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:
authorJean-Luc Peurière <jlp@nerim.net>2008-03-14 02:54:02 +0300
committerJean-Luc Peurière <jlp@nerim.net>2008-03-14 02:54:02 +0300
commita68a7f42b02ad0260220d94f36ab61c772db071a (patch)
tree620b763cd24fbfc1259f00ccb005217914af0c6f
parent526d0bec4722900a86d81ff0f5d71504b2b4ad8c (diff)
parent15215493bf9d1d08e650109e6eb6189fc76e289e (diff)
resolved conflict state with HEAD r14096
blenderbuttons still bad not let this compile
-rw-r--r--CMakeLists.txt35
-rw-r--r--Makefile9
-rw-r--r--SConstruct53
-rw-r--r--bin/.blender/.Blanguages1
-rw-r--r--config/darwin-config.py2
-rw-r--r--config/linux2-config.py17
-rw-r--r--config/linuxcross-config.py2
-rw-r--r--config/openbsd3-config.py2
-rw-r--r--config/sunos5-config.py2
-rw-r--r--config/win32-mingw-config.py28
-rw-r--r--config/win32-vc-config.py12
-rw-r--r--doc/blender-scons.txt15
-rw-r--r--extern/CMakeLists.txt9
-rw-r--r--extern/Makefile4
-rw-r--r--extern/SConscript11
-rw-r--r--[-rwxr-xr-x]extern/bFTGL/include/FTGL.h6
-rw-r--r--extern/bFTGL/src/FTVectoriser.cpp8
-rw-r--r--extern/bFTGL/src/Makefile3
-rw-r--r--extern/binreloc/CMakeLists.txt26
-rw-r--r--extern/binreloc/Makefile37
-rw-r--r--extern/binreloc/SConscript13
-rw-r--r--extern/binreloc/binreloc.c766
-rw-r--r--extern/binreloc/include/binreloc.h80
-rw-r--r--extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj18
-rw-r--r--extern/bullet2/src/Bullet-C-Api.h37
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp261
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h83
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h2
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h40
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h5
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h10
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp56
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h100
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp13
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp55
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp49
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp14
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h79
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp115
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h51
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp18
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp31
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h18
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp39
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h13
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp23
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp150
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h5
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp55
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp13
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h13
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp15
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h50
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp58
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h35
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp146
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h60
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp36
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h31
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h19
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h24
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp38
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp22
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h46
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp48
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h32
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h9
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp299
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h36
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp22
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp714
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h288
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp52
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h44
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp13
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp19
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp53
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h57
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp27
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h43
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h9
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp36
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h14
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h2
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h13
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp16
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h4
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h2
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp5
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp39
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h5
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h27
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp111
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp8
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h43
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h8
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp24
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h6
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h4
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp32
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h6
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp135
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h12
-rw-r--r--extern/bullet2/src/BulletDynamics/CMakeLists.txt1
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp285
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h123
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h6
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp100
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h57
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h30
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp78
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h12
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp35
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h11
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h18
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp7
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h13
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp846
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h37
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp58
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h7
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h71
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h63
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp12
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h14
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp120
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp340
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h31
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h16
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp133
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h59
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp30
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h6
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp173
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h57
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h4
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp13
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h24
-rw-r--r--extern/bullet2/src/LinearMath/btAabbUtil2.h10
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedAllocator.cpp27
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedAllocator.h7
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedObjectArray.h226
-rw-r--r--extern/bullet2/src/LinearMath/btDefaultMotionState.h7
-rw-r--r--extern/bullet2/src/LinearMath/btGeometryUtil.cpp45
-rw-r--r--extern/bullet2/src/LinearMath/btGeometryUtil.h6
-rw-r--r--extern/bullet2/src/LinearMath/btIDebugDraw.h35
-rw-r--r--extern/bullet2/src/LinearMath/btMatrix3x3.h217
-rw-r--r--extern/bullet2/src/LinearMath/btMotionState.h7
-rw-r--r--extern/bullet2/src/LinearMath/btPoint3.h2
-rw-r--r--extern/bullet2/src/LinearMath/btQuadWord.h30
-rw-r--r--extern/bullet2/src/LinearMath/btQuaternion.h79
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.cpp2
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.h131
-rw-r--r--extern/bullet2/src/LinearMath/btScalar.h76
-rw-r--r--extern/bullet2/src/LinearMath/btSimdMinMax.h2
-rw-r--r--extern/bullet2/src/LinearMath/btTransform.h39
-rw-r--r--extern/bullet2/src/LinearMath/btTransformUtil.h51
-rw-r--r--extern/bullet2/src/LinearMath/btVector3.h33
-rw-r--r--extern/bullet2/src/SConscript2
-rw-r--r--extern/bullet2/src/btBulletCollisionCommon.h1
-rw-r--r--extern/bullet2/src/btBulletDynamicsCommon.h1
-rw-r--r--extern/verse/Makefile3
-rw-r--r--extern/verse/dist/v_connection.c3
-rw-r--r--extern/verse/dist/v_network.c7
-rw-r--r--intern/SoundSystem/SConscript9
-rw-r--r--intern/SoundSystem/openal/SND_OpenALDevice.cpp12
-rw-r--r--intern/action/ACT_Action.h141
-rw-r--r--intern/action/ACT_ActionC-Api.h193
-rw-r--r--intern/action/ACT_ActionStack.h185
-rw-r--r--intern/action/Makefile52
-rw-r--r--intern/action/doc/Doxyfile746
-rw-r--r--intern/action/intern/ACT_ActionC-Api.cpp134
-rw-r--r--intern/action/intern/ACT_ActionStack.cpp245
-rw-r--r--intern/action/intern/ACT_CallbackAction.h125
-rw-r--r--intern/action/make/msvc_6_0/action.dsp128
-rw-r--r--intern/action/make/msvc_6_0/action.dsw29
-rw-r--r--intern/action/make/msvc_7_0/action.sln21
-rw-r--r--intern/action/make/msvc_7_0/action.vcproj145
-rw-r--r--intern/action/test/action_c_test/ActionTest.c87
-rw-r--r--intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsp109
-rw-r--r--intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsw44
-rw-r--r--intern/action/test/action_cpp_test/ActionTest.cpp87
-rw-r--r--intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsp105
-rw-r--r--intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsw44
-rw-r--r--intern/bmfont/BMF_Api.h37
-rw-r--r--intern/bmfont/intern/BMF_Api.cpp22
-rw-r--r--intern/bmfont/intern/BMF_BitmapFont.cpp118
-rw-r--r--intern/bmfont/intern/BMF_BitmapFont.h35
-rw-r--r--intern/boolop/intern/BOP_BSPNode.cpp100
-rw-r--r--intern/boolop/intern/BOP_BSPNode.h7
-rw-r--r--intern/boolop/intern/BOP_BSPTree.cpp43
-rw-r--r--intern/boolop/intern/BOP_BSPTree.h1
-rw-r--r--intern/boolop/intern/BOP_Face.cpp10
-rw-r--r--intern/boolop/intern/BOP_Face.h13
-rw-r--r--intern/boolop/intern/BOP_Face2Face.cpp116
-rw-r--r--intern/boolop/intern/BOP_Interface.cpp4
-rw-r--r--intern/boolop/intern/BOP_MathUtils.cpp68
-rw-r--r--intern/boolop/intern/BOP_MathUtils.h16
-rw-r--r--intern/boolop/intern/BOP_Merge.cpp6
-rw-r--r--intern/boolop/intern/BOP_Mesh.cpp45
-rw-r--r--intern/boolop/intern/BOP_Triangulator.cpp53
-rw-r--r--[-rwxr-xr-x]intern/bsp/intern/BSP_CSGMesh_CFIterator.h7
-rw-r--r--intern/csg/SConscript8
-rw-r--r--intern/csg/extern/CSG_Interface.h434
-rw-r--r--intern/csg/intern/CSG_BBox.h206
-rw-r--r--intern/csg/intern/CSG_BBoxTree.cpp125
-rw-r--r--intern/csg/intern/CSG_BBoxTree.h135
-rw-r--r--intern/csg/intern/CSG_BlenderVProp.h94
-rw-r--r--intern/csg/intern/CSG_BooleanOp.h88
-rw-r--r--intern/csg/intern/CSG_BooleanOp.inl235
-rw-r--r--intern/csg/intern/CSG_CVertex.h104
-rw-r--r--intern/csg/intern/CSG_ConnectedMesh.h95
-rw-r--r--intern/csg/intern/CSG_ConnectedMeshWrapper.inl210
-rw-r--r--intern/csg/intern/CSG_GeometryBinder.h72
-rw-r--r--intern/csg/intern/CSG_IndexDefs.h42
-rw-r--r--intern/csg/intern/CSG_Math.h152
-rw-r--r--intern/csg/intern/CSG_Math.inl362
-rw-r--r--intern/csg/intern/CSG_Mesh.h66
-rw-r--r--intern/csg/intern/CSG_MeshCopier.h45
-rw-r--r--intern/csg/intern/CSG_MeshWrapper.h110
-rw-r--r--intern/csg/intern/CSG_MeshWrapper.inl150
-rw-r--r--intern/csg/intern/CSG_Polygon.h93
-rw-r--r--intern/csg/intern/CSG_SplitFunction.h188
-rw-r--r--intern/csg/intern/CSG_TreeQueries.h158
-rw-r--r--intern/csg/intern/CSG_Triangulate.h96
-rw-r--r--intern/csg/intern/CSG_Triangulate.inl232
-rw-r--r--intern/csg/intern/CSG_Vertex.h56
-rw-r--r--intern/csg/intern/MT_Line3.cpp81
-rw-r--r--intern/csg/intern/MT_Line3.h109
-rw-r--r--intern/csg/intern/blender/CSG_BlenderMesh.h45
-rw-r--r--intern/csg/intern/blender/CSG_BlenderVProp.cpp35
-rw-r--r--intern/csg/intern/blender/CSG_CsgOp.cpp257
-rw-r--r--intern/csg/intern/blender/CSG_CsgOp.h59
-rw-r--r--intern/csg/intern/blender/CSG_IndexDefs.h22
-rw-r--r--intern/csg/intern/blender/CSG_Interface.cpp193
-rw-r--r--intern/csg/intern/blender/CSG_Iterator.h199
-rw-r--r--intern/csg/intern/blender/CSG_MeshBuilder.h123
-rw-r--r--intern/csg/intern/blender/CSG_PropArray.h126
-rw-r--r--intern/csg/intern/blender/CSG_SimpleProp.cpp4
-rw-r--r--intern/csg/intern/blender/CSG_SimpleProp.h58
-rw-r--r--intern/csg/make/msvc60/csg.dsp234
-rw-r--r--intern/csg/make/msvc60/csg.dsw29
-rw-r--r--intern/elbeem/CMakeLists.txt4
-rw-r--r--intern/elbeem/SConscript6
-rw-r--r--intern/elbeem/extern/elbeem.h2
-rw-r--r--intern/elbeem/intern/attributes.cpp1
-rw-r--r--intern/elbeem/intern/elbeem.h2
-rw-r--r--intern/elbeem/intern/isosurface.cpp3
-rw-r--r--intern/elbeem/intern/loop_tools.h81
-rw-r--r--intern/elbeem/intern/ntl_geometryobject.cpp2
-rw-r--r--intern/elbeem/intern/ntl_vector3dim.h3
-rw-r--r--intern/elbeem/intern/paraloopend.h42
-rw-r--r--intern/elbeem/intern/parametrizer.cpp2
-rw-r--r--intern/elbeem/intern/particletracer.cpp1
-rw-r--r--intern/elbeem/intern/simulation_object.cpp5
-rw-r--r--intern/elbeem/intern/solver_adap.cpp4
-rw-r--r--intern/elbeem/intern/solver_class.h5
-rw-r--r--intern/elbeem/intern/solver_init.cpp55
-rw-r--r--intern/elbeem/intern/solver_interface.cpp7
-rw-r--r--intern/elbeem/intern/solver_interface.h6
-rw-r--r--intern/elbeem/intern/solver_main.cpp24
-rw-r--r--intern/elbeem/intern/solver_util.cpp1
-rw-r--r--intern/elbeem/intern/utilities.cpp6
-rw-r--r--intern/elbeem/intern/utilities.h2
-rw-r--r--intern/ghost/GHOST_C-api.h12
-rw-r--r--intern/ghost/GHOST_ISystem.h12
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp13
-rw-r--r--intern/ghost/intern/GHOST_DisplayManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_System.h15
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp68
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.h18
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp59
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h14
-rw-r--r--[-rwxr-xr-x]intern/ghost/intern/GHOST_SystemX11.cpp171
-rw-r--r--[-rwxr-xr-x]intern/ghost/intern/GHOST_SystemX11.h15
-rw-r--r--[-rwxr-xr-x]intern/ghost/intern/GHOST_WindowX11.cpp27
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h7
-rw-r--r--intern/guardedalloc/intern/mallocn.c131
-rw-r--r--intern/iksolver/extern/IK_solver.h2
-rw-r--r--intern/iksolver/intern/IK_QJacobian.cpp3
-rw-r--r--intern/iksolver/intern/IK_QJacobian.h4
-rw-r--r--intern/iksolver/intern/IK_QJacobianSolver.cpp172
-rw-r--r--intern/iksolver/intern/IK_QJacobianSolver.h26
-rw-r--r--intern/iksolver/intern/IK_QSegment.cpp47
-rw-r--r--intern/iksolver/intern/IK_QSegment.h9
-rw-r--r--intern/iksolver/intern/IK_QTask.h9
-rw-r--r--intern/iksolver/intern/IK_Solver.cpp35
-rw-r--r--intern/iksolver/intern/TNT/svd.h9
-rw-r--r--intern/keymaker/Makefile92
-rw-r--r--intern/keymaker/blenkey.h83
-rw-r--r--intern/keymaker/key.c496
-rw-r--r--intern/keymaker/key_internal.h92
-rw-r--r--intern/keymaker/keyloader.c319
-rw-r--r--intern/keymaker/make/msvc_6_0/blenkey.dsp134
-rw-r--r--intern/keymaker/make/msvc_6_0/blenkey.dsw29
-rw-r--r--intern/keymaker/make/msvc_7_0/blenkey.sln21
-rw-r--r--intern/keymaker/make/msvc_7_0/blenkey.vcproj282
-rw-r--r--intern/keymaker/mt19937int.c134
-rw-r--r--intern/keymaker/python/key_pyc.h154
-rw-r--r--intern/make/msvc_7_0/intern.sln15
-rw-r--r--intern/memutil/MEM_CacheLimiter.h3
-rw-r--r--[-rwxr-xr-x]intern/moto/include/MT_Matrix3x3.h20
-rw-r--r--intern/moto/include/MT_Vector3.h1
-rw-r--r--intern/moto/include/MT_Vector4.h1
-rw-r--r--intern/moto/include/MT_assert.h2
-rw-r--r--intern/moto/intern/MT_Assert.cpp2
-rw-r--r--intern/opennl/SConscript4
-rw-r--r--intern/opennl/extern/ONL_opennl.h35
-rw-r--r--intern/opennl/intern/opennl.c526
-rw-r--r--intern/string/STR_String.h4
-rw-r--r--intern/string/intern/STR_String.cpp1
-rw-r--r--po/Makefile3
-rw-r--r--projectfiles/blender/src/BL_src.dsp4
-rw-r--r--projectfiles/blender/src/BL_src_cre.dsp4
-rw-r--r--projectfiles_vc7/blender/blender.sln2
-rw-r--r--projectfiles_vc7/blender/blender.vcproj2
-rw-r--r--projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj75
-rw-r--r--projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj18
-rw-r--r--projectfiles_vc7/blender/ftfont/FTF_ftfont.vcproj2
-rw-r--r--projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj85
-rw-r--r--projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj6
-rw-r--r--projectfiles_vc7/blender/nodes/nodes.vcproj49
-rw-r--r--projectfiles_vc7/blender/render/BRE_render.vcproj12
-rw-r--r--projectfiles_vc7/blender/src/BL_src.vcproj47
-rw-r--r--projectfiles_vc7/blender/src/BL_src_cre.vcproj4
-rw-r--r--projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj18
-rw-r--r--projectfiles_vc7/gameengine/gameplayer/ghost/GP_ghost.vcproj8
-rw-r--r--projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj6
-rw-r--r--projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj34
-rw-r--r--release/Makefile105
-rw-r--r--release/datafiles/preview.blendbin459544 -> 433792 bytes
-rw-r--r--release/datafiles/prviconsbin0 -> 13732 bytes
-rw-r--r--release/datafiles/splash.jpgbin0 -> 84581 bytes
-rwxr-xr-xrelease/getversion.py55
-rw-r--r--release/scripts/3ds_import.py15
-rw-r--r--release/scripts/DirectX8Importer.py231
-rw-r--r--release/scripts/ac3d_import.py2
-rw-r--r--release/scripts/add_mesh_empty.py13
-rw-r--r--release/scripts/add_mesh_torus.py9
-rw-r--r--release/scripts/bpymodules/BPyMesh.py2
-rw-r--r--release/scripts/bpymodules/BPyMessages.py2
-rw-r--r--release/scripts/bpymodules/BPyObject.py2
-rw-r--r--release/scripts/bpymodules/BPyRender.py135
-rw-r--r--release/scripts/bpymodules/blend2renderinfo.py95
-rw-r--r--release/scripts/bpymodules/paths_ai2obj.py10
-rw-r--r--release/scripts/bpymodules/paths_gimp2obj.py4
-rw-r--r--release/scripts/bvh_import.py4
-rw-r--r--release/scripts/console.py35
-rw-r--r--release/scripts/export_fbx.py2352
-rw-r--r--release/scripts/export_m3g.py39
-rw-r--r--release/scripts/export_mdd.py3
-rw-r--r--release/scripts/export_obj.py198
-rw-r--r--release/scripts/flt_defaultp.py1
-rw-r--r--[-rwxr-xr-x]release/scripts/flt_export.py1501
-rw-r--r--release/scripts/flt_filewalker.py9
-rw-r--r--[-rwxr-xr-x]release/scripts/flt_import.py1585
-rw-r--r--release/scripts/flt_palettemanager.py388
-rw-r--r--release/scripts/flt_properties.py619
-rw-r--r--release/scripts/flt_toolbar.py654
-rw-r--r--release/scripts/image_auto_layout.py57
-rw-r--r--release/scripts/image_billboard.py142
-rw-r--r--release/scripts/image_find_paths.py167
-rw-r--r--release/scripts/import_dxf.py8089
-rw-r--r--release/scripts/import_mdd.py12
-rw-r--r--release/scripts/import_obj.py5
-rw-r--r--release/scripts/lightwave_import.py193
-rw-r--r--release/scripts/mesh_edges2curves.py12
-rw-r--r--release/scripts/mesh_skin.py2
-rw-r--r--release/scripts/mesh_unfolder.py194
-rw-r--r--release/scripts/mesh_wire.py27
-rw-r--r--release/scripts/object_drop.py5
-rw-r--r--release/scripts/object_find.py35
-rw-r--r--[-rwxr-xr-x]release/scripts/object_random_loc_sz_rot.py65
-rw-r--r--release/scripts/object_timeofs_follow_act.py107
-rw-r--r--release/scripts/ply_export.py15
-rw-r--r--release/scripts/ply_import.py8
-rw-r--r--release/scripts/render_save_layers.py116
-rw-r--r--release/scripts/save_theme.py6
-rw-r--r--release/scripts/scripttemplate_mesh_edit.py1
-rw-r--r--release/scripts/scripttemplate_pyconstraint.py114
-rw-r--r--release/scripts/uv_export.py64
-rw-r--r--release/scripts/uv_seams_from_islands.py7
-rw-r--r--release/scripts/uvcalc_follow_active_coords.py12
-rw-r--r--release/scripts/uvcalc_from_adjacent.py129
-rw-r--r--release/scripts/uvcalc_lightmap.py15
-rw-r--r--release/scripts/uvcalc_quad_clickproj.py11
-rw-r--r--release/scripts/uvcalc_smart_project.py3
-rw-r--r--release/scripts/vertexpaint_selfshadow_ao.py11
-rw-r--r--release/scripts/vrml97_export.py8
-rw-r--r--release/scripts/weightpaint_average.py121
-rw-r--r--release/scripts/weightpaint_invert.py95
-rw-r--r--release/scripts/weightpaint_normalize.py126
-rw-r--r--release/scripts/wizard_curve2tree.py4007
-rw-r--r--release/scripts/x3d_export.py12
-rw-r--r--release/windows/installer/00.sconsblender.nsi41
-rw-r--r--source/Makefile98
-rw-r--r--source/blender/Makefile2
-rw-r--r--source/blender/SConscript3
-rw-r--r--source/blender/avi/intern/avi.c192
-rw-r--r--source/blender/avi/intern/endian.c2
-rw-r--r--source/blender/avi/intern/options.c4
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h28
-rw-r--r--source/blender/blenkernel/BKE_action.h22
-rw-r--r--source/blender/blenkernel/BKE_anim.h5
-rw-r--r--source/blender/blenkernel/BKE_armature.h6
-rw-r--r--source/blender/blenkernel/BKE_bad_level_calls.h54
-rw-r--r--source/blender/blenkernel/BKE_blender.h4
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h237
-rw-r--r--source/blender/blenkernel/BKE_cloth.h270
-rw-r--r--source/blender/blenkernel/BKE_collision.h192
-rw-r--r--source/blender/blenkernel/BKE_constraint.h139
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/BKE_deform.h1
-rw-r--r--source/blender/blenkernel/BKE_displist.h2
-rw-r--r--source/blender/blenkernel/BKE_global.h26
-rw-r--r--source/blender/blenkernel/BKE_group.h5
-rw-r--r--source/blender/blenkernel/BKE_icons.h75
-rw-r--r--source/blender/blenkernel/BKE_idprop.h1
-rw-r--r--source/blender/blenkernel/BKE_image.h7
-rw-r--r--source/blender/blenkernel/BKE_ipo.h2
-rw-r--r--source/blender/blenkernel/BKE_key.h1
-rw-r--r--source/blender/blenkernel/BKE_lattice.h4
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_material.h3
-rw-r--r--source/blender/blenkernel/BKE_mball.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh.h34
-rw-r--r--source/blender/blenkernel/BKE_modifier.h26
-rw-r--r--source/blender/blenkernel/BKE_multires.h68
-rw-r--r--source/blender/blenkernel/BKE_node.h88
-rw-r--r--source/blender/blenkernel/BKE_object.h13
-rw-r--r--source/blender/blenkernel/BKE_particle.h317
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h54
-rw-r--r--source/blender/blenkernel/BKE_scene.h9
-rw-r--r--source/blender/blenkernel/BKE_sculpt.h74
-rw-r--r--source/blender/blenkernel/BKE_softbody.h14
-rw-r--r--source/blender/blenkernel/BKE_text.h3
-rw-r--r--source/blender/blenkernel/BKE_texture.h3
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h35
-rw-r--r--source/blender/blenkernel/BKE_verse.h82
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/SConscript7
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/Makefile4
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/stubs.c89
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c394
-rw-r--r--source/blender/blenkernel/intern/BME_eulers.c975
-rw-r--r--source/blender/blenkernel/intern/BME_mesh.c304
-rw-r--r--source/blender/blenkernel/intern/BME_structure.c618
-rw-r--r--source/blender/blenkernel/intern/BME_tools.c1212
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c35
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c504
-rw-r--r--source/blender/blenkernel/intern/Makefile14
-rw-r--r--source/blender/blenkernel/intern/action.c234
-rw-r--r--source/blender/blenkernel/intern/anim.c685
-rw-r--r--source/blender/blenkernel/intern/armature.c903
-rw-r--r--source/blender/blenkernel/intern/blender.c24
-rw-r--r--source/blender/blenkernel/intern/bmesh_private.h71
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c23
-rw-r--r--source/blender/blenkernel/intern/cloth.c1467
-rw-r--r--source/blender/blenkernel/intern/collision.c1240
-rw-r--r--source/blender/blenkernel/intern/colortools.c40
-rw-r--r--source/blender/blenkernel/intern/constraint.c5115
-rw-r--r--source/blender/blenkernel/intern/curve.c112
-rw-r--r--source/blender/blenkernel/intern/customdata.c169
-rw-r--r--source/blender/blenkernel/intern/deform.c26
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c298
-rw-r--r--source/blender/blenkernel/intern/displist.c182
-rw-r--r--source/blender/blenkernel/intern/effect.c34
-rw-r--r--source/blender/blenkernel/intern/exotic.c30
-rw-r--r--source/blender/blenkernel/intern/group.c35
-rw-r--r--source/blender/blenkernel/intern/icons.c184
-rw-r--r--source/blender/blenkernel/intern/idprop.c65
-rw-r--r--source/blender/blenkernel/intern/image.c535
-rw-r--r--source/blender/blenkernel/intern/implicit.c1698
-rw-r--r--source/blender/blenkernel/intern/ipo.c240
-rw-r--r--source/blender/blenkernel/intern/kdop.c862
-rw-r--r--source/blender/blenkernel/intern/key.c60
-rw-r--r--source/blender/blenkernel/intern/lattice.c26
-rw-r--r--source/blender/blenkernel/intern/library.c41
-rw-r--r--source/blender/blenkernel/intern/material.c48
-rw-r--r--source/blender/blenkernel/intern/mball.c18
-rw-r--r--source/blender/blenkernel/intern/mesh.c212
-rw-r--r--source/blender/blenkernel/intern/modifier.c2356
-rw-r--r--source/blender/blenkernel/intern/multires-firstlevel.c (renamed from source/blender/src/multires-firstlevel.c)3
-rw-r--r--source/blender/blenkernel/intern/multires.c1305
-rw-r--r--source/blender/blenkernel/intern/node.c356
-rw-r--r--source/blender/blenkernel/intern/object.c548
-rw-r--r--source/blender/blenkernel/intern/particle.c3779
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4680
-rw-r--r--source/blender/blenkernel/intern/pointcache.c262
-rw-r--r--source/blender/blenkernel/intern/sca.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c230
-rw-r--r--source/blender/blenkernel/intern/script.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c1662
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c613
-rw-r--r--source/blender/blenkernel/intern/text.c22
-rw-r--r--source/blender/blenkernel/intern/texture.c26
-rw-r--r--source/blender/blenkernel/intern/verse_geometry_node.c547
-rw-r--r--source/blender/blenkernel/intern/verse_method.c523
-rw-r--r--source/blender/blenkernel/intern/verse_node.c15
-rw-r--r--source/blender/blenkernel/intern/verse_object_node.c8
-rw-r--r--source/blender/blenkernel/intern/verse_session.c7
-rw-r--r--source/blender/blenkernel/intern/world.c15
-rw-r--r--source/blender/blenkernel/intern/writeavi.c5
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c51
-rw-r--r--source/blender/blenlib/BLI_arithb.h1034
-rw-r--r--source/blender/blenlib/BLI_blenlib.h61
-rw-r--r--source/blender/blenlib/BLI_boxpack2d.h5
-rw-r--r--source/blender/blenlib/BLI_bpath.h60
-rw-r--r--source/blender/blenlib/BLI_editVert.h14
-rw-r--r--source/blender/blenlib/BLI_fnmatch.h69
-rw-r--r--source/blender/blenlib/BLI_kdtree.h63
-rw-r--r--source/blender/blenlib/BLI_rand.h3
-rw-r--r--source/blender/blenlib/BLI_storage_types.h3
-rw-r--r--source/blender/blenlib/BLI_threads.h1
-rw-r--r--source/blender/blenlib/CMakeLists.txt7
-rw-r--r--source/blender/blenlib/SConscript1
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c18
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c341
-rw-r--r--source/blender/blenlib/intern/BLI_storage.h5
-rw-r--r--source/blender/blenlib/intern/Makefile7
-rw-r--r--source/blender/blenlib/intern/arithb.c1163
-rw-r--r--source/blender/blenlib/intern/bpath.c556
-rw-r--r--source/blender/blenlib/intern/fileops.c69
-rw-r--r--source/blender/blenlib/intern/fnmatch.c250
-rw-r--r--source/blender/blenlib/intern/psfont.c2
-rw-r--r--source/blender/blenlib/intern/rand.c8
-rw-r--r--source/blender/blenlib/intern/storage.c61
-rw-r--r--source/blender/blenlib/intern/threads.c73
-rw-r--r--source/blender/blenlib/intern/util.c495
-rw-r--r--source/blender/blenloader/BLO_readfile.h19
-rw-r--r--source/blender/blenloader/intern/Makefile4
-rw-r--r--source/blender/blenloader/intern/readblenentry.c66
-rw-r--r--source/blender/blenloader/intern/readfile.c1689
-rw-r--r--source/blender/blenloader/intern/readfile.h4
-rw-r--r--source/blender/blenloader/intern/writefile.c318
-rw-r--r--source/blender/blenpluginapi/iff.h2
-rw-r--r--source/blender/blenpluginapi/intern/Makefile4
-rw-r--r--source/blender/ftfont/CMakeLists.txt2
-rw-r--r--source/blender/ftfont/FTF_Api.h16
-rw-r--r--source/blender/ftfont/SConscript2
-rw-r--r--source/blender/ftfont/intern/FTF_Api.cpp32
-rw-r--r--source/blender/ftfont/intern/FTF_TTFont.cpp8
-rw-r--r--source/blender/ftfont/intern/FTF_TTFont.h11
-rw-r--r--source/blender/ftfont/intern/Makefile6
-rw-r--r--source/blender/imbuf/IMB_imbuf.h29
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h15
-rw-r--r--source/blender/imbuf/IMB_thumbs.h74
-rw-r--r--source/blender/imbuf/SConscript3
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h4
-rw-r--r--source/blender/imbuf/intern/IMB_imginfo.h85
-rw-r--r--source/blender/imbuf/intern/IMB_jpeg.h2
-rw-r--r--source/blender/imbuf/intern/Makefile7
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c8
-rw-r--r--source/blender/imbuf/intern/anim.c148
-rw-r--r--source/blender/imbuf/intern/cineon/Makefile4
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c24
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c12
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c14
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c29
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.h4
-rw-r--r--source/blender/imbuf/intern/cineon/logImageLib.c5
-rw-r--r--source/blender/imbuf/intern/cineon/logImageLib.h1
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp591
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h248
-rw-r--r--source/blender/imbuf/intern/dds/Color.h99
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp317
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h116
-rw-r--r--source/blender/imbuf/intern/dds/Common.h56
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp1023
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h181
-rw-r--r--source/blender/imbuf/intern/dds/Image.cpp132
-rw-r--r--source/blender/imbuf/intern/dds/Image.h104
-rw-r--r--source/blender/imbuf/intern/dds/Makefile (renamed from intern/action/intern/Makefile)35
-rw-r--r--source/blender/imbuf/intern/dds/PixelFormat.h110
-rw-r--r--source/blender/imbuf/intern/dds/SConscript19
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp99
-rw-r--r--source/blender/imbuf/intern/dds/Stream.h49
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp132
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.h43
-rw-r--r--source/blender/imbuf/intern/divers.c2
-rw-r--r--source/blender/imbuf/intern/dynlibtiff.c8
-rw-r--r--source/blender/imbuf/intern/filter.c73
-rwxr-xr-xsource/blender/imbuf/intern/gen_dynlibtiff.py8
-rw-r--r--source/blender/imbuf/intern/imageprocess.c260
-rw-r--r--source/blender/imbuf/intern/imginfo.c158
-rw-r--r--source/blender/imbuf/intern/jpeg.c94
-rw-r--r--source/blender/imbuf/intern/md5.c361
-rw-r--r--source/blender/imbuf/intern/md5.h116
-rw-r--r--source/blender/imbuf/intern/openexr/Makefile4
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp51
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h8
-rw-r--r--source/blender/imbuf/intern/png.c39
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c29
-rw-r--r--source/blender/imbuf/intern/readimage.c11
-rw-r--r--source/blender/imbuf/intern/rectop.c84
-rw-r--r--source/blender/imbuf/intern/rotate.c91
-rw-r--r--source/blender/imbuf/intern/scaling.c473
-rw-r--r--source/blender/imbuf/intern/thumbs.c459
-rw-r--r--source/blender/imbuf/intern/tiff.c192
-rw-r--r--source/blender/imbuf/intern/util.c20
-rw-r--r--source/blender/imbuf/intern/writeimage.c10
-rw-r--r--source/blender/include/BDR_drawaction.h40
-rw-r--r--source/blender/include/BDR_drawmesh.h3
-rw-r--r--source/blender/include/BDR_editcurve.h8
-rw-r--r--source/blender/include/BDR_editface.h4
-rw-r--r--source/blender/include/BDR_editmball.h2
-rw-r--r--source/blender/include/BDR_editobject.h11
-rw-r--r--source/blender/include/BDR_sculptmode.h72
-rw-r--r--source/blender/include/BDR_unwrapper.h1
-rw-r--r--source/blender/include/BIF_butspace.h36
-rw-r--r--source/blender/include/BIF_drawimage.h11
-rw-r--r--source/blender/include/BIF_drawseq.h1
-rw-r--r--source/blender/include/BIF_drawtext.h2
-rw-r--r--source/blender/include/BIF_editaction.h170
-rw-r--r--source/blender/include/BIF_editarmature.h22
-rw-r--r--source/blender/include/BIF_editconstraint.h23
-rw-r--r--source/blender/include/BIF_editdeform.h3
-rw-r--r--source/blender/include/BIF_editmesh.h28
-rw-r--r--source/blender/include/BIF_editmode_undo.h3
-rw-r--r--source/blender/include/BIF_editparticle.h98
-rw-r--r--source/blender/include/BIF_editseq.h46
-rw-r--r--source/blender/include/BIF_editsima.h35
-rw-r--r--source/blender/include/BIF_editsound.h2
-rw-r--r--source/blender/include/BIF_editview.h2
-rw-r--r--source/blender/include/BIF_filelist.h86
-rw-r--r--source/blender/include/BIF_fsmenu.h7
-rw-r--r--source/blender/include/BIF_gl.h13
-rw-r--r--source/blender/include/BIF_imasel.h26
-rw-r--r--source/blender/include/BIF_interface.h3
-rw-r--r--source/blender/include/BIF_interface_icons.h3
-rw-r--r--source/blender/include/BIF_language.h3
-rw-r--r--source/blender/include/BIF_meshlaplacian.h87
-rw-r--r--source/blender/include/BIF_meshtools.h4
-rw-r--r--source/blender/include/BIF_outliner.h5
-rw-r--r--source/blender/include/BIF_poselib.h55
-rw-r--r--source/blender/include/BIF_poseobject.h17
-rw-r--r--source/blender/include/BIF_radialcontrol.h62
-rw-r--r--source/blender/include/BIF_renderwin.h10
-rw-r--r--source/blender/include/BIF_resources.h44
-rw-r--r--source/blender/include/BIF_space.h8
-rw-r--r--source/blender/include/BIF_spacetypes.h3
-rw-r--r--source/blender/include/BIF_toolbox.h10
-rw-r--r--source/blender/include/BIF_transform.h30
-rw-r--r--source/blender/include/BIF_usiblender.h1
-rw-r--r--source/blender/include/BPI_script.h71
-rw-r--r--source/blender/include/BSE_drawimasel.h35
-rw-r--r--source/blender/include/BSE_drawipo.h1
-rw-r--r--source/blender/include/BSE_drawview.h2
-rw-r--r--source/blender/include/BSE_edit.h1
-rw-r--r--source/blender/include/BSE_editaction_types.h87
-rw-r--r--source/blender/include/BSE_editipo.h34
-rw-r--r--source/blender/include/BSE_filesel.h2
-rw-r--r--source/blender/include/BSE_headerbuttons.h1
-rw-r--r--source/blender/include/BSE_node.h11
-rw-r--r--source/blender/include/BSE_seqeffects.h1
-rw-r--r--source/blender/include/BSE_seqscopes.h3
-rw-r--r--source/blender/include/BSE_sequence.h30
-rw-r--r--source/blender/include/BSE_time.h21
-rw-r--r--source/blender/include/BSE_trans_types.h1
-rw-r--r--source/blender/include/BSE_view.h1
-rw-r--r--source/blender/include/blendef.h136
-rw-r--r--source/blender/include/butspace.h114
-rw-r--r--source/blender/include/datatoc.h3
-rw-r--r--source/blender/include/editmesh.h2
-rw-r--r--source/blender/include/interface.h2
-rw-r--r--source/blender/include/multires.h28
-rw-r--r--source/blender/include/mydevice.h2
-rw-r--r--source/blender/include/reeb.h127
-rw-r--r--source/blender/include/transform.h95
-rw-r--r--source/blender/makesdna/DNA_ID.h28
-rw-r--r--source/blender/makesdna/DNA_action_types.h220
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h33
-rw-r--r--source/blender/makesdna/DNA_armature_types.h117
-rw-r--r--source/blender/makesdna/DNA_camera_types.h2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h135
-rw-r--r--source/blender/makesdna/DNA_color_types.h5
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h387
-rw-r--r--source/blender/makesdna/DNA_curve_types.h18
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h13
-rw-r--r--source/blender/makesdna/DNA_group_types.h4
-rw-r--r--source/blender/makesdna/DNA_image_types.h14
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h58
-rw-r--r--source/blender/makesdna/DNA_key_types.h7
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h34
-rw-r--r--source/blender/makesdna/DNA_listBase.h9
-rw-r--r--source/blender/makesdna/DNA_material_types.h59
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h26
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h36
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h143
-rw-r--r--source/blender/makesdna/DNA_nla_types.h38
-rw-r--r--source/blender/makesdna/DNA_node_types.h64
-rw-r--r--source/blender/makesdna/DNA_object_force.h63
-rw-r--r--source/blender/makesdna/DNA_object_types.h62
-rw-r--r--source/blender/makesdna/DNA_particle_types.h449
-rw-r--r--source/blender/makesdna/DNA_scene_types.h259
-rw-r--r--source/blender/makesdna/DNA_screen_types.h4
-rw-r--r--source/blender/makesdna/DNA_scriptlink_types.h3
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h105
-rw-r--r--source/blender/makesdna/DNA_space_types.h258
-rw-r--r--source/blender/makesdna/DNA_texture_types.h49
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h185
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h4
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h13
-rw-r--r--source/blender/makesdna/DNA_world_types.h19
-rw-r--r--source/blender/makesdna/intern/Makefile4
-rw-r--r--source/blender/makesdna/intern/SConscript2
-rw-r--r--source/blender/makesdna/intern/makesdna.c8
-rw-r--r--source/blender/nodes/CMP_node.h11
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/SConscript4
-rw-r--r--source/blender/nodes/SHD_node.h4
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c57
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c272
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_blur.c144
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c4
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_crop.c119
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_curves.c8
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_defocus.c27
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c143
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_displace.c15
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_glare.c502
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_idMask.c22
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_image.c54
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_invert.c2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c192
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_math.c40
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_normalize.c113
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c77
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_scale.c6
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_texture.c33
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c173
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c75
-rw-r--r--source/blender/nodes/intern/CMP_nodes/Makefile5
-rw-r--r--source/blender/nodes/intern/CMP_util.c665
-rw-r--r--source/blender/nodes/intern/CMP_util.h43
-rw-r--r--source/blender/nodes/intern/Makefile7
-rw-r--r--source/blender/nodes/intern/SHD_nodes/Makefile7
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c762
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_geom.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c94
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c105
-rw-r--r--source/blender/python/BPY_extern.h37
-rw-r--r--source/blender/python/BPY_interface.c1251
-rw-r--r--source/blender/python/BPY_menus.c32
-rw-r--r--source/blender/python/SConscript5
-rw-r--r--source/blender/python/api2_2x/Armature.c341
-rw-r--r--source/blender/python/api2_2x/BGL.c9
-rw-r--r--source/blender/python/api2_2x/BezTriple.c25
-rw-r--r--source/blender/python/api2_2x/Blender.c164
-rw-r--r--source/blender/python/api2_2x/Bone.c92
-rw-r--r--source/blender/python/api2_2x/Bone.h1
-rw-r--r--source/blender/python/api2_2x/Camera.c139
-rw-r--r--source/blender/python/api2_2x/Constraint.c901
-rw-r--r--source/blender/python/api2_2x/CurNurb.c73
-rw-r--r--source/blender/python/api2_2x/Curve.c188
-rw-r--r--source/blender/python/api2_2x/Draw.c437
-rw-r--r--source/blender/python/api2_2x/Draw.h8
-rw-r--r--source/blender/python/api2_2x/Effect.c266
-rw-r--r--source/blender/python/api2_2x/Font.c33
-rw-r--r--source/blender/python/api2_2x/Geometry.c57
-rw-r--r--[-rwxr-xr-x]source/blender/python/api2_2x/Group.c34
-rw-r--r--source/blender/python/api2_2x/IDProp.c63
-rw-r--r--source/blender/python/api2_2x/Image.c373
-rw-r--r--source/blender/python/api2_2x/Ipo.c38
-rw-r--r--source/blender/python/api2_2x/Ipocurve.c82
-rw-r--r--source/blender/python/api2_2x/Ipocurve.h2
-rw-r--r--source/blender/python/api2_2x/Key.c106
-rw-r--r--source/blender/python/api2_2x/Lamp.c290
-rw-r--r--source/blender/python/api2_2x/Lattice.c10
-rw-r--r--source/blender/python/api2_2x/Library.c44
-rw-r--r--source/blender/python/api2_2x/Makefile12
-rw-r--r--source/blender/python/api2_2x/Material.c524
-rw-r--r--source/blender/python/api2_2x/Mathutils.c20
-rw-r--r--source/blender/python/api2_2x/Mathutils.h2
-rw-r--r--source/blender/python/api2_2x/Mesh.c1208
-rw-r--r--source/blender/python/api2_2x/Metaball.c24
-rw-r--r--source/blender/python/api2_2x/Modifier.c72
-rw-r--r--source/blender/python/api2_2x/NLA.c66
-rw-r--r--source/blender/python/api2_2x/NMesh.c42
-rw-r--r--source/blender/python/api2_2x/Node.c722
-rw-r--r--source/blender/python/api2_2x/Node.h16
-rw-r--r--source/blender/python/api2_2x/Noise.c4
-rw-r--r--source/blender/python/api2_2x/Object.c254
-rw-r--r--source/blender/python/api2_2x/Pose.c125
-rw-r--r--source/blender/python/api2_2x/Scene.c119
-rw-r--r--source/blender/python/api2_2x/Sound.c61
-rw-r--r--source/blender/python/api2_2x/SurfNurb.c20
-rw-r--r--source/blender/python/api2_2x/Sys.c54
-rw-r--r--source/blender/python/api2_2x/Text.c47
-rw-r--r--source/blender/python/api2_2x/Text3d.c18
-rw-r--r--source/blender/python/api2_2x/Texture.c455
-rw-r--r--source/blender/python/api2_2x/Types.c2
-rw-r--r--source/blender/python/api2_2x/Window.c300
-rw-r--r--source/blender/python/api2_2x/World.c80
-rw-r--r--source/blender/python/api2_2x/bpy_config.c19
-rw-r--r--source/blender/python/api2_2x/bpy_data.c59
-rw-r--r--source/blender/python/api2_2x/doc/Armature.py20
-rw-r--r--source/blender/python/api2_2x/doc/BGL.py15
-rw-r--r--source/blender/python/api2_2x/doc/Blender.py12
-rw-r--r--source/blender/python/api2_2x/doc/Constraint.py58
-rw-r--r--source/blender/python/api2_2x/doc/Curve.py8
-rw-r--r--source/blender/python/api2_2x/doc/Draw.py24
-rw-r--r--source/blender/python/api2_2x/doc/Font.py8
-rw-r--r--source/blender/python/api2_2x/doc/Geometry.py7
-rw-r--r--source/blender/python/api2_2x/doc/Group.py6
-rw-r--r--source/blender/python/api2_2x/doc/Image.py41
-rw-r--r--source/blender/python/api2_2x/doc/Ipo.py12
-rw-r--r--source/blender/python/api2_2x/doc/Key.py38
-rw-r--r--source/blender/python/api2_2x/doc/Lamp.py9
-rw-r--r--source/blender/python/api2_2x/doc/LibData.py8
-rw-r--r--source/blender/python/api2_2x/doc/Material.py1
-rw-r--r--source/blender/python/api2_2x/doc/Mathutils.py10
-rw-r--r--source/blender/python/api2_2x/doc/Mesh.py58
-rw-r--r--source/blender/python/api2_2x/doc/Modifier.py7
-rw-r--r--source/blender/python/api2_2x/doc/NLA.py1
-rw-r--r--source/blender/python/api2_2x/doc/Object.py3
-rw-r--r--source/blender/python/api2_2x/doc/Pose.py14
-rw-r--r--source/blender/python/api2_2x/doc/Render.py136
-rw-r--r--source/blender/python/api2_2x/doc/Scene.py12
-rw-r--r--source/blender/python/api2_2x/doc/Text3d.py4
-rw-r--r--source/blender/python/api2_2x/doc/Texture.py10
-rw-r--r--source/blender/python/api2_2x/doc/Window.py40
-rw-r--r--source/blender/python/api2_2x/doc/epy_docgen-3.sh12
-rw-r--r--source/blender/python/api2_2x/euler.c2
-rw-r--r--source/blender/python/api2_2x/gen_library.c12
-rw-r--r--source/blender/python/api2_2x/gen_library.h4
-rw-r--r--source/blender/python/api2_2x/gen_utils.c72
-rw-r--r--source/blender/python/api2_2x/gen_utils.h3
-rw-r--r--source/blender/python/api2_2x/logic.c82
-rw-r--r--source/blender/python/api2_2x/matrix.c19
-rw-r--r--source/blender/python/api2_2x/quat.c6
-rw-r--r--source/blender/python/api2_2x/rgbTuple.c40
-rw-r--r--source/blender/python/api2_2x/sceneRender.c1383
-rw-r--r--source/blender/python/api2_2x/sceneRender.h14
-rw-r--r--source/blender/python/api2_2x/sceneSequence.c124
-rw-r--r--source/blender/python/api2_2x/sceneSequence.h2
-rw-r--r--source/blender/python/api2_2x/vector.c8
-rw-r--r--source/blender/python/api2_2x/windowTheme.c25
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c43
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c19
-rw-r--r--source/blender/radiosity/intern/source/Makefile4
-rw-r--r--source/blender/radiosity/intern/source/radfactors.c10
-rw-r--r--source/blender/radiosity/intern/source/radrender.c393
-rw-r--r--source/blender/readblenfile/intern/Makefile4
-rw-r--r--source/blender/readblenfile/stub/Makefile4
-rw-r--r--source/blender/readblenfile/test/Makefile4
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h31
-rw-r--r--source/blender/render/extern/include/RE_raytrace.h114
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h6
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h26
-rw-r--r--source/blender/render/intern/include/occlusion.h49
-rw-r--r--source/blender/render/intern/include/pixelblending.h2
-rw-r--r--source/blender/render/intern/include/render_types.h196
-rw-r--r--source/blender/render/intern/include/rendercore.h15
-rw-r--r--source/blender/render/intern/include/renderdatabase.h92
-rw-r--r--source/blender/render/intern/include/shadbuf.h9
-rw-r--r--source/blender/render/intern/include/shading.h18
-rw-r--r--source/blender/render/intern/include/strand.h116
-rw-r--r--source/blender/render/intern/include/zbuf.h59
-rw-r--r--source/blender/render/intern/source/Makefile5
-rw-r--r--source/blender/render/intern/source/convertblender.c5202
-rw-r--r--source/blender/render/intern/source/envmap.c159
-rw-r--r--source/blender/render/intern/source/imagetexture.c42
-rw-r--r--source/blender/render/intern/source/initrender.c23
-rw-r--r--source/blender/render/intern/source/occlusion.c1760
-rw-r--r--source/blender/render/intern/source/pipeline.c574
-rw-r--r--source/blender/render/intern/source/pixelblending.c125
-rw-r--r--source/blender/render/intern/source/pixelshading.c11
-rw-r--r--source/blender/render/intern/source/ray.c2469
-rw-r--r--source/blender/render/intern/source/rayshade.c2112
-rw-r--r--source/blender/render/intern/source/raytrace.c1439
-rw-r--r--source/blender/render/intern/source/rendercore.c1157
-rw-r--r--source/blender/render/intern/source/renderdatabase.c1092
-rw-r--r--source/blender/render/intern/source/shadbuf.c436
-rw-r--r--source/blender/render/intern/source/shadeinput.c668
-rw-r--r--source/blender/render/intern/source/shadeoutput.c243
-rw-r--r--source/blender/render/intern/source/sss.c48
-rw-r--r--source/blender/render/intern/source/strand.c1012
-rw-r--r--source/blender/render/intern/source/texture.c214
-rw-r--r--source/blender/render/intern/source/zbuf.c1894
-rw-r--r--source/blender/src/CMakeLists.txt4
-rw-r--r--source/blender/src/Makefile12
-rw-r--r--source/blender/src/SConscript28
-rw-r--r--source/blender/src/blenderbuttons.c2071
-rw-r--r--source/blender/src/booleanops.c23
-rw-r--r--source/blender/src/butspace.c7
-rw-r--r--source/blender/src/buttons_editing.c1556
-rw-r--r--source/blender/src/buttons_logic.c68
-rw-r--r--source/blender/src/buttons_object.c4086
-rw-r--r--source/blender/src/buttons_scene.c1179
-rw-r--r--source/blender/src/buttons_script.c16
-rw-r--r--source/blender/src/buttons_shading.c892
-rw-r--r--source/blender/src/drawaction.c1489
-rw-r--r--source/blender/src/drawarmature.c1439
-rw-r--r--source/blender/src/drawimage.c1611
-rw-r--r--source/blender/src/drawimasel.c1358
-rw-r--r--source/blender/src/drawipo.c189
-rw-r--r--source/blender/src/drawmesh.c463
-rw-r--r--source/blender/src/drawnla.c83
-rw-r--r--source/blender/src/drawnode.c1210
-rw-r--r--source/blender/src/drawobject.c1746
-rw-r--r--source/blender/src/drawoops.c183
-rw-r--r--source/blender/src/drawscene.c11
-rw-r--r--source/blender/src/drawscript.c39
-rw-r--r--source/blender/src/drawseq.c645
-rw-r--r--source/blender/src/drawsound.c15
-rw-r--r--source/blender/src/drawtext.c291
-rw-r--r--source/blender/src/drawtime.c330
-rw-r--r--source/blender/src/drawview.c711
-rw-r--r--source/blender/src/edit.c285
-rw-r--r--source/blender/src/editaction.c7019
-rw-r--r--source/blender/src/editarmature.c2789
-rw-r--r--source/blender/src/editconstraint.c1128
-rw-r--r--source/blender/src/editcurve.c1299
-rw-r--r--source/blender/src/editdeform.c98
-rw-r--r--source/blender/src/editface.c646
-rw-r--r--source/blender/src/editfont.c6
-rw-r--r--source/blender/src/editgroup.c84
-rw-r--r--source/blender/src/editimasel.c1338
-rw-r--r--source/blender/src/editipo.c2358
-rw-r--r--source/blender/src/editipo_lib.c74
-rw-r--r--source/blender/src/editipo_mods.c159
-rw-r--r--source/blender/src/editkey.c55
-rw-r--r--source/blender/src/editlattice.c45
-rw-r--r--source/blender/src/editmball.c54
-rw-r--r--source/blender/src/editmesh.c233
-rw-r--r--source/blender/src/editmesh_add.c31
-rw-r--r--source/blender/src/editmesh_lib.c231
-rw-r--r--source/blender/src/editmesh_loop.c9
-rw-r--r--source/blender/src/editmesh_mods.c843
-rw-r--r--source/blender/src/editmesh_tools.c553
-rw-r--r--source/blender/src/editmode_undo.c12
-rw-r--r--source/blender/src/editnla.c503
-rw-r--r--source/blender/src/editnode.c376
-rw-r--r--source/blender/src/editobject.c1124
-rw-r--r--source/blender/src/editparticle.c3193
-rw-r--r--source/blender/src/editscreen.c66
-rw-r--r--source/blender/src/editseq.c2105
-rw-r--r--source/blender/src/editsima.c2211
-rw-r--r--source/blender/src/editsound.c31
-rw-r--r--source/blender/src/edittime.c140
-rw-r--r--source/blender/src/editview.c234
-rw-r--r--source/blender/src/filelist.c1137
-rw-r--r--source/blender/src/filesel.c357
-rw-r--r--source/blender/src/fluidsim.c16
-rw-r--r--source/blender/src/fsmenu.c257
-rw-r--r--source/blender/src/ghostwinlay.c14
-rw-r--r--source/blender/src/glutil.c21
-rw-r--r--source/blender/src/hddaudio.c93
-rw-r--r--source/blender/src/header_action.c1047
-rw-r--r--source/blender/src/header_buttonswin.c13
-rw-r--r--source/blender/src/header_filesel.c22
-rw-r--r--source/blender/src/header_image.c328
-rw-r--r--source/blender/src/header_imasel.c142
-rw-r--r--source/blender/src/header_info.c478
-rw-r--r--source/blender/src/header_ipo.c111
-rw-r--r--source/blender/src/header_nla.c87
-rw-r--r--source/blender/src/header_node.c56
-rw-r--r--source/blender/src/header_oops.c7
-rw-r--r--source/blender/src/header_script.c2
-rw-r--r--source/blender/src/header_seq.c276
-rw-r--r--source/blender/src/header_sound.c6
-rw-r--r--source/blender/src/header_text.c190
-rw-r--r--source/blender/src/header_time.c34
-rw-r--r--source/blender/src/header_view3d.c1301
-rw-r--r--source/blender/src/headerbuttons.c109
-rw-r--r--source/blender/src/imagepaint.c3
-rw-r--r--source/blender/src/imasel.c861
-rw-r--r--source/blender/src/interface.c171
-rw-r--r--source/blender/src/interface_draw.c147
-rw-r--r--source/blender/src/interface_icons.c320
-rw-r--r--source/blender/src/interface_panel.c11
-rw-r--r--source/blender/src/language.c77
-rw-r--r--source/blender/src/meshlaplacian.c1911
-rw-r--r--source/blender/src/meshtools.c309
-rw-r--r--source/blender/src/multires.c1426
-rw-r--r--source/blender/src/oops.c30
-rw-r--r--source/blender/src/outliner.c475
-rw-r--r--source/blender/src/parametrizer.c132
-rw-r--r--source/blender/src/parametrizer.h4
-rw-r--r--source/blender/src/playanim.c64
-rw-r--r--source/blender/src/poselib.c1333
-rw-r--r--source/blender/src/poseobject.c941
-rw-r--r--source/blender/src/preview.blend.c25128
-rw-r--r--source/blender/src/previewrender.c11
-rw-r--r--source/blender/src/prvicons.c436
-rw-r--r--source/blender/src/radialcontrol.c267
-rw-r--r--source/blender/src/reeb.c1923
-rw-r--r--source/blender/src/renderwin.c287
-rw-r--r--source/blender/src/resources.c100
-rw-r--r--source/blender/src/retopo.c33
-rw-r--r--source/blender/src/sculptmode-stroke.c284
-rw-r--r--source/blender/src/sculptmode.c1441
-rw-r--r--source/blender/src/seqaudio.c54
-rw-r--r--source/blender/src/seqeffects.c307
-rw-r--r--source/blender/src/seqscopes.c429
-rw-r--r--source/blender/src/sequence.c2167
-rw-r--r--source/blender/src/space.c1506
-rw-r--r--source/blender/src/spacetypes.c15
-rw-r--r--source/blender/src/splash.jpg.c9868
-rw-r--r--source/blender/src/toets.c60
-rw-r--r--source/blender/src/toolbox.c191
-rw-r--r--[-rwxr-xr-x]source/blender/src/transform.c1765
-rw-r--r--[-rwxr-xr-x]source/blender/src/transform_constraints.c90
-rw-r--r--source/blender/src/transform_conversions.c1978
-rw-r--r--source/blender/src/transform_generics.c318
-rw-r--r--source/blender/src/transform_manipulator.c139
-rw-r--r--source/blender/src/transform_orientations.c643
-rw-r--r--source/blender/src/transform_snap.c349
-rw-r--r--source/blender/src/unwrapper.c148
-rw-r--r--source/blender/src/usiblender.c197
-rw-r--r--source/blender/src/verse_mesh.c3
-rw-r--r--source/blender/src/verse_object.c1
-rw-r--r--source/blender/src/view.c94
-rw-r--r--source/blender/src/vpaint.c91
-rw-r--r--source/blender/src/winlay.h6
-rw-r--r--source/blender/src/writeimage.c6
-rw-r--r--source/blender/verify/intern/Makefile4
-rw-r--r--source/blender/yafray/YafRay_Api.h2
-rw-r--r--source/blender/yafray/intern/Makefile4
-rw-r--r--[-rwxr-xr-x]source/blender/yafray/intern/api.cpp2
-rw-r--r--[-rwxr-xr-x]source/blender/yafray/intern/export_File.cpp22
-rw-r--r--[-rwxr-xr-x]source/blender/yafray/intern/export_File.h2
-rw-r--r--source/blender/yafray/intern/export_Plugin.cpp57
-rw-r--r--source/blender/yafray/intern/export_Plugin.h12
-rw-r--r--source/blender/yafray/intern/yafray_Render.cpp146
-rw-r--r--source/blender/yafray/intern/yafray_Render.h12
-rw-r--r--source/creator/CMakeLists.txt12
-rw-r--r--source/creator/Makefile9
-rw-r--r--source/creator/SConscript4
-rw-r--r--source/creator/buildinfo.c1
-rw-r--r--source/creator/creator.c165
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp41
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp4
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp33
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h10
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp3
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp37
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp2
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp155
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h14
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp85
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp2
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.cpp7
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp7
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp42
-rw-r--r--source/gameengine/Expressions/Expression.cpp4
-rw-r--r--source/gameengine/Expressions/Value.cpp86
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt1
-rw-r--r--source/gameengine/GameLogic/Makefile1
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp118
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h44
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h6
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp9
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp34
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp34
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h1
-rw-r--r--[-rwxr-xr-x]source/gameengine/GameLogic/SConscript1
-rw-r--r--source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp2
-rw-r--r--source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp4
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp33
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h9
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp10
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp30
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp4
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp4
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h1
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp49
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.cpp134
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.h36
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h2
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp59
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp24
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h4
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp47
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp36
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h1
-rw-r--r--source/gameengine/Ketsji/KX_RayCast.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp138
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h36
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h7
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h8
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp7
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp147
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h18
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp182
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h20
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp2
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h5
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h1
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp340
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h91
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h21
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h19
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h (renamed from intern/action/test/action_c_test/TestAction.c)45
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h (renamed from intern/action/test/action_cpp_test/TestAction.h)44
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h53
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h (renamed from intern/action/intern/ACT_Action.cpp)44
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h (renamed from intern/keymaker/mt19937int.h)26
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h56
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h61
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h (renamed from intern/action/test/action_c_test/TestAction.h)31
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h55
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h60
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp122
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h18
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp20
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h20
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.cpp5
-rw-r--r--source/gameengine/SceneGraph/SG_Node.h2
-rw-r--r--source/kernel/gen_messaging/intern/Makefile4
-rw-r--r--source/nan_compile.mk81
-rw-r--r--source/nan_definitions.mk93
-rw-r--r--source/nan_link.mk16
-rw-r--r--tools/Blender.py17
-rwxr-xr-xtools/btools.py23
1174 files changed, 178390 insertions, 78741 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 978b3cd339e..a758c2a09d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,8 +65,9 @@ OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON)
OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF)
OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" OFF)
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
-OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
-OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
+OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
+OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
+OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
@@ -183,6 +184,13 @@ IF(UNIX)
SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++")
+ IF(WITH_OPENMP)
+ SET(LLIBS "${LLIBS} -lgomp ")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
+ ENDIF(WITH_OPENMP)
+
+
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts")
SET(PLATFORM_LINKFLAGS "-pthread")
@@ -239,7 +247,11 @@ IF(WIN32)
SET(OPENEXR ${LIBDIR}/openexr)
SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath)
SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread)
+ IF (MSVC80)
+ SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005)
+ ELSE (MSVC80)
SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc)
+ ENDIF(MSVC80)
SET(QUICKTIME ${LIBDIR}/QTDevWin)
SET(QUICKTIME_INC ${QUICKTIME}/CIncludes)
@@ -265,6 +277,11 @@ IF(WIN32)
SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
+ IF(WITH_OPENMP)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ")
+ ENDIF(WITH_OPENMP)
+
SET(SDL ${LIBDIR}/sdl)
SET(SDL_INC ${SDL}/include)
SET(SDL_LIB SDL)
@@ -342,6 +359,12 @@ IF(APPLE)
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")
+ IF(WITH_OPENMP)
+ SET(LLIBS "${LLIBS} -lgomp ")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
+ ENDIF(WITH_OPENMP)
+
SET(SDL ${LIBDIR}/sdl)
SET(SDL_INC ${SDL}/include)
SET(SDL_LIB SDL)
@@ -361,6 +384,11 @@ IF(APPLE)
SET(EXETYPE MACOSX_BUNDLE)
ENDIF(APPLE)
+IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc)
+ SET(BINRELOC_INC ${BINRELOC}/include)
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+
#-----------------------------------------------------------------------------
# Common.
SET(VERSE_INC ${CMAKE_SOURCE_DIR}/extern/verse/dist)
@@ -379,6 +407,9 @@ INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
IF(WITH_GAMEENGINE)
SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DGAMEBLENDER ")
ENDIF(WITH_GAMEENGINE)
+IF(WITH_BULLET)
+ SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DWITH_BULLET ")
+ENDIF(WITH_BULLET)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS} ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ")
diff --git a/Makefile b/Makefile
index b77adf82cfb..1189a3abeea 100644
--- a/Makefile
+++ b/Makefile
@@ -47,10 +47,15 @@ MAKEFLAGS=-I$(NANBLENDERHOME)/source --no-print-directory
SOURCEDIR =
ifeq ($(FREE_WINDOWS),true)
- DIRS ?= dlltool extern intern source po
+ DIRS ?= dlltool extern intern source
+endif
+
+DIRS ?= extern intern source
+
+ifneq ($(INTERNATIONAL),false)
+ DIRS += po
endif
-DIRS ?= extern intern source po
include source/nan_subdirs.mk
.PHONY: release
diff --git a/SConstruct b/SConstruct
index 7e9e0344c3a..3ee56f7cff1 100644
--- a/SConstruct
+++ b/SConstruct
@@ -170,12 +170,32 @@ else:
opts = btools.read_opts(optfiles, B.arguments)
opts.Update(env)
+if not env['BF_FANCY']:
+ B.bc.disable()
+
# disable elbeem (fluidsim) compilation?
if env['BF_NO_ELBEEM'] == 1:
env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
+if env['WITH_BF_OPENMP'] == 1:
+ if env['OURPLATFORM']=='win32-vc':
+ env['CCFLAGS'].append('/openmp')
+ env['CPPFLAGS'].append('/openmp')
+ env['CXXFLAGS'].append('/openmp')
+ else:
+ if env['CC'] == 'icc':
+ env.Append(LINKFLAGS=['-openmp', '-static-intel'])
+ env['CCFLAGS'].append('-openmp')
+ env['CPPFLAGS'].append('-openmp')
+ env['CXXFLAGS'].append('-openmp')
+ else:
+ env.Append(LINKFLAGS=['-lgomp'])
+ env['CCFLAGS'].append('-fopenmp')
+ env['CPPFLAGS'].append('-fopenmp')
+ env['CXXFLAGS'].append('-fopenmp')
+
#check for additional debug libnames
if env.has_key('BF_DEBUG_LIBS'):
@@ -241,13 +261,16 @@ if 'clean' in B.targets:
do_clean = True
if not quickie and do_clean:
- print B.bc.HEADER+'Cleaning...'+B.bc.ENDC
- dirs = os.listdir(B.root_build_dir)
- for dir in dirs:
- if os.path.isdir(B.root_build_dir + dir) == 1:
- print "clean dir %s"%(B.root_build_dir+dir)
- shutil.rmtree(B.root_build_dir+dir)
- print B.bc.OKGREEN+'...done'+B.bc.ENDC
+ if os.path.exists(B.root_build_dir):
+ print B.bc.HEADER+'Cleaning...'+B.bc.ENDC
+ dirs = os.listdir(B.root_build_dir)
+ for dir in dirs:
+ if os.path.isdir(B.root_build_dir + dir) == 1:
+ print "clean dir %s"%(B.root_build_dir+dir)
+ shutil.rmtree(B.root_build_dir+dir)
+ print B.bc.OKGREEN+'...done'+B.bc.ENDC
+ else:
+ print B.bc.HEADER+'Already Clean, nothing to do.'+B.bc.ENDC
Exit()
if not os.path.isdir ( B.root_build_dir):
@@ -390,12 +413,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
dllsources = ['${LCGDIR}/gettext/lib/gnu_gettext.dll',
'${LCGDIR}/png/lib/libpng.dll',
'#release/windows/extra/python25.zip',
-# '#release/windows/extra/zlib.pyd',
+ '#release/windows/extra/zlib.pyd',
'${LCGDIR}/sdl/lib/SDL.dll',
'${LCGDIR}/zlib/lib/zlib.dll',
'${LCGDIR}/tiff/lib/libtiff.dll']
if env['BF_DEBUG']:
- dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
+ dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}_d.dll')
else:
dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
if env['OURPLATFORM'] == 'win32-mingw':
@@ -404,10 +427,10 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
dllsources += ['${LCGDIR}/pthreads/lib/pthreadVC2.dll']
if env['WITH_BF_ICONV']:
dllsources += ['${LCGDIR}/iconv/lib/iconv.dll']
- if env['WITH_BF_FFMPEG']:
- dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-51.dll',
- '${LCGDIR}/ffmpeg/lib/avformat-51.dll',
- '${LCGDIR}/ffmpeg/lib/avutil-49.dll']
+# if env['WITH_BF_FFMPEG']:
+# dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-51.dll',
+# '${LCGDIR}/ffmpeg/lib/avformat-51.dll',
+# '${LCGDIR}/ffmpeg/lib/avutil-49.dll']
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
allinstall += windlls
@@ -429,7 +452,9 @@ if not env['WITH_BF_GAMEENGINE']:
Depends(nsiscmd, allinstall)
Default(B.program_list)
-Default(installtarget)
+
+if not env['WITHOUT_BF_INSTALL']:
+ Default(installtarget)
#------------ RELEASE
# TODO: zipup the installation
diff --git a/bin/.blender/.Blanguages b/bin/.blender/.Blanguages
index be5e397b149..7b59bfcd3f0 100644
--- a/bin/.blender/.Blanguages
+++ b/bin/.blender/.Blanguages
@@ -19,3 +19,4 @@ Polish:pl_PL
Romanian:ro
Arabic:ar
Bulgarian:bg
+Greek:el
diff --git a/config/darwin-config.py b/config/darwin-config.py
index 1071adb222f..df4b3235136 100644
--- a/config/darwin-config.py
+++ b/config/darwin-config.py
@@ -54,6 +54,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
diff --git a/config/linux2-config.py b/config/linux2-config.py
index a041f518ba7..4d8b5c97512 100644
--- a/config/linux2-config.py
+++ b/config/linux2-config.py
@@ -29,8 +29,14 @@ BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
BF_OPENEXR = '/usr'
+# when compiling with your own openexr lib you might need to set...
+# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
+
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
+# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+
+WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr'
@@ -112,12 +118,17 @@ BF_ICONV_INC = '${BF_ICONV}/include'
BF_ICONV_LIB = 'iconv'
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
+WITH_BF_BINRELOC = 'true'
+
# enable ffmpeg support
-WITH_BF_FFMPEG = 'false' # -DWITH_FFMPEG
-BF_FFMPEG = '/usr'
+WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG
+BF_FFMPEG = '#extern/ffmpeg'
+BF_FFMPEG_LIB = ''
+# Uncomment the following two lines to use system's ffmpeg
+# BF_FFMPEG = '/usr'
+# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil'
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avformat avcodec avutil'
# Mesa Libs should go here if your using them as well....
WITH_BF_STATICOPENGL = 'false'
diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py
index 1c2288a8430..e6c4e8769b4 100644
--- a/config/linuxcross-config.py
+++ b/config/linuxcross-config.py
@@ -39,6 +39,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py
index b3579d4ac65..f7f254973af 100644
--- a/config/openbsd3-config.py
+++ b/config/openbsd3-config.py
@@ -28,6 +28,8 @@ BF_OPENEXR = '/usr/local'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr/local'
BF_JPEG_INC = '${BF_JPEG}/include'
diff --git a/config/sunos5-config.py b/config/sunos5-config.py
index 7939e210993..b3ca0e267ff 100644
--- a/config/sunos5-config.py
+++ b/config/sunos5-config.py
@@ -29,6 +29,8 @@ BF_OPENEXR_INC = ['${BF_OPENEXR}/include', '${BF_OPENEXR}/include/OpenEXR' ]
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr/local'
BF_JPEG_INC = '${BF_JPEG}/include'
diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py
index 95c096c4bac..d9fd6ce8d4f 100644
--- a/config/win32-mingw-config.py
+++ b/config/win32-mingw-config.py
@@ -14,11 +14,11 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include'
-BF_OPENAL_LIB = 'openal_static'
+BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_FFMPEG = 'false'
-BF_FFMPEG_LIB = 'avformat avutil avcodec'
+BF_FFMPEG_LIB = 'avformat swscale avcodec avutil xvidcore x264'
BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib'
BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include'
@@ -42,6 +42,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
@@ -60,7 +62,6 @@ BF_TIFF_INC = '${BF_TIFF}/include'
WITH_BF_ZLIB = 'true'
BF_ZLIB = LIBDIR + '/zlib'
BF_ZLIB_INC = '${BF_ZLIB}/include'
-#BF_ZLIB_LIB = 'z'
BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = 'true'
@@ -109,9 +110,6 @@ WITH_BF_YAFRAY = 'true'
#BF_MOZILLA_LIB =
# Will fall back to look in BF_MOZILLA_INC/nspr and BF_MOZILLA_LIB
# if this is not set.
-#
-# Be paranoid regarding library creation (do not update archives)
-#BF_PARANOID = 'true'
# enable freetype2 support for text objects
BF_FREETYPE = LIBDIR + '/gcc/freetype'
@@ -141,8 +139,6 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
##
CC = 'gcc'
CXX = 'g++'
-##ifeq ($CPU),alpha)
-## CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -mieee
CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
@@ -150,24 +146,18 @@ CPPFLAGS = [ '-DXP_UNIX', '-DWIN32', '-DFREE_WINDOWS' ]
CXXFLAGS = ['-pipe', '-mwindows', '-funsigned-char', '-fno-strict-aliasing' ]
REL_CFLAGS = [ '-O2' ]
REL_CCFLAGS = [ '-O2' ]
-##BF_DEPEND = 'true'
-##
-##AR = ar
-##ARFLAGS = ruv
-##ARFLAGSQUIET = ru
-##
+
C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
CC_WARN = [ '-Wall' ]
-##FIX_STUBS_WARNINGS = -Wno-unused
-
-LLIBS = ['-lshell32', '-lshfolder', '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread']
-##LOPTS = --dynamic
-##DYNLDFLAGS = -shared $(LDFLAGS)
+LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++']
BF_DEBUG = 'false'
BF_DEBUG_FLAGS= '-g'
+BF_PROFILE_FLAGS = ['-pg','-g']
+BF_PROFILE = 'false'
+
BF_BUILDDIR = '..\\build\\win32-mingw'
BF_INSTALLDIR='..\\install\\win32-mingw'
diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py
index 7e0d98c072b..1b75f981a37 100644
--- a/config/win32-vc-config.py
+++ b/config/win32-vc-config.py
@@ -21,7 +21,7 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include ${BF_OPENAL}/include/AL '
-BF_OPENAL_LIB = 'openal_static'
+BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_ICONV = 'true'
@@ -50,6 +50,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEX
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_msvc'
+WITH_BF_DDS = 'true'
+
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
@@ -104,6 +106,8 @@ BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE'
WITH_BF_YAFRAY = 'true'
+WITH_BF_BINRELOC = 'false'
+
#WITH_BF_NSPR = 'true'
#BF_NSPR = $(LIBDIR)/nspr
#BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr
@@ -145,15 +149,15 @@ CXX = 'cl.exe'
CCFLAGS = ['/nologo', '/Og', '/Ot', '/Ob1', '/Op', '/G6','/EHsc', '/J', '/W3', '/Gd', '/MT']
-BF_DEBUG_FLAGS = ['/Zi', '/FR${TARGET.base}.sbr']
+BF_DEBUG_FLAGS = ['/Zi', '/FR${TARGET}.sbr']
-CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DUSE_OPENAL', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
+CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
REL_CFLAGS = ['-O2', '-DNDEBUG']
REL_CCFLAGS = ['-O2', '-DNDEBUG']
C_WARN = []
CC_WARN = []
-LLIBS = 'ws2_32 dxguid vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid'
+LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid'
PLATFORM_LINKFLAGS = '''
/SUBSYSTEM:CONSOLE
diff --git a/doc/blender-scons.txt b/doc/blender-scons.txt
index 66f7edef292..8c71c31db0c 100644
--- a/doc/blender-scons.txt
+++ b/doc/blender-scons.txt
@@ -1,6 +1,6 @@
$Id$
- Note: The current official release of SCons is 0.96.1
+ Note: The current official release of SCons is 0.97
Blenders SCons build scripts
============================
@@ -29,7 +29,7 @@ $Id$
To build Blender with the SCons scripts you need a full Python
install, version 2.4 or later (http://www.python.org) and a SCons
- installation, version v0.96.1 (http://www.scons.org).
+ installation, version v0.97 (http://www.scons.org).
Check from the page
http://www.blender.org/development/building-blender/getting-dependencies/
@@ -160,6 +160,17 @@ $Id$
for example, setting BF_QUICKDEBUG won't overwrite the contents of BF_DEBUG_LIBS.
+ Not installing
+ --------------
+
+ If you dont want to install the build result, you can use the following option either
+ on the commandline or in your user-config.py :
+
+ WITHOUT_BF_INSTALL='true'
+
+ by default, this is set to 'false', and so the build is installed
+
+
Supported toolset
-----------------
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 0f07bde72d5..8d2e1f9dc9b 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -29,11 +29,11 @@
IF(WITH_GAMEENGINE)
SUBDIRS(qhull solid)
+ENDIF(WITH_GAMEENGINE)
- IF(WITH_BULLET)
+IF(WITH_BULLET)
SUBDIRS(bullet2)
- ENDIF(WITH_BULLET)
-ENDIF(WITH_GAMEENGINE)
+ENDIF(WITH_BULLET)
IF(WITH_INTERNATIONAL)
SUBDIRS(bFTGL)
@@ -43,3 +43,6 @@ IF(WITH_VERSE)
SUBDIRS(verse)
ENDIF(WITH_VERSE)
+IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ SUBDIRS(binreloc)
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
diff --git a/extern/Makefile b/extern/Makefile
index 04b282a8926..4ca63b6e7f9 100644
--- a/extern/Makefile
+++ b/extern/Makefile
@@ -56,6 +56,10 @@ ifneq ($(NAN_NO_KETSJI), true)
DIRS += bullet2
endif
+ifeq ($(WITH_BINRELOC), true)
+ DIRS += binreloc
+endif
+
TARGET =
ifneq ($(OS),irix)
TARGET=solid
diff --git a/extern/SConscript b/extern/SConscript
index 0cdf9676862..bcf67055788 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -5,11 +5,18 @@ Import('env')
if env['WITH_BF_GAMEENGINE']:
SConscript(['qhull/SConscript',
'solid/SConscript'])
- if env['WITH_BF_BULLET']:
- SConscript(['bullet2/src/SConscript'])
+
+if env['WITH_BF_BULLET']:
+ SConscript(['bullet2/src/SConscript'])
if env['WITH_BF_INTERNATIONAL']:
SConscript(['bFTGL/SConscript'])
if env['WITH_BF_VERSE']:
SConscript(['verse/dist/SConstruct'])
+
+if env['WITH_BF_FFMPEG'] and env['BF_FFMPEG_LIB'] == '':
+ SConscript(['ffmpeg/SConscript']);
+
+if env['OURPLATFORM'] == 'linux2':
+ SConscript(['binreloc/SConscript']); \ No newline at end of file
diff --git a/extern/bFTGL/include/FTGL.h b/extern/bFTGL/include/FTGL.h
index e92bd526012..2b76de8b8bd 100755..100644
--- a/extern/bFTGL/include/FTGL.h
+++ b/extern/bFTGL/include/FTGL.h
@@ -42,7 +42,11 @@ typedef float FTGL_FLOAT;
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
- #include <GL/glu.h>
+ #if defined (__sun__) && !defined (__sparc__)
+ #include <mesa/glu.h>
+ #else
+ #include <GL/glu.h>
+ #endif
#endif
#endif
diff --git a/extern/bFTGL/src/FTVectoriser.cpp b/extern/bFTGL/src/FTVectoriser.cpp
index bb133d025b4..82dcb0c0f51 100644
--- a/extern/bFTGL/src/FTVectoriser.cpp
+++ b/extern/bFTGL/src/FTVectoriser.cpp
@@ -5,8 +5,12 @@
#define CALLBACK
#endif
-#ifdef __APPLE_CC__
- typedef GLvoid (*GLUTesselatorFunction)(...);
+#if defined(__APPLE_CC__)
+ #if __APPLE_CC__ >= 5465
+ typedef GLvoid (*GLUTesselatorFunction)();
+ #else
+ typedef GLvoid (*GLUTesselatorFunction)(...);
+ #endif
#elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__)
typedef GLvoid (*GLUTesselatorFunction)();
#elif defined ( WIN32)
diff --git a/extern/bFTGL/src/Makefile b/extern/bFTGL/src/Makefile
index 064480fbd16..3ebf9bee45c 100644
--- a/extern/bFTGL/src/Makefile
+++ b/extern/bFTGL/src/Makefile
@@ -46,7 +46,8 @@ CCSRCS = FTBitmapGlyph.cpp FTCharmap.cpp FTContour.cpp FTExtrdGlyph.cpp \
include nan_compile.mk
CPPFLAGS += -I../include
-CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2
+CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2
+CPPFLAGS += -I$(OPENGL_HEADERS)
install: all debug
@[ -d $(NAN_FTGL) ] || mkdir -p $(NAN_FTGL)
diff --git a/extern/binreloc/CMakeLists.txt b/extern/binreloc/CMakeLists.txt
new file mode 100644
index 00000000000..78dc65d8112
--- /dev/null
+++ b/extern/binreloc/CMakeLists.txt
@@ -0,0 +1,26 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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 by The Blender Foundation
+# All rights reserved.
+#
+
+SET(INC ./include ${WINTAB_INC})
+ADD_DEFINITIONS(-DWITH_BINRELOC)
+FILE(GLOB SRC *.c)
+
+BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
+#, libtype=['core','player'], priority = [25,15] )
diff --git a/extern/binreloc/Makefile b/extern/binreloc/Makefile
new file mode 100644
index 00000000000..dbd093500a1
--- /dev/null
+++ b/extern/binreloc/Makefile
@@ -0,0 +1,37 @@
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You 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 by The Blender Foundation
+# All rights reserved.
+#
+#
+
+LIBNAME = binreloc
+DIR = $(OCGDIR)/extern/$(LIBNAME)
+
+include nan_definitions.mk
+
+CPPFLAGS += -I./include
+
+
+include nan_compile.mk
+
+
+install: all debug
+ @[ -d $(DIR) ] || mkdir $(DIR)
+ @[ -d $(DIR)/include ] || mkdir $(DIR)/include
+ @../../intern/tools/cpifdiff.sh include/*.h $(DIR)/include/
diff --git a/extern/binreloc/SConscript b/extern/binreloc/SConscript
new file mode 100644
index 00000000000..2747702985d
--- /dev/null
+++ b/extern/binreloc/SConscript
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+import sys
+import os
+
+Import('env')
+defs = 'ENABLE_BINRELOC'
+cflags = []
+
+sources = ['binreloc.c']
+incs = 'include'
+
+env.BlenderLib ( 'extern_binreloc', sources, Split(incs), Split(defs), libtype=['intern','player'], priority=[36, 226], compileflags = cflags)
+
diff --git a/extern/binreloc/binreloc.c b/extern/binreloc/binreloc.c
new file mode 100644
index 00000000000..c6dc0ae709f
--- /dev/null
+++ b/extern/binreloc/binreloc.c
@@ -0,0 +1,766 @@
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_C__
+#define __BINRELOC_C__
+
+#ifdef ENABLE_BINRELOC
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+#endif /* ENABLE_BINRELOC */
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include "binreloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/** @internal
+ * Find the canonical filename of the executable. Returns the filename
+ * (which must be freed) or NULL on error. If the parameter 'error' is
+ * not NULL, the error code will be stored there, if an error occured.
+ */
+static char *
+_br_find_exe (BrInitError *error)
+{
+#ifndef ENABLE_BINRELOC
+ if (error)
+ *error = BR_INIT_ERROR_DISABLED;
+ return NULL;
+#else
+ char *path, *path2, *line, *result;
+ size_t buf_size;
+ ssize_t size;
+ struct stat stat_buf;
+ FILE *f;
+
+ /* Read from /proc/self/exe (symlink) */
+ if (sizeof (path) > SSIZE_MAX)
+ buf_size = SSIZE_MAX - 1;
+ else
+ buf_size = PATH_MAX - 1;
+ path = (char *) malloc (buf_size);
+ if (path == NULL) {
+ /* Cannot allocate memory. */
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ return NULL;
+ }
+ path2 = (char *) malloc (buf_size);
+ if (path2 == NULL) {
+ /* Cannot allocate memory. */
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ free (path);
+ return NULL;
+ }
+
+ strncpy (path2, "/proc/self/exe", buf_size - 1);
+
+ while (1) {
+ int i;
+
+ size = readlink (path2, path, buf_size - 1);
+ if (size == -1) {
+ /* Error. */
+ free (path2);
+ break;
+ }
+
+ /* readlink() success. */
+ path[size] = '\0';
+
+ /* Check whether the symlink's target is also a symlink.
+ * We want to get the final target. */
+ i = stat (path, &stat_buf);
+ if (i == -1) {
+ /* Error. */
+ free (path2);
+ break;
+ }
+
+ /* stat() success. */
+ if (!S_ISLNK (stat_buf.st_mode)) {
+ /* path is not a symlink. Done. */
+ free (path2);
+ return path;
+ }
+
+ /* path is a symlink. Continue loop and resolve this. */
+ strncpy (path, path2, buf_size - 1);
+ }
+
+
+ /* readlink() or stat() failed; this can happen when the program is
+ * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
+
+ buf_size = PATH_MAX + 128;
+ line = (char *) realloc (path, buf_size);
+ if (line == NULL) {
+ /* Cannot allocate memory. */
+ free (path);
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ return NULL;
+ }
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL) {
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_OPEN_MAPS;
+ return NULL;
+ }
+
+ /* The first entry should be the executable name. */
+ result = fgets (line, (int) buf_size, f);
+ if (result == NULL) {
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_READ_MAPS;
+ return NULL;
+ }
+
+ /* Get rid of newline character. */
+ buf_size = strlen (line);
+ if (buf_size <= 0) {
+ /* Huh? An empty string? */
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_INVALID_MAPS;
+ return NULL;
+ }
+ if (line[buf_size - 1] == 10)
+ line[buf_size - 1] = 0;
+
+ /* Extract the filename; it is always an absolute path. */
+ path = strchr (line, '/');
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || path == NULL) {
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_INVALID_MAPS;
+ return NULL;
+ }
+
+ path = strdup (path);
+ free (line);
+ fclose (f);
+ return path;
+#endif /* ENABLE_BINRELOC */
+}
+
+
+/** @internal
+ * Find the canonical filename of the executable which owns symbol.
+ * Returns a filename which must be freed, or NULL on error.
+ */
+static char *
+_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
+{
+#ifndef ENABLE_BINRELOC
+ if (error)
+ *error = BR_INIT_ERROR_DISABLED;
+ return (char *) NULL;
+#else
+ #define SIZE PATH_MAX + 100
+ FILE *f;
+ size_t address_string_len;
+ char *address_string, line[SIZE], *found;
+
+ if (symbol == NULL)
+ return (char *) NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL)
+ return (char *) NULL;
+
+ address_string_len = 4;
+ address_string = (char *) malloc (address_string_len);
+ found = (char *) NULL;
+
+ while (!feof (f)) {
+ char *start_addr, *end_addr, *end_addr_end, *file;
+ void *start_addr_p, *end_addr_p;
+ size_t len;
+
+ if (fgets (line, SIZE, f) == NULL)
+ break;
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
+ continue;
+
+ /* Parse line. */
+ start_addr = line;
+ end_addr = strchr (line, '-');
+ file = strchr (line, '/');
+
+ /* More sanity check. */
+ if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+ continue;
+
+ end_addr[0] = '\0';
+ end_addr++;
+ end_addr_end = strchr (end_addr, ' ');
+ if (end_addr_end == NULL)
+ continue;
+
+ end_addr_end[0] = '\0';
+ len = strlen (file);
+ if (len == 0)
+ continue;
+ if (file[len - 1] == '\n')
+ file[len - 1] = '\0';
+
+ /* Get rid of "(deleted)" from the filename. */
+ len = strlen (file);
+ if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
+ file[len - 10] = '\0';
+
+ /* I don't know whether this can happen but better safe than sorry. */
+ len = strlen (start_addr);
+ if (len != strlen (end_addr))
+ continue;
+
+
+ /* Transform the addresses into a string in the form of 0xdeadbeef,
+ * then transform that into a pointer. */
+ if (address_string_len < len + 3) {
+ address_string_len = len + 3;
+ address_string = (char *) realloc (address_string, address_string_len);
+ }
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, start_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &start_addr_p);
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, end_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &end_addr_p);
+
+
+ if (symbol >= start_addr_p && symbol < end_addr_p) {
+ found = file;
+ break;
+ }
+ }
+
+ free (address_string);
+ fclose (f);
+
+ if (found == NULL)
+ return (char *) NULL;
+ else
+ return strdup (found);
+#endif /* ENABLE_BINRELOC */
+}
+
+
+#ifndef BINRELOC_RUNNING_DOXYGEN
+ #undef NULL
+ #define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
+#endif
+
+static char *exe = (char *) NULL;
+
+
+/** Initialize the BinReloc library (for applications).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the application's canonical filename.
+ *
+ * @note If you want to use BinReloc for a library, then you should call
+ * br_init_lib() instead.
+ *
+ * @param error If BinReloc failed to initialize, then the error code will
+ * be stored in this variable. Set to NULL if you want to
+ * ignore this. See #BrInitError for a list of error codes.
+ *
+ * @returns 1 on success, 0 if BinReloc failed to initialize.
+ */
+int
+br_init (BrInitError *error)
+{
+ exe = _br_find_exe (error);
+ return exe != NULL;
+}
+
+
+/** Initialize the BinReloc library (for libraries).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the calling library's canonical filename.
+ *
+ * @note The BinReloc source code MUST be included in your library, or this
+ * function won't work correctly.
+ *
+ * @param error If BinReloc failed to initialize, then the error code will
+ * be stored in this variable. Set to NULL if you want to
+ * ignore this. See #BrInitError for a list of error codes.
+ *
+ * @returns 1 on success, 0 if a filename cannot be found.
+ */
+int
+br_init_lib (BrInitError *error)
+{
+ exe = _br_find_exe_for_symbol ((const void *) "", error);
+ return exe != NULL;
+}
+
+
+/** Find the canonical filename of the current application.
+ *
+ * @param default_exe A default filename which will be used as fallback.
+ * @returns A string containing the application's canonical filename,
+ * which must be freed when no longer necessary. If BinReloc is
+ * not initialized, or if br_init() failed, then a copy of
+ * default_exe will be returned. If default_exe is NULL, then
+ * NULL will be returned.
+ */
+char *
+br_find_exe (const char *default_exe)
+{
+ if (exe == (char *) NULL) {
+ /* BinReloc is not initialized. */
+ if (default_exe != (const char *) NULL)
+ return strdup (default_exe);
+ else
+ return (char *) NULL;
+ }
+ return strdup (exe);
+}
+
+
+/** Locate the directory in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(exename)
+ * \endcode
+ *
+ * @param default_dir A default directory which will used as fallback.
+ * @return A string containing the directory, which must be freed when no
+ * longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_dir
+ * will be returned. If default_dir is NULL, then NULL will be
+ * returned.
+ */
+char *
+br_find_exe_dir (const char *default_dir)
+{
+ if (exe == NULL) {
+ /* BinReloc not initialized. */
+ if (default_dir != NULL)
+ return strdup (default_dir);
+ else
+ return NULL;
+ }
+
+ return br_dirname (exe);
+}
+
+
+/** Locate the prefix in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(dirname(exename))
+ * \endcode
+ *
+ * @param default_prefix A default prefix which will used as fallback.
+ * @return A string containing the prefix, which must be freed when no
+ * longer necessary. If BinReloc is not initialized, or if
+ * the initialization function failed, then a copy of default_prefix
+ * will be returned. If default_prefix is NULL, then NULL will be returned.
+ */
+char *
+br_find_prefix (const char *default_prefix)
+{
+ char *dir1, *dir2;
+
+ if (exe == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_prefix != (const char *) NULL)
+ return strdup (default_prefix);
+ else
+ return (char *) NULL;
+ }
+
+ dir1 = br_dirname (exe);
+ dir2 = br_dirname (dir1);
+ free (dir1);
+ return dir2;
+}
+
+
+/** Locate the application's binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/bin"
+ * \endcode
+ *
+ * @param default_bin_dir A default path which will used as fallback.
+ * @return A string containing the bin folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if
+ * the initialization function failed, then a copy of default_bin_dir will
+ * be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_bin_dir (const char *default_bin_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_bin_dir != (const char *) NULL)
+ return strdup (default_bin_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "bin");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's superuser binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/sbin"
+ * \endcode
+ *
+ * @param default_sbin_dir A default path which will used as fallback.
+ * @return A string containing the sbin folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_sbin_dir will
+ * be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_sbin_dir (const char *default_sbin_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_sbin_dir != (const char *) NULL)
+ return strdup (default_sbin_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "sbin");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's data folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share"
+ * \endcode
+ *
+ * @param default_data_dir A default path which will used as fallback.
+ * @return A string containing the data folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_data_dir
+ * will be returned. If default_data_dir is NULL, then NULL will be
+ * returned.
+ */
+char *
+br_find_data_dir (const char *default_data_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_data_dir != (const char *) NULL)
+ return strdup (default_data_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "share");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's localization folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share/locale"
+ * \endcode
+ *
+ * @param default_locale_dir A default path which will used as fallback.
+ * @return A string containing the localization folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_locale_dir will be returned.
+ * If default_locale_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_locale_dir (const char *default_locale_dir)
+{
+ char *data_dir, *dir;
+
+ data_dir = br_find_data_dir ((const char *) NULL);
+ if (data_dir == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_locale_dir != (const char *) NULL)
+ return strdup (default_locale_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (data_dir, "locale");
+ free (data_dir);
+ return dir;
+}
+
+
+/** Locate the application's library folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/lib"
+ * \endcode
+ *
+ * @param default_lib_dir A default path which will used as fallback.
+ * @return A string containing the library folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_lib_dir will be returned.
+ * If default_lib_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_lib_dir (const char *default_lib_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_lib_dir != (const char *) NULL)
+ return strdup (default_lib_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "lib");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's libexec folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/libexec"
+ * \endcode
+ *
+ * @param default_libexec_dir A default path which will used as fallback.
+ * @return A string containing the libexec folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_libexec_dir will be returned.
+ * If default_libexec_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_libexec_dir (const char *default_libexec_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_libexec_dir != (const char *) NULL)
+ return strdup (default_libexec_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "libexec");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's configuration files folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/etc"
+ * \endcode
+ *
+ * @param default_etc_dir A default path which will used as fallback.
+ * @return A string containing the etc folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_etc_dir will be returned.
+ * If default_etc_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_etc_dir (const char *default_etc_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_etc_dir != (const char *) NULL)
+ return strdup (default_etc_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "etc");
+ free (prefix);
+ return dir;
+}
+
+
+/***********************
+ * Utility functions
+ ***********************/
+
+/** Concatenate str1 and str2 to a newly allocated string.
+ *
+ * @param str1 A string.
+ * @param str2 Another string.
+ * @returns A newly-allocated string. This string should be freed when no longer needed.
+ */
+char *
+br_strcat (const char *str1, const char *str2)
+{
+ char *result;
+ size_t len1, len2;
+
+ if (str1 == NULL)
+ str1 = "";
+ if (str2 == NULL)
+ str2 = "";
+
+ len1 = strlen (str1);
+ len2 = strlen (str2);
+
+ result = (char *) malloc (len1 + len2 + 1);
+ memcpy (result, str1, len1);
+ memcpy (result + len1, str2, len2);
+ result[len1 + len2] = '\0';
+
+ return result;
+}
+
+
+char *
+br_build_path (const char *dir, const char *file)
+{
+ char *dir2, *result;
+ size_t len;
+ int must_free = 0;
+
+ len = strlen (dir);
+ if (len > 0 && dir[len - 1] != '/') {
+ dir2 = br_strcat (dir, "/");
+ must_free = 1;
+ } else
+ dir2 = (char *) dir;
+
+ result = br_strcat (dir2, file);
+ if (must_free)
+ free (dir2);
+ return result;
+}
+
+
+/* Emulates glibc's strndup() */
+static char *
+br_strndup (const char *str, size_t size)
+{
+ char *result = (char *) NULL;
+ size_t len;
+
+ if (str == (const char *) NULL)
+ return (char *) NULL;
+
+ len = strlen (str);
+ if (len == 0)
+ return strdup ("");
+ if (size > len)
+ size = len;
+
+ result = (char *) malloc (len + 1);
+ memcpy (result, str, size);
+ result[size] = '\0';
+ return result;
+}
+
+
+/** Extracts the directory component of a path.
+ *
+ * Similar to g_dirname() or the dirname commandline application.
+ *
+ * Example:
+ * \code
+ * br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
+ * \endcode
+ *
+ * @param path A path.
+ * @returns A directory name. This string should be freed when no longer needed.
+ */
+char *
+br_dirname (const char *path)
+{
+ char *end, *result;
+
+ if (path == (const char *) NULL)
+ return (char *) NULL;
+
+ end = strrchr (path, '/');
+ if (end == (const char *) NULL)
+ return strdup (".");
+
+ while (end > path && *end == '/')
+ end--;
+ result = br_strndup (path, end - path + 1);
+ if (result[0] == 0) {
+ free (result);
+ return strdup ("/");
+ } else
+ return result;
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BINRELOC_C__ */
diff --git a/extern/binreloc/include/binreloc.h b/extern/binreloc/include/binreloc.h
new file mode 100644
index 00000000000..5d0d9f4a209
--- /dev/null
+++ b/extern/binreloc/include/binreloc.h
@@ -0,0 +1,80 @@
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_H__
+#define __BINRELOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
+typedef enum {
+ /** Cannot allocate memory. */
+ BR_INIT_ERROR_NOMEM,
+ /** Unable to open /proc/self/maps; see errno for details. */
+ BR_INIT_ERROR_OPEN_MAPS,
+ /** Unable to read from /proc/self/maps; see errno for details. */
+ BR_INIT_ERROR_READ_MAPS,
+ /** The file format of /proc/self/maps is invalid; kernel bug? */
+ BR_INIT_ERROR_INVALID_MAPS,
+ /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
+ BR_INIT_ERROR_DISABLED
+} BrInitError;
+
+
+#ifndef BINRELOC_RUNNING_DOXYGEN
+/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
+ #define br_init zLhm65070058860608_br_init
+ #define br_init_lib zLhm65070058860608_br_init_lib
+ #define br_find_exe zLhm65070058860608_br_find_exe
+ #define br_find_exe_dir zLhm65070058860608_br_find_exe_dir
+ #define br_find_prefix zLhm65070058860608_br_find_prefix
+ #define br_find_bin_dir zLhm65070058860608_br_find_bin_dir
+ #define br_find_sbin_dir zLhm65070058860608_br_find_sbin_dir
+ #define br_find_data_dir zLhm65070058860608_br_find_data_dir
+ #define br_find_locale_dir zLhm65070058860608_br_find_locale_dir
+ #define br_find_lib_dir zLhm65070058860608_br_find_lib_dir
+ #define br_find_libexec_dir zLhm65070058860608_br_find_libexec_dir
+ #define br_find_etc_dir zLhm65070058860608_br_find_etc_dir
+ #define br_strcat zLhm65070058860608_br_strcat
+ #define br_build_path zLhm65070058860608_br_build_path
+ #define br_dirname zLhm65070058860608_br_dirname
+
+
+#endif
+int br_init (BrInitError *error);
+int br_init_lib (BrInitError *error);
+
+char *br_find_exe (const char *default_exe);
+char *br_find_exe_dir (const char *default_dir);
+char *br_find_prefix (const char *default_prefix);
+char *br_find_bin_dir (const char *default_bin_dir);
+char *br_find_sbin_dir (const char *default_sbin_dir);
+char *br_find_data_dir (const char *default_data_dir);
+char *br_find_locale_dir (const char *default_locale_dir);
+char *br_find_lib_dir (const char *default_lib_dir);
+char *br_find_libexec_dir (const char *default_libexec_dir);
+char *br_find_etc_dir (const char *default_etc_dir);
+
+/* Utility functions */
+char *br_strcat (const char *str1, const char *str2);
+char *br_build_path (const char *dir, const char *file);
+char *br_dirname (const char *path);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BINRELOC_H__ */
diff --git a/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj b/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj
index c282c496e87..6de2fd3a2bd 100644
--- a/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj
+++ b/extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj
@@ -340,6 +340,9 @@ ECHO Done
<File
RelativePath="..\..\src\btBulletDynamicsCommon.h">
</File>
+ <File
+ RelativePath="..\..\src\Bullet-C-Api.h">
+ </File>
<Filter
Name="BulletDynamics"
Filter="">
@@ -347,6 +350,12 @@ ECHO Done
Name="ConstraintSolver"
Filter="">
<File
+ RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConeTwistConstraint.cpp">
+ </File>
+ <File
+ RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConeTwistConstraint.h">
+ </File>
+ <File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConstraintSolver.h">
</File>
<File
@@ -422,6 +431,9 @@ ECHO Done
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\btSimpleDynamicsWorld.h">
</File>
+ <File
+ RelativePath="..\..\src\BulletDynamics\Dynamics\Bullet-C-API.cpp">
+ </File>
</Filter>
<Filter
Name="Vehicle"
@@ -681,6 +693,12 @@ ECHO Done
RelativePath="..\..\src\BulletCollision\CollisionShapes\btBvhTriangleMeshShape.h">
</File>
<File
+ RelativePath="..\..\src\BulletCollision\CollisionShapes\btCapsuleShape.cpp">
+ </File>
+ <File
+ RelativePath="..\..\src\BulletCollision\CollisionShapes\btCapsuleShape.h">
+ </File>
+ <File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btCollisionMargin.h">
</File>
<File
diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h
new file mode 100644
index 00000000000..078dcae63bb
--- /dev/null
+++ b/extern/bullet2/src/Bullet-C-Api.h
@@ -0,0 +1,37 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
+ Work in progress, functionality will be added on demand.
+
+ If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
+*/
+
+#ifndef BULLET_C_API_H
+#define BULLET_C_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BULLET_C_API_H
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
index b05285ca727..be4a11506df 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
@@ -21,9 +21,34 @@
#include <assert.h>
+#ifdef DEBUG_BROADPHASE
+#include <stdio.h>
+void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality)
+{
+ int numEdges = m_pHandles[0].m_maxEdges[axis];
+ printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
+
+ int i;
+ for (i=0;i<numEdges+1;i++)
+ {
+ Edge* pEdge = m_pEdges[axis] + i;
+ Handle* pHandlePrev = getHandle(pEdge->m_handle);
+ int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
+ char beginOrEnd;
+ beginOrEnd=pEdge->IsMax()?'E':'B';
+ printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
+ }
+
+ if (checkCardinality)
+ assert(numEdges == m_numHandles*2+1);
+}
+#endif //DEBUG_BROADPHASE
+
+
btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
{
- unsigned short handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
+ (void)shapeType;
+ BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
Handle* handle = getHandle(handleId);
@@ -40,6 +65,7 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con
{
Handle* handle = static_cast<Handle*>(proxy);
updateHandle(handle->m_handleId,aabbMin,aabbMax);
+
}
@@ -50,10 +76,11 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles)
:btOverlappingPairCache()
{
+ m_invalidPair = 0;
//assert(bounds.HasVolume());
// 1 handle is reserved as sentinel
- assert(maxHandles > 1 && maxHandles < 32767);
+ btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES);
// init bounds
m_worldAabbMin = worldAabbMin;
@@ -61,7 +88,9 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
- m_quantize = btVector3(65535.0f,65535.0f,65535.0f) / aabbSize;
+ BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL;
+
+ m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
// allocate handles buffer and put all handles on free list
m_pHandles = new Handle[maxHandles];
@@ -71,7 +100,7 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
// handle 0 is reserved as the null index, and is also used as the sentinel
m_firstFreeHandle = 1;
{
- for (int i = m_firstFreeHandle; i < maxHandles; i++)
+ for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
m_pHandles[i].SetNextFree(i + 1);
m_pHandles[maxHandles - 1].SetNextFree(0);
}
@@ -94,9 +123,14 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
m_pEdges[axis][0].m_pos = 0;
m_pEdges[axis][0].m_handle = 0;
- m_pEdges[axis][1].m_pos = 0xffff;
+ m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL;
m_pEdges[axis][1].m_handle = 0;
+#ifdef DEBUG_BROADPHASE
+ debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
}
+
}
btAxisSweep3::~btAxisSweep3()
@@ -107,43 +141,36 @@ btAxisSweep3::~btAxisSweep3()
delete[] m_pHandles;
}
-void btAxisSweep3::quantize(unsigned short* out, const btPoint3& point, int isMax) const
+void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
{
btPoint3 clampedPoint(point);
- /*
- if (isMax)
- clampedPoint += btVector3(10,10,10);
- else
- {
- clampedPoint -= btVector3(10,10,10);
- }
- */
+
clampedPoint.setMax(m_worldAabbMin);
clampedPoint.setMin(m_worldAabbMax);
btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
- out[0] = (unsigned short)(((int)v.getX() & 0xfffc) | isMax);
- out[1] = (unsigned short)(((int)v.getY() & 0xfffc) | isMax);
- out[2] = (unsigned short)(((int)v.getZ() & 0xfffc) | isMax);
+ out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax);
+ out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax);
+ out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax);
}
-unsigned short btAxisSweep3::allocHandle()
+BP_FP_INT_TYPE btAxisSweep3::allocHandle()
{
assert(m_firstFreeHandle);
- unsigned short handle = m_firstFreeHandle;
+ BP_FP_INT_TYPE handle = m_firstFreeHandle;
m_firstFreeHandle = getHandle(handle)->GetNextFree();
m_numHandles++;
return handle;
}
-void btAxisSweep3::freeHandle(unsigned short handle)
+void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle)
{
assert(handle > 0 && handle < m_maxHandles);
@@ -155,15 +182,15 @@ void btAxisSweep3::freeHandle(unsigned short handle)
-unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
+BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
{
// quantize the bounds
- unsigned short min[3], max[3];
+ BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// allocate a handle
- unsigned short handle = allocHandle();
+ BP_FP_INT_TYPE handle = allocHandle();
assert(handle!= 0xcdcd);
Handle* pHandle = getHandle(handle);
@@ -175,11 +202,13 @@ unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a
pHandle->m_collisionFilterMask = collisionFilterMask;
// compute current limit of edge arrays
- int limit = m_numHandles * 2;
+ BP_FP_INT_TYPE limit = m_numHandles * 2;
+
// insert new edges just inside the max boundary edge
- for (int axis = 0; axis < 3; axis++)
+ for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
{
+
m_pHandles[0].m_maxEdges[axis] += 2;
m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
@@ -202,14 +231,14 @@ unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a
sortMinDown(2, pHandle->m_minEdges[2], true);
sortMaxDown(2, pHandle->m_maxEdges[2], true);
- //PrintAxis(1);
return handle;
}
-void btAxisSweep3::removeHandle(unsigned short handle)
+void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle)
{
+
Handle* pHandle = getHandle(handle);
//explicitly remove the pairs containing the proxy
@@ -220,42 +249,145 @@ void btAxisSweep3::removeHandle(unsigned short handle)
// compute current limit of edge arrays
int limit = m_numHandles * 2;
+
int axis;
for (axis = 0;axis<3;axis++)
{
- Edge* pEdges = m_pEdges[axis];
- int maxEdge= pHandle->m_maxEdges[axis];
- pEdges[maxEdge].m_pos = 0xffff;
- int minEdge = pHandle->m_minEdges[axis];
- pEdges[minEdge].m_pos = 0xffff;
+ m_pHandles[0].m_maxEdges[axis] -= 2;
}
// remove the edges by sorting them up to the end of the list
for ( axis = 0; axis < 3; axis++)
{
Edge* pEdges = m_pEdges[axis];
- int max = pHandle->m_maxEdges[axis];
- pEdges[max].m_pos = 0xffff;
+ BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
+ pEdges[max].m_pos = BP_HANDLE_SENTINEL;
sortMaxUp(axis,max,false);
-
- int i = pHandle->m_minEdges[axis];
- pEdges[i].m_pos = 0xffff;
+
+
+ BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
+ pEdges[i].m_pos = BP_HANDLE_SENTINEL;
+
sortMinUp(axis,i,false);
pEdges[limit-1].m_handle = 0;
- pEdges[limit-1].m_pos = 0xffff;
+ pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL;
+
+#ifdef DEBUG_BROADPHASE
+ debugPrintAxis(axis,false);
+#endif //DEBUG_BROADPHASE
+
}
+
// free the handle
freeHandle(handle);
}
+extern int gOverlappingPairs;
+
+
+void btAxisSweep3::refreshOverlappingPairs()
+{
+
+}
+void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback)
+{
+
+ //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+ m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
+
+ //remove the 'invalid' ones
+#ifdef USE_POPBACK_REMOVAL
+ while (m_invalidPair>0)
+ {
+ m_invalidPair--;
+ m_overlappingPairArray.pop_back();
+ }
+#else
+ m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair);
+ m_invalidPair = 0;
+#endif
+
+
+ int i;
+
+ btBroadphasePair previousPair;
+ previousPair.m_pProxy0 = 0;
+ previousPair.m_pProxy1 = 0;
+ previousPair.m_algorithm = 0;
+
+
+ for (i=0;i<m_overlappingPairArray.size();i++)
+ {
+
+ btBroadphasePair& pair = m_overlappingPairArray[i];
+
+ bool isDuplicate = (pair == previousPair);
+
+ previousPair = pair;
+
+ bool needsRemoval = false;
+
+ if (!isDuplicate)
+ {
+ bool hasOverlap = testOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+ if (hasOverlap)
+ {
+ needsRemoval = callback->processOverlap(pair);
+ } else
+ {
+ needsRemoval = true;
+ }
+ } else
+ {
+ //remove duplicate
+ needsRemoval = true;
+ //should have no algorithm
+ btAssert(!pair.m_algorithm);
+ }
+
+ if (needsRemoval)
+ {
+ cleanOverlappingPair(pair);
+
+ // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+ // m_overlappingPairArray.pop_back();
+ pair.m_pProxy0 = 0;
+ pair.m_pProxy1 = 0;
+ m_invalidPair++;
+ gOverlappingPairs--;
+ }
+
+ }
+}
+
+
+bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+ const Handle* pHandleA = static_cast<Handle*>(proxy0);
+ const Handle* pHandleB = static_cast<Handle*>(proxy1);
+
+ //optimization 1: check the array index (memory address), instead of the m_pos
+
+ for (int axis = 0; axis < 3; axis++)
+ {
+ if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
+ pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
{
//optimization 1: check the array index (memory address), instead of the m_pos
@@ -272,7 +404,7 @@ bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Hand
}
}
- //optimization 2: only 2 axis need to be tested
+ //optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization)
/*for (int axis = 0; axis < 3; axis++)
{
@@ -287,7 +419,7 @@ bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Hand
return true;
}
-void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
+void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
{
// assert(bounds.IsFinite());
//assert(bounds.HasVolume());
@@ -295,15 +427,15 @@ void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,c
Handle* pHandle = getHandle(handle);
// quantize the new bounds
- unsigned short min[3], max[3];
+ BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// update changed edges
for (int axis = 0; axis < 3; axis++)
{
- unsigned short emin = pHandle->m_minEdges[axis];
- unsigned short emax = pHandle->m_maxEdges[axis];
+ BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
+ BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
@@ -324,14 +456,22 @@ void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,c
if (dmax < 0)
sortMaxDown(axis, emax);
+
+#ifdef DEBUG_BROADPHASE
+ debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
}
- //PrintAxis(1);
+
}
+
+
+
// sorting a min edge downwards can only ever *add* overlaps
-void btAxisSweep3::sortMinDown(int axis, unsigned short edge, bool updateOverlaps)
+void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
+
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
@@ -368,16 +508,21 @@ void btAxisSweep3::sortMinDown(int axis, unsigned short edge, bool updateOverlap
pEdge--;
pPrev--;
}
+
+#ifdef DEBUG_BROADPHASE
+ debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
}
// sorting a min edge upwards can only ever *remove* overlaps
-void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
+void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
- while (pEdge->m_pos > pNext->m_pos)
+ while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
@@ -386,10 +531,12 @@ void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
// if next edge is maximum remove any overlap between the two handles
if (updateOverlaps)
{
+ /*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
btBroadphasePair tmpPair(*handle0,*handle1);
removeOverlappingPair(tmpPair);
+ */
}
@@ -410,11 +557,14 @@ void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
pEdge++;
pNext++;
}
+
+
}
// sorting a max edge downwards can only ever *remove* overlaps
-void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlaps)
+void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
+
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
@@ -428,6 +578,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
// if previous edge was a minimum remove any overlap between the two handles
if (updateOverlaps)
{
+ //this is done during the overlappingpairarray iteration/narrowphase collision
+ /*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pPrev->m_handle);
btBroadphasePair* pair = findPair(handle0,handle1);
@@ -437,6 +589,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
{
removeOverlappingPair(*pair);
}
+ */
+
}
// update edge reference in other handle
@@ -456,16 +610,22 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
pEdge--;
pPrev--;
}
+
+
+#ifdef DEBUG_BROADPHASE
+ debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
}
// sorting a max edge upwards can only ever *add* overlaps
-void btAxisSweep3::sortMaxUp(int axis, unsigned short edge, bool updateOverlaps)
+void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
- while (pEdge->m_pos > pNext->m_pos)
+ while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
@@ -496,4 +656,5 @@ void btAxisSweep3::sortMaxUp(int axis, unsigned short edge, bool updateOverlaps)
pEdge++;
pNext++;
}
+
}
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
index ebbbe01bbe6..57bbb368672 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
@@ -19,11 +19,29 @@
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
-#include "LinearMath/btPoint3.h"
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btPoint3.h"
+#include "../../LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"
#include "btBroadphaseProxy.h"
+
+//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects
+//#define BP_USE_FIXEDPOINT_INT_32 1
+
+#ifdef BP_USE_FIXEDPOINT_INT_32
+ #define BP_FP_INT_TYPE unsigned int
+ #define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles
+ #define BP_HANDLE_SENTINEL 0x7fffffff
+ #define BP_HANDLE_MASK 0xfffffffe
+#else
+ #define BP_FP_INT_TYPE unsigned short int
+ #define BP_MAX_HANDLES 32767
+ #define BP_HANDLE_SENTINEL 0xffff
+ #define BP_HANDLE_MASK 0xfffe
+#endif //BP_USE_FIXEDPOINT_INT_32
+
+//#define DEBUG_BROADPHASE 1
+
/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats.
/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos
@@ -36,10 +54,10 @@ public:
class Edge
{
public:
- unsigned short m_pos; // low bit is min/max
- unsigned short m_handle;
+ BP_FP_INT_TYPE m_pos; // low bit is min/max
+ BP_FP_INT_TYPE m_handle;
- unsigned short IsMax() const {return m_pos & 1;}
+ BP_FP_INT_TYPE IsMax() const {return m_pos & 1;}
};
public:
@@ -48,14 +66,14 @@ public:
public:
// indexes into the edge arrays
- unsigned short m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
- unsigned short m_handleId;
- unsigned short m_pad;
+ BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
+ BP_FP_INT_TYPE m_handleId;
+ BP_FP_INT_TYPE m_pad;
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
- inline void SetNextFree(unsigned short next) {m_minEdges[0] = next;}
- inline unsigned short GetNextFree() const {return m_minEdges[0];}
+ inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
+ inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
}; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
@@ -65,51 +83,56 @@ private:
btVector3 m_quantize; // scaling factor for quantization
- int m_numHandles; // number of active handles
+ BP_FP_INT_TYPE m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
Handle* m_pHandles; // handles pool
- unsigned short m_firstFreeHandle; // free handles list
+ BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
+ int m_invalidPair;
// allocation/deallocation
- unsigned short allocHandle();
- void freeHandle(unsigned short handle);
+ BP_FP_INT_TYPE allocHandle();
+ void freeHandle(BP_FP_INT_TYPE handle);
bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB);
- //Overlap* AddOverlap(unsigned short handleA, unsigned short handleB);
- //void RemoveOverlap(unsigned short handleA, unsigned short handleB);
+#ifdef DEBUG_BROADPHASE
+ void debugPrintAxis(int axis,bool checkCardinality=true);
+#endif //DEBUG_BROADPHASE
- void quantize(unsigned short* out, const btPoint3& point, int isMax) const;
+ //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
+ //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
- void sortMinDown(int axis, unsigned short edge, bool updateOverlaps = true);
- void sortMinUp(int axis, unsigned short edge, bool updateOverlaps = true);
- void sortMaxDown(int axis, unsigned short edge, bool updateOverlaps = true);
- void sortMaxUp(int axis, unsigned short edge, bool updateOverlaps = true);
+ void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
+
+ void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
+ void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
+ void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
+ void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
public:
btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384);
virtual ~btAxisSweep3();
- virtual void refreshOverlappingPairs()
- {
- //this is replace by sweep and prune
- }
+ virtual void refreshOverlappingPairs();
- unsigned short addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
- void removeHandle(unsigned short handle);
- void updateHandle(unsigned short handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
- inline Handle* getHandle(unsigned short index) const {return m_pHandles + index;}
+ BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
+ void removeHandle(BP_FP_INT_TYPE handle);
+ void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
+ inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
+ void processAllOverlappingPairs(btOverlapCallback* callback);
//Broadphase Interface
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
virtual void destroyProxy(btBroadphaseProxy* proxy);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
+ bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
};
-#endif //AXIS_SWEEP_3_H
+#endif
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
index 0c0bfe4f7b9..b6ace03c07a 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
@@ -21,7 +21,7 @@ subject to the following restrictions:
struct btDispatcherInfo;
class btDispatcher;
struct btBroadphaseProxy;
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
///BroadphaseInterface for aabb-overlapping object pairs
class btBroadphaseInterface
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
index b279022c802..40d9748ffa9 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
@@ -16,6 +16,7 @@ subject to the following restrictions:
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
+#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
/// btDispatcher uses these types
@@ -33,6 +34,7 @@ enum BroadphaseNativeTypes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
MULTI_SPHERE_SHAPE_PROXYTYPE,
+ CAPSULE_SHAPE_PROXYTYPE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
@@ -71,7 +73,7 @@ struct btBroadphaseProxy
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
- AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger,
+ AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
@@ -113,7 +115,8 @@ struct btBroadphaseProxy
return (proxyType == STATIC_PLANE_PROXYTYPE);
}
-};
+}
+;
class btCollisionAlgorithm;
@@ -128,14 +131,16 @@ struct btBroadphasePair
:
m_pProxy0(0),
m_pProxy1(0),
- m_algorithm(0)
+ m_algorithm(0),
+ m_userInfo(0)
{
}
btBroadphasePair(const btBroadphasePair& other)
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
- m_algorithm(other.m_algorithm)
+ m_algorithm(other.m_algorithm),
+ m_userInfo(other.m_userInfo)
{
}
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
@@ -154,6 +159,7 @@ struct btBroadphasePair
}
m_algorithm = 0;
+ m_userInfo = 0;
}
@@ -161,15 +167,37 @@ struct btBroadphasePair
btBroadphaseProxy* m_pProxy1;
mutable btCollisionAlgorithm* m_algorithm;
-};
+ mutable void* m_userInfo;
+};
+/*
//comparison for set operation, see Solid DT_Encounter
-inline bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
+SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
{
return a.m_pProxy0 < b.m_pProxy0 ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
}
+*/
+
+
+class btBroadphasePairSortPredicate
+{
+ public:
+
+ bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
+ {
+ return a.m_pProxy0 > b.m_pProxy0 ||
+ (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
+ (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
+ }
+};
+
+
+SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b)
+{
+ return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
+}
#endif //BROADPHASE_PROXY_H
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
index f9e22057058..55cec386a7b 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
@@ -16,6 +16,8 @@ subject to the following restrictions:
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
+#include "../../LinearMath/btScalar.h"
+
struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
@@ -34,6 +36,7 @@ struct btCollisionAlgorithmConstructionInfo
btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
:m_dispatcher(dispatcher)
{
+ (void)temp;
}
btDispatcher* m_dispatcher;
@@ -66,7 +69,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
};
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
index c7714f592c4..3d958cc8fef 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
@@ -16,6 +16,8 @@ subject to the following restrictions:
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
+#include "../../LinearMath/btScalar.h"
+
class btCollisionAlgorithm;
struct btBroadphaseProxy;
class btRigidBody;
@@ -34,10 +36,10 @@ struct btDispatcherInfo
DISPATCH_CONTINUOUS
};
btDispatcherInfo()
- :m_timeStep(0.f),
+ :m_timeStep(btScalar(0.)),
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
- m_timeOfImpact(1.f),
+ m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_debugDraw(0),
m_enableSatConvex(false),
@@ -46,10 +48,10 @@ struct btDispatcherInfo
{
}
- float m_timeStep;
+ btScalar m_timeStep;
int m_stepCount;
int m_dispatchFunc;
- float m_timeOfImpact;
+ btScalar m_timeOfImpact;
bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
bool m_enableSatConvex;
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
index 5e3fa633589..60f0a41a9d7 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
@@ -24,7 +24,8 @@ subject to the following restrictions:
int gOverlappingPairs = 0;
btOverlappingPairCache::btOverlappingPairCache():
-m_blockedForChanges(false)
+m_blockedForChanges(false),
+m_overlapFilterCallback(0)
//m_NumOverlapBroadphasePair(0)
{
}
@@ -39,15 +40,15 @@ btOverlappingPairCache::~btOverlappingPairCache()
void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair)
{
- std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(findPair);
-// assert(it != m_overlappingPairSet.end());
-
- if (it != m_overlappingPairSet.end())
+ int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
+ if (findIndex < m_overlappingPairArray.size())
{
gOverlappingPairs--;
- btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
- cleanOverlappingPair(*pair);
- m_overlappingPairSet.erase(it);
+ btBroadphasePair& pair = m_overlappingPairArray[findIndex];
+ cleanOverlappingPair(pair);
+
+ m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1);
+ m_overlappingPairArray.pop_back();
}
}
@@ -78,7 +79,7 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
btBroadphasePair pair(*proxy0,*proxy1);
- m_overlappingPairSet.insert(pair);
+ m_overlappingPairArray.push_back(pair);
gOverlappingPairs++;
}
@@ -93,13 +94,15 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1);
- std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(tmpPair);
- if ((it == m_overlappingPairSet.end()))
- return 0;
+ int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
- //assert(it != m_overlappingPairSet.end());
- btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
- return pair;
+ if (findIndex < m_overlappingPairArray.size())
+ {
+ //assert(it != m_overlappingPairSet.end());
+ btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
+ return pair;
+ }
+ return 0;
}
@@ -170,30 +173,23 @@ void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseP
void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback)
{
- std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.begin();
- for (; !(it==m_overlappingPairSet.end());)
+
+ int i;
+
+ for (i=0;i<m_overlappingPairArray.size();)
{
- btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
+ btBroadphasePair* pair = &m_overlappingPairArray[i];
if (callback->processOverlap(*pair))
{
cleanOverlappingPair(*pair);
- std::set<btBroadphasePair>::iterator it2 = it;
- //why does next line not compile under OS X??
-#ifdef MAC_OSX_FIXED_STL_SET
- it2++;
- it = m_overlappingPairSet.erase(it);
- assert(it == it2);
-#else
- it++;
- m_overlappingPairSet.erase(it2);
-#endif //MAC_OSX_FIXED_STL_SET
-
+ m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+ m_overlappingPairArray.pop_back();
gOverlappingPairs--;
} else
{
- it++;
+ i++;
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
index bc62961bf3c..a81fe3264df 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
@@ -20,65 +20,101 @@ subject to the following restrictions:
#include "btBroadphaseInterface.h"
#include "btBroadphaseProxy.h"
-#include "LinearMath/btPoint3.h"
-#include <set>
+#include "../../LinearMath/btPoint3.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
struct btOverlapCallback
{
-virtual ~btOverlapCallback()
-{
-}
+ virtual ~btOverlapCallback()
+ {}
//return true for deletion of the pair
virtual bool processOverlap(btBroadphasePair& pair) = 0;
};
+struct btOverlapFilterCallback
+{
+ virtual ~btOverlapFilterCallback()
+ {}
+ // return true when pairs need collision
+ virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
+};
+
///btOverlappingPairCache maintains the objects with overlapping AABB
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
class btOverlappingPairCache : public btBroadphaseInterface
{
- //avoid brute-force finding all the time
- std::set<btBroadphasePair> m_overlappingPairSet;
-
- //during the dispatch, check that user doesn't destroy/create proxy
- bool m_blockedForChanges;
-
- public:
+ protected:
+ //avoid brute-force finding all the time
+ btAlignedObjectArray<btBroadphasePair> m_overlappingPairArray;
+
+ //during the dispatch, check that user doesn't destroy/create proxy
+ bool m_blockedForChanges;
- btOverlappingPairCache();
- virtual ~btOverlappingPairCache();
+ //if set, use the callback instead of the built in filter in needBroadphaseCollision
+ btOverlapFilterCallback* m_overlapFilterCallback;
+ public:
+
+ btOverlappingPairCache();
+ virtual ~btOverlappingPairCache();
- void processAllOverlappingPairs(btOverlapCallback*);
+ virtual void processAllOverlappingPairs(btOverlapCallback*);
- void removeOverlappingPair(btBroadphasePair& pair);
+ void removeOverlappingPair(btBroadphasePair& pair);
- void cleanOverlappingPair(btBroadphasePair& pair);
-
- void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+ void cleanOverlappingPair(btBroadphasePair& pair);
+
+ void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
- btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+ btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
-
- void cleanProxyFromPairs(btBroadphaseProxy* proxy);
+ void cleanProxyFromPairs(btBroadphaseProxy* proxy);
- void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
+ void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
- inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
- {
- bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
- collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
-
- return collides;
- }
+ inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
+ {
+ if (m_overlapFilterCallback)
+ return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
+
+ bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+ collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+
+ return collides;
+ }
+
-
- virtual void refreshOverlappingPairs() =0;
+ virtual void refreshOverlappingPairs() =0;
+ btBroadphasePair* getOverlappingPairArrayPtr()
+ {
+ return &m_overlappingPairArray[0];
+ }
+ const btBroadphasePair* getOverlappingPairArrayPtr() const
+ {
+ return &m_overlappingPairArray[0];
+ }
+ int getNumOverlappingPairs() const
+ {
+ return m_overlappingPairArray.size();
+ }
+
+ btOverlapFilterCallback* getOverlapFilterCallback()
+ {
+ return m_overlapFilterCallback;
+ }
+
+ void setOverlapFilterCallback(btOverlapFilterCallback* callback)
+ {
+ m_overlapFilterCallback = callback;
+ }
};
#endif //OVERLAPPING_PAIR_CACHE_H
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
index 6281e93eeb4..30bcbe0c5f1 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
-#include <vector>
+#include <new>
void btSimpleBroadphase::validate()
@@ -85,8 +85,8 @@ btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& min, cons
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
- int index = proxy - proxy1;
- assert(index == freeIndex);
+ int index = int(proxy - proxy1);
+ btAssert(index == freeIndex);
m_pProxies[m_numProxies] = proxy;
m_numProxies++;
@@ -100,7 +100,8 @@ class RemovingOverlapCallback : public btOverlapCallback
protected:
virtual bool processOverlap(btBroadphasePair& pair)
{
- assert(0);
+ (void)pair;
+ btAssert(0);
return false;
}
};
@@ -131,8 +132,8 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
- int index = proxy0 - proxy1;
- assert (index < m_maxProxies);
+ int index = int(proxy0 - proxy1);
+ btAssert (index < m_maxProxies);
m_freeProxies[--m_firstFreeProxy] = index;
removeOverlappingPairsContainingProxy(proxyOrg);
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
index 281677081d7..fb155e7047c 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
@@ -31,6 +31,7 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
m_min(minpt),m_max(maxpt)
{
+ (void)shapeType;
}
@@ -40,6 +41,8 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
class btSimpleBroadphase : public btOverlappingPairCache
{
+protected:
+
btSimpleBroadphaseProxy* m_proxies;
int* m_freeProxies;
int m_firstFreeProxy;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
index 0d76b1013f9..81133670f0c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
@@ -13,6 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
+#include "LinearMath/btScalar.h"
#include "SphereTriangleDetector.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
@@ -28,13 +29,14 @@ m_triangle(triangle)
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
{
+ (void)debugDraw;
const btTransform& transformA = input.m_transformA;
const btTransform& transformB = input.m_transformB;
btVector3 point,normal;
- btScalar timeOfImpact = 1.f;
- btScalar depth = 0.f;
-// output.m_distance = 1e30f;
+ btScalar timeOfImpact = btScalar(1.);
+ btScalar depth = btScalar(0.);
+// output.m_distance = btScalar(1e30);
//move sphere into triangle space
btTransform sphereInTr = transformB.inverseTimes(transformA);
@@ -45,19 +47,19 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
}
-#define MAX_OVERLAP 0.f
+#define MAX_OVERLAP btScalar(0.)
// See also geometrictools.com
// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
-float SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
+btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
btVector3 diff = p - from;
btVector3 v = to - from;
- float t = v.dot(diff);
+ btScalar t = v.dot(diff);
if (t > 0) {
- float dotVV = v.dot(v);
+ btScalar dotVV = v.dot(v);
if (t < dotVV) {
t /= dotVV;
diff -= t*v;
@@ -80,7 +82,7 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
}
///combined discrete/continuous sphere-triangle
-bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, float &timeOfImpact)
+bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact)
{
const btVector3* vertices = &m_triangle->getVertexPtr(0);
@@ -92,25 +94,25 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
normal.normalize();
btVector3 p1ToCentre = c - vertices[0];
- float distanceFromPlane = p1ToCentre.dot(normal);
+ btScalar distanceFromPlane = p1ToCentre.dot(normal);
- if (distanceFromPlane < 0.f)
+ if (distanceFromPlane < btScalar(0.))
{
//triangle facing the other way
- distanceFromPlane *= -1.f;
- normal *= -1.f;
+ distanceFromPlane *= btScalar(-1.);
+ normal *= btScalar(-1.);
}
///todo: move this gContactBreakingThreshold into a proper structure
- extern float gContactBreakingThreshold;
+ extern btScalar gContactBreakingThreshold;
- float contactMargin = gContactBreakingThreshold;
+ btScalar contactMargin = gContactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
- float deltaDotNormal = delta.dot(normal);
- if (!isInsideShellPlane && deltaDotNormal >= 0.0f)
+ btScalar deltaDotNormal = delta.dot(normal);
+ if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0))
return false;
// Check for contact / intersection
@@ -123,7 +125,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
contactPoint = c - normal*distanceFromPlane;
} else {
// Could be inside one of the contact capsules
- float contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
+ btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
btVector3 nearestOnEdge;
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
@@ -132,7 +134,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
m_triangle->getEdge(i,pa,pb);
- float distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
+ btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
if (distanceSqr < contactCapsuleRadiusSqr) {
// Yep, we're inside a capsule
hasContact = true;
@@ -145,25 +147,22 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
if (hasContact) {
btVector3 contactToCentre = c - contactPoint;
- float distanceSqr = contactToCentre.length2();
+ btScalar distanceSqr = contactToCentre.length2();
if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) {
- float distance = btSqrt(distanceSqr);
- if (1)
- {
- resultNormal = contactToCentre;
- resultNormal.normalize();
- }
+ btScalar distance = btSqrt(distanceSqr);
+ resultNormal = contactToCentre;
+ resultNormal.normalize();
point = contactPoint;
depth = -(r-distance);
return true;
}
- if (delta.dot(contactToCentre) >= 0.0f)
+ if (delta.dot(contactToCentre) >= btScalar(0.0))
return false;
// Moving towards the contact point -> collision
point = contactPoint;
- timeOfImpact = 0.0f;
+ timeOfImpact = btScalar(0.0);
return true;
}
@@ -189,7 +188,7 @@ bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const b
btVector3 edge2_normal( edge2.cross(normal));
btVector3 edge3_normal( edge3.cross(normal));
- float r1, r2, r3;
+ btScalar r1, r2, r3;
r1 = edge1_normal.dot( p1_to_p );
r2 = edge2_normal.dot( p2_to_p );
r3 = edge3_normal.dot( p3_to_p );
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
index 8fedba19922..b32806a6846 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
-#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
+#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "../../LinearMath/btPoint3.h"
class btSphereShape;
@@ -36,7 +36,7 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
private:
- bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, float &timeOfImpact);
+ bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact);
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
index 1eaa4a0fd50..d51a59af7f0 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef COLLISION_CREATE_FUNC
#define COLLISION_CREATE_FUNC
-#include <vector>
-
-typedef std::vector<class btCollisionObject*> btCollisionObjectArray;
+#include "../../LinearMath/btAlignedObjectArray.h"
+typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
class btCollisionAlgorithm;
class btCollisionObject;
@@ -35,8 +34,11 @@ struct btCollisionAlgorithmCreateFunc
}
virtual ~btCollisionAlgorithmCreateFunc(){};
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1)
{
+
+ (void)body0;
+ (void)body1;
return 0;
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
index 309c1890b40..b535fac6563 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
@@ -25,7 +25,6 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
-#include <algorithm>
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
int gNumManifold = 0;
@@ -33,16 +32,17 @@ int gNumManifold = 0;
#include <stdio.h>
-btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms)
-:m_useIslands(true),
-m_convexConvexCreateFunc(0),
+btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms):
m_count(0),
+m_useIslands(true),
+m_convexConvexCreateFunc(0),
m_convexConcaveCreateFunc(0),
m_swappedConvexConcaveCreateFunc(0),
m_compoundCreateFunc(0),
m_swappedCompoundCreateFunc(0),
m_emptyCreateFunc(0)
{
+ (void)noDefaultAlgorithms;
int i;
setNearCallback(defaultNearCallback);
@@ -56,11 +56,14 @@ m_emptyCreateFunc(0)
}
}
}
-
+//if you want to not link with the default collision algorithms, you can
+//define BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
+//in your Bullet library build system
+#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
btCollisionDispatcher::btCollisionDispatcher ():
- m_useIslands(true),
- m_count(0)
+ m_count(0),
+ m_useIslands(true)
{
int i;
@@ -86,6 +89,9 @@ btCollisionDispatcher::btCollisionDispatcher ():
};
+#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
+
+
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
{
m_doubleDispatch[proxyType0][proxyType1] = createFunc;
@@ -129,20 +135,17 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
gNumManifold--;
//printf("releaseManifold: gNumManifold %d\n",gNumManifold);
-
clearManifold(manifold);
- std::vector<btPersistentManifold*>::iterator i =
- std::find(m_manifoldsPtr.begin(), m_manifoldsPtr.end(), manifold);
- if (!(i == m_manifoldsPtr.end()))
+ ///todo: this can be improved a lot, linear search might be slow part!
+ int findIndex = m_manifoldsPtr.findLinearSearch(manifold);
+ if (findIndex < m_manifoldsPtr.size())
{
- std::swap(*i, m_manifoldsPtr.back());
+ m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
m_manifoldsPtr.pop_back();
delete manifold;
-
}
-
}
@@ -164,6 +167,8 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
}
+#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
+
btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1)
{
@@ -197,6 +202,8 @@ btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(in
return m_emptyCreateFunc;
}
+#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
+
#ifndef USE_DISPATCH_REGISTRY_ARRAY
@@ -266,6 +273,8 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
if ((!body0->isActive()) && (!body1->isActive()))
needsCollision = false;
+ else if (!body0->checkCollideWith(body1))
+ needsCollision = false;
return needsCollision ;
@@ -288,6 +297,16 @@ public:
{
}
+ btCollisionPairCallback& operator=(btCollisionPairCallback& other)
+ {
+ m_dispatchInfo = other.m_dispatchInfo;
+ m_dispatcher = other.m_dispatcher;
+ return *this;
+ }
+
+ virtual ~btCollisionPairCallback() {}
+
+
virtual bool processOverlap(btBroadphasePair& pair)
{
(*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
@@ -337,7 +356,7 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
} else
{
//continuous collision detection query, time of impact (toi)
- float toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
+ btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
if (dispatchInfo.m_timeOfImpact > toi)
dispatchInfo.m_timeOfImpact = toi;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
index 77c09b618ec..ca5aba8f01c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
@@ -16,13 +16,13 @@ subject to the following restrictions:
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
-#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
-#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "../BroadphaseCollision/btDispatcher.h"
+#include "../NarrowPhaseCollision/btPersistentManifold.h"
-#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
-
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "../CollisionDispatch/btManifoldResult.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
class btIDebugDraw;
class btOverlappingPairCache;
@@ -41,8 +41,9 @@ typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispa
///Time of Impact, Closest Points and Penetration Depth.
class btCollisionDispatcher : public btDispatcher
{
+ int m_count;
- std::vector<btPersistentManifold*> m_manifoldsPtr;
+ btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
bool m_useIslands;
@@ -68,7 +69,6 @@ class btCollisionDispatcher : public btDispatcher
public:
-
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
@@ -92,8 +92,6 @@ public:
return m_manifoldsPtr[index];
}
- int m_count;
-
///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support
btCollisionDispatcher ();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
index 13fa0b5baa9..d4c0a4e8cb3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
@@ -20,15 +20,19 @@ btCollisionObject::btCollisionObject()
m_collisionShape(0),
m_collisionFlags(0),
m_activationState1(1),
- m_deactivationTime(0.f),
+ m_deactivationTime(btScalar(0.)),
m_userObjectPointer(0),
- m_hitFraction(1.f),
- m_ccdSweptSphereRadius(0.f),
- m_ccdSquareMotionThreshold(0.f)
+ m_hitFraction(btScalar(1.)),
+ m_ccdSweptSphereRadius(btScalar(0.)),
+ m_ccdSquareMotionThreshold(btScalar(0.)),
+ m_checkCollideWith(false)
{
}
+btCollisionObject::~btCollisionObject()
+{
+}
void btCollisionObject::setActivationState(int newState)
{
@@ -46,7 +50,7 @@ void btCollisionObject::activate(bool forceActivation)
if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
{
setActivationState(ACTIVE_TAG);
- m_deactivationTime = 0.f;
+ m_deactivationTime = btScalar(0.);
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
index 9a0129ac29c..9fb6a67c4a3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
-#include "LinearMath/btTransform.h"
+#include "../../LinearMath/btTransform.h"
//island management, m_activationState1
#define ACTIVE_TAG 1
@@ -27,21 +27,19 @@ subject to the following restrictions:
struct btBroadphaseProxy;
class btCollisionShape;
-#include "LinearMath/btMotionState.h"
+#include "../../LinearMath/btMotionState.h"
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
/// They can be added to the btCollisionWorld.
-class btCollisionObject
+ATTRIBUTE_ALIGNED16(class) btCollisionObject
{
protected:
btTransform m_worldTransform;
- btBroadphaseProxy* m_broadphaseHandle;
- btCollisionShape* m_collisionShape;
///m_interpolationWorldTransform is used for CCD and interpolation
///it can be either previous or future (predicted) transform
@@ -50,12 +48,16 @@ protected:
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
+ btBroadphaseProxy* m_broadphaseHandle;
+ btCollisionShape* m_collisionShape;
int m_collisionFlags;
int m_islandTag1;
+ int m_companionId;
+
int m_activationState1;
- float m_deactivationTime;
+ btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
@@ -67,13 +69,23 @@ protected:
void* m_internalOwner;
///time of impact calculation
- float m_hitFraction;
+ btScalar m_hitFraction;
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
- float m_ccdSweptSphereRadius;
+ btScalar m_ccdSweptSphereRadius;
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
- float m_ccdSquareMotionThreshold;
+ btScalar m_ccdSquareMotionThreshold;
+
+ /// If some object should have elaborate collision filtering by sub-classes
+ bool m_checkCollideWith;
+
+ char m_pad[7];
+
+ virtual bool checkCollideWithOverride(btCollisionObject* co)
+ {
+ return true;
+ }
public:
@@ -82,7 +94,7 @@ public:
CF_STATIC_OBJECT= 1,
CF_KINEMATIC_OBJECT= 2,
CF_NO_CONTACT_RESPONSE = 4,
- CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
+ CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
};
@@ -114,6 +126,7 @@ public:
btCollisionObject();
+ virtual ~btCollisionObject();
void setCollisionShape(btCollisionShape* collisionShape)
{
@@ -137,11 +150,11 @@ public:
void setActivationState(int newState);
- void setDeactivationTime(float time)
+ void setDeactivationTime(btScalar time)
{
m_deactivationTime = time;
}
- float getDeactivationTime() const
+ btScalar getDeactivationTime() const
{
return m_deactivationTime;
}
@@ -155,19 +168,19 @@ public:
return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
}
- void setRestitution(float rest)
+ void setRestitution(btScalar rest)
{
m_restitution = rest;
}
- float getRestitution() const
+ btScalar getRestitution() const
{
return m_restitution;
}
- void setFriction(float frict)
+ void setFriction(btScalar frict)
{
m_friction = frict;
}
- float getFriction() const
+ btScalar getFriction() const
{
return m_friction;
}
@@ -251,12 +264,22 @@ public:
m_islandTag1 = tag;
}
- const float getHitFraction() const
+ const int getCompanionId() const
+ {
+ return m_companionId;
+ }
+
+ void setCompanionId(int id)
+ {
+ m_companionId = id;
+ }
+
+ const btScalar getHitFraction() const
{
return m_hitFraction;
}
- void setHitFraction(float hitFraction)
+ void setHitFraction(btScalar hitFraction)
{
m_hitFraction = hitFraction;
}
@@ -273,25 +296,25 @@ public:
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
- float getCcdSweptSphereRadius() const
+ btScalar getCcdSweptSphereRadius() const
{
return m_ccdSweptSphereRadius;
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
- void setCcdSweptSphereRadius(float radius)
+ void setCcdSweptSphereRadius(btScalar radius)
{
m_ccdSweptSphereRadius = radius;
}
- float getCcdSquareMotionThreshold() const
+ btScalar getCcdSquareMotionThreshold() const
{
return m_ccdSquareMotionThreshold;
}
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
- void setCcdSquareMotionThreshold(float ccdSquareMotionThreshold)
+ void setCcdSquareMotionThreshold(btScalar ccdSquareMotionThreshold)
{
m_ccdSquareMotionThreshold = ccdSquareMotionThreshold;
}
@@ -308,6 +331,16 @@ public:
m_userObjectPointer = userPointer;
}
-};
+ inline bool checkCollideWith(btCollisionObject* co)
+ {
+ if (m_checkCollideWith)
+ return checkCollideWithOverride(co);
+
+ return true;
+ }
+
+
+}
+;
#endif //COLLISION_OBJECT_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index fa1561973fb..b49036a5b50 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -17,6 +17,8 @@ subject to the following restrictions:
#include "btCollisionDispatcher.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+
#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" //for raycasting
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
@@ -31,7 +33,6 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
-#include <algorithm>
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize)
:m_dispatcher1(dispatcher),
@@ -50,13 +51,10 @@ btCollisionWorld::~btCollisionWorld()
delete m_stackAlloc;
//clean up remaining objects
- std::vector<btCollisionObject*>::iterator i;
-
- for (i=m_collisionObjects.begin();
- !(i==m_collisionObjects.end()); i++)
-
+ int i;
+ for (i=0;i<m_collisionObjects.size();i++)
{
- btCollisionObject* collisionObject= (*i);
+ btCollisionObject* collisionObject= m_collisionObjects[i];
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
@@ -89,9 +87,7 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
{
//check that the object isn't already added
- std::vector<btCollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
- assert(i == m_collisionObjects.end());
-
+ btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
m_collisionObjects.push_back(collisionObject);
@@ -125,13 +121,13 @@ void btCollisionWorld::performDiscreteCollisionDetection()
{
btDispatcherInfo& dispatchInfo = getDispatchInfo();
- BEGIN_PROFILE("performDiscreteCollisionDetection");
+ BEGIN_PROFILE("perform Broadphase Collision Detection");
//update aabb (of all moved objects)
btVector3 aabbMin,aabbMax;
- for (size_t i=0;i<m_collisionObjects.size();i++)
+ for (int i=0;i<m_collisionObjects.size();i++)
{
m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax);
m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax);
@@ -139,6 +135,11 @@ void btCollisionWorld::performDiscreteCollisionDetection()
m_broadphasePairCache->refreshOverlappingPairs();
+
+ END_PROFILE("perform Broadphase Collision Detection");
+
+ BEGIN_PROFILE("performDiscreteCollisionDetection");
+
btDispatcher* dispatcher = getDispatcher();
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo);
@@ -169,39 +170,53 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
}
- std::vector<btCollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
-
- if (!(i == m_collisionObjects.end()))
- {
- std::swap(*i, m_collisionObjects.back());
- m_collisionObjects.pop_back();
- }
+ //swapremove
+ m_collisionObjects.remove(collisionObject);
+
}
+
+
void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
- RayResultCallback& resultCallback)
+ RayResultCallback& resultCallback,short int collisionFilterMask)
+{
+
+ btSphereShape pointShape(btScalar(0.0));
+ pointShape.setMargin(0.f);
+
+ objectQuerySingle(&pointShape,rayFromTrans,rayToTrans,
+ collisionObject,
+ collisionShape,
+ colObjWorldTransform,
+ resultCallback,collisionFilterMask);
+}
+
+void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ btCollisionObject* collisionObject,
+ const btCollisionShape* collisionShape,
+ const btTransform& colObjWorldTransform,
+ RayResultCallback& resultCallback,short int collisionFilterMask)
{
- btSphereShape pointShape(0.0f);
if (collisionShape->isConvex())
{
btConvexCast::CastResult castResult;
- castResult.m_fraction = 1.f;//??
+ castResult.m_fraction = btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
- btSubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
- //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
- //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
+ btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
+ //GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
+ //ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
- if (castResult.m_normal.length2() > 0.0001f)
+ if (castResult.m_normal.length2() > btScalar(0.0001))
{
castResult.m_normal.normalize();
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
@@ -252,7 +267,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
- virtual float reportHit(const btVector3& hitNormalLocal, float hitFraction, int partId, int triangleIndex )
+ virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
@@ -294,11 +309,11 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
- rayTestSingle(rayFromTrans,rayToTrans,
+ objectQuerySingle(castShape, rayFromTrans,rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
- resultCallback);
+ resultCallback, collisionFilterMask);
}
@@ -308,7 +323,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
}
-void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback)
+void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
{
@@ -321,28 +336,26 @@ void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
- std::vector<btCollisionObject*>::iterator iter;
-
- for (iter=m_collisionObjects.begin();
- !(iter==m_collisionObjects.end()); iter++)
+ int i;
+ for (i=0;i<m_collisionObjects.size();i++)
{
-
- btCollisionObject* collisionObject= (*iter);
-
- //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
- btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
- collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
-
- float hitLambda = 1.f; //could use resultCallback.m_closestHitFraction, but needs testing
- btVector3 hitNormal;
- if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
- {
- rayTestSingle(rayFromTrans,rayToTrans,
- collisionObject,
- collisionObject->getCollisionShape(),
- collisionObject->getWorldTransform(),
- resultCallback);
-
+ btCollisionObject* collisionObject= m_collisionObjects[i];
+ //only perform raycast if filterMask matches
+ if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
+ //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+ collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+
+ btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
+ btVector3 hitNormal;
+ if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+ {
+ rayTestSingle(rayFromTrans,rayToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ resultCallback);
+ }
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
index bd09d8c4d5d..b6d80233ab7 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
@@ -53,9 +53,9 @@ subject to the following restrictions:
* Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
*
* @section copyright Copyright
- * Copyright (C) 2005-2006 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
+ * Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
* Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
- * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren.
+ * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
*
*/
@@ -66,16 +66,14 @@ subject to the following restrictions:
class btStackAlloc;
class btCollisionShape;
+class btConvexShape;
class btBroadphaseInterface;
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
#include "btCollisionObject.h"
#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
-#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
-
-#include <vector>
-
-
+#include "../BroadphaseCollision/btOverlappingPairCache.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
///CollisionWorld is interface and container for the collision detection
class btCollisionWorld
@@ -84,7 +82,7 @@ class btCollisionWorld
protected:
- std::vector<btCollisionObject*> m_collisionObjects;
+ btAlignedObjectArray<btCollisionObject*> m_collisionObjects;
btDispatcher* m_dispatcher1;
@@ -137,18 +135,18 @@ public:
LocalRayResult(btCollisionObject* collisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
- float hitFraction)
+ btScalar hitFraction)
:m_collisionObject(collisionObject),
- m_localShapeInfo(m_localShapeInfo),
+ m_localShapeInfo(localShapeInfo),
m_hitNormalLocal(hitNormalLocal),
m_hitFraction(hitFraction)
{
}
- btCollisionObject* m_collisionObject;
+ btCollisionObject* m_collisionObject;
LocalShapeInfo* m_localShapeInfo;
- const btVector3& m_hitNormalLocal;
- float m_hitFraction;
+ btVector3 m_hitNormalLocal;
+ btScalar m_hitFraction;
};
@@ -158,17 +156,17 @@ public:
virtual ~RayResultCallback()
{
}
- float m_closestHitFraction;
+ btScalar m_closestHitFraction;
bool HasHit()
{
- return (m_closestHitFraction < 1.f);
+ return (m_closestHitFraction < btScalar(1.));
}
RayResultCallback()
- :m_closestHitFraction(1.f)
+ :m_closestHitFraction(btScalar(1.))
{
}
- virtual float AddSingleResult(LocalRayResult& rayResult) = 0;
+ virtual btScalar AddSingleResult(LocalRayResult& rayResult) = 0;
};
struct ClosestRayResultCallback : public RayResultCallback
@@ -187,7 +185,7 @@ public:
btVector3 m_hitPointWorld;
btCollisionObject* m_collisionObject;
- virtual float AddSingleResult(LocalRayResult& rayResult)
+ virtual btScalar AddSingleResult(LocalRayResult& rayResult)
{
//caller already does the filter on the m_closestHitFraction
@@ -211,16 +209,23 @@ public:
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
- void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback);
+ void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1);
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
/// This allows more customization.
- void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ btCollisionObject* collisionObject,
+ const btCollisionShape* collisionShape,
+ const btTransform& colObjWorldTransform,
+ RayResultCallback& resultCallback, short int collisionFilterMask=-1);
+
+ /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
+ static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
- RayResultCallback& resultCallback);
+ RayResultCallback& resultCallback, short int collisionFilterMask=-1);
void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
index 43887d26a45..92f4c8b28a6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
@@ -77,9 +77,9 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
- btTransform childTrans = compoundShape->getChildTransform(i);
- btTransform newChildWorldTrans = orgTrans*childTrans ;
- colObj->setWorldTransform( newChildWorldTrans );
+ const btTransform& childTrans = compoundShape->getChildTransform(i);
+ //btTransform newChildWorldTrans = orgTrans*childTrans ;
+ colObj->setWorldTransform( orgTrans*childTrans );
//the contactpoint is still projected back using the original inverted worldtrans
colObj->setCollisionShape( childShape );
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
@@ -89,7 +89,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
}
}
-float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* colObj = m_isSwapped? body1 : body0;
@@ -106,7 +106,7 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* bod
//then use each overlapping node AABB against Tree0
//and vise versa.
- float hitFraction = 1.f;
+ btScalar hitFraction = btScalar(1.);
int numChildren = m_childCollisionAlgorithms.size();
int i;
@@ -119,12 +119,12 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* bod
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
- btTransform childTrans = compoundShape->getChildTransform(i);
- btTransform newChildWorldTrans = orgTrans*childTrans ;
- colObj->setWorldTransform( newChildWorldTrans );
+ const btTransform& childTrans = compoundShape->getChildTransform(i);
+ //btTransform newChildWorldTrans = orgTrans*childTrans ;
+ colObj->setWorldTransform( orgTrans*childTrans );
colObj->setCollisionShape( childShape );
- float frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
+ btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction)
{
hitFraction = frac;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
index fe2d8628656..7091b233b46 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
@@ -16,21 +16,21 @@ subject to the following restrictions:
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btDispatcher.h"
+#include "../BroadphaseCollision/btBroadphaseInterface.h"
-#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "../NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include <vector>
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
/// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{
- std::vector<btCollisionAlgorithm*> m_childCollisionAlgorithms;
+ btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;
public:
@@ -41,7 +41,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
index 06adb3a04c8..24ceacfd40d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
@@ -95,7 +95,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
//btVector3 center = triangle[0] + triangle[1]+triangle[2];
- //center *= 0.333333f;
+ //center *= btScalar(0.333333);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
@@ -134,7 +134,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
-void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle;
@@ -146,7 +146,7 @@ void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTrian
btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
- float extraMargin = collisionMarginTriangle;
+ btScalar extraMargin = collisionMarginTriangle;
btVector3 extra(extraMargin,extraMargin,extraMargin);
m_aabbMax += extra;
@@ -176,7 +176,7 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
if (convexBody->getCollisionShape()->isConvex())
{
- float collisionMarginTriangle = concaveShape->getMargin();
+ btScalar collisionMarginTriangle = concaveShape->getMargin();
resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
@@ -196,9 +196,10 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
}
-float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
-
+ (void)resultOut;
+ (void)dispatchInfo;
btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
@@ -207,10 +208,10 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
//only perform CCD above a certain threshold, this prevents blocking on the long run
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
- float squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
+ btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
{
- return 1.f;
+ return btScalar(1.);
}
//const btVector3& from = convexbody->m_worldTransform.getOrigin();
@@ -227,11 +228,11 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
btTransform m_ccdSphereToTrans;
btTransform m_meshTransform;
- float m_ccdSphereRadius;
- float m_hitFraction;
+ btScalar m_ccdSphereRadius;
+ btScalar m_hitFraction;
- LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,float ccdSphereRadius,float hitFraction)
+ LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
:m_ccdSphereFromTrans(from),
m_ccdSphereToTrans(to),
m_ccdSphereRadius(ccdSphereRadius),
@@ -242,6 +243,8 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
+ (void)partId;
+ (void)triangleIndex;
//do a swept sphere for now
btTransform ident;
ident.setIdentity();
@@ -276,11 +279,11 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
rayAabbMin.setMin(convexToLocal.getOrigin());
btVector3 rayAabbMax = convexFromLocal.getOrigin();
rayAabbMax.setMax(convexToLocal.getOrigin());
- float ccdRadius0 = convexbody->getCcdSweptSphereRadius();
+ btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
- float curHitFraction = 1.f; //is this available?
+ btScalar curHitFraction = btScalar(1.); //is this available?
LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
convexbody->getCcdSweptSphereRadius(),curHitFraction);
@@ -304,6 +307,6 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
}
}
- return 1.f;
+ return btScalar(1.);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
index afcb38c94ef..4915b6c20c8 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
@@ -16,13 +16,13 @@ subject to the following restrictions:
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
-#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
-#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btDispatcher.h"
+#include "../BroadphaseCollision/btBroadphaseInterface.h"
+#include "../CollisionShapes/btTriangleCallback.h"
+#include "../NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
@@ -38,7 +38,7 @@ class btConvexTriangleCallback : public btTriangleCallback
btDispatcher* m_dispatcher;
const btDispatcherInfo* m_dispatchInfoPtr;
- float m_collisionMarginTriangle;
+ btScalar m_collisionMarginTriangle;
public:
int m_triangleCount;
@@ -47,7 +47,7 @@ int m_triangleCount;
btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
- void setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btConvexTriangleCallback();
@@ -86,7 +86,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void clearCache();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
index 09457aea3e9..9105fe20b49 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
@@ -43,23 +43,9 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-#ifdef WIN32
-#if _MSC_VER >= 1310
-//only use SIMD Hull code under Win32
-#ifdef TEST_HULL
-#define USE_HULL 1
-#endif //TEST_HULL
-#endif //_MSC_VER
-#endif //WIN32
-#ifdef USE_HULL
-#include "NarrowPhaseCollision/Hull.h"
-#include "NarrowPhaseCollision/HullContactCollector.h"
-
-
-#endif //USE_HULL
btConvexConvexAlgorithm::CreateFunc::CreateFunc()
@@ -76,6 +62,14 @@ btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simp
m_pdSolver = pdSolver;
}
+btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
+{
+ if (m_ownsSolvers){
+ delete m_simplexSolver;
+ delete m_pdSolver;
+ }
+}
+
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
: btCollisionAlgorithm(ci),
m_gjkPairDetector(0,0,simplexSolver,pdSolver),
@@ -83,6 +77,9 @@ m_ownManifold (false),
m_manifoldPtr(mf),
m_lowLevelOfDetail(false)
{
+ (void)body0;
+ (void)body1;
+
}
@@ -147,7 +144,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
-// input.m_maximumDistanceSquared = 1e30f;
+// input.m_maximumDistanceSquared = btScalar(1e30);
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
@@ -160,24 +157,26 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
bool disableCcd = false;
-float btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)resultOut;
+ (void)dispatchInfo;
///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
///col0->m_worldTransform,
- float resultFraction = 1.f;
+ btScalar resultFraction = btScalar(1.);
- float squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
- float squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
+ btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
+ btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
if (squareMot0 < col0->getCcdSquareMotionThreshold() &&
squareMot1 < col1->getCcdSquareMotionThreshold())
return resultFraction;
if (disableCcd)
- return 1.f;
+ return btScalar(1.);
//An adhoc way of testing the Continuous Collision Detection algorithms
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
index ccfe6d5b8cb..cbea9a92b75 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
@@ -16,11 +16,11 @@ subject to the following restrictions:
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
-#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../NarrowPhaseCollision/btGjkPairDetector.h"
+#include "../NarrowPhaseCollision/btPersistentManifold.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "btCollisionCreateFunc.h"
class btConvexPenetrationDepthSolver;
@@ -44,7 +44,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void setLowLevelOfDetail(bool useLowLevel);
@@ -62,6 +62,7 @@ public:
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
CreateFunc();
+ virtual ~CreateFunc();
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
index 9bc106564af..936054387c4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
@@ -22,14 +22,13 @@ btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& c
{
}
-void btEmptyAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
{
-
}
-float btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
{
- return 1.f;
+ return btScalar(1.);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
index e0e136250ac..b1a193d2cfd 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
@@ -15,7 +15,7 @@ subject to the following restrictions:
#ifndef EMPTY_ALGORITH
#define EMPTY_ALGORITH
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "btCollisionCreateFunc.h"
#define ATTRIBUTE_ALIGNED(a)
@@ -31,12 +31,14 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
+ (void)body0;
+ (void)body1;
return new btEmptyAlgorithm(ci);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
index cd22f3dd91e..490acc0b611 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
@@ -27,7 +27,7 @@ inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const b
{
btScalar friction = body0->getFriction() * body1->getFriction();
- const btScalar MAX_FRICTION = 10.f;
+ const btScalar MAX_FRICTION = btScalar(10.);
if (friction < -MAX_FRICTION)
friction = -MAX_FRICTION;
if (friction > MAX_FRICTION)
@@ -53,7 +53,7 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
}
-void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
+void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
assert(m_manifoldPtr);
//order in manifold needs to match
@@ -63,15 +63,22 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
- btTransform transAInv = isSwapped? m_rootTransB.inverse() : m_rootTransA.inverse();
- btTransform transBInv = isSwapped? m_rootTransA.inverse() : m_rootTransB.inverse();
-
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
- btVector3 localA = transAInv(pointA );
- btVector3 localB = transBInv(pointInWorld);
- btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
+ btVector3 localA;
+ btVector3 localB;
+ if (isSwapped)
+ {
+ localA = m_rootTransB.invXform(pointA );
+ localB = m_rootTransA.invXform(pointInWorld);
+ } else
+ {
+ localA = m_rootTransA.invXform(pointA );
+ localB = m_rootTransB.invXform(pointInWorld);
+ }
+
+ btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
index 3d70689e3eb..77192625513 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
@@ -23,7 +23,7 @@ class btManifoldPoint;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btTransform.h"
+#include "../../LinearMath/btTransform.h"
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback;
@@ -68,7 +68,7 @@ public:
m_index1=index1;
}
- virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth);
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
index 06a5f95143e..ac2e8554c3a 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
@@ -8,8 +8,7 @@
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
#include <stdio.h>
-#include <algorithm>
-
+#include "LinearMath/btQuickprof.h"
btSimulationIslandManager::btSimulationIslandManager()
{
@@ -33,7 +32,7 @@ void btSimulationIslandManager::findUnions(btDispatcher* dispatcher)
for (int i=0;i<dispatcher->getNumManifolds();i++)
{
const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
- //static objects (invmass 0.f) don't merge !
+ //static objects (invmass btScalar(0.)) don't merge !
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
@@ -57,16 +56,15 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
// put the index into m_controllers into m_tag
{
- std::vector<btCollisionObject*>::iterator i;
int index = 0;
- for (i=colWorld->getCollisionObjectArray().begin();
- !(i==colWorld->getCollisionObjectArray().end()); i++)
+ int i;
+ for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
{
-
- btCollisionObject* collisionObject= (*i);
+ btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
collisionObject->setIslandTag(index);
- collisionObject->setHitFraction(1.f);
+ collisionObject->setCompanionId(-1);
+ collisionObject->setHitFraction(btScalar(1.));
index++;
}
@@ -88,20 +86,19 @@ void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* col
{
- std::vector<btCollisionObject*>::iterator i;
-
int index = 0;
- for (i=colWorld->getCollisionObjectArray().begin();
- !(i==colWorld->getCollisionObjectArray().end()); i++)
+ int i;
+ for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
{
- btCollisionObject* collisionObject= (*i);
-
+ btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
if (collisionObject->mergesSimulationIslands())
{
collisionObject->setIslandTag( m_unionFind.find(index) );
+ collisionObject->setCompanionId(-1);
} else
{
collisionObject->setIslandTag(-1);
+ collisionObject->setCompanionId(-2);
}
index++;
}
@@ -118,13 +115,21 @@ inline int getIslandId(const btPersistentManifold* lhs)
}
-bool btPersistentManifoldSortPredicate(const btPersistentManifold* lhs, const btPersistentManifold* rhs)
+
+
+/// function object that routes calls to operator<
+class btPersistentManifoldSortPredicate
{
- int rIslandId0,lIslandId0;
- rIslandId0 = getIslandId(rhs);
- lIslandId0 = getIslandId(lhs);
- return lIslandId0 < rIslandId0;
-}
+ public:
+
+ SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs )
+ {
+ return getIslandId(lhs) < getIslandId(rhs);
+ }
+};
+
+
+
//
@@ -132,6 +137,22 @@ bool btPersistentManifoldSortPredicate(const btPersistentManifold* lhs, const bt
//
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
{
+
+
+
+ /*if (0)
+ {
+ int maxNumManifolds = dispatcher->getNumManifolds();
+ btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher;
+ btPersistentManifold** manifold = colDis->getInternalManifoldPointer();
+ callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0);
+ return;
+ }
+ */
+
+
+ BEGIN_PROFILE("islandUnionFindAndHeapSort");
+
//we are going to sort the unionfind array, and store the element id in the size
//afterwards, we clean unionfind, to make sure no-one uses it anymore
@@ -139,9 +160,11 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
int numElem = getUnionFind().getNumElements();
int endIslandIndex=1;
+ int startIslandIndex;
+
//update the sleeping state for bodies, if all are sleeping
- for (int startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
+ for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
{
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
@@ -224,7 +247,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
}
}
- std::vector<btPersistentManifold*> islandmanifold;
+ btAlignedObjectArray<btPersistentManifold*> islandmanifold;
int i;
int maxNumManifolds = dispatcher->getNumManifolds();
islandmanifold.reserve(maxNumManifolds);
@@ -261,63 +284,74 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
// Sort manifolds, based on islands
// Sort the vector using predicate and std::sort
- std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
+ //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
+
+ //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
+ islandmanifold.heapSort(btPersistentManifoldSortPredicate());
//now process all active islands (sets of manifolds for now)
int startManifoldIndex = 0;
int endManifoldIndex = 1;
- int islandId;
+ //int islandId;
+
+ END_PROFILE("islandUnionFindAndHeapSort");
+
+ btAlignedObjectArray<btCollisionObject*> islandBodies;
- //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
- for (int startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
- {
- int islandId = getUnionFind().getElement(startIslandIndex).m_id;
-
-
- bool islandSleeping = false;
+ //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
+ for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
+ {
+ int islandId = getUnionFind().getElement(startIslandIndex).m_id;
+
+
+ bool islandSleeping = false;
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
{
int i = getUnionFind().getElement(endIslandIndex).m_sz;
btCollisionObject* colObj0 = collisionObjects[i];
+ islandBodies.push_back(colObj0);
if (!colObj0->isActive())
islandSleeping = true;
}
- //find the accompanying contact manifold for this islandId
- int numIslandManifolds = 0;
- btPersistentManifold** startManifold = 0;
+ //find the accompanying contact manifold for this islandId
+ int numIslandManifolds = 0;
+ btPersistentManifold** startManifold = 0;
- if (startManifoldIndex<numManifolds)
- {
- int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
- if (curIslandId == islandId)
- {
- startManifold = &islandmanifold[startManifoldIndex];
-
- for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
- {
+ if (startManifoldIndex<numManifolds)
+ {
+ int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
+ if (curIslandId == islandId)
+ {
+ startManifold = &islandmanifold[startManifoldIndex];
+
+ for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
+ {
- }
- /// Process the actual simulation, only if not sleeping/deactivated
- numIslandManifolds = endManifoldIndex-startManifoldIndex;
- }
+ }
+ /// Process the actual simulation, only if not sleeping/deactivated
+ numIslandManifolds = endManifoldIndex-startManifoldIndex;
+ }
- }
+ }
- if (!islandSleeping)
- {
- callback->ProcessIsland(startManifold,numIslandManifolds, islandId);
- }
+ if (!islandSleeping)
+ {
+ callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
+ }
+
+ if (numIslandManifolds)
+ {
+ startManifoldIndex = endManifoldIndex;
+ }
- if (numIslandManifolds)
- {
- startManifoldIndex = endManifoldIndex;
- }
- }
+ islandBodies.resize(0);
+ }
+
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
index 68d9b8038d6..d91ed1c20eb 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
@@ -16,9 +16,10 @@ subject to the following restrictions:
#ifndef SIMULATION_ISLAND_MANAGER_H
#define SIMULATION_ISLAND_MANAGER_H
-#include "BulletCollision/CollisionDispatch/btUnionFind.h"
+#include "../CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
+class btCollisionObject;
class btCollisionWorld;
class btDispatcher;
@@ -49,7 +50,7 @@ public:
{
virtual ~IslandCallback() {};
- virtual void ProcessIsland(class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
+ virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
};
void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
index 1423c335407..05556bd34e2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
@@ -50,6 +50,8 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)dispatchInfo;
+ (void)resultOut;
if (!m_manifoldPtr)
return;
@@ -64,7 +66,7 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin();
btScalar radius = sphere0->getRadius();
- float dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
+ btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
if (dist < SIMD_EPSILON)
{
@@ -81,10 +83,15 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
}
-float btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)resultOut;
+ (void)dispatchInfo;
+ (void)col0;
+ (void)col1;
+
//not yet
- return 1.f;
+ return btScalar(1.);
}
@@ -117,14 +124,14 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
/////////////////////////////////////////////////
btVector3 tmp, prel, n[6], normal, v3P;
- btScalar fSep = 10000000.0f, fSepThis;
+ btScalar fSep = btScalar(10000000.0), fSepThis;
- n[0].setValue( -1.0f, 0.0f, 0.0f );
- n[1].setValue( 0.0f, -1.0f, 0.0f );
- n[2].setValue( 0.0f, 0.0f, -1.0f );
- n[3].setValue( 1.0f, 0.0f, 0.0f );
- n[4].setValue( 0.0f, 1.0f, 0.0f );
- n[5].setValue( 0.0f, 0.0f, 1.0f );
+ n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) );
+ n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) );
+ n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) );
+ n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) );
+ n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) );
+ n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) );
// convert point in local space
prel = m44T.invXform( sphereCenter);
@@ -136,7 +143,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
for (int i=0;i<6;i++)
{
int j = i<3? 0:1;
- if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > 0.0f )
+ if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) )
{
v3P = v3P - n[i]*fSepThis;
bFound = true;
@@ -154,9 +161,9 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
pointOnBox = v3P + normal*margins;
v3PointOnSphere = prel - normal*fRadius;
- if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > 0.0f )
+ if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) )
{
- return 1.0f;
+ return btScalar(1.0);
}
// transform back in world space
@@ -171,7 +178,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
{
fSep = - btSqrt(fSeps2);
normal = (pointOnBox-v3PointOnSphere);
- normal *= 1.f/fSep;
+ normal *= btScalar(1.)/fSep;
}
return fSep;
@@ -185,10 +192,10 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
- if ( fPenetration <= 0.0f )
+ if ( fPenetration <= btScalar(0.0) )
return (fPenetration-margins);
else
- return 1.0f;
+ return btScalar(1.0);
}
btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax)
@@ -200,14 +207,14 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
bounds[1] = aabbMax;
btVector3 p0, tmp, prel, n[6], normal;
- btScalar fSep = -10000000.0f, fSepThis;
+ btScalar fSep = btScalar(-10000000.0), fSepThis;
- n[0].setValue( -1.0f, 0.0f, 0.0f );
- n[1].setValue( 0.0f, -1.0f, 0.0f );
- n[2].setValue( 0.0f, 0.0f, -1.0f );
- n[3].setValue( 1.0f, 0.0f, 0.0f );
- n[4].setValue( 0.0f, 1.0f, 0.0f );
- n[5].setValue( 0.0f, 0.0f, 1.0f );
+ n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) );
+ n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) );
+ n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) );
+ n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) );
+ n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) );
+ n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) );
const btTransform& m44T = boxObj->getWorldTransform();
@@ -219,7 +226,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
for (int i=0;i<6;i++)
{
int j = i<3 ? 0:1;
- if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > 0.0f ) return 1.0f;
+ if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > btScalar(0.0) ) return btScalar(1.0);
if ( fSepThis > fSep )
{
p0 = bounds[j]; normal = (btVector3&)n[i];
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
index 68915a43e6f..07592909200 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
@@ -16,11 +16,11 @@ subject to the following restrictions:
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
@@ -38,7 +38,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
index eb05bf974c5..424ff432f84 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
@@ -41,6 +41,8 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)dispatchInfo;
+
if (!m_manifoldPtr)
return;
@@ -48,7 +50,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin();
- float len = diff.length();
+ btScalar len = diff.length();
btScalar radius0 = sphere0->getRadius();
btScalar radius1 = sphere1->getRadius();
@@ -71,8 +73,13 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
}
-float btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)col0;
+ (void)col1;
+ (void)dispatchInfo;
+ (void)resultOut;
+
//not yet
- return 1.f;
+ return btScalar(1.);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
index 8b08d015aec..7a19ff31edf 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
@@ -16,9 +16,9 @@ subject to the following restrictions:
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
@@ -37,7 +37,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btSphereSphereCollisionAlgorithm();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
index 6f74c488659..b011b707e3f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
@@ -56,7 +56,7 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
SphereTriangleDetector detector(sphere,triangle);
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
- input.m_maximumDistanceSquared = 1e30f;//todo: tighter bounds
+ input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
input.m_transformA = col0->getWorldTransform();
input.m_transformB = col1->getWorldTransform();
@@ -64,8 +64,13 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
}
-float btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
+ (void)resultOut;
+ (void)dispatchInfo;
+ (void)col0;
+ (void)col1;
+
//not yet
- return 1.f;
+ return btScalar(1.);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
index 82e4c5b37f1..57c6e6af619 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
@@ -16,9 +16,9 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "../BroadphaseCollision/btCollisionAlgorithm.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
@@ -38,7 +38,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btSphereTriangleCollisionAlgorithm();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
index 046f348a147..62254335796 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
@@ -15,7 +15,6 @@ subject to the following restrictions:
#include "btUnionFind.h"
#include <assert.h>
-#include <algorithm>
@@ -50,11 +49,16 @@ void btUnionFind::reset(int N)
}
}
-bool btUnionFindElementSortPredicate(const btElement& lhs, const btElement& rhs)
+
+class btUnionFindElementSortPredicate
{
- return lhs.m_id < rhs.m_id;
-}
+ public:
+ bool operator() ( const btElement& lhs, const btElement& rhs )
+ {
+ return lhs.m_id < rhs.m_id;
+ }
+};
///this is a special operation, destroying the content of btUnionFind.
///it sorts the elements, based on island id, in order to make it easy to iterate over islands
@@ -71,7 +75,9 @@ void btUnionFind::sortIslands()
}
// Sort the vector using predicate and std::sort
- std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
+ //std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
+ //perhaps use radix sort?
+ m_elements.heapSort(btUnionFindElementSortPredicate());
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
index b1baca9ff15..236cc33b94f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
@@ -16,7 +16,10 @@ subject to the following restrictions:
#ifndef UNION_FIND_H
#define UNION_FIND_H
-#include <vector>
+#include "../../LinearMath/btAlignedObjectArray.h"
+
+ #define USE_PATH_COMPRESSION 1
+
struct btElement
{
int m_id;
@@ -29,7 +32,7 @@ struct btElement
class btUnionFind
{
private:
- std::vector<btElement> m_elements;
+ btAlignedObjectArray<btElement> m_elements;
public:
@@ -78,6 +81,7 @@ class btUnionFind
if (i == j)
return;
+#ifndef USE_PATH_COMPRESSION
//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
if (m_elements[i].m_sz < m_elements[j].m_sz)
{
@@ -87,6 +91,9 @@ class btUnionFind
{
m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz;
}
+#else
+ m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz;
+#endif //USE_PATH_COMPRESSION
}
int find(int x)
@@ -97,7 +104,7 @@ class btUnionFind
while (x != m_elements[x].m_id)
{
//not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
- #define USE_PATH_COMPRESSION 1
+
#ifdef USE_PATH_COMPRESSION
//
m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp
index b5f80de4557..636b0046c13 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.cpp
@@ -42,17 +42,16 @@ void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabb
void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
- //float margin = 0.f;
+ //btScalar margin = btScalar(0.);
btVector3 halfExtents = getHalfExtents();
- btScalar lx=2.f*(halfExtents.x());
- btScalar ly=2.f*(halfExtents.y());
- btScalar lz=2.f*(halfExtents.z());
-
- inertia[0] = mass/(12.0f) * (ly*ly + lz*lz);
- inertia[1] = mass/(12.0f) * (lx*lx + lz*lz);
- inertia[2] = mass/(12.0f) * (lx*lx + ly*ly);
+ btScalar lx=btScalar(2.)*(halfExtents.x());
+ btScalar ly=btScalar(2.)*(halfExtents.y());
+ btScalar lz=btScalar(2.)*(halfExtents.z());
+ inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
+ mass/(btScalar(12.0)) * (lx*lx + lz*lz),
+ mass/(btScalar(12.0)) * (lx*lx + ly*ly));
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
index ee451a9b6c0..bc42f146c7c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
@@ -17,10 +17,10 @@ subject to the following restrictions:
#define OBB_BOX_MINKOWSKI_H
#include "btPolyhedralConvexShape.h"
-#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "LinearMath/btPoint3.h"
-#include "LinearMath/btSimdMinMax.h"
+#include "btCollisionMargin.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
+#include "../../LinearMath/btPoint3.h"
+#include "../../LinearMath/btSimdMinMax.h"
///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box
class btBoxShape: public btPolyhedralConvexShape
@@ -41,9 +41,9 @@ public:
btVector3 halfExtents = getHalfExtents();
btVector3 supVertex;
- supVertex = btPoint3(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
- vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
- vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+ supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
+ vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
+ vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
return supVertex;
}
@@ -54,9 +54,9 @@ public:
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents -= margin;
- return btVector3(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
- vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
- vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+ return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
+ vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
+ vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
@@ -69,9 +69,9 @@ public:
for (int i=0;i<numVectors;i++)
{
const btVector3& vec = vectors[i];
- supportVerticesOut[i].setValue(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
- vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
- vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+ supportVerticesOut[i].setValue(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
+ vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
+ vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
}
@@ -132,27 +132,27 @@ public:
switch (i)
{
case 0:
- plane.setValue(1.f,0.f,0.f);
+ plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
plane[3] = -halfExtents.x();
break;
case 1:
- plane.setValue(-1.f,0.f,0.f);
+ plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
plane[3] = -halfExtents.x();
break;
case 2:
- plane.setValue(0.f,1.f,0.f);
+ plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
plane[3] = -halfExtents.y();
break;
case 3:
- plane.setValue(0.f,-1.f,0.f);
+ plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
plane[3] = -halfExtents.y();
break;
case 4:
- plane.setValue(0.f,0.f,1.f);
+ plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
plane[3] = -halfExtents.z();
break;
case 5:
- plane.setValue(0.f,0.f,-1.f);
+ plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
plane[3] = -halfExtents.z();
break;
default:
@@ -265,22 +265,22 @@ public:
switch (index)
{
case 0:
- penetrationVector.setValue(1.f,0.f,0.f);
+ penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
break;
case 1:
- penetrationVector.setValue(-1.f,0.f,0.f);
+ penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
break;
case 2:
- penetrationVector.setValue(0.f,1.f,0.f);
+ penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
break;
case 3:
- penetrationVector.setValue(0.f,-1.f,0.f);
+ penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
break;
case 4:
- penetrationVector.setValue(0.f,0.f,1.f);
+ penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
break;
case 5:
- penetrationVector.setValue(0.f,0.f,-1.f);
+ penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
break;
default:
assert(0);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
index 3bd0a317545..8da554ef14d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
@@ -18,21 +18,53 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
+
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
-btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface)
-:btTriangleMeshShape(meshInterface)
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
+:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
m_bvh = new btOptimizedBvh();
- m_bvh->build(meshInterface);
+ btVector3 bvhAabbMin,bvhAabbMax;
+ meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
+ m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
#endif //DISABLE_BVH
}
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
+:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
+{
+ //construct bvh from meshInterface
+#ifndef DISABLE_BVH
+
+ m_bvh = new btOptimizedBvh();
+ m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+
+#endif //DISABLE_BVH
+
+}
+
+void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
+
+ m_localAabbMin.setMin(aabbMin);
+ m_localAabbMax.setMax(aabbMax);
+}
+
+
+void btBvhTriangleMeshShape::refitTree()
+{
+ m_bvh->refit( m_meshInterface );
+
+ recalcLocalAabb();
+}
+
btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
{
delete m_bvh;
@@ -63,7 +95,7 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
{
}
- virtual void processNode(const btOptimizedBvhNode* node)
+ virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
{
const unsigned char *vertexbase;
int numverts;
@@ -84,19 +116,21 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
indexstride,
numfaces,
indicestype,
- node->m_subPart);
+ nodeSubPart);
- int* gfxbase = (int*)(indexbase+node->m_triangleIndex*indexstride);
-
+ int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
+
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = gfxbase[j];
+
+
#ifdef DEBUG_TRIANGLE_MESH
printf("%d ,",graphicsindex);
#endif //DEBUG_TRIANGLE_MESH
- float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+ btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(
graphicsbase[0]*meshScaling.getX(),
@@ -107,8 +141,8 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
#endif //DEBUG_TRIANGLE_MESH
}
- m_callback->processTriangle(m_triangle,node->m_subPart,node->m_triangleIndex);
- m_meshInterface->unLockReadOnlyVertexBase(node->m_subPart);
+ m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+ m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
}
};
@@ -130,8 +164,10 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
btTriangleMeshShape::setLocalScaling(scaling);
delete m_bvh;
+ ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
m_bvh = new btOptimizedBvh();
- m_bvh->build(m_meshInterface);
//rebuild the bvh...
+ m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
+
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
index 59a27e8641a..4914d9f959c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
@@ -16,20 +16,26 @@ subject to the following restrictions:
#ifndef BVH_TRIANGLE_MESH_SHAPE_H
#define BVH_TRIANGLE_MESH_SHAPE_H
-#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
-#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
+#include "btTriangleMeshShape.h"
+#include "btOptimizedBvh.h"
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
-class btBvhTriangleMeshShape : public btTriangleMeshShape
+ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
{
btOptimizedBvh* m_bvh;
-
-
+ bool m_useQuantizedAabbCompression;
+ bool m_pad[12];////need padding due to alignment
+
public:
- btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface);
+ btBvhTriangleMeshShape() :btTriangleMeshShape(0) {};
+ btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression);
+
+ ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
+ btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
+
virtual ~btBvhTriangleMeshShape();
@@ -44,6 +50,10 @@ public:
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ void refitTree();
+
+ ///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks
+ void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
//debugging
virtual char* getName()const {return "BVHTRIANGLEMESH";}
@@ -51,8 +61,15 @@ public:
virtual void setLocalScaling(const btVector3& scaling);
-
-
-};
+ btOptimizedBvh* getOptimizedBvh()
+ {
+ return m_bvh;
+ }
+ bool usesQuantizedAabbCompression() const
+ {
+ return m_useQuantizedAabbCompression;
+ }
+}
+;
#endif //BVH_TRIANGLE_MESH_SHAPE_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
new file mode 100644
index 00000000000..b7e15172da2
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
@@ -0,0 +1,146 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "btCapsuleShape.h"
+
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "LinearMath/btQuaternion.h"
+
+btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
+{
+ m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
+}
+
+
+ btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+
+ btVector3 supVec(0,0,0);
+
+ btScalar maxDot(btScalar(-1e30));
+
+ btVector3 vec = vec0;
+ btScalar lenSqr = vec.length2();
+ if (lenSqr < btScalar(0.0001))
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+ vec *= rlen;
+ }
+
+ btVector3 vtx;
+ btScalar newDot;
+
+ btScalar radius = getRadius();
+
+
+ {
+ btVector3 pos(0,getHalfHeight(),0);
+ vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ {
+ btVector3 pos(0,-getHalfHeight(),0);
+ vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+
+ return supVec;
+
+}
+
+ void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+
+
+ btScalar radius = getRadius();
+
+ for (int j=0;j<numVectors;j++)
+ {
+ btScalar maxDot(btScalar(-1e30));
+ const btVector3& vec = vectors[j];
+
+ btVector3 vtx;
+ btScalar newDot;
+ {
+ btVector3 pos(0,getHalfHeight(),0);
+ vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supportVerticesOut[j] = vtx;
+ }
+ }
+ {
+ btVector3 pos(0,-getHalfHeight(),0);
+ vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supportVerticesOut[j] = vtx;
+ }
+ }
+
+ }
+}
+
+
+void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+{
+ //as an approximation, take the inertia of the box that bounds the spheres
+
+ btTransform ident;
+ ident.setIdentity();
+
+
+ btScalar radius = getRadius();
+
+ btVector3 halfExtents(radius,radius+getHalfHeight(),radius);
+
+ btScalar margin = CONVEX_DISTANCE_MARGIN;
+
+ btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
+ btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
+ btScalar lz=btScalar(2.)*(halfExtents[2]+margin);
+ const btScalar x2 = lx*lx;
+ const btScalar y2 = ly*ly;
+ const btScalar z2 = lz*lz;
+ const btScalar scaledmass = mass * btScalar(.08333333);
+
+ inertia[0] = scaledmass * (y2+z2);
+ inertia[1] = scaledmass * (x2+z2);
+ inertia[2] = scaledmass * (x2+y2);
+
+}
+
+
+
+
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
new file mode 100644
index 00000000000..27da8adefa5
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
@@ -0,0 +1,60 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_CAPSULE_SHAPE_H
+#define BT_CAPSULE_SHAPE_H
+
+#include "btConvexShape.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+
+///btCapsuleShape represents a capsule around the Y axis
+///A more general solution that can represent capsules is the btMultiSphereShape
+class btCapsuleShape : public btConvexShape
+{
+
+public:
+ btCapsuleShape(btScalar radius,btScalar height);
+
+ ///CollisionShape Interface
+ virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
+
+ /// btConvexShape Interface
+ virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+
+ virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+ virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
+
+ virtual char* getName()const
+ {
+ return "CapsuleShape";
+ }
+
+ btScalar getRadius() const
+ {
+ return m_implicitShapeDimensions.getX();
+ }
+
+ btScalar getHalfHeight() const
+ {
+ return m_implicitShapeDimensions.getY();
+ }
+
+};
+
+
+
+#endif //BT_CAPSULE_SHAPE_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h
index 377f0e506a2..4730264d3df 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionMargin.h
@@ -18,7 +18,7 @@ subject to the following restrictions:
//used by Gjk and some other algorithms
-#define CONVEX_DISTANCE_MARGIN 0.04f// 0.1f//;//0.01f
+#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
index 5474a201c37..81d82428f4c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
@@ -15,6 +15,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+
+/*
+ Make sure this dummy function never changes so that it
+ can be used by probes that are checking whether the
+ library is actually installed.
+*/
+extern "C" void btBulletCollisionProbe () {}
+
+
+
void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const
{
btTransform tr;
@@ -23,14 +33,14 @@ void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) con
getAabb(tr,aabbMin,aabbMax);
- radius = (aabbMax-aabbMin).length()*0.5f;
- center = (aabbMin+aabbMax)*0.5f;
+ radius = (aabbMax-aabbMin).length()*btScalar(0.5);
+ center = (aabbMin+aabbMax)*btScalar(0.5);
}
-float btCollisionShape::getAngularMotionDisc() const
+btScalar btCollisionShape::getAngularMotionDisc() const
{
btVector3 center;
- float disc;
+ btScalar disc;
getBoundingSphere(center,disc);
disc += (center).length();
return disc;
@@ -41,25 +51,25 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b
//start with static aabb
getAabb(curTrans,temporalAabbMin,temporalAabbMax);
- float temporalAabbMaxx = temporalAabbMax.getX();
- float temporalAabbMaxy = temporalAabbMax.getY();
- float temporalAabbMaxz = temporalAabbMax.getZ();
- float temporalAabbMinx = temporalAabbMin.getX();
- float temporalAabbMiny = temporalAabbMin.getY();
- float temporalAabbMinz = temporalAabbMin.getZ();
+ btScalar temporalAabbMaxx = temporalAabbMax.getX();
+ btScalar temporalAabbMaxy = temporalAabbMax.getY();
+ btScalar temporalAabbMaxz = temporalAabbMax.getZ();
+ btScalar temporalAabbMinx = temporalAabbMin.getX();
+ btScalar temporalAabbMiny = temporalAabbMin.getY();
+ btScalar temporalAabbMinz = temporalAabbMin.getZ();
// add linear motion
btVector3 linMotion = linvel*timeStep;
//todo: simd would have a vector max/min operation, instead of per-element access
- if (linMotion.x() > 0.f)
+ if (linMotion.x() > btScalar(0.))
temporalAabbMaxx += linMotion.x();
else
temporalAabbMinx += linMotion.x();
- if (linMotion.y() > 0.f)
+ if (linMotion.y() > btScalar(0.))
temporalAabbMaxy += linMotion.y();
else
temporalAabbMiny += linMotion.y();
- if (linMotion.z() > 0.f)
+ if (linMotion.z() > btScalar(0.))
temporalAabbMaxz += linMotion.z();
else
temporalAabbMinz += linMotion.z();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
index 7b2a00a1c57..96268734a83 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
@@ -16,18 +16,18 @@ subject to the following restrictions:
#ifndef COLLISION_SHAPE_H
#define COLLISION_SHAPE_H
-#include "LinearMath/btTransform.h"
-#include "LinearMath/btVector3.h"
-#include <LinearMath/btMatrix3x3.h>
-#include "LinearMath/btPoint3.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "../../LinearMath/btPoint3.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects.
class btCollisionShape
{
public:
- btCollisionShape() :m_tempDebug(0)
+ btCollisionShape()
{
}
virtual ~btCollisionShape()
@@ -40,14 +40,15 @@ public:
virtual void getBoundingSphere(btVector3& center,btScalar& radius) const;
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
- virtual float getAngularMotionDisc() const;
+ virtual btScalar getAngularMotionDisc() const;
- virtual int getShapeType() const=0;
///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
///result is conservative
void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax);
+#ifndef __SPU__
+
inline bool isPolyhedral() const
{
return btBroadphaseProxy::isPolyhedral(getShapeType());
@@ -72,20 +73,20 @@ public:
return btBroadphaseProxy::isInfinite(getShapeType());
}
+ virtual int getShapeType() const=0;
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
-
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) = 0;
+
//debugging support
virtual char* getName()const =0 ;
- const char* getExtraDebugInfo() const { return m_tempDebug;}
- void setExtraDebugInfo(const char* extraDebugInfo) { m_tempDebug = extraDebugInfo;}
- const char * m_tempDebug;
-//endif debugging support
+#endif //__SPU__
+
+
- virtual void setMargin(float margin) = 0;
- virtual float getMargin() const = 0;
+ virtual void setMargin(btScalar margin) = 0;
+ virtual btScalar getMargin() const = 0;
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
index 88ae8c7dfd4..a4712b3e925 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
@@ -20,11 +20,11 @@ subject to the following restrictions:
btCompoundShape::btCompoundShape()
-:m_localAabbMin(1e30f,1e30f,1e30f),
-m_localAabbMax(-1e30f,-1e30f,-1e30f),
+:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
+m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
m_aabbTree(0),
-m_collisionMargin(0.f),
-m_localScaling(1.f,1.f,1.f)
+m_collisionMargin(btScalar(0.)),
+m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
{
}
@@ -60,8 +60,8 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
- btVector3 localHalfExtents = 0.5f*(m_localAabbMax-m_localAabbMin);
- btVector3 localCenter = 0.5f*(m_localAabbMax+m_localAabbMin);
+ btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
+ btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
@@ -84,15 +84,15 @@ void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
btVector3 aabbMin,aabbMax;
getAabb(ident,aabbMin,aabbMax);
- btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
+ btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
- btScalar lx=2.f*(halfExtents.x());
- btScalar ly=2.f*(halfExtents.y());
- btScalar lz=2.f*(halfExtents.z());
+ btScalar lx=btScalar(2.)*(halfExtents.x());
+ btScalar ly=btScalar(2.)*(halfExtents.y());
+ btScalar lz=btScalar(2.)*(halfExtents.z());
- inertia[0] = mass/(12.0f) * (ly*ly + lz*lz);
- inertia[1] = mass/(12.0f) * (lx*lx + lz*lz);
- inertia[2] = mass/(12.0f) * (lx*lx + ly*ly);
+ inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz);
+ inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz);
+ inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
index 84188bc8b76..86dc1f80947 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
@@ -18,12 +18,11 @@ subject to the following restrictions:
#include "btCollisionShape.h"
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
-#include "LinearMath/btMatrix3x3.h"
-#include <vector>
-#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
-#include "LinearMath/btAlignedObjectArray.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
class btOptimizedBvh;
@@ -59,11 +58,11 @@ public:
return m_childShapes[index];
}
- btTransform getChildTransform(int index)
+ btTransform& getChildTransform(int index)
{
return m_childTransforms[index];
}
- const btTransform getChildTransform(int index) const
+ const btTransform& getChildTransform(int index) const
{
return m_childTransforms[index];
}
@@ -85,11 +84,11 @@ public:
virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
- virtual void setMargin(float margin)
+ virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
- virtual float getMargin() const
+ virtual btScalar getMargin() const
{
return m_collisionMargin;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp
index 7cd35a91860..5103500a012 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.cpp
@@ -17,7 +17,7 @@ subject to the following restrictions:
#include "btConcaveShape.h"
-btConcaveShape::btConcaveShape() : m_collisionMargin(0.f)
+btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.))
{
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
index 2bbba88bc44..73f974e4ee9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef CONCAVE_SHAPE_H
#define CONCAVE_SHAPE_H
-#include "BulletCollision/CollisionShapes/btCollisionShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
-
+#include "btCollisionShape.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btTriangleCallback.h"
@@ -27,7 +26,7 @@ subject to the following restrictions:
class btConcaveShape : public btCollisionShape
{
protected:
- float m_collisionMargin;
+ btScalar m_collisionMargin;
public:
btConcaveShape();
@@ -36,10 +35,10 @@ public:
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0;
- virtual float getMargin() const {
+ virtual btScalar getMargin() const {
return m_collisionMargin;
}
- virtual void setMargin(float collisionMargin)
+ virtual void setMargin(btScalar collisionMargin)
{
m_collisionMargin = collisionMargin;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
index 46232b3187c..207b3024bc3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
@@ -24,7 +24,7 @@ m_height(height)
{
setConeUpIndex(1);
btVector3 halfExtents;
- m_sinAngle = (m_radius / sqrt(m_radius * m_radius + m_height * m_height));
+ m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
}
btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height):
@@ -67,15 +67,15 @@ void btConeShape::setConeUpIndex(int upIndex)
btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
{
- float halfHeight = m_height * 0.5f;
+ btScalar halfHeight = m_height * btScalar(0.5);
if (v[m_coneIndices[1]] > v.length() * m_sinAngle)
{
btVector3 tmp;
- tmp[m_coneIndices[0]] = 0.f;
+ tmp[m_coneIndices[0]] = btScalar(0.);
tmp[m_coneIndices[1]] = halfHeight;
- tmp[m_coneIndices[2]] = 0.f;
+ tmp[m_coneIndices[2]] = btScalar(0.);
return tmp;
}
else {
@@ -90,9 +90,9 @@ btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
}
else {
btVector3 tmp;
- tmp[m_coneIndices[0]] = 0.f;
+ tmp[m_coneIndices[0]] = btScalar(0.);
tmp[m_coneIndices[1]] = -halfHeight;
- tmp[m_coneIndices[2]] = 0.f;
+ tmp[m_coneIndices[2]] = btScalar(0.);
return tmp;
}
}
@@ -117,12 +117,12 @@ void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVect
btVector3 btConeShape::localGetSupportingVertex(const btVector3& vec) const
{
btVector3 supVertex = coneLocalSupport(vec);
- if ( getMargin()!=0.f )
+ if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
index 52d925fe714..3ccda5b12c6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
@@ -17,16 +17,16 @@ subject to the following restrictions:
#define CONE_MINKOWSKI_H
#include "btConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btConeShape implements a Cone shape, around the Y axis
class btConeShape : public btConvexShape
{
- float m_sinAngle;
- float m_radius;
- float m_height;
+ btScalar m_sinAngle;
+ btScalar m_radius;
+ btScalar m_height;
int m_coneIndices[3];
btVector3 coneLocalSupport(const btVector3& v) const;
@@ -38,8 +38,8 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- float getRadius() const { return m_radius;}
- float getHeight() const { return m_height;}
+ btScalar getRadius() const { return m_radius;}
+ btScalar getHeight() const { return m_height;}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia)
@@ -49,17 +49,17 @@ public:
btVector3 aabbMin,aabbMax;
getAabb(identity,aabbMin,aabbMax);
- btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
+ btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
- float margin = getMargin();
+ btScalar margin = getMargin();
- btScalar lx=2.f*(halfExtents.x()+margin);
- btScalar ly=2.f*(halfExtents.y()+margin);
- btScalar lz=2.f*(halfExtents.z()+margin);
+ btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
+ btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
+ btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
- const btScalar scaledmass = mass * 0.08333333f;
+ const btScalar scaledmass = mass * btScalar(0.08333333);
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
index 5af6e5f03d9..deb3954b5c3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
@@ -19,7 +19,7 @@ subject to the following restrictions:
-btConvexHullShape ::btConvexHullShape (const float* points,int numPoints,int stride)
+btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride)
{
m_points.resize(numPoints);
@@ -30,26 +30,37 @@ btConvexHullShape ::btConvexHullShape (const float* points,int numPoints,int str
btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
m_points[i] = point[0];
}
+
+ recalcLocalAabb();
+
+}
+
+
+void btConvexHullShape::addPoint(const btPoint3& point)
+{
+ m_points.push_back(point);
+ recalcLocalAabb();
+
}
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
- btVector3 supVec(0.f,0.f,0.f);
- btScalar newDot,maxDot = -1e30f;
+ btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
+ btScalar newDot,maxDot = btScalar(-1e30);
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
- if (lenSqr < 0.0001f)
+ if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
- float rlen = 1.f / btSqrt(lenSqr );
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
- for (size_t i=0;i<m_points.size();i++)
+ for (int i=0;i<m_points.size();i++)
{
btPoint3 vtx = m_points[i] * m_localScaling;
@@ -70,10 +81,10 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
{
for (int i=0;i<numVectors;i++)
{
- supportVerticesOut[i][3] = -1e30f;
+ supportVerticesOut[i][3] = btScalar(-1e30);
}
}
- for (size_t i=0;i<m_points.size();i++)
+ for (int i=0;i<m_points.size();i++)
{
btPoint3 vtx = m_points[i] * m_localScaling;
@@ -101,12 +112,12 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
{
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
- if ( getMargin()!=0.f )
+ if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -153,13 +164,14 @@ int btConvexHullShape::getNumPlanes() const
return 0;
}
-void btConvexHullShape::getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
+void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const
{
- assert(0);
+
+ btAssert(0);
}
//not yet
-bool btConvexHullShape::isInside(const btPoint3& pt,btScalar tolerance) const
+bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const
{
assert(0);
return false;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
index beea0e63201..3fd5e382525 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
@@ -17,29 +17,37 @@ subject to the following restrictions:
#define CONVEX_HULL_SHAPE_H
#include "btPolyhedralConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
-
-
-#include "LinearMath/btAlignedObjectArray.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../../LinearMath/btAlignedObjectArray.h"
///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
///(memory is much slower then the cpu)
-class btConvexHullShape : public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
{
btAlignedObjectArray<btPoint3> m_points;
public:
- ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive float (x,y,z), the striding defines the number of bytes between each point, in memory.
+
+
+ ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
///btConvexHullShape make an internal copy of the points.
- btConvexHullShape(const float* points=0,int numPoints=0, int stride=sizeof(btPoint3));
+ btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3));
+
+ void addPoint(const btPoint3& point);
- void addPoint(const btPoint3& point)
+ btPoint3* getPoints()
{
- m_points.push_back(point);
+ return &m_points[0];
}
+
+ int getNumPoints()
+ {
+ return m_points.size();
+ }
+
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
index 9537235ff8a..7edf1ea6db8 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
@@ -15,8 +15,9 @@ subject to the following restrictions:
#include "btConvexShape.h"
+
btConvexShape::btConvexShape()
-: m_localScaling(1.f,1.f,1.f),
+: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
{
}
@@ -35,35 +36,42 @@ void btConvexShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVec
btScalar margin = getMargin();
for (int i=0;i<3;i++)
{
- btVector3 vec(0.f,0.f,0.f);
- vec[i] = 1.f;
+ btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+ vec[i] = btScalar(1.);
btVector3 sv = localGetSupportingVertex(vec*trans.getBasis());
btVector3 tmp = trans(sv);
maxAabb[i] = tmp[i]+margin;
- vec[i] = -1.f;
+ vec[i] = btScalar(-1.);
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
minAabb[i] = tmp[i]-margin;
}
};
+
btVector3 btConvexShape::localGetSupportingVertex(const btVector3& vec)const
- {
+{
+#ifndef __SPU__
+
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
- if ( getMargin()!=0.f )
+ if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
}
return supVertex;
+#else
+ return btVector3(0,0,0);
+#endif //__SPU__
+
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
index 0de334b3521..746f383dfc7 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
@@ -18,11 +18,10 @@ subject to the following restrictions:
#include "btCollisionShape.h"
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
-#include "LinearMath/btMatrix3x3.h"
-#include <vector>
-#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
//todo: get rid of this btConvexCastResult thing!
struct btConvexCastResult;
@@ -31,9 +30,9 @@ struct btConvexCastResult;
/// btConvexShape is an abstract shape interface.
/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
/// used in combination with GJK or btConvexCast
-class btConvexShape : public btCollisionShape
+ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape
{
-
+
protected:
//local scaling. collisionMargin is not scaled !
@@ -43,14 +42,27 @@ protected:
btScalar m_collisionMargin;
+ btScalar m_padding[2];
+
+
+
+
public:
btConvexShape();
+ virtual ~btConvexShape()
+ {
+
+ }
+
+
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
+#ifndef __SPU__
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
+#endif //#ifndef __SPU__
const btVector3& getImplicitShapeDimensions() const
{
@@ -74,12 +86,21 @@ public:
return m_localScaling;
}
+ const btVector3& getLocalScalingNV() const
+ {
+ return m_localScaling;
+ }
- virtual void setMargin(float margin)
+ virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
- virtual float getMargin() const
+ virtual btScalar getMargin() const
+ {
+ return m_collisionMargin;
+ }
+
+ btScalar getMarginNV() const
{
return m_collisionMargin;
}
@@ -91,12 +112,15 @@ public:
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
{
- assert(0);
+ (void)penetrationVector;
+ (void)index;
+ btAssert(0);
}
-};
+}
+;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
index 9d8e7e1408e..6941030b15f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
@@ -22,6 +22,7 @@ subject to the following restrictions:
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface)
:m_stridingMesh(meshInterface)
{
+ recalcLocalAabb();
}
@@ -39,14 +40,17 @@ public:
btVector3 m_supportVecLocal;
LocalSupportVertexCallback(const btVector3& supportVecLocal)
- : m_supportVertexLocal(0.f,0.f,0.f),
- m_maxDot(-1e30f),
+ : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
+ m_maxDot(btScalar(-1e30)),
m_supportVecLocal(supportVecLocal)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
{
+ (void)triangleIndex;
+ (void)partId;
+
for (int i=0;i<3;i++)
{
btScalar dot = m_supportVecLocal.dot(triangle[i]);
@@ -71,21 +75,21 @@ public:
btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
- btVector3 supVec(0.f,0.f,0.f);
+ btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
- if (lenSqr < 0.0001f)
+ if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
- float rlen = 1.f / btSqrt(lenSqr );
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
LocalSupportVertexCallback supportCallback(vec);
- btVector3 aabbMax(1e30f,1e30f,1e30f);
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
supVec = supportCallback.GetSupportVertexLocal();
@@ -98,7 +102,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
{
for (int i=0;i<numVectors;i++)
{
- supportVerticesOut[i][3] = -1e30f;
+ supportVerticesOut[i][3] = btScalar(-1e30);
}
}
@@ -109,7 +113,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
{
const btVector3& vec = vectors[j];
LocalSupportVertexCallback supportCallback(vec);
- btVector3 aabbMax(1e30f,1e30f,1e30f);
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
}
@@ -122,12 +126,12 @@ btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& v
{
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
- if ( getMargin()!=0.f )
+ if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -157,14 +161,14 @@ int btConvexTriangleMeshShape::getNumEdges() const
return 0;
}
-void btConvexTriangleMeshShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const
{
- assert(0);
+ btAssert(0);
}
-void btConvexTriangleMeshShape::getVertex(int i,btPoint3& vtx) const
+void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const
{
- assert(0);
+ btAssert(0);
}
int btConvexTriangleMeshShape::getNumPlanes() const
@@ -172,15 +176,15 @@ int btConvexTriangleMeshShape::getNumPlanes() const
return 0;
}
-void btConvexTriangleMeshShape::getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
+void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const
{
- assert(0);
+ btAssert(0);
}
//not yet
-bool btConvexTriangleMeshShape::isInside(const btPoint3& pt,btScalar tolerance) const
+bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const
{
- assert(0);
+ btAssert(0);
return false;
}
@@ -189,5 +193,13 @@ bool btConvexTriangleMeshShape::isInside(const btPoint3& pt,btScalar tolerance)
void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
m_stridingMesh->setScaling(scaling);
+
+ recalcLocalAabb();
+
}
+
+const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
+{
+ return m_stridingMesh->getScaling();
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
index 86e871c6c0b..34ee7af744c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
@@ -3,9 +3,8 @@
#include "btPolyhedralConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
-#include <vector>
/// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead.
/// It uses the btStridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data.
@@ -40,7 +39,8 @@ public:
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
- void setLocalScaling(const btVector3& scaling);
+ virtual void setLocalScaling(const btVector3& scaling);
+ virtual const btVector3& getLocalScaling() const;
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
index 16b263474f0..1666afb3b88 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
@@ -16,23 +16,33 @@ subject to the following restrictions:
#include "LinearMath/btPoint3.h"
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
-:btBoxShape(halfExtents)
+:btBoxShape(halfExtents),
+m_upAxis(1)
{
-
+ recalcLocalAabb();
}
btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
:btCylinderShape(halfExtents)
{
+ m_upAxis = 0;
+ recalcLocalAabb();
}
btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
:btCylinderShape(halfExtents)
{
+ m_upAxis = 2;
+ recalcLocalAabb();
}
+void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+ //skip the box 'getAabb'
+ btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax);
+}
inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
@@ -46,8 +56,8 @@ const int ZZ = 2;
// extents of the cylinder is: X,Y is for radius, and Z for height
- float radius = halfExtents[XX];
- float halfHeight = halfExtents[cylinderUpAxis];
+ btScalar radius = halfExtents[XX];
+ btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;
@@ -87,8 +97,8 @@ const int YY = 1;
const int ZZ = 2;
- float radius = halfExtents[XX];
- float halfHeight = halfExtents[cylinderUpAxis];
+ btScalar radius = halfExtents[XX];
+ btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;
@@ -124,8 +134,8 @@ const int ZZ = 1;
// extents of the cylinder is: X,Y is for radius, and Z for height
- float radius = halfExtents[XX];
- float halfHeight = halfExtents[cylinderUpAxis];
+ btScalar radius = halfExtents[XX];
+ btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
index bb0e4298abc..c78890c887a 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
@@ -17,22 +17,23 @@ subject to the following restrictions:
#define CYLINDER_MINKOWSKI_H
#include "btBoxShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
-#include "LinearMath/btVector3.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../../LinearMath/btVector3.h"
/// implements cylinder shape interface
class btCylinderShape : public btBoxShape
{
+protected:
+
+ int m_upAxis;
+
public:
btCylinderShape (const btVector3& halfExtents);
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
- void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
- {
- getAabbSlow(t,aabbMin,aabbMax);
- }
+ void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -44,12 +45,12 @@ public:
btVector3 supVertex;
supVertex = localGetSupportingVertexWithoutMargin(vec);
- if ( getMargin()!=0.f )
+ if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -66,12 +67,12 @@ public:
return CYLINDER_SHAPE_PROXYTYPE;
}
- virtual int getUpAxis() const
+ int getUpAxis() const
{
- return 1;
+ return m_upAxis;
}
- virtual float getRadius() const
+ virtual btScalar getRadius() const
{
return getHalfExtents().getX();
}
@@ -93,17 +94,14 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- virtual int getUpAxis() const
- {
- return 0;
- }
+
//debugging
virtual char* getName()const
{
return "CylinderX";
}
- virtual float getRadius() const
+ virtual btScalar getRadius() const
{
return getHalfExtents().getY();
}
@@ -128,7 +126,7 @@ public:
return "CylinderZ";
}
- virtual float getRadius() const
+ virtual btScalar getRadius() const
{
return getHalfExtents().getX();
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
index c63f4a9c571..dcc486f194b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
@@ -40,9 +40,9 @@ void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aa
}
-void btEmptyShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& )
{
- assert(0);
+ btAssert(0);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
index c16149e55fb..8ec53444976 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
@@ -18,11 +18,10 @@ subject to the following restrictions:
#include "btConcaveShape.h"
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
-#include "LinearMath/btMatrix3x3.h"
-#include <vector>
-#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
index 57132ee9512..94be43c88e2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
@@ -18,9 +18,66 @@ subject to the following restrictions:
#include "LinearMath/btTransformUtil.h"
-btHeightfieldTerrainShape::btHeightfieldTerrainShape()
-:m_localScaling(0.f,0.f,0.f)
+btHeightfieldTerrainShape::btHeightfieldTerrainShape(int width,int length,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
+:m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+m_width(width),
+m_length(length),
+m_heightfieldDataUnknown(heightfieldData),
+m_maxHeight(maxHeight),
+m_upAxis(upAxis),
+m_useFloatData(useFloatData),
+m_flipQuadEdges(flipQuadEdges),
+m_useDiamondSubdivision(false)
{
+
+
+ btScalar quantizationMargin = 1.f;
+
+ //enlarge the AABB to avoid division by zero when initializing the quantization values
+ btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
+
+ btVector3 halfExtents(0,0,0);
+
+ switch (m_upAxis)
+ {
+ case 0:
+ {
+ halfExtents.setValue(
+ m_maxHeight,
+ m_width,
+ m_length);
+ break;
+ }
+ case 1:
+ {
+ halfExtents.setValue(
+ m_width,
+ m_maxHeight,
+ m_length);
+ break;
+ };
+ case 2:
+ {
+ halfExtents.setValue(
+ m_width,
+ m_length,
+ m_maxHeight
+ );
+ break;
+ }
+ default:
+ {
+ //need to get valid m_upAxis
+ btAssert(0);
+ }
+ }
+
+ halfExtents*= btScalar(0.5);
+
+ m_localAabbMin = -halfExtents - clampValue;
+ m_localAabbMax = halfExtents + clampValue;
+ btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
+
}
@@ -32,54 +89,244 @@ btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
+/*
aabbMin.setValue(-1e30f,-1e30f,-1e30f);
aabbMax.setValue(1e30f,1e30f,1e30f);
+*/
+
+ btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
+
+ btMatrix3x3 abs_b = t.getBasis().absolute();
+ btPoint3 center = t.getOrigin();
+ btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
+ abs_b[1].dot(halfExtents),
+ abs_b[2].dot(halfExtents));
+ extent += btVector3(getMargin(),getMargin(),getMargin());
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+
+
+}
+
+btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
+{
+ btScalar val = 0.f;
+ if (m_useFloatData)
+ {
+ val = m_heightfieldDataFloat[(y*m_width)+x];
+ } else
+ {
+ //assume unsigned short int
+ unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_width)+x];
+ val = heightFieldValue* (m_maxHeight/btScalar(65535));
+ }
+ return val;
}
-void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+
+void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
{
- btVector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
- btScalar radius = halfExtents.length();
- btVector3 center = (aabbMax + aabbMin) * 0.5f;
+ btAssert(x>=0);
+ btAssert(y>=0);
+ btAssert(x<m_width);
+ btAssert(y<m_length);
+
+
+ btScalar height = getHeightFieldValue(x,y);
+
+ switch (m_upAxis)
+ {
+ case 0:
+ {
+ vertex.setValue(
+ height,
+ (-m_width/2 ) + x,
+ (-m_length/2 ) + y
+ );
+ break;
+ }
+ case 1:
+ {
+ vertex.setValue(
+ (-m_width/2 ) + x,
+ height,
+ (-m_length/2 ) + y
+ );
+ break;
+ };
+ case 2:
+ {
+ vertex.setValue(
+ (-m_width/2 ) + x,
+ (-m_length/2 ) + y,
+ height
+ );
+ break;
+ }
+ default:
+ {
+ //need to get valid m_upAxis
+ btAssert(0);
+ }
+ }
+
+ vertex*=m_localScaling;
- //TODO
- //this is where the triangles are generated, given AABB and plane equation (normal/constant)
-/*
- btVector3 tangentDir0,tangentDir1;
+}
+
+
+void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point) const
+{
+
+
+ btVector3 clampedPoint(point);
+ clampedPoint.setMax(m_localAabbMin);
+ clampedPoint.setMin(m_localAabbMax);
+
+ btVector3 v = (clampedPoint );// * m_quantization;
+
+ out[0] = (int)(v.getX());
+ out[1] = (int)(v.getY());
+ out[2] = (int)(v.getZ());
+ //correct for
+
+}
+
+
+void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+ (void)callback;
+ (void)aabbMax;
+ (void)aabbMin;
- //tangentDir0/tangentDir1 can be precalculated
- btPlaneSpace1(m_planeNormal,tangentDir0,tangentDir1);
+ //quantize the aabbMin and aabbMax, and adjust the start/end ranges
- btVector3 supVertex0,supVertex1;
+ int quantizedAabbMin[3];
+ int quantizedAabbMax[3];
- btVector3 projectedCenter = center - (m_planeNormal.dot(center) - m_planeConstant)*m_planeNormal;
+ btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+ btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+
+ quantizeWithClamp(quantizedAabbMin, localAabbMin);
+ quantizeWithClamp(quantizedAabbMax, localAabbMax);
+
- btVector3 triangle[3];
- triangle[0] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
- triangle[1] = projectedCenter + tangentDir0*radius - tangentDir1*radius;
- triangle[2] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
- callback->processTriangle(triangle,0,0);
+ int startX=0;
+ int endX=m_width-1;
+ int startJ=0;
+ int endJ=m_length-1;
- triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
- triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius;
- triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
+ switch (m_upAxis)
+ {
+ case 0:
+ {
+ quantizedAabbMin[1]+=m_width/2-1;
+ quantizedAabbMax[1]+=m_width/2+1;
+ quantizedAabbMin[2]+=m_length/2-1;
+ quantizedAabbMax[2]+=m_length/2+1;
- callback->processTriangle(triangle,0,1);
-*/
+ if (quantizedAabbMin[1]>startX)
+ startX = quantizedAabbMin[1];
+ if (quantizedAabbMax[1]<endX)
+ endX = quantizedAabbMax[1];
+ if (quantizedAabbMin[2]>startJ)
+ startJ = quantizedAabbMin[2];
+ if (quantizedAabbMax[2]<endJ)
+ endJ = quantizedAabbMax[2];
+ break;
+ }
+ case 1:
+ {
+ quantizedAabbMin[0]+=m_width/2-1;
+ quantizedAabbMax[0]+=m_width/2+1;
+ quantizedAabbMin[2]+=m_length/2-1;
+ quantizedAabbMax[2]+=m_length/2+1;
+
+ if (quantizedAabbMin[0]>startX)
+ startX = quantizedAabbMin[0];
+ if (quantizedAabbMax[0]<endX)
+ endX = quantizedAabbMax[0];
+ if (quantizedAabbMin[2]>startJ)
+ startJ = quantizedAabbMin[2];
+ if (quantizedAabbMax[2]<endJ)
+ endJ = quantizedAabbMax[2];
+ break;
+ };
+ case 2:
+ {
+ quantizedAabbMin[0]+=m_width/2-1;
+ quantizedAabbMax[0]+=m_width/2+1;
+ quantizedAabbMin[1]+=m_length/2-1;
+ quantizedAabbMax[1]+=m_length/2+1;
+
+ if (quantizedAabbMin[0]>startX)
+ startX = quantizedAabbMin[0];
+ if (quantizedAabbMax[0]<endX)
+ endX = quantizedAabbMax[0];
+ if (quantizedAabbMin[1]>startJ)
+ startJ = quantizedAabbMin[1];
+ if (quantizedAabbMax[1]<endJ)
+ endJ = quantizedAabbMax[1];
+ break;
+ }
+ default:
+ {
+ //need to get valid m_upAxis
+ btAssert(0);
+ }
+ }
+
+
+
+
+ for(int j=startJ; j<endJ; j++)
+ {
+ for(int x=startX; x<endX; x++)
+ {
+ btVector3 vertices[3];
+ if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1)))
+ {
+ //first triangle
+ getVertex(x,j,vertices[0]);
+ getVertex(x+1,j,vertices[1]);
+ getVertex(x+1,j+1,vertices[2]);
+ callback->processTriangle(vertices,x,j);
+ //second triangle
+ getVertex(x,j,vertices[0]);
+ getVertex(x+1,j+1,vertices[1]);
+ getVertex(x,j+1,vertices[2]);
+ callback->processTriangle(vertices,x,j);
+ } else
+ {
+ //first triangle
+ getVertex(x,j,vertices[0]);
+ getVertex(x,j+1,vertices[1]);
+ getVertex(x+1,j,vertices[2]);
+ callback->processTriangle(vertices,x,j);
+ //second triangle
+ getVertex(x+1,j,vertices[0]);
+ getVertex(x,j+1,vertices[1]);
+ getVertex(x+1,j+1,vertices[2]);
+ callback->processTriangle(vertices,x,j);
+ }
+ }
+ }
+
+
}
-void btHeightfieldTerrainShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
+void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia)
{
//moving concave objects not supported
- inertia.setValue(0.f,0.f,0.f);
+ inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
index e4cc9d42d59..49f3e106733 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef HEIGHTFIELD_TERRAIN_SHAPE_H
#define HEIGHTFIELD_TERRAIN_SHAPE_H
-#include "BulletCollision/CollisionShapes/btConcaveShape.h"
+#include "btConcaveShape.h"
///btHeightfieldTerrainShape simulates a 2D heightfield terrain
class btHeightfieldTerrainShape : public btConcaveShape
@@ -25,16 +25,46 @@ protected:
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
- //todo: terrain data
+ ///terrain data
+ int m_width;
+ int m_length;
+ btScalar m_maxHeight;
+ union
+ {
+ unsigned char* m_heightfieldDataUnsignedChar;
+ btScalar* m_heightfieldDataFloat;
+ void* m_heightfieldDataUnknown;
+ };
+
+ bool m_useFloatData;
+ bool m_flipQuadEdges;
+ bool m_useDiamondSubdivision;
+ int m_upAxis;
+
btVector3 m_localScaling;
+ virtual btScalar getHeightFieldValue(int x,int y) const;
+ void quantizeWithClamp(int* out, const btVector3& point) const;
+ void getVertex(int x,int y,btVector3& vertex) const;
+
+ inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const
+ {
+ bool overlap = true;
+ overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+ overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+ overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+ return overlap;
+ }
+
public:
- btHeightfieldTerrainShape();
+ btHeightfieldTerrainShape(int width,int height,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
virtual ~btHeightfieldTerrainShape();
+ void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
+
virtual int getShapeType() const
{
return TERRAIN_SHAPE_PROXYTYPE;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
index 4bf8c478a53..015314bc09f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
@@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btMinkowskiSumShape.h"
-btMinkowskiSumShape::btMinkowskiSumShape(btConvexShape* shapeA,btConvexShape* shapeB)
+btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB)
:m_shapeA(shapeA),
m_shapeB(shapeB)
{
@@ -43,7 +43,7 @@ void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(cons
-float btMinkowskiSumShape::getMargin() const
+btScalar btMinkowskiSumShape::getMargin() const
{
return m_shapeA->getMargin() + m_shapeB->getMargin();
}
@@ -51,6 +51,7 @@ float btMinkowskiSumShape::getMargin() const
void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
- assert(0);
+ (void)mass;
+ btAssert(0);
inertia.setValue(0,0,0);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
index e974f57a4c2..198faaff9f9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define MINKOWSKI_SUM_SHAPE_H
#include "btConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
/// btMinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes.
class btMinkowskiSumShape : public btConvexShape
@@ -25,12 +25,12 @@ class btMinkowskiSumShape : public btConvexShape
btTransform m_transA;
btTransform m_transB;
- btConvexShape* m_shapeA;
- btConvexShape* m_shapeB;
+ const btConvexShape* m_shapeA;
+ const btConvexShape* m_shapeB;
public:
- btMinkowskiSumShape(btConvexShape* shapeA,btConvexShape* shapeB);
+ btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB);
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -48,7 +48,7 @@ public:
virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; }
- virtual float getMargin() const;
+ virtual btScalar getMargin() const;
const btConvexShape* getShapeA() const { return m_shapeA;}
const btConvexShape* getShapeB() const { return m_shapeB;}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
index fde4d95da14..6015a618082 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
@@ -20,7 +20,7 @@ subject to the following restrictions:
btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
:m_inertiaHalfExtents(inertiaHalfExtents)
{
- float startMargin = 1e30f;
+ btScalar startMargin = btScalar(1e30);
m_numSpheres = numSpheres;
for (int i=0;i<m_numSpheres;i++)
@@ -42,17 +42,17 @@ btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,cons
int i;
btVector3 supVec(0,0,0);
- btScalar maxDot(-1e30f);
+ btScalar maxDot(btScalar(-1e30));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
- if (lenSqr < 0.0001f)
+ if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
- float rlen = 1.f / btSqrt(lenSqr );
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
@@ -84,7 +84,7 @@ btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,cons
for (int j=0;j<numVectors;j++)
{
- btScalar maxDot(-1e30f);
+ btScalar maxDot(btScalar(-1e30));
const btVector3& vec = vectors[j];
@@ -126,17 +126,17 @@ void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
// getAabb(ident,aabbMin,aabbMax);
- btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* 0.5f;
+ btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* btScalar(0.5);
- float margin = CONVEX_DISTANCE_MARGIN;
+ btScalar margin = CONVEX_DISTANCE_MARGIN;
- btScalar lx=2.f*(halfExtents[0]+margin);
- btScalar ly=2.f*(halfExtents[1]+margin);
- btScalar lz=2.f*(halfExtents[2]+margin);
+ btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
+ btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
+ btScalar lz=btScalar(2.)*(halfExtents[2]+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
- const btScalar scaledmass = mass * 0.08333333f;
+ const btScalar scaledmass = mass * btScalar(.08333333);
inertia[0] = scaledmass * (y2+z2);
inertia[1] = scaledmass * (x2+z2);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
index 2dde9d3855a..1897b474057 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define MULTI_SPHERE_MINKOWSKI_H
#include "btConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#define MAX_NUM_SPHERES 5
@@ -46,6 +46,20 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+ int getSphereCount() const
+ {
+ return m_numSpheres;
+ }
+
+ const btVector3& getSpherePosition(int index) const
+ {
+ return m_localPositions[index];
+ }
+
+ btScalar getSphereRadius(int index) const
+ {
+ return m_radi[index];
+ }
virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; }
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
index 37f15e1dcc4..44438a24455 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
@@ -16,89 +16,373 @@ subject to the following restrictions:
#include "btOptimizedBvh.h"
#include "btStridingMeshInterface.h"
#include "LinearMath/btAabbUtil2.h"
+#include "LinearMath/btIDebugDraw.h"
-btOptimizedBvh::btOptimizedBvh() :m_rootNode1(0), m_numNodes(0)
+
+btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false),
+ m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
+ //m_traversalMode(TRAVERSAL_STACKLESS)
+ //m_traversalMode(TRAVERSAL_RECURSIVE)
{
}
-void btOptimizedBvh::build(btStridingMeshInterface* triangles)
+void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax)
{
- //int countTriangles = 0;
+ m_useQuantization = useQuantizedAabbCompression;
-
// NodeArray triangleNodes;
struct NodeTriangleCallback : public btInternalTriangleIndexCallback
{
+
NodeArray& m_triangleNodes;
+ NodeTriangleCallback& operator=(NodeTriangleCallback& other)
+ {
+ m_triangleNodes = other.m_triangleNodes;
+ return *this;
+ }
+
NodeTriangleCallback(NodeArray& triangleNodes)
:m_triangleNodes(triangleNodes)
{
-
}
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
{
-
btOptimizedBvhNode node;
- node.m_aabbMin = btVector3(1e30f,1e30f,1e30f);
- node.m_aabbMax = btVector3(-1e30f,-1e30f,-1e30f);
- node.m_aabbMin.setMin(triangle[0]);
- node.m_aabbMax.setMax(triangle[0]);
- node.m_aabbMin.setMin(triangle[1]);
- node.m_aabbMax.setMax(triangle[1]);
- node.m_aabbMin.setMin(triangle[2]);
- node.m_aabbMax.setMax(triangle[2]);
+ btVector3 aabbMin,aabbMax;
+ aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ aabbMin.setMin(triangle[0]);
+ aabbMax.setMax(triangle[0]);
+ aabbMin.setMin(triangle[1]);
+ aabbMax.setMax(triangle[1]);
+ aabbMin.setMin(triangle[2]);
+ aabbMax.setMax(triangle[2]);
+
+ //with quantization?
+ node.m_aabbMinOrg = aabbMin;
+ node.m_aabbMaxOrg = aabbMax;
node.m_escapeIndex = -1;
- node.m_leftChild = 0;
- node.m_rightChild = 0;
-
-
+
//for child nodes
node.m_subPart = partId;
node.m_triangleIndex = triangleIndex;
+ m_triangleNodes.push_back(node);
+ }
+ };
+ struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback
+ {
+ QuantizedNodeArray& m_triangleNodes;
+ const btOptimizedBvh* m_optimizedTree; // for quantization
+
+ QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other)
+ {
+ m_triangleNodes = other.m_triangleNodes;
+ m_optimizedTree = other.m_optimizedTree;
+ return *this;
+ }
+
+ QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btOptimizedBvh* tree)
+ :m_triangleNodes(triangleNodes),m_optimizedTree(tree)
+ {
+ }
+
+ virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
+ {
+ btAssert(partId==0);
+ //negative indices are reserved for escapeIndex
+ btAssert(triangleIndex>=0);
+
+ btQuantizedBvhNode node;
+ btVector3 aabbMin,aabbMax;
+ aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ aabbMin.setMin(triangle[0]);
+ aabbMax.setMax(triangle[0]);
+ aabbMin.setMin(triangle[1]);
+ aabbMax.setMax(triangle[1]);
+ aabbMin.setMin(triangle[2]);
+ aabbMax.setMax(triangle[2]);
+
+ m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin);
+ m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax);
+
+ node.m_escapeIndexOrTriangleIndex = triangleIndex;
-
m_triangleNodes.push_back(node);
}
};
+
+
+
+ int numLeafNodes = 0;
+ if (m_useQuantization)
+ {
- NodeTriangleCallback callback(m_leafNodes);
+ //initialize quantization values
+ setQuantizationValues(bvhAabbMin,bvhAabbMax);
+
+ QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this);
+
+
+ triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax);
- btVector3 aabbMin(-1e30f,-1e30f,-1e30f);
- btVector3 aabbMax(1e30f,1e30f,1e30f);
+ //now we have an array of leafnodes in m_leafNodes
+ numLeafNodes = m_quantizedLeafNodes.size();
- triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
- //now we have an array of leafnodes in m_leafNodes
+ m_quantizedContiguousNodes.resize(2*numLeafNodes);
+
+
+ } else
+ {
+ NodeTriangleCallback callback(m_leafNodes);
+
+ btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+
+ triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
+
+ //now we have an array of leafnodes in m_leafNodes
+ numLeafNodes = m_leafNodes.size();
+
+ m_contiguousNodes.resize(2*numLeafNodes);
+ }
- m_contiguousNodes = new btOptimizedBvhNode[2*m_leafNodes.size()];
m_curNodeIndex = 0;
- m_rootNode1 = buildTree(m_leafNodes,0,m_leafNodes.size());
+ buildTree(0,numLeafNodes);
+
+ ///if the entire tree is small then subtree size, we need to create a header info for the tree
+ if(m_useQuantization && !m_SubtreeHeaders.size())
+ {
+ btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+ subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
+ subtree.m_rootNodeIndex = 0;
+ subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
+ }
+}
+
+
+
+void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ //incrementally initialize quantization values
+ btAssert(m_useQuantization);
+
+ btAssert(aabbMin.getX() > m_bvhAabbMin.getX());
+ btAssert(aabbMin.getY() > m_bvhAabbMin.getY());
+ btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ());
+
+ btAssert(aabbMax.getX() < m_bvhAabbMax.getX());
+ btAssert(aabbMax.getY() < m_bvhAabbMax.getY());
+ btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ());
+
+ ///we should update all quantization values, using updateBvhNodes(meshInterface);
+ ///but we only update chunks that overlap the given aabb
+
+ unsigned short quantizedQueryAabbMin[3];
+ unsigned short quantizedQueryAabbMax[3];
+
+ quantizeWithClamp(&quantizedQueryAabbMin[0],aabbMin);
+ quantizeWithClamp(&quantizedQueryAabbMax[0],aabbMax);
+ int i;
+ for (i=0;i<this->m_SubtreeHeaders.size();i++)
+ {
+ btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
- ///create the leafnodes first
-// btOptimizedBvhNode* leafNodes = new btOptimizedBvhNode;
+ bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
+ if (overlap)
+ {
+ updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i);
+
+ subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
+ }
+ }
+
}
+///just for debugging, to visualize the individual patches/subtrees
+#ifdef DEBUG_PATCH_COLORS
+btVector3 color[4]=
+{
+ btVector3(255,0,0),
+ btVector3(0,255,0),
+ btVector3(0,0,255),
+ btVector3(0,255,255)
+};
+#endif //DEBUG_PATCH_COLORS
+
+
+void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index)
+{
+ (void)index;
+
+ btAssert(m_useQuantization);
+
+ int nodeSubPart=0;
+
+ //get access info to trianglemesh data
+ const unsigned char *vertexbase;
+ int numverts;
+ PHY_ScalarType type;
+ int stride;
+ const unsigned char *indexbase;
+ int indexstride;
+ int numfaces;
+ PHY_ScalarType indicestype;
+ meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart);
+
+ btVector3 triangleVerts[3];
+ btVector3 aabbMin,aabbMax;
+ const btVector3& meshScaling = meshInterface->getScaling();
+
+ int i;
+ for (i=endNode-1;i>=firstNode;i--)
+ {
+
+
+ btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i];
+ if (curNode.isLeafNode())
+ {
+ //recalc aabb from triangle data
+ int nodeTriangleIndex = curNode.getTriangleIndex();
+ //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts,
+
+ int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
+
+
+ for (int j=2;j>=0;j--)
+ {
+
+ int graphicsindex = gfxbase[j];
+ btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
+#ifdef DEBUG_PATCH_COLORS
+ btVector3 mycolor = color[index&3];
+ graphicsbase[8] = mycolor.getX();
+ graphicsbase[9] = mycolor.getY();
+ graphicsbase[10] = mycolor.getZ();
+#endif //DEBUG_PATCH_COLORS
+
+
+ triangleVerts[j] = btVector3(
+ graphicsbase[0]*meshScaling.getX(),
+ graphicsbase[1]*meshScaling.getY(),
+ graphicsbase[2]*meshScaling.getZ());
+ }
+
+
+
+ aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ aabbMin.setMin(triangleVerts[0]);
+ aabbMax.setMax(triangleVerts[0]);
+ aabbMin.setMin(triangleVerts[1]);
+ aabbMax.setMax(triangleVerts[1]);
+ aabbMin.setMin(triangleVerts[2]);
+ aabbMax.setMax(triangleVerts[2]);
+
+ quantizeWithClamp(&curNode.m_quantizedAabbMin[0],aabbMin);
+ quantizeWithClamp(&curNode.m_quantizedAabbMax[0],aabbMax);
+
+ } else
+ {
+ //combine aabb from both children
+
+ btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1];
+
+ btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] :
+ &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()];
+
+
+ {
+ for (int i=0;i<3;i++)
+ {
+ curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i];
+ if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i])
+ curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i];
+
+ curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i];
+ if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i])
+ curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i];
+ }
+ }
+ }
+
+ }
+
+ meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+
+
+}
+
+void btOptimizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
+{
+ //enlarge the AABB to avoid division by zero when initializing the quantization values
+ btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
+ m_bvhAabbMin = bvhAabbMin - clampValue;
+ m_bvhAabbMax = bvhAabbMax + clampValue;
+ btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
+ m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize;
+}
+
+
+void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
+{
+ if (m_useQuantization)
+ {
+ //calculate new aabb
+ btVector3 aabbMin,aabbMax;
+ meshInterface->calculateAabbBruteForce(aabbMin,aabbMax);
+
+ setQuantizationValues(aabbMin,aabbMax);
+
+ updateBvhNodes(meshInterface,0,m_curNodeIndex,0);
+
+ ///now update all subtree headers
+
+ int i;
+ for (i=0;i<m_SubtreeHeaders.size();i++)
+ {
+ btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
+ subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
+ }
+
+ } else
+ {
+
+ }
+}
+
+
+
btOptimizedBvh::~btOptimizedBvh()
{
- if (m_contiguousNodes)
- delete []m_contiguousNodes;
}
-btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startIndex,int endIndex)
+#ifdef DEBUG_TREE_BUILDING
+int gStackDepth = 0;
+int gMaxStackDepth = 0;
+#endif //DEBUG_TREE_BUILDING
+
+void btOptimizedBvh::buildTree (int startIndex,int endIndex)
{
- btOptimizedBvhNode* internalNode;
+#ifdef DEBUG_TREE_BUILDING
+ gStackDepth++;
+ if (gStackDepth > gMaxStackDepth)
+ gMaxStackDepth = gStackDepth;
+#endif //DEBUG_TREE_BUILDING
+
int splitAxis, splitIndex, i;
int numIndices =endIndex-startIndex;
@@ -108,96 +392,172 @@ btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startInd
if (numIndices==1)
{
- return new (&m_contiguousNodes[m_curNodeIndex++]) btOptimizedBvhNode(leafNodes[startIndex]);
+#ifdef DEBUG_TREE_BUILDING
+ gStackDepth--;
+#endif //DEBUG_TREE_BUILDING
+
+ assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
+
+ m_curNodeIndex++;
+ return;
}
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
- splitAxis = calcSplittingAxis(leafNodes,startIndex,endIndex);
+ splitAxis = calcSplittingAxis(startIndex,endIndex);
- splitIndex = sortAndCalcSplittingIndex(leafNodes,startIndex,endIndex,splitAxis);
+ splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
- internalNode = &m_contiguousNodes[m_curNodeIndex++];
+ int internalNodeIndex = m_curNodeIndex;
- internalNode->m_aabbMax.setValue(-1e30f,-1e30f,-1e30f);
- internalNode->m_aabbMin.setValue(1e30f,1e30f,1e30f);
+ setInternalNodeAabbMax(m_curNodeIndex,btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)));
+ setInternalNodeAabbMin(m_curNodeIndex,btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)));
for (i=startIndex;i<endIndex;i++)
{
- internalNode->m_aabbMax.setMax(leafNodes[i].m_aabbMax);
- internalNode->m_aabbMin.setMin(leafNodes[i].m_aabbMin);
+ mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
}
+ m_curNodeIndex++;
//internalNode->m_escapeIndex;
- internalNode->m_leftChild = buildTree(leafNodes,startIndex,splitIndex);
- internalNode->m_rightChild = buildTree(leafNodes,splitIndex,endIndex);
+
+ int leftChildNodexIndex = m_curNodeIndex;
+
+ //build left child tree
+ buildTree(startIndex,splitIndex);
+
+ int rightChildNodexIndex = m_curNodeIndex;
+ //build right child tree
+ buildTree(splitIndex,endIndex);
+
+#ifdef DEBUG_TREE_BUILDING
+ gStackDepth--;
+#endif //DEBUG_TREE_BUILDING
+
+ int escapeIndex = m_curNodeIndex - curIndex;
+
+ if (m_useQuantization)
+ {
+ //escapeIndex is the number of nodes of this subtree
+ const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
+ const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
+ if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
+ {
+ updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
+ }
+ }
+
+ setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
- internalNode->m_escapeIndex = m_curNodeIndex - curIndex;
- return internalNode;
}
-int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startIndex,int endIndex,int splitAxis)
+void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
+{
+ btAssert(m_useQuantization);
+
+ btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
+ int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
+ int leftSubTreeSizeInBytes = leftSubTreeSize * sizeof(btQuantizedBvhNode);
+
+ btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
+ int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
+ int rightSubTreeSizeInBytes = rightSubTreeSize * sizeof(btQuantizedBvhNode);
+
+ if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
+ {
+ btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+ subtree.setAabbFromQuantizeNode(leftChildNode);
+ subtree.m_rootNodeIndex = leftChildNodexIndex;
+ subtree.m_subtreeSize = leftSubTreeSize;
+ }
+
+ if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
+ {
+ btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+ subtree.setAabbFromQuantizeNode(rightChildNode);
+ subtree.m_rootNodeIndex = rightChildNodexIndex;
+ subtree.m_subtreeSize = rightSubTreeSize;
+ }
+}
+
+
+int btOptimizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
{
int i;
int splitIndex =startIndex;
int numIndices = endIndex - startIndex;
- float splitValue;
+ btScalar splitValue;
- btVector3 means(0.f,0.f,0.f);
+ btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
for (i=startIndex;i<endIndex;i++)
{
- btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
+ btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
means+=center;
}
- means *= (1.f/(float)numIndices);
+ means *= (btScalar(1.)/(btScalar)numIndices);
splitValue = means[splitAxis];
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
for (i=startIndex;i<endIndex;i++)
{
- btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
+ btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
if (center[splitAxis] > splitValue)
{
//swap
- btOptimizedBvhNode tmp = leafNodes[i];
- leafNodes[i] = leafNodes[splitIndex];
- leafNodes[splitIndex] = tmp;
+ swapLeafNodes(i,splitIndex);
splitIndex++;
}
}
- if ((splitIndex==startIndex) || (splitIndex == (endIndex-1)))
+
+ //if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+ //otherwise the tree-building might fail due to stack-overflows in certain cases.
+ //unbalanced1 is unsafe: it can cause stack overflows
+ //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+ //unbalanced2 should work too: always use center (perfect balanced trees)
+ //bool unbalanced2 = true;
+
+ //this should be safe too:
+ int rangeBalancedIndices = numIndices/3;
+ bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+
+ if (unbalanced)
{
splitIndex = startIndex+ (numIndices>>1);
}
+
+ bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
+ btAssert(!unbal);
+
return splitIndex;
}
-int btOptimizedBvh::calcSplittingAxis(NodeArray& leafNodes,int startIndex,int endIndex)
+int btOptimizedBvh::calcSplittingAxis(int startIndex,int endIndex)
{
int i;
- btVector3 means(0.f,0.f,0.f);
- btVector3 variance(0.f,0.f,0.f);
+ btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+ btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
int numIndices = endIndex-startIndex;
for (i=startIndex;i<endIndex;i++)
{
- btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
+ btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
means+=center;
}
- means *= (1.f/(float)numIndices);
+ means *= (btScalar(1.)/(btScalar)numIndices);
for (i=startIndex;i<endIndex;i++)
{
- btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
+ btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
btVector3 diff2 = center-means;
diff2 = diff2 * diff2;
variance += diff2;
}
- variance *= (1.f/ ((float)numIndices-1) );
+ variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
return variance.maxAxis();
}
@@ -208,11 +568,83 @@ void btOptimizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb
{
//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
- //walkTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
- walkStacklessTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
+ if (m_useQuantization)
+ {
+ ///quantize query AABB
+ unsigned short int quantizedQueryAabbMin[3];
+ unsigned short int quantizedQueryAabbMax[3];
+ quantizeWithClamp(quantizedQueryAabbMin,aabbMin);
+ quantizeWithClamp(quantizedQueryAabbMax,aabbMax);
+
+ switch (m_traversalMode)
+ {
+ case TRAVERSAL_STACKLESS:
+ walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
+ break;
+ case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
+ walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+ break;
+ case TRAVERSAL_RECURSIVE:
+ {
+ const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
+ walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+ }
+ break;
+ default:
+ //unsupported
+ btAssert(0);
+ }
+ } else
+ {
+ walkStacklessTree(nodeCallback,aabbMin,aabbMax);
+ }
}
+
+int maxIterations = 0;
+
+void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+ btAssert(!m_useQuantization);
+
+ const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
+ int escapeIndex, curIndex = 0;
+ int walkIterations = 0;
+ bool aabbOverlap, isLeafNode;
+
+ while (curIndex < m_curNodeIndex)
+ {
+ //catch bugs in tree data
+ assert (walkIterations < m_curNodeIndex);
+
+ walkIterations++;
+ aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
+ isLeafNode = rootNode->m_escapeIndex == -1;
+
+ if (isLeafNode && aabbOverlap)
+ {
+ nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
+ }
+
+ if (aabbOverlap || isLeafNode)
+ {
+ rootNode++;
+ curIndex++;
+ } else
+ {
+ escapeIndex = rootNode->m_escapeIndex;
+ rootNode += escapeIndex;
+ curIndex += escapeIndex;
+ }
+ }
+ if (maxIterations < walkIterations)
+ maxIterations = walkIterations;
+
+}
+
+/*
+///this was the original recursive traversal, before we optimized towards stackless traversal
void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
@@ -230,27 +662,82 @@ void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback
}
}
+*/
-int maxIterations = 0;
+void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
+{
+ btAssert(m_useQuantization);
+
+ bool aabbOverlap, isLeafNode;
-void btOptimizedBvh::walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
+ aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
+ isLeafNode = currentNode->isLeafNode();
+
+ if (aabbOverlap)
+ {
+ if (isLeafNode)
+ {
+ nodeCallback->processNode(0,currentNode->getTriangleIndex());
+ } else
+ {
+ //process left and right children
+ const btQuantizedBvhNode* leftChildNode = currentNode+1;
+ walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+
+ const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
+ walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+ }
+ }
+}
+
+
+
+
+
+
+
+void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
{
- int escapeIndex, curIndex = 0;
+ btAssert(m_useQuantization);
+
+ int curIndex = startNodeIndex;
int walkIterations = 0;
+ int subTreeSize = endNodeIndex - startNodeIndex;
+
+ const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
+ int escapeIndex;
+
bool aabbOverlap, isLeafNode;
- while (curIndex < m_curNodeIndex)
+ while (curIndex < endNodeIndex)
{
+
+//#define VISUALLY_ANALYZE_BVH 1
+#ifdef VISUALLY_ANALYZE_BVH
+ //some code snippet to debugDraw aabb, to visually analyze bvh structure
+ static int drawPatch = 0;
+ //need some global access to a debugDrawer
+ extern btIDebugDraw* debugDrawerPtr;
+ if (curIndex==drawPatch)
+ {
+ btVector3 aabbMin,aabbMax;
+ aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
+ aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
+ btVector3 color(1,0,0);
+ debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
+ }
+#endif//VISUALLY_ANALYZE_BVH
+
//catch bugs in tree data
- assert (walkIterations < m_curNodeIndex);
+ assert (walkIterations < subTreeSize);
walkIterations++;
- aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
- isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
+ aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
+ isLeafNode = rootNode->isLeafNode();
if (isLeafNode && aabbOverlap)
{
- nodeCallback->processNode(rootNode);
+ nodeCallback->processNode(0,rootNode->getTriangleIndex());
}
if (aabbOverlap || isLeafNode)
@@ -259,21 +746,100 @@ void btOptimizedBvh::walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverla
curIndex++;
} else
{
- escapeIndex = rootNode->m_escapeIndex;
+ escapeIndex = rootNode->getEscapeIndex();
rootNode += escapeIndex;
curIndex += escapeIndex;
}
-
}
-
if (maxIterations < walkIterations)
maxIterations = walkIterations;
}
+//This traversal can be called from Playstation 3 SPU
+void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
+{
+ btAssert(m_useQuantization);
+
+ int i;
+
+
+ for (i=0;i<this->m_SubtreeHeaders.size();i++)
+ {
+ const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
+
+ bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
+ if (overlap)
+ {
+ walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
+ subtree.m_rootNodeIndex,
+ subtree.m_rootNodeIndex+subtree.m_subtreeSize);
+ }
+ }
+}
+
+
+
void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
+ (void)nodeCallback;
+ (void)aabbMin;
+ (void)aabbMax;
+ //not yet, please use aabb
+ btAssert(0);
+}
+
+
+void btOptimizedBvh::quantizeWithClamp(unsigned short* out, const btVector3& point) const
+{
+
+ btAssert(m_useQuantization);
+
+ btVector3 clampedPoint(point);
+ clampedPoint.setMax(m_bvhAabbMin);
+ clampedPoint.setMin(m_bvhAabbMax);
+
+ btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization;
+ out[0] = (unsigned short)(v.getX()+0.5f);
+ out[1] = (unsigned short)(v.getY()+0.5f);
+ out[2] = (unsigned short)(v.getZ()+0.5f);
+}
+
+btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const
+{
+ btVector3 vecOut;
+ vecOut.setValue(
+ (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
+ (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
+ (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
+ vecOut += m_bvhAabbMin;
+ return vecOut;
+}
+
+void btOptimizedBvh::swapLeafNodes(int i,int splitIndex)
+{
+ if (m_useQuantization)
+ {
+ btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
+ m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
+ m_quantizedLeafNodes[splitIndex] = tmp;
+ } else
+ {
+ btOptimizedBvhNode tmp = m_leafNodes[i];
+ m_leafNodes[i] = m_leafNodes[splitIndex];
+ m_leafNodes[splitIndex] = tmp;
+ }
}
+void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
+{
+ if (m_useQuantization)
+ {
+ m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
+ } else
+ {
+ m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
+ }
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h
index cb76cb23340..d5159586344 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.h
@@ -17,103 +17,313 @@ subject to the following restrictions:
#define OPTIMIZED_BVH_H
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
-#include <vector>
-
class btStridingMeshInterface;
-/// btOptimizedBvhNode contains both internal and leaf node information.
-/// It hasn't been optimized yet for storage. Some obvious optimizations are:
-/// Removal of the pointers (can already be done, they are not used for traversal)
-/// and storing aabbmin/max as quantized integers.
-/// 'subpart' doesn't need an integer either. It allows to re-use graphics triangle
-/// meshes stored in a non-uniform way (like batches/subparts of triangle-fans
-ATTRIBUTE_ALIGNED16 (struct btOptimizedBvhNode)
-{
+//Note: currently we have 16 bytes per quantized node
+#define MAX_SUBTREE_SIZE_IN_BYTES 2048
- btVector3 m_aabbMin;
- btVector3 m_aabbMax;
-//these 2 pointers are obsolete, the stackless traversal just uses the escape index
- btOptimizedBvhNode* m_leftChild;
- btOptimizedBvhNode* m_rightChild;
+///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
+///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
+ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
+{
+
+ //12 bytes
+ unsigned short int m_quantizedAabbMin[3];
+ unsigned short int m_quantizedAabbMax[3];
+ //4 bytes
+ int m_escapeIndexOrTriangleIndex;
+
+ bool isLeafNode() const
+ {
+ //skipindex is negative (internal node), triangleindex >=0 (leafnode)
+ return (m_escapeIndexOrTriangleIndex >= 0);
+ }
+ int getEscapeIndex() const
+ {
+ btAssert(!isLeafNode());
+ return -m_escapeIndexOrTriangleIndex;
+ }
+ int getTriangleIndex() const
+ {
+ btAssert(isLeafNode());
+ return m_escapeIndexOrTriangleIndex;
+ }
+}
+;
+/// btOptimizedBvhNode contains both internal and leaf node information.
+/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes.
+ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
+{
+ //32 bytes
+ btVector3 m_aabbMinOrg;
+ btVector3 m_aabbMaxOrg;
+
+ //4
int m_escapeIndex;
+ //8
//for child nodes
int m_subPart;
int m_triangleIndex;
+ int m_padding[5];//bad, due to alignment
+
};
+
+///btBvhSubtreeInfo provides info to gather a subtree of limited size
+ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo
+{
+public:
+ //12 bytes
+ unsigned short int m_quantizedAabbMin[3];
+ unsigned short int m_quantizedAabbMax[3];
+ //4 bytes, points to the root of the subtree
+ int m_rootNodeIndex;
+ //4 bytes
+ int m_subtreeSize;
+ int m_padding[3];
+
+
+ void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode)
+ {
+ m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0];
+ m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1];
+ m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2];
+ m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0];
+ m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1];
+ m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2];
+ }
+}
+;
+
+
class btNodeOverlapCallback
{
public:
virtual ~btNodeOverlapCallback() {};
- virtual void processNode(const btOptimizedBvhNode* node) = 0;
+ virtual void processNode(int subPart, int triangleIndex) = 0;
};
-#include "LinearMath/btAlignedAllocator.h"
-#include "LinearMath/btAlignedObjectArray.h"
+#include "../../LinearMath/btAlignedAllocator.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
-//typedef std::vector< unsigned , allocator_type > container_type;
-const unsigned size = (1 << 20);
-typedef btAlignedAllocator< btOptimizedBvhNode , size > allocator_type;
-//typedef btAlignedObjectArray<btOptimizedBvhNode, allocator_type> NodeArray;
+///for code readability:
typedef btAlignedObjectArray<btOptimizedBvhNode> NodeArray;
+typedef btAlignedObjectArray<btQuantizedBvhNode> QuantizedNodeArray;
+typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray;
///OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future)
-class btOptimizedBvh
+ATTRIBUTE_ALIGNED16(class) btOptimizedBvh
{
NodeArray m_leafNodes;
+ NodeArray m_contiguousNodes;
- btOptimizedBvhNode* m_rootNode1;
+ QuantizedNodeArray m_quantizedLeafNodes;
+
+ QuantizedNodeArray m_quantizedContiguousNodes;
- btOptimizedBvhNode* m_contiguousNodes;
int m_curNodeIndex;
- int m_numNodes;
+ //quantization data
+ bool m_useQuantization;
+ btVector3 m_bvhAabbMin;
+ btVector3 m_bvhAabbMax;
+ btVector3 m_bvhQuantization;
+ enum btTraversalMode
+ {
+ TRAVERSAL_STACKLESS = 0,
+ TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
+ TRAVERSAL_RECURSIVE
+ };
-public:
- btOptimizedBvh();
+ btTraversalMode m_traversalMode;
- virtual ~btOptimizedBvh();
- void build(btStridingMeshInterface* triangles);
- btOptimizedBvhNode* buildTree (NodeArray& leafNodes,int startIndex,int endIndex);
- int calcSplittingAxis(NodeArray& leafNodes,int startIndex,int endIndex);
+ BvhSubtreeInfoArray m_SubtreeHeaders;
+
+
+ ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
+ ///this might be refactored into a virtual, it is usually not calculated at run-time
+ void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin)
+ {
+ if (m_useQuantization)
+ {
+ quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin);
+ } else
+ {
+ m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin;
+
+ }
+ }
+ void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax)
+ {
+ if (m_useQuantization)
+ {
+ quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax);
+ } else
+ {
+ m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax;
+ }
+ }
+
+ btVector3 getAabbMin(int nodeIndex) const
+ {
+ if (m_useQuantization)
+ {
+ return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]);
+ }
+ //non-quantized
+ return m_leafNodes[nodeIndex].m_aabbMinOrg;
+
+ }
+ btVector3 getAabbMax(int nodeIndex) const
+ {
+ if (m_useQuantization)
+ {
+ return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]);
+ }
+ //non-quantized
+ return m_leafNodes[nodeIndex].m_aabbMaxOrg;
+
+ }
+
+ void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
+
+ void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
+ {
+ if (m_useQuantization)
+ {
+ m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex;
+ }
+ else
+ {
+ m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex;
+ }
+
+ }
+
+ void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax)
+ {
+ if (m_useQuantization)
+ {
+ unsigned short int quantizedAabbMin[3];
+ unsigned short int quantizedAabbMax[3];
+ quantizeWithClamp(quantizedAabbMin,newAabbMin);
+ quantizeWithClamp(quantizedAabbMax,newAabbMax);
+ for (int i=0;i<3;i++)
+ {
+ if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i])
+ m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i];
+
+ if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i])
+ m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i];
+
+ }
+ } else
+ {
+ //non-quantized
+ m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin);
+ m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax);
+ }
+ }
+
+ void swapLeafNodes(int firstIndex,int secondIndex);
+
+ void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex);
+
+protected:
- int sortAndCalcSplittingIndex(NodeArray& leafNodes,int startIndex,int endIndex,int splitAxis);
- void walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+ void buildTree (int startIndex,int endIndex);
+
+ int calcSplittingAxis(int startIndex,int endIndex);
+
+ int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis);
- void walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+ void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
+
+ ///tree traversal designed for small-memory processors like PS3 SPU
+ void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
+
+ ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
+ void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
+
+ ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
+ void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
- //OptimizedBvhNode* GetRootNode() { return m_rootNode1;}
+ inline bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
+ {
+ bool overlap = true;
+ overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+ overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+ overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+ return overlap;
+ }
+
+ void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
+
+public:
+ btOptimizedBvh();
+
+ virtual ~btOptimizedBvh();
- int getNumNodes() { return m_numNodes;}
+ void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax);
void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ void quantizeWithClamp(unsigned short* out, const btVector3& point) const;
+
+ btVector3 unQuantize(const unsigned short* vecIn) const;
-};
+ ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees.
+ void setTraversalMode(btTraversalMode traversalMode)
+ {
+ m_traversalMode = traversalMode;
+ }
+
+ void refit(btStridingMeshInterface* triangles);
+
+ void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax);
+
+ void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index);
+
+
+ QuantizedNodeArray& getQuantizedNodeArray()
+ {
+ return m_quantizedContiguousNodes;
+ }
+
+ BvhSubtreeInfoArray& getSubtreeInfoArray()
+ {
+ return m_SubtreeHeaders;
+ }
+
+}
+;
#endif //OPTIMIZED_BVH_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
index 6f2272cc454..bbc4ba62af6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
@@ -16,7 +16,10 @@ subject to the following restrictions:
#include <BulletCollision/CollisionShapes/btPolyhedralConvexShape.h>
btPolyhedralConvexShape::btPolyhedralConvexShape()
-:m_optionalHull(0)
+:m_localAabbMin(1,1,1),
+m_localAabbMax(-1,-1,-1),
+m_isLocalAabbValid(false),
+m_optionalHull(0)
{
}
@@ -28,16 +31,16 @@ btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const b
int i;
btVector3 supVec(0,0,0);
- btScalar maxDot(-1e30f);
+ btScalar maxDot(btScalar(-1e30));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
- if (lenSqr < 0.0001f)
+ if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
- float rlen = 1.f / btSqrt(lenSqr );
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
@@ -68,7 +71,7 @@ void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(
for (i=0;i<numVectors;i++)
{
- supportVerticesOut[i][3] = -1e30f;
+ supportVerticesOut[i][3] = btScalar(-1e30);
}
for (int j=0;j<numVectors;j++)
@@ -96,23 +99,50 @@ void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& ine
{
//not yet, return box inertia
- float margin = getMargin();
+ btScalar margin = getMargin();
btTransform ident;
ident.setIdentity();
btVector3 aabbMin,aabbMax;
getAabb(ident,aabbMin,aabbMax);
- btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
+ btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
- btScalar lx=2.f*(halfExtents.x()+margin);
- btScalar ly=2.f*(halfExtents.y()+margin);
- btScalar lz=2.f*(halfExtents.z()+margin);
+ btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
+ btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
+ btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
- const btScalar scaledmass = mass * 0.08333333f;
+ const btScalar scaledmass = mass * btScalar(0.08333333);
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
}
+
+
+void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+ getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
+}
+
+
+
+
+void btPolyhedralConvexShape::recalcLocalAabb()
+{
+ m_isLocalAabbValid = true;
+
+ for (int i=0;i<3;i++)
+ {
+ btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+ vec[i] = btScalar(1.);
+ btVector3 tmp = localGetSupportingVertex(vec);
+ m_localAabbMax[i] = tmp[i]+m_collisionMargin;
+ vec[i] = btScalar(-1.);
+ tmp = localGetSupportingVertex(vec);
+ m_localAabbMin[i] = tmp[i]-m_collisionMargin;
+ }
+}
+
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
index a404504ba86..c35f7512663 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
@@ -16,15 +16,20 @@ subject to the following restrictions:
#ifndef BU_SHAPE
#define BU_SHAPE
-#include <LinearMath/btPoint3.h>
-#include <LinearMath/btMatrix3x3.h>
-#include <BulletCollision/CollisionShapes/btConvexShape.h>
+#include "../../LinearMath/btPoint3.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "btConvexShape.h"
///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes.
class btPolyhedralConvexShape : public btConvexShape
{
+protected:
+ btVector3 m_localAabbMin;
+ btVector3 m_localAabbMax;
+ bool m_isLocalAabbValid;
+
public:
btPolyhedralConvexShape();
@@ -36,6 +41,39 @@ public:
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
+ inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
+ {
+
+ //lazy evaluation of local aabb
+ btAssert(m_isLocalAabbValid);
+
+ btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX());
+ btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY());
+ btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ());
+
+
+ btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
+ btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
+
+ btMatrix3x3 abs_b = trans.getBasis().absolute();
+
+ btPoint3 center = trans(localCenter);
+
+ btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
+ abs_b[1].dot(localHalfExtents),
+ abs_b[2].dot(localHalfExtents));
+ extent += btVector3(margin,margin,margin);
+
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+
+
+ }
+
+
+ virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+ void recalcLocalAabb();
virtual int getNumVertices() const = 0 ;
virtual int getNumEdges() const = 0;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
index 39e458c0f22..ca65dd03f3e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
@@ -26,14 +26,17 @@ btSphereShape ::btSphereShape (btScalar radius)
btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
- return btVector3(0.f,0.f,0.f);
+ (void)vec;
+ return btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
}
void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
+ (void)vectors;
+
for (int i=0;i<numVectors;i++)
{
- supportVerticesOut[i].setValue(0.f,0.f,0.f);
+ supportVerticesOut[i].setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
}
@@ -46,7 +49,7 @@ btVector3 btSphereShape::localGetSupportingVertex(const btVector3& vec)const
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
- vecnorm.setValue(-1.f,-1.f,-1.f);
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -67,8 +70,8 @@ void btSphereShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& a
void btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
- btScalar elem = 0.4f * mass * getMargin()*getMargin();
- inertia[0] = inertia[1] = inertia[2] = elem;
+ btScalar elem = btScalar(0.4) * mass * getMargin()*getMargin();
+ inertia.setValue(elem,elem,elem);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
index 2db6a872b40..66521664087 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
@@ -17,10 +17,10 @@ subject to the following restrictions:
#define SPHERE_MINKOWSKI_H
#include "btConvexShape.h"
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btSphereShape implements an implicit (getSupportingVertex) Sphere
-class btSphereShape : public btConvexShape
+ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexShape
{
@@ -45,11 +45,11 @@ public:
//debugging
virtual char* getName()const {return "SPHERE";}
- virtual void setMargin(float margin)
+ virtual void setMargin(btScalar margin)
{
btConvexShape::setMargin(margin);
}
- virtual float getMargin() const
+ virtual btScalar getMargin() const
{
//to improve gjk behaviour, use radius+margin as the full margin, so never get into the penetration case
//this means, non-uniform scaling is not supported anymore
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
index 8c7022ba83b..4fbaafa1b93 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
@@ -21,7 +21,7 @@ subject to the following restrictions:
btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
:m_planeNormal(planeNormal),
m_planeConstant(planeConstant),
-m_localScaling(0.f,0.f,0.f)
+m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
{
}
@@ -34,16 +34,19 @@ btStaticPlaneShape::~btStaticPlaneShape()
void btStaticPlaneShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
- btVector3 infvec (1e30f,1e30f,1e30f);
+ (void)t;
+ /*
+ btVector3 infvec (btScalar(1e30),btScalar(1e30),btScalar(1e30));
btVector3 center = m_planeNormal*m_planeConstant;
aabbMin = center + infvec*m_planeNormal;
aabbMax = aabbMin;
aabbMin.setMin(center - infvec*m_planeNormal);
aabbMax.setMax(center - infvec*m_planeNormal);
+ */
- aabbMin.setValue(-1e30f,-1e30f,-1e30f);
- aabbMax.setValue(1e30f,1e30f,1e30f);
+ aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
}
@@ -53,9 +56,9 @@ void btStaticPlaneShape::getAabb(const btTransform& t,btVector3& aabbMin,btVecto
void btStaticPlaneShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
- btVector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
+ btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5);
btScalar radius = halfExtents.length();
- btVector3 center = (aabbMax + aabbMin) * 0.5f;
+ btVector3 center = (aabbMax + aabbMin) * btScalar(0.5);
//this is where the triangles are generated, given AABB and plane equation (normal/constant)
@@ -85,9 +88,11 @@ void btStaticPlaneShape::processAllTriangles(btTriangleCallback* callback,const
void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
+ (void)mass;
+
//moving concave objects not supported
- inertia.setValue(0.f,0.f,0.f);
+ inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
void btStaticPlaneShape::setLocalScaling(const btVector3& scaling)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
index 65b30e1ff06..f59cc0c3347 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef STATIC_PLANE_SHAPE_H
#define STATIC_PLANE_SHAPE_H
-#include "BulletCollision/CollisionShapes/btConcaveShape.h"
+#include "btConcaveShape.h"
///StaticPlaneShape simulates an 'infinite' plane by dynamically reporting triangles approximated by intersection of the plane with the AABB.
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
index 76b5859be7e..03ca1ae7736 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
@@ -23,6 +23,8 @@ btStridingMeshInterface::~btStridingMeshInterface()
void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
+ (void)aabbMin;
+ (void)aabbMax;
int numtotalphysicsverts = 0;
int part,graphicssubparts = getNumSubParts();
const unsigned char * vertexbase;
@@ -33,7 +35,7 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
int stride,numverts,numtriangles;
int gfxindex;
btVector3 triangle[3];
- float* graphicsbase;
+ btScalar* graphicsbase;
btVector3 meshScaling = getScaling();
@@ -50,11 +52,11 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{
int* tri_indices= (int*)(indexbase+gfxindex*indexstride);
- graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride);
triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
- graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride);
triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
- graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride);
triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
callback->internalProcessTriangleIndex(triangle,part,gfxindex);
}
@@ -65,11 +67,11 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
{
short int* tri_indices= (short int*)(indexbase+gfxindex*indexstride);
- graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride);
triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
- graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride);
triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
- graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
+ graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride);
triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(), graphicsbase[2]*meshScaling.getZ());
callback->internalProcessTriangleIndex(triangle,part,gfxindex);
}
@@ -83,3 +85,40 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
}
}
+void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
+{
+
+ struct AabbCalculationCallback : public btInternalTriangleIndexCallback
+ {
+ btVector3 m_aabbMin;
+ btVector3 m_aabbMax;
+
+ AabbCalculationCallback()
+ {
+ m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ }
+
+ virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
+ {
+ (void)partId;
+ (void)triangleIndex;
+
+ m_aabbMin.setMin(triangle[0]);
+ m_aabbMax.setMax(triangle[0]);
+ m_aabbMin.setMin(triangle[1]);
+ m_aabbMax.setMax(triangle[1]);
+ m_aabbMin.setMin(triangle[2]);
+ m_aabbMax.setMax(triangle[2]);
+ }
+ };
+
+ //first calculate the total aabb for all triangles
+ AabbCalculationCallback aabbCallback;
+ aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+ aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
+
+ aabbMin = aabbCallback.m_aabbMin;
+ aabbMax = aabbCallback.m_aabbMax;
+} \ No newline at end of file
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
index 830cbb28200..d7b354b7855 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef STRIDING_MESHINTERFACE_H
#define STRIDING_MESHINTERFACE_H
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
#include "btTriangleCallback.h"
/// PHY_ScalarType enumerates possible scalar types.
@@ -38,7 +38,7 @@ class btStridingMeshInterface
btVector3 m_scaling;
public:
- btStridingMeshInterface() :m_scaling(1.f,1.f,1.f)
+ btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.))
{
}
@@ -49,6 +49,8 @@ class btStridingMeshInterface
void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+ ///brute force method to calculate aabb
+ void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax);
/// get read and write access to a subpart of a triangle mesh
/// this subpart has a continuous array of vertices and indices
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
index 7cb40c4fac1..3aa1eda9964 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
@@ -58,6 +58,8 @@ btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const
void btBU_Simplex1to4::addVertex(const btPoint3& pt)
{
m_vertices[m_numVertices++] = pt;
+
+ recalcLocalAabb();
}
@@ -176,17 +178,17 @@ int btBU_Simplex1to4::getNumPlanes() const
}
-void btBU_Simplex1to4::getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const
+void btBU_Simplex1to4::getPlane(btVector3&, btPoint3& ,int ) const
{
}
-int btBU_Simplex1to4::getIndex(int i) const
+int btBU_Simplex1to4::getIndex(int ) const
{
return 0;
}
-bool btBU_Simplex1to4::isInside(const btPoint3& pt,btScalar tolerance) const
+bool btBU_Simplex1to4::isInside(const btPoint3& ,btScalar ) const
{
return false;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
index 9e17a248f84..94bc4ec0fa5 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
@@ -17,8 +17,8 @@ subject to the following restrictions:
#define BU_SIMPLEX_1TO4_SHAPE
-#include <BulletCollision/CollisionShapes/btPolyhedralConvexShape.h>
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "btPolyhedralConvexShape.h"
+#include "../BroadphaseCollision/btBroadphaseProxy.h"
///BU_Simplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex).
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
index 9a623403846..3805c519d22 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
@@ -17,8 +17,7 @@ subject to the following restrictions:
#define BT_TRIANGLE_BUFFER_H
#include "btTriangleCallback.h"
-//#include <vector>
-#include "LinearMath/btAlignedObjectArray.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
struct btTriangle
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h
index 7b2337498ec..fbb87bc4fd8 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleCallback.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef TRIANGLE_CALLBACK_H
#define TRIANGLE_CALLBACK_H
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
class btTriangleCallback
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
index 7400d372bee..00847861cf1 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
@@ -15,15 +15,15 @@ subject to the following restrictions:
#include "btTriangleIndexVertexArray.h"
-btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,float* vertexBase,int vertexStride)
+btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride)
{
btIndexedMesh mesh;
mesh.m_numTriangles = numTriangles;
- mesh.m_triangleIndexBase = triangleIndexBase;
+ mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase;
mesh.m_triangleIndexStride = triangleIndexStride;
mesh.m_numVertices = numVertices;
- mesh.m_vertexBase = vertexBase;
+ mesh.m_vertexBase = (const unsigned char *)vertexBase;
mesh.m_vertexStride = vertexStride;
addIndexedMesh(mesh);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
index 3ec827c03d9..6ab6a762b39 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
@@ -17,40 +17,44 @@ subject to the following restrictions:
#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
#include "btStridingMeshInterface.h"
-#include <LinearMath/btAlignedObjectArray.h>
+#include "../../LinearMath/btAlignedObjectArray.h"
///IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
///instead of the number of indices, we pass the number of triangles
///todo: explain with pictures
-struct btIndexedMesh
- {
- int m_numTriangles;
- int* m_triangleIndexBase;
- int m_triangleIndexStride;
- int m_numVertices;
- float* m_vertexBase;
- int m_vertexStride;
- };
+ATTRIBUTE_ALIGNED16( struct) btIndexedMesh
+{
+ int m_numTriangles;
+ const unsigned char * m_triangleIndexBase;
+ int m_triangleIndexStride;
+ int m_numVertices;
+ const unsigned char * m_vertexBase;
+ int m_vertexStride;
+ int pad[2];
+}
+;
+
+
+typedef btAlignedObjectArray<btIndexedMesh> IndexedMeshArray;
///TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
///Additional meshes can be added using addIndexedMesh
///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays.
///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray.
-class btTriangleIndexVertexArray : public btStridingMeshInterface
+ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface
{
- btAlignedObjectArray<btIndexedMesh> m_indexedMeshes;
+ IndexedMeshArray m_indexedMeshes;
+ int m_pad[3];
public:
-
-
btTriangleIndexVertexArray()
{
}
//just to be backwards compatible
- btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,float* vertexBase,int vertexStride);
+ btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride);
void addIndexedMesh(const btIndexedMesh& mesh)
{
@@ -64,19 +68,30 @@ public:
/// unLockVertexBase finishes the access to a subpart of the triangle mesh
/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
- virtual void unLockVertexBase(int subpart) {}
+ virtual void unLockVertexBase(int subpart) {(void)subpart;}
- virtual void unLockReadOnlyVertexBase(int subpart) const {}
+ virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;}
/// getNumSubParts returns the number of seperate subparts
/// each subpart has a continuous array of vertices and indices
virtual int getNumSubParts() const {
return (int)m_indexedMeshes.size();
}
-
- virtual void preallocateVertices(int numverts){}
- virtual void preallocateIndices(int numindices){}
-};
+ IndexedMeshArray& getIndexedMeshArray()
+ {
+ return m_indexedMeshes;
+ }
+
+ const IndexedMeshArray& getIndexedMeshArray() const
+ {
+ return m_indexedMeshes;
+ }
+
+ virtual void preallocateVertices(int numverts){(void) numverts;}
+ virtual void preallocateIndices(int numindices){(void) numindices;}
+
+}
+;
#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
index 489fe1bbcaa..98c54ef45f8 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btTriangleMesh.h"
#include <assert.h>
-static int myindices[3] = {0,1,2};
btTriangleMesh::btTriangleMesh ()
{
@@ -25,31 +24,31 @@ btTriangleMesh::btTriangleMesh ()
void btTriangleMesh::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart)
{
- numverts = 3;
- *vertexbase = (unsigned char*)&m_triangles[subpart];
+ (void)subpart;
+ numverts = m_vertices.size();
+ *vertexbase = (unsigned char*)&m_vertices[0];
type = PHY_FLOAT;
stride = sizeof(btVector3);
-
- numfaces = 1;
- *indexbase = (unsigned char*) &myindices[0];
+ numfaces = m_indices.size()/3;
+ *indexbase = (unsigned char*) &m_indices[0];
indicestype = PHY_INTEGER;
- indexstride = sizeof(int);
+ indexstride = 3*sizeof(int);
}
void btTriangleMesh::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const
{
- numverts = 3;
- *vertexbase = (unsigned char*)&m_triangles[subpart];
+ (void)subpart;
+ numverts = m_vertices.size();
+ *vertexbase = (unsigned char*)&m_vertices[0];
type = PHY_FLOAT;
stride = sizeof(btVector3);
-
- numfaces = 1;
- *indexbase = (unsigned char*) &myindices[0];
+ numfaces = m_indices.size()/3;
+ *indexbase = (unsigned char*) &m_indices[0];
indicestype = PHY_INTEGER;
- indexstride = sizeof(int);
+ indexstride = 3*sizeof(int);
}
@@ -57,5 +56,5 @@ void btTriangleMesh::getLockedReadOnlyVertexIndexBase(const unsigned char **vert
int btTriangleMesh::getNumSubParts() const
{
- return m_triangles.size();
+ return 1;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
index 1be03d70436..525f5336b48 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
@@ -17,42 +17,37 @@ subject to the following restrictions:
#ifndef TRIANGLE_MESH_H
#define TRIANGLE_MESH_H
-#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
-#include <LinearMath/btVector3.h>
-#include "LinearMath/btAlignedObjectArray.h"
-struct btMyTriangle
-{
- btVector3 m_vert0;
- btVector3 m_vert1;
- btVector3 m_vert2;
-};
+#include "btStridingMeshInterface.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
///TriangleMesh provides storage for a concave triangle mesh. It can be used as data for the btTriangleMeshShape.
class btTriangleMesh : public btStridingMeshInterface
{
- btAlignedObjectArray<btMyTriangle> m_triangles;
+ btAlignedObjectArray<btVector3> m_vertices;
+ btAlignedObjectArray<int> m_indices;
public:
btTriangleMesh ();
void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2)
{
- btMyTriangle tri;
- tri.m_vert0 = vertex0;
- tri.m_vert1 = vertex1;
- tri.m_vert2 = vertex2;
- m_triangles.push_back(tri);
+ int curIndex = m_indices.size();
+ m_vertices.push_back(vertex0);
+ m_vertices.push_back(vertex1);
+ m_vertices.push_back(vertex2);
+
+ m_indices.push_back(curIndex++);
+ m_indices.push_back(curIndex++);
+ m_indices.push_back(curIndex++);
}
int getNumTriangles() const
{
- return m_triangles.size();
+ return m_indices.size() / 3;
}
- const btMyTriangle& getTriangle(int index) const
- {
- return m_triangles[index];
- }
+
//StridingMeshInterface interface implementation
@@ -62,16 +57,16 @@ class btTriangleMesh : public btStridingMeshInterface
/// unLockVertexBase finishes the access to a subpart of the triangle mesh
/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
- virtual void unLockVertexBase(int subpart) {}
+ virtual void unLockVertexBase(int subpart) {(void) subpart;}
- virtual void unLockReadOnlyVertexBase(int subpart) const {}
+ virtual void unLockReadOnlyVertexBase(int subpart) const { (void) subpart;}
/// getNumSubParts returns the number of seperate subparts
/// each subpart has a continuous array of vertices and indices
virtual int getNumSubParts() const;
- virtual void preallocateVertices(int numverts){}
- virtual void preallocateIndices(int numindices){}
+ virtual void preallocateVertices(int numverts){(void) numverts;}
+ virtual void preallocateIndices(int numindices){(void) numindices;}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
index cd2bf7261d1..ed81897b515 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
@@ -40,8 +40,8 @@ btTriangleMeshShape::~btTriangleMeshShape()
void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
- btVector3 localHalfExtents = 0.5f*(m_localAabbMax-m_localAabbMin);
- btVector3 localCenter = 0.5f*(m_localAabbMax+m_localAabbMin);
+ btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
+ btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
@@ -62,11 +62,11 @@ void btTriangleMeshShape::recalcLocalAabb()
{
for (int i=0;i<3;i++)
{
- btVector3 vec(0.f,0.f,0.f);
- vec[i] = 1.f;
+ btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+ vec[i] = btScalar(1.);
btVector3 tmp = localGetSupportingVertex(vec);
m_localAabbMax[i] = tmp[i]+m_collisionMargin;
- vec[i] = -1.f;
+ vec[i] = btScalar(-1.);
tmp = localGetSupportingVertex(vec);
m_localAabbMin[i] = tmp[i]-m_collisionMargin;
}
@@ -85,7 +85,7 @@ public:
btVector3 m_supportVecLocal;
SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
- : m_supportVertexLocal(0.f,0.f,0.f), m_worldTrans(trans) ,m_maxDot(-1e30f)
+ : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-1e30))
{
m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
@@ -93,6 +93,8 @@ public:
virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
{
+ (void)partId;
+ (void)triangleIndex;
for (int i=0;i<3;i++)
{
btScalar dot = m_supportVecLocal.dot(triangle[i]);
@@ -138,8 +140,7 @@ const btVector3& btTriangleMeshShape::getLocalScaling() const
void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
-
- struct FilteredCallback : public btInternalTriangleIndexCallback
+ struct FilteredCallback : public btInternalTriangleIndexCallback
{
btTriangleCallback* m_callback;
btVector3 m_aabbMin;
@@ -167,18 +168,19 @@ void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const
FilteredCallback filterCallback(callback,aabbMin,aabbMax);
m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
-
}
+
void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
+ (void)mass;
//moving concave objects not supported
- assert(0);
- inertia.setValue(0.f,0.f,0.f);
+ btAssert(0);
+ inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
@@ -191,7 +193,7 @@ btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) co
SupportVertexCallback supportCallback(vec,ident);
- btVector3 aabbMax(1e30f,1e30f,1e30f);
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
processAllTriangles(&supportCallback,-aabbMax,aabbMax);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
index 4bf000f0c8d..e6173e47640 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
@@ -16,17 +16,17 @@ subject to the following restrictions:
#ifndef TRIANGLE_MESH_SHAPE_H
#define TRIANGLE_MESH_SHAPE_H
-#include "BulletCollision/CollisionShapes/btConcaveShape.h"
-#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
+#include "btConcaveShape.h"
+#include "btStridingMeshInterface.h"
///Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
class btTriangleMeshShape : public btConcaveShape
{
protected:
- btStridingMeshInterface* m_meshInterface;
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
+ btStridingMeshInterface* m_meshInterface;
public:
@@ -58,6 +58,16 @@ public:
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const;
+ btStridingMeshInterface* getMeshInterface()
+ {
+ return m_meshInterface;
+ }
+
+ const btStridingMeshInterface* getMeshInterface() const
+ {
+ return m_meshInterface;
+ }
+
//debugging
virtual char* getName()const {return "TRIANGLEMESH";}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
index 3284a599ea7..c2e240c051c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define OBB_TRIANGLE_MINKOWSKI_H
#include "btConvexShape.h"
-#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "btBoxShape.h"
class btTriangleShape : public btPolyhedralConvexShape
{
@@ -57,6 +57,7 @@ public:
getVertex((i+1)%3,pb);
}
+
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const
{
// btAssert(0);
@@ -110,14 +111,16 @@ public:
virtual void getPlaneEquation(int i, btVector3& planeNormal,btPoint3& planeSupport) const
{
+ (void)i;
calcNormal(planeNormal);
planeSupport = m_vertices1[0];
}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia)
{
+ (void)mass;
btAssert(0);
- inertia.setValue(0.f,0.f,0.f);
+ inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
@@ -166,7 +169,7 @@ public:
{
calcNormal(penetrationVector);
if (index)
- penetrationVector *= -1.f;
+ penetrationVector *= btScalar(-1.);
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
index ae3ce42e77f..2c565734e97 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
@@ -49,28 +49,28 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
/// compute linear and angular velocity for this interval, to interpolate
btVector3 linVelA,angVelA,linVelB,angVelB;
- btTransformUtil::calculateVelocity(fromA,toA,1.f,linVelA,angVelA);
- btTransformUtil::calculateVelocity(fromB,toB,1.f,linVelB,angVelB);
+ btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
+ btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);
btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();
btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
- float radius = 0.001f;
+ btScalar radius = btScalar(0.001);
- btScalar lambda = 0.f;
+ btScalar lambda = btScalar(0.);
btVector3 v(1,0,0);
int maxIter = MAX_ITERATIONS;
btVector3 n;
- n.setValue(0.f,0.f,0.f);
+ n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
bool hasResult = false;
btVector3 c;
- float lastLambda = lambda;
- //float epsilon = 0.001f;
+ btScalar lastLambda = lambda;
+ //btScalar epsilon = btScalar(0.001);
int numIter = 0;
//first solution, using GJK
@@ -79,8 +79,8 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
btTransform identityTrans;
identityTrans.setIdentity();
- btSphereShape raySphere(0.0f);
- raySphere.setMargin(0.f);
+ btSphereShape raySphere(btScalar(0.0));
+ raySphere.setMargin(btScalar(0.));
// result.drawCoordSystem(sphereTr);
@@ -116,23 +116,23 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
if (numIter > maxIter)
return false; //todo: report a failure
- float dLambda = 0.f;
+ btScalar dLambda = btScalar(0.);
//calculate safe moving fraction from distance / (linear+rotational velocity)
- //float clippedDist = GEN_min(angularConservativeRadius,dist);
- //float clippedDist = dist;
+ //btScalar clippedDist = GEN_min(angularConservativeRadius,dist);
+ //btScalar clippedDist = dist;
- float projectedLinearVelocity = (linVelB-linVelA).dot(n);
+ btScalar projectedLinearVelocity = (linVelB-linVelA).dot(n);
dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
lambda = lambda + dLambda;
- if (lambda > 1.f)
+ if (lambda > btScalar(1.))
return false;
- if (lambda < 0.f)
+ if (lambda < btScalar(0.))
return false;
//todo: next check with relative epsilon
@@ -159,7 +159,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
gjk.getClosestPoints(input,pointCollector,0);
if (pointCollector.m_hasResult)
{
- if (pointCollector.m_distance < 0.f)
+ if (pointCollector.m_distance < btScalar(0.))
{
//degenerate ?!
result.m_fraction = lastLambda;
@@ -188,9 +188,9 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
//todo:
//if movement away from normal, discard result
btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
- if (result.m_fraction < 1.f)
+ if (result.m_fraction < btScalar(1.))
{
- if (move.dot(result.m_normal) <= 0.f)
+ if (move.dot(result.m_normal) <= btScalar(0.))
{
}
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
index 4258d829cca..3101b59993d 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h
@@ -17,11 +17,11 @@ subject to the following restrictions:
#ifndef CONVEX_CAST_H
#define CONVEX_CAST_H
-#include <LinearMath/btTransform.h>
-#include <LinearMath/btVector3.h>
-#include <LinearMath/btScalar.h>
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btScalar.h"
class btMinkowskiSumShape;
-#include "LinearMath/btIDebugDraw.h"
+#include "../../LinearMath/btIDebugDraw.h"
/// btConvexCast is an interface for Casting
class btConvexCast
@@ -37,11 +37,11 @@ public:
{
//virtual bool addRayResult(const btVector3& normal,btScalar fraction) = 0;
- virtual void DebugDraw(btScalar fraction) {}
- virtual void drawCoordSystem(const btTransform& trans) {}
+ virtual void DebugDraw(btScalar fraction) {(void)fraction;}
+ virtual void drawCoordSystem(const btTransform& trans) {(void)trans;}
CastResult()
- :m_fraction(1e30f),
+ :m_fraction(btScalar(1e30)),
m_debugDrawer(0)
{
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
index 188c8258c8e..7caeba4be45 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
@@ -21,7 +21,7 @@ class btStackAlloc;
class btVector3;
#include "btSimplexSolverInterface.h"
class btConvexShape;
-#include "LinearMath/btPoint3.h"
+#include "../../LinearMath/btPoint3.h"
class btTransform;
///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
index e9db97d1b13..15000c1ab61 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
#define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
-#include "LinearMath/btTransform.h"
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
class btStackAlloc;
/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations
@@ -30,19 +30,18 @@ struct btDiscreteCollisionDetectorInterface
struct Result
{
- void operator delete(void* ptr) {};
virtual ~Result(){}
///setShapeIdentifiers provides experimental support for per-triangle material / custom material combiner
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)=0;
- virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)=0;
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0;
};
struct ClosestPointInput
{
ClosestPointInput()
- :m_maximumDistanceSquared(1e30f),
+ :m_maximumDistanceSquared(btScalar(1e30)),
m_stackAlloc(0)
{
}
@@ -69,13 +68,13 @@ struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result
btVector3 m_closestPointInB;
btScalar m_distance; //negative means penetration !
- btStorageResult() : m_distance(1e30f)
+ btStorageResult() : m_distance(btScalar(1e30))
{
}
virtual ~btStorageResult() {};
- virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
if (depth < m_distance)
{
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
index bf465b61857..93edffeafd6 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
@@ -60,9 +60,9 @@ bool btGjkConvexCast::calcTimeOfImpact(
- float radius = 0.01f;
+ btScalar radius = btScalar(0.01);
- btScalar lambda = 0.f;
+ btScalar lambda = btScalar(0.);
btVector3 s = rayFromLocalA.getOrigin();
btVector3 r = rayToLocalA.getOrigin()-rayFromLocalA.getOrigin();
btVector3 x = s;
@@ -71,7 +71,7 @@ bool btGjkConvexCast::calcTimeOfImpact(
bool hasResult = false;
btVector3 c;
- float lastLambda = lambda;
+ btScalar lastLambda = lambda;
//first solution, using GJK
@@ -81,8 +81,8 @@ bool btGjkConvexCast::calcTimeOfImpact(
btTransform identityTrans;
identityTrans.setIdentity();
- btSphereShape raySphere(0.0f);
- raySphere.setMargin(0.f);
+ btSphereShape raySphere(btScalar(0.0));
+ raySphere.setMargin(btScalar(0.));
btTransform sphereTr;
sphereTr.setIdentity();
@@ -112,7 +112,7 @@ bool btGjkConvexCast::calcTimeOfImpact(
if (dist < radius)
{
//penetration
- lastLambda = 1.f;
+ lastLambda = btScalar(1.);
}
//not close enough
@@ -143,7 +143,7 @@ bool btGjkConvexCast::calcTimeOfImpact(
gjk.getClosestPoints(input,pointCollector,0);
if (pointCollector.m_hasResult)
{
- if (pointCollector.m_distance < 0.f)
+ if (pointCollector.m_distance < btScalar(0.))
{
//degeneracy, report a hit
result.m_fraction = lastLambda;
@@ -160,7 +160,7 @@ bool btGjkConvexCast::calcTimeOfImpact(
}
- if (lastLambda < 1.f)
+ if (lastLambda < btScalar(1.))
{
result.m_fraction = lastLambda;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
index 66b34b88363..3905c45e6d6 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
@@ -18,9 +18,9 @@ subject to the following restrictions:
#ifndef GJK_CONVEX_CAST_H
#define GJK_CONVEX_CAST_H
-#include <BulletCollision/CollisionShapes/btCollisionMargin.h>
+#include "../CollisionShapes/btCollisionMargin.h"
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
#include "btConvexCast.h"
class btConvexShape;
class btMinkowskiSumShape;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
index 359829f8f31..759b30bb17f 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
@@ -21,7 +21,7 @@ Nov.2006
#ifndef _05E48D53_04E0_49ad_BB0A_D74FE62E7366_
#define _05E48D53_04E0_49ad_BB0A_D74FE62E7366_
-#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "../CollisionShapes/btConvexShape.h"
class btStackAlloc;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
index 3d252751c9a..87330493b60 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
@@ -26,8 +26,11 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
{
+ (void)debugDraw;
+ (void)v;
+ (void)simplexSolver;
- const btScalar radialmargin(0.f);
+ const btScalar radialmargin(btScalar(0.));
btGjkEpaSolver::sResults results;
if(btGjkEpaSolver::Collide( pConvexA,transformA,
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
index 0ce04dcfad8..f1f3f7f7f6c 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
@@ -27,7 +27,7 @@ subject to the following restrictions:
#endif
//must be above the machine epsilon
-#define REL_ERROR2 1.0e-6f
+#define REL_ERROR2 btScalar(1.0e-6)
//temp globals, to improve GJK/EPA/penetration calculations
int gNumDeepPenetrationChecks = 0;
@@ -36,7 +36,7 @@ int gNumGjkChecks = 0;
btGjkPairDetector::btGjkPairDetector(btConvexShape* objectA,btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver)
-:m_cachedSeparatingAxis(0.f,0.f,1.f),
+:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)),
m_penetrationDepthSolver(penetrationDepthSolver),
m_simplexSolver(simplexSolver),
m_minkowskiA(objectA),
@@ -49,25 +49,25 @@ m_catchDegeneracies(1)
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
{
- btScalar distance=0.f;
- btVector3 normalInB(0.f,0.f,0.f);
+ btScalar distance=btScalar(0.);
+ btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 pointOnA,pointOnB;
btTransform localTransA = input.m_transformA;
btTransform localTransB = input.m_transformB;
- btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * 0.5f;
+ btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
localTransA.getOrigin() -= positionOffset;
localTransB.getOrigin() -= positionOffset;
- float marginA = m_minkowskiA->getMargin();
- float marginB = m_minkowskiB->getMargin();
+ btScalar marginA = m_minkowskiA->getMargin();
+ btScalar marginB = m_minkowskiB->getMargin();
gNumGjkChecks++;
//for CCD we don't use margins
if (m_ignoreMargin)
{
- marginA = 0.f;
- marginB = 0.f;
+ marginA = btScalar(0.);
+ marginB = btScalar(0.);
}
m_curIter = 0;
@@ -83,7 +83,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
{
btScalar squaredDistance = SIMD_INFINITY;
- btScalar delta = 0.f;
+ btScalar delta = btScalar(0.);
btScalar margin = marginA + marginB;
@@ -91,7 +91,8 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
m_simplexSolver->reset();
- while (true)
+ for ( ; ; )
+ //while (true)
{
btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
@@ -120,12 +121,12 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
break;
}
// are we getting any closer ?
- float f0 = squaredDistance - delta;
- float f1 = squaredDistance * REL_ERROR2;
+ btScalar f0 = squaredDistance - delta;
+ btScalar f1 = squaredDistance * REL_ERROR2;
if (f0 <= f1)
{
- if (f0 <= 0.f)
+ if (f0 <= btScalar(0.))
{
m_degenerateSimplex = 2;
}
@@ -191,7 +192,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
{
m_simplexSolver->compute_points(pointOnA, pointOnB);
normalInB = pointOnA-pointOnB;
- float lenSqr = m_cachedSeparatingAxis.length2();
+ btScalar lenSqr = m_cachedSeparatingAxis.length2();
//valid normal
if (lenSqr < 0.0001)
{
@@ -199,14 +200,14 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
}
if (lenSqr > SIMD_EPSILON*SIMD_EPSILON)
{
- float rlen = 1.f / btSqrt(lenSqr );
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
normalInB *= rlen; //normalize
btScalar s = btSqrt(squaredDistance);
btAssert(s > btScalar(0.0));
pointOnA -= m_cachedSeparatingAxis * (marginA / s);
pointOnB += m_cachedSeparatingAxis * (marginB / s);
- distance = ((1.f/rlen) - margin);
+ distance = ((btScalar(1.)/rlen) - margin);
isValid = true;
m_lastUsedMethod = 1;
@@ -243,11 +244,11 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
if (isValid2)
{
btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
- float lenSqr = tmpNormalInB.length2();
+ btScalar lenSqr = tmpNormalInB.length2();
if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
{
tmpNormalInB /= btSqrt(lenSqr);
- float distance2 = -(tmpPointOnA-tmpPointOnB).length();
+ btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
//only replace valid penetrations when the result is deeper (check)
if (!isValid || (distance2 < distance))
{
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
index 09c1669bd78..af0fe32f6c7 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
@@ -20,9 +20,8 @@ subject to the following restrictions:
#define GJK_PAIR_DETECTOR_H
#include "btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
-
-#include <BulletCollision/CollisionShapes/btCollisionMargin.h>
+#include "../../LinearMath/btPoint3.h"
+#include "../CollisionShapes/btCollisionMargin.h"
class btConvexShape;
#include "btSimplexSolverInterface.h"
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
index 00a9206fef0..f6a893151da 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef MANIFOLD_CONTACT_POINT_H
#define MANIFOLD_CONTACT_POINT_H
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransformUtil.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransformUtil.h"
@@ -29,7 +29,8 @@ class btManifoldPoint
{
public:
btManifoldPoint()
- :m_userPersistentData(0)
+ :m_userPersistentData(0),
+ m_lifeTime(0)
{
}
@@ -40,8 +41,8 @@ class btManifoldPoint
m_localPointB( pointB ),
m_normalWorldOnB( normal ),
m_distance1( distance ),
- m_combinedFriction(0.f),
- m_combinedRestitution(0.f),
+ m_combinedFriction(btScalar(0.)),
+ m_combinedRestitution(btScalar(0.)),
m_userPersistentData(0),
m_lifeTime(0)
{
@@ -58,16 +59,16 @@ class btManifoldPoint
btVector3 m_positionWorldOnA;
btVector3 m_normalWorldOnB;
- float m_distance1;
- float m_combinedFriction;
- float m_combinedRestitution;
+ btScalar m_distance1;
+ btScalar m_combinedFriction;
+ btScalar m_combinedRestitution;
- void* m_userPersistentData;
+ mutable void* m_userPersistentData;
int m_lifeTime;//lifetime of the contactpoint in frames
- float getDistance() const
+ btScalar getDistance() const
{
return m_distance1;
}
@@ -76,17 +77,17 @@ class btManifoldPoint
return m_lifeTime;
}
- btVector3 getPositionWorldOnA() {
+ const btVector3& getPositionWorldOnA() const {
return m_positionWorldOnA;
// return m_positionWorldOnB + m_normalWorldOnB * m_distance1;
}
- const btVector3& getPositionWorldOnB()
+ const btVector3& getPositionWorldOnB() const
{
return m_positionWorldOnB;
}
- void setDistance(float dist)
+ void setDistance(btScalar dist)
{
m_distance1 = dist;
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
index de6749a9b72..c4bab3a134a 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
@@ -25,48 +25,48 @@ subject to the following restrictions:
#define NUM_UNITSPHERE_POINTS 42
static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] =
{
-btVector3(0.000000f , -0.000000f,-1.000000f),
-btVector3(0.723608f , -0.525725f,-0.447219f),
-btVector3(-0.276388f , -0.850649f,-0.447219f),
-btVector3(-0.894426f , -0.000000f,-0.447216f),
-btVector3(-0.276388f , 0.850649f,-0.447220f),
-btVector3(0.723608f , 0.525725f,-0.447219f),
-btVector3(0.276388f , -0.850649f,0.447220f),
-btVector3(-0.723608f , -0.525725f,0.447219f),
-btVector3(-0.723608f , 0.525725f,0.447219f),
-btVector3(0.276388f , 0.850649f,0.447219f),
-btVector3(0.894426f , 0.000000f,0.447216f),
-btVector3(-0.000000f , 0.000000f,1.000000f),
-btVector3(0.425323f , -0.309011f,-0.850654f),
-btVector3(-0.162456f , -0.499995f,-0.850654f),
-btVector3(0.262869f , -0.809012f,-0.525738f),
-btVector3(0.425323f , 0.309011f,-0.850654f),
-btVector3(0.850648f , -0.000000f,-0.525736f),
-btVector3(-0.525730f , -0.000000f,-0.850652f),
-btVector3(-0.688190f , -0.499997f,-0.525736f),
-btVector3(-0.162456f , 0.499995f,-0.850654f),
-btVector3(-0.688190f , 0.499997f,-0.525736f),
-btVector3(0.262869f , 0.809012f,-0.525738f),
-btVector3(0.951058f , 0.309013f,0.000000f),
-btVector3(0.951058f , -0.309013f,0.000000f),
-btVector3(0.587786f , -0.809017f,0.000000f),
-btVector3(0.000000f , -1.000000f,0.000000f),
-btVector3(-0.587786f , -0.809017f,0.000000f),
-btVector3(-0.951058f , -0.309013f,-0.000000f),
-btVector3(-0.951058f , 0.309013f,-0.000000f),
-btVector3(-0.587786f , 0.809017f,-0.000000f),
-btVector3(-0.000000f , 1.000000f,-0.000000f),
-btVector3(0.587786f , 0.809017f,-0.000000f),
-btVector3(0.688190f , -0.499997f,0.525736f),
-btVector3(-0.262869f , -0.809012f,0.525738f),
-btVector3(-0.850648f , 0.000000f,0.525736f),
-btVector3(-0.262869f , 0.809012f,0.525738f),
-btVector3(0.688190f , 0.499997f,0.525736f),
-btVector3(0.525730f , 0.000000f,0.850652f),
-btVector3(0.162456f , -0.499995f,0.850654f),
-btVector3(-0.425323f , -0.309011f,0.850654f),
-btVector3(-0.425323f , 0.309011f,0.850654f),
-btVector3(0.162456f , 0.499995f,0.850654f)
+btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
+btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
+btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
+btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
+btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
+btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
+btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
+btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
+btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
+btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
+btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
+btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
+btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
+btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
+btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
+btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
+btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
+btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
+btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
+btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
+btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
+btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
+btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
+btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
+btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
+btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
+btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
+btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
+btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
+btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
+btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
+btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
+btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
+btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
+btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
+btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
+btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
+btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
};
@@ -78,6 +78,9 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
)
{
+ (void)stackAlloc;
+ (void)v;
+
struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result
{
@@ -88,13 +91,17 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
btVector3 m_normalOnBInWorld;
btVector3 m_pointInWorld;
- float m_depth;
+ btScalar m_depth;
bool m_hasResult;
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
{
+ (void)partId0;
+ (void)index0;
+ (void)partId1;
+ (void)index1;
}
- void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
+ void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
m_normalOnBInWorld = normalOnBInWorld;
m_pointInWorld = pointInWorld;
@@ -104,7 +111,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
};
//just take fixed number of orientation, and sample the penetration depth in that direction
- float minProj = 1e30f;
+ btScalar minProj = btScalar(1e30);
btVector3 minNorm;
btVector3 minVertex;
btVector3 minA,minB;
@@ -180,7 +187,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
pWorld = transA(pInA);
qWorld = transB(qInB);
w = qWorld - pWorld;
- float delta = norm.dot(w);
+ btScalar delta = norm.dot(w);
//find smallest delta
if (delta < minProj)
{
@@ -234,7 +241,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
pWorld = transA(pInA);
qWorld = transB(qInB);
w = qWorld - pWorld;
- float delta = norm.dot(w);
+ btScalar delta = norm.dot(w);
//find smallest delta
if (delta < minProj)
{
@@ -251,7 +258,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
minA += minNorm*convexA->getMargin();
minB -= minNorm*convexB->getMargin();
//no penetration
- if (minProj < 0.f)
+ if (minProj < btScalar(0.))
return false;
minProj += (convexA->getMargin() + convexB->getMargin());
@@ -268,7 +275,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
debugDraw->drawLine(minA,minB,color);
color = btVector3 (1,1,1);
btVector3 vec = minB-minA;
- float prj2 = minNorm.dot(vec);
+ btScalar prj2 = minNorm.dot(vec);
debugDraw->drawLine(minA,minA+(minNorm*minProj),color);
}
@@ -292,16 +299,16 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
input.m_transformA = displacedTrans;
input.m_transformB = transB;
- input.m_maximumDistanceSquared = 1e30f;//minProj;
+ input.m_maximumDistanceSquared = btScalar(1e30);//minProj;
btIntermediateResult res;
gjkdet.getClosestPoints(input,res,debugDraw);
- float correctedMinNorm = minProj - res.m_depth;
+ btScalar correctedMinNorm = minProj - res.m_depth;
//the penetration depth is over-estimated, relax it
- float penetration_relaxation= 1.f;
+ btScalar penetration_relaxation= btScalar(1.);
minNorm*=penetration_relaxation;
if (res.m_hasResult)
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
index ee2be163063..08cb3ed334d 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
@@ -18,7 +18,7 @@ subject to the following restrictions:
#include "LinearMath/btTransform.h"
#include <assert.h>
-float gContactBreakingThreshold = 0.02f;
+btScalar gContactBreakingThreshold = btScalar(0.02);
ContactDestroyedCallback gContactDestroyedCallback = 0;
@@ -100,7 +100,7 @@ int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt)
int maxPenetrationIndex = -1;
#define KEEP_DEEPEST_POINT 1
#ifdef KEEP_DEEPEST_POINT
- float maxPenetration = pt.getDistance();
+ btScalar maxPenetration = pt.getDistance();
for (int i=0;i<4;i++)
{
if (m_pointCache[i].getDistance() < maxPenetration)
@@ -111,7 +111,7 @@ int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt)
}
#endif //KEEP_DEEPEST_POINT
- btScalar res0(0.f),res1(0.f),res2(0.f),res3(0.f);
+ btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.));
if (maxPenetrationIndex != 0)
{
btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA;
@@ -193,7 +193,7 @@ void btPersistentManifold::AddManifoldPoint(const btManifoldPoint& newPoint)
replaceContactPoint(newPoint,insertIndex);
}
-float btPersistentManifold::getContactBreakingThreshold() const
+btScalar btPersistentManifold::getContactBreakingThreshold() const
{
return gContactBreakingThreshold;
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
index c2372b648f6..a5918b84db3 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
@@ -17,14 +17,14 @@ subject to the following restrictions:
#define PERSISTENT_MANIFOLD_H
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
#include "btManifoldPoint.h"
struct btCollisionResult;
///contact breaking and merging threshold
-extern float gContactBreakingThreshold;
+extern btScalar gContactBreakingThreshold;
typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
extern ContactDestroyedCallback gContactDestroyedCallback;
@@ -36,7 +36,7 @@ extern ContactDestroyedCallback gContactDestroyedCallback;
///btPersistentManifold maintains contact points, and reduces them to 4.
///It does contact filtering/contact reduction.
-class btPersistentManifold
+ATTRIBUTE_ALIGNED16( class) btPersistentManifold
{
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
@@ -97,7 +97,7 @@ public:
}
/// todo: get this margin from the current physics / collision environment
- float getContactBreakingThreshold() const;
+ btScalar getContactBreakingThreshold() const;
int getCacheEntry(const btManifoldPoint& newPoint) const;
@@ -108,18 +108,36 @@ public:
clearUserCache(m_pointCache[index]);
int lastUsedIndex = getNumContacts() - 1;
- m_pointCache[index] = m_pointCache[lastUsedIndex];
- //get rid of duplicated userPersistentData pointer
- m_pointCache[lastUsedIndex].m_userPersistentData = 0;
+// m_pointCache[index] = m_pointCache[lastUsedIndex];
+ if(index != lastUsedIndex)
+ {
+ m_pointCache[index] = m_pointCache[lastUsedIndex];
+ //get rid of duplicated userPersistentData pointer
+ m_pointCache[lastUsedIndex].m_userPersistentData = 0;
+ }
+
+ btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
m_cachedPoints--;
}
void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex)
{
- assert(validContactDistance(newPoint));
+ btAssert(validContactDistance(newPoint));
- clearUserCache(m_pointCache[insertIndex]);
+#define MAINTAIN_PERSISTENCY 1
+#ifdef MAINTAIN_PERSISTENCY
+ int lifeTime = m_pointCache[insertIndex].getLifeTime();
+ btAssert(lifeTime>=0);
+ void* cache = m_pointCache[insertIndex].m_userPersistentData;
m_pointCache[insertIndex] = newPoint;
+
+ m_pointCache[insertIndex].m_userPersistentData = cache;
+ m_pointCache[insertIndex].m_lifeTime = lifeTime;
+#else
+ clearUserCache(m_pointCache[insertIndex]);
+ m_pointCache[insertIndex] = newPoint;
+
+#endif
}
bool validContactDistance(const btManifoldPoint& pt) const
@@ -133,7 +151,10 @@ public:
-};
+}
+;
+
+
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
index a51e2d5e13b..6262f44b9f1 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPointCollector.h
@@ -31,16 +31,20 @@ struct btPointCollector : public btDiscreteCollisionDetectorInterface::Result
bool m_hasResult;
btPointCollector ()
- : m_distance(1e30f),m_hasResult(false)
+ : m_distance(btScalar(1e30)),m_hasResult(false)
{
}
virtual void setShapeIdentifiers(int partId0,int index0, int partId1,int index1)
{
+ (void)partId0;
+ (void)index0;
+ (void)partId1;
+ (void)index1;
//??
}
- virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
if (depth< m_distance)
{
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
index 88ee005792c..31b91467777 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
@@ -20,7 +20,7 @@ btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const
:
m_from(from),
m_to(to),
- m_hitFraction(1.f)
+ m_hitFraction(btScalar(1.))
{
}
@@ -40,19 +40,19 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
btVector3 triangleNormal; triangleNormal = v10.cross( v20 );
- const float dist = vert0.dot(triangleNormal);
- float dist_a = triangleNormal.dot(m_from) ;
+ const btScalar dist = vert0.dot(triangleNormal);
+ btScalar dist_a = triangleNormal.dot(m_from) ;
dist_a-= dist;
- float dist_b = triangleNormal.dot(m_to);
+ btScalar dist_b = triangleNormal.dot(m_to);
dist_b -= dist;
- if ( dist_a * dist_b >= 0.0f)
+ if ( dist_a * dist_b >= btScalar(0.0) )
{
return ; // same sign
}
- const float proj_length=dist_a-dist_b;
- const float distance = (dist_a)/(proj_length);
+ const btScalar proj_length=dist_a-dist_b;
+ const btScalar distance = (dist_a)/(proj_length);
// Now we have the intersection point on the plane, we'll see if it's inside the triangle
// Add an epsilon as a tolerance for the raycast,
// in case the ray hits exacly on the edge of the triangle.
@@ -62,27 +62,27 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
{
- float edge_tolerance =triangleNormal.length2();
- edge_tolerance *= -0.0001f;
+ btScalar edge_tolerance =triangleNormal.length2();
+ edge_tolerance *= btScalar(-0.0001);
btVector3 point; point.setInterpolate3( m_from, m_to, distance);
{
btVector3 v0p; v0p = vert0 - point;
btVector3 v1p; v1p = vert1 - point;
btVector3 cp0; cp0 = v0p.cross( v1p );
- if ( (float)(cp0.dot(triangleNormal)) >=edge_tolerance)
+ if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance)
{
btVector3 v2p; v2p = vert2 - point;
btVector3 cp1;
cp1 = v1p.cross( v2p);
- if ( (float)(cp1.dot(triangleNormal)) >=edge_tolerance)
+ if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance)
{
btVector3 cp2;
cp2 = v2p.cross(v0p);
- if ( (float)(cp2.dot(triangleNormal)) >=edge_tolerance)
+ if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance)
{
if ( dist_a > 0 )
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
index fbb51d30522..a0bbc9f8fe9 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef RAYCAST_TRI_CALLBACK_H
#define RAYCAST_TRI_CALLBACK_H
-#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "../CollisionShapes/btTriangleCallback.h"
struct btBroadphaseProxy;
@@ -28,13 +28,13 @@ public:
btVector3 m_from;
btVector3 m_to;
- float m_hitFraction;
+ btScalar m_hitFraction;
btTriangleRaycastCallback(const btVector3& from,const btVector3& to);
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
- virtual float reportHit(const btVector3& hitNormalLocal, float hitFraction, int partId, int triangleIndex ) = 0;
+ virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0;
};
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
index cf65f46505b..58393b2eab9 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
@@ -18,8 +18,8 @@ subject to the following restrictions:
#ifndef SIMPLEX_SOLVER_INTERFACE_H
#define SIMPLEX_SOLVER_INTERFACE_H
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btPoint3.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btPoint3.h"
#define NO_VIRTUAL_INTERFACE 1
#ifdef NO_VIRTUAL_INTERFACE
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
index dc995ca1f72..687738b7fa9 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
-btSubsimplexConvexCast::btSubsimplexConvexCast (btConvexShape* convexA,btConvexShape* convexB,btSimplexSolverInterface* simplexSolver)
+btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver)
:m_simplexSolver(simplexSolver),
m_convexA(convexA),m_convexB(convexB)
{
@@ -28,8 +28,11 @@ m_convexA(convexA),m_convexB(convexB)
///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
+#ifdef BT_USE_DOUBLE_PRECISION
+#define MAX_ITERATIONS 64
+#else
#define MAX_ITERATIONS 32
-
+#endif
bool btSubsimplexConvexCast::calcTimeOfImpact(
const btTransform& fromA,
const btTransform& toA,
@@ -52,9 +55,9 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
convex->setTransformB(btTransform(rayFromLocalA.getBasis()));
- //float radius = 0.01f;
+ //btScalar radius = btScalar(0.01);
- btScalar lambda = 0.f;
+ btScalar lambda = btScalar(0.);
//todo: need to verify this:
//because of minkowski difference, we need the inverse direction
@@ -69,27 +72,30 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
int maxIter = MAX_ITERATIONS;
btVector3 n;
- n.setValue(0.f,0.f,0.f);
+ n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
bool hasResult = false;
btVector3 c;
- float lastLambda = lambda;
-
+ btScalar lastLambda = lambda;
- float dist2 = v.length2();
- float epsilon = 0.0001f;
+ btScalar dist2 = v.length2();
+#ifdef BT_USE_DOUBLE_PRECISION
+ btScalar epsilon = btScalar(0.0001);
+#else
+ btScalar epsilon = btScalar(0.0001);
+#endif //BT_USE_DOUBLE_PRECISION
btVector3 w,p;
- float VdotR;
+ btScalar VdotR;
while ( (dist2 > epsilon) && maxIter--)
{
p = convex->localGetSupportingVertex( v);
w = x - p;
- float VdotW = v.dot(w);
+ btScalar VdotW = v.dot(w);
- if ( VdotW > 0.f)
+ if ( VdotW > btScalar(0.))
{
VdotR = v.dot(r);
@@ -117,7 +123,7 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
//printf("numverts = %i\n",m_simplexSolver->numVertices());
} else
{
- dist2 = 0.f;
+ dist2 = btScalar(0.);
}
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
index a2a3193b090..05662db5d23 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
@@ -28,12 +28,12 @@ class btConvexShape;
class btSubsimplexConvexCast : public btConvexCast
{
btSimplexSolverInterface* m_simplexSolver;
- btConvexShape* m_convexA;
- btConvexShape* m_convexB;
+ const btConvexShape* m_convexA;
+ const btConvexShape* m_convexB;
public:
- btSubsimplexConvexCast (btConvexShape* shapeA,btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver);
+ btSubsimplexConvexCast (const btConvexShape* shapeA,const btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver);
//virtual ~btSubsimplexConvexCast();
///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects.
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
index 23d66a3bbc8..105b7eccefa 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
@@ -70,7 +70,7 @@ void btVoronoiSimplexSolver::reset()
m_cachedValidClosest = false;
m_numVertices = 0;
m_needsUpdate = true;
- m_lastW = btVector3(1e30f,1e30f,1e30f);
+ m_lastW = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_cachedBC.reset();
}
@@ -109,7 +109,7 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints()
m_cachedP2 = m_simplexPointsQ[0];
m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0]
m_cachedBC.reset();
- m_cachedBC.setBarycentricCoordinates(1.f,0.f,0.f,0.f);
+ m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.));
m_cachedValidClosest = m_cachedBC.isValid();
break;
};
@@ -120,13 +120,13 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints()
const btVector3& to = m_simplexVectorW[1];
btVector3 nearest;
- btVector3 p (0.f,0.f,0.f);
+ btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 diff = p - from;
btVector3 v = to - from;
- float t = v.dot(diff);
+ btScalar t = v.dot(diff);
if (t > 0) {
- float dotVV = v.dot(v);
+ btScalar dotVV = v.dot(v);
if (t < dotVV) {
t /= dotVV;
diff -= t*v;
@@ -156,38 +156,36 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints()
m_cachedValidClosest = m_cachedBC.isValid();
break;
}
- case 3:
- {
- //closest point origin from triangle
- btVector3 p (0.f,0.f,0.f);
-
- const btVector3& a = m_simplexVectorW[0];
- const btVector3& b = m_simplexVectorW[1];
- const btVector3& c = m_simplexVectorW[2];
+ case 3:
+ {
+ //closest point origin from triangle
+ btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.));
- closestPtPointTriangle(p,a,b,c,m_cachedBC);
- m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] +
- m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] +
- m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] +
- m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3];
+ const btVector3& a = m_simplexVectorW[0];
+ const btVector3& b = m_simplexVectorW[1];
+ const btVector3& c = m_simplexVectorW[2];
- m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] +
- m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] +
- m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] +
- m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3];
+ closestPtPointTriangle(p,a,b,c,m_cachedBC);
+ m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2];
- m_cachedV = m_cachedP1-m_cachedP2;
+ m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] +
+ m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] +
+ m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2];
- reduceVertices (m_cachedBC.m_usedVertices);
- m_cachedValidClosest = m_cachedBC.isValid();
+ m_cachedV = m_cachedP1-m_cachedP2;
- break;
+ reduceVertices (m_cachedBC.m_usedVertices);
+ m_cachedValidClosest = m_cachedBC.isValid();
+
+ break;
}
case 4:
{
- btVector3 p (0.f,0.f,0.f);
+ btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.));
const btVector3& a = m_simplexVectorW[0];
const btVector3& b = m_simplexVectorW[1];
@@ -222,7 +220,7 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints()
{
m_cachedValidClosest = true;
//degenerate case == false, penetration = true + zero
- m_cachedV.setValue(0.f,0.f,0.f);
+ m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
break;
}
@@ -256,7 +254,7 @@ bool btVoronoiSimplexSolver::closest(btVector3& v)
btScalar btVoronoiSimplexSolver::maxVertex()
{
int i, numverts = numVertices();
- btScalar maxV = 0.f;
+ btScalar maxV = btScalar(0.);
for (i=0;i<numverts;i++)
{
btScalar curLen2 = m_simplexVectorW[i].length2();
@@ -288,7 +286,7 @@ bool btVoronoiSimplexSolver::inSimplex(const btVector3& w)
{
bool found = false;
int i, numverts = numVertices();
- //btScalar maxV = 0.f;
+ //btScalar maxV = btScalar(0.);
//w is in the current (reduced) simplex
for (i=0;i<numverts;i++)
@@ -335,9 +333,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
btVector3 ab = b - a;
btVector3 ac = c - a;
btVector3 ap = p - a;
- float d1 = ab.dot(ap);
- float d2 = ac.dot(ap);
- if (d1 <= 0.0f && d2 <= 0.0f)
+ btScalar d1 = ab.dot(ap);
+ btScalar d2 = ac.dot(ap);
+ if (d1 <= btScalar(0.0) && d2 <= btScalar(0.0))
{
result.m_closestPointOnSimplex = a;
result.m_usedVertices.usedVertexA = true;
@@ -347,9 +345,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
// Check if P in vertex region outside B
btVector3 bp = p - b;
- float d3 = ab.dot(bp);
- float d4 = ac.dot(bp);
- if (d3 >= 0.0f && d4 <= d3)
+ btScalar d3 = ab.dot(bp);
+ btScalar d4 = ac.dot(bp);
+ if (d3 >= btScalar(0.0) && d4 <= d3)
{
result.m_closestPointOnSimplex = b;
result.m_usedVertices.usedVertexB = true;
@@ -358,9 +356,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
return true; // b; // barycentric coordinates (0,1,0)
}
// Check if P in edge region of AB, if so return projection of P onto AB
- float vc = d1*d4 - d3*d2;
- if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
- float v = d1 / (d1 - d3);
+ btScalar vc = d1*d4 - d3*d2;
+ if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) {
+ btScalar v = d1 / (d1 - d3);
result.m_closestPointOnSimplex = a + v * ab;
result.m_usedVertices.usedVertexA = true;
result.m_usedVertices.usedVertexB = true;
@@ -371,9 +369,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
// Check if P in vertex region outside C
btVector3 cp = p - c;
- float d5 = ab.dot(cp);
- float d6 = ac.dot(cp);
- if (d6 >= 0.0f && d5 <= d6)
+ btScalar d5 = ab.dot(cp);
+ btScalar d6 = ac.dot(cp);
+ if (d6 >= btScalar(0.0) && d5 <= d6)
{
result.m_closestPointOnSimplex = c;
result.m_usedVertices.usedVertexC = true;
@@ -382,9 +380,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
}
// Check if P in edge region of AC, if so return projection of P onto AC
- float vb = d5*d2 - d1*d6;
- if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
- float w = d2 / (d2 - d6);
+ btScalar vb = d5*d2 - d1*d6;
+ if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) {
+ btScalar w = d2 / (d2 - d6);
result.m_closestPointOnSimplex = a + w * ac;
result.m_usedVertices.usedVertexA = true;
result.m_usedVertices.usedVertexC = true;
@@ -394,9 +392,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
}
// Check if P in edge region of BC, if so return projection of P onto BC
- float va = d3*d6 - d5*d4;
- if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
- float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+ btScalar va = d3*d6 - d5*d4;
+ if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) {
+ btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
result.m_closestPointOnSimplex = b + w * (c - b);
result.m_usedVertices.usedVertexB = true;
@@ -407,9 +405,9 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
}
// P inside face region. Compute Q through its barycentric coordinates (u,v,w)
- float denom = 1.0f / (va + vb + vc);
- float v = vb * denom;
- float w = vc * denom;
+ btScalar denom = btScalar(1.0) / (va + vb + vc);
+ btScalar v = vb * denom;
+ btScalar w = vc * denom;
result.m_closestPointOnSimplex = a + ab * v + ac * w;
result.m_usedVertices.usedVertexA = true;
@@ -418,7 +416,7 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
result.setBarycentricCoordinates(1-v-w,v,w);
return true;
-// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = 1.0f - v - w
+// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w
}
@@ -431,18 +429,26 @@ int btVoronoiSimplexSolver::pointOutsideOfPlane(const btPoint3& p, const btPoint
{
btVector3 normal = (b-a).cross(c-a);
- float signp = (p - a).dot(normal); // [AP AB AC]
- float signd = (d - a).dot( normal); // [AD AB AC]
+ btScalar signp = (p - a).dot(normal); // [AP AB AC]
+ btScalar signd = (d - a).dot( normal); // [AD AB AC]
#ifdef CATCH_DEGENERATE_TETRAHEDRON
- if (signd * signd < (1e-4f * 1e-4f))
+#ifdef BT_USE_DOUBLE_PRECISION
+if (signd * signd < (btScalar(1e-8) * btScalar(1e-8)))
+ {
+ return -1;
+ }
+#else
+ if (signd * signd < (btScalar(1e-4) * btScalar(1e-4)))
{
// printf("affine dependent/degenerate\n");//
return -1;
}
#endif
+
+#endif
// Points on opposite sides if expression signs are opposite
- return signp * signd < 0.f;
+ return signp * signd < btScalar(0.);
}
@@ -475,14 +481,14 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
}
- float bestSqDist = FLT_MAX;
+ btScalar bestSqDist = FLT_MAX;
// If point outside face abc then compute closest point on abc
if (pointOutsideABC)
{
closestPtPointTriangle(p, a, b, c,tempResult);
btPoint3 q = tempResult.m_closestPointOnSimplex;
- float sqDist = (q - p).dot( q - p);
+ btScalar sqDist = (q - p).dot( q - p);
// Update best closest point if (squared) distance is less than current best
if (sqDist < bestSqDist) {
bestSqDist = sqDist;
@@ -510,13 +516,14 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
btPoint3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
- float sqDist = (q - p).dot( q - p);
+ btScalar sqDist = (q - p).dot( q - p);
if (sqDist < bestSqDist)
{
bestSqDist = sqDist;
finalResult.m_closestPointOnSimplex = q;
finalResult.m_usedVertices.reset();
finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+
finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB;
finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC;
finalResult.setBarycentricCoordinates(
@@ -537,15 +544,16 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
btPoint3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
- float sqDist = (q - p).dot( q - p);
+ btScalar sqDist = (q - p).dot( q - p);
if (sqDist < bestSqDist)
{
bestSqDist = sqDist;
finalResult.m_closestPointOnSimplex = q;
finalResult.m_usedVertices.reset();
finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
- finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC;
+
+ finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
finalResult.setBarycentricCoordinates(
tempResult.m_barycentricCoords[VERTA],
tempResult.m_barycentricCoords[VERTC],
@@ -563,15 +571,16 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
closestPtPointTriangle(p, b, d, c,tempResult);
btPoint3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
- float sqDist = (q - p).dot( q - p);
+ btScalar sqDist = (q - p).dot( q - p);
if (sqDist < bestSqDist)
{
bestSqDist = sqDist;
finalResult.m_closestPointOnSimplex = q;
finalResult.m_usedVertices.reset();
+ //
finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA;
- finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC;
+ finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
finalResult.setBarycentricCoordinates(
0,
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
index 8b743996915..356d335bc93 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
@@ -55,7 +55,7 @@ struct btSubSimplexClosestResult
//stores the simplex vertex-usage, using the MASK,
// if m_usedVertices & MASK then the related vertex is used
btUsageBitfield m_usedVertices;
- float m_barycentricCoords[4];
+ btScalar m_barycentricCoords[4];
bool m_degenerate;
void reset()
@@ -66,15 +66,15 @@ struct btSubSimplexClosestResult
}
bool isValid()
{
- bool valid = (m_barycentricCoords[0] >= 0.f) &&
- (m_barycentricCoords[1] >= 0.f) &&
- (m_barycentricCoords[2] >= 0.f) &&
- (m_barycentricCoords[3] >= 0.f);
+ bool valid = (m_barycentricCoords[0] >= btScalar(0.)) &&
+ (m_barycentricCoords[1] >= btScalar(0.)) &&
+ (m_barycentricCoords[2] >= btScalar(0.)) &&
+ (m_barycentricCoords[3] >= btScalar(0.));
return valid;
}
- void setBarycentricCoordinates(float a=0.f,float b=0.f,float c=0.f,float d=0.f)
+ void setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.))
{
m_barycentricCoords[0] = a;
m_barycentricCoords[1] = b;
diff --git a/extern/bullet2/src/BulletDynamics/CMakeLists.txt b/extern/bullet2/src/BulletDynamics/CMakeLists.txt
index 79e07b7f77b..8598575799a 100644
--- a/extern/bullet2/src/BulletDynamics/CMakeLists.txt
+++ b/extern/bullet2/src/BulletDynamics/CMakeLists.txt
@@ -13,6 +13,7 @@ ADD_LIBRARY(LibBulletDynamics
ConstraintSolver/btTypedConstraint.cpp
Dynamics/btDiscreteDynamicsWorld.cpp
Dynamics/btSimpleDynamicsWorld.cpp
+ Dynamics/Bullet-C-API.cpp
Dynamics/btRigidBody.cpp
Vehicle/btRaycastVehicle.cpp
Vehicle/btWheelInfo.cpp
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
new file mode 100644
index 00000000000..2289621e8e3
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
@@ -0,0 +1,285 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Written by: Marcus Hennix
+*/
+
+
+#include "btConeTwistConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btSimdMinMax.h"
+#include <new>
+
+btConeTwistConstraint::btConeTwistConstraint()
+{
+}
+
+
+btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,
+ const btTransform& rbAFrame,const btTransform& rbBFrame)
+ :btTypedConstraint(rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame),
+ m_angularOnly(false)
+{
+ // flip axis for correct angles
+ m_rbBFrame.getBasis()[1][0] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[1][1] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
+
+ m_swingSpan1 = btScalar(1e30);
+ m_swingSpan2 = btScalar(1e30);
+ m_twistSpan = btScalar(1e30);
+ m_biasFactor = 0.3f;
+ m_relaxationFactor = 1.0f;
+
+ m_solveTwistLimit = false;
+ m_solveSwingLimit = false;
+
+}
+
+btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)
+ :btTypedConstraint(rbA),m_rbAFrame(rbAFrame),
+ m_angularOnly(false)
+{
+ m_rbBFrame = m_rbAFrame;
+
+ // flip axis for correct angles
+ m_rbBFrame.getBasis()[1][0] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[1][1] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
+
+ m_rbBFrame.getBasis()[2][0] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[2][1] *= btScalar(-1.);
+ m_rbBFrame.getBasis()[2][2] *= btScalar(-1.);
+
+ m_swingSpan1 = btScalar(1e30);
+ m_swingSpan2 = btScalar(1e30);
+ m_twistSpan = btScalar(1e30);
+ m_biasFactor = 0.3f;
+ m_relaxationFactor = 1.0f;
+
+ m_solveTwistLimit = false;
+ m_solveSwingLimit = false;
+
+}
+
+void btConeTwistConstraint::buildJacobian()
+{
+ m_appliedImpulse = btScalar(0.);
+
+ //set bias, sign, clear accumulator
+ m_swingCorrection = btScalar(0.);
+ m_twistLimitSign = btScalar(0.);
+ m_solveTwistLimit = false;
+ m_solveSwingLimit = false;
+ m_accTwistLimitImpulse = btScalar(0.);
+ m_accSwingLimitImpulse = btScalar(0.);
+
+ if (!m_angularOnly)
+ {
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+ btVector3 relPos = pivotBInW - pivotAInW;
+
+ btVector3 normal[3];
+ if (relPos.length2() > SIMD_EPSILON)
+ {
+ normal[0] = relPos.normalized();
+ }
+ else
+ {
+ normal[0].setValue(btScalar(1.0),0,0);
+ }
+
+ btPlaneSpace1(normal[0], normal[1], normal[2]);
+
+ for (int i=0;i<3;i++)
+ {
+ new (&m_jac[i]) btJacobianEntry(
+ m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+ pivotAInW - m_rbA.getCenterOfMassPosition(),
+ pivotBInW - m_rbB.getCenterOfMassPosition(),
+ normal[i],
+ m_rbA.getInvInertiaDiagLocal(),
+ m_rbA.getInvMass(),
+ m_rbB.getInvInertiaDiagLocal(),
+ m_rbB.getInvMass());
+ }
+ }
+
+ btVector3 b1Axis1,b1Axis2,b1Axis3;
+ btVector3 b2Axis1,b2Axis2;
+
+ b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0);
+ b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0);
+
+ btScalar swing1=btScalar(0.),swing2 = btScalar(0.);
+
+ // Get Frame into world space
+ if (m_swingSpan1 >= btScalar(0.05f))
+ {
+ b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1);
+ swing1 = btAtan2Fast( b2Axis1.dot(b1Axis2),b2Axis1.dot(b1Axis1) );
+ }
+
+ if (m_swingSpan2 >= btScalar(0.05f))
+ {
+ b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2);
+ swing2 = btAtan2Fast( b2Axis1.dot(b1Axis3),b2Axis1.dot(b1Axis1) );
+ }
+
+ btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1);
+ btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2);
+ btScalar EllipseAngle = btFabs(swing1)* RMaxAngle1Sq + btFabs(swing2) * RMaxAngle2Sq;
+
+ if (EllipseAngle > 1.0f)
+ {
+ m_swingCorrection = EllipseAngle-1.0f;
+ m_solveSwingLimit = true;
+
+ // Calculate necessary axis & factors
+ m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3));
+ m_swingAxis.normalize();
+
+ btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f;
+ m_swingAxis *= swingAxisSign;
+
+ m_kSwing = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis));
+
+ }
+
+ // Twist limits
+ if (m_twistSpan >= btScalar(0.))
+ {
+ btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1);
+ btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1);
+ btVector3 TwistRef = quatRotate(rotationArc,b2Axis2);
+ btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) );
+
+ btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.);
+ if (twist <= -m_twistSpan*lockedFreeFactor)
+ {
+ m_twistCorrection = -(twist + m_twistSpan);
+ m_solveTwistLimit = true;
+
+ m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
+ m_twistAxis.normalize();
+ m_twistAxis *= -1.0f;
+
+ m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+
+ } else
+ if (twist > m_twistSpan*lockedFreeFactor)
+ {
+ m_twistCorrection = (twist - m_twistSpan);
+ m_solveTwistLimit = true;
+
+ m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
+ m_twistAxis.normalize();
+
+ m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+
+ }
+ }
+}
+
+void btConeTwistConstraint::solveConstraint(btScalar timeStep)
+{
+
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+
+ btScalar tau = btScalar(0.3);
+
+ //linear part
+ if (!m_angularOnly)
+ {
+ btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+
+ btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
+ btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
+ btVector3 vel = vel1 - vel2;
+
+ for (int i=0;i<3;i++)
+ {
+ const btVector3& normal = m_jac[i].m_linearJointAxis;
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
+
+ btScalar rel_vel;
+ rel_vel = normal.dot(vel);
+ //positional error (zeroth order error)
+ btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
+ btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
+ m_appliedImpulse += impulse;
+ btVector3 impulse_vector = normal * impulse;
+ m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition());
+ m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition());
+ }
+ }
+
+ {
+ ///solve angular part
+ const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
+ const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+
+ // solve swing limit
+ if (m_solveSwingLimit)
+ {
+ btScalar amplitude = ((angVelB - angVelA).dot( m_swingAxis )*m_relaxationFactor*m_relaxationFactor + m_swingCorrection*(btScalar(1.)/timeStep)*m_biasFactor);
+ btScalar impulseMag = amplitude * m_kSwing;
+
+ // Clamp the accumulated impulse
+ btScalar temp = m_accSwingLimitImpulse;
+ m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, 0.0f );
+ impulseMag = m_accSwingLimitImpulse - temp;
+
+ btVector3 impulse = m_swingAxis * impulseMag;
+
+ m_rbA.applyTorqueImpulse(impulse);
+ m_rbB.applyTorqueImpulse(-impulse);
+
+ }
+
+ // solve twist limit
+ if (m_solveTwistLimit)
+ {
+ btScalar amplitude = ((angVelB - angVelA).dot( m_twistAxis )*m_relaxationFactor*m_relaxationFactor + m_twistCorrection*(btScalar(1.)/timeStep)*m_biasFactor );
+ btScalar impulseMag = amplitude * m_kTwist;
+
+ // Clamp the accumulated impulse
+ btScalar temp = m_accTwistLimitImpulse;
+ m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, 0.0f );
+ impulseMag = m_accTwistLimitImpulse - temp;
+
+ btVector3 impulse = m_twistAxis * impulseMag;
+
+ m_rbA.applyTorqueImpulse(impulse);
+ m_rbB.applyTorqueImpulse(-impulse);
+
+ }
+
+ }
+
+}
+
+void btConeTwistConstraint::updateRHS(btScalar timeStep)
+{
+ (void)timeStep;
+
+}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
new file mode 100644
index 00000000000..874669c80b3
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
@@ -0,0 +1,123 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Written by: Marcus Hennix
+*/
+
+
+
+#ifndef CONETWISTCONSTRAINT_H
+#define CONETWISTCONSTRAINT_H
+
+#include "../../LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+
+class btRigidBody;
+
+
+///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
+class btConeTwistConstraint : public btTypedConstraint
+{
+ btJacobianEntry m_jac[3]; //3 orthogonal linear constraints
+
+ btTransform m_rbAFrame;
+ btTransform m_rbBFrame;
+
+ btScalar m_limitSoftness;
+ btScalar m_biasFactor;
+ btScalar m_relaxationFactor;
+
+ btScalar m_swingSpan1;
+ btScalar m_swingSpan2;
+ btScalar m_twistSpan;
+
+ btVector3 m_swingAxis;
+ btVector3 m_twistAxis;
+
+ btScalar m_kSwing;
+ btScalar m_kTwist;
+
+ btScalar m_twistLimitSign;
+ btScalar m_swingCorrection;
+ btScalar m_twistCorrection;
+
+ btScalar m_accSwingLimitImpulse;
+ btScalar m_accTwistLimitImpulse;
+
+ bool m_angularOnly;
+ bool m_solveTwistLimit;
+ bool m_solveSwingLimit;
+
+
+public:
+
+ btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
+
+ btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
+
+ btConeTwistConstraint();
+
+ virtual void buildJacobian();
+
+ virtual void solveConstraint(btScalar timeStep);
+
+ void updateRHS(btScalar timeStep);
+
+ const btRigidBody& getRigidBodyA() const
+ {
+ return m_rbA;
+ }
+ const btRigidBody& getRigidBodyB() const
+ {
+ return m_rbB;
+ }
+
+ void setAngularOnly(bool angularOnly)
+ {
+ m_angularOnly = angularOnly;
+ }
+
+ void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 0.8f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
+ {
+ m_swingSpan1 = _swingSpan1;
+ m_swingSpan2 = _swingSpan2;
+ m_twistSpan = _twistSpan;
+
+ m_limitSoftness = _softness;
+ m_biasFactor = _biasFactor;
+ m_relaxationFactor = _relaxationFactor;
+ }
+
+ const btTransform& getAFrame() { return m_rbAFrame; };
+ const btTransform& getBFrame() { return m_rbBFrame; };
+
+ inline int getSolveTwistLimit()
+ {
+ return m_solveTwistLimit;
+ }
+
+ inline int getSolveSwingLimit()
+ {
+ return m_solveTwistLimit;
+ }
+
+ inline btScalar getTwistLimitSign()
+ {
+ return m_twistLimitSign;
+ }
+
+};
+
+#endif //CONETWISTCONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
index ce90f798c04..7e8458c2c7b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
@@ -16,12 +16,16 @@ subject to the following restrictions:
#ifndef CONSTRAINT_SOLVER_H
#define CONSTRAINT_SOLVER_H
+#include "../../LinearMath/btScalar.h"
+
class btPersistentManifold;
class btRigidBody;
+class btCollisionObject;
class btTypedConstraint;
struct btContactSolverInfo;
struct btBroadphaseProxy;
class btIDebugDraw;
+class btStackAlloc;
/// btConstraintSolver provides solver interface
class btConstraintSolver
@@ -31,7 +35,7 @@ public:
virtual ~btConstraintSolver() {}
- virtual float solveGroup(btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer = 0) = 0;
+ virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc) = 0;
};
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
index 1b85a0eea42..bb3fe832592 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
@@ -30,13 +30,17 @@ subject to the following restrictions:
//bilateral constraint between two dynamic objects
void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
btRigidBody& body2, const btVector3& pos2,
- btScalar distance, const btVector3& normal,btScalar& impulse ,float timeStep)
+ btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep)
{
- float normalLenSqr = normal.length2();
- ASSERT2(fabs(normalLenSqr) < 1.1f);
- if (normalLenSqr > 1.1f)
+ (void)timeStep;
+ (void)distance;
+
+
+ btScalar normalLenSqr = normal.length2();
+ ASSERT2(btFabs(normalLenSqr) < btScalar(1.1));
+ if (normalLenSqr > btScalar(1.1))
{
- impulse = 0.f;
+ impulse = btScalar(0.);
return;
}
btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
@@ -54,24 +58,24 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
body2.getInvInertiaDiagLocal(),body2.getInvMass());
btScalar jacDiagAB = jac.getDiagonal();
- btScalar jacDiagABInv = 1.f / jacDiagAB;
+ btScalar jacDiagABInv = btScalar(1.) / jacDiagAB;
btScalar rel_vel = jac.getRelativeVelocity(
body1.getLinearVelocity(),
body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(),
body2.getLinearVelocity(),
body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity());
- float a;
+ btScalar a;
a=jacDiagABInv;
rel_vel = normal.dot(vel);
//todo: move this into proper structure
- btScalar contactDamping = 0.2f;
+ btScalar contactDamping = btScalar(0.2);
#ifdef ONLY_USE_LINEAR_MASS
- btScalar massTerm = 1.f / (body1.getInvMass() + body2.getInvMass());
+ btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass());
impulse = - contactDamping * rel_vel * massTerm;
#else
btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv;
@@ -82,19 +86,20 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
//response between two dynamic objects with friction
-float resolveSingleCollision(
+btScalar resolveSingleCollision(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
const btContactSolverInfo& solverInfo)
{
- const btVector3& pos1 = contactPoint.getPositionWorldOnA();
- const btVector3& pos2 = contactPoint.getPositionWorldOnB();
+ const btVector3& pos1_ = contactPoint.getPositionWorldOnA();
+ const btVector3& pos2_ = contactPoint.getPositionWorldOnB();
const btVector3& normal = contactPoint.m_normalWorldOnB;
- btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition();
- btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+ //constant over all iterations
+ btVector3 rel_pos1 = pos1_ - body1.getCenterOfMassPosition();
+ btVector3 rel_pos2 = pos2_ - body2.getCenterOfMassPosition();
btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
@@ -102,11 +107,11 @@ float resolveSingleCollision(
btScalar rel_vel;
rel_vel = normal.dot(vel);
- btScalar Kfps = 1.f / solverInfo.m_timeStep ;
+ btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ;
- // float damping = solverInfo.m_damping ;
- float Kerp = solverInfo.m_erp;
- float Kcor = Kerp *Kfps;
+ // btScalar damping = solverInfo.m_damping ;
+ btScalar Kerp = solverInfo.m_erp;
+ btScalar Kcor = Kerp *Kfps;
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
assert(cpd);
@@ -121,9 +126,9 @@ float resolveSingleCollision(
btScalar normalImpulse = penetrationImpulse+velocityImpulse;
// See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
- float oldNormalImpulse = cpd->m_appliedImpulse;
- float sum = oldNormalImpulse + normalImpulse;
- cpd->m_appliedImpulse = 0.f > sum ? 0.f: sum;
+ btScalar oldNormalImpulse = cpd->m_appliedImpulse;
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse;
@@ -145,13 +150,15 @@ float resolveSingleCollision(
}
-float resolveSingleFriction(
+btScalar resolveSingleFriction(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
const btContactSolverInfo& solverInfo)
{
+ (void)solverInfo;
+
const btVector3& pos1 = contactPoint.getPositionWorldOnA();
const btVector3& pos2 = contactPoint.getPositionWorldOnB();
@@ -161,11 +168,11 @@ float resolveSingleFriction(
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
assert(cpd);
- float combinedFriction = cpd->m_friction;
+ btScalar combinedFriction = cpd->m_friction;
btScalar limit = cpd->m_appliedImpulse * combinedFriction;
- if (cpd->m_appliedImpulse>0.f)
+ if (cpd->m_appliedImpulse>btScalar(0.))
//friction
{
//apply friction in the 2 tangential directions
@@ -183,7 +190,7 @@ float resolveSingleFriction(
// calculate j that moves us to zero relative velocity
j1 = -vrel * cpd->m_jacDiagABInvTangent0;
- float oldTangentImpulse = cpd->m_accumulatedTangentImpulse0;
+ btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse0;
cpd->m_accumulatedTangentImpulse0 = oldTangentImpulse + j1;
GEN_set_min(cpd->m_accumulatedTangentImpulse0, limit);
GEN_set_max(cpd->m_accumulatedTangentImpulse0, -limit);
@@ -197,7 +204,7 @@ float resolveSingleFriction(
// calculate j that moves us to zero relative velocity
j2 = -vrel * cpd->m_jacDiagABInvTangent1;
- float oldTangentImpulse = cpd->m_accumulatedTangentImpulse1;
+ btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse1;
cpd->m_accumulatedTangentImpulse1 = oldTangentImpulse + j2;
GEN_set_min(cpd->m_accumulatedTangentImpulse1, limit);
GEN_set_max(cpd->m_accumulatedTangentImpulse1, -limit);
@@ -226,13 +233,15 @@ float resolveSingleFriction(
}
-float resolveSingleFrictionOriginal(
+btScalar resolveSingleFrictionOriginal(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
const btContactSolverInfo& solverInfo)
{
+ (void)solverInfo;
+
const btVector3& pos1 = contactPoint.getPositionWorldOnA();
const btVector3& pos2 = contactPoint.getPositionWorldOnB();
@@ -242,10 +251,10 @@ float resolveSingleFrictionOriginal(
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
assert(cpd);
- float combinedFriction = cpd->m_friction;
+ btScalar combinedFriction = cpd->m_friction;
btScalar limit = cpd->m_appliedImpulse * combinedFriction;
- //if (contactPoint.m_appliedImpulse>0.f)
+ //if (contactPoint.m_appliedImpulse>btScalar(0.))
//friction
{
//apply friction in the 2 tangential directions
@@ -260,7 +269,7 @@ float resolveSingleFrictionOriginal(
// calculate j that moves us to zero relative velocity
btScalar j = -vrel * cpd->m_jacDiagABInvTangent0;
- float total = cpd->m_accumulatedTangentImpulse0 + j;
+ btScalar total = cpd->m_accumulatedTangentImpulse0 + j;
GEN_set_min(total, limit);
GEN_set_max(total, -limit);
j = total - cpd->m_accumulatedTangentImpulse0;
@@ -280,7 +289,7 @@ float resolveSingleFrictionOriginal(
// calculate j that moves us to zero relative velocity
btScalar j = -vrel * cpd->m_jacDiagABInvTangent1;
- float total = cpd->m_accumulatedTangentImpulse1 + j;
+ btScalar total = cpd->m_accumulatedTangentImpulse1 + j;
GEN_set_min(total, limit);
GEN_set_max(total, -limit);
j = total - cpd->m_accumulatedTangentImpulse1;
@@ -295,7 +304,7 @@ float resolveSingleFrictionOriginal(
//velocity + friction
//response between two dynamic objects with friction
-float resolveSingleCollisionCombined(
+btScalar resolveSingleCollisionCombined(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
@@ -315,11 +324,11 @@ float resolveSingleCollisionCombined(
btScalar rel_vel;
rel_vel = normal.dot(vel);
- btScalar Kfps = 1.f / solverInfo.m_timeStep ;
+ btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ;
- //float damping = solverInfo.m_damping ;
- float Kerp = solverInfo.m_erp;
- float Kcor = Kerp *Kfps;
+ //btScalar damping = solverInfo.m_damping ;
+ btScalar Kerp = solverInfo.m_erp;
+ btScalar Kcor = Kerp *Kfps;
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
assert(cpd);
@@ -334,9 +343,9 @@ float resolveSingleCollisionCombined(
btScalar normalImpulse = penetrationImpulse+velocityImpulse;
// See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
- float oldNormalImpulse = cpd->m_appliedImpulse;
- float sum = oldNormalImpulse + normalImpulse;
- cpd->m_appliedImpulse = 0.f > sum ? 0.f: sum;
+ btScalar oldNormalImpulse = cpd->m_appliedImpulse;
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse;
@@ -367,7 +376,7 @@ float resolveSingleCollisionCombined(
btVector3 lat_vel = vel - normal * rel_vel;
btScalar lat_rel_vel = lat_vel.length();
- float combinedFriction = cpd->m_friction;
+ btScalar combinedFriction = cpd->m_friction;
if (cpd->m_appliedImpulse > 0)
if (lat_rel_vel > SIMD_EPSILON)
@@ -390,12 +399,19 @@ float resolveSingleCollisionCombined(
return normalImpulse;
}
-float resolveSingleFrictionEmpty(
+
+btScalar resolveSingleFrictionEmpty(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
const btContactSolverInfo& solverInfo)
{
- return 0.f;
+ (void)contactPoint;
+ (void)body1;
+ (void)body2;
+ (void)solverInfo;
+
+
+ return btScalar(0.);
};
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
index d88ba0d8ed4..0834deddeac 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
@@ -19,8 +19,8 @@ subject to the following restrictions:
//todo: make into a proper class working with the iterative constraint solver
class btRigidBody;
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btScalar.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btScalar.h"
struct btContactSolverInfo;
class btManifoldPoint;
@@ -33,7 +33,7 @@ enum {
};
-typedef float (*ContactSolverFunc)(btRigidBody& body1,
+typedef btScalar (*ContactSolverFunc)(btRigidBody& body1,
btRigidBody& body2,
class btManifoldPoint& contactPoint,
const btContactSolverInfo& info);
@@ -42,15 +42,15 @@ typedef float (*ContactSolverFunc)(btRigidBody& body1,
struct btConstraintPersistentData
{
inline btConstraintPersistentData()
- :m_appliedImpulse(0.f),
- m_prevAppliedImpulse(0.f),
- m_accumulatedTangentImpulse0(0.f),
- m_accumulatedTangentImpulse1(0.f),
- m_jacDiagABInv(0.f),
+ :m_appliedImpulse(btScalar(0.)),
+ m_prevAppliedImpulse(btScalar(0.)),
+ m_accumulatedTangentImpulse0(btScalar(0.)),
+ m_accumulatedTangentImpulse1(btScalar(0.)),
+ m_jacDiagABInv(btScalar(0.)),
m_persistentLifeTime(0),
- m_restitution(0.f),
- m_friction(0.f),
- m_penetration(0.f),
+ m_restitution(btScalar(0.)),
+ m_friction(btScalar(0.)),
+ m_penetration(btScalar(0.)),
m_contactSolverFunc(0),
m_frictionSolverFunc(0)
{
@@ -58,18 +58,18 @@ struct btConstraintPersistentData
/// total applied impulse during most recent frame
- float m_appliedImpulse;
- float m_prevAppliedImpulse;
- float m_accumulatedTangentImpulse0;
- float m_accumulatedTangentImpulse1;
+ btScalar m_appliedImpulse;
+ btScalar m_prevAppliedImpulse;
+ btScalar m_accumulatedTangentImpulse0;
+ btScalar m_accumulatedTangentImpulse1;
- float m_jacDiagABInv;
- float m_jacDiagABInvTangent0;
- float m_jacDiagABInvTangent1;
+ btScalar m_jacDiagABInv;
+ btScalar m_jacDiagABInvTangent0;
+ btScalar m_jacDiagABInvTangent1;
int m_persistentLifeTime;
- float m_restitution;
- float m_friction;
- float m_penetration;
+ btScalar m_restitution;
+ btScalar m_friction;
+ btScalar m_penetration;
btVector3 m_frictionWorldTangential0;
btVector3 m_frictionWorldTangential1;
@@ -91,19 +91,28 @@ struct btConstraintPersistentData
///positive distance = separation, negative distance = penetration
void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
btRigidBody& body2, const btVector3& pos2,
- btScalar distance, const btVector3& normal,btScalar& impulse ,float timeStep);
+ btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep);
///contact constraint resolution:
///calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint
///positive distance = separation, negative distance = penetration
-float resolveSingleCollision(
+btScalar resolveSingleCollision(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
const btContactSolverInfo& info);
-float resolveSingleFriction(
+btScalar resolveSingleFriction(
+ btRigidBody& body1,
+ btRigidBody& body2,
+ btManifoldPoint& contactPoint,
+ const btContactSolverInfo& solverInfo
+ );
+
+
+
+btScalar resolveSingleCollisionCombined(
btRigidBody& body1,
btRigidBody& body2,
btManifoldPoint& contactPoint,
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
index ed1ba6ac1ba..c3c73e300f4 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
@@ -22,25 +22,25 @@ struct btContactSolverInfo
inline btContactSolverInfo()
{
- m_tau = 0.6f;
- m_damping = 1.0f;
- m_friction = 0.3f;
- m_restitution = 0.f;
- m_maxErrorReduction = 20.f;
+ m_tau = btScalar(0.6);
+ m_damping = btScalar(1.0);
+ m_friction = btScalar(0.3);
+ m_restitution = btScalar(0.);
+ m_maxErrorReduction = btScalar(20.);
m_numIterations = 10;
- m_erp = 0.4f;
- m_sor = 1.3f;
+ m_erp = btScalar(0.4);
+ m_sor = btScalar(1.3);
}
- float m_tau;
- float m_damping;
- float m_friction;
- float m_timeStep;
- float m_restitution;
+ btScalar m_tau;
+ btScalar m_damping;
+ btScalar m_friction;
+ btScalar m_timeStep;
+ btScalar m_restitution;
int m_numIterations;
- float m_maxErrorReduction;
- float m_sor;
- float m_erp;
+ btScalar m_maxErrorReduction;
+ btScalar m_sor;
+ btScalar m_erp;
};
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
index b2132a8d4f3..747d10d1f8b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
@@ -17,8 +17,9 @@ subject to the following restrictions:
#include "btGeneric6DofConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btTransformUtil.h"
+#include <new>
-static const btScalar kSign[] = { 1.0f, -1.0f, 1.0f };
+static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) };
static const int kAxisA[] = { 1, 0, 0 };
static const int kAxisB[] = { 2, 2, 1 };
#define GENERIC_D6_DISABLE_WARMSTARTING 1
@@ -38,9 +39,9 @@ btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody&
//so start all locked
for (int i=0; i<6;++i)
{
- m_lowerLimit[i] = 0.0f;
- m_upperLimit[i] = 0.0f;
- m_accumulatedImpulse[i] = 0.0f;
+ m_lowerLimit[i] = btScalar(0.0);
+ m_upperLimit[i] = btScalar(0.0);
+ m_accumulatedImpulse[i] = btScalar(0.0);
}
}
@@ -83,7 +84,7 @@ void btGeneric6DofConstraint::buildJacobian()
//optionally disable warmstarting
#ifdef GENERIC_D6_DISABLE_WARMSTARTING
- m_accumulatedImpulse[i] = 0.f;
+ m_accumulatedImpulse[i] = btScalar(0.);
#endif //GENERIC_D6_DISABLE_WARMSTARTING
// Apply accumulated impulse
@@ -115,7 +116,7 @@ void btGeneric6DofConstraint::buildJacobian()
m_rbB.getInvInertiaDiagLocal());
#ifdef GENERIC_D6_DISABLE_WARMSTARTING
- m_accumulatedImpulse[i + 3] = 0.f;
+ m_accumulatedImpulse[i + 3] = btScalar(0.);
#endif //GENERIC_D6_DISABLE_WARMSTARTING
// Apply accumulated impulse
@@ -127,7 +128,7 @@ void btGeneric6DofConstraint::buildJacobian()
}
}
-float getMatrixElem(const btMatrix3x3& mat,int index)
+btScalar getMatrixElem(const btMatrix3x3& mat,int index)
{
int row = index%3;
int col = index / 3;
@@ -143,9 +144,9 @@ bool MatrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz)
/// 0..8
- if (getMatrixElem(mat,2) < 1.0f)
+ if (getMatrixElem(mat,2) < btScalar(1.0))
{
- if (getMatrixElem(mat,2) > -1.0f)
+ if (getMatrixElem(mat,2) > btScalar(-1.0))
{
xyz[0] = btAtan2(-getMatrixElem(mat,5),getMatrixElem(mat,8));
xyz[1] = btAsin(getMatrixElem(mat,2));
@@ -157,7 +158,7 @@ bool MatrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz)
// WARNING. Not unique. XA - ZA = -atan2(r10,r11)
xyz[0] = -btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4));
xyz[1] = -SIMD_HALF_PI;
- xyz[2] = 0.0f;
+ xyz[2] = btScalar(0.0);
return false;
}
}
@@ -167,16 +168,17 @@ bool MatrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz)
xyz[0] = btAtan2(getMatrixElem(mat,3),getMatrixElem(mat,4));
xyz[1] = SIMD_HALF_PI;
xyz[2] = 0.0;
- return false;
+
}
- return false;
+
+ return false;
}
void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
{
- btScalar tau = 0.1f;
- btScalar damping = 1.0f;
+ btScalar tau = btScalar(0.1);
+ btScalar damping = btScalar(1.0);
btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_frameInA.getOrigin();
btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_frameInB.getOrigin();
@@ -199,7 +201,7 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
localNormalInA[i] = 1;
btVector3 normalWorld = m_rbA.getCenterOfMassTransform().getBasis() * localNormalInA;
- btScalar jacDiagABInv = 1.f / m_jacLinear[i].getDiagonal();
+ btScalar jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal();
//velocity error (first order error)
btScalar rel_vel = m_jacLinear[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
@@ -207,8 +209,8 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
//positional error (zeroth order error)
btScalar depth = -(pivotAInW - pivotBInW).dot(normalWorld);
- btScalar lo = -1e30f;
- btScalar hi = 1e30f;
+ btScalar lo = btScalar(-1e30);
+ btScalar hi = btScalar(1e30);
//handle the limits
if (m_lowerLimit[i] < m_upperLimit[i])
@@ -217,14 +219,14 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
if (depth > m_upperLimit[i])
{
depth -= m_upperLimit[i];
- lo = 0.f;
+ lo = btScalar(0.);
} else
{
if (depth < m_lowerLimit[i])
{
depth -= m_lowerLimit[i];
- hi = 0.f;
+ hi = btScalar(0.);
} else
{
continue;
@@ -234,9 +236,9 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
}
btScalar normalImpulse= (tau*depth/timeStep - damping*rel_vel) * jacDiagABInv;
- float oldNormalImpulse = m_accumulatedImpulse[i];
- float sum = oldNormalImpulse + normalImpulse;
- m_accumulatedImpulse[i] = sum > hi ? 0.f : sum < lo ? 0.f : sum;
+ btScalar oldNormalImpulse = m_accumulatedImpulse[i];
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ m_accumulatedImpulse[i] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
normalImpulse = m_accumulatedImpulse[i] - oldNormalImpulse;
btVector3 impulse_vector = normalWorld * normalImpulse;
@@ -267,7 +269,7 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity();
btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity();
- btScalar jacDiagABInv = 1.f / m_jacAng[i].getDiagonal();
+ btScalar jacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal();
//velocity error (first order error)
btScalar rel_vel = m_jacAng[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
@@ -279,27 +281,27 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
btScalar rel_pos = kSign[i] * axisA.dot(axisB);
- btScalar lo = -1e30f;
- btScalar hi = 1e30f;
+ btScalar lo = btScalar(-1e30);
+ btScalar hi = btScalar(1e30);
//handle the twist limit
if (m_lowerLimit[i+3] < m_upperLimit[i+3])
{
//clamp the values
- btScalar loLimit = m_upperLimit[i+3] > -3.1415 ? m_lowerLimit[i+3] : -1e30f;
- btScalar hiLimit = m_upperLimit[i+3] < 3.1415 ? m_upperLimit[i+3] : 1e30f;
+ btScalar loLimit = m_lowerLimit[i+3] > -3.1415 ? m_lowerLimit[i+3] : btScalar(-1e30);
+ btScalar hiLimit = m_upperLimit[i+3] < 3.1415 ? m_upperLimit[i+3] : btScalar(1e30);
- float projAngle = -2.f*xyz[i];
+ btScalar projAngle = btScalar(-1.)*xyz[i];
if (projAngle < loLimit)
{
- hi = 0.f;
+ hi = btScalar(0.);
rel_pos = (loLimit - projAngle);
} else
{
if (projAngle > hiLimit)
{
- lo = 0.f;
+ lo = btScalar(0.);
rel_pos = (hiLimit - projAngle);
} else
{
@@ -311,9 +313,9 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
//impulse
btScalar normalImpulse= -(tau*rel_pos/timeStep + damping*rel_vel) * jacDiagABInv;
- float oldNormalImpulse = m_accumulatedImpulse[i+3];
- float sum = oldNormalImpulse + normalImpulse;
- m_accumulatedImpulse[i+3] = sum > hi ? 0.f : sum < lo ? 0.f : sum;
+ btScalar oldNormalImpulse = m_accumulatedImpulse[i+3];
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ m_accumulatedImpulse[i+3] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
normalImpulse = m_accumulatedImpulse[i+3] - oldNormalImpulse;
// Dirk: Not needed - we could actually project onto Jacobian entry here (same as above)
@@ -328,12 +330,13 @@ void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
void btGeneric6DofConstraint::updateRHS(btScalar timeStep)
{
+ (void)timeStep;
}
btScalar btGeneric6DofConstraint::computeAngle(int axis) const
{
- btScalar angle;
+ btScalar angle = btScalar(0.f);
switch (axis)
{
@@ -375,9 +378,12 @@ btScalar btGeneric6DofConstraint::computeAngle(int axis) const
angle = btAtan2( s, c );
}
break;
- default: assert ( 0 ) ; break ;
+ default:
+ btAssert ( 0 ) ;
+
+ break ;
}
- return angle;
+ return angle;
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
index 329048b5737..b114e54fa69 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef GENERIC_6DOF_CONSTRAINT_H
#define GENERIC_6DOF_CONSTRAINT_H
-#include "LinearMath/btVector3.h"
-
-#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h"
+#include "../../LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
#include "btTypedConstraint.h"
class btRigidBody;
@@ -41,12 +40,19 @@ class btGeneric6DofConstraint : public btTypedConstraint
btScalar m_accumulatedImpulse[6];
+ btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other)
+ {
+ btAssert(0);
+ (void) other;
+ return *this;
+ }
public:
btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB );
btGeneric6DofConstraint();
+
virtual void buildJacobian();
virtual void solveConstraint(btScalar timeStep);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
index f72278e2cbf..27e30987549 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
@@ -17,7 +17,7 @@ subject to the following restrictions:
#include "btHingeConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btTransformUtil.h"
-
+#include <new>
btHingeConstraint::btHingeConstraint():
m_enableAngularMotor(false)
@@ -49,7 +49,7 @@ m_enableAngularMotor(false)
void btHingeConstraint::buildJacobian()
{
- m_appliedImpulse = 0.f;
+ m_appliedImpulse = btScalar(0.);
btVector3 normal(0,0,0);
@@ -115,8 +115,8 @@ void btHingeConstraint::solveConstraint(btScalar timeStep)
btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB;
btVector3 normal(0,0,0);
- btScalar tau = 0.3f;
- btScalar damping = 1.f;
+ btScalar tau = btScalar(0.3);
+ btScalar damping = btScalar(1.);
//linear part
if (!m_angularOnly)
@@ -124,7 +124,7 @@ void btHingeConstraint::solveConstraint(btScalar timeStep)
for (int i=0;i<3;i++)
{
normal[i] = 1;
- btScalar jacDiagABInv = 1.f / m_jac[i].getDiagonal();
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
@@ -165,27 +165,27 @@ void btHingeConstraint::solveConstraint(btScalar timeStep)
btVector3 velrelOrthog = angAorthog-angBorthog;
{
//solve orthogonal angular velocity correction
- float relaxation = 1.f;
- float len = velrelOrthog.length();
- if (len > 0.00001f)
+ btScalar relaxation = btScalar(1.);
+ btScalar len = velrelOrthog.length();
+ if (len > btScalar(0.00001))
{
btVector3 normal = velrelOrthog.normalized();
- float denom = getRigidBodyA().computeAngularImpulseDenominator(normal) +
+ btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) +
getRigidBodyB().computeAngularImpulseDenominator(normal);
// scale for mass and relaxation
//todo: expose this 0.9 factor to developer
- velrelOrthog *= (1.f/denom) * 0.9f;
+ velrelOrthog *= (btScalar(1.)/denom) * btScalar(0.9);
}
//solve angular positional correction
- btVector3 angularError = -axisA.cross(axisB) *(1.f/timeStep);
- float len2 = angularError.length();
- if (len2>0.00001f)
+ btVector3 angularError = -axisA.cross(axisB) *(btScalar(1.)/timeStep);
+ btScalar len2 = angularError.length();
+ if (len2>btScalar(0.00001))
{
btVector3 normal2 = angularError.normalized();
- float denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) +
+ btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) +
getRigidBodyB().computeAngularImpulseDenominator(normal2);
- angularError *= (1.f/denom2) * relaxation;
+ angularError *= (btScalar(1.)/denom2) * relaxation;
}
m_rbA.applyTorqueImpulse(-velrelOrthog+angularError);
@@ -204,10 +204,10 @@ void btHingeConstraint::solveConstraint(btScalar timeStep)
btScalar desiredMotorVel = m_motorTargetVelocity;
btScalar motor_relvel = desiredMotorVel - projRelVel;
- float denom3 = getRigidBodyA().computeAngularImpulseDenominator(axisA) +
+ btScalar denom3 = getRigidBodyA().computeAngularImpulseDenominator(axisA) +
getRigidBodyB().computeAngularImpulseDenominator(axisA);
- btScalar unclippedMotorImpulse = (1.f/denom3) * motor_relvel;;
+ btScalar unclippedMotorImpulse = (btScalar(1.)/denom3) * motor_relvel;;
//todo: should clip against accumulated impulse
btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse;
clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse;
@@ -223,6 +223,7 @@ void btHingeConstraint::solveConstraint(btScalar timeStep)
void btHingeConstraint::updateRHS(btScalar timeStep)
{
+ (void)timeStep;
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
index 553ec135c8a..5c1ceafbc5b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef HINGECONSTRAINT_H
#define HINGECONSTRAINT_H
-#include "LinearMath/btVector3.h"
-
-#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h"
+#include "../../LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
#include "btTypedConstraint.h"
class btRigidBody;
@@ -38,8 +37,8 @@ class btHingeConstraint : public btTypedConstraint
bool m_angularOnly;
- float m_motorTargetVelocity;
- float m_maxMotorImpulse;
+ btScalar m_motorTargetVelocity;
+ btScalar m_maxMotorImpulse;
bool m_enableAngularMotor;
public:
@@ -70,7 +69,7 @@ public:
m_angularOnly = angularOnly;
}
- void enableAngularMotor(bool enableMotor,float targetVelocity,float maxMotorImpulse)
+ void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
{
m_enableAngularMotor = enableMotor;
m_motorTargetVelocity = targetVelocity;
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
index 384e4f7bab5..aae3ed0373f 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef JACOBIAN_ENTRY_H
#define JACOBIAN_ENTRY_H
-#include "LinearMath/btVector3.h"
-#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "../../LinearMath/btVector3.h"
+#include "../Dynamics/btRigidBody.h"
//notes:
@@ -50,7 +50,7 @@ public:
m_1MinvJt = inertiaInvB * m_bJ;
m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ);
- btAssert(m_Adiag > 0.0f);
+ btAssert(m_Adiag > btScalar(0.0));
}
//angular constraint between two different rigidbodies
@@ -59,7 +59,7 @@ public:
const btMatrix3x3& world2B,
const btVector3& inertiaInvA,
const btVector3& inertiaInvB)
- :m_linearJointAxis(btVector3(0.f,0.f,0.f))
+ :m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
{
m_aJ= world2A*jointAxis;
m_bJ = world2B*-jointAxis;
@@ -67,7 +67,7 @@ public:
m_1MinvJt = inertiaInvB * m_bJ;
m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);
- btAssert(m_Adiag > 0.0f);
+ btAssert(m_Adiag > btScalar(0.0));
}
//angular constraint between two different rigidbodies
@@ -75,7 +75,7 @@ public:
const btVector3& axisInB,
const btVector3& inertiaInvA,
const btVector3& inertiaInvB)
- : m_linearJointAxis(btVector3(0.f,0.f,0.f))
+ : m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
, m_aJ(axisInA)
, m_bJ(-axisInB)
{
@@ -83,7 +83,7 @@ public:
m_1MinvJt = inertiaInvB * m_bJ;
m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);
- btAssert(m_Adiag > 0.0f);
+ btAssert(m_Adiag > btScalar(0.0));
}
//constraint on one rigidbody
@@ -98,10 +98,10 @@ public:
m_aJ= world2A*(rel_pos1.cross(jointAxis));
m_bJ = world2A*(rel_pos2.cross(-jointAxis));
m_0MinvJt = inertiaInvA * m_aJ;
- m_1MinvJt = btVector3(0.f,0.f,0.f);
+ m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
m_Adiag = massInvA + m_0MinvJt.dot(m_aJ);
- btAssert(m_Adiag > 0.0f);
+ btAssert(m_Adiag > btScalar(0.0));
}
btScalar getDiagonal() const { return m_Adiag; }
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
index d15bdaad790..aacb0a3ea66 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
@@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btPoint2PointConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
-
+#include <new>
@@ -39,7 +39,7 @@ btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector
void btPoint2PointConstraint::buildJacobian()
{
- m_appliedImpulse = 0.f;
+ m_appliedImpulse = btScalar(0.);
btVector3 normal(0,0,0);
@@ -76,7 +76,7 @@ void btPoint2PointConstraint::solveConstraint(btScalar timeStep)
for (int i=0;i<3;i++)
{
normal[i] = 1;
- btScalar jacDiagABInv = 1.f / m_jac[i].getDiagonal();
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
@@ -110,6 +110,7 @@ void btPoint2PointConstraint::solveConstraint(btScalar timeStep)
void btPoint2PointConstraint::updateRHS(btScalar timeStep)
{
+ (void)timeStep;
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
index 8aae8d74ce7..71da8ac0347 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef POINT2POINTCONSTRAINT_H
#define POINT2POINTCONSTRAINT_H
-#include "LinearMath/btVector3.h"
-
-#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h"
+#include "../../LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
#include "btTypedConstraint.h"
class btRigidBody;
@@ -26,12 +25,12 @@ class btRigidBody;
struct btConstraintSetting
{
btConstraintSetting() :
- m_tau(0.3f),
- m_damping(1.f)
+ m_tau(btScalar(0.3)),
+ m_damping(btScalar(1.))
{
}
- float m_tau;
- float m_damping;
+ btScalar m_tau;
+ btScalar m_damping;
};
/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
index eaf172b9395..14b36ad44fd 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -24,7 +24,13 @@ subject to the following restrictions:
#include "btJacobianEntry.h"
#include "LinearMath/btMinMax.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include <new>
+#include "LinearMath/btStackAlloc.h"
+#include "LinearMath/btQuickprof.h"
+#include "btSolverBody.h"
+#include "btSolverConstraint.h"
+#include "LinearMath/btAlignedObjectArray.h"
#ifdef USE_PROFILE
#include "LinearMath/btQuickprof.h"
@@ -36,24 +42,26 @@ int gTotalContactPoints = 0;
struct btOrderIndex
{
- short int m_manifoldIndex;
- short int m_pointIndex;
+ int m_manifoldIndex;
+ int m_pointIndex;
};
+
+
#define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384
static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS];
-static unsigned long btSeed2 = 0;
-unsigned long btRand2()
+
+
+unsigned long btSequentialImpulseConstraintSolver::btRand2()
{
- btSeed2 = (1664525L*btSeed2 + 1013904223L) & 0xffffffff;
- return btSeed2;
+ m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
+ return m_btSeed2;
}
-
//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
-int btRandInt2 (int n)
+int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
{
// seems good; xor-fold and modulus
const unsigned long un = n;
@@ -82,15 +90,7 @@ int btRandInt2 (int n)
-int btRandIntWrong (int n)
-{
- float a = float(n) / 4294967296.0f;
-// printf("n = %d\n",n);
-// printf("a = %f\n",a);
- int res = (int) (float(btRand2()) * a);
-// printf("res=%d\n",res);
- return res;
-}
+
bool MyContactDestroyedCallback(void* userPersistentData)
{
@@ -102,18 +102,12 @@ bool MyContactDestroyedCallback(void* userPersistentData)
return true;
}
-btSequentialImpulseConstraintSolver3::btSequentialImpulseConstraintSolver3()
-{
- btSeed2 = 0;
- setSolverMode(SOLVER_RANDMIZE_ORDER);
-}
btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
-:m_solverMode(SOLVER_USE_WARMSTARTING)
+:m_solverMode(SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY), //not using SOLVER_USE_WARMSTARTING,
+m_btSeed2(0)
{
- btSeed2 = 0;
-
gContactDestroyedCallback = &MyContactDestroyedCallback;
//initialize default friction/contact funcs
@@ -127,35 +121,487 @@ btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
}
}
-/// btSequentialImpulseConstraintSolver Sequentially applies impulses
-float btSequentialImpulseConstraintSolver3::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
+
+void initSolverBody(btSolverBody* solverBody, btRigidBody* rigidbody)
+{
+/* int size = sizeof(btSolverBody);
+ int sizeofrb = sizeof(btRigidBody);
+ int sizemanifold = sizeof(btPersistentManifold);
+ int sizeofmp = sizeof(btManifoldPoint);
+ int sizeofPersistData = sizeof (btConstraintPersistentData);
+*/
+
+ solverBody->m_angularVelocity = rigidbody->getAngularVelocity();
+ solverBody->m_centerOfMassPosition = rigidbody->getCenterOfMassPosition();
+ solverBody->m_friction = rigidbody->getFriction();
+// solverBody->m_invInertiaWorld = rigidbody->getInvInertiaTensorWorld();
+ solverBody->m_invMass = rigidbody->getInvMass();
+ solverBody->m_linearVelocity = rigidbody->getLinearVelocity();
+ solverBody->m_originalBody = rigidbody;
+ solverBody->m_angularFactor = rigidbody->getAngularFactor();
+}
+
+btScalar penetrationResolveFactor = btScalar(0.9);
+btScalar restitutionCurve(btScalar rel_vel, btScalar restitution)
+{
+ btScalar rest = restitution * -rel_vel;
+ return rest;
+}
+
+
+
+
+
+
+//velocity + friction
+//response between two dynamic objects with friction
+SIMD_FORCE_INLINE btScalar resolveSingleCollisionCombinedCacheFriendly(
+ btSolverBody& body1,
+ btSolverBody& body2,
+ btSolverConstraint& contactConstraint,
+ const btContactSolverInfo& solverInfo)
+{
+ (void)solverInfo;
+
+ btScalar normalImpulse(0.f);
+ {
+ if (contactConstraint.m_penetration < 0.f)
+ return 0.f;
+
+ // Optimized version of projected relative velocity, use precomputed cross products with normal
+ // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
+ // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
+ // btVector3 vel = vel1 - vel2;
+ // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel);
+
+ btScalar rel_vel;
+ btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity)
+ + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity);
+ btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity)
+ + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity);
+
+ rel_vel = vel1Dotn-vel2Dotn;
+
+
+ btScalar positionalError = contactConstraint.m_penetration;
+ btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
+
+ btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv;
+ btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv;
+ btScalar normalImpulse = penetrationImpulse+velocityImpulse;
+
+ // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
+ btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse;
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
+
+ btScalar oldVelocityImpulse = contactConstraint.m_appliedVelocityImpulse;
+ btScalar velocitySum = oldVelocityImpulse + velocityImpulse;
+ contactConstraint.m_appliedVelocityImpulse = btScalar(0.) > velocitySum ? btScalar(0.): velocitySum;
+
+ normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse;
+
+ if (body1.m_invMass)
+ {
+ body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,
+ contactConstraint.m_angularComponentA,normalImpulse);
+ }
+ if (body2.m_invMass)
+ {
+ body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,
+ contactConstraint.m_angularComponentB,-normalImpulse);
+ }
+
+ }
+
+
+
+ return normalImpulse;
+}
+
+
+#ifndef NO_FRICTION_TANGENTIALS
+
+SIMD_FORCE_INLINE btScalar resolveSingleFrictionCacheFriendly(
+ btSolverBody& body1,
+ btSolverBody& body2,
+ btSolverConstraint& contactConstraint,
+ const btContactSolverInfo& solverInfo,
+ btScalar appliedNormalImpulse)
{
+ (void)solverInfo;
+
- btContactSolverInfo info = infoGlobal;
+ const btScalar combinedFriction = contactConstraint.m_friction;
+
+ const btScalar limit = appliedNormalImpulse * combinedFriction;
+
+ if (appliedNormalImpulse>btScalar(0.))
+ //friction
+ {
+
+ btScalar j1;
+ {
- int numiter = infoGlobal.m_numIterations;
-#ifdef USE_PROFILE
- btProfiler::beginBlock("solve");
-#endif //USE_PROFILE
+ btScalar rel_vel;
+ const btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity)
+ + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity);
+ const btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity)
+ + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity);
+ rel_vel = vel1Dotn-vel2Dotn;
+
+ // calculate j that moves us to zero relative velocity
+ j1 = -rel_vel * contactConstraint.m_jacDiagABInv;
+ btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse;
+ contactConstraint.m_appliedImpulse = oldTangentImpulse + j1;
+ GEN_set_min(contactConstraint.m_appliedImpulse, limit);
+ GEN_set_max(contactConstraint.m_appliedImpulse, -limit);
+ j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse;
- int totalPoints = 0;
+ }
+
+ if (body1.m_invMass)
+ {
+ body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1);
+ }
+ if (body2.m_invMass)
+ {
+ body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1);
+ }
+
+ }
+ return 0.f;
+}
+#else
+
+//velocity + friction
+//response between two dynamic objects with friction
+btScalar resolveSingleFrictionCacheFriendly(
+ btSolverBody& body1,
+ btSolverBody& body2,
+ btSolverConstraint& contactConstraint,
+ const btContactSolverInfo& solverInfo)
+{
+
+ btVector3 vel1;
+ btVector3 vel2;
+ btScalar normalImpulse(0.f);
+
{
- int j;
- for (j=0;j<numManifolds;j++)
+ const btVector3& normal = contactConstraint.m_contactNormal;
+ if (contactConstraint.m_penetration < 0.f)
+ return 0.f;
+
+
+ body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
+ body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
+ btVector3 vel = vel1 - vel2;
+ btScalar rel_vel;
+ rel_vel = normal.dot(vel);
+
+ btVector3 lat_vel = vel - normal * rel_vel;
+ btScalar lat_rel_vel = lat_vel.length2();
+
+ btScalar combinedFriction = contactConstraint.m_friction;
+ const btVector3& rel_pos1 = contactConstraint.m_rel_posA;
+ const btVector3& rel_pos2 = contactConstraint.m_rel_posB;
+
+
+ //if (contactConstraint.m_appliedVelocityImpulse > 0.f)
+ if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON)
{
- btPersistentManifold* manifold = manifoldPtr[j];
- prepareConstraints(manifold,info,debugDrawer);
+ lat_rel_vel = btSqrt(lat_rel_vel);
+
+ lat_vel /= lat_rel_vel;
+ btVector3 temp1 = body1.m_invInertiaWorld * rel_pos1.cross(lat_vel);
+ btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel);
+ btScalar friction_impulse = lat_rel_vel /
+ (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
+ btScalar normal_impulse = contactConstraint.m_appliedVelocityImpulse * combinedFriction;
+
+ GEN_set_min(friction_impulse, normal_impulse);
+ GEN_set_max(friction_impulse, -normal_impulse);
+ body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1);
+ body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
+ }
+ }
+
+ return normalImpulse;
+}
+
+#endif //NO_FRICTION_TANGENTIALS
+
+btAlignedObjectArray<btSolverBody> tmpSolverBodyPool;
+btAlignedObjectArray<btSolverConstraint> tmpSolverConstraintPool;
+btAlignedObjectArray<btSolverConstraint> tmpSolverFrictionConstraintPool;
+
+
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+{
+ (void)stackAlloc;
+ (void)debugDrawer;
+
+ if (!(numConstraints + numManifolds))
+ {
+// printf("empty\n");
+ return 0.f;
+ }
+
+ BEGIN_PROFILE("refreshManifolds");
+
+ int i;
+ for (i=0;i<numManifolds;i++)
+ {
+ btPersistentManifold* manifold = manifoldPtr[i];
+ btRigidBody* rb0 = (btRigidBody*)manifold->getBody0();
+ btRigidBody* rb1 = (btRigidBody*)manifold->getBody1();
- for (int p=0;p<manifoldPtr[j]->getNumContacts();p++)
+ manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
+
+ }
+
+ END_PROFILE("refreshManifolds");
+
+
+ BEGIN_PROFILE("gatherSolverData");
+
+ //int sizeofSB = sizeof(btSolverBody);
+ //int sizeofSC = sizeof(btSolverConstraint);
+
+
+ //if (1)
+ {
+ //if m_stackAlloc, try to pack bodies/constraints to speed up solving
+// btBlock* sablock;
+// sablock = stackAlloc->beginBlock();
+
+ // int memsize = 16;
+// unsigned char* stackMemory = stackAlloc->allocate(memsize);
+
+
+ //todo: use stack allocator for this temp memory
+ int minReservation = numManifolds*2;
+
+ tmpSolverBodyPool.reserve(minReservation);
+
+ {
+ for (int i=0;i<numBodies;i++)
{
- gOrder[totalPoints].m_manifoldIndex = j;
- gOrder[totalPoints].m_pointIndex = p;
- totalPoints++;
+ btRigidBody* rb = btRigidBody::upcast(bodies[i]);
+ if (rb && (rb->getIslandTag() >= 0))
+ {
+ btAssert(rb->getCompanionId() < 0);
+ int solverBodyId = tmpSolverBodyPool.size();
+ btSolverBody& solverBody = tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody,rb);
+ rb->setCompanionId(solverBodyId);
+ }
+ }
+ }
+
+
+ tmpSolverConstraintPool.reserve(minReservation);
+ tmpSolverFrictionConstraintPool.reserve(minReservation);
+ {
+ int i;
+
+ for (i=0;i<numManifolds;i++)
+ {
+ btPersistentManifold* manifold = manifoldPtr[i];
+ btRigidBody* rb0 = (btRigidBody*)manifold->getBody0();
+ btRigidBody* rb1 = (btRigidBody*)manifold->getBody1();
+
+
+ int solverBodyIdA=-1;
+ int solverBodyIdB=-1;
+
+ if (manifold->getNumContacts())
+ {
+
+
+
+ if (rb0->getIslandTag() >= 0)
+ {
+ solverBodyIdA = rb0->getCompanionId();
+ } else
+ {
+ //create a static body
+ solverBodyIdA = tmpSolverBodyPool.size();
+ btSolverBody& solverBody = tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody,rb0);
+ }
+
+ if (rb1->getIslandTag() >= 0)
+ {
+ solverBodyIdB = rb1->getCompanionId();
+ } else
+ {
+ //create a static body
+ solverBodyIdB = tmpSolverBodyPool.size();
+ btSolverBody& solverBody = tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody,rb1);
+ }
+ }
+
+ for (int j=0;j<manifold->getNumContacts();j++)
+ {
+
+ btManifoldPoint& cp = manifold->getContactPoint(j);
+
+ int frictionIndex = tmpSolverConstraintPool.size();
+
+ if (cp.getDistance() <= btScalar(0.))
+ {
+
+ const btVector3& pos1 = cp.getPositionWorldOnA();
+ const btVector3& pos2 = cp.getPositionWorldOnB();
+
+ btVector3 rel_pos1 = pos1 - rb0->getCenterOfMassPosition();
+ btVector3 rel_pos2 = pos2 - rb1->getCenterOfMassPosition();
+
+
+ btScalar relaxation = 1.f;
+
+ {
+ btSolverConstraint& solverConstraint = tmpSolverConstraintPool.expand();
+
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+ solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D;
+
+
+
+ {
+ //can be optimized, the cross products are already calculated
+ btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
+ btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
+ btScalar denom = relaxation/(denom0+denom1);
+ solverConstraint.m_jacDiagABInv = denom;
+ }
+
+ solverConstraint.m_contactNormal = cp.m_normalWorldOnB;
+ solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB);
+
+
+ btVector3 vel1 = rb0->getVelocityInLocalPoint(rel_pos1);
+ btVector3 vel2 = rb1->getVelocityInLocalPoint(rel_pos2);
+
+ btVector3 vel = vel1 - vel2;
+ btScalar rel_vel;
+ rel_vel = cp.m_normalWorldOnB.dot(vel);
+
+
+ solverConstraint.m_penetration = cp.getDistance();///btScalar(infoGlobal.m_numIterations);
+ solverConstraint.m_friction = cp.m_combinedFriction;
+ btScalar rest = restitutionCurve(rel_vel, cp.m_combinedRestitution);
+ if (rest <= btScalar(0.))
+ {
+ rest = 0.f;
+ };
+
+ btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep;
+ if (rest > penVel)
+ {
+ rest = btScalar(0.);
+ }
+ solverConstraint.m_restitution = rest;
+
+ solverConstraint.m_penetration *= -(infoGlobal.m_erp/infoGlobal.m_timeStep);
+
+ solverConstraint.m_appliedImpulse = 0.f;
+ solverConstraint.m_appliedVelocityImpulse = 0.f;
+
+
+ btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*torqueAxis0;
+ btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*torqueAxis1;
+ }
+
+ //create 2 '1d axis' constraints for 2 tangential friction directions
+
+ //re-calculate friction direction every frame, todo: check if this is really needed
+ btVector3 frictionTangential0a, frictionTangential1b;
+
+ btPlaneSpace1(cp.m_normalWorldOnB,frictionTangential0a,frictionTangential1b);
+
+ {
+ btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand();
+ solverConstraint.m_contactNormal = frictionTangential0a;
+
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+ solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
+ solverConstraint.m_frictionIndex = frictionIndex;
+
+ solverConstraint.m_friction = cp.m_combinedFriction;
+
+ solverConstraint.m_appliedImpulse = btScalar(0.);
+ solverConstraint.m_appliedVelocityImpulse = 0.f;
+
+ btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
+ btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
+ btScalar denom = relaxation/(denom0+denom1);
+ solverConstraint.m_jacDiagABInv = denom;
+
+ {
+ btVector3 ftorqueAxis0 = rel_pos1.cross(solverConstraint.m_contactNormal);
+ solverConstraint.m_relpos1CrossNormal = ftorqueAxis0;
+ solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis0;
+ }
+ {
+ btVector3 ftorqueAxis0 = rel_pos2.cross(solverConstraint.m_contactNormal);
+ solverConstraint.m_relpos2CrossNormal = ftorqueAxis0;
+ solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis0;
+ }
+
+ }
+
+
+ {
+
+ btSolverConstraint& solverConstraint = tmpSolverFrictionConstraintPool.expand();
+ solverConstraint.m_contactNormal = frictionTangential1b;
+
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+ solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
+ solverConstraint.m_frictionIndex = frictionIndex;
+
+ solverConstraint.m_friction = cp.m_combinedFriction;
+
+ solverConstraint.m_appliedImpulse = btScalar(0.);
+ solverConstraint.m_appliedVelocityImpulse = 0.f;
+
+ btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
+ btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
+ btScalar denom = relaxation/(denom0+denom1);
+ solverConstraint.m_jacDiagABInv = denom;
+ {
+ btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
+ solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
+ solverConstraint.m_angularComponentA = rb0->getInvInertiaTensorWorld()*ftorqueAxis1;
+ }
+ {
+ btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal);
+ solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
+ solverConstraint.m_angularComponentB = rb1->getInvInertiaTensorWorld()*ftorqueAxis1;
+ }
+ }
+
+ }
+ }
}
}
}
+ END_PROFILE("gatherSolverData");
+
+ BEGIN_PROFILE("prepareConstraints");
+
+ btContactSolverInfo info = infoGlobal;
{
int j;
@@ -166,21 +612,57 @@ float btSequentialImpulseConstraintSolver3::solveGroup(btPersistentManifold** ma
}
}
- //should traverse the contacts random order...
- int iteration;
+ btAlignedObjectArray<int> gOrderTmpConstraintPool;
+ btAlignedObjectArray<int> gOrderFrictionConstraintPool;
+ int numConstraintPool = tmpSolverConstraintPool.size();
+ int numFrictionPool = tmpSolverFrictionConstraintPool.size();
+
+ ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
+ gOrderTmpConstraintPool.resize(numConstraintPool);
+ gOrderFrictionConstraintPool.resize(numFrictionPool);
{
- for ( iteration = 0;iteration<numiter-1;iteration++)
+ int i;
+ for (i=0;i<numConstraintPool;i++)
+ {
+ gOrderTmpConstraintPool[i] = i;
+ }
+ for (i=0;i<numFrictionPool;i++)
{
+ gOrderFrictionConstraintPool[i] = i;
+ }
+ }
+
+
+
+
+ END_PROFILE("prepareConstraints");
+
+
+ BEGIN_PROFILE("solveConstraints");
+
+ //should traverse the contacts random order...
+ int iteration;
+ {
+ for ( iteration = 0;iteration<info.m_numIterations;iteration++)
+ {
+
int j;
if (m_solverMode & SOLVER_RANDMIZE_ORDER)
{
if ((iteration & 7) == 0) {
- for (j=0; j<totalPoints; ++j) {
- btOrderIndex tmp = gOrder[j];
+ for (j=0; j<numConstraintPool; ++j) {
+ int tmp = gOrderTmpConstraintPool[j];
int swapi = btRandInt2(j+1);
- gOrder[j] = gOrder[swapi];
- gOrder[swapi] = tmp;
+ gOrderTmpConstraintPool[j] = gOrderTmpConstraintPool[swapi];
+ gOrderTmpConstraintPool[swapi] = tmp;
+ }
+
+ for (j=0; j<numFrictionPool; ++j) {
+ int tmp = gOrderFrictionConstraintPool[j];
+ int swapi = btRandInt2(j+1);
+ gOrderFrictionConstraintPool[j] = gOrderFrictionConstraintPool[swapi];
+ gOrderFrictionConstraintPool[swapi] = tmp;
}
}
}
@@ -188,38 +670,102 @@ float btSequentialImpulseConstraintSolver3::solveGroup(btPersistentManifold** ma
for (j=0;j<numConstraints;j++)
{
btTypedConstraint* constraint = constraints[j];
+ ///todo: use solver bodies, so we don't need to copy from/to btRigidBody
+
+ if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
+ {
+ tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity();
+ }
+ if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
+ {
+ tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity();
+ }
+
constraint->solveConstraint(info.m_timeStep);
+
+ if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
+ {
+ tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity();
+ }
+ if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
+ {
+ tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity();
+ }
+
}
- for (j=0;j<totalPoints;j++)
{
- btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
- solve( (btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1()
- ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
+ int numPoolConstraints = tmpSolverConstraintPool.size();
+ for (j=0;j<numPoolConstraints;j++)
+ {
+ btSolverConstraint& solveManifold = tmpSolverConstraintPool[gOrderTmpConstraintPool[j]];
+ resolveSingleCollisionCombinedCacheFriendly(tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
+ tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,info);
+ }
}
-
- for (j=0;j<totalPoints;j++)
+
{
- btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
- solveFriction((btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
+ int numFrictionPoolConstraints = tmpSolverFrictionConstraintPool.size();
+ for (j=0;j<numFrictionPoolConstraints;j++)
+ {
+ btSolverConstraint& solveManifold = tmpSolverFrictionConstraintPool[gOrderFrictionConstraintPool[j]];
+ btScalar appliedNormalImpulse = tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+
+ resolveSingleFrictionCacheFriendly(tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
+ tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,info,appliedNormalImpulse);
+ }
}
+
+
+
}
}
-#ifdef USE_PROFILE
- btProfiler::endBlock("solve");
-#endif //USE_PROFILE
+ for ( i=0;i<tmpSolverBodyPool.size();i++)
+ {
+ tmpSolverBodyPool[i].writebackVelocity();
+ }
+
+ END_PROFILE("solveConstraints");
+
+// printf("tmpSolverConstraintPool.size() = %i\n",tmpSolverConstraintPool.size());
+
+/*
+ printf("tmpSolverBodyPool.size() = %i\n",tmpSolverBodyPool.size());
+ printf("tmpSolverConstraintPool.size() = %i\n",tmpSolverConstraintPool.size());
+ printf("tmpSolverFrictionConstraintPool.size() = %i\n",tmpSolverFrictionConstraintPool.size());
+
+
+ printf("tmpSolverBodyPool.capacity() = %i\n",tmpSolverBodyPool.capacity());
+ printf("tmpSolverConstraintPool.capacity() = %i\n",tmpSolverConstraintPool.capacity());
+ printf("tmpSolverFrictionConstraintPool.capacity() = %i\n",tmpSolverFrictionConstraintPool.capacity());
+*/
+
+ tmpSolverBodyPool.resize(0);
+ tmpSolverConstraintPool.resize(0);
+ tmpSolverFrictionConstraintPool.resize(0);
+
return 0.f;
}
-
/// btSequentialImpulseConstraintSolver Sequentially applies impulses
-float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
+btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
{
+
+ if (getSolverMode() & SOLVER_CACHE_FRIENDLY)
+ {
+ //you need to provide at least some bodies
+ //btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY
+ btAssert(bodies);
+ btAssert(numBodies);
+ return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
+ }
+
+
+ BEGIN_PROFILE("prepareConstraints");
+
btContactSolverInfo info = infoGlobal;
int numiter = infoGlobal.m_numIterations;
@@ -227,21 +773,25 @@ float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** man
btProfiler::beginBlock("solve");
#endif //USE_PROFILE
+ int totalPoints = 0;
+
+
{
- int j;
+ short j;
for (j=0;j<numManifolds;j++)
{
btPersistentManifold* manifold = manifoldPtr[j];
prepareConstraints(manifold,info,debugDrawer);
- for (int p=0;p<manifoldPtr[j]->getNumContacts();p++)
+
+ for (short p=0;p<manifoldPtr[j]->getNumContacts();p++)
{
- //interleaving here gives better results
- solve( (btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1()
- ,manifoldPtr[j]->getContactPoint(p),info,0,debugDrawer);
+ gOrder[totalPoints].m_manifoldIndex = j;
+ gOrder[totalPoints].m_pointIndex = p;
+ totalPoints++;
}
}
}
+
{
int j;
for (j=0;j<numConstraints;j++)
@@ -251,66 +801,77 @@ float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** man
}
}
+ END_PROFILE("prepareConstraints");
+
+
+ BEGIN_PROFILE("solveConstraints");
+
//should traverse the contacts random order...
int iteration;
- for ( iteration = 0;iteration<numiter-1;iteration++)
{
- int j;
-
- for (j=0;j<numConstraints;j++)
+ for ( iteration = 0;iteration<numiter;iteration++)
{
- btTypedConstraint* constraint = constraints[j];
- constraint->solveConstraint(info.m_timeStep);
- }
+ int j;
+ if (m_solverMode & SOLVER_RANDMIZE_ORDER)
+ {
+ if ((iteration & 7) == 0) {
+ for (j=0; j<totalPoints; ++j) {
+ btOrderIndex tmp = gOrder[j];
+ int swapi = btRandInt2(j+1);
+ gOrder[j] = gOrder[swapi];
+ gOrder[swapi] = tmp;
+ }
+ }
+ }
- for (j=0;j<numManifolds;j++)
- {
- btPersistentManifold* manifold = manifoldPtr[j];
- for (int p=0;p<manifold->getNumContacts();p++)
+ for (j=0;j<numConstraints;j++)
{
+ btTypedConstraint* constraint = constraints[j];
+ constraint->solveConstraint(info.m_timeStep);
+ }
+
+ for (j=0;j<totalPoints;j++)
+ {
+ btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
solve( (btRigidBody*)manifold->getBody0(),
(btRigidBody*)manifold->getBody1()
- ,manifold->getContactPoint(p),info,iteration,debugDrawer);
+ ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
}
- }
-
- }
-
- for ( iteration = 0;iteration<numiter-1;iteration++)
- {
- int j;
- for (j=0;j<numManifolds;j++)
- {
- btPersistentManifold* manifold = manifoldPtr[j];
- for (int p=0;p<manifold->getNumContacts();p++)
+
+ for (j=0;j<totalPoints;j++)
{
+ btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
solveFriction((btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(p),info,iteration,debugDrawer);
+ (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
}
}
}
-
+ END_PROFILE("solveConstraints");
+
+
#ifdef USE_PROFILE
btProfiler::endBlock("solve");
#endif //USE_PROFILE
- return 0.f;
-}
-float penetrationResolveFactor = 0.9f;
-btScalar restitutionCurve(btScalar rel_vel, btScalar restitution)
-{
- btScalar rest = restitution * -rel_vel;
- return rest;
+
+ return btScalar(0.);
}
+
+
+
+
+
void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer)
{
+ (void)debugDrawer;
+
btRigidBody* body0 = (btRigidBody*)manifoldPtr->getBody0();
btRigidBody* body1 = (btRigidBody*)manifoldPtr->getBody1();
@@ -327,7 +888,7 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
for (int i=0;i<numpoints ;i++)
{
btManifoldPoint& cp = manifoldPtr->getContactPoint(i);
- if (cp.getDistance() <= 0.f)
+ if (cp.getDistance() <= btScalar(0.))
{
const btVector3& pos1 = cp.getPositionWorldOnA();
const btVector3& pos2 = cp.getPositionWorldOnB();
@@ -376,7 +937,7 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
}
assert(cpd);
- cpd->m_jacDiagABInv = 1.f / jacDiagAB;
+ cpd->m_jacDiagABInv = btScalar(1.) / jacDiagAB;
//Dependent on Rigidbody A and B types, fetch the contact/friction response func
//perhaps do a similar thing for friction/restutution combiner funcs...
@@ -390,14 +951,14 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
btScalar rel_vel;
rel_vel = cp.m_normalWorldOnB.dot(vel);
- float combinedRestitution = cp.m_combinedRestitution;
+ btScalar combinedRestitution = cp.m_combinedRestitution;
- cpd->m_penetration = cp.getDistance();
+ cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations);
cpd->m_friction = cp.m_combinedFriction;
cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution);
- if (cpd->m_restitution <= 0.) //0.f)
+ if (cpd->m_restitution <= btScalar(0.))
{
- cpd->m_restitution = 0.0f;
+ cpd->m_restitution = btScalar(0.0);
};
@@ -408,18 +969,18 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
if (cpd->m_restitution > penVel)
{
- cpd->m_penetration = 0.f;
+ cpd->m_penetration = btScalar(0.);
}
- float relaxation = info.m_damping;
+ btScalar relaxation = info.m_damping;
if (m_solverMode & SOLVER_USE_WARMSTARTING)
{
cpd->m_appliedImpulse *= relaxation;
} else
{
- cpd->m_appliedImpulse =0.f;
+ cpd->m_appliedImpulse =btScalar(0.);
}
//for friction
@@ -432,12 +993,12 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
#define NO_FRICTION_WARMSTART 1
#ifdef NO_FRICTION_WARMSTART
- cpd->m_accumulatedTangentImpulse0 = 0.f;
- cpd->m_accumulatedTangentImpulse1 = 0.f;
+ cpd->m_accumulatedTangentImpulse0 = btScalar(0.);
+ cpd->m_accumulatedTangentImpulse1 = btScalar(0.);
#endif //NO_FRICTION_WARMSTART
- float denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0);
- float denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0);
- float denom = relaxation/(denom0+denom1);
+ btScalar denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0);
+ btScalar denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0);
+ btScalar denom = relaxation/(denom0+denom1);
cpd->m_jacDiagABInvTangent0 = denom;
@@ -492,16 +1053,54 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
}
}
-float btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
+
+btScalar btSequentialImpulseConstraintSolver::solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
{
+ btScalar maxImpulse = btScalar(0.);
+
+ {
+
+ btVector3 color(0,1,0);
+ {
+ if (cp.getDistance() <= btScalar(0.))
+ {
- float maxImpulse = 0.f;
+ if (iter == 0)
+ {
+ if (debugDrawer)
+ debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
+ }
+
+ {
+
+ //btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
+ btScalar impulse = resolveSingleCollisionCombined(
+ *body0,*body1,
+ cp,
+ info);
+
+ if (maxImpulse < impulse)
+ maxImpulse = impulse;
+
+ }
+ }
+ }
+ }
+ return maxImpulse;
+}
+
+
+
+btScalar btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
+{
+
+ btScalar maxImpulse = btScalar(0.);
{
btVector3 color(0,1,0);
{
- if (cp.getDistance() <= 0.f)
+ if (cp.getDistance() <= btScalar(0.))
{
if (iter == 0)
@@ -513,7 +1112,7 @@ float btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody*
{
btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
- float impulse = cpd->m_contactSolverFunc(
+ btScalar impulse = cpd->m_contactSolverFunc(
*body0,*body1,
cp,
info);
@@ -528,16 +1127,19 @@ float btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody*
return maxImpulse;
}
-float btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
+btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
{
+ (void)debugDrawer;
+ (void)iter;
+
{
btVector3 color(0,1,0);
{
- if (cp.getDistance() <= 0.f)
+ if (cp.getDistance() <= btScalar(0.))
{
btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
@@ -552,5 +1154,5 @@ float btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRi
}
- return 0.f;
+ return btScalar(0.);
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
index 0989a86e2cd..13e70c41be4 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
@@ -18,7 +18,6 @@ subject to the following restrictions:
#include "btConstraintSolver.h"
class btIDebugDraw;
-
#include "btContactConstraint.h"
@@ -31,8 +30,8 @@ class btSequentialImpulseConstraintSolver : public btConstraintSolver
{
protected:
- float solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
- float solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
+ btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
+ btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer);
ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
@@ -40,6 +39,8 @@ protected:
//choose between several modes, different friction model etc.
int m_solverMode;
+ ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
+ unsigned long m_btSeed2;
public:
@@ -47,7 +48,8 @@ public:
{
SOLVER_RANDMIZE_ORDER = 1,
SOLVER_FRICTION_SEPARATE = 2,
- SOLVER_USE_WARMSTARTING = 4
+ SOLVER_USE_WARMSTARTING = 4,
+ SOLVER_CACHE_FRIENDLY = 8
};
btSequentialImpulseConstraintSolver();
@@ -68,7 +70,12 @@ public:
virtual ~btSequentialImpulseConstraintSolver() {}
- virtual float solveGroup(btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer=0);
+ virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc);
+
+ virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
+
+ btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
+
void setSolverMode(int mode)
{
@@ -79,20 +86,24 @@ public:
{
return m_solverMode;
}
-};
-
-/// Small variation on btSequentialImpulseConstraintSolver: warmstarting, separate friction, non-randomized ordering
-class btSequentialImpulseConstraintSolver3 : public btSequentialImpulseConstraintSolver
-{
-public:
- btSequentialImpulseConstraintSolver3();
+ unsigned long btRand2();
- virtual float solveGroup(btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer=0);
+ int btRandInt2 (int n);
+ void setRandSeed(unsigned long seed)
+ {
+ m_btSeed2 = seed;
+ }
+ unsigned long getRandSeed() const
+ {
+ return m_btSeed2;
+ }
};
+
+
#endif //SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
index edca6c8fa08..0c7dbd668bb 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
@@ -43,12 +43,18 @@ void btSolve2LinearConstraint::resolveUnilateralPairConstraint(
btScalar depthB, const btVector3& normalB,
btScalar& imp0,btScalar& imp1)
{
+ (void)linvelA;
+ (void)linvelB;
+ (void)angvelB;
+ (void)angvelA;
- imp0 = 0.f;
- imp1 = 0.f;
- btScalar len = fabs(normalA.length())-1.f;
- if (fabs(len) >= SIMD_EPSILON)
+
+ imp0 = btScalar(0.);
+ imp1 = btScalar(0.);
+
+ btScalar len = btFabs(normalA.length()) - btScalar(1.);
+ if (btFabs(len) >= SIMD_EPSILON)
return;
btAssert(len < SIMD_EPSILON);
@@ -67,7 +73,7 @@ void btSolve2LinearConstraint::resolveUnilateralPairConstraint(
const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));
// btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv
- btScalar massTerm = 1.f / (invMassA + invMassB);
+ btScalar massTerm = btScalar(1.) / (invMassA + invMassB);
// calculate rhs (or error) terms
@@ -87,7 +93,7 @@ void btSolve2LinearConstraint::resolveUnilateralPairConstraint(
btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
- btScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+ btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
//imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
//imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
@@ -126,11 +132,18 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint(
btScalar& imp0,btScalar& imp1)
{
- imp0 = 0.f;
- imp1 = 0.f;
+ (void)linvelA;
+ (void)linvelB;
+ (void)angvelA;
+ (void)angvelB;
+
+
- btScalar len = fabs(normalA.length())-1.f;
- if (fabs(len) >= SIMD_EPSILON)
+ imp0 = btScalar(0.);
+ imp1 = btScalar(0.);
+
+ btScalar len = btFabs(normalA.length()) - btScalar(1.);
+ if (btFabs(len) >= SIMD_EPSILON)
return;
btAssert(len < SIMD_EPSILON);
@@ -164,7 +177,7 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint(
btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
- btScalar invDet = 1.0f / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+ btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
//imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
//imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
@@ -178,41 +191,41 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint(
//[jA nD] * [imp0] = [dv0]
//[nD jB] [imp1] [dv1]
- if ( imp0 > 0.0f)
+ if ( imp0 > btScalar(0.0))
{
- if ( imp1 > 0.0f )
+ if ( imp1 > btScalar(0.0) )
{
//both positive
}
else
{
- imp1 = 0.f;
+ imp1 = btScalar(0.);
// now imp0>0 imp1<0
imp0 = dv0 / jacA.getDiagonal();
- if ( imp0 > 0.0f )
+ if ( imp0 > btScalar(0.0) )
{
} else
{
- imp0 = 0.f;
+ imp0 = btScalar(0.);
}
}
}
else
{
- imp0 = 0.f;
+ imp0 = btScalar(0.);
imp1 = dv1 / jacB.getDiagonal();
- if ( imp1 <= 0.0f )
+ if ( imp1 <= btScalar(0.0) )
{
- imp1 = 0.f;
+ imp1 = btScalar(0.);
// now imp0>0 imp1<0
imp0 = dv0 / jacA.getDiagonal();
- if ( imp0 > 0.0f )
+ if ( imp0 > btScalar(0.0) )
{
} else
{
- imp0 = 0.f;
+ imp0 = btScalar(0.);
}
} else
{
@@ -221,7 +234,7 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint(
}
-
+/*
void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invInertiaAWS,
const btScalar invMassA,
const btVector3& linvelA,const btVector3& angvelA,
@@ -238,4 +251,5 @@ void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invI
{
}
+*/
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
index 639e4c9433f..e7d26645c6a 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef SOLVE_2LINEAR_CONSTRAINT_H
#define SOLVE_2LINEAR_CONSTRAINT_H
-#include "LinearMath/btMatrix3x3.h"
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btMatrix3x3.h"
+#include "../../LinearMath/btVector3.h"
class btRigidBody;
@@ -85,7 +85,7 @@ public:
btScalar depthB, const btVector3& normalB,
btScalar& imp0,btScalar& imp1);
-
+/*
void resolveAngularConstraint( const btMatrix3x3& invInertiaAWS,
const btScalar invMassA,
const btVector3& linvelA,const btVector3& angvelA,
@@ -100,6 +100,7 @@ public:
btScalar depthB, const btVector3& normalB,
btScalar& imp0,btScalar& imp1);
+*/
};
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
new file mode 100644
index 00000000000..0ab536f42b3
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
@@ -0,0 +1,71 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_SOLVER_BODY_H
+#define BT_SOLVER_BODY_H
+
+class btRigidBody;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+
+
+
+
+ATTRIBUTE_ALIGNED16 (struct) btSolverBody
+{
+ btVector3 m_centerOfMassPosition;
+ btVector3 m_linearVelocity;
+ btVector3 m_angularVelocity;
+ btRigidBody* m_originalBody;
+ float m_invMass;
+ float m_friction;
+ float m_angularFactor;
+
+ inline void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const
+ {
+ velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos);
+ }
+
+ //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
+ inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
+ {
+ m_linearVelocity += linearComponent*impulseMagnitude;
+ m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
+ }
+
+ void writebackVelocity()
+ {
+ if (m_invMass)
+ {
+ m_originalBody->setLinearVelocity(m_linearVelocity);
+ m_originalBody->setAngularVelocity(m_angularVelocity);
+ }
+ }
+
+ void readVelocity()
+ {
+ if (m_invMass)
+ {
+ m_linearVelocity = m_originalBody->getLinearVelocity();
+ m_angularVelocity = m_originalBody->getAngularVelocity();
+ }
+ }
+
+
+
+
+};
+
+#endif //BT_SOLVER_BODY_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
new file mode 100644
index 00000000000..f1f40ffdf19
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
@@ -0,0 +1,63 @@
+
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_SOLVER_CONSTRAINT_H
+#define BT_SOLVER_CONSTRAINT_H
+
+class btRigidBody;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+
+//#define NO_FRICTION_TANGENTIALS 1
+
+///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
+ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint
+{
+ btVector3 m_relpos1CrossNormal;
+ btVector3 m_relpos2CrossNormal;
+ btVector3 m_contactNormal;
+ btVector3 m_angularComponentA;
+ btVector3 m_angularComponentB;
+
+ btScalar m_appliedVelocityImpulse;
+ int m_solverBodyIdA;
+ int m_solverBodyIdB;
+ btScalar m_friction;
+ btScalar m_restitution;
+ btScalar m_jacDiagABInv;
+ btScalar m_penetration;
+ btScalar m_appliedImpulse;
+
+ int m_constraintType;
+ int m_frictionIndex;
+ int m_unusedPadding[2];
+
+ enum btSolverConstraintType
+ {
+ BT_SOLVER_CONTACT_1D = 0,
+ BT_SOLVER_FRICTION_1D
+ };
+};
+
+
+
+
+
+
+#endif //BT_SOLVER_CONSTRAINT_H
+
+
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
index cb3fa72d440..a15b3e026cd 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
@@ -24,18 +24,18 @@ btTypedConstraint::btTypedConstraint()
m_userConstraintId(-1),
m_rbA(s_fixed),
m_rbB(s_fixed),
-m_appliedImpulse(0.f)
+m_appliedImpulse(btScalar(0.))
{
- s_fixed.setMassProps(0.f,btVector3(0.f,0.f,0.f));
+ s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
}
btTypedConstraint::btTypedConstraint(btRigidBody& rbA)
: m_userConstraintType(-1),
m_userConstraintId(-1),
m_rbA(rbA),
m_rbB(s_fixed),
-m_appliedImpulse(0.f)
+m_appliedImpulse(btScalar(0.))
{
- s_fixed.setMassProps(0.f,btVector3(0.f,0.f,0.f));
+ s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
}
@@ -45,9 +45,9 @@ btTypedConstraint::btTypedConstraint(btRigidBody& rbA,btRigidBody& rbB)
m_userConstraintId(-1),
m_rbA(rbA),
m_rbB(rbB),
-m_appliedImpulse(0.f)
+m_appliedImpulse(btScalar(0.))
{
- s_fixed.setMassProps(0.f,btVector3(0.f,0.f,0.f));
+ s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
index bc25eaa759c..dfee6e80d0e 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
@@ -17,19 +17,25 @@ subject to the following restrictions:
#define TYPED_CONSTRAINT_H
class btRigidBody;
-#include "LinearMath/btScalar.h"
+#include "../../LinearMath/btScalar.h"
///TypedConstraint is the baseclass for Bullet constraints and vehicles
class btTypedConstraint
{
int m_userConstraintType;
int m_userConstraintId;
-
+
+ btTypedConstraint& operator=(btTypedConstraint& other)
+ {
+ btAssert(0);
+ (void) other;
+ return *this;
+ }
protected:
btRigidBody& m_rbA;
btRigidBody& m_rbB;
- float m_appliedImpulse;
+ btScalar m_appliedImpulse;
public:
@@ -81,7 +87,7 @@ public:
{
return m_userConstraintId;
}
- float getAppliedImpulse()
+ btScalar getAppliedImpulse()
{
return m_appliedImpulse;
}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
new file mode 100644
index 00000000000..248c582dcd8
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
@@ -0,0 +1,120 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
+ Work in progress, functionality will be added on demand.
+
+ If possible, use the richer Bullet C++ API, by including <src/btBulletDynamicsCommon.h>
+*/
+
+#include "Bullet-C-Api.h"
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btScalar.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "LinearMath/btStackAlloc.h"
+
+extern "C"
+double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3])
+{
+ btVector3 vp(p1[0], p1[1], p1[2]);
+ btTriangleShape trishapeA(vp,
+ btVector3(p2[0], p2[1], p2[2]),
+ btVector3(p3[0], p3[1], p3[2]));
+ trishapeA.setMargin(0.000001f);
+ btVector3 vq(q1[0], q1[1], q1[2]);
+ btTriangleShape trishapeB(vq,
+ btVector3(q2[0], q2[1], q2[2]),
+ btVector3(q3[0], q3[1], q3[2]));
+ trishapeB.setMargin(0.000001f);
+
+ // btVoronoiSimplexSolver sGjkSimplexSolver;
+ // btGjkEpaPenetrationDepthSolver penSolverPtr;
+
+ static btSimplexSolverInterface sGjkSimplexSolver;
+ sGjkSimplexSolver.reset();
+
+ static btGjkEpaPenetrationDepthSolver Solver0;
+ static btMinkowskiPenetrationDepthSolver Solver1;
+
+ btConvexPenetrationDepthSolver* Solver = NULL;
+
+ Solver = &Solver1;
+
+ btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver);
+
+ convexConvex.m_catchDegeneracies = 1;
+
+ // btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0);
+
+ btPointCollector gjkOutput;
+ btGjkPairDetector::ClosestPointInput input;
+
+ btStackAlloc gStackAlloc(1024*1024*2);
+
+ input.m_stackAlloc = &gStackAlloc;
+
+ btTransform tr;
+ tr.setIdentity();
+
+ input.m_transformA = tr;
+ input.m_transformB = tr;
+
+ convexConvex.getClosestPoints(input, gjkOutput, 0);
+
+
+ if (gjkOutput.m_hasResult)
+ {
+
+ pb[0] = pa[0] = gjkOutput.m_pointInWorld[0];
+ pb[1] = pa[1] = gjkOutput.m_pointInWorld[1];
+ pb[2] = pa[2] = gjkOutput.m_pointInWorld[2];
+
+ pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance;
+ pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance;
+ pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance;
+
+ normal[0] = gjkOutput.m_normalOnBInWorld[0];
+ normal[1] = gjkOutput.m_normalOnBInWorld[1];
+ normal[2] = gjkOutput.m_normalOnBInWorld[2];
+
+ return gjkOutput.m_distance;
+ }
+ return -1.0f;
+}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index fc37cf2e3c3..29719ec9a3e 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -16,7 +16,6 @@ subject to the following restrictions:
#include "btDiscreteDynamicsWorld.h"
-
//collision detection
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
@@ -31,15 +30,17 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
//for debug rendering
-#include "BulletCollision/CollisionShapes/btCompoundShape.h"
-#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
-#include "BulletCollision/CollisionShapes/btCylinderShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/CollisionShapes/btConeShape.h"
-#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
-#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btCylinderShape.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
#include "LinearMath/btIDebugDraw.h"
@@ -54,8 +55,6 @@ subject to the following restrictions:
-#include <algorithm>
-
btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver)
@@ -63,7 +62,7 @@ btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOver
m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver),
m_debugDrawer(0),
m_gravity(0,-10,0),
-m_localTime(1.f/60.f),
+m_localTime(btScalar(1.)/btScalar(60.)),
m_profileTimings(0)
{
m_islandManager = new btSimulationIslandManager();
@@ -81,10 +80,10 @@ btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
delete m_constraintSolver;
}
-void btDiscreteDynamicsWorld::saveKinematicState(float timeStep)
+void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
{
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for (int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -110,27 +109,27 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
{
//todo: iterate over awake simulation islands!
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
{
- btVector3 color(255.f,255.f,255.f);
+ btVector3 color(btScalar(255.),btScalar(255.),btScalar(255.));
switch(colObj->getActivationState())
{
case ACTIVE_TAG:
- color = btVector3(255.f,255.f,255.f); break;
+ color = btVector3(btScalar(255.),btScalar(255.),btScalar(255.)); break;
case ISLAND_SLEEPING:
- color = btVector3(0.f,255.f,0.f);break;
+ color = btVector3(btScalar(0.),btScalar(255.),btScalar(0.));break;
case WANTS_DEACTIVATION:
- color = btVector3(0.f,255.f,255.f);break;
+ color = btVector3(btScalar(0.),btScalar(255.),btScalar(255.));break;
case DISABLE_DEACTIVATION:
- color = btVector3(255.f,0.f,0.f);break;
+ color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));break;
case DISABLE_SIMULATION:
- color = btVector3(255.f,255.f,0.f);break;
+ color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break;
default:
{
- color = btVector3(255.f,0.f,0.f);
+ color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));
}
};
@@ -139,7 +138,10 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
btRigidBody* body = btRigidBody::upcast(colObj);
if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
{
- if (body->getActivationState() != ISLAND_SLEEPING)
+ //we need to call the update at least once, even for sleeping objects
+ //otherwise the 'graphics' transform never updates properly
+ //so todo: add 'dirty' flag
+ //if (body->getActivationState() != ISLAND_SLEEPING)
{
btTransform interpolatedTransform;
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
@@ -152,7 +154,7 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
{
- for (unsigned int i=0;i<this->m_vehicles.size();i++)
+ for ( int i=0;i<this->m_vehicles.size();i++)
{
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
{
@@ -188,7 +190,7 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
}
-int btDiscreteDynamicsWorld::stepSimulation( float timeStep,int maxSubSteps, float fixedTimeStep)
+int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
{
int numSimulationSubSteps = 0;
@@ -243,7 +245,7 @@ int btDiscreteDynamicsWorld::stepSimulation( float timeStep,int maxSubSteps, flo
return numSimulationSubSteps;
}
-void btDiscreteDynamicsWorld::internalSingleStepSimulation(float timeStep)
+void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
{
startProfiling(timeStep);
@@ -291,7 +293,7 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(float timeStep)
void btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
{
m_gravity = gravity;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -318,19 +320,32 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
if (body->getCollisionShape())
{
bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
- short collisionFilterGroup = isDynamic? btBroadphaseProxy::DefaultFilter : btBroadphaseProxy::StaticFilter;
- short collisionFilterMask = isDynamic? btBroadphaseProxy::AllFilter : btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter;
+ short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
+ short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
}
}
+void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
+{
+ if (!body->isStaticOrKinematicObject())
+ {
+ body->setGravity(m_gravity);
+ }
+
+ if (body->getCollisionShape())
+ {
+ addCollisionObject(body,group,mask);
+ }
+}
+
-void btDiscreteDynamicsWorld::updateVehicles(float timeStep)
+void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
{
BEGIN_PROFILE("updateVehicles");
- for (unsigned int i=0;i<m_vehicles.size();i++)
+ for ( int i=0;i<m_vehicles.size();i++)
{
btRaycastVehicle* vehicle = m_vehicles[i];
vehicle->updateVehicle( timeStep);
@@ -338,11 +353,11 @@ void btDiscreteDynamicsWorld::updateVehicles(float timeStep)
END_PROFILE("updateVehicles");
}
-void btDiscreteDynamicsWorld::updateActivationState(float timeStep)
+void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
{
BEGIN_PROFILE("updateActivationState");
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -370,18 +385,21 @@ void btDiscreteDynamicsWorld::updateActivationState(float timeStep)
END_PROFILE("updateActivationState");
}
-void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint)
+void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
{
m_constraints.push_back(constraint);
+ if (disableCollisionsBetweenLinkedBodies)
+ {
+ constraint->getRigidBodyA().addConstraintRef(constraint);
+ constraint->getRigidBodyB().addConstraintRef(constraint);
+ }
}
void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
{
- std::vector<btTypedConstraint*>::iterator cit = std::find(m_constraints.begin(),m_constraints.end(),constraint);
- if (!(cit==m_constraints.end()))
- {
- m_constraints.erase(cit);
- }
+ m_constraints.remove(constraint);
+ constraint->getRigidBodyA().removeConstraintRef(constraint);
+ constraint->getRigidBodyB().removeConstraintRef(constraint);
}
void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle)
@@ -391,11 +409,7 @@ void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle)
void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle)
{
- std::vector<btRaycastVehicle*>::iterator vit = std::find(m_vehicles.begin(),m_vehicles.end(),vehicle);
- if (!(vit==m_vehicles.end()))
- {
- m_vehicles.erase(vit);
- }
+ m_vehicles.remove(vehicle);
}
inline int btGetConstraintIslandId(const btTypedConstraint* lhs)
@@ -409,19 +423,26 @@ inline int btGetConstraintIslandId(const btTypedConstraint* lhs)
}
-static bool btSortConstraintOnIslandPredicate(const btTypedConstraint* lhs, const btTypedConstraint* rhs)
+
+class btSortConstraintOnIslandPredicate
{
- int rIslandId0,lIslandId0;
- rIslandId0 = btGetConstraintIslandId(rhs);
- lIslandId0 = btGetConstraintIslandId(lhs);
- return lIslandId0 < rIslandId0;
-}
+ public:
+
+ bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs )
+ {
+ int rIslandId0,lIslandId0;
+ rIslandId0 = btGetConstraintIslandId(rhs);
+ lIslandId0 = btGetConstraintIslandId(lhs);
+ return lIslandId0 < rIslandId0;
+ }
+};
+
+
+
void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{
- BEGIN_PROFILE("solveConstraints");
-
struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
{
@@ -430,7 +451,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
btTypedConstraint** m_sortedConstraints;
int m_numConstraints;
btIDebugDraw* m_debugDrawer;
-
+ btStackAlloc* m_stackAlloc;
InplaceSolverIslandCallback(
@@ -438,17 +459,25 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
btConstraintSolver* solver,
btTypedConstraint** sortedConstraints,
int numConstraints,
- btIDebugDraw* debugDrawer)
+ btIDebugDraw* debugDrawer,
+ btStackAlloc* stackAlloc)
:m_solverInfo(solverInfo),
m_solver(solver),
m_sortedConstraints(sortedConstraints),
m_numConstraints(numConstraints),
- m_debugDrawer(debugDrawer)
+ m_debugDrawer(debugDrawer),
+ m_stackAlloc(stackAlloc)
{
}
- virtual void ProcessIsland(btPersistentManifold** manifolds,int numManifolds, int islandId)
+ InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
+ {
+ btAssert(0);
+ (void)other;
+ return *this;
+ }
+ virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
{
//also add all non-contact constraints/joints for this island
btTypedConstraint** startConstraint = 0;
@@ -473,36 +502,35 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
}
}
- m_solver->solveGroup( manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer);
+ m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc);
}
};
-
-
-
-
//sorted version of all btTypedConstraint, based on islandId
- std::vector<btTypedConstraint*> sortedConstraints;
+ btAlignedObjectArray<btTypedConstraint*> sortedConstraints;
sortedConstraints.resize( m_constraints.size());
int i;
for (i=0;i<getNumConstraints();i++)
{
sortedConstraints[i] = m_constraints[i];
}
+
+// assert(0);
+
- std::sort(sortedConstraints.begin(),sortedConstraints.end(),btSortConstraintOnIslandPredicate);
+
+ sortedConstraints.heapSort(btSortConstraintOnIslandPredicate());
btTypedConstraint** constraintsPtr = getNumConstraints() ? &sortedConstraints[0] : 0;
- InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer);
+ InplaceSolverIslandCallback solverCallback( solverInfo, m_constraintSolver, constraintsPtr,sortedConstraints.size(), m_debugDrawer,m_stackAlloc);
/// solve all the constraints for this island
m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback);
- END_PROFILE("solveConstraints");
}
@@ -545,37 +573,6 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands()
}
-static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVector3& to,const btVector3& color)
-{
-
- btVector3 halfExtents = (to-from)* 0.5f;
- btVector3 center = (to+from) *0.5f;
- int i,j;
-
- btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
- for (i=0;i<4;i++)
- {
- for (j=0;j<3;j++)
- {
- pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
- edgecoord[2]*halfExtents[2]);
- pa+=center;
-
- int othercoord = j%3;
- edgecoord[othercoord]*=-1.f;
- pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
- edgecoord[2]*halfExtents[2]);
- pb+=center;
-
- debugDrawer->drawLine(pa,pb,color);
- }
- edgecoord = btVector3(-1.f,-1.f,-1.f);
- if (i<3)
- edgecoord[i]*=-1.f;
- }
-
-
-}
void btDiscreteDynamicsWorld::updateAabbs()
{
@@ -583,7 +580,7 @@ void btDiscreteDynamicsWorld::updateAabbs()
btVector3 colorvec(1,0,0);
btTransform predictedTrans;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -594,34 +591,33 @@ void btDiscreteDynamicsWorld::updateAabbs()
{
btPoint3 minAabb,maxAabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
- btSimpleBroadphase* bp = (btSimpleBroadphase*)m_broadphasePairCache;
+ btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
//moving objects should be moderately sized, probably something wrong if not
- if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < 1e12f))
+ if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
{
bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb);
} else
{
//something went wrong, investigate
//this assert is unwanted in 3D modelers (danger of loosing work)
- assert(0);
body->setActivationState(DISABLE_SIMULATION);
static bool reportMe = true;
- if (reportMe)
+ if (reportMe && m_debugDrawer)
{
reportMe = false;
- printf("Overflow in AABB, object removed from simulation \n");
- printf("If you can reproduce this, please email bugs@continuousphysics.com\n");
- printf("Please include above information, your Platform, version of OS.\n");
- printf("Thanks.\n");
+ m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
+ m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
+ m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
+ m_debugDrawer->reportErrorWarning("Thanks.\n");
}
}
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
- DrawAabb(m_debugDrawer,minAabb,maxAabb,colorvec);
+ m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
}
}
}
@@ -630,11 +626,11 @@ void btDiscreteDynamicsWorld::updateAabbs()
END_PROFILE("updateAabbs");
}
-void btDiscreteDynamicsWorld::integrateTransforms(float timeStep)
+void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
{
BEGIN_PROFILE("integrateTransforms");
btTransform predictedTrans;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -652,10 +648,10 @@ void btDiscreteDynamicsWorld::integrateTransforms(float timeStep)
-void btDiscreteDynamicsWorld::predictUnconstraintMotion(float timeStep)
+void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
BEGIN_PROFILE("predictUnconstraintMotion");
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -676,8 +672,9 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(float timeStep)
}
-void btDiscreteDynamicsWorld::startProfiling(float timeStep)
+void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep)
{
+ (void)timeStep;
#ifdef USE_QUICKPROF
@@ -724,10 +721,10 @@ class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIn
public:
- DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color)
- : m_debugDrawer(debugDrawer),
- m_worldTrans(worldTrans),
- m_color(color)
+ DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) :
+ m_debugDrawer(debugDrawer),
+ m_color(color),
+ m_worldTrans(worldTrans)
{
}
@@ -738,6 +735,9 @@ public:
virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
{
+ (void)partId;
+ (void)triangleIndex;
+
btVector3 wv0,wv1,wv2;
wv0 = m_worldTrans*triangle[0];
wv1 = m_worldTrans*triangle[1];
@@ -748,10 +748,42 @@ public:
}
};
-
+void btDiscreteDynamicsWorld::debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
+{
+ btVector3 start = transform.getOrigin();
+
+ const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
+ const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
+ const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
+
+ // XY
+ getDebugDrawer()->drawLine(start-xoffs, start+yoffs, color);
+ getDebugDrawer()->drawLine(start+yoffs, start+xoffs, color);
+ getDebugDrawer()->drawLine(start+xoffs, start-yoffs, color);
+ getDebugDrawer()->drawLine(start-yoffs, start-xoffs, color);
+
+ // XZ
+ getDebugDrawer()->drawLine(start-xoffs, start+zoffs, color);
+ getDebugDrawer()->drawLine(start+zoffs, start+xoffs, color);
+ getDebugDrawer()->drawLine(start+xoffs, start-zoffs, color);
+ getDebugDrawer()->drawLine(start-zoffs, start-xoffs, color);
+
+ // YZ
+ getDebugDrawer()->drawLine(start-yoffs, start+zoffs, color);
+ getDebugDrawer()->drawLine(start+zoffs, start+yoffs, color);
+ getDebugDrawer()->drawLine(start+yoffs, start-zoffs, color);
+ getDebugDrawer()->drawLine(start-zoffs, start-yoffs, color);
+}
void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
{
+ // Draw a small simplex at the center of the object
+ {
+ btVector3 start = worldTransform.getOrigin();
+ getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0));
+ getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0));
+ getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1));
+ }
if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
{
@@ -771,25 +803,63 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
case SPHERE_SHAPE_PROXYTYPE:
{
const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
- float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
- btVector3 start = worldTransform.getOrigin();
- getDebugDrawer()->drawLine(start,start+worldTransform.getBasis() * btVector3(radius,0,0),color);
- getDebugDrawer()->drawLine(start,start+worldTransform.getBasis() * btVector3(0,radius,0),color);
- getDebugDrawer()->drawLine(start,start+worldTransform.getBasis() * btVector3(0,0,radius),color);
- //drawSphere
+ btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
+
+ debugDrawSphere(radius, worldTransform, color);
break;
}
case MULTI_SPHERE_SHAPE_PROXYTYPE:
+ {
+ const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
+
+ for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
+ {
+ btTransform childTransform = worldTransform;
+ childTransform.getOrigin() += multiSphereShape->getSpherePosition(i);
+ debugDrawSphere(multiSphereShape->getSphereRadius(i), childTransform, color);
+ }
+
+ break;
+ }
+ case CAPSULE_SHAPE_PROXYTYPE:
+ {
+ const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
+
+ btScalar radius = capsuleShape->getRadius();
+ btScalar halfHeight = capsuleShape->getHalfHeight();
+
+ // Draw the ends
+ {
+ btTransform childTransform = worldTransform;
+ childTransform.getOrigin() = worldTransform * btVector3(0,halfHeight,0);
+ debugDrawSphere(radius, childTransform, color);
+ }
+
+ {
+ btTransform childTransform = worldTransform;
+ childTransform.getOrigin() = worldTransform * btVector3(0,-halfHeight,0);
+ debugDrawSphere(radius, childTransform, color);
+ }
+
+ // Draw some additional lines
+ btVector3 start = worldTransform.getOrigin();
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(-radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(-radius,-halfHeight,0), color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(radius,-halfHeight,0), color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,-radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,-radius), color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,radius), color);
+
+ break;
+ }
case CONE_SHAPE_PROXYTYPE:
{
const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
- float radius = coneShape->getRadius();//+coneShape->getMargin();
- float height = coneShape->getHeight();//+coneShape->getMargin();
+ btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
+ btScalar height = coneShape->getHeight();//+coneShape->getMargin();
btVector3 start = worldTransform.getOrigin();
- getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0.f,0.f,0.5f*height),start+worldTransform.getBasis() * btVector3(radius,0.f,-0.5f*height),color);
- getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0.f,0.f,0.5f*height),start+worldTransform.getBasis() * btVector3(-radius,0.f,-0.5f*height),color);
- getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0.f,0.f,0.5f*height),start+worldTransform.getBasis() * btVector3(0.f,radius,-0.5f*height),color);
- getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0.f,0.f,0.5f*height),start+worldTransform.getBasis() * btVector3(0.f,-radius,-0.5f*height),color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(radius,btScalar(0.),btScalar(-0.5)*height),color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(-radius,btScalar(0.),btScalar(-0.5)*height),color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),radius,btScalar(-0.5)*height),color);
+ getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(btScalar(0.),btScalar(0.),btScalar(0.5)*height),start+worldTransform.getBasis() * btVector3(btScalar(0.),-radius,btScalar(-0.5)*height),color);
break;
}
@@ -797,8 +867,8 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
{
const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
int upAxis = cylinder->getUpAxis();
- float radius = cylinder->getRadius();
- float halfHeight = cylinder->getHalfExtents()[upAxis];
+ btScalar radius = cylinder->getRadius();
+ btScalar halfHeight = cylinder->getHalfExtents()[upAxis];
btVector3 start = worldTransform.getOrigin();
btVector3 offsetHeight(0,0,0);
offsetHeight[upAxis] = halfHeight;
@@ -811,15 +881,13 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
default:
{
- if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ if (shape->isConcave())
{
- btTriangleMeshShape* concaveMesh = (btTriangleMeshShape*) shape;
- //btVector3 aabbMax(1e30f,1e30f,1e30f);
- //btVector3 aabbMax(100,100,100);//1e30f,1e30f,1e30f);
-
+ btConcaveShape* concaveMesh = (btConcaveShape*) shape;
+
//todo pass camera, for some culling
- btVector3 aabbMax(1e30f,1e30f,1e30f);
- btVector3 aabbMin(-1e30f,-1e30f,-1e30f);
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
@@ -830,8 +898,8 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
{
btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
//todo: pass camera for some culling
- btVector3 aabbMax(1e30f,1e30f,1e30f);
- btVector3 aabbMin(-1e30f,-1e30f,-1e30f);
+ btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+ btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
//DebugDrawcallback drawCallback;
DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
convexMesh->getStridingMesh()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
index 8575f8506f1..83b90bfeebc 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
@@ -23,12 +23,12 @@ class btOverlappingPairCache;
class btConstraintSolver;
class btSimulationIslandManager;
class btTypedConstraint;
-#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+#include "../ConstraintSolver/btContactSolverInfo.h"
class btRaycastVehicle;
class btIDebugDraw;
+#include "../../LinearMath/btAlignedObjectArray.h"
-#include <vector>
///btDiscreteDynamicsWorld provides discrete rigid body simulation
///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
@@ -40,14 +40,14 @@ protected:
btSimulationIslandManager* m_islandManager;
- std::vector<btTypedConstraint*> m_constraints;
+ btAlignedObjectArray<btTypedConstraint*> m_constraints;
btIDebugDraw* m_debugDrawer;
btVector3 m_gravity;
//for variable timesteps
- float m_localTime;
+ btScalar m_localTime;
//for variable timesteps
bool m_ownsIslandManager;
@@ -56,30 +56,31 @@ protected:
btContactSolverInfo m_solverInfo;
- std::vector<btRaycastVehicle*> m_vehicles;
+ btAlignedObjectArray<btRaycastVehicle*> m_vehicles;
int m_profileTimings;
- void predictUnconstraintMotion(float timeStep);
+ void predictUnconstraintMotion(btScalar timeStep);
- void integrateTransforms(float timeStep);
+ void integrateTransforms(btScalar timeStep);
void calculateSimulationIslands();
void solveConstraints(btContactSolverInfo& solverInfo);
- void updateActivationState(float timeStep);
+ void updateActivationState(btScalar timeStep);
- void updateVehicles(float timeStep);
+ void updateVehicles(btScalar timeStep);
- void startProfiling(float timeStep);
+ void startProfiling(btScalar timeStep);
- virtual void internalSingleStepSimulation( float timeStep);
+ virtual void internalSingleStepSimulation( btScalar timeStep);
void synchronizeMotionStates();
- void saveKinematicState(float timeStep);
+ void saveKinematicState(btScalar timeStep);
+ void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
public:
@@ -90,11 +91,11 @@ public:
virtual ~btDiscreteDynamicsWorld();
///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
- virtual int stepSimulation( float timeStep,int maxSubSteps=1, float fixedTimeStep=1.f/60.f);
+ virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
virtual void updateAabbs();
- void addConstraint(btTypedConstraint* constraint);
+ void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
void removeConstraint(btTypedConstraint* constraint);
@@ -131,6 +132,8 @@ public:
virtual void addRigidBody(btRigidBody* body);
+ virtual void addRigidBody(btRigidBody* body, short group, short mask);
+
virtual void removeRigidBody(btRigidBody* body);
void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
index 617ed98d2af..65b63fad4b5 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef BT_DYNAMICS_WORLD_H
#define BT_DYNAMICS_WORLD_H
-#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "../../BulletCollision/CollisionDispatch/btCollisionWorld.h"
class btTypedConstraint;
class btRaycastVehicle;
class btConstraintSolver;
@@ -39,17 +39,17 @@ class btDynamicsWorld : public btCollisionWorld
///stepSimulation proceeds the simulation over timeStep units
///if maxSubSteps > 0, it will interpolate time steps
- virtual int stepSimulation( float timeStep,int maxSubSteps=1, float fixedTimeStep=1.f/60.f)=0;
+ virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0;
virtual void updateAabbs() = 0;
- virtual void addConstraint(btTypedConstraint* constraint) {};
+ virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) { (void)constraint;};
- virtual void removeConstraint(btTypedConstraint* constraint) {};
+ virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;};
- virtual void addVehicle(btRaycastVehicle* vehicle) {};
+ virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
- virtual void removeVehicle(btRaycastVehicle* vehicle) {};
+ virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
virtual void setDebugDrawer(btIDebugDraw* debugDrawer) = 0;
@@ -68,9 +68,9 @@ class btDynamicsWorld : public btCollisionWorld
virtual int getNumConstraints() const { return 0; }
- virtual btTypedConstraint* getConstraint(int index) { return 0; }
+ virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; }
- virtual const btTypedConstraint* getConstraint(int index) const { return 0; }
+ virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; }
};
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
index 705c023d3a0..9ed3579d89c 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -16,28 +16,29 @@ subject to the following restrictions:
#include "btRigidBody.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "LinearMath/btMinMax.h"
-#include <LinearMath/btTransformUtil.h>
-#include <LinearMath/btMotionState.h>
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btMotionState.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
-float gLinearAirDamping = 1.f;
+btScalar gLinearAirDamping = btScalar(1.);
//'temporarily' global variables
-float gDeactivationTime = 2.f;
+btScalar gDeactivationTime = btScalar(2.);
bool gDisableDeactivation = false;
-float gLinearSleepingThreshold = 0.8f;
-float gAngularSleepingThreshold = 1.0f;
+btScalar gLinearSleepingThreshold = btScalar(0.8);
+btScalar gAngularSleepingThreshold = btScalar(1.0);
static int uniqueId = 0;
-btRigidBody::btRigidBody(float mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
+btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
:
- m_gravity(0.0f, 0.0f, 0.0f),
- m_totalForce(0.0f, 0.0f, 0.0f),
- m_totalTorque(0.0f, 0.0f, 0.0f),
- m_linearVelocity(0.0f, 0.0f, 0.0f),
- m_angularVelocity(0.f,0.f,0.f),
- m_angularFactor(1.f),
- m_linearDamping(0.f),
- m_angularDamping(0.5f),
+ m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)),
+ m_angularFactor(btScalar(1.)),
+ m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_linearDamping(btScalar(0.)),
+ m_angularDamping(btScalar(0.5)),
m_optionalMotionState(motionState),
m_contactSolverType(0),
m_frictionSolverType(0)
@@ -72,15 +73,15 @@ btRigidBody::btRigidBody(float mass, btMotionState* motionState, btCollisionShap
}
#ifdef OBSOLETE_MOTIONSTATE_LESS
-btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
+btRigidBody::btRigidBody( btScalar mass,const btTransform& worldTransform,btCollisionShape* collisionShape,const btVector3& localInertia,btScalar linearDamping,btScalar angularDamping,btScalar friction,btScalar restitution)
:
- m_gravity(0.0f, 0.0f, 0.0f),
- m_totalForce(0.0f, 0.0f, 0.0f),
- m_totalTorque(0.0f, 0.0f, 0.0f),
- m_linearVelocity(0.0f, 0.0f, 0.0f),
- m_angularVelocity(0.f,0.f,0.f),
- m_linearDamping(0.f),
- m_angularDamping(0.5f),
+ m_gravity(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_totalForce(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_totalTorque(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_linearVelocity(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+ m_angularVelocity(btScalar(0.),btScalar(0.),btScalar(0.)),
+ m_linearDamping(btScalar(0.)),
+ m_angularDamping(btScalar(0.5)),
m_optionalMotionState(0),
m_contactSolverType(0),
m_frictionSolverType(0)
@@ -110,16 +111,18 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi
#endif //OBSOLETE_MOTIONSTATE_LESS
+
+
//#define EXPERIMENTAL_JITTER_REMOVAL 1
#ifdef EXPERIMENTAL_JITTER_REMOVAL
//Bullet 2.20b has experimental damping code to reduce jitter just before objects fall asleep/deactivate
//doesn't work very well yet (value 0 disabled this damping)
//note there this influences deactivation thresholds!
-float gClippedAngvelThresholdSqr = 0.01f;
-float gClippedLinearThresholdSqr = 0.01f;
+btScalar gClippedAngvelThresholdSqr = btScalar(0.01);
+btScalar gClippedLinearThresholdSqr = btScalar(0.01);
#endif //EXPERIMENTAL_JITTER_REMOVAL
-float gJitterVelocityDampingFactor = 1.f;
+btScalar gJitterVelocityDampingFactor = btScalar(0.7);
void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform)
{
@@ -144,7 +147,7 @@ void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& pred
void btRigidBody::saveKinematicState(btScalar timeStep)
{
//todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
- if (timeStep != 0.f)
+ if (timeStep != btScalar(0.))
{
//if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
if (getMotionState())
@@ -169,9 +172,9 @@ void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
void btRigidBody::setGravity(const btVector3& acceleration)
{
- if (m_inverseMass != 0.0f)
+ if (m_inverseMass != btScalar(0.0))
{
- m_gravity = acceleration * (1.0f / m_inverseMass);
+ m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
}
}
@@ -182,8 +185,8 @@ void btRigidBody::setGravity(const btVector3& acceleration)
void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
{
- m_linearDamping = GEN_clamped(lin_damping, 0.0f, 1.0f);
- m_angularDamping = GEN_clamped(ang_damping, 0.0f, 1.0f);
+ m_linearDamping = GEN_clamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+ m_angularDamping = GEN_clamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
}
@@ -198,36 +201,36 @@ void btRigidBody::applyForces(btScalar step)
applyCentralForce(m_gravity);
- m_linearVelocity *= GEN_clamped((1.f - step * gLinearAirDamping * m_linearDamping), 0.0f, 1.0f);
- m_angularVelocity *= GEN_clamped((1.f - step * m_angularDamping), 0.0f, 1.0f);
+ m_linearVelocity *= GEN_clamped((btScalar(1.) - step * gLinearAirDamping * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+ m_angularVelocity *= GEN_clamped((btScalar(1.) - step * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
#define FORCE_VELOCITY_DAMPING 1
#ifdef FORCE_VELOCITY_DAMPING
- float speed = m_linearVelocity.length();
+ btScalar speed = m_linearVelocity.length();
if (speed < m_linearDamping)
{
- float dampVel = 0.005f;
+ btScalar dampVel = btScalar(0.005);
if (speed > dampVel)
{
btVector3 dir = m_linearVelocity.normalized();
m_linearVelocity -= dir * dampVel;
} else
{
- m_linearVelocity.setValue(0.f,0.f,0.f);
+ m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
}
- float angSpeed = m_angularVelocity.length();
+ btScalar angSpeed = m_angularVelocity.length();
if (angSpeed < m_angularDamping)
{
- float angDampVel = 0.005f;
+ btScalar angDampVel = btScalar(0.005);
if (angSpeed > angDampVel)
{
btVector3 dir = m_angularVelocity.normalized();
m_angularVelocity -= dir * angDampVel;
} else
{
- m_angularVelocity.setValue(0.f,0.f,0.f);
+ m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
}
#endif //FORCE_VELOCITY_DAMPING
@@ -242,19 +245,19 @@ void btRigidBody::proceedToTransform(const btTransform& newTrans)
void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
{
- if (mass == 0.f)
+ if (mass == btScalar(0.))
{
m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
- m_inverseMass = 0.f;
+ m_inverseMass = btScalar(0.);
} else
{
m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT);
- m_inverseMass = 1.0f / mass;
+ m_inverseMass = btScalar(1.0) / mass;
}
- m_invInertiaLocal.setValue(inertia[0] != 0.0f ? 1.0f / inertia[0]: 0.0f,
- inertia[1] != 0.0f ? 1.0f / inertia[1]: 0.0f,
- inertia[2] != 0.0f ? 1.0f / inertia[2]: 0.0f);
+ m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
+ inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
+ inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
}
@@ -276,7 +279,7 @@ void btRigidBody::integrateVelocities(btScalar step)
#define MAX_ANGVEL SIMD_HALF_PI
/// clamp angular velocity. collision calculations will fail on higher angular velocities
- float angvel = m_angularVelocity.length();
+ btScalar angvel = m_angularVelocity.length();
if (angvel*step > MAX_ANGVEL)
{
m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
@@ -295,7 +298,14 @@ btQuaternion btRigidBody::getOrientation() const
void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
{
- m_interpolationWorldTransform = m_worldTransform;
+
+ if (isStaticOrKinematicObject())
+ {
+ m_interpolationWorldTransform = m_worldTransform;
+ } else
+ {
+ m_interpolationWorldTransform = xform;
+ }
m_interpolationLinearVelocity = getLinearVelocity();
m_interpolationAngularVelocity = getAngularVelocity();
m_worldTransform = xform;
@@ -303,4 +313,33 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
}
+bool btRigidBody::checkCollideWithOverride(btCollisionObject* co)
+{
+ btRigidBody* otherRb = btRigidBody::upcast(co);
+ if (!otherRb)
+ return true;
+
+ for (int i = 0; i < m_constraintRefs.size(); ++i)
+ {
+ btTypedConstraint* c = m_constraintRefs[i];
+ if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
+ return false;
+ }
+
+ return true;
+}
+
+void btRigidBody::addConstraintRef(btTypedConstraint* c)
+{
+ int index = m_constraintRefs.findLinearSearch(c);
+ if (index == m_constraintRefs.size())
+ m_constraintRefs.push_back(c);
+
+ m_checkCollideWith = true;
+}
+void btRigidBody::removeConstraintRef(btTypedConstraint* c)
+{
+ m_constraintRefs.remove(c);
+ m_checkCollideWith = m_constraintRefs.size() > 0;
+}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
index 43869363cdf..0707595d48e 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
@@ -16,26 +16,23 @@ subject to the following restrictions:
#ifndef RIGIDBODY_H
#define RIGIDBODY_H
-#include <vector>
-#include <LinearMath/btPoint3.h>
-#include <LinearMath/btTransform.h>
-#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-
-
-#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
+#include "../../LinearMath/btPoint3.h"
+#include "../../LinearMath/btTransform.h"
+#include "../../BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "../../BulletCollision/CollisionDispatch/btCollisionObject.h"
class btCollisionShape;
class btMotionState;
+class btTypedConstraint;
+extern btScalar gLinearAirDamping;
-extern float gLinearAirDamping;
-extern bool gUseEpa;
-
-extern float gDeactivationTime;
+extern btScalar gDeactivationTime;
extern bool gDisableDeactivation;
-extern float gLinearSleepingThreshold;
-extern float gAngularSleepingThreshold;
+extern btScalar gLinearSleepingThreshold;
+extern btScalar gAngularSleepingThreshold;
/// btRigidBody class for btRigidBody Dynamics
@@ -61,14 +58,17 @@ class btRigidBody : public btCollisionObject
//m_optionalMotionState allows to automatic synchronize the world transform for active objects
btMotionState* m_optionalMotionState;
+ //keep track of typed constraints referencing this rigid body
+ btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
+
public:
#ifdef OBSOLETE_MOTIONSTATE_LESS
//not supported, please use btMotionState
- btRigidBody(float mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
+ btRigidBody(btScalar mass, const btTransform& worldTransform, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.));
#endif //OBSOLETE_MOTIONSTATE_LESS
- btRigidBody(float mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=0.f,btScalar angularDamping=0.f,btScalar friction=0.5f,btScalar restitution=0.f);
+ btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0),btScalar linearDamping=btScalar(0.),btScalar angularDamping=btScalar(0.),btScalar friction=btScalar(0.5),btScalar restitution=btScalar(0.));
void proceedToTransform(const btTransform& newTrans);
@@ -157,7 +157,7 @@ public:
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
{
- if (m_inverseMass != 0.f)
+ if (m_inverseMass != btScalar(0.))
{
applyCentralImpulse(impulse);
if (m_angularFactor)
@@ -168,9 +168,9 @@ public:
}
//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
- inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,float impulseMagnitude)
+ inline void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
{
- if (m_inverseMass != 0.f)
+ if (m_inverseMass != btScalar(0.))
{
m_linearVelocity += linearComponent*impulseMagnitude;
if (m_angularFactor)
@@ -182,8 +182,8 @@ public:
void clearForces()
{
- m_totalForce.setValue(0.0f, 0.0f, 0.0f);
- m_totalTorque.setValue(0.0f, 0.0f, 0.0f);
+ m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+ m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
void updateInertiaTensor();
@@ -238,7 +238,7 @@ public:
- inline float computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
+ inline btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
{
btVector3 r0 = pos - getCenterOfMassPosition();
@@ -250,13 +250,13 @@ public:
}
- inline float computeAngularImpulseDenominator(const btVector3& axis) const
+ inline btScalar computeAngularImpulseDenominator(const btVector3& axis) const
{
btVector3 vec = axis * getInvInertiaTensorWorld();
return axis.dot(vec);
}
- inline void updateDeactivation(float timeStep)
+ inline void updateDeactivation(btScalar timeStep)
{
if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
return;
@@ -267,7 +267,7 @@ public:
m_deactivationTime += timeStep;
} else
{
- m_deactivationTime=0.f;
+ m_deactivationTime=btScalar(0.);
setActivationState(0);
}
@@ -280,7 +280,7 @@ public:
return false;
//disable deactivation
- if (gDisableDeactivation || (gDeactivationTime == 0.f))
+ if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
return false;
if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
@@ -328,11 +328,11 @@ public:
int m_contactSolverType;
int m_frictionSolverType;
- void setAngularFactor(float angFac)
+ void setAngularFactor(btScalar angFac)
{
m_angularFactor = angFac;
}
- float getAngularFactor() const
+ btScalar getAngularFactor() const
{
return m_angularFactor;
}
@@ -343,6 +343,11 @@ public:
return (getBroadphaseProxy() != 0);
}
+ virtual bool checkCollideWithOverride(btCollisionObject* co);
+
+ void addConstraintRef(btTypedConstraint* c);
+ void removeConstraintRef(btTypedConstraint* c);
+
int m_debugBodyId;
};
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
index fe0124c041a..4ebcb8e7517 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
@@ -22,6 +22,14 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+/*
+ Make sure this dummy function never changes so that it
+ can be used by probes that are checking whether the
+ library is actually installed.
+*/
+extern "C" void btBulletDynamicsProbe () {}
+
+
btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver)
@@ -41,8 +49,12 @@ btSimpleDynamicsWorld::~btSimpleDynamicsWorld()
delete m_constraintSolver;
}
-int btSimpleDynamicsWorld::stepSimulation( float timeStep,int maxSubSteps, float fixedTimeStep)
+int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
{
+ (void)fixedTimeStep;
+ (void)maxSubSteps;
+
+
///apply gravity, predict motion
predictUnconstraintMotion(timeStep);
@@ -63,7 +75,7 @@ int btSimpleDynamicsWorld::stepSimulation( float timeStep,int maxSubSteps, floa
btContactSolverInfo infoGlobal;
infoGlobal.m_timeStep = timeStep;
- m_constraintSolver->solveGroup(manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer);
+ m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc);
}
///integrate transforms
@@ -81,7 +93,7 @@ int btSimpleDynamicsWorld::stepSimulation( float timeStep,int maxSubSteps, floa
void btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
{
m_gravity = gravity;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -110,7 +122,7 @@ void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
void btSimpleDynamicsWorld::updateAabbs()
{
btTransform predictedTrans;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -127,10 +139,10 @@ void btSimpleDynamicsWorld::updateAabbs()
}
}
-void btSimpleDynamicsWorld::integrateTransforms(float timeStep)
+void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
{
btTransform predictedTrans;
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -147,9 +159,9 @@ void btSimpleDynamicsWorld::integrateTransforms(float timeStep)
-void btSimpleDynamicsWorld::predictUnconstraintMotion(float timeStep)
+void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
@@ -172,7 +184,7 @@ void btSimpleDynamicsWorld::predictUnconstraintMotion(float timeStep)
void btSimpleDynamicsWorld::synchronizeMotionStates()
{
//todo: iterate over awake simulation islands!
- for (unsigned int i=0;i<m_collisionObjects.size();i++)
+ for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
index cdc0c5559f6..25f4ccd8e68 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
@@ -37,9 +37,9 @@ protected:
btIDebugDraw* m_debugDrawer;
- void predictUnconstraintMotion(float timeStep);
+ void predictUnconstraintMotion(btScalar timeStep);
- void integrateTransforms(float timeStep);
+ void integrateTransforms(btScalar timeStep);
btVector3 m_gravity;
@@ -53,7 +53,7 @@ public:
virtual ~btSimpleDynamicsWorld();
///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead
- virtual int stepSimulation( float timeStep,int maxSubSteps=1, float fixedTimeStep=1.f/60.f);
+ virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
{
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
index c85fead5334..d53de7f3687 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
@@ -18,6 +18,7 @@
#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
#include "btVehicleRaycaster.h"
#include "btWheelInfo.h"
+#include "LinearMath/btMinMax.h"
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
@@ -28,7 +29,7 @@ static btRigidBody s_fixedObject( 0,0,0);
btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster )
:m_vehicleRaycaster(raycaster),
-m_pitchControl(0.f)
+m_pitchControl(btScalar(0.))
{
m_chassisBody = chassis;
m_indexRightAxis = 0;
@@ -40,8 +41,9 @@ m_pitchControl(0.f)
void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning)
{
- m_currentVehicleSpeedKmHour = 0.f;
- m_steeringValue = 0.f;
+ (void)tuning;
+ m_currentVehicleSpeedKmHour = btScalar(0.);
+ m_steeringValue = btScalar(0.);
}
@@ -105,12 +107,12 @@ void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedT
// up.normalize();
//rotate around steering over de wheelAxleWS
- float steering = wheel.m_steering;
+ btScalar steering = wheel.m_steering;
btQuaternion steeringOrn(up,steering);//wheel.m_steering);
btMatrix3x3 steeringMat(steeringOrn);
- btQuaternion rotatingOrn(right,wheel.m_rotation);
+ btQuaternion rotatingOrn(right,-wheel.m_rotation);
btMatrix3x3 rotatingMat(rotatingOrn);
btMatrix3x3 basis2(
@@ -133,11 +135,11 @@ void btRaycastVehicle::resetSuspension()
{
btWheelInfo& wheel = m_wheelInfo[i];
wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength();
- wheel.m_suspensionRelativeVelocity = 0.0f;
+ wheel.m_suspensionRelativeVelocity = btScalar(0.0);
wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS;
- //wheel_info.setContactFriction(0.0f);
- wheel.m_clippedInvContactDotSuspension = 1.0f;
+ //wheel_info.setContactFriction(btScalar(0.0));
+ wheel.m_clippedInvContactDotSuspension = btScalar(1.0);
}
}
@@ -170,7 +172,7 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
const btVector3& target = wheel.m_raycastInfo.m_contactPointWS;
- btScalar param = 0.f;
+ btScalar param = btScalar(0.);
btVehicleRaycaster::btVehicleRaycasterResult rayResults;
@@ -195,8 +197,8 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius;
//clamp on max suspension travel
- float minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*0.01f;
- float maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*0.01f;
+ btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01);
+ btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01);
if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength)
{
wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
@@ -217,14 +219,14 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );
- if ( denominator >= -0.1f)
+ if ( denominator >= btScalar(-0.1))
{
- wheel.m_suspensionRelativeVelocity = 0.0f;
- wheel.m_clippedInvContactDotSuspension = 1.0f / 0.1f;
+ wheel.m_suspensionRelativeVelocity = btScalar(0.0);
+ wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1);
}
else
{
- btScalar inv = -1.f / denominator;
+ btScalar inv = btScalar(-1.) / denominator;
wheel.m_suspensionRelativeVelocity = projVel * inv;
wheel.m_clippedInvContactDotSuspension = inv;
}
@@ -233,9 +235,9 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
{
//put wheel info as in rest position
wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength();
- wheel.m_suspensionRelativeVelocity = 0.0f;
+ wheel.m_suspensionRelativeVelocity = btScalar(0.0);
wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS;
- wheel.m_clippedInvContactDotSuspension = 1.0f;
+ wheel.m_clippedInvContactDotSuspension = btScalar(1.0);
}
return depth;
@@ -267,7 +269,7 @@ void btRaycastVehicle::updateVehicle( btScalar step )
}
- m_currentVehicleSpeedKmHour = 3.6f * getRigidBody()->getLinearVelocity().length();
+ m_currentVehicleSpeedKmHour = btScalar(3.6) * getRigidBody()->getLinearVelocity().length();
const btTransform& chassisTrans = getChassisWorldTransform();
@@ -276,9 +278,9 @@ void btRaycastVehicle::updateVehicle( btScalar step )
chassisTrans.getBasis()[1][m_indexForwardAxis],
chassisTrans.getBasis()[2][m_indexForwardAxis]);
- if (forwardW.dot(getRigidBody()->getLinearVelocity()) < 0.f)
+ if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.))
{
- m_currentVehicleSpeedKmHour *= -1.f;
+ m_currentVehicleSpeedKmHour *= btScalar(-1.);
}
//
@@ -300,9 +302,9 @@ void btRaycastVehicle::updateVehicle( btScalar step )
//apply suspension force
btWheelInfo& wheel = m_wheelInfo[i];
- float suspensionForce = wheel.m_wheelsSuspensionForce;
+ btScalar suspensionForce = wheel.m_wheelsSuspensionForce;
- float gMaxSuspensionForce = 6000.f;
+ btScalar gMaxSuspensionForce = btScalar(6000.);
if (suspensionForce > gMaxSuspensionForce)
{
suspensionForce = gMaxSuspensionForce;
@@ -347,7 +349,7 @@ void btRaycastVehicle::updateVehicle( btScalar step )
wheel.m_rotation += wheel.m_deltaRotation;
}
- wheel.m_deltaRotation *= 0.99f;//damping of rotation when not in contact
+ wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact
}
@@ -394,17 +396,18 @@ btWheelInfo& btRaycastVehicle::getWheelInfo(int index)
return m_wheelInfo[index];
}
-void btRaycastVehicle::setBrake(float brake,int wheelIndex)
+void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex)
{
btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels()));
- getWheelInfo(wheelIndex).m_brake;
+ getWheelInfo(wheelIndex).m_brake = brake;
}
void btRaycastVehicle::updateSuspension(btScalar deltaTime)
{
+ (void)deltaTime;
- btScalar chassisMass = 1.f / m_chassisBody->getInvMass();
+ btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass();
for (int w_it=0; w_it<getNumWheels(); w_it++)
{
@@ -429,7 +432,7 @@ void btRaycastVehicle::updateSuspension(btScalar deltaTime)
btScalar projected_rel_vel = wheel_info.m_suspensionRelativeVelocity;
{
btScalar susp_damping;
- if ( projected_rel_vel < 0.0f )
+ if ( projected_rel_vel < btScalar(0.0) )
{
susp_damping = wheel_info.m_wheelsDampingCompression;
}
@@ -443,20 +446,77 @@ void btRaycastVehicle::updateSuspension(btScalar deltaTime)
// RESULT
wheel_info.m_wheelsSuspensionForce = force * chassisMass;
- if (wheel_info.m_wheelsSuspensionForce < 0.f)
+ if (wheel_info.m_wheelsSuspensionForce < btScalar(0.))
{
- wheel_info.m_wheelsSuspensionForce = 0.f;
+ wheel_info.m_wheelsSuspensionForce = btScalar(0.);
}
}
else
{
- wheel_info.m_wheelsSuspensionForce = 0.0f;
+ wheel_info.m_wheelsSuspensionForce = btScalar(0.0);
}
}
}
-float sideFrictionStiffness2 = 1.0f;
+
+struct btWheelContactPoint
+{
+ btRigidBody* m_body0;
+ btRigidBody* m_body1;
+ btVector3 m_frictionPositionWorld;
+ btVector3 m_frictionDirectionWorld;
+ btScalar m_jacDiagABInv;
+ btScalar m_maxImpulse;
+
+
+ btWheelContactPoint(btRigidBody* body0,btRigidBody* body1,const btVector3& frictionPosWorld,const btVector3& frictionDirectionWorld, btScalar maxImpulse)
+ :m_body0(body0),
+ m_body1(body1),
+ m_frictionPositionWorld(frictionPosWorld),
+ m_frictionDirectionWorld(frictionDirectionWorld),
+ m_maxImpulse(maxImpulse)
+ {
+ btScalar denom0 = body0->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
+ btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
+ btScalar relaxation = 1.f;
+ m_jacDiagABInv = relaxation/(denom0+denom1);
+ }
+
+
+
+};
+
+btScalar calcRollingFriction(btWheelContactPoint& contactPoint)
+{
+
+ btScalar j1=0.f;
+
+ const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld;
+
+ btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition();
+ btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition();
+
+ btScalar maxImpulse = contactPoint.m_maxImpulse;
+
+ btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1);
+ btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2);
+ btVector3 vel = vel1 - vel2;
+
+ btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel);
+
+ // calculate j that moves us to zero relative velocity
+ j1 = -vrel * contactPoint.m_jacDiagABInv;
+ GEN_set_min(j1, maxImpulse);
+ GEN_set_max(j1, -maxImpulse);
+
+ return j1;
+}
+
+
+
+
+btScalar sideFrictionStiffness2 = btScalar(1.0);
void btRaycastVehicle::updateFriction(btScalar timeStep)
{
@@ -481,8 +541,8 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
if (groundObject)
numWheelsOnGround++;
- sideImpulse[i] = 0.f;
- forwardImpulse[i] = 0.f;
+ sideImpulse[i] = btScalar(0.);
+ forwardImpulse[i] = btScalar(0.);
}
@@ -517,7 +577,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
resolveSingleBilateral(*m_chassisBody, wheelInfo.m_raycastInfo.m_contactPointWS,
*groundObject, wheelInfo.m_raycastInfo.m_contactPointWS,
- 0.f, axle[i],sideImpulse[i],timeStep);
+ btScalar(0.), axle[i],sideImpulse[i],timeStep);
sideImpulse[i] *= sideFrictionStiffness2;
@@ -527,7 +587,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
}
}
- btScalar sideFactor = 1.f;
+ btScalar sideFactor = btScalar(1.);
btScalar fwdFactor = 0.5;
bool sliding = false;
@@ -537,25 +597,46 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
btWheelInfo& wheelInfo = m_wheelInfo[wheel];
class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
+ btScalar rollingFriction = 0.f;
- forwardImpulse[wheel] = 0.f;
- m_wheelInfo[wheel].m_skidInfo= 1.f;
+ if (groundObject)
+ {
+ if (wheelInfo.m_engineForce != 0.f)
+ {
+ rollingFriction = wheelInfo.m_engineForce* timeStep;
+ } else
+ {
+ btScalar defaultRollingFrictionImpulse = 0.f;
+ btScalar maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
+ btWheelContactPoint contactPt(m_chassisBody,groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,forwardWS[wheel],maxImpulse);
+ rollingFriction = calcRollingFriction(contactPt);
+ }
+ }
+
+ //switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break)
+
+
+
+
+ forwardImpulse[wheel] = btScalar(0.);
+ m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
if (groundObject)
{
- m_wheelInfo[wheel].m_skidInfo= 1.f;
+ m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
btScalar maximp = wheelInfo.m_wheelsSuspensionForce * timeStep * wheelInfo.m_frictionSlip;
btScalar maximpSide = maximp;
btScalar maximpSquared = maximp * maximpSide;
+
- forwardImpulse[wheel] = wheelInfo.m_engineForce* timeStep;
+ forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;
- float x = (forwardImpulse[wheel] ) * fwdFactor;
- float y = (sideImpulse[wheel] ) * sideFactor;
+ btScalar x = (forwardImpulse[wheel] ) * fwdFactor;
+ btScalar y = (sideImpulse[wheel] ) * sideFactor;
- float impulseSquared = (x*x + y*y);
+ btScalar impulseSquared = (x*x + y*y);
if (impulseSquared > maximpSquared)
{
@@ -577,9 +658,9 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
{
for (int wheel = 0;wheel < getNumWheels(); wheel++)
{
- if (sideImpulse[wheel] != 0.f)
+ if (sideImpulse[wheel] != btScalar(0.))
{
- if (m_wheelInfo[wheel].m_skidInfo< 1.f)
+ if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.))
{
forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
@@ -597,11 +678,11 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS -
m_chassisBody->getCenterOfMassPosition();
- if (forwardImpulse[wheel] != 0.f)
+ if (forwardImpulse[wheel] != btScalar(0.))
{
m_chassisBody->applyImpulse(forwardWS[wheel]*(forwardImpulse[wheel]),rel_pos);
}
- if (sideImpulse[wheel] != 0.f)
+ if (sideImpulse[wheel] != btScalar(0.))
{
class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject;
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
index fa961e468d7..f4249599615 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
@@ -11,11 +11,11 @@
#ifndef RAYCASTVEHICLE_H
#define RAYCASTVEHICLE_H
-#include "BulletDynamics/Dynamics/btRigidBody.h"
-#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "../Dynamics/btRigidBody.h"
+#include "../ConstraintSolver/btTypedConstraint.h"
#include "btVehicleRaycaster.h"
class btDynamicsWorld;
-#include "LinearMath/btAlignedObjectArray.h"
+#include "../../LinearMath/btAlignedObjectArray.h"
#include "btWheelInfo.h"
class btVehicleTuning;
@@ -29,18 +29,18 @@ public:
public:
btVehicleTuning()
- :m_suspensionStiffness(5.88f),
- m_suspensionCompression(0.83f),
- m_suspensionDamping(0.88f),
- m_maxSuspensionTravelCm(500.f),
- m_frictionSlip(10.5f)
+ :m_suspensionStiffness(btScalar(5.88)),
+ m_suspensionCompression(btScalar(0.83)),
+ m_suspensionDamping(btScalar(0.88)),
+ m_maxSuspensionTravelCm(btScalar(500.)),
+ m_frictionSlip(btScalar(10.5))
{
}
- float m_suspensionStiffness;
- float m_suspensionCompression;
- float m_suspensionDamping;
- float m_maxSuspensionTravelCm;
- float m_frictionSlip;
+ btScalar m_suspensionStiffness;
+ btScalar m_suspensionCompression;
+ btScalar m_suspensionDamping;
+ btScalar m_maxSuspensionTravelCm;
+ btScalar m_frictionSlip;
};
private:
@@ -48,9 +48,9 @@ private:
btScalar m_tau;
btScalar m_damping;
btVehicleRaycaster* m_vehicleRaycaster;
- float m_pitchControl;
- float m_steeringValue;
- float m_currentVehicleSpeedKmHour;
+ btScalar m_pitchControl;
+ btScalar m_steeringValue;
+ btScalar m_currentVehicleSpeedKmHour;
btRigidBody* m_chassisBody;
@@ -105,9 +105,9 @@ public:
void updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true);
- void setBrake(float brake,int wheelIndex);
+ void setBrake(btScalar brake,int wheelIndex);
- void setPitchControl(float pitch)
+ void setPitchControl(btScalar pitch)
{
m_pitchControl = pitch;
}
@@ -142,6 +142,26 @@ public:
return m_indexForwardAxis;
}
+
+ ///Worldspace forward vector
+ btVector3 getForwardVector() const
+ {
+ const btTransform& chassisTrans = getChassisWorldTransform();
+
+ btVector3 forwardW (
+ chassisTrans.getBasis()[0][m_indexForwardAxis],
+ chassisTrans.getBasis()[1][m_indexForwardAxis],
+ chassisTrans.getBasis()[2][m_indexForwardAxis]);
+
+ return forwardW;
+ }
+
+ ///Velocity of vehicle (positive if velocity vector has same direction as foward vector)
+ btScalar getCurrentSpeedKmHour() const
+ {
+ return m_currentVehicleSpeedKmHour;
+ }
+
virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex)
{
m_indexRightAxis = rightIndex;
@@ -156,6 +176,7 @@ public:
virtual void solveConstraint(btScalar timeStep)
{
+ (void)timeStep;
//not yet
}
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h
index 5be3693fe73..64a47fcaada 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btVehicleRaycaster.h
@@ -11,7 +11,7 @@
#ifndef VEHICLE_RAYCASTER_H
#define VEHICLE_RAYCASTER_H
-#include "LinearMath/btVector3.h"
+#include "../../LinearMath/btVector3.h"
/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting
struct btVehicleRaycaster
@@ -21,7 +21,7 @@ virtual ~btVehicleRaycaster()
}
struct btVehicleRaycasterResult
{
- btVehicleRaycasterResult() :m_distFraction(-1.f){};
+ btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){};
btVector3 m_hitPointInWorld;
btVector3 m_hitNormalInWorld;
btScalar m_distFraction;
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp
index 43baf56edbc..ef93c16fffc 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.cpp
@@ -21,6 +21,7 @@ btScalar btWheelInfo::getSuspensionRestLength() const
void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo)
{
+ (void)raycastInfo;
if (m_raycastInfo.m_isInContact)
@@ -31,14 +32,14 @@ void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInf
btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition();
chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos );
btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );
- if ( project >= -0.1f)
+ if ( project >= btScalar(-0.1))
{
- m_suspensionRelativeVelocity = 0.0f;
- m_clippedInvContactDotSuspension = 1.0f / 0.1f;
+ m_suspensionRelativeVelocity = btScalar(0.0);
+ m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1);
}
else
{
- btScalar inv = -1.f / project;
+ btScalar inv = btScalar(-1.) / project;
m_suspensionRelativeVelocity = projVel * inv;
m_clippedInvContactDotSuspension = inv;
}
@@ -48,8 +49,8 @@ void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInf
else // Not in contact : position wheel in a nice (rest length) position
{
m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength();
- m_suspensionRelativeVelocity = 0.0f;
+ m_suspensionRelativeVelocity = btScalar(0.0);
m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS;
- m_clippedInvContactDotSuspension = 1.0f;
+ m_clippedInvContactDotSuspension = btScalar(1.0);
}
}
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h
index 83a3b114ab9..2e349b3fde4 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btWheelInfo.h
@@ -11,8 +11,8 @@
#ifndef WHEEL_INFO_H
#define WHEEL_INFO_H
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btTransform.h"
+#include "../../LinearMath/btVector3.h"
+#include "../../LinearMath/btTransform.h"
class btRigidBody;
@@ -25,10 +25,10 @@ struct btWheelInfoConstructionInfo
btScalar m_maxSuspensionTravelCm;
btScalar m_wheelRadius;
- float m_suspensionStiffness;
- float m_wheelsDampingCompression;
- float m_wheelsDampingRelaxation;
- float m_frictionSlip;
+ btScalar m_suspensionStiffness;
+ btScalar m_wheelsDampingCompression;
+ btScalar m_wheelsDampingRelaxation;
+ btScalar m_frictionSlip;
bool m_bIsFrontWheel;
};
@@ -92,12 +92,12 @@ struct btWheelInfo
m_wheelDirectionCS = ci.m_wheelDirectionCS;
m_wheelAxleCS = ci.m_wheelAxleCS;
m_frictionSlip = ci.m_frictionSlip;
- m_steering = 0.f;
- m_engineForce = 0.f;
- m_rotation = 0.f;
- m_deltaRotation = 0.f;
- m_brake = 0.f;
- m_rollInfluence = 0.1f;
+ m_steering = btScalar(0.);
+ m_engineForce = btScalar(0.);
+ m_rotation = btScalar(0.);
+ m_deltaRotation = btScalar(0.);
+ m_brake = btScalar(0.);
+ m_rollInfluence = btScalar(0.1);
m_bIsFrontWheel = ci.m_bIsFrontWheel;
}
diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h
index 2eacb8e242b..429163c8138 100644
--- a/extern/bullet2/src/LinearMath/btAabbUtil2.h
+++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h
@@ -17,8 +17,8 @@ subject to the following restrictions:
#ifndef AABB_UTIL2
#define AABB_UTIL2
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btSimdMinMax.h"
+#include "btVector3.h"
+#include "btSimdMinMax.h"
#define btMin(a,b) ((a < b ? a : b))
@@ -73,8 +73,8 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
const btVector3& aabbMax,
btScalar& param, btVector3& normal)
{
- btVector3 aabbHalfExtent = (aabbMax-aabbMin)* 0.5f;
- btVector3 aabbCenter = (aabbMax+aabbMin)* 0.5f;
+ btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5);
+ btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5);
btVector3 source = rayFrom - aabbCenter;
btVector3 target = rayTo - aabbCenter;
int sourceOutcode = btOutcode(source,aabbHalfExtent);
@@ -110,7 +110,7 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom,
}
bit<<=1;
}
- normSign = -1.f;
+ normSign = btScalar(-1.);
}
if (lambda_enter <= lambda_exit)
{
diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
index 19b811b0ce8..1f5877fa37e 100644
--- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
+++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
@@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btAlignedAllocator.h"
-#if defined (WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#if defined (BT_HAS_ALIGNED_ALOCATOR)
#include <malloc.h>
void* btAlignedAlloc (int size, int alignment)
@@ -31,6 +31,26 @@ void btAlignedFree (void* ptr)
#else
+#ifdef __CELLOS_LV2__
+
+#include <stdlib.h>
+
+int numAllocs = 0;
+int numFree = 0;
+
+void* btAlignedAlloc (int size, int alignment)
+{
+ numAllocs++;
+ return memalign(alignment, size);
+}
+
+void btAlignedFree (void* ptr)
+{
+ numFree++;
+ free(ptr);
+}
+
+#else
///todo
///will add some multi-platform version that works without _aligned_malloc/_aligned_free
@@ -41,7 +61,10 @@ void* btAlignedAlloc (int size, int alignment)
void btAlignedFree (void* ptr)
{
- delete ptr;
+ delete [] (char*) ptr;
}
+#endif //
#endif
+
+
diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h
index 159399ce7d4..07585717f45 100644
--- a/extern/bullet2/src/LinearMath/btAlignedAllocator.h
+++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.h
@@ -36,11 +36,13 @@ class btAlignedAllocator {
typedef btAlignedAllocator< T , Alignment > self_type;
public:
+
//just going down a list:
btAlignedAllocator() {}
-
+ /*
btAlignedAllocator( const self_type & ) {}
-
+ */
+
template < typename Other >
btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {}
@@ -53,6 +55,7 @@ public:
pointer address ( reference ref ) const { return &ref; }
const_pointer address ( const_reference ref ) const { return &ref; }
pointer allocate ( size_type n , const_pointer * hint = 0 ) {
+ (void)hint;
return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment ));
}
void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); }
diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
index 3bfdb36f4c7..8bef5eb5d06 100644
--- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
+++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
@@ -20,18 +20,37 @@ subject to the following restrictions:
#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
#include "btAlignedAllocator.h"
+///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW
+///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors
+///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator=
+///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and
+///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240
+
+#define BT_USE_PLACEMENT_NEW 1
+//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise...
+
+#ifdef BT_USE_MEMCPY
+#include <memory.h>
+#include <string.h>
+#endif //BT_USE_MEMCPY
+
+#ifdef BT_USE_PLACEMENT_NEW
+#include <new> //for placement new
+#endif //BT_USE_PLACEMENT_NEW
+
+
///btAlignedObjectArray uses a subset of the stl::vector interface for its methods
///It is developed to replace stl::vector to avoid STL alignment issues to add SIMD/SSE data
template <typename T>
//template <class T>
class btAlignedObjectArray
{
+ btAlignedAllocator<T , 16> m_allocator;
+
int m_size;
int m_capacity;
T* m_data;
- btAlignedAllocator<T , 16> m_allocator;
-
protected:
SIMD_FORCE_INLINE int allocSize(int size)
{
@@ -40,8 +59,12 @@ class btAlignedObjectArray
SIMD_FORCE_INLINE void copy(int start,int end, T* dest)
{
int i;
- for (i=0;i<m_size;++i)
+ for (i=start;i<end;++i)
+#ifdef BT_USE_PLACEMENT_NEW
+ new (&dest[i]) T(m_data[i]);
+#else
dest[i] = m_data[i];
+#endif //BT_USE_PLACEMENT_NEW
}
SIMD_FORCE_INLINE void init()
@@ -53,7 +76,7 @@ class btAlignedObjectArray
SIMD_FORCE_INLINE void destroy(int first,int last)
{
int i;
- for (i=0; i<m_size;i++)
+ for (i=first; i<last;i++)
{
m_data[i].~T();
}
@@ -74,6 +97,8 @@ class btAlignedObjectArray
}
}
+
+
public:
@@ -123,17 +148,50 @@ class btAlignedObjectArray
m_data[m_size].~T();
}
- SIMD_FORCE_INLINE void resize(int newsize)
+ SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
{
- if (newsize > size())
+ int curSize = size();
+
+ if (newsize < size())
+ {
+ for(int i = curSize; i < newsize; i++)
+ {
+ m_data[i].~T();
+ }
+ } else
{
- reserve(newsize);
+ if (newsize > size())
+ {
+ reserve(newsize);
+ }
+#ifdef BT_USE_PLACEMENT_NEW
+ for (int i=curSize;i<newsize;i++)
+ {
+ new ( &m_data[i]) T(fillData);
+ }
+#endif //BT_USE_PLACEMENT_NEW
+
}
m_size = newsize;
}
+ SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
+ {
+ int sz = size();
+ if( sz == capacity() )
+ {
+ reserve( allocSize(size()) );
+ }
+ m_size++;
+#ifdef BT_USE_PLACEMENT_NEW
+ new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
+#endif
+
+ return m_data[sz];
+ }
+
SIMD_FORCE_INLINE void push_back(const T& _Val)
{
@@ -143,8 +201,12 @@ class btAlignedObjectArray
reserve( allocSize(size()) );
}
- m_data[size()] = _Val;
- //::new ( m_data[m_size] ) T(_Val);
+#ifdef BT_USE_PLACEMENT_NEW
+ new ( &m_data[m_size] ) T(_Val);
+#else
+ m_data[size()] = _Val;
+#endif //BT_USE_PLACEMENT_NEW
+
m_size++;
}
@@ -154,24 +216,152 @@ class btAlignedObjectArray
{ // determine new minimum length of allocated storage
if (capacity() < _Count)
{ // not enough room, reallocate
- if (capacity() < _Count)
- {
- T* s = (T*)allocate(_Count);
+ T* s = (T*)allocate(_Count);
+
+ copy(0, size(), s);
+
+ destroy(0,size());
- copy(0, size(), s);
+ deallocate();
+
+ m_data = s;
+
+ m_capacity = _Count;
+
+ }
+ }
- destroy(0,size());
- deallocate();
+ class less
+ {
+ public:
- m_data = s;
-
- m_capacity = _Count;
+ bool operator() ( const T& a, const T& b )
+ {
+ return ( a < b );
+ }
+ };
+
+ ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
+ template <typename L>
+ void downHeap(T *pArr, int k, int n,L CompareFunc)
+ {
+ /* PRE: a[k+1..N] is a heap */
+ /* POST: a[k..N] is a heap */
+
+ T temp = pArr[k - 1];
+ /* k has child(s) */
+ while (k <= n/2)
+ {
+ int child = 2*k;
+
+ if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
+ {
+ child++;
+ }
+ /* pick larger child */
+ if (CompareFunc(temp , pArr[child - 1]))
+ {
+ /* move child up */
+ pArr[k - 1] = pArr[child - 1];
+ k = child;
}
+ else
+ {
+ break;
+ }
+ }
+ pArr[k - 1] = temp;
+ } /*downHeap*/
+
+ void swap(int index0,int index1)
+ {
+#ifdef BT_USE_MEMCPY
+ char temp[sizeof(T)];
+ memcpy(temp,&m_data[index0],sizeof(T));
+ memcpy(&m_data[index0],&m_data[index1],sizeof(T));
+ memcpy(&m_data[index1],temp,sizeof(T));
+#else
+ T temp = m_data[index0];
+ m_data[index0] = m_data[index1];
+ m_data[index1] = temp;
+#endif //BT_USE_PLACEMENT_NEW
+
+ }
+
+ template <typename L>
+ void heapSort(L CompareFunc)
+ {
+ /* sort a[0..N-1], N.B. 0 to N-1 */
+ int k;
+ int n = m_size;
+ for (k = n/2; k > 0; k--)
+ {
+ downHeap(m_data, k, n, CompareFunc);
+ }
+
+ /* a[1..N] is now a heap */
+ while ( n>=1 )
+ {
+ swap(0,n-1); /* largest of a[0..n-1] */
+
+
+ n = n - 1;
+ /* restore a[1..i-1] heap */
+ downHeap(m_data, 1, n, CompareFunc);
+ }
+ }
+
+ ///non-recursive binary search, assumes sorted array
+ int findBinarySearch(const T& key) const
+ {
+ int first = 0;
+ int last = size();
+
+ //assume sorted array
+ while (first <= last) {
+ int mid = (first + last) / 2; // compute mid point.
+ if (key > m_data[mid])
+ first = mid + 1; // repeat search in top half.
+ else if (key < m_data[mid])
+ last = mid - 1; // repeat search in bottom half.
+ else
+ return mid; // found it. return position /////
+ }
+ return size(); // failed to find key
+ }
+
+
+ int findLinearSearch(const T& key) const
+ {
+ int index=size();
+ int i;
+
+ for (i=0;i<size();i++)
+ {
+ if (m_data[i] == key)
+ {
+ index = i;
+ break;
}
}
+ return index;
+ }
+
+ void remove(const T& key)
+ {
+
+ int findIndex = findLinearSearch(key);
+ if (findIndex<size())
+ {
+ swap( findIndex,size()-1);
+ pop_back();
+ }
+ }
};
#endif //BT_OBJECT_ARRAY__
+
+
diff --git a/extern/bullet2/src/LinearMath/btDefaultMotionState.h b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
index 6b85b37fb9e..d4ec8e8879c 100644
--- a/extern/bullet2/src/LinearMath/btDefaultMotionState.h
+++ b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
@@ -31,12 +31,7 @@ struct btDefaultMotionState : public btMotionState
m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ;
}
- ///Bullet gives a callback for objects that are about to be deactivated (put asleep)
- /// You can intercept this callback for your own bookkeeping.
- ///Also you can return false to disable deactivation for this object this frame.
- virtual bool deactivationCallback(void* userPointer) {
- return true;
- }
+
};
diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.cpp b/extern/bullet2/src/LinearMath/btGeometryUtil.cpp
index 5036894b2b3..3d0fb122a6b 100644
--- a/extern/bullet2/src/LinearMath/btGeometryUtil.cpp
+++ b/extern/bullet2/src/LinearMath/btGeometryUtil.cpp
@@ -16,14 +16,23 @@ subject to the following restrictions:
#include "btGeometryUtil.h"
-bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, float margin)
+
+/*
+ Make sure this dummy function never changes so that it
+ can be used by probes that are checking whether the
+ library is actually installed.
+*/
+extern "C" void btBulletMathProbe () {}
+
+
+bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin)
{
int numbrushes = planeEquations.size();
for (int i=0;i<numbrushes;i++)
{
const btVector3& N1 = planeEquations[i];
- float dist = float(N1.dot(point))+float(N1[3])-margin;
- if (dist>0.f)
+ btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin;
+ if (dist>btScalar(0.))
{
return false;
}
@@ -33,14 +42,14 @@ bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>&
}
-bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, float margin)
+bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin)
{
int numvertices = vertices.size();
for (int i=0;i<numvertices;i++)
{
const btVector3& N1 = vertices[i];
- float dist = float(planeNormal.dot(N1))+float(planeNormal[3])-margin;
- if (dist>0.f)
+ btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin;
+ if (dist>btScalar(0.))
{
return false;
}
@@ -54,7 +63,7 @@ bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector
for (int i=0;i<numbrushes;i++)
{
const btVector3& N1 = planeEquations[i];
- if (planeEquation.dot(N1) > 0.999f)
+ if (planeEquation.dot(N1) > btScalar(0.999))
{
return false;
}
@@ -83,11 +92,11 @@ void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector
btVector3 planeEquation,edge0,edge1;
edge0 = N2-N1;
edge1 = N3-N1;
- float normalSign = 1.f;
+ btScalar normalSign = btScalar(1.);
for (int ww=0;ww<2;ww++)
{
planeEquation = normalSign * edge0.cross(edge1);
- if (planeEquation.length2() > 0.0001f)
+ if (planeEquation.length2() > btScalar(0.0001))
{
planeEquation.normalize();
if (notExist(planeEquation,planeEquationsOut))
@@ -95,13 +104,13 @@ void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector
planeEquation[3] = -planeEquation.dot(N1);
//check if inside, and replace supportingVertexOut if needed
- if (areVerticesBehindPlane(planeEquation,vertices,0.01f))
+ if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01)))
{
planeEquationsOut.push_back(planeEquation);
}
}
}
- normalSign = -1.f;
+ normalSign = btScalar(-1.);
}
}
@@ -132,9 +141,9 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt
btVector3 n3n1; n3n1 = N3.cross(N1);
btVector3 n1n2; n1n2 = N1.cross(N2);
- if ( ( n2n3.length2() > 0.0001f ) &&
- ( n3n1.length2() > 0.0001f ) &&
- ( n1n2.length2() > 0.0001f ) )
+ if ( ( n2n3.length2() > btScalar(0.0001) ) &&
+ ( n3n1.length2() > btScalar(0.0001) ) &&
+ ( n1n2.length2() > btScalar(0.0001) ) )
{
//point P out of 3 plane equations:
@@ -143,10 +152,10 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt
// N1 . ( N2 * N3 )
- float quotient = (N1.dot(n2n3));
- if (btFabs(quotient) > 0.000001f)
+ btScalar quotient = (N1.dot(n2n3));
+ if (btFabs(quotient) > btScalar(0.000001))
{
- quotient = -1.f / quotient;
+ quotient = btScalar(-1.) / quotient;
n2n3 *= N1[3];
n3n1 *= N2[3];
n1n2 *= N3[3];
@@ -156,7 +165,7 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt
potentialVertex *= quotient;
//check if inside, and replace supportingVertexOut if needed
- if (isPointInsidePlanes(planeEquations,potentialVertex,0.01f))
+ if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01)))
{
verticesOut.push_back(potentialVertex);
}
diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.h b/extern/bullet2/src/LinearMath/btGeometryUtil.h
index 018ffa72296..766cd75c383 100644
--- a/extern/bullet2/src/LinearMath/btGeometryUtil.h
+++ b/extern/bullet2/src/LinearMath/btGeometryUtil.h
@@ -28,11 +28,11 @@ class btGeometryUtil
static void getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut );
- static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, float margin);
+ static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar margin);
- static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, float margin);
+ static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin);
- static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, float margin);
+ static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin);
};
diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h
index 86db735ce94..5f40ca39157 100644
--- a/extern/bullet2/src/LinearMath/btIDebugDraw.h
+++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h
@@ -28,7 +28,7 @@ DEALINGS IN THE SOFTWARE.
#ifndef IDEBUG_DRAW__H
#define IDEBUG_DRAW__H
-#include "LinearMath/btVector3.h"
+#include "btVector3.h"
class btIDebugDraw
@@ -56,14 +56,45 @@ class btIDebugDraw
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
- virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)=0;
+ virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
+
+ virtual void reportErrorWarning(const char* warningString) = 0;
virtual void setDebugMode(int debugMode) =0;
virtual int getDebugMode() const = 0;
+ inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
+ {
+ btVector3 halfExtents = (to-from)* 0.5f;
+ btVector3 center = (to+from) *0.5f;
+ int i,j;
+
+ btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
+ for (i=0;i<4;i++)
+ {
+ for (j=0;j<3;j++)
+ {
+ pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
+ edgecoord[2]*halfExtents[2]);
+ pa+=center;
+
+ int othercoord = j%3;
+ edgecoord[othercoord]*=-1.f;
+ pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],
+ edgecoord[2]*halfExtents[2]);
+ pb+=center;
+
+ drawLine(pa,pb,color);
+ }
+ edgecoord = btVector3(-1.f,-1.f,-1.f);
+ if (i<3)
+ edgecoord[i]*=-1.f;
+ }
+ }
};
+
#endif //IDEBUG_DRAW__H
diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h
index c3cc90a82c7..94f53c3c0a5 100644
--- a/extern/bullet2/src/LinearMath/btMatrix3x3.h
+++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h
@@ -16,10 +16,10 @@ subject to the following restrictions:
#ifndef btMatrix3x3_H
#define btMatrix3x3_H
-#include "LinearMath/btScalar.h"
+#include "btScalar.h"
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btQuaternion.h"
+#include "btVector3.h"
+#include "btQuaternion.h"
class btMatrix3x3 {
@@ -45,12 +45,29 @@ class btMatrix3x3 {
zx, zy, zz);
}
- btVector3 getColumn(int i) const
+ SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
+ {
+ m_el[0] = other.m_el[0];
+ m_el[1] = other.m_el[1];
+ m_el[2] = other.m_el[2];
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
+ {
+ m_el[0] = other.m_el[0];
+ m_el[1] = other.m_el[1];
+ m_el[2] = other.m_el[2];
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE btVector3 getColumn(int i) const
{
return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
}
+
- const btVector3& getRow(int i) const
+
+ SIMD_FORCE_INLINE const btVector3& getRow(int i) const
{
return m_el[i];
}
@@ -58,13 +75,13 @@ class btMatrix3x3 {
SIMD_FORCE_INLINE btVector3& operator[](int i)
{
- assert(0 <= i && i < 3);
+ btFullAssert(0 <= i && i < 3);
return m_el[i];
}
- const btVector3& operator[](int i) const
+ SIMD_FORCE_INLINE const btVector3& operator[](int i) const
{
- assert(0 <= i && i < 3);
+ btFullAssert(0 <= i && i < 3);
return m_el[i];
}
@@ -73,41 +90,30 @@ class btMatrix3x3 {
void setFromOpenGLSubMatrix(const btScalar *m)
{
- m_el[0][0] = (m[0]);
- m_el[1][0] = (m[1]);
- m_el[2][0] = (m[2]);
- m_el[0][1] = (m[4]);
- m_el[1][1] = (m[5]);
- m_el[2][1] = (m[6]);
- m_el[0][2] = (m[8]);
- m_el[1][2] = (m[9]);
- m_el[2][2] = (m[10]);
+ m_el[0].setValue(m[0],m[4],m[8]);
+ m_el[1].setValue(m[1],m[5],m[9]);
+ m_el[2].setValue(m[2],m[6],m[10]);
+
}
void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,
const btScalar& yx, const btScalar& yy, const btScalar& yz,
const btScalar& zx, const btScalar& zy, const btScalar& zz)
{
- m_el[0][0] = btScalar(xx);
- m_el[0][1] = btScalar(xy);
- m_el[0][2] = btScalar(xz);
- m_el[1][0] = btScalar(yx);
- m_el[1][1] = btScalar(yy);
- m_el[1][2] = btScalar(yz);
- m_el[2][0] = btScalar(zx);
- m_el[2][1] = btScalar(zy);
- m_el[2][2] = btScalar(zz);
+ m_el[0].setValue(xx,xy,xz);
+ m_el[1].setValue(yx,yy,yz);
+ m_el[2].setValue(zx,zy,zz);
}
void setRotation(const btQuaternion& q)
{
btScalar d = q.length2();
- assert(d != btScalar(0.0));
+ btFullAssert(d != btScalar(0.0));
btScalar s = btScalar(2.0) / d;
- btScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s;
- btScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs;
- btScalar xx = q[0] * xs, xy = q[0] * ys, xz = q[0] * zs;
- btScalar yy = q[1] * ys, yz = q[1] * zs, zz = q[2] * zs;
+ btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s;
+ btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs;
+ btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs;
+ btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs;
setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
@@ -168,90 +174,88 @@ class btMatrix3x3 {
void getOpenGLSubMatrix(btScalar *m) const
{
- m[0] = btScalar(m_el[0][0]);
- m[1] = btScalar(m_el[1][0]);
- m[2] = btScalar(m_el[2][0]);
+ m[0] = btScalar(m_el[0].x());
+ m[1] = btScalar(m_el[1].x());
+ m[2] = btScalar(m_el[2].x());
m[3] = btScalar(0.0);
- m[4] = btScalar(m_el[0][1]);
- m[5] = btScalar(m_el[1][1]);
- m[6] = btScalar(m_el[2][1]);
+ m[4] = btScalar(m_el[0].y());
+ m[5] = btScalar(m_el[1].y());
+ m[6] = btScalar(m_el[2].y());
m[7] = btScalar(0.0);
- m[8] = btScalar(m_el[0][2]);
- m[9] = btScalar(m_el[1][2]);
- m[10] = btScalar(m_el[2][2]);
+ m[8] = btScalar(m_el[0].z());
+ m[9] = btScalar(m_el[1].z());
+ m[10] = btScalar(m_el[2].z());
m[11] = btScalar(0.0);
}
void getRotation(btQuaternion& q) const
{
- btScalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2];
+ btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
+ btScalar temp[4];
if (trace > btScalar(0.0))
{
btScalar s = btSqrt(trace + btScalar(1.0));
- q[3] = s * btScalar(0.5);
+ temp[3]=(s * btScalar(0.5));
s = btScalar(0.5) / s;
- q[0] = (m_el[2][1] - m_el[1][2]) * s;
- q[1] = (m_el[0][2] - m_el[2][0]) * s;
- q[2] = (m_el[1][0] - m_el[0][1]) * s;
+ temp[0]=((m_el[2].y() - m_el[1].z()) * s);
+ temp[1]=((m_el[0].z() - m_el[2].x()) * s);
+ temp[2]=((m_el[1].x() - m_el[0].y()) * s);
}
else
{
- int i = m_el[0][0] < m_el[1][1] ?
- (m_el[1][1] < m_el[2][2] ? 2 : 1) :
- (m_el[0][0] < m_el[2][2] ? 2 : 0);
+ int i = m_el[0].x() < m_el[1].y() ?
+ (m_el[1].y() < m_el[2].z() ? 2 : 1) :
+ (m_el[0].x() < m_el[2].z() ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
- q[i] = s * btScalar(0.5);
+ temp[i] = s * btScalar(0.5);
s = btScalar(0.5) / s;
- q[3] = (m_el[k][j] - m_el[j][k]) * s;
- q[j] = (m_el[j][i] + m_el[i][j]) * s;
- q[k] = (m_el[k][i] + m_el[i][k]) * s;
+ temp[3] = (m_el[k][j] - m_el[j][k]) * s;
+ temp[j] = (m_el[j][i] + m_el[i][j]) * s;
+ temp[k] = (m_el[k][i] + m_el[i][k]) * s;
}
+ q.setValue(temp[0],temp[1],temp[2],temp[3]);
}
-
-
void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const
{
- pitch = btScalar(btAsin(-m_el[2][0]));
- if (pitch < SIMD_2_PI)
+
+ if (btScalar(m_el[1].z()) < btScalar(1))
{
- if (pitch > SIMD_2_PI)
+ if (btScalar(m_el[1].z()) > -btScalar(1))
{
- yaw = btScalar(btAtan2(m_el[1][0], m_el[0][0]));
- roll = btScalar(btAtan2(m_el[2][1], m_el[2][2]));
+ yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
+ pitch = btScalar(btAsin(-m_el[1].y()));
+ roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
}
else
{
- yaw = btScalar(-btAtan2(-m_el[0][1], m_el[0][2]));
+ yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z()));
+ pitch = SIMD_HALF_PI;
roll = btScalar(0.0);
}
}
else
{
- yaw = btScalar(btAtan2(-m_el[0][1], m_el[0][2]));
+ yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z()));
+ pitch = -SIMD_HALF_PI;
roll = btScalar(0.0);
}
}
-
- btVector3 getScaling() const
- {
- return btVector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0],
- m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1],
- m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]);
- }
+
+
btMatrix3x3 scaled(const btVector3& s) const
{
- return btMatrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2],
- m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2],
- m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]);
+ return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
+ m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
+ m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
}
btScalar determinant() const;
@@ -263,10 +267,20 @@ class btMatrix3x3 {
btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
- btScalar tdot(int c, const btVector3& v) const
+ SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const
{
- return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2];
+ return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
}
+ SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const
+ {
+ return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
+ }
+ SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const
+ {
+ return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
+ }
+
+
protected:
btScalar cofac(int r1, int c1, int r2, int c2) const
@@ -280,9 +294,9 @@ class btMatrix3x3 {
SIMD_FORCE_INLINE btMatrix3x3&
btMatrix3x3::operator*=(const btMatrix3x3& m)
{
- setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]),
- m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]),
- m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2]));
+ setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
+ m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
+ m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
return *this;
}
@@ -297,17 +311,17 @@ class btMatrix3x3 {
btMatrix3x3::absolute() const
{
return btMatrix3x3(
- btFabs(m_el[0][0]), btFabs(m_el[0][1]), btFabs(m_el[0][2]),
- btFabs(m_el[1][0]), btFabs(m_el[1][1]), btFabs(m_el[1][2]),
- btFabs(m_el[2][0]), btFabs(m_el[2][1]), btFabs(m_el[2][2]));
+ btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
+ btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
+ btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
}
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::transpose() const
{
- return btMatrix3x3(m_el[0][0], m_el[1][0], m_el[2][0],
- m_el[0][1], m_el[1][1], m_el[2][1],
- m_el[0][2], m_el[1][2], m_el[2][2]);
+ return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
+ m_el[0].y(), m_el[1].y(), m_el[2].y(),
+ m_el[0].z(), m_el[1].z(), m_el[2].z());
}
SIMD_FORCE_INLINE btMatrix3x3
@@ -323,26 +337,26 @@ class btMatrix3x3 {
{
btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
btScalar det = (*this)[0].dot(co);
- assert(det != btScalar(0.0f));
- btScalar s = btScalar(1.0f) / det;
- return btMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
- co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
- co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
+ btFullAssert(det != btScalar(0.0));
+ btScalar s = btScalar(1.0) / det;
+ return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
+ co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
+ co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
}
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
{
return btMatrix3x3(
- m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0],
- m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1],
- m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2],
- m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0],
- m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1],
- m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2],
- m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0],
- m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1],
- m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]);
+ m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
+ m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
+ m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
+ m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
+ m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
+ m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
+ m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
+ m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
+ m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].x());
}
SIMD_FORCE_INLINE btMatrix3x3
@@ -365,19 +379,19 @@ class btMatrix3x3 {
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v, const btMatrix3x3& m)
{
- return btVector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v));
+ return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
}
SIMD_FORCE_INLINE btMatrix3x3
operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
return btMatrix3x3(
- m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]),
- m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]),
- m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2]));
+ m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
+ m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
+ m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
}
-
+/*
SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) {
return btMatrix3x3(
m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
@@ -390,6 +404,7 @@ class btMatrix3x3 {
m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
}
+*/
#endif
diff --git a/extern/bullet2/src/LinearMath/btMotionState.h b/extern/bullet2/src/LinearMath/btMotionState.h
index a9e212d3c71..1975e5ff900 100644
--- a/extern/bullet2/src/LinearMath/btMotionState.h
+++ b/extern/bullet2/src/LinearMath/btMotionState.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef BT_MOTIONSTATE_H
#define BT_MOTIONSTATE_H
-#include "LinearMath/btTransform.h"
+#include "btTransform.h"
///btMotionState allows the dynamics world to synchronize the updated world transforms with graphics
///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation)
@@ -34,10 +34,7 @@ class btMotionState
//Bullet only calls the update of worldtransform for active objects
virtual void setWorldTransform(const btTransform& worldTrans)=0;
- //future: when Bullet makes attempt to deactivate object, you can intercept this callback (return false to disable deactivation for this object this frame)
- virtual bool deactivationCallback(void* userPointer) {
- return true;
- }
+
};
#endif //BT_MOTIONSTATE_H
diff --git a/extern/bullet2/src/LinearMath/btPoint3.h b/extern/bullet2/src/LinearMath/btPoint3.h
index 4be7e9015bb..a2020e26d12 100644
--- a/extern/bullet2/src/LinearMath/btPoint3.h
+++ b/extern/bullet2/src/LinearMath/btPoint3.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#ifndef btPoint3_H
#define btPoint3_H
-#include "LinearMath/btVector3.h"
+#include "btVector3.h"
typedef btVector3 btPoint3;
diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h
index 4331b668210..961ac484d20 100644
--- a/extern/bullet2/src/LinearMath/btQuadWord.h
+++ b/extern/bullet2/src/LinearMath/btQuadWord.h
@@ -16,12 +16,13 @@ subject to the following restrictions:
#ifndef SIMD_QUADWORD_H
#define SIMD_QUADWORD_H
-#include "LinearMath/btScalar.h"
+#include "btScalar.h"
-ATTRIBUTE_ALIGNED16 (class btQuadWord)
+///btQuadWord is base-class for vectors, points
+class btQuadWord
{
protected:
btScalar m_x;
@@ -31,8 +32,8 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord)
public:
- SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; }
- SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; }
+// SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; }
+// SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; }
SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; }
@@ -40,11 +41,13 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord)
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; }
- SIMD_FORCE_INLINE void setX(float x) { m_x = x;};
+ SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;};
- SIMD_FORCE_INLINE void setY(float y) { m_y = y;};
+ SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;};
- SIMD_FORCE_INLINE void setZ(float z) { m_z = z;};
+ SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;};
+
+ SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;};
SIMD_FORCE_INLINE const btScalar& x() const { return m_x; }
@@ -52,15 +55,18 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord)
SIMD_FORCE_INLINE const btScalar& z() const { return m_z; }
+ SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; }
+
- operator btScalar *() { return &m_x; }
- operator const btScalar *() const { return &m_x; }
+ SIMD_FORCE_INLINE operator btScalar *() { return &m_x; }
+ SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; }
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
{
m_x=x;
m_y=y;
m_z=z;
+ m_unusedW = 0.f;
}
/* void getValue(btScalar *m) const
@@ -78,15 +84,15 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord)
m_unusedW=w;
}
- SIMD_FORCE_INLINE btQuadWord() :
- m_x(0.f),m_y(0.f),m_z(0.f),m_unusedW(0.f)
+ SIMD_FORCE_INLINE btQuadWord()
+ // :m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.))
{
}
SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)
:m_x(x),m_y(y),m_z(z)
//todo, remove this in release/simd ?
- ,m_unusedW(0.f)
+ ,m_unusedW(btScalar(0.))
{
}
diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h
index aec25a54955..50334970ba6 100644
--- a/extern/bullet2/src/LinearMath/btQuaternion.h
+++ b/extern/bullet2/src/LinearMath/btQuaternion.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#ifndef SIMD__QUATERNION_H_
#define SIMD__QUATERNION_H_
-#include "LinearMath/btVector3.h"
+#include "btVector3.h"
class btQuaternion : public btQuadWord {
public:
@@ -68,13 +68,13 @@ public:
btQuaternion& operator+=(const btQuaternion& q)
{
- m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q[3];
+ m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
return *this;
}
btQuaternion& operator-=(const btQuaternion& q)
{
- m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q[3];
+ m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
return *this;
}
@@ -87,16 +87,16 @@ public:
btQuaternion& operator*=(const btQuaternion& q)
{
- setValue(m_unusedW * q.x() + m_x * q[3] + m_y * q.z() - m_z * q.y(),
- m_unusedW * q.y() + m_y * q[3] + m_z * q.x() - m_x * q.z(),
- m_unusedW * q.z() + m_z * q[3] + m_x * q.y() - m_y * q.x(),
- m_unusedW * q[3] - m_x * q.x() - m_y * q.y() - m_z * q.z());
+ setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
+ m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
+ m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
+ m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
return *this;
}
btScalar dot(const btQuaternion& q) const
{
- return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q[3];
+ return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
}
btScalar length2() const
@@ -150,7 +150,7 @@ public:
btScalar getAngle() const
{
- btScalar s = 2.f * btAcos(m_unusedW);
+ btScalar s = btScalar(2.) * btAcos(m_unusedW);
return s;
}
@@ -165,20 +165,20 @@ public:
operator+(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1[3] + q2[3]);
+ return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
}
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1[3] - q2[3]);
+ return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
}
SIMD_FORCE_INLINE btQuaternion operator-() const
{
const btQuaternion& q2 = *this;
- return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2[3]);
+ return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW);
}
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
@@ -202,7 +202,7 @@ public:
return btQuaternion((m_x * s0 + q.x() * s1) * d,
(m_y * s0 + q.y() * s1) * d,
(m_z * s0 + q.z() * s1) * d,
- (m_unusedW * s0 + q[3] * s1) * d);
+ (m_unusedW * s0 + q.m_unusedW * s1) * d);
}
else
{
@@ -212,6 +212,7 @@ public:
SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
+
};
@@ -219,7 +220,7 @@ public:
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q)
{
- return btQuaternion(-q.x(), -q.y(), -q.z(), -q[3]);
+ return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
}
@@ -227,27 +228,27 @@ operator-(const btQuaternion& q)
SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q1, const btQuaternion& q2) {
- return btQuaternion(q1[3] * q2.x() + q1.x() * q2[3] + q1.y() * q2.z() - q1.z() * q2.y(),
- q1[3] * q2.y() + q1.y() * q2[3] + q1.z() * q2.x() - q1.x() * q2.z(),
- q1[3] * q2.z() + q1.z() * q2[3] + q1.x() * q2.y() - q1.y() * q2.x(),
- q1[3] * q2[3] - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
+ return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
+ q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
+ q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
+ q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
}
SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q, const btVector3& w)
{
- return btQuaternion( q[3] * w.x() + q.y() * w.z() - q.z() * w.y(),
- q[3] * w.y() + q.z() * w.x() - q.x() * w.z(),
- q[3] * w.z() + q.x() * w.y() - q.y() * w.x(),
+ return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
+ q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
+ q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
-q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
}
SIMD_FORCE_INLINE btQuaternion
operator*(const btVector3& w, const btQuaternion& q)
{
- return btQuaternion( w.x() * q[3] + w.y() * q.z() - w.z() * q.y(),
- w.y() * q[3] + w.z() * q.x() - w.x() * q.z(),
- w.z() * q[3] + w.x() * q.y() - w.y() * q.x(),
+ return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
+ w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
+ w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
}
@@ -283,6 +284,36 @@ slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
return q1.slerp(q2, t);
}
+SIMD_FORCE_INLINE btVector3
+quatRotate(btQuaternion& rotation, btVector3& v)
+{
+ btQuaternion q = rotation * v;
+ q *= rotation.inverse();
+ return btVector3(q.getX(),q.getY(),q.getZ());
+}
+
+SIMD_FORCE_INLINE btQuaternion
+shortestArcQuat(btVector3& v0,btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
+{
+ btVector3 c = v0.cross(v1);
+ btScalar d = v0.dot(v1);
+
+ if (d < -1.0 + SIMD_EPSILON)
+ return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector
+
+ btScalar s = btSqrt((1.0f + d) * 2.0f);
+ btScalar rs = 1.0f / s;
+
+ return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
+}
+
+SIMD_FORCE_INLINE btQuaternion
+shortestArcQuatNormalize(btVector3& v0,btVector3& v1)
+{
+ v0.normalize();
+ v1.normalize();
+ return shortestArcQuat(v0,v1);
+}
#endif
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp
index 4d013a65853..37a0c8c3be5 100644
--- a/extern/bullet2/src/LinearMath/btQuickprof.cpp
+++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp
@@ -27,7 +27,7 @@ subject to the following restrictions:
// Note: We must declare these private static variables again here to
// avoid link errors.
bool btProfiler::mEnabled = false;
-hidden::Clock btProfiler::mClock;
+btClock btProfiler::mClock;
unsigned long int btProfiler::mCurrentCycleStartMicroseconds = 0;
unsigned long int btProfiler::mLastCycleDurationMicroseconds = 0;
std::map<std::string, hidden::ProfileBlock*> btProfiler::mProfileBlocks;
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h
index ec560c8e33e..a885967c5fa 100644
--- a/extern/bullet2/src/LinearMath/btQuickprof.h
+++ b/extern/bullet2/src/LinearMath/btQuickprof.h
@@ -22,17 +22,17 @@ subject to the following restrictions:
#ifndef QUICK_PROF_H
#define QUICK_PROF_H
-#define USE_QUICKPROF 1
+#include "btScalar.h"
-#ifdef USE_QUICKPROF
+//#define USE_QUICKPROF 1
+//Don't use quickprof for now, because it contains STL. TODO: replace STL by Bullet container classes.
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <map>
+//if you don't need btClock, you can comment next line
+#define USE_BT_CLOCK 1
-#ifdef __PPU__
+#ifdef USE_BT_CLOCK
+#ifdef __CELLOS_LV2__
#include <sys/sys_time.h>
#include <stdio.h>
typedef uint64_t __int64;
@@ -43,47 +43,30 @@ typedef uint64_t __int64;
#endif
#if defined(WIN32) || defined(_WIN32)
- #define USE_WINDOWS_TIMERS
+
+ #define USE_WINDOWS_TIMERS
+ #define WIN32_LEAN_AND_MEAN
+ #define NOWINRES
+ #define NOMCX
+ #define NOIME
+#ifdef _XBOX
+ #include <Xtl.h>
+#else
#include <windows.h>
+#endif
#include <time.h>
+
#else
#include <sys/time.h>
#endif
#define mymin(a,b) (a > b ? a : b)
-namespace hidden
-{
- /// A simple data structure representing a single timed block
- /// of code.
- struct ProfileBlock
- {
- ProfileBlock()
- {
- currentBlockStartMicroseconds = 0;
- currentCycleTotalMicroseconds = 0;
- lastCycleTotalMicroseconds = 0;
- totalMicroseconds = 0;
- }
-
- /// The starting time (in us) of the current block update.
- unsigned long int currentBlockStartMicroseconds;
-
- /// The accumulated time (in us) spent in this block during the
- /// current profiling cycle.
- unsigned long int currentCycleTotalMicroseconds;
-
- /// The accumulated time (in us) spent in this block during the
- /// past profiling cycle.
- unsigned long int lastCycleTotalMicroseconds;
-
- /// The total accumulated time (in us) spent in this block.
- unsigned long int totalMicroseconds;
- };
- class Clock
+/// basic clock
+class btClock
{
public:
- Clock()
+ btClock()
{
#ifdef USE_WINDOWS_TIMERS
QueryPerformanceFrequency(&mClockFrequency);
@@ -91,7 +74,7 @@ namespace hidden
reset();
}
- ~Clock()
+ ~btClock()
{
}
@@ -103,7 +86,7 @@ namespace hidden
mStartTick = GetTickCount();
mPrevElapsedTime = 0;
#else
-#ifdef __PPU__
+#ifdef __CELLOS_LV2__
typedef uint64_t __int64;
typedef __int64 ClockSize;
@@ -111,14 +94,14 @@ namespace hidden
__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
mStartTime = newTime;
#else
- gettimeofday(&mStartTime, NULL);
+ gettimeofday(&mStartTime, 0);
#endif
#endif
}
/// Returns the time in ms since the last call to reset or since
- /// the Clock was created.
+ /// the btClock was created.
unsigned long int getTimeMilliseconds()
{
#ifdef USE_WINDOWS_TIMERS
@@ -156,7 +139,7 @@ namespace hidden
return msecTicks;
#else
-#ifdef __PPU__
+#ifdef __CELLOS_LV2__
__int64 freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq) / 1000.0;
typedef uint64_t __int64;
@@ -168,10 +151,10 @@ namespace hidden
#else
struct timeval currentTime;
- gettimeofday(&currentTime, NULL);
+ gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 +
(currentTime.tv_usec - mStartTime.tv_usec) / 1000;
-#endif //__PPU__
+#endif //__CELLOS_LV2__
#endif
}
@@ -214,7 +197,7 @@ namespace hidden
return usecTicks;
#else
-#ifdef __PPU__
+#ifdef __CELLOS_LV2__
__int64 freq=sys_time_get_timebase_frequency();
double dFreq=((double) freq)/ 1000000.0;
typedef uint64_t __int64;
@@ -226,10 +209,10 @@ namespace hidden
#else
struct timeval currentTime;
- gettimeofday(&currentTime, NULL);
+ gettimeofday(&currentTime, 0);
return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 +
(currentTime.tv_usec - mStartTime.tv_usec);
-#endif//__PPU__
+#endif//__CELLOS_LV2__
#endif
}
@@ -240,14 +223,58 @@ namespace hidden
LONGLONG mPrevElapsedTime;
LARGE_INTEGER mStartTime;
#else
-#ifdef __PPU__
+#ifdef __CELLOS_LV2__
uint64_t mStartTime;
#else
struct timeval mStartTime;
#endif
-#endif //__PPU__
+#endif //__CELLOS_LV2__
+
+ };
+
+#endif //USE_BT_CLOCK
+
+#ifdef USE_QUICKPROF
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <map>
+
+
+
+
+namespace hidden
+{
+ /// A simple data structure representing a single timed block
+ /// of code.
+ struct ProfileBlock
+ {
+ ProfileBlock()
+ {
+ currentBlockStartMicroseconds = 0;
+ currentCycleTotalMicroseconds = 0;
+ lastCycleTotalMicroseconds = 0;
+ totalMicroseconds = 0;
+ }
+
+ /// The starting time (in us) of the current block update.
+ unsigned long int currentBlockStartMicroseconds;
+
+ /// The accumulated time (in us) spent in this block during the
+ /// current profiling cycle.
+ unsigned long int currentCycleTotalMicroseconds;
+
+ /// The accumulated time (in us) spent in this block during the
+ /// past profiling cycle.
+ unsigned long int lastCycleTotalMicroseconds;
+
+ /// The total accumulated time (in us) spent in this block.
+ unsigned long int totalMicroseconds;
};
+
};
/// A static class that manages timing for a set of profiling blocks.
@@ -336,6 +363,7 @@ public:
/// Prints an error message to standard output.
inline static void printError(const std::string& msg)
{
+ //btAssert(0);
std::cout << "[QuickProf error] " << msg << std::endl;
}
@@ -343,7 +371,7 @@ public:
static bool mEnabled;
/// The clock used to time profile blocks.
- static hidden::Clock mClock;
+ static btClock mClock;
/// The starting time (in us) of the current profiling cycle.
static unsigned long int mCurrentCycleStartMicroseconds;
@@ -681,3 +709,4 @@ std::string btProfiler::createStatsString(BlockTimingMethod method)
#endif //QUICK_PROF_H
+
diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h
index dd76fb2de1a..01ad93e786a 100644
--- a/extern/bullet2/src/LinearMath/btScalar.h
+++ b/extern/bullet2/src/LinearMath/btScalar.h
@@ -25,21 +25,40 @@ subject to the following restrictions:
#ifdef WIN32
- #if defined(__MINGW32__) || defined(__CYGWIN__)
+ #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
#define SIMD_FORCE_INLINE inline
#define ATTRIBUTE_ALIGNED16(a) a
#else
+ #define BT_HAS_ALIGNED_ALOCATOR
#pragma warning(disable:4530)
#pragma warning(disable:4996)
#pragma warning(disable:4786)
#define SIMD_FORCE_INLINE __forceinline
#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
+ #ifdef _XBOX
+ #define BT_USE_VMX128
+ #else
+ #define BT_USE_SSE
+ #endif
#endif //__MINGW32__
#include <assert.h>
#define btAssert assert
+ //btFullAssert is optional, slows down a lot
+ #define btFullAssert(x)
#else
+#if defined (__CELLOS_LV2__)
+ #define SIMD_FORCE_INLINE inline
+ #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+ #ifndef assert
+ #include <assert.h>
+ #endif
+ #define btAssert assert
+ //btFullAssert is optional, slows down a lot
+ #define btFullAssert(x)
+#else
+
//non-windows systems
#define SIMD_FORCE_INLINE inline
@@ -48,16 +67,28 @@ subject to the following restrictions:
#include <assert.h>
#endif
#define btAssert assert
+ //btFullAssert is optional, slows down a lot
+ #define btFullAssert(x)
+#endif //__CELLOS_LV2__
#endif
+/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
+/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
+#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
+//use slow double float precision operation on those platforms
+#ifndef BT_USE_DOUBLE_PRECISION
+#define BT_FORCE_DOUBLE_FUNCTIONS
+#endif
+#endif
+#if defined(BT_USE_DOUBLE_PRECISION)
+typedef double btScalar;
+#else
+typedef float btScalar;
+#endif
-typedef float btScalar;
-///older compilers (gcc 3.x) and Sun needs double versions of srqt etc.
-///exclude Apple Intel (it's assumed to be a Macbook or newer Intel Dual Core processor)
-#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
-//use slow double float precision operation on those platforms
+#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
@@ -89,14 +120,35 @@ SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
#endif
+#define SIMD_2_PI btScalar(6.283185307179586232)
+#define SIMD_PI (SIMD_2_PI * btScalar(0.5))
+#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
+#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
+#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
-#define SIMD_2_PI 6.283185307179586232f
-#define SIMD_PI (SIMD_2_PI * btScalar(0.5f))
-#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25f))
-#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0f))
-#define SIMD_DEGS_PER_RAD (btScalar(360.0f) / SIMD_2_PI)
+#ifdef BT_USE_DOUBLE_PRECISION
+#define SIMD_EPSILON DBL_EPSILON
+#define SIMD_INFINITY DBL_MAX
+#else
#define SIMD_EPSILON FLT_EPSILON
#define SIMD_INFINITY FLT_MAX
+#endif
+
+SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
+{
+ btScalar coeff_1 = SIMD_PI / 4.0f;
+ btScalar coeff_2 = 3.0f * coeff_1;
+ btScalar abs_y = btFabs(y);
+ btScalar angle;
+ if (x >= 0.0f) {
+ btScalar r = (x - abs_y) / (x + abs_y);
+ angle = coeff_1 - coeff_1 * r;
+ } else {
+ btScalar r = (x + abs_y) / (abs_y - x);
+ angle = coeff_2 - coeff_1 * r;
+ }
+ return (y < 0.0f) ? -angle : angle;
+}
SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
@@ -117,7 +169,7 @@ SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y)
*/
SIMD_FORCE_INLINE int btIsNegative(btScalar x) {
- return x < 0.0f ? 1 : 0;
+ return x < btScalar(0.0) ? 1 : 0;
}
SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
diff --git a/extern/bullet2/src/LinearMath/btSimdMinMax.h b/extern/bullet2/src/LinearMath/btSimdMinMax.h
index 2731c8b09f3..75e83f3c53f 100644
--- a/extern/bullet2/src/LinearMath/btSimdMinMax.h
+++ b/extern/bullet2/src/LinearMath/btSimdMinMax.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef SIMD_MINMAX_H
#define SIMD_MINMAX_H
-#include "LinearMath/btScalar.h"
+#include "btScalar.h"
template <class T>
SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) {
diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h
index 3f9a48407c7..2d55fec83a4 100644
--- a/extern/bullet2/src/LinearMath/btTransform.h
+++ b/extern/bullet2/src/LinearMath/btTransform.h
@@ -17,8 +17,8 @@ subject to the following restrictions:
#ifndef btTransform_H
#define btTransform_H
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btMatrix3x3.h"
+#include "btVector3.h"
+#include "btMatrix3x3.h"
///btTransform supports rigid transforms (only translation and rotation, no scaling/shear)
@@ -42,23 +42,38 @@ public:
m_origin(c)
{}
+ SIMD_FORCE_INLINE btTransform (const btTransform& other)
+ : m_basis(other.m_basis),
+ m_origin(other.m_origin)
+ {
+ }
+
+ SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
+ {
+ m_basis = other.m_basis;
+ m_origin = other.m_origin;
+ return *this;
+ }
+
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
m_basis = t1.m_basis * t2.m_basis;
m_origin = t1(t2.m_origin);
}
- void multInverseLeft(const btTransform& t1, const btTransform& t2) {
+/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
btVector3 v = t2.m_origin - t1.m_origin;
m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
m_origin = v * t1.m_basis;
}
+ */
+
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
{
- return btVector3(m_basis[0].dot(x) + m_origin[0],
- m_basis[1].dot(x) + m_origin[1],
- m_basis[2].dot(x) + m_origin[2]);
+ return btVector3(m_basis[0].dot(x) + m_origin.x(),
+ m_basis[1].dot(x) + m_origin.y(),
+ m_basis[2].dot(x) + m_origin.z());
}
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
@@ -88,18 +103,16 @@ public:
void setFromOpenGLMatrix(const btScalar *m)
{
m_basis.setFromOpenGLSubMatrix(m);
- m_origin[0] = m[12];
- m_origin[1] = m[13];
- m_origin[2] = m[14];
+ m_origin.setValue(m[12],m[13],m[14]);
}
void getOpenGLMatrix(btScalar *m) const
{
m_basis.getOpenGLSubMatrix(m);
- m[12] = m_origin[0];
- m[13] = m_origin[1];
- m[14] = m_origin[2];
- m[15] = btScalar(1.0f);
+ m[12] = m_origin.x();
+ m[13] = m_origin.y();
+ m[14] = m_origin.z();
+ m[15] = btScalar(1.0);
}
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h
index 39fa830f4df..bc42fd166b6 100644
--- a/extern/bullet2/src/LinearMath/btTransformUtil.h
+++ b/extern/bullet2/src/LinearMath/btTransformUtil.h
@@ -16,48 +16,40 @@ subject to the following restrictions:
#ifndef SIMD_TRANSFORM_UTIL_H
#define SIMD_TRANSFORM_UTIL_H
-#include "LinearMath/btTransform.h"
-#define ANGULAR_MOTION_THRESHOLD 0.5f*SIMD_HALF_PI
+#include "btTransform.h"
+#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI
#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
-#define btRecipSqrt(x) ((float)(1.0f/btSqrt(float(x)))) /* reciprocal square root */
+#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */
inline btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir)
{
- return btVector3(supportDir.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
- supportDir.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
- supportDir.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
+ return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
+ supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
+ supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
inline void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q)
{
- if (btFabs(n[2]) > SIMDSQRT12) {
+ if (btFabs(n.z()) > SIMDSQRT12) {
// choose p in y-z plane
btScalar a = n[1]*n[1] + n[2]*n[2];
btScalar k = btRecipSqrt (a);
- p[0] = 0;
- p[1] = -n[2]*k;
- p[2] = n[1]*k;
+ p.setValue(0,-n[2]*k,n[1]*k);
// set q = n x p
- q[0] = a*k;
- q[1] = -n[0]*p[2];
- q[2] = n[0]*p[1];
+ q.setValue(a*k,-n[0]*p[2],n[0]*p[1]);
}
else {
// choose p in x-y plane
- btScalar a = n[0]*n[0] + n[1]*n[1];
+ btScalar a = n.x()*n.x() + n.y()*n.y();
btScalar k = btRecipSqrt (a);
- p[0] = -n[1]*k;
- p[1] = n[0]*k;
- p[2] = 0;
+ p.setValue(-n.y()*k,n.x()*k,0);
// set q = n x p
- q[0] = -n[2]*p[1];
- q[1] = n[2]*p[0];
- q[2] = a*k;
+ q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k);
}
}
@@ -74,9 +66,9 @@ public:
predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
// #define QUATERNION_DERIVATIVE
#ifdef QUATERNION_DERIVATIVE
- btQuaternion orn = curTrans.getRotation();
- orn += (angvel * orn) * (timeStep * 0.5f);
- orn.normalize();
+ btQuaternion predictedOrn = curTrans.getRotation();
+ predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
+ predictedOrn.normalize();
#else
//exponential map
btVector3 axis;
@@ -87,20 +79,21 @@ public:
fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
}
- if ( fAngle < 0.001f )
+ if ( fAngle < btScalar(0.001) )
{
// use Taylor's expansions of sync function
- axis = angvel*( 0.5f*timeStep-(timeStep*timeStep*timeStep)*(0.020833333333f)*fAngle*fAngle );
+ axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
}
else
{
// sync(fAngle) = sin(c*fAngle)/t
- axis = angvel*( btSin(0.5f*fAngle*timeStep)/fAngle );
+ axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
}
- btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*0.5f ));
+ btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
btQuaternion orn0 = curTrans.getRotation();
btQuaternion predictedOrn = dorn * orn0;
+ predictedOrn.normalize();
#endif
predictedTransform.setRotation(predictedOrn);
}
@@ -130,11 +123,11 @@ public:
angle = dorn.getAngle();
axis = btVector3(dorn.x(),dorn.y(),dorn.z());
- axis[3] = 0.f;
+ axis[3] = btScalar(0.);
//check for axis length
btScalar len = axis.length2();
if (len < SIMD_EPSILON*SIMD_EPSILON)
- axis = btVector3(1.f,0.f,0.f);
+ axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
else
axis /= btSqrt(len);
}
diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h
index 5a35652ecd3..74d41ad2a19 100644
--- a/extern/bullet2/src/LinearMath/btVector3.h
+++ b/extern/bullet2/src/LinearMath/btVector3.h
@@ -19,11 +19,10 @@ subject to the following restrictions:
#include "btQuadWord.h"
-
-///btVector3 is 16byte aligned, and has an extra unused component m_w
-///this extra component can be used by derived classes (Quaternion?) or by user
-class btVector3 : public btQuadWord {
-
+///btVector3 can be used to represent 3D points and vectors.
+///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
+///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
+class btVector3 : public btQuadWord {
public:
SIMD_FORCE_INLINE btVector3() {}
@@ -31,7 +30,7 @@ public:
SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
- :btQuadWord(x,y,z,0.f)
+ :btQuadWord(x,y,z,btScalar(0.))
{
}
@@ -64,7 +63,7 @@ public:
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
{
- assert(s != btScalar(0.0));
+ btFullAssert(s != btScalar(0.0));
return *this *= btScalar(1.0) / s;
}
@@ -99,7 +98,7 @@ public:
SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
{
btScalar s = btSqrt(length2() * v.length2());
- assert(s != btScalar(0.0));
+ btFullAssert(s != btScalar(0.0));
return btAcos(dot(v) / s);
}
@@ -148,10 +147,10 @@ public:
SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt)
{
- btScalar s = 1.0f - rt;
- m_x = s * v0[0] + rt * v1.x();
- m_y = s * v0[1] + rt * v1.y();
- m_z = s * v0[2] + rt * v1.z();
+ btScalar s = btScalar(1.0) - rt;
+ m_x = s * v0.x() + rt * v1.x();
+ m_y = s * v0.y() + rt * v1.y();
+ m_z = s * v0.z() + rt * v1.z();
//don't do the unused w component
// m_co[3] = s * v0[3] + rt * v1[3];
}
@@ -213,7 +212,7 @@ operator*(const btScalar& s, const btVector3& v)
SIMD_FORCE_INLINE btVector3
operator/(const btVector3& v, const btScalar& s)
{
- assert(s != btScalar(0.0));
+ btFullAssert(s != btScalar(0.0));
return v * (btScalar(1.0) / s);
}
@@ -271,7 +270,7 @@ lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2)
{
- return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2];
+ return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z();
}
SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const
@@ -327,13 +326,13 @@ public:
- float getW() const { return m_unusedW;}
+ btScalar getW() const { return m_unusedW;}
SIMD_FORCE_INLINE int maxAxis4() const
{
int maxIndex = -1;
- float maxVal = -1e30f;
+ btScalar maxVal = btScalar(-1e30);
if (m_x > maxVal)
{
maxIndex = 0;
@@ -366,7 +365,7 @@ public:
SIMD_FORCE_INLINE int minAxis4() const
{
int minIndex = -1;
- float minVal = 1e30f;
+ btScalar minVal = btScalar(1e30);
if (m_x < minVal)
{
minIndex = 0;
diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript
index 1220be1b654..19702782b0d 100644
--- a/extern/bullet2/src/SConscript
+++ b/extern/bullet2/src/SConscript
@@ -29,10 +29,12 @@ bulletdyn_src = ["BulletDynamics/ConstraintSolver/btContactConstraint.cpp",
"BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp",
"BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp",
"BulletDynamics/ConstraintSolver/btTypedConstraint.cpp",
+ "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp",
"BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp",
"BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp",
"BulletDynamics/Dynamics/btRigidBody.cpp",
"BulletDynamics/Vehicle/btRaycastVehicle.cpp",
+ "BulletDynamics/Dynamics/Bullet-C-API.cpp",
"BulletDynamics/Vehicle/btWheelInfo.cpp"]
collision_src = ["BulletCollision/BroadphaseCollision/btAxisSweep3.cpp",
"BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp",
diff --git a/extern/bullet2/src/btBulletCollisionCommon.h b/extern/bullet2/src/btBulletCollisionCommon.h
index 834dca09e47..8417ccc671f 100644
--- a/extern/bullet2/src/btBulletCollisionCommon.h
+++ b/extern/bullet2/src/btBulletCollisionCommon.h
@@ -25,6 +25,7 @@ subject to the following restrictions:
///Collision Shapes
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
#include "BulletCollision/CollisionShapes/btCylinderShape.h"
#include "BulletCollision/CollisionShapes/btConeShape.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
diff --git a/extern/bullet2/src/btBulletDynamicsCommon.h b/extern/bullet2/src/btBulletDynamicsCommon.h
index 89211d230fd..25f016cba8a 100644
--- a/extern/bullet2/src/btBulletDynamicsCommon.h
+++ b/extern/bullet2/src/btBulletDynamicsCommon.h
@@ -25,6 +25,7 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
diff --git a/extern/verse/Makefile b/extern/verse/Makefile
index 91ab4d26eaa..bd8bba33195 100644
--- a/extern/verse/Makefile
+++ b/extern/verse/Makefile
@@ -34,6 +34,7 @@ DIR = $(OCGDIR)/$(SOURCEDIR)
DIRS = dist
include nan_subdirs.mk
+include nan_compile.mk
include nan_link.mk
DISTDIR = dist
@@ -53,5 +54,5 @@ install: all debug
ifeq ($(OS),darwin)
ranlib $(NAN_VERSE)/lib/libverse.a
endif
- $(CC) $(LDFLAGS) -o $(DIR)/verse$(EXT) $(DIR)/libverse.a $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(CCFLAGS) $(LDFLAGS) -o $(DIR)/verse$(EXT) $(DIR)/libverse.a $(LIBS) $(SLIBS) $(LLIBS) $(DADD) $(LOPTS)
@$(CP) $(DIR)/verse$(EXT) $(OCGDIR)/bin
diff --git a/extern/verse/dist/v_connection.c b/extern/verse/dist/v_connection.c
index 2a97ec66ed1..3bfafad5660 100644
--- a/extern/verse/dist/v_connection.c
+++ b/extern/verse/dist/v_connection.c
@@ -275,7 +275,8 @@ boolean v_con_callback_update(void)
{
static unsigned int seconds;
boolean output = FALSE;
- unsigned int size, connection, s;
+ size_t size;
+ unsigned int connection, s;
VNetInPacked *p;
v_n_get_current_time(&s, NULL);
diff --git a/extern/verse/dist/v_network.c b/extern/verse/dist/v_network.c
index 47bf7d970f3..3d67218bb7e 100644
--- a/extern/verse/dist/v_network.c
+++ b/extern/verse/dist/v_network.c
@@ -37,6 +37,10 @@ typedef char boolean;
#include "v_cmd_gen.h"
#include "v_network.h"
+#if !defined socklen_t
+#define socklen_t int
+#endif
+
#define TRUE 1
#define FALSE 0
@@ -209,7 +213,8 @@ unsigned int v_n_wait_for_incoming(unsigned int microseconds)
int v_n_receive_data(VNetworkAddress *address, char *data, size_t length)
{
struct sockaddr_in address_in;
- size_t from_length = sizeof address_in, len;
+ socklen_t from_length = sizeof address_in;
+ size_t len;
if(v_n_socket_create() == -1)
return 0;
diff --git a/intern/SoundSystem/SConscript b/intern/SoundSystem/SConscript
index a9c1110c09a..baf680f03f0 100644
--- a/intern/SoundSystem/SConscript
+++ b/intern/SoundSystem/SConscript
@@ -7,10 +7,11 @@ sources = env.Glob('dummy/*.cpp') + env.Glob('intern/*.cpp')
incs = '. intern ../moto/include ../string dummy openal sdl'
defs = ''
if env['WITH_BF_OPENAL']:
- sources += env.Glob('openal/*.cpp') + env.Glob('sdl/*.cpp')
- incs += ' ' + env['BF_OPENAL_INC']
- incs += ' ' + env['BF_SDL_INC']
+ sources += env.Glob('openal/*.cpp') + env.Glob('sdl/*.cpp')
+ incs += ' ' + env['BF_OPENAL_INC']
+ incs += ' ' + env['BF_SDL_INC']
+ defs = 'USE_OPENAL'
else:
- defs = 'NO_SOUND'
+ defs = 'NO_SOUND'
env.BlenderLib ('bf_soundsystem', sources, Split(incs), Split(defs), libtype=['core','player'], priority = [20,140] )
diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp
index a278384dfd8..bb0204af53b 100644
--- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp
+++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp
@@ -332,12 +332,6 @@ SND_OpenALDevice::~SND_OpenALDevice()
{
MakeCurrent();
- if (m_buffersinitialized)
- {
- alDeleteBuffers(NUM_BUFFERS, m_buffers);
- m_buffersinitialized = false;
- }
-
if (m_sourcesinitialized)
{
for (int i = 0; i < NUM_SOURCES; i++)
@@ -347,6 +341,12 @@ SND_OpenALDevice::~SND_OpenALDevice()
m_sourcesinitialized = false;
}
+ if (m_buffersinitialized)
+ {
+ alDeleteBuffers(NUM_BUFFERS, m_buffers);
+ m_buffersinitialized = false;
+ }
+
if (m_context) {
MakeCurrent();
#ifdef AL_VERSION_1_1
diff --git a/intern/action/ACT_Action.h b/intern/action/ACT_Action.h
deleted file mode 100644
index 876ca2bc6b9..00000000000
--- a/intern/action/ACT_Action.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifndef _H_ACT_ACTION_H_
-#define _H_ACT_ACTION_H_
-
-#include "MEM_RefCounted.h"
-#include "STR_String.h"
-
-/**
- * An action that can be applied or undone.
- * Virtual base class for actions with a name.
- * An action object inherits the shared object reference count mechanism.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-class ACT_Action : public MEM_RefCounted {
-public:
- /**
- * Constructs an action with the given name .
- * @param name the name of the action.
- * @param applied state of the action after creation.
- */
- ACT_Action(const STR_String& name, bool applied = false);
-
- /**
- * Returns the name of the action.
- * @param name the name of the action.
- */
- inline virtual void getName(STR_String& name) const;
-
- /**
- * Returns the name of the action as a pointer to the data of the string.
- * @return pointer to the name of the action.
- */
- inline virtual char* getName();
-
- /**
- * Sets the name of the action.
- * @param name the name of the action.
- */
- inline virtual void setName(const STR_String& name);
-
- /**
- * Returns whether this action is applied.
- * @return whether this action is applied.
- */
- inline virtual bool getIsApplied() const;
-
-
- /**
- * Call this member to apply an action.
- * Child classes should override the doApply member to implement apply functionality.
- * @see doApply.
- */
- virtual void apply();
-
- /**
- * Call this member to undo an action .
- * Child classes should override the doUndo member to implement undo functionality.
- * @see doApply()
- */
- virtual void undo();
-
-protected:
- /**
- * Implementations should overload this method to provide the apply functionality.
- */
- virtual void doApply() = 0;
-
- /**
- * Implementations should overload this method to provide the undo functionality.
- */
- virtual void doUndo() = 0;
-
- /** Name of this action */
- STR_String m_name;
- /** Is this action already applied? */
- bool m_applied;
-};
-
-
-void ACT_Action::getName(STR_String& name) const
-{
- name = m_name;
-}
-
-char* ACT_Action::getName()
-{
- return m_name.Ptr();
-}
-
-void ACT_Action::setName(const STR_String& name)
-{
- m_name = name;
-}
-
-inline bool ACT_Action::getIsApplied() const
-{
- return m_applied;
-}
-
-#endif // _H_ACT_ACTION_H_
-
diff --git a/intern/action/ACT_ActionC-Api.h b/intern/action/ACT_ActionC-Api.h
deleted file mode 100644
index 64f279a2df6..00000000000
--- a/intern/action/ACT_ActionC-Api.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Interface for C access to actions.
- * @author Maarten Gribnau
- * @date April, 25, 2001
- */
-
-#ifndef _H_ACT_ACTION_C_API
-#define _H_ACT_ACTION_C_API
-
-#include "MEM_RefCountedC-Api.h"
-
-/** A pointer to an action object. */
-typedef MEM_TRefCountedObjectPtr ACT_ActionPtr;
-/** A pointer to an action stack object. */
-typedef MEM_TObjectPtr ACT_ActionStackPtr;
-
-
-/** A pointer to user data passed by the callbacks. */
-typedef void* ACT_ActionUserDataPtr;
-
-/**
- * An action apply callback routine.
- * @param action The action that should be applied.
- * @param userData The pointer to the user data provided when the action was created.
- */
-typedef void (*ACT_ActionApplyProcPtr)(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-
-/**
- * An action undo callback routine.
- * @param action The action that should be undone.
- * @param userData The pointer to the user data provided when the action was created.
- */
-typedef void (*ACT_ActionUndoProcPtr)(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-
-/**
- * An action dispose callback routine.
- * @param action The action that is disposed.
- * @param userData The pointer to the user data provided when the action was created.
- */
-typedef void (*ACT_ActionDisposeProcPtr)(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * An action is a shared object that can be applied or undone.
- */
-
-/**
- * Creates a new action.
- * This is an action that calls the given callbacks when it needs to be applied or undone.
- * @param name The name of the action.
- * @param isApplied Indication as to whether the action is already applied (0 = not applied).
- * @param userData Pointer passed to the apply/undo callbacks.
- * @param applyProc Pointer to the callback invoked when the action needs to be applied.
- * @param undoProc Pointer to the callback invoked when the action needs to be undone.
- * @return The new action (null in case of error).
- */
-extern ACT_ActionPtr ACT_ActionCreate(
- char* name,
- int isApplied,
- ACT_ActionUserDataPtr userData,
- ACT_ActionApplyProcPtr applyProc,
- ACT_ActionUndoProcPtr undoProc,
- ACT_ActionDisposeProcPtr disposeProc);
-
-/**
- * Returns the name of an action.
- * @return The name of the action (null in case of error).
- */
-extern char* ACT_ActionGetName(ACT_ActionPtr action);
-
-
-
-/**
- * An action stack stores actions and implements undo/redo functionality.
- */
-
-/**
- * Creates a new action stack.
- * @param stackSize The maximum number of actions on the stack.
- * @return The new stack (or NULL in case of error).
- */
-extern ACT_ActionStackPtr ACT_ActionStackCreate(unsigned int stackSize);
-
-/**
- * Disposes an action stack.
- * @param stack The appropriate stack.
- */
-extern void ACT_ActionStackDispose(ACT_ActionStackPtr stack);
-
-/**
- * Returns the current depth of the stack.
- * @param stack The appropriate stack.
- * @return the current stack depth.
- */
-extern unsigned int ACT_ActionStackGetStackDepth(ACT_ActionStackPtr stack);
-
-/**
- * Returns the current maximum depth of the stack.
- * @param stack The appropriate stack.
- * @return the maximum stack depth.
- */
-extern unsigned int ACT_ActionStackGetMaxStackDepth(ACT_ActionStackPtr stack);
-
-/**
- * Sets new maximum depth of the stack.
- * @param stack The appropriate stack.
- * @param maxStackDepth The new stack depth.
- */
-extern void ACT_ActionStackSetMaxStackDepth(ACT_ActionStackPtr stack, unsigned int maxStackDepth);
-
-/**
- * Pushes an action on the stack.
- * If the action has not been applied yet, it will be applied here.
- * This will increase the reference count of the action.
- * If there is not enough capacity, the action at the bottom of the stack is removed (and its reference count decreased).
- * @param stack The appropriate stack.
- * @param action the action that is pushed onto the stack.
- */
-extern void ACT_ActionStackPush(ACT_ActionStackPtr stack, ACT_ActionPtr action);
-
-/**
- * Returns pointer to the current undo item.
- * @param stack The appropriate stack.
- * @return The action scheduled for undo (0 if there is none).
- */
-extern ACT_ActionStackPtr ACT_ActionStackPeekUndo(ACT_ActionStackPtr stack);
-
-/**
- * Returns pointer to the current redo item.
- * @param stack The appropriate stack.
- * @return The action scheduled for redo (0 if there is none).
- */
-extern ACT_ActionStackPtr ACT_ActionStackPeekRedo(ACT_ActionStackPtr stack);
-
-/**
- * Undos the current action.
- * @param stack The appropriate stack.
- * This will move the current undo index down (if the stack depth allows it).
- */
-extern void ACT_ActionStackUndo(ACT_ActionStackPtr stack);
-
-/**
- * Redos the current action.
- * @param stack The appropriate stack.
- * This will move the action index up (if the stack depth allows it).
- */
-extern void ACT_ActionStackRedo(ACT_ActionStackPtr stack);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _H_ACT_ACTION_C_API
-
diff --git a/intern/action/ACT_ActionStack.h b/intern/action/ACT_ActionStack.h
deleted file mode 100644
index 421dca76e59..00000000000
--- a/intern/action/ACT_ActionStack.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifndef _H_ACT_ACTIONSTACK
-#define _H_ACT_ACTIONSTACK
-
-#include "ACT_Action.h"
-#include <deque>
-
-
-/**
- * A stack with actions that implements undo/redo capabilities.
- * A stack can grow to a maximum number of actions by pushing actions on the stack.
- * By calling undo and redo the apply and undo members of the actions on the stack are called.
- * In addition, this will move the stackIndex up and down the stack.
- * When a new action is pushed onto the stack, the actions above the current action are removed from the stack.
- * Actions pushed onto the stack are applied if they are not applied already.
- * @todo implement error handling (e.g. memory errors)
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-class ACT_ActionStack {
-public:
- /**
- * Constructs an action stack.
- */
- ACT_ActionStack(unsigned int maxStackDepth = 1);
-
- /**
- * Destructs an action stack.
- */
- virtual ~ACT_ActionStack();
-
- /**
- * Returns the current depth of the stack.
- * @return the current stack depth.
- */
- virtual unsigned int getStackDepth() const;
-
- /**
- * Returns the current maximum depth of the stack.
- * @return the maximum stack depth.
- */
- virtual unsigned int getMaxStackDepth() const;
-
- /**
- * Sets new maximum depth of the stack.
- * @param maxStackDepth The new stack depth.
- */
- virtual void setMaxStackDepth(unsigned int maxStackDepth);
-
- /**
- * Pushes an action on the stack.
- * If the action has not been applied yet, it will be applied here.
- * This will increase the reference count of the action.
- * If there is not enough capacity, the action at the bottom of the stack is removed (and its reference count decreased).
- * @param action the action that is pushed onto the stack.
- */
- virtual void push(ACT_Action& action);
-
- /**
- * Returns pointer to the current undo item.
- * @return The action scheduled for undo (0 if there is none).
- */
- virtual ACT_Action* peekUndo();
-
- /**
- * Returns pointer to the current redo item.
- * @return The action scheduled for redo (0 if there is none).
- */
- virtual ACT_Action* peekRedo();
-
- /**
- * Flushes the action stack.
- * All actions are removed from the stack and their reference counts decreased.
- */
- virtual void flush();
-
- /**
- * Returns whether we can undo the current action.
- * @return Indication of the possibility to undo.
- */
- virtual bool canUndo() const;
-
- /**
- * Undos the current action.
- * This will move the current undo index down (if the stack depth allows it).
- */
- virtual void undo();
-
- /**
- * Returns whether we can redo the current action.
- * @return Indication of the possibility to redo.
- */
- virtual bool canRedo() const;
-
- /**
- * Redos the current action.
- * This will move the action index up (if the stack depth allows it).
- */
- virtual void redo();
-
-protected:
- /**
- * Removes <i>numActions</i> actions from the back of the stack.
- * @param numActions number of items to remove.
- * @return the number of actions removed.
- */
- virtual unsigned int popBack(unsigned int numActions = 1);
-
- /**
- * Removes <i>numActions</i> actions from the front of the stack.
- * @param numActions number of items to remove.
- * @return the number of actions removed.
- */
- virtual unsigned int popFront(unsigned int numActions = 1);
-
- /**
- * Returns the index of the current undo action.
- * @param index The index of the action.
- * @return Indication as to whether the index is valid (==true).
- */
- virtual bool getUndoIndex(unsigned int& index) const;
-
- /**
- * Returns the index of the current redo action.
- * @param index The index of the action.
- * @return Indication as to whether the index is valid (==true).
- */
- virtual bool getRedoIndex(unsigned int& index) const;
-
- /** The maximum depth of this stack. */
- unsigned int m_maxStackDepth;
- /** The index of the current undo action in the stack. */
- unsigned int m_undoIndex;
- /** Is the index of the current undo action in the stack valid? */
- bool m_undoIndexValid;
- /** The index of the current redo action in the stack. */
- unsigned int m_redoIndex;
- /** Is the index of the current redo action in the stack valid? */
- bool m_redoIndexValid;
- /** The stack with actions. */
- deque<ACT_Action*> m_stack;
-};
-
-
-#endif // _H_ACT_ACTIONSTACK
-
diff --git a/intern/action/Makefile b/intern/action/Makefile
deleted file mode 100644
index ed1cfccfc52..00000000000
--- a/intern/action/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# $Id$
-#
-# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version. The Blender
-# Foundation also sells licenses for use in proprietary software under
-# the Blender License. See http://www.blender.org/BL/ for information
-# about this.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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/BL DUAL LICENSE BLOCK *****
-# action main makefile.
-#
-
-include nan_definitions.mk
-
-LIBNAME = action
-SOURCEDIR = intern/$(LIBNAME)
-DIR = $(OCGDIR)/$(SOURCEDIR)
-DIRS = intern
-TESTDIRS = test
-
-include nan_subdirs.mk
-
-install: all debug
- @[ -d $(NAN_ACTION) ] || mkdir $(NAN_ACTION)
- @[ -d $(NAN_ACTION)/include ] || mkdir $(NAN_ACTION)/include
- @[ -d $(NAN_ACTION)/lib ] || mkdir $(NAN_ACTION)/lib
- @[ -d $(NAN_ACTION)/lib/debug ] || mkdir $(NAN_ACTION)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libaction.a $(NAN_ACTION)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libaction.a $(NAN_ACTION)/lib/debug/
- @../tools/cpifdiff.sh *.h $(NAN_ACTION)/include/
-
diff --git a/intern/action/doc/Doxyfile b/intern/action/doc/Doxyfile
deleted file mode 100644
index 2cc9de2d97c..00000000000
--- a/intern/action/doc/Doxyfile
+++ /dev/null
@@ -1,746 +0,0 @@
-# Doxyfile 1.2.4
-
-# This file describes the settings to be used by doxygen for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# General configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-PROJECT_NAME = foundation
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY =
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
-# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
-# Polish, Portuguese and Slovene.
-
-OUTPUT_LANGUAGE = English
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these class will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH =
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a class diagram (in Html and LaTeX) for classes with base or
-# super classes. Setting the tag to NO turns the diagrams off.
-
-CLASS_DIAGRAMS = YES
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower case letters. If set to YES upper case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# users are adviced to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explict @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# reimplements.
-
-INHERIT_DOCS = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# The ENABLE_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text.
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = ../extern ../intern
-
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-FILE_PATTERNS = *.h *.cpp *.c
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-
-INPUT_FILTER =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse.
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript and frames is required (for instance Netscape 4.0+
-# or Internet explorer 4.0+).
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimised for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using a WORD or other.
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assigments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation. Warning: This feature
-# is still experimental and very incomplete.
-
-GENERATE_XML = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH = ../../generic/extern
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tagfiles.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
-# YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other
-# documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
-# YES then doxygen will generate a graph for each documented header file showing
-# the documented files that directly or indirectly include this file
-
-INCLUDED_BY_GRAPH = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
-
-# The CGI_NAME tag should be the name of the CGI script that
-# starts the search engine (doxysearch) with the correct parameters.
-# A script with this name will be generated by doxygen.
-
-CGI_NAME = search.cgi
-
-# The CGI_URL tag should be the absolute URL to the directory where the
-# cgi binaries are located. See the documentation of your http daemon for
-# details.
-
-CGI_URL =
-
-# The DOC_URL tag should be the absolute URL to the directory where the
-# documentation is located. If left blank the absolute path to the
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL =
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the
-# documentation is located. If left blank the directory on the local machine
-# will be used.
-
-DOC_ABSPATH =
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
-# is installed.
-
-BIN_ABSPATH = c:\program files\doxygen\bin
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to
-# documentation generated for other projects. This allows doxysearch to search
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS =
diff --git a/intern/action/intern/ACT_ActionC-Api.cpp b/intern/action/intern/ACT_ActionC-Api.cpp
deleted file mode 100644
index 7fcd1d7b60a..00000000000
--- a/intern/action/intern/ACT_ActionC-Api.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date April, 25, 2001
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ACT_ActionC-Api.h"
-
-#include "ACT_ActionStack.h"
-#include "ACT_CallbackAction.h"
-
-
-ACT_ActionPtr ACT_ActionCreate(
- char* name,
- int isApplied,
- ACT_ActionUserDataPtr data,
- ACT_ActionApplyProcPtr applyProc,
- ACT_ActionUndoProcPtr undoProc,
- ACT_ActionDisposeProcPtr disposeProc)
-{
- STR_String tmp (name);
- ACT_CallbackAction* action = new ACT_CallbackAction(tmp, isApplied != 0, data, applyProc, undoProc, disposeProc);
- return (ACT_ActionPtr) action;
-}
-
-
-char* ACT_ActionGetName(ACT_ActionPtr action)
-{
- return action ? ((ACT_Action*)action)->getName() : 0;
-}
-
-
-ACT_ActionStackPtr ACT_ActionStackCreate(unsigned int stackSize)
-{
- return ((ACT_ActionStackPtr) (new ACT_ActionStack (stackSize)));
-}
-
-
-void ACT_ActionStackDispose(ACT_ActionStackPtr stack)
-{
- if (stack) {
- delete (ACT_ActionStack*) stack;
- }
-}
-
-
-unsigned int ACT_ActionStackGetStackDepth(ACT_ActionStackPtr stack)
-{
- return stack ? ((ACT_ActionStack*)stack)->getStackDepth() : 0;
-}
-
-unsigned int ACT_ActionStackGetMaxStackDepth(ACT_ActionStackPtr stack)
-{
- return stack ? ((ACT_ActionStack*)stack)->getMaxStackDepth() : 0;
-}
-
-void ACT_ActionStackSetMaxStackDepth(ACT_ActionStackPtr stack, unsigned int maxStackDepth)
-{
- if (stack) {
- ((ACT_ActionStack*)stack)->setMaxStackDepth(maxStackDepth);
- }
-}
-
-void ACT_ActionStackPush(ACT_ActionStackPtr stack, ACT_ActionPtr action)
-{
- if (stack && action) {
- ((ACT_ActionStack*)stack)->push(*((ACT_Action*)action));
- }
-}
-
-
-ACT_ActionStackPtr ACT_ActionStackPeekUndo(ACT_ActionStackPtr stack)
-{
- return (ACT_ActionStackPtr) (stack ? ((ACT_ActionStack*)stack)->peekUndo() : 0);
-}
-
-
-ACT_ActionStackPtr ACT_ActionStackPeekRedo(ACT_ActionStackPtr stack)
-{
- return (ACT_ActionStackPtr) (stack ? ((ACT_ActionStack*)stack)->peekRedo() : 0);
-}
-
-
-void ACT_ActionStackUndo(ACT_ActionStackPtr stack)
-{
- if (stack) {
- ((ACT_ActionStack*)stack)->undo();
- }
-}
-
-
-void ACT_ActionStackRedo(ACT_ActionStackPtr stack)
-{
- if (stack) {
- ((ACT_ActionStack*)stack)->redo();
- }
-}
diff --git a/intern/action/intern/ACT_ActionStack.cpp b/intern/action/intern/ACT_ActionStack.cpp
deleted file mode 100644
index 2025f744958..00000000000
--- a/intern/action/intern/ACT_ActionStack.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ACT_ActionStack.h"
-
-
-ACT_ActionStack::ACT_ActionStack(unsigned int maxStackDepth)
- : m_maxStackDepth(maxStackDepth),
- m_undoIndex(0), m_undoIndexValid(false),
- m_redoIndex(0), m_redoIndexValid(false)
-{
-}
-
-
-ACT_ActionStack::~ACT_ActionStack()
-{
- flush();
-}
-
-
-unsigned int ACT_ActionStack::getStackDepth() const
-{
- return m_stack.size();
-}
-
-
-unsigned int ACT_ActionStack::getMaxStackDepth() const
-{
- return m_maxStackDepth;
-}
-
-
-void ACT_ActionStack::setMaxStackDepth(unsigned int maxStackDepth)
-{
- if (maxStackDepth != m_maxStackDepth) {
- if (maxStackDepth) {
- unsigned int size = m_stack.size();
- if (maxStackDepth < size) {
- // New max stack size is smaller than current stack size, need to shrink stack
- unsigned int numRemove = size - maxStackDepth;
- if (m_undoIndex >= maxStackDepth) {
- // Pop items from the front (throw away undo steps)
- popFront(numRemove);
- m_undoIndex -= numRemove;
- m_redoIndex = m_undoIndex + 1;
- m_redoIndexValid = m_redoIndexValid && (maxStackDepth > 1);
- }
- else {
- // Pop items from the back (throw away redo steps)
- popBack(numRemove);
- m_redoIndexValid = m_redoIndexValid && (m_redoIndex < maxStackDepth);
- }
- }
- }
- else {
- // New stack size is zero
- flush();
- }
- m_maxStackDepth = maxStackDepth;
- }
-}
-
-
-void ACT_ActionStack::push(ACT_Action& action)
-{
- if (m_maxStackDepth) {
- unsigned int size = m_stack.size();
- if (m_redoIndexValid) {
- // Remove items after the current action (throw away redo steps)
- popBack(size - m_redoIndex);
- }
- else if (size >= m_maxStackDepth) {
- // Remove items from the front (throw away undo steps)
- popFront(m_maxStackDepth - size + 1);
- }
-
- // Store the action
- if (!action.getIsApplied()) {
- action.apply();
- }
- action.incRef();
- m_stack.push_back(&action);
-
- // Update action indices
- m_redoIndex = m_stack.size();
- m_redoIndexValid = false;
- m_undoIndex = m_redoIndex - 1;
- m_undoIndexValid = true;
- }
-}
-
-
-ACT_Action* ACT_ActionStack::peekUndo()
-{
- unsigned int i;
- return getUndoIndex(i) ? m_stack[i] : 0;
-}
-
-
-ACT_Action* ACT_ActionStack::peekRedo()
-{
- unsigned int i;
- return getRedoIndex(i) ? m_stack[i] : 0;
-}
-
-
-void ACT_ActionStack::flush()
-{
- popBack(m_stack.size());
- m_undoIndex = 0;
- m_undoIndexValid = false;
- m_redoIndex = 0;
- m_redoIndexValid = false;
-}
-
-
-bool ACT_ActionStack::canUndo() const
-{
- unsigned int i;
- return getUndoIndex(i);
-}
-
-
-void ACT_ActionStack::undo()
-{
- ACT_Action* action = peekUndo();
- if (action) {
- action->undo();
-
- // Update action indices
- m_redoIndex = m_undoIndex;
- m_redoIndexValid = true;
- if (m_undoIndex) {
- m_undoIndex--;
- }
- else {
- m_undoIndexValid = false;
- }
- }
-}
-
-
-bool ACT_ActionStack::canRedo() const
-{
- unsigned int i;
- return getRedoIndex(i);
-}
-
-
-void ACT_ActionStack::redo()
-{
- ACT_Action* action = peekRedo();
- if (action) {
- action->apply();
-
- // Update action indices
- m_undoIndex = m_redoIndex;
- m_undoIndexValid = true;
- m_redoIndex++;
- m_redoIndexValid = m_redoIndex < m_stack.size();
- }
-}
-
-
-unsigned int ACT_ActionStack::popFront(unsigned int numActions)
-{
- unsigned int numRemoved = 0;
-
- while (numActions-- && m_stack.size()) {
- ACT_Action* action = m_stack[0];
- action->decRef();
- m_stack.pop_front();
- numRemoved++;
- }
- return numRemoved;
-}
-
-
-unsigned int ACT_ActionStack::popBack(unsigned int numActions)
-{
- unsigned int numRemoved = 0;
- unsigned int size;
-
- while (numActions-- && (size = m_stack.size())) {
- ACT_Action* action = m_stack[size-1];
- action->decRef();
- m_stack.pop_back();
- numRemoved++;
- }
- return numRemoved;
-}
-
-
-bool ACT_ActionStack::getUndoIndex(unsigned int& i) const
-{
- i = m_undoIndex;
- return m_undoIndexValid;
-}
-
-
-bool ACT_ActionStack::getRedoIndex(unsigned int& i) const
-{
- i = m_redoIndex;
- return m_redoIndexValid;
-}
diff --git a/intern/action/intern/ACT_CallbackAction.h b/intern/action/intern/ACT_CallbackAction.h
deleted file mode 100644
index 148a77f13ed..00000000000
--- a/intern/action/intern/ACT_CallbackAction.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date June 17, 2001
- */
-
-#ifndef _H_ACT_CALLBACK_ACTION_H
-#define _H_ACT_CALLBACK_ACTION_H
-
-#include "ACT_Action.h"
-#include "ACT_ActionC-Api.h"
-
-
-/**
- * An action implementation that uses callbacks for undo and redo.
- * @author Maarten Gribnau
- * @date June 17, 2001
- */
-
-class ACT_CallbackAction : public ACT_Action {
-public:
- /**
- * Constructs an action with the given name .
- * @param name The name of the action.
- * @param applied State of the action after creation.
- * @param data Pointer to user data passed to the callbacks.
- * @param applyProc Callback invoked for apply action.
- * @param undoProc Callback invoked for undo action.
- */
- ACT_CallbackAction(
- STR_String& name,
- bool applied,
- ACT_ActionUserDataPtr data,
- ACT_ActionApplyProcPtr applyProc,
- ACT_ActionUndoProcPtr undoProc,
- ACT_ActionDisposeProcPtr disposeProc)
- : ACT_Action(name, applied), m_userData(data), m_applyProc(applyProc), m_undoProc(undoProc), m_disposeProc(disposeProc)
- {
- }
-
- /**
- * Default destructor.
- * Will call the dispose callback.
- */
- virtual ~ACT_CallbackAction()
- {
- // Should assert
- m_disposeProc((ACT_ActionPtr)this, m_userData);
- }
-
-
-protected:
- /**
- * Calls the appropriate callback.
- */
- inline virtual void doApply();
-
- /**
- * Calls the appropriate callback.
- */
- inline virtual void doUndo();
-
- /** User data supplied at creation and passed to the callbacks. */
- ACT_ActionUserDataPtr m_userData;
-
- /** Callback invoked for apply action. */
- ACT_ActionApplyProcPtr m_applyProc;
-
- /** Callback invoked for undo action. */
- ACT_ActionApplyProcPtr m_undoProc;
-
- /** Callback invoked when the action is disposed. */
- ACT_ActionDisposeProcPtr m_disposeProc;
-};
-
-
-inline void ACT_CallbackAction::doApply()
-{
- // Should assert
- m_applyProc((ACT_ActionPtr)this, m_userData);
-}
-
-
-inline void ACT_CallbackAction::doUndo()
-{
- // Should assert
- m_undoProc((ACT_ActionPtr)this, m_userData);
-}
-
-
-#endif // _H_ACT_CALLBACK_ACTION_H
-
diff --git a/intern/action/make/msvc_6_0/action.dsp b/intern/action/make/msvc_6_0/action.dsp
deleted file mode 100644
index 3ea450b19a7..00000000000
--- a/intern/action/make/msvc_6_0/action.dsp
+++ /dev/null
@@ -1,128 +0,0 @@
-# Microsoft Developer Studio Project File - Name="action" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=action - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "action.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "action.mak" CFG="action - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "action - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "action - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "action - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../../../../obj/windows/intern/action/"
-# PROP Intermediate_Dir "../../../../../obj/windows/intern/action/"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "../.." /I "../../../../lib/windows/memutil/include/" /I "../../../../lib/windows/string/include/" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ELSEIF "$(CFG)" == "action - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../../../../obj/windows/intern/action/debug"
-# PROP Intermediate_Dir "../../../../../obj/windows/intern/action/debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../.." /I "../../../../lib/windows/memutil/include/" /I "../../../../lib/windows/string/include/" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo
-
-!ENDIF
-
-# Begin Target
-
-# Name "action - Win32 Release"
-# Name "action - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\intern\ACT_Action.cpp
-# End Source File
-# Begin Source File
-
-SOURCE="..\..\intern\ACT_ActionC-Api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\ACT_ActionStack.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Group "intern"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\intern\ACT_CallbackAction.h
-# End Source File
-# End Group
-# Begin Group "extern"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\ACT_Action.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\..\ACT_ActionC-Api.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\ACT_ActionStack.h
-# End Source File
-# End Group
-# End Group
-# End Target
-# End Project
diff --git a/intern/action/make/msvc_6_0/action.dsw b/intern/action/make/msvc_6_0/action.dsw
deleted file mode 100644
index f93cbb896fd..00000000000
--- a/intern/action/make/msvc_6_0/action.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "action"=".\action.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/action/make/msvc_7_0/action.sln b/intern/action/make/msvc_7_0/action.sln
deleted file mode 100644
index 3ab830940c8..00000000000
--- a/intern/action/make/msvc_7_0/action.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "action", "action.vcproj", "{FA745D82-2D98-4843-8B72-874AB3622A8C}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {FA745D82-2D98-4843-8B72-874AB3622A8C}.Debug.ActiveCfg = Debug|Win32
- {FA745D82-2D98-4843-8B72-874AB3622A8C}.Debug.Build.0 = Debug|Win32
- {FA745D82-2D98-4843-8B72-874AB3622A8C}.Release.ActiveCfg = Release|Win32
- {FA745D82-2D98-4843-8B72-874AB3622A8C}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/intern/action/make/msvc_7_0/action.vcproj b/intern/action/make/msvc_7_0/action.vcproj
deleted file mode 100644
index 04af58a8d52..00000000000
--- a/intern/action/make/msvc_7_0/action.vcproj
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="action"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\../../../../../obj/windows/intern/action/debug"
- IntermediateDirectory=".\../../../../../obj/windows/intern/action/debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="../..,../../../../lib/windows/memutil/include/,../../../../lib/windows/string/include/"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="5"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\../../../../../obj/windows/intern/action/debug/action.pch"
- AssemblerListingLocation=".\../../../../../obj/windows/intern/action/debug/"
- ObjectFile=".\../../../../../obj/windows/intern/action/debug/"
- ProgramDataBaseFileName=".\../../../../../obj/windows/intern/action/debug/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile=".\../../../../../obj/windows/intern/action/debug\action.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\../../../../../obj/windows/intern/action"
- IntermediateDirectory=".\../../../../../obj/windows/intern/action"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="../..,../../../../lib/windows/memutil/include/,../../../../lib/windows/string/include/"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="4"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\../../../../../obj/windows/intern/action/action.pch"
- AssemblerListingLocation=".\../../../../../obj/windows/intern/action/"
- ObjectFile=".\../../../../../obj/windows/intern/action/"
- ProgramDataBaseFileName=".\../../../../../obj/windows/intern/action/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile=".\../../../../../obj/windows/intern/action\action.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="..\..\intern\ACT_Action.cpp">
- </File>
- <File
- RelativePath="..\..\intern\ACT_ActionC-Api.cpp">
- </File>
- <File
- RelativePath="..\..\intern\ACT_ActionStack.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <Filter
- Name="intern"
- Filter="">
- <File
- RelativePath="..\..\intern\ACT_CallbackAction.h">
- </File>
- </Filter>
- <Filter
- Name="extern"
- Filter="">
- <File
- RelativePath="..\..\ACT_Action.h">
- </File>
- <File
- RelativePath="..\..\ACT_ActionC-Api.h">
- </File>
- <File
- RelativePath="..\..\ACT_ActionStack.h">
- </File>
- </Filter>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/action/test/action_c_test/ActionTest.c b/intern/action/test/action_c_test/ActionTest.c
deleted file mode 100644
index 8f169528204..00000000000
--- a/intern/action/test/action_c_test/ActionTest.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ACT_ActionC-Api.h"
-#include "TestAction.h"
-
-int main(int argc, char *argv[])
-{
- ACT_ActionStackPtr stack = ACT_ActionStackCreate (3);
- ACT_ActionPtr action = ACT_ActionCreate("action1", 0, 0, printApplied, printUndone, printDisposed);
- ACT_ActionStackPush(stack, action);
- MEM_RefCountedDecRef(action);
- action = ACT_ActionCreate("action2", 0, 0, printApplied, printUndone, printDisposed);
- ACT_ActionStackPush(stack, action);
- MEM_RefCountedDecRef(action);
- action = ACT_ActionCreate("action3", 0, 0, printApplied, printUndone, printDisposed);
- ACT_ActionStackPush(stack, action);
- MEM_RefCountedDecRef(action);
-
- ACT_ActionStackUndo(stack);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackRedo(stack);
- ACT_ActionStackRedo(stack);
- ACT_ActionStackRedo(stack);
-
- ACT_ActionStackSetMaxStackDepth(stack, 1);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackRedo(stack);
- ACT_ActionStackSetMaxStackDepth(stack, 5);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackRedo(stack);
-
- action = ACT_ActionCreate("action4", 0, 0, printApplied, printUndone, printDisposed);
- ACT_ActionStackPush(stack, action);
- MEM_RefCountedDecRef(action);
- ACT_ActionStackUndo(stack);
- action = ACT_ActionCreate("action5", 0, 0, printApplied, printUndone, printDisposed);
- ACT_ActionStackPush(stack, action);
- MEM_RefCountedDecRef(action);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackUndo(stack);
- ACT_ActionStackRedo(stack);
- ACT_ActionStackRedo(stack);
-
- return 0;
-}
diff --git a/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsp b/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsp
deleted file mode 100644
index 807024f20be..00000000000
--- a/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsp
+++ /dev/null
@@ -1,109 +0,0 @@
-# Microsoft Developer Studio Project File - Name="action_c_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=action_c_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "action_c_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "action_c_test.mak" CFG="action_c_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "action_c_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "action_c_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "action_c_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../../../../../../obj/windows/intern/action/test"
-# PROP Intermediate_Dir "../../../../../../../obj/windows/intern/action/test"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "../../../.." /I "../../../../../../lib/windows/memutil/include/" /I "../../../../../../lib/windows/string/include/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib string.lib memutil.lib /nologo /subsystem:console /machine:I386 /libpath:"../../../../../../lib/windows/memutil/lib" /libpath:"../../../../../../lib/windows/string/lib"
-
-!ELSEIF "$(CFG)" == "action_c_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../../../../../../obj/windows/intern/action/test/debug"
-# PROP Intermediate_Dir "../../../../../../../obj/windows/intern/action/test/debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../.." /I "../../../../../../lib/windows/memutil/include/" /I "../../../../../../lib/windows/string/include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib string.lib memutil.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../../../../lib/windows/memutil/lib/debug" /libpath:"../../../../../../lib/windows/string/lib/debug"
-
-!ENDIF
-
-# Begin Target
-
-# Name "action_c_test - Win32 Release"
-# Name "action_c_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\ActionTest.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\TestAction.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\TestAction.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsw b/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsw
deleted file mode 100644
index 688f24e4d53..00000000000
--- a/intern/action/test/action_c_test/make/msvc_6_0/action_c_test.dsw
+++ /dev/null
@@ -1,44 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "action"="..\..\..\..\make\msvc_6_0\action.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "action_c_test"=".\action_c_test.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name action
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/action/test/action_cpp_test/ActionTest.cpp b/intern/action/test/action_cpp_test/ActionTest.cpp
deleted file mode 100644
index 55173bafb7b..00000000000
--- a/intern/action/test/action_cpp_test/ActionTest.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ACT_ActionStack.h"
-#include "TestAction.h"
-
-int main()
-{
- ACT_ActionStack testStack (3);
- TestAction* testAction = new TestAction (STR_String("action1"));
- testStack.push(*testAction);
- testAction->decRef();
- testAction = new TestAction (STR_String("action2"));
- testStack.push(*testAction);
- testAction->decRef();
- testAction = new TestAction (STR_String("action3"));
- testStack.push(*testAction);
- testAction->decRef();
-
- testStack.undo();
- testStack.undo();
- testStack.undo();
- testStack.redo();
- testStack.redo();
- testStack.redo();
-
- testStack.setMaxStackDepth(1);
- testStack.undo();
- testStack.redo();
- testStack.setMaxStackDepth(5);
- testStack.undo();
- testStack.redo();
-
- testAction = new TestAction (STR_String("action4"));
- testStack.push(*testAction);
- testAction->decRef();
- testStack.undo();
- testAction = new TestAction (STR_String("action5"));
- testStack.push(*testAction);
- testAction->decRef();
- testStack.undo();
- testStack.undo();
- testStack.redo();
- testStack.redo();
-
- return 0;
-}
diff --git a/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsp b/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsp
deleted file mode 100644
index bc0c40b6d36..00000000000
--- a/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsp
+++ /dev/null
@@ -1,105 +0,0 @@
-# Microsoft Developer Studio Project File - Name="action_cpp_test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=action_cpp_test - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "action_cpp_test.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "action_cpp_test.mak" CFG="action_cpp_test - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "action_cpp_test - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "action_cpp_test - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "action_cpp_test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "../../../../../../../obj/windows/intern/action/test"
-# PROP Intermediate_Dir "../../../../../../../obj/windows/intern/action/test"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "../../../.." /I "../../../../../../lib/windows/memutil/include/" /I "../../../../../../lib/windows/string/include/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib string.lib memutil.lib /nologo /subsystem:console /machine:I386 /libpath:"../../../../../../lib/windows/memutil/lib" /libpath:"../../../../../../lib/windows/string/lib"
-
-!ELSEIF "$(CFG)" == "action_cpp_test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "../../../../../../../obj/windows/intern/action/test/debug"
-# PROP Intermediate_Dir "../../../../../../../obj/windows/intern/action/test/debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../.." /I "../../../../../../lib/windows/memutil/include/" /I "../../../../../../lib/windows/string/include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib string.lib memutil.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../../../../lib/windows/memutil/lib/debug" /libpath:"../../../../../../lib/windows/string/lib/debug"
-
-!ENDIF
-
-# Begin Target
-
-# Name "action_cpp_test - Win32 Release"
-# Name "action_cpp_test - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\ActionTest.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\TestAction.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsw b/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsw
deleted file mode 100644
index 0a9d7374379..00000000000
--- a/intern/action/test/action_cpp_test/make/msvc_6_0/action_cpp_test.dsw
+++ /dev/null
@@ -1,44 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "action"="..\..\..\..\make\msvc_6_0\action.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "action_cpp_test"=".\action_cpp_test.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
- Begin Project Dependency
- Project_Dep_Name action
- End Project Dependency
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/bmfont/BMF_Api.h b/intern/bmfont/BMF_Api.h
index 001a9788920..4465242e9fa 100644
--- a/intern/bmfont/BMF_Api.h
+++ b/intern/bmfont/BMF_Api.h
@@ -89,13 +89,30 @@ int BMF_GetCharacterWidth(BMF_Font* font, char c);
int BMF_GetStringWidth(BMF_Font* font, char* str);
/**
+ * Returns the bounding box of a string of characters.
+ * @param font The font to use.
+ * @param str The string.
+ * @param llx Lower left x coord
+ * @param lly Lower left y coord
+ * @param urx Upper right x coord
+ * @param ury Upper right y coord
+ */
+void BMF_GetStringBoundingBox(BMF_Font* font, char* str, float*llx, float *lly, float *urx, float *ury);
+
+
+/**
* Returns the bounding box of the font. The width and
* height represent the bounding box of the union of
* all glyps. The minimum and maximum values of the
* box represent the extent of the font and its positioning
* about the origin.
*/
-void BMF_GetBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_r, int *ymax_r);
+void BMF_GetFontBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_r, int *ymax_r);
+
+/**
+ * Same as GetFontBoundingBox but only returns the height
+ */
+int BMF_GetFontHeight(BMF_Font* font);
/**
* Convert the given @a font to a texture, and return the GL texture
@@ -122,6 +139,24 @@ int BMF_GetFontTexture(BMF_Font* font);
*/
void BMF_DrawStringTexture(BMF_Font* font, char* string, float x, float y, float z);
+ /**
+ * Draw the given @a string at the point @a xpos, @a ypos using
+ * char and float buffers.
+ *
+ * @param string The c-string to draw.
+ * @param xpos The x coordinate to start drawing at.
+ * @param ypos The y coordinate to start drawing at.
+ * @param fgcol The forground color.
+ * @param bgcol The background color.
+ * @param buf Unsigned char image buffer, when NULL to not operate on it.
+ * @param fbuf float image buffer, when NULL to not operate on it.
+ * @param w image buffer width.
+ * @param h image buffer height.
+ * @param channels number of channels in the image (3 or 4 - currently)
+ */
+void BMF_DrawStringBuf(BMF_Font* font, char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h, int channels);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/bmfont/intern/BMF_Api.cpp b/intern/bmfont/intern/BMF_Api.cpp
index 46776b08ba0..24e053515fb 100644
--- a/intern/bmfont/intern/BMF_Api.cpp
+++ b/intern/bmfont/intern/BMF_Api.cpp
@@ -150,11 +150,24 @@ int BMF_GetStringWidth(BMF_Font* font, char* str)
return ((BMF_BitmapFont*)font)->GetStringWidth(str);
}
+void BMF_GetStringBoundingBox(BMF_Font* font, char* str, float*llx, float *lly, float *urx, float *ury){
+ if (!font){
+ *llx = *lly = *urx = *ury = 0;
+ }else{
+ ((BMF_BitmapFont*)font)->GetStringBoundingBox(str, llx, lly, urx, ury);
+ }
+}
-void BMF_GetBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_r, int *ymax_r)
+void BMF_GetFontBoundingBox(BMF_Font* font, int *xmin_r, int *ymin_r, int *xmax_r, int *ymax_r)
{
if (!font) return;
- ((BMF_BitmapFont*)font)->GetBoundingBox(*xmin_r, *ymin_r, *xmax_r, *ymax_r);
+ ((BMF_BitmapFont*)font)->GetFontBoundingBox(*xmin_r, *ymin_r, *xmax_r, *ymax_r);
+}
+
+int BMF_GetFontHeight(BMF_Font* font)
+{
+ if (!font) return -1;
+ return ((BMF_BitmapFont*)font)->GetFontHeight();
}
int BMF_GetFontTexture(BMF_Font* font) {
@@ -166,3 +179,8 @@ void BMF_DrawStringTexture(BMF_Font* font, char *string, float x, float y, float
if (!font) return;
((BMF_BitmapFont*)font)->DrawStringTexture(string, x, y, z);
}
+
+void BMF_DrawStringBuf(BMF_Font* font, char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h, int channels) {
+ if (!font) return;
+ ((BMF_BitmapFont*)font)->DrawStringBuf(str, posx, posy, col, buf, fbuf, w, h, channels);
+}
diff --git a/intern/bmfont/intern/BMF_BitmapFont.cpp b/intern/bmfont/intern/BMF_BitmapFont.cpp
index bbba2c978dd..afdcf7fbfbb 100644
--- a/intern/bmfont/intern/BMF_BitmapFont.cpp
+++ b/intern/bmfont/intern/BMF_BitmapFont.cpp
@@ -35,6 +35,11 @@
* Copyright (C) 2001 NaN Technologies B.V.
*/
+
+#include <stdio.h>
+
+
+
#include <string.h>
#ifdef HAVE_CONFIG_H
@@ -107,7 +112,7 @@ int BMF_BitmapFont::GetStringWidth(char* str)
return length;
}
-void BMF_BitmapFont::GetBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax)
+void BMF_BitmapFont::GetFontBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax)
{
xMin = m_fontData->xmin;
yMin = m_fontData->ymin;
@@ -115,6 +120,32 @@ void BMF_BitmapFont::GetBoundingBox(int & xMin, int & yMin, int & xMax, int & yM
yMax = m_fontData->ymax;
}
+int BMF_BitmapFont::GetFontHeight( void )
+{
+ return m_fontData->ymax - m_fontData->ymin;
+}
+
+void BMF_BitmapFont::GetStringBoundingBox(char* str, float*llx, float *lly, float *urx, float *ury)
+{
+ unsigned char c;
+ int length = 0;
+ int ascent = 0;
+ int descent = 0;
+
+ while ( (c = (unsigned char) *str++) ) {
+ length += m_fontData->chars[c].advance;
+ int d = m_fontData->chars[c].yorig;
+ int a = m_fontData->chars[c].height - m_fontData->chars[c].yorig;
+ if(a > ascent) ascent = a;
+ if(d > descent) descent = d;
+ }
+ *llx = (float)0;
+ *lly = (float)-descent;
+ *urx = (float)length;
+ *ury = (float)ascent;
+}
+
+
int BMF_BitmapFont::GetTexture()
{
int fWidth = m_fontData->xmax - m_fontData->xmin;
@@ -208,3 +239,88 @@ void BMF_BitmapFont::DrawStringTexture(char *str, float x, float y, float z)
}
glEnd();
}
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+void BMF_BitmapFont::DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h, int channels)
+{
+ int x, y;
+
+ if (buf==0 && fbuf==0)
+ return;
+
+ /*offset for font*/
+ posx -= m_fontData->xmin;
+ posy -= m_fontData->ymin;
+
+ if (buf) {
+ unsigned char colch[4];
+ unsigned char *max, *pixel;
+ unsigned char c;
+
+ for (x=0; x<4; x++) {
+ colch[x] = FTOCHAR(col[x]);
+ }
+
+ max = buf + (4 * (w * h));
+ while ((c = (unsigned char) *str++)) {
+ BMF_CharData & cd = m_fontData->chars[c];
+ if (cd.data_offset != -1) {
+ for (y = 0; y < cd.height; y++) {
+ unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*y];
+ for (x = cd.xorig; x < cd.width; x++) {
+ pixel = buf + 4 * (((posy + y - cd.yorig) * w) + (posx + x));
+ if ((pixel < max) && (pixel > buf)) {
+ int byteIdx = x/8;
+ int bitIdx = 7 - (x%8);
+
+ if (chrRow[byteIdx]&(1<<bitIdx)) {
+ pixel[0] = colch[0];
+ pixel[1] = colch[1];
+ pixel[2] = colch[2];
+ if (channels==4) {
+ pixel[4] = 1; /*colch[3];*/
+ }
+
+ }
+ }
+ }
+ }
+ }
+ posx += cd.advance;
+ }
+ }
+
+ if (fbuf) {
+ float *pixel, *max;
+ unsigned char c;
+ int xi, yi;
+
+ max = fbuf + (4 * (w * h));
+
+ while ((c = (unsigned char) *str++)) {
+ BMF_CharData & cd = m_fontData->chars[c];
+ if (cd.data_offset != -1) {
+ for (yi = 0; yi < cd.height; yi++) {
+ unsigned char* chrRow = &m_fontData->bitmap_data[cd.data_offset + ((cd.width+7)/8)*yi];
+ for (xi = cd.xorig; xi < cd.width; xi++) {
+ pixel = fbuf + 4 * (((posy + yi - cd.yorig) * w) + (posx + xi));
+ if ((pixel < max) && (pixel > fbuf)) {
+ int byteIdx = xi/8;
+ int bitIdx = 7 - (xi%8);
+
+ if (chrRow[byteIdx]&(1<<bitIdx)) {
+ pixel[0] = col[0];
+ pixel[1] = col[1];
+ pixel[2] = col[2];
+ if (channels==4) {
+ pixel[3] = 1; /*col[3];*/
+ }
+ }
+ }
+ }
+ }
+ }
+ posx += cd.advance;
+ }
+ }
+}
diff --git a/intern/bmfont/intern/BMF_BitmapFont.h b/intern/bmfont/intern/BMF_BitmapFont.h
index 30cfd650353..f8d3d5370dd 100644
--- a/intern/bmfont/intern/BMF_BitmapFont.h
+++ b/intern/bmfont/intern/BMF_BitmapFont.h
@@ -76,7 +76,24 @@ public:
* box represent the extent of the font and its positioning
* about the origin.
*/
- void GetBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax);
+ void GetFontBoundingBox(int & xMin, int & yMin, int & xMax, int & yMax);
+
+ /**
+ * Return the bounding box height of the font.
+ */
+ int GetFontHeight(void);
+
+ /**
+ * Returns the bounding box of a string of characters.
+ * @param font The font to use.
+ * @param str The string.
+ * @param llx Lower left x coord
+ * @param lly Lower left y coord
+ * @param urx Upper right x coord
+ * @param ury Upper right y coord
+ */
+ void GetStringBoundingBox(char* str, float*llx, float *lly, float *urx, float *ury);
+
/**
* Convert the font to a texture, and return the GL texture
@@ -101,6 +118,22 @@ public:
*/
void DrawStringTexture(char* string, float x, float y, float z);
+ /**
+ * Draw the given @a string at the point @a xpos, @a ypos using
+ * char and float buffers.
+ *
+ * @param string The c-string to draw.
+ * @param xpos The x coordinate to start drawing at.
+ * @param ypos The y coordinate to start drawing at.
+ * @param col The forground color.
+ * @param buf Unsigned char image buffer, when NULL to not operate on it.
+ * @param fbuf float image buffer, when NULL to not operate on it.
+ * @param w image buffer width.
+ * @param h image buffer height.
+ * @param channels number of channels in the image (3 or 4 - currently)
+ */
+ void DrawStringBuf(char *str, int posx, int posy, float *col, unsigned char *buf, float *fbuf, int w, int h, int channels);
+
protected:
/** Pointer to the font data. */
BMF_FontData* m_fontData;
diff --git a/intern/boolop/intern/BOP_BSPNode.cpp b/intern/boolop/intern/BOP_BSPNode.cpp
index af5c40baad9..68a20d7a5a4 100644
--- a/intern/boolop/intern/BOP_BSPNode.cpp
+++ b/intern/boolop/intern/BOP_BSPNode.cpp
@@ -58,30 +58,82 @@ BOP_BSPNode::~BOP_BSPNode()
/**
* Adds a new face to this BSP tree.
- * @param p1 first face point.
- * @param p2 second face point.
- * @param p3 third face point.
+ * @param pts vector containing face points
* @param plane face plane.
*/
-unsigned int BOP_BSPNode::addFace(const MT_Point3& p1,
- const MT_Point3& p2,
- const MT_Point3& p3,
- const MT_Plane3& plane)
+
+unsigned int BOP_BSPNode::addFace(BOP_BSPPoints pts,
+ const MT_Plane3& plane )
{
unsigned int newDeep = 0;
- BOP_TAG tag = BOP_createTAG(testPoint(p1), testPoint(p2), testPoint(p3));
- if ((tag & IN_IN_IN) != 0) {
+ BOP_TAG tag = ON;
+
+ // find out if any points on the "face" lie in either half-space
+ BOP_IT_BSPPoints ptsEnd = pts.end();
+ for(BOP_IT_BSPPoints itp=pts.begin();itp!=ptsEnd;itp++){
+ tag = (BOP_TAG) ((int) tag | (int)testPoint(*itp));
+ }
+
+ if (tag == ON) { } // face lies on hyperplane: do nothing
+ else if ((tag & IN) != 0 && (tag & OUT) == 0) { // face is entirely on inside
if (m_inChild != NULL)
- newDeep = m_inChild->addFace(p1, p2, p3, plane) + 1;
+ newDeep = m_inChild->addFace(pts, plane) + 1;
+ else {
+ m_inChild = new BOP_BSPNode(plane);
+ newDeep = 2;
+ }
+ } else if ((tag & OUT) != 0 && (tag & IN) == 0) { // face is entirely on outside
+ if (m_outChild != NULL)
+ newDeep = m_outChild->addFace(pts, plane) + 1;
+ else {
+ m_outChild = new BOP_BSPNode(plane);
+ newDeep = 2;
+ }
+ } else { // face lies in both half-spaces: split it
+ BOP_BSPPoints inside, outside;
+ MT_Point3 lpoint= pts[pts.size()-1];
+ BOP_TAG ltag = testPoint(lpoint);
+ BOP_TAG tstate = ltag;
+
+ // classify each line segment, looking for endpoints which lie on different
+ // sides of the hyperplane.
+
+ ptsEnd = pts.end();
+ for(BOP_IT_BSPPoints itp=pts.begin();itp!=ptsEnd;itp++){
+ MT_Point3 npoint= *itp;
+ BOP_TAG ntag = testPoint(npoint);
+
+ if(ltag != ON) { // last point not on hyperplane
+ if(tstate == IN) {
+ if (m_inChild != NULL) inside.push_back(lpoint);
+ } else {
+ if (m_outChild != NULL) outside.push_back(lpoint);
+ }
+ if(ntag != ON && ntag != tstate) { // last, self in different half-spaces
+ MT_Point3 mpoint = BOP_intersectPlane( m_plane, lpoint, npoint );
+ if (m_inChild != NULL) inside.push_back(mpoint);
+ if (m_outChild != NULL) outside.push_back(mpoint);
+ tstate = ntag;
+ }
+ } else { // last point on hyperplane, so we're switching
+ // half-spaces
+ // boundary point belong to both faces
+ if (m_inChild != NULL) inside.push_back(lpoint);
+ if (m_outChild != NULL) outside.push_back(lpoint);
+ tstate = ntag; // state changes to new point tag
+ }
+ lpoint = npoint; // save point, tag for next iteration
+ ltag = ntag;
+ }
+
+ if (m_inChild != NULL)
+ newDeep = m_inChild->addFace(inside, plane) + 1;
else {
m_inChild = new BOP_BSPNode(plane);
newDeep = 2;
}
- }
-
- if ((tag & OUT_OUT_OUT) != 0){
if (m_outChild != NULL)
- newDeep = MT_max(newDeep, m_outChild->addFace(p1, p2, p3, plane) + 1);
+ newDeep = MT_max(newDeep, m_outChild->addFace(outside, plane) + 1);
else {
m_outChild = new BOP_BSPNode(plane);
newDeep = MT_max(newDeep,(unsigned int)2);
@@ -653,19 +705,13 @@ int BOP_BSPNode::splitTriangle(MT_Point3* res,
*/
void BOP_BSPNode::print(unsigned int deep)
{
- for (unsigned int i = 0; i < deep; ++i)
- cout << " ";
-
- cout << m_plane.x() << ", ";
- cout << m_plane.y() << ", ";
- cout << m_plane.z() << ", ";
- cout << m_plane.w() << endl;
- if (m_inChild != NULL) {
- cout << "IN:";
+ cout << "(" << deep << "," << m_plane << ")," << endl;
+ if (m_inChild != NULL)
m_inChild->print(deep + 1);
- }
- if (m_outChild != NULL) {
- cout << "OUT:";
+ else
+ cout << "(" << deep+1 << ",None)," << endl;
+ if (m_outChild != NULL)
m_outChild->print(deep + 1);
- }
+ else
+ cout << "(" << deep+1 << ",None)," << endl;
}
diff --git a/intern/boolop/intern/BOP_BSPNode.h b/intern/boolop/intern/BOP_BSPNode.h
index d4f7f1c28a1..39a84b94dec 100644
--- a/intern/boolop/intern/BOP_BSPNode.h
+++ b/intern/boolop/intern/BOP_BSPNode.h
@@ -35,6 +35,9 @@
#include "BOP_Tag.h"
#include "BOP_Face.h"
+typedef vector<MT_Point3> BOP_BSPPoints;
+typedef vector<MT_Point3>::iterator BOP_IT_BSPPoints;
+
class BOP_BSPNode
{
protected:
@@ -47,9 +50,7 @@ public:
// Construction methods
BOP_BSPNode(const MT_Plane3& plane);
~BOP_BSPNode();
- unsigned int addFace(const MT_Point3& p1,
- const MT_Point3& p2,
- const MT_Point3& p3,
+ unsigned int addFace(BOP_BSPPoints pts,
const MT_Plane3& plane);
BOP_TAG classifyFace(const MT_Point3& p1,
const MT_Point3& p2,
diff --git a/intern/boolop/intern/BOP_BSPTree.cpp b/intern/boolop/intern/BOP_BSPTree.cpp
index 4e5c171bc83..3ae375294cd 100644
--- a/intern/boolop/intern/BOP_BSPTree.cpp
+++ b/intern/boolop/intern/BOP_BSPTree.cpp
@@ -69,6 +69,7 @@ void BOP_BSPTree::addMesh(BOP_Mesh* mesh, BOP_Faces& facesList)
* @param mesh Input data for BSP tree.
* @param face index to mesh face.
*/
+
void BOP_BSPTree::addFace(BOP_Mesh* mesh, BOP_Face* face)
{
addFace(mesh->getVertex(face->getVertex(0))->getPoint(),
@@ -91,8 +92,15 @@ void BOP_BSPTree::addFace(const MT_Point3& p1,
{
if (m_root == NULL)
m_root = new BOP_BSPNode(plane);
- else
- m_root->addFace(p1,p2,p3,plane);
+ else {
+ BOP_BSPPoints pts;
+
+ pts.push_back(p1);
+ pts.push_back(p2);
+ pts.push_back(p3);
+
+ m_root->addFace(pts,plane);
+ }
// update bounding box
m_bbox.add(p1);
@@ -171,37 +179,6 @@ unsigned int BOP_BSPTree::getDeep() const
}
/**
- * Computes the bounding BSP data.
- */
-void BOP_BSPTree::computeBox()
-{
- if ( m_root != NULL ) {
- MT_Point3 p1(m_bbox.m_minX,m_bbox.m_minY,m_bbox.m_minZ);
- MT_Point3 p2(m_bbox.m_maxX,m_bbox.m_minY,m_bbox.m_minZ);
- MT_Point3 p3(m_bbox.m_maxX,m_bbox.m_maxY,m_bbox.m_minZ);
- MT_Point3 p4(m_bbox.m_minX,m_bbox.m_maxY,m_bbox.m_minZ);
- MT_Point3 p5(m_bbox.m_minX,m_bbox.m_minY,m_bbox.m_maxZ);
- MT_Point3 p6(m_bbox.m_maxX,m_bbox.m_minY,m_bbox.m_maxZ);
- MT_Point3 p7(m_bbox.m_maxX,m_bbox.m_maxY,m_bbox.m_maxZ);
- MT_Point3 p8(m_bbox.m_minX,m_bbox.m_maxY,m_bbox.m_maxZ);
-
- MT_Plane3 plane1(p3,p2,p1);
- MT_Plane3 plane2(p5,p6,p7);
- MT_Plane3 plane3(p1,p2,p6);
- MT_Plane3 plane4(p8,p7,p3);
- MT_Plane3 plane5(p2,p3,p7);
- MT_Plane3 plane6(p1,p5,p8);
-
- BOP_BSPNode bsp(plane1);
- bsp.addFace(p5,p6,p7,plane2);
- bsp.addFace(p1,p2,p6,plane3);
- bsp.addFace(p8,p7,p3,plane4);
- bsp.addFace(p2,p3,p7,plane5);
- bsp.addFace(p1,p5,p8,plane6);
- }
-}
-
-/**
* Prints debug information.
*/
void BOP_BSPTree::print()
diff --git a/intern/boolop/intern/BOP_BSPTree.h b/intern/boolop/intern/BOP_BSPTree.h
index 7e5b5a4fa76..412d5a40753 100644
--- a/intern/boolop/intern/BOP_BSPTree.h
+++ b/intern/boolop/intern/BOP_BSPTree.h
@@ -65,7 +65,6 @@ public:
const MT_Point3& p3,
const MT_Plane3& plane) const;
unsigned int getDeep() const;
- void computeBox();
void print();
inline void setRoot(BOP_BSPNode* root) {m_root=root;};
inline BOP_BSPNode* getRoot() const {return m_root;};
diff --git a/intern/boolop/intern/BOP_Face.cpp b/intern/boolop/intern/BOP_Face.cpp
index 80c917f2838..ebe34237d4f 100644
--- a/intern/boolop/intern/BOP_Face.cpp
+++ b/intern/boolop/intern/BOP_Face.cpp
@@ -44,6 +44,8 @@ BOP_Face::BOP_Face(MT_Plane3 plane, BOP_Index originalFace)
m_plane = plane;
m_tag = UNCLASSIFIED;
m_originalFace = originalFace;
+ m_split = 0;
+ m_bbox = NULL;
}
/**
@@ -197,6 +199,14 @@ bool BOP_Face3::getNextVertex(BOP_Index v, BOP_Index &w)
*/
void BOP_Face3::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
{
+ /* if the old index really exists, and new index also exists already,
+ * don't create an edge with both vertices == newIndex */
+
+ if( (m_indexs[0] == oldIndex || m_indexs[1] == oldIndex || m_indexs[2] == oldIndex) &&
+ (m_indexs[0] == newIndex || m_indexs[1] == newIndex || m_indexs[2] == newIndex) ) {
+ setTAG(BROKEN);
+ }
+
if (m_indexs[0] == oldIndex) m_indexs[0] = newIndex;
else if (m_indexs[1] == oldIndex) m_indexs[1] = newIndex;
else if (m_indexs[2] == oldIndex) m_indexs[2] = newIndex;
diff --git a/intern/boolop/intern/BOP_Face.h b/intern/boolop/intern/BOP_Face.h
index 7db5ab1fe5c..1d854ec00ca 100644
--- a/intern/boolop/intern/BOP_Face.h
+++ b/intern/boolop/intern/BOP_Face.h
@@ -34,6 +34,7 @@
#include "BOP_Tag.h"
#include "MT_Plane3.h"
#include "BOP_Indexs.h"
+#include "BOP_BBox.h"
#include <iostream>
#include <vector>
using namespace std;
@@ -53,10 +54,12 @@ private:
protected:
BOP_Index m_indexs[4];
unsigned int m_size;
+ unsigned int m_split;
+ BOP_BBox *m_bbox;
public:
BOP_Face(MT_Plane3 plane, BOP_Index originalFace);
- virtual ~BOP_Face(){};
+ virtual ~BOP_Face(){if (m_bbox) delete m_bbox;};
inline MT_Plane3 getPlane() const {return m_plane;};
inline void setPlane(const MT_Plane3 plane) {m_plane = plane;};
inline BOP_TAG getTAG() const {return m_tag;};
@@ -65,7 +68,15 @@ public:
inline void setOriginalFace(const BOP_Index originalFace) {m_originalFace=originalFace;};
inline BOP_Index getVertex(unsigned int i) const {return m_indexs[i];};
inline void setVertex(const BOP_Index idx, const BOP_Index i) {m_indexs[idx]=i;};
+ inline unsigned int getSplit() const {return m_split;};
+ inline void setSplit(const unsigned int i) {m_split=i;};
+
void invert();
+ inline void setBBox(const MT_Point3& p1,const MT_Point3& p2,const MT_Point3& p3) {
+ m_bbox = new BOP_BBox(p1, p2, p3);};
+ inline BOP_BBox *getBBox() {return m_bbox;};
+ inline void freeBBox(){if (m_bbox!=NULL) {delete m_bbox; m_bbox=NULL;} };
+
inline unsigned int size() const {return m_size;};
virtual bool getEdgeIndex(BOP_Index v1, BOP_Index v2, unsigned int &e) = 0;
diff --git a/intern/boolop/intern/BOP_Face2Face.cpp b/intern/boolop/intern/BOP_Face2Face.cpp
index 7e2b6bd7b2f..ef67e5dd24b 100644
--- a/intern/boolop/intern/BOP_Face2Face.cpp
+++ b/intern/boolop/intern/BOP_Face2Face.cpp
@@ -1,4 +1,7 @@
/**
+ *
+ * $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -23,7 +26,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Marc Freixas, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -144,9 +147,18 @@ void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace);
* @param mesh mesh that contains the faces, edges and vertices
* @param facesA set of faces from object A
* @param facesB set of faces from object B
+ *
+ * Two optimizations were added here:
+ * 1) keep the bounding box for a face once it's created; this is
+ * especially important for B faces, since they were being created and
+ * recreated over and over
+ * 2) associate a "split" index in the faceB vector with each A face; when
+ * an A face is split, we will not need to recheck any B faces have
+ * already been checked against that original A face
*/
+
void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
-{
+{
for(unsigned int idxFaceA=0;idxFaceA<facesA->size();idxFaceA++) {
BOP_Face *faceA = (*facesA)[idxFaceA];
MT_Plane3 planeA = faceA->getPlane();
@@ -154,23 +166,33 @@ void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
MT_Point3 p2 = mesh->getVertex(faceA->getVertex(1))->getPoint();
MT_Point3 p3 = mesh->getVertex(faceA->getVertex(2))->getPoint();
- BOP_BBox boxA(p1,p2,p3);
-
- for(unsigned int idxFaceB=0;
+ /* get (or create) bounding box for face A */
+ if( faceA->getBBox() == NULL )
+ faceA->setBBox(p1,p2,p3);
+ BOP_BBox *boxA = faceA->getBBox();
+
+ /* start checking B faces with the previously stored split index */
+
+ for(unsigned int idxFaceB=faceA->getSplit();
idxFaceB<facesB->size() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) {
BOP_Face *faceB = (*facesB)[idxFaceB];
+ faceA->setSplit(idxFaceB);
if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) {
- BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(),
- mesh->getVertex(faceB->getVertex(1))->getPoint(),
- mesh->getVertex(faceB->getVertex(2))->getPoint());
- if (boxA.intersect(boxB)) {
+ /* get (or create) bounding box for face B */
+ if( faceB->getBBox() == NULL )
+ faceB->setBBox(mesh->getVertex(faceB->getVertex(0))->getPoint(),
+ mesh->getVertex(faceB->getVertex(1))->getPoint(),
+ mesh->getVertex(faceB->getVertex(2))->getPoint());
+ BOP_BBox *boxB = faceB->getBBox();
+
+ if (boxA->intersect(*boxB)) {
MT_Plane3 planeB = faceB->getPlane();
if (BOP_containsPoint(planeB,p1) &&
BOP_containsPoint(planeB,p2) &&
BOP_containsPoint(planeB,p3)) {
if (BOP_orientation(planeB,planeA)>0) {
- BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
+ BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false);
}
}
else {
@@ -178,10 +200,7 @@ void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB)
}
}
}
- if (faceB->getTAG()==BROKEN){
- facesB->erase(facesB->begin()+idxFaceB);
- }else
- idxFaceB++;
+ idxFaceB++;
}
}
@@ -385,56 +404,11 @@ void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace)
for(unsigned int idxFace = firstFace; idxFace < numFaces; idxFace++) {
BOP_Face *face = mesh->getFace(idxFace);
if ((face->getTAG() != BROKEN) && (face->getTAG() != PHANTOM)) {
- BOP_Index v1 = face->getVertex(0);
- BOP_Index v2 = face->getVertex(1);
- BOP_Index v3 = face->getVertex(2);
- MT_Point3 vertex1 = mesh->getVertex(v1)->getPoint();
- MT_Point3 vertex2 = mesh->getVertex(v2)->getPoint();
- MT_Point3 vertex3 = mesh->getVertex(v3)->getPoint();
- int dist12 = BOP_comp(vertex1,vertex2);
- int dist13 = BOP_comp(vertex1,vertex3);
- int dist23 = BOP_comp(vertex2,vertex3);
-
- if (dist12 == 0) {
- if (dist13 == 0) {
- // v1 ~= v2 , v1 ~= v3 , v2 ~= v3
- mesh->replaceVertexIndex(v2,v1);
- mesh->replaceVertexIndex(v3,v1);
- }
- else {
- if (dist23 == 0) {
- mesh->replaceVertexIndex(v1,v2);
- mesh->replaceVertexIndex(v3,v2);
- }
- else {
- mesh->replaceVertexIndex(v1,v2);
- }
- }
- }
- else {
- if (dist13 == 0) {
- // v1 ~= v3
- if (dist23 == 0) {
- mesh->replaceVertexIndex(v1,v3);
- mesh->replaceVertexIndex(v2,v3);
- }
- else {
- mesh->replaceVertexIndex(v1,v3);
- }
- }
- else {
- if (dist23 == 0) {
- // v2 ~= v3
- mesh->replaceVertexIndex(v2,v3);
- } else {
- // all differents
- if (BOP_collinear(vertex1,vertex2,vertex3)) {
- // collinear triangle
- face->setTAG(PHANTOM);
- }
- }
- }
- }
+ MT_Point3 vertex1 = mesh->getVertex(face->getVertex(0))->getPoint();
+ MT_Point3 vertex2 = mesh->getVertex(face->getVertex(1))->getPoint();
+ MT_Point3 vertex3 = mesh->getVertex(face->getVertex(2))->getPoint();
+ if (BOP_collinear(vertex1,vertex2,vertex3)) // collinear triangle
+ face->setTAG(PHANTOM);
}
}
}
@@ -507,7 +481,7 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
if (size == 2) {
// Trivial case, only test the merge ...
- if (BOP_comp(0,points[0].distance(points[1]))==0) {
+ if (BOP_fuzzyZero(points[0].distance(points[1]))) {
face[0] = 3;
size--;
}
@@ -592,8 +566,8 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
// Merge data
MT_Scalar d1 = sortedPoints[1].distance(sortedPoints[0]);
MT_Scalar d2 = sortedPoints[1].distance(sortedPoints[2]);
- if (BOP_comp(0,d1)==0 && sortedFaces[1] != sortedFaces[0]) {
- if (BOP_comp(0,d2)==0 && sortedFaces[1] != sortedFaces[2]) {
+ if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[0]) {
+ if (BOP_fuzzyZero(d2) && sortedFaces[1] != sortedFaces[2]) {
if (d1 < d2) {
// merge 0 and 1
sortedFaces[0] = 3;
@@ -605,7 +579,7 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
if (size == 3) {
// merge 1 and 2 ???
d1 = sortedPoints[1].distance(sortedPoints[2]);
- if (BOP_comp(0,d1)==0 && sortedFaces[1] != sortedFaces[2]) {
+ if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[2]) {
// merge!
sortedFaces[1] = 3;
size--;
@@ -633,7 +607,7 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
if (size == 3) {
// merge 1 i 2 ???
d1 = sortedPoints[1].distance(sortedPoints[2]);
- if (BOP_comp(0,d1)==0 && sortedFaces[1] != sortedFaces[2]) {
+ if (BOP_fuzzyZero(d1) && sortedFaces[1] != sortedFaces[2]) {
// merge!
sortedFaces[1] = 3;
size--;
@@ -642,7 +616,7 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
}
}
else {
- if (BOP_comp(0,d2)==0 && sortedFaces[1] != sortedFaces[2]) {
+ if (BOP_fuzzyZero(d2) && sortedFaces[1] != sortedFaces[2]) {
// merge 1 and 2
sortedFaces[1] = 3;
for(i = 2; i<size-1;i++) {
@@ -653,7 +627,7 @@ void BOP_mergeSort(MT_Point3 *points, unsigned int *face, unsigned int &size, bo
}
else if (size == 4) {
d1 = sortedPoints[2].distance(sortedPoints[3]);
- if (BOP_comp(0,d1)==0 && sortedFaces[2] != sortedFaces[3]) {
+ if (BOP_fuzzyZero(d1) && sortedFaces[2] != sortedFaces[3]) {
// merge 2 and 3
sortedFaces[2] = 3;
size--;
diff --git a/intern/boolop/intern/BOP_Interface.cpp b/intern/boolop/intern/BOP_Interface.cpp
index 6d1ae56da2d..3c61fd6c7b8 100644
--- a/intern/boolop/intern/BOP_Interface.cpp
+++ b/intern/boolop/intern/BOP_Interface.cpp
@@ -152,12 +152,10 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC,
// Create BSPs trees for mesh A & B
BOP_BSPTree bspA;
bspA.addMesh(meshC, *facesA);
- bspA.computeBox();
BOP_BSPTree bspB;
bspB.addMesh(meshC, *facesB);
- bspB.computeBox();
-
+
#ifdef DEBUG
c = chrono.stamp(); t += c;
cout << "Create BSP " << c << endl;
diff --git a/intern/boolop/intern/BOP_MathUtils.cpp b/intern/boolop/intern/BOP_MathUtils.cpp
index 7a0210247eb..e0d96b465ee 100644
--- a/intern/boolop/intern/BOP_MathUtils.cpp
+++ b/intern/boolop/intern/BOP_MathUtils.cpp
@@ -1,4 +1,7 @@
/**
+ *
+ * $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -23,7 +26,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Marc Freixas, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -40,9 +43,38 @@ using namespace std;
*/
int BOP_comp(const MT_Scalar A, const MT_Scalar B)
{
+#ifndef VAR_EPSILON
if (A >= B + BOP_EPSILON) return 1;
else if (B >= A + BOP_EPSILON) return -1;
else return 0;
+#else
+ int expA, expB;
+ float mant;
+ frexp(A, &expA); /* get exponents of each number */
+ frexp(B, &expB);
+
+ if(expA < expB) /* find the larger exponent */
+ expA = expB;
+ mant = frexp((A-B), &expB); /* get exponent of the difference */
+ /* mantissa will only be zero is (A-B) is really zero; otherwise, also
+ * also allow a "reasonably" small exponent or "reasonably large"
+ * difference in exponents to be considers "close to zero" */
+ if( mant == 0 || expB < -30 || expA - expB > 31) return 0;
+ else if( mant > 0) return 1;
+ else return -1;
+#endif
+}
+
+/**
+ * Compares a scalar with EPSILON accuracy.
+ * @param A scalar
+ * @return 1 if A > 0, -1 if A < 0, 0 otherwise
+ */
+int BOP_comp0(const MT_Scalar A)
+{
+ if (A >= BOP_EPSILON) return 1;
+ else if (0 >= A + BOP_EPSILON) return -1;
+ else return 0;
}
/**
@@ -53,6 +85,7 @@ int BOP_comp(const MT_Scalar A, const MT_Scalar B)
*/
int BOP_comp(const MT_Tuple3& A, const MT_Tuple3& B)
{
+#ifndef VAR_EPSILON
if (A.x() >= (B.x() + BOP_EPSILON)) return 1;
else if (B.x() >= (A.x() + BOP_EPSILON)) return -1;
else if (A.y() >= (B.y() + BOP_EPSILON)) return 1;
@@ -60,6 +93,13 @@ int BOP_comp(const MT_Tuple3& A, const MT_Tuple3& B)
else if (A.z() >= (B.z() + BOP_EPSILON)) return 1;
else if (B.z() >= (A.z() + BOP_EPSILON)) return -1;
else return 0;
+#else
+ int result = BOP_comp(A.x(), B.x());
+ if (result != 0) return result;
+ result = BOP_comp(A.y(), B.y());
+ if (result != 0) return result;
+ return BOP_comp(A.z(), B.z());
+#endif
}
/**
@@ -113,12 +153,20 @@ bool BOP_between(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3)
*/
bool BOP_collinear(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3)
{
+ if( BOP_comp(p1,p2) == 0 || BOP_comp(p2,p3) == 0 ) return true;
+
MT_Vector3 v1 = p2 - p1;
MT_Vector3 v2 = p3 - p2;
-
+
+ /* normalize vectors before taking their cross product, so its length
+ * has some actual meaning */
+ // if(MT_fuzzyZero(v1.length()) || MT_fuzzyZero(v2.length())) return true;
+ v1.normalize();
+ v2.normalize();
+
MT_Vector3 w = v1.cross(v2);
- return (BOP_comp(w.x(),0.0) == 0) && (BOP_comp(w.y(),0.0) == 0) && (BOP_comp(w.z(),0.0) == 0);
+ return (BOP_fuzzyZero(w.x()) && BOP_fuzzyZero(w.y()) && BOP_fuzzyZero(w.z()));
}
/**
@@ -184,17 +232,17 @@ bool BOP_intersect(const MT_Vector3& vL1, const MT_Point3& pL1, const MT_Vector3
MT_Scalar t = -1;
MT_Scalar den = (vL1.y()*vL2.x() - vL1.x() * vL2.y());
- if (BOP_comp(den,0)) {
+ if (!BOP_fuzzyZero(den)) {
t = (pL2.y()*vL1.x() - vL1.y()*pL2.x() + pL1.x()*vL1.y() - pL1.y()*vL1.x()) / den ;
}
else {
den = (vL1.y()*vL2.z() - vL1.z() * vL2.y());
- if (BOP_comp(den,0)) {
+ if (!BOP_fuzzyZero(den)) {
t = (pL2.y()*vL1.z() - vL1.y()*pL2.z() + pL1.z()*vL1.y() - pL1.y()*vL1.z()) / den ;
}
else {
den = (vL1.x()*vL2.z() - vL1.z() * vL2.x());
- if (BOP_comp(den,0)) {
+ if (!BOP_fuzzyZero(den)) {
t = (pL2.x()*vL1.z() - vL1.x()*pL2.z() + pL1.z()*vL1.x() - pL1.x()*vL1.z()) / den ;
}
else {
@@ -318,7 +366,7 @@ MT_Scalar BOP_orientation(const MT_Plane3& p1, const MT_Plane3& p2)
int BOP_classify(const MT_Point3& p, const MT_Plane3& plane)
{
// Compare plane - point distance with zero
- return BOP_comp(plane.signedDistance(p),0);
+ return BOP_comp0(plane.signedDistance(p));
}
/**
@@ -360,7 +408,7 @@ MT_Point3 BOP_intersectPlane(const MT_Plane3& plane, const MT_Point3& p1, const
*/
bool BOP_containsPoint(const MT_Plane3& plane, const MT_Point3& point)
{
- return BOP_comp(plane.signedDistance(point),0) == 0;
+ return BOP_fuzzyZero(plane.signedDistance(point));
}
/**
@@ -416,8 +464,8 @@ MT_Scalar BOP_EpsilonDistance(const MT_Point3& p0, const MT_Point3& p1, const MT
MT_Scalar d1 = p0.distance(q);
MT_Scalar d;
- if (BOP_comp(d0,0)==0) d = 1.0;
- else if (BOP_comp(d1,0)==0) d = 0.0;
+ if (BOP_fuzzyZero(d0)) d = 1.0;
+ else if (BOP_fuzzyZero(d1)) d = 0.0;
else d = d1 / d0;
return d;
}
diff --git a/intern/boolop/intern/BOP_MathUtils.h b/intern/boolop/intern/BOP_MathUtils.h
index 61458bd8a78..3cff2d6a23b 100644
--- a/intern/boolop/intern/BOP_MathUtils.h
+++ b/intern/boolop/intern/BOP_MathUtils.h
@@ -1,4 +1,7 @@
/**
+ *
+ * $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -23,7 +26,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Marc Freixas, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -36,16 +39,23 @@
#include "MT_Point3.h"
#include "MT_Plane3.h"
+/* define this to give better precision comparisons */
+#define VAR_EPSILON
+
+#ifndef VAR_EPSILON
const MT_Scalar BOP_EPSILON(1.0e-5);
+#else
+const MT_Scalar BOP_EPSILON(9.3132257461547852e-10); /* ~= 2**-30 */
+#endif
inline int BOP_sign(MT_Scalar x) {
return x < 0.0 ? -1 : x > 0.0 ? 1 : 0;
}
inline MT_Scalar BOP_abs(MT_Scalar x) { return fabs(x); }
-inline bool BOP_fuzzyZero(MT_Scalar x) { return BOP_abs(x) < BOP_EPSILON; }
-
int BOP_comp(const MT_Scalar A, const MT_Scalar B);
int BOP_comp(const MT_Tuple3& A, const MT_Tuple3& B);
+int BOP_comp0(const MT_Scalar A);
+inline bool BOP_fuzzyZero(MT_Scalar x) { return BOP_comp0(x) == 0; }
int BOP_exactComp(const MT_Scalar A, const MT_Scalar B);
int BOP_exactComp(const MT_Tuple3& A, const MT_Tuple3& B);
bool BOP_between(const MT_Point3& p1, const MT_Point3& p2, const MT_Point3& p3);
diff --git a/intern/boolop/intern/BOP_Merge.cpp b/intern/boolop/intern/BOP_Merge.cpp
index fb5bfbc0e7b..c2b1a2db2b7 100644
--- a/intern/boolop/intern/BOP_Merge.cpp
+++ b/intern/boolop/intern/BOP_Merge.cpp
@@ -1,4 +1,7 @@
/**
+ *
+ * $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -23,7 +26,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Marc Freixas, Ken Hughes
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -592,6 +595,7 @@ bool BOP_Merge::createQuads()
// Get mesh faces
BOP_Faces faces = m_mesh->getFaces();
+
// Merge mesh triangles
const BOP_IT_Faces facesIEnd = (faces.end()-1);
diff --git a/intern/boolop/intern/BOP_Mesh.cpp b/intern/boolop/intern/BOP_Mesh.cpp
index 3b194ef72d4..0b70cc61533 100644
--- a/intern/boolop/intern/BOP_Mesh.cpp
+++ b/intern/boolop/intern/BOP_Mesh.cpp
@@ -681,6 +681,23 @@ unsigned int BOP_Mesh::getNumFaces(BOP_TAG tag)
}
/**
+ * Marks faces which bad edges as BROKEN (invalid face, no further processing).
+ * @param edge edge which is being replaced
+ * @param mesh mesh containing faces
+ */
+
+static void removeBrokenFaces( BOP_Edge *edge, BOP_Mesh *mesh )
+{
+ BOP_Faces m_faces = mesh->getFaces();
+
+ BOP_Indexs edgeFaces = edge->getFaces();
+ const BOP_IT_Indexs edgeFacesEnd = edgeFaces.end();
+ for(BOP_IT_Indexs idxFace=edgeFaces.begin();idxFace!=edgeFacesEnd;
+ idxFace++)
+ m_faces[*idxFace]->setTAG(BROKEN);
+}
+
+/**
* Replaces a vertex index.
* @param oldIndex old vertex index
* @param newIndex new vertex index
@@ -695,9 +712,6 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
BOP_Vertex *newVertex = m_vertexs[newIndex];
BOP_Indexs oldEdges = oldVertex->getEdges();
- BOP_Index edgeIdx=0;
- bool found = false;
-
// Update faces to the newIndex
BOP_IT_Indexs oldEdgesEnd = oldEdges.end();
for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
@@ -706,14 +720,9 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
if ((edge->getVertex1()==oldIndex && edge->getVertex2()==newIndex) ||
(edge->getVertex2()==oldIndex && edge->getVertex1()==newIndex)) {
// Remove old edge ==> set edge faces to BROKEN
- BOP_Indexs edgeFaces = edge->getFaces();
- const BOP_IT_Indexs edgeFacesEnd = edgeFaces.end();
- for(BOP_IT_Indexs idxFace=edgeFaces.begin();idxFace!=edgeFacesEnd;
- idxFace++) {
- m_faces[*idxFace]->setTAG(BROKEN);
- }
- edgeIdx = *oldEdgeIndex;
- found = true;
+ removeBrokenFaces( edge, this );
+ oldVertex->removeEdge(*oldEdgeIndex);
+ newVertex->removeEdge(*oldEdgeIndex);
}
else {
BOP_Indexs faces = edge->getFaces();
@@ -724,10 +733,6 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
}
}
}
- if (found) {
- oldVertex->removeEdge(edgeIdx);
- newVertex->removeEdge(edgeIdx);
- }
oldEdgesEnd = oldEdges.end();
for(oldEdgeIndex=oldEdges.begin();oldEdgeIndex!=oldEdgesEnd;
@@ -739,6 +744,10 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
v1 = (v1==oldIndex?edge->getVertex2():v1);
if ((edge2 = getEdge(newIndex,v1)) == NULL) {
edge->replaceVertexIndex(oldIndex,newIndex);
+ if ( edge->getVertex1() == edge->getVertex2() ) {
+ removeBrokenFaces( edge, this );
+ oldVertex->removeEdge(*oldEdgeIndex);
+ }
#ifdef HASH
rehashVertex(oldIndex,newIndex,v1);
#endif
@@ -754,6 +763,11 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex)
BOP_Vertex *oppositeVertex = m_vertexs[v1];
oppositeVertex->removeEdge(*oldEdgeIndex);
edge->replaceVertexIndex(oldIndex,newIndex);
+ if ( edge->getVertex1() == edge->getVertex2() ) {
+ removeBrokenFaces( edge, this );
+ oldVertex->removeEdge(*oldEdgeIndex);
+ newVertex->removeEdge(*oldEdgeIndex);
+ }
#ifdef HASH
rehashVertex(oldIndex,newIndex,v1);
#endif
@@ -1063,3 +1077,4 @@ void BOP_Mesh::updatePlanes()
face->setPlane(plane);
}
}
+
diff --git a/intern/boolop/intern/BOP_Triangulator.cpp b/intern/boolop/intern/BOP_Triangulator.cpp
index ad23e69d8c0..fd7b3154195 100644
--- a/intern/boolop/intern/BOP_Triangulator.cpp
+++ b/intern/boolop/intern/BOP_Triangulator.cpp
@@ -90,8 +90,11 @@ void BOP_triangulateA(BOP_Mesh *mesh, BOP_Faces *faces, BOP_Face * face, BOP_Ind
BOP_addFace(mesh, faces, face1, face->getTAG());
BOP_addFace(mesh, faces, face2, face->getTAG());
+ face1->setSplit(face->getSplit());
+ face2->setSplit(face->getSplit());
face->setTAG(BROKEN);
+ face->freeBBox();
}
/**
@@ -122,7 +125,11 @@ void BOP_triangulateB(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face, BOP_Inde
BOP_addFace(mesh,faces,face1,face->getTAG());
BOP_addFace(mesh,faces,face2,face->getTAG());
BOP_addFace(mesh,faces,face3,face->getTAG());
+ face1->setSplit(face->getSplit());
+ face2->setSplit(face->getSplit());
+ face3->setSplit(face->getSplit());
face->setTAG(BROKEN);
+ face->freeBBox();
}
@@ -180,26 +187,33 @@ void BOP_triangulateC_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face,
{
BOP_Index v = BOP_getTriangleVertex(mesh, v1, v2, v4, v5);
BOP_Index w = (v == v4 ? v5 : v4);
+ BOP_Face *face1 = new BOP_Face3(v1, v, w, face->getPlane(), face->getOriginalFace());
+ BOP_Face *face2 = new BOP_Face3(v1, v2, v, face->getPlane(), face->getOriginalFace());
+ BOP_Face *face3 = new BOP_Face3(v1, w, v3, face->getPlane(), face->getOriginalFace());
// v1 v w defines the nice triangle in the correct order
// v1 v2 v defines one lateral triangle in the correct order
// v1 w v3 defines the other lateral triangle in the correct order
// w v v2 v3 defines the quad in the correct order
- BOP_addFace(mesh, faces, new BOP_Face3(v1, v, w, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
- BOP_addFace(mesh, faces, new BOP_Face3(v1, v2, v, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
- BOP_addFace(mesh, faces, new BOP_Face3(v1, w, v3, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
+ BOP_addFace(mesh, faces, face1, face->getTAG());
+ BOP_addFace(mesh, faces, face2, face->getTAG());
+ BOP_addFace(mesh, faces, face3, face->getTAG());
+
+ face1->setSplit(face->getSplit());
+ face2->setSplit(face->getSplit());
+ face3->setSplit(face->getSplit());
BOP_Face *faces45[2];
BOP_splitQuad(mesh, face->getPlane(), v2, v3, w, v, faces45, face->getOriginalFace());
BOP_addFace(mesh, faces, faces45[0], face->getTAG());
BOP_addFace(mesh, faces, faces45[1], face->getTAG());
+ faces45[0]->setSplit(face->getSplit());
+ faces45[1]->setSplit(face->getSplit());
face->setTAG(BROKEN);
+ face->freeBBox();
}
@@ -254,15 +268,19 @@ void BOP_triangulateD_split(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face,
{
BOP_Index v = BOP_getNearestVertex(mesh, v1, v4, v5);
BOP_Index w = (v == v4 ? v5 : v4);
+ BOP_Face *face1 = new BOP_Face3(v1, v, v3, face->getPlane(), face->getOriginalFace());
+ BOP_Face *face2 = new BOP_Face3(v, w, v3, face->getPlane(), face->getOriginalFace());
+ BOP_Face *face3 = new BOP_Face3(w, v2, v3, face->getPlane(), face->getOriginalFace());
- BOP_addFace(mesh, faces, new BOP_Face3(v1, v, v3, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
- BOP_addFace(mesh, faces, new BOP_Face3(v, w, v3, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
- BOP_addFace(mesh, faces, new BOP_Face3(w, v2, v3, face->getPlane(),
- face->getOriginalFace()), face->getTAG());
-
+ BOP_addFace(mesh, faces, face1, face->getTAG());
+ BOP_addFace(mesh, faces, face2, face->getTAG());
+ BOP_addFace(mesh, faces, face3, face->getTAG());
+ face1->setSplit(face->getSplit());
+ face2->setSplit(face->getSplit());
+ face3->setSplit(face->getSplit());
+
face->setTAG(BROKEN);
+ face->freeBBox();
}
@@ -328,7 +346,11 @@ void BOP_triangulateE(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face,
BOP_addFace(mesh, faces, face1, face->getTAG());
BOP_addFace(mesh, faces, faces23[0], face->getTAG());
BOP_addFace(mesh, faces, faces23[1], face->getTAG());
+ face1->setSplit(face->getSplit());
+ faces23[0]->setSplit(face->getSplit());
+ faces23[1]->setSplit(face->getSplit());
face->setTAG(BROKEN);
+ face->freeBBox();
}
/**
@@ -380,8 +402,13 @@ void BOP_triangulateF(BOP_Mesh* mesh, BOP_Faces* faces, BOP_Face* face,
BOP_addFace(mesh, faces, faces12[1], face->getTAG());
BOP_addFace(mesh, faces, faces34[0], face->getTAG());
BOP_addFace(mesh, faces, faces34[1], face->getTAG());
+ faces12[0]->setSplit(face->getSplit());
+ faces12[1]->setSplit(face->getSplit());
+ faces34[0]->setSplit(face->getSplit());
+ faces34[1]->setSplit(face->getSplit());
face->setTAG(BROKEN);
+ face->freeBBox();
}
/**
diff --git a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
index 6863bf38cfc..010f62159a5 100755..100644
--- a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
+++ b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
@@ -125,7 +125,8 @@ BSP_CSGMeshVertexIt_Construct(
BSP_CSGMesh_VertexIt * v_it = new BSP_CSGMesh_VertexIt;
v_it->mesh = mesh;
- v_it->pos = &mesh->VertexSet()[0];
+ if( output->num_elements > 0 )
+ v_it->pos = &mesh->VertexSet()[0];
output->it = v_it;
};
@@ -257,11 +258,11 @@ BSP_CSGMesh_FaceIt_Construct(
BSP_CSGMesh_FaceIt * f_it = new BSP_CSGMesh_FaceIt;
f_it->mesh = mesh;
- f_it->pos = &mesh->FaceSet()[0];
+ if( output->num_elements > 0 )
+ f_it->pos = &mesh->FaceSet()[0];
f_it->face_triangle = 0;
output->it = f_it;
-
};
diff --git a/intern/csg/SConscript b/intern/csg/SConscript
deleted file mode 100644
index 84d718e5b67..00000000000
--- a/intern/csg/SConscript
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/python
-Import('env')
-
-sources = env.Glob('intern/*.cpp') + env.Glob('intern/*.inl')
-
-incs = 'intern ../container ../moto/include ../memutil intern/blender extern'
-
-env.BlenderLib ('blender_BSP', sources, Split(incs) , [], libtype='blender', priority=15)
diff --git a/intern/csg/extern/CSG_Interface.h b/intern/csg/extern/CSG_Interface.h
deleted file mode 100644
index 44b01c6f500..00000000000
--- a/intern/csg/extern/CSG_Interface.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef CSG_BOOLEANOPS_H
-#define CSG_BOOLEANOPS_H
-
-
-/**
- * @section Interface structures for CSG module.
- * This interface falls into 2 categories.
- * The first section deals with an abstract mesh description
- * between blender and this module. The second deals with
- * the module functions.
- * The CSG module needs to know about the following entities:
- */
-
-/**
- * CSG_IFace -- an interface polygon structure.
- * vertex_index is a fixed size array of 4 elements containing indices into
- * an abstract vertex container. 3 or 4 of these elements may be used to
- * describe either quads or triangles.
- * vertex_number is the number of vertices in this face - either 3 or 4.
- * vertex_colors is an array of {r,g,b} triplets one for each vertex index.
- * tex_coords is an array of {u,v} triplets one for each vertex index.
- * user_data is a pointer to arbitary data of fixed width ,
- * this data is copied around with the face, and duplicated if a face is
- * split. Contains things like material index.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if 0
-typedef struct {
- int vertex_index[4];
- int vertex_number;
-
- void *user_face_vertex_data[4];
- void *user_face_data;
-} CSG_IFace;
-#else
-
-/**
- * The following structs are much better to use than the crazy
- * abstract type above. It's a value type an allows the CSG
- * module to directly access mesh properties which is very useful
- * for debugging etc.
- */
-
-typedef struct
-{
- int m_vertexIndex;
- float m_uv[2];
- float m_color[4];
- short m_normal[3];
-} CSG_IFaceVertexData;
-
-typedef struct
-{
- struct Material *m_material;
-
- /* assorted tface flags */
- void *m_tpage;
- char m_flag, m_transp;
- short m_mode, m_tile;
-} CSG_IFaceData;
-
-typedef struct
-{
- CSG_IFaceVertexData m_vertexData[4];
- int m_vertexNumber;
-
- CSG_IFaceData m_faceData;
-
-} CSG_IFace;
-
-#endif
-
-/**
- * CSG_IVertex -- an interface vertex structure.
- * position is the location of the vertex in 3d space.
- */
-
-typedef struct {
- float position[3];
-} CSG_IVertex;
-
-
-/**
- * @section Iterator abstraction.
- *
- * The CSG module asks blender to fill in an instance of the above
- * structure, and requests blender to move up and down (iterate) through
- * it's face and vertex containers.
- *
- * An iterator supports the following functions.
- * int IsDone(iterator *it) -- returns true if the iterator has reached
- * the end of it's container.
- *
- * void Fill(iterator *it,DataType *data) -- Return the contents of the
- * container at the current iterator position.
- *
- * void Step(iterator *it) -- increment the iterator to the next position
- * in the container.
- *
- * The iterator is used in the following manner.
- *
- * MyIterator * iterator = ...
- * DataType data;
- *
- * while (!IsDone(iterator)) {
- * Fill(iterator,&data);
- * //process information pointed to by data
- * ...
- * Step(iterator);
- * }
- *
- * The CSG module does not want to know about the implementation of these
- * functions so we use the c function ptr mechanism to hide them. Our
- * iterator descriptor now looks like this.
- */
-
-typedef void* CSG_IteratorPtr;
-
-typedef int (*CSG_FaceItDoneFunc)(CSG_IteratorPtr it);
-typedef void (*CSG_FaceItFillFunc)(CSG_IteratorPtr it,CSG_IFace *face);
-typedef void (*CSG_FaceItStepFunc)(CSG_IteratorPtr it);
-typedef void (*CSG_FaceItResetFunc)(CSG_IteratorPtr it);
-
-typedef struct CSG_FaceIteratorDescriptor {
- CSG_IteratorPtr it;
- CSG_FaceItDoneFunc Done;
- CSG_FaceItFillFunc Fill;
- CSG_FaceItStepFunc Step;
- CSG_FaceItResetFunc Reset;
- unsigned int num_elements;
-} CSG_FaceIteratorDescriptor;
-
-/**
- * Similarly to walk through the vertex arrays we have.
- */
-typedef int (*CSG_VertexItDoneFunc)(CSG_IteratorPtr it);
-typedef void (*CSG_VertexItFillFunc)(CSG_IteratorPtr it,CSG_IVertex *face);
-typedef void (*CSG_VertexItStepFunc)(CSG_IteratorPtr it);
-typedef void (*CSG_VertexItResetFunc)(CSG_IteratorPtr it);
-
-typedef struct CSG_VertexIteratorDescriptor {
- CSG_IteratorPtr it;
- CSG_VertexItDoneFunc Done;
- CSG_VertexItFillFunc Fill;
- CSG_VertexItStepFunc Step;
- CSG_VertexItResetFunc Reset;
- unsigned int num_elements;
-} CSG_VertexIteratorDescriptor;
-
-/**
- * The actual iterator structures are not exposed to the CSG module, they
- * will contain datatypes specific to blender.
- */
-
-/**
- * @section CSG Module interface functions.
- *
- * The functions below are to be used in the following way:
- *
- * // Create a boolean operation handle
- * CSG_BooleanOperation *operation = CSG_NewBooleanFunction();
- * if (operation == NULL) {
- * // deal with low memory exception
- * }
- *
- * // Describe each mesh operand to the module.
- * // NOTE: example properties!
- * CSG_MeshPropertyDescriptor propA,propB;
- * propA.user_data_size = 0;
- * propA.user_face_vertex_data = 0;
- * propB.user_face_vertex_data = 0;
- * propB.user_data_size = 0;
- *
- * // Get the output properties of the mesh.
- * CSG_MeshPropertyDescriptor output_properties;
- * output_properties = CSG_DescibeOperands(
- * operation,
- * propA,
- * propB
- * );
- *
- * // Report to the user if they will loose any data!
- * ...
- *
- * // Get some mesh iterators for your mesh data structures
- * CSG_FaceIteratorDescriptor obA_faces = ...
- * CSG_VertexIteratorDescriptor obA_verts = ...
- *
- * // same for object B
- * CSG_FaceIteratorDescriptor obB_faces = ...
- * CSG_VertexIteratorDescriptor obB_verts = ...
- *
- * // perform the operation...!
- *
- * int success = CSG_PerformBooleanOperation(
- * operation,
- * e_csg_intersection,
- * obA_faces,
- * obA_vertices,
- * obB_faces,
- * obB_vertices
- * );
- *
- * // if the operation failes report miserable faiulre to user
- * // and clear up data structures.
- * if (!success) {
- * ...
- * CSG_FreeBooleanOperation(operation);
- * return;
- * }
- *
- * // read the new mesh vertices back from the module
- * // and assign to your own mesh structure.
- *
- * // First we need to create a CSG_IVertex so the module can fill it in.
- * CSG_IVertex vertex;
- * CSG_VertexIteratorDescriptor * verts_it = CSG_OutputVertexDescriptor(operation);
- *
- * // initialize your vertex container with the number of verts (verts_it->num_elements)
- *
- * while (!verts_it->Done(verts_it->it)) {
- * verts_it->Fill(verts_it->it,&vertex);
- *
- * // create a new vertex of your own type and add it
- * // to your mesh structure.
- * verts_it->Step(verts_it->it);
- * }
- * // Free the vertex iterator
- * CSG_FreeVertexDescriptor(verts_it);
- *
- * // similarly for faces.
- * CSG_IFace face;
- *
- * // you may need to reserve some memory in face->user_data here.
- *
- * // initialize your face container with the number of faces (faces_it->num_elements)
- *
- * CSG_FaceIteratorDescriptor * faces_it = CSG_OutputFaceDescriptor(operation);
- *
- * while (!faces_it->Done(faces_it->it)) {
- * faces_it->Fill(faces_it->it,&face);
- *
- * // create a new face of your own type and add it
- * // to your mesh structure.
- * faces_it->Step(&faces_it->it);
- * }
- *
- * // Free the face iterator
- * CSG_FreeVertexDescriptor(faces_it);
- *
- * // that's it free the operation.
- *
- * CSG_FreeBooleanOperation(operation);
- * return;
- *
- */
-
-/**
- * Description of boolean operation type.
- */
-
-typedef enum {
- e_csg_union,
- e_csg_intersection,
- e_csg_difference,
- e_csg_classify
-} CSG_OperationType;
-
-/**
- * 'Handle' into the CSG module that identifies a particular CSG operation.
- * the pointer CSG_info containers module specific data, and should not
- * be touched in anyway outside of the module.
- */
-
-typedef struct {
- void *CSG_info;
-} CSG_BooleanOperation;
-
-/**
- * Return a ptr to a CSG_BooleanOperation object allocated
- * on the heap. The CSG module owns the memory associated with
- * the returned ptr, use CSG_FreeBooleanOperation() to free this memory.
- */
- CSG_BooleanOperation *
-CSG_NewBooleanFunction(
- void
-);
-
-/**
- * The user data is handled by the BSP modules through
- * the following function which is called whenever the
- * module needs new face vertex properties (when a face is split).
- * d1,d2 are pointers to existing vertex face data. dnew is
- * a pointer to an allocated but unfilled area of user data of
- * size user_face_vertex_data_size in the CSG_MeshPropertyDescriptor
- * returned by a call to the above function. Epsilon is the relative
- * distance (between [0,1]) of the new vertex and the vertex associated
- * with d1. Use epsilon to interpolate the face vertex data in d1 and d2
- * and fill dnew
- */
-
-typedef int (*CSG_InterpolateUserFaceVertexDataFunc)(
- const CSG_IFaceVertexData *d1,
- const CSG_IFaceVertexData * d2,
- CSG_IFaceVertexData *dnew,
- double epsilon
-);
-
-
-/**
- * Attempt to perform a boolean operation between the 2 objects of the
- * desired type. This may fail due to an internal error or lack of memory.
- * In this case 0 is returned, otehrwise 1 is returned indicating success.
- * @param operation is a 'handle' into the CSG_Module created by CSG_NewBooleanFunction()
- * @param op_type is the operation to perform.
- * @param obAFaces is an iterator over the faces of objectA,
- * @param obAVertices is an iterator over the vertices of objectA
- * @param obAFaces is an iterator over the faces of objectB,
- * @param obAVertices is an iterator over the vertices of objectB
- * @param interp_func the face_vertex data interpolation function.(see above)
- *
- * All iterators must be valid and pointing to the first element in their
- * respective containers.
- */
- int
-CSG_PerformBooleanOperation(
- CSG_BooleanOperation * operation,
- CSG_OperationType op_type,
- CSG_FaceIteratorDescriptor obAFaces,
- CSG_VertexIteratorDescriptor obAVertices,
- CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interp_func
-);
-
-/**
- * If the a boolean operation was successful, you may access the results
- * through the following functions.
- *
- * CSG_OuputFaceDescriptor() returns a ptr to a CSG_FaceIteratorDesciptor
- * allocated on the heap and owned by the CSG module. The iterator is
- * positioned at the start of the internal face container.
- * CSG_OutputVertexDescriptor() returns a ptr to a CSG_VertexIteratorDescriptor
- * allocated on the heap and owned by the CSG module. The iterator is
- * positioned at the start of the internal vertex container.
- * There is no function to rewind an iterator but you may obtain more
- * than one
- * iterator at a time. Please use the function CSG_FreeFaceIterator()
- * and CSG_FreeVertexIterator to free internal memory allocated for these
- * iterators.
- *
- * If the last operation was not successful, these functions return NULL.
- */
- int
-CSG_OutputFaceDescriptor(
- CSG_BooleanOperation * operation,
- CSG_FaceIteratorDescriptor * output
-);
-
- int
-CSG_OutputVertexDescriptor(
- CSG_BooleanOperation * operation,
- CSG_VertexIteratorDescriptor *output
-);
-
-/**
- * Clean up functions.
- * Free internal memory associated with CSG interface structures. You must
- * call these functions on any structures created by the module, even if
- * subsequent operations did not succeed.
- */
- void
-CSG_FreeVertexDescriptor(
- CSG_VertexIteratorDescriptor * v_descriptor
-);
-
- void
-CSG_FreeFaceDescriptor(
- CSG_FaceIteratorDescriptor * f_descriptor
-);
-
-/**
- * Free the memory associated with a boolean operation.
- * NOTE any iterator descriptor describing the output will become
- * invalid after this call and should be freed immediately.
- */
- void
-CSG_FreeBooleanOperation(
- CSG_BooleanOperation *operation
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif
-
diff --git a/intern/csg/intern/CSG_BBox.h b/intern/csg/intern/CSG_BBox.h
deleted file mode 100644
index 4d17b935a80..00000000000
--- a/intern/csg/intern/CSG_BBox.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
-The following BBox class is a lightly modfied version of what
-is found in Free Solid 2.0
-*/
-
-/*
- SOLID - Software Library for Interference Detection
- Copyright (C) 1997-1998 Gino van den Bergen
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to gino@win.tue.nl,
- or write to:
- Gino van den Bergen
- Department of Mathematics and Computing Science
- Eindhoven University of Technology
- P.O. Box 513, 5600 MB Eindhoven, The Netherlands
-*/
-
-#ifndef _BBOX_H_
-#define _BBOX_H_
-
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-#include "MT_MinMax.h"
-
-class BBox {
-public:
- BBox() {}
-
- BBox(
- const MT_Point3& mini,
- const MT_Point3& maxi
- ) { SetValue(mini,maxi); }
-
- const MT_Point3&
- Center(
- ) const {
- return m_center;
- }
-
- const MT_Vector3&
- Extent(
- ) const {
- return m_extent;
- }
-
- MT_Point3&
- Center(
- ) {
- return m_center;
- }
-
- MT_Vector3&
- Extent(
- ) {
- return m_extent;
- }
-
- void
- SetValue(
- const MT_Point3& mini,
- const MT_Point3& maxi
- ) {
- m_extent = (maxi-mini)/2;
- m_center = mini+m_extent;
- }
-
- void
- Enclose(
- const BBox& a,
- const BBox& b
- ) {
- MT_Point3 lower(
- MT_min(a.Lower(0), b.Lower(0)),
- MT_min(a.Lower(1), b.Lower(1)),
- MT_min(a.Lower(2), b.Lower(2))
- );
- MT_Point3 upper(
- MT_max(a.Upper(0), b.Upper(0)),
- MT_max(a.Upper(1), b.Upper(1)),
- MT_max(a.Upper(2), b.Upper(2))
- );
- SetValue(lower, upper);
- }
-
- void
- SetEmpty() {
- m_center.setValue(0, 0, 0);
- m_extent.setValue(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY);
- }
-
- void
- Include (
- const MT_Point3& p
- ) {
- MT_Point3 lower(
- MT_min(Lower(0), p[0]),
- MT_min(Lower(1), p[1]),
- MT_min(Lower(2), p[2])
- );
- MT_Point3 upper(
- MT_max(Upper(0), p[0]),
- MT_max(Upper(1), p[1]),
- MT_max(Upper(2), p[2])
- );
- SetValue(lower, upper);
- }
-
- void
- Include (
- const BBox& b
- ) {
- Enclose(*this, b);
- }
-
- MT_Scalar
- Lower(
- int i
- ) const {
- return m_center[i] - m_extent[i];
- }
- MT_Scalar
- Upper(
- int i
- ) const {
- return m_center[i] + m_extent[i];
- }
-
- MT_Point3
- Lower(
- ) const {
- return m_center - m_extent;
- }
- MT_Point3
- Upper(
- ) const {
- return m_center + m_extent;
- }
-
- MT_Scalar
- Size(
- ) const {
- return MT_max(MT_max(m_extent[0], m_extent[1]), m_extent[2]);
- }
-
- int
- LongestAxis(
- ) const {
- return m_extent.closestAxis();
- }
-
- bool
- IntersectXRay(
- const MT_Point3& xBase
- ) const {
- if (xBase[0] <= Upper(0))
- {
- if (xBase[1] <= Upper(1) && xBase[1] >= Lower(1))
- {
- if (xBase[2] <= Upper(2) && xBase[2] >= Lower(2))
- {
- return true;
- }
- }
- }
- return false;
- }
-
-
-
-
- friend bool intersect(const BBox& a, const BBox& b);
-
-private:
- MT_Point3 m_center;
- MT_Vector3 m_extent;
-};
-
-inline
- bool
-intersect(
- const BBox& a,
- const BBox& b
-) {
- return
- MT_abs(a.m_center[0] - b.m_center[0]) <= a.m_extent[0] + b.m_extent[0] &&
- MT_abs(a.m_center[1] - b.m_center[1]) <= a.m_extent[1] + b.m_extent[1] &&
- MT_abs(a.m_center[2] - b.m_center[2]) <= a.m_extent[2] + b.m_extent[2];
-}
-
-#endif
-
-
diff --git a/intern/csg/intern/CSG_BBoxTree.cpp b/intern/csg/intern/CSG_BBoxTree.cpp
deleted file mode 100644
index 503c3e7f2d4..00000000000
--- a/intern/csg/intern/CSG_BBoxTree.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- SOLID - Software Library for Interference Detection
- Copyright (C) 1997-1998 Gino van den Bergen
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to gino@win.tue.nl,
- or write to:
- Gino van den Bergen
- Department of Mathematics and Computing Science
- Eindhoven University of Technology
- P.O. Box 513, 5600 MB Eindhoven, The Netherlands
-*/
-
-#include "CSG_BBoxTree.h"
-#include <algorithm>
-
-
-using namespace std;
-
-
-BBoxInternal::
-BBoxInternal(
- int n, LeafPtr leafIt
-)
-{
- m_tag = INTERNAL;
- m_bbox.SetEmpty();
-
- int i;
- for (i=0;i<n;i++) {
- m_bbox.Include(leafIt[i].m_bbox);
- }
-}
-// Construct a BBoxInternal from a list of BBoxLeaf nodes.
-// Recursive function that does the longest axis median point
-// fit.
-
-void BBoxTree::
-BuildTree(
- LeafPtr leaves, int numLeaves
-) {
- m_branch = 0;
- m_leaves = leaves;
- m_numLeaves = numLeaves;
- m_internals = new BBoxInternal[numLeaves];
-
- RecursiveTreeBuild(m_numLeaves,m_leaves);
-}
-
- void
-BBoxTree::
-RecursiveTreeBuild(
- int n, LeafPtr leafIt
-){
- m_internals[m_branch] = BBoxInternal(n,leafIt);
- BBoxInternal& aBBox = m_internals[m_branch];
-
- m_branch++;
-
- int axis = aBBox.m_bbox.LongestAxis();
- int i = 0, mid = n;
-
- // split the leaves into two groups those that are < bbox.getCenter()[axis]
- // and those that are >=
- // smart bit about this code is it does the grouping in place.
- while (i < mid)
- {
- if (leafIt[i].m_bbox.Center()[axis] < aBBox.m_bbox.Center()[axis])
- {
- ++i;
- } else {
- --mid;
- swap(leafIt[i], leafIt[mid]);
- }
- }
-
- // all of the nodes were on one side of the box center
- // I'm not sure if this case ever gets reached?
- if (mid == 0 || mid == n)
- {
- mid = n / 2;
- }
-
- if (mid >= 2)
- {
- aBBox.rson = m_internals + m_branch;
- RecursiveTreeBuild(mid,leafIt);
- } else {
- aBBox.rson = leafIt;
- }
- if (n - mid >= 2) {
- aBBox.lson = m_internals + m_branch;
- RecursiveTreeBuild(n - mid, leafIt + mid);
- } else {
- aBBox.lson = leafIt + mid;
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_BBoxTree.h b/intern/csg/intern/CSG_BBoxTree.h
deleted file mode 100644
index a9013ccf329..00000000000
--- a/intern/csg/intern/CSG_BBoxTree.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * I've modified some very nice bounding box tree code from
- * Gino van der Bergen's Free Solid Library below. It's basically
- * the same code - but I've hacked out the transformation stuff as
- * I didn't understand it. I've also made it far less elegant!
- *
- */
-
-/*
- SOLID - Software Library for Interference Detection
- Copyright (C) 1997-1998 Gino van den Bergen
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to gino@win.tue.nl,
- or write to:
- Gino van den Bergen
- Department of Mathematics and Computing Science
- Eindhoven University of Technology
- P.O. Box 513, 5600 MB Eindhoven, The Netherlands
-*/
-
-#ifndef _BBOXTREE_H_
-#define _BBOXTREE_H_
-
-#include "CSG_BBox.h"
-#include "MT_Line3.h"
-#include "CSG_IndexDefs.h"
-
-#include <vector>
-
-/**
- * Tree structure
- */
-
-class BBoxNode
-{
-public:
- enum TagType { LEAF, INTERNAL };
-
- BBox m_bbox;
- TagType m_tag;
-};
-
-
-class BBoxLeaf : public BBoxNode
-{
-public:
- int m_polyIndex;
-
- BBoxLeaf() {}
-
- BBoxLeaf(int polyIndex, const BBox& bbox)
- : m_polyIndex(polyIndex)
- {
- m_bbox = bbox;
- m_tag = LEAF;
- }
-
-};
-
-
-typedef BBoxLeaf* LeafPtr;
-typedef BBoxNode* NodePtr;
-
-
-class BBoxInternal : public BBoxNode
-{
-public:
- NodePtr lson;
- NodePtr rson;
-
- BBoxInternal() {}
- BBoxInternal(
- int n, LeafPtr leafIt
- );
-
-};
-
-typedef BBoxInternal* InternalPtr;
-
-
-class BBoxTree
-{
-public :
- BBoxTree() {};
-
- const NodePtr RootNode() const {
- return m_internals;
- }
-
- ~BBoxTree() {
- delete[] m_leaves;
- delete[] m_internals;
- }
-
- // tree takes ownership of the leaves.
- void BuildTree(LeafPtr leaves, int numLeaves);
-
-private :
-
- void RecursiveTreeBuild(
- int n, LeafPtr leafIt
- );
-
- int m_branch;
-
- LeafPtr m_leaves;
- InternalPtr m_internals;
- int m_numLeaves;
-};
-
-
-
-
-
-#endif
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_BlenderVProp.h b/intern/csg/intern/CSG_BlenderVProp.h
deleted file mode 100644
index 72cad752c31..00000000000
--- a/intern/csg/intern/CSG_BlenderVProp.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef CSG_BlenderVProp_H
-#define CSG_BlenderVProp_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-// A vertex property that stores a CSG_IFaceVertexData structure defined
-// in the interface between the CSG module and blender CSG_Interface.h!
-
-#include "CSG_Interface.h"
-#include "MT_Scalar.h"
-
-class BlenderVProp
-{
-public :
- // You must set the interpolation function ptr
- // before using this class.
-
- static CSG_InterpolateUserFaceVertexDataFunc InterpFunc;
-
-private :
-
- CSG_IFaceVertexData m_data;
-
-public :
-
- BlenderVProp(const int& vIndex)
- {
- m_data.m_vertexIndex = vIndex;
- }
-
- BlenderVProp(
- const int& vIndex,
- const BlenderVProp& p1,
- const BlenderVProp& p2,
- const MT_Scalar& epsilon
- ){
- m_data.m_vertexIndex = vIndex;
- InterpFunc(&(p1.m_data),&(p2.m_data),&m_data,epsilon);
- }
-
-
- BlenderVProp(
- ) {};
-
- // Default copy constructor and assignment operator are fine.
-
- // Support conversion to an integer
- ///////////////////////////////////
- operator int(
- ) const {
- return m_data.m_vertexIndex;
- }
-
- // and assignment from an integer.
- //////////////////////////////////
- BlenderVProp&
- operator = (
- int i
- ) {
- m_data.m_vertexIndex = i;
- return *this;
- }
-
- // return a reference to our data
- const CSG_IFaceVertexData& Data() const {
- return m_data;
- }
-
- CSG_IFaceVertexData& Data() {
- return m_data;
- }
-
-
-};
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/CSG_BooleanOp.h b/intern/csg/intern/CSG_BooleanOp.h
deleted file mode 100644
index ff293799286..00000000000
--- a/intern/csg/intern/CSG_BooleanOp.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef CSG_BOOLEANOP_H
-#define CSG_BOOLEANOP_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_IndexDefs.h"
-#include "CSG_BBoxTree.h"
-
-template <typename CMesh, typename TMesh> class BooleanOp
-{
-public :
-
- // unimplemented
- ////////////////
- BooleanOp();
- BooleanOp(const BooleanOp&);
- BooleanOp& operator = (const BooleanOp&);
-
- //helpers
- /////////
-
- static
- void
- BuildSplitGroup(
- const TMesh& meshA,
- const TMesh& meshB,
- const BBoxTree& treeA,
- const BBoxTree& treeB,
- OverlapTable& aOverlapsB,
- OverlapTable& bOverlapsA
- );
-
- // Split mesh with mesh2, table is an OverlapTable containing the polygons
- // of mesh2 that intersect with polygons of mesh.
- // if preserve is true this function will aim to reduce the number of
- // T-junctions created.
-
- static
- void
- PartitionMesh(
- CMesh & mesh,
- const TMesh & mesh2,
- const OverlapTable& table
- );
-
- // Classify meshB with respect to meshA, uses a BBox tree of meshA
- // to drastically improve speed!
- static
- void
- ClassifyMesh(
- const TMesh& meshA,
- const BBoxTree& aTree,
- CMesh& meshB
- );
-
- static
- void
- ExtractClassification(
- CMesh& meshA,
- TMesh& newMesh,
- int classification,
- bool reverse
- );
-
-
-};
-
-#include "CSG_BooleanOp.inl"
-
-#endif
diff --git a/intern/csg/intern/CSG_BooleanOp.inl b/intern/csg/intern/CSG_BooleanOp.inl
deleted file mode 100644
index 9309d4ffbb5..00000000000
--- a/intern/csg/intern/CSG_BooleanOp.inl
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#include "CSG_Math.h"
-#include "CSG_BBoxTree.h"
-#include "CSG_TreeQueries.h"
-
-using namespace std;
-
-template <typename CMesh, typename TMesh>
- void
-BooleanOp<CMesh,TMesh>::
-BuildSplitGroup(
- const TMesh& meshA,
- const TMesh& meshB,
- const BBoxTree& treeA,
- const BBoxTree& treeB,
- OverlapTable& aOverlapsB,
- OverlapTable& bOverlapsA
-) {
-
- aOverlapsB = OverlapTable(meshB.Polys().size());
- bOverlapsA = OverlapTable(meshA.Polys().size());
-
- // iterate through the polygons of A and then B
- // and mark each
- TreeIntersector<TMesh>(treeA,treeB,&aOverlapsB,&bOverlapsA,&meshA,&meshB);
-
-}
-
-template <typename CMesh, typename TMesh>
- void
-BooleanOp<CMesh,TMesh>::
-PartitionMesh(
- CMesh & mesh,
- const TMesh & mesh2,
- const OverlapTable& table
-) {
-
- // iterate through the overlap table.
- int i;
-
- MT_Scalar onEpsilon(1e-4);
-
- for (i = 0; i < table.size(); i++)
- {
- if (table[i].size())
- {
- // current list of fragments - initially contains
- // just the to-be-split polygon index
- PIndexList fragments;
- fragments.push_back(i);
-
- // iterate through the splitting polygons.
- int j;
- for (j =0 ; j <table[i].size(); ++j)
- {
- PIndexList newFragments;
-
- // find the splitting plane
- MT_Plane3 splitPlane = mesh2.Polys()[table[i][j]].Plane();
-
- // iterate through the current fragments and split them
- // with the new plane, adding the resulting fragments to
- // the newFragments list.
- int k;
- for (k = 0; k < fragments.size(); ++k)
- {
- int newInFragment;
- int newOutFragment;
-
- CMesh::TGBinder pg1(mesh,fragments[k]);
- TMesh::TGBinder pg2(mesh2,table[i][j]);
-
- const MT_Plane3& fragPlane = mesh.Polys()[fragments[k]].Plane();
-
- if (CSG_PolygonIntersector<CMesh::TGBinder,TMesh::TGBinder >::
- IntersectPolygons(pg1,pg2,fragPlane,splitPlane))
- {
- mesh.SplitPolygon(fragments[k],splitPlane,newInFragment,newOutFragment,onEpsilon);
-
- if (-1 != newInFragment) newFragments.push_back(newInFragment);
- if (-1 != newOutFragment) newFragments.push_back(newOutFragment);
- } else {
- // this fragment was not split by this polygon but it may be split by a subsequent
- // polygon in the list
- newFragments.push_back(fragments[k]);
- }
-
- }
-
- fragments = newFragments;
- }
- }
- }
-}
-
-template <typename CMesh, typename TMesh>
- void
-BooleanOp<CMesh,TMesh>::
-ClassifyMesh(
- const TMesh& meshA,
- const BBoxTree& aTree,
- CMesh& meshB
-) {
-
- // walk through all of the polygons of meshB. Create a
- // ray in the direction of the polygons normal emintaing from the
- // mid point of the polygon
-
- // Do a ray test with all of the polygons of MeshA
- // Find the nearest intersection point and record the polygon index
-
- // If there were no intersections then the ray is outside.
- // If there was an intersection and the dot product of the ray and normal
- // of the intersected polygon from meshA is +ve then we are on the inside
- // else outside.
-
- int i;
- for (i = 0; i < meshB.Polys().size(); i++)
- {
- CMesh::TGBinder pg(meshB,i);
-
- MT_Line3 midPointRay = CSG_Math<CMesh::TGBinder >::PolygonMidPointRay(pg,meshB.Polys()[i].Plane());
-
- MT_Line3 midPointXRay(midPointRay.Origin(),MT_Vector3(1,0,0));
-
- int aPolyIndex(-1);
-
- RayTreeIntersector<TMesh>(aTree,&meshA,midPointXRay,aPolyIndex);
-
- if (-1 != aPolyIndex)
- {
- if (meshA.Polys()[aPolyIndex].Plane().signedDistance(midPointXRay.Origin()) < 0)
- {
- meshB.Polys()[i].Classification()= 1;
- } else {
- meshB.Polys()[i].Classification()= 2;
- }
- } else {
- meshB.Polys()[i].Classification()= 2;
- }
- }
-}
-
-
-template <typename CMesh, typename TMesh>
- void
-BooleanOp<CMesh,TMesh>::
-ExtractClassification(
- CMesh& meshA,
- TMesh& newMesh,
- int classification,
- bool reverse
-){
-
- int i;
- for (i = 0; i < meshA.Polys().size(); ++i)
- {
- CMesh::Polygon& meshAPolygon = meshA.Polys()[i];
- if (meshAPolygon.Classification() == classification)
- {
- newMesh.Polys().push_back(meshAPolygon);
- TMesh::Polygon& newPolygon = newMesh.Polys().back();
-
- if (reverse) newPolygon.Reverse();
-
- // iterate through the vertices of the new polygon
- // and find a new place for them in the new mesh (if they arent already there)
-
- int j;
- for (j=0; j< newPolygon.Size(); j++)
- {
- if (meshA.Verts()[newPolygon[j]].VertexMap() == -1)
- {
- // this is the first time we have visited this vertex
- // copy it over to the new mesh.
- newMesh.Verts().push_back(meshA.Verts()[newPolygon[j]]);
- // and record it's position in the new mesh for the next time we visit it.
- meshA.Verts()[newPolygon[j]].VertexMap() = newMesh.Verts().size() -1;
- }
- newPolygon.VertexProps(j) = meshA.Verts()[newPolygon[j]].VertexMap();
- }
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_CVertex.h b/intern/csg/intern/CSG_CVertex.h
deleted file mode 100644
index fd0a7b098b5..00000000000
--- a/intern/csg/intern/CSG_CVertex.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef CSG_CVertex_H
-#define CSG_CVertex_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include <algorithm>
-#include "CSG_IndexDefs.h"
-#include "CSG_Vertex.h"
-// This class extends an existing vertex by connecting
-// them with their polygons through the PIndexList member.
-//
-// This extra information allows us to perform local
-// mesh topology queries
-//
-// These queries are availble through the ConnectedMesh class.
-
-class CVertex : public VertexBase
-{
-private :
-
- // polygons using this vertex
- PIndexList m_polygons;
-
-public :
-
- CVertex()
- :VertexBase(),m_polygons()
- {
- };
-
- // have to change VertexBase and all functions to
- // use Pos() rather than m_pos;
-
- CVertex(const VertexBase& vertex)
- :VertexBase(vertex),m_polygons()
- {}
-
- // Value type model
- ///////////////////
- CVertex(const CVertex& other)
- : VertexBase(other), m_polygons(other.m_polygons)
- {}
-
- CVertex& operator = (const CVertex& other)
- {
- m_pos = other.Pos();
- m_vertexMap = other.m_vertexMap;
- m_polygons = other.m_polygons;
-
- return *this;
- }
-
-
- CVertex& operator = (const VertexBase& other)
- {
- m_pos= other.Pos();
- return *this;
- }
-
-
- ~CVertex(){};
-
- // Our special connected vertex functions.
- //////////////////////////////////////////
-
- const PIndexList& Polys() const { return m_polygons;}
- PIndexList& Polys() { return m_polygons;}
-
- int & operator[] (const int & i) { return m_polygons[i];}
-
- const int & operator[] (const int& i) const { return m_polygons[i];}
-
- void AddPoly(int polyIndex) {m_polygons.push_back(polyIndex);}
-
- void RemovePolygon(int polyIndex)
- {
- PIndexIt foundIt = std::find(m_polygons.begin(),m_polygons.end(),polyIndex);
- if (foundIt != m_polygons.end()) {
- std::swap(m_polygons.back(), *foundIt);
- m_polygons.pop_back();
- }
- }
-};
-
-
-#endif
diff --git a/intern/csg/intern/CSG_ConnectedMesh.h b/intern/csg/intern/CSG_ConnectedMesh.h
deleted file mode 100644
index 6cf73ef2240..00000000000
--- a/intern/csg/intern/CSG_ConnectedMesh.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef CSG_ConnectedMesh_H
-#define CSG_ConnectedMesh_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_GeometryBinder.h"
-#include "MT_Plane3.h"
-
-template <typename TMesh> class ConnectedMeshWrapper
-{
-public :
-
- typedef TMesh::Polygon Polygon;
- typedef TMesh::Vertex Vertex;
-
- typedef TMesh::Polygon::TVProp VProp;
-
- typedef TMesh::VLIST VLIST;
- typedef TMesh::PLIST PLIST;
-
- typedef PolygonGeometry<ConnectedMeshWrapper> TGBinder;
-
- typedef ConnectedMeshWrapper<TMesh> MyType;
-
-private :
- TMesh& m_mesh;
-
- unsigned int m_uniqueEdgeTestId;
-
-public :
-
- // Mesh Template interface
- //////////////////////////
- VLIST& Verts() {return m_mesh.Verts();}
- const VLIST& Verts() const {return m_mesh.Verts();}
-
- PLIST& Polys() {return m_mesh.Polys();}
- const PLIST& Polys() const {return m_mesh.Polys();}
-
- // Mesh Wrapper functions
- /////////////////////////
-
- ConnectedMeshWrapper(TMesh& mesh):
- m_mesh(mesh),m_uniqueEdgeTestId(0) {};
-
- void BuildVertexPolyLists();
-
- void DisconnectPolygon(int polyIndex);
-
- void ConnectPolygon(int polyIndex);
-
- //return the polygons neibouring the given edge.
- void EdgePolygons(int v1, int v2, PIndexList& polys);
-
- void InsertVertexAlongEdge(int v1,int v2, const VProp& prop);
-
- void
- SplitPolygon(
- const int p1Index,
- const MT_Plane3& plane,
- int& inPiece,
- int& outPiece,
- const MT_Scalar onEpsilon
- );
-
- ~ConnectedMeshWrapper(){};
-};
-
-#include "CSG_ConnectedMeshWrapper.inl"
-
-#endif
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_ConnectedMeshWrapper.inl b/intern/csg/intern/CSG_ConnectedMeshWrapper.inl
deleted file mode 100644
index 5d6cc11cc48..00000000000
--- a/intern/csg/intern/CSG_ConnectedMeshWrapper.inl
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#include <algorithm>
-#include <iterator>
-#include "CSG_SplitFunction.h"
-
-// Define functors things that bind a function to an object,
-// for the templated split polygon code.
-
-template <typename CMesh> class SplitFunctionBindor
-{
-private :
- CMesh& m_mesh;
-
-public :
-
- SplitFunctionBindor(CMesh& mesh):m_mesh(mesh) {};
-
- void DisconnectPolygon(int polyIndex){
- m_mesh.DisconnectPolygon(polyIndex);
- }
-
- void ConnectPolygon(int polygonIndex) {
- m_mesh.ConnectPolygon(polygonIndex);
- }
-
- void InsertVertexAlongEdge(int lastIndex,int newIndex,const CMesh::VProp& prop) {
- m_mesh.InsertVertexAlongEdge(lastIndex,newIndex,prop);
- }
-
- ~SplitFunctionBindor(){};
-};
-
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-BuildVertexPolyLists(
-) {
- int i;
- for (i=0; i < Polys().size(); i++)
- {
- ConnectPolygon(i);
- }
-}
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-DisconnectPolygon(
- int polyIndex
-){
- const Polygon& poly = Polys()[polyIndex];
-
- int j;
- for (j=0;j<poly.Verts().size(); j++)
- {
- Verts()[poly[j]].RemovePolygon(polyIndex);
- }
-}
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-ConnectPolygon(
- int polyIndex
-){
- const Polygon& poly = Polys()[polyIndex];
-
- int j;
- for (j=0;j<poly.Verts().size(); j++)
- {
- Verts()[poly[j]].AddPoly(polyIndex);
- }
-}
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-EdgePolygons(
- int v1,
- int v2,
- PIndexList& polys
-) {
- ++m_uniqueEdgeTestId;
-
- Vertex& vb1 = Verts()[v1];
- int i;
- for (i=0;i < vb1.Polys().size(); ++i)
- {
- Polys()[vb1[i]].Classification() = m_uniqueEdgeTestId;
- }
-
- Vertex& vb2 = Verts()[v2];
- int j;
- for (j=0;j < vb2.Polys().size(); ++j)
- {
- if (Polys()[vb2[j]].Classification() == m_uniqueEdgeTestId)
- {
- polys.push_back(vb2[j]);
- }
- }
-}
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-InsertVertexAlongEdge(
- int v1,
- int v2,
- const VProp& prop
-) {
-
- PIndexList npolys;
- EdgePolygons(v1,v2,npolys);
-
- // iterate through the neighbouting polygons of
- // this edge and insert the vertex into the polygon
-
- int newVertex = int(prop);
-
- int i;
- for (i=0;i < npolys.size(); i++)
- {
- // find the first vertex index in this polygon
- Polygon::TVPropList& polyVerts = Polys()[npolys[i]].Verts();
-
- Polygon::TVPropIt v1pos = std::find(polyVerts.begin(),polyVerts.end(),v1);
-
- // this should never be false!
- if (v1pos != polyVerts.end())
- {
- // v2 must be either side of this pos
- Polygon::TVPropIt prevPos = (v1pos == polyVerts.begin()) ? polyVerts.end()-1 : v1pos-1;
- Polygon::TVPropIt nextPos = (v1pos == polyVerts.end()-1) ? polyVerts.begin() : v1pos+1;
-
- if (*prevPos == v2) {
- polyVerts.insert(v1pos,prop);
- } else
- if (*nextPos == v2) {
- polyVerts.insert(nextPos,prop);
- } else {
- //assert(false);
- }
-
- Verts()[newVertex].AddPoly(npolys[i]);
- } else {
- assert(false);
- }
- }
-}
-
-
-template <typename TMesh>
- void
-ConnectedMeshWrapper<TMesh>::
-SplitPolygon(
- const int p1Index,
- const MT_Plane3& plane,
- int& inPiece,
- int& outPiece,
- const MT_Scalar onEpsilon
-){
-
- SplitFunctionBindor<MyType> functionBindor(*this);
-
- SplitFunction<MyType,SplitFunctionBindor<MyType> > splitFunction(*this,functionBindor);
- splitFunction.SplitPolygon(p1Index,plane,inPiece,outPiece,onEpsilon);
-}
-
-#if 0
-template <class TPolygon, class TVertex>
- void
-Mesh::
-printMesh(
- std::ostream& stream
-) {
-
- int i;
- for (i =0; i < m_polys.size(); i++)
- {
- std::ostream_iterator<int> streamIt(stream," ");
- std::copy(m_polys[i].Verts().begin(),m_polys[i].Verts().end(),streamIt);
- stream << "\n";
- }
-}
-
-#endif
-
-
-
-
diff --git a/intern/csg/intern/CSG_GeometryBinder.h b/intern/csg/intern/CSG_GeometryBinder.h
deleted file mode 100644
index 2977ac65971..00000000000
--- a/intern/csg/intern/CSG_GeometryBinder.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef CSG_GEOMETRY_BINDER_H
-#define CSG_GEOMETRY_BINDER_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-// This class binds the geometry of a polygon
-// to the polygon itself it provides just one
-// operator [int i] that returns the vertex position
-// of the ith vertex in the polygon.
-
-// Its a model of a geometry binder primarily used by the CSG_Math
-// template class to compute geometric information about a mesh.
-
-#include "MT_Point3.h"
-
-
-template <typename TMesh> class PolygonGeometry
-{
-public :
-
- typedef typename TMesh::Polygon TPolygon;
-
- PolygonGeometry(const TMesh& mesh, int pIndex)
- : m_poly(mesh.Polys()[pIndex]),m_mesh(mesh)
- {};
-
- PolygonGeometry(const TMesh& mesh,const TPolygon& poly)
- : m_poly(poly),m_mesh(mesh)
- {};
-
- const MT_Point3& operator[] (int i) const {
- return m_mesh.Verts()[m_poly[i]].Pos();
- };
-
- int Size() const { return m_poly.Size();}
-
- ~PolygonGeometry(){};
-
-private :
-
- PolygonGeometry(const PolygonGeometry& other) {};
- PolygonGeometry& operator = (PolygonGeometry& other) { return *this;}
-
- const TMesh& m_mesh;
- const TPolygon& m_poly;
-
-};
-
-#endif
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_IndexDefs.h b/intern/csg/intern/CSG_IndexDefs.h
deleted file mode 100644
index 2e1e05a5eb4..00000000000
--- a/intern/csg/intern/CSG_IndexDefs.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef CSG_INDEXDEFS_H
-#define CSG_INDEXDEFS_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-//typdefs for lists and things in the CSG library
-
-#include <vector>
-
-typedef std::vector<int> PIndexList;
-typedef PIndexList::iterator PIndexIt;
-typedef PIndexList::const_iterator const_PIndexIt;
-
-typedef std::vector<int> VIndexList;
-typedef VIndexList::iterator VIndexIt;
-typedef VIndexList::const_iterator const_VIndexIt;
-
-typedef std::vector< PIndexList > OverlapTable;
-
-
-
-#endif
-
-
diff --git a/intern/csg/intern/CSG_Math.h b/intern/csg/intern/CSG_Math.h
deleted file mode 100644
index 0c41e3d63ae..00000000000
--- a/intern/csg/intern/CSG_Math.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef __CSG_MATH_H
-#define __CSG_MATH_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "MT_Plane3.h"
-#include "MT_Matrix3x3.h"
-#include "MT_Line3.h"
-#include "CSG_BBox.h"
-
-// useful geometry functions.
-/////////////////////////////
-
-const int cofacTable[3][2] = {{1,2},{0,2},{0,1}};
-
-class CSG_Geometry
-{
-public :
-
- static bool Intersect(
- const MT_Plane3& p1,
- const MT_Plane3& p2,
- MT_Line3& output
- );
-
- // Return intersection of line1 and line 2 in the plane formed by the given
- // standard axis. Intersection l1Param is the intersection parameter of line1.
- static bool Intersect2D(
- const MT_Line3& l1,
- const MT_Line3& l2,
- int majAxis,
- MT_Scalar& l1Param
- );
-
- static bool Intersect2DBoundsCheck(
- const MT_Line3& l1,
- const MT_Line3& l2,
- int majAxis,
- MT_Scalar& l1Param,
- MT_Scalar& l2Param
- );
-
- static bool Intersect2DNoBoundsCheck(
- const MT_Line3& l1,
- const MT_Line3& l2,
- int majAxis,
- MT_Scalar& l1Param,
- MT_Scalar& l2Param
- );
-
- static int ComputeClassification(
- const MT_Scalar& distance,
- const MT_Scalar& epsilon
- );
-};
-
-// The template parameter TGBinder is a model of a Geometry Binder concept
-// see CSG_GeometryBinder.h for an example.
-
-template <typename TGBinder> class CSG_Math
-{
-public :
-
- static bool IntersectPolyWithLine2D(
- const MT_Line3& l,
- const TGBinder& p1,
- const MT_Plane3& plane,
- MT_Scalar& a,
- MT_Scalar& b
- );
-
- static bool InstersectPolyWithLine3D(
- const MT_Line3& l,
- const TGBinder& p1,
- const MT_Plane3& plane,
- MT_Scalar& a
- );
-
- static bool PointInPolygonTest3D(
- const TGBinder& p1,
- const MT_Plane3& plane,
- const MT_Point3& origin,
- const MT_Point3& pointOnPlane
- );
-
- // Return the mid-point of the given polygon index.
- static MT_Point3 PolygonMidPoint(
- const TGBinder& p1
- );
-
- static MT_Line3 PolygonMidPointRay(
- const TGBinder& p1,
- const MT_Plane3& plane
- );
-
- static MT_Plane3 ComputePlane(
- const TGBinder &p1
- );
-
- // Return a bounding box of the given polygon index.
- static BBox FitBBox(
- const TGBinder& p1
- );
-
- // Return which side of the polygon the plane is on.
- // 0 == 0n
- // 1 == in
- // 2 == out
- // 3 == Straddle
- static int WhichSide(
- const TGBinder& p1,
- const MT_Plane3& plane1
- );
-
-};
-
-template <class TGBinderA, class TGBinderB> class CSG_PolygonIntersector
-{
-public :
-
- static bool IntersectPolygons (
- const TGBinderA& p1,
- const TGBinderB& p2,
- const MT_Plane3& plane1,
- const MT_Plane3& plane2
- );
-
-};
-
-
-#include "CSG_Math.inl"
-
-#endif
-
diff --git a/intern/csg/intern/CSG_Math.inl b/intern/csg/intern/CSG_Math.inl
deleted file mode 100644
index 73483ea41d6..00000000000
--- a/intern/csg/intern/CSG_Math.inl
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#include "CSG_Math.h"
-#include "MT_minmax.h"
-#include "MT_Point2.h"
-#include "MT_Vector2.h"
-#include "MT_Plane3.h"
-
-#include <vector>
-
-using namespace std;
-
-inline bool CSG_Geometry::Intersect(
- const MT_Plane3& p1,
- const MT_Plane3& p2,
- MT_Line3& output
-) {
- MT_Matrix3x3 mat;
- mat[0] = p1.Normal();
- mat[1] = p2.Normal();
- mat[2] = mat[0].cross(mat[1]);
-
- if (mat[2].fuzzyZero())
- {
- return false;
- }
-
- MT_Vector3 aPoint(-p1.Scalar(),-p2.Scalar(),0);
-
- output = MT_Line3(MT_Point3(0,0,0) + mat.inverse()*aPoint ,mat[2]);
-
- assert(MT_fuzzyZero(p1.signedDistance(output.Origin())));
- assert(MT_fuzzyZero(p2.signedDistance(output.Origin())));
-
-
- return true;
-}
-
-inline bool CSG_Geometry::Intersect2DNoBoundsCheck(
- const MT_Line3& l1,
- const MT_Line3& l2,
- int majAxis,
- MT_Scalar& l1Param,
- MT_Scalar& l2Param
-){
- int ind1 = cofacTable[majAxis][0];
- int ind2 = cofacTable[majAxis][1];
-
- MT_Scalar Zx = l2.Origin()[ind1] - l1.Origin()[ind1];
- MT_Scalar Zy = l2.Origin()[ind2] - l1.Origin()[ind2];
-
- MT_Scalar det = l1.Direction()[ind1]*l2.Direction()[ind2] -
- l2.Direction()[ind1]*l1.Direction()[ind2];
-
- if (MT_fuzzyZero(det))
- {
- return false;
- }
-
- l1Param = (l2.Direction()[ind2]*Zx - l2.Direction()[ind1]*Zy)/det;
- l2Param = -(-l1.Direction()[ind2]*Zx + l1.Direction()[ind1]*Zy)/det;
-
- return true;
-}
-
-
-inline bool CSG_Geometry::Intersect2DBoundsCheck(
- const MT_Line3& l1,
- const MT_Line3& l2,
- int majAxis,
- MT_Scalar& l1Param,
- MT_Scalar& l2Param
-) {
-
- bool isect = Intersect2DNoBoundsCheck(l1,l2,majAxis,l1Param,l2Param);
- if (!isect) return false;
-
- return l1.IsParameterOnLine(l1Param) && l2.IsParameterOnLine(l2Param);
-}
-
-
-//IMplementation of CSG_Math
-////////////////////////////
-
-template<typename TGBinder>
-inline bool CSG_Math<TGBinder>::IntersectPolyWithLine2D(
- const MT_Line3& l,
- const TGBinder& p1,
- const MT_Plane3& plane,
- MT_Scalar& a,
- MT_Scalar& b
-){
- int majAxis = plane.Normal().closestAxis();
- int lastInd = p1.Size()-1;
-
- b = (-MT_INFINITY);
- a = (MT_INFINITY);
-
- MT_Scalar isectParam(0);
- MT_Scalar isectParam2(0);
-
- int i;
- int j = lastInd;
- int isectsFound(0);
- for (i=0;i<=lastInd; j=i,i++ )
- {
- MT_Line3 testLine(p1[j],p1[i]);
- if ( CSG_Geometry::Intersect2DBoundsCheck(l,testLine,majAxis,isectParam,isectParam2))
- {
- ++isectsFound;
- b = MT_max(isectParam,b);
- a = MT_min(isectParam,a);
- }
- }
-
- return (isectsFound > 0);
-}
-
-template<typename TGBinder>
-inline bool CSG_Math<TGBinder>::InstersectPolyWithLine3D(
- const MT_Line3& l,
- const TGBinder& p1,
- const MT_Plane3& plane,
- MT_Scalar& a
-){
- // First compute intersection parameter t
- MT_Scalar determinant = l.Direction().dot(plane.Normal());
-
- // they are coplanar but we're not interested in that right?
- if (MT_fuzzyZero(determinant)) return false;
-
- a = -plane.Scalar() - plane.Normal().dot(l.Origin());
- a /= determinant;
-
- // intersection point is behind the ray.
- if (a <= 0 ) return false;
-
-
- // check if line is bounded and if t lies in bounds.
- if (!l.IsParameterOnLine(a)) return false;
-
- // calculate the point on the plane
- MT_Point3 pointOnPlane = l.Origin() + l.Direction()*a;
-
- assert(MT_fuzzyZero(plane.signedDistance(pointOnPlane)));
-
- // make sure the intersection point is within the polygon
- return PointInPolygonTest3D(p1,plane,l.Origin(),pointOnPlane);
-}
-
-
-
-template<typename TGBinder>
-inline bool CSG_Math<TGBinder>::PointInPolygonTest3D(
- const TGBinder& p1,
- const MT_Plane3& plane,
- const MT_Point3& origin,
- const MT_Point3& pointOnPlane
-) {
- // Form planes with the edges of the polygon and the origin.
- // make sure that origin is inside all these planes.
-
- // ONe small detail we have to first workout which side the origin
- // is wrt the plane of the polygon.
-
- bool discardSign = plane.signedDistance(origin) < 0 ? true : false;
-
- const int polySize = p1.Size();
-
- MT_Point3 lastPoint = p1[polySize-1];
-
- int i;
- for (i=0;i<polySize; ++i)
- {
- const MT_Point3& aPoint = p1[i];
-
- MT_Plane3 testPlane(origin,lastPoint,aPoint);
- if ((testPlane.signedDistance(pointOnPlane) <= 0) == discardSign)
- {
- return false;
- }
- lastPoint = aPoint;
- }
- return true;
-}
-
-// return 0 = on
-// return 1 = in
-// return 2 = out
-
-inline int CSG_Geometry::ComputeClassification(
- const MT_Scalar& distance,
- const MT_Scalar& epsilon
-) {
- if (MT_abs(distance) < epsilon)
- {
- return 0;
- } else {
- return distance < 0 ? 1 : 2;
- }
-}
-
-// Return the mid-point of the given polygon index.
-template <typename TGBinder>
-inline MT_Point3 CSG_Math<TGBinder>::PolygonMidPoint(
- const TGBinder& p1
-){
-
- MT_Point3 midPoint(0,0,0);
-
- int i;
- for (i=0; i < p1.Size(); i++)
- {
- midPoint += p1[i];
- }
-
- return MT_Point3(midPoint[0]/i,midPoint[1]/i,midPoint[2]/i);
-}
-
-template <typename TGBinder>
-int CSG_Math<TGBinder>::WhichSide(
- const TGBinder& p1,
- const MT_Plane3& plane1
-){
-
- int output = 0;
- int i;
- for (i=0; i<p1.Size(); i++)
- {
- MT_Scalar signedDistance = plane1.signedDistance(p1[i]);
- if (!MT_fuzzyZero(signedDistance))
- {
- signedDistance < 0 ? (output |= 1) : (output |=2);
- }
- }
- return output;
-
-}
-
-
-template <typename TGBinder>
-inline MT_Line3 CSG_Math<TGBinder>::PolygonMidPointRay(
- const TGBinder& p1,
- const MT_Plane3& plane
-){
- return MT_Line3(PolygonMidPoint(p1),plane.Normal(),true,false);
-}
-
-template <typename TGBinder>
-inline MT_Plane3 CSG_Math<TGBinder>::ComputePlane(
- const TGBinder &poly
-){
- assert(poly.Size() >= 3);
- MT_Point3 plast(poly[poly.Size()-1]);
- MT_Point3 pivot;
- MT_Vector3 edge;
- int j;
- for (j=0; j < poly.Size(); j++)
- {
- pivot = poly[j];
- edge = pivot - plast;
- if (!edge.fuzzyZero()) break;
- }
-
- for (; j < poly.Size(); j++)
- {
- MT_Vector3 v2 = poly[j] - pivot;
- MT_Vector3 v3 = edge.cross(v2);
- if (!v3.fuzzyZero())
- {
- return MT_Plane3(v3,pivot);
- }
- }
-
- return MT_Plane3();
-
-}
-
-template <typename TGBinder>
-inline BBox CSG_Math<TGBinder>::FitBBox(
- const TGBinder& p1
-) {
- BBox bbox;
- bbox.SetEmpty();
-
- for (int i = 0; i < p1.Size(); ++i) {
- bbox.Include(p1[i]);
- }
- return bbox;
-}
-
-// we now have enough machinary to intersect 3d polygons
-// Compute line of intersect
-// Intersect line with each edge in PolygonB record min and max intersection parameters
-// Do same for PolygonB. If range of intersections overlap then polys overlap.
-
-// Does not yet deal with 2d case.
-
-template<typename TGBinderA, typename TGBinderB>
-inline bool CSG_PolygonIntersector<TGBinderA,TGBinderB>::IntersectPolygons (
- const TGBinderA& p1,
- const TGBinderB& p2,
- const MT_Plane3& plane1,
- const MT_Plane3& plane2
-){
- MT_Line3 intersectLine;
- if (!CSG_Geometry::Intersect(plane1,plane2,intersectLine))
- {
- // parrallel planes
- return false;
- }
- // check intersection of polygons with intersectLine
- MT_Scalar p1A,p1B;
- MT_Scalar p2A,p2B;
- if (
- !CSG_Math<TGBinderA>::IntersectPolyWithLine2D(intersectLine,p1,plane1,p1A,p1B) ||
- !CSG_Math<TGBinderB>::IntersectPolyWithLine2D(intersectLine,p2,plane2,p2A,p2B)
- ) {
- return false;
- }
-
- // see if intersections overlap.
-
- MT_Scalar maxOMin = MT_max(p1A,p2A);
- MT_Scalar minOMax = MT_min(p1B,p2B);
-
- return (maxOMin <= minOMax);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_Mesh.h b/intern/csg/intern/CSG_Mesh.h
deleted file mode 100644
index bd687824484..00000000000
--- a/intern/csg/intern/CSG_Mesh.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef __MESH_H
-#define __MESH_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_GeometryBinder.h"
-#include <vector>
-
-// Simple vertex polygon container class
-//--------------------------------------
-
-template <typename TPolygon, typename TVertex> class Mesh
-{
-public :
- typedef std::vector<TVertex> VLIST;
- typedef std::vector<TPolygon> PLIST;
-
- typedef TPolygon Polygon;
- typedef TVertex Vertex;
-
- typedef PolygonGeometry<Mesh> TGBinder;
-
-private :
-
- VLIST m_verts;
- PLIST m_polys;
-
- MT_Point3 m_bBoxMin;
- MT_Point3 m_bBoxMax;
-
-
-public :
-
- Mesh():
- m_verts(),
- m_polys()
- {};
-
- VLIST& Verts() {return m_verts;}
- const VLIST& Verts() const {return m_verts;}
-
- PLIST& Polys() {return m_polys;}
- const PLIST& Polys() const {return m_polys;}
-
- ~Mesh() {}
-};
-
-#endif
diff --git a/intern/csg/intern/CSG_MeshCopier.h b/intern/csg/intern/CSG_MeshCopier.h
deleted file mode 100644
index 4acf4440df6..00000000000
--- a/intern/csg/intern/CSG_MeshCopier.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef CSG_MeshCopier_H
-#define CSG_MeshCopier_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-
-template <typename MeshA, typename MeshB> class MeshCopier
-{
-public :
-
- static void Copy(const MeshA& source, MeshB& output)
- {
- int vertexNum = source.Verts().size();
- int polyNum = source.Polys().size();
-
- output.Verts() = MeshB::VLIST(vertexNum);
- output.Polys() = MeshB::PLIST(polyNum);
-
- std::copy(source.Verts().begin(),source.Verts().end(),output.Verts().begin());
- std::copy(source.Polys().begin(),source.Polys().end(),output.Polys().begin());
-
- }
-
-};
-
-#endif
-
diff --git a/intern/csg/intern/CSG_MeshWrapper.h b/intern/csg/intern/CSG_MeshWrapper.h
deleted file mode 100644
index b557dde37c9..00000000000
--- a/intern/csg/intern/CSG_MeshWrapper.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef CSG_MESH_WRAPPER_H
-#define CSG_MESH_WRAPPER_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-// This class wraps a mesh providing
-// simple mesh functions required by the CSG library.
-// TMesh is a model of a mesh and as such should have the
-// following public typedefs and functions
-//
-// TMesh::Vertex the vertex type
-// TMesh::Polygon the polygon type.
-// TMesh::VLIST an stl container of Vertex objects
-// TMesh::PLIST an stl container of Polygon objects
-//
-// VLIST& Verts();
-// const VLIST& Verts();
-//
-// PLIST& Polys();
-// const PLIST& Polys();
-
-#include "CSG_GeometryBinder.h"
-#include "MT_Transform.h"
-#include "CSG_BBox.h"
-
-#include <vector>
-
-template <typename TMesh> class MeshWrapper
-{
-public :
-
- typedef TMesh::Polygon Polygon;
- typedef TMesh::Vertex Vertex;
-
- typedef TMesh::VLIST VLIST;
- typedef TMesh::PLIST PLIST;
-
- typedef PolygonGeometry<MeshWrapper> TGBinder;
-
- typedef MeshWrapper<TMesh> MyType;
-
-private :
- TMesh& m_mesh;
-
-public :
-
- // Mesh Template interface
- //////////////////////////
-
- VLIST& Verts() {return m_mesh.Verts();}
- const VLIST& Verts() const {return m_mesh.Verts();}
-
- PLIST& Polys() {return m_mesh.Polys();}
- const PLIST& Polys() const {return m_mesh.Polys();}
-
- // Mesh Wrapper functions
- /////////////////////////
-
- MeshWrapper(TMesh& mesh)
- : m_mesh(mesh)
- {}
-
- void ComputePlanes();
-
- void BurnTransform(const MT_Transform& t);
-
- BBox ComputeBBox() const;
-
- // Triangulate this mesh - does not preserve vertex->polygon information.
- void Triangulate();
-
- // Split the polygon at position p1Index in the mesh mesh1 into 2 pieces.
- // Remove the polygon p1 and add the 2 pieces (along with the 2 new vertices)
- // to the mesh. Returns the index of the 2 new pieces in the mesh.(either of [but never both] which can be
- // -1 if there was nothing to split.
-
- void SplitPolygon(
- const int p1Index,
- const MT_Plane3& plane,
- int& inPiece,
- int& outPiece,
- const MT_Scalar onEpsilon
- );
-
-
- ~MeshWrapper(){};
-
-};
-
-#include "CSG_MeshWrapper.inl"
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/CSG_MeshWrapper.inl b/intern/csg/intern/CSG_MeshWrapper.inl
deleted file mode 100644
index 7a9a141e92a..00000000000
--- a/intern/csg/intern/CSG_MeshWrapper.inl
+++ /dev/null
@@ -1,150 +0,0 @@
-// Implementation of MeshWrapper template class.
-////////////////////////////////////////////////
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#include "CSG_Math.h"
-#include "CSG_Triangulate.h"
-#include "CSG_SplitFunction.h"
-
-template <typename TMesh>
-void MeshWrapper<TMesh>::ComputePlanes()
-{
- PLIST& polyList = Polys();
-
- int i;
- for (i=0;i < polyList.size(); i++)
- {
- TGBinder binder(m_mesh,i);
- polyList[i].SetPlane(CSG_Math<TGBinder>::ComputePlane(binder));
- }
-}
-
-template <typename TMesh>
-void MeshWrapper<TMesh>::BurnTransform(const MT_Transform& t)
-{
- VLIST& vertexList = Verts();
-
- int i;
- for (i=0;i<vertexList.size(); i++)
- {
- vertexList[i].Pos() = t * vertexList[i].Pos();
- }
- ComputePlanes();
-
-}
-
-template <typename TMesh>
-BBox MeshWrapper<TMesh>::ComputeBBox() const
-{
- const VLIST& vertexList = Verts();
-
- BBox bbox;
- bbox.SetEmpty();
-
- int i;
- for (i=0;i<vertexList.size(); i++)
- {
- bbox.Include(vertexList[i].Pos());
- }
- return bbox;
-
-}
-
-
-template <typename TMesh>
-void MeshWrapper<TMesh>::Triangulate()
-{
- vector<Polygon> newPolys;
-
- CSG_Triangulate<TGBinder> triangulator;
- int i;
- for (i=0; i< Polys().size(); ++i)
- {
- TGBinder pg(m_mesh,i);
- const Polygon& poly = Polys()[i];
-
- if (pg.Size() >= 4)
- {
- VIndexList triangleList;
-
- if (triangulator.Process(pg,poly.Plane(),triangleList))
- {
-
- // translate the triangle list into the real vertex properties
- int tSize = triangleList.size();
- Polygon::TVPropList triangleProps(tSize);
-
- int j;
- for (j=0; j < tSize; j++)
- {
- triangleProps[j] = poly.VertexProps(triangleList[j]);
- }
-
- // iterate through the new triangles
- for (j=0; j < tSize; j+=3)
- {
- // copy the polygon
- newPolys.push_back(poly);
- newPolys.back().Verts().clear();
-
- // copy the relevant triangle indices
- newPolys.back().Verts().assign(triangleProps.begin() + j,triangleProps.begin() + j +3);
- }
-
- }
- } else {
- if (pg.Size() >= 3) {
- newPolys.push_back(poly);
- }
- }
- }
-
- // replace our polygons with the new ones.
- Polys() = newPolys;
-};
-
-template<typename TMesh>
-void MeshWrapper<TMesh>::SplitPolygon(
- const int p1Index,
- const MT_Plane3& plane,
- int& inPiece,
- int& outPiece,
- const MT_Scalar onEpsilon
-){
-
- DefaultSplitFunctionBindor<TMesh::Polygon::TVProp> defaultSplitFunction;
-
- SplitFunction<MyType,DefaultSplitFunctionBindor<TMesh::Polygon::TVProp> > splitFunction(*this,defaultSplitFunction);
- splitFunction.SplitPolygon(p1Index,plane,inPiece,outPiece,onEpsilon);
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/csg/intern/CSG_Polygon.h b/intern/csg/intern/CSG_Polygon.h
deleted file mode 100644
index 8332977da71..00000000000
--- a/intern/csg/intern/CSG_Polygon.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef __POLYGON_H
-#define __POLYGON_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_IndexDefs.h"
-
-#include <algorithm>
-#include "MT_Plane3.h"
-#include "MT_Point3.h"
-
-template <typename AVProp, typename AFProp> class PolygonBase
-{
-public :
-
- // The per vertex properties
- typedef AVProp TVProp;
-
- // The per face properties
- typedef AFProp TFProp;
-
- typedef std::vector<TVProp> TVPropList;
- typedef TVPropList::iterator TVPropIt;
-
- // Functions required by the CSG library
- ////////////////////////////////////////
-
- PolygonBase():m_fProp(){}
-
- const TVPropList& Verts() const { return m_verts;}
- TVPropList& Verts() { return m_verts;}
-
- int Size() const { return m_verts.size();}
-
- int operator[](int i) const {return m_verts[i];}
-
- const TVProp& VertexProps(int i) const { return m_verts[i];}
- TVProp& VertexProps(int i) { return m_verts[i];}
-
- void SetPlane(const MT_Plane3& plane) { m_plane = plane;}
-
- const MT_Plane3& Plane() const { return m_plane;}
- MT_Vector3 Normal() const { return m_plane.Normal();}
-
- int & Classification() { return m_classification;}
- const int& Classification() const { return m_classification;}
-
- // Reverse this polygon.
- void Reverse()
- {
- std::reverse(m_verts.begin(),m_verts.end());
- m_plane.Invert();
- }
-
- // Our functions
- ////////////////
-
- TFProp& FProp(){ return m_fProp;}
- const TFProp& FProp() const { return m_fProp;}
-
- ~PolygonBase() {}
-
-private :
-
- TVPropList m_verts;
- MT_Plane3 m_plane;
-
- TFProp m_fProp;
-
- // gross waste of bits! 1 = in, 2 = out;
- int m_classification;
-
-};
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/CSG_SplitFunction.h b/intern/csg/intern/CSG_SplitFunction.h
deleted file mode 100644
index 70929a3d4ec..00000000000
--- a/intern/csg/intern/CSG_SplitFunction.h
+++ /dev/null
@@ -1,188 +0,0 @@
-#ifndef CCG_SplitFunction_H
-#define CCG_SplitFunction_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-// This class contains the all important split function.
-// It's a bit of weird definition but doing it like this
-// means we don't have to copy any code between implementations
-// that preserve mesh connectivity and those that introduce T junctions.
-
-template <typename TMesh, typename TSplitFunctionBindor> class SplitFunction
-{
-private :
-
- TMesh& m_mesh;
- TSplitFunctionBindor& m_functionBindor;
-
-public :
-
- SplitFunction( TMesh& mesh, TSplitFunctionBindor& functionBindor)
- : m_mesh(mesh), m_functionBindor(functionBindor)
- {};
-
- void
- SplitPolygon(
- const int p1Index,
- const MT_Plane3& plane,
- int& inPiece,
- int& outPiece,
- const MT_Scalar onEpsilon
- ){
-
- const TMesh::Polygon& p = m_mesh.Polys()[p1Index];
- TMesh::Polygon inP(p),outP(p);
-
- inP.Verts().clear();
- outP.Verts().clear();
-
- // Disconnect the polygon from the mesh.
- m_functionBindor.DisconnectPolygon(p1Index);
-
- int lastIndex = p.Verts().back();
- MT_Point3 lastVertex = m_mesh.Verts()[lastIndex].Pos();
-
- int lastClassification = CSG_Geometry::ComputeClassification(plane.signedDistance(lastVertex),onEpsilon);
- int totalClassification(lastClassification);
-
- // iterate through the vertex indices of the to-be-split polygon
-
- int i;
- int j=p.Size()-1;
- for (i = 0; i < p.Size(); j = i, ++i)
- {
- int newIndex = p[i];
- MT_Point3 aVertex = m_mesh.Verts()[newIndex].Pos();
- int newClassification = CSG_Geometry::ComputeClassification(plane.signedDistance(aVertex),onEpsilon);
-
- // if neither the new vertex nor the old vertex were on and they differ
- if ((newClassification != lastClassification) && newClassification && lastClassification)
- {
- // create new vertex
- int newVertexIndex = m_mesh.Verts().size();
- m_mesh.Verts().push_back(TMesh::Vertex());
-
- // work out new vertex position.
- MT_Vector3 v = aVertex - lastVertex;
- MT_Scalar sideA = plane.signedDistance(lastVertex);
-
- MT_Scalar epsilon = -sideA/plane.Normal().dot(v);
- m_mesh.Verts().back().Pos() = lastVertex + (v * epsilon);
-
- // Make a new VertexProp
- TMesh::Polygon::TVProp splitProp(newVertexIndex,p.VertexProps(j),p.VertexProps(i),epsilon);
-
-
- // add new index to both polygons.
- inP.Verts().push_back( splitProp );
- outP.Verts().push_back( splitProp );
-
- // insert vertex into any neighbouring polygons of this edge
- m_functionBindor.InsertVertexAlongEdge(lastIndex,newIndex,splitProp);
-
- }
-
- Classify(inP.Verts(),outP.Verts(),newClassification,p.VertexProps(i));
- lastClassification = newClassification;
- totalClassification |= newClassification;
- lastVertex = aVertex;
- lastIndex = newIndex;
- }
-
- if (totalClassification == 3)
- {
- // replace polygon p with the inpiece and add the outPiece to the back
- // of the mesh. we just replace the vertices as the normal will be the same.
-
- inPiece = p1Index;
- outPiece = m_mesh.Polys().size();
-
- m_mesh.Polys()[p1Index] = inP;
- m_mesh.Polys().push_back( outP );
-
- m_functionBindor.ConnectPolygon(inPiece);
- m_functionBindor.ConnectPolygon(outPiece);
-
- } else {
-
- // remember to connect back the original polygon!
- m_functionBindor.ConnectPolygon(p1Index);
-
- // dont touch the mesh but just return the index of the original polygon
- if (totalClassification == 1)
- {
- inPiece = p1Index;
- outPiece = -1;
- } else {
- outPiece = p1Index;
- inPiece = -1;
- }
- }
- }
-
-
- void Classify(
- TMesh::Polygon::TVPropList &inGroup,
- TMesh::Polygon::TVPropList &outGroup,
- int classification,
- TMesh::Polygon::TVProp prop
- ) {
- switch (classification)
- {
- case 0 :
- inGroup.push_back(prop);
- outGroup.push_back(prop);
- break;
- case 1 :
- inGroup.push_back(prop);
- break;
- case 2 :
- outGroup.push_back(prop);
- break;
- default :
- break;
- }
- }
-
- ~SplitFunction() {};
-};
-
-
-template <typename PROP> class DefaultSplitFunctionBindor
-{
-public :
-
- DefaultSplitFunctionBindor() {};
-
- void DisconnectPolygon(int){
- }
-
- void ConnectPolygon(int) {
- }
-
- void InsertVertexAlongEdge(int,int,const PROP& ) {
- }
-
- ~DefaultSplitFunctionBindor(){};
-};
-
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/CSG_TreeQueries.h b/intern/csg/intern/CSG_TreeQueries.h
deleted file mode 100644
index 1b79d2ca36d..00000000000
--- a/intern/csg/intern/CSG_TreeQueries.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef CSG_TREEQUERIES_H
-#define CSG_TREEQUERIES_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_IndexDefs.h"
-#include "CSG_BBoxTree.h"
-#include "CSG_Math.h"
-
-template <typename TMesh> class TreeIntersector
-{
-public :
-
- TreeIntersector(
- const BBoxTree& a,
- const BBoxTree& b,
- OverlapTable *aOverlapsB,
- OverlapTable *bOverlapsA,
- const TMesh* meshA,
- const TMesh* meshB
- ) {
- m_aOverlapsB = aOverlapsB;
- m_bOverlapsA = bOverlapsA;
- m_meshA = meshA;
- m_meshB = meshB;
-
- MarkIntersectingPolygons(a.RootNode(),b.RootNode());
- }
-
-private :
-
- void MarkIntersectingPolygons(const BBoxNode*a,const BBoxNode *b)
- {
- if (!intersect(a->m_bbox, b->m_bbox)) return;
- if (a->m_tag == BBoxNode::LEAF && b->m_tag == BBoxNode::LEAF)
- {
- const BBoxLeaf *la = (const BBoxLeaf *)a;
- const BBoxLeaf *lb = (const BBoxLeaf *)b;
-
- PolygonGeometry<TMesh> pg1(*m_meshA,la->m_polyIndex);
- PolygonGeometry<TMesh> pg2(*m_meshB,lb->m_polyIndex);
-
- if (CSG_PolygonIntersector<PolygonGeometry<TMesh>,PolygonGeometry<TMesh> >::
- IntersectPolygons(pg1,pg2,
- m_meshA->Polys()[la->m_polyIndex].Plane(),
- m_meshB->Polys()[lb->m_polyIndex].Plane()
- )
- ) {
- (*m_aOverlapsB)[lb->m_polyIndex].push_back(la->m_polyIndex);
- (*m_bOverlapsA)[la->m_polyIndex].push_back(lb->m_polyIndex);
- }
- } else
- if ( a->m_tag == BBoxNode::LEAF ||
- (b->m_tag != BBoxNode::LEAF && a->m_bbox.Size() < b->m_bbox.Size())
- ) {
- MarkIntersectingPolygons(a,((const BBoxInternal *)b)->lson);
- MarkIntersectingPolygons(a,((const BBoxInternal *)b)->rson);
- } else {
- MarkIntersectingPolygons(((const BBoxInternal *)a)->lson,b);
- MarkIntersectingPolygons(((const BBoxInternal *)a)->rson,b);
- }
- }
-
- // Temporaries held through recursive intersection
- OverlapTable* m_aOverlapsB;
- OverlapTable* m_bOverlapsA;
- const TMesh* m_meshA;
- const TMesh* m_meshB;
-
-};
-
-template<typename TMesh> class RayTreeIntersector
-{
-public:
-
- RayTreeIntersector(
- const BBoxTree& a,
- const TMesh* meshA,
- const MT_Line3& xRay,
- int& polyIndex
- ):
- m_meshA(meshA),
- m_polyIndex(-1),
- m_lastIntersectValue(MT_INFINITY)
- {
- FindIntersectingPolygons(a.RootNode(),xRay);
- polyIndex = m_polyIndex;
- }
-
-
-private :
-
- void FindIntersectingPolygons(const BBoxNode*a,const MT_Line3& xRay)
- {
- if ((xRay.Origin().x() + m_lastIntersectValue < a->m_bbox.Lower(0)) ||
- !a->m_bbox.IntersectXRay(xRay.Origin())
- ) {
- // ray does not intersect this box.
- return;
- }
-
- if (a->m_tag == BBoxNode::LEAF)
- {
- const BBoxLeaf *la = (const BBoxLeaf *)a;
- MT_Scalar testParameter(0);
-
- PolygonGeometry<TMesh> pg(*m_meshA,la->m_polyIndex);
-
- if (
- CSG_Math<PolygonGeometry<TMesh> >::InstersectPolyWithLine3D(
- xRay,pg,m_meshA->Polys()[la->m_polyIndex].Plane(),testParameter
- )
- ) {
- if (testParameter < m_lastIntersectValue)
- {
- m_lastIntersectValue = testParameter;
- m_polyIndex = la->m_polyIndex;
- }
- }
- } else {
- FindIntersectingPolygons(((const BBoxInternal*)a)->lson,xRay);
- FindIntersectingPolygons(((const BBoxInternal*)a)->rson,xRay);
- }
- }
-
- const TMesh* m_meshA;
-
- MT_Scalar m_lastIntersectValue;
- int m_polyIndex;
-};
-
-
-
-
-
-
-
-
-
-#endif
diff --git a/intern/csg/intern/CSG_Triangulate.h b/intern/csg/intern/CSG_Triangulate.h
deleted file mode 100644
index 95c0b602ddf..00000000000
--- a/intern/csg/intern/CSG_Triangulate.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef TRIANGULATE_H
-#define TRIANGULATE_H
-
-/*****************************************************************/
-/** Static class to triangulate any contour/polygon efficiently **/
-/** You should replace Vector2d with whatever your own Vector **/
-/** class might be. Does not support polygons with holes. **/
-/** Uses STL vectors to represent a dynamic array of vertices. **/
-/** This code snippet was submitted to FlipCode.com by **/
-/** John W. Ratcliff (jratcliff@verant.com) on July 22, 2000 **/
-/** I did not write the original code/algorithm for this **/
-/** this triangulator, in fact, I can't even remember where I **/
-/** found it in the first place. However, I did rework it into **/
-/** the following black-box static class so you can make easy **/
-/** use of it in your own code. Simply replace Vector2d with **/
-/** whatever your own Vector implementation might be. **/
-/*****************************************************************/
-
-#include "CSG_IndexDefs.h"
-#include <vector> // Include STL vector class.
-class MT_Plane3;
-
-template <typename PGBinder> class CSG_Triangulate
-{
-public:
-
- CSG_Triangulate(
- );
-
- // triangulate a contour/polygon, places results in STL vector
- // as series of triangles. IT uses the major axis of the normal
- // to turn it into a 2d problem.
-
- // Should chaange this to accept a point array and a list of
- // indices into that point array. Result should be indices of those
- // indices.
- //
- // MT_Point3 global_array
- // vector<BSP_VertexInd> polygon
- // result is vector<int> into polygon.
-
- bool
- Process(
- const PGBinder& contour,
- const MT_Plane3 &normal,
- VIndexList &result
- );
-
- ~CSG_Triangulate(
- );
-
-private:
-
- // compute area of a contour/polygon
- MT_Scalar
- Area(
- const PGBinder& contour
- );
-
- // decide if point Px/Py is inside triangle defined by
- // (Ax,Ay) (Bx,By) (Cx,Cy)
-
- bool
- InsideTriangle(
- MT_Scalar Ax, MT_Scalar Ay,
- MT_Scalar Bx, MT_Scalar By,
- MT_Scalar Cx, MT_Scalar Cy,
- MT_Scalar Px, MT_Scalar Py
- );
-
-
- bool
- Snip(
- const PGBinder& contour,
- int u,
- int v,
- int w,
- int n,
- int *V
- );
-
- int m_xi;
- int m_yi;
- int m_zi;
-
- // Temporary storage
-
- VIndexList m_V;
-
-};
-
-#include "CSG_Triangulate.inl"
-
-#endif
-
-
diff --git a/intern/csg/intern/CSG_Triangulate.inl b/intern/csg/intern/CSG_Triangulate.inl
deleted file mode 100644
index d7f12201af3..00000000000
--- a/intern/csg/intern/CSG_Triangulate.inl
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#include "MT_Plane3.h"
-#include "MT_Point3.h"
-
-static const MT_Scalar EPSILON = MT_Scalar(1e-10);
-
-template <typename PGBinder>
-CSG_Triangulate<PGBinder>::
-CSG_Triangulate(
-):
- m_xi(0),
- m_yi(1)
-{
-}
-
-template <typename PGBinder>
-CSG_Triangulate<PGBinder>::
-~CSG_Triangulate(
-){
-}
-
-
-template <typename PGBinder>
- MT_Scalar
-CSG_Triangulate<PGBinder>::
-Area(
- const PGBinder& contour
-){
-
- int n = contour.Size();
- MT_Scalar A(0.0);
-
- for(int p=n-1,q=0; q<n; p=q++)
- {
- A+= contour[p][m_xi]*contour[q][m_yi] -
- contour[q][m_xi]*contour[p][m_yi];
- }
- return A*MT_Scalar(0.5);
-}
-
-/*
- InsideTriangle decides if a point P is Inside of the triangle
- defined by A, B, C.
- Or within an epsilon of it.
-*/
-
-template <typename PGBinder>
- bool
-CSG_Triangulate<PGBinder>::
-InsideTriangle(
- MT_Scalar Ax, MT_Scalar Ay,
- MT_Scalar Bx, MT_Scalar By,
- MT_Scalar Cx, MT_Scalar Cy,
- MT_Scalar Px, MT_Scalar Py
-){
- MT_Scalar ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
- MT_Scalar cCROSSap, bCROSScp, aCROSSbp;
-
- ax = Cx - Bx; ay = Cy - By;
- bx = Ax - Cx; by = Ay - Cy;
- cx = Bx - Ax; cy = By - Ay;
- apx= Px - Ax; apy= Py - Ay;
- bpx= Px - Bx; bpy= Py - By;
- cpx= Px - Cx; cpy= Py - Cy;
-
- aCROSSbp = ax*bpy - ay*bpx;
- cCROSSap = cx*apy - cy*apx;
- bCROSScp = bx*cpy - by*cpx;
-
- return ((aCROSSbp >= -EPSILON) && (bCROSScp >= -EPSILON) && (cCROSSap >= -EPSILON));
-};
-
-template <typename PGBinder>
- bool
-CSG_Triangulate<PGBinder>::
-Snip(
- const PGBinder& contour,
- int u,int v,
- int w,int n,
- int *V
-){
- MT_Scalar Ax, Ay, Bx, By, Cx, Cy;
-
- Ax = contour[V[u]][m_xi];
- Ay = contour[V[u]][m_yi];
-
- Bx = contour[V[v]][m_xi];
- By = contour[V[v]][m_yi];
-
- Cx = contour[V[w]][m_xi];
- Cy = contour[V[w]][m_yi];
-
- // Snip is passes if the area of the candidate triangle is
- // greater than 2*epsilon
- // And if none of the remaining vertices are inside the polygon
- // or within an epsilon of the boundary,
-
- if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false;
-#if 1
- // this check is only needed for non-convex polygons
- // well yeah but convex to me and you is not necessarily convex to opengl.
- int p;
- MT_Scalar Px,Py;
-
- for (p=0;p<n;p++)
- {
- if( (p == u) || (p == v) || (p == w) ) continue;
- Px = contour[V[p]][m_xi];
- Py = contour[V[p]][m_yi];
- if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
- }
-#endif
- return true;
-}
-
-template <typename PGBinder>
- bool
-CSG_Triangulate<PGBinder>::
-Process(
- const PGBinder& contour,
- const MT_Plane3 &normal,
- VIndexList &result
-){
-
- // Choose major axis of normal and assign
- // 'projection' indices m_xi,m_yi;
-
- int maj_axis = normal.Normal().closestAxis();
-
- if (maj_axis == 0) {
- m_xi = 1; m_yi = 2;
- } else
- if (maj_axis == 1) {
- m_xi = 0; m_yi = 2;
- } else {
- m_xi = 0; m_yi = 1;
- }
- m_zi = maj_axis;
-
- /* initialize list of Vertices in polygon */
-
- int n = contour.Size();
- if ( n < 3 ) return false;
-
- /* we want a counter-clockwise polygon in V */
- /* to true but we also nead to preserve the winding order
- of polygons going into the routine. We keep track of what
- we did with a little bool */
- bool is_flipped = false;
-
- if ( 0.0f < Area(contour) ) {
- for (int v=0; v<n; v++) m_V.push_back(v);
- } else {
- for(int v=0; v<n; v++) m_V.push_back((n-1)-v);
- is_flipped = true;
- }
-
- int nv = n;
-
- /* remove nv-2 Vertices, creating 1 triangle every time */
- int count = 2*nv; /* error detection */
-
- for(int m=0, v=nv-1; nv>2; )
- {
- /* if we loop, it is probably a non-simple polygon */
- if (0 >= (count--))
- {
- //** Triangulate: ERROR - probable bad polygon!
- m_V.clear();
- return false;
- }
-
- /* three consecutive vertices in current polygon, <u,v,w> */
- int u = v ; if (nv <= u) u = 0; /* previous */
- v = u+1; if (nv <= v) v = 0; /* new v */
- int w = v+1; if (nv <= w) w = 0; /* next */
-
- /* Try and snip this triangle off from the
- current polygon.*/
-
- if ( Snip(contour,u,v,w,nv,m_V.begin()) )
- {
- int a,b,c,s,t;
-
- /* true names of the vertices */
- a = m_V[u]; b = m_V[v]; c = m_V[w];
-
- /* output Triangle indices*/
- if (is_flipped) {
- result.push_back( c );
- result.push_back( b );
- result.push_back( a );
- } else {
- result.push_back( a );
- result.push_back( b );
- result.push_back( c );
- }
-
- m++;
-
- /* remove v from remaining polygon */
- for(s=v,t=v+1;t<nv;s++,t++) m_V[s] = m_V[t]; nv--;
-
- /* resest error detection counter */
- count = 2*nv;
- }
- }
-
- m_V.clear();
- return true;
-}
-
-
diff --git a/intern/csg/intern/CSG_Vertex.h b/intern/csg/intern/CSG_Vertex.h
deleted file mode 100644
index bb39dbceab5..00000000000
--- a/intern/csg/intern/CSG_Vertex.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __VERTEX_H
-#define __VERTEX_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "MT_Point3.h"
-#include <algorithm>
-#include "CSG_IndexDefs.h"
-
-
-class VertexBase
-{
-protected:
-
- // Map to this vertex position in the classified Mesh
- // or -1 if this vertex has not yet been used.
- int m_vertexMap;
-
- MT_Point3 m_pos;
-
-public :
-
- VertexBase():m_vertexMap(-1) {};
-
- // Regular vertex model
- //////////////////////
- const MT_Point3& Pos() const { return m_pos;}
- MT_Point3& Pos() {return m_pos;}
-
- int & VertexMap() { return m_vertexMap;}
- const int & VertexMap() const { return m_vertexMap;}
-
- ~VertexBase(){};
-};
-
-#endif
-
-
diff --git a/intern/csg/intern/MT_Line3.cpp b/intern/csg/intern/MT_Line3.cpp
deleted file mode 100644
index 199eaea3390..00000000000
--- a/intern/csg/intern/MT_Line3.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-//implementation of MT_Line3
-/////////////////////////////
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "MT_Line3.h"
-
-MT_Line3::MT_Line3()
-:
- m_origin(0,0,0),
- m_dir(1,0,0)
-{
- m_bounds[0] = false;
- m_bounds[1] = false;
-
- m_params[0] = 0;
- m_params[1] = 1;
-}
-
-
-MT_Line3::MT_Line3(
- const MT_Point3& p1,
- const MT_Point3& p2
-):
- m_origin(p1),
- m_dir(p2-p1)
-{
- m_bounds[0] = true;
- m_bounds[1] = true;
- m_params[0] = 0;
- m_params[1] = 1;
-}
-
-// construct infinite line from p1 in direction v
-MT_Line3::MT_Line3(
- const MT_Point3& p1,
- const MT_Vector3& v
-):
- m_origin(p1),
- m_dir(v)
-{
- m_bounds[0] = false;
- m_bounds[1] = false;
- m_params[0] = 0;
- m_params[1] = 1;
-}
-
-MT_Line3::MT_Line3(
- const MT_Point3& p1,
- const MT_Vector3& v,
- bool bound1,
- bool bound2
-):
- m_origin(p1),
- m_dir(v)
-{
- m_bounds[0] = bound1;
- m_bounds[1] = bound2;
- m_params[0] = 0;
- m_params[1] = 1;
-}
-
-
diff --git a/intern/csg/intern/MT_Line3.h b/intern/csg/intern/MT_Line3.h
deleted file mode 100644
index e36f3995b91..00000000000
--- a/intern/csg/intern/MT_Line3.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __CGS_LINE_H
-#define __CGS_LINE_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "MT_Point3.h"
-#include "MT_Vector3.h"
-
-class MT_Line3
-{
-public :
-
- MT_Line3();
-
- // construct closed line segment from p1 -> p2
- MT_Line3(const MT_Point3& p1, const MT_Point3& p2);
-
- // construct infinite line from p1 in direction v
- MT_Line3(const MT_Point3& p1, const MT_Vector3& v);
-
- MT_Line3(const MT_Point3& p1, const MT_Vector3& v, bool bound1, bool bound2);
-
- // return an infinite ray from the point p1 in the direction v
- static MT_Line3 InfiniteRay(const MT_Point3& p1, const MT_Vector3& v);
-
- // return direction of line
- const MT_Vector3& Direction() const { return m_dir;}
-
- // return a point on the line
- const MT_Point3& Origin() const { return m_origin;}
-
- bool Bounds(int i) const {
- return (i == 0 ? m_bounds[0] : m_bounds[1]);
- }
-
- bool & Bounds(int i) {
- return (i == 0 ? m_bounds[0] : m_bounds[1]);
- }
-
- const MT_Scalar& Param(int i) const {
- return (i == 0 ? m_params[0] : m_params[1]);
- }
-
- MT_Scalar& Param(int i){
- return (i == 0 ? m_params[0] : m_params[1]);
- }
-
- // Return the smallest Vector from the point to the line
- // does not take into account bounds of line.
- MT_Vector3 UnboundSmallestVector(const MT_Point3& point) const
- {
- MT_Vector3 diff(m_origin-point);
- return diff - m_dir * diff.dot(m_dir);
- }
-
- // Return the closest parameter of the line to the
- // point.
- MT_Scalar UnboundClosestParameter(const MT_Point3& point) const
- {
- MT_Vector3 diff(m_origin-point);
- return diff.dot(m_dir);
- }
-
- MT_Scalar UnboundDistance(const MT_Point3& point) const
- {
- return UnboundSmallestVector(point).length();
- }
-
- // Return true if the line parameter t is actually within the line bounds.
- bool IsParameterOnLine(const MT_Scalar &t) const
- {
- return ((m_params[0]-MT_EPSILON < t) || (!m_bounds[0])) && ((m_params[1] > t+MT_EPSILON) || (!m_bounds[1]));
-// return ((m_params[0] < t) || (!m_bounds[0])) && ((m_params[1] > t ) || (!m_bounds[1]));
- }
-
-
-private :
-
- bool m_bounds[2];
-
- MT_Scalar m_params[2];
- MT_Point3 m_origin;
- MT_Vector3 m_dir;
-
-};
-
-
-
-
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_BlenderMesh.h b/intern/csg/intern/blender/CSG_BlenderMesh.h
deleted file mode 100644
index 1f7a841d1e2..00000000000
--- a/intern/csg/intern/blender/CSG_BlenderMesh.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef CSG_BlenderMesh_H
-#define CSG_BlenderMesh_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-//typedefs for types used to represent blender meshes in the CSG library
-
-#include "CSG_IndexDefs.h"
-#include "CSG_ConnectedMesh.h"
-
-#include "CSG_Vertex.h"
-#include "CSG_CVertex.h"
-#include "CSG_Polygon.h"
-#include "CSG_Mesh.h"
-#include "CSG_MeshWrapper.h"
-#include "CSG_Interface.h"
-#include "CSG_BlenderVProp.h"
-
-typedef PolygonBase<BlenderVProp,CSG_IFaceData> TestPolygon;
-
-typedef Mesh<TestPolygon,VertexBase> AMesh;
-typedef Mesh<TestPolygon,CVertex > AConnectedMesh;
-
-typedef MeshWrapper<AMesh> AMeshWrapper;
-typedef ConnectedMeshWrapper<AConnectedMesh> AConnectedMeshWrapper;
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_BlenderVProp.cpp b/intern/csg/intern/blender/CSG_BlenderVProp.cpp
deleted file mode 100644
index 6acbdf25e6f..00000000000
--- a/intern/csg/intern/blender/CSG_BlenderVProp.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "CSG_Interface.h"
-#include "CSG_BlenderVProp.h"
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#pragma warning( disable : 4786 )
-
-int NoFunc(
- const CSG_IFaceVertexData*,
- const CSG_IFaceVertexData*,
- CSG_IFaceVertexData*,
- double
-){
- return 0;
-}
-
-
-CSG_InterpolateUserFaceVertexDataFunc BlenderVProp::InterpFunc = &NoFunc; \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_CsgOp.cpp b/intern/csg/intern/blender/CSG_CsgOp.cpp
deleted file mode 100644
index 1ff84ab0f3b..00000000000
--- a/intern/csg/intern/blender/CSG_CsgOp.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-#pragma warning( disable : 4786 )
-
-#include "CSG_CsgOp.h"
-#include "CSG_BooleanOp.h"
-#include "CSG_BBoxTree.h"
-#include "CSG_Math.h"
-#include "CSG_GeometryBinder.h"
-#include "CSG_MeshCopier.h"
-
-#include "MEM_SmartPtr.h"
-
-using namespace std;
-
- void
-BuildTree(
- const AMesh& mesh,
- BBoxTree& tree
-) {
- int numLeaves = mesh.Polys().size();
-
- BBoxLeaf *aLeaves = new BBoxLeaf[numLeaves];
-
- int i;
- for (i=0;i< mesh.Polys().size(); i++)
- {
- PolygonGeometry<AMesh> pg(mesh,i);
- aLeaves[i] = BBoxLeaf(i,CSG_Math<PolygonGeometry<AMesh> >::FitBBox(pg) );
- }
-
- tree.BuildTree(aLeaves,numLeaves);
-}
-
-
- void
-ExtractClassificationPreserve(
- const AMesh& meshA,
- const AMesh& meshB,
- const BBoxTree& aTree,
- const BBoxTree& bTree,
- const OverlapTable& aOverlapsB,
- const OverlapTable& bOverlapsA,
- int aClassification,
- int bClassification,
- bool reverseA,
- bool reverseB,
- AMesh& output
-){
-
- // Now we need to make a copy of each mesh and then partition each of those
- // copies with respect to the original meshes.
- AConnectedMesh meshAPartitioned;
- AConnectedMesh meshBPartitioned;
-
- MeshCopier<AMesh,AConnectedMesh>::Copy(meshA,meshAPartitioned);
- MeshCopier<AMesh,AConnectedMesh>::Copy(meshB,meshBPartitioned);
-
- AConnectedMeshWrapper meshAWrapper(meshAPartitioned);
- AConnectedMeshWrapper meshBWrapper(meshBPartitioned);
-
- meshAWrapper.BuildVertexPolyLists();
- meshBWrapper.BuildVertexPolyLists();
- // Partition meshA wrt to meshB
- BooleanOp<AConnectedMeshWrapper,AMesh>::PartitionMesh(meshAWrapper,meshB,bOverlapsA);
- // and now meshB wrt meshA
- BooleanOp<AConnectedMeshWrapper,AMesh>::PartitionMesh(meshBWrapper,meshA,aOverlapsB);
-
- // Classify the partioned meshes wrt to the originals.
- BooleanOp<AConnectedMesh,AMesh>::ClassifyMesh(meshB,bTree,meshAPartitioned);
- BooleanOp<AConnectedMesh,AMesh>::ClassifyMesh(meshA,aTree,meshBPartitioned);
-
- // Extract the classification we want from both meshes
- BooleanOp<AConnectedMesh,AMesh>::ExtractClassification(meshAPartitioned, output,aClassification,reverseA);
- BooleanOp<AConnectedMesh,AMesh>::ExtractClassification(meshBPartitioned, output,bClassification,reverseB);
-}
-
- void
-ExtractClassification(
- const AMesh& meshA,
- const AMesh& meshB,
- const BBoxTree& aTree,
- const BBoxTree& bTree,
- const OverlapTable& aOverlapsB,
- const OverlapTable& bOverlapsA,
- int aClassification,
- int bClassification,
- bool reverseA,
- bool reverseB,
- AMesh& output
-){
- // Now we need to make a copy of each mesh and then partition each of those
- // copies with respect to the original meshes.
- AMesh meshAPartitioned(meshA);
- AMesh meshBPartitioned(meshB);
-
- AMeshWrapper meshAWrapper(meshAPartitioned);
- AMeshWrapper meshBWrapper(meshBPartitioned);
-
- // Partition meshA wrt to meshB
- BooleanOp<AMeshWrapper,AMesh>::PartitionMesh(meshAWrapper,meshB,bOverlapsA);
- // and now meshB wrt meshA
- BooleanOp<AMeshWrapper,AMesh>::PartitionMesh(meshBWrapper,meshA,aOverlapsB);
-
- // Classify the partioned meshes wrt to the originals.
- BooleanOp<AMesh,AMesh>::ClassifyMesh(meshB,bTree,meshAPartitioned);
- BooleanOp<AMesh,AMesh>::ClassifyMesh(meshA,aTree,meshBPartitioned);
-
- // Extract the classification we want from both meshes
- BooleanOp<AMesh,AMesh>::ExtractClassification(meshAPartitioned, output,aClassification,reverseA);
- BooleanOp<AMesh,AMesh>::ExtractClassification(meshBPartitioned, output,bClassification,reverseB);
-}
-
- AMesh *
-CsgOp::
-Intersect(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
-){
- // assumes they occups the same space and their planes have
- // been computed.
-
- // First thing is to build a BBoxTree for each mesh.
- BBoxTree aTree,bTree;
- BuildTree(meshA,aTree);
- BuildTree(meshB,bTree);
-
- // Build the overlap tables - they tell us which polygons from
- // meshA overlap with those of meshB and vice versa
- OverlapTable bOverlapsA(meshA.Polys().size());
- OverlapTable aOverlapsB(meshB.Polys().size());
-
- BooleanOp<AMesh,AMesh>::BuildSplitGroup(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA);
-
- // Create a new mesh for the output
- MEM_SmartPtr<AMesh> output = new AMesh;
- if (output == NULL) return NULL;
-
- if (preserve)
- {
- ExtractClassificationPreserve(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,1,1,false,false,output.Ref());
- } else {
- ExtractClassification(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,1,1,false,false,output.Ref());
- }
-
-#if 1
- // Triangulate the result
- AMeshWrapper outputWrapper(output.Ref());
- outputWrapper.Triangulate();
-#endif
- return output.Release();
-}
-
-
- AMesh *
-CsgOp::
-Union(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
-){
- // assumes they occups the same space and their planes have
- // been computed.
-
- // First thing is to build a BBoxTree for each mesh.
- BBoxTree aTree,bTree;
- BuildTree(meshA,aTree);
- BuildTree(meshB,bTree);
-
- // Build the overlap tables - they tell us which polygons from
- // meshA overlap with those of meshB and vice versa
- OverlapTable bOverlapsA(meshA.Polys().size());
- OverlapTable aOverlapsB(meshB.Polys().size());
-
- BooleanOp<AMesh,AMesh>::BuildSplitGroup(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA);
-
- // Create a new mesh for the output
- MEM_SmartPtr<AMesh> output = new AMesh;
- if (output == NULL) return NULL;
-
- if (preserve)
- {
- ExtractClassificationPreserve(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,2,2,false,false,output.Ref());
- } else {
- ExtractClassification(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,2,2,false,false,output.Ref());
- }
-
-#if 1
- // Triangulate the result
- AMeshWrapper outputWrapper(output.Ref());
- outputWrapper.Triangulate();
-#endif
- return output.Release();
-}
-
- AMesh *
-CsgOp::
-Difference(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
-){
-
- // assumes they occups the same space and their planes have
- // been computed.
-
- // First thing is to build a BBoxTree for each mesh.
- BBoxTree aTree,bTree;
- BuildTree(meshA,aTree);
- BuildTree(meshB,bTree);
-
- // Build the overlap tables - they tell us which polygons from
- // meshA overlap with those of meshB and vice versa
- OverlapTable bOverlapsA(meshA.Polys().size());
- OverlapTable aOverlapsB(meshB.Polys().size());
-
- BooleanOp<AMesh,AMesh>::BuildSplitGroup(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA);
-
- // Create a new mesh for the output
- MEM_SmartPtr<AMesh> output = new AMesh;
- if (output == NULL) return NULL;
-
- if (preserve)
- {
- ExtractClassificationPreserve(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,2,1,false,true,output.Ref());
- } else {
- ExtractClassification(meshA,meshB,aTree,bTree,aOverlapsB,bOverlapsA,2,1,false,true,output.Ref());
- }
-
-#if 1
- // Triangulate the result
- AMeshWrapper outputWrapper(output.Ref());
- outputWrapper.Triangulate();
-#endif
- return output.Release();
-}
-
-
diff --git a/intern/csg/intern/blender/CSG_CsgOp.h b/intern/csg/intern/blender/CSG_CsgOp.h
deleted file mode 100644
index 3b0e8b33766..00000000000
--- a/intern/csg/intern/blender/CSG_CsgOp.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef CSG_CsgOp_h
-#define CSG_CsgOp_h
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_BlenderMesh.h"
-
-
-class CsgOp
-{
-public :
-
- static
- AMesh *
- Intersect(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
- );
-
- static
- AMesh *
- Union(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
- );
-
- static
- AMesh *
- Difference(
- const AMesh& meshA,
- const AMesh& meshB,
- bool preserve
- );
-
-
-};
-
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_IndexDefs.h b/intern/csg/intern/blender/CSG_IndexDefs.h
deleted file mode 100644
index f385537d0ac..00000000000
--- a/intern/csg/intern/blender/CSG_IndexDefs.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef CSG_INDEXDEFS_H
-#define CSG_INDEXDEFS_H
-
-//typdefs for lists and things in the CSG library
-
-#include <vector>
-
-typedef std::vector<int> PIndexList;
-typedef PIndexList::iterator PIndexIt;
-typedef PIndexList::const_iterator const_PIndexIt;
-
-typedef std::vector<int> VIndexList;
-typedef VIndexList::iterator VIndexIt;
-typedef VIndexList::const_iterator const_VIndexIt;
-
-typedef std::vector< PIndexList > OverlapTable;
-
-
-
-#endif
-
-
diff --git a/intern/csg/intern/blender/CSG_Interface.cpp b/intern/csg/intern/blender/CSG_Interface.cpp
deleted file mode 100644
index 8b6415f1b3a..00000000000
--- a/intern/csg/intern/blender/CSG_Interface.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-/**
- * Implementation of external C api for CSG lib .
- */
-#pragma warning( disable : 4786 )
-
-#include "CSG_Interface.h"
-#include "CSG_Iterator.h"
-#include "CSG_BlenderMesh.h"
-#include "CSG_MeshBuilder.h"
-#include "CSG_CsgOp.h"
-
-#include "MEM_SmartPtr.h"
-
-struct CSG_MeshInfo {
- MEM_SmartPtr<AMesh> output_mesh;
-};
-
- CSG_BooleanOperation *
-CSG_NewBooleanFunction(
- void
-){
- CSG_MeshInfo * mesh_info = new CSG_MeshInfo;
- CSG_BooleanOperation * output = new CSG_BooleanOperation;
-
- if (mesh_info==NULL || output==NULL) return NULL;
-
- mesh_info->output_mesh = NULL;
- output->CSG_info = mesh_info;
-
- return output;
-}
-
- int
-CSG_PerformBooleanOperation(
- CSG_BooleanOperation * operation,
- CSG_OperationType op_type,
- CSG_FaceIteratorDescriptor obAFaces,
- CSG_VertexIteratorDescriptor obAVertices,
- CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interp_func
-){
-
- if (operation == NULL) return 0;
-
- CSG_MeshInfo * mesh_info = static_cast<CSG_MeshInfo *>(operation->CSG_info);
- if (mesh_info == NULL) return 0;
-
- obAFaces.Reset(obAFaces.it);
- obBFaces.Reset(obBFaces.it);
- obAVertices.Reset(obAVertices.it);
- obBVertices.Reset(obBVertices.it);
-
- MEM_SmartPtr<AMesh> outputMesh;
-
- try {
- // Build the individual meshes
- // set the face data size
- BlenderVProp::InterpFunc = interp_func;
-
- MEM_SmartPtr<AMesh> obA = MeshBuilder::NewMesh(obAFaces,obAVertices);
-
- MEM_SmartPtr<AMesh> obB = MeshBuilder::NewMesh(obBFaces,obBVertices);
-
- if (
- obA == NULL ||
- obB == NULL
- ) {
- return 0;
- }
-
- // build normals
- AMeshWrapper aMeshWrap(obA.Ref()), bMeshWrap(obB.Ref());
- aMeshWrap.ComputePlanes();
- bMeshWrap.ComputePlanes();
-
- // translate enums!
-
- switch(op_type) {
- case e_csg_union :
- case e_csg_classify :
- outputMesh = CsgOp::Union(obA.Ref(),obB.Ref(),true);
- break;
- case e_csg_intersection :
- outputMesh = CsgOp::Intersect(obA.Ref(),obB.Ref(),true);
- break;
- case e_csg_difference :
- outputMesh = CsgOp::Difference(obA.Ref(),obB.Ref(),true);
- break;
- default :
- return 0;
- }
- }
- catch(...) {
- return 0;
- }
-
- // set the output mesh
- mesh_info->output_mesh = outputMesh;
-
- return 1;
-}
-
- int
-CSG_OutputFaceDescriptor(
- CSG_BooleanOperation * operation,
- CSG_FaceIteratorDescriptor * output
-){
- if (operation == NULL) return 0;
- CSG_MeshInfo * mesh_info = static_cast<CSG_MeshInfo *>(operation->CSG_info);
-
- if (mesh_info == NULL) return 0;
- if (mesh_info->output_mesh == NULL) return 0;
-
- AMesh_FaceIt_Construct(mesh_info->output_mesh,output);
- return 1;
-}
-
-
- int
-CSG_OutputVertexDescriptor(
- CSG_BooleanOperation * operation,
- CSG_VertexIteratorDescriptor *output
-){
- if (operation == NULL) return 0;
- CSG_MeshInfo * mesh_info = static_cast<CSG_MeshInfo *>(operation->CSG_info);
-
- if (mesh_info == NULL) return 0;
- if (mesh_info->output_mesh == NULL) return 0;
-
- AMesh_VertexIt_Construct(mesh_info->output_mesh,output);
- return 1;
-}
-
- void
-CSG_FreeVertexDescriptor(
- CSG_VertexIteratorDescriptor * v_descriptor
-){
- AMesh_VertexIt_Destruct(v_descriptor);
-}
-
-
- void
-CSG_FreeFaceDescriptor(
- CSG_FaceIteratorDescriptor * f_descriptor
-){
- AMesh_FaceIt_Destruct(f_descriptor);
-}
-
-
- void
-CSG_FreeBooleanOperation(
- CSG_BooleanOperation *operation
-){
- if (operation != NULL) {
- CSG_MeshInfo * mesh_info = static_cast<CSG_MeshInfo *>(operation->CSG_info);
- delete(mesh_info);
- delete(operation);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/csg/intern/blender/CSG_Iterator.h b/intern/csg/intern/blender/CSG_Iterator.h
deleted file mode 100644
index e349229be9e..00000000000
--- a/intern/csg/intern/blender/CSG_Iterator.h
+++ /dev/null
@@ -1,199 +0,0 @@
-
-#ifndef CSG_Iterator_H
-#define CSG_Iterator_H
-
-#include "CSG_BlenderMesh.h"
-#include "CSG_Interface.h"
-
-#include "MEM_SmartPtr.h"
-/**
- * This class defines 2 C style iterators over a CSG mesh, one for
- * vertices and 1 for faces. They conform to the iterator interface
- * defined in CSG_BooleanOps.h
- */
-
-struct AMesh_VertexIt {
- AMesh* mesh;
- AMesh::VLIST::const_iterator pos;
-};
-
-
-static
- void
-AMesh_VertexIt_Destruct(
- CSG_VertexIteratorDescriptor * vIterator
-) {
- delete ((AMesh_VertexIt *)(vIterator->it));
- vIterator->it = NULL;
- vIterator->Done = NULL;
- vIterator->Fill = NULL;
- vIterator->Reset = NULL;
- vIterator->Step = NULL;
- vIterator->num_elements = 0;
-};
-
-
-static
- int
-AMesh_VertexIt_Done(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_VertexIt * vertex_it = (AMesh_VertexIt *)it;
-
- if (vertex_it->pos < vertex_it->mesh->Verts().end() ) return 0;
- return 1;
-};
-
-static
- void
-AMesh_VertexIt_Fill(
- CSG_IteratorPtr it,
- CSG_IVertex *vert
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_VertexIt * vertex_it = (AMesh_VertexIt *)it;
-
- vertex_it->pos->Pos().getValue(vert->position);
-};
-
-static
- void
-AMesh_VertexIt_Step(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_VertexIt * vertex_it = (AMesh_VertexIt *)it;
-
- ++(vertex_it->pos);
-};
-
-static
- void
-AMesh_VertexIt_Reset(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_VertexIt * vertex_it = (AMesh_VertexIt *)it;
- vertex_it->pos = vertex_it->mesh->Verts().begin();
-};
-
-static
- void
-AMesh_VertexIt_Construct(
- AMesh *mesh,
- CSG_VertexIteratorDescriptor *output
-){
- // user should have insured mesh is not equal to NULL.
-
- output->Done = AMesh_VertexIt_Done;
- output->Fill = AMesh_VertexIt_Fill;
- output->Step = AMesh_VertexIt_Step;
- output->Reset = AMesh_VertexIt_Reset;
- output->num_elements = mesh->Verts().size();
-
- AMesh_VertexIt * v_it = new AMesh_VertexIt;
- v_it->mesh = mesh;
- v_it->pos = mesh->Verts().begin();
- output->it = v_it;
-};
-
-
-/**
- * Face iterator.
- */
-
-struct AMesh_FaceIt {
- AMesh* mesh;
- AMesh::PLIST::const_iterator pos;
-};
-
-
-static
- void
-AMesh_FaceIt_Destruct(
- CSG_FaceIteratorDescriptor *fIterator
-) {
- delete ((AMesh_FaceIt *)(fIterator->it));
- fIterator->it = NULL;
- fIterator->Done = NULL;
- fIterator->Fill = NULL;
- fIterator->Reset = NULL;
- fIterator->Step = NULL;
- fIterator->num_elements = 0;
-};
-
-
-static
- int
-AMesh_FaceIt_Done(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_FaceIt * face_it = (AMesh_FaceIt *)it;
-
- return face_it->pos >= face_it->mesh->Polys().end();
-};
-
-static
- void
-AMesh_FaceIt_Fill(
- CSG_IteratorPtr it,
- CSG_IFace *face
-){
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_FaceIt * face_it = (AMesh_FaceIt *)it;
-
- face->m_vertexData[0] = face_it->pos->VertexProps(0).Data();
- face->m_vertexData[1] = face_it->pos->VertexProps(1).Data();
- face->m_vertexData[2] = face_it->pos->VertexProps(2).Data();
-
- face->m_vertexNumber =3;
- face->m_faceData = face_it->pos->FProp();
-};
-
-static
- void
-AMesh_FaceIt_Step(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_FaceIt * face_it = (AMesh_FaceIt *)it;
- face_it->pos++;
-};
-
-static
- void
-AMesh_FaceIt_Reset(
- CSG_IteratorPtr it
-) {
- // assume CSG_IteratorPtr is of the correct type.
- AMesh_FaceIt * f_it = (AMesh_FaceIt *)it;
- f_it->pos = f_it->mesh->Polys().begin();
-};
-
-static
- void
-AMesh_FaceIt_Construct(
- AMesh * mesh,
- CSG_FaceIteratorDescriptor *output
-) {
-
- output->Done = AMesh_FaceIt_Done;
- output->Fill = AMesh_FaceIt_Fill;
- output->Step = AMesh_FaceIt_Step;
- output->Reset = AMesh_FaceIt_Reset;
-
- output->num_elements = mesh->Polys().size();
-
- AMesh_FaceIt * f_it = new AMesh_FaceIt;
- f_it->mesh = mesh;
- f_it->pos = mesh->Polys().begin();
-
- output->it = f_it;
-
-};
-
-
-#endif
-
diff --git a/intern/csg/intern/blender/CSG_MeshBuilder.h b/intern/csg/intern/blender/CSG_MeshBuilder.h
deleted file mode 100644
index 5d65acdab50..00000000000
--- a/intern/csg/intern/blender/CSG_MeshBuilder.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef CSG_MeshBuilder_H
-#define CSG_MeshBuilder_H
-/*
- CSGLib - Software Library for Constructive Solid Geometry
- Copyright (C) 2003-2004 Laurence Bourn
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Please send remarks, questions and bug reports to laurencebourn@hotmail.com
-*/
-
-#include "CSG_IndexDefs.h"
-#include "CSG_Vertex.h"
-#include "CSG_Polygon.h"
-#include "CSG_Interface.h"
-#include "CSG_BlenderMesh.h"
-
-// build a mesh from external c interface to this module
-////////////////////////////////////////////////////////
-
-class MeshBuilder
-{
-
-public :
-
- // You must have set the size of the SimpleProps data ptr size
- // before calling this function.
-
- static AMesh* NewMesh(
- CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices
- ) {
-
- AMesh *output = new AMesh();
-
- // first get the vertices.
- AMesh::VLIST& verts = output->Verts();
-
- verts.reserve(obBVertices.num_elements);
-
- obBVertices.Reset(obBFaces.it);
-
- CSG_IVertex iVert;
-
- while (!obBVertices.Done(obBVertices.it))
- {
- obBVertices.Fill(obBVertices.it,&iVert);
-
- AMesh::Vertex aVertex;
- aVertex.Pos().setValue(iVert.position);
- verts.push_back(aVertex);
-
- obBVertices.Step(obBVertices.it);
- }
-
- // now for the faces
- ////////////////////
-
- AMesh::PLIST &faces = output->Polys();
- faces.reserve(obBFaces.num_elements);
-
- CSG_IFace iFace;
-
- while (!obBFaces.Done(obBFaces.it))
- {
- obBFaces.Fill(obBFaces.it,&iFace);
-
- AMesh::Polygon aPolygon;
- aPolygon.FProp() = iFace.m_faceData;
-
- int i;
- for (i=0;i < 3; i++)
- {
- AMesh::Polygon::TVProp vProp;
- vProp.Data() = iFace.m_vertexData[i];
- aPolygon.Verts().push_back(vProp);
- }
- faces.push_back(aPolygon);
-
- if (iFace.m_vertexNumber == 4)
- {
- AMesh::Polygon::TVProp vProp[3];
- vProp[0].Data() = iFace.m_vertexData[2];
- vProp[1].Data() = iFace.m_vertexData[3];
- vProp[2].Data() = iFace.m_vertexData[0];
-
- aPolygon.VertexProps(0) = vProp[0];
- aPolygon.VertexProps(1) = vProp[1];
- aPolygon.VertexProps(2) = vProp[2];
-
- faces.push_back(aPolygon);
- }
-
- obBFaces.Step(obBFaces.it);
- }
-
- return output;
- }
-};
-
-
-#endif
-
-
-
-
-
-
-
-
- \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_PropArray.h b/intern/csg/intern/blender/CSG_PropArray.h
deleted file mode 100644
index 7e28a2a417e..00000000000
--- a/intern/csg/intern/blender/CSG_PropArray.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef CSG_IndexProp_H
-#define CSG_IndexProp_H
-
-#include <vector>
-#include <memory.h>
-// Face and vertex props that are contained in a seperate array
-// (PropArray) and indexed through a VProp compliant thing.
-
-typedef int (*CSG_InterpFunc)(const void *d1, const void * d2, void *dnew, float epsilon);
-
-class IndexProp
-{
-private :
-
- int m_vIndex;
- int m_size;
- unsigned char *m_data;
- mutable CSG_InterpFunc m_interpFunc;
-
-public :
-
- IndexProp(const int& vIndex)
- : m_vIndex(vIndex),
- m_size(0),
- m_data(0)
- {};
-
- IndexProp(
- const int& vIndex,
- const IndexProp& p1,
- const IndexProp& p2,
- const MT_Scalar& epsilon
- ):
- m_vIndex(vIndex),
- m_data(0)
- {
- SetInterpFunc(p1.m_interpFunc);
- SetSize(p1.m_size);
- m_interpFunc(p1.m_data,p2.m_data,m_data,(float)epsilon);
- }
-
- IndexProp(const IndexProp& other)
- : m_vIndex(other.m_vIndex),
- m_data(0),
- m_interpFunc(other.m_interpFunc)
- {
- SetInterpFunc(other.m_interpFunc);
- SetSize(other.m_size);
- memcpy(m_data,other.m_data,m_size);
- }
-
- IndexProp(
- ): m_vIndex(-1),
- m_size(0),
- m_data(0)
- {};
-
- // Support conversion to an integer
- ///////////////////////////////////
- operator int(
- ) const {
- return m_vIndex;
- }
-
- // and assignment from an integer.
- //////////////////////////////////
- IndexProp&
- operator = (
- int i
- ) {
- m_vIndex = i;
- return *this;
- }
-
- IndexProp&
- operator = (
- const IndexProp& other
- ) {
- m_vIndex = other.m_vIndex;
- m_data = 0;
- SetSize(other.m_size);
- SetInterpFunc(other.m_interpFunc);
- memcpy(m_data,other.m_data,m_size);
- return *this;
- }
-
- // Our local functions
- //////////////////////
-
- void SetInterpFunc(CSG_InterpFunc interpFunc)
- {
- m_interpFunc = interpFunc;
- }
-
- void SetSize(int size)
- {
- delete[] m_data;
- m_data = new unsigned char[size];
- m_size = size;
- }
-
- int Size() const {
- return m_size;
- }
-
- void CopyData(const void * userData)
- {
- memcpy(m_data,userData,m_size);
- }
-
- void Create(int size, const void * userData, CSG_InterpFunc interpFunc)
- {
- SetInterpFunc(interpFunc);
- SetSize(size);
- CopyData(userData);
- }
-
- const unsigned char * GetData() const { return m_data;}
-
- ~IndexProp() {
- delete[] m_data;
- };
-};
-
-
-#endif \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_SimpleProp.cpp b/intern/csg/intern/blender/CSG_SimpleProp.cpp
deleted file mode 100644
index 2c8f0eedae9..00000000000
--- a/intern/csg/intern/blender/CSG_SimpleProp.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "CSG_SimpleProp.h"
-
-
-int SimpleProp::s_size = 4; \ No newline at end of file
diff --git a/intern/csg/intern/blender/CSG_SimpleProp.h b/intern/csg/intern/blender/CSG_SimpleProp.h
deleted file mode 100644
index dc8ab45c6d8..00000000000
--- a/intern/csg/intern/blender/CSG_SimpleProp.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef CSG_SIMPLEPROP_H
-#define CSG_SIMPLEPROP_H
-
-// Simple face prop contains a fixed size piece of memory
-// initiated by the client and copied round through this
-// value type by the CSG library.
-#include <memory.h>
-
-class SimpleProp
-{
-private :
-
- static int s_size;
- unsigned char * m_data;
-
-public :
-
- static void SetSize(int size) {
- s_size = size;
- }
-
- static int Size() {
- return s_size;
- }
-
- SimpleProp()
- : m_data(new unsigned char[s_size])
- {}
-
- SimpleProp(const SimpleProp& other)
- : m_data(new unsigned char[s_size])
- {
- memcpy(m_data,other.m_data,s_size);
- }
-
- SimpleProp& operator = (const SimpleProp& other)
- {
- memcpy(m_data,other.m_data,s_size);
- return *this;
- }
-
- void SetData(const void * data)
- {
- memcpy(m_data,data,s_size);
- }
-
- const unsigned char * Data() const {
- return m_data;
- }
-
-
- ~SimpleProp()
- {
- delete[] m_data;
- }
-};
-
-#endif \ No newline at end of file
diff --git a/intern/csg/make/msvc60/csg.dsp b/intern/csg/make/msvc60/csg.dsp
deleted file mode 100644
index ae67f505bc3..00000000000
--- a/intern/csg/make/msvc60/csg.dsp
+++ /dev/null
@@ -1,234 +0,0 @@
-# Microsoft Developer Studio Project File - Name="csg" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=csg - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "csg.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "csg.mak" CFG="csg - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "csg - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "csg - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "csg - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\bsp\"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\bsp\"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /G6 /MT /W3 /GX /I "../../intern/blender" /I "../../extern" /I "../../intern" /I "../../../../../lib/windows/memutil/include" /I "../.." /I "../../../../../lib/windows/moto/include" /I"..\..\..\moto\include" /I"..\..\..\memutil" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
-# ADD BASE RSC /l 0x413 /d "NDEBUG"
-# ADD RSC /l 0x413 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\bsp\libbsp.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /E /Y ..\..\extern\*.h ..\..\..\..\..\lib\windows\bsp\include\ ECHO Copying lib XCOPY /E /Y ..\..\..\..\obj\windows\intern\bsp\*.lib ..\..\..\..\lib\windows\bsp\lib\*.a ECHO Done
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "csg - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\bsp\debug\"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\bsp\debug\"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../intern/blender" /I "../../extern" /I "../../intern" /I "../../../../../lib/windows/memutil/include" /I "../.." /I "../../../../../lib/windows/moto/include" /I"..\..\..\moto\include" /I"..\..\..\memutil" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c
-# ADD BASE RSC /l 0x413 /d "_DEBUG"
-# ADD RSC /l 0x413 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\bsp\debug\libbsp.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /E /Y ..\..\extern\*.h ..\..\..\..\..\lib\windows\bsp\include\ ECHO Copying lib XCOPY /E /Y ..\..\..\..\obj\windows\intern\bsp\debug\*.lib ..\..\..\..\..\lib\windows\bsp\lib\debug\*.a ECHO Copying Debug info. XCOPY /E /Y ..\..\..\..\obj\windows\intern\bsp\debug\vc60.* ..\..\..\..\..\lib\windows\bsp\lib\debug\ ECHO Done
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "csg - Win32 Release"
-# Name "csg - Win32 Debug"
-# Begin Group "AABBTree"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BBox.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BBoxTree.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BBoxTree.h
-# End Source File
-# End Group
-# Begin Group "inlines"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_ConnectedMeshWrapper.inl
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Math.inl
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Triangulate.inl
-# End Source File
-# End Group
-# Begin Group "blender"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_BlenderMesh.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_BlenderVProp.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BlenderVProp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_CsgOp.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_CsgOp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_Interface.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\extern\CSG_Interface.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\blender\CSG_MeshBuilder.h
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BooleanOp.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_BooleanOp.inl
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_ConnectedMesh.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_CVertex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_GeometryBinder.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_IndexDefs.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Math.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Mesh.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_MeshCopier.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_MeshWrapper.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_MeshWrapper.inl
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Polygon.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_SplitFunction.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_TreeQueries.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Triangulate.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\CSG_Vertex.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\MT_Line3.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\MT_Line3.h
-# End Source File
-# End Target
-# End Project
diff --git a/intern/csg/make/msvc60/csg.dsw b/intern/csg/make/msvc60/csg.dsw
deleted file mode 100644
index 7f9bd29b97a..00000000000
--- a/intern/csg/make/msvc60/csg.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "csg"=.\csg.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/elbeem/CMakeLists.txt b/intern/elbeem/CMakeLists.txt
index 86a60180b05..48d25901499 100644
--- a/intern/elbeem/CMakeLists.txt
+++ b/intern/elbeem/CMakeLists.txt
@@ -36,5 +36,9 @@ IF(WINDOWS)
ADD_DEFINITIONS(-DUSE_MSVC6FIXES)
ENDIF(WINDOWS)
+IF(WITH_OPENMP)
+ ADD_DEFINITIONS(-DPARALLEL=1)
+ENDIF(WITH_OPENMP)
+
BLENDERLIB_NOLIST(bf_elbeem "${SRC}" "${INC}")
#, libtype='blender', priority=0 )
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index bb6637ba32d..bdcb0507987 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -5,7 +5,11 @@ Import('env')
sources = env.Glob('intern/*.cpp')
-defs = 'NOGUI ELBEEM_BLENDER=1'
+defs = ' NOGUI ELBEEM_BLENDER=1'
+
+if env['WITH_BF_OPENMP'] == 1:
+ defs += ' PARALLEL'
+
if env['OURPLATFORM']=='win32-vc':
defs += ' USE_MSVC6FIXES'
incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC'] + ' ' +env['BF_SDL_INC']
diff --git a/intern/elbeem/extern/elbeem.h b/intern/elbeem/extern/elbeem.h
index b3feda8bbe8..2a594dd07e6 100644
--- a/intern/elbeem/extern/elbeem.h
+++ b/intern/elbeem/extern/elbeem.h
@@ -154,7 +154,7 @@ typedef struct elbeemMesh {
short volumeInitType;
/* name of the mesh, mostly for debugging */
- char *name;
+ const char *name;
} elbeemMesh;
// API functions
diff --git a/intern/elbeem/intern/attributes.cpp b/intern/elbeem/intern/attributes.cpp
index 890d6e75c9e..464486f2500 100644
--- a/intern/elbeem/intern/attributes.cpp
+++ b/intern/elbeem/intern/attributes.cpp
@@ -103,6 +103,7 @@ void AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string sou
// set that a parameter can be given, and will be ignored...
bool AttributeList::ignoreParameter(string name, string source) {
+ name = source = ("");
return false;
}
diff --git a/intern/elbeem/intern/elbeem.h b/intern/elbeem/intern/elbeem.h
index b3feda8bbe8..2a594dd07e6 100644
--- a/intern/elbeem/intern/elbeem.h
+++ b/intern/elbeem/intern/elbeem.h
@@ -154,7 +154,7 @@ typedef struct elbeemMesh {
short volumeInitType;
/* name of the mesh, mostly for debugging */
- char *name;
+ const char *name;
} elbeemMesh;
// API functions
diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp
index 9646e8581da..1b0ba13c707 100644
--- a/intern/elbeem/intern/isosurface.cpp
+++ b/intern/elbeem/intern/isosurface.cpp
@@ -13,8 +13,7 @@
#include <algorithm>
#include <stdio.h>
-// sirdude fix for solaris
-#if !defined(linux) && (defined (__sparc) || defined (__sparc__))
+#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
#include <ieeefp.h>
#endif
diff --git a/intern/elbeem/intern/loop_tools.h b/intern/elbeem/intern/loop_tools.h
index 3c15a609210..70ecb9ce3e0 100644
--- a/intern/elbeem/intern/loop_tools.h
+++ b/intern/elbeem/intern/loop_tools.h
@@ -54,15 +54,84 @@
-#define unused_GRID_REGION_END() \
- } /* main_region */ \
- // end unusedGRID_REGION_END
-
// -----------------------------------------------------------------------------------
#else // PARALLEL==1
-#include "paraloop.h"
+//#include "paraloop.h"
+#define PERFORM_USQRMAXCHECK USQRMAXCHECK(usqr,ux,uy,uz, calcMaxVlen, calcMxvx,calcMxvy,calcMxvz);
+#define LIST_EMPTY(x) calcListEmpty.push_back( x );
+#define LIST_FULL(x) calcListFull.push_back( x );
+#define FSGR_ADDPART(x) calcListParts.push_back( x );
+
+
+// parallel region
+//was: # pragma omp parallel default(shared)
+#if COMPRESSGRIDS!=1
+ // requires compressed grids...!
+ ERROR!
+#endif
+
+// loop start
+#define GRID_REGION_START() \
+ { \
+ \
+ \
+ if(mSizez<2) { \
+ mPanic = 1; \
+ errFatal("ParaLoop::2D","Not valid...!", SIMWORLD_GENERICERROR); \
+ } \
+ \
+ \
+ vector<LbmPoint> calcListFull; \
+ vector<LbmPoint> calcListEmpty; \
+ vector<ParticleObject> calcListParts; \
+ LbmFloat calcMxvx, calcMxvy, calcMxvz, calcMaxVlen; \
+ calcMxvx = calcMxvy = calcMxvz = calcMaxVlen = 0.0; \
+ calcListEmpty.reserve(mListEmpty.capacity() / omp_get_num_threads() ); \
+ calcListFull.reserve( mListFull.capacity() / omp_get_num_threads() ); \
+ calcListParts.reserve(mSizex); \
+ \
+ \
+ const int id = omp_get_thread_num(); \
+ const int Nthrds = omp_get_num_threads(); \
+ \
+ \
+ \
+ \
+ \
+ int kdir = 1; \
+ \
+ int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine); \
+ if(gridLoopBound>0){ kstart=getForZMin1(); kend=getForZMax1(mMaxRefine); } \
+ LbmFloat *ccel = NULL, *tcel = NULL; \
+ CellFlagType *pFlagSrc=NULL, *pFlagDst=NULL; \
+ \
+ \
+ if(mLevel[mMaxRefine].setCurr==1) { \
+ kdir = -1; \
+ int temp = kend; \
+ kend = kstart-1; \
+ kstart = temp-1; \
+ } \
+ \
+ const int Nj = mLevel[mMaxRefine].lSizey; \
+ int jstart = 0+( id * (Nj / Nthrds) ); \
+ int jend = 0+( (id+1) * (Nj / Nthrds) ); \
+ if( ((Nj/Nthrds) *Nthrds) != Nj) { \
+ errMsg("LbmFsgrSolver","Invalid domain size Nj="<<Nj<<" Nthrds="<<Nthrds); \
+ } \
+ \
+ if(jstart<gridLoopBound) jstart = gridLoopBound; \
+ if(jend>mLevel[mMaxRefine].lSizey-gridLoopBound) jend = mLevel[mMaxRefine].lSizey-gridLoopBound; \
+ \
+ debMsgStd("ParaLoop::OMP",DM_MSG,"Thread:"<<id<<" i:"<<istart<<"-"<<iend<<" j:"<<jstart<<"-"<<jend<<", k:"<<kstart<<"-"<<kend<<" ", 1); \
+ \
+
+
+
+
+// para GRID LOOP END is parainc3
#endif // PARALLEL==1
@@ -101,9 +170,11 @@
+
// old loop for COMPRESSGRIDS==0
#define old__GRID_LOOP_START() \
for(int k=kstart;k<kend;++k) { \
for(int j=1;j<mLevel[lev].lSizey-1;++j) { \
for(int i=0;i<mLevel[lev].lSizex-2; ) {
+
diff --git a/intern/elbeem/intern/ntl_geometryobject.cpp b/intern/elbeem/intern/ntl_geometryobject.cpp
index bc004b656f5..f2ebd572682 100644
--- a/intern/elbeem/intern/ntl_geometryobject.cpp
+++ b/intern/elbeem/intern/ntl_geometryobject.cpp
@@ -83,7 +83,7 @@ bool ntlGeometryObject::checkIsAnimated() {
/* Init attributes etc. of this object */
/*****************************************************************************/
#define GEOINIT_STRINGS 9
-static char *initStringStrs[GEOINIT_STRINGS] = {
+static const char *initStringStrs[GEOINIT_STRINGS] = {
"fluid",
"bnd_no","bnd_noslip",
"bnd_free","bnd_freeslip",
diff --git a/intern/elbeem/intern/ntl_vector3dim.h b/intern/elbeem/intern/ntl_vector3dim.h
index d6a7557f69d..27c3be0d71f 100644
--- a/intern/elbeem/intern/ntl_vector3dim.h
+++ b/intern/elbeem/intern/ntl_vector3dim.h
@@ -22,6 +22,7 @@
#include <math.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
// hack for MSVC6.0 compiler
#ifdef _MSC_VER
@@ -202,7 +203,7 @@ private:
//! global string for formatting vector output in utilities.cpp
-extern char *globVecFormatStr;
+extern const char *globVecFormatStr;
/*************************************************************************
Outputs the object in human readable form using the format
diff --git a/intern/elbeem/intern/paraloopend.h b/intern/elbeem/intern/paraloopend.h
new file mode 100644
index 00000000000..6bb224b625a
--- /dev/null
+++ b/intern/elbeem/intern/paraloopend.h
@@ -0,0 +1,42 @@
+
+// same as grid loop_end + barrier
+
+ } // i
+ int i=0; //dummy
+ ADVANCE_POINTERS(2*gridLoopBound);
+ } // j
+
+# if COMPRESSGRIDS==1
+# if PARALLEL==1
+ //frintf(stderr," (id=%d k=%d) ",id,k);
+#pragma omp barrier
+# endif // PARALLEL==1
+# else // COMPRESSGRIDS==1
+ int i=0; //dummy
+ ADVANCE_POINTERS(mLevel[lev].lSizex*2);
+# endif // COMPRESSGRIDS==1
+
+} // all cell loop k,j,i
+
+#pragma omp critical
+{
+ if(doReduce) {
+ // synchronize global vars
+ for(int j=0; j<calcListFull.size() ; j++) mListFull.push_back( calcListFull[j] );
+ for(int j=0; j<calcListEmpty.size(); j++) mListEmpty.push_back( calcListEmpty[j] );
+ for(int j=0; j<calcListParts.size(); j++) mpParticles->addFullParticle( calcListParts[j] );
+ if(calcMaxVlen>mMaxVlen) {
+ mMxvx = calcMxvx;
+ mMxvy = calcMxvy;
+ mMxvz = calcMxvz;
+ mMaxVlen = calcMaxVlen;
+ }
+ if(0) {debMsgStd("OMP_CRIT",DM_MSG, "reduce id"<<id<<" curr: "<<mMaxVlen<<"|"<<mMxvx<<","<<mMxvy<<","<<mMxvz<<
+ " calc[ "<<calcMaxVlen<<"|"<<calcMxvx<<","<<calcMxvy<<","<<calcMxvz<<"] " ,4 ); }
+ }
+} // critical
+
+
+} /* main_region */
+ //?lobOutstrForce = true;
+
diff --git a/intern/elbeem/intern/parametrizer.cpp b/intern/elbeem/intern/parametrizer.cpp
index 0bbdc2ee363..dca0b48d265 100644
--- a/intern/elbeem/intern/parametrizer.cpp
+++ b/intern/elbeem/intern/parametrizer.cpp
@@ -14,7 +14,7 @@
#define DEBUG_PARAMCHANNELS 0
/*! param seen debug string array */
-char *ParamStrings[] = {
+const char *ParamStrings[] = {
"RelaxTime",
"Reynolds",
"Viscosity",
diff --git a/intern/elbeem/intern/particletracer.cpp b/intern/elbeem/intern/particletracer.cpp
index c537a893c27..819fcdd0b9a 100644
--- a/intern/elbeem/intern/particletracer.cpp
+++ b/intern/elbeem/intern/particletracer.cpp
@@ -325,6 +325,7 @@ void ParticleTracer::getTriangles(double time, vector<ntlTriangle> *triangles,
// suppress warnings...
vertices = NULL; triangles = NULL;
normals = NULL; objectId = 0;
+ time = 0.;
#else // ELBEEM_PLUGIN
int pcnt = 0;
// currently not used in blender
diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp
index 19bdb119681..9b47ae696af 100644
--- a/intern/elbeem/intern/simulation_object.cpp
+++ b/intern/elbeem/intern/simulation_object.cpp
@@ -68,6 +68,7 @@ SimulationObject::~SimulationObject()
/*! init tree for certain geometry init */
/*****************************************************************************/
void SimulationObject::initGeoTree() {
+ // unused!! overriden by solver interface
if(mpGlob == NULL) {
errFatal("SimulationObject::initGeoTree error","Requires globals!", SIMWORLD_INITERROR);
return;
@@ -79,7 +80,7 @@ void SimulationObject::initGeoTree() {
char treeFlag = (1<<(mGeoInitId+4));
mpGiTree = new ntlTree( 20, 4, // warning - fixed values for depth & maxtriangles here...
scene, treeFlag );
- exit(1); // unused!? overriden by solver interface
+ // unused!! overriden by solver interface
}
/*****************************************************************************/
@@ -309,7 +310,7 @@ void SimulationObject::step( void )
// dont advance for stopped time
mpLbm->step();
mTime += mpParam->getTimestep();
-//if(mTime>0.001) { errMsg("DEBUG!!!!!!!!","quit mlsu..."); exit(1); } // PROFILE DEBUG TEST!
+ //if(mTime>0.001) { errMsg("DEBUG!!!!!!!!","quit mlsu..."); xit(1); } // PROFILE DEBUG TEST!
}
if(mpLbm->getPanic()) mPanic = true;
diff --git a/intern/elbeem/intern/solver_adap.cpp b/intern/elbeem/intern/solver_adap.cpp
index ef516a578bd..5616d805232 100644
--- a/intern/elbeem/intern/solver_adap.cpp
+++ b/intern/elbeem/intern/solver_adap.cpp
@@ -11,7 +11,9 @@
#include "solver_relax.h"
#include "particletracer.h"
-
+#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
+#include <ieeefp.h>
+#endif
/*****************************************************************************/
//! coarse step functions
diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h
index e6b1ad4ed53..d46f065adfd 100644
--- a/intern/elbeem/intern/solver_class.h
+++ b/intern/elbeem/intern/solver_class.h
@@ -99,10 +99,9 @@
#define LBM_INLINED inline
// sirdude fix for solaris
-#if !defined(linux) && (defined (__sparc) || defined (__sparc__))
-#include <ieeefp.h>
+#if !defined(linux) && defined(sun)
#ifndef expf
-#define expf exp
+#define expf(x) exp((double)(x))
#endif
#endif
diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp
index abec4a89c89..c953d2f47da 100644
--- a/intern/elbeem/intern/solver_init.cpp
+++ b/intern/elbeem/intern/solver_init.cpp
@@ -655,6 +655,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
int orgSz = mSizez;
double sizeReduction = 1.0;
double memEstFromFunc = -1.0;
+ double memEstFine = -1.0;
string memreqStr("");
bool firstMInit = true;
int minitTries=0;
@@ -672,7 +673,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
firstMInit=false;
calculateMemreqEstimate( mSizex, mSizey, mSizez,
- mMaxRefine, mFarFieldSize, &memEstFromFunc, &memreqStr );
+ mMaxRefine, mFarFieldSize, &memEstFromFunc, &memEstFine, &memreqStr );
double memLimit;
string memLimStr("-");
@@ -685,13 +686,36 @@ bool LbmFsgrSolver::initializeSolverMemory()
memLimit = 16.0* 1024.0*1024.0*1024.0;
memLimStr = string("16GB");
}
- if(memEstFromFunc>memLimit) {
+
+ // restrict max. chunk of 1 mem block to 1GB for windos
+ bool memBlockAllocProblem = false;
+ double maxWinMemChunk = 1100.*1024.*1024.;
+ double maxMacMemChunk = 1200.*1024.*1024.;
+ double maxDefaultMemChunk = 2.*1024.*1024.*1024.;
+ //std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG
+#ifdef WIN32
+ if(memEstFine> maxWinMemChunk) {
+ memBlockAllocProblem = true;
+ }
+#endif // WIN32
+#ifdef __APPLE__
+ if(memEstFine> maxMacMemChunk) {
+ memBlockAllocProblem = true;
+ }
+#endif // Mac
+ if(sizeof(void *)==4 && memEstFine>maxDefaultMemChunk) {
+ // max memory chunk for 32bit systems 2gig
+ memBlockAllocProblem = true;
+ }
+
+ if(memEstFromFunc>memLimit || memBlockAllocProblem) {
sizeReduction *= 0.9;
mSizex = (int)(orgSx * sizeReduction);
mSizey = (int)(orgSy * sizeReduction);
mSizez = (int)(orgSz * sizeReduction);
debMsgStd("LbmFsgrSolver::initialize",DM_WARNING,"initGridSizes: memory limit exceeded "<<
//memEstFromFunc<<"/"<<memLimit<<", "<<
+ //memEstFine<<"/"<<maxWinMemChunk<<", "<<
memreqStr<<"/"<<memLimStr<<", "<<
"retrying: "<<PRINT_VEC(mSizex,mSizey,mSizez)<<" org:"<<PRINT_VEC(orgSx,orgSy,orgSz)
, 3 );
@@ -778,10 +802,6 @@ bool LbmFsgrSolver::initializeSolverMemory()
mLevel[ mMaxRefine ].simCellSize = mpParam->getCellSize();
mLevel[ mMaxRefine ].lcellfactor = 1.0;
LONGINT rcellSize = ((mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez) *dTotalNum);
- // +4 for safety ?
- mLevel[ mMaxRefine ].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
- mLevel[ mMaxRefine ].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
- ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
#if COMPRESSGRIDS==0
mLevel[ mMaxRefine ].mprsCells[0] = new LbmFloat[ rcellSize +4 ];
@@ -789,11 +809,34 @@ bool LbmFsgrSolver::initializeSolverMemory()
ownMemCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
#else // COMPRESSGRIDS==0
LONGINT compressOffset = (mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*dTotalNum*2);
+ // D int tmp = ( (rcellSize +compressOffset +4)/(1024*1024) )*4;
+ // D printf("Debug MEMMMM excee: %d\n", tmp);
mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +compressOffset +4 ];
mLevel[ mMaxRefine ].mprsCells[0] = mLevel[ mMaxRefine ].mprsCells[1]+compressOffset;
ownMemCheck += sizeof(LbmFloat) * (rcellSize +compressOffset +4);
#endif // COMPRESSGRIDS==0
+ if(!mLevel[ mMaxRefine ].mprsCells[1] || !mLevel[ mMaxRefine ].mprsCells[0]) {
+ errFatal("LbmFsgrSolver::initialize","Fatal: Couldnt allocate memory (1)! Aborting...",SIMWORLD_INITERROR);
+ return false;
+ }
+
+ // +4 for safety ?
+ mLevel[ mMaxRefine ].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
+ mLevel[ mMaxRefine ].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
+ ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
+ if(!mLevel[ mMaxRefine ].mprsFlags[1] || !mLevel[ mMaxRefine ].mprsFlags[0]) {
+ errFatal("LbmFsgrSolver::initialize","Fatal: Couldnt allocate memory (2)! Aborting...",SIMWORLD_INITERROR);
+
+#if COMPRESSGRIDS==0
+ delete[] mLevel[ mMaxRefine ].mprsCells[0];
+ delete[] mLevel[ mMaxRefine ].mprsCells[1];
+#else // COMPRESSGRIDS==0
+ delete[] mLevel[ mMaxRefine ].mprsCells[1];
+#endif // COMPRESSGRIDS==0
+ return false;
+ }
+
LbmFloat lcfdimFac = 8.0;
if(LBMDIM==2) lcfdimFac = 4.0;
for(int i=mMaxRefine-1; i>=0; i--) {
diff --git a/intern/elbeem/intern/solver_interface.cpp b/intern/elbeem/intern/solver_interface.cpp
index 8dcfa495b95..d25850a003b 100644
--- a/intern/elbeem/intern/solver_interface.cpp
+++ b/intern/elbeem/intern/solver_interface.cpp
@@ -141,7 +141,7 @@ void initGridSizes(int &sizex, int &sizey, int &sizez,
void calculateMemreqEstimate( int resx,int resy,int resz,
int refine, float farfield,
- double *reqret, string *reqstr) {
+ double *reqret, double *reqretFine, string *reqstr) {
// debug estimation?
const bool debugMemEst = true;
// COMPRESSGRIDS define is not available here, make sure it matches
@@ -149,6 +149,7 @@ void calculateMemreqEstimate( int resx,int resy,int resz,
// make sure we can handle bid numbers here... all double
double memCnt = 0.0;
double ddTotalNum = (double)dTotalNum;
+ if(reqretFine) *reqretFine = -1.;
double currResx = (double)resx;
double currResy = (double)resy;
@@ -158,10 +159,12 @@ void calculateMemreqEstimate( int resx,int resy,int resz,
if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"res:"<<PRINT_VEC(currResx,currResy,currResz)<<" rcellSize:"<<rcellSize<<" mc:"<<memCnt, 10);
if(!useGridComp) {
memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
+ if(reqretFine) *reqretFine = (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," no-comp, mc:"<<memCnt, 10);
} else {
double compressOffset = (double)(currResx*currResy*ddTotalNum*2.0);
memCnt += (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0));
+ if(reqretFine) *reqretFine = (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0));
if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," w-comp, mc:"<<memCnt, 10);
}
for(int i=refine-1; i>=0; i--) {
@@ -186,7 +189,7 @@ void calculateMemreqEstimate( int resx,int resy,int resz,
// cpdata init check missing...
double memd = memCnt;
- char *sizeStr = "";
+ const char *sizeStr = "";
const double sfac = 1024.0;
if(memd>sfac){ memd /= sfac; sizeStr="KB"; }
if(memd>sfac){ memd /= sfac; sizeStr="MB"; }
diff --git a/intern/elbeem/intern/solver_interface.h b/intern/elbeem/intern/solver_interface.h
index 1dfdf156ee5..c3dc4983cac 100644
--- a/intern/elbeem/intern/solver_interface.h
+++ b/intern/elbeem/intern/solver_interface.h
@@ -21,7 +21,7 @@
#if LBM_USE_GUI==1
#define USE_GLUTILITIES
// for debug display
-#include <GL/gl.h>
+//#include <GL/gl.h>
#include "../gui/guifuncs.h"
#endif
@@ -596,8 +596,10 @@ class LbmSolverInterface
void initGridSizes(int &mSizex, int &mSizey, int &mSizez,
ntlVec3Gfx &mvGeoStart, ntlVec3Gfx &mvGeoEnd,
int mMaxRefine, bool parallel);
+// return the amount of memory required in total (reqret)
+// and for the finest grid only (reqretFine, can be NULL)
void calculateMemreqEstimate(int resx,int resy,int resz, int refine,
- float farfieldsize, double *reqret, string *reqstr);
+ float farfieldsize, double *reqret, double *reqretFine, string *reqstr);
//! helper function to convert flag to string (for debuggin)
string convertCellFlagType2String( CellFlagType flag );
diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp
index bced75ab444..13ebf91b696 100644
--- a/intern/elbeem/intern/solver_main.cpp
+++ b/intern/elbeem/intern/solver_main.cpp
@@ -11,6 +11,12 @@
#include "solver_relax.h"
#include "particletracer.h"
#include "loop_tools.h"
+#include <stdlib.h>
+
+#if (defined (__sun__) || defined (__sun)) || (!defined(linux) && (defined (__sparc) || defined (__sparc__)))
+#include <ieeefp.h>
+#endif
+
/*****************************************************************************/
/*! perform a single LBM step */
@@ -374,7 +380,11 @@ LbmFsgrSolver::mainLoop(int lev)
const int gridLoopBound=1;
GRID_REGION_INIT();
#if PARALLEL==1
-#include "paraloopstart.h"
+#pragma omp parallel default(shared) \
+ reduction(+: \
+ calcCurrentMass,calcCurrentVolume, \
+ calcCellsFilled,calcCellsEmptied, \
+ calcNumUsedCells )
GRID_REGION_START();
#else // PARALLEL==1
GRID_REGION_START();
@@ -1111,7 +1121,11 @@ LbmFsgrSolver::preinitGrids()
GRID_REGION_INIT();
#if PARALLEL==1
-#include "paraloopstart.h"
+#pragma omp parallel default(shared) \
+ reduction(+: \
+ calcCurrentMass,calcCurrentVolume, \
+ calcCellsFilled,calcCellsEmptied, \
+ calcNumUsedCells )
#endif // PARALLEL==1
GRID_REGION_START();
GRID_LOOP_START();
@@ -1144,7 +1158,11 @@ LbmFsgrSolver::standingFluidPreinit()
GRID_REGION_INIT();
#if PARALLEL==1
-#include "paraloopstart.h"
+#pragma omp parallel default(shared) \
+ reduction(+: \
+ calcCurrentMass,calcCurrentVolume, \
+ calcCellsFilled,calcCellsEmptied, \
+ calcNumUsedCells )
#endif // PARALLEL==1
GRID_REGION_START();
diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp
index 43be8af46df..a6685babe68 100644
--- a/intern/elbeem/intern/solver_util.cpp
+++ b/intern/elbeem/intern/solver_util.cpp
@@ -15,6 +15,7 @@
#include "ntl_world.h"
#include "simulation_object.h"
+#include <stdlib.h>
#include <zlib.h>
#ifndef sqrtf
#define sqrtf sqrt
diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp
index ad827efa2fc..551c4d0d384 100644
--- a/intern/elbeem/intern/utilities.cpp
+++ b/intern/elbeem/intern/utilities.cpp
@@ -55,7 +55,7 @@ int isSimworldOk(void) {
char gElbeemErrorString[256] = {'-','\0' };
// access elbeem simulator error string
-void setElbeemErrorString(char* set) {
+void setElbeemErrorString(const char* set) {
strncpy(gElbeemErrorString, set, 256);
}
char* getElbeemErrorString(void) { return gElbeemErrorString; }
@@ -76,7 +76,7 @@ int globalFirstEnvCheck = 0;
void resetGlobalColorSetting() { globalColorSetting = DEF_globalColorSetting; }
// global string for formatting vector output, TODO test!?
-char *globVecFormatStr = "V[%f,%f,%f]";
+const char *globVecFormatStr = "V[%f,%f,%f]";
// global mp on/off switch
@@ -481,7 +481,7 @@ double elbeemEstimateMemreq(int res,
double memreq = -1.0;
string memreqStr("");
// ignore farfield for now...
- calculateMemreqEstimate(resx,resy,resz, refine, 0., &memreq, &memreqStr );
+ calculateMemreqEstimate(resx,resy,resz, refine, 0., &memreq, NULL, &memreqStr );
if(retstr) {
// copy at max. 32 characters
diff --git a/intern/elbeem/intern/utilities.h b/intern/elbeem/intern/utilities.h
index 4d887c3f99b..825e92251fe 100644
--- a/intern/elbeem/intern/utilities.h
+++ b/intern/elbeem/intern/utilities.h
@@ -45,7 +45,7 @@ int getElbeemState(void);
int isSimworldOk(void);
// access elbeem simulator error string
-void setElbeemErrorString(char* set);
+void setElbeemErrorString(const char* set);
char* getElbeemErrorString(void);
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 2b17b8f8c61..11b0204eacb 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -771,6 +771,18 @@ extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
*/
extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
GHOST_RectangleHandle anotherrectanglehandle);
+
+/**
+ * Return the data from the clipboad
+ * @return clipboard data
+ */
+extern GHOST_TUns8* GHOST_getClipboard(int flag);
+
+/**
+ * Put data to the Clipboard
+ */
+extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int flag);
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 381aac64de0..0cb860d8158 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -352,6 +352,18 @@ public:
*/
virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
+ /**
+ * Returns the selection buffer
+ * @return Returns "unsinged char" from X11 XA_CUT_BUFFER0 buffer
+ *
+ */
+ virtual GHOST_TUns8* getClipboard(int flag) const = 0;
+
+ /**
+ * Put data to the Clipboard
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const = 0;
+
protected:
/**
* Initialize the system.
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 054cd507d1d..8c93788ee1b 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -817,3 +817,16 @@ GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
return result;
}
+
+GHOST_TUns8* GHOST_getClipboard(int flag)
+{
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+ return system->getClipboard(flag);
+}
+
+void GHOST_putClipboard(GHOST_TInt8 *buffer, int flag)
+{
+ GHOST_ISystem* system = GHOST_ISystem::getSystem();
+ system->putClipboard(buffer, flag);
+}
+
diff --git a/intern/ghost/intern/GHOST_DisplayManager.cpp b/intern/ghost/intern/GHOST_DisplayManager.cpp
index b36143ee1a9..f806daee86b 100644
--- a/intern/ghost/intern/GHOST_DisplayManager.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManager.cpp
@@ -116,7 +116,7 @@ GHOST_DisplayManager::getDisplaySetting(
GHOST_TUns8 numDisplays;
success = getNumDisplays(numDisplays);
if (success == GHOST_kSuccess) {
- if (display < numDisplays && index < m_settings[display].size()) {
+ if (display < numDisplays && ((GHOST_TUns8)index < m_settings[display].size())) {
setting = m_settings[display][index];
}
else {
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 4c797fbaa80..8477d70c42f 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -285,6 +285,21 @@ public:
*/
virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const = 0;
+ /**
+ * Returns the selection buffer
+ * @param flag Only used on X11
+ * @return Returns the clipboard data
+ *
+ */
+ virtual GHOST_TUns8* getClipboard(int flag) const = 0;
+
+ /**
+ * Put data to the Clipboard
+ * @param buffer The buffer to copy to the clipboard
+ * @param flag The clipboard to copy too only used on X11
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const = 0;
+
protected:
/**
* Initialize the system.
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index 7f1a2467d1a..cf4015815a9 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -1115,3 +1115,71 @@ OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, Even
return err;
}
+
+GHOST_TUns8* GHOST_SystemCarbon::getClipboard(int flag) const
+{
+ PasteboardRef inPasteboard;
+ PasteboardItemID itemID;
+ CFDataRef flavorData;
+ OSStatus err = noErr;
+ GHOST_TUns8 * temp_buff;
+ CFRange range;
+
+ err = PasteboardCreate(kPasteboardClipboard, &inPasteboard);
+ if(err != noErr) { return NULL;}
+
+ err = PasteboardSynchronize( inPasteboard );
+ if(err != noErr) { return NULL;}
+
+ err = PasteboardGetItemIdentifier( inPasteboard, 1, &itemID );
+ if(err != noErr) { return NULL;}
+
+ err = PasteboardCopyItemFlavorData( inPasteboard, itemID, CFSTR("public.utf8-plain-text"), &flavorData);
+ if(err != noErr) { return NULL;}
+
+ range = CFRangeMake(0, CFDataGetLength(flavorData));
+
+ temp_buff = (GHOST_TUns8*) malloc(range.length+1);
+
+ CFDataGetBytes(flavorData, range, (UInt8*)temp_buff);
+
+ temp_buff[range.length] = '\0';
+
+ if(temp_buff) {
+ return temp_buff;
+ } else {
+ return NULL;
+ }
+}
+
+void GHOST_SystemCarbon::putClipboard(GHOST_TInt8 *buffer, int flag) const
+{
+ if(flag == 1) {return;} //If Flag is 1 means the selection and is used on X11
+ PasteboardRef inPasteboard;
+ CFDataRef textData = NULL;
+ OSStatus err = noErr; /*For error checking*/
+
+ err = PasteboardCreate(kPasteboardClipboard, &inPasteboard);
+ if(err != noErr) { return;}
+
+ err = PasteboardSynchronize( inPasteboard );
+ if(err != noErr) { return;}
+
+ err = PasteboardClear( inPasteboard );
+ if(err != noErr) { return;}
+
+ textData = CFDataCreate(kCFAllocatorDefault, (UInt8*)buffer, strlen(buffer));
+
+ if (textData) {
+ err = PasteboardPutItemFlavor( inPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), textData, 0);
+ if(err != noErr) {
+ if(textData) { CFRelease(textData);}
+ return;
+ }
+ }
+
+ if(textData) {
+ CFRelease(textData);
+ }
+}
+
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h
index f2e3a775701..68e2d059226 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.h
+++ b/intern/ghost/intern/GHOST_SystemCarbon.h
@@ -60,12 +60,12 @@ public:
/**
* Constructor.
*/
- GHOST_SystemCarbon::GHOST_SystemCarbon();
+ GHOST_SystemCarbon();
/**
* Destructor.
*/
- GHOST_SystemCarbon::~GHOST_SystemCarbon();
+ ~GHOST_SystemCarbon();
/***************************************************************************************
** Time(r) functionality
@@ -168,6 +168,20 @@ public:
*/
virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+ /**
+ * Returns Clipboard data
+ * @param flag Indicate which buffer to return
+ * @return Returns the selected buffer
+ */
+ virtual GHOST_TUns8* getClipboard(int flag) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * @param buffer The buffer to be copied
+ * @param flag Indicates which buffer to copy too Only used on X11
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const;
+
protected:
/**
* Initializes the system.
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 5f4bfe9d668..c15e4f1246c 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -54,7 +54,7 @@
#define WM_MOUSEWHEEL 0x020A
#endif // WM_MOUSEWHEEL
#ifndef WHEEL_DELTA
-#define WHEEL_DELTA 120 /* Value for rolling one detent */
+#define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */
#endif // WHEEL_DELTA
@@ -481,7 +481,11 @@ GHOST_EventWheel* GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WP
{
// short fwKeys = LOWORD(wParam); // key flags
int zDelta = (short) HIWORD(wParam); // wheel rotation
- zDelta /= WHEEL_DELTA;
+
+ // zDelta /= WHEEL_DELTA;
+ // temporary fix below: microsoft now has added more precision, making the above division not work
+ if (zDelta <= 0 ) zDelta= -1; else zDelta= 1;
+
// short xPos = (short) LOWORD(lParam); // horizontal position of pointer
// short yPos = (short) HIWORD(lParam); // vertical position of pointer
return new GHOST_EventWheel (getSystem()->getMilliSeconds(), window, zDelta);
@@ -893,3 +897,54 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
return lResult;
}
+
+GHOST_TUns8* GHOST_SystemWin32::getClipboard(int flag) const
+{
+ char *buffer;
+ char *temp_buff;
+
+ if ( OpenClipboard(NULL) ) {
+ HANDLE hData = GetClipboardData( CF_TEXT );
+ buffer = (char*)GlobalLock( hData );
+
+ temp_buff = (char*) malloc(strlen(buffer)+1);
+ strcpy(temp_buff, buffer);
+
+ GlobalUnlock( hData );
+ CloseClipboard();
+
+ temp_buff[strlen(buffer)] = '\0';
+ if (buffer) {
+ return (GHOST_TUns8*)temp_buff;
+ } else {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, int flag) const
+{
+ if(flag == 1) {return;} //If Flag is 1 means the selection and is used on X11
+ if (OpenClipboard(NULL)) {
+ HLOCAL clipbuffer;
+ char *data;
+
+ if (buffer) {
+ EmptyClipboard();
+
+ clipbuffer = LocalAlloc(LMEM_FIXED,((strlen(buffer)+1)));
+ data = (char*)GlobalLock(clipbuffer);
+
+ strcpy(data, (char*)buffer);
+ data[strlen(buffer)] = '\0';
+ LocalUnlock(clipbuffer);
+ SetClipboardData(CF_TEXT,clipbuffer);
+ }
+ CloseClipboard();
+ } else {
+ return;
+ }
+}
+
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 218fc5794eb..762e5a988a4 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -170,6 +170,20 @@ public:
*/
virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+ /**
+ * Returns unsinged char from CUT_BUFFER0
+ * @param flag Flag is not used on win32 on used on X11
+ * @return Returns the Clipboard
+ */
+ virtual GHOST_TUns8* getClipboard(int flag) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * @param flag Flag is not used on win32 on used on X11
+ * @return No return
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const;
+
protected:
/**
* Initializes the system.
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 9d4717b00ef..47bcb76441f 100755..100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -66,6 +66,7 @@
#include <unistd.h>
#include <vector>
+#include <stdio.h> // for fprintf only
typedef struct NDOFPlatformInfo {
Display *display;
@@ -79,6 +80,11 @@ typedef struct NDOFPlatformInfo {
static NDOFPlatformInfo sNdofInfo = {NULL, 0, NULL, 0, 0, 0, 0};
+
+//these are for copy and select copy
+static char *txt_cut_buffer= NULL;
+static char *txt_select_buffer= NULL;
+
using namespace std;
GHOST_SystemX11::
@@ -316,7 +322,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
if (!window) {
return;
}
-
+
switch (xe->type) {
case Expose:
{
@@ -510,8 +516,57 @@ GHOST_SystemX11::processEvent(XEvent *xe)
case MappingNotify:
case ReparentNotify:
break;
-
- default: {
+ case SelectionRequest:
+ {
+ XEvent nxe;
+ Atom target, string, compound_text, c_string;
+ XSelectionRequestEvent *xse = &xe->xselectionrequest;
+
+ target = XInternAtom(m_display, "TARGETS", False);
+ string = XInternAtom(m_display, "STRING", False);
+ compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
+ c_string = XInternAtom(m_display, "C_STRING", False);
+
+ /* support obsolete clients */
+ if (xse->property == None) {
+ xse->property = xse->target;
+ }
+
+ nxe.xselection.type = SelectionNotify;
+ nxe.xselection.requestor = xse->requestor;
+ nxe.xselection.property = xse->property;
+ nxe.xselection.display = xse->display;
+ nxe.xselection.selection = xse->selection;
+ nxe.xselection.target = xse->target;
+ nxe.xselection.time = xse->time;
+
+ /*Check to see if the requestor is asking for String*/
+ if(xse->target == string || xse->target == compound_text || xse->target == c_string) {
+ if (xse->selection == XInternAtom(m_display, "PRIMARY", False)) {
+ XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, (unsigned char*)txt_select_buffer, strlen(txt_select_buffer));
+ } else if (xse->selection == XInternAtom(m_display, "CLIPBOARD", False)) {
+ XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 8, PropModeReplace, (unsigned char*)txt_cut_buffer, strlen(txt_cut_buffer));
+ }
+ } else if (xse->target == target) {
+ Atom alist[4];
+ alist[0] = target;
+ alist[1] = string;
+ alist[2] = compound_text;
+ alist[3] = c_string;
+ XChangeProperty(m_display, xse->requestor, xse->property, xse->target, 32, PropModeReplace, (unsigned char*)alist, 4);
+ XFlush(m_display);
+ } else {
+ //Change property to None because we do not support anything but STRING
+ nxe.xselection.property = None;
+ }
+
+ //Send the event to the client 0 0 == False, SelectionNotify
+ XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
+ XFlush(m_display);
+ break;
+ }
+
+ default: {
if(xe->type == window->GetXTablet().MotionEvent)
{
XDeviceMotionEvent* data = (XDeviceMotionEvent*)xe;
@@ -893,3 +948,113 @@ convertXKey(
}
#undef GXMAP
+
+ GHOST_TUns8*
+GHOST_SystemX11::
+getClipboard(int flag
+) const {
+ //Flag
+ //0 = Regular clipboard 1 = selection
+ static Atom Primary_atom, clip_String, compound_text;
+ Atom rtype;
+ Window m_window, owner;
+ unsigned char *data, *tmp_data;
+ int bits;
+ unsigned long len, bytes;
+ XEvent xevent;
+
+ vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
+ m_window = window->getXWindow();
+
+ clip_String = XInternAtom(m_display, "_BLENDER_STRING", False);
+ compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
+
+ //lets check the owner and if it is us then return the static buffer
+ if(flag == 0) {
+ Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
+ owner = XGetSelectionOwner(m_display, Primary_atom);
+ if (owner == m_window) {
+ data = (unsigned char*) malloc(strlen(txt_cut_buffer));
+ strcpy((char*)data, txt_cut_buffer);
+ return (GHOST_TUns8*)data;
+ } else if (owner == None) {
+ return NULL;
+ }
+ } else {
+ Primary_atom = XInternAtom(m_display, "PRIMARY", False);
+ owner = XGetSelectionOwner(m_display, Primary_atom);
+ if (owner == m_window) {
+ data = (unsigned char*) malloc(strlen(txt_select_buffer));
+ strcpy((char*)data, txt_select_buffer);
+ return (GHOST_TUns8*)data;
+ } else if (owner == None) {
+ return NULL;
+ }
+ }
+
+ if(!Primary_atom) {
+ return NULL;
+ }
+
+ XDeleteProperty(m_display, m_window, Primary_atom);
+ XConvertSelection(m_display, Primary_atom, compound_text, clip_String, m_window, CurrentTime); //XA_STRING
+ XFlush(m_display);
+
+ //This needs to change so we do not wait for ever or check owner first
+ while(1) {
+ XNextEvent(m_display, &xevent);
+ if(xevent.type == SelectionNotify) {
+ if(XGetWindowProperty(m_display, m_window, xevent.xselection.property, 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) {
+ tmp_data = (unsigned char*) malloc(strlen((char*)data));
+ strcpy((char*)tmp_data, (char*)data);
+ XFree(data);
+ return (GHOST_TUns8*)tmp_data;
+ }
+ return NULL;
+ }
+ }
+}
+
+ void
+GHOST_SystemX11::
+putClipboard(
+GHOST_TInt8 *buffer, int flag) const
+{
+ static Atom Primary_atom;
+ Window m_window, owner;
+
+ if(!buffer) {return;}
+
+ if(flag == 0) {
+ Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
+ if(txt_cut_buffer) { free((void*)txt_cut_buffer); }
+
+ txt_cut_buffer = (char*) malloc(strlen(buffer));
+ strcpy(txt_cut_buffer, buffer);
+ } else {
+ Primary_atom = XInternAtom(m_display, "PRIMARY", False);
+ if(txt_select_buffer) { free((void*)txt_select_buffer); }
+
+ txt_select_buffer = (char*) malloc(strlen(buffer));
+ strcpy(txt_select_buffer, buffer);
+ }
+
+ vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
+ vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
+ GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
+ m_window = window->getXWindow();
+
+ if(!Primary_atom) {
+ return;
+ }
+
+ XSetSelectionOwner(m_display, Primary_atom, m_window, CurrentTime);
+ owner = XGetSelectionOwner(m_display, Primary_atom);
+ if (owner != m_window)
+ fprintf(stderr, "failed to own primary\n");
+
+ return;
+}
+
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index e6adff44155..1c100bee852 100755..100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -201,6 +201,21 @@ public:
volatile GHOST_TEventNDOFData *current_values
);
+ /**
+ * Returns unsinged char from CUT_BUFFER0
+ * @param flag Flag indicates which buffer to return 0 for clipboard 1 for selection
+ * @return Returns the Clipboard indicated by Flag
+ */
+ GHOST_TUns8*
+ getClipboard(int flag) const;
+
+ /**
+ * Puts buffer to system clipboard
+ * @param buffer The buffer to copy to the clipboard
+ * @param flag Flag indicates which buffer to set ownership of 0 for clipboard 1 for selection
+ */
+ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const;
+
private :
Display * m_display;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 056b5756587..1b9b3c491d5 100755..100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -38,6 +38,13 @@
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
+#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__)
+#include <strings.h>
+#endif
+
+#include <cstring>
+#include <cstdio>
+
// For obscure full screen mode stuuf
// lifted verbatim from blut.
@@ -168,6 +175,7 @@ GHOST_WindowX11(
if (m_visual == NULL) {
// barf : no visual meeting these requirements could be found.
+ printf("%s:%d: X11 glxChooseVisual() failed for OpenGL, verify working openGL system!\n", __FILE__, __LINE__);
return;
}
@@ -196,7 +204,7 @@ GHOST_WindowX11(
KeyPressMask | KeyReleaseMask |
EnterWindowMask | LeaveWindowMask |
ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | FocusChangeMask;
+ PointerMotionMask | FocusChangeMask | PropertyChangeMask;
// create the window!
@@ -758,6 +766,15 @@ validate(
GHOST_WindowX11::
~GHOST_WindowX11(
){
+ static Atom Primary_atom, Clipboard_atom;
+ Window p_owner, c_owner;
+ /*Change the owner of the Atoms to None if we are the owner*/
+ Primary_atom = XInternAtom(m_display, "PRIMARY", False);
+ Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
+
+ p_owner = XGetSelectionOwner(m_display, Primary_atom);
+ c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
+
std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
for (; it != m_standard_cursors.end(); it++) {
XFreeCursor(m_display, it->second);
@@ -776,6 +793,14 @@ GHOST_WindowX11::
}
glXDestroyContext(m_display, m_context);
}
+
+ if (p_owner == m_window) {
+ XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
+ }
+ if (c_owner == m_window) {
+ XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
+ }
+
XDestroyWindow(m_display, m_window);
XFree(m_visual);
}
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 26a9258d03b..73eddff7d8a 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -100,9 +100,16 @@ extern "C" {
void *MEM_mapallocN(unsigned int len, const char * str);
/** Print a list of the names and sizes of all allocated memory
+ * blocks. as a python dict for easy investigation */
+ void MEM_printmemlist_pydict(void);
+
+ /** Print a list of the names and sizes of all allocated memory
* blocks. */
void MEM_printmemlist(void);
+ /** Print statistics about memory usage */
+ void MEM_printmemlist_stats(void);
+
/** Set the callback function for error output. */
void MEM_set_error_callback(void (*func)(char *));
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 51c2a2427b5..20d3a5b07fc 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -332,25 +332,146 @@ void *MEM_mapallocN(unsigned int len, const char *str)
#endif
}
+/* Memory statistics print */
+typedef struct MemPrintBlock {
+ const char *name;
+ unsigned long len;
+ int items;
+} MemPrintBlock;
+
+static int compare_name(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1= (const MemPrintBlock*)p1;
+ const MemPrintBlock *pb2= (const MemPrintBlock*)p2;
+
+ return strcmp(pb1->name, pb2->name);
+}
+
+static int compare_len(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1= (const MemPrintBlock*)p1;
+ const MemPrintBlock *pb2= (const MemPrintBlock*)p2;
+
+ if(pb1->len < pb2->len)
+ return 1;
+ else if(pb1->len == pb2->len)
+ return 0;
+ else
+ return -1;
+}
-void MEM_printmemlist()
+void MEM_printmemlist_stats()
{
MemHead *membl;
+ MemPrintBlock *pb, *printblock;
+ int totpb, a, b;
mem_lock_thread();
+ /* put memory blocks into array */
+ printblock= malloc(sizeof(MemPrintBlock)*totblock);
+
+ pb= printblock;
+ totpb= 0;
+
membl = membase->first;
if (membl) membl = MEMNEXT(membl);
+
while(membl) {
- print_error("%s len: %d %p\n",membl->name,membl->len, membl+1);
+ pb->name= membl->name;
+ pb->len= membl->len;
+ pb->items= 1;
+
+ totpb++;
+ pb++;
+
if(membl->next)
membl= MEMNEXT(membl->next);
else break;
}
+ /* sort by name and add together blocks with the same name */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
+ for(a=0, b=0; a<totpb; a++) {
+ if(a == b) {
+ continue;
+ }
+ else if(strcmp(printblock[a].name, printblock[b].name) == 0) {
+ printblock[b].len += printblock[a].len;
+ printblock[b].items++;
+ }
+ else {
+ b++;
+ memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
+ }
+ }
+ totpb= b+1;
+
+ /* sort by length and print */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use/(double)(1024*1024));
+ for(a=0, pb=printblock; a<totpb; a++, pb++)
+ printf("%s items: %d, len: %.3f MB\n", pb->name, pb->items, (double)pb->len/(double)(1024*1024));
+
+ free(printblock);
+
+ mem_unlock_thread();
+}
+
+/* Prints in python syntax for easy */
+static void MEM_printmemlist_internal( int pydict )
+{
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ if (pydict) {
+ print_error("# membase_debug.py\n");
+ print_error("membase = [\\\n");
+ }
+ while(membl) {
+ if (pydict) {
+ fprintf(stderr, "{'len':%i, 'name':'''%s''', 'pointer':'%p'},\\\n", membl->len, membl->name, membl+1);
+ } else {
+ print_error("%s len: %d %p\n",membl->name,membl->len, membl+1);
+ }
+ if(membl->next)
+ membl= MEMNEXT(membl->next);
+ else break;
+ }
+ if (pydict) {
+ fprintf(stderr, "]\n\n");
+ fprintf(stderr,
+"mb_userinfo = {}\n"
+"totmem = 0\n"
+"for mb_item in membase:\n"
+"\tmb_item_user_size = mb_userinfo.setdefault(mb_item['name'], [0,0])\n"
+"\tmb_item_user_size[0] += 1 # Add a user\n"
+"\tmb_item_user_size[1] += mb_item['len'] # Increment the size\n"
+"\ttotmem += mb_item['len']\n"
+"print '(membase) items:', len(membase), '| unique-names:', len(mb_userinfo), '| total-mem:', totmem\n"
+"mb_userinfo_sort = mb_userinfo.items()\n"
+"for sort_name, sort_func in (('size', lambda a: -a[1][1]), ('users', lambda a: -a[1][0]), ('name', lambda a: a[0])):\n"
+"\tprint '\\nSorting by:', sort_name\n"
+"\tmb_userinfo_sort.sort(key = sort_func)\n"
+"\tfor item in mb_userinfo_sort:\n"
+"\t\tprint 'name:%%s, users:%%i, len:%%i' %% (item[0], item[1][0], item[1][1])\n"
+ );
+ }
+
mem_unlock_thread();
}
+void MEM_printmemlist( void ) {
+ MEM_printmemlist_internal(0);
+}
+void MEM_printmemlist_pydict( void ) {
+ MEM_printmemlist_internal(1);
+}
+
short MEM_freeN(void *vmemh) /* anders compileertie niet meer */
{
short error = 0;
@@ -408,8 +529,10 @@ short MEM_freeN(void *vmemh) /* anders compileertie niet meer */
} else{
error = -1;
name = check_memlist(memh);
- if (name == 0) MemorY_ErroR("free","pointer not in memlist");
- else MemorY_ErroR(name,"error in header");
+ if (name == 0)
+ MemorY_ErroR("free","pointer not in memlist");
+ else
+ MemorY_ErroR(name,"error in header");
}
totblock--;
diff --git a/intern/iksolver/extern/IK_solver.h b/intern/iksolver/extern/IK_solver.h
index 8626ca22beb..bf53a9e3724 100644
--- a/intern/iksolver/extern/IK_solver.h
+++ b/intern/iksolver/extern/IK_solver.h
@@ -158,6 +158,8 @@ void IK_FreeSolver(IK_Solver *solver);
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight);
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight);
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle);
+float IK_SolverGetPoleAngle(IK_Solver *solver);
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations);
diff --git a/intern/iksolver/intern/IK_QJacobian.cpp b/intern/iksolver/intern/IK_QJacobian.cpp
index 03c5f9500be..1dd4d086aa8 100644
--- a/intern/iksolver/intern/IK_QJacobian.cpp
+++ b/intern/iksolver/intern/IK_QJacobian.cpp
@@ -42,11 +42,10 @@ IK_QJacobian::~IK_QJacobian()
{
}
-void IK_QJacobian::ArmMatrices(int dof, int task_size, int tasks)
+void IK_QJacobian::ArmMatrices(int dof, int task_size)
{
m_dof = dof;
m_task_size = task_size;
- m_tasks = tasks;
m_jacobian.newsize(task_size, dof);
m_jacobian = 0;
diff --git a/intern/iksolver/intern/IK_QJacobian.h b/intern/iksolver/intern/IK_QJacobian.h
index b80db1d8f53..3e20e4a9fd0 100644
--- a/intern/iksolver/intern/IK_QJacobian.h
+++ b/intern/iksolver/intern/IK_QJacobian.h
@@ -49,7 +49,7 @@ public:
~IK_QJacobian();
// Call once to initialize
- void ArmMatrices(int dof, int task_size, int tasks);
+ void ArmMatrices(int dof, int task_size);
void SetDoFWeight(int dof, MT_Scalar weight);
// Iteratively called
@@ -75,7 +75,7 @@ private:
void InvertSDLS();
void InvertDLS();
- int m_dof, m_task_size, m_tasks;
+ int m_dof, m_task_size;
bool m_transpose;
// the jacobian matrix and it's null space projector
diff --git a/intern/iksolver/intern/IK_QJacobianSolver.cpp b/intern/iksolver/intern/IK_QJacobianSolver.cpp
index 7cfdcccc2ad..17750a7195f 100644
--- a/intern/iksolver/intern/IK_QJacobianSolver.cpp
+++ b/intern/iksolver/intern/IK_QJacobianSolver.cpp
@@ -30,9 +30,47 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+#include <stdio.h>
#include "IK_QJacobianSolver.h"
+#include "MT_Quaternion.h"
//#include "analyze.h"
+IK_QJacobianSolver::IK_QJacobianSolver()
+{
+ m_poleconstraint = false;
+ m_getpoleangle = false;
+ m_rootmatrix.setIdentity();
+}
+
+MT_Scalar IK_QJacobianSolver::ComputeScale()
+{
+ std::vector<IK_QSegment*>::iterator seg;
+ float length = 0.0f;
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ length += (*seg)->MaxExtension();
+
+ if(length == 0.0f)
+ return 1.0f;
+ else
+ return 1.0f/length;
+}
+
+void IK_QJacobianSolver::Scale(float scale, std::list<IK_QTask*>& tasks)
+{
+ std::list<IK_QTask*>::iterator task;
+ std::vector<IK_QSegment*>::iterator seg;
+
+ for (task = tasks.begin(); task != tasks.end(); task++)
+ (*task)->Scale(scale);
+
+ for (seg = m_segments.begin(); seg != m_segments.end(); seg++)
+ (*seg)->Scale(scale);
+
+ m_rootmatrix.getOrigin() *= scale;
+ m_goal *= scale;
+ m_polegoal *= scale;
+}
void IK_QJacobianSolver::AddSegmentList(IK_QSegment *seg)
{
@@ -48,7 +86,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
m_segments.clear();
AddSegmentList(root);
- // assing each segment a unique id for the jacobian
+ // assign each segment a unique id for the jacobian
std::vector<IK_QSegment*>::iterator seg;
int num_dof = 0;
@@ -106,9 +144,9 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
}
// set matrix sizes
- m_jacobian.ArmMatrices(num_dof, primary_size, primary);
+ m_jacobian.ArmMatrices(num_dof, primary_size);
if (secondary > 0)
- m_jacobian_sub.ArmMatrices(num_dof, secondary_size, secondary);
+ m_jacobian_sub.ArmMatrices(num_dof, secondary_size);
// set dof weights
int i;
@@ -120,6 +158,109 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks)
return true;
}
+void IK_QJacobianSolver::SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal, MT_Vector3& polegoal, float poleangle, bool getangle)
+{
+ m_poleconstraint = true;
+ m_poletip = tip;
+ m_goal = goal;
+ m_polegoal = polegoal;
+ m_poleangle = (getangle)? 0.0f: poleangle;
+ m_getpoleangle = getangle;
+}
+
+static MT_Scalar safe_acos(MT_Scalar f)
+{
+ // acos that does not return NaN with rounding errors
+ if (f <= -1.0f) return MT_PI;
+ else if (f >= 1.0f) return 0.0;
+ else return acos(f);
+}
+
+static MT_Vector3 normalize(const MT_Vector3& v)
+{
+ // a sane normalize function that doesn't give (1, 0, 0) in case
+ // of a zero length vector, like MT_Vector3.normalize
+ MT_Scalar len = v.length();
+ return MT_fuzzyZero(len)? MT_Vector3(0, 0, 0): v/len;
+}
+
+static float angle(const MT_Vector3& v1, const MT_Vector3& v2)
+{
+ return safe_acos(v1.dot(v2));
+}
+
+void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks)
+{
+ // this function will be called before and after solving. calling it before
+ // solving gives predictable solutions by rotating towards the solution,
+ // and calling it afterwards ensures the solution is exact.
+
+ if(!m_poleconstraint)
+ return;
+
+ // disable pole vector constraint in case of multiple position tasks
+ std::list<IK_QTask*>::iterator task;
+ int positiontasks = 0;
+
+ for (task = tasks.begin(); task != tasks.end(); task++)
+ if((*task)->PositionTask())
+ positiontasks++;
+
+ if (positiontasks >= 2) {
+ m_poleconstraint = false;
+ return;
+ }
+
+ // get positions and rotations
+ root->UpdateTransform(m_rootmatrix);
+
+ const MT_Vector3 rootpos = root->GlobalStart();
+ const MT_Vector3 endpos = m_poletip->GlobalEnd();
+ const MT_Matrix3x3& rootbasis = root->GlobalTransform().getBasis();
+
+ // construct "lookat" matrices (like gluLookAt), based on a direction and
+ // an up vector, with the direction going from the root to the end effector
+ // and the up vector going from the root to the pole constraint position.
+ MT_Vector3 dir = normalize(endpos - rootpos);
+ MT_Vector3 rootx= rootbasis.getColumn(0);
+ MT_Vector3 rootz= rootbasis.getColumn(2);
+ MT_Vector3 up = rootx*cos(m_poleangle) + rootz*sin(m_poleangle);
+
+ // in post, don't rotate towards the goal but only correct the pole up
+ MT_Vector3 poledir = (m_getpoleangle)? dir: normalize(m_goal - rootpos);
+ MT_Vector3 poleup = normalize(m_polegoal - rootpos);
+
+ MT_Matrix3x3 mat, polemat;
+
+ mat[0] = normalize(MT_cross(dir, up));
+ mat[1] = MT_cross(mat[0], dir);
+ mat[2] = -dir;
+
+ polemat[0] = normalize(MT_cross(poledir, poleup));
+ polemat[1] = MT_cross(polemat[0], poledir);
+ polemat[2] = -poledir;
+
+ if(m_getpoleangle) {
+ // we compute the pole angle that to rotate towards the target
+ m_poleangle = angle(mat[1], polemat[1]);
+
+ if(rootz.dot(mat[1]*cos(m_poleangle) + mat[0]*sin(m_poleangle)) > 0.0f)
+ m_poleangle = -m_poleangle;
+
+ // solve again, with the pole angle we just computed
+ m_getpoleangle = false;
+ ConstrainPoleVector(root, tasks);
+ }
+ else {
+ // now we set as root matrix the difference between the current and
+ // desired rotation based on the pole vector constraint. we use
+ // transpose instead of inverse because we have orthogonal matrices
+ // anyway, and in case of a singular matrix we don't get NaN's.
+ MT_Transform trans(MT_Point3(0, 0, 0), polemat.transposed()*mat);
+ m_rootmatrix = trans*m_rootmatrix;
+ }
+}
+
bool IK_QJacobianSolver::UpdateAngles(MT_Scalar& norm)
{
// assing each segment a unique id for the jacobian
@@ -182,15 +323,20 @@ bool IK_QJacobianSolver::Solve(
const int max_iterations
)
{
+ float scale = ComputeScale();
+ bool solved = false;
//double dt = analyze_time();
- if (!Setup(root, tasks))
- return false;
+ Scale(scale, tasks);
+
+ ConstrainPoleVector(root, tasks);
+
+ root->UpdateTransform(m_rootmatrix);
// iterate
for (int iterations = 0; iterations < max_iterations; iterations++) {
// update transform
- root->UpdateTransform(MT_Transform::Identity());
+ root->UpdateTransform(m_rootmatrix);
std::list<IK_QTask*>::iterator task;
@@ -212,7 +358,7 @@ bool IK_QJacobianSolver::Solve(
m_jacobian.SubTask(m_jacobian_sub);
}
catch (...) {
- printf("IK Exception\n");
+ fprintf(stderr, "IK Exception\n");
return false;
}
@@ -231,12 +377,18 @@ bool IK_QJacobianSolver::Solve(
// check for convergence
if (norm < 1e-3) {
- //analyze_add_run(iterations, analyze_time()-dt);
- return true;
+ solved = true;
+ break;
}
}
+ if(m_poleconstraint)
+ root->PrependBasis(m_rootmatrix.getBasis());
+
+ Scale(1.0f/scale, tasks);
+
//analyze_add_run(max_iterations, analyze_time()-dt);
- return false;
+
+ return solved;
}
diff --git a/intern/iksolver/intern/IK_QJacobianSolver.h b/intern/iksolver/intern/IK_QJacobianSolver.h
index adf95eb82dc..9ad46cd0aa6 100644
--- a/intern/iksolver/intern/IK_QJacobianSolver.h
+++ b/intern/iksolver/intern/IK_QJacobianSolver.h
@@ -43,6 +43,7 @@
#include <list>
#include "MT_Vector3.h"
+#include "MT_Transform.h"
#include "IK_QJacobian.h"
#include "IK_QSegment.h"
#include "IK_QTask.h"
@@ -50,11 +51,18 @@
class IK_QJacobianSolver
{
public:
- IK_QJacobianSolver() {};
+ IK_QJacobianSolver();
~IK_QJacobianSolver() {};
- // returns true if converged, false if max number of iterations was used
+ // setup pole vector constraint
+ void SetPoleVectorConstraint(IK_QSegment *tip, MT_Vector3& goal,
+ MT_Vector3& polegoal, float poleangle, bool getangle);
+ float GetPoleAngle() { return m_poleangle; };
+
+ // call setup once before solving, if it fails don't solve
+ bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
+ // returns true if converged, false if max number of iterations was used
bool Solve(
IK_QSegment *root,
std::list<IK_QTask*> tasks,
@@ -64,8 +72,11 @@ public:
private:
void AddSegmentList(IK_QSegment *seg);
- bool Setup(IK_QSegment *root, std::list<IK_QTask*>& tasks);
bool UpdateAngles(MT_Scalar& norm);
+ void ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTask*>& tasks);
+
+ MT_Scalar ComputeScale();
+ void Scale(float scale, std::list<IK_QTask*>& tasks);
private:
@@ -75,6 +86,15 @@ private:
bool m_secondary_enabled;
std::vector<IK_QSegment*> m_segments;
+
+ MT_Transform m_rootmatrix;
+
+ bool m_poleconstraint;
+ bool m_getpoleangle;
+ MT_Vector3 m_goal;
+ MT_Vector3 m_polegoal;
+ float m_poleangle;
+ IK_QSegment *m_poletip;
};
#endif
diff --git a/intern/iksolver/intern/IK_QSegment.cpp b/intern/iksolver/intern/IK_QSegment.cpp
index cf9e1615d8c..bf38c369363 100644
--- a/intern/iksolver/intern/IK_QSegment.cpp
+++ b/intern/iksolver/intern/IK_QSegment.cpp
@@ -61,11 +61,11 @@ static MT_Scalar EulerAngleFromMatrix(const MT_Matrix3x3& R, int axis)
MT_Scalar t = sqrt(R[0][0]*R[0][0] + R[0][1]*R[0][1]);
if (t > 16.0*MT_EPSILON) {
- if (axis == 0) return atan2(R[1][2], R[2][2]);
+ if (axis == 0) return -atan2(R[1][2], R[2][2]);
else if(axis == 1) return atan2(-R[0][2], t);
- else return atan2(R[0][1], R[0][0]);
+ else return -atan2(R[0][1], R[0][0]);
} else {
- if (axis == 0) return atan2(-R[2][1], R[1][1]);
+ if (axis == 0) return -atan2(-R[2][1], R[1][1]);
else if(axis == 1) return atan2(-R[0][2], t);
else return 0.0f;
}
@@ -236,6 +236,18 @@ IK_QSegment::IK_QSegment(int num_DoF, bool translational)
m_orig_translation = m_translation;
}
+void IK_QSegment::Reset()
+{
+ m_locked[0] = m_locked[1] = m_locked[2] = false;
+
+ m_basis = m_orig_basis;
+ m_translation = m_orig_translation;
+ SetBasis(m_basis);
+
+ for (IK_QSegment *seg = m_child; seg; seg = seg->m_sibling)
+ seg->Reset();
+}
+
void IK_QSegment::SetTransform(
const MT_Vector3& start,
const MT_Matrix3x3& rest_basis,
@@ -326,6 +338,21 @@ void IK_QSegment::UpdateTransform(const MT_Transform& global)
seg->UpdateTransform(m_global_transform);
}
+void IK_QSegment::PrependBasis(const MT_Matrix3x3& mat)
+{
+ m_basis = m_rest_basis.inverse() * mat * m_rest_basis * m_basis;
+}
+
+void IK_QSegment::Scale(float scale)
+{
+ m_start *= scale;
+ m_translation *= scale;
+ m_orig_translation *= scale;
+ m_global_start *= scale;
+ m_global_transform.getOrigin() *= scale;
+ m_max_extension *= scale;
+}
+
// IK_QSphericalSegment
IK_QSphericalSegment::IK_QSphericalSegment()
@@ -1009,3 +1036,17 @@ void IK_QTranslateSegment::SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax)
m_limit[axis]= true;
}
+void IK_QTranslateSegment::Scale(float scale)
+{
+ int i;
+
+ IK_QSegment::Scale(scale);
+
+ for (i = 0; i < 3; i++) {
+ m_min[0] *= scale;
+ m_max[1] *= scale;
+ }
+
+ m_new_translation *= scale;
+}
+
diff --git a/intern/iksolver/intern/IK_QSegment.h b/intern/iksolver/intern/IK_QSegment.h
index e406585bc8b..3c5df463468 100644
--- a/intern/iksolver/intern/IK_QSegment.h
+++ b/intern/iksolver/intern/IK_QSegment.h
@@ -165,6 +165,13 @@ public:
virtual void SetBasis(const MT_Matrix3x3& basis) { m_basis = basis; }
+ // functions needed for pole vector constraint
+ void PrependBasis(const MT_Matrix3x3& mat);
+ void Reset();
+
+ // scale
+ virtual void Scale(float scale);
+
protected:
// num_DoF: number of degrees of freedom
@@ -331,6 +338,8 @@ public:
void SetWeight(int axis, MT_Scalar weight);
void SetLimit(int axis, MT_Scalar lmin, MT_Scalar lmax);
+ void Scale(float scale);
+
private:
int m_axis[3];
bool m_axis_enabled[3], m_limit[3];
diff --git a/intern/iksolver/intern/IK_QTask.h b/intern/iksolver/intern/IK_QTask.h
index 0e00925d908..f2fd34119a1 100644
--- a/intern/iksolver/intern/IK_QTask.h
+++ b/intern/iksolver/intern/IK_QTask.h
@@ -75,6 +75,10 @@ public:
virtual MT_Scalar Distance() const=0;
+ virtual bool PositionTask() const { return false; }
+
+ virtual void Scale(float scale) {}
+
protected:
int m_id;
int m_size;
@@ -97,6 +101,9 @@ public:
MT_Scalar Distance() const;
+ bool PositionTask() const { return true; }
+ void Scale(float scale) { m_goal *= scale; m_clamp_length *= scale; }
+
private:
MT_Vector3 m_goal;
MT_Scalar m_clamp_length;
@@ -133,6 +140,8 @@ public:
MT_Scalar Distance() const;
+ void Scale(float scale) { m_goal_center *= scale; m_distance *= scale; }
+
private:
MT_Scalar ComputeTotalMass(const IK_QSegment *segment);
MT_Vector3 ComputeCenter(const IK_QSegment *segment);
diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp
index 919eeb739ce..140c35c8c46 100644
--- a/intern/iksolver/intern/IK_Solver.cpp
+++ b/intern/iksolver/intern/IK_Solver.cpp
@@ -41,7 +41,7 @@ using namespace std;
class IK_QSolver {
public:
- IK_QSolver() {};
+ IK_QSolver() : root(NULL) {};
IK_QJacobianSolver solver;
IK_QSegment *root;
@@ -197,13 +197,12 @@ void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
if (stiffness < 0.0)
return;
- if (stiffness > 0.99)
- stiffness = 0.99;
+ if (stiffness > 0.999)
+ stiffness = 0.999;
IK_QSegment *qseg = (IK_QSegment*)seg;
MT_Scalar weight = 1.0-stiffness;
-
if (axis >= IK_TRANS_X) {
if(!qseg->Translational())
if(qseg->Composite() && qseg->Composite()->Translational())
@@ -318,6 +317,31 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[
qsolver->tasks.push_back(orient);
}
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle)
+{
+ if (solver == NULL || tip == NULL)
+ return;
+
+ IK_QSolver *qsolver = (IK_QSolver*)solver;
+ IK_QSegment *qtip = (IK_QSegment*)tip;
+
+ MT_Vector3 qgoal(goal);
+ MT_Vector3 qpolegoal(polegoal);
+
+ qsolver->solver.SetPoleVectorConstraint(
+ qtip, qgoal, qpolegoal, poleangle, getangle);
+}
+
+float IK_SolverGetPoleAngle(IK_Solver *solver)
+{
+ if (solver == NULL)
+ return 0.0f;
+
+ IK_QSolver *qsolver = (IK_QSolver*)solver;
+
+ return qsolver->solver.GetPoleAngle();
+}
+
void IK_SolverAddCenterOfMass(IK_Solver *solver, IK_Segment *root, float goal[3], float weight)
{
if (solver == NULL || root == NULL)
@@ -346,6 +370,9 @@ int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
std::list<IK_QTask*>& tasks = qsolver->tasks;
MT_Scalar tol = tolerance;
+ if(!jacobian.Setup(root, tasks))
+ return 0;
+
bool result = jacobian.Solve(root, tasks, tol, max_iterations);
return ((result)? 1: 0);
diff --git a/intern/iksolver/intern/TNT/svd.h b/intern/iksolver/intern/TNT/svd.h
index af281d0fce0..9ca51fa2650 100644
--- a/intern/iksolver/intern/TNT/svd.h
+++ b/intern/iksolver/intern/TNT/svd.h
@@ -18,11 +18,13 @@
#include "tntmath.h"
+#define SVD_MAX_ITER 200
+
namespace TNT
{
template <class MaTRiX, class VecToR >
-void SVD(MaTRiX &A, MaTRiX &U, VecToR &s, MaTRiX &V, VecToR &work1, VecToR &work2) {
+void SVD(MaTRiX &A, MaTRiX &U, VecToR &s, MaTRiX &V, VecToR &work1, VecToR &work2, int maxiter=SVD_MAX_ITER) {
int m = A.num_rows();
int n = A.num_cols();
@@ -216,7 +218,10 @@ void SVD(MaTRiX &A, MaTRiX &U, VecToR &s, MaTRiX &V, VecToR &work1, VecToR &work
int kase=0;
k=0;
- // Here is where a test for too many iterations would go.
+ // Test for maximum iterations to avoid infinite loop
+ if(maxiter == 0)
+ break;
+ maxiter--;
// This section of the program inspects for
// negligible elements in the s and e arrays. On
diff --git a/intern/keymaker/Makefile b/intern/keymaker/Makefile
deleted file mode 100644
index 703482a851b..00000000000
--- a/intern/keymaker/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# $Id$
-# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version. The Blender
-# Foundation also sells licenses for use in proprietary software under
-# the Blender License. See http://www.blender.org/BL/ for information
-# about this.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You 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/BL DUAL LICENSE BLOCK *****
-# blender keyreader-library makefile
-#
-
-LIBNAME = blenkey
-SOURCEDIR = intern/$(LIBNAME)
-DIR = $(OCGDIR)/$(SOURCEDIR)
-CSRCS = mt19937int.c key.c
-
-ALLTARGETS = $(OBJS)
-
-include nan_compile.mk
-
-CFLAGS += $(LEVEL_2_C_WARNINGS)
-
-CPPFLAGS += -I$(NAN_OPENSSL)/include -Ipython/
-
-include nan_link.mk
-
-# OBJS is for the library, set by nan_compile.mk
-LOADER_OBJS = $(DIR)/$(DEBUG_DIR)keyloader.o
-
-ifneq ($(OS),windows)
- LIBS = $(NAN_OPENSSL)/lib/libcrypto.a
-else
- ifeq ($(FREE_WINDOWS),true)
- LIBS = $(NAN_OPENSSL)/lib/libcrypto.a
- else
- LIBS = $(NAN_OPENSSL)/lib/libeay32.lib
- LIBS += advapi32.lib gdi32.lib
- endif
-endif
-
-all debug:: link
-
-link: $(DIR)/$(DEBUG_DIR)keyloader
-
-strip:
- ifneq ($(OS),windows)
- strip keyloader
- @ls -la keyloader
- else
- @ls -la keyloader.exe
- endif
-
-install: all debug
- @[ -d $(LCGDIR)/$(LIBNAME) ] || mkdir $(LCGDIR)/$(LIBNAME)
- @[ -d $(LCGDIR)/$(LIBNAME)/include ] || mkdir $(LCGDIR)/$(LIBNAME)/include
- @[ -d $(LCGDIR)/$(LIBNAME)/lib ] || mkdir $(LCGDIR)/$(LIBNAME)/lib
- @../tools/cpifdiff.sh blenkey.h $(LCGDIR)/$(LIBNAME)/include/
- @../tools/cpifdiff.sh $(LIB_a) $(LCGDIR)/$(LIBNAME)/lib/
-ifeq ($(OS),darwin)
- ranlib $(LCGDIR)/$(LIBNAME)/lib/lib$(LIBNAME).a
-endif
-
-$(DIR)/$(DEBUG_DIR)keyloader: $(LOADER_OBJS) $(LIB_a)
- $(CC) $(LDFLAGS) -o $@ $(LOADER_OBJS) $(LIB_a) $(LIBS)
-
-clean::
- $(RM) $(DIR)/key* $(DIR)/debug/key*
- $(RM) $(DIR)/nan* $(DIR)/debug/nan*
-
-tags:
- etags *.c *.h
diff --git a/intern/keymaker/blenkey.h b/intern/keymaker/blenkey.h
deleted file mode 100644
index e504fdf62b8..00000000000
--- a/intern/keymaker/blenkey.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Blender Key loader library external interface
- */
-
-#ifndef BLENKEY_H
-#define BLENKEY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned char byte;
-
-typedef struct UserStructType {
- char name[100];
- char email[100];
- char shopid[100];
- unsigned long reldate;
- int keytype; /* 1 = Individual, 2 = Corporate, 3 = Unlimited */
- int keylevel; /* key disclosure level, starts at 1 */
- int keyformat; /* if we change the keyformat, up BLENKEYFORMAT */
-} UserStruct;
-
-char *Hexify(byte *in, unsigned int length);
-byte *DeHexify(char *in);
-
-byte checkfunc0(byte a, byte b);
-byte checkfunc1(byte a, byte b);
-byte checkfunc2(byte a, byte b);
-byte checkfunc3(byte a, byte b);
-byte checkfunc4(byte a, byte b);
-
-/* the byte size of the checksum datablock
-#define MAXBYTEDATABLOCK 1000 */
-
-#define BLENKEYMAGIC "0ce0ba52"
-#define BLENKEYSEPERATOR "---+++---"
-#define BLENKEYFORMAT 1
-
-
-int ReadKeyFile(char *filename, UserStruct *User,
- char **Priv, char **Pub, byte **Byte, char **Python);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BLENKEY_H */
-
diff --git a/intern/keymaker/key.c b/intern/keymaker/key.c
deleted file mode 100644
index 413ee8b448c..00000000000
--- a/intern/keymaker/key.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/* ex:ts=4 */
-
-/**
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Blender Key loader library
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "blenkey.h" /* external interface */
-#include "key_internal.h"
-
-char *Hexify(byte *in, unsigned int length) {
- unsigned int i;
- char Tstring[3];
- char *out = malloc((2*length + 1) * sizeof(char));
- sprintf(out, "%02X", in[0]);
- for (i=1; i<length; i++) {
- sprintf(Tstring, "%02X", in[i]);
- strcat(out, Tstring);
- }
- return (out);
-}
-
-byte *DeHexify(char *in) {
- size_t len = strlen(in);
- byte *out = malloc((len/2) * sizeof(byte));
- unsigned int hexedbyte;
- unsigned int i;
- char *inp = in;
- byte *outp = out;
- for (i=0; i<(len/2); i++) {
- sscanf(inp, "%2x", &hexedbyte);
- inp += 2;
- *outp = (byte) hexedbyte;
- outp++;
- }
- /* printf("\nlen=%d, string=[%s]\n", len, Hexify(out, len/2)); */
- return (out);
-}
-
-int from_hex(char c) {
- return (c<'A') ? (c-'0') : (c-'A'+10);
-}
-
-/* 5 ReadHex helper functions ------------------------------------------
- read one Hex byte (two characters) and skip newlines if necessary */
-byte ReadHexByteFp(FILE *fh, int *newlinetracker) {
- unsigned char a;
- unsigned char a1, a2;
- /* read 2 bytes hexcode of ascii data type */
- fread(&a1, 1, 1, fh);
- fread(&a2, 1, 1, fh);
- a = 16 * (from_hex(a1)) + (from_hex(a2));
- /*printf("Char[%d] = %02X\n", *newlinetracker, a); */
- *newlinetracker += 2;
- /* skip the newlines */
- if (*newlinetracker == 72) {
- fseek(fh, 1, SEEK_CUR);
- *newlinetracker = 0;
- /*printf("LastChar = %02X\n", a); */
- }
- return((byte) a);
-}
-byte ReadHexByteCp(char **from) {
- int a;
- /* read 2 bytes hexcode of ascii data type */
- sscanf(*from, "%2x", &a);
- /*printf("Char = %02X\n", a); */
- *from += 2;
- return((byte) a);
-}
-/* Generic hex2int */
-int HexToInt(int a) {
- if (a == 0x20) /* space, count as 0 ;-) */
- return 0;
- else
- return(a - '0');
-}
-/* Note: this is only to be used for the header type */
-int HexToIntFp(FILE *fh, int *newlinetracker) {
- byte a = ReadHexByteFp(fh, newlinetracker);
- if (DEBUG) printf("%02X = %d\n", a, a); /* note: no HexToInt here */
- return(a);
-}
-int HexToIntCp(char **from) {
- byte a = ReadHexByteCp(from);
- if (DEBUG) printf("%02X = %d\n", a, a); /* note: no HexToInt here */
- return(a);
-}
-/* Note: this is only to be used for the header length */
-int Hex5ToInt(byte a, byte b, byte c, byte d, byte e) {
- return(HexToInt((int) a) * 10000 +
- HexToInt((int) b) * 1000 +
- HexToInt((int) c) * 100 +
- HexToInt((int) d) * 10 +
- HexToInt((int) e));
-}
-/* Note: this is only to be used for the header length */
-int Hex5ToIntFp(FILE *fh, int *newlinetracker) {
- byte a = ReadHexByteFp(fh, newlinetracker),
- b = ReadHexByteFp(fh, newlinetracker),
- c = ReadHexByteFp(fh, newlinetracker),
- d = ReadHexByteFp(fh, newlinetracker),
- e = ReadHexByteFp(fh, newlinetracker);
- if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e,
- Hex5ToInt(a, b, c, d, e));
- return(Hex5ToInt(a, b, c, d, e));
-}
-int Hex5ToIntCp(char **from) {
- byte a = ReadHexByteCp(from),
- b = ReadHexByteCp(from),
- c = ReadHexByteCp(from),
- d = ReadHexByteCp(from),
- e = ReadHexByteCp(from);
- if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e,
- Hex5ToInt(a, b, c, d, e));
- return(Hex5ToInt(a, b, c, d, e));
-}
-/* --------------------------------------------------------------------- */
-
-/* return the biggest */
-byte checkfunc0(byte a, byte b) {
- if (a > b) return a;
- else return b;
-}
-/* return |a-b| */
-byte checkfunc1(byte a, byte b) {
- if (a > b) return a - b;
- else return b - a;
-}
-/* return the sum mod 256 */
-byte checkfunc2(byte a, byte b) {
- return ((a + b) % 256);
-}
-/* return the multiplication mod 256 */
-byte checkfunc3(byte a, byte b) {
- return ((a * b) % 256);
-}
-/* return a/b or 0 */
-byte checkfunc4(byte a, byte b) {
- if (b != 0) return (a / b);
- else return 0;
-}
-
-char *scan_ascii(FILE *fh, UserStruct *User) {
- long ascii_size;
- char *ascii_data = NULL;
- char *mdhex = NULL;
- byte md[RIPEMD160_DIGEST_LENGTH];
- char string[1024];
- char dosnewlines = 0;
- int lines = 0;
- int oldftell;
-
- /* NOTE: fscanf is notorious for its buffer overflows. This must be
- fixed some day, consider this a proof-of-concept version. */
-
- fscanf(fh, "%1000[^\n]", string);
- sscanf(string, "%*s %s %s %lu %d %d %d",
- User->email,
- User->shopid,
- &User->reldate,
- &User->keytype,
- &User->keylevel,
- &User->keyformat);
-
- if (User->keyformat <= BLENKEYFORMAT) {
- if (DEBUG) printf(
- "Email:[%s] ShopID:[%s] RelDate:[%lu] KeyType[%d] KeyLevel[%d]\n",
- User->email, User->shopid, User->reldate, User->keytype,
- User->keylevel);
-
- /* read /n/n
- check if we're reading dow newlines...
- */
- oldftell = ftell(fh);
- getc(fh);
- if ((ftell(fh) - oldftell) == 2) {
- /* yes ! */
- dosnewlines = 1;
- }
- getc(fh);
-
- fscanf(fh, "%1000[^\n]", string);
- strncpy(User->name, string, sizeof(User->name) - 1);
-
- if (DEBUG) printf("Name:[%s]\n", User->name);
-
- getc(fh);
-
- /* 4 lines read uptil now... */
- lines = 4;
-
- while (getc(fh) != EOF) {
- fscanf(fh, "%1000[^\n]", string);
- lines++;
- /* if (DEBUG) printf("%s\n", string); */
- if (strcmp(string, BLENKEYSEPERATOR) == 0) {
- getc(fh);
- break;
- }
- }
-
- /* fh now points at the start of the datablock */
- ascii_size = ftell(fh);
-
- if (dosnewlines) {
- /* if we were reading on dos
- ftell will also count the ^M 's in the file;
- substract them
- */
- ascii_size -= lines;
- }
-
- ascii_data = malloc((ascii_size+1) * sizeof(char));
- fseek(fh, 0, SEEK_SET);
- fread(ascii_data, sizeof(char), ascii_size, fh);
- ascii_data[ascii_size] = '\0';
-
- if (DEBUG)
- printf("asciiblock is %ld bytes long:\n[%s]\n", ascii_size, ascii_data);
-
- /* calculate the hash checksum */
- RIPEMD160(ascii_data, ascii_size, md);
- free(ascii_data);
- mdhex = Hexify(md, RIPEMD160_DIGEST_LENGTH);
- }
-
- return(mdhex);
-}
-
-char *ReadHexCryptedData(FILE *fh, int *newlinetracker) {
- int HexCryptedDataLength = Hex5ToIntFp(fh, newlinetracker);
- int DataType = HexToIntFp(fh, newlinetracker);
- char *HexCryptedData = malloc((HexCryptedDataLength+1) * sizeof(char));
- int i;
-
- if (DataType != 1) {
- /* printf("Error: unexpected datatype for HexCryptedData\n"); */
- free(HexCryptedData);
- HexCryptedData = 0;
- } else {
- for (i=0; i<(HexCryptedDataLength/2); i++) {
- sprintf(HexCryptedData+2*i, "%02X", ReadHexByteFp(fh, newlinetracker));
- }
- }
-
- return(HexCryptedData);
-}
-
-char *ReadHexCryptedKey(FILE *fh, int *newlinetracker) {
- int HexCryptedKeyLength = Hex5ToIntFp(fh, newlinetracker);
- int DataType = HexToIntFp(fh, newlinetracker);
- char *HexCryptedKey = malloc((HexCryptedKeyLength+1) * sizeof(char));
- int i;
-
- if (DataType != 2) {
- /* printf("Error: unexpected datatype for HexCryptedKey\n"); */
- free(HexCryptedKey);
- HexCryptedKey = 0;
- } else {
- for (i=0; i<(HexCryptedKeyLength/2); i++) {
- sprintf(HexCryptedKey+2*i, "%02X", ReadHexByteFp(fh, newlinetracker));
- }
- }
-
- return(HexCryptedKey);
-}
-
-/* NOTE: CHANGE THIS INTO A KEY OF OUR OWN */
-void LoadRSApubKey(RSA *Pub) {
- static unsigned char n[] =
-"\xD1\x12\x0C\x6A\x34\x0A\xCF\x4C\x6B\x34\xA9\x3C\xDD\x1A\x2A\x68"
-"\x34\xE5\xB4\xA2\x08\xE8\x9F\xCE\x76\xEF\x4B\x92\x9B\x99\xB4\x57"
-"\x72\x95\x78\x1D\x9E\x21\x1B\xF9\x5C\x1B\x0E\xC9\xD0\x89\x75\x28"
-"\x08\x13\x6A\xD8\xA9\xC2\xA4\x31\x91\x53\x5A\xB9\x26\x71\x8C\x05";
- static unsigned char e[] =
-"\x01\x00\x01";
-/*
- static unsigned char e[] = "\x11";
- static unsigned char n[] =
-"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
-"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
-"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
-"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
-"\xF5";
-*/
-
- Pub->e = BN_bin2bn(e, sizeof(e)-1, Pub->e);
- Pub->n = BN_bin2bn(n, sizeof(n)-1, Pub->n);
-}
-
-byte *RSADecryptKey(char *HexCryptedKey) {
- byte *CryptedKey = NULL;
- byte *Key = NULL;
- int KeyLen;
- int CryptedKeyLen = strlen(HexCryptedKey)/2;
- RSA *Pub = NULL;
-
- /* Load RSA public key */
- Pub = RSA_new();
- if (Pub == NULL) {
- /* printf("Error in RSA_new\n"); */
- } else {
- LoadRSApubKey(Pub);
-
- Key = malloc(RSA_size(Pub) * sizeof(byte));
-
- CryptedKey = DeHexify(HexCryptedKey);
-
- KeyLen = RSA_public_decrypt(CryptedKeyLen, CryptedKey, Key, Pub,
- RSA_PKCS1_PADDING);
- if (DEBUG)
- printf("CryptedKeyLen = %d, KeyLen = %d\n", CryptedKeyLen, KeyLen);
- if (KeyLen == -1) {
-#ifndef NDEBUG
- printf("Error in RSA_public_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
-#endif
- free(Key);
- Key = NULL;
- }
- }
-
- return (Key);
-}
-
-char *DeCryptDatablock(byte *CryptKey, int keylen, char *HexCryptedData) {
- RC4_KEY key;
- byte *CryptedData = DeHexify(HexCryptedData);
- unsigned int datalen = strlen(HexCryptedData)/2;
- char *KeyDataString = malloc(datalen * sizeof(char));
-
- RC4_set_key(&key, keylen, CryptKey);
- RC4(&key, datalen, CryptedData, KeyDataString);
- free(CryptedData);
-
- return(KeyDataString);
-}
-
-char *get_from_datablock(char **DataPtr, char *TypeString) {
- int tstringsize = Hex5ToIntCp(DataPtr);
- int tstringtype = HexToIntCp(DataPtr);
- char *HexString = NULL;
-
- if (atoi(TypeString) != tstringtype) {
- /* printf("Unexpected type %d, expected %s\n", tstringtype, TypeString); */
- } else {
- HexString = malloc((tstringsize+1) * sizeof(char));
-
- strncpy(HexString, *DataPtr, tstringsize);
- *DataPtr += tstringsize;
- HexString[tstringsize] = '\0';
- }
-
- return(HexString);
-}
-
-int ReadKeyFile(char *filename, UserStruct *User,
- char **Priv, char **Pub, byte **Byte, char **Python) {
- FILE *rawkeyfile;
- char *HexAsciiHash = NULL, *HexCryptedData = NULL, *HexCryptedKey =
- NULL;
- int newlinetracker = 0; /* line position, counts from 0-71 */
- byte *CryptKey = NULL;
- char *KeyDataString = NULL;
- char *KeyDataPtr = NULL;
- char *HexByte = NULL;
- char *mdhex = NULL;
- int ret_val = 1;
-
- if ((rawkeyfile = fopen(filename, "rb")) == NULL) {
- /* printf("error, cannot read %s\n", filename); */
- } else {
- /* Scan and interpret the ASCII part */
- HexAsciiHash = scan_ascii(rawkeyfile, User);
- if (DEBUG) printf("\nHexHash: %s\n", HexAsciiHash);
-
- /* Read the HexCryptedData */
- HexCryptedData = ReadHexCryptedData(rawkeyfile, &newlinetracker);
- if (DEBUG) printf("\nHexCryptedData: %s\n", HexCryptedData);
-
- /* Read the HexCryptedKey */
- HexCryptedKey = ReadHexCryptedKey(rawkeyfile, &newlinetracker);
- if (DEBUG) printf("\nHexCryptedKey: %s\n", HexCryptedKey);
-
- /* close keyfile */
- fclose(rawkeyfile);
-
- if (HexAsciiHash && HexCryptedKey && HexCryptedData) {
- /* Decrypt HexCryptedKey */
- CryptKey = RSADecryptKey(HexCryptedKey);
-
- if (CryptKey) {
- /* Decrypt HexCryptedData */
- KeyDataString = DeCryptDatablock(CryptKey, 16, HexCryptedData);
- free(CryptKey);
- CryptKey = NULL;
-
- if (KeyDataString) {
- if (DEBUG) printf("\nKeyDataString: %s\n", KeyDataString);
-
- /* Extract data from KeyDataString */
- KeyDataPtr = KeyDataString;
- mdhex = get_from_datablock(&KeyDataPtr, "01");
- *Priv = get_from_datablock(&KeyDataPtr, "02");
- *Pub = get_from_datablock(&KeyDataPtr, "03");
- HexByte = get_from_datablock(&KeyDataPtr, "04");
- if (HexByte) {
- *Byte = DeHexify(HexByte);
- free(HexByte);
- HexByte = NULL;
-
- *Python = get_from_datablock(&KeyDataPtr, "05");
-
- /* Check ascii hash */
- if (strcmp(mdhex, HexAsciiHash) != 0) {
- /* printf("Ascii part checksums do not match !\n");
- printf("found: %s\n", mdhex);
- printf("check: %s\n", HexAsciiHash);
- */
- ret_val = 2;
- } else {
- if (DEBUG) printf("\nThe ascii part checksum matches\n");
- /* everything ok ! */
- ret_val = 0;
- }
- free(mdhex);
- mdhex = NULL;
- }
-
- free(KeyDataString);
- KeyDataString = NULL;
- }
- }
- }
-
- /* cleanup */
-
- if (HexAsciiHash) {
- free(HexAsciiHash);
- HexAsciiHash = NULL;
- }
-
- if (HexCryptedKey) {
- free(HexCryptedKey);
- HexCryptedKey = NULL;
- }
-
- if (HexCryptedData) {
- free(HexCryptedData);
- HexCryptedData = NULL;
- }
- }
-
- return (ret_val);
-}
-
diff --git a/intern/keymaker/key_internal.h b/intern/keymaker/key_internal.h
deleted file mode 100644
index 2bd60b9e9d8..00000000000
--- a/intern/keymaker/key_internal.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/* ex:ts=4 */
-
-/**
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Blender Key loader library internal stuff
- */
-
-#include "openssl/rand.h"
-#include "openssl/rsa.h"
-#include "openssl/ripemd.h"
-#include "openssl/rc4.h"
-#include "openssl/err.h"
-#include "blenkey.h"
-
-#include "mt19937int.h" /* Mersenne Twister (under artistic license) */
-
-#define MAXASCIIBLOCK 1000
-#define MAXBYTEDATABLOCK 1000
-
-#ifdef NDEBUG
- #define DEBUG 0
-#else
- #define DEBUG 1
-#endif
-
-/* keyloader and keymaker internal prototypes */
-int from_hex(char c);
-byte ReadHexByteFp(FILE *fh, int *newlinetracker);
-byte ReadHexByteCp(char **from);
-int HexToInt(int a);
-int HexToIntFp(FILE *fh, int *newlinetracker);
-int HexToIntCp(char **from);
-int Hex5ToInt(byte a, byte b, byte c, byte d, byte e);
-int Hex5ToIntFp(FILE *fh, int *newlinetracker);
-int Hex5ToIntCp(char **from);
-void pub_priv_test(char *HexPriv, char *HexPub);
-int main(int argc, char **argv);
-
-/* keyloader only internal prototypes */
-char *scan_ascii(FILE *fh, UserStruct *User);
-char *ReadHexCryptedData(FILE *fh, int *newlinetracker);
-char *ReadHexCryptedKey(FILE *fh, int *newlinetracker);
-void LoadRSApubKey(RSA *Pub);
-byte *RSADecryptKey(char *HexCryptedKey);
-char *DeCryptDatablock(byte *CryptKey, int keylen, char *HexCryptedData);
-char *get_from_datablock(char **DataPtr, char *TypeString);
-int Check_All_Byte_Calculus_Data(char *KeyBytePtr);
-
-/* keymaker only internal prototypes */
-void usage(void);
-char *Create_Ascii_Part(int argc, char **argv);
-void Create_User_RSA_Keys(unsigned int keylength,
- char **rsaPrivString, char **rsaPubString);
-char *Create_Byte_Calculus_Data(void);
-byte *CreateCryptKey(unsigned int size);
-char *CryptDatablock(byte *CryptKey, int keylen, char *KeyDataString);
-char *RSACryptKey(RSA *rsa, byte *CryptKey, int KeyLen);
-void add_to_datablock(char **DataString, char *HexString, char *TypeString);
-void LoadRSAprivKey(RSA *Priv);
-
diff --git a/intern/keymaker/keyloader.c b/intern/keymaker/keyloader.c
deleted file mode 100644
index 878ed319cb5..00000000000
--- a/intern/keymaker/keyloader.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/* ex:ts=4 */
-
-/**
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Blender Key Read-tester
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "key_pyc.h" /* the Python byte code */
-#include "blenkey.h" /* the external interface */
-#include "key_internal.h"
-
-#define TESTReadKeyFile 1
-
-int Check_All_Byte_Calculus_Data(char *KeyBytePtr) {
- int i;
-
- /* create some unique number arrays */
- int NoRealRandomArray[MAXBYTEDATABLOCK];
-
- typedef byte (*funcpoin)(byte, byte);
- funcpoin checkfunc[] = {&checkfunc0, &checkfunc1, &checkfunc2,
- &checkfunc3, &checkfunc4};
-
- byte *KeyByteData = DeHexify(KeyBytePtr);
-
- /* first create a fixed seed random number generator */
- sgenrand(666); /* seed it fixed */
-
- /* initialize arrays with unique numbers */
- for (i=0; i<MAXBYTEDATABLOCK; i++) {
- NoRealRandomArray[i] = i;
- }
- /* then stir the unique number lists */
- for (i=0; i<MAXBYTEDATABLOCK; i++) {
- unsigned long randswap = genrand();
- int swap1 = (int) (randswap % MAXBYTEDATABLOCK);
- int swap2 = (int) ((randswap>>16) % MAXBYTEDATABLOCK);
- int store = NoRealRandomArray[swap1];
- /* printf("%lu %d %d\n", randswap, swap1, swap2); */
- NoRealRandomArray[swap1] = NoRealRandomArray[swap2];
- NoRealRandomArray[swap2] = store;
- }
- if (DEBUG) {
- printf("\nFixed seed unique number random data: ");
- for (i=0; i<MAXBYTEDATABLOCK; i++) {
- printf("%d ", NoRealRandomArray[i]);
- }
- printf("\n\n");
- }
-
- /* check our byte calculus functions on the random data */
- for (i=0; i<(MAXBYTEDATABLOCK-3); i+=3) {
- if (DEBUG) {
- char *Pcheckfunc[] = {"max", " - ", " + ", " * ", " / "};
- printf("[%3d]=[%3d]%s[%3d] ",
- NoRealRandomArray[i], NoRealRandomArray[i+1],
- Pcheckfunc[NoRealRandomArray[i]%5], NoRealRandomArray[i+2]);
- printf("%3d%s%3d: %3d == %3d\n",
- KeyByteData[NoRealRandomArray[i+1]],
- Pcheckfunc[NoRealRandomArray[i]%5],
- KeyByteData[NoRealRandomArray[i+2]],
- KeyByteData[NoRealRandomArray[i]],
- checkfunc[(NoRealRandomArray[i]%5)](
- KeyByteData[NoRealRandomArray[i+1]],
- KeyByteData[NoRealRandomArray[i+2]]));
- }
- if (KeyByteData[NoRealRandomArray[i]] !=
- checkfunc[(NoRealRandomArray[i]%5)](
- KeyByteData[NoRealRandomArray[i+1]],
- KeyByteData[NoRealRandomArray[i+2]])) {
- printf("\nByte Checksum failed !\n");
- return (1);
- }
- }
- return (0);
-}
-
-void pub_priv_test(char *HexPriv, char *HexPub)
-{
- RSA *rsa = NULL;
- /* static unsigned char rsa_e[] = "\x11"; */
- static unsigned char rsa_e[] = "\x01\x00\x01";
- byte cryptKey[16];
- byte *cryptedKey;
- byte *pubKey, *privKey;
- int pubKeyLen, privKeyLen;
- int deCryptKeyLen;
- unsigned char *deCryptKey;
- int cryptKeyLen = 16;
- int cryptedKeyLen;
-
- strcpy(cryptKey, "abcdefghijklmno");
-
- pubKey = DeHexify(HexPub);
- pubKeyLen = strlen(HexPub) / 2;
-
- privKey = DeHexify(HexPriv);
- privKeyLen = strlen(HexPriv) / 2;
-
- rsa = RSA_new();
- if (rsa == NULL) {
- fprintf(stderr, "Error in RSA_new\n");
- exit(1);
- }
- rsa->e = BN_bin2bn(rsa_e, sizeof(rsa_e)-1, rsa->e);
- rsa->n = BN_bin2bn(pubKey, pubKeyLen, rsa->n);
- rsa->d = BN_bin2bn(privKey, privKeyLen, rsa->d);
-
- fprintf(stderr, "NOTE e %d, n %d, d %d rsa_size %d\n",
- sizeof(rsa_e)-1, pubKeyLen, privKeyLen, RSA_size(rsa));
-
- cryptedKey = malloc(RSA_size(rsa) * sizeof(byte));
- cryptedKeyLen = RSA_private_encrypt(cryptKeyLen, cryptKey,
- cryptedKey, rsa, RSA_PKCS1_PADDING);
-
- deCryptKey = malloc(RSA_size(rsa) * sizeof(unsigned char));
- deCryptKeyLen = RSA_public_decrypt(cryptedKeyLen, cryptedKey,
- deCryptKey, rsa, RSA_PKCS1_PADDING);
- if (deCryptKeyLen == -1) {
- printf("Error in RSA_public_decrypt: %s\n",
- ERR_error_string(ERR_get_error(), NULL));
- exit(1);
- } else {
- printf("RSA_public_decrypt test SUCCEEDED\n");
- }
-
-}
-
-#ifdef TESTReadKeyFile
-int main(int argc, char **argv) {
- int result;
- UserStruct User;
- char *HexPriv = NULL, *HexPub = NULL, *HexPython = NULL;
- byte *Byte = NULL;
- byte *PythonData = NULL;
- int PythonLength;
- char *HexByte = NULL;
-
- if (argc != 2) {
- printf("usage: %s keyfile\n", argv[0]);
- exit(1);
- }
-
- result = ReadKeyFile(argv[1], &User, &HexPriv, &HexPub, &Byte, &HexPython);
- if (result != 0) {
- printf("\nReadKeyFile error %d\n", result);
- exit(result);
- } else {
- printf("\nReadKeyFile OK\n");
- }
-
- /* just print the rsaPrivString and rsaPubString */
- if (DEBUG) printf("\nrsaPrivString: %s\n", HexPriv);
- if (DEBUG) printf("\nrsaPubString: %s\n", HexPub);
-
- /* try to private encrypt-public decrypt something */
- if (DEBUG) pub_priv_test(HexPriv, HexPub);
-
- /* check all the Byte checksums
- rehexify it for our Check_All_Byte_Calculus_Data function ... */
- HexByte = Hexify(Byte, 1000);
- if (Check_All_Byte_Calculus_Data(HexByte) != 0) {
- printf("\nByte_Calculus_Data checksums do not match !\n");
- exit(1);
- } else {
- if (DEBUG) printf("\nThe Byte Calculus Data checksums match\n");
- }
-
- /* Check the KeyPythonPtr */
- PythonLength = strlen(HexPython)/2;
- PythonData = DeHexify(HexPython);
- if (memcmp(PythonData, g_keycode, PythonLength) != 0) {
- printf("\nPython Byte code datablocks do not match !\n");
- exit(1);
- } else {
- if (DEBUG) printf("\nThe Python Byte code datablock matches\n");
- }
-
- return(0);
-}
-#else
-int main(int argc, char **argv) {
- FILE *rawkeyfile;
- char *AsciiHash;
- char *HexCryptedData, *HexCryptedKey;
- int newlinetracker = 0; /* line position, counts from 0-71 */
- byte *CryptKey;
- char *KeyDataString;
- char *KeyDataPtr;
- char *mdhex;
- char *rsaPrivString;
- char *rsaPubString;
- char *KeyBytePtr;
- char *KeyPythonPtr;
- byte *PythonData;
- int PythonLength;
- UserStruct User;
-
- if (argc != 2) {
- printf("usage: %s keyfile\n", argv[0]);
- exit(1);
- }
-
- /* open keyfile for reading */
- if ((rawkeyfile = fopen(argv[1], "r")) == NULL) {
- printf("error, cannot read %s\n", argv[1]);
- exit(1);
- }
-
- /* Scan and interpret the ASCII part */
- AsciiHash = scan_ascii(rawkeyfile, &User);
- if (DEBUG) printf("\nHexHash: %s\n", AsciiHash);
-
- /* Read the HexCryptedData */
- HexCryptedData = ReadHexCryptedData(rawkeyfile, &newlinetracker);
- if (DEBUG) printf("\nHexCryptedData: %s\n", HexCryptedData);
-
- /* Read the HexCryptedKey */
- HexCryptedKey = ReadHexCryptedKey(rawkeyfile, &newlinetracker);
- if (DEBUG) printf("\nHexCryptedKey: %s\n", HexCryptedKey);
-
- /* close keyfile */
- fclose(rawkeyfile);
-
- /* Decrypt HexCryptedKey */
- CryptKey = RSADecryptKey(HexCryptedKey);
-
- /* Decrypt HexCryptedData */
- KeyDataString = DeCryptDatablock(CryptKey, 16, HexCryptedData);
- free(CryptKey);
- free(HexCryptedData);
- free(HexCryptedKey);
- if (DEBUG) printf("\nKeyDataString: %s\n", KeyDataString);
-
- /* Extract data from KeyDataString */
- KeyDataPtr = KeyDataString;
-
- mdhex = get_from_datablock(&KeyDataPtr, "01");
- rsaPrivString = get_from_datablock(&KeyDataPtr, "02");
- rsaPubString = get_from_datablock(&KeyDataPtr, "03");
- KeyBytePtr = get_from_datablock(&KeyDataPtr, "04");
- KeyPythonPtr = get_from_datablock(&KeyDataPtr, "05");
- free(KeyDataString);
-
- /* Check ascii hash */
- if (strcmp(mdhex, AsciiHash) != 0) {
- printf("Ascii part checksums do not match !\n");
- printf("found: %s\n", mdhex);
- printf("check: %s\n", AsciiHash);
- exit(1);
- } else {
- if (DEBUG) printf("\nThe ascii part checksum matches\n");
- }
-
- /* just print the rsaPrivString and rsaPubString */
- if (DEBUG) printf("\nrsaPrivString: %s\n", rsaPrivString);
- if (DEBUG) printf("\nrsaPubString: %s\n", rsaPubString);
-
- /* check all the Byte checksums */
- if (Check_All_Byte_Calculus_Data(KeyBytePtr) != 0) {
- printf("Byte_Calculus_Data checksums do not match !\n");
- exit(1);
- } else {
- if (DEBUG) printf("\nThe Byte Calculus Data checksums match\n");
- }
-
- /* Check the KeyPythonPtr */
- PythonLength = strlen(KeyPythonPtr)/2;
- PythonData = DeHexify(KeyPythonPtr);
- if (memcmp(PythonData, g_keycode, PythonLength) != 0) {
- printf("Python Byte code datablocks do not match !\n");
- exit(1);
- } else {
- if (DEBUG) printf("\nThe Python Byte code datablock matches\n");
- }
-
- return(0);
-}
-#endif
diff --git a/intern/keymaker/make/msvc_6_0/blenkey.dsp b/intern/keymaker/make/msvc_6_0/blenkey.dsp
deleted file mode 100644
index 4cc63f9fc24..00000000000
--- a/intern/keymaker/make/msvc_6_0/blenkey.dsp
+++ /dev/null
@@ -1,134 +0,0 @@
-# Microsoft Developer Studio Project File - Name="blenkey" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=blenkey - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "blenkey.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "blenkey.mak" CFG="blenkey - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "blenkey - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "blenkey - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "blenkey - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\blenkey\"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\blenkey\"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "..\.." /I "..\..\..\..\..\lib\windows\openssl\include" /I "..\..\python" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\blenkey\libblenkey.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\lib\windows\blenkey\include\ ECHO Copying lib XCOPY /Y ..\..\..\..\obj\windows\intern\blenkey\*.lib ..\..\..\..\..\lib\windows\blenkey\lib\*.a ECHO Done
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "blenkey - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\blenkey\debug"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\blenkey\debug"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\..\..\..\lib\windows\openssl\include" /I "..\..\python" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\blenkey\debug\libblenkey.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\lib\windows\blenkey\include\ ECHO Copying lib XCOPY /Y ..\..\..\..\obj\windows\intern\blenkey\debug\*.lib ..\..\..\..\..\lib\windows\blenkey\lib\debug\*.a
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "blenkey - Win32 Release"
-# Name "blenkey - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\key.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\keyloader.c
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\mt19937int.c
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Group "intern"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\key_internal.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\mt19937int.h
-# End Source File
-# End Group
-# Begin Group "extern"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\blenkey.h
-# End Source File
-# End Group
-# End Group
-# End Target
-# End Project
diff --git a/intern/keymaker/make/msvc_6_0/blenkey.dsw b/intern/keymaker/make/msvc_6_0/blenkey.dsw
deleted file mode 100644
index 4d97144c6ed..00000000000
--- a/intern/keymaker/make/msvc_6_0/blenkey.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "blenkey"=".\blenkey.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/intern/keymaker/make/msvc_7_0/blenkey.sln b/intern/keymaker/make/msvc_7_0/blenkey.sln
deleted file mode 100644
index 5ddf040506e..00000000000
--- a/intern/keymaker/make/msvc_7_0/blenkey.sln
+++ /dev/null
@@ -1,21 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenkey", "blenkey.vcproj", "{E8AF94A5-15FC-432C-9FFD-68D9CD642488}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = Debug
- ConfigName.1 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {E8AF94A5-15FC-432C-9FFD-68D9CD642488}.Debug.ActiveCfg = Debug|Win32
- {E8AF94A5-15FC-432C-9FFD-68D9CD642488}.Debug.Build.0 = Debug|Win32
- {E8AF94A5-15FC-432C-9FFD-68D9CD642488}.Release.ActiveCfg = Release|Win32
- {E8AF94A5-15FC-432C-9FFD-68D9CD642488}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/intern/keymaker/make/msvc_7_0/blenkey.vcproj b/intern/keymaker/make/msvc_7_0/blenkey.vcproj
deleted file mode 100644
index df24f3da382..00000000000
--- a/intern/keymaker/make/msvc_7_0/blenkey.vcproj
+++ /dev/null
@@ -1,282 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="blenkey"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\python;..\..\..\..\..\lib\windows\openssl\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\blenkey\debug\blenkey.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\blenkey\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\blenkey\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\blenkey\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\debug\libblenkey.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying BLENKEY files library (debug target) to lib tree"
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\blenkey\include MKDIR ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\python;..\..\..\..\..\lib\windows\openssl\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\blenkey\blenkey.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\blenkey\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\blenkey\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\blenkey\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\libblenkey.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying BLENKEY files library to lib tree"
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\blenkey\include MKDIR ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\python;..\..\..\..\..\lib\windows\openssl\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\blenkey.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\mtdll\libblenkey.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying BLENKEY files library to lib tree"
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\blenkey\include MKDIR ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\python;..\..\..\..\..\lib\windows\openssl\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug\blenkey.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\blenkey\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\mtdll\debug\libblenkey.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying BLENKEY files library (debug target) to lib tree"
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\blenkey\include MKDIR ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-XCOPY /Y ..\..\blenkey.h ..\..\..\..\..\build\msvc_7\intern\blenkey\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="..\..\key.c">
- </File>
- <File
- RelativePath="..\..\keyloader.c">
- </File>
- <File
- RelativePath="..\..\mt19937int.c">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <Filter
- Name="intern"
- Filter="">
- <File
- RelativePath="..\..\key_internal.h">
- </File>
- <File
- RelativePath="..\..\mt19937int.h">
- </File>
- </Filter>
- <Filter
- Name="extern"
- Filter="">
- <File
- RelativePath="..\..\blenkey.h">
- </File>
- </Filter>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/keymaker/mt19937int.c b/intern/keymaker/mt19937int.c
deleted file mode 100644
index 9481a48aade..00000000000
--- a/intern/keymaker/mt19937int.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* A C-program for MT19937: Integer version (1999/10/28) */
-
-/* genrand() generates one pseudorandom unsigned integer (32bit) */
-/* which is uniformly distributed among 0 to 2^32-1 for each */
-/* call. sgenrand(seed) sets initial values to the working area */
-/* of 624 words. Before genrand(), sgenrand(seed) must be */
-/* called once. (seed is any 32-bit integer.) */
-/* Coded by Takuji Nishimura, considering the suggestions by */
-/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
-
-/* This library is free software under the Artistic license: */
-/* see the file COPYING distributed together with this code. */
-/* For the verification of the code, its output sequence file */
-/* mt19937int.out is attached (2001/4/2) */
-
-/* Copyright (C) 1997, 1999 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 */
-
-/* REFERENCE */
-/* M. Matsumoto and T. Nishimura, */
-/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */
-/* Pseudo-Random Number Generator", */
-/* ACM Transactions on Modeling and Computer Simulation, */
-/* Vol. 8, No. 1, January 1998, pp 3--30. */
-
-#include<stdio.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "mt19937int.h"
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0df /* constant vector a */
-#define UPPER_MASK 0x80000000 /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffff /* least significant r bits */
-
-/* Tempering parameters */
-#define TEMPERING_MASK_B 0x9d2c5680
-#define TEMPERING_MASK_C 0xefc60000
-#define TEMPERING_SHIFT_U(y) (y >> 11)
-#define TEMPERING_SHIFT_S(y) (y << 7)
-#define TEMPERING_SHIFT_T(y) (y << 15)
-#define TEMPERING_SHIFT_L(y) (y >> 18)
-
-static unsigned long mt[N]; /* the array for the state vector */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-
-/* Initializing the array with a seed */
-void sgenrand(signed long seed)
-{
- int i;
-
- for (i=0;i<N;i++) {
- mt[i] = seed & 0xffff0000;
- seed = 69069 * seed + 1;
- mt[i] |= (seed & 0xffff0000) >> 16;
- seed = 69069 * seed + 1;
- }
- mti = N;
-}
-
-/* Initialization by "sgenrand()" is an example. Theoretically, */
-/* there are 2^19937-1 possible states as an intial state. */
-/* This function allows to choose any of 2^19937-1 ones. */
-/* Essential bits in "seed_array[]" is following 19937 bits: */
-/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]. */
-/* (seed_array[0]&LOWER_MASK) is discarded. */
-/* Theoretically, */
-/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1] */
-/* can take any values except all zeros. */
-void lsgenrand(unsigned long *seed_array)
- /* the length of seed_array[] must be at least N */
-{
- int i;
-
- for (i=0;i<N;i++)
- mt[i] = seed_array[i];
- mti=N;
-}
-
-unsigned long genrand()
-{
- unsigned long y;
- static unsigned long mag01[2]={0x0, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
-
- if (mti >= N) { /* generate N words at one time */
- int kk;
-
- if (mti == N+1) /* if sgenrand() has not been called, */
- sgenrand(4357); /* a default initial seed is used */
-
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
- }
- for (;kk<N-1;kk++) {
- 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++];
- 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 y;
-}
-
-/* This main() outputs first 1000 generated numbers. */
-/*
-main()
-{
- int i;
-
- sgenrand(4357);
- for (i=0; i<1000; i++) {
- printf("%10lu ", genrand());
- if (i%5==4) printf("\n");
- }
-}
-*/
diff --git a/intern/keymaker/python/key_pyc.h b/intern/keymaker/python/key_pyc.h
deleted file mode 100644
index 16dd15f6e86..00000000000
--- a/intern/keymaker/python/key_pyc.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
-
-/* generated by keygen.py -- don't edit !! */
-
-
-#define KEYCODELEN 1157
-static unsigned char g_keycode[] = {
- 0x63,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x73,
- 0xb3,0x00,0x00,0x00,0x7f,0x00,0x00,0x7f,0x02,0x00,
- 0x64,0x00,0x00,0x6b,0x00,0x00,0x5a,0x00,0x00,0x7f,
- 0x06,0x00,0x64,0x01,0x00,0x84,0x00,0x00,0x5a,0x01,
- 0x00,0x7f,0x09,0x00,0x64,0x02,0x00,0x84,0x00,0x00,
- 0x5a,0x02,0x00,0x7f,0x11,0x00,0x64,0x03,0x00,0x84,
- 0x00,0x00,0x5a,0x03,0x00,0x7f,0x1c,0x00,0x65,0x00,
- 0x00,0x69,0x04,0x00,0x83,0x00,0x00,0x5a,0x05,0x00,
- 0x7f,0x1d,0x00,0x7f,0x21,0x00,0x65,0x00,0x00,0x69,
- 0x06,0x00,0x83,0x00,0x00,0x5a,0x07,0x00,0x7f,0x22,
- 0x00,0x65,0x08,0x00,0x65,0x07,0x00,0x83,0x01,0x00,
- 0x5a,0x09,0x00,0x7f,0x23,0x00,0x65,0x03,0x00,0x65,
- 0x09,0x00,0x83,0x01,0x00,0x01,0x7f,0x24,0x00,0x78,
- 0x39,0x00,0x65,0x0a,0x00,0x65,0x07,0x00,0x83,0x01,
- 0x00,0x64,0x04,0x00,0x7f,0x24,0x00,0x72,0x26,0x00,
- 0x5a,0x0b,0x00,0x7f,0x25,0x00,0x65,0x00,0x00,0x69,
- 0x0c,0x00,0x65,0x09,0x00,0x65,0x0b,0x00,0x19,0x65,
- 0x00,0x00,0x69,0x0d,0x00,0x65,0x0b,0x00,0x83,0x01,
- 0x00,0x83,0x02,0x00,0x01,0x71,0x82,0x00,0x57,0x64,
- 0x00,0x00,0x53,0x28,0x05,0x00,0x00,0x00,0x4e,0x63,
- 0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x73,0x1c,
- 0x00,0x00,0x00,0x7f,0x06,0x00,0x7f,0x07,0x00,0x7f,
- 0x08,0x00,0x7c,0x00,0x00,0x7c,0x01,0x00,0x7c,0x02,
- 0x00,0x66,0x03,0x00,0x61,0x03,0x00,0x64,0x00,0x00,
- 0x53,0x28,0x01,0x00,0x00,0x00,0x4e,0x28,0x04,0x00,
- 0x00,0x00,0x73,0x01,0x00,0x00,0x00,0x61,0x73,0x01,
- 0x00,0x00,0x00,0x62,0x73,0x01,0x00,0x00,0x00,0x63,
- 0x73,0x05,0x00,0x00,0x00,0x5f,0x73,0x65,0x65,0x64,
- 0x28,0x03,0x00,0x00,0x00,0x73,0x01,0x00,0x00,0x00,
- 0x61,0x73,0x01,0x00,0x00,0x00,0x62,0x73,0x01,0x00,
- 0x00,0x00,0x63,0x73,0x08,0x00,0x00,0x00,0x3c,0x73,
- 0x74,0x72,0x69,0x6e,0x67,0x3e,0x73,0x04,0x00,0x00,
- 0x00,0x73,0x65,0x65,0x64,0x06,0x00,0x73,0x04,0x00,
- 0x00,0x00,0x03,0x01,0x03,0x01,0x63,0x00,0x00,0x03,
- 0x00,0x03,0x00,0x03,0x00,0x73,0x70,0x00,0x00,0x00,
- 0x7f,0x09,0x00,0x7f,0x0a,0x00,0x7f,0x0b,0x00,0x74,
- 0x00,0x00,0x5c,0x03,0x00,0x7d,0x00,0x00,0x7d,0x01,
- 0x00,0x7d,0x02,0x00,0x7f,0x0c,0x00,0x64,0x01,0x00,
- 0x7c,0x00,0x00,0x14,0x64,0x02,0x00,0x16,0x7d,0x00,
- 0x00,0x7f,0x0d,0x00,0x64,0x03,0x00,0x7c,0x01,0x00,
- 0x14,0x64,0x04,0x00,0x16,0x7d,0x01,0x00,0x7f,0x0e,
- 0x00,0x64,0x05,0x00,0x7c,0x02,0x00,0x14,0x64,0x06,
- 0x00,0x16,0x7d,0x02,0x00,0x7f,0x0f,0x00,0x7c,0x00,
- 0x00,0x7c,0x01,0x00,0x7c,0x02,0x00,0x66,0x03,0x00,
- 0x61,0x00,0x00,0x7f,0x10,0x00,0x7c,0x00,0x00,0x7c,
- 0x01,0x00,0x17,0x7c,0x02,0x00,0x17,0x53,0x64,0x00,
- 0x00,0x53,0x28,0x07,0x00,0x00,0x00,0x4e,0x69,0xab,
- 0x00,0x00,0x00,0x69,0x3d,0x76,0x00,0x00,0x69,0xac,
- 0x00,0x00,0x00,0x69,0x63,0x76,0x00,0x00,0x69,0xaa,
- 0x00,0x00,0x00,0x69,0x73,0x76,0x00,0x00,0x28,0x04,
- 0x00,0x00,0x00,0x73,0x05,0x00,0x00,0x00,0x5f,0x73,
- 0x65,0x65,0x64,0x73,0x01,0x00,0x00,0x00,0x61,0x73,
- 0x01,0x00,0x00,0x00,0x62,0x73,0x01,0x00,0x00,0x00,
- 0x63,0x28,0x03,0x00,0x00,0x00,0x73,0x01,0x00,0x00,
- 0x00,0x61,0x73,0x01,0x00,0x00,0x00,0x62,0x73,0x01,
- 0x00,0x00,0x00,0x63,0x73,0x08,0x00,0x00,0x00,0x3c,
- 0x73,0x74,0x72,0x69,0x6e,0x67,0x3e,0x73,0x09,0x00,
- 0x00,0x00,0x72,0x61,0x6e,0x64,0x6f,0x6d,0x69,0x7a,
- 0x65,0x09,0x00,0x73,0x0e,0x00,0x00,0x00,0x03,0x01,
- 0x03,0x01,0x12,0x01,0x11,0x01,0x11,0x01,0x11,0x01,
- 0x12,0x01,0x63,0x01,0x00,0x06,0x00,0x06,0x00,0x03,
- 0x00,0x73,0x8b,0x00,0x00,0x00,0x7f,0x11,0x00,0x7f,
- 0x13,0x00,0x74,0x00,0x00,0x7c,0x00,0x00,0x83,0x01,
- 0x00,0x7d,0x01,0x00,0x7f,0x14,0x00,0x78,0x6f,0x00,
- 0x74,0x03,0x00,0x7c,0x01,0x00,0x83,0x01,0x00,0x64,
- 0x01,0x00,0x7f,0x14,0x00,0x72,0x5c,0x00,0x7d,0x02,
- 0x00,0x7f,0x15,0x00,0x7c,0x01,0x00,0x7c,0x02,0x00,
- 0x18,0x7d,0x03,0x00,0x7f,0x16,0x00,0x74,0x06,0x00,
- 0x74,0x07,0x00,0x83,0x00,0x00,0x7c,0x03,0x00,0x16,
- 0x83,0x01,0x00,0x7d,0x04,0x00,0x7f,0x17,0x00,0x7c,
- 0x00,0x00,0x7c,0x02,0x00,0x19,0x7d,0x05,0x00,0x7f,
- 0x18,0x00,0x7c,0x00,0x00,0x7c,0x02,0x00,0x7c,0x04,
- 0x00,0x17,0x19,0x7c,0x00,0x00,0x7c,0x02,0x00,0x3c,
- 0x7f,0x19,0x00,0x7c,0x05,0x00,0x7c,0x00,0x00,0x7c,
- 0x02,0x00,0x7c,0x04,0x00,0x17,0x3c,0x71,0x24,0x00,
- 0x57,0x64,0x00,0x00,0x53,0x28,0x02,0x00,0x00,0x00,
- 0x4e,0x69,0x00,0x00,0x00,0x00,0x28,0x0a,0x00,0x00,
- 0x00,0x73,0x03,0x00,0x00,0x00,0x6c,0x65,0x6e,0x73,
- 0x04,0x00,0x00,0x00,0x6c,0x69,0x73,0x74,0x73,0x04,
- 0x00,0x00,0x00,0x73,0x69,0x7a,0x65,0x73,0x06,0x00,
- 0x00,0x00,0x78,0x72,0x61,0x6e,0x67,0x65,0x73,0x01,
- 0x00,0x00,0x00,0x69,0x73,0x04,0x00,0x00,0x00,0x6c,
- 0x65,0x66,0x74,0x73,0x03,0x00,0x00,0x00,0x69,0x6e,
- 0x74,0x73,0x09,0x00,0x00,0x00,0x72,0x61,0x6e,0x64,
- 0x6f,0x6d,0x69,0x7a,0x65,0x73,0x01,0x00,0x00,0x00,
- 0x72,0x73,0x03,0x00,0x00,0x00,0x74,0x6d,0x70,0x28,
- 0x06,0x00,0x00,0x00,0x73,0x04,0x00,0x00,0x00,0x6c,
- 0x69,0x73,0x74,0x73,0x04,0x00,0x00,0x00,0x73,0x69,
- 0x7a,0x65,0x73,0x01,0x00,0x00,0x00,0x69,0x73,0x04,
- 0x00,0x00,0x00,0x6c,0x65,0x66,0x74,0x73,0x01,0x00,
- 0x00,0x00,0x72,0x73,0x03,0x00,0x00,0x00,0x74,0x6d,
- 0x70,0x73,0x08,0x00,0x00,0x00,0x3c,0x73,0x74,0x72,
- 0x69,0x6e,0x67,0x3e,0x73,0x04,0x00,0x00,0x00,0x73,
- 0x74,0x69,0x72,0x11,0x00,0x73,0x10,0x00,0x00,0x00,
- 0x03,0x02,0x0f,0x01,0x12,0x00,0x09,0x01,0x0d,0x01,
- 0x16,0x01,0x0d,0x01,0x15,0x01,0x69,0x00,0x00,0x00,
- 0x00,0x28,0x0e,0x00,0x00,0x00,0x73,0x04,0x00,0x00,
- 0x00,0x70,0x72,0x6f,0x74,0x73,0x04,0x00,0x00,0x00,
- 0x73,0x65,0x65,0x64,0x73,0x09,0x00,0x00,0x00,0x72,
- 0x61,0x6e,0x64,0x6f,0x6d,0x69,0x7a,0x65,0x73,0x04,
- 0x00,0x00,0x00,0x73,0x74,0x69,0x72,0x73,0x07,0x00,
- 0x00,0x00,0x67,0x65,0x74,0x73,0x65,0x65,0x64,0x73,
- 0x05,0x00,0x00,0x00,0x5f,0x73,0x65,0x65,0x64,0x73,
- 0x06,0x00,0x00,0x00,0x67,0x65,0x74,0x6c,0x65,0x6e,
- 0x73,0x01,0x00,0x00,0x00,0x6e,0x73,0x05,0x00,0x00,
- 0x00,0x72,0x61,0x6e,0x67,0x65,0x73,0x04,0x00,0x00,
- 0x00,0x6c,0x69,0x73,0x74,0x73,0x06,0x00,0x00,0x00,
- 0x78,0x72,0x61,0x6e,0x67,0x65,0x73,0x01,0x00,0x00,
- 0x00,0x69,0x73,0x06,0x00,0x00,0x00,0x73,0x65,0x74,
- 0x70,0x74,0x72,0x73,0x06,0x00,0x00,0x00,0x67,0x65,
- 0x74,0x70,0x74,0x72,0x28,0x00,0x00,0x00,0x00,0x73,
- 0x08,0x00,0x00,0x00,0x3c,0x73,0x74,0x72,0x69,0x6e,
- 0x67,0x3e,0x73,0x01,0x00,0x00,0x00,0x3f,0x02,0x00,
- 0x73,0x16,0x00,0x00,0x00,0x0f,0x04,0x0c,0x03,0x0c,
- 0x08,0x0c,0x0b,0x0f,0x01,0x03,0x04,0x0f,0x01,0x0f,
- 0x01,0x0d,0x01,0x12,0x00,0x09,0x01
-};
-
diff --git a/intern/make/msvc_7_0/intern.sln b/intern/make/msvc_7_0/intern.sln
index 146a0297dc1..5fdb4ca95d0 100644
--- a/intern/make/msvc_7_0/intern.sln
+++ b/intern/make/msvc_7_0/intern.sln
@@ -8,7 +8,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "build_install_all", "build_
{B093415D-C0F6-4E76-8F5A-6BC1917BCE9E} = {B093415D-C0F6-4E76-8F5A-6BC1917BCE9E}
{E784098D-3ED8-433A-9353-9679415DDDC5} = {E784098D-3ED8-433A-9353-9679415DDDC5}
{76D90B92-ECC7-409C-9F98-A8814B90F3C0} = {76D90B92-ECC7-409C-9F98-A8814B90F3C0}
- {121EC196-8E8A-4937-B0BD-0F114C87D55E} = {121EC196-8E8A-4937-B0BD-0F114C87D55E}
{542A9FA1-B7FF-441C-AE15-054DB31D3488} = {542A9FA1-B7FF-441C-AE15-054DB31D3488}
{213356A9-3A1F-41DA-9819-1297BCD17DEE} = {213356A9-3A1F-41DA-9819-1297BCD17DEE}
{51A348C1-8684-4D67-B980-97B1FC74159B} = {51A348C1-8684-4D67-B980-97B1FC74159B}
@@ -24,10 +23,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MoTo", "..\..\moto\make\msv
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenkey", "..\..\keymaker\make\msvc_7_0\blenkey.vcproj", "{121EC196-8E8A-4937-B0BD-0F114C87D55E}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bmfont", "..\..\bmfont\make\msvc_7_0\bmfont.vcproj", "{E784098D-3ED8-433A-9353-9679415DDDC5}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -110,6 +105,8 @@ Global
Blender Debug = Blender Debug
Blender Release = Blender Release
EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{02110D03-59DB-4571-8787-72B3C03B2F2D}.3DPlugin Debug.ActiveCfg = 3DPlugin Debug|Win32
{02110D03-59DB-4571-8787-72B3C03B2F2D}.3DPlugin Debug.Build.0 = 3DPlugin Debug|Win32
@@ -127,14 +124,6 @@ Global
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74}.Blender Debug.Build.0 = Blender Debug|Win32
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74}.Blender Release.ActiveCfg = Blender Release|Win32
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74}.Blender Release.Build.0 = Blender Release|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.3DPlugin Debug.ActiveCfg = 3DPlugin Debug|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.3DPlugin Debug.Build.0 = 3DPlugin Debug|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.3DPlugin Release.ActiveCfg = 3DPlugin Release|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.3DPlugin Release.Build.0 = 3DPlugin Release|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.Blender Debug.ActiveCfg = Blender Debug|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.Blender Debug.Build.0 = Blender Debug|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.Blender Release.ActiveCfg = Blender Release|Win32
- {121EC196-8E8A-4937-B0BD-0F114C87D55E}.Blender Release.Build.0 = Blender Release|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.3DPlugin Debug.ActiveCfg = 3DPlugin Debug|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.3DPlugin Debug.Build.0 = 3DPlugin Debug|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.3DPlugin Release.ActiveCfg = 3DPlugin Release|Win32
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index c1c805b6310..13fb6b23446 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -68,6 +68,7 @@ extern "C" {
extern int MEM_CacheLimiter_get_maximum();
// this is rather _ugly_!
extern int mem_in_use;
+ extern int mmap_in_use;
};
#endif
@@ -148,7 +149,7 @@ public:
return;
}
for (iterator it = queue.begin();
- it != queue.end() && mem_in_use > max;) {
+ it != queue.end() && mem_in_use + mmap_in_use > max;) {
iterator jt = it;
++it;
(*jt)->destroy_if_possible();
diff --git a/intern/moto/include/MT_Matrix3x3.h b/intern/moto/include/MT_Matrix3x3.h
index fb899a7da96..98851e73040 100755..100644
--- a/intern/moto/include/MT_Matrix3x3.h
+++ b/intern/moto/include/MT_Matrix3x3.h
@@ -147,6 +147,26 @@ public:
-sj, cj * si, cj * ci);
}
+ void getEuler(MT_Scalar& yaw, MT_Scalar& pitch, MT_Scalar& roll) const
+ {
+ if (m_el[2][0] != -1.0 && m_el[2][0] != 1.0) {
+ pitch = MT_Scalar(-asin(m_el[2][0]));
+ yaw = MT_Scalar(atan2(m_el[2][1] / cos(pitch), m_el[2][2] / cos(pitch)));
+ roll = MT_Scalar(atan2(m_el[1][0] / cos(pitch), m_el[0][0] / cos(pitch)));
+ }
+ else {
+ roll = MT_Scalar(0);
+ if (m_el[2][0] == -1.0) {
+ pitch = MT_PI / 2.0;
+ yaw = MT_Scalar(atan2(m_el[0][1], m_el[0][2]));
+ }
+ else {
+ pitch = - MT_PI / 2.0;
+ yaw = MT_Scalar(atan2(m_el[0][1], m_el[0][2]));
+ }
+ }
+ }
+
void scale(MT_Scalar x, MT_Scalar y, MT_Scalar z) {
m_el[0][0] *= x; m_el[0][1] *= y; m_el[0][2] *= z;
m_el[1][0] *= x; m_el[1][1] *= y; m_el[1][2] *= z;
diff --git a/intern/moto/include/MT_Vector3.h b/intern/moto/include/MT_Vector3.h
index 41291e915be..c35a9d47234 100644
--- a/intern/moto/include/MT_Vector3.h
+++ b/intern/moto/include/MT_Vector3.h
@@ -51,6 +51,7 @@
class MT_Vector3 : public MT_Tuple3 {
public:
+ virtual ~MT_Vector3() {}
MT_Vector3() {}
MT_Vector3(const float *v) : MT_Tuple3(v) {}
MT_Vector3(const double *v) : MT_Tuple3(v) {}
diff --git a/intern/moto/include/MT_Vector4.h b/intern/moto/include/MT_Vector4.h
index fa91abf2a84..5f1ee99d584 100644
--- a/intern/moto/include/MT_Vector4.h
+++ b/intern/moto/include/MT_Vector4.h
@@ -52,6 +52,7 @@
class MT_Vector4 : public MT_Tuple4 {
public:
+ virtual ~MT_Vector4() {}
MT_Vector4() {}
MT_Vector4(const float *v) : MT_Tuple4(v) {}
MT_Vector4(const double *v) : MT_Tuple4(v) {}
diff --git a/intern/moto/include/MT_assert.h b/intern/moto/include/MT_assert.h
index c20f5699ea3..54aea403cda 100644
--- a/intern/moto/include/MT_assert.h
+++ b/intern/moto/include/MT_assert.h
@@ -48,7 +48,7 @@
// file, line, predicate form the message to ask, *do_assert should be set
// to 0 to ignore.
// returns 1 to break, false to ignore
-MT_CDECL int MT_QueryAssert(char *file, int line, char *predicate, int *do_assert);
+MT_CDECL int MT_QueryAssert(const char *file, int line, const char *predicate, int *do_assert);
#ifdef NDEBUG
diff --git a/intern/moto/intern/MT_Assert.cpp b/intern/moto/intern/MT_Assert.cpp
index 999e3da5842..c16c43f2045 100644
--- a/intern/moto/intern/MT_Assert.cpp
+++ b/intern/moto/intern/MT_Assert.cpp
@@ -45,7 +45,7 @@
// Query the user if they want to break/abort the program, ignore the assert, or ignore all future
// occurance of the assert.
-int MT_QueryAssert(char *file, int line, char *predicate, int *do_assert)
+int MT_QueryAssert(const char *file, int line, const char *predicate, int *do_assert)
{
#ifdef _WIN32
if (*do_assert)
diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript
index bcfb030f7e6..e46cefbff58 100644
--- a/intern/opennl/SConscript
+++ b/intern/opennl/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
incs = 'extern superlu'
if (env['OURPLATFORM'] == 'win32-mingw'):
- env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core','intern'], priority=[1,80] )
+ env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core','intern','player'], priority=[1,80,22] )
else:
- env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype='core', priority=55 )
+ env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core','player'], priority=[55,22] )
diff --git a/intern/opennl/extern/ONL_opennl.h b/intern/opennl/extern/ONL_opennl.h
index 345cf0dc717..be76aa95eac 100644
--- a/intern/opennl/extern/ONL_opennl.h
+++ b/intern/opennl/extern/ONL_opennl.h
@@ -79,20 +79,16 @@ typedef void* NLContext;
#define NL_SYSTEM 0x0
#define NL_MATRIX 0x1
-#define NL_ROW 0x2
/* Solver Parameters */
-#define NL_SOLVER 0x100
-#define NL_NB_VARIABLES 0x101
-#define NL_LEAST_SQUARES 0x102
-#define NL_SYMMETRIC 0x106
-#define NL_ERROR 0x108
-
-/* Row parameters */
-
-#define NL_RIGHT_HAND_SIDE 0x500
-#define NL_ROW_SCALING 0x501
+#define NL_SOLVER 0x100
+#define NL_NB_VARIABLES 0x101
+#define NL_LEAST_SQUARES 0x102
+#define NL_SYMMETRIC 0x106
+#define NL_ERROR 0x108
+#define NL_NB_ROWS 0x110
+#define NL_NB_RIGHT_HAND_SIDES 0x112 /* 4 max */
/* Contexts */
@@ -106,9 +102,6 @@ NLContext nlGetCurrent(void);
void nlSolverParameterf(NLenum pname, NLfloat param);
void nlSolverParameteri(NLenum pname, NLint param);
-void nlRowParameterf(NLenum pname, NLfloat param);
-void nlRowParameteri(NLenum pname, NLint param);
-
void nlGetBooleanv(NLenum pname, NLboolean* params);
void nlGetFloatv(NLenum pname, NLfloat* params);
void nlGetIntergerv(NLenum pname, NLint* params);
@@ -119,8 +112,8 @@ NLboolean nlIsEnabled(NLenum pname);
/* Variables */
-void nlSetVariable(NLuint index, NLfloat value);
-NLfloat nlGetVariable(NLuint index);
+void nlSetVariable(NLuint rhsindex, NLuint index, NLfloat value);
+NLfloat nlGetVariable(NLuint rhsindex, NLuint index);
void nlLockVariable(NLuint index);
void nlUnlockVariable(NLuint index);
NLboolean nlVariableIsLocked(NLuint index);
@@ -129,12 +122,16 @@ NLboolean nlVariableIsLocked(NLuint index);
void nlBegin(NLenum primitive);
void nlEnd(NLenum primitive);
-void nlCoefficient(NLuint index, NLfloat value);
-/* Setting random elements matrix/vector - not for least squares! */
+/* Setting elements in matrix/vector */
void nlMatrixAdd(NLuint row, NLuint col, NLfloat value);
-void nlRightHandSideAdd(NLuint index, NLfloat value);
+void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLfloat value);
+void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLfloat value);
+
+/* Multiply */
+
+void nlMatrixMultiply(NLfloat *x, NLfloat *y);
/* Solve */
diff --git a/intern/opennl/intern/opennl.c b/intern/opennl/intern/opennl.c
index c5518731c6b..d779e861cb6 100644
--- a/intern/opennl/intern/opennl.c
+++ b/intern/opennl/intern/opennl.c
@@ -207,10 +207,6 @@ static void __nlRowColumnAppend(__NLRowColumn* c, NLint index, NLfloat value) {
c->size++;
}
-static void __nlRowColumnZero(__NLRowColumn* c) {
- c->size = 0;
-}
-
static void __nlRowColumnClear(__NLRowColumn* c) {
c->size = 0;
c->capacity = 0;
@@ -244,7 +240,7 @@ static void __nlSparseMatrixConstruct(
M->storage = storage;
if(storage & __NL_ROWS) {
M->row = __NL_NEW_ARRAY(__NLRowColumn, m);
- for(i=0; i<n; i++) {
+ for(i=0; i<m; i++) {
__nlRowColumnConstruct(&(M->row[i]));
}
} else {
@@ -432,48 +428,98 @@ static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLfloat* x, NLfloat* y) {
}
}
+/* ****************** Routines for least squares ******************* */
+
+static void __nlSparseMatrix_square(
+ __NLSparseMatrix* AtA, __NLSparseMatrix *A
+) {
+ NLuint m = A->m;
+ NLuint n = A->n;
+ NLuint i, j0, j1;
+ __NLRowColumn *Ri = NULL;
+ __NLCoeff *c0 = NULL, *c1 = NULL;
+ float value;
+
+ __nlSparseMatrixConstruct(AtA, n, n, A->storage);
+
+ for(i=0; i<m; i++) {
+ Ri = &(A->row[i]);
+
+ for(j0=0; j0<Ri->size; j0++) {
+ c0 = &(Ri->coeff[j0]);
+ for(j1=0; j1<Ri->size; j1++) {
+ c1 = &(Ri->coeff[j1]);
+
+ value = c0->value*c1->value;
+ __nlSparseMatrixAdd(AtA, c0->index, c1->index, value);
+ }
+ }
+ }
+}
+
+static void __nlSparseMatrix_transpose_mult_rows(
+ __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+) {
+ NLuint m = A->m;
+ NLuint n = A->n;
+ NLuint i,ij;
+ __NLRowColumn* Ri = NULL;
+ __NLCoeff* c = NULL;
+
+ __NL_CLEAR_ARRAY(NLfloat, y, n);
+
+ for(i=0; i<m; i++) {
+ Ri = &(A->row[i]);
+ for(ij=0; ij<Ri->size; ij++) {
+ c = &(Ri->coeff[ij]);
+ y[c->index] += c->value * x[i];
+ }
+ }
+}
+
/************************************************************************************/
/* NLContext data structure */
typedef void(*__NLMatrixFunc)(float* x, float* y);
typedef struct {
- NLfloat value;
+ NLfloat value[4];
NLboolean locked;
NLuint index;
+ __NLRowColumn *a;
} __NLVariable;
#define __NL_STATE_INITIAL 0
#define __NL_STATE_SYSTEM 1
#define __NL_STATE_MATRIX 2
-#define __NL_STATE_ROW 3
-#define __NL_STATE_MATRIX_CONSTRUCTED 4
-#define __NL_STATE_SYSTEM_CONSTRUCTED 5
-#define __NL_STATE_SYSTEM_SOLVED 7
+#define __NL_STATE_MATRIX_CONSTRUCTED 3
+#define __NL_STATE_SYSTEM_CONSTRUCTED 4
+#define __NL_STATE_SYSTEM_SOLVED 5
typedef struct {
- NLenum state;
+ NLenum state;
+ NLuint n;
+ NLuint m;
__NLVariable* variable;
- NLuint n;
+ NLfloat* b;
+ NLfloat* Mtb;
__NLSparseMatrix M;
- __NLRowColumn af;
- __NLRowColumn al;
+ __NLSparseMatrix MtM;
NLfloat* x;
- NLfloat* b;
- NLfloat right_hand_side;
- NLuint nb_variables;
- NLuint current_row;
+ NLuint nb_variables;
+ NLuint nb_rows;
NLboolean least_squares;
NLboolean symmetric;
+ NLuint nb_rhs;
NLboolean solve_again;
NLboolean alloc_M;
- NLboolean alloc_af;
- NLboolean alloc_al;
+ NLboolean alloc_MtM;
NLboolean alloc_variable;
NLboolean alloc_x;
NLboolean alloc_b;
- NLfloat error;
- __NLMatrixFunc matrix_vector_prod;
+ NLboolean alloc_Mtb;
+ NLfloat error;
+ __NLMatrixFunc matrix_vector_prod;
struct __NLSuperLUContext {
NLboolean alloc_slu;
@@ -493,8 +539,8 @@ static void __nlMatrixVectorProd_default(NLfloat* x, NLfloat* y) {
NLContext nlNewContext(void) {
__NLContext* result = __NL_NEW(__NLContext);
result->state = __NL_STATE_INITIAL;
- result->right_hand_side = 0.0;
result->matrix_vector_prod = __nlMatrixVectorProd_default;
+ result->nb_rhs = 1;
nlMakeCurrent(result);
return result;
}
@@ -503,27 +549,34 @@ static void __nlFree_SUPERLU(__NLContext *context);
void nlDeleteContext(NLContext context_in) {
__NLContext* context = (__NLContext*)(context_in);
+ int i;
+
if(__nlCurrentContext == context) {
__nlCurrentContext = NULL;
}
if(context->alloc_M) {
__nlSparseMatrixDestroy(&context->M);
}
- if(context->alloc_af) {
- __nlRowColumnDestroy(&context->af);
- }
- if(context->alloc_al) {
- __nlRowColumnDestroy(&context->al);
+ if(context->alloc_MtM) {
+ __nlSparseMatrixDestroy(&context->MtM);
}
if(context->alloc_variable) {
- __NL_DELETE_ARRAY(context->variable);
- }
- if(context->alloc_x) {
- __NL_DELETE_ARRAY(context->x);
+ for(i=0; i<context->nb_variables; i++) {
+ if(context->variable[i].a) {
+ __nlRowColumnDestroy(context->variable[i].a);
+ __NL_DELETE(context->variable[i].a);
+ }
+ }
}
if(context->alloc_b) {
__NL_DELETE_ARRAY(context->b);
}
+ if(context->alloc_Mtb) {
+ __NL_DELETE_ARRAY(context->Mtb);
+ }
+ if(context->alloc_x) {
+ __NL_DELETE_ARRAY(context->x);
+ }
if (context->slu.alloc_slu) {
__nlFree_SUPERLU(context);
}
@@ -561,12 +614,19 @@ void nlSolverParameterf(NLenum pname, NLfloat param) {
__nl_assert(param > 0);
__nlCurrentContext->nb_variables = (NLuint)param;
} break;
+ case NL_NB_ROWS: {
+ __nl_assert(param > 0);
+ __nlCurrentContext->nb_rows = (NLuint)param;
+ } break;
case NL_LEAST_SQUARES: {
__nlCurrentContext->least_squares = (NLboolean)param;
} break;
case NL_SYMMETRIC: {
__nlCurrentContext->symmetric = (NLboolean)param;
- }
+ } break;
+ case NL_NB_RIGHT_HAND_SIDES: {
+ __nlCurrentContext->nb_rhs = (NLuint)param;
+ } break;
default: {
__nl_assert_not_reached;
} break;
@@ -580,32 +640,21 @@ void nlSolverParameteri(NLenum pname, NLint param) {
__nl_assert(param > 0);
__nlCurrentContext->nb_variables = (NLuint)param;
} break;
+ case NL_NB_ROWS: {
+ __nl_assert(param > 0);
+ __nlCurrentContext->nb_rows = (NLuint)param;
+ } break;
case NL_LEAST_SQUARES: {
__nlCurrentContext->least_squares = (NLboolean)param;
} break;
case NL_SYMMETRIC: {
__nlCurrentContext->symmetric = (NLboolean)param;
- }
- default: {
- __nl_assert_not_reached;
} break;
- }
-}
-
-void nlRowParameterf(NLenum pname, NLfloat param) {
- __nlCheckState(__NL_STATE_MATRIX);
- switch(pname) {
- case NL_RIGHT_HAND_SIDE: {
- __nlCurrentContext->right_hand_side = param;
+ case NL_NB_RIGHT_HAND_SIDES: {
+ __nlCurrentContext->nb_rhs = (NLuint)param;
} break;
- }
-}
-
-void nlRowParameteri(NLenum pname, NLint param) {
- __nlCheckState(__NL_STATE_MATRIX);
- switch(pname) {
- case NL_RIGHT_HAND_SIDE: {
- __nlCurrentContext->right_hand_side = (NLfloat)param;
+ default: {
+ __nl_assert_not_reached;
} break;
}
}
@@ -629,6 +678,9 @@ void nlGetFloatv(NLenum pname, NLfloat* params) {
case NL_NB_VARIABLES: {
*params = (NLfloat)(__nlCurrentContext->nb_variables);
} break;
+ case NL_NB_ROWS: {
+ *params = (NLfloat)(__nlCurrentContext->nb_rows);
+ } break;
case NL_LEAST_SQUARES: {
*params = (NLfloat)(__nlCurrentContext->least_squares);
} break;
@@ -649,6 +701,9 @@ void nlGetIntergerv(NLenum pname, NLint* params) {
case NL_NB_VARIABLES: {
*params = (NLint)(__nlCurrentContext->nb_variables);
} break;
+ case NL_NB_ROWS: {
+ *params = (NLint)(__nlCurrentContext->nb_rows);
+ } break;
case NL_LEAST_SQUARES: {
*params = (NLint)(__nlCurrentContext->least_squares);
} break;
@@ -692,16 +747,16 @@ NLboolean nlIsEnabled(NLenum pname) {
/************************************************************************************/
/* Get/Set Lock/Unlock variables */
-void nlSetVariable(NLuint index, NLfloat value) {
+void nlSetVariable(NLuint rhsindex, NLuint index, NLfloat value) {
__nlCheckState(__NL_STATE_SYSTEM);
__nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- __nlCurrentContext->variable[index].value = value;
+ __nlCurrentContext->variable[index].value[rhsindex] = value;
}
-NLfloat nlGetVariable(NLuint index) {
+NLfloat nlGetVariable(NLuint rhsindex, NLuint index) {
__nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
__nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
- return __nlCurrentContext->variable[index].value;
+ return __nlCurrentContext->variable[index].value[rhsindex];
}
void nlLockVariable(NLuint index) {
@@ -726,27 +781,41 @@ NLboolean nlVariableIsLocked(NLuint index) {
/* System construction */
static void __nlVariablesToVector() {
- NLuint i;
- __nl_assert(__nlCurrentContext->alloc_x);
- __nl_assert(__nlCurrentContext->alloc_variable);
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- __NLVariable* v = &(__nlCurrentContext->variable[i]);
+ __NLContext *context = __nlCurrentContext;
+ NLuint i, j, nb_rhs;
+
+ __nl_assert(context->alloc_x);
+ __nl_assert(context->alloc_variable);
+
+ nb_rhs= context->nb_rhs;
+
+ for(i=0; i<context->nb_variables; i++) {
+ __NLVariable* v = &(context->variable[i]);
if(!v->locked) {
- __nl_assert(v->index < __nlCurrentContext->n);
- __nlCurrentContext->x[v->index] = v->value;
+ __nl_assert(v->index < context->n);
+
+ for(j=0; j<nb_rhs; j++)
+ context->x[context->n*j + v->index] = v->value[j];
}
}
}
static void __nlVectorToVariables() {
- NLuint i;
- __nl_assert(__nlCurrentContext->alloc_x);
- __nl_assert(__nlCurrentContext->alloc_variable);
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- __NLVariable* v = &(__nlCurrentContext->variable[i]);
+ __NLContext *context = __nlCurrentContext;
+ NLuint i, j, nb_rhs;
+
+ __nl_assert(context->alloc_x);
+ __nl_assert(context->alloc_variable);
+
+ nb_rhs= context->nb_rhs;
+
+ for(i=0; i<context->nb_variables; i++) {
+ __NLVariable* v = &(context->variable[i]);
if(!v->locked) {
- __nl_assert(v->index < __nlCurrentContext->n);
- v->value = __nlCurrentContext->x[v->index];
+ __nl_assert(v->index < context->n);
+
+ for(j=0; j<nb_rhs; j++)
+ v->value[j] = context->x[context->n*j + v->index];
}
}
}
@@ -760,8 +829,8 @@ static void __nlBeginSystem() {
__nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM);
__nlCurrentContext->variable = __NL_NEW_ARRAY(
- __NLVariable, __nlCurrentContext->nb_variables
- );
+ __NLVariable, __nlCurrentContext->nb_variables);
+
__nlCurrentContext->alloc_variable = NL_TRUE;
}
}
@@ -772,159 +841,161 @@ static void __nlEndSystem() {
static void __nlBeginMatrix() {
NLuint i;
- NLuint n = 0;
+ NLuint m = 0, n = 0;
NLenum storage = __NL_ROWS;
+ __NLContext *context = __nlCurrentContext;
__nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX);
- if (!__nlCurrentContext->solve_again) {
- for(i=0; i<__nlCurrentContext->nb_variables; i++) {
- if(!__nlCurrentContext->variable[i].locked)
- __nlCurrentContext->variable[i].index = n++;
+ if (!context->solve_again) {
+ for(i=0; i<context->nb_variables; i++) {
+ if(context->variable[i].locked) {
+ context->variable[i].index = ~0;
+ context->variable[i].a = __NL_NEW(__NLRowColumn);
+ __nlRowColumnConstruct(context->variable[i].a);
+ }
else
- __nlCurrentContext->variable[i].index = ~0;
+ context->variable[i].index = n++;
}
- __nlCurrentContext->n = n;
+ m = (context->nb_rows == 0)? n: context->nb_rows;
- /* a least squares problem results in a symmetric matrix */
- if(__nlCurrentContext->least_squares)
- __nlCurrentContext->symmetric = NL_TRUE;
+ context->m = m;
+ context->n = n;
- if(__nlCurrentContext->symmetric)
- storage = (storage | __NL_SYMMETRIC);
+ __nlSparseMatrixConstruct(&context->M, m, n, storage);
+ context->alloc_M = NL_TRUE;
- /* SuperLU storage does not support symmetric storage */
- storage = (storage & ~__NL_SYMMETRIC);
+ context->b = __NL_NEW_ARRAY(NLfloat, m*context->nb_rhs);
+ context->alloc_b = NL_TRUE;
- __nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage);
- __nlCurrentContext->alloc_M = NL_TRUE;
-
- __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n);
- __nlCurrentContext->alloc_x = NL_TRUE;
-
- __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n);
- __nlCurrentContext->alloc_b = NL_TRUE;
+ context->x = __NL_NEW_ARRAY(NLfloat, n*context->nb_rhs);
+ context->alloc_x = NL_TRUE;
}
else {
/* need to recompute b only, A is not constructed anymore */
- __NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, __nlCurrentContext->n);
+ __NL_CLEAR_ARRAY(NLfloat, context->b, context->m*context->nb_rhs);
}
__nlVariablesToVector();
+}
+
+static void __nlEndMatrixRHS(NLuint rhs) {
+ __NLContext *context = __nlCurrentContext;
+ __NLVariable *variable;
+ __NLRowColumn *a;
+ NLfloat *b, *Mtb;
+ NLuint i, j;
+
+ b = context->b + context->m*rhs;
+ Mtb = context->Mtb + context->n*rhs;
+
+ for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+ variable = &(context->variable[i]);
- __nlRowColumnConstruct(&__nlCurrentContext->af);
- __nlCurrentContext->alloc_af = NL_TRUE;
- __nlRowColumnConstruct(&__nlCurrentContext->al);
- __nlCurrentContext->alloc_al = NL_TRUE;
+ if(variable->locked) {
+ a = variable->a;
- __nlCurrentContext->current_row = 0;
+ for(j=0; j<a->size; j++) {
+ b[a->coeff[j].index] -= a->coeff[j].value*variable->value[rhs];
+ }
+ }
+ }
+
+ if(context->least_squares)
+ __nlSparseMatrix_transpose_mult_rows(&context->M, b, Mtb);
}
static void __nlEndMatrix() {
+ __NLContext *context = __nlCurrentContext;
+ NLuint i;
+
__nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED);
- __nlRowColumnDestroy(&__nlCurrentContext->af);
- __nlCurrentContext->alloc_af = NL_FALSE;
- __nlRowColumnDestroy(&__nlCurrentContext->al);
- __nlCurrentContext->alloc_al = NL_FALSE;
-
-#if 0
- if(!__nlCurrentContext->least_squares) {
- __nl_assert(
- __nlCurrentContext->current_row ==
- __nlCurrentContext->n
- );
+ if(context->least_squares) {
+ if(!__nlCurrentContext->solve_again) {
+ __nlSparseMatrix_square(&context->MtM, &context->M);
+ context->alloc_MtM = NL_TRUE;
+
+ context->Mtb =
+ __NL_NEW_ARRAY(NLfloat, context->n*context->nb_rhs);
+ context->alloc_Mtb = NL_TRUE;
+ }
}
-#endif
-}
-static void __nlBeginRow() {
- __nlTransition(__NL_STATE_MATRIX, __NL_STATE_ROW);
- __nlRowColumnZero(&__nlCurrentContext->af);
- __nlRowColumnZero(&__nlCurrentContext->al);
+ for(i=0; i<context->nb_rhs; i++)
+ __nlEndMatrixRHS(i);
}
-static void __nlEndRow() {
- __NLRowColumn* af = &__nlCurrentContext->af;
- __NLRowColumn* al = &__nlCurrentContext->al;
- __NLSparseMatrix* M = &__nlCurrentContext->M;
- NLfloat* b = __nlCurrentContext->b;
- NLuint nf = af->size;
- NLuint nl = al->size;
- NLuint current_row = __nlCurrentContext->current_row;
- NLuint i;
- NLuint j;
- NLfloat S;
- __nlTransition(__NL_STATE_ROW, __NL_STATE_MATRIX);
-
- if(__nlCurrentContext->least_squares) {
- if (!__nlCurrentContext->solve_again) {
- for(i=0; i<nf; i++) {
- for(j=0; j<nf; j++) {
- __nlSparseMatrixAdd(
- M, af->coeff[i].index, af->coeff[j].index,
- af->coeff[i].value * af->coeff[j].value
- );
- }
- }
- }
+void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
+{
+ __NLContext *context = __nlCurrentContext;
- S = -__nlCurrentContext->right_hand_side;
- for(j=0; j<nl; j++)
- S += al->coeff[j].value;
+ __nlCheckState(__NL_STATE_MATRIX);
- for(i=0; i<nf; i++)
- b[ af->coeff[i].index ] -= af->coeff[i].value * S;
- } else {
- if (!__nlCurrentContext->solve_again) {
- for(i=0; i<nf; i++) {
- __nlSparseMatrixAdd(
- M, current_row, af->coeff[i].index, af->coeff[i].value
- );
- }
- }
- b[current_row] = -__nlCurrentContext->right_hand_side;
- for(i=0; i<nl; i++) {
- b[current_row] -= al->coeff[i].value;
- }
+ if(context->solve_again)
+ return;
+
+ if (!context->least_squares && context->variable[row].locked);
+ else if (context->variable[col].locked) {
+ if(!context->least_squares)
+ row = context->variable[row].index;
+ __nlRowColumnAppend(context->variable[col].a, row, value);
+ }
+ else {
+ __NLSparseMatrix* M = &context->M;
+
+ if(!context->least_squares)
+ row = context->variable[row].index;
+ col = context->variable[col].index;
+
+ __nl_range_assert(row, 0, context->m - 1);
+ __nl_range_assert(col, 0, context->n - 1);
+
+ __nlSparseMatrixAdd(M, row, col, value);
}
- __nlCurrentContext->current_row++;
- __nlCurrentContext->right_hand_side = 0.0;
}
-void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
+void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLfloat value)
{
- __NLSparseMatrix* M = &__nlCurrentContext->M;
+ __NLContext *context = __nlCurrentContext;
+ NLfloat* b = context->b;
+
__nlCheckState(__NL_STATE_MATRIX);
- __nl_range_assert(row, 0, __nlCurrentContext->n - 1);
- __nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1);
- __nl_assert(!__nlCurrentContext->least_squares);
- __nlSparseMatrixAdd(M, row, col, value);
+ if(context->least_squares) {
+ __nl_range_assert(index, 0, context->m - 1);
+ b[rhsindex*context->m + index] += value;
+ }
+ else {
+ if(!context->variable[index].locked) {
+ index = context->variable[index].index;
+ __nl_range_assert(index, 0, context->m - 1);
+
+ b[rhsindex*context->m + index] += value;
+ }
+ }
}
-void nlRightHandSideAdd(NLuint index, NLfloat value)
+void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLfloat value)
{
- NLfloat* b = __nlCurrentContext->b;
+ __NLContext *context = __nlCurrentContext;
+ NLfloat* b = context->b;
__nlCheckState(__NL_STATE_MATRIX);
- __nl_range_assert(index, 0, __nlCurrentContext->n - 1);
- __nl_assert(!__nlCurrentContext->least_squares);
- b[index] += value;
-}
+ if(context->least_squares) {
+ __nl_range_assert(index, 0, context->m - 1);
+ b[rhsindex*context->m + index] = value;
+ }
+ else {
+ if(!context->variable[index].locked) {
+ index = context->variable[index].index;
+ __nl_range_assert(index, 0, context->m - 1);
-void nlCoefficient(NLuint index, NLfloat value) {
- __NLVariable* v;
- unsigned int zero= 0;
- __nlCheckState(__NL_STATE_ROW);
- __nl_range_assert(index, zero, __nlCurrentContext->nb_variables - 1);
- v = &(__nlCurrentContext->variable[index]);
- if(v->locked)
- __nlRowColumnAppend(&(__nlCurrentContext->al), 0, value*v->value);
- else
- __nlRowColumnAppend(&(__nlCurrentContext->af), v->index, value);
+ b[rhsindex*context->m + index] = value;
+ }
+ }
}
void nlBegin(NLenum prim) {
@@ -935,9 +1006,6 @@ void nlBegin(NLenum prim) {
case NL_MATRIX: {
__nlBeginMatrix();
} break;
- case NL_ROW: {
- __nlBeginRow();
- } break;
default: {
__nl_assert_not_reached;
}
@@ -952,9 +1020,6 @@ void nlEnd(NLenum prim) {
case NL_MATRIX: {
__nlEndMatrix();
} break;
- case NL_ROW: {
- __nlEndRow();
- } break;
default: {
__nl_assert_not_reached;
}
@@ -969,7 +1034,7 @@ void nlEnd(NLenum prim) {
static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) {
/* OpenNL Context */
- __NLSparseMatrix* M = &(context->M);
+ __NLSparseMatrix* M = (context->least_squares)? &context->MtM: &context->M;
NLuint n = context->n;
NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */
@@ -986,7 +1051,6 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
superlu_options_t options;
/* Temporary variables */
- __NLRowColumn* Ri = NULL;
NLuint i, jj, count;
__nl_assert(!(M->storage & __NL_SYMMETRIC));
@@ -1049,7 +1113,7 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
/* Cleanup */
Destroy_SuperMatrix_Store(&At);
- Destroy_SuperMatrix_Store(&AtP);
+ Destroy_CompCol_Permuted(&AtP);
__NL_DELETE_ARRAY(etree);
__NL_DELETE_ARRAY(xa);
@@ -1065,31 +1129,33 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
static NLboolean __nlInvert_SUPERLU(__NLContext *context) {
/* OpenNL Context */
- NLfloat* b = context->b;
+ NLfloat* b = (context->least_squares)? context->Mtb: context->b;
NLfloat* x = context->x;
- NLuint n = context->n;
+ NLuint n = context->n, j;
/* SuperLU variables */
SuperMatrix B;
NLint info;
- /* Create superlu array for B */
- sCreate_Dense_Matrix(
- &B, n, 1, b, n,
- SLU_DN, /* Fortran-type column-wise storage */
- SLU_S, /* floats */
- SLU_GE /* general */
- );
+ for(j=0; j<context->nb_rhs; j++, b+=n, x+=n) {
+ /* Create superlu array for B */
+ sCreate_Dense_Matrix(
+ &B, n, 1, b, n,
+ SLU_DN, /* Fortran-type column-wise storage */
+ SLU_S, /* floats */
+ SLU_GE /* general */
+ );
- /* Forward/Back substitution to compute x */
- sgstrs(TRANS, &(context->slu.L), &(context->slu.U),
- context->slu.perm_c, context->slu.perm_r, &B,
- &(context->slu.stat), &info);
+ /* Forward/Back substitution to compute x */
+ sgstrs(TRANS, &(context->slu.L), &(context->slu.U),
+ context->slu.perm_c, context->slu.perm_r, &B,
+ &(context->slu.stat), &info);
- if(info == 0)
- memcpy(x, ((DNformat*)B.Store)->nzval, sizeof(*x)*n);
+ if(info == 0)
+ memcpy(x, ((DNformat*)B.Store)->nzval, sizeof(*x)*n);
- Destroy_SuperMatrix_Store(&B);
+ Destroy_SuperMatrix_Store(&B);
+ }
return (info == 0);
}
@@ -1108,15 +1174,18 @@ static void __nlFree_SUPERLU(__NLContext *context) {
}
void nlPrintMatrix(void) {
- __NLSparseMatrix* M = &(__nlCurrentContext->M);
- float *b = __nlCurrentContext->b;
+ __NLContext *context = __nlCurrentContext;
+ __NLSparseMatrix* M = &(context->M);
+ __NLSparseMatrix* MtM = &(context->MtM);
+ float *b = context->b;
NLuint i, jj, k;
- NLuint n = __nlCurrentContext->n;
+ NLuint m = context->m;
+ NLuint n = context->n;
__NLRowColumn* Ri = NULL;
- float *value = malloc(sizeof(*value)*n);
+ float *value = malloc(sizeof(*value)*(n+m));
printf("A:\n");
- for(i=0; i<n; i++) {
+ for(i=0; i<m; i++) {
Ri = &(M->row[i]);
memset(value, 0.0, sizeof(*value)*n);
@@ -1128,10 +1197,35 @@ void nlPrintMatrix(void) {
printf("\n");
}
- printf("b:\n");
- for(i=0; i<n; i++)
- printf("%f ", b[i]);
- printf("\n");
+ for(k=0; k<context->nb_rhs; k++) {
+ printf("b (%d):\n", k);
+ for(i=0; i<n; i++)
+ printf("%f ", b[context->n*k + i]);
+ printf("\n");
+ }
+
+ if(context->alloc_MtM) {
+ printf("AtA:\n");
+ for(i=0; i<n; i++) {
+ Ri = &(MtM->row[i]);
+
+ memset(value, 0.0, sizeof(*value)*m);
+ for(jj=0; jj<Ri->size; jj++)
+ value[Ri->coeff[jj].index] = Ri->coeff[jj].value;
+
+ for (k = 0; k<n; k++)
+ printf("%.3f ", value[k]);
+ printf("\n");
+ }
+
+ for(k=0; k<context->nb_rhs; k++) {
+ printf("Mtb (%d):\n", k);
+ for(i=0; i<n; i++)
+ printf("%f ", context->Mtb[context->n*k + i]);
+ printf("\n");
+ }
+ printf("\n");
+ }
free(value);
}
diff --git a/intern/string/STR_String.h b/intern/string/STR_String.h
index 2da2b57c6f2..7b02e6c1855 100644
--- a/intern/string/STR_String.h
+++ b/intern/string/STR_String.h
@@ -47,6 +47,10 @@
#include <vector>
#include <limits.h>
+
+#include <cstring>
+#include <cstdlib>
+
using namespace std;
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index c243bc28224..af8f0d11445 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -41,6 +41,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
+#include <string.h>
#include "STR_String.h"
/*-------------------------------------------------------------------------------------------------
diff --git a/po/Makefile b/po/Makefile
index 21ec6a662ff..ea0bc6cbe5e 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -36,7 +36,8 @@ SOURCEDIR = blender/po
include nan_definitions.mk
-LINGUAS = ar bg ca cs de es fr hr it ja nl pl pt_br ro ru sr sr@Latn sv uk zh_CN
+LINGUAS = ar bg ca cs de el es fi fr hr it ja nl pl pt_BR ro ru sr sr@Latn sv uk zh_CN
+
ifeq ($(OS), darwin)
DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/$@/LC_MESSAGES/
else
diff --git a/projectfiles/blender/src/BL_src.dsp b/projectfiles/blender/src/BL_src.dsp
index d55a732a072..d6a1c3945e9 100644
--- a/projectfiles/blender/src/BL_src.dsp
+++ b/projectfiles/blender/src/BL_src.dsp
@@ -43,7 +43,7 @@ RSC=rc.exe
LINK32=link.exe -lib
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /I "..\..\..\..\lib\windows\memutil\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "xGAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /FR /J /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /I "..\..\..\..\lib\windows\memutil\include" /I "..\..\..\..\lib\windows\pthreads\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "xGAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /FR /J /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -68,7 +68,7 @@ LIB32=link.exe -lib
LINK32=link.exe -lib
MTL=midl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /I "..\..\..\..\lib\windows\memutil\include" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "xGAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /U "_DEBUG" /J /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /I "..\..\..\..\lib\windows\memutil\include" /I "..\..\..\..\lib\windows\pthreads\include" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "xGAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /U "_DEBUG" /J /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/projectfiles/blender/src/BL_src_cre.dsp b/projectfiles/blender/src/BL_src_cre.dsp
index ea1992c33d4..1705b45a96f 100644
--- a/projectfiles/blender/src/BL_src_cre.dsp
+++ b/projectfiles/blender/src/BL_src_cre.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Target_Dir ""
LINK32=link.exe -lib
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderui" /I "..\..\..\source\gameengine\soundsystem\\" /I "..\..\..\..\lib\windows\python\include\python2.2\\" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "NAN_GAME" /D "GAME" /J /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderui" /I "..\..\..\source\gameengine\soundsystem\\" /I "..\..\..\..\lib\windows\python\include\python2.2\\" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\pthreads\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "NAN_GAME" /D "GAME" /J /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -66,7 +66,7 @@ LIB32=link.exe -lib
# PROP Target_Dir ""
LINK32=link.exe -lib
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderui" /I "..\..\..\source\gameengine\soundsystem\\" /I "..\..\..\..\lib\windows\python\include\python2.2\\" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "NAN_GAME" /D "GAME" /U "_DEBUG" /J /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderui" /I "..\..\..\source\gameengine\soundsystem\\" /I "..\..\..\..\lib\windows\python\include\python2.2\\" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\pthreads\include" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "NAN_GAME" /D "GAME" /U "_DEBUG" /J /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
diff --git a/projectfiles_vc7/blender/blender.sln b/projectfiles_vc7/blender/blender.sln
index 0888cf7971a..60c2d8f2d4c 100644
--- a/projectfiles_vc7/blender/blender.sln
+++ b/projectfiles_vc7/blender/blender.sln
@@ -248,8 +248,6 @@ Global
Debug = Debug
Release = Release
EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{F78B7FC9-DE32-465E-9F26-BB0B6B7A2EAF}.3D Plugin Debug.ActiveCfg = Blender Debug|Win32
{F78B7FC9-DE32-465E-9F26-BB0B6B7A2EAF}.3D Plugin Release.ActiveCfg = Blender Release|Win32
diff --git a/projectfiles_vc7/blender/blender.vcproj b/projectfiles_vc7/blender/blender.vcproj
index 9761d94d746..e9cf694c281 100644
--- a/projectfiles_vc7/blender/blender.vcproj
+++ b/projectfiles_vc7/blender/blender.vcproj
@@ -13,7 +13,7 @@
<Configurations>
<Configuration
Name="Blender Release|Win32"
- OutputDirectory="..\..\bin\debug"
+ OutputDirectory="..\..\bin"
IntermediateDirectory="..\..\..\build\msvc_7\source\blender"
ConfigurationType="1"
UseOfMFC="0"
diff --git a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
index eed71426945..1e55e9795d8 100644
--- a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
@@ -73,8 +73,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
- PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2;WITH_VERSE;WITH_OPENEXR"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\extern\bullet\include"
+ PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
@@ -125,8 +125,8 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
- PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_FREETYPE2;UNWRAPPER;WITH_VERSE;WITH_OPENEXR"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\extern\bullet\include"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_FREETYPE2;UNWRAPPER;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
@@ -229,7 +229,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\extern\bullet\include"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_FREETYPE2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -281,7 +281,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\extern\bullet\include"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_FREETYPE2,UNWRAPPER"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -342,6 +342,21 @@
RelativePath="..\..\..\source\blender\blenkernel\intern\blender.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\BME_conversions.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\BME_eulers.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\BME_mesh.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\BME_structure.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\BME_tools.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\bmfont.c">
</File>
<File
@@ -354,6 +369,12 @@
RelativePath="..\..\..\source\blender\blenkernel\intern\cdderivedmesh.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\cloth.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\collision.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\colortools.c">
</File>
<File
@@ -399,9 +420,15 @@
RelativePath="..\..\..\source\blender\blenkernel\intern\image.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\implicit.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\ipo.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\kdop.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\key.c">
</File>
<File
@@ -423,6 +450,12 @@
RelativePath="..\..\..\source\blender\blenkernel\intern\modifier.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\multires-firstlevel.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\multires.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\nla.c">
</File>
<File
@@ -435,6 +468,15 @@
RelativePath="..\..\..\source\blender\blenkernel\intern\packedFile.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\particle.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\particle_system.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\pointcache.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\property.c">
</File>
<File
@@ -511,6 +553,9 @@
RelativePath="..\..\..\source\blender\blenkernel\BKE_blender.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_bmesh.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\BKE_bmfont.h">
</File>
<File
@@ -529,6 +574,12 @@
RelativePath="..\..\..\source\blender\blenkernel\BKE_cdderivedmesh.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_cloth.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_collision.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\BKE_colortools.h">
</File>
<File
@@ -604,6 +655,9 @@
RelativePath="..\..\..\source\blender\blenkernel\BKE_modifier.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_multires.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\BKE_nla.h">
</File>
<File
@@ -619,9 +673,15 @@
RelativePath="..\..\..\source\blender\blenkernel\BKE_packedFile.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_particle.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\BKE_plugin_types.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\BKE_pointcache.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\BKE_property.h">
</File>
<File
@@ -670,6 +730,9 @@
RelativePath="..\..\..\source\blender\blenkernel\BKE_writeframeserver.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\bmesh_private.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\CCGSubSurf.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
index f7038e610f1..8a2b8b95e38 100644
--- a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
+++ b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
@@ -347,6 +347,9 @@
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_heap.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\intern\BLI_kdtree.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_linklist.c">
</File>
<File
@@ -356,6 +359,9 @@
RelativePath="..\..\..\source\blender\blenlib\intern\boxpack2d.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\intern\bpath.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\dynlib.c">
</File>
<File
@@ -365,6 +371,9 @@
RelativePath="..\..\..\source\blender\blenlib\intern\fileops.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\intern\fnmatch.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\freetypefont.c">
</File>
<File
@@ -423,6 +432,9 @@
RelativePath="..\..\..\source\blender\blenlib\BLI_boxpack2d.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_bpath.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_callbacks.h">
</File>
<File
@@ -435,6 +447,9 @@
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_fileops.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_fnmatch.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\BLI_ghash.h">
</File>
<File
@@ -444,6 +459,9 @@
RelativePath="..\..\..\source\blender\blenlib\BLI_jitter.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_kdtree.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\BLI_linklist.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/ftfont/FTF_ftfont.vcproj b/projectfiles_vc7/blender/ftfont/FTF_ftfont.vcproj
index ad0f5d83ced..9eee41b4cff 100644
--- a/projectfiles_vc7/blender/ftfont/FTF_ftfont.vcproj
+++ b/projectfiles_vc7/blender/ftfont/FTF_ftfont.vcproj
@@ -74,7 +74,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\freetype\include;..\..\..\..\build\msvc_7\extern\ftgl\include;..\..\..\..\lib\windows\gettext\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\freetype\include;..\..\..\..\build\msvc_7\extern\ftgl\include;..\..\..\..\lib\windows\gettext\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\makesdna;..\..\..\source\blender\include"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WCHAR_T16,HAVE_LC_MESSAGES,FTGL_LIBRARY_STATIC"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
diff --git a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj
index 61c0a857da1..b4daf386c26 100644
--- a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj
+++ b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj
@@ -21,8 +21,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME;WITH_OPENEXR"
+ 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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="_DEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR;WITH_DDS"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
@@ -176,8 +176,8 @@
<Tool
Name="VCCLCompilerTool"
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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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"
- PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_QUICKTIME;WITH_OPENEXR"
+ 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
@@ -228,8 +228,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME"
+ 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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="_DEBUG,WIN32,_LIB,WITH_QUICKTIME,WITH_DDS"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
@@ -280,8 +280,8 @@
<Tool
Name="VCCLCompilerTool"
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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
+ 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;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\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_DDS"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
@@ -383,12 +383,18 @@
RelativePath="..\..\..\source\blender\imbuf\intern\imageprocess.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\imginfo.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\iris.c">
</File>
<File
RelativePath="..\..\..\source\blender\imbuf\intern\jpeg.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\md5.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\openexr\openexr_api.cpp">
</File>
<File
@@ -419,6 +425,9 @@
RelativePath="..\..\..\source\blender\imbuf\intern\targa.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\thumbs.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\tiff.c">
</File>
<File
@@ -481,6 +490,60 @@
</File>
</Filter>
</Filter>
+ <Filter
+ Name="dds"
+ Filter="">
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\BlockDXT.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\ColorBlock.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\dds_api.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\DirectDrawSurface.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Image.cpp">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Stream.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="">
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\BlockDXT.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Color.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\ColorBlock.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Common.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\dds_api.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\DirectDrawSurface.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Image.h">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\imbuf\intern\dds\Stream.h">
+ </File>
+ </Filter>
+ </Filter>
</Filter>
<Filter
Name="Header Files"
@@ -534,6 +597,9 @@
RelativePath="..\..\..\source\blender\imbuf\IMB_imbuf_types.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\IMB_imginfo.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_iris.h">
</File>
<File
@@ -549,6 +615,9 @@
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_targa.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\IMB_thumbs.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_tiff.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj b/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj
index f8d88f8640e..04d964ba657 100644
--- a/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj
+++ b/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj
@@ -445,6 +445,9 @@ DNA_makesdna.exe dna.c
RelativePath="..\..\..\source\blender\makesdna\DNA_camera_types.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\makesdna\DNA_cloth_types.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesdna\DNA_color_types.h">
</File>
<File
@@ -526,6 +529,9 @@ DNA_makesdna.exe dna.c
RelativePath="..\..\..\source\blender\makesdna\DNA_packedFile_types.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\makesdna\DNA_particle_types.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesdna\DNA_property_types.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/nodes/nodes.vcproj b/projectfiles_vc7/blender/nodes/nodes.vcproj
index 32e38330473..3e19417de9f 100644
--- a/projectfiles_vc7/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc7/blender/nodes/nodes.vcproj
@@ -19,7 +19,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2"
MinimalRebuild="FALSE"
BasicRuntimeChecks="3"
@@ -66,7 +66,7 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
@@ -113,7 +113,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2;WITH_OPENEXR"
MinimalRebuild="FALSE"
BasicRuntimeChecks="3"
@@ -160,8 +160,8 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
- PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_FREETYPE2, WITH_OPENEXR"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\zlib\include;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\source\blender;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\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_7\extern\verse\include"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_FREETYPE2, WITH_OPENEXR"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
DefaultCharIsUnsigned="TRUE"
@@ -222,6 +222,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_alphaOver.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_bilateralblur.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_blur.c">
</File>
<File
@@ -240,6 +243,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_composite.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_crop.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_curves.c">
</File>
<File
@@ -252,6 +258,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_dilate.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_directionalblur.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_displace.c">
</File>
<File
@@ -264,6 +273,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_gamma.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_glare.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_hueSatVal.c">
</File>
<File
@@ -273,6 +285,12 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_image.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_invert.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_lensdist.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_lummaMatte.c">
</File>
<File
@@ -291,9 +309,15 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_normal.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_normalize.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_outputFile.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_premulkey.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_rgb.c">
</File>
<File
@@ -324,6 +348,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_texture.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_tonemap.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\CMP_nodes\CMP_translate.c">
</File>
<File
@@ -352,9 +379,18 @@
RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_curves.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_dynamic.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_geom.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_hueSatVal.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_invert.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_mapping.c">
</File>
<File
@@ -376,6 +412,9 @@
RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_rgb.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_sepcombRGB.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\SHD_nodes\SHD_squeeze.c">
</File>
<File
diff --git a/projectfiles_vc7/blender/render/BRE_render.vcproj b/projectfiles_vc7/blender/render/BRE_render.vcproj
index c04d456fc33..88a66defce9 100644
--- a/projectfiles_vc7/blender/render/BRE_render.vcproj
+++ b/projectfiles_vc7/blender/render/BRE_render.vcproj
@@ -137,6 +137,9 @@
RelativePath="..\..\..\source\blender\render\intern\source\initrender.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\render\intern\source\occlusion.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\render\intern\source\pipeline.c">
</File>
<File
@@ -167,6 +170,9 @@
RelativePath="..\..\..\source\blender\render\intern\source\sss.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\render\intern\source\strand.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\render\intern\source\texture.c">
</File>
<File
@@ -189,6 +195,9 @@
RelativePath="..\..\..\source\blender\render\intern\include\initrender.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\render\intern\include\occlusion.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\render\intern\include\old_zbuffer_types.h">
</File>
<File
@@ -231,6 +240,9 @@
RelativePath="..\..\..\source\blender\render\intern\include\sss.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\render\intern\include\strand.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\render\intern\include\texture.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/src/BL_src.vcproj b/projectfiles_vc7/blender/src/BL_src.vcproj
index af367ac2ce3..b0a41131ac8 100644
--- a/projectfiles_vc7/blender/src/BL_src.vcproj
+++ b/projectfiles_vc7/blender/src/BL_src.vcproj
@@ -21,8 +21,8 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\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\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\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_7\extern\verse\include"
- PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\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\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\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_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
@@ -73,8 +73,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\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\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\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_7\extern\verse\include"
- PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\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\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\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_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include"
+ PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="TRUE"
@@ -308,6 +308,9 @@
RelativePath="..\..\..\source\blender\src\editoops.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\editparticle.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\editscreen.c">
</File>
<File
@@ -329,12 +332,18 @@
RelativePath="..\..\..\source\blender\src\eventdebug.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\filelist.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\filesel.c">
</File>
<File
RelativePath="..\..\..\source\blender\src\fluidsim.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\fsmenu.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\ghostwinlay.c">
</File>
<File
@@ -428,9 +437,6 @@
RelativePath="..\..\..\source\blender\src\meshtools.c">
</File>
<File
- RelativePath="..\..\..\source\blender\src\multires-firstlevel.c">
- </File>
- <File
RelativePath="..\..\..\source\blender\src\multires.c">
</File>
<File
@@ -452,6 +458,9 @@
RelativePath="..\..\..\source\blender\blenpluginapi\intern\pluginapi.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\poselib.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\poseobject.c">
</File>
<File
@@ -461,6 +470,15 @@
RelativePath="..\..\..\source\blender\src\previewrender.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\prvicons.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\src\radialcontrol.c">
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\src\reeb.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\renderwin.c">
</File>
<File
@@ -527,6 +545,9 @@
RelativePath="..\..\..\source\blender\src\transform_numinput.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\src\transform_orientations.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\src\transform_snap.c">
</File>
<File
@@ -660,6 +681,9 @@
RelativePath="..\..\..\source\blender\include\BIF_editoops.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\include\BIF_editparticle.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\include\BIF_editsca.h">
</File>
<File
@@ -675,6 +699,9 @@
RelativePath="..\..\..\source\blender\include\BIF_editview.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\include\BIF_filelist.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\include\BIF_fsmenu.h">
</File>
<File
@@ -723,6 +750,9 @@
RelativePath="..\..\..\source\blender\include\BIF_previewrender.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\include\BIF_radialcontrol.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\include\BIF_renderwin.h">
</File>
<File
@@ -861,6 +891,9 @@
RelativePath="..\..\..\source\blender\include\playanim_ext.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\include\reeb.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\include\transform.h">
</File>
<File
diff --git a/projectfiles_vc7/blender/src/BL_src_cre.vcproj b/projectfiles_vc7/blender/src/BL_src_cre.vcproj
index 1f0b4e9e8d4..70de861c91c 100644
--- a/projectfiles_vc7/blender/src/BL_src_cre.vcproj
+++ b/projectfiles_vc7/blender/src/BL_src_cre.vcproj
@@ -21,7 +21,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\verify;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem;..\..\..\source\gameengine\soundsystem\snd_openal"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\verify;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\lib\windows\pthreads\include"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB,_CONSOLE,NAN_GAME,GAME"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -74,7 +74,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\verify;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem;..\..\..\source\gameengine\soundsystem\snd_openal"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\verify;..\..\..\source\blender\blenlib;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\renderconverter;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\lib\windows\pthreads\include"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;NAN_GAME;GAME"
StringPooling="TRUE"
RuntimeLibrary="0"
diff --git a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
index 4336f0dd7cd..07fcfa64a72 100644
--- a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
+++ b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
@@ -21,7 +21,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -73,7 +73,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -125,7 +125,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="TRUE"
RuntimeLibrary="2"
@@ -177,7 +177,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="WIN32,_LIB,EXP_PYTHON_EMBEDDING,_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -229,7 +229,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -281,7 +281,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Rasterizer"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB,EXP_PYTHON_EMBEDDING"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -330,6 +330,9 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.cpp">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.cpp">
</File>
<File
@@ -427,6 +430,9 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
+ RelativePath="..\..\..\source\gameengine\GameLogic\SCA_2DFilterActuator.h">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\GameLogic\SCA_AlwaysEventManager.h">
</File>
<File
diff --git a/projectfiles_vc7/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc7/gameengine/gameplayer/ghost/GP_ghost.vcproj
index ffa4c00f098..3d6794a795f 100644
--- a/projectfiles_vc7/gameengine/gameplayer/ghost/GP_ghost.vcproj
+++ b/projectfiles_vc7/gameengine/gameplayer/ghost/GP_ghost.vcproj
@@ -21,7 +21,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\openal\include;..\..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\..\build\msvc_7\intern\SoundSystem\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\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"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\openal\include;..\..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\..\build\msvc_7\intern\SoundSystem\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\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"
PreprocessorDefinitions="WIN32,_CONSOLE,dSINGLE, _DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -40,7 +40,7 @@
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386
"
- AdditionalDependencies="libguardedalloc.lib libstring.lib libghost.lib odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libblenkey.lib libeay32.lib libpng.lib libz.lib libmoto.lib libSoundSystem.lib qtmlClient.lib libDummySoundSystem.lib libOpenALSoundSystem.lib SDL.lib solid.lib freetype2ST.lib Bullet.lib libdecimation.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib verse.lib"
+ AdditionalDependencies="libguardedalloc.lib libstring.lib libghost.lib odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib libmoto.lib libSoundSystem.lib qtmlClient.lib libDummySoundSystem.lib libOpenALSoundSystem.lib SDL.lib solid.lib freetype2ST.lib Bullet.lib libdecimation.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib verse.lib libopennl.lib"
ShowProgress="0"
OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"
LinkIncremental="2"
@@ -97,7 +97,7 @@ ECHO Done
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\openal\include;..\..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\..\build\msvc_7\intern\SoundSystem\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\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"
+ AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\openal\include;..\..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\..\build\msvc_7\intern\iksolver\include;..\..\..\..\..\build\msvc_7\intern\SoundSystem\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\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"
PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -116,7 +116,7 @@ ECHO Done
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="libguardedalloc.lib libstring.lib libghost.lib odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libblenkey.lib libeay32.lib libpng.lib libz.lib libmoto.lib libSoundSystem.lib qtmlClient.lib libDummySoundSystem.lib libOpenALSoundSystem.lib SDL.lib solid.lib freetype2ST.lib Bullet.lib libdecimation.lib python25.lib pthreadVSE2.lib pthreadVC2.lib verse.lib"
+ AdditionalDependencies="libguardedalloc.lib libstring.lib libghost.lib odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib libmoto.lib libSoundSystem.lib qtmlClient.lib libDummySoundSystem.lib libOpenALSoundSystem.lib SDL.lib solid.lib freetype2ST.lib Bullet.lib libdecimation.lib python25.lib pthreadVSE2.lib pthreadVC2.lib verse.lib libopennl.lib"
OutputFile="..\..\..\..\bin\blenderplayer.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
diff --git a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
index 129084f7b1b..75a2a852011 100644
--- a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
+++ b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
@@ -330,6 +330,9 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
+ RelativePath="..\..\..\source\gameengine\Rasterizer\RAS_2DFilterManager.cpp">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Rasterizer\RAS_BucketManager.cpp">
</File>
<File
@@ -361,6 +364,9 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
+ RelativePath="..\..\..\source\gameengine\Rasterizer\RAS_2DFilterManager.h">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Rasterizer\RAS_BucketManager.h">
</File>
<File
diff --git a/projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj b/projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
index 40bd1369aae..6046cc5cac5 100644
--- a/projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
+++ b/projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
@@ -367,6 +367,40 @@
RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer\RAS_VAOpenGLRasterizer.h">
</File>
</Filter>
+ <Filter
+ Name="Filters"
+ Filter="">
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Blur2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Dilation2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Erosion2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_GrayScale2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Invert2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Laplacian2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Prewitt2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Sepia2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Sharpen2DFilter.h">
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Rasterizer\RAS_OpenGLFilters\RAS_Sobel2DFilter.h">
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
diff --git a/release/Makefile b/release/Makefile
index 2791982a6fa..fa288314f03 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -31,54 +31,63 @@
include nan_definitions.mk
-export VERSION := $(shell cat VERSION)
+export VERSION := $(shell ./getversion.py)
-BLENDNAME=blender-$(VERSION)-$(CONFIG_GUESS)$(TYPE)
+BLENDNAME=blender-$(VERSION)-$(CONFIG_GUESS)-py$(NAN_PYTHON_VERSION)$(TYPE)
export DISTDIR=$(NAN_OBJDIR)/$(BLENDNAME)
export CONFDIR=$(DISTDIR)/.blender
+ifeq ($(OS),beos)
+ TAR="zip"
+ TARFLAGS="-ry9"
+ EXT0=""
+ EXT1=".zip"
+ COMPRESS=""
+ EXT2=""
+ NOPLUGINS?=true
+endif
+
+ifeq ($(OS),$(findstring $(OS), "freebsd irix linux openbsd solaris"))
+ TAR="tar"
+ TARFLAGS="cf"
+ EXT0=""
+ EXT1=".tar"
+ COMPRESS="bzip2"
+ COMPRESSFLAGS="-f"
+ EXT2=".bz2"
+ ifeq ($(OS), solaris)
+ ifeq ($(CPU), i386)
+ NOPLUGINS?=true
+ endif
+ endif
+endif
+
+ifeq ($(OS),windows)
+ TAR="zip"
+ TARFLAGS="-r9"
+ EXT0=".exe"
+ EXT1=".zip"
+ NOPLUGINS?=true
+ NOSTRIP?=true
+endif
+
+ifeq ($(OS),darwin)
+ TAR="tar"
+ TARFLAGS="cf"
+ EXT0=".app"
+ EXT1=".tar"
+ COMPRESS="bzip2"
+ COMPRESSFLAGS="-f"
+ EXT2=".bz2"
+endif
release: all
all:
- ifeq ($(OS),beos)
- @$(MAKE) pkg TYPE="" TAR="zip -ry9" EXT1=".zip" NOPLUGINS="true"
- endif
- ifeq ($(OS),freebsd)
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
- ifeq ($(OS),irix)
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
- ifeq ($(OS),linux)
- ifeq ($(CPU),alpha)
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- else
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
- endif
- ifeq ($(OS),openbsd)
- @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
- ifeq ($(OS),solaris)
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
- ifeq ($(OS),windows)
- @$(MAKE) pkg TYPE="" TAR="zip -r9" EXT0=".exe" EXT1=".zip" \
- NOPLUGINS="true" NOSTRIP="true"
- endif
- ifeq ($(OS),darwin)
- @$(MAKE) pkg TYPE="" TAR="tar cf" EXT0"=.app" EXT1=".tar" \
- COMPRESS="bzip2 -f" EXT2=".bz2"
- endif
+ @$(MAKE) pkg TYPE=""
+ifeq ($(WITH_BF_STATICOPENGL), true)
+ @$(MAKE) pkg TYPE="-static"
+endif
# OS independent targets below:
@@ -112,8 +121,9 @@ install: package
ifneq ($(OS), darwin)
@[ ! -d $(OCGDIR)/bin/.blender ] || \
cp -r $(OCGDIR)/bin/.blender $(DISTDIR)
- cp $(NANBLENDERHOME)/bin/.blender/.Blanguages $(CONFDIR)
- cp $(NANBLENDERHOME)/bin/.blender/.bfont.ttf $(CONFDIR)
+ @rm -rf $(DISTDIR)/.svn $(DISTDIR)/*/.svn $(DISTDIR)/*/*/.svn
+ @cp $(NANBLENDERHOME)/bin/.blender/.Blanguages $(CONFDIR)
+ @cp $(NANBLENDERHOME)/bin/.blender/.bfont.ttf $(CONFDIR)
endif
@echo "----> Copy blender$(EXT0) executable"
ifeq ($(TYPE),-static)
@@ -137,7 +147,7 @@ ifneq ($(NOPLUGINS),true)
@cp ../source/blender/blenpluginapi/*.h $(DISTDIR)/plugins/include/
@chmod 755 $(DISTDIR)/plugins/bmake
@$(MAKE) -C $(DISTDIR)/plugins all > /dev/null || exit 1;
- @rm -fr $(DISTDIR)/plugins/CVS $(DISTDIR)/plugins/*/CVS \
+ @rm -fr $(DISTDIR)/plugins/.svn $(DISTDIR)/plugins/*/.svn \
$(DISTDIR)/plugins/*/*.o
#on OS X the plugins move to the installation directory
@@ -151,7 +161,7 @@ endif
@echo "----> Copy python infrastructure"
@[ ! -d scripts ] || cp -r scripts $(CONFDIR)/scripts
- @[ ! -d $(CONFDIR)/scripts ] || rm -fr $(CONFDIR)/scripts/CVS
+ @[ ! -d $(CONFDIR)/scripts ] || rm -fr $(CONFDIR)/scripts/.svn $(CONFDIR)/scripts/*/.svn $(CONFDIR)/scripts/*/*/.svn
ifeq ($(OS),darwin)
@echo "----> Move .blender to .app/Contents/MacOS/"
@@ -178,12 +188,11 @@ pkg: install
@echo "----> Create distribution file $(BLENDNAME)$(EXT1)"
@#enable the next sleep if you get 'tar file changed while reading'
@#sleep 10
- @cd $(NAN_OBJDIR) && \
- rm -f $(VERSION)/$(BLENDNAME)$(EXT1)* && \
- $(TAR) $(VERSION)/$(BLENDNAME)$(EXT1) $(BLENDNAME)
+ rm -f $(NAN_OBJDIR)/$(VERSION)/$(BLENDNAME)$(EXT1)*
+ @cd $(NAN_OBJDIR) && $(TAR) $(TARFLAGS) $(VERSION)/$(BLENDNAME)$(EXT1) $(BLENDNAME)
ifdef COMPRESS
@echo "----> Compressing distribution to $(BLENDNAME)$(EXT1)$(EXT2)"
- @$(COMPRESS) $(NAN_OBJDIR)/$(VERSION)/$(BLENDNAME)$(EXT1)
+ @$(COMPRESS) $(COMPRESSFLAGS) $(NAN_OBJDIR)/$(VERSION)/$(BLENDNAME)$(EXT1)
endif
@#echo "****> Clean up temporary distribution directory"
@rm -fr $(DISTDIR)
diff --git a/release/datafiles/preview.blend b/release/datafiles/preview.blend
index 8d67a88f679..9e09d579b2b 100644
--- a/release/datafiles/preview.blend
+++ b/release/datafiles/preview.blend
Binary files differ
diff --git a/release/datafiles/prvicons b/release/datafiles/prvicons
new file mode 100644
index 00000000000..de3980f9676
--- /dev/null
+++ b/release/datafiles/prvicons
Binary files differ
diff --git a/release/datafiles/splash.jpg b/release/datafiles/splash.jpg
new file mode 100644
index 00000000000..243e779273d
--- /dev/null
+++ b/release/datafiles/splash.jpg
Binary files differ
diff --git a/release/getversion.py b/release/getversion.py
new file mode 100755
index 00000000000..a64a6189b6f
--- /dev/null
+++ b/release/getversion.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2008 by the Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+import sys, os, re
+
+nanblenderhome = os.getenv("NANBLENDERHOME");
+
+if nanblenderhome == None:
+ nanblenderhome = os.path.dirname(os.path.abspath(sys.argv[0]))+"/.."
+
+config = nanblenderhome+"/source/blender/blenkernel/BKE_blender.h"
+
+infile = open(config)
+
+major = None
+minor = None
+
+for line in infile.readlines():
+ m = re.search("#define BLENDER_VERSION\s+(\d+)", line)
+ if m:
+ major = m.group(1)
+ m = re.search("#define BLENDER_SUBVERSION\s+(\d+)", line)
+ if m:
+ minor = m.group(1)
+ if minor and major:
+ major = float(major) / 100.0
+ break
+
+infile.close()
+
+if minor and major:
+ print str(major)+"."+minor
+else:
+ print "unknownversion"
diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py
index 56acc50e38d..07da4df1603 100644
--- a/release/scripts/3ds_import.py
+++ b/release/scripts/3ds_import.py
@@ -1,7 +1,7 @@
#!BPY
"""
Name: '3D Studio (.3ds)...'
-Blender: 241
+Blender: 244
Group: 'Import'
Tooltip: 'Import from 3DS file format (.3ds)'
"""
@@ -382,7 +382,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
# +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 contextMeshUV or img:
+ if bmesh.faces and (contextMeshUV or img):
bmesh.faceUV= 1
for ii, i in enumerate(faces):
@@ -945,6 +945,7 @@ if __name__=='__main__' and not DEBUG:
#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:
# DEBUG ONLY
TIME= Blender.sys.time()
@@ -956,6 +957,11 @@ else:
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):
@@ -963,8 +969,8 @@ else:
return False
for i, _3ds in enumerate(lines):
- if between(i, 1,200):
- _3ds= _3ds[:-1]
+ 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)
@@ -972,4 +978,5 @@ else:
load_3ds(_3ds, False)
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
+
''' \ No newline at end of file
diff --git a/release/scripts/DirectX8Importer.py b/release/scripts/DirectX8Importer.py
index 7e6a8429759..0dda654944d 100644
--- a/release/scripts/DirectX8Importer.py
+++ b/release/scripts/DirectX8Importer.py
@@ -2,7 +2,7 @@
""" Registration info for Blender menus:
Name: 'DirectX(.x)...'
-Blender: 240
+Blender: 244
Group: 'Import'
Tip: 'Import from DirectX text file format format.'
@@ -25,7 +25,7 @@ Tip: 'Import from DirectX text file format format.'
# Grab the latest version here :www.omariben.too.it
import bpy
import Blender
-from Blender import NMesh,Object,Material,Texture,Image,Draw
+from Blender import Mesh,Object,Material,Texture,Image,Draw
class xImport:
@@ -41,13 +41,16 @@ class xImport:
lines = self.lines
print "importing into Blender ..."
scene = bpy.data.scenes.active
- mesh = NMesh.GetRaw()
+
+ 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
- idx = 0
i = -1
mat_list = []
tex_list = []
@@ -56,31 +59,33 @@ class xImport:
l = line.strip()
words = line.split()
if words[0] == "Material" :
- idx += 1
- self.writeMaterials(j, idx, mat_list, tex_list)
+ #context_indicies["Material"] = j
+ self.loadMaterials(j, mat_list, tex_list)
elif words[0] == "MeshTextureCoords" :
- nr_uv_ind = j
+ context_indicies["MeshTextureCoords"] = j
+ #nr_uv_ind = j
elif words[0] == "MeshMaterialList" :
- nr_fac_mat = j + 2
+ context_indicies["MeshMaterialList"] = j+2
+ #nr_fac_mat = j + 2
elif words[0] == "Mesh": # Avoid a second loop
- mesh_line_indicies.append(j)
-
- #Create The Mesh
- for nr_vr_ind in mesh_line_indicies:
- self.writeVertices(nr_vr_ind, mesh, nr_uv_ind, nr_fac_mat, tex_list)
-
- mesh.setMaterials(mat_list)
- if nr_fac_mat:
- self.writeMeshMaterials(nr_fac_mat, mesh)
- NMesh.PutRaw(mesh,"Mesh",1)
-
+ 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 writeVertices(self, nr_vr_ind, mesh, nr_uv, nr_fac_mat, tex_list):
+ 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 :
@@ -92,7 +97,6 @@ class xImport:
lin_c = self.CleanLine(lin)
nr_vert = int((lin_c.split()[0]))
- vx_array = range(v_ind + 1, (v_ind + nr_vert +1))
#--------------------------------------------------
nr_fac_li = v_ind + nr_vert +1
lin_f = self.lines[nr_fac_li]
@@ -105,136 +109,80 @@ class xImport:
lin_fc = self.CleanLine(lin_f)
nr_face = int((lin_fc.split()[0]))
- fac_array = range(nr_fac_li + 1, (nr_fac_li + nr_face + 1))
#Get Coordinates
- for l in vx_array:
+ 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:
- mesh.verts.append(NMesh.Vert(float(words[0]),float(words[1]),float(words[2])))
-
+ 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 fac_array:
+ 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:
- f= NMesh.Face([\
- mesh_verts[int(words[1])],
- mesh_verts[int(words[2])],
- mesh_verts[int(words[3])],
- mesh_verts[int(words[4])]])
-
- mesh.faces.append(f)
- if nr_uv :
- uv = []
- #---------------------------------
- l1_uv = self.lines[nr_uv + 2 + int(words[1])]
- fixed_l1_uv = self.CleanLine(l1_uv)
- w1 = fixed_l1_uv.split()
- uv_1 = (float(w1[0]), -float(w1[1]))
- uv.append(uv_1)
- #---------------------------------
- l2_uv = self.lines[nr_uv + 2 + int(words[2])]
- fixed_l2_uv = self.CleanLine(l2_uv)
- w2 = fixed_l2_uv.split()
- uv_2 = (float(w2[0]), -float(w2[1]))
- uv.append(uv_2)
- #---------------------------------
- l3_uv = self.lines[nr_uv + 2 + int(words[3])]
- fixed_l3_uv = self.CleanLine(l3_uv)
- w3 = fixed_l3_uv.split()
- uv_3 = (float(w3[0]), -float(w3[1]))
- uv.append(uv_3)
- #---------------------------------
- l4_uv = self.lines[nr_uv + 2 + int(words[4])]
- fixed_l4_uv = self.CleanLine(l4_uv)
- w4 = fixed_l4_uv.split()
- uv_4 = (float(w4[0]), -float(w4[1]))
- uv.append(uv_4)
- #---------------------------------
- f.uv = uv
- 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])
- name_tex = tex_list[w_tex]
- if name_tex :
- name_file = Blender.sys.join(my_path,name_tex)
- try:
- img = Image.Load(name_file)
- f.image = img
- except:
- #Draw.PupMenu("No image to load")
- #print "No image " + name_tex + " to load"
- pass
-
+ face_list.append((1+int(words[1]), 1+int(words[2]), 1+int(words[3]), 1+int(words[4])))
elif len(words) == 4:
- f=NMesh.Face([\
- mesh_verts[int(words[1])],\
- mesh_verts[int(words[2])],\
- mesh_verts[int(words[3])]])
-
- mesh.faces.append(f)
- if nr_uv :
- uv = []
- #---------------------------------
- l1_uv = self.lines[nr_uv + 2 + int(words[1])]
- fixed_l1_uv = self.CleanLine(l1_uv)
- w1 = fixed_l1_uv.split()
- uv_1 = (float(w1[0]), -float(w1[1]))
- uv.append(uv_1)
- #---------------------------------
- l2_uv = self.lines[nr_uv + 2 + int(words[2])]
- fixed_l2_uv = self.CleanLine(l2_uv)
- w2 = fixed_l2_uv.split()
- uv_2 = (float(w2[0]), -float(w2[1]))
- uv.append(uv_2)
- #---------------------------------
- l3_uv = self.lines[nr_uv + 2 + int(words[3])]
- fixed_l3_uv = self.CleanLine(l3_uv)
- w3 = fixed_l3_uv.split()
- uv_3 = (float(w3[0]), -float(w3[1]))
- uv.append(uv_3)
- #---------------------------------
- f.uv = uv
- 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])
- name_tex = tex_list[w_tex]
- if name_tex :
- name_file = Blender.sys.join(my_path ,name_tex)
- try:
- img = Image.Load(name_file)
- f.image = img
- except:
- #Draw.PupMenu("No image to load")
- #print "No image " + name_tex + " to load"
- pass
-
-
-
-
+ 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):
- fix_line = line.replace(";", " ")
- fix_1_line = fix_line.replace('"', ' ')
- fix_2_line = fix_1_line.replace("{", " ")
- fix_3_line = fix_2_line.replace("}", " ")
- fix_4_line = fix_3_line.replace(",", " ")
- fix_5_line = fix_4_line.replace("'", " ")
- return fix_5_line
+ return line.replace(\
+ ";", " ").replace(\
+ '"', ' ').replace(\
+ "{", " ").replace(\
+ "}", " ").replace(\
+ ",", " ").replace(\
+ "'", " ")
#------------------------------------------------------------------
# CREATE MATERIALS
#------------------------------------------------------------------
- def writeMaterials(self, nr_mat, idx, mat_list, tex_list):
- name = "Material_" + str(idx)
- mat = Material.New(name)
+ 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()
@@ -244,35 +192,33 @@ class xImport:
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(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(tex_n_succ[0])
+ tex_list.append(load_image(tex_n_succ[0]))
else :
- tex_name = None
- tex_list.append(tex_name)
+ tex_list.append(None) # no texture for this index
return mat_list, tex_list
#------------------------------------------------------------------
# SET MATERIALS
#------------------------------------------------------------------
- def writeMeshMaterials(self, nr_fc_mat, mesh):
+ 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.materialIndex = mat_idx
-
+ face.mat = mat_idx
#------------------------------------------------------------------
# MAIN
@@ -286,4 +232,7 @@ arg = __script__['arg']
if __name__ == '__main__':
Blender.Window.FileSelector(my_callback, "Import DirectX", "*.x")
-# my_callback('/directxterrain.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/ac3d_import.py b/release/scripts/ac3d_import.py
index d538838fdf3..9a7004e4b4d 100644
--- a/release/scripts/ac3d_import.py
+++ b/release/scripts/ac3d_import.py
@@ -679,6 +679,8 @@ class AC3DImport:
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('\\','/'))
diff --git a/release/scripts/add_mesh_empty.py b/release/scripts/add_mesh_empty.py
new file mode 100644
index 00000000000..537bd1e2c3d
--- /dev/null
+++ b/release/scripts/add_mesh_empty.py
@@ -0,0 +1,13 @@
+#!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
index de2db42d482..4f759256497 100644
--- a/release/scripts/add_mesh_torus.py
+++ b/release/scripts/add_mesh_torus.py
@@ -51,9 +51,9 @@ def main():
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, 'Radius for the main ring of the torus'),\
- ('Minor Segments:', PREF_MINOR_SEG, 3, 256, 'Radius for the minor ring of the torus setting the thickness of the ring.'),\
+ ('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
@@ -61,4 +61,5 @@ def main():
BPyAddMesh.add_mesh_simple('Torus', verts, [], faces)
-main() \ No newline at end of file
+main()
+
diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py
index 70fc1a87a52..415c2a12c69 100644
--- a/release/scripts/bpymodules/BPyMesh.py
+++ b/release/scripts/bpymodules/BPyMesh.py
@@ -56,7 +56,7 @@ def meshWeight2List(me):
if not len_groupNames:
# no verts? return a vert aligned empty list
- return [[] for i in xrange(len(me.verts))]
+ return [[] for i in xrange(len(me.verts))], []
else:
vWeightList= [[0.0]*len_groupNames for i in xrange(len(me.verts))]
diff --git a/release/scripts/bpymodules/BPyMessages.py b/release/scripts/bpymodules/BPyMessages.py
index 0ff8e178ac1..8ee1aa6c707 100644
--- a/release/scripts/bpymodules/BPyMessages.py
+++ b/release/scripts/bpymodules/BPyMessages.py
@@ -11,6 +11,8 @@ 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):
diff --git a/release/scripts/bpymodules/BPyObject.py b/release/scripts/bpymodules/BPyObject.py
index 7de2c4113f9..54ff949218d 100644
--- a/release/scripts/bpymodules/BPyObject.py
+++ b/release/scripts/bpymodules/BPyObject.py
@@ -10,7 +10,7 @@ def getObjectArmature(ob):
arm = ob.parent
if arm and arm.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE:
- arm
+ return arm
for m in ob.modifiers:
if m.type== Blender.Modifier.Types.ARMATURE:
diff --git a/release/scripts/bpymodules/BPyRender.py b/release/scripts/bpymodules/BPyRender.py
index bb5ef628356..a83eb6a8de8 100644
--- a/release/scripts/bpymodules/BPyRender.py
+++ b/release/scripts/bpymodules/BPyRender.py
@@ -91,7 +91,7 @@ def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True, cam
render_cam_ob= Object.New('Camera')
render_cam_ob.link(render_cam_data)
render_scn.link(render_cam_ob)
- render_scn.setCurrentCamera(render_cam_ob)
+ render_scn.objects.camera = render_cam_ob
render_cam_data.type= 'ortho'
@@ -181,7 +181,6 @@ def imageFromObjectsOrtho(objects, path, width, height, smooth, alpha= True, cam
Blender.Window.RedrawAll()
- render_context.threads= 2 # good for dual core cpu's
render_context.render()
render_context.saveRenderedImage(path)
Render.CloseRenderWindow()
@@ -496,3 +495,135 @@ def vcol2image(me_s,\
mat.mode &= ~Blender.Material.Modes.SHADELESS
return image
+
+def bakeToPlane(sce, ob_from, width, height, bakemodes, axis='z', margin=0):
+ '''
+ 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.
+
+ 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 object selection
+ BACKUP_obsel = list(sce.objects.selected)
+ BACKUP_obact = sce.objects.active
+
+ # New bake settings
+ rend.bakeClear = True
+ rend.bakeMargin = margin
+ BACKUP_bakeToActive = 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
+ 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
+ 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
+ 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, 24)
+
+ 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
+
+ # 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/blend2renderinfo.py b/release/scripts/bpymodules/blend2renderinfo.py
new file mode 100644
index 00000000000..1b9dec58d55
--- /dev/null
+++ b/release/scripts/bpymodules/blend2renderinfo.py
@@ -0,0 +1,95 @@
+#!/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/paths_ai2obj.py b/release/scripts/bpymodules/paths_ai2obj.py
index dcf56853184..6eb5023a8d4 100644
--- a/release/scripts/bpymodules/paths_ai2obj.py
+++ b/release/scripts/bpymodules/paths_ai2obj.py
@@ -1,3 +1,4 @@
+# -*- coding: latin-1 -*-
"""
paths_ai2obj.py
# ---------------------------------------------------------------
@@ -42,10 +43,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Communiquer les problemes et erreurs sur:
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
#----------------------------------------------
+
+#Changelog
#----------------------------------------------
-#Chagelog
-#----------------------------------------------
-# 0.1.1 : 2004/08/03, bug in boudingbox reading when Value are negative
+# 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
@@ -57,6 +58,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# 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
diff --git a/release/scripts/bpymodules/paths_gimp2obj.py b/release/scripts/bpymodules/paths_gimp2obj.py
index 8b31c5d7294..c2ce9718c71 100644
--- a/release/scripts/bpymodules/paths_gimp2obj.py
+++ b/release/scripts/bpymodules/paths_gimp2obj.py
@@ -1,3 +1,4 @@
+# -*- coding: latin-1 -*-
"""
#----------------------------------------------
# (c) jm soler juillet 2004,
@@ -43,6 +44,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# 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
diff --git a/release/scripts/bvh_import.py b/release/scripts/bvh_import.py
index d027956a507..2093ac109f7 100644
--- a/release/scripts/bvh_import.py
+++ b/release/scripts/bvh_import.py
@@ -110,7 +110,7 @@ def eulerRotate(x,y,z, rot_order):
def read_bvh(file_path, GLOBAL_SCALE=1.0):
# File loading stuff
# Open the file for importing
- file = open(file_path, 'r')
+ file = open(file_path, 'rU')
# Seperate into a list of lists, each line a list of words.
file_lines = file.readlines()
@@ -354,7 +354,7 @@ def bvh_node_dict2objects(bvh_nodes, IMPORT_START_FRAME= 1, IMPORT_LOOP= False):
bvh_node.temp.rot= rx*DEG2RAD,ry*DEG2RAD,rz*DEG2RAD
- bvh_node.temp.insertIpoKey(Blender.Object.IpoKeys.LOCROT)
+ bvh_node.temp.insertIpoKey(Blender.Object.IpoKeyTypes.LOCROT)
scn.update(1)
return objects
diff --git a/release/scripts/console.py b/release/scripts/console.py
index e253e3c9857..7d9d8be5e9e 100644
--- a/release/scripts/console.py
+++ b/release/scripts/console.py
@@ -285,6 +285,8 @@ def runUserCode(__USER_CODE_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__
@@ -295,7 +297,8 @@ def runUserCode(__USER_CODE_STRING__):
# 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\
@@ -715,6 +718,15 @@ def draw_gui():
else:
BGL.glColor3f(1, 1, 0)
+ if consoleLineIdx == 1: # user input
+ BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8)
+ Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0])
+ else:
+ BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8)
+ Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0])
+
+ # Wrapping is totally slow, can even hang blender - dont do it!
+ '''
if consoleLineIdx == 1: # NEVER WRAP THE USER INPUT
BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8)
# BUG, LARGE TEXT DOSENT DISPLAY
@@ -751,7 +763,7 @@ def draw_gui():
BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8)
Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0])
-
+ '''
consoleLineIdx += 1
@@ -774,8 +786,9 @@ histIndex = cursor = -1 # How far back from the first letter are we? - in curren
# Autoexec, startup code.
scriptDir = Get('scriptsdir')
+console_autoexec = None
if scriptDir:
- if scriptDir.endswith(Blender.sys.sep):
+ if not scriptDir.endswith(Blender.sys.sep):
scriptDir += Blender.sys.sep
console_autoexec = '%s%s' % (scriptDir, 'console_autoexec.py')
@@ -788,7 +801,10 @@ if scriptDir:
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))
@@ -802,7 +818,8 @@ def include_console(includeFile):
# Execute an external py file as if local
exec(include(includeFile))
-
+
+def standard_imports():
# Write local to global __CONSOLE_VAR_DICT__ for reuse,
for ls in (dir(), dir(Blender)):
for __TMP_VAR_NAME__ in ls:
@@ -810,10 +827,12 @@ def include_console(includeFile):
exec('%s%s' % ('__CONSOLE_VAR_DICT__[__TMP_VAR_NAME__]=', __TMP_VAR_NAME__))
exec('%s%s' % ('__CONSOLE_VAR_DICT__["bpy"]=', 'bpy'))
-
-if scriptDir:
+
+if scriptDir and console_autoexec:
include_console(console_autoexec) # pass the blender module
+standard_imports() # import Blender and bpy
+
#-end autoexec-----------------------------------------------------------------#
@@ -827,4 +846,4 @@ def main():
Draw.Register(draw_gui, handle_event, handle_button_event)
if __name__ == '__main__':
- main() \ No newline at end of file
+ main()
diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py
index a4a4787d5f3..99d036b38bc 100644
--- a/release/scripts/export_fbx.py
+++ b/release/scripts/export_fbx.py
@@ -1,7 +1,7 @@
#!BPY
"""
Name: 'Autodesk FBX (.fbx)...'
-Blender: 243
+Blender: 244
Group: 'Export'
Tooltip: 'Selection to an ASCII Autodesk FBX '
"""
@@ -12,13 +12,8 @@ __version__ = "1.1"
__bpydoc__ = """\
This script is an exporter to the FBX file format.
-Usage:
-
-Select the objects you wish to export and run this script from "File->Export" menu.
-All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
-will be exported as mesh data.
+http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx
"""
-
# --------------------------------------------------------------------------
# FBX Export v0.1 by Campbell Barton (AKA Ideasman)
# --------------------------------------------------------------------------
@@ -41,57 +36,470 @@ will be exported as mesh data.
# ***** 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
+
+# for python 2.3 support
+try:
+ set()
+except:
+ try:
+ from sets import Set as set
+ 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
+
import Blender
+import bpy
+from Blender.Mathutils import Matrix, Vector, RotationMatrix
+
import BPyObject
import BPyMesh
import BPySys
import BPyMessages
-import time
-from math import degrees, atan, pi
-# Used to add the scene name into the filename without using odd chars
+import sys
+
+## 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,42,43,47,58,59,60,61,62,63,64,92,94,96,124,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])
+def cleanName(name):
+ for ch in invalid: name = name.replace(ch, '_')
+ return name
+del v, i
+
+
+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, textures):
+ if not dest_dir.endswith(Blender.sys.sep):
+ dest_dir += Blender.sys.sep
+
+ image_paths = set()
+ for img in textures:
+ image_paths.add(Blender.sys.expandpath(img.filename))
+
+ # Now copy images
+ copyCount = 0
+ for image_path in image_paths:
+ if Blender.sys.exists(image_path):
+ # 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)
+ try:
+ copy_file(image_path, dest_image_path)
+ copyCount+=1
+ except:
+ print '\t\tWarning, file failed to copy, skipping.'
+
+ print '\tCopied %d images' % copyCount
+
+mtx4_identity = Matrix()
+
+# testing
+mtx_x90 = RotationMatrix( 90, 3, 'x') # used
+#mtx_x90n = RotationMatrix(-90, 3, 'x')
+#mtx_y90 = RotationMatrix( 90, 3, 'y')
+#mtx_y90n = RotationMatrix(-90, 3, 'y')
+#mtx_z90 = RotationMatrix( 90, 3, 'z')
+#mtx_z90n = RotationMatrix(-90, 3, 'z')
+
+#mtx4_x90 = RotationMatrix( 90, 4, 'x')
+mtx4_x90n = RotationMatrix(-90, 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
+
+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 = {}
sane_name_mapping_mat = {}
sane_name_mapping_tex = {}
+sane_name_mapping_take = {}
+sane_name_mapping_group = {}
-def strip_path(p):
- return p.split('\\')[-1].split('/')[-1]
+# Make sure reserved names are not used
+sane_name_mapping_ob['Scene'] = 'Scene_'
+sane_name_mapping_ob['blend_root'] = 'blend_root_'
+
+def increment_string(t):
+ name = t
+ num = ''
+ while name and name[-1].isdigit():
+ num = name[-1] + num
+ name = name[:-1]
+ if num: return '%s%d' % (name, int(num)+1)
+ else: return name + '_0'
+
+
+# todo - Disallow the name 'Scene' and 'blend_root' - it will bugger things up.
def sane_name(data, dct):
- if not data: return None
+ #if not data: return None
name = data.name
- try: return dct[name]
- except: pass
+
+ # dont cache, only ever call once for each data type now,
+ # so as to avoid namespace collision between types - like with objects <-> bones
+ #try: return dct[name]
+ #except: pass
orig_name = name
- name = BPySys.cleanName(name)
+ if not name:
+ name = 'unnamed' # blank string, ASKING FOR TROUBLE!
+ else:
+ #name = BPySys.cleanName(name)
+ name = cleanName(name) # use our own
+
+ while name in dct.itervalues(): name = increment_string(name)
+
dct[orig_name] = name
return name
def sane_obname(data): return sane_name(data, sane_name_mapping_ob)
def sane_matname(data): return sane_name(data, sane_name_mapping_mat)
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)
+
-# May use this later
-"""
-# Auto class, use for datastorage only, a like a dictionary but with limited slots
-def auto_class(slots):
- exec('class container_class(object): __slots__=%s' % slots)
- return container_class
-"""
+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 ])
+
+def meshNormalizedWeights(me):
+ try: # account for old bad BPyMesh
+ groupNames, vWeightList = BPyMesh.meshWeight2List(me)
+ except:
+ return [],[]
+
+ if not groupNames:
+ return [],[]
+
+ for i, vWeights in enumerate(vWeightList):
+ tot = 0.0
+ for w in vWeights:
+ tot+=w
+
+ if tot:
+ for j, w in enumerate(vWeights):
+ vWeights[j] = w/tot
+
+ return groupNames, vWeightList
+
header_comment = \
'''; FBX 6.1.0 project file
; Created by Blender FBX Exporter
-; for support mail cbarton@metavr.com
+; for support mail: ideasman42@gmail.com
; ----------------------------------------------------
'''
-def write_header(file):
+# This func can be called with just the filename
+def write(filename, batch_objects = None, \
+ EXP_OBS_SELECTED = True,
+ EXP_MESH = True,
+ EXP_MESH_APPLY_MOD = True,
+ EXP_MESH_HQ_NORMALS = False,
+ EXP_ARMATURE = True,
+ EXP_LAMP = True,
+ EXP_CAMERA = True,
+ EXP_EMPTY = True,
+ EXP_IMAGE_COPY = False,
+ GLOBAL_MATRIX = 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
+ ):
+
+ # ----------------- Batch support!
+ if BATCH_ENABLE:
+ if os == None: BATCH_OWN_DIR = False
+
+ fbxpath = filename
+
+ # get the path component of filename
+ 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!')
+ return
+
+ tmp_exists = Blender.sys.exists(fbxpath)
+
+ if tmp_exists != 2:
+ Draw.PupMenu('Error%t|Directory does not exist!')
+ return
+
+ if not fbxpath.endswith(Blender.sys.sep):
+ fbxpath += Blender.sys.sep
+ del tmp_exists
+
+
+ if BATCH_GROUP:
+ data_seq = bpy.data.groups
+ else:
+ data_seq = bpy.data.scenes
+
+ # call this function within a loop with BATCH_ENABLE == False
+ 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)
+
+
+ if BATCH_OWN_DIR:
+ new_fbxpath = fbxpath + newname + Blender.sys.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:
+ os.mkdir(new_fbxpath)
+
+
+ filename = new_fbxpath + newname + '.fbx'
+
+ print '\nBatch exporting %s as...\n\t"%s"' % (data, filename)
+
+ if BATCH_GROUP: #group
+ # group, so objects update properly, add a dummy scene.
+ sce = bpy.data.scenes.new()
+ sce.Layers = (1<<20) -1
+ bpy.data.scenes.active = sce
+ for ob_base in data.objects:
+ sce.objects.link(ob_base)
+
+ sce.update(1)
+
+ # TODO - BUMMER! Armatures not in the group wont animate the mesh
+
+ else:# scene
+
+
+ data_seq.active = data
+
+
+ # Call self with modified args
+ # Dont pass batch options since we alredy usedt them
+ write(filename, data.objects,
+ False,
+ EXP_MESH,
+ EXP_MESH_APPLY_MOD,
+ EXP_MESH_HQ_NORMALS,
+ EXP_ARMATURE,
+ EXP_LAMP,
+ EXP_CAMERA,
+ EXP_EMPTY,
+ EXP_IMAGE_COPY,
+ GLOBAL_MATRIX,
+ ANIM_ENABLE,
+ ANIM_OPTIMIZE,
+ ANIM_OPTIMIZE_PRECISSION,
+ ANIM_ACTION_ALL
+ )
+
+ if BATCH_GROUP:
+ # remove temp group scene
+ bpy.data.scenes.unlink(sce)
+
+ bpy.data.scenes.active = orig_sce
+
+ return # so the script wont run after we have batch exported.
+
+ # end batch support
+
+
+ # ----------------------------------------------
+ # storage classes
+ class my_bone_class:
+ __slots__ =(\
+ 'blenName',\
+ 'blenBone',\
+ 'blenMeshes',\
+ 'restMatrix',\
+ 'parent',\
+ 'blenName',\
+ 'fbxName',\
+ 'fbxArm',\
+ '__pose_bone',\
+ '__anim_poselist')
+
+ def __init__(self, blenBone, fbxArm):
+
+ # This is so 2 armatures dont have naming conflicts since FBX bones use object namespace
+ self.fbxName = sane_obname(blenBone)
+
+ self.blenName = blenBone.name
+ self.blenBone = blenBone
+ self.blenMeshes = {} # fbxMeshObName : mesh
+ self.fbxArm = fbxArm
+ self.restMatrix = blenBone.matrix['ARMATURESPACE']
+
+ # not used yet
+ # self.restMatrixInv = self.restMatrix.copy().invert()
+ # self.restMatrixLocal = None # set later, need parent matrix
+
+ self.parent = None
+
+ # not public
+ pose = fbxArm.blenObject.getPose()
+ self.__pose_bone = pose.bones[self.blenName]
+
+ # store a list if matricies here, (poseMatrix, head, tail)
+ # {frame:posematrix, frame:posematrix, ...}
+ self.__anim_poselist = {}
+
+ '''
+ def calcRestMatrixLocal(self):
+ if self.parent:
+ self.restMatrixLocal = self.restMatrix * self.parent.restMatrix.copy().invert()
+ else:
+ self.restMatrixLocal = self.restMatrix.copy()
+ '''
+ def setPoseFrame(self, f):
+ # cache pose info here, frame must be set beforehand
+
+ # Didnt end up needing head or tail, if we do - here it is.
+ '''
+ self.__anim_poselist[f] = (\
+ self.__pose_bone.poseMatrix.copy(),\
+ self.__pose_bone.head.copy(),\
+ self.__pose_bone.tail.copy() )
+ '''
+
+ self.__anim_poselist[f] = self.__pose_bone.poseMatrix.copy()
+
+ # get pose from frame.
+ def getPoseMatrix(self, f):# ----------------------------------------------
+ return self.__anim_poselist[f]
+ '''
+ def getPoseHead(self, f):
+ #return self.__pose_bone.head.copy()
+ return self.__anim_poselist[f][1].copy()
+ def getPoseTail(self, f):
+ #return self.__pose_bone.tail.copy()
+ return self.__anim_poselist[f][2].copy()
+ '''
+ # end
+
+ def getAnimParRelMatrix(self, frame):
+ #arm_mat = self.fbxArm.matrixWorld
+ #arm_mat = self.fbxArm.parRelMatrix()
+ if not self.parent:
+ #return mtx4_z90 * (self.getPoseMatrix(frame) * arm_mat) # dont apply arm matrix anymore
+ return mtx4_z90 * self.getPoseMatrix(frame)
+ else:
+ #return (mtx4_z90 * ((self.getPoseMatrix(frame) * arm_mat))) * (mtx4_z90 * (self.parent.getPoseMatrix(frame) * arm_mat)).invert()
+ return (mtx4_z90 * (self.getPoseMatrix(frame))) * (mtx4_z90 * self.parent.getPoseMatrix(frame)).invert()
+
+ # we need thes because cameras and lights modified rotations
+ def getAnimParRelMatrixRot(self, frame):
+ return self.getAnimParRelMatrix(frame)
+
+ def flushAnimData(self):
+ self.__anim_poselist.clear()
+
+
+ class my_object_generic:
+ # Other settings can be applied for each type - mesh, armature etc.
+ def __init__(self, ob, matrixWorld = None):
+ self.fbxName = sane_obname(ob)
+ self.blenObject = ob
+ 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
+ self.__anim_poselist = {} # we should only access this
+
+ def parRelMatrix(self):
+ if self.fbxParent:
+ return self.matrixWorld * self.fbxParent.matrixWorld.copy().invert()
+ else:
+ return self.matrixWorld
+
+ def setPoseFrame(self, f):
+ self.__anim_poselist[f] = self.blenObject.matrixWorld.copy()
+
+ def getAnimParRelMatrix(self, frame):
+ if self.fbxParent:
+ #return (self.__anim_poselist[frame] * self.fbxParent.__anim_poselist[frame].copy().invert() ) * GLOBAL_MATRIX
+ return (self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert()
+ else:
+ return self.__anim_poselist[frame] * GLOBAL_MATRIX
+
+ def getAnimParRelMatrixRot(self, frame):
+ type = self.blenObject.type
+ if self.fbxParent:
+ matrix_rot = (((self.__anim_poselist[frame] * GLOBAL_MATRIX) * (self.fbxParent.__anim_poselist[frame] * GLOBAL_MATRIX).invert())).rotationPart()
+ else:
+ matrix_rot = (self.__anim_poselist[frame] * GLOBAL_MATRIX).rotationPart()
+
+ # Lamps need to be rotated
+ 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)
+
+ return matrix_rot
+
+ # ----------------------------------------------
+
+
+
+
+
+ print '\nFBX export starting...', filename
+ start_time = Blender.sys.time()
+ try:
+ file = open(filename, 'w')
+ except:
+ return False
+
+ sce = bpy.data.scenes.active
+ world = sce.world
+
+
+ # ---------------------------- Write the header first
file.write(header_comment)
- curtime = time.localtime()[0:6]
+ if time:
+ curtime = time.localtime()[0:6]
+ else:
+ curtime = [0,0,0,0,0,0]
#
file.write(\
'''FBXHeaderExtension: {
@@ -115,49 +523,78 @@ def write_header(file):
file.write('\nCreationTime: "%.4i-%.2i-%.2i %.2i:%.2i:%.2i:000"' % curtime)
file.write('\nCreator: "Blender3D version %.2f"' % Blender.Get('version'))
-
-
-
-
-def write_scene(file, sce, world):
- def write_object_tx(ob, loc, matrix):
+ pose_items = [] # list of (fbxName, matrix) to write pose data for, easier to collect allong the way
+
+ # --------------- funcs for exporting
+ def object_tx(ob, loc, matrix, matrix_mod = None):
'''
- We have loc to set the location if non blender objects that have a location
+ Matrix mod is so armature objects can modify their bone matricies
'''
-
- if ob and not matrix: matrix = ob.matrixWorld
- matrix_rot = matrix
- #if matrix:
- # matrix = matrix_scale * matrix
-
- if matrix:
- loc = tuple(matrix.translationPart())
- scale = tuple(matrix.scalePart())
+ 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
+
+ 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
+ matrix = matrix * par_matrix.copy().invert()
+
+ matrix_rot = matrix.rotationPart()
+
+ loc = tuple(matrix.translationPart())
+ scale = tuple(matrix.scalePart())
+ rot = tuple(matrix_rot.toEuler())
- matrix_rot = matrix.rotationPart()
- # Lamps need to be rotated
- if ob and ob.type =='Lamp':
- matrix_rot = Blender.Mathutils.RotationMatrix(90, 4, 'x') * matrix
- rot = tuple(matrix_rot.toEuler())
- elif ob and ob.type =='Camera':
- y = Blender.Mathutils.Vector(0,1,0) * matrix_rot
- matrix_rot = matrix_rot * Blender.Mathutils.RotationMatrix(90, 3, 'r', y)
- rot = tuple(matrix_rot.toEuler())
- else:
- rot = tuple(matrix_rot.toEuler())
else:
- if not loc:
- loc = 0,0,0
- scale = 1,1,1
- rot = 0,0,0
+ # 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!"
+
+ matrix_rot = matrix
+ #if matrix:
+ # matrix = matrix_scale * matrix
+
+ if matrix:
+ loc = tuple(matrix.translationPart())
+ scale = tuple(matrix.scalePart())
+
+ matrix_rot = matrix.rotationPart()
+ # Lamps need to be rotated
+ if ob and ob.type =='Lamp':
+ 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)
+ rot = tuple(matrix_rot.toEuler())
+ else:
+ rot = tuple(matrix_rot.toEuler())
+ else:
+ if not loc:
+ loc = 0,0,0
+ scale = 1,1,1
+ rot = 0,0,0
+
+ return loc, rot, scale, matrix, matrix_rot
+
+ def write_object_tx(ob, loc, matrix, matrix_mod= None):
+ '''
+ We have loc to set the location if non blender objects that have a location
+
+ matrix_mod is only used for bones at the moment
+ '''
+ 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 Scaling", "Lcl Scaling", "A+",%.15f,%.15f,%.15f' % scale)
return loc, rot, scale, matrix, matrix_rot
- def write_object_props(ob=None, loc=None, matrix=None):
+ def write_object_props(ob=None, loc=None, matrix=None, matrix_mod=None):
# if the type is 0 its an empty otherwise its a mesh
# only difference at the moment is one has a color
file.write('''
@@ -165,16 +602,16 @@ def write_scene(file, sce, world):
Property: "QuaternionInterpolate", "bool", "",0
Property: "Visibility", "Visibility", "A+",1''')
- loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix)
+ loc, rot, scale, matrix, matrix_rot = write_object_tx(ob, loc, matrix, matrix_mod)
- # Rotation order
- # eEULER_XYZ
+ # Rotation order, note, for FBX files Iv loaded normal order is 1
+ # setting to zero.
+ # eEULER_XYZ = 0
# eEULER_XZY
# eEULER_YZX
# eEULER_YXZ
# eEULER_ZXY
- # eEULER_ZYX
-
+ # eEULER_ZYX
file.write('''
Property: "RotationOffset", "Vector3D", "",0,0,0
@@ -190,7 +627,7 @@ def write_scene(file, sce, world):
Property: "TranslationMaxX", "bool", "",0
Property: "TranslationMaxY", "bool", "",0
Property: "TranslationMaxZ", "bool", "",0
- Property: "RotationOrder", "enum", "",1
+ Property: "RotationOrder", "enum", "",0
Property: "RotationSpaceForLimitOnly", "bool", "",0
Property: "AxisLen", "double", "",10
Property: "PreRotation", "Vector3D", "",0,0,0
@@ -240,7 +677,7 @@ def write_scene(file, sce, world):
Property: "Show", "bool", "",1
Property: "NegativePercentShapeSupport", "bool", "",1
Property: "DefaultAttributeIndex", "int", "",0''')
- if ob:
+ 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')
@@ -248,6 +685,42 @@ def write_scene(file, sce, world):
return loc, rot, scale, matrix, matrix_rot
+
+ # -------------------------------------------- Armatures
+ #def write_bone(bone, name, matrix_mod):
+ def write_bone(my_bone):
+ file.write('\n\tModel: "Model::%s", "Limb" {' % my_bone.fbxName)
+ file.write('\n\t\tVersion: 232')
+
+ #poseMatrix = write_object_props(my_bone.blenBone, None, None, my_bone.fbxArm.parRelMatrix())[3]
+ poseMatrix = write_object_props(my_bone.blenBone)[3] # dont apply bone matricies anymore
+ pose_items.append( (my_bone.fbxName, poseMatrix) )
+
+
+ # file.write('\n\t\t\tProperty: "Size", "double", "",%.6f' % ((my_bone.blenData.head['ARMATURESPACE'] - my_bone.blenData.tail['ARMATURESPACE']) * my_bone.fbxArm.parRelMatrix()).length)
+ file.write('\n\t\t\tProperty: "Size", "double", "",1')
+
+ #((my_bone.blenData.head['ARMATURESPACE'] * my_bone.fbxArm.matrixWorld) - (my_bone.blenData.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']) * 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", "",1')
+ file.write('\n\t\t\tProperty: "Color", "ColorRGB", "",0.8,0.8,0.8')
+ file.write('\n\t\t\tProperty: "Color", "Color", "A",0.8,0.8,0.8')
+ file.write('\n\t\t}')
+ file.write('\n\t\tMultiLayer: 0')
+ file.write('\n\t\tMultiTake: 1')
+ file.write('\n\t\tShading: Y')
+ file.write('\n\t\tCulling: "CullingOff"')
+ file.write('\n\t\tTypeFlags: "Skeleton"')
+ file.write('\n\t}')
+
def write_camera_switch():
file.write('''
Model: "Model::Camera Switcher", "CameraSwitcher" {
@@ -370,7 +843,7 @@ def write_scene(file, sce, world):
write_camera_dummy('Producer Right', (4000,0,0), 1, 30000, 1, (0,1,0))
write_camera_dummy('Producer Left', (-4000,0,0), 1, 30000, 1, (0,1,0))
- def write_camera(ob, name):
+ def write_camera(my_cam):
'''
Write a blender camera
'''
@@ -379,11 +852,11 @@ def write_scene(file, sce, world):
height = render.sizeY
aspect = float(width)/height
- data = ob.data
+ data = my_cam.blenObject.data
- file.write('\n\tModel: "Model::%s", "Camera" {' % name )
+ file.write('\n\tModel: "Model::%s", "Camera" {' % my_cam.fbxName )
file.write('\n\t\tVersion: 232')
- loc, rot, scale, matrix, matrix_rot = write_object_props(ob)
+ loc, rot, scale, matrix, matrix_rot = write_object_props(my_cam.blenObject, None, my_cam.parRelMatrix())
file.write('\n\t\t\tProperty: "Roll", "Roll", "A+",0')
file.write('\n\t\t\tProperty: "FieldOfView", "FieldOfView", "A+",%.6f' % data.angle)
@@ -471,8 +944,8 @@ def write_scene(file, sce, world):
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(Blender.Mathutils.Vector(0,1,0) * matrix_rot) )
- file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(Blender.Mathutils.Vector(0,0,-1)*matrix_rot) )
+ 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: 0,0,0' )
#file.write('\n\t\tLookAt: 0,0,0' )
@@ -483,12 +956,12 @@ def write_scene(file, sce, world):
file.write('\n\t\tCameraOrthoZoom: 1')
file.write('\n\t}')
- def write_light(ob, name):
- light = ob.data
- file.write('\n\tModel: "Model::%s", "Light" {' % name)
+ def write_light(my_light):
+ light = my_light.blenObject.data
+ file.write('\n\tModel: "Model::%s", "Light" {' % my_light.fbxName)
file.write('\n\t\tVersion: 232')
- write_object_props(ob)
+ write_object_props(my_light.blenObject, None, my_light.parRelMatrix())
# Why are these values here twice?????? - oh well, follow the holy sdk's output
@@ -499,7 +972,20 @@ def write_scene(file, sce, world):
#eSPOT
light_type = light.type
if light_type > 3: light_type = 0
-
+
+ mode = light.mode
+ 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):
+ do_light = 0
+ else:
+ do_light = 1
+
+ scale = abs(GLOBAL_MATRIX.scalePart()[0]) # scale is always uniform in this case
+
file.write('\n\t\t\tProperty: "LightType", "enum", "",%i' % light_type)
file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
@@ -507,15 +993,15 @@ def write_scene(file, sce, world):
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
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' % (light.energy*100))
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
+ 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))
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: "Intensity", "Intensity", "A+",%.2f' % (light.energy*100))
- file.write('\n\t\t\tProperty: "Cone angle", "Cone angle", "A+",%.2f' % light.spotSize)
+ 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))
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", "",1')
+ file.write('\n\t\t\tProperty: "CastLightOnObject", "bool", "",%i' % do_light)
file.write('\n\t\t\tProperty: "DrawGroundProjection", "bool", "",1')
file.write('\n\t\t\tProperty: "DrawFrontFacingVolumetricLight", "bool", "",0')
file.write('\n\t\t\tProperty: "DrawVolumetricLight", "bool", "",1')
@@ -528,7 +1014,7 @@ def write_scene(file, sce, world):
file.write('\n\t\t\tProperty: "EnableFarAttenuation", "bool", "",0')
file.write('\n\t\t\tProperty: "FarAttenuationStart", "double", "",0')
file.write('\n\t\t\tProperty: "FarAttenuationEnd", "double", "",0')
- file.write('\n\t\t\tProperty: "CastShadows", "bool", "",0')
+ file.write('\n\t\t\tProperty: "CastShadows", "bool", "",%i' % do_shadow)
file.write('\n\t\t\tProperty: "ShadowColor", "ColorRGBA", "",0,0,0,1')
file.write('\n\t\t}')
file.write('\n\t\tMultiLayer: 0')
@@ -539,12 +1025,36 @@ def write_scene(file, sce, world):
file.write('\n\t\tGeometryVersion: 124')
file.write('\n\t}')
- # Material Settings
- if world:
- world_amb = world.getAmb()
- else:
- world_amb = (0,0,0) # Default value
+ # matrixOnly is not used at the moment
+ def write_null(my_null = None, fbxName = None, matrixOnly = None):
+ # ob can be null
+ if not fbxName: fbxName = my_null.fbxName
+
+ file.write('\n\tModel: "Model::%s", "Null" {' % fbxName)
+ file.write('\n\t\tVersion: 232')
+
+ # only use this for the root matrix at the moment
+ if matrixOnly:
+ poseMatrix = write_object_props(None, None, matrixOnly)[3]
+
+ else: # all other Null's
+ if my_null: poseMatrix = write_object_props(my_null.blenObject, None, my_null.parRelMatrix())[3]
+ else: poseMatrix = write_object_props()[3]
+
+ pose_items.append((fbxName, poseMatrix))
+
+ file.write('''
+ }
+ MultiLayer: 0
+ MultiTake: 1
+ Shading: Y
+ Culling: "CullingOff"
+ TypeFlags: "Null"
+ }''')
+ # Material Settings
+ if world: world_amb = world.getAmb()
+ else: world_amb = (0,0,0) # Default value
def write_material(matname, mat):
file.write('\n\tMaterial: "Material::%s", "" {' % matname)
@@ -561,6 +1071,7 @@ def write_scene(file, sce, world):
mat_hard = (float(mat.hard)-1)/5.10
mat_spec = mat.spec/2.0
mat_alpha = mat.alpha
+ mat_emit = mat.emit
mat_shadeless = mat.mode & Blender.Material.Modes.SHADELESS
if mat_shadeless:
mat_shader = 'Lambert'
@@ -578,6 +1089,7 @@ def write_scene(file, sce, world):
mat_hard = 20.0
mat_spec = 0.2
mat_alpha = 1.0
+ mat_emit = 0.0
mat_shadeless = False
mat_shader = 'Phong'
@@ -588,27 +1100,27 @@ def write_scene(file, sce, world):
file.write('\n\t\tProperties60: {')
file.write('\n\t\t\tProperty: "ShadingModel", "KString", "", "%s"' % mat_shader)
file.write('\n\t\t\tProperty: "MultiLayer", "bool", "",0')
- file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",0,0,0')
- file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",1')
+ file.write('\n\t\t\tProperty: "EmissiveColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold) # emit and diffuse color are he same in blender
+ file.write('\n\t\t\tProperty: "EmissiveFactor", "double", "",%.4f' % mat_dif)
- file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
- file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.1f' % mat_amb)
- file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
- file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.1f' % mat_dif)
+ file.write('\n\t\t\tProperty: "AmbientColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_colamb)
+ file.write('\n\t\t\tProperty: "AmbientFactor", "double", "",%.4f' % mat_amb)
+ file.write('\n\t\t\tProperty: "DiffuseColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cold)
+ file.write('\n\t\t\tProperty: "DiffuseFactor", "double", "",%.4f' % mat_emit)
file.write('\n\t\t\tProperty: "Bump", "Vector3D", "",0,0,0')
file.write('\n\t\t\tProperty: "TransparentColor", "ColorRGB", "",1,1,1')
- file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",0')
+ file.write('\n\t\t\tProperty: "TransparencyFactor", "double", "",%.4f' % (1.0 - mat_alpha))
if not mat_shadeless:
- file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols)
- file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.1f' % mat_spec)
+ file.write('\n\t\t\tProperty: "SpecularColor", "ColorRGB", "",%.4f,%.4f,%.4f' % mat_cols)
+ file.write('\n\t\t\tProperty: "SpecularFactor", "double", "",%.4f' % mat_spec)
file.write('\n\t\t\tProperty: "ShininessExponent", "double", "",80.0')
file.write('\n\t\t\tProperty: "ReflectionColor", "ColorRGB", "",0,0,0')
file.write('\n\t\t\tProperty: "ReflectionFactor", "double", "",1')
- file.write('\n\t\t\tProperty: "Emissive", "Vector3D", "",0,0,0')
- file.write('\n\t\t\tProperty: "Ambient", "Vector3D", "",%.1f,%.1f,%.1f' % mat_colamb)
- file.write('\n\t\t\tProperty: "Diffuse", "Vector3D", "",%.1f,%.1f,%.1f' % mat_cold)
+ file.write('\n\t\t\tProperty: "Emissive", "ColorRGB", "",0,0,0')
+ file.write('\n\t\t\tProperty: "Ambient", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_colamb)
+ file.write('\n\t\t\tProperty: "Diffuse", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cold)
if not mat_shadeless:
- file.write('\n\t\t\tProperty: "Specular", "Vector3D", "",%.1f,%.1f,%.1f' % mat_cols)
+ file.write('\n\t\t\tProperty: "Specular", "ColorRGB", "",%.1f,%.1f,%.1f' % mat_cols)
file.write('\n\t\t\tProperty: "Shininess", "double", "",%.1f' % mat_hard)
file.write('\n\t\t\tProperty: "Opacity", "double", "",%.1f' % mat_alpha)
if not mat_shadeless:
@@ -669,15 +1181,21 @@ def write_scene(file, sce, world):
Property: "Rotation", "Vector", "A+",0,0,0
Property: "Scaling", "Vector", "A+",1,1,1''')
file.write('\n\t\t\tProperty: "Texture alpha", "Number", "A+",%i' % num)
+
+
+ # WrapModeU/V 0==rep, 1==clamp, TODO add support
file.write('''
Property: "TextureTypeUse", "enum", "",0
Property: "CurrentTextureBlendMode", "enum", "",1
Property: "UseMaterial", "bool", "",0
Property: "UseMipMap", "bool", "",0
Property: "CurrentMappingType", "enum", "",0
- Property: "UVSwap", "bool", "",0
- Property: "WrapModeU", "enum", "",0
- Property: "WrapModeV", "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('''
Property: "TextureRotationPivot", "Vector3D", "",0,0,0
Property: "TextureScalingPivot", "Vector3D", "",0,0,0
Property: "VideoProperty", "object", ""
@@ -698,194 +1216,143 @@ def write_scene(file, sce, world):
Texture_Alpha_Source: "None"
Cropping: 0,0,0,0
}''')
-
- ob_meshes = []
- ob_lights = []
- ob_cameras = []
- materials = {}
- textures = {}
- armatures = [] # We should export standalone armatures also
- armatures_totbones = 0 # we need this because each bone is a model
- for ob_base in sce.objects.context:
- for ob, mtx in BPyObject.getDerivedObjects(ob_base):
- #for ob in [ob_base,]:
- ob_type = ob.type
- if ob_type == 'Camera':
- ob_cameras.append((sane_obname(ob), ob))
- elif ob_type == 'Lamp':
- ob_lights.append((sane_obname(ob), ob))
-
- else:
- if ob_type == 'Mesh': me = ob.getData(mesh=1)
- else: me = BPyMesh.getMeshFromObject(ob)
-
- if me:
- mats = me.materials
- for mat in mats:
- # 2.44 use mat.lib too for uniqueness
- if mat: materials[mat.name] = mat
-
- if me.faceUV:
- uvlayer_orig = me.activeUVLayer
- for uvlayer in me.getUVLayerNames():
- me.activeUVLayer = uvlayer
- for f in me.faces:
- img = f.image
- if img: textures[img.name] = img
-
- me.activeUVLayer = uvlayer_orig
-
- arm = BPyObject.getObjectArmature(ob)
-
- if arm:
- armname = sane_obname(arm)
- bones = arm.bones.values()
- armatures_totbones += len(bones)
- armatures.append((arm, armname, bones))
- else:
- armname = None
-
- #### me.transform(ob.matrixWorld) # Export real ob coords.
- #### High Quality, not realy needed for now.
- #BPyMesh.meshCalcNormals(me) # high quality normals nice for realtime engines.
- ob_meshes.append( (sane_obname(ob), ob, mtx, me, mats, arm, armname) )
-
- del ob_type
-
- materials = [(sane_matname(mat), mat) for mat in materials.itervalues()]
- textures = [(sane_texname(img), img) for img in textures.itervalues()]
- materials.sort() # sort by name
- textures.sort()
-
- if not materials:
- materials = [('null', None)]
-
- material_mapping = {} # blen name : index
- if textures:
- texture_mapping_local = {None:0} # ditto
- i = 0
- for texname, tex in textures:
- texture_mapping_local[tex.name] = i
- i+=1
- textures.insert(0, ('_empty_', None))
-
- i = 0
- for matname, mat in materials:
- if mat: mat = mat.name
- material_mapping[mat] = i
- i+=1
-
- camera_count = 8
- file.write('''
-
-; Object definitions
-;------------------------------------------------------------------
-Definitions: {
- Version: 100
- Count: %i''' % (\
- 1+1+camera_count+\
- len(ob_meshes)+\
- len(ob_lights)+\
- len(ob_cameras)+\
- len(armatures)+\
- armatures_totbones+\
- len(materials)+\
- (len(textures)*2))) # add 1 for the root model 1 for global settings
-
- file.write('''
- ObjectType: "Model" {
- Count: %i
- }''' % (\
- 1+camera_count+\
- len(ob_meshes)+\
- len(ob_lights)+\
- len(ob_cameras)+\
- len(armatures)+\
- armatures_totbones)) # add 1 for the root model
-
- file.write('''
- ObjectType: "Geometry" {
- Count: %i
- }''' % len(ob_meshes))
-
- if materials:
- file.write('''
- ObjectType: "Material" {
- Count: %i
- }''' % len(materials))
-
- if textures:
- file.write('''
- ObjectType: "Texture" {
- Count: %i
- }''' % len(textures)) # add 1 for an empty tex
+ def write_deformer_skin(obname):
+ '''
+ Each mesh has its own deformer
+ '''
+ file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {' % obname)
file.write('''
- ObjectType: "Video" {
- Count: %i
- }''' % len(textures)) # add 1 for an empty tex
-
- file.write('''
- ObjectType: "GlobalSettings" {
- Count: 1
- }
-}
-''')
-
- file.write(\
-'''
-; Object properties
-;------------------------------------------------------------------
-
-Objects: {''')
-
- # To comply with other FBX FILES
- write_camera_switch()
-
- # Write the null object
- file.write('''
- Model: "Model::blend_root", "Null" {
- Version: 232''')
- write_object_props()
-
- file.write('''
- }
+ Version: 100
MultiLayer: 0
- MultiTake: 1
- Shading: Y
- Culling: "CullingOff"
- TypeFlags: "Null"
+ Type: "Skin"
+ Properties60: {
+ }
+ Link_DeformAcuracy: 50
}''')
- for obname, ob in ob_cameras:
- write_camera(ob, obname)
-
- for obname, ob in ob_lights:
- write_light(ob, obname)
+ # in the example was 'Bip01 L Thigh_2'
+ def write_sub_deformer_skin(my_mesh, my_bone, weights):
+
+ '''
+ Each subdeformer is spesific to a mesh, but the bone it links to can be used by many sub-deformers
+ So the SubDeformer needs the mesh-object name as a prefix to make it unique
+
+ Its possible that there is no matching vgroup in this mesh, in that case no verts are in the subdeformer,
+ a but silly but dosnt really matter
+ '''
+ file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {' % (my_mesh.fbxName, my_bone.fbxName))
+
+ file.write('''
+ Version: 100
+ MultiLayer: 0
+ Type: "Cluster"
+ Properties60: {
+ Property: "SrcModel", "object", ""
+ Property: "SrcModelReference", "object", ""
+ }
+ UserData: "", ""''')
+
+ # Support for bone parents
+ if my_mesh.fbxBoneParent:
+ if my_mesh.fbxBoneParent == my_bone:
+ # 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))]
+ else:
+ # This bone is not a parent of this mesh object, no weights
+ vgroup_data = []
+
+ else:
+ # Normal weight painted mesh
+ if my_bone.blenName in weights[0]:
+ # Before we used normalized wright list
+ #vgroup_data = me.getVertsFromGroup(bone.name, 1)
+ group_index = weights[0].index(my_bone.blenName)
+ vgroup_data = [(j, weight[group_index]) for j, weight in enumerate(weights[1]) if weight[group_index]]
+ else:
+ vgroup_data = []
+
+ file.write('\n\t\tIndexes: ')
+
+ i = -1
+ for vg in vgroup_data:
+ if i == -1:
+ file.write('%i' % vg[0])
+ i=0
+ else:
+ if i==23:
+ file.write('\n\t\t')
+ i=0
+ file.write(',%i' % vg[0])
+ i+=1
+
+ file.write('\n\t\tWeights: ')
+ i = -1
+ for vg in vgroup_data:
+ if i == -1:
+ file.write('%.8f' % vg[1])
+ i=0
+ else:
+ if i==38:
+ file.write('\n\t\t')
+ i=0
+ file.write(',%.8f' % vg[1])
+ i+=1
+
+ if my_mesh.fbxParent:
+ # TODO FIXME, this case is broken in some cases. skinned meshes just shouldnt have parents where possible!
+ m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() )
+ else:
+ # Yes! this is it... - but dosnt work when the mesh is a.
+ m = mtx4_z90 * (my_bone.restMatrix * my_bone.fbxArm.matrixWorld.copy() * my_mesh.matrixWorld.copy().invert() )
+
+ #m = mtx4_z90 * my_bone.restMatrix
+ matstr = mat4x4str(m)
+ matstr_i = mat4x4str(m.invert())
+
+ file.write('\n\t\tTransform: %s' % matstr_i) # THIS IS __NOT__ THE GLOBAL MATRIX AS DOCUMENTED :/
+ file.write('\n\t\tTransformLink: %s' % matstr)
+ file.write('\n\t}')
- for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
- file.write('\n\tModel: "Model::%s", "Mesh" {' % sane_obname(ob))
+ def write_mesh(my_mesh):
+
+ me = my_mesh.blenData
+
+ # if there are non NULL materials on this mesh
+ if [mat for mat in my_mesh.blenMaterials if mat]: do_materials = True
+ else: do_materials = False
+
+ if my_mesh.blenTextures: do_textures = True
+ else: do_textures = False
+
+
+ file.write('\n\tModel: "Model::%s", "Mesh" {' % my_mesh.fbxName)
file.write('\n\t\tVersion: 232') # newline is added in write_object_props
- write_object_props(ob, None, mtx)
+
+ write_object_props(my_mesh.blenObject, None, my_mesh.parRelMatrix())
+
file.write('\n\t\t}')
file.write('\n\t\tMultiLayer: 0')
file.write('\n\t\tMultiTake: 1')
file.write('\n\t\tShading: Y')
file.write('\n\t\tCulling: "CullingOff"')
+
# Write the Real Mesh data here
file.write('\n\t\tVertices: ')
i=-1
+
for v in me.verts:
if i==-1:
- file.write('%.6f,%.6f,%.6f' % tuple(v.co))
- i=0
+ file.write('%.6f,%.6f,%.6f' % tuple(v.co)); i=0
else:
if i==7:
- file.write('\n\t\t')
- i=0
+ file.write('\n\t\t'); i=0
file.write(',%.6f,%.6f,%.6f'% tuple(v.co))
i+=1
+
file.write('\n\t\tPolygonVertexIndex: ')
i=-1
for f in me.faces:
@@ -932,22 +1399,20 @@ Objects: {''')
MappingInformationType: "ByVertice"
ReferenceInformationType: "Direct"
Normals: ''')
-
+
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.no)); i=0
else:
if i==2:
- file.write('\n ')
- i=0
+ file.write('\n '); i=0
file.write(',%.15f,%.15f,%.15f' % tuple(v.no))
i+=1
file.write('\n\t\t}')
-
# Write VertexColor Layers
+ # note, no programs seem to use this info :/
collayers = []
if me.vertexColors:
collayers = me.getColorLayerNames()
@@ -1043,32 +1508,47 @@ Objects: {''')
file.write('\n\t\t}')
- if textures:
+ 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('''
- MappingInformationType: "ByPolygon"
- ReferenceInformationType: "IndexToDirect"
- BlendMode: "Translucent"
- TextureAlpha: 1
- TextureId: ''')
- i=-1
- for f in me.faces:
- img_key = f.image
- if img_key: img_key = img_key.name
+ if len(my_mesh.blenTextures) == 1:
+ file.write('\n\t\t\tMappingInformationType: "AllSame"')
+ else:
+ file.write('\n\t\t\tMappingInformationType: "ByPolygon"')
+
+ file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"')
+ file.write('\n\t\t\tBlendMode: "Translucent"')
+ file.write('\n\t\t\tTextureAlpha: 1')
+ file.write('\n\t\t\tTextureId: ')
+
+ if len(my_mesh.blenTextures) == 1:
+ file.write('0')
+ else:
+ #texture_mapping_local = {None:0}
+ texture_mapping_local = {None:-1}
- if i==-1:
- i=0
- file.write( '%s' % texture_mapping_local[img_key])
- else:
- if i==55:
- file.write('\n ')
- i=0
+ i = 0 # 1 for dummy
+ for tex in my_mesh.blenTextures:
+ texture_mapping_local[tex] = i
+ i+=1
+
+ i=-1
+ for f in me.faces:
+ img_key = f.image
- file.write(',%s' % texture_mapping_local[img_key])
- i+=1
+ if i==-1:
+ i=0
+ file.write( '%s' % texture_mapping_local[img_key])
+ else:
+ if i==55:
+ file.write('\n ')
+ i=0
+
+ file.write(',%s' % texture_mapping_local[img_key])
+ i+=1
+
else:
file.write('''
LayerElementTexture: 0 {
@@ -1085,44 +1565,50 @@ Objects: {''')
# Done with UV/textures.
- if materials:
- file.write('''
- LayerElementMaterial: 0 {
- Version: 101
- Name: ""
- MappingInformationType: "ByPolygon"
- ReferenceInformationType: "IndexToDirect"
- Materials: ''')
-
- # Build a material mapping for this
- material_mapping_local = {} # local-index : global index.
- for i, mat in enumerate(mats):
- if mat:
- material_mapping_local[i] = material_mapping[mat.name]
- else:
- material_mapping_local[i] = 0 # None material is zero for now.
+ if do_materials:
+ file.write('\n\t\tLayerElementMaterial: 0 {')
+ file.write('\n\t\t\tVersion: 101')
+ file.write('\n\t\t\tName: ""')
- if not material_mapping_local:
- material_mapping_local[0] = 0
+ if len(my_mesh.blenMaterials) == 1:
+ file.write('\n\t\t\tMappingInformationType: "AllSame"')
+ else:
+ file.write('\n\t\t\tMappingInformationType: "ByPolygon"')
- len_material_mapping_local = len(material_mapping_local)
+ file.write('\n\t\t\tReferenceInformationType: "IndexToDirect"')
+ file.write('\n\t\t\tMaterials: ')
- i=-1
- for f in me.faces:
- f_mat = f.mat
- if f_mat >= len_material_mapping_local:
- f_mat = 0
+ if len(my_mesh.blenMaterials) == 1:
+ file.write('0')
+ else:
+ # Build a material mapping for this
+ #material_mapping_local = [0] * 16 # local-index : global index.
+ material_mapping_local = [-1] * 16 # local-index : global index.
+ i= 0 # 1
+ for j, mat in enumerate(my_mesh.blenMaterials):
+ if mat:
+ material_mapping_local[j] = i
+ i+=1
+ # else leave as -1
- if i==-1:
- i=0
- file.write( '%s' % material_mapping_local[f_mat])
- else:
- if i==55:
- file.write('\n\t\t\t\t')
- i=0
+ len_material_mapping_local = len(material_mapping_local)
+
+ i=-1
+ for f in me.faces:
+ f_mat = f.mat
+ if f_mat >= len_material_mapping_local:
+ f_mat = 0
- file.write(',%s' % material_mapping_local[f_mat])
- i+=1
+ if i==-1:
+ i=0
+ file.write( '%s' % (material_mapping_local[f_mat]))
+ else:
+ if i==55:
+ file.write('\n\t\t\t\t')
+ i=0
+
+ file.write(',%s' % (material_mapping_local[f_mat]))
+ i+=1
file.write('\n\t\t}')
@@ -1134,7 +1620,7 @@ Objects: {''')
TypedIndex: 0
}''')
- if materials:
+ if do_materials:
file.write('''
LayerElement: {
Type: "LayerElementMaterial"
@@ -1142,7 +1628,7 @@ Objects: {''')
}''')
# Always write this
- if textures:
+ if do_textures:
file.write('''
LayerElement: {
Type: "LayerElementTexture"
@@ -1179,7 +1665,7 @@ Objects: {''')
file.write('\n\t\t\t\tTypedIndex: %i' % i)
file.write('\n\t\t\t}')
- if textures:
+ if do_textures:
file.write('''
LayerElement: {
@@ -1206,7 +1692,425 @@ Objects: {''')
file.write('\n\t\t\t\tTypedIndex: %i' % i)
file.write('\n\t\t\t}')
file.write('\n\t\t}')
- file.write('\n\t}')
+ file.write('\n\t}')
+
+ def write_group(name):
+ file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {' % name)
+
+ file.write('''
+ Properties60: {
+ Property: "MultiLayer", "bool", "",0
+ Property: "Pickable", "bool", "",1
+ Property: "Transformable", "bool", "",1
+ Property: "Show", "bool", "",1
+ }
+ MultiLayer: 0
+ }''')
+
+
+ # add meshes here to clear because they are not used anywhere.
+ meshes_to_clear = []
+
+ ob_meshes = []
+ ob_lights = []
+ ob_cameras = []
+ # in fbx we export bones as children of the mesh
+ # armatures not a part of a mesh, will be added to ob_arms
+ ob_bones = []
+ ob_arms = []
+ ob_null = [] # emptys
+
+ # List of types that have blender objects (not bones)
+ ob_all_typegroups = [ob_meshes, ob_lights, ob_cameras, ob_arms, ob_null]
+
+ groups = [] # blender groups, only add ones that have objects in the selections
+ materials = {}
+ textures = {}
+
+ tmp_ob_type = ob_type = None # incase no objects are exported, so as not to raise an error
+
+ # if EXP_OBS_SELECTED is false, use sceens objects
+ if not batch_objects:
+ if EXP_OBS_SELECTED: tmp_objects = sce.objects.context
+ else: tmp_objects = sce.objects
+ else:
+ tmp_objects = batch_objects
+
+ if EXP_ARMATURE:
+ # 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]
+
+ for arm in bpy.data.armatures:
+ arm.restPosition = True
+
+ if ob_arms_orig_rest:
+ for ob_base in bpy.data.objects:
+ #if ob_base.type == 'Armature':
+ ob_base.makeDisplayList()
+
+ # This causes the makeDisplayList command to effect the mesh
+ 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,]:
+ tmp_ob_type = ob.type
+ if tmp_ob_type == 'Camera':
+ if EXP_CAMERA:
+ ob_cameras.append(my_object_generic(ob, mtx))
+ elif tmp_ob_type == 'Lamp':
+ if EXP_LAMP:
+ ob_lights.append(my_object_generic(ob, mtx))
+ 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':
+ 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)
+ except: me = None
+ if me:
+ meshes_to_clear.append( me )
+ mats = me.materials
+ origData = False
+ else:
+ # Mesh Type!
+ if EXP_MESH_APPLY_MOD:
+ me = bpy.data.meshes.new()
+ 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)
+
+ # print ob, me, me.getVertGroupNames()
+ meshes_to_clear.append( me )
+ origData = False
+ mats = me.materials
+ else:
+ 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
+
+
+ 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.
+
+ for mat in mats:
+ # 2.44 use mat.lib too for uniqueness
+ if mat: materials[mat] = mat
+
+ texture_mapping_local = {}
+ if me.faceUV:
+ uvlayer_orig = me.activeUVLayer
+ for uvlayer in me.getUVLayerNames():
+ me.activeUVLayer = uvlayer
+ for f in me.faces:
+ img = f.image
+ textures[img] = texture_mapping_local[img] = img
+
+ me.activeUVLayer = uvlayer_orig
+
+ if EXP_ARMATURE:
+ armob = BPyObject.getObjectArmature(ob)
+ blenParentBoneName = None
+
+ # Note - Fixed in BPyObject but for now just copy the function because testers wont have up to date modukes,
+ # TODO - remove this for 2.45 release since getObjectArmature has been fixed
+ if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.ARMATURE:
+ armob = ob.parent
+
+ # parent bone - special case
+ if (not armob) and ob.parent and ob.parent.type == 'Armature' and ob.parentType == Blender.Object.ParentTypes.BONE:
+ armob = ob.parent
+ blenParentBoneName = ob.parentbonename
+
+
+ if armob and armob not in ob_arms:
+ ob_arms.append(armob)
+
+ else:
+ blenParentBoneName = armob = None
+
+ my_mesh = my_object_generic(ob, mtx)
+ my_mesh.blenData = me
+ my_mesh.origData = origData
+ my_mesh.blenMaterials = mats
+ my_mesh.blenTextures = texture_mapping_local.values()
+
+ # if only 1 null texture then empty the list
+ if len(my_mesh.blenTextures) == 1 and my_mesh.blenTextures[0] == None:
+ my_mesh.blenTextures = []
+
+ my_mesh.fbxArm = armob # replace with my_object_generic armature instance later
+ my_mesh.fbxBoneParent = blenParentBoneName # replace with my_bone instance later
+
+ ob_meshes.append( my_mesh )
+
+ 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]
+
+ if ob_arms_orig_rest:
+ for ob_base in bpy.data.objects:
+ if ob_base.type == 'Armature':
+ ob_base.makeDisplayList()
+ # This causes the makeDisplayList command to effect the mesh
+ Blender.Set('curframe', Blender.Get('curframe'))
+
+ del tmp_ob_type, tmp_objects
+
+ # now we have collected all armatures, add bones
+ for i, ob in enumerate(ob_arms):
+
+ ob_arms[i] = my_arm = my_object_generic(ob)
+
+ my_arm.fbxBones = []
+ my_arm.blenData = ob.data
+ 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():
+ my_bone = my_bone_class(bone, my_arm)
+ my_arm.fbxBones.append( my_bone )
+ ob_bones.append( my_bone )
+
+ # add the meshes to the bones and replace the meshes armature with own armature class
+ #for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
+ for my_mesh in ob_meshes:
+ # Replace
+ # ...this could be sped up with dictionary mapping but its unlikely for
+ # it ever to be a bottleneck - (would need 100+ meshes using armatures)
+ if my_mesh.fbxArm:
+ for my_arm in ob_arms:
+ if my_arm.blenObject == my_mesh.fbxArm:
+ my_mesh.fbxArm = my_arm
+ break
+
+ for my_bone in ob_bones:
+
+ # The mesh uses this bones armature!
+ if my_bone.fbxArm == my_mesh.fbxArm:
+ my_bone.blenMeshes[my_mesh.fbxName] = me
+
+
+ # parent bone: replace bone names with our class instances
+ # my_mesh.fbxBoneParent is None or a blender bone name initialy, replacing if the names match.
+ if my_mesh.fbxBoneParent == my_bone.blenName:
+ my_mesh.fbxBoneParent = my_bone
+
+ bone_deformer_count = 0 # count how many bones deform a mesh
+ my_bone_blenParent = None
+ for my_bone in ob_bones:
+ my_bone_blenParent = my_bone.blenBone.parent
+ if my_bone_blenParent:
+ for my_bone_parent in ob_bones:
+ # Note 2.45rc2 you can compare bones normally
+ if my_bone_blenParent.name == my_bone_parent.blenName and my_bone.fbxArm == my_bone_parent.fbxArm:
+ my_bone.parent = my_bone_parent
+ break
+
+ # Not used at the moment
+ # my_bone.calcRestMatrixLocal()
+ bone_deformer_count += len(my_bone.blenMeshes)
+
+ del my_bone_blenParent
+
+
+ # Build blenObject -> fbxObject mapping
+ # this is needed for groups as well as fbxParenting
+ bpy.data.objects.tag = False
+ tmp_obmapping = {}
+ for ob_generic in ob_all_typegroups:
+ for ob_base in ob_generic:
+ 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 fbxGroupName == None:
+ fbxGroupName = sane_groupname(blenGroup)
+ groups.append((fbxGroupName, blenGroup))
+
+ tmp_obmapping[ob].fbxGroupNames.append(fbxGroupName) # also adds to the objects fbxGroupNames
+
+ groups.sort() # not really needed
+
+ # Assign parents using this mapping
+ 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
+ my_ob.fbxParent = tmp_obmapping[parent]
+
+
+ del tmp_obmapping
+ # Finished finding groups we use
+
+
+ materials = [(sane_matname(mat), mat) for mat in materials.itervalues() if mat]
+ textures = [(sane_texname(img), img) for img in textures.itervalues() if img]
+ materials.sort() # sort by name
+ textures.sort()
+
+ camera_count = 8
+ file.write('''
+
+; Object definitions
+;------------------------------------------------------------------
+
+Definitions: {
+ Version: 100
+ Count: %i''' % (\
+ 1+1+camera_count+\
+ len(ob_meshes)+\
+ len(ob_lights)+\
+ len(ob_cameras)+\
+ len(ob_arms)+\
+ len(ob_null)+\
+ len(ob_bones)+\
+ bone_deformer_count+\
+ len(materials)+\
+ (len(textures)*2))) # add 1 for the root model 1 for global settings
+
+ del bone_deformer_count
+
+ file.write('''
+ ObjectType: "Model" {
+ Count: %i
+ }''' % (\
+ 1+camera_count+\
+ len(ob_meshes)+\
+ len(ob_lights)+\
+ len(ob_cameras)+\
+ len(ob_arms)+\
+ len(ob_null)+\
+ len(ob_bones))) # add 1 for the root model
+
+ file.write('''
+ ObjectType: "Geometry" {
+ Count: %i
+ }''' % len(ob_meshes))
+
+ if materials:
+ file.write('''
+ ObjectType: "Material" {
+ Count: %i
+ }''' % len(materials))
+
+ if textures:
+ file.write('''
+ ObjectType: "Texture" {
+ Count: %i
+ }''' % len(textures)) # add 1 for an empty tex
+ file.write('''
+ ObjectType: "Video" {
+ Count: %i
+ }''' % len(textures)) # add 1 for an empty tex
+
+ tmp = 0
+ # Add deformer nodes
+ for my_mesh in ob_meshes:
+ if my_mesh.fbxArm:
+ tmp+=1
+
+ # Add subdeformers
+ for my_bone in ob_bones:
+ tmp += len(my_bone.blenMeshes)
+
+ if tmp:
+ file.write('''
+ ObjectType: "Deformer" {
+ Count: %i
+ }''' % tmp)
+ del tmp
+
+ # we could avoid writing this possibly but for now just write it
+
+ file.write('''
+ ObjectType: "Pose" {
+ Count: 1
+ }''')
+
+ if groups:
+ file.write('''
+ ObjectType: "GroupSelection" {
+ Count: %i
+ }''' % len(groups))
+
+ file.write('''
+ ObjectType: "GlobalSettings" {
+ Count: 1
+ }
+}''')
+
+ file.write('''
+
+; Object properties
+;------------------------------------------------------------------
+
+Objects: {''')
+
+ # To comply with other FBX FILES
+ write_camera_switch()
+
+ # Write the null object
+ write_null(None, 'blend_root')# , GLOBAL_MATRIX)
+
+ for my_null in ob_null:
+ write_null(my_null)
+
+ for my_arm in ob_arms:
+ write_null(my_arm)
+
+ for my_cam in ob_cameras:
+ write_camera(my_cam)
+
+ for my_light in ob_lights:
+ write_light(my_light)
+
+ for my_mesh in ob_meshes:
+ write_mesh(my_mesh)
+
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ write_bone(my_bone)
write_camera_default()
@@ -1221,6 +2125,51 @@ Objects: {''')
write_texture(texname, tex, i)
i+=1
+ for groupname, group in groups:
+ write_group(groupname)
+
+ # NOTE - c4d and motionbuilder dont need normalized weights, but deep-exploration 5 does and (max?) do.
+
+ # Write armature modifiers
+ # TODO - add another MODEL? - because of this skin definition.
+ for my_mesh in ob_meshes:
+ if my_mesh.fbxArm:
+ write_deformer_skin(my_mesh.fbxName)
+
+ # Get normalized weights for temorary use
+ if my_mesh.fbxBoneParent:
+ weights = None
+ else:
+ 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():
+ write_sub_deformer_skin(my_mesh, my_bone, weights)
+
+ # Write pose's really weired, only needed when an armature and mesh are used together
+ # each by themselves dont need pose data. for now only pose meshes and bones
+
+ file.write('''
+ Pose: "Pose::BIND_POSES", "BindPose" {
+ Type: "BindPose"
+ Version: 100
+ Properties60: {
+ }
+ NbPoseNodes: ''')
+ file.write(str(len(pose_items)))
+
+
+ for fbxName, matrix in pose_items:
+ file.write('\n\t\tPoseNode: {')
+ file.write('\n\t\t\tNode: "Model::%s"' % fbxName )
+ if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix))
+ else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity))
+ file.write('\n\t\t}')
+
+ file.write('\n\t}')
+
+
# Finish Writing Objects
# Write global settings
file.write('''
@@ -1233,7 +2182,7 @@ Objects: {''')
Property: "FrontAxisSign", "int", "",1
Property: "CoordAxis", "int", "",0
Property: "CoordAxisSign", "int", "",1
- Property: "UnitScaleFactor", "double", "",1
+ Property: "UnitScaleFactor", "double", "",100
}
}
''')
@@ -1247,14 +2196,26 @@ Objects: {''')
Relations: {''')
file.write('\n\tModel: "Model::blend_root", "Null" {\n\t}')
- for obname, ob in ob_cameras:
- file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % obname)
+
+ for my_null in ob_null:
+ file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_null.fbxName)
+
+ for my_arm in ob_arms:
+ file.write('\n\tModel: "Model::%s", "Null" {\n\t}' % my_arm.fbxName)
+
+ for my_mesh in ob_meshes:
+ file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % my_mesh.fbxName)
+
+ # TODO - limbs can have the same name for multiple armatures, should prefix.
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ file.write('\n\tModel: "Model::%s", "Limb" {\n\t}' % my_bone.fbxName)
- for obname, ob in ob_lights:
- file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % obname)
+ for my_cam in ob_cameras:
+ file.write('\n\tModel: "Model::%s", "Camera" {\n\t}' % my_cam.fbxName)
- for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
- file.write('\n\tModel: "Model::%s", "Mesh" {\n\t}' % obname)
+ for my_light in ob_lights:
+ file.write('\n\tModel: "Model::%s", "Light" {\n\t}' % my_light.fbxName)
file.write('''
Model: "Model::Producer Perspective", "Camera" {
@@ -1283,6 +2244,23 @@ Relations: {''')
for texname, tex in textures:
file.write('\n\tVideo: "Video::%s", "Clip" {\n\t}' % texname)
+ # deformers - modifiers
+ for my_mesh in ob_meshes:
+ if my_mesh.fbxArm:
+ file.write('\n\tDeformer: "Deformer::Skin %s", "Skin" {\n\t}' % my_mesh.fbxName)
+
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ for fbxMeshObName in my_bone.blenMeshes: # .keys() - fbxMeshObName
+ # is this bone effecting a mesh?
+ file.write('\n\tDeformer: "SubDeformer::Cluster %s %s", "Cluster" {\n\t}' % (fbxMeshObName, my_bone.fbxName))
+
+ # This should be at the end
+ # file.write('\n\tPose: "Pose::BIND_POSES", "BindPose" {\n\t}')
+
+ for groupname, group in groups:
+ file.write('\n\tGroupSelection: "GroupSelection::%s", "Default" {\n\t}' % groupname)
+
file.write('\n}')
file.write('''
@@ -1290,64 +2268,357 @@ Relations: {''')
;------------------------------------------------------------------
Connections: {''')
+
+ # NOTE - The FBX SDK dosnt care about the order but some importers DO!
+ # for instance, defining the material->mesh connection
+ # before the mesh->blend_root crashes cinema4d
+
# write the fake root node
file.write('\n\tConnect: "OO", "Model::blend_root", "Model::Scene"')
- for obname, ob in ob_cameras:
- file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
-
- for obname, ob in ob_lights:
- file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
-
- for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
- file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % obname)
+ for ob_generic in ob_all_typegroups: # all blender 'Object's we support
+ for my_ob in ob_generic:
+ if my_ob.fbxParent:
+ file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_ob.fbxName, my_ob.fbxParent.fbxName))
+ else:
+ file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_ob.fbxName)
- for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
- # Connect all materials to all objects, not good form but ok for now.
- for mat in mats:
- file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_matname(mat), obname))
+ if materials:
+ for my_mesh in ob_meshes:
+ # Connect all materials to all objects, not good form but ok for now.
+ for mat in my_mesh.blenMaterials:
+ if mat:
+ file.write('\n\tConnect: "OO", "Material::%s", "Model::%s"' % (sane_name_mapping_mat[mat.name], my_mesh.fbxName))
if textures:
- for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
- for texname, tex in textures:
- file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (texname, obname))
+ for my_mesh in ob_meshes:
+ if my_mesh.blenTextures:
+ # file.write('\n\tConnect: "OO", "Texture::_empty_", "Model::%s"' % my_mesh.fbxName)
+ for tex in my_mesh.blenTextures:
+ if tex:
+ file.write('\n\tConnect: "OO", "Texture::%s", "Model::%s"' % (sane_name_mapping_tex[tex.name], my_mesh.fbxName))
for texname, tex in textures:
file.write('\n\tConnect: "OO", "Video::%s", "Texture::%s"' % (texname, texname))
+ for my_mesh in ob_meshes:
+ if my_mesh.fbxArm:
+ file.write('\n\tConnect: "OO", "Deformer::Skin %s", "Model::%s"' % (my_mesh.fbxName, my_mesh.fbxName))
+
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ for fbxMeshObName in my_bone.blenMeshes: # .keys()
+ file.write('\n\tConnect: "OO", "SubDeformer::Cluster %s %s", "Deformer::Skin %s"' % (fbxMeshObName, my_bone.fbxName, fbxMeshObName))
+
+ # limbs -> deformers
+ # for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ for fbxMeshObName in my_bone.blenMeshes: # .keys()
+ file.write('\n\tConnect: "OO", "Model::%s", "SubDeformer::Cluster %s %s"' % (my_bone.fbxName, fbxMeshObName, my_bone.fbxName))
+
+
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for my_bone in ob_bones:
+ # Always parent to armature now
+ if my_bone.parent:
+ file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.parent.fbxName) )
+ else:
+ # the armature object is written as an empty and all root level bones connect to it
+ file.write('\n\tConnect: "OO", "Model::%s", "Model::%s"' % (my_bone.fbxName, my_bone.fbxArm.fbxName) )
+
+ # groups
+ if groups:
+ for ob_generic in ob_all_typegroups:
+ for ob_base in ob_generic:
+ for fbxGroupName in ob_base.fbxGroupNames:
+ file.write('\n\tConnect: "OO", "Model::%s", "GroupSelection::%s"' % (ob_base.fbxName, fbxGroupName))
+
+ for my_arm in ob_arms:
+ file.write('\n\tConnect: "OO", "Model::%s", "Model::blend_root"' % my_arm.fbxName)
+
file.write('\n}')
- # Clear mesh data Only when writing with modifiers applied
- #for obname, ob, me, mats, arm, armname in objects:
- # me.verts = None
+ # Needed for scene footer as well as animation
+ render = sce.render
+
+ # from the FBX sdk
+ #define KTIME_ONE_SECOND KTime (K_LONGLONG(46186158000))
+ def fbx_time(t):
+ # 0.5 + val is the same as rounding.
+ return int(0.5 + ((t/fps) * 46186158000))
+
+ fps = float(render.fps)
+ start = render.sFrame
+ end = render.eFrame
+ if end < start: start, end = end, start
+ if start==end: ANIM_ENABLE = False
+
+ # animations for these object types
+ ob_anim_lists = ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms
+
+ if ANIM_ENABLE and [tmp for tmp in ob_anim_lists if tmp]:
+
+ frame_orig = Blender.Get('curframe')
+
+ if ANIM_OPTIMIZE:
+ ANIM_OPTIMIZE_PRECISSION_FLOAT = 0.1 ** ANIM_OPTIMIZE_PRECISSION
+
+ # default action, when no actions are avaioable
+ tmp_actions = [None] # None is the default action
+ blenActionDefault = None
+ action_lastcompat = None
+
+ if ANIM_ACTION_ALL:
+ bpy.data.actions.tag = False
+ tmp_actions = list(bpy.data.actions)
+
+
+ # find which actions are compatible with the armatures
+ # blenActions is not yet initialized so do it now.
+ tmp_act_count = 0
+ for my_arm in ob_arms:
+
+ # get the default name
+ if not blenActionDefault:
+ blenActionDefault = my_arm.blenAction
+
+ 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()) )
+
+ if action_chan_names: # at least one channel matches.
+ my_arm.blenActionList.append(action)
+ action.tag = True
+ tmp_act_count += 1
+
+ # incase there is no actions applied to armatures
+ action_lastcompat = action
+
+ if tmp_act_count:
+ # unlikely to ever happen but if no actions applied to armatures, just use the last compatible armature.
+ if not blenActionDefault:
+ blenActionDefault = action_lastcompat
+
+ del action_lastcompat
+
+ file.write('''
+;Takes and animation section
+;----------------------------------------------------
+Takes: {''')
+
+ if blenActionDefault:
+ file.write('\n\tCurrent: "%s"' % sane_takename(blenActionDefault))
+ else:
+ file.write('\n\tCurrent: "Default Take"')
+
+ 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
+ else:
+ print '\taction: "%s" has no armature using it, skipping' % blenAction.name
+ continue
+
+ if blenAction == None:
+ # Warning, this only accounts for tmp_actions being [None]
+ file.write('\n\tTake: "Default Take" {')
+ act_start = start
+ act_end = end
+ else:
+ # use existing name
+ if blenAction == blenActionDefault: # have we alredy got the name
+ 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
+
+ # Set the action active
+ for my_bone in ob_arms:
+ if blenAction in my_bone.blenActionList:
+ ob.action = blenAction
+ # print '\t\tSetting Action!', blenAction
+ # sce.update(1)
+
+ file.write('\n\t\tFileName: "Default_Take.tak"') # ??? - not sure why this is needed
+ file.write('\n\t\tLocalTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed
+ file.write('\n\t\tReferenceTime: %i,%i' % (fbx_time(act_start-1), fbx_time(act_end-1))) # ??? - not sure why this is needed
+
+ file.write('''
-def write_footer(file, sce, world):
+ ;Models animation
+ ;----------------------------------------------------''')
+
+
+ # set pose data for all bones
+ # do this here incase the action changes
+ '''
+ for my_bone in ob_bones:
+ my_bone.flushAnimData()
+ '''
+ i = act_start
+ while i <= act_end:
+ Blender.Set('curframe', i)
+ for ob_generic in ob_anim_lists:
+ for my_ob in ob_generic:
+ #Blender.Window.RedrawAll()
+ if ob_generic == ob_meshes and my_ob.fbxArm:
+ # We cant animate armature meshes!
+ pass
+ else:
+ my_ob.setPoseFrame(i)
+
+ i+=1
+
+
+ #for bonename, bone, obname, me, armob in ob_bones:
+ for ob_generic in (ob_bones, ob_meshes, ob_null, ob_cameras, ob_lights, ob_arms):
+
+ for my_ob in ob_generic:
+
+ if ob_generic == ob_meshes and my_ob.fbxArm:
+ # do nothing,
+ pass
+ else:
+
+ file.write('\n\t\tModel: "Model::%s" {' % my_ob.fbxName) # ??? - not sure why this is needed
+ 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) ]
+
+ # ----------------
+ # ----------------
+ for TX_LAYER, TX_CHAN in enumerate('TRS'): # transform, rotate, scale
+
+ if TX_CHAN=='T': context_bone_anim_vecs = [mtx[0].translationPart() for mtx in context_bone_anim_mats]
+ elif TX_CHAN=='R': context_bone_anim_vecs = [mtx[1].toEuler() for mtx in context_bone_anim_mats]
+ else: context_bone_anim_vecs = [mtx[0].scalePart() for mtx in context_bone_anim_mats]
+
+ file.write('\n\t\t\t\tChannel: "%s" {' % TX_CHAN) # translation
+
+ for i in xrange(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] )
+ file.write('\n\t\t\t\t\t\tKeyVer: 4005')
+
+ if not ANIM_OPTIMIZE:
+ # Just write all frames, simple but in-eficient
+ file.write('\n\t\t\t\t\t\tKeyCount: %i' % (1 + act_end - act_start))
+ file.write('\n\t\t\t\t\t\tKey: ')
+ frame = act_start
+ while frame <= act_end:
+ if frame!=act_start:
+ file.write(',')
+
+ # Curve types are
+ # C,n is for bezier? - linear is best for now so we can do simple keyframe removal
+ file.write('\n\t\t\t\t\t\t\t%i,%.15f,C,n' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] ))
+ #file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame-1), context_bone_anim_vecs[frame-act_start][i] ))
+ frame+=1
+ else:
+ # remove unneeded keys, j is the frame, needed when some frames are removed.
+ context_bone_anim_keys = [ (vec[i], j) for j, vec in enumerate(context_bone_anim_vecs) ]
+
+ # last frame to fisrt frame, missing 1 frame on either side.
+ # removeing in a backwards loop is faster
+ for j in xrange( (act_end-act_start)-1, 0, -1 ):
+ # Is this key reduenant?
+ if abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j-1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT and\
+ abs(context_bone_anim_keys[j][0] - context_bone_anim_keys[j+1][0]) < ANIM_OPTIMIZE_PRECISSION_FLOAT:
+ del context_bone_anim_keys[j]
+
+ if len(context_bone_anim_keys) == 2 and context_bone_anim_keys[0][0] == context_bone_anim_keys[1][0]:
+ # This axis has no moton, its okay to skip KeyCount and Keys in this case
+ pass
+ else:
+ # We only need to write these if there is at least one
+ file.write('\n\t\t\t\t\t\tKeyCount: %i' % len(context_bone_anim_keys))
+ file.write('\n\t\t\t\t\t\tKey: ')
+ for val, frame in context_bone_anim_keys:
+ if frame != context_bone_anim_keys[0][1]: # not the first
+ file.write(',')
+ # frame is alredy one less then blenders frame
+ file.write('\n\t\t\t\t\t\t\t%i,%.15f,C,n' % (fbx_time(frame), val ))
+ #file.write('\n\t\t\t\t\t\t\t%i,%.15f,L' % (fbx_time(frame), val ))
+
+ if i==0: file.write('\n\t\t\t\t\t\tColor: 1,0,0')
+ elif i==1: file.write('\n\t\t\t\t\t\tColor: 0,1,0')
+ elif i==2: file.write('\n\t\t\t\t\t\tColor: 0,0,1')
+
+ file.write('\n\t\t\t\t\t}')
+ file.write('\n\t\t\t\t\tLayerType: %i' % (TX_LAYER+1) )
+ file.write('\n\t\t\t\t}')
+
+ # ---------------
+
+ file.write('\n\t\t\t}')
+ file.write('\n\t\t}')
+
+ # end the take
+ file.write('\n\t}')
+
+ # end action loop. set original actions
+ # do this after every loop incase actions effect eachother.
+ for my_bone in ob_arms:
+ my_bone.blenObject.action = my_bone.blenAction
+
+ file.write('\n}')
+
+ Blender.Set('curframe', frame_orig)
+
+ else:
+ # no animation
+ file.write('\n;Takes and animation section')
+ file.write('\n;----------------------------------------------------')
+ file.write('\n')
+ file.write('\nTakes: {')
+ file.write('\n\tCurrent: ""')
+ file.write('\n}')
- tuple(world.hor)
- tuple(world.amb)
- has_mist = world.mode & 1
+ # write meshes animation
+ #for obname, ob, mtx, me, mats, arm, armname in ob_meshes:
+
- mist_intense, mist_start, mist_end, mist_height = world.mist
+ # Clear mesh data Only when writing with modifiers applied
+ for me in meshes_to_clear:
+ me.verts = None
- render = sce.render
- file.write('\n;Takes and animation section')
- file.write('\n;----------------------------------------------------')
- file.write('\n')
- file.write('\nTakes: {')
- file.write('\n\tCurrent: ""')
- file.write('\n}')
+
+ # --------------------------- Footer
+ if world:
+ has_mist = world.mode & 1
+ mist_intense, mist_start, mist_end, mist_height = world.mist
+ world_hor = world.hor
+ else:
+ has_mist = mist_intense = mist_start = mist_end = mist_height = 0
+ world_hor = 0,0,0
+
file.write('\n;Version 5 settings')
file.write('\n;------------------------------------------------------------------')
file.write('\n')
file.write('\nVersion5: {')
file.write('\n\tAmbientRenderSettings: {')
file.write('\n\t\tVersion: 101')
- file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world.amb))
+ file.write('\n\t\tAmbientLightColor: %.1f,%.1f,%.1f,0' % tuple(world_amb))
file.write('\n\t}')
file.write('\n\tFogOptions: {')
file.write('\n\t\tFlogEnable: %i' % has_mist)
@@ -1355,15 +2626,15 @@ def write_footer(file, sce, world):
file.write('\n\t\tFogDensity: %.3f' % mist_intense)
file.write('\n\t\tFogStart: %.3f' % mist_start)
file.write('\n\t\tFogEnd: %.3f' % mist_end)
- file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world.hor))
+ file.write('\n\t\tFogColor: %.1f,%.1f,%.1f,1' % tuple(world_hor))
file.write('\n\t}')
file.write('\n\tSettings: {')
- file.write('\n\t\tFrameRate: "%i"' % render.fps)
+ file.write('\n\t\tFrameRate: "%i"' % int(fps))
file.write('\n\t\tTimeFormat: 1')
file.write('\n\t\tSnapOnFrames: 0')
file.write('\n\t\tReferenceTimeIndex: -1')
- file.write('\n\t\tTimeLineStartTime: %i' % render.sFrame)
- file.write('\n\t\tTimeLineStopTime: %i' % render.eFrame)
+ file.write('\n\t\tTimeLineStartTime: %i' % fbx_time(start-1))
+ file.write('\n\t\tTimeLineStopTime: %i' % fbx_time(end-1))
file.write('\n\t}')
file.write('\n\tRendererSetting: {')
file.write('\n\t\tDefaultCamera: "Producer Perspective"')
@@ -1377,24 +2648,329 @@ def write_footer(file, sce, world):
sane_name_mapping_mat.clear()
sane_name_mapping_tex.clear()
+ ob_arms[:] = []
+ ob_bones[:] = []
+ ob_cameras[:] = []
+ ob_lights[:] = []
+ ob_meshes[:] = []
+ ob_null[:] = []
+
+
+ # copy images if enabled
+ if EXP_IMAGE_COPY:
+ copy_images( Blender.sys.dirname(filename), [ tex[1] for tex in textures if tex[1] != None ])
+
+ print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
+ return True
+
-import bpy
-def write_ui(filename):
- if not filename.lower().endswith('.fbx'):
- filename += '.fbx'
+# --------------------------------------------
+# 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
+EVENT_NONE = 0
+EVENT_EXIT = 1
+EVENT_REDRAW = 2
+EVENT_FILESEL = 3
+
+GLOBALS = {}
+
+# export opts
+
+def do_redraw(e,v): GLOBALS['EVENT'] = e
+
+# toggle between these 2, only allow one on at once
+def do_obs_sel(e,v):
+ GLOBALS['EVENT'] = e
+ GLOBALS['EXP_OBS_SCENE'].val = 0
+ GLOBALS['EXP_OBS_SELECTED'].val = 1
+
+def do_obs_sce(e,v):
+ GLOBALS['EVENT'] = e
+ 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
+ GLOBALS['BATCH_SCENE'].val = 0
+
+def do_batch_type_sce(e,v):
+ GLOBALS['EVENT'] = e
+ GLOBALS['BATCH_GROUP'].val = 0
+ GLOBALS['BATCH_SCENE'].val = 1
+
+def do_anim_act_all(e,v):
+ GLOBALS['EVENT'] = e
+ GLOBALS['ANIM_ACTION_ALL'][0].val = 1
+ GLOBALS['ANIM_ACTION_ALL'][1].val = 0
+
+def do_anim_act_cur(e,v):
+ if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val:
+ Draw.PupMenu('Warning%t|Cant use this with batch export group option')
+ else:
+ GLOBALS['EVENT'] = e
+ GLOBALS['ANIM_ACTION_ALL'][0].val = 0
+ GLOBALS['ANIM_ACTION_ALL'][1].val = 1
+
+def fbx_ui_exit(e,v):
+ GLOBALS['EVENT'] = e
+
+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
- #if not BPyMessages.Warning_SaveOver(filename):
- # return
- sce = bpy.data.scenes.active
- world = sce.world
+ try:
+ import webbrowser
+ webbrowser.open(url)
+ except:
+ print '...could not open a browser window.'
+
+
+
+# run when export is pressed
+#def fbx_ui_write(e,v):
+def fbx_ui_write(filename):
+
+ # Dont allow overwriting files when saving normally
+ if not GLOBALS['BATCH_ENABLE'].val:
+ if not BPyMessages.Warning_SaveOver(filename):
+ return
+
+ GLOBALS['EVENT'] = EVENT_EXIT
+
+ # Keep the order the same as above for simplicity
+ # the [] is a dummy arg used for objects
Blender.Window.WaitCursor(1)
- file = open(filename, 'w')
- write_header(file)
- write_scene(file, sce, world)
- write_footer(file, sce, world)
+
+ # Make the matrix
+ GLOBAL_MATRIX = mtx4_identity
+ GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val
+ if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_x90n
+ if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_y90n
+ if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = GLOBAL_MATRIX * mtx4_z90n
+
+ ret = write(\
+ filename, None,\
+ GLOBALS['EXP_OBS_SELECTED'].val,\
+ GLOBALS['EXP_MESH'].val,\
+ GLOBALS['EXP_MESH_APPLY_MOD'].val,\
+ GLOBALS['EXP_MESH_HQ_NORMALS'].val,\
+ GLOBALS['EXP_ARMATURE'].val,\
+ GLOBALS['EXP_LAMP'].val,\
+ GLOBALS['EXP_CAMERA'].val,\
+ GLOBALS['EXP_EMPTY'].val,\
+ GLOBALS['EXP_IMAGE_COPY'].val,\
+ GLOBAL_MATRIX,\
+ GLOBALS['ANIM_ENABLE'].val,\
+ GLOBALS['ANIM_OPTIMIZE'].val,\
+ GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\
+ GLOBALS['ANIM_ACTION_ALL'][0].val,\
+ GLOBALS['BATCH_ENABLE'].val,\
+ GLOBALS['BATCH_GROUP'].val,\
+ GLOBALS['BATCH_SCENE'].val,\
+ GLOBALS['BATCH_FILE_PREFIX'].val,\
+ GLOBALS['BATCH_OWN_DIR'].val,\
+ )
+
Blender.Window.WaitCursor(0)
+ GLOBALS.clear()
+
+ if ret == False:
+ Draw.PupMenu('Error%t|Path cannot be written to!')
+
+
+def fbx_ui():
+ # Only to center the UI
+ x,y = GLOBALS['MOUSE']
+ x-=180; y-=0 # offset... just to get it centered
+
+ Draw.Label('Export Objects...', x+20,y+165, 200, 20)
+
+ if not GLOBALS['BATCH_ENABLE'].val:
+ Draw.BeginAlign()
+ GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel)
+ GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce)
+ Draw.EndAlign()
+
+ Draw.BeginAlign()
+ GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)')
+ GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrese about the X axis')
+ GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrese about the Y axis')
+ GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrese about the Z axis')
+ Draw.EndAlign()
+
+ y -= 35
+
+ Draw.BeginAlign()
+ GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects')
+ GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects')
+ GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects')
+ GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects')
+ GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z)
+ Draw.EndAlign()
+
+ if GLOBALS['EXP_MESH'].val:
+ # below mesh but
+ Draw.BeginAlign()
+ GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z)
+ GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z)
+ Draw.EndAlign()
+
+ GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z)
+
+
+ Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20)
+
+ GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw)
+ if GLOBALS['ANIM_ENABLE'].val:
+ Draw.BeginAlign()
+ GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw)
+ if GLOBALS['ANIM_OPTIMIZE'].val:
+ GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 3, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)')
+ Draw.EndAlign()
+
+ Draw.BeginAlign()
+ GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur)
+ GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all)
+ Draw.EndAlign()
+
+
+ Draw.Label('Export Batch...', x+20,y-60, 300, 20)
+ GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw)
+
+ if GLOBALS['BATCH_ENABLE'].val:
+ Draw.BeginAlign()
+ GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp)
+ GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce)
+
+ # Own dir requires OS module
+ if os:
+ GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file')
+ GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
+ else:
+ GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
+
+
+ Draw.EndAlign()
+ #y+=80
+
+ '''
+ Draw.BeginAlign()
+ GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ')
+ Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw)
+ '''
+ # Until batch is added
+ #
+
+
+ #Draw.BeginAlign()
+ Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help)
+ Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit)
+ Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw)
+
+ #Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write)
+ #Draw.EndAlign()
+
+ # exit when mouse out of the view?
+ # GLOBALS['EVENT'] = EVENT_EXIT
+
+#def write_ui(filename):
+def write_ui():
+
+ # globals
+ GLOBALS['EVENT'] = 2
+ #GLOBALS['MOUSE'] = Window.GetMouseCoords()
+ GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
+ GLOBALS['FILENAME'] = ''
+ '''
+ # IF called from the fileselector
+ if filename == None:
+ GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx'))
+ else:
+ GLOBALS['FILENAME'].val = filename
+ '''
+ GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity
+ GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0)
+
+ GLOBALS['EXP_MESH'] = Draw.Create(1)
+ GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1)
+ GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0)
+ GLOBALS['EXP_ARMATURE'] = Draw.Create(1)
+ GLOBALS['EXP_LAMP'] = Draw.Create(1)
+ GLOBALS['EXP_CAMERA'] = Draw.Create(1)
+ GLOBALS['EXP_EMPTY'] = Draw.Create(1)
+ GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0)
+ # animation opts
+ GLOBALS['ANIM_ENABLE'] = Draw.Create(1)
+ GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1)
+ GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(6) # decimal places
+ GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action
+
+ # batch export options
+ GLOBALS['BATCH_ENABLE'] = Draw.Create(0)
+ GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once.
+ GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above
+ GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1])
+ GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0)
+ # done setting globals
+
+ # Used by the user interface
+ GLOBALS['_SCALE'] = Draw.Create(1.0)
+ GLOBALS['_XROT90'] = Draw.Create(True)
+ GLOBALS['_YROT90'] = Draw.Create(False)
+ GLOBALS['_ZROT90'] = Draw.Create(False)
+
+ # horrible ugly hack so tooltips draw, dosnt always work even
+ # Fixed in Draw.UIBlock for 2.45rc2, but keep this until 2.45 is released
+ Window.SetKeyQualifiers(0)
+ while Window.GetMouseButtons(): Blender.sys.sleep(10)
+ for i in xrange(100): Window.QHandle(i)
+ # END HORRID HACK
+
+ # best not do move the cursor
+ # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()])
+
+ # hack so the toggle buttons redraw. this is not nice at all
+ while GLOBALS['EVENT'] != EVENT_EXIT:
+
+ if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val:
+ #Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ")
+ GLOBALS['ANIM_ACTION_ALL'][0].val = 1
+ GLOBALS['ANIM_ACTION_ALL'][1].val = 0
+
+ if GLOBALS['EVENT'] == EVENT_FILESEL:
+ if GLOBALS['BATCH_ENABLE'].val:
+ txt = 'Batch FBX Dir'
+ name = Blender.sys.expandpath('//')
+ else:
+ txt = 'Export FBX'
+ name = Blender.sys.makename(ext='.fbx')
+
+ Blender.Window.FileSelector(fbx_ui_write, txt, name)
+ #fbx_ui_write('/test.fbx')
+ break
+
+ Draw.UIBlock(fbx_ui)
+
+
+ # GLOBALS.clear()
+#test = [write_ui]
if __name__ == '__main__':
- Blender.Window.FileSelector(write_ui, 'Export FBX', Blender.sys.makename(ext='.fbx'))
- #write_ui('/test.fbx')
+ # 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()
diff --git a/release/scripts/export_m3g.py b/release/scripts/export_m3g.py
index afb019fcc1e..08215b3d027 100644
--- a/release/scripts/export_m3g.py
+++ b/release/scripts/export_m3g.py
@@ -234,6 +234,19 @@ Tooltip: 'Export to M3G'
#
# * 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
@@ -1213,7 +1226,7 @@ class M3GVertexArray(M3GObject3D):
# 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]= int(self.components[i]*(-1))
+ 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!")
@@ -1284,7 +1297,7 @@ class M3GVertexArray(M3GObject3D):
self.blenderIndexes[key]=index
#print"blenderIndexes",self.blenderIndexes
else:
- # print "VertexArray.append: element=",element
+ print "VertexArray.append: element=",element
self.components.append(element)
class M3GVertexBuffer(M3GObject3D):
@@ -2001,7 +2014,7 @@ class M3GTranslator:
self.scene = Blender.Scene.GetCurrent()
self.world = self.translateWorld(self.scene)
- for obj in self.scene.objects:
+ for obj in self.scene.objects :
if obj.getType()=='Camera': # older Version: isinstance(obj.getData(),Types.CameraType)
self.translateCamera(obj)
elif obj.getType()=='Mesh':
@@ -2176,7 +2189,7 @@ class M3GTranslator:
if mOptions.createAmbientLight & mOptions.lightingEnabled:
lLight = M3GLight()
lLight.mode = lLight.modes['AMBIENT']
- lLight.color = self.translateRGB(AllWorlds[0].getAmb())
+ lLight.color = self.translateRGB(blWorld.getAmb())
self.nodes.append(lLight)
#TODO: Set background picture from world
@@ -2550,7 +2563,7 @@ class M3GTranslator:
mLight.intensity = lamp.energy
#SpotAngle, SpotExponent (SPOT)
if lampType == Lamp.Types.Spot:
- mLight.spotAngle = lamp.spotSize
+ mLight.spotAngle = lamp.spotSize/2
mLight.spotExponent = lamp.spotBlend
self.translateToNode(obj,mLight)
@@ -2945,6 +2958,8 @@ class OptionMgr:
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
@@ -2958,6 +2973,8 @@ class OptionMgr:
self.perspectiveCorrection = False
self.smoothShading = True
self.exportAsJava = False
+ self.exportVersion2 = False
+ self.exportGamePhysics = False
def save(self):
d = {}
@@ -2970,7 +2987,9 @@ class OptionMgr:
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)
@@ -2993,6 +3012,8 @@ def gui():
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'),\
@@ -3008,7 +3029,9 @@ def gui():
('Posing'),\
('All Armature Actions', exportAllActions, 'Exports all actions for armatures'),\
('Export'),\
- ('As Java Source', exportAsJava, 'Exports scene as Java source code')
+ ('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).
@@ -3022,6 +3045,8 @@ def gui():
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:
diff --git a/release/scripts/export_mdd.py b/release/scripts/export_mdd.py
index 42a85029505..8173059ca5a 100644
--- a/release/scripts/export_mdd.py
+++ b/release/scripts/export_mdd.py
@@ -58,7 +58,8 @@ def mdd_export(filepath, ob, PREF_STARTFRAME, PREF_ENDFRAME, PREF_FPS):
Window.EditMode(0)
Blender.Window.WaitCursor(1)
- mesh_orig = ob.getData(mesh=1)
+ mesh_orig = Mesh.New()
+ mesh_orig.getFromObject(ob.name)
#Flip y and z
'''
diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py
index 4c7ced2d200..8e7374f02b5 100644
--- a/release/scripts/export_obj.py
+++ b/release/scripts/export_obj.py
@@ -68,15 +68,11 @@ def fixName(name):
else:
return name.replace(' ', '_')
-# Used to add the scene name into the filename without using odd chars
-global MTL_DICT
-
# A Dict of Materials
# (material.name, image.name):matname_imagename # matname_imagename has gaps removed.
MTL_DICT = {}
def write_mtl(filename):
- global MTL_DICT
world = Blender.World.GetCurrent()
if world:
@@ -88,23 +84,14 @@ def write_mtl(filename):
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 in MTL_DICT.iteritems():
+ 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 key[0] == None:
- #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
- else:
- mat = Blender.Material.Get(key[0])
+ 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
@@ -120,13 +107,20 @@ def write_mtl(filename):
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 key[1] != None: # We have an image on the face!
- img = Image.Get(key[1])
+ 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 key[0] != None: # No face image. if we havea material search for MTex image.
+ elif not 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:
@@ -157,26 +151,26 @@ def copy_images(dest_dir):
# Get unique image names
uniqueImages = {}
- for matname, imagename in MTL_DICT.iterkeys(): # Only use image name
+ for matname, mat, image in MTL_DICT.itervalues(): # Only use image name
# Get Texface images
- if imagename != None:
- uniqueImages[imagename] = None # Should use sets here. wait until Python 2.4 is default.
+ if image:
+ uniqueImages[image] = image # Should use sets here. wait until Python 2.4 is default.
# Get MTex images
- if matname != None:
- mat= Blender.Material.Get(matname)
+ if mat:
for mtex in mat.getTextures():
if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
- try:
- uniqueImages[mtex.tex.image.name] = None
- except:
- pass
+ image_tex = mtex.tex.image
+ if image_tex:
+ try:
+ uniqueImages[image_tex] = image_tex
+ except:
+ pass
# Now copy images
copyCount = 0
- for imageName in uniqueImages.iterkeys():
- bImage = Image.Get(imageName)
+ for bImage in uniqueImages.itervalues():
image_path = sys.expandpath(bImage.filename)
if sys.exists(image_path):
# Make a name for the target path.
@@ -187,12 +181,6 @@ def copy_images(dest_dir):
copyCount+=1
print '\tCopied %d images' % copyCount
-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 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,\
@@ -204,8 +192,14 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
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)
+
print 'OBJ Export path: "%s"' % filename
- global MTL_DICT
temp_mesh_name = '~tmp-mesh'
time1 = sys.time()
@@ -241,7 +235,7 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
# Initialize totals, these are updated each object
totverts = totuvco = totno = 1
- face_vert_index = 1 # used for uvs now
+ face_vert_index = 1
globalNormals = {}
@@ -253,7 +247,11 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scn)
if not me:
continue
- faceuv= me.faceUV
+
+ if EXPORT_UV:
+ faceuv= me.faceUV
+ else:
+ faceuv = False
# We have a valid mesh
if EXPORT_TRI and me.faces:
@@ -293,14 +291,21 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
me.transform(ob_mat)
# High Quality Normals
- if EXPORT_NORMALS and EXPORT_NORMALS_HQ and faces:
- BPyMesh.meshCalcNormals(me)
+ 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
@@ -313,13 +318,13 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
# 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_MORPH_TARGET:
pass
- elif faceuv and EXPORT_UV:
+ 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:
@@ -353,10 +358,23 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
file.write('v %.6f %.6f %.6f\n' % tuple(v.co))
# UV
- if faceuv and EXPORT_UV:
- for f in faces:
- for uv in f.uv:
- file.write('vt %.6f %.6f 0.0\n' % tuple(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:
@@ -376,18 +394,22 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
totno +=1
file.write('vn %.6f %.6f %.6f\n' % noKey)
- for f in faces:
+ if not faceuv:
+ f_image = None
+
+ 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 EXPORT_UV and faceuv and f.image: # Object is always true.
- key = materialNames[min(f.mat,len(materialNames)-1)], f.image.name
- #key = materialNames[f.mat], f.image.name
+ if faceuv and f_image: # Object is always true.
+ key = materialNames[f_mat], f_image.name
else:
- key = materialNames[min(f.mat,len(materialNames)-1)], None # No image, use None instead.
- #key = materialNames[f.mat], None # No image, use None instead.
+ key = materialNames[f_mat], None # No image, use None instead.
# CHECK FOR CONTEXT SWITCH
if key == contextMat:
@@ -395,16 +417,13 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
else:
if key[0] == None and key[1] == None:
# Write a null material, since we know the context has changed.
- matstring = '(null)'
+ 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:
- try: # Faster to try then 2x dict lookups.
- # We have the material, just need to write the context switch,
- matstring = MTL_DICT[key]
-
-
- except KeyError:
+ mat_data= MTL_DICT.get(key)
+ if not mat_data:
# First add to global dict so we can export to mtl
# Then write mtl
@@ -413,32 +432,31 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
# If none image dont bother adding it to the name
if key[1] == None:
- matstring = MTL_DICT[key] ='%s' % fixName(key[0])
+ mat_data = MTL_DICT[key] = ('%s'%fixName(key[0])), materialItems[f_mat], f_image
else:
- matstring = MTL_DICT[key] = '%s_%s' % (fixName(key[0]), fixName(key[1]))
-
- if EXPORT_GROUP_BY_MAT:
- file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), matstring) ) # can be mat_image or (null)
- file.write('usemtl %s\n' % matstring) # can be mat_image or (null)
+ 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 contextSmooth: # on now off
- file.write('s off\n')
- contextSmooth = True
- else: # was off now on
+ if f_smooth != contextSmooth:
+ if f_smooth: # on now off
file.write('s 1\n')
- contextSmooth = False
+ contextSmooth = f_smooth
+ else: # was off now on
+ file.write('s off\n')
+ contextSmooth = f_smooth
file.write('f')
- if faceuv and EXPORT_UV:
+ if faceuv:
if EXPORT_NORMALS:
- if f.smooth: # Smoothed, use vertex normals
+ if f_smooth: # Smoothed, use vertex normals
for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % (\
v.index+totverts,\
- face_vert_index + vi,\
+ totuvco + uv_face_mapping[f_index][vi],\
globalNormals[ veckey3d(v.no) ])) # vert, uv, normal
else: # No smoothing, face normals
@@ -446,20 +464,20 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
for vi, v in enumerate(f_v):
file.write( ' %d/%d/%d' % (\
v.index+totverts,\
- face_vert_index + vi,\
+ 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,\
- face_vert_index + vi)) # vert, uv
+ 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
+ if f_smooth: # Smoothed, use vertex normals
for v in f_v:
file.write( ' %d//%d' % (\
v.index+totverts,\
@@ -486,6 +504,8 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_MORPH_TARGET=False)
# Make the indicies global rather then per mesh
totverts += len(me.verts)
+ if faceuv:
+ totuvco += uv_unique_count
me.verts= None
file.close()
@@ -512,9 +532,8 @@ def write_ui(filename):
if not filename.lower().endswith('.obj'):
filename += '.obj'
- #if not BPyMessages.Warning_SaveOver(filename):
- # return
-
+ if not BPyMessages.Warning_SaveOver(filename):
+ return
EXPORT_APPLY_MODIFIERS = Draw.Create(1)
EXPORT_ROTX90 = Draw.Create(1)
@@ -535,7 +554,6 @@ def write_ui(filename):
# removed too many options are bad!
-
# Get USER Options
pup_block = [\
('Context...'),\
@@ -631,14 +649,14 @@ def write_ui(filename):
full_path= ''.join(context_name)
- if BPyMessages.Warning_SaveOver(full_path):
- # 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_MORPH_TARGET)
+ # 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_MORPH_TARGET)
Blender.Set('curframe', orig_frame)
diff --git a/release/scripts/flt_defaultp.py b/release/scripts/flt_defaultp.py
new file mode 100644
index 00000000000..5dca8ba63d7
--- /dev/null
+++ b/release/scripts/flt_defaultp.py
@@ -0,0 +1 @@
+pal = [-256,0,16711680,-16777216,-19529984,-19726592,-19923200,-20119808,-20316416,-20578560,-20840704,-21102848,-21364992,-21692672,-22020352,-22413568,-22806784,-23200000,-23658752,-24117504,-24641792,-25166080,-25755904,-26411264,-27066624,-27787520,-28573952,-29425920,-30343424,-31326464,-32375040,-33489152,-354550016,-371458304,-388366592,-405274880,-422183168,-439156992,-456130816,-473104640,-506855680,-540672256,-574488832,-608305408,-642121984,-676004096,-709886208,-760611072,-811335936,-862060800,-912851200,-980418816,-1048051968,-1115685120,-1183383808,-1267925248,-1352466688,-1453850880,-1555300608,-1656815872,-1775173888,-1893597440,-2028863744,2130771712,-1010376448,-1043996416,-1077681920,-1111367424,-1145052928,-1178738432,-1229201152,-1279663872,-1330126592,-1380654848,-1431183104,-1498488576,-1565794048,-1633165056,-1700536064,-1784684288,-1868832512,-1969823488,-2070814464,2123096320,2005262592,1887428864,1752752384,1601298688,1449779456,1281417472,1096278272,911073536,709026048,490201344,254533888,2023680,-1380857856,-1397700608,-1431320576,-1464940544,-1498560512,-1532180480,-1565865984,-1599551488,-1650014208,-1700476928,-1750939648,-1801402368,-1851865088,-1919170560,-1986476032,-2053781504,-2121086976,2089797632,2005649408,1904723968,1803798528,1686030336,1568262144,1450493952,1315883008,1164494848,1013041152,844810240,659736576,457885696,239192064,3655680,-1767919872,-1784762624,-1801605376,-1818448128,-1852068096,-1885688064,-1919308032,-1952928000,-1986547968,-2020167936,-2070565120,-2120962304,2123542272,2073079552,2022616832,1955376896,1888136960,1820897024,1736879872,1652797184,1568714496,1467854592,1366994688,1249357568,1131654912,997175040,862695168,711372544,560049920,391950080,207007488,5287680,2139657728,2122880512,2106103296,2089326080,2072548864,2055771648,2022217216,1988662784,1955108352,1921553920,1887933952,1854313984,1803916800,1753519616,1703122432,1652725248,1602328064,1535153664,1467979264,1400804864,1316853248,1232901632,1148950016,1048221184,947426816,846632448,729060864,611489280,477140480,326014464,174888448,6919680,1837268224,1820491008,1803713792,1786936576,1770159360,1753382144,1736604928,1719827712,1686273280,1652718848,1619164416,1585609984,1552055552,1518501120,1468169472,1417837824,1367506176,1317174528,1266842880,1199734016,1132625152,1065516288,998407424,914521344,830635264,729971968,629308672,528645376,411204864,293764352,159546624,8551680,-2086957824,-2103735040,-2120512256,-2137289472,2140900608,2107346176,2073791744,2040237056,2006682368,1973127680,1939572992,1906018304,1855686400,1805354496,1755022592,1704690688,1654358784,1587249664,1520140544,1453031424,1369145088,1285258496,1201371904,1100708096,1000044288,882603264,765162240,630943744,496725248,345729536,177956608,10183680,-1699438080,-1716215552,-1732993024,-1766547712,-1800102400,-1833657088,-1867211776,-1900766464,-1934321152,-1967875840,-2018207744,-2068539904,-2118872064,2125763072,2058653696,1991544320,1924434944,1857325568,1773438720,1689551872,1588887808,1488223744,1387559424,1270117888,1152676352,1018457600,884238592,733242368,565468672,397694976,213144064,11815680,-1311918848,-1345473536,-1379028224,-1412582912,-1446137600,-1479692544,-1513247488,-1546802432,-1597134592,-1647466752,-1697798912,-1748131072,-1798463488,-1865573120,-1932682752,-1999792384,-2083679232,2127400960,2043513856,1942849536,1842184960,1724743168,1607301376,1473082112,1338862848,1187866112,1020092160,852317952,667766528,466437632,248331264,13447680,-924399104,-957954048,-991508992,-1025063936,-1058618880,-1092173824,-1142505984,-1192838144,-1243170560,-1293502976,-1343835392,-1410945024,-1478054656,-1545164544,-1629051648,-1712938752,-1796826112,-1897490688,-1998155264,-2098820096,2078705152,1961262848,1827043328,1676046336,1525049344,1357274880,1172722944,971393792,753287168,518403072,283518720,15079680,-570434304,-603989248,-637544192,-671099136,-704654080,-754986496,-805318912,-855651328,-905983744,-973093632,-1040203520,-1107313408,-1174423296,-1258310656,-1342198016,-1442862848,-1543527680,-1644192512,-1761634816,-1879077120,-2013296896,2147450624,1996453376,1828678656,1660903936,1476351744,1275022080,1056914944,822030336,570368256,301928704,16711680,-503325440,-536880384,-570435328,-603990272,-637545216,-671100416,-721432832,-771765248,-822097664,-872430336,-922763008,-989872896,-1056982784,-1124092928,-1191203072,-1275090688,-1358978304,-1459643136,-1560308224,-1660973312,-1778415872,-1895858432,-2030078464,2113891328,1962893824,1795118848,1610566400,1426013696,1224683520,1006575872,771690752,520028160,-452993792,-469771520,-503326464,-536881408,-570436352,-603991552,-637546752,-671101952,-721434368,-771767040,-822099712,-872432384,-922765056,-989875200,-1056985344,-1124095744,-1191206144,-1275093760,-1358981632,-1459646720,-1560312064,-1677754624,-1795197440,-1912640512,-2046860800,2097108736,1946110720,1778335232,1593782272,1392451840,1174343936,939458560,-419439360,-436217088,-452994816,-469772544,-503327488,-536882688,-570437888,-603993088,-637548288,-671103744,-721436416,-771769088,-822101760,-872434688,-922767616,-989878016,-1056988416,-1124098816,-1207986688,-1291874560,-1375762688,-1476428032,-1577093632,-1694536704,-1811979776,-1946200320,-2080421120,2063547904,1912549376,1744773376,1560219904,1358888960,-385884928,-402662656,-419440384,-436218112,-452995840,-469773824,-503329024,-536884224,-570439424,-603994880,-637550336,-671105792,-721438464,-771771392,-822104320,-872437504,-922770688,-989881088,-1056991744,-1124102400,-1191213312,-1275101440,-1358989824,-1459655680,-1560321536,-1677764864,-1795208448,-1912652288,-2046873600,2097094912,1946095872,1778319360,-335553280,-352331008,-369108736,-385886464,-402664192,-419442176,-436220160,-452998144,-486553344,-520108800,-553664256,-587219712,-620775168,-654330880,-687886592,-738219776,-788552960,-838886144,-889219584,-939553024,-1006663936,-1073774848,-1140886016,-1224774656,-1308663296,-1392552192,-1493218560,-1593885184,-1711329280,-1828773632,-1962995456,-2097217536,-285221632,-301999360,-318777088,-335554816,-352332544,-369110528,-385888512,-402666496,-419444480,-436222720,-453000960,-469779200,-503334656,-536890368,-570446080,-604002048,-637558016,-671113984,-721447424,-771780864,-822114560,-872448256,-922782208,-989893632,-1057005056,-1124116736,-1191228672,-1275118080,-1359007744,-1459674880,-1560342272,-1677787136,-234889984,-234890496,-251668224,-268445952,-285223680,-302001664,-318779648,-335557632,-352335616,-369113856,-385892096,-402670336,-419448576,-436227072,-453005568,-469784320,-503340288,-536896256,-570452480,-604008704,-637565184,-671121664,-704678400,-755012608,-805346816,-855681280,-906016000,-973128192,-1040240640,-1107353344,-1174466304,-1258356736,-234889984,-234890496,-234891008,-234891520,-234892032,-234892800,-234893568,-234894336,-234895104,-251673344,-268451584,-285229824,-302008064,-318786560,-335565056,-352343808,-369122560,-385901312,-402680320,-419459328,-436238592,-453017856,-486574592,-520131584,-553688576,-587245824,-620803328,-654361088,-687919104,-738254592,-788590336,-838926336,-234889984,-234890496,-234891008,-234891520,-234892032,-234892800,-234893568,-234894336,-234895104,-234896128,-234897152,-234898176,-234899200,-234900480,-234901760,-234903296,-234904832,-234906368,-234908160,-234909952,-234912000,-251691264,-268470784,-285250560,-302030336,-318810368,-335590656,-352371200,-369152000,-385933056,-402714368,-419495936,-8960,-9472,-9984,-10496,-11008,-11776,-12544,-13312,-14080,-15104,-16128,-17152,-18176,-19456,-20736,-22272,-23808,-25344,-27136,-28928,-30976,-33024,-35328,-37888,-40448,-43264,-46336,-49664,-53248,-57088,-61184,-65536,-926464,-926976,-927488,-928000,-928512,-929280,-930048,-930816,-931584,-932608,-933632,-934656,-935680,-936960,-938240,-939776,-941312,-1008384,-1075712,-1143040,-1210624,-1278208,-1346048,-1414144,-1482240,-1550592,-1619200,-1688064,-1757184,-1826560,-1896192,-2031616,-926464,-926976,-927488,-928000,-928512,-929280,-930048,-996352,-1062656,-1129216,-1195776,-1262336,-1328896,-1395712,-1462528,-1529600,-1596672,-1663744,-1731072,-1798400,-1865984,-1999104,-2132480,-2266112,-2399744,-2533632,-2667776,-2867712,-3067904,-3268352,-3469056,-3670016,-926464,-992512,-1058560,-1124608,-1190656,-1256960,-1323264,-1389568,-1455872,-1522432,-1588992,-1655552,-1722112,-1788928,-1855744,-1988352,-2120960,-2253568,-2386432,-2519296,-2652416,-2785536,-2984448,-3183616,-3382784,-3582208,-3847424,-4112896,-4378624,-4644608,-4976384,-5308416,-1188608,-1254656,-1320704,-1386752,-1452800,-1519104,-1585408,-1651712,-1718016,-1784576,-1851136,-1983232,-2115328,-2247680,-2380032,-2512640,-2645248,-2777856,-2976256,-3174656,-3373312,-3571968,-3836416,-4101120,-4365824,-4630784,-4961536,-5292544,-5689344,-6086400,-6483712,-6946816,-1385216,-1451264,-1517312,-1583360,-1649408,-1715712,-1782016,-1848320,-1980160,-2112256,-2244352,-2376448,-2508544,-2640896,-2838784,-3036928,-3235072,-3433216,-3631616,-3895552,-4159744,-4423936,-4688384,-5018624,-5348864,-5744896,-6141184,-6537728,-7000064,-7462656,-7991040,-8585216,-1581824,-1647872,-1713920,-1779968,-1846016,-1977856,-2109696,-2241536,-2373376,-2505472,-2637568,-2769664,-2967296,-3165184,-3363072,-3561216,-3759360,-4023040,-4286976,-4550912,-4880640,-5210368,-5540352,-5936128,-6331904,-6793472,-7255296,-7782912,-8310784,-8904448,-9563904,-10223616,-1712896,-1778944,-1844992,-1976576,-2108160,-2240000,-2371840,-2503680,-2635520,-2767616,-2965248,-3162880,-3360512,-3558400,-3821824,-4085504,-4349184,-4612864,-4942336,-5271808,-5667072,-6062336,-6457856,-6919168,-7380480,-7907584,-8434944,-9028096,-9687040,-10346240,-11071232,-11862016,-1843968,-1975552,-2107136,-2238720,-2370304,-2502144,-2633984,-2765824,-2963200,-3160832,-3358464,-3556096,-3753728,-4017152,-4280576,-4544256,-4873472,-5202688,-5532160,-5927168,-6322432,-6783232,-7244288,-7771136,-8297984,-8890624,-9549056,-10207744,-10932224,-11722496,-12578560,-13500416,-1975040,-2106624,-2238208,-2369792,-2501376,-2633216,-2830592,-3027968,-3225344,-3422976,-3620608,-3883776,-4146944,-4410368,-4673792,-5003008,-5332224,-5726976,-6121984,-6582528,-7043328,-7504128,-8030720,-8623104,-9215488,-9873664,-10597632,-11387392,-12242944,-13164288,-14085888,-15138816,-2237184,-2368768,-2500352,-2631936,-2763520,-2960896,-3158272,-3355648,-3553024,-3816192,-4079360,-4342528,-4605696,-4934656,-5263616,-5658368,-6053120,-6447872,-6908416,-7368960,-7895296,-8421632,-9013760,-9671680,-10329600,-11053312,-11842816,-12698112,-13619200,-14606080,-15658752,-16777216] \ No newline at end of file
diff --git a/release/scripts/flt_export.py b/release/scripts/flt_export.py
index 283c24a3ad0..5e69e203374 100755..100644
--- a/release/scripts/flt_export.py
+++ b/release/scripts/flt_export.py
@@ -1,45 +1,25 @@
#!BPY
""" Registration info for Blender menus:
Name: 'OpenFlight (.flt)...'
-Blender: 237
+Blender: 245
Group: 'Export'
Tip: 'Export to OpenFlight v16.0 (.flt)'
"""
-__author__ = "Greg MacDonald"
-__version__ = "1.2 10/20/05"
+__author__ = "Greg MacDonald, Geoffrey Bantle"
+__version__ = "2.0 11/21/07"
__url__ = ("blender", "elysiun", "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.
-Run from "File->Export" menu.
-
-Options are available from Blender's "Scripts Config Editor," accessible through
-the "Scripts->System" menu from the scripts window.
-
-Features:<br>
-* Heirarchy retained.<br>
-* Normals retained.<br>
-* First texture exported.<br>
-* Diffuse material color is exported as the face color, material color, or both
-depending on the option settings.<br>
-* Double sided faces are exported as two faces.<br>
-* Object transforms exported.
-
-Things To Be Aware Of:<br>
-* Object names are exported, not mesh or data names.
-* Material indices that don't have a material associated with them will confuse the
-exporter. If a warning appears about this, correct it by deleting the offending
-material indices in Blender.
-
-What's Not Handled:<br>
-* Animations.<br>
-* Vetex colors.<br>
+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
+#
+# 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
@@ -56,29 +36,87 @@ What's Not Handled:<br>
# 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
+
+FF = FileFinder()
+records = process_recordDefs()
class ExporterOptions:
def __init__(self):
- self.defaults = { 'Diffuse Color To OpenFlight Material': False,
- 'Diffuse Color To OpenFlight Face': True}
+ self.verbose = 1
+ self.tolerance = 0.001
+ self.writevcol = True
- d = Blender.Registry.GetKey('flt_export', True)
+ #new stuff
+ self.export_shading = 0
+ self.shading_default = 45.0
+ self.basepath = os.path.dirname(Blender.Get('filename'))
+ self.scale = 1.0
- if d == None or d.keys() != self.defaults.keys():
- d = self.defaults
- Blender.Registry.SetKey('flt_export', d, True)
+ #set externals path
+ if(os.path.exists(os.path.join(self.basepath,'externals'))):
+ self.externalspath = os.path.join(self.basepath,'externals')
+ else:
+ self.externalspath = self.basepath
- self.verbose = 1
- self.tolerance = 0.001
- self.use_mat_color = d['Diffuse Color To OpenFlight Material']
- self.use_face_color = d['Diffuse Color To OpenFlight Face']
+ self.doxrefs = 1
+
+ #texture options
+ if(os.path.exists(os.path.join(self.basepath,'textures'))):
+ self.texturespath = os.path.join(self.basepath,'textures')
+ else:
+ self.texturespath = self.basepath
+
+ #misc
+ self.write_attrib_files = 0
+ self.copy_textures = 0
+ self.export_transform = 0
+ self.flattenmesh = False
+ self.xapp = 1
+ reg = Blender.Registry.GetKey('flt_export',1)
+ if(reg and 'xappath' in reg.keys()):
+ self.xappath = reg['xappath']
+ else:
+ self.xappath = ''
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):
@@ -102,13 +140,47 @@ class MaterialDesc:
self.alpha = 1.0 # Range is [0.0, 1.0]
class VertexDesc:
- def __init__(self, co=None, no=None, uv=None):
+ 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):
@@ -121,44 +193,104 @@ class GlobalResourceRepository:
def request_vertex_desc(self, i):
return self.vertex_lst[i]
- def request_vertex_index(self, desc):
- match = None
- for i, v in enumerate(self.vertex_lst):
- if\
- abs(v.x - desc.x) > FLOAT_TOLERANCE or\
- abs(v.y - desc.y) > FLOAT_TOLERANCE or\
- abs(v.z - desc.z) > FLOAT_TOLERANCE or\
- abs(v.nx - desc.nx) > FLOAT_TOLERANCE or\
- abs(v.ny - desc.ny) > FLOAT_TOLERANCE or\
- abs(v.nz - desc.nz) > FLOAT_TOLERANCE or\
- abs(v.u - desc.u) > FLOAT_TOLERANCE or\
- abs(v.v - desc.v) > FLOAT_TOLERANCE:
- pass
- else:
- match = i
- break
+ def request_vertex_index(self, object, mesh, face, vfindex, uvok,cindex):
- if match != None:
- return match
- else:
- self.vertex_lst.append(desc)
- return len(self.vertex_lst) - 1
+ flatShadeNorm = None
+ vno = None
- def request_texture_index(self, filename):
+
+ 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.export_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] != filename:
+ if self.texture_lst[i] != image:
continue
match = i
break
if match != None:
return match
else:
- self.texture_lst.append(filename)
+ self.texture_lst.append(image)
return len(self.texture_lst) - 1
def request_texture_filename(self, index):
- return self.texture_lst[index]
+ return Blender.sys.expandpath(self.texture_lst[index].getFilename())
def texture_count(self):
return len(self.texture_lst)
@@ -239,7 +371,11 @@ class GlobalResourceRepository:
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]]
@@ -253,7 +389,6 @@ class Node:
if self.object:
if options.verbose >= 2:
print '\t' * level[0], self.name, self.object.type
-
level[0] += 1
for child in self.children:
@@ -288,183 +423,537 @@ class Node:
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, object_lst):
+ def __init__(self, parent, header, object,props):
+ global options
+
self.header = header
self.object = object
if object:
self.name = self.object.name
- self.matrix = self.object.getMatrix('localspace')
+ if not options.export_transform:
+ oloc = Blender.Mathutils.Vector(object.getLocation('worldspace'))
+ vec = Blender.Mathutils.Vector(oloc[0] * options.scale, oloc[1] * options.scale, oloc[2] * options.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)
-
- left_over = object_lst[:]
- self.child_objects = []
-
- # Add children to child list and remove from left_over list.
- # Pop is faster then remove
- i = len(object_lst)
- while i:
- i-=1
- if object_lst[i].parent == object:
- self.child_objects.append(left_over.pop(i))
-
# Spawn children.
- self.has_object_child = False # For Database class.
for child in self.child_objects:
- if child.type == 'Mesh':
- BlenderMesh(self, header, child, left_over)
- self.has_object_child = True
- else: # Treat all non meshes as emptys
- BlenderEmpty(self, header, child, left_over)
-
+ if(not child.restrictDisplay):
+ childprops = None
+ type = None
+ if not child.properties.has_key('FLT'):
+ if child.type == 'Empty':
+ if child.DupGroup:
+ childprops = FLTXRef.copy()
+ type = 63
+ else:
+ childprops = FLTGroup.copy()
+ type = 2
+ elif child.type == 'Mesh':
+ if self.header.childhash[child.name] or not child.parent:
+ childprops = FLTGroup.copy()
+ type = 2
+ else:
+ childprops = FLTObject.copy()
+ type = 4
+
+ else:
+ childprops = dict()
+ for prop in child.properties['FLT']:
+ childprops[prop] = child.properties['FLT'][prop]
+ type = child.properties['FLT']['type']
+
+ if type in self.childtypes and type in alltypes:
+ Newnode = FLTNode(self,header,child,childprops,type)
+ if child.type == 'Mesh':
+ self.header.mnodes.append(Newnode)
class FaceDesc:
def __init__(self):
self.vertex_index_lst = []
+ self.mface = None
self.texture_index = -1
self.material_index = -1
self.color_index = 127
-
-class BlenderMesh(Node):
- def blender_export(self):
- Node.blender_export(self)
-
- mesh = self.object.getData()
- mesh_hasuv = mesh.hasFaceUV()
- # Gather materials and textures.
- tex_index_lst = []
- mat_index_lst = []
- color_index_lst = []
- materials = mesh.getMaterials()
-
- if not materials:
- materials = [Blender.Material.New()]
-
- for mat in materials:
- # Gather Color.
- if options.use_face_color:
- color_index_lst.append(self.header.GRR.request_color_index(mat.getRGBCol()))
+ 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:
- color_index_lst.append(127) # white
- # Gather Texture.
- mtex_lst = mat.getTextures()
-
- index = -1
- mtex = mtex_lst[0] # Not doing multi-texturing at the moment.
- if mtex != None:
- tex = mtex_lst[0].tex
- if tex != None:
- image = tex.getImage()
- if image != None:
- filename = image.getFilename()
- index = self.header.GRR.request_texture_index(filename)
-
- tex_index_lst.append(index)
-
- # Gather Material
- mat_desc = MaterialDesc()
- mat_desc.name = mat.name
- mat_desc.alpha = mat.getAlpha()
- mat_desc.shininess = mat.getSpec() * 64.0 # 2.0 => 128.0
- if options.use_mat_color:
- mat_desc.diffuse = mat.getRGBCol()
+ 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:
- mat_desc.diffuse = [1.0, 1.0, 1.0]
+ curvert = curedge.v1
- mat_desc.specular = mat.getSpecCol()
- amb = mat.getAmb()
- mat_desc.ambient = [amb, amb, amb]
- emit = mat.getEmit()
- mat_desc.emissive = [emit, emit, emit]
+ 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)
- mat_index_lst.append(self.header.GRR.request_material_index(mat_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:
+ visited[vert] = True
+ loop = [vert]
+ othervert = edge_get_othervert(vert, disk[vert][0])
+ self.vertwalk(othervert, loop, disk, visited)
+ if len(loop) > 2: loops.append( ('Open', loop) )
+
+ for vert in wireverts:
+ if not visited[vert]:
+ visited[vert] = True
+ loop = [vert]
+ othervert = edge_get_othervert(vert,disk[vert][0])
+ self.vertwalk(othervert, loop, disk, visited)
+ if len(loop) > 2: loops.append( ('closed', loop) )
+
+ #now go through the loops and append.
+ for l in loops:
+ (type, 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 type == 'closed':
+ face_desc.renderstyle = 2
+ else:
+ face_desc.renderstyle = 3
+ face_desc.color_index = 227
+ self.face_lst.append(face_desc)
- # Faces described as lists of indices into the GRR's vertex_lst.
- for face in mesh.faces:
-
- face_v = face.v # Faster access
-
- # Create vertex description list for each face.
- if mesh_hasuv:
- vertex_lst = [VertexDesc(v.co, v.no, face.uv[i]) for i, v in enumerate(face_v)]
- else:
- vertex_lst = [VertexDesc(v.co, v.no) for i, v in enumerate(face_v)]
+ 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 = []
- for vert_desc in vertex_lst:
- index_lst.append(self.header.GRR.request_vertex_index(vert_desc))
-
+ 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)
- if face.materialIndex < len(materials):
- face_desc.color_index = color_index_lst[face.materialIndex]
- face_desc.texture_index = tex_index_lst[face.materialIndex]
- face_desc.material_index = mat_index_lst[face.materialIndex]
- else:
- if options.verbose >=1:
- print 'Warning: Missing material for material index. Materials will not be imported correctly. Fix by deleting abandoned material indices in Blender.'
+ #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
- self.face_lst.append(face_desc)
+ 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([])
- # Export double sided face as 2 faces with opposite orientations.
- if mesh_hasuv and face.mode & Blender.NMesh.FaceModes['TWOSIDE']:
- # Create vertex description list for each face. they have a face mode, so we know they have a UV too.
- vertex_lst = [VertexDesc(v.co, -v.no, face.uv[i]) for i, v in enumerate(face_v)]
- vertex_lst.reverse() # Reversing flips the face.
+ 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.export_transform:
+ vec = vert.co
+ vec = Blender.Mathutils.Vector(vec[0] * options.scale, vec[1] * options.scale, vec[2] * options.scale) #scale
+ vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))
- index_lst = []
- for vert_desc in vertex_lst:
- index_lst.append(self.header.GRR.request_vertex_index(vert_desc))
+ if options.scale != 1.0:
+ vert.co = vert.co * options.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.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.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.export_transform:
+ vec = vert.co
+ vec = Blender.Mathutils.Vector(vec[0] * options.scale, vec[1] * options.scale, vec[2] * options.scale) #scale
+ vert.co = Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))
- face_desc = FaceDesc()
- face_desc.vertex_index_lst = index_lst
- if face.materialIndex < len(materials):
- face_desc.color_index = color_index_lst[face.materialIndex]
- face_desc.texture_index = tex_index_lst[face.materialIndex]
- face_desc.material_index = mat_index_lst[face.materialIndex]
- else:
- if options.verbose >=1:
- print 'Error: No material for material index. Delete abandoned material indices in Blender.'
-
- self.face_lst.append(face_desc)
+ if options.scale != 1.0:
+ vert.co = vert.co * options.scale
+
+ flipped = self.object.getMatrix('worldspace').determinant()
+
+ if not options.export_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.export_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:
- face_name = self.header.GRR.new_face_name()
+ 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(0) # Draw type
+ 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(1) # Template
+ self.header.fw.write_char(alpha) # Template
self.header.fw.write_short(-1) # Detail tex pat index
self.header.fw.write_short(face_desc.texture_index) # Tex pattern index
self.header.fw.write_short(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_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(0x00000000) # Flags
+ 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(-1) # Packed color
- self.header.fw.write_uint(-1) # Packed alt color
+ 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
@@ -473,7 +962,24 @@ class BlenderMesh(Node):
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):
+ 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
@@ -484,72 +990,97 @@ class BlenderMesh(Node):
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):
- if self.open_flight_type == 'Object':
- self.header.fw.write_short(4) # Object opcode
- self.header.fw.write_ushort(28) # Length of record
- self.header.fw.write_string(self.name, 8) # ASCII ID
- self.header.fw.pad(16)
-
- self.write_longid(self.name)
+ 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.externalspath:
+ try:
+ exportdict['3t200!filename'] = os.path.join(options.externalspath,self.object.DupGroup.name+'.flt')
+ self.header.xrefnames.append(self.object.DupGroup.name)
+ except:
+ pass
+
+ for key in records[self.opcode]:
+ (type,length,propname) = records[self.opcode][key]
+ write_prop(self.header.fw,type,exportdict[propname],length)
+
+ if self.props.has_key('comment'):
+ self.write_comment(self.props['comment'])
+ self.write_longid(self.name) #fix this!
+
+ if options.export_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_push()
self.write_faces()
+ #self.write_pop()
- self.write_pop()
- else:
- self.header.fw.write_short(2) # Group opcode
- self.header.fw.write_ushort(44) # Length of record
- self.header.fw.write_string(self.name, 8) # ASCII ID
- self.header.fw.pad(32)
-
- self.write_longid(self.name)
-
- # Because a group can contain faces as well as children.
- self.write_push()
-
- self.write_faces()
-
- for child in self.children:
- child.write()
-
+ 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, object_lst):
- Node.__init__(self, parent, header, object, object_lst)
- self.face_lst = []
-
- if self.children:
- self.open_flight_type= 'Group'
- else: # Empty list.
- self.open_flight_type = 'Object'
-
-class BlenderEmpty(Node):
- def write(self):
- self.header.fw.write_short(2) # Group opcode
- self.header.fw.write_ushort(44) # Length of record
- self.header.fw.write_string(self.name, 8) # ASCII ID
- self.header.fw.pad(32)
-
- self.write_longid(self.name)
-
- self.write_matrix()
+ def __init__(self, parent, header, object,props,type):
+ self.opcode = type #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.children: # != []
- self.write_push()
-
- for child in self.children:
- child.write()
- self.write_pop()
+ 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):
@@ -568,8 +1099,19 @@ class Database(Node):
self.fw.write_int(0) # projection type, 0 = flat earth
self.fw.pad(30)
self.fw.write_short(1) # double precision
- self.fw.pad(140)
+ 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):
@@ -579,14 +1121,13 @@ class Database(Node):
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(0x2000) # Flags set to no color
+ self.fw.write_ushort(0) # Color name index
+ self.fw.write_short(0x20000000) # Flags
self.fw.write_double(desc.x)
self.fw.write_double(desc.y)
self.fw.write_double(desc.z)
@@ -595,16 +1136,19 @@ class Database(Node):
self.fw.write_float(desc.nz)
self.fw.write_float(desc.u)
self.fw.write_float(desc.v)
- self.fw.pad(12)
+ 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 in xrange(self.GRR.texture_count()):
+ 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(self.GRR.request_texture_filename(i), 200) # Filename
+ 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
@@ -641,13 +1185,17 @@ class Database(Node):
self.fw.write_short(32) # Color palette opcode.
self.fw.write_short(4228) # Length of record
self.fw.pad(128)
- count = self.GRR.color_count()
+ try:
+ cpalette = self.scene.properties['FLT']['Color Palette']
+ except:
+ cpalette = defaultp.pal
+ count = len(cpalette)
for i in xrange(count):
- col = self.GRR.request_max_color(i)
- self.fw.write_uchar(255) # alpha
- self.fw.write_uchar(col[2]) # b
- self.fw.write_uchar(col[1]) # g
- self.fw.write_uchar(col[0]) # r
+ 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):
@@ -657,66 +1205,429 @@ class Database(Node):
self.write_mat_pal()
self.write_col_pal()
- # Wrap everything in a group if it has an object child.
- if self.has_object_child:
- self.header.fw.write_short(2) # Group opcode
- self.header.fw.write_ushort(44) # Length of record
- self.header.fw.write_string('g1', 8) # ASCII ID
- self.header.fw.pad(32)
-
self.write_push()
-
- for child in self.children:
- child.write()
-
+
+ if options.flattenmesh:
+ self.mnodes.reverse()
+ for mnode in self.mnodes:
+ mnode.write_faces()
+ else:
+ 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.copy_textures:
+ filename = os.path.normpath(os.path.join(options.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.all_objects = list(scene.objects)
- self.GRR = GlobalResourceRepository()
+ 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)
- Node.__init__(self, None, self, None, self.all_objects)
+ self.GRR = GlobalResourceRepository()
+ Node.__init__(self, None, self, None,None)
-def fs_callback(filename):
- Blender.Window.WaitCursor(True)
-
- if Blender.sys.exists(filename):
- r = Blender.Draw.PupMenu('Overwrite ' + filename + '?%t|Yes|No')
- if r != 1:
- if options.verbose >= 1:
- print 'Export cancelled.'
- return
-
- time1 = Blender.sys.time() # Start timing
+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']:
+ (type,length,propname) = records['Image'][key]
+ write_prop(fw,type,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.externalspath:
+ fname = os.path.join(options.basepath,scene.name + '.flt')
+ else:
+ fname = os.path.join(options.externalspath,scene.name + '.flt')
- fw = FltOut(filename)
-
- db = Database(Blender.Scene.GetCurrent(), fw)
+ fw = FltOut(fname)
+ db = Database(scene,fw)
if options.verbose >= 1:
- print 'Pass 1: Exporting from Blender.\n'
-
- db.blender_export()
+ print 'Pass 1: Exporting ', scene.name,'.flt from Blender.\n'
+ xreflist = db.blender_export()
if options.verbose >= 1:
- print 'Pass 2: Writing %s\n' % filename
-
+ print 'Pass 2: Writing %s\n' % fname
db.write()
-
fw.close_file()
+
+ if options.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.copy_textures:
+ 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.write_attrib_files:
+ write_attribute_files()
+
+ if options.xapp:
+ cmd= options.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
+
+def setshadingangle(ID,val):
+ global options
+ options.shading_default = val
+def setBpath(fname):
+ global options
+ options.basepath = os.path.dirname(fname)
+ #update xref and textures path too....
+ if(os.path.exists(os.path.join(options.basepath,'externals'))):
+ options.externalspath = os.path.join(options.basepath,'externals')
+ if(os.path.exists(os.path.join(options.texturespath,'textures'))):
+ options.texturespath = os.path.join(options.basepath,'textures')
+def setexportscale(ID,val):
+ global options
+ options.scale = val
+
+def setTpath(fname):
+ global options
+ options.texturespath = os.path.dirname(fname)
+def setXpath(fname):
+ global options
+ options.externalspath = os.path.dirname(fname)
+def setXApath(fname):
+ global options
+ options.xappath = fname
+ d = dict()
+ d['xappath'] = options.xappath
+ Blender.Registry.SetKey('flt_export', d, 1)
+def event(evt, val):
+ x = 1
+def but_event(evt):
+ global options
+
+ global FLTExport
+ global FLTClose
+ global FLTLabel
+
+ global FLTBaseLabel
+ global FLTTextureLabel
+ global FLTXRefLabel
-if options.verbose >= 1:
- print '\nOpenFlight Exporter'
- print 'Version:', __version__
- print 'Author: Greg MacDonald'
- print __url__[2]
- print
+ 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
+
+
-fname = Blender.sys.makename(ext=".flt")
-Blender.Window.FileSelector(fs_callback, "Export OpenFlight v16.0", fname)
+ #choose base path for export
+ if evt == 4:
+ Blender.Window.FileSelector(setBpath, "DB Root", options.basepath)
+
+ #choose XREF path
+ if evt == 6:
+ Blender.Window.FileSelector(setXpath,"DB Externals",options.externalspath)
+
+ #choose texture path
+ if evt == 8:
+ Blender.Window.FileSelector(setTpath,"DB Textures",options.texturespath)
+
+ #export shading toggle
+ if evt == 9:
+ options.export_shading = FLTShadeExport.val
+ #export Textures
+ if evt == 11:
+ options.copy_textures = FLTCopyTex.val
+ #export XRefs
+ if evt == 13:
+ options.doxrefs = FLTDoXRef.val
+ #export Transforms
+ if evt == 12:
+ options.export_transform = FLTGlobal.val
+
+ if evt == 14:
+ options.xapp = FLTXAPP.val
+ if evt == 16:
+ Blender.Window.FileSelector(setXApath,"External Application",options.xappath)
+ if evt == 20:
+ options.write_attrib_files = FLTAttrib.val
+
+ #Export DB
+ if evt == 1:
+ dbexport()
+
+ #exit
+ if evt == 2:
+ Draw.Exit()
+
+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
+
+ #base path
+ FLTBaseLabel = Draw.Label("Base Path:",cx,cy,100,20)
+ FLTBaseString = Draw.String("",3,cx+100,cy,300,20,options.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.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.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.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.export_shading,"Turn on export of custom shading")
+ FLTShadDefault = Draw.Number("",10,cx + 120,cy,100,20,options.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.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.copy_textures,"Copy textures to folder indicated above")
+ cy = cy-40
+ FLTGlobal = Draw.Toggle("Export Transforms",12,cx,cy,220,20,options.export_transform,"If unchecked, Global coordinates are used (recommended)")
+ cy = cy-40
+ FLTDoXRef = Draw.Toggle("Export XRefs", 13,cx,cy,220,20,options.doxrefs,"Export External references (only those below current scene!)")
+ cy = cy-40
+ FLTXAPP = Draw.Toggle("Launch External App", 14, cx,cy,220,20,options.xapp,"Launch External Application on export")
+ cy = cy-40
+ FLTAttrib = Draw.Toggle("Write Attribute Files", 20, cx, cy, 220,20,options.write_attrib_files, "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
index 442c9728e91..4a9b86c45d2 100644
--- a/release/scripts/flt_filewalker.py
+++ b/release/scripts/flt_filewalker.py
@@ -17,6 +17,11 @@
# 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
@@ -199,7 +204,9 @@ class FltOut:
self.file.close()
def __init__(self, filename):
- self.file = open(filename, 'wb')
+ self.file = open(filename, 'wb')
+ self.filename = filename
+
class FileFinder:
def add_file_to_search_path(self, filename):
diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py
index ca0db650447..3ba118c0d18 100755..100644
--- a/release/scripts/flt_import.py
+++ b/release/scripts/flt_import.py
@@ -1,72 +1,26 @@
#!BPY
""" Registration info for Blender menus:
Name: 'OpenFlight (.flt)...'
-Blender: 238
+Blender: 245
Group: 'Import'
Tip: 'Import OpenFlight (.flt)'
"""
-__author__ = "Greg MacDonald, Campbell Barton"
-__version__ = "1.2 10/20/05"
+__author__ = "Greg MacDonald, Campbell Barton, Geoffrey Bantle"
+__version__ = "2.0 11/21/07"
__url__ = ("blender", "elysiun", "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.
-Run from "File->Import" menu.
-
-Options are available from Blender's "Scripts Config Editor," accessible through
-the "Scripts->System" menu from the scripts window.
-
-All global_prefs are toggle switches that let the user choose what is imported. Most
-are straight-forward, but one option could be a source of confusion. The
-"Diffuse Color From Face" option when set pulls the diffuse color from the face
-colors. Otherwise the diffuse color comes from the material. What may be
-confusing is that this global_prefs only works if the "Diffuse Color" option is set.
-
-New Features:<br>
-* Importer is 14 times faster.<br>
-* External triangle module is no longer required, but make sure the importer
-has a 3d View screen open while its running or triangulation won't work.<br>
-* Should be able to import all versions of flight files.
-
-Features:<br>
-* Heirarchy retained.<br>
-* First texture imported.<br>
-* Colors imported from face or material.<br>
-* LOD seperated out into different layers.<br>
-* Asks for location of unfound textures or external references.<br>
-* Searches Blender's texture directory in the user preferences panel.<br>
-* Triangles with more than 4 verts are triangulated if the Triangle python
-module is installed.<br>
-* Matrix transforms imported.<br>
-* External references to whole files are imported.
-
-Things To Be Aware Of:<br>
-* Each new color and face attribute creates a new material and there are only a maximum of 16
-materials per object.<br>
-* For triangulated faces, normals must be recomputed outward manually by typing
-CTRL+N in edit mode.<br>
-* You can change global_prefs only after an initial import.<br>
-* External references are imported as geometry and will be exported that way.<br>
-* A work around for not using the Triangle python module is to simply to
-triangulate in Creator before importing. This is only necessary if your
-model contains 5 or more vertices.<br>
-* You have to manually blend the material color with the texture color.
-
-What's Not Handled:<br>
-* Special texture repeating modes.<br>
-* Replications and instancing.<br>
-* Comment and attribute fields.<br>
-* Light points.<br>
-* Animations.<br>
-* External references to a node within a file.<br>
-* Multitexturing.<br>
-* Vetex colors.<br>
+Feature overview and more availible at:
+http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_flt
+
+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
+# 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
@@ -87,15 +41,33 @@ import os
import BPyMesh
import BPyImage
import flt_filewalker
+import flt_properties
+reload(flt_properties)
+from flt_properties import *
-Vector= Blender.Mathutils.Vector
+#Globals. Should Clean these up and minimize their usage.
-def col_to_gray(c):
- return 0.3*c[0] + 0.59*c[1] + 0.11*c[2]
+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
+
+Vector= Blender.Mathutils.Vector
+FLOAT_TOLERANCE = 0.01
+FF = flt_filewalker.FileFinder()
+current_layer = 0x01
global_prefs = dict()
-global_prefs['verbose']= 1
+global_prefs['verbose']= 4
global_prefs['get_texture'] = True
global_prefs['get_diffuse'] = True
global_prefs['get_specular'] = False
@@ -105,8 +77,41 @@ 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
+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, 100, 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.
@@ -185,16 +190,14 @@ class VertexDesc:
self.y = 0.0
self.z = 0.0
- ''' # IGNORE_NORMALS
+
self.nx = 0.0
- self.ny = 1.0
+ self.ny = 0.0
self.nz = 0.0
- '''
+
self.uv= Vector(0,0)
- self.r = 1.0
- self.g = 1.0
- self.b = 1.0
- self.a = 1.0
+ self.cindex = 127 #default/lowest
+ self.cnorm = False
class LightPointAppDesc:
def make_key(self):
@@ -222,7 +225,7 @@ class LightPointAppDesc:
self.props.update({'LOD scale': 0.0})
class GlobalResourceRepository:
- def request_lightpoint_app(self, desc):
+ def request_lightpoint_app(self, desc, scene):
match = self.light_point_app.get(desc.make_key())
if match:
@@ -231,7 +234,7 @@ class GlobalResourceRepository:
# Create empty and fill with properties.
name = desc.props['type'] + ': ' + desc.props['id']
object = Blender.Object.New('Empty', name)
- scene.link(object)
+ scene.objects.link(object)
object.Layers= current_layer
object.sel= 1
@@ -306,6 +309,9 @@ class GlobalResourceRepository:
return tex
def __init__(self):
+
+ #list of scenes xrefs belong to.
+ self.xrefs = dict()
# material
self.mat_dict = dict()
mat_lst = Blender.Material.Get()
@@ -341,108 +347,6 @@ class GlobalResourceRepository:
# light point
self.light_point_app = dict()
-# Globals
-GRR = GlobalResourceRepository()
-FF = flt_filewalker.FileFinder()
-scene = Blender.Scene.GetCurrent() # just hope they dont chenge scenes once the file selector pops up.
-current_layer = 0x01
-
-
-# Opcodes that indicate its time to return control to parent.
-throw_back_opcodes = [2, 73, 4, 11, 96, 14, 91, 98, 63]
-do_not_report_opcodes = [76, 78, 79, 80, 81, 82, 94, 83, 33, 112, 100, 101, 102, 97, 31, 103, 104, 117, 118, 120, 121, 124, 125]
-
-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'}
-
class Handler:
def in_throw_back_lst(self, opcode):
return opcode in self.throw_back_lst
@@ -487,11 +391,11 @@ class Node:
print '-', self.props['comment'],
print
-
+
for child in self.children:
child.blender_import()
-
- # Import comment.
+
+# Import comment.
# if self.props['comment'] != '':
# name = 'COMMENT: ' + self.props['id']
# t = Blender.Text.New(name)
@@ -568,8 +472,8 @@ class Node:
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 opcode_name[opcode], 'not handled'
+ 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
@@ -581,7 +485,19 @@ class Node:
def parse_comment(self):
self.props['comment'] = self.header.fw.read_string(self.header.fw.get_length()-4)
return True
-
+
+ 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()
@@ -647,20 +563,16 @@ class VertexPalette(Node):
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)
-
- color_index = self.header.fw.read_uint()
- v.r, v.g, v.b, v.a= self.header.get_color(color_index)
-
+ #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):
@@ -672,16 +584,10 @@ class VertexPalette(Node):
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()
- '''
- # Just to advance
- self.header.fw.read_float()
- self.header.fw.read_float()
- self.header.fw.read_float()
self.parse_vertex_post_common(v)
@@ -698,15 +604,10 @@ class VertexPalette(Node):
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()
- '''
- # Just to advance
- self.header.fw.read_float()
- self.header.fw.read_float()
- self.header.fw.read_float()
v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float()
@@ -721,89 +622,374 @@ class InterNode(Node):
def __init__(self):
self.object = None
self.mesh = None
- self.isMesh = False
+ self.hasMesh = False
self.faceLs= []
self.matrix = None
-
- def blender_import_my_faces(self):
+ self.vis = True
+ self.hasmtex = False
+ self.uvlayers = dict()
+ self.blayernames = dict()
+ self.subfacelevel = 0
+
+ mask = 2147483648
+ for i in xrange(7):
+ self.uvlayers[mask] = False
+ mask = mask / 2
+
+ def blender_import_my_faces(self):
+
# Add the verts onto the mesh
- mesh = self.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]
-
- mesh.verts.extend([blender_verts[i] for i in vert_list])
-
+ 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:
- material_index= flt_face.blen_mat_idx
- image= flt_face.blen_image
-
+ 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 <=4: # tri or quad
+ 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((material_index, image, uvs))
+ 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(mesh, mesh_face_indicies)
+ tri_ngons= ngon(self.mesh, mesh_face_indicies)
new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons])
- new_faces_props.extend( [ (material_index, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]) ) 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
-
- mesh.faces.extend(new_faces)
-
- try: mesh.faceUV= True
- except: pass
-
- for i, f in enumerate(mesh.faces):
- f.mat, f.image, f.uv= new_faces_props[i]
-
+ 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"]
+
+ #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):
+ 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.verts.delete(0) # remove the dummy vert
+ self.mesh.sel= 1
+ self.header.scene.update(1) #slow!
+ self.mesh.remDoubles(0.0001)
+
+ 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):
-# name = self.props['type'] + ': ' + self.props['id']
+ if self.vis and self.parent:
+ self.vis = self.parent.vis
name = self.props['id']
- if self.isMesh:
- self.object = Blender.Object.New('Mesh', name)
- #self.mesh = self.object.getData()
+
+ if self.hasMesh:
self.mesh = Blender.Mesh.New()
- self.mesh.verts.extend( Vector() ) # DUMMYVERT
- self.object.link(self.mesh)
+ 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 = Blender.Object.New('Empty', name)
+ self.object = self.header.scene.objects.new('Empty')
- if self.parent:
- self.parent.object.makeParent([self.object])
+ self.object.name = name
+ self.header.group.objects.link(self.object)
- scene.link(self.object)
- self.object.Layer = current_layer
- self.object.sel = 1
+ #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.parent and self.parent.object and (self.header.scene == self.parent.header.scene):
+ self.parent.object.makeParent([self.object])
+
+ 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:
+ 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
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+
Node.blender_import(self) # Attach faces to self.faceLs
- if self.isMesh:
+ if self.hasMesh:
# Add all my faces into the mesh at once
self.blender_import_my_faces()
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- # Attach properties
- #for name, value in self.props.items():
- # self.object.addProperty(name, value)
-
+
def parse_face(self):
- child = Face(self)
+ child = Face(self, self.subfacelevel)
child.parse()
return True
@@ -838,6 +1024,11 @@ class InterNode(Node):
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()
@@ -857,32 +1048,42 @@ class InterNode(Node):
m[i].append(f)
self.matrix = Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
-EDGE_FGON= Blender.Mesh.EdgeFlags['FGON']
-FACE_TEX= Blender.Mesh.FaceModes['TEX']
+ 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):
+ def __init__(self, parent,subfacelevel):
Node.__init__(self, parent, parent.header)
self.root_handler.set_handler({31: self.parse_comment,
- 10: self.parse_push})
+ 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})
+ 11: self.parse_pop,
+ 53: self.parse_uvlist})
if parent:
- parent.isMesh = True
+ parent.hasMesh = True
- self.indices = list() # face verts here
+ 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.fromkeys(['ir color', 'priority',
- 'draw type', 'texture white', 'template billboard',
- 'smc', 'fid', 'ir material', 'lod generation control',
- 'flags', 'light mode'])
-
- self.header.fw.read_ahead(8) # face id
+ 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()
@@ -919,186 +1120,14 @@ class Face(Node):
self.alt_color_index = self.header.fw.read_uint()
#self.header.fw.read_ahead(2)
#self.shader_index = self.header.fw.read_short()
-
-
- """
- def blender_import_face(self, material_index, image):
-
-
- mesh = self.parent.mesh
- face_len= len(self.indices)
-
- mesh_vert_len_orig= len(mesh.verts)
- mesh.verts.extend([ self.header.vert_pal.blender_verts[i] for i in self.indices])
-
- # Exception for an edge
- if face_len==2:
- mesh.edges.extend((mesh.verts[-1], mesh.verts[-2]))
- return
-
-
- mesh_face_indicies = range(mesh_vert_len_orig, mesh_vert_len_orig+face_len)
-
- #print mesh_face_indicies , 'mesh_face_indicies '
-
- # First we need to triangulate NGONS
- if face_len>4:
- tri_indicies = [[i+mesh_vert_len_orig for i in t] for t in BPyMesh.ngon(mesh, mesh_face_indicies) ] # use range because the verts are in order.
- else:
- tri_indicies= [mesh_face_indicies] # can be a quad but thats ok
-
- # Extend face or ngon
-
- mesh.faces.extend(tri_indicies)
- #print mesh.faces, 'mesh.faces'
- mesh.faceUV= True
-
- # Now set UVs
- for i in xrange(len(mesh.faces)-len(tri_indicies), len(mesh.faces)):
- f= mesh.faces[i]
- f_v= f.v
- for j, uv in enumerate(f.uv):
- vertex_index_flt= self.indices[f_v[j].index - mesh_vert_len_orig]
-
- vert_desc = self.header.vert_pal.vert_desc_lst[vertex_index_flt]
- uv.x, uv.y= vert_desc.u, vert_desc.v
-
- # Only a bug in 2.42, fixed in cvs
- for c in f.col:
- c.r=c.g=c.b= 255
-
- f.mat = material_index
- if image:
- f.image = image
- else:
- f.mode &= ~FACE_TEX
-
- # FGon
-
- if face_len>4:
- # Add edges we know are not fgon
- end_index= len(mesh.verts)
- start_index= end_index - len(self.indices)
- edge_dict= dict([ ((i, i+1), None) for i in xrange(start_index, end_index-1)])
- edge_dict[(start_index, end_index)]= None # wish this was a set
-
- fgon_edges= {}
- for tri in tri_indicies:
- for i in (0,1,2):
- i1= tri[i]
- i2= tri[i-1]
-
- # Sort
- if i1>i2:
- i1,i2= i2,i1
-
- if not edge_dict.has_key( (i1,i2) ): # if this works its an edge vert
- fgon_edges[i1,i2]= None
-
-
- # Now set fgon flags
- for ed in mesh.edges:
- i1= ed.v1.index
- i2= ed.v2.index
- if i1>i2:
- i1,i2= i2,i1
-
- if fgon_edges.has_key( (i1,i2) ):
- # This is an edge tagged for fgonning?
- fgon_edges[i1, i2]
- ed.flag |= EDGE_FGON
- del fgon_edges[i1, i2] # make later searches faster?
-
- if not fgon_edges:
- break
- """
-
+
def parse_comment(self):
self.comment = self.header.fw.read_string(self.header.fw.get_length()-4)
return True
- # returns a tuple (material, image) where material is the blender material and
- # image is the blender image or None.
- def create_blender_material(self):
- # Create face material.
- mat_desc = MaterialDesc()
-
- if self.mat_index != -1:
- if not self.mat_index in self.header.mat_desc_pal:
- if global_prefs['verbose'] >= 1:
- #print 'Warning: Material index', self.mat_index, 'not in material palette.'
- pass
- else:
- mat_pal_desc = self.header.mat_desc_pal[self.mat_index]
- mat_desc.alpha = mat_pal_desc.alpha * self.alpha # combine face and mat alphas
- mat_desc.ambient = mat_pal_desc.ambient
- mat_desc.diffuse = mat_pal_desc.diffuse
- mat_desc.specular = mat_pal_desc.specular
- mat_desc.emissive = mat_pal_desc.emissive
- mat_desc.shininess = mat_pal_desc.shininess
- else:
- # if no material get alpha from just face.
- mat_desc.alpha = self.alpha
-
- # Color.
- if global_prefs['color_from_face']:
- color = None
- if not self.props['flags'] & 0x40000000:
- if self.props['flags'] & 0x10000000: # packed color
- color = self.packed_color
- else:
- color = self.header.get_color(self.color_index)
-
- if color:
- r = float(color[0])/255.0
- g = float(color[1])/255.0
- b = float(color[2])/255.0
- mat_desc.diffuse = [r, g, b]
-
- # Texture
- image = None
- if self.tex_index != -1 and self.tex_index in self.header.bl_tex_pal:
- mat_desc.tex0 = self.header.bl_tex_pal[self.tex_index]
- if mat_desc.tex0:
- mat_desc.name = FF.strip_path(self.header.tex_pal[self.tex_index])
- image = mat_desc.tex0.image
-
- # OpenFlight Face Attributes
- mat_desc.face_props = self.props
-
- # Get material.
- mat = GRR.request_mat(mat_desc)
-
- # Add material to mesh.
- mesh = self.parent.mesh
-
- # Return where it is in the mesh for faces.
- mesh_materials= mesh.materials
-
- material_index= -1
- for i,m in enumerate(mesh_materials):
- if m.name==mat.name:
- material_index= i
- break
-
- if material_index==-1:
- material_index= len(mesh_materials)
- if material_index==16:
- material_index= 15
- if global_prefs['verbose'] >= 1:
- print 'Warning: Too many materials per mesh object. Only a maximum of 16 ' + \
- 'allowed. Using 16th material instead.'
-
- else:
- mesh_materials.append(mat)
- mesh.materials= mesh_materials
-
- return (material_index, image)
-
-
def blender_import(self):
vert_count = len(self.indices)
- if vert_count < 3:
+ if vert_count < 1:
if global_prefs['verbose'] >= 2:
print 'Warning: Ignoring face with no vertices.'
return
@@ -1106,18 +1135,21 @@ class Face(Node):
# Assign material and image
self.parent.faceLs.append(self)
- self.blen_mat_idx, self.blen_image= self.create_blender_material()
-
-
-
+ #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.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
@@ -1138,8 +1170,49 @@ class Face(Node):
' 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)
@@ -1152,15 +1225,15 @@ class Object(InterNode):
self.root_handler.set_throw_back_lst(throw_back_opcodes)
self.child_handler.set_handler({5: self.parse_face,
- #130: self.parse_indexed_light_point,
- #111: self.parse_inline_light_point,
+ 19: self.parse_subpush,
+ 20: self.parse_subpop,
+ 111: self.parse_inline_light_point,
10: self.parse_push,
11: self.parse_pop})
- self.props['type'] = 'Object'
- self.props['id'] = self.header.fw.read_string(8)
-
-
+ self.props = dict()
+ self.props['comment'] = ''
+ self.parse_record()
class Group(InterNode):
def __init__(self, parent):
@@ -1174,15 +1247,16 @@ class Group(InterNode):
self.root_handler.set_throw_back_lst(throw_back_opcodes)
self.child_handler.set_handler({5: self.parse_face,
- #130: self.parse_indexed_light_point,
- #111: self.parse_inline_light_point,
+ 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_unhandled,
+ 14: self.parse_dof,
91: self.parse_unhandled,
98: self.parse_unhandled,
63: self.parse_xref})
@@ -1190,20 +1264,48 @@ class Group(InterNode):
'special2', 'significance', 'layer code', 'loop count',
'loop duration', 'last frame duration'])
- self.props['type'] = 'Group'
self.props['comment'] = ''
- self.props['id'] = self.header.fw.read_string(8)
- self.props['priority'] = self.header.fw.read_short()
- self.header.fw.read_ahead(2)
- self.props['flags'] = self.header.fw.read_int()
- self.props['special1'] = self.header.fw.read_short()
- self.props['special2'] = self.header.fw.read_short()
- self.props['significance'] = self.header.fw.read_short()
- self.props['layer code'] = self.header.fw.read_char()
- self.header.fw.read_ahead(5)
- self.props['loop count'] = self.header.fw.read_int()
- self.props['loop duration'] = self.header.fw.read_float()
- self.props['last frame duration'] = self.header.fw.read_float()
+ 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})
+ 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.props = dict()
+ self.props['comment'] = ''
+ self.parse_record()
+
class XRef(InterNode):
def parse(self):
@@ -1214,31 +1316,66 @@ class XRef(InterNode):
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)
- xref_filename = self.header.fw.read_string(200)
- filename = FF.find(xref_filename)
+ self.props = dict()
+ self.props['comment'] = ''
+ self.parse_record()
- self.props['type'] = 'XRef'
+ xref_filename = self.props['3t200!filename']
+ self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(xref_filename))[0] #this is really wrong as well....
- if filename != None:
- self.xref = Database(filename, self)
- self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(filename))[0]
+ if global_prefs['doxrefs'] and os.path.exists(xref_filename) and not self.header.grr.xrefs.has_key(xref_filename):
+ self.xref = Database(xref_filename, self.header.grr, self)
+ self.header.grr.xrefs[xref_filename] = self.xref
else:
self.xref = None
- self.props['id'] = 'X: broken'
+
+
+ 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])
+
+ #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
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+ Node.blender_import(self)
+
+
class LOD(InterNode):
def blender_import(self):
- self.move_to_next_layer()
+ #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,
@@ -1246,18 +1383,20 @@ class LOD(InterNode):
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_unhandled, # DOF
+ 14: self.parse_dof, # DOF
91: self.parse_unhandled, # sound
98: self.parse_unhandled, # clip
63: self.parse_xref})
- self.props['type'] = 'LOD'
- self.props['id'] = self.header.fw.read_string(8)
+ self.props = dict()
+ self.props['comment'] = ''
+ self.parse_record()
class InlineLightPoint(InterNode):
def __init__(self, parent):
@@ -1274,119 +1413,49 @@ class InlineLightPoint(InterNode):
11: self.parse_pop})
self.indices = list()
-
- self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
- self.app_props = dict()
-
+ self.props = dict()
self.props['comment'] = ''
- self.props['type'] = 'Light Point'
- self.props['id'] = self.header.fw.read_string(8)
-
- self.app_props.update({'smc': self.header.fw.read_short()})
- self.app_props.update({'fid': self.header.fw.read_short()})
- self.app_props.update({'back color: a': self.header.fw.read_uchar()})
- self.app_props.update({'back color: b': self.header.fw.read_uchar()})
- self.app_props.update({'back color: g': self.header.fw.read_uchar()})
- self.app_props.update({'back color: r': self.header.fw.read_uchar()})
- self.app_props.update({'display mode': self.header.fw.read_int()})
- self.app_props.update({'intensity': self.header.fw.read_float()})
- self.app_props.update({'back intensity': self.header.fw.read_float()})
- self.app_props.update({'minimum defocus': self.header.fw.read_float()})
- self.app_props.update({'maximum defocus': self.header.fw.read_float()})
- self.app_props.update({'fading mode': self.header.fw.read_int()})
- self.app_props.update({'fog punch mode': self.header.fw.read_int()})
- self.app_props.update({'directional mode': self.header.fw.read_int()})
- self.app_props.update({'range mode': self.header.fw.read_int()})
- self.app_props.update({'min pixel size': self.header.fw.read_float()})
- self.app_props.update({'max pixel size': self.header.fw.read_float()})
- self.app_props.update({'actual size': self.header.fw.read_float()})
- self.app_props.update({'trans falloff pixel size': self.header.fw.read_float()})
- self.app_props.update({'trans falloff exponent': self.header.fw.read_float()})
- self.app_props.update({'trans falloff scalar': self.header.fw.read_float()})
- self.app_props.update({'trans falloff clamp': self.header.fw.read_float()})
- self.app_props.update({'fog scalar': self.header.fw.read_float()})
- self.app_props.update({'fog intensity': self.header.fw.read_float()})
- self.app_props.update({'size threshold': self.header.fw.read_float()})
- self.app_props.update({'directionality': self.header.fw.read_int()})
- self.app_props.update({'horizontal lobe angle': self.header.fw.read_float()})
- self.app_props.update({'vertical lobe angle': self.header.fw.read_float()})
- self.app_props.update({'lobe roll angle': self.header.fw.read_float()})
- self.app_props.update({'dir falloff exponent': self.header.fw.read_float()})
- self.app_props.update({'dir ambient intensity': self.header.fw.read_float()})
- self.header.fw.read_ahead(12) # Animation settings.
- self.app_props.update({'significance': self.header.fw.read_float()})
- self.props['draw order'] = self.header.fw.read_int()
- self.app_props.update({'flags': self.header.fw.read_int()})
- #self.fw.read_ahead(12) # More animation settings.
-
- # 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 = GRR.request_lightpoint_app(app_desc)
+ self.parse_record()
- 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 = '%s: %s' % (self.props['type'], self.props['id'])
+
- name_to_indices = self.group_points(self.app_props)
+ 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.parent and self.parent.object and self.header.scene == self.parent.header.scene:
+ self.parent.object.makeParent([self.object])
- for app_name, indices in name_to_indices.iteritems():
- self.object = Blender.Object.New('Mesh', name)
- #self.mesh = self.object.getData()
- self.mesh= Blender.Mesh.New()
- self.mesh.verts.extend( Vector() ) # DUMMYVERT
- self.object.link(self.mesh)
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
- if self.parent:
- self.parent.object.makeParent([self.object])
+ 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()
- for i in indices:
- vert = self.header.vert_pal.blender_verts[i]
- self.mesh.verts.append(vert)
-
- scene.link(self.object)
- self.object.Layer = current_layer
- self.object.sel= 1
-
- 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
@@ -1432,7 +1501,7 @@ class IndexedLightPoint(InterNode):
app_desc.props.update({'b': vert_desc.b})
app_desc.props.update({'a': vert_desc.a})
- app_name = GRR.request_lightpoint_app(app_desc)
+ 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)
@@ -1448,7 +1517,6 @@ class IndexedLightPoint(InterNode):
for app_name, indices in name_to_indices.iteritems():
self.object = Blender.Object.New('Mesh', name)
- #self.mesh = self.object.getData()
self.mesh= Blender.Mesh.New()
self.mesh.verts.extend( Vector() ) # DUMMYVERT
self.object.link(self.mesh)
@@ -1460,7 +1528,7 @@ class IndexedLightPoint(InterNode):
vert = self.header.vert_pal.blender_verts[i]
self.mesh.verts.append(vert)
- scene.link(self.object)
+ self.header.scene.objects.link(self.object)
self.object.Layer = current_layer
@@ -1543,7 +1611,7 @@ class Unhandled(InterNode):
10: self.parse_push,
11: self.parse_pop,
96: self.parse_unhandled, # switch
- 14: self.parse_unhandled, # DOF
+ 14: self.parse_dof, # DOF
91: self.parse_unhandled, # sound
98: self.parse_unhandled, # clip
63: self.parse_xref})
@@ -1552,30 +1620,31 @@ class Unhandled(InterNode):
class Database(InterNode):
def blender_import(self):
- self.tex_pal = dict(self.tex_pal_lst)
- del self.tex_pal_lst
-
- # Setup Textures
- bl_tex_pal_lst = list()
- for i in self.tex_pal.iterkeys():
- path_filename = FF.find(self.tex_pal[i])
+ for key in self.tex_pal.keys():
+ path_filename= FF.find(self.tex_pal[key][0])
if path_filename != None:
- img = GRR.request_image(path_filename)
+ img = self.grr.request_image(path_filename)
if img:
- tex = GRR.request_texture(img)
- tex.setName(FF.strip_path(self.tex_pal[i]))
- bl_tex_pal_lst.append( (i, tex) )
- else:
- bl_tex_pal_lst.append( (i, None) )
+ self.tex_pal[key][1] = img
elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to find', self.tex_pal[i]
-
- self.bl_tex_pal = dict(bl_tex_pal_lst)
-
- # Setup Materials
- self.mat_desc_pal = dict(self.mat_desc_pal_lst)
-
- InterNode.blender_import(self)
+ 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
+
+ #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()
@@ -1696,9 +1765,10 @@ class Database(InterNode):
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)
@@ -1707,7 +1777,7 @@ class Database(InterNode):
a = int(brightest[3])
color = [r, g, b, a]
-
+
return color
def parse_color_palette(self):
@@ -1728,15 +1798,56 @@ class Database(InterNode):
def parse_texture_palette(self):
name = self.fw.read_string(200)
index = self.fw.read_int()
- self.tex_pal_lst.append( (index, name) )
+ self.tex_pal[index]= [name, None]
return True
-
- def __init__(self, filename, parent=None):
+
+ 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
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)
@@ -1753,23 +1864,26 @@ class Database(InterNode):
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,
+ 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_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.tex_pal_lst = list()
+ #self.bl_tex_pal = dict()
self.col_pal = list()
self.mat_desc_pal_lst = list()
self.mat_desc_pal = dict()
@@ -1778,7 +1892,70 @@ class Database(InterNode):
'sw lon', 'ne lat', 'ne lon', 'origin lat', 'origin lon', 'lambert lat1',
'lambert lat2', 'ellipsoid model', 'utm zone', 'radius', 'major axis', 'minor axis'])
-def select_file(filename):
+
+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 and location[1] != 0.0 and 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)
@@ -1801,13 +1978,12 @@ def select_file(filename):
global_prefs['get_ambient'] = False
global_prefs['get_shininess'] = True
global_prefs['color_from_face'] = True
+ global_prefs['log to blender'] = True
+
+
- # Start loading the file,
- # first set the context
Blender.Window.WaitCursor(True)
Blender.Window.EditMode(0)
- for ob in scene.objects:
- ob.sel=0
FF.add_file_to_search_path(filename)
@@ -1817,7 +1993,7 @@ def select_file(filename):
print
load_time = Blender.sys.time()
- db = Database(filename)
+ db = Database(filename,grr)
db.parse()
load_time = Blender.sys.time() - load_time
@@ -1828,23 +2004,15 @@ def select_file(filename):
import_time = Blender.sys.time()
db.blender_import()
- import_time = Blender.sys.time() - import_time
-
- Blender.Window.ViewLayer(range(1,21))
-
- # FIX UP AFTER DUMMY VERT AND REMOVE DOUBLES
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
- for ob in scene.objects.context:
- if ob.type=='Mesh':
- me=ob.getData(mesh=1)
- me.verts.delete(0) # remove the dummy vert
- me.sel= 1
- me.remDoubles(0.0001)
+ if global_prefs['attrib']:
+ print "reading attribute files"
+ db.read_attribute_files()
+ Blender.Window.ViewLayer(range(1,21))
- Blender.Window.RedrawAll()
-
+ update_scene(db.scene,[])
+ import_time = Blender.sys.time() - import_time
if global_prefs['verbose'] >= 1:
print 'Done.'
print
@@ -1854,37 +2022,112 @@ def select_file(filename):
Blender.Window.WaitCursor(False)
+def setimportscale(ID,val):
+ global global_prefs
+ global_prefs['scale'] = val
+def setBpath(fname):
+ global_prefs['fltfile'] = fname
-if global_prefs['verbose'] >= 1:
- print
- print 'OpenFlight Importer'
- print 'Version:', __version__
- print 'Author: Greg MacDonald'
- print __url__[2]
- print
+def event(evt,val):
+ pass
+def but_event(evt):
+
+ global FLTBaseLabel
+ global FLTBaseString
+ global FLTBaseChooser
+ global FLTExport
+ global FLTClose
+
+ global FLTDoXRef
+ global FLTShadeImport
+ global FLTAttrib
+
+ #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()
+ select_file(global_prefs['fltfile'], GRR)
+ #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()
+
-if __name__ == '__main__':
- Blender.Window.FileSelector(select_file, "Import OpenFlight", "*.flt")
- #select_file('/fe/flt/helnwsflt/helnws.flt')
- #select_file('/fe/flt/Container_006.flt')
- #select_file('/fe/flt/NaplesORIGINALmesh.flt')
- #select_file('/Anti_tank_D30.flt')
- #select_file('/metavr/file_examples/flt/cherrypoint/CherryPoint_liter_runway.flt')
+
+from Blender.BGL import *
+from Blender import Draw
+def gui():
+
+ global FLTBaseLabel
+ global FLTBaseString
+ global FLTBaseChooser
-"""
-TIME= Blender.sys.time()
-import os
-PATH= 'c:\\flt_test'
-for FNAME in os.listdir(PATH):
- if FNAME.lower().endswith('.flt'):
- FPATH= os.path.join(PATH, FNAME)
- newScn= Blender.Scene.New(FNAME)
- newScn.makeCurrent()
- scene= newScn
- select_file(FPATH)
-
-print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-"""
- \ No newline at end of file
+ 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_palettemanager.py b/release/scripts/flt_palettemanager.py
new file mode 100644
index 00000000000..c641a0a4f08
--- /dev/null
+++ b/release/scripts/flt_palettemanager.py
@@ -0,0 +1,388 @@
+#!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', 'elysiun')
+
+__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 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
+import flt_defaultp as defaultp
+from flt_properties import *
+
+
+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 = ""
+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.CKEY:
+
+ 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.VKEY:
+ 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.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:
+ 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
+
+ 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(xpos-6,grady-1)
+ glVertex2i(xpos+6,grady-1)
+ glVertex2i(xpos+6,grady+palette_size+1)
+ glVertex2i(xpos-6,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()
+
+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)
+
diff --git a/release/scripts/flt_properties.py b/release/scripts/flt_properties.py
new file mode 100644
index 00000000000..2c9e9d7667b
--- /dev/null
+++ b/release/scripts/flt_properties.py
@@ -0,0 +1,619 @@
+#!BPY
+# 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':
+ fw.write_uint(value)
+ 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
+
+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,
+ '6d!switch out' : 0,
+ '7s!sfx ID1' : 0,
+ '8s!sfx ID2' : 0,
+ '9I!flags' : 0,
+ '10d!X co' : 0,
+ '11d!Y co' : 0,
+ '12d!Z co' : 0,
+ '13d!Transition' : 0,
+ '14d!Sig Size' : 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' : 255,
+ '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' : 0,
+ '36f!anim phase' : 0,
+ '37f!anim enabled' : 0,
+ '38f!significance' : 0.0,
+ '39i!draw order' : 0,
+ '40I!flags' : 813875616,
+ '41f!roti' : 0,
+ '42f!rotj' : 0,
+ '43f!rotk' : 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,
+ '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
new file mode 100644
index 00000000000..213fac1bb3c
--- /dev/null
+++ b/release/scripts/flt_toolbar.py
@@ -0,0 +1,654 @@
+#!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', 'elysiun')
+
+__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
+}
+
+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
+
+def update_state():
+ state = dict()
+ state["activeScene"] = Blender.Scene.getCurrent()
+ state["activeObject"] = state["activeScene"].getActiveObject()
+ 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 update_all():
+ 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:
+ 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',state["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
+
+
+#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:
+ 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()
+ 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 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")
+ draw_postcommon(origx, origy,y)
+
+def gui():
+ #draw the propsheet/toolbox.
+ psheety = 280
+ #psheetx = psheety + 10
+ draw_propsheet(0,psheety)
+Draw.Register(gui,event,but_event)
+ \ No newline at end of file
diff --git a/release/scripts/image_auto_layout.py b/release/scripts/image_auto_layout.py
index a4a9e82955f..19ee396c3b1 100644
--- a/release/scripts/image_auto_layout.py
+++ b/release/scripts/image_auto_layout.py
@@ -42,7 +42,6 @@ This is usefull for game models where 1 image is faster then many, and saves the
# Function to find all the images we use
import Blender as B
-import boxpack2d
from Blender.Mathutils import Vector, RotationMatrix
from Blender.Scene import Render
import BPyMathutils
@@ -162,9 +161,10 @@ class faceGroup(object):
self.ymin= ymin - (PREF_IMAGE_MARGIN/size[1])
self.box_pack=[\
- image.name,\
+ 0.0, 0.0,\
size[0]*(self.xmax - self.xmin),\
- size[1]*(self.ymax - self.ymin)]
+ size[1]*(self.ymax - self.ymin),\
+ image.name]
'''
# default.
@@ -194,8 +194,8 @@ class faceGroup(object):
# 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[1]/width
- offset_y= self.box_pack[2]/height
+ offset_x= self.box_pack[0]/width
+ offset_y= self.box_pack[1]/height
for f in self.faces:
for uv in f.uv:
@@ -204,7 +204,11 @@ class faceGroup(object):
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'''
+ '''
+ Main packing function
+
+ All meshes from mesh_list must have faceUV else this function will fail.
+ '''
face_groups= {}
for me in mesh_list:
@@ -224,11 +228,11 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR
face_groups[image.name]= faceGroup(mesh_list, image, size, PREF_IMAGE_MARGIN)
if not face_groups:
- B.Draw.PupMenu('No Images found in mesh. aborting.')
+ 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 using 2 or more images.')
+ B.Draw.PupMenu('Only 1 image found|Select a mesh(es) using 2 or more images.')
return
'''
@@ -286,7 +290,7 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR
render_cam_ob= B.Object.New('Camera')
render_cam_ob.link(render_cam_data)
render_scn.link(render_cam_ob)
- render_scn.setCurrentCamera(render_cam_ob)
+ render_scn.objects.camera = render_cam_ob
render_cam_data.type= 'ortho'
render_cam_data.scale= 1.0
@@ -299,8 +303,7 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR
# List to send to to boxpack function.
boxes2Pack= [ fg.box_pack for fg in face_groups.itervalues()]
-
- packWidth, packHeight, packedLs = boxpack2d.boxPackIter(boxes2Pack)
+ packWidth, packHeight = B.Geometry.BoxPack2D(boxes2Pack)
if PREF_KEEP_ASPECT:
packWidth= packHeight= max(packWidth, packHeight)
@@ -308,17 +311,17 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR
# packedLs is a list of [(anyUniqueID, left, bottom, width, height)...]
# Re assign the face groups boxes to the face_group.
- for box in packedLs:
- face_groups[ box[0] ].box_pack= box # box[0] is the ID (image name)
+ 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[1] / packWidth
- _y= fg.box_pack[2] / packHeight
- _w= fg.box_pack[3] / packWidth
- _h= fg.box_pack[4] / packHeight
+ _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),\
@@ -374,10 +377,11 @@ def consolidate_mesh_images(mesh_list, scn, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PR
for fg in face_groups.itervalues():
fg.move2packed(packWidth, packHeight)
-
+
scn.makeCurrent()
- B.Scene.Unlink(render_scn)
render_me.verts= None # free a tiny amount of memory.
+ B.Scene.Unlink(render_scn)
+ target_image.makeCurrent()
def main():
@@ -422,10 +426,23 @@ def main():
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.
- mesh_list= dict([(me.name, me) for me in mesh_list]).values()
+
+ 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()
diff --git a/release/scripts/image_billboard.py b/release/scripts/image_billboard.py
index 2ca1d9d46e4..54f0f7c5c55 100644
--- a/release/scripts/image_billboard.py
+++ b/release/scripts/image_billboard.py
@@ -46,47 +46,37 @@ Usage
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-import Blender as B
+import Blender
+from Blender import Mesh, Material, Draw
import BPyMathutils
-# reload(BPyMathutils)
+import bpy
import BPyRender
-reload(BPyRender)
-import boxpack2d
-# reload(boxpack2d) # for developing.
from Blender.Scene import Render
+# reload(BPyRender)
+# reload(BPyMathutils)
+
import os
-Vector= B.Mathutils.Vector
+Vector= Blender.Mathutils.Vector
def alpha_mat(image):
# returns a material useable for
- mtl= B.Material.New()
- mtl.mode |= (B.Material.Modes.SHADELESS | B.Material.Modes.ZTRANSP | B.Material.Modes.FULLOSA )
- mtl.alpha= 0.0 # so image sets the alpha
-
- tex= B.Texture.New()
- tex.type= B.Texture.Types.IMAGE
- image.antialias = True
- tex.setImageFlags('InterPol', 'UseAlpha')
- tex.setExtend('Clip')
- tex.image= image
-
- mtl.setTexture(0, tex, B.Texture.TexCo.UV, B.Texture.MapTo.COL | B.Texture.MapTo.ALPHA)
-
+ 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= B.Draw.Create(512)
-PREF_TILE_RES= B.Draw.Create(256)
-PREF_AA = B.Draw.Create(1)
-PREF_ALPHA= B.Draw.Create(1)
-PREF_Z_OFFSET = B.Draw.Create(10.0)
-PREF_IMG_PACK= B.Draw.Create(1)
+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):
- B.Window.WaitCursor(1)
+ Blender.Window.WaitCursor(1)
# remove png, add it later
PREF_IMAGE_PATH= PREF_IMAGE_PATH.replace('.png', '')
@@ -94,7 +84,7 @@ def save_billboard(PREF_IMAGE_PATH):
me_ob = GLOBALS['me_ob']
me_data = GLOBALS['me_data']
- time= B.sys.time()
+ time= Blender.sys.time()
me_mat= me_ob.matrixWorld
@@ -102,9 +92,10 @@ def save_billboard(PREF_IMAGE_PATH):
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]
@@ -117,61 +108,64 @@ def save_billboard(PREF_IMAGE_PATH):
else:
rot90= False
-
- #plane.reverse()
- no= B.Mathutils.QuadNormal(*plane)
+ 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.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 |= B.Mesh.FaceModes.TEX
+ f.mode |= Mesh.FaceModes.TEX
f.image = img
- f.uv=Vector(0,1), Vector(0,0), Vector(1,0), Vector(1,1)
if PREF_ALPHA.val:
- f.transp |= B.Mesh.FaceTranspModes.ALPHA
+ 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, rot90) )
- boxes2Pack.append( (i, h, w) )
+ 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)
- packWidth, packHeight, packedLs = boxpack2d.boxPackIter(boxes2Pack)
render_obs= []
+ render_mat= alpha_mat(img)
+
# Add geometry to the mesh
- for box in packedLs:
- i= box[0]
+ for box in boxes2Pack:
+ i= box[4]
- orig_f, img, rot90= face_data[i]
+ orig_f, img= face_data[i]
# New Mesh and Object
- render_mat= alpha_mat(img)
- render_me= B.Mesh.New()
- render_ob= B.Object.New('Mesh')
+ 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[1] / packWidth
- _y= box[2] / packHeight
- _w= box[3] / packWidth
- _h= box[4] / packHeight
+ _x= box[0] / packWidth
+ _y= box[1] / packHeight
+ _w= box[2] / packWidth
+ _h= box[3] / packHeight
render_me.verts.extend([\
@@ -180,65 +174,56 @@ def save_billboard(PREF_IMAGE_PATH):
Vector(_x + _w, _y +_h, 0),\
Vector(_x + _w, _y, 0),\
])
-
+
render_me.faces.extend(list(render_me.verts))
render_me.faceUV= True
- # target_face= render_me.faces[-1]
- # TEXFACE isnt used because of the renderign engine cant to alpha's for texdface.
- #target_face.image= img
- #target_face.mode |= B.Mesh.FaceModes.TEX
+ 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?
- uv1, uv2, uv3, uv4= orig_f.uv
- uv3.x= uv4.x= _x+_w
- uv1.x= uv2.x= _x
-
- uv2.y= uv3.y= _y+_h
- uv1.y= uv4.y= _y
-
- if rot90:
- orig_f.uv= Vector(uv4), Vector(uv1), Vector(uv2), Vector(uv3)
-
+ 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 |= B.Mesh.FaceTranspModes.ALPHA
+ 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()
- B.Window.WaitCursor(0)
- print '%.2f secs taken' % (B.sys.time()-time)
-
-
+ Blender.Window.WaitCursor(0)
+ print '%.2f secs taken' % (Blender.sys.time()-time)
def main():
- scn= B.Scene.GetCurrent()
+ scn= bpy.data.scenes.active
ob_sel= list(scn.objects.context)
PREF_KEEP_ASPECT= False
-
# Error Checking
if len(ob_sel) < 2:
- B.Draw.PupMenu("Error%t|Select 2 mesh objects")
+ Draw.PupMenu("Error%t|Select 2 mesh objects")
return
me_ob= scn.objects.active
if not me_ob:
- B.Draw.PupMenu("Error%t|No active mesh selected.")
+ Draw.PupMenu("Error%t|No active mesh selected.")
try:
ob_sel.remove(me_ob)
@@ -246,32 +231,30 @@ def main():
pass
if me_ob.type != 'Mesh':
- B.Draw.PupMenu("Error%t|Active Object must be a mesh to write billboard images too")
+ 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:
- B.Draw.PupMenu("Error%t|Active mesh must have only quads")
+ 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 all images into 1 image"),\
+ ("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 B.Draw.PupBlock("Billboard Render", block):
+ if not Draw.PupBlock("Billboard Render", block):
return
# Set globals
@@ -279,7 +262,8 @@ def main():
GLOBALS['me_ob'] = me_ob
GLOBALS['me_data'] = me_data
- B.Window.FileSelector(save_billboard, 'SAVE BILLBOARD', B.sys.makename(ext='.png'))
+ 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_find_paths.py b/release/scripts/image_find_paths.py
deleted file mode 100644
index 266ecee9435..00000000000
--- a/release/scripts/image_find_paths.py
+++ /dev/null
@@ -1,167 +0,0 @@
-#!BPY
-
-"""
-Name: 'Fix Broken Paths'
-Blender: 242
-Group: 'Image'
-Tooltip: 'Search for new image paths to make relative links to'
-"""
-
-__author__ = "Campbell Barton AKA Ideasman"
-__url__ = ["blenderartist.org"]
-
-__bpydoc__ = """\
-Find image target paths
-
-This script searches for images whos
-file paths do not point to an existing image file,
-all image paths are made relative where possible.
-usefull when moving projects between computers, when absolute paths links are broken.
-"""
-
-# ***** 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 *
-
-try:
- import os
-except:
- Draw.PupMenu('You need a full python install to use this script')
- os= None
-
-
-#==============================================#
-# Strips the slashes from the back of a string #
-#==============================================#
-def stripPath(path):
- return path.split('/')[-1].split('\\')[-1]
-
-# finds the file starting at the root.
-def findImage(findRoot, imagePath):
- newImageFile = None
-
- imageFile = imagePath.split('/')[-1].split('\\')[-1]
-
- # ROOT, DIRS, FILES
- pathWalk = os.walk(findRoot)
- 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]:
- # FOUND A MATCH
- if file.lower() == imageFile.lower():
- name = pathList[0] + sys.sep + file
- try:
- size = os.path.getsize(name)
- except:
- size = 0
-
- if size:
- print ' found:', name
- matchList.append( (name, size) )
-
- if matchList == []:
- print 'no match for:', imageFile
- return None
- else:
- # Sort by file size
- matchList.sort(lambda A, B: cmp(B[1], A[1]) )
-
- print 'using:', matchList[0][0]
- # First item is the largest
- return matchList[0][0] # 0 - first, 0 - pathname
-
-
-# Makes the pathe relative to the blend file path.
-def makeRelative(path, blendBasePath):
- if path.startswith(blendBasePath):
- path = path.replace(blendBasePath, '//')
- path = path.replace('//\\', '//')
- return path
-
-def find_images(findRoot):
- print findRoot
-
- # findRoot = Draw.PupStrInput ('find in: ', '', 100)
-
- if findRoot == '':
- Draw.PupMenu('No Directory Selected')
- return
-
- # Account for //
- findRoot = sys.expandpath(findRoot)
-
- # Strip filename
- while findRoot[-1] != '/' and findRoot[-1] != '\\':
- findRoot = findRoot[:-1]
-
-
- if not findRoot.endswith(sys.sep):
- findRoot += sys.sep
-
-
- if findRoot != '/' and not sys.exists(findRoot[:-1]):
- Draw.PupMenu('Directory Dosent Exist')
-
- blendBasePath = sys.expandpath('//')
-
-
- Window.WaitCursor(1)
- # ============ DIR DONE\
- images = Image.Get()
- len_images = float(len(images))
- for idx, i in enumerate(images):
-
- progress = idx / len_images
- Window.DrawProgressBar(progress, 'searching for images')
-
- # If files not there?
- if not sys.exists(sys.expandpath(i.filename )):
- newImageFile = findImage(findRoot, i.filename)
- if newImageFile != None:
- newImageFile= makeRelative(newImageFile, blendBasePath)
- print 'newpath relink:', newImageFile
- i.filename = newImageFile
- i.reload()
- else:
- # Exists
- newImageFile= makeRelative(i.filename, blendBasePath)
- if newImageFile!=i.filename:
- print 'newpath relative:', newImageFile
- i.filename = newImageFile
-
-
- Window.RedrawAll()
- Window.DrawProgressBar(1.0, '')
- Window.WaitCursor(0)
-
-if __name__ == '__main__' and os:
- Window.FileSelector(find_images, 'SEARCH ROOT DIR', sys.expandpath('//'))
-
-
diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py
index a4e4e69b366..4fa7a6472cf 100644
--- a/release/scripts/import_dxf.py
+++ b/release/scripts/import_dxf.py
@@ -1,54 +1,263 @@
#!BPY
-# """
-# Name: 'Drawing eXchange Format (.dxf)'
-# Blender: 243
-# Group: 'Import'
-# Tooltip: 'Import DXF file.'
-# """
-__author__ = 'Kitsu (Ed Blake)'
-__version__ = '0.9 1/2007'
-__url__ = ["elysiun.com", "BlenderArtists.org"]
-__email__ = ["Kitsune_e@yahoo.com"]
+"""
+Name: 'Autodesk DXF (.dxf)'
+Blender: 244
+Group: 'Import'
+Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
+"""
+__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
+__version__ = '1.0.12 - 2008.02.08 by migius'
+__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
+ "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
+__email__ = ["Kitsune_e(at)yahoo.com", "migius(at)4d-vectors.de"]
__bpydoc__ = """\
-This is a Blender import script for dxf files.
-
-This script imports the dxf Geometery from dxf versions 2007 and earlier.
-
-Supported:<br>
- At this time only mesh based imports are supported.<br>
- Future support for all curve import is planned.<br>
- <br>
-Currently Supported DXF Ojects:<br>
- Lines<br>
- LightWeight polylines<br>
- True polylines<br>
- Text<br>
- Mtext<br>
- Circles<br>
- Arcs<br>
- Ellipses<br>
- Blocks<br>
- 3Dfaces<br>
-
-Known issues:<br>
- Does not convert perfectly between Object Coordinate System (OCS)
- and World Coordinate System (WCS). Only rudimentary support for
- true polylines have been implimented - splines/fitted curves/
- 3d plines/polymeshes are not supported.
- No support for most 3d entities. Doesn't support the new style object
- visability. There are problems importing some curves/arcs/circles.
-
-Notes:<br>
- This is primarally a 2d drawing release. Currently only support for
- 3d faces has been added.
- Blocks are created on layer 19 then referenced at each insert point. The
- insert point is designated with a small 3d crosshair. This handle does not render.
+This script imports objects from DXF (2d/3d) into Blender.
+
+This script imports 2d and 3d geometery from DXFr12 format files.
+Enhanced features are:
+- configurable object filtering and geometry manipulation,
+- configurable material pre-processing,
+- DXF-data analyze and raporting.
+
+Supported DXF r12 objects:
+LINE,
+POINT,
+SOLID,
+TRACE,
+TEXT,
+INSERT (=block),
+MINSERT (=array of blocks),
+CIRCLE,
+ARC,
+3DFACE,
+2d-POLYLINE (=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,
+(wip v1.0.12 partly supported) LWPOLYLINE (LightWeight),
+(wip v1.0.12) MLINE,
+(wip v1.0.12) MTEXT
+
+Unsupported Objects:
+DXF r12: DIMENSION.
+DXF>r12: SPLINE, GROUP, RAY/XLINE, LEADER, 3DSOLID, BODY, REGION, dynamic BLOCK
+
+Supported Geometry: 2d and 3d DXF-objects.
+Curves imported as curves or meshes optionally.
+
+Supported layout modes:
+"model space" is default,
+"paper space" as option (= "layout views")
+
+Scene definitions produced with AVE_RENDER:
+scene: selection of lights assigned to the camera,
+lights: DIRECT, OVERHEAD, SH_SPOT,
+(wip v1.0.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,
+(wip v1.0.12: 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.
+- Big DXF-files (over 1500 objects) decrease import performance.
+The problem is not the inefficiency of python-scripting but Blenders performance
+in creating new objects in his database - probably a database management problem.
+
+TODO:
+- the new style object visibility
+- support for real 3d-solids (ACIS)
+- (to see more, search for "--todo--" in script code)
+
+"""
+
+"""
+History:
+ v1.0 - 2008.01. by migius
+ planned tasks:
+ -- 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
+ -- bug:? object = Object.Get(obname) -> = SCENE.getChildren(obname)
+ -- "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 sometimes errors
+ -- bug: Registry recall from hd_cache ?? only win32 bug??
+
+ v1.0.12: 2008.02.08 by migius
+ -- support DXF-definitions of scene, lights and cameras
+ -- support ortho mode for VIEWs and VPORTs as cameras
+ 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 anoname/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 v0.9 by Ed Blake (AKA Kitsu)
+# DXF Import v1.0 by Ed Blake (AKA kitsu) and Remigiusz Fiedler (AKA migius)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -70,2195 +279,5667 @@ Notes:<br>
# --------------------------------------------------------------------------
import Blender
+#import bpy
from Blender import *
-Sys = sys
+#from Blender.Mathutils import Vector, Matrix
+#import BPyMessages
-from dxfReader import readDXF, get_name, get_layer
+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 *
try:
- import os
- if os.name:# != 'mac':
- import psyco
- psyco.log()
- psyco.full(memory=100)
- psyco.profile(0.05, memory=100)
- psyco.profile(0.2)
+ import os
+ if os.name:# != 'mac':
+ 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:
- pass
+ #print 'psyco not imported'
+ pass
+
+print '\n\n\n\n'
+print 'DXF-Importer *** start ***' #---------------------
-SCENE = Scene.GetCurrent()
+SCENE = None
WORLDX = Mathutils.Vector((1,0,0))
+WORLDY = Mathutils.Vector((1,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
+
+TARGET_LAYER = 3 #target blender_layer
+GROUP_BYLAYER = 0 #(0/1) all entities from same layer import into one blender-group
+
+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
-BYLAYER=256
+FREE = BezTriple.HandleTypes.FREE
+VECT = BezTriple.HandleTypes.VECT
+ALIGN = BezTriple.HandleTypes.ALIGN
+cur_COUNTER = 0 #counter for progress_bar
+
+
"""This module provides wrapper objects for dxf entities.
-
- The wrappers expect a "dxf object" as input. The dxf object is
- an object with a type and a data attribute. Type is a lowercase
- string matching the 0 code of a dxf entity. Data is a list containing
- dxf objects or lists of [code, data] pairs.
-
- This module is not general, and is only for dxf import.
+
+ The wrappers expect a "dxf object" as input. The dxf object is
+ an object with a type and a data attribute. Type is a lowercase
+ string matching the 0 code of a dxf entity. Data is a list containing
+ dxf objects or lists of [code, data] pairs.
+
+ This module is not general, and is only for dxf import.
"""
# from Stani's dxf writer v1.1 (c)www.stani.be (GPL)
#---color values
-BYBLOCK=0
-BYLAYER=256
+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
+#---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)
+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)
+
+#---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
#---mtext flags
#attachment point
-TOP_LEFT = 1
-TOP_CENTER = 2
-TOP_RIGHT = 3
-MIDDLE_LEFT = 4
+TOP_LEFT = 1
+TOP_CENTER = 2
+TOP_RIGHT = 3
+MIDDLE_LEFT = 4
MIDDLE_CENTER = 5
-MIDDLE_RIGHT = 6
-BOTTOM_LEFT = 7
+MIDDLE_RIGHT = 6
+BOTTOM_LEFT = 7
BOTTOM_CENTER = 8
-BOTTOM_RIGHT = 9
+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
+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
-class Layer:
- """Class for objects representing dxf layers."""
-
- def __init__(self, obj, name=None, color=None, frozen=None):
- """Expects an entity object of type line as input."""
- self.type = obj.type
- self.data = obj.data[:]
-
- if name:
- self.name = name
- else:
- self.name = obj.get_type(2)[0]
- if color:
- self.color = color
- else:
- self.color = obj.get_type(62)[0]
- if frozen:
- 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)
-
-
-
-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 = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.points = self.get_points(obj.data)
-
-
-
-
- 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
- sx, sy, sz, ex, ey, ez = 0, 0, 0, 0, 0, 0
- for item in data:
- if item[0] == 10: # 10 = x
- sx = item[1]
- elif item[0] == 20: # 20 = y
- sy = item[1]
- elif item[0] == 30: # 30 = z
- sz = item[1]
- elif item[0] == 11: # 11 = x
- ex = item[1]
- elif item[0] == 21: # 21 = y
- ey = item[1]
- elif item[0] == 31: # 31 = z
- ez = item[1]
- return [[sx, sy, sz], [ex, ey, ez]]
-
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import lines into Blender."""
- # Generate the geometery
- points = self.points
- edges = [[0, 1]]
-
- me = Mesh.New('line') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', 'line') # link mesh to an object
- ob.link(me)
-
- return ob
-
-
-
-
-class LWpolyline:
- """Class for objects representing dxf LWpolylines."""
-
- def __init__(self, obj):
- """Expects an entity object of type lwpolyline as input."""
- 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 = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- self.elevation = obj.get_type(38)
- if self.elevation:
- self.elevation = self.elevation[0]
- else:
- self.elevation = 0
-
- self.flags = obj.get_type(70)
- if self.flags:
- self.flags = self.flags[0]
- else:
- self.flags = 0
-
- self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.points = self.get_points(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
-
- def get_points(self, data):
- """Gets points for a polyline type object.
-
- 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]
- 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 get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import plines into Blender."""
- # Generate the geometery
- points = []
- for i in range(len(self.points)):
- point = self.points[i]
- if not point.bulge:
- points.append(point.loc)
- elif point.bulge and i < len(self.points)-1:# > 0:
- center, radius, start, end = solveBulge(point, self.points[i+1])
- #print center, radius, start, end
- verts, nosense = drawArc(center, radius, start, end)
- verts.pop(0) # remove first
- verts.pop() #remove last
- if point.bulge >= 0:
- verts.reverse()
- points.extend(verts)
- edges = [[num, num+1] for num in range(len(points)-1)]
- if self.closed:
- edges.append([len(self.points)-1, 0])
-
- me = Mesh.New('lwpline') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', 'lwpline') # link mesh to an object
- ob.link(me)
- transform(self.extrusion, ob)
- ob.LocZ = self.elevation
-
- return ob
-
-
-
-class Polyline:
- """Class for objects representing dxf LWpolylines."""
-
- def __init__(self, obj):
- """Expects an entity object of type polyline as input."""
- if not obj.type == 'polyline':
- raise TypeError, "Wrong type %s for polyline object!" %obj.type
- self.type = obj.type
- self.data = obj.data[:]
- self.points = []
-
- # optional data (with defaults)
- self.space = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- self.elevation = obj.get_type(30)
- if self.elevation:
- self.elevation = self.elevation[0]
- else:
- self.elevation = 0
-
- self.flags = obj.get_type(70)
- if self.flags:
- self.flags = self.flags[0]
- else:
- self.flags = 0
-
- self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import plines into Blender."""
- # Generate the geometery
- points = []
- for i in range(len(self.points)):
- point = self.points[i]
- if not point.bulge:
- points.append(point.loc)
- elif point.bulge and i < len(self.points)-1:# > 0:
- center, radius, start, end = solveBulge(point, self.points[i+1])
- #print center, radius, start, end
- verts, nosense = drawArc(center, radius, start, end)
- verts.pop(0) # remove first
- verts.pop() #remove last
- if point.bulge >= 0:
- verts.reverse()
- points.extend(verts)
- edges = [[num, num+1] for num in range(len(points)-1)]
- if self.closed:
- edges.append([len(self.points)-1, 0])
-
- me = Mesh.New('pline') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.edges.extend(edges) # add edges to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', 'pline') # link mesh to an object
- ob.link(me)
- transform(self.extrusion, ob)
- ob.LocZ = self.elevation
-
- return ob
-
-
-
-
-class Vertex(object):
- """Generic vertex object used by polylines (and maybe others)."""
-
- def __init__(self, obj=None):
- """Initializes vertex data.
-
- The optional obj arg is an entity object of type vertex.
- """
- self.loc = [0,0,0]
- self.bulge = 0
- self.swidth = 0
- self.ewidth = 0
- self.flags = 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.data)
-
-
- 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
- """
- for item in data:
- if item[0] == 10: # 10 = x
- self.x = item[1]
- elif item[0] == 20: # 20 = y
- self.y = item[1]
- elif item[0] == 30: # 30 = z
- self.z = item[1]
- elif item[0] == 40: # 40 = start width
- self.swidth = item[1]
- elif item[0] == 41: # 41 = end width
- self.ewidth = item[1]
- elif item[0] == 42: # 42 = bulge
- self.bulge = item[1]
- elif item[0] == 70: # 70 = vert flags
- self.flags = item[1]
-
-
- 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" %(self.loc, self.swidth, self.ewidth, self.bulge)
-
-
- 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 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 = obj.get_type(40)[0]
- self.value = obj.get_type(1)[0] # The text string value
-
- # optional data (with defaults)
- self.space = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- self.rotation = obj.get_type(50) # radians?
- if not self.rotation:
- self.rotation = 0
- else:
- self.rotation = self.rotation[0]
-
- self.width_factor = obj.get_type(41) # Scaling factor along local x axis
- if not self.width_factor:
- self.width_factor = 1
- else:
- self.width_factor = self.width_factor[0]
-
- self.oblique = obj.get_type(51) # skew in degrees -90 <= oblique <= 90
- if not self.oblique:
- self.oblique = 0
- else:
- self.oblique = self.oblique[0]
-
- self.halignment = obj.get_type(72) # horiz. alignment
- if not self.halignment: # 0=left, 1=center, 2=right, 3=aligned, 4=middle, 5=fit
- self.halignment = 0
- else:
- self.halignment = self.halignment[0]
-
- self.valignment = obj.get_type(73) # vert. alignment
- if not self.valignment: # 0=baseline, 1=bottom, 2=middle, 3=top
- self.valignment = 0
- else:
- self.valignment = self.valignment[0]
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data, self.halignment, self.valignment)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
- def get_loc(self, data, halign, valign):
- """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
- for item in data:
- if item[0] == 10: # 10 = x
- x = item[1]
- elif item[0] == 20: # 20 = y
- y = item[1]
- elif item[0] == 30: # 30 = z
- z = item[1]
- elif item[0] == 11: # 11 = x
- jx = item[1]
- elif item[0] == 21: # 21 = y
- jy = item[1]
- elif item[0] == 31: # 31 = z
- jz = item[1]
-
- if halign or valign:
- x, y, z = jx, jy, jz
- return [x, y, z]
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import texts into Blender."""
- # Generate the geometery
- txt = Text3d.New("text")
- txt.setSize(1)
- txt.setShear(self.oblique/90)
- txt.setExtrudeDepth(0.5)
- if self.halignment == 0:
- align = Text3d.LEFT
- elif self.halignment == 1:
- align = Text3d.MIDDLE
- elif self.halignment == 2:
- align = Text3d.RIGHT
- elif self.halignment == 3:
- align = Text3d.FLUSH
- else:
- align = Text3d.MIDDLE
- txt.setAlignment(align)
- txt.setText(self.value)
-
- # Now Create an object
- ob = Object.New('Text', 'text') # link mesh to an object
- ob.link(txt)
-
- transform(self.extrusion, ob)
-
- # move the object center to the text location
- ob.loc = tuple(self.loc)
- # scale it to the text size
- ob.SizeX = self.height*self.width_factor
- ob.SizeY = self.height
- ob.SizeZ = self.height
- # and rotate it around z
- ob.RotZ = radians(self.rotation)
-
- return ob
-
-
-
-
-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.data) # The text string value
-
- # optional data (with defaults)
- self.space = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- self.rotation = obj.get_type(50) # radians
- if not self.rotation:
- self.rotation = 0
- else:
- self.rotation = self.rotation[0]
-
- self.width_factor = obj.get_type(42) # Scaling factor along local x axis
- if not self.width_factor:
- self.width_factor = 1
- else:
- self.width_factor = self.width_factor[0]
-
- self.line_space = obj.get_type(44) # percentage of default
- if not self.line_space:
- self.line_space = 1
- else:
- self.line_space = self.line_space[0]
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
- 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 location.
- """
- loc = [0,0,0]
- for item in data:
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- return loc
-
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, value - %s" %(self.__class__.__name__, self.layer, self.value)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import mtexts into Blender."""
- # Generate the geometery
- txt = Text3d.New("mtext")
- 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)
-
- # Now Create an object
- ob = Object.New('Text', 'mtext') # link mesh to an object
- ob.link(txt)
-
- transform(self.extrusion, ob)
-
- # move the object center to the text location
- ob.loc = tuple(self.loc)
- # scale it to the text size
- ob.SizeX = self.height*self.width_factor
- ob.SizeY = self.height
- ob.SizeZ = self.height
- # and rotate it around z
- ob.RotZ = radians(self.rotation)
-
- 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 = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
- def get_loc(self, data):
- """Gets the center location for circle type objects.
-
- Circles have a single coord location.
- """
- loc = [0, 0, 0]
- for item in data:
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- return loc
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import circles into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveCircle(self)
- else:
- center = self.loc
- radius = self.radius
-
- circ = 2 * pi * radius
- if circ < 65: # if circumfrance is too small
- verts = 32 # set a fixed number of 32 verts
- else:
- verts = circ/.5 # figure out how many verts we need
- if verts > 100: # Blender only accepts values
- verts = 100 # [3:100]
-
- c = Mesh.Primitives.Circle(int(verts), radius*2)
-
- ob = Object.New('Mesh', 'circle')
- ob.link(c) # link curve data with this object
-
- ob.loc = tuple(center)
- transform(self.extrusion, 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 = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
- def get_loc(self, data):
- """Gets the center location for arc type objects.
-
- Arcs have a single coord location.
- """
- loc = [0, 0, 0]
- for item in data:
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- return loc
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import arcs into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveArc(self)
- else:
- center = self.loc
- radius = self.radius
- start = self.start_angle
- end = self.end_angle
- verts, edges = drawArc(None, radius, start, end)
-
- a = Mesh.New('arc')
-
- a.verts.extend(verts) # add vertices to mesh
- a.edges.extend(edges) # add edges to the mesh
-
- ob = Object.New('Mesh', 'arc')
- ob.link(a) # link curve data with this object
- ob.loc = tuple(center)
- ob.RotX = radians(180)
-
- transform(self.extrusion, 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 = obj.get_type(2)[0]
-
- # optional data (with defaults)
- self.insertion_units = obj.get_type(70)
- if not self.insertion_units:
- self.insertion_units = None
- else:
- self.insertion_units = self.insertion_units[0]
-
- self.insert_units = obj.get_type(1070)
- if not self.insert_units:
- self.insert_units = None
- else:
- self.insert_units = self.insert_units[0]
-
-
-
-
-
-
- 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.data = obj.data[:]
- self.name = obj.name
-
- # required data
- self.flags = obj.get_type(70)[0]
- self.entities = dxfObject('block_contents')
- self.entities.data = objectify([ent for ent in obj.data if type(ent) != list])
-
- # optional data (with defaults)
- self.path = obj.get_type(1)
- if self.path:
- self.path = self.path[0]
- else:
- self.path = ''
-
- self.discription = obj.get_type(4)
- if self.discription:
- self.discription = self.discription[0]
- else:
- self.discription = ''
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
-
-
-
-
- def get_loc(self, data):
- """Gets the insert point of the block."""
- loc = [0, 0, 0]
- for item in data:
- if type(item) != list:
- continue
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- 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[:]
-
- # required data
- self.block = obj.get_type(2)[0]
-
- # optional data (with defaults)
- self.rotation = obj.get_type(50)
- if self.rotation:
- self.rotation = self.rotation[0]
- else:
- self.rotation = 0
-
- self.space = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
- self.scale = self.get_scale(obj.data)
- self.rows, self.columns = self.get_array(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
-
-
-
-
-
- def get_loc(self, data):
- """Gets the center location for circle type objects.
-
- Circles have a single coord location.
- """
- loc = [0, 0, 0]
- for item in data:
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- return loc
-
-
-
- def get_scale(self, data):
- """Gets the x/y/z scale factor for the block.
- """
- scale = [1, 1, 1]
- for item in data:
- if item[0] == 41: # 41 = x scale
- scale[0] = item[1]
- elif item[0] == 42: # 42 = y scale
- scale[1] = item[1]
- elif item[0] == 43: # 43 = z scale
- scale[2] = item[1]
- return scale
-
-
-
- def get_array(self, data):
- """Returns the pair (row number, row spacing), (column number, column spacing)."""
- columns = 1
- rows = 1
- cspace = 0
- rspace = 0
- for item in data:
- if item[0] == 70: # 70 = columns
- columns = item[1]
- elif item[0] == 71: # 71 = rows
- rows = item[1]
- if item[0] == 44: # 44 = columns
- cspace = item[1]
- elif item[0] == 45: # 45 = rows
- rspace = item[1]
- return (rows, rspace), (columns, cspace)
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, block - %s" %(self.__class__.__name__, self.layer, self.block)
-
-
- def draw(self, handle, settings):
- """Do all the specific things needed to import blocks into Blender.
-
- Blocks are made of three objects:
- the block_record in the tables section
- the block in the blocks section
- the insert object in the entities section
-
- block_records give the insert units, blocks provide the objects drawn in the
- block, and the insert object gives the location/scale/rotation of the block
- instances. To draw a block you must first get a group with all the
- blocks entities drawn in it, then scale the entities to match the world
- units, then dupligroup that data to an object matching each insert object."""
-
- # Create an object
- ob = Object.New('Mesh', self.block)
- ob.link(handle) # Give the object a handle
-
- if settings.drawTypes['blocks']:
- # get our block group
- block = settings.blocks(self.block)
-
- ob.DupGroup = block
- ob.enableDupGroup = True
-
- ob.loc = tuple(self.loc)
- transform(self.extrusion, ob)
- ob.RotZ += radians(self.rotation)
- 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]
- self.start_angle = obj.get_type(41)[0]
- self.end_angle = obj.get_type(42)[0]
-
- # optional data (with defaults)
- self.space = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.loc = self.get_loc(obj.data)
- self.major = self.get_major(obj.data)
- self.extrusion = self.get_extrusion(obj.data)
- self.radius = sqrt(self.major[0]**2 + self.major[0]**2 + self.major[0]**2)
-
-
-
-
- def get_loc(self, data):
- """Gets the center location for arc type objects.
-
- Arcs have a single coord location.
- """
- loc = [0, 0, 0]
- for item in data:
- if item[0] == 10: # 10 = x
- loc[0] = item[1]
- elif item[0] == 20: # 20 = y
- loc[1] = item[1]
- elif item[0] == 30: # 30 = z
- loc[2] = item[1]
- 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]
- for item in data:
- if item[0] == 11: # 11 = x
- loc[0] = item[1]
- elif item[0] == 21: # 21 = y
- loc[1] = item[1]
- elif item[0] == 31: # 31 = z
- loc[2] = item[1]
- return loc
-
-
-
- def get_extrusion(self, data):
- """Find the axis of extrusion.
-
- Used to get the objects Object Coordinate System (ocs).
- """
- vec = [0,0,1]
- for item in data:
- if item[0] == 210: # 210 = x
- vec[0] = item[1]
- elif item[0] == 220: # 220 = y
- vec[1] = item[1]
- elif item[0] == 230: # 230 = z
- vec[2] = item[1]
- return vec
-
-
- def __repr__(self):
- return "%s: layer - %s, radius - %s" %(self.__class__.__name__, self.layer, self.radius)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import ellipses into Blender."""
- # Generate the geometery
- # Now Create an object
- if curves:
- ob = drawCurveArc(self)
- else:
- major = Mathutils.Vector(self.major)
- delta = Mathutils.AngleBetweenVecs(major, WORLDX)
- center = self.loc
- radius = major.length
- start = degrees(self.start_angle)
- end = degrees(self.end_angle)
- verts, edges = drawArc(None, radius, start, end)
-
- e = Mesh.New('ellipse')
-
- e.verts.extend(verts) # add vertices to mesh
- e.edges.extend(edges) # add edges to the mesh
-
-
- ob = Object.New('Mesh', 'arc')
- ob.link(e) # link curve data with this object
- ob.loc = tuple(center)
- ob.SizeY = self.ratio
- #ob.RotZ = radians(delta)
- ob.RotX = radians(180)
-
-
- transform(self.extrusion, ob)
- ob.RotZ = radians(delta)
-
- return ob
-
-
-
-class Face:
- """Class for objects representing dxf 3d faces."""
-
- 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 = obj.get_type(67)
- if self.space:
- self.space = self.space[0]
- else:
- self.space = 0
-
- self.color_index = obj.get_type(62)
- if self.color_index:
- self.color_index = self.color_index[0]
- else:
- self.color_index = BYLAYER
-
- discard, self.layer = get_layer(obj.data)
- obj.data.remove(discard)
- self.points = self.get_points(obj.data)
-
-
-
-
- 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 = False
- for item in data:
- # ----------- a -------------
- if item[0] == 10: # 10 = x
- a[0] = item[1]
- elif item[0] == 20: # 20 = y
- a[1] = item[1]
- elif item[0] == 30: # 30 = z
- a[2] = item[1]
- # ----------- b -------------
- elif item[0] == 11: # 11 = x
- b[0] = item[1]
- elif item[0] == 21: # 21 = y
- b[1] = item[1]
- elif item[0] == 31: # 31 = z
- b[2] = item[1]
- # ----------- c -------------
- elif item[0] == 12: # 12 = x
- c[0] = item[1]
- elif item[0] == 22: # 22 = y
- c[1] = item[1]
- elif item[0] == 32: # 32 = z
- c[2] = item[1]
- # ----------- d -------------
- elif item[0] == 13: # 13 = x
- d = [0, 0, 0]
- d[0] = item[1]
- elif item[0] == 23: # 23 = y
- d[1] = item[1]
- elif item[0] == 33: # 33 = z
- d[2] = item[1]
- out = [a,b,c]
- if d:
- out.append(d)
- return out
-
-
- def __repr__(self):
- return "%s: layer - %s, points - %s" %(self.__class__.__name__, self.layer, self.points)
-
-
- def draw(self, curves=False):
- """Do all the specific things needed to import 3d faces into Blender."""
- # Generate the geometery
- points = self.points
- if len(self.points) > 3:
- faces = [[0, 1, 2, 3]]
- else:
- faces = [[0, 1, 2]]
-
- me = Mesh.New('3dface') # create a new mesh
-
- me.verts.extend(points) # add vertices to mesh
- me.faces.extend(faces) # add faces to the mesh
-
- # Now Create an object
- ob = Object.New('Mesh', '3dface') # link mesh to an object
- ob.link(me)
-
- return ob
-
-
-
-# type to object map
+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.data, 10, 0.0) #view center pointX (in DCS)
+ self.centerY = getit(obj.data, 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.data, 11, 0.0) #view directionX from target (in WCS)
+ self.dir[1] = getit(obj.data, 21, 0.0) #
+ self.dir[2] = getit(obj.data, 31, 0.0) #
+
+ self.target = [0,0,0]
+ self.target[0] = getit(obj.data, 12, 0.0) #target pointX(in WCS)
+ self.target[1] = getit(obj.data, 22, 0.0) #
+ self.target[2] = getit(obj.data, 32, 0.0) #
+
+ self.length = obj.get_type(42)[0] #Lens length
+ self.clip_front = getit(obj.data, 43) #Front clipping plane (offset from target point)
+ self.clip_back = getit(obj.data, 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.data, 12, 0.0) #vport center pointX (in DCS)
+ self.centerY = getit(obj.data, 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.data, 16, 0.0) #vport directionX from target (in WCS)
+ self.dir[1] = getit(obj.data, 26, 0.0) #
+ self.dir[2] = getit(obj.data, 36, 0.0) #
+
+ self.target = [0,0,0]
+ self.target[0] = getit(obj.data, 17, 0.0) #target pointX(in WCS)
+ self.target[1] = getit(obj.data, 27, 0.0) #
+ self.target[2] = getit(obj.data, 37, 0.0) #
+
+ self.length = obj.get_type(42)[0] #Lens length
+ self.clip_front = getit(obj.data, 43) #Front clipping plane (offset from target point)
+ self.clip_back = getit(obj.data, 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 object of type layer as input.
+ """
+ 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:
+ 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
+
+
+
+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.data, 8, None)
+ self.extrusion = get_extrusion(obj.data)
+ self.points = self.get_points(obj.data)
+
+
+
+ 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]]
+
+
+
+ me = Mesh.New(obname) # create a new mesh
+ 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
+
+ ob = SCENE.objects.new(me) # create a new mesh_object
+ if settings.var['vGroup_on']:
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ replace = Blender.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.data, 8, None)
+ self.extrusion = get_extrusion(obj.data)
+ self.points = self.get_points(obj.data)
+
+
+ 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']
+
+ if 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]
+ 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 activObjectLayer == self.layer and settings.var['one_mesh_on']:
+ obname = activObjectName
+ #print 'deb:line.draw obname from activObjectName: ', obname #---------------------
+ ob = Object.Get(obname) # open an existing mesh_object
+ #ob = SCENE.getChildren(obname) # open an existing mesh_object
+ me = Mesh.Get(ob.name) # open objects mesh data
+ 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']:
+ # 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 = Blender.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.data, 8, None)
+ self.extrusion = get_extrusion(obj.data)
+ self.points = self.get_points(obj.data)
+
+
+ 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 True: #--todo-- points_as in [1,3,4,5]:
+ if True: # 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 activObjectLayer == self.layer and settings.var['one_mesh_on']:
+ obname = activObjectName
+ #print 'deb:draw:point.ob obname from activObjectName: ', obname #---------------------
+ ob = Object.Get(obname) # open an existing mesh_object
+ #ob = SCENE.getChildren(obname) # open an existing mesh_object
+ 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 LWpolyline: #-----------------------------------------------------------------
+ """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.color_index = getit(obj, 62, BYLAYER)
+
+ self.elevation = getit(obj, 30, 0)
+ self.thic = getit(obj, 39, 0)
+ self.flags = getit(obj, 70, 0)
+
+ self.closed = self.flags&1 # byte coded, 1 = closed, 128 = plinegen
+
+ self.layer = getit(obj.data, 8, None)
+ self.points = self.get_points(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+
+ #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]
+ 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)
+
+
+ def draw(self, settings):
+ """for LWPOLYLINE: generate Blender_geometry.
+ """
+ #print 'deb:LWpolyline.draw.START:----------------' #------------------------
+ points = []
+ obname = 'lw_%s' %self.layer # create object name from layer name
+ obname = obname[:MAX_NAMELENGTH]
+ #settings.var['curves_on'] == True
+ #print 'deb:index_len: ', len(self.points) #------------------
+ for i, point in enumerate(self.points):
+ #print 'deb:index: ', i #------------------
+ if not point.bulge:
+ points.append(point.loc)
+ elif point.bulge and not self.closed and i == len(self.points)-1:
+ points.append(point.loc)
+ elif point.bulge: #
+ if i == len(self.points)-1:
+ point2 = self.points[0]
+ else:
+ point2 = self.points[i+1]
+ arc_res = settings.var['arc_res']/sqrt(settings.var['arc_rad'])
+ verts, center = calcBulge(point, point2, arc_res)
+# if i == len(self.points)-1:
+# if self.closed:
+# verts.pop() #remove last(=first) vertex
+# else:
+# verts.pop() #remove last vertex, because this point will be writen as the next vertex
+ points.extend(verts)
+
+ thic = self.thic
+ if settings.var['thick_force'] and thic == 0: thic = settings.var['thick_min']
+ if settings.var['thick_on'] and thic != 0:
+ len1 = len(points)
+ points.extend([[point[0], point[1], point[2]+thic] for point in points])
+ faces = []
+ #print 'deb:len1:', len1 #-----------------------
+ 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])
+ #print 'deb:faces_list:\n', faces #-----------------------
+ 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
+ else:
+ edges = [[num, num+1] for num in xrange(len(points)-1)]
+ if self.closed:
+ edges.append([len(points)-1, 0])
+ #print 'deb:edges_list:\n', edges #-----------------------
+ 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
+
+ ob.LocZ = self.elevation
+ transform(self.extrusion, 0, ob)
+
+ #print 'deb:LWpolyline.draw.END:----------------' #------------------------
+ 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[:]
+ #print 'deb:polyline.obj.data[:]:\n', obj.data[:] #------------------------
+ self.points = []
+
+ # optional data (with defaults)
+ 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 # Bspline-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
+
+ if self.poly3d or self.plface or self.plmesh:
+ self.poly2d = False # its not a 2D-polyline
+ else:
+ self.poly2d = True # it is a 2D-polyline
+
+ 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.curvetyp = getit(obj, 75, 0) # type of curve/surface: 0=None/5=Quadric/6=Cubic/8=Bezier
+ self.curvNormal = False
+ self.curvQBspline = False
+ self.curvCBspline = False
+ self.curvBezier = False
+ if self.curvetyp == 0: self.curvNormal = True
+ elif self.curvetyp == 5: self.curvQBspline = True
+ elif self.curvetyp == 6: self.curvCBspline = True
+ elif self.curvetyp == 8: self.curvBezier = True
+
+ self.layer = getit(obj.data, 8, None)
+ self.extrusion = get_extrusion(obj.data)
+
+ 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 draw(self, settings): #-------------%%%% DRAW POLYLINE %%%---------------
+ """for POLYLINE: generate Blender_geometry.
+ """
+ ob = []
+ #---- 3dPolyFace - mesh with free topology
+ if self.plface and settings.drawTypes['plmesh']:
+ ob = self.drawPlFace(settings)
+ #---- 3dPolyMesh - mesh with ortogonal topology
+ elif self.plmesh and settings.drawTypes['plmesh']:
+ ob = self.drawPlMesh(settings)
+ #---- 2dPolyline - plane polyline with arc/wide/thic segments
+ elif (self.poly2d and settings.drawTypes['polyline']):
+ if settings.var['plines_as'] == 5: # and self.spline:
+ ob = self.drawPolyCurve(settings)
+ else:
+ ob = self.drawPoly2d(settings)
+ #---- 3dPolyline - non-plane polyline (thin segments = without arc/wide/thic)
+ elif (self.poly3d and settings.drawTypes['pline3']):
+ if settings.var['plines3_as'] == 5: # and self.spline:
+ 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)
+
+
+ #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
+ #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['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
+ 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)
+
+ 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 False: #self.spline: # NURBSplines-----FAKE(with Bezier)-----
+ #print 'deb:polyline2dCurve.draw self.spline!' #---------------
+ 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]
+ if self.closed:
+ curve.flagU = 1 # Set curve cyclic=close
+ else:
+ curve.flagU = 0 # Set curve not cyclic=open
+ curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
+ curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
+
+ elif self.spline: # NURBSplines-----OK-----
+ #print 'deb:polyline2dCurve.draw self.spline!' #---------------
+ weight1 = 0.5
+ weight2 = 1.0
+ # generate middlepoints except start/end-segments ---
+ if self.curvQBspline:
+ temp_points = []
+ point = d_points[0].loc
+ point.append(weight1)
+ temp_points.append(point)
+ for i in xrange(1,len(d_points)-2):
+ point1 = d_points[i].loc
+ point2 = d_points[i+1].loc
+ mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
+ mpoint.append(weight2)
+ point1.append(weight1)
+ temp_points.append(point1)
+ temp_points.append(mpoint)
+ point2.append(weight1)
+ temp_points.append(point2)
+ point = d_points[-1].loc
+ point.append(weight1)
+ temp_points.append(point)
+ d_points = temp_points
+ else:
+ temp_points = []
+ for d in d_points:
+ d = d.loc
+ d.append(weight1)
+ temp_points.append(d)
+ d_points = temp_points
+
+ if not self.closed:
+ # generate extended startpoint and endpoint------
+ point1 = Mathutils.Vector(d_points[0][:3])
+ point2 = Mathutils.Vector(d_points[1][:3])
+ startpoint = list(point1 - point2 + point1)
+ startpoint.append(weight1)
+ point1 = Mathutils.Vector(d_points[-1][:3])
+ point2 = Mathutils.Vector(d_points[-2][:3])
+ endpoint = list(point1 - point2 + point1)
+ endpoint.append(weight1)
+ temp_points = []
+ temp_points.append(startpoint)
+ temp_points.extend(d_points)
+ d_points = temp_points
+ d_points.append(endpoint)
+
+ point = d_points[0]
+ curve = pline.appendNurb(point)
+ curve.setType(4) #NURBS curve
+ for point in d_points[1:]:
+ curve.append(point)
+ if self.closed:
+ curve.flagU = 1 # Set curve cyclic=close
+ else:
+ curve.flagU = 0 # Set curve not cyclic=open
+
+ elif self.curved: #--Bezier-curves---OK-------
+ #print 'deb:polyline2dCurve.draw self.curved!' #---------------
+ 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]
+ if self.closed:
+ curve.flagU = 1 # Set curve cyclic=close
+ else:
+ curve.flagU = 0 # Set curve not cyclic=open
+ curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
+ curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
+
+ else: #--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]
+ if False: #-----outdated!- standard calculation ----------------------------------
+ if point1.bulge and (i < len(d_points)-2 or self.closed):
+ verts, center = calcBulge(point1, point2, arc_res, triples=False)
+ if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
+ else: curve.append(BezTriple.New(verts[0]))
+ curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
+ for p in verts[1:]:
+ curve.append(BezTriple.New(p))
+ curve[-1].handleTypes = [AUTO, AUTO]
+ else:
+ if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
+ else: curve.append(BezTriple.New(point1.loc))
+ curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
+
+ elif True: #----- 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]
+
+ for p in VectorTriples[1:-1]:
+ curve.append(BezTriple.New(p))
+ curve[-1].handleTypes = [FREE, FREE]
+
+ 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
+ else:
+ if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
+ else: curve.append(BezTriple.New(point1.loc))
+ curve[-1].handleTypes = [VECT, VECT]
+
+
+
+ #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]
+ #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
+ 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
+ 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 #------------------------
+
+
+ # routine to sort out of "double.vertices" ------------------------------------
+ minimal_dist = settings.var['dist_min'] * 0.1
+ 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: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
+ 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 #------------------------
+
+ #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
+ if swidth == None: swidth = swidth_default
+ if ewidth == None: ewidth = ewidth_default
+ if swidth != 0.0 or ewidth != 0.0: wide_segment_exist = True
+
+ 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)
+ elif False: # the standard no-intersection
+ # --todo-- not optimal, because produces X-face
+ pointsLc.extend((pointsLe[i],pointsLs[i+1]))
+ pointsRc.extend((pointsRe[i],pointsRs[i+1]))
+ elif False: # --todo-- the optimised non-intersection
+ if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
+ left_angle = True
+ else:
+ left_angle = False
+ limit_dist = settings.var['dist_min']
+ if left_angle: # if left turning angle
+ print 'deb:drawPoly2d it is left turning angle' #-------------
+ # to avoid triangelface/doubleVertex
+ delta1 = (cornerpointL - vecL1).normalize() * limit_dist
+ delta4 = (cornerpointL - vecL4).normalize() * limit_dist
+ pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
+ pointsRc.extend((pointsRe[i],pointsRs[i+1]))
+ else: # if right turning angle
+ print 'deb:drawPoly2d right turning angle' #-------------
+ delta1 = (cornerpointR - vecR1).normalize() * limit_dist
+ delta4 = (cornerpointR - vecR4).normalize() * limit_dist
+ pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
+ pointsLc.extend((pointsLe[i],pointsLs[i+1]))
+ 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
+ if True:
+ cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
+ cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
+ pointsLc.append(cornerpointL[0])
+ pointsRc.append(cornerpointR[0])
+ else:
+ pointVec = Mathutils.Vector(point[i])
+
+ 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 #-----------------------
+ 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']:
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ replace = Blender.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', list(set(vg_left)), 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(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:
+ if True:
+ 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])
+ 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])
+ 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:
+ if True:
+ 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])
+ 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).
+ """
+
+ 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 = 0
+ self.ewidth = 0
+ self.bulge = 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.data)
+ #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.curv_t = self.flags&2 # Bezier-curve-fit:tangent exists
+ self.spline = self.flags&8 # Bspline-fit:additional-vertex
+ self.splin2 = self.flags&16 # Bspline-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.curv_t:
+ self.curv_tangent = getit(data, 50, None) # curve_tangent
+
+ if 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 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.data, 8, None)
+ self.loc1, self.loc2 = self.get_loc(obj.data)
+ if self.loc2[0] != None and self.halignment != 5:
+ self.loc = self.loc2
+ else:
+ self.loc = self.loc1
+ self.extrusion = get_extrusion(obj.data)
+
+
+
+ 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.data) # 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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+
+
+ 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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+
+
+
+ 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 -------------
+ if True: # universal version
+ 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]
+ else: # standard version
+ c = Curve.New(obname) # 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 = c.appendNurb(p1)
+ curve.append(p2)
+ curve.append(p3)
+ curve.append(p4)
+ for point in curve:
+ point.handleTypes = [AUTO, AUTO]
+
+ 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
+
+ elif False: # create a new mesh_object with buildin_circle_primitive
+ verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
+ if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
+ if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
+ if thic != 0:
+ loc2 = thic * 0.5 #-----blenderAPI draw Cylinder with 2*thickness
+ self.loc[2] += loc2 #---new location for the basis of cylinder
+ #print 'deb:circleDraw:self.loc2:', self.loc #-----------------------
+ c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
+ else:
+ c = Mesh.Primitives.Circle(int(verts_num), radius*2)
+
+ #c.update()
+ ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
+ ob.loc = tuple(self.loc)
+ transform(self.extrusion, 0, ob)
+ return ob
+
+ else: # draw CIRCLE as mesh -----------------------------------------------
+ cir = Mesh.New(obname) # create a new mesh
+ ob = SCENE.objects.new(cir) # create a new circle_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 #---------------
+ cir.verts.extend(verts) # add vertices to mesh
+ cir.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):
+ cir.faces[i].smooth = True
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ if settings.var['vGroup_on']:
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
+ vg_band, vg_top, vg_bottom = [], [], []
+ for v in f_band: vg_band.extend(v)
+ cir.addVertGroup('side.band') ; cir.assignVertsToGroup('side.band', list(set(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)
+ cir.addVertGroup('side.top') ; cir.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
+ cir.addVertGroup('side.bottom'); cir.assignVertsToGroup('side.bottom',list(set(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 #---------------
+ cir.verts.extend(verts) # add vertices to mesh
+ cir.faces.extend(faces) # add faces to the mesh
+ else:
+ cir.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
+ cir.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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+ #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]
+ 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 --------------------
+ 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']:
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ replace = Blender.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', list(set(vg_left)), 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(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 Einfügeeinheiten:
+ 0 = Keine Einheiten; 1 = Zoll; 2 = Fuß; 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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+
+ #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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+ self.scale = self.get_scale(obj.data)
+ self.rows, self.columns = self.get_array(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+
+ #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
+ elif False: # 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.data, 8, None)
+ self.loc = self.get_loc(obj.data)
+ self.major = self.get_major(obj.data)
+ self.extrusion = get_extrusion(obj.data)
+
+
+ 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
+ if True:
+ 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
+
+ else: # bug in AutoCAD_2002 dxf-exporter into r12 for ELLIPSE->POLYLINE_ARC
+ #print 'deb:calcEllipse---------:\n start=%s\n end=%s' %(self.start_angle, self.end_angle) #---------
+ if self.start_angle > pi+pi: self.start_angle %= pi+pi
+ if self.end_angle > pi+pi: self.end_angle %= pi+pi
+ if abs(self.end_angle - pi - pi) < 0.00001: self.end_angle = pi + pi
+ ellipse_closed = False
+ if abs(self.end_angle - self.start_angle) == pi + pi: ellipse_closed = True
+ test = self.start_angle % pi
+ if test < 0.001 or pi - test < 0.001: start = self.start_angle
+ else:
+ start = atan(tan(self.start_angle) * self.ratio)
+ if start < 0.0: start += pi
+ if self.start_angle > pi: start += pi
+ test = self.end_angle % pi
+ if test < 0.001 or pi - test < 0.001: end = self.end_angle
+ else:
+ end = atan(tan(self.end_angle) * self.ratio)
+ if end < 0.0: end += pi
+ if self.end_angle > pi: end += pi
+ start = degrees(start)
+ end = degrees(end)
+
+ # 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']
+ if settings.var['lines_as'] == 3: # as thin cylinder
+ cyl_rad = 0.5 * settings.var['width_min']
+
+ if 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]
+ 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]
+ 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 --------------------------------------
+ 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]
+ if False: #--todo--: if ellipse_closed:
+ verts = verts[:-1] #list without last point/edge (cause closed curve)
+ 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']:
+ # each MeshSide becomes vertexGroup for easier material assignment ---------------------
+ replace = Blender.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', list(set(vg_left)), 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(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.data, 8, None)
+ self.points = self.get_points(obj.data)
+
+
+ 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 activObjectLayer == self.layer and settings.var['one_mesh_on']:
+ obname = activObjectName
+ #print 'deb:face.draw obname from activObjectName: ', obname #---------------------
+ ob = Object.Get(obname) # open an existing mesh_object
+ #ob = SCENE.getChildren(obname) # open an existing mesh_object
+ 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']:
+ # 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 = Blender.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 = {
- 'line':Line,
- 'lwpolyline':LWpolyline,
- 'text':Text,
- 'mtext':Mtext,
- 'circle':Circle,
- 'arc':Arc,
- 'layer':Layer,
- 'block_record':BlockRecord,
- 'block':Block,
- 'insert':Insert,
- 'ellipse':Ellipse,
- '3dface':Face
+ '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,
+# '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.
- """
- objects = [] # colector for finished objects
- known_types = type_map.keys() # so we don't have to call foo.keys() every iteration
- index = 0
- while index < len(data):
- item = data[index]
- if type(item) != list and item.type in known_types:
- # proccess the object and append the resulting object
- objects.append(type_map[item.type](item))
- elif 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':
- pline = Polyline(item)
- while 1:
- index += 1
- item = data[index]
- if item.type == 'vertex':
- v = Vertex(item)
- pline.points.append(v)
- elif item.type == 'seqend':
- break
- else:
- print "Error: non-vertex found before seqend!"
- index -= 1
- break
- objects.append(pline)
- else:
- # we will just let the data pass un-harrased
- objects.append(item)
- index += 1
- return objects
-
-class MatColors:
- """A smart container for color based materials.
-
- This class is a wrapper around a dictionary mapping color indicies to materials.
- When called with a color index it returns a material corrisponding 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, map):
- """Expects a dictionary mapping layer names to color idices."""
- self.map = map
- self.colors = {}
-
-
- 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 not color:
- color = 0
- if type(color) == str: # Layer name
- try:
- color = self.map[color].color # color = layer_map[name].color
- except KeyError:
- layer = Layer(name=color, color=0, frozen=False)
- self.map[color] = layer
- color = 0
- color = abs(color)
- if color not in self.colors.keys():
- self.add(color)
- return self.colors[color]
-
-
-
-
- def add(self, color):
- """Create a new material using the provided color index."""
- global color_map
- mat = Material.New('ColorIndex-%s' %color)
- mat.setRGBCol(color_map[color])
- mat.setMode("Shadeless", "Wire")
- self.colors[color] = 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 corrisponding 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 pair to its dict and returns
- the block.
- """
-
- def __init__(self, map, settings):
- """Expects a dictionary mapping block names to block objects."""
- self.map = map
- self.settings = settings
- self.blocks = {}
-
-
- def __call__(self, name=None):
- """Return the data block associated with name.
-
- If no name is provided return self.blocks.
- """
- if not name:
- return self.blocks
- if name not in self.blocks.keys():
- self.add(name)
- return self.blocks[name]
-
-
-
- def add(self, name):
- """Create a new block group for the block with name."""
- write = self.settings.write
- group = Group.New(name)
- block = self.map[name]
- write("\nDrawing %s block entities..." %name)
- drawEntities(block.entities, self.settings, group)
- write("Done!")
- self.blocks[name] = 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, drawing, curves, optimization, **kwds):
- """Given the drawing initialize all the important settings used by the draw functions."""
- self.curves = curves
- self.optimization = optimization
- print "Setting optimization level %s!" %optimization
- self.drawTypes = kwds
- self.layers = True
- self.blocks = True
-
- # First sort out all the sections
- sections = dict([(item.name, item) for item in drawing.data])
-
- # The header section may be omited
- if 'header' in sections.keys():
- self.write("Found header!")
- else:
- self.write("File contains no header!")
-
- # The tables section may be partialy or completely missing.
- if 'tables' in sections.keys():
- self.write("Found tables!")
- tables = dict([(item.name, item) for item in sections["tables"].data])
- if 'layer' in tables.keys():
- self.write("Found layers!")
- # Read the layers table and get the layer colors
- self.colors = getLayers(drawing)
- else:
- self.write("File contains no layers table!")
- self.layers = False
- self.colors = MatColors({})
- else:
- self.write("File contains no tables!")
- self.write("File contains no layers table!")
- self.layers = False
- self.colors = MatColors({})
-
- # The blocks section may be omited
- if 'blocks' in sections.keys():
- self.write("Found blocks!")
- # Read the block definitions and build our block object
- if self.drawTypes['blocks']:
- self.blocks = getBlocks(drawing, self)
- else:
- self.write("File contains no blocks!")
- self.drawTypes['blocks'] = False
- def write(self, text, newline=True):
- """Wraps the built-in print command in a optimization check."""
- if self.optimization <= self.MID:
- if newline:
- print text
- else:
- print text,
-
- def redraw(self):
- """Update Blender if optimization level is low enough."""
- if self.optimization <= self.MIN:
- Blender.Redraw()
-
-
- def progress(self, done, text):
- """Wrapper for Blender.Window.DrawProgressBar."""
- if self.optimization <= self.PRO:
- Window.DrawProgressBar(done, text)
-
-
- def isOff(self, name):
- """Given a layer name look up the layer object and return its visable status."""
- # colors are negative if layer is off
- try:
- layer = self.colors.map[name]
- except KeyError:
- return False
-
- if layer.frozen or layer.color < 0:
- return True
- else:
- return False
-
-
-
-
-def main(filename=None):
- editmode = Window.EditMode() # are we in edit mode? If so ...
- if editmode: Window.EditMode(0) # leave edit mode before
- Window.WaitCursor(True) # Let the user know we are thinking
-
- try:
- if not filename:
- print "DXF import: error, no file selected. Attempting to load default file."
- try:
- filename = Sys.expandpath(r".\examples\big-test.dxf")
- except IOError:
- print "DXF import: error finding default test file, exiting..."
- return None
- drawing = readDXF(filename, objectify)
- drawDrawing(drawing)
- finally:
- # restore state even if things didn't work
- 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."""
- # world x, y, and z axis
- wx = WORLDX
- wy = Mathutils.Vector((0,1,0))
- wz = Mathutils.Vector((0,0,1))
-
- #decide if we need to transform our coords
- if az[0] == 0 and az[1] == 0:
- return False
- # elif abs(az[0]) < 0.0001 or abs(az[1]) < 0.0001:
- # return False
- 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 = Mathutils.CrossVecs(wy, az)
- else:
- ax = Mathutils.CrossVecs(wz, az)
- ax = ax.normalize()
- ay = Mathutils.CrossVecs(az, ax)
- ay = ay.normalize()
- return ax, ay, az
-
-def transform(normal, 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.
- """
- ocs = getOCS(normal)
- if ocs:
- #print ocs
- x, y, z = ocs
- x = x.resize4D()
- y = y.resize4D()
- z = -z.resize4D()
- x.w = 0
- y.w = 0
- z.w = 0
- o = Mathutils.Vector(obj.loc)
- o = o.resize4D()
- mat = Mathutils.Matrix(x, y, z, o)
- obj.setMatrix(mat)
-
-def getLayers(drawing):
- """Build a dictionary of name:color pairs for the given drawing."""
- tables = drawing.tables
- for table in tables.data:
- if table.name == 'layer':
- layers = table
- break
- map = {}
- for item in layers.data:
- if type(item) != list and item.type == 'layer':
- map[item.name] = item
- colors = MatColors(map)
- return colors
-def getBlocks(drawing, settings):
- """Build a dictionary of name:block pairs for the given drawing."""
- map = {}
- for item in drawing.blocks.data:
- if type(item) != list and item.type == 'block':
- try:
- map[item.name] = item
- except KeyError:
- # annon block
- print "Cannot map %s - %s!" %(item.name, item)
- blocks = Blocks(map, settings)
- return blocks
-def drawDrawing(drawing):
- """Given a drawing object recreate the drawing in Blender."""
- print "Getting settings..."
- Window.WaitCursor(False)
- #width, height = Window.GetScreenSize()
- Window.SetMouseCoords()
-
- # Create a PupBlock to get user preferences
- lines = Draw.Create(1)
- arcs = Draw.Create(1)
- circles = Draw.Create(1)
- polylines = Draw.Create(1)
- text = Draw.Create(1)
- blocks = Draw.Create(1)
- faces = Draw.Create(1)
- optim = Draw.Create(1)
-
- block = []
- block.append("Draw Options:")
- block.append(("Lines", lines, "Toggle drawing of lines"))
- block.append(("Arcs", arcs, "Toggle drawing of arcs"))
- block.append(("Circles", circles, "Toggle drawing of circles"))
- block.append(("Polylines", polylines, "Toggle drawing of polylines"))
- block.append(("Text", text, "Toggle drawing of text"))
- block.append(("Blocks", blocks, "Toggle drawing of blocks"))
- block.append(("Faces", faces, "Toggle drawing of faces"))
- block.append("Update Optimization:")
- block.append(("Level: ", optim, 0, 3))
-
- retval = Draw.PupBlock("DXF Import", block)
-
- Window.WaitCursor(True) # Let the user know we are thinking
- # The settings object controls how dxf entities are drawn
- settings = Settings(drawing, curves=False,
- optimization=int(optim.val),
- lines=bool(lines.val),
- arcs=bool(arcs.val),
- circles=bool(circles.val),
- polylines=bool(polylines.val),
- text=bool(text.val),
- blocks=bool(blocks.val),
- faces=bool(faces.val)
- )
-
- settings.write("Drawings entities...")
- # Draw all the know entity types in the current scene
- drawEntities(drawing.entities, settings)
-
- # Set the visable layers
- SCENE.setLayers([i+1 for i in range(18)])
- Blender.Redraw(-1)
- settings.write("Done!")
-
-
-def drawEntities(entities, settings, group=None):
- """Draw every kind of thing in the entity list.
-
- If provided 'group' is the Blender group new entities are to be added to.
- """
- for _type in type_map.keys():
- # for each known type get a list of that type and call the associated draw function
- drawer(_type, entities.get_type(_type), settings, group)
-
-
-def drawer(_type, entities, settings, group):
- """Call with a list of entities and a settings object to generate Blender geometry."""
- if entities:
- # Break out early if settings says we aren't drawing the current type
- block = False
- skip = False
- if _type == 'block_record':
- skip = True
- if _type == 'line' and not settings.drawTypes['lines']:
- skip = True
- elif _type == 'arc' and not settings.drawTypes['arcs']:
- skip = True
- elif _type == 'circle' and not settings.drawTypes['circles']:
- skip = True
- elif _type in ['lwpolyline', 'polyline'] and not settings.drawTypes['polylines']:
- skip = True
- elif _type in ['text', 'mtext'] and not settings.drawTypes['text']:
- skip = True
- elif _type == 'insert':
- if not settings.drawTypes['blocks']:
- skip = True
- block = True
- elif _type == '3dface' and not settings.drawTypes['faces']:
- skip = True
- if skip:
- settings.write("Skipping %s type entities!" %_type)
- return
-
- message = "Drawing %ss..." %_type
- settings.write(message, False)
- settings.progress(0, message)
-
- if block:
- # create one 'handle' data block to use with all blocks
- handle = Mesh.New('insert')
- handle.verts.extend(
- [(-0.01,0,0),
- (0.01,0,0),
- (0,-0.01,0),
- (0,0.01,0),
- (0,0,-0.01),
- (0,0,0.01)]
- )
- handle.edges.extend([(0,1),(2,3),(4,5)])
-
- # For now we only want model-space objects
- entities = [entity for entity in entities if entity.space == 0]
-
- if group:
- block_def = True
- else:
- block_def = False
-
- tot = len(entities)
- cur = 1.0
- for entity in entities:
- settings.write('\b.', False)
- settings.progress(cur/tot, message)
- cur += 1
-
- # First get the layer group
- if not block_def:
- group = getGroup('layer %s' %entity.layer) # add overhead just to make things a little cleaner
-
- if block:
- ob = entity.draw(handle, settings)
- else:
- ob = entity.draw(settings.curves)
-
- setColor(entity, ob, settings)
- # Link it to the scene and add it to the correct group
- SCENE.link(ob)
- setGroup(group, ob)
-
- # Set the visability
- if settings.isOff(entity.layer):
- ob.layers = [20]
- elif block_def:
- ob.layers = [19]
- else:
- ob.layers = [i+1 for i in range(20)]
-
- # # Set the visability
- # if settings.isOff(entity.layer) or block_def:
- # ob.restrictDisplay = True
- # ob.restrictRender = True
-
- settings.redraw()
- message = "\nFinished drawing %ss!" %entities[0].type
- settings.write(message)
- settings.progress(1, message)
-
-
-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 setColor(entity, ob, settings):
- # Set the color
- if entity.color_index == BYLAYER:
- mat = settings.colors(entity.layer)
- else:
- mat = settings.colors(entity.color_index)
- try:
- ob.setMaterials([mat])
- except ValueError:
- settings.write("material error - %s!" %mat)
- ob.colbits = 0x01 # Set OB materials.
-def setGroup(group, it):
- try:
- group.objects.link(it)
- except:
- group.objects.append(it)
-
-def solveBulge(p1, p2):
- """return the center, radius, start angle, and end angle given two points.
-
- 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 = start angle + angle of arc
- """
- bulge = p1.bulge
- p2 = Mathutils.Vector(p2.loc)
- p1 = Mathutils.Vector(p1.loc)
- cord = p2 - p1 # vector from p1 to p2
- clength = cord.length
- s = (bulge * clength)/2 # sagitta (height)
- radius = abs(((clength/2)**2 + s**2)/(2*s)) # magic formula
- angle = abs(degrees(4*atan(bulge))) # theta (included angle)
- delta = (180 - angle)/2 # the angle from cord to center
- if bulge > 0:
- delta = -delta
- radial = cord.normalize() * radius # a radius length vector aligned with cord
- rmat = Mathutils.RotationMatrix(delta, 3, 'Z')
- center = p1 + (rmat * radial) # rotate radial by delta degrees, then add to p1 to find center
- if bulge < 0:
- sv = (p1 - center) # start from point 2
- else:
- sv = (p2 - center) # start from point 1
- start = Mathutils.AngleBetweenVecs(sv, WORLDX) # start angle is the angle between the first leg of the section and the x axis
- # The next bit is my cludge to figure out if start should be negative
- rmat = Mathutils.RotationMatrix(start, 3, 'Z')
- rstart = rmat * sv
- if Mathutils.AngleBetweenVecs(rstart, WORLDX) < start:
- start = -start
- # the end angle is just 'angle' more than start angle
- end = start + angle
- return list(center), radius, start, end
-def drawArc(center, radius, start, end, step=0.5):
- """Draw a mesh arc with the given parameters."""
- # center is currently set by object
-
- # if start > end:
- # start = start - 360
- if end > 360:
- end = end%360
- 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))
- points = [startpoint]
-
- if end < start:
- end +=360
-
- delta = end - start
- length = radians(delta) * radius
- if radius < step*10: # if circumfrance is too small
- pieces = int(delta/10) # set a fixed step of 10 degrees
- else:
- pieces = int(length/step) # figure out how many pieces we need for our arc
- if pieces == 0: # stupid way to avoid a div by zero error
- pieces = 1 # what would be a smarter way to fix this?
- step = delta/pieces # set step so pieces * step = degrees in arc
-
- stepmatrix = Mathutils.RotationMatrix(step, 3, "Z")
- point = Mathutils.Vector(startpoint)
- for i in range(int(pieces)):
- point = stepmatrix * point
- points.append(point)
- points.append(endpoint)
-
- if center:
- points = [[point[0]+center[0], point[1]+center[1], point[2]+center[2]] for point in points]
- edges = [[num, num+1] for num in range(len(points)-1)]
-
- return points, edges
-# Here are some alternate drawing functions for creating curve geometery.
-
-def drawCurveCircle(circle):
- """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]
- curve.flagU = 1 # Set curve cyclic
- c.update()
-
- ob = Object.New('Curve', 'circle') # make curve object
- return ob
-
-def drawCurveArc(arc):
- """Given a dxf circle object return a blender circle object using curves."""
- if start > end:
- start = start - 360
- 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
-
- 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 = a.appendNurb(p1)
- curve.append(p2)
- curve.append(p3)
- curve.append(p4)
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- curve.flagU = 1 # Set curve cyclic
- a.update()
-
- ob = Object.New('Curve', 'arc') # make curve object
- return ob
+
+
+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 Bspline-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.splin2): #correct for real NURBS-import
+ #if (v.spline and not curves_on) or (curves_on and not v.splin2): #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, layersmap):
+ """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 layersmap: color = layersmap[color].color
+ if color == 256: # color 0 = 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, layersmap):
+ """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:
+ drawEntities(block.entities, self.settings, block_def)
+ 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['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.
+ """
+
+ #de: paßt die distance parameter an 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(layersmap)
+ self.layMaterials = MatLayers(layersmap)
+ else:
+ self.write("File contains no table:layers!")
+
+
+ if views: #----------------------------------
+ if self.var['views_on']:
+ global oblist
+ 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']:
+ global oblist
+ 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, self.obj_number = getBlocksmap(drawing, layersmap, self.var['layFrozen_on'])
+ 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)
+ #print 'deb:settings_valid self.obj_number', self.obj_number #----------
+ 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 = Blender.sys.time() #time marker1
+ drawing = readDXF(dxfFile, objectify)
+ print 'finish reading in %.4f sec.' % (Blender.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 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
+ 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:
+ #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 = Blender.sys.time() #time marker1
+ drawing = readDXF(dxfFile, objectify)
+ print 'reading finished in %.4f sec.' % (Blender.sys.time()-time1)
+ Window.WaitCursor(False)
+ 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
+ global oblist
+ oblist = [] # a list of all created AND linked objects for final f_globalScale
+ time2 = Blender.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
+
+ drawEntities(drawing.entities, settings)
+
+ #print 'deb:drawEntities after: oblist:', oblist #-----------------------
+ 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 = Blender.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 = Mathutils.CrossVecs(WORLDY, az)
+ else:
+ ax = Mathutils.CrossVecs(WORLDZ, az)
+ ax = ax.normalize()
+ ay = Mathutils.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(layers): #------------------------------------------------------
+ """Build two dictionaries: 1.layername:layer object, and 2.layername:layername_short
+ """
+ layersmap = {}
+ layernamesmap = {}
+ for item in layers.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)
+ 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 map "%s" - "%s" as Block!' %(item.name, item)
+ #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: pass
+
+ 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
+ usedblocks[child[0]][0] = True # marked as used BLOCK
+
+ 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'.
+ """
+ #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]
+
+ # 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'] and entity.name.startswith('*X'): #---- support for noname BLOCKs
+ #print 'deb:drawer entity.name:', entity.name #------------
+ continue
+ elif 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 and 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 = 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]
+ 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]
+ curve.flagU = 1 # Set curve cyclic
+ a.update()
+
+ ob = Object.New('Curve', 'arc') # make curve object
+ return ob
+
+
+
+
+# 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_PRESETCURV = 10
+EVENT_PRESETS = 11
+EVENT_DXF_DIR = 12
+EVENT_DXF_NAME = 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|curve %x5"
+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|curve %x5"
+plines3_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|curve %x5"
+plmesh_as_menu = "convert to: %t|*edge %x1|mesh %x2"
+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,
+ '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,
+ 'pl_3d' : 1,
+ '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,
+ '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,
+ '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,
+ '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 #---------------
+# 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):
+ try:
+ f = file(iniFile, 'r')
+ try: header_str = f.readline()
+ finally: f.close()
+ except: pass
+ 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')
+ try:
+ f.write(INIFILE_HEADER + '\n# this is a comment line\n')
+ f.write(output_str)
+ finally: 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):
+ try:
+ f = file(iniFile, 'r')
+ try:
+ 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:
+ Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile)
+ finally: f.close()
+ except: pass
+ 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(): #-----------------------------------------------
+ """Sets settings/config/materials for curve representation.
+
+ """
+ global GUI_A
+ if 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['plines3_as'].val = 5
+ else:
+ 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['plines3_as'].val = 2
+
+
+def resetDefaultConfig_2D(): #-----------------------------------------------
+ """Sets settings/config/materials to defaults 2D.
+
+ """
+# presetConfig_curv()
+ 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,
+ 'pl_3d' : 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,
+ 'plmesh': 0,
+ 'pline3': 0,
+ '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()
+ keywords3d = {
+ 'vGroup_on' : 1,
+ 'thick_on' : 1,
+ 'thick_force': 0,
+ 'width_on' : 1,
+ 'width_force': 0,
+ 'dist_on' : 1,
+ 'dist_force': 0,
+ 'pl_3d' : 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,
+ 'plmesh': 1,
+ 'pline3': 1,
+ 'lwpolyline': 1,
+ 'text' : 1,
+ '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
+
+ # 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 = 80
+ 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-Importer ver." + __version__, but0c, y, menu_w, 20)
+
+ if config_UI.val:
+ b0, b0_ = but0c, but_0c + butt_margin
+ b1, b1_ = but1c, but_1c
+ 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, "(*wip)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['polyline'] = Draw.Toggle('2D-PLINE', 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 -= 10
+ y -= 20
+ 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 -= 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 -= 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/arcsegments on/off")
+ GUI_A['pl_trim_on'] = Draw.Toggle('trim', EVENT_NONE, b1-20, y, 32, 20, GUI_A['pl_trim_on'].val, "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, "limit for 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['curves_on'] = Draw.Toggle('to Curves', EVENT_PRESETCURV, b0, y, b0_, 20, GUI_A['curves_on'].val, "import into curves instead into meshes on/off")
+ GUI_A['curve_arc'] = Draw.Number('', EVENT_NONE, b1, y, b1_/2, 20, GUI_A['curve_arc'].val, 3, 32, "Bezier circle: amount of segments: 3-32")
+ GUI_A['curve_res'] = Draw.Number('', EVENT_NONE, b1+b1_/2, y, b1_/2, 20, GUI_A['curve_res'].val, 1, 128, "Set the Curve's U-resolution value: 1-128")
+ Draw.EndAlign()
+
+ y -= 20
+ GUI_A['group_bylayer_on'] = Draw.Toggle('Lay', EVENT_NONE, b0, y, 30, 20, GUI_A['group_bylayer_on'].val, "grouping entities from the same layer on/off")
+ GUI_A['vGroup_on'] = Draw.Toggle('vGroups', EVENT_NONE, b0+30, y, b1_-10, 20, GUI_A['vGroup_on'].val, "support Blender-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['paper_space_on'] = Draw.Toggle('paper space', EVENT_NONE, b0, y, b0_+20, 20, GUI_A['paper_space_on'].val, "import only layout (paper space) on/off")
+ GUI_A['layFrozen_on'] = Draw.Toggle('frozen', EVENT_NONE, b1+20, y, b1_-20, 20, GUI_A['layFrozen_on'].val, "import also from frozen layers 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()
+
+ y_down = y
+ # -----------------------------------------------
+ y = simple_menu_h + extend_menu_h +20
+ b0, b0_ = but2c, but_2c + butt_margin
+ b1, b1_ = but3c, but_3c
+
+ y -= 20
+ Draw.BeginAlign()
+ GUI_B['plmesh'] = Draw.Toggle('POLY-MESH/FACE', EVENT_NONE, b0, y, b0_+b1_, 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")
+ Draw.EndAlign()
+
+ y -= 20
+ Draw.BeginAlign()
+ 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")
+ Draw.EndAlign()
+ #print 'deb:support solid, trace', GUI_B['trace'].val, GUI_B['solid'].val # ------------
+
+
+ y -= 20
+ Draw.BeginAlign()
+ 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, "(*wip)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")
+ Draw.EndAlign()
+
+ 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['blockFilter_on'] = Draw.Toggle('F', EVENT_NONE, b1-15, y, 15, 20, GUI_A['blockFilter_on'].val, "(*wip) support name filtering of BLOCKs on/off")
+ GUI_A['xref_on'] = Draw.Toggle('Xref', EVENT_NONE, b1, y, 20, 20, GUI_A['xref_on'].val, "support place holder for XREF-BLOCKs 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
+ 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, "(*wip) 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, "(*wip) support AVE_RENDER lights on/off")
+ Draw.EndAlign()
+
+ y -= 10
+ y -= 20
+ y -= 20
+ y -= 20
+
+ 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
+ GUI_A['newScene_on'] = Draw.Toggle('newScene', EVENT_NONE, b0, y, b0_, 20, GUI_A['newScene_on'].val, "creates new Blender-Scene for each import on/off")
+ GUI_A['target_layer'] = Draw.Number('layer', EVENT_NONE, b1, y, b1_, 20, GUI_A['target_layer'].val, 1, 18, "imports into this Blender-layer (<19> reserved for block_definitions)")
+
+ #--------------------------------------
+ if y > y_down: y = y_down
+ #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_0c-butt_margin, 20, iniFileName.val, FILENAME_MAX, "write here the name of the INI-file")
+ Draw.EndAlign()
+
+ y -= 20
+ Draw.BeginAlign()
+ Draw.PushButton('#', EVENT_PRESETS, but0c, y, 20, 20, "tipist for Preset-INI-files")
+ Draw.PushButton('Load', EVENT_LOAD_INI, but0c+20, y, but_0c-20, 20, '.Loads configuration from ini-file: %s' % iniFileName.val)
+ Draw.PushButton('Save', EVENT_SAVE_INI, but1c, y, but_1c-20, 20, 'Saves configuration to ini-file: %s' % iniFileName.val)
+ Draw.EndAlign()
+ but_ = (but_2c+but_3c)/4
+ but = but2c
+ Draw.PushButton('reset', EVENT_RESET, but, y, but_, 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')
+ GUI_A['optimization'] = Draw.Number('', EVENT_NONE, but4c-35, y, 35, 20, GUI_A['optimization'].val, 0, 3, "Optimization Level: 0=Debug/directDrawing, 1=Verbose, 2=ProgressBar, 3=silentMode/fastest")
+
+
+ y = simple_menu_h
+ Draw.BeginAlign()
+ Draw.PushButton('DXFfile >', EVENT_CHOOSE_DXF, but0c, y, but_0c, 20, 'Select DXF-file from project directory')
+ dxfFileName = Draw.String(' :', EVENT_NONE, but1c, y, but_1c+but_2c+but_3c-20, 20, dxfFileName.val, FILENAME_MAX, "type the name of DXF-file or type *.dxf for multi-import")
+ Draw.PushButton('*.*', EVENT_DXF_DIR, but3c+but_3c-20, y, 20, 20, 'Set asterisk * as filter')
+ Draw.EndAlign()
+
+
+ y -= 50
+ Draw.BeginAlign()
+ Draw.PushButton('EXIT', EVENT_EXIT, but0c, y, but_0c, 40, '' )
+ Draw.PushButton('HELP', EVENT_HELP, but1c, y, but_1c-20, 20, 'calls BlenderWiki for Manual, Updates and Support.')
+ Draw.PushButton('?', EVENT_LIST, but1c+but_1c-20, y, 20, 20, 'DXF analyze tool: print listing of LAYERs and BLOCKs into the text file .INF')
+ Draw.PushButton('START IMPORT', EVENT_START, but2c, y, but_2c+but_3c+butt_margin, 40, 'Start the import procedure')
+ Draw.EndAlign()
+
+ config_UI = Draw.Toggle('CONFIG', EVENT_REDRAW, but1c-butt_margin/2, y+20, but_1c+butt_margin, 20, config_UI.val, 'Advanced configuration on/off' )
+
+ y -= 20
+ Draw.BeginAlign()
+ Draw.Label(' ', but0c-menu_margin, y, menu_margin, 20)
+ Draw.Label("*) parts under construction", 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
+ 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 event(evt, val):
+ if evt in (Draw.QKEY, Draw.ESCKEY) and not val:
+ Blender.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
+
+ ######### Manages GUI events
+ if (evt==EVENT_EXIT):
+ Blender.Draw.Exit()
+ print 'DXF-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()
+ 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
+ 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['newScene_on'].val = 1
+ Draw.Redraw()
+# elif (evt==EVENT_DXF_NAME):
+# dirname == Blender.sys.dirname(Blender.Get('filename'))
+# update_RegistryKey('DirName', dirname)
+# #print 'deb:EVENT_DXF_NAME dxfFileName.val:', dxfFileName.val #--------------
+# update_RegistryKey('dxfFileName', dxfFileName.val)
+ 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 #----------------------
+ update_RegistryKey('dxfFileName', dxfFileName.val)
+ if dxfFile.lower().endswith('*.dxf'):
+ if Draw.PupMenu('DXF importer: OK?|will import all DXF-files from:|%s' % dxfFile) == 1:
+ global UI_MODE
+ UI_MODE = False
+ multi_import(dxfFile[:-5]) # cut last 5 characters '*.dxf'
+ Draw.Redraw()
+ #Draw.Exit()
+ else:
+ Draw.Redraw()
+ elif dxfFile.lower().endswith('.dxf') and sys.exists(dxfFile):
+ 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: Alert!%t|no valid DXF-file selected!')
+ print "DXF importer: error, no valid DXF-file selected! try again"
+ Draw.Redraw()
+
+
+
+
+def multi_import(DIR):
+ """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 = \
+ [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 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' % (Blender.sys.time() - batchTIME)
+ print '\a\r', # beep when done
+
+
if __name__ == "__main__":
- Window.FileSelector(main, 'Import a DXF file', '*.dxf')
+ 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 = Blender.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= Blender.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' % (Blender.sys.time() - TIME)
+""" \ No newline at end of file
diff --git a/release/scripts/import_mdd.py b/release/scripts/import_mdd.py
index 8e7b9985d3d..1ee196ab67f 100644
--- a/release/scripts/import_mdd.py
+++ b/release/scripts/import_mdd.py
@@ -1,11 +1,11 @@
#!BPY
- #"""
- #Name: 'Load MDD to Mesh RVKs'
- #Blender: 242
- #Group: 'Import'
- #Tooltip: 'baked vertex animation to active mesh object.'
- #"""
+"""
+ 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.
diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py
index 753d8816ff9..e5bdc796e16 100644
--- a/release/scripts/import_obj.py
+++ b/release/scripts/import_obj.py
@@ -535,13 +535,16 @@ def get_float_func(filepath):
find the float function for this obj file
- weather to replace commas or not
'''
- file= open(filepath, 'r')
+ file= open(filepath, 'rU')
for line in file: #.xreadlines():
if line.startswith('v'): # vn vt v
if ',' in line:
return lambda f: float(f.replace(',', '.'))
elif '.' in line:
return float
+
+ # incase all vert values were ints
+ 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, IMAGE_SEARCH=True):
'''
diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py
index 63506a6dc1a..2049fbd2380 100644
--- a/release/scripts/lightwave_import.py
+++ b/release/scripts/lightwave_import.py
@@ -656,7 +656,12 @@ def read_clip(lwochunk, dir_part):
# ima, IMAG, g_IMAG refers to clip dictionary 'ID' entries: refer to blok and surf
clip_dict = {}
data = cStringIO.StringIO(lwochunk.read())
- image_index, = struct.unpack(">L", data.read(4))
+ 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):
@@ -693,7 +698,7 @@ def read_clip(lwochunk, dir_part):
i = i + 6 + subchunklen
#end loop on surf chunks
###if DEBUG: print "read image:%s" % clip_dict
- if clip_dict.has_key('XREF'):
+ if 'XREF' in clip_dict: # has_key
###if DEBUG: print "Cross-reference: no image pre-allocated."
return clip_dict
#look for images
@@ -985,7 +990,8 @@ def read_surfs(lwochunk, surf_list, tag_list):
if uvname: # != "":
my_dict['UVNAME'] = uvname #theoretically there could be a number of them: only one used per surf
- if not(my_dict.has_key('g_IMAG')) and (rr.has_key('CHAN')) and (rr.has_key('OPAC')) and (rr.has_key('IMAG')):
+ # 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
@@ -1005,40 +1011,6 @@ def read_surfs(lwochunk, surf_list, tag_list):
###if DEBUG: print "-> Material pre-allocated."
return my_dict
-
-
-def reduce_face(verts, face):
- TriangleArea= Blender.Mathutils.TriangleArea
- Vector= Blender.Mathutils.Vector
- ####if DEBUG: print len(face), face
- # wants indicies local to the face
- len_face= len(face)
- if len_face==3:
- return [face]
- elif len_face==4:
- vecs= [Vector(verts[i]) for i in face]
- # Get the convave quad area
- a1= TriangleArea(vecs[0], vecs[1], vecs[2])
- a2= TriangleArea(vecs[0], vecs[2], vecs[3])
-
- a3= TriangleArea(vecs[0], vecs[1], vecs[3])
- a4= TriangleArea(vecs[1], vecs[2], vecs[3])
-
- if abs((a1+a2) - (a3+a4)) < (a1+a2+a3+a4)/100: # Not convace
- ####if DEBUG: print 'planer'
- return [[0,1,2,3]]
- if a1+a2<a3+a4:
- return [[0,1,2], [0,2,3]]
- else:
- return [[0,1,3], [1,2,3]]
-
- else: # 5+
- ####if DEBUG: print 'SCANFILL...', len(face)
- ngons= BPyMesh.ngon(verts, face, PREF_FIX_LOOPS= True)
- return ngons
-
-
-
# =========================
# === Recalculate Faces ===
# =========================
@@ -1109,7 +1081,7 @@ def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not
pass
msh.mode |= Blender.Mesh.Modes.AUTOSMOOTH #smooth it anyway
- if surf.has_key('SMAN'):
+ 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
@@ -1119,12 +1091,8 @@ def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not
except:
img= None
-
#uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])) and (img != None))
- uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])))
-
-
-
+ uv_flag = (('UVNAME' in surf) and (surf['UVNAME'] in uvcoords_dict))
###if DEBUG: print "\n#===================================================================#"
###if DEBUG: print "Processing Object: %s" % objname
@@ -1186,55 +1154,50 @@ def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not
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:
- rev_face = (cur_face[2], cur_face[1], cur_face[0])
+ 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 > 3:
- meta_faces= reduce_face(complete_vertlist, cur_face) # Indices of triangles
+ elif numfaceverts > 4:
+ meta_faces= BPyMesh.ngon(complete_vertlist, cur_face, PREF_FIX_LOOPS= True)
edge_face_count = {}
for mf in meta_faces:
- # ###if DEBUG: print 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 len(mf) == 3: #triangle
- 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 i in xrange(3):
- v1= mf[i]
- v2= mf[i-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 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
- else: #quads
- mf= cur_face[mf[3]], 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 edge_face_count:
edges_fgon.extend( [vert_key for vert_key, count in edge_face_count.iteritems() if count] )
-
- msh.edges.extend(edges)
+ if edges:
+ msh.edges.extend(edges)
+
face_mapping_removed = msh.faces.extend(face_data, indexList=True)
- if surf.has_key('TRAN') or (mat and mat.alpha<1.0): # incase mat is null
+ if 'TRAN' in surf or (mat and mat.alpha<1.0): # incase mat is null
transp_flag = True
else:
transp_flag = False
@@ -1347,7 +1310,7 @@ def create_objects(clip_list, objspec_list, surf_list):
def lookup_imag(clip_list, ima_id):
for ii in clip_list:
if ii and ii['ID'] == ima_id:
- if ii.has_key('XREF'):
+ if 'XREF' in ii: # has_key
#cross reference - recursively look for images
return lookup_imag(clip_list, ii['XREF'])
else:
@@ -1415,7 +1378,7 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos):
#if not blok['ENAB']:
# ###if DEBUG: print "***Image is not ENABled! Quitting this block"
# break
- if not(blok.has_key('IMAG')):
+ 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 ....
@@ -1434,13 +1397,13 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos):
tname += "+"
else:
tname += "x" #let's signal when should not be enabled
- if blok.has_key('CHAN'):
+ 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 blok.has_key('WRAP'):
+ if 'WRAP' in blok: # has_key
if (blok['WRAP'] == 3) or (blok['WRAP'] == 2):
newtex.setExtend('Extend')
elif (blok['WRAP'] == 1):
@@ -1457,35 +1420,35 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos):
nega = False
mapflag = Blender.Texture.MapTo.COL #default to color
maptype = Blender.Texture.Mappings.FLAT
- if blok.has_key('CHAN'):
- if blok['CHAN'] == 'COLR' and blok.has_key('OPACVAL'):
+ 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 blok.has_key('OPACVAL'): norfac = blok['OPACVAL']
+ 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 blok.has_key('OPACVAL'): dvar = blok['OPACVAL']
+ 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 blok.has_key('OPACVAL'): dvar = blok['OPACVAL']
+ 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 blok.has_key('OPACVAL'): dvar = blok['OPACVAL']
+ 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 blok.has_key('OPACVAL'): dvar = blok['OPACVAL']
+ if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
alphaflag = 1
nega = True
- if blok.has_key('NEGA'):
+ if 'NEGA' in blok: # has_key
###if DEBUG: print "!!!Watch-out: effect of this texture channel must be INVERTED!"
nega = not nega
@@ -1498,7 +1461,7 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos):
'Texture Displacement',
'Additive']
set_blendmode = 7 #default additive
- if blok.has_key('OPAC'):
+ if 'OPAC' in blok: # has_key
set_blendmode = blok['OPAC']
if set_blendmode == 5: #transparency
newtex.imageFlags |= Blender.Texture.ImageFlags.CALCALPHA
@@ -1509,7 +1472,7 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos):
axis = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z]
size = [1.0] * 3
ofs = [0.0] * 3
- if blok.has_key('PROJ'):
+ if 'PROJ' in blok: # has_key
if blok['PROJ'] == 0: #0 - Planar
###if DEBUG: print "!!!Flat projection"
coordflag = Blender.Texture.TexCo.ORCO
@@ -1598,44 +1561,44 @@ def update_material(clip_list, objspec, surf_list):
break
#mat = Blender.Material.New(surf['NAME'])
#surf['g_MAT'] = mat
- if surf.has_key('COLR'):
+ if 'COLR' in surf: # has_key
mat.rgbCol = surf['COLR']
- if surf.has_key('LUMI'):
+ if 'LUMI' in surf:
mat.setEmit(surf['LUMI'])
- if surf.has_key('GVAL'):
+ if 'GVAL' in surf: # has_key
mat.setAdd(surf['GVAL'])
- if surf.has_key('SPEC'):
- 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 surf.has_key('DIFF'):
- mat.setRef(surf['DIFF']) #lwo [0.0, 1.0] - blender [0.0, 1.0]
- if surf.has_key('GLOS'): #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 '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 surf.has_key('TRNL'):
+ 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.getMode()
+ mm = mat.mode
mm |= Blender.Material.Modes.TRANSPSHADOW
- if surf.has_key('REFL'):
+ 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 surf.has_key('TRAN'):
+ 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 surf.has_key('RIND'):
+ 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 surf.has_key('BLOK') and surf['BLOK'] != []:
+ 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.setMode(mm)
+ mat.mode = mm
#finished setting up the material
#end if exist SURF
#end loop on materials (SURFs)
@@ -1679,9 +1642,10 @@ def main():
if __name__=='__main__':
main()
-"""
-# Cams debugging lwo loader
+
+# Cams debugging lwo loader
+"""
TIME= Blender.sys.time()
import os
print 'Searching for files'
@@ -1690,6 +1654,12 @@ os.system('find /fe/lwo/Objects/ -follow -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):
@@ -1706,8 +1676,9 @@ for i, _lwo in enumerate(lines):
#if between(i, 525, 550):
#if i > 1635:
#if i != 1519: # 730
- if i>125:
- _lwo= _lwo[:-1]
+ 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)
diff --git a/release/scripts/mesh_edges2curves.py b/release/scripts/mesh_edges2curves.py
index fdf61298ebc..f65eccae9a4 100644
--- a/release/scripts/mesh_edges2curves.py
+++ b/release/scripts/mesh_edges2curves.py
@@ -12,7 +12,7 @@ __version__ = "1.0 2006/02/08"
__bpydoc__ = """\
Edges to Curves
-This script converts open and closed edge loops into polylines
+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.
@@ -39,17 +39,8 @@ Supported:<br>
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-
from Blender import *
-def edkey(ed):
- i1 = ed.v1.index
- i2 = ed.v2.index
- if i1>i2:
- return (i2,i1), ed
- else:
- return (i1,i2), ed
-
def polysFromMesh(me):
# a polyline is 2
#polylines are a list
@@ -138,6 +129,7 @@ def mesh2polys():
v= poly[vIdx]
cu.appendNurb([v.co.x, v.co.y, v.co.z, w, t])
+ vIdx += 1
cu[i].type= 0 # Poly Line
# Close the polyline if its closed.
diff --git a/release/scripts/mesh_skin.py b/release/scripts/mesh_skin.py
index fdb721bc9f3..a554e128b41 100644
--- a/release/scripts/mesh_skin.py
+++ b/release/scripts/mesh_skin.py
@@ -628,7 +628,7 @@ def main():
try: me.faces.delete(1, [ f for f in me.faces if f.sel ])
except: pass
- me.faces.extend(faces)
+ me.faces.extend(faces, smooth = True)
print '\nSkin done in %.4f sec.' % (Blender.sys.time()-time1)
diff --git a/release/scripts/mesh_unfolder.py b/release/scripts/mesh_unfolder.py
index 8ebf1777c2e..906e0f0a300 100644
--- a/release/scripts/mesh_unfolder.py
+++ b/release/scripts/mesh_unfolder.py
@@ -1,10 +1,10 @@
#!BPY
"""
Name: 'Unfold'
-Blender: 243
+Blender: 245
Group: 'Mesh'
Tip: 'Unfold meshes to create nets'
-Version: v2.2.4
+Version: v2.5
Author: Matthew Chadwick
"""
import Blender
@@ -18,16 +18,18 @@ try:
from math import *
import sys
import random
- from decimal import *
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:
- print "One of the Python modules required can't be found."
- print sys.exc_info()[1]
- traceback.print_exc(file=sys.stdout)
-
+ 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.2.4 24032007'
+__version__ = '2.5 06102007'
__url__ = ["http://celeriac.net/unfolder/", "blender", "blenderartist"]
__email__ = ["post at cele[remove this text]riac.net", "scripts"]
__bpydoc__ = """\
@@ -79,7 +81,7 @@ class FacesAndEdges:
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
+ # 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)):
@@ -107,84 +109,7 @@ class FacesAndEdges:
if(bface!=None):
bface.sel= True
self.nfaces+=1
-
-
-class IntersectionResult:
- def __init__(self, rn, rd, v=None):
- self.v = v
- self.rd = rd
- self.rn = rn
- def intersected(self):
- return not(not(self.v))
- def isParallel(self):
- return (self.rd==0)
- def isColinear(self):
- return (self.rn==0)
- def intersection(self):
- return self.v
-
-# represents a line segment between two points [p1, p2]. the points are [x,y]
-class LineSegment:
- def __init__(self, p):
- self.p = p
- def intersects(self, s):
- rn = ((self.p[0].y-s.p[0].y)*(s.p[1].x-s.p[0].x)-(self.p[0].x-s.p[0].x)*(s.p[1].y-s.p[0].y))
- rd = ((self.p[1].x-self.p[0].x)*(s.p[1].y-s.p[0].y)-(self.p[1].y-self.p[0].y)*(s.p[1].x-s.p[0].x))
- # need an epsilon closeTo() here
- if(rd<0.0000001 or rn==0.0):
- return IntersectionResult(rn,rd)
- r = rn/rd
- s = ((self.p[0].y-s.p[0].y)*(self.p[1].x-self.p[0].x)-(self.p[0].x-s.p[0].x)*(self.p[1].y-self.p[0].y)) / rd
- i = (0.0<=r and r<=1.0 and 0.0<=s and s<=1.0)
- if not(i):
- return None
- ix = self.p[0].x + r*(self.p[1].x - self.p[0].x)
- iy = self.p[0].y + r*(self.p[1].y - self.p[0].y)
- t = 0.0001
- if ( abs(ix-self.p[0].x)>t and abs(iy-self.p[0].x)>t and abs(ix-self.p[1].x)>t and abs(iy-self.p[1].y)>t ):
- return IntersectionResult( rn, rd,Vector([ix,iy,0.0]))
- else:
- return None
-
-class LineSegments:
- def __init__(self, face):
- self.face = face
- def segmentAt(self, i):
- if(i>self.face.nPoints()-1):
- return None
- if(i==self.face.nPoints()-1):
- j = 0
- else:
- j = i+1
- return LineSegment([ self.face.v[i], self.face.v[j] ])
- def iterateSegments(self, something):
- results = []
- for i in xrange(self.face.nPoints()):
- results.extend(something.haveSegment(self.segmentAt(i)))
- return results
- def compareSegments(self, something, segment):
- results = []
- for i in xrange(self.face.nPoints()):
- results.append(something.compareSegments([self.segmentAt(i), segment]))
- return results
-
-class FaceOverlapTest:
- def __init__(self, face1, face2):
- self.faces = [face1, face2]
- self.segments = [ LineSegments(self.faces[0]), LineSegments(self.faces[1]) ]
- def suspectsOverlap(self):
- tests = self.segments[0].iterateSegments(self)
- gi = 0
- for i in tests:
- if( i!=None and i.intersected() ):
- gi+=1
- return gi>0
- def haveSegment(self, segment):
- return self.segments[1].compareSegments(self, segment)
- def compareSegments(self, segments):
- return segments[0].intersects(segments[1])
-
# A fold between two faces with a common edge
class Fold:
@@ -398,7 +323,7 @@ class Net:
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
+ # hmmm. I honestly can't remember why this needs to be done, but it does.
u=0
v=1
w=2
@@ -412,6 +337,7 @@ class Net:
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
@@ -423,6 +349,7 @@ class Net:
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)
@@ -459,11 +386,12 @@ class Net:
for afold in folds:
mdf = afold.unfoldedFace()
if(afold!=fold):
- it1 = FaceOverlapTest(mf, mdf)
- it2 = FaceOverlapTest(mdf, mf)
- overlap = (it1.suspectsOverlap() or it2.suspectsOverlap())
+ # 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( overlap or inside or mdf.overlays(mf)):
+ if( intersects or inside or mdf.overlays(mf)):
c.append(afold)
return c
def getOverlapsBetweenGL(self, fold, folds):
@@ -644,9 +572,9 @@ class Net:
overlaps = self.report()
attempts+=1
return attempts
- def unfoldSelected(feedback=None, netName=None):
+ def fromSelected(feedback=None, netName=None):
return Net.createNet(Blender.Object.GetSelected()[0], feedback, netName)
- unfoldSelected = staticmethod(unfoldSelected)
+ fromSelected = staticmethod(fromSelected)
def clone(self, object=None):
if(object==None):
object = self.object
@@ -823,7 +751,7 @@ class Curvature(EdgeIterator):
g += f.dihedralAngle()
self.gooodness = g
-
+
class Edge:
def __init__(self, v1=None, v2=None, mEdge=None, i=-1):
self.idx = i
@@ -891,6 +819,23 @@ class Edge:
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
@@ -899,6 +844,7 @@ class Poly:
self.v = []
self.id = Poly.ids
self.boundz = None
+ self.edges = None
def getID(self):
return self.id
def normal(self):
@@ -910,6 +856,21 @@ class Poly:
q = a-c
q.resize3D()
return CrossVecs(p,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:
@@ -1031,8 +992,7 @@ class Poly:
def toString(self):
return self.v
# This is the BEST algorithm for point-in-polygon detection.
- # It's by W. Randolph Franklin. It's also very beautiful (looks even better in C).
- # All the others are shite; they give false positives.
+ # It's by W. Randolph Franklin.
# returns 1 for inside, 1 or 0 for edges
def contains(self, tp):
c = 0
@@ -1114,6 +1074,7 @@ class SVGExporter:
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]
@@ -1141,14 +1102,14 @@ class SVGExporter:
self.addPolys()
self.e.endElement("clipPath")
def addUVImage(self):
- image = Blender.Image.GetCurrent()
+ 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()
+ 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
@@ -1242,7 +1203,7 @@ class SVGExporter:
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
@@ -1413,7 +1374,7 @@ class GUI:
while(s):# and search < searchLimit):
if(net!=None):
name = net.des.name
- net = Net.unfoldSelected(self, name)
+ net = Net.fromSelected(self, name)
net.setAvoidsOverlaps(not(self.overlaps.val))
print
print "Unfolding selected object"
@@ -1516,6 +1477,14 @@ class GUI:
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)
@@ -1567,6 +1536,7 @@ class GUI:
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")
@@ -1574,7 +1544,7 @@ class GUI:
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.5, 0.5, 0.5, 1)
+ BGL.glClearColor(0.3, 0.3, 0.3, 1)
BGL.glColor3f(0.3,0.3,0.3)
l.newLine()
BGL.glRasterPos2i(32, 100)
@@ -1601,10 +1571,12 @@ class FlowLayout:
self.y-=self.ch+self.margin
self.x = self.margin
-try:
- sys.setrecursionlimit(10000)
- gui = GUI()
- gui.makeStandardGUI()
- #gui.makePopupGUI()
-except:
- traceback.print_exc(file=sys.stdout)
+# 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
index 35cfa325497..bd38c47a9b9 100644
--- a/release/scripts/mesh_wire.py
+++ b/release/scripts/mesh_wire.py
@@ -44,6 +44,7 @@ from BPyMathutils import angleToLength
import mesh_solidify
import BPyMessages
+reload(BPyMessages)
import bpy
@@ -219,9 +220,7 @@ def solid_wire(ob_orig, me_orig, sce, PREF_THICKNESS, PREF_SOLID, PREF_SHARP, PR
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)
@@ -245,6 +244,18 @@ def main():
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)
@@ -259,16 +270,10 @@ def main():
]
if not Blender.Draw.PupBlock('Solid Wireframe', pup_block):
+ if is_editmode: Window.EditMode(1)
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
@@ -282,4 +287,4 @@ def main():
# This lets you can import the script without running it
if __name__ == '__main__':
- main() \ No newline at end of file
+ main()
diff --git a/release/scripts/object_drop.py b/release/scripts/object_drop.py
index 4ea8bde2ca8..63a0bd574fb 100644
--- a/release/scripts/object_drop.py
+++ b/release/scripts/object_drop.py
@@ -1,7 +1,7 @@
#!BPY
"""
Name: 'Drop Onto Ground'
-Blender: 243
+Blender: 245
Group: 'Object'
Tooltip: 'Drop the selected objects onto "ground" objects'
"""
@@ -221,4 +221,5 @@ def main():
if __name__ == '__main__':
main()
-GLOBALS.clear() \ No newline at end of file
+GLOBALS.clear()
+
diff --git a/release/scripts/object_find.py b/release/scripts/object_find.py
index 4ce93998f00..0cfd6ad1d92 100644
--- a/release/scripts/object_find.py
+++ b/release/scripts/object_find.py
@@ -41,20 +41,27 @@ import BPyMessages
def get_object_images(ob):
# Could optimize this
- if ob.type == 'Mesh':
- unique_images = {}
- me = ob.getData(mesh=1)
- 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
-
- return unique_images.values()
+ 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
+
+ return unique_images.values()
# Todo, support other object types, materials
return []
diff --git a/release/scripts/object_random_loc_sz_rot.py b/release/scripts/object_random_loc_sz_rot.py
index 13c42e859d7..1af0dc7218a 100755..100644
--- a/release/scripts/object_random_loc_sz_rot.py
+++ b/release/scripts/object_random_loc_sz_rot.py
@@ -33,46 +33,67 @@ This script randomizes the selected objects location/size/rotation.
# ***** 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():
- return Rand()-0.5
+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()
+ 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:
- ob.loc = (ob.LocX+(PREF_LOC*rnd()), ob.LocY+(PREF_LOC*rnd()), ob.LocZ+(PREF_LOC*rnd()))
-
+ 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 = 1 + (PREF_SIZE*rnd())
+ rand = PREF_SIZE*rnd("SIZE")
if PREF_X_AXIS: x= rand
- else: x= 1
+ else: x= 0
if PREF_Y_AXIS: y= rand
- else: y= 1
+ else: y= 0
if PREF_Z_AXIS: z= rand
- else: z= 1
- ob.size = (ob.SizeX*x, ob.SizeY*y, ob.SizeZ*z)
+ else: z= 0
+
else:
- if PREF_X_AXIS: x= 1+ PREF_SIZE*rnd()
- else: x= 1
- if PREF_Y_AXIS: y= 1+ PREF_SIZE*rnd()
- else: y= 1
- if PREF_Z_AXIS: z= 1+ PREF_SIZE*rnd()
- else: z= 1
+ 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 = (ob.SizeX*x, ob.SizeY*y, ob.SizeZ*z)
+ 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()
+ 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()), ob.RotY+(PREF_Y_AXIS*PREF_ROT*rnd()), ob.RotZ+(PREF_Z_AXIS*PREF_ROT*rnd()))
+ 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():
@@ -89,9 +110,9 @@ def main():
PREF_Z_AXIS= Draw.Create(1)
pup_block = [\
- ('loc:', PREF_LOC, 0.0, 10.0, 'Amount to randomize the location'),\
- ('size:', PREF_SIZE, 0.0, 10.0, 'Amount to randomize the size'),\
- ('rot:', PREF_ROT, 0.0, 10.0, 'Amount to randomize the rotation'),\
+ ('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'),\
diff --git a/release/scripts/object_timeofs_follow_act.py b/release/scripts/object_timeofs_follow_act.py
new file mode 100644
index 00000000000..83863da7d8f
--- /dev/null
+++ b/release/scripts/object_timeofs_follow_act.py
@@ -0,0 +1,107 @@
+#!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/ply_export.py b/release/scripts/ply_export.py
index 010ee72ec67..cecde5a0b59 100644
--- a/release/scripts/ply_export.py
+++ b/release/scripts/ply_export.py
@@ -7,6 +7,7 @@ Group: 'Export'
Tooltip: 'Export active object to Stanford PLY format'
"""
+import bpy
import Blender
from Blender import Mesh, Scene, Window, sys, Image, Draw
import BPyMesh
@@ -64,7 +65,7 @@ def file_callback(filename):
if not filename.lower().endswith('.ply'):
filename += '.ply'
- scn= Blender.Scene.GetCurrent()
+ scn= bpy.data.scenes.active
ob= scn.objects.active
if not ob:
Blender.Draw.PupMenu('Error%t|Select 1 active object')
@@ -89,6 +90,10 @@ def file_callback(filename):
if not Draw.PupBlock('Export...', pup_block):
return
+ is_editmode = Blender.Window.EditMode()
+ if is_editmode:
+ Blender.Window.EditMode(0, '', 0)
+
Window.WaitCursor(1)
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val
@@ -132,7 +137,7 @@ def file_callback(filename):
if vertexColors: col = f.col
for j, v in enumerate(f):
if smooth:
- normal= v.no
+ normal= tuple(v.no)
normal_key = rvec3d(normal)
if faceUV:
@@ -211,12 +216,12 @@ def file_callback(filename):
file.write('\n')
file.close()
-
-
+
+ if is_editmode:
+ Blender.Window.EditMode(1, '', 0)
def main():
Blender.Window.FileSelector(file_callback, 'PLY Export', Blender.sys.makename(ext='.ply'))
-
if __name__=='__main__':
main()
diff --git a/release/scripts/ply_import.py b/release/scripts/ply_import.py
index a1118d8356d..6b96777102a 100644
--- a/release/scripts/ply_import.py
+++ b/release/scripts/ply_import.py
@@ -199,10 +199,14 @@ def read(filename):
obj = obj_spec.load(format_specs[format], file)
except IOError, (errno, strerror):
- file.close()
+ try: file.close()
+ except: pass
+
return None
- file.close()
+ try: file.close()
+ except: pass
+
return (obj_spec, obj);
diff --git a/release/scripts/render_save_layers.py b/release/scripts/render_save_layers.py
new file mode 100644
index 00000000000..04bedde6e8d
--- /dev/null
+++ b/release/scripts/render_save_layers.py
@@ -0,0 +1,116 @@
+#!BPY
+
+"""
+Name: 'Save Render Layers...'
+Blender: 245
+Group: 'Render'
+Tooltip: 'Save current renderlayers as a BPython script'
+"""
+
+__author__ = "Campbell Barton"
+__url__ = ("blender", "elysiun")
+__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: theme's name + '_theme.py' in user's scripts dir:
+default_fname = Blender.Get("scriptsdir")
+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 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 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) \ No newline at end of file
diff --git a/release/scripts/save_theme.py b/release/scripts/save_theme.py
index 7b21b5c74f7..a99050b404d 100644
--- a/release/scripts/save_theme.py
+++ b/release/scripts/save_theme.py
@@ -73,7 +73,11 @@ theme = Theme.Get()[0] # get current theme
# default filename: theme's name + '_theme.py' in user's scripts dir:
default_fname = Blender.Get("scriptsdir")
-default_fname = Blender.sys.join(default_fname, theme.name + '_theme.py')
+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):
diff --git a/release/scripts/scripttemplate_mesh_edit.py b/release/scripts/scripttemplate_mesh_edit.py
index e94b139a92d..159fb884925 100644
--- a/release/scripts/scripttemplate_mesh_edit.py
+++ b/release/scripts/scripttemplate_mesh_edit.py
@@ -70,6 +70,7 @@ def main():
# 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
diff --git a/release/scripts/scripttemplate_pyconstraint.py b/release/scripts/scripttemplate_pyconstraint.py
new file mode 100644
index 00000000000..68aa9194435
--- /dev/null
+++ b/release/scripts/scripttemplate_pyconstraint.py
@@ -0,0 +1,114 @@
+#!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 tranformation 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/uv_export.py b/release/scripts/uv_export.py
index f32b5b4fc12..5977a3b76f6 100644
--- a/release/scripts/uv_export.py
+++ b/release/scripts/uv_export.py
@@ -9,7 +9,7 @@ Tooltip: 'Export the UV face layout of the selected object to a .TGA or .SVG fil
__author__ = "Martin 'theeth' Poirier"
__url__ = ("http://www.blender.org", "http://blenderartists.org/")
-__version__ = "2.4"
+__version__ = "2.5"
__bpydoc__ = """\
This script exports the UV face layout of the selected mesh object to
@@ -96,6 +96,11 @@ Notes:<br>See change logs in scripts for a list of contributors.
# 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
@@ -178,12 +183,16 @@ def ExportCallback(f):
time1= Blender.sys.time()
- if obj.type != "Mesh":
+ 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
@@ -202,6 +211,8 @@ def ExportCallback(f):
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)
@@ -322,7 +333,7 @@ def UV_Export_TGA(vList, size, wsize, wrap, file):
step = 0
- img = Buffer(size+1,size+1)
+ img = Buffer(size,size)
if wrap:
wrapSize = size
@@ -333,15 +344,16 @@ def UV_Export_TGA(vList, size, wsize, wrap, file):
for f in vList:
for v in f:
x = int(v[0] * size)
- maxx = max (x, maxx)
- minx = min (x, minx)
+ maxx = max (x + wsize - 1, maxx)
+ minx = min (x - wsize + 1, minx)
y = int(v[1] * size)
- maxy = max (y, maxy)
- miny = min (y, miny)
+ 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)
@@ -361,31 +373,31 @@ def UV_Export_TGA(vList, size, wsize, wrap, file):
if step:
try:
for t in xrange(step):
- x = int(floor((co1[0] + t*(co2[0]-co1[0])/step) * size))
- y = int(floor((co1[1] + t*(co2[1]-co1[1])/step) * size))
+ 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))
- 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] = 0
- if wsize > 1:
- for x in range(-1*wsize + 1,wsize):
- for y in range(-1*wsize,wsize):
- img[co + 1 * x + y * 1 * size] = 0
+ 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] * size)
- y = int(v[1] * size)
+ x = int(v[0] * max_index)
+ y = int(v[1] * max_index)
if wrap:
x = x % wrapSize
diff --git a/release/scripts/uv_seams_from_islands.py b/release/scripts/uv_seams_from_islands.py
index dd27aab4ce9..241f38fc4aa 100644
--- a/release/scripts/uv_seams_from_islands.py
+++ b/release/scripts/uv_seams_from_islands.py
@@ -37,7 +37,6 @@ def seams_from_islands(me):
# add seams
SEAM = Mesh.EdgeFlags.SEAM
for ed in me.edges:
- print len(set(edge_uvs[ed.key]))
if len(set(edge_uvs[ed.key])) > 1:
ed.flag |= SEAM
@@ -59,7 +58,7 @@ def main():
# editmode if its enabled, we cant make
# changes to the mesh data while in editmode.
is_editmode = Window.EditMode()
- if is_editmode: Window.EditMode(1)
+ if is_editmode: Window.EditMode(0)
Window.WaitCursor(1)
@@ -68,8 +67,10 @@ def main():
# 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 'My Script finished in %.2f seconds' % (sys.time()-t)
+ print 'UV Seams from Islands finished in %.2f seconds' % (sys.time()-t)
Window.WaitCursor(0)
diff --git a/release/scripts/uvcalc_follow_active_coords.py b/release/scripts/uvcalc_follow_active_coords.py
index c97e7168d2f..2a79d0d05df 100644
--- a/release/scripts/uvcalc_follow_active_coords.py
+++ b/release/scripts/uvcalc_follow_active_coords.py
@@ -51,6 +51,11 @@ def extend():
Draw.PupMenu('ERROR: No mesh object.')
return
+ # Toggle Edit mode
+ is_editmode = Window.EditMode()
+ if is_editmode:
+ Window.EditMode(0)
+
me = ob.getData(mesh=1)
me_verts = me.verts
@@ -233,7 +238,12 @@ def extend():
face_modes[i] = 2 # dont search again
print sys.time() - t
- me.update()
+
+ if is_editmode:
+ Window.EditMode(1)
+ else:
+ me.update()
+
Window.RedrawAll()
Window.WaitCursor(0)
diff --git a/release/scripts/uvcalc_from_adjacent.py b/release/scripts/uvcalc_from_adjacent.py
deleted file mode 100644
index 32bbd9e08e6..00000000000
--- a/release/scripts/uvcalc_from_adjacent.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!BPY
-"""
-Name: 'UVs from unselected adjacent'
-Blender: 242
-Group: 'UVCalculation'
-Tooltip: 'Assign UVs to selected faces from surrounding unselected faces.'
-"""
-__author__ = "Campbell Barton"
-__url__ = ("blender", "elysiun")
-__version__ = "1.0 2006/02/07"
-
-__bpydoc__ = """\
-This script sets the UV mapping and image of selected faces from adjacent unselected faces.
-
-Use this script in face select mode for texturing between textured faces.
-"""
-
-# ***** 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
-
-def mostUsedImage(imageList): # Returns the image most used in the list.
- if not imageList:
- return None
- elif len(imageList) < 3:
- return imageList[0]
-
- # 3+ Images, Get the most used image for surrounding faces.
- imageCount = {}
- for image in imageList:
- if image:
- image_key= image.name
- else:
- image_key = None
-
- try:
- imageCount[image_key]['imageCount'] +=1 # an extra user of this image
- except:
- imageCount[image_key] = {'imageCount':1, 'blenderImage':image} # start with 1 user.
-
- # Now a list of tuples, (imageName, {imageCount, image})
- imageCount = imageCount.items()
-
- try: imageCount.sort(key=lambda a: a[1])
- except: imageCount.sort(lambda a,b: cmp(a[1], b[1]))
-
-
- return imageCount[-1][1]['blenderImage']
-
-
-def main():
- scn = bpy.data.scenes.active
- ob = scn.objects.active
- if ob == None or ob.type != 'Mesh':
- Draw.PupMenu('ERROR: No mesh object in face select mode.')
- return
- me = ob.getData(mesh=1)
-
- if not me.faceUV:
- Draw.PupMenu('ERROR: No mesh object in face select mode.')
- return
-
- selfaces = [f for f in me.faces if f.sel]
- unselfaces = [f for f in me.faces if not f.sel if not f.hide]
-
- # Gather per Vert UV and Image, store in vertUvAverage
- vertUvAverage = [[[],[]] for i in xrange(len(me.verts))]
-
- for f in unselfaces: # Unselected faces only.
- fuv = f.uv
- for i,v in enumerate(f):
- vertUvAverage[v.index][0].append(fuv[i])
- vertUvAverage[v.index][1].append(f.image)
-
- # Average per vectex UV coords
- for vertUvData in vertUvAverage:
- uvList = vertUvData[0]
- if uvList:
- # Convert from a list of vectors into 1 vector.
- vertUvData[0] = reduce(lambda a,b: a+b, uvList, Mathutils.Vector(0,0)) * (1.0/len(uvList))
- else:
- vertUvData[0] = None
-
-
-
- # Assign to selected faces
- TEX_FLAG = Mesh.FaceModes['TEX']
- for f in selfaces:
- uvlist = []
- imageList = []
- for i,v in enumerate(f):
- uv, vImages = vertUvAverage[v.index]
- uvlist.append( uv )
- imageList.extend(vImages)
-
- if None not in uvlist:
- # all the faces images used by this faces vert. some faces will be added twice but thats ok.
- # Get the most used image and assign to the face.
- image = mostUsedImage(imageList)
- f.uv = uvlist
-
- if image:
- f.image = image
- f.mode |= TEX_FLAG
- Window.RedrawAll()
-
-if __name__ == '__main__':
- main() \ No newline at end of file
diff --git a/release/scripts/uvcalc_lightmap.py b/release/scripts/uvcalc_lightmap.py
index a4269149203..af9acb09e17 100644
--- a/release/scripts/uvcalc_lightmap.py
+++ b/release/scripts/uvcalc_lightmap.py
@@ -221,7 +221,11 @@ PREF_MARGIN_DIV= 512):
else:
face_groups = []
- for me in meshes:
+ 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:
@@ -540,6 +544,12 @@ def main():
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,\
@@ -550,6 +560,9 @@ def main():
PREF_BOX_DIV.val,\
int(1/(PREF_MARGIN_DIV.val/100)))
+ if is_editmode:
+ Window.EditMode(1)
+
Window.WaitCursor(0)
if __name__ == '__main__':
diff --git a/release/scripts/uvcalc_quad_clickproj.py b/release/scripts/uvcalc_quad_clickproj.py
index 67b58885f9d..791fd661cc9 100644
--- a/release/scripts/uvcalc_quad_clickproj.py
+++ b/release/scripts/uvcalc_quad_clickproj.py
@@ -80,6 +80,10 @@ def main():
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, '')
@@ -100,10 +104,8 @@ def main():
mouse_buttons = Window.GetMouseButtons()
-
Window.DrawProgressBar (0.2, '(2 of 3 ) Click confirms the U coords')
-
mousedown_wait()
obmat= ob.matrixWorld
@@ -112,7 +114,7 @@ def main():
if not mouseInView or not OriginA:
return
-
+
me = ob.getData(mesh=1)
# Get the face under the mouse
@@ -255,6 +257,9 @@ def main():
Window.Redraw(Window.Types.VIEW3D)
Window.SetCursorPos(*orig_cursor)
+ if is_editmode:
+ Window.EditMode(1)
+
Window.RedrawAll()
if __name__=='__main__':
diff --git a/release/scripts/uvcalc_smart_project.py b/release/scripts/uvcalc_smart_project.py
index b10b69285e0..49d52d12d47 100644
--- a/release/scripts/uvcalc_smart_project.py
+++ b/release/scripts/uvcalc_smart_project.py
@@ -1121,6 +1121,9 @@ def main():
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()
diff --git a/release/scripts/vertexpaint_selfshadow_ao.py b/release/scripts/vertexpaint_selfshadow_ao.py
index c083bc9e8b0..7a6f4f9176d 100644
--- a/release/scripts/vertexpaint_selfshadow_ao.py
+++ b/release/scripts/vertexpaint_selfshadow_ao.py
@@ -39,6 +39,7 @@ and optionaly blur the shading to remove artifacts from spesific edges.
# --------------------------------------------------------------------------
from Blender import Scene, Draw, sys, Window, Mathutils, Mesh
+import bpy
import BPyMesh
@@ -135,10 +136,10 @@ def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PRE
Window.WaitCursor(0)
def main():
- scn= Scene.GetCurrent()
- ob= scn.getActiveObject()
+ sce= bpy.data.scenes.active
+ ob= sce.objects.active
- if not ob or ob.getType() != 'Mesh':
+ if not ob or ob.type != 'Mesh':
Draw.PupMenu('Error, no active mesh object, aborting.')
return
@@ -174,8 +175,8 @@ def main():
PREF_SHADOW_ONLY= PREF_SHADOW_ONLY.val
PREF_SEL_ONLY= PREF_SEL_ONLY.val
- if not me.faceUV:
- me.faceUV= 1
+ if not me.vertexColors:
+ me.vertexColors= 1
t= sys.time()
vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_RADIUS, PREF_MIN_EDLEN, PREF_CLAMP_CONCAVE, PREF_CLAMP_CONVEX, PREF_SHADOW_ONLY, PREF_SEL_ONLY)
diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py
index b5afacbe272..57ffd243bfc 100644
--- a/release/scripts/vrml97_export.py
+++ b/release/scripts/vrml97_export.py
@@ -656,10 +656,10 @@ class VRML2Export:
self.writeMaterial(mater, self.cleanStr(mater.name,''))
if (mater.mode & Blender.Material.Modes['TEXFACE']):
if image != None:
- self.writeImageTexture(image.name)
+ self.writeImageTexture(image.name, image.filename)
else:
if image != None:
- self.writeImageTexture(image.name)
+ self.writeImageTexture(image.name, image.filename)
self.writeIndented("}\n", -1)
@@ -837,7 +837,7 @@ class VRML2Export:
self.writeIndented("transparency %s\n" % (round(transp,self.cp)))
self.writeIndented("}\n",-1)
- def writeImageTexture(self, name):
+ def writeImageTexture(self, name, filename):
if self.texNames.has_key(name):
self.writeIndented("texture USE %s\n" % self.cleanStr(name))
self.texNames[name] += 1
@@ -846,7 +846,7 @@ class VRML2Export:
self.writeIndented("texture DEF %s ImageTexture {\n" % \
self.cleanStr(name), 1)
self.writeIndented('url "%s"\n' % \
- name.split("\\")[-1].split("/")[-1])
+ filename.split("\\")[-1].split("/")[-1])
self.writeIndented("}\n",-1)
self.texNames[name] = 1
diff --git a/release/scripts/weightpaint_average.py b/release/scripts/weightpaint_average.py
new file mode 100644
index 00000000000..4e8830256b2
--- /dev/null
+++ b/release/scripts/weightpaint_average.py
@@ -0,0 +1,121 @@
+#!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_invert.py b/release/scripts/weightpaint_invert.py
new file mode 100644
index 00000000000..cdae83a9d50
--- /dev/null
+++ b/release/scripts/weightpaint_invert.py
@@ -0,0 +1,95 @@
+#!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
index 204868a79fc..1f6c3d201aa 100644
--- a/release/scripts/weightpaint_normalize.py
+++ b/release/scripts/weightpaint_normalize.py
@@ -40,54 +40,100 @@ proportion of the veighting is unchanged.
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-from Blender import Scene, Draw
+from Blender import Scene, Draw, Object, Modifier
import BPyMesh
SMALL_NUM= 0.000001
-def actWeightNormalize(me, PREF_PEAKWEIGHT, PREF_KEEP_PROPORTION):
+
+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
- 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
-
- if max_weight < SMALL_NUM or new_weight == -1:
- Draw.PupMenu('No verts to normalize. exiting.')
- return
+ if PREF_ACTIVE_ONLY:
+ normalizeGroups = [act_group]
+ else:
+ normalizeGroups = groupNames[:]
- if abs(max_weight-PREF_PEAKWEIGHT) < SMALL_NUM:
- Draw.PupMenu('Vert Weights are alredy normalized.')
- return
+ 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]
- 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.
- local_maxweight= max(wd.itervalues()) / PREF_PEAKWEIGHT
- for weight in wd.iterkeys():
- wd[weight] /= local_maxweight
-
+ 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
- else: # Simple, just scale the weights up.
- for wd in vWeightDictUsed:
- if wd: # not false.
- wd[act_group] /= max_weight
+ # 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)
@@ -104,17 +150,21 @@ def main():
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, PREF_PEAKWEIGHT.val, PREF_KEEP_PROPORTION.val)
+ 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/wizard_curve2tree.py b/release/scripts/wizard_curve2tree.py
new file mode 100644
index 00000000000..f11d797636f
--- /dev/null
+++ b/release/scripts/wizard_curve2tree.py
@@ -0,0 +1,4007 @@
+#!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, CrossVecs, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix, RotationMatrix, Rand
+from Blender.Geometry import ClosestPointOnLine
+from Blender.Noise import randuvec
+
+GLOBALS = {}
+GLOBALS['non_bez_error'] = 0
+
+def AngleBetweenVecsSafe(a1, a2):
+ try:
+ return AngleBetweenVecs(a1,a2)
+ except:
+ return 180.0
+
+# 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
+ self.branches_all.sort( key = lambda brch: -brch.bpoints[0].radius )
+
+
+ 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
+ if dist < 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 = CrossVecs(zup, 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 = CrossVecs(parent_pt.no, parent_pt.prev.no - parent_pt.no)
+ else: cross = CrossVecs(parent_pt.no, 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 = CrossVecs( seg.no, line_normal )
+ cross2 = CrossVecs( pt.no, 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:
+ segments_level_current.sort( key = lambda seg: -(seg.headCo-seg.tailCo).length )
+
+ 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:
+ branches_sorted.sort( key = lambda brch: brch.getLength())
+ elif twig_select_mode==1:
+ branches_sorted.sort( key = lambda brch:-brch.getLength())
+ elif twig_select_mode==2:
+ branches_sorted.sort( key = lambda brch:brch.getStraightness())
+ elif twig_select_mode==3:
+ branches_sorted.sort( key = lambda brch:-brch.getStraightness())
+
+ factor_int = int(len(self.branches_all) * twig_select_factor)
+ branches_sorted[factor_int:] = [] # remove the last part of the list
+
+ branches_sorted.sort( key = lambda brch: len(brch.bpoints))
+
+ 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 = 45.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 = CrossVecs(zup, pt.no) # use this to offset the leaf later
+ cross2 = CrossVecs(cross1, 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 = CrossVecs(zup, 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...
+ '''
+
+ 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 = CrossVecs(self.no, self.branch.getParentFaceCent() - self.branch.parent_pt.getAbsVec( self.branch.getParentQuadIndex() ))
+ 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 = CrossVecs(self.prev.vecs[0], self.no)
+
+ self.vecs[0] = Blender.Mathutils.CrossVecs(self.no, 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 = CrossVecs(self_normal, self.parent_pt.no)
+ self_normal = CrossVecs(self.parent_pt.no, 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 = CrossVecs(parent_normal, 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 = CrossVecs(cos_ls[-1], 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 = CrossVecs(xy_nor, 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.0)
+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])
+ 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 idprop[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 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, 2.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, '', do_active_image); xtmp += but_width;
+ Draw.PushButton('Generate from selection', EVENT_REDRAW, xtmp, y, but_width*3, 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/x3d_export.py b/release/scripts/x3d_export.py
index 36359f1d122..eb9d5d35d6c 100644
--- a/release/scripts/x3d_export.py
+++ b/release/scripts/x3d_export.py
@@ -162,7 +162,8 @@ class VRML2Export:
##########################################################
def writeHeader(self):
- bfile = sys.expandpath(Blender.Get('filename'))
+ #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '&lt').replace('>', '&gt')
+ bfile = self.filename.replace('<', '&lt').replace('>', '&gt') # use outfile name
self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
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")
@@ -246,17 +247,17 @@ class VRML2Export:
def writeNavigationInfo(self, scene):
allObj = []
allObj = list(scene.objects)
- headlight = "TRUE"
+ headlight = "true"
vislimit = 0.0
for thisObj in allObj:
objType=thisObj.type
if objType == "Camera":
vislimit = thisObj.data.clipEnd
elif objType == "Lamp":
- headlight = "FALSE"
+ headlight = "false"
self.file.write("<NavigationInfo headlight=\"%s\" " % headlight)
self.file.write("visibilityLimit=\"%s\" " % (round(vislimit,self.cp)))
- self.file.write("type=\"EXAMINE, ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
+ self.file.write("type=\"EXAMINE\", \"ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
def writeSpotLight(self, ob, lamp):
safeName = self.cleanStr(ob.name)
@@ -404,7 +405,7 @@ class VRML2Export:
self.writeIndented("<Appearance>\n", 1)
# right now this script can only handle a single material per mesh.
if len(maters) >= 1:
- mat=Blender.Material.Get(maters[0].name)
+ mat=maters[0]
matFlags = mat.getMode()
if not matFlags & Blender.Material.Modes['TEXFACE']:
self.writeMaterial(mat, self.cleanStr(maters[0].name,''))
@@ -452,6 +453,7 @@ class VRML2Export:
for face in mesh.faces:
if face.smooth:
issmooth=1
+ break
if issmooth==1 and self.wire == 0:
creaseAngle=(mesh.getMaxSmoothAngle())*(math.pi/180.0)
self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
diff --git a/release/windows/installer/00.sconsblender.nsi b/release/windows/installer/00.sconsblender.nsi
index ff7a198d0b9..5875be289b6 100644
--- a/release/windows/installer/00.sconsblender.nsi
+++ b/release/windows/installer/00.sconsblender.nsi
@@ -3,6 +3,8 @@
;
; Blender Self-Installer for Windows (NSIS - http://nsis.sourceforge.net)
;
+; Requires the MoreInfo plugin - http://nsis.sourceforge.net/MoreInfo_plug-in
+;
!include "MUI.nsh"
!include "FileFunc.nsh"
@@ -209,13 +211,13 @@ Function .onInit
Call GetWindowsVersion
Pop $R0
Strcpy $winversion $R0
- !insertmacro MUI_INSTALLOPTIONS_EXTRACT "RELDIR\data.ini"
+ !insertmacro MUI_INSTALLOPTIONS_EXTRACT_AS "RELDIR\data.ini" "data.ini"
FunctionEnd
!define DLL_VER "8.00.50727.42"
+!define DLL_VER2 "7.10.3052.4"
-Function LocateCallback
-
+Function LocateCallback_80
MoreInfo::GetProductVersion "$R9"
Pop $0
@@ -236,12 +238,38 @@ Function LocateCallback
FunctionEnd
+Function LocateCallback_71
+ MoreInfo::GetProductVersion "$R9"
+ Pop $0
+
+ ${VersionCompare} "$0" "${DLL_VER2}" $R1
+
+ StrCmp $R1 0 0 new
+ new:
+ StrCmp $R1 1 0 old
+ old:
+ StrCmp $R1 2 0 end
+ ; Found DLL is older
+ Call PythonInstall
+
+ end:
+ StrCpy "$0" StopLocate
+ StrCpy $DLL_found "true"
+ Push "$0"
+
+FunctionEnd
+
Function DownloadDLL
MessageBox MB_OK "You will need to download the Microsoft Visual C++ 2005 Redistributable Package in order to run Blender. Pressing OK will take you to the download page, please follow the instructions on the page that appears."
StrCpy $0 "http://www.microsoft.com/downloads/details.aspx?familyid=32BC1BEE-A3F9-4C13-9C99-220B62A191EE&displaylang=en"
Call openLinkNewWindow
FunctionEnd
+Function PythonInstall
+ MessageBox MB_OK "You will need to install python 2.5 in order to run blender. Pressing OK will take you to the python.org website."
+ StrCpy $0 "http://www.python.org"
+ Call openLinkNewWindow
+FunctionEnd
Var HWND
Var DLGITEM
@@ -344,9 +372,14 @@ Section "Blender-VERSION (required)" SecCopyUI
MessageBox MB_OK "The installer will now check your system for the required system dlls."
StrCpy $1 $WINDIR
StrCpy $DLL_found "false"
- ${Locate} "$1" "/L=F /M=MSVCR80.DLL /S=0B" "LocateCallback"
+ ${Locate} "$1" "/L=F /M=MSVCR80.DLL /S=0B" "LocateCallback_80"
StrCmp $DLL_found "false" 0 +2
Call DownloadDLL
+ StrCpy $1 $WINDIR
+ StrCpy $DLL_found "false"
+ ${Locate} "$1" "/L=F /M=MSVCR71.DLL /S=0B" "LocateCallback_71"
+ StrCmp $DLL_found "false" 0 +2
+ Call PythonInstall
SectionEnd
diff --git a/source/Makefile b/source/Makefile
index d2969f41301..3553c723b51 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -56,11 +56,11 @@ ifdef NAN_BUILDINFO
BUILDINFO_C = $(SRCHOME)/creator/buildinfo.c
BUILD_DATE := $(shell date "+%Y-%m-%d")
BUILD_TIME := $(shell date "+%H:%M:%S")
+ BUILD_REV := $(shell svnversion)
endif
############# set pyplayerlib ##################
-PYPLAYERLIB ?= $(PYLIB)
############# libraries ##################
# COMLIB COMmon LIBraries for all targets
@@ -103,6 +103,8 @@ COMLIB += $(OCGDIR)/blender/nodes_cmp/$(DEBUG_DIR)libnodes_cmp.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 += $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a
+COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a
COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a
COMLIB += $(NAN_JPEG)/lib/libjpeg.a
@@ -169,52 +171,31 @@ endif
COMLIB += $(OCGDIR)/blender/imbuf/cineon/$(DEBUG_DIR)libcineon.a
+ifeq ($(WITH_DDS), true)
+ COMLIB += $(OCGDIR)/blender/imbuf/dds/$(DEBUG_DIR)libdds.a
+endif
+
+ifeq ($(WITH_BINRELOC), true)
+ COMLIB += $(OCGDIR)/extern/binreloc/$(DEBUG_DIR)libbinreloc.a
+endif
+
ifeq ($(WITH_FREETYPE2), true)
+ COMLIB += $(OCGDIR)/blender/ftfont/$(DEBUG_DIR)libftfont.a
ifeq ($(OS), windows)
ifeq ($(FREE_WINDOWS), true)
+ COMLIB += $(NAN_FTGL)/lib/libftgl.a
COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
else
+ COMLIB += $(NAN_FTGL)/lib/ftgl_static_ST.lib
COMLIB += $(NAN_FREETYPE)/lib/freetype2ST.lib
endif
else
+ COMLIB += $(NAN_FTGL)/lib/libftgl.a
ifeq ($(OS), irix)
COMLIB += $(NAN_FREETYPE)/lib32/libfreetype.a
- else
- COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
- endif
- endif
-endif
-
-ifeq ($(INTERNATIONAL), true)
- COMLIB += $(OCGDIR)/blender/ftfont/$(DEBUG_DIR)libftfont.a
- ifeq ($(OS), windows)
- ifeq ($(FREE_WINDOWS), true)
- COMLIB += $(NAN_GETTEXT)/lib/freegettext.a
- COMLIB += $(NAN_FTGL)/lib/libftgl.a
- #COMLIB += $(NAN_ICONV)/lib/freeiconv.a
- else
- COMLIB += $(NAN_GETTEXT)/lib/gnu_gettext.lib
- COMLIB += $(NAN_FTGL)/lib/ftgl_static_ST.lib
- COMLIB += $(NAN_FREETYPE)/lib/freetype2ST.lib
- COMLIB += $(NAN_ICONV)/lib/iconv.lib
- endif
- else
- COMLIB += $(NAN_FTGL)/lib/libftgl.a
- ifeq ($(OS), irix)
- COMLIB += $(NAN_FREETYPE)/lib32/libfreetype.a
- COMLIB += $(NAN_FREETYPE)/lib32/libintl.a
else
- COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
- endif
- endif
- ifeq ($(OS), darwin)
- COMLIB += $(NAN_GETTEXT)/lib/libintl.a
- ifeq ($(CPU), i386)
- COMLIB += $(NAN_GETTEXT)/lib/libiconv.a
- endif
- endif
- ifeq ($(OS), solaris)
- COMLIB += $(NAN_GETTEXT)/lib/libintl.a
+ COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
+ endif
endif
endif
@@ -347,14 +328,7 @@ ifeq ($(WITH_BF_WEBPLUGIN), true)
endif
endif
-ifdef PY_FRAMEWORK
- PYLIB = -framework Python
-else
- PYLIB = $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
-endif
-
ifeq ($(OS),solaris)
- PYLIB += $(NAN_ZLIB)/lib/libz.a
PULIB += $(NAN_ZLIB)/lib/libz.a
SPLIB += $(NAN_ZLIB)/lib/libz.a
endif
@@ -429,14 +403,6 @@ else
endif
ifeq ($(OS),windows)
- ifeq ($(FREE_WINDOWS),true)
- PYLIB = $(NAN_PYTHON)/lib/freepy.a
- else
- PYLIB = $(NAN_PYTHON)/lib/python23.lib
- endif
-
- PYPLAYERLIB = $(NAN_PYTHON)/static/*.obj
- PYPLAYERLIB = $(PYLIB)
# Might need to change this to $(NAN_MOZILLA_LIB)/nspr4.lib
NSPLUGLIB += $(NAN_NSPR)/lib/nspr4.lib
@@ -540,10 +506,10 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderstatic: $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"static"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"static"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
- $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderstatic $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB) $(PYLIB) $(LLIBS) $(SADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderstatic $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB) $(LLIBS) $(SADD) $(LOPTS)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -554,10 +520,10 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blender$(EXT): $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
- $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blender$(EXT) $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB) $(PYLIB) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blender$(EXT) $(BUILDINFO_O) $(OBJS) $(GRPLIB) $(COMLIB) $(PULIB) $(LLIBS) $(DADD) $(LOPTS)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -568,10 +534,10 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderplayer$(EXT): $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
- $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(PYPLAYERLIB) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(LLIBS) $(DADD) $(LOPTS)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -582,10 +548,10 @@ endif
$(DIR)/$(DEBUG_DIR)bin/blenderdynplayer$(EXT): $(OBJS) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
- $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderdynplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(PYLIB) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(LDFLAGS) -o $(DIR)/$(DEBUG_DIR)bin/blenderdynplayer$(EXT) $(BUILDINFO_O) $(OBJS) $(SPLIB1) $(COMLIB) $(SPLIB) $(LLIBS) $(DADD) $(LOPTS)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -596,7 +562,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/Blender3DPlugin$(SOEXT): $(PLUGAPPLIB_XPLINK)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(DYNLDFLAGS) -o $@ $(PLUGAPPLIB_XPLINK) $(LOPTS)
@@ -612,10 +578,10 @@ DEFFILE = ./gameengine/GamePlayer/netscape/src/npB3DPlg.def
$(DIR)/$(DEBUG_DIR)npB3DPlg$(SOEXT): $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
-# $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PYLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
- $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PYLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS) /def:$(DEFFILE)
+# $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS) /def:$(DEFFILE)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -623,10 +589,10 @@ endif
$(DIR)/$(DEBUG_DIR)bin/npBlender3DPlugin$(SOEXT): $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
- $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PYLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
+ $(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGAPPLIB) $(COMLIB) $(SPLIB) $(PLUGREMLIB) $(LLIBS) $(DADD) $(LOPTS)
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
@@ -634,7 +600,7 @@ endif
$(DIR)/$(DEBUG_DIR)bin/npTestPlugin$(SOEXT): $(NSPLUGLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
- $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
+ $(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
endif
mkdir -p $(DIR)/$(DEBUG_DIR)bin
$(CCC) $(DYNLDFLAGS) -o $@ $(NSPLUGLIB) $(PLUGTESTLIB) $(LLIBS) $(DADD) $(LOPTS)
diff --git a/source/blender/Makefile b/source/blender/Makefile
index c0001495210..2c1f83edf39 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -38,7 +38,7 @@ DIRS += avi imbuf render radiosity blenlib blenkernel blenpluginapi
DIRS += makesdna src yafray
DIRS += python nodes
-ifeq ($(INTERNATIONAL), true)
+ifeq ($(WITH_FREETYPE2), true)
DIRS += ftfont
endif
diff --git a/source/blender/SConscript b/source/blender/SConscript
index 410c2667ff7..56a661238f8 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -23,6 +23,9 @@ if env['WITH_BF_YAFRAY'] == 1:
if env['WITH_BF_INTERNATIONAL'] == 1:
SConscript (['ftfont/SConscript'])
+if env['WITH_BF_DDS'] == 1:
+ SConscript (['imbuf/intern/dds/SConscript'])
+
if env['WITH_BF_OPENEXR'] == 1:
SConscript (['imbuf/intern/openexr/SConscript'])
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index 3ad844bfdc1..da51c00c196 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -190,6 +190,7 @@ void AVI_set_debug (int mode) {
AVI_DEBUG= mode;
}
+/*
int AVI_is_avi (char *name) {
FILE *fp;
int ret;
@@ -209,6 +210,195 @@ int AVI_is_avi (char *name) {
fclose(fp);
return ret;
}
+*/
+
+int AVI_is_avi (char *name) {
+ int temp, fcca, j;
+ AviMovie movie;
+ AviMainHeader header;
+ AviBitmapInfoHeader bheader;
+
+ DEBUG("opening movie\n");
+
+ memset(&movie, 0, sizeof(AviMovie));
+
+ movie.type = AVI_MOVIE_READ;
+ movie.fp = fopen (name, "rb");
+ movie.offset_table = NULL;
+
+ if (movie.fp == NULL)
+ return 0;
+
+ if (GET_FCC (movie.fp) != FCC("RIFF") ||
+ !(movie.size = GET_FCC (movie.fp))) {
+ fclose(movie.fp);
+ return 0;
+ }
+
+ movie.header = &header;
+
+ if (GET_FCC (movie.fp) != FCC("AVI ") ||
+ GET_FCC (movie.fp) != FCC("LIST") ||
+ !GET_FCC (movie.fp) ||
+ GET_FCC (movie.fp) != FCC("hdrl") ||
+ (movie.header->fcc = GET_FCC (movie.fp)) != FCC("avih") ||
+ !(movie.header->size = GET_FCC (movie.fp))) {
+ DEBUG("bad initial header info\n");
+ fclose(movie.fp);
+ return 0;
+ }
+
+ movie.header->MicroSecPerFrame = GET_FCC(movie.fp);
+ movie.header->MaxBytesPerSec = GET_FCC(movie.fp);
+ movie.header->PaddingGranularity = GET_FCC(movie.fp);
+ movie.header->Flags = GET_FCC(movie.fp);
+ movie.header->TotalFrames = GET_FCC(movie.fp);
+ movie.header->InitialFrames = GET_FCC(movie.fp);
+ movie.header->Streams = GET_FCC(movie.fp);
+ movie.header->SuggestedBufferSize = GET_FCC(movie.fp);
+ movie.header->Width = GET_FCC(movie.fp);
+ movie.header->Height = GET_FCC(movie.fp);
+ movie.header->Reserved[0] = GET_FCC(movie.fp);
+ movie.header->Reserved[1] = GET_FCC(movie.fp);
+ movie.header->Reserved[2] = GET_FCC(movie.fp);
+ movie.header->Reserved[3] = GET_FCC(movie.fp);
+
+ fseek (movie.fp, movie.header->size-14*4, SEEK_CUR);
+
+ if (movie.header->Streams < 1) {
+ DEBUG("streams less than 1\n");
+ fclose(movie.fp);
+ return 0;
+ }
+
+ movie.streams = (AviStreamRec *) MEM_callocN (sizeof(AviStreamRec) * movie.header->Streams, "moviestreams");
+
+ for (temp=0; temp < movie.header->Streams; temp++) {
+
+ if (GET_FCC(movie.fp) != FCC("LIST") ||
+ !GET_FCC (movie.fp) ||
+ GET_FCC (movie.fp) != FCC ("strl") ||
+ (movie.streams[temp].sh.fcc = GET_FCC (movie.fp)) != FCC ("strh") ||
+ !(movie.streams[temp].sh.size = GET_FCC (movie.fp))) {
+ DEBUG("bad stream header information\n");
+
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 0;
+ }
+
+ movie.streams[temp].sh.Type = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Handler = GET_FCC (movie.fp);
+
+ fcca = movie.streams[temp].sh.Handler;
+
+ if (movie.streams[temp].sh.Type == FCC("vids")) {
+ if (fcca == FCC ("DIB ") ||
+ fcca == FCC ("RGB ") ||
+ fcca == FCC ("rgb ") ||
+ fcca == FCC ("RAW ") ||
+ fcca == 0) {
+ movie.streams[temp].format = AVI_FORMAT_AVI_RGB;
+ } else if (fcca == FCC ("mjpg")||fcca == FCC ("MJPG")) {
+ movie.streams[temp].format = AVI_FORMAT_MJPEG;
+ } else {
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 0;
+ }
+ }
+
+ movie.streams[temp].sh.Flags = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Priority = GET_TCC (movie.fp);
+ movie.streams[temp].sh.Language = GET_TCC (movie.fp);
+ movie.streams[temp].sh.InitialFrames = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Scale = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Rate = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Start = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Length = GET_FCC (movie.fp);
+ movie.streams[temp].sh.SuggestedBufferSize = GET_FCC (movie.fp);
+ movie.streams[temp].sh.Quality = GET_FCC (movie.fp);
+ movie.streams[temp].sh.SampleSize = GET_FCC (movie.fp);
+ movie.streams[temp].sh.left = GET_TCC (movie.fp);
+ movie.streams[temp].sh.top = GET_TCC (movie.fp);
+ movie.streams[temp].sh.right = GET_TCC (movie.fp);
+ movie.streams[temp].sh.bottom = GET_TCC (movie.fp);
+
+ fseek (movie.fp, movie.streams[temp].sh.size-14*4, SEEK_CUR);
+
+ if (GET_FCC (movie.fp) != FCC("strf")) {
+ DEBUG("no stream format information\n");
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 0;
+ }
+
+ movie.streams[temp].sf_size= GET_FCC(movie.fp);
+ if (movie.streams[temp].sh.Type == FCC("vids")) {
+ j = movie.streams[temp].sf_size - (sizeof(AviBitmapInfoHeader) - 8);
+ if (j >= 0) {
+ AviBitmapInfoHeader *bi;
+
+ movie.streams[temp].sf= &bheader;
+ bi= (AviBitmapInfoHeader *) movie.streams[temp].sf;
+
+ bi->fcc= FCC("strf");
+ bi->size= movie.streams[temp].sf_size;
+ bi->Size= GET_FCC(movie.fp);
+ bi->Width= GET_FCC(movie.fp);
+ bi->Height= GET_FCC(movie.fp);
+ bi->Planes= GET_TCC(movie.fp);
+ bi->BitCount= GET_TCC(movie.fp);
+ bi->Compression= GET_FCC(movie.fp);
+ bi->SizeImage= GET_FCC(movie.fp);
+ bi->XPelsPerMeter= GET_FCC(movie.fp);
+ bi->YPelsPerMeter= GET_FCC(movie.fp);
+ bi->ClrUsed= GET_FCC(movie.fp);
+ bi->ClrImportant= GET_FCC(movie.fp);
+
+ fcca = bi->Compression;
+
+ if ( movie.streams[temp].format ==
+ AVI_FORMAT_AVI_RGB) {
+ if (fcca == FCC ("DIB ") ||
+ fcca == FCC ("RGB ") ||
+ fcca == FCC ("rgb ") ||
+ fcca == FCC ("RAW ") ||
+ fcca == 0 ) {
+ } else if ( fcca == FCC ("mjpg") ||
+ fcca == FCC ("MJPG")) {
+ movie.streams[temp].format = AVI_FORMAT_MJPEG;
+ } else {
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 0;
+ }
+ }
+
+ }
+ if (j > 0) fseek (movie.fp, j, SEEK_CUR);
+ } else fseek (movie.fp, movie.streams[temp].sf_size, SEEK_CUR);
+
+ /* Walk to the next LIST */
+ while (GET_FCC (movie.fp) != FCC("LIST")) {
+ temp= GET_FCC (movie.fp);
+ if (temp<0 || ftell(movie.fp) > movie.size) {
+ DEBUG("incorrect size in header or error in AVI\n");
+
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 0;
+ }
+ fseek(movie.fp, temp, SEEK_CUR);
+ }
+
+ fseek(movie.fp, -4L, SEEK_CUR);
+ }
+
+ MEM_freeN(movie.streams);
+ fclose(movie.fp);
+ return 1;
+}
AviError AVI_open_movie (char *name, AviMovie *movie) {
int temp, fcca, size, j;
@@ -442,7 +632,7 @@ AviError AVI_open_movie (char *name, AviMovie *movie) {
}
void *AVI_read_frame (AviMovie *movie, AviFormat format, int frame, int stream) {
- int cur_frame, temp, i, rewind=1;
+ int cur_frame=-1, temp, i=0, rewind=1;
void *buffer;
/* Retrieve the record number of the desired frame in the index
diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/endian.c
index 152530dac0d..2ebbd5d4975 100644
--- a/source/blender/avi/intern/endian.c
+++ b/source/blender/avi/intern/endian.c
@@ -50,6 +50,7 @@
#define WORDS_BIGENDIAN
#endif
+#ifdef WORDS_BIGENDIAN
static void invert (int *num) {
int new=0,i,j;
@@ -79,6 +80,7 @@ static void Ichunk (AviChunk *chunk) {
invert (&chunk->fcc);
invert (&chunk->size);
}
+#endif
#ifdef WORDS_BIGENDIAN
static void Ilist (AviList *list){
diff --git a/source/blender/avi/intern/options.c b/source/blender/avi/intern/options.c
index a46688c8263..08c8cb254f0 100644
--- a/source/blender/avi/intern/options.c
+++ b/source/blender/avi/intern/options.c
@@ -99,8 +99,8 @@ AviError AVI_set_compress_option (AviMovie *movie, int option_type, int stream,
break;
case AVI_OPTION_FRAMERATE:
- if (1000000/(*((int *) opt_data)))
- movie->header->MicroSecPerFrame = 1000000/(*((int *) opt_data));
+ if (1000000/(*((double *) opt_data)))
+ movie->header->MicroSecPerFrame = 1000000/(*((double *) opt_data));
for (i=0; i < movie->header->Streams; i++) {
if (avi_get_format_type(movie->streams[i].format) == FCC("vids")) {
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 872717fdb9b..29fc1438c47 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -57,6 +57,7 @@ struct Mesh;
struct EditMesh;
struct ModifierData;
struct MCol;
+struct ColorBand;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
@@ -69,6 +70,7 @@ struct DerivedMesh {
CustomData vertData, edgeData, faceData;
int numVertData, numEdgeData, numFaceData;
int needsFree; /* checked on ->release, is set to 0 for cached results */
+ int deformedOnly; /* set by modifier stack if only deformed from original */
/* Misc. Queries */
@@ -395,6 +397,9 @@ void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
void DM_swap_face_data(struct DerivedMesh *dm, int index, int *corner_indices);
+/* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
+void vDM_ColorBand_store(struct ColorBand *coba);
+
/* Simple function to get me->totvert amount of vertices/normals,
correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
In use now by vertex/weigt paint and particles */
@@ -425,10 +430,33 @@ DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask);
DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r,
CustomDataMask dataMask);
+/* returns an array of deform matrices for crazyspace correction, and the
+ number of modifiers left */
+int editmesh_get_first_deform_matrices(float (**deformmats)[3][3],
+ float (**deformcos)[3]);
+
void weight_to_rgb(float input, float *fr, float *fg, float *fb);
/* determines required DerivedMesh data according to view and edit modes */
CustomDataMask get_viewedit_datamask();
+/* repeate this pattern
+ X000X000
+ 00000000
+ 00X000X0
+ 00000000 */
+
+#define DM_FACE_STIPPLE \
+{ \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0 \
+}
+
#endif
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index e848ef0a11b..1e1c3c110e8 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -60,6 +60,11 @@ extern "C" {
*/
void free_pose_channels(struct bPose *pose);
+/**
+ * Removes and deallocates all data from a pose, and also frees the pose.
+ */
+void free_pose(struct bPose *pose);
+
/**
* Allocate a new pose on the heap, and copy the src pose and it's channels
* into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
@@ -101,6 +106,9 @@ struct bPoseChannel *verify_pose_channel(struct bPose* pose,
/* sets constraint flags */
void update_pose_constraint_flags(struct bPose *pose);
+/* clears BONE_UNKEYED flags for frame changing */
+void framechange_poses_clear_unkeyed(void);
+
/**
* Allocate a new bAction on the heap and copy
* the contents of src into it. If src is NULL NULL is returned.
@@ -116,8 +124,12 @@ void calc_action_range(const struct bAction *act, float *start, float *end, int
/**
* Set the pose channels from the given action.
*/
-void extract_pose_from_action(struct bPose *pose, struct bAction *act,
- float ctime);
+void extract_pose_from_action(struct bPose *pose, struct bAction *act, float ctime);
+
+/**
+ * Get the effects of the given action using a workob
+ */
+void what_does_obaction(struct Object *ob, struct bAction *act, float cframe);
/**
* Iterate through the action channels of the action
@@ -153,11 +165,5 @@ float get_action_frame_inv(struct Object *ob, float cframe);
};
#endif
-/* nla strip->mode, for action blending */
-enum {
- POSE_BLEND = 0,
- POSE_ADD
-};
-
#endif
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index c7808331d7e..54fcb19d5dc 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -34,6 +34,8 @@
#ifndef BKE_ANIM_H
#define BKE_ANIM_H
+#define MAX_DUPLI_RECUR 8
+
struct Path;
struct Object;
struct PartEff;
@@ -44,8 +46,9 @@ typedef struct DupliObject {
struct DupliObject *next, *prev;
struct Object *ob;
unsigned int origlay;
- int index, no_draw;
+ int index, no_draw, type, animated;
float mat[4][4], omat[4][4];
+ float orco[3], uv[2];
} DupliObject;
void free_path(struct Path *path);
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 37022d89ac1..2c573faeb87 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -78,9 +78,11 @@ void unlink_armature(struct bArmature *arm);
void free_armature(struct bArmature *arm);
void make_local_armature(struct bArmature *arm);
struct bArmature *copy_armature(struct bArmature *arm);
+
void bone_flip_name (char *name, int strip_number);
+void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail);
-struct bArmature* get_armature (struct Object* ob);
+struct bArmature *get_armature (struct Object *ob);
struct Bone *get_named_bone (struct bArmature *arm, const char *name);
float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist);
@@ -112,7 +114,7 @@ typedef struct Mat4 {
float mat[4][4];
} Mat4;
-Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan);
+Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h
index ddc18851a9f..0a042c1612a 100644
--- a/source/blender/blenkernel/BKE_bad_level_calls.h
+++ b/source/blender/blenkernel/BKE_bad_level_calls.h
@@ -63,6 +63,15 @@ struct Script;
struct Text;
struct IpoDriver; /* DNA_curve_types.h */
struct Object;
+struct PyObject;
+struct Node_Type;
+struct BPy_Node;
+struct bNode;
+struct bNodeStack;
+struct ShadeInput;
+struct bPythonConstraint;
+struct bConstraintOb;
+struct bConstraintTarget;
void BPY_do_pyscript (struct ID *id, short int event);
void BPY_clear_script (struct Script *script);
void BPY_free_compiled_text (struct Text *text);
@@ -72,7 +81,16 @@ float BPY_pydriver_eval(struct IpoDriver *driver);
void BPY_pydriver_update(void);
/* button python evaluation */
int BPY_button_eval(char *expr, double *value);
-
+/* pyconstraints */
+void BPY_pyconstraint_eval(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
+void BPY_pyconstraint_targets(struct bPythonConstraint *con, struct bConstraintTarget *ct);
+/* pynodes */
+int EXPP_dict_set_item_str(struct PyObject *dict, char *key, struct PyObject *value);
+void Node_SetStack(struct BPy_Node *self, struct bNodeStack **stack, int type);
+void InitNode(struct BPy_Node *self, struct bNode *node);
+void Node_SetShi(struct BPy_Node *self, struct ShadeInput *shi);
+struct BPy_NodeSockets *Node_CreateSockets(struct bNode *node);
+int pytype_is_pynode(struct PyObject *pyob);
/* writefile.c */
struct Oops;
void free_oops(struct Oops *oops);
@@ -84,8 +102,9 @@ extern struct ListBase editNurb;
void mainqenter (unsigned short event, short val);
void waitcursor(int);
void allqueue(unsigned short event, short val);
-#define REDRAWVIEW3D 0x4010
-#define REDRAWBUTSEDIT 0x4019
+#define REDRAWVIEW3D 0x4010
+#define REDRAWBUTSOBJECT 0x4018
+#define REDRAWBUTSEDIT 0x4019
struct Material;
extern struct Material defmaterial;
@@ -179,6 +198,9 @@ void post_tag_change(struct VTag *vtag);
void post_taggroup_create(struct VTagGroup *vtaggroup);
char *verse_client_name(void);
void post_transform(struct VNode *vnode);
+void post_transform_pos(struct VNode *vnode);
+void post_transform_rot(struct VNode *vnode);
+void post_transform_scale(struct VNode *vnode);
void post_object_free_constraint(struct VNode *vnode);
void post_link_set(struct VLink *vlink);
void post_link_destroy(struct VLink *vlink);
@@ -196,24 +218,24 @@ void post_layer_create(struct VLayer *vlayer);
void post_layer_destroy(struct VLayer *vlayer);
void post_server_add(void);
-/* multires.c */
-struct Multires;
-struct MultiresLevel;
-struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
-void multires_free(struct Multires *mr);
-void multires_set_level(struct Object *ob, struct Mesh *me, const int render);
-void multires_update_levels(struct Mesh *me, const int render);
-void multires_calc_level_maps(struct MultiresLevel *lvl);
-struct Multires *multires_copy(struct Multires *orig);
-/* sculptmode.c */
-void sculptmode_free_all(struct Scene *sce);
-void sculptmode_init(struct Scene *sce);
-
/* zbuf.c */
void antialias_tagbuf(int xsize, int ysize, char *rectmove);
/* imagetexture.c */
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result);
+/* modifier.c */
+struct MeshDeformModifierData;
+
+void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
+ float (*vertexcos)[3], int totvert, float cagemat[][4]);
+
+/* particle.c */
+struct ParticleSystem;
+
+void PE_free_particle_edit(struct ParticleSystem *psys);
+void PE_get_colors(char sel[4], char nosel[4]);
+void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys);
+
#endif
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 4b9e10651cf..d81eb4d5103 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -43,8 +43,8 @@ extern "C" {
struct ListBase;
struct MemFile;
-#define BLENDER_VERSION 244
-#define BLENDER_SUBVERSION 2
+#define BLENDER_VERSION 245
+#define BLENDER_SUBVERSION 15
#define BLENDER_MINVERSION 240
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
new file mode 100644
index 00000000000..ca40295515b
--- /dev/null
+++ b/source/blender/blenkernel/BKE_bmesh.h
@@ -0,0 +1,237 @@
+/**
+ * BKE_bmesh.h jan 2007
+ *
+ * BMesh modeler structure and functions.
+ *
+ * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_BMESH_H
+#define BKE_BMESH_H
+
+#include "DNA_listBase.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+#include "DNA_customdata_types.h"
+#include "BLI_editVert.h"
+#include "BKE_DerivedMesh.h"
+#include "transform.h"
+
+struct BME_Vert;
+struct BME_Edge;
+struct BME_Poly;
+struct BME_Loop;
+
+typedef struct BME_CycleNode{
+ struct BME_CycleNode *next, *prev;
+ void *data;
+} BME_CycleNode;
+
+typedef struct BME_Mesh
+{
+ ListBase verts, edges, polys, loops;
+ int totvert, totedge, totpoly, totloop; /*record keeping*/
+ int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/
+ struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
+ /*some scratch arrays used by eulers*/
+ struct BME_Vert **vtar;
+ struct BME_Edge **edar;
+ struct BME_Loop **lpar;
+ struct BME_Poly **plar;
+ int vtarlen, edarlen, lparlen, plarlen;
+} BME_Mesh;
+
+typedef struct BME_Vert
+{
+ struct BME_Vert *next, *prev;
+ int EID;
+ float co[3];
+ float no[3];
+ struct BME_Edge *edge; /*first edge in the disk cycle for this vertex*/
+ void *data; /*custom vertex data*/
+ int eflag1, eflag2; /*reserved for use by eulers*/
+ int tflag1, tflag2; /*reserved for use by tools*/
+ unsigned short flag, h;
+ float bweight;
+} BME_Vert;
+
+typedef struct BME_Edge
+{
+ struct BME_Edge *next, *prev;
+ int EID;
+ struct BME_Vert *v1, *v2; /*note that order of vertex pointers means nothing to eulers*/
+ struct BME_CycleNode d1, d2; /*disk cycle nodes for v1 and v2 respectivley*/
+ struct BME_Loop *loop; /*first BME_Loop in the radial cycle around this edge*/
+ void *data; /*custom edge data*/
+ int eflag1, eflag2; /*reserved for use by eulers*/
+ int tflag1, tflag2; /*reserved for use by tools*/
+ unsigned char flag, h;
+ float crease, bweight;
+} BME_Edge;
+
+typedef struct BME_Loop
+{
+ struct BME_Loop *next, *prev; /*circularly linked list around face*/
+ int EID;
+ struct BME_CycleNode radial; /*circularly linked list used to find faces around an edge*/
+ struct BME_CycleNode *gref; /*pointer to loop ref. Nasty.*/
+ struct BME_Vert *v; /*vertex that this loop starts at.*/
+ struct BME_Edge *e; /*edge this loop belongs to*/
+ struct BME_Poly *f; /*face this loop belongs to*/
+ void *data; /*custom per face vertex data*/
+ int eflag1, eflag2; /*reserved for use by eulers*/
+ int tflag1, tflag2; /*reserved for use by tools*/
+ unsigned short flag, h;
+} BME_Loop;
+
+typedef struct BME_Poly
+{
+ struct BME_Poly *next, *prev;
+ int EID;
+ struct BME_Loop *loopbase; /*First editloop around Polygon.*/
+ unsigned int len; /*total length of the face. Eulers should preserve this data*/
+ void *data; /*custom face data*/
+ int eflag1, eflag2; /*reserved for use by eulers*/
+ int tflag1, tflag2; /*reserved for use by tools*/
+ unsigned short flag, h, mat_nr;
+} BME_Poly;
+
+//*EDGE UTILITIES*/
+int BME_verts_in_edge(struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *e);
+int BME_vert_in_edge(struct BME_Edge *e, BME_Vert *v);
+struct BME_Vert *BME_edge_getothervert(struct BME_Edge *e, struct BME_Vert *v);
+
+/*GENERAL CYCLE*/
+int BME_cycle_length(void *h);
+
+/*DISK CYCLE*/
+struct BME_Edge *BME_disk_nextedge(struct BME_Edge *e, struct BME_Vert *v);
+struct BME_CycleNode *BME_disk_getpointer(struct BME_Edge *e, struct BME_Vert *v);
+struct BME_Edge *BME_disk_next_edgeflag(struct BME_Edge *e, struct BME_Vert *v, int eflag, int tflag);
+int BME_disk_count_edgeflag(struct BME_Vert *v, int eflag, int tflag);
+
+/*RADIAL CYCLE*/
+struct BME_Loop *BME_radial_nextloop(struct BME_Loop *l);
+int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f);
+
+/*LOOP CYCLE*/
+struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v);
+
+/*MESH CREATION/DESTRUCTION*/
+struct BME_Mesh *BME_make_mesh(void);
+void BME_free_mesh(struct BME_Mesh *bm);
+/*FULL MESH VALIDATION*/
+int BME_validate_mesh(struct BME_Mesh *bm, int halt);
+/*ENTER/EXIT MODELLING LOOP*/
+int BME_model_begin(struct BME_Mesh *bm);
+void BME_model_end(struct BME_Mesh *bm);
+
+/*MESH CONSTRUCTION API.*/
+/*MAKE*/
+struct BME_Vert *BME_MV(struct BME_Mesh *bm, float *vec);
+struct BME_Edge *BME_ME(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2);
+struct BME_Poly *BME_MF(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge **elist, int len);
+/*KILL*/
+int BME_KV(struct BME_Mesh *bm, struct BME_Vert *v);
+int BME_KE(struct BME_Mesh *bm, struct BME_Edge *e);
+int BME_KF(struct BME_Mesh *bm, struct BME_Poly *bply);
+/*SPLIT*/
+struct BME_Vert *BME_SEMV(struct BME_Mesh *bm, struct BME_Vert *tv, struct BME_Edge *e, struct BME_Edge **re);
+struct BME_Poly *BME_SFME(struct BME_Mesh *bm, struct BME_Poly *f, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Loop **rl);
+/*JOIN*/
+int BME_JEKV(struct BME_Mesh *bm, struct BME_Edge *ke, struct BME_Vert *kv);
+struct BME_Poly *BME_JFKE(struct BME_Mesh *bm, struct BME_Poly *f1, struct BME_Poly *f2,struct BME_Edge *e); /*no reason to return BME_Poly pointer?*/
+/*NORMAL FLIP(Is its own inverse)*/
+int BME_loop_reverse(struct BME_Mesh *bm, struct BME_Poly *f);
+
+/* bevel tool defines */
+/* element flags */
+#define BME_BEVEL_ORIG 1
+#define BME_BEVEL_BEVEL (1<<1)
+#define BME_BEVEL_NONMAN (1<<2)
+#define BME_BEVEL_WIRE (1<<3)
+
+/* tool options */
+#define BME_BEVEL_SELECT 1
+#define BME_BEVEL_VERT (1<<1)
+#define BME_BEVEL_RADIUS (1<<2)
+#define BME_BEVEL_ANGLE (1<<3)
+#define BME_BEVEL_WEIGHT (1<<4)
+//~ #define BME_BEVEL_EWEIGHT (1<<4)
+//~ #define BME_BEVEL_VWEIGHT (1<<5)
+#define BME_BEVEL_PERCENT (1<<6)
+#define BME_BEVEL_EMIN (1<<7)
+#define BME_BEVEL_EMAX (1<<8)
+#define BME_BEVEL_RUNNING (1<<9)
+#define BME_BEVEL_RES (1<<10)
+
+typedef struct BME_TransData {
+ BME_Mesh *bm; /* the bmesh the vert belongs to */
+ BME_Vert *v; /* pointer to the vert this tdata applies to */
+ float co[3]; /* the original coordinate */
+ float org[3]; /* the origin */
+ float vec[3]; /* a directional vector; always, always normalize! */
+ void *loc; /* a pointer to the data to transform (likely the vert's cos) */
+ float factor; /* primary scaling factor; also accumulates number of weighted edges for beveling tool */
+ float weight; /* another scaling factor; used primarily for propogating vertex weights to transforms; */
+ /* weight is also used across recursive bevels to help with the math */
+ float maxfactor; /* the unscaled, original factor (used only by "edge verts" in recursive beveling) */
+ float *max; /* the maximum distance this vert can be transformed; negative is infinite
+ * it points to the "parent" maxfactor (where maxfactor makes little sense)
+ * where the max limit is stored (limits are stored per-corner) */
+} BME_TransData;
+
+typedef struct BME_TransData_Head {
+ GHash *gh; /* the hash structure for element lookup */
+ MemArena *ma; /* the memory "pool" we will be drawing individual elements from */
+ int len;
+} BME_TransData_Head;
+
+typedef struct BME_Glob { /* stored in Global G for Transform() purposes */
+ BME_Mesh *bm;
+ BME_TransData_Head *td;
+ struct TransInfo *Trans; /* a pointer to the global Trans struct */
+ int imval[2]; /* for restoring original mouse co when initTransform() is called multiple times */
+ int options;
+ int res;
+} BME_Glob;
+
+struct BME_TransData *BME_get_transdata(struct BME_TransData_Head *td, struct BME_Vert *v);
+void BME_free_transdata(struct BME_TransData_Head *td);
+float *BME_bevel_calc_polynormal(struct BME_Poly *f, struct BME_TransData_Head *td);
+struct BME_Mesh *BME_bevel(struct BME_Mesh *bm, float value, int res, int options, int defgrp_index, float angle, BME_TransData_Head **rtd);
+
+/*CONVERSION FUNCTIONS*/
+struct BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, struct BME_Mesh *bm);
+struct EditMesh *BME_bmesh_to_editmesh(struct BME_Mesh *bm, BME_TransData_Head *td);
+struct BME_Mesh *BME_derivedmesh_to_bmesh(struct DerivedMesh *dm, struct BME_Mesh *bm);
+struct DerivedMesh *BME_bmesh_to_derivedmesh(struct BME_Mesh *bm, struct DerivedMesh *dm);
+#endif
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
new file mode 100644
index 00000000000..181264137b3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -0,0 +1,270 @@
+/**
+ * BKE_cloth.h
+ *
+ * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef BKE_CLOTH_H
+#define BKE_CLOTH_H
+
+#include "float.h"
+#include "BLI_editVert.h"
+#include "BLI_linklist.h"
+
+#include "BKE_collision.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+
+#include "DNA_cloth_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+struct Object;
+struct Cloth;
+struct MFace;
+struct DerivedMesh;
+struct ClothModifierData;
+struct CollisionTree;
+
+// this is needed for inlining behaviour
+#ifndef _WIN32
+#define LINUX
+#ifndef __sgi
+#define DO_INLINE inline
+#else
+#define DO_INLINE
+#endif
+#else
+#define DO_INLINE __inline
+#endif
+
+#define CLOTH_MAX_THREAD 2
+
+/* goal defines */
+#define SOFTGOALSNAP 0.999f
+
+/* This is approximately the smallest number that can be
+* represented by a float, given its precision. */
+#define ALMOST_ZERO FLT_EPSILON
+
+/* Bits to or into the ClothVertex.flags. */
+#define CLOTH_VERT_FLAG_PINNED 1
+#define CLOTH_VERT_FLAG_COLLISION 2
+#define CLOTH_VERT_FLAG_PINNED_EM 3
+
+/**
+ * The definition of a cloth vertex.
+ */
+typedef struct ClothVertex
+{
+ int flags; /* General flags per vertex. */
+ float v [3]; /* The velocity of the point. */
+ float xconst [3]; /* constrained position */
+ float x [3]; /* The current position of this vertex. */
+ float xold [3]; /* The previous position of this vertex.*/
+ float tx [3]; /* temporary position */
+ float txold [3]; /* temporary old position */
+ float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */
+ float mass; /* mass / weight of the vertex */
+ float goal; /* goal, from SB */
+ float impulse[3]; /* used in collision.c */
+ unsigned int impulse_count; /* same as above */
+ float avg_spring_len; /* average length of connected springs */
+ float struct_stiff;
+ float bend_stiff;
+ float shear_stiff;
+ int spring_count; /* how many springs attached? */
+}
+ClothVertex;
+
+/**
+ * The definition of a spring.
+ */
+typedef struct ClothSpring
+{
+ int ij; /* Pij from the paper, one end of the spring. */
+ int kl; /* Pkl from the paper, one end of the spring. */
+ float restlen; /* The original length of the spring. */
+ int matrix_index; /* needed for implicit solver (fast lookup) */
+ int type; /* types defined in BKE_cloth.h ("springType") */
+ int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
+ float dfdx[3][3];
+ float dfdv[3][3];
+ float f[3];
+ float stiffness; /* stiffness factor from the vertex groups */
+ float editrestlen;
+}
+ClothSpring;
+
+// some macro enhancements for vector treatment
+#define VECADDADD(v1,v2,v3) {*(v1)+= *(v2) + *(v3); *(v1+1)+= *(v2+1) + *(v3+1); *(v1+2)+= *(v2+2) + *(v3+2);}
+#define VECSUBADD(v1,v2,v3) {*(v1)-= *(v2) + *(v3); *(v1+1)-= *(v2+1) + *(v3+1); *(v1+2)-= *(v2+2) + *(v3+2);}
+#define VECADDSUB(v1,v2,v3) {*(v1)+= *(v2) - *(v3); *(v1+1)+= *(v2+1) - *(v3+1); *(v1+2)+= *(v2+2) - *(v3+2);}
+#define VECSUBADDSS(v1,v2,aS,v3,bS) {*(v1)-= *(v2)*aS + *(v3)*bS; *(v1+1)-= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)-= *(v2+2)*aS + *(v3+2)*bS;}
+#define VECADDSUBSS(v1,v2,aS,v3,bS) {*(v1)+= *(v2)*aS - *(v3)*bS; *(v1+1)+= *(v2+1)*aS - *(v3+1)*bS; *(v1+2)+= *(v2+2)*aS - *(v3+2)*bS;}
+#define VECADDSS(v1,v2,aS,v3,bS) {*(v1)= *(v2)*aS + *(v3)*bS; *(v1+1)= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)= *(v2+2)*aS + *(v3+2)*bS;}
+#define VECADDS(v1,v2,v3,bS) {*(v1)= *(v2) + *(v3)*bS; *(v1+1)= *(v2+1) + *(v3+1)*bS; *(v1+2)= *(v2+2) + *(v3+2)*bS;}
+#define VECSUBMUL(v1,v2,aS) {*(v1)-= *(v2) * aS; *(v1+1)-= *(v2+1) * aS; *(v1+2)-= *(v2+2) * aS;}
+#define VECSUBS(v1,v2,v3,bS) {*(v1)= *(v2) - *(v3)*bS; *(v1+1)= *(v2+1) - *(v3+1)*bS; *(v1+2)= *(v2+2) - *(v3+2)*bS;}
+#define VECSUBSB(v1,v2, v3,bS) {*(v1)= (*(v2)- *(v3))*bS; *(v1+1)= (*(v2+1) - *(v3+1))*bS; *(v1+2)= (*(v2+2) - *(v3+2))*bS;}
+#define VECMULS(v1,aS) {*(v1)*= aS; *(v1+1)*= aS; *(v1+2)*= *aS;}
+#define VECADDMUL(v1,v2,aS) {*(v1)+= *(v2) * aS; *(v1+1)+= *(v2+1) * aS; *(v1+2)+= *(v2+2) * aS;}
+
+/* SIMULATION FLAGS: goal flags,.. */
+/* These are the bits used in SimSettings.flags. */
+typedef enum
+{
+ CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ), // The CM object requires a reinitializaiton.
+ CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),// object is only collision object, no cloth simulation is done
+ CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled
+ CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled
+ CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ), // true if tearing is enabled
+ CLOTH_SIMSETTINGS_FLAG_EDITMODE = ( 1 << 6 ), // are we in editmode? -several things disabled
+ CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */
+ CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */
+ CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */
+ CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */
+} CLOTH_SIMSETTINGS_FLAGS;
+
+/* COLLISION FLAGS */
+typedef enum
+{
+ CLOTH_COLLSETTINGS_FLAG_ENABLED = ( 1 << 1 ), /* enables cloth - object collisions */
+ CLOTH_COLLSETTINGS_FLAG_SELF = ( 1 << 2 ), /* enables selfcollisions */
+} CLOTH_COLLISIONSETTINGS_FLAGS;
+
+/* Spring types as defined in the paper.*/
+typedef enum
+{
+ CLOTH_SPRING_TYPE_STRUCTURAL = ( 1 << 1 ),
+ CLOTH_SPRING_TYPE_SHEAR = ( 1 << 2 ) ,
+ CLOTH_SPRING_TYPE_BENDING = ( 1 << 3 ),
+ CLOTH_SPRING_TYPE_GOAL = ( 1 << 4 ),
+} CLOTH_SPRING_TYPES;
+
+/* SPRING FLAGS */
+typedef enum
+{
+ CLOTH_SPRING_FLAG_DEACTIVATE = ( 1 << 1 ),
+ CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied
+} CLOTH_SPRINGS_FLAGS;
+
+/////////////////////////////////////////////////
+// collision.c
+////////////////////////////////////////////////
+
+// needed for implicit.c
+int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
+
+////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////
+// implicit.c
+////////////////////////////////////////////////
+
+// needed for cloth.c
+int implicit_init ( Object *ob, ClothModifierData *clmd );
+int implicit_free ( ClothModifierData *clmd );
+int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors );
+void implicit_set_positions ( ClothModifierData *clmd );
+
+// globally needed
+void clmdSetInterruptCallBack ( int ( *f ) ( void ) );
+////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////
+// cloth.c
+////////////////////////////////////////////////
+
+// needed for modifier.c
+void cloth_free_modifier_extern ( ClothModifierData *clmd );
+void cloth_free_modifier ( Object *ob, ClothModifierData *clmd );
+void cloth_init ( ClothModifierData *clmd );
+DerivedMesh *clothModifier_do ( ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc );
+
+void cloth_update_normals ( ClothVertex *verts, int nVerts, MFace *face, int totface );
+
+// needed for collision.c
+void bvh_update_from_cloth ( ClothModifierData *clmd, int moving );
+
+// needed for editmesh.c
+void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+int cloth_read_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+
+// needed for button_object.c
+void cloth_clear_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+
+// needed for cloth.c
+int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type);
+
+////////////////////////////////////////////////
+
+
+/* Typedefs for function pointers we need for solvers and collision detection. */
+typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step );
+typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
+
+
+/* This enum provides the IDs for our solvers. */
+// only one available in the moment
+typedef enum
+{
+ CM_IMPLICIT = 0,
+} CM_SOLVER_ID;
+
+
+/* This structure defines how to call the solver.
+*/
+typedef struct
+{
+ char *name;
+ CM_SOLVER_ID id;
+ int ( *init ) ( Object *ob, ClothModifierData *clmd );
+ int ( *solver ) ( Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors );
+ int ( *free ) ( ClothModifierData *clmd );
+}
+CM_SOLVER_DEF;
+
+/* used for caching in implicit.c */
+typedef struct Frame
+{
+ ClothVertex *verts;
+ ClothSpring *springs;
+ unsigned int numverts, numsprings;
+ float time; /* we need float since we want to support sub-frames */
+}
+Frame;
+
+#endif
+
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
new file mode 100644
index 00000000000..463254b8e4f
--- /dev/null
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -0,0 +1,192 @@
+/**
+ * BKE_cloth.h
+ *
+ * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef BKE_COLLISIONS_H
+#define BKE_COLLISIONS_H
+
+#include <math.h>
+#include "float.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* types */
+#include "BLI_linklist.h"
+#include "BKE_collision.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "DNA_cloth_types.h"
+#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+struct Object;
+struct Cloth;
+struct MFace;
+struct DerivedMesh;
+struct ClothModifierData;
+struct CollisionTree;
+
+
+////////////////////////////////////////
+// used in kdop.c and collision.c
+////////////////////////////////////////
+typedef struct CollisionTree
+{
+ struct CollisionTree *nodes[4]; // 4 children --> quad-tree
+ struct CollisionTree *parent;
+ struct CollisionTree *nextLeaf;
+ struct CollisionTree *prevLeaf;
+ float bv[26]; // Bounding volume of all nodes / we have 7 axes on a 14-DOP
+ unsigned int tri_index; // this saves the index of the face
+ // int point_index[4]; // supports up to 4 points in a leaf
+ int count_nodes; // how many nodes are used
+ int traversed; // how many nodes already traversed until this level?
+ int isleaf;
+ float alpha; /* for selfcollision */
+ float normal[3]; /* for selfcollision */
+}
+CollisionTree;
+
+typedef struct BVH
+{
+ unsigned int numfaces;
+ unsigned int numverts;
+ MVert *current_x; // e.g. txold in clothvertex
+ MVert *current_xold; // e.g. tx in clothvertex
+ MFace *mfaces; // just a pointer to the original datastructure
+ struct LinkNode *tree;
+ CollisionTree *root; // TODO: saving the root --> is this really needed? YES!
+ CollisionTree *leaf_tree; /* Tail of the leaf linked list. */
+ CollisionTree *leaf_root; /* Head of the leaf linked list. */
+ float epsilon; /* epslion is used for inflation of the k-dop */
+ int flags; /* bvhFlags */
+}
+BVH;
+////////////////////////////////////////
+
+
+
+////////////////////////////////////////
+// kdop.c
+////////////////////////////////////////
+
+// needed for collision.c
+typedef void ( *CM_COLLISION_RESPONSE ) ( ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2 );
+
+// needed for collision.c
+int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision);
+
+////////////////////////////////////////
+
+
+////////////////////////////////////////
+// used for collisions in kdop.c and also collision.c
+////////////////////////////////////////
+/* used for collisions in collision.c */
+typedef struct CollPair
+{
+ unsigned int face1; // cloth face
+ unsigned int face2; // object face
+ double distance; // magnitude of vector
+ float normal[3];
+ float vector[3]; // unnormalized collision vector: p2-p1
+ float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
+ int lastsign; // indicates if the distance sign has changed, unused itm
+ float time; // collision time, from 0 up to 1
+ unsigned int ap1, ap2, ap3, bp1, bp2, bp3;
+ unsigned int pointsb[4];
+}
+CollPair;
+
+/* used for collisions in collision.c */
+typedef struct EdgeCollPair
+{
+ unsigned int p11, p12, p21, p22;
+ float normal[3];
+ float vector[3];
+ float time;
+ int lastsign;
+ float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
+}
+EdgeCollPair;
+
+/* used for collisions in collision.c */
+typedef struct FaceCollPair
+{
+ unsigned int p11, p12, p13, p21;
+ float normal[3];
+ float vector[3];
+ float time;
+ int lastsign;
+ float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
+}
+FaceCollPair;
+////////////////////////////////////////
+
+
+
+/////////////////////////////////////////////////
+// forward declarations
+/////////////////////////////////////////////////
+
+// NOTICE: mvert-routines for building + update the BVH are the most native ones
+
+// builds bounding volume hierarchy
+void bvh_build (BVH *bvh);
+BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon);
+
+// frees the same
+void bvh_free ( BVH * bvh );
+
+// checks two bounding volume hierarchies for potential collisions and returns some list with those
+
+
+// update bounding volumes, needs updated positions in bvh->x
+void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving);
+void bvh_update(BVH * bvh, int moving);
+
+LinkNode *BLI_linklist_append_fast ( LinkNode **listp, void *ptr );
+
+// move Collision modifier object inter-frame with step = [0,1]
+// defined in collisions.c
+void collision_move_object(CollisionModifierData *collmd, float step, float prevstep);
+
+// interface for collision functions
+void collisions_compute_barycentric (float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3);
+void interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3);
+
+/////////////////////////////////////////////////
+
+#endif
+
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 2bec643d5b0..4ad7de7a583 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007 - Joshua Leung (major recode)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -34,42 +34,111 @@
#define BKE_CONSTRAINT_H
struct bConstraint;
-struct Object;
+struct bConstraintTarget;
struct ListBase;
+struct Object;
struct bConstraintChannel;
-struct bAction;
-struct bArmature;
-
-/* Function prototypes */
-void unique_constraint_name (struct bConstraint *con, struct ListBase *list);
-void *new_constraint_data (short type);
-void evaluate_constraint (struct bConstraint *constraint, struct Object *ob, short ownertype, void *ownerdata, float targetmat[][4]);
-void free_constraints (struct ListBase *conlist);
-void copy_constraints (struct ListBase *dst, struct ListBase *src);
-void copy_constraint_channels (ListBase *dst, ListBase *src);
-void clone_constraint_channels (struct ListBase *dst, struct ListBase *src);
-void relink_constraints (struct ListBase *list);
-void free_constraint_data (struct bConstraint *con);
-
-/* channels */
-struct bConstraintChannel *get_constraint_channel (ListBase *list, const char *name);
-struct bConstraintChannel *verify_constraint_channel (ListBase *list, const char *name);
-void free_constraint_channels (ListBase *chanbase);
-
-/* Gemeric functions */
-void do_constraint_channels (struct ListBase *conbase, struct ListBase *chanbase, float ctime);
-short get_constraint_target_matrix (struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float size[3], float time);
-char constraint_has_target (struct bConstraint *con);
-struct Object *get_constraint_target(struct bConstraint *con, char **subtarget);
-void set_constraint_target(struct bConstraint *con, struct Object *ob, char *subtarget);
-
-
-/* Constraint target/owner types */
-#define TARGET_OBJECT 1 // string is ""
-#define TARGET_BONE 2 // string is bone-name
-#define TARGET_VERT 3 // string is "VE:#"
-#define TARGET_FACE 4 // string is "FA:#"
-#define TARGET_CV 5 // string is "CV:#"
+struct bPoseChannel;
+
+/* ---------------------------------------------------------------------------- */
+
+/* special struct for use in constraint evaluation */
+typedef struct bConstraintOb {
+ struct Object *ob; /* if pchan, then armature that it comes from, otherwise constraint owner */
+ struct bPoseChannel *pchan; /* pose channel that owns the constraints being evaluated */
+
+ float matrix[4][4]; /* matrix where constraints are accumulated + solved */
+ float startmat[4][4]; /* original matrix (before constraint solving) */
+
+ short type; /* type of owner */
+} bConstraintOb;
+
+/* ---------------------------------------------------------------------------- */
+
+/* Constraint Type-Info (shorthand in code = cti):
+ * This struct provides function pointers for runtime, so that functions can be
+ * written more generally (with fewer/no special exceptions for various constraints).
+ *
+ * Callers of these functions must check that they actually point to something useful,
+ * as some constraints don't define some of these.
+ *
+ * Warning: it is not too advisable to reorder order of members of this struct,
+ * as you'll have to edit quite a few ($NUM_CONSTRAINT_TYPES) of these
+ * structs.
+ */
+typedef struct bConstraintTypeInfo {
+ /* admin/ident */
+ short type; /* CONSTRAINT_TYPE_### */
+ short size; /* size in bytes of the struct */
+ char name[32]; /* name of constraint in interface */
+ char structName[32]; /* name of struct for SDNA */
+
+ /* data management function pointers - special handling */
+ /* free any data that is allocated separately (optional) */
+ void (*free_data)(struct bConstraint *con);
+ /* adjust pointer to other ID-data using ID_NEW(), but not to targets (optional) */
+ void (*relink_data)(struct bConstraint *con);
+ /* copy any special data that is allocated separately (optional) */
+ void (*copy_data)(struct bConstraint *con, struct bConstraint *src);
+ /* set settings for data that will be used for bConstraint.data (memory already allocated) */
+ void (*new_data)(void *cdata);
+
+ /* target handling function pointers */
+ /* for multi-target constraints: return that list; otherwise make a temporary list (returns number of targets) */
+ int (*get_constraint_targets)(struct bConstraint *con, struct ListBase *list);
+ /* for single-target constraints only: flush data back to source data, and the free memory used */
+ void (*flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, short nocopy);
+
+ /* evaluation */
+ /* set the ct->matrix for the given constraint target (at the given ctime) */
+ void (*get_target_matrix)(struct bConstraint *con, struct bConstraintOb *cob, struct bConstraintTarget *ct, float ctime);
+ /* evaluate the constraint for the given time */
+ void (*evaluate_constraint)(struct bConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
+} bConstraintTypeInfo;
+
+/* Function Prototypes for bConstraintTypeInfo's */
+bConstraintTypeInfo *constraint_get_typeinfo(struct bConstraint *con);
+bConstraintTypeInfo *get_constraint_typeinfo(int type);
+
+/* ---------------------------------------------------------------------------- */
+/* Useful macros for testing various common flag combinations */
+
+/* Constraint Target Macros */
+#define VALID_CONS_TARGET(ct) ((ct) && (ct->tar))
+
+
+/* ---------------------------------------------------------------------------- */
+
+/* Constraint function prototypes */
+void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
+
+void free_constraints(struct ListBase *conlist);
+void copy_constraints(struct ListBase *dst, struct ListBase *src);
+void relink_constraints(struct ListBase *list);
+void free_constraint_data(struct bConstraint *con);
+
+/* Constraints + Proxies function prototypes */
+void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
+
+/* Constraint Channel function prototypes */
+struct bConstraintChannel *get_constraint_channel(struct ListBase *list, const char *name);
+struct bConstraintChannel *verify_constraint_channel(struct ListBase *list, const char *name);
+void do_constraint_channels(struct ListBase *conbase, struct ListBase *chanbase, float ctime, short onlydrivers);
+void copy_constraint_channels(struct ListBase *dst, struct ListBase *src);
+void clone_constraint_channels(struct ListBase *dst, struct ListBase *src);
+void free_constraint_channels(struct ListBase *chanbase);
+
+
+/* Constraint Evaluation function prototypes */
+struct bConstraintOb *constraints_make_evalob(struct Object *ob, void *subdata, short datatype);
+void constraints_clear_evalob(struct bConstraintOb *cob);
+
+void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
+
+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);
+
#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 19c3c620419..ee63f678505 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -55,6 +55,7 @@ short curve_type( struct Curve *cu);
void test_curve_type( struct Object *ob);
void tex_space_curve( struct Curve *cu);
int count_curveverts( struct ListBase *nurb);
+int count_curveverts_without_handles( struct ListBase *nurb);
void freeNurb( struct Nurb *nu);
void freeNurblist( struct ListBase *lb);
struct Nurb *duplicateNurb( struct Nurb *nu);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 4a486e6795f..d0535f1752e 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -185,6 +185,8 @@ int CustomData_get_layer_index(const struct CustomData *data, int type);
int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name);
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
+int CustomData_get_active_layer(const struct CustomData *data, int type);
+int CustomData_get_render_layer(const struct CustomData *data, int type);
/* copies the data from source to the data element at index in the first
* layer of type
@@ -207,6 +209,10 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
void CustomData_set_layer_active(struct CustomData *data, int type, int n);
void CustomData_set_layer_render(struct CustomData *data, int type, int n);
+/* same as above but works with an index from CustomData_get_layer_index */
+void CustomData_set_layer_active_index(struct CustomData *data, int type, int n);
+void CustomData_set_layer_render_index(struct CustomData *data, int type, int n);
+
/* adds flag to the layer flags */
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index de0dddabfd3..67e2a8948d5 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -46,6 +46,7 @@ void copy_defgroups (struct ListBase *lb1, struct ListBase *lb2);
struct bDeformGroup *copy_defgroup (struct bDeformGroup *ingroup);
struct bDeformGroup *get_named_vertexgroup (Object *ob, char *name);
int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg);
+int get_named_vertexgroup_num (Object *ob, char *name);
void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 979ed31fb20..2dc4de32132 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -123,5 +123,7 @@ void filldisplist(struct ListBase *dispbase, struct ListBase *to);
void fastshade_free_render(void);
+float calc_taper(struct Object *taperobj, int cur, int tot);
+
#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index f2c42197fb5..d1005395561 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -62,6 +62,7 @@ struct Object;
struct bSoundListener;
struct BMF_Font;
struct EditMesh;
+struct BME_Glob;
typedef struct Global {
@@ -111,6 +112,9 @@ typedef struct Global {
/* Editmode lists */
struct EditMesh *editMesh;
+
+ /* Used for BMesh transformations */
+ struct BME_Glob *editBMesh;
float textcurs[4][2];
@@ -178,21 +182,28 @@ typedef struct Global {
#define G_DRAWCREASES (1 << 19)
#define G_DRAWSEAMS (1 << 20)
#define G_HIDDENEDGES (1 << 21)
-
/* Measurement info Drawing */
#define G_DRAW_EDGELEN (1 << 22)
#define G_DRAW_FACEAREA (1 << 23)
#define G_DRAW_EDGEANG (1 << 24)
-#define G_RECORDKEYS (1 << 25)
-
+/* #define G_RECORDKEYS (1 << 25) also removed */
/*#ifdef WITH_VERSE*/
#define G_VERSE_CONNECTED (1 << 26)
#define G_DRAW_VERSE_DEBUG (1 << 27)
/*#endif*/
-
#define G_DRAWSHARP (1 << 28) /* draw edges with the sharp flag */
#define G_SCULPTMODE (1 << 29)
+#define G_PARTICLEEDIT (1 << 30)
+
+/* #define G_AUTOMATKEYS (1 << 30) also removed */
+#define G_HIDDENHANDLES (1 << 31) /* used for curves only */
+#define G_DRAWBWEIGHTS (1 << 31)
+
+/* macro for testing face select mode
+ * Texture paint could be removed since selected faces are not used
+ * however hiding faces is useful */
+#define FACESEL_PAINT_TEST ((G.f&G_FACESELECT) && (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)))
/* G.fileflags */
@@ -241,9 +252,10 @@ typedef struct Global {
#define B_ENDIAN 0
/* G.moving, signals drawing in (3d) window to denote transform */
-#define G_TRANSFORM_OBJ 1
-#define G_TRANSFORM_EDIT 2
-#define G_TRANSFORM_MANIP 4
+#define G_TRANSFORM_OBJ 1
+#define G_TRANSFORM_EDIT 2
+#define G_TRANSFORM_MANIP 4
+#define G_TRANSFORM_PARTICLE 8
/* G.special1 */
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 9038422795d..f7158daa937 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -44,9 +44,10 @@ void free_group(struct Group *group);
void unlink_group(struct Group *group);
struct Group *add_group(char *name);
void add_to_group(struct Group *group, struct Object *ob);
-void rem_from_group(struct Group *group, struct Object *ob);
-struct Group *find_group(struct Object *ob);
+int rem_from_group(struct Group *group, struct Object *ob);
+struct Group *find_group(struct Object *ob, struct Group *group);
int object_in_group(struct Object *ob, struct Group *group);
+int group_is_animated(struct Object *parent, struct Group *group);
void group_tag_recalc(struct Group *group);
void group_handle_recalc_and_update(struct Object *parent, struct Group *group);
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 315c7dc7a53..737adea78be 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -1,34 +1,32 @@
/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
+* $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) 2006-2007 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
#ifndef BKE_ICONS_H
#define BKE_ICONS_H
@@ -44,12 +42,13 @@ struct Icon
void *drawinfo;
void *obj;
short type;
- short changed;
DrawInfoFreeFP drawinfo_free;
};
typedef struct Icon Icon;
+struct PreviewImage;
+
void BKE_icons_init(int first_dyn_id);
/* return icon id for library object or create new icon if not found */
@@ -71,5 +70,19 @@ void BKE_icon_changed(int icon_id);
/* free all icons */
void BKE_icons_free();
+/* free the preview image */
+void BKE_previewimg_free(struct PreviewImage **prv);
+
+/* free the preview image belonging to the id */
+void BKE_previewimg_free_id(ID *id);
+
+/* create a new preview image */
+struct PreviewImage* BKE_previewimg_create() ;
+
+/* create a copy of the preview image */
+struct PreviewImage* BKE_previewimg_copy(struct PreviewImage *prv);
+
+/* retrieve existing or create new preview image */
+PreviewImage* BKE_previewimg_get(ID *id);
#endif /* BKE_ICONS_H */
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 92b624f80ab..961cca511de 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -137,6 +137,7 @@ void IDP_FreeIterBeforeEnd(void *vself);
to create the Group property and attach it to id if it doesn't exist; otherwise
the function will return NULL if there's no Group property attached to the ID.*/
struct IDProperty *IDP_GetProperties(struct ID *id, int create_if_needed);
+struct IDProperty *IDP_CopyProperty(struct IDProperty *prop);
/*
Allocate a new ID.
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 58f96491a1b..a584722031b 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -46,6 +46,8 @@ struct anim;
/* call from library */
void free_image(struct Image *me);
+void BKE_stamp_info(struct ImBuf *ibuf);
+void BKE_stamp_buf(unsigned char *rect, float *rectf, int width, int height, int channels);
int BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
void BKE_makepicstring(char *string, char *base, int frame, int imtype);
void BKE_add_image_extension(char *string, int imtype);
@@ -112,7 +114,7 @@ struct ImBuf *BKE_image_get_ibuf(struct Image *ima, struct ImageUser *iuser);
struct Image *BKE_add_image_file(const char *name);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4]);
+struct Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]);
/* for reload, refresh, pack */
void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal);
@@ -146,6 +148,9 @@ void BKE_image_all_free_anim_ibufs(int except_frame);
void BKE_image_memorypack(struct Image *ima);
+/* prints memory statistics for images */
+void BKE_image_print_memlist(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index 2a6065eb4f1..01fe0903775 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -95,7 +95,7 @@ void do_ipo_nocalc(struct Ipo *ipo);
void do_ipo(struct Ipo *ipo);
void do_mat_ipo(struct Material *ma);
void do_ob_ipo(struct Object *ob);
-void do_seq_ipo(struct Sequence *seq);
+void do_seq_ipo(struct Sequence *seq, int cfra);
void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo, float ctime);
int has_ipo_code(struct Ipo *ipo, int code);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 94ba1cbd69d..5325b3a8bc1 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -59,6 +59,7 @@ int do_ob_key(struct Object *ob);
struct Key *ob_get_key(struct Object *ob);
struct KeyBlock *ob_get_keyblock(struct Object *ob);
+struct KeyBlock *key_get_keyblock(struct Key *key, int index);
#endif
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 55eb1d27cc0..bf505fa23d7 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -64,8 +64,8 @@ void lattice_deform_verts(struct Object *laOb, struct Object *target,
int numVerts, char *vgroup);
void armature_deform_verts(struct Object *armOb, struct Object *target,
struct DerivedMesh *dm, float (*vertexCos)[3],
- int numVerts, int deformflag,
- const char *defgrp_name);
+ float (*defMats)[3][3], int numVerts, int deformflag,
+ float (*prevCos)[3], const char *defgrp_name);
float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3];
void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]);
void lattice_calc_modifiers(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 6e0f2fdb284..2cfa1dc5cc4 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -78,6 +78,7 @@ typedef struct Main {
ListBase action;
ListBase nodetree;
ListBase brush;
+ ListBase particle;
} Main;
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 2add4b95080..0c93e4e32a2 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -57,6 +57,9 @@ struct ID *material_from(struct Object *ob, int act);
void assign_material(struct Object *ob, struct Material *ma, int act);
void new_material_to_objectdata(struct Object *ob);
+int find_material_index(struct Object *ob, struct Material *ma);
+
+
void init_render_material(struct Material *, int, float *);
void init_render_materials(int, float *);
void end_render_material(struct Material *);
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 269e7150768..038331747db 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -165,8 +165,8 @@ void free_mball(struct MetaBall *mb);
struct MetaBall *add_mball(char *name);
struct MetaBall *copy_mball(struct MetaBall *mb);
void make_local_mball(struct MetaBall *mb);
-void tex_space_mball( struct Object *ob);
-void make_orco_mball( struct Object *ob);
+void tex_space_mball(struct Object *ob);
+float *make_orco_mball(struct Object *ob);
struct Object *find_basis_mball( struct Object *ob);
int is_basis_mball(struct Object *ob);
void metaball_polygonize(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 4ec62821455..9be633ed6e3 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -62,9 +62,9 @@ void make_local_tface(struct Mesh *me);
void make_local_mesh(struct Mesh *me);
void boundbox_mesh(struct Mesh *me, float *loc, float *size);
void tex_space_mesh(struct Mesh *me);
-float *mesh_create_orco_render(struct Object *ob);
-float *mesh_create_orco(struct Object *ob);
-void test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
+float *get_mesh_orco_verts(struct Object *ob);
+void transform_mesh_orco_verts(struct Mesh *me, float (*orco)[3], int totvert, int invert);
+int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);
void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
@@ -75,7 +75,7 @@ int update_realtime_texture(struct MTFace *tface, double time);
void mesh_delete_material_index(struct Mesh *me, int index);
void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth);
-struct BoundBox *mesh_get_bb(struct Mesh *me);
+struct BoundBox *mesh_get_bb(struct Object *ob);
void mesh_get_texspace(struct Mesh *me, float *loc_r, float *rot_r, float *size_r);
/* if old, it converts mface->edcode to edge drawflags */
@@ -90,22 +90,42 @@ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces,
/* Return a newly MEM_malloc'd array of all the mesh vertex locations
* (_numVerts_r_ may be NULL) */
float (*mesh_getVertexCos(struct Mesh *me, int *numVerts_r))[3];
+float (*mesh_getRefKeyCos(struct Mesh *me, int *numVerts_r))[3];
/* map from uv vertex to face (for select linked, stitch, uv suburf) */
-struct UvVertMap;
-typedef struct UvVertMap UvVertMap;
+/* UvVertMap */
+
+#define STD_UV_CONNECT_LIMIT 0.0001f
+
+typedef struct UvVertMap {
+ struct UvMapVert **vert;
+ struct UvMapVert *buf;
+} UvVertMap;
typedef struct UvMapVert {
struct UvMapVert *next;
unsigned int f;
- unsigned char tfindex, separate;
+ unsigned char tfindex, separate, flag;
} UvMapVert;
UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit);
UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v);
void free_uv_vert_map(UvVertMap *vmap);
+/* Partial Mesh Visibility */
+struct PartialVisibility *mesh_pmv_copy(struct PartialVisibility *);
+void mesh_pmv_free(struct PartialVisibility *);
+void mesh_pmv_revert(struct Object *ob, struct Mesh *me);
+void mesh_pmv_off(struct Object *ob, struct Mesh *me);
+
+/* functions for making menu's from customdata layers */
+int mesh_layers_menu_charlen(struct CustomData *data, int type); /* use this to work out how many chars to allocate */
+void mesh_layers_menu_concat(struct CustomData *data, int type, char *str);
+int mesh_layers_menu(struct CustomData *data, int type);
+
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index ce3f33bd35c..fba30264fea 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -59,6 +59,12 @@ typedef enum {
eModifierTypeType_Constructive,
eModifierTypeType_Nonconstructive,
+
+ /* both deformVerts & applyModifier are valid calls
+ * used for particles modifier that doesn't actually modify the object
+ * unless it's a mesh and can be exploded -> curve can also emit particles
+ */
+ eModifierTypeType_DeformOrConstruct
} ModifierTypeType;
typedef enum {
@@ -79,10 +85,14 @@ typedef enum {
* be placed after any non-deformative modifier.
*/
eModifierTypeFlag_RequiresOriginalData = (1<<5),
+
+ /* For modifiers that support pointcache, so we can check to see if it has files we need to deal with
+ */
+ eModifierTypeFlag_UsesPointCache = (1<<6),
} ModifierTypeFlag;
-typedef void (*ObjectWalkFunc)(void *userData, Object *ob, Object **obpoin);
-typedef void (*IDWalkFunc)(void *userData, Object *ob, ID **idpoin);
+typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin);
+typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin);
typedef struct ModifierTypeInfo {
/* The user visible name for this modifier */
@@ -125,6 +135,11 @@ typedef struct ModifierTypeInfo {
struct EditMesh *editData, struct DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts);
+ /* Set deform matrix per vertex for crazyspace correction */
+ void (*deformMatricesEM)(
+ struct ModifierData *md, struct Object *ob,
+ struct EditMesh *editData, struct DerivedMesh *derivedData,
+ float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
/********************* Non-deform modifier functions *********************/
@@ -257,6 +272,7 @@ void modifier_copyData(struct ModifierData *md, struct ModifierData *ta
int modifier_dependsOnTime(struct ModifierData *md);
int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage(struct ModifierData *md);
+int modifier_isDeformer(struct ModifierData *md);
void modifier_setError(struct ModifierData *md, char *format, ...);
void modifiers_foreachObjectLink(struct Object *ob,
@@ -271,10 +287,16 @@ int modifiers_getCageIndex(struct Object *ob,
int *lastPossibleCageIndex_r);
int modifiers_isSoftbodyEnabled(struct Object *ob);
+int modifiers_isClothEnabled(struct Object *ob);
+int modifiers_isParticleEnabled(struct Object *ob);
+
struct Object *modifiers_isDeformedByArmature(struct Object *ob);
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
int modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
int modifiers_isDeformed(struct Object *ob);
+void modifier_freeTemporaryData(struct ModifierData *md);
+
+int modifiers_indexInObject(struct Object *ob, struct ModifierData *md);
/* Calculates and returns a linked list of CustomDataMasks indicating the
* data required by each modifier in the stack pointed to by md for correct
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
new file mode 100644
index 00000000000..61eb796e53d
--- /dev/null
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -0,0 +1,68 @@
+/*
+ * $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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+struct CustomData;
+struct EditMesh;
+struct Multires;
+struct MultiresLevel;
+struct Mesh;
+struct Object;
+
+/* Level access */
+struct MultiresLevel *current_level(struct Multires *mr);
+struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
+
+/* Level control */
+void multires_add_level(struct Object *ob, struct Mesh *me, const char subdiv_type);
+void multires_set_level(struct Object *ob, struct Mesh *me, const int render);
+void multires_free_level(struct MultiresLevel *lvl);
+
+void multires_edge_level_update(struct Object *ob, struct Mesh *me);
+
+void multires_free(struct Multires *mr);
+struct Multires *multires_copy(struct Multires *orig);
+void multires_create(struct Object *ob, struct Mesh *me);
+
+/* CustomData */
+void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n);
+void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n);
+void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl);
+void multires_to_mcol(struct MultiresColFace *f, MCol mcol[4]);
+/* After adding or removing vcolor layers, run this */
+void multires_load_cols(struct Mesh *me);
+
+/* Private (used in multires-firstlevel.c) */
+void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render);
+void multires_update_levels(struct Mesh *me, const int render);
+void multires_update_first_level(struct Mesh *me, struct EditMesh *em);
+void multires_update_customdata(struct MultiresLevel *lvl1, struct CustomData *src,
+ struct CustomData *dst, const int type);
+void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em,
+ struct MultiresLevel *lvl, struct CustomData *src,
+ struct CustomData *dst, const int type);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 44266a1c854..76581e4f34f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -87,8 +87,8 @@ typedef struct bNodeType {
/* for use with dynamic typedefs */
ID *id;
- void *script; /* holds pointer to python script */
- void *dict; /* holds pointer to python script dictionary (scope)*/
+ void *pynode; /* holds pointer to python script */
+ void *pydict; /* holds pointer to python script dictionary (scope)*/
} bNodeType;
@@ -103,13 +103,14 @@ typedef struct bNodeType {
#define NODE_CLASS_INPUT 0
#define NODE_CLASS_OUTPUT 1
#define NODE_CLASS_OP_COLOR 3
-#define NODE_CLASS_OP_VECTOR 4
-#define NODE_CLASS_OP_FILTER 5
+#define NODE_CLASS_OP_VECTOR 4
+#define NODE_CLASS_OP_FILTER 5
#define NODE_CLASS_GROUP 6
#define NODE_CLASS_FILE 7
-#define NODE_CLASS_CONVERTOR 8
+#define NODE_CLASS_CONVERTOR 8
#define NODE_CLASS_MATTE 9
#define NODE_CLASS_DISTORT 10
+#define NODE_CLASS_OP_DYNAMIC 11
/* ************** GENERIC API, TREES *************** */
@@ -119,6 +120,7 @@ struct bNodeTree *ntreeAddTree(int type);
void ntreeInitTypes(struct bNodeTree *ntree);
void ntreeMakeOwnType(struct bNodeTree *ntree);
+void ntreeUpdateType(struct bNodeTree *ntree, struct bNodeType *ntype);
void ntreeFreeTree(struct bNodeTree *ntree);
struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree, int internal_select);
void ntreeMakeLocal(struct bNodeTree *ntree);
@@ -143,13 +145,21 @@ void nodeVerifyType(struct bNodeTree *ntree, struct bNode *node);
void nodeAddToPreview(struct bNode *, float *, int, int);
-struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup);
+void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
+void nodeAddSockets(struct bNode *node, struct bNodeType *ntype);
+struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup, struct ID *id);
+void nodeRegisterType(struct ListBase *typelist, const struct bNodeType *ntype) ;
+void nodeUpdateType(struct bNodeTree *ntree, struct bNode* node, struct bNodeType *ntype);
+void nodeMakeDynamicType(struct bNode *node);
+int nodeDynamicUnlinkText(struct ID *txtid);
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
-struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
+struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal);
struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock);
void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link);
+int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex);
+
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to);
int nodeCountSocketLinks(struct bNodeTree *ntree, struct bNodeSocket *sock);
@@ -169,10 +179,13 @@ int nodeGroupUnGroup(struct bNodeTree *ntree, struct bNode *gnode);
void nodeVerifyGroup(struct bNodeTree *ngroup);
void nodeGroupSocketUseFlags(struct bNodeTree *ngroup);
+void nodeCopyGroup(struct bNode *gnode);
+
/* ************** COMMON NODES *************** */
#define NODE_GROUP 2
#define NODE_GROUP_MENU 1000
+#define NODE_DYNAMIC_MENU 4000
extern bNodeType node_group_typeinfo;
@@ -189,7 +202,7 @@ struct ShadeResult;
#define SH_NODE_OUTPUT 1
#define SH_NODE_MATERIAL 100
-#define SH_NODE_RGB 101
+#define SH_NODE_RGB 101
#define SH_NODE_VALUE 102
#define SH_NODE_MIX_RGB 103
#define SH_NODE_VALTORGB 104
@@ -206,12 +219,24 @@ struct ShadeResult;
#define SH_NODE_SQUEEZE 117
#define SH_NODE_MATERIAL_EXT 118
#define SH_NODE_INVERT 119
-
+#define SH_NODE_SEPRGB 120
+#define SH_NODE_COMBRGB 121
+#define SH_NODE_HUE_SAT 122
+#define NODE_DYNAMIC 123
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
#define SH_NODE_MAT_SPEC 2
#define SH_NODE_MAT_NEG 4
+/* custom defines: states for Script node. These are bit indices */
+#define NODE_DYNAMIC_READY 0 /* 1 */
+#define NODE_DYNAMIC_LOADED 1 /* 2 */
+#define NODE_DYNAMIC_NEW 2 /* 4 */
+#define NODE_DYNAMIC_UPDATED 3 /* 8 */
+#define NODE_DYNAMIC_ADDEXIST 4 /* 16 */
+#define NODE_DYNAMIC_ERROR 5 /* 32 */
+#define NODE_DYNAMIC_REPARSE 6 /* 64 */
+#define NODE_DYNAMIC_SET 15 /* sign */
/* the type definitions array */
extern struct ListBase node_all_shaders;
@@ -230,21 +255,22 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
/* ************** COMPOSITE NODES *************** */
/* output socket defines */
-#define RRES_OUT_IMAGE 0
-#define RRES_OUT_ALPHA 1
-#define RRES_OUT_Z 2
-#define RRES_OUT_NORMAL 3
-#define RRES_OUT_UV 4
-#define RRES_OUT_VEC 5
-#define RRES_OUT_RGBA 6
-#define RRES_OUT_DIFF 7
-#define RRES_OUT_SPEC 8
-#define RRES_OUT_SHADOW 9
-#define RRES_OUT_AO 10
-#define RRES_OUT_REFLECT 11
-#define RRES_OUT_REFRACT 12
-#define RRES_OUT_RADIO 13
-#define RRES_OUT_INDEXOB 14
+#define RRES_OUT_IMAGE 0
+#define RRES_OUT_ALPHA 1
+#define RRES_OUT_Z 2
+#define RRES_OUT_NORMAL 3
+#define RRES_OUT_UV 4
+#define RRES_OUT_VEC 5
+#define RRES_OUT_RGBA 6
+#define RRES_OUT_DIFF 7
+#define RRES_OUT_SPEC 8
+#define RRES_OUT_SHADOW 9
+#define RRES_OUT_AO 10
+#define RRES_OUT_REFLECT 11
+#define RRES_OUT_REFRACT 12
+#define RRES_OUT_RADIO 13
+#define RRES_OUT_INDEXOB 14
+#define RRES_OUT_MIST 15
/* note: types are needed to restore callbacks, don't change values */
#define CMP_NODE_VIEWER 201
@@ -298,6 +324,15 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
#define CMP_NODE_BRIGHTCONTRAST 249
#define CMP_NODE_GAMMA 250
#define CMP_NODE_INVERT 251
+#define CMP_NODE_NORMALIZE 252
+#define CMP_NODE_CROP 253
+#define CMP_NODE_DBLUR 254
+#define CMP_NODE_BILATERALBLUR 255
+#define CMP_NODE_PREMULKEY 256
+
+#define CMP_NODE_GLARE 301
+#define CMP_NODE_TONEMAP 302
+#define CMP_NODE_LENSDIST 303
/* channel toggles */
#define CMP_CHAN_RGB 1
@@ -316,8 +351,9 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, str
#define CMP_FILT_SHADOW 6
/* scale node type, in custom1 */
-#define CMP_SCALE_RELATIVE 0
-#define CMP_SCALE_ABSOLUTE 1
+#define CMP_SCALE_RELATIVE 0
+#define CMP_SCALE_ABSOLUTE 1
+#define CMP_SCALE_SCENEPERCENT 2
/* the type definitions array */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 52d529ea32d..903ca7a66aa 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -45,11 +45,16 @@ struct BoundBox;
struct View3D;
struct SoftBody;
struct Group;
+struct bAction;
void clear_workob(void);
void copy_baseflags(void);
void copy_objectflags(void);
struct SoftBody *copy_softbody(struct SoftBody *sb);
+void copy_object_particlesystems(struct Object *obn, struct Object *ob);
+void copy_object_softbody(struct Object *obn, struct Object *ob);
+void object_free_particlesystems(struct Object *ob);
+void object_free_softbody(struct Object *ob);
void update_base_layer(struct Object *ob);
void free_object(struct Object *ob);
@@ -63,6 +68,7 @@ int exist_object(struct Object *obtest);
void *add_camera(char *name);
struct Camera *copy_camera(struct Camera *cam);
void make_local_camera(struct Camera *cam);
+float dof_camera(struct Object *ob);
void *add_lamp(char *name);
struct Lamp *copy_lamp(struct Lamp *la);
void make_local_lamp(struct Lamp *la);
@@ -81,7 +87,7 @@ void set_mblur_offs(float blur);
void set_field_offs(float field);
void disable_speed_curve(int val);
-float bsystem_time(struct Object *ob, struct Object *par, float cfra, float ofs);
+float bsystem_time(struct Object *ob, float cfra, float ofs);
void object_to_mat3(struct Object *ob, float mat[][3]);
void object_to_mat4(struct Object *ob, float mat[][4]);
@@ -97,6 +103,7 @@ void where_is_object(struct Object *ob);
void where_is_object_simul(struct Object *ob);
void what_does_parent(struct Object *ob);
+
struct BoundBox *unit_boundbox(void);
void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]);
struct BoundBox *object_get_boundbox(struct Object *ob);
@@ -104,13 +111,13 @@ void object_boundbox_flag(struct Object *ob, int flag, int set);
void minmax_object(struct Object *ob, float *min, float *max);
void minmax_object_duplis(struct Object *ob, float *min, float *max);
void solve_tracking (struct Object *ob, float targetmat[][4]);
-void solve_constraints (struct Object *ob, short obtype, void *obdata, float ctime);
void object_handle_update(struct Object *ob);
+float give_timeoffset(struct Object *ob);
+
#ifdef __cplusplus
}
#endif
#endif
-
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
new file mode 100644
index 00000000000..e0b935fc106
--- /dev/null
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -0,0 +1,317 @@
+/* BKE_particle.h
+ *
+ *
+ * $Id: BKE_particle.h $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_PARTICLE_H
+#define BKE_PARTICLE_H
+
+#include "DNA_particle_types.h"
+#include "DNA_object_types.h"
+
+struct ParticleSystemModifierData;
+struct ParticleSystem;
+struct ParticleKey;
+struct HairKey;
+
+struct Main;
+struct Group;
+struct Object;
+struct DerivedMesh;
+struct ModifierData;
+struct MTFace;
+struct MCol;
+struct MFace;
+struct MVert;
+struct IpoCurve;
+struct LinkNode;
+struct KDTree;
+struct RNG;
+
+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;
+
+ short type, psys_nbr;
+
+ struct Object obcopy; /* for restoring transformation data */
+} ParticleEffectorCache;
+
+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 */
+ float time, life, exist, size; /* used in init */
+ float pvel[3]; /* used in physics */
+ float length, clump, kink, rough; /* used in path caching */
+} ParticleTexture;
+
+typedef struct BoidVecFunc{
+ void (*Addf)(float *v, float *v1, float *v2);
+ void (*Subf)(float *v, float *v1, float *v2);
+ void (*Mulf)(float *v, float f);
+ float (*Length)(float *v);
+ float (*Normalize)(float *v);
+ float (*Inpf)(float *v1, float *v2);
+ void (*Copyf)(float *v1, float *v2);
+} BoidVecFunc;
+
+typedef struct ParticleSeam{
+ float v0[3], v1[3];
+ float nor[3], dir[3], tan[3];
+ float length2;
+} ParticleSeam;
+
+typedef struct ParticleCacheKey{
+ float co[3];
+ float vel[3];
+ float col[3];
+ float rot[4];
+ int steps;
+} ParticleCacheKey;
+
+typedef struct ParticleEditKey{
+ float *co;
+ float *vel;
+ float *rot;
+ float *time;
+
+ float world_co[3];
+ float length;
+ short flag;
+} ParticleEditKey;
+
+typedef struct ParticleUndo {
+ struct ParticleUndo *next, *prev;
+ struct ParticleEditKey **keys;
+ struct KDTree *emitter_field;
+ struct ParticleData *particles;
+ float *emitter_cosnos;
+ int totpart, totkeys;
+ char name[64];
+} ParticleUndo;
+
+typedef struct ParticleEdit{
+ ListBase undo;
+ struct ParticleUndo *curundo;
+ struct KDTree *emitter_field;
+ ParticleEditKey **keys;
+ int *mirror_cache;
+ float *emitter_cosnos;
+
+ int totkeys;
+} ParticleEdit;
+
+typedef struct ParticleThreadContext {
+ /* shared */
+ struct Object *ob;
+ struct DerivedMesh *dm;
+ struct ParticleSystemModifierData *psmd;
+ struct ParticleSystem *psys;
+ struct Material *ma;
+
+ /* distribution */
+ struct KDTree *tree;
+
+ struct ParticleSeam *seams;
+ int totseam;
+
+ float *jit, *jitoff, *weight;
+ float maxweight;
+ int *index, *skip, jitlevel;
+
+ int from, cfrom, distr;
+
+ struct ParticleData *tpars;
+
+ /* path caching */
+ int editupdate, between, steps;
+ int totchild, totparent;
+
+ float cfra;
+
+ float *vg_length, *vg_clump, *vg_kink;
+ float *vg_rough1, *vg_rough2, *vg_roughe;
+ float *vg_effector;
+} ParticleThreadContext;
+
+typedef struct ParticleThread {
+ ParticleThreadContext *ctx;
+ struct RNG *rng, *rng_path;
+ int num, tot;
+} ParticleThread;
+
+/* ----------- 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);
+short psys_get_current_num(struct Object *ob);
+//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 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);
+int psys_in_edit_mode(struct ParticleSystem *psys);
+int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
+
+void psys_free_settings(struct ParticleSettings *part);
+void free_child_path_cache(struct ParticleSystem *psys);
+void psys_free_path_cache(struct ParticleSystem *psys);
+void free_hair(struct ParticleSystem *psys);
+void free_keyed_keys(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);
+int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
+int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
+
+void clear_particles_from_cache(struct Object *ob, struct ParticleSystem *psys, int cfra);
+//void psys_remove_from_particle_list(struct Object *ob, short nbr, struct ParticleSystem *psys);
+
+void psys_interpolate_uvs(struct MTFace *tface, int quad, float *uv, float *uvco);
+void psys_interpolate_mcol(struct MCol *mcol, int quad, float *uv, struct MCol *mc);
+
+void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
+
+void psys_particle_on_emitter(struct Object *ob, struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
+struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
+
+struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
+struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
+void psys_flush_settings(struct ParticleSettings *part, int event, int hair_recalc);
+
+void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys);
+
+void psys_cache_paths(struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
+void psys_cache_child_paths(struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
+int do_guide(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);
+float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra);
+float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
+void psys_get_particle_on_path(struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel);
+int psys_get_particle_state(struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always);
+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);
+
+ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys, int totthread);
+int psys_threads_init_distribution(ParticleThread *threads, struct DerivedMesh *dm, int from);
+int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate);
+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);
+
+/* particle_system.c */
+int 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 Object *obsrc, struct Group *group, struct ParticleSystem *psys);
+void psys_end_effectors(struct ParticleSystem *psys);
+
+void particle_system_update(struct Object *ob, struct ParticleSystem *psys);
+
+/* ----------- functions needed only inside particlesystem ------------ */
+/* particle.c */
+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]);
+
+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_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_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);
+
+int psys_intersect_dm(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);
+void psys_particle_on_dm(struct Object *ob, 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);
+void reset_particle(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 do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
+
+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);
+
+/* ParticleEffectorCache->type */
+#define PSYS_EC_EFFECTOR 1
+#define PSYS_EC_DEFLECT 2
+#define PSYS_EC_PARTICLE 4
+#define PSYS_EC_REACTOR 8
+
+/* ParticleEditKey->flag */
+#define PEK_SELECT 1
+#define PEK_TO_SELECT 2
+#define PEK_TAG 4
+#define PEK_HIDE 8
+
+/* index_dmcache */
+#define DMCACHE_NOTFOUND -1
+#define DMCACHE_ISCHILD -2
+
+#endif
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
new file mode 100644
index 00000000000..12068f7dedf
--- /dev/null
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -0,0 +1,54 @@
+/*
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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): Campbell Barton <ideasman42@gmail.com>
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
+
+#ifndef BKE_POINTCACHE_H
+#define BKE_POINTCACHE_H
+
+#include "DNA_ID.h"
+
+/* options for clearing pointcache - used for BKE_ptcache_id_clear
+ Before and after are non inclusive (they wont remove the cfra) */
+#define PTCACHE_CLEAR_ALL 0
+#define PTCACHE_CLEAR_FRAME 1
+#define PTCACHE_CLEAR_BEFORE 2
+#define PTCACHE_CLEAR_AFTER 3
+
+/* Add the blendfile name after blendcache_ */
+#define PTCACHE_EXT ".bphys"
+#define PTCACHE_PATH "blendcache_"
+
+/* Global funcs */
+void BKE_ptcache_remove(void);
+
+/* Object spesific funcs */
+int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
+FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
+void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index);
+int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index);
+
+#endif
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 69ff6876acd..66ae5d5e1cd 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -34,11 +34,14 @@
#ifndef BKE_SCENE_H
#define BKE_SCENE_H
+struct bglMats;
struct Scene;
struct Object;
struct Base;
struct AviCodecData;
struct QuicktimeCodecData;
+struct SculptData;
+struct RenderData;
/* sequence related defines */
#define WHILE_SEQ(base) { \
@@ -80,5 +83,11 @@ void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
void scene_add_render_layer(struct Scene *sce);
+/* render profile */
+int get_render_subsurf_level(struct RenderData *r, int level);
+int get_render_child_particle_number(struct RenderData *r, int num);
+int get_render_shadow_samples(struct RenderData *r, int samples);
+float get_render_aosss_error(struct RenderData *r, float error);
+
#endif
diff --git a/source/blender/blenkernel/BKE_sculpt.h b/source/blender/blenkernel/BKE_sculpt.h
new file mode 100644
index 00000000000..e03e38bab75
--- /dev/null
+++ b/source/blender/blenkernel/BKE_sculpt.h
@@ -0,0 +1,74 @@
+/*
+ * $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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_SCULPT_H
+#define BKE_SCULPT_H
+
+struct NumInput;
+struct RadialControl;
+struct Scene;
+struct SculptData;
+struct SculptSession;
+
+typedef struct SculptSession {
+ struct ProjVert *projverts;
+
+ struct bglMats *mats;
+
+ /* An array of lists; array is sized as
+ large as the number of verts in the mesh,
+ the list for each vert contains the index
+ for all the faces that use that vertex */
+ struct ListBase *vertex_users;
+ struct IndexNode *vertex_users_mem;
+ int vertex_users_size;
+
+ /* Used temporarily per-stroke */
+ float *vertexcosnos;
+ ListBase damaged_rects;
+ ListBase damaged_verts;
+
+ /* Used to cache the render of the active texture */
+ unsigned int texcache_w, texcache_h, *texcache;
+
+ struct RadialControl *radialcontrol;
+
+ /* For rotating around a pivot point */
+ vec3f pivot;
+
+ struct SculptStroke *stroke;
+} SculptSession;
+
+void sculptdata_init(struct Scene *sce);
+void sculptdata_free(struct Scene *sce);
+void sculptsession_free(struct Scene *sce);
+void sculpt_vertexusers_free(struct SculptSession *ss);
+void sculpt_reset_curve(struct SculptData *sd);
+
+#endif
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 15200bf46f8..91bc4cc070d 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -37,12 +37,26 @@
struct Object;
struct SoftBody;
+typedef struct BodyPoint {
+ float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
+ float goal;
+ float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
+ float impdv[3],impdx[3];
+ int nofsprings; int *springs;
+ float choke,choke2,frozen;
+ float colball;
+ short flag;
+ char octantflag;
+} BodyPoint;
+
/* allocates and initializes general main data */
extern struct SoftBody *sbNew(void);
/* frees internal data and softbody itself */
extern void sbFree(struct SoftBody *sb);
+extern void softbody_clear_cache(struct Object *ob, float framenr);
+
/* do one simul step, reading and writing vertex locs from given array */
extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 35f0ee841be..c4a2ffe369b 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -95,7 +95,8 @@ void indent (struct Text *text);
void uncomment (struct Text *text);
int setcurr_tab (struct Text *text);
void convert_tabs (struct SpaceText *st, int tab);
-
+void txt_copy_clipboard (struct Text *text);
+void txt_paste_clipboard (struct Text *text);
/* Undo opcodes */
/* Simple main cursor movement */
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 83229ec35a2..902423482b1 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -52,8 +52,11 @@ int test_dlerr(const char *name, const char *symbol);
void open_plugin_tex(struct PluginTex *pit);
struct PluginTex *add_plugin_tex(char *str);
void free_plugin_tex(struct PluginTex *pit);
+
+void init_colorband(struct ColorBand *coba, int rangetype);
struct ColorBand *add_colorband(int rangetype);
int do_colorband(struct ColorBand *coba, float in, float out[4]);
+
void default_tex(struct Tex *tex);
struct Tex *add_texture(char *name);
void default_mtex(struct MTex *mtex);
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 81dd2807812..d53ee212ee5 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -57,6 +57,11 @@
#define ELEM6(a, b, c, d, e, f, g) ( ELEM(a, b, c) || ELEM4(a, d, e, f, g) )
#define ELEM7(a, b, c, d, e, f, g, h) ( ELEM3(a, b, c, d) || ELEM4(a, e, f, g, h) )
#define ELEM8(a, b, c, d, e, f, g, h, i) ( ELEM4(a, b, c, d, e) || ELEM4(a, f, g, h, i) )
+#define ELEM9(a, b, c, d, e, f, g, h, i, j) ( ELEM4(a, b, c, d, e) || ELEM5(a, f, g, h, i, j) )
+
+/* shift around elements */
+#define SHIFT3(type, a, b, c) { type tmp; tmp = a; a = c; c = b; b = tmp; }
+#define SHIFT4(type, a, b, c, d) { type tmp; tmp = a; a = d; d = c; c = b; b = tmp; }
/* string compare */
#define STREQ(str, a) ( strcmp((str), (a))==0 )
@@ -96,14 +101,19 @@
#define ABS(a) ( (a)<0 ? (-(a)) : (a) )
+#define AVG2(x, y) ( 0.5 * ((x) + (y)) )
+
#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);}
+#define VECCOPY2D(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1);}
#define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);}
#define LONGCOPY(a, b, c) {int lcpc=c, *lcpa=(int *)a, *lcpb=(int *)b; while(lcpc-->0) *(lcpa++)= *(lcpb++);}
#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);}
#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);}
+#define VECSUB2D(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1);}
#define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);}
+#define QUATADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac); *(v1+3)= *(v2+3) + *(v3+3)*(fac);}
#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] )
@@ -162,20 +172,22 @@
/* This one rotates the bytes in an int */
#define SWITCH_INT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
- s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
+ char s_i, *p_i; \
+ p_i= (char *)&(a); \
+ s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
+ s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
#define SWITCH_SHORT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; }
+ char s_i, *p_i; \
+ p_i= (char *)&(a); \
+ s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; }
/* Bit operations */
-#define BTST(a,b) ( ( (a) & 1<<(b) )!=0 )
-#define BSET(a,b) ( (a) | 1<<(b) )
+#define BTST(a,b) ( ( (a) & 1<<(b) )!=0 )
+#define BNTST(a,b) ( ( (a) & 1<<(b) )==0 )
+#define BTST2(a,b,c) ( BTST( (a), (b) ) || BTST( (a), (c) ) )
+#define BSET(a,b) ( (a) | 1<<(b) )
#define BCLR(a,b) ( (a) & ~(1<<(b)) )
/* bit-row */
#define BROW(min, max) (((max)>=31? 0xFFFFFFFF: (1<<(max+1))-1) - ((min)? ((1<<(min))-1):0) )
@@ -186,5 +198,10 @@
#endif
#define GS(a) (*((short *)(a)))
+/* Warning-free macros for storing ints in pointers. Use these _only_
+ * for storing an int in a pointer, not a pointer in an int (64bit)! */
+#define SET_INT_IN_POINTER(i) ((void*)(long)(i))
+#define GET_INT_FROM_POINTER(i) ((int)(long)(i))
+
#endif
diff --git a/source/blender/blenkernel/BKE_verse.h b/source/blender/blenkernel/BKE_verse.h
index fe5fc44ba1e..aba42302364 100644
--- a/source/blender/blenkernel/BKE_verse.h
+++ b/source/blender/blenkernel/BKE_verse.h
@@ -46,21 +46,12 @@ struct VerseEdge;
#define VEDHASH(a, b) ((a<b ? a : b) % VEDHASHSIZE)
/*
- * virtual data type (used only for retype)
- */
-typedef struct verse_parent {
- struct verse_parent *next, *prev;
- VLayerID layer_id;
- uint32 id;
-} verse_parent;
-
-/*
* verse data: 4 float value
*/
typedef struct quat_real32_item {
struct quat_real32_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
real32 value[4];
} quat_real32_item;
@@ -69,8 +60,8 @@ typedef struct quat_real32_item {
*/
typedef struct quat_uint32_item {
struct quat_uint32_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
uint32 value[4];
} quat_uint32_item;
@@ -79,8 +70,8 @@ typedef struct quat_uint32_item {
*/
typedef struct vec_real32_item {
struct vec_real32_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
real32 value[3];
} vec_real32_item;
@@ -89,8 +80,8 @@ typedef struct vec_real32_item {
*/
typedef struct real32_item {
struct real32_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
real32 value;
} real32_item;
@@ -99,8 +90,8 @@ typedef struct real32_item {
*/
typedef struct uint32_item {
struct uint32_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
uint32 value;
} uint32_item;
@@ -109,8 +100,8 @@ typedef struct uint32_item {
*/
typedef struct uint8_item {
struct uint8_item *next, *prev;
- VLayerID layer_id;
- void *parent;
+ struct VLayer *vlayer; /* pointer at VerseLayer */
+ uint32 id; /* id of item */
uint8 value;
} uint8_item;
@@ -335,6 +326,30 @@ typedef struct VTagGroup {
void (*post_taggroup_create)(struct VTagGroup *vtaggroup);
} VTagGroup;
+ /*
+ * Verse Method Group
+ */
+typedef struct VMethodGroup
+{
+ struct VMethodGroup *next, *prev;
+ uint16 group_id;
+ char name[16];
+ struct ListBase methods;
+} VMethodGroup;
+
+/*
+ * Verse Method
+ */
+typedef struct VMethod
+{
+ struct VMethod *next, *prev;
+ uint16 id;
+ char name[500];
+ uint8 param_count;
+ VNOParamType *param_type;
+ char **param_name;
+} VMethod;
+
/*
* Verse Node
*/
@@ -349,6 +364,7 @@ typedef struct VNode {
/* blender internals */
char flag; /* flags: NODE_SENT, NODE_RECEIVED, NODE_DELTED, NODE_OBSOLETE */
struct DynamicList taggroups; /* dynamic list with access array of taggroups */
+ struct ListBase methodgroups; /* method groups */
struct ListBase queue; /* list of taggroups waiting for receiving from verse server */
void *data; /* generic pointer at some data (VObjectData, VGeomData, ...) */
int counter; /* counter of verse link pointing at this vnode (vlink->target) */
@@ -356,6 +372,10 @@ typedef struct VNode {
void (*post_node_create)(struct VNode *vnode);
void (*post_node_destroy)(struct VNode *vnode);
void (*post_node_name_set)(struct VNode *vnode);
+#ifdef VERSECHAT
+ /* verse chat */
+ int chat_flag; /* CHAT_LOGGED, CHAT_NOTLOGGED */
+#endif
} VNode;
@@ -411,6 +431,11 @@ typedef struct PostCallbackFunction {
#define NODE_DELTED 4
#define NODE_OBSOLETE 8
+#ifdef VERSECHAT
+#define CHAT_NOTLOGGED 0
+#define CHAT_LOGGED 1
+#endif
+
/* VLayer flags */
#define LAYER_SENT 1
#define LAYER_RECEIVED 2
@@ -482,7 +507,7 @@ struct VerseSession *current_verse_session(void);
struct VerseSession *create_verse_session(const char *name, const char *pass, const char *address, uint8 *expected_key);
void free_verse_session(struct VerseSession *session);
void b_verse_update(void);
-void b_vers_ms_get(void);
+void b_verse_ms_get(void);
void b_verse_connect(char *address);
void end_verse_session(struct VerseSession *session);
void end_all_verse_sessions(void);
@@ -493,6 +518,7 @@ void send_verse_taggroup(struct VTagGroup *vtaggroup);
void send_verse_node(struct VNode *vnode);
void free_verse_node_data(struct VNode *vnode);
void free_verse_node(struct VNode *vnode);
+struct VNode* lookup_vnode(VerseSession *session, VNodeID node_id);
struct VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNodeID owner_id);
void set_node_callbacks(void);
@@ -508,6 +534,18 @@ void send_verse_link(struct VLink *vlink);
void free_object_data(struct VNode *vnode);
void set_object_callbacks(void);
struct VObjectData *create_object_data(void);
+
+
+/* functions from verse_method.c */
+void free_verse_methodgroup(VMethodGroup *vmg);
+#ifdef VERSECHAT
+void send_say(const char *chan, const char *utter);
+void send_login(struct VNode *vnode);
+void send_logout(struct VNode *vnode);
+void send_join(struct VNode *vnode, const char *chan);
+void send_leave(struct VNode *vnode, const char *chan);
+#endif
+void set_method_callbacks(void);
/* functions from verse_geometry_node.c */
struct VerseFace* create_verse_face(struct VLayer *vlayer, uint32 polygon_id, uint32 v0, uint32 v1, uint32 v2, uint32 v3);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b8c23a6517d..ea6bc2179fe 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -32,11 +32,13 @@ FILE(GLOB SRC intern/*.c)
SET(INC
. ../../../intern/guardedalloc ../include ../blenlib ../makesdna
../python ../render/extern/include ../../../intern/decimation/extern
- ../imbuf ../avi ../../../intern/elbeem/extern
+ ../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
../../../intern/iksolver/extern ../blenloader ../quicktime
+ ../../../intern/bmfont ../../../extern/bullet2/src
../nodes
${SDL_INC}
${ZLIB_INC}
+ ${PYTHON_INC}
)
IF(WITH_VERSE)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index d7b48105d3d..1bb98239a68 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -7,7 +7,11 @@ incs = '. #/intern/guardedalloc ../include ../blenlib ../makesdna'
incs += ' ../python ../render/extern/include #/intern/decimation/extern'
incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes'
incs += ' #/intern/iksolver/extern ../blenloader ../quicktime'
+incs += ' #/extern/bullet2/src'
+incs += ' #/intern/bmfont'
+incs += ' #/intern/opennl/extern'
+incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC']
incs += ' ' + env['BF_SDL_INC']
@@ -27,6 +31,9 @@ if env['WITH_BF_VERSE']:
if env['WITH_BF_OPENEXR'] == 1:
defs += ' WITH_OPENEXR'
+if env['WITH_BF_DDS'] == 1:
+ defs += ' WITH_DDS'
+
if env['WITH_BF_FFMPEG'] == 1:
defs += ' WITH_FFMPEG'
incs += ' ' + env['BF_FFMPEG_INC']
diff --git a/source/blender/blenkernel/bad_level_call_stubs/Makefile b/source/blender/blenkernel/bad_level_call_stubs/Makefile
index 2d98ea5a1af..1d4db1037ea 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/Makefile
+++ b/source/blender/blenkernel/bad_level_call_stubs/Makefile
@@ -39,10 +39,6 @@ include nan_compile.mk
CFLAGS += $(LEVEL_2_C_WARNINGS)
CFLAGS += $(FIX_STUBS_WARNINGS)
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CPPFLAGS += $(OGL_CPPFLAGS)
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../include
diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
index 344f763608c..1da46149eac 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c
+++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
@@ -36,7 +36,7 @@
#include "BKE_bad_level_calls.h"
#include "BLI_blenlib.h"
-#include "BPI_script.h"
+#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -49,14 +49,21 @@
int winqueue_break= 0;
char bprogname[1];
+char btempdir[1];
struct IpoCurve;
struct FluidsimSettings;
struct Render;
struct RenderResult;
+struct Object;
+struct bPythonConstraint;
+struct bConstraintOb;
+struct bConstraintTarget;
+struct ListBase;
+struct EditFace;
char *getIpoCurveName( struct IpoCurve * icu );
-void insert_vert_ipo(struct IpoCurve *icu, float x, float y);
+void insert_vert_icu(struct IpoCurve *icu, float x, float y, short fast);
struct IpoCurve *verify_ipocurve(struct ID *id, short a, char *b, char *d, int e);
void elbeemDebugOut(char *msg);
void fluidsimSettingsFree(struct FluidsimSettings* sb);
@@ -80,7 +87,7 @@ char *getIpoCurveName( struct IpoCurve * icu )
return 0;
}
-void insert_vert_ipo(struct IpoCurve *icu, float x, float y)
+void insert_vert_icu(struct IpoCurve *icu, float x, float y, short fast)
{
}
@@ -114,6 +121,21 @@ float BPY_pydriver_eval(struct IpoDriver *driver)
{
return 0;
}
+int EXPP_dict_set_item_str(struct PyObject *dict, char *key, struct PyObject *value)
+{
+ return 0;
+}
+void Node_SetStack(struct BPy_Node *self, struct bNodeStack **stack, int type){}
+void InitNode(struct BPy_Node *self, struct bNode *node){}
+void Node_SetShi(struct BPy_Node *self, struct ShadeInput *shi){}
+struct BPy_NodeSockets *Node_CreateSockets(struct bNode *node)
+{
+ return 0;
+}
+int pytype_is_pynode(struct PyObject *pyob)
+{
+ return 0;
+}
/* depsgraph.c: */
struct Object **BPY_pydriver_get_objects(struct IpoDriver *driver)
{
@@ -124,6 +146,15 @@ int BPY_button_eval(char *expr, double *value)
return 0;
}
+/* PyConstraints - BPY_interface.c */
+void BPY_pyconstraint_eval(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets)
+{
+}
+void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct)
+{
+}
+
+
/* writefile.c */
/* struct Oops; */
void free_oops(struct Oops *oops){}
@@ -176,6 +207,20 @@ short pupmenu(char *instr){ return 0;} // will be general callback
void free_editing(struct Editing *ed){} // scenes and sequences problem...
void BPY_do_all_scripts (short int event){}
+/*editmesh_lib.c*/
+void EM_select_face(struct EditFace *efa, int sel) {}
+void EM_select_edge(struct EditEdge *eed, int sel) {}
+
+/*editmesh.c*/
+struct EditVert *addvertlist(float *vec, struct EditVert *example) { return 0;}
+struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example) { return 0;}
+struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges) { return 0;}
+struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2) { return 0;}
+/*edit.c*/
+
+void countall(void) {}
+
+
/* IKsolver stubs */
#include "IK_solver.h"
@@ -194,6 +239,9 @@ void IK_FreeSolver(IK_Solver *solver) {};
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight) {}
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight) {}
+void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle) {}
+float IK_SolverGetPoleAngle(IK_Solver *solver) { return 0.0f; }
+
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations) { return 0; }
/* exotic.c */
@@ -229,6 +277,8 @@ void fluidsimSettingsCopy(struct FluidsimSettings* sb) {}
/*new render funcs */
int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) { return 0; }
+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) { return 0; }
void RE_FreeRenderResult(struct RenderResult *rr) {}
void RE_GetResultImage(struct Render *re, struct RenderResult *rr) {}
@@ -243,7 +293,7 @@ void RE_FreeRender(Render *re) {}
void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr) {}
void RE_DataBase_GetView(Render *re, float mat[][4]) {}
struct Render *RE_NewRender(const char *name) {return (struct Render *)NULL;}
-void RE_Database_Baking(struct Render *re, struct Scene *scene, int make_faces) {};
+void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob) {};
/* node_composite.c */
@@ -291,15 +341,6 @@ void post_geometry_free_constraint(struct VNode *vnode) {}
void post_layer_create(struct VLayer *vlayer) {}
void post_layer_destroy(struct VLayer *vlayer) {}
void post_server_add(void) {}
- /* Multires/sculpt stubs */
-struct MultiresLevel *multires_level_n(struct Multires *mr, int n) {return NULL;}
-void multires_free(struct Multires *mr) {}
-void multires_set_level(struct Object *ob, struct Mesh *me, const int render) {}
-void multires_update_levels(struct Mesh *me, const int render) {}
-void multires_calc_level_maps(struct MultiresLevel *lvl) {}
-struct Multires *multires_copy(struct Multires *orig) {return NULL;}
-void sculptmode_init(struct Scene *sce) {}
-void sculptmode_free_all(struct Scene *sce) {}
/* zbuf.c stub */
void antialias_tagbuf(int xsize, int ysize, char *rectmove) {}
@@ -307,6 +348,22 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) {}
/* imagetexture.c stub */
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {}
-void update_for_newframe()
-{
-}
+void update_for_newframe() {}
+
+struct FileList;
+void BIF_filelist_freelib(struct FileList* filelist) {};
+
+/* edittime.c stub */
+TimeMarker *get_frame_marker(int frame){return 0;};
+
+/* editseq.c */
+Sequence *get_forground_frame_seq(int frame){return 0;};
+
+/* modifier.c stub */
+void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
+ float (*vertexcos)[3], int totvert, float cagemat[][4]) {}
+
+/* particle.c */
+void PE_free_particle_edit(struct ParticleSystem *psys) {}
+void PE_get_colors(char sel[4], char nosel[4]) {}
+void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys) {}
diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c
new file mode 100644
index 00000000000..e34aba2d5d7
--- /dev/null
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -0,0 +1,394 @@
+/**
+ * BME_mesh.c jan 2007
+ *
+ * BMesh mesh level functions.
+ *
+ * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle, Levi Schooley.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_mesh.h"
+#include "BKE_bmesh.h"
+#include "BKE_global.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BIF_editmesh.h"
+#include "editmesh.h"
+#include "bmesh_private.h"
+
+#include "BSE_edit.h"
+
+BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em, BME_Mesh *bm) {
+ BME_Vert *v1, *v2;
+ BME_Edge *e, *edar[4];
+ BME_Poly *f;
+
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+
+ int len;
+
+ BME_model_begin(bm);
+
+ /*add verts*/
+ eve= em->verts.first;
+ while(eve) {
+ v1 = BME_MV(bm,eve->co);
+ VECCOPY(v1->no,eve->no);
+ v1->flag = eve->f;
+ v1->h = eve->h;
+ v1->bweight = eve->bweight;
+
+ /* link the verts for edge and face construction;
+ * kind of a dangerous thing - remember to cast back to BME_Vert before using! */
+ eve->tmp.v = (EditVert*)v1;
+ eve = eve->next;
+ }
+
+ /*add edges*/
+ eed= em->edges.first;
+ while(eed) {
+ v1 = (BME_Vert*)eed->v1->tmp.v;
+ v2 = (BME_Vert*)eed->v2->tmp.v;
+ e = BME_ME(bm, v1, v2);
+ e->crease = eed->crease;
+ e->bweight = eed->bweight;
+ e->flag = eed->f & SELECT;
+ if(eed->sharp) e->flag |= ME_SHARP;
+ if(eed->seam) e->flag |= ME_SEAM;
+ if(eed->h & EM_FGON) e->flag |= ME_FGON;
+ if(eed->h & 1) e->flag |= ME_HIDE;
+
+ /* link the edges for face construction;
+ * kind of a dangerous thing - remember to cast back to BME_Edge before using! */
+ eed->tmp.e = (EditEdge*)e;
+ eed = eed->next;
+ }
+
+ /*add faces.*/
+ efa= em->faces.first;
+ while(efa) {
+ if(efa->v4) len = 4;
+ else len = 3;
+
+ edar[0] = (BME_Edge*)efa->e1->tmp.e;
+ edar[1] = (BME_Edge*)efa->e2->tmp.e;
+ edar[2] = (BME_Edge*)efa->e3->tmp.e;
+ if(len == 4){
+ edar[3] = (BME_Edge*)efa->e4->tmp.e;
+ }
+
+ /*find v1 and v2*/
+ v1 = (BME_Vert*)efa->v1->tmp.v;
+ v2 = (BME_Vert*)efa->v2->tmp.v;
+
+ f = BME_MF(bm,v1,v2,edar,len);
+ f->mat_nr = efa->mat_nr;
+ f->flag = efa->flag;
+ if(efa->h) {
+ f->flag |= ME_HIDE;
+ f->flag &= ~ME_FACE_SEL;
+ }
+ else {
+ if(efa->f & 1) f->flag |= ME_FACE_SEL;
+ else f->flag &= ~ME_FACE_SEL;
+ }
+ efa = efa->next;
+ }
+ BME_model_end(bm);
+ return bm;
+}
+
+/* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh)
+ * if td != NULL, the transdata will be mapped to the EditVert's co */
+EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
+ BME_Vert *v1;
+ BME_Edge *e;
+ BME_Poly *f;
+
+ BME_TransData *vtd;
+
+ EditMesh *em;
+ EditVert *eve1, *eve2, *eve3, *eve4, **evlist;
+ EditEdge *eed;
+ EditFace *efa;
+
+ int totvert, len, i;
+
+ em = G.editMesh;
+
+ if (em == NULL) return NULL;
+
+ /* convert to EditMesh */
+ /* make editverts */
+ totvert = BLI_countlist(&(bm->verts));
+ evlist= (EditVert **)MEM_mallocN(totvert*sizeof(void *),"evlist");
+ for (i=0,v1=bm->verts.first;v1;v1=v1->next,i++) {
+ v1->tflag1 = i;
+ eve1 = addvertlist(v1->co,NULL);
+ if (td && (vtd = BME_get_transdata(td,v1))) {
+ vtd->loc = eve1->co;
+ }
+ eve1->keyindex = i;
+ evlist[i]= eve1;
+ eve1->f = (unsigned char)v1->flag;
+ eve1->h = (unsigned char)v1->h;
+ eve1->bweight = v1->bweight;
+ }
+
+ /* make edges */
+ for (e=bm->edges.first;e;e=e->next) {
+ if(!(findedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1]))){
+ eed= addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL);
+ eed->crease = e->crease;
+ eed->bweight = e->bweight;
+ if(e->flag & ME_SEAM) eed->seam = 1;
+ if(e->flag & ME_SHARP) eed->sharp = 1;
+ if(e->flag & SELECT) eed->f |= SELECT;
+ if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+ if(e->flag & ME_HIDE) eed->h |= 1;
+ if(G.scene->selectmode==SCE_SELECT_EDGE)
+ EM_select_edge(eed, eed->f & SELECT);
+ }
+ }
+
+ /* make faces */
+ for (f=bm->polys.first;f;f=f->next) {
+ len = BME_cycle_length(f->loopbase);
+ if (len==3 || len==4) {
+ eve1= evlist[f->loopbase->v->tflag1];
+ eve2= evlist[f->loopbase->next->v->tflag1];
+ eve3= evlist[f->loopbase->next->next->v->tflag1];
+ if (len == 4) {
+ eve4= evlist[f->loopbase->prev->v->tflag1];
+ }
+ else {
+ eve4= NULL;
+ }
+
+ efa = addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
+ efa->mat_nr = (unsigned char)f->mat_nr;
+ efa->flag= f->flag & ~ME_HIDE;
+ if(f->flag & ME_FACE_SEL) {
+ efa->f |= SELECT;
+ }
+ if(f->flag & ME_HIDE) efa->h= 1;
+ if((G.f & G_FACESELECT) && (efa->f & SELECT))
+ EM_select_face(efa, 1); /* flush down */
+ }
+ }
+
+ MEM_freeN(evlist);
+
+ countall();
+
+ return em;
+}
+
+/* Adds the geometry found in dm to bm
+ * NOTE: it does not allocate a new BME_Mesh!
+ */
+BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm, BME_Mesh *bm)
+{
+ MVert *mvert, *mv;
+ MEdge *medge, *me;
+ MFace *mface, *mf;
+ int totface,totedge,totvert,i,len;
+
+ BME_Vert *v1=NULL,*v2=NULL, **vert_array;
+ BME_Edge *e=NULL;
+ BME_Poly *f=NULL;
+
+ EdgeHash *edge_hash = BLI_edgehash_new();
+
+ totvert = dm->getNumVerts(dm);
+ totedge = dm->getNumEdges(dm);
+ totface = dm->getNumFaces(dm);
+ mvert = dm->getVertArray(dm);
+ medge = dm->getEdgeArray(dm);
+ mface = dm->getFaceArray(dm);
+
+ vert_array = MEM_mallocN(sizeof(*vert_array)*totvert,"BME_derivedmesh_to_bmesh BME_Vert* array");
+
+ BME_model_begin(bm);
+ /*add verts*/
+ for(i=0,mv = mvert; i < totvert;i++,mv++){
+ v1 = BME_MV(bm,mv->co);
+ vert_array[i] = v1;
+ v1->flag = mv->flag;
+ v1->bweight = mv->bweight/255.0f;
+ }
+ /*add edges*/
+ for(i=0,me = medge; i < totedge;i++,me++){
+ v1 = vert_array[me->v1];
+ v2 = vert_array[me->v2];
+ e = BME_ME(bm, v1, v2);
+ e->crease = me->crease/255.0f;
+ e->bweight = me->bweight/255.0f;
+ e->flag = (unsigned char)me->flag;
+ BLI_edgehash_insert(edge_hash,me->v1,me->v2,e);
+ }
+ /*add faces.*/
+ for(i=0,mf = mface; i < totface;i++,mf++){
+ BME_Edge *edar[4];
+ if(mf->v4) len = 4;
+ else len = 3;
+
+ edar[0] = BLI_edgehash_lookup(edge_hash,mf->v1,mf->v2);
+ edar[1] = BLI_edgehash_lookup(edge_hash,mf->v2,mf->v3);
+ if(len == 4){
+ edar[2] = BLI_edgehash_lookup(edge_hash,mf->v3,mf->v4);
+ edar[3] = BLI_edgehash_lookup(edge_hash,mf->v4,mf->v1);
+ }
+ else
+ edar[2] = BLI_edgehash_lookup(edge_hash,mf->v3,mf->v1);
+
+ /*find v1 and v2*/
+ v1 = vert_array[mf->v1];
+ v2 = vert_array[mf->v2];
+
+ f = BME_MF(bm,v1,v2,edar,len);
+ f->mat_nr = mf->mat_nr;
+ f->flag = mf->flag;
+ }
+
+ BME_model_end(bm);
+ BLI_edgehash_free(edge_hash, NULL);
+ MEM_freeN(vert_array);
+ return bm;
+}
+
+DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
+{
+ MFace *mface, *mf;
+ MEdge *medge, *me;
+ MVert *mvert, *mv;
+ int totface,totedge,totvert,i,bmeshok,len;
+
+ BME_Vert *v1=NULL;
+ BME_Edge *e=NULL, *oe=NULL;
+ BME_Poly *f=NULL;
+
+ DerivedMesh *result;
+ EdgeHash *edge_hash = BLI_edgehash_new();
+
+ totvert = BLI_countlist(&(bm->verts));
+ totedge = 0;
+
+ /*we cannot have double edges in a derived mesh!*/
+ for(i=0, v1=bm->verts.first; v1; v1=v1->next, i++) v1->tflag1 = i;
+ for(e=bm->edges.first; e; e=e->next){
+ oe = BLI_edgehash_lookup(edge_hash,e->v1->tflag1, e->v2->tflag1);
+ if(!oe){
+ totedge++;
+ BLI_edgehash_insert(edge_hash,e->v1->tflag1,e->v2->tflag1,e);
+ e->tflag2 = 1;
+ }
+ else{
+ e->tflag2 = 0;
+ }
+ }
+
+ /*count quads and tris*/
+ totface = 0;
+ bmeshok = 1;
+ for(f=bm->polys.first;f;f=f->next){
+ len = BME_cycle_length(f->loopbase);
+ if(len == 3 || len == 4) totface++;
+ }
+
+ /*convert back to mesh*/
+ result = CDDM_from_template(dm,totvert,totedge,totface);
+ /*Make Verts*/
+ mvert = CDDM_get_verts(result);
+ for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){
+ VECCOPY(mv->co,v1->co);
+ mv->flag = (unsigned char)v1->flag;
+ mv->bweight = (char)(255.0*v1->bweight);
+ }
+ medge = CDDM_get_edges(result);
+ i=0;
+ for(e=bm->edges.first,me=medge;e;e=e->next){
+ if(e->tflag2){
+ if(e->v1->tflag1 < e->v2->tflag1){
+ me->v1 = e->v1->tflag1;
+ me->v2 = e->v2->tflag1;
+ }
+ else{
+ me->v1 = e->v2->tflag1;
+ me->v2 = e->v1->tflag1;
+ }
+
+ me->crease = (char)(255.0*e->crease);
+ me->bweight = (char)(255.0*e->bweight);
+ me->flag = e->flag;
+ me++;
+ i++;
+ }
+ }
+ if(totface){
+ mface = CDDM_get_faces(result);
+ /*make faces*/
+ for(i=0,f=bm->polys.first;f;f=f->next){
+ mf = &mface[i];
+ len = BME_cycle_length(f->loopbase);
+ if(len==3 || len==4){
+ mf->v1 = f->loopbase->v->tflag1;
+ mf->v2 = f->loopbase->next->v->tflag1;
+ mf->v3 = f->loopbase->next->next->v->tflag1;
+ if(len == 4){
+ mf->v4 = f->loopbase->prev->v->tflag1;
+ }
+ /* test and rotate indexes if necessary so that verts 3 and 4 aren't index 0 */
+ if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){
+ test_index_face(mf, NULL, i, len);
+ }
+ i++;
+ mf->mat_nr = (unsigned char)f->mat_nr;
+ mf->flag = (unsigned char)f->flag;
+ }
+ }
+ }
+ BLI_edgehash_free(edge_hash, NULL);
+ return result;
+}
diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c
new file mode 100644
index 00000000000..7de0d8b49cf
--- /dev/null
+++ b/source/blender/blenkernel/intern/BME_eulers.c
@@ -0,0 +1,975 @@
+/**
+ * BME_eulers.c jan 2007
+ *
+ * BMesh Euler construction API.
+ *
+ * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
+
+#include "BLI_blenlib.h"
+#include "bmesh_private.h"
+#include "BLI_ghash.h"
+
+/*********************************************************
+ * "Euler API" *
+ * *
+ * *
+ * Primitive construction operators for mesh tools. *
+ * *
+ **********************************************************/
+
+
+/*
+ The functions in this file represent the 'primitive' or 'atomic' operators that
+ mesh tools use to manipulate the topology of the structure.* The purpose of these
+ functions is to provide a trusted set of operators to manipulate the mesh topology
+ and which can also be combined together like building blocks to create more
+ sophisticated tools. It needs to be stressed that NO manipulation of an existing
+ mesh structure should be done outside of these functions.
+
+ In the BMesh system, each euler is named by an ancronym which describes what it actually does.
+ Furthermore each Euler has a logical inverse. An important design criteria of all Eulers is that
+ through a Euler's logical inverse you can 'undo' an operation. (Special note should
+ be taken of BME_loop_reverse, which is its own inverse).
+
+ BME_MF/KF: Make Face and Kill Face
+ BME_ME/KE: Make Edge and Kill Edge
+ BME_MV/KV: Make Vert and Kill Vert
+ BME_SEMV/JEKV: Split Edge, Make Vert and Join Edge, Kill Vert
+ BME_SFME/JFKE: Split Face, Make Edge and Join Face, Kill Edge
+ BME_loop_reverse: Reverse a Polygon's loop cycle. (used for flip normals for one)
+
+ Using a combination of these eleven eulers any non-manifold modelling operation can be achieved.
+ Each Euler operator has a detailed explanation of what is does in the comments preceding its
+ code.
+
+ *The term "Euler Operator" is actually a misnomer when referring to a non-manifold
+ data structure. Its use is in keeping with the convention established by others.
+
+ TODO:
+ -Finish inserting 'strict' validation in all Eulers
+*/
+
+void *BME_exit(char *s) {
+ if (s) printf("%s\n",s);
+ return NULL;
+}
+
+#define RETCLEAR(bm) {bm->rval->v = bm->rval->e = bm->rval->f = bm->rva->l = NULL;}
+/*MAKE Eulers*/
+
+/**
+ * BME_MV
+ *
+ * MAKE VERT EULER:
+ *
+ * Makes a single loose vertex.
+ *
+ * Returns -
+ * A BME_Vert pointer.
+ */
+
+BME_Vert *BME_MV(BME_Mesh *bm, float *vec){
+ BME_Vert *v = BME_addvertlist(bm, NULL);
+ VECCOPY(v->co,vec);
+ return v;
+}
+
+/**
+ * BME_ME
+ *
+ * MAKE EDGE EULER:
+ *
+ * Makes a single wire edge between two vertices.
+ * If the caller does not want there to be duplicate
+ * edges between the vertices, it is up to them to check
+ * for this condition beforehand.
+ *
+ * Returns -
+ * A BME_Edge pointer.
+ */
+
+BME_Edge *BME_ME(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2){
+ BME_Edge *e=NULL;
+ BME_CycleNode *d1=NULL, *d2=NULL;
+ int valance1=0, valance2=0, edok;
+
+ /*edge must be between two distinct vertices...*/
+ if(v1 == v2) return NULL;
+
+ #ifndef BME_FASTEULER
+ /*count valance of v1*/
+ if(v1->edge){
+ d1 = BME_disk_getpointer(v1->edge,v1);
+ if(d1) valance1 = BME_cycle_length(d1);
+ else BME_error();
+ }
+ if(v2->edge){
+ d2 = BME_disk_getpointer(v2->edge,v2);
+ if(d2) valance2 = BME_cycle_length(d2);
+ else BME_error();
+ }
+ #endif
+
+ /*go ahead and add*/
+ e = BME_addedgelist(bm, v1, v2, NULL);
+ BME_disk_append_edge(e, e->v1);
+ BME_disk_append_edge(e, e->v2);
+
+ #ifndef BME_FASTEULER
+ /*verify disk cycle lengths*/
+ d1 = BME_disk_getpointer(e, e->v1);
+ edok = BME_cycle_validate(valance1+1, d1);
+ if(!edok) BME_error();
+ d2 = BME_disk_getpointer(e, e->v2);
+ edok = BME_cycle_validate(valance2+1, d2);
+ if(!edok) BME_error();
+
+ /*verify that edge actually made it into the cycle*/
+ edok = BME_disk_hasedge(v1, e);
+ if(!edok) BME_error();
+ edok = BME_disk_hasedge(v2, e);
+ if(!edok) BME_error();
+ #endif
+ return e;
+}
+
+
+
+/**
+ * BME_MF
+ *
+ * MAKE FACE EULER:
+ * Takes a list of edge pointers which form a closed loop and makes a face
+ * from them. The first edge in elist is considered to be the start of the
+ * polygon, and v1 and v2 are its vertices and determine the winding of the face
+ * Other than the first edge, no other assumptions are made about the order of edges
+ * in the elist array. To verify that it is a single closed loop and derive the correct
+ * order a simple series of verifications is done and all elements are visited.
+ *
+ * Returns -
+ * A BME_Poly pointer
+ */
+
+#define MF_CANDIDATE 1
+#define MF_VISITED 2
+#define MF_TAKEN 4
+
+BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int len)
+{
+ BME_Poly *f = NULL;
+ BME_Edge *curedge;
+ BME_Vert *curvert, *tv, **vlist;
+ int i, j, done, cont, edok;
+
+ if(len < 2) return NULL;
+
+ /*make sure that v1 and v2 are in elist[0]*/
+ if(BME_verts_in_edge(v1,v2,elist[0]) == 0) return NULL;
+
+ /*clear euler flags*/
+ for(i=0;i<len;i++) elist[i]->eflag1=elist[i]->eflag2 = 0;
+ for(i=0;i<len;i++){
+ elist[i]->eflag1 |= MF_CANDIDATE;
+
+ /*if elist[i] has a loop, count its radial length*/
+ if(elist[i]->loop) elist[i]->eflag2 = BME_cycle_length(&(elist[i]->loop->radial));
+ else elist[i]->eflag2 = 0;
+ }
+
+ /* For each vertex in each edge, it must have exactly two MF_CANDIDATE edges attached to it
+ Note that this does not gauruntee that face is a single closed loop. At best it gauruntees
+ that elist contains a finite number of seperate closed loops.
+ */
+ for(i=0; i<len; i++){
+ edok = BME_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
+ if(edok != 2) return NULL;
+ edok = BME_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
+ if(edok != 2) return NULL;
+ }
+
+ /*set start edge, start vert and target vert for our loop traversal*/
+ curedge = elist[0];
+ tv = v1;
+ curvert = v2;
+
+ if(bm->vtarlen < len){
+ MEM_freeN(bm->vtar);
+ bm->vtar = MEM_callocN(sizeof(BME_Vert *)* len, "BMesh Vert pointer array");
+ bm->vtarlen = len;
+ }
+ /*insert tv into vlist since its the first vertex in face*/
+ i=0;
+ vlist=bm->vtar;
+ vlist[i] = tv;
+
+ /* Basic procedure: Starting with curv we find the edge in it's disk cycle which hasn't
+ been visited yet. When we do, we put curv in a linked list and find the next MF_CANDIDATE
+ edge, loop until we find TV. We know TV is reachable because of test we did earlier.
+ */
+ done=0;
+ while(!done){
+ /*add curvert to vlist*/
+ /*insert some error cheking here for overflows*/
+ i++;
+ vlist[i] = curvert;
+
+ /*mark curedge as visited*/
+ curedge->eflag1 |= MF_VISITED;
+
+ /*find next edge and vert*/
+ curedge = BME_disk_next_edgeflag(curedge, curvert, MF_CANDIDATE, 0);
+ curvert = BME_edge_getothervert(curedge, curvert);
+ if(curvert == tv){
+ curedge->eflag1 |= MF_VISITED;
+ done=1;
+ }
+ }
+
+ /* Verify that all edges have been visited It's possible that we did reach tv
+ from sv, but that several unconnected loops were passed in via elist.
+ */
+ cont=1;
+ for(i=0; i<len; i++){
+ if((elist[i]->eflag1 & MF_VISITED) == 0) cont = 0;
+ }
+
+ /*if we get this far, its ok to allocate the face and add the loops*/
+ if(cont){
+ BME_Loop *l;
+ BME_Edge *e;
+ f = BME_addpolylist(bm, NULL);
+ f->len = len;
+ for(i=0;i<len;i++){
+ curvert = vlist[i];
+ l = BME_create_loop(bm,curvert,NULL,f,NULL);
+ if(!(f->loopbase)) f->loopbase = l;
+ BME_cycle_append(f->loopbase, l);
+ }
+
+ /*take care of edge pointers and radial cycle*/
+ for(i=0, l = f->loopbase; i<len; i++, l=l->next){
+ e = NULL;
+ if(l == f->loopbase) e = elist[0]; /*first edge*/
+
+ else{/*search elist for others*/
+ for(j=1; j<len; j++){
+ edok = BME_verts_in_edge(l->v, l->next->v, elist[j]);
+ if(edok){
+ e = elist[j];
+ break;
+ }
+ }
+ }
+ l->e = e; /*set pointer*/
+ BME_radial_append(e, l); /*append into radial*/
+ }
+
+ f->len = len;
+
+ /*Validation Loop cycle*/
+ edok = BME_cycle_validate(len, f->loopbase);
+ if(!edok) BME_error();
+ for(i=0, l = f->loopbase; i<len; i++, l=l->next){
+ /*validate loop vert pointers*/
+ edok = BME_verts_in_edge(l->v, l->next->v, l->e);
+ if(!edok) BME_error();
+ /*validate the radial cycle of each edge*/
+ edok = BME_cycle_length(&(l->radial));
+ if(edok != (l->e->eflag2 + 1)) BME_error();
+ }
+ }
+ return f;
+}
+
+/* KILL Eulers */
+
+/**
+ * BME_KV
+ *
+ * KILL VERT EULER:
+ *
+ * Kills a single loose vertex.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+
+int BME_KV(BME_Mesh *bm, BME_Vert *v){
+ if(v->edge == NULL){
+ BLI_remlink(&(bm->verts), v);
+ BME_free_vert(bm,v);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * BME_KE
+ *
+ * KILL EDGE EULER:
+ *
+ * Kills a wire edge.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+
+int BME_KE(BME_Mesh *bm, BME_Edge *e){
+ int edok;
+
+ /*Make sure that no faces!*/
+ if(e->loop == NULL){
+ BME_disk_remove_edge(e, e->v1);
+ BME_disk_remove_edge(e, e->v2);
+
+ /*verify that edge out of disk*/
+ edok = BME_disk_hasedge(e->v1, e);
+ if(edok) BME_error();
+ edok = BME_disk_hasedge(e->v2, e);
+ if(edok) BME_error();
+
+ /*remove and deallocate*/
+ BLI_remlink(&(bm->edges), e);
+ BME_free_edge(bm, e);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * BME_KF
+ *
+ * KILL FACE EULER:
+ *
+ * The logical inverse of BME_MF.
+ * Kills a face and removes each of its loops from the radial that it belongs to.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+*/
+
+int BME_KF(BME_Mesh *bm, BME_Poly *bply){
+ BME_Loop *newbase,*oldbase, *curloop;
+ int i,len=0;
+
+ /*add validation to make sure that radial cycle is cleaned up ok*/
+ /*deal with radial cycle first*/
+ len = BME_cycle_length(bply->loopbase);
+ for(i=0, curloop=bply->loopbase; i < len; i++, curloop = curloop->next)
+ BME_radial_remove_loop(curloop, curloop->e);
+
+ /*now deallocate the editloops*/
+ for(i=0; i < len; i++){
+ newbase = bply->loopbase->next;
+ oldbase = bply->loopbase;
+ BME_cycle_remove(oldbase, oldbase);
+ BME_free_loop(bm, oldbase);
+ bply->loopbase = newbase;
+ }
+
+ BLI_remlink(&(bm->polys), bply);
+ BME_free_poly(bm, bply);
+ return 1;
+}
+
+/*SPLIT Eulers*/
+
+/**
+ * BME_SEMV
+ *
+ * SPLIT EDGE MAKE VERT:
+ * Takes a given edge and splits it into two, creating a new vert.
+ *
+ *
+ * Before: OV---------TV
+ * After: OV----NV---TV
+ *
+ * Returns -
+ * BME_Vert pointer.
+ *
+*/
+
+BME_Vert *BME_SEMV(BME_Mesh *bm, BME_Vert *tv, BME_Edge *e, BME_Edge **re){
+ BME_Vert *nv, *ov;
+ BME_CycleNode *diskbase;
+ BME_Edge *ne;
+ int i, edok, valance1=0, valance2=0;
+
+ if(BME_vert_in_edge(e,tv) == 0) return NULL;
+ ov = BME_edge_getothervert(e,tv);
+ //v2 = tv;
+
+ /*count valance of v1*/
+ diskbase = BME_disk_getpointer(e, ov);
+ valance1 = BME_cycle_length(diskbase);
+ /*count valance of v2*/
+ diskbase = BME_disk_getpointer(e, tv);
+ valance2 = BME_cycle_length(diskbase);
+
+ nv = BME_addvertlist(bm, tv);
+ ne = BME_addedgelist(bm, nv, tv, e);
+
+ //e->v2 = nv;
+ /*remove e from v2's disk cycle*/
+ BME_disk_remove_edge(e, tv);
+ /*swap out tv for nv in e*/
+ BME_edge_swapverts(e, tv, nv);
+ /*add e to nv's disk cycle*/
+ BME_disk_append_edge(e, nv);
+ /*add ne to nv's disk cycle*/
+ BME_disk_append_edge(ne, nv);
+ /*add ne to tv's disk cycle*/
+ BME_disk_append_edge(ne, tv);
+ /*verify disk cycles*/
+ diskbase = BME_disk_getpointer(ov->edge,ov);
+ edok = BME_cycle_validate(valance1, diskbase);
+ if(!edok) BME_error();
+ diskbase = BME_disk_getpointer(tv->edge,tv);
+ edok = BME_cycle_validate(valance2, diskbase);
+ if(!edok) BME_error();
+ diskbase = BME_disk_getpointer(nv->edge,nv);
+ edok = BME_cycle_validate(2, diskbase);
+ if(!edok) BME_error();
+
+ /*Split the radial cycle if present*/
+ if(e->loop){
+ BME_Loop *nl,*l;
+ BME_CycleNode *radEBase=NULL, *radNEBase=NULL;
+ int radlen = BME_cycle_length(&(e->loop->radial));
+ /*Take the next loop. Remove it from radial. Split it. Append to appropriate radials.*/
+ while(e->loop){
+ l=e->loop;
+ l->f->len++;
+ BME_radial_remove_loop(l,e);
+
+ nl = BME_create_loop(bm,NULL,NULL,l->f,l);
+ nl->prev = l;
+ nl->next = l->next;
+ nl->prev->next = nl;
+ nl->next->prev = nl;
+ nl->v = nv;
+
+ /*assign the correct edge to the correct loop*/
+ if(BME_verts_in_edge(nl->v, nl->next->v, e)){
+ nl->e = e;
+ l->e = ne;
+
+ /*append l into ne's rad cycle*/
+ if(!radNEBase){
+ radNEBase = &(l->radial);
+ radNEBase->next = NULL;
+ radNEBase->prev = NULL;
+ }
+
+ if(!radEBase){
+ radEBase = &(nl->radial);
+ radEBase->next = NULL;
+ radEBase->prev = NULL;
+ }
+
+ BME_cycle_append(radEBase,&(nl->radial));
+ BME_cycle_append(radNEBase,&(l->radial));
+
+ }
+ else if(BME_verts_in_edge(nl->v,nl->next->v,ne)){
+ nl->e = ne;
+ l->e = e;
+
+ if(!radNEBase){
+ radNEBase = &(nl->radial);
+ radNEBase->next = NULL;
+ radNEBase->prev = NULL;
+ }
+ if(!radEBase){
+ radEBase = &(l->radial);
+ radEBase->next = NULL;
+ radEBase->prev = NULL;
+ }
+ BME_cycle_append(radEBase,&(l->radial));
+ BME_cycle_append(radNEBase,&(nl->radial));
+ }
+
+ }
+
+ e->loop = radEBase->data;
+ ne->loop = radNEBase->data;
+
+ /*verify length of radial cycle*/
+ edok = BME_cycle_validate(radlen,&(e->loop->radial));
+ if(!edok) BME_error();
+ edok = BME_cycle_validate(radlen,&(ne->loop->radial));
+ if(!edok) BME_error();
+
+ /*verify loop->v and loop->next->v pointers for e*/
+ for(i=0,l=e->loop; i < radlen; i++, l = l->radial.next->data){
+ if(!(l->e == e)) BME_error();
+ if(!(l->radial.data == l)) BME_error();
+ if(l->prev->e != ne && l->next->e != ne) BME_error();
+ edok = BME_verts_in_edge(l->v, l->next->v, e);
+ if(!edok) BME_error();
+ if(l->v == l->next->v) BME_error();
+ if(l->e == l->next->e) BME_error();
+ /*verify loop cycle for kloop->f*/
+ edok = BME_cycle_validate(l->f->len, l->f->loopbase);
+ if(!edok) BME_error();
+ }
+ /*verify loop->v and loop->next->v pointers for ne*/
+ for(i=0,l=ne->loop; i < radlen; i++, l = l->radial.next->data){
+ if(!(l->e == ne)) BME_error();
+ if(!(l->radial.data == l)) BME_error();
+ if(l->prev->e != e && l->next->e != e) BME_error();
+ edok = BME_verts_in_edge(l->v, l->next->v, ne);
+ if(!edok) BME_error();
+ if(l->v == l->next->v) BME_error();
+ if(l->e == l->next->e) BME_error();
+ /*verify loop cycle for kloop->f. Redundant*/
+ edok = BME_cycle_validate(l->f->len, l->f->loopbase);
+ if(!edok) BME_error();
+ }
+ }
+
+ if(re) *re = ne;
+ return nv;
+}
+
+/**
+ * BME_SFME
+ *
+ * SPLIT FACE MAKE EDGE:
+ *
+ * Takes as input two vertices in a single face. An edge is created which divides the original face
+ * into two distinct regions. One of the regions is assigned to the original face and it is closed off.
+ * The second region has a new face assigned to it.
+ *
+ * Examples:
+ *
+ * Before: After:
+ * ---------- ----------
+ * | | | |
+ * | | | f1 |
+ * v1 f1 v2 v1======v2
+ * | | | f2 |
+ * | | | |
+ * ---------- ----------
+ *
+ * Note that the input vertices can be part of the same edge. This will result in a two edged face.
+ * This is desirable for advanced construction tools and particularly essential for edge bevel. Because
+ * of this it is up to the caller to decide what to do with the extra edge.
+ *
+ * Returns -
+ * A BME_Poly pointer
+ */
+BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **rl){
+
+ BME_Poly *f2;
+ BME_Loop *v1loop = NULL, *v2loop = NULL, *curloop, *f1loop=NULL, *f2loop=NULL;
+ BME_Edge *e;
+ int i, len, f1len, f2len;
+
+
+ /*verify that v1 and v2 are in face.*/
+ len = BME_cycle_length(f->loopbase);
+ for(i = 0, curloop = f->loopbase; i < len; i++, curloop = curloop->next){
+ if(curloop->v == v1) v1loop = curloop;
+ else if(curloop->v == v2) v2loop = curloop;
+ }
+
+ if(!v1loop || !v2loop) return NULL;
+
+ /*allocate new edge between v1 and v2*/
+ e = BME_addedgelist(bm, v1, v2,NULL);
+ BME_disk_append_edge(e, v1);
+ BME_disk_append_edge(e, v2);
+
+ f2 = BME_addpolylist(bm,f);
+ f1loop = BME_create_loop(bm,v2,e,f,NULL);
+ f2loop = BME_create_loop(bm,v1,e,f2,NULL);
+
+ f1loop->prev = v2loop->prev;
+ f2loop->prev = v1loop->prev;
+ v2loop->prev->next = f1loop;
+ v1loop->prev->next = f2loop;
+
+ f1loop->next = v1loop;
+ f2loop->next = v2loop;
+ v1loop->prev = f1loop;
+ v2loop->prev = f2loop;
+
+ f2->loopbase = f2loop;
+ f->loopbase = f1loop;
+
+ /*validate both loops*/
+ /*I dont know how many loops are supposed to be in each face at this point! FIXME!*/
+
+ /*go through all of f2's loops and make sure they point to it properly.*/
+ f2len = BME_cycle_length(f2->loopbase);
+ for(i=0, curloop = f2->loopbase; i < f2len; i++, curloop = curloop->next) curloop->f = f2;
+
+ /*link up the new loops into the new edges radial*/
+ BME_radial_append(e, f1loop);
+ BME_radial_append(e, f2loop);
+
+
+ f2->len = f2len;
+
+ f1len = BME_cycle_length(f->loopbase);
+ f->len = f1len;
+
+ if(rl) *rl = f2loop;
+ return f2;
+}
+
+
+/**
+ * BME_JEKV
+ *
+ * JOIN EDGE KILL VERT:
+ * Takes a an edge and pointer to one of its vertices and collapses
+ * the edge on that vertex.
+ *
+ * Before: OE KE
+ * ------- -------
+ * | || |
+ * OV KV TV
+ *
+ *
+ * After: OE
+ * ---------------
+ * | |
+ * OV TV
+ *
+ *
+ * Restrictions:
+ * KV is a vertex that must have a valance of exactly two. Furthermore
+ * both edges in KV's disk cycle (OE and KE) must be unique (no double
+ * edges).
+ *
+ * It should also be noted that this euler has the possibility of creating
+ * faces with just 2 edges. It is up to the caller to decide what to do with
+ * these faces.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
+{
+ BME_Edge *oe;
+ BME_Vert *ov, *tv;
+ BME_CycleNode *diskbase;
+ BME_Loop *killoop,*nextl;
+ int len,radlen=0, halt = 0, i, valance1, valance2,edok;
+
+ if(BME_vert_in_edge(ke,kv) == 0) return 0;
+ diskbase = BME_disk_getpointer(kv->edge, kv);
+ len = BME_cycle_length(diskbase);
+
+ if(len == 2){
+ oe = BME_disk_nextedge(ke, kv);
+ tv = BME_edge_getothervert(ke, kv);
+ ov = BME_edge_getothervert(oe, kv);
+ halt = BME_verts_in_edge(kv, tv, oe); //check for double edges
+
+ if(halt) return 0;
+ else{
+
+ /*For verification later, count valance of ov and tv*/
+ diskbase = BME_disk_getpointer(ov->edge, ov);
+ valance1 = BME_cycle_length(diskbase);
+ diskbase = BME_disk_getpointer(tv->edge, tv);
+ valance2 = BME_cycle_length(diskbase);
+
+ /*remove oe from kv's disk cycle*/
+ BME_disk_remove_edge(oe,kv);
+ /*relink oe->kv to be oe->tv*/
+ BME_edge_swapverts(oe, kv, tv);
+ /*append oe to tv's disk cycle*/
+ BME_disk_append_edge(oe, tv);
+ /*remove ke from tv's disk cycle*/
+ BME_disk_remove_edge(ke, tv);
+
+ /*deal with radial cycle of ke*/
+ if(ke->loop){
+ /*first step, fix the neighboring loops of all loops in ke's radial cycle*/
+ radlen = BME_cycle_length(&(ke->loop->radial));
+ for(i=0,killoop = ke->loop; i<radlen; i++, killoop = BME_radial_nextloop(killoop)){
+ /*relink loops and fix vertex pointer*/
+ killoop->next->prev = killoop->prev;
+ killoop->prev->next = killoop->next;
+ if(killoop->next->v == kv) killoop->next->v = tv;
+
+ /*fix len attribute of face*/
+ killoop->f->len--;
+ if(killoop->f->loopbase == killoop) killoop->f->loopbase = killoop->next;
+ }
+ /*second step, remove all the hanging loops attached to ke*/
+ killoop = ke->loop;
+ radlen = BME_cycle_length(&(ke->loop->radial));
+ /*make sure we have enough room in bm->lpar*/
+ if(bm->lparlen < radlen){
+ MEM_freeN(bm->lpar);
+ bm->lpar = MEM_callocN(sizeof(BME_Loop *)* radlen, "BMesh Loop pointer array");
+ bm->lparlen = bm->lparlen * radlen;
+ }
+ /*this should be wrapped into a bme_free_radial function to be used by BME_KF as well...*/
+ i=0;
+ while(i<radlen){
+ bm->lpar[i] = killoop;
+ killoop = killoop->radial.next->data;
+ i++;
+ }
+ i=0;
+ while(i<radlen){
+ BME_free_loop(bm,bm->lpar[i]);
+ i++;
+ }
+ /*Validate radial cycle of oe*/
+ edok = BME_cycle_validate(radlen,&(oe->loop->radial));
+
+ }
+
+ /*Validate disk cycles*/
+ diskbase = BME_disk_getpointer(ov->edge,ov);
+ edok = BME_cycle_validate(valance1, diskbase);
+ if(!edok) BME_error();
+ diskbase = BME_disk_getpointer(tv->edge,tv);
+ edok = BME_cycle_validate(valance2, diskbase);
+ if(!edok) BME_error();
+
+ /*Validate loop cycle of all faces attached to oe*/
+ for(i=0,nextl = oe->loop; i<radlen; i++, nextl = BME_radial_nextloop(nextl)){
+ edok = BME_cycle_validate(nextl->f->len,nextl->f->loopbase);
+ if(!edok) BME_error();
+ }
+ /*deallocate edge*/
+ BLI_remlink(&(bm->edges), ke);
+ BME_free_edge(bm, ke);
+ /*deallocate vertex*/
+ BLI_remlink(&(bm->verts), kv);
+ BME_free_vert(bm, kv);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * BME_loop_reverse
+ *
+ * FLIP FACE EULER
+ *
+ * Changes the winding order of a face from CW to CCW or vice versa.
+ * This euler is a bit peculiar in compairson to others as it is its
+ * own inverse.
+ *
+ * TODO: reinsert validation code.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+
+int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
+ BME_Loop *l = f->loopbase, *curloop, *oldprev, *oldnext;
+ int i, j, edok, len = 0;
+
+ len = BME_cycle_length(l);
+ if(bm->edarlen < len){
+ MEM_freeN(bm->edar);
+ bm->edar = MEM_callocN(sizeof(BME_Edge *)* len, "BMesh Edge pointer array");
+ bm->edarlen = len;
+ }
+
+ for(i=0, curloop = l; i< len; i++, curloop=curloop->next){
+ curloop->e->eflag1 = 0;
+ curloop->e->eflag2 = BME_cycle_length(&curloop->radial);
+ BME_radial_remove_loop(curloop, curloop->e);
+ /*in case of border edges we HAVE to zero out curloop->radial Next/Prev*/
+ curloop->radial.next = curloop->radial.prev = NULL;
+ bm->edar[i] = curloop->e;
+ }
+
+ /*actually reverse the loop. This belongs in BME_cycle_reverse!*/
+ for(i=0, curloop = l; i < len; i++){
+ oldnext = curloop->next;
+ oldprev = curloop->prev;
+ curloop->next = oldprev;
+ curloop->prev = oldnext;
+ curloop = oldnext;
+ }
+
+ if(len == 2){ //two edged face
+ //do some verification here!
+ l->e = bm->edar[1];
+ l->next->e = bm->edar[0];
+ }
+ else{
+ for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
+ edok = 0;
+ for(j=0; j < len; j++){
+ edok = BME_verts_in_edge(curloop->v, curloop->next->v, bm->edar[j]);
+ if(edok){
+ curloop->e = bm->edar[j];
+ break;
+ }
+ }
+ }
+ }
+ /*rebuild radial*/
+ for(i=0, curloop = l; i < len; i++, curloop = curloop->next) BME_radial_append(curloop->e, curloop);
+
+ /*validate radial*/
+ for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
+ edok = BME_cycle_validate(curloop->e->eflag2, &(curloop->radial));
+ if(!edok){
+ BME_error();
+ }
+ }
+ return 1;
+}
+
+/**
+ * BME_JFKE
+ *
+ * JOIN FACE KILL EDGE:
+ *
+ * Takes two faces joined by a single 2-manifold edge and fuses them togather.
+ * The edge shared by the faces must not be connected to any other edges which have
+ * Both faces in its radial cycle
+ *
+ * Examples:
+ *
+ * A B
+ * ---------- ----------
+ * | | | |
+ * | f1 | | f1 |
+ * v1========v2 = Ok! v1==V2==v3 == Wrong!
+ * | f2 | | f2 |
+ * | | | |
+ * ---------- ----------
+ *
+ * In the example A, faces f1 and f2 are joined by a single edge, and the euler can safely be used.
+ * In example B however, f1 and f2 are joined by multiple edges and will produce an error. The caller
+ * in this case should call BME_JEKV on the extra edges before attempting to fuse f1 and f2.
+ *
+ * Also note that the order of arguments decides whether or not certain per-face attributes are present
+ * in the resultant face. For instance vertex winding, material index, smooth flags, ect are inherited
+ * from f1, not f2.
+ *
+ * Returns -
+ * A BME_Poly pointer
+*/
+
+BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
+{
+
+ BME_Loop *curloop, *f1loop=NULL, *f2loop=NULL;
+ int loopok = 0, newlen = 0,i, f1len=0, f2len=0, radlen=0, edok;
+
+ if(f1 == f2) return NULL; //can't join a face to itself
+ /*verify that e is in both f1 and f2*/
+ f1len = BME_cycle_length(f1->loopbase);
+ f2len = BME_cycle_length(f2->loopbase);
+ for(i=0, curloop = f1->loopbase; i < f1len; i++, curloop = curloop->next){
+ if(curloop->e == e){
+ f1loop = curloop;
+ break;
+ }
+ }
+ for(i=0, curloop = f2->loopbase; i < f2len; i++, curloop = curloop->next){
+ if(curloop->e==e){
+ f2loop = curloop;
+ break;
+ }
+ }
+ if(!(f1loop && f2loop)) return NULL;
+
+ /*validate that edge is 2-manifold edge*/
+ radlen = BME_cycle_length(&(f1loop->radial));
+ if(radlen != 2) return NULL;
+
+ /*validate direction of f2's loop cycle is compatible.*/
+ if(f1loop->v == f2loop->v) return NULL;
+
+ /*
+ Finally validate that for each face, each vertex has another edge in its disk cycle that is
+ not e, and not shared.
+ */
+ if(BME_radial_find_face(f1loop->next->e,f2)) return NULL;
+ if(BME_radial_find_face(f1loop->prev->e,f2)) return NULL;
+ if(BME_radial_find_face(f2loop->next->e,f1)) return NULL;
+ if(BME_radial_find_face(f2loop->prev->e,f1)) return NULL;
+
+ /*join the two loops*/
+ f1loop->prev->next = f2loop->next;
+ f2loop->next->prev = f1loop->prev;
+
+ f1loop->next->prev = f2loop->prev;
+ f2loop->prev->next = f1loop->next;
+
+ /*if f1loop was baseloop, give f1loop->next the base.*/
+ if(f1->loopbase == f1loop) f1->loopbase = f1loop->next;
+
+ /*validate the new loop*/
+ loopok = BME_cycle_validate((f1len+f2len)-2, f1->loopbase);
+ if(!loopok) BME_error();
+
+ /*make sure each loop points to the proper face*/
+ newlen = BME_cycle_length(f1->loopbase);
+ for(i = 0, curloop = f1->loopbase; i < newlen; i++, curloop = curloop->next) curloop->f = f1;
+
+ f1->len = newlen;
+
+ edok = BME_cycle_validate(f1->len, f1->loopbase);
+ if(!edok) BME_error();
+
+ /*remove edge from the disk cycle of its two vertices.*/
+ BME_disk_remove_edge(f1loop->e, f1loop->e->v1);
+ BME_disk_remove_edge(f1loop->e, f1loop->e->v2);
+
+ /*deallocate edge and its two loops as well as f2*/
+ BLI_remlink(&(bm->edges), f1loop->e);
+ BLI_remlink(&(bm->polys), f2);
+ BME_free_edge(bm, f1loop->e);
+ BME_free_loop(bm, f1loop);
+ BME_free_loop(bm, f2loop);
+ BME_free_poly(bm, f2);
+ return f1;
+}
diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c
new file mode 100644
index 00000000000..b6049f8c0a7
--- /dev/null
+++ b/source/blender/blenkernel/intern/BME_mesh.c
@@ -0,0 +1,304 @@
+/**
+ * BME_mesh.c jan 2007
+ *
+ * BMesh mesh level functions.
+ *
+ * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+
+#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
+#include "BKE_global.h"
+#include "BKE_depsgraph.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+#include "BIF_editmesh.h"
+#include "BIF_space.h"
+#include "editmesh.h"
+#include "bmesh_private.h"
+#include "mydevice.h"
+
+#include "BSE_edit.h"
+
+
+/*
+ * BME MAKE MESH
+ *
+ * Allocates a new BME_Mesh structure
+*/
+
+BME_Mesh *BME_make_mesh(void){
+ BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
+ return bm;
+}
+
+/*
+ * BME FREE MESH
+ *
+ * Frees a BME_Mesh structure.
+*/
+
+void BME_free_mesh(BME_Mesh *bm)
+{
+ BME_Poly *bf, *nextf;
+ BME_Edge *be, *nexte;
+ BME_Vert *bv, *nextv;
+ BME_CycleNode *loopref;
+
+ /*destroy polygon data*/
+ bf = bm->polys.first;
+ while(bf){
+ nextf = bf->next;
+ BLI_remlink(&(bm->polys), bf);
+ BME_free_poly(bm, bf);
+
+ bf = nextf;
+ }
+ /*destroy edge data*/
+ be = bm->edges.first;
+ while(be){
+ nexte = be->next;
+ BLI_remlink(&(bm->edges), be);
+ BME_free_edge(bm, be);
+ be = nexte;
+ }
+ /*destroy vert data*/
+ bv = bm->verts.first;
+ while(bv){
+ nextv = bv->next;
+ BLI_remlink(&(bm->verts), bv);
+ BME_free_vert(bm, bv);
+ bv = nextv;
+ }
+
+ for(loopref=bm->loops.first;loopref;loopref=loopref->next) BME_delete_loop(bm,loopref->data);
+ BLI_freelistN(&(bm->loops));
+
+ //CustomData_free(&bm->vdata, 0);
+ //CustomData_free(&bm->edata, 0);
+ //CustomData_free(&bm->ldata, 0);
+ //CustomData_free(&bm->pdata, 0);
+
+ MEM_freeN(bm);
+}
+
+/*
+ * BME MODEL BEGIN AND END
+ *
+ * These two functions represent the 'point of entry' for tools. Every BMesh tool
+ * must begin with a call to BME_model_end() and finish with a call to BME_model_end().
+ * No modification of mesh data is allowed except in between these two calls.
+ *
+ * TODO
+ * FOR BME_MODEL_BEGIN:
+ * -integrate euler undo system.
+ * -make full copy of structure to safely recover from errors.
+ * -accept a toolname string.
+ * -accept param to turn off full copy if just selection tool. (perhaps check for this in eulers...)
+ *
+ * BME_MODEL_END:
+ * -full mesh validation if debugging turned on
+ * -free structure copy or use it to restore.
+ * -do euler undo push.
+ *
+*/
+
+int BME_model_begin(BME_Mesh *bm){
+ /*Initialize some scratch pointer arrays used by eulers*/
+ bm->vtar = MEM_callocN(sizeof(BME_Vert *) * 1024, "BMesh scratch vert array");
+ bm->edar = MEM_callocN(sizeof(BME_Edge *) * 1024, "BMesh scratch edge array");
+ bm->lpar = MEM_callocN(sizeof(BME_Loop *) * 1024, "BMesh scratch loop array");
+ bm->plar = MEM_callocN(sizeof(BME_Poly *) * 1024, "BMesh scratch poly array");
+
+ bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 1024;
+
+ return 1;
+}
+
+void BME_model_end(BME_Mesh *bm){
+ int meshok, totvert, totedge, totpoly, totloop;
+
+ totvert = BLI_countlist(&(bm->verts));
+ totedge = BLI_countlist(&(bm->edges));
+ totpoly = BLI_countlist(&(bm->polys));
+ totloop = BLI_countlist(&(bm->loops));
+
+ if(bm->vtar) MEM_freeN(bm->vtar);
+ if(bm->edar) MEM_freeN(bm->edar);
+ if(bm->lpar) MEM_freeN(bm->lpar);
+ if(bm->plar) MEM_freeN(bm->plar);
+
+ bm->vtar = NULL;
+ bm->edar = NULL;
+ bm->lpar = NULL;
+ bm->plar = NULL;
+ bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 1024;
+
+
+ if(bm->totvert!=totvert || bm->totedge!=totedge || bm->totpoly!=totpoly || bm->totloop!=totloop)
+ BME_error();
+
+ meshok = BME_validate_mesh(bm, 1);
+ if(!meshok){
+ BME_error();
+ }
+}
+
+/*
+ * BME VALIDATE MESH
+ *
+ * There are several levels of validation for meshes. At the
+ * Euler level, some basic validation is done to local topology.
+ * To catch more subtle problems however, BME_validate_mesh() is
+ * called by BME_model_end() whenever a tool is done executing.
+ * The purpose of this function is to insure that during the course
+ * of tool execution that nothing has been done to invalidate the
+ * structure, and if it has, provide a way of reporting that so that
+ * we can restore the proper structure from a backup. Since a full mesh
+ * validation would be too expensive, this is presented as a compromise.
+ *
+ * TODO
+ *
+ * -Write a full mesh validation function for debugging purposes.
+ */
+
+#define VHALT(halt) {BME_error(); if(halt) return 0;}
+
+int BME_validate_mesh(struct BME_Mesh *bm, int halt)
+{
+ BME_Vert *v;
+ BME_Edge *e;
+ BME_Poly *f;
+ BME_Loop *l;
+ BME_CycleNode *diskbase;
+ int i, ok;
+
+ /*Simple edge verification*/
+ for(e=bm->edges.first; e; e=e->next){
+ if(e->v1 == e->v2) VHALT(halt);
+ /*validate e->d1.data and e->d2.data*/
+ if(e->d1.data != e || e->d2.data != e) VHALT(halt);
+ /*validate e->loop->e*/
+ if(e->loop){
+ if(e->loop->e != e) VHALT(halt);
+ }
+ }
+
+ /*calculate disk cycle lengths*/
+ for(v=bm->verts.first; v; v=v->next) v->tflag1 = v->tflag2 = 0;
+ for(e=bm->edges.first; e; e=e->next){
+ e->v1->tflag1++;
+ e->v2->tflag1++;
+ }
+ /*Validate vertices and disk cycle*/
+ for(v=bm->verts.first; v; v=v->next){
+ /*validate v->edge pointer*/
+ if(v->tflag1){
+ if(v->edge){
+ ok = BME_vert_in_edge(v->edge,v);
+ if(!ok) VHALT(halt);
+ /*validate length of disk cycle*/
+ diskbase = BME_disk_getpointer(v->edge, v);
+ ok = BME_cycle_validate(v->tflag1, diskbase);
+ if(!ok) VHALT(halt);
+ /*validate that each edge in disk cycle contains V*/
+ for(i=0, e=v->edge; i < v->tflag1; i++, e = BME_disk_nextedge(e,v)){
+ ok = BME_vert_in_edge(e, v);
+ if(!ok) VHALT(halt);
+ }
+ }
+ else VHALT(halt);
+ }
+ }
+ /*validate edges*/
+ for(e=bm->edges.first; e; e=e->next){
+ /*seperate these into BME_disk_hasedge (takes pointer to edge)*/
+ /*search v1 disk cycle for edge*/
+ ok = BME_disk_hasedge(e->v1,e);
+ if(!ok) VHALT(halt);
+ /*search v2 disk cycle for edge*/
+ ok = BME_disk_hasedge(e->v2,e);
+ if(!ok) VHALT(halt);
+ }
+
+ for(e=bm->edges.first; e; e=e->next) e->tflag2 = 0; //store incident faces
+ /*Validate the loop cycle integrity.*/
+ for(f=bm->polys.first; f; f=f->next){
+ ok = BME_cycle_length(f->loopbase);
+ if(ok > 1){
+ f->tflag1 = ok;
+ }
+ else VHALT(halt);
+ for(i=0, l=f->loopbase; i < f->tflag1; i++, l=l->next){
+ /*verify loop->v pointers*/
+ ok = BME_verts_in_edge(l->v, l->next->v, l->e);
+ if(!ok) VHALT(halt);
+ /*verify radial node data pointer*/
+ if(l->radial.data != l) VHALT(halt);
+ /*validate l->e->loop poitner*/
+ if(l->e->loop == NULL) VHALT(halt);
+ /*validate l->f pointer*/
+ if(l->f != f) VHALT(halt);
+ /*see if l->e->loop is actually in radial cycle*/
+
+ l->e->tflag2++;
+ }
+ }
+
+ /*validate length of radial cycle*/
+ for(e=bm->edges.first; e; e=e->next){
+ if(e->loop){
+ ok = BME_cycle_validate(e->tflag2,&(e->loop->radial));
+ if(!ok) VHALT(halt);
+ }
+ }
+
+ /*validate that EIDs are within range... if not indicates corrupted mem*/
+
+ /*if we get this far, pretty safe to return 1*/
+ return 1;
+}
+
+/* Currently just a convient place for a breakpoint.
+ Probably should take an error string
+*/
+void BME_error(void){
+ printf("BME modelling error!");
+}
diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c
new file mode 100644
index 00000000000..78afb502572
--- /dev/null
+++ b/source/blender/blenkernel/intern/BME_structure.c
@@ -0,0 +1,618 @@
+/**
+ * BME_structure.c jan 2007
+ *
+ * Low level routines for manipulating the BMesh structure.
+ *
+ * $Id: BME_structure.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <limits.h>
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_ghash.h"
+
+#include "BKE_customdata.h"
+/**
+ * MISC utility functions.
+ *
+ */
+
+int BME_vert_in_edge(BME_Edge *e, BME_Vert *v){
+ if(e->v1 == v || e->v2 == v) return 1;
+ return 0;
+}
+int BME_verts_in_edge(BME_Vert *v1, BME_Vert *v2, BME_Edge *e){
+ if(e->v1 == v1 && e->v2 == v2) return 1;
+ else if(e->v1 == v2 && e->v2 == v1) return 1;
+ return 0;
+}
+
+BME_Vert *BME_edge_getothervert(BME_Edge *e, BME_Vert *v){
+ if(e->v1 == v) return e->v2;
+ else if(e->v2 == v) return e->v1;
+ return NULL;
+}
+
+int BME_edge_swapverts(BME_Edge *e, BME_Vert *orig, BME_Vert *new){
+ if(e->v1 == orig){
+ e->v1 = new;
+ e->d1.next = NULL;
+ e->d1.prev = NULL;
+ return 1;
+ }
+ else if(e->v2 == orig){
+ e->v2 = new;
+ e->d2.next = NULL;
+ e->d2.prev = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * ALLOCATION/DEALLOCATION FUNCTIONS
+ */
+
+BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
+ BME_Vert *v=NULL;
+ v = MEM_callocN(sizeof(BME_Vert), "BME Vertex");
+ BLI_addtail(&(bm->verts), v);
+ v->EID = bm->nextv;
+ bm->nextv++;
+ bm->totvert++;
+
+ if(example)
+ VECCOPY(v->co,example->co);
+ //if(example)
+ // CustomData_em_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
+ //else
+ // CustomData_em_set_default(&bm->vdata, &v->data);
+
+ return v;
+}
+BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){
+ BME_Edge *e=NULL;
+ e = MEM_callocN(sizeof(BME_Edge), "BME_Edge");
+ e->v1 = v1;
+ e->v2 = v2;
+ e->d1.data = e;
+ e->d2.data = e;
+ e->EID = bm->nexte;
+ bm->nexte++;
+ bm->totedge++;
+ BLI_addtail(&(bm->edges), e);
+
+ //if(example)
+ // CustomData_em_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
+ //else
+ // CustomData_em_set_default(&bm->edata, &e->data);
+
+
+ return e;
+}
+BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){
+ /*allocate a BME_Loop and add it to the loophash*/
+ BME_Loop *l=NULL;
+ BME_CycleNode *loopnode = MEM_callocN(sizeof(BME_CycleNode),"BME Loop Reference");
+ l = MEM_callocN(sizeof(BME_Loop), "BME_Loop");
+ l->radial.data = l;
+ l->v = v;
+ l->e = e;
+ l->f = f;
+ l->EID = bm->nextl;
+ l->gref = loopnode;
+ loopnode->data = l;
+ BLI_addtail(&(bm->loops),loopnode);
+ bm->nextl++;
+ bm->totloop++;
+
+
+/* if(example)
+ BME_CustomData_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
+ else
+ BME_CustomData_set_default(&bm->ldata, &l->data);
+*/
+ return l;
+}
+
+BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
+ BME_Poly *f = NULL;
+ f= MEM_callocN(sizeof(BME_Poly),"BME_Poly");
+ BLI_addtail(&(bm->polys),f);
+ f->EID = bm->nextp;
+ bm->nextp++;
+ bm->totpoly++;
+
+ //if(example)
+ // CustomData_em_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
+ //else
+ // CustomData_em_set_default(&bm->pdata, &f->data);
+
+
+ return f;
+}
+
+/* free functions dont do much *yet*. When per-vertex, per-edge and per-face/faceloop
+ data is added though these will be needed.
+*/
+void BME_free_vert(BME_Mesh *bm, BME_Vert *v){
+ bm->totvert--;
+ //CustomData_em_free_block(&bm->vdata, &v->data);
+ MEM_freeN(v);
+}
+void BME_free_edge(BME_Mesh *bm, BME_Edge *e){
+ bm->totedge--;
+ //CustomData_em_free_block(&bm->edata, &e->data);
+ MEM_freeN(e);
+}
+void BME_free_poly(BME_Mesh *bm, BME_Poly *f){
+ bm->totpoly--;
+ //CustomData_em_free_block(&bm->pdata, &f->data);
+ MEM_freeN(f);
+}
+void BME_delete_loop(BME_Mesh *bm, BME_Loop *l){
+ bm->totloop--;
+ //CustomData_em_free_block(&bm->ldata, &l->data);
+ MEM_freeN(l);
+}
+void BME_free_loop(BME_Mesh *bm, BME_Loop *l){
+ BME_CycleNode *loopref = l->gref;
+ BLI_freelinkN(&(bm->loops),loopref);
+ BME_delete_loop(bm,l);
+}
+
+
+/**
+ * BMESH CYCLES
+ *
+ * Cycles are circular doubly linked lists that form the basis of adjacency
+ * information in the BME modeller. Full adjacency relations can be derived
+ * from examining these cycles very quickly. Although each cycle is a double
+ * circular linked list, each one is considered to have a 'base' or 'head',
+ * and care must be taken by Euler code when modifying the contents of a cycle.
+ *
+ * The contents of this file are split into two parts. First there are the
+ * BME_cycle family of functions which are generic circular double linked list
+ * procedures. The second part contains higher level procedures for supporting
+ * modification of specific cycle types.
+ *
+ * The three cycles explicitly stored in the BMesh data structure are as follows:
+ *
+ * 1: The Disk Cycle - A circle of edges around a vertex
+ * Base: vertex->edge pointer.
+ *
+ * This cycle is the most complicated in terms of its structure. Each BME_Edge contains
+ * two BME_CycleNode structures to keep track of that edge's membership in the disk cycle
+ * of each of its vertices. However for any given vertex it may be the first in some edges
+ * in its disk cycle and the second for others. The BME_disk_XXX family of functions contain
+ * some nice utilities for navigating disk cycles in a way that hides this detail from the
+ * tool writer.
+ *
+ * Note that the disk cycle is completley independant from face data. One advantage of this
+ * is that wire edges are fully integrated into the topology database. Another is that the
+ * the disk cycle has no problems dealing with non-manifold conditions involving faces.
+ *
+ * Functions relating to this cycle:
+ *
+ * BME_disk_append_edge
+ * BME_disk_remove_edge
+ * BME_disk_nextedge
+ * BME_disk_getpointer
+ *
+ * 2: The Radial Cycle - A circle of face edges (BME_Loop) around an edge
+ * Base: edge->loop->radial structure.
+ *
+ * The radial cycle is similar to the radial cycle in the radial edge data structure.*
+ * Unlike the radial edge however, the radial cycle does not require a large amount of memory
+ * to store non-manifold conditions since BMesh does not keep track of region/shell
+ * information.
+ *
+ * Functions relating to this cycle:
+ *
+ * BME_radial_append
+ * BME_radial_remove_loop
+ * BME_radial_nextloop
+ * BME_radial_find_face
+ *
+ *
+ * 3: The Loop Cycle - A circle of face edges around a polygon.
+ * Base: polygon->loopbase.
+ *
+ * The loop cycle keeps track of a faces vertices and edges. It should be noted that the
+ * direction of a loop cycle is either CW or CCW depending on the face normal, and is
+ * not oriented to the faces editedges.
+ *
+ * Functions relating to this cycle:
+ *
+ * BME_cycle_XXX family of functions.
+ *
+ *
+ * Note that the order of elements in all cycles except the loop cycle is undefined. This
+ * leads to slightly increased seek time for deriving some adjacency relations, however the
+ * advantage is that no intrinsic properties of the data structures are dependant upon the
+ * cycle order and all non-manifold conditions are represented trivially.
+ *
+*/
+
+
+void BME_cycle_append(void *h, void *nt)
+{
+ BME_CycleNode *oldtail, *head, *newtail;
+
+ head = (BME_CycleNode*)h;
+ newtail = (BME_CycleNode*)nt;
+
+ if(head->next == NULL){
+ head->next = newtail;
+ head->prev = newtail;
+ newtail->next = head;
+ newtail->prev = head;
+ }
+ else{
+ oldtail = head->prev;
+ oldtail->next = newtail;
+ newtail->next = head;
+ newtail->prev = oldtail;
+ head->prev = newtail;
+
+ }
+}
+
+/**
+ * BME_cycle_length
+ *
+ * Count the nodes in a cycle.
+ *
+ * Returns -
+ * Integer
+ */
+
+int BME_cycle_length(void *h){
+
+ int len = 0;
+ BME_CycleNode *head, *curnode;
+ head = (BME_CycleNode*)h;
+
+ if(head){
+ len = 1;
+ for(curnode = head->next; curnode != head; curnode=curnode->next){
+ if(len == INT_MAX){ //check for infinite loop/corrupted cycle
+ return -1;
+ }
+ len++;
+ }
+ }
+ return len;
+}
+
+
+/**
+ * BME_cycle_remove
+ *
+ * Removes a node from a cycle.
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+
+int BME_cycle_remove(void *h, void *remn)
+{
+ int i, len;
+ BME_CycleNode *head, *remnode, *curnode;
+
+ head = (BME_CycleNode*)h;
+ remnode = (BME_CycleNode*)remn;
+ len = BME_cycle_length(h);
+
+ if(len == 1 && head == remnode){
+ head->next = NULL;
+ head->prev = NULL;
+ return 1;
+ }
+ else{
+ for(i=0, curnode = head; i < len; curnode = curnode->next){
+ if(curnode == remnode){
+ remnode->prev->next = remnode->next;
+ remnode->next->prev = remnode->prev;
+ /*zero out remnode pointers, important!*/
+ //remnode->next = NULL;
+ //remnode->prev = NULL;
+ return 1;
+
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * BME_cycle_validate
+ *
+ * Validates a cycle. Takes as an argument the expected length of the cycle and
+ * a pointer to the cycle head or base.
+ *
+ *
+ * Returns -
+ * 1 for success, 0 for failure.
+ */
+
+int BME_cycle_validate(int len, void *h){
+ int i;
+ BME_CycleNode *curnode, *head;
+ head = (BME_CycleNode*)h;
+
+ /*forward validation*/
+ for(i = 0, curnode = head; i < len; i++, curnode = curnode->next);
+ if(curnode != head) return 0;
+
+ /*reverse validation*/
+ for(i = 0, curnode = head; i < len; i++, curnode = curnode->prev);
+ if(curnode != head) return 0;
+
+ return 1;
+}
+
+/*Begin Disk Cycle routines*/
+
+/**
+ * BME_disk_nextedge
+ *
+ * Find the next edge in a disk cycle
+ *
+ * Returns -
+ * Pointer to the next edge in the disk cycle for the vertex v.
+ */
+
+BME_Edge *BME_disk_nextedge(BME_Edge *e, BME_Vert *v)
+{
+ if(BME_vert_in_edge(e, v)){
+ if(e->v1 == v) return e->d1.next->data;
+ else if(e->v2 == v) return e->d2.next->data;
+ }
+ return NULL;
+}
+
+/**
+ * BME_disk_getpointer
+ *
+ * Given an edge and one of its vertices, find the apporpriate CycleNode
+ *
+ * Returns -
+ * Pointer to BME_CycleNode.
+ */
+BME_CycleNode *BME_disk_getpointer(BME_Edge *e, BME_Vert *v){
+ /*returns pointer to the cycle node for the appropriate vertex in this disk*/
+ if(e->v1 == v) return &(e->d1);
+ else if (e->v2 == v) return &(e->d2);
+ return NULL;
+}
+
+/**
+ * BME_disk_append_edge
+ *
+ * Appends edge to the end of a vertex disk cycle.
+ *
+ * Returns -
+ * 1 for success, 0 for failure
+ */
+
+int BME_disk_append_edge(BME_Edge *e, BME_Vert *v)
+{
+
+ BME_CycleNode *base, *tail;
+
+ if(BME_vert_in_edge(e, v) == 0) return 0; /*check to make sure v is in e*/
+
+ /*check for loose vert first*/
+ if(v->edge == NULL){
+ v->edge = e;
+ base = tail = BME_disk_getpointer(e, v);
+ BME_cycle_append(base, tail); /*circular reference is ok!*/
+ return 1;
+ }
+
+ /*insert e at the end of disk cycle and make it the new v->edge*/
+ base = BME_disk_getpointer(v->edge, v);
+ tail = BME_disk_getpointer(e, v);
+ BME_cycle_append(base, tail);
+ return 1;
+}
+
+/**
+ * BME_disk_remove_edge
+ *
+ * Removes an edge from a disk cycle. If the edge to be removed is
+ * at the base of the cycle, the next edge becomes the new base.
+ *
+ *
+ * Returns -
+ * Nothing
+ */
+
+void BME_disk_remove_edge(BME_Edge *e, BME_Vert *v)
+{
+ BME_CycleNode *base, *remnode;
+ BME_Edge *newbase;
+ int len;
+
+ base = BME_disk_getpointer(v->edge, v);
+ remnode = BME_disk_getpointer(e, v);
+
+ /*first deal with v->edge pointer...*/
+ len = BME_cycle_length(base);
+ if(len == 1) newbase = NULL;
+ else if(v->edge == e) newbase = base->next-> data;
+ else newbase = v->edge;
+
+ /*remove and rebase*/
+ BME_cycle_remove(base, remnode);
+ v->edge = newbase;
+}
+
+/**
+ * BME_disk_next_edgeflag
+ *
+ * Searches the disk cycle of v, starting with e, for the
+ * next edge that has either eflag or tflag.
+ *
+ * BME_Edge pointer.
+ */
+
+BME_Edge *BME_disk_next_edgeflag(BME_Edge *e, BME_Vert *v, int eflag, int tflag){
+
+ BME_CycleNode *diskbase;
+ BME_Edge *curedge;
+ int len, ok;
+
+ if(eflag && tflag) return NULL;
+
+ ok = BME_vert_in_edge(e,v);
+ if(ok){
+ diskbase = BME_disk_getpointer(e, v);
+ len = BME_cycle_length(diskbase);
+ curedge = BME_disk_nextedge(e,v);
+ while(curedge != e){
+ if(tflag){
+ if(curedge->tflag1 == tflag) return curedge;
+ }
+ else if(eflag){
+ if(curedge->eflag1 == eflag) return curedge;
+ }
+ curedge = BME_disk_nextedge(curedge, v);
+ }
+ }
+ return NULL;
+}
+
+/**
+ * BME_disk_count_edgeflag
+ *
+ * Counts number of edges in this verts disk cycle which have
+ * either eflag or tflag (but not both!)
+ *
+ * Returns -
+ * Integer.
+ */
+
+int BME_disk_count_edgeflag(BME_Vert *v, int eflag, int tflag){
+ BME_CycleNode *diskbase;
+ BME_Edge *curedge;
+ int i, len=0, count=0;
+
+ if(v->edge){
+ if(eflag && tflag) return 0; /*tflag and eflag are reserved for different functions!*/
+ diskbase = BME_disk_getpointer(v->edge, v);
+ len = BME_cycle_length(diskbase);
+
+ for(i = 0, curedge=v->edge; i<len; i++){
+ if(tflag){
+ if(curedge->tflag1 == tflag) count++;
+ }
+ else if(eflag){
+ if(curedge->eflag1 == eflag) count++;
+ }
+ curedge = BME_disk_nextedge(curedge, v);
+ }
+ }
+ return count;
+}
+
+int BME_disk_hasedge(BME_Vert *v, BME_Edge *e){
+ BME_CycleNode *diskbase;
+ BME_Edge *curedge;
+ int i, len=0;
+
+ if(v->edge){
+ diskbase = BME_disk_getpointer(v->edge,v);
+ len = BME_cycle_length(diskbase);
+
+ for(i = 0, curedge=v->edge; i<len; i++){
+ if(curedge == e) return 1;
+ else curedge=BME_disk_nextedge(curedge, v);
+ }
+ }
+ return 0;
+}
+/*end disk cycle routines*/
+
+BME_Loop *BME_radial_nextloop(BME_Loop *l){
+ return (BME_Loop*)(l->radial.next->data);
+}
+
+void BME_radial_append(BME_Edge *e, BME_Loop *l){
+ if(e->loop == NULL) e->loop = l;
+ BME_cycle_append(&(e->loop->radial), &(l->radial));
+}
+
+void BME_radial_remove_loop(BME_Loop *l, BME_Edge *e)
+{
+ BME_Loop *newbase;
+ int len;
+
+ /*deal with edge->loop pointer*/
+ len = BME_cycle_length(&(e->loop->radial));
+ if(len == 1) newbase = NULL;
+ else if(e->loop == l) newbase = e->loop->radial.next->data;
+ else newbase = e->loop;
+
+ /*remove and rebase*/
+ BME_cycle_remove(&(e->loop->radial), &(l->radial));
+ e->loop = newbase;
+}
+
+int BME_radial_find_face(BME_Edge *e,BME_Poly *f)
+{
+
+ BME_Loop *curloop;
+ int i, len;
+
+ len = BME_cycle_length(&(e->loop->radial));
+ for(i = 0, curloop = e->loop; i < len; i++, curloop = curloop->radial.next->data){
+ if(curloop->f == f) return 1;
+ }
+ return 0;
+}
+
+struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v) {
+ BME_Loop *l;
+ int i, len;
+
+ len = BME_cycle_length(f->loopbase);
+ for (i = 0, l=f->loopbase; i < len; i++, l=l->next) {
+ if (l->v == v) return l;
+ }
+ return NULL;
+}
diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c
new file mode 100644
index 00000000000..25de4445693
--- /dev/null
+++ b/source/blender/blenkernel/intern/BME_tools.c
@@ -0,0 +1,1212 @@
+/**
+ * BME_tools.c jan 2007
+ *
+ * Functions for changing the topology of a mesh.
+ *
+ * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle and Levi Schooley.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "blendef.h"
+
+/*split this all into a seperate bevel.c file in src*/
+
+/* ------- Bevel code starts here -------- */
+
+BME_TransData_Head *BME_init_transdata(int bufsize) {
+ BME_TransData_Head *td;
+
+ td = MEM_callocN(sizeof(BME_TransData_Head), "BMesh transdata header");
+ td->gh = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp);
+ td->ma = BLI_memarena_new(bufsize);
+ BLI_memarena_use_calloc(td->ma);
+
+ return td;
+}
+
+void BME_free_transdata(BME_TransData_Head *td) {
+ BLI_ghash_free(td->gh,NULL,NULL);
+ BLI_memarena_free(td->ma);
+ MEM_freeN(td);
+}
+
+BME_TransData *BME_assign_transdata(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v,
+ float *co, float *org, float *vec, float *loc,
+ float factor, float weight, float maxfactor, float *max) {
+ BME_TransData *vtd;
+ int is_new = 0;
+
+ if (v == NULL) return NULL;
+
+ if ((vtd = BLI_ghash_lookup(td->gh, v)) == NULL && bm != NULL) {
+ vtd = BLI_memarena_alloc(td->ma, sizeof(*vtd));
+ BLI_ghash_insert(td->gh, v, vtd);
+ td->len++;
+ is_new = 1;
+ }
+
+ vtd->bm = bm;
+ vtd->v = v;
+ if (co != NULL) VECCOPY(vtd->co,co);
+ if (org == NULL && is_new) { VECCOPY(vtd->org,v->co); } /* default */
+ else if (org != NULL) VECCOPY(vtd->org,org);
+ if (vec != NULL) {
+ VECCOPY(vtd->vec,vec);
+ Normalize(vtd->vec);
+ }
+ vtd->loc = loc;
+
+ vtd->factor = factor;
+ vtd->weight = weight;
+ vtd->maxfactor = maxfactor;
+ vtd->max = max;
+
+ return vtd;
+}
+
+BME_TransData *BME_get_transdata(BME_TransData_Head *td, BME_Vert *v) {
+ BME_TransData *vtd;
+ vtd = BLI_ghash_lookup(td->gh, v);
+ return vtd;
+}
+
+/* a hack (?) to use the transdata memarena to allocate floats for use with the max limits */
+float *BME_new_transdata_float(BME_TransData_Head *td) {
+ return BLI_memarena_alloc(td->ma, sizeof(float));
+}
+
+static int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
+ BME_Edge *e, *oe;
+ BME_Loop *l;
+ int len, count, flag;
+
+ if (v->edge == NULL) {
+ /* loose vert */
+ return 1;
+ }
+
+ /* count edges while looking for non-manifold edges */
+ oe = v->edge;
+ for (len=0,e=v->edge; e != oe || (e == oe && len == 0); len++,e=BME_disk_nextedge(e,v)) {
+ if (e->loop == NULL) {
+ /* loose edge */
+ return 1;
+ }
+
+ if (BME_cycle_length(&(e->loop->radial)) > 2) {
+ /* edge shared by more than two faces */
+ return 1;
+ }
+ }
+
+ count = 1;
+ flag = 1;
+ e = NULL;
+ oe = v->edge;
+ l = oe->loop;
+ while(e != oe) {
+ if (l->v == v) l = l->prev;
+ else l = l->next;
+ e = l->e;
+ count++; /* count the edges */
+
+ if (flag && l->radial.next->data == l) {
+ /* we've hit the edge of an open mesh, reset once */
+ flag = 0;
+ count = 1;
+ oe = e;
+ e = NULL;
+ l = oe->loop;
+ }
+ else if (l->radial.next->data == l) {
+ /* break the loop */
+ e = oe;
+ }
+ else {
+ l = l->radial.next->data;
+ }
+ }
+
+ if (count < len) {
+ /* vert shared by multiple regions */
+ return 1;
+ }
+
+ return 0;
+}
+
+/* a wrapper for BME_JFKE that [for now just] checks to
+ * make sure loop directions are compatible */
+static BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
+ BME_Loop *l1, *l2;
+
+ l1 = e->loop;
+ l2 = l1->radial.next->data;
+ if (l1->v == l2->v) {
+ BME_loop_reverse(bm, f2);
+ }
+
+ return BME_JFKE(bm, f1, f2, e);
+}
+
+/* a wrapper for BME_SFME that transfers element flags */
+static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
+ BME_Poly *nf;
+ nf = BME_SFME(bm,f,v1,v2,nl);
+ nf->flag = f->flag;
+ /* if the edge was selected, select this face, too */
+ if (example->flag & SELECT) f->flag |= ME_FACE_SEL;
+ nf->h = f->h;
+ nf->mat_nr = f->mat_nr;
+ if (nl && example) {
+ (*nl)->e->flag = example->flag;
+ (*nl)->e->h = example->h;
+ (*nl)->e->crease = example->crease;
+ (*nl)->e->bweight = example->bweight;
+ }
+
+ return nf;
+}
+
+/* a wrapper for BME_SEMV that transfers element flags */
+static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
+ BME_Vert *nv, *v2;
+ float len;
+
+ v2 = BME_edge_getothervert(e,v);
+ nv = BME_SEMV(bm,v,e,ne);
+ if (nv == NULL) return NULL;
+ VECSUB(nv->co,v2->co,v->co);
+ len = VecLength(nv->co);
+ VECADDFAC(nv->co,v->co,nv->co,len*percent);
+ nv->flag = v->flag;
+ nv->bweight = v->bweight;
+ if (ne) {
+ (*ne)->flag = e->flag;
+ (*ne)->h = e->h;
+ (*ne)->crease = e->crease;
+ (*ne)->bweight = e->bweight;
+ }
+
+ return nv;
+}
+
+static int BME_bevel_is_split_vert(BME_Loop *l) {
+ /* look for verts that have already been added to the edge when
+ * beveling other polys; this can be determined by testing the
+ * vert and the edges around it for originality
+ */
+ if ((l->v->tflag1 & BME_BEVEL_ORIG)==0
+ && (l->e->tflag1 & BME_BEVEL_ORIG)
+ && (l->prev->e->tflag1 & BME_BEVEL_ORIG))
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/* get a vector, vec, that points from v1->co to wherever makes sense to
+ * the bevel operation as a whole based on the relationship between v1 and v2
+ * (won't necessarily be a vec from v1->co to v2->co, though it probably will be);
+ * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */
+static int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head *td) {
+ BME_TransData *vtd1, *vtd2;
+
+ vtd1 = BME_get_transdata(td,v1);
+ vtd2 = BME_get_transdata(td,v2);
+ if (!vtd1 || !vtd2) {
+ //printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
+ return -1;
+ }
+
+ /* compare the transform origins to see if we can use the vert co's;
+ * if they belong to different origins, then we will use the origins to determine
+ * the vector */
+ if (VecCompare(vtd1->org,vtd2->org,0.000001f)) {
+ VECSUB(vec,v2->co,v1->co);
+ if (VecLength(vec) < 0.000001f) {
+ VecMulf(vec,0);
+ }
+ return 0;
+ }
+ else {
+ VECSUB(vec,vtd2->org,vtd1->org);
+ if (VecLength(vec) < 0.000001f) {
+ VecMulf(vec,0);
+ }
+ return 1;
+ }
+}
+
+/* "Projects" a vector perpendicular to vec2 against vec1, such that
+ * the projected vec1 + vec2 has a min distance of 1 from the "edge" defined by vec2.
+ * note: the direction, is_forward, is used in conjunction with up_vec to determine
+ * whether this is a convex or concave corner. If it is a concave corner, it will
+ * be projected "backwards." If vec1 is before vec2, is_forward should be 0 (we are projecting backwards).
+ * vec1 is the vector to project onto (expected to be normalized)
+ * vec2 is the direction of projection (pointing away from vec1)
+ * up_vec is used for orientation (expected to be normalized)
+ * returns the length of the projected vector that lies along vec1 */
+static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *td) {
+ float factor, vec3[3], tmp[3],c1,c2;
+
+ Crossf(tmp,vec1,vec2);
+ Normalize(tmp);
+ factor = Inpf(up_vec,tmp);
+ if ((factor > 0 && is_forward) || (factor < 0 && !is_forward)) {
+ Crossf(vec3,vec2,tmp); /* hmm, maybe up_vec should be used instead of tmp */
+ }
+ else {
+ Crossf(vec3,tmp,vec2); /* hmm, maybe up_vec should be used instead of tmp */
+ }
+ Normalize(vec3);
+ c1 = Inpf(vec3,vec1);
+ c2 = Inpf(vec1,vec1);
+ if (fabs(c1) < 0.000001f || fabs(c2) < 0.000001f) {
+ factor = 0.0f;
+ }
+ else {
+ factor = c2/c1;
+ }
+
+ return factor;
+}
+
+/* BME_bevel_split_edge() is the main math work-house; its responsibilities are:
+ * using the vert and the loop passed, get or make the split vert, set its coordinates
+ * and transform properties, and set the max limits.
+ * Finally, return the split vert. */
+static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
+ BME_TransData *vtd, *vtd1, *vtd2;
+ BME_Vert *sv, *v2, *v3;
+ BME_Loop *lv1, *lv2;
+ BME_Edge *ne, *e1, *e2;
+ float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
+ int is_edge, forward, is_split_vert;
+
+ if (l == NULL) {
+ /* what you call operator overloading in C :)
+ * I wanted to use the same function for both wire edges and poly loops
+ * so... here we walk around edges to find the needed verts */
+ forward = 1;
+ is_split_vert = 0;
+ if (v->edge == NULL) {
+ //printf("We can't split a loose vert's edge!\n");
+ return NULL;
+ }
+ e1 = v->edge; /* we just use the first two edges */
+ e2 = BME_disk_nextedge(v->edge, v);
+ if (e1 == e2) {
+ //printf("You need at least two edges to use BME_bevel_split_edge()\n");
+ return NULL;
+ }
+ v2 = BME_edge_getothervert(e1, v);
+ v3 = BME_edge_getothervert(e2, v);
+ if (v1 != v2 && v1 != v3) {
+ //printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
+ return NULL;
+ }
+ if (v1 == v2) {
+ v2 = v3;
+ }
+ else {
+ e1 = e2;
+ }
+ sv = BME_split_edge(bm,v,e1,&ne,0);
+ BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
+ sv->tflag1 |= BME_BEVEL_BEVEL;
+ ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
+ BME_bevel_get_vec(vec1,v1,v,td);
+ BME_bevel_get_vec(vec2,v2,v,td);
+ Crossf(t_up_vec,vec1,vec2);
+ Normalize(t_up_vec);
+ up_vec = t_up_vec;
+ }
+ else {
+ /* establish loop direction */
+ if (l->v == v) {
+ forward = 1;
+ lv1 = l->next;
+ lv2 = l->prev;
+ v1 = l->next->v;
+ v2 = l->prev->v;
+ }
+ else if (l->next->v == v) {
+ forward = 0;
+ lv1 = l;
+ lv2 = l->next->next;
+ v1 = l->v;
+ v2 = l->next->next->v;
+ }
+ else {
+ //printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
+ return NULL;
+ }
+
+ if (BME_bevel_is_split_vert(lv1)) {
+ is_split_vert = 1;
+ sv = v1;
+ if (forward) v1 = l->next->next->v;
+ else v1 = l->prev->v;
+ }
+ else {
+ is_split_vert = 0;
+ sv = BME_split_edge(bm,v,l->e,&ne,0);
+ BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
+ sv->tflag1 |= BME_BEVEL_BEVEL;
+ ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
+ }
+
+ if (BME_bevel_is_split_vert(lv2)) {
+ if (forward) v2 = lv2->prev->v;
+ else v2 = lv2->next->v;
+ }
+ }
+
+ is_edge = BME_bevel_get_vec(vec1,v,v1,td); /* get the vector we will be projecting onto */
+ BME_bevel_get_vec(vec2,v,v2,td); /* get the vector we will be projecting parallel to */
+ len = VecLength(vec1);
+ Normalize(vec1);
+
+ vtd = BME_get_transdata(td, sv);
+ vtd1 = BME_get_transdata(td, v);
+ vtd2 = BME_get_transdata(td,v1);
+
+ if (vtd1->loc == NULL) {
+ /* this is a vert with data only for calculating initial weights */
+ if (vtd1->weight < 0) {
+ vtd1->weight = 0;
+ }
+ scale = vtd1->weight/vtd1->factor;
+ if (!vtd1->max) {
+ vtd1->max = BME_new_transdata_float(td);
+ *vtd1->max = -1;
+ }
+ }
+ else {
+ scale = vtd1->weight;
+ }
+ vtd->max = vtd1->max;
+
+ if (is_edge && vtd1->loc != NULL) {
+ maxfactor = vtd1->maxfactor;
+ }
+ else {
+ maxfactor = scale*BME_bevel_project_vec(vec1,vec2,up_vec,forward,td);
+ if (vtd->maxfactor > 0 && vtd->maxfactor < maxfactor) {
+ maxfactor = vtd->maxfactor;
+ }
+ }
+
+ dis = (v1->tflag1 & BME_BEVEL_ORIG)? len/3 : len/2;
+ if (is_edge || dis > maxfactor*value) {
+ dis = maxfactor*value;
+ }
+ VECADDFAC(sv->co,v->co,vec1,dis);
+ VECSUB(vec1,sv->co,vtd1->org);
+ dis = VecLength(vec1);
+ Normalize(vec1);
+ BME_assign_transdata(td, bm, sv, vtd1->org, vtd1->org, vec1, sv->co, dis, scale, maxfactor, vtd->max);
+
+ return sv;
+}
+
+static float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_Head *td) {
+ BME_TransData *vtd1, *vtd2;
+ float max, fac1, fac2, vec1[3], vec2[3], vec3[3];
+
+ BME_bevel_get_vec(vec1,v1,v2,td);
+ vtd1 = BME_get_transdata(td,v1);
+ vtd2 = BME_get_transdata(td,v2);
+
+ if (vtd1->loc == NULL) {
+ fac1 = 0;
+ }
+ else {
+ VECCOPY(vec2,vtd1->vec);
+ VecMulf(vec2,vtd1->factor);
+ if (Inpf(vec1, vec1)) {
+ Projf(vec2,vec2,vec1);
+ fac1 = VecLength(vec2)/value;
+ }
+ else {
+ fac1 = 0;
+ }
+ }
+
+ if (vtd2->loc == NULL) {
+ fac2 = 0;
+ }
+ else {
+ VECCOPY(vec3,vtd2->vec);
+ VecMulf(vec3,vtd2->factor);
+ if (Inpf(vec1, vec1)) {
+ Projf(vec2,vec3,vec1);
+ fac2 = VecLength(vec2)/value;
+ }
+ else {
+ fac2 = 0;
+ }
+ }
+
+ if (fac1 || fac2) {
+ max = VecLength(vec1)/(fac1 + fac2);
+ if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) {
+ *vtd1->max = max;
+ }
+ if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) {
+ *vtd2->max = max;
+ }
+ }
+ else {
+ max = -1;
+ }
+
+ return max;
+}
+
+static BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int options, BME_TransData_Head *td) {
+ BME_Vert *ov1, *ov2, *v1, *v2;
+
+ ov1 = BME_edge_getothervert(v->edge, v);
+ ov2 = BME_edge_getothervert(BME_disk_nextedge(v->edge, v), v);
+
+ /* split the edges */
+ v1 = BME_bevel_split_edge(bm,v,ov1,NULL,NULL,value,td);
+ v1->tflag1 |= BME_BEVEL_NONMAN;
+ v2 = BME_bevel_split_edge(bm,v,ov2,NULL,NULL,value,td);
+ v2->tflag1 |= BME_BEVEL_NONMAN;
+
+ if (value > 0.5) {
+ BME_bevel_set_max(v1,ov1,value,td);
+ BME_bevel_set_max(v2,ov2,value,td);
+ }
+
+ /* remove the original vert */
+ if (res) {
+ BME_JEKV(bm,v->edge,v);
+ }
+
+ return v1;
+}
+
+static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+ BME_Vert *v1, *v2, *kv;
+ BME_Loop *kl=NULL, *nl;
+ BME_Edge *e;
+ BME_Poly *f;
+
+ f = l->f;
+ e = l->e;
+
+ if ((l->e->tflag1 & BME_BEVEL_BEVEL) == 0
+ && ((l->v->tflag1 & BME_BEVEL_BEVEL) || (l->next->v->tflag1 & BME_BEVEL_BEVEL)))
+ { /* sanity check */
+ return l;
+ }
+
+ /* checks and operations for prev edge */
+ /* first, check to see if this edge was inset previously */
+ if ((l->prev->e->tflag1 & BME_BEVEL_ORIG) == 0
+ && (l->v->tflag1 & BME_BEVEL_NONMAN) == 0) {
+ kl = l->prev->radial.next->data;
+ if (kl->v == l->v) kl = kl->prev;
+ else kl = kl->next;
+ kv = l->v;
+ }
+ else {
+ kv = NULL;
+ }
+ /* get/make the first vert to be used in SFME */
+ if (l->v->tflag1 & BME_BEVEL_NONMAN){
+ v1 = l->v;
+ }
+ else { /* we'll need to split the previous edge */
+ v1 = BME_bevel_split_edge(bm,l->v,NULL,l->prev,up_vec,value,td);
+ }
+ /* if we need to clean up geometry... */
+ if (kv) {
+ l = l->next;
+ if (kl->v == kv) {
+ BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
+ BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
+ BME_JEKV(bm,kl->e,kv);
+ }
+ else {
+ BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
+ BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
+ BME_JEKV(bm,kl->e,kv);
+ }
+ l = l->prev;
+ }
+
+ /* checks and operations for the next edge */
+ /* first, check to see if this edge was inset previously */
+ if ((l->next->e->tflag1 & BME_BEVEL_ORIG) == 0
+ && (l->next->v->tflag1 & BME_BEVEL_NONMAN) == 0) {
+ kl = l->next->radial.next->data;
+ if (kl->v == l->next->v) kl = kl->prev;
+ else kl = kl->next;
+ kv = l->next->v;
+ }
+ else {
+ kv = NULL;
+ }
+ /* get/make the second vert to be used in SFME */
+ if (l->next->v->tflag1 & BME_BEVEL_NONMAN) {
+ v2 = l->next->v;
+ }
+ else { /* we'll need to split the next edge */
+ v2 = BME_bevel_split_edge(bm,l->next->v,NULL,l->next,up_vec,value,td);
+ }
+ /* if we need to clean up geometry... */
+ if (kv) {
+ if (kl->v == kv) {
+ BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
+ BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
+ BME_JEKV(bm,kl->e,kv);
+ }
+ else {
+ BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
+ BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
+ BME_JEKV(bm,kl->e,kv);
+ }
+ }
+
+ if ((v1->tflag1 & BME_BEVEL_NONMAN)==0 || (v2->tflag1 & BME_BEVEL_NONMAN)==0) {
+ BME_split_face(bm,f,v2,v1,&l,e);
+ l->e->tflag1 = BME_BEVEL_BEVEL;
+ l = l->radial.next->data;
+ }
+
+ if (l->f != f){
+ //printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
+ }
+
+ return l;
+}
+
+static BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+ BME_Vert *v1, *v2;
+ BME_Poly *f;
+
+ /* get/make the first vert to be used in SFME */
+ /* may need to split the previous edge */
+ v1 = BME_bevel_split_edge(bm,l->v,NULL,l->prev,up_vec,value,td);
+
+ /* get/make the second vert to be used in SFME */
+ /* may need to split this edge (so move l) */
+ l = l->prev;
+ v2 = BME_bevel_split_edge(bm,l->next->v,NULL,l->next,up_vec,value,td);
+ l = l->next->next;
+
+ /* "cut off" this corner */
+ f = BME_split_face(bm,l->f,v2,v1,NULL,l->e);
+
+ return l;
+}
+
+/**
+ * BME_bevel_poly
+ *
+ * Polygon inset tool:
+ *
+ * Insets a polygon/face based on the tflag1's of its vertices
+ * and edges. Used by the bevel tool only, for now.
+ * The parameter "value" is the distance to inset (should be negative).
+ * The parameter "options" is not currently used.
+ *
+ * Returns -
+ * A BME_Poly pointer to the resulting inner face.
+*/
+static BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BME_TransData_Head *td) {
+ BME_Loop *l, *ol;
+ BME_TransData *vtd1, *vtd2;
+ float up_vec[3], vec1[3], vec2[3], vec3[3], fac1, fac2, max = -1;
+ int len, i;
+
+ up_vec[0] = 0.0f;
+ up_vec[1] = 0.0f;
+ up_vec[2] = 0.0f;
+ /* find a good normal for this face (there's better ways, I'm sure) */
+ ol = f->loopbase;
+ l = ol->next;
+ for (i=0,ol=f->loopbase,l=ol->next; l->next!=ol; l=l->next) {
+ BME_bevel_get_vec(vec1,l->next->v,ol->v,td);
+ BME_bevel_get_vec(vec2,l->v,ol->v,td);
+ Crossf(vec3,vec2,vec1);
+ VECADD(up_vec,up_vec,vec3);
+ i++;
+ }
+ VecMulf(up_vec,1.0f/i);
+ Normalize(up_vec);
+
+ for (i=0,len=f->len; i<len; i++,l=l->next) {
+ if ((l->e->tflag1 & BME_BEVEL_BEVEL) && (l->e->tflag1 & BME_BEVEL_ORIG)) {
+ max = 1.0f;
+ l = BME_bevel_edge(bm, l, value, options, up_vec, td);
+ }
+ else if ((l->v->tflag1 & BME_BEVEL_BEVEL) && (l->v->tflag1 & BME_BEVEL_ORIG) && (l->prev->e->tflag1 & BME_BEVEL_BEVEL) == 0) {
+ max = 1.0f;
+ l = BME_bevel_vert(bm, l, value, options, up_vec, td);
+ }
+ }
+
+ /* max pass */
+ if (value > 0.5 && max > 0) {
+ max = -1;
+ for (i=0,len=f->len; i<len; i++,l=l->next) {
+ if ((l->e->tflag1 & BME_BEVEL_BEVEL) || (l->e->tflag1 & BME_BEVEL_ORIG)) {
+ BME_bevel_get_vec(vec1,l->v,l->next->v,td);
+ vtd1 = BME_get_transdata(td,l->v);
+ vtd2 = BME_get_transdata(td,l->next->v);
+ if (vtd1->loc == NULL) {
+ fac1 = 0;
+ }
+ else {
+ VECCOPY(vec2,vtd1->vec);
+ VecMulf(vec2,vtd1->factor);
+ if (Inpf(vec1, vec1)) {
+ Projf(vec2,vec2,vec1);
+ fac1 = VecLength(vec2)/value;
+ }
+ else {
+ fac1 = 0;
+ }
+ }
+ if (vtd2->loc == NULL) {
+ fac2 = 0;
+ }
+ else {
+ VECCOPY(vec3,vtd2->vec);
+ VecMulf(vec3,vtd2->factor);
+ if (Inpf(vec1, vec1)) {
+ Projf(vec2,vec3,vec1);
+ fac2 = VecLength(vec2)/value;
+ }
+ else {
+ fac2 = 0;
+ }
+ }
+ if (fac1 || fac2) {
+ max = VecLength(vec1)/(fac1 + fac2);
+ if (vtd1->max && (*vtd1->max < 0 || max < *vtd1->max)) {
+ *vtd1->max = max;
+ }
+ if (vtd2->max && (*vtd2->max < 0 || max < *vtd2->max)) {
+ *vtd2->max = max;
+ }
+ }
+ }
+ }
+ }
+
+ return l->f;
+}
+
+static void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, float weight, float factor, int options) {
+ BME_TransData *vtd;
+
+ if (v->tflag1 & BME_BEVEL_NONMAN) return;
+ v->tflag1 |= BME_BEVEL_BEVEL;
+ if ( (vtd = BME_get_transdata(td, v)) ) {
+ if (options & BME_BEVEL_EMIN) {
+ vtd->factor = 1.0;
+ if (vtd->weight < 0 || weight < vtd->weight) {
+ vtd->weight = weight;
+ }
+ }
+ else if (options & BME_BEVEL_EMAX) {
+ vtd->factor = 1.0;
+ if (weight > vtd->weight) {
+ vtd->weight = weight;
+ }
+ }
+ else if (vtd->weight < 0) {
+ vtd->factor = factor;
+ vtd->weight = weight;
+ }
+ else {
+ vtd->factor += factor; /* increment number of edges with weights (will be averaged) */
+ vtd->weight += weight; /* accumulate all the weights */
+ }
+ }
+ else {
+ /* we'll use vtd->loc == NULL to mark that this vert is not moving */
+ vtd = BME_assign_transdata(td, bm, v, v->co, NULL, NULL, NULL, factor, weight, -1, NULL);
+ }
+}
+
+static float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
+ BME_Vert *v1, *v2;
+ BME_Loop *l1, *l2;
+ float vec1[3], vec2[3], vec3[3], vec4[3];
+
+ l1 = e->loop;
+ l2 = e->loop->radial.next->data;
+ if (l1->v == v) {
+ v1 = l1->prev->v;
+ v2 = l1->next->v;
+ }
+ else {
+ v1 = l1->next->next->v;
+ v2 = l1->v;
+ }
+ VECSUB(vec1,v1->co,v->co);
+ VECSUB(vec2,v2->co,v->co);
+ Crossf(vec3,vec1,vec2);
+
+ l1 = l2;
+ if (l1->v == v) {
+ v1 = l1->prev->v;
+ v2 = l1->next->v;
+ }
+ else {
+ v1 = l1->next->next->v;
+ v2 = l1->v;
+ }
+ VECSUB(vec1,v1->co,v->co);
+ VECSUB(vec2,v2->co,v->co);
+ Crossf(vec4,vec2,vec1);
+
+ Normalize(vec3);
+ Normalize(vec4);
+
+ return Inpf(vec3,vec4);
+}
+
+/**
+ * BME_bevel_initialize
+ *
+ * Prepare the mesh for beveling:
+ *
+ * Sets the tflag1's of the mesh elements based on the options passed.
+ *
+ * Returns -
+ * A BME_Mesh pointer to the BMesh passed as a parameter.
+*/
+static BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, float angle, BME_TransData_Head *td) {
+ BME_Vert *v;
+ BME_Edge *e;
+ BME_Poly *f;
+ BME_TransData *vtd;
+ MDeformVert *dvert;
+ MDeformWeight *dw;
+ int len;
+ float weight, threshold;
+
+ /* vert pass */
+ for (v=bm->verts.first; v; v=v->next) {
+ dvert = NULL;
+ dw = NULL;
+ v->tflag1 = BME_BEVEL_ORIG;
+ /* originally coded, a vertex gets tagged with BME_BEVEL_BEVEL in this pass if
+ * the vert is manifold (or is shared by only two edges - wire bevel)
+ * BME_BEVEL_SELECT is passed and the vert has v->flag&SELECT or
+ * BME_BEVEL_VWEIGHT is passed, and the vert has a defgrp and weight
+ * BME_BEVEL_ANGLE is not passed
+ * BME_BEVEL_EWEIGHT is not passed
+ */
+ /* originally coded, a vertex gets tagged with BME_BEVEL_NONMAN in this pass if
+ * the vert is loose, shared by multiple regions, or is shared by wire edges
+ * note: verts belonging to edges of open meshes are not tagged with BME_BEVEL_NONMAN
+ */
+ /* originally coded, a vertex gets a transform weight set in this pass if
+ * BME_BEVEL_VWEIGHT is passed, and the vert has a defgrp and weight
+ */
+
+ /* get disk cycle length */
+ if (v->edge == NULL) {
+ len = 0;
+ }
+ else {
+ len = BME_cycle_length(BME_disk_getpointer(v->edge,v));
+ /* we'll assign a default transform data to every vert (except the loose ones) */
+ vtd = BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 0, -1, -1, NULL);
+ }
+
+ /* check for non-manifold vert */
+ if (BME_is_nonmanifold_vert(bm,v)) {
+ v->tflag1 |= BME_BEVEL_NONMAN;
+ }
+
+ /* BME_BEVEL_BEVEL tests */
+ if ((v->tflag1 & BME_BEVEL_NONMAN) == 0 || len == 2) { /* either manifold vert, or wire vert */
+ if (((options & BME_BEVEL_SELECT) && (v->flag & SELECT))
+ || ((options & BME_BEVEL_WEIGHT) && (options & BME_BEVEL_VERT)) /* use weights for verts */
+ || ((options & BME_BEVEL_ANGLE) == 0
+ && (options & BME_BEVEL_SELECT) == 0
+ && (options & BME_BEVEL_WEIGHT) == 0))
+ {
+ if (options & BME_BEVEL_WEIGHT) {
+ /* do vert weight stuff */
+ //~ dvert = CustomData_em_get(&bm->vdata,v->data,CD_MDEFORMVERT);
+ //~ if (!dvert) continue;
+ //~ for (i = 0; i < dvert->totweight; ++i) {
+ //~ if(dvert->dw[i].def_nr == defgrp_index) {
+ //~ dw = &dvert->dw[i];
+ //~ break;
+ //~ }
+ //~ }
+ //~ if (!dw || dw->weight == 0.0) continue;
+ if (v->bweight == 0.0) continue;
+ vtd = BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 1.0, v->bweight, -1, NULL);
+ v->tflag1 |= BME_BEVEL_BEVEL;
+ }
+ else {
+ vtd = BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 1.0, 1.0, -1, NULL);
+ v->tflag1 |= BME_BEVEL_BEVEL;
+ }
+ }
+ }
+ }
+
+ /* edge pass */
+ threshold = (float)cos((angle + 0.00001) * M_PI / 180.0);
+ for (e=bm->edges.first; e; e=e->next) {
+ e->tflag1 = BME_BEVEL_ORIG;
+ weight = 0.0;
+ /* originally coded, an edge gets tagged with BME_BEVEL_BEVEL in this pass if
+ * BME_BEVEL_VERT is not set
+ * the edge is manifold (shared by exactly two faces)
+ * BME_BEVEL_SELECT is passed and the edge has e->flag&SELECT or
+ * BME_BEVEL_EWEIGHT is passed, and the edge has the crease set or
+ * BME_BEVEL_ANGLE is passed, and the edge is sharp enough
+ * BME_BEVEL_VWEIGHT is passed, and both verts are set for bevel
+ */
+ /* originally coded, a vertex gets tagged with BME_BEVEL_BEVEL in this pass if
+ * the vert belongs to the edge
+ * the vert is not tagged with BME_BEVEL_NONMAN
+ * the edge is eligible for bevel (even if BME_BEVEL_VERT is set, or the edge is shared by less than 2 faces)
+ */
+ /* originally coded, a vertex gets a transform weight set in this pass if
+ * the vert belongs to the edge
+ * the edge has a weight
+ */
+ /* note: edge weights are cumulative at the verts,
+ * i.e. the vert's weight is the average of the weights of its weighted edges
+ */
+
+ if (e->loop == NULL) {
+ len = 0;
+ e->v1->tflag1 |= BME_BEVEL_NONMAN;
+ e->v2->tflag1 |= BME_BEVEL_NONMAN;
+ }
+ else {
+ len = BME_cycle_length(&(e->loop->radial));
+ }
+
+ if (len > 2) {
+ /* non-manifold edge of the worst kind */
+ continue;
+ }
+
+ if ((options & BME_BEVEL_SELECT) && (e->flag & SELECT)) {
+ weight = 1.0;
+ /* stupid editmode doesn't always flush selections, or something */
+ e->v1->flag |= SELECT;
+ e->v2->flag |= SELECT;
+ }
+ else if ((options & BME_BEVEL_WEIGHT) && (options & BME_BEVEL_VERT) == 0) {
+ weight = e->bweight;
+ }
+ else if (options & BME_BEVEL_ANGLE) {
+ if ((e->v1->tflag1 & BME_BEVEL_NONMAN) == 0 && BME_bevel_get_angle(bm,e,e->v1) < threshold) {
+ e->tflag1 |= BME_BEVEL_BEVEL;
+ e->v1->tflag1 |= BME_BEVEL_BEVEL;
+ BME_bevel_add_vweight(td, bm, e->v1, 1.0, 1.0, options);
+ }
+ else {
+ BME_bevel_add_vweight(td, bm, e->v1, 0.0, 1.0, options);
+ }
+ if ((e->v2->tflag1 & BME_BEVEL_NONMAN) == 0 && BME_bevel_get_angle(bm,e,e->v2) < threshold) {
+ e->tflag1 |= BME_BEVEL_BEVEL;
+ e->v2->tflag1 |= BME_BEVEL_BEVEL;
+ BME_bevel_add_vweight(td, bm, e->v2, 1.0, 1.0, options);
+ }
+ else {
+ BME_bevel_add_vweight(td, bm, e->v2, 0.0, 1.0, options);
+ }
+ }
+ //~ else if ((options & BME_BEVEL_VWEIGHT) && (options & BME_BEVEL_VERT) == 0) {
+ //~ if ((e->v1->tflag1 & BME_BEVEL_BEVEL) && (e->v2->tflag1 & BME_BEVEL_BEVEL)) {
+ //~ e->tflag1 |= BME_BEVEL_BEVEL;
+ //~ }
+ //~ }
+ else if ((options & BME_BEVEL_SELECT) == 0
+ && (options & BME_BEVEL_VERT) == 0)
+ {
+ weight = 1.0;
+ }
+
+ if (weight > 0.0) {
+ e->tflag1 |= BME_BEVEL_BEVEL;
+ BME_bevel_add_vweight(td, bm, e->v1, weight, 1.0, options);
+ BME_bevel_add_vweight(td, bm, e->v2, weight, 1.0, options);
+ }
+
+ if (len != 2 || options & BME_BEVEL_VERT) {
+ e->tflag1 &= ~BME_BEVEL_BEVEL;
+ }
+ }
+
+ /* face pass */
+ for (f=bm->polys.first; f; f=f->next) f->tflag1 = BME_BEVEL_ORIG;
+
+ return bm;
+}
+
+/* tags all elements as originals */
+static BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
+ BME_Vert *v;
+ BME_Edge *e;
+ BME_Poly *f;
+
+ for (v = bm->verts.first; v; v=v->next) {
+ v->tflag1 |= BME_BEVEL_ORIG;
+ }
+
+ for (e=bm->edges.first; e; e=e->next) {
+ e->tflag1 |= BME_BEVEL_ORIG;
+ }
+
+ for (f=bm->polys.first; f; f=f->next) {
+ f->tflag1 |= BME_BEVEL_ORIG;
+ }
+
+ return bm;
+}
+
+/**
+ * BME_bevel_mesh
+ *
+ * Mesh beveling tool:
+ *
+ * Bevels an entire mesh. It currently uses the tflag1's of
+ * its vertices and edges to track topological changes.
+ * The parameter "value" is the distance to inset (should be negative).
+ * The parameter "options" is not currently used.
+ *
+ * Returns -
+ * A BME_Mesh pointer to the BMesh passed as a parameter.
+*/
+
+static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){
+ BME_Poly *f;
+ BME_Edge *e;
+ int done, len;
+
+ if(v->edge){
+ done = 0;
+ while(!done){
+ done = 1;
+ e = v->edge; /*loop the edge looking for a edge to dissolve*/
+ do{
+ f = NULL;
+ len = BME_cycle_length(&(e->loop->radial));
+ if(len == 2){
+ f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
+ }
+ if(f){
+ done = 0;
+ break;
+ }
+ e = BME_disk_nextedge(e,v);
+ }while(e != v->edge);
+ }
+ BME_JEKV(bm,v->edge,v);
+ }
+}
+static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
+ BME_Vert *v, *nv;
+ BME_Edge *e, *oe;
+ BME_Loop *l, *l2;
+ BME_Poly *f;
+ unsigned int i, len;
+
+ for (f=bm->polys.first; f; f=f->next) {
+ if(f->tflag1 & BME_BEVEL_ORIG) {
+ BME_bevel_poly(bm,f,value,options,td);
+ }
+ }
+
+ /* here we will loop through all the verts to clean up the left over geometry */
+ /* crazy idea. when res == 0, don't remove the original geometry */
+ for (v = bm->verts.first; v; /* we may kill v, so increment in-loop */) {
+ nv = v->next;
+ if ((v->tflag1 & BME_BEVEL_NONMAN) && (v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG)) {
+ v = BME_bevel_wire(bm, v, value, res, options, td);
+ }
+ else if (res && ((v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG))) {
+
+ /* first, make sure we're not sitting on an edge to be removed */
+ oe = v->edge;
+ e = BME_disk_nextedge(oe,v);
+ while ((e->tflag1 & BME_BEVEL_BEVEL) && (e->tflag1 & BME_BEVEL_ORIG)) {
+ e = BME_disk_nextedge(e,v);
+ if (e == oe) {
+ //printf("Something's wrong! We can't remove every edge here!\n");
+ break;
+ }
+ }
+ /* look for original edges, and remove them */
+ oe = e;
+ while ( (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) ) {
+ /* join the faces (we'll split them later) */
+ f = BME_JFKE_safe(bm,e->loop->f,((BME_Loop*)e->loop->radial.next->data)->f,e);
+ if (!f){
+ //printf("Non-manifold geometry not getting tagged right?\n");
+ }
+ }
+
+ /* all original edges marked to be beveled have been removed;
+ * now we need to link up the edges for this "corner" */
+ len = BME_cycle_length(BME_disk_getpointer(v->edge, v));
+ for (i=0,e=v->edge; i < len; i++,e=BME_disk_nextedge(e,v)) {
+ l = e->loop;
+ l2 = l->radial.next->data;
+ if (l->v != v) l = l->next;
+ if (l2->v != v) l2 = l2->next;
+ /* look for faces that have had the original edges removed via JFKE */
+ if (l->f->len > 3) {
+ BME_split_face(bm,l->f,l->next->v,l->prev->v,&l,l->e); /* clip this corner off */
+ if (len > 2) {
+ l->e->tflag1 |= BME_BEVEL_BEVEL;
+ }
+ }
+ if (l2->f->len > 3) {
+ BME_split_face(bm,l2->f,l2->next->v,l2->prev->v,&l,l2->e); /* clip this corner off */
+ if (len > 2) {
+ l->e->tflag1 |= BME_BEVEL_BEVEL;
+ }
+ }
+ }
+ bmesh_dissolve_disk(bm, v);
+ }
+ v = nv;
+ }
+
+ return bm;
+}
+
+static BME_Mesh *BME_tesselate(BME_Mesh *bm) {
+ BME_Loop *l, *nextloop;
+ BME_Poly *f;
+
+ for (f=bm->polys.first; f; f=f->next) {
+ l = f->loopbase;
+ while (l->f->len > 4) {
+ nextloop = l->next->next->next;
+ /* make a quad */
+ BME_split_face(bm,l->f,l->v,nextloop->v,NULL,l->e);
+ l = nextloop;
+ }
+ }
+ return bm;
+}
+
+
+/*Main bevel function:
+ Should be only one exported
+
+*/
+
+/* options that can be passed:
+ * BME_BEVEL_VWEIGHT <---- v, Look at vertex weights; use defgrp_index if option is present
+ * BME_BEVEL_SELECT <---- v,e, check selection for verts and edges
+ * BME_BEVEL_ANGLE <---- v,e, don't bevel-tag verts - tag verts per edge
+ * BME_BEVEL_VERT <---- e, don't tag edges
+ * BME_BEVEL_EWEIGHT <---- e, use crease flag for now
+ * BME_BEVEL_PERCENT <---- Will need to think about this one; will probably need to incorporate into actual bevel routine
+ * BME_BEVEL_RADIUS <---- Will need to think about this one; will probably need to incorporate into actual bevel routine
+ * All weights/limits are stored per-vertex
+ */
+BME_Mesh *BME_bevel(BME_Mesh *bm, float value, int res, int options, int defgrp_index, float angle, BME_TransData_Head **rtd) {
+ BME_Vert *v;
+ BME_TransData_Head *td;
+ BME_TransData *vtd;
+ int i;
+ float fac=1, d;
+
+ td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
+
+ BME_bevel_initialize(bm, options, defgrp_index, angle, td);
+
+ /* recursion math courtesy of Martin Poirier (theeth) */
+ for (i=0; i<res-1; i++) {
+ if (i==0) fac += 1.0f/3.0f; else fac += 1.0f/(3 * i * 2.0f);
+ }
+ d = 1.0f/fac;
+ /* crazy idea. if res == 0, don't remove original geometry */
+ for (i=0; i<res || (res==0 && i==0); i++) {
+ if (i != 0) BME_bevel_reinitialize(bm);
+ BME_model_begin(bm);
+ BME_bevel_mesh(bm,d,res,options,defgrp_index,td);
+ BME_model_end(bm);
+ if (i==0) d /= 3; else d /= 2;
+ }
+
+ BME_tesselate(bm);
+
+ if (rtd) {
+ *rtd = td;
+ return bm;
+ }
+
+ /* transform pass */
+ for (v = bm->verts.first; v; v=v->next) {
+ if ( (vtd = BME_get_transdata(td, v)) ) {
+ if (vtd->max && (*vtd->max > 0 && value > *vtd->max)) {
+ d = *vtd->max;
+ }
+ else {
+ d = value;
+ }
+ VECADDFAC(v->co,vtd->org,vtd->vec,vtd->factor*d);
+ }
+ v->tflag1 = 0;
+ }
+
+ BME_free_transdata(td);
+ return bm;
+}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index bd585d36a68..4e00e29029c 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -483,20 +483,17 @@ static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss) {
_edge_free(e, ss);
}
-static float EDGE_getSharpness(CCGEdge *e, int lvl, CCGSubSurf *ss) {
- float sharpness = e->crease;
- while (lvl--) {
- if (sharpness>1.0) {
- sharpness -= 1.0;
- } else {
- sharpness = 0.0;
- }
- }
- return sharpness;
+static float EDGE_getSharpness(CCGEdge *e, int lvl) {
+ if (!lvl)
+ return e->crease;
+ else if (!e->crease)
+ return 0.0;
+ else if (e->crease - lvl < 0.0)
+ return 0.0;
+ else
+ return e->crease - lvl;
}
-/***/
-
static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, int levels, int dataSize, CCGSubSurf *ss) {
int maxGridSize = 1 + (1<<(ss->subdivLevels-1));
CCGFace *f = CCGSUBSURF_alloc(ss, sizeof(CCGFace) + sizeof(CCGVert*)*numVerts + sizeof(CCGEdge*)*numVerts + ss->meshIFC.vertDataSize *(1 + numVerts*maxGridSize + numVerts*maxGridSize*maxGridSize) + ss->meshIFC.faceUserSize);
@@ -1194,7 +1191,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
CCGEdge *e = effectedE[ptrIdx];
void *co = EDGE_getCo(e, nextLvl, 1);
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (_edge_isBoundary(e) || sharpness>=1.0) {
VertDataCopy(co, VERT_getCo(e->v0, curLvl));
@@ -1233,7 +1230,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
for (i=0; i<v->numEdges; i++) {
CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (seam && _edge_isBoundary(e))
seamEdges++;
@@ -1307,7 +1304,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
for (i=0; i<v->numEdges; i++) {
CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (seam) {
if (_edge_isBoundary(e)) {
@@ -1472,7 +1469,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
*/
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (_edge_isBoundary(e) || sharpness>1.0) {
for (x=0; x<edgeSize-1; x++) {
@@ -1531,7 +1528,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
for (i=0; i<v->numEdges; i++) {
CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (seam && _edge_isBoundary(e))
seamEdges++;
@@ -1607,7 +1604,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
for (i=0; i<v->numEdges; i++) {
CCGEdge *e = v->edges[i];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
if (seam) {
if (_edge_isBoundary(e))
@@ -1647,7 +1644,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss) {
*/
for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) {
CCGEdge *e = (CCGEdge*) effectedE[ptrIdx];
- float sharpness = EDGE_getSharpness(e, curLvl, ss);
+ float sharpness = EDGE_getSharpness(e, curLvl);
int sharpCount = 0;
float avgSharpness = 0.0;
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 5f8e9c7b207..c263b4aae8c 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -51,9 +51,11 @@
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h" // N_T
#include "DNA_scene_types.h" // N_T
+#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_particle_types.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -61,20 +63,23 @@
#include "BLI_editVert.h"
#include "BLI_linklist.h"
-#include "BKE_utildefines.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_key.h"
#include "BKE_material.h"
+#include "BKE_modifier.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_subsurf.h"
-#include "BKE_deform.h"
-#include "BKE_modifier.h"
-#include "BKE_key.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_particle.h"
#ifdef WITH_VERSE
#include "BKE_verse.h"
@@ -83,8 +88,6 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "multires.h"
-
// headers for fluidsim bobj meshes
#include <stdlib.h>
#include "LBM_fluidsim.h"
@@ -633,9 +636,10 @@ static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *use
}
static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
{
+ GLubyte act_face_stipple[32*32/8] = DM_FACE_STIPPLE;
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa;
- int i;
+ int i, draw;
if (emdm->vertexCos) {
EditVert *eve;
@@ -645,7 +649,13 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
- if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
+ draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
+ if(draw) {
+ if (draw==2) { /* enabled with stipple */
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(act_face_stipple);
+ }
+
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
@@ -668,12 +678,20 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
glEnd();
+
+ if (draw==2)
+ glDisable(GL_POLYGON_STIPPLE);
}
}
} else {
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
- if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
+ draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
+ if(draw) {
+ if (draw==2) { /* enabled with stipple */
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(act_face_stipple);
+ }
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
@@ -696,11 +714,180 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
glEnd();
+
+ if (draw==2)
+ glDisable(GL_POLYGON_STIPPLE);
+ }
+ }
+ }
+}
+
+static void emDM_drawFacesTex_common(DerivedMesh *dm,
+ int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+ int (*drawParamsMapped)(void *userData, int index),
+ void *userData)
+{
+ EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+ EditMesh *em= emdm->em;
+ float (*vertexCos)[3]= emdm->vertexCos;
+ float (*vertexNos)[3]= emdm->vertexNos;
+ EditFace *efa;
+ int i;
+
+ if (vertexCos) {
+ EditVert *eve;
+
+ for (i=0,eve=em->verts.first; eve; eve= eve->next)
+ eve->tmp.l = (long) i++;
+
+ for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
+ MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ unsigned char *cp= NULL;
+ int drawSmooth= (efa->flag & ME_SMOOTH);
+ int flag;
+
+ if(drawParams)
+ flag= drawParams(tf, mcol, efa->mat_nr);
+ else if(drawParamsMapped)
+ flag= drawParamsMapped(userData, i);
+ else
+ flag= 1;
+
+ if(flag != 0) { /* flag 0 == the face is hidden or invisible */
+ if (flag==1 && mcol)
+ cp= (unsigned char*)mcol;
+
+ glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+ if (!drawSmooth) {
+ glNormal3fv(emdm->faceNos[i]);
+
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+
+ if(efa->v4) {
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+ }
+ } else {
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
+ glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
+ glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
+ glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+
+ if(efa->v4) {
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
+ glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+ }
+ }
+ glEnd();
+ }
+ }
+ } else {
+ for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
+ MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ unsigned char *cp= NULL;
+ int drawSmooth= (efa->flag & ME_SMOOTH);
+ int flag;
+
+ if(drawParams)
+ flag= drawParams(tf, mcol, efa->mat_nr);
+ else if(drawParamsMapped)
+ flag= drawParamsMapped(userData, i);
+ else
+ flag= 1;
+
+ if(flag != 0) { /* flag 0 == the face is hidden or invisible */
+ if (flag==1 && mcol)
+ cp= (unsigned char*)mcol;
+
+ glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
+
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+ if (!drawSmooth) {
+ glNormal3fv(efa->n);
+
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glVertex3fv(efa->v1->co);
+
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glVertex3fv(efa->v2->co);
+
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glVertex3fv(efa->v3->co);
+
+ if(efa->v4) {
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glVertex3fv(efa->v4->co);
+ }
+ } else {
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3fv(efa->v1->no);
+ glVertex3fv(efa->v1->co);
+
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3fv(efa->v2->no);
+ glVertex3fv(efa->v2->co);
+
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3fv(efa->v3->no);
+ glVertex3fv(efa->v3->co);
+
+ if(efa->v4) {
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3fv(efa->v4->no);
+ glVertex3fv(efa->v4->co);
+ }
+ }
+ glEnd();
}
}
}
}
+static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+{
+ emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
+}
+
+static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
+{
+ emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
+}
+
static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
@@ -755,6 +942,7 @@ void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
/* TODO what to do with vert_r->flag and vert_r->mat_nr? */
vert_r->mat_nr = 0;
+ vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
}
void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
@@ -767,6 +955,7 @@ void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
for(i = 0; i < index; ++i) ee = ee->next;
edge_r->crease = (unsigned char) (ee->crease*255.0f);
+ edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
/* TODO what to do with edge_r->flag? */
edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
if (ee->seam) edge_r->flag |= ME_SEAM;
@@ -847,6 +1036,7 @@ void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
/* TODO what to do with vert_r->flag and vert_r->mat_nr? */
vert_r->mat_nr = 0;
vert_r->flag = 0;
+ vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
}
}
@@ -863,6 +1053,7 @@ void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
for( ; ee; ee = ee->next, ++edge_r) {
edge_r->crease = (unsigned char) (ee->crease*255.0f);
+ edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
/* TODO what to do with edge_r->flag? */
edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
if (ee->seam) edge_r->flag |= ME_SEAM;
@@ -946,6 +1137,8 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
+ emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
+ emdm->dm.drawFacesTex = emDM_drawFacesTex;
emdm->dm.drawUVEdges = emDM_drawUVEdges;
emdm->dm.release = emDM_release;
@@ -1129,6 +1322,7 @@ void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
/* not supported yet */
edge_r->flag = 0;
edge_r->crease = 0;
+ edge_r->bweight = 0;
break;
}
}
@@ -1235,6 +1429,7 @@ void vDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
/* not supported yet */
edge_r->flag = 0;
edge_r->crease = 0;
+ edge_r->bweight = 0;
}
}
}
@@ -1614,7 +1809,7 @@ CustomDataMask get_viewedit_datamask()
ScrArea *sa;
/* check if we need tfaces & mcols due to face select or texture paint */
- if(G.f & G_FACESELECT || G.f & G_TEXTUREPAINT) {
+ if(FACESEL_PAINT_TEST || G.f & G_TEXTUREPAINT) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
} else {
/* check if we need tfaces & mcols due to view mode */
@@ -1623,9 +1818,9 @@ CustomDataMask get_viewedit_datamask()
View3D *view = sa->spacedata.first;
if(view->drawtype == OB_SHADED) {
/* this includes normals for mesh_create_shadedColors */
- mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL;
+ mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL | CD_MASK_ORCO;
}
- if(view->drawtype == OB_TEXTURE) {
+ if((view->drawtype == OB_TEXTURE) || ((view->drawtype == OB_SOLID) && (view->flag2 & V3D_SOLID_TEX))) {
mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
}
}
@@ -1639,20 +1834,65 @@ CustomDataMask get_viewedit_datamask()
return mask;
}
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me)
+{
+ DerivedMesh *dm;
+ float (*orco)[3];
+
+ dm= CDDM_from_mesh(me, ob);
+ orco= (float(*)[3])get_mesh_orco_verts(ob);
+ CDDM_apply_vert_coords(dm, orco);
+ CDDM_calc_normals(dm);
+ MEM_freeN(orco);
+
+ return dm;
+}
+
+static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
+{
+ float (*orco)[3], (*layerorco)[3];
+ int totvert;
+
+ totvert= dm->getNumVerts(dm);
+
+ if(orcodm) {
+ orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+
+ if(orcodm->getNumVerts(orcodm) == totvert)
+ orcodm->getVertCos(orcodm, orco);
+ else
+ dm->getVertCos(dm, orco);
+ }
+ else
+ orco= (float(*)[3])get_mesh_orco_verts(ob);
+
+ transform_mesh_orco_verts(ob->data, orco, totvert, 0);
+
+ if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
+ memcpy(layerorco, orco, sizeof(float)*totvert);
+ MEM_freeN(orco);
+ }
+ else
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
+}
+
static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
DerivedMesh **deform_r, DerivedMesh **final_r,
int useRenderParams, int useDeform,
int needMapping, CustomDataMask dataMask)
{
Mesh *me = ob->data;
- ModifierData *md = modifiers_getVirtualModifierList(ob);
+ ModifierData *firstmd, *md;
LinkNode *datamasks, *curr;
+ CustomDataMask mask;
float (*deformedVerts)[3] = NULL;
- DerivedMesh *dm;
+ DerivedMesh *dm, *orcodm, *finaldm;
int numVerts = me->totvert;
int fluidsimMeshUsed = 0;
int required_mode;
+ md = firstmd = modifiers_getVirtualModifierList(ob);
+
modifiers_clearErrors(ob);
/* we always want to keep original indices */
@@ -1729,7 +1969,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
} else {
if(!fluidsimMeshUsed) {
/* default behaviour for meshes */
- deformedVerts = inputVertexCos;
+ if(inputVertexCos)
+ deformedVerts = inputVertexCos;
+ else
+ deformedVerts = mesh_getRefKeyCos(me, &numVerts);
} else {
/* the fluid sim mesh might have more vertices than the original
* one, so inputVertexCos shouldnt be used
@@ -1743,6 +1986,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
* OnlyDeform ones.
*/
dm = NULL;
+ orcodm = NULL;
#ifdef WITH_VERSE
/* hack to make sure modifiers don't try to use mesh data from a verse
@@ -1764,12 +2008,20 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
if(mti->isDisabled && mti->isDisabled(md)) continue;
if(needMapping && !modifier_supportsMapping(md)) continue;
+ /* add an orco layer if needed by this modifier */
+ if(dm && mti->requiredDataMask) {
+ mask = mti->requiredDataMask(md);
+ if(mask & CD_MASK_ORCO)
+ add_orco_dm(ob, dm, orcodm);
+ }
+
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
* deformed vertices) and (b) what type the modifier is.
*/
if(mti->type == eModifierTypeType_OnlyDeform) {
+
/* No existing verts to deform, need to build them. */
if(!deformedVerts) {
if(dm) {
@@ -1809,11 +2061,32 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
}
}
+ /* create an orco derivedmesh in parallel */
+ mask= (CustomDataMask)curr->link;
+ if(mask & CD_MASK_ORCO) {
+ if(!orcodm)
+ orcodm= create_orco_dm(ob, me);
+
+ mask &= ~CD_MASK_ORCO;
+ DM_set_only_copy(orcodm, mask);
+ ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, !inputVertexCos);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(orcodm && orcodm != ndm) orcodm->release(orcodm);
+ orcodm = ndm;
+ }
+ }
+
/* set the DerivedMesh to only copy needed data */
- DM_set_only_copy(dm, (CustomDataMask)curr->link);
+ DM_set_only_copy(dm, mask);
+
+ /* add an origspace layer if needed */
+ if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
+ if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
+ DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
- ndm = mti->applyModifier(md, ob, dm, useRenderParams,
- !inputVertexCos);
+ ndm = mti->applyModifier(md, ob, dm, useRenderParams, !inputVertexCos);
if(ndm) {
/* if the modifier returned a new dm, release the old one */
@@ -1831,39 +2104,55 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
}
}
+ for(md=firstmd; md; md=md->next)
+ modifier_freeTemporaryData(md);
+
/* Yay, we are done. If we have a DerivedMesh and deformed vertices
* need to apply these back onto the DerivedMesh. If we have no
* DerivedMesh then we need to build one.
*/
if(dm && deformedVerts) {
- *final_r = CDDM_copy(dm);
+ finaldm = CDDM_copy(dm);
dm->release(dm);
- CDDM_apply_vert_coords(*final_r, deformedVerts);
- CDDM_calc_normals(*final_r);
+ CDDM_apply_vert_coords(finaldm, deformedVerts);
+ CDDM_calc_normals(finaldm);
} else if(dm) {
- *final_r = dm;
+ finaldm = dm;
} else {
#ifdef WITH_VERSE
if(me->vnode)
- *final_r = derivedmesh_from_versemesh(me->vnode, deformedVerts);
+ finaldm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
else {
- *final_r = CDDM_from_mesh(me, ob);
+ finaldm = CDDM_from_mesh(me, ob);
if(deformedVerts) {
- CDDM_apply_vert_coords(*final_r, deformedVerts);
- CDDM_calc_normals(*final_r);
+ CDDM_apply_vert_coords(finaldm, deformedVerts);
+ CDDM_calc_normals(finaldm);
}
}
#else
- *final_r = CDDM_from_mesh(me, ob);
+ finaldm = CDDM_from_mesh(me, ob);
if(deformedVerts) {
- CDDM_apply_vert_coords(*final_r, deformedVerts);
- CDDM_calc_normals(*final_r);
+ CDDM_apply_vert_coords(finaldm, deformedVerts);
+ CDDM_calc_normals(finaldm);
}
#endif
}
+ /* add an orco layer if needed */
+ if(dataMask & CD_MASK_ORCO) {
+ add_orco_dm(ob, finaldm, orcodm);
+
+ if(deform_r && *deform_r)
+ add_orco_dm(ob, *deform_r, NULL);
+ }
+
+ *final_r = finaldm;
+
+ if(orcodm)
+ orcodm->release(orcodm);
+
if(deformedVerts && deformedVerts != inputVertexCos)
MEM_freeN(deformedVerts);
@@ -1887,6 +2176,24 @@ static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
return cos;
}
+static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
+
+ if((md->mode & required_mode) != required_mode) return 0;
+ if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
+ modifier_setError(md, "Internal error, modifier requires"
+ "original data (bad stack position).");
+ return 0;
+ }
+ if(mti->isDisabled && mti->isDisabled(md)) return 0;
+ if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
+ if(md->mode & eModifierMode_DisableTemporary) return 0;
+
+ return 1;
+}
+
static void editmesh_calc_modifiers(DerivedMesh **cage_r,
DerivedMesh **final_r,
CustomDataMask dataMask)
@@ -1897,7 +2204,6 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
float (*deformedVerts)[3] = NULL;
DerivedMesh *dm;
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
- int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
LinkNode *datamasks, *curr;
modifiers_clearErrors(ob);
@@ -1918,14 +2224,8 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
for(i = 0; md; i++, md = md->next, curr = curr->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- if((md->mode & required_mode) != required_mode) continue;
- if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
- modifier_setError(md, "Internal error, modifier requires"
- "original data (bad stack position).");
+ if(!editmesh_modifier_is_enabled(md, dm))
continue;
- }
- if(mti->isDisabled && mti->isDisabled(md)) continue;
- if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
@@ -1980,6 +2280,10 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r,
/* set the DerivedMesh to only copy needed data */
DM_set_only_copy(dm, (CustomDataMask)curr->link);
+ if(((CustomDataMask)curr->link) & CD_MASK_ORIGSPACE)
+ if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
+ DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+
ndm = mti->applyModifierEM(md, ob, em, dm);
if (ndm) {
@@ -2071,10 +2375,10 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb)
*fb= 0.0f;
}
}
-static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col)
+static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
{
Mesh *me = ob->data;
- float fr, fg, fb, input = 0.0f;
+ float colf[4], input = 0.0f;
int i;
if (me->dvert) {
@@ -2085,29 +2389,41 @@ static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col
CLAMP(input, 0.0f, 1.0f);
- weight_to_rgb(input, &fr, &fg, &fb);
+ if(coba)
+ do_colorband(coba, input, colf);
+ else
+ weight_to_rgb(input, colf, colf+1, colf+2);
- col[3] = (unsigned char)(fr * 255.0f);
- col[2] = (unsigned char)(fg * 255.0f);
- col[1] = (unsigned char)(fb * 255.0f);
+ col[3] = (unsigned char)(colf[0] * 255.0f);
+ col[2] = (unsigned char)(colf[1] * 255.0f);
+ col[1] = (unsigned char)(colf[2] * 255.0f);
col[0] = 255;
}
+
+static ColorBand *stored_cb= NULL;
+
+void vDM_ColorBand_store(ColorBand *coba)
+{
+ stored_cb= coba;
+}
+
static unsigned char *calc_weightpaint_colors(Object *ob)
{
Mesh *me = ob->data;
MFace *mf = me->mface;
+ ColorBand *coba= stored_cb; /* warning, not a local var */
unsigned char *wtcol;
int i;
wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
- for (i=0; i<me->totface; i++, mf++){
- calc_weightpaint_vert_color(ob, mf->v1, &wtcol[(i*4 + 0)*4]);
- calc_weightpaint_vert_color(ob, mf->v2, &wtcol[(i*4 + 1)*4]);
- calc_weightpaint_vert_color(ob, mf->v3, &wtcol[(i*4 + 2)*4]);
+ for (i=0; i<me->totface; i++, mf++) {
+ calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]);
if (mf->v4)
- calc_weightpaint_vert_color(ob, mf->v4, &wtcol[(i*4 + 3)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]);
}
return wtcol;
@@ -2118,6 +2434,10 @@ static void clear_mesh_caches(Object *ob)
Mesh *me= ob->data;
/* also serves as signal to remake texspace */
+ if (ob->bb) {
+ MEM_freeN(ob->bb);
+ ob->bb = NULL;
+ }
if (me->bb) {
MEM_freeN(me->bb);
me->bb = NULL;
@@ -2146,7 +2466,7 @@ static void mesh_build_data(Object *ob, CustomDataMask dataMask)
if(ob!=G.obedit) {
Object *obact = G.scene->basact?G.scene->basact->object:NULL;
- int editing = (G.f & (G_FACESELECT|G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT));
+ int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
int needMapping = editing && (ob==obact);
if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
@@ -2165,7 +2485,7 @@ static void mesh_build_data(Object *ob, CustomDataMask dataMask)
CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
} else {
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
- &ob->derivedFinal, 0, 1,
+ &ob->derivedFinal, G.rendering, 1,
needMapping, dataMask);
}
@@ -2173,7 +2493,9 @@ static void mesh_build_data(Object *ob, CustomDataMask dataMask)
ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
- boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
+ if(!ob->bb)
+ ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
+ boundbox_set_from_min_max(ob->bb, min, max);
ob->derivedFinal->needsFree = 0;
ob->derivedDeform->needsFree = 0;
@@ -2209,7 +2531,9 @@ static void editmesh_build_data(CustomDataMask dataMask)
em->derivedFinal->getMinMax(em->derivedFinal, min, max);
- boundbox_set_from_min_max(mesh_get_bb(G.obedit->data), min, max);
+ if(!G.obedit->bb)
+ G.obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
+ boundbox_set_from_min_max(G.obedit->bb, min, max);
em->derivedFinal->needsFree = 0;
em->derivedCage->needsFree = 0;
@@ -2260,7 +2584,7 @@ float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
{
float *vert_copy= NULL;
- if(me->mr) {
+ if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
MultiresLevel *lvl= NULL;
int i;
@@ -2283,18 +2607,24 @@ float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
}
/* Propagate the changes to render level - fails if mesh topology changed */
-void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy, const int orig_lvl)
+void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy,
+ const int orig_lvl, CustomDataMask dataMask)
{
- if(me->mr) {
+ if(me->mr && !(me->mr->flag & MULTIRES_NO_RENDER)) {
if((*dm)->getNumVerts(*dm) == me->totvert &&
(*dm)->getNumFaces(*dm) == me->totface) {
MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
DerivedMesh *old= NULL;
+ MVert *vertdup= NULL;
int i;
- (*dm)->copyVertArray(*dm, me->mvert);
+ /* Copy the verts into the mesh */
+ vertdup= (*dm)->dupVertArray(*dm);
(*dm)->release(*dm);
+ for(i=0; i<me->totvert; ++i)
+ me->mvert[i]= vertdup[i];
+ /* Go to the render level */
me->mr->newlvl= me->mr->renderlvl;
multires_set_level(ob, me, 1);
(*dm)= getMeshDerivedMesh(me, ob, NULL);
@@ -2304,6 +2634,9 @@ void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_c
(*dm)= CDDM_copy(old);
old->release(old);
+ if(dataMask & CD_MASK_ORCO)
+ add_orco_dm(ob, *dm, NULL);
+
/* Restore the original verts */
me->mr->newlvl= BLI_countlist(&me->mr->levels);
multires_set_level(ob, me, 1);
@@ -2331,7 +2664,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask);
- multires_render_final(ob, me, &final, vert_copy, orig_lvl);
+ multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
return final;
}
@@ -2366,7 +2699,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
vert_copy= multires_render_pin(ob, me, &orig_lvl);
mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask);
- multires_render_final(ob, me, &final, vert_copy, orig_lvl);
+ multires_render_final(ob, me, &final, vert_copy, orig_lvl, dataMask);
return final;
}
@@ -2461,6 +2794,61 @@ float *mesh_get_mapped_verts_nors(Object *ob)
return vertexcosnos;
}
+/* ********* crazyspace *************** */
+
+int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**deformcos)[3])
+{
+ Object *ob = G.obedit;
+ EditMesh *em = G.editMesh;
+ ModifierData *md;
+ DerivedMesh *dm;
+ int i, a, numleft = 0, numVerts = 0;
+ int cageIndex = modifiers_getCageIndex(ob, NULL);
+ float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
+
+ modifiers_clearErrors(ob);
+
+ dm = NULL;
+ md = ob->modifiers.first;
+
+ /* compute the deformation matrices and coordinates for the first
+ modifiers with on cage editing that are enabled and support computing
+ deform matrices */
+ for(i = 0; md && i <= cageIndex; i++, md = md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if(!editmesh_modifier_is_enabled(md, dm))
+ continue;
+
+ if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
+ if(!defmats) {
+ dm= getEditMeshDerivedMesh(em, ob, NULL);
+ deformedVerts= editmesh_getVertexCos(em, &numVerts);
+ defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
+
+ for(a=0; a<numVerts; a++)
+ Mat3One(defmats[a]);
+ }
+
+ mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
+ numVerts);
+ }
+ else
+ break;
+ }
+
+ for(; md && i <= cageIndex; md = md->next, i++)
+ if(editmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md))
+ numleft++;
+
+ if(dm)
+ dm->release(dm);
+
+ *deformmats= defmats;
+ *deformcos= deformedVerts;
+
+ return numleft;
+}
/* ************************* fluidsim bobj file handling **************************** */
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile
index a6b14a72690..488d8801e41 100644
--- a/source/blender/blenkernel/intern/Makefile
+++ b/source/blender/blenkernel/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd openbsd linux solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
# OpenGL and Python
@@ -64,6 +60,8 @@ CPPFLAGS += -I../../include
# to include the render stuff:
CPPFLAGS += -I../../render/extern/include
+# for image stamping
+CPPFLAGS += -I$(NAN_BMFONT)/include
# for sound
#CPPFLAGS += -I../../../kernel/gen_system
CPPFLAGS += $(NAN_SDLCFLAGS)
@@ -71,6 +69,7 @@ CPPFLAGS += $(NAN_SDLCFLAGS)
CPPFLAGS += -I$(NAN_IKSOLVER)/include
CPPFLAGS += -I$(NAN_DECIMATION)/include
CPPFLAGS += -I$(NAN_ELBEEM)/include
+CPPFLAGS += -I$(NAN_OPENNL)/include
# path to zlib
CPPFLAGS += -I$(NAN_ZLIB)/include
@@ -81,6 +80,9 @@ CPPFLAGS += -I../../nodes
# path to our own external headerfiles
CPPFLAGS += -I..
+# path to bullet2, for cloth
+CPPFLAGS += -I../../../../extern/bullet2/src
+
ifeq ($(WITH_FREETYPE2), true)
CPPFLAGS += -DWITH_FREETYPE2
CPPFLAGS += -I$(NAN_FREETYPE)/include
@@ -101,6 +103,10 @@ ifeq ($(WITH_OPENEXR), true)
CPPFLAGS += -DWITH_OPENEXR
endif
+ifeq ($(WITH_DDS), true)
+ CPPFLAGS += -DWITH_DDS
+endif
+
ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -I../../quicktime
CPPFLAGS += -DWITH_QUICKTIME
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index aa9d3d30f98..b8c05f3bb7b 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -112,7 +112,6 @@ static void make_local_action_channels(bAction *act)
}
}
}
-
}
void make_local_action(bAction *act)
@@ -165,37 +164,64 @@ void make_local_action(bAction *act)
}
-void free_action(bAction *act)
+void free_action (bAction *act)
{
bActionChannel *chan;
/* Free channels */
- for (chan=act->chanbase.first; chan; chan=chan->next){
+ for (chan=act->chanbase.first; chan; chan=chan->next) {
if (chan->ipo)
chan->ipo->id.us--;
free_constraint_channels(&chan->constraintChannels);
}
if (act->chanbase.first)
- BLI_freelistN (&act->chanbase);
+ BLI_freelistN(&act->chanbase);
+
+ /* Free groups */
+ if (act->groups.first)
+ BLI_freelistN(&act->groups);
+
+ /* Free pose-references (aka local markers) */
+ if (act->markers.first)
+ BLI_freelistN(&act->markers);
}
-bAction* copy_action(bAction *src)
+bAction *copy_action (bAction *src)
{
bAction *dst = NULL;
bActionChannel *dchan, *schan;
+ bActionGroup *dgrp, *sgrp;
- if(!src) return NULL;
+ if (!src) return NULL;
dst= copy_libblock(src);
+
duplicatelist(&(dst->chanbase), &(src->chanbase));
+ duplicatelist(&(dst->groups), &(src->groups));
+ duplicatelist(&(dst->markers), &(src->markers));
- for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){
+ for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next) {
+ for (dgrp=dst->groups.first, sgrp=src->groups.first; dgrp && sgrp; dgrp=dgrp->next, sgrp=sgrp->next) {
+ if (dchan->grp == sgrp) {
+ dchan->grp= dgrp;
+
+ if (dgrp->channels.first == schan)
+ dgrp->channels.first= dchan;
+ if (dgrp->channels.last == schan)
+ dgrp->channels.last= dchan;
+
+ break;
+ }
+ }
+
dchan->ipo = copy_ipo(dchan->ipo);
copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels);
}
+
dst->id.flag |= LIB_FAKEUSER;
dst->id.us++;
+
return dst;
}
@@ -225,12 +251,12 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
{
bPoseChannel *chan;
- if (!pose){
+ if (!pose) {
return NULL;
}
/* See if this channel exists */
- for (chan=pose->chanbase.first; chan; chan=chan->next){
+ for (chan=pose->chanbase.first; chan; chan=chan->next) {
if (!strcmp (name, chan->name))
return chan;
}
@@ -239,7 +265,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
strncpy (chan->name, name, 31);
- /* init vars to prevent mat errors */
+ /* init vars to prevent math errors */
chan->quat[0] = 1.0F;
chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
@@ -247,6 +273,8 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
chan->limitmax[0]= chan->limitmax[1]= chan->limitmax[2]= 180.0f;
chan->stiffness[0]= chan->stiffness[1]= chan->stiffness[2]= 0.0f;
+ Mat4One(chan->constinv);
+
BLI_addtail (&pose->chanbase, chan);
return chan;
@@ -284,7 +312,7 @@ void free_pose_channels(bPose *pose)
{
bPoseChannel *pchan;
- if (pose->chanbase.first){
+ if (pose->chanbase.first) {
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next){
if(pchan->path)
MEM_freeN(pchan->path);
@@ -294,6 +322,21 @@ void free_pose_channels(bPose *pose)
}
}
+void free_pose(bPose *pose)
+{
+ if (pose) {
+ /* free pose-channels */
+ free_pose_channels(pose);
+
+ /* free pose-groups */
+ if (pose->agroups.first)
+ BLI_freelistN(&pose->agroups);
+
+ /* free pose */
+ MEM_freeN(pose);
+ }
+}
+
static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan)
{
bConstraint *pcon, *con;
@@ -304,8 +347,10 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
pchan->flag= chan->flag;
con= chan->constraints.first;
- for(pcon= pchan->constraints.first; pcon; pcon= pcon->next)
+ for(pcon= pchan->constraints.first; pcon; pcon= pcon->next) {
pcon->enforce= con->enforce;
+ pcon->headtail= con->headtail;
+ }
}
/* checks for IK constraint, can do more constraints flags later */
@@ -350,6 +395,28 @@ void update_pose_constraint_flags(bPose *pose)
}
}
+/* Clears all BONE_UNKEYED flags for every pose channel in every pose
+ * This should only be called on frame changing, when it is acceptable to
+ * do this. Otherwise, these flags should not get cleared as poses may get lost.
+ */
+void framechange_poses_clear_unkeyed(void)
+{
+ Object *ob;
+ bPose *pose;
+ bPoseChannel *pchan;
+
+ /* This needs to be done for each object that has a pose */
+ // TODO: proxies may/may not be correctly handled here... (this needs checking)
+ for (ob= G.main->object.first; ob; ob= ob->id.next) {
+ /* we only need to do this on objects with a pose */
+ if ( (pose= ob->pose) ) {
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_UNKEYED;
+ }
+ }
+ }
+}
/* ************************ END Pose channels *************** */
@@ -363,7 +430,7 @@ bActionChannel *get_action_channel(bAction *act, const char *name)
if (!act || !name)
return NULL;
- for (chan = act->chanbase.first; chan; chan=chan->next){
+ for (chan = act->chanbase.first; chan; chan=chan->next) {
if (!strcmp (chan->name, name))
return chan;
}
@@ -371,18 +438,16 @@ bActionChannel *get_action_channel(bAction *act, const char *name)
return NULL;
}
-/* returns existing channel, or adds new one. In latter case it doesnt activate it, context is required for that*/
+/* returns existing channel, or adds new one. In latter case it doesnt activate it, context is required for that */
bActionChannel *verify_action_channel(bAction *act, const char *name)
{
bActionChannel *chan;
chan= get_action_channel(act, name);
- if(chan==NULL) {
- if (!chan) {
- chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
- strncpy (chan->name, name, 31);
- BLI_addtail (&act->chanbase, chan);
- }
+ if (chan == NULL) {
+ chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
+ strncpy(chan->name, name, 31);
+ BLI_addtail(&act->chanbase, chan);
}
return chan;
}
@@ -408,21 +473,19 @@ static bActionStrip *get_active_strip(Object *ob)
/* non clipped mapping of strip */
static float get_actionstrip_frame(bActionStrip *strip, float cframe, int invert)
{
- float length, actlength, repeat;
+ float length, actlength, repeat, scale;
- if (strip->flag & ACTSTRIP_USESTRIDE)
- repeat= 1.0f;
- else
- repeat= strip->repeat;
-
- length = strip->end-strip->start;
- if(length==0.0f)
- length= 1.0f;
- actlength = strip->actend-strip->actstart;
+ repeat = (strip->flag & ACTSTRIP_USESTRIDE) ? (1.0f) : (strip->repeat);
+ if(strip->scale == 0.0f) strip->scale= 1.0f;
+ scale = abs(strip->scale); /* scale must be positive (for now) */
+ actlength = strip->actend-strip->actstart;
+ if (actlength == 0.0f) actlength = 1.0f;
+ length = repeat * scale * actlength;
- if(invert)
+ /* invert = convert action-strip time to global time */
+ if (invert)
return length*(cframe - strip->actstart)/(repeat*actlength) + strip->start;
else
return repeat*actlength*(cframe - strip->start)/length + strip->actstart;
@@ -456,10 +519,10 @@ static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mo
float dstweight;
switch (mode){
- case POSE_BLEND:
+ case ACTSTRIPMODE_BLEND:
dstweight = 1.0F - srcweight;
break;
- case POSE_ADD:
+ case ACTSTRIPMODE_ADD:
dstweight = 1.0F;
break;
default :
@@ -561,10 +624,10 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
int i;
switch (mode){
- case POSE_BLEND:
+ case ACTSTRIPMODE_BLEND:
dstweight = 1.0F - srcweight;
break;
- case POSE_ADD:
+ case ACTSTRIPMODE_ADD:
dstweight = 1.0F;
break;
default :
@@ -580,10 +643,12 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
if (schan->flag & POSE_ROT) {
QUATCOPY(dquat, dchan->quat);
QUATCOPY(squat, schan->quat);
- if(mode==POSE_BLEND)
+ if(mode==ACTSTRIPMODE_BLEND)
QuatInterpol(dchan->quat, dquat, squat, srcweight);
- else
- QuatAdd(dchan->quat, dquat, squat, srcweight);
+ else {
+ QuatMulFac(squat, srcweight);
+ QuatMul(dchan->quat, dquat, squat);
+ }
NormalQuat (dchan->quat);
}
@@ -679,9 +744,15 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
/* Copy the data from the action into the pose */
for (pchan= pose->chanbase.first; pchan; pchan=pchan->next) {
+ /* skip this pose channel if it has been tagged as having unkeyed poses */
+ if ((pchan->bone) && (pchan->bone->flag & BONE_UNKEYED))
+ continue;
+
+ /* get action channel and clear pchan-transform flags */
achan= get_action_channel(act, pchan->name);
pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
- if(achan) {
+
+ if (achan) {
ipo = achan->ipo;
if (ipo) {
/* Evaluates and sets the internal ipo value */
@@ -689,7 +760,8 @@ void extract_pose_from_action(bPose *pose, bAction *act, float ctime)
/* This call also sets the pchan flags */
execute_action_ipo(achan, pchan);
}
- do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime);
+ /* 0 = do all ipos, not only drivers */
+ do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime, 0);
}
}
@@ -789,7 +861,7 @@ static void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act,
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");
@@ -823,10 +895,10 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int
float dstweight;
switch (mode){
- case POSE_BLEND:
+ case ACTSTRIPMODE_BLEND:
dstweight = 1.0F - srcweight;
break;
- case POSE_ADD:
+ case ACTSTRIPMODE_ADD:
dstweight = 1.0F;
break;
default :
@@ -1031,6 +1103,46 @@ static Object *get_parent_path(Object *ob)
/* ************** do the action ************ */
+/* For the calculation of the effects of an action at the given frame on an object
+ * This is currently only used for the action constraint
+ */
+void what_does_obaction (Object *ob, bAction *act, float cframe)
+{
+ ListBase tchanbase= {NULL, NULL};
+
+ clear_workob();
+ Mat4CpyMat4(workob.obmat, ob->obmat);
+ Mat4CpyMat4(workob.parentinv, ob->parentinv);
+ Mat4CpyMat4(workob.constinv, ob->constinv);
+ workob.parent= ob->parent;
+ workob.track= ob->track;
+
+ workob.trackflag= ob->trackflag;
+ workob.upflag= ob->upflag;
+
+ workob.partype= ob->partype;
+ workob.par1= ob->par1;
+ workob.par2= ob->par2;
+ workob.par3= ob->par3;
+
+ workob.constraints.first = ob->constraints.first;
+ workob.constraints.last = ob->constraints.last;
+
+ strcpy(workob.parsubstr, ob->parsubstr);
+
+ /* extract_ipochannels_from_action needs id's! */
+ workob.action= act;
+
+ extract_ipochannels_from_action(&tchanbase, &ob->id, act, "Object", bsystem_time(&workob, cframe, 0.0));
+
+ if (tchanbase.first) {
+ execute_ipochannels(&tchanbase);
+ BLI_freelistN(&tchanbase);
+ }
+}
+
+/* ----- nla, etc. --------- */
+
static void do_nla(Object *ob, int blocktype)
{
bPose *tpose= NULL;
@@ -1039,7 +1151,7 @@ static void do_nla(Object *ob, int blocktype)
bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
float striptime, frametime, length, actlength;
float blendfac, stripframe;
- float scene_cfra= G.scene->r.cfra;
+ float scene_cfra= frame_to_float(G.scene->r.cfra);
int doit, dostride;
if(blocktype==ID_AR) {
@@ -1069,10 +1181,10 @@ static void do_nla(Object *ob, int blocktype)
}
}
if(strip==NULL) { /* extend */
- if(stripfirst)
- scene_cfra= stripfirst->start;
- else if(striplast)
+ if(striplast)
scene_cfra= striplast->end;
+ else if(stripfirst)
+ scene_cfra= stripfirst->start;
}
/* and now go over all strips */
@@ -1109,7 +1221,7 @@ static void do_nla(Object *ob, int blocktype)
if(cu->path) {
/* Find the position on the path */
- ctime= bsystem_time(ob, parent, scene_cfra, 0.0);
+ ctime= bsystem_time(ob, scene_cfra, 0.0);
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
/* correct for actions not starting on zero */
@@ -1131,7 +1243,7 @@ static void do_nla(Object *ob, int blocktype)
}
frametime = (striptime * actlength) + strip->actstart;
- frametime= bsystem_time(ob, 0, frametime, 0.0);
+ frametime= bsystem_time(ob, frametime, 0.0);
if(blocktype==ID_AR) {
extract_pose_from_action (tpose, strip->act, frametime);
@@ -1182,7 +1294,7 @@ static void do_nla(Object *ob, int blocktype)
frametime = actlength * (strip->repeat-(int)strip->repeat);
if(frametime<=0.000001f) frametime= actlength; /* rounding errors... */
- frametime= bsystem_time(ob, 0, frametime+strip->actstart, 0.0);
+ frametime= bsystem_time(ob, frametime+strip->actstart, 0.0);
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, frametime);
@@ -1241,22 +1353,19 @@ static void do_nla(Object *ob, int blocktype)
}
/* free */
- if (tpose){
- free_pose_channels(tpose);
- MEM_freeN(tpose);
- }
+ if (tpose)
+ free_pose(tpose);
if(chanbase.first)
BLI_freelistN(&chanbase);
}
void do_all_pose_actions(Object *ob)
{
-
- // only to have safe calls from editor
+ /* only to have safe calls from editor */
if(ob==NULL) return;
if(ob->type!=OB_ARMATURE || ob->pose==NULL) return;
- if(ob->pose->flag & POSE_LOCKED) { // no actions to execute while transform
+ if(ob->pose->flag & POSE_LOCKED) { /* no actions to execute while transform */
if(ob->pose->flag & POSE_DO_UNLOCK)
ob->pose->flag &= ~(POSE_LOCKED|POSE_DO_UNLOCK);
}
@@ -1265,11 +1374,14 @@ void do_all_pose_actions(Object *ob)
cframe= get_action_frame(ob, cframe);
- extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, cframe, 0.0));
+ extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, cframe, 0.0));
}
else if(ob->nlastrips.first) {
do_nla(ob, ID_AR);
}
+
+ /* clear POSE_DO_UNLOCK flags that might have slipped through (just in case) */
+ ob->pose->flag &= ~POSE_DO_UNLOCK;
}
/* called from where_is_object */
@@ -1286,9 +1398,9 @@ void do_all_object_actions(Object *ob)
cframe= get_action_frame(ob, cframe);
- extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, 0, cframe, 0.0));
+ extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, cframe, 0.0));
if(key)
- extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(ob, 0, cframe, 0.0));
+ extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(ob, cframe, 0.0));
if(tchanbase.first) {
execute_ipochannels(&tchanbase);
@@ -1299,5 +1411,3 @@ void do_all_object_actions(Object *ob)
do_nla(ob, ID_OB);
}
}
-
-
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 0019308a569..764b8aee032 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -38,6 +38,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_rand.h"
#include "DNA_listBase.h"
#include "DNA_curve_types.h"
@@ -46,7 +47,9 @@
#include "DNA_key_types.h"
#include "DNA_mesh_types.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_view3d_types.h"
#include "DNA_vfont_types.h"
@@ -60,8 +63,11 @@
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
+#include "BKE_lattice.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
#include "BKE_bad_level_calls.h"
@@ -70,6 +76,8 @@
#include <config.h>
#endif
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
+
void free_path(Path *path)
{
if(path->data) MEM_freeN(path->data);
@@ -101,7 +109,7 @@ void calc_curvepath(Object *ob)
cu->path= NULL;
bl= cu->bev.first;
- if(bl==NULL) return;
+ if(bl==NULL || !bl->nr) return;
cu->path=path= MEM_callocN(sizeof(Path), "path");
@@ -223,6 +231,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
/* test for cyclic */
bl= cu->bev.first;
+ if (!bl->nr) return 0;
if(bl && bl->poly> -1) cycl= 1;
ctime *= (path->len-1);
@@ -275,7 +284,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
/* ****************** DUPLICATOR ************** */
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index)
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated)
{
DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject");
@@ -285,20 +294,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
Mat4CpyMat4(dob->omat, ob->obmat);
dob->origlay= ob->lay;
dob->index= index;
+ dob->type= type;
+ dob->animated= (type == OB_DUPLIGROUP) && animated;
ob->lay= lay;
- /* allowing duplicators for particle systems... a bit silly still */
- {
- PartEff *paf= give_parteff(ob);
- if(paf) {
- Mat4Invert(ob->imat, ob->obmat);
- Mat4CpyMat4(paf->imat, ob->imat);
- }
- }
return dob;
}
-static void group_duplilist(ListBase *lb, Object *ob, int level)
+static void group_duplilist(ListBase *lb, Object *ob, int level, int animated)
{
DupliObject *dob;
Group *group;
@@ -309,34 +312,39 @@ static void group_duplilist(ListBase *lb, Object *ob, int level)
group= ob->dup_group;
/* simple preventing of too deep nested groups */
- if(level>4) return;
+ if(level>MAX_DUPLI_RECUR) return;
/* handles animated groups, and */
/* we need to check update for objects that are not in scene... */
group_handle_recalc_and_update(ob, group);
+ animated= animated || group_is_animated(ob, group);
for(go= group->gobject.first; go; go= go->next) {
/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
if(go->ob!=ob) {
+
Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
- dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0);
+ dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);
dob->no_draw= (dob->origlay & group->layer)==0;
- if(go->ob->dup_group && (go->ob->transflag & OB_DUPLIGROUP)) {
+ if(go->ob->transflag & OB_DUPLI) {
Mat4CpyMat4(dob->ob->obmat, dob->mat);
- group_duplilist(lb, go->ob, level+1);
+ object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1, animated);
Mat4CpyMat4(dob->ob->obmat, dob->omat);
}
}
}
}
-static void frames_duplilist(ListBase *lb, Object *ob)
+static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
{
extern int enable_cu_speed; /* object.c */
Object copyob;
int cfrao, ok;
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+
cfrao= G.scene->r.cfra;
if(ob->parent==NULL && ob->track==NULL && ob->ipo==NULL && ob->constraints.first==NULL) return;
@@ -355,7 +363,7 @@ static void frames_duplilist(ListBase *lb, Object *ob)
if(ok) {
do_ob_ipo(ob);
where_is_object_time(ob, (float)G.scene->r.cfra);
- new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra);
+ new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
}
}
@@ -365,66 +373,130 @@ static void frames_duplilist(ListBase *lb, Object *ob)
}
struct vertexDupliData {
+ ID *id; /* scene or group, for recursive loops */
+ int level;
+ int animated;
ListBase *lb;
float pmat[4][4];
+ float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
Object *ob, *par;
+ float (*orco)[3];
};
static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
+ DupliObject *dob;
struct vertexDupliData *vdd= userData;
- float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4];
+ float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
VECCOPY(vec, co);
Mat4MulVecfl(vdd->pmat, vec);
VecSubf(vec, vec, vdd->pmat[3]);
- VecAddf(vec, vec, vdd->ob->obmat[3]);
+ VecAddf(vec, vec, vdd->obmat[3]);
- Mat4CpyMat4(obmat, vdd->ob->obmat);
+ Mat4CpyMat4(obmat, vdd->obmat);
VECCOPY(obmat[3], vec);
if(vdd->par->transflag & OB_DUPLIROT) {
+ if(no_f) {
+ vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2];
+ }
+ else if(no_s) {
+ vec[0]= -no_s[0]; vec[1]= -no_s[1]; vec[2]= -no_s[2];
+ }
- vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2];
-
- q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag);
+ vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag, q2);
QuatToMat3(q2, mat);
Mat4CpyMat4(tmat, obmat);
Mat4MulMat43(obmat, tmat, mat);
}
- new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index);
+ dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated);
+ if(vdd->orco)
+ VECCOPY(dob->orco, vdd->orco[index]);
+
+ if(vdd->ob->transflag & OB_DUPLI) {
+ float tmpmat[4][4];
+ Mat4CpyMat4(tmpmat, vdd->ob->obmat);
+ Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
+ object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated);
+ Mat4CpyMat4(vdd->ob->obmat, tmpmat);
+ }
}
-static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
+static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
{
- Object *ob;
- Base *base;
+ Object *ob, *ob_iter;
+ Mesh *me;
+ Base *base = NULL;
float vec[3], no[3], pmat[4][4];
- int lay, totvert, a;
+ int lay, totvert, a, oblay;
DerivedMesh *dm;
+ struct vertexDupliData vdd;
+ Scene *sce = NULL;
+ Group *group = NULL;
+ GroupObject * go = NULL;
Mat4CpyMat4(pmat, par->obmat);
- lay= G.scene->lay;
-
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+
if(par==G.obedit)
dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
else
- dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH);
+ dm= mesh_get_derived_deform(par, CD_MASK_BAREMESH);
+
+ if(G.rendering) {
+ me= par->data;
+ vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
+ transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
+ }
+ else
+ vdd.orco= NULL;
totvert = dm->getNumVerts(dm);
- base= sce->base.first;
- while(base) {
-
- if(base->object->type>0 && (lay & base->lay) && G.obedit!=base->object) {
- ob= base->object->parent;
+ /* having to loop on scene OR group objects is NOT FUN */
+ if (GS(id->name) == ID_SCE) {
+ sce = (Scene *)id;
+ lay= sce->lay;
+ base= sce->base.first;
+ } else {
+ group = (Group *)id;
+ lay= group->layer;
+ go = group->gobject.first;
+ }
+
+ /* Start looping on Scene OR Group objects */
+ while (base || go) {
+ if (sce) {
+ ob_iter= base->object;
+ oblay = base->lay;
+ } else {
+ ob_iter= go->ob;
+ oblay = ob_iter->lay;
+ }
+
+ if (lay & oblay && G.obedit!=ob_iter) {
+ ob=ob_iter->parent;
while(ob) {
if(ob==par) {
- struct vertexDupliData vdd;
+ ob = ob_iter;
+ /* End Scene/Group object loop, below is generic */
+
- ob= base->object;
+ /* par_space_mat - only used for groups so we can modify the space dupli's are in
+ when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
+ */
+ if(par_space_mat)
+ Mat4MulMat4(vdd.obmat, ob->obmat, par_space_mat);
+ else
+ Mat4CpyMat4(vdd.obmat, ob->obmat);
+
+ vdd.id= id;
+ vdd.level= level;
+ vdd.animated= animated;
vdd.lb= lb;
vdd.ob= ob;
vdd.par= par;
@@ -450,26 +522,37 @@ static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
ob= ob->parent;
}
}
- base= base->next;
+ if (sce) base= base->next; /* scene loop */
+ else go= go->next; /* group loop */
}
+ if(vdd.orco)
+ MEM_freeN(vdd.orco);
dm->release(dm);
}
-static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
+static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated)
{
- Object *ob;
- Base *base;
+ Object *ob, *ob_iter;
+ Base *base = NULL;
+ DupliObject *dob;
DerivedMesh *dm;
+ Mesh *me;
+ MTFace *mtface;
MFace *mface;
MVert *mvert;
- float pmat[4][4], imat[3][3];
- int lay, totface, a;
-
- Mat4CpyMat4(pmat, par->obmat);
+ float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
+ int lay, oblay, totface, a;
+ Scene *sce = NULL;
+ Group *group = NULL;
+ GroupObject *go = NULL;
+ float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
- lay= G.scene->lay;
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+ Mat4CpyMat4(pmat, par->obmat);
+
if(par==G.obedit) {
int totvert;
dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
@@ -488,26 +571,69 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
mface= dm->getFaceArray(dm);
mvert= dm->getVertArray(dm);
}
+
+ if(G.rendering) {
+ me= (Mesh*)par->data;
+
+ orco= (float(*)[3])get_mesh_orco_verts(par);
+ transform_mesh_orco_verts(me, orco, me->totvert, 0);
+ mtface= me->mtface;
+ }
+ else {
+ orco= NULL;
+ mtface= NULL;
+ }
+ /* having to loop on scene OR group objects is NOT FUN */
+ if (GS(id->name) == ID_SCE) {
+ sce = (Scene *)id;
+ lay= sce->lay;
+ base= sce->base.first;
+ } else {
+ group = (Group *)id;
+ lay= group->layer;
+ go = group->gobject.first;
+ }
- for(base= sce->base.first; base; base= base->next) {
+ /* Start looping on Scene OR Group objects */
+ while (base || go) {
+ if (sce) {
+ ob_iter= base->object;
+ oblay = base->lay;
+ } else {
+ ob_iter= go->ob;
+ oblay = ob_iter->lay;
+ }
- if(base->object->type>0 && (lay & base->lay) && G.obedit!=base->object) {
- ob= base->object->parent;
+ if (lay & oblay && G.obedit!=ob_iter) {
+ ob=ob_iter->parent;
while(ob) {
if(ob==par) {
+ ob = ob_iter;
+ /* End Scene/Group object loop, below is generic */
- ob= base->object;
- Mat3CpyMat4(imat, ob->parentinv);
+ /* par_space_mat - only used for groups so we can modify the space dupli's are in
+ when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
+ */
+ if(par_space_mat)
+ Mat4MulMat4(ob__obmat, ob->obmat, par_space_mat);
+ else
+ Mat4CpyMat4(ob__obmat, ob->obmat);
+ Mat3CpyMat4(imat, ob->parentinv);
+
/* mballs have a different dupli handling */
if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */
for(a=0; a<totface; a++) {
- float *v1= mvert[ mface[a].v1 ].co;
- float *v2= mvert[ mface[a].v2 ].co;
- float *v3= mvert[ mface[a].v3 ].co;
- float *v4= mface[a].v4?mvert[ mface[a].v4 ].co:NULL;
+ int mv1 = mface[a].v1;
+ int mv2 = mface[a].v2;
+ int mv3 = mface[a].v3;
+ int mv4 = mface[a].v4;
+ float *v1= mvert[mv1].co;
+ float *v2= mvert[mv2].co;
+ float *v3= mvert[mv3].co;
+ float *v4= (mv4)? mvert[mv4].co: NULL;
float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
/* translation */
@@ -518,9 +644,10 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
Mat4MulVecfl(pmat, cent);
VecSubf(cent, cent, pmat[3]);
- VecAddf(cent, cent, ob->obmat[3]);
+ VecAddf(cent, cent, ob__obmat[3]);
+
+ Mat4CpyMat4(obmat, ob__obmat);
- Mat4CpyMat4(obmat, ob->obmat);
VECCOPY(obmat[3], cent);
/* rotation */
@@ -530,7 +657,7 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
/* scale */
if(par->transflag & OB_DUPLIFACES_SCALE) {
float size= v4?AreaQ3Dfl(v1, v2, v3, v4):AreaT3Dfl(v1, v2, v3);
- size= sqrt(size);
+ size= sqrt(size) * par->dupfacesca;
Mat3MulFloat(mat[0], size);
}
@@ -540,8 +667,40 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
Mat4CpyMat4(tmat, obmat);
Mat4MulMat43(obmat, tmat, mat);
- new_dupli_object(lb, ob, obmat, lay, a);
+ dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated);
+ if(G.rendering) {
+ w= (mv4)? 0.25f: 1.0f/3.0f;
+ if(orco) {
+ VECADDFAC(dob->orco, dob->orco, orco[mv1], w);
+ VECADDFAC(dob->orco, dob->orco, orco[mv2], w);
+ VECADDFAC(dob->orco, dob->orco, orco[mv3], w);
+ if(mv4)
+ VECADDFAC(dob->orco, dob->orco, orco[mv4], w);
+ }
+
+ if(mtface) {
+ dob->uv[0] += w*mtface[a].uv[0][0];
+ dob->uv[1] += w*mtface[a].uv[0][1];
+ dob->uv[0] += w*mtface[a].uv[1][0];
+ dob->uv[1] += w*mtface[a].uv[1][1];
+ dob->uv[0] += w*mtface[a].uv[2][0];
+ dob->uv[1] += w*mtface[a].uv[2][1];
+
+ if(mv4) {
+ dob->uv[0] += w*mtface[a].uv[3][0];
+ dob->uv[1] += w*mtface[a].uv[3][1];
+ }
+ }
+ }
+
+ if(ob->transflag & OB_DUPLI) {
+ float tmpmat[4][4];
+ Mat4CpyMat4(tmpmat, ob->obmat);
+ Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */
+ object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1, animated);
+ Mat4CpyMat4(ob->obmat, tmpmat);
+ }
}
break;
@@ -549,144 +708,220 @@ static void face_duplilist(ListBase *lb, Scene *sce, Object *par)
ob= ob->parent;
}
}
+ if (sce) base= base->next; /* scene loop */
+ else go= go->next; /* group loop */
}
if(par==G.obedit) {
MEM_freeN(mface);
MEM_freeN(mvert);
}
+
+ if(orco)
+ MEM_freeN(orco);
dm->release(dm);
}
-
-
-static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf)
+static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
{
- Object *ob, copyob;
- Base *base;
- Particle *pa;
- float ctime, vec1[3];
- float vec[3], tmat[4][4], mat[3][3];
- float *q2;
- int lay, a, counter; /* counter is used to find in render the indexed object */
-
- pa= paf->keys;
- if(pa==NULL || (G.rendering && paf->disp!=100)) {
- build_particle_system(par);
- pa= paf->keys;
- if(pa==NULL) return;
- }
+ GroupObject *go;
+ Object *ob=0, **oblist=0;
+ DupliObject *dob;
+ 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], obrotmat[4][4], pamat[4][4], size=0.0;
+ float obmat[4][4], (*obmatlist)[4][4]=0;
+ float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
+ int lay, a, b, k, step_nbr = 0, counter, hair = 0;
+ int totpart, totchild, totgroup=0, pa_num;
+
+ if(psys==0) return;
- ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0);
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+ part=psys->part;
+ psmd= psys_get_modifier(par, psys);
+
+ if(part==0)
+ return;
+
+ if(!psys_check_enabled(par, psys))
+ return;
+
+ ctime = bsystem_time(par, (float)G.scene->r.cfra, 0.0);
+
+ totpart = psys->totpart;
+ totchild = psys->totchild;
+
+ BLI_srandom(31415926 + psys->seed);
+
lay= G.scene->lay;
+ if((part->draw_as == PART_DRAW_OB && part->dup_ob) ||
+ (part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) {
- for(base= sce->base.first; base; base= base->next) {
- if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) {
- ob= base->object->parent;
- while(ob) {
- if(ob==par) {
-
- ob= base->object;
- /* temp copy, to have ipos etc to work OK */
- copyob= *ob;
-
- /* don't want parent animation to apply on past object positions */
- if(!(paf->flag & PAF_STATIC))
- ob->parent= NULL;
-
- for(a=0, pa= paf->keys, counter=0; a<paf->totpart; a++, pa+=paf->totkey, counter++) {
-
- if(paf->flag & PAF_STATIC) {
- float mtime;
-
- where_is_particle(paf, pa, pa->time, vec1);
- mtime= pa->time+pa->lifetime;
-
- for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep, counter++) {
-
- /* make sure hair grows until the end.. */
- if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
-
- /* to give ipos in object correct offset */
- where_is_object_time(ob, ctime-pa->time);
-
- where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec
- Mat4MulVecfl(par->obmat, vec);
-
- if(paf->stype==PAF_VECT) {
- where_is_particle(paf, pa, ctime+1.0, vec1); // makes sure there's always a vec
- Mat4MulVecfl(par->obmat, vec1);
-
- VecSubf(vec1, vec1, vec);
- q2= vectoquat(vec1, ob->trackflag, ob->upflag);
-
- QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, ob->obmat);
- Mat4MulMat43(ob->obmat, tmat, mat);
- }
-
- VECCOPY(ob->obmat[3], vec);
- /* put object back in original state, so it cam be restored OK */
- Mat4CpyMat4(tmat, ob->obmat);
- Mat4CpyMat4(ob->obmat, copyob.obmat);
- new_dupli_object(lb, ob, tmat, par->lay, counter);
- }
- }
- else { // non static particles
-
- if((paf->flag & PAF_UNBORN)==0 && ctime < pa->time) continue;
- if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue;
+ if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && part->draw & PART_DRAW_KEYS)
+ step_nbr = part->keys_step;
+ else
+ step_nbr = 0;
- //if(ctime < pa->time+pa->lifetime) {
+ /* if we have a hair particle system, use the path cache */
+ if(part->type == PART_HAIR) {
+ if(psys->flag & PSYS_HAIR_DONE)
+ hair= (totchild == 0 || psys->childcache) && psys->pathcache;
+ if(!hair)
+ return;
+ }
- /* to give ipos in object correct offset, ob->parent is NULLed */
- where_is_object_time(ob, ctime-pa->time);
-
- where_is_particle(paf, pa, ctime, vec);
- if(paf->stype==PAF_VECT) {
-
- /* if particle died, we use previous position */
- if(ctime > pa->time+pa->lifetime) {
- where_is_particle(paf, pa, pa->time+pa->lifetime-1.0f, vec1);
- VecSubf(vec1, vec, vec1);
- }
- else {
- where_is_particle(paf, pa, ctime+1.0f, vec1);
- VecSubf(vec1, vec1, vec);
- }
- q2= vectoquat(vec1, ob->trackflag, ob->upflag);
-
- QuatToMat3(q2, mat);
- Mat4CpyMat4(tmat, ob->obmat);
- Mat4MulMat43(ob->obmat, tmat, mat);
- }
+ psys->lattice = psys_get_lattice(par, psys);
- VECCOPY(ob->obmat[3], vec);
-
- /* put object back in original state, so it can be restored OK */
- Mat4CpyMat4(tmat, ob->obmat);
- Mat4CpyMat4(ob->obmat, copyob.obmat);
- new_dupli_object(lb, ob, tmat, par->lay, counter);
- }
+ if(part->draw_as==PART_DRAW_GR) {
+ group_handle_recalc_and_update(par, part->dup_group);
+
+ go= part->dup_group->gobject.first;
+ while(go) {
+ go=go->next;
+ totgroup++;
+ }
+
+ oblist= MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
+ obmatlist= MEM_callocN(totgroup*sizeof(float)*4*4, "dupgroup obmat list");
+ go= part->dup_group->gobject.first;
+ for(a=0; a<totgroup; a++, go=go->next) {
+ oblist[a]=go->ob;
+ Mat4CpyMat4(obmatlist[a], go->ob->obmat);
+ }
+ }
+ else {
+ ob = part->dup_ob;
+ Mat4CpyMat4(obmat, ob->obmat);
+ }
+
+ if(totchild==0 || part->draw & PART_DRAW_PARENT)
+ a=0;
+ else
+ a=totpart;
+
+ for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) {
+ if(a<totpart) {
+ if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP))
+ continue;
+
+ pa_num=pa->num;
+
+ pa_time=pa->time;
+
+ size=pa->size;
+ }
+ else {
+ /* TODO: figure these two out */
+ cpa= &psys->child[a - totpart];
+ pa_num = a;
+ pa_time = psys->particles[cpa->parent].time;
+
+ size=psys_get_child_size(psys, cpa, ctime, 0);
+ }
+
+ if(part->draw_as==PART_DRAW_GR) {
+ if(part->draw&PART_DRAW_RAND_GR)
+ b= BLI_rand() % totgroup;
+ else if(part->from==PART_FROM_PARTICLE)
+ b= pa_num % totgroup;
+ else
+ b= a % totgroup;
+
+ ob = oblist[b];
+ Mat4CpyMat4(obmat, obmatlist[b]);
+ }
+
+ for(k=0; k<=step_nbr; k++, counter++) {
+ if(hair) {
+ if(a < totpart) {
+ cache = psys->pathcache[a];
+ psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
+ }
+ else {
+ cache = psys->childcache[a-totpart];
+ psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
}
- /* temp copy, to have ipos etc to work OK */
- *ob= copyob;
+
+ VECCOPY(pamat[3], cache->co);
+ }
+ else if(step_nbr) {
+ state.time = (float)k / (float)step_nbr;
+ psys_get_particle_on_path(par, psys, a, &state, 0);
+
+ QuatToMat4(state.rot, pamat);
+ VECCOPY(pamat[3], state.co);
+ pamat[3][3]= 1.0f;
+ }
+ else {
+ state.time = -1.0;
+ if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
+ continue;
+
+ QuatToMat4(state.rot, pamat);
+ VECCOPY(pamat[3], state.co);
+ pamat[3][3]= 1.0f;
+ }
+
+ if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
+ for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
+
+ Mat4MulMat4(tmat, obmatlist[b], pamat);
+ Mat4MulFloat3((float *)tmat, size*scale);
+ if(par_space_mat)
+ Mat4MulMat4(mat, tmat, par_space_mat);
+ else
+ Mat4CpyMat4(mat, tmat);
+
+ dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+ if(G.rendering)
+ psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
+ }
+ }
+ else {
+ /* to give ipos in object correct offset */
+ where_is_object_time(ob, ctime-pa_time);
- break;
+ if(!hair) {
+ vectoquat(xvec, ob->trackflag, ob->upflag, q);
+ QuatToMat4(q, obrotmat);
+ obrotmat[3][3]= 1.0f;
+ Mat4MulMat4(mat, obrotmat, pamat);
+ }
+ else
+ Mat4CpyMat4(mat, pamat);
+
+ Mat4MulMat4(tmat, obmat, mat);
+ Mat4MulFloat3((float *)tmat, size*scale);
+ if(par_space_mat)
+ Mat4MulMat4(mat, tmat, par_space_mat);
+ else
+ Mat4CpyMat4(mat, tmat);
+
+ dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+ if(G.rendering)
+ psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
}
- ob= ob->parent;
}
}
}
-
- if(G.rendering && paf->disp!=100) {
- MEM_freeN(paf->keys);
- paf->keys= NULL;
+ if(oblist)
+ MEM_freeN(oblist);
+ if(obmatlist)
+ MEM_freeN(obmatlist);
+
+ if(psys->lattice) {
+ end_latt_deform();
+ psys->lattice = 0;
}
-
-
}
static Object *find_family_object(Object **obar, char *family, char ch)
@@ -712,7 +947,7 @@ static Object *find_family_object(Object **obar, char *family, char ch)
}
-static void font_duplilist(ListBase *lb, Object *par)
+static void font_duplilist(ListBase *lb, Object *par, int level, int animated)
{
Object *ob, *obar[256];
Curve *cu;
@@ -720,6 +955,9 @@ static void font_duplilist(ListBase *lb, Object *par)
float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
int slen, a;
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+
Mat4CpyMat4(pmat, par->obmat);
/* in par the family name is stored, use this to find the other objects */
@@ -750,53 +988,72 @@ static void font_duplilist(ListBase *lb, Object *par)
Mat4CpyMat4(obmat, par->obmat);
VECCOPY(obmat[3], vec);
- new_dupli_object(lb, ob, obmat, par->lay, a);
+ new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated);
}
-
}
MEM_freeN(chartransdata);
}
/* ***************************** */
-
-/* note; group dupli's already set transform matrix. see note in group_duplilist() */
-ListBase *object_duplilist(Scene *sce, Object *ob)
-{
- ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist");
- duplilist->first= duplilist->last= NULL;
+static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated)
+{
+ if((ob->transflag & OB_DUPLI)==0)
+ return;
- if(ob->transflag & OB_DUPLI) {
- if(ob->transflag & OB_DUPLIVERTS) {
- if(ob->type==OB_MESH) {
- PartEff *paf;
- if( (paf=give_parteff(ob)) )
- particle_duplilist(duplilist, sce, ob, paf);
- else
- vertex_duplilist(duplilist, sce, ob);
- }
- else if(ob->type==OB_FONT) {
- font_duplilist(duplilist, ob);
+ /* Should the dupli's be generated for this object? - Respect restrict flags */
+ if (G.rendering) {
+ if (ob->restrictflag & OB_RESTRICT_RENDER) {
+ return;
+ }
+ } else {
+ if (ob->restrictflag & OB_RESTRICT_VIEW) {
+ return;
+ }
+ }
+
+ if(ob->transflag & OB_DUPLIPARTS) {
+ ParticleSystem *psys = ob->particlesystem.first;
+ for(; psys; psys=psys->next)
+ new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1, animated);
+ }
+ else if(ob->transflag & OB_DUPLIVERTS) {
+ if(ob->type==OB_MESH) {
+ vertex_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
+ }
+ else if(ob->type==OB_FONT) {
+ if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
+ font_duplilist(duplilist, ob, level+1, animated);
}
}
- else if(ob->transflag & OB_DUPLIFACES) {
- if(ob->type==OB_MESH)
- face_duplilist(duplilist, sce, ob);
+ }
+ else if(ob->transflag & OB_DUPLIFACES) {
+ if(ob->type==OB_MESH)
+ face_duplilist(duplilist, id, ob, par_space_mat, level+1, animated);
+ }
+ else if(ob->transflag & OB_DUPLIFRAMES) {
+ if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */
+ frames_duplilist(duplilist, ob, level+1, animated);
}
- else if(ob->transflag & OB_DUPLIFRAMES)
- frames_duplilist(duplilist, ob);
- else if(ob->transflag & OB_DUPLIGROUP) {
- DupliObject *dob;
-
- group_duplilist(duplilist, ob, 0); /* now recursive */
-
- /* make copy already, because in group dupli's deform displists can be makde, requiring parent matrices */
+ } else if(ob->transflag & OB_DUPLIGROUP) {
+ DupliObject *dob;
+
+ group_duplilist(duplilist, ob, level+1, animated); /* now recursive */
+
+ if (level==0) {
for(dob= duplilist->first; dob; dob= dob->next)
- Mat4CpyMat4(dob->ob->obmat, dob->mat);
+ if(dob->type == OB_DUPLIGROUP)
+ Mat4CpyMat4(dob->ob->obmat, dob->mat);
}
-
}
-
+}
+
+/* note; group dupli's already set transform matrix. see note in group_duplilist() */
+ListBase *object_duplilist(Scene *sce, Object *ob)
+{
+ ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist");
+ duplilist->first= duplilist->last= NULL;
+ object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0, 0);
return duplilist;
}
@@ -819,14 +1076,18 @@ int count_duplilist(Object *ob)
if(ob->transflag & OB_DUPLIVERTS) {
if(ob->type==OB_MESH) {
if(ob->transflag & OB_DUPLIVERTS) {
- PartEff *paf;
- if( (paf=give_parteff(ob)) ) {
- return paf->totpart;
- }
- else {
+ ParticleSystem *psys = ob->particlesystem.first;
+ int pdup=0;
+
+ for(; psys; psys=psys->next)
+ pdup += psys->totpart;
+
+ if(pdup==0){
Mesh *me= ob->data;
return me->totvert;
}
+ else
+ return pdup;
}
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 669724bd250..7ec56bd08ab 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -30,6 +30,8 @@
#include <math.h>
#include <string.h>
#include <stdio.h>
+#include <float.h>
+
#include "MEM_guardedalloc.h"
#include "nla.h"
@@ -354,6 +356,88 @@ void bone_flip_name (char *name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
+/* Finds the best possible extension to the name on a particular axis. (For renaming, check for unique names afterwards)
+ * This assumes that bone names are at most 32 chars long!
+ * strip_number: removes number extensions (TODO: not used)
+ * axis: the axis to name on
+ * head/tail: the head/tail co-ordinate of the bone on the specified axis
+ */
+void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
+{
+ int len;
+ char basename[32]={""};
+ char extension[5]={""};
+
+ len= strlen(name);
+ if (len == 0) return;
+ strcpy(basename, name);
+
+ /* Figure out extension to append:
+ * - The extension to append is based upon the axis that we are working on.
+ * - If head happens to be on 0, then we must consider the tail position as well to decide
+ * which side the bone is on
+ * -> If tail is 0, then it's bone is considered to be on axis, so no extension should be added
+ * -> Otherwise, extension is added from perspective of object based on which side tail goes to
+ * - If head is non-zero, extension is added from perspective of object based on side head is on
+ */
+ if (axis == 2) {
+ /* z-axis - vertical (top/bottom) */
+ if (IS_EQ(head, 0)) {
+ if (tail < 0)
+ strcpy(extension, ".Bot");
+ else if (tail > 0)
+ strcpy(extension, ".Top");
+ }
+ else {
+ if (head < 0)
+ strcpy(extension, ".Bot");
+ else
+ strcpy(extension, ".Top");
+ }
+ }
+ else if (axis == 1) {
+ /* y-axis - depth (front/back) */
+ if (IS_EQ(head, 0)) {
+ if (tail < 0)
+ strcpy(extension, ".Fr");
+ else if (tail > 0)
+ strcpy(extension, ".Bk");
+ }
+ else {
+ if (head < 0)
+ strcpy(extension, ".Fr");
+ else
+ strcpy(extension, ".Bk");
+ }
+ }
+ else {
+ /* x-axis - horizontal (left/right) */
+ if (IS_EQ(head, 0)) {
+ if (tail < 0)
+ strcpy(extension, ".R");
+ else if (tail > 0)
+ strcpy(extension, ".L");
+ }
+ else {
+ if (head < 0)
+ strcpy(extension, ".R");
+ else if (head > 0)
+ strcpy(extension, ".L");
+ }
+ }
+
+ /* Simple name truncation
+ * - truncate if there is an extension and it wouldn't be able to fit
+ * - otherwise, just append to end (TODO: this should really check if there was already a tag there, and remove it)
+ */
+ if (extension[0]) {
+ if ((32 - len) < strlen(extension)) {
+ strncpy(name, basename, len-strlen(extension));
+ }
+ }
+
+ sprintf(name, "%s%s", basename, extension);
+}
/* ************* B-Bone support ******************* */
@@ -404,17 +488,38 @@ static void equalize_bezier(float *data, int desired)
/* returns pointer to static array, filled with desired amount of bone->segments elements */
/* this calculation is done within unit bone space */
-Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
+Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
{
static Mat4 bbone_array[MAX_BBONE_SUBDIV];
+ static Mat4 bbone_rest_array[MAX_BBONE_SUBDIV];
+ Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
bPoseChannel *next, *prev;
Bone *bone= pchan->bone;
- float h1[3], h2[3], length, hlength1, hlength2, roll;
- float mat3[3][3], imat[4][4];
+ float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2;
+ float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4];
float data[MAX_BBONE_SUBDIV+1][4], *fp;
- int a;
-
+ int a, doscale= 0;
+
length= bone->length;
+
+ if(!rest) {
+ /* check if we need to take non-uniform bone scaling into account */
+ scale[0]= VecLength(pchan->pose_mat[0]);
+ scale[1]= VecLength(pchan->pose_mat[1]);
+ scale[2]= VecLength(pchan->pose_mat[2]);
+
+ if(fabs(scale[0] - scale[1]) > 1e-6f || fabs(scale[1] - scale[2]) > 1e-6f) {
+ Mat4One(scalemat);
+ scalemat[0][0]= scale[0];
+ scalemat[1][1]= scale[1];
+ scalemat[2][2]= scale[2];
+ Mat4Invert(iscalemat, scalemat);
+
+ length *= scale[1];
+ doscale = 1;
+ }
+ }
+
hlength1= bone->ease1*length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
hlength2= bone->ease2*length*0.390464f;
@@ -430,32 +535,75 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
first point = (0,0,0)
last point = (0, length, 0) */
- Mat4Invert(imat, pchan->pose_mat);
+ if(rest) {
+ Mat4Invert(imat, pchan->bone->arm_mat);
+ }
+ else if(doscale) {
+ Mat4CpyMat4(posemat, pchan->pose_mat);
+ Mat4Ortho(posemat);
+ Mat4Invert(imat, posemat);
+ }
+ else
+ Mat4Invert(imat, pchan->pose_mat);
if(prev) {
+ float difmat[4][4], result[3][3], imat3[3][3];
+
/* transform previous point inside this bone space */
- VECCOPY(h1, prev->pose_head);
+ if(rest)
+ VECCOPY(h1, prev->bone->arm_head)
+ else
+ VECCOPY(h1, prev->pose_head)
Mat4MulVecfl(imat, h1);
- /* if previous bone is B-bone too, use average handle direction */
- if(prev->bone->segments>1) h1[1]-= length;
+
+ if(prev->bone->segments>1) {
+ /* if previous bone is B-bone too, use average handle direction */
+ h1[1]-= length;
+ roll1= 0.0f;
+ }
+
Normalize(h1);
VecMulf(h1, -hlength1);
+
+ if(prev->bone->segments==1) {
+ /* find the previous roll to interpolate */
+ if(rest)
+ Mat4MulMat4(difmat, prev->bone->arm_mat, imat);
+ else
+ Mat4MulMat4(difmat, prev->pose_mat, imat);
+ Mat3CpyMat4(result, difmat); // the desired rotation at beginning of next bone
+
+ vec_roll_to_mat3(h1, 0.0f, mat3); // the result of vec_roll without roll
+
+ Mat3Inv(imat3, mat3);
+ Mat3MulMat3(mat3, result, imat3); // the matrix transforming vec_roll to desired roll
+
+ roll1= atan2(mat3[2][0], mat3[2][2]);
+ }
}
else {
h1[0]= 0.0f; h1[1]= hlength1; h1[2]= 0.0f;
+ roll1= 0.0f;
}
if(next) {
float difmat[4][4], result[3][3], imat3[3][3];
/* transform next point inside this bone space */
- VECCOPY(h2, next->pose_tail);
+ if(rest)
+ VECCOPY(h2, next->bone->arm_tail)
+ else
+ VECCOPY(h2, next->pose_tail)
Mat4MulVecfl(imat, h2);
/* if next bone is B-bone too, use average handle direction */
if(next->bone->segments>1);
else h2[1]-= length;
+ Normalize(h2);
/* find the next roll to interpolate as well */
- Mat4MulMat4(difmat, next->pose_mat, imat);
+ if(rest)
+ Mat4MulMat4(difmat, next->bone->arm_mat, imat);
+ else
+ Mat4MulMat4(difmat, next->pose_mat, imat);
Mat3CpyMat4(result, difmat); // the desired rotation at beginning of next bone
vec_roll_to_mat3(h2, 0.0f, mat3); // the result of vec_roll without roll
@@ -463,18 +611,16 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
Mat3Inv(imat3, mat3);
Mat3MulMat3(mat3, imat3, result); // the matrix transforming vec_roll to desired roll
- roll= atan2(mat3[2][0], mat3[2][2]);
+ roll2= atan2(mat3[2][0], mat3[2][2]);
/* and only now negate handle */
- Normalize(h2);
VecMulf(h2, -hlength2);
-
}
else {
h2[0]= 0.0f; h2[1]= -hlength2; h2[2]= 0.0f;
- roll= 0.0;
+ roll2= 0.0;
}
-
+
/* make curve */
if(bone->segments > MAX_BBONE_SUBDIV)
bone->segments= MAX_BBONE_SUBDIV;
@@ -482,7 +628,7 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4);
forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4);
forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4);
- forward_diff_bezier(0.0, 0.390464f*roll, (1.0f-0.390464f)*roll, roll, data[0]+3, MAX_BBONE_SUBDIV, 4);
+ forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4);
equalize_bezier(data[0], bone->segments); // note: does stride 4!
@@ -490,53 +636,93 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
VecSubf(h1, fp+4, fp);
vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll
- Mat4CpyMat3(bbone_array[a].mat, mat3);
- VECCOPY(bbone_array[a].mat[3], fp);
+
+ Mat4CpyMat3(result_array[a].mat, mat3);
+ VECCOPY(result_array[a].mat[3], fp);
+
+ if(doscale) {
+ /* correct for scaling when this matrix is used in scaled space */
+ Mat4MulSerie(result_array[a].mat, iscalemat, result_array[a].mat,
+ scalemat, NULL, NULL, NULL, NULL, NULL);
+ }
}
- return bbone_array;
+ return result_array;
}
/* ************ Armature Deform ******************* */
-static void pchan_b_bone_defmats(bPoseChannel *pchan)
+static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int rest_def)
{
Bone *bone= pchan->bone;
- Mat4 *b_bone= b_bone_spline_setup(pchan);
+ Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
+ Mat4 *b_bone_rest= (rest_def)? NULL: b_bone_spline_setup(pchan, 1);
Mat4 *b_bone_mats;
+ DualQuat *b_bone_dual_quats= NULL;
+ float tmat[4][4];
int a;
- pchan->b_bone_mats=b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats");
+ /* allocate b_bone matrices and dual quats */
+ b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats");
+ pchan->b_bone_mats= b_bone_mats;
+
+ if(use_quaternion) {
+ b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs");
+ pchan->b_bone_dual_quats= b_bone_dual_quats;
+ }
- /* first matrix is the inverse arm_mat, to bring points in local bone space */
+ /* first matrix is the inverse arm_mat, to bring points in local bone space
+ for finding out which segment it belongs to */
Mat4Invert(b_bone_mats[0].mat, bone->arm_mat);
-
- /* then we multiply the bbone_mats with arm_mat */
+
+ /* then we make the b_bone_mats:
+ - first transform to local bone space
+ - translate over the curve to the bbone mat space
+ - transform with b_bone matrix
+ - transform back into global space */
+ Mat4One(tmat);
+
for(a=0; a<bone->segments; a++) {
- Mat4MulMat4(b_bone_mats[a+1].mat, b_bone[a].mat, bone->arm_mat);
+ if(b_bone_rest)
+ Mat4Invert(tmat, b_bone_rest[a].mat);
+ else
+ tmat[3][1] = -a*(bone->length/(float)bone->segments);
+
+ Mat4MulSerie(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat,
+ b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL);
+
+ if(use_quaternion)
+ Mat4ToDQuat(bone->arm_mat, b_bone_mats[a+1].mat, &b_bone_dual_quats[a]);
}
}
-static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *defpos)
+static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
{
Mat4 *b_bone= pchan->b_bone_mats;
- float segment;
+ float (*mat)[4]= b_bone[0].mat;
+ float segment, y;
int a;
- /* need to transform defpos back to bonespace */
- Mat4MulVecfl(b_bone[0].mat, defpos);
+ /* need to transform co back to bonespace, only need y */
+ y= mat[0][1]*co[0] + mat[1][1]*co[1] + mat[2][1]*co[2] + mat[3][1];
/* now calculate which of the b_bones are deforming this */
segment= bone->length/((float)bone->segments);
- a= (int) (defpos[1]/segment);
+ a= (int)(y/segment);
- /* note; by clamping it extends deform at endpoints, goes best with straight joints in restpos. */
+ /* note; by clamping it extends deform at endpoints, goes best with
+ straight joints in restpos. */
CLAMP(a, 0, bone->segments-1);
- /* since the bbone mats translate from (0.0.0) on the curve, we subtract */
- defpos[1] -= ((float)a)*segment;
-
- Mat4MulVecfl(b_bone[a+1].mat, defpos);
+ if(dq) {
+ DQuatCpyDQuat(dq, &((DualQuat*)pchan->b_bone_dual_quats)[a]);
+ }
+ else {
+ Mat4MulVecfl(b_bone[a+1].mat, co);
+
+ if(defmat)
+ Mat3CpyMat4(defmat, b_bone[a+1].mat);
+ }
}
/* using vec with dist to bone b1 - b2 */
@@ -590,12 +776,25 @@ float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, fl
}
}
-static float dist_bone_deform(bPoseChannel *pchan, float *vec, float *co)
+static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3])
+{
+ float wmat[3][3];
+
+ if(pchan->bone->segments>1)
+ Mat3CpyMat3(wmat, bbonemat);
+ else
+ Mat3CpyMat4(wmat, pchan->chan_mat);
+
+ Mat3MulFloat((float*)wmat, weight);
+ Mat3AddMat3(mat, mat, wmat);
+}
+
+static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, float mat[][3], float *co)
{
Bone *bone= pchan->bone;
- float fac;
- float cop[3];
- float contrib=0.0;
+ float fac, contrib=0.0;
+ float cop[3], bbonemat[3][3];
+ DualQuat bbonedq;
if(bone==NULL) return 0.0f;
@@ -603,62 +802,95 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, float *co)
fac= distfactor_to_bone(cop, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
- if (fac>0.0){
+ if (fac>0.0) {
fac*=bone->weight;
contrib= fac;
if(contrib>0.0) {
+ if(vec) {
+ if(bone->segments>1)
+ // applies on cop and bbonemat
+ b_bone_deform(pchan, bone, cop, NULL, (mat)?bbonemat:NULL);
+ else
+ Mat4MulVecfl(pchan->chan_mat, cop);
- VECCOPY (cop, co);
-
- if(bone->segments>1)
- b_bone_deform(pchan, bone, cop); // applies on cop
-
- Mat4MulVecfl(pchan->chan_mat, cop);
-
- VecSubf (cop, cop, co); // Make this a delta from the base position
- cop[0]*=fac; cop[1]*=fac; cop[2]*=fac;
- VecAddf (vec, vec, cop);
+ // Make this a delta from the base position
+ VecSubf (cop, cop, co);
+ cop[0]*=fac; cop[1]*=fac; cop[2]*=fac;
+ VecAddf (vec, vec, cop);
+
+ if(mat)
+ pchan_deform_mat_add(pchan, fac, bbonemat, mat);
+ }
+ else {
+ if(bone->segments>1) {
+ b_bone_deform(pchan, bone, cop, &bbonedq, NULL);
+ DQuatAddWeighted(dq, &bbonedq, fac);
+ }
+ else
+ DQuatAddWeighted(dq, pchan->dual_quat, fac);
+ }
}
}
return contrib;
}
-static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, float *co, float *contrib)
+static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
{
- float cop[3];
+ float cop[3], bbonemat[3][3];
+ DualQuat bbonedq;
if (!weight)
return;
- VECCOPY (cop, co);
-
- if(pchan->bone->segments>1)
- b_bone_deform(pchan, pchan->bone, cop); // applies on cop
-
- Mat4MulVecfl(pchan->chan_mat, cop);
-
- vec[0]+=(cop[0]-co[0])*weight;
- vec[1]+=(cop[1]-co[1])*weight;
- vec[2]+=(cop[2]-co[2])*weight;
+ VECCOPY(cop, co);
+
+ if(vec) {
+ if(pchan->bone->segments>1)
+ // applies on cop and bbonemat
+ b_bone_deform(pchan, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
+ else
+ Mat4MulVecfl(pchan->chan_mat, cop);
+
+ vec[0]+=(cop[0]-co[0])*weight;
+ vec[1]+=(cop[1]-co[1])*weight;
+ vec[2]+=(cop[2]-co[2])*weight;
+
+ if(mat)
+ pchan_deform_mat_add(pchan, weight, bbonemat, mat);
+ }
+ else {
+ if(pchan->bone->segments>1) {
+ b_bone_deform(pchan, pchan->bone, cop, &bbonedq, NULL);
+ DQuatAddWeighted(dq, &bbonedq, weight);
+ }
+ else
+ DQuatAddWeighted(dq, pchan->dual_quat, weight);
+ }
(*contrib)+=weight;
}
void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, int deformflag,
- const char *defgrp_name)
+ float (*vertexCos)[3], float (*defMats)[3][3],
+ int numVerts, int deformflag,
+ float (*prevCos)[3], const char *defgrp_name)
{
bPoseChannel *pchan, **defnrToPC = NULL;
MDeformVert *dverts = NULL;
bDeformGroup *dg;
+ DualQuat *dualquats= NULL;
float obinv[4][4], premat[4][4], postmat[4][4];
int use_envelope = deformflag & ARM_DEF_ENVELOPE;
+ int use_quaternion = deformflag & ARM_DEF_QUATERNION;
+ int bbone_rest_def = deformflag & ARM_DEF_B_BONE_REST;
+ int invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP;
int numGroups = 0; /* safety for vertexgroup index overflow */
int i, target_totvert = 0; /* safety for vertexgroup overflow */
int use_dverts = 0;
int armature_def_nr = -1;
+ int totchan;
if(armOb == G.obedit) return;
@@ -669,11 +901,23 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
/* bone defmats are already in the channels, chan_mat */
- /* initialize B_bone matrices */
+ /* initialize B_bone matrices and dual quaternions */
+ if(use_quaternion) {
+ totchan= BLI_countlist(&armOb->pose->chanbase);
+ dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats");
+ }
+
+ totchan= 0;
for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
- if(!(pchan->bone->flag & BONE_NO_DEFORM))
+ if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
if(pchan->bone->segments > 1)
- pchan_b_bone_defmats(pchan);
+ pchan_b_bone_defmats(pchan, use_quaternion, bbone_rest_def);
+
+ if(use_quaternion) {
+ pchan->dual_quat= &dualquats[totchan++];
+ Mat4ToDQuat(pchan->bone->arm_mat, pchan->chan_mat, pchan->dual_quat);
+ }
+ }
}
/* get the def_nr for the overall armature vertex group if present */
@@ -722,13 +966,28 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(i = 0; i < numVerts; i++) {
MDeformVert *dvert;
- float *co = vertexCos[i];
- float vec[3];
+ DualQuat sumdq, *dq = NULL;
+ float *co, dco[3];
+ float sumvec[3], summat[3][3];
+ float *vec = NULL, (*smat)[3] = NULL;
float contrib = 0.0f;
- float armature_weight = 1.0f; /* default to 1 if no overall def group */
+ float armature_weight = 1.0f; /* default to 1 if no overall def group */
+ float prevco_weight = 1.0f; /* weight for optional cached vertexcos */
int j;
- vec[0] = vec[1] = vec[2] = 0.0f;
+ if(use_quaternion) {
+ memset(&sumdq, 0, sizeof(DualQuat));
+ dq= &sumdq;
+ }
+ else {
+ sumvec[0] = sumvec[1] = sumvec[2] = 0.0f;
+ vec= sumvec;
+
+ if(defMats) {
+ Mat3Clr((float*)summat);
+ smat = summat;
+ }
+ }
if(use_dverts || armature_def_nr >= 0) {
if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
@@ -745,11 +1004,22 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
break;
}
}
+ /* hackish: the blending factor can be used for blending with prevCos too */
+ if(prevCos) {
+ if(invert_vgroup)
+ prevco_weight= 1.0f-armature_weight;
+ else
+ prevco_weight= armature_weight;
+ armature_weight= 1.0f;
+ }
}
/* check if there's any point in calculating for this vert */
if(armature_weight == 0.0f) continue;
+ /* get the coord we work on */
+ co= prevCos?prevCos[i]:vertexCos[i];
+
/* Apply the object's matrix */
Mat4MulVecfl(premat, co);
@@ -772,7 +1042,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
bone->rad_tail,
bone->dist);
}
- pchan_bone_deform(pchan, weight, vec, co, &contrib);
+ pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
}
}
/* if there are vertexgroups but not groups with bones
@@ -782,7 +1052,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(pchan = armOb->pose->chanbase.first; pchan;
pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, co);
+ contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
}
}
@@ -790,19 +1060,61 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(pchan = armOb->pose->chanbase.first; pchan;
pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, co);
+ contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
}
/* actually should be EPSILON? weight values and contrib can be like 10e-39 small */
if(contrib > 0.0001f) {
- VecMulf(vec, armature_weight / contrib);
- VecAddf(co, vec, co);
+ if(use_quaternion) {
+ DQuatNormalize(dq, contrib);
+
+ if(armature_weight != 1.0f) {
+ VECCOPY(dco, co);
+ DQuatMulVecfl(dq, dco, (defMats)? summat: NULL);
+ VecSubf(dco, dco, co);
+ VecMulf(dco, armature_weight);
+ VecAddf(co, co, dco);
+ }
+ else
+ DQuatMulVecfl(dq, co, (defMats)? summat: NULL);
+
+ smat = summat;
+ }
+ else {
+ VecMulf(vec, armature_weight/contrib);
+ VecAddf(co, vec, co);
+ }
+
+ if(defMats) {
+ float pre[3][3], post[3][3], tmpmat[3][3];
+
+ Mat3CpyMat4(pre, premat);
+ Mat3CpyMat4(post, postmat);
+ Mat3CpyMat3(tmpmat, defMats[i]);
+
+ if(!use_quaternion) /* quaternion already is scale corrected */
+ Mat3MulFloat((float*)smat, armature_weight/contrib);
+
+ Mat3MulSerie(defMats[i], tmpmat, pre, smat, post,
+ NULL, NULL, NULL, NULL);
+ }
}
+
/* always, check above code */
Mat4MulVecfl(postmat, co);
+
+
+ /* interpolate with previous modifier position using weight group */
+ if(prevCos) {
+ float mw= 1.0f - prevco_weight;
+ vertexCos[i][0]= prevco_weight*vertexCos[i][0] + mw*co[0];
+ vertexCos[i][1]= prevco_weight*vertexCos[i][1] + mw*co[1];
+ vertexCos[i][2]= prevco_weight*vertexCos[i][2] + mw*co[2];
+ }
}
+ if(dualquats) MEM_freeN(dualquats);
if(defnrToPC) MEM_freeN(defnrToPC);
/* free B_bone matrices */
@@ -811,6 +1123,12 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
MEM_freeN(pchan->b_bone_mats);
pchan->b_bone_mats = NULL;
}
+ if(pchan->b_bone_dual_quats) {
+ MEM_freeN(pchan->b_bone_dual_quats);
+ pchan->b_bone_dual_quats = NULL;
+ }
+
+ pchan->dual_quat = NULL;
}
}
@@ -1070,7 +1388,6 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
bPose *pose= ob->pose, *frompose= from->pose;
bPoseChannel *pchan, *pchanp, pchanw;
bConstraint *con;
- char *str;
if(frompose==NULL) return;
@@ -1084,6 +1401,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchan= pose->chanbase.first;
for(; pchan; pchan= pchan->next) {
if(pchan->bone->layer & layer_protected) {
+ ListBase proxylocal_constraints = {NULL, NULL};
pchanp= get_pose_channel(frompose, pchan->name);
/* copy posechannel to temp, but restore important pointers */
@@ -1094,16 +1412,36 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.child= pchan->child;
pchanw.path= NULL;
- /* constraints, set target ob pointer to own object */
+ /* constraints - proxy constraints are flushed... local ones are added after
+ * 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
+ * 2. copy proxy-pchan's constraints on-to new
+ * 3. add extracted local constraints back on top
+ */
+ extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
copy_constraints(&pchanw.constraints, &pchanp->constraints);
-
- for(con= pchanw.constraints.first; con; con= con->next) {
- if(from==get_constraint_target(con, &str))
- set_constraint_target(con, ob, NULL);
+ addlisttolist(&pchanw.constraints, &proxylocal_constraints);
+
+ /* constraints - set target ob pointer to own object */
+ for (con= pchanw.constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == from)
+ ct->tar = ob;
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
}
/* free stuff from current channel */
- if(pchan->path) MEM_freeN(pchan->path);
+ if (pchan->path) MEM_freeN(pchan->path);
free_constraints(&pchan->constraints);
/* the final copy */
@@ -1321,7 +1659,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
float goalrot[3][3], goalpos[3];
float rootmat[4][4], imat[4][4];
float goal[4][4], goalinv[4][4];
- float size[3], irest_basis[3][3], full_basis[3][3];
+ 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;
int a, flag, hasstretch=0;
@@ -1329,7 +1667,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
IK_Segment *seg, *parent, **iktree, *iktarget;
IK_Solver *solver;
PoseTarget *target;
- bKinematicConstraint *data;
+ bKinematicConstraint *data, *poleangledata=NULL;
Bone *bone;
if (tree->totchannel == 0)
@@ -1343,11 +1681,11 @@ static void execute_posetree(Object *ob, PoseTree *tree)
/* set DoF flag */
flag= 0;
- if((pchan->ikflag & BONE_IK_NO_XDOF) == 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) == 0)
+ if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP))
flag |= IK_YDOF;
- if((pchan->ikflag & BONE_IK_NO_ZDOF) == 0)
+ if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP))
flag |= IK_ZDOF;
if(tree->stretch && (pchan->ikstretch > 0.0)) {
@@ -1440,53 +1778,88 @@ static void execute_posetree(Object *ob, PoseTree *tree)
Mat4MulMat4 (imat, rootmat, ob->obmat);
Mat4Invert (goalinv, imat);
- for(target=tree->targets.first; target; target=target->next) {
- data= (bKinematicConstraint*)target->con->data;
-
- /* 1.0=ctime, we pass on object for auto-ik */
- get_constraint_target_matrix(target->con, TARGET_BONE, ob, rootmat, size, 1.0);
+ 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;
+
+ if(data->flag & CONSTRAINT_IK_GETANGLE) {
+ poleangledata= data;
+ data->flag &= ~CONSTRAINT_IK_GETANGLE;
+ }
+ }
+ }
/* do we need blending? */
- if(target->con->enforce!=1.0) {
+ if (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(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) && (data->flag & CONSTRAINT_IK_AUTO)==0)
- IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
+ }
+ 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 */
@@ -1603,220 +1976,46 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = t
pchan->flag |= POSE_DONE;
}
-static void do_local_constraint(bPoseChannel *pchan, bConstraint *con)
+/* NLA strip modifiers */
+static void do_strip_modifiers(Object *armob, Bone *bone, bPoseChannel *pchan)
{
- switch(con->type) {
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data= con->data;
- float fac= con->enforce;
+ bActionModifier *amod;
+ bActionStrip *strip, *strip2;
+ float scene_cfra= G.scene->r.cfra;
+ int do_modif;
+
+ for (strip=armob->nlastrips.first; strip; strip=strip->next) {
+ do_modif=0;
+
+ if (scene_cfra>=strip->start && scene_cfra<=strip->end)
+ do_modif=1;
+
+ if ((scene_cfra > strip->end) && (strip->flag & ACTSTRIP_HOLDLASTFRAME)) {
+ do_modif=1;
- if(data->tar && data->subtarget[0]) {
- bPoseChannel *pchant= get_pose_channel(data->tar->pose, data->subtarget);
- if(pchant) {
- float loc[3];
-
- /* copy location of tip of bone? */
- if (data->flag & LOCLIKE_TIP) {
- float mat[4][4], tmat[4][4];
-
- Mat4One(tmat);
- VECCOPY(tmat[3], pchant->pose_tail);
-
- armature_mat_pose_to_delta(mat, tmat, pchant->bone->arm_mat);
- VECCOPY(loc, mat[3]);
- }
- else
- VECCOPY(loc, pchant->loc);
-
- /* do offsets? */
- if (data->flag & LOCLIKE_OFFSET)
- VecAddf(loc, loc, pchan->loc);
-
- if (data->flag & LOCLIKE_X)
- pchan->loc[0]= FloatLerpf(loc[0], pchan->loc[0], fac);
- if (data->flag & LOCLIKE_Y)
- pchan->loc[1]= FloatLerpf(loc[1], pchan->loc[1], fac);
- if (data->flag & LOCLIKE_Z)
- pchan->loc[2]= FloatLerpf(loc[2], pchan->loc[2], fac);
- if (data->flag & LOCLIKE_X_INVERT)
- pchan->loc[0]= FloatLerpf(pchant->loc[0], pchan->loc[0], -fac);
- if (data->flag & LOCLIKE_Y_INVERT)
- pchan->loc[1]= FloatLerpf(pchant->loc[1], pchan->loc[1], -fac);
- if (data->flag & LOCLIKE_Z_INVERT)
- pchan->loc[2]= FloatLerpf(pchant->loc[2], pchan->loc[2], -fac);
- }
- }
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data= con->data;
- if(data->tar && data->subtarget[0]) {
- bPoseChannel *pchant= get_pose_channel(data->tar->pose, data->subtarget);
- if(pchant) {
- if(data->flag != (ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z)) {
- float eul[3], eult[3], euln[3];
- float fac= con->enforce;
-
- QuatToEul(pchan->quat, eul);
- QuatToEul(pchant->quat, eult);
- VECCOPY(euln, eul);
-
- if(data->flag & ROTLIKE_X) euln[0]= FloatLerpf(eult[0], eul[0], fac);
- if(data->flag & ROTLIKE_Y) euln[1]= FloatLerpf(eult[1], eul[1], fac);
- if(data->flag & ROTLIKE_Z) euln[2]= FloatLerpf(eult[2], eul[2], fac);
- if(data->flag & ROTLIKE_X_INVERT) euln[0]= FloatLerpf(eult[0], eul[0], -fac);
- if(data->flag & ROTLIKE_Y_INVERT) euln[1]= FloatLerpf(eult[1], eul[1], -fac);
- if(data->flag & ROTLIKE_Z_INVERT) euln[2]= FloatLerpf(eult[2], eul[2], -fac);
-
- compatible_eul(eul, euln);
- EulToQuat(euln, pchan->quat);
- }
- else {
- QuatInterpol(pchan->quat, pchan->quat, pchant->quat, con->enforce);
- }
+ /* if there are any other strips active, ignore modifiers for this strip -
+ * 'hold' option should only hold action modifiers if there are
+ * no other active strips */
+ for (strip2=strip->next; strip2; strip2=strip2->next) {
+ if (strip2 == strip) continue;
+
+ if (scene_cfra>=strip2->start && scene_cfra<=strip2->end) {
+ if (!(strip2->flag & ACTSTRIP_MUTE))
+ do_modif=0;
}
}
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data= con->data;
- float fac= con->enforce;
- if(data->tar && data->subtarget[0]) {
- bPoseChannel *pchant= get_pose_channel(data->tar->pose, data->subtarget);
- if(pchant) {
- if (data->flag & SIZELIKE_X)
- pchan->size[0]= FloatLerpf(pchant->size[0], pchan->size[0], fac);
- if (data->flag & SIZELIKE_Y)
- pchan->size[1]= FloatLerpf(pchant->size[1], pchan->size[1], fac);
- if (data->flag & SIZELIKE_Z)
- pchan->size[2]= FloatLerpf(pchant->size[2], pchan->size[2], fac);
+ /* if there are any later, activated, strips with 'hold' set, they take precedence,
+ * so ignore modifiers for this strip */
+ for (strip2=strip->next; strip2; strip2=strip2->next) {
+ if (scene_cfra < strip2->start) continue;
+ if ((strip2->flag & ACTSTRIP_HOLDLASTFRAME) && !(strip2->flag & ACTSTRIP_MUTE)) {
+ do_modif=0;
}
}
}
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
- {
- bLocLimitConstraint *data= con->data;
- float fac= con->enforce;
-
- if (data->flag & LIMIT_XMIN) {
- if(pchan->loc[0] < data->xmin)
- pchan->loc[0] = FloatLerpf(data->xmin, pchan->loc[0], fac);
- }
- if (data->flag & LIMIT_XMAX) {
- if (pchan->loc[0] > data->xmax)
- pchan->loc[0] = FloatLerpf(data->xmax, pchan->loc[0], fac);
- }
- if (data->flag & LIMIT_YMIN) {
- if(pchan->loc[1] < data->ymin)
- pchan->loc[1] = FloatLerpf(data->ymin, pchan->loc[1], fac);
- }
- if (data->flag & LIMIT_YMAX) {
- if (pchan->loc[1] > data->ymax)
- pchan->loc[1] = FloatLerpf(data->ymax, pchan->loc[1], fac);
- }
- if (data->flag & LIMIT_ZMIN) {
- if(pchan->loc[2] < data->zmin)
- pchan->loc[2] = FloatLerpf(data->zmin, pchan->loc[2], fac);
- }
- if (data->flag & LIMIT_ZMAX) {
- if (pchan->loc[2] > data->zmax)
- pchan->loc[2] = FloatLerpf(data->zmax, pchan->loc[2], fac);
- }
- }
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
- {
- bRotLimitConstraint *data = con->data;
- float eul[3];
- float fac= con->enforce;
-
- QuatToEul(pchan->quat, eul);
-
- /* eulers: radians to degrees! */
- eul[0] = (eul[0] / (2*M_PI) * 360);
- eul[1] = (eul[1] / (2*M_PI) * 360);
- eul[2] = (eul[2] / (2*M_PI) * 360);
-
- /* limiting of euler values... */
- if (data->flag & LIMIT_XROT) {
- if (eul[0] < data->xmin)
- eul[0] = FloatLerpf(data->xmin, eul[0], fac);
-
- if (eul[0] > data->xmax)
- eul[0] = FloatLerpf(data->xmax, eul[0], fac);
- }
- if (data->flag & LIMIT_YROT) {
- if (eul[1] < data->ymin)
- eul[1] = FloatLerpf(data->ymin, eul[1], fac);
-
- if (eul[1] > data->ymax)
- eul[1] = FloatLerpf(data->ymax, eul[1], fac);
- }
- if (data->flag & LIMIT_ZROT) {
- if (eul[2] < data->zmin)
- eul[2] = FloatLerpf(data->zmin, eul[2], fac);
-
- if (eul[2] > data->zmax)
- eul[2] = FloatLerpf(data->zmax, eul[2], fac);
- }
-
- /* eulers: degrees to radians ! */
- eul[0] = (eul[0] / 360 * (2*M_PI));
- eul[1] = (eul[1] / 360 * (2*M_PI));
- eul[2] = (eul[2] / 360 * (2*M_PI));
-
- /* convert back */
- EulToQuat(eul, pchan->quat);
- }
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- {
- bSizeLimitConstraint *data= con->data;
- float fac= con->enforce;
-
- if (data->flag & LIMIT_XMIN) {
- if(pchan->size[0] < data->xmin)
- pchan->size[0] = FloatLerpf(data->xmin, pchan->size[0], fac);
- }
- if (data->flag & LIMIT_XMAX) {
- if (pchan->size[0] > data->xmax)
- pchan->size[0] = FloatLerpf(data->xmax, pchan->size[0], fac);
- }
- if (data->flag & LIMIT_YMIN) {
- if(pchan->size[1] < data->ymin)
- pchan->size[1] = FloatLerpf(data->ymin, pchan->size[1], fac);
- }
- if (data->flag & LIMIT_YMAX) {
- if (pchan->size[1] > data->ymax)
- pchan->size[1] = FloatLerpf(data->ymax, pchan->size[1], fac);
- }
- if (data->flag & LIMIT_ZMIN) {
- if(pchan->size[2] < data->zmin)
- pchan->size[2] = FloatLerpf(data->zmin, pchan->size[2], fac);
- }
- if (data->flag & LIMIT_ZMAX) {
- if (pchan->size[2] > data->zmax)
- pchan->size[2] = FloatLerpf(data->zmax, pchan->size[2], fac);
- }
- }
- break;
- }
-}
-
-static void do_strip_modifiers(Object *armob, Bone *bone, bPoseChannel *pchan)
-{
- bActionModifier *amod;
- bActionStrip *strip;
- float scene_cfra= G.scene->r.cfra;
-
- for (strip=armob->nlastrips.first; strip; strip=strip->next) {
- if(scene_cfra>=strip->start && scene_cfra<=strip->end) {
-
+
+ if (do_modif) {
/* temporal solution to prevent 2 strips accumulating */
if(scene_cfra==strip->end && strip->next && strip->next->start==scene_cfra)
continue;
@@ -1906,32 +2105,16 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime)
{
Bone *bone, *parbone;
bPoseChannel *parchan;
- float vec[3], quat[4];
- int did_local= 0; /* copying quaternion should be limited, chan_calc_mat() normalizes quat */
+ float vec[3];
/* set up variables for quicker access below */
bone= pchan->bone;
parbone= bone->parent;
parchan= pchan->parent;
-
- /* Do local constraints, these only work on the channel data (loc rot size) */
- QUATCOPY(quat, pchan->quat);
- if(pchan->constraints.first) {
- bConstraint *con;
- for(con=pchan->constraints.first; con; con= con->next) {
- if(con->flag & CONSTRAINT_LOCAL) {
- do_local_constraint(pchan, con);
- did_local= 1;
- }
- }
- }
/* this gives a chan_mat with actions (ipos) results */
chan_calc_mat(pchan);
- if(did_local)
- QUATCOPY(pchan->quat, quat); /* local constraint hack. bad! */
-
/* construct the posemat based on PoseChannels, that we do before applying constraints */
/* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) */
@@ -1961,6 +2144,21 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime)
Mat4MulSerie(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
}
+ else if(bone->flag & BONE_NO_SCALE) {
+ float orthmat[4][4], vec[3];
+
+ /* get the official transform, but we only use the vector from it (optimize...) */
+ Mat4MulSerie(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
+ VECCOPY(vec, pchan->pose_mat[3]);
+
+ /* do this again, but with an ortho-parent matrix */
+ Mat4CpyMat4(orthmat, parchan->pose_mat);
+ Mat4Ortho(orthmat);
+ Mat4MulSerie(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
+
+ /* copy correct transform */
+ VECCOPY(pchan->pose_mat[3], vec);
+ }
else
Mat4MulSerie(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
}
@@ -1970,44 +2168,36 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime)
VecAddf(pchan->pose_mat[3], pchan->pose_mat[3], ob->pose->cyclic_offset);
}
+ /* do NLA strip modifiers - i.e. curve follow */
do_strip_modifiers(ob, bone, pchan);
/* Do constraints */
- if(pchan->constraints.first) {
- static Object conOb;
- static int initialized= 0;
+ if (pchan->constraints.first) {
+ bConstraintOb *cob;
- VECCOPY(vec, pchan->pose_mat[3]);
-
- /* Build a workob to pass the bone to the constraint solver */
- if(initialized==0) {
- memset(&conOb, 0, sizeof(Object));
- initialized= 1;
- }
- conOb.size[0]= conOb.size[1]= conOb.size[2]= 1.0;
- conOb.data = ob->data;
- conOb.type = ob->type;
- conOb.parent = ob; // ik solver retrieves the armature that way !?!?!?!
- conOb.pose= ob->pose; // needed for retrieving pchan
- conOb.trackflag = ob->trackflag;
- conOb.upflag = ob->upflag;
+ /* local constraints */
+ do_constraint_channels(&pchan->constraints, NULL, ctime, 0);
- /* Collect the constraints from the pose (listbase copy) */
- conOb.constraints = pchan->constraints;
+ /* make a copy of location of PoseChannel for later */
+ VECCOPY(vec, pchan->pose_mat[3]);
- /* conOb.obmat takes bone to worldspace */
- Mat4MulMat4 (conOb.obmat, pchan->pose_mat, ob->obmat);
+ /* prepare PoseChannel for Constraint solving
+ * - makes a copy of matrix, and creates temporary struct to use
+ */
+ cob= constraints_make_evalob(ob, pchan, CONSTRAINT_OBTYPE_BONE);
- /* Solve */
- solve_constraints (&conOb, TARGET_BONE, (void*)pchan, ctime); // ctime doesnt alter objects
+ /* Solve PoseChannel's Constraints */
+ solve_constraints(&pchan->constraints, cob, ctime); // ctime doesnt alter objects
- /* Take out of worldspace */
- Mat4MulMat4 (pchan->pose_mat, conOb.obmat, ob->imat);
+ /* cleanup after Constraint Solving
+ * - applies matrix back to pchan, and frees temporary struct used
+ */
+ constraints_clear_evalob(cob);
/* prevent constraints breaking a chain */
- if(pchan->bone->flag & BONE_CONNECTED)
+ if(pchan->bone->flag & BONE_CONNECTED) {
VECCOPY(pchan->pose_mat[3], vec);
-
+ }
}
/* calculate head */
@@ -2016,7 +2206,6 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime)
VECCOPY(vec, pchan->pose_mat[1]);
VecMulf(vec, bone->length);
VecAddf(pchan->pose_tail, pchan->pose_head, vec);
-
}
/* This only reads anim data from channels, and writes to channels */
@@ -2027,7 +2216,7 @@ void where_is_pose (Object *ob)
Bone *bone;
bPoseChannel *pchan;
float imat[4][4];
- float ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0); /* not accurate... */
+ float ctime= bsystem_time(ob, (float)G.scene->r.cfra, 0.0); /* not accurate... */
arm = get_armature(ob);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index cad8d3b0861..534ddc555e9 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -63,6 +63,7 @@
#include "DNA_mesh_types.h"
#include "DNA_screen_types.h"
+#include "BKE_action.h"
#include "BKE_blender.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -266,7 +267,7 @@ static void clear_global(void)
free_vertexpaint();
- G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT);
+ G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT + G_PARTICLEEDIT);
}
/* make sure path names are correct for OS */
@@ -307,7 +308,6 @@ static void clean_paths(Main *main)
}
BLI_clean(scene->r.backbuf);
BLI_clean(scene->r.pic);
- BLI_clean(scene->r.ftype);
scene= scene->id.next;
}
@@ -396,6 +396,9 @@ static void setup_app_data(BlendFileData *bfd, char *filename)
/* baseflags, groups, make depsgraph, etc */
set_scene_bg(G.scene);
+ /* clear BONE_UNKEYED flags, these are not valid anymore for proxies */
+ framechange_poses_clear_unkeyed();
+
/* last stage of do_versions actually, that sets recalc flags for recalc poses */
for(ob= G.main->object.first; ob; ob= ob->id.next) {
if(ob->type==OB_ARMATURE)
@@ -409,8 +412,9 @@ static void setup_app_data(BlendFileData *bfd, char *filename)
/* there's an onload scriptlink to execute in screenmain */
mainqenter(ONLOAD_SCRIPT, 1);
}
-
- strcpy(G.sce, filename);
+ if (G.sce != filename) /* these are the same at times, should never copy to the same location */
+ strcpy(G.sce, filename);
+
strcpy(G.main->name, filename); /* is guaranteed current file */
MEM_freeN(bfd);
@@ -478,7 +482,7 @@ int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r)
if (type_r)
*((BlenFileType*)type_r)= bfd->type;
- setup_app_data(bfd, "<memory>");
+ setup_app_data(bfd, "<memory2>");
} else {
error("Loading failed: %s", BLO_bre_as_string(bre));
}
@@ -500,7 +504,7 @@ int BKE_read_file_from_memfile(MemFile *memfile)
bfd= BLO_read_from_memfile(G.sce, memfile, &bre);
if (bfd) {
- setup_app_data(bfd, "<memory>");
+ setup_app_data(bfd, "<memory1>");
} else {
error("Loading failed: %s", BLO_bre_as_string(bre));
}
@@ -601,7 +605,7 @@ void BKE_write_undo(char *name)
counter= counter % U.undosteps;
sprintf(numstr, "%d.blend", counter);
- BLI_make_file_string("/", tstr, U.tempdir, numstr);
+ BLI_make_file_string("/", tstr, btempdir, numstr);
success= BLO_write_file(tstr, G.fileflags, &err);
@@ -712,11 +716,11 @@ void BKE_undo_save_quit(void)
/* no undo state to save */
if(undobase.first==undobase.last) return;
- BLI_make_file_string("/", str, U.tempdir, "quit.blend");
+ BLI_make_file_string("/", str, btempdir, "quit.blend");
file = open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
if(file == -1) {
- printf("Unable to save %s\n", str);
+ error("Unable to save %s, check you have permissions", str);
return;
}
@@ -728,7 +732,7 @@ void BKE_undo_save_quit(void)
close(file);
- if(chunk) printf("Unable to save %s\n", str);
+ if(chunk) error("Unable to save %s, internal error", str);
else printf("Saved session recovery to %s\n", str);
}
diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h
new file mode 100644
index 00000000000..4c6460b3378
--- /dev/null
+++ b/source/blender/blenkernel/intern/bmesh_private.h
@@ -0,0 +1,71 @@
+/**
+ * BME_private.h jan 2007
+ *
+ * low level, 'private' function prototypes for bmesh kernel.
+ *
+ * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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) 2004 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Geoffrey Bantle.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BMESH_PRIVATE
+#define BMESH_PRIVATE
+
+#include "BKE_bmesh.h"
+
+/*ALLOCATION/DEALLOCATION*/
+struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example);
+struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example);
+struct BME_Poly *BME_addpolylist(struct BME_Mesh *bm, struct BME_Poly *example);
+struct BME_Loop *BME_create_loop(struct BME_Mesh *bm, struct BME_Vert *v, struct BME_Edge *e, struct BME_Poly *f, struct BME_Loop *example);
+
+void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v);
+void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e);
+void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f);
+void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l);
+void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l);
+
+/*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/
+void BME_cycle_append(void *h, void *nt);
+int BME_cycle_remove(void *h, void *remn);
+int BME_cycle_validate(int len, void *h);
+/*DISK CYCLE MANAGMENT*/
+int BME_disk_append_edge(struct BME_Edge *e, struct BME_Vert *v);
+void BME_disk_remove_edge(struct BME_Edge *e, struct BME_Vert *v);
+/*RADIAL CYCLE MANAGMENT*/
+void BME_radial_append(struct BME_Edge *e, struct BME_Loop *l);
+void BME_radial_remove_loop(struct BME_Loop *l, struct BME_Edge *e);
+
+/*MISC FUNCTIONS*/
+int BME_edge_swapverts(struct BME_Edge *e, struct BME_Vert *orig, struct BME_Vert *new); /*relink edge*/
+int BME_disk_hasedge(struct BME_Vert *v, struct BME_Edge *e);
+
+/*Error reporting. Shouldnt be called by tools ever.*/
+void BME_error(void);
+#endif
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 2d5f5f091c3..c2946bb666f 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -52,6 +52,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_object_fluidsim.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -746,17 +747,24 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
DerivedMesh *dm = &cddm->dm;
- int i, *index;
+ int i, *index, alloctype;
- /* this does a referenced copy, the only new layers being ORIGINDEX */
+ /* this does a referenced copy, the only new layers being ORIGINDEX,
+ * with an exception for fluidsim */
DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
+ dm->deformedOnly = 1;
+
+ if(ob && ob->fluidsimSettings && ob->fluidsimSettings->meshSurface)
+ alloctype= CD_DUPLICATE;
+ else
+ alloctype= CD_REFERENCE;
- CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, CD_REFERENCE,
+ CustomData_merge(&mesh->vdata, &dm->vertData, CD_MASK_MESH, alloctype,
mesh->totvert);
- CustomData_merge(&mesh->edata, &dm->edgeData, CD_MASK_MESH, CD_REFERENCE,
+ CustomData_merge(&mesh->edata, &dm->edgeData, CD_MASK_MESH, alloctype,
mesh->totedge);
- CustomData_merge(&mesh->fdata, &dm->faceData, CD_MASK_MESH, CD_REFERENCE,
+ CustomData_merge(&mesh->fdata, &dm->faceData, CD_MASK_MESH, alloctype,
mesh->totface);
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
@@ -798,6 +806,8 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
MFace *mface = cddm->mface;
int i, *index;
+ dm->deformedOnly = 1;
+
CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
CD_CALLOC, dm->numVertData);
/* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
@@ -830,6 +840,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
mv->no[0] = eve->no[0] * 32767.0;
mv->no[1] = eve->no[1] * 32767.0;
mv->no[2] = eve->no[2] * 32767.0;
+ mv->bweight = (unsigned char) (eve->bweight * 255.0f);
mv->mat_nr = 0;
mv->flag = 0;
@@ -847,6 +858,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
med->v1 = eed->v1->tmp.l;
med->v2 = eed->v2->tmp.l;
med->crease = (unsigned char) (eed->crease * 255.0f);
+ med->bweight = (unsigned char) (eed->bweight * 255.0f);
med->flag = ME_EDGEDRAW|ME_EDGERENDER;
if(eed->seam) med->flag |= ME_SEAM;
@@ -889,6 +901,7 @@ DerivedMesh *CDDM_copy(DerivedMesh *source)
/* this initializes dm, and copies all non mvert/medge/mface layers */
DM_from_template(dm, source, numVerts, numEdges, numFaces);
+ dm->deformedOnly = source->deformedOnly;
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
new file mode 100644
index 00000000000..3d5de19c1fc
--- /dev/null
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -0,0 +1,1467 @@
+/* cloth.c
+*
+*
+* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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) Blender Foundation
+* All rights reserved.
+*
+* Contributor(s): Daniel Genrich
+*
+* ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+/* types */
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_cloth_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BLI_linklist.h"
+
+#include "BKE_curve.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_cloth.h"
+#include "BKE_modifier.h"
+#include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
+#include "BIF_editdeform.h"
+#include "BIF_editkey.h"
+#include "DNA_screen_types.h"
+#include "BSE_headerbuttons.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "mydevice.h"
+
+#include "BKE_pointcache.h"
+
+#ifdef _WIN32
+void tstart ( void )
+{}
+void tend ( void )
+{
+}
+double tval()
+{
+ return 0;
+}
+#else
+#include <sys/time.h>
+ static struct timeval _tstart, _tend;
+ static struct timezone tz;
+ void tstart ( void )
+{
+ gettimeofday ( &_tstart, &tz );
+}
+void tend ( void )
+{
+ gettimeofday ( &_tend,&tz );
+}
+double tval()
+{
+ double t1, t2;
+ t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );
+ t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 );
+ return t2-t1;
+}
+#endif
+
+/* Our available solvers. */
+// 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
+// 254 = MAX!
+static CM_SOLVER_DEF solvers [] =
+{
+ { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
+ // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
+};
+
+/* ********** cloth engine ******* */
+/* Prototypes for internal functions.
+*/
+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 cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
+static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
+
+
+/******************************************************************************
+*
+* External interface called by modifier.c clothModifier functions.
+*
+******************************************************************************/
+/**
+ * cloth_init - creates a new cloth simulation.
+ *
+ * 1. create object
+ * 2. fill object with standard values or with the GUI settings if given
+ */
+void cloth_init ( ClothModifierData *clmd )
+{
+ /* Initialize our new data structure to reasonable values. */
+ clmd->sim_parms->gravity [0] = 0.0;
+ clmd->sim_parms->gravity [1] = 0.0;
+ clmd->sim_parms->gravity [2] = -9.81;
+ clmd->sim_parms->structural = 15.0;
+ clmd->sim_parms->shear = 15.0;
+ clmd->sim_parms->bending = 0.5;
+ clmd->sim_parms->Cdis = 5.0;
+ clmd->sim_parms->Cvi = 1.0;
+ clmd->sim_parms->mass = 0.3f;
+ clmd->sim_parms->stepsPerFrame = 5;
+ clmd->sim_parms->sim_time = 1.0;
+ clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT;
+ clmd->sim_parms->solver_type = 0;
+ clmd->sim_parms->preroll = 0;
+ clmd->sim_parms->maxspringlen = 10;
+ clmd->sim_parms->firstframe = 1;
+ clmd->sim_parms->lastframe = 250;
+ clmd->sim_parms->vgroup_mass = 0;
+ clmd->sim_parms->lastcachedframe = 0;
+ clmd->sim_parms->editedframe = 0;
+ clmd->sim_parms->autoprotect = 25;
+ clmd->sim_parms->firstcachedframe = -1.0;
+ clmd->sim_parms->avg_spring_len = 0.0;
+ clmd->sim_parms->presets = 2; /* cotton as start setting */
+
+ clmd->coll_parms->self_friction = 5.0;
+ clmd->coll_parms->friction = 5.0;
+ clmd->coll_parms->loop_count = 3;
+ clmd->coll_parms->epsilon = 0.015f;
+ clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
+ clmd->coll_parms->collision_list = NULL;
+ clmd->coll_parms->self_loop_count = 1.0;
+ clmd->coll_parms->selfepsilon = 0.75;
+
+ /* These defaults are copied from softbody.c's
+ * softbody_calc_forces() function.
+ */
+ clmd->sim_parms->eff_force_scale = 1000.0;
+ clmd->sim_parms->eff_wind_scale = 250.0;
+
+ // also from softbodies
+ clmd->sim_parms->maxgoal = 1.0f;
+ clmd->sim_parms->mingoal = 0.0f;
+ clmd->sim_parms->defgoal = 0.0f;
+ clmd->sim_parms->goalspring = 1.0f;
+ clmd->sim_parms->goalfrict = 0.0f;
+}
+
+
+BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
+{
+ unsigned int i = 0;
+ BVH *bvh=NULL;
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = NULL;
+
+ if(!clmd)
+ return NULL;
+
+ cloth = clmd->clothObject;
+
+ if(!cloth)
+ return NULL;
+
+ verts = cloth->verts;
+
+ // in the moment, return zero if no faces there
+ if(!cloth->numfaces)
+ return NULL;
+
+ bvh = MEM_callocN(sizeof(BVH), "BVH");
+ if (bvh == NULL)
+ {
+ printf("bvh: Out of memory.\n");
+ return NULL;
+ }
+
+ // springs = cloth->springs;
+ // numsprings = cloth->numsprings;
+
+ bvh->flags = 0;
+ bvh->leaf_tree = NULL;
+ bvh->leaf_root = NULL;
+ bvh->tree = NULL;
+
+ bvh->epsilon = epsilon;
+ bvh->numfaces = cloth->numfaces;
+ bvh->mfaces = cloth->mfaces;
+
+ bvh->numverts = cloth->numverts;
+
+ bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
+
+ if (bvh->current_x == NULL)
+ {
+ printf("bvh: Out of memory.\n");
+ MEM_freeN(bvh);
+ return NULL;
+ }
+
+ bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
+
+ if (bvh->current_xold == NULL)
+ {
+ printf("bvh: Out of memory.\n");
+ MEM_freeN(bvh->current_x);
+ MEM_freeN(bvh);
+ return NULL;
+ }
+
+ for(i = 0; i < bvh->numverts; i++)
+ {
+ VECCOPY(bvh->current_x[i].co, verts[i].tx);
+ VECCOPY(bvh->current_xold[i].co, verts[i].txold);
+ }
+
+ bvh_build (bvh);
+
+ return bvh;
+}
+
+void bvh_update_from_cloth(ClothModifierData *clmd, int moving)
+{
+ unsigned int i = 0;
+ Cloth *cloth = clmd->clothObject;
+ BVH *bvh = cloth->tree;
+ ClothVertex *verts = cloth->verts;
+
+ if(!bvh)
+ return;
+
+ if(cloth->numverts!=bvh->numverts)
+ return;
+
+ if(cloth->verts)
+ {
+ for(i = 0; i < bvh->numverts; i++)
+ {
+ VECCOPY(bvh->current_x[i].co, verts[i].tx);
+ VECCOPY(bvh->current_xold[i].co, verts[i].txold);
+ }
+ }
+
+ bvh_update(bvh, moving);
+}
+
+DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm )
+{
+ DerivedMesh *result = NULL;
+ unsigned int i = 0, a = 0, j=0;
+ int numverts = dm->getNumVerts ( dm );
+ int numfaces = dm->getNumFaces ( dm );
+
+ MVert *mvert = CDDM_get_verts ( dm );
+ MFace *mface = CDDM_get_faces ( dm );
+
+ MVert *mvert2;
+ MFace *mface2;
+ EdgeHash *edgehash = NULL;
+ Cloth *cloth = clmd->clothObject;
+ ClothSpring *springs = (ClothSpring *)cloth->springs;
+ unsigned int numsprings = cloth->numsprings;
+
+ // create spring tearing hash
+ edgehash = BLI_edgehash_new();
+
+ for ( i = 0; i < numsprings; i++ )
+ {
+ if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE )
+ && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) )
+ {
+ BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL );
+ BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL );
+ j++;
+ }
+ }
+
+ // printf("found %d tears\n", j);
+
+ result = CDDM_from_template ( dm, numverts, 0, numfaces );
+
+ if ( !result )
+ return NULL;
+
+ // do verts
+ mvert2 = CDDM_get_verts ( result );
+ for ( a=0; a<numverts; a++ )
+ {
+ MVert *inMV;
+ MVert *mv = &mvert2[a];
+
+ inMV = &mvert[a];
+
+ DM_copy_vert_data ( dm, result, a, a, 1 );
+ *mv = *inMV;
+ }
+
+
+ // do faces
+ mface2 = CDDM_get_faces ( result );
+ for ( a=0, i=0; a<numfaces; a++ )
+ {
+ MFace *mf = &mface2[i];
+ MFace *inMF;
+ inMF = &mface[a];
+
+ /*
+ DM_copy_face_data(dm, result, a, i, 1);
+
+ *mf = *inMF;
+ */
+
+ if ( ( !BLI_edgehash_haskey ( edgehash, mface[a].v1, mface[a].v2 ) )
+ && ( !BLI_edgehash_haskey ( edgehash, mface[a].v2, mface[a].v3 ) )
+ && ( !BLI_edgehash_haskey ( edgehash, mface[a].v3, mface[a].v4 ) )
+ && ( !BLI_edgehash_haskey ( edgehash, mface[a].v4, mface[a].v1 ) ) )
+ {
+ mf->v1 = mface[a].v1;
+ mf->v2 = mface[a].v2;
+ mf->v3 = mface[a].v3;
+ mf->v4 = mface[a].v4;
+
+ test_index_face ( mf, NULL, 0, 4 );
+
+ i++;
+ }
+ }
+
+ CDDM_lower_num_faces ( result, i );
+ CDDM_calc_edges ( result );
+ CDDM_calc_normals ( result );
+
+ BLI_edgehash_free ( edgehash, NULL );
+
+ return result;
+}
+
+int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
+
+int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
+{
+ FILE *fp = NULL;
+ int stack_index = -1;
+ unsigned int a, ret = 1;
+ Cloth *cloth = clmd->clothObject;
+
+ if(!cloth)
+ return 0;
+
+ stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
+ if(!fp)
+ ret = 0;
+ else {
+ for(a = 0; a < cloth->numverts; a++)
+ {
+ if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3)
+ {
+ ret = 0;
+ break;
+ }
+ if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3)
+ {
+ ret = 0;
+ break;
+ }
+ if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3)
+ {
+ ret = 0;
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ if(clmd->sim_parms->lastcachedframe < framenr)
+ {
+ if(G.rt > 0)
+ printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe);
+ }
+
+ if(G.rt > 0)
+ printf("cloth_read_cache: %f successfully \n", framenr);
+ }
+
+ if(G.rt > 0)
+ printf("cloth_read_cache: %f\n", framenr);
+
+ return ret;
+}
+
+void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+{
+ int stack_index = -1;
+
+ // don't do anything as long as we're in editmode!
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
+ {
+ /* delete cache free request */
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+
+ return;
+ }
+
+ /* clear cache if specific frame cleaning requested or cache is not protected */
+ if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE))
+ {
+ stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
+
+ BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index);
+
+ /* update last cached frame # */
+ clmd->sim_parms->lastcachedframe = framenr;
+
+ /* update first cached frame # */
+ if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0))
+ clmd->sim_parms->firstcachedframe = -1.0;
+
+ if(G.rt > 0)
+ printf("cloth_clear_cache: %f\n", framenr);
+ }
+
+ /* delete cache free request */
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+
+
+}
+void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
+{
+ FILE *fp = NULL;
+ int stack_index = -1;
+ unsigned int a;
+ Cloth *cloth = clmd->clothObject;
+
+ if(G.rt > 0)
+ printf("cloth_write_cache: %f\n", framenr);
+
+ if(!cloth)
+ {
+ if(G.rt > 0)
+ printf("cloth_write_cache: no cloth\n");
+ return;
+ }
+
+ stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
+ if(!fp)
+ {
+ if(G.rt > 0)
+ printf("cloth_write_cache: no fp\n");
+ return;
+ }
+
+ for(a = 0; a < cloth->numverts; a++)
+ {
+ fwrite(&cloth->verts[a].x, sizeof(float),3,fp);
+ fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp);
+ fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
+ }
+
+ /* update last cached frame # */
+ clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr);
+
+ /* update first cached frame # */
+ if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0)))
+ clmd->sim_parms->firstcachedframe = framenr;
+
+ if(G.rt > 0)
+ printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr);
+
+ fclose(fp);
+}
+
+/************************************************
+ * clothModifier_do - main simulation function
+************************************************/
+DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+
+{
+ unsigned int i;
+ Cloth *cloth = clmd->clothObject;
+ float framenr = G.scene->r.cfra;
+ float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+ ListBase *effectors = NULL;
+ ClothVertex *verts = NULL;
+ float deltaTime = current_time - clmd->sim_parms->sim_time;
+ unsigned int numverts = -1;
+ unsigned int numedges = -1;
+ unsigned int numfaces = -1;
+ MVert *mvert = NULL;
+ MEdge *medge = NULL;
+ MFace *mface = NULL;
+ DerivedMesh *result = NULL;
+ int ret = 0;
+
+ if(G.rt > 0)
+ printf("clothModifier_do start\n");
+
+ /* we're getting called two times during file load,
+ resulting in a not valid G.relbase on the first time (cache makes problems)
+ --> just return back */
+ if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED) && (!G.relbase_valid))
+ {
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED;
+ return dm;
+ }
+
+ result = CDDM_copy(dm);
+
+ if(!result)
+ {
+ return dm;
+ }
+
+ numverts = result->getNumVerts(result);
+ numedges = result->getNumEdges(result);
+ numfaces = result->getNumFaces(result);
+ mvert = dm->getVertArray(result);
+ medge = dm->getEdgeArray(result);
+ mface = dm->getFaceArray(result);
+
+ /* check if cache is active / if file is already saved */
+ /*
+ if ((!G.relbase_valid) && ( deltaTime != 1.0f ))
+ {
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+}
+ */
+
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)
+ {
+ cloth_free_modifier (ob, clmd);
+ if(G.rt > 0)
+ printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
+
+ // prevent rebuilding of cloth each time you move backward
+ if(deltaTime < 0.0)
+ return result;
+ }
+
+ // unused in the moment, calculated seperately in implicit.c
+ clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame;
+
+ if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) )
+ {
+ /* only force free the cache if we have a different number of verts */
+ if(clmd->clothObject && (numverts != clmd->clothObject->numverts ))
+ {
+ if(G.rt > 0)
+ printf("Force Freeing: numverts != clmd->clothObject->numverts\n");
+
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+ cloth_free_modifier ( ob, clmd );
+ }
+
+ cloth_clear_cache(ob, clmd, 0);
+
+ if ( !cloth_from_object ( ob, clmd, result, framenr ) )
+ return result;
+
+ if ( clmd->clothObject == NULL )
+ return result;
+
+ cloth = clmd->clothObject;
+
+ if(!cloth_read_cache(ob, clmd, framenr))
+ {
+ /* save first frame in case we have a reseted object
+ and we move one frame forward.
+ In that case we would only start with the SECOND frame
+ if we don't save the current state before
+ TODO PROBLEM: IMHO we can't track external movement from the
+ first frame in this case! */
+ /*
+ if ( deltaTime == 1.0f )
+ cloth_write_cache(ob, clmd, framenr-1.0);
+ */
+ if(G.rt > 0)
+ printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n");
+ }
+ else
+ {
+ if(G.rt > 0)
+ printf("cloth_from_object cloth_read_cache\n");
+
+ implicit_set_positions(clmd);
+ }
+
+ clmd->sim_parms->sim_time = current_time;
+ }
+
+ // only be active during a specific period:
+ // that's "first frame" and "last frame" on GUI
+ if ( current_time < clmd->sim_parms->firstframe )
+ {
+ if(G.rt > 0)
+ printf("current_time < clmd->sim_parms->firstframe\n");
+ return result;
+ }
+ else if ( current_time > clmd->sim_parms->lastframe )
+ {
+ int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
+
+ if(G.rt > 0)
+ printf("current_time > clmd->sim_parms->lastframe\n");
+
+ if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index))
+ {
+ if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe))
+ {
+ implicit_set_positions(clmd);
+
+ // Copy the result back to the object.
+ cloth_to_object (ob, clmd, result);
+ }
+ }
+ return result;
+ }
+
+ // check for autoprotection, but only if cache active
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
+ {
+ if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
+ {
+ if(G.rt > 0)
+ printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
+
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+ }
+ }
+
+ /* nice moving one frame forward */
+ if ( deltaTime == 1.0f )
+ {
+ clmd->sim_parms->sim_time = current_time;
+
+ if(G.rt > 0)
+ printf("clothModifier_do deltaTime=1\n");
+
+ if(!cloth_read_cache(ob, clmd, framenr))
+ {
+ verts = cloth->verts;
+
+ // Force any pinned verts to their constrained location.
+ for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
+ {
+ // Save the previous position.
+ VECCOPY ( verts->xold, verts->xconst );
+ VECCOPY ( verts->txold, verts->x );
+
+ // Get the current position.
+ VECCOPY ( verts->xconst, mvert[i].co );
+ Mat4MulVecfl ( ob->obmat, verts->xconst );
+ }
+
+ tstart();
+
+ // Call the solver.
+ if ( solvers [clmd->sim_parms->solver_type].solver )
+ {
+ ret = solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors );
+ }
+
+ tend();
+ // printf ( "Cloth simulation time: %f\n", ( float ) tval() );
+
+ if(ret)
+ cloth_write_cache(ob, clmd, framenr);
+ else
+ clmd->sim_parms->sim_time--;
+ }
+ else
+ {
+ if(G.rt > 0)
+ printf("clothModifier_do deltaTime=1 cacheread\n");
+ implicit_set_positions(clmd);
+ }
+
+ // Copy the result back to the object.
+ cloth_to_object (ob, clmd, result);
+ }
+ else if(deltaTime == 0.0f)
+ {
+ if(G.rt > 0)
+ printf("dt = 0, %f\n", framenr);
+ if(cloth_read_cache(ob, clmd, framenr))
+ {
+ cloth_to_object (ob, clmd, result);
+ implicit_set_positions(clmd);
+ }
+ else /* same cache parts are missing */
+ {
+ /* jump to a non-existing frame makes sim reset if cache is not protected */
+ if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+ {
+ /* prevent freeing when used with vectorblur */
+ if(!useRenderParams)
+ {
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+ cloth_clear_cache(ob, clmd, 0);
+
+ cloth_write_cache(ob, clmd, framenr);
+ }
+ }
+ }
+ }
+ else
+ {
+ if(G.rt > 0)
+ printf("dt > 1.0 || dt < 0.0, %f, st: %f, ct: %f\n", framenr, clmd->sim_parms->sim_time, current_time);
+ if(cloth_read_cache(ob, clmd, framenr))
+ {
+ cloth_to_object (ob, clmd, result);
+ implicit_set_positions(clmd);
+ }
+ else
+ {
+ /* jump to a non-existing frame makes sim reset if cache is not protected */
+ if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+ {
+ /* prevent freeing when used with vectorblur */
+ if(!useRenderParams)
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
+ }
+ clmd->sim_parms->sim_time = current_time;
+ }
+
+ return result;
+}
+
+/* frees all */
+void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
+{
+ Cloth *cloth = NULL;
+
+ if ( !clmd )
+ return;
+
+ cloth = clmd->clothObject;
+
+
+ if ( cloth )
+ {
+ // If our solver provides a free function, call it
+ if ( solvers [clmd->sim_parms->solver_type].free )
+ {
+ solvers [clmd->sim_parms->solver_type].free ( clmd );
+ }
+
+ // Free the verts.
+ if ( cloth->verts != NULL )
+ MEM_freeN ( cloth->verts );
+
+ cloth->verts = NULL;
+ cloth->numverts = 0;
+
+ // Free the springs.
+ if ( cloth->springs != NULL )
+ {
+ LinkNode *search = cloth->springs;
+ while(search)
+ {
+ ClothSpring *spring = search->link;
+
+ MEM_freeN ( spring );
+ search = search->next;
+ }
+ BLI_linklist_free(cloth->springs, NULL);
+
+ cloth->springs = NULL;
+ }
+
+ cloth->springs = NULL;
+ cloth->numsprings = 0;
+
+ // free BVH collision tree
+ if ( cloth->tree )
+ bvh_free ( ( BVH * ) cloth->tree );
+
+ // we save our faces for collision objects
+ if ( cloth->mfaces )
+ MEM_freeN ( cloth->mfaces );
+
+ if(cloth->edgehash)
+ BLI_edgehash_free ( cloth->edgehash, NULL );
+
+
+ /*
+ if(clmd->clothObject->facemarks)
+ MEM_freeN(clmd->clothObject->facemarks);
+ */
+ MEM_freeN ( cloth );
+ clmd->clothObject = NULL;
+ }
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET;
+}
+
+/* frees all */
+void cloth_free_modifier_extern ( ClothModifierData *clmd )
+{
+ Cloth *cloth = NULL;
+ if(G.rt > 0)
+ printf("cloth_free_modifier_extern\n");
+
+ if ( !clmd )
+ return;
+
+ cloth = clmd->clothObject;
+
+ if ( cloth )
+ {
+ if(G.rt > 0)
+ printf("cloth_free_modifier_extern in\n");
+
+ // If our solver provides a free function, call it
+ if ( solvers [clmd->sim_parms->solver_type].free )
+ {
+ solvers [clmd->sim_parms->solver_type].free ( clmd );
+ }
+
+ // Free the verts.
+ if ( cloth->verts != NULL )
+ MEM_freeN ( cloth->verts );
+
+ cloth->verts = NULL;
+ cloth->numverts = 0;
+
+ // Free the springs.
+ if ( cloth->springs != NULL )
+ {
+ LinkNode *search = cloth->springs;
+ while(search)
+ {
+ ClothSpring *spring = search->link;
+
+ MEM_freeN ( spring );
+ search = search->next;
+ }
+ BLI_linklist_free(cloth->springs, NULL);
+
+ cloth->springs = NULL;
+ }
+
+ cloth->springs = NULL;
+ cloth->numsprings = 0;
+
+ // free BVH collision tree
+ if ( cloth->tree )
+ bvh_free ( ( BVH * ) cloth->tree );
+
+ // we save our faces for collision objects
+ if ( cloth->mfaces )
+ MEM_freeN ( cloth->mfaces );
+
+ if(cloth->edgehash)
+ BLI_edgehash_free ( cloth->edgehash, NULL );
+
+
+ /*
+ if(clmd->clothObject->facemarks)
+ MEM_freeN(clmd->clothObject->facemarks);
+ */
+ MEM_freeN ( cloth );
+ clmd->clothObject = NULL;
+ }
+}
+
+/******************************************************************************
+*
+* Internal functions.
+*
+******************************************************************************/
+
+/**
+ * cloth_to_object - copies the deformed vertices to the object.
+ *
+ **/
+static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm)
+{
+ unsigned int i = 0;
+ MVert *mvert = NULL;
+ unsigned int numverts;
+ Cloth *cloth = clmd->clothObject;
+
+ if (clmd->clothObject) {
+ /* inverse matrix is not uptodate... */
+ Mat4Invert (ob->imat, ob->obmat);
+
+ mvert = CDDM_get_verts(dm);
+ numverts = dm->getNumVerts(dm);
+
+ for (i = 0; i < numverts; i++)
+ {
+ VECCOPY (mvert[i].co, cloth->verts[i].x);
+ Mat4MulVecfl (ob->imat, mvert[i].co); /* cloth is in global coords */
+ }
+ }
+}
+
+
+/**
+ * cloth_apply_vgroup - applies a vertex group as specified by type
+ *
+ **/
+/* can be optimized to do all groups in one loop */
+static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
+{
+ unsigned int i = 0;
+ unsigned int j = 0;
+ MDeformVert *dvert = NULL;
+ Cloth *clothObj = NULL;
+ unsigned int numverts = dm->getNumVerts ( dm );
+ float goalfac = 0;
+ ClothVertex *verts = NULL;
+
+ clothObj = clmd->clothObject;
+
+ if ( !dm )
+ return;
+
+ numverts = dm->getNumVerts ( dm );
+
+ verts = clothObj->verts;
+
+ if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
+ (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
+ ((clmd->sim_parms->vgroup_mass>0) ||
+ (clmd->sim_parms->vgroup_struct>0)||
+ (clmd->sim_parms->vgroup_bend>0)))
+ {
+ for ( i = 0; i < numverts; i++, verts++ )
+ {
+ dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT );
+ if ( dvert )
+ {
+ for ( j = 0; j < dvert->totweight; j++ )
+ {
+ if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ))
+ {
+ verts->goal = dvert->dw [j].weight;
+ goalfac= 1.0f;
+
+ /*
+ // Kicking goal factor to simplify things...who uses that anyway?
+ // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
+ */
+
+ verts->goal = ( float ) pow ( verts->goal , 4.0f );
+ if ( verts->goal >=SOFTGOALSNAP )
+ {
+ verts->flags |= CLOTH_VERT_FLAG_PINNED;
+ }
+ }
+
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING )
+ {
+ if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1))
+ {
+ verts->struct_stiff = dvert->dw [j].weight;
+ verts->shear_stiff = dvert->dw [j].weight;
+ }
+
+ if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1))
+ {
+ verts->bend_stiff = dvert->dw [j].weight;
+ }
+ }
+ /*
+ // for later
+ if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1))
+ {
+ verts->mass = dvert->dw [j].weight;
+ }
+ */
+ }
+ }
+ }
+ }
+}
+
+static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr)
+{
+ unsigned int i = 0;
+ MVert *mvert = NULL;
+ ClothVertex *verts = NULL;
+ float tnull[3] = {0,0,0};
+ int cache_there = 0;
+ Cloth *cloth = NULL;
+
+ // If we have a clothObject, free it.
+ if ( clmd->clothObject != NULL )
+ {
+ cloth_free_modifier ( ob, clmd );
+ if(G.rt > 0)
+ printf("cloth_free_modifier cloth_from_object\n");
+ }
+
+ // Allocate a new cloth object.
+ clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" );
+ if ( clmd->clothObject )
+ {
+ clmd->clothObject->old_solver_type = 255;
+ // clmd->clothObject->old_collision_type = 255;
+ cloth = clmd->clothObject;
+ clmd->clothObject->edgehash = NULL;
+ }
+ else if ( !clmd->clothObject )
+ {
+ modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." );
+ return 0;
+ }
+
+ // mesh input objects need DerivedMesh
+ if ( !dm )
+ return 0;
+
+ cloth_from_mesh ( ob, clmd, dm );
+
+ if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe))))
+ {
+ // no cache there
+ cache_there = 0;
+ if(G.rt > 0)
+ printf("cache_there = 0\n");
+ }
+ else
+ {
+ // we have a cache
+ cache_there = 1;
+ if(G.rt > 0)
+ printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe);
+ }
+
+ // create springs
+ clmd->clothObject->springs = NULL;
+ clmd->clothObject->numsprings = -1;
+
+ mvert = dm->getVertArray ( dm );
+ verts = clmd->clothObject->verts;
+
+ // set initial values
+ for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
+ {
+ if(!cache_there)
+ {
+ VECCOPY ( verts->x, mvert[i].co );
+ Mat4MulVecfl ( ob->obmat, verts->x );
+ }
+
+ /* no GUI interface yet */
+ verts->mass = clmd->sim_parms->mass;
+ verts->impulse_count = 0;
+
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+ verts->goal= clmd->sim_parms->defgoal;
+ else
+ verts->goal= 0.0f;
+
+ verts->flags = 0;
+ VECCOPY ( verts->xold, verts->x );
+ VECCOPY ( verts->xconst, verts->x );
+ VECCOPY ( verts->txold, verts->x );
+ VecMulf ( verts->v, 0.0f );
+
+ verts->impulse_count = 0;
+ VECCOPY ( verts->impulse, tnull );
+ }
+
+ // apply / set vertex groups
+ // has to be happen before springs are build!
+ cloth_apply_vgroup (clmd, dm);
+
+
+ if ( !cloth_build_springs ( clmd, dm ) )
+ {
+ cloth_free_modifier ( ob, clmd );
+ modifier_setError ( & ( clmd->modifier ), "Can't build springs." );
+ printf("cloth_free_modifier cloth_build_springs\n");
+ return 0;
+ }
+
+ for ( i = 0; i < dm->getNumVerts(dm); i++)
+ {
+ if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO))
+ {
+ cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL);
+ }
+ }
+
+ // init our solver
+ if ( solvers [clmd->sim_parms->solver_type].init )
+ solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
+
+ if(cache_there)
+ implicit_set_positions(clmd);
+
+ clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
+
+ return 1;
+}
+
+
+static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
+{
+ unsigned int numverts = dm->getNumVerts ( dm );
+ unsigned int numfaces = dm->getNumFaces ( dm );
+ MFace *mface = CDDM_get_faces(dm);
+ unsigned int i = 0;
+
+ /* Allocate our vertices. */
+ clmd->clothObject->numverts = numverts;
+ clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
+ if ( clmd->clothObject->verts == NULL )
+ {
+ cloth_free_modifier ( ob, clmd );
+ modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
+ printf("cloth_free_modifier clmd->clothObject->verts\n");
+ return;
+ }
+
+ // save face information
+ clmd->clothObject->numfaces = numfaces;
+ clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" );
+ if ( clmd->clothObject->mfaces == NULL )
+ {
+ cloth_free_modifier ( ob, clmd );
+ modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." );
+ printf("cloth_free_modifier clmd->clothObject->mfaces\n");
+ return;
+ }
+ for ( i = 0; i < numfaces; i++ )
+ memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) );
+
+ /* Free the springs since they can't be correct if the vertices
+ * changed.
+ */
+ if ( clmd->clothObject->springs != NULL )
+ MEM_freeN ( clmd->clothObject->springs );
+
+}
+
+/***************************************************************************************
+* SPRING NETWORK BUILDING IMPLEMENTATION BEGIN
+***************************************************************************************/
+
+// be carefull: implicit solver has to be resettet when using this one!
+// --> only for implicit handling of this spring!
+int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothSpring *spring = NULL;
+
+ if(cloth)
+ {
+ // TODO: look if this spring is already there
+
+ spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if(!spring)
+ return 0;
+
+ spring->ij = indexA;
+ spring->kl = indexB;
+ spring->restlen = restlength;
+ spring->type = spring_type;
+ spring->flags = 0;
+ spring->stiffness = 0;
+
+ cloth->numsprings++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+
+ return 1;
+ }
+ return 0;
+}
+
+void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
+{
+ unsigned int i = 0;
+
+ if ( cloth->springs != NULL )
+ {
+ LinkNode *search = cloth->springs;
+ while(search)
+ {
+ ClothSpring *spring = search->link;
+
+ MEM_freeN ( spring );
+ search = search->next;
+ }
+ BLI_linklist_free(cloth->springs, NULL);
+
+ cloth->springs = NULL;
+ }
+
+ if(edgelist)
+ {
+ for ( i = 0; i < cloth->numverts; i++ )
+ {
+ BLI_linklist_free ( edgelist[i],NULL );
+ }
+
+ MEM_freeN ( edgelist );
+ }
+
+ if(cloth->edgehash)
+ BLI_edgehash_free ( cloth->edgehash, NULL );
+}
+
+int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
+ unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
+ unsigned int i = 0;
+ unsigned int numverts = dm->getNumVerts ( dm );
+ unsigned int numedges = dm->getNumEdges ( dm );
+ unsigned int numfaces = dm->getNumFaces ( dm );
+ MEdge *medge = CDDM_get_edges ( dm );
+ MFace *mface = CDDM_get_faces ( dm );
+ unsigned int index2 = 0; // our second vertex index
+ LinkNode **edgelist = NULL;
+ EdgeHash *edgehash = NULL;
+ LinkNode *search = NULL, *search2 = NULL;
+ float temp[3];
+
+ // error handling
+ if ( numedges==0 )
+ return 0;
+
+ cloth->springs = NULL;
+
+ edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" );
+
+ if(!edgelist)
+ return 0;
+
+ for ( i = 0; i < numverts; i++ )
+ {
+ edgelist[i] = NULL;
+ }
+
+ if ( cloth->springs )
+ MEM_freeN ( cloth->springs );
+
+ // create spring network hash
+ edgehash = BLI_edgehash_new();
+
+ // structural springs
+ for ( i = 0; i < numedges; i++ )
+ {
+ spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if ( spring )
+ {
+ spring->ij = MIN2(medge[i].v1, medge[i].v2);
+ spring->kl = MAX2(medge[i].v2, medge[i].v1);
+ VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ spring->restlen = sqrt ( INPR ( temp, temp ) );
+ clmd->sim_parms->avg_spring_len += spring->restlen;
+ cloth->verts[spring->ij].avg_spring_len += spring->restlen;
+ cloth->verts[spring->kl].avg_spring_len += spring->restlen;
+ cloth->verts[spring->ij].spring_count++;
+ cloth->verts[spring->kl].spring_count++;
+ spring->type = CLOTH_SPRING_TYPE_STRUCTURAL;
+ spring->flags = 0;
+ spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0;
+ struct_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+ }
+ else
+ {
+ cloth_free_errorsprings(cloth, edgehash, edgelist);
+ return 0;
+ }
+ }
+
+ if(struct_springs > 0)
+ clmd->sim_parms->avg_spring_len /= struct_springs;
+
+ for(i = 0; i < numverts; i++)
+ {
+ cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49 / ((float)cloth->verts[i].spring_count);
+ }
+
+ // shear springs
+ for ( i = 0; i < numfaces; i++ )
+ {
+ // triangle faces already have shear springs due to structural geometry
+ if ( !mface[i].v4 )
+ continue;
+
+ spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if(!spring)
+ {
+ cloth_free_errorsprings(cloth, edgehash, edgelist);
+ return 0;
+ }
+
+ spring->ij = MIN2(mface[i].v1, mface[i].v3);
+ spring->kl = MAX2(mface[i].v3, mface[i].v1);
+ VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ spring->restlen = sqrt ( INPR ( temp, temp ) );
+ spring->type = CLOTH_SPRING_TYPE_SHEAR;
+ spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
+
+ BLI_linklist_append ( &edgelist[spring->ij], spring );
+ BLI_linklist_append ( &edgelist[spring->kl], spring );
+ shear_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+
+
+ // if ( mface[i].v4 ) --> Quad face
+ spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if(!spring)
+ {
+ cloth_free_errorsprings(cloth, edgehash, edgelist);
+ return 0;
+ }
+
+ spring->ij = MIN2(mface[i].v2, mface[i].v4);
+ spring->kl = MAX2(mface[i].v4, mface[i].v2);
+ VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ spring->restlen = sqrt ( INPR ( temp, temp ) );
+ spring->type = CLOTH_SPRING_TYPE_SHEAR;
+ spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
+
+ BLI_linklist_append ( &edgelist[spring->ij], spring );
+ BLI_linklist_append ( &edgelist[spring->kl], spring );
+ shear_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+ }
+
+ // 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 )
+ {
+ 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;
+ }
+
+ /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
+ for ( i = 0; i < numedges; i++ ) // struct springs
+ BLI_edgehash_insert ( edgehash, MIN2(medge[i].v1, medge[i].v2), MAX2(medge[i].v2, medge[i].v1), NULL );
+
+ for ( i = 0; i < numfaces; i++ ) // edge springs
+ {
+ if(mface[i].v4)
+ {
+ BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL );
+
+ BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL );
+ }
+ }
+
+
+ cloth->numsprings = struct_springs + shear_springs + bend_springs;
+
+ if ( edgelist )
+ {
+ for ( i = 0; i < numverts; i++ )
+ {
+ BLI_linklist_free ( edgelist[i],NULL );
+ }
+
+ MEM_freeN ( edgelist );
+ }
+
+ cloth->edgehash = edgehash;
+
+ if(G.rt>0)
+ printf("avg_len: %f\n",clmd->sim_parms->avg_spring_len);
+
+ return 1;
+
+} /* cloth_build_springs */
+/***************************************************************************************
+* SPRING NETWORK BUILDING IMPLEMENTATION END
+***************************************************************************************/
+
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
new file mode 100644
index 00000000000..f9391a0adb8
--- /dev/null
+++ b/source/blender/blenkernel/intern/collision.c
@@ -0,0 +1,1240 @@
+/* collision.c
+*
+*
+* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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) Blender Foundation
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "MEM_guardedalloc.h"
+/* types */
+#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_cloth_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_edgehash.h"
+#include "BLI_linklist.h"
+#include "BKE_curve.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_cloth.h"
+#include "BKE_modifier.h"
+#include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
+#include "DNA_screen_types.h"
+#include "BSE_headerbuttons.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "mydevice.h"
+
+#include "Bullet-C-Api.h"
+
+/***********************************
+Collision modifier code start
+***********************************/
+
+/* step is limited from 0 (frame start position) to 1 (frame end position) */
+void collision_move_object(CollisionModifierData *collmd, float step, float prevstep)
+{
+ float tv[3] = {0,0,0};
+ unsigned int i = 0;
+
+ for ( i = 0; i < collmd->numverts; i++ )
+ {
+ VECSUB(tv, collmd->xnew[i].co, collmd->x[i].co);
+ VECADDS(collmd->current_x[i].co, collmd->x[i].co, tv, prevstep);
+ VECADDS(collmd->current_xnew[i].co, collmd->x[i].co, tv, step);
+ VECSUB(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co);
+ }
+}
+
+/* build bounding volume hierarchy from mverts (see kdop.c for whole BVH code) */
+BVH *bvh_build_from_mvert (MFace *mfaces, unsigned int numfaces, MVert *x, unsigned int numverts, float epsilon)
+{
+ BVH *bvh=NULL;
+
+ bvh = MEM_callocN(sizeof(BVH), "BVH");
+ if (bvh == NULL)
+ {
+ printf("bvh: Out of memory.\n");
+ return NULL;
+ }
+
+ // in the moment, return zero if no faces there
+ if(!numfaces)
+ return NULL;
+
+ bvh->flags = 0;
+ bvh->leaf_tree = NULL;
+ bvh->leaf_root = NULL;
+ bvh->tree = NULL;
+
+ bvh->epsilon = epsilon;
+ bvh->numfaces = numfaces;
+ bvh->mfaces = mfaces;
+
+ // we have no faces, we save seperate points
+ if(!mfaces)
+ {
+ bvh->numfaces = numverts;
+ }
+
+ bvh->numverts = numverts;
+ bvh->current_x = MEM_dupallocN(x);
+ bvh->current_xold = MEM_dupallocN(x);
+
+ bvh_build(bvh);
+
+ return bvh;
+}
+
+void bvh_update_from_mvert(BVH * bvh, MVert *x, unsigned int numverts, MVert *xnew, int moving)
+{
+ if(!bvh)
+ return;
+
+ if(numverts!=bvh->numverts)
+ return;
+
+ if(x)
+ memcpy(bvh->current_xold, x, sizeof(MVert) * numverts);
+
+ if(xnew)
+ memcpy(bvh->current_x, xnew, sizeof(MVert) * numverts);
+
+ bvh_update(bvh, moving);
+}
+
+/***********************************
+Collision modifier code end
+***********************************/
+
+/**
+ * gsl_poly_solve_cubic -
+ *
+ * copied from SOLVE_CUBIC.C --> GSL
+ */
+
+/* DG: debug hint! don't forget that all functions were "fabs", "sinf", etc before */
+#define mySWAP(a,b) { float tmp = b ; b = a ; a = tmp ; }
+
+int gsl_poly_solve_cubic (float a, float b, float c, float *x0, float *x1, float *x2)
+{
+ float q = (a * a - 3 * b);
+ float r = (2 * a * a * a - 9 * a * b + 27 * c);
+
+ float Q = q / 9;
+ float R = r / 54;
+
+ float Q3 = Q * Q * Q;
+ float R2 = R * R;
+
+ float CR2 = 729 * r * r;
+ float CQ3 = 2916 * q * q * q;
+
+ if (R == 0 && Q == 0)
+ {
+ *x0 = - a / 3 ;
+ *x1 = - a / 3 ;
+ *x2 = - a / 3 ;
+ return 3 ;
+ }
+ else if (CR2 == CQ3)
+ {
+ /* this test is actually R2 == Q3, written in a form suitable
+ for exact computation with integers */
+
+ /* Due to finite precision some float roots may be missed, and
+ considered to be a pair of complex roots z = x +/- epsilon i
+ close to the real axis. */
+
+ float sqrtQ = sqrt (Q);
+
+ if (R > 0)
+ {
+ *x0 = -2 * sqrtQ - a / 3;
+ *x1 = sqrtQ - a / 3;
+ *x2 = sqrtQ - a / 3;
+ }
+ else
+ {
+ *x0 = - sqrtQ - a / 3;
+ *x1 = - sqrtQ - a / 3;
+ *x2 = 2 * sqrtQ - a / 3;
+ }
+ return 3 ;
+ }
+ else if (CR2 < CQ3) /* equivalent to R2 < Q3 */
+ {
+ float sqrtQ = sqrt (Q);
+ float sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
+ float theta = acos (R / sqrtQ3);
+ float norm = -2 * sqrtQ;
+ *x0 = norm * cos (theta / 3) - a / 3;
+ *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3;
+ *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3;
+
+ /* Sort *x0, *x1, *x2 into increasing order */
+
+ if (*x0 > *x1)
+ mySWAP(*x0, *x1) ;
+
+ if (*x1 > *x2)
+ {
+ mySWAP(*x1, *x2) ;
+
+ if (*x0 > *x1)
+ mySWAP(*x0, *x1) ;
+ }
+
+ return 3;
+ }
+ else
+ {
+ float sgnR = (R >= 0 ? 1 : -1);
+ float A = -sgnR * pow (ABS (R) + sqrt (R2 - Q3), 1.0/3.0);
+ float B = Q / A ;
+ *x0 = A + B - a / 3;
+ return 1;
+ }
+}
+
+
+/**
+ * gsl_poly_solve_quadratic
+ *
+ * copied from GSL
+ */
+int gsl_poly_solve_quadratic (float a, float b, float c, float *x0, float *x1)
+{
+ float disc = b * b - 4 * a * c;
+
+ if (disc > 0)
+ {
+ if (b == 0)
+ {
+ float r = ABS (0.5 * sqrt (disc) / a);
+ *x0 = -r;
+ *x1 = r;
+ }
+ else
+ {
+ float sgnb = (b > 0 ? 1 : -1);
+ float temp = -0.5 * (b + sgnb * sqrt (disc));
+ float r1 = temp / a ;
+ float r2 = c / temp ;
+
+ if (r1 < r2)
+ {
+ *x0 = r1 ;
+ *x1 = r2 ;
+ }
+ else
+ {
+ *x0 = r2 ;
+ *x1 = r1 ;
+ }
+ }
+ return 2;
+ }
+ else if (disc == 0)
+ {
+ *x0 = -0.5 * b / a ;
+ *x1 = -0.5 * b / a ;
+ return 2 ;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+
+/*
+ * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
+ * page 4, left column
+ */
+
+int cloth_get_collision_time(float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3])
+{
+ int num_sols = 0;
+
+ float g = -a[2] * c[1] * e[0] + a[1] * c[2] * e[0] +
+ a[2] * c[0] * e[1] - a[0] * c[2] * e[1] -
+ a[1] * c[0] * e[2] + a[0] * c[1] * e[2];
+
+ float h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] +
+ a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] +
+ a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] +
+ b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] -
+ a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] -
+ a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2];
+
+ float i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] +
+ b[2] * d[0] * e[1] - b[0] * d[2] * e[1] -
+ b[1] * d[0] * e[2] + b[0] * d[1] * e[2] -
+ b[2] * c[1] * f[0] + b[1] * c[2] * f[0] -
+ a[2] * d[1] * f[0] + a[1] * d[2] * f[0] +
+ b[2] * c[0] * f[1] - b[0] * c[2] * f[1] +
+ a[2] * d[0] * f[1] - a[0] * d[2] * f[1] -
+ b[1] * c[0] * f[2] + b[0] * c[1] * f[2] -
+ a[1] * d[0] * f[2] + a[0] * d[1] * f[2];
+
+ float j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] +
+ b[2] * d[0] * f[1] - b[0] * d[2] * f[1] -
+ b[1] * d[0] * f[2] + b[0] * d[1] * f[2];
+
+ // Solve cubic equation to determine times t1, t2, t3, when the collision will occur.
+ if(ABS(j) > ALMOST_ZERO)
+ {
+ i /= j;
+ h /= j;
+ g /= j;
+
+ num_sols = gsl_poly_solve_cubic(i, h, g, &solution[0], &solution[1], &solution[2]);
+ }
+ else if(ABS(i) > ALMOST_ZERO)
+ {
+ num_sols = gsl_poly_solve_quadratic(i, h, g, &solution[0], &solution[1]);
+ solution[2] = -1.0;
+ }
+ else if(ABS(h) > ALMOST_ZERO)
+ {
+ solution[0] = -g / h;
+ solution[1] = solution[2] = -1.0;
+ num_sols = 1;
+ }
+ else if(ABS(g) > ALMOST_ZERO)
+ {
+ solution[0] = 0;
+ solution[1] = solution[2] = -1.0;
+ num_sols = 1;
+ }
+
+ // Discard negative solutions
+ if ((num_sols >= 1) && (solution[0] < 0))
+ {
+ --num_sols;
+ solution[0] = solution[num_sols];
+ }
+ if ((num_sols >= 2) && (solution[1] < 0))
+ {
+ --num_sols;
+ solution[1] = solution[num_sols];
+ }
+ if ((num_sols == 3) && (solution[2] < 0))
+ {
+ --num_sols;
+ }
+
+ // Sort
+ if (num_sols == 2)
+ {
+ if (solution[0] > solution[1])
+ {
+ double tmp = solution[0];
+ solution[0] = solution[1];
+ solution[1] = tmp;
+ }
+ }
+ else if (num_sols == 3)
+ {
+
+ // Bubblesort
+ if (solution[0] > solution[1]) {
+ double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp;
+ }
+ if (solution[1] > solution[2]) {
+ double tmp = solution[1]; solution[1] = solution[2]; solution[2] = tmp;
+ }
+ if (solution[0] > solution[1]) {
+ double tmp = solution[0]; solution[0] = solution[1]; solution[1] = tmp;
+ }
+ }
+
+ return num_sols;
+}
+
+// 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)
+{
+ double tempV1[3], tempV2[3], tempV4[3];
+ double a,b,c,d,e,f;
+
+ VECSUB (tempV1, p1, p3);
+ VECSUB (tempV2, p2, p3);
+ VECSUB (tempV4, pv, p3);
+
+ a = INPR (tempV1, tempV1);
+ b = INPR (tempV1, tempV2);
+ c = INPR (tempV2, tempV2);
+ e = INPR (tempV1, tempV4);
+ f = INPR (tempV2, tempV4);
+
+ d = (a * c - b * b);
+
+ if (ABS(d) < ALMOST_ZERO) {
+ *w1 = *w2 = *w3 = 1.0 / 3.0;
+ return;
+ }
+
+ w1[0] = (float)((e * c - b * f) / d);
+
+ if(w1[0] < 0)
+ w1[0] = 0;
+
+ w2[0] = (float)((f - b * (double)w1[0]) / c);
+
+ if(w2[0] < 0)
+ w2[0] = 0;
+
+ w3[0] = 1.0f - w1[0] - w2[0];
+}
+
+DO_INLINE void collision_interpolateOnTriangle(float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3)
+{
+ to[0] = to[1] = to[2] = 0;
+ VECADDMUL(to, v1, w1);
+ VECADDMUL(to, v2, w2);
+ VECADDMUL(to, v3, w3);
+}
+
+int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd)
+{
+ int result = 0;
+ LinkNode *search = NULL;
+ CollPair *collpair = NULL;
+ Cloth *cloth1;
+ float w1, w2, w3, u1, u2, u3;
+ float v1[3], v2[3], relativeVelocity[3];
+ float magrelVel;
+
+ cloth1 = clmd->clothObject;
+
+ search = clmd->coll_parms->collision_list;
+
+ while(search)
+ {
+ collpair = search->link;
+
+ // compute barycentric coordinates for both collision points
+ collision_compute_barycentric(collpair->pa,
+ cloth1->verts[collpair->ap1].txold,
+ cloth1->verts[collpair->ap2].txold,
+ cloth1->verts[collpair->ap3].txold,
+ &w1, &w2, &w3);
+
+ // was: txold
+ collision_compute_barycentric(collpair->pb,
+ collmd->current_x[collpair->bp1].co,
+ collmd->current_x[collpair->bp2].co,
+ collmd->current_x[collpair->bp3].co,
+ &u1, &u2, &u3);
+
+ // Calculate relative "velocity".
+ collision_interpolateOnTriangle(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3);
+
+ collision_interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3);
+
+ VECSUB(relativeVelocity, v2, v1);
+
+ // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+ magrelVel = INPR(relativeVelocity, collpair->normal);
+
+ // printf("magrelVel: %f\n", magrelVel);
+
+ // Calculate masses of points.
+ // TODO
+
+ // If v_n_mag < 0 the edges are approaching each other.
+ if(magrelVel > ALMOST_ZERO)
+ {
+ // Calculate Impulse magnitude to stop all motion in normal direction.
+ float magtangent = 0, repulse = 0, d = 0;
+ double impulse = 0.0;
+ float vrel_t_pre[3];
+ float temp[3];
+
+ // calculate tangential velocity
+ VECCOPY(temp, collpair->normal);
+ VecMulf(temp, magrelVel);
+ VECSUB(vrel_t_pre, relativeVelocity, temp);
+
+ // Decrease in magnitude of relative tangential velocity due to coulomb friction
+ // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+ magtangent = MIN2(clmd->coll_parms->friction * 0.01 * magrelVel,sqrt(INPR(vrel_t_pre,vrel_t_pre)));
+
+ // Apply friction impulse.
+ if (magtangent > ALMOST_ZERO)
+ {
+ Normalize(vrel_t_pre);
+
+ impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+ VECADDMUL(cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse);
+ VECADDMUL(cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse);
+ VECADDMUL(cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse);
+ }
+
+ // Apply velocity stopping impulse
+ // I_c = m * v_N / 2.0
+ // no 2.0 * magrelVel normally, but looks nicer DG
+ impulse = magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+
+ VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
+ cloth1->verts[collpair->ap1].impulse_count++;
+
+ VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
+ cloth1->verts[collpair->ap2].impulse_count++;
+
+ VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
+ cloth1->verts[collpair->ap3].impulse_count++;
+
+ // Apply repulse impulse if distance too short
+ // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+ d = clmd->coll_parms->epsilon*8.0/9.0 - collpair->distance;
+ if((magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame) && (d > ALMOST_ZERO))
+ {
+ repulse = MIN2(d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
+
+ // stay on the safe side and clamp repulse
+ if(impulse > ALMOST_ZERO)
+ repulse = MIN2(repulse, 5.0*impulse);
+ repulse = MAX2(impulse, repulse);
+
+ impulse = repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3); // original 2.0 / 0.25
+ VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, impulse);
+ VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, impulse);
+ VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, impulse);
+ }
+
+ result = 1;
+ }
+
+ search = search->next;
+ }
+
+
+ return result;
+}
+
+int cloth_collision_response_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+ return 1;
+}
+
+
+int cloth_collision_response_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd)
+{
+ return 1;
+}
+
+void cloth_collision_static(ModifierData *md1, ModifierData *md2, CollisionTree *tree1, CollisionTree *tree2)
+{
+ ClothModifierData *clmd = (ClothModifierData *)md1;
+ CollisionModifierData *collmd = (CollisionModifierData *)md2;
+ CollPair *collpair = NULL;
+ Cloth *cloth1=NULL;
+ MFace *face1=NULL, *face2=NULL;
+ ClothVertex *verts1=NULL;
+ double distance = 0;
+ float epsilon = clmd->coll_parms->epsilon;
+ unsigned int i = 0;
+
+ for(i = 0; i < 4; i++)
+ {
+ collpair = (CollPair *)MEM_callocN(sizeof(CollPair), "cloth coll pair");
+
+ cloth1 = clmd->clothObject;
+
+ verts1 = cloth1->verts;
+
+ face1 = &(cloth1->mfaces[tree1->tri_index]);
+ face2 = &(collmd->mfaces[tree2->tri_index]);
+
+ // check all possible pairs of triangles
+ if(i == 0)
+ {
+ collpair->ap1 = face1->v1;
+ collpair->ap2 = face1->v2;
+ collpair->ap3 = face1->v3;
+
+ collpair->bp1 = face2->v1;
+ collpair->bp2 = face2->v2;
+ collpair->bp3 = face2->v3;
+
+ }
+
+ if(i == 1)
+ {
+ if(face1->v4)
+ {
+ collpair->ap1 = face1->v3;
+ collpair->ap2 = face1->v4;
+ collpair->ap3 = face1->v1;
+
+ collpair->bp1 = face2->v1;
+ collpair->bp2 = face2->v2;
+ collpair->bp3 = face2->v3;
+ }
+ else
+ i++;
+ }
+
+ if(i == 2)
+ {
+ if(face2->v4)
+ {
+ collpair->ap1 = face1->v1;
+ collpair->ap2 = face1->v2;
+ collpair->ap3 = face1->v3;
+
+ collpair->bp1 = face2->v3;
+ collpair->bp2 = face2->v4;
+ collpair->bp3 = face2->v1;
+ }
+ else
+ i+=2;
+ }
+
+ if(i == 3)
+ {
+ if((face1->v4)&&(face2->v4))
+ {
+ collpair->ap1 = face1->v3;
+ collpair->ap2 = face1->v4;
+ collpair->ap3 = face1->v1;
+
+ collpair->bp1 = face2->v3;
+ collpair->bp2 = face2->v4;
+ collpair->bp3 = face2->v1;
+ }
+ else
+ i++;
+ }
+
+ // calc SIPcode (?)
+
+ if(i < 4)
+ {
+ // calc distance + normal
+#if WITH_BULLET == 1
+ distance = plNearestPoints(
+ verts1[collpair->ap1].txold, verts1[collpair->ap2].txold, verts1[collpair->ap3].txold, collmd->current_x[collpair->bp1].co, collmd->current_x[collpair->bp2].co, collmd->current_x[collpair->bp3].co, collpair->pa,collpair->pb,collpair->vector);
+#else
+ // just be sure that we don't add anything
+ distance = 2.0 * (epsilon + ALMOST_ZERO);
+#endif
+ if (distance <= (epsilon + ALMOST_ZERO))
+ {
+ // printf("dist: %f\n", (float)distance);
+
+ // collpair->face1 = tree1->tri_index;
+ // collpair->face2 = tree2->tri_index;
+
+ VECCOPY(collpair->normal, collpair->vector);
+ Normalize(collpair->normal);
+
+ collpair->distance = distance;
+ BLI_linklist_prepend(&clmd->coll_parms->collision_list, collpair);
+
+ }
+ else
+ {
+ MEM_freeN(collpair);
+ }
+ }
+ else
+ {
+ MEM_freeN(collpair);
+ }
+ }
+}
+
+int cloth_are_edges_adjacent(ClothModifierData *clmd, ClothModifierData *coll_clmd, EdgeCollPair *edgecollpair)
+{
+ Cloth *cloth1 = NULL, *cloth2 = NULL;
+ ClothVertex *verts1 = NULL, *verts2 = NULL;
+ float temp[3];
+
+ cloth1 = clmd->clothObject;
+ cloth2 = coll_clmd->clothObject;
+
+ verts1 = cloth1->verts;
+ verts2 = cloth2->verts;
+
+ VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p21].xold);
+ if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+ return 1;
+
+ VECSUB(temp, verts1[edgecollpair->p11].xold, verts2[edgecollpair->p22].xold);
+ if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+ return 1;
+
+ VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p21].xold);
+ if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+ return 1;
+
+ VECSUB(temp, verts1[edgecollpair->p12].xold, verts2[edgecollpair->p22].xold);
+ if(ABS(INPR(temp, temp)) < ALMOST_ZERO)
+ return 1;
+
+ return 0;
+}
+
+void cloth_collision_moving_edges(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+ EdgeCollPair edgecollpair;
+ Cloth *cloth1=NULL, *cloth2=NULL;
+ MFace *face1=NULL, *face2=NULL;
+ ClothVertex *verts1=NULL, *verts2=NULL;
+ unsigned int i = 0, j = 0, k = 0;
+ int numsolutions = 0;
+ float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+
+ cloth1 = clmd->clothObject;
+ cloth2 = coll_clmd->clothObject;
+
+ verts1 = cloth1->verts;
+ verts2 = cloth2->verts;
+
+ face1 = &(cloth1->mfaces[tree1->tri_index]);
+ face2 = &(cloth2->mfaces[tree2->tri_index]);
+
+ for( i = 0; i < 5; i++)
+ {
+ if(i == 0)
+ {
+ edgecollpair.p11 = face1->v1;
+ edgecollpair.p12 = face1->v2;
+ }
+ else if(i == 1)
+ {
+ edgecollpair.p11 = face1->v2;
+ edgecollpair.p12 = face1->v3;
+ }
+ else if(i == 2)
+ {
+ if(face1->v4)
+ {
+ edgecollpair.p11 = face1->v3;
+ edgecollpair.p12 = face1->v4;
+ }
+ else
+ {
+ edgecollpair.p11 = face1->v3;
+ edgecollpair.p12 = face1->v1;
+ i+=5; // get out of here after this edge pair is handled
+ }
+ }
+ else if(i == 3)
+ {
+ if(face1->v4)
+ {
+ edgecollpair.p11 = face1->v4;
+ edgecollpair.p12 = face1->v1;
+ }
+ else
+ continue;
+ }
+ else
+ {
+ edgecollpair.p11 = face1->v3;
+ edgecollpair.p12 = face1->v1;
+ }
+
+
+ for( j = 0; j < 5; j++)
+ {
+ if(j == 0)
+ {
+ edgecollpair.p21 = face2->v1;
+ edgecollpair.p22 = face2->v2;
+ }
+ else if(j == 1)
+ {
+ edgecollpair.p21 = face2->v2;
+ edgecollpair.p22 = face2->v3;
+ }
+ else if(j == 2)
+ {
+ if(face2->v4)
+ {
+ edgecollpair.p21 = face2->v3;
+ edgecollpair.p22 = face2->v4;
+ }
+ else
+ {
+ edgecollpair.p21 = face2->v3;
+ edgecollpair.p22 = face2->v1;
+ }
+ }
+ else if(j == 3)
+ {
+ if(face2->v4)
+ {
+ edgecollpair.p21 = face2->v4;
+ edgecollpair.p22 = face2->v1;
+ }
+ else
+ continue;
+ }
+ else
+ {
+ edgecollpair.p21 = face2->v3;
+ edgecollpair.p22 = face2->v1;
+ }
+
+
+ if(!cloth_are_edges_adjacent(clmd, coll_clmd, &edgecollpair))
+ {
+ VECSUB(a, verts1[edgecollpair.p12].xold, verts1[edgecollpair.p11].xold);
+ VECSUB(b, verts1[edgecollpair.p12].v, verts1[edgecollpair.p11].v);
+ VECSUB(c, verts1[edgecollpair.p21].xold, verts1[edgecollpair.p11].xold);
+ VECSUB(d, verts1[edgecollpair.p21].v, verts1[edgecollpair.p11].v);
+ VECSUB(e, verts2[edgecollpair.p22].xold, verts1[edgecollpair.p11].xold);
+ VECSUB(f, verts2[edgecollpair.p22].v, verts1[edgecollpair.p11].v);
+
+ numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
+
+ for (k = 0; k < numsolutions; k++)
+ {
+ if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
+ {
+ //float out_collisionTime = solution[k];
+
+ // TODO: check for collisions
+
+ // TODO: put into (edge) collision list
+
+ // printf("Moving edge found!\n");
+ }
+ }
+ }
+ }
+ }
+}
+
+void cloth_collision_moving_tris(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+ CollPair collpair;
+ Cloth *cloth1=NULL, *cloth2=NULL;
+ MFace *face1=NULL, *face2=NULL;
+ ClothVertex *verts1=NULL, *verts2=NULL;
+ unsigned int i = 0, j = 0, k = 0;
+ int numsolutions = 0;
+ float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+
+ for(i = 0; i < 2; i++)
+ {
+ cloth1 = clmd->clothObject;
+ cloth2 = coll_clmd->clothObject;
+
+ verts1 = cloth1->verts;
+ verts2 = cloth2->verts;
+
+ face1 = &(cloth1->mfaces[tree1->tri_index]);
+ face2 = &(cloth2->mfaces[tree2->tri_index]);
+
+ // check all possible pairs of triangles
+ if(i == 0)
+ {
+ collpair.ap1 = face1->v1;
+ collpair.ap2 = face1->v2;
+ collpair.ap3 = face1->v3;
+
+ collpair.pointsb[0] = face2->v1;
+ collpair.pointsb[1] = face2->v2;
+ collpair.pointsb[2] = face2->v3;
+ collpair.pointsb[3] = face2->v4;
+ }
+
+ if(i == 1)
+ {
+ if(face1->v4)
+ {
+ collpair.ap1 = face1->v3;
+ collpair.ap2 = face1->v4;
+ collpair.ap3 = face1->v1;
+
+ collpair.pointsb[0] = face2->v1;
+ collpair.pointsb[1] = face2->v2;
+ collpair.pointsb[2] = face2->v3;
+ collpair.pointsb[3] = face2->v4;
+ }
+ else
+ i++;
+ }
+
+ // calc SIPcode (?)
+
+ if(i < 2)
+ {
+ VECSUB(a, verts1[collpair.ap2].xold, verts1[collpair.ap1].xold);
+ VECSUB(b, verts1[collpair.ap2].v, verts1[collpair.ap1].v);
+ VECSUB(c, verts1[collpair.ap3].xold, verts1[collpair.ap1].xold);
+ VECSUB(d, verts1[collpair.ap3].v, verts1[collpair.ap1].v);
+
+ for(j = 0; j < 4; j++)
+ {
+ if((j==3) && !(face2->v4))
+ break;
+
+ VECSUB(e, verts2[collpair.pointsb[j]].xold, verts1[collpair.ap1].xold);
+ VECSUB(f, verts2[collpair.pointsb[j]].v, verts1[collpair.ap1].v);
+
+ numsolutions = cloth_get_collision_time(a, b, c, d, e, f, solution);
+
+ for (k = 0; k < numsolutions; k++)
+ {
+ if ((solution[k] >= 0.0) && (solution[k] <= 1.0))
+ {
+ //float out_collisionTime = solution[k];
+
+ // TODO: check for collisions
+
+ // TODO: put into (point-face) collision list
+
+ // printf("Moving found!\n");
+
+ }
+ }
+
+ // TODO: check borders for collisions
+ }
+
+ }
+ }
+}
+
+void cloth_collision_moving(ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2)
+{
+ // TODO: check for adjacent
+ cloth_collision_moving_edges(clmd, coll_clmd, tree1, tree2);
+
+ cloth_collision_moving_tris(clmd, coll_clmd, tree1, tree2);
+ cloth_collision_moving_tris(coll_clmd, clmd, tree2, tree1);
+}
+
+void cloth_free_collision_list(ClothModifierData *clmd)
+{
+ // free collision list
+ if(clmd->coll_parms->collision_list)
+ {
+ LinkNode *search = clmd->coll_parms->collision_list;
+ while(search)
+ {
+ CollPair *coll_pair = search->link;
+
+ MEM_freeN(coll_pair);
+ search = search->next;
+ }
+ BLI_linklist_free(clmd->coll_parms->collision_list,NULL);
+
+ clmd->coll_parms->collision_list = NULL;
+ }
+}
+
+int cloth_bvh_objcollisions_do(ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt)
+{
+ Cloth *cloth = clmd->clothObject;
+ BVH *cloth_bvh=(BVH *) cloth->tree;
+ long i=0, j = 0, numfaces = 0, numverts = 0;
+ ClothVertex *verts = NULL;
+ int ret = 0;
+ unsigned int result = 0;
+ float tnull[3] = {0,0,0};
+
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ verts = cloth->verts;
+
+ if (collmd->tree)
+ {
+ BVH *coll_bvh = collmd->tree;
+
+ collision_move_object(collmd, step + dt, step);
+
+ bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0);
+ }
+ else
+ {
+ if(G.rt > 0)
+ printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+ }
+
+ // process all collisions (calculate impulses, TODO: also repulses if distance too short)
+ result = 1;
+ for(j = 0; j < 5; j++) // 5 is just a value that ensures convergence
+ {
+ result = 0;
+
+ if (collmd->tree)
+ result += cloth_collision_response_static(clmd, collmd);
+
+ // apply impulses in parallel
+ if(result)
+ for(i = 0; i < numverts; i++)
+ {
+ // calculate "velocities" (just xnew = xold + v; no dt in v)
+ if(verts[i].impulse_count)
+ {
+ VECADDMUL(verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count);
+ VECCOPY(verts[i].impulse, tnull);
+ verts[i].impulse_count = 0;
+
+ ret++;
+ }
+ }
+
+ if(!result)
+ break;
+ }
+
+ cloth_free_collision_list(clmd);
+
+ return ret;
+}
+
+// cloth - object collisions
+int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
+{
+ Base *base=NULL;
+ CollisionModifierData *collmd=NULL;
+ Cloth *cloth=NULL;
+ Object *coll_ob=NULL;
+ BVH *cloth_bvh=NULL;
+ long i=0, j = 0, numfaces = 0, numverts = 0;
+ unsigned int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output;
+ ClothVertex *verts = NULL;
+ int ret = 0;
+ ClothModifierData *tclmd;
+ int collisions = 0, count = 0;
+
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || !(((Cloth *)clmd->clothObject)->tree))
+ {
+ return 0;
+ }
+
+ cloth = clmd->clothObject;
+ verts = cloth->verts;
+ cloth_bvh = (BVH *) cloth->tree;
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ ////////////////////////////////////////////////////////////
+ // static collisions
+ ////////////////////////////////////////////////////////////
+
+ // update cloth bvh
+ bvh_update_from_cloth(clmd, 0); // 0 means STATIC, 1 means MOVING (see later in this function)
+
+ do
+ {
+ result = 0;
+ clmd->coll_parms->collision_list = NULL;
+
+ // check all collision objects
+ for (base = G.scene->base.first; base; base = base->next)
+ {
+ coll_ob = base->object;
+ collmd = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision);
+
+ if (!collmd)
+ {
+ 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 = (CollisionModifierData *) modifiers_findByType (coll_ob, eModifierType_Collision);
+
+ if (!collmd)
+ continue;
+
+ tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+ if(tclmd == clmd)
+ continue;
+
+ ret += cloth_bvh_objcollisions_do(clmd, collmd, step, dt);
+ }
+ }
+ }
+ else
+ {
+ tclmd = (ClothModifierData *) modifiers_findByType (coll_ob, eModifierType_Cloth);
+ if(tclmd == clmd)
+ continue;
+
+ ret += cloth_bvh_objcollisions_do(clmd, collmd, step, dt);
+ }
+ }
+ rounds++;
+
+ ////////////////////////////////////////////////////////////
+ // update positions
+ // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
+ ////////////////////////////////////////////////////////////
+
+ // verts come from clmd
+ for(i = 0; i < numverts; i++)
+ {
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ {
+ if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ continue;
+ }
+ }
+
+ VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+ }
+ ////////////////////////////////////////////////////////////
+
+
+ ////////////////////////////////////////////////////////////
+ // Test on *simple* selfcollisions
+ ////////////////////////////////////////////////////////////
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)
+ {
+ collisions = 1;
+ verts = cloth->verts; // needed for openMP
+
+ for(count = 0; count < clmd->coll_parms->self_loop_count; count++)
+ {
+ if(collisions)
+ {
+ collisions = 0;
+ #pragma omp parallel for private(i,j, collisions) shared(verts, ret)
+ for(i = 0; i < cloth->numverts; i++)
+ {
+ for(j = i + 1; j < cloth->numverts; j++)
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance = clmd->coll_parms->selfepsilon*(cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len);
+
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ {
+ if((cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ && (cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED))
+ {
+ continue;
+ }
+ }
+
+ VECSUB(temp, verts[i].tx, verts[j].tx);
+
+ if ((ABS(temp[0]) > mindistance) || (ABS(temp[1]) > mindistance) || (ABS(temp[2]) > mindistance)) continue;
+
+ // check for adjacent points (i must be smaller j)
+ if(BLI_edgehash_haskey (cloth->edgehash, i, j ))
+ {
+ continue;
+ }
+
+ length = Normalize(temp);
+
+ if(length < mindistance)
+ {
+ float correction = mindistance - length;
+
+ if(cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ VecMulf(temp, -correction);
+ VECADD(verts[j].tx, verts[j].tx, temp);
+ }
+ else if(cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ VecMulf(temp, correction);
+ VECADD(verts[i].tx, verts[i].tx, temp);
+ }
+ else
+ {
+ VecMulf(temp, -correction*0.5);
+ VECADD(verts[j].tx, verts[j].tx, temp);
+
+ VECSUB(verts[i].tx, verts[i].tx, temp);
+ }
+
+ collisions = 1;
+
+ if(!ret)
+ {
+ #pragma omp critical
+ {
+ ret = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if(ret)
+ {
+ for(i = 0; i < cloth->numverts; i++)
+ {
+ if(!(cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ }
+ }
+ while(result && (clmd->coll_parms->loop_count>rounds));
+
+ return MIN2(ret, 1);
+}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index fda31d9e7c0..e4336576e2a 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -62,12 +62,18 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
{
CurveMapping *cumap;
int a;
+ float clipminx, clipminy, clipmaxx, clipmaxy;
cumap= MEM_callocN(sizeof(CurveMapping), "new curvemap");
cumap->flag= CUMA_DO_CLIP;
if(tot==4) cumap->cur= 3; /* rhms, hack for 'col' curve? */
- BLI_init_rctf(&cumap->curr, minx, maxx, miny, maxy);
+ clipminx = MIN2(minx, maxx);
+ clipminy = MIN2(miny, maxy);
+ clipmaxx = MAX2(minx, maxx);
+ clipmaxy = MAX2(miny, maxy);
+
+ BLI_init_rctf(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy);
cumap->clipr= cumap->curr;
cumap->white[0]= cumap->white[1]= cumap->white[2]= 1.0f;
@@ -161,18 +167,30 @@ void curvemap_remove(CurveMap *cuma, int flag)
void curvemap_insert(CurveMap *cuma, float x, float y)
{
CurveMapPoint *cmp= MEM_callocN((cuma->totpoint+1)*sizeof(CurveMapPoint), "curve points");
- int a;
-
- memcpy(cmp, cuma->curve, (cuma->totpoint)*sizeof(CurveMapPoint));
+ int a, b, foundloc= 0;
+
+ /* insert fragments of the old one and the new point to the new curve */
+ cuma->totpoint++;
+ for(a=0, b=0; a<cuma->totpoint; a++) {
+ if((x < cuma->curve[a].x) && !foundloc) {
+ cmp[a].x= x;
+ cmp[a].y= y;
+ cmp[a].flag= CUMA_SELECT;
+ foundloc= 1;
+ }
+ else {
+ cmp[a].x= cuma->curve[b].x;
+ cmp[a].y= cuma->curve[b].y;
+ cmp[a].flag= cuma->curve[b].flag;
+ cmp[a].flag &= ~CUMA_SELECT; /* make sure old points don't remain selected */
+ cmp[a].shorty= cuma->curve[b].shorty;
+ b++;
+ }
+ }
+
+ /* free old curve and replace it with new one */
MEM_freeN(cuma->curve);
cuma->curve= cmp;
-
- cuma->curve[cuma->totpoint].x= x;
- cuma->curve[cuma->totpoint].y= y;
- cuma->curve[cuma->totpoint].flag = CUMA_SELECT;
- for(a=0; a<cuma->totpoint; a++, cmp++)
- cmp->flag= 0;
- cuma->totpoint++;
}
void curvemap_reset(CurveMap *cuma, rctf *clipr)
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 97f5ed18cbe..4a0c799d2be 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -25,12 +25,13 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung, major recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <stdio.h>
+#include <stddef.h>
#include <string.h>
#include <math.h>
@@ -45,19 +46,29 @@
#include "DNA_object_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
+#include "DNA_text_types.h"
#include "BKE_utildefines.h"
#include "BKE_action.h"
-#include "BKE_anim.h" // for the curve calculation part
+#include "BKE_anim.h" /* for the curve calculation part */
#include "BKE_armature.h"
#include "BKE_blender.h"
#include "BKE_constraint.h"
#include "BKE_displist.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h" /* for geometry targets */
+#include "BKE_cdderivedmesh.h" /* for geometry targets */
#include "BKE_object.h"
#include "BKE_ipo.h"
#include "BKE_global.h"
#include "BKE_library.h"
+#include "BKE_idprop.h"
+
+
+#include "BPY_extern.h"
#include "blendef.h"
@@ -69,35 +80,19 @@
#define M_PI 3.14159265358979323846
#endif
-/* used by object.c */
-void Mat4BlendMat4(float [][4], float [][4], float [][4], float );
-
-/* Local function prototypes */
-
-/* ********************* Data level ****************** */
-
-void free_constraint_data (bConstraint *con)
-{
- if (con->data) {
- /* any constraint-type specific stuff here */
-
- MEM_freeN(con->data);
- }
-}
-void free_constraints (ListBase *conlist)
-{
- bConstraint *con;
-
- /* Do any specific freeing */
- for (con=conlist->first; con; con=con->next) {
- free_constraint_data(con);
- }
-
- /* Free the whole list */
- BLI_freelistN(conlist);
-}
+/* ******************* Constraint Channels ********************** */
+/* Constraint Channels exist in one of two places:
+ * - Under Action Channels in an Action (act->chanbase->achan->constraintChannels)
+ * - Under Object without object-level action yet (ob->constraintChannels)
+ *
+ * The main purpose that constraint channels serve is to act as a link
+ * between an IPO-block which
+ */
+/* ------------ Data Management ----------- */
+
+/* Free constraint channels, and reduce the number of users of the related ipo-blocks */
void free_constraint_channels (ListBase *chanbase)
{
bConstraintChannel *chan;
@@ -111,117 +106,14 @@ void free_constraint_channels (ListBase *chanbase)
BLI_freelistN(chanbase);
}
-void relink_constraints (struct ListBase *list)
-{
- bConstraint *con;
-
- for (con = list->first; con; con=con->next) {
- switch (con->type) {
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
- bRigidBodyJointConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data;
- data = con->data;
-
- ID_NEW(data->tar);
- }
- break;
- }
- }
-}
-
+/* Make a copy of the constraint channels from dst to src, and also give the
+ * new constraint channels their own copy of the original's IPO.
+ */
void copy_constraint_channels (ListBase *dst, ListBase *src)
{
bConstraintChannel *dchan, *schan;
- dst->first=dst->last=NULL;
+ dst->first = dst->last = NULL;
duplicatelist(dst, src);
for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next) {
@@ -229,11 +121,14 @@ void copy_constraint_channels (ListBase *dst, ListBase *src)
}
}
+/* Make a copy of the constraint channels from dst to src, but make the
+ * new constraint channels use the same IPO-data as their twin.
+ */
void clone_constraint_channels (ListBase *dst, ListBase *src)
{
bConstraintChannel *dchan, *schan;
- dst->first=dst->last=NULL;
+ dst->first = dst->last = NULL;
duplicatelist(dst, src);
for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next) {
@@ -241,664 +136,894 @@ void clone_constraint_channels (ListBase *dst, ListBase *src)
}
}
-void copy_constraints (ListBase *dst, ListBase *src)
+/* ------------- Constraint Channel Tools ------------ */
+
+/* Find the constraint channel with a given name */
+bConstraintChannel *get_constraint_channel (ListBase *list, const char name[])
{
- bConstraint *con;
+ bConstraintChannel *chan;
+
+ if(list) {
+ for (chan = list->first; chan; chan=chan->next) {
+ if (!strcmp(name, chan->name)) {
+ return chan;
+ }
+ }
+ }
- dst->first= dst->last= NULL;
+ return NULL;
+}
+
+/* Find or create a new constraint channel */
+bConstraintChannel *verify_constraint_channel (ListBase *list, const char name[])
+{
+ bConstraintChannel *chan;
- duplicatelist (dst, src);
+ chan= get_constraint_channel(list, name);
- for (con = dst->first; con; con=con->next) {
- con->data = MEM_dupallocN (con->data);
+ if (chan == NULL) {
+ chan= MEM_callocN(sizeof(bConstraintChannel), "new constraint channel");
+ BLI_addtail(list, chan);
+ strcpy(chan->name, name);
}
+
+ return chan;
}
+/* --------- Constraint Channel Evaluation/Execution --------- */
-/* **************** Editor Functions **************** */
-
-char constraint_has_target (bConstraint *con)
+/* IPO-system call: calculate IPO-block for constraint channels, and flush that
+ * info onto the corresponding constraint.
+ */
+void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, short onlydrivers)
{
- switch (con->type) {
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = con->data;
- if (data->tar)
- return 1;
- }
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
- bRigidBodyJointConstraint *data = con->data;
- if (data->tar)
- return 1;
+ bConstraint *con;
+
+ /* for each Constraint, calculate its Influence from the corresponding ConstraintChannel */
+ for (con=conbase->first; con; con=con->next) {
+ Ipo *ipo= NULL;
+
+ if(con->flag & CONSTRAINT_OWN_IPO)
+ ipo= con->ipo;
+ else {
+ bConstraintChannel *chan = get_constraint_channel(chanbase, con->name);
+ if(chan) ipo= chan->ipo;
}
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data = con->data;
- if (data->tar)
- return 1;
+
+ if (ipo) {
+ IpoCurve *icu;
+
+ calc_ipo(ipo, ctime);
+
+ for (icu=ipo->curve.first; icu; icu=icu->next) {
+ if (!onlydrivers || icu->driver) {
+ switch (icu->adrcode) {
+ case CO_ENFORCE:
+ {
+ /* Influence is clamped to 0.0f -> 1.0f range */
+ con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
+ }
+ break;
+ case CO_HEADTAIL:
+ {
+ con->headtail = icu->curval;
+ }
+ break;
+ }
+ }
+ }
}
- break;
}
- // Unknown types or CONSTRAINT_TYPE_NULL or no target
- return 0;
}
-Object *get_constraint_target(bConstraint *con, char **subtarget)
+/* ************************ Constraints - General Utilities *************************** */
+/* These functions here don't act on any specific constraints, and are therefore should/will
+ * not require any of the special function-pointers afforded by the relevant constraint
+ * type-info structs.
+ */
+
+/* -------------- Naming -------------- */
+
+/* Find the first available, non-duplicate name for a given constraint */
+void unique_constraint_name (bConstraint *con, ListBase *list)
{
- /* If the target for this constraint is target, return a pointer
- * to the name for this constraints subtarget ... NULL otherwise
- */
- switch (con->type) {
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = con->data;
- *subtarget= data->subtarget;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = con->data;
- *subtarget= NULL;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = con->data;
- *subtarget= data->subtarget;
- return (data->tar);
- }
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
- bRigidBodyJointConstraint *data = con->data;
- *subtarget= NULL;
- return data->tar;
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data = con->data;
- *subtarget= NULL;
- return data->tar;
- }
- break;
- default:
- *subtarget= NULL;
- break;
- }
-
- return NULL;
+ BLI_uniquename(list, con, "Const", offsetof(bConstraint, name), 32);
}
-void set_constraint_target(bConstraint *con, Object *ob, char *subtarget)
+/* ----------------- Evaluation Loop Preparation --------------- */
+
+/* package an object/bone for use in constraint evaluation */
+/* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
+bConstraintOb *constraints_make_evalob (Object *ob, void *subdata, short datatype)
{
- /* Set the target for this constraint */
- switch (con->type) {
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = con->data;
- data->tar= ob;
+ bConstraintOb *cob;
+
+ /* create regardless of whether we have any data! */
+ cob= MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
+
+ /* based on type of available data */
+ switch (datatype) {
+ case CONSTRAINT_OBTYPE_OBJECT:
+ {
+ /* disregard subdata... calloc should set other values right */
+ if (ob) {
+ cob->ob = ob;
+ cob->type = datatype;
+ Mat4CpyMat4(cob->matrix, ob->obmat);
+ }
+ else
+ Mat4One(cob->matrix);
+
+ Mat4CpyMat4(cob->startmat, cob->matrix);
}
break;
- case CONSTRAINT_TYPE_STRETCHTO:
+ case CONSTRAINT_OBTYPE_BONE:
{
- bStretchToConstraint *data = con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
+ /* only set if we have valid bone, otherwise default */
+ if (ob && subdata) {
+ cob->ob = ob;
+ cob->pchan = (bPoseChannel *)subdata;
+ cob->type = datatype;
+
+ /* matrix in world-space */
+ Mat4MulMat4(cob->matrix, cob->pchan->pose_mat, ob->obmat);
+ }
+ else
+ Mat4One(cob->matrix);
+
+ Mat4CpyMat4(cob->startmat, cob->matrix);
}
break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
- bRigidBodyJointConstraint *data = con->data;
- data->tar= ob;
- }
+
+ default: /* other types not yet handled */
+ Mat4One(cob->matrix);
+ Mat4One(cob->startmat);
break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = (bMinMaxConstraint*)con->data;
- data->tar= ob;
- if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
+ }
+
+ return cob;
+}
+
+/* cleanup after constraint evaluation */
+void constraints_clear_evalob (bConstraintOb *cob)
+{
+ float delta[4][4], imat[4][4];
+
+ /* prevent crashes */
+ if (cob == NULL)
+ return;
+
+ /* calculate delta of constraints evaluation */
+ Mat4Invert(imat, cob->startmat);
+ Mat4MulMat4(delta, imat, cob->matrix);
+
+ /* copy matrices back to source */
+ switch (cob->type) {
+ case CONSTRAINT_OBTYPE_OBJECT:
+ {
+ /* cob->ob might not exist! */
+ if (cob->ob) {
+ /* copy new ob-matrix back to owner */
+ Mat4CpyMat4(cob->ob->obmat, cob->matrix);
+
+ /* copy inverse of delta back to owner */
+ Mat4Invert(cob->ob->constinv, delta);
+ }
}
break;
- case CONSTRAINT_TYPE_CLAMPTO:
+ case CONSTRAINT_OBTYPE_BONE:
{
- bClampToConstraint *data = con->data;
- data->tar= ob;
+ /* cob->ob or cob->pchan might not exist */
+ if (cob->ob && cob->pchan) {
+ /* copy new pose-matrix back to owner */
+ Mat4MulMat4(cob->pchan->pose_mat, cob->matrix, cob->ob->imat);
+
+ /* copy inverse of delta back to owner */
+ Mat4Invert(cob->pchan->constinv, delta);
+ }
}
break;
}
+
+ /* free tempolary struct */
+ MEM_freeN(cob);
}
-void unique_constraint_name (bConstraint *con, ListBase *list)
+/* -------------- Space-Conversion API -------------- */
+
+/* This function is responsible for the correct transformations/conversions
+ * of a matrix from one space to another for constraint evaluation.
+ * For now, this is only implemented for Objects and PoseChannels.
+ */
+void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
{
- char tempname[64];
- int number;
- char *dot;
- int exists = 0;
- bConstraint *curcon;
+ float tempmat[4][4];
+ float diff_mat[4][4];
+ float imat[4][4];
- /* See if we are given an empty string */
- if (con->name[0] == '\0') {
- /* give it default name first */
- strcpy (con->name, "Const");
- }
+ /* prevent crashes in these unlikely events */
+ if (ob==NULL || mat==NULL) return;
+ /* optimise trick - check if need to do anything */
+ if (from == to) return;
- /* See if we even need to do this */
- for (curcon = list->first; curcon; curcon=curcon->next){
- if (curcon!=con){
- if (!strcmp(curcon->name, con->name)){
- exists = 1;
+ /* are we dealing with pose-channels or objects */
+ if (pchan) {
+ /* pose channels */
+ switch (from) {
+ case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
+ {
+ /* world to pose */
+ if (to==CONSTRAINT_SPACE_POSE || to==CONSTRAINT_SPACE_LOCAL || to==CONSTRAINT_SPACE_PARLOCAL) {
+ Mat4Invert(imat, ob->obmat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, imat);
+ }
+
+ /* pose to local */
+ if (to == CONSTRAINT_SPACE_LOCAL) {
+ /* call self with slightly different values */
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ }
+ /* pose to local + parent */
+ else if (to == CONSTRAINT_SPACE_PARLOCAL) {
+ /* call self with slightly different values */
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ }
+ }
break;
+ case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
+ {
+ /* pose to world */
+ if (to == CONSTRAINT_SPACE_WORLD) {
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, ob->obmat);
+ }
+ /* pose to local */
+ else if (to == CONSTRAINT_SPACE_LOCAL) {
+ if (pchan->bone) {
+ if (pchan->parent) {
+ float offs_bone[4][4];
+
+ /* construct offs_bone the same way it is done in armature.c */
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ VECCOPY(offs_bone[3], pchan->bone->head);
+ offs_bone[3][1]+= pchan->bone->parent->length;
+
+ if (pchan->bone->flag & BONE_HINGE) {
+ /* pose_mat = par_pose-space_location * chan_mat */
+ float tmat[4][4];
+
+ /* the rotation of the parent restposition */
+ Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
+
+ /* the location of actual parent transform */
+ VECCOPY(tmat[3], offs_bone[3]);
+ offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
+ Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
+
+ Mat4MulMat4(diff_mat, offs_bone, tmat);
+ Mat4Invert(imat, diff_mat);
+ }
+ else {
+ /* pose_mat = par_pose_mat * bone_mat * chan_mat */
+ Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
+ Mat4Invert(imat, diff_mat);
+ }
+ }
+ else {
+ /* pose_mat = chan_mat * arm_mat */
+ Mat4Invert(imat, pchan->bone->arm_mat);
+ }
+
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, imat);
+ }
+ }
+ /* pose to local with parent */
+ else if (to == CONSTRAINT_SPACE_PARLOCAL) {
+ if (pchan->bone) {
+ Mat4Invert(imat, pchan->bone->arm_mat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, imat);
+ }
+ }
}
+ break;
+ case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
+ {
+ /* local to pose */
+ if (to==CONSTRAINT_SPACE_POSE || to==CONSTRAINT_SPACE_WORLD) {
+ /* do inverse procedure that was done for pose to local */
+ if (pchan->bone) {
+ /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
+ if (pchan->parent) {
+ float offs_bone[4][4];
+
+ /* construct offs_bone the same way it is done in armature.c */
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ VECCOPY(offs_bone[3], pchan->bone->head);
+ offs_bone[3][1]+= pchan->bone->parent->length;
+
+ if (pchan->bone->flag & BONE_HINGE) {
+ /* pose_mat = par_pose-space_location * chan_mat */
+ float tmat[4][4];
+
+ /* the rotation of the parent restposition */
+ Mat4CpyMat4(tmat, pchan->bone->parent->arm_mat);
+
+ /* the location of actual parent transform */
+ VECCOPY(tmat[3], offs_bone[3]);
+ offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
+ Mat4MulVecfl(pchan->parent->pose_mat, tmat[3]);
+
+ Mat4MulMat4(diff_mat, offs_bone, tmat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, diff_mat);
+ }
+ else {
+ /* pose_mat = par_pose_mat * bone_mat * chan_mat */
+ Mat4MulMat4(diff_mat, offs_bone, pchan->parent->pose_mat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, diff_mat);
+ }
+ }
+ else {
+ Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
+
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, diff_mat);
+ }
+ }
+ }
+ /* local to world */
+ if (to == CONSTRAINT_SPACE_WORLD) {
+ /* call self with slightly different values */
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ }
+ }
+ break;
+ case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
+ {
+ /* local to pose */
+ if (to==CONSTRAINT_SPACE_POSE || to==CONSTRAINT_SPACE_WORLD) {
+ if (pchan->bone) {
+ Mat4CpyMat4(diff_mat, pchan->bone->arm_mat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, diff_mat, tempmat);
+ }
+ }
+ /* local to world */
+ if (to == CONSTRAINT_SPACE_WORLD) {
+ /* call self with slightly different values */
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ }
+ }
+ break;
}
}
-
- if (!exists)
- return;
-
- /* Strip off the suffix */
- dot=strchr(con->name, '.');
- if (dot)
- *dot=0;
-
- for (number = 1; number <=999; number++){
- sprintf (tempname, "%s.%03d", con->name, number);
-
- exists = 0;
- for (curcon=list->first; curcon; curcon=curcon->next){
- if (con!=curcon){
- if (!strcmp (curcon->name, tempname)){
- exists = 1;
- break;
- }
+ else {
+ /* objects */
+ if (from==CONSTRAINT_SPACE_WORLD && to==CONSTRAINT_SPACE_LOCAL) {
+ /* check if object has a parent - otherwise this won't work */
+ if (ob->parent) {
+ /* 'subtract' parent's effects from owner */
+ Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
+ Mat4Invert(imat, diff_mat);
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(mat, tempmat, imat);
}
}
- if (!exists){
- strcpy (con->name, tempname);
- return;
+ else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
+ /* check that object has a parent - otherwise this won't work */
+ if (ob->parent) {
+ /* 'add' parent's effect back to owner */
+ Mat4CpyMat4(tempmat, mat);
+ Mat4MulMat4(diff_mat, ob->parentinv, ob->parent->obmat);
+ Mat4MulMat4(mat, tempmat, diff_mat);
+ }
}
}
}
-void *new_constraint_data (short type)
+/* ------------ General Target Matrix Tools ---------- */
+
+/* function that sets the given matrix based on given vertex group in mesh */
+static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
{
- void *result;
+ DerivedMesh *dm;
+ float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
+ float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
+ float imat[3][3], tmat[3][3];
+ int dgroup;
- switch (type) {
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
- data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
-
- data->weight= (float)1.0;
- data->orientweight= (float)1.0;
- data->iterations = 500;
- data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
+ /* initialize target matrix using target matrix */
+ Mat4CpyMat4(mat, ob->obmat);
+
+ /* get index of vertex group */
+ dgroup = get_named_vertexgroup_num(ob, substring);
+ if (dgroup < 0) return;
+
+ /* get DerivedMesh */
+ if (G.obedit && G.editMesh) {
+ /* we are in editmode, so get a special derived mesh */
+ dm = CDDM_from_editmesh(G.editMesh, ob->data);
+ }
+ else {
+ /* when not in EditMode, this should exist */
+ dm = (DerivedMesh *)ob->derivedFinal;
+ }
+
+ /* only continue if there's a valid DerivedMesh */
+ if (dm) {
+ MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+ int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
+ int numVerts = dm->getNumVerts(dm);
+ int i, j, count = 0;
+ float co[3], nor[3];
+
+ /* check that dvert and index are valid pointers (just in case) */
+ if (dvert && index) {
+ /* get the average of all verts with that are in the vertex-group */
+ for (i = 0; i < numVerts; i++, index++) {
+ for (j = 0; j < dvert[i].totweight; j++) {
+ /* does this vertex belong to nominated vertex group? */
+ if (dvert[i].dw[j].def_nr == dgroup) {
+ dm->getVertCo(dm, i, co);
+ dm->getVertNo(dm, i, nor);
+ VecAddf(vec, vec, co);
+ VecAddf(normal, normal, nor);
+ count++;
+ break;
+ }
+
+ }
+ }
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint");
- data->reserved1 = TRACK_Y;
- data->reserved2 = UP_Z;
+ /* calculate averages of normal and coordinates */
+ if (count > 0) {
+ VecMulf(vec, 1.0f / count);
+ VecMulf(normal, 1.0f / count);
+ }
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data;
- data = MEM_callocN(sizeof(bMinMaxConstraint), "minmaxConstraint");
- data->minmaxflag = TRACK_Z;
- data->offset = 0.0f;
- data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
- data->flag = 0;
+ /* derive the rotation from the average normal:
+ * - code taken from transform_manipulator.c,
+ * calc_manipulator_stats, V3D_MANIP_NORMAL case
+ */
+ /* we need the transpose of the inverse for a normal... */
+ Mat3CpyMat4(imat, ob->obmat);
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint");
- data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
- data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint");
- data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data;
- data = MEM_callocN(sizeof(bLocateLikeConstraint), "sizelikeConstraint");
- data->flag |= SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
- data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint");
- data->local= 1;
+ Mat3Inv(tmat, imat);
+ Mat3Transp(tmat);
+ Mat3MulVecfl(tmat, normal);
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data;
- data = MEM_callocN(sizeof(bLockTrackConstraint), "locktrackConstraint");
-
- data->trackflag = TRACK_Y;
- data->lockflag = LOCK_Z;
-
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
- data = MEM_callocN(sizeof(bFollowPathConstraint), "followpathConstraint");
-
- data->trackflag = TRACK_Y;
- data->upflag = UP_Z;
- data->offset = 0;
- data->followflag = 0;
-
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
- data = MEM_callocN(sizeof(bStretchToConstraint), "StretchToConstraint");
-
- data->volmode = 0;
- data->plane = 0;
- data->orglength = 0.0;
- data->bulge = 1.0;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
- {
- bLocLimitConstraint *data;
- data = MEM_callocN(sizeof(bLocLimitConstraint), "LocLimitConstraint");
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
- {
- bRotLimitConstraint *data;
- data = MEM_callocN(sizeof(bRotLimitConstraint), "RotLimitConstraint");
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- {
- bSizeLimitConstraint *data;
- data = MEM_callocN(sizeof(bSizeLimitConstraint), "SizeLimitConstraint");
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
- bRigidBodyJointConstraint *data;
- int i;
- Base *base_iter;
-
- data = MEM_callocN(sizeof(bRigidBodyJointConstraint), "RigidBodyToConstraint");
- base_iter = G.scene->base.first;
- while( base_iter && !data->tar ) {
- if( ( ( base_iter->flag & SELECT ) &&
-// ( base_iter->lay & G.vd->lay ) ) &&
- ( base_iter != G.scene->basact ) )
- )
- data->tar=base_iter->object;
- base_iter = base_iter->next;
- }
- data->type=1;
- data->pivX=0.0;
- data->pivY=0.0;
- data->pivZ=0.0;
- data->axX=0.0;
- data->axY=0.0;
- data->axZ=0.0;
- for (i=0;i<6;i++)
- {
- data->minLimit[i]=0.0;
- data->maxLimit[i]=0.0;
- }
- data->extraFz=0.0;
- result = data;
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data;
- data = MEM_callocN(sizeof(bClampToConstraint), "ClampToConstraint");
- result = data;
+ Normalize(normal);
+ VECCOPY(plane, tmat[1]);
+
+ VECCOPY(tmat[2], normal);
+ Crossf(tmat[0], normal, plane);
+ Crossf(tmat[1], tmat[2], tmat[0]);
+
+ Mat4CpyMat3(mat, tmat);
+ Mat4Ortho(mat);
+
+
+ /* apply the average coordinate as the new location */
+ VecMat4MulVecfl(tvec, ob->obmat, vec);
+ VECCOPY(mat[3], tvec);
}
- break;
-
- default:
- result = NULL;
- break;
}
-
- return result;
-}
-
-bConstraintChannel *get_constraint_channel (ListBase *list, const char *name)
-{
- bConstraintChannel *chan;
-
- for (chan = list->first; chan; chan=chan->next) {
- if (!strcmp(name, chan->name)) {
- return chan;
- }
+
+ /* free temporary DerivedMesh created (in EditMode case) */
+ if (G.editMesh) {
+ if (dm) dm->release(dm);
}
- return NULL;
}
-/* finds or creates new constraint channel */
-bConstraintChannel *verify_constraint_channel (ListBase *list, const char *name)
+/* function that sets the given matrix based on given vertex group in lattice */
+static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][4])
{
- bConstraintChannel *chan;
+ Lattice *lt= (Lattice *)ob->data;
- chan= get_constraint_channel (list, name);
- if(chan==NULL) {
- chan= MEM_callocN(sizeof(bConstraintChannel), "new constraint chan");
- BLI_addtail(list, chan);
- strcpy(chan->name, name);
+ DispList *dl = find_displist(&ob->disp, DL_VERTS);
+ float *co = dl?dl->verts:NULL;
+ BPoint *bp = lt->def;
+
+ MDeformVert *dvert = lt->dvert;
+ int tot_verts= lt->pntsu*lt->pntsv*lt->pntsw;
+ float vec[3]= {0.0f, 0.0f, 0.0f}, tvec[3];
+ int dgroup=0, grouped=0;
+ int i, n;
+
+ /* initialize target matrix using target matrix */
+ Mat4CpyMat4(mat, ob->obmat);
+
+ /* get index of vertex group */
+ dgroup = get_named_vertexgroup_num(ob, substring);
+ if (dgroup < 0) return;
+ if (dvert == NULL) return;
+
+ /* 1. Loop through control-points checking if in nominated vertex-group.
+ * 2. If it is, add it to vec to find the average point.
+ */
+ for (i=0; i < tot_verts; i++, dvert++) {
+ for (n= 0; n < dvert->totweight; n++) {
+ /* found match - vert is in vgroup */
+ if (dvert->dw[n].def_nr == dgroup) {
+ /* copy coordinates of point to temporary vector, then add to find average */
+ if (co)
+ memcpy(tvec, co, 3*sizeof(float));
+ else
+ memcpy(tvec, bp->vec, 3*sizeof(float));
+
+ VecAddf(vec, vec, tvec);
+ grouped++;
+
+ break;
+ }
+ }
+
+ /* advance pointer to coordinate data */
+ if (co) co+= 3;
+ else bp++;
}
- return chan;
+ /* find average location, then multiply by ob->obmat to find world-space location */
+ if (grouped)
+ VecMulf(vec, 1.0f / grouped);
+ VecMat4MulVecfl(tvec, ob->obmat, vec);
+
+ /* copy new location to matrix */
+ VECCOPY(mat[3], tvec);
}
-
-/* ***************** Evaluating ********************* */
-
-/* does ipos only */
-void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime)
+/* generic function to get the appropriate matrix for most target cases */
+/* The cases where the target can be object data have not been implemented */
+static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
{
- bConstraint *con;
- bConstraintChannel *chan;
- IpoCurve *icu=NULL;
-
- for (con=conbase->first; con; con=con->next) {
- chan = get_constraint_channel(chanbase, con->name);
- if (chan && chan->ipo){
- calc_ipo(chan->ipo, ctime);
- for (icu=chan->ipo->curve.first; icu; icu=icu->next){
- switch (icu->adrcode){
- case CO_ENFORCE:
- con->enforce = icu->curval;
- if (con->enforce<0.0f) con->enforce= 0.0f;
- else if (con->enforce>1.0f) con->enforce= 1.0f;
- break;
- }
+ /* Case OBJECT */
+ if (!strlen(substring)) {
+ Mat4CpyMat4(mat, ob->obmat);
+ constraint_mat_convertspace(ob, NULL, mat, from, to);
+ }
+ /* Case VERTEXGROUP */
+ /* Current method just takes the average location of all the points in the
+ * VertexGroup, and uses that as the location value of the targets. Where
+ * possible, the orientation will also be calculated, by calculating an
+ * 'average' vertex normal, and deriving the rotaation from that.
+ *
+ * NOTE: EditMode is not currently supported, and will most likely remain that
+ * way as constraints can only really affect things on object/bone level.
+ */
+ else if (ob->type == OB_MESH) {
+ contarget_get_mesh_mat(ob, substring, mat);
+ constraint_mat_convertspace(ob, NULL, mat, from, to);
+ }
+ else if (ob->type == OB_LATTICE) {
+ contarget_get_lattice_mat(ob, substring, mat);
+ constraint_mat_convertspace(ob, NULL, mat, from, to);
+ }
+ /* Case BONE */
+ else {
+ bPoseChannel *pchan;
+
+ pchan = get_pose_channel(ob->pose, substring);
+ if (pchan) {
+ /* Multiply the PoseSpace accumulation/final matrix for this
+ * PoseChannel by the Armature Object's Matrix to get a worldspace
+ * matrix.
+ */
+ if (headtail < 0.000001) {
+ /* skip length interpolation if set to head */
+ Mat4MulMat4(mat, pchan->pose_mat, ob->obmat);
}
- }
+ else {
+ float tempmat[4][4], loc[3];
+
+ /* interpolate along length of bone */
+ VecLerpf(loc, pchan->pose_head, pchan->pose_tail, headtail);
+
+ /* use interpolated distance for subtarget */
+ Mat4CpyMat4(tempmat, pchan->pose_mat);
+ VecCopyf(tempmat[3], loc);
+
+ Mat4MulMat4(mat, tempmat, ob->obmat);
+ }
+ }
+ else
+ Mat4CpyMat4(mat, ob->obmat);
+
+ /* convert matrix space as required */
+ constraint_mat_convertspace(ob, pchan, mat, from, to);
}
}
-void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight)
+/* ************************* Specific Constraints ***************************** */
+/* Each constraint defines a set of functions, which will be called at the appropriate
+ * times. In addition to this, each constraint should have a type-info struct, where
+ * its functions are attached for use.
+ */
+
+/* Template for type-info data:
+ * - make a copy of this when creating new constraints, and just change the functions
+ * pointed to as necessary
+ * - although the naming of functions doesn't matter, it would help for code
+ * readability, to follow the same naming convention as is presented here
+ * - any functions that a constraint doesn't need to define, don't define
+ * for such cases, just use NULL
+ * - these should be defined after all the functions have been defined, so that
+ * forward-definitions/prototypes don't need to be used!
+ * - keep this copy #if-def'd so that future constraints can get based off this
+ */
+#if 0
+static bConstraintTypeInfo CTI_CONSTRNAME = {
+ CONSTRAINT_TYPE_CONSTRNAME, /* type */
+ sizeof(bConstrNameConstraint), /* size */
+ "ConstrName", /* name */
+ "bConstrNameConstraint", /* struct name */
+ constrname_free, /* free data */
+ constrname_relink, /* relink data */
+ constrname_copy, /* copy data */
+ constrname_new_data, /* new data */
+ constrname_get_tars, /* get constraint targets */
+ constrname_flush_tars, /* flush constraint targets */
+ constrname_get_tarmat, /* get target matrix */
+ constrname_evaluate /* evaluate */
+};
+#endif
+
+/* This function should be used for the get_target_matrix member of all
+ * constraints that are not picky about what happens to their target matrix.
+ */
+static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
{
- float squat[4], dquat[4], fquat[4];
- float ssize[3], dsize[3], fsize[4];
- float sloc[3], dloc[3], floc[3];
- float mat3[3][3], dstweight;
- float qmat[3][3], smat[3][3];
- int i;
+ if (VALID_CONS_TARGET(ct))
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ else if (ct)
+ Mat4One(ct->matrix);
+}
- dstweight = 1.0F-srcweight;
+/* This following macro should be used for all standard single-target *_get_tars functions
+ * to save typing and reduce maintainance woes.
+ * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
+ * really just to help this code easier to read)
+ */
+#define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
+ { \
+ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
+ \
+ ct->tar= datatar; \
+ strcpy(ct->subtarget, datasubtarget); \
+ ct->space= con->tarspace; \
+ 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; \
+ } \
+ \
+ BLI_addtail(list, ct); \
+ }
+
+/* This following macro should be used for all standard single-target *_get_tars functions
+ * to save typing and reduce maintainance woes. It does not do the subtarget related operations
+ * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
+ * really just to help this code easier to read)
+ */
+#define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
+ { \
+ ct= MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
+ \
+ ct->tar= datatar; \
+ ct->space= con->tarspace; \
+ ct->flag= CONSTRAINT_TAR_TEMP; \
+ \
+ if (ct->tar) ct->type = CONSTRAINT_OBTYPE_OBJECT; \
+ \
+ BLI_addtail(list, ct); \
+ }
- Mat3CpyMat4(mat3, dst);
- Mat3ToQuat(mat3, dquat);
- Mat3ToSize(mat3, dsize);
- VECCOPY (dloc, dst[3]);
+/* This following macro should be used for all standard single-target *_flush_tars functions
+ * to save typing and reduce maintainance woes.
+ * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
+ * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
+ * really just to help this code easier to read)
+ */
+#define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, nocopy) \
+ { \
+ if (ct) { \
+ bConstraintTarget *ctn = ct->next; \
+ if (nocopy == 0) { \
+ datatar= ct->tar; \
+ strcpy(datasubtarget, ct->subtarget); \
+ con->tarspace= ct->space; \
+ } \
+ \
+ BLI_freelinkN(list, ct); \
+ ct= ctn; \
+ } \
+ }
+
+/* This following macro should be used for all standard single-target *_flush_tars functions
+ * to save typing and reduce maintainance woes. It does not do the subtarget related operations.
+ * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
+ * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
+ * really just to help this code easier to read)
+ */
+#define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, nocopy) \
+ { \
+ if (ct) { \
+ bConstraintTarget *ctn = ct->next; \
+ if (nocopy == 0) { \
+ datatar= ct->tar; \
+ con->tarspace= ct->space; \
+ } \
+ \
+ BLI_freelinkN(list, ct); \
+ ct= ctn; \
+ } \
+ }
+
+/* --------- ChildOf Constraint ------------ */
- Mat3CpyMat4(mat3, src);
- Mat3ToQuat(mat3, squat);
- Mat3ToSize(mat3, ssize);
- VECCOPY (sloc, src[3]);
+static void childof_new_data (void *cdata)
+{
+ bChildOfConstraint *data= (bChildOfConstraint *)cdata;
- /* Do the actual blend */
- for (i=0; i<3; i++){
- floc[i] = (dloc[i]*dstweight) + (sloc[i]*srcweight);
- fsize[i] = 1.0f + ((dsize[i]-1.0f)*dstweight) + ((ssize[i]-1.0f)*srcweight);
- fquat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight);
+ data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ |
+ CHILDOF_ROTX |CHILDOF_ROTY | CHILDOF_ROTZ |
+ CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
+ Mat4One(data->invmat);
+}
+
+static int childof_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bChildOfConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
}
- /* Do one more iteration for the quaternions only and normalize the quaternion if needed */
- fquat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight);
- NormalQuat (fquat);
+ return 0;
+}
- QuatToMat3(fquat, qmat);
- SizeToMat3(fsize, smat);
+static void childof_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bChildOfConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
- Mat3MulMat3(mat3, qmat, smat);
- Mat4CpyMat3(out, mat3);
- VECCOPY (out[3], floc);
+static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bChildOfConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float parmat[4][4], invmat[4][4], tempmat[4][4];
+ float loc[3], eul[3], size[3];
+ float loco[3], eulo[3], sizo[3];
+
+ /* get offset (parent-inverse) matrix */
+ Mat4CpyMat4(invmat, data->invmat);
+
+ /* extract components of both matrices */
+ VECCOPY(loc, ct->matrix[3]);
+ Mat4ToEul(ct->matrix, eul);
+ Mat4ToSize(ct->matrix, size);
+
+ VECCOPY(loco, invmat[3]);
+ Mat4ToEul(invmat, eulo);
+ Mat4ToSize(invmat, sizo);
+
+ /* disable channels not enabled */
+ if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
+ if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
+ if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
+ if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
+ if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
+ if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
+ if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
+ if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
+ if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
+
+ /* make new target mat and offset mat */
+ LocEulSizeToMat4(ct->matrix, loc, eul, size);
+ LocEulSizeToMat4(invmat, loco, eulo, sizo);
+
+ /* multiply target (parent matrix) by offset (parent inverse) to get
+ * the effect of the parent that will be exherted on the owner
+ */
+ Mat4MulMat4(parmat, invmat, ct->matrix);
+
+ /* now multiply the parent matrix by the owner matrix to get the
+ * the effect of this constraint (i.e. owner is 'parented' to parent)
+ */
+ Mat4CpyMat4(tempmat, cob->matrix);
+ Mat4MulMat4(cob->matrix, tempmat, parmat);
+ }
}
-static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], float size[3])
+static bConstraintTypeInfo CTI_CHILDOF = {
+ CONSTRAINT_TYPE_CHILDOF, /* type */
+ sizeof(bChildOfConstraint), /* size */
+ "ChildOf", /* name */
+ "bChildOfConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ childof_new_data, /* new data */
+ childof_get_tars, /* get constraint targets */
+ childof_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get a target matrix */
+ childof_evaluate /* evaluate */
+};
+
+/* -------- TrackTo Constraint ------- */
+
+static void trackto_new_data (void *cdata)
{
+ bTrackToConstraint *data= (bTrackToConstraint *)cdata;
+
+ data->reserved1 = TRACK_Y;
+ data->reserved2 = UP_Z;
+}
- /* Case OBJECT */
- if (!strlen(substring)) {
- Mat4CpyMat4 (mat, ob->obmat);
- VECCOPY (size, ob->size); // whats this for, hack! (ton)
+static int trackto_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bTrackToConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
}
- /* Case BONE */
- else {
- bPoseChannel *pchan;
- float bsize[3]={1, 1, 1};
-
- pchan = get_pose_channel(ob->pose, substring);
- if (pchan){
- /**
- * Multiply the objectspace bonematrix by the skeletons's global
- * transform to obtain the worldspace transformation of the target
- */
- Mat4MulMat4 (mat, pchan->pose_mat, ob->obmat);
- }
- else
- Mat4CpyMat4 (mat, ob->obmat);
+
+ return 0;
+}
- VECCOPY(size, bsize); // whats this for, hack! (ton)
+static void trackto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bTrackToConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
}
}
-/* stupid little cross product function, 0:x, 1:y, 2:z axes */
-static int basis_cross(int n, int m)
+static int basis_cross (int n, int m)
{
- if(n-m == 1) return 1;
- if(n-m == -1) return -1;
- if(n-m == 2) return -1;
- if(n-m == -2) return 1;
- else return 0;
+ switch (n-m) {
+ case 1:
+ case -2:
+ return 1;
+
+ case -1:
+ case 2:
+ return -1;
+
+ default:
+ return 0;
+ }
}
-static void vectomat(float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
+static void vectomat (float *vec, float *target_up, short axis, short upflag, short flags, float m[][3])
{
float n[3];
float u[3]; /* vector specifying the up axis */
@@ -906,19 +1031,18 @@ static void vectomat(float *vec, float *target_up, short axis, short upflag, sho
float right[3];
float neg = -1;
int right_index;
-
+
VecCopyf(n, vec);
- if(Normalize(n) == 0.0) {
+ if (Normalize(n) == 0.0) {
n[0] = 0.0;
n[1] = 0.0;
n[2] = 1.0;
}
- if(axis > 2) axis -= 3;
+ if (axis > 2) axis -= 3;
else VecMulf(n,-1);
/* n specifies the transformation of the track axis */
-
- if(flags & TARGET_Z_UP) {
+ if (flags & TARGET_Z_UP) {
/* target Z axis is the global up axis */
u[0] = target_up[0];
u[1] = target_up[1];
@@ -936,7 +1060,7 @@ static void vectomat(float *vec, float *target_up, short axis, short upflag, sho
VecSubf(proj, u, proj); /* then onto the plane */
/* proj specifies the transformation of the up axis */
- if(Normalize(proj) == 0.0) { /* degenerate projection */
+ if (Normalize(proj) == 0.0) { /* degenerate projection */
proj[0] = 0.0;
proj[1] = 1.0;
proj[2] = 0.0;
@@ -946,24 +1070,24 @@ static void vectomat(float *vec, float *target_up, short axis, short upflag, sho
Crossf(right, proj, n);
Normalize(right);
- if(axis != upflag) {
+ if (axis != upflag) {
right_index = 3 - axis - upflag;
- neg = (float) basis_cross(axis, upflag);
-
+ neg = (float)basis_cross(axis, upflag);
+
/* account for up direction, track direction */
m[right_index][0] = neg * right[0];
m[right_index][1] = neg * right[1];
m[right_index][2] = neg * right[2];
-
+
m[upflag][0] = proj[0];
m[upflag][1] = proj[1];
m[upflag][2] = proj[2];
-
+
m[axis][0] = n[0];
m[axis][1] = n[1];
m[axis][2] = n[2];
}
-
+ /* identity matrix - don't do anything if the two axes are the same */
else {
m[0][0]= m[1][1]= m[2][2]= 1.0;
m[0][1]= m[0][2]= m[0][3]= 0.0;
@@ -973,1316 +1097,2491 @@ static void vectomat(float *vec, float *target_up, short axis, short upflag, sho
}
-/* called during solve_constraints */
-/* also for make_parent, to find correct inverse of "follow path" */
-/* warning, ownerdata is void... is not Bone anymore, but PoseChannel or Object */
-/* ctime is global time, uncorrected for local bsystem_time */
-short get_constraint_target_matrix (bConstraint *con, short ownertype, void* ownerdata, float mat[][4], float size[3], float ctime)
+static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
- short valid=0;
+ bTrackToConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float size[3], vec[3];
+ float totmat[3][3];
+ float tmat[4][4];
+
+ /* Get size property, since ob->size is only the object's own relative size, not its global one */
+ Mat4ToSize(cob->matrix, size);
+
+ /* Clear the object's rotation */
+ cob->matrix[0][0]=size[0];
+ cob->matrix[0][1]=0;
+ cob->matrix[0][2]=0;
+ cob->matrix[1][0]=0;
+ cob->matrix[1][1]=size[1];
+ cob->matrix[1][2]=0;
+ cob->matrix[2][0]=0;
+ cob->matrix[2][1]=0;
+ cob->matrix[2][2]=size[2];
+
+ /* targetmat[2] instead of ownermat[2] is passed to vectomat
+ * for backwards compatability it seems... (Aligorith)
+ */
+ VecSubf(vec, cob->matrix[3], ct->matrix[3]);
+ vectomat(vec, ct->matrix[2],
+ (short)data->reserved1, (short)data->reserved2,
+ data->flags, totmat);
+
+ Mat4CpyMat4(tmat, cob->matrix);
+ Mat4MulMat34(cob->matrix, totmat, tmat);
+ }
+}
- switch (con->type){
- case CONSTRAINT_TYPE_NULL:
- {
- Mat4One(mat);
- }
- break;
- case CONSTRAINT_TYPE_ACTION:
- {
- if (ownertype == TARGET_BONE) {
- extern void chan_calc_mat(bPoseChannel *chan);
- bActionConstraint *data = (bActionConstraint*)con->data;
- bPose *pose;
- bPoseChannel *pchan, *tchan;
- float tempmat3[3][3];
- float eul[3];
- float s,t;
-
- Mat4One(mat); // return mat
-
- if (data->tar==NULL) return 0;
-
- /* need proper check for bone... */
- if(data->subtarget[0]) {
- pchan = get_pose_channel(data->tar->pose, data->subtarget);
- if (pchan) {
- float arm_mat[3][3], pose_mat[3][3]; /* arm mat should be bone mat! bug... */
-
- Mat3CpyMat4(arm_mat, pchan->bone->arm_mat);
- Mat3CpyMat4(pose_mat, pchan->pose_mat);
-
- /* new; true local rotation constraint */
- if(data->local) {
- float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
- /* we need the local rotation = current rotation - (parent rotation + restpos) */
-
- if (pchan->parent) {
- Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
- Mat3MulMat3(diff_mat, par_mat, arm_mat);
-
- Mat3Inv(ipar_mat, diff_mat);
- }
- else {
- Mat3Inv(ipar_mat, arm_mat);
- }
-
- Mat3MulMat3(tempmat3, ipar_mat, pose_mat);
- }
- else { /* we use the deform mat, for backwards compatibility */
- float imat[3][3];
-
- Mat3Inv(imat, arm_mat);
- Mat3MulMat3(tempmat3, pose_mat, imat);
- }
- }
- else Mat3One(tempmat3);
- }
- else {
- float ans[4][4];
-
- constraint_target_to_mat4(data->tar, data->subtarget, ans, size);
- /* extract rotation, is in global world coordinates */
- Mat3CpyMat4(tempmat3, ans);
- }
-
- Mat3ToEul(tempmat3, eul);
- eul[0]*=(float)(180.0/M_PI);
- eul[1]*=(float)(180.0/M_PI);
- eul[2]*=(float)(180.0/M_PI);
-
- /* Target defines the animation */
- s = (eul[data->type]-data->min)/(data->max-data->min);
- if (s<0)
- s=0;
- if (s>1)
- s=1;
+static bConstraintTypeInfo CTI_TRACKTO = {
+ CONSTRAINT_TYPE_TRACKTO, /* type */
+ sizeof(bTrackToConstraint), /* size */
+ "TrackTo", /* name */
+ "bTrackToConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ trackto_new_data, /* new data */
+ trackto_get_tars, /* get constraint targets */
+ trackto_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ trackto_evaluate /* evaluate */
+};
+
+/* --------- Inverse-Kinemetics --------- */
+
+static void kinematic_new_data (void *cdata)
+{
+ bKinematicConstraint *data= (bKinematicConstraint *)cdata;
+
+ data->weight= (float)1.0;
+ data->orientweight= (float)1.0;
+ data->iterations = 500;
+ data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_STRETCH|CONSTRAINT_IK_POS;
+}
- t = ( s * (data->end-data->start)) + data->start;
+static int kinematic_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bKinematicConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints is used twice here */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+ SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list)
+
+ return 2;
+ }
+
+ return 0;
+}
- /* Get the appropriate information from the action, we make temp pose */
- pose = MEM_callocN(sizeof(bPose), "pose");
-
- pchan = ownerdata;
- tchan= verify_pose_channel(pose, pchan->name);
- extract_pose_from_action (pose, data->act, t);
-
- chan_calc_mat(tchan);
-
- Mat4CpyMat4(mat, tchan->chan_mat);
+static void kinematic_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bKinematicConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, nocopy)
+ }
+}
- /* Clean up */
- free_pose_channels(pose);
- MEM_freeN(pose);
- }
+static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ bKinematicConstraint *data= con->data;
+
+ if (VALID_CONS_TARGET(ct))
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ else if (ct) {
+ if (data->flag & CONSTRAINT_IK_AUTO) {
+ Object *ob= cob->ob;
+ if (ob == NULL) {
+ Mat4One(ct->matrix);
+ }
+ else {
+ float vec[3];
+ /* move grabtarget into world space */
+ VECCOPY(vec, data->grabtarget);
+ Mat4MulVecfl(ob->obmat, vec);
+ Mat4CpyMat4(ct->matrix, ob->obmat);
+ VECCOPY(ct->matrix[3], vec);
+ }
}
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = (bLocateLikeConstraint*)con->data;
- Object *ob= data->tar;
+ else
+ Mat4One(ct->matrix);
+ }
+}
+
+static bConstraintTypeInfo CTI_KINEMATIC = {
+ CONSTRAINT_TYPE_KINEMATIC, /* type */
+ sizeof(bKinematicConstraint), /* size */
+ "IK", /* name */
+ "bKinematicConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ kinematic_new_data, /* new data */
+ kinematic_get_tars, /* get constraint targets */
+ kinematic_flush_tars, /* flush constraint targets */
+ kinematic_get_tarmat, /* get target matrix */
+ NULL /* evaluate - solved as separate loop */
+};
+
+/* -------- Follow-Path Constraint ---------- */
+
+static void followpath_new_data (void *cdata)
+{
+ bFollowPathConstraint *data= (bFollowPathConstraint *)cdata;
+
+ data->trackflag = TRACK_Y;
+ data->upflag = UP_Z;
+ data->offset = 0;
+ data->followflag = 0;
+}
+
+static int followpath_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bFollowPathConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints without subtargets */
+ SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void followpath_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bFollowPathConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
+ }
+}
+
+static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ bFollowPathConstraint *data= con->data;
+
+ if (VALID_CONS_TARGET(ct)) {
+ Curve *cu= ct->tar->data;
+ float q[4], vec[4], dir[3], quat[4], x1;
+ float totmat[4][4];
+ float curvetime;
+
+ Mat4One(totmat);
+ Mat4One(ct->matrix);
+
+ /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
+ * currently for paths to work it needs to go through the bevlist/displist system (ton)
+ */
+
+ /* only happens on reload file, but violates depsgraph still... fix! */
+ if (cu->path==NULL || cu->path->data==NULL)
+ makeDispListCurveTypes(ct->tar, 0);
+
+ if (cu->path && cu->path->data) {
+ curvetime= bsystem_time(ct->tar, (float)ctime, 0.0) - data->offset;
+
+ if (calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
+ curvetime /= cu->pathlen;
+ CLAMP(curvetime, 0.0, 1.0);
+ }
- if (data->tar) {
- if (strlen(data->subtarget)) {
- bPoseChannel *pchan;
- float tmat[4][4];
- float bsize[3]={1, 1, 1};
+ if ( where_on_path(ct->tar, curvetime, vec, dir) ) {
+ if (data->followflag) {
+ vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat);
- pchan = get_pose_channel(ob->pose, data->subtarget);
- if (pchan) {
- Mat4CpyMat4(tmat, pchan->pose_mat);
-
- if (data->flag & LOCLIKE_TIP)
- VECCOPY(tmat[3], pchan->pose_tail);
-
- Mat4MulMat4 (mat, tmat, ob->obmat);
- }
- else
- Mat4CpyMat4 (mat, ob->obmat);
+ Normalize(dir);
+ q[0]= (float)cos(0.5*vec[3]);
+ x1= (float)sin(0.5*vec[3]);
+ q[1]= -x1*dir[0];
+ q[2]= -x1*dir[1];
+ q[3]= -x1*dir[2];
+ QuatMul(quat, q, quat);
- VECCOPY(size, bsize); // what's this hack for?
- }
- else {
- Mat4CpyMat4 (mat, ob->obmat);
- VECCOPY(size, data->tar->size); // what's this hack for?
+ QuatToMat4(quat, totmat);
}
- valid=1;
+ VECCOPY(totmat[3], vec);
+
+ Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
}
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = (bMinMaxConstraint*)con->data;
+ }
+ }
+ else if (ct)
+ Mat4One(ct->matrix);
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- data = (bRotateLikeConstraint*)con->data;
+static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float obmat[4][4];
+ float size[3], obsize[3];
+
+ /* get Object local transform (loc/rot/size) to determine transformation from path */
+ //object_to_mat4(ob, obmat);
+ Mat4CpyMat4(obmat, cob->matrix); // FIXME!!!
+
+ /* get scaling of object before applying constraint */
+ Mat4ToSize(cob->matrix, size);
+
+ /* apply targetmat - containing location on path, and rotation */
+ Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ /* un-apply scaling caused by path */
+ Mat4ToSize(cob->matrix, obsize);
+ if (obsize[0])
+ VecMulf(cob->matrix[0], size[0] / obsize[0]);
+ if (obsize[1])
+ VecMulf(cob->matrix[1], size[1] / obsize[1]);
+ if (obsize[2])
+ VecMulf(cob->matrix[2], size[2] / obsize[2]);
+ }
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data;
- data = (bSizeLikeConstraint*)con->data;
+static bConstraintTypeInfo CTI_FOLLOWPATH = {
+ CONSTRAINT_TYPE_FOLLOWPATH, /* type */
+ sizeof(bFollowPathConstraint), /* size */
+ "Follow Path", /* name */
+ "bFollowPathConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ followpath_new_data, /* new data */
+ followpath_get_tars, /* get constraint targets */
+ followpath_flush_tars, /* flush constraint targets */
+ followpath_get_tarmat, /* get target matrix */
+ followpath_evaluate /* evaluate */
+};
+
+/* --------- Limit Location --------- */
+
+
+static void loclimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bLocLimitConstraint *data = con->data;
+
+ if (data->flag & LIMIT_XMIN) {
+ if (cob->matrix[3][0] < data->xmin)
+ cob->matrix[3][0] = data->xmin;
+ }
+ if (data->flag & LIMIT_XMAX) {
+ if (cob->matrix[3][0] > data->xmax)
+ cob->matrix[3][0] = data->xmax;
+ }
+ if (data->flag & LIMIT_YMIN) {
+ if (cob->matrix[3][1] < data->ymin)
+ cob->matrix[3][1] = data->ymin;
+ }
+ if (data->flag & LIMIT_YMAX) {
+ if (cob->matrix[3][1] > data->ymax)
+ cob->matrix[3][1] = data->ymax;
+ }
+ if (data->flag & LIMIT_ZMIN) {
+ if (cob->matrix[3][2] < data->zmin)
+ cob->matrix[3][2] = data->zmin;
+ }
+ if (data->flag & LIMIT_ZMAX) {
+ if (cob->matrix[3][2] > data->zmax)
+ cob->matrix[3][2] = data->zmax;
+ }
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- data = (bTrackToConstraint*)con->data;
+static bConstraintTypeInfo CTI_LOCLIMIT = {
+ CONSTRAINT_TYPE_LOCLIMIT, /* type */
+ sizeof(bLocLimitConstraint), /* size */
+ "Limit Location", /* name */
+ "bLocLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ loclimit_evaluate /* evaluate */
+};
+
+/* -------- Limit Rotation --------- */
+
+static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bRotLimitConstraint *data = con->data;
+ float loc[3];
+ float eul[3];
+ float size[3];
+
+ VECCOPY(loc, cob->matrix[3]);
+ Mat4ToSize(cob->matrix, size);
+
+ Mat4ToEul(cob->matrix, eul);
+
+ /* eulers: radians to degrees! */
+ eul[0] = (eul[0] / M_PI * 180);
+ eul[1] = (eul[1] / M_PI * 180);
+ eul[2] = (eul[2] / M_PI * 180);
+
+ /* limiting of euler values... */
+ if (data->flag & LIMIT_XROT) {
+ if (eul[0] < data->xmin)
+ eul[0] = data->xmin;
+
+ if (eul[0] > data->xmax)
+ eul[0] = data->xmax;
+ }
+ if (data->flag & LIMIT_YROT) {
+ if (eul[1] < data->ymin)
+ eul[1] = data->ymin;
+
+ if (eul[1] > data->ymax)
+ eul[1] = data->ymax;
+ }
+ if (data->flag & LIMIT_ZROT) {
+ if (eul[2] < data->zmin)
+ eul[2] = data->zmin;
+
+ if (eul[2] > data->zmax)
+ eul[2] = data->zmax;
+ }
+
+ /* eulers: degrees to radians ! */
+ eul[0] = (eul[0] / 180 * M_PI);
+ eul[1] = (eul[1] / 180 * M_PI);
+ eul[2] = (eul[2] / 180 * M_PI);
+
+ LocEulSizeToMat4(cob->matrix, loc, eul, size);
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data;
- data = (bKinematicConstraint*)con->data;
+static bConstraintTypeInfo CTI_ROTLIMIT = {
+ CONSTRAINT_TYPE_ROTLIMIT, /* type */
+ sizeof(bRotLimitConstraint), /* size */
+ "Limit Rotation", /* name */
+ "bRotLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ rotlimit_evaluate /* evaluate */
+};
+
+/* --------- Limit Scaling --------- */
+
+
+static void sizelimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bSizeLimitConstraint *data = con->data;
+ float obsize[3], size[3];
+
+ Mat4ToSize(cob->matrix, size);
+ Mat4ToSize(cob->matrix, obsize);
+
+ if (data->flag & LIMIT_XMIN) {
+ if (size[0] < data->xmin)
+ size[0] = data->xmin;
+ }
+ if (data->flag & LIMIT_XMAX) {
+ if (size[0] > data->xmax)
+ size[0] = data->xmax;
+ }
+ if (data->flag & LIMIT_YMIN) {
+ if (size[1] < data->ymin)
+ size[1] = data->ymin;
+ }
+ if (data->flag & LIMIT_YMAX) {
+ if (size[1] > data->ymax)
+ size[1] = data->ymax;
+ }
+ if (data->flag & LIMIT_ZMIN) {
+ if (size[2] < data->zmin)
+ size[2] = data->zmin;
+ }
+ if (data->flag & LIMIT_ZMAX) {
+ if (size[2] > data->zmax)
+ size[2] = data->zmax;
+ }
+
+ if (obsize[0])
+ VecMulf(cob->matrix[0], size[0]/obsize[0]);
+ if (obsize[1])
+ VecMulf(cob->matrix[1], size[1]/obsize[1]);
+ if (obsize[2])
+ VecMulf(cob->matrix[2], size[2]/obsize[2]);
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else if (data->flag & CONSTRAINT_IK_AUTO) {
- Object *ob= ownerdata;
-
- if(ob==NULL)
- Mat4One(mat);
- else {
- float vec[3];
- /* move grabtarget into world space */
- VECCOPY(vec, data->grabtarget);
- Mat4MulVecfl(ob->obmat, vec);
- Mat4CpyMat4(mat, ob->obmat);
- VECCOPY(mat[3], vec);
- }
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data;
- data = (bLockTrackConstraint*)con->data;
+static bConstraintTypeInfo CTI_SIZELIMIT = {
+ CONSTRAINT_TYPE_SIZELIMIT, /* type */
+ sizeof(bSizeLimitConstraint), /* size */
+ "Limit Scaling", /* name */
+ "bSizeLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ sizelimit_evaluate /* evaluate */
+};
+
+/* ----------- Copy Location ------------- */
+
+static void loclike_new_data (void *cdata)
+{
+ bLocateLikeConstraint *data= (bLocateLikeConstraint *)cdata;
+
+ data->flag = LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
+}
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid=1;
- }
- else
- Mat4One (mat);
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
- data = (bFollowPathConstraint*)con->data;
+static int loclike_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bLocateLikeConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
- if (data->tar){
- Curve *cu;
- float q[4], vec[4], dir[3], *quat, x1, totmat[4][4];
- float curvetime;
+static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bLocateLikeConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
- Mat4One (totmat);
- Mat4One (mat);
+static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bLocateLikeConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float offset[3] = {0.0f, 0.0f, 0.0f};
+
+ if (data->flag & LOCLIKE_OFFSET)
+ VECCOPY(offset, cob->matrix[3]);
+
+ if (data->flag & LOCLIKE_X) {
+ cob->matrix[3][0] = ct->matrix[3][0];
+
+ if (data->flag & LOCLIKE_X_INVERT) cob->matrix[3][0] *= -1;
+ cob->matrix[3][0] += offset[0];
+ }
+ if (data->flag & LOCLIKE_Y) {
+ cob->matrix[3][1] = ct->matrix[3][1];
+
+ if (data->flag & LOCLIKE_Y_INVERT) cob->matrix[3][1] *= -1;
+ cob->matrix[3][1] += offset[1];
+ }
+ if (data->flag & LOCLIKE_Z) {
+ cob->matrix[3][2] = ct->matrix[3][2];
+
+ if (data->flag & LOCLIKE_Z_INVERT) cob->matrix[3][2] *= -1;
+ cob->matrix[3][2] += offset[2];
+ }
+ }
+}
- cu= data->tar->data;
+static bConstraintTypeInfo CTI_LOCLIKE = {
+ CONSTRAINT_TYPE_LOCLIKE, /* type */
+ sizeof(bLocateLikeConstraint), /* size */
+ "Copy Location", /* name */
+ "bLocateLikeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ loclike_new_data, /* new data */
+ loclike_get_tars, /* get constraint targets */
+ loclike_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ loclike_evaluate /* evaluate */
+};
+
+/* ----------- Copy Rotation ------------- */
+
+static void rotlike_new_data (void *cdata)
+{
+ bRotateLikeConstraint *data= (bRotateLikeConstraint *)cdata;
+
+ data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
+}
- /* note; when creating constraints that follow path, the curve gets the CU_PATH set now,
- currently for paths to work it needs to go through the bevlist/displist system (ton) */
-
- if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
- makeDispListCurveTypes(data->tar, 0);
- if(cu->path && cu->path->data) {
-
- curvetime= bsystem_time(data->tar, data->tar->parent, (float)ctime, 0.0) - data->offset;
+static int rotlike_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bRotateLikeConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
- if(calc_ipo_spec(cu->ipo, CU_SPEED, &curvetime)==0) {
- curvetime /= cu->pathlen;
- CLAMP(curvetime, 0.0, 1.0);
- }
+static void rotlike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bRotateLikeConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
- if(where_on_path(data->tar, curvetime, vec, dir) ) {
+static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bRotateLikeConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float loc[3];
+ float eul[3], obeul[3];
+ float size[3];
+
+ VECCOPY(loc, cob->matrix[3]);
+ Mat4ToSize(cob->matrix, size);
+
+ Mat4ToEul(ct->matrix, eul);
+ Mat4ToEul(cob->matrix, obeul);
+
+ if ((data->flag & ROTLIKE_X)==0)
+ eul[0] = obeul[0];
+ else {
+ if (data->flag & ROTLIKE_OFFSET)
+ euler_rot(eul, obeul[0], 'x');
+
+ if (data->flag & ROTLIKE_X_INVERT)
+ eul[0] *= -1;
+ }
+
+ if ((data->flag & ROTLIKE_Y)==0)
+ eul[1] = obeul[1];
+ else {
+ if (data->flag & ROTLIKE_OFFSET)
+ euler_rot(eul, obeul[1], 'y');
+
+ if (data->flag & ROTLIKE_Y_INVERT)
+ eul[1] *= -1;
+ }
+
+ if ((data->flag & ROTLIKE_Z)==0)
+ eul[2] = obeul[2];
+ else {
+ if (data->flag & ROTLIKE_OFFSET)
+ euler_rot(eul, obeul[2], 'z');
+
+ if (data->flag & ROTLIKE_Z_INVERT)
+ eul[2] *= -1;
+ }
+
+ compatible_eul(eul, obeul);
+ LocEulSizeToMat4(cob->matrix, loc, eul, size);
+ }
+}
- if(data->followflag){
- quat= vectoquat(dir, (short) data->trackflag, (short) data->upflag);
+static bConstraintTypeInfo CTI_ROTLIKE = {
+ CONSTRAINT_TYPE_ROTLIKE, /* type */
+ sizeof(bRotateLikeConstraint), /* size */
+ "Copy Rotation", /* name */
+ "bRotateLikeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ rotlike_new_data, /* new data */
+ rotlike_get_tars, /* get constraint targets */
+ rotlike_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ rotlike_evaluate /* evaluate */
+};
+
+/* ---------- Copy Scaling ---------- */
+
+static void sizelike_new_data (void *cdata)
+{
+ bSizeLikeConstraint *data= (bSizeLikeConstraint *)cdata;
+
+ data->flag = SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
+}
- Normalize(dir);
- q[0]= (float)cos(0.5*vec[3]);
- x1= (float)sin(0.5*vec[3]);
- q[1]= -x1*dir[0];
- q[2]= -x1*dir[1];
- q[3]= -x1*dir[2];
- QuatMul(quat, q, quat);
-
+static int sizelike_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bSizeLikeConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
- QuatToMat4(quat, totmat);
- }
- VECCOPY(totmat[3], vec);
+static void sizelike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bSizeLikeConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
- Mat4MulSerie(mat, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
- }
- }
- valid=1;
+static void sizelike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bSizeLikeConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float obsize[3], size[3];
+
+ Mat4ToSize(ct->matrix, size);
+ Mat4ToSize(cob->matrix, obsize);
+
+ if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) {
+ if (data->flag & SIZELIKE_OFFSET) {
+ size[0] += (obsize[0] - 1.0f);
+ VecMulf(cob->matrix[0], size[0] / obsize[0]);
}
else
- Mat4One (mat);
+ VecMulf(cob->matrix[0], size[0] / obsize[0]);
}
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
- data = (bStretchToConstraint*)con->data;
-
- if (data->tar){
- constraint_target_to_mat4(data->tar, data->subtarget, mat, size);
- valid = 1;
+ if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) {
+ if (data->flag & SIZELIKE_OFFSET) {
+ size[1] += (obsize[1] - 1.0f);
+ VecMulf(cob->matrix[1], size[1] / obsize[1]);
}
else
- Mat4One (mat);
+ VecMulf(cob->matrix[1], size[1] / obsize[1]);
}
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data;
- data = (bClampToConstraint*)con->data;
-
- if (data->tar) {
- Curve *cu= data->tar->data;
-
- /* note; when creating constraints that follow path, the curve gets the CU_PATH set now,
- currently for paths to work it needs to go through the bevlist/displist system (ton) */
-
- if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
- makeDispListCurveTypes(data->tar, 0);
+ if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) {
+ if (data->flag & SIZELIKE_OFFSET) {
+ size[2] += (obsize[2] - 1.0f);
+ VecMulf(cob->matrix[2], size[2] / obsize[2]);
}
-
- Mat4One (mat);
+ else
+ VecMulf(cob->matrix[2], size[2] / obsize[2]);
}
- break;
-
- default:
- Mat4One(mat);
- break;
}
+}
- return valid;
+static bConstraintTypeInfo CTI_SIZELIKE = {
+ CONSTRAINT_TYPE_SIZELIKE, /* type */
+ sizeof(bSizeLikeConstraint), /* size */
+ "Copy Scale", /* name */
+ "bSizeLikeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ sizelike_new_data, /* new data */
+ sizelike_get_tars, /* get constraint targets */
+ sizelike_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ sizelike_evaluate /* evaluate */
+};
+
+/* ----------- Python Constraint -------------- */
+
+static void pycon_free (bConstraint *con)
+{
+ bPythonConstraint *data= con->data;
+
+ /* id-properties */
+ IDP_FreeProperty(data->prop);
+ MEM_freeN(data->prop);
+
+ /* multiple targets */
+ BLI_freelistN(&data->targets);
+}
+
+static void pycon_relink (bConstraint *con)
+{
+ bPythonConstraint *data= con->data;
+
+ ID_NEW(data->text);
}
-/* only called during solve_constraints */
-/* bone constraints create a fake object to work on, then ob is a workob */
-/* if ownerdata is set, it's the posechannel */
-void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, void *ownerdata, float targetmat[][4])
+static void pycon_copy (bConstraint *con, bConstraint *srccon)
{
- float M_oldmat[4][4];
- float M_identity[4][4];
+ bPythonConstraint *pycon = (bPythonConstraint *)con->data;
+ bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
- if (!constraint || !ob)
- return;
+ pycon->prop = IDP_CopyProperty(opycon->prop);
+ duplicatelist(&pycon->targets, &opycon->targets);
+}
- Mat4One (M_identity);
+static void pycon_new_data (void *cdata)
+{
+ bPythonConstraint *data= (bPythonConstraint *)cdata;
- switch (constraint->type) {
- case CONSTRAINT_TYPE_NULL:
- case CONSTRAINT_TYPE_KINEMATIC: /* removed */
- break;
+ /* everything should be set correctly by calloc, except for the prop->type constant.*/
+ data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
+ data->prop->type = IDP_GROUP;
+}
+
+static int pycon_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bPythonConstraint *data= con->data;
+
+ list->first = data->targets.first;
+ list->last = data->targets.last;
+
+ return data->tarnum;
+ }
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data;
- float temp[4][4];
-
- data = constraint->data;
- Mat4CpyMat4 (temp, ob->obmat);
+ return 0;
+}
- Mat4MulMat4(ob->obmat, targetmat, temp);
+/* Whether this approach is maintained remains to be seen (aligorith) */
+static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ bPythonConstraint *data= con->data;
+
+ if (VALID_CONS_TARGET(ct)) {
+ /* special exception for curves - depsgraph issues */
+ if (ct->tar->type == OB_CURVE) {
+ Curve *cu= ct->tar->data;
+
+ /* this check is to make sure curve objects get updated on file load correctly.*/
+ if (cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
+ makeDispListCurveTypes(ct->tar, 0);
}
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data;
- float offset[3] = {0.0f, 0.0f, 0.0f};
+
+ /* firstly calculate the matrix the normal way, then let the py-function override
+ * this matrix if it needs to do so
+ */
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ BPY_pyconstraint_target(data, ct);
+ }
+ else if (ct)
+ Mat4One(ct->matrix);
+}
- data = constraint->data;
-
- if (data->flag & LOCLIKE_OFFSET)
- VECCOPY(offset, ob->obmat[3]);
-
- if (data->flag & LOCLIKE_X) {
- ob->obmat[3][0] = targetmat[3][0];
-
- if(data->flag & LOCLIKE_X_INVERT) ob->obmat[3][0] *= -1;
- ob->obmat[3][0] += offset[0];
- }
- if (data->flag & LOCLIKE_Y) {
- ob->obmat[3][1] = targetmat[3][1];
-
- if(data->flag & LOCLIKE_Y_INVERT) ob->obmat[3][1] *= -1;
- ob->obmat[3][1] += offset[1];
- }
- if (data->flag & LOCLIKE_Z) {
- ob->obmat[3][2] = targetmat[3][2];
-
- if(data->flag & LOCLIKE_Z_INVERT) ob->obmat[3][2] *= -1;
- ob->obmat[3][2] += offset[2];
- }
+static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bPythonConstraint *data= con->data;
+
+/* currently removed, until I this can be re-implemented for multiple targets */
+#if 0
+ /* Firstly, run the 'driver' function which has direct access to the objects involved
+ * Technically, this is potentially dangerous as users may abuse this and cause dependency-problems,
+ * but it also allows certain 'clever' rigging hacks to work.
+ */
+ BPY_pyconstraint_driver(data, cob, targets);
+#endif
+
+ /* Now, run the actual 'constraint' function, which should only access the matrices */
+ BPY_pyconstraint_eval(data, cob, targets);
+}
+
+static bConstraintTypeInfo CTI_PYTHON = {
+ CONSTRAINT_TYPE_PYTHON, /* type */
+ sizeof(bPythonConstraint), /* size */
+ "Script", /* name */
+ "bPythonConstraint", /* struct name */
+ pycon_free, /* free data */
+ pycon_relink, /* relink data */
+ pycon_copy, /* copy data */
+ pycon_new_data, /* new data */
+ pycon_get_tars, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ pycon_get_tarmat, /* get target matrix */
+ pycon_evaluate /* evaluate */
+};
+
+/* -------- Action Constraint ----------- */
+
+static void actcon_relink (bConstraint *con)
+{
+ bActionConstraint *data= con->data;
+ ID_NEW(data->act);
+}
+
+static void actcon_new_data (void *cdata)
+{
+ bActionConstraint *data= (bActionConstraint *)cdata;
+
+ /* set type to 20 (Loc X), as 0 is Rot X for backwards compatability */
+ data->type = 20;
+}
+
+static int actcon_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bActionConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void actcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bActionConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ extern void chan_calc_mat(bPoseChannel *chan);
+ bActionConstraint *data = con->data;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float tempmat[4][4], vec[3];
+ float s, t;
+ short axis;
+
+ /* initialise return matrix */
+ Mat4One(ct->matrix);
+
+ /* get the transform matrix of the target */
+ constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+
+ /* determine where in transform range target is */
+ /* data->type is mapped as follows for backwards compatability:
+ * 00,01,02 - rotation (it used to be like this)
+ * 10,11,12 - scaling
+ * 20,21,22 - location
+ */
+ if (data->type < 10) {
+ /* extract rotation (is in whatever space target should be in) */
+ Mat4ToEul(tempmat, vec);
+ vec[0] *= (float)(180.0/M_PI);
+ vec[1] *= (float)(180.0/M_PI);
+ vec[2] *= (float)(180.0/M_PI);
+ axis= data->type;
+ }
+ else if (data->type < 20) {
+ /* extract scaling (is in whatever space target should be in) */
+ Mat4ToSize(tempmat, vec);
+ axis= data->type - 10;
+ }
+ else {
+ /* extract location */
+ VECCOPY(vec, tempmat[3]);
+ axis= data->type - 20;
}
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data;
- float loc[3];
- float eul[3], obeul[3];
- float size[3];
+
+ /* Target defines the animation */
+ s = (vec[axis]-data->min) / (data->max-data->min);
+ CLAMP(s, 0, 1);
+ t = ( s * (data->end-data->start)) + data->start;
+
+ /* Get the appropriate information from the action */
+ if (cob->type == CONSTRAINT_OBTYPE_BONE) {
+ bPose *pose;
+ bPoseChannel *pchan, *tchan;
- data = constraint->data;
+ /* make a temporary pose and evaluate using that */
+ pose = MEM_callocN(sizeof(bPose), "pose");
- VECCOPY(loc, ob->obmat[3]);
- Mat4ToSize(ob->obmat, size);
+ pchan = cob->pchan;
+ tchan= verify_pose_channel(pose, pchan->name);
+ extract_pose_from_action(pose, data->act, t);
- Mat4ToEul(targetmat, eul);
- Mat4ToEul(ob->obmat, obeul);
-
- if(data->flag != (ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z)) {
- if(!(data->flag & ROTLIKE_X)) {
- eul[0]= obeul[0];
- }
- if(!(data->flag & ROTLIKE_Y)) {
- eul[1]= obeul[1];
- }
- if(!(data->flag & ROTLIKE_Z)) {
- eul[2]= obeul[2];
- }
- compatible_eul(eul, obeul);
- }
+ chan_calc_mat(tchan);
- if((data->flag & ROTLIKE_X) && (data->flag & ROTLIKE_X_INVERT))
- eul[0]*=-1;
- if((data->flag & ROTLIKE_Y) && (data->flag & ROTLIKE_Y_INVERT))
- eul[1]*=-1;
- if((data->flag & ROTLIKE_Z) && (data->flag & ROTLIKE_Z_INVERT))
- eul[2]*=-1;
+ Mat4CpyMat4(ct->matrix, tchan->chan_mat);
- LocEulSizeToMat4(ob->obmat, loc, eul, size);
+ /* Clean up */
+ free_pose(pose);
}
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data;
- float obsize[3], size[3];
-
- data = constraint->data;
-
- Mat4ToSize(targetmat, size);
- Mat4ToSize(ob->obmat, obsize);
-
- if (data->flag & SIZELIKE_X && obsize[0] != 0)
- VecMulf(ob->obmat[0], size[0] / obsize[0]);
- if (data->flag & SIZELIKE_Y && obsize[1] != 0)
- VecMulf(ob->obmat[1], size[1] / obsize[1]);
- if (data->flag & SIZELIKE_Z && obsize[2] != 0)
- VecMulf(ob->obmat[2], size[2] / obsize[2]);
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data;
- float val1, val2;
- int index;
- float obmat[4][4],imat[4][4],tarmat[4][4],tmat[4][4];
+ else if (cob->type == CONSTRAINT_OBTYPE_OBJECT) {
+ /* evaluate using workob */
+ what_does_obaction(cob->ob, data->act, t);
+ object_to_mat4(&workob, ct->matrix);
+ }
+ else {
+ /* behaviour undefined... */
+ puts("Error: unknown owner type for Action Constraint");
+ }
+ }
+}
- data = constraint->data;
-
- Mat4CpyMat4(obmat,ob->obmat);
- Mat4CpyMat4(tarmat,targetmat);
-
- if (data->flag&MINMAX_USEROT) {
- /* take rotation of target into account by doing the transaction in target's localspace */
- Mat4Invert(imat,tarmat);
- Mat4MulMat4(tmat,obmat,imat);
- Mat4CpyMat4(obmat,tmat);
- Mat4One(tarmat);
- }
+static void actcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float temp[4][4];
+
+ /* Nice and simple... we just need to multiply the matrices, as the get_target_matrix
+ * function has already taken care of everything else.
+ */
+ Mat4CpyMat4(temp, cob->matrix);
+ Mat4MulMat4(cob->matrix, ct->matrix, temp);
+ }
+}
- switch (data->minmaxflag) {
- case TRACK_Z:
- val1 = tarmat[3][2];
- val2 = obmat[3][2]-data->offset;
- index = 2;
- break;
- case TRACK_Y:
- val1 = tarmat[3][1];
- val2 = obmat[3][1]-data->offset;
- index = 1;
- break;
- case TRACK_X:
- val1 = tarmat[3][0];
- val2 = obmat[3][0]-data->offset;
- index = 0;
- break;
- case TRACK_nZ:
- val2 = tarmat[3][2];
- val1 = obmat[3][2]-data->offset;
- index = 2;
- break;
- case TRACK_nY:
- val2 = tarmat[3][1];
- val1 = obmat[3][1]-data->offset;
- index = 1;
- break;
- case TRACK_nX:
- val2 = tarmat[3][0];
- val1 = obmat[3][0]-data->offset;
- index = 0;
- break;
- default:
- return;
- }
-
- if (val1 > val2) {
- obmat[3][index] = tarmat[3][index] + data->offset;
- if (data->flag & MINMAX_STICKY) {
- if (data->flag & MINMAX_STUCK) {
- VECCOPY(obmat[3], data->cache);
- }
- else {
- VECCOPY(data->cache, obmat[3]);
- data->flag|=MINMAX_STUCK;
- }
- }
- if (data->flag & MINMAX_USEROT) {
- /* get out of localspace */
- Mat4MulMat4(tmat,obmat,targetmat);
- Mat4CpyMat4(ob->obmat,tmat);
- }
- else {
- VECCOPY(ob->obmat[3],obmat[3]);
- }
- }
- else {
- data->flag&=~MINMAX_STUCK;
- }
-
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data;
- float size[3];
- float vec[3];
- float totmat[3][3];
- float tmat[4][4];
+static bConstraintTypeInfo CTI_ACTION = {
+ CONSTRAINT_TYPE_ACTION, /* type */
+ sizeof(bActionConstraint), /* size */
+ "Action", /* name */
+ "bActionConstraint", /* struct name */
+ NULL, /* free data */
+ actcon_relink, /* relink data */
+ NULL, /* copy data */
+ actcon_new_data, /* new data */
+ actcon_get_tars, /* get constraint targets */
+ actcon_flush_tars, /* flush constraint targets */
+ actcon_get_tarmat, /* get target matrix */
+ actcon_evaluate /* evaluate */
+};
+
+/* --------- Locked Track ---------- */
+
+static void locktrack_new_data (void *cdata)
+{
+ bLockTrackConstraint *data= (bLockTrackConstraint *)cdata;
+
+ data->trackflag = TRACK_Y;
+ data->lockflag = LOCK_Z;
+}
- data=(bTrackToConstraint*)constraint->data;
-
- if (data->tar) {
- /* Get size property, since ob->size is only the object's own relative size, not its global one */
- Mat4ToSize (ob->obmat, size);
-
- Mat4CpyMat4 (M_oldmat, ob->obmat);
-
- // Clear the object's rotation
- ob->obmat[0][0]=size[0];
- ob->obmat[0][1]=0;
- ob->obmat[0][2]=0;
- ob->obmat[1][0]=0;
- ob->obmat[1][1]=size[1];
- ob->obmat[1][2]=0;
- ob->obmat[2][0]=0;
- ob->obmat[2][1]=0;
- ob->obmat[2][2]=size[2];
+static int locktrack_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bLockTrackConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
-
- VecSubf(vec, ob->obmat[3], targetmat[3]);
- vectomat(vec, targetmat[2],
- (short)data->reserved1, (short)data->reserved2,
- data->flags, totmat);
-
- Mat4CpyMat4(tmat, ob->obmat);
-
- Mat4MulMat34(ob->obmat, totmat, tmat);
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
+ return 0;
+}
+
+static void locktrack_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bLockTrackConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bLockTrackConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ if (VALID_CONS_TARGET(ct)) {
+ float vec[3],vec2[3];
+ float totmat[3][3];
+ float tmpmat[3][3];
+ float invmat[3][3];
+ float tmat[4][4];
+ float mdet;
+
+ /* Vector object -> target */
+ VecSubf(vec, ct->matrix[3], cob->matrix[3]);
+ switch (data->lockflag){
+ case LOCK_X: /* LOCK X */
{
- bLockTrackConstraint *data;
- float vec[3],vec2[3];
- float totmat[3][3];
- float tmpmat[3][3];
- float invmat[3][3];
- float tmat[4][4];
- float mdet;
-
- data=(bLockTrackConstraint*)constraint->data;
-
- if (data->tar) {
- Mat4CpyMat4 (M_oldmat, ob->obmat);
-
- /* Vector object -> target */
- VecSubf(vec, targetmat[3], ob->obmat[3]);
- switch (data->lockflag){
- case LOCK_X: /* LOCK X */
- {
- switch (data->trackflag){
- case TRACK_Y: /* LOCK X TRACK Y */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[0]);
- VecSubf(totmat[1], vec, vec2);
- Normalize(totmat[1]);
-
- /* the x axis is fixed*/
- totmat[0][0] = ob->obmat[0][0];
- totmat[0][1] = ob->obmat[0][1];
- totmat[0][2] = ob->obmat[0][2];
- Normalize(totmat[0]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[2], totmat[0], totmat[1]);
- }
- break;
- case TRACK_Z: /* LOCK X TRACK Z */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[0]);
- VecSubf(totmat[2], vec, vec2);
- Normalize(totmat[2]);
-
- /* the x axis is fixed*/
- totmat[0][0] = ob->obmat[0][0];
- totmat[0][1] = ob->obmat[0][1];
- totmat[0][2] = ob->obmat[0][2];
- Normalize(totmat[0]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[1], totmat[2], totmat[0]);
- }
- break;
- case TRACK_nY: /* LOCK X TRACK -Y */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[0]);
- VecSubf(totmat[1], vec, vec2);
- Normalize(totmat[1]);
- VecMulf(totmat[1],-1);
-
- /* the x axis is fixed*/
- totmat[0][0] = ob->obmat[0][0];
- totmat[0][1] = ob->obmat[0][1];
- totmat[0][2] = ob->obmat[0][2];
- Normalize(totmat[0]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[2], totmat[0], totmat[1]);
- }
- break;
- case TRACK_nZ: /* LOCK X TRACK -Z */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[0]);
- VecSubf(totmat[2], vec, vec2);
- Normalize(totmat[2]);
- VecMulf(totmat[2],-1);
-
- /* the x axis is fixed*/
- totmat[0][0] = ob->obmat[0][0];
- totmat[0][1] = ob->obmat[0][1];
- totmat[0][2] = ob->obmat[0][2];
- Normalize(totmat[0]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[1], totmat[2], totmat[0]);
- }
- break;
- default:
- {
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
- }
- break;
- }
- }
+ switch (data->trackflag) {
+ case TRACK_Y: /* LOCK X TRACK Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[0]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalize(totmat[1]);
+
+ /* the x axis is fixed */
+ totmat[0][0] = cob->matrix[0][0];
+ totmat[0][1] = cob->matrix[0][1];
+ totmat[0][2] = cob->matrix[0][2];
+ Normalize(totmat[0]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
break;
- case LOCK_Y: /* LOCK Y */
- {
- switch (data->trackflag){
- case TRACK_X: /* LOCK Y TRACK X */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[1]);
- VecSubf(totmat[0], vec, vec2);
- Normalize(totmat[0]);
-
- /* the y axis is fixed*/
- totmat[1][0] = ob->obmat[1][0];
- totmat[1][1] = ob->obmat[1][1];
- totmat[1][2] = ob->obmat[1][2];
- Normalize(totmat[1]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[2], totmat[0], totmat[1]);
- }
- break;
- case TRACK_Z: /* LOCK Y TRACK Z */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[1]);
- VecSubf(totmat[2], vec, vec2);
- Normalize(totmat[2]);
-
- /* the y axis is fixed*/
- totmat[1][0] = ob->obmat[1][0];
- totmat[1][1] = ob->obmat[1][1];
- totmat[1][2] = ob->obmat[1][2];
- Normalize(totmat[1]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[0], totmat[1], totmat[2]);
- }
- break;
- case TRACK_nX: /* LOCK Y TRACK -X */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[1]);
- VecSubf(totmat[0], vec, vec2);
- Normalize(totmat[0]);
- VecMulf(totmat[0],-1);
-
- /* the y axis is fixed*/
- totmat[1][0] = ob->obmat[1][0];
- totmat[1][1] = ob->obmat[1][1];
- totmat[1][2] = ob->obmat[1][2];
- Normalize(totmat[1]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[2], totmat[0], totmat[1]);
- }
- break;
- case TRACK_nZ: /* LOCK Y TRACK -Z */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[1]);
- VecSubf(totmat[2], vec, vec2);
- Normalize(totmat[2]);
- VecMulf(totmat[2],-1);
-
- /* the y axis is fixed*/
- totmat[1][0] = ob->obmat[1][0];
- totmat[1][1] = ob->obmat[1][1];
- totmat[1][2] = ob->obmat[1][2];
- Normalize(totmat[1]);
-
- /* the z axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[0], totmat[1], totmat[2]);
- }
- break;
- default:
- {
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
- }
- break;
- }
- }
+ case TRACK_Z: /* LOCK X TRACK Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[0]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalize(totmat[2]);
+
+ /* the x axis is fixed */
+ totmat[0][0] = cob->matrix[0][0];
+ totmat[0][1] = cob->matrix[0][1];
+ totmat[0][2] = cob->matrix[0][2];
+ Normalize(totmat[0]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
break;
- case LOCK_Z: /* LOCK Z */
- {
- switch (data->trackflag){
- case TRACK_X: /* LOCK Z TRACK X */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[2]);
- VecSubf(totmat[0], vec, vec2);
- Normalize(totmat[0]);
-
- /* the z axis is fixed*/
- totmat[2][0] = ob->obmat[2][0];
- totmat[2][1] = ob->obmat[2][1];
- totmat[2][2] = ob->obmat[2][2];
- Normalize(totmat[2]);
-
- /* the x axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[1], totmat[2], totmat[0]);
- }
- break;
- case TRACK_Y: /* LOCK Z TRACK Y */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[2]);
- VecSubf(totmat[1], vec, vec2);
- Normalize(totmat[1]);
-
- /* the z axis is fixed*/
- totmat[2][0] = ob->obmat[2][0];
- totmat[2][1] = ob->obmat[2][1];
- totmat[2][2] = ob->obmat[2][2];
- Normalize(totmat[2]);
-
- /* the x axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[0], totmat[1], totmat[2]);
- }
- break;
- case TRACK_nX: /* LOCK Z TRACK -X */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[2]);
- VecSubf(totmat[0], vec, vec2);
- Normalize(totmat[0]);
- VecMulf(totmat[0],-1);
-
- /* the z axis is fixed*/
- totmat[2][0] = ob->obmat[2][0];
- totmat[2][1] = ob->obmat[2][1];
- totmat[2][2] = ob->obmat[2][2];
- Normalize(totmat[2]);
+ case TRACK_nY: /* LOCK X TRACK -Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[0]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalize(totmat[1]);
+ VecMulf(totmat[1],-1);
+
+ /* the x axis is fixed */
+ totmat[0][0] = cob->matrix[0][0];
+ totmat[0][1] = cob->matrix[0][1];
+ totmat[0][2] = cob->matrix[0][2];
+ Normalize(totmat[0]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
+ }
+ break;
+ case TRACK_nZ: /* LOCK X TRACK -Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[0]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalize(totmat[2]);
+ VecMulf(totmat[2],-1);
- /* the x axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[1], totmat[2], totmat[0]);
- }
- break;
- case TRACK_nY: /* LOCK Z TRACK -Y */
- {
- /* Projection of Vector on the plane */
- Projf(vec2, vec, ob->obmat[2]);
- VecSubf(totmat[1], vec, vec2);
- Normalize(totmat[1]);
- VecMulf(totmat[1],-1);
-
- /* the z axis is fixed*/
- totmat[2][0] = ob->obmat[2][0];
- totmat[2][1] = ob->obmat[2][1];
- totmat[2][2] = ob->obmat[2][2];
- Normalize(totmat[2]);
+ /* the x axis is fixed */
+ totmat[0][0] = cob->matrix[0][0];
+ totmat[0][1] = cob->matrix[0][1];
+ totmat[0][2] = cob->matrix[0][2];
+ Normalize(totmat[0]);
- /* the x axis gets mapped onto
- a third orthogonal vector */
- Crossf(totmat[0], totmat[1], totmat[2]);
- }
- break;
- default:
- {
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
- }
- break;
- }
- }
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
break;
default:
- {
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
- }
- break;
- }
- /* Block to keep matrix heading */
- tmpmat[0][0] = ob->obmat[0][0];tmpmat[0][1] = ob->obmat[0][1];tmpmat[0][2] = ob->obmat[0][2];
- tmpmat[1][0] = ob->obmat[1][0];tmpmat[1][1] = ob->obmat[1][1];tmpmat[1][2] = ob->obmat[1][2];
- tmpmat[2][0] = ob->obmat[2][0];tmpmat[2][1] = ob->obmat[2][1];tmpmat[2][2] = ob->obmat[2][2];
- Normalize(tmpmat[0]);
- Normalize(tmpmat[1]);
- Normalize(tmpmat[2]);
- Mat3Inv(invmat,tmpmat);
- Mat3MulMat3(tmpmat,totmat,invmat);
- totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
- totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
- totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
-
- Mat4CpyMat4(tmat, ob->obmat);
-
- mdet = Det3x3( totmat[0][0],totmat[0][1],totmat[0][2],
- totmat[1][0],totmat[1][1],totmat[1][2],
- totmat[2][0],totmat[2][1],totmat[2][2]);
- if (mdet==0)
{
totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
}
-
- /* apply out transformaton to the object */
- Mat4MulMat34(ob->obmat, totmat, tmat);
- }
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data;
- float obmat[4][4];
- float size[3], obsize[3];
-
- data=(bFollowPathConstraint*)constraint->data;
-
- if (data->tar) {
- /* get Object local transform (loc/rot/size) to determine transformation from path */
- object_to_mat4(ob, obmat);
-
- /* get scaling of object before applying constraint */
- Mat4ToSize(ob->obmat, size);
-
- /* apply targetmat - containing location on path, and rotation */
- Mat4MulSerie(ob->obmat, targetmat, obmat, NULL, NULL, NULL, NULL, NULL, NULL);
-
- /* un-apply scaling caused by path */
- Mat4ToSize(ob->obmat, obsize);
- if (obsize[0] != 0)
- VecMulf(ob->obmat[0], size[0] / obsize[0]);
- if (obsize[1] != 0)
- VecMulf(ob->obmat[1], size[1] / obsize[1]);
- if (obsize[2] != 0)
- VecMulf(ob->obmat[2], size[2] / obsize[2]);
+ break;
}
}
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data;
- float size[3],scale[3],vec[3],xx[3],zz[3],orth[3];
- float totmat[3][3];
- float tmat[4][4];
- float dist;
-
- data=(bStretchToConstraint*)constraint->data;
- Mat4ToSize (ob->obmat, size);
-
- if (data->tar) {
- /* store X orientation before destroying obmat */
- xx[0] = ob->obmat[0][0];
- xx[1] = ob->obmat[0][1];
- xx[2] = ob->obmat[0][2];
- Normalize(xx);
-
- /* store Z orientation before destroying obmat */
- zz[0] = ob->obmat[2][0];
- zz[1] = ob->obmat[2][1];
- zz[2] = ob->obmat[2][2];
- Normalize(zz);
-
- VecSubf(vec, ob->obmat[3], targetmat[3]);
- vec[0] /= size[0];
- vec[1] /= size[1];
- vec[2] /= size[2];
-
- dist = Normalize(vec);
- //dist = VecLenf( ob->obmat[3], targetmat[3]);
-
- if (data->orglength == 0) data->orglength = dist;
- if (data->bulge ==0) data->bulge = 1.0;
-
- scale[1] = dist/data->orglength;
- switch (data->volmode) {
- /* volume preserving scaling */
- case VOLUME_XZ :
- scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
- scale[2] = scale[0];
- break;
- case VOLUME_X:
- scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
- scale[2] = 1.0;
- break;
- case VOLUME_Z:
- scale[0] = 1.0;
- scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
- break;
- /* don't care for volume */
- case NO_VOLUME:
- scale[0] = 1.0;
- scale[2] = 1.0;
- break;
- default: /* should not happen, but in case*/
- return;
- } /* switch (data->volmode) */
-
- /* Clear the object's rotation and scale */
- ob->obmat[0][0]=size[0]*scale[0];
- ob->obmat[0][1]=0;
- ob->obmat[0][2]=0;
- ob->obmat[1][0]=0;
- ob->obmat[1][1]=size[1]*scale[1];
- ob->obmat[1][2]=0;
- ob->obmat[2][0]=0;
- ob->obmat[2][1]=0;
- ob->obmat[2][2]=size[2]*scale[2];
-
- VecSubf(vec, ob->obmat[3], targetmat[3]);
- Normalize(vec);
- /* new Y aligns object target connection*/
- totmat[1][0] = -vec[0];
- totmat[1][1] = -vec[1];
- totmat[1][2] = -vec[2];
- switch (data->plane) {
- case PLANE_X:
- /* build new Z vector */
- /* othogonal to "new Y" "old X! plane */
- Crossf(orth, vec, xx);
- Normalize(orth);
-
- /* new Z*/
- totmat[2][0] = orth[0];
- totmat[2][1] = orth[1];
- totmat[2][2] = orth[2];
-
- /* we decided to keep X plane*/
- Crossf(xx,orth, vec);
- Normalize(xx);
- totmat[0][0] = xx[0];
- totmat[0][1] = xx[1];
- totmat[0][2] = xx[2];
- break;
- case PLANE_Z:
- /* build new X vector */
- /* othogonal to "new Y" "old Z! plane */
- Crossf(orth, vec, zz);
- Normalize(orth);
-
- /* new X */
- totmat[0][0] = -orth[0];
- totmat[0][1] = -orth[1];
- totmat[0][2] = -orth[2];
-
- /* we decided to keep Z */
- Crossf(zz,orth, vec);
- Normalize(zz);
- totmat[2][0] = zz[0];
- totmat[2][1] = zz[1];
- totmat[2][2] = zz[2];
- break;
- } /* switch (data->plane) */
-
- Mat4CpyMat4(tmat, ob->obmat);
-
- Mat4MulMat34(ob->obmat, totmat, tmat);
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
+ break;
+ case LOCK_Y: /* LOCK Y */
{
- bLocLimitConstraint *data;
-
- data = constraint->data;
-
- /* limit location relative to origin or parent */
- if ((data->flag2 & LIMIT_NOPARENT) && ob->parent) {
- /* limiting relative to parent */
- float parmat[4][4]; /* matrix of parent */
- float objLoc[3], parLoc[3]; /* location of object, and location of parent */
- float relLoc[3]; /* objLoc - parLoc*/
-
- /* get matrix of parent */
- Mat4CpyMat4(parmat, ob->parent->obmat);
-
- /* get locations as vectors */
- objLoc[0] = ob->obmat[3][0];
- objLoc[1] = ob->obmat[3][1];
- objLoc[2] = ob->obmat[3][2];
-
- parLoc[0] = parmat[3][0];
- parLoc[1] = parmat[3][1];
- parLoc[2] = parmat[3][2];
-
- /* get relative location of obj from parent */
- VecSubf(relLoc, objLoc, parLoc);
-
- /* limiting location */
- if (data->flag & LIMIT_XMIN) {
- if(relLoc[0] < data->xmin)
- ob->obmat[3][0] = (parLoc[0]+data->xmin);
- }
- if (data->flag & LIMIT_XMAX) {
- if (relLoc[0] > data->xmax)
- ob->obmat[3][0] = (parLoc[0]+data->xmax);
- }
- if (data->flag & LIMIT_YMIN) {
- if(relLoc[1] < data->ymin)
- ob->obmat[3][1] = (parLoc[1]+data->ymin);
- }
- if (data->flag & LIMIT_YMAX) {
- if (relLoc[1] > data->ymax)
- ob->obmat[3][1] = (parLoc[1]+data->ymax);
- }
- if (data->flag & LIMIT_ZMIN) {
- if(relLoc[2] < data->zmin)
- ob->obmat[3][2] = (parLoc[2]+data->zmin);
- }
- if (data->flag & LIMIT_ZMAX) {
- if (relLoc[2] > data->zmax)
- ob->obmat[3][2] = (parLoc[2]+data->zmax);
- }
- } else {
- /* limiting relative to origin */
- if (data->flag & LIMIT_XMIN) {
- if(ob->obmat[3][0] < data->xmin)
- ob->obmat[3][0] = data->xmin;
- }
- if (data->flag & LIMIT_XMAX) {
- if (ob->obmat[3][0] > data->xmax)
- ob->obmat[3][0] = data->xmax;
+ switch (data->trackflag) {
+ case TRACK_X: /* LOCK Y TRACK X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[1]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalize(totmat[0]);
+
+ /* the y axis is fixed */
+ totmat[1][0] = cob->matrix[1][0];
+ totmat[1][1] = cob->matrix[1][1];
+ totmat[1][2] = cob->matrix[1][2];
+ Normalize(totmat[1]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
}
- if (data->flag & LIMIT_YMIN) {
- if(ob->obmat[3][1] < data->ymin)
- ob->obmat[3][1] = data->ymin;
+ break;
+ case TRACK_Z: /* LOCK Y TRACK Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[1]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalize(totmat[2]);
+
+ /* the y axis is fixed */
+ totmat[1][0] = cob->matrix[1][0];
+ totmat[1][1] = cob->matrix[1][1];
+ totmat[1][2] = cob->matrix[1][2];
+ Normalize(totmat[1]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
}
- if (data->flag & LIMIT_YMAX) {
- if (ob->obmat[3][1] > data->ymax)
- ob->obmat[3][1] = data->ymax;
+ break;
+ case TRACK_nX: /* LOCK Y TRACK -X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[1]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalize(totmat[0]);
+ VecMulf(totmat[0],-1);
+
+ /* the y axis is fixed */
+ totmat[1][0] = cob->matrix[1][0];
+ totmat[1][1] = cob->matrix[1][1];
+ totmat[1][2] = cob->matrix[1][2];
+ Normalize(totmat[1]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[2], totmat[0], totmat[1]);
}
- if (data->flag & LIMIT_ZMIN) {
- if(ob->obmat[3][2] < data->zmin)
- ob->obmat[3][2] = data->zmin;
+ break;
+ case TRACK_nZ: /* LOCK Y TRACK -Z */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[1]);
+ VecSubf(totmat[2], vec, vec2);
+ Normalize(totmat[2]);
+ VecMulf(totmat[2],-1);
+
+ /* the y axis is fixed */
+ totmat[1][0] = cob->matrix[1][0];
+ totmat[1][1] = cob->matrix[1][1];
+ totmat[1][2] = cob->matrix[1][2];
+ Normalize(totmat[1]);
+
+ /* the z axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
}
- if (data->flag & LIMIT_ZMAX) {
- if (ob->obmat[3][2] > data->zmax)
- ob->obmat[3][2] = data->zmax;
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
}
+ break;
}
}
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
+ break;
+ case LOCK_Z: /* LOCK Z */
{
- bRotLimitConstraint *data;
- float loc[3];
- float eul[3];
- float size[3];
-
- data = constraint->data;
-
- VECCOPY(loc, ob->obmat[3]);
- Mat4ToSize(ob->obmat, size);
-
- Mat4ToEul(ob->obmat, eul);
-
- /* eulers: radians to degrees! */
- eul[0] = (eul[0] / M_PI * 180);
- eul[1] = (eul[1] / M_PI * 180);
- eul[2] = (eul[2] / M_PI * 180);
-
- /* limiting of euler values... */
- if (data->flag & LIMIT_XROT) {
- if (eul[0] < data->xmin)
- eul[0] = data->xmin;
+ switch (data->trackflag) {
+ case TRACK_X: /* LOCK Z TRACK X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[2]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalize(totmat[0]);
- if (eul[0] > data->xmax)
- eul[0] = data->xmax;
- }
- if (data->flag & LIMIT_YROT) {
- if (eul[1] < data->ymin)
- eul[1] = data->ymin;
+ /* the z axis is fixed */
+ totmat[2][0] = cob->matrix[2][0];
+ totmat[2][1] = cob->matrix[2][1];
+ totmat[2][2] = cob->matrix[2][2];
+ Normalize(totmat[2]);
- if (eul[1] > data->ymax)
- eul[1] = data->ymax;
- }
- if (data->flag & LIMIT_ZROT) {
- if (eul[2] < data->zmin)
- eul[2] = data->zmin;
+ /* the x axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ case TRACK_Y: /* LOCK Z TRACK Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[2]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalize(totmat[1]);
+
+ /* the z axis is fixed */
+ totmat[2][0] = cob->matrix[2][0];
+ totmat[2][1] = cob->matrix[2][1];
+ totmat[2][2] = cob->matrix[2][2];
+ Normalize(totmat[2]);
+
+ /* the x axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ case TRACK_nX: /* LOCK Z TRACK -X */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[2]);
+ VecSubf(totmat[0], vec, vec2);
+ Normalize(totmat[0]);
+ VecMulf(totmat[0],-1);
+
+ /* the z axis is fixed */
+ totmat[2][0] = cob->matrix[2][0];
+ totmat[2][1] = cob->matrix[2][1];
+ totmat[2][2] = cob->matrix[2][2];
+ Normalize(totmat[2]);
- if (eul[2] > data->zmax)
- eul[2] = data->zmax;
+ /* the x axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[1], totmat[2], totmat[0]);
+ }
+ break;
+ case TRACK_nY: /* LOCK Z TRACK -Y */
+ {
+ /* Projection of Vector on the plane */
+ Projf(vec2, vec, cob->matrix[2]);
+ VecSubf(totmat[1], vec, vec2);
+ Normalize(totmat[1]);
+ VecMulf(totmat[1],-1);
+
+ /* the z axis is fixed */
+ totmat[2][0] = cob->matrix[2][0];
+ totmat[2][1] = cob->matrix[2][1];
+ totmat[2][2] = cob->matrix[2][2];
+ Normalize(totmat[2]);
+
+ /* the x axis gets mapped onto a third orthogonal vector */
+ Crossf(totmat[0], totmat[1], totmat[2]);
+ }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+ break;
}
-
- /* eulers: degrees to radians ! */
- eul[0] = (eul[0] / 180 * M_PI);
- eul[1] = (eul[1] / 180 * M_PI);
- eul[2] = (eul[2] / 180 * M_PI);
-
- LocEulSizeToMat4(ob->obmat, loc, eul, size);
}
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- {
- bSizeLimitConstraint *data;
- float obsize[3], size[3];
- int clearNegScale=0;
-
- data = constraint->data;
-
- Mat4ToSize(ob->obmat, size);
- Mat4ToSize(ob->obmat, obsize);
-
- if (data->flag & LIMIT_XMIN) {
- if (ob->transflag & OB_NEG_SCALE) {
- size[0] *= -1;
-
- if (size[0] < data->xmin) {
- size[0] = data->xmin;
- clearNegScale += 1;
- }
- } else {
- if (size[0] < data->xmin)
- size[0] = data->xmin;
- }
+ break;
+ default:
+ {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
}
- if (data->flag & LIMIT_XMAX) {
- if (size[0] > data->xmax)
- size[0] = data->xmax;
+ break;
+ }
+ /* Block to keep matrix heading */
+ tmpmat[0][0] = cob->matrix[0][0];tmpmat[0][1] = cob->matrix[0][1];tmpmat[0][2] = cob->matrix[0][2];
+ tmpmat[1][0] = cob->matrix[1][0];tmpmat[1][1] = cob->matrix[1][1];tmpmat[1][2] = cob->matrix[1][2];
+ tmpmat[2][0] = cob->matrix[2][0];tmpmat[2][1] = cob->matrix[2][1];tmpmat[2][2] = cob->matrix[2][2];
+ Normalize(tmpmat[0]);
+ Normalize(tmpmat[1]);
+ Normalize(tmpmat[2]);
+ Mat3Inv(invmat, tmpmat);
+ Mat3MulMat3(tmpmat, totmat, invmat);
+ totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
+ totmat[1][0] = tmpmat[1][0];totmat[1][1] = tmpmat[1][1];totmat[1][2] = tmpmat[1][2];
+ totmat[2][0] = tmpmat[2][0];totmat[2][1] = tmpmat[2][1];totmat[2][2] = tmpmat[2][2];
+
+ Mat4CpyMat4(tmat, cob->matrix);
+
+ mdet = Det3x3( totmat[0][0],totmat[0][1],totmat[0][2],
+ totmat[1][0],totmat[1][1],totmat[1][2],
+ totmat[2][0],totmat[2][1],totmat[2][2]);
+ if (mdet==0) {
+ totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
+ totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
+ totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ }
+
+ /* apply out transformaton to the object */
+ Mat4MulMat34(cob->matrix, totmat, tmat);
+ }
+}
+
+static bConstraintTypeInfo CTI_LOCKTRACK = {
+ CONSTRAINT_TYPE_LOCKTRACK, /* type */
+ sizeof(bLockTrackConstraint), /* size */
+ "Locked Track", /* name */
+ "bLockTrackConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ locktrack_new_data, /* new data */
+ locktrack_get_tars, /* get constraint targets */
+ locktrack_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ locktrack_evaluate /* evaluate */
+};
+
+/* ---------- Limit Distance Constraint ----------- */
+
+static void distlimit_new_data (void *cdata)
+{
+ bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
+
+ data->dist= 0.0;
+}
+
+static int distlimit_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float dvec[3], dist=0.0f, sfac=1.0f;
+ short clamp_surf= 0;
+
+ /* calculate our current distance from the target */
+ dist= VecLenf(cob->matrix[3], ct->matrix[3]);
+
+ /* set distance (flag is only set when user demands it) */
+ if (data->dist == 0)
+ data->dist= dist;
+
+ /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
+ if (data->mode == LIMITDIST_OUTSIDE) {
+ /* if inside, then move to surface */
+ if (dist <= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
}
- if (data->flag & LIMIT_YMIN) {
- if (ob->transflag & OB_NEG_SCALE) {
- size[1] *= -1;
+ /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ if (dist <= (data->dist + data->soft)) {
- if (size[1] < data->ymin) {
- size[1] = data->ymin;
- clearNegScale += 1;
- }
- } else {
- if (size[1] < data->ymin)
- size[1] = data->ymin;
- }
+ }
}
- if (data->flag & LIMIT_YMAX) {
- if (size[1] > data->ymax)
- size[1] = data->ymax;
+ }
+ else if (data->mode == LIMITDIST_INSIDE) {
+ /* if outside, then move to surface */
+ if (dist >= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
}
- if (data->flag & LIMIT_ZMIN) {
- if (ob->transflag & OB_NEG_SCALE) {
- size[2] *= -1;
+ /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ // FIXME: there's a problem with "jumping" when this kicks in
+ if (dist >= (data->dist - data->soft)) {
+ sfac = data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist;
+ sfac /= dist;
- if (size[2] < data->zmin) {
- size[2] = data->zmin;
- clearNegScale += 1;
- }
- } else {
- if (size[2] < data->zmin)
- size[2] = data->zmin;
- }
- }
- if (data->flag & LIMIT_ZMAX) {
- if (size[2] > data->zmax)
- size[2] = data->zmax;
+ clamp_surf= 1;
+ }
}
-
- if (clearNegScale != 0) {
- ob->transflag &= ~OB_NEG_SCALE; /* is this how we remove that flag? */
+ }
+ else {
+ if (IS_EQ(dist, data->dist)==0) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
}
+ }
+
+ /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
+ if (clamp_surf) {
+ /* simply interpolate along line formed by target -> owner */
+ VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
- VecMulf(ob->obmat[0], size[0]/obsize[0]);
- VecMulf(ob->obmat[1], size[1]/obsize[1]);
- VecMulf(ob->obmat[2], size[2]/obsize[2]);
+ /* copy new vector onto owner */
+ VECCOPY(cob->matrix[3], dvec);
}
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- {
+ }
+}
+static bConstraintTypeInfo CTI_DISTLIMIT = {
+ CONSTRAINT_TYPE_DISTLIMIT, /* type */
+ sizeof(bDistLimitConstraint), /* size */
+ "Limit Distance", /* name */
+ "bDistLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ distlimit_new_data, /* new data */
+ distlimit_get_tars, /* get constraint targets */
+ distlimit_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get a target matrix */
+ distlimit_evaluate /* evaluate */
+};
+
+/* ---------- Stretch To ------------ */
+
+static void stretchto_new_data (void *cdata)
+{
+ bStretchToConstraint *data= (bStretchToConstraint *)cdata;
+
+ data->volmode = 0;
+ data->plane = 0;
+ data->orglength = 0.0;
+ data->bulge = 1.0;
+}
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data;
- Curve *cu;
- float obmat[4][4], targetMatrix[4][4], ownLoc[3];
- float curveMin[3], curveMax[3];
+static int stretchto_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bStretchToConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void stretchto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bStretchToConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bStretchToConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
+ float totmat[3][3];
+ float tmat[4][4];
+ float dist;
+
+ /* store scaling before destroying obmat */
+ Mat4ToSize(cob->matrix, size);
+
+ /* store X orientation before destroying obmat */
+ xx[0] = cob->matrix[0][0];
+ xx[1] = cob->matrix[0][1];
+ xx[2] = cob->matrix[0][2];
+ Normalize(xx);
+
+ /* store Z orientation before destroying obmat */
+ zz[0] = cob->matrix[2][0];
+ zz[1] = cob->matrix[2][1];
+ zz[2] = cob->matrix[2][2];
+ Normalize(zz);
+
+ VecSubf(vec, cob->matrix[3], ct->matrix[3]);
+ vec[0] /= size[0];
+ vec[1] /= size[1];
+ vec[2] /= size[2];
+
+ dist = Normalize(vec);
+ //dist = VecLenf( ob->obmat[3], targetmat[3]);
+
+ /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
+ if (data->orglength == 0)
+ data->orglength = dist;
+ if (data->bulge == 0)
+ data->bulge = 1.0;
+
+ scale[1] = dist/data->orglength;
+ switch (data->volmode) {
+ /* volume preserving scaling */
+ case VOLUME_XZ :
+ scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
+ scale[2] = scale[0];
+ break;
+ case VOLUME_X:
+ scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
+ scale[2] = 1.0;
+ break;
+ case VOLUME_Z:
+ scale[0] = 1.0;
+ scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
+ break;
+ /* don't care for volume */
+ case NO_VOLUME:
+ scale[0] = 1.0;
+ scale[2] = 1.0;
+ break;
+ default: /* should not happen, but in case*/
+ return;
+ } /* switch (data->volmode) */
+
+ /* Clear the object's rotation and scale */
+ cob->matrix[0][0]=size[0]*scale[0];
+ cob->matrix[0][1]=0;
+ cob->matrix[0][2]=0;
+ cob->matrix[1][0]=0;
+ cob->matrix[1][1]=size[1]*scale[1];
+ cob->matrix[1][2]=0;
+ cob->matrix[2][0]=0;
+ cob->matrix[2][1]=0;
+ cob->matrix[2][2]=size[2]*scale[2];
+
+ VecSubf(vec, cob->matrix[3], ct->matrix[3]);
+ Normalize(vec);
+
+ /* new Y aligns object target connection*/
+ totmat[1][0] = -vec[0];
+ totmat[1][1] = -vec[1];
+ totmat[1][2] = -vec[2];
+ switch (data->plane) {
+ case PLANE_X:
+ /* build new Z vector */
+ /* othogonal to "new Y" "old X! plane */
+ Crossf(orth, vec, xx);
+ Normalize(orth);
- data = constraint->data;
+ /* new Z*/
+ totmat[2][0] = orth[0];
+ totmat[2][1] = orth[1];
+ totmat[2][2] = orth[2];
- /* prevent crash if user deletes curve */
- if ((data->tar == NULL) || (data->tar->type != OB_CURVE) )
- return;
- else
- cu= data->tar->data;
+ /* we decided to keep X plane*/
+ Crossf(xx, orth, vec);
+ Normalize(xx);
+ totmat[0][0] = xx[0];
+ totmat[0][1] = xx[1];
+ totmat[0][2] = xx[2];
+ break;
+ case PLANE_Z:
+ /* build new X vector */
+ /* othogonal to "new Y" "old Z! plane */
+ Crossf(orth, vec, zz);
+ Normalize(orth);
- Mat4CpyMat4(obmat, ob->obmat);
- Mat4One(targetMatrix);
- VECCOPY(ownLoc, obmat[3]);
+ /* new X */
+ totmat[0][0] = -orth[0];
+ totmat[0][1] = -orth[1];
+ totmat[0][2] = -orth[2];
- INIT_MINMAX(curveMin, curveMax)
- minmax_object(data->tar, curveMin, curveMax);
+ /* we decided to keep Z */
+ Crossf(zz, orth, vec);
+ Normalize(zz);
+ totmat[2][0] = zz[0];
+ totmat[2][1] = zz[1];
+ totmat[2][2] = zz[2];
+ break;
+ } /* switch (data->plane) */
+
+ Mat4CpyMat4(tmat, cob->matrix);
+ Mat4MulMat34(cob->matrix, totmat, tmat);
+ }
+}
+
+static bConstraintTypeInfo CTI_STRETCHTO = {
+ CONSTRAINT_TYPE_STRETCHTO, /* type */
+ sizeof(bStretchToConstraint), /* size */
+ "Stretch To", /* name */
+ "bStretchToConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ stretchto_new_data, /* new data */
+ stretchto_get_tars, /* get constraint targets */
+ stretchto_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ stretchto_evaluate /* evaluate */
+};
+
+/* ---------- Floor ------------ */
+
+static void minmax_new_data (void *cdata)
+{
+ bMinMaxConstraint *data= (bMinMaxConstraint *)cdata;
+
+ data->minmaxflag = TRACK_Z;
+ data->offset = 0.0f;
+ data->cache[0] = data->cache[1] = data->cache[2] = 0.0f;
+ data->flag = 0;
+}
+
+static int minmax_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bMinMaxConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void minmax_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bMinMaxConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bMinMaxConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float obmat[4][4], imat[4][4], tarmat[4][4], tmat[4][4];
+ float val1, val2;
+ int index;
+
+ Mat4CpyMat4(obmat, cob->matrix);
+ Mat4CpyMat4(tarmat, ct->matrix);
+
+ if (data->flag & MINMAX_USEROT) {
+ /* take rotation of target into account by doing the transaction in target's localspace */
+ Mat4Invert(imat, tarmat);
+ Mat4MulMat4(tmat, obmat, imat);
+ Mat4CpyMat4(obmat, tmat);
+ Mat4One(tarmat);
+ }
+
+ switch (data->minmaxflag) {
+ case TRACK_Z:
+ val1 = tarmat[3][2];
+ val2 = obmat[3][2]-data->offset;
+ index = 2;
+ break;
+ case TRACK_Y:
+ val1 = tarmat[3][1];
+ val2 = obmat[3][1]-data->offset;
+ index = 1;
+ break;
+ case TRACK_X:
+ val1 = tarmat[3][0];
+ val2 = obmat[3][0]-data->offset;
+ index = 0;
+ break;
+ case TRACK_nZ:
+ val2 = tarmat[3][2];
+ val1 = obmat[3][2]-data->offset;
+ index = 2;
+ break;
+ case TRACK_nY:
+ val2 = tarmat[3][1];
+ val1 = obmat[3][1]-data->offset;
+ index = 1;
+ break;
+ case TRACK_nX:
+ val2 = tarmat[3][0];
+ val1 = obmat[3][0]-data->offset;
+ index = 0;
+ break;
+ default:
+ return;
+ }
+
+ if (val1 > val2) {
+ obmat[3][index] = tarmat[3][index] + data->offset;
+ if (data->flag & MINMAX_STICKY) {
+ if (data->flag & MINMAX_STUCK) {
+ VECCOPY(obmat[3], data->cache);
+ }
+ else {
+ VECCOPY(data->cache, obmat[3]);
+ data->flag |= MINMAX_STUCK;
+ }
+ }
+ if (data->flag & MINMAX_USEROT) {
+ /* get out of localspace */
+ Mat4MulMat4(tmat, obmat, ct->matrix);
+ Mat4CpyMat4(cob->matrix, tmat);
+ }
+ else {
+ VECCOPY(cob->matrix[3], obmat[3]);
+ }
+ }
+ else {
+ data->flag &= ~MINMAX_STUCK;
+ }
+ }
+}
+
+static bConstraintTypeInfo CTI_MINMAX = {
+ CONSTRAINT_TYPE_MINMAX, /* type */
+ sizeof(bMinMaxConstraint), /* size */
+ "Floor", /* name */
+ "bMinMaxConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ minmax_new_data, /* new data */
+ minmax_get_tars, /* get constraint targets */
+ minmax_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ minmax_evaluate /* evaluate */
+};
+
+/* ------- RigidBody Joint ---------- */
+
+static void rbj_new_data (void *cdata)
+{
+ bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint *)cdata;
+
+ // removed code which set target of this constraint
+ data->type=1;
+}
+
+static int rbj_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bRigidBodyJointConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints without subtargets */
+ SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void rbj_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bRigidBodyJointConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
+ }
+}
+
+static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
+ CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
+ sizeof(bRigidBodyJointConstraint), /* size */
+ "RigidBody Joint", /* name */
+ "bRigidBodyJointConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ rbj_new_data, /* new data */
+ rbj_get_tars, /* get constraint targets */
+ rbj_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ NULL /* evaluate - this is not solved here... is just an interface for game-engine */
+};
+
+/* -------- Clamp To ---------- */
+
+static int clampto_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bClampToConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints without subtargets */
+ SINGLETARGETNS_GET_TARS(con, data->tar, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void clampto_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bClampToConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, nocopy)
+ }
+}
+
+static void clampto_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ if (VALID_CONS_TARGET(ct)) {
+ Curve *cu= ct->tar->data;
+
+ /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
+ * currently for paths to work it needs to go through the bevlist/displist system (ton)
+ */
+
+ /* only happens on reload file, but violates depsgraph still... fix! */
+ if (cu->path==NULL || cu->path->data==NULL)
+ makeDispListCurveTypes(ct->tar, 0);
+ }
+
+ /* technically, this isn't really needed for evaluation, but we don't know what else
+ * might end up calling this...
+ */
+ if (ct)
+ Mat4One(ct->matrix);
+}
+
+static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bClampToConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target and it is a curve */
+ if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
+ Curve *cu= data->tar->data;
+ float obmat[4][4], targetMatrix[4][4], ownLoc[3];
+ float curveMin[3], curveMax[3];
+
+ Mat4CpyMat4(obmat, cob->matrix);
+ Mat4One(targetMatrix);
+ VECCOPY(ownLoc, obmat[3]);
+
+ INIT_MINMAX(curveMin, curveMax)
+ minmax_object(ct->tar, curveMin, curveMax);
+
+ /* get targetmatrix */
+ if (cu->path && cu->path->data) {
+ float vec[4], dir[3], totmat[4][4];
+ float curvetime;
+ short clamp_axis;
- /* get targetmatrix */
- if(cu->path && cu->path->data) {
- float vec[4], dir[3], totmat[4][4];
- float curvetime;
- short clamp_axis;
+ /* find best position on curve */
+ /* 1. determine which axis to sample on? */
+ if (data->flag == CLAMPTO_AUTO) {
+ float size[3];
+ VecSubf(size, curveMax, curveMin);
+
+ /* find axis along which the bounding box has the greatest
+ * extent. Otherwise, default to the x-axis, as that is quite
+ * frequently used.
+ */
+ if ((size[2]>size[0]) && (size[2]>size[1]))
+ clamp_axis= CLAMPTO_Z - 1;
+ else if ((size[1]>size[0]) && (size[1]>size[2]))
+ clamp_axis= CLAMPTO_Y - 1;
+ else
+ clamp_axis = CLAMPTO_X - 1;
+ }
+ else
+ clamp_axis= data->flag - 1;
+
+ /* 2. determine position relative to curve on a 0-1 scale based on bounding box */
+ if (data->flag2 & CLAMPTO_CYCLIC) {
+ /* cyclic, so offset within relative bounding box is used */
+ float len= (curveMax[clamp_axis] - curveMin[clamp_axis]);
+ float offset;
- /* find best position on curve */
- /* 1. determine which axis to sample on? */
- if (data->flag==CLAMPTO_AUTO) {
- float size[3];
- VecSubf(size, curveMax, curveMin);
+ /* find bounding-box range where target is located */
+ if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
+ /* bounding-box range is before */
+ offset= curveMin[clamp_axis];
- /* find axis along which the bounding box has the greatest
- * extent. Otherwise, default to the x-axis, as that is quite
- * frequently used.
- */
- if ((size[2]>size[0]) && (size[2]>size[1]))
- clamp_axis= CLAMPTO_Z;
- else if ((size[1]>size[0]) && (size[1]>size[2]))
- clamp_axis= CLAMPTO_Y;
- else
- clamp_axis = CLAMPTO_X;
+ while (ownLoc[clamp_axis] < offset)
+ offset -= len;
+
+ /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */
+ curvetime = (ownLoc[clamp_axis] - offset) / (len);
}
- else
- clamp_axis= data->flag;
+ else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) {
+ /* bounding-box range is after */
+ offset= curveMax[clamp_axis];
+
+ while (ownLoc[clamp_axis] > offset) {
+ if ((offset + len) > ownLoc[clamp_axis])
+ break;
+ else
+ offset += len;
+ }
- /* 2. determine position relative to curve on a 0-1 scale */
- if (clamp_axis > 0) clamp_axis--;
+ /* now, we calculate as per normal, except using offset instead of curveMax[clamp_axis] */
+ curvetime = (ownLoc[clamp_axis] - offset) / (len);
+ }
+ else {
+ /* as the location falls within bounds, just calculate */
+ curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len);
+ }
+ }
+ else {
+ /* no cyclic, so position is clamped to within the bounding box */
if (ownLoc[clamp_axis] <= curveMin[clamp_axis])
curvetime = 0.0;
else if (ownLoc[clamp_axis] >= curveMax[clamp_axis])
curvetime = 1.0;
else
- curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]); // umm
+ curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]);
+ }
+
+ /* 3. position on curve */
+ if (where_on_path(ct->tar, curvetime, vec, dir) ) {
+ Mat4One(totmat);
+ VECCOPY(totmat[3], vec);
- /* 3. position on curve */
- if(where_on_path(data->tar, curvetime, vec, dir) ) {
- Mat4One(totmat);
- VECCOPY(totmat[3], vec);
+ Mat4MulSerie(targetMatrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ }
+
+ /* obtain final object position */
+ VECCOPY(cob->matrix[3], targetMatrix[3]);
+ }
+}
+
+static bConstraintTypeInfo CTI_CLAMPTO = {
+ CONSTRAINT_TYPE_CLAMPTO, /* type */
+ sizeof(bClampToConstraint), /* size */
+ "Clamp To", /* name */
+ "bClampToConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ clampto_get_tars, /* get constraint targets */
+ clampto_flush_tars, /* flush constraint targets */
+ clampto_get_tarmat, /* get target matrix */
+ clampto_evaluate /* evaluate */
+};
+
+/* ---------- Transform Constraint ----------- */
+
+static void transform_new_data (void *cdata)
+{
+ bTransformConstraint *data= (bTransformConstraint *)cdata;
+
+ data->map[0]= 0;
+ data->map[1]= 1;
+ data->map[2]= 2;
+}
+
+static int transform_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bTransformConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void transform_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bTransformConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bTransformConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float loc[3], eul[3], size[3];
+ float dvec[3], sval[3];
+ short i;
+
+ /* obtain target effect */
+ switch (data->from) {
+ case 2: /* scale */
+ Mat4ToSize(ct->matrix, dvec);
+ break;
+ case 1: /* rotation (convert to degrees first) */
+ Mat4ToEul(ct->matrix, dvec);
+ for (i=0; i<3; i++)
+ dvec[i] = dvec[i] / M_PI * 180;
+ break;
+ default: /* location */
+ VecCopyf(dvec, ct->matrix[3]);
+ break;
+ }
+
+ /* extract components of owner's matrix */
+ VECCOPY(loc, cob->matrix[3]);
+ Mat4ToEul(cob->matrix, eul);
+ Mat4ToSize(cob->matrix, size);
+
+ /* determine where in range current transforms lie */
+ if (data->expo) {
+ for (i=0; i<3; i++) {
+ if (data->from_max[i] - data->from_min[i])
+ sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
+ else
+ sval[i]= 0.0f;
+ }
+ }
+ else {
+ /* clamp transforms out of range */
+ for (i=0; i<3; i++) {
+ CLAMP(dvec[i], data->from_min[i], data->from_max[i]);
+ if (data->from_max[i] - data->from_min[i])
+ sval[i]= (dvec[i] - data->from_min[i]) / (data->from_max[i] - data->from_min[i]);
+ else
+ sval[i]= 0.0f;
+ }
+ }
+
+ /* convert radians<->degrees */
+ if (data->to == 1) {
+ /* if output is rotation, convert to radians from degrees */
+ for (i=0; i<3; i++)
+ sval[i] = sval[i] / 180 * M_PI;
+ }
+
+ /* apply transforms */
+ switch (data->to) {
+ case 2: /* scaling */
+ for (i=0; i<3; i++)
+ size[i]= data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i]));
+ break;
+ case 1: /* rotation */
+ for (i=0; i<3; i++) {
+ float tmin, tmax;
- Mat4MulSerie(targetMatrix, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
+ /* convert destination min/max ranges from degrees to radians */
+ tmin= data->to_min[i] / M_PI * 180;
+ tmax= data->to_max[i] / M_PI * 180;
+
+ eul[i]= tmin + (sval[data->map[i]] * (tmax - tmin));
+ }
+ break;
+ default: /* location */
+ /* get new location */
+ for (i=0; i<3; i++)
+ loc[i]= (data->to_min[i] + (sval[data->map[i]] * (data->to_max[i] - data->to_min[i])));
+
+ /* add original location back on (so that it can still be moved) */
+ VecAddf(loc, cob->matrix[3], loc);
+ break;
+ }
+
+ /* apply to matrix */
+ LocEulSizeToMat4(cob->matrix, loc, eul, size);
+ }
+}
+
+static bConstraintTypeInfo CTI_TRANSFORM = {
+ CONSTRAINT_TYPE_TRANSFORM, /* type */
+ sizeof(bTransformConstraint), /* size */
+ "Transform", /* name */
+ "bTransformConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ transform_new_data, /* new data */
+ transform_get_tars, /* get constraint targets */
+ transform_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get a target matrix */
+ transform_evaluate /* evaluate */
+};
+
+/* ************************* Constraints Type-Info *************************** */
+/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
+ * and operations that involve constraint specifc code.
+ */
+
+/* These globals only ever get directly accessed in this file */
+static bConstraintTypeInfo *constraintsTypeInfo[NUM_CONSTRAINT_TYPES+1];
+static short CTI_INIT= 1; /* when non-zero, the list needs to be updated */
+
+/* This function only gets called when CTI_INIT is non-zero */
+static void constraints_init_typeinfo () {
+ constraintsTypeInfo[0]= NULL; /* 'Null' Constraint */
+ constraintsTypeInfo[1]= &CTI_CHILDOF; /* ChildOf Constraint */
+ constraintsTypeInfo[2]= &CTI_TRACKTO; /* TrackTo Constraint */
+ constraintsTypeInfo[3]= &CTI_KINEMATIC; /* IK Constraint */
+ constraintsTypeInfo[4]= &CTI_FOLLOWPATH; /* Follow-Path Constraint */
+ constraintsTypeInfo[5]= &CTI_ROTLIMIT; /* Limit Rotation Constraint */
+ constraintsTypeInfo[6]= &CTI_LOCLIMIT; /* Limit Location Constraint */
+ constraintsTypeInfo[7]= &CTI_SIZELIMIT; /* Limit Scaling Constraint */
+ constraintsTypeInfo[8]= &CTI_ROTLIKE; /* Copy Rotation Constraint */
+ constraintsTypeInfo[9]= &CTI_LOCLIKE; /* Copy Location Constraint */
+ constraintsTypeInfo[10]= &CTI_SIZELIKE; /* Copy Scaling Constraint */
+ constraintsTypeInfo[11]= &CTI_PYTHON; /* Python/Script Constraint */
+ constraintsTypeInfo[12]= &CTI_ACTION; /* Action Constraint */
+ constraintsTypeInfo[13]= &CTI_LOCKTRACK; /* Locked-Track Constraint */
+ constraintsTypeInfo[14]= &CTI_DISTLIMIT; /* Limit Distance Constraint */
+ constraintsTypeInfo[15]= &CTI_STRETCHTO; /* StretchTo Constaint */
+ constraintsTypeInfo[16]= &CTI_MINMAX; /* Floor Constraint */
+ constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */
+ constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */
+ constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
+}
+
+/* This function should be used for getting the appropriate type-info when only
+ * a constraint type is known
+ */
+bConstraintTypeInfo *get_constraint_typeinfo (int type)
+{
+ /* initialise the type-info list? */
+ if (CTI_INIT) {
+ constraints_init_typeinfo();
+ CTI_INIT = 0;
+ }
+
+ /* only return for valid types */
+ if ( (type >= CONSTRAINT_TYPE_NULL) &&
+ (type <= NUM_CONSTRAINT_TYPES ) )
+ {
+ /* there shouldn't be any segfaults here... */
+ return constraintsTypeInfo[type];
+ }
+ else {
+ printf("No valid constraint type-info data available. Type = %i \n", type);
+ }
+
+ return NULL;
+}
+
+/* This function should always be used to get the appropriate type-info, as it
+ * has checks which prevent segfaults in some weird cases.
+ */
+bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
+{
+ /* only return typeinfo for valid constraints */
+ if (con)
+ return get_constraint_typeinfo(con->type);
+ else
+ return NULL;
+}
+
+/* ************************* General Constraints API ************************** */
+/* The functions here are called by various parts of Blender. Very few (should be none if possible)
+ * constraint-specific code should occur here.
+ */
+
+/* ---------- Data Management ------- */
+
+/* Free data of a specific constraint if it has any info */
+void free_constraint_data (bConstraint *con)
+{
+ if (con->data) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+ /* perform any special freeing constraint may have */
+ if (cti && cti->free_data)
+ cti->free_data(con);
+
+ /* free constraint data now */
+ MEM_freeN(con->data);
+ }
+}
+
+/* Free all constraints from a constraint-stack */
+void free_constraints (ListBase *conlist)
+{
+ bConstraint *con;
+
+ /* Free constraint data and also any extra data */
+ for (con= conlist->first; con; con= con->next) {
+ free_constraint_data(con);
+ }
+
+ /* Free the whole list */
+ BLI_freelistN(conlist);
+}
+
+/* Reassign links that constraints have to other data (called during file loading?) */
+void relink_constraints (ListBase *conlist)
+{
+ bConstraint *con;
+ bConstraintTarget *ct;
+
+ for (con= conlist->first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+ if (cti) {
+ /* relink any targets */
+ if (cti->get_constraint_targets) {
+ ListBase targets = {NULL, NULL};
+
+ cti->get_constraint_targets(con, &targets);
+ for (ct= targets.first; ct; ct= ct->next) {
+ ID_NEW(ct->tar);
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
- /* obtain final object position */
- VECCOPY(ob->obmat[3], targetMatrix[3]);
+ /* relink any other special data */
+ if (cti->relink_data)
+ cti->relink_data(con);
}
- break;
- default:
- printf ("Error: Unknown constraint type\n");
- break;
+ }
+}
+
+/* duplicate all of the constraints in a constraint stack */
+void copy_constraints (ListBase *dst, ListBase *src)
+{
+ bConstraint *con, *srccon;
+
+ dst->first= dst->last= NULL;
+ duplicatelist(dst, src);
+
+ for (con=dst->first, srccon=src->first; con; srccon=srccon->next, con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+ /* make a new copy of the constraint's data */
+ con->data = MEM_dupallocN(con->data);
+
+ /* only do specific constraints if required */
+ if (cti && cti->copy_data)
+ cti->copy_data(con, srccon);
+ }
+}
+
+/* -------- Constraints and Proxies ------- */
+
+/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
+void extract_proxylocal_constraints (ListBase *dst, ListBase *src)
+{
+ bConstraint *con, *next;
+
+ /* for each tagged constraint, remove from src and move to dst */
+ for (con= src->first; con; con= next) {
+ next= con->next;
+
+ /* check if tagged */
+ if (con->flag & CONSTRAINT_PROXY_LOCAL) {
+ BLI_remlink(src, con);
+ BLI_addtail(dst, con);
+ }
+ }
+}
+
+/* Returns if the owner of the constraint is proxy-protected */
+short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan)
+{
+ /* Currently, constraints can only be on object or bone level */
+ if (ob && ob->proxy) {
+ if (ob->pose && pchan) {
+ bArmature *arm= ob->data;
+
+ /* On bone-level, check if bone is on proxy-protected layer */
+ if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
+ return 1;
+ }
+ else {
+ /* FIXME: constraints on object-level are not handled well yet */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* -------- Target-Matrix Stuff ------- */
+
+/* This function is a relic from the prior implementations of the constraints system, when all
+ * constraints either had one or no targets. It used to be called during the main constraint solving
+ * loop, but is now only used for the remaining cases for a few constraints.
+ *
+ * None of the actual calculations of the matricies should be done here! Also, this function is
+ * not to be used by any new constraints, particularly any that have multiple targets.
+ */
+void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
+{
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintOb *cob;
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ /* make 'constraint-ob' */
+ cob= MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
+ cob->type= ownertype;
+ switch (ownertype) {
+ case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
+ {
+ cob->ob= (Object *)ownerdata;
+ cob->pchan= NULL;
+ if (cob->ob) {
+ Mat4CpyMat4(cob->matrix, cob->ob->obmat);
+ Mat4CpyMat4(cob->startmat, cob->matrix);
+ }
+ else {
+ Mat4One(cob->matrix);
+ Mat4One(cob->startmat);
+ }
+ }
+ break;
+ case CONSTRAINT_OBTYPE_BONE: /* this may occur in some cases */
+ {
+ cob->ob= NULL; /* this might not work at all :/ */
+ cob->pchan= (bPoseChannel *)ownerdata;
+ if (cob->pchan) {
+ Mat4CpyMat4(cob->matrix, cob->pchan->pose_mat);
+ Mat4CpyMat4(cob->startmat, cob->matrix);
+ }
+ else {
+ Mat4One(cob->matrix);
+ Mat4One(cob->startmat);
+ }
+ }
+ break;
+ }
+
+ /* get targets - we only need the first one though (and there should only be one) */
+ cti->get_constraint_targets(con, &targets);
+
+ /* only calculate the target matrix on the first target */
+ ct= (bConstraintTarget *)targets.first;
+ while(ct && n-- > 0)
+ ct= ct->next;
+
+ if (ct) {
+ if (cti->get_target_matrix)
+ cti->get_target_matrix(con, cob, ct, ctime);
+ Mat4CpyMat4(mat, ct->matrix);
+ }
+
+ /* free targets + 'constraint-ob' */
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
+ MEM_freeN(cob);
+ }
+ else {
+ /* invalid constraint - perhaps... */
+ Mat4One(mat);
+ }
+}
+
+/* ---------- Evaluation ----------- */
+
+/* This function is called whenever constraints need to be evaluated. Currently, all
+ * constraints that can be evaluated are everytime this gets run.
+ *
+ * constraints_make_evalob and constraints_clear_evalob should be called before and
+ * after running this function, to sort out cob
+ */
+void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
+{
+ bConstraint *con;
+ float solution[4][4], delta[4][4];
+ float oldmat[4][4], imat[4][4];
+ float enf;
+
+ /* check that there is a valid constraint object to evaluate */
+ if (cob == NULL)
+ return;
+
+ /* loop over available constraints, solving and blending them */
+ for (con= conlist->first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+
+ /* these we can skip completely (invalid constraints...) */
+ if (cti == NULL) continue;
+ if (con->flag & CONSTRAINT_DISABLE) continue;
+ /* these constraints can't be evaluated anyway */
+ if (cti->evaluate_constraint == NULL) continue;
+ /* influence == 0 should be ignored */
+ if (con->enforce == 0.0f) continue;
+
+ /* influence of constraint
+ * - value should have been set from IPO's/Constraint Channels already
+ */
+ enf = con->enforce;
+
+ /* move owner matrix into right space */
+ constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
+ Mat4CpyMat4(oldmat, cob->matrix);
+
+ /* prepare targets for constraint solving */
+ if (cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+
+ /* get targets
+ * - constraints should use ct->matrix, not directly accessing values
+ * - ct->matrix members have not yet been calculated here!
+ */
+ cti->get_constraint_targets(con, &targets);
+
+ /* set matrices
+ * - calculate if possible, otherwise just initialise as identity matrix
+ */
+ if (cti->get_target_matrix) {
+ for (ct= targets.first; ct; ct= ct->next)
+ cti->get_target_matrix(con, cob, ct, ctime);
+ }
+ else {
+ for (ct= targets.first; ct; ct= ct->next)
+ Mat4One(ct->matrix);
+ }
+ }
+
+ /* Solve the constraint */
+ cti->evaluate_constraint(con, cob, &targets);
+
+ /* clear targets after use
+ * - this should free temp targets but no data should be copied back
+ * as constraints may have done some nasty things to it...
+ */
+ if (cti->flush_constraint_targets) {
+ cti->flush_constraint_targets(con, &targets, 1);
+ }
+
+ /* Interpolate the enforcement, to blend result of constraint into final owner transform */
+ /* 1. Remove effects of original matrix from constraint solution ==> delta */
+ Mat4Invert(imat, oldmat);
+ Mat4CpyMat4(solution, cob->matrix);
+ Mat4MulMat4(delta, solution, imat);
+
+ /* 2. If constraint influence is not full strength, then interpolate
+ * identity_matrix --> delta_matrix to get the effect the constraint actually exerts
+ */
+ if (enf < 1.0) {
+ float identity[4][4];
+ Mat4One(identity);
+ Mat4BlendMat4(delta, identity, delta, enf);
+ }
+
+ /* 3. Now multiply the delta by the matrix in use before the evaluation */
+ Mat4MulMat4(cob->matrix, delta, oldmat);
+
+ /* move owner back into worldspace for next constraint/other business */
+ if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
+ constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
}
}
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 142bedadc93..dcd8bc6d9eb 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -324,7 +324,20 @@ int count_curveverts(ListBase *nurb)
return tot;
}
-
+int count_curveverts_without_handles(ListBase *nurb)
+{
+ Nurb *nu;
+ int tot=0;
+
+ nu= nurb->first;
+ while(nu) {
+ if(nu->bezt) tot+= nu->pntsu;
+ else if(nu->bp) tot+= nu->pntsu*nu->pntsv;
+
+ nu= nu->next;
+ }
+ return tot;
+}
/* **************** NURBS ROUTINES ******************** */
@@ -573,7 +586,7 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
/* this is for float inaccuracy */
if(t < knots[0]) t= knots[0];
- else if(t > knots[opp2]) t= knots[opp2];
+ else if(t > knots[opp2]) t= knots[opp2]; /* Valgrind reports an error here, use a nurbs torus and change u/v res to reproduce a crash TODO*/
/* this part is order '1' */
o2 = order + 1;
@@ -1432,7 +1445,7 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
for(a=0; a<resolu; a++, fac+= dfac) {
- set_four_ipo(fac, t, KEY_LINEAR);
+ set_four_ipo(fac, t, nu->tilt_interp);
data_a[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa;
}
@@ -1454,7 +1467,7 @@ void makeBevelList(Object *ob)
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
float *data, *data_a, *v1, *v2, min, inp, x1, x2, y1, y2, vec[3];
struct bevelsort *sortdata, *sd, *sd1;
- int a, b, len, nr, poly, resolu;
+ int a, b, nr, poly, resolu, len=0;
/* this function needs an object, because of tflag and upflag */
cu= ob->data;
@@ -1466,14 +1479,17 @@ void makeBevelList(Object *ob)
else nu= cu->nurb.first;
while(nu) {
- if(nu->pntsu>1) {
+ if(nu->pntsu<=1) {
+ bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList");
+ BLI_addtail(&(cu->bev), bl);
+ bl->nr= 0;
+ } else {
if(G.rendering && cu->resolu_ren!=0)
resolu= cu->resolu_ren;
else
resolu= nu->resolu;
if((nu->type & 7)==CU_POLY) {
-
len= nu->pntsu;
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList");
BLI_addtail(&(cu->bev), bl);
@@ -1526,7 +1542,7 @@ void makeBevelList(Object *ob)
bevp->y= prevbezt->vec[1][1];
bevp->z= prevbezt->vec[1][2];
bevp->alfa= prevbezt->alfa;
- bevp->f1= 1;
+ bevp->f1= SELECT;
bevp->f2= 0;
bevp++;
bl->nr++;
@@ -1624,28 +1640,30 @@ void makeBevelList(Object *ob)
/* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */
bl= cu->bev.first;
while(bl) {
- nr= bl->nr;
- bevp1= (BevPoint *)(bl+1);
- bevp0= bevp1+(nr-1);
- nr--;
- while(nr--) {
- if( fabs(bevp0->x-bevp1->x)<0.00001 ) {
- if( fabs(bevp0->y-bevp1->y)<0.00001 ) {
- if( fabs(bevp0->z-bevp1->z)<0.00001 ) {
- bevp0->f2= 1;
- bl->flag++;
+ if (bl->nr) { /* null bevel items come from single points */
+ nr= bl->nr;
+ bevp1= (BevPoint *)(bl+1);
+ bevp0= bevp1+(nr-1);
+ nr--;
+ while(nr--) {
+ if( fabs(bevp0->x-bevp1->x)<0.00001 ) {
+ if( fabs(bevp0->y-bevp1->y)<0.00001 ) {
+ if( fabs(bevp0->z-bevp1->z)<0.00001 ) {
+ bevp0->f2= SELECT;
+ bl->flag++;
+ }
}
}
+ bevp0= bevp1;
+ bevp1++;
}
- bevp0= bevp1;
- bevp1++;
}
bl= bl->next;
}
bl= cu->bev.first;
while(bl) {
blnext= bl->next;
- if(bl->flag) {
+ if(bl->nr && bl->flag) {
nr= bl->nr- bl->flag+1; /* +1 because vectorbezier sets flag too */
blnew= MEM_mallocN(sizeof(BevList)+nr*sizeof(BevPoint), "makeBevelList");
memcpy(blnew, bl, sizeof(BevList));
@@ -1673,7 +1691,7 @@ void makeBevelList(Object *ob)
bl= cu->bev.first;
poly= 0;
while(bl) {
- if(bl->poly>=0) {
+ if(bl->nr && bl->poly>=0) {
poly++;
bl->poly= poly;
bl->gat= 0; /* 'gat' is dutch for hole */
@@ -1770,13 +1788,13 @@ void makeBevelList(Object *ob)
bevp2->cosa= bevp1->cosa;
if(cu->flag & CU_3D) { /* 3D */
- float *quat, q[4];
+ float quat[4], q[4];
vec[0]= bevp1->x - bevp2->x;
vec[1]= bevp1->y - bevp2->y;
vec[2]= bevp1->z - bevp2->z;
- quat= vectoquat(vec, 5, 1);
+ vectoquat(vec, 5, 1, quat);
Normalize(vec);
q[0]= (float)cos(0.5*bevp1->alfa);
@@ -1802,7 +1820,7 @@ void makeBevelList(Object *ob)
while(nr--) {
if(cu->flag & CU_3D) { /* 3D */
- float *quat, q[4];
+ float quat[4], q[4];
vec[0]= bevp2->x - bevp0->x;
vec[1]= bevp2->y - bevp0->y;
@@ -1810,7 +1828,7 @@ void makeBevelList(Object *ob)
Normalize(vec);
- quat= vectoquat(vec, 5, 1);
+ vectoquat(vec, 5, 1, quat);
q[0]= (float)cos(0.5*bevp1->alfa);
x1= (float)sin(0.5*bevp1->alfa);
@@ -1956,7 +1974,7 @@ float calc_curve_subdiv_radius(Curve *cu, Nurb *nu, int cursubdiv)
}
if ( ((nu->type & 7)==CU_NURBS) && (nu->flagu & CU_CYCLIC)) {
- if (bp == bplast) bp = bpfirst;
+ if (bp >= bplast) bp = bpfirst;
else bp++;
}
@@ -2149,7 +2167,7 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
if(len1==0.0) len1=1.0;
if(len2==0.0) len2=1.0;
- if(bezt->f1 & 1) { /* order of calculation */
+ if(bezt->f1 & SELECT) { /* order of calculation */
if(bezt->h2==HD_ALIGN) { /* aligned */
len= len2/len1;
p2[3]= p2[0]+len*(p2[0]-p2[-3]);
@@ -2225,9 +2243,9 @@ void testhandlesNurb(Nurb *nu)
a= nu->pntsu;
while(a--) {
flag= 0;
- if(bezt->f1 & 1) flag++;
- if(bezt->f2 & 1) flag += 2;
- if(bezt->f3 & 1) flag += 4;
+ if(bezt->f1 & SELECT) flag++;
+ if(bezt->f2 & SELECT) flag += 2;
+ if(bezt->f3 & SELECT) flag += 4;
if( !(flag==0 || flag==7) ) {
if(bezt->h1==HD_AUTO) { /* auto */
@@ -2338,6 +2356,8 @@ void sethandlesNurb(short code)
/* code==2: set vectorhandle */
/* code==3 (HD_ALIGN) it toggle, vectorhandles become HD_FREE */
/* code==4: sets icu flag to become IPO_AUTO_HORIZ, horizontal extremes on auto-handles */
+ /* code==5: Set align, like 3 but no toggle */
+ /* code==6: Clear align, like 3 but no toggle */
Nurb *nu;
BezTriple *bezt;
short a, ok=0;
@@ -2368,22 +2388,28 @@ void sethandlesNurb(short code)
/* there is 1 handle not FREE: FREE it all, else make ALIGNED */
nu= editNurb.first;
- while(nu) {
- if( (nu->type & 7)==1) {
- bezt= nu->bezt;
- a= nu->pntsu;
- while(a--) {
- if(bezt->f1 && bezt->h1) ok= 1;
- if(bezt->f3 && bezt->h2) ok= 1;
- if(ok) break;
- bezt++;
+ if (code == 5) {
+ ok = HD_ALIGN;
+ } else if (code == 6) {
+ ok = HD_FREE;
+ } else {
+ /* Toggle */
+ while(nu) {
+ if( (nu->type & 7)==1) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ if(bezt->f1 && bezt->h1) ok= 1;
+ if(bezt->f3 && bezt->h2) ok= 1;
+ if(ok) break;
+ bezt++;
+ }
}
+ nu= nu->next;
}
- nu= nu->next;
+ if(ok) ok= HD_FREE;
+ else ok= HD_ALIGN;
}
- if(ok) ok= HD_FREE;
- else ok= HD_ALIGN;
-
nu= editNurb.first;
while(nu) {
if( (nu->type & 7)==1) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index e239583c4eb..d8ce311b5ca 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -271,7 +271,7 @@ static void layerSwap_tface(void *data, int *corner_indices)
static void layerDefault_tface(void *data, int count)
{
- static MTFace default_tf = {{{0, 1}, {0, 0}, {1, 0}, {1, 1}}, NULL,
+ static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
0, 0, TF_DYNAMIC, 0, 0};
MTFace *tf = (MTFace*)data;
int i;
@@ -280,6 +280,83 @@ static void layerDefault_tface(void *data, int count)
tf[i] = default_tf;
}
+static void layerCopy_origspace_face(const void *source, void *dest, int count)
+{
+ const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
+ OrigSpaceFace *dest_tf = (OrigSpaceFace*)dest;
+ int i;
+
+ for(i = 0; i < count; ++i)
+ dest_tf[i] = source_tf[i];
+}
+
+static void layerInterp_origspace_face(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ OrigSpaceFace *osf = dest;
+ int i, j, k;
+ float uv[4][2];
+ float *sub_weight;
+
+ if(count <= 0) return;
+
+ memset(uv, 0, sizeof(uv));
+
+ sub_weight = sub_weights;
+ for(i = 0; i < count; ++i) {
+ float weight = weights ? weights[i] : 1;
+ OrigSpaceFace *src = sources[i];
+
+ for(j = 0; j < 4; ++j) {
+ if(sub_weights) {
+ for(k = 0; k < 4; ++k, ++sub_weight) {
+ float w = (*sub_weight) * weight;
+ float *tmp_uv = src->uv[k];
+
+ uv[j][0] += tmp_uv[0] * w;
+ uv[j][1] += tmp_uv[1] * w;
+ }
+ } else {
+ uv[j][0] += src->uv[j][0] * weight;
+ uv[j][1] += src->uv[j][1] * weight;
+ }
+ }
+ }
+
+ *osf = *(OrigSpaceFace *)sources[0];
+ for(j = 0; j < 4; ++j) {
+ osf->uv[j][0] = uv[j][0];
+ osf->uv[j][1] = uv[j][1];
+ }
+}
+
+static void layerSwap_origspace_face(void *data, int *corner_indices)
+{
+ OrigSpaceFace *osf = data;
+ float uv[4][2];
+ int j;
+
+ for(j = 0; j < 4; ++j) {
+ uv[j][0] = osf->uv[corner_indices[j]][0];
+ uv[j][1] = osf->uv[corner_indices[j]][1];
+ }
+ memcpy(osf->uv, uv, sizeof(osf->uv));
+}
+
+static void layerDefault_origspace_face(void *data, int count)
+{
+ static OrigSpaceFace default_osf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}};
+ OrigSpaceFace *osf = (OrigSpaceFace*)data;
+ int i;
+
+ for(i = 0; i < count; i++)
+ osf[i] = default_osf;
+}
+/* --------- */
+
+
+
+
static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -367,23 +444,32 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 3 floats per normal vector */
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
+ {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
+ {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+ {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
+ layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
+ {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
- "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags"};
+ "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
+ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
const CustomDataMask CD_MASK_MESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
- CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL;
+ CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
+ CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL;
+ CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL | CD_MASK_ORIGINDEX;
+ CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
+ CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO;
static const LayerTypeInfo *layerType_getInfo(int type)
{
@@ -540,6 +626,29 @@ int CustomData_get_render_layer_index(const CustomData *data, int type)
return -1;
}
+int CustomData_get_active_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active;
+
+ return -1;
+}
+
+int CustomData_get_render_layer(const CustomData *data, int type)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ return data->layers[i].active_rnd;
+
+ return -1;
+}
+
+
void CustomData_set_layer_active(CustomData *data, int type, int n)
{
int i;
@@ -558,6 +667,25 @@ void CustomData_set_layer_render(CustomData *data, int type, int n)
data->layers[i].active_rnd = n;
}
+/* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */
+void CustomData_set_layer_active_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active = n-i;
+}
+
+void CustomData_set_layer_render_index(CustomData *data, int type, int n)
+{
+ int i;
+
+ for(i=0; i < data->totlayer; ++i)
+ if(data->layers[i].type == type)
+ data->layers[i].active_rnd = n-i;
+}
+
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
{
@@ -1335,6 +1463,13 @@ const char *CustomData_layertype_name(int type)
return layerType_getName(type);
}
+static int CustomData_is_property_layer(int type)
+{
+ if((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
+ return 1;
+ return 0;
+}
+
void CustomData_set_layer_unique_name(CustomData *data, int index)
{
char tempname[64];
@@ -1355,9 +1490,17 @@ void CustomData_set_layer_unique_name(CustomData *data, int index)
/* see if there is a duplicate */
for(i=0; i<data->totlayer; i++) {
layer = &data->layers[i];
-
- if(i!=index && layer->type==type && strcmp(layer->name, name)==0)
- break;
+
+ if(CustomData_is_property_layer(type)){
+ if(i!=index && CustomData_is_property_layer(layer->type) &&
+ strcmp(layer->name, name)==0)
+ break;
+
+ }
+ else{
+ if(i!=index && layer->type==type && strcmp(layer->name, name)==0)
+ break;
+ }
}
if(i == data->totlayer)
@@ -1373,8 +1516,16 @@ void CustomData_set_layer_unique_name(CustomData *data, int index)
for(i=0; i<data->totlayer; i++) {
layer = &data->layers[i];
- if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0)
+ if(CustomData_is_property_layer(type)){
+ if(i!=index && CustomData_is_property_layer(layer->type) &&
+ strcmp(layer->name, tempname)==0)
+
break;
+ }
+ else{
+ if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0)
+ break;
+ }
}
if(i == data->totlayer) {
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index aa6220e88bc..9356ba14071 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -113,14 +113,31 @@ bDeformGroup *get_named_vertexgroup (Object *ob, char *name)
return NULL;
}
-int get_defgroup_num (Object *ob, bDeformGroup *dg)
+int get_named_vertexgroup_num (Object *ob, char *name)
+{
+ /* Return the location of the named deform group within the list of
+ * deform groups. This function is a combination of get_defgroup_num and
+ * get_named_vertexgroup. The other two could be called instead, but that
+ * require looping over the vertexgroups twice.
+ */
+ bDeformGroup *curdef;
+ int def_nr;
+
+ for (curdef=ob->defbase.first, def_nr=0; curdef; curdef=curdef->next, def_nr++) {
+ if (!strcmp(curdef->name, name))
+ return def_nr;
+ }
+
+ return -1;
+}
+
+int get_defgroup_num (Object *ob, bDeformGroup *dg)
{
/* Fetch the location of this deform group
* within the linked list of deform groups.
* (this number is stored in the deform
* weights of the deform verts to link them
- * to this deform group) deform deform
- * deform blah blah deform
+ * to this deform group).
*/
bDeformGroup *eg;
@@ -129,8 +146,7 @@ int get_defgroup_num (Object *ob, bDeformGroup *dg)
eg = ob->defbase.first;
def_nr = 0;
- /* loop through all deform groups
- */
+ /* loop through all deform groups */
while (eg != NULL) {
/* if the current deform group is
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index a71ed731b07..32927b6058c 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -44,6 +44,7 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
+#include "DNA_camera_types.h"
#include "DNA_ID.h"
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
@@ -56,6 +57,7 @@
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
#include "DNA_oops_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -71,8 +73,9 @@
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
-#include "BKE_scene.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
+#include "BKE_scene.h"
#include "MEM_guardedalloc.h"
#include "blendef.h"
@@ -347,10 +350,12 @@ static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int
static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask)
{
bConstraint *con;
+ bConstraintChannel *conchan;
DagNode * node;
DagNode * node2;
DagNode * node3;
Key *key;
+ ParticleSystem *psys;
int addtoroot= 1;
node = dag_get_node(dag, ob);
@@ -366,25 +371,34 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
if (ob->pose){
bPoseChannel *pchan;
bConstraint *con;
- Object * target;
- char *subtarget;
- for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
- for (con = pchan->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
+ for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ for (con = pchan->constraints.first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
- target = get_constraint_target(con, &subtarget);
- if (target!=ob) {
- // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
- node3 = dag_get_node(dag, target);
-
- if(subtarget && subtarget[0])
- dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
- else
- dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
-
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar && ct->tar != ob) {
+ // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
+ node3 = dag_get_node(dag, ct->tar);
+
+ if (ct->subtarget[0])
+ dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
+ else if(ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO))
+ dag_add_relation(dag,node3,node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ else
+ dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
+ }
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
+
}
}
}
@@ -398,9 +412,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
if(key && key->ipo)
dag_add_driver_relation(key->ipo, dag, node, 1);
+ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next)
+ if(conchan->ipo)
+ dag_add_driver_relation(conchan->ipo, dag, node, 0);
+
if(ob->action) {
bActionChannel *chan;
- bConstraintChannel *conchan;
for (chan = ob->action->chanbase.first; chan; chan=chan->next){
if(chan->ipo)
dag_add_driver_relation(chan->ipo, dag, node, 1);
@@ -477,7 +494,13 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB);
/* inverted relation, so addtoroot shouldn't be set to zero */
}
-
+ if (ob->type==OB_CAMERA) {
+ Camera *cam = (Camera *)ob->data;
+ if (cam->dof_ob) {
+ node2 = dag_get_node(dag, cam->dof_ob);
+ dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+ }
+ }
if (ob->transflag & OB_DUPLI) {
if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
GroupObject *go;
@@ -566,22 +589,98 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
}
}
}
+
+ psys= ob->particlesystem.first;
+ if(psys) {
+ ParticleEffectorCache *nec;
+ GroupObject *go;
+
+ for(; psys; psys=psys->next) {
+ ParticleSettings *part= psys->part;
+
+ dag_add_relation(dag, node, node, DAG_RL_OB_DATA);
+
+ if(part->phystype==PART_PHYS_KEYED && psys->keyed_ob &&
+ BLI_findlink(&psys->keyed_ob->particlesystem,psys->keyed_psys-1)) {
+ node2 = dag_get_node(dag, psys->keyed_ob);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA);
+ }
+
+ if(part->draw_as == PART_DRAW_OB && part->dup_ob) {
+ node2 = dag_get_node(dag, part->dup_ob);
+ dag_add_relation(dag, node, node2, DAG_RL_OB_OB);
+ }
+
+ if(part->draw_as == PART_DRAW_GR && part->dup_group) {
+ for(go=part->dup_group->gobject.first; go; go=go->next) {
+ node2 = dag_get_node(dag, go->ob);
+ dag_add_relation(dag, node, node2, DAG_RL_OB_OB);
+ }
+ }
+
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+ psys_init_effectors(ob,psys->part->eff_group,psys);
+
+ if(psys->effectors.first) {
+ 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);
+ else
+ dag_add_relation(dag, node2, node, DAG_RL_OB_DATA);
+ }
+ 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);
+ }
+ else if(nec->type & PSYS_EC_PARTICLE) {
+ node2 = dag_get_node(dag, ob1);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA);
+ }
+
+ if(nec->type & PSYS_EC_REACTOR) {
+ node2 = dag_get_node(dag, ob1);
+ dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA);
+ }
+ }
+ }
+ }
+ }
- for (con = ob->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- char *str;
- Object *obt= get_constraint_target(con, &str);
+ for (con = ob->constraints.first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
- node2 = dag_get_node(dag, obt);
- if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
- else {
- if(obt->type==OB_ARMATURE && str[0])
- dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ for (ct= targets.first; ct; ct= ct->next) {
+ Object *obt;
+
+ if (ct->tar)
+ obt= ct->tar;
else
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
+ continue;
+
+ node2 = dag_get_node(dag, obt);
+ if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO))
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ else {
+ if (ELEM3(obt->type, OB_ARMATURE, OB_MESH, OB_LATTICE) && (ct->subtarget[0]))
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ else
+ dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
+ }
+ addtoroot = 0;
}
- addtoroot = 0;
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
}
@@ -1705,10 +1804,23 @@ static void dag_object_time_update_flags(Object *ob)
if(ob->ipo) ob->recalc |= OB_RECALC_OB;
else if(ob->constraints.first) {
bConstraint *con;
- for (con = ob->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- ob->recalc |= OB_RECALC_OB;
- break;
+ for (con = ob->constraints.first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar) {
+ ob->recalc |= OB_RECALC_OB;
+ break;
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
}
}
@@ -1765,6 +1877,8 @@ static void dag_object_time_update_flags(Object *ob)
ob->recalc |= OB_RECALC_DATA; // NT FSPARTICLE
}
}
+ if(ob->particlesystem.first)
+ ob->recalc |= OB_RECALC_DATA;
break;
case OB_CURVE:
case OB_SURF:
@@ -1794,6 +1908,17 @@ static void dag_object_time_update_flags(Object *ob)
if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
break;
}
+
+ if(ob->particlesystem.first) {
+ ParticleSystem *psys= ob->particlesystem.first;
+
+ for(; psys; psys=psys->next) {
+ if(psys_check_enabled(ob, psys)) {
+ ob->recalc |= OB_RECALC_DATA;
+ break;
+ }
+ }
+ }
}
}
@@ -1952,8 +2077,8 @@ void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay)
/* object not in scene? then handle group exception. needs to be dagged once too */
if(node==NULL) {
- Group *group= find_group(ob);
- if(group) {
+ Group *group= NULL;
+ while( (group = find_group(ob, group)) ) {
GroupObject *go;
/* primitive; tag all... this call helps building groups for particles */
for(go= group->gobject.first; go; go= go->next)
@@ -1989,16 +2114,21 @@ void DAG_object_update_flags(Scene *sce, Object *ob, unsigned int lay)
static int node_recurs_level(DagNode *node, int level)
{
DagAdjList *itA;
-
+ int newlevel;
+
node->color= DAG_BLACK; /* done */
- level++;
+ newlevel= ++level;
for(itA= node->parent; itA; itA= itA->next) {
- if(itA->node->color==DAG_WHITE)
+ if(itA->node->color==DAG_WHITE) {
itA->node->ancestor_count= node_recurs_level(itA->node, level);
+ newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
+ }
+ else
+ newlevel= MAX2(newlevel, level+itA->node->ancestor_count);
}
- return level;
+ return newlevel;
}
static void pose_check_cycle(DagForest *dag)
@@ -2063,42 +2193,72 @@ void DAG_pose_sort(Object *ob)
dag_add_parent_relation(dag, node2, node, 0);
addtoroot = 0;
}
- for (con = pchan->constraints.first; con; con=con->next){
- if (constraint_has_target(con)) {
- char *subtarget;
- Object *target = get_constraint_target(con, &subtarget);
+ for (con = pchan->constraints.first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if(con->ipo) {
+ IpoCurve *icu;
+ for(icu= con->ipo->curve.first; icu; icu= icu->next) {
+ /* icu->driver->ob should actually point to ob->proxy if it
+ * is a proxy, but since it wasn't set correct it older
+ * files comparing with ob->proxy makes it work for those */
+ if(icu->driver && (icu->driver->ob==ob || icu->driver->ob==ob->proxy)) {
+ bPoseChannel *target= get_pose_channel(ob->pose, icu->driver->name);
+ if(target) {
+ node2 = dag_get_node(dag, target);
+ dag_add_relation(dag, node2, node, 0);
+ dag_add_parent_relation(dag, node2, node, 0);
+
+ /* uncommented this line, results in dependencies
+ * not being added properly for this constraint,
+ * what is the purpose of this? - brecht */
+ /*cti= NULL;*/ /* trick to get next loop skipped */
+ }
+ }
+ }
+ }
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
- if (target==ob && subtarget) {
- bPoseChannel *target= get_pose_channel(ob->pose, subtarget);
- if(target) {
- node2= dag_get_node(dag, target);
- dag_add_relation(dag, node2, node, 0);
- dag_add_parent_relation(dag, node2, node, 0);
-
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
- bKinematicConstraint *data = (bKinematicConstraint*)con->data;
- bPoseChannel *parchan;
- int segcount= 0;
-
- /* exclude tip from chain? */
- if(!(data->flag & CONSTRAINT_IK_TIP))
- parchan= pchan->parent;
- else
- parchan= pchan;
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar==ob && ct->subtarget[0]) {
+ bPoseChannel *target= get_pose_channel(ob->pose, ct->subtarget);
+ if (target) {
+ node2= dag_get_node(dag, target);
+ dag_add_relation(dag, node2, node, 0);
+ dag_add_parent_relation(dag, node2, node, 0);
- /* Walk to the chain's root */
- while (parchan){
- node3= dag_get_node(dag, parchan);
- dag_add_relation(dag, node2, node3, 0);
- dag_add_parent_relation(dag, node2, node3, 0);
+ if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data = (bKinematicConstraint *)con->data;
+ bPoseChannel *parchan;
+ int segcount= 0;
- segcount++;
- if(segcount==data->rootbone || segcount>255) break; // 255 is weak
- parchan= parchan->parent;
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ parchan= pchan->parent;
+ else
+ parchan= pchan;
+
+ /* Walk to the chain's root */
+ while (parchan) {
+ node3= dag_get_node(dag, parchan);
+ dag_add_relation(dag, node2, node3, 0);
+ dag_add_parent_relation(dag, node2, node3, 0);
+
+ segcount++;
+ if (segcount==data->rootbone || segcount>255) break; // 255 is weak
+ parchan= parchan->parent;
+ }
}
}
}
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
}
if (addtoroot == 1 ) {
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 30a4c8c3433..a9f009cd876 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -152,12 +152,9 @@ DispList *find_displist(ListBase *lb, int type)
int displist_has_faces(ListBase *lb)
{
DispList *dl;
-
- dl= lb->first;
- while(dl) {
+ for(dl= lb->first; dl; dl= dl->next) {
if ELEM3(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)
return 1;
- dl= dl->next;
}
return 0;
}
@@ -296,7 +293,7 @@ static Render *fastshade_get_render(void)
if(re==NULL) {
re= RE_NewRender("_Shade View_");
- RE_Database_Baking(re, G.scene, 0); /* 0= no faces */
+ RE_Database_Baking(re, G.scene, 0, 0); /* 0= no faces */
}
return re;
}
@@ -485,9 +482,11 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
| CD_MASK_MTFACE | CD_MASK_NORMAL;
+
init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
- orco = (need_orco)? mesh_create_orco(ob): NULL;
+ if(need_orco)
+ dataMask |= CD_MASK_ORCO;
if (onlyForMesh)
dm = mesh_get_derived_deform(ob, dataMask);
@@ -499,6 +498,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
nors = dm->getFaceDataArray(dm, CD_NORMAL);
totvert = dm->getNumVerts(dm);
totface = dm->getNumFaces(dm);
+ orco= dm->getVertDataArray(dm, CD_ORCO);
if (onlyForMesh) {
col1 = *col1_r;
@@ -577,9 +577,6 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
}
MEM_freeN(vnors);
- if (orco)
- MEM_freeN(orco);
-
dm->release(dm);
end_fastshade_for_ob(ob);
@@ -1098,7 +1095,7 @@ void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
- first point left, last point right
- based on subdivided points in original curve, not on points in taper curve (still)
*/
-static float calc_taper(Object *taperobj, int cur, int tot)
+float calc_taper(Object *taperobj, int cur, int tot)
{
Curve *cu;
DispList *dl;
@@ -1256,7 +1253,7 @@ void curve_calc_modifiers_post(Object *ob, ListBase *nurb, ListBase *dispbase, i
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
- if (mti->type!=eModifierTypeType_OnlyDeform) continue;
+ if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
for (dl=dispbase->first; dl; dl=dl->next) {
mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
@@ -1426,99 +1423,102 @@ void makeDispListCurveTypes(Object *ob, int forOrco)
BevPoint *bevp;
int a,b;
- /* exception handling; curve without bevel or extrude, with width correction */
- if(dlbev.first==NULL) {
- dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
- dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
- BLI_addtail(dispbase, dl);
-
- if(bl->poly!= -1) dl->type= DL_POLY;
- else dl->type= DL_SEGM;
-
- if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
+ if (bl->nr) { /* blank bevel lists can happen */
- dl->parts= 1;
- dl->nr= bl->nr;
- dl->col= nu->mat_nr;
- dl->charidx= nu->charidx;
- dl->rt= nu->flag;
-
- a= dl->nr;
- bevp= (BevPoint *)(bl+1);
- data= dl->verts;
- while(a--) {
- data[0]= bevp->x+widfac*bevp->sina;
- data[1]= bevp->y+widfac*bevp->cosa;
- data[2]= bevp->z;
- bevp++;
- data+=3;
- }
- }
- else {
- DispList *dlb;
-
- for (dlb=dlbev.first; dlb; dlb=dlb->next) {
-
- /* for each part of the bevel use a separate displblock */
- dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
- dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
+ /* exception handling; curve without bevel or extrude, with width correction */
+ if(dlbev.first==NULL) {
+ dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
+ dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
BLI_addtail(dispbase, dl);
-
- dl->type= DL_SURF;
- dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
- if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
- if(bl->poly>=0) dl->flag |= DL_CYCL_V;
+ if(bl->poly!= -1) dl->type= DL_POLY;
+ else dl->type= DL_SEGM;
- dl->parts= bl->nr;
- dl->nr= dlb->nr;
+ if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
+
+ dl->parts= 1;
+ dl->nr= bl->nr;
dl->col= nu->mat_nr;
dl->charidx= nu->charidx;
dl->rt= nu->flag;
- dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
- bevp= (BevPoint *)(bl+1);
-
- /* for each point of poly make a bevel piece */
+
+ a= dl->nr;
bevp= (BevPoint *)(bl+1);
- for(a=0; a<bl->nr; a++,bevp++) {
- float fac=1.0;
- if (cu->taperobj==NULL) {
- if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
- fac = calc_curve_subdiv_radius(cu, nu, a);
- } else {
- fac = calc_taper(cu->taperobj, a, bl->nr);
- }
+ data= dl->verts;
+ while(a--) {
+ data[0]= bevp->x+widfac*bevp->sina;
+ data[1]= bevp->y+widfac*bevp->cosa;
+ data[2]= bevp->z;
+ bevp++;
+ data+=3;
+ }
+ }
+ else {
+ DispList *dlb;
+
+ for (dlb=dlbev.first; dlb; dlb=dlb->next) {
+
+ /* for each part of the bevel use a separate displblock */
+ dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
+ dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
+ BLI_addtail(dispbase, dl);
+
+ dl->type= DL_SURF;
- if (bevp->f1) {
- dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
- }
-
- /* rotate bevel piece and write in data */
- fp1= dlb->verts;
- for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
- if(cu->flag & CU_3D) {
- float vec[3];
-
- vec[0]= fp1[1]+widfac;
- vec[1]= fp1[2];
- vec[2]= 0.0;
-
- Mat3MulVecfl(bevp->mat, vec);
-
- data[0]= bevp->x+ fac*vec[0];
- data[1]= bevp->y+ fac*vec[1];
- data[2]= bevp->z+ fac*vec[2];
+ dl->flag= dlb->flag & (DL_FRONT_CURVE|DL_BACK_CURVE);
+ if(dlb->type==DL_POLY) dl->flag |= DL_CYCL_U;
+ if(bl->poly>=0) dl->flag |= DL_CYCL_V;
+
+ dl->parts= bl->nr;
+ dl->nr= dlb->nr;
+ dl->col= nu->mat_nr;
+ dl->charidx= nu->charidx;
+ dl->rt= nu->flag;
+ dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
+ bevp= (BevPoint *)(bl+1);
+
+ /* for each point of poly make a bevel piece */
+ bevp= (BevPoint *)(bl+1);
+ for(a=0; a<bl->nr; a++,bevp++) {
+ float fac=1.0;
+ if (cu->taperobj==NULL) {
+ if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) )
+ fac = calc_curve_subdiv_radius(cu, nu, a);
+ } else {
+ fac = calc_taper(cu->taperobj, a, bl->nr);
}
- else {
- data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina;
- data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa;
- data[2]= bevp->z+ fac*fp1[2];
+
+ if (bevp->f1) {
+ dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
+ }
+
+ /* rotate bevel piece and write in data */
+ fp1= dlb->verts;
+ for (b=0; b<dlb->nr; b++,fp1+=3,data+=3) {
+ if(cu->flag & CU_3D) {
+ float vec[3];
+
+ vec[0]= fp1[1]+widfac;
+ vec[1]= fp1[2];
+ vec[2]= 0.0;
+
+ Mat3MulVecfl(bevp->mat, vec);
+
+ data[0]= bevp->x+ fac*vec[0];
+ data[1]= bevp->y+ fac*vec[1];
+ data[2]= bevp->z+ fac*vec[2];
+ }
+ else {
+ data[0]= bevp->x+ fac*(widfac+fp1[1])*bevp->sina;
+ data[1]= bevp->y+ fac*(widfac+fp1[1])*bevp->cosa;
+ data[2]= bevp->z+ fac*fp1[2];
+ }
}
}
+
+ /* gl array drawing: using indices */
+ displist_surf_indices(dl);
}
-
- /* gl array drawing: using indices */
- displist_surf_indices(dl);
}
}
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 00b2eb9fbd9..6e33805fbeb 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -799,7 +799,7 @@ static int pdDoDeflection(RNG *rng, float opco[3], float npco[3], float opno[3],
// t= 0.5; // this is labda of line, can use it optimize quad intersection
// sorry but no .. see below (BM)
- if( LineIntersectsTriangle(opco, npco, nv1, nv2, nv3, &t) ) {
+ if( LineIntersectsTriangle(opco, npco, nv1, nv2, nv3, &t, NULL) ) {
if (t < min_t) {
deflected = 1;
deflected_now = 1;
@@ -810,7 +810,7 @@ static int pdDoDeflection(RNG *rng, float opco[3], float npco[3], float opno[3],
// it might give a smaller t on (close to) the edge .. this is numerics not esoteric maths :)
// note: the 2 triangles don't need to share a plane ! (BM)
if (mface->v4) {
- if( LineIntersectsTriangle(opco, npco, nv1, nv3, nv4, &t2) ) {
+ if( LineIntersectsTriangle(opco, npco, nv1, nv3, nv4, &t2, NULL) ) {
if (t2 < min_t) {
deflected = 1;
deflected_now = 2;
@@ -1541,6 +1541,7 @@ typedef struct pMatrixCache {
/* WARN: this function stores data in ob->id.idnew! */
+/* error: this function changes ob->recalc of other objects... */
static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
{
pMatrixCache *mcache, *mc;
@@ -1551,26 +1552,27 @@ static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
/* object can be linked in group... stupid exception */
if(NULL==object_in_scene(ob, G.scene))
- group= find_group(ob);
+ group= find_group(ob, NULL); /* TODO - dont just use the first group! - Campbell */
mcache= mc= MEM_mallocN( (end-start+1)*sizeof(pMatrixCache), "ob matrix cache");
framelenold= G.scene->r.framelen;
G.scene->r.framelen= 1.0f;
cfrao= G.scene->r.cfra;
- sfo= ob->sf;
+ sfo= ob->sf; /* warning, dont use sfo, value should be from give_timeoffset if used for anything */
ob->sf= 0.0f;
- /* clear storage */
- for(obcopy= G.main->object.first; obcopy; obcopy= obcopy->id.next)
+ /* clear storage, copy recalc tag (bad loop) */
+ for(obcopy= G.main->object.first; obcopy; obcopy= obcopy->id.next) {
obcopy->id.newid= NULL;
+ obcopy->recalco= obcopy->recalc;
+ obcopy->recalc= 0;
+ }
/* all objects get tagged recalc that influence this object (does group too) */
- /* another hack; while transform you cannot call this, it sets own recalc flags */
- if(G.moving==0) {
- ob->recalc |= OB_RECALC_OB; /* make sure a recalc gets flushed */
- DAG_object_update_flags(G.scene, ob, -1);
- }
+ /* note that recalco has the real recalc tags, set by callers of this function */
+ ob->recalc |= OB_RECALC_OB; /* make sure a recalc gets flushed */
+ DAG_object_update_flags(G.scene, ob, -1);
for(G.scene->r.cfra= start; G.scene->r.cfra<=end; G.scene->r.cfra++, mc++) {
@@ -1649,7 +1651,12 @@ static pMatrixCache *cache_object_matrices(Object *ob, int start, int end)
}
}
}
- }
+ }
+
+ /* copy recalc tag (bad loop) */
+ for(obcopy= G.main->object.first; obcopy; obcopy= obcopy->id.next)
+ obcopy->recalc= obcopy->recalco;
+
return mcache;
}
@@ -1679,7 +1686,9 @@ void build_particle_system(Object *ob)
float *volengths= NULL, *folengths= NULL;
int deform=0, a, totpart, paf_sta, paf_end;
int waitcursor_set= 0, totvert, totface, curface, curvert;
+#ifndef DISABLE_ELBEEM
int readMask, activeParts, fileParts;
+#endif
/* return conditions */
if(ob->type!=OB_MESH) return;
@@ -2088,6 +2097,7 @@ void build_particle_system(Object *ob)
/* reset deflector cache */
for(base= G.scene->base.first; base; base= base->next) {
if(base->object->sumohandle) {
+
MEM_freeN(base->object->sumohandle);
base->object->sumohandle= NULL;
}
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 9d5e76e9ce7..b78efcd4ecf 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -878,7 +878,7 @@ static void read_videoscape_lamp(char *str)
Object *ob;
Lamp *la;
FILE *fp;
- float vec[3], *q1;
+ float vec[3], q1[4];
int tot, val;
char s[50];
@@ -906,7 +906,7 @@ static void read_videoscape_lamp(char *str)
fscanf(fp, "%f %f %f\n", ob->loc, ob->loc+1, ob->loc+2);
val= fscanf(fp, "%f %f %f\n", vec, vec+1, vec+2);
- q1= vectoquat(vec, 5, 2);
+ vectoquat(vec, 5, 2, q1);
QuatToEul(q1, ob->rot);
if(val<=0) break;
@@ -1246,7 +1246,12 @@ static void read_inventor(char *str, struct ListBase *listb)
error("Can't read file\n");
return;
}
+
filelen= BLI_filesize(file);
+ if(filelen < 1) {
+ close(file);
+ return;
+ }
maindata= MEM_mallocN(filelen, "leesInventor");
read(file, maindata, filelen);
@@ -3020,7 +3025,7 @@ void write_vrml(char *str)
/* FIRST: write all the datablocks */
- fprintf(fp, "#VRML V1.0 ascii\n\n# Blender V2.0\n\n# 'Switch' is used as a hack, to ensure it is not part of the drawing\n\n");
+ fprintf(fp, "#VRML V1.0 ascii\n\n# Blender V%d\n\n# 'Switch' is used as a hack, to ensure it is not part of the drawing\n\n", G.version);
fprintf(fp, "Separator {\n");
fprintf(fp, "Switch {\n");
@@ -3032,9 +3037,16 @@ void write_vrml(char *str)
ma= ma->id.next;
}
+ /* only write meshes we're using in this scene */
+ flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
+
+ for(base= G.scene->base.first; base; base= base->next)
+ if(base->object->type== OB_MESH)
+ ((ID *)base->object->data)->flag |= LIB_DOIT;
+
me= G.main->mesh.first;
while(me) {
- if(me->id.us) {
+ if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
write_mesh_vrml(fp, me);
}
me= me->id.next;
@@ -3337,10 +3349,18 @@ void write_dxf(char *str)
write_group(0, "SECTION");
write_group(2, "BLOCKS");
+
+ /* only write meshes we're using in this scene */
+ flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
+
+ for(base= G.scene->base.first; base; base= base->next)
+ if(base->object->type== OB_MESH)
+ ((ID *)base->object->data)->flag |= LIB_DOIT;
+
/* Write all the meshes */
me= G.main->mesh.first;
while(me) {
- if(me->id.us) {
+ if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
write_mesh_dxf(fp, me);
}
me= me->id.next;
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 201d93220f9..706bdf1245c 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -134,11 +134,11 @@ void add_to_group(Group *group, Object *ob)
}
/* also used for ob==NULL */
-void rem_from_group(Group *group, Object *ob)
+int rem_from_group(Group *group, Object *ob)
{
GroupObject *go, *gon;
-
- if(group==NULL) return;
+ int removed = 0;
+ if(group==NULL) return 0;
go= group->gobject.first;
while(go) {
@@ -146,9 +146,12 @@ void rem_from_group(Group *group, Object *ob)
if(go->ob==ob) {
BLI_remlink(&group->gobject, go);
free_group_object(go);
+ removed = 1;
+ /* should break here since an object being in a group twice cant happen? */
}
go= gon;
}
+ return removed;
}
int object_in_group(Object *ob, Group *group)
@@ -164,9 +167,12 @@ int object_in_group(Object *ob, Group *group)
return 0;
}
-Group *find_group(Object *ob)
+Group *find_group(Object *ob, Group *group)
{
- Group *group= G.main->group.first;
+ if (group)
+ group= group->id.next;
+ else
+ group= G.main->group.first;
while(group) {
if(object_in_group(ob, group))
@@ -188,6 +194,20 @@ void group_tag_recalc(Group *group)
}
}
+int group_is_animated(Object *parent, Group *group)
+{
+ GroupObject *go;
+
+ if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first)
+ return 1;
+
+ for(go= group->gobject.first; go; go= go->next)
+ if(go->ob && go->ob->proxy)
+ return 1;
+
+ return 0;
+}
+
/* only replaces object strips or action when parent nla instructs it */
/* keep checking nla.c though, in case internal structure of strip changes */
static void group_replaces_nla(Object *parent, Object *target, char mode)
@@ -228,7 +248,6 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
}
}
-
/* puts all group members in local timing system, after this call
you can draw everything, leaves tags in objects to signal it needs further updating */
@@ -238,12 +257,12 @@ void group_handle_recalc_and_update(Object *parent, Group *group)
GroupObject *go;
/* if animated group... */
- if(parent->sf != 0.0f || parent->nlastrips.first) {
+ if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first) {
int cfrao;
/* switch to local time */
cfrao= G.scene->r.cfra;
- G.scene->r.cfra -= (int)parent->sf;
+ G.scene->r.cfra -= (int)give_timeoffset(parent);
/* we need a DAG per group... */
for(go= group->gobject.first; go; go= go->next) {
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index ee37a4ec9f9..cab7865c1b6 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -1,34 +1,32 @@
/**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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/BL DUAL LICENSE BLOCK *****
- */
+* $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) 2006-2007 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
#include <math.h>
#include <stdlib.h>
@@ -41,10 +39,16 @@
#include "MEM_guardedalloc.h"
#include "DNA_ID.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_world_types.h"
#include "BLI_ghash.h"
#include "BKE_icons.h"
+#include "BKE_utildefines.h"
#define GS(a) (*((short *)(a)))
@@ -84,7 +88,7 @@ static int get_next_free_id()
return gNextIconId++;
/* now we try to find the smallest icon id not stored in the gIcons hash */
- while (BLI_ghash_lookup(gIcons, (void *)startId) && startId>=gFirstIconId)
+ while (BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(startId)) && startId>=gFirstIconId)
startId++;
/* if we found a suitable one that isnt used yet, return it */
@@ -111,6 +115,101 @@ void BKE_icons_free()
gIcons = NULL;
}
+struct PreviewImage* BKE_previewimg_create()
+{
+ PreviewImage* prv_img = NULL;
+ int i;
+
+ prv_img = MEM_callocN(sizeof(PreviewImage), "img_prv");
+
+ for (i=0; i<PREVIEW_MIPMAPS; ++i) {
+ prv_img->changed[i] = 1;
+ }
+ return prv_img;
+}
+
+void BKE_previewimg_free(PreviewImage **prv)
+{
+ if(prv && (*prv)) {
+ int i;
+
+ for (i=0; i<PREVIEW_MIPMAPS;++i) {
+ if ((*prv)->rect[i]) {
+ MEM_freeN((*prv)->rect[i]);
+ (*prv)->rect[i] = NULL;
+ }
+ }
+ MEM_freeN((*prv));
+ *prv = NULL;
+ }
+}
+
+struct PreviewImage* BKE_previewimg_copy(PreviewImage *prv)
+{
+ PreviewImage* prv_img = NULL;
+ int i;
+
+ if (prv) {
+ prv_img = MEM_dupallocN(prv);
+ for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+ if (prv->rect[i]) {
+ prv_img->rect[i] = MEM_dupallocN(prv->rect[i]);
+ } else {
+ prv_img->rect[i] = NULL;
+ }
+ }
+ }
+ return prv_img;
+}
+
+void BKE_previewimg_free_id(ID *id)
+{
+ if (GS(id->name) == ID_MA) {
+ Material *mat = (Material*)id;
+ BKE_previewimg_free(&mat->preview);
+ } else if (GS(id->name) == ID_TE) {
+ Tex *tex = (Tex*)id;
+ BKE_previewimg_free(&tex->preview);
+ } else if (GS(id->name) == ID_WO) {
+ World *wo = (World*)id;
+ BKE_previewimg_free(&wo->preview);
+ } else if (GS(id->name) == ID_LA) {
+ Lamp *la = (Lamp*)id;
+ BKE_previewimg_free(&la->preview);
+ } else if (GS(id->name) == ID_IM) {
+ Image *img = (Image*)id;
+ BKE_previewimg_free(&img->preview);
+ }
+}
+
+PreviewImage* BKE_previewimg_get(ID *id)
+{
+ PreviewImage* prv_img = NULL;
+
+ if (GS(id->name) == ID_MA) {
+ Material *mat = (Material*)id;
+ if (!mat->preview) mat->preview = BKE_previewimg_create();
+ prv_img = mat->preview;
+ } else if (GS(id->name) == ID_TE) {
+ Tex *tex = (Tex*)id;
+ if (!tex->preview) tex->preview = BKE_previewimg_create();
+ prv_img = tex->preview;
+ } else if (GS(id->name) == ID_WO) {
+ World *wo = (World*)id;
+ if (!wo->preview) wo->preview = BKE_previewimg_create();
+ prv_img = wo->preview;
+ } else if (GS(id->name) == ID_LA) {
+ Lamp *la = (Lamp*)id;
+ if (!la->preview) la->preview = BKE_previewimg_create();
+ prv_img = la->preview;
+ } else if (GS(id->name) == ID_IM) {
+ Image *img = (Image*)id;
+ if (!img->preview) img->preview = BKE_previewimg_create();
+ prv_img = img->preview;
+ }
+
+ return prv_img;
+}
void BKE_icon_changed(int id)
{
@@ -118,11 +217,19 @@ void BKE_icon_changed(int id)
if (!id) return;
- icon = BLI_ghash_lookup(gIcons, (void *)id);
+ icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id));
if (icon)
{
- icon->changed = 1;
+ PreviewImage *prv = BKE_previewimg_get((ID*)icon->obj);
+
+ /* all previews changed */
+ if (prv) {
+ int i;
+ for (i=0; i<PREVIEW_MIPMAPS; ++i) {
+ prv->changed[i] = 1;
+ }
+ }
}
}
@@ -151,9 +258,8 @@ int BKE_icon_getid(struct ID* id)
/* next two lines make sure image gets created */
new_icon->drawinfo = 0;
new_icon->drawinfo_free = 0;
- new_icon->changed = 1;
- BLI_ghash_insert(gIcons, (void *)id->icon_id, new_icon);
+ BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon);
return id->icon_id;
}
@@ -162,7 +268,7 @@ Icon* BKE_icon_get(int icon_id)
{
Icon* icon = 0;
- icon = BLI_ghash_lookup(gIcons, (void*)icon_id);
+ icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
if (!icon) {
printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id);
@@ -176,7 +282,7 @@ void BKE_icon_set(int icon_id, struct Icon* icon)
{
Icon* old_icon = 0;
- old_icon = BLI_ghash_lookup(gIcons, (void*)icon_id);
+ old_icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
if (old_icon)
{
@@ -184,7 +290,7 @@ void BKE_icon_set(int icon_id, struct Icon* icon)
return;
}
- BLI_ghash_insert(gIcons, (void *)icon_id, icon);
+ BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(icon_id), icon);
}
void BKE_icon_delete(struct ID* id)
@@ -192,6 +298,6 @@ void BKE_icon_delete(struct ID* id)
if (!id->icon_id) return; /* no icon defined for library object */
- BLI_ghash_remove(gIcons, (void*)id->icon_id, 0, icon_free);
+ BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), 0, icon_free);
id->icon_id = 0;
}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 4ff4073fdbe..8ac0ff77832 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -104,6 +104,31 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
MEM_freeN(prop->data.pointer);
}
+
+ static IDProperty *idp_generic_copy(IDProperty *prop)
+ {
+ IDProperty *newp = MEM_callocN(sizeof(IDProperty), "IDProperty array dup");
+
+ strncpy(newp->name, prop->name, MAX_IDPROP_NAME);
+ newp->type = prop->type;
+ newp->flag = prop->flag;
+ newp->data.val = prop->data.val;
+
+ return newp;
+ }
+
+IDProperty *IDP_CopyArray(IDProperty *prop)
+{
+ IDProperty *newp = idp_generic_copy(prop);
+
+ if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer);
+ newp->len = prop->len;
+ newp->subtype = prop->subtype;
+ newp->totallen = prop->totallen;
+
+ return newp;
+}
+
/*taken from readfile.c*/
#define SWITCH_LONGINT(a) { \
char s_i, *p_i; \
@@ -116,6 +141,19 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
/* ---------- String Type ------------ */
+IDProperty *IDP_CopyString(IDProperty *prop)
+{
+ IDProperty *newp = idp_generic_copy(prop);
+
+ if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer);
+ newp->len = prop->len;
+ newp->subtype = prop->subtype;
+ newp->totallen = prop->totallen;
+
+ return newp;
+}
+
+
void IDP_AssignString(IDProperty *prop, char *st)
{
int stlen;
@@ -154,7 +192,7 @@ void IDP_FreeString(IDProperty *prop)
}
-/*-------- ID Type -------*/
+/*-------- ID Type, not in use yet -------*/
void IDP_LinkID(IDProperty *prop, ID *id)
{
@@ -171,6 +209,18 @@ void IDP_UnlinkID(IDProperty *prop)
/*-------- Group Functions -------*/
/*checks if a property with the same name as prop exists, and if so replaces it.*/
+IDProperty *IDP_CopyGroup(IDProperty *prop)
+{
+ IDProperty *newp = idp_generic_copy(prop), *link;
+ newp->len = prop->len;
+
+ for (link=prop->data.group.first; link; link=link->next) {
+ BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
+ }
+
+ return newp;
+}
+
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
{
IDProperty *loop;
@@ -178,10 +228,11 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
if (BSTR_EQ(loop->name, prop->name)) {
if (loop->next) BLI_insertlinkbefore(&group->data.group, loop->next, prop);
else BLI_addtail(&group->data.group, prop);
+
BLI_remlink(&group->data.group, loop);
IDP_FreeProperty(loop);
MEM_freeN(loop);
- group->len++;
+
return;
}
}
@@ -274,6 +325,7 @@ void IDP_FreeGroup(IDProperty *prop)
for (loop=prop->data.group.first; loop; loop=next)
{
next = loop->next;
+ BLI_remlink(&prop->data.group, loop);
IDP_FreeProperty(loop);
MEM_freeN(loop);
}
@@ -281,6 +333,15 @@ void IDP_FreeGroup(IDProperty *prop)
/*-------- Main Functions --------*/
+IDProperty *IDP_CopyProperty(IDProperty *prop)
+{
+ switch (prop->type) {
+ case IDP_GROUP: return IDP_CopyGroup(prop);
+ case IDP_STRING: return IDP_CopyString(prop);
+ case IDP_ARRAY: return IDP_CopyArray(prop);
+ default: return idp_generic_copy(prop);
+ }
+}
IDProperty *IDP_GetProperties(ID *id, int create_if_needed)
{
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 21fa38fd83d..195f4aa4bbf 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -52,6 +52,7 @@
#include "DNA_image_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
@@ -70,6 +71,8 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BIF_editseq.h"
+
#include "PIL_time.h"
#include "RE_pipeline.h"
@@ -77,6 +80,12 @@
/* bad level; call to free_realtime_image */
#include "BKE_bad_level_calls.h"
+/* for stamp drawing to an image */
+#include "BMF_Api.h"
+
+#include "blendef.h"
+#include "BSE_time.h"
+
/* max int, to indicate we don't store sequences in ibuf */
#define IMA_NO_INDEX 0x7FEFEFEF
@@ -86,35 +95,53 @@
/* ******** IMAGE PROCESSING ************* */
-/* used by sequencer */
+/* used by sequencer and image premul option - IMA_DO_PREMUL */
void converttopremul(struct ImBuf *ibuf)
{
- int x, y, val;
- char *cp;
+ int x, y;
if(ibuf==0) return;
- if(ibuf->depth==24) { /* put alpha at 255 */
-
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- cp[3]= 255;
+ if (ibuf->rect) {
+ int val;
+ char *cp;
+ if(ibuf->depth==24) { /* put alpha at 255 */
+ cp= (char *)(ibuf->rect);
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ cp[3]= 255;
+ }
+ }
+ } else {
+ cp= (char *)(ibuf->rect);
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ val= cp[3];
+ cp[0]= (cp[0]*val)>>8;
+ cp[1]= (cp[1]*val)>>8;
+ cp[2]= (cp[2]*val)>>8;
+ }
}
}
- return;
}
-
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- if(cp[3]==0) {
- cp[0]= cp[1]= cp[2]= 0;
+ if (ibuf->rect_float) {
+ float val;
+ float *cp;
+ if(ibuf->depth==24) { /* put alpha at 1.0 */
+ cp= ibuf->rect_float;;
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ cp[3]= 1.0;
+ }
}
- else if(cp[3]!=255) {
- val= cp[3];
- cp[0]= (cp[0]*val)>>8;
- cp[1]= (cp[1]*val)>>8;
- cp[2]= (cp[2]*val)>>8;
+ } else {
+ cp= ibuf->rect_float;
+ for(y=0; y<ibuf->y; y++) {
+ for(x=0; x<ibuf->x; x++, cp+=4) {
+ val= cp[3];
+ cp[0]= cp[0]*val;
+ cp[1]= cp[1]*val;
+ cp[2]= cp[2]*val;
+ }
}
}
}
@@ -206,12 +233,6 @@ static void image_free_buffers(Image *ima)
if(ima->anim) IMB_free_anim(ima->anim);
ima->anim= NULL;
- if (ima->preview) {
- MEM_freeN(ima->preview->rect);
- MEM_freeN(ima->preview);
- ima->preview = NULL;
- }
-
if(ima->rr) {
RE_FreeRenderResult(ima->rr);
ima->rr= NULL;
@@ -233,6 +254,10 @@ void free_image(Image *ima)
}
BKE_icon_delete(&ima->id);
ima->id.icon_id = 0;
+ if (ima->preview) {
+ BKE_previewimg_free(&ima->preview);
+ }
+
}
/* only image block itself */
@@ -245,6 +270,7 @@ static Image *image_alloc(const char *name, short source, short type)
ima->ok= IMA_OK;
ima->xrep= ima->yrep= 1;
+ ima->aspx= ima->aspy= 1.0;
ima->gen_x= 256; ima->gen_y= 256;
ima->gen_type= 1; /* no defines yet? */
@@ -335,7 +361,7 @@ Image *BKE_add_image_file(const char *name)
/* first search an identical image */
for(ima= G.main->image.first; ima; ima= ima->id.next) {
- if(ima->source!=IMA_SRC_VIEWER) {
+ if(ima->source!=IMA_SRC_VIEWER && ima->source!=IMA_SRC_GENERATED) {
BLI_strncpy(strtest, ima->name, sizeof(ima->name));
BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
@@ -370,20 +396,27 @@ Image *BKE_add_image_file(const char *name)
return ima;
}
-static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, float color[4])
+static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4])
{
ImBuf *ibuf;
float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
- unsigned char *rect;
+ unsigned char *rect= NULL;
+ float *rect_float= NULL;
int x, y;
int checkerwidth=21, dark=1;
- ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
+ if (floatbuf) {
+ ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0);
+ rect_float= (float*)ibuf->rect_float;
+ }
+ else {
+ ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
+ rect= (unsigned char*)ibuf->rect;
+ }
+
strcpy(ibuf->name, "Untitled");
ibuf->userflags |= IB_BITMAPDIRTY;
- rect= (unsigned char*)ibuf->rect;
-
if (uvtestgrid) {
/* these two passes could be combined into one, but it's more readable and
* easy to tweak like this, speed isn't really that much of an issue in this situation... */
@@ -392,26 +425,40 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid,
for(y=0; y<ibuf->y; y++) {
dark = pow(-1, floor(y / checkerwidth));
- for(x=0; x<ibuf->x; x++, rect+=4) {
+ for(x=0; x<ibuf->x; x++) {
if (x % checkerwidth == 0) dark *= -1;
- if (dark > 0) {
- rect[0] = rect[1] = rect[2] = 64;
- rect[3] = 255;
- } else {
- rect[0] = rect[1] = rect[2] = 150;
- rect[3] = 255;
+ if (floatbuf) {
+ if (dark > 0) {
+ rect_float[0] = rect_float[1] = rect_float[2] = 0.25;
+ rect_float[3] = 1.0;
+ } else {
+ rect_float[0] = rect_float[1] = rect_float[2] = 0.58;
+ rect_float[3] = 1.0;
+ }
+ rect_float+=4;
+ }
+ else {
+ if (dark > 0) {
+ rect[0] = rect[1] = rect[2] = 64;
+ rect[3] = 255;
+ } else {
+ rect[0] = rect[1] = rect[2] = 150;
+ rect[3] = 255;
+ }
+ rect += 4;
}
}
}
/* 2nd pass, colored + */
- rect= (unsigned char*)ibuf->rect;
+ if (floatbuf) rect_float= (float*)ibuf->rect_float;
+ else rect= (unsigned char*)ibuf->rect;
for(y=0; y<ibuf->y; y++) {
hoffs = 0.125 * floor(y / checkerwidth);
- for(x=0; x<ibuf->x; x++, rect+=4) {
+ for(x=0; x<ibuf->x; x++) {
h = 0.125 * floor(x / checkerwidth);
if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
@@ -423,22 +470,44 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid,
hue = fmod(fabs(h-hoffs), 1.0);
hsv_to_rgb(hue, s, v, &r, &g, &b);
- rect[0]= (char)(r * 255.0);
- rect[1]= (char)(g * 255.0);
- rect[2]= (char)(b * 255.0);
- rect[3]= 255;
+ if (floatbuf) {
+ rect_float[0]= r;
+ rect_float[1]= g;
+ rect_float[2]= b;
+ rect_float[3]= 1.0;
+ }
+ else {
+ rect[0]= (char)(r * 255.0);
+ rect[1]= (char)(g * 255.0);
+ rect[2]= (char)(b * 255.0);
+ rect[3]= 255;
+ }
}
}
-
+
+ if (floatbuf)
+ rect_float+=4;
+ else
+ rect+=4;
}
}
} else { /* blank image */
for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, rect+=4) {
- rect[0]= (char)(color[0] * 255.0);
- rect[1]= (char)(color[1] * 255.0);
- rect[2]= (char)(color[2] * 255.0);
- rect[3]= (char)(color[3] * 255.0);
+ for(x=0; x<ibuf->x; x++) {
+ if (floatbuf) {
+ rect_float[0]= color[0];
+ rect_float[1]= color[1];
+ rect_float[2]= color[2];
+ rect_float[3]= color[3];
+ rect_float+=4;
+ }
+ else {
+ rect[0]= (char)(color[0] * 255.0);
+ rect[1]= (char)(color[1] * 255.0);
+ rect[2]= (char)(color[2] * 255.0);
+ rect[3]= (char)(color[3] * 255.0);
+ rect+=4;
+ }
}
}
}
@@ -446,7 +515,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid,
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4])
+Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4])
{
Image *ima;
@@ -461,7 +530,7 @@ Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, f
ima->gen_y= height;
ima->gen_type= uvtestgrid;
- ibuf= add_ibuf_size(width, height, name, uvtestgrid, color);
+ ibuf= add_ibuf_size(width, height, name, floatbuf, uvtestgrid, color);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok= IMA_OK_LOADED;
@@ -560,6 +629,47 @@ void free_old_images()
}
}
+static unsigned long image_mem_size(Image *ima)
+{
+ ImBuf *ibuf, *ibufm;
+ int level;
+ unsigned long size = 0;
+
+ size= 0;
+ for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) {
+ if(ibuf->rect) size += MEM_allocN_len(ibuf->rect);
+ else if(ibuf->rect_float) size += MEM_allocN_len(ibuf->rect_float);
+
+ for(level=0; level<IB_MIPMAP_LEVELS; level++) {
+ ibufm= ibuf->mipmap[level];
+ if(ibufm) {
+ if(ibufm->rect) size += MEM_allocN_len(ibufm->rect);
+ else if(ibufm->rect_float) size += MEM_allocN_len(ibufm->rect_float);
+ }
+ }
+ }
+
+ return size;
+}
+
+void BKE_image_print_memlist(void)
+{
+ Image *ima;
+ unsigned long size, totsize= 0;
+
+ for(ima= G.main->image.first; ima; ima= ima->id.next)
+ totsize += image_mem_size(ima);
+
+ printf("\ntotal image memory len: %.3lf MB\n", (double)totsize/(double)(1024*1024));
+
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ size= image_mem_size(ima);
+
+ if(size)
+ printf("%s len: %.3f MB\n", ima->id.name+2, (double)size/(double)(1024*1024));
+ }
+}
+
void BKE_image_free_all_textures(void)
{
Tex *tex;
@@ -633,6 +743,10 @@ int BKE_imtype_to_ftype(int imtype)
return RADHDR;
else if (imtype==R_PNG)
return PNG;
+#ifdef WITH_DDS
+ else if (imtype==R_DDS)
+ return DDS;
+#endif
else if (imtype==R_BMP)
return BMP;
else if (imtype==R_TIFF)
@@ -663,6 +777,10 @@ int BKE_ftype_to_imtype(int ftype)
return R_RADHDR;
else if (ftype & PNG)
return R_PNG;
+#ifdef WITH_DDS
+ else if (ftype & DDS)
+ return R_DDS;
+#endif
else if (ftype & BMP)
return R_BMP;
else if (ftype & TIF)
@@ -715,16 +833,22 @@ void BKE_add_image_extension(char *string, int imtype)
if(!BLI_testextensie(string, ".hdr"))
extension= ".hdr";
}
- else if(imtype==R_PNG) {
+ else if(imtype==R_PNG || imtype==R_FFMPEG) {
if(!BLI_testextensie(string, ".png"))
extension= ".png";
}
+#ifdef WITH_DDS
+ else if(imtype==R_DDS) {
+ if(!BLI_testextensie(string, ".dds"))
+ extension= ".dds";
+ }
+#endif
else if(imtype==R_RAWTGA) {
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
}
else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
- if(!BLI_testextensie(string, ".jpg"))
+ if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
extension= ".jpg";
}
else if(imtype==R_BMP) {
@@ -757,6 +881,283 @@ void BKE_add_image_extension(char *string, int imtype)
strcat(string, extension);
}
+/* could allow access externally - 512 is for long names, 64 is for id names */
+typedef struct StampData {
+ char file[512];
+ char note[512];
+ char date[512];
+ char marker[512];
+ char time[512];
+ char frame[512];
+ char camera[64];
+ char scene[64];
+ char strip[64];
+} StampData;
+
+static void stampdata(StampData *stamp_data, int do_prefix)
+{
+ char text[256];
+
+#ifndef WIN32
+ struct tm *tl;
+ time_t t;
+#else
+ char sdate[9];
+#endif /* WIN32 */
+
+ if (G.scene->r.stamp & R_STAMP_FILENAME) {
+ if (G.relbase_valid) {
+ if (do_prefix) sprintf(stamp_data->file, "File %s", G.sce);
+ else sprintf(stamp_data->file, "%s", G.sce);
+ } else {
+ if (do_prefix) strcpy(stamp_data->file, "File <untitled>");
+ else strcpy(stamp_data->file, "<untitled>");
+ }
+ stamp_data->note[0] = '\0';
+ } else {
+ stamp_data->file[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_NOTE) {
+ /* Never do prefix for Note */
+ sprintf(stamp_data->note, "%s", G.scene->r.stamp_udata);
+ } else {
+ stamp_data->note[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_DATE) {
+#ifdef WIN32
+ _strdate (sdate);
+ sprintf (text, "%s", sdate);
+#else
+ t = time (NULL);
+ tl = localtime (&t);
+ sprintf (text, "%04d-%02d-%02d", tl->tm_year+1900, tl->tm_mon+1, tl->tm_mday);
+#endif /* WIN32 */
+ if (do_prefix) sprintf(stamp_data->date, "Date %s", text);
+ else sprintf(stamp_data->date, "%s", text);
+ } else {
+ stamp_data->date[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_MARKER) {
+ TimeMarker *marker = get_frame_marker(CFRA);
+
+ if (marker) strcpy(text, marker->name);
+ else strcpy(text, "<none>");
+
+ if (do_prefix) sprintf(stamp_data->marker, "Marker %s", text);
+ else sprintf(stamp_data->marker, "%s", text);
+ } else {
+ stamp_data->marker[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_TIME) {
+ int h, m, s, f;
+ h= m= s= f= 0;
+ f = (int)(G.scene->r.cfra % G.scene->r.frs_sec);
+ s = (int)(G.scene->r.cfra / G.scene->r.frs_sec);
+
+ if (s) {
+ m = (int)(s / 60);
+ s %= 60;
+
+ if (m) {
+ h = (int)(m / 60);
+ m %= 60;
+ }
+ }
+
+ if (G.scene->r.frs_sec < 100)
+ sprintf (text, "%02d:%02d:%02d.%02d", h, m, s, f);
+ else
+ sprintf (text, "%02d:%02d:%02d.%03d", h, m, s, f);
+
+ if (do_prefix) sprintf(stamp_data->time, "Time %s", text);
+ else sprintf(stamp_data->time, "%s", text);
+ } else {
+ stamp_data->time[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_FRAME) {
+ char format[32];
+ if (do_prefix) sprintf(format, "Frame %%0%di\n", 1 + (int) log10(G.scene->r.efra));
+ else sprintf(format, "%%0%di\n", 1 + (int) log10(G.scene->r.efra));
+ sprintf (stamp_data->frame, format, G.scene->r.cfra);
+ } else {
+ stamp_data->frame[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_CAMERA) {
+ if (do_prefix) sprintf(stamp_data->camera, "Camera %s", ((Camera *) G.scene->camera)->id.name+2);
+ else sprintf(stamp_data->camera, "%s", ((Camera *) G.scene->camera)->id.name+2);
+ } else {
+ stamp_data->camera[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_SCENE) {
+ if (do_prefix) sprintf(stamp_data->scene, "Scene %s", G.scene->id.name+2);
+ else sprintf(stamp_data->scene, "%s", G.scene->id.name+2);
+ } else {
+ stamp_data->scene[0] = '\0';
+ }
+
+ if (G.scene->r.stamp & R_STAMP_SEQSTRIP) {
+ Sequence *seq = get_forground_frame_seq(CFRA);
+
+ if (seq) strcpy(text, seq->name+2);
+ else strcpy(text, "<none>");
+
+ if (do_prefix) sprintf(stamp_data->strip, "Strip %s", text);
+ else sprintf(stamp_data->strip, "%s", text);
+ } else {
+ stamp_data->strip[0] = '\0';
+ }
+}
+
+void BKE_stamp_buf(unsigned char *rect, float *rectf, int width, int height, int channels)
+{
+ struct StampData stamp_data;
+
+ int x=1,y=1;
+ int font_height;
+ int text_width;
+ int text_pad;
+ struct BMF_Font *font;
+
+ if (!rect && !rectf)
+ return;
+
+ stampdata(&stamp_data, 1);
+
+ switch (G.scene->r.stamp_font_id) {
+ case 1: /* tiny */
+ font = BMF_GetFont(BMF_kHelveticaBold8);
+ break;
+ case 2: /* small */
+ font = BMF_GetFont(BMF_kHelveticaBold10);
+ break;
+ case 3: /* medium */
+ font = BMF_GetFont(BMF_kScreen12);
+ break;
+ case 0: /* large - default */
+ font = BMF_GetFont(BMF_kScreen15);
+ break;
+ case 4: /* huge */
+ font = BMF_GetFont(BMF_kHelveticaBold14);
+ break;
+ default:
+ font = NULL;
+ break;
+ }
+
+ font_height = BMF_GetFontHeight(font);
+ /* All texts get halfspace+1 pixel on each side and 1 pix
+ above and below as padding against their backing rectangles */
+ text_pad = BMF_GetStringWidth(font, " ");
+
+ x = 1; /* Inits for everyone, text position, so 1 for padding, not 0 */
+ y = height - font_height - 1; /* Also inits for everyone, notice padding pixel */
+
+ if (stamp_data.file[0]) {
+ /* Top left corner */
+ text_width = BMF_GetStringWidth(font, stamp_data.file);
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.file, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ y -= font_height+2; /* Top and bottom 1 pix padding each */
+ }
+
+ /* Top left corner, below File */
+ if (stamp_data.note[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.note);
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.note, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ y -= font_height+2; /* Top and bottom 1 pix padding each */
+ }
+
+ /* Top left corner, below File (or Note) */
+ if (stamp_data.date[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.date);
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.date, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+ /* Bottom left corner, leaving space for timing */
+ if (stamp_data.marker[0]) {
+ x = 1;
+ y = font_height+2+1; /* 2 for padding in TIME|FRAME fields below and 1 for padding in this one */
+ text_width = BMF_GetStringWidth(font, stamp_data.marker);
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.marker, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+ /* Left bottom corner */
+ if (stamp_data.time[0]) {
+ x = 1;
+ y = 1;
+ text_width = BMF_GetStringWidth(font, stamp_data.time);
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.time, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ x += text_width+text_pad+2; /* Both sides have 1 pix additional padding each */
+ }
+
+ if (stamp_data.frame[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.frame);
+ /* Left bottom corner (after SMPTE if exists) */
+ if (!stamp_data.time[0]) x = 1;
+ y = 1;
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.frame, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+ if (stamp_data.camera[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.camera);
+ /* Center of bottom edge */
+ x = (width/2) - (BMF_GetStringWidth(font, stamp_data.camera)/2);
+ y = 1;
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.camera, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+ if (stamp_data.scene[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.scene);
+ /* Bottom right corner */
+ x = width - (text_width+1+text_pad);
+ y = 1;
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.scene, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+ if (stamp_data.strip[0]) {
+ text_width = BMF_GetStringWidth(font, stamp_data.strip);
+ /* Top right corner */
+ x = width - (text_width+1+text_pad);
+ y = height - font_height - 1;
+ buf_rectfill_area(rect, rectf, width, height, G.scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
+ BMF_DrawStringBuf(font, stamp_data.strip, x+(text_pad/2), y, G.scene->r.fg_stamp, rect, rectf, width, height, channels);
+ }
+
+}
+
+void BKE_stamp_info(struct ImBuf *ibuf)
+{
+ struct StampData stamp_data;
+
+ if (!ibuf) return;
+
+ /* fill all the data values, no prefix */
+ stampdata(&stamp_data, 0);
+
+ if (stamp_data.file[0]) IMB_imginfo_change_field (ibuf, "File", stamp_data.file);
+ if (stamp_data.note[0]) IMB_imginfo_change_field (ibuf, "Note", stamp_data.note);
+ if (stamp_data.date[0]) IMB_imginfo_change_field (ibuf, "Date", stamp_data.date);
+ if (stamp_data.marker[0]) IMB_imginfo_change_field (ibuf, "Marker", stamp_data.marker);
+ if (stamp_data.time[0]) IMB_imginfo_change_field (ibuf, "Time", stamp_data.time);
+ if (stamp_data.frame[0]) IMB_imginfo_change_field (ibuf, "Frame", stamp_data.frame);
+ if (stamp_data.camera[0]) IMB_imginfo_change_field (ibuf, "Camera", stamp_data.camera);
+ if (stamp_data.scene[0]) IMB_imginfo_change_field (ibuf, "Scene", stamp_data.scene);
+ if (stamp_data.strip[0]) IMB_imginfo_change_field (ibuf, "Strip", stamp_data.strip);
+}
int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quality)
{
@@ -768,14 +1169,22 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
else if ((imtype==R_RADHDR)) {
ibuf->ftype= RADHDR;
}
- else if ((imtype==R_PNG)) {
+ else if (imtype==R_PNG || imtype==R_FFMPEG) {
ibuf->ftype= PNG;
}
+#ifdef WITH_DDS
+ else if ((imtype==R_DDS)) {
+ ibuf->ftype= DDS;
+ }
+#endif
else if ((imtype==R_BMP)) {
ibuf->ftype= BMP;
}
else if ((G.have_libtiff) && (imtype==R_TIFF)) {
ibuf->ftype= TIF;
+
+ if(subimtype & R_TIFF_16BIT)
+ ibuf->ftype |= TIF_16BIT;
}
#ifdef WITH_OPENEXR
else if (imtype==R_OPENEXR || imtype==R_MULTILAYER) {
@@ -812,6 +1221,9 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
}
BLI_make_existing_file(name);
+
+ if(G.scene->r.scemode & R_STAMP_INFO)
+ BKE_stamp_info(ibuf);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
if (ok == 0) {
@@ -1236,7 +1648,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
BLI_convertstringcode(str, G.sce, cfra);
/* read ibuf */
- ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer);
+ ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer|IB_imginfo);
}
if (ibuf) {
@@ -1258,6 +1670,9 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
ima->packedfile = newPackedFile(str);
}
+
+ if(ima->flag & IMA_DO_PREMUL)
+ converttopremul(ibuf);
}
else
ima->ok= 0;
@@ -1358,6 +1773,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
ibuf->rect_float= rectf;
ibuf->flags |= IB_rectfloat;
ibuf->channels= channels;
+ ibuf->zbuf_float= rres.rectz;
+ ibuf->flags |= IB_zbuffloat;
ima->ok= IMA_OK_LOADED;
return ibuf;
@@ -1450,7 +1867,7 @@ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
/* 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;
- ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_type, color);
+ 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;
}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
new file mode 100644
index 00000000000..2b01f256c56
--- /dev/null
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -0,0 +1,1698 @@
+/* implicit.c
+*
+*
+* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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) Blender Foundation
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+#include "math.h"
+#include "float.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "MEM_guardedalloc.h"
+/* types */
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_cloth_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_threads.h"
+#include "BKE_curve.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_object.h"
+#include "BKE_cloth.h"
+#include "BKE_modifier.h"
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BIF_editdeform.h"
+
+
+#ifdef _WIN32
+#include <windows.h>
+static LARGE_INTEGER _itstart, _itend;
+static LARGE_INTEGER ifreq;
+void itstart(void)
+{
+ static int first = 1;
+ if(first) {
+ QueryPerformanceFrequency(&ifreq);
+ first = 0;
+ }
+ QueryPerformanceCounter(&_itstart);
+}
+void itend(void)
+{
+ QueryPerformanceCounter(&_itend);
+}
+double itval()
+{
+ return ((double)_itend.QuadPart -
+ (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
+}
+#else
+#include <sys/time.h>
+// intrinsics need better compile flag checking
+// #include <xmmintrin.h>
+// #include <pmmintrin.h>
+// #include <pthread.h>
+
+ static struct timeval _itstart, _itend;
+ static struct timezone itz;
+ void itstart(void)
+{
+ gettimeofday(&_itstart, &itz);
+}
+void itend(void)
+{
+ gettimeofday(&_itend,&itz);
+}
+double itval()
+{
+ double t1, t2;
+ t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000);
+ t2 = (double)_itend.tv_sec + (double)_itend.tv_usec/(1000*1000);
+ return t2-t1;
+}
+#endif
+
+static float I[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
+static float ZERO[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
+
+/*
+#define C99
+#ifdef C99
+#defineDO_INLINE inline
+#else
+#defineDO_INLINE static
+#endif
+*/
+struct Cloth;
+
+//////////////////////////////////////////
+/* fast vector / matrix library, enhancements are welcome :) -dg */
+/////////////////////////////////////////
+
+/* DEFINITIONS */
+typedef float lfVector[3];
+typedef struct fmatrix3x3 {
+ float m[3][3]; /* 3x3 matrix */
+ unsigned int c,r; /* column and row number */
+ int pinned; /* is this vertex allowed to move? */
+ float n1,n2,n3; /* three normal vectors for collision constrains */
+ unsigned int vcount; /* vertex count */
+ unsigned int scount; /* spring count */
+} fmatrix3x3;
+
+///////////////////////////
+// float[3] vector
+///////////////////////////
+/* simple vector code */
+/* STATUS: verified */
+DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
+{
+ to[0] = from[0] * scalar;
+ to[1] = from[1] * scalar;
+ to[2] = from[2] * scalar;
+}
+/* simple cross product */
+/* STATUS: verified */
+DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3])
+{
+ to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1];
+ to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2];
+ to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0];
+}
+/* simple v^T * v product ("outer product") */
+/* STATUS: HAS TO BE verified (*should* work) */
+DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
+{
+ mul_fvector_S(to[0], vectorB, vectorA[0]);
+ mul_fvector_S(to[1], vectorB, vectorA[1]);
+ mul_fvector_S(to[2], vectorB, vectorA[2]);
+}
+/* simple v^T * v product with scalar ("outer product") */
+/* STATUS: HAS TO BE verified (*should* work) */
+DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
+{
+ mul_fvectorT_fvector(to, vectorA, vectorB);
+
+ mul_fvector_S(to[0], to[0], aS);
+ mul_fvector_S(to[1], to[1], aS);
+ mul_fvector_S(to[2], to[2], aS);
+}
+
+
+/* printf vector[3] on console: for debug output */
+void print_fvector(float m3[3])
+{
+ printf("%f\n%f\n%f\n\n",m3[0],m3[1],m3[2]);
+}
+
+///////////////////////////
+// long float vector float (*)[3]
+///////////////////////////
+/* print long vector on console: for debug output */
+DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+ for(i = 0; i < verts; i++)
+ {
+ print_fvector(fLongVector[i]);
+ }
+}
+/* create long vector */
+DO_INLINE lfVector *create_lfvector(unsigned int verts)
+{
+ // TODO: check if memory allocation was successfull */
+ return (lfVector *)MEM_callocN (verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
+ // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
+}
+/* delete long vector */
+DO_INLINE void del_lfvector(float (*fLongVector)[3])
+{
+ if (fLongVector != NULL)
+ {
+ MEM_freeN (fLongVector);
+ // cloth_aligned_free(&MEMORY_BASE, fLongVector);
+ }
+}
+/* copy long vector */
+DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
+{
+ memcpy(to, from, verts * sizeof(lfVector));
+}
+/* init long vector with float[3] */
+DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
+{
+ unsigned int i = 0;
+ for(i = 0; i < verts; i++)
+ {
+ VECCOPY(fLongVector[i], vector);
+ }
+}
+/* zero long vector with float[3] */
+DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
+{
+ memset(to, 0.0f, verts * sizeof(lfVector));
+}
+/* multiply long vector with scalar*/
+DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < verts; i++)
+ {
+ mul_fvector_S(to[i], fLongVector[i], scalar);
+ }
+}
+/* multiply long vector with scalar*/
+/* A -= B * float */
+DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
+{
+ unsigned int i = 0;
+ for(i = 0; i < verts; i++)
+ {
+ VECSUBMUL(to[i], fLongVector[i], scalar);
+ }
+}
+/* dot product for big vector */
+DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ long i = 0;
+ float temp = 0.0;
+// schedule(guided, 2)
+#pragma omp parallel for reduction(+: temp)
+ for(i = 0; i < (long)verts; i++)
+ {
+ temp += INPR(fLongVectorA[i], fLongVectorB[i]);
+ }
+ return temp;
+}
+/* A = B + C --> for big vector */
+DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < verts; i++)
+ {
+ VECADD(to[i], fLongVectorA[i], fLongVectorB[i]);
+ }
+
+}
+/* A = B + C * float --> for big vector */
+DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < verts; i++)
+ {
+ VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
+
+ }
+}
+/* A = B * float + C * float --> for big vector */
+DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < verts; i++)
+ {
+ VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
+ }
+}
+/* A = B - C * float --> for big vector */
+DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+ for(i = 0; i < verts; i++)
+ {
+ VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
+ }
+
+}
+/* A = B - C --> for big vector */
+DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < verts; i++)
+ {
+ VECSUB(to[i], fLongVectorA[i], fLongVectorB[i]);
+ }
+
+}
+///////////////////////////
+// 3x3 matrix
+///////////////////////////
+/* printf 3x3 matrix on console: for debug output */
+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]);
+ printf("%f\t%f\t%f\n\n",m3[2][0],m3[2][1],m3[2][2]);
+}
+
+/* copy 3x3 matrix */
+DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
+{
+ // memcpy(to, from, sizeof (float) * 9);
+ VECCOPY(to[0], from[0]);
+ VECCOPY(to[1], from[1]);
+ VECCOPY(to[2], from[2]);
+}
+
+/* copy 3x3 matrix */
+DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
+{
+ cp_fmatrix(to, ZERO);
+
+ to[0][0] = aS;
+ to[1][1] = aS;
+ to[2][2] = aS;
+}
+
+/* calculate determinant of 3x3 matrix */
+DO_INLINE float det_fmatrix(float m[3][3])
+{
+ return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0]
+ -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
+}
+
+DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
+{
+ unsigned int i, j;
+ float d;
+
+ if((d=det_fmatrix(from))==0)
+ {
+ printf("can't build inverse");
+ exit(0);
+ }
+ for(i=0;i<3;i++)
+ {
+ for(j=0;j<3;j++)
+ {
+ int i1=(i+1)%3;
+ int i2=(i+2)%3;
+ int j1=(j+1)%3;
+ int j2=(j+2)%3;
+ // reverse indexs i&j to take transpose
+ to[j][i] = (from[i1][j1]*from[i2][j2]-from[i1][j2]*from[i2][j1])/d;
+ /*
+ if(i==j)
+ to[i][j] = 1.0f / from[i][j];
+ else
+ to[i][j] = 0;
+ */
+ }
+ }
+
+}
+
+/* 3x3 matrix multiplied by a scalar */
+/* STATUS: verified */
+DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
+{
+ mul_fvector_S(matrix[0], matrix[0],scalar);
+ mul_fvector_S(matrix[1], matrix[1],scalar);
+ mul_fvector_S(matrix[2], matrix[2],scalar);
+}
+
+/* a vector multiplied by a 3x3 matrix */
+/* STATUS: verified */
+DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3])
+{
+ to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
+ to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
+ to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
+}
+
+/* 3x3 matrix multiplied by a vector */
+/* STATUS: verified */
+DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float *from)
+{
+ to[0] = INPR(matrix[0],from);
+ to[1] = INPR(matrix[1],from);
+ to[2] = INPR(matrix[2],from);
+}
+/* 3x3 matrix multiplied by a 3x3 matrix */
+/* STATUS: verified */
+DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ mul_fvector_fmatrix(to[0], matrixA[0],matrixB);
+ mul_fvector_fmatrix(to[1], matrixA[1],matrixB);
+ mul_fvector_fmatrix(to[2], matrixA[2],matrixB);
+}
+/* 3x3 matrix addition with 3x3 matrix */
+DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECADD(to[0], matrixA[0], matrixB[0]);
+ VECADD(to[1], matrixA[1], matrixB[1]);
+ VECADD(to[2], matrixA[2], matrixB[2]);
+}
+/* 3x3 matrix add-addition with 3x3 matrix */
+DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECADDADD(to[0], matrixA[0], matrixB[0]);
+ VECADDADD(to[1], matrixA[1], matrixB[1]);
+ VECADDADD(to[2], matrixA[2], matrixB[2]);
+}
+/* 3x3 matrix sub-addition with 3x3 matrix */
+DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
+{
+ VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS);
+ VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS);
+ VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS);
+}
+/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */
+DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECSUBADD(to[0], matrixA[0], matrixB[0]);
+ VECSUBADD(to[1], matrixA[1], matrixB[1]);
+ VECSUBADD(to[2], matrixA[2], matrixB[2]);
+}
+/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
+DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
+{
+ VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
+ VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
+ VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
+}
+/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
+DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECSUB(to[0], matrixA[0], matrixB[0]);
+ VECSUB(to[1], matrixA[1], matrixB[1]);
+ VECSUB(to[2], matrixA[2], matrixB[2]);
+}
+/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */
+DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECADDSUB(to[0], matrixA[0], matrixB[0]);
+ VECADDSUB(to[1], matrixA[1], matrixB[1]);
+ VECADDSUB(to[2], matrixA[2], matrixB[2]);
+}
+/////////////////////////////////////////////////////////////////
+// special functions
+/////////////////////////////////////////////////////////////////
+/* a vector multiplied and added to/by a 3x3 matrix */
+DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
+{
+ to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
+ to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
+ to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
+}
+/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */
+DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ muladd_fvector_fmatrix(to[0], matrixA[0],matrixB);
+ muladd_fvector_fmatrix(to[1], matrixA[1],matrixB);
+ muladd_fvector_fmatrix(to[2], matrixA[2],matrixB);
+}
+/* a vector multiplied and sub'd to/by a 3x3 matrix */
+DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
+{
+ to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
+ to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
+ to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
+}
+/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */
+DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ mulsub_fvector_fmatrix(to[0], matrixA[0],matrixB);
+ mulsub_fvector_fmatrix(to[1], matrixA[1],matrixB);
+ mulsub_fvector_fmatrix(to[2], matrixA[2],matrixB);
+}
+/* 3x3 matrix multiplied+added by a vector */
+/* STATUS: verified */
+DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
+{
+ to[0] += INPR(matrix[0],from);
+ to[1] += INPR(matrix[1],from);
+ to[2] += INPR(matrix[2],from);
+}
+/* 3x3 matrix multiplied+sub'ed by a vector */
+DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
+{
+ to[0] -= INPR(matrix[0],from);
+ to[1] -= INPR(matrix[1],from);
+ to[2] -= INPR(matrix[2],from);
+}
+/////////////////////////////////////////////////////////////////
+
+///////////////////////////
+// SPARSE SYMMETRIC big matrix with 3x3 matrix entries
+///////////////////////////
+/* printf a big matrix on console: for debug output */
+void print_bfmatrix(fmatrix3x3 *m3)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < m3[0].vcount + m3[0].scount; i++)
+ {
+ print_fmatrix(m3[i].m);
+ }
+}
+/* create big matrix */
+DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
+{
+ // TODO: check if memory allocation was successfull */
+ fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN (sizeof (fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
+ temp[0].vcount = verts;
+ temp[0].scount = springs;
+ return temp;
+}
+/* delete big matrix */
+DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
+{
+ if (matrix != NULL)
+ {
+ MEM_freeN (matrix);
+ }
+}
+
+/* copy big matrix */
+DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
+{
+ // TODO bounds checking
+ memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount+from[0].scount) );
+}
+
+/* init big matrix */
+// slow in parallel
+DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
+{
+ unsigned int i;
+
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ cp_fmatrix(matrix[i].m, m3);
+ }
+}
+
+/* init the diagonal of big matrix */
+// slow in parallel
+DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
+{
+ unsigned int i,j;
+ float tmatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
+
+ for(i = 0; i < matrix[0].vcount; i++)
+ {
+ cp_fmatrix(matrix[i].m, m3);
+ }
+ for(j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++)
+ {
+ cp_fmatrix(matrix[j].m, tmatrix);
+ }
+}
+
+/* multiply big matrix with scalar*/
+DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
+{
+ unsigned int i = 0;
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ mul_fmatrix_S(matrix[i].m, scalar);
+ }
+}
+
+/* SPARSE SYMMETRIC multiply big matrix with long vector*/
+/* STATUS: verified */
+DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
+{
+ unsigned int i = 0;
+ lfVector *temp = create_lfvector(from[0].vcount);
+
+ zero_lfvector(to, from[0].vcount);
+
+#pragma omp parallel sections private(i)
+ {
+#pragma omp section
+ {
+ for(i = from[0].vcount; i < from[0].vcount+from[0].scount; i++)
+ {
+ muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
+ }
+ }
+#pragma omp section
+ {
+ for(i = 0; i < from[0].vcount+from[0].scount; i++)
+ {
+ muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
+ }
+ }
+ }
+ add_lfvector_lfvector(to, to, temp, from[0].vcount);
+
+ del_lfvector(temp);
+
+
+}
+
+/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
+/* STATUS: verified */
+DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
+{
+ unsigned int i = 0;
+
+ for(i = 0; i < from[0].vcount; i++)
+ {
+ mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
+ }
+}
+
+/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
+DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
+ }
+
+}
+/* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */
+DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
+ }
+
+}
+/* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */
+DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
+ }
+
+}
+/* A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */
+DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
+ }
+
+}
+/* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */
+DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount; i++)
+ {
+ sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m);
+ }
+
+}
+/* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */
+DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
+ }
+
+}
+/* SPARSE SYMMETRIC sub big matrix with big matrix*/
+/* A -= B * float + C * float --> for big matrix */
+/* VERIFIED */
+DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for(i = 0; i < matrix[0].vcount+matrix[0].scount; i++)
+ {
+ subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS);
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////
+// simulator start
+///////////////////////////////////////////////////////////////////
+typedef struct Implicit_Data
+{
+ lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z;
+ fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI, *M;
+} Implicit_Data;
+
+int implicit_init (Object *ob, ClothModifierData *clmd)
+{
+ unsigned int i = 0;
+ unsigned int pinned = 0;
+ Cloth *cloth = NULL;
+ ClothVertex *verts = NULL;
+ ClothSpring *spring = NULL;
+ Implicit_Data *id = NULL;
+ LinkNode *search = NULL;
+
+ if(G.rt > 0)
+ printf("implicit_init\n");
+
+ // init memory guard
+ // MEMORY_BASE.first = MEMORY_BASE.last = NULL;
+
+ cloth = (Cloth *)clmd->clothObject;
+ verts = cloth->verts;
+
+ // create implicit base
+ id = (Implicit_Data *)MEM_callocN (sizeof(Implicit_Data), "implicit vecmat");
+ cloth->implicit = id;
+
+ /* process diagonal elements */
+ id->A = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->dFdV = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->dFdX = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->S = create_bfmatrix(cloth->numverts, 0);
+ id->Pinv = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->P = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->bigI = create_bfmatrix(cloth->numverts, cloth->numsprings); // TODO 0 springs
+ id->M = create_bfmatrix(cloth->numverts, cloth->numsprings);
+ id->X = create_lfvector(cloth->numverts);
+ id->Xnew = create_lfvector(cloth->numverts);
+ id->V = create_lfvector(cloth->numverts);
+ id->Vnew = create_lfvector(cloth->numverts);
+ id->olddV = create_lfvector(cloth->numverts);
+ zero_lfvector(id->olddV, cloth->numverts);
+ id->F = create_lfvector(cloth->numverts);
+ id->B = create_lfvector(cloth->numverts);
+ id->dV = create_lfvector(cloth->numverts);
+ id->z = create_lfvector(cloth->numverts);
+
+ for(i=0;i<cloth->numverts;i++)
+ {
+ id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = id->M[i].r = id->M[i].c = i;
+
+ if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ id->S[pinned].pinned = 1;
+ id->S[pinned].c = id->S[pinned].r = i;
+ pinned++;
+ }
+
+ initdiag_fmatrixS(id->M[i].m, verts[i].mass);
+ }
+
+ // S is special and needs specific vcount and scount
+ id->S[0].vcount = pinned; id->S[0].scount = 0;
+
+ // init springs
+ search = cloth->springs;
+ for(i=0;i<cloth->numsprings;i++)
+ {
+ spring = search->link;
+
+ // dFdV_start[i].r = big_I[i].r = big_zero[i].r =
+ id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r =
+ id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = id->M[i+cloth->numverts].r = spring->ij;
+
+ // dFdV_start[i].c = big_I[i].c = big_zero[i].c =
+ id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c =
+ id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = id->M[i+cloth->numverts].c = spring->kl;
+
+ spring->matrix_index = i + cloth->numverts;
+
+ search = search->next;
+ }
+
+ initdiag_bfmatrix(id->bigI, I);
+
+ for(i = 0; i < cloth->numverts; i++)
+ {
+ VECCOPY(id->X[i], verts[i].x);
+ }
+
+ return 1;
+}
+int implicit_free (ClothModifierData *clmd)
+{
+ Implicit_Data *id;
+ Cloth *cloth;
+ cloth = (Cloth *)clmd->clothObject;
+
+ if(cloth)
+ {
+ id = cloth->implicit;
+
+ if(id)
+ {
+ del_bfmatrix(id->A);
+ del_bfmatrix(id->dFdV);
+ del_bfmatrix(id->dFdX);
+ del_bfmatrix(id->S);
+ del_bfmatrix(id->P);
+ del_bfmatrix(id->Pinv);
+ del_bfmatrix(id->bigI);
+ del_bfmatrix(id->M);
+
+ del_lfvector(id->X);
+ del_lfvector(id->Xnew);
+ del_lfvector(id->V);
+ del_lfvector(id->Vnew);
+ del_lfvector(id->olddV);
+ del_lfvector(id->F);
+ del_lfvector(id->B);
+ del_lfvector(id->dV);
+ del_lfvector(id->z);
+
+ MEM_freeN(id);
+ }
+ }
+
+ return 1;
+}
+
+DO_INLINE float fb(float length, float L)
+{
+ float x = length/L;
+ return (-11.541f*pow(x,4)+34.193f*pow(x,3)-39.083f*pow(x,2)+23.116f*x-9.713f);
+}
+
+DO_INLINE float fbderiv(float length, float L)
+{
+ float x = length/L;
+
+ return (-46.164f*pow(x,3)+102.579f*pow(x,2)-78.166f*x+23.116f);
+}
+
+DO_INLINE float fbstar(float length, float L, float kb, float cb)
+{
+ float tempfb = kb * fb(length, L);
+
+ float fbstar = cb * (length - L);
+
+ if(tempfb < fbstar)
+ return fbstar;
+ else
+ return tempfb;
+}
+
+// function to calculae bending spring force (taken from Choi & Co)
+DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
+{
+ float tempfb = kb * fb(length, L);
+ float fbstar = cb * (length - L);
+
+ if(tempfb < fbstar)
+ {
+ return cb;
+ }
+ else
+ {
+ return kb * fbderiv(length, L);
+ }
+}
+
+DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
+{
+ unsigned int i=0;
+
+ for(i=0;i<S[0].vcount;i++)
+ {
+ mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m);
+ }
+}
+
+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;
+ float conjgrad_epsilon=0.0001f, conjgrad_lasterror=0;
+ lfVector *q, *d, *tmp, *r;
+ float s, starget, a, s_prev;
+ unsigned int numverts = lA[0].vcount;
+ q = create_lfvector(numverts);
+ d = create_lfvector(numverts);
+ tmp = create_lfvector(numverts);
+ r = create_lfvector(numverts);
+
+ // zero_lfvector(ldV, CLOTHPARTICLES);
+ filter(ldV, S);
+
+ add_lfvector_lfvector(ldV, ldV, z, numverts);
+
+ // r = B - Mul(tmp,A,X); // just use B if X known to be zero
+ cp_lfvector(r, lB, numverts);
+ mul_bfmatrix_lfvector(tmp, lA, ldV);
+ sub_lfvector_lfvector(r, r, tmp, numverts);
+
+ filter(r,S);
+
+ cp_lfvector(d, r, numverts);
+
+ s = dot_lfvector(r, r, numverts);
+ starget = s * sqrt(conjgrad_epsilon);
+
+ while((s>starget && conjgrad_loopcount < conjgrad_looplimit))
+ {
+ // Mul(q,A,d); // q = A*d;
+ mul_bfmatrix_lfvector(q, lA, d);
+
+ filter(q,S);
+
+ a = s/dot_lfvector(d, q, numverts);
+
+ // X = X + d*a;
+ add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
+
+ // r = r - q*a;
+ sub_lfvector_lfvectorS(r, r, q, a, numverts);
+
+ s_prev = s;
+ s = dot_lfvector(r, r, numverts);
+
+ //d = r+d*(s/s_prev);
+ add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts);
+
+ filter(d,S);
+
+ conjgrad_loopcount++;
+ }
+ conjgrad_lasterror = s;
+
+ del_lfvector(q);
+ del_lfvector(d);
+ del_lfvector(tmp);
+ del_lfvector(r);
+ // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
+
+ return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
+}
+
+// block diagonalizer
+DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+{
+ unsigned int i = 0;
+
+ // Take only the diagonal blocks of A
+// #pragma omp parallel for private(i)
+ for(i = 0; i<lA[0].vcount; i++)
+ {
+ // block diagonalizer
+ cp_fmatrix(P[i].m, lA[i].m);
+ inverse_fmatrix(Pinv[i].m, P[i].m);
+
+ }
+}
+/*
+// version 1.3
+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;
+ float conjgrad_epsilon=0.0001; // 0.2 is dt for steps=5
+ lfVector *r = create_lfvector(numverts);
+ lfVector *p = create_lfvector(numverts);
+ lfVector *s = create_lfvector(numverts);
+ lfVector *h = create_lfvector(numverts);
+
+ BuildPPinv(lA, P, Pinv);
+
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ delta0 = deltaNew * sqrt(conjgrad_epsilon);
+
+ // itstart();
+
+ while ((deltaNew > delta0) && (iterations < conjgrad_looplimit))
+ {
+ iterations++;
+
+ mul_bfmatrix_lfvector(s, lA, p);
+ filter(s, S);
+
+ alpha = deltaNew / dot_lfvector(p, s, numverts);
+
+ add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
+
+ add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
+
+ mul_prevfmatrix_lfvector(h, Pinv, r);
+ filter(h, S);
+
+ deltaOld = deltaNew;
+
+ deltaNew = dot_lfvector(r, h, numverts);
+
+ add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
+
+ filter(p, S);
+
+ }
+
+ // itend();
+ // printf("cg_filtered_pre time: %f\n", (float)itval());
+
+ del_lfvector(h);
+ del_lfvector(s);
+ del_lfvector(p);
+ del_lfvector(r);
+
+ printf("iterations: %d\n", iterations);
+
+ return iterations<conjgrad_looplimit;
+}
+*/
+// version 1.4
+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;
+ lfVector *r = create_lfvector(numverts);
+ lfVector *p = create_lfvector(numverts);
+ lfVector *s = create_lfvector(numverts);
+ lfVector *h = create_lfvector(numverts);
+ lfVector *bhat = create_lfvector(numverts);
+ lfVector *btemp = create_lfvector(numverts);
+
+ BuildPPinv(lA, P, Pinv);
+
+ initdiag_bfmatrix(bigI, I);
+ sub_bfmatrix_Smatrix(bigI, bigI, S);
+
+ // x = Sx_0+(I-S)z
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ // b_hat = S(b-A(I-S)z)
+ mul_bfmatrix_lfvector(r, lA, z);
+ mul_bfmatrix_lfvector(bhat, bigI, r);
+ sub_lfvector_lfvector(bhat, lB, bhat, numverts);
+
+ // r = S(b-Ax)
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ // p = SP^-1r
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ // delta0 = bhat^TP^-1bhat
+ mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
+ delta0 = dot_lfvector(bhat, btemp, numverts);
+
+ // deltaNew = r^TP
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ /*
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ delta0 = deltaNew * sqrt(conjgrad_epsilon);
+ */
+
+ // itstart();
+
+ tol = (0.01*0.2);
+
+ while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit))
+ {
+ iterations++;
+
+ mul_bfmatrix_lfvector(s, lA, p);
+ filter(s, S);
+
+ alpha = deltaNew / dot_lfvector(p, s, numverts);
+
+ add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
+
+ add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
+
+ mul_prevfmatrix_lfvector(h, Pinv, r);
+ filter(h, S);
+
+ deltaOld = deltaNew;
+
+ deltaNew = dot_lfvector(r, h, numverts);
+
+ add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
+
+ filter(p, S);
+
+ }
+
+ // itend();
+ // printf("cg_filtered_pre time: %f\n", (float)itval());
+
+ del_lfvector(btemp);
+ del_lfvector(bhat);
+ del_lfvector(h);
+ del_lfvector(s);
+ del_lfvector(p);
+ del_lfvector(r);
+
+ // printf("iterations: %d\n", iterations);
+
+ return iterations<conjgrad_looplimit;
+}
+
+// outer product is NOT cross product!!!
+DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k)
+{
+ // dir is unit length direction, rest is spring's restlength, k is spring constant.
+ // return (outerprod(dir,dir)*k + (I - outerprod(dir,dir))*(k - ((k*L)/length)));
+ float temp[3][3];
+ float temp1 = k*(1.0 - (L/length));
+
+ mul_fvectorT_fvectorS(temp, extent, extent, 1.0 / dot);
+ sub_fmatrix_fmatrix(to, I, temp);
+ mul_fmatrix_S(to, temp1);
+
+ mul_fvectorT_fvectorS(temp, extent, extent, k/ dot);
+ add_fmatrix_fmatrix(to, to, temp);
+
+ /*
+ mul_fvectorT_fvector(temp, dir, dir);
+ sub_fmatrix_fmatrix(to, I, temp);
+ mul_fmatrix_S(to, k* (1.0f-(L/length)));
+ mul_fmatrix_S(temp, k);
+ add_fmatrix_fmatrix(to, temp, to);
+ */
+}
+
+DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb)
+{
+ // return outerprod(dir,dir)*fbstar_jacobi(length, L, k, cb);
+ mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
+}
+
+DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
+{
+ // derivative of force wrt velocity.
+ mul_fvectorT_fvectorS(to, dir, dir, damping);
+
+}
+
+DO_INLINE void dfdx_spring(float to[3][3], float dir[3],float length,float L,float k)
+{
+ // dir is unit length direction, rest is spring's restlength, k is spring constant.
+ //return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
+ mul_fvectorT_fvector(to, dir, dir);
+ sub_fmatrix_fmatrix(to, I, to);
+ mul_fmatrix_S(to, (((L/length)> 1.0f) ? (1.0f): (L/length)));
+ sub_fmatrix_fmatrix(to, to, I);
+ mul_fmatrix_S(to, -k);
+}
+
+// unused atm
+DO_INLINE void dfdx_damp(float to[3][3], float dir[3],float length,const float vel[3],float rest,float damping)
+{
+ // inner spring damping vel is the relative velocity of the endpoints.
+ // return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest)));
+ mul_fvectorT_fvector(to, dir, dir);
+ sub_fmatrix_fmatrix(to, I, to);
+ mul_fmatrix_S(to, (-damping * -(INPR(dir,vel)/MAX2(length,rest))));
+
+}
+
+DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float time)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts;
+ float extent[3];
+ float length = 0, dot = 0;
+ float dir[3] = {0,0,0};
+ float vel[3];
+ float k = 0.0f;
+ float L = s->restlen;
+ float cb = clmd->sim_parms->structural;
+
+ float nullf[3] = {0,0,0};
+ float stretch_force[3] = {0,0,0};
+ float bending_force[3] = {0,0,0};
+ float damping_force[3] = {0,0,0};
+ float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
+
+ float scaling = 0.0;
+
+ VECCOPY(s->f, nullf);
+ cp_fmatrix(s->dfdx, nulldfdx);
+ cp_fmatrix(s->dfdv, nulldfdx);
+
+ // calculate elonglation
+ VECSUB(extent, X[s->kl], X[s->ij]);
+ VECSUB(vel, V[s->kl], V[s->ij]);
+ dot = INPR(extent, extent);
+ length = sqrt(dot);
+
+ s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
+
+ if(length > ALMOST_ZERO)
+ {
+ /*
+ if(length>L)
+ {
+ if((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
+ && ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
+ {
+ s->flags |= CSPRING_FLAG_DEACTIVATE;
+ return;
+ }
+ }
+ */
+ mul_fvector_S(dir, extent, 1.0f/length);
+ }
+ else
+ {
+ mul_fvector_S(dir, extent, 0.0f);
+ }
+
+ // calculate force of structural + shear springs
+ if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR))
+ {
+ if(length > L) // only on elonglation
+ {
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ k = clmd->sim_parms->structural;
+
+ scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
+
+ k = scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
+
+ // TODO: verify, half verified (couldn't see error)
+ mul_fvector_S(stretch_force, dir, k*(length-L));
+
+ VECADD(s->f, s->f, stretch_force);
+
+ // Ascher & Boxman, p.21: Damping only during elonglation
+ // something wrong with it...
+ mul_fvector_S(damping_force, dir, clmd->sim_parms->Cdis * INPR(vel,dir));
+ VECADD(s->f, s->f, damping_force);
+
+ /* VERIFIED */
+ dfdx_spring(s->dfdx, dir, length, L, k);
+
+ /* VERIFIED */
+ dfdv_damp(s->dfdv, dir, clmd->sim_parms->Cdis);
+
+ }
+ }
+ else if(s->type & CLOTH_SPRING_TYPE_GOAL)
+ {
+ float tvect[3];
+
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ // current_position = xold + t * (newposition - xold)
+ VECSUB(tvect, verts[s->ij].xconst, verts[s->ij].xold);
+ mul_fvector_S(tvect, tvect, time);
+ VECADD(tvect, tvect, verts[s->ij].xold);
+
+ VECSUB(extent, X[s->ij], tvect);
+
+ dot = INPR(extent, extent);
+ length = sqrt(dot);
+
+ k = clmd->sim_parms->goalspring;
+
+ scaling = k + s->stiffness * ABS(clmd->sim_parms->max_struct-k);
+
+ k = verts [s->ij].goal * scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
+
+ VECADDS(s->f, s->f, extent, -k);
+
+ mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01 * INPR(vel,dir));
+ VECADD(s->f, s->f, damping_force);
+
+ // HERE IS THE PROBLEM!!!!
+ // dfdx_spring(s->dfdx, dir, length, 0.0, k);
+ // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)));
+ }
+ else // calculate force of bending springs
+ {
+ if(length < L)
+ {
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ k = clmd->sim_parms->bending;
+
+ scaling = k + s->stiffness * ABS(clmd->sim_parms->max_bend-k);
+ cb = k = scaling / (20.0*(clmd->sim_parms->avg_spring_len + FLT_EPSILON));
+
+ mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
+ VECADD(s->f, s->f, bending_force);
+
+ dfdx_spring_type2(s->dfdx, dir, length,L, k, cb);
+ }
+ }
+}
+
+DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *lF, lfVector *X, lfVector *V, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
+{
+ if(s->flags & CLOTH_SPRING_FLAG_NEEDED)
+ {
+ if(!(s->type & CLOTH_SPRING_TYPE_BENDING))
+ {
+ sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
+ sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
+ add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);
+ }
+
+ VECADD(lF[s->ij], lF[s->ij], s->f);
+
+ if(!(s->type & CLOTH_SPRING_TYPE_GOAL))
+ VECSUB(lF[s->kl], lF[s->kl], s->f);
+
+ sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
+ sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
+ add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx);
+ }
+}
+
+float calculateVertexWindForce(float wind[3], float vertexnormal[3])
+{
+ return sqrt(fabs(INPR(wind, vertexnormal)))*2.0*0.1;
+}
+
+void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
+{
+ /* Collect forces and derivatives: F,dFdX,dFdV */
+ Cloth *cloth = clmd->clothObject;
+ long i = 0;
+ float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
+ float gravity[3];
+ float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
+ MFace *mfaces = cloth->mfaces;
+ ClothVertex *verts = cloth->verts;
+ float wind_normalized[3];
+ unsigned int numverts = cloth->numverts;
+ LinkNode *search = cloth->springs;
+
+
+ VECCOPY(gravity, clmd->sim_parms->gravity);
+ mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
+
+ /* set dFdX jacobi matrix to zero */
+ init_bfmatrix(dFdX, ZERO);
+ /* set dFdX jacobi matrix diagonal entries to -spring_air */
+ initdiag_bfmatrix(dFdV, tm2);
+
+ init_lfvector(lF, gravity, numverts);
+
+ // multiply lF with mass matrix
+ for(i = 0; i < (long)numverts; i++)
+ {
+ float temp[3];
+ VECCOPY(temp, lF[i]);
+ mul_fmatrix_fvector(lF[i], M[i].m, temp);
+ }
+
+ submul_lfvectorS(lF, lV, spring_air, numverts);
+
+ /* handle external forces like wind */
+ if(effectors)
+ {
+ for(i = 0; i < cloth->numfaces; i++)
+ {
+ float vertexnormal[3]={0,0,0};
+ float speed[3] = {0.0f, 0.0f,0.0f};
+ float force[3]= {0.0f, 0.0f, 0.0f};
+
+ if(mfaces[i].v4)
+ CalcNormFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],vertexnormal);
+ else
+ CalcNormFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],vertexnormal);
+
+ pdDoEffectors(effectors, lX[mfaces[i].v1], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ VECCOPY(wind_normalized, speed);
+ Normalize(wind_normalized);
+ VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal) * verts[mfaces[i].v1].mass);
+
+ if(mfaces[i].v4)
+ {
+ VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 0.25);
+ }
+ else
+ {
+ VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 1.0 / 3.0);
+ }
+
+ pdDoEffectors(effectors, lX[mfaces[i].v2], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ VECCOPY(wind_normalized, speed);
+ Normalize(wind_normalized);
+ VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal) * verts[mfaces[i].v2].mass);
+ if(mfaces[i].v4)
+ {
+ VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 0.25);
+ }
+ else
+ {
+ VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 1.0 / 3.0);
+ }
+
+ pdDoEffectors(effectors, lX[mfaces[i].v3], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ VECCOPY(wind_normalized, speed);
+ Normalize(wind_normalized);
+ VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal) * verts[mfaces[i].v3].mass);
+ if(mfaces[i].v4)
+ {
+ VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 0.25);
+ }
+ else
+ {
+ VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 1.0 / 3.0);
+ }
+
+ if(mfaces[i].v4)
+ {
+ pdDoEffectors(effectors, lX[i], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
+ VECCOPY(wind_normalized, speed);
+ Normalize(wind_normalized);
+ VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal) * verts[mfaces[i].v4].mass);
+ VECADDS(lF[i], lF[i], wind_normalized, 0.25);
+ }
+
+ }
+ }
+
+ // calculate spring forces
+ search = cloth->springs;
+ while(search)
+ {
+ // only handle active springs
+ // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)){}
+ cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, time);
+
+ search = search->next;
+ }
+
+ // apply spring forces
+ search = cloth->springs;
+ while(search)
+ {
+ // only handle active springs
+ // if(((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) && !(springs[i].flags & CSPRING_FLAG_DEACTIVATE))|| !(clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED))
+ cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
+ search = search->next;
+ }
+ // 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)
+{
+ unsigned int numverts = dFdV[0].vcount;
+
+ lfVector *dFdXmV = create_lfvector(numverts);
+ zero_lfvector(dV, numverts);
+
+ cp_bfmatrix(A, M);
+
+ subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
+
+ mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
+
+ add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
+
+ itstart();
+
+ cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
+ // cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI);
+
+ itend();
+ // printf("cg_filtered calc time: %f\n", (float)itval());
+
+ cp_lfvector(olddV, dV, numverts);
+
+ // advance velocities
+ add_lfvector_lfvector(Vnew, lV, dV, numverts);
+
+
+ del_lfvector(dFdXmV);
+}
+
+int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
+{
+ unsigned int i=0;
+ float step=0.0f, tf=1.0f;
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts;
+ unsigned int numverts = cloth->numverts;
+ float dt = 1.0f / clmd->sim_parms->stepsPerFrame;
+ Implicit_Data *id = cloth->implicit;
+ int result = 0;
+
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
+ {
+ for(i = 0; i < numverts; i++)
+ {
+ // update velocities with constrained velocities from pinned verts
+ if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ VECSUB(id->V[i], verts[i].xconst, verts[i].xold);
+ // VecMulf(id->V[i], clmd->sim_parms->stepsPerFrame);
+ }
+ }
+ }
+
+ while(step < tf)
+ {
+ // calculate forces
+ effectors= pdInitEffectors(ob,NULL);
+ cloth_calc_force(clmd, 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);
+
+ // advance positions
+ add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
+
+ /* move pinned verts to correct position */
+ for(i = 0; i < numverts; i++)
+ {
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ {
+ if(verts [i].flags & CLOTH_VERT_FLAG_PINNED)
+ {
+ float tvect[3] = {.0,.0,.0};
+ VECSUB(tvect, verts[i].xconst, verts[i].xold);
+ mul_fvector_S(tvect, tvect, step+dt);
+ VECADD(tvect, tvect, verts[i].xold);
+ VECCOPY(id->Xnew[i], tvect);
+ }
+ }
+
+ VECCOPY(verts[i].txold, id->X[i]);
+ }
+
+ if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
+ {
+ // collisions
+ // itstart();
+
+ // update verts to current positions
+ for(i = 0; i < numverts; i++)
+ {
+ VECCOPY(verts[i].tx, id->Xnew[i]);
+
+ VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
+ VECCOPY(verts[i].v, verts[i].tv);
+ }
+
+ // call collision function
+ result = cloth_bvh_objcollision(clmd, step + dt, dt);
+
+ // copy corrected positions back to simulation
+ for(i = 0; i < numverts; i++)
+ {
+ if(result)
+ {
+
+ if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ continue;
+
+ VECCOPY(id->Xnew[i], verts[i].tx);
+ VECCOPY(id->Vnew[i], verts[i].tv);
+ VecMulf(id->Vnew[i], clmd->sim_parms->stepsPerFrame);
+ }
+ }
+
+ // X = Xnew;
+ cp_lfvector(id->X, id->Xnew, numverts);
+
+ // if there were collisions, advance the velocity from v_n+1/2 to v_n+1
+
+ if(result)
+ {
+ // V = Vnew;
+ cp_lfvector(id->V, id->Vnew, numverts);
+
+ // calculate
+ effectors= pdInitEffectors(ob,NULL);
+ cloth_calc_force(clmd, 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);
+ }
+
+ }
+ else
+ {
+ // X = Xnew;
+ cp_lfvector(id->X, id->Xnew, numverts);
+ }
+
+ // itend();
+ // printf("collision time: %f\n", (float)itval());
+
+ // V = Vnew;
+ cp_lfvector(id->V, id->Vnew, numverts);
+
+ step += dt;
+
+ }
+
+ for(i = 0; i < numverts; i++)
+ {
+ if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ {
+ VECCOPY(verts[i].txold, verts[i].xconst); // TODO: test --> should be .x
+ VECCOPY(verts[i].x, verts[i].xconst);
+ VECCOPY(verts[i].v, id->V[i]);
+ }
+ else
+ {
+ VECCOPY(verts[i].txold, id->X[i]);
+ VECCOPY(verts[i].x, id->X[i]);
+ VECCOPY(verts[i].v, id->V[i]);
+ }
+ }
+
+ return 1;
+}
+
+void implicit_set_positions (ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts;
+ unsigned int numverts = cloth->numverts, i;
+ Implicit_Data *id = cloth->implicit;
+
+ for(i = 0; i < numverts; i++)
+ {
+ VECCOPY(id->X[i], verts[i].x);
+ VECCOPY(id->V[i], verts[i].v);
+ }
+ if(G.rt > 0)
+ printf("implicit_set_positions\n");
+}
+
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 08924ac96d5..4af310913d6 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -52,6 +52,7 @@
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
@@ -85,7 +86,7 @@
*/
int co_ar[CO_TOTIPO]= {
- CO_ENFORCE
+ CO_ENFORCE, CO_HEADTAIL
};
int ob_ar[OB_TOTIPO]= {
@@ -93,7 +94,7 @@ int ob_ar[OB_TOTIPO]= {
OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z,
OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z,
OB_LAY, OB_TIME, OB_COL_R, OB_COL_G, OB_COL_B, OB_COL_A,
- OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM
+ OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM, OB_PD_FMAXD
};
int ac_ar[AC_TOTIPO]= {
@@ -180,6 +181,12 @@ int fluidsim_ar[FLUIDSIM_TOTIPO]= {
FLUIDSIM_ACTIVE
};
+int part_ar[PART_TOTIPO]= {
+ PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
+ PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
+ PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
+ PART_BB_TILT
+};
float frame_to_float(int cfra) /* see also bsystem_time in object.c */
@@ -523,9 +530,9 @@ void testhandles_ipocurve(IpoCurve *icu)
a= icu->totvert;
while(a--) {
flag= 0;
- if(bezt->f1 & 1) flag++;
- if(bezt->f2 & 1) flag += 2;
- if(bezt->f3 & 1) flag += 4;
+ if(bezt->f1 & SELECT) flag++;
+ if(bezt->f2 & SELECT) flag += 2;
+ if(bezt->f3 & SELECT) flag += 4;
if( !(flag==0 || flag==7) ) {
if(bezt->h1==HD_AUTO) { /* auto */
@@ -751,6 +758,49 @@ void berekenx(float *f, float *o, int b)
}
}
+/* we need the local transform = current transform - (parent transform + bone transform) */
+/* (local transform is on action channel level) */
+static void posechannel_get_local_transform(bPoseChannel *pchan, float *loc, float *eul, float *size)
+{
+ float diff_mat[4][4];
+ float parmat[4][4], offs_bone[4][4], imat[4][4];
+
+ if (pchan->parent) {
+ /* get first the parent + bone transform in parmat */
+
+ /* bone transform itself */
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ /* The bone's root offset (is in the parent's coordinate system) */
+ VECCOPY(offs_bone[3], pchan->bone->head);
+ /* Get the length translation of parent (length along y axis) */
+ offs_bone[3][1]+= pchan->parent->bone->length;
+
+ Mat4MulSerie(parmat, pchan->parent->pose_mat, offs_bone, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ /* invert it */
+ Mat4Invert(imat, parmat);
+ }
+ else {
+ Mat4CpyMat3(offs_bone, pchan->bone->bone_mat);
+ VECCOPY(offs_bone[3], pchan->bone->head);
+
+ /* invert it */
+ Mat4Invert(imat, offs_bone);
+
+ }
+
+ /* difference: current transform - (parent transform + bone transform) */
+ Mat4MulMat4(diff_mat, pchan->pose_mat, imat);
+
+ if(loc)
+ VECCOPY(loc, diff_mat[3]);
+ if(eul)
+ Mat4ToEul(diff_mat, eul);
+ if(size)
+ Mat4ToSize(diff_mat, size);
+
+}
+
/* has to return a float value */
static float eval_driver(IpoDriver *driver, float ipotime)
{
@@ -802,48 +852,49 @@ static float eval_driver(IpoDriver *driver, float ipotime)
else { /* ID_AR */
bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
if(pchan && pchan->bone) {
- float pose_mat[3][3];
- float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
- float eul[3], size[3];
- /* we need the local transform = current transform - (parent transform + bone transform) */
-
- Mat3CpyMat4(pose_mat, pchan->pose_mat);
-
- if (pchan->parent) {
- Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
- Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
-
- Mat3Inv(ipar_mat, diff_mat);
+ /* rotation difference is not a simple driver (i.e. value drives value), but the angle between 2 bones is driving stuff... which is useful */
+ if(driver->adrcode==OB_ROT_DIFF) {
+ bPoseChannel *pchan2= get_pose_channel(ob->pose, driver->name+DRIVER_NAME_OFFS);
+ if(pchan2 && pchan2->bone) {
+ float q1[4], q2[4], quat[4], angle;
+
+ Mat4ToQuat(pchan->pose_mat, q1);
+ Mat4ToQuat(pchan2->pose_mat, q2);
+
+ QuatInv(q1);
+ QuatMul(quat, q1, q2);
+ angle = 2.0f * (saacos(quat[0]));
+ angle= ABS(angle);
+
+ return angle>M_PI?2.0f*M_PI-angle:angle;
+ }
}
else {
- Mat3Inv(ipar_mat, pchan->bone->bone_mat);
- }
-
- Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
-
- Mat3ToEul(diff_mat, eul);
- Mat3ToSize(diff_mat, size);
-
- switch(driver->adrcode) {
- case OB_LOC_X:
- return pchan->loc[0];
- case OB_LOC_Y:
- return pchan->loc[1];
- case OB_LOC_Z:
- return pchan->loc[2];
- case OB_ROT_X:
- return eul[0]/(M_PI_2/9.0);
- case OB_ROT_Y:
- return eul[1]/(M_PI_2/9.0);
- case OB_ROT_Z:
- return eul[2]/(M_PI_2/9.0);
- case OB_SIZE_X:
- return size[0];
- case OB_SIZE_Y:
- return size[1];
- case OB_SIZE_Z:
- return size[2];
+ float loc[3], eul[3], size[3];
+
+ posechannel_get_local_transform(pchan, loc, eul, size);
+
+ switch(driver->adrcode) {
+ case OB_LOC_X:
+ return loc[0];
+ case OB_LOC_Y:
+ return loc[1];
+ case OB_LOC_Z:
+ return loc[2];
+ case OB_ROT_X:
+ return eul[0]/(M_PI_2/9.0);
+ case OB_ROT_Y:
+ return eul[1]/(M_PI_2/9.0);
+ case OB_ROT_Z:
+ return eul[2]/(M_PI_2/9.0);
+ case OB_SIZE_X:
+ return size[0];
+ case OB_SIZE_Y:
+ return size[1];
+ case OB_SIZE_Z:
+ return size[2];
+ }
}
}
}
@@ -995,10 +1046,13 @@ void calc_ipo(Ipo *ipo, float ctime)
IpoCurve *icu;
if(ipo==NULL) return;
+ if(ipo->muteipo) return;
for(icu= ipo->curve.first; icu; icu= icu->next) {
- if(icu->driver || (icu->flag & IPO_LOCK)==0)
- calc_icu(icu, ctime);
+ if(icu->driver || (icu->flag & IPO_LOCK)==0) {
+ if((icu->flag & IPO_MUTE)==0)
+ calc_icu(icu, ctime);
+ }
}
}
@@ -1185,6 +1239,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
Lamp *la;
Sequence *seq;
World *wo;
+ ParticleSettings *part;
*type= IPO_FLOAT;
@@ -1262,6 +1317,9 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
case OB_PD_PERM:
if(ob->pd) poin= &(ob->pd->pdef_perm);
break;
+ case OB_PD_FMAXD:
+ if(ob->pd) poin= &(ob->pd->maxdist);
+ break;
}
}
else if( GS(id->name)==ID_MA) {
@@ -1514,13 +1572,54 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(snd->attenuation); break;
}
}
-
+ else if( GS(id->name)==ID_PA) {
+
+ part= (ParticleSettings *)id;
+
+ switch(icu->adrcode) {
+ case PART_EMIT_FREQ:
+ case PART_EMIT_LIFE:
+ case PART_EMIT_VEL:
+ case PART_EMIT_AVE:
+ case PART_EMIT_SIZE:
+ poin= NULL; break;
+ case PART_CLUMP:
+ poin= &(part->clumpfac); break;
+ case PART_AVE:
+ poin= &(part->avefac); break;
+ case PART_SIZE:
+ poin= &(part->size); break;
+ case PART_DRAG:
+ poin= &(part->dragfac); break;
+ case PART_BROWN:
+ poin= &(part->brownfac); break;
+ case PART_DAMP:
+ poin= &(part->dampfac); break;
+ case PART_LENGTH:
+ poin= &(part->length); break;
+ case PART_GRAV_X:
+ poin= &(part->acc[0]); break;
+ case PART_GRAV_Y:
+ poin= &(part->acc[1]); break;
+ case PART_GRAV_Z:
+ poin= &(part->acc[2]); break;
+ case PART_KINK_AMP:
+ poin= &(part->kink_amp); break;
+ case PART_KINK_FREQ:
+ poin= &(part->kink_freq); break;
+ case PART_KINK_SHAPE:
+ poin= &(part->kink_shape); break;
+ case PART_BB_TILT:
+ poin= &(part->bb_tilt); break;
+ }
+ }
+
return poin;
}
void set_icu_vars(IpoCurve *icu)
{
-
+ /* defaults. 0.0 for y-extents makes these ignored */
icu->ymin= icu->ymax= 0.0;
icu->ipo= IPO_BEZ;
@@ -1809,6 +1908,37 @@ void set_icu_vars(IpoCurve *icu)
break;
}
}
+ else if(icu->blocktype==ID_PA){
+
+ switch(icu->adrcode) {
+ case PART_EMIT_LIFE:
+ case PART_SIZE:
+ case PART_KINK_FREQ:
+ case PART_EMIT_VEL:
+ case PART_EMIT_AVE:
+ case PART_EMIT_SIZE:
+ icu->ymin= 0.0;
+ break;
+ case PART_CLUMP:
+ case PART_DRAG:
+ case PART_DAMP:
+ case PART_LENGTH:
+ icu->ymin= 0.0;
+ icu->ymax= 1.0;
+ break;
+ case PART_KINK_SHAPE:
+ icu->ymin= -0.999;
+ icu->ymax= 0.999;
+ }
+ }
+ else if(icu->blocktype==ID_CO) {
+ icu->ymin= 0.0;
+ icu->ymax= 1.0f;
+ }
+
+ /* by default, slider limits will be icu->ymin and icu->ymax */
+ icu->slide_min= icu->ymin;
+ icu->slide_max= icu->ymax;
}
/* not for actions or constraints! */
@@ -1997,7 +2127,7 @@ void do_ob_ipo(Object *ob)
/* do not set ob->ctime here: for example when parent in invisible layer */
- ctime= bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(ob, (float) G.scene->r.cfra, 0.0);
calc_ipo(ob->ipo, ctime);
@@ -2031,7 +2161,7 @@ void do_ob_ipodrivers(Object *ob, Ipo *ipo, float ctime)
}
}
-void do_seq_ipo(Sequence *seq)
+void do_seq_ipo(Sequence *seq, int cfra)
{
float ctime, div;
@@ -2039,11 +2169,10 @@ void do_seq_ipo(Sequence *seq)
if(seq->ipo) {
if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
- ctime = frame_to_float(G.scene->r.cfra);
+ ctime = frame_to_float(cfra);
div = 1.0;
} else {
- ctime= frame_to_float(G.scene->r.cfra
- - seq->startdisp);
+ ctime= frame_to_float(cfra - seq->startdisp);
div= (seq->enddisp - seq->startdisp)/100.0f;
if(div==0.0) return;
}
@@ -2161,7 +2290,7 @@ void do_all_data_ipos()
|| seq->type == SEQ_HD_SOUND) && (seq->ipo) &&
(seq->startdisp<=G.scene->r.cfra+2) &&
(seq->enddisp>G.scene->r.cfra))
- do_seq_ipo(seq);
+ do_seq_ipo(seq, G.scene->r.cfra);
seq= seq->next;
}
}
@@ -2219,7 +2348,7 @@ void add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
if( ce->cfra==bezt->vec[1][0] ) {
/* do because of double keys */
- if(bezt->f2 & 1) ce->sel= bezt->f2;
+ if(bezt->f2 & SELECT) ce->sel= bezt->f2;
return;
}
else if(ce->cfra > bezt->vec[1][0]) break;
@@ -2271,6 +2400,7 @@ void make_cfra_list(Ipo *ipo, ListBase *elems)
case OB_PD_SDAMP:
case OB_PD_RDAMP:
case OB_PD_PERM:
+ case OB_PD_FMAXD:
bezt= icu->bezt;
if(bezt) {
a= icu->totvert;
diff --git a/source/blender/blenkernel/intern/kdop.c b/source/blender/blenkernel/intern/kdop.c
new file mode 100644
index 00000000000..06525449bf4
--- /dev/null
+++ b/source/blender/blenkernel/intern/kdop.c
@@ -0,0 +1,862 @@
+/* kdop.c
+*
+*
+* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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) Blender Foundation
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "MEM_guardedalloc.h"
+/* types */
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_cloth_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_modifier_types.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_edgehash.h"
+#include "BLI_linklist.h"
+#include "BKE_curve.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_cloth.h"
+#include "BKE_modifier.h"
+#include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
+#include "BIF_editdeform.h"
+#include "BIF_editkey.h"
+#include "DNA_screen_types.h"
+#include "BSE_headerbuttons.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "mydevice.h"
+
+#include "BKE_utildefines.h"
+
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+// Additional fastened appending function
+// It uses the link to the last inserted node as start value
+// for searching the end of the list
+// NEW: in compare to the original function, this one returns
+// the reference to the last inserted node
+////////////////////////////////////////////////////////////////////////
+LinkNode *BLI_linklist_append_fast(LinkNode **listp, void *ptr) {
+ LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink");
+ LinkNode *node = *listp;
+
+ nlink->link = ptr;
+ nlink->next = NULL;
+
+ if(node == NULL){
+ *listp = nlink;
+ } else {
+ while(node->next != NULL){
+ node = node->next;
+ }
+ node->next = nlink;
+ }
+ return nlink;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Bounding Volume Hierarchy Definition
+//
+// Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below
+// Notes: You have to choose the type at compile time ITM
+// Notes: You can choose the tree type --> binary, quad, octree, choose below
+////////////////////////////////////////////////////////////////////////
+
+static float KDOP_AXES[13][3] =
+{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 1}, {1, -1, 1}, {1, 1, -1},
+{1, -1, -1}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {1, -1, 0}, {1, 0, -1},
+{0, 1, -1}
+};
+
+///////////// choose bounding volume here! /////////////
+
+#define KDOP_26
+
+
+
+#ifdef KDOP_26
+#define KDOP_END 13
+#define KDOP_START 0
+#endif
+
+#ifdef KDOP_18
+#define KDOP_END 13
+#define KDOP_START 7
+#endif
+
+#ifdef KDOP_14
+#define KDOP_END 7
+#define KDOP_START 0
+#endif
+
+// this is basicly some AABB
+#ifdef KDOP_8
+#define KDOP_END 4
+#define KDOP_START 0
+#endif
+
+// this is basicly some OBB
+#ifdef KDOP_6
+#define KDOP_END 3
+#define KDOP_START 0
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+// Introsort
+// with permission deriven from the following Java code:
+// http://ralphunden.net/content/tutorials/a-guide-to-introsort/
+// and he derived it from the SUN STL
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+static int size_threshold = 16;
+/*
+* Common methods for all algorithms
+*/
+DO_INLINE void bvh_exchange(CollisionTree **a, int i, int j)
+{
+ CollisionTree *t=a[i];
+ a[i]=a[j];
+ a[j]=t;
+}
+DO_INLINE int floor_lg(int a)
+{
+ return (int)(floor(log(a)/log(2)));
+}
+
+/*
+* Insertion sort algorithm
+*/
+static void bvh_insertionsort(CollisionTree **a, int lo, int hi, int axis)
+{
+ int i,j;
+ CollisionTree *t;
+ for (i=lo; i < hi; i++)
+ {
+ j=i;
+ t = a[i];
+ while((j!=lo) && (t->bv[axis] < (a[j-1])->bv[axis]))
+ {
+ a[j] = a[j-1];
+ j--;
+ }
+ a[j] = t;
+ }
+}
+
+static int bvh_partition(CollisionTree **a, int lo, int hi, CollisionTree * x, int axis)
+{
+ int i=lo, j=hi;
+ while (1)
+ {
+ while ((a[i])->bv[axis] < x->bv[axis]) i++;
+ j=j-1;
+ while (x->bv[axis] < (a[j])->bv[axis]) j=j-1;
+ if(!(i < j))
+ return i;
+ bvh_exchange(a, i,j);
+ i++;
+ }
+}
+
+/*
+* Heapsort algorithm
+*/
+static void bvh_downheap(CollisionTree **a, int i, int n, int lo, int axis)
+{
+ CollisionTree * d = a[lo+i-1];
+ int child;
+ while (i<=n/2)
+ {
+ child = 2*i;
+ if ((child < n) && ((a[lo+child-1])->bv[axis] < (a[lo+child])->bv[axis]))
+ {
+ child++;
+ }
+ if (!(d->bv[axis] < (a[lo+child-1])->bv[axis])) break;
+ a[lo+i-1] = a[lo+child-1];
+ i = child;
+ }
+ a[lo+i-1] = d;
+}
+
+static void bvh_heapsort(CollisionTree **a, int lo, int hi, int axis)
+{
+ int n = hi-lo, i;
+ for (i=n/2; i>=1; i=i-1)
+ {
+ bvh_downheap(a, i,n,lo, axis);
+ }
+ for (i=n; i>1; i=i-1)
+ {
+ bvh_exchange(a, lo,lo+i-1);
+ bvh_downheap(a, 1,i-1,lo, axis);
+ }
+}
+
+static CollisionTree *bvh_medianof3(CollisionTree **a, int lo, int mid, int hi, int axis) // returns Sortable
+{
+ if ((a[mid])->bv[axis] < (a[lo])->bv[axis])
+ {
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis])
+ return a[mid];
+ else
+ {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis])
+ return a[hi];
+ else
+ return a[lo];
+ }
+ }
+ else
+ {
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis])
+ {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis])
+ return a[lo];
+ else
+ return a[hi];
+ }
+ else
+ return a[mid];
+ }
+}
+/*
+* Quicksort algorithm modified for Introsort
+*/
+static void bvh_introsort_loop (CollisionTree **a, int lo, int hi, int depth_limit, int axis)
+{
+ int p;
+
+ while (hi-lo > size_threshold)
+ {
+ if (depth_limit == 0)
+ {
+ bvh_heapsort(a, lo, hi, axis);
+ return;
+ }
+ depth_limit=depth_limit-1;
+ p=bvh_partition(a, lo, hi, bvh_medianof3(a, lo, lo+((hi-lo)/2)+1, hi-1, axis), axis);
+ bvh_introsort_loop(a, p, hi, depth_limit, axis);
+ hi=p;
+ }
+}
+
+DO_INLINE void bvh_sort(CollisionTree **a0, int begin, int end, int axis)
+{
+ if (begin < end)
+ {
+ CollisionTree **a=a0;
+ bvh_introsort_loop(a, begin, end, 2*floor_lg(end-begin), axis);
+ bvh_insertionsort(a, begin, end, axis);
+ }
+}
+DO_INLINE void bvh_sort_along_axis(CollisionTree **face_list, int start, int end, int axis)
+{
+ bvh_sort(face_list, start, end, axis);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////
+void bvh_free(BVH * bvh)
+{
+ LinkNode *search = NULL;
+ CollisionTree *tree = NULL;
+
+ if (bvh)
+ {
+
+ search = bvh->tree;
+
+ while(search)
+ {
+ LinkNode *next= search->next;
+ tree = search->link;
+
+ MEM_freeN(tree);
+
+ search = next;
+ }
+
+ BLI_linklist_free(bvh->tree,NULL);
+ bvh->tree = NULL;
+
+ if(bvh->current_x)
+ MEM_freeN(bvh->current_x);
+ if(bvh->current_xold)
+ MEM_freeN(bvh->current_xold);
+
+ MEM_freeN(bvh);
+ bvh = NULL;
+ }
+}
+
+// only supports x,y,z axis in the moment
+// but we should use a plain and simple function here for speed sake
+DO_INLINE int bvh_largest_axis(float *bv)
+{
+ float middle_point[3];
+
+ middle_point[0] = (bv[1]) - (bv[0]); // x axis
+ middle_point[1] = (bv[3]) - (bv[2]); // y axis
+ middle_point[2] = (bv[5]) - (bv[4]); // z axis
+ if (middle_point[0] > middle_point[1])
+ {
+ if (middle_point[0] > middle_point[2])
+ return 1; // max x axis
+ else
+ return 5; // max z axis
+ }
+ else
+ {
+ if (middle_point[1] > middle_point[2])
+ return 3; // max y axis
+ else
+ return 5; // max z axis
+ }
+}
+
+// depends on the fact that the BVH's for each face is already build
+DO_INLINE void bvh_calc_DOP_hull_from_faces(BVH * bvh, CollisionTree **tri, int numfaces, float *bv)
+{
+ float newmin,newmax;
+ int i, j;
+ for (j = 0; j < numfaces; j++)
+ {
+ // for all Axes.
+ for (i = KDOP_START; i < KDOP_END; i++)
+ {
+ newmin = (tri [j])->bv[(2 * i)];
+ if ((newmin < bv[(2 * i)]) || (j == 0))
+ {
+ bv[(2 * i)] = newmin;
+ }
+
+ newmax = (tri [j])->bv[(2 * i) + 1];
+ if ((newmax > bv[(2 * i) + 1]) || (j == 0))
+ {
+ bv[(2 * i) + 1] = newmax;
+ }
+ }
+ }
+}
+
+DO_INLINE void bvh_calc_DOP_hull_static(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree)
+{
+ MFace *tempMFace = bvh->mfaces;
+ float *tempBV = bv;
+ float newminmax;
+ int i, j, k;
+
+ for (j = 0; j < numfaces; j++)
+ {
+ tempMFace = bvh->mfaces + (tri [j])->tri_index;
+ // 3 or 4 vertices per face.
+ for (k = 0; k < 4; k++)
+ {
+ int temp = 0;
+ // If this is a triangle.
+ if (k == 3 && !tempMFace->v4)
+ continue;
+ // TODO: other name for "temp" this gets all vertices of a face
+ if (k == 0)
+ temp = tempMFace->v1;
+ else if (k == 1)
+ temp = tempMFace->v2;
+ else if (k == 2)
+ temp = tempMFace->v3;
+ else if (k == 3)
+ temp = tempMFace->v4;
+ // for all Axes.
+ for (i = KDOP_START; i < KDOP_END; i++)
+ {
+ newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
+ if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
+ tempBV[(2 * i)] = newminmax;
+ if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
+ tempBV[(2 * i) + 1] = newminmax;
+ }
+ }
+
+ /* calculate normal of this face */
+ /* (code copied from cdderivedmesh.c) */
+ if(tempMFace->v4)
+ CalcNormFloat4(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co,
+ bvh->current_xold[tempMFace->v3].co, bvh->current_xold[tempMFace->v4].co, tree->normal);
+ else
+ CalcNormFloat(bvh->current_xold[tempMFace->v1].co, bvh->current_xold[tempMFace->v2].co,
+ bvh->current_xold[tempMFace->v3].co, tree->normal);
+
+ tree->alpha = 0;
+
+
+ }
+}
+
+DO_INLINE void bvh_calc_DOP_hull_moving(BVH * bvh, CollisionTree **tri, int numfaces, float *bv, CollisionTree *tree)
+{
+ MFace *tempMFace = bvh->mfaces;
+ float *tempBV = bv;
+ float newminmax;
+ int i, j, k;
+
+ /* TODO: calculate normals */
+
+ for (j = 0; j < numfaces; j++)
+ {
+ tempMFace = bvh->mfaces + (tri [j])->tri_index;
+ // 3 or 4 vertices per face.
+ for (k = 0; k < 4; k++)
+ {
+ int temp = 0;
+ // If this is a triangle.
+ if (k == 3 && !tempMFace->v4)
+ continue;
+ // TODO: other name for "temp" this gets all vertices of a face
+ if (k == 0)
+ temp = tempMFace->v1;
+ else if (k == 1)
+ temp = tempMFace->v2;
+ else if (k == 2)
+ temp = tempMFace->v3;
+ else if (k == 3)
+ temp = tempMFace->v4;
+ // for all Axes.
+ for (i = KDOP_START; i < KDOP_END; i++)
+ {
+ newminmax = INPR(bvh->current_xold[temp].co, KDOP_AXES[i]);
+ if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
+ tempBV[(2 * i)] = newminmax;
+ if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
+ tempBV[(2 * i) + 1] = newminmax;
+
+ newminmax = INPR(bvh->current_x[temp].co, KDOP_AXES[i]);
+ if ((newminmax < tempBV[(2 * i)]) || (k == 0 && j == 0))
+ tempBV[(2 * i)] = newminmax;
+ if ((newminmax > tempBV[(2 * i) + 1])|| (k == 0 && j == 0))
+ tempBV[(2 * i) + 1] = newminmax;
+ }
+ }
+ }
+}
+
+static void bvh_div_env_node(BVH *bvh, CollisionTree *tree, CollisionTree **face_list, unsigned int start, unsigned int end, int lastaxis, LinkNode *nlink)
+{
+ int i = 0;
+ CollisionTree *newtree = NULL;
+ int laxis = 0, max_nodes=4;
+ unsigned int tstart, tend;
+ LinkNode *nlink1 = nlink;
+ LinkNode *tnlink;
+ tree->traversed = 0;
+ // Determine which axis to split along
+ laxis = bvh_largest_axis(tree->bv);
+
+ // Sort along longest axis
+ if(laxis!=lastaxis)
+ bvh_sort_along_axis(face_list, start, end, laxis);
+
+ max_nodes = MIN2((end-start + 1 ),4);
+
+ for (i = 0; i < max_nodes; i++)
+ {
+ tree->count_nodes++;
+
+ if(end-start > 4)
+ {
+ int quarter = ((float)((float)(end - start + 1) / 4.0f));
+ tstart = start + i * quarter;
+ tend = tstart + quarter - 1;
+
+ // be sure that we get all faces
+ if(i==3)
+ {
+ tend = end;
+ }
+ }
+ else
+ {
+ tend = tstart = start + i;
+ }
+
+ // Build tree until 4 node left.
+ if ((tend-tstart + 1 ) > 1)
+ {
+ newtree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
+ tnlink = BLI_linklist_append_fast(&nlink1->next, newtree);
+
+ newtree->nodes[0] = newtree->nodes[1] = newtree->nodes[2] = newtree->nodes[3] = NULL;
+ newtree->count_nodes = 0;
+ newtree->parent = tree;
+ newtree->isleaf = 0;
+
+ tree->nodes[i] = newtree;
+
+ nlink1 = tnlink;
+
+ bvh_calc_DOP_hull_from_faces(bvh, &face_list[tstart], tend-tstart + 1, tree->nodes[i]->bv);
+
+ bvh_div_env_node(bvh, tree->nodes[i], face_list, tstart, tend, laxis, nlink1);
+ }
+ else // ok, we have 1 left for this node
+ {
+ CollisionTree *tnode = face_list[tstart];
+ tree->nodes[i] = tnode;
+ tree->nodes[i]->parent = tree;
+ }
+ }
+ return;
+}
+
+/* function cannot be directly called - needs alloced bvh */
+void bvh_build (BVH *bvh)
+{
+ unsigned int i = 0, j = 0, k = 0;
+ CollisionTree **face_list=NULL;
+ CollisionTree *tree=NULL;
+ LinkNode *nlink = NULL;
+
+ tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
+ // TODO: check succesfull alloc
+ BLI_linklist_append(&bvh->tree, tree);
+
+ nlink = bvh->tree;
+
+ if (tree == NULL)
+ {
+ printf("bvh_build: Out of memory for nodes.\n");
+ bvh_free(bvh);
+ return;
+ }
+ bvh->root = bvh->tree->link;
+ bvh->root->isleaf = 0;
+ bvh->root->parent = NULL;
+ bvh->root->nodes[0] = bvh->root->nodes[1] = bvh->root->nodes[1] = bvh->root->nodes[3] = NULL;
+
+ if(bvh->numfaces<=1)
+ {
+ bvh->root->tri_index = 0; // Why that? --> only one face there
+ bvh->root->isleaf = 1;
+ bvh->root->traversed = 0;
+ bvh->root->count_nodes = 0;
+ bvh->leaf_root = bvh->root;
+ bvh->leaf_tree = bvh->root;
+ bvh->root->nextLeaf = NULL;
+ bvh->root->prevLeaf = NULL;
+ }
+ else
+ {
+ // create face boxes
+ face_list = MEM_callocN (bvh->numfaces * sizeof (CollisionTree *), "CollisionTree");
+ if (face_list == NULL)
+ {
+ printf("bvh_build: Out of memory for face_list.\n");
+ bvh_free(bvh);
+ return;
+ }
+
+ // create face boxes
+ for(i = 0, k = 0; i < bvh->numfaces; i++)
+ {
+ LinkNode *tnlink;
+
+ tree = (CollisionTree *)MEM_callocN(sizeof(CollisionTree), "CollisionTree");
+ // TODO: check succesfull alloc
+
+ tnlink = BLI_linklist_append_fast(&nlink->next, tree);
+
+ face_list[i] = tree;
+ tree->tri_index = i;
+ tree->isleaf = 1;
+ tree->nextLeaf = NULL;
+ tree->prevLeaf = bvh->leaf_tree;
+ tree->parent = NULL;
+ tree->count_nodes = 0;
+
+ if(i==0)
+ {
+ bvh->leaf_tree = bvh->leaf_root = tree;
+ }
+ else
+ {
+ bvh->leaf_tree->nextLeaf = tree;
+ bvh->leaf_tree = bvh->leaf_tree->nextLeaf;
+ }
+
+ tree->nodes[0] = tree->nodes[1] = tree->nodes[2] = tree->nodes[3] = NULL;
+
+ bvh_calc_DOP_hull_static(bvh, &face_list[i], 1, tree->bv, tree);
+
+ // inflate the bv with some epsilon
+ for (j = KDOP_START; j < KDOP_END; j++)
+ {
+ tree->bv[(2 * j)] -= bvh->epsilon; // minimum
+ tree->bv[(2 * j) + 1] += bvh->epsilon; // maximum
+ }
+
+ nlink = tnlink;
+ }
+
+ // build root bvh
+ bvh_calc_DOP_hull_from_faces(bvh, face_list, bvh->numfaces, bvh->root->bv);
+
+ // This is the traversal function.
+ bvh_div_env_node(bvh, bvh->root, face_list, 0, bvh->numfaces-1, 0, nlink);
+ if (face_list)
+ MEM_freeN(face_list);
+
+ }
+
+}
+
+// bvh_overlap - is it possbile for 2 bv's to collide ?
+DO_INLINE int bvh_overlap(float *bv1, float *bv2)
+{
+ int i = 0;
+ for (i = KDOP_START; i < KDOP_END; i++)
+ {
+ // Minimum test.
+ if (bv1[(2 * i)] > bv2[(2 * i) + 1])
+ {
+ return 0;
+ }
+ // Maxiumum test.
+ if (bv2[(2 * i)] > bv1[(2 * i) + 1])
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+// bvh_overlap_self - is it possbile for 2 bv's to selfcollide ?
+DO_INLINE int bvh_overlap_self(CollisionTree * tree1, CollisionTree * tree2)
+{
+ // printf("overlap: %f, q: %f\n", (saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha), saacos(INPR(tree1->normal, tree2->normal)));
+
+ if((saacos(INPR(tree1->normal, tree2->normal)) / 2.0)+MAX2(tree1->alpha, tree2->alpha) > M_PI)
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/**
+ * bvh_traverse - traverse two bvh trees looking for potential collisions.
+ *
+ * max collisions are n*n collisions --> every triangle collide with
+ * every other triangle that doesn't require any realloc, but uses
+ * much memory
+ */
+int bvh_traverse ( ModifierData * md1, ModifierData * md2, CollisionTree * tree1, CollisionTree * tree2, float step, CM_COLLISION_RESPONSE collision_response, int selfcollision)
+{
+ int i = 0, ret=0, overlap = 0;
+
+ /*
+ // Shouldn't be possible
+ if(!tree1 || !tree2)
+ {
+ printf("Error: no tree there\n");
+ return 0;
+}
+ */
+
+ if(selfcollision)
+ overlap = bvh_overlap_self(tree1, tree2);
+ else
+ overlap = bvh_overlap(tree1->bv, tree2->bv);
+
+ if (overlap)
+ {
+ // Check if this node in the first tree is a leaf
+ if (tree1->isleaf)
+ {
+ // Check if this node in the second tree a leaf
+ if (tree2->isleaf)
+ {
+ // Provide the collision response.
+
+ if(collision_response)
+ collision_response (md1, md2, tree1, tree2);
+ return 1;
+ }
+ else
+ {
+ // Process the quad tree.
+ for (i = 0; i < 4; i++)
+ {
+ // Only traverse nodes that exist.
+ if (tree2->nodes[i] && bvh_traverse (md1, md2, tree1, tree2->nodes[i], step, collision_response, selfcollision))
+ ret = 1;
+ }
+ }
+ }
+ else
+ {
+ // Process the quad tree.
+ for (i = 0; i < 4; i++)
+ {
+ // Only traverse nodes that exist.
+ if (tree1->nodes [i] && bvh_traverse (md1, md2, tree1->nodes[i], tree2, step, collision_response, selfcollision))
+ ret = 1;
+ }
+ }
+ }
+
+ return ret;
+}
+// bottom up update of bvh tree:
+// join the 4 children here
+void bvh_join(CollisionTree *tree)
+{
+ int i = 0, j = 0;
+ float max = 0;
+
+ if (!tree)
+ return;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (tree->nodes[i])
+ {
+ for (j = KDOP_START; j < KDOP_END; j++)
+ {
+ // update minimum
+ if ((tree->nodes[i]->bv[(2 * j)] < tree->bv[(2 * j)]) || (i == 0))
+ {
+ tree->bv[(2 * j)] = tree->nodes[i]->bv[(2 * j)];
+ }
+ // update maximum
+ if ((tree->nodes[i]->bv[(2 * j) + 1] > tree->bv[(2 * j) + 1])|| (i == 0))
+ {
+ tree->bv[(2 * j) + 1] = tree->nodes[i]->bv[(2 * j) + 1];
+ }
+ }
+
+ /* for selfcollisions */
+ if(!i)
+ {
+ tree->alpha = tree->nodes[i]->alpha;
+ VECCOPY(tree->normal, tree->nodes[i]->normal);
+ }
+ else
+ {
+ tree->alpha += saacos(INPR(tree->normal, tree->nodes[i]->normal)) / 2.0;
+ VECADD(tree->normal, tree->normal, tree->nodes[i]->normal);
+ VecMulf(tree->normal, 0.5);
+ max = MAX2(max, tree->nodes[i]->alpha);
+ }
+
+ }
+ else
+ break;
+ }
+
+ tree->alpha += max;
+}
+
+// update static bvh
+/* you have to update the bvh position before calling this function */
+void bvh_update(BVH * bvh, int moving)
+{
+ CollisionTree *leaf, *parent;
+ int traversecheck = 1; // if this is zero we don't go further
+ unsigned int j = 0;
+
+ for (leaf = bvh->leaf_root; leaf; leaf = leaf->nextLeaf)
+ {
+ traversecheck = 1;
+ if ((leaf->parent) && (leaf->parent->traversed == leaf->parent->count_nodes))
+ {
+ leaf->parent->traversed = 0;
+ }
+ if(!moving)
+ bvh_calc_DOP_hull_static(bvh, &leaf, 1, leaf->bv, leaf);
+ else
+ bvh_calc_DOP_hull_moving(bvh, &leaf, 1, leaf->bv, leaf);
+
+ // inflate the bv with some epsilon
+ for (j = KDOP_START; j < KDOP_END; j++)
+ {
+ leaf->bv[(2 * j)] -= bvh->epsilon; // minimum
+ leaf->bv[(2 * j) + 1] += bvh->epsilon; // maximum
+ }
+
+ for (parent = leaf->parent; parent; parent = parent->parent)
+ {
+ if (traversecheck)
+ {
+ parent->traversed++; // we tried to go up in hierarchy
+ if (parent->traversed < parent->count_nodes)
+ {
+ traversecheck = 0;
+
+ if (parent->parent)
+ {
+ if (parent->parent->traversed == parent->parent->count_nodes)
+ {
+ parent->parent->traversed = 0;
+ }
+ }
+ break; // we do not need to check further
+ }
+ else
+ {
+ bvh_join(parent);
+ }
+ }
+
+ }
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 345bc522449..f4acfe511cb 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -545,26 +545,26 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
case IPO_FLOAT:
if(weights) {
- memcpy(poin, kref, 4*cp[0]);
+ memcpy(poin, kref, sizeof(float)*cp[0]);
if(*weights!=0.0f)
rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights);
weights++;
}
else
- memcpy(poin, k1, 4*cp[0]);
+ memcpy(poin, k1, sizeof(float)*cp[0]);
poin+= ofsp[0];
break;
case IPO_BPOINT:
- memcpy(poin, k1, 3*4);
- memcpy(poin+16, k1+12, 4);
+ memcpy(poin, k1, 3*sizeof(float));
+ memcpy(poin+4*sizeof(float), k1+3*sizeof(float), sizeof(float));
poin+= ofsp[0];
break;
case IPO_BEZTRIPLE:
- memcpy(poin, k1, 4*12);
+ memcpy(poin, k1, sizeof(float)*10);
poin+= ofsp[0];
break;
@@ -672,19 +672,21 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
/* step 2: do it */
- kb= key->block.first;
- while(kb) {
-
+ for(kb=key->block.first; kb; kb=kb->next) {
if(kb!=key->refkey) {
float icuval= kb->curval;
/* only with value, and no difference allowed */
- if(icuval!=0.0f && kb->totelem==tot) {
+ if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
+ KeyBlock *refb;
float weight, *weights= kb->weights;
poin= basispoin;
- reffrom= key->refkey->data;
from= kb->data;
+ /* reference now can be any block */
+ refb= BLI_findlink(&key->block, kb->relative);
+ if(refb==NULL) continue;
+ reffrom= refb->data;
poin+= start*ofs[0];
reffrom+= key->elemsize*start; // key elemsize yes!
@@ -734,7 +736,6 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
}
}
}
- kb= kb->next;
}
}
@@ -1025,7 +1026,7 @@ static int do_mesh_key(Object *ob, Mesh *me)
for(a=0; a<me->totvert; a+=step, cfra+= delta) {
- ctime= bsystem_time(0, 0, cfra, 0.0);
+ ctime= bsystem_time(0, cfra, 0.0);
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
@@ -1060,7 +1061,7 @@ static int do_mesh_key(Object *ob, Mesh *me)
}
}
else {
- ctime= bsystem_time(ob, 0, G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(ob, G.scene->r.cfra, 0.0);
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
@@ -1180,7 +1181,7 @@ static int do_curve_key(Curve *cu)
for(a=0; a<tot; a+=step, cfra+= delta) {
- ctime= bsystem_time(0, 0, cfra, 0.0);
+ ctime= bsystem_time(0, cfra, 0.0);
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
@@ -1202,7 +1203,7 @@ static int do_curve_key(Curve *cu)
}
else {
- ctime= bsystem_time(NULL, 0, (float)G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(NULL, (float)G.scene->r.cfra, 0.0);
if(cu->key->type==KEY_RELATIVE) {
do_rel_cu_key(cu, ctime);
@@ -1244,7 +1245,7 @@ static int do_latt_key(Object *ob, Lattice *lt)
for(a=0; a<tot; a++, cfra+= delta) {
- ctime= bsystem_time(0, 0, cfra, 0.0);
+ ctime= bsystem_time(0, cfra, 0.0);
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
@@ -1261,7 +1262,7 @@ static int do_latt_key(Object *ob, Lattice *lt)
}
}
else {
- ctime= bsystem_time(NULL, 0, (float)G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(NULL, (float)G.scene->r.cfra, 0.0);
if(lt->key->type==KEY_RELATIVE) {
KeyBlock *kb;
@@ -1308,6 +1309,9 @@ int do_ob_key(Object *ob)
if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) {
KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
+ if(kb && (kb->flag & KEYBLOCK_MUTE))
+ kb= key->refkey;
+
if(kb==NULL) {
kb= key->block.first;
ob->shapenr= 1;
@@ -1342,7 +1346,7 @@ int do_ob_key(Object *ob)
if(ob->ipoflag & OB_ACTION_KEY)
do_all_object_actions(ob);
else {
- calc_ipo(key->ipo, bsystem_time(ob, 0, G.scene->r.cfra, 0.0));
+ calc_ipo(key->ipo, bsystem_time(ob, G.scene->r.cfra, 0.0));
execute_ipo((ID *)key, key->ipo);
}
@@ -1386,3 +1390,23 @@ KeyBlock *ob_get_keyblock(Object *ob)
return NULL;
}
+
+/* get the appropriate KeyBlock given an index */
+KeyBlock *key_get_keyblock(Key *key, int index)
+{
+ KeyBlock *kb;
+ int i;
+
+ if (key) {
+ kb= key->block.first;
+
+ for (i= 1; i < key->totkey; i++) {
+ kb= kb->next;
+
+ if (index==i)
+ return kb;
+ }
+ }
+
+ return NULL;
+}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 64c081c27a6..47175a789b1 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -483,6 +483,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)
/* test for cyclic */
bl= cu->bev.first;
+ if (!bl->nr) return 0;
if(bl && bl->poly> -1) cycl= 1;
if(cycl==0) {
@@ -518,7 +519,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)
/* co: local coord, result local too */
/* returns quaternion for rotation, using cd->no_rot_axis */
/* axis is using another define!!! */
-static float *calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
+static int calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
{
Curve *cu= par->data;
float fac, loc[4], dir[3], cent[3];
@@ -548,7 +549,7 @@ static float *calc_curve_deform(Object *par, float *co, short axis, CurveDeform
/* to be sure, mostly after file load */
if(cu->path==NULL) {
makeDispListCurveTypes(par, 0);
- if(cu->path==NULL) return NULL; // happens on append...
+ if(cu->path==NULL) return 0; // happens on append...
}
/* options */
@@ -574,14 +575,13 @@ static float *calc_curve_deform(Object *par, float *co, short axis, CurveDeform
}
if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
- float q[4], mat[3][3];
- float *quat;
+ float q[4], mat[3][3], quat[4];
if(cd->no_rot_axis) /* set by caller */
dir[cd->no_rot_axis-1]= 0.0f;
/* -1 for compatibility with old track defines */
- quat= vectoquat(dir, axis-1, upflag); /* gives static quat */
+ vectoquat(dir, axis-1, upflag, quat);
/* the tilt */
if(loc[3]!=0.0) {
@@ -601,9 +601,12 @@ static float *calc_curve_deform(Object *par, float *co, short axis, CurveDeform
/* translation */
VECADD(co, cent, loc);
- return quat;
+ if(quatp)
+ QUATCOPY(quatp, quat);
+
+ return 1;
}
- return NULL;
+ return 0;
}
void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, char *vgroup, short defaxis)
@@ -667,7 +670,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
for(j = 0; j < dvert->totweight; j++) {
if(dvert->dw[j].def_nr == index) {
VECCOPY(vec, vertexCos[a]);
- calc_curve_deform(cuOb, vec, defaxis, &cd);
+ calc_curve_deform(cuOb, vec, defaxis, &cd, NULL);
VecLerpf(vertexCos[a], vertexCos[a], vec,
dvert->dw[j].weight);
Mat4MulVecfl(cd.objectspace, vertexCos[a]);
@@ -685,7 +688,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
}
for(a = 0; a < numVerts; a++) {
- calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd);
+ calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd, NULL);
Mat4MulVecfl(cd.objectspace, vertexCos[a]);
}
}
@@ -698,7 +701,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
void curve_deform_vector(Object *cuOb, Object *target, float *orco, float *vec, float mat[][3], int no_rot_axis)
{
CurveDeform cd;
- float *quat;
+ float quat[4];
init_curve_deform(cuOb, target, &cd, 0); /* 0 no dloc */
cd.no_rot_axis= no_rot_axis; /* option to only rotate for XY, for example */
@@ -708,8 +711,7 @@ void curve_deform_vector(Object *cuOb, Object *target, float *orco, float *vec,
Mat4MulVecfl(cd.curvespace, vec);
- quat= calc_curve_deform(cuOb, vec, target->trackflag+1, &cd);
- if(quat) {
+ if(calc_curve_deform(cuOb, vec, target->trackflag+1, &cd, quat)) {
float qmat[3][3];
QuatToMat3(quat, qmat);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 23cf864e181..4cd7e1c6d38 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -78,6 +78,8 @@
#include "DNA_nla_types.h"
#include "DNA_effect_types.h"
#include "DNA_brush_types.h"
+#include "DNA_particle_types.h"
+#include "BKE_particle.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
@@ -112,7 +114,7 @@
#include "BKE_brush.h"
#include "BKE_idprop.h"
-#include "BPI_script.h"
+#include "DNA_space_types.h"
#define MAX_IDPUP 60 /* was 24 */
@@ -194,6 +196,8 @@ ListBase *wich_libbase(Main *mainlib, short type)
return &(mainlib->nodetree);
case ID_BR:
return &(mainlib->brush);
+ case ID_PA:
+ return &(mainlib->particle);
}
return 0;
}
@@ -254,16 +258,17 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[18]= &(main->nodetree);
lb[19]= &(main->brush);
lb[20]= &(main->script);
+ lb[21]= &(main->particle);
- lb[21]= &(main->world);
- lb[22]= &(main->screen);
- lb[23]= &(main->object);
- lb[24]= &(main->scene);
- lb[25]= &(main->library);
+ lb[22]= &(main->world);
+ lb[23]= &(main->screen);
+ lb[24]= &(main->object);
+ lb[25]= &(main->scene);
+ lb[26]= &(main->library);
- lb[26]= NULL;
+ lb[27]= NULL;
- return 26;
+ return 27;
}
/* *********** ALLOC AND FREE *****************
@@ -359,6 +364,9 @@ static ID *alloc_libblock_notest(short type)
case ID_BR:
id = MEM_callocN(sizeof(Brush), "brush");
break;
+ case ID_PA:
+ id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
+ break;
}
return id;
}
@@ -409,7 +417,8 @@ void *copy_libblock(void *rt)
id->newid= idn;
idn->flag |= LIB_NEW;
-
+ if (id->properties) idn->properties = IDP_CopyProperty(id->properties);
+
return idn;
}
@@ -502,6 +511,9 @@ void free_libblock(ListBase *lb, void *idv)
case ID_BR:
free_brush((Brush *)id);
break;
+ case ID_PA:
+ psys_free_settings((ParticleSettings *)id);
+ break;
}
if (id->properties) {
@@ -915,12 +927,17 @@ int new_id(ListBase *lb, ID *id, const char *tname)
/* if no libdata given, look up based on ID */
if(lb==NULL) lb= wich_libbase(G.main, GS(id->name));
- if(tname==0) /* if no name given, use name of current ID */
+ if(tname==0) { /* if no name given, use name of current ID */
strncpy(name, id->name+2, 21);
- else /* else make a copy (tname args can be const) */
+ result= strlen(id->name+2);
+ }
+ else { /* else make a copy (tname args can be const) */
strncpy(name, tname, 21);
+ result= strlen(tname);
+ }
- if( strlen(name) > 21 ) name[21]= 0;
+ /* if result > 21, strncpy don't put the final '\0' to name. */
+ if( result > 21 ) name[21]= 0;
result = check_for_dupid( lb, id, name );
strcpy( id->name+2, name );
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 56b8307020a..42cac46c241 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -90,6 +90,7 @@ void free_material(Material *ma)
if(ma->ramp_col) MEM_freeN(ma->ramp_col);
if(ma->ramp_spec) MEM_freeN(ma->ramp_spec);
+ BKE_previewimg_free(&ma->preview);
BKE_icon_delete((struct ID*)ma);
ma->id.icon_id = 0;
@@ -139,6 +140,12 @@ void init_material(Material *ma)
ma->tx_falloff= 1.0;
ma->shad_alpha= 1.0f;
+ ma->gloss_mir = ma->gloss_tra= 1.0;
+ ma->samp_gloss_mir = ma->samp_gloss_tra= 18;
+ ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
+ ma->dist_mir = 0.0;
+ ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
+
ma->rampfac_col= 1.0;
ma->rampfac_spec= 1.0;
ma->pr_lamp= 3; /* two lamps, is bits */
@@ -159,6 +166,8 @@ void init_material(Material *ma)
ma->sss_back= 1.0f;
ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR;
+
+ ma->preview = NULL;
}
Material *add_material(char *name)
@@ -196,6 +205,8 @@ Material *copy_material(Material *ma)
if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col);
if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec);
+ if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
+
if(ma->nodetree) {
man->nodetree= ntreeCopyTree(ma->nodetree, 0); /* 0 == full new tree */
}
@@ -570,6 +581,26 @@ void assign_material(Object *ob, Material *ma, int act)
test_object_materials(ob->data);
}
+int find_material_index(Object *ob, Material *ma)
+{
+ Material ***matarar;
+ short a, *totcolp;
+
+ if(ma==NULL) return 0;
+
+ totcolp= give_totcolp(ob);
+ matarar= give_matarar(ob);
+
+ if(totcolp==NULL || matarar==NULL) return 0;
+
+ for(a=0; a<*totcolp; a++)
+ if((*matarar)[a]==ma)
+ break;
+ if(a<*totcolp)
+ return a+1;
+ return 0;
+}
+
void new_material_to_objectdata(Object *ob)
{
Material *ma;
@@ -598,7 +629,7 @@ void new_material_to_objectdata(Object *ob)
static void do_init_render_material(Material *ma, int r_mode, float *amb)
{
MTex *mtex;
- int a, needuv=0;
+ int a, needuv=0, needtang=0;
if(ma->flarec==0) ma->flarec= 1;
@@ -622,8 +653,14 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT|TEXCO_SPEED)) needuv= 1;
else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1;
+
+ if((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
+ needtang= 1;
}
}
+
+ if(needtang) ma->mode |= MA_NORMAP_TANG;
+ else ma->mode &= ~MA_NORMAP_TANG;
if(r_mode & R_RADIO)
if(ma->mode & MA_RADIO) needuv= 1;
@@ -650,6 +687,9 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
/* will become or-ed result of all node modes */
ma->mode_l= ma->mode;
ma->mode_l &= ~MA_SHLESS;
+
+ if(ma->strand_surfnor > 0.0f)
+ ma->mode_l |= MA_STR_SURFDIFF;
}
static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb)
@@ -746,9 +786,9 @@ int material_in_material(Material *parmat, Material *mat)
/* ****************** */
char colname_array[125][20]= {
-"Black","DarkRed","HalveRed","Red","Red",
+"Black","DarkRed","HalfRed","Red","Red",
"DarkGreen","DarkOlive","Brown","Chocolate","OrangeRed",
-"HalveGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange",
+"HalfGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange",
"LightGreen","Chartreuse","YellowGreen","Yellow","Gold",
"Green","LawnGreen","GreenYellow","LightOlive","Yellow",
"DarkBlue","DarkPurple","HotPink","VioletPink","RedPink",
@@ -756,7 +796,7 @@ char colname_array[125][20]= {
"SeaGreen","PaleGreen","GreenKhaki","LightBrown","LightSalmon",
"SpringGreen","PaleGreen","MediumOlive","YellowBrown","LightGold",
"LightGreen","LightGreen","LightGreen","GreenYellow","PaleYellow",
-"HalveBlue","DarkSky","HalveMagenta","VioletRed","DeepPink",
+"HalfBlue","DarkSky","HalfMagenta","VioletRed","DeepPink",
"SteelBlue","SkyBlue","Orchid","LightHotPink","HotPink",
"SeaGreen","SlateGray","MediumGrey","Burlywood","LightPink",
"SpringGreen","Aquamarine","PaleGreen","Khaki","PaleOrange",
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index e731f0fdfe0..e2b78affd59 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -233,14 +233,14 @@ void tex_space_mball(Object *ob)
boundbox_set_from_min_max(bb, min, max);
}
-void make_orco_mball(Object *ob)
+float *make_orco_mball(Object *ob)
{
BoundBox *bb;
DispList *dl;
- float *data;
+ float *data, *orco, *orcodata;
float loc[3], size[3];
int a;
-
+
/* restore size and loc */
bb= ob->bb;
loc[0]= (bb->vec[0][0]+bb->vec[4][0])/2.0f;
@@ -251,15 +251,21 @@ void make_orco_mball(Object *ob)
size[2]= bb->vec[1][2]-loc[2];
dl= ob->disp.first;
+ orcodata= MEM_mallocN(sizeof(float)*3*dl->nr, "MballOrco");
+
data= dl->verts;
+ orco= orcodata;
a= dl->nr;
while(a--) {
- data[0]= (data[0]-loc[0])/size[0];
- data[1]= (data[1]-loc[1])/size[1];
- data[2]= (data[2]-loc[2])/size[2];
+ orco[0]= (data[0]-loc[0])/size[0];
+ orco[1]= (data[1]-loc[1])/size[1];
+ orco[2]= (data[2]-loc[2])/size[2];
data+= 3;
+ orco+= 3;
}
+
+ return orcodata;
}
/** \brief Test, if Object *ob is basic MetaBall.
*
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 4c6bfda1517..3bfd605cf27 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -55,14 +55,13 @@
#include "DNA_meshdata_types.h"
#include "DNA_ipo_types.h"
-#include "BDR_sculptmode.h"
-
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_subsurf.h"
#include "BKE_displist.h"
#include "BKE_library.h"
@@ -83,8 +82,6 @@
#include "BLI_editVert.h"
#include "BLI_arithb.h"
-#include "multires.h"
-
int update_realtime_texture(MTFace *tface, double time)
{
Image *ima;
@@ -454,11 +451,15 @@ void tex_space_mesh(Mesh *me)
}
}
-BoundBox *mesh_get_bb(Mesh *me)
+BoundBox *mesh_get_bb(Object *ob)
{
- if (!me->bb) {
+ Mesh *me= ob->data;
+
+ if(ob->bb)
+ return ob->bb;
+
+ if (!me->bb)
tex_space_mesh(me);
- }
return me->bb;
}
@@ -474,45 +475,23 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
if (size_r) VECCOPY(size_r, me->size);
}
-static float *make_orco_mesh_internal(Object *ob, int render)
+float *get_mesh_orco_verts(Object *ob)
{
Mesh *me = ob->data;
- float (*orcoData)[3];
int a, totvert;
- float loc[3], size[3];
- DerivedMesh *dm;
float (*vcos)[3] = NULL;
- /* Get appropriate vertex coordinates */
-
+ /* Get appropriate vertex coordinates */
if(me->key && me->texcomesh==0 && me->key->refkey) {
- KeyBlock *kb= me->key->refkey;
- float *fp= kb->data;
- totvert= MIN2(kb->totelem, me->totvert);
- vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
-
- for(a=0; a<totvert; a++, fp+=3) {
- vcos[a][0]= fp[0];
- vcos[a][1]= fp[1];
- vcos[a][2]= fp[2];
- }
+ vcos= mesh_getRefKeyCos(me, &totvert);
}
else {
- MultiresLevel *lvl = NULL;
- MVert *mvert = NULL;
-
- if(me->mr) {
- lvl = multires_level_n(me->mr, me->mr->pinlvl);
- vcos = MEM_callocN(sizeof(*vcos)*lvl->totvert, "orco mr mesh");
- mvert = me->mr->verts;
- totvert = lvl->totvert;
- }
- else {
- Mesh *tme = me->texcomesh?me->texcomesh:me;
- vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
- mvert = tme->mvert;
- totvert = MIN2(tme->totvert, me->totvert);
- }
+ MVert *mvert = NULL;
+ Mesh *tme = me->texcomesh?me->texcomesh:me;
+
+ vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
+ mvert = tme->mvert;
+ totvert = MIN2(tme->totvert, me->totvert);
for(a=0; a<totvert; a++, mvert++) {
vcos[a][0]= mvert->co[0];
@@ -521,45 +500,37 @@ static float *make_orco_mesh_internal(Object *ob, int render)
}
}
- /* Apply orco-changing modifiers */
-
- if (render) {
- dm = mesh_create_derived_no_deform_render(ob, vcos, CD_MASK_BAREMESH);
- } else {
- dm = mesh_create_derived_no_deform(ob, vcos, CD_MASK_BAREMESH);
- }
- totvert = dm->getNumVerts(dm);
+ return (float*)vcos;
+}
- orcoData = MEM_mallocN(sizeof(*orcoData)*totvert, "orcoData");
- dm->getVertCos(dm, orcoData);
- dm->release(dm);
- MEM_freeN(vcos);
+void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert, int invert)
+{
+ float loc[3], size[3];
+ int a;
mesh_get_texspace(me->texcomesh?me->texcomesh:me, loc, NULL, size);
- for(a=0; a<totvert; a++) {
- float *co = orcoData[a];
- co[0] = (co[0]-loc[0])/size[0];
- co[1] = (co[1]-loc[1])/size[1];
- co[2] = (co[2]-loc[2])/size[2];
+ if(invert) {
+ for(a=0; a<totvert; a++) {
+ float *co = orco[a];
+ co[0] = co[0]*size[0] + loc[0];
+ co[1] = co[1]*size[1] + loc[1];
+ co[2] = co[2]*size[2] + loc[2];
+ }
+ }
+ else {
+ for(a=0; a<totvert; a++) {
+ float *co = orco[a];
+ co[0] = (co[0]-loc[0])/size[0];
+ co[1] = (co[1]-loc[1])/size[1];
+ co[2] = (co[2]-loc[2])/size[2];
+ }
}
-
- return (float*) orcoData;
-}
-
-float *mesh_create_orco_render(Object *ob)
-{
- return make_orco_mesh_internal(ob, 1);
-}
-
-float *mesh_create_orco(Object *ob)
-{
- return make_orco_mesh_internal(ob, 0);
}
/* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.
this is necessary to make the if(mface->v4) check for quads work */
-void test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
+int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
{
/* first test if the face is legal */
if(mface->v3 && mface->v3==mface->v4) {
@@ -601,6 +572,8 @@ void test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
CustomData_swap(fdata, mfindex, corner_indices);
}
}
+
+ return nr;
}
Mesh *get_mesh(Object *ob)
@@ -797,8 +770,7 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
mface->v4= index[3];
mface->flag= ME_SMOOTH;
- if(mface->v3==mface->v4)
- mface->v4= 0;
+ test_index_face(mface, NULL, 0, (mface->v3==mface->v4)? 3: 4);
mface++;
index+= 4;
@@ -933,8 +905,8 @@ void nurbs_to_mesh(Object *ob)
index= dl->index;
while(a--) {
mface->v1= startvert+index[0];
- mface->v2= startvert+index[1];
- mface->v3= startvert+index[2];
+ mface->v2= startvert+index[2];
+ mface->v3= startvert+index[1];
mface->v4= 0;
test_index_face(mface, NULL, 0, 3);
@@ -1120,9 +1092,8 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1");
if (numVerts_r) *numVerts_r = numVerts;
- for (i=0; i<numVerts; i++) {
+ for (i=0; i<numVerts; i++)
VECCOPY(cos[i], me->mvert[i].co);
- }
return cos;
#ifdef WITH_VERSE
@@ -1130,12 +1101,24 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
#endif
}
-/* UvVertMap */
+float (*mesh_getRefKeyCos(Mesh *me, int *numVerts_r))[3]
+{
+ KeyBlock *kb;
+ float (*cos)[3] = NULL;
+ int totvert;
+
+ if(me->key && me->key->refkey) {
+ if(numVerts_r) *numVerts_r= me->totvert;
+ cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1");
-struct UvVertMap {
- struct UvMapVert **vert;
- struct UvMapVert *buf;
-};
+ kb= me->key->refkey;
+ totvert= MIN2(kb->totelem, me->totvert);
+
+ memcpy(cos, kb->data, sizeof(*cos)*totvert);
+ }
+
+ return cos;
+}
UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit)
{
@@ -1158,12 +1141,12 @@ UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned
if(totuv==0)
return NULL;
- vmap= (UvVertMap*)MEM_mallocN(sizeof(*vmap), "UvVertMap");
+ vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap");
if (!vmap)
return NULL;
vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totvert, "UvMapVert*");
- buf= vmap->buf= (UvMapVert*)MEM_mallocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
+ buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
if (!vmap->vert || !vmap->buf) {
free_uv_vert_map(vmap);
@@ -1246,3 +1229,70 @@ void free_uv_vert_map(UvVertMap *vmap)
}
}
+/* Partial Mesh Visibility */
+PartialVisibility *mesh_pmv_copy(PartialVisibility *pmv)
+{
+ PartialVisibility *n= MEM_dupallocN(pmv);
+ n->vert_map= MEM_dupallocN(pmv->vert_map);
+ n->edge_map= MEM_dupallocN(pmv->edge_map);
+ n->old_edges= MEM_dupallocN(pmv->old_edges);
+ n->old_faces= MEM_dupallocN(pmv->old_faces);
+ return n;
+}
+
+void mesh_pmv_free(PartialVisibility *pv)
+{
+ MEM_freeN(pv->vert_map);
+ MEM_freeN(pv->edge_map);
+ MEM_freeN(pv->old_faces);
+ MEM_freeN(pv->old_edges);
+ MEM_freeN(pv);
+}
+
+void mesh_pmv_revert(Object *ob, Mesh *me)
+{
+ if(me->pv) {
+ unsigned i;
+ MVert *nve, *old_verts;
+
+ /* Reorder vertices */
+ nve= me->mvert;
+ old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts");
+ for(i=0; i<me->pv->totvert; ++i)
+ old_verts[i]= nve[me->pv->vert_map[i]];
+
+ /* Restore verts, edges and faces */
+ CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
+ CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
+ CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
+
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge);
+ CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->pv->old_faces, me->pv->totface);
+ mesh_update_customdata_pointers(me);
+
+ me->totvert= me->pv->totvert;
+ me->totedge= me->pv->totedge;
+ me->totface= me->pv->totface;
+
+ me->pv->old_edges= NULL;
+ me->pv->old_faces= NULL;
+
+ /* Free maps */
+ MEM_freeN(me->pv->edge_map);
+ me->pv->edge_map= NULL;
+ MEM_freeN(me->pv->vert_map);
+ me->pv->vert_map= NULL;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+}
+
+void mesh_pmv_off(Object *ob, Mesh *me)
+{
+ if(ob && me->pv) {
+ mesh_pmv_revert(ob, me);
+ MEM_freeN(me->pv);
+ me->pv= NULL;
+ }
+}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 707f050d56e..4db391ddc95 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -41,16 +41,19 @@
#include "math.h"
#include "float.h"
-#include "BLI_blenlib.h"
-#include "BLI_rand.h"
#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_kdtree.h"
#include "BLI_linklist.h"
+#include "BLI_rand.h"
#include "BLI_edgehash.h"
#include "BLI_ghash.h"
+#include "BLI_memarena.h"
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_effect_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -58,6 +61,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_curve_types.h"
@@ -71,21 +75,28 @@
#include "BKE_main.h"
#include "BKE_anim.h"
#include "BKE_bad_level_calls.h"
+#include "BKE_cloth.h"
+#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
-#include "BKE_utildefines.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
#include "BKE_booleanops.h"
#include "BKE_displist.h"
#include "BKE_modifier.h"
#include "BKE_lattice.h"
+#include "BKE_library.h"
#include "BKE_subsurf.h"
#include "BKE_object.h"
#include "BKE_mesh.h"
#include "BKE_softbody.h"
+#include "BKE_cloth.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_utildefines.h"
#include "depsgraph_private.h"
+#include "BKE_bmesh.h"
#include "LOD_DependKludge.h"
#include "LOD_decimation.h"
@@ -237,12 +248,29 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
}
}
+static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
+{
+ md= md->next;
+ if(md) {
+ if(md->type==eModifierType_Armature) {
+ ArmatureModifierData *amd = (ArmatureModifierData*) md;
+ if(amd->multi)
+ amd->prevCos= MEM_dupallocN(vertexCos);
+ }
+ /* lattice/mesh modifier too */
+ }
+}
+
+
static void latticeModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts)
{
LatticeModifierData *lmd = (LatticeModifierData*) md;
+
+ modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
lattice_deform_verts(lmd->object, ob, derivedData,
vertexCos, numVerts, lmd->name);
}
@@ -383,7 +411,7 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
for(i = 0; i < maxFaces; ++i) faceMap[i] = i;
if (ob) {
- frac = bsystem_time(ob, 0, (float)G.scene->r.cfra,
+ frac = bsystem_time(ob, (float)G.scene->r.cfra,
bmd->start - 1.0f) / bmd->length;
} else {
frac = G.scene->r.cfra - bmd->start / bmd->length;
@@ -408,18 +436,18 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
MFace mf;
dm->getFace(dm, faceMap[i], &mf);
- if(!BLI_ghash_haskey(vertHash, (void *)mf.v1))
- BLI_ghash_insert(vertHash, (void *)mf.v1,
- (void *)BLI_ghash_size(vertHash));
- if(!BLI_ghash_haskey(vertHash, (void *)mf.v2))
- BLI_ghash_insert(vertHash, (void *)mf.v2,
- (void *)BLI_ghash_size(vertHash));
- if(!BLI_ghash_haskey(vertHash, (void *)mf.v3))
- BLI_ghash_insert(vertHash, (void *)mf.v3,
- (void *)BLI_ghash_size(vertHash));
- if(mf.v4 && !BLI_ghash_haskey(vertHash, (void *)mf.v4))
- BLI_ghash_insert(vertHash, (void *)mf.v4,
- (void *)BLI_ghash_size(vertHash));
+ if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+ if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+ if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+ if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
}
/* get the set of edges that will be in the new mesh (i.e. all edges
@@ -430,10 +458,10 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
MEdge me;
dm->getEdge(dm, i, &me);
- if(BLI_ghash_haskey(vertHash, (void *)me.v1)
- && BLI_ghash_haskey(vertHash, (void *)me.v2))
+ if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))
+ && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
BLI_ghash_insert(edgeHash,
- (void *)BLI_ghash_size(edgeHash), (void *)i);
+ SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i));
}
} else if(numEdges) {
if(bmd->randomize)
@@ -447,12 +475,12 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
MEdge me;
dm->getEdge(dm, edgeMap[i], &me);
- if(!BLI_ghash_haskey(vertHash, (void *)me.v1))
- BLI_ghash_insert(vertHash, (void *)me.v1,
- (void *)BLI_ghash_size(vertHash));
- if(!BLI_ghash_haskey(vertHash, (void *)me.v2))
- BLI_ghash_insert(vertHash, (void *)me.v2,
- (void *)BLI_ghash_size(vertHash));
+ if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
+ if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2),
+ SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
}
/* get the set of edges that will be in the new mesh
@@ -461,8 +489,8 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
MEdge me;
dm->getEdge(dm, edgeMap[i], &me);
- BLI_ghash_insert(edgeHash, (void *)BLI_ghash_size(edgeHash),
- (void *)edgeMap[i]);
+ BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)),
+ SET_INT_IN_POINTER(edgeMap[i]));
}
} else {
int numVerts = dm->getNumVerts(dm) * frac;
@@ -475,7 +503,7 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
* mapped to the new indices
*/
for(i = 0; i < numVerts; ++i)
- BLI_ghash_insert(vertHash, (void *)vertMap[i], (void *)i);
+ BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
}
/* now we know the number of verts, edges and faces, we can create
@@ -490,8 +518,8 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
BLI_ghashIterator_step(hashIter)) {
MVert source;
MVert *dest;
- int oldIndex = (int)BLI_ghashIterator_getKey(hashIter);
- int newIndex = (int)BLI_ghashIterator_getValue(hashIter);
+ int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
+ int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
dm->getVert(dm, oldIndex, &source);
dest = CDDM_get_vert(result, newIndex);
@@ -505,13 +533,13 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
for(i = 0; i < BLI_ghash_size(edgeHash); ++i) {
MEdge source;
MEdge *dest;
- int oldIndex = (int)BLI_ghash_lookup(edgeHash, (void *)i);
+ int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
dm->getEdge(dm, oldIndex, &source);
dest = CDDM_get_edge(result, i);
- source.v1 = (int)BLI_ghash_lookup(vertHash, (void *)source.v1);
- source.v2 = (int)BLI_ghash_lookup(vertHash, (void *)source.v2);
+ source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+ source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
DM_copy_edge_data(dm, result, oldIndex, i, 1);
*dest = source;
@@ -528,11 +556,11 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
orig_v4 = source.v4;
- source.v1 = (int)BLI_ghash_lookup(vertHash, (void *)source.v1);
- source.v2 = (int)BLI_ghash_lookup(vertHash, (void *)source.v2);
- source.v3 = (int)BLI_ghash_lookup(vertHash, (void *)source.v3);
+ source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+ source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
+ source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
if(source.v4)
- source.v4 = (int)BLI_ghash_lookup(vertHash, (void *)source.v4);
+ source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
DM_copy_face_data(dm, result, faceMap[i], i, 1);
*dest = source;
@@ -774,10 +802,10 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|| amd->fit_type == MOD_ARR_FITCURVE) {
float dist = sqrt(MTC_dot3Float(offset[3], offset[3]));
- if(dist > FLT_EPSILON)
+ if(dist > 1e-6f)
/* this gives length = first copy start to last copy end
add a tiny offset for floating point rounding errors */
- count = (length + FLT_EPSILON) / dist;
+ count = (length + 1e-6f) / dist;
else
/* if the offset has no translation, just make one copy */
count = 1;
@@ -913,6 +941,8 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
count - 1);
}
+ if(med.v1 == med.v2) continue;
+
if (initFlags) {
med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
@@ -974,7 +1004,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
if(inMF.v4 && indexMap[inMF.v4].merge_final)
mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
- test_index_face(mf, &result->faceData, numFaces, inMF.v4?4:3);
+ if(test_index_face(mf, &result->faceData, numFaces, inMF.v4?4:3) < 3)
+ continue;
+
numFaces++;
/* if the face has fewer than 3 vertices, don't create it */
@@ -1229,6 +1261,7 @@ static void mirrorModifier_initData(ModifierData *md)
mmd->flag |= MOD_MIR_AXIS_X;
mmd->tolerance = 0.001;
+ mmd->mirror_ob = NULL;
}
static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
@@ -1239,12 +1272,37 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
tmmd->axis = mmd->axis;
tmmd->flag = mmd->flag;
tmmd->tolerance = mmd->tolerance;
+ tmmd->mirror_ob = mmd->mirror_ob;;
+}
+
+static void mirrorModifier_foreachObjectLink(
+ ModifierData *md, Object *ob,
+ void (*walk)(void *userData, Object *ob, Object **obpoin),
+ void *userData)
+{
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ walk(userData, ob, &mmd->mirror_ob);
+}
+
+static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+ Object *ob, DagNode *obNode)
+{
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ if(mmd->mirror_ob) {
+ DagNode *latNode = dag_get_node(forest, mmd->mirror_ob);
+
+ dag_add_relation(forest, latNode, obNode,
+ DAG_RL_DATA_DATA | DAG_RL_OB_DATA);
+ }
}
static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
- DerivedMesh *dm,
- int initFlags,
- int axis)
+ Object *ob,
+ DerivedMesh *dm,
+ int initFlags,
+ int axis)
{
int i;
float tolerance = mmd->tolerance;
@@ -1254,6 +1312,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
int maxEdges = dm->getNumEdges(dm);
int maxFaces = dm->getNumFaces(dm);
int (*indexMap)[2];
+ float mtx[4][4], imtx[4][4];
numVerts = numEdges = numFaces = 0;
@@ -1261,13 +1320,28 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2);
+ 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 < maxVerts; i++) {
MVert inMV;
MVert *mv = CDDM_get_vert(result, numVerts);
int isShared;
+ float co[3];
dm->getVert(dm, i, &inMV);
- isShared = ABS(inMV.co[axis])<=tolerance;
+
+ VecCopyf(co, inMV.co);
+
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(co, mtx, co);
+ }
+ isShared = ABS(co[axis])<=tolerance;
/* Because the topology result (# of vertices) must be the same if
* the mesh data is overridden by vertex cos, have to calc sharedness
@@ -1281,7 +1355,12 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
indexMap[i][1] = !isShared;
if(isShared) {
- mv->co[axis] = 0;
+ co[axis] = 0;
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(co, imtx, co);
+ }
+ VecCopyf(mv->co, co);
+
mv->flag |= ME_VERT_MERGED;
} else {
MVert *mv2 = CDDM_get_vert(result, numVerts);
@@ -1290,7 +1369,11 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
*mv2 = *mv;
numVerts++;
- mv2->co[axis] = -mv2->co[axis];
+ co[axis] = -co[axis];
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(co, imtx, co);
+ }
+ VecCopyf(mv2->co, co);
}
}
@@ -1384,23 +1467,23 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
}
static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
- DerivedMesh *dm,
+ Object *ob, DerivedMesh *dm,
int initFlags)
{
DerivedMesh *result = dm;
/* check which axes have been toggled and mirror accordingly */
if(mmd->flag & MOD_MIR_AXIS_X) {
- result = doMirrorOnAxis(mmd, result, initFlags, 0);
+ result = doMirrorOnAxis(mmd, ob, result, initFlags, 0);
}
if(mmd->flag & MOD_MIR_AXIS_Y) {
DerivedMesh *tmp = result;
- result = doMirrorOnAxis(mmd, result, initFlags, 1);
+ result = doMirrorOnAxis(mmd, ob, result, initFlags, 1);
if(tmp != dm) tmp->release(tmp); /* free intermediate results */
}
if(mmd->flag & MOD_MIR_AXIS_Z) {
DerivedMesh *tmp = result;
- result = doMirrorOnAxis(mmd, result, initFlags, 2);
+ result = doMirrorOnAxis(mmd, ob, result, initFlags, 2);
if(tmp != dm) tmp->release(tmp); /* free intermediate results */
}
@@ -1414,7 +1497,7 @@ static DerivedMesh *mirrorModifier_applyModifier(
DerivedMesh *result;
MirrorModifierData *mmd = (MirrorModifierData*) md;
- result = mirrorModifier__doMirror(mmd, derivedData, 0);
+ result = mirrorModifier__doMirror(mmd, ob, derivedData, 0);
CDDM_calc_normals(result);
@@ -2453,7 +2536,42 @@ static void split_sharp_edges(SmoothMesh *mesh, float split_angle, int flags)
}
-static void split_single_verts(SmoothMesh *mesh)
+static int count_bridge_verts(SmoothMesh *mesh)
+{
+ int i, j, count = 0;
+
+ for(i = 0; i < mesh->num_faces; i++) {
+ SmoothFace *face = &mesh->faces[i];
+
+ for(j = 0; j < SMOOTHFACE_MAX_EDGES && face->edges[j]; j++) {
+ SmoothEdge *edge = face->edges[j];
+ SmoothEdge *next_edge;
+ SmoothVert *vert = edge->verts[1 - face->flip[j]];
+ int next = (j + 1) % SMOOTHFACE_MAX_EDGES;
+
+ /* wrap next around if at last edge */
+ if(!face->edges[next]) next = 0;
+
+ next_edge = face->edges[next];
+
+ /* if there are other faces sharing this vertex but not
+ * these edges, the vertex will be split, so count it
+ */
+ /* vert has to have at least one face (this one), so faces != 0 */
+ if(!edge->faces->next && !next_edge->faces->next
+ && vert->faces->next) {
+ count++;
+ }
+ }
+ }
+
+ /* each bridge vert will be counted once per face that uses it,
+ * so count is too high, but it's ok for now
+ */
+ return count;
+}
+
+static void split_bridge_verts(SmoothMesh *mesh)
{
int i,j;
@@ -2501,6 +2619,7 @@ static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd,
/* 2. count max number of elements to add */
tag_and_count_extra_edges(mesh, emd->split_angle, emd->flags, &max_edges);
max_verts = max_edges * 2 + mesh->max_verts;
+ max_verts += count_bridge_verts(mesh);
max_edges += mesh->max_edges;
/* 3. reallocate smoothmesh arrays & copy elements across */
@@ -2518,9 +2637,8 @@ static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd,
printf("********** Post-edge-split **********\n");
smoothmesh_print(mesh);
#endif
-#if 1
- split_single_verts(mesh);
-#endif
+
+ split_bridge_verts(mesh);
#ifdef EDGESPLIT_DEBUG_1
printf("********** Post-vert-split **********\n");
@@ -2560,6 +2678,90 @@ static DerivedMesh *edgesplitModifier_applyModifierEM(
return edgesplitModifier_applyModifier(md, ob, derivedData, 0, 1);
}
+/* Bevel */
+
+static void bevelModifier_initData(ModifierData *md)
+{
+ BevelModifierData *bmd = (BevelModifierData*) md;
+
+ bmd->value = 0.1f;
+ bmd->res = 1;
+ bmd->flags = 0;
+ bmd->val_flags = 0;
+ bmd->lim_flags = 0;
+ bmd->e_flags = 0;
+ bmd->bevel_angle = 30;
+ bmd->defgrp_name[0] = '\0';
+}
+
+static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ BevelModifierData *bmd = (BevelModifierData*) md;
+ BevelModifierData *tbmd = (BevelModifierData*) target;
+
+ tbmd->value = bmd->value;
+ tbmd->res = bmd->res;
+ tbmd->flags = bmd->flags;
+ tbmd->val_flags = bmd->val_flags;
+ tbmd->lim_flags = bmd->lim_flags;
+ tbmd->e_flags = bmd->e_flags;
+ tbmd->bevel_angle = bmd->bevel_angle;
+ strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
+}
+
+CustomDataMask bevelModifier_requiredDataMask(ModifierData *md)
+{
+ BevelModifierData *bmd = (BevelModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if(bmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
+
+ return dataMask;
+}
+
+static DerivedMesh *bevelModifier_applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ int useRenderParams, int isFinalCalc)
+{
+ DerivedMesh *result;
+ BME_Mesh *bm;
+ /*bDeformGroup *def;*/
+ int /*i,*/ options, defgrp_index = -1;
+ BevelModifierData *bmd = (BevelModifierData*) md;
+
+ options = bmd->flags|bmd->val_flags|bmd->lim_flags|bmd->e_flags;
+
+ //~ if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) {
+ //~ for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
+ //~ if (!strcmp(def->name, bmd->defgrp_name)) {
+ //~ defgrp_index = i;
+ //~ break;
+ //~ }
+ //~ }
+ //~ if (defgrp_index < 0) {
+ //~ options &= ~BME_BEVEL_VWEIGHT;
+ //~ }
+ //~ }
+
+ bm = BME_make_mesh();
+ bm = BME_derivedmesh_to_bmesh(derivedData, bm);
+ BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL);
+ result = BME_bmesh_to_derivedmesh(bm,derivedData);
+ BME_free_mesh(bm);
+
+ CDDM_calc_normals(result);
+
+ return result;
+}
+
+static DerivedMesh *bevelModifier_applyModifierEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData)
+{
+ return bevelModifier_applyModifier(md, ob, derivedData, 0, 1);
+}
+
/* Displace */
static void displaceModifier_initData(ModifierData *md)
@@ -2577,7 +2779,14 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
DisplaceModifierData *dmd = (DisplaceModifierData*) md;
DisplaceModifierData *tdmd = (DisplaceModifierData*) target;
- *tdmd = *dmd;
+ tdmd->texture = dmd->texture;
+ tdmd->strength = dmd->strength;
+ tdmd->direction = dmd->direction;
+ strncpy(tdmd->defgrp_name, dmd->defgrp_name, 32);
+ tdmd->midlevel = dmd->midlevel;
+ tdmd->texmapping = dmd->texmapping;
+ tdmd->map_object = dmd->map_object;
+ strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
}
CustomDataMask displaceModifier_requiredDataMask(ModifierData *md)
@@ -2609,7 +2818,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob,
walk(userData, ob, (ID **)&dmd->texture);
- displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc) walk, userData);
+ displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}
static int displaceModifier_isDisabled(ModifierData *md)
@@ -4323,11 +4532,11 @@ static void waveModifier_do(
MVert *mvert = NULL;
MDeformVert *dvert = NULL;
int defgrp_index;
- float ctime = bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
+ float ctime = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
float minfac =
(float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
float lifefac = wmd->height;
- float (*tex_co)[3];
+ float (*tex_co)[3] = NULL;
if(wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH)
mvert = dm->getVertArray(dm);
@@ -4570,8 +4779,16 @@ static void armatureModifier_deformVerts(
{
ArmatureModifierData *amd = (ArmatureModifierData*) md;
- armature_deform_verts(amd->object, ob, derivedData, vertexCos, numVerts,
- amd->deformflag, amd->defgrp_name);
+ modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
+ armature_deform_verts(amd->object, ob, derivedData, vertexCos, NULL,
+ numVerts, amd->deformflag,
+ (float(*)[3])amd->prevCos, amd->defgrp_name);
+ /* free cache */
+ if(amd->prevCos) {
+ MEM_freeN(amd->prevCos);
+ amd->prevCos= NULL;
+ }
}
static void armatureModifier_deformVertsEM(
@@ -4583,8 +4800,24 @@ static void armatureModifier_deformVertsEM(
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
- armature_deform_verts(amd->object, ob, dm, vertexCos, numVerts,
- amd->deformflag, amd->defgrp_name);
+ armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts,
+ amd->deformflag, NULL, amd->defgrp_name);
+
+ if(!derivedData) dm->release(dm);
+}
+
+static void armatureModifier_deformMatricesEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData, float (*vertexCos)[3],
+ float (*defMats)[3][3], int numVerts)
+{
+ ArmatureModifierData *amd = (ArmatureModifierData*) md;
+ DerivedMesh *dm = derivedData;
+
+ if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
+
+ armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
+ amd->deformflag, NULL, amd->defgrp_name);
if(!derivedData) dm->release(dm);
}
@@ -4797,6 +5030,293 @@ static void softbodyModifier_deformVerts(
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
}
+
+/* Cloth */
+
+static void clothModifier_initData(ModifierData *md)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), "cloth sim parms");
+ clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), "cloth coll parms");
+
+ /* check for alloc failing */
+ if(!clmd->sim_parms || !clmd->coll_parms)
+ return;
+
+ cloth_init (clmd);
+}
+
+static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+ DerivedMesh *result=NULL;
+
+ /* check for alloc failing */
+ if(!clmd->sim_parms || !clmd->coll_parms)
+ return derivedData;
+
+ result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
+
+ if(result)
+ {
+ CDDM_calc_normals(result);
+ return result;
+ }
+ return derivedData;
+}
+
+static void clothModifier_updateDepgraph(
+ ModifierData *md, DagForest *forest, Object *ob,
+ DagNode *obNode)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ Base *base;
+
+ if(clmd)
+ {
+ for(base = G.scene->base.first; base; base= base->next)
+ {
+ Object *ob1= base->object;
+ if(ob1 != ob)
+ {
+ CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
+ if(coll_clmd)
+ {
+ DagNode *curNode = dag_get_node(forest, ob1);
+ dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ }
+ }
+ }
+ }
+}
+
+CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
+{
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ dataMask |= (1 << CD_MDEFORMVERT);
+
+ return dataMask;
+}
+
+static void clothModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+ ClothModifierData *tclmd = (ClothModifierData*) target;
+
+ if(tclmd->sim_parms)
+ MEM_freeN(tclmd->sim_parms);
+ if(tclmd->coll_parms)
+ MEM_freeN(tclmd->coll_parms);
+
+ tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
+ tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
+
+ tclmd->sim_parms->lastcachedframe = 0;
+}
+
+
+static int clothModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void clothModifier_freeData(ModifierData *md)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ if (clmd)
+ {
+ if(G.rt > 0)
+ printf("clothModifier_freeData\n");
+
+ cloth_free_modifier_extern (clmd);
+
+ if(clmd->sim_parms)
+ MEM_freeN(clmd->sim_parms);
+ if(clmd->coll_parms)
+ MEM_freeN(clmd->coll_parms);
+ }
+}
+
+/* Collision */
+
+static void collisionModifier_initData(ModifierData *md)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time = -1;
+ collmd->numverts = 0;
+ collmd->tree = NULL;
+}
+
+static void collisionModifier_freeData(ModifierData *md)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+
+ if (collmd)
+ {
+ if(collmd->tree)
+ bvh_free(collmd->tree);
+ if(collmd->x)
+ MEM_freeN(collmd->x);
+ if(collmd->xnew)
+ MEM_freeN(collmd->xnew);
+ if(collmd->current_x)
+ MEM_freeN(collmd->current_x);
+ if(collmd->current_xnew)
+ MEM_freeN(collmd->current_xnew);
+ if(collmd->current_v)
+ MEM_freeN(collmd->current_v);
+
+ if(collmd->mfaces)
+ MEM_freeN(collmd->mfaces);
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time = -1;
+ collmd->numverts = 0;
+ collmd->tree = NULL;
+ collmd->mfaces = NULL;
+ }
+}
+
+static int collisionModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void collisionModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+ DerivedMesh *dm = NULL;
+ float current_time = 0;
+ unsigned int numverts = 0, i = 0;
+ MVert *tempVert = NULL;
+
+ /* if possible use/create DerivedMesh */
+ if(derivedData) dm = CDDM_copy(derivedData);
+ else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+
+ if(!ob->pd)
+ {
+ printf("collisionModifier_deformVerts: Should not happen!\n");
+ return;
+ }
+
+ if(dm)
+ {
+ CDDM_apply_vert_coords(dm, vertexCos);
+ CDDM_calc_normals(dm);
+
+ current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+
+ if(G.rt > 0)
+ printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
+
+ numverts = dm->getNumVerts ( dm );
+
+ if(current_time > collmd->time)
+ {
+ // check if mesh has changed
+ if(collmd->x && (numverts != collmd->numverts))
+ collisionModifier_freeData((ModifierData *)collmd);
+
+ if(collmd->time == -1) // first time
+ {
+ collmd->x = dm->dupVertArray(dm); // frame start position
+
+ for ( i = 0; i < numverts; i++ )
+ {
+ // we save global positions
+ Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
+ }
+
+ collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
+ collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
+
+ collmd->numverts = numverts;
+
+ collmd->mfaces = dm->dupFaceArray(dm);
+ collmd->numfaces = dm->getNumFaces(dm);
+
+ // TODO: epsilon
+ // create bounding box hierarchy
+ collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sbift);
+
+ collmd->time = current_time;
+ }
+ else if(numverts == collmd->numverts)
+ {
+ // put positions to old positions
+ tempVert = collmd->x;
+ collmd->x = collmd->xnew;
+ collmd->xnew = tempVert;
+
+ memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
+
+ for ( i = 0; i < numverts; i++ )
+ {
+ // we save global positions
+ Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
+ }
+
+ memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert));
+ memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
+
+ /* happens on file load (ONLY when i decomment changes in readfile.c */
+ if(!collmd->tree)
+ {
+ collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sbift);
+ }
+ else
+ {
+ // recalc static bounding boxes
+ bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
+ }
+
+ collmd->time = current_time;
+ }
+ else if(numverts != collmd->numverts)
+ {
+ collisionModifier_freeData((ModifierData *)collmd);
+ }
+
+ }
+ else if(current_time < collmd->time)
+ {
+ collisionModifier_freeData((ModifierData *)collmd);
+ }
+ else
+ {
+ if(numverts != collmd->numverts)
+ {
+ collisionModifier_freeData((ModifierData *)collmd);
+ }
+ }
+ }
+
+ if(dm)
+ dm->release(dm);
+}
+
+
/* Boolean */
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -4849,7 +5369,7 @@ static DerivedMesh *booleanModifier_applyModifier(
/* we do a quick sanity check */
if(((Mesh *)ob->data)->totface > 3
&& bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
- DerivedMesh *result = NewBooleanDerivedMesh(ob, bmd->object,
+ DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
1 + bmd->operation);
/* if new mesh returned, return it; otherwise there was
@@ -4863,6 +5383,1544 @@ static DerivedMesh *booleanModifier_applyModifier(
return derivedData;
}
+/* Particles */
+static void particleSystemModifier_initData(ModifierData *md)
+{
+ ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
+ psmd->psys= 0;
+ psmd->dm=0;
+ psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
+}
+static void particleSystemModifier_freeData(ModifierData *md)
+{
+ ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
+
+ if(psmd->dm){
+ psmd->dm->needsFree = 1;
+ psmd->dm->release(psmd->dm);
+ psmd->dm=0;
+ }
+
+ psmd->psys->flag &= ~PSYS_ENABLED;
+ psmd->psys->flag |= PSYS_DELETE;
+}
+static void particleSystemModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
+ ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target;
+
+ tpsmd->dm = 0;
+ tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
+ //tpsmd->facepa = 0;
+ tpsmd->flag = psmd->flag;
+ /* need to keep this to recognise a bit later in copy_object */
+ tpsmd->psys = psmd->psys;
+}
+
+CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
+{
+ ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
+ CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+ int i;
+
+ /* ask for vertexgroups if we need them */
+ for(i=0; i<PSYS_TOT_VG; i++){
+ if(psmd->psys->vgroup[i]){
+ dataMask |= (1 << CD_MDEFORMVERT);
+ break;
+ }
+ }
+
+ /* particles only need this if they are after a non deform modifier, and
+ * the modifier stack will only create them in that case. */
+ dataMask |= CD_MASK_ORIGSPACE;
+
+ dataMask |= CD_MASK_ORCO;
+
+ return dataMask;
+}
+static int is_last_displist(Object *ob)
+{
+ Curve *cu = ob->data;
+ static int curvecount=0, totcurve=0;
+
+ if(curvecount==0){
+ DispList *dl;
+
+ totcurve=0;
+ for(dl=cu->disp.first; dl; dl=dl->next){
+ totcurve++;
+ }
+ }
+
+ curvecount++;
+
+ if(curvecount==totcurve){
+ curvecount=0;
+ return 1;
+ }
+
+ return 0;
+}
+/* saves the current emitter state for a particle system and calculates particles */
+static void particleSystemModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts)
+{
+ DerivedMesh *dm = derivedData;
+ ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
+ ParticleSystem * psys=0;
+ int needsFree=0;
+
+ if(ob->particlesystem.first)
+ psys=psmd->psys;
+ else
+ return;
+
+ if(!psys_check_enabled(ob, psys))
+ return;
+
+ if(dm==0){
+ if(ob->type==OB_MESH){
+ dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
+
+ CDDM_apply_vert_coords(dm, vertexCos);
+ //CDDM_calc_normals(dm);
+
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
+
+ needsFree=1;
+ }
+ else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)){
+ Object *tmpobj;
+ Curve *tmpcu;
+
+ if(is_last_displist(ob)){
+ /* copies object and modifiers (but not the data) */
+ tmpobj= copy_object( ob );
+ tmpcu = (Curve *)tmpobj->data;
+ tmpcu->id.us--;
+
+ /* copies the data */
+ tmpobj->data = copy_curve( (Curve *) ob->data );
+
+ makeDispListCurveTypes( tmpobj, 1 );
+ nurbs_to_mesh( tmpobj );
+
+ dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
+ //CDDM_calc_normals(dm);
+
+ free_libblock_us( &G.main->object, tmpobj );
+
+ needsFree=1;
+ }
+ else return;
+ }
+ else return;
+ }
+
+ /* clear old dm */
+ if(psmd->dm){
+ psmd->dm->needsFree = 1;
+ psmd->dm->release(psmd->dm);
+ }
+
+ /* make new dm */
+ psmd->dm=CDDM_copy(dm);
+ CDDM_calc_normals(psmd->dm);
+
+ if(needsFree){
+ dm->needsFree = 1;
+ dm->release(dm);
+ }
+
+ /* protect dm */
+ psmd->dm->needsFree = 0;
+
+ /* report change in mesh structure */
+ if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert ||
+ psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge ||
+ psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
+ /* in file read dm hasn't really changed but just wasn't saved in file */
+
+ psys->recalc |= PSYS_RECALC_HAIR;
+ psys->recalc |= PSYS_DISTR;
+ psmd->flag |= eParticleSystemFlag_DM_changed;
+
+ psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
+ psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm);
+ psmd->totdmface= psmd->dm->getNumFaces(psmd->dm);
+ }
+
+ if(psys){
+ particle_system_update(ob,psys);
+ psmd->flag |= eParticleSystemFlag_psys_updated;
+ psmd->flag &= ~eParticleSystemFlag_DM_changed;
+ }
+}
+
+/* disabled particles in editmode for now, until support for proper derivedmesh
+ * updates is coded */
+#if 0
+static void particleSystemModifier_deformVertsEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+ DerivedMesh *dm = derivedData;
+
+ if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
+
+ particleSystemModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
+
+ if(!derivedData) dm->release(dm);
+}
+#endif
+
+/* Particle Instance */
+static void particleInstanceModifier_initData(ModifierData *md)
+{
+ ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+
+ pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
+ eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
+ pimd->psys = 1;
+
+}
+static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+ ParticleInstanceModifierData *tpimd= (ParticleInstanceModifierData*) target;
+
+ tpimd->ob = pimd->ob;
+ tpimd->psys = pimd->psys;
+ tpimd->flag = pimd->flag;
+}
+
+static int particleInstanceModifier_dependsOnTime(ModifierData *md)
+{
+ return 0;
+}
+static void particleInstanceModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+ Object *ob, DagNode *obNode)
+{
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
+
+ if (pimd->ob) {
+ DagNode *curNode = dag_get_node(forest, pimd->ob);
+
+ dag_add_relation(forest, curNode, obNode,
+ DAG_RL_DATA_DATA | DAG_RL_OB_DATA);
+ }
+}
+
+static void particleInstanceModifier_foreachObjectLink(ModifierData *md, Object *ob,
+ ObjectWalkFunc walk, void *userData)
+{
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
+
+ walk(userData, ob, &pimd->ob);
+}
+
+static DerivedMesh * particleInstanceModifier_applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ int useRenderParams, int isFinalCalc)
+{
+ DerivedMesh *dm = derivedData, *result;
+ ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+ ParticleSystem * psys=0;
+ ParticleData *pa=0, *pars=0;
+ MFace *mface, *orig_mface;
+ MVert *mvert, *orig_mvert;
+ int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
+ short track=ob->trackflag%3, trackneg;
+ float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
+
+ trackneg=((ob->trackflag>2)?1:0);
+
+ if(pimd->ob==ob){
+ pimd->ob=0;
+ return derivedData;
+ }
+
+ if(pimd->ob){
+ psys = BLI_findlink(&pimd->ob->particlesystem,pimd->psys-1);
+ if(psys==0 || psys->totpart==0)
+ return derivedData;
+ }
+ else return derivedData;
+
+ if(pimd->flag & eParticleInstanceFlag_Parents)
+ totpart+=psys->totpart;
+ if(pimd->flag & eParticleInstanceFlag_Children){
+ if(totpart==0)
+ first_particle=psys->totpart;
+ totpart+=psys->totchild;
+ }
+
+ if(totpart==0)
+ return derivedData;
+
+ pars=psys->particles;
+
+ totvert=dm->getNumVerts(dm);
+ totface=dm->getNumFaces(dm);
+
+ maxvert=totvert*totpart;
+ maxface=totface*totpart;
+
+ psys->lattice=psys_get_lattice(ob, psys);
+
+ if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
+ float co[3];
+ for(i=0; i< totvert; i++){
+ dm->getVertCo(dm,i,co);
+ if(i==0){
+ min_co=max_co=co[track];
+ }
+ else{
+ if(co[track]<min_co)
+ min_co=co[track];
+
+ if(co[track]>max_co)
+ max_co=co[track];
+ }
+ }
+ }
+
+ result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface);
+
+ mvert=result->getVertArray(result);
+ orig_mvert=dm->getVertArray(dm);
+
+ for(i=0; i<maxvert; i++){
+ MVert *inMV;
+ MVert *mv = mvert + i;
+ ParticleKey state;
+
+ inMV = orig_mvert + i%totvert;
+ DM_copy_vert_data(dm, result, i%totvert, i, 1);
+ *mv = *inMV;
+
+ /*change orientation based on object trackflag*/
+ VECCOPY(temp_co,mv->co);
+ mv->co[0]=temp_co[track];
+ mv->co[1]=temp_co[(track+1)%3];
+ mv->co[2]=temp_co[(track+2)%3];
+
+ if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && pimd->flag & eParticleInstanceFlag_Path){
+ state.time=(mv->co[0]-min_co)/(max_co-min_co);
+ if(trackneg)
+ state.time=1.0f-state.time;
+ psys_get_particle_on_path(pimd->ob,psys,first_particle + i/totvert,&state,1);
+
+ mv->co[0] = 0.0;
+
+ Normalize(state.vel);
+
+ if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) {
+ state.rot[0] = 1.0;
+ state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
+ }
+ else {
+ /* a cross product of state.vel and a unit vector in x-direction */
+ cross[0] = 0.0f;
+ cross[1] = -state.vel[2];
+ cross[2] = state.vel[1];
+
+ /* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/
+ VecRotToQuat(cross,saacos(state.vel[0]),state.rot);
+ }
+ }
+ else{
+ state.time=-1.0;
+ psys_get_particle_state(pimd->ob,psys,i/totvert,&state,1);
+ }
+
+ QuatMulVecf(state.rot,mv->co);
+ VECADD(mv->co,mv->co,state.co);
+ }
+
+ mface=result->getFaceArray(result);
+ orig_mface=dm->getFaceArray(dm);
+
+ for(i=0; i<maxface; i++){
+ MFace *inMF;
+ MFace *mf = mface + i;
+
+ if(pimd->flag & eParticleInstanceFlag_Parents){
+ if(i/totface>=psys->totpart){
+ if(psys->part->childtype==PART_CHILD_PARTICLES)
+ pa=psys->particles+(psys->child+i/totface-psys->totpart)->parent;
+ else
+ pa=0;
+ }
+ else
+ pa=pars+i/totface;
+ }
+ else{
+ if(psys->part->childtype==PART_CHILD_PARTICLES)
+ pa=psys->particles+(psys->child+i/totface)->parent;
+ else
+ pa=0;
+ }
+
+ if(pa){
+ if(pa->alive==PARS_UNBORN && (pimd->flag&eParticleInstanceFlag_Unborn)==0) continue;
+ if(pa->alive==PARS_ALIVE && (pimd->flag&eParticleInstanceFlag_Alive)==0) continue;
+ if(pa->alive==PARS_DEAD && (pimd->flag&eParticleInstanceFlag_Dead)==0) continue;
+ }
+
+ inMF = orig_mface + i%totface;
+ DM_copy_face_data(dm, result, i%totface, i, 1);
+ *mf = *inMF;
+
+ mf->v1+=(i/totface)*totvert;
+ mf->v2+=(i/totface)*totvert;
+ mf->v3+=(i/totface)*totvert;
+ if(mf->v4)
+ mf->v4+=(i/totface)*totvert;
+ }
+
+ CDDM_calc_edges(result);
+ CDDM_calc_normals(result);
+
+ if(psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
+ }
+
+ return result;
+}
+static DerivedMesh *particleInstanceModifier_applyModifierEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData)
+{
+ return particleInstanceModifier_applyModifier(md, ob, derivedData, 0, 1);
+}
+
+/* Explode */
+static void explodeModifier_initData(ModifierData *md)
+{
+ ExplodeModifierData *emd= (ExplodeModifierData*) md;
+
+ emd->facepa=0;
+ emd->flag |= eExplodeFlag_Unborn+eExplodeFlag_Alive+eExplodeFlag_Dead;
+}
+static void explodeModifier_freeData(ModifierData *md)
+{
+ ExplodeModifierData *emd= (ExplodeModifierData*) md;
+
+ if(emd->facepa) MEM_freeN(emd->facepa);
+}
+static void explodeModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ExplodeModifierData *emd= (ExplodeModifierData*) md;
+ ExplodeModifierData *temd= (ExplodeModifierData*) target;
+
+ temd->facepa = 0;
+ temd->flag = emd->flag;
+}
+static int explodeModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
+{
+ ExplodeModifierData *emd= (ExplodeModifierData*) md;
+ CustomDataMask dataMask = 0;
+
+ if(emd->vgroup)
+ dataMask |= (1 << CD_MDEFORMVERT);
+
+ return dataMask;
+}
+
+/* this should really be put somewhere permanently */
+static float vert_weight(MDeformVert *dvert, int group)
+{
+ MDeformWeight *dw;
+ int i;
+
+ if(dvert) {
+ dw= dvert->dw;
+ for(i= dvert->totweight; i>0; i--, dw++) {
+ if(dw->def_nr == group) return dw->weight;
+ if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/
+ }
+ }
+ return 0.0;
+}
+
+static void explodeModifier_createFacepa(ExplodeModifierData *emd,
+ ParticleSystemModifierData *psmd,
+ Object *ob, DerivedMesh *dm)
+{
+ ParticleSystem *psys=psmd->psys;
+ MFace *fa=0, *mface=0;
+ MVert *mvert = 0;
+ ParticleData *pa;
+ KDTree *tree;
+ float center[3], co[3];
+ int *facepa=0,*vertpa=0,totvert=0,totface=0,totpart=0;
+ int i,p,v1,v2,v3,v4=0;
+
+ mvert = dm->getVertArray(dm);
+ mface = dm->getFaceArray(dm);
+ totface= dm->getNumFaces(dm);
+ totvert= dm->getNumVerts(dm);
+ totpart= psmd->psys->totpart;
+
+ BLI_srandom(psys->seed);
+
+ if(emd->facepa)
+ MEM_freeN(emd->facepa);
+
+ facepa = emd->facepa = MEM_callocN(sizeof(int)*totface, "explode_facepa");
+
+ vertpa = MEM_callocN(sizeof(int)*totvert, "explode_vertpa");
+
+ /* initialize all faces & verts to no particle */
+ for(i=0; i<totface; i++)
+ facepa[i]=totpart;
+
+ for (i=0; i<totvert; i++)
+ vertpa[i]=totpart;
+
+ /* set protected verts */
+ if(emd->vgroup){
+ MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+ float val;
+ if(dvert){
+ for(i=0; i<totvert; i++){
+ val = BLI_frand();
+ val = (1.0f-emd->protect)*val + emd->protect*0.5f;
+ if(val < vert_weight(dvert+i,emd->vgroup-1))
+ vertpa[i] = -1;
+ }
+ }
+ }
+
+ /* make tree of emitter locations */
+ tree=BLI_kdtree_new(totpart);
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
+ BLI_kdtree_insert(tree, p, co, NULL);
+ }
+ BLI_kdtree_balance(tree);
+
+ /* set face-particle-indexes to nearest particle to face center */
+ for(i=0,fa=mface; i<totface; i++,fa++){
+ VecAddf(center,mvert[fa->v1].co,mvert[fa->v2].co);
+ VecAddf(center,center,mvert[fa->v3].co);
+ if(fa->v4){
+ VecAddf(center,center,mvert[fa->v4].co);
+ VecMulf(center,0.25);
+ }
+ else
+ VecMulf(center,0.3333f);
+
+ p= BLI_kdtree_find_nearest(tree,center,NULL,NULL);
+
+ v1=vertpa[fa->v1];
+ v2=vertpa[fa->v2];
+ v3=vertpa[fa->v3];
+ if(fa->v4)
+ v4=vertpa[fa->v4];
+
+ if(v1>=0 && v2>=0 && v3>=0 && (fa->v4==0 || v4>=0))
+ facepa[i]=p;
+
+ if(v1>=0) vertpa[fa->v1]=p;
+ if(v2>=0) vertpa[fa->v2]=p;
+ if(v3>=0) vertpa[fa->v3]=p;
+ if(fa->v4 && v4>=0) vertpa[fa->v4]=p;
+ }
+
+ if(vertpa) MEM_freeN(vertpa);
+ BLI_kdtree_free(tree);
+}
+static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
+ DerivedMesh *splitdm;
+ MFace *mf=0,*df1=0,*df2=0,*df3=0;
+ MFace *mface=CDDM_get_faces(dm);
+ MVert *dupve, *mv;
+ int totvert=dm->getNumVerts(dm);
+ int totface=dm->getNumFaces(dm);
+
+ int *edgesplit = MEM_callocN(sizeof(int)*totvert*totvert,"explode_edgesplit");
+ int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_edgesplit");
+ int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
+ int *facepa = emd->facepa;
+ int *fs, totesplit=0,totfsplit=0,totin=0,curdupvert=0,curdupface=0,curdupin=0;
+ int i,j,v1,v2,v3,v4;
+
+ /* recreate vertpa from facepa calculation */
+ for (i=0,mf=mface; i<totface; i++,mf++) {
+ vertpa[mf->v1]=facepa[i];
+ vertpa[mf->v2]=facepa[i];
+ vertpa[mf->v3]=facepa[i];
+ if(mf->v4)
+ vertpa[mf->v4]=facepa[i];
+ }
+
+ /* mark edges for splitting and how to split faces */
+ for (i=0,mf=mface,fs=facesplit; i<totface; i++,mf++,fs++) {
+ if(mf->v4){
+ v1=vertpa[mf->v1];
+ v2=vertpa[mf->v2];
+ v3=vertpa[mf->v3];
+ v4=vertpa[mf->v4];
+
+ if(v1!=v2){
+ edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+ (*fs)++;
+ }
+
+ if(v2!=v3){
+ edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+ (*fs)++;
+ }
+
+ if(v3!=v4){
+ edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+ (*fs)++;
+ }
+
+ if(v1!=v4){
+ edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+ (*fs)++;
+ }
+
+ if(*fs==2){
+ if((v1==v2 && v3==v4) || (v1==v4 && v2==v3))
+ *fs=1;
+ else if(v1!=v2){
+ if(v1!=v4)
+ edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+ else
+ edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+ }
+ else{
+ if(v1!=v4)
+ edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+ else
+ edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+ }
+ }
+ }
+ }
+
+ /* count splits & reindex */
+ totesplit=totvert;
+ for(j=0; j<totvert; j++){
+ for(i=j+1; i<totvert; i++){
+ if(edgesplit[j*totvert+i])
+ edgesplit[j*totvert+i]=edgesplit[i*totvert+j]=totesplit++;
+ }
+ }
+ /* count new faces due to splitting */
+ for(i=0,fs=facesplit; i<totface; i++,fs++){
+ if(*fs==1)
+ totfsplit+=1;
+ else if(*fs==2)
+ totfsplit+=2;
+ else if(*fs==3)
+ totfsplit+=3;
+ else if(*fs==4){
+ totfsplit+=3;
+
+ mf=dm->getFaceData(dm,i,CD_MFACE);//CDDM_get_face(dm,i);
+
+ if(vertpa[mf->v1]!=vertpa[mf->v2] && vertpa[mf->v2]!=vertpa[mf->v3])
+ totin++;
+ }
+ }
+
+ splitdm= CDDM_from_template(dm, totesplit+totin, dm->getNumEdges(dm),totface+totfsplit);
+
+ /* copy new faces & verts (is it really this painful with custom data??) */
+ for(i=0; i<totvert; i++){
+ MVert source;
+ MVert *dest;
+ dm->getVert(dm, i, &source);
+ dest = CDDM_get_vert(splitdm, i);
+
+ DM_copy_vert_data(dm, splitdm, i, i, 1);
+ *dest = source;
+ }
+ for(i=0; i<totface; i++){
+ MFace source;
+ MFace *dest;
+ dm->getFace(dm, i, &source);
+ dest = CDDM_get_face(splitdm, i);
+
+ DM_copy_face_data(dm, splitdm, i, i, 1);
+ *dest = source;
+ }
+
+ /* override original facepa (original pointer is saved in caller function) */
+ facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
+ memcpy(facepa,emd->facepa,totface*sizeof(int));
+ emd->facepa=facepa;
+
+ /* create new verts */
+ curdupvert=totvert;
+ for(j=0; j<totvert; j++){
+ for(i=j+1; i<totvert; i++){
+ if(edgesplit[j*totvert+i]){
+ mv=CDDM_get_vert(splitdm,j);
+ dupve=CDDM_get_vert(splitdm,edgesplit[j*totvert+i]);
+
+ DM_copy_vert_data(splitdm,splitdm,j,edgesplit[j*totvert+i],1);
+
+ *dupve=*mv;
+
+ mv=CDDM_get_vert(splitdm,i);
+
+ VECADD(dupve->co,dupve->co,mv->co);
+ VecMulf(dupve->co,0.5);
+ }
+ }
+ }
+
+ /* create new faces */
+ curdupface=totface;
+ curdupin=totesplit;
+ for(i=0,fs=facesplit; i<totface; i++,fs++){
+ if(*fs){
+ mf=CDDM_get_face(splitdm,i);
+
+ v1=vertpa[mf->v1];
+ v2=vertpa[mf->v2];
+ v3=vertpa[mf->v3];
+ v4=vertpa[mf->v4];
+ /* ouch! creating new faces & remapping them to new verts is no fun */
+ if(*fs==1){
+ df1=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df1=*mf;
+ curdupface++;
+
+ if(v1==v2){
+ df1->v1=edgesplit[mf->v1*totvert+mf->v4];
+ df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+ mf->v3=df1->v2;
+ mf->v4=df1->v1;
+ }
+ else{
+ df1->v1=edgesplit[mf->v1*totvert+mf->v2];
+ df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+ mf->v2=df1->v1;
+ mf->v3=df1->v4;
+ }
+
+ facepa[i]=v1;
+ facepa[curdupface-1]=v3;
+
+ test_index_face(df1, &splitdm->faceData, curdupface, (df1->v4 ? 4 : 3));
+ }
+ if(*fs==2){
+ df1=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df1=*mf;
+ curdupface++;
+
+ df2=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df2=*mf;
+ curdupface++;
+
+ if(v1!=v2){
+ if(v1!=v4){
+ df1->v1=edgesplit[mf->v1*totvert+mf->v4];
+ df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+ df2->v1=df1->v3=mf->v2;
+ df2->v3=df1->v4=mf->v4;
+ df2->v2=mf->v3;
+
+ mf->v2=df1->v2;
+ mf->v3=df1->v1;
+
+ df2->v4=mf->v4=0;
+
+ facepa[i]=v1;
+ }
+ else{
+ df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+ df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+ df1->v4=mf->v3;
+ df2->v2=mf->v3;
+ df2->v3=mf->v4;
+
+ mf->v1=df1->v2;
+ mf->v3=df1->v3;
+
+ df2->v4=mf->v4=0;
+
+ facepa[i]=v2;
+ }
+ facepa[curdupface-1]=facepa[curdupface-2]=v3;
+ }
+ else{
+ if(v1!=v4){
+ df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+ df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+ df1->v2=mf->v3;
+
+ mf->v1=df1->v4;
+ mf->v2=df1->v3;
+ mf->v3=mf->v4;
+
+ df2->v4=mf->v4=0;
+
+ facepa[i]=v4;
+ }
+ else{
+ df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+ df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+ df1->v1=mf->v4;
+ df1->v2=mf->v2;
+ df2->v3=mf->v4;
+
+ mf->v1=df1->v4;
+ mf->v2=df1->v3;
+
+ df2->v4=mf->v4=0;
+
+ facepa[i]=v3;
+ }
+
+ facepa[curdupface-1]=facepa[curdupface-2]=v1;
+ }
+
+ test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
+ }
+ else if(*fs==3){
+ df1=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df1=*mf;
+ curdupface++;
+
+ df2=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df2=*mf;
+ curdupface++;
+
+ df3=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df3=*mf;
+ curdupface++;
+
+ if(v1==v2){
+ df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
+ df3->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+ df3->v3=df2->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+ df3->v2=mf->v3;
+ df2->v3=mf->v4;
+ df1->v4=df2->v4=df3->v4=0;
+
+ mf->v3=df1->v2;
+ mf->v4=df1->v1;
+
+ facepa[i]=facepa[curdupface-3]=v1;
+ facepa[curdupface-1]=v3;
+ facepa[curdupface-2]=v4;
+ }
+ else if(v2==v3){
+ df3->v1=df2->v3=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
+ df2->v2=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+ df3->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+
+ df3->v3=mf->v4;
+ df2->v1=mf->v1;
+ df1->v4=df2->v4=df3->v4=0;
+
+ mf->v1=df1->v2;
+ mf->v4=df1->v3;
+
+ facepa[i]=facepa[curdupface-3]=v2;
+ facepa[curdupface-1]=v4;
+ facepa[curdupface-2]=v1;
+ }
+ else if(v3==v4){
+ df3->v2=df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
+ df2->v3=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+ df3->v3=df1->v3=edgesplit[mf->v1*totvert+mf->v4];
+
+ df3->v1=mf->v1;
+ df2->v2=mf->v2;
+ df1->v4=df2->v4=df3->v4=0;
+
+ mf->v1=df1->v3;
+ mf->v2=df1->v2;
+
+ facepa[i]=facepa[curdupface-3]=v3;
+ facepa[curdupface-1]=v1;
+ facepa[curdupface-2]=v2;
+ }
+ else{
+ df3->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
+ df3->v3=df2->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+ df2->v3=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+
+ df3->v2=mf->v2;
+ df2->v2=mf->v3;
+ df1->v4=df2->v4=df3->v4=0;
+
+ mf->v2=df1->v1;
+ mf->v3=df1->v3;
+
+ facepa[i]=facepa[curdupface-3]=v1;
+ facepa[curdupface-1]=v2;
+ facepa[curdupface-2]=v3;
+ }
+
+ test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
+ }
+ else if(*fs==4){
+ if(v1!=v2 && v2!=v3){
+
+ /* set new vert to face center */
+ mv=CDDM_get_vert(splitdm,mf->v1);
+ dupve=CDDM_get_vert(splitdm,curdupin);
+ DM_copy_vert_data(splitdm,splitdm,mf->v1,curdupin,1);
+ *dupve=*mv;
+
+ mv=CDDM_get_vert(splitdm,mf->v2);
+ VECADD(dupve->co,dupve->co,mv->co);
+ mv=CDDM_get_vert(splitdm,mf->v3);
+ VECADD(dupve->co,dupve->co,mv->co);
+ mv=CDDM_get_vert(splitdm,mf->v4);
+ VECADD(dupve->co,dupve->co,mv->co);
+ VecMulf(dupve->co,0.25);
+
+
+ df1=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df1=*mf;
+ curdupface++;
+
+ df2=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df2=*mf;
+ curdupface++;
+
+ df3=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df3=*mf;
+ curdupface++;
+
+ df1->v1=edgesplit[mf->v1*totvert+mf->v2];
+ df3->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+
+ df2->v1=edgesplit[mf->v1*totvert+mf->v4];
+ df3->v4=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+
+ df3->v1=df2->v2=df1->v4=curdupin;
+
+ mf->v2=df1->v1;
+ mf->v3=curdupin;
+ mf->v4=df2->v1;
+
+ curdupin++;
+
+ facepa[i]=v1;
+ facepa[curdupface-3]=v2;
+ facepa[curdupface-2]=v3;
+ facepa[curdupface-1]=v4;
+
+ test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
+
+ test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
+ }
+ else{
+ df1=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df1=*mf;
+ curdupface++;
+
+ df2=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df2=*mf;
+ curdupface++;
+
+ df3=CDDM_get_face(splitdm,curdupface);
+ DM_copy_face_data(splitdm,splitdm,i,curdupface,1);
+ *df3=*mf;
+ curdupface++;
+
+ if(v2==v3){
+ df1->v1=edgesplit[mf->v1*totvert+mf->v2];
+ df3->v1=df1->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+ df2->v1=df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+
+ df3->v3=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+
+ df3->v2=mf->v3;
+ df3->v4=0;
+
+ mf->v2=df1->v1;
+ mf->v3=df1->v4;
+ mf->v4=0;
+
+ facepa[i]=v1;
+ facepa[curdupface-3]=facepa[curdupface-2]=v2;
+ facepa[curdupface-1]=v3;
+ }
+ else{
+ df3->v1=df2->v1=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+ df2->v4=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+ df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+
+ df3->v3=df2->v2=edgesplit[mf->v2*totvert+mf->v3];
+
+ df3->v4=0;
+
+ mf->v1=df1->v4;
+ mf->v2=df1->v3;
+ mf->v3=mf->v4;
+ mf->v4=0;
+
+ facepa[i]=v4;
+ facepa[curdupface-3]=facepa[curdupface-2]=v1;
+ facepa[curdupface-1]=v2;
+ }
+
+ test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
+ test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
+ }
+ }
+
+ test_index_face(df1, &splitdm->faceData, i, (df1->v4 ? 4 : 3));
+ }
+ }
+
+ MEM_freeN(edgesplit);
+ MEM_freeN(facesplit);
+ MEM_freeN(vertpa);
+
+ return splitdm;
+
+}
+static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
+ ParticleSystemModifierData *psmd, Object *ob,
+ DerivedMesh *to_explode)
+{
+ DerivedMesh *explode, *dm=to_explode;
+ MFace *mf=0;
+ MVert *dupvert=0;
+ ParticleSettings *part=psmd->psys->part;
+ ParticleData *pa, *pars=psmd->psys->particles;
+ ParticleKey state;
+ float *vertco=0, imat[4][4];
+ float loc0[3], nor[3];
+ float timestep, cfra;
+ int *facepa=emd->facepa, *vertpa=0;
+ int totdup=0,totvert=0,totface=0,totpart=0;
+ int i, j, v, mindex=0;
+
+ totface= dm->getNumFaces(dm);
+ totvert= dm->getNumVerts(dm);
+ totpart= psmd->psys->totpart;
+
+ timestep= psys_get_timestep(part);
+
+ if(part->flag & PART_GLOB_TIME)
+ cfra=bsystem_time(0,(float)G.scene->r.cfra,0.0);
+ else
+ cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0);
+
+ /* table for vertice <-> particle relations (row totpart+1 is for yet unexploded verts) */
+ vertpa = MEM_callocN(sizeof(int)*(totpart+1)*totvert, "explode_vertpatab");
+ for(i=0; i<(totpart+1)*totvert; i++)
+ vertpa[i] = -1;
+
+ for (i=0; i<totface; i++) {
+ if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
+ mindex = totpart*totvert;
+ else
+ mindex = facepa[i]*totvert;
+
+ mf=CDDM_get_face(dm,i);
+
+ /*set face vertices to exist in particle group*/
+ vertpa[mindex+mf->v1] = 1;
+ vertpa[mindex+mf->v2] = 1;
+ vertpa[mindex+mf->v3] = 1;
+ if(mf->v4)
+ vertpa[mindex+mf->v4] = 1;
+ }
+
+ /*make new vertice indexes & count total vertices after duplication*/
+ for(i=0; i<(totpart+1)*totvert; i++){
+ if(vertpa[i] != -1)
+ vertpa[i] = totdup++;
+ }
+
+ /*the final duplicated vertices*/
+ explode= CDDM_from_template(dm, totdup, 0,totface);
+ dupvert= CDDM_get_verts(explode);
+
+ /* getting back to object space */
+ Mat4Invert(imat,ob->obmat);
+
+ psmd->psys->lattice = psys_get_lattice(ob, psmd->psys);
+
+ /*duplicate & displace vertices*/
+ for(i=0, pa=pars; i<=totpart; i++, pa++){
+ if(i!=totpart){
+ psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+ Mat4MulVecfl(ob->obmat,loc0);
+
+ state.time=cfra;
+ psys_get_particle_state(ob,psmd->psys,i,&state,1);
+ }
+
+ for(j=0; j<totvert; j++){
+ v=vertpa[i*totvert+j];
+ if(v != -1) {
+ MVert source;
+ MVert *dest;
+
+ dm->getVert(dm, j, &source);
+ dest = CDDM_get_vert(explode,v);
+
+ DM_copy_vert_data(dm,explode,j,v,1);
+ *dest = source;
+
+ if(i!=totpart){
+ vertco=CDDM_get_vert(explode,v)->co;
+
+ Mat4MulVecfl(ob->obmat,vertco);
+
+ VECSUB(vertco,vertco,loc0);
+
+ /* apply rotation, size & location */
+ QuatMulVecf(state.rot,vertco);
+ VecMulf(vertco,pa->size);
+ VECADD(vertco,vertco,state.co);
+
+ Mat4MulVecfl(imat,vertco);
+ }
+ }
+ }
+ }
+
+ /*map new vertices to faces*/
+ for (i=0; i<totface; i++) {
+ MFace source;
+ int orig_v4;
+
+ if(facepa[i]!=totpart)
+ {
+ pa=pars+facepa[i];
+
+ if(pa->alive==PARS_UNBORN && (emd->flag&eExplodeFlag_Unborn)==0) continue;
+ if(pa->alive==PARS_ALIVE && (emd->flag&eExplodeFlag_Alive)==0) continue;
+ if(pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0) continue;
+ }
+
+ dm->getFace(dm,i,&source);
+ mf=CDDM_get_face(explode,i);
+
+ orig_v4 = source.v4;
+
+ if(facepa[i]!=totpart && cfra <= pa->time)
+ mindex = totpart*totvert;
+ else
+ mindex = facepa[i]*totvert;
+
+ source.v1 = vertpa[mindex+source.v1];
+ source.v2 = vertpa[mindex+source.v2];
+ source.v3 = vertpa[mindex+source.v3];
+ if(source.v4)
+ source.v4 = vertpa[mindex+source.v4];
+
+ DM_copy_face_data(dm,explode,i,i,1);
+
+ *mf = source;
+
+ test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
+ }
+
+
+ /* cleanup */
+ if(vertpa) MEM_freeN(vertpa);
+
+ /* finalization */
+ CDDM_calc_edges(explode);
+ CDDM_calc_normals(explode);
+
+ if(psmd->psys->lattice){
+ end_latt_deform();
+ psmd->psys->lattice=0;
+ }
+
+ return explode;
+}
+
+static ParticleSystemModifierData * explodeModifier_findPrecedingParticlesystem(Object *ob, ModifierData *emd)
+{
+ ModifierData *md;
+ ParticleSystemModifierData *psmd=0;
+
+ for (md=ob->modifiers.first; emd!=md; md=md->next){
+ if(md->type==eModifierType_ParticleSystem)
+ psmd= (ParticleSystemModifierData*) md;
+ }
+ return psmd;
+}
+static DerivedMesh * explodeModifier_applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ int useRenderParams, int isFinalCalc)
+{
+ DerivedMesh *dm = derivedData;
+ ExplodeModifierData *emd= (ExplodeModifierData*) md;
+ ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);;
+
+ if(psmd){
+ ParticleSystem * psys=psmd->psys;
+
+ if(psys==0 || psys->totpart==0) return derivedData;
+ if(psys->part==0 || psys->particles==0) return derivedData;
+
+ /* 1. find faces to be exploded if needed */
+ if(emd->facepa==0
+ || psmd->flag&eParticleSystemFlag_Pars
+ || emd->flag&eExplodeFlag_CalcFaces
+ || MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumFaces(dm)){
+ if(psmd->flag & eParticleSystemFlag_Pars)
+ psmd->flag &= ~eParticleSystemFlag_Pars;
+
+ if(emd->flag & eExplodeFlag_CalcFaces)
+ emd->flag &= ~eExplodeFlag_CalcFaces;
+
+ explodeModifier_createFacepa(emd,psmd,ob,derivedData);
+ }
+
+ /* 2. create new mesh */
+ if(emd->flag & eExplodeFlag_EdgeSplit){
+ int *facepa = emd->facepa;
+ DerivedMesh *splitdm=explodeModifier_splitEdges(emd,dm);
+ DerivedMesh *explode=explodeModifier_explodeMesh(emd,psmd,ob,splitdm);
+
+ MEM_freeN(emd->facepa);
+ emd->facepa=facepa;
+ splitdm->release(splitdm);
+ return explode;
+ }
+ else
+ return explodeModifier_explodeMesh(emd,psmd,ob,derivedData);
+ }
+ return derivedData;
+}
+/* MeshDeform */
+
+static void meshdeformModifier_initData(ModifierData *md)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ mmd->gridsize= 5;
+}
+
+static void meshdeformModifier_freeData(ModifierData *md)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ if(mmd->bindweights) MEM_freeN(mmd->bindweights);
+ if(mmd->bindcos) MEM_freeN(mmd->bindcos);
+ if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
+ if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+ if(mmd->dynverts) MEM_freeN(mmd->dynverts);
+}
+
+static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+ MeshDeformModifierData *tmmd = (MeshDeformModifierData*) target;
+
+ tmmd->gridsize = mmd->gridsize;
+ tmmd->object = mmd->object;
+}
+
+CustomDataMask meshdeformModifier_requiredDataMask(ModifierData *md)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if(mmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
+
+ return dataMask;
+}
+
+static int meshdeformModifier_isDisabled(ModifierData *md)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ return !mmd->object;
+}
+
+static void meshdeformModifier_foreachObjectLink(
+ ModifierData *md, Object *ob,
+ void (*walk)(void *userData, Object *ob, Object **obpoin),
+ void *userData)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ walk(userData, ob, &mmd->object);
+}
+
+static void meshdeformModifier_updateDepgraph(
+ ModifierData *md, DagForest *forest, Object *ob,
+ DagNode *obNode)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ if (mmd->object) {
+ DagNode *curNode = dag_get_node(forest, mmd->object);
+
+ dag_add_relation(forest, curNode, obNode,
+ DAG_RL_DATA_DATA|DAG_RL_OB_DATA|DAG_RL_DATA_OB|DAG_RL_OB_OB);
+ }
+}
+
+static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec)
+{
+ MDefCell *cell;
+ MDefInfluence *inf;
+ float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz;
+ float weight, cageweight, totweight, *cageco;
+ int i, j, a, x, y, z, size;
+
+ co[0]= co[1]= co[2]= 0.0f;
+ totweight= 0.0f;
+ size= mmd->dyngridsize;
+
+ for(i=0; i<3; i++) {
+ gridvec[i]= (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth*0.5f)/mmd->dyncellwidth;
+ ivec[i]= (int)gridvec[i];
+ dvec[i]= gridvec[i] - ivec[i];
+ }
+
+ for(i=0; i<8; i++) {
+ if(i & 1) { x= ivec[0]+1; wx= dvec[0]; }
+ else { x= ivec[0]; wx= 1.0f-dvec[0]; }
+
+ if(i & 2) { y= ivec[1]+1; wy= dvec[1]; }
+ else { y= ivec[1]; wy= 1.0f-dvec[1]; }
+
+ if(i & 4) { z= ivec[2]+1; wz= dvec[2]; }
+ else { z= ivec[2]; wz= 1.0f-dvec[2]; }
+
+ CLAMP(x, 0, size-1);
+ CLAMP(y, 0, size-1);
+ CLAMP(z, 0, size-1);
+
+ a= x + y*size + z*size*size;
+ weight= wx*wy*wz;
+
+ cell= &mmd->dyngrid[a];
+ inf= mmd->dyninfluences + cell->offset;
+ for(j=0; j<cell->totinfluence; j++, inf++) {
+ cageco= dco[inf->vertex];
+ cageweight= weight*inf->weight;
+ co[0] += cageweight*cageco[0];
+ co[1] += cageweight*cageco[1];
+ co[2] += cageweight*cageco[2];
+ totweight += cageweight;
+ }
+ }
+
+ VECCOPY(vec, co);
+
+ return totweight;
+}
+
+static void meshdeformModifier_do(
+ ModifierData *md, Object *ob, DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+ float imat[4][4], cagemat[4][4], icagemat[4][4], iobmat[3][3];
+ float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
+ int a, b, totvert, totcagevert, defgrp_index;
+ DerivedMesh *tmpdm, *cagedm;
+ MDeformVert *dvert = NULL;
+ MDeformWeight *dw;
+ MVert *cagemvert;
+
+ if(!mmd->object || (!mmd->bindcos && !mmd->needbind))
+ return;
+
+ /* get cage derivedmesh */
+ if(mmd->object == G.obedit) {
+ tmpdm= editmesh_get_derived_cage_and_final(&cagedm, 0);
+ if(tmpdm)
+ tmpdm->release(tmpdm);
+ }
+ else
+ cagedm= mmd->object->derivedFinal;
+
+ if(!cagedm)
+ return;
+
+ /* compute matrices to go in and out of cage object space */
+ Mat4Invert(imat, mmd->object->obmat);
+ Mat4MulMat4(cagemat, ob->obmat, imat);
+ Mat4Invert(icagemat, cagemat);
+ Mat3CpyMat4(iobmat, icagemat);
+
+ /* bind weights if needed */
+ if(!mmd->bindcos)
+ harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
+
+ /* verify we have compatible weights */
+ totvert= numVerts;
+ totcagevert= cagedm->getNumVerts(cagedm);
+
+ if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcos) {
+ cagedm->release(cagedm);
+ return;
+ }
+
+ /* setup deformation data */
+ cagemvert= cagedm->getVertArray(cagedm);
+ weights= mmd->bindweights;
+ bindcos= (float(*)[3])mmd->bindcos;
+
+ dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco");
+ for(a=0; a<totcagevert; a++) {
+ /* get cage vertex in world space with binding transform */
+ VECCOPY(co, cagemvert[a].co);
+
+ if(G.rt != 527) {
+ Mat4MulVecfl(mmd->bindmat, co);
+ /* compute difference with world space bind coord */
+ VECSUB(dco[a], co, bindcos[a]);
+ }
+ else
+ VECCOPY(dco[a], co)
+ }
+
+ defgrp_index = -1;
+
+ if(mmd->defgrp_name[0]) {
+ bDeformGroup *def;
+
+ for(a=0, def=ob->defbase.first; def; def=def->next, a++) {
+ if(!strcmp(def->name, mmd->defgrp_name)) {
+ defgrp_index= a;
+ break;
+ }
+ }
+
+ if (defgrp_index >= 0)
+ dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
+ }
+
+ /* do deformation */
+ fac= 1.0f;
+
+ for(b=0; b<totvert; b++) {
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
+ if(!mmd->dynverts[b])
+ continue;
+
+ if(dvert) {
+ for(dw=NULL, a=0; a<dvert[b].totweight; a++) {
+ if(dvert[b].dw[a].def_nr == defgrp_index) {
+ dw = &dvert[b].dw[a];
+ break;
+ }
+ }
+
+ if(mmd->flag & MOD_MDEF_INVERT_VGROUP) {
+ if(!dw) fac= 1.0f;
+ else if(dw->weight == 1.0f) continue;
+ else fac=1.0f-dw->weight;
+ }
+ else {
+ if(!dw) continue;
+ else fac= dw->weight;
+ }
+ }
+
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
+ /* transform coordinate into cage's local space */
+ VECCOPY(co, vertexCos[b]);
+ Mat4MulVecfl(cagemat, co);
+ totweight= meshdeform_dynamic_bind(mmd, dco, co);
+ }
+ else {
+ totweight= 0.0f;
+ co[0]= co[1]= co[2]= 0.0f;
+
+ for(a=0; a<totcagevert; a++) {
+ weight= weights[a + b*totcagevert];
+ co[0]+= weight*dco[a][0];
+ co[1]+= weight*dco[a][1];
+ co[2]+= weight*dco[a][2];
+ totweight += weight;
+ }
+ }
+
+ if(totweight > 0.0f) {
+ VecMulf(co, fac/totweight);
+ Mat3MulVecfl(iobmat, co);
+ if(G.rt != 527)
+ VECADD(vertexCos[b], vertexCos[b], co)
+ else
+ VECCOPY(vertexCos[b], co)
+ }
+ }
+
+ /* release cage derivedmesh */
+ MEM_freeN(dco);
+ cagedm->release(cagedm);
+}
+
+static void meshdeformModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts)
+{
+ DerivedMesh *dm;
+
+ if(!derivedData && ob->type==OB_MESH)
+ dm= CDDM_from_mesh(ob->data, ob);
+ else
+ dm= derivedData;
+
+ modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
+ meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
+
+ if(dm != derivedData)
+ dm->release(dm);
+}
+
+static void meshdeformModifier_deformVertsEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+ DerivedMesh *dm;
+
+ if(!derivedData && ob->type == OB_MESH)
+ dm = CDDM_from_editmesh(editData, ob->data);
+ else
+ dm = derivedData;
+
+ meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
+
+ if(dm != derivedData)
+ dm->release(dm);
+}
+
/***/
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -4963,6 +7021,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
| eModifierTypeFlag_EnableInEditmode;
mti->initData = mirrorModifier_initData;
mti->copyData = mirrorModifier_copyData;
+ mti->foreachObjectLink = mirrorModifier_foreachObjectLink;
+ mti->updateDepgraph = mirrorModifier_updateDepgraph;
mti->applyModifier = mirrorModifier_applyModifier;
mti->applyModifierEM = mirrorModifier_applyModifierEM;
@@ -4977,6 +7037,17 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->applyModifier = edgesplitModifier_applyModifier;
mti->applyModifierEM = edgesplitModifier_applyModifierEM;
+ mti = INIT_TYPE(Bevel);
+ mti->type = eModifierTypeType_Constructive;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_SupportsEditmode
+ | eModifierTypeFlag_EnableInEditmode;
+ mti->initData = bevelModifier_initData;
+ mti->copyData = bevelModifier_copyData;
+ mti->requiredDataMask = bevelModifier_requiredDataMask;
+ mti->applyModifier = bevelModifier_applyModifier;
+ mti->applyModifierEM = bevelModifier_applyModifierEM;
+
mti = INIT_TYPE(Displace);
mti->type = eModifierTypeType_OnlyDeform;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsEditmode;
@@ -5060,6 +7131,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->updateDepgraph = armatureModifier_updateDepgraph;
mti->deformVerts = armatureModifier_deformVerts;
mti->deformVertsEM = armatureModifier_deformVertsEM;
+ mti->deformMatricesEM = armatureModifier_deformMatricesEM;
mti = INIT_TYPE(Hook);
mti->type = eModifierTypeType_OnlyDeform;
@@ -5080,16 +7152,95 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsCVs
| eModifierTypeFlag_RequiresOriginalData;
mti->deformVerts = softbodyModifier_deformVerts;
+
+ mti = INIT_TYPE(Cloth);
+ mti->type = eModifierTypeType_Nonconstructive;
+ mti->initData = clothModifier_initData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_UsesPointCache;
+ mti->dependsOnTime = clothModifier_dependsOnTime;
+ mti->freeData = clothModifier_freeData;
+ mti->requiredDataMask = clothModifier_requiredDataMask;
+ mti->copyData = clothModifier_copyData;
+ mti->applyModifier = clothModifier_applyModifier;
+ mti->updateDepgraph = clothModifier_updateDepgraph;
+
+ mti = INIT_TYPE(Collision);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->initData = collisionModifier_initData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->dependsOnTime = collisionModifier_dependsOnTime;
+ mti->freeData = collisionModifier_freeData;
+ mti->deformVerts = collisionModifier_deformVerts;
+ // mti->copyData = collisionModifier_copyData;
mti = INIT_TYPE(Boolean);
mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_RequiresOriginalData
+ | eModifierTypeFlag_UsesPointCache;
mti->copyData = booleanModifier_copyData;
mti->isDisabled = booleanModifier_isDisabled;
mti->applyModifier = booleanModifier_applyModifier;
mti->foreachObjectLink = booleanModifier_foreachObjectLink;
mti->updateDepgraph = booleanModifier_updateDepgraph;
+ mti = INIT_TYPE(MeshDeform);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->flags = eModifierTypeFlag_AcceptsCVs
+ | eModifierTypeFlag_SupportsEditmode;
+ mti->initData = meshdeformModifier_initData;
+ mti->freeData = meshdeformModifier_freeData;
+ mti->copyData = meshdeformModifier_copyData;
+ mti->requiredDataMask = meshdeformModifier_requiredDataMask;
+ mti->isDisabled = meshdeformModifier_isDisabled;
+ mti->foreachObjectLink = meshdeformModifier_foreachObjectLink;
+ mti->updateDepgraph = meshdeformModifier_updateDepgraph;
+ mti->deformVerts = meshdeformModifier_deformVerts;
+ mti->deformVertsEM = meshdeformModifier_deformVertsEM;
+
+ mti = INIT_TYPE(ParticleSystem);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_SupportsMapping
+ | eModifierTypeFlag_UsesPointCache;
+#if 0
+ | eModifierTypeFlag_SupportsEditmode;
+ |eModifierTypeFlag_EnableInEditmode;
+#endif
+ mti->initData = particleSystemModifier_initData;
+ mti->freeData = particleSystemModifier_freeData;
+ mti->copyData = particleSystemModifier_copyData;
+ mti->deformVerts = particleSystemModifier_deformVerts;
+#if 0
+ mti->deformVertsEM = particleSystemModifier_deformVertsEM;
+#endif
+ mti->requiredDataMask = particleSystemModifier_requiredDataMask;
+
+ mti = INIT_TYPE(ParticleInstance);
+ mti->type = eModifierTypeType_Constructive;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_SupportsMapping
+ | eModifierTypeFlag_SupportsEditmode
+ | eModifierTypeFlag_EnableInEditmode;
+ mti->initData = particleInstanceModifier_initData;
+ mti->copyData = particleInstanceModifier_copyData;
+ mti->dependsOnTime = particleInstanceModifier_dependsOnTime;
+ mti->foreachObjectLink = particleInstanceModifier_foreachObjectLink;
+ mti->applyModifier = particleInstanceModifier_applyModifier;
+ mti->applyModifierEM = particleInstanceModifier_applyModifierEM;
+ mti->updateDepgraph = particleInstanceModifier_updateDepgraph;
+
+ mti = INIT_TYPE(Explode);
+ mti->type = eModifierTypeType_Nonconstructive;
+ mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->initData = explodeModifier_initData;
+ mti->freeData = explodeModifier_freeData;
+ mti->copyData = explodeModifier_copyData;
+ mti->dependsOnTime = explodeModifier_dependsOnTime;
+ mti->requiredDataMask = explodeModifier_requiredDataMask;
+ mti->applyModifier = explodeModifier_applyModifier;
+
typeArrInit = 0;
#undef INIT_TYPE
}
@@ -5143,9 +7294,8 @@ int modifier_supportsMapping(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- return ( (mti->flags & eModifierTypeFlag_SupportsEditmode) &&
- ( (mti->type==eModifierTypeType_OnlyDeform ||
- (mti->flags & eModifierTypeFlag_SupportsMapping))) );
+ return (mti->type==eModifierTypeType_OnlyDeform ||
+ (mti->flags & eModifierTypeFlag_SupportsMapping));
}
ModifierData *modifiers_findByType(Object *ob, ModifierType type)
@@ -5261,6 +7411,7 @@ int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
if (!(md->mode & eModifierMode_Editmode)) continue;
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
+ if (md->mode & eModifierMode_DisableTemporary) continue;
if (!modifier_supportsMapping(md))
break;
@@ -5281,6 +7432,20 @@ int modifiers_isSoftbodyEnabled(Object *ob)
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
}
+int modifiers_isClothEnabled(Object *ob)
+{
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
+
+ return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
+}
+
+int modifiers_isParticleEnabled(Object *ob)
+{
+ ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
+
+ return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
+}
+
LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
{
LinkNode *dataMasks = NULL;
@@ -5440,20 +7605,61 @@ int modifiers_usesArmature(Object *ob, bArmature *arm)
return 0;
}
+int modifier_isDeformer(ModifierData *md)
+{
+ if (md->type==eModifierType_Armature)
+ return 1;
+ if (md->type==eModifierType_Curve)
+ return 1;
+ if (md->type==eModifierType_Lattice)
+ return 1;
+
+ return 0;
+}
+
int modifiers_isDeformed(Object *ob)
{
ModifierData *md = modifiers_getVirtualModifierList(ob);
for (; md; md=md->next) {
if(ob==G.obedit && (md->mode & eModifierMode_Editmode)==0);
- else {
- if (md->type==eModifierType_Armature)
- return 1;
- if (md->type==eModifierType_Curve)
- return 1;
- if (md->type==eModifierType_Lattice)
- return 1;
+ else if(modifier_isDeformer(md))
+ return 1;
+ }
+ return 0;
+}
+
+int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
+{
+ int i= 0;
+ ModifierData *md;
+
+ for (md=ob->modifiers.first; (md && md_seek!=md); md=md->next, i++);
+ if (!md) return -1; /* modifier isnt in the object */
+ 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) {
+ ArmatureModifierData *amd= (ArmatureModifierData*)md;
+
+ if(amd->prevCos)
+ MEM_freeN(amd->prevCos);
+ }
+}
+
+
diff --git a/source/blender/src/multires-firstlevel.c b/source/blender/blenkernel/intern/multires-firstlevel.c
index 2be867b5db0..778dd6f9c77 100644
--- a/source/blender/src/multires-firstlevel.c
+++ b/source/blender/blenkernel/intern/multires-firstlevel.c
@@ -43,13 +43,13 @@
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BLI_editVert.h"
#include "MEM_guardedalloc.h"
#include "blendef.h"
-#include "multires.h"
#include <string.h>
@@ -392,7 +392,6 @@ void multires_delete_layer(Mesh *me, CustomData *cd, const int type, int n)
}
}
-MultiresLevel *current_level(Multires *mr);
void multires_add_layer(Mesh *me, CustomData *cd, const int type, const int n)
{
if(me && me->mr && cd) {
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
new file mode 100644
index 00000000000..3a8847a5be1
--- /dev/null
+++ b/source/blender/blenkernel/intern/multires.c
@@ -0,0 +1,1305 @@
+/*
+ * $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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_vec_types.h"
+
+#include "BIF_editmesh.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_multires.h"
+
+#include "blendef.h"
+#include "editmesh.h"
+
+#include <math.h>
+
+/* Returns the active multires level (currently applied to the mesh) */
+MultiresLevel *current_level(Multires *mr)
+{
+ return BLI_findlink(&mr->levels, mr->current - 1);
+}
+
+/* Returns the nth multires level, starting at 1 */
+MultiresLevel *multires_level_n(Multires *mr, int n)
+{
+ if(mr)
+ return BLI_findlink(&mr->levels, n - 1);
+ else
+ return NULL;
+}
+
+/* Free and clear the temporary connectivity data */
+static void multires_free_temp_data(MultiresLevel *lvl)
+{
+ if(lvl) {
+ if(lvl->edge_boundary_states) MEM_freeN(lvl->edge_boundary_states);
+ if(lvl->vert_edge_map) MEM_freeN(lvl->vert_edge_map);
+ if(lvl->vert_face_map) MEM_freeN(lvl->vert_face_map);
+ if(lvl->map_mem) MEM_freeN(lvl->map_mem);
+
+ lvl->edge_boundary_states = NULL;
+ lvl->vert_edge_map = lvl->vert_face_map = NULL;
+ lvl->map_mem = NULL;
+ }
+}
+
+/* Does not actually free lvl itself */
+void multires_free_level(MultiresLevel *lvl)
+{
+ if(lvl) {
+ if(lvl->faces) MEM_freeN(lvl->faces);
+ if(lvl->edges) MEM_freeN(lvl->edges);
+ if(lvl->colfaces) MEM_freeN(lvl->colfaces);
+
+ multires_free_temp_data(lvl);
+ }
+}
+
+void multires_free(Multires *mr)
+{
+ if(mr) {
+ MultiresLevel* lvl= mr->levels.first;
+
+ /* Free the first-level data */
+ if(lvl) {
+ CustomData_free(&mr->vdata, lvl->totvert);
+ CustomData_free(&mr->fdata, lvl->totface);
+ MEM_freeN(mr->edge_flags);
+ MEM_freeN(mr->edge_creases);
+ }
+
+ while(lvl) {
+ multires_free_level(lvl);
+ lvl= lvl->next;
+ }
+
+ MEM_freeN(mr->verts);
+
+ BLI_freelistN(&mr->levels);
+
+ MEM_freeN(mr);
+ }
+}
+
+static MultiresLevel *multires_level_copy(MultiresLevel *orig)
+{
+ if(orig) {
+ MultiresLevel *lvl= MEM_dupallocN(orig);
+
+ lvl->next= lvl->prev= NULL;
+ lvl->faces= MEM_dupallocN(orig->faces);
+ lvl->colfaces= MEM_dupallocN(orig->colfaces);
+ lvl->edges= MEM_dupallocN(orig->edges);
+ lvl->edge_boundary_states = NULL;
+ lvl->vert_edge_map= lvl->vert_face_map= NULL;
+ lvl->map_mem= NULL;
+
+ return lvl;
+ }
+ return NULL;
+}
+
+Multires *multires_copy(Multires *orig)
+{
+ const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT;
+
+ if(orig) {
+ Multires *mr= MEM_dupallocN(orig);
+ MultiresLevel *lvl;
+
+ mr->levels.first= mr->levels.last= NULL;
+
+ for(lvl= orig->levels.first; lvl; lvl= lvl->next)
+ BLI_addtail(&mr->levels, multires_level_copy(lvl));
+
+ mr->verts= MEM_dupallocN(orig->verts);
+
+ lvl= mr->levels.first;
+ if(lvl) {
+ CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert);
+ CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface);
+ mr->edge_flags= MEM_dupallocN(orig->edge_flags);
+ mr->edge_creases= MEM_dupallocN(orig->edge_creases);
+ }
+
+ return mr;
+ }
+ return NULL;
+}
+
+static void multires_get_vert(MVert *out, EditVert *eve, MVert *m, int i)
+{
+ if(eve) {
+ VecCopyf(out->co, eve->co);
+ out->flag= 0;
+ if(eve->f & SELECT) out->flag |= 1;
+ if(eve->h) out->flag |= ME_HIDE;
+ eve->tmp.l= i;
+ }
+ else
+ *out= *m;
+}
+
+void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease)
+{
+ if(!eed || !flag) return;
+
+ /* Would be nice if EditMesh edge flags could be unified with Mesh flags! */
+ *flag= (eed->f & SELECT) | ME_EDGERENDER;
+ if(eed->f2<2) *flag |= ME_EDGEDRAW;
+ if(eed->f2==0) *flag |= ME_LOOSEEDGE;
+ if(eed->sharp) *flag |= ME_SHARP;
+ if(eed->seam) *flag |= ME_SEAM;
+ if(eed->h & EM_FGON) *flag |= ME_FGON;
+ if(eed->h & 1) *flag |= ME_HIDE;
+
+ *crease= (char)(255.0*eed->crease);
+}
+
+static void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease)
+{
+ if(eed) {
+ e->v[0]= eed->v1->tmp.l;
+ e->v[1]= eed->v2->tmp.l;
+ eed_to_medge_flag(eed, flag, crease);
+ } else {
+ e->v[0]= m->v1;
+ e->v[1]= m->v2;
+ *flag= m->flag;
+ *crease= m->crease;
+ }
+}
+
+static void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
+{
+ if(efa) {
+ MFace tmp;
+ int j;
+ tmp.v1= efa->v1->tmp.l;
+ tmp.v2= efa->v2->tmp.l;
+ tmp.v3= efa->v3->tmp.l;
+ tmp.v4= 0;
+ if(efa->v4) tmp.v4= efa->v4->tmp.l;
+ test_index_face(&tmp, NULL, 0, efa->v4?4:3);
+ for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
+
+ /* Flags */
+ f->flag= efa->flag;
+ if(efa->f & 1) f->flag |= ME_FACE_SEL;
+ else f->flag &= ~ME_FACE_SEL;
+ if(efa->h) f->flag |= ME_HIDE;
+ f->mat_nr= efa->mat_nr;
+ } else {
+ f->v[0]= m->v1;
+ f->v[1]= m->v2;
+ f->v[2]= m->v3;
+ f->v[3]= m->v4;
+ f->flag= m->flag;
+ f->mat_nr= m->mat_nr;
+ }
+}
+
+/* For manipulating vertex colors / uvs */
+static void mcol_to_multires(MultiresColFace *mrf, MCol *mcol)
+{
+ char i;
+ for(i=0; i<4; ++i) {
+ mrf->col[i].a= mcol[i].a;
+ mrf->col[i].r= mcol[i].r;
+ mrf->col[i].g= mcol[i].g;
+ mrf->col[i].b= mcol[i].b;
+ }
+}
+
+/* 1 <= count <= 4 */
+static void multires_col_avg(MultiresCol *avg, MultiresCol cols[4], char count)
+{
+ unsigned i;
+ avg->a= avg->r= avg->g= avg->b= 0;
+ for(i=0; i<count; ++i) {
+ avg->a+= cols[i].a;
+ avg->r+= cols[i].r;
+ avg->g+= cols[i].g;
+ avg->b+= cols[i].b;
+ }
+ avg->a/= count;
+ avg->r/= count;
+ avg->g/= count;
+ avg->b/= count;
+}
+
+static void multires_col_avg2(MultiresCol *avg, MultiresCol *c1, MultiresCol *c2)
+{
+ MultiresCol in[2];
+ in[0]= *c1;
+ in[1]= *c2;
+ multires_col_avg(avg,in,2);
+}
+
+void multires_load_cols(Mesh *me)
+{
+ MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *cur;
+ EditMesh *em= G.obedit ? G.editMesh : NULL;
+ CustomData *src= em ? &em->fdata : &me->fdata;
+ EditFace *efa= NULL;
+ unsigned i,j;
+
+ if(!CustomData_has_layer(src, CD_MCOL) && !CustomData_has_layer(src, CD_MTFACE)) return;
+
+ /* Add texcol data */
+ for(cur= me->mr->levels.first; cur; cur= cur->next)
+ if(!cur->colfaces)
+ cur->colfaces= MEM_callocN(sizeof(MultiresColFace)*cur->totface,"ColFaces");
+
+ me->mr->use_col= CustomData_has_layer(src, CD_MCOL);
+
+ if(em) efa= em->faces.first;
+ for(i=0; i<lvl->totface; ++i) {
+ MultiresColFace *f= &lvl->colfaces[i];
+
+ if(me->mr->use_col)
+ mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]);
+
+ if(em) efa= efa->next;
+ }
+
+ /* Update higher levels */
+ lvl= lvl->next;
+ while(lvl) {
+ MultiresColFace *cf= lvl->colfaces;
+ for(i=0; i<lvl->prev->totface; ++i) {
+ const char sides= lvl->prev->faces[i].v[3]?4:3;
+ MultiresCol cntr;
+
+ /* Find average color of 4 (or 3 for triangle) verts */
+ multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides);
+
+ for(j=0; j<sides; ++j) {
+ MultiresColFace *pf= &lvl->prev->colfaces[i];
+
+ multires_col_avg2(&cf->col[0],
+ &pf->col[j],
+ &pf->col[j==0?sides-1:j-1]);
+ cf->col[1]= pf->col[j];
+ multires_col_avg2(&cf->col[2],
+ &pf->col[j],
+ &pf->col[j==sides-1?0:j+1]);
+ cf->col[3]= cntr;
+
+ ++cf;
+ }
+ }
+ lvl= lvl->next;
+ }
+
+ /* Update lower levels */
+ lvl= me->mr->levels.last;
+ lvl= lvl->prev;
+ while(lvl) {
+ unsigned curf= 0;
+ for(i=0; i<lvl->totface; ++i) {
+ MultiresFace *f= &lvl->faces[i];
+ for(j=0; j<(f->v[3]?4:3); ++j) {
+ lvl->colfaces[i].col[j]= lvl->next->colfaces[curf].col[1];
+ ++curf;
+ }
+ }
+ lvl= lvl->prev;
+ }
+}
+
+void multires_create(Object *ob, Mesh *me)
+{
+ MultiresLevel *lvl;
+ EditMesh *em= G.obedit ? G.editMesh : NULL;
+ EditVert *eve= NULL;
+ EditFace *efa= NULL;
+ EditEdge *eed= NULL;
+ int i;
+
+ lvl= MEM_callocN(sizeof(MultiresLevel), "multires level");
+
+ if(me->pv) mesh_pmv_off(ob, me);
+
+ me->mr= MEM_callocN(sizeof(Multires), "multires data");
+
+ BLI_addtail(&me->mr->levels,lvl);
+ me->mr->current= 1;
+ me->mr->level_count= 1;
+ me->mr->edgelvl= 1;
+ me->mr->pinlvl= 1;
+ me->mr->renderlvl= 1;
+
+ /* Load mesh (or editmesh) into multires data */
+
+ /* Load vertices and vdata (MDeformVerts) */
+ lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert;
+ me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
+ multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata,
+ &me->mr->vdata, CD_MDEFORMVERT);
+ if(em) eve= em->verts.first;
+ for(i=0; i<lvl->totvert; ++i) {
+ multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
+ if(em) eve= eve->next;
+ }
+
+ /* Load faces and fdata (MTFaces) */
+ lvl->totface= em ? BLI_countlist(&em->faces) : me->totface;
+ lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
+ multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata,
+ &me->mr->fdata, CD_MTFACE);
+ if(em) efa= em->faces.first;
+ for(i=0; i<lvl->totface; ++i) {
+ multires_get_face(&lvl->faces[i], efa, &me->mface[i]);
+ if(em) efa= efa->next;
+ }
+
+ /* Load edges and edge_flags */
+ lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge;
+ lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
+ me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags");
+ me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases");
+ if(em) eed= em->edges.first;
+ for(i=0; i<lvl->totedge; ++i) {
+ multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]);
+ if(em) eed= eed->next;
+ }
+
+ multires_load_cols(me);
+}
+
+typedef struct MultiresMapNode {
+ struct MultiresMapNode *next, *prev;
+ unsigned Index;
+} MultiresMapNode;
+
+/* Produces temporary connectivity data for the multires lvl */
+static void multires_calc_temp_data(MultiresLevel *lvl)
+{
+ unsigned i, j, emax;
+ MultiresMapNode *indexnode= NULL;
+
+ lvl->map_mem= MEM_mallocN(sizeof(MultiresMapNode)*(lvl->totedge*2 + lvl->totface*4), "map_mem");
+ indexnode= lvl->map_mem;
+
+ /* edge map */
+ lvl->vert_edge_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_edge_map");
+ for(i=0; i<lvl->totedge; ++i) {
+ for(j=0; j<2; ++j, ++indexnode) {
+ indexnode->Index= i;
+ BLI_addtail(&lvl->vert_edge_map[lvl->edges[i].v[j]], indexnode);
+ }
+ }
+
+ /* face map */
+ lvl->vert_face_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_face_map");
+ for(i=0; i<lvl->totface; ++i){
+ for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j, ++indexnode) {
+ indexnode->Index= i;
+ BLI_addtail(&lvl->vert_face_map[lvl->faces[i].v[j]], indexnode);
+ }
+ }
+
+ /* edge boundaries */
+ emax = (lvl->prev ? (lvl->prev->totedge * 2) : lvl->totedge);
+ lvl->edge_boundary_states= MEM_callocN(sizeof(char)*lvl->totedge, "edge_boundary_states");
+ for(i=0; i<emax; ++i) {
+ MultiresMapNode *n1= lvl->vert_face_map[lvl->edges[i].v[0]].first;
+ unsigned total= 0;
+
+ lvl->edge_boundary_states[i] = 1;
+ while(n1 && lvl->edge_boundary_states[i] == 1) {
+ MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[i].v[1]].first;
+ while(n2) {
+ if(n1->Index == n2->Index) {
+ ++total;
+
+ if(total > 1) {
+ lvl->edge_boundary_states[i] = 0;
+ break;
+ }
+ }
+
+ n2= n2->next;
+ }
+ n1= n1->next;
+ }
+ }
+}
+
+/* CATMULL-CLARK
+ ============= */
+
+typedef struct MultiApplyData {
+ /* Smooth faces */
+ float *corner1, *corner2, *corner3, *corner4;
+ char quad;
+
+ /* Smooth edges */
+ char boundary;
+ float edge_face_neighbor_midpoints_accum[3];
+ unsigned edge_face_neighbor_midpoints_total;
+ float *endpoint1, *endpoint2;
+
+ /* Smooth verts */
+ /* uses 'char boundary' */
+ float *original;
+ int edge_count;
+ float vert_face_neighbor_midpoints_average[3];
+ float vert_edge_neighbor_midpoints_average[3];
+ float boundary_edges_average[3];
+} MultiApplyData;
+
+/* Simply averages the four corners of a polygon. */
+static float catmullclark_smooth_face(MultiApplyData *data, const unsigned i)
+{
+ const float total= data->corner1[i]+data->corner2[i]+data->corner3[i];
+ return data->quad ? (total+data->corner4[i])/4 : total/3;
+}
+
+static float catmullclark_smooth_edge(MultiApplyData *data, const unsigned i)
+{
+ float accum= 0;
+ unsigned count= 2;
+
+ accum+= data->endpoint1[i] + data->endpoint2[i];
+
+ if(!data->boundary) {
+ accum+= data->edge_face_neighbor_midpoints_accum[i];
+ count+= data->edge_face_neighbor_midpoints_total;
+ }
+
+ return accum / count;
+}
+
+static float catmullclark_smooth_vert(MultiApplyData *data, const unsigned i)
+{
+ if(data->boundary) {
+ return data->original[i]*0.75 + data->boundary_edges_average[i]*0.25;
+ } else {
+ return (data->vert_face_neighbor_midpoints_average[i] +
+ 2*data->vert_edge_neighbor_midpoints_average[i] +
+ data->original[i]*(data->edge_count-3))/data->edge_count;
+ }
+}
+
+
+
+/* Call func count times, passing in[i] as the input and storing the output in out[i] */
+static void multi_apply(float *out, MultiApplyData *data,
+ const unsigned count, float (*func)(MultiApplyData *, const unsigned))
+{
+ unsigned i;
+ for(i=0; i<count; ++i)
+ out[i]= func(data,i);
+}
+
+static short multires_vert_is_boundary(MultiresLevel *lvl, unsigned v)
+{
+ MultiresMapNode *node= lvl->vert_edge_map[v].first;
+ while(node) {
+ if(lvl->edge_boundary_states[node->Index])
+ return 1;
+ node= node->next;
+ }
+ return 0;
+}
+
+#define GET_FLOAT(array, i, j, stride) (((float*)((char*)(array)+((i)*(stride))))[(j)])
+
+static void edge_face_neighbor_midpoints_accum(MultiApplyData *data, MultiresLevel *lvl,
+ void *array, const char stride, const MultiresEdge *e)
+{
+ ListBase *neighbors1= &lvl->vert_face_map[e->v[0]];
+ ListBase *neighbors2= &lvl->vert_face_map[e->v[1]];
+ MultiresMapNode *n1, *n2;
+ unsigned j,count= 0;
+ float *out= data->edge_face_neighbor_midpoints_accum;
+
+ out[0]=out[1]=out[2]= 0;
+
+ for(n1= neighbors1->first; n1; n1= n1->next) {
+ for(n2= neighbors2->first; n2; n2= n2->next) {
+ if(n1->Index == n2->Index) {
+ for(j=0; j<3; ++j)
+ out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride);
+ ++count;
+ }
+ }
+ }
+
+ data->edge_face_neighbor_midpoints_total= count;
+}
+
+static void vert_face_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl,
+ void *array, const char stride, const unsigned i)
+{
+ ListBase *neighbors= &lvl->vert_face_map[i];
+ MultiresMapNode *n1;
+ unsigned j,count= 0;
+ float *out= data->vert_face_neighbor_midpoints_average;
+
+ out[0]=out[1]=out[2]= 0;
+
+ for(n1= neighbors->first; n1; n1= n1->next) {
+ for(j=0; j<3; ++j)
+ out[j]+= GET_FLOAT(array,lvl->faces[n1->Index].mid,j,stride);
+ ++count;
+ }
+ for(j=0; j<3; ++j) out[j]/= count;
+}
+
+static void vert_edge_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl,
+ void *array, const char stride, const unsigned i)
+{
+ ListBase *neighbors= &lvl->vert_edge_map[i];
+ MultiresMapNode *n1;
+ unsigned j,count= 0;
+ float *out= data->vert_edge_neighbor_midpoints_average;
+
+ out[0]=out[1]=out[2]= 0;
+
+ for(n1= neighbors->first; n1; n1= n1->next) {
+ for(j=0; j<3; ++j)
+ out[j]+= (GET_FLOAT(array,lvl->edges[n1->Index].v[0],j,stride) +
+ GET_FLOAT(array,lvl->edges[n1->Index].v[1],j,stride)) / 2;
+ ++count;
+ }
+ for(j=0; j<3; ++j) out[j]/= count;
+}
+
+static void boundary_edges_average(MultiApplyData *data, MultiresLevel *lvl,
+ void *array, const char stride, const unsigned i)
+{
+ ListBase *neighbors= &lvl->vert_edge_map[i];
+ MultiresMapNode *n1;
+ unsigned j,count= 0;
+ float *out= data->boundary_edges_average;
+
+ out[0]=out[1]=out[2]= 0;
+
+ for(n1= neighbors->first; n1; n1= n1->next) {
+ const MultiresEdge *e= &lvl->edges[n1->Index];
+ const unsigned end= e->v[0]==i ? e->v[1] : e->v[0];
+
+ if(lvl->edge_boundary_states[n1->Index]) {
+ for(j=0; j<3; ++j)
+ out[j]+= GET_FLOAT(array,end,j,stride);
+ ++count;
+ }
+ }
+ for(j=0; j<3; ++j) out[j]/= count;
+}
+
+/* END CATMULL-CLARK
+ ================= */
+
+/* Update vertex locations and vertex flags */
+static void multires_update_vertices(Mesh *me, EditMesh *em)
+{
+ MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
+ *last_lvl= me->mr->levels.last;
+ vec3f *pr_deltas= NULL, *cr_deltas= NULL, *swap_deltas= NULL;
+ EditVert *eve= NULL;
+ MultiApplyData data;
+ int i, j;
+
+ /* Prepare deltas */
+ pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1");
+ cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2");
+
+ /* Calculate initial deltas -- current mesh subtracted from current level*/
+ if(em) eve= em->verts.first;
+ for(i=0; i<cr_lvl->totvert; ++i) {
+ if(em) {
+ VecSubf(&cr_deltas[i].x, eve->co, me->mr->verts[i].co);
+ eve= eve->next;
+ } else
+ VecSubf(&cr_deltas[i].x, me->mvert[i].co, me->mr->verts[i].co);
+ }
+
+
+ /* Copy current level's vertex flags and clear the rest */
+ if(em) eve= em->verts.first;
+ for(i=0; i < last_lvl->totvert; ++i) {
+ if(i < cr_lvl->totvert) {
+ MVert mvflag;
+ multires_get_vert(&mvflag, eve, &me->mvert[i], i);
+ if(em) eve= eve->next;
+ me->mr->verts[i].flag= mvflag.flag;
+ }
+ else
+ me->mr->verts[i].flag= 0;
+ }
+
+ /* If already on the highest level, copy current verts (including flags) into current level */
+ if(cr_lvl == last_lvl) {
+ if(em)
+ eve= em->verts.first;
+ for(i=0; i<cr_lvl->totvert; ++i) {
+ multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
+ if(em) eve= eve->next;
+ }
+ }
+
+ /* Update higher levels */
+ pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
+ cr_lvl= pr_lvl->next;
+ while(cr_lvl) {
+ multires_calc_temp_data(pr_lvl);
+
+ /* Swap the old/new deltas */
+ swap_deltas= pr_deltas;
+ pr_deltas= cr_deltas;
+ cr_deltas= swap_deltas;
+
+ /* Calculate and add new deltas
+ ============================ */
+ for(i=0; i<pr_lvl->totface; ++i) {
+ const MultiresFace *f= &pr_lvl->faces[i];
+ data.corner1= &pr_deltas[f->v[0]].x;
+ data.corner2= &pr_deltas[f->v[1]].x;
+ data.corner3= &pr_deltas[f->v[2]].x;
+ data.corner4= &pr_deltas[f->v[3]].x;
+ data.quad= f->v[3] ? 1 : 0;
+ multi_apply(&cr_deltas[f->mid].x, &data, 3, catmullclark_smooth_face);
+
+ for(j=0; j<(data.quad?4:3); ++j)
+ me->mr->verts[f->mid].flag |= me->mr->verts[f->v[j]].flag;
+ }
+
+ for(i=0; i<pr_lvl->totedge; ++i) {
+ const MultiresEdge *e= &pr_lvl->edges[i];
+ data.boundary= pr_lvl->edge_boundary_states[i];
+ edge_face_neighbor_midpoints_accum(&data,pr_lvl,cr_deltas,sizeof(vec3f),e);
+ data.endpoint1= &pr_deltas[e->v[0]].x;
+ data.endpoint2= &pr_deltas[e->v[1]].x;
+ multi_apply(&cr_deltas[e->mid].x, &data, 3, catmullclark_smooth_edge);
+
+ for(j=0; j<2; ++j)
+ me->mr->verts[e->mid].flag |= me->mr->verts[e->v[j]].flag;
+ }
+
+ for(i=0; i<pr_lvl->totvert; ++i) {
+ data.boundary= multires_vert_is_boundary(pr_lvl,i);
+ data.original= &pr_deltas[i].x;
+ data.edge_count= BLI_countlist(&pr_lvl->vert_edge_map[i]);
+ if(data.boundary)
+ boundary_edges_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i);
+ else {
+ vert_face_neighbor_midpoints_average(&data,pr_lvl,cr_deltas,sizeof(vec3f),i);
+ vert_edge_neighbor_midpoints_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i);
+ }
+ multi_apply(&cr_deltas[i].x, &data, 3, catmullclark_smooth_vert);
+ }
+
+ /* Apply deltas to vertex locations */
+ for(i=0; (cr_lvl == last_lvl) && (i < cr_lvl->totvert); ++i) {
+ VecAddf(me->mr->verts[i].co,
+ me->mr->verts[i].co,
+ &cr_deltas[i].x);
+ }
+
+ multires_free_temp_data(pr_lvl);
+
+ pr_lvl= pr_lvl->next;
+ cr_lvl= cr_lvl->next;
+ }
+ if(pr_deltas) MEM_freeN(pr_deltas);
+ if(cr_deltas) MEM_freeN(cr_deltas);
+
+}
+
+static void multires_update_faces(Mesh *me, EditMesh *em)
+{
+ MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
+ *last_lvl= me->mr->levels.last;
+ char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL,
+ *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL;
+ EditFace *efa= NULL;
+ unsigned i,j,curf;
+
+ /* Find for each face whether flag/mat has changed */
+ pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
+ cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
+ pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
+ cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
+ if(em) efa= em->faces.first;
+ for(i=0; i<cr_lvl->totface; ++i) {
+ MultiresFace mftmp;
+ multires_get_face(&mftmp, efa, &me->mface[i]);
+ if(cr_lvl->faces[i].flag != mftmp.flag)
+ cr_flag_damaged[i]= 1;
+ if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr)
+ cr_mat_damaged[i]= 1;
+
+ /* Update current level */
+ cr_lvl->faces[i].flag= mftmp.flag;
+ cr_lvl->faces[i].mat_nr= mftmp.mat_nr;
+
+ if(em) efa= efa->next;
+ }
+ or_flag_damaged= MEM_dupallocN(cr_flag_damaged);
+ or_mat_damaged= MEM_dupallocN(cr_mat_damaged);
+
+ /* Update lower levels */
+ cr_lvl= cr_lvl->prev;
+ while(cr_lvl) {
+ swap= pr_flag_damaged;
+ pr_flag_damaged= cr_flag_damaged;
+ cr_flag_damaged= swap;
+
+ swap= pr_mat_damaged;
+ pr_mat_damaged= cr_mat_damaged;
+ cr_mat_damaged= swap;
+
+ curf= 0;
+ for(i=0; i<cr_lvl->totface; ++i) {
+ const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
+
+ /* Check damages */
+ for(j=0; j<sides; ++j, ++curf) {
+ if(pr_flag_damaged[curf]) {
+ cr_lvl->faces[i].flag= cr_lvl->next->faces[curf].flag;
+ cr_flag_damaged[i]= 1;
+ }
+ if(pr_mat_damaged[curf]) {
+ cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr;
+ cr_mat_damaged[i]= 1;
+ }
+ }
+ }
+
+ cr_lvl= cr_lvl->prev;
+ }
+
+ /* Clear to original damages */
+ if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
+ if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
+ cr_flag_damaged= or_flag_damaged;
+ cr_mat_damaged= or_mat_damaged;
+
+ /* Update higher levels */
+ pr_lvl= current_level(me->mr);
+ cr_lvl= pr_lvl->next;
+ while(cr_lvl) {
+ swap= pr_flag_damaged;
+ pr_flag_damaged= cr_flag_damaged;
+ cr_flag_damaged= swap;
+
+ swap= pr_mat_damaged;
+ pr_mat_damaged= cr_mat_damaged;
+ cr_mat_damaged= swap;
+
+ /* Update faces */
+ for(i=0, curf= 0; i<pr_lvl->totface; ++i) {
+ const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
+ for(j=0; j<sides; ++j, ++curf) {
+ if(pr_flag_damaged[i]) {
+ cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
+ cr_flag_damaged[curf]= 1;
+ }
+ if(pr_mat_damaged[i]) {
+ cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
+ cr_mat_damaged[curf]= 1;
+ }
+ }
+ }
+
+ pr_lvl= pr_lvl->next;
+ cr_lvl= cr_lvl->next;
+ }
+
+ if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
+ if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
+ if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
+ if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
+}
+
+static void multires_update_colors(Mesh *me, EditMesh *em)
+{
+ MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
+ MultiresCol *pr_deltas= NULL, *cr_deltas= NULL;
+ CustomData *src= em ? &em->fdata : &me->fdata;
+ EditFace *efa= NULL;
+ unsigned i,j,curf= 0;
+
+ if(me->mr->use_col) {
+ /* Calc initial deltas */
+ cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"initial color/uv deltas");
+
+ if(em) efa= em->faces.first;
+ for(i=0; i<lvl->totface; ++i) {
+ MCol *col= em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4];
+ for(j=0; j<4; ++j) {
+ if(me->mr->use_col) {
+ cr_deltas[i*4+j].a= col[j].a - lvl->colfaces[i].col[j].a;
+ cr_deltas[i*4+j].r= col[j].r - lvl->colfaces[i].col[j].r;
+ cr_deltas[i*4+j].g= col[j].g - lvl->colfaces[i].col[j].g;
+ cr_deltas[i*4+j].b= col[j].b - lvl->colfaces[i].col[j].b;
+ }
+ }
+ if(em) efa= efa->next;
+ }
+
+ /* Update current level */
+ if(em) efa= em->faces.first;
+ for(i=0; i<lvl->totface; ++i) {
+ MultiresColFace *f= &lvl->colfaces[i];
+
+ if(me->mr->use_col)
+ mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]);
+
+ if(em) efa= efa->next;
+ }
+
+ /* Update higher levels */
+ lvl= lvl->next;
+ while(lvl) {
+ /* Set up new deltas, but keep the ones from the previous level */
+ if(pr_deltas) MEM_freeN(pr_deltas);
+ pr_deltas= cr_deltas;
+ cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"color deltas");
+
+ curf= 0;
+ for(i=0; i<lvl->prev->totface; ++i) {
+ const char sides= lvl->prev->faces[i].v[3]?4:3;
+ MultiresCol cntr;
+
+ /* Find average color of 4 (or 3 for triangle) verts */
+ multires_col_avg(&cntr,&pr_deltas[i*4],sides);
+
+ for(j=0; j<sides; ++j) {
+ multires_col_avg2(&cr_deltas[curf*4],
+ &pr_deltas[i*4+j],
+ &pr_deltas[i*4+(j==0?sides-1:j-1)]);
+ cr_deltas[curf*4+1]= pr_deltas[i*4+j];
+ multires_col_avg2(&cr_deltas[curf*4+2],
+ &pr_deltas[i*4+j],
+ &pr_deltas[i*4+(j==sides-1?0:j+1)]);
+ cr_deltas[curf*4+3]= cntr;
+ ++curf;
+ }
+ }
+
+ for(i=0; i<lvl->totface; ++i) {
+ for(j=0; j<4; ++j) {
+ lvl->colfaces[i].col[j].a+= cr_deltas[i*4+j].a;
+ lvl->colfaces[i].col[j].r+= cr_deltas[i*4+j].r;
+ lvl->colfaces[i].col[j].g+= cr_deltas[i*4+j].g;
+ lvl->colfaces[i].col[j].b+= cr_deltas[i*4+j].b;
+ }
+ }
+
+ lvl= lvl->next;
+ }
+ if(pr_deltas) MEM_freeN(pr_deltas);
+ if(cr_deltas) MEM_freeN(cr_deltas);
+
+ /* Update lower levels */
+ lvl= me->mr->levels.last;
+ lvl= lvl->prev;
+ while(lvl) {
+ MultiresColFace *nf= lvl->next->colfaces;
+ for(i=0; i<lvl->totface; ++i) {
+ MultiresFace *f= &lvl->faces[i];
+ for(j=0; j<(f->v[3]?4:3); ++j) {
+ lvl->colfaces[i].col[j]= nf->col[1];
+ ++nf;
+ }
+ }
+ lvl= lvl->prev;
+ }
+ }
+}
+
+void multires_update_levels(Mesh *me, const int render)
+{
+ EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
+
+ multires_update_first_level(me, em);
+ multires_update_vertices(me, em);
+ multires_update_faces(me, em);
+ multires_update_colors(me, em);
+}
+
+static void check_colors(Mesh *me)
+{
+ CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata;
+ const char col= CustomData_has_layer(src, CD_MCOL);
+
+ /* Check if vertex colors have been deleted or added */
+ if(me->mr->use_col && !col)
+ me->mr->use_col= 0;
+ else if(!me->mr->use_col && col) {
+ me->mr->use_col= 1;
+ multires_load_cols(me);
+ }
+}
+
+static unsigned int find_mid_edge(ListBase *vert_edge_map,
+ MultiresLevel *lvl,
+ const unsigned int v1,
+ const unsigned int v2 )
+{
+ MultiresMapNode *n= vert_edge_map[v1].first;
+ while(n) {
+ if(lvl->edges[n->Index].v[0]==v2 ||
+ lvl->edges[n->Index].v[1]==v2)
+ return lvl->edges[n->Index].mid;
+
+ n= n->next;
+ }
+ return -1;
+}
+
+static float clamp_component(const float c)
+{
+ if(c<0) return 0;
+ else if(c>255) return 255;
+ else return c;
+}
+
+void multires_to_mcol(MultiresColFace *f, MCol mcol[4])
+{
+ unsigned char j;
+ for(j=0; j<4; ++j) {
+ mcol->a= clamp_component(f->col[j].a);
+ mcol->r= clamp_component(f->col[j].r);
+ mcol->g= clamp_component(f->col[j].g);
+ mcol->b= clamp_component(f->col[j].b);
+ ++mcol;
+ }
+}
+
+void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
+{
+ MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
+ int i;
+ EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
+
+ if(em)
+ return;
+
+ CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
+ CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
+ CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
+ CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+ CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface);
+ CustomData_free_layers(&me->fdata, CD_MCOL, me->totface);
+
+ me->totvert= lvl->totvert;
+ me->totface= lvl->totface;
+ me->totedge= lvl->totedge;
+
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
+ CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
+ mesh_update_customdata_pointers(me);
+
+ /* Vertices/Edges/Faces */
+
+ for(i=0; i<lvl->totvert; ++i) {
+ me->mvert[i]= me->mr->verts[i];
+ }
+ for(i=0; i<lvl->totedge; ++i) {
+ me->medge[i].v1= lvl->edges[i].v[0];
+ me->medge[i].v2= lvl->edges[i].v[1];
+ me->medge[i].flag &= ~ME_HIDE;
+ }
+ for(i=0; i<lvl->totface; ++i) {
+ me->mface[i].v1= lvl->faces[i].v[0];
+ me->mface[i].v2= lvl->faces[i].v[1];
+ me->mface[i].v3= lvl->faces[i].v[2];
+ me->mface[i].v4= lvl->faces[i].v[3];
+ me->mface[i].flag= lvl->faces[i].flag;
+ me->mface[i].flag &= ~ME_HIDE;
+ me->mface[i].mat_nr= lvl->faces[i].mat_nr;
+ }
+
+ /* Edge flags */
+ if(lvl==me->mr->levels.first) {
+ for(i=0; i<lvl->totedge; ++i) {
+ me->medge[i].flag= me->mr->edge_flags[i];
+ me->medge[i].crease= me->mr->edge_creases[i];
+ }
+ } else {
+ MultiresLevel *lvl1= me->mr->levels.first;
+ const int last= lvl1->totedge * pow(2, me->mr->current-1);
+ for(i=0; i<last; ++i) {
+ const int ndx= i / pow(2, me->mr->current-1);
+
+ me->medge[i].flag= me->mr->edge_flags[ndx];
+ me->medge[i].crease= me->mr->edge_creases[ndx];
+ }
+ }
+
+ multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
+ multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
+
+ /* Colors */
+ if(me->mr->use_col) {
+ CustomData *src= &me->fdata;
+
+ if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface);
+
+ for(i=0; i<lvl->totface; ++i) {
+ if(me->mr->use_col)
+ multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]);
+ }
+
+ }
+
+ mesh_update_customdata_pointers(me);
+
+ multires_edge_level_update(ob,me);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+}
+
+void multires_add_level(Object *ob, Mesh *me, const char subdiv_type)
+{
+ int i,j, curf, cure;
+ MultiresLevel *lvl= NULL;
+ MultiApplyData data;
+ MVert *oldverts= NULL;
+
+ lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel");
+ if(me->pv) mesh_pmv_off(ob, me);
+
+ check_colors(me);
+ multires_update_levels(me, 0);
+
+ ++me->mr->level_count;
+ BLI_addtail(&me->mr->levels,lvl);
+
+ /* Create vertices
+ =============== */
+ lvl->totvert= lvl->prev->totvert + lvl->prev->totedge + lvl->prev->totface;
+ oldverts= me->mr->verts;
+ me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert, "multitres verts");
+ /* Copy old verts */
+ for(i=0; i<lvl->prev->totvert; ++i)
+ me->mr->verts[i]= oldverts[i];
+ /* Create new edge verts */
+ for(i=0; i<lvl->prev->totedge; ++i) {
+ VecMidf(me->mr->verts[lvl->prev->totvert + i].co,
+ oldverts[lvl->prev->edges[i].v[0]].co,
+ oldverts[lvl->prev->edges[i].v[1]].co);
+ lvl->prev->edges[i].mid= lvl->prev->totvert + i;
+ }
+ /* Create new face verts */
+ for(i=0; i<lvl->prev->totface; ++i) {
+ lvl->prev->faces[i].mid= lvl->prev->totvert + lvl->prev->totedge + i;
+ }
+
+ multires_calc_temp_data(lvl->prev);
+
+ /* Create faces
+ ============ */
+ /* Allocate all the new faces (each triangle creates three, and
+ each quad creates four */
+ lvl->totface= 0;
+ for(i=0; i<lvl->prev->totface; ++i)
+ lvl->totface+= lvl->prev->faces[i].v[3] ? 4 : 3;
+ lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
+
+ curf= 0;
+ for(i=0; i<lvl->prev->totface; ++i) {
+ const int max= lvl->prev->faces[i].v[3] ? 3 : 2;
+
+ for(j=0; j<max+1; ++j) {
+ lvl->faces[curf].v[0]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev,
+ lvl->prev->faces[i].v[j],
+ lvl->prev->faces[i].v[j==0?max:j-1]);
+ lvl->faces[curf].v[1]= lvl->prev->faces[i].v[j];
+ lvl->faces[curf].v[2]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev,
+ lvl->prev->faces[i].v[j],
+ lvl->prev->faces[i].v[j==max?0:j+1]);
+ lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i;
+ lvl->faces[curf].flag= lvl->prev->faces[i].flag;
+ lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr;
+
+ ++curf;
+ }
+ }
+
+ /* Create edges
+ ============ */
+ /* Figure out how many edges to allocate */
+ lvl->totedge= lvl->prev->totedge*2;
+ for(i=0; i<lvl->prev->totface; ++i)
+ lvl->totedge+= lvl->prev->faces[i].v[3]?4:3;
+ lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
+
+ for(i=0; i<lvl->prev->totedge; ++i) {
+ lvl->edges[i*2].v[0]= lvl->prev->edges[i].v[0];
+ lvl->edges[i*2].v[1]= lvl->prev->edges[i].mid;
+ lvl->edges[i*2+1].v[0]= lvl->prev->edges[i].mid;
+ lvl->edges[i*2+1].v[1]= lvl->prev->edges[i].v[1];
+ }
+ /* Add edges inside of old polygons */
+ curf= 0;
+ cure= lvl->prev->totedge*2;
+ for(i=0; i<lvl->prev->totface; ++i) {
+ for(j=0; j<(lvl->prev->faces[i].v[3]?4:3); ++j) {
+ lvl->edges[cure].v[0]= lvl->faces[curf].v[2];
+ lvl->edges[cure].v[1]= lvl->faces[curf].v[3];
+ ++cure;
+ ++curf;
+ }
+ }
+
+ /* Smooth vertices
+ =============== */
+ for(i=0; i<lvl->prev->totface; ++i) {
+ const MultiresFace *f= &lvl->prev->faces[i];
+ data.corner1= oldverts[f->v[0]].co;
+ data.corner2= oldverts[f->v[1]].co;
+ data.corner3= oldverts[f->v[2]].co;
+ data.corner4= oldverts[f->v[3]].co;
+ data.quad= f->v[3] ? 1 : 0;
+ multi_apply(me->mr->verts[f->mid].co, &data, 3, catmullclark_smooth_face);
+ }
+
+ if(subdiv_type == 0) {
+ for(i=0; i<lvl->prev->totedge; ++i) {
+ const MultiresEdge *e= &lvl->prev->edges[i];
+ data.boundary= lvl->prev->edge_boundary_states[i];
+ edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e);
+ data.endpoint1= oldverts[e->v[0]].co;
+ data.endpoint2= oldverts[e->v[1]].co;
+ multi_apply(me->mr->verts[e->mid].co, &data, 3, catmullclark_smooth_edge);
+ }
+
+ for(i=0; i<lvl->prev->totvert; ++i) {
+ data.boundary= multires_vert_is_boundary(lvl->prev,i);
+ data.original= oldverts[i].co;
+ data.edge_count= BLI_countlist(&lvl->prev->vert_edge_map[i]);
+ if(data.boundary)
+ boundary_edges_average(&data,lvl->prev, oldverts, sizeof(MVert),i);
+ else {
+ vert_face_neighbor_midpoints_average(&data,lvl->prev, me->mr->verts,
+ sizeof(MVert),i);
+ vert_edge_neighbor_midpoints_average(&data,lvl->prev, oldverts,
+ sizeof(MVert),i);
+ }
+ multi_apply(me->mr->verts[i].co, &data, 3, catmullclark_smooth_vert);
+ }
+ }
+
+ multires_free_temp_data(lvl->prev);
+ MEM_freeN(oldverts);
+
+ /* Vertex Colors
+ ============= */
+ curf= 0;
+ if(me->mr->use_col) {
+ MultiresColFace *cf= MEM_callocN(sizeof(MultiresColFace)*lvl->totface,"Multirescolfaces");
+ lvl->colfaces= cf;
+ for(i=0; i<lvl->prev->totface; ++i) {
+ const char sides= lvl->prev->faces[i].v[3]?4:3;
+ MultiresCol cntr;
+
+ /* Find average color of 4 (or 3 for triangle) verts */
+ multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides);
+
+ for(j=0; j<sides; ++j) {
+ multires_col_avg2(&cf->col[0],
+ &lvl->prev->colfaces[i].col[j],
+ &lvl->prev->colfaces[i].col[j==0?sides-1:j-1]);
+ cf->col[1]= lvl->prev->colfaces[i].col[j];
+ multires_col_avg2(&cf->col[2],
+ &lvl->prev->colfaces[i].col[j],
+ &lvl->prev->colfaces[i].col[j==sides-1?0:j+1]);
+ cf->col[3]= cntr;
+
+ ++cf;
+ }
+ }
+ }
+
+ me->mr->newlvl= me->mr->level_count;
+ me->mr->current= me->mr->newlvl;
+ /* Unless the render level has been set to something other than the
+ highest level (by the user), increment the render level to match
+ the highest available level */
+ if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count;
+
+ multires_level_to_mesh(ob, me, 0);
+}
+
+void multires_set_level(Object *ob, Mesh *me, const int render)
+{
+ if(me->pv) mesh_pmv_off(ob, me);
+
+ check_colors(me);
+ multires_update_levels(me, render);
+
+ me->mr->current= me->mr->newlvl;
+ if(me->mr->current<1) me->mr->current= 1;
+ else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count;
+
+ multires_level_to_mesh(ob, me, render);
+}
+
+/* Update the edge visibility flags to only show edges on or below the edgelvl */
+void multires_edge_level_update(Object *ob, Mesh *me)
+{
+ if(!G.obedit) {
+ MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
+ MultiresLevel *edge_lvl= BLI_findlink(&me->mr->levels,me->mr->edgelvl-1);
+ const int threshold= edge_lvl->totedge * pow(2, me->mr->current - me->mr->edgelvl);
+ unsigned i;
+
+ for(i=0; i<cr_lvl->totedge; ++i) {
+ const int ndx= me->pv ? me->pv->edge_map[i] : i;
+ if(ndx != -1) { /* -1= hidden edge */
+ if(me->mr->edgelvl >= me->mr->current || i<threshold)
+ me->medge[ndx].flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ else
+ me->medge[ndx].flag &= ~ME_EDGEDRAW & ~ME_EDGERENDER;
+ }
+ }
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index e7b7b36aaa4..bc9aa23ee15 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -27,6 +27,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <Python.h>
#include <stdlib.h>
#include <string.h>
@@ -34,6 +35,7 @@
#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_material_types.h"
+#include "DNA_text_types.h"
#include "DNA_scene_types.h"
#include "BKE_blender.h"
@@ -44,6 +46,7 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_texture.h"
+#include "BKE_text.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
@@ -61,6 +64,8 @@
#include "RE_render_ext.h" /* <- ibuf_sample() */
#include "CMP_node.h"
+#include "intern/CMP_util.h" /* stupid include path... */
+
#include "SHD_node.h"
/* not very important, but the stack solver likes to know a maximum */
@@ -72,7 +77,7 @@ ListBase node_all_shaders = {NULL, NULL};
/* ************** Type stuff ********** */
-static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup)
+static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
{
if(type==NODE_GROUP) {
if(ngroup && GS(ngroup->id.name)==ID_NT) {
@@ -83,7 +88,7 @@ static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup)
else {
bNodeType *ntype = ntree->alltypes.first;
for(; ntype; ntype= ntype->next)
- if(ntype->type==type)
+ if(ntype->type==type && id==ntype->id )
return ntype;
return NULL;
@@ -105,7 +110,27 @@ void ntreeInitTypes(bNodeTree *ntree)
for(node= ntree->nodes.first; node; node= next) {
next= node->next;
- node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id);
+ if(node->type==NODE_DYNAMIC) {
+ bNodeType *stype= NULL;
+ if(node->id==NULL) { /* empty script node */
+ stype= node_get_type(ntree, node->type, NULL, NULL);
+ } else { /* not an empty script node */
+ stype= node_get_type(ntree, node->type, NULL, node->id);
+ if(!stype) {
+ stype= node_get_type(ntree, node->type, NULL, NULL);
+ /* needed info if the pynode script fails now: */
+ if (node->id) node->storage= ntree;
+ } else {
+ node->custom1= 0;
+ node->custom1= BSET(node->custom1,NODE_DYNAMIC_ADDEXIST);
+ }
+ }
+ node->typeinfo= stype;
+ node->typeinfo->initfunc(node);
+ } else {
+ node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL);
+ }
+
if(node->typeinfo==NULL) {
printf("Error: Node type %s doesn't exist anymore, removed\n", node->name);
nodeFreeNode(ntree, node);
@@ -115,6 +140,18 @@ void ntreeInitTypes(bNodeTree *ntree)
ntree->init |= NTREE_TYPE_INIT;
}
+/* updates node with (modified) bNodeType.. this should be done for all trees */
+void ntreeUpdateType(bNodeTree *ntree, bNodeType *ntype)
+{
+ bNode *node;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo== ntype) {
+ nodeUpdateType(ntree, node, ntype);
+ }
+ }
+}
+
/* only used internal... we depend on type definitions! */
static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
{
@@ -137,7 +174,7 @@ static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype)
if(lb)
BLI_addtail(lb, sock);
-
+
return sock;
}
@@ -483,6 +520,20 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
BLI_addtail(&ngroup->nodes, node);
node->locx-= 0.5f*(min[0]+max[0]);
node->locy-= 0.5f*(min[1]+max[1]);
+
+ /* set selin and selout of the nodetree */
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ngroup->selin= sock;
+ break;
+ }
+ }
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ngroup->selout= sock;
+ break;
+ }
+ }
}
}
@@ -499,7 +550,7 @@ bNode *nodeMakeGroupFromSelected(bNodeTree *ntree)
ntreeMakeOwnType(ngroup);
/* make group node */
- gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup);
+ gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup, NULL);
gnode->locx= 0.5f*(min[0]+max[0]);
gnode->locy= 0.5f*(min[1]+max[1]);
@@ -653,7 +704,8 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup)
}
}
-static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
+/* finds a node based on given socket */
+int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex)
{
bNode *node;
bNodeSocket *tsock;
@@ -671,13 +723,15 @@ static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **n
if(tsock)
break;
}
+
if(node) {
*nodep= node;
- *sockindex= index;
- }
- else {
- *nodep= NULL;
+ if(sockindex) *sockindex= index;
+ return 1;
}
+
+ *nodep= NULL;
+ return 0;
}
/* returns 1 if its OK */
@@ -717,7 +771,7 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
for(link= ntree->links.first; link; link= link->next) {
if(link->tonode==gnode) {
/* link->tosock->tosock is on the node we look for */
- find_node_with_socket(ngroup, link->tosock->tosock, &nextn, &index);
+ nodeFindNode(ngroup, link->tosock->tosock, &nextn, &index);
if(nextn==NULL) printf("wrong stuff!\n");
else if(nextn->new_node==NULL) printf("wrong stuff too!\n");
else {
@@ -727,7 +781,7 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
}
else if(link->fromnode==gnode) {
/* link->fromsock->tosock is on the node we look for */
- find_node_with_socket(ngroup, link->fromsock->tosock, &nextn, &index);
+ nodeFindNode(ngroup, link->fromsock->tosock, &nextn, &index);
if(nextn==NULL) printf("1 wrong stuff!\n");
else if(nextn->new_node==NULL) printf("1 wrong stuff too!\n");
else {
@@ -749,30 +803,28 @@ int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode)
return 1;
}
-/* ************** Add stuff ********** */
+void nodeCopyGroup(bNode *gnode)
+{
+ bNodeSocket *sock;
+
+ gnode->id->us--;
+ gnode->id= (ID *)ntreeCopyTree((bNodeTree *)gnode->id, 0);
+
+ /* new_sock was set in nodeCopyNode */
+ for(sock=gnode->inputs.first; sock; sock=sock->next)
+ if(sock->tosock)
+ sock->tosock= sock->tosock->new_sock;
+
+ for(sock=gnode->outputs.first; sock; sock=sock->next)
+ if(sock->tosock)
+ sock->tosock= sock->tosock->new_sock;
+}
-bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
+/* ************** Add stuff ********** */
+void nodeAddSockets(bNode *node, bNodeType *ntype)
{
- bNode *node;
- bNodeType *ntype= node_get_type(ntree, type, ngroup);
bNodeSocketType *stype;
-
- node= MEM_callocN(sizeof(bNode), "new node");
- BLI_addtail(&ntree->nodes, node);
- node->typeinfo= ntype;
-
- if(ngroup)
- BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
- else
- BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
- node->type= ntype->type;
- node->flag= NODE_SELECT|ntype->flag;
- node->width= ntype->width;
- node->miniwidth= 42.0f; /* small value only, allows print of first chars */
-
- if(type==NODE_GROUP)
- node->id= (ID *)ngroup;
-
+
if(ntype->inputs) {
stype= ntype->inputs;
while(stype->type != -1) {
@@ -787,34 +839,111 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup)
stype++;
}
}
-
+}
+
+
+bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
+{
+ bNode *node= NULL;
+ bNodeType *ntype= NULL;
+
+ if(type>=NODE_DYNAMIC_MENU) {
+ int a=0, idx= type-NODE_DYNAMIC_MENU;
+ ntype= ntree->alltypes.first;
+ while(ntype) {
+ if(ntype->type==NODE_DYNAMIC) {
+ if(a==idx)
+ break;
+ a++;
+ }
+ ntype= ntype->next;
+ }
+ } else
+ ntype= node_get_type(ntree, type, ngroup, id);
+
+ node= MEM_callocN(sizeof(bNode), "new node");
+ BLI_addtail(&ntree->nodes, node);
+ node->typeinfo= ntype;
+ if(type>=NODE_DYNAMIC_MENU)
+ node->custom2= type; /* for node_dynamic_init */
+
+ if(ngroup)
+ BLI_strncpy(node->name, ngroup->id.name+2, NODE_MAXSTR);
+ else if(type>NODE_DYNAMIC_MENU) {
+ BLI_strncpy(node->name, ntype->id->name+2, NODE_MAXSTR);
+ }
+ else
+ BLI_strncpy(node->name, ntype->name, NODE_MAXSTR);
+ node->type= ntype->type;
+ node->flag= NODE_SELECT|ntype->flag;
+ node->width= ntype->width;
+ node->miniwidth= 42.0f; /* small value only, allows print of first chars */
+
+ if(type==NODE_GROUP)
+ node->id= (ID *)ngroup;
+
/* need init handler later? */
- /* got it-bob*/
- if(ntype->initfunc!=NULL)
- ntype->initfunc(node);
+ /* got it-bob*/
+ if(ntype->initfunc!=NULL)
+ ntype->initfunc(node);
+
+ nodeAddSockets(node, ntype);
+
+ return node;
+}
- return node;
+void nodeMakeDynamicType(bNode *node)
+{
+ /* find SH_DYNAMIC_NODE ntype */
+ bNodeType *ntype= node_all_shaders.first;
+ while(ntype) {
+ if(ntype->type==NODE_DYNAMIC && ntype->id==NULL)
+ break;
+ ntype= ntype->next;
+ }
+
+ /* make own type struct to fill */
+ if(ntype) {
+ /*node->typeinfo= MEM_dupallocN(ntype);*/
+ bNodeType *newtype= MEM_callocN(sizeof(bNodeType), "dynamic bNodeType");
+ *newtype= *ntype;
+ newtype->name= BLI_strdup(ntype->name);
+ node->typeinfo= newtype;
+ }
+}
+
+void nodeUpdateType(bNodeTree *ntree, bNode* node, bNodeType *ntype)
+{
+ verify_socket_list(ntree, &node->inputs, ntype->inputs);
+ verify_socket_list(ntree, &node->outputs, ntype->outputs);
}
/* keep socket listorder identical, for copying links */
/* ntree is the target tree */
-bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
+bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
{
bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node");
- bNodeSocket *sock;
+ bNodeSocket *sock, *oldsock;
*nnode= *node;
BLI_addtail(&ntree->nodes, nnode);
duplicatelist(&nnode->inputs, &node->inputs);
- for(sock= nnode->inputs.first; sock; sock= sock->next)
- sock->own_index= 0;
+ oldsock= node->inputs.first;
+ for(sock= nnode->inputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
+ oldsock->new_sock= sock;
+ if(internal)
+ sock->own_index= 0;
+ }
duplicatelist(&nnode->outputs, &node->outputs);
- for(sock= nnode->outputs.first; sock; sock= sock->next) {
- sock->own_index= 0;
+ oldsock= node->outputs.first;
+ for(sock= nnode->outputs.first; sock; sock= sock->next, oldsock= oldsock->next) {
+ if(internal)
+ sock->own_index= 0;
sock->stack_index= 0;
sock->ns.data= NULL;
+ oldsock->new_sock= sock;
}
if(nnode->id)
@@ -892,12 +1021,34 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
node->new_node= NULL;
if(internal_select==0 || (node->flag & NODE_SELECT)) {
- nnode= nodeCopyNode(newtree, node); /* sets node->new */
+ nnode= nodeCopyNode(newtree, node, internal_select); /* sets node->new */
if(internal_select) {
node->flag &= ~NODE_SELECT;
nnode->flag |= NODE_SELECT;
}
node->flag &= ~NODE_ACTIVE;
+
+ /* deselect original sockets */
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
+ }
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
+ }
+
+ /* set tree selin and selout to new sockets */
+ for(sock= nnode->inputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ntree->selin= sock;
+ break;
+ }
+ }
+ for(sock= nnode->outputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ntree->selout= sock;
+ break;
+ }
+ }
}
if(node==last) break;
}
@@ -941,7 +1092,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
/* ************** Free stuff ********** */
/* goes over entire tree */
-static void node_unlink_node(bNodeTree *ntree, bNode *node)
+void nodeUnlinkNode(bNodeTree *ntree, bNode *node)
{
bNodeLink *link, *next;
bNodeSocket *sock;
@@ -985,7 +1136,7 @@ static void composit_free_node_cache(bNode *node)
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
- node_unlink_node(ntree, node);
+ nodeUnlinkNode(ntree, node);
BLI_remlink(&ntree->nodes, node);
/* since it is called while free database, node->id is undefined */
@@ -1003,6 +1154,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
if(node->typeinfo && node->typeinfo->freestoragefunc) {
node->typeinfo->freestoragefunc(node);
}
+
MEM_freeN(node);
}
@@ -1840,6 +1992,27 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
/* ***************************** threaded version for execute composite nodes ************* */
+/* these are nodes without input, only giving values */
+/* or nodes with only value inputs */
+static int node_only_value(bNode *node)
+{
+ bNodeSocket *sock;
+
+ if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
+ return 1;
+
+ /* doing this for all node types goes wrong. memory free errors */
+ if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
+ int retval= 1;
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ if(sock->link)
+ retval &= node_only_value(sock->link->fromnode);
+ }
+ return retval;
+ }
+ return 0;
+}
+
/* not changing info, for thread callback */
typedef struct ThreadData {
@@ -1856,7 +2029,14 @@ static void *exec_composite_node(void *node_v)
node_get_stack(node, thd->stack, nsin, nsout);
- if(node->typeinfo->execfunc) {
+ if((node->flag & NODE_MUTED) && (!node_only_value(node))) {
+ /* viewers we execute, for feedback to user */
+ if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
+ else
+ node_compo_pass_on(node, nsin, nsout);
+ }
+ else if(node->typeinfo->execfunc) {
node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
}
else if(node->type==NODE_GROUP && node->id) {
@@ -1867,27 +2047,6 @@ static void *exec_composite_node(void *node_v)
return 0;
}
-/* these are nodes without input, only giving values */
-/* or nodes with only value inputs */
-static int node_only_value(bNode *node)
-{
- bNodeSocket *sock;
-
- if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_VALUE, CMP_NODE_RGB))
- return 1;
-
- /* doing this for all node types goes wrong. memory free errors */
- if(node->inputs.first && node->type==CMP_NODE_MAP_VALUE) {
- int retval= 1;
- for(sock= node->inputs.first; sock; sock= sock->next) {
- if(sock->link)
- retval &= node_only_value(sock->link->fromnode);
- }
- return retval;
- }
- return 0;
-}
-
/* return total of executable nodes, for timecursor */
/* only compositor uses it */
static int setExecutableNodes(bNodeTree *ntree, ThreadData *thd)
@@ -2172,6 +2331,8 @@ static void force_hidden_passes(bNode *node, int passflag)
if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
+ if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
}
@@ -2281,12 +2442,12 @@ void ntreeCompositTagGenerators(bNodeTree *ntree)
/* ************* node definition init ********** */
-static bNodeType *is_nodetype_registered(ListBase *typelist, int type)
+static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id)
{
bNodeType *ntype= typelist->first;
for(;ntype; ntype= ntype->next )
- if(ntype->type==type)
+ if(ntype->type==type && ntype->id==id)
return ntype;
return NULL;
@@ -2295,10 +2456,10 @@ static bNodeType *is_nodetype_registered(ListBase *typelist, int type)
/* type can be from a static array, we make copy for duplicate types (like group) */
void nodeRegisterType(ListBase *typelist, const bNodeType *ntype)
{
- bNodeType *found= is_nodetype_registered(typelist, ntype->type);
+ bNodeType *found= is_nodetype_registered(typelist, ntype->type, ntype->id);
if(found==NULL) {
- bNodeType *ntypen= MEM_mallocN(sizeof(bNodeType), "node type");
+ bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type");
*ntypen= *ntype;
BLI_addtail(typelist, ntypen);
}
@@ -2331,9 +2492,12 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_normal);
nodeRegisterType(ntypelist, &cmp_node_curve_vec);
nodeRegisterType(ntypelist, &cmp_node_map_value);
+ nodeRegisterType(ntypelist, &cmp_node_normalize);
nodeRegisterType(ntypelist, &cmp_node_filter);
nodeRegisterType(ntypelist, &cmp_node_blur);
+ nodeRegisterType(ntypelist, &cmp_node_dblur);
+ nodeRegisterType(ntypelist, &cmp_node_bilateralblur);
nodeRegisterType(ntypelist, &cmp_node_vecblur);
nodeRegisterType(ntypelist, &cmp_node_dilateerode);
nodeRegisterType(ntypelist, &cmp_node_defocus);
@@ -2351,6 +2515,7 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_combyuva);
nodeRegisterType(ntypelist, &cmp_node_sepycca);
nodeRegisterType(ntypelist, &cmp_node_combycca);
+ nodeRegisterType(ntypelist, &cmp_node_premulkey);
nodeRegisterType(ntypelist, &cmp_node_diff_matte);
nodeRegisterType(ntypelist, &cmp_node_chroma);
@@ -2362,8 +2527,12 @@ static void registerCompositNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &cmp_node_rotate);
nodeRegisterType(ntypelist, &cmp_node_scale);
nodeRegisterType(ntypelist, &cmp_node_flip);
+ nodeRegisterType(ntypelist, &cmp_node_crop);
nodeRegisterType(ntypelist, &cmp_node_displace);
nodeRegisterType(ntypelist, &cmp_node_mapuv);
+ nodeRegisterType(ntypelist, &cmp_node_glare);
+ nodeRegisterType(ntypelist, &cmp_node_tonemap);
+ nodeRegisterType(ntypelist, &cmp_node_lensdist);
}
static void registerShaderNodes(ListBase *ntypelist)
@@ -2387,7 +2556,44 @@ static void registerShaderNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &sh_node_value);
nodeRegisterType(ntypelist, &sh_node_rgb);
nodeRegisterType(ntypelist, &sh_node_texture);
+ nodeRegisterType(ntypelist, &node_dynamic_typeinfo);
nodeRegisterType(ntypelist, &sh_node_invert);
+ nodeRegisterType(ntypelist, &sh_node_seprgb);
+ nodeRegisterType(ntypelist, &sh_node_combrgb);
+ nodeRegisterType(ntypelist, &sh_node_hue_sat);
+}
+
+static void remove_dynamic_typeinfos(ListBase *list)
+{
+ bNodeType *ntype= list->first;
+ bNodeType *next= NULL;
+ while(ntype) {
+ next= ntype->next;
+ if(ntype->type==NODE_DYNAMIC && ntype->id!=NULL) {
+ BLI_remlink(list, ntype);
+ if(ntype->inputs) {
+ bNodeSocketType *sock= ntype->inputs;
+ while(sock->type!=-1) {
+ MEM_freeN(sock->name);
+ sock++;
+ }
+ MEM_freeN(ntype->inputs);
+ }
+ if(ntype->outputs) {
+ bNodeSocketType *sock= ntype->outputs;
+ while(sock->type!=-1) {
+ MEM_freeN(sock->name);
+ sock++;
+ }
+ MEM_freeN(ntype->outputs);
+ }
+ if(ntype->name) {
+ MEM_freeN(ntype->name);
+ }
+ MEM_freeN(ntype);
+ }
+ ntype= next;
+ }
}
void init_nodesystem(void)
@@ -2398,8 +2604,8 @@ void init_nodesystem(void)
void free_nodesystem(void)
{
+ /*remove_dynamic_typeinfos(&node_all_composit);*/ /* unused for now */
BLI_freelistN(&node_all_composit);
+ remove_dynamic_typeinfos(&node_all_shaders);
BLI_freelistN(&node_all_shaders);
}
-
-
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4cb6f64569f..3f1515f146a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -60,6 +60,7 @@
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
#include "DNA_oops_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -70,6 +71,7 @@
#include "BKE_armature.h"
#include "BKE_action.h"
+#include "BKE_colortools.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_nla.h"
@@ -100,6 +102,7 @@
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
@@ -154,6 +157,25 @@ void update_base_layer(Object *ob)
}
}
+void object_free_particlesystems(Object *ob)
+{
+ while(ob->particlesystem.first){
+ ParticleSystem *psys = ob->particlesystem.first;
+
+ BLI_remlink(&ob->particlesystem,psys);
+
+ psys_free(ob,psys);
+ }
+}
+
+void object_free_softbody(Object *ob)
+{
+ if(ob->soft) {
+ sbFree(ob->soft);
+ ob->soft= NULL;
+ }
+}
+
void object_free_modifiers(Object *ob)
{
while (ob->modifiers.first) {
@@ -163,6 +185,12 @@ void object_free_modifiers(Object *ob)
modifier_free(md);
}
+
+ /* particle modifiers were freed, so free the particlesystems as well */
+ object_free_particlesystems(ob);
+
+ /* same for softbody */
+ object_free_softbody(ob);
}
/* here we will collect all local displist stuff */
@@ -213,15 +241,13 @@ void free_object(Object *ob)
ob->path= 0;
if(ob->ipo) ob->ipo->id.us--;
if(ob->action) ob->action->id.us--;
+ if(ob->poselib) ob->poselib->id.us--;
if(ob->dup_group) ob->dup_group->id.us--;
if(ob->defbase.first)
BLI_freelistN(&ob->defbase);
- if(ob->pose) {
- free_pose_channels(ob->pose);
- MEM_freeN(ob->pose);
- }
+ if(ob->pose)
+ free_pose(ob->pose);
free_effects(&ob->effect);
- BLI_freelistN(&ob->network);
free_properties(&ob->prop);
object_free_modifiers(ob);
@@ -235,7 +261,11 @@ void free_object(Object *ob)
BPY_free_scriptlink(&ob->scriptlink);
- if(ob->pd) MEM_freeN(ob->pd);
+ if(ob->pd){
+ if(ob->pd->tex)
+ ob->pd->tex->id.us--;
+ MEM_freeN(ob->pd);
+ }
if(ob->soft) sbFree(ob->soft);
if(ob->fluidsimSettings) fluidsimSettingsFree(ob->fluidsimSettings);
}
@@ -260,10 +290,10 @@ void unlink_object(Object *ob)
Tex *tex;
Ipo *ipo;
Group *group;
+ Camera *camera;
bConstraint *con;
bActionStrip *strip;
int a;
- char *str;
unlink_controllers(&ob->controllers);
unlink_actuators(&ob->actuators);
@@ -312,9 +342,23 @@ void unlink_object(Object *ob)
bPoseChannel *pchan;
for(pchan= obt->pose->chanbase.first; pchan; pchan= pchan->next) {
for (con = pchan->constraints.first; con; con=con->next) {
- if(ob==get_constraint_target(con, &str)) {
- set_constraint_target(con, NULL, NULL);
- obt->recalc |= OB_RECALC_DATA;
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == ob) {
+ ct->tar = NULL;
+ strcpy(ct->subtarget, "");
+ obt->recalc |= OB_RECALC_DATA;
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
}
if(pchan->custom==ob)
@@ -325,9 +369,23 @@ void unlink_object(Object *ob)
sca_remove_ob_poin(obt, ob);
for (con = obt->constraints.first; con; con=con->next) {
- if(ob==get_constraint_target(con, &str)) {
- set_constraint_target(con, NULL, NULL);
- obt->recalc |= OB_RECALC_OB;
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == ob) {
+ ct->tar = NULL;
+ strcpy(ct->subtarget, "");
+ obt->recalc |= OB_RECALC_DATA;
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
}
@@ -352,6 +410,47 @@ void unlink_object(Object *ob)
}
}
+ /* particle systems */
+ if(obt->particlesystem.first) {
+ ParticleSystem *tpsys= obt->particlesystem.first;
+ for(; tpsys; tpsys=tpsys->next) {
+ if(tpsys->keyed_ob==ob) {
+ ParticleSystem *psys= BLI_findlink(&ob->particlesystem,tpsys->keyed_psys-1);
+
+ if(psys && psys->keyed_ob) {
+ tpsys->keyed_ob= psys->keyed_ob;
+ tpsys->keyed_psys= psys->keyed_psys;
+ }
+ else
+ tpsys->keyed_ob= NULL;
+
+ obt->recalc |= OB_RECALC_DATA;
+ }
+
+ if(tpsys->target_ob==ob) {
+ tpsys->target_ob= NULL;
+ obt->recalc |= OB_RECALC_DATA;
+ }
+
+ if(tpsys->part->dup_ob==ob)
+ tpsys->part->dup_ob= NULL;
+
+ if(tpsys->part->flag&PART_STICKY) {
+ ParticleData *pa;
+ int p;
+
+ for(p=0,pa=tpsys->particles; p<tpsys->totpart; p++,pa++) {
+ if(pa->stick_ob==ob) {
+ pa->stick_ob= 0;
+ pa->flag &= ~PARS_STICKY;
+ }
+ }
+ }
+ }
+ if(ob->pd)
+ obt->recalc |= OB_RECALC_DATA;
+ }
+
obt= obt->id.next;
}
@@ -473,6 +572,15 @@ void unlink_object(Object *ob)
rem_from_group(group, ob);
group= group->id.next;
}
+
+ /* cameras */
+ camera= G.main->camera.first;
+ while(camera) {
+ if (camera->dof_ob==ob) {
+ camera->dof_ob = NULL;
+ }
+ camera= camera->id.next;
+ }
}
int exist_object(Object *obtest)
@@ -573,7 +681,23 @@ void make_local_camera(Camera *cam)
}
}
-
+/* get the camera's dof value, takes the dof object into account */
+float dof_camera(Object *ob)
+{
+ Camera *cam = (Camera *)ob->data;
+ if (ob->type != OB_CAMERA)
+ return 0.0;
+ if (cam->dof_ob) {
+ /* too simple, better to return the distance on the view axis only
+ * return VecLenf(ob->obmat[3], cam->dof_ob->obmat[3]); */
+
+ float mat[4][4];
+ Mat4Invert(ob->imat, ob->obmat);
+ Mat4MulMat4(mat, cam->dof_ob->obmat, ob->imat);
+ return fabs(mat[3][2]);
+ }
+ return cam->YF_dofdist;
+}
void *add_lamp(char *name)
{
@@ -599,7 +723,12 @@ void *add_lamp(char *name)
la->area_size=la->area_sizey=la->area_sizez= 1.0;
la->buffers= 1;
la->buftype= LA_SHADBUF_HALFWAY;
-
+ la->ray_samp_method = LA_SAMP_HALTON;
+ la->adapt_thresh = 0.001;
+ la->preview=NULL;
+ la->falloff_type = LA_FALLOFF_INVLINEAR;
+ la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
+ curvemapping_initialize(la->curfalloff);
return la;
}
@@ -618,8 +747,12 @@ Lamp *copy_lamp(Lamp *la)
}
}
+ lan->curfalloff = curvemapping_copy(la->curfalloff);
+
id_us_plus((ID *)lan->ipo);
+ if (la->preview) lan->preview = BKE_previewimg_copy(la->preview);
+
BPY_copy_scriptlink(&la->scriptlink);
return lan;
@@ -690,7 +823,7 @@ void free_lamp(Lamp *la)
/* scriptlinks */
BPY_free_scriptlink(&la->scriptlink);
-
+
for(a=0; a<MAX_MTEX; a++) {
mtex= la->mtex[a];
if(mtex && mtex->tex) mtex->tex->id.us--;
@@ -698,6 +831,9 @@ void free_lamp(Lamp *la)
}
la->ipo= 0;
+ curvemapping_free(la->curfalloff);
+
+ BKE_previewimg_free(&la->preview);
BKE_icon_delete(&la->id);
la->id.icon_id = 0;
}
@@ -772,6 +908,7 @@ Object *add_only_object(int type, char *name)
ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
+ Mat4One(ob->constinv);
Mat4One(ob->parentinv);
Mat4One(ob->obmat);
ob->dt= OB_SHADED;
@@ -791,6 +928,7 @@ Object *add_only_object(int type, char *name)
ob->ipowin= ID_OB; /* the ipowin shown */
ob->dupon= 1; ob->dupoff= 0;
ob->dupsta= 1; ob->dupend= 100;
+ ob->dupfacesca = 1.0;
/* Game engine defaults*/
ob->mass= ob->inertia= 1.0f;
@@ -850,13 +988,15 @@ void base_init_from_view3d(Base *base, View3D *v3d)
VECCOPY(ob->loc, G.scene->cursor);
}
- v3d->viewquat[0]= -v3d->viewquat[0];
- if (ob->transflag & OB_QUAT) {
- QUATCOPY(ob->quat, v3d->viewquat);
- } else {
- QuatToEul(v3d->viewquat, ob->rot);
+ if (U.flag & USER_ADD_VIEWALIGNED) {
+ v3d->viewquat[0]= -v3d->viewquat[0];
+ if (ob->transflag & OB_QUAT) {
+ QUATCOPY(ob->quat, v3d->viewquat);
+ } else {
+ QuatToEul(v3d->viewquat, ob->rot);
+ }
+ v3d->viewquat[0]= -v3d->viewquat[0];
}
- v3d->viewquat[0]= -v3d->viewquat[0];
}
SoftBody *copy_softbody(SoftBody *sb)
@@ -878,19 +1018,102 @@ SoftBody *copy_softbody(SoftBody *sb)
return sbn;
}
+ParticleSystem *copy_particlesystem(ParticleSystem *psys)
+{
+ ParticleSystem *psysn;
+ ParticleData *pa;
+ int a;
+
+ psysn= MEM_dupallocN(psys);
+ psysn->particles= MEM_dupallocN(psys->particles);
+ psysn->child= MEM_dupallocN(psys->child);
+
+ for(a=0, pa=psysn->particles; a<psysn->totpart; a++, pa++) {
+ if(pa->hair)
+ pa->hair= MEM_dupallocN(pa->hair);
+ if(pa->keys)
+ pa->keys= MEM_dupallocN(pa->keys);
+ }
+
+ if(psys->soft) {
+ psysn->soft= copy_softbody(psys->soft);
+ psysn->soft->particles = psysn;
+ }
+
+ psysn->pathcache= NULL;
+ psysn->childcache= NULL;
+ psysn->edit= NULL;
+ psysn->effectors.first= psysn->effectors.last= 0;
+
+ id_us_plus((ID *)psysn->part);
+
+ return psysn;
+}
+
+void copy_object_particlesystems(Object *obn, Object *ob)
+{
+ ParticleSystemModifierData *psmd;
+ ParticleSystem *psys, *npsys;
+ ModifierData *md;
+
+ obn->particlesystem.first= obn->particlesystem.last= NULL;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ npsys= copy_particlesystem(psys);
+
+ BLI_addtail(&obn->particlesystem, npsys);
+
+ /* need to update particle modifiers too */
+ for(md=obn->modifiers.first; md; md=md->next) {
+ if(md->type==eModifierType_ParticleSystem) {
+ psmd= (ParticleSystemModifierData*)md;
+ if(psmd->psys==psys)
+ psmd->psys= npsys;
+ }
+ }
+ }
+}
+
+void copy_object_softbody(Object *obn, Object *ob)
+{
+ if(ob->soft)
+ obn->soft= copy_softbody(ob->soft);
+}
+
static void copy_object_pose(Object *obn, Object *ob)
{
bPoseChannel *chan;
- copy_pose(&obn->pose, ob->pose, 1);
+ copy_pose(&obn->pose, ob->pose, 1); /* 1 = copy constraints */
for (chan = obn->pose->chanbase.first; chan; chan=chan->next){
bConstraint *con;
- char *str;
+
chan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
- for(con= chan->constraints.first; con; con= con->next) {
- if(ob==get_constraint_target(con, &str))
- set_constraint_target(con, obn, NULL);
+
+ for (con= chan->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if(con->ipo) {
+ IpoCurve *icu;
+ for(icu= con->ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver && icu->driver->ob==ob)
+ icu->driver->ob= obn;
+ }
+ }
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == ob)
+ ct->tar = obn;
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
}
}
}
@@ -920,8 +1143,6 @@ Object *copy_object(Object *ob)
BLI_addtail(&obn->modifiers, nmd);
}
- obn->network.first= obn->network.last= 0;
-
BPY_copy_scriptlink(&ob->scriptlink);
copy_properties(&obn->prop, &ob->prop);
@@ -951,7 +1172,11 @@ Object *copy_object(Object *ob)
obn->disp.first= obn->disp.last= NULL;
- if(ob->pd) obn->pd= MEM_dupallocN(ob->pd);
+ if(ob->pd){
+ obn->pd= MEM_dupallocN(ob->pd);
+ if(obn->pd->tex)
+ id_us_plus(&(obn->pd->tex->id));
+ }
obn->soft= copy_softbody(ob->soft);
/* NT copy fluid sim setting memory */
@@ -962,6 +1187,8 @@ Object *copy_object(Object *ob)
obn->fluidsimSettings->orgMesh = (Mesh *)obn->data;
}
}
+
+ copy_object_particlesystems(obn, ob);
obn->derivedDeform = NULL;
obn->derivedFinal = NULL;
@@ -982,6 +1209,7 @@ void expand_local_object(Object *ob)
id_lib_extern((ID *)ob->action);
id_lib_extern((ID *)ob->ipo);
id_lib_extern((ID *)ob->data);
+ id_lib_extern((ID *)ob->dup_group);
for(a=0; a<ob->totcol; a++) {
id_lib_extern((ID *)ob->mat[a]);
@@ -1061,6 +1289,20 @@ void make_local_object(Object *ob)
/* *************** PROXY **************** */
+/* when you make proxy, ensure the exposed layers are extern */
+void armature_set_id_extern(Object *ob)
+{
+ bArmature *arm= ob->data;
+ bPoseChannel *pchan;
+ int lay= arm->layer_protected;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ if(!(pchan->bone->layer & lay))
+ id_lib_extern((ID *)pchan->custom);
+ }
+
+}
+
/* proxy rule: lib_object->proxy_from == the one we borrow from, set temporally while object_update */
/* local_object->proxy == pointer to library object, saved in files and read */
/* local_object->proxy_group == pointer to group dupli-object, saved in files and read */
@@ -1084,6 +1326,8 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
VECCOPY(ob->loc, gob->loc);
VECCOPY(ob->rot, gob->rot);
VECCOPY(ob->size, gob->size);
+
+ group_tag_recalc(gob->dup_group);
}
else {
VECCOPY(ob->loc, target->loc);
@@ -1097,6 +1341,7 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
/* skip constraints, constraintchannels, nla? */
+
ob->type= target->type;
ob->data= target->data;
id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_EXTERN */
@@ -1106,6 +1351,8 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
copy_object_pose(ob, target); /* data copy, object pointers in constraints */
rest_pose(ob->pose); /* clear all transforms in channels */
armature_rebuild_pose(ob, ob->data); /* set all internal links */
+
+ armature_set_id_extern(ob);
}
}
@@ -1134,20 +1381,23 @@ void disable_speed_curve(int val)
}
/* ob can be NULL */
-float bsystem_time(Object *ob, Object *par, float cfra, float ofs)
+float bsystem_time(Object *ob, float cfra, float ofs)
{
/* returns float ( see frame_to_float in ipo.c) */
-
+
+ /* bluroffs and fieldoffs are ugly globals that are set by render */
cfra+= bluroffs+fieldoffs;
/* global time */
cfra*= G.scene->r.framelen;
- if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra);
-
- /* ofset frames */
- if(ob && (ob->ipoflag & OB_OFFS_PARENT)) {
- if((ob->partype & PARSLOW)==0) cfra-= ob->sf;
+ 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);
}
cfra-= ofs;
@@ -1217,8 +1467,8 @@ int enable_cu_speed= 1;
static void ob_parcurve(Object *ob, Object *par, float mat[][4])
{
Curve *cu;
- float q[4], vec[4], dir[3], *quat, x1, ctime;
- float timeoffs= 0.0;
+ float q[4], vec[4], dir[3], quat[4], x1, ctime;
+ float timeoffs = 0.0, sf_orig = 0.0;
Mat4One(mat);
@@ -1229,7 +1479,8 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4])
/* exception, timeoffset is regarded as distance offset */
if(cu->flag & CU_OFFS_PATHDIST) {
- SWAP(float, timeoffs, ob->sf);
+ timeoffs = give_timeoffset(ob);
+ SWAP(float, sf_orig, ob->sf);
}
/* catch exceptions: feature for nla stride editing */
@@ -1238,7 +1489,7 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4])
}
/* catch exceptions: curve paths used as a duplicator */
else if(enable_cu_speed) {
- ctime= bsystem_time(ob, par, (float)G.scene->r.cfra, 0.0);
+ ctime= bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
ctime /= cu->pathlen;
@@ -1246,7 +1497,7 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4])
}
}
else {
- ctime= G.scene->r.cfra - ob->sf;
+ ctime= G.scene->r.cfra - give_timeoffset(ob);
ctime /= cu->pathlen;
CLAMP(ctime, 0.0, 1.0);
@@ -1257,7 +1508,7 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4])
ctime += timeoffs/cu->path->totdist;
/* restore */
- SWAP(float, timeoffs, ob->sf);
+ SWAP(float, sf_orig, ob->sf);
}
@@ -1265,7 +1516,7 @@ static void ob_parcurve(Object *ob, Object *par, float mat[][4])
if( where_on_path(par, ctime, vec, dir) ) {
if(cu->flag & CU_FOLLOW) {
- quat= vectoquat(dir, ob->trackflag, ob->upflag);
+ vectoquat(dir, ob->trackflag, ob->upflag, quat);
/* the tilt */
Normalize(dir);
@@ -1490,7 +1741,7 @@ void where_is_object_time(Object *ob, float ctime)
if(ob==NULL) return;
/* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
- stime= bsystem_time(ob, 0, ctime, 0.0);
+ stime= bsystem_time(ob, ctime, 0.0);
if(stime != ob->ctime) {
ob->ctime= stime;
@@ -1502,18 +1753,20 @@ void where_is_object_time(Object *ob, float ctime)
else
do_all_object_actions(ob);
- /* do constraint ipos ..., note it needs stime */
- do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime);
+ /* 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);
}
if(ob->parent) {
Object *par= ob->parent;
- if(ob->ipoflag & OB_OFFS_PARENT) ctime-= ob->sf;
+ if(ob->ipoflag & OB_OFFS_PARENT) ctime-= give_timeoffset(ob);
/* hurms, code below conflicts with depgraph... (ton) */
/* and even worse, it gives bad effects for NLA stride too (try ctime != par->ctime, with MBlur) */
@@ -1537,7 +1790,7 @@ void where_is_object_time(Object *ob, float ctime)
if(ob->partype & PARSLOW) {
// include framerate
- fac1= (1.0f/(1.0f+ fabs(ob->sf)));
+ fac1= (1.0f/(1.0f+ fabs(give_timeoffset(ob))));
if(fac1>=1.0) return;
fac2= 1.0f-fac1;
@@ -1560,9 +1813,18 @@ void where_is_object_time(Object *ob, float ctime)
}
- /* constraints need ctime, not stime. it calls where_is_object_time and bsystem_time */
- solve_constraints (ob, TARGET_OBJECT, NULL, ctime);
-
+ /* solve constraints */
+ if (ob->constraints.first) {
+ bConstraintOb *cob;
+
+ cob= constraints_make_evalob(ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+
+ /* constraints need ctime, not stime. Some call where_is_object_time and bsystem_time */
+ solve_constraints (&ob->constraints, cob, ctime);
+
+ constraints_clear_evalob(cob);
+ }
+
if(ob->scriptlink.totscript && !during_script()) {
if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_REDRAW);
}
@@ -1654,13 +1916,13 @@ static void solve_parenting (Object *ob, Object *par, float obmat[][4], float sl
}
void solve_tracking (Object *ob, float targetmat[][4])
{
- float *quat;
+ float quat[4];
float vec[3];
float totmat[3][3];
float tmat[4][4];
VecSubf(vec, ob->obmat[3], targetmat[3]);
- quat= vectoquat(vec, ob->trackflag, ob->upflag);
+ vectoquat(vec, ob->trackflag, ob->upflag, quat);
QuatToMat3(quat, totmat);
if(ob->parent && (ob->transflag & OB_POWERTRACK)) {
@@ -1711,7 +1973,7 @@ for a lamp that is the child of another object */
if(ob->partype & PARSLOW) {
- fac1= (float)(1.0/(1.0+ fabs(ob->sf)));
+ fac1= (float)(1.0/(1.0+ fabs(give_timeoffset(ob))));
fac2= 1.0f-fac1;
fp1= ob->obmat[0];
fp2= slowmat[0];
@@ -1728,132 +1990,26 @@ for a lamp that is the child of another object */
if(ob->track)
solve_tracking(ob, ob->track->obmat);
- solve_constraints(ob, TARGET_OBJECT, NULL, G.scene->r.cfra);
+ /* solve constraints */
+ if (ob->constraints.first) {
+ bConstraintOb *cob;
+
+ cob= constraints_make_evalob(ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ solve_constraints (&ob->constraints, cob, G.scene->r.cfra);
+ constraints_clear_evalob(cob);
+ }
/* WATCH IT!!! */
ob->ipo= ipo;
-
-}
-extern void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight);
-
-void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
-{
- bConstraint *con;
- float tmat[4][4], focusmat[4][4], lastmat[4][4];
- int i, clear=1, tot=0;
- float a=0;
- float aquat[4], quat[4];
- float aloc[3], loc[3];
- float asize[3], size[3];
- float oldmat[4][4];
- float smat[3][3], rmat[3][3], mat[3][3];
- float enf;
-
- for (con = ob->constraints.first; con; con=con->next) {
- // inverse kinematics is solved seperate
- if (con->type==CONSTRAINT_TYPE_KINEMATIC) continue;
- // and this we can skip completely
- if (con->flag & CONSTRAINT_DISABLE) continue;
- // local constraints are handled in armature.c only
- if (con->flag & CONSTRAINT_LOCAL) continue;
-
- /* Clear accumulators if necessary*/
- if (clear) {
- clear= 0;
- a= 0;
- tot= 0;
- memset(aquat, 0, sizeof(float)*4);
- memset(aloc, 0, sizeof(float)*3);
- memset(asize, 0, sizeof(float)*3);
- }
-
- enf = con->enforce; // value from ipos (from action channels)
-
- /* Get the targetmat */
- get_constraint_target_matrix(con, obtype, obdata, tmat, size, ctime);
-
- Mat4CpyMat4(focusmat, tmat);
-
- /* Extract the components & accumulate */
- Mat4ToQuat(focusmat, quat);
- VECCOPY(loc, focusmat[3]);
- Mat3CpyMat4(mat, focusmat);
- Mat3ToSize(mat, size);
-
- a+= enf;
- tot++;
-
- for(i=0; i<3; i++) {
- aquat[i+1]+=(quat[i+1]) * enf;
- aloc[i]+=(loc[i]) * enf;
- asize[i]+=(size[i]-1.0f) * enf;
- }
- aquat[0]+=(quat[0])*enf;
- Mat4CpyMat4(lastmat, focusmat);
-
- /* removed for now, probably becomes option? (ton) */
-
- /* If the next constraint is not the same type (or there isn't one),
- * then evaluate the accumulator & request a clear */
- if (TRUE) { //(!con->next)||(con->next && con->next->type!=con->type)) {
- clear= 1;
- Mat4CpyMat4(oldmat, ob->obmat);
-
- /* If we have several inputs, do a blend of them */
- if (tot) {
- if (tot>1) {
- if (a) {
- for (i=0; i<3; i++) {
- asize[i]=1.0f + (asize[i]/(a));
- aloc[i]=(aloc[i]/a);
- }
-
- NormalQuat(aquat);
-
- QuatToMat3(aquat, rmat);
- SizeToMat3(asize, smat);
- Mat3MulMat3(mat, rmat, smat);
- Mat4CpyMat3(focusmat, mat);
- VECCOPY(focusmat[3], aloc);
-
- evaluate_constraint(con, ob, obtype, obdata, focusmat);
- }
-
- }
- /* If we only have one, blend with the current obmat */
- else {
- float solution[4][4];
- float delta[4][4];
- float imat[4][4];
- float identity[4][4];
-
- /* solve the constraint then blend it to the previous one */
- evaluate_constraint(con, ob, obtype, obdata, lastmat);
-
- Mat4CpyMat4 (solution, ob->obmat);
-
- /* Interpolate the enforcement */
- Mat4Invert (imat, oldmat);
- Mat4MulMat4 (delta, solution, imat);
-
- if (a<1.0) {
- Mat4One(identity);
- Mat4BlendMat4(delta, identity, delta, a);
- }
- Mat4MulMat4 (ob->obmat, delta, oldmat);
- }
- }
- }
- }
}
/* for calculation of the inverse parent transform, only used for editor */
void what_does_parent(Object *ob)
{
-
clear_workob();
Mat4One(workob.obmat);
Mat4One(workob.parentinv);
+ Mat4One(workob.constinv);
workob.parent= ob->parent;
workob.track= ob->track;
@@ -1868,7 +2024,7 @@ void what_does_parent(Object *ob)
workob.constraints.first = ob->constraints.first;
workob.constraints.last = ob->constraints.last;
- strcpy (workob.parsubstr, ob->parsubstr);
+ strcpy(workob.parsubstr, ob->parsubstr);
where_is_object(&workob);
}
@@ -1878,7 +2034,7 @@ BoundBox *unit_boundbox()
BoundBox *bb;
float min[3] = {-1,-1,-1}, max[3] = {-1,-1,-1};
- bb= MEM_mallocN(sizeof(BoundBox), "bb");
+ bb= MEM_callocN(sizeof(BoundBox), "bb");
boundbox_set_from_min_max(bb, min, max);
return bb;
@@ -1901,7 +2057,7 @@ BoundBox *object_get_boundbox(Object *ob)
BoundBox *bb= NULL;
if(ob->type==OB_MESH) {
- bb = mesh_get_bb(ob->data);
+ bb = mesh_get_bb(ob);
}
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
bb= ( (Curve *)ob->data )->bb;
@@ -1963,7 +2119,7 @@ void minmax_object(Object *ob, float *min, float *max)
me= get_mesh(ob);
if(me) {
- bb = *mesh_get_bb(me);
+ bb = *mesh_get_bb(ob);
for(a=0; a<8; a++) {
Mat4MulVecfl(ob->obmat, bb.vec[a]);
@@ -2038,6 +2194,7 @@ void object_handle_update(Object *ob)
}
else
where_is_object(ob);
+ if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_OBJECTUPDATE);
}
if(ob->recalc & OB_RECALC_DATA) {
@@ -2071,8 +2228,41 @@ void object_handle_update(Object *ob)
where_is_pose(ob);
}
}
+
+ if(ob->particlesystem.first) {
+ ParticleSystem *tpsys, *psys;
+ DerivedMesh *dm;
+
+ psys= ob->particlesystem.first;
+ while(psys) {
+ if(psys_check_enabled(ob, psys)) {
+ particle_system_update(ob, psys);
+ psys= psys->next;
+ }
+ else if(psys->flag & PSYS_DELETE) {
+ tpsys=psys->next;
+ BLI_remlink(&ob->particlesystem, psys);
+ psys_free(ob,psys);
+ psys= tpsys;
+ }
+ else
+ psys= psys->next;
+ }
+
+ if(G.rendering && ob->transflag & OB_DUPLIPARTS) {
+ /* this is to make sure we get render level duplis in groups:
+ * the derivedmesh must be created before init_render_mesh,
+ * since object_duplilist does dupliparticles before that */
+ dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+ dm->release(dm);
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
+ }
+ }
+ if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_OBDATAUPDATE);
}
-
+
/* the no-group proxy case, we call update */
if(ob->proxy && ob->proxy_group==NULL) {
/* set pointer in library proxy target, for copying, but restore it */
@@ -2090,3 +2280,11 @@ void object_handle_update(Object *ob)
// printf("set proxy pointer for later group stuff %s\n", ob->id.name);
}
}
+
+float give_timeoffset(Object *ob) {
+ if ((ob->ipoflag & OB_OFFS_PARENTADD) && ob->parent) {
+ return ob->sf + give_timeoffset(ob->parent);
+ } else {
+ return ob->sf;
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
new file mode 100644
index 00000000000..27c4091e36f
--- /dev/null
+++ b/source/blender/blenkernel/intern/particle.c
@@ -0,0 +1,3779 @@
+/* particle.c
+ *
+ *
+ * $Id: particle.c $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_force.h"
+#include "DNA_texture_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_key_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
+#include "BLI_kdtree.h"
+#include "BLI_linklist.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+
+#include "BKE_anim.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_lattice.h"
+#include "BKE_utildefines.h"
+#include "BKE_displist.h"
+#include "BKE_particle.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_ipo.h"
+#include "BKE_object.h"
+#include "BKE_softbody.h"
+#include "BKE_material.h"
+#include "BKE_key.h"
+#include "BKE_library.h"
+#include "BKE_depsgraph.h"
+#include "BKE_bad_level_calls.h"
+#include "BKE_modifier.h"
+#include "BKE_mesh.h"
+#include "BKE_cdderivedmesh.h"
+
+#include "blendef.h"
+#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);
+
+/* few helpers for countall etc. */
+int count_particles(ParticleSystem *psys){
+ ParticleSettings *part=psys->part;
+ ParticleData *pa;
+ int tot=0,p;
+
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++){
+ if(pa->alive == PARS_KILLED);
+ else 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;
+}
+int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
+ ParticleSettings *part=psys->part;
+ ParticleData *pa;
+ int tot=0,p;
+
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++){
+ if(pa->alive == PARS_KILLED);
+ else 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)
+{
+ ParticleData *pa;
+ int i, totpart=psys->totpart, totkey=0;
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++)
+ 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;
+}
+/************************************************/
+/* Getting stuff */
+/************************************************/
+/* get object's active particle system safely */
+ParticleSystem *psys_get_current(Object *ob)
+{
+ ParticleSystem *psys;
+ if(ob==0) return 0;
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ if(psys->flag & PSYS_CURRENT)
+ return psys;
+ }
+
+ return 0;
+}
+short psys_get_current_num(Object *ob)
+{
+ ParticleSystem *psys;
+ short i;
+
+ if(ob==0) return 0;
+
+ for(psys=ob->particlesystem.first, i=0; psys; psys=psys->next, i++)
+ if(psys->flag & PSYS_CURRENT)
+ return i;
+
+ return i;
+}
+/* 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(Object *ob, ParticleSystem *psys)
+{
+ Object *lattice=0;
+
+ if(psys_in_edit_mode(psys)==0){
+
+ ModifierData *md = (ModifierData*)psys_get_modifier(ob,psys);
+
+ for(; md; md=md->next){
+ if(md->type==eModifierType_Lattice){
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ lattice=lmd->object;
+ break;
+ }
+ }
+ if(lattice)
+ init_latt_deform(lattice,0);
+ }
+
+ return lattice;
+}
+void psys_disable_all(Object *ob)
+{
+ ParticleSystem *psys=ob->particlesystem.first;
+
+ for(; psys; psys=psys->next)
+ psys->flag &= ~PSYS_ENABLED;
+}
+void psys_enable_all(Object *ob)
+{
+ ParticleSystem *psys=ob->particlesystem.first;
+
+ for(; psys; psys=psys->next)
+ psys->flag |= PSYS_ENABLED;
+}
+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(ParticleSystem *psys)
+{
+ return ((G.f & G_PARTICLEEDIT) && psys==psys_get_current(OBACT) && psys->edit);
+}
+int psys_check_enabled(Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd;
+
+ if(!(psys->flag & PSYS_ENABLED))
+ return 0;
+
+ psmd= psys_get_modifier(ob, psys);
+ if(psys->renderdata) {
+ if(!(psmd->modifier.mode & eModifierMode_Render))
+ return 0;
+ }
+ else if(!(psmd->modifier.mode & eModifierMode_Realtime))
+ return 0;
+
+ return 1;
+}
+
+/************************************************/
+/* Freeing stuff */
+/************************************************/
+void psys_free_settings(ParticleSettings *part)
+{
+ if(part->pd)
+ MEM_freeN(part->pd);
+}
+void free_hair(ParticleSystem *psys)
+{
+ ParticleData *pa;
+ int i, totpart=psys->totpart;
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ pa->hair = NULL;
+ }
+
+ psys->flag &= ~PSYS_HAIR_DONE;
+
+ if(psys->soft) {
+ sbFree(psys->soft);
+ psys->soft = NULL;
+ }
+}
+void free_keyed_keys(ParticleSystem *psys)
+{
+ if(psys->particles && psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
+}
+void free_child_path_cache(ParticleSystem *psys)
+{
+ if(psys->childcache){
+ if(psys->childcache[0])
+ MEM_freeN(psys->childcache[0]);
+
+ MEM_freeN(psys->childcache);
+
+ psys->childcache = NULL;
+ psys->totchildcache = 0;
+ }
+}
+void psys_free_path_cache(ParticleSystem *psys)
+{
+ if(psys->pathcache){
+ if(psys->pathcache[0])
+ MEM_freeN(psys->pathcache[0]);
+
+ MEM_freeN(psys->pathcache);
+
+ psys->pathcache = NULL;
+ psys->totcached = 0;
+ }
+ free_child_path_cache(psys);
+}
+void psys_free_children(ParticleSystem *psys)
+{
+ if(psys->child) {
+ MEM_freeN(psys->child);
+ psys->child=0;
+ psys->totchild=0;
+ }
+
+ free_child_path_cache(psys);
+}
+/* free everything */
+void psys_free(Object *ob, ParticleSystem * psys)
+{
+ if(psys){
+ if(ob->particlesystem.first == NULL && G.f & G_PARTICLEEDIT)
+ G.f &= ~G_PARTICLEEDIT;
+
+ psys_free_path_cache(psys);
+
+ free_hair(psys);
+
+ free_keyed_keys(psys);
+
+ PE_free_particle_edit(psys);
+
+ if(psys->particles){
+ MEM_freeN(psys->particles);
+ psys->particles = 0;
+ psys->totpart = 0;
+ }
+
+ if(psys->child){
+ MEM_freeN(psys->child);
+ psys->child = 0;
+ psys->totchild = 0;
+ }
+
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+
+ if(psys->part){
+ psys->part->id.us--;
+ psys->part=0;
+ }
+
+ MEM_freeN(psys);
+ }
+}
+
+/* these functions move away particle data and bring it back after
+ * rendering, to make different render settings possible without
+ * removing the previous data. this should be solved properly once */
+
+typedef struct ParticleRenderElem {
+ int curchild, totchild, reduce;
+ float lambda, t, scalemin, scalemax;
+} ParticleRenderElem;
+
+typedef struct ParticleRenderData {
+ ChildParticle *child;
+ ParticleCacheKey **pathcache;
+ ParticleCacheKey **childcache;
+ int totchild, totcached, totchildcache;
+ DerivedMesh *dm;
+ int totdmvert, totdmedge, totdmface;
+
+ float mat[4][4];
+ float viewmat[4][4], winmat[4][4];
+ int winx, winy;
+
+ int dosimplify;
+ int timeoffset;
+ ParticleRenderElem *elems;
+ int *origindex;
+} ParticleRenderData;
+
+static float psys_render_viewport_falloff(double rate, float dist, float width)
+{
+ return pow(rate, dist/width);
+}
+
+static float psys_render_projected_area(ParticleSystem *psys, float *center, float area, double vprate, float *viewport)
+{
+ ParticleRenderData *data= psys->renderdata;
+ float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius;
+
+ /* transform to view space */
+ VECCOPY(co, center);
+ co[3]= 1.0f;
+ Mat4MulVec4fl(data->viewmat, co);
+
+ /* compute two vectors orthogonal to view vector */
+ VECCOPY(view, co);
+ Normalize(view);
+ VecOrthoBasisf(view, ortho1, ortho2);
+
+ /* compute on screen minification */
+ w= co[2]*data->winmat[2][3] + data->winmat[3][3];
+ dx= data->winx*ortho2[0]*data->winmat[0][0];
+ dy= data->winy*ortho2[1]*data->winmat[1][1];
+ w= sqrt(dx*dx + dy*dy)/w;
+
+ /* w squared because we are working with area */
+ area= area*w*w;
+
+ /* viewport of the screen test */
+
+ /* project point on screen */
+ Mat4MulVec4fl(data->winmat, co);
+ if(co[3] != 0.0f) {
+ co[0]= 0.5f*data->winx*(1.0f + co[0]/co[3]);
+ co[1]= 0.5f*data->winy*(1.0f + co[1]/co[3]);
+ }
+
+ /* screen space radius */
+ radius= sqrt(area/M_PI);
+
+ /* make smaller using fallof once over screen edge */
+ *viewport= 1.0f;
+
+ if(co[0]+radius < 0.0f)
+ *viewport *= psys_render_viewport_falloff(vprate, -(co[0]+radius), data->winx);
+ else if(co[0]-radius > data->winx)
+ *viewport *= psys_render_viewport_falloff(vprate, (co[0]-radius) - data->winx, data->winx);
+
+ if(co[1]+radius < 0.0f)
+ *viewport *= psys_render_viewport_falloff(vprate, -(co[1]+radius), data->winy);
+ else if(co[1]-radius > data->winy)
+ *viewport *= psys_render_viewport_falloff(vprate, (co[1]-radius) - data->winy, data->winy);
+
+ return area;
+}
+
+void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset)
+{
+ ParticleRenderData*data;
+ ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
+
+ if(!G.rendering)
+ return;
+ if(psys->renderdata)
+ return;
+
+ data= MEM_callocN(sizeof(ParticleRenderData), "ParticleRenderData");
+
+ data->child= psys->child;
+ data->totchild= psys->totchild;
+ data->pathcache= psys->pathcache;
+ data->totcached= psys->totcached;
+ data->childcache= psys->childcache;
+ data->totchildcache= psys->totchildcache;
+
+ if(psmd->dm)
+ data->dm= CDDM_copy(psmd->dm);
+ data->totdmvert= psmd->totdmvert;
+ data->totdmedge= psmd->totdmedge;
+ data->totdmface= psmd->totdmface;
+
+ psys->child= NULL;
+ psys->pathcache= NULL;
+ psys->childcache= NULL;
+ psys->totchild= psys->totcached= psys->totchildcache= 0;
+
+ Mat4CpyMat4(data->winmat, winmat);
+ Mat4MulMat4(data->viewmat, ob->obmat, viewmat);
+ Mat4MulMat4(data->mat, data->viewmat, winmat);
+ data->winx= winx;
+ data->winy= winy;
+
+ data->timeoffset= timeoffset;
+
+ psys->renderdata= data;
+}
+
+void psys_render_restore(Object *ob, ParticleSystem *psys)
+{
+ ParticleRenderData*data;
+ ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
+
+ data= psys->renderdata;
+ if(!data)
+ return;
+
+ if(data->elems)
+ MEM_freeN(data->elems);
+
+ if(psmd->dm) {
+ psmd->dm->needsFree= 1;
+ psmd->dm->release(psmd->dm);
+ }
+
+ psys_free_path_cache(psys);
+
+ if(psys->child){
+ MEM_freeN(psys->child);
+ psys->child= 0;
+ psys->totchild= 0;
+ }
+
+ psys->child= data->child;
+ psys->totchild= data->totchild;
+ psys->pathcache= data->pathcache;
+ psys->totcached= data->totcached;
+ psys->childcache= data->childcache;
+ psys->totchildcache= data->totchildcache;
+
+ psmd->dm= data->dm;
+ psmd->totdmvert= data->totdmvert;
+ psmd->totdmedge= data->totdmedge;
+ psmd->totdmface= data->totdmface;
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+
+ if(psmd->dm)
+ psys_calc_dmcache(ob, psmd->dm, psys);
+
+ MEM_freeN(data);
+ psys->renderdata= NULL;
+}
+
+int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
+{
+ DerivedMesh *dm= ctx->dm;
+ Mesh *me= (Mesh*)(ctx->ob->data);
+ MFace *mf, *mface;
+ MVert *mvert;
+ ParticleRenderData *data;
+ ParticleRenderElem *elems, *elem;
+ ParticleSettings *part= ctx->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;
+ int *origindex, *facetotvert;
+ int a, b, totorigface, totface, newtot, skipped;
+
+ if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
+ return tot;
+ if(!ctx->psys->renderdata)
+ return tot;
+
+ data= ctx->psys->renderdata;
+ if(data->timeoffset)
+ return 0;
+ if(!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
+ return tot;
+
+ mvert= dm->getVertArray(dm);
+ mface= dm->getFaceArray(dm);
+ origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ totface= dm->getNumFaces(dm);
+ totorigface= me->totface;
+
+ if(totface == 0 || totorigface == 0 || origindex == NULL)
+ return tot;
+
+ facearea= MEM_callocN(sizeof(float)*totorigface, "SimplifyFaceArea");
+ facecenter= MEM_callocN(sizeof(float[3])*totorigface, "SimplifyFaceCenter");
+ facetotvert= MEM_callocN(sizeof(int)*totorigface, "SimplifyFaceArea");
+ elems= MEM_callocN(sizeof(ParticleRenderElem)*totorigface, "SimplifyFaceElem");
+
+ if(data->elems)
+ MEM_freeN(data->elems);
+
+ data->dosimplify= 1;
+ data->elems= elems;
+ data->origindex= origindex;
+
+ /* compute number of children per original face */
+ for(a=0; a<tot; a++) {
+ b= origindex[ctx->index[a]];
+ if(b != -1)
+ elems[b].totchild++;
+ }
+
+ /* compute areas and centers of original faces */
+ for(mf=mface, a=0; a<totface; a++, mf++) {
+ b= origindex[a];
+
+ if(b != -1) {
+ VECCOPY(co1, mvert[mf->v1].co);
+ VECCOPY(co2, mvert[mf->v2].co);
+ VECCOPY(co3, mvert[mf->v3].co);
+
+ VECADD(facecenter[b], facecenter[b], co1);
+ VECADD(facecenter[b], facecenter[b], co2);
+ VECADD(facecenter[b], facecenter[b], co3);
+
+ if(mf->v4) {
+ VECCOPY(co4, mvert[mf->v4].co);
+ VECADD(facecenter[b], facecenter[b], co4);
+ facearea[b] += AreaQ3Dfl(co1, co2, co3, co4);
+ facetotvert[b] += 4;
+ }
+ else {
+ facearea[b] += AreaT3Dfl(co1, co2, co3);
+ facetotvert[b] += 3;
+ }
+ }
+ }
+
+ for(a=0; a<totorigface; a++)
+ if(facetotvert[a] > 0)
+ VecMulf(facecenter[a], 1.0f/facetotvert[a]);
+
+ /* for conversion from BU area / pixel area to reference screen size */
+ mesh_get_texspace(me, 0, 0, size);
+ fac= ((size[0] + size[1] + size[2])/3.0f)/part->simplify_refsize;
+ fac= fac*fac;
+
+ powrate= log(0.5f)/log(part->simplify_rate*0.5f);
+ if(part->simplify_flag & PART_SIMPLIFY_VIEWPORT)
+ vprate= pow(1.0 - part->simplify_viewport, 5.0);
+ else
+ vprate= 1.0;
+
+ /* 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);
+ arearatio= fac*area/facearea[a];
+
+ if((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
+ /* lambda is percentage of elements to keep */
+ lambda= (arearatio < 1.0f)? pow(arearatio, powrate): 1.0f;
+ lambda *= viewport;
+
+ lambda= MAX2(lambda, 1.0f/elem->totchild);
+
+ /* compute transition region */
+ t= part->simplify_transition;
+ elem->t= (lambda-t < 0.0f)? lambda: (lambda+t > 1.0f)? 1.0f-lambda: t;
+ elem->reduce= 1;
+
+ /* scale at end and beginning of the transition region */
+ elem->scalemax= (lambda+t < 1.0f)? 1.0f/lambda: 1.0f/(1.0f - elem->t*elem->t/t);
+ elem->scalemin= (lambda+t < 1.0f)? 0.0f: elem->scalemax*(1.0f-elem->t/t);
+
+ elem->scalemin= sqrt(elem->scalemin);
+ elem->scalemax= sqrt(elem->scalemax);
+
+ /* clamp scaling */
+ scaleclamp= MIN2(elem->totchild, 10.0f);
+ elem->scalemin= MIN2(scaleclamp, elem->scalemin);
+ elem->scalemax= MIN2(scaleclamp, elem->scalemax);
+
+ /* extend lambda to include transition */
+ lambda= lambda + elem->t;
+ if(lambda > 1.0f)
+ lambda= 1.0f;
+ }
+ else {
+ lambda= arearatio;
+
+ elem->scalemax= 1.0f; //sqrt(lambda);
+ elem->scalemin= 1.0f; //sqrt(lambda);
+ elem->reduce= 0;
+ }
+
+ elem->lambda= lambda;
+ elem->scalemin= sqrt(elem->scalemin);
+ elem->scalemax= sqrt(elem->scalemax);
+ elem->curchild= 0;
+ }
+
+ MEM_freeN(facearea);
+ MEM_freeN(facecenter);
+ MEM_freeN(facetotvert);
+
+ /* move indices and set random number skipping */
+ ctx->skip= MEM_callocN(sizeof(int)*tot, "SimplificationSkip");
+
+ skipped= 0;
+ for(a=0, newtot=0; a<tot; a++) {
+ b= origindex[ctx->index[a]];
+ if(b != -1) {
+ if(elems[b].curchild++ < ceil(elems[b].lambda*elems[b].totchild)) {
+ ctx->index[newtot]= ctx->index[a];
+ ctx->skip[newtot]= skipped;
+ skipped= 0;
+ newtot++;
+ }
+ else skipped++;
+ }
+ else skipped++;
+ }
+
+ for(a=0, elem=elems; a<totorigface; a++, elem++)
+ elem->curchild= 0;
+
+ return newtot;
+}
+
+int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params)
+{
+ ParticleRenderData *data;
+ ParticleRenderElem *elem;
+ float x, w, scale, alpha, lambda, t, scalemin, scalemax;
+ int b;
+
+ if(!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE)))
+ return 0;
+
+ data= psys->renderdata;
+ if(!data->dosimplify)
+ return 0;
+
+ b= data->origindex[cpa->num];
+ if(b == -1)
+ return 0;
+
+ elem= &data->elems[b];
+
+ lambda= elem->lambda;
+ t= elem->t;
+ scalemin= elem->scalemin;
+ scalemax= elem->scalemax;
+
+ if(!elem->reduce) {
+ scale= scalemin;
+ alpha= 1.0f;
+ }
+ else {
+ x= (elem->curchild+0.5f)/elem->totchild;
+ if(x < lambda-t) {
+ scale= scalemax;
+ alpha= 1.0f;
+ }
+ else if(x >= lambda+t) {
+ scale= scalemin;
+ alpha= 0.0f;
+ }
+ else {
+ w= (lambda+t - x)/(2.0f*t);
+ scale= scalemin + (scalemax - scalemin)*w;
+ alpha= w;
+ }
+ }
+
+ params[0]= scale;
+ params[1]= alpha;
+
+ elem->curchild++;
+
+ return 1;
+}
+
+/************************************************/
+/* Interpolated Particles */
+/************************************************/
+static float interpolate_particle_value(float v1, float v2, float v3, float v4, float *w, int four)
+{
+ float value;
+
+ value= w[0]*v1 + w[1]*v2 + w[2]*v3;
+ if(four)
+ value += w[3]*v4;
+
+ return value;
+}
+static void weighted_particle_vector(float *v1, float *v2, float *v3, float *v4, float *weights, float *vec)
+{
+ vec[0]= weights[0]*v1[0] + weights[1]*v2[0] + weights[2]*v3[0] + weights[3]*v4[0];
+ vec[1]= weights[0]*v1[1] + weights[1]*v2[1] + weights[2]*v3[1] + weights[3]*v4[1];
+ vec[2]= weights[0]*v1[2] + weights[1]*v2[2] + weights[2]*v3[2] + weights[3]*v4[2];
+}
+static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
+{
+ float t[4];
+
+ if(type<0) {
+ VecfCubicInterpol(keys[1].co, keys[1].vel, keys[2].co, keys[2].vel, dt, result->co, result->vel);
+ }
+ else {
+ set_four_ipo(dt, t, type);
+
+ weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, result->co);
+
+ if(velocity){
+ float temp[3];
+
+ if(dt>0.999f){
+ set_four_ipo(dt-0.001f, t, type);
+ weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
+ VECSUB(result->vel, result->co, temp);
+ }
+ else{
+ set_four_ipo(dt+0.001f, t, type);
+ weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp);
+ VECSUB(result->vel, temp, result->co);
+ }
+ }
+ }
+}
+
+
+
+/************************************************/
+/* Particles on a dm */
+/************************************************/
+/* interpolate a location on a face based on face coordinates */
+void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], float *w, float *vec, float *nor, float *utan, float *vtan, float *orco,float *ornor){
+ float *v1=0, *v2=0, *v3=0, *v4=0;
+ float e1[3],e2[3],s1,s2,t1,t2;
+ float *uv1, *uv2, *uv3, *uv4;
+ float n1[3], n2[3], n3[3], n4[3];
+ float tuv[4][2];
+ float *o1, *o2, *o3, *o4;
+
+ v1= (mvert+mface->v1)->co;
+ v2= (mvert+mface->v2)->co;
+ v3= (mvert+mface->v3)->co;
+ VECCOPY(n1,(mvert+mface->v1)->no);
+ VECCOPY(n2,(mvert+mface->v2)->no);
+ VECCOPY(n3,(mvert+mface->v3)->no);
+ Normalize(n1);
+ Normalize(n2);
+ Normalize(n3);
+
+ if(mface->v4) {
+ v4= (mvert+mface->v4)->co;
+ VECCOPY(n4,(mvert+mface->v4)->no);
+ Normalize(n4);
+
+ vec[0]= w[0]*v1[0] + w[1]*v2[0] + w[2]*v3[0] + w[3]*v4[0];
+ vec[1]= w[0]*v1[1] + w[1]*v2[1] + w[2]*v3[1] + w[3]*v4[1];
+ vec[2]= w[0]*v1[2] + w[1]*v2[2] + w[2]*v3[2] + w[3]*v4[2];
+
+ if(nor){
+ if(mface->flag & ME_SMOOTH){
+ nor[0]= w[0]*n1[0] + w[1]*n2[0] + w[2]*n3[0] + w[3]*n4[0];
+ nor[1]= w[0]*n1[1] + w[1]*n2[1] + w[2]*n3[1] + w[3]*n4[1];
+ nor[2]= w[0]*n1[2] + w[1]*n2[2] + w[2]*n3[2] + w[3]*n4[2];
+ }
+ else
+ CalcNormFloat4(v1,v2,v3,v4,nor);
+ }
+ }
+ else {
+ vec[0]= w[0]*v1[0] + w[1]*v2[0] + w[2]*v3[0];
+ vec[1]= w[0]*v1[1] + w[1]*v2[1] + w[2]*v3[1];
+ vec[2]= w[0]*v1[2] + w[1]*v2[2] + w[2]*v3[2];
+
+ if(nor){
+ if(mface->flag & ME_SMOOTH){
+ nor[0]= w[0]*n1[0] + w[1]*n2[0] + w[2]*n3[0];
+ nor[1]= w[0]*n1[1] + w[1]*n2[1] + w[2]*n3[1];
+ nor[2]= w[0]*n1[2] + w[1]*n2[2] + w[2]*n3[2];
+ }
+ else
+ CalcNormFloat(v1,v2,v3,nor);
+ }
+ }
+
+ /* calculate tangent vectors */
+ if(utan && vtan){
+ if(tface){
+ uv1= tface->uv[0];
+ uv2= tface->uv[1];
+ uv3= tface->uv[2];
+ uv4= tface->uv[3];
+ }
+ else{
+ uv1= tuv[0]; uv2= tuv[1]; uv3= tuv[2]; uv4= tuv[3];
+ spheremap(v1[0], v1[1], v1[2], uv1, uv1+1);
+ spheremap(v2[0], v2[1], v2[2], uv2, uv2+1);
+ spheremap(v3[0], v3[1], v3[2], uv3, uv3+1);
+ if(v4)
+ spheremap(v4[0], v4[1], v4[2], uv4, uv4+1);
+ }
+
+ if(v4){
+ s1= uv3[0] - uv1[0];
+ s2= uv4[0] - uv1[0];
+
+ t1= uv3[1] - uv1[1];
+ t2= uv4[1] - uv1[1];
+
+ VecSubf(e1, v3, v1);
+ VecSubf(e2, v4, v1);
+ }
+ else{
+ s1= uv2[0] - uv1[0];
+ s2= uv3[0] - uv1[0];
+
+ t1= uv2[1] - uv1[1];
+ t2= uv3[1] - uv1[1];
+
+ VecSubf(e1, v2, v1);
+ VecSubf(e2, v3, v1);
+ }
+
+ vtan[0] = (s1*e2[0] - s2*e1[0]);
+ vtan[1] = (s1*e2[1] - s2*e1[1]);
+ vtan[2] = (s1*e2[2] - s2*e1[2]);
+
+ utan[0] = (t1*e2[0] - t2*e1[0]);
+ utan[1] = (t1*e2[1] - t2*e1[1]);
+ utan[2] = (t1*e2[2] - t2*e1[2]);
+ }
+
+ if(orco) {
+ if(orcodata) {
+ o1= orcodata[mface->v1];
+ o2= orcodata[mface->v2];
+ o3= orcodata[mface->v3];
+
+ if(mface->v4) {
+ o4= orcodata[mface->v4];
+ orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0] + w[3]*o4[0];
+ orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1] + w[3]*o4[1];
+ orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2] + w[3]*o4[2];
+
+ if(ornor)
+ CalcNormFloat4(o1, o2, o3, o4, ornor);
+ }
+ else {
+ orco[0]= w[0]*o1[0] + w[1]*o2[0] + w[2]*o3[0];
+ orco[1]= w[0]*o1[1] + w[1]*o2[1] + w[2]*o3[1];
+ orco[2]= w[0]*o1[2] + w[1]*o2[2] + w[2]*o3[2];
+
+ if(ornor)
+ CalcNormFloat(o1, o2, o3, ornor);
+ }
+ }
+ else {
+ VECCOPY(orco, vec);
+ if(ornor)
+ VECCOPY(ornor, nor);
+ }
+ }
+}
+void psys_interpolate_uvs(MTFace *tface, int quad, float *w, float *uvco)
+{
+ float v10= tface->uv[0][0];
+ float v11= tface->uv[0][1];
+ float v20= tface->uv[1][0];
+ float v21= tface->uv[1][1];
+ float v30= tface->uv[2][0];
+ float v31= tface->uv[2][1];
+ float v40,v41;
+
+ if(quad) {
+ v40= tface->uv[3][0];
+ v41= tface->uv[3][1];
+
+ uvco[0]= w[0]*v10 + w[1]*v20 + w[2]*v30 + w[3]*v40;
+ uvco[1]= w[0]*v11 + w[1]*v21 + w[2]*v31 + w[3]*v41;
+ }
+ else {
+ uvco[0]= w[0]*v10 + w[1]*v20 + w[2]*v30;
+ uvco[1]= w[0]*v11 + w[1]*v21 + w[2]*v31;
+ }
+}
+
+void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc)
+{
+ char *cp, *cp1, *cp2, *cp3, *cp4;
+
+ cp= (char *)mc;
+ cp1= (char *)&mcol[0];
+ cp2= (char *)&mcol[1];
+ cp3= (char *)&mcol[2];
+
+ if(quad) {
+ cp4= (char *)&mcol[3];
+
+ cp[0]= (int)(w[0]*cp1[0] + w[1]*cp2[0] + w[2]*cp3[0] + w[3]*cp4[0]);
+ cp[1]= (int)(w[0]*cp1[1] + w[1]*cp2[1] + w[2]*cp3[1] + w[3]*cp4[1]);
+ cp[2]= (int)(w[0]*cp1[2] + w[1]*cp2[2] + w[2]*cp3[2] + w[3]*cp4[2]);
+ cp[3]= (int)(w[0]*cp1[3] + w[1]*cp2[3] + w[2]*cp3[3] + w[3]*cp4[3]);
+ }
+ else {
+ cp[0]= (int)(w[0]*cp1[0] + w[1]*cp2[0] + w[2]*cp3[0]);
+ cp[1]= (int)(w[0]*cp1[1] + w[1]*cp2[1] + w[2]*cp3[1]);
+ cp[2]= (int)(w[0]*cp1[2] + w[1]*cp2[2] + w[2]*cp3[2]);
+ cp[3]= (int)(w[0]*cp1[3] + w[1]*cp2[3] + w[2]*cp3[3]);
+ }
+}
+
+float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values)
+{
+ if(values==0)
+ return 0.0;
+
+ switch(from){
+ case PART_FROM_VERT:
+ return values[index];
+ case PART_FROM_FACE:
+ case PART_FROM_VOLUME:
+ {
+ MFace *mf=dm->getFaceData(dm,index,CD_MFACE);
+ return interpolate_particle_value(values[mf->v1],values[mf->v2],values[mf->v3],values[mf->v4],fw,mf->v4);
+ }
+
+ }
+ return 0.0;
+}
+
+/* conversion of pa->fw to origspace layer coordinates */
+static void psys_w_to_origspace(float *w, float *uv)
+{
+ uv[0]= w[1] + w[2];
+ uv[1]= w[2] + w[3];
+}
+
+/* conversion of pa->fw to weights in face from origspace */
+static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, float *w, float *neww)
+{
+ float v[4][3], co[3];
+
+ v[0][0]= osface->uv[0][0]; v[0][1]= osface->uv[0][1]; v[0][2]= 0.0f;
+ v[1][0]= osface->uv[1][0]; v[1][1]= osface->uv[1][1]; v[1][2]= 0.0f;
+ v[2][0]= osface->uv[2][0]; v[2][1]= osface->uv[2][1]; v[2][2]= 0.0f;
+
+ psys_w_to_origspace(w, co);
+ co[2]= 0.0f;
+
+ if(quad) {
+ v[3][0]= osface->uv[3][0]; v[3][1]= osface->uv[3][1]; v[3][2]= 0.0f;
+ MeanValueWeights(v, 4, co, neww);
+ }
+ else {
+ MeanValueWeights(v, 3, co, neww);
+ neww[3]= 0.0f;
+ }
+}
+
+/* find the derived mesh face for a particle, set the mf passed.
+This is slow, can be optimized but only for many lookups, return the face lookup index*/
+int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *fw, struct LinkNode *node)
+{
+ Mesh *me= (Mesh*)ob->data;
+ MFace *mface;
+ OrigSpaceFace *osface;
+ int *origindex;
+ int quad, findex, totface;
+ float uv[2], (*faceuv)[2];
+
+ mface = dm->getFaceDataArray(dm, CD_MFACE);
+ origindex = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ osface = dm->getFaceDataArray(dm, CD_ORIGSPACE);
+
+ totface = dm->getNumFaces(dm);
+
+ if(osface==NULL || origindex==NULL) {
+ /* Assume we dont need osface data */
+ if (index <totface) {
+ //printf("\tNO CD_ORIGSPACE, assuming not needed\n");
+ return index;
+ } else {
+ printf("\tNO CD_ORIGSPACE, error out of range\n");
+ return DMCACHE_NOTFOUND;
+ }
+ }
+ else if(index >= me->totface)
+ return DMCACHE_NOTFOUND; /* index not in the original mesh */
+
+ psys_w_to_origspace(fw, uv);
+
+ if(node) { /* we have a linked list of faces that we use, faster! */
+ for(;node; node=node->next) {
+ findex= GET_INT_FROM_POINTER(node->link);
+ faceuv= osface[findex].uv;
+ quad= mface[findex].v4;
+
+ /* check that this intersects - Its possible this misses :/ -
+ * could also check its not between */
+ if(quad) {
+ if(IsectPQ2Df(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
+ return findex;
+ }
+ else if(IsectPT2Df(uv, faceuv[0], faceuv[1], faceuv[2]))
+ return findex;
+ }
+ }
+ else { /* if we have no node, try every face */
+ for(findex=0; findex<totface; findex++) {
+ if(origindex[findex] == index) {
+ faceuv= osface[findex].uv;
+ quad= mface[findex].v4;
+
+ /* check that this intersects - Its possible this misses :/ -
+ * could also check its not between */
+ if(quad) {
+ if(IsectPQ2Df(uv, faceuv[0], faceuv[1], faceuv[2], faceuv[3]))
+ return findex;
+ }
+ else if(IsectPT2Df(uv, faceuv[0], faceuv[1], faceuv[2]))
+ return findex;
+ }
+ }
+ }
+
+ return DMCACHE_NOTFOUND;
+}
+
+/* interprets particle data to get a point on a mesh in object space */
+#define PARTICLE_ON_DM_ERROR \
+ { if(vec) { vec[0]=vec[1]=vec[2]=0.0; } \
+ if(nor) { nor[0]=nor[1]=0.0; nor[2]=1.0; } \
+ if(orco) { orco[0]=orco[1]=orco[2]=0.0; } \
+ if(ornor) { ornor[0]=ornor[1]=0.0; ornor[2]=1.0; } \
+ if(utan) { utan[0]=utan[1]=utan[2]=0.0; } \
+ if(vtan) { vtan[0]=vtan[1]=vtan[2]=0.0; } }
+
+void psys_particle_on_dm(Object *ob, 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)
+{
+ float temp1[3];
+ float (*orcodata)[3];
+
+ if(index < 0) { /* 'no dm' error has happened! */
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+ orcodata= dm->getVertDataArray(dm, CD_ORCO);
+
+ if (dm->deformedOnly || index_dmcache == DMCACHE_ISCHILD) {
+ /* this works for meshes with deform verts only - constructive modifiers wont work properly*/
+ if(from == PART_FROM_VERT) {
+ if(index >= dm->getNumVerts(dm)) {
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+
+ dm->getVertCo(dm,index,vec);
+ if(nor){
+ dm->getVertNo(dm,index,nor);
+ Normalize(nor);
+ }
+ if(orco)
+ VECCOPY(orco, orcodata[index])
+ if(ornor) {
+ dm->getVertNo(dm,index,nor);
+ Normalize(nor);
+ }
+ }
+ else { /* PART_FROM_FACE / PART_FROM_VOLUME */
+ MFace *mface;
+ MTFace *mtface=0;
+ MVert *mvert;
+ int uv_index;
+
+ if(index >= dm->getNumFaces(dm)) {
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+
+ mface=dm->getFaceData(dm,index,CD_MFACE);
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+ uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
+
+ if(uv_index>=0){
+ CustomDataLayer *layer=&dm->faceData.layers[uv_index];
+ mtface= &((MTFace*)layer->data)[index];
+ }
+
+ if(from==PART_FROM_VOLUME){
+ psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,temp1,utan,vtan,orco,ornor);
+ if(nor)
+ VECCOPY(nor,temp1);
+ Normalize(temp1);
+ VecMulf(temp1,-foffset);
+ VECADD(vec,vec,temp1);
+ }
+ else
+ psys_interpolate_face(mvert,mface,mtface,orcodata,fw,vec,nor,utan,vtan,orco,ornor);
+ }
+ } else {
+ /* Need to support constructive modifiers, this is a bit more tricky
+ we need a customdata layer like UV's so we can position the particle */
+
+ /* Only face supported at the moment */
+ if(ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ /* find a face on the derived mesh that uses this face */
+ Mesh *me= (Mesh*)ob->data;
+ MVert *mvert;
+ MFace *mface;
+ MTFace *mtface;
+ OrigSpaceFace *osface;
+ int *origindex;
+ float fw_mod[4];
+ int i, totface;
+
+ mvert= dm->getVertDataArray(dm,CD_MVERT);
+
+ osface= dm->getFaceDataArray(dm, CD_ORIGSPACE);
+ origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+
+ /* For this to work we need origindex and OrigSpace coords */
+ if(origindex==NULL || osface==NULL || index>=me->totface) {
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+
+ if (index_dmcache == DMCACHE_NOTFOUND)
+ i = psys_particle_dm_face_lookup(ob, dm, index, fw, (LinkNode*)NULL);
+ else
+ i = index_dmcache;
+
+ totface = dm->getNumFaces(dm);
+
+ /* Any time this happens, and the face has not been removed,
+ * its a BUG watch out for this error! */
+ if (i==-1) {
+ printf("Cannot find original face %i\n", index);
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+ else if(i >= totface)
+ return;
+
+ mface= dm->getFaceData(dm, i, CD_MFACE);
+ mtface= dm->getFaceData(dm, i, CD_MTFACE);
+ osface += i;
+
+ /* we need to modify the original weights to become weights for
+ * the derived mesh face */
+ psys_origspace_to_w(osface, mface->v4, fw, fw_mod);
+
+ if(from==PART_FROM_VOLUME){
+ psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,temp1,utan,vtan,orco,ornor);
+ if(nor)
+ VECCOPY(nor,temp1);
+ Normalize(temp1);
+ VecMulf(temp1,-foffset);
+ VECADD(vec,vec,temp1);
+ }
+ else
+ psys_interpolate_face(mvert,mface,mtface,orcodata,fw_mod,vec,nor,utan,vtan,orco,ornor);
+ }
+ else if(from == PART_FROM_VERT) {
+ if (index_dmcache == DMCACHE_NOTFOUND || index_dmcache > dm->getNumVerts(dm)) {
+ PARTICLE_ON_DM_ERROR;
+ return;
+ }
+
+ dm->getVertCo(dm,index_dmcache,vec);
+ if(nor) {
+ dm->getVertNo(dm,index_dmcache,nor);
+ Normalize(nor);
+ }
+ if(orco)
+ VECCOPY(orco, orcodata[index])
+ if(ornor) {
+ dm->getVertNo(dm,index_dmcache,nor);
+ Normalize(nor);
+ }
+ if(utan && vtan) {
+ utan[0]= utan[1]= utan[2]= 0.0f;
+ vtan[0]= vtan[1]= vtan[2]= 0.0f;
+ }
+ }
+ else {
+ PARTICLE_ON_DM_ERROR;
+ }
+ }
+}
+#undef PARTICLE_ON_DM_ERROR
+
+ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys)
+{
+ ModifierData *md;
+ ParticleSystemModifierData *psmd;
+
+ for(md=ob->modifiers.first; md; md=md->next){
+ if(md->type==eModifierType_ParticleSystem){
+ psmd= (ParticleSystemModifierData*) md;
+ if(psmd->psys==psys){
+ return psmd;
+ }
+ }
+ }
+ return 0;
+}
+/************************************************/
+/* Particles on a shape */
+/************************************************/
+/* ready for future use */
+void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor)
+{
+ /* TODO */
+ float zerovec[3]={0.0f,0.0f,0.0f};
+ if(vec){
+ VECCOPY(vec,zerovec);
+ }
+ if(nor){
+ VECCOPY(nor,zerovec);
+ }
+ if(utan){
+ VECCOPY(utan,zerovec);
+ }
+ if(vtan){
+ VECCOPY(vtan,zerovec);
+ }
+ if(orco){
+ VECCOPY(orco,zerovec);
+ }
+ if(ornor){
+ VECCOPY(ornor,zerovec);
+ }
+}
+/************************************************/
+/* Particles on emitter */
+/************************************************/
+void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
+ if(psmd){
+ if(psmd->psys->part->distr==PART_DISTR_GRID){
+ if(vec){
+ VECCOPY(vec,fuv);
+ }
+ return;
+ }
+ /* we cant use the num_dmcache */
+ psys_particle_on_dm(ob, psmd->dm,from,index,index_dmcache,fuv,foffset,vec,nor,utan,vtan,orco,ornor);
+ }
+ else
+ psys_particle_on_shape(from,index,fuv,vec,nor,utan,vtan,orco,ornor);
+
+}
+/************************************************/
+/* Path Cache */
+/************************************************/
+static void hair_to_particle(ParticleKey *key, HairKey *hkey)
+{
+ VECCOPY(key->co, hkey->co);
+ key->time = hkey->time;
+}
+static void bp_to_particle(ParticleKey *key, BodyPoint *bp, HairKey *hkey)
+{
+ VECCOPY(key->co, bp->pos);
+ key->time = hkey->time;
+}
+static float vert_weight(MDeformVert *dvert, int group)
+{
+ MDeformWeight *dw;
+ int i;
+
+ if(dvert) {
+ dw= dvert->dw;
+ for(i= dvert->totweight; i>0; i--, dw++) {
+ if(dw->def_nr == group) return dw->weight;
+ if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/
+ }
+ }
+ return 0.0;
+}
+static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, short type, short axis, float obmat[][4])
+{
+ float vec[3]={0.0,0.0,0.0}, q1[4]={1,0,0,0},q2[4];
+ float t;
+
+ CLAMP(time,0.0,1.0);
+
+ if(shape!=0.0f && type!=PART_KINK_BRAID) {
+ if(shape<0.0f)
+ time= (float)pow(time, 1.0+shape);
+ else
+ time= (float)pow(time, 1.0/(1.0-shape));
+ }
+
+ t=time;
+
+ t*=(float)M_PI*freq;
+
+ if(par==0) return;
+
+ switch(type){
+ case PART_KINK_CURL:
+ vec[axis]=1.0;
+ if(par_rot)
+ QUATCOPY(q2,par_rot)
+ else
+ vectoquat(par->vel,axis,(axis+1)%3, q2);
+ QuatMulVecf(q2,vec);
+ VecMulf(vec,amplitude);
+ VECADD(state->co,state->co,vec);
+
+ VECSUB(vec,state->co,par->co);
+
+ if(t!=0.0)
+ VecRotToQuat(par->vel,t,q1);
+
+ QuatMulVecf(q1,vec);
+
+ VECADD(state->co,par->co,vec);
+ break;
+ case PART_KINK_RADIAL:
+ VECSUB(vec,state->co,par->co);
+
+ Normalize(vec);
+ VecMulf(vec,amplitude*(float)sin(t));
+
+ VECADD(state->co,state->co,vec);
+ break;
+ case PART_KINK_WAVE:
+ vec[axis]=1.0;
+ if(obmat)
+ Mat4MulVecfl(obmat,vec);
+
+ if(par_rot)
+ QuatMulVecf(par_rot,vec);
+
+ Projf(q1,vec,par->vel);
+
+ VECSUB(vec,vec,q1);
+ Normalize(vec);
+
+ VecMulf(vec,amplitude*(float)sin(t));
+
+ VECADD(state->co,state->co,vec);
+ break;
+ case PART_KINK_BRAID:
+ if(par){
+ float y_vec[3]={0.0,1.0,0.0};
+ float z_vec[3]={0.0,0.0,1.0};
+ float vec_from_par[3], vec_one[3], radius, state_co[3];
+ float inp_y,inp_z,length;
+
+ if(par_rot)
+ QUATCOPY(q2,par_rot)
+ else
+ vectoquat(par->vel,axis,(axis+1)%3,q2);
+ QuatMulVecf(q2,y_vec);
+ QuatMulVecf(q2,z_vec);
+
+ VECSUB(vec_from_par,state->co,par->co);
+ VECCOPY(vec_one,vec_from_par);
+ radius=Normalize(vec_one);
+
+ inp_y=Inpf(y_vec,vec_one);
+ inp_z=Inpf(z_vec,vec_one);
+
+ if(inp_y>0.5){
+ VECCOPY(state_co,y_vec);
+
+ VecMulf(y_vec,amplitude*(float)cos(t));
+ VecMulf(z_vec,amplitude/2.0f*(float)sin(2.0f*t));
+ }
+ else if(inp_z>0.0){
+ VECCOPY(state_co,z_vec);
+ VecMulf(state_co,(float)sin(M_PI/3.0f));
+ VECADDFAC(state_co,state_co,y_vec,-0.5f);
+
+ VecMulf(y_vec,-amplitude*(float)cos(t + M_PI/3.0f));
+ VecMulf(z_vec,amplitude/2.0f*(float)cos(2.0f*t + M_PI/6.0f));
+ }
+ else{
+ VECCOPY(state_co,z_vec);
+ VecMulf(state_co,-(float)sin(M_PI/3.0f));
+ VECADDFAC(state_co,state_co,y_vec,-0.5f);
+
+ VecMulf(y_vec,amplitude*(float)-sin(t+M_PI/6.0f));
+ VecMulf(z_vec,amplitude/2.0f*(float)-sin(2.0f*t+M_PI/3.0f));
+ }
+
+ VecMulf(state_co,amplitude);
+ VECADD(state_co,state_co,par->co);
+ VECSUB(vec_from_par,state->co,state_co);
+
+ length=Normalize(vec_from_par);
+ VecMulf(vec_from_par,MIN2(length,amplitude/2.0f));
+
+ VECADD(state_co,par->co,y_vec);
+ VECADD(state_co,state_co,z_vec);
+ VECADD(state_co,state_co,vec_from_par);
+
+ shape=(2.0f*(float)M_PI)*(1.0f+shape);
+
+ if(t<shape){
+ shape=t/shape;
+ shape=(float)sqrt((double)shape);
+ VecLerpf(state->co,state->co,state_co,shape);
+ }
+ else{
+ VECCOPY(state->co,state_co);
+ }
+ }
+ break;
+ }
+}
+static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump)
+{
+ if(par && clumpfac!=0.0){
+ float clump, cpow;
+
+ if(clumppow<0.0)
+ cpow=1.0f+clumppow;
+ else
+ cpow=1.0f+9.0f*clumppow;
+
+ if(clumpfac<0.0) /* clump roots instead of tips */
+ clump = -clumpfac*pa_clump*(float)pow(1.0-(double)time,(double)cpow);
+ else
+ clump = clumpfac*pa_clump*(float)pow((double)time,(double)cpow);
+ VecLerpf(state->co,state->co,par->co,clump);
+ }
+}
+int do_guide(ParticleKey *state, int pa_num, float time, ListBase *lb)
+{
+ PartDeflect *pd;
+ ParticleEffectorCache *ec;
+ Object *eob;
+ Curve *cu;
+ ParticleKey key, par;
+
+ float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0;
+ float guidevec[4], guidedir[3], rot2[4], 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;
+
+ 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;
+
+ distance=ec->distances[pa_num];
+ mindist=pd->f_strength;
+
+ VECCOPY(pa_loc, ec->locations+3*pa_num);
+ VECCOPY(pa_zero,pa_loc);
+ VECADD(pa_zero,pa_zero,ec->firstloc);
+
+ guidetime=time/(1.0-pd->free_end);
+
+ /* WARNING: bails out with continue here */
+ if(((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) || 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);
+ }
+
+ if(pd->flag & PFIELD_GUIDE_PATH_ADD)
+ where_on_path(eob, f_force*guidetime, guidevec, guidedir);
+ else
+ where_on_path(eob, guidetime, guidevec, guidedir);
+
+ Mat4MulVecfl(ec->ob->obmat,guidevec);
+ Mat4Mul3Vecfl(ec->ob->obmat,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);
+
+ /* curve tilt */
+ VecRotToQuat(guidedir,guidevec[3]-ec->firstloc[3],rot2);
+ QuatMulVecf(rot2,pa_loc);
+
+ //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(cu->taperobj,(int)(f_force*guidetime*100.0),100));
+ /* TODO */
+ //else{
+ ///* curve size*/
+ // calc_curve_subdiv_radius(cu,cu->nurb.first,((Nurb*)cu->nurb.first)->
+ //}
+ 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;
+ }
+ }
+ }
+
+ 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);
+
+ Normalize(veffect);
+ VecMulf(veffect,VecLength(state->vel));
+ VECCOPY(state->vel,veffect);
+ return 1;
+ }
+ }
+ return 0;
+}
+static void do_rough(float *loc, float t, float fac, float size, float thres, ParticleKey *state)
+{
+ float rough[3];
+ float rco[3];
+
+ if(thres!=0.0)
+ if((float)fabs((float)(-1.5+loc[0]+loc[1]+loc[2]))<1.5f*thres) return;
+
+ VECCOPY(rco,loc);
+ VecMulf(rco,t);
+ rough[0]=-1.0f+2.0f*BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2,0,2);
+ rough[1]=-1.0f+2.0f*BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2,0,2);
+ rough[2]=-1.0f+2.0f*BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2,0,2);
+ VECADDFAC(state->co,state->co,rough,fac);
+}
+static void do_rough_end(float *loc, float t, float fac, float shape, ParticleKey *state, ParticleKey *par)
+{
+ float rough[3], rnor[3];
+ float roughfac;
+
+ roughfac=fac*(float)pow((double)t,shape);
+ VECCOPY(rough,loc);
+ rough[0]=-1.0f+2.0f*rough[0];
+ rough[1]=-1.0f+2.0f*rough[1];
+ rough[2]=-1.0f+2.0f*rough[2];
+ VecMulf(rough,roughfac);
+
+
+ if(par){
+ VECCOPY(rnor,par->vel);
+ }
+ else{
+ VECCOPY(rnor,state->vel);
+ }
+ Normalize(rnor);
+ Projf(rnor,rough,rnor);
+ VECSUB(rough,rough,rnor);
+
+ VECADD(state->co,state->co,rough);
+}
+static void do_path_effectors(Object *ob, ParticleSystem *psys, 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};
+ ParticleKey eff_key;
+ ParticleData *pa;
+
+ 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, ob, psys, rootco, force, vel, dfra, cfra);
+
+ VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
+
+ VecAddf(force, force, vec);
+
+ Normalize(force);
+
+ if(k < steps) {
+ VecSubf(vec, (ca+1)->co, ca->co);
+ *length = VecLength(vec);
+ }
+
+ VECADDFAC(ca->co, (ca-1)->co, force, *length);
+}
+static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *state, float max_length, float *cur_length, float length, float *dvec)
+{
+ if(*cur_length + length > max_length){
+ //if(p<totparent){
+ // if(k<=(int)cache[totpart+p]->time){
+ // /* parents need to be calculated fully first so that they don't mess up their children */
+ // /* we'll make a note of where we got to though so that they're easy to finish later */
+ // state->time=(max_length-*cur_length)/length;
+ // cache[totpart+p]->time=(float)k;
+ // }
+ //}
+ //else{
+ VecMulf(dvec, (max_length - *cur_length) / length);
+ VECADD(state->co, (state - 1)->co, dvec);
+ keys->steps = k;
+ /* something over the maximum step value */
+ return k=100000;
+ //}
+ }
+ else {
+ *cur_length+=length;
+ return k;
+ }
+}
+static void finalize_path_length(ParticleCacheKey *keys)
+{
+ ParticleCacheKey *state = keys;
+ float dvec[3];
+ state += state->steps;
+
+ VECSUB(dvec, state->co, (state - 1)->co);
+ VecMulf(dvec, state->steps);
+ VECADD(state->co, (state - 1)->co, dvec);
+}
+static void offset_child(ChildParticle *cpa, ParticleKey *par, ParticleKey *child, float flat, float radius)
+{
+ VECCOPY(child->co,cpa->fuv);
+ VecMulf(child->co,radius);
+
+ child->co[0]*=flat;
+
+ VECCOPY(child->vel,par->vel);
+
+ QuatMulVecf(par->rot,child->co);
+
+ QUATCOPY(child->rot,par->rot);
+
+ VECADD(child->co,child->co,par->co);
+}
+float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
+{
+ float *vg=0;
+
+ if(psys->vgroup[vgroup]){
+ MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+ if(dvert){
+ int totvert=dm->getNumVerts(dm), i;
+ vg=MEM_callocN(sizeof(float)*totvert, "vg_cache");
+ if(psys->vg_neg&(1<<vgroup)){
+ for(i=0; i<totvert; i++)
+ vg[i]=1.0f-vert_weight(dvert+i,psys->vgroup[vgroup]-1);
+ }
+ else{
+ for(i=0; i<totvert; i++)
+ vg[i]=vert_weight(dvert+i,psys->vgroup[vgroup]-1);
+ }
+ }
+ }
+ return vg;
+}
+void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys)
+{
+ ParticleSettings *part=psys->part;
+ KDTree *tree;
+ ChildParticle *cpa;
+ int p, totparent,totchild=psys->totchild;
+ float co[3], orco[3];
+ int from=PART_FROM_FACE;
+ totparent=(int)(totchild*part->parents*0.3);
+
+ tree=BLI_kdtree_new(totparent);
+
+ for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
+ psys_particle_on_emitter(ob,psmd,from,cpa->num,-1,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(ob,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);
+ }
+
+ BLI_kdtree_free(tree);
+}
+
+static void get_strand_normal(Material *ma, float *surfnor, float surfdist, float *nor)
+{
+ float cross[3], nstrand[3], vnor[3], blend;
+
+ if(!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f)))
+ return;
+
+ if(ma->mode & MA_STR_SURFDIFF) {
+ Crossf(cross, surfnor, nor);
+ Crossf(nstrand, nor, cross);
+
+ blend= INPR(nstrand, surfnor);
+ CLAMP(blend, 0.0f, 1.0f);
+
+ VecLerpf(vnor, nstrand, surfnor, blend);
+ Normalize(vnor);
+ }
+ else
+ VECCOPY(vnor, nor)
+
+ if(ma->strand_surfnor > 0.0f) {
+ if(ma->strand_surfnor > surfdist) {
+ blend= (ma->strand_surfnor - surfdist)/ma->strand_surfnor;
+ VecLerpf(vnor, vnor, surfnor, blend);
+ Normalize(vnor);
+ }
+ }
+
+ VECCOPY(nor, vnor);
+}
+
+int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
+{
+ ParticleThreadContext *ctx= threads[0].ctx;
+ Object *ob= ctx->ob;
+ ParticleSystem *psys= ctx->psys;
+ ParticleSettings *part = psys->part;
+ ParticleEditSettings *pset = &G.scene->toolsettings->particle;
+ int totparent=0, between=0;
+ int steps = (int)pow(2.0,(double)part->draw_step);
+ int totchild = psys->totchild;
+ int i, seed, totthread= threads[0].tot;
+
+ /*---start figuring out what is actually wanted---*/
+ if(psys_in_edit_mode(psys))
+ if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0)
+ totchild=0;
+
+ if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ totparent=(int)(totchild*part->parents*0.3);
+ /* part->parents could still be 0 so we can't test with totparent */
+ between=1;
+ }
+
+ if(psys->renderdata)
+ steps=(int)pow(2.0,(double)part->ren_step);
+ else{
+ totchild=(int)((float)totchild*(float)part->disp/100.0f);
+ totparent=MIN2(totparent,totchild);
+ }
+
+ if(totchild==0) return 0;
+
+ /* init random number generator */
+ if(ctx->psys->part->flag & PART_ANIM_BRANCHING)
+ seed= 31415926 + ctx->psys->seed + (int)cfra;
+ else
+ seed= 31415926 + ctx->psys->seed;
+
+ if(part->flag & PART_BRANCHING || ctx->editupdate || totchild < 10000)
+ totthread= 1;
+
+ for(i=0; i<totthread; i++) {
+ threads[i].rng_path= rng_new(seed);
+ threads[i].tot= totthread;
+ }
+
+ /* fill context values */
+ ctx->between= between;
+ ctx->steps= steps;
+ ctx->totchild= totchild;
+ ctx->totparent= totparent;
+ ctx->cfra= cfra;
+
+ psys->lattice = psys_get_lattice(ob, psys);
+
+ /* cache all relevant vertex groups if they exist */
+ if(part->from!=PART_FROM_PARTICLE){
+ ctx->vg_length = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_LENGTH);
+ ctx->vg_clump = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_CLUMP);
+ ctx->vg_kink = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_KINK);
+ ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1);
+ ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2);
+ ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE);
+ if(psys->part->flag & PART_CHILD_EFFECT)
+ ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR);
+ }
+
+ /* set correct ipo timing */
+ if(part->flag&PART_ABS_TIME && part->ipo){
+ calc_ipo(part->ipo, cfra);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ return 1;
+}
+
+/* note: this function must be thread safe, except for branching! */
+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;
+ ParticleSettings *part = psys->part;
+ ParticleCacheKey **cache= psys->childcache;
+ ParticleCacheKey **pcache= psys->pathcache;
+ ParticleCacheKey *state, *par = NULL, *key[4];
+ ParticleData *pa;
+ ParticleTexture ptex;
+ float *cpa_fuv=0;
+ float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
+ float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
+ float pa_rough1, pa_rough2, pa_roughe;
+ float length, pa_length, pa_clump, pa_kink, pa_effector;
+ float max_length = 1.0f, cur_length = 0.0f;
+ float eff_length, eff_vec[3];
+ int k, cpa_num, guided=0;
+ short cpa_from;
+
+ if(part->flag & PART_BRANCHING) {
+ branch_begin=rng_getFloat(thread->rng_path);
+ branch_end=branch_begin+(1.0f-branch_begin)*rng_getFloat(thread->rng_path);
+ branch_prob=rng_getFloat(thread->rng_path);
+ rough_rand=rng_getFloat(thread->rng_path);
+ }
+ else {
+ branch_begin= 0.0f;
+ branch_end= 0.0f;
+ branch_prob= 0.0f;
+ rough_rand= 0.0f;
+ }
+
+ if(i<psys->totpart){
+ branch_begin=0.0f;
+ branch_end=1.0f;
+ branch_prob=0.0f;
+ }
+
+ if(ctx->between){
+ int w, needupdate;
+ float foffset;
+
+ if(ctx->editupdate && !(part->flag & PART_BRANCHING)) {
+ needupdate= 0;
+ w= 0;
+ while(w<4 && cpa->pa[w]>=0) {
+ if(psys->particles[cpa->pa[w]].flag & PARS_EDIT_RECALC) {
+ needupdate= 1;
+ break;
+ }
+ w++;
+ }
+
+ if(!needupdate)
+ return;
+ else
+ memset(keys, 0, sizeof(*keys)*(ctx->steps+1));
+ }
+
+ /* get parent paths */
+ w= 0;
+ while(w<4 && cpa->pa[w]>=0){
+ key[w] = pcache[cpa->pa[w]];
+ w++;
+ }
+
+ /* get the original coordinates (orco) for texture usage */
+ cpa_num = cpa->num;
+
+ foffset= cpa->foffset;
+ if(part->childtype == PART_CHILD_FACES)
+ foffset = -(2.0f + part->childspread);
+ cpa_fuv = cpa->fuv;
+ cpa_from = PART_FROM_FACE;
+
+ psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
+
+ /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
+ VECCOPY(cpa_1st,co);
+ Mat4MulVecfl(ob->obmat,cpa_1st);
+
+ pa=0;
+ }
+ else{
+ if(ctx->editupdate && !(part->flag & PART_BRANCHING)) {
+ if(!(psys->particles[cpa->parent].flag & PARS_EDIT_RECALC))
+ return;
+
+ memset(keys, 0, sizeof(*keys)*(ctx->steps+1));
+ }
+
+ /* get the parent path */
+ key[0]=pcache[cpa->parent];
+
+ /* get the original coordinates (orco) for texture usage */
+ pa=psys->particles+cpa->parent;
+
+ cpa_from=part->from;
+ cpa_num=pa->num;
+ cpa_fuv=pa->fuv;
+
+ psys_particle_on_emitter(ob,ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
+ }
+
+ keys->steps = ctx->steps;
+
+ /* correct child ipo timing */
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ float dsta=part->end-part->sta;
+ calc_ipo(part->ipo, 100.0f*(ctx->cfra-(part->sta+dsta*cpa->rand[1]))/(part->lifetime*(1.0f - part->randlife*cpa->rand[0])));
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ /* get different child parameters from textures & vgroups */
+ ptex.length=part->length*(1.0f - part->randlength*cpa->rand[0]);
+ ptex.clump=1.0;
+ ptex.kink=1.0;
+ ptex.rough= 1.0;
+
+ get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,&ptex,
+ MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
+
+ pa_length=ptex.length;
+ pa_clump=ptex.clump;
+ pa_kink=ptex.kink;
+ pa_rough1=ptex.rough;
+ pa_rough2=ptex.rough;
+ pa_roughe=ptex.rough;
+ pa_effector= 1.0f;
+
+ if(ctx->vg_length)
+ pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
+ if(ctx->vg_clump)
+ pa_clump*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_clump);
+ if(ctx->vg_kink)
+ pa_kink*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_kink);
+ if(ctx->vg_rough1)
+ pa_rough1*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough1);
+ if(ctx->vg_rough2)
+ pa_rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2);
+ if(ctx->vg_roughe)
+ pa_roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe);
+ if(ctx->vg_effector)
+ pa_effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
+
+ /* create the child path */
+ for(k=0,state=keys; k<=ctx->steps; k++,state++){
+ if(ctx->between){
+ int w=0;
+
+ state->co[0] = state->co[1] = state->co[2] = 0.0f;
+ state->vel[0] = state->vel[1] = state->vel[2] = 0.0f;
+ state->rot[0] = state->rot[1] = state->rot[2] = state->rot[3] = 0.0f;
+
+ //QUATCOPY(state->rot,key[0]->rot);
+
+ /* child position is the weighted sum of parent positions */
+ while(w<4 && cpa->pa[w]>=0){
+ state->co[0] += cpa->w[w] * key[w]->co[0];
+ state->co[1] += cpa->w[w] * key[w]->co[1];
+ state->co[2] += cpa->w[w] * key[w]->co[2];
+
+ state->vel[0] += cpa->w[w] * key[w]->vel[0];
+ state->vel[1] += cpa->w[w] * key[w]->vel[1];
+ state->vel[2] += cpa->w[w] * key[w]->vel[2];
+ key[w]++;
+ w++;
+ }
+ if(k==0){
+ /* calculate the offset between actual child root position and first position interpolated from parents */
+ VECSUB(cpa_1st,cpa_1st,state->co);
+ }
+ /* apply offset for correct positioning */
+ VECADD(state->co,state->co,cpa_1st);
+ }
+ else{
+ /* offset the child from the parent position */
+ offset_child(cpa, (ParticleKey*)key[0], (ParticleKey*)state, part->childflat, part->childrad);
+
+ key[0]++;
+ }
+ }
+
+ /* apply effectors */
+ if(part->flag & PART_CHILD_EFFECT) {
+ for(k=0,state=keys; k<=ctx->steps; k++,state++) {
+ if(k) {
+ do_path_effectors(ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
+ }
+ else {
+ VecSubf(eff_vec,(state+1)->co,state->co);
+ eff_length= VecLength(eff_vec);
+ }
+ }
+ }
+
+ for(k=0,state=keys; k<=ctx->steps; k++,state++){
+ t=(float)k/(float)ctx->steps;
+
+ if(ctx->totparent){
+ if(i>=ctx->totparent)
+ /* this is not threadsafe, but should only happen for
+ * branching particles particles, which are not threaded */
+ par = cache[cpa->parent] + k;
+ else
+ par=0;
+ }
+ else if(cpa->parent>=0){
+ par=pcache[cpa->parent]+k;
+ }
+
+ /* apply different deformations to the child path */
+ if(part->flag & PART_CHILD_EFFECT)
+ /* state is safe to cast, since only co and vel are used */
+ guided = do_guide((ParticleKey*)state, cpa->parent, t, &(psys->effectors));
+
+ if(guided==0){
+ if(part->kink)
+ do_prekink((ParticleKey*)state, (ParticleKey*)par, par->rot, t,
+ part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat);
+
+ do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump);
+ }
+
+ if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING)
+ rough_t = t * rough_rand;
+ else
+ rough_t = t;
+
+ if(part->rough1 != 0.0 && pa_rough1 != 0.0)
+ do_rough(orco, rough_t, pa_rough1*part->rough1, part->rough1_size, 0.0, (ParticleKey*)state);
+
+ if(part->rough2 != 0.0 && pa_rough2 != 0.0)
+ do_rough(cpa->rand, rough_t, pa_rough2*part->rough2, part->rough2_size, part->rough2_thres, (ParticleKey*)state);
+
+ if(part->rough_end != 0.0 && pa_roughe != 0.0)
+ do_rough_end(cpa->rand, rough_t, pa_roughe*part->rough_end, part->rough_end_shape, (ParticleKey*)state, (ParticleKey*)par);
+
+ if(part->flag & PART_BRANCHING && ctx->between==0){
+ if(branch_prob > part->branch_thres){
+ branchfac=0.0f;
+ }
+ else{
+ if(part->flag & PART_SYMM_BRANCHING){
+ if(t < branch_begin || t > branch_end)
+ branchfac=0.0f;
+ else{
+ if((t-branch_begin)/(branch_end-branch_begin)<0.5)
+ branchfac=2.0f*(t-branch_begin)/(branch_end-branch_begin);
+ else
+ branchfac=2.0f*(branch_end-t)/(branch_end-branch_begin);
+
+ CLAMP(branchfac,0.0f,1.0f);
+ }
+ }
+ else{
+ if(t < branch_begin){
+ branchfac=0.0f;
+ }
+ else{
+ branchfac=(t-branch_begin)/((1.0f-branch_begin)*0.5f);
+ CLAMP(branchfac,0.0f,1.0f);
+ }
+ }
+ }
+
+ if(i<psys->totpart)
+ VecLerpf(state->co, (pcache[i] + k)->co, state->co, branchfac);
+ else
+ /* this is not threadsafe, but should only happen for
+ * branching particles particles, which are not threaded */
+ VecLerpf(state->co, (cache[i - psys->totpart] + k)->co, state->co, branchfac);
+ }
+
+ /* we have to correct velocity because of kink & clump */
+ if(k>1){
+ VECSUB((state-1)->vel,state->co,(state-2)->co);
+ VecMulf((state-1)->vel,0.5);
+
+ if(ctx->ma && (part->draw & PART_DRAW_MAT_COL))
+ get_strand_normal(ctx->ma, ornor, cur_length, (state-1)->vel);
+ }
+
+ /* check if path needs to be cut before actual end of data points */
+ if(k){
+ VECSUB(dvec,state->co,(state-1)->co);
+ if(part->flag&PART_ABS_LENGTH)
+ length=VecLength(dvec);
+ else
+ length=1.0f/(float)ctx->steps;
+
+ k=check_path_length(k,keys,state,max_length,&cur_length,length,dvec);
+ }
+ else{
+ /* initialize length calculation */
+ if(part->flag&PART_ABS_LENGTH)
+ max_length= part->abslength*pa_length;
+ else
+ max_length= pa_length;
+
+ cur_length= 0.0f;
+ }
+
+ if(ctx->ma && (part->draw & PART_DRAW_MAT_COL)) {
+ VECCOPY(state->col, &ctx->ma->r)
+ get_strand_normal(ctx->ma, ornor, cur_length, state->vel);
+ }
+ }
+
+ /* now let's finalise the interpolated parents that we might have left half done before */
+ if(i<ctx->totparent)
+ finalize_path_length(keys);
+}
+
+void *exec_child_path_cache(void *data)
+{
+ ParticleThread *thread= (ParticleThread*)data;
+ ParticleThreadContext *ctx= thread->ctx;
+ ParticleSystem *psys= ctx->psys;
+ ParticleCacheKey **cache= psys->childcache;
+ ChildParticle *cpa;
+ int i, totchild= ctx->totchild;
+
+ cpa= psys->child + thread->num;
+ for(i=thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
+ psys_thread_create_path(thread, cpa, cache[i], i);
+
+ return 0;
+}
+
+void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+{
+ ParticleSettings *part = psys->part;
+ ParticleThread *pthreads;
+ ParticleThreadContext *ctx;
+ ParticleCacheKey **cache, *tcache;
+ ListBase threads;
+ int i, totchild, totparent, totthread;
+ unsigned long totchildstep;
+
+ pthreads= psys_threads_create(ob, psys, G.scene->r.threads);
+
+ if(!psys_threads_init_path(pthreads, cfra, editupdate)) {
+ psys_threads_free(pthreads);
+ return;
+ }
+
+ ctx= pthreads[0].ctx;
+ totchild= ctx->totchild;
+ totparent= ctx->totparent;
+
+ if(editupdate && psys->childcache && !(part->flag & PART_BRANCHING) && totchild == psys->totchildcache) {
+ cache = psys->childcache;
+ }
+ else {
+ /* clear out old and create new empty path cache */
+ free_child_path_cache(psys);
+
+ cache = psys->childcache = MEM_callocN(totchild*sizeof(void *), "Child path cache array");
+ totchildstep= totchild*(ctx->steps + 1);
+ tcache = MEM_callocN(totchildstep*sizeof(ParticleCacheKey), "Child path cache");
+ for(i=0; i<totchild; i++)
+ cache[i] = tcache + i * (ctx->steps + 1);
+
+ psys->totchildcache = totchild;
+ }
+
+ totthread= pthreads[0].tot;
+
+ if(totthread > 1) {
+ BLI_init_threads(&threads, exec_child_path_cache, totthread);
+
+ for(i=0; i<totthread; i++)
+ BLI_insert_thread(&threads, &pthreads[i]);
+
+ BLI_end_threads(&threads);
+ }
+ else
+ exec_child_path_cache(&pthreads[0]);
+
+ psys_threads_free(pthreads);
+}
+
+/* Calculates paths ready for drawing/rendering. */
+/* -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(Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+{
+ ParticleCacheKey *ca, **cache=psys->pathcache;
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ ParticleEditSettings *pset = &G.scene->toolsettings->particle;
+
+ ParticleData *pa;
+ ParticleKey keys[4], result, *kkey[2] = {NULL, NULL};
+ HairKey *hkey[2] = {NULL, NULL};
+
+ ParticleEdit *edit = 0;
+ ParticleEditKey *ekey = 0;
+
+ SoftBody *soft = 0;
+ BodyPoint *bp[2] = {NULL, NULL};
+
+ Material *ma;
+
+ float birthtime = 0.0, dietime = 0.0;
+ float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = G.scene->r.frs_sec;
+ float col[3] = {0.5f, 0.5f, 0.5f};
+ float prev_tangent[3], hairmat[4][4];
+ int k,i;
+ int steps = (int)pow(2.0, (double)psys->part->draw_step);
+ int totpart = psys->totpart;
+ char nosel[4], sel[4];
+ float sel_col[3];
+ float nosel_col[3];
+ float length, vec[3];
+ float *vg_effector= NULL, effector=0.0f;
+
+ /* we don't have anything valid to create paths from so let's quit here */
+ if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
+ return;
+
+ if(psys->renderdata)
+ steps = (int)pow(2.0, (double)psys->part->ren_step);
+ else if(psys_in_edit_mode(psys)){
+ edit=psys->edit;
+
+ //timed = edit->draw_timed;
+
+ PE_get_colors(sel,nosel);
+ if(pset->brushtype == PE_BRUSH_WEIGHT){
+ sel_col[0] = sel_col[1] = sel_col[2] = 1.0f;
+ nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f;
+ }
+ else{
+ sel_col[0] = (float)sel[0] / 255.0f;
+ sel_col[1] = (float)sel[1] / 255.0f;
+ sel_col[2] = (float)sel[2] / 255.0f;
+ nosel_col[0] = (float)nosel[0] / 255.0f;
+ nosel_col[1] = (float)nosel[1] / 255.0f;
+ nosel_col[2] = (float)nosel[2] / 255.0f;
+ }
+ }
+
+ if(editupdate && psys->pathcache && totpart == psys->totcached) {
+ cache = psys->pathcache;
+ }
+ else {
+ /* clear out old and create new empty path cache */
+ psys_free_path_cache(psys);
+
+ /* allocate cache array for fast access and set pointers to contiguous mem block */
+ cache = psys->pathcache = MEM_callocN(MAX2(1, totpart) * sizeof(void *), "Path cache array");
+ cache[0] = MEM_callocN(totpart * (steps + 1) * sizeof(ParticleCacheKey), "Path cache");
+ for(i=1; i<totpart; i++)
+ cache[i] = cache[0] + i * (steps + 1);
+ }
+
+ if(edit==NULL && psys->soft && psys->softflag & OB_SB_ENABLE)
+ soft = psys->soft;
+
+ psys->lattice = psys_get_lattice(ob, psys);
+ ma= give_current_material(ob, psys->part->omat);
+ if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
+ VECCOPY(col, &ma->r)
+
+ if(psys->part->from!=PART_FROM_PARTICLE) {
+ if(!(psys->part->flag & PART_CHILD_EFFECT))
+ vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
+ }
+
+ /*---first main loop: create all actual particles' paths---*/
+ for(i=0,pa=psys->particles; i<totpart; i++, pa++){
+ if(psys && edit==NULL && (pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)) {
+ if(soft)
+ bp[0] += pa->totkey; /* TODO use of initialized value? */
+ continue;
+ }
+
+ if(editupdate && !(pa->flag & PARS_EDIT_RECALC)) continue;
+ else memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
+
+ cache[i]->steps = steps;
+
+ if(edit)
+ ekey = edit->keys[i];
+
+ /*--get the first data points--*/
+ if(psys->flag & PSYS_KEYED) {
+ kkey[0] = pa->keys;
+ kkey[1] = kkey[0] + 1;
+
+ birthtime = kkey[0]->time;
+ dietime = kkey[0][pa->totkey-1].time;
+ }
+ else {
+ hkey[0] = pa->hair;
+ hkey[1] = hkey[0] + 1;
+
+ birthtime = hkey[0]->time;
+ dietime = hkey[0][pa->totkey-1].time;
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ }
+
+ if(soft){
+ bp[0] = soft->bpoint + pa->bpi;
+ bp[1] = bp[0] + 1;
+ }
+
+ /*--interpolate actual path from data points--*/
+ for(k=0, ca=cache[i]; k<=steps; k++, ca++){
+ time = (float)k / (float)steps;
+
+ t = birthtime + time * (dietime - birthtime);
+
+ if(psys->flag & PSYS_KEYED) {
+ while(kkey[1]->time < t) {
+ kkey[1]++;
+ }
+
+ kkey[0] = kkey[1] - 1;
+ }
+ else {
+ while(hkey[1]->time < t) {
+ hkey[1]++;
+ bp[1]++;
+ }
+
+ hkey[0] = hkey[1] - 1;
+ }
+
+ if(soft) {
+ bp[0] = bp[1] - 1;
+ bp_to_particle(keys + 1, bp[0], hkey[0]);
+ bp_to_particle(keys + 2, bp[1], hkey[1]);
+ }
+ else if(psys->flag & PSYS_KEYED) {
+ memcpy(keys + 1, kkey[0], sizeof(ParticleKey));
+ memcpy(keys + 2, kkey[1], sizeof(ParticleKey));
+ }
+ else {
+ hair_to_particle(keys + 1, hkey[0]);
+ hair_to_particle(keys + 2, hkey[1]);
+ }
+
+
+ if((psys->flag & PSYS_KEYED)==0) {
+ if(soft) {
+ if(hkey[0] != pa->hair)
+ bp_to_particle(keys, bp[0] - 1, hkey[0] - 1);
+ else
+ bp_to_particle(keys, bp[0], hkey[0]);
+ }
+ else {
+ if(hkey[0] != pa->hair)
+ hair_to_particle(keys, hkey[0] - 1);
+ else
+ hair_to_particle(keys, hkey[0]);
+ }
+
+ if(soft) {
+ if(hkey[1] != pa->hair + pa->totkey - 1)
+ bp_to_particle(keys + 3, bp[1] + 1, hkey[1] + 1);
+ else
+ bp_to_particle(keys + 3, bp[1], hkey[1]);
+ }
+ else {
+ if(hkey[1] != pa->hair + pa->totkey - 1)
+ hair_to_particle(keys + 3, hkey[1] + 1);
+ else
+ hair_to_particle(keys + 3, hkey[1]);
+ }
+ }
+
+ dfra = keys[2].time - keys[1].time;
+
+ keytime = (t - keys[1].time) / dfra;
+
+ /* convert velocity to timestep size */
+ if(psys->flag & PSYS_KEYED){
+ VecMulf(keys[1].vel, dfra / frs_sec);
+ VecMulf(keys[2].vel, dfra / frs_sec);
+ }
+
+ /* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/
+ interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
+ ,keys, keytime, &result, 0);
+
+ /* the velocity needs to be converted back from cubic interpolation */
+ if(psys->flag & PSYS_KEYED){
+ VecMulf(result.vel, frs_sec / dfra);
+ }
+ else if(soft==NULL) { /* softbody and keyed are allready in global space */
+ Mat4MulVecfl(hairmat, result.co);
+ }
+
+ VECCOPY(ca->co, result.co);
+
+ /* selection coloring in edit mode */
+ if(edit){
+ if(pset->brushtype==PE_BRUSH_WEIGHT){
+ if(k==steps)
+ VecLerpf(ca->col, nosel_col, sel_col, hkey[0]->weight);
+ else
+ VecLerpf(ca->col, nosel_col, sel_col,
+ (1.0f - keytime) * hkey[0]->weight + keytime * hkey[1]->weight);
+ }
+ else{
+ if((ekey + (hkey[0] - pa->hair))->flag & PEK_SELECT){
+ if((ekey + (hkey[1] - pa->hair))->flag & PEK_SELECT){
+ VECCOPY(ca->col, sel_col);
+ }
+ else{
+ VecLerpf(ca->col, sel_col, nosel_col, keytime);
+ }
+ }
+ else{
+ if((ekey + (hkey[1] - pa->hair))->flag & PEK_SELECT){
+ VecLerpf(ca->col, nosel_col, sel_col, keytime);
+ }
+ else{
+ VECCOPY(ca->col, nosel_col);
+ }
+ }
+ }
+ }
+ else{
+ VECCOPY(ca->col, col);
+ }
+ }
+
+ /*--modify paths--*/
+
+ VecSubf(vec,(cache[i]+1)->co,cache[i]->co);
+ length = VecLength(vec);
+
+ effector= 1.0f;
+ if(vg_effector)
+ effector*= psys_interpolate_value_from_verts(psmd->dm,psys->part->from,pa->num,pa->fuv,vg_effector);
+
+ for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
+ /* apply effectors */
+ if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
+ do_path_effectors(ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
+
+ /* apply guide curves to path data */
+ if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
+ /* ca is safe to cast, since only co and vel are used */
+ do_guide((ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
+
+ /* apply lattice */
+ if(psys->lattice && edit==0)
+ calc_latt_deform(ca->co, 1.0f);
+
+ /* figure out rotation */
+
+ if(k) {
+ float cosangle, angle, tangent[3], normal[3], q[4];
+
+ if(k == 1) {
+ VECSUB(tangent, ca->co, (ca - 1)->co);
+
+ vectoquat(tangent, OB_POSX, OB_POSZ, (ca-1)->rot);
+
+ VECCOPY(prev_tangent, tangent);
+ Normalize(prev_tangent);
+ }
+ else {
+ VECSUB(tangent, ca->co, (ca - 1)->co);
+ Normalize(tangent);
+
+ cosangle= Inpf(tangent, prev_tangent);
+
+ /* note we do the comparison on cosangle instead of
+ * angle, since floating point accuracy makes it give
+ * different results across platforms */
+ if(cosangle > 0.999999f) {
+ QUATCOPY((ca - 1)->rot, (ca - 2)->rot);
+ }
+ else {
+ angle= saacos(cosangle);
+ Crossf(normal, prev_tangent, tangent);
+ VecRotToQuat(normal, angle, q);
+ QuatMul((ca - 1)->rot, q, (ca - 2)->rot);
+ }
+
+ VECCOPY(prev_tangent, tangent);
+ }
+
+ if(k == steps)
+ QUATCOPY(ca->rot, (ca - 1)->rot);
+ }
+
+
+ /* set velocity */
+
+ if(k){
+ VECSUB(ca->vel, ca->co, (ca-1)->co);
+
+ if(k==1) {
+ VECCOPY((ca-1)->vel, ca->vel);
+ }
+
+ }
+
+ }
+ }
+
+ psys->totcached = totpart;
+
+ if(psys && psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
+ }
+
+ if(vg_effector)
+ MEM_freeN(vg_effector);
+}
+/************************************************/
+/* Particle Key handling */
+/************************************************/
+void copy_particle_key(ParticleKey *to, ParticleKey *from, int time){
+ if(time){
+ memcpy(to,from,sizeof(ParticleKey));
+ }
+ else{
+ float to_time=to->time;
+ memcpy(to,from,sizeof(ParticleKey));
+ to->time=to_time;
+ }
+ /*
+ VECCOPY(to->co,from->co);
+ VECCOPY(to->vel,from->vel);
+ QUATCOPY(to->rot,from->rot);
+ if(time)
+ to->time=from->time;
+ to->flag=from->flag;
+ to->sbw=from->sbw;
+ */
+}
+void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time){
+ if(loc) VECCOPY(loc,key->co);
+ if(vel) VECCOPY(vel,key->vel);
+ if(rot) QUATCOPY(rot,key->rot);
+ 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);
+}
+static void key_from_object(Object *ob, ParticleKey *key){
+ float q[4];
+
+ VECADD(key->vel,key->vel,key->co);
+
+ Mat4MulVecfl(ob->obmat,key->co);
+ Mat4MulVecfl(ob->obmat,key->vel);
+ Mat4ToQuat(ob->obmat,q);
+
+ VECSUB(key->vel,key->vel,key->co);
+ QuatMul(key->rot,q,key->rot);
+}
+
+static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4])
+{
+ float det, w1, w2, d1[2], d2[2];
+
+ memset(mat, 0, sizeof(float)*4*4);
+ mat[3][3]= 1.0f;
+
+ /* first axis is the normal */
+ CalcNormFloat(v1, v2, v3, mat[2]);
+
+ /* second axis along (1, 0) in uv space */
+ if(uv) {
+ d1[0]= uv[1][0] - uv[0][0];
+ d1[1]= uv[1][1] - uv[0][1];
+ d2[0]= uv[2][0] - uv[0][0];
+ d2[1]= uv[2][1] - uv[0][1];
+
+ det = d2[0]*d1[1] - d2[1]*d1[0];
+
+ if(det != 0.0f) {
+ det= 1.0f/det;
+ w1= -d2[1]*det;
+ w2= d1[1]*det;
+
+ mat[1][0]= w1*(v2[0] - v1[0]) + w2*(v3[0] - v1[0]);
+ mat[1][1]= w1*(v2[1] - v1[1]) + w2*(v3[1] - v1[1]);
+ mat[1][2]= w1*(v2[2] - v1[2]) + w2*(v3[2] - v1[2]);
+ Normalize(mat[1]);
+ }
+ else
+ mat[1][0]= mat[1][1]= mat[1][2]= 0.0f;
+ }
+ else {
+ VecSubf(mat[1], v2, v1);
+ Normalize(mat[1]);
+ }
+
+ /* third as a cross product */
+ Crossf(mat[0], mat[1], mat[2]);
+}
+
+static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco)
+{
+ float v[3][3];
+ MFace *mface;
+ OrigSpaceFace *osface;
+ float (*orcodata)[3];
+
+ int i = pa->num_dmcache==DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
+
+ if (i==-1 || i >= dm->getNumFaces(dm)) { Mat4One(mat); return; }
+
+ mface=dm->getFaceData(dm,i,CD_MFACE);
+ osface=dm->getFaceData(dm,i,CD_ORIGSPACE);
+
+ if(orco && (orcodata=dm->getVertDataArray(dm, CD_ORCO))) {
+ VECCOPY(v[0], orcodata[mface->v1]);
+ VECCOPY(v[1], orcodata[mface->v2]);
+ VECCOPY(v[2], orcodata[mface->v3]);
+
+ /* ugly hack to use non-transformed orcos, since only those
+ * give symmetric results for mirroring in particle mode */
+ transform_mesh_orco_verts(ob->data, v, 3, 1);
+ }
+ else {
+ dm->getVertCo(dm,mface->v1,v[0]);
+ dm->getVertCo(dm,mface->v2,v[1]);
+ dm->getVertCo(dm,mface->v3,v[2]);
+ }
+
+ triatomat(v[0], v[1], v[2], (osface)? osface->uv: NULL, mat);
+}
+
+void psys_mat_hair_to_object(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+{
+ float vec[3];
+
+ psys_face_mat(0, dm, pa, hairmat, 0);
+ psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0);
+ VECCOPY(hairmat[3],vec);
+}
+
+void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+{
+ float vec[3], orco[3];
+
+ psys_face_mat(ob, dm, pa, hairmat, 1);
+ psys_particle_on_dm(ob, dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
+
+ /* see psys_face_mat for why this function is called */
+ transform_mesh_orco_verts(ob->data, &orco, 1, 1);
+ VECCOPY(hairmat[3],orco);
+}
+
+/*
+void psys_key_to_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
+{
+ float q[4], v1[3], v2[3], v3[3];
+
+ dm->getVertCo(dm,pa->verts[0],v1);
+ dm->getVertCo(dm,pa->verts[1],v2);
+ dm->getVertCo(dm,pa->verts[2],v3);
+
+ triatoquat(v1, v2, v3, q);
+
+ QuatInv(q);
+
+ VECSUB(key->co,key->co,v1);
+
+ VECADD(key->vel,key->vel,key->co);
+
+ QuatMulVecf(q, key->co);
+ QuatMulVecf(q, key->vel);
+
+ VECSUB(key->vel,key->vel,key->co);
+
+ QuatMul(key->rot,q,key->rot);
+}
+
+void psys_key_from_geometry(DerivedMesh *dm, ParticleData *pa, ParticleKey *key)
+{
+ float q[4], v1[3], v2[3], v3[3];
+
+ dm->getVertCo(dm,pa->verts[0],v1);
+ dm->getVertCo(dm,pa->verts[1],v2);
+ dm->getVertCo(dm,pa->verts[2],v3);
+
+ triatoquat(v1, v2, v3, q);
+
+ VECADD(key->vel,key->vel,key->co);
+
+ QuatMulVecf(q, key->co);
+ QuatMulVecf(q, key->vel);
+
+ VECSUB(key->vel,key->vel,key->co);
+
+ VECADD(key->co,key->co,v1);
+
+ QuatMul(key->rot,q,key->rot);
+}
+*/
+
+void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec)//to_geometry(DerivedMesh *dm, ParticleData *pa, float *vec)
+{
+ float mat[4][4];
+
+ psys_face_mat(0, dm, pa, mat, 0);
+ Mat4Transp(mat); /* cheap inverse for rotation matrix */
+ Mat4Mul3Vecfl(mat, vec);
+}
+
+/* unused */
+#if 0
+static void psys_vec_rot_from_face(DerivedMesh *dm, ParticleData *pa, float *vec)//from_geometry(DerivedMesh *dm, ParticleData *pa, float *vec)
+{
+ float q[4], v1[3], v2[3], v3[3];
+ /*
+ dm->getVertCo(dm,pa->verts[0],v1);
+ dm->getVertCo(dm,pa->verts[1],v2);
+ dm->getVertCo(dm,pa->verts[2],v3);
+ */
+ /* replace with this */
+ MFace *mface;
+ int i; // = psys_particle_dm_face_lookup(dm, pa->num, pa->fuv, pa->foffset, (LinkNode*)NULL);
+ i = pa->num_dmcache==DMCACHE_NOTFOUND ? pa->num : pa->num_dmcache;
+ if (i==-1 || i >= dm->getNumFaces(dm)) { vec[0] = vec[1] = 0; vec[2] = 1; return; }
+ mface=dm->getFaceData(dm,i,CD_MFACE);
+
+ dm->getVertCo(dm,mface->v1,v1);
+ dm->getVertCo(dm,mface->v2,v2);
+ dm->getVertCo(dm,mface->v3,v3);
+ /* done */
+
+ triatoquat(v1, v2, v3, q);
+
+ QuatMulVecf(q, vec);
+
+ //VECADD(vec,vec,v1);
+}
+#endif
+
+void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4])
+{
+ float facemat[4][4];
+
+ psys_mat_hair_to_object(ob, dm, from, pa, facemat);
+
+ Mat4MulMat4(hairmat, facemat, ob->obmat);
+}
+
+/************************************************/
+/* ParticleSettings handling */
+/************************************************/
+static void default_particle_settings(ParticleSettings *part)
+{
+ int i;
+
+ part->type= PART_EMITTER;
+ part->distr= PART_DISTR_JIT;
+ part->draw_as=PART_DRAW_DOT;
+ part->bb_uv_split=1;
+ part->bb_align=PART_BB_VIEW;
+ part->bb_split_offset=PART_BB_OFF_LINEAR;
+ part->flag=PART_REACT_MULTIPLE|PART_HAIR_GEOMETRY;
+
+ part->sta= 1.0;
+ part->end= 100.0;
+ part->lifetime= 50.0;
+ part->jitfac= 1.0;
+ part->totpart= 1000;
+ part->grid_res= 10;
+ part->timetweak= 1.0;
+ part->keyed_time= 0.5;
+ //part->userjit;
+
+ part->integrator= PART_INT_MIDPOINT;
+ part->phystype= PART_PHYS_NEWTON;
+ part->hair_step= 5;
+ part->keys_step= 5;
+ part->draw_step= 2;
+ part->ren_step= 3;
+ part->adapt_angle= 5;
+ part->adapt_pix= 3;
+ part->kink_axis= 2;
+ part->reactevent= PART_EVENT_DEATH;
+ part->disp=100;
+ part->from= PART_FROM_FACE;
+ part->length= 1.0;
+ part->nbetween= 4;
+ part->boidneighbours= 5;
+
+ part->max_vel = 10.0f;
+ part->average_vel = 0.3f;
+ part->max_tan_acc = 0.2f;
+ part->max_lat_acc = 1.0f;
+
+ part->reactshape=1.0f;
+
+ part->mass=1.0;
+ part->size=1.0;
+ part->childsize=1.0;
+
+ part->child_nbr=10;
+ part->ren_child_nbr=100;
+ part->childrad=0.2f;
+ part->childflat=0.0f;
+ part->clumppow=0.0f;
+ part->kink_amp=0.2f;
+ part->kink_freq=2.0;
+
+ part->rough1_size=1.0;
+ part->rough2_size=1.0;
+ part->rough_end_shape=1.0;
+
+ part->draw_line[0]=0.5;
+
+ part->banking=1.0;
+ part->max_bank=1.0;
+
+ for(i=0; i<BOID_TOT_RULES; i++){
+ part->boidrule[i]=(char)i;
+ part->boidfac[i]=0.5;
+ }
+
+ part->ipo = NULL;
+
+ part->simplify_refsize= 1920;
+ part->simplify_rate= 1.0f;
+ part->simplify_transition= 0.1f;
+ part->simplify_viewport= 0.8;
+}
+
+
+ParticleSettings *psys_new_settings(char *name, Main *main)
+{
+ ParticleSettings *part;
+
+ part= alloc_libblock(&main->particle, ID_PA, name);
+
+ default_particle_settings(part);
+
+ return part;
+}
+
+ParticleSettings *psys_copy_settings(ParticleSettings *part)
+{
+ ParticleSettings *partn;
+
+ partn= copy_libblock(part);
+ if(partn->pd) partn->pd= MEM_dupallocN(part->pd);
+
+ return partn;
+}
+
+void psys_make_local_settings(ParticleSettings *part)
+{
+ Object *ob;
+ ParticleSettings *par;
+ int local=0, lib=0;
+
+ /* - only lib users: do nothing
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+
+ if(part->id.lib==0) return;
+ if(part->id.us==1) {
+ part->id.lib= 0;
+ part->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)part, 0);
+ return;
+ }
+
+ /* test objects */
+ ob= G.main->object.first;
+ while(ob) {
+ ParticleSystem *psys=ob->particlesystem.first;
+ for(; psys; psys=psys->next){
+ if(psys->part==part) {
+ if(ob->id.lib) lib= 1;
+ else local= 1;
+ }
+ }
+ ob= ob->id.next;
+ }
+
+ if(local && lib==0) {
+ part->id.lib= 0;
+ part->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)part, 0);
+ }
+ else if(local && lib) {
+
+ par= psys_copy_settings(part);
+ par->id.us= 0;
+
+ /* do objects */
+ ob= G.main->object.first;
+ while(ob) {
+ ParticleSystem *psys=ob->particlesystem.first;
+ for(; psys; psys=psys->next){
+ if(psys->part==part && ob->id.lib==0) {
+ psys->part= par;
+ par->id.us++;
+ part->id.us--;
+ }
+ }
+ ob= ob->id.next;
+ }
+ }
+}
+
+/* should be integrated to depgraph signals */
+void psys_flush_settings(ParticleSettings *part, int event, int hair_recalc)
+{
+ Base *base;
+ Object *ob, *tob;
+ ParticleSystem *psys;
+ int flush;
+
+ /* update all that have same particle settings */
+ for(base = G.scene->base.first; base; base= base->next) {
+ if(base->object->particlesystem.first) {
+ ob=base->object;
+ flush=0;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ if(psys->part==part){
+ psys->recalc |= event;
+ if(hair_recalc)
+ psys->recalc |= PSYS_RECALC_HAIR;
+ flush++;
+ }
+ else if(psys->part->type==PART_REACTOR){
+ ParticleSystem *tpsys;
+ tob=psys->target_ob;
+ if(tob==0)
+ tob=ob;
+ tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
+
+ if(tpsys && tpsys->part==part){
+ psys->recalc |= event;
+ flush++;
+ }
+ }
+ }
+ if(flush)
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+}
+/************************************************/
+/* Textures */
+/************************************************/
+static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float *fw, float *orco, ParticleTexture *ptex, int event)
+{
+ MTex *mtex;
+ int m,setvars=0;
+ float value, rgba[4], texco[3];
+
+ if(ma) for(m=0; m<MAX_MTEX; m++){
+ mtex=ma->mtex[m];
+ if(mtex && (ma->septex & (1<<m))==0){
+ float var=mtex->varfac;
+ short blend=mtex->blendtype;
+ short neg=mtex->pmaptoneg;
+
+ if(mtex->texco & TEXCO_UV && fw){
+ int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname);
+ if(uv_index<0){
+ uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
+ }
+ if(uv_index>=0){
+ CustomDataLayer *layer=&dm->faceData.layers[uv_index];
+ MTFace *mtface= &((MTFace*)layer->data)[face_index];
+ MFace *mf=dm->getFaceData(dm,face_index,CD_MFACE);
+ psys_interpolate_uvs(mtface,mf->v4,fw,texco);
+ texco[0]*=2.0;
+ texco[1]*=2.0;
+ texco[0]-=1.0;
+ texco[1]-=1.0;
+ }
+ else
+ VECCOPY(texco,orco);
+ }
+ else{
+ VECCOPY(texco,orco);
+ }
+ externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
+ if((event & mtex->pmapto) & MAP_PA_TIME){
+ if((setvars&MAP_PA_TIME)==0){
+ 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);
+ }
+ if((event & mtex->pmapto) & MAP_PA_LENGTH)
+ ptex->length= texture_value_blend(value,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
+ if((event & mtex->pmapto) & MAP_PA_CLUMP)
+ ptex->clump= texture_value_blend(value,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
+ if((event & mtex->pmapto) & MAP_PA_KINK)
+ ptex->kink= texture_value_blend(value,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
+ if((event & mtex->pmapto) & MAP_PA_ROUGH)
+ ptex->rough= texture_value_blend(value,ptex->rough,value,var,blend,neg & MAP_PA_ROUGH);
+ }
+ }
+ if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
+ if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); }
+ if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
+ if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
+ if(event & MAP_PA_ROUGH) { CLAMP(ptex->rough,0.0,1.0); }
+}
+void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
+{
+ MTex *mtex;
+ int m;
+ float value, rgba[4], co[3], texco[3];
+ int setvars=0;
+
+ if(ma) for(m=0; m<MAX_MTEX; m++){
+ mtex=ma->mtex[m];
+ if(mtex && (ma->septex & (1<<m))==0){
+ float var=mtex->varfac;
+ short blend=mtex->blendtype;
+ short neg=mtex->pmaptoneg;
+
+ if(mtex->texco & TEXCO_UV){
+ int uv_index=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,mtex->uvname);
+ if(uv_index<0){
+ uv_index=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE);
+ }
+ if(uv_index>=0){
+ CustomDataLayer *layer=&psmd->dm->faceData.layers[uv_index];
+ MTFace *mtface= &((MTFace*)layer->data)[pa->num];
+ MFace *mf=psmd->dm->getFaceData(psmd->dm,pa->num,CD_MFACE);
+ psys_interpolate_uvs(mtface,mf->v4,pa->fuv,texco);
+ texco[0]*=2.0;
+ texco[1]*=2.0;
+ texco[0]-=1.0;
+ texco[1]-=1.0;
+ }
+ else
+ //psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->fuv,pa->foffset,texco,0,0,0);
+ /* <jahka> anyways I think it will be too small a difference to notice, so psys_get_texture should only know about the original mesh structure.. no dm needed anywhere */
+ /* <brecht> the code only does dm based lookup now, so passing num_dmcache anyway to avoid^
+ * massive slowdown here */
+ psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
+ }
+ else{
+ //psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->fuv,pa->offset,texco,0,0,0);
+ /* ditto above */
+ psys_particle_on_emitter(ob,psmd,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);
+
+ 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);
+ setvars |= MAP_PA_TIME;
+ }
+ else
+ ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,var,blend,neg & MAP_PA_TIME);
+ }
+ if((event & mtex->pmapto) & MAP_PA_LIFE)
+ ptex->life= texture_value_blend(mtex->def_var,ptex->life,value,var,blend,neg & MAP_PA_LIFE);
+ if((event & mtex->pmapto) & MAP_PA_DENS)
+ ptex->exist= texture_value_blend(mtex->def_var,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
+ if((event & mtex->pmapto) & MAP_PA_SIZE)
+ ptex->size= texture_value_blend(mtex->def_var,ptex->size,value,var,blend,neg & MAP_PA_SIZE);
+ if((event & mtex->pmapto) & MAP_PA_IVEL)
+ ptex->ivel= texture_value_blend(mtex->def_var,ptex->ivel,value,var,blend,neg & MAP_PA_IVEL);
+ if((event & mtex->pmapto) & MAP_PA_PVEL)
+ texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,var,blend);
+ if((event & mtex->pmapto) & MAP_PA_LENGTH)
+ ptex->length= texture_value_blend(mtex->def_var,ptex->length,value,var,blend,neg & MAP_PA_LENGTH);
+ if((event & mtex->pmapto) & MAP_PA_CLUMP)
+ ptex->clump= texture_value_blend(mtex->def_var,ptex->clump,value,var,blend,neg & MAP_PA_CLUMP);
+ if((event & mtex->pmapto) & MAP_PA_KINK)
+ ptex->kink= texture_value_blend(mtex->def_var,ptex->kink,value,var,blend,neg & MAP_PA_CLUMP);
+ }
+ }
+ if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
+ if(event & MAP_PA_LIFE) { CLAMP(ptex->life,0.0,1.0); }
+ if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
+ if(event & MAP_PA_SIZE) { CLAMP(ptex->size,0.0,1.0); }
+ if(event & MAP_PA_IVEL) { CLAMP(ptex->ivel,0.0,1.0); }
+ if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); }
+ if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
+ if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
+}
+/************************************************/
+/* Particle State */
+/************************************************/
+float psys_get_timestep(ParticleSettings *part)
+{
+ 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;
+
+ 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(icu_size){
+ calc_icu(icu_size,pa->time);
+ size*=icu_size->curval;
+ }
+
+ if(vg_size)
+ size*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_size);
+
+ if(part->randsize!=0.0)
+ size*= 1.0f - part->randsize*pa->sizemul;
+
+ return size*part->size;
+}
+float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra)
+{
+ ParticleSettings *part = psys->part;
+
+ if(part->childtype==PART_CHILD_FACES){
+ float time;
+ int w=0;
+ time=0.0;
+ while(w<4 && cpa->pa[w]>=0){
+ time+=cpa->w[w]*(psys->particles+cpa->pa[w])->time;
+ w++;
+ }
+
+ return (cfra-time)/(part->lifetime*(1.0f-part->randlife*cpa->rand[1]));
+ }
+ else{
+ ParticleData *pa = psys->particles + cpa->parent;
+ return (cfra-pa->time)/pa->lifetime;
+ }
+}
+float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *pa_time)
+{
+ ParticleSettings *part = psys->part;
+ float size, time;
+
+ if(part->childtype==PART_CHILD_FACES){
+ if(pa_time)
+ time=*pa_time;
+ else
+ time=psys_get_child_time(psys,cpa,cfra);
+
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ calc_ipo(part->ipo, 100*time);
+ execute_ipo((ID *)part, part->ipo);
+ }
+ size=part->size;
+ }
+ else
+ size=psys->particles[cpa->parent].size;
+
+ size*=part->childsize;
+
+ if(part->childrandsize!=0.0)
+ size *= 1.0f - part->childrandsize*cpa->rand[2];
+
+ return size;
+}
+/* get's hair (or keyed) particles state at the "path time" specified in state->time */
+void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, 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);
+ ParticleData *pa;
+ ChildParticle *cpa;
+ ParticleTexture ptex;
+ ParticleKey *kkey[2] = {NULL, NULL};
+ HairKey *hkey[2] = {NULL, NULL};
+ ParticleKey *par=0, keys[4];
+
+ float t, real_t, dfra, keytime, frs_sec = G.scene->r.frs_sec;
+ float co[3], orco[3];
+ float hairmat[4][4];
+ float pa_clump = 0.0, pa_kink = 0.0;
+ int totparent = 0;
+ int totpart = psys->totpart;
+ int totchild = psys->totchild;
+ short between = 0, edit = 0;
+
+ float *cpa_fuv; int cpa_num; short cpa_from;
+
+ //if(psys_in_edit_mode(psys)){
+ // if((psys->edit_path->flag & PSYS_EP_SHOW_CHILD)==0)
+ // totchild=0;
+ // edit=1;
+ //}
+
+ /* user want's cubic interpolation but only without sb it possible */
+ //if(interpolation==PART_INTER_CUBIC && baked && psys->softflag==OB_SB_ENABLE)
+ // interpolation=PART_INTER_BSPLINE;
+ //else if(baked==0) /* it doesn't make sense to use other types for keyed */
+ // interpolation=PART_INTER_CUBIC;
+
+ t=state->time;
+ CLAMP(t, 0.0, 1.0);
+
+ if(p<totpart){
+ pa = psys->particles + p;
+
+ if(pa->alive==PARS_DEAD && part->flag & PART_STICKY && pa->flag & PARS_STICKY && pa->stick_ob){
+ copy_particle_key(state,&pa->state,0);
+ key_from_object(pa->stick_ob,state);
+ return;
+ }
+
+ if(psys->flag & PSYS_KEYED) {
+ kkey[0] = pa->keys;
+ kkey[1] = kkey[0] + 1;
+
+ real_t = kkey[0]->time + t * (kkey[0][pa->totkey-1].time - kkey[0]->time);
+ }
+ else {
+ hkey[0] = pa->hair;
+ hkey[1] = pa->hair + 1;
+
+ real_t = hkey[0]->time + (hkey[0][pa->totkey-1].time - hkey[0]->time) * t;
+ }
+
+ if(psys->flag & PSYS_KEYED) {
+ while(kkey[1]->time < real_t) {
+ kkey[1]++;
+ }
+ kkey[0] = kkey[1] - 1;
+
+ memcpy(keys + 1, kkey[0], sizeof(ParticleKey));
+ memcpy(keys + 2, kkey[1], sizeof(ParticleKey));
+ }
+ else {
+ while(hkey[1]->time < real_t)
+ hkey[1]++;
+
+ hkey[0] = hkey[1] - 1;
+
+ hair_to_particle(keys + 1, hkey[0]);
+ hair_to_particle(keys + 2, hkey[1]);
+ }
+
+ if((psys->flag & PSYS_KEYED)==0) {
+ //if(soft){
+ // if(key[0] != sbel.keys)
+ // DB_copy_key(&k1,key[0]-1);
+ // else
+ // DB_copy_key(&k1,&k2);
+ //}
+ //else{
+ if(hkey[0] != pa->hair)
+ hair_to_particle(keys, hkey[0] - 1);
+ else
+ hair_to_particle(keys, hkey[0]);
+ //}
+
+ //if(soft){
+ // if(key[1] != sbel.keys + sbel.totkey-1)
+ // DB_copy_key(&k4,key[1]+1);
+ // else
+ // DB_copy_key(&k4,&k3);
+ //}
+ //else {
+ if(hkey[1] != pa->hair + pa->totkey - 1)
+ hair_to_particle(keys + 3, hkey[1] + 1);
+ else
+ hair_to_particle(keys + 3, hkey[1]);
+ }
+ //}
+
+ //psys_get_particle_on_path(bsys,p,t,bkey,ckey[0]);
+
+ //if(part->rotfrom==PART_ROT_KEYS)
+ // QuatInterpol(state->rot,k2.rot,k3.rot,keytime);
+ //else{
+ // /* TODO: different rotations */
+ // float nvel[3];
+ // VECCOPY(nvel,state->vel);
+ // VecMulf(nvel,-1.0f);
+ // vectoquat(nvel, OB_POSX, OB_POSZ, state->rot);
+ //}
+
+ dfra = keys[2].time - keys[1].time;
+
+ keytime = (real_t - keys[1].time) / dfra;
+
+ /* convert velocity to timestep size */
+ if(psys->flag & PSYS_KEYED){
+ VecMulf(keys[1].vel, dfra / frs_sec);
+ VecMulf(keys[2].vel, dfra / frs_sec);
+ QuatInterpol(state->rot,keys[1].rot,keys[2].rot,keytime);
+ }
+
+ interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */
+ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL)
+ ,keys, keytime, state, 1);
+
+ /* the velocity needs to be converted back from cubic interpolation */
+ if(psys->flag & PSYS_KEYED){
+ VecMulf(state->vel, frs_sec / dfra);
+ }
+ else {
+ if((pa->flag & PARS_REKEY)==0) {
+ psys_mat_hair_to_global(ob, 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(state, p, state->time, &psys->effectors);
+ /* TODO: proper velocity handling */
+ }
+
+ if(psys->lattice && edit==0)
+ calc_latt_deform(state->co,1.0f);
+ }
+ }
+ }
+ else if(totchild){
+ //Mat4Invert(imat,ob->obmat);
+
+ cpa=psys->child+p-totpart;
+
+ if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ totparent=(int)(totchild*part->parents*0.3);
+ /* part->parents could still be 0 so we can't test with totparent */
+ between=1;
+ }
+ if(between){
+ int w = 0;
+ float foffset;
+
+ /* get parent states */
+ while(w<4 && cpa->pa[w]>=0){
+ keys[w].time = t;
+ psys_get_particle_on_path(ob, psys, cpa->pa[w], keys+w, 1);
+ w++;
+ }
+
+ /* get the original coordinates (orco) for texture usage */
+ cpa_num=cpa->num;
+
+ foffset= cpa->foffset;
+ if(part->childtype == PART_CHILD_FACES)
+ foffset = -(2.0f + part->childspread);
+ cpa_fuv = cpa->fuv;
+ cpa_from = PART_FROM_FACE;
+
+ psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0);
+
+ /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
+ //VECCOPY(cpa_1st,co);
+
+ //Mat4MulVecfl(ob->obmat,cpa_1st);
+
+ pa=0;
+ }
+ else{
+ /* get the parent state */
+
+ keys->time = t;
+ psys_get_particle_on_path(ob,psys,cpa->parent,keys,1);
+
+ /* get the original coordinates (orco) for texture usage */
+ pa=psys->particles+cpa->parent;
+
+ cpa_from=part->from;
+ cpa_num=pa->num;
+ cpa_fuv=pa->fuv;
+
+ psys_particle_on_emitter(ob,psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
+ }
+
+ /* correct child ipo timing */
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ calc_ipo(part->ipo, 100.0f*t);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ /* get different child parameters from textures & vgroups */
+ ptex.clump=1.0;
+ ptex.kink=1.0;
+
+ get_cpa_texture(psmd->dm,ma,cpa_num,cpa_fuv,orco,&ptex,MAP_PA_CLUMP|MAP_PA_KINK);
+
+ pa_clump=ptex.clump;
+ pa_kink=ptex.kink;
+
+ /* TODO: vertex groups */
+
+ if(between){
+ int w=0;
+
+ state->co[0] = state->co[1] = state->co[2] = 0.0f;
+ state->vel[0] = state->vel[1] = state->vel[2] = 0.0f;
+
+ /* child position is the weighted sum of parent positions */
+ while(w<4 && cpa->pa[w]>=0){
+ state->co[0] += cpa->w[w] * keys[w].co[0];
+ state->co[1] += cpa->w[w] * keys[w].co[1];
+ state->co[2] += cpa->w[w] * keys[w].co[2];
+
+ state->vel[0] += cpa->w[w] * keys[w].vel[0];
+ state->vel[1] += cpa->w[w] * keys[w].vel[1];
+ state->vel[2] += cpa->w[w] * keys[w].vel[2];
+ w++;
+ }
+ /* apply offset for correct positioning */
+ //VECADD(state->co,state->co,cpa_1st);
+ }
+ else{
+ /* offset the child from the parent position */
+ offset_child(cpa, keys, state, part->childflat, part->childrad);
+ }
+
+ par = keys;
+ //if(totparent){
+ // if(p-totpart>=totparent){
+ // key.time=t;
+ // psys_get_particle_on_path(ob,psys,totpart+cpa->parent,&key,1);
+ // bti->convert_dynamic_key(bsys,&key,par,cpar);
+ // }
+ // else
+ // par=0;
+ //}
+ //else
+ // DB_get_key_on_path(bsys,cpa->parent,t,par,cpar);
+
+ /* apply different deformations to the child path */
+ if(part->kink)
+ do_prekink(state, par, par->rot, t, part->kink_freq * pa_kink, part->kink_shape,
+ part->kink_amp, part->kink, part->kink_axis, ob->obmat);
+
+ do_clump(state, par, t, part->clumpfac, part->clumppow, 1.0f);
+
+ if(part->rough1 != 0.0)
+ do_rough(orco, t, part->rough1, part->rough1_size, 0.0, state);
+
+ if(part->rough2 != 0.0)
+ do_rough(cpa->rand, t, part->rough2, part->rough2_size, part->rough2_thres, state);
+
+ if(part->rough_end != 0.0)
+ do_rough_end(cpa->rand, t, part->rough_end, part->rough_end_shape, state, par);
+
+ //if(vel){
+ // if(t>=0.001f){
+ // tstate.time=t-0.001f;
+ // psys_get_particle_on_path(ob,psys,p,&tstate,0);
+ // VECSUB(state->vel,state->co,tstate.co);
+ // }
+ // else{
+ // tstate.time=t+0.001f;
+ // psys_get_particle_on_path(ob,psys,p,&tstate,0);
+ // VECSUB(state->vel,tstate.co,state->co);
+ // }
+ //}
+ }
+}
+/* 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(Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){
+ ParticleSettings *part=psys->part;
+ ParticleData *pa=0;
+ float cfra;
+ int totpart=psys->totpart, between=0;
+
+ if(state->time>0)
+ cfra=state->time;
+ else
+ cfra=bsystem_time(0,(float)G.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);
+
+ if(always==0)
+ if((state->time<0.0 && (part->flag & PART_UNBORN)==0)
+ || (state->time>1.0 && (part->flag & PART_DIED)==0))
+ return 0;
+ }
+ else{
+ if(pa->alive==PARS_KILLED) return 0;
+ if(always==0)
+ if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
+ || (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
+ return 0;
+ }
+
+ 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-pa->time)/(pa->dietime-pa->time);
+
+ psys_get_particle_on_path(ob,psys,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;
+ ParticleKey *key1, skey;
+ float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime;
+
+ pa = psys->particles + cpa->parent;
+
+ if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob) {
+ key1 = &skey;
+ copy_particle_key(key1,&pa->state,0);
+ key_from_object(pa->stick_ob,key1);
+ }
+ else {
+ 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);
+
+ /* TODO: pa_clump vgroup */
+ do_clump(state,key1,t,part->clumpfac,part->clumppow,1.0);
+ }
+ else{
+ if (pa) { /* TODO PARTICLE - should this ever be NULL? - Campbell */
+ copy_particle_key(state,&pa->state,0);
+
+ if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob){
+ key_from_object(pa->stick_ob,state);
+ }
+
+ if(psys->lattice)
+ calc_latt_deform(state->co,1.0f);
+ }
+ }
+
+ return 1;
+ }
+}
+
+void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco)
+{
+ MFace *mface;
+ MTFace *mtface;
+ float loc[3];
+ int num;
+
+ if(cpa) {
+ if(part->childtype == PART_CHILD_FACES) {
+ mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+ if(mtface) {
+ mface= psmd->dm->getFaceData(psmd->dm, cpa->num, CD_MFACE);
+ mtface += cpa->num;
+ psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
+ }
+ else
+ uv[0]= uv[1]= 0.0f;
+ }
+ else
+ uv[0]= uv[1]= 0.0f;
+
+ psys_particle_on_emitter(ob, psmd,
+ (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+ cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0);
+ }
+ else {
+ if(part->from == PART_FROM_FACE) {
+ mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+ num= pa->num_dmcache;
+
+ if(num == DMCACHE_NOTFOUND)
+ if(pa->num < psmd->dm->getNumFaces(psmd->dm))
+ num= pa->num;
+
+ if(mtface && num != DMCACHE_NOTFOUND) {
+ mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE);
+ mtface += num;
+ psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
+ }
+ else
+ uv[0]= uv[1]= 0.0f;
+ }
+ else
+ uv[0]= uv[1]= 0.0f;
+
+ psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
+ }
+}
+
+void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
+{
+ 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];
+
+ VecSubf(vec, (cache+cache->steps-1)->co, cache->co);
+ len= Normalize(vec);
+
+ if(pa)
+ psys_particle_on_emitter(ob,psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+ else
+ psys_particle_on_emitter(ob, psmd,
+ (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+ cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+
+ if(psys->part->rotmode) {
+ if(!pa)
+ pa= psys->particles+cpa->pa[0];
+
+ vectoquat(xvec, ob->trackflag, ob->upflag, q);
+ QuatToMat4(q, obrotmat);
+ obrotmat[3][3]= 1.0f;
+
+ QuatToMat4(pa->state.rot, qmat);
+ Mat4MulMat4(mat, obrotmat, qmat);
+ }
+ else {
+ Crossf(side, nor, vec);
+ Normalize(side);
+ Crossf(nor, vec, side);
+
+ Mat4One(mat);
+ VECCOPY(mat[0], vec);
+ VECCOPY(mat[1], side);
+ VECCOPY(mat[2], nor);
+ }
+
+ *scale= len;
+}
+
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
new file mode 100644
index 00000000000..568a3a34d91
--- /dev/null
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -0,0 +1,4680 @@
+/* particle_system.c
+ *
+ *
+ * $Id: particle_system.c $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_particle_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+
+#include "BLI_rand.h"
+#include "BLI_jitter.h"
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_kdtree.h"
+#include "BLI_linklist.h"
+#include "BLI_threads.h"
+
+#include "BKE_anim.h"
+#include "BKE_bad_level_calls.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_displist.h"
+#include "BKE_particle.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
+#include "BKE_ipo.h"
+#include "BKE_softbody.h"
+#include "BKE_depsgraph.h"
+#include "BKE_lattice.h"
+#include "BKE_pointcache.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_scene.h"
+
+#include "BSE_headerbuttons.h"
+
+#include "blendef.h"
+
+#include "RE_shader_ext.h"
+
+/************************************************/
+/* Reacting to system events */
+/************************************************/
+
+static int get_current_display_percentage(ParticleSystem *psys)
+{
+ ParticleSettings *part=psys->part;
+
+ if(psys->renderdata || (part->child_nbr && part->childtype))
+ return 100;
+
+ if(part->phystype==PART_PHYS_KEYED){
+ if(psys->flag & PSYS_FIRST_KEYED)
+ return psys->part->disp;
+ else
+ return 100;
+ }
+ else
+ return psys->part->disp;
+}
+
+static void alloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
+{
+ ParticleData *newpars = 0, *pa;
+ int i, totpart, totsaved = 0;
+
+ if(new_totpart<0) {
+ if(psys->part->distr==PART_DISTR_GRID) {
+ totpart= psys->part->grid_res;
+ totpart*=totpart*totpart;
+ }
+ else
+ totpart=psys->part->totpart;
+ }
+ else
+ totpart=new_totpart;
+
+ if(totpart)
+ newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
+ if(psys->particles) {
+ totsaved=MIN2(psys->totpart,totpart);
+ /*save old pars*/
+ if(totsaved)
+ memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
+
+ for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
+ if(pa->hair) MEM_freeN(pa->hair);
+
+ MEM_freeN(psys->particles);
+ }
+ psys->particles=newpars;
+
+ if(psys->child) {
+ MEM_freeN(psys->child);
+ psys->child=0;
+ psys->totchild=0;
+ }
+
+ psys->totpart=totpart;
+}
+
+static int get_psys_child_number(ParticleSystem *psys)
+{
+ int nbr;
+
+ if(!psys->part->childtype)
+ return 0;
+
+ if(psys->renderdata) {
+ nbr= psys->part->ren_child_nbr;
+ return get_render_child_particle_number(&G.scene->r, nbr);
+ }
+ else
+ return psys->part->child_nbr;
+}
+
+static int get_psys_tot_child(ParticleSystem *psys)
+{
+ return psys->totpart*get_psys_child_number(psys);
+}
+
+static void alloc_child_particles(ParticleSystem *psys, int tot)
+{
+ if(psys->child){
+ MEM_freeN(psys->child);
+ psys->child=0;
+ psys->totchild=0;
+ }
+
+ if(psys->part->childtype) {
+ psys->totchild= tot;
+ if(psys->totchild)
+ psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
+ }
+}
+
+void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
+{
+ /* use for building derived mesh mapping info:
+
+ node: the allocated links - total derived mesh element count
+ nodearray: the array of nodes aligned with the base mesh's elements, so
+ each original elements can reference its derived elements
+ */
+ Mesh *me= (Mesh*)ob->data;
+ ParticleData *pa= 0;
+ int p;
+
+ /* CACHE LOCATIONS */
+ if(!dm->deformedOnly) {
+ /* Will use later to speed up subsurf/derivedmesh */
+ LinkNode *node, *nodedmelem, **nodearray;
+ int totdmelem, totelem, i, *origindex;
+
+ if(psys->part->from == PART_FROM_VERT) {
+ totdmelem= dm->getNumVerts(dm);
+ totelem= me->totvert;
+ origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ }
+ else { /* FROM_FACE/FROM_VOLUME */
+ totdmelem= dm->getNumFaces(dm);
+ totelem= me->totface;
+ origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ }
+
+ nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
+ nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
+
+ for(i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) {
+ node->link= SET_INT_IN_POINTER(i);
+
+ if(*origindex != -1) {
+ if(nodearray[*origindex]) {
+ /* prepend */
+ node->next = nodearray[*origindex];
+ nodearray[*origindex]= node;
+ }
+ else
+ nodearray[*origindex]= node;
+ }
+ }
+
+ /* cache the verts/faces! */
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
+ if(psys->part->from == PART_FROM_VERT) {
+ if(nodearray[pa->num])
+ pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
+ }
+ else { /* FROM_FACE/FROM_VOLUME */
+ /* Note that somtimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
+ * but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
+ pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
+ }
+ }
+
+ MEM_freeN(nodearray);
+ MEM_freeN(nodedmelem);
+ }
+ else {
+ /* TODO PARTICLE, make the following line unnecessary, each function
+ * should know to use the num or num_dmcache, set the num_dmcache to
+ * an invalid value, just incase */
+
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++)
+ pa->num_dmcache = -1;
+ }
+}
+
+static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
+{
+ ParticleData *pa=0;
+ float min[3], max[3], delta[3], d;
+ MVert *mv, *mvert = dm->getVertDataArray(dm,0);
+ int totvert=dm->getNumVerts(dm), from=psys->part->from;
+ int i, j, k, p, res=psys->part->grid_res, size[3], axis;
+
+ mv=mvert;
+
+ /* find bounding box of dm */
+ VECCOPY(min,mv->co);
+ VECCOPY(max,mv->co);
+ mv++;
+
+ for(i=1; i<totvert; i++, mv++){
+ min[0]=MIN2(min[0],mv->co[0]);
+ min[1]=MIN2(min[1],mv->co[1]);
+ min[2]=MIN2(min[2],mv->co[2]);
+
+ max[0]=MAX2(max[0],mv->co[0]);
+ max[1]=MAX2(max[1],mv->co[1]);
+ max[2]=MAX2(max[2],mv->co[2]);
+ }
+
+ VECSUB(delta,max,min);
+
+ /* determine major axis */
+ axis = (delta[0]>=delta[1])?0:((delta[1]>=delta[2])?1:2);
+
+ d = delta[axis]/(float)res;
+
+ size[axis]=res;
+ size[(axis+1)%3]=(int)ceil(delta[(axis+1)%3]/d);
+ size[(axis+2)%3]=(int)ceil(delta[(axis+2)%3]/d);
+
+ /* float errors grrr.. */
+ size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
+ size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
+
+ min[0]+=d/2.0f;
+ min[1]+=d/2.0f;
+ min[2]+=d/2.0f;
+
+ for(i=0,p=0,pa=psys->particles; i<res; i++){
+ for(j=0; j<res; j++){
+ for(k=0; k<res; k++,p++,pa++){
+ pa->fuv[0]=min[0]+(float)i*d;
+ pa->fuv[1]=min[1]+(float)j*d;
+ pa->fuv[2]=min[2]+(float)k*d;
+ pa->flag |= PARS_UNEXIST;
+ pa->loop=0; /* abused in volume calculation */
+ }
+ }
+ }
+
+ /* enable particles near verts/edges/faces/inside surface */
+ if(from==PART_FROM_VERT){
+ float vec[3];
+
+ pa=psys->particles;
+
+ min[0]-=d/2.0f;
+ min[1]-=d/2.0f;
+ min[2]-=d/2.0f;
+
+ for(i=0,mv=mvert; i<totvert; i++,mv++){
+ VecSubf(vec,mv->co,min);
+ vec[0]/=delta[0];
+ vec[1]/=delta[1];
+ vec[2]/=delta[2];
+ (pa +((int)(vec[0]*(size[0]-1))*res
+ +(int)(vec[1]*(size[1]-1)))*res
+ +(int)(vec[2]*(size[2]-1)))->flag &= ~PARS_UNEXIST;
+ }
+ }
+ else if(ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)){
+ float co1[3], co2[3];
+
+ MFace *mface=0;
+ float v1[3], v2[3], v3[3], v4[4], lambda;
+ int a, a1, a2, a0mul, a1mul, a2mul, totface;
+ int amax= from==PART_FROM_FACE ? 3 : 1;
+
+ totface=dm->getNumFaces(dm);
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+
+ for(a=0; a<amax; a++){
+ if(a==0){ a0mul=res*res; a1mul=res; a2mul=1; }
+ else if(a==1){ a0mul=res; a1mul=1; a2mul=res*res; }
+ else{ a0mul=1; a1mul=res*res; a2mul=res; }
+
+ for(a1=0; a1<size[(a+1)%3]; a1++){
+ for(a2=0; a2<size[(a+2)%3]; a2++){
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+
+ pa=psys->particles + a1*a1mul + a2*a2mul;
+ VECCOPY(co1,pa->fuv);
+ co1[a]-=d/2.0f;
+ VECCOPY(co2,co1);
+ co2[a]+=delta[a] + 0.001f*d;
+ co1[a]-=0.001f*d;
+
+ /* lets intersect the faces */
+ for(i=0; i<totface; i++,mface++){
+ VECCOPY(v1,mvert[mface->v1].co);
+ VECCOPY(v2,mvert[mface->v2].co);
+ VECCOPY(v3,mvert[mface->v3].co);
+
+ if(AxialLineIntersectsTriangle(a,co1, co2, v2, v3, v1, &lambda)){
+ if(from==PART_FROM_FACE)
+ (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ else /* store number of intersections */
+ (pa+(int)(lambda*size[a])*a0mul)->loop++;
+ }
+
+ if(mface->v4){
+ VECCOPY(v4,mvert[mface->v4].co);
+
+ if(AxialLineIntersectsTriangle(a,co1, co2, v4, v1, v3, &lambda)){
+ if(from==PART_FROM_FACE)
+ (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ else
+ (pa+(int)(lambda*size[a])*a0mul)->loop++;
+ }
+ }
+ }
+
+ if(from==PART_FROM_VOLUME){
+ int in=pa->loop%2;
+ if(in) pa->loop++;
+ for(i=0; i<size[0]; i++){
+ if(in || (pa+i*a0mul)->loop%2)
+ (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
+ /* odd intersections == in->out / out->in */
+ /* even intersections -> in stays same */
+ in=(in + (pa+i*a0mul)->loop) % 2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(psys->part->flag & PART_GRID_INVERT){
+ for(i=0,pa=psys->particles; i<size[0]; i++){
+ for(j=0; j<size[1]; j++){
+ pa=psys->particles + res*(i*res + j);
+ for(k=0; k<size[2]; k++, pa++){
+ pa->flag ^= PARS_UNEXIST;
+ }
+ }
+ }
+ }
+}
+
+/* modified copy from rayshade.c */
+static void hammersley_create(float *out, int n, int seed, float amount)
+{
+ RNG *rng;
+ double p, t, offs[2];
+ int k, kk;
+
+ rng = rng_new(31415926 + n + seed);
+ offs[0]= rng_getDouble(rng) + amount;
+ offs[1]= rng_getDouble(rng) + amount;
+ rng_free(rng);
+
+ for (k = 0; k < n; k++) {
+ t = 0;
+ for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
+ if (kk & 1) /* kk mod 2 = 1 */
+ t += p;
+
+ out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
+ out[2*k + 1]= fmod(t + offs[1], 1.0);
+ }
+}
+
+/* modified copy from effect.c */
+static void init_mv_jit(float *jit, int num, int seed2, float amount)
+{
+ RNG *rng;
+ float *jit2, x, rad1, rad2, rad3;
+ int i, num2;
+
+ if(num==0) return;
+
+ rad1= (float)(1.0/sqrt((float)num));
+ rad2= (float)(1.0/((float)num));
+ rad3= (float)sqrt((float)num)/((float)num);
+
+ rng = rng_new(31415926 + num + seed2);
+ x= 0;
+ num2 = 2 * num;
+ for(i=0; i<num2; i+=2) {
+
+ jit[i]= x + amount*rad1*(0.5f - rng_getFloat(rng));
+ jit[i+1]= i/(2.0f*num) + amount*rad1*(0.5f - rng_getFloat(rng));
+
+ jit[i]-= (float)floor(jit[i]);
+ jit[i+1]-= (float)floor(jit[i+1]);
+
+ x+= rad3;
+ x -= (float)floor(x);
+ }
+
+ jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
+
+ for (i=0 ; i<4 ; i++) {
+ BLI_jitterate1(jit, jit2, num, rad1);
+ BLI_jitterate1(jit, jit2, num, rad1);
+ BLI_jitterate2(jit, jit2, num, rad2);
+ }
+ MEM_freeN(jit2);
+ rng_free(rng);
+}
+
+static void psys_uv_to_w(float u, float v, int quad, float *w)
+{
+ float vert[4][3], co[3];
+
+ if(!quad) {
+ if(u+v > 1.0f)
+ v= 1.0f-v;
+ else
+ u= 1.0f-u;
+ }
+
+ vert[0][0]= 0.0f; vert[0][1]= 0.0f; vert[0][2]= 0.0f;
+ vert[1][0]= 1.0f; vert[1][1]= 0.0f; vert[1][2]= 0.0f;
+ vert[2][0]= 1.0f; vert[2][1]= 1.0f; vert[2][2]= 0.0f;
+
+ co[0]= u;
+ co[1]= v;
+ co[2]= 0.0f;
+
+ if(quad) {
+ vert[3][0]= 0.0f; vert[3][1]= 1.0f; vert[3][2]= 0.0f;
+ MeanValueWeights(vert, 4, co, w);
+ }
+ else {
+ MeanValueWeights(vert, 3, co, w);
+ w[3]= 0.0f;
+ }
+}
+
+static int binary_search_distribution(float *sum, int n, float value)
+{
+ int mid, low=0, high=n;
+
+ while(low <= high) {
+ mid= (low + high)/2;
+ if(sum[mid] <= value && value <= sum[mid+1])
+ return mid;
+ else if(sum[mid] > value)
+ high= mid - 1;
+ else if(sum[mid] < value)
+ low= mid + 1;
+ else
+ return mid;
+ }
+
+ return low;
+}
+
+/* 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)
+{
+ ParticleThreadContext *ctx= thread->ctx;
+ Object *ob= ctx->ob;
+ DerivedMesh *dm= ctx->dm;
+ ParticleData *tpa;
+ ParticleSettings *part= ctx->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;
+ int cfrom= ctx->cfrom;
+ int distr= ctx->distr;
+ int i, intersect, tot;
+
+ if(from == PART_FROM_VERT) {
+ /* TODO_PARTICLE - use original index */
+ 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){
+ KDTreeNearest ptn[3];
+ int w, maxw;
+
+ psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
+ transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
+ maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
+
+ for(w=0; w<maxw; w++){
+ pa->verts[w]=ptn->num;
+ }
+ }
+#endif
+ }
+ else if(from == PART_FROM_FACE || from == PART_FROM_VOLUME) {
+ MFace *mface;
+
+ pa->num = i = ctx->index[p];
+ mface = dm->getFaceData(dm,i,CD_MFACE);
+
+ switch(distr){
+ case PART_DISTR_JIT:
+ 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);
+ randv= rng_getFloat(thread->rng);
+ psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
+ break;
+ }
+ 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);
+
+ tot=dm->getNumFaces(dm);
+
+ psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
+
+ Normalize(nor);
+ VecMulf(nor,-100.0);
+
+ VECADD(co2,co1,nor);
+
+ min_d=2.0;
+ intersect=0;
+
+ for(i=0,mface=dm->getFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++){
+ if(i==pa->num) continue;
+
+ v1=mvert[mface->v1].co;
+ v2=mvert[mface->v2].co;
+ v3=mvert[mface->v3].co;
+
+ if(LineIntersectsTriangle(co1, co2, v2, v3, v1, &cur_d, 0)){
+ if(cur_d<min_d){
+ min_d=cur_d;
+ pa->foffset=cur_d*50.0f; /* to the middle of volume */
+ intersect=1;
+ }
+ }
+ if(mface->v4){
+ v4=mvert[mface->v4].co;
+
+ if(LineIntersectsTriangle(co1, co2, v4, v1, v3, &cur_d, 0)){
+ if(cur_d<min_d){
+ min_d=cur_d;
+ pa->foffset=cur_d*50.0f; /* to the middle of volume */
+ intersect=1;
+ }
+ }
+ }
+ }
+ if(intersect==0)
+ pa->foffset=0.0;
+ else switch(distr){
+ case PART_DISTR_JIT:
+ pa->foffset*= ctx->jit[2*(int)ctx->jitoff[i]];
+ break;
+ case PART_DISTR_RAND:
+ pa->foffset*=BLI_frand();
+ break;
+ }
+ }
+ }
+ 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];
+ pa->fuv[1]=tpa->fuv[1];
+ /* abusing foffset a little for timing in near reaction */
+ pa->foffset=ctx->weight[ctx->index[p]];
+ ctx->weight[ctx->index[p]]+=ctx->maxweight;
+ }
+ else if(from == PART_FROM_CHILD) {
+ MFace *mf;
+
+ if(ctx->index[p] < 0) {
+ 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;
+ //}
+
+ 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;
+ float maxd,mind,dd,totw=0.0;
+ int parent[10];
+ float pweight[10];
+
+ do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
+
+ psys_particle_on_dm(ob,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);
+
+ maxd=ptn[maxw-1].dist;
+ mind=ptn[0].dist;
+ dd=maxd-mind;
+
+ /* the weights here could be done better */
+ 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)
+ VecMulf(tan,-1.0f);
+ }
+ 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){
+ cpa->pa[i]=parent[w];
+ cpa->w[i]=pweight[w];
+ totw+=pweight[w];
+ i++;
+ }
+ }
+ for(;i<4; i++){
+ cpa->pa[i]=-1;
+ cpa->w[i]=0.0f;
+ }
+
+ if(totw>0.0f) for(w=0; w<4; w++)
+ cpa->w[w]/=totw;
+
+ cpa->parent=cpa->pa[0];
+ }
+ }
+}
+
+void *exec_distribution(void *data)
+{
+ ParticleThread *thread= (ParticleThread*)data;
+ ParticleSystem *psys= thread->ctx->psys;
+ ParticleData *pa;
+ ChildParticle *cpa;
+ int p, totpart;
+
+ if(thread->ctx->from == PART_FROM_CHILD) {
+ totpart= psys->totchild;
+ cpa= psys->child;
+
+ for(p=0; p<totpart; p++, cpa++) {
+ if(thread->ctx->skip) /* simplification skip */
+ rng_skip(thread->rng, 5*thread->ctx->skip[p]);
+
+ if((p+thread->num) % thread->tot == 0)
+ psys_thread_distribute_particle(thread, NULL, cpa, p);
+ else /* thread skip */
+ rng_skip(thread->rng, 5);
+ }
+ }
+ else {
+ totpart= psys->totpart;
+ pa= psys->particles + thread->num;
+ for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
+ psys_thread_distribute_particle(thread, pa, NULL, p);
+ }
+
+ return 0;
+}
+
+/* not thread safe, but qsort doesn't take userdata argument */
+static int *COMPARE_ORIG_INDEX = NULL;
+static int compare_orig_index(const void *p1, const void *p2)
+{
+ int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
+ int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
+
+ if(index1 < index2)
+ return -1;
+ else if(index1 == index2)
+ return 0;
+ else
+ return 1;
+}
+
+/* creates a distribution of coordinates on a DerivedMesh */
+/* */
+/* 1. lets check from what we are emitting */
+/* 2. now we know that we have something to emit from so */
+/* let's calculate some weights */
+/* 2.1 from even distribution */
+/* 2.2 and from vertex groups */
+/* 3. next we determine the indexes of emitting thing that */
+/* the particles will have */
+/* 4. let's do jitter if we need it */
+/* 5. now we're ready to set the indexes & distributions to */
+/* the particles */
+/* 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, DerivedMesh *finaldm, int from)
+{
+ ParticleThreadContext *ctx= threads[0].ctx;
+ Object *ob= ctx->ob;
+ ParticleSystem *psys= ctx->psys;
+ Object *tob;
+ ParticleData *pa=0, *tpars= 0;
+ ParticleSettings *part;
+ ParticleSystem *tpsys;
+ ParticleSeam *seams= 0;
+ ChildParticle *cpa=0;
+ KDTree *tree=0;
+ DerivedMesh *dm= NULL;
+ float *jit= NULL;
+ int i, seed, p=0, totthread= threads[0].tot;
+ int no_distr=0, cfrom=0;
+ int tot=0, totpart, *index=0, children=0, totseam=0;
+ //int *vertpart=0;
+ int jitlevel= 1, distr;
+ float *weight=0,*sum=0,*jitoff=0;
+ float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3];
+
+ if(ob==0 || psys==0 || psys->part==0)
+ return 0;
+
+ part=psys->part;
+ totpart=psys->totpart;
+ if(totpart==0)
+ return 0;
+
+ if (!finaldm->deformedOnly && !CustomData_has_layer( &finaldm->faceData, CD_ORIGINDEX ) ) {
+ error("Can't paint with the current modifier stack, disable destructive modifiers");
+ return 0;
+ }
+
+ BLI_srandom(31415926 + psys->seed);
+
+ if(from==PART_FROM_CHILD){
+ distr=PART_DISTR_RAND;
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ dm= finaldm;
+ children=1;
+
+ tree=BLI_kdtree_new(totpart);
+
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
+ transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
+ BLI_kdtree_insert(tree, p, orco, ornor);
+ }
+
+ BLI_kdtree_balance(tree);
+
+ totpart=get_psys_tot_child(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);
+
+ 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];
+
+ 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);
+
+ 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]);
+
+ VecAddf(cur_seam->nor,temp,temp2);
+ Normalize(cur_seam->nor);
+
+ Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
+
+ Normalize(cur_seam->tan);
+
+ cur_seam++;
+ }
+ }
+ }
+
+ }
+ }
+ else{
+ /* no need to figure out distribution */
+ int child_nbr= get_psys_child_number(psys);
+
+ totpart= get_psys_tot_child(psys);
+ alloc_child_particles(psys, totpart);
+ cpa=psys->child;
+ for(i=0; i<child_nbr; i++){
+ for(p=0; p<psys->totpart; p++,cpa++){
+ float length=2.0;
+ cpa->parent=p;
+
+ /* create even spherical distribution inside unit sphere */
+ while(length>=1.0f){
+ cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
+ length=VecLength(cpa->fuv);
+ }
+
+ cpa->rand[0]=BLI_frand();
+ cpa->rand[1]=BLI_frand();
+ cpa->rand[2]=BLI_frand();
+
+ cpa->num=-1;
+ }
+ }
+
+ return 0;
+ }
+ }
+ else{
+ dm= CDDM_from_mesh((Mesh*)ob->data, ob);
+
+ /* special handling of grid distribution */
+ if(part->distr==PART_DISTR_GRID){
+ distribute_particles_in_grid(dm,psys);
+ dm->release(dm);
+ return 0;
+ }
+
+ /* we need orco for consistent distributions */
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
+
+ distr=part->distr;
+ pa=psys->particles;
+ if(from==PART_FROM_VERT){
+ MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
+ float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO);
+ int totvert = dm->getNumVerts(dm);
+
+ tree=BLI_kdtree_new(totvert);
+
+ for(p=0; p<totvert; p++){
+ if(orcodata) {
+ VECCOPY(co,orcodata[p])
+ transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
+ }
+ else
+ VECCOPY(co,mv[p].co)
+ BLI_kdtree_insert(tree,p,co,NULL);
+ }
+
+ BLI_kdtree_balance(tree);
+ }
+ }
+
+ /* 1. */
+ switch(from){
+ case PART_FROM_VERT:
+ tot = dm->getNumVerts(dm);
+ break;
+ case PART_FROM_VOLUME:
+ case PART_FROM_FACE:
+ tot = dm->getNumFaces(dm);
+ break;
+ case PART_FROM_PARTICLE:
+ if(psys->target_ob)
+ tob=psys->target_ob;
+ else
+ tob=ob;
+
+ if((tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1))){
+ tpars=tpsys->particles;
+ tot=tpsys->totpart;
+ }
+ break;
+ }
+
+ if(tot==0){
+ no_distr=1;
+ if(children){
+ fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
+ for(p=0,cpa=psys->child; p<totpart; p++,cpa++){
+ cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
+ cpa->foffset= 0.0f;
+ cpa->parent=0;
+ cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
+ cpa->num= -1;
+ }
+ }
+ else {
+ fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
+ pa->foffset= 0.0f;
+ pa->num= -1;
+ }
+ }
+
+ if(dm != finaldm) dm->release(dm);
+ return 0;
+ }
+
+ /* 2. */
+
+ weight=MEM_callocN(sizeof(float)*tot, "particle_distribution_weights");
+ index=MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
+ sum=MEM_callocN(sizeof(float)*(tot+1), "particle_distribution_sum");
+ jitoff=MEM_callocN(sizeof(float)*tot, "particle_distribution_jitoff");
+
+ /* 2.1 */
+ if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
+ MVert *v1, *v2, *v3, *v4;
+ float totarea=0.0, co1[3], co2[3], co3[3], co4[3];
+ float (*orcodata)[3];
+
+ orcodata= dm->getVertDataArray(dm, CD_ORCO);
+
+ for(i=0; i<tot; i++){
+ MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
+
+ if(orcodata) {
+ VECCOPY(co1, orcodata[mf->v1]);
+ VECCOPY(co2, orcodata[mf->v2]);
+ VECCOPY(co3, orcodata[mf->v3]);
+ transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
+ transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
+ transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
+ }
+ else {
+ v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
+ v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
+ v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
+ VECCOPY(co1, v1->co);
+ VECCOPY(co2, v2->co);
+ VECCOPY(co3, v3->co);
+ }
+
+ if (mf->v4){
+ if(orcodata) {
+ VECCOPY(co4, orcodata[mf->v4]);
+ transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
+ }
+ else {
+ v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
+ VECCOPY(co4, v4->co);
+ }
+ cur= AreaQ3Dfl(co1, co2, co3, co4);
+ }
+ else
+ cur= AreaT3Dfl(co1, co2, co3);
+
+ if(cur>maxweight)
+ maxweight=cur;
+
+ weight[i]= cur;
+ totarea+=cur;
+ }
+
+ for(i=0; i<tot; i++)
+ weight[i] /= totarea;
+
+ maxweight /= totarea;
+ }
+ else if(from==PART_FROM_PARTICLE){
+ float val=(float)tot/(float)totpart;
+ for(i=0; i<tot; i++)
+ weight[i]=val;
+ maxweight=val;
+ }
+ else{
+ float min=1.0f/(float)(MIN2(tot,totpart));
+ for(i=0; i<tot; i++)
+ weight[i]=min;
+ maxweight=min;
+ }
+
+ /* 2.2 */
+ if(ELEM3(from,PART_FROM_VERT,PART_FROM_FACE,PART_FROM_VOLUME)){
+ float *vweight= psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
+
+ if(vweight){
+ if(from==PART_FROM_VERT) {
+ for(i=0;i<tot; i++)
+ weight[i]*=vweight[i];
+ }
+ else { /* PART_FROM_FACE / PART_FROM_VOLUME */
+ for(i=0;i<tot; i++){
+ MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
+ tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
+
+ if(mf->v4) {
+ tweight += vweight[mf->v4];
+ tweight /= 4.0;
+ }
+ else {
+ tweight /= 3.0;
+ }
+
+ weight[i]*=tweight;
+ }
+ }
+ MEM_freeN(vweight);
+ }
+ }
+
+ /* 3. */
+ totweight= 0.0f;
+ for(i=0;i<tot; i++)
+ totweight += weight[i];
+
+ if(totweight > 0.0f)
+ totweight= 1.0f/totweight;
+
+ sum[0]= 0.0f;
+ for(i=0;i<tot; i++)
+ sum[i+1]= sum[i]+weight[i]*totweight;
+
+ if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
+ float pos;
+
+ for(p=0; p<totpart; p++) {
+ pos= BLI_frand();
+ index[p]= binary_search_distribution(sum, tot, pos);
+ index[p]= MIN2(tot-1, index[p]);
+ jitoff[index[p]]= pos;
+ }
+ }
+ else {
+ double step, pos;
+
+ step= (totpart <= 1)? 0.5: 1.0/(totpart-1);
+ pos= 1e-16f; /* tiny offset to avoid zero weight face */
+ i= 0;
+
+ for(p=0; p<totpart; p++, pos+=step) {
+ while((i < tot) && (pos > sum[i+1]))
+ i++;
+
+ index[p]= MIN2(tot-1, i);
+
+ /* avoid zero weight face */
+ if(p == totpart-1 && weight[index[p]] == 0.0f)
+ index[p]= index[p-1];
+
+ jitoff[index[p]]= pos;
+ }
+ }
+
+ MEM_freeN(sum);
+
+ /* for hair, sort by origindex, allows optimizations in rendering */
+ if(part->type == PART_HAIR) {
+ COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
+ if(COMPARE_ORIG_INDEX)
+ qsort(index, totpart, sizeof(int), compare_orig_index);
+ }
+
+ /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
+ if(from==PART_FROM_PARTICLE){
+ for(i=0; i<tot; i++)
+ weight[i]=0.0f;
+ }
+
+ /* 4. */
+ if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
+ jitlevel= part->userjit;
+
+ if(jitlevel == 0) {
+ 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");
+
+ /* for small amounts of particles we use regular jitter since it looks
+ * a bit better, for larger amounts we switch to hammersley sequence
+ * because it is much faster */
+ if(jitlevel < 25)
+ init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
+ else
+ hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
+ BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
+ }
+
+ /* 5. */
+ ctx->tree= tree;
+ ctx->seams= seams;
+ ctx->totseam= totseam;
+ ctx->psys= psys;
+ ctx->index= index;
+ ctx->jit= jit;
+ ctx->jitlevel= jitlevel;
+ ctx->jitoff= jitoff;
+ ctx->weight= weight;
+ ctx->maxweight= maxweight;
+ ctx->from= (children)? PART_FROM_CHILD: from;
+ ctx->cfrom= cfrom;
+ ctx->distr= distr;
+ ctx->dm= dm;
+ ctx->tpars= tpars;
+
+ if(children) {
+ totpart= psys_render_simplify_distribution(ctx, totpart);
+ alloc_child_particles(psys, totpart);
+ }
+
+ if(!children || psys->totchild < 10000)
+ totthread= 1;
+
+ seed= 31415926 + ctx->psys->seed;
+ for(i=0; i<totthread; i++) {
+ threads[i].rng= rng_new(seed);
+ threads[i].tot= totthread;
+ }
+
+ return 1;
+}
+
+static void distribute_particles_on_dm(DerivedMesh *finaldm, Object *ob, ParticleSystem *psys, int from)
+{
+ ListBase threads;
+ ParticleThread *pthreads;
+ ParticleThreadContext *ctx;
+ int i, totthread;
+
+ pthreads= psys_threads_create(ob, psys, G.scene->r.threads);
+
+ if(!psys_threads_init_distribution(pthreads, finaldm, from)) {
+ psys_threads_free(pthreads);
+ return;
+ }
+
+ totthread= pthreads[0].tot;
+ if(totthread > 1) {
+ BLI_init_threads(&threads, exec_distribution, totthread);
+
+ for(i=0; i<totthread; i++)
+ BLI_insert_thread(&threads, &pthreads[i]);
+
+ BLI_end_threads(&threads);
+ }
+ else
+ exec_distribution(&pthreads[0]);
+
+ psys_calc_dmcache(ob, finaldm, psys);
+
+ ctx= pthreads[0].ctx;
+ if(ctx->dm != finaldm)
+ ctx->dm->release(ctx->dm);
+
+ psys_threads_free(pthreads);
+}
+
+/* ready for future use, to emit particles without geometry */
+static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from)
+{
+ ParticleData *pa;
+ int totpart=psys->totpart, p;
+
+ fprintf(stderr,"Shape emission not yet possible!\n");
+
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
+ pa->foffset= 0.0f;
+ pa->num= -1;
+ }
+}
+static void distribute_particles(Object *ob, ParticleSystem *psys, int from)
+{
+ ParticleSystemModifierData *psmd=0;
+ int distr_error=0;
+ psmd=psys_get_modifier(ob,psys);
+
+ if(psmd){
+ if(psmd->dm)
+ distribute_particles_on_dm(psmd->dm,ob,psys,from);
+ else
+ distr_error=1;
+ }
+ else
+ distribute_particles_on_shape(ob,psys,from);
+
+ if(distr_error){
+ ParticleData *pa;
+ int totpart=psys->totpart, p;
+
+ fprintf(stderr,"Particle distribution error!\n");
+
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
+ pa->foffset= 0.0f;
+ pa->num= -1;
+ }
+ }
+}
+
+/* threaded child particle distribution and path caching */
+ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys, int totthread)
+{
+ ParticleThread *threads;
+ ParticleThreadContext *ctx;
+ int i;
+
+ threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
+ ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
+
+ 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);
+
+ memset(threads, 0, sizeof(ParticleThread)*totthread);
+
+ for(i=0; i<totthread; i++) {
+ threads[i].ctx= ctx;
+ threads[i].num= i;
+ threads[i].tot= totthread;
+ }
+
+ return threads;
+}
+
+void psys_threads_free(ParticleThread *threads)
+{
+ ParticleThreadContext *ctx= threads[0].ctx;
+ int i, totthread= threads[0].tot;
+
+ /* path caching */
+ if(ctx->vg_length)
+ MEM_freeN(ctx->vg_length);
+ if(ctx->vg_clump)
+ MEM_freeN(ctx->vg_clump);
+ if(ctx->vg_kink)
+ MEM_freeN(ctx->vg_kink);
+ if(ctx->vg_rough1)
+ MEM_freeN(ctx->vg_rough1);
+ if(ctx->vg_rough2)
+ MEM_freeN(ctx->vg_rough2);
+ if(ctx->vg_roughe)
+ MEM_freeN(ctx->vg_roughe);
+
+ if(ctx->psys->lattice){
+ end_latt_deform();
+ ctx->psys->lattice=0;
+ }
+
+ /* distribution */
+ if(ctx->jit) MEM_freeN(ctx->jit);
+ if(ctx->jitoff) MEM_freeN(ctx->jitoff);
+ if(ctx->weight) MEM_freeN(ctx->weight);
+ if(ctx->index) MEM_freeN(ctx->index);
+ if(ctx->skip) MEM_freeN(ctx->skip);
+ if(ctx->seams) MEM_freeN(ctx->seams);
+ //if(ctx->vertpart) MEM_freeN(ctx->vertpart);
+ BLI_kdtree_free(ctx->tree);
+
+ /* threads */
+ for(i=0; i<totthread; i++) {
+ if(threads[i].rng)
+ rng_free(threads[i].rng);
+ if(threads[i].rng_path)
+ rng_free(threads[i].rng_path);
+ }
+
+ MEM_freeN(ctx);
+ MEM_freeN(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)
+{
+ ParticleSettings *part;
+ ParticleTexture ptex;
+ Material *ma=0;
+ IpoCurve *icu=0;
+ int totpart;
+ float rand,length;
+
+ part=psys->part;
+
+ totpart=psys->totpart;
+
+ ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
+ ptex.time=(float)p/(float)totpart;
+
+ BLI_srandom(psys->seed+p);
+
+ if(part->from!=PART_FROM_PARTICLE){
+ ma=give_current_material(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);
+ }
+
+ 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=MAXFRAMEF;
+ else{
+ //icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
+ //if(icu){
+ // calc_icu(icu,100*ptex.time);
+ // ptex.time=icu->curval;
+ //}
+
+ pa->time= part->sta + (part->end - part->sta)*ptex.time;
+ }
+
+
+ if(part->type==PART_HAIR){
+ pa->lifetime=100.0f;
+ }
+ else{
+ icu=find_ipocurve(psys->part->ipo,PART_EMIT_LIFE);
+ if(icu){
+ calc_icu(icu,100*ptex.time);
+ pa->lifetime*=icu->curval;
+ }
+
+ /* need to get every rand even if we don't use them so that randoms don't affect eachother */
+ rand= BLI_frand();
+ if(part->randlife!=0.0)
+ pa->lifetime*= 1.0f - part->randlife*rand;
+ }
+
+ pa->dietime= pa->time+pa->lifetime;
+
+ pa->sizemul= BLI_frand();
+
+ rand= BLI_frand();
+
+ /* while loops are to have a spherical distribution (avoid cubic distribution) */
+ length=2.0f;
+ while(length>1.0){
+ pa->r_ve[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ve[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ve[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(pa->r_ve);
+ }
+
+ length=2.0f;
+ while(length>1.0){
+ pa->r_ave[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ave[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ave[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(pa->r_ave);
+ }
+
+ pa->r_rot[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[2]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[3]=2.0f*(BLI_frand()-0.5f);
+
+ NormalQuat(pa->r_rot);
+
+ if(part->distr!=PART_DISTR_GRID){
+ /* any unique random number will do (r_ave[0]) */
+ if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
+ pa->flag |= PARS_UNEXIST;
+ else
+ pa->flag &= ~PARS_UNEXIST;
+ }
+
+ pa->loop=0;
+ /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
+ /* 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)
+{
+ IpoCurve *icu=0;
+ ParticleData *pa;
+ int p, totpart=psys->totpart;
+
+ for(p=0, pa=psys->particles; p<totpart; p++, pa++)
+ initialize_particle(pa,p,ob,psys,psmd);
+
+ /* store the derived mesh face index for each particle */
+ icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
+ if(icu){
+ float time=psys->part->sta, end=psys->part->end;
+ float v1, v2, a=0.0f, t1,t2, d;
+
+ p=0;
+ pa=psys->particles;
+
+ calc_icu(icu,time);
+ v1=icu->curval;
+ if(v1<0.0f) v1=0.0f;
+
+ calc_icu(icu,time+1.0f);
+ v2=icu->curval;
+ if(v2<0.0f) v2=0.0f;
+
+ for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){
+ while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){
+ a+=0.5f*(v1+v2);
+ v1=v2;
+ time++;
+ calc_icu(icu,time+1.0f);
+ v2=icu->curval;
+ }
+ if(time<end){
+ if(v1==v2){
+ pa->time=time+((float)(p+1)-a)/v1;
+ }
+ else{
+ d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1)));
+ t1=(-v1+d)/(v2-v1);
+ t2=(-v1-d)/(v2-v1);
+
+ /* the root between 0-1 is the correct one */
+ if(t1>0.0f && t1<=1.0f)
+ pa->time=time+t1;
+ else
+ pa->time=time+t2;
+ }
+ }
+
+ pa->dietime = pa->time+pa->lifetime;
+ pa->flag &= ~PARS_UNEXIST;
+ }
+ for(; p<totpart; p++, pa++){
+ pa->flag |= PARS_UNEXIST;
+ }
+ }
+}
+/* sets particle to the emitter surface with initial velocity & rotation */
+void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
+ float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot)
+{
+ ParticleSettings *part;
+ ParticleTexture ptex;
+ ParticleKey state;
+ IpoCurve *icu=0;
+ 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 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];
+ part=psys->part;
+
+ ptex.ivel=1.0;
+
+ if(part->from==PART_FROM_PARTICLE){
+ Object *tob;
+ ParticleSystem *tpsys=0;
+ float speed;
+
+ tob=psys->target_ob;
+ if(tob==0)
+ tob=ob;
+
+ tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
+
+ /*TODO: get precise location of particle at birth*/
+
+ state.time=cfra;
+ psys_get_particle_state(tob,tpsys,pa->num,&state,1);
+ psys_get_from_key(&state,loc,nor,rot,0);
+
+ QuatMulVecf(rot,vtan);
+ QuatMulVecf(rot,utan);
+ VECCOPY(r_vel,pa->r_ve);
+ VECCOPY(r_rot,pa->r_rot);
+ VECCOPY(r_ave,pa->r_ave);
+
+ VECCOPY(p_vel,state.vel);
+ speed=Normalize(p_vel);
+ VecMulf(p_vel,Inpf(pa->r_ve,p_vel));
+ VECSUB(p_vel,pa->r_ve,p_vel);
+ Normalize(p_vel);
+ VecMulf(p_vel,speed);
+ }
+ 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(ob,pa->time);
+
+ /* get birth location from object */
+ psys_particle_on_emitter(ob,psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
+
+ /* save local coordinates for later */
+ VECCOPY(tloc,loc);
+
+ /* get possible textural influence */
+ psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
+
+ if(vg_vel){
+ ptex.ivel*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_vel);
+ }
+
+ /* particles live in global space so */
+ /* let's convert: */
+ /* -location */
+ Mat4MulVecfl(ob->obmat,loc);
+
+ /* -normal */
+ VECADD(nor,tloc,nor);
+ Mat4MulVecfl(ob->obmat,nor);
+ VECSUB(nor,nor,loc);
+ Normalize(nor);
+
+ /* -tangent */
+ if(part->tanfac!=0.0){
+ float phase=vg_rot?2.0f*(psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_rot)-0.5f):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);
+
+ VECCOPY(utan,nor);
+ VecMulf(utan,Inpf(vtan,nor));
+ VECSUB(vtan,vtan,utan);
+
+ Normalize(vtan);
+ }
+
+
+ /* -velocity */
+ if(part->randfac!=0.0){
+ VECADD(r_vel,tloc,pa->r_ve);
+ Mat4MulVecfl(ob->obmat,r_vel);
+ VECSUB(r_vel,r_vel,loc);
+ Normalize(r_vel);
+ }
+
+ /* -angular velocity */
+ if(part->avemode==PART_AVE_RAND){
+ VECADD(r_ave,tloc,pa->r_ave);
+ Mat4MulVecfl(ob->obmat,r_ave);
+ VECSUB(r_ave,r_ave,loc);
+ Normalize(r_ave);
+ }
+
+ /* -rotation */
+ if(part->randrotfac != 0.0f){
+ QUATCOPY(r_rot,pa->r_rot);
+ Mat4ToQuat(ob->obmat,rot);
+ QuatMul(r_rot,r_rot,rot);
+ }
+ }
+ /* conversion done so now we apply new: */
+ /* -velocity from: */
+ /* *emitter velocity */
+ if(dtime!=0.0 && part->obfac!=0.0){
+ VECSUB(vel,loc,pa->state.co);
+ VecMulf(vel,part->obfac/dtime);
+ }
+
+ /* *emitter normal */
+ if(part->normfac!=0.0)
+ VECADDFAC(vel,vel,nor,part->normfac);
+
+ /* *emitter tangent */
+ if(part->tanfac!=0.0)
+ VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_tan):1.0f));
+
+ /* *texture */
+ /* TODO */
+
+ /* *random */
+ if(part->randfac!=0.0)
+ VECADDFAC(vel,vel,r_vel,part->randfac);
+
+ /* *particle */
+ if(part->partfac!=0.0)
+ VECADDFAC(vel,vel,p_vel,part->partfac);
+
+ icu=find_ipocurve(psys->part->ipo,PART_EMIT_VEL);
+ if(icu){
+ calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
+ ptex.ivel*=icu->curval;
+ }
+
+ VecMulf(vel,ptex.ivel);
+
+ VECCOPY(pa->state.vel,vel);
+
+ /* -location from emitter */
+ VECCOPY(pa->state.co,loc);
+
+ /* -rotation */
+ pa->state.rot[0]=1.0;
+ pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0;
+
+ if(part->rotmode){
+ /* create vector into which rotation is aligned */
+ switch(part->rotmode){
+ case PART_ROT_NOR:
+ VecCopyf(rot_vec, nor);
+ break;
+ case PART_ROT_VEL:
+ VecCopyf(rot_vec, vel);
+ break;
+ case PART_ROT_GLOB_X:
+ case PART_ROT_GLOB_Y:
+ case PART_ROT_GLOB_Z:
+ rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
+ break;
+ case PART_ROT_OB_X:
+ case PART_ROT_OB_Y:
+ case PART_ROT_OB_Z:
+ VecCopyf(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
+ break;
+ }
+
+ /* create rotation quat */
+ VecMulf(rot_vec,-1.0);
+ vectoquat(rot_vec, OB_POSX, OB_POSZ, q2);
+
+ /* randomize rotation quat */
+ if(part->randrotfac!=0.0f)
+ QuatInterpol(rot, q2, r_rot, part->randrotfac);
+ else
+ QuatCopy(rot,q2);
+
+ /* rotation phase */
+ phasefac = part->phasefac;
+ if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */
+ phasefac += part->randphasefac * pa->r_ave[0];
+ VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase);
+
+ /* combine base rotation & phase */
+ QuatMul(pa->state.rot, rot, q_phase);
+ }
+
+ /* -angular velocity */
+
+ pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0;
+
+ if(part->avemode){
+ switch(part->avemode){
+ case PART_AVE_SPIN:
+ VECCOPY(pa->state.ave,vel);
+ break;
+ case PART_AVE_RAND:
+ VECCOPY(pa->state.ave,r_ave);
+ break;
+ }
+ Normalize(pa->state.ave);
+ VecMulf(pa->state.ave,part->avefac);
+
+ icu=find_ipocurve(psys->part->ipo,PART_EMIT_AVE);
+ if(icu){
+ calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
+ VecMulf(pa->state.ave,icu->curval);
+ }
+ }
+
+ pa->dietime = pa->time + pa->lifetime;
+
+ if(pa->time >= cfra)
+ pa->alive = PARS_UNBORN;
+
+ pa->state.time = cfra;
+
+ pa->stick_ob = 0;
+ pa->flag &= ~PARS_STICKY;
+}
+static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, 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);
+
+ for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
+ reset_particle(pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
+
+ if(vg_vel)
+ MEM_freeN(vg_vel);
+}
+/************************************************/
+/* Keyed particles */
+/************************************************/
+/* a bit of an unintuitive function :) counts objects in a keyed chain and returns 1 if some of them were selected (used in drawing) */
+int psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
+{
+ ParticleSystem *kpsys=psys,*tpsys;
+ ParticleSettings *tpart;
+ Object *kob=ob,*tob;
+ int select=ob->flag&SELECT;
+ short totkeyed=0;
+ Base *base;
+
+ ListBase lb;
+ lb.first=lb.last=0;
+
+ tob=psys->keyed_ob;
+ while(tob){
+ if((tpsys=BLI_findlink(&tob->particlesystem,kpsys->keyed_psys-1))){
+ tpart=tpsys->part;
+
+ if(tpart->phystype==PART_PHYS_KEYED){
+ if(lb.first){
+ for(base=lb.first;base;base=base->next){
+ if(tob==base->object){
+ fprintf(stderr,"Error: loop in keyed chain!\n");
+ BLI_freelistN(&lb);
+ return select;
+ }
+ }
+ }
+ base=MEM_callocN(sizeof(Base), "keyed base");
+ base->object=tob;
+ BLI_addtail(&lb,base);
+
+ if(tob->flag&SELECT)
+ select++;
+ kob=tob;
+ kpsys=tpsys;
+ tob=tpsys->keyed_ob;
+ totkeyed++;
+ }
+ else{
+ tob=0;
+ totkeyed++;
+ }
+ }
+ else
+ tob=0;
+ }
+ psys->totkeyed=totkeyed;
+ BLI_freelistN(&lb);
+ return select;
+}
+void set_keyed_keys(Object *ob, ParticleSystem *psys)
+{
+ Object *kob = ob;
+ ParticleSystem *kpsys = psys;
+ ParticleData *pa;
+ ParticleKey state;
+ int totpart = psys->totpart, i, k, totkeys = psys->totkeyed + 1;
+ float prevtime, nexttime, keyedtime;
+
+ /* no proper targets so let's clear and bail out */
+ if(psys->totkeyed==0){
+ free_keyed_keys(psys);
+ psys->flag &= ~PSYS_KEYED;
+ return;
+ }
+
+ if(totpart && psys->particles->totkey != totkeys){
+ free_keyed_keys(psys);
+
+ psys->particles->keys = MEM_callocN(psys->totpart * totkeys * sizeof(ParticleKey),"Keyed keys");
+
+ psys->particles->totkey = totkeys;
+
+ for(i=1, pa=psys->particles+1; i<totpart; i++,pa++){
+ pa->keys = (pa-1)->keys + totkeys;
+ pa->totkey = totkeys;
+ }
+ }
+
+ psys->flag &= ~PSYS_KEYED;
+ state.time=-1.0;
+
+ for(k=0; k<totkeys; k++){
+ for(i=0,pa=psys->particles; i<totpart; i++, pa++){
+ psys_get_particle_state(kob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
+
+ if(k==0)
+ pa->keys->time = pa->time;
+ else if(k==totkeys-1)
+ (pa->keys + k)->time = pa->time + pa->lifetime;
+ else{
+ if(psys->flag & PSYS_KEYED_TIME){
+ prevtime = (pa->keys + k - 1)->time;
+ nexttime = pa->time + pa->lifetime;
+ keyedtime = kpsys->part->keyed_time;
+ (pa->keys + k)->time = (1.0f - keyedtime) * prevtime + keyedtime * nexttime;
+ }
+ else
+ (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
+ }
+ }
+ if(kpsys->keyed_ob){
+ kob = kpsys->keyed_ob;
+ kpsys = BLI_findlink(&kob->particlesystem, kpsys->keyed_psys - 1);
+ }
+ }
+
+ psys->flag |= PSYS_KEYED;
+}
+/************************************************/
+/* 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){
+ 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->alive=PARS_ALIVE;
+ pa->time=pa_time;
+ pa->dietime=pa->time+pa->lifetime;
+ }
+ }
+ else{
+ if(pa->alive==PARS_UNBORN){
+ pa->alive=PARS_ALIVE;
+ 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->alive=PARS_ALIVE;
+ 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;
+}
+/************************************************/
+/* Point Cache */
+/************************************************/
+void clear_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
+{
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
+
+ BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_ALL, cfra, stack_index);
+}
+static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
+{
+ FILE *fp = NULL;
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ ParticleData *pa;
+ int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
+ int i, totpart = psys->totpart;
+
+ if(totpart == 0) return;
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'w', cfra, stack_index);
+ if(!fp) return;
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++)
+ fwrite(&pa->state, sizeof(ParticleKey), 1, fp);
+
+ fclose(fp);
+}
+static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
+{
+ FILE *fp = NULL;
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ ParticleData *pa;
+ int stack_index = modifiers_indexInObject(ob,(ModifierData*)psmd);
+ int i, totpart = psys->totpart, ret = 1;
+
+ if(totpart == 0) return 0;
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'r', cfra, stack_index);
+ if(!fp)
+ ret = 0;
+ else {
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++)
+ if((fread(&pa->state, sizeof(ParticleKey), 1, fp)) != 1) {
+ ret = 0;
+ break;
+ }
+
+ fclose(fp);
+ }
+
+ return ret;
+}
+/************************************************/
+/* Effectors */
+/************************************************/
+static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
+{
+ if(!usemin)
+ mindist= 0.0f;
+
+ if(fac < mindist) {
+ return 1.0f;
+ }
+ else if(usemax) {
+ if(fac>maxdist || (maxdist-mindist)<=0.0f)
+ return 0.0f;
+
+ fac= (fac-mindist)/(maxdist-mindist);
+ return 1.0f - (float)pow((double)fac, (double)power);
+ }
+ else
+ return pow((double)1.0f+fac-mindist, (double)-power);
+}
+
+static float falloff_func_dist(PartDeflect *pd, float fac)
+{
+ return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
+}
+
+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);
+}
+
+static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
+{
+ float eff_dir[3], temp[3];
+ float falloff=1.0, fac, r_fac;
+
+ VecCopyf(eff_dir,eff_velocity);
+ Normalize(eff_dir);
+
+ if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
+ falloff=0.0f;
+ else switch(pd->falloff){
+ case PFIELD_FALL_SPHERE:
+ fac=VecLength(vec_to_part);
+ falloff= falloff_func_dist(pd, fac);
+ break;
+
+ case PFIELD_FALL_TUBE:
+ fac=Inpf(vec_to_part,eff_dir);
+ falloff= falloff_func_dist(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);
+ break;
+ case PFIELD_FALL_CONE:
+ fac=Inpf(vec_to_part,eff_dir);
+ falloff= falloff_func_dist(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);
+
+ break;
+// case PFIELD_FALL_INSIDE:
+ //for(i=0; i<totface; i++,mface++){
+ // VECCOPY(v1,mvert[mface->v1].co);
+ // VECCOPY(v2,mvert[mface->v2].co);
+ // VECCOPY(v3,mvert[mface->v3].co);
+
+ // if(AxialLineIntersectsTriangle(a,co1, co2, v2, v3, v1, &lambda)){
+ // if(from==PART_FROM_FACE)
+ // (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ // else /* store number of intersections */
+ // (pa+(int)(lambda*size[a])*a0mul)->loop++;
+ // }
+ //
+ // if(mface->v4){
+ // VECCOPY(v4,mvert[mface->v4].co);
+
+ // if(AxialLineIntersectsTriangle(a,co1, co2, v4, v1, v3, &lambda)){
+ // if(from==PART_FROM_FACE)
+ // (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ // else
+ // (pa+(int)(lambda*size[a])*a0mul)->loop++;
+ // }
+ // }
+ //}
+
+// break;
+ }
+
+ return falloff;
+}
+static void do_physical_effector(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)
+{
+ float mag_vec[3]={0,0,0};
+ float temp[3], temp2[3];
+ float eff_vel[3];
+
+ VecCopyf(eff_vel,eff_velocity);
+ Normalize(eff_vel);
+
+ switch(type){
+ case PFIELD_WIND:
+ VECCOPY(mag_vec,eff_vel);
+
+ VecMulf(mag_vec,force_val*falloff);
+ VecAddf(field,field,mag_vec);
+ break;
+
+ case PFIELD_FORCE:
+ if(planar)
+ Projf(mag_vec,vec_to_part,eff_vel);
+ else
+ VecCopyf(mag_vec,vec_to_part);
+
+ VecMulf(mag_vec,force_val*falloff);
+ VecAddf(field,field,mag_vec);
+ break;
+
+ case PFIELD_VORTEX:
+ Crossf(mag_vec,eff_vel,vec_to_part);
+ Normalize(mag_vec);
+
+ VecMulf(mag_vec,force_val*distance*falloff);
+ VecAddf(field,field,mag_vec);
+
+ break;
+ case PFIELD_MAGNET:
+ if(planar)
+ VecCopyf(temp,eff_vel);
+ else
+ /* magnetic field of a moving charge */
+ Crossf(temp,eff_vel,vec_to_part);
+
+ Crossf(temp2,velocity,temp);
+ VecAddf(mag_vec,mag_vec,temp2);
+
+ 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);
+
+ VecMulf(mag_vec,force_val*falloff);
+ VecSubf(field,field,mag_vec);
+
+ VecCopyf(mag_vec,velocity);
+ /* 1.9 is an experimental value to get critical damping at damp=1.0 */
+ VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
+ VecSubf(field,field,mag_vec);
+ break;
+ case PFIELD_NUCLEAR:
+ /*pow here is root of cosine expression below*/
+ //rad=(float)pow(2.0,-1.0/power)*distance/size;
+ //VECCOPY(mag_vec,vec_to_part);
+ //Normalize(mag_vec);
+ //VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
+ //VECADDFAC(field,field,mag_vec,force_val);
+ break;
+ }
+}
+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, 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(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;
+ 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++){
+ type=0;
+ if(epsys!=psys){
+ epart=epsys->part;
+
+ if(epsys->part->pd && epsys->part->pd->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;
+ BLI_addtail(lb, ec);
+ }
+ }
+ }
+
+ }
+}
+
+static void psys_init_effectors_recurs(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, ob, obsrc, psys);
+
+ if(ob->dup_group) {
+ group= ob->dup_group;
+ for(go= group->gobject.first; go; go= go->next)
+ psys_init_effectors_recurs(go->ob, obsrc, psys, listb, level+1);
+ }
+ }
+}
+
+void psys_init_effectors(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(go->ob, obsrc, psys, listb, 0);
+ }
+ else {
+ for(base = G.scene->base.first; base; base= base->next)
+ psys_init_effectors_recurs(base->object, obsrc, psys, listb, 0);
+ }
+}
+
+void psys_end_effectors(ParticleSystem *psys)
+{
+ ListBase *lb=&psys->effectors;
+ if(lb->first) {
+ ParticleEffectorCache *ec;
+ for(ec= lb->first; 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);
+ }
+
+ BLI_freelistN(lb);
+ }
+}
+
+static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
+{
+ ListBase *lb=&psys->effectors;
+ ParticleEffectorCache *ec;
+ ParticleSettings *part=psys->part;
+ ParticleData *pa;
+ float vec2[3],loc[3],*co=0;
+ int p,totpart,totvert;
+
+ for(ec= lb->first; ec; ec= ec->next) {
+ PartDeflect *pd= ec->ob->pd;
+
+ 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);
+
+ Mat4MulVecfl(ec->ob->obmat,vec);
+ Mat4Mul3Vecfl(ec->ob->obmat,vec2);
+
+ QUATCOPY(ec->firstloc,vec);
+ VECCOPY(ec->firstdir,vec2);
+
+ totpart=psys->totpart;
+
+ if(totpart){
+ ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
+ ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
+
+ for(p=0,pa=psys->particles; p<totpart; p++, pa++){
+ psys_particle_on_emitter(ob,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_DEFLECT){
+ DerivedMesh *dm;
+ MFace *mface=0;
+ MVert *mvert=0;
+ int i, totface;
+ float v1[3],v2[3],v3[3],v4[4], *min, *max;
+
+ if(ob==ec->ob)
+ dm=psmd->dm;
+ else{
+ psys_disable_all(ec->ob);
+
+ dm=mesh_get_derived_final(ec->ob,0);
+
+ psys_enable_all(ec->ob);
+ }
+
+ if(dm){
+ totvert=dm->getNumVerts(dm);
+ totface=dm->getNumFaces(dm);
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+ /* Decide which is faster to calculate by the amount of*/
+ /* matrice multiplications needed to convert spaces. */
+ /* With size deflect we have to convert allways because */
+ /* the object can be scaled nonuniformly (sphere->ellipsoid). */
+ if(totvert<2*psys->totpart || part->flag & PART_SIZE_DEFL){
+ co=ec->vert_cos=MEM_callocN(sizeof(float)*3*totvert,"Particle deflection vert cos");
+ /* convert vert coordinates to global (particle) coordinates */
+ for(i=0; i<totvert; i++, co+=3){
+ VECCOPY(co,mvert[i].co);
+ Mat4MulVecfl(ec->ob->obmat,co);
+ }
+ co=ec->vert_cos;
+ }
+ else
+ ec->vert_cos=0;
+
+ INIT_MINMAX(ec->ob_minmax,ec->ob_minmax+3);
+
+ min=ec->face_minmax=MEM_callocN(sizeof(float)*6*totface,"Particle deflection face minmax");
+ max=min+3;
+
+ for(i=0; i<totface; i++,mface++,min+=6,max+=6){
+ if(co){
+ VECCOPY(v1,co+3*mface->v1);
+ VECCOPY(v2,co+3*mface->v2);
+ VECCOPY(v3,co+3*mface->v3);
+ }
+ else{
+ VECCOPY(v1,mvert[mface->v1].co);
+ VECCOPY(v2,mvert[mface->v2].co);
+ VECCOPY(v3,mvert[mface->v3].co);
+ }
+ INIT_MINMAX(min,max);
+ DO_MINMAX(v1,min,max);
+ DO_MINMAX(v2,min,max);
+ DO_MINMAX(v3,min,max);
+
+ if(mface->v4){
+ if(co){
+ VECCOPY(v4,co+3*mface->v4);
+ }
+ else{
+ VECCOPY(v4,mvert[mface->v4].co);
+ }
+ DO_MINMAX(v4,min,max);
+ }
+
+ DO_MINMAX(min,ec->ob_minmax,ec->ob_minmax+3);
+ DO_MINMAX(max,ec->ob_minmax,ec->ob_minmax+3);
+ }
+ }
+ else
+ ec->face_minmax=0;
+ }
+ else if(ec->type==PSYS_EC_PARTICLE){
+ if(psys->part->phystype==PART_PHYS_BOIDS){
+ Object *eob = ec->ob;
+ ParticleSystem *epsys;
+ ParticleSettings *epart;
+ ParticleData *epa;
+ ParticleKey state;
+ PartDeflect *pd;
+ int totepart, p;
+ epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
+ epart= epsys->part;
+ pd= epart->pd;
+ totepart= epsys->totpart;
+ 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(eob,epsys,p,&state,0))
+ BLI_kdtree_insert(tree, p, state.co, NULL);
+
+ BLI_kdtree_balance(tree);
+ }
+ }
+ }
+ }
+}
+
+
+/* calculate forces that all effectors apply to a particle*/
+void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, 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];
+ float falloff;
+ int p;
+
+ /* check all effector objects for interaction */
+ if(lb->first){
+ 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(eob,cfra);
+ /* Get IPO force strength and fall off values here */
+ //if (has_ipo_code(eob->ipo, OB_PD_FSTR))
+ // force_val = IPO_GetFloatValue(eob->ipo, OB_PD_FSTR, cfra);
+ //else
+ // force_val = pd->f_strength;
+
+ //if (has_ipo_code(eob->ipo, OB_PD_FFALL))
+ // ffall_val = IPO_GetFloatValue(eob->ipo, OB_PD_FFALL, cfra);
+ //else
+ // ffall_val = pd->f_power;
+
+ //if (has_ipo_code(eob->ipo, OB_PD_FMAXD))
+ // maxdist = IPO_GetFloatValue(eob->ipo, OB_PD_FMAXD, cfra);
+ //else
+ // maxdist = pd->maxdist;
+
+ /* use center of object for distance calculus */
+ //obloc= eob->obmat[3];
+ VecSubf(vec_to_part, state->co, eob->obmat[3]);
+ distance = VecLength(vec_to_part);
+
+ falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
+
+ 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,
+ pd->f_strength, falloff, force_field);
+ } else {
+ do_physical_effector(pd->forcefield,pd->f_strength,distance,
+ falloff,pd->f_dist,pd->f_damp,eob->obmat[2],vec_to_part,
+ pa->state.vel,force_field,pd->flag&PFIELD_PLANAR);
+ }
+ }
+ if(ec->type & PSYS_EC_PARTICLE){
+ int totepart;
+ epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
+ epart= epsys->part;
+ pd= epart->pd;
+ totepart= epsys->totpart;
+
+ if(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(ob,psys);
+
+ for(; p<totepart; p++){
+ epa = epsys->particles + p;
+ estate.time=-1.0;
+ if(psys_get_particle_state(eob,epsys,p,&estate,0)){
+ VECSUB(vec_to_part, state->co, estate.co);
+ distance = VecLength(vec_to_part);
+
+ //if(pd->forcefield==PFIELD_HARMONIC){
+ // //if(cfra < epa->time + radius){ /* radius is fade-in in ui */
+ // // eforce*=(cfra-epa->time)/radius;
+ // //}
+ //}
+ //else{
+ // /* Limit minimum distance to effector particle so that */
+ // /* the force is not too big */
+ // if (distance < 0.001) distance = 0.001f;
+ //}
+
+ falloff=effector_falloff(pd,estate.vel,vec_to_part);
+
+ if(falloff<=0.0f)
+ ; /* don't do anything */
+ else
+ do_physical_effector(pd->forcefield,pd->f_strength,distance,
+ falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
+ state->vel,force_field,0);
+ }
+ else if(pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
+ /* first step after key release */
+ psys_get_particle_state(eob,epsys,p,&estate,1);
+ VECADD(vel,vel,estate.vel);
+ /* TODO: add rotation handling here too */
+ }
+ }
+
+ if(epsys->lattice){
+ end_latt_deform();
+ epsys->lattice=0;
+ }
+ }
+ }
+ }
+}
+
+/************************************************/
+/* Newtonian physics */
+/************************************************/
+/* gathers all forces that effect particles and calculates a new state for the particle */
+static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra, ParticleKey *state)
+{
+ 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;
+ int i, steps=1;
+
+ /* maintain angular velocity */
+ VECCOPY(state->ave,pa->state.ave);
+
+ if(part->flag & PART_SIZEMASS)
+ pa_mass*=pa->size;
+
+ switch(part->integrator){
+ case PART_INT_EULER:
+ steps=1;
+ break;
+ case PART_INT_MIDPOINT:
+ steps=2;
+ break;
+ case PART_INT_RK4:
+ steps=4;
+ break;
+ }
+
+ copy_particle_key(states,&pa->state,1);
+
+ for(i=0; i<steps; i++){
+ force[0]=force[1]=force[2]=0.0;
+ tvel[0]=tvel[1]=tvel[2]=0.0;
+ /* add effectors */
+ if(part->type != PART_HAIR)
+ do_effectors(pa_no,pa,states+i,ob,psys,states->co,force,tvel,dfra,fra);
+
+ /* calculate air-particle interaction */
+ if(part->dragfac!=0.0f){
+ fac=-part->dragfac*pa->size*pa->size*VecLength(states[i].vel);
+ VECADDFAC(force,force,states[i].vel,fac);
+ }
+
+ /* brownian force */
+ if(part->brownfac!=0.0){
+ force[0]+=(BLI_frand()-0.5f)*part->brownfac;
+ force[1]+=(BLI_frand()-0.5f)*part->brownfac;
+ force[2]+=(BLI_frand()-0.5f)*part->brownfac;
+ }
+
+ /* force to acceleration*/
+ VecMulf(force,1.0f/pa_mass);
+
+ /* add global acceleration (gravitation) */
+ VECADD(force,force,part->acc);
+
+ /* calculate next state */
+ VECADD(states[i].vel,states[i].vel,tvel);
+
+ switch(part->integrator){
+ case PART_INT_EULER:
+ VECADDFAC(state->co,states->co,states->vel,dtime);
+ VECADDFAC(state->vel,states->vel,force,dtime);
+ break;
+ case PART_INT_MIDPOINT:
+ 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;
+ }
+ else{
+ VECADDFAC(state->co,states->co,states[1].vel,dtime);
+ VECADDFAC(state->vel,states->vel,force,dtime);
+ }
+ break;
+ case PART_INT_RK4:
+ switch(i){
+ case 0:
+ VECCOPY(dx[0],states->vel);
+ VecMulf(dx[0],dtime);
+ VECCOPY(dv[0],force);
+ VecMulf(dv[0],dtime);
+
+ 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;
+ break;
+ case 1:
+ VECADDFAC(dx[1],states->vel,dv[0],0.5f);
+ VecMulf(dx[1],dtime);
+ VECCOPY(dv[1],force);
+ VecMulf(dv[1],dtime);
+
+ VECADDFAC(states[2].co,states->co,dx[1],0.5f);
+ VECADDFAC(states[2].vel,states->vel,dv[1],0.5f);
+ break;
+ case 2:
+ VECADDFAC(dx[2],states->vel,dv[1],0.5f);
+ VecMulf(dx[2],dtime);
+ VECCOPY(dv[2],force);
+ VecMulf(dv[2],dtime);
+
+ VECADD(states[3].co,states->co,dx[2]);
+ VECADD(states[3].vel,states->vel,dv[2]);
+ fra=cfra;
+ break;
+ case 3:
+ VECADD(dx[3],states->vel,dv[2]);
+ VecMulf(dx[3],dtime);
+ VECCOPY(dv[3],force);
+ VecMulf(dv[3],dtime);
+
+ VECADDFAC(state->co,states->co,dx[0],1.0f/6.0f);
+ VECADDFAC(state->co,state->co,dx[1],1.0f/3.0f);
+ VECADDFAC(state->co,state->co,dx[2],1.0f/3.0f);
+ VECADDFAC(state->co,state->co,dx[3],1.0f/6.0f);
+
+ VECADDFAC(state->vel,states->vel,dv[0],1.0f/6.0f);
+ VECADDFAC(state->vel,state->vel,dv[1],1.0f/3.0f);
+ VECADDFAC(state->vel,state->vel,dv[2],1.0f/3.0f);
+ VECADDFAC(state->vel,state->vel,dv[3],1.0f/6.0f);
+ }
+ break;
+ }
+ }
+
+ /* damp affects final velocity */
+ if(part->dampfac!=0.0)
+ VecMulf(state->vel,1.0f-part->dampfac);
+
+ /* finally we do guides */
+ time=(cfra-pa->time)/pa->lifetime;
+ CLAMP(time,0.0,1.0);
+
+ VECCOPY(tkey.co,state->co);
+ VECCOPY(tkey.vel,state->vel);
+ tkey.time=state->time;
+
+ if(part->type != PART_HAIR) {
+ if(do_guide(&tkey,pa_no,time,&psys->effectors)) {
+ VECCOPY(state->co,tkey.co);
+ /* guides don't produce valid velocity */
+ VECSUB(state->vel,tkey.co,pa->state.co);
+ VecMulf(state->vel,1.0f/dtime);
+ state->time=tkey.time;
+ }
+ }
+}
+static void rotate_particle(ParticleSettings *part, ParticleData *pa, float dfra, float timestep, ParticleKey *state)
+{
+ float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
+
+ if((part->flag & PART_ROT_DYN)==0){
+ if(part->avemode==PART_AVE_SPIN){
+ float angle;
+ float len1 = VecLength(pa->state.vel);
+ float len2 = VecLength(state->vel);
+
+ if(len1==0.0f || len2==0.0f)
+ state->ave[0]=state->ave[1]=state->ave[2]=0.0f;
+ else{
+ Crossf(state->ave,pa->state.vel,state->vel);
+ Normalize(state->ave);
+ angle=Inpf(pa->state.vel,state->vel)/(len1*len2);
+ VecMulf(state->ave,saacos(angle)/dtime);
+ }
+
+ VecRotToQuat(state->vel,dtime*part->avefac,rot2);
+ }
+ }
+
+ rotfac=VecLength(state->ave);
+ if(rotfac==0.0){ /* QuatOne (in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
+ rot1[0]=1.0;
+ rot1[1]=rot1[2]=rot1[3]=0;
+ }
+ else{
+ VecRotToQuat(state->ave,rotfac*dtime,rot1);
+ }
+ QuatMul(state->rot,rot1,pa->state.rot);
+ QuatMul(state->rot,rot2,state->rot);
+
+ /* keep rotation quat in good health */
+ NormalQuat(state->rot);
+}
+
+/* convert from triangle barycentric weights to quad mean value weights */
+static void intersect_dm_quad_weights(float *v1, float *v2, float *v3, float *v4, float *w)
+{
+ float co[3], vert[4][3];
+
+ VECCOPY(vert[0], v1);
+ VECCOPY(vert[1], v2);
+ VECCOPY(vert[2], v3);
+ VECCOPY(vert[3], v4);
+
+ co[0]= v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3];
+ co[1]= v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3];
+ co[2]= v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3];
+
+ MeanValueWeights(vert, 4, co, w);
+}
+
+/* check intersection with a derivedmesh */
+int psys_intersect_dm(Object *ob, DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_w,
+ float *face_minmax, float *pa_minmax, float radius, float *ipoint)
+{
+ MFace *mface=0;
+ MVert *mvert=0;
+ int i, totface, intersect=0;
+ float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3],p_max[3];
+ float cur_ipoint[3];
+
+ if(dm==0){
+ psys_disable_all(ob);
+
+ dm=mesh_get_derived_final(ob,0);
+ if(dm==0)
+ mesh_get_derived_deform(ob,0);
+
+ psys_enable_all(ob);
+
+ if(dm==0)
+ return 0;
+ }
+
+
+
+ if(pa_minmax==0){
+ INIT_MINMAX(p_min,p_max);
+ DO_MINMAX(co1,p_min,p_max);
+ DO_MINMAX(co2,p_min,p_max);
+ }
+ else{
+ VECCOPY(p_min,pa_minmax);
+ VECCOPY(p_max,pa_minmax+3);
+ }
+
+ totface=dm->getNumFaces(dm);
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+ /* lets intersect the faces */
+ for(i=0; i<totface; i++,mface++){
+ if(vert_cos){
+ VECCOPY(v1,vert_cos+3*mface->v1);
+ VECCOPY(v2,vert_cos+3*mface->v2);
+ VECCOPY(v3,vert_cos+3*mface->v3);
+ if(mface->v4)
+ VECCOPY(v4,vert_cos+3*mface->v4)
+ }
+ else{
+ VECCOPY(v1,mvert[mface->v1].co);
+ VECCOPY(v2,mvert[mface->v2].co);
+ VECCOPY(v3,mvert[mface->v3].co);
+ if(mface->v4)
+ VECCOPY(v4,mvert[mface->v4].co)
+ }
+
+ if(face_minmax==0){
+ INIT_MINMAX(min,max);
+ DO_MINMAX(v1,min,max);
+ DO_MINMAX(v2,min,max);
+ DO_MINMAX(v3,min,max);
+ if(mface->v4)
+ DO_MINMAX(v4,min,max)
+ if(AabbIntersectAabb(min,max,p_min,p_max)==0)
+ continue;
+ }
+ else{
+ VECCOPY(min, face_minmax+6*i);
+ VECCOPY(max, face_minmax+6*i+3);
+ if(AabbIntersectAabb(min,max,p_min,p_max)==0)
+ continue;
+ }
+
+ if(radius>0.0f){
+ if(SweepingSphereIntersectsTriangleUV(co1, co2, radius, v2, v3, v1, &cur_d, cur_ipoint)){
+ if(cur_d<*min_d){
+ *min_d=cur_d;
+ VECCOPY(ipoint,cur_ipoint);
+ *min_face=i;
+ intersect=1;
+ }
+ }
+ if(mface->v4){
+ if(SweepingSphereIntersectsTriangleUV(co1, co2, radius, v4, v1, v3, &cur_d, cur_ipoint)){
+ if(cur_d<*min_d){
+ *min_d=cur_d;
+ VECCOPY(ipoint,cur_ipoint);
+ *min_face=i;
+ intersect=1;
+ }
+ }
+ }
+ }
+ else{
+ if(LineIntersectsTriangle(co1, co2, v1, v2, v3, &cur_d, cur_uv)){
+ if(cur_d<*min_d){
+ *min_d=cur_d;
+ min_w[0]= 1.0 - cur_uv[0] - cur_uv[1];
+ min_w[1]= cur_uv[0];
+ min_w[2]= cur_uv[1];
+ min_w[3]= 0.0f;
+ if(mface->v4)
+ intersect_dm_quad_weights(v1, v2, v3, v4, min_w);
+ *min_face=i;
+ intersect=1;
+ }
+ }
+ if(mface->v4){
+ if(LineIntersectsTriangle(co1, co2, v1, v3, v4, &cur_d, cur_uv)){
+ if(cur_d<*min_d){
+ *min_d=cur_d;
+ min_w[0]= 1.0 - cur_uv[0] - cur_uv[1];
+ min_w[1]= 0.0f;
+ min_w[2]= cur_uv[0];
+ min_w[3]= cur_uv[1];
+ intersect_dm_quad_weights(v1, v2, v3, v4, min_w);
+ *min_face=i;
+ intersect=1;
+ }
+ }
+ }
+ }
+ }
+ return intersect;
+}
+/* particle - mesh collision code */
+/* in addition to basic point to surface collisions handles friction & damping,*/
+/* 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(Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float dfra, float cfra, ParticleKey *state, int *pa_die){
+ Object *ob, *min_ob;
+ MFace *mface;
+ MVert *mvert;
+ DerivedMesh *dm;
+ ListBase *lb=&psys->effectors;
+ ParticleEffectorCache *ec;
+ ParticleKey cstate;
+ float imat[4][4];
+ float co1[3],co2[3],def_loc[3],def_nor[3],unit_nor[3],def_tan[3],dvec[3],def_vel[3],dave[3],dvel[3];
+ float t_co1[3]={0.0,0.0,0.0},t_co2[3]={0.0,0.0,0.0};
+ float pa_minmax[6];
+ float min_w[4], zerovec[3]={0.0,0.0,0.0}, ipoint[3];
+ float min_d,dotprod,damp,frict,o_len,d_len,radius=-1.0f;
+ int min_face=0, intersect=1, through=0;
+ short deflections=0, global=0;
+
+ VECCOPY(def_loc,pa->state.co);
+ VECCOPY(def_vel,pa->state.vel);
+
+ /* 10 iterations to catch multiple deflections */
+ if(lb->first) while(deflections<10){
+ intersect=0;
+ global=0;
+ min_d=20000.0;
+ min_ob=NULL;
+ /* 1. */
+ for(ec=lb->first; ec; ec=ec->next){
+ if(ec->type & PSYS_EC_DEFLECT){
+ ob= ec->ob;
+
+ if(part->type!=PART_HAIR)
+ where_is_object_time(ob,cfra);
+
+ if(ob==pob){
+ dm=psmd->dm;
+ /* particles should not collide with emitter at birth */
+ if(pa->time < cfra && pa->time >= psys->cfra)
+ continue;
+ }
+ else
+ dm=0;
+
+ VECCOPY(co1,def_loc);
+ VECCOPY(co2,state->co);
+
+ if(ec->vert_cos==0){
+ /* convert particle coordinates to object coordinates */
+ Mat4Invert(imat,ob->obmat);
+
+ VECCOPY(t_co1,co1);
+ VECCOPY(t_co2,co2);
+ Mat4MulVecfl(imat,co1);
+ Mat4MulVecfl(imat,co2);
+ }
+
+ INIT_MINMAX(pa_minmax,pa_minmax+3);
+ DO_MINMAX(co1,pa_minmax,pa_minmax+3);
+ DO_MINMAX(co2,pa_minmax,pa_minmax+3);
+ if(part->flag&PART_SIZE_DEFL){
+ pa_minmax[0]-=pa->size;
+ pa_minmax[1]-=pa->size;
+ pa_minmax[2]-=pa->size;
+ pa_minmax[3]+=pa->size;
+ pa_minmax[4]+=pa->size;
+ pa_minmax[5]+=pa->size;
+
+ radius=pa->size;
+ }
+
+ if(ec->face_minmax==0 || AabbIntersectAabb(pa_minmax,pa_minmax+3,ec->ob_minmax,ec->ob_minmax+3))
+ if(psys_intersect_dm(ob,dm,ec->vert_cos,co1,co2,&min_d,&min_face,min_w,
+ ec->face_minmax,pa_minmax,radius,ipoint)){
+ min_ob=ob;
+ if(ec->vert_cos)
+ global=1;
+ else
+ global=0;
+ }
+
+ if(ec->vert_cos==0){
+ /* get global coordinates back */
+ VECCOPY(co1,t_co1);
+ VECCOPY(co2,t_co2);
+ }
+ }
+ }
+
+ /* 2. */
+ if(min_ob){
+ BLI_srandom((int)cfra+p);
+ ob=min_ob;
+
+ if(ob==pob){
+ dm=psmd->dm;
+ }
+ else{
+ psys_disable_all(ob);
+
+ dm=mesh_get_derived_final(ob,0);
+
+ psys_enable_all(ob);
+ }
+
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+ mface+=min_face;
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+
+ /* permeability check */
+ if(BLI_frand()<ob->pd->pdef_perm)
+ through=1;
+ else
+ through=0;
+
+ if(through==0 && (part->flag & PART_DIE_ON_COL || ob->pd->flag & PDEFLE_KILL_PART)){
+ pa->dietime = cfra-(1.0f-min_d)*dfra;
+ VecLerpf(def_loc,co1,co2,min_d);
+
+ if(global==0)
+ Mat4MulVecfl(ob->obmat,def_loc);
+
+ VECCOPY(state->co,def_loc);
+ VecLerpf(state->vel,pa->state.vel,state->vel,min_d);
+ QuatInterpol(state->rot,pa->state.rot,state->rot,min_d);
+ VecLerpf(state->ave,pa->state.ave,state->ave,min_d);
+
+ *pa_die=1;
+
+ /* particle is dead so we don't need to calculate further */
+ deflections=10;
+
+ /* store for reactors */
+ copy_particle_key(&cstate,state,0);
+
+ if(part->flag & PART_STICKY){
+ pa->stick_ob=ob;
+ pa->flag |= PARS_STICKY;
+ //stick_particle_to_object(ob,pa,state);
+ }
+ }
+ else{
+ VecLerpf(def_loc,co1,co2,min_d);
+
+ if(radius>0.0f){
+ VECSUB(unit_nor,def_loc,ipoint);
+ }
+ else{
+ /* get deflection point & normal */
+ psys_interpolate_face(mvert,mface,0,0,min_w,ipoint,unit_nor,0,0,0,0);
+ if(global){
+ Mat4Mul3Vecfl(ob->obmat,unit_nor);
+ Mat4MulVecfl(ob->obmat,ipoint);
+ }
+ }
+
+ Normalize(unit_nor);
+
+ VECSUB(dvec,co1,co2);
+ /* scale to remaining length after deflection */
+ VecMulf(dvec,1.0f-min_d);
+
+ /* flip normal to face particle */
+ if(Inpf(unit_nor,dvec)<0.0f)
+ VecMulf(unit_nor,-1.0f);
+
+ /* store for easy velocity calculation */
+ o_len=VecLength(dvec);
+
+ /* project particle movement to normal & create tangent */
+ dotprod=Inpf(dvec,unit_nor);
+ VECCOPY(def_nor,unit_nor);
+ VecMulf(def_nor,dotprod);
+ VECSUB(def_tan,def_nor,dvec);
+
+ damp=ob->pd->pdef_damp+ob->pd->pdef_rdamp*2*(BLI_frand()-0.5f);
+
+ /* create location after deflection */
+ VECCOPY(dvec,def_nor);
+ damp=ob->pd->pdef_damp+ob->pd->pdef_rdamp*2*(BLI_frand()-0.5f);
+ CLAMP(damp,0.0,1.0);
+ VecMulf(dvec,1.0f-damp);
+ if(through)
+ VecMulf(dvec,-1.0);
+
+ frict=ob->pd->pdef_frict+ob->pd->pdef_rfrict*2.0f*(BLI_frand()-0.5f);
+ CLAMP(frict,0.0,1.0);
+ VECADDFAC(dvec,dvec,def_tan,1.0f-frict);
+
+ /* store for easy velocity calculation */
+ d_len=VecLength(dvec);
+
+ /* just to be sure we don't hit the current face again */
+ if(through){
+ VECADDFAC(ipoint,ipoint,unit_nor,-0.0001f);
+ VECADDFAC(def_loc,def_loc,unit_nor,-0.0001f);
+
+ if(part->flag & PART_ROT_DYN){
+ VECADDFAC(def_tan,def_tan,unit_nor,-0.0001f);
+ VECADDFAC(def_nor,def_nor,unit_nor,-0.0001f);
+ }
+ }
+ else{
+ VECADDFAC(ipoint,ipoint,unit_nor,0.0001f);
+ VECADDFAC(def_loc,def_loc,unit_nor,0.0001f);
+
+ if(part->flag & PART_ROT_DYN){
+ VECADDFAC(def_tan,def_tan,unit_nor,0.0001f);
+ VECADDFAC(def_nor,def_nor,unit_nor,0.0001f);
+ }
+ }
+
+ /* lets get back to global space */
+ if(global==0){
+ Mat4Mul3Vecfl(ob->obmat,dvec);
+ Mat4MulVecfl(ob->obmat,ipoint);
+ Mat4MulVecfl(ob->obmat,def_loc);/* def_loc remains as intersection point for next iteration */
+ }
+
+ /* store for reactors */
+ VECCOPY(cstate.co,ipoint);
+ VecLerpf(cstate.vel,pa->state.vel,state->vel,min_d);
+ QuatInterpol(cstate.rot,pa->state.rot,state->rot,min_d);
+
+ /* slightly unphysical but looks nice enough */
+ if(part->flag & PART_ROT_DYN){
+ if(global==0){
+ Mat4Mul3Vecfl(ob->obmat,def_nor);
+ Mat4Mul3Vecfl(ob->obmat,def_tan);
+ }
+
+ Normalize(def_tan);
+ Normalize(def_nor);
+ VECCOPY(unit_nor,def_nor);
+
+ /* create normal velocity */
+ VecMulf(def_nor,Inpf(pa->state.vel,def_nor));
+
+ /* create tangential velocity */
+ VecMulf(def_tan,Inpf(pa->state.vel,def_tan));
+
+ /* angular velocity change due to tangential velocity */
+ Crossf(dave,unit_nor,def_tan);
+ VecMulf(dave,1.0f/pa->size);
+
+ /* linear velocity change due to angular velocity */
+ VecMulf(unit_nor,pa->size); /* point of impact from particle center */
+ Crossf(dvel,pa->state.ave,unit_nor);
+
+ if(through)
+ VecMulf(def_nor,-1.0);
+
+ VecMulf(def_nor,1.0f-damp);
+ VECSUB(dvel,dvel,def_nor);
+
+ VecMulf(dvel,1.0f-frict);
+ VecMulf(dave,1.0f-frict);
+ }
+
+ if(d_len<0.001 && VecLength(pa->state.vel)<0.001){
+ /* kill speed to stop slipping */
+ VECCOPY(state->vel,zerovec);
+ VECCOPY(state->co,def_loc);
+ if(part->flag & PART_ROT_DYN)
+ VECCOPY(state->ave,zerovec);
+ deflections=10;
+ }
+ else{
+
+ /* apply new coordinates */
+ VECADD(state->co,def_loc,dvec);
+
+ Normalize(dvec);
+
+ /* we have to use original velocity because otherwise we get slipping */
+ /* when forces like gravity balance out damping & friction */
+ VecMulf(dvec,VecLength(pa->state.vel)*(d_len/o_len));
+ VECCOPY(state->vel,dvec);
+
+ if(part->flag & PART_ROT_DYN){
+ VECADD(state->vel,state->vel,dvel);
+ VecMulf(state->vel,0.5);
+ VECADD(state->ave,state->ave,dave);
+ VecMulf(state->ave,0.5);
+ }
+ }
+ }
+ deflections++;
+
+ cstate.time=cfra-(1.0f-min_d)*dfra;
+ //particle_react_to_collision(min_ob,pob,psys,pa,p,&cstate);
+ push_reaction(pob,psys,p,PART_EVENT_COLLIDE,&cstate);
+ }
+ else
+ return;
+ }
+}
+/************************************************/
+/* Boid physics */
+/************************************************/
+static int boid_see_mesh(ListBase *lb, Object *pob, ParticleSystem *psys, float *vec1, float *vec2, float *loc, float *nor, float cfra)
+{
+ Object *ob, *min_ob;
+ DerivedMesh *dm;
+ MFace *mface;
+ MVert *mvert;
+ ParticleEffectorCache *ec;
+ ParticleSystemModifierData *psmd=psys_get_modifier(pob,psys);
+ float imat[4][4];
+ float co1[3], co2[3], min_w[4], min_d;
+ int min_face=0, intersect=0;
+
+ if(lb->first){
+ intersect=0;
+ min_d=20000.0;
+ min_ob=NULL;
+ for(ec=lb->first; ec; ec=ec->next){
+ if(ec->type & PSYS_EC_DEFLECT){
+ ob= ec->ob;
+
+ if(psys->part->type!=PART_HAIR)
+ where_is_object_time(ob,cfra);
+
+ if(ob==pob)
+ dm=psmd->dm;
+ else
+ dm=0;
+
+ VECCOPY(co1,vec1);
+ VECCOPY(co2,vec2);
+
+ if(ec->vert_cos==0){
+ /* convert particle coordinates to object coordinates */
+ Mat4Invert(imat,ob->obmat);
+
+ Mat4MulVecfl(imat,co1);
+ Mat4MulVecfl(imat,co2);
+ }
+
+ if(psys_intersect_dm(ob,dm,ec->vert_cos,co1,co2,&min_d,&min_face,min_w,ec->face_minmax,0,0,0))
+ min_ob=ob;
+ }
+ }
+ if(min_ob){
+ ob=min_ob;
+
+ if(ob==pob){
+ dm=psmd->dm;
+ }
+ else{
+ psys_disable_all(ob);
+
+ dm=mesh_get_derived_deform(ob,0);
+
+ psys_enable_all(ob);
+ }
+
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+ mface+=min_face;
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+ /* get deflection point & normal */
+ psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0);
+
+ VECADD(nor,nor,loc);
+ Mat4MulVecfl(ob->obmat,loc);
+ Mat4MulVecfl(ob->obmat,nor);
+ VECSUB(nor,nor,loc);
+ return 1;
+ }
+ }
+ return 0;
+}
+/* vector calculus functions in 2d vs. 3d */
+static void set_boid_vec_func(BoidVecFunc *bvf, int is_2d)
+{
+ if(is_2d){
+ bvf->Addf = Vec2Addf;
+ bvf->Subf = Vec2Subf;
+ bvf->Mulf = Vec2Mulf;
+ bvf->Length = Vec2Length;
+ bvf->Normalize = Normalize2;
+ bvf->Inpf = Inp2f;
+ bvf->Copyf = Vec2Copyf;
+ }
+ else{
+ bvf->Addf = VecAddf;
+ bvf->Subf = VecSubf;
+ bvf->Mulf = VecMulf;
+ bvf->Length = VecLength;
+ bvf->Normalize = Normalize;
+ bvf->Inpf = Inpf;
+ bvf->Copyf = VecCopyf;
+ }
+}
+/* boids have limited processing capability so once there's too much information (acceleration) no more is processed */
+static int add_boid_acc(BoidVecFunc *bvf, float lat_max, float tan_max, float *lat_accu, float *tan_accu, float *acc, float *dvec, float *vel)
+{
+ static float tangent[3];
+ static float tan_length;
+
+ if(vel){
+ bvf->Copyf(tangent,vel);
+ tan_length=bvf->Normalize(tangent);
+ return 1;
+ }
+ else{
+ float cur_tan, cur_lat;
+ float tan_acc[3], lat_acc[3];
+ int ret=0;
+
+ bvf->Copyf(tan_acc,tangent);
+
+ if(tan_length>0.0){
+ bvf->Mulf(tan_acc,Inpf(tangent,dvec));
+
+ bvf->Subf(lat_acc,dvec,tan_acc);
+ }
+ else{
+ bvf->Copyf(tan_acc,dvec);
+ lat_acc[0]=lat_acc[1]=lat_acc[2]=0.0f;
+ *lat_accu=lat_max;
+ }
+
+ cur_tan=bvf->Length(tan_acc);
+ cur_lat=bvf->Length(lat_acc);
+
+ /* add tangential acceleration */
+ if(*lat_accu+cur_lat<=lat_max){
+ bvf->Addf(acc,acc,lat_acc);
+ *lat_accu+=cur_lat;
+ ret=1;
+ }
+ else{
+ bvf->Mulf(lat_acc,(lat_max-*lat_accu)/cur_lat);
+ bvf->Addf(acc,acc,lat_acc);
+ *lat_accu=lat_max;
+ }
+
+ /* add lateral acceleration */
+ if(*tan_accu+cur_tan<=tan_max){
+ bvf->Addf(acc,acc,tan_acc);
+ *tan_accu+=cur_tan;
+ ret=1;
+ }
+ else{
+ bvf->Mulf(tan_acc,(tan_max-*tan_accu)/cur_tan);
+ bvf->Addf(acc,acc,tan_acc);
+ *tan_accu=tan_max;
+ }
+
+ return ret;
+ }
+}
+/* determines the acceleration that the boid tries to acchieve */
+static void boid_brain(BoidVecFunc *bvf, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, KDTree *tree, float timestep, float cfra, float *acc, int *pa_die)
+{
+ ParticleData *pars=psys->particles;
+ KDTreeNearest ptn[MAX_BOIDNEIGHBOURS+1];
+ ParticleEffectorCache *ec=0;
+ float dvec[3]={0.0,0.0,0.0}, ob_co[3], ob_nor[3];
+ float avoid[3]={0.0,0.0,0.0}, velocity[3]={0.0,0.0,0.0}, center[3]={0.0,0.0,0.0};
+ float cubedist[MAX_BOIDNEIGHBOURS+1];
+ int i, n, neighbours=0, near, not_finished=1;
+
+ float cur_vel;
+ float lat_accu=0.0f, max_lat_acc=part->max_vel*part->max_lat_acc;
+ float tan_accu=0.0f, max_tan_acc=part->max_vel*part->max_tan_acc;
+ float avg_vel=part->average_vel*part->max_vel;
+
+ acc[0]=acc[1]=acc[2]=0.0f;
+ /* the +1 neighbour is because boid itself is in the tree */
+ neighbours=BLI_kdtree_find_n_nearest(tree,part->boidneighbours+1,pa->state.co,NULL,ptn);
+
+ for(n=1; n<neighbours; n++){
+ cubedist[n]=(float)pow((double)(ptn[n].dist/pa->size),3.0);
+ cubedist[n]=1.0f/MAX2(cubedist[n],1.0f);
+ }
+
+ /* initialize tangent */
+ add_boid_acc(bvf,0.0,0.0,0,0,0,0,pa->state.vel);
+
+ for(i=0; i<BOID_TOT_RULES && not_finished; i++){
+ switch(part->boidrule[i]){
+ case BOID_COLLIDE:
+ /* collision avoidance */
+ bvf->Copyf(dvec,pa->state.vel);
+ bvf->Mulf(dvec,5.0f);
+ bvf->Addf(dvec,dvec,pa->state.co);
+ if(boid_see_mesh(&psys->effectors,ob,psys,pa->state.co,dvec,ob_co,ob_nor,cfra)){
+ float probelen = bvf->Length(dvec);
+ float proj;
+ float oblen;
+
+ Normalize(ob_nor);
+ proj = bvf->Inpf(ob_nor,pa->state.vel);
+
+ bvf->Subf(dvec,pa->state.co,ob_co);
+ oblen=bvf->Length(dvec);
+
+ bvf->Copyf(dvec,ob_nor);
+ bvf->Mulf(dvec,-proj);
+ bvf->Mulf(dvec,((probelen/oblen)-1.0f)*100.0f*part->boidfac[BOID_COLLIDE]);
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ break;
+ case BOID_AVOID:
+ /* predator avoidance */
+ if(psys->effectors.first){
+ for(ec=psys->effectors.first; ec; ec=ec->next){
+ if(ec->type & PSYS_EC_EFFECTOR){
+ Object *eob = ec->ob;
+ PartDeflect *pd = eob->pd;
+
+ if(pd->forcefield==PFIELD_FORCE && pd->f_strength<0.0){
+ float distance;
+ VECSUB(dvec,eob->obmat[3],pa->state.co);
+
+ distance=Normalize(dvec);
+
+ if(part->flag & PART_DIE_ON_COL && distance < pd->mindist){
+ *pa_die=1;
+ pa->dietime=cfra;
+ i=BOID_TOT_RULES;
+ break;
+ }
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ bvf->Mulf(dvec,part->boidfac[BOID_AVOID]*pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ }
+ }
+ else if(ec->type & PSYS_EC_PARTICLE){
+ Object *eob = ec->ob;
+ ParticleSystem *epsys;
+ ParticleSettings *epart;
+ ParticleKey state;
+ PartDeflect *pd;
+ KDTreeNearest ptn2[MAX_BOIDNEIGHBOURS];
+ int totepart, p, count;
+ float distance;
+ epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
+ epart= epsys->part;
+ pd= epart->pd;
+ totepart= epsys->totpart;
+
+ if(pd->forcefield==PFIELD_FORCE && pd->f_strength<0.0){
+ count=BLI_kdtree_find_n_nearest(ec->tree,epart->boidneighbours,pa->state.co,NULL,ptn2);
+ for(p=0; p<count; p++){
+ state.time=-1.0;
+ if(psys_get_particle_state(eob,epsys,ptn2[p].index,&state,0)){
+ VECSUB(dvec, state.co, pa->state.co);
+
+ distance = Normalize(dvec);
+
+ if(part->flag & PART_DIE_ON_COL && distance < (epsys->particles+ptn2[p].index)->size){
+ *pa_die=1;
+ pa->dietime=cfra;
+ i=BOID_TOT_RULES;
+ break;
+ }
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ bvf->Mulf(dvec,part->boidfac[BOID_AVOID]*pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case BOID_CROWD:
+ /* crowd avoidance */
+ near=0;
+ for(n=1; n<neighbours; n++){
+ if(ptn[n].dist<2.0f*pa->size){
+ bvf->Subf(dvec,pa->state.co,pars[ptn[n].index].state.co);
+ bvf->Mulf(dvec,(2.0f*pa->size-ptn[n].dist)/ptn[n].dist);
+ bvf->Addf(avoid,avoid,dvec);
+ near++;
+ }
+ /* ptn[] is distance ordered so no need to check others */
+ else break;
+ }
+ if(near){
+ bvf->Mulf(avoid,part->boidfac[BOID_CROWD]*2.0f/timestep);
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,avoid,0);
+ }
+ break;
+ case BOID_CENTER:
+ /* flock centering */
+ if(neighbours>1){
+ for(n=1; n<neighbours; n++){
+ bvf->Addf(center,center,pars[ptn[n].index].state.co);
+ }
+ bvf->Mulf(center,1.0f/((float)neighbours-1.0f));
+
+ bvf->Subf(dvec,center,pa->state.co);
+
+ bvf->Mulf(dvec,part->boidfac[BOID_CENTER]*2.0f);
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ break;
+ case BOID_AV_VEL:
+ /* average velocity */
+ cur_vel=bvf->Length(pa->state.vel);
+ if(cur_vel>0.0){
+ bvf->Copyf(dvec,pa->state.vel);
+ bvf->Mulf(dvec,part->boidfac[BOID_AV_VEL]*(avg_vel-cur_vel)/cur_vel);
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ break;
+ case BOID_VEL_MATCH:
+ /* velocity matching */
+ if(neighbours>1){
+ for(n=1; n<neighbours; n++){
+ bvf->Copyf(dvec,pars[ptn[n].index].state.vel);
+ bvf->Mulf(dvec,cubedist[n]);
+ bvf->Addf(velocity,velocity,dvec);
+ }
+ bvf->Mulf(velocity,1.0f/((float)neighbours-1.0f));
+
+ bvf->Subf(dvec,velocity,pa->state.vel);
+
+ bvf->Mulf(dvec,part->boidfac[BOID_VEL_MATCH]);
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ break;
+ case BOID_GOAL:
+ /* goal seeking */
+ if(psys->effectors.first){
+ for(ec=psys->effectors.first; ec; ec=ec->next){
+ if(ec->type & PSYS_EC_EFFECTOR){
+ Object *eob = ec->ob;
+ PartDeflect *pd = eob->pd;
+ float temp[4];
+
+ if(pd->forcefield==PFIELD_FORCE && pd->f_strength>0.0){
+ float distance;
+ VECSUB(dvec,eob->obmat[3],pa->state.co);
+
+ distance=Normalize(dvec);
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ VecMulf(dvec,pd->f_strength*part->boidfac[BOID_GOAL]/(float)pow((double)distance,(double)pd->f_power));
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ }
+ else if(pd->forcefield==PFIELD_GUIDE){
+ float distance;
+
+ where_on_path(eob, (cfra-pa->time)/pa->lifetime, temp, dvec);
+
+ VECSUB(dvec,temp,pa->state.co);
+
+ distance=Normalize(dvec);
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ VecMulf(dvec,pd->f_strength*part->boidfac[BOID_GOAL]/(float)pow((double)distance,(double)pd->f_power));
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ }
+ }
+ else if(ec->type & PSYS_EC_PARTICLE){
+ Object *eob = ec->ob;
+ ParticleSystem *epsys;
+ ParticleSettings *epart;
+ ParticleKey state;
+ PartDeflect *pd;
+ KDTreeNearest ptn2[MAX_BOIDNEIGHBOURS];
+ int totepart, p, count;
+ float distance;
+ epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
+ epart= epsys->part;
+ pd= epart->pd;
+ totepart= epsys->totpart;
+
+ if(pd->forcefield==PFIELD_FORCE && pd->f_strength>0.0){
+ count=BLI_kdtree_find_n_nearest(ec->tree,epart->boidneighbours,pa->state.co,NULL,ptn2);
+ for(p=0; p<count; p++){
+ state.time=-1.0;
+ if(psys_get_particle_state(eob,epsys,ptn2[p].index,&state,0)){
+ VECSUB(dvec, state.co, pa->state.co);
+
+ distance = Normalize(dvec);
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ bvf->Mulf(dvec,part->boidfac[BOID_AVOID]*pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
+
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ case BOID_LEVEL:
+ /* level flight */
+ if((part->flag & PART_BOIDS_2D)==0){
+ dvec[0]=dvec[1]=0.0;
+ dvec[2]=-pa->state.vel[2];
+
+ VecMulf(dvec,part->boidfac[BOID_LEVEL]);
+ not_finished=add_boid_acc(bvf,max_lat_acc,max_tan_acc,&lat_accu,&tan_accu,acc,dvec,0);
+ }
+ break;
+ }
+ }
+}
+/* tries to realize the wanted acceleration */
+static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys, ParticleSettings *part, float timestep, float *acc, ParticleKey *state)
+{
+ float dvec[3], bvec[3], length, max_vel=part->max_vel;
+ float q2[4], q[4];
+ float g=9.81f, pa_mass=part->mass;
+ float yvec[3]={0.0,1.0,0.0}, zvec[3]={0.0,0.0,-1.0}, bank;
+
+ /* apply new velocity, location & rotation */
+ copy_particle_key(state,&pa->state,0);
+
+ if(part->flag & PART_SIZEMASS)
+ pa_mass*=pa->size;
+
+ /* by regarding the acceleration as a force at this stage we*/
+ /* can get better controll allthough it's a bit unphysical */
+ bvf->Mulf(acc,1.0f/pa_mass);
+
+ bvf->Copyf(dvec,acc);
+ bvf->Mulf(dvec,timestep*timestep*0.5f);
+
+ bvf->Copyf(bvec,state->vel);
+ bvf->Mulf(bvec,timestep);
+ bvf->Addf(dvec,dvec,bvec);
+ bvf->Addf(state->co,state->co,dvec);
+
+ /* air speed from wind effectors */
+ if(psys->effectors.first){
+ ParticleEffectorCache *ec;
+ for(ec=psys->effectors.first; ec; ec=ec->next){
+ if(ec->type & PSYS_EC_EFFECTOR){
+ Object *eob = ec->ob;
+ PartDeflect *pd = eob->pd;
+
+ if(pd->forcefield==PFIELD_WIND && pd->f_strength!=0.0){
+ float distance, wind[3];
+ VecCopyf(wind,eob->obmat[2]);
+ distance=VecLenf(state->co,eob->obmat[3]);
+
+ if (distance < 0.001) distance = 0.001f;
+
+ if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
+ ;
+ else{
+ Normalize(wind);
+ VecMulf(wind,pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
+ bvf->Addf(state->co,state->co,wind);
+ }
+ }
+ }
+ }
+ }
+
+
+ if((part->flag & PART_BOIDS_2D)==0 && pa->state.vel[0]!=0.0 && pa->state.vel[0]!=0.0 && pa->state.vel[0]!=0.0){
+ Crossf(yvec,state->vel,zvec);
+
+ Normalize(yvec);
+
+ bank=Inpf(yvec,acc);
+
+ bank=-(float)atan((double)(bank/g));
+
+ bank*=part->banking;
+
+ bank-=pa->bank;
+ if(bank>M_PI*part->max_bank){
+ bank=pa->bank+(float)M_PI*part->max_bank;
+ }
+ else if(bank<-M_PI*part->max_bank){
+ bank=pa->bank-(float)M_PI*part->max_bank;
+ }
+ else
+ bank+=pa->bank;
+
+ pa->bank=bank;
+ }
+ else{
+ bank=0.0;
+ }
+
+
+ VecRotToQuat(state->vel,bank,q);
+
+ VECCOPY(dvec,state->vel);
+ VecMulf(dvec,-1.0f);
+ vectoquat(dvec, OB_POSX, OB_POSZ, q2);
+
+ QuatMul(state->rot,q,q2);
+
+ bvf->Mulf(acc,timestep);
+ bvf->Addf(state->vel,state->vel,acc);
+
+ if(part->flag & PART_BOIDS_2D){
+ state->vel[2]=0.0;
+ state->co[2]=part->groundz;
+
+ if(psys->keyed_ob){
+ Object *zob=psys->keyed_ob;
+ int min_face;
+ float co1[3],co2[3],min_d=2.0,min_w[4],imat[4][4];
+ VECCOPY(co1,state->co);
+ VECCOPY(co2,state->co);
+
+ co1[2]=1000.0f;
+ co2[2]=-1000.0f;
+
+ Mat4Invert(imat,zob->obmat);
+ Mat4MulVecfl(imat,co1);
+ Mat4MulVecfl(imat,co2);
+
+ if(psys_intersect_dm(zob,0,0,co1,co2,&min_d,&min_face,min_w,0,0,0,0)){
+ DerivedMesh *dm;
+ MFace *mface;
+ MVert *mvert;
+ float loc[3],nor[3],q1[4];
+
+ psys_disable_all(zob);
+ dm=mesh_get_derived_final(zob,0);
+ psys_enable_all(zob);
+
+ mface=dm->getFaceDataArray(dm,CD_MFACE);
+ mface+=min_face;
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+ /* get deflection point & normal */
+ psys_interpolate_face(mvert,mface,0,0,min_w,loc,nor,0,0,0,0);
+
+ Mat4MulVecfl(zob->obmat,loc);
+ Mat4Mul3Vecfl(zob->obmat,nor);
+
+ Normalize(nor);
+
+ VECCOPY(state->co,loc);
+
+ zvec[2]=1.0;
+
+ Crossf(loc,zvec,nor);
+
+ bank=VecLength(loc);
+ if(bank>0.0){
+ bank=saasin(bank);
+
+ VecRotToQuat(loc,bank,q);
+
+ QUATCOPY(q1,state->rot);
+
+ QuatMul(state->rot,q,q1);
+ }
+ }
+ }
+ }
+
+ length=bvf->Length(state->vel);
+ if(length > max_vel)
+ bvf->Mulf(state->vel,max_vel/length);
+}
+/************************************************/
+/* Hair */
+/************************************************/
+void save_hair(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
+ ParticleData *pa;
+ HairKey *key;
+ int totpart;
+ int i;
+
+ Mat4Invert(ob->imat,ob->obmat);
+
+ psys->lattice=psys_get_lattice(ob,psys);
+
+ if(psys->totpart==0) return;
+
+ totpart=psys->totpart;
+
+ /* save new keys for elements if needed */
+ for(i=0,pa=psys->particles; i<totpart; i++,pa++) {
+ /* first time alloc */
+ if(pa->totkey==0 || pa->hair==NULL) {
+ pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys");
+ pa->totkey = 0;
+ }
+
+ key = pa->hair + pa->totkey;
+
+ /* convert from global to geometry space */
+ VecCopyf(key->co, pa->state.co);
+ Mat4MulVecfl(ob->imat, key->co);
+
+ if(pa->totkey) {
+ VECSUB(key->co, key->co, pa->hair->co);
+ psys_vec_rot_to_face(psmd->dm, pa, key->co);
+ }
+
+ key->time = pa->state.time;
+
+ key->weight = 1.0f - key->time / 100.0f;
+
+ pa->totkey++;
+
+ /* root is always in the origin of hair space so we set it to be so after the last key is saved*/
+ if(pa->totkey == psys->part->hair_step + 1)
+ pa->hair->co[0] = pa->hair->co[1] = pa->hair->co[2] = 0.0f;
+ }
+}
+/************************************************/
+/* System Core */
+/************************************************/
+/* unbaked particles are calculated dynamically */
+static void dynamics_step(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
+ float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size)
+{
+ ParticleData *pa;
+ ParticleKey *outstate, *key;
+ ParticleSettings *part=psys->part;
+ KDTree *tree=0;
+ BoidVecFunc bvf;
+ IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE);
+ Material *ma=give_current_material(ob,part->omat);
+ float timestep;
+ int p, totpart, pa_die;
+ /* current time */
+ float ctime, ipotime;
+ /* frame & time changes */
+ float dfra, dtime, pa_dtime, pa_dfra=0.0;
+ float birthtime, dietime;
+
+ /* where have we gone in time since last time */
+ dfra= cfra - psys->cfra;
+
+ totpart=psys->totpart;
+
+ timestep=psys_get_timestep(part);
+ dtime= dfra*timestep;
+ ctime= cfra*timestep;
+ ipotime= cfra;
+
+ if(part->flag&PART_ABS_TIME && part->ipo){
+ calc_ipo(part->ipo, cfra);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ if(dfra<0.0){
+ float *vg_size=0;
+ if(part->type==PART_REACTOR)
+ vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
+
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ if(pa->flag & PARS_UNEXIST) continue;
+
+ /* set correct ipo timing */
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
+ calc_ipo(part->ipo, ipotime);
+ execute_ipo((ID *)part, part->ipo);
+ }
+ pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+
+ if(part->type==PART_REACTOR)
+ initialize_particle(pa,p,ob,psys,psmd);
+
+ reset_particle(pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
+
+ 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;
+ }
+ }
+
+ if(vg_size)
+ MEM_freeN(vg_size);
+
+ //if(part->phystype==PART_PHYS_SOLID)
+ // reset_to_first_fragment(psys);
+ }
+ else{
+ BLI_srandom(31415926 + (int)cfra + psys->seed);
+
+ /* outstate is used so that particles are updated in parallel */
+ outstate=MEM_callocN(totpart*sizeof(ParticleKey),"Particle Outstates");
+
+ /* update effectors */
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+
+ psys_init_effectors(ob,part->eff_group,psys);
+
+ if(psys->effectors.first)
+ precalc_effectors(ob,psys,psmd);
+
+ if(part->phystype==PART_PHYS_BOIDS){
+ /* create particle tree for fast inter-particle comparisons */
+ tree=BLI_kdtree_new(totpart);
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive!=PARS_ALIVE)
+ continue;
+
+ BLI_kdtree_insert(tree, p, pa->state.co, NULL);
+ }
+ BLI_kdtree_balance(tree);
+ set_boid_vec_func(&bvf,part->flag&PART_BOIDS_2D);
+ }
+
+ /* main loop: calculate physics for all particles */
+ for(p=0, pa=psys->particles, key=outstate; p<totpart; p++,pa++,key++){
+ if(pa->flag & PARS_UNEXIST) continue;
+
+ copy_particle_key(key,&pa->state,1);
+
+ /* set correct ipo timing */
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
+ calc_ipo(part->ipo, ipotime);
+ execute_ipo((ID *)part, part->ipo);
+ }
+ pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+
+ pa_die=0;
+
+ birthtime = pa->time + pa->loop * pa->lifetime;
+
+ if(pa->alive==PARS_UNBORN
+ || pa->alive==PARS_KILLED
+ || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
+ || birthtime >= cfra){
+ /* allways reset particles to emitter before birth */
+ reset_particle(pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
+ copy_particle_key(key,&pa->state,1);
+ }
+
+ if(dfra>0.0 || psys->recalc){
+
+ if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
+ react_to_events(psys,p);
+
+ pa_dfra = dfra;
+ pa_dtime = dtime;
+
+ dietime = birthtime + pa->lifetime;
+
+ if(birthtime < cfra && birthtime >= psys->cfra){
+ /* particle is born some time between this and last step*/
+ pa->alive = PARS_ALIVE;
+ pa_dfra = cfra - birthtime;
+ pa_dtime = pa_dfra*timestep;
+ }
+ else if(dietime <= cfra && psys->cfra < dietime){
+ /* particle dies some time between this and last step */
+ pa_dfra = dietime - psys->cfra;
+ pa_dtime = pa_dfra * timestep;
+ pa_die = 1;
+ }
+ else if(dietime < cfra){
+ /* TODO: figure out if there's something to be done when particle is dead */
+ }
+
+ copy_particle_key(key,&pa->state,1);
+
+ if(dfra>0.0 && pa->alive==PARS_ALIVE){
+ switch(part->phystype){
+ case PART_PHYS_NEWTON:
+ /* do global forces & effectors */
+ apply_particle_forces(p,pa,ob,psys,part,timestep,pa_dfra,cfra,key);
+
+ /* deflection */
+ deflect_particle(ob,psmd,psys,part,pa,p,pa_dfra,cfra,key,&pa_die);
+
+ /* rotations */
+ rotate_particle(part,pa,pa_dfra,timestep,key);
+
+ break;
+ case PART_PHYS_BOIDS:
+ {
+ float acc[3];
+ boid_brain(&bvf,pa,ob,psys,part,tree,timestep,cfra,acc,&pa_die);
+ if(pa_die==0)
+ boid_body(&bvf,pa,psys,part,timestep,acc,key);
+ break;
+ }
+ }
+
+ push_reaction(ob,psys,p,PART_EVENT_NEAR,key);
+
+ if(pa_die){
+ push_reaction(ob,psys,p,PART_EVENT_DEATH,key);
+
+ if(part->flag & PART_LOOP && part->type!=PART_HAIR){
+ pa->loop++;
+ reset_particle(pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot);
+ copy_particle_key(key,&pa->state,1);
+ pa->alive=PARS_ALIVE;
+ }
+ else{
+ pa->alive=PARS_DEAD;
+ key->time=pa->dietime;
+
+ if(pa->flag&PARS_STICKY)
+ psys_key_to_object(pa->stick_ob,key,0);
+ }
+ }
+ else
+ key->time=cfra;
+ }
+ }
+ }
+ /* apply outstates to particles */
+ for(p=0, pa=psys->particles, key=outstate; p<totpart; p++,pa++,key++)
+ copy_particle_key(&pa->state,key,1);
+
+ MEM_freeN(outstate);
+ }
+ if(psys->reactevents.first)
+ BLI_freelistN(&psys->reactevents);
+
+ if(tree)
+ BLI_kdtree_free(tree);
+}
+
+/* check if path cache or children need updating and do it if needed */
+static void psys_update_path_cache(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+{
+ ParticleSettings *part=psys->part;
+ ParticleEditSettings *pset=&G.scene->toolsettings->particle;
+ int distr=0,alloc=0;
+
+ if((psys->part->childtype && psys->totchild != get_psys_tot_child(psys)) || psys->recalc&PSYS_ALLOC)
+ alloc=1;
+
+ if(alloc || psys->recalc&PSYS_DISTR || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT)))
+ distr=1;
+
+ if(distr){
+ if(alloc)
+ alloc_particles(ob,psys,psys->totpart);
+
+ if(get_psys_tot_child(psys)) {
+ /* don't generate children while computing the hair keys */
+ if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
+ distribute_particles(ob,psys,PART_FROM_CHILD);
+
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
+ psys_find_parents(ob,psmd,psys);
+ }
+ }
+ }
+
+ if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && (psys_in_edit_mode(psys)
+ || (part->type==PART_HAIR || part->draw_as==PART_DRAW_PATH) || part->draw&PART_DRAW_KEYS)){
+ psys_cache_paths(ob, psys, cfra, 0);
+
+ /* for render, child particle paths are computed on the fly */
+ if(part->childtype) {
+ if(((psys->totchild!=0)) || (psys_in_edit_mode(psys) && (pset->flag&PE_SHOW_CHILD)))
+ if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE))
+ psys_cache_child_paths(ob, psys, cfra, 0);
+ }
+ }
+ else if(psys->pathcache)
+ psys_free_path_cache(psys);
+}
+
+static void hair_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
+{
+ ParticleSettings *part = psys->part;
+ ParticleData *pa;
+ int p;
+ float disp = (float)get_current_display_percentage(psys)/50.0f-1.0f;
+
+ for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
+ if(pa->r_rot[0] > disp)
+ pa->flag |= PARS_NO_DISP;
+ else
+ pa->flag &= ~PARS_NO_DISP;
+ }
+
+ if(psys->recalc & PSYS_DISTR)
+ /* need this for changing subsurf levels */
+ psys_calc_dmcache(ob, psmd->dm, psys);
+
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+
+ psys_init_effectors(ob,part->eff_group,psys);
+ if(psys->effectors.first)
+ precalc_effectors(ob,psys,psmd);
+
+ if(psys_in_edit_mode(psys))
+ PE_recalc_world_cos(ob, psys);
+
+ psys_update_path_cache(ob,psmd,psys,cfra);
+}
+
+/* updates cached particles' alive & other flags etc..*/
+static void cached_step(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra, float *vg_size)
+{
+ ParticleSettings *part=psys->part;
+ ParticleData *pa;
+ ParticleKey state;
+ IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE);
+ Material *ma=give_current_material(ob,part->omat);
+ int p;
+ float ipotime=cfra, disp, birthtime, dietime;
+
+ if(psys->effectors.first)
+ psys_end_effectors(psys);
+
+ //if(part->flag & (PART_BAKED_GUIDES+PART_BAKED_DEATHS)){
+ psys_init_effectors(ob,part->eff_group,psys);
+ if(psys->effectors.first)
+ precalc_effectors(ob,psys,psmd);
+ //}
+
+ disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
+
+ for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
+ calc_ipo(part->ipo, ipotime);
+ execute_ipo((ID *)part, part->ipo);
+ }
+ pa->size= psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
+
+ psys->lattice=psys_get_lattice(ob,psys);
+
+ if(part->flag & PART_LOOP && part->type!=PART_HAIR)
+ pa->loop = (short)((cfra - pa->time) / pa->lifetime);
+ else
+ pa->loop = 0;
+
+ birthtime = pa->time + pa->loop * pa->lifetime;
+ dietime = birthtime + pa->lifetime;
+
+ /* update alive status and push events */
+ if(pa->time > cfra)
+ pa->alive = PARS_UNBORN;
+ else if(dietime <= cfra){
+ if(dietime > psys->cfra){
+ state.time = pa->dietime;
+ psys_get_particle_state(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(ob,psys,p,&state,1);
+ state.time = cfra;
+ push_reaction(ob,psys,p,PART_EVENT_NEAR,&state);
+ }
+
+ if(psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
+ }
+
+ if(pa->r_rot[0] > 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(psys)) {
+ alloc_particles(ob, psys, psys->totpart);
+ distribute_particles(ob, psys, PART_FROM_CHILD);
+ }
+}
+/* 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(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
+{
+ ParticleSettings *part;
+ ParticleData *pa;
+ int totpart,oldtotpart=0,p;
+ float disp, *vg_vel=0, *vg_tan=0, *vg_rot=0, *vg_size=0;
+ int init=0,distr=0,alloc=0;
+
+ /*----start validity checks----*/
+
+ part=psys->part;
+
+ if(part->flag&PART_ABS_TIME && part->ipo){
+ calc_ipo(part->ipo, cfra);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ if(part->from!=PART_FROM_PARTICLE)
+ vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
+
+ if(part->type == PART_HAIR) {
+ if(psys->flag & PSYS_HAIR_DONE) {
+ hair_step(ob, psmd, psys, cfra);
+ psys->cfra = cfra;
+ psys->recalc = 0;
+ return;
+ }
+ }
+ else if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
+ ; /* cache shouldn't be used for "none" or "keyed" physics */
+ else {
+ if(psys->recalc && (psys->flag & PSYS_PROTECT_CACHE) == 0)
+ clear_particles_from_cache(ob,psys,(int)cfra);
+ else if(get_particles_from_cache(ob, psys, (int)cfra)) {
+ cached_step(ob,psmd,psys,cfra,vg_size);
+ psys->cfra=cfra;
+ psys->recalc = 0;
+ return;
+ }
+ }
+
+ /* if still here react to events */
+
+ if(psys->recalc&PSYS_TYPE) {
+ /* 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->distr == PART_DISTR_GRID)
+ part->distr = PART_DISTR_JIT;
+ }
+
+ if(psys->part->phystype != PART_PHYS_KEYED)
+ psys->flag &= ~PSYS_KEYED;
+
+ if(part->type == PART_HAIR) {
+ part->draw_as = PART_DRAW_PATH;
+ part->rotfrom = PART_ROT_IINCR;
+ }
+ else
+ free_hair(psys);
+
+ psys->softflag= 0;
+ psys->recalc &= ~PSYS_TYPE;
+ alloc = 1;
+
+ /* this is a bad level call, but currently type change
+ * can happen after redraw, so force redraw from here */
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+ else
+ oldtotpart = psys->totpart;
+
+ if(part->distr == PART_DISTR_GRID)
+ totpart = part->grid_res * part->grid_res * part->grid_res;
+ else
+ totpart = psys->part->totpart;
+
+ if(oldtotpart != totpart || psys->recalc&PSYS_ALLOC || (psys->part->childtype && psys->totchild != get_psys_tot_child(psys)))
+ alloc = 1;
+
+ if(alloc || psys->recalc&PSYS_DISTR || (psys->vgroup[PSYS_VG_DENSITY] && (G.f & G_WEIGHTPAINT) && ob==OBACT))
+ distr = 1;
+
+ if(distr || psys->recalc&PSYS_INIT)
+ init = 1;
+
+ if(init) {
+ if(distr) {
+ if(alloc)
+ alloc_particles(ob, psys, totpart);
+
+ distribute_particles(ob, psys, 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(psys))
+ distribute_particles(ob, psys, PART_FROM_CHILD);
+ }
+ initialize_all_particles(ob, psys, psmd);
+
+ if(alloc)
+ reset_all_particles(ob, psys, psmd, 0.0, cfra, oldtotpart);
+
+ /* flag for possible explode modifiers after this system */
+ psmd->flag |= eParticleSystemFlag_Pars;
+ }
+
+
+ if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED)
+ psys_count_keyed_targets(ob,psys);
+
+ 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);
+ }
+
+ /* set particles to be not calculated */
+ disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
+
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ if(pa->r_rot[0] > disp)
+ pa->flag |= PARS_NO_DISP;
+ else
+ pa->flag &= ~PARS_NO_DISP;
+ }
+
+ /* ok now we're all set so let's go */
+ if(psys->totpart)
+ dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size);
+
+ psys->recalc = 0;
+ psys->cfra = cfra;
+
+ if(part->type == PART_HAIR || part->phystype == PART_PHYS_NO
+ || (part->phystype == PART_PHYS_KEYED && psys->flag & PSYS_FIRST_KEYED))
+ ; /* cache shouldn't be used for hair or "none" or "first keyed" physics */
+ else
+ write_particles_to_cache(ob, psys, cfra);
+
+ /* for keyed particles the path is allways known so it can be drawn */
+ if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED){
+ set_keyed_keys(ob, psys);
+ psys_update_path_cache(ob,psmd,psys,(int)cfra);
+ }
+ else if(psys->pathcache)
+ psys_free_path_cache(psys);
+
+ if(vg_vel) MEM_freeN(vg_vel);
+ if(vg_tan) MEM_freeN(vg_tan);
+ if(vg_rot) MEM_freeN(vg_rot);
+
+ if(psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
+ }
+}
+
+void psys_to_softbody(Object *ob, ParticleSystem *psys, int force_recalc)
+{
+ SoftBody *sb;
+ short softflag;
+
+ if((psys->softflag&OB_SB_ENABLE)==0) return;
+
+ if(psys->recalc || force_recalc)
+ psys->softflag|=OB_SB_REDO;
+
+ /* let's replace the object's own softbody with the particle softbody */
+ /* a temporary solution before cloth simulation is implemented, jahka */
+
+ /* save these */
+ sb=ob->soft;
+ softflag=ob->softflag;
+
+ /* swich to new ones */
+ ob->soft=psys->soft;
+ ob->softflag=psys->softflag;
+
+ /* do softbody */
+ sbObjectStep(ob, (float)G.scene->r.cfra, NULL, psys_count_keys(psys));
+
+ /* return things back to normal */
+ psys->soft=ob->soft;
+ psys->softflag=ob->softflag;
+
+ ob->soft=sb;
+ ob->softflag=softflag;
+}
+static int hair_needs_recalc(ParticleSystem *psys)
+{
+ if((psys->flag & PSYS_EDITED)==0 && (
+ (psys->flag & PSYS_HAIR_DONE)==0
+ || psys->recalc & PSYS_RECALC_HAIR)
+ ) {
+ psys->recalc &= ~PSYS_RECALC_HAIR;
+ return 1;
+ }
+
+ return 0;
+}
+/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
+void particle_system_update(Object *ob, ParticleSystem *psys){
+
+ ParticleSystemModifierData *psmd=0;
+ float cfra;
+
+ if(!psys_check_enabled(ob, psys))
+ return;
+
+ cfra=bsystem_time(ob,(float)CFRA,0.0);
+ psmd= psys_get_modifier(ob, psys);
+
+ /* system was already updated from modifier stack */
+ if(psmd->flag&eParticleSystemFlag_psys_updated) {
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ /* make sure it really was updated to cfra */
+ if(psys->cfra==cfra)
+ return;
+ }
+
+ if(!psmd->dm)
+ return;
+
+ /* baked path softbody */
+ if(psys->part->type==PART_HAIR && psys->soft)
+ psys_to_softbody(ob, psys, 0);
+
+ /* not needed, this is all handled in hair_step */
+ ///* is the mesh changing under the edited particles? */
+ //if((psys->flag & PSYS_EDITED) && psys->part->type==PART_HAIR && psys->recalc & PSYS_RECALC_HAIR) {
+ // /* Just update the particles on the mesh */
+ // psys_update_edithair_dmfaces(ob, psmd->dm, psys);
+ //}
+
+ if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)){
+ float hcfra=0.0f;
+ int i;
+ free_hair(psys);
+
+ /* first step is negative so particles get killed and reset */
+ psys->cfra=1.0f;
+
+ for(i=0; i<=psys->part->hair_step; i++){
+ hcfra=100.0f*(float)i/(float)psys->part->hair_step;
+ system_step(ob,psys,psmd,hcfra);
+ save_hair(ob,psys,psmd,hcfra);
+ }
+
+ psys->flag |= PSYS_HAIR_DONE;
+
+ if(psys->softflag&OB_SB_ENABLE)
+ psys_to_softbody(ob,psys,1);
+ }
+
+ system_step(ob,psys,psmd,cfra);
+
+ Mat4Invert(psys->imat, ob->obmat); /* used for duplicators */
+}
+
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
new file mode 100644
index 00000000000..cdb95e2f015
--- /dev/null
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -0,0 +1,262 @@
+/**
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+* Contributor(s): Campbell Barton <ideasman42@gmail.com>
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "BKE_pointcache.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+
+#include "BLI_blenlib.h"
+#include "BKE_utildefines.h"
+#include "blendef.h"
+
+/* needed for directory lookup */
+#ifndef WIN32
+ #include <dirent.h>
+#else
+ #include "BLI_winstuff.h"
+#endif
+
+/* untitled blend's need getpid for a unique name */
+#ifdef WIN32
+#include <process.h>
+#else
+#include <unistd.h>
+#endif
+
+/* Takes an Object ID and returns a unique name
+ - id: object id
+ - cfra: frame for the cache, can be negative
+ - stack_index: index in the modifier stack. we can have cache for more then one stack_index
+*/
+
+static int ptcache_path(char *filename)
+{
+ int i;
+ if (G.relbase_valid) {
+ char dir[FILE_MAX], file[FILE_MAX]; /* we dont want the dir, only the file */
+
+ BLI_split_dirfile(G.sce, dir, file);
+ i = strlen(file);
+
+ /* remove .blend */
+ if (i > 6)
+ file[i-6] = '\0';
+
+ sprintf(filename, "//"PTCACHE_PATH"%s/", file); /* add blend file name to pointcache dir */
+ BLI_convertstringcode(filename, G.sce, 0);
+ return strlen(filename);
+ }
+
+ /* use the temp path. this is weak but better then not using point cache at all */
+ /* btempdir is assumed to exist and ALWAYS has a trailing slash */
+ return sprintf(filename, "%s"PTCACHE_PATH"%d/", btempdir, abs(getpid()));
+}
+
+int BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext)
+{
+ int len=0;
+ char *idname;
+ char *newname;
+ filename[0] = '\0';
+ newname = filename;
+
+ /*if (!G.relbase_valid) return 0; *//* save blend file before using pointcache */
+
+ /* start with temp dir */
+ if (do_path) {
+ len = ptcache_path(filename);
+ newname += len;
+ }
+ idname = (id->name+2);
+ /* convert chars to hex so they are always a valid filename */
+ while('\0' != *idname) {
+ sprintf(newname, "%02X", (char)(*idname++));
+ newname+=2;
+ len += 2;
+ }
+
+ if (do_ext) {
+ sprintf(newname, "_%06d_%02d"PTCACHE_EXT, cfra, stack_index); /* always 6 chars */
+ len += 16;
+ }
+
+ return len; /* make sure the above string is always 16 chars */
+}
+
+/* youll need to close yourself after! */
+FILE *BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index)
+{
+ /* mode is same as fopen's modes */
+ FILE *fp = NULL;
+ char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+
+ /*if (!G.relbase_valid) return NULL; *//* save blend file before using pointcache */
+
+ BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
+
+ if (mode=='r') {
+ if (!BLI_exists(filename)) {
+ return NULL;
+ }
+ fp = fopen(filename, "rb");
+ } else if (mode=='w') {
+ BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
+ fp = fopen(filename, "wb");
+ }
+
+ if (!fp) {
+ return NULL;
+ }
+
+ return fp;
+}
+
+/* youll need to close yourself after!
+ * mode - PTCACHE_CLEAR_ALL,
+
+*/
+
+void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
+{
+ int len; /* store the length of the string */
+
+ /* mode is same as fopen's modes */
+ DIR *dir;
+ struct dirent *de;
+ char path[FILE_MAX];
+ char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+ char path_full[(FILE_MAXDIR+FILE_MAXFILE)*2];
+
+ /*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
+
+ /* clear all files in the temp dir with the prefix of the ID and the ".bphys" suffix */
+ switch (mode) {
+ case PTCACHE_CLEAR_ALL:
+ case PTCACHE_CLEAR_BEFORE:
+ case PTCACHE_CLEAR_AFTER:
+ ptcache_path(path);
+
+ len = BKE_ptcache_id_filename(id, filename, cfra, stack_index, 0, 0); /* no path */
+
+ dir = opendir(path);
+ if (dir==NULL)
+ return;
+
+ while ((de = readdir(dir)) != NULL) {
+ if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
+ if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ if (mode == PTCACHE_CLEAR_ALL) {
+ BLI_join_dirfile(path_full, path, de->d_name);
+ BLI_delete(path_full, 0, 0);
+ } else {
+ /* read the number of the file */
+ int frame, len2 = strlen(de->d_name);
+ char num[7];
+ if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+ strncpy(num, de->d_name + (strlen(de->d_name) - 15), 6);
+ frame = atoi(num);
+
+ if((mode==PTCACHE_CLEAR_BEFORE && frame < cfra) ||
+ (mode==PTCACHE_CLEAR_AFTER && frame > cfra) ) {
+
+ BLI_join_dirfile(path_full, path, de->d_name);
+ BLI_delete(path_full, 0, 0);
+ }
+ }
+ }
+ }
+ }
+ }
+ closedir(dir);
+ break;
+
+ case PTCACHE_CLEAR_FRAME:
+ len = BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1); /* no path */
+ BLI_delete(filename, 0, 0);
+ break;
+ }
+ return;
+}
+
+int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index)
+{
+ char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+
+ BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
+
+ return BLI_exists(filename);
+}
+
+/* Use this when quitting blender, with unsaved files */
+void BKE_ptcache_remove(void)
+{
+ char path[FILE_MAX];
+ char path_full[FILE_MAX];
+ int rmdir = 1;
+
+ ptcache_path(path);
+
+ if (BLI_exists(path)) {
+ /* TODO, Check with win32, probably needs last slash removed */
+ /* The pointcache dir exists? - remove all pointcache */
+
+ DIR *dir;
+ struct dirent *de;
+
+ dir = opendir(path);
+ if (dir==NULL)
+ return;
+
+ while ((de = readdir(dir)) != NULL) {
+ if( strcmp(de->d_name, ".")==0 || strcmp(de->d_name, "..")==0) {
+ /* do nothing */
+ } else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
+ BLI_join_dirfile(path_full, path, de->d_name);
+ BLI_delete(path_full, 0, 0);
+ } else {
+ rmdir = 0; /* unknown file, dont remove the dir */
+ }
+ }
+ } else {
+ rmdir = 0; /* path dosnt exist */
+ }
+
+ if (rmdir) {
+ BLI_delete(path, 1, 0);
+ }
+}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index e772a3bcdb4..88afa8d5e61 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -461,6 +461,9 @@ void init_actuator(bActuator *act)
case ACT_VISIBILITY:
act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
break;
+ case ACT_2DFILTER:
+ act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
+ break;
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 42a61fb5f11..216ad101569 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -47,6 +47,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
+#include "DNA_color_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
@@ -63,6 +64,7 @@
#include "BKE_anim.h"
#include "BKE_armature.h"
#include "BKE_bad_level_calls.h"
+#include "BKE_colortools.h"
#include "BKE_constraint.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -75,11 +77,11 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_sculpt.h"
#include "BKE_world.h"
#include "BKE_utildefines.h"
#include "BIF_previewrender.h"
-#include "BDR_sculptmode.h"
#include "BPY_extern.h"
#include "BLI_arithb.h"
@@ -151,6 +153,7 @@ void free_scene(Scene *sce)
}
BLI_freelistN(&sce->markers);
+ BLI_freelistN(&sce->transform_spaces);
BLI_freelistN(&sce->r.layers);
if(sce->toolsettings){
@@ -168,12 +171,14 @@ void free_scene(Scene *sce)
MEM_freeN(sce->nodetree);
}
- sculptmode_free_all(sce);
+ sculptdata_free(sce);
}
Scene *add_scene(char *name)
{
Scene *sce;
+ ParticleEditSettings *pset;
+ int a;
sce= alloc_libblock(&G.main->scene, ID_SCE, name);
sce->lay= 1;
@@ -197,11 +202,14 @@ Scene *add_scene(char *name)
sce->r.images= 100;
sce->r.framelen= 1.0;
sce->r.frs_sec= 25;
+ sce->r.frs_sec_base= 1;
+ sce->r.ocres = 128;
sce->r.bake_mode= 1; /* prevent to include render stuff here */
sce->r.bake_filter= 2;
sce->r.bake_osa= 5;
sce->r.bake_flag= R_BAKE_CLEAR;
+ sce->r.bake_normal_space= R_BAKE_SPACE_TANGENT;
sce->r.xplay= 640;
sce->r.yplay= 480;
@@ -212,6 +220,15 @@ Scene *add_scene(char *name)
sce->r.stereomode = 1; // no stereo
+ sce->r.simplify_subsurf= 6;
+ sce->r.simplify_particles= 1.0f;
+ sce->r.simplify_shadowsamples= 16;
+ sce->r.simplify_aosss= 1.0f;
+
+ sce->r.cineonblack= 95;
+ sce->r.cineonwhite= 685;
+ sce->r.cineongamma= 1.7f;
+
sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings),"Tool Settings Struct");
sce->toolsettings->cornertype=1;
sce->toolsettings->degr = 90;
@@ -229,19 +246,32 @@ Scene *add_scene(char *name)
sce->toolsettings->uvcalc_mapalign = 1;
sce->toolsettings->unwrapper = 1;
sce->toolsettings->select_thresh= 0.01f;
+ sce->toolsettings->jointrilimit = 0.8f;
+
+ pset= &sce->toolsettings->particle;
+ pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
+ pset->emitterdist= 0.25f;
+ pset->totrekey= 5;
+ pset->totaddkey= 5;
+ pset->brushtype= PE_BRUSH_NONE;
+ for(a=0; a<PE_TOT_BRUSH; a++) {
+ pset->brush[a].strength= 50;
+ pset->brush[a].size= 50;
+ pset->brush[a].step= 10;
+ }
+ pset->brush[PE_BRUSH_CUT].strength= 100;
sce->jumpframe = 10;
sce->audio.mixrate = 44100;
strcpy(sce->r.backbuf, "//backbuf");
strcpy(sce->r.pic, U.renderdir);
- strcpy(sce->r.ftype, "//ftype");
BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
sce->r.osa= 8;
- sculptmode_init(sce);
-
+ sculptdata_init(sce);
+
/* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
scene_add_render_layer(sce);
@@ -477,27 +507,23 @@ void scene_select_base(Scene *sce, Base *selbase)
int scene_check_setscene(Scene *sce)
{
Scene *scene;
+ int a, totscene;
if(sce->set==NULL) return 1;
- /* LIB_DOIT is the free flag to tag library data */
+ totscene= 0;
for(scene= G.main->scene.first; scene; scene= scene->id.next)
- scene->id.flag &= ~LIB_DOIT;
-
- scene= sce;
- while(scene->set) {
- scene->id.flag |= LIB_DOIT;
- /* when set has flag set, we got a cycle */
- if(scene->set->id.flag & LIB_DOIT)
- break;
- scene= scene->set;
- }
-
- if(scene->set) {
- /* the tested scene gets zero'ed, that's typically current scene */
- sce->set= NULL;
- return 0;
+ totscene++;
+
+ for(a=0, scene=sce; scene->set; scene=scene->set, a++) {
+ /* more iterations than scenes means we have a cycle */
+ if(a > totscene) {
+ /* the tested scene gets zero'ed, that's typically current scene */
+ sce->set= NULL;
+ return 0;
+ }
}
+
return 1;
}
@@ -528,6 +554,9 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay)
{
Scene *scene= sce;
+ /* clears all BONE_UNKEYED flags for every pose's pchans */
+ framechange_poses_clear_unkeyed();
+
/* object ipos are calculated in where_is_object */
do_all_data_ipos();
@@ -538,7 +567,6 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay)
scene_update(sce, lay);
scene_update(scene, lay);
-
}
/* return default layer, also used to patch old files */
@@ -557,3 +585,161 @@ void scene_add_render_layer(Scene *sce)
srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
}
+/* Initialize 'permanent' sculpt data that is saved with file kept after
+ switching out of sculptmode. */
+void sculptdata_init(Scene *sce)
+{
+ SculptData *sd;
+
+ if(!sce)
+ return;
+
+ sd= &sce->sculptdata;
+
+ if(sd->cumap) {
+ curvemapping_free(sd->cumap);
+ sd->cumap = NULL;
+ }
+
+ memset(sd, 0, sizeof(SculptData));
+
+ sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size =
+ sd->inflatebrush.size = sd->grabbrush.size =
+ sd->layerbrush.size = sd->flattenbrush.size = 50;
+ sd->drawbrush.strength = sd->smoothbrush.strength =
+ sd->pinchbrush.strength = sd->inflatebrush.strength =
+ sd->grabbrush.strength = sd->layerbrush.strength =
+ sd->flattenbrush.strength = 25;
+ sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1;
+ sd->drawbrush.flag = sd->smoothbrush.flag =
+ sd->pinchbrush.flag = sd->inflatebrush.flag =
+ sd->layerbrush.flag = sd->flattenbrush.flag = 0;
+ sd->drawbrush.view= 0;
+ sd->brush_type= DRAW_BRUSH;
+ sd->texact= -1;
+ sd->texfade= 1;
+ sd->averaging= 1;
+ sd->texsep= 0;
+ sd->texrept= SCULPTREPT_DRAG;
+ sd->flags= SCULPT_DRAW_BRUSH;
+ sd->tablet_size=3;
+ sd->tablet_strength=10;
+ sd->rake=0;
+ sculpt_reset_curve(sd);
+}
+
+void sculptdata_free(Scene *sce)
+{
+ SculptData *sd= &sce->sculptdata;
+ int a;
+
+ sculptsession_free(sce);
+
+ for(a=0; a<MAX_MTEX; a++) {
+ MTex *mtex= sd->mtex[a];
+ if(mtex) {
+ if(mtex->tex) mtex->tex->id.us--;
+ MEM_freeN(mtex);
+ }
+ }
+
+ curvemapping_free(sd->cumap);
+ sd->cumap = NULL;
+}
+
+void sculpt_vertexusers_free(SculptSession *ss)
+{
+ if(ss && ss->vertex_users){
+ MEM_freeN(ss->vertex_users);
+ MEM_freeN(ss->vertex_users_mem);
+ ss->vertex_users= NULL;
+ ss->vertex_users_mem= NULL;
+ ss->vertex_users_size= 0;
+ }
+}
+
+void sculptsession_free(Scene *sce)
+{
+ SculptSession *ss= sce->sculptdata.session;
+ if(ss) {
+ if(ss->projverts)
+ MEM_freeN(ss->projverts);
+ if(ss->mats)
+ MEM_freeN(ss->mats);
+
+ if(ss->radialcontrol)
+ MEM_freeN(ss->radialcontrol);
+
+ sculpt_vertexusers_free(ss);
+ if(ss->texcache)
+ MEM_freeN(ss->texcache);
+ MEM_freeN(ss);
+ sce->sculptdata.session= NULL;
+ }
+}
+
+/* Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1 */
+void sculpt_reset_curve(SculptData *sd)
+{
+ CurveMap *cm = NULL;
+
+ if(!sd->cumap)
+ sd->cumap = curvemapping_add(1, 0, 0, 1, 1);
+
+ cm = sd->cumap->cm;
+
+ if(cm->curve)
+ MEM_freeN(cm->curve);
+ cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points");
+ cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ cm->totpoint= 6;
+ cm->curve[0].x= 0;
+ cm->curve[0].y= 1;
+ cm->curve[1].x= 0.1;
+ cm->curve[1].y= 0.97553;
+ cm->curve[2].x= 0.3;
+ cm->curve[2].y= 0.79389;
+ cm->curve[3].x= 0.9;
+ cm->curve[3].y= 0.02447;
+ cm->curve[4].x= 0.7;
+ cm->curve[4].y= 0.20611;
+ cm->curve[5].x= 1;
+ cm->curve[5].y= 0;
+
+ curvemapping_changed(sd->cumap, 0);
+}
+
+/* render simplification */
+
+int get_render_subsurf_level(RenderData *r, int lvl)
+{
+ if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+ return MIN2(r->simplify_subsurf, lvl);
+ else
+ return lvl;
+}
+
+int get_render_child_particle_number(RenderData *r, int num)
+{
+ if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+ return (int)(r->simplify_particles*num);
+ else
+ return num;
+}
+
+int get_render_shadow_samples(RenderData *r, int samples)
+{
+ if(G.rt == 1 && (r->mode & R_SIMPLIFY) && samples > 0)
+ return MIN2(r->simplify_shadowsamples, samples);
+ else
+ return samples;
+}
+
+float get_render_aosss_error(RenderData *r, float error)
+{
+ if(G.rt == 1 && (r->mode & R_SIMPLIFY))
+ return ((1.0f-r->simplify_aosss)*10.0f + 1.0f)*error;
+ else
+ return error;
+}
+
diff --git a/source/blender/blenkernel/intern/script.c b/source/blender/blenkernel/intern/script.c
index b99c2c51441..099fedf460a 100644
--- a/source/blender/blenkernel/intern/script.c
+++ b/source/blender/blenkernel/intern/script.c
@@ -35,7 +35,7 @@
*/
#include "BKE_script.h"
-#include "BPI_script.h"
+#include "DNA_space_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_bad_level_calls.h" /* for BPY_clear_script */
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 16a29fb8e80..834e5fad3dd 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -61,9 +61,11 @@ variables on the UI for now
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h" /* here is the softbody struct */
+#include "DNA_particle_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
@@ -75,13 +77,17 @@ variables on the UI for now
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_pointcache.h"
+#include "BKE_modifier.h"
#include "BIF_editdeform.h"
#include "BIF_graphics.h"
#include "PIL_time.h"
+// #include "ONL_opennl.h" remove linking to ONL for now
/* callbacks for errors and interrupts and some goo */
static int (*SB_localInterruptCallBack)(void) = NULL;
@@ -90,21 +96,9 @@ static int (*SB_localInterruptCallBack)(void) = NULL;
/* ********** soft body engine ******* */
-
-typedef struct BodyPoint {
- float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
- float goal;
- float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
- int nofsprings; int *springs;
- float choke;
- float colball;
- short flag;
- char octantflag;
-} BodyPoint;
-
typedef struct BodySpring {
int v1, v2;
- float len, strength, cf;
+ float len, strength, cf,load;
float ext_force[3]; /* edges colliding and sailing */
short order;
short flag;
@@ -112,7 +106,7 @@ typedef struct BodySpring {
typedef struct BodyFace {
int v1, v2, v3 ,v4;
- float ext_force[3]; /* edges colliding and sailing */
+ float ext_force[3]; /* faces colliding */
short flag;
} BodyFace;
@@ -127,6 +121,11 @@ typedef struct SBScratch {
float aabbmin[3],aabbmax[3];
}SBScratch;
+#define NLF_BUILD 1
+#define NLF_SOLVE 2
+
+#define MID_PRESERVE 1
+
#define SOFTGOALSNAP 0.999f
/* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
removes *unnecessary* stiffnes from ODE system
@@ -136,7 +135,9 @@ typedef struct SBScratch {
#define BSF_INTERSECT 1 /* edge intersects collider face */
#define SBF_DOFUZZY 1 /* edge intersects collider face */
-#define BFF_INTERSECT 1 /* edge intersects collider face */
+
+#define BFF_INTERSECT 1 /* collider edge intrudes face */
+#define BFF_CLOSEVERT 2 /* collider vertex repulses face */
float SoftHeunTol = 1.0f; /* humm .. this should be calculated from sb parameters and sizes */
@@ -480,21 +481,31 @@ void ccd_build_deflector_hache(Object *vertexowner,GHash *hash)
while (base) {
/*Only proceed for mesh object in same layer */
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
+ int particles=0;
ob= base->object;
- if((vertexowner) && (ob == vertexowner)){
- /* if vertexowner is given we don't want to check collision with owner object */
- base = base->next;
- continue;
+ if((vertexowner) && (ob == vertexowner)) {
+ if(vertexowner->soft->particles){
+ particles=1;
+ }
+ else {
+ /* if vertexowner is given we don't want to check collision with owner object */
+ base = base->next;
+ continue;
+ }
}
/*+++ only with deflecting set */
if(ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == 0) {
DerivedMesh *dm= NULL;
-
- if(ob->softflag & OB_SB_COLLFINAL) { /* so maybe someone wants overkill to collide with subsurfed */
- dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
- } else {
- dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
+
+ if(particles) {
+ dm = psys_get_modifier(ob,psys_get_current(ob))->dm;
+ }
+ else {
+ if(ob->softflag & OB_SB_COLLFINAL) /* so maybe someone wants overkill to collide with subsurfed */
+ dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
+ else
+ dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
}
if(dm){
@@ -582,6 +593,7 @@ static void add_mesh_quad_diag_springs(Object *ob)
if (ob->soft){
int nofquads;
+ float s_shear = ob->soft->shearstiff*ob->soft->shearstiff;
nofquads = count_mesh_quads(me);
if (nofquads) {
@@ -602,12 +614,12 @@ static void add_mesh_quad_diag_springs(Object *ob)
if(mface->v4) {
bs->v1= mface->v1;
bs->v2= mface->v3;
- bs->strength= 1.0;
+ bs->strength= s_shear;
bs->order =2;
bs++;
bs->v1= mface->v2;
bs->v2= mface->v4;
- bs->strength= 1.0;
+ bs->strength= s_shear;
bs->order =2;
bs++;
@@ -689,6 +701,7 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
{
int counter = 0;
BodySpring *bs_new;
+ stiffness *=stiffness;
add_2nd_order_roller(ob,stiffness,&counter,0); /* counting */
if (counter) {
@@ -782,80 +795,37 @@ static void calculate_collision_balls(Object *ob)
}
if (akku_count > 0) {
- if (sb->sbc_mode == 0){
+ if (sb->sbc_mode == SBC_MODE_MANUAL){
bp->colball=sb->colball;
- }
- if (sb->sbc_mode == 1){
- bp->colball = akku/(float)akku_count*sb->colball;
}
- if (sb->colball == 2){
+ if (sb->sbc_mode == SBC_MODE_AVG){
+ bp->colball = akku/(float)akku_count*sb->colball;
+ }
+ if (sb->sbc_mode == SBC_MODE_MIN){
bp->colball=min*sb->colball;
- }
- if (sb->colball == 3){
+ }
+ if (sb->sbc_mode == SBC_MODE_MAX){
bp->colball=max*sb->colball;
- }
- if (sb->colball == 4){
- bp->colball = (min + max)/2.0f*sb->colball;
- }
+ }
+ if (sb->sbc_mode == SBC_MODE_AVGMINMAX){
+ bp->colball = (min + max)/2.0f*sb->colball;
+ }
}
else bp->colball=0;
}/*for bp*/
}
-char set_octant_flags(float *ce, float *pos, float ball)
-{
- float x,y,z;
- char res = 0;
- int a;
-
- for (a=0;a<7;a++){
- switch(a){
- case 0: x=pos[0]; y=pos[1]; z=pos[2]; break;
- case 1: x=pos[0]+ball; y=pos[1]; z=pos[2]; break;
- case 2: x=pos[0]-ball; y=pos[1]; z=pos[2]; break;
- case 3: x=pos[0]; y=pos[1]+ball; z=pos[2]; break;
- case 4: x=pos[0]; y=pos[1]-ball; z=pos[2]; break;
- case 5: x=pos[0]; y=pos[1]; z=pos[2]+ball; break;
- case 6: x=pos[0]; y=pos[1]; z=pos[2]-ball; break;
- }
-
- x=pos[0]; y=pos[1]; z=pos[2];
-
- if (x > ce[0]){
- if (y > ce[1]){
- if (z > ce[2]) res|= 1;
- else res|= 2;
- }
- else{
- if (z > ce[2]) res|= 4;
- else res|= 8;
- }
- }
-
- else{
- if (y > ce[1]){
- if (z > ce[2]) res|= 16;
- else res|= 32;
- }
- else{
- if (z > ce[2]) res|= 64;
- else res|= 128;
- }
- }
- }
- return res;
-}
-
/* creates new softbody if didn't exist yet, makes new points and springs arrays */
static void renew_softbody(Object *ob, int totpoint, int totspring)
{
SoftBody *sb;
int i;
-
+ short softflag;
if(ob->soft==NULL) ob->soft= sbNew();
else free_softbody_intern(ob->soft);
sb= ob->soft;
+ softflag=ob->softflag;
if(totpoint) {
sb->totpoint= totpoint;
@@ -869,8 +839,8 @@ static void renew_softbody(Object *ob, int totpoint, int totspring)
for (i=0; i<totpoint; i++) {
BodyPoint *bp = &sb->bpoint[i];
- if(ob->softflag & OB_SB_GOAL) {
- bp->goal= ob->soft->defgoal;
+ if(softflag & OB_SB_GOAL) {
+ bp->goal= sb->defgoal;
}
else {
bp->goal= 0.0f;
@@ -880,6 +850,8 @@ static void renew_softbody(Object *ob, int totpoint, int totspring)
bp->nofsprings= 0;
bp->springs= NULL;
bp->choke = 0.0f;
+ bp->choke2 = 0.0f;
+ bp->frozen = 1.0f;
bp->colball = 0.0f;
bp->flag = 0;
@@ -900,7 +872,6 @@ static void free_softbody_baked(SoftBody *sb)
sb->keys= NULL;
sb->totkey= 0;
-
}
static void free_scratch(SoftBody *sb)
{
@@ -985,6 +956,7 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
}
/* +++ dependancy information functions*/
+
static int are_there_deflectors(unsigned int layer)
{
Base *base;
@@ -1002,38 +974,9 @@ static int query_external_colliders(Object *me)
{
return(are_there_deflectors(me->lay));
}
-
-#if 0
-static int query_external_forces(Object *me)
-{
-/* silly but true: we need to create effector cache to see if anything is in it */
- ListBase *ec = pdInitEffectors(me,NULL);
- int result = 0;
- if (ec){
- result = 1;
- pdEndEffectors(ec); /* sorry ec, yes i'm an idiot, but i needed to know if you were there */
- }
- return result;
-}
-
-/*
-any of that external objects may have an IPO or something alike ..
-so unless we can ask them if they are moving we have to assume they do
-*/
-static int query_external_time(Object *me)
-{
- if (query_external_colliders(me)) return 1;
- if (query_external_forces(me)) return 1;
- return 0;
-}
-static int query_internal_time(Object *me)
-{
- if (me->softflag & OB_SB_GOAL) return 1;
- return 0;
-}
-#endif
/* --- dependancy information functions*/
+
/* +++ the aabb "force" section*/
int sb_detect_aabb_collisionCached( float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
{
@@ -1099,6 +1042,103 @@ int sb_detect_aabb_collisionCached( float force[3], unsigned int par_layer,struc
/* +++ the face external section*/
+int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
+ float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
+ {
+ Object *ob;
+ GHash *hash;
+ GHashIterator *ihash;
+ float nv1[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3],aabbmax[3];
+ float facedist,outerfacethickness,tune = 10.f;
+ int a, deflected=0;
+
+ aabbmin[0] = MIN3(face_v1[0],face_v2[0],face_v3[0]);
+ aabbmin[1] = MIN3(face_v1[1],face_v2[1],face_v3[1]);
+ aabbmin[2] = MIN3(face_v1[2],face_v2[2],face_v3[2]);
+ aabbmax[0] = MAX3(face_v1[0],face_v2[0],face_v3[0]);
+ aabbmax[1] = MAX3(face_v1[1],face_v2[1],face_v3[1]);
+ aabbmax[2] = MAX3(face_v1[2],face_v2[2],face_v3[2]);
+
+ /* calculate face normal once again SIGH */
+ VECSUB(edge1, face_v1, face_v2);
+ VECSUB(edge2, face_v3, face_v2);
+ Crossf(d_nvect, edge2, edge1);
+ Normalize(d_nvect);
+
+
+ hash = vertexowner->soft->scratch->colliderhash;
+ ihash = BLI_ghashIterator_new(hash);
+ while (!BLI_ghashIterator_isDone(ihash) ) {
+
+ ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
+ ob = BLI_ghashIterator_getKey (ihash);
+ /* only with deflecting set */
+ if(ob->pd && ob->pd->deflect) {
+ MVert *mvert= NULL;
+ MVert *mprevvert= NULL;
+ if(ccdm){
+ mvert= ccdm->mvert;
+ a = ccdm->totvert;
+ mprevvert= ccdm->mprevvert;
+ outerfacethickness =ob->pd->pdef_sboft;
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
+ (aabbmax[1] < ccdm->bbmin[1]) ||
+ (aabbmax[2] < ccdm->bbmin[2]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[2] > ccdm->bbmax[2]) ) {
+ /* boxes dont intersect */
+ BLI_ghashIterator_step(ihash);
+ continue;
+ }
+
+ }
+ else{
+ /*aye that should be cached*/
+ printf("missing cache error \n");
+ BLI_ghashIterator_step(ihash);
+ continue;
+ }
+
+
+ /* use mesh*/
+ if (mvert) {
+ while(a){
+ VECCOPY(nv1,mvert[a-1].co);
+ if(mprevvert){
+ VecMulf(nv1,time);
+ Vec3PlusStVec(nv1,(1.0f-time),mprevvert[a-1].co);
+ }
+ /* origin to face_v2*/
+ VECSUB(nv1, nv1, face_v2);
+ facedist = Inpf(nv1,d_nvect);
+ if (ABS(facedist)<outerfacethickness){
+ if (point_in_tri_prism(nv1, face_v1,face_v2,face_v3) ){
+ float df;
+ if (facedist > 0){
+ df = (outerfacethickness-facedist)/outerfacethickness;
+ }
+ else {
+ df = (outerfacethickness+facedist)/outerfacethickness;
+ }
+
+ *damp=df*tune*ob->pd->pdef_sbdamp;
+
+ df = 0.01f*exp(- 100.0f*df);
+ Vec3PlusStVec(force,-df,d_nvect);
+ deflected = 3;
+ }
+ }
+ a--;
+ }/* while(a)*/
+ } /* if (mvert) */
+ } /* if(ob->pd && ob->pd->deflect) */
+ BLI_ghashIterator_step(ihash);
+ } /* while () */
+ BLI_ghashIterator_free(ihash);
+ return deflected;
+}
+
int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
@@ -1107,7 +1147,7 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_
GHash *hash;
GHashIterator *ihash;
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3],aabbmax[3];
- float t;
+ float t,tune = 10.0f;
int a, deflected=0;
aabbmin[0] = MIN3(face_v1[0],face_v2[0],face_v3[0]);
@@ -1203,11 +1243,11 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_
Crossf(d_nvect, edge2, edge1);
Normalize(d_nvect);
if (
- LineIntersectsTriangle(nv1, nv2, face_v1, face_v2, face_v3, &t) ||
- LineIntersectsTriangle(nv2, nv3, face_v1, face_v2, face_v3, &t) ||
- LineIntersectsTriangle(nv3, nv1, face_v1, face_v2, face_v3, &t) ){
- Vec3PlusStVec(force,-1.0f,d_nvect);
- *damp=ob->pd->pdef_sbdamp;
+ LineIntersectsTriangle(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
+ LineIntersectsTriangle(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
+ LineIntersectsTriangle(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) ){
+ Vec3PlusStVec(force,-0.5f,d_nvect);
+ *damp=tune*ob->pd->pdef_sbdamp;
deflected = 2;
}
if (mface->v4){ /* quad */
@@ -1217,11 +1257,12 @@ int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_
Crossf(d_nvect, edge2, edge1);
Normalize(d_nvect);
if (
- LineIntersectsTriangle(nv1, nv3, face_v1, face_v2, face_v3, &t) ||
- LineIntersectsTriangle(nv3, nv4, face_v1, face_v2, face_v3, &t) ||
- LineIntersectsTriangle(nv4, nv1, face_v1, face_v2, face_v3, &t) ){
- Vec3PlusStVec(force,-1.0f,d_nvect);
- *damp=ob->pd->pdef_sbdamp;
+ /* LineIntersectsTriangle(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
+ we did that edge allready */
+ LineIntersectsTriangle(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) ||
+ LineIntersectsTriangle(nv4, nv1, face_v1, face_v2, face_v3, &t, NULL) ){
+ Vec3PlusStVec(force,-0.5f,d_nvect);
+ *damp=tune*ob->pd->pdef_sbdamp;
deflected = 2;
}
}
@@ -1242,7 +1283,7 @@ void scan_for_ext_face_forces(Object *ob,float timenow)
SoftBody *sb = ob->soft;
BodyFace *bf;
int a;
- float damp;
+ float damp=0.0f,choke=1.0f;
float tune = -10.0f;
float feedback[3];
@@ -1252,43 +1293,71 @@ void scan_for_ext_face_forces(Object *ob,float timenow)
bf = sb->scratch->bodyface;
for(a=0; a<sb->scratch->totface; a++, bf++) {
bf->ext_force[0]=bf->ext_force[1]=bf->ext_force[2]=0.0f;
+/*+++edges intruding*/
+ bf->flag &= ~BFF_INTERSECT;
feedback[0]=feedback[1]=feedback[2]=0.0f;
- bf->flag &= ~BFF_INTERSECT;
-
if (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
&damp, feedback, ob->lay ,ob , timenow)){
- Vec3PlusStVec(bf->ext_force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v2].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
+// Vec3PlusStVec(bf->ext_force,tune,feedback);
bf->flag |= BFF_INTERSECT;
+ choke = MIN2(MAX2(damp,choke),1.0f);
}
feedback[0]=feedback[1]=feedback[2]=0.0f;
if ((bf->v4) && (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
&damp, feedback, ob->lay ,ob , timenow))){
- Vec3PlusStVec(bf->ext_force,tune,feedback);
- bf->flag |= BFF_INTERSECT;
+ Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v4].force,tune,feedback);
+// Vec3PlusStVec(bf->ext_force,tune,feedback);
+ bf->flag |= BFF_INTERSECT;
+ choke = MIN2(MAX2(damp,choke),1.0f);
}
- }
+/*---edges intruding*/
+
+/*+++ close vertices*/
+ if (( bf->flag & BFF_INTERSECT)==0){
+ bf->flag &= ~BFF_CLOSEVERT;
+ tune = -1.0f;
+ feedback[0]=feedback[1]=feedback[2]=0.0f;
+ if (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
+ &damp, feedback, ob->lay ,ob , timenow)){
+ Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v2].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
+// Vec3PlusStVec(bf->ext_force,tune,feedback);
+ bf->flag |= BFF_CLOSEVERT;
+ choke = MIN2(MAX2(damp,choke),1.0f);
+ }
-
-
+ feedback[0]=feedback[1]=feedback[2]=0.0f;
+ if ((bf->v4) && (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
+ &damp, feedback, ob->lay ,ob , timenow))){
+ Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
+ Vec3PlusStVec(sb->bpoint[bf->v4].force,tune,feedback);
+// Vec3PlusStVec(bf->ext_force,tune,feedback);
+ bf->flag |= BFF_CLOSEVERT;
+ choke = MIN2(MAX2(damp,choke),1.0f);
+ }
+ }
+/*--- close vertices*/
+ }
bf = sb->scratch->bodyface;
for(a=0; a<sb->scratch->totface; a++, bf++) {
- if ( bf->flag & BFF_INTERSECT)
+ if (( bf->flag & BFF_INTERSECT) || ( bf->flag & BFF_CLOSEVERT))
{
- VECADD(sb->bpoint[bf->v1].force,sb->bpoint[bf->v1].force,bf->ext_force);
- VECADD(sb->bpoint[bf->v2].force,sb->bpoint[bf->v2].force,bf->ext_force);
- VECADD(sb->bpoint[bf->v3].force,sb->bpoint[bf->v3].force,bf->ext_force);
+ sb->bpoint[bf->v1].choke2=MAX2(sb->bpoint[bf->v1].choke2,choke);
+ sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
+ sb->bpoint[bf->v3].choke2=MAX2(sb->bpoint[bf->v3].choke2,choke);
if (bf->v4){
- VECADD(sb->bpoint[bf->v4].force,sb->bpoint[bf->v4].force,bf->ext_force);
+ sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
}
-
- }
-
+ }
}
-
-
-
-
}
}
@@ -1402,7 +1471,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
Crossf(d_nvect, edge2, edge1);
Normalize(d_nvect);
- if ( LineIntersectsTriangle(edge_v1, edge_v2, nv1, nv2, nv3, &t)){
+ if ( LineIntersectsTriangle(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)){
float v1[3],v2[3];
float intrusiondepth,i1,i2;
VECSUB(v1, edge_v1, nv2);
@@ -1421,7 +1490,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
Crossf(d_nvect, edge2, edge1);
Normalize(d_nvect);
- if (LineIntersectsTriangle( edge_v1, edge_v2,nv1, nv3, nv4, &t)){
+ if (LineIntersectsTriangle( edge_v1, edge_v2,nv1, nv3, nv4, &t, NULL)){
float v1[3],v2[3];
float intrusiondepth,i1,i2;
VECSUB(v1, edge_v1, nv4);
@@ -1447,6 +1516,7 @@ int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp
}
+
void scan_for_ext_spring_forces(Object *ob,float timenow)
{
SoftBody *sb = ob->soft;
@@ -1498,14 +1568,20 @@ void scan_for_ext_spring_forces(Object *ob,float timenow)
}
f = Normalize(vel);
f = -0.0001f*f*f*sb->aeroedge;
- /* todo add a nice angle dependant function */
- /* look up one at bergman scheafer */
+ /* (todo) add a nice angle dependant function done for now BUT */
+ /* still there could be some nice drag/lift function, but who needs it */
VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
Projf(pr,vel,sp);
VECSUB(vel,vel,pr);
Normalize(vel);
- Vec3PlusStVec(bs->ext_force,f,vel);
+ if (ob->softflag & OB_SB_AERO_ANGLE){
+ Normalize(sp);
+ Vec3PlusStVec(bs->ext_force,f*(1.0f-ABS(Inpf(vel,sp))),vel);
+ }
+ else{
+ Vec3PlusStVec(bs->ext_force,f,vel); // to keep compatible with 2.45 release files
+ }
}
/* --- springs seeing wind */
}
@@ -1547,19 +1623,22 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
float force[3], unsigned int par_layer,struct Object *vertexowner,
float time,float vel[3], float *intrusion)
{
- Object *ob;
+ Object *ob= NULL;
GHash *hash;
GHashIterator *ihash;
- float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3],
- vv1[3], vv2[3], vv3[3], vv4[3],
+ float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3]={0.0,0.0,0.0},
+ vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f,
+ outerforceaccu[3],innerforceaccu[3],
facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
innerfacethickness = -0.5f, outerfacethickness = 0.2f,
- ee = 5.0f, ff = 0.1f, fa;
+ ee = 5.0f, ff = 0.1f, fa=1;
int a, deflected=0, cavel=0,ci=0;
/* init */
*intrusion = 0.0f;
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
+ outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
+ innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
/* go */
while (!BLI_ghashIterator_isDone(ihash) ) {
@@ -1675,16 +1754,24 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
Crossf(d_nvect, edge2, edge1);
n_mag = Normalize(d_nvect);
facedist = Inpf(dv1,d_nvect);
+ // so rules are
+ //
if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
if (point_in_tri_prism(opco, nv1, nv2, nv3) ){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
*damp=ob->pd->pdef_sbdamp;
if (facedist > 0.0f){
*damp *= (1.0f - facedist/outerfacethickness);
+ Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+ deflected = 3;
+
+ }
+ else {
+ Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+ if (deflected < 2) deflected = 2;
}
if ((mprevvert) && (*damp > 0.0f)){
choose_winner(ve,opco,nv1,nv2,nv3,vv1,vv2,vv3);
@@ -1693,7 +1780,6 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
}
*intrusion += facedist;
ci++;
- deflected = 2;
}
}
if (mface->v4){ /* quad */
@@ -1711,11 +1797,17 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
*damp=ob->pd->pdef_sbdamp;
- if (facedist > 0.0f){
- *damp *= (1.0f - facedist/outerfacethickness);
- }
+ if (facedist > 0.0f){
+ *damp *= (1.0f - facedist/outerfacethickness);
+ Vec3PlusStVec(outerforceaccu,force_mag_norm,d_nvect);
+ deflected = 3;
+
+ }
+ else {
+ Vec3PlusStVec(innerforceaccu,force_mag_norm,d_nvect);
+ if (deflected < 2) deflected = 2;
+ }
if ((mprevvert) && (*damp > 0.0f)){
choose_winner(ve,opco,nv1,nv3,nv4,vv1,vv3,vv4);
@@ -1724,248 +1816,61 @@ int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float *
}
*intrusion += facedist;
ci++;
- deflected = 2;
}
}
- }
- mface++;
- mima++;
- }/* while a */
- } /* if(ob->pd && ob->pd->deflect) */
- BLI_ghashIterator_step(ihash);
- } /* while () */
- BLI_ghashIterator_free(ihash);
- if (cavel) VecMulf(avel,1.0f/(float)cavel);
- VECCOPY(vel,avel);
- if (ci) *intrusion /= ci;
- if (deflected){
- VECCOPY(facenormal,force);
- Normalize(facenormal);
- }
- return deflected;
-}
-
-/* not complete yet ..
- try to find a pos resolving all inside collisions
-*/
-#if 0 //mute it for now
-int sb_detect_vertex_collisionCachedEx(float opco[3], float facenormal[3], float *damp,
- float force[3], unsigned int par_layer,struct Object *vertexowner,
- float time,float vel[3], float *intrusion)
-{
- Object *ob;
- GHash *hash;
- GHashIterator *ihash;
- float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3],
- vv1[3], vv2[3], vv3[3], vv4[3],
- facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
- innerfacethickness,outerfacethickness,
- closestinside,
- ee = 5.0f, ff = 0.1f, fa;
- int a, deflected=0, cavel=0;
-/* init */
- *intrusion = 0.0f;
- hash = vertexowner->soft->scratch->colliderhash;
- ihash = BLI_ghashIterator_new(hash);
-/* go */
- while (!BLI_ghashIterator_isDone(ihash) ) {
-
- ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
- ob = BLI_ghashIterator_getKey (ihash);
- /* only with deflecting set */
- if(ob->pd && ob->pd->deflect) {
- MFace *mface= NULL;
- MVert *mvert= NULL;
- MVert *mprevvert= NULL;
- ccdf_minmax *mima= NULL;
-
- if(ccdm){
- mface= ccdm->mface;
- mvert= ccdm->mvert;
- mprevvert= ccdm->mprevvert;
- mima= ccdm->mima;
- a = ccdm->totface;
-
- minx =ccdm->bbmin[0];
- miny =ccdm->bbmin[1];
- minz =ccdm->bbmin[2];
-
- maxx =ccdm->bbmax[0];
- maxy =ccdm->bbmax[1];
- maxz =ccdm->bbmax[2];
-
- if ((opco[0] < minx) ||
- (opco[1] < miny) ||
- (opco[2] < minz) ||
- (opco[0] > maxx) ||
- (opco[1] > maxy) ||
- (opco[2] > maxz) ) {
- /* outside the padded boundbox --> collision object is too far away */
- BLI_ghashIterator_step(ihash);
- continue;
- }
- }
- else{
- /*aye that should be cached*/
- printf("missing cache error \n");
- BLI_ghashIterator_step(ihash);
- continue;
- }
-
- /* do object level stuff */
- /* need to have user control for that since it depends on model scale */
- innerfacethickness =-ob->pd->pdef_sbift;
- outerfacethickness =ob->pd->pdef_sboft;
- closestinside = innerfacethickness;
- fa = (ff*outerfacethickness-outerfacethickness);
- fa *= fa;
- fa = 1.0f/fa;
- avel[0]=avel[1]=avel[2]=0.0f;
- /* use mesh*/
- while (a--) {
- if (
- (opco[0] < mima->minx) ||
- (opco[0] > mima->maxx) ||
- (opco[1] < mima->miny) ||
- (opco[1] > mima->maxy) ||
- (opco[2] < mima->minz) ||
- (opco[2] > mima->maxz)
- ) {
- mface++;
- mima++;
- continue;
- }
-
- if (mvert){
-
- VECCOPY(nv1,mvert[mface->v1].co);
- VECCOPY(nv2,mvert[mface->v2].co);
- VECCOPY(nv3,mvert[mface->v3].co);
- if (mface->v4){
- VECCOPY(nv4,mvert[mface->v4].co);
- }
-
- if (mprevvert){
- /* grab the average speed of the collider vertices
- before we spoil nvX
- humm could be done once a SB steps but then we' need to store that too
- since the AABB reduced propabitlty to get here drasticallly
- it might be a nice tradeof CPU <--> memory
- */
- VECSUB(vv1,nv1,mprevvert[mface->v1].co);
- VECSUB(vv2,nv2,mprevvert[mface->v2].co);
- VECSUB(vv3,nv3,mprevvert[mface->v3].co);
- if (mface->v4){
- VECSUB(vv4,nv4,mprevvert[mface->v4].co);
+ if ((deflected < 2)&& (G.rt != 444)) // we did not hit a face until now
+ { // see if 'outer' hits an edge
+ float dist;
+
+ PclosestVL3Dfl(ve, opco, nv1, nv2);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
}
- VecMulf(nv1,time);
- Vec3PlusStVec(nv1,(1.0f-time),mprevvert[mface->v1].co);
-
- VecMulf(nv2,time);
- Vec3PlusStVec(nv2,(1.0f-time),mprevvert[mface->v2].co);
-
- VecMulf(nv3,time);
- Vec3PlusStVec(nv3,(1.0f-time),mprevvert[mface->v3].co);
-
- if (mface->v4){
- VecMulf(nv4,time);
- Vec3PlusStVec(nv4,(1.0f-time),mprevvert[mface->v4].co);
+ PclosestVL3Dfl(ve, opco, nv2, nv3);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
}
- }
- }
-
- /* switch origin to be nv2*/
- VECSUB(edge1, nv1, nv2);
- VECSUB(edge2, nv3, nv2);
- VECSUB(dv1,opco,nv2); /* abuse dv1 to have vertex in question at *origin* of triangle */
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalize(d_nvect);
- facedist = Inpf(dv1,d_nvect);
-
- if ((facedist > closestinside) && (facedist < outerfacethickness)){
-// if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- if (point_in_tri_prism(opco, nv1, nv2, nv3) ){
- force_mag_norm =(float)exp(-ee*facedist);
- if (facedist > outerfacethickness*ff)
- force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- *damp=ob->pd->pdef_sbdamp;
-
- if (facedist > 0.0f){
- *damp *= (1.0f - facedist/outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
- if (deflected < 2){
- deflected = 1;
- if ((mprevvert) && (*damp > 0.0f)){
- choose_winner(ve,opco,nv1,nv2,nv3,vv1,vv2,vv3);
- VECADD(avel,avel,ve);
- cavel ++;
- }
- }
-
- }
- else{
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
- VECCOPY(facenormal,d_nvect);
- if ((mprevvert) && (*damp > 0.0f)){
- choose_winner(avel,opco,nv1,nv2,nv3,vv1,vv2,vv3);
- cavel = 1;
- deflected = 2;
- closestinside = facedist;
- }
+ PclosestVL3Dfl(ve, opco, nv3, nv1);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
+ }
+ if (mface->v4){ /* quad */
+ PclosestVL3Dfl(ve, opco, nv3, nv4);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
}
- *intrusion = facedist;
- }
- }
- if (mface->v4){ /* quad */
- /* switch origin to be nv4 */
- VECSUB(edge1, nv3, nv4);
- VECSUB(edge2, nv1, nv4);
- VECSUB(dv1,opco,nv4); /* abuse dv1 to have vertex in question at *origin* of triangle */
-
- Crossf(d_nvect, edge2, edge1);
- n_mag = Normalize(d_nvect);
- facedist = Inpf(dv1,d_nvect);
-
- if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
- if (point_in_tri_prism(opco, nv1, nv3, nv4) ){
- force_mag_norm =(float)exp(-ee*facedist);
- if (facedist > outerfacethickness*ff)
- force_mag_norm =(float)force_mag_norm*fa*(facedist - outerfacethickness)*(facedist - outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
- *damp=ob->pd->pdef_sbdamp;
- if (facedist > 0.0f){
- *damp *= (1.0f - facedist/outerfacethickness);
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
- if (deflected < 2){
- deflected = 1;
- if ((mprevvert) && (*damp > 0.0f)){
- choose_winner(ve,opco,nv1,nv3,nv4,vv1,vv3,vv4);
- VECADD(avel,avel,ve);
- cavel ++;
- }
- }
-
- }
- else{
- Vec3PlusStVec(force,force_mag_norm,d_nvect);
- VECCOPY(facenormal,d_nvect);
- if ((mprevvert) && (*damp > 0.0f)){
- choose_winner(avel,opco,nv1,nv3,nv4,vv1,vv3,vv4);
- cavel = 1;
- deflected = 2;
- closestinside = facedist;
- }
+ PclosestVL3Dfl(ve, opco, nv1, nv4);
+ VECSUB(ve,opco,ve);
+ dist = Normalize(ve);
+ if ((dist < outerfacethickness)&&(dist < mindistedge )){
+ VECCOPY(coledge,ve);
+ mindistedge = dist,
+ deflected=1;
}
-
-
-
- *intrusion = facedist;
+
}
+
}
}
mface++;
@@ -1974,24 +1879,35 @@ int sb_detect_vertex_collisionCachedEx(float opco[3], float facenormal[3], float
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
+
+ if (deflected == 1){ // no face but 'outer' edge cylinder sees vert
+ force_mag_norm =(float)exp(-ee*mindistedge);
+ if (mindistedge > outerfacethickness*ff)
+ force_mag_norm =(float)force_mag_norm*fa*(mindistedge - outerfacethickness)*(mindistedge - outerfacethickness);
+ Vec3PlusStVec(force,force_mag_norm,coledge);
+ *damp=ob->pd->pdef_sbdamp;
+ if (mindistedge > 0.0f){
+ *damp *= (1.0f - mindistedge/outerfacethickness);
+ }
+
+ }
+ if (deflected == 2){ // face inner detected
+ VECADD(force,force,innerforceaccu);
+ }
+ if (deflected == 3){ // face outer detected
+ VECADD(force,force,outerforceaccu);
+ }
+
BLI_ghashIterator_free(ihash);
if (cavel) VecMulf(avel,1.0f/(float)cavel);
VECCOPY(vel,avel);
-
- /* we did stay "outside" but have some close to contact forces
- just to be complete fake a face normal
- */
- if (deflected ==1){
+ if (ci) *intrusion /= ci;
+ if (deflected){
VECCOPY(facenormal,force);
Normalize(facenormal);
- }
- else{
- facenormal[0] = facenormal[1] = facenormal[2] = 0.0f;
}
return deflected;
}
-#endif
-
/* sandbox to plug in various deflection algos */
@@ -2005,8 +1921,112 @@ static int sb_deflect_face(Object *ob,float *actpos,float *facenormal,float *for
return(deflected);
}
+/* hiding this for now .. but the jacobian may pop up on other tasks .. so i'd like to keep it
+static void dfdx_spring(int ia, int ic, int op, float dir[3],float L,float len,float factor)
+{
+ float m,delta_ij;
+ int i ,j;
+ if (L < len){
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++){
+ delta_ij = (i==j ? (1.0f): (0.0f));
+ m=factor*(dir[i]*dir[j] + (1-L/len)*(delta_ij - dir[i]*dir[j]));
+ nlMatrixAdd(ia+i,op+ic+j,m);
+ }
+ }
+ else{
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++){
+ m=factor*dir[i]*dir[j];
+ nlMatrixAdd(ia+i,op+ic+j,m);
+ }
+ }
+}
+
-static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
+static void dfdx_goal(int ia, int ic, int op, float factor)
+{
+ int i;
+ for(i=0;i<3;i++) nlMatrixAdd(ia+i,op+ic+i,factor);
+}
+
+static void dfdv_goal(int ia, int ic,float factor)
+{
+ int i;
+ for(i=0;i<3;i++) nlMatrixAdd(ia+i,ic+i,factor);
+}
+*/
+static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ BodyPoint *bp1,*bp2;
+
+ float dir[3],dvel[3];
+ float distance,forcefactor,kd,absvel,projvel;
+ int ia,ic;
+ /* prepare depending on which side of the spring we are on */
+ if (bpi == bs->v1){
+ bp1 = &sb->bpoint[bs->v1];
+ bp2 = &sb->bpoint[bs->v2];
+ ia =3*bs->v1;
+ ic =3*bs->v2;
+ }
+ else if (bpi == bs->v2){
+ bp1 = &sb->bpoint[bs->v2];
+ bp2 = &sb->bpoint[bs->v1];
+ ia =3*bs->v2;
+ ic =3*bs->v1;
+ }
+ else{
+ /* TODO make this debug option */
+ /**/
+ printf("bodypoint <bpi> is not attached to spring <*bs> --> sb_spring_force()\n");
+ return;
+ }
+
+ /* do bp1 <--> bp2 elastic */
+ VecSubf(dir,bp1->pos,bp2->pos);
+ distance = Normalize(dir);
+ if (bs->len < distance)
+ iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
+ else
+ iks = 1.0f/(1.0f-sb->inpush)-1.0f ;/* inner spring constants function */
+
+ if(bs->len > 0.0f) /* check for degenerated springs */
+ forcefactor = iks/bs->len;
+ else
+ forcefactor = iks;
+ forcefactor *= bs->strength;
+ Vec3PlusStVec(bp1->force,(bs->len - distance)*forcefactor,dir);
+
+ /* do bp1 <--> bp2 viscous */
+ VecSubf(dvel,bp1->vec,bp2->vec);
+ kd = sb->infrict * sb_fric_force_scale(ob);
+ absvel = Normalize(dvel);
+ projvel = Inpf(dir,dvel);
+ kd *= absvel * projvel;
+ Vec3PlusStVec(bp1->force,-kd,dir);
+
+ /* do jacobian stuff if needed */
+ if(nl_flags & NLF_BUILD){
+ //int op =3*sb->totpoint;
+ //float mvel = -forcetime*kd;
+ //float mpos = -forcetime*forcefactor;
+ /* depending on my pos */
+ // dfdx_spring(ia,ia,op,dir,bs->len,distance,-mpos);
+ /* depending on my vel */
+ // dfdv_goal(ia,ia,mvel); // well that ignores geometie
+ if(bp2->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
+ /* depending on other pos */
+ // dfdx_spring(ia,ic,op,dir,bs->len,distance,mpos);
+ /* depending on other vel */
+ // dfdv_goal(ia,ia,-mvel); // well that ignores geometie
+ }
+ }
+}
+
+
+static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int nl_flags)
{
/* rule we never alter free variables :bp->vec bp->pos in here !
* this will ruin adaptive stepsize AKA heun! (BM)
@@ -2016,10 +2036,20 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
BodyPoint *bproot;
BodySpring *bs;
ListBase *do_effector;
- float iks, ks, kd, gravity, actspringlen, forcefactor, sd[3];
+ float iks, ks, kd, gravity;
float fieldfactor = 1000.0f, windfactor = 250.0f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
+
+
+/* jacobian
+ NLboolean success;
+
+ if(nl_flags){
+ nlBegin(NL_SYSTEM);
+ nlBegin(NL_MATRIX);
+ }
+*/
gravity = sb->grav * sb_grav_force_scale(ob);
@@ -2042,17 +2072,29 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
}
- if (do_selfcollision ){
- float ce[3];
- VecMidf(ce,sb->scratch->aabbmax,sb->scratch->aabbmin);
- for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- bp->octantflag = set_octant_flags(ce,bp->pos,bp->colball);
- }
- }
-
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* clear forces accumulator */
bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
+ if(nl_flags & NLF_BUILD){
+ //int ia =3*(sb->totpoint-a);
+ //int op =3*sb->totpoint;
+ /* dF/dV = v */
+ /* jacobioan
+ nlMatrixAdd(op+ia,ia,-forcetime);
+ nlMatrixAdd(op+ia+1,ia+1,-forcetime);
+ nlMatrixAdd(op+ia+2,ia+2,-forcetime);
+
+ nlMatrixAdd(ia,ia,1);
+ nlMatrixAdd(ia+1,ia+1,1);
+ nlMatrixAdd(ia+2,ia+2,1);
+
+ nlMatrixAdd(op+ia,op+ia,1);
+ nlMatrixAdd(op+ia+1,op+ia+1,1);
+ nlMatrixAdd(op+ia+2,op+ia+2,1);
+ */
+
+
+ }
/* naive ball self collision */
/* needs to be done if goal snaps or not */
@@ -2066,7 +2108,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
for(c=sb->totpoint, obp= sb->bpoint; c>=a; c--, obp++) {
- if ((bp->octantflag & obp->octantflag) == 0) continue;
+ //if ((bp->octantflag & obp->octantflag) == 0) continue;
compare = (obp->colball + bp->colball);
VecSubf(def, bp->pos, obp->pos);
@@ -2092,8 +2134,33 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
VecSubf(dvel,velcenter,bp->vec);
VecMulf(dvel,sb->nodemass);
- Vec3PlusStVec(bp->force,sb->balldamp,dvel);
Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
+ Vec3PlusStVec(bp->force,sb->balldamp,dvel);
+
+ if(nl_flags & NLF_BUILD){
+ //int ia =3*(sb->totpoint-a);
+ //int ic =3*(sb->totpoint-c);
+ //int op =3*sb->totpoint;
+ //float mvel = forcetime*sb->nodemass*sb->balldamp;
+ //float mpos = forcetime*tune*(1.0f-sb->balldamp);
+ /*some quick and dirty entries to the jacobian*/
+ //dfdx_goal(ia,ia,op,mpos);
+ //dfdv_goal(ia,ia,mvel);
+ /* exploit force(a,b) == -force(b,a) part1/2 */
+ //dfdx_goal(ic,ic,op,mpos);
+ //dfdv_goal(ic,ic,mvel);
+
+
+ /*TODO sit down an X-out the true jacobian entries*/
+ /*well does not make to much sense because the eigenvalues
+ of the jacobian go negative; and negative eigenvalues
+ on a complex iterative system z(n+1)=A * z(n)
+ give imaginary roots in the charcateristic polynom
+ --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here
+ where u(t) is a unknown amplitude function (worst case rising fast)
+ */
+ }
+
/* exploit force(a,b) == -force(b,a) part2/2 */
VecSubf(dvel,velcenter,obp->vec);
VecMulf(dvel,sb->nodemass);
@@ -2101,6 +2168,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
Vec3PlusStVec(obp->force,sb->balldamp,dvel);
Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
+
}
}
}
@@ -2110,24 +2178,40 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
float auxvect[3];
float velgoal[3];
- float absvel =0, projvel= 0;
-
+
/* do goal stuff */
if(ob->softflag & OB_SB_GOAL) {
/* true elastic goal */
- VecSubf(auxvect,bp->origT,bp->pos);
+ VecSubf(auxvect,bp->pos,bp->origT);
ks = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
- bp->force[0]+= ks*(auxvect[0]);
- bp->force[1]+= ks*(auxvect[1]);
- bp->force[2]+= ks*(auxvect[2]);
+ bp->force[0]+= -ks*(auxvect[0]);
+ bp->force[1]+= -ks*(auxvect[1]);
+ bp->force[2]+= -ks*(auxvect[2]);
+
+ if(nl_flags & NLF_BUILD){
+ //int ia =3*(sb->totpoint-a);
+ //int op =3*(sb->totpoint);
+ /* depending on my pos */
+ //dfdx_goal(ia,ia,op,ks*forcetime);
+ }
+
+
/* calulate damping forces generated by goals*/
VecSubf(velgoal,bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob) ;
+ VecAddf(auxvect,velgoal,bp->vec);
if (forcetime > 0.0 ) { /* make sure friction does not become rocket motor on time reversal */
- bp->force[0]-= kd * (velgoal[0] + bp->vec[0]);
- bp->force[1]-= kd * (velgoal[1] + bp->vec[1]);
- bp->force[2]-= kd * (velgoal[2] + bp->vec[2]);
+ bp->force[0]-= kd * (auxvect[0]);
+ bp->force[1]-= kd * (auxvect[1]);
+ bp->force[2]-= kd * (auxvect[2]);
+ if(nl_flags & NLF_BUILD){
+ //int ia =3*(sb->totpoint-a);
+ Normalize(auxvect);
+ /* depending on my vel */
+ //dfdv_goal(ia,ia,kd*forcetime);
+ }
+
}
else {
bp->force[0]-= kd * (velgoal[0] - bp->vec[0]);
@@ -2140,6 +2224,7 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
/* gravitation */
bp->force[2]-= gravity*sb->nodemass; /* individual mass of node here */
+ //bp->force[1]-= gravity*sb->nodemass; /* individual mass of node here */
/* particle field & vortex */
@@ -2170,16 +2255,26 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
bp->force[1]-= bp->vec[1]*kd;
bp->force[2]-= bp->vec[2]*kd;
/* friction in media done */
+ if(nl_flags & NLF_BUILD){
+ //int ia =3*(sb->totpoint-a);
+ /* da/dv = */
+
+// nlMatrixAdd(ia,ia,forcetime*kd);
+// nlMatrixAdd(ia+1,ia+1,forcetime*kd);
+// nlMatrixAdd(ia+2,ia+2,forcetime*kd);
+ }
+
}
/* +++cached collision targets */
bp->choke = 0.0f;
+ bp->choke2 = 0.0f;
bp->flag &= ~SBF_DOFUZZY;
if(do_deflector) {
float cfforce[3],defforce[3] ={0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}, facenormal[3], cf = 1.0f,intrusion;
kd = 1.0f;
if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
- if (intrusion < 0.0f){
+ if ((!nl_flags)&&(intrusion < 0.0f)){
/*bjornmose: uugh.. what an evil hack
violation of the 'don't touch bp->pos in here' rule
but works nice, like this-->
@@ -2197,8 +2292,15 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
VECSUB(cfforce,bp->vec,vel);
Vec3PlusStVec(bp->force,-cf*50.0f,cfforce);
}
-
Vec3PlusStVec(bp->force,kd,defforce);
+ if (nl_flags & NLF_BUILD){
+ // int ia =3*(sb->totpoint-a);
+ // int op =3*sb->totpoint;
+ //dfdx_goal(ia,ia,op,mpos); // don't do unless you know
+ //dfdv_goal(ia,ia,-cf);
+
+ }
+
}
}
@@ -2215,50 +2317,8 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
bp->choke = bs->cf;
}
-
- if (( (sb->totpoint-a) == bs->v1) ){
- actspringlen= VecLenf( (bproot+bs->v2)->pos, bp->pos);
- VecSubf(sd,(bproot+bs->v2)->pos, bp->pos);
- Normalize(sd);
-
- /* friction stuff V1 */
- VecSubf(velgoal,bp->vec,(bproot+bs->v2)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalize(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0f) /* check for degenerated springs */
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- forcefactor *= bs->strength;
-
- Vec3PlusStVec(bp->force,-forcefactor,sd);
-
- }
-
- if (( (sb->totpoint-a) == bs->v2) ){
- actspringlen= VecLenf( (bproot+bs->v1)->pos, bp->pos);
- VecSubf(sd,bp->pos,(bproot+bs->v1)->pos);
- Normalize(sd);
-
- /* friction stuff V2 */
- VecSubf(velgoal,bp->vec,(bproot+bs->v1)->vec);
- kd = sb->infrict * sb_fric_force_scale(ob);
- absvel = Normalize(velgoal);
- projvel = ABS(Inpf(sd,velgoal));
- kd *= absvel * projvel;
- Vec3PlusStVec(bp->force,-kd,velgoal);
-
- if(bs->len > 0.0)
- forcefactor = (bs->len - actspringlen)/bs->len * iks;
- else
- forcefactor = actspringlen * iks;
- forcefactor *= bs->strength;
- Vec3PlusStVec(bp->force,+forcefactor,sd);
- }
+ // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+ sb_spring_force(ob,sb->totpoint-a,bs,iks,forcetime,nl_flags);
}/* loop springs */
}/* existing spring list */
}/*any edges*/
@@ -2268,14 +2328,81 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow)
/* finally add forces caused by face collision */
- if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
- /* cleanup */
- if(do_effector) pdEndEffectors(do_effector);
-}
+ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
+
+ /* finish matrix and solve */
+#if (0) // remove onl linking for now .. still i am not sure .. the jacobian can be usefull .. so keep that BM
+ if(nl_flags & NLF_SOLVE){
+ //double sct,sst=PIL_check_seconds_timer();
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ int iv =3*(sb->totpoint-a);
+ int ip =3*(2*sb->totpoint-a);
+ int n;
+ for (n=0;n<3;n++) {nlRightHandSideSet(0, iv+n, bp->force[0+n]);}
+ for (n=0;n<3;n++) {nlRightHandSideSet(0, ip+n, bp->vec[0+n]);}
+ }
+ nlEnd(NL_MATRIX);
+ nlEnd(NL_SYSTEM);
+ if ((G.rt >0) && (nl_flags & NLF_BUILD))
+ {
+ printf("####MEE#####\n");
+ nlPrintMatrix();
+ }
+ success= nlSolveAdvanced(NULL, 1);
+
+ // nlPrintMatrix(); /* for debug purpose .. anyhow cropping B vector looks like working */
+ if(success){
+ float f;
+ int index =0;
+ /* for debug purpose .. anyhow cropping B vector looks like working */
+ if (G.rt >0)
+ for(a=2*sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ printf("(%f ",f);index++;
+ f=nlGetVariable(0,index);
+ printf("%f ",f);index++;
+ f=nlGetVariable(0,index);
+ printf("%f)",f);index++;
+ }
+
+ index =0;
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ bp->impdv[0] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdv[1] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdv[2] = f; index++;
+ }
+ /*
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ f=nlGetVariable(0,index);
+ bp->impdx[0] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdx[1] = f; index++;
+ f=nlGetVariable(0,index);
+ bp->impdx[2] = f; index++;
+ }
+ */
+ }
+ else{
+ printf("Matrix inversion failed \n");
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ VECCOPY(bp->impdv,bp->force);
+ }
+
+ }
-static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err)
+ //sct=PIL_check_seconds_timer();
+ //if (sct-sst > 0.01f) printf(" implicit solver time %f %s \r",sct-sst,ob->id.name);
+ }
+ /* cleanup */
+#endif
+ if(do_effector) pdEndEffectors(do_effector);
+}
+static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *err, int mid_flags)
{
/* time evolution */
/* actually does an explicit euler step mode == 0 */
@@ -2283,7 +2410,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp;
float dx[3],dv[3],aabbmin[3],aabbmax[3],cm[3]={0.0f,0.0f,0.0f};
- float timeovermass;
+ float timeovermass/*,freezeloc=0.00001f,freezeforce=0.00000000001f*/;
float maxerrpos= 0.0f,maxerrvel = 0.0f;
int a,fuzzy=0;
@@ -2298,14 +2425,14 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
if(bp->goal < SOFTGOALSNAP){
+ /* this makes t~ = t */
+ if(mid_flags & MID_PRESERVE) VECCOPY(dx,bp->vec);
/* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/
/* the ( ... )' operator denotes derivate respective time */
/* the euler step for velocity then becomes */
/* v(t + dt) = v(t) + a(t) * dt */
- bp->force[0]*= timeovermass; /* individual mass of node here */
- bp->force[1]*= timeovermass;
- bp->force[2]*= timeovermass;
+ VecMulf(bp->force,timeovermass);/* individual mass of node here */
/* some nasty if's to have heun in here too */
VECCOPY(dv,bp->force);
@@ -2313,6 +2440,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
VECCOPY(bp->prevvec, bp->vec);
VECCOPY(bp->prevdv, dv);
}
+
if (mode ==2){
/* be optimistic and execute step */
bp->vec[0] = bp->prevvec[0] + 0.5f * (dv[0] + bp->prevdv[0]);
@@ -2325,15 +2453,24 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
}
else {VECADD(bp->vec, bp->vec, bp->force);}
+ /* this makes t~ = t+dt */
+ if(!(mid_flags & MID_PRESERVE)) VECCOPY(dx,bp->vec);
+
/* so here is (x)'= v(elocity) */
/* the euler step for location then becomes */
- /* x(t + dt) = x(t) + v(t) * dt */
-
- VECCOPY(dx,bp->vec);
- dx[0]*=forcetime ;
- dx[1]*=forcetime ;
- dx[2]*=forcetime ;
-
+ /* x(t + dt) = x(t) + v(t~) * dt */
+ VecMulf(dx,forcetime);
+
+ /* the freezer */
+ /*
+ if ((Inpf(dx,dx)<freezeloc )&&(Inpf(bp->force,bp->force)<freezeforce )){
+ bp->frozen /=2;
+ }
+ else{
+ bp->frozen =MIN2(bp->frozen*1.05f,1.0f);
+ }
+ VecMulf(dx,bp->frozen);
+ */
/* again some nasty if's to have heun in here too */
if (mode ==1){
VECCOPY(bp->prevpos,bp->pos);
@@ -2343,7 +2480,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
if (mode ==2){
bp->pos[0] = bp->prevpos[0] + 0.5f * ( dx[0] + bp->prevdx[0]);
bp->pos[1] = bp->prevpos[1] + 0.5f * ( dx[1] + bp->prevdx[1]);
- bp->pos[2] = bp->prevpos[2] + 0.5f* ( dx[2] + bp->prevdx[2]);
+ bp->pos[2] = bp->prevpos[2] + 0.5f * ( dx[2] + bp->prevdx[2]);
maxerrpos = MAX2(maxerrpos,ABS(dx[0] - bp->prevdx[0]));
maxerrpos = MAX2(maxerrpos,ABS(dx[1] - bp->prevdx[1]));
maxerrpos = MAX2(maxerrpos,ABS(dx[2] - bp->prevdx[2]));
@@ -2352,10 +2489,11 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
the collider object signals to get out by pushing hard. on the other hand
we don't want to end up in deep space so we add some <viscosity>
to balance that out */
+ if (bp->choke2 > 0.0f){
+ VecMulf(bp->vec,(1.0f - bp->choke2));
+ }
if (bp->choke > 0.0f){
- bp->vec[0] = bp->vec[0]*(1.0f - bp->choke);
- bp->vec[1] = bp->vec[1]*(1.0f - bp->choke);
- bp->vec[2] = bp->vec[2]*(1.0f - bp->choke);
+ VecMulf(bp->vec,(1.0f - bp->choke));
}
}
@@ -2402,6 +2540,81 @@ static void softbody_restore_prev_step(Object *ob)
}
}
+#if 0
+static void softbody_store_step(Object *ob)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ VECCOPY(bp->prevvec,bp->vec);
+ VECCOPY(bp->prevpos,bp->pos);
+ }
+}
+
+
+/* used by predictors and correctors */
+static void softbody_store_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(pv, bp->vec);
+ pv+=3;
+
+ VECCOPY(pp, bp->pos);
+ pp+=3;
+ }
+}
+
+/* used by predictors and correctors */
+static void softbody_retrieve_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(bp->vec,pv);
+ pv+=3;
+
+ VECCOPY(bp->pos,pp);
+ pp+=3;
+ }
+}
+
+/* used by predictors and correctors */
+static void softbody_swap_state(Object *ob,float *ppos,float *pvel)
+{
+ SoftBody *sb= ob->soft; /* is supposed to be there*/
+ BodyPoint *bp;
+ int a;
+ float *pp=ppos,*pv=pvel;
+ float temp[3];
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+
+ VECCOPY(temp, bp->vec);
+ VECCOPY(bp->vec,pv);
+ VECCOPY(pv,temp);
+ pv+=3;
+
+ VECCOPY(temp, bp->pos);
+ VECCOPY(bp->pos,pp);
+ VECCOPY(pp,temp);
+ pp+=3;
+ }
+}
+#endif
+
+
/* care for bodypoints taken out of the 'ordinary' solver step
** because they are screwed to goal by bolts
** they just need to move along with the goal in time
@@ -2422,6 +2635,30 @@ static void softbody_apply_goalsnap(Object *ob)
}
}
+
+void apply_spring_memory(Object *ob)
+{
+ SoftBody *sb = ob->soft;
+ BodySpring *bs;
+ BodyPoint *bp1, *bp2;
+ int a;
+ float b,l,r;
+
+ b = sb->plastic;
+ if (sb && sb->totspring){
+ for(a=0; a<sb->totspring; a++) {
+ bs = &sb->bspring[a];
+ bp1 =&sb->bpoint[bs->v1];
+ bp2 =&sb->bpoint[bs->v2];
+ l = VecLenf(bp1->pos,bp2->pos);
+ r = bs->len/l;
+ if (( r > 1.05f) || (r < 0.95)){
+ bs->len = ((100.0f - b) * bs->len + b*l)/100.0f;
+ }
+ }
+ }
+}
+
/* expects full initialized softbody */
static void interpolate_exciter(Object *ob, int timescale, int time)
{
@@ -2492,6 +2729,7 @@ static void springs_from_mesh(Object *ob)
Mesh *me= ob->data;
BodyPoint *bp;
int a;
+ float scale =1.0f;
sb= ob->soft;
if (me && sb)
@@ -2509,9 +2747,13 @@ static void springs_from_mesh(Object *ob)
}
/* recalculate spring length for meshes here */
+ /* special hidden feature! shrink to fit */
+ if (G.rt > 500){
+ scale = (G.rt - 500) / 100.0f;
+ }
for(a=0; a<sb->totspring; a++) {
BodySpring *bs = &sb->bspring[a];
- bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
+ bs->len= scale*VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
}
}
}
@@ -2861,6 +3103,106 @@ static void curve_surf_to_softbody(Object *ob)
}
+static void springs_from_particles(Object *ob)
+{
+ ParticleSystem *psys;
+ ParticleSystemModifierData *psmd=0;
+ ParticleData *pa=0;
+ HairKey *key=0;
+ SoftBody *sb;
+ BodyPoint *bp;
+ BodySpring *bs;
+ int a,k;
+ float hairmat[4][4];
+
+ psys= ob->soft->particles;
+ sb= ob->soft;
+ if(ob && sb && psys) {
+ psmd = psys_get_modifier(ob, psys);
+
+ bp= sb->bpoint;
+ for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) {
+ for(k=0, key=pa->hair; k<pa->totkey; k++, bp++, key++) {
+ VECCOPY(bp->origS, key->co);
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ Mat4MulVecfl(hairmat, bp->origS);
+ }
+ }
+
+ for(a=0, bs=sb->bspring; a<sb->totspring; a++, bs++)
+ bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
+ }
+}
+
+static void particles_to_softbody(Object *ob)
+{
+ SoftBody *sb;
+ BodyPoint *bp;
+ BodySpring *bs;
+ ParticleData *pa;
+ HairKey *key;
+ ParticleSystem *psys= ob->soft->particles;
+ float goalfac;
+ int a, k, curpoint;
+ int totpoint= psys_count_keys(psys);
+ int totedge= totpoint-psys->totpart;
+
+ /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
+ renew_softbody(ob, totpoint, totedge);
+
+ /* find first BodyPoint index for each particle */
+ if(psys->totpart > 0) {
+ psys->particles->bpi = 0;
+ for(a=1, pa=psys->particles+1; a<psys->totpart; a++, pa++)
+ pa->bpi = (pa-1)->bpi + (pa-1)->totkey;
+ }
+
+ /* we always make body points */
+ sb= ob->soft;
+ bp= sb->bpoint;
+ bs= sb->bspring;
+ goalfac= ABS(sb->maxgoal - sb->mingoal);
+
+ if((ob->softflag & OB_SB_GOAL)) {
+ for(a=0, pa=psys->particles; a<psys->totpart; a++, pa++) {
+ for(k=0, key=pa->hair; k<pa->totkey; k++,bp++,key++) {
+ if(k) {
+ bp->goal= key->weight;
+ bp->goal= sb->mingoal + bp->goal*goalfac;
+ bp->goal= (float)pow(bp->goal, 4.0f);
+ }
+ else{
+ /* hair roots are allways fixed fully to goal */
+ bp->goal= 1.0f;
+ }
+ }
+ }
+ }
+
+ bp= sb->bpoint;
+ curpoint=0;
+ for(a=0, pa=psys->particles; a<psys->totpart; a++, curpoint++, pa++) {
+ for(k=0; k<pa->totkey-1; k++,bs++,curpoint++) {
+ bs->v1=curpoint;
+ bs->v2=curpoint+1;
+ bs->strength= 1.0;
+ bs->order=1;
+ }
+ }
+
+ build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
+ /* insert *other second order* springs if desired */
+ if(sb->secondspring > 0.0000001f) {
+ add_2nd_order_springs(ob,sb->secondspring*10.0); /* exploits the the first run of build_bps_springlist(ob);*/
+ build_bps_springlist(ob); /* yes we need to do it again*/
+ }
+ springs_from_particles(ob); /* write the 'rest'-lenght of the springs */
+ if(ob->softflag & OB_SB_SELF)
+ calculate_collision_balls(ob);
+}
+
/* copies softbody result back in object */
static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, int local)
{
@@ -2877,117 +3219,94 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts,
}
}
-/* return 1 if succesfully baked and applied step */
-static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
+void softbody_clear_cache(Object *ob, float framenr)
{
- SoftBody *sb= ob->soft;
- SBVertex *key0, *key1, *key2, *key3;
- BodyPoint *bp;
- float data[4], sfra, efra, cfra, dfra, fac; /* start, end, current, delta */
- int ofs1, a;
-
- /* precondition check */
- if(sb==NULL || sb->keys==NULL || sb->totkey==0) return 0;
- /* so we got keys, but no bodypoints... even without simul we need it for the bake */
- if(sb->bpoint==NULL) sb->bpoint= MEM_callocN( sb->totpoint*sizeof(BodyPoint), "bodypoint");
-
- /* convert cfra time to system time */
- sfra= (float)sb->sfra;
- cfra= bsystem_time(ob, NULL, framenr, 0.0);
- efra= (float)sb->efra;
- dfra= (float)sb->interval;
+ SoftBody *sb = ob->soft;
+ ModifierData *md = ob->modifiers.first;
+ int stack_index = -1;
+ int a;
- /* offset in keys array */
- ofs1= (int)floor( (cfra-sfra)/dfra );
+ if(sb==NULL) return;
- if(ofs1 < 0) {
- key0=key1=key2=key3= *sb->keys;
- }
- else if(ofs1 >= sb->totkey-1) {
- key0=key1=key2=key3= *(sb->keys+sb->totkey-1);
- }
+ if(sb->particles)
+ stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
else {
- key1= *(sb->keys+ofs1);
- key2= *(sb->keys+ofs1+1);
-
- if(ofs1>0) key0= *(sb->keys+ofs1-1);
- else key0= key1;
-
- if(ofs1<sb->totkey-2) key3= *(sb->keys+ofs1+2);
- else key3= key2;
- }
-
- sb->ctime= cfra; /* needed? */
-
- /* timing */
- fac= ((cfra-sfra)/dfra) - (float)ofs1;
- CLAMP(fac, 0.0, 1.0);
- set_four_ipo(fac, data, KEY_BSPLINE);
- if (key0&&key1&&key2&&key3) // may be null because we SHIFT_ESCAPED
- for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++, key0++, key1++, key2++, key3++) {
- bp->pos[0]= data[0]*key0->vec[0] + data[1]*key1->vec[0] + data[2]*key2->vec[0] + data[3]*key3->vec[0];
- bp->pos[1]= data[0]*key0->vec[1] + data[1]*key1->vec[1] + data[2]*key2->vec[1] + data[3]*key3->vec[1];
- bp->pos[2]= data[0]*key0->vec[2] + data[1]*key1->vec[2] + data[2]*key2->vec[2] + data[3]*key3->vec[2];
+ for(a=0; md; md=md->next, a++) {
+ if(md->type == eModifierType_Softbody) {
+ stack_index = a;
+ break;
+ }
+ }
}
-
- softbody_to_object(ob, vertexCos, numVerts, sb->local);
-
- return 1;
-}
-/* only gets called after succesfully doing softbody_step */
-/* already checked for OB_SB_BAKE flag */
-static void softbody_baked_add(Object *ob, float framenr)
+ BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_ALL, framenr, stack_index);
+}
+static void softbody_write_cache(Object *ob, float framenr)
{
- SoftBody *sb= ob->soft;
- SBVertex *key;
+ FILE *fp = NULL;
+ SoftBody *sb = ob->soft;
BodyPoint *bp;
- float sfra, efra, cfra, dfra, fac1; /* start, end, current, delta */
- int ofs1, a;
-
- /* convert cfra time to system time */
- sfra= (float)sb->sfra;
- fac1= ob->sf; ob->sf= 0.0f; /* disable startframe */
- cfra= bsystem_time(ob, NULL, framenr, 0.0);
- ob->sf= fac1;
- efra= (float)sb->efra;
- dfra= (float)sb->interval;
-
- if(sb->totkey==0) {
- if(sb->sfra >= sb->efra) return; /* safety, UI or py setting allows */
- if(sb->interval<1) sb->interval= 1; /* just be sure */
-
- sb->totkey= 1 + (int)(ceil( (efra-sfra)/dfra ) );
- sb->keys= MEM_callocN( sizeof(void *)*sb->totkey, "sb keys");
+ ModifierData *md = ob->modifiers.first;
+ int stack_index = -1;
+ int a;
+
+ if(sb->totpoint == 0) return;
+
+ if(sb->particles)
+ stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
+ else {
+ for(a=0; md; md=md->next, a++) {
+ if(md->type == eModifierType_Softbody) {
+ stack_index = a;
+ break;
+ }
+ }
}
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
+ if(!fp) return;
+
+ for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
+ fwrite(&bp->pos, sizeof(float), 3, fp);
- /* inverse matrix might not be uptodate... */
- Mat4Invert(ob->imat, ob->obmat);
-
- /* now find out if we have to store a key */
-
- /* offset in keys array */
- if(cfra>=(efra)) {
- ofs1= sb->totkey-1;
- fac1= 0.0;
- }
+ fclose(fp);
+}
+static int softbody_read_cache(Object *ob, float framenr)
+{
+ FILE *fp = NULL;
+ SoftBody *sb = ob->soft;
+ BodyPoint *bp;
+ ModifierData *md = ob->modifiers.first;
+ int stack_index = -1;
+ int a, ret = 1;
+
+ if(sb->totpoint == 0) return 0;
+
+ if(sb->particles)
+ stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,sb->particles));
else {
- ofs1= (int)floor( (cfra-sfra)/dfra );
- fac1= ((cfra-sfra)/dfra) - (float)ofs1;
- }
- if( fac1 < 1.0/dfra ) {
-
- key= *(sb->keys+ofs1);
- if(key == NULL) {
- *(sb->keys+ofs1)= key= MEM_mallocN(sb->totpoint*sizeof(SBVertex), "softbody key");
-
- for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++, key++) {
- VECCOPY(key->vec, bp->pos);
- if(sb->local)
- Mat4MulVecfl(ob->imat, key->vec);
+ for(a=0; md; md=md->next, a++) {
+ if(md->type == eModifierType_Softbody) {
+ stack_index = a;
+ break;
}
}
}
+
+ fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
+ if(!fp)
+ ret = 0;
+ else {
+ for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++)
+ if(fread(&bp->pos, sizeof(float), 3, fp) != 3) {
+ ret = 0;
+ break;
+ }
+
+ fclose(fp);
+ }
+
+ return ret;
}
/* +++ ************ maintaining scratch *************** */
void sb_new_scratch(SoftBody *sb)
@@ -3026,6 +3345,8 @@ SoftBody *sbNew(void)
sb->inspring= 0.5f;
sb->infrict= 0.5f;
+ /*todo backward file compat should copy inspring to inpush while reading old files*/
+ sb->inpush = 0.5f;
sb->interval= 10;
sb->sfra= G.scene->r.sfra;
@@ -3035,7 +3356,16 @@ SoftBody *sbNew(void)
sb->balldamp = 0.50f;
sb->ballstiff= 1.0f;
sb->sbc_mode = 1;
+
+
+ sb->minloops = 10;
+ sb->maxloops = 300;
+
+ sb->choke = 3;
sb_new_scratch(sb);
+ /*todo backward file compat should set sb->shearstiff = 1.0f while reading old files*/
+ sb->shearstiff = 1.0f;
+ sb->solverflags |= SBSO_OLDERR;
return sb;
}
@@ -3078,15 +3408,14 @@ void sbSetInterruptCallBack(int (*f)(void))
/* simulates one step. framenr is in frames */
void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
{
+ ParticleSystemModifierData *psmd=0;
+ ParticleData *pa=0;
SoftBody *sb;
+ HairKey *key= NULL;
BodyPoint *bp;
int a;
- float dtime,ctime,forcetime,err;
-
- /* baking works with global time */
- if(!(ob->softflag & OB_SB_BAKEDO) )
- if(softbody_baked_step(ob, framenr, vertexCos, numVerts) ) return;
-
+ float dtime,ctime,forcetime;
+ float hairmat[4][4];
/* This part only sets goals and springs, based on original mesh/curve/lattice data.
Copying coordinates happens in next chunk by setting softbody flag OB_SB_RESET */
@@ -3097,7 +3426,13 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
(numVerts!=ob->soft->totpoint) || /* should never happen, just to be safe */
((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) /* happens when in UI edges was set */
{
- switch(ob->type) {
+ if(ob->soft && ob->soft->bpoint) /* don't clear on file load */
+ softbody_clear_cache(ob, framenr);
+
+ if(ob->soft->particles){
+ particles_to_softbody(ob);
+ }
+ else switch(ob->type) {
case OB_MESH:
mesh_to_softbody(ob);
break;
@@ -3123,10 +3458,14 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
/* still no points? go away */
if(sb->totpoint==0) return;
+ if(sb->particles){
+ psmd=psys_get_modifier(ob,sb->particles);
+ pa=sb->particles->particles;
+ }
/* checking time: */
- ctime= bsystem_time(ob, NULL, framenr, 0.0);
+ ctime= bsystem_time(ob, framenr, 0.0);
if (ob->softflag&OB_SB_RESET) {
dtime = 0.0;
@@ -3134,17 +3473,45 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
dtime= ctime - sb->ctime;
}
+ if(softbody_read_cache(ob, framenr)) {
+ if(sb->particles==0)
+ softbody_to_object(ob, vertexCos, numVerts, sb->local);
+ sb->ctime = ctime;
+ return;
+ }
+
/* the simulator */
/* update the vertex locations */
if (dtime!=0.0) {
+ if(sb->particles) {
+ pa=sb->particles->particles;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
/* store where goals are now */
VECCOPY(bp->origS, bp->origE);
/* copy the position of the goals at desired end time */
- VECCOPY(bp->origE, vertexCos[a]);
- /* vertexCos came from local world, go global */
- Mat4MulVecfl(ob->obmat, bp->origE);
+ if(sb->particles) {
+ if(key == pa->hair + pa->totkey) {
+ pa++;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+ VECCOPY(bp->origE, key->co);
+ Mat4MulVecfl(hairmat,bp->origE);
+
+ key++;
+ }
+ else{
+ VECCOPY(bp->origE, vertexCos[a]);
+ /* vertexCos came from local world, go global */
+ Mat4MulVecfl(ob->obmat, bp->origE);
+ }
/* just to be save give bp->origT a defined value
will be calulated in interpolate_exciter()*/
VECCOPY(bp->origT, bp->origE);
@@ -3156,9 +3523,29 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
(dtime>=9.9*G.scene->r.framelen) /* too far forward in time --> goals won't be accurate enough */
)
{
+ if(sb->particles) {
+ pa=sb->particles->particles;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
- VECCOPY(bp->pos, vertexCos[a]);
- Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
+ if(sb->particles) {
+ if(key == pa->hair + pa->totkey) {
+ pa++;
+ key = pa->hair;
+
+ psys_mat_hair_to_global(ob, psmd->dm, sb->particles->part->from, pa, hairmat);
+ }
+ VECCOPY(bp->pos, key->co);
+ Mat4MulVecfl(hairmat, bp->pos);
+ key++;
+ }
+ else {
+ VECCOPY(bp->pos, vertexCos[a]);
+ Mat4MulVecfl(ob->obmat, bp->pos); /* yep, sofbody is global coords*/
+ }
VECCOPY(bp->origS, bp->pos);
VECCOPY(bp->origE, bp->pos);
VECCOPY(bp->origT, bp->pos);
@@ -3186,23 +3573,22 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sb_new_scratch(sb); /* make a new */
sb->scratch->needstobuildcollider=1;
-
- /* copy some info to scratch */
- switch(ob->type) {
- case OB_MESH:
- if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
- break;
- case OB_LATTICE:
- break;
- case OB_CURVE:
- case OB_SURF:
- break;
- default:
- break;
+ if((sb->particles)==0) {
+ /* copy some info to scratch */
+ switch(ob->type) {
+ case OB_MESH:
+ if (ob->softflag & OB_SB_FACECOLL) mesh_faces_to_scratch(ob);
+ break;
+ case OB_LATTICE:
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ break;
+ default:
+ break;
+ }
}
-
-
ob->softflag &= ~OB_SB_RESET;
}
else if(dtime>0.0) {
@@ -3218,8 +3604,10 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
}
- if (TRUE) { /* */
+ if (sb->solver_ID < 2) {
/* special case of 2nd order Runge-Kutta type AKA Heun */
+ int mid_flags=0;
+ float err = 0;
float forcetimemax = 1.0f;
float forcetimemin = 0.001f;
float timedone =0.0; /* how far did we get without violating error condition */
@@ -3231,7 +3619,8 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
if (sb->minloops > 0) forcetimemax = 1.0f / sb->minloops;
if (sb->maxloops > 0) forcetimemin = 1.0f / sb->maxloops;
-
+
+ if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
//forcetime = dtime; /* hope for integrating in one step */
forcetime =forcetimemax; /* hope for integrating in one step */
@@ -3242,11 +3631,14 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sb->scratch->flag &= ~SBF_DOFUZZY;
/* do predictive euler step */
- softbody_calc_forces(ob, forcetime,timedone/dtime);
- softbody_apply_forces(ob, forcetime, 1, NULL);
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 1, NULL,mid_flags);
+
+
/* crop new slope values to do averaged slope step */
- softbody_calc_forces(ob, forcetime,timedone/dtime);
- softbody_apply_forces(ob, forcetime, 2, &err);
+ softbody_calc_forces(ob, forcetime,timedone/dtime,0);
+ softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
+
softbody_apply_goalsnap(ob);
if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
@@ -3286,6 +3678,7 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
sct=PIL_check_seconds_timer();
if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone);
}
+ /* ask for user break */
if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
}
@@ -3300,21 +3693,34 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts
}
}
+ else if (sb->solver_ID == 2)
+ {/* do semi "fake" implicit euler */
+ //removed
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 4)
+ {
+ /* do semi "fake" implicit euler */
+ }/*SOLVER SELECT*/
+ else if (sb->solver_ID == 3){
+ /* do "stupid" semi "fake" implicit euler */
+ //removed
+
+ }/*SOLVER SELECT*/
else{
- /* do brute force explicit euler */
- /* removed but left this branch for better integrators / solvers (BM) */
- /* yah! Nicholas Guttenberg (NichG) here is the place to plug in */
- }
+ printf("softbody no valid solver ID!");
+ }/*SOLVER SELECT*/
+ if(sb->plastic){ apply_spring_memory(ob);}
+
if(sb->solverflags & SBSO_MONITOR ){
sct=PIL_check_seconds_timer();
if (sct-sst > 0.5f) printf(" solver time %f %s \r",sct-sst,ob->id.name);
}
}
- softbody_to_object(ob, vertexCos, numVerts, 0);
+ if(sb->particles==0)
+ softbody_to_object(ob, vertexCos, numVerts, 0);
sb->ctime= ctime;
-
- if(ob->softflag & OB_SB_BAKEDO) softbody_baked_add(ob, framenr);
+ softbody_write_cache(ob, framenr);
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 7f3c5ddf8a7..7a0c47237e7 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -42,16 +42,18 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "BKE_bad_level_calls.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_scene.h"
#include "BKE_subsurf.h"
-#include "BKE_displist.h"
-#include "BKE_DerivedMesh.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
@@ -75,8 +77,6 @@ struct CCGDerivedMesh {
CCGSubSurf *ss;
int drawInteriorEdges, useSubsurfUv;
- Mesh *me;
-
struct {int startVert; CCGVert *vert;} *vertMap;
struct {int startVert; int startEdge; CCGEdge *edge;} *edgeMap;
struct {int startVert; int startEdge;
@@ -224,7 +224,7 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGV
break;
}
- fverts[j]= (CCGVertHDL)(nv->f*4 + nv->tfindex);
+ fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
}
}
@@ -241,7 +241,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
EdgeHash *ehash;
float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
- limit[0]= limit[1]= 0.0001f;
+ limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
if (!vmap)
return 0;
@@ -262,7 +262,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
if (v->separate) {
CCGVert *ssv;
- CCGVertHDL vhdl = (CCGVertHDL)(v->f*4 + v->tfindex);
+ CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
float uv[3];
uv[0]= (tface+v->f)->uv[v->tfindex][0];
@@ -280,20 +280,20 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
for (i=0; i<totface; i++) {
MFace *mf = &((MFace*) mface)[i];
int nverts= mf->v4? 4: 3;
- CCGFace *origf= ccgSubSurf_getFace(origss, (CCGFaceHDL)i);
+ CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
unsigned int *fv = &mf->v1;
get_face_uv_map_vert(vmap, mf, i, fverts);
for (j=0; j<nverts; j++) {
- int v0 = (int)fverts[j];
- int v1 = (int)fverts[(j+1)%nverts];
+ int v0 = GET_INT_FROM_POINTER(fverts[j]);
+ int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
MVert *mv0 = mvert + *(fv+j);
MVert *mv1 = mvert + *(fv+((j+1)%nverts));
if (!BLI_edgehash_haskey(ehash, v0, v1)) {
CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
- CCGEdgeHDL ehdl= (CCGEdgeHDL)(i*4 + j);
+ CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
float crease;
if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
@@ -316,7 +316,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm,
CCGFace *f;
get_face_uv_map_vert(vmap, mf, i, fverts);
- ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, nverts, fverts, &f);
+ ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
}
free_uv_vert_map(vmap);
@@ -335,7 +335,6 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
-
if(!dmtface || !tface)
return;
@@ -359,7 +358,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
fi = ccgSubSurf_getFaceIterator(uvss);
for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- faceMap[(int) ccgSubSurf_getFaceFaceHandle(uvss, f)] = f;
+ faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
}
ccgFaceIterator_free(fi);
@@ -503,7 +502,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
+ vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))] = v;
}
ccgVertIterator_free(vi);
@@ -513,7 +512,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
- edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
+ edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))] = e;
}
totface = ccgSubSurf_getNumFaces(ss);
@@ -522,7 +521,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
+ faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
}
ccgFaceIterator_free(fi);
@@ -550,7 +549,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(S = 0; S < numVerts; S++) {
CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
- vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
}
DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i);
@@ -614,9 +613,9 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
CCGVert *v;
v = ccgSubSurf_getEdgeVert0(ss, e);
- vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
v = ccgSubSurf_getEdgeVert1(ss, e);
- vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
for(x = 1; x < edgeSize - 1; x++) {
float w[2];
@@ -639,7 +638,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
CCGVert *v = vertMap2[index];
int vertIdx;
- vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
DM_copy_vert_data(dm, result, vertIdx, i, 1);
VecCopyf(mvert->co, ccgSubSurf_getVertData(ss, v));
@@ -700,7 +699,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
for(index = 0; index < totedge; index++) {
CCGEdge *e = edgeMap2[index];
unsigned int flags = 0;
- int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+ int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
@@ -734,7 +733,7 @@ DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
int mat_nr;
int flag;
int mapIndex = ccgDM_getFaceMapIndex(NULL, ss, f);
- int faceIdx = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+ int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
if(!ssFromEditmesh) {
MFace origMFace;
@@ -838,9 +837,9 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
CCGVert *v;
if(vertexCos) {
- ccgSubSurf_syncVert(ss, (CCGVertHDL)i, vertexCos[i], 0, &v);
+ ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
} else {
- ccgSubSurf_syncVert(ss, (CCGVertHDL)i, mv->co, 0, &v);
+ ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
}
((int*)ccgSubSurf_getVertUserData(ss, v))[1] = *index;
@@ -855,8 +854,8 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
crease = useFlatSubdiv ? creaseFactor :
me->crease * creaseFactor / 255.0f;
- ccgSubSurf_syncEdge(ss, (CCGEdgeHDL)i, (CCGVertHDL)me->v1,
- (CCGVertHDL)me->v2, crease, &e);
+ ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
+ SET_INT_IN_POINTER(me->v2), crease, &e);
((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = *index;
}
@@ -866,16 +865,16 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
for (i = 0; i < totface; i++, mf++, index++) {
CCGFace *f;
- fVerts[0] = (CCGVertHDL) mf->v1;
- fVerts[1] = (CCGVertHDL) mf->v2;
- fVerts[2] = (CCGVertHDL) mf->v3;
- fVerts[3] = (CCGVertHDL) mf->v4;
+ fVerts[0] = SET_INT_IN_POINTER(mf->v1);
+ fVerts[1] = SET_INT_IN_POINTER(mf->v2);
+ fVerts[2] = SET_INT_IN_POINTER(mf->v3);
+ fVerts[3] = SET_INT_IN_POINTER(mf->v4);
// this is very bad, means mesh is internally consistent.
// it is not really possible to continue without modifying
// other parts of code significantly to handle missing faces.
// since this really shouldn't even be possible we just bail.
- if(ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, fVerts[3] ? 4 : 3,
+ if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
fVerts, &f) == eCCGError_InvalidValue) {
static int hasGivenError = 0;
@@ -1095,7 +1094,7 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
/* this vert comes from edge data */
CCGEdge *e;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
- int x;
+ int x, *edgeFlag;
unsigned int flags = 0;
i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
@@ -1109,24 +1108,12 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
- if(ccgdm->me) {
- int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
-
- if(edgeIdx!=-1) {
- MEdge *medge = ccgdm->me->medge;
- MEdge *origMed = &medge[edgeIdx];
-
- flags |= (origMed->flag & (ME_SEAM | ME_SHARP))
- | ME_EDGEDRAW | ME_EDGERENDER;
- }
- } else {
- int *edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
- if(edgeFlag)
- flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
- | ME_EDGEDRAW | ME_EDGERENDER;
- else
- flags |= ME_EDGEDRAW | ME_EDGERENDER;
- }
+ edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
+ if(edgeFlag)
+ flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
+ | ME_EDGEDRAW | ME_EDGERENDER;
+ else
+ flags |= ME_EDGEDRAW | ME_EDGERENDER;
med->flag = flags;
}
@@ -1147,7 +1134,7 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
int grid;
int x, y;
int lastface = ccgSubSurf_getNumFaces(ss) - 1;
- int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
+ char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
memset(mf, 0, sizeof(*mf));
@@ -1169,7 +1156,7 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
- if(faceFlags) mf->flag = faceFlags[i];
+ if(faceFlags) mf->flag = faceFlags[i*4];
else mf->flag = ME_SMOOTH;
}
@@ -1236,11 +1223,8 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int i = 0;
- MEdge *origEdges = NULL;
int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS);
- if(ccgdm->me) origEdges = ccgdm->me->medge;
-
totface = ccgSubSurf_getNumFaces(ss);
for(index = 0; index < totface; index++) {
CCGFace *f = ccgdm->faceMap[index].face;
@@ -1288,18 +1272,11 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
CCGEdge *e = ccgdm->edgeMap[index].edge;
unsigned int flags = 0;
int x;
- int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+ int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
- if(origEdges){
- if(edgeIdx != -1) {
- MEdge *origMed = &origEdges[edgeIdx];
-
- flags |= (origMed->flag & (ME_SEAM | ME_SHARP))
- | ME_EDGEDRAW | ME_EDGERENDER;
- }
- } else if(edgeFlags) {
+ if(edgeFlags) {
if(edgeIdx != -1) {
flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP))
| ME_EDGEDRAW | ME_EDGERENDER;
@@ -1327,10 +1304,7 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int i = 0;
- MFace *origFaces = NULL;
- int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
-
- if(ccgdm->me) origFaces = ccgdm->me->mface;
+ char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
totface = ccgSubSurf_getNumFaces(ss);
for(index = 0; index < totface; index++) {
@@ -1339,16 +1313,6 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
int mat_nr = 0;
int flag = ME_SMOOTH; /* assume face is smooth by default */
- if(!faceFlags) {
- if(origFaces) {
- int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
- MFace *origMFace = &origFaces[origIdx];
-
- mat_nr = origMFace->mat_nr;
- flag = origMFace->flag;
- }
- }
-
for(S = 0; S < numVerts; S++) {
for(y = 0; y < gridSize - 1; y++) {
for(x = 0; x < gridSize - 1; x++) {
@@ -1362,7 +1326,7 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
edgeSize, gridSize);
mf->mat_nr = mat_nr;
- if(faceFlags) mf->flag = faceFlags[index];
+ if(faceFlags) mf->flag = faceFlags[index*4];
else mf->flag = flag;
i++;
@@ -1392,7 +1356,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
+ vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))] = v;
}
ccgVertIterator_free(vi);
@@ -1402,7 +1366,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
- edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
+ edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))] = e;
}
totface = ccgSubSurf_getNumFaces(ss);
@@ -1411,7 +1375,7 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
+ faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
}
ccgFaceIterator_free(fi);
@@ -1623,28 +1587,51 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
ccgEdgeIterator_free(ei);
}
+static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
+{
+ float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
+ float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
+ float no[3];
+
+ no[0] = b_dY*a_cZ - b_dZ*a_cY;
+ no[1] = b_dZ*a_cX - b_dX*a_cZ;
+ no[2] = b_dX*a_cY - b_dY*a_cX;
+
+ /* don't normalize, GL_NORMALIZE is be enabled */
+ glNormal3fv(no);
+}
+
/* Only used by non-editmesh types */
static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
- MFace *mface = ccgdm->me->mface;
+ char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
- int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
- MFace *mf = &mface[index];
+ int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
+ int drawSmooth, mat_nr;
+
+ if(faceFlags) {
+ drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
+ mat_nr= faceFlags[index*4 + 1];
+ }
+ else {
+ drawSmooth = 1;
+ mat_nr= 0;
+ }
- if (!setMaterial(mf->mat_nr+1))
+ if (!setMaterial(mat_nr+1))
continue;
- glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
+ glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (mf->flag&ME_SMOOTH) {
+ if (drawSmooth) {
for (y=0; y<gridSize-1; y++) {
glBegin(GL_QUAD_STRIP);
for (x=0; x<gridSize; x++) {
@@ -1666,14 +1653,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
float *b = faceGridData[(y+0)*gridSize + x + 1].co;
float *c = faceGridData[(y+1)*gridSize + x + 1].co;
float *d = faceGridData[(y+1)*gridSize + x].co;
- float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
- float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
- float no[3];
- no[0] = b_dY*a_cZ - b_dZ*a_cY;
- no[1] = b_dZ*a_cX - b_dX*a_cZ;
- no[2] = b_dX*a_cY - b_dY*a_cX;
- glNormal3fv(no);
+ ccgDM_glNormalFast(a, b, c, d);
glVertex3fv(d);
glVertex3fv(c);
@@ -1753,132 +1734,188 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned ch
ccgFaceIterator_free(fi);
}
-static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(MTFace *tface, MCol *mcol, int matnr))
+static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
+ int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+ int (*drawParamsMapped)(void *userData, int index),
+ void *userData)
{
- /* unimplemented, no textures in editmode anyway */
-}
-static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData)
-{
- /* unfinished code, no textures in editmode anyway */
-
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
- int gridSize = ccgSubSurf_getGridSize(ss);
- MFace *mface = ccgdm->me->mface;
- MCol *mcol = ccgdm->me->mcol;
-// float uv[4][2];
-// float col[4][3];
+ MCol *mcol = DM_get_face_data_layer(dm, CD_MCOL);
+ MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+ char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
+ int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
+ int gridFaces = gridSize - 1;
- glBegin(GL_QUADS);
- for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ totface = ccgSubSurf_getNumFaces(ss);
+ for(i = 0; i < totface; i++) {
+ CCGFace *f = ccgdm->faceMap[i].face;
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
- int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
- MFace *mf = &mface[index];
+ int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
+ int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
unsigned char *cp= NULL;
- int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
- int flag = (findex == -1)? 0: setDrawParams(userData, findex);
+ int mat_nr;
+
+ if(faceFlags) {
+ drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
+ mat_nr= faceFlags[origIndex*4 + 1];
+ }
+ else {
+ drawSmooth = 1;
+ mat_nr= 0;
+ }
- if (flag==0)
+ if(drawParams)
+ flag = drawParams(tf, mcol, mat_nr);
+ else
+ flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
+
+ if (flag == 0) { /* flag 0 == the face is hidden or invisible */
+ if(tf) tf += gridFaces*gridFaces*numVerts;
+ if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
continue;
- else if (flag==1 && mcol)
- cp= (unsigned char*) &mcol[index*4];
+ }
+
+ /* flag 1 == use vertex colors */
+ if(mcol) {
+ if(flag==1) cp= (unsigned char*)mcol;
+ mcol += gridFaces*gridFaces*numVerts*4;
+ }
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- for (y=0; y<gridSize-1; y++) {
- for (x=0; x<gridSize-1; x++) {
- VertData *a = &faceGridData[(y+0)*gridSize + x + 0];
- VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
- VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
- VertData *d = &faceGridData[(y+1)*gridSize + x + 0];
+ VertData *a, *b;
- if (!(mf->flag&ME_SMOOTH)) {
- float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2];
- float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[2];
- float no[3];
+ if (drawSmooth) {
+ glShadeModel(GL_SMOOTH);
+ for (y=0; y<gridFaces; y++) {
+ glBegin(GL_QUAD_STRIP);
+ for (x=0; x<gridFaces; x++) {
+ a = &faceGridData[(y+0)*gridSize + x];
+ b = &faceGridData[(y+1)*gridSize + x];
- no[0] = b_dY*a_cZ - b_dZ*a_cY;
- no[1] = b_dZ*a_cX - b_dX*a_cZ;
- no[2] = b_dX*a_cY - b_dY*a_cX;
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3fv(a->no);
+ glVertex3fv(a->co);
- glNormal3fv(no);
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3fv(b->no);
+ glVertex3fv(b->co);
+
+ if(x != gridFaces-1) {
+ if(tf) tf++;
+ if(cp) cp += 16;
+ }
}
-// if (tf) glTexCoord2fv(tf->uv[0]);
-// if (cp) glColor3ub(cp[3], cp[2], cp[1]);
-// if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
-// glVertex3fv(mvert[mf->v1].co);
+ a = &faceGridData[(y+0)*gridSize + x];
+ b = &faceGridData[(y+1)*gridSize + x];
-/*
- {
- float x_v = (float) fx/(gridSize-1);
- float y_v = (float) fy/(gridSize-1);
- float data[6];
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3fv(a->no);
+ glVertex3fv(a->co);
- for (k=0; k<numDataComponents; k++) {
- data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) +
- (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
- }
-*/
-
-// if (cp) glColor3ub(cp[3], cp[2], cp[1]);
- if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
- glVertex3fv(d->co);
-// if (cp) glColor3ub(cp[7], cp[6], cp[5]);
- if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
- glVertex3fv(c->co);
-// if (cp) glColor3ub(cp[11], cp[10], cp[9]);
- if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3fv(b->no);
glVertex3fv(b->co);
-// if (cp) glColor3ub(cp[15], cp[14], cp[13]);
- if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
- glVertex3fv(a->co);
+
+ if(tf) tf++;
+ if(cp) cp += 16;
+
+ glEnd();
}
+ } else {
+ glShadeModel(GL_FLAT);
+ glBegin(GL_QUADS);
+ for (y=0; y<gridFaces; y++) {
+ for (x=0; x<gridFaces; x++) {
+ float *a = faceGridData[(y+0)*gridSize + x].co;
+ float *b = faceGridData[(y+0)*gridSize + x + 1].co;
+ float *c = faceGridData[(y+1)*gridSize + x + 1].co;
+ float *d = faceGridData[(y+1)*gridSize + x].co;
+
+ ccgDM_glNormalFast(a, b, c, d);
+
+ if(tf) glTexCoord2fv(tf->uv[1]);
+ if(cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glVertex3fv(d);
+
+ if(tf) glTexCoord2fv(tf->uv[2]);
+ if(cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glVertex3fv(c);
+
+ if(tf) glTexCoord2fv(tf->uv[3]);
+ if(cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glVertex3fv(b);
+
+ if(tf) glTexCoord2fv(tf->uv[0]);
+ if(cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glVertex3fv(a);
+
+ if(tf) tf++;
+ if(cp) cp += 16;
+ }
+ }
+ glEnd();
}
}
}
- glEnd();
+}
- ccgFaceIterator_free(fi);
-/*
- MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
- Mesh *me = mdm->me;
- MVert *mvert= mdm->verts;
- MFace *mface= me->mface;
- MTFace *tface = me->mtface;
- float *nors = mdm->nors;
- int a;
-
- for (a=0; a<me->totface; a++) {
- MFace *mf= &mface[a];
- if (tf) glTexCoord2fv(tf->uv[1]);
- if (cp) glColor3ub(cp[7], cp[6], cp[5]);
- if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
- glVertex3fv(mvert[mf->v2].co);
-
- if (tf) glTexCoord2fv(tf->uv[2]);
- if (cp) glColor3ub(cp[11], cp[10], cp[9]);
- if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
- glVertex3fv(mvert[mf->v3].co);
-
- if(mf->v4) {
- if (tf) glTexCoord2fv(tf->uv[3]);
- if (cp) glColor3ub(cp[15], cp[14], cp[13]);
- if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
- glVertex3fv(mvert[mf->v4].co);
+static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+{
+ ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
+}
+
+static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
+{
+ ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
+}
+
+static void ccgDM_drawUVEdges(DerivedMesh *dm)
+{
+
+ MFace *mf = dm->getFaceArray(dm);
+ MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+ int i;
+
+ if (tf) {
+ glBegin(GL_LINES);
+ for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
+ if(!(mf->flag&ME_HIDE)) {
+ glVertex2fv(tf->uv[0]);
+ glVertex2fv(tf->uv[1]);
+
+ glVertex2fv(tf->uv[1]);
+ glVertex2fv(tf->uv[2]);
+
+ if(!mf->v4) {
+ glVertex2fv(tf->uv[2]);
+ glVertex2fv(tf->uv[0]);
+ } else {
+ glVertex2fv(tf->uv[2]);
+ glVertex2fv(tf->uv[3]);
+
+ glVertex2fv(tf->uv[3]);
+ glVertex2fv(tf->uv[0]);
+ }
+ }
}
glEnd();
}
-*/
}
+
static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
+ GLubyte act_face_stipple[32*32/8] = DM_FACE_STIPPLE;
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int i, gridSize = ccgSubSurf_getGridSize(ss);
- int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
+ char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
@@ -1886,55 +1923,67 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
int origIndex;
- origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+ origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
- if(faceFlags) drawSmooth = (faceFlags[origIndex] & ME_SMOOTH);
+ if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
else drawSmooth = 1;
-
- if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
- for (S=0; S<numVerts; S++) {
- VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (drawSmooth) {
- glShadeModel(GL_SMOOTH);
- for (y=0; y<gridSize-1; y++) {
- glBegin(GL_QUAD_STRIP);
- for (x=0; x<gridSize; x++) {
- VertData *a = &faceGridData[(y+0)*gridSize + x];
- VertData *b = &faceGridData[(y+1)*gridSize + x];
-
- glNormal3fv(a->no);
- glVertex3fv(a->co);
- glNormal3fv(b->no);
- glVertex3fv(b->co);
+
+ if (index!=-1) {
+ int draw;
+ draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth);
+
+ if (draw) {
+ if (draw==2) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(act_face_stipple);
+ }
+
+ for (S=0; S<numVerts; S++) {
+ VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+ if (drawSmooth) {
+ glShadeModel(GL_SMOOTH);
+ for (y=0; y<gridSize-1; y++) {
+ glBegin(GL_QUAD_STRIP);
+ for (x=0; x<gridSize; x++) {
+ VertData *a = &faceGridData[(y+0)*gridSize + x];
+ VertData *b = &faceGridData[(y+1)*gridSize + x];
+
+ glNormal3fv(a->no);
+ glVertex3fv(a->co);
+ glNormal3fv(b->no);
+ glVertex3fv(b->co);
+ }
+ glEnd();
}
- glEnd();
- }
- } else {
- glShadeModel(GL_FLAT);
- glBegin(GL_QUADS);
- for (y=0; y<gridSize-1; y++) {
- for (x=0; x<gridSize-1; x++) {
- float *a = faceGridData[(y+0)*gridSize + x].co;
- float *b = faceGridData[(y+0)*gridSize + x + 1].co;
- float *c = faceGridData[(y+1)*gridSize + x + 1].co;
- float *d = faceGridData[(y+1)*gridSize + x].co;
- float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
- float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
- float no[3];
-
- no[0] = b_dY*a_cZ - b_dZ*a_cY;
- no[1] = b_dZ*a_cX - b_dX*a_cZ;
- no[2] = b_dX*a_cY - b_dY*a_cX;
- glNormal3fv(no);
-
- glVertex3fv(d);
- glVertex3fv(c);
- glVertex3fv(b);
- glVertex3fv(a);
+ } else {
+ glShadeModel(GL_FLAT);
+ glBegin(GL_QUADS);
+ for (y=0; y<gridSize-1; y++) {
+ for (x=0; x<gridSize-1; x++) {
+ float *a = faceGridData[(y+0)*gridSize + x].co;
+ float *b = faceGridData[(y+0)*gridSize + x + 1].co;
+ float *c = faceGridData[(y+1)*gridSize + x + 1].co;
+ float *d = faceGridData[(y+1)*gridSize + x].co;
+ float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
+ float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
+ float no[3];
+
+ no[0] = b_dY*a_cZ - b_dZ*a_cY;
+ no[1] = b_dZ*a_cX - b_dX*a_cZ;
+ no[2] = b_dX*a_cY - b_dY*a_cX;
+ glNormal3fv(no);
+
+ glVertex3fv(d);
+ glVertex3fv(c);
+ glVertex3fv(b);
+ glVertex3fv(a);
+ }
}
+ glEnd();
}
- glEnd();
}
+ if (draw==2)
+ glDisable(GL_POLYGON_STIPPLE);
}
}
}
@@ -2035,7 +2084,7 @@ static void ccgDM_release(DerivedMesh *dm) {
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
- int useSubsurfUv, Mesh *me,
+ int useSubsurfUv,
DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
@@ -2046,7 +2095,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int i;
int vertNum, edgeNum, faceNum;
int *vertOrigIndex, *edgeOrigIndex, *faceOrigIndex;
- int *faceFlags, *edgeFlags;
+ int *edgeFlags;
+ char *faceFlags;
int edgeSize;
int gridSize;
int gridFaces;
@@ -2059,20 +2109,14 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
MFace *mface = NULL;
FaceVertWeight *qweight, *tweight;
- if(dm) {
- DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
- ccgSubSurf_getNumFinalEdges(ss),
- ccgSubSurf_getNumFinalFaces(ss));
- DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
- DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
-
- CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
- CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
- } else {
- DM_init(&ccgdm->dm, ccgSubSurf_getNumFinalVerts(ss),
- ccgSubSurf_getNumFinalEdges(ss),
- ccgSubSurf_getNumFinalFaces(ss));
- }
+ DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
+ ccgSubSurf_getNumFinalEdges(ss),
+ ccgSubSurf_getNumFinalFaces(ss));
+ DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
+ DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
+
+ CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
+ CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
ccgdm->dm.getMinMax = ccgDM_getMinMax;
ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
@@ -2105,6 +2149,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
+ ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
@@ -2114,7 +2159,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->ss = ss;
ccgdm->drawInteriorEdges = drawInteriorEdges;
ccgdm->useSubsurfUv = useSubsurfUv;
- ccgdm->me = me;
totvert = ccgSubSurf_getNumVerts(ss);
ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
@@ -2122,7 +2166,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- ccgdm->vertMap[(int) ccgSubSurf_getVertVertHandle(ss, v)].vert = v;
+ ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))].vert = v;
}
ccgVertIterator_free(vi);
@@ -2132,7 +2176,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
- ccgdm->edgeMap[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)].edge = e;
+ ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))].edge = e;
}
totface = ccgSubSurf_getNumFaces(ss);
@@ -2141,7 +2185,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- ccgdm->faceMap[(int) ccgSubSurf_getFaceFaceHandle(ss, f)].face = f;
+ ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
}
ccgFaceIterator_free(fi);
@@ -2159,15 +2203,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
edgeNum = 0;
faceNum = 0;
- if(dm) {
- mvert = dm->getVertArray(dm);
- medge = dm->getEdgeArray(dm);
- mface = dm->getFaceArray(dm);
- } else if(me) {
- mvert = me->mvert;
- medge = me->medge;
- mface = me->mface;
- }
+ mvert = dm->getVertArray(dm);
+ medge = dm->getEdgeArray(dm);
+ mface = dm->getFaceArray(dm);
vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
@@ -2180,7 +2218,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
- int origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
+ int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
int S, x, y;
int vertIdx[4];
@@ -2195,7 +2233,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(S = 0; S < numVerts; S++) {
CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
- vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
}
DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
@@ -2277,7 +2315,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
}
}
- faceFlags[index] = mface[origIndex].flag;
+ faceFlags[index*4] = mface[origIndex].flag;
+ faceFlags[index*4 + 1] = mface[origIndex].mat_nr;
edgeNum += numFinalEdges;
}
@@ -2300,13 +2339,13 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
int x;
int vertIdx[2];
- int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
+ int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
CCGVert *v;
v = ccgSubSurf_getEdgeVert0(ss, e);
- vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
v = ccgSubSurf_getEdgeVert1(ss, e);
- vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
ccgdm->edgeMap[index].startVert = vertNum;
ccgdm->edgeMap[index].startEdge = edgeNum;
@@ -2340,7 +2379,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int mapIndex = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
int vertIdx;
- vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
+ vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
ccgdm->vertMap[index].startVert = vertNum;
@@ -2381,10 +2420,17 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
return (DerivedMesh *)getCCGDerivedMesh(smd->emCache,
drawInteriorEdges,
- useSubsurfUv, NULL, dm);
+ useSubsurfUv, dm);
} else if(useRenderParams) {
/* Do not use cache in render mode. */
- CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, useSimple);
+ CCGSubSurf *ss;
+ int levels;
+
+ levels= get_render_subsurf_level(&G.scene->r, smd->renderLevels);
+ if(levels == 0)
+ return dm;
+
+ ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
@@ -2418,8 +2464,13 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+
return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
useSubsurfUv, dm);
+
+ /*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
+ drawInteriorEdges,
+ useSubsurfUv, dm);*/
} else {
if (smd->mCache && isFinalCalc) {
ccgSubSurf_free(smd->mCache);
@@ -2429,6 +2480,11 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+ /*smd->mCache = ss;
+ result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
+ drawInteriorEdges,
+ useSubsurfUv, dm);*/
+
result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
useSubsurfUv, dm);
@@ -2441,11 +2497,11 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
{
- /* Finds the subsurf limit positions for the verts in a mesh
- * and puts them in an array of floats. Please note that the
- * calculated vert positions is incorrect for the verts
- * on the boundary of the mesh.
- */
+ /* Finds the subsurf limit positions for the verts in a mesh
+ * and puts them in an array of floats. Please note that the
+ * calculated vert positions is incorrect for the verts
+ * on the boundary of the mesh.
+ */
CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
float edge_sum[3], face_sum[3];
CCGVertIterator *vi;
@@ -2456,7 +2512,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
vi = ccgSubSurf_getVertIterator(ss);
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
+ int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
int N = ccgSubSurf_getVertNumEdges(ss, v);
int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
float *co;
@@ -2474,6 +2530,11 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
}
+ /* ad-hoc correction for boundary vertices, to at least avoid them
+ moving completely out of place (brecht) */
+ if(numFaces && numFaces != N)
+ VecMulf(face_sum, (float)N/(float)numFaces);
+
co = ccgSubSurf_getVertData(ss, v);
positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index ea0dabe1e81..c54ab3e82ab 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1033,7 +1033,7 @@ int txt_find_string(Text *text, char *findstr)
void txt_cut_sel (Text *text)
{
- txt_copy_sel(text);
+ txt_copy_clipboard(text);
txt_delete_sel(text);
txt_make_dirty(text);
@@ -2352,7 +2352,7 @@ int setcurr_tab (Text *text)
int test = 0;
char *word = ":";
char *comm = "#";
- char back_words[3][7] = {"return", "break", "pass"};
+ char back_words[4][7] = {"return", "break", "pass", "yield"};
if (!text) return 0;
if (!text->curl) return 0;
@@ -2369,16 +2369,25 @@ int setcurr_tab (Text *text)
if(strstr(text->curl->line, word))
{
//if we find a : then add a tab but not if it is in a comment
- if(strcspn(text->curl->line, word) < strcspn(text->curl->line, comm))
+ int a, indent = 0;
+ for(a=0; text->curl->line[a] != '\0'; a++)
{
+ if (text->curl->line[a]=='#') {
+ break;
+ } else if (text->curl->line[a]==':') {
+ indent = 1;
+ } else if (text->curl->line[a]==']') {
+ indent = 0;
+ }
+ }
+ if (indent) {
i++;
-
}
}
- while(test < 3)
+ for(test=0; test < 4; test++)
{
- //if there are these 3 key words then remove a tab because we are done with the block
+ //if there are these 4 key words then remove a tab because we are done with the block
if(strstr(text->curl->line, back_words[test]) && i > 0)
{
if(strcspn(text->curl->line, back_words[test]) < strcspn(text->curl->line, comm))
@@ -2386,7 +2395,6 @@ int setcurr_tab (Text *text)
i--;
}
}
- test++;
}
return i;
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index bda933802ee..3b8292a791c 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -107,6 +107,7 @@ void open_plugin_tex(PluginTex *pit)
pit->result= 0;
pit->cfra= 0;
pit->version= 0;
+ pit->instance_init= 0;
/* clear the error list */
PIL_dynlib_get_error_as_string(NULL);
@@ -238,13 +239,10 @@ void init_mapping(TexMapping *texmap)
/* ****************** COLORBAND ******************* */
-ColorBand *add_colorband(int rangetype)
+void init_colorband(ColorBand *coba, int rangetype)
{
- ColorBand *coba;
int a;
- coba= MEM_callocN( sizeof(ColorBand), "colorband");
-
coba->data[0].pos= 0.0;
coba->data[1].pos= 1.0;
@@ -281,6 +279,15 @@ ColorBand *add_colorband(int rangetype)
coba->tot= 2;
+}
+
+ColorBand *add_colorband(int rangetype)
+{
+ ColorBand *coba;
+
+ coba= MEM_callocN( sizeof(ColorBand), "colorband");
+ init_colorband(coba, rangetype);
+
return coba;
}
@@ -390,6 +397,7 @@ void free_texture(Tex *tex)
free_plugin_tex(tex->plugin);
if(tex->coba) MEM_freeN(tex->coba);
if(tex->env) BKE_free_envmap(tex->env);
+ BKE_previewimg_free(&tex->preview);
BKE_icon_delete((struct ID*)tex);
tex->id.icon_id = 0;
}
@@ -404,7 +412,7 @@ void default_tex(Tex *tex)
tex->stype= 0;
tex->flag= TEX_CHECKER_ODD;
- tex->imaflag= TEX_INTERPOL+TEX_MIPMAP;
+ tex->imaflag= TEX_INTERPOL+TEX_MIPMAP+TEX_USEALPHA;
tex->extend= TEX_REPEAT;
tex->cropxmin= tex->cropymin= 0.0;
tex->cropxmax= tex->cropymax= 1.0;
@@ -418,7 +426,8 @@ void default_tex(Tex *tex)
tex->turbul= 5.0;
tex->nabla= 0.025; // also in do_versions
tex->bright= 1.0;
- tex->contrast= tex->filtersize= 1.0;
+ tex->contrast= 1.0;
+ tex->filtersize= 1.0;
tex->rfac= 1.0;
tex->gfac= 1.0;
tex->bfac= 1.0;
@@ -462,6 +471,8 @@ void default_tex(Tex *tex)
tex->iuser.fie_ima= 2;
tex->iuser.ok= 1;
tex->iuser.frames= 100;
+
+ tex->preview = NULL;
}
/* ------------------------------------------------------------------------- */
@@ -507,6 +518,7 @@ void default_mtex(MTex *mtex)
mtex->norfac= 0.5;
mtex->varfac= 1.0;
mtex->dispfac=0.2;
+ mtex->normapspace= MTEX_NSPACE_TANGENT;
}
@@ -541,6 +553,8 @@ Tex *copy_texture(Tex *tex)
if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
+ if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
+
return texn;
}
diff --git a/source/blender/blenkernel/intern/verse_geometry_node.c b/source/blender/blenkernel/intern/verse_geometry_node.c
index 8d58d140c79..613d4eadbec 100644
--- a/source/blender/blenkernel/intern/verse_geometry_node.c
+++ b/source/blender/blenkernel/intern/verse_geometry_node.c
@@ -141,6 +141,11 @@ static void recalculate_verseface_normals(VNode *vnode)
*/
void add_item_to_send_queue(ListBase *lb, void *item, short type)
{
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct VerseVert *vvert;
+ struct VerseFace *vface;
+
/* this prevent from adding duplicated faces */
if(type==VERSE_FACE) {
struct Link *link = (Link*)lb->first;
@@ -188,35 +193,59 @@ void add_item_to_send_queue(ListBase *lb, void *item, short type)
send_verse_taggroup((VTagGroup*)item);
break;
case VERSE_VERT_UINT32: /* parent item has to exist */
- if( ((verse_parent*)((uint32_item*)item)->parent)->id != -1)
+ vnode = (((uint32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
+ vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((uint32_item*)item)->id );
+ if(vvert != NULL)
send_verse_vert_uint32((uint32_item*)item, type);
break;
case VERSE_VERT_REAL32: /* parent item has to exist */
- if( ((verse_parent*)((real32_item*)item)->parent)->id != -1)
+ vnode = (((real32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
+ vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((real32_item*)item)->id );
+ if( vvert != NULL)
send_verse_vert_real32((real32_item*)item, type);
break;
case VERSE_VERT_VEC_REAL32: /* parent item has to exist */
- if( ((verse_parent*)((vec_real32_item*)item)->parent)->id != -1)
+ vnode = (((vec_real32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 0 );
+ vvert = (VerseVert*)BLI_dlist_find_link(&(vlayer->dl), ((vec_real32_item*)item)->id );
+ if(vvert != NULL)
send_verse_vert_vec_real32((vec_real32_item*)item, type);
break;
case VERSE_FACE_UINT8: /* parent item has to exist */
- if( ((verse_parent*)((uint8_item*)item)->parent)->id != -1)
+ vnode = (((uint8_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
+ vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((uint8_item*)item)->id );
+ if(vface != NULL)
send_verse_face_uint8((uint8_item*)item, type);
break;
case VERSE_FACE_UINT32: /* parent item has to exist */
- if( ((verse_parent*)((uint32_item*)item)->parent)->id != -1)
+ vnode = (((uint32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
+ vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((uint32_item*)item)->id );
+ if(vface != NULL)
send_verse_face_uint32((uint32_item*)item, type);
break;
case VERSE_FACE_REAL32: /* parent item has to exist */
- if( ((verse_parent*)((real32_item*)item)->parent)->id != -1)
+ vnode = (((real32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
+ vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((real32_item*)item)->id );
+ if(vface != NULL)
send_verse_face_real32((real32_item*)item, type);
break;
case VERSE_FACE_QUAT_UINT32: /* parent item has to exist */
- if( ((verse_parent*)((quat_uint32_item*)item)->parent)->id != -1)
+ vnode = (((quat_uint32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
+ vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((quat_uint32_item*)item)->id );
+ if(vface != NULL)
send_verse_face_corner_quat_uint32((quat_uint32_item*)item, type);
break;
case VERSE_FACE_QUAT_REAL32: /* parent item has to exist */
- if( ((verse_parent*)((quat_real32_item*)item)->parent)->id != -1)
+ vnode = (((quat_real32_item*)item)->vlayer)->vnode;
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), 1 );
+ vface = (VerseFace*)BLI_dlist_find_link(&(vlayer->dl), ((quat_real32_item*)item)->id );
+ if(vface != NULL)
send_verse_face_corner_quat_real32((quat_real32_item*)item, type);
break;
}
@@ -479,12 +508,10 @@ static VerseVert* find_verse_vert_in_queue(
*/
void send_verse_face_corner_quat_real32(quat_real32_item *item, short type)
{
- struct VerseFace *vface = (VerseFace*)item->parent;
-
verse_send_g_polygon_set_corner_real32(
- vface->vlayer->vnode->id,
- item->layer_id,
- vface->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value[0],
item->value[1],
item->value[2],
@@ -496,12 +523,10 @@ void send_verse_face_corner_quat_real32(quat_real32_item *item, short type)
*/
void send_verse_face_corner_quat_uint32(quat_uint32_item *item, short type)
{
- struct VerseFace *vface = (VerseFace*)item->parent;
-
verse_send_g_polygon_set_corner_uint32(
- vface->vlayer->vnode->id,
- item->layer_id,
- vface->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value[0],
item->value[1],
item->value[2],
@@ -513,12 +538,10 @@ void send_verse_face_corner_quat_uint32(quat_uint32_item *item, short type)
*/
void send_verse_face_real32(real32_item *item, short type)
{
- struct VerseFace *vface = (VerseFace*)item->parent;
-
verse_send_g_polygon_set_face_real32(
- vface->vlayer->vnode->id,
- item->layer_id,
- vface->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value);
}
@@ -527,12 +550,10 @@ void send_verse_face_real32(real32_item *item, short type)
*/
void send_verse_face_uint32(uint32_item *item, short type)
{
- struct VerseFace *vface = (VerseFace*)item->parent;
-
verse_send_g_polygon_set_face_uint32(
- vface->vlayer->vnode->id,
- item->layer_id,
- vface->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value);
}
@@ -541,12 +562,10 @@ void send_verse_face_uint32(uint32_item *item, short type)
*/
void send_verse_face_uint8(uint8_item *item, short type)
{
- struct VerseFace *vface = (VerseFace*)item->parent;
-
verse_send_g_polygon_set_face_uint8(
- vface->vlayer->vnode->id,
- item->layer_id,
- vface->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value);
}
@@ -555,12 +574,10 @@ void send_verse_face_uint8(uint8_item *item, short type)
*/
void send_verse_vert_vec_real32(vec_real32_item *item, short type)
{
- struct VerseVert *vvert = (VerseVert*)item->parent;
-
verse_send_g_vertex_set_xyz_real32(
- vvert->vlayer->vnode->id,
- item->layer_id,
- vvert->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value[0],
item->value[1],
item->value[2]);
@@ -571,12 +588,10 @@ void send_verse_vert_vec_real32(vec_real32_item *item, short type)
*/
void send_verse_vert_real32(real32_item *item, short type)
{
- struct VerseVert *vvert = (VerseVert*)item->parent;
-
verse_send_g_vertex_set_real32(
- vvert->vlayer->vnode->id,
- item->layer_id,
- vvert->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value);
}
@@ -585,12 +600,10 @@ void send_verse_vert_real32(real32_item *item, short type)
*/
void send_verse_vert_uint32(uint32_item *item, short type)
{
- struct VerseVert *vvert = (VerseVert*)item->parent;
-
verse_send_g_vertex_set_uint32(
- vvert->vlayer->vnode->id,
- item->layer_id,
- vvert->id,
+ item->vlayer->vnode->id,
+ item->vlayer->id,
+ item->id,
item->value);
}
@@ -663,7 +676,6 @@ static void send_verse_face(VerseFace *vface)
vface->flag |= FACE_SENT;
if(vface->v3 != -1) {
-/* printf("\tSEND: VerseFace: %d, %d, %d, %d, %d\n", vface->id, vface->v0, vface->v3, vface->v2, vface->v1);*/
verse_send_g_polygon_set_corner_uint32(
vface->vlayer->vnode->id,
vface->vlayer->id,
@@ -674,7 +686,6 @@ static void send_verse_face(VerseFace *vface)
vface->v1); /* verse use clock-wise winding */
}
else {
-/* printf("\tSEND: VerseFace: %d, %d, %d, %d, %d\n", vface->id, vface->v0, vface->v2, vface->v1, vface->v3);*/
verse_send_g_polygon_set_corner_uint32(
vface->vlayer->vnode->id,
vface->vlayer->id,
@@ -948,162 +959,80 @@ VGeomData *create_geometry_data(void)
return geom;
}
-/*
- * callback function: vertex crease was set
- */
-static void cb_g_crease_set_vertex(
- void *user_data,
- VNodeID node_id,
- const char *layer,
- uint32 def_crease)
+/* Create item containing 4 floats */
+static quat_real32_item *create_quat_real32_item(
+ VLayer *vlayer,
+ uint32 item_id,
+ real32 v0,
+ real32 v1,
+ real32 v2,
+ real32 v3)
{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
-}
+ struct quat_real32_item *item;
-/*
- * callback function: edge crease was set
- */
-static void cb_g_crease_set_edge(
- void *user_data,
- VNodeID node_id,
- const char *layer,
- uint32 def_crease)
-{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
-}
+ item = (quat_real32_item*)MEM_mallocN(sizeof(quat_real32_item), "quat_real32_item");
-/*
- * callback function: float value for polygon was set up
- */
-static void cb_g_polygon_set_face_real32(
- void *user_def,
- VNodeID node_id,
- VLayerID layer_id,
- uint32 polygon_id,
- real32 value)
-{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
-}
+ item->vlayer = vlayer;
+ item->id = item_id;
+ item->value[0] = v0;
+ item->value[1] = v1;
+ item->value[2] = v2;
+ item->value[3] = v3;
-/*
- * callback function: int values for polygon was set up
- */
-static void cb_g_polygon_set_face_uint32(
- void *user_def,
- VNodeID node_id,
- VLayerID layer_id,
- uint32 polygon_id,
- uint32 value)
-{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
+ return item;
}
-static uint8_item *create_uint8_item(void)
+/* Create item containing 1 float */
+static real32_item *create_real32_item(VLayer *vlayer, uint32 item_id, real32 value)
{
- struct uint8_item *item;
+ struct real32_item *item;
- item = (uint8_item*)MEM_mallocN(sizeof(uint8_item), "uint8_item");
- item->value = 0;
+ item = (real32_item*)MEM_mallocN(sizeof(real32_item), "real32_item");
+
+ item->vlayer = vlayer;
+ item->id = item_id;
+ item->value = value;
return item;
}
-/*
- * callback function: uint8 value for polygon was set up
- */
-static void cb_g_polygon_set_face_uint8(
- void *user_def,
- VNodeID node_id,
- VLayerID layer_id,
- uint32 polygon_id,
- uint8 value)
+/* Create item containing 1 integer */
+static uint32_item *create_uint32_item(VLayer *vlayer, uint32 item_id, uint32 value)
{
- struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;
- struct VLayer *vlayer;
- struct uint8_item *item;
+ struct uint32_item *item;
- if(!session) return;
+ item = (uint32_item*)MEM_mallocN(sizeof(uint32_item), "uint32_item");
- /* find needed node (we can be sure, that it is geometry node) */
- vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+ item->vlayer = vlayer;
+ item->id = item_id;
+ item->value = value;
- /* find layer containing uint_8 data */
- vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
-
- /* try to find item*/
- item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
-
- if(item) {
- item->value = value;
- }
- else {
- item = create_uint8_item();
- BLI_dlist_add_item_index(&(vlayer->dl), item, polygon_id);
- item->value = value;
- }
+ return item;
}
-/*
- * callback function: float value for polygon corner was set up
- */
-static void cb_g_polygon_set_corner_real32(
- void *user_def,
- VNodeID node_id,
- VLayerID layer_id,
- uint32 polygon_id,
- real32 v0,
- real32 v1,
- real32 v2,
- real32 v3)
+/* Create item containing 1 byte */
+static uint8_item *create_uint8_item(VLayer *vlayer, uint32 item_id, uint8 value)
{
+ struct uint8_item *item;
+
+ item = (uint8_item*)MEM_mallocN(sizeof(uint8_item), "uint8_item");
+
+ item->vlayer = vlayer;
+ item->id = item_id;
+ item->value = value;
+
+ return item;
}
/*
- * callback function: polygon is deleted
+ * callback function: vertex crease was set
*/
-static void cb_g_polygon_delete(
+static void cb_g_crease_set_vertex(
void *user_data,
VNodeID node_id,
- uint32 polygon_id)
+ const char *layer,
+ uint32 def_crease)
{
- struct VerseSession *session = (VerseSession*)current_verse_session();
- VNode *vnode;
- VLayer *vlayer;
- VerseFace *vface;
-
- if(!session) return;
-
- /* find needed node (we can be sure, that it is geometry node) */
- vnode = BLI_dlist_find_link(&(session->nodes), node_id);
-
- /* find layer containing faces */
- vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
-
- /* find wanted VerseFace */
- vface = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
-
- if(!vface) return;
-
- /* update edge hash */
- update_edgehash_of_deleted_verseface(vnode, vface);
-
- ((VGeomData*)vnode->data)->post_polygon_delete(vface);
-
- /* decrease references at coresponding VerseVertexes */
- vface->vvert0->counter--;
- vface->vvert1->counter--;
- vface->vvert2->counter--;
- if(vface->vvert3) vface->vvert3->counter--;
-
- /* delete unneeded VerseVertexes */
- free_unneeded_verseverts_of_verseface(vnode, vface);
-
- free_verse_face(vlayer, vface);
}
/*
@@ -1365,6 +1294,206 @@ static void update_edgehash_of_new_verseface(
}
/*
+ * callback function: edge crease was set
+ */
+static void cb_g_crease_set_edge(
+ void *user_data,
+ VNodeID node_id,
+ const char *layer,
+ uint32 def_crease)
+{
+}
+
+/*
+ * callback function: float value for polygon was set up
+ */
+static void cb_g_polygon_set_face_real32(
+ void *user_def,
+ VNodeID node_id,
+ VLayerID layer_id,
+ uint32 polygon_id,
+ real32 value)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct real32_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
+
+ if(item) {
+ item->value = value;
+ }
+ else {
+ item = create_real32_item(vlayer, polygon_id, value);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
+}
+
+/*
+ * callback function: int values for polygon was set up
+ */
+static void cb_g_polygon_set_face_uint32(
+ void *user_def,
+ VNodeID node_id,
+ VLayerID layer_id,
+ uint32 polygon_id,
+ uint32 value)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct uint32_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
+
+ if(item) {
+ item->value = value;
+ }
+ else {
+ item = create_uint32_item(vlayer, polygon_id, value);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
+}
+
+/*
+ * callback function: uint8 value for polygon was set up
+ */
+static void cb_g_polygon_set_face_uint8(
+ void *user_def,
+ VNodeID node_id,
+ VLayerID layer_id,
+ uint32 polygon_id,
+ uint8 value)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct uint8_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
+
+ if(item) {
+ item->value = value;
+ }
+ else {
+ item = create_uint8_item(vlayer, polygon_id, value);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
+}
+
+/*
+ * callback function: float value for polygon corner was set up
+ */
+static void cb_g_polygon_set_corner_real32(
+ void *user_def,
+ VNodeID node_id,
+ VLayerID layer_id,
+ uint32 polygon_id,
+ real32 v0,
+ real32 v1,
+ real32 v2,
+ real32 v3)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct quat_real32_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
+
+ if(item) {
+ item->value[0] = v0;
+ item->value[1] = v1;
+ item->value[2] = v2;
+ item->value[3] = v3;
+ }
+ else {
+ item = create_quat_real32_item(vlayer, polygon_id, v0, v1, v2, v3);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
+}
+
+/*
+ * callback function: polygon is deleted
+ */
+static void cb_g_polygon_delete(
+ void *user_data,
+ VNodeID node_id,
+ uint32 polygon_id)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ VNode *vnode;
+ VLayer *vlayer;
+ VerseFace *vface;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = BLI_dlist_find_link(&(session->nodes), node_id);
+
+ /* find layer containing faces */
+ vlayer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
+
+ /* find wanted VerseFace */
+ vface = BLI_dlist_find_link(&(vlayer->dl), polygon_id);
+
+ if(!vface) return;
+
+ /* update edge hash */
+ update_edgehash_of_deleted_verseface(vnode, vface);
+
+ ((VGeomData*)vnode->data)->post_polygon_delete(vface);
+
+ /* decrease references at coresponding VerseVertexes */
+ vface->vvert0->counter--;
+ vface->vvert1->counter--;
+ vface->vvert2->counter--;
+ if(vface->vvert3) vface->vvert3->counter--;
+
+ /* delete unneeded VerseVertexes */
+ free_unneeded_verseverts_of_verseface(vnode, vface);
+
+ free_verse_face(vlayer, vface);
+}
+
+/*
* callback function: new polygon (face) created or existing polygon was changed
*/
static void cb_g_polygon_set_corner_uint32(
@@ -1395,8 +1524,6 @@ static void cb_g_polygon_set_corner_uint32(
/* we have to test coretness of incoming data */
if(!test_polygon_set_corner_uint32(v0, v1, v2, v3)) return;
-/* printf("\tRECEIVE VerseFace: %d, %d, %d, %d, %d\n", polygon_id, v0, v1, v2, v3);*/
-
/* Blender uses different order of vertexes */
if(v3!=-1) { /* quat swap */
unsigned int v; v = v1; v1 = v3; v3 = v;
@@ -1414,12 +1541,10 @@ static void cb_g_polygon_set_corner_uint32(
if(vface) {
BLI_remlink(&(vlayer->queue), (void*)vface);
BLI_dlist_add_item_index(&(vlayer->dl), (void*)vface, (unsigned int)polygon_id);
-/* printf("\treceived changed face (changed by this app)\n");*/
}
}
if(!vface) {
-/* printf("\tno vface\n");*/
/* try to find VerseFace in list of VerseVaces created by me and set up polygon and
* layer ids */
vface = find_verse_face_in_queue(vlayer, node_id, polygon_id, v0, v1, v2, v3);
@@ -1428,12 +1553,10 @@ static void cb_g_polygon_set_corner_uint32(
update_edgehash_of_new_verseface(vnode, v0, v1, v2, v3);
if(vface){
-/* printf("\tremove from vface queue\n");*/
/* I creeated this face ... remove VerseFace from queue */
BLI_remlink(&(vlayer->queue), (void*)vface);
}
else {
-/* printf("\tcreate vface\n");*/
/* some other client created this face*/
vface = create_verse_face(vlayer, polygon_id, v0, v1, v2, v3);
}
@@ -1452,7 +1575,6 @@ static void cb_g_polygon_set_corner_uint32(
((VGeomData*)vnode->data)->post_polygon_create(vface);
}
else {
-/* printf("\torphan vface\n");*/
/* when all needed VerseVertexes weren't received, then VerseFace is moved to
* the list of orphans waiting on needed vertexes */
vface->flag |= FACE_RECEIVED;
@@ -1461,7 +1583,6 @@ static void cb_g_polygon_set_corner_uint32(
}
else {
VLayer *vert_vlayer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
-/* printf("\tvface changed\n");*/
/* VerseVertexes of existing VerseFace were changed (VerseFace will use some different
* VerseVertexes or it will use them in different order) */
@@ -1594,8 +1715,29 @@ static void cb_g_vertex_set_real32(
uint32 vertex_id,
real32 value)
{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct real32_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), vertex_id);
+
+ if(item) {
+ item->value = value;
+ }
+ else {
+ item = create_real32_item(vlayer, vertex_id, value);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
}
/*
@@ -1608,8 +1750,29 @@ static void cb_g_vertex_set_uint32(
uint32 vertex_id,
uint32 value)
{
-/* struct VerseSession *session = (VerseSession*)current_verse_session();
- struct VNode *vnode;*/
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VLayer *vlayer;
+ struct uint32_item *item;
+
+ if(!session) return;
+
+ /* find needed node (we can be sure, that it is geometry node) */
+ vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ /* find layer containing uint_8 data */
+ vlayer = (VLayer*)BLI_dlist_find_link(&(((VGeomData*)vnode->data)->layers), (unsigned int)layer_id);
+
+ /* try to find item*/
+ item = BLI_dlist_find_link(&(vlayer->dl), vertex_id);
+
+ if(item) {
+ item->value = value;
+ }
+ else {
+ item = create_uint32_item(vlayer, vertex_id, value);
+ BLI_dlist_add_item_index(&(vlayer->dl), item, item->id);
+ }
}
/*
diff --git a/source/blender/blenkernel/intern/verse_method.c b/source/blender/blenkernel/intern/verse_method.c
new file mode 100644
index 00000000000..89b5282acfd
--- /dev/null
+++ b/source/blender/blenkernel/intern/verse_method.c
@@ -0,0 +1,523 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Nathan Letwory.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WITH_VERSE
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_userdef_types.h"
+#include "DNA_text_types.h"
+
+#include "BLI_dynamiclist.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "BIF_verse.h"
+
+#include "BKE_bad_level_calls.h"
+#include "BKE_library.h"
+#include "BKE_text.h"
+#include "BKE_verse.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "verse.h"
+
+/* helper struct for creating method descriptions */
+typedef struct VMethodInfo {
+ const char *name;
+ uint8 param_count;
+ const VNOParamType param_type[4];
+ const char *param_name[4];
+ uint16 id;
+} VMethodInfo;
+
+#ifdef VERSECHAT
+/* array with methods for verse chat */
+static VMethodInfo vmethod_info[] = {
+ { "join", 1, { VN_O_METHOD_PTYPE_STRING }, { "channel"}},
+ { "leave", 1, { VN_O_METHOD_PTYPE_STRING }, { "channel"}},
+ { "hear", 3, { VN_O_METHOD_PTYPE_STRING, VN_O_METHOD_PTYPE_STRING, VN_O_METHOD_PTYPE_STRING }, { "channel", "from", "msg"}}
+};
+#endif
+
+/* lookup a method group based on its name */
+struct VMethodGroup *lookup_vmethodgroup_name(ListBase *lb, const char *name) {
+ struct VMethodGroup *vmg;
+
+ for(vmg= lb->first; vmg; vmg= vmg->next)
+ if(strcmp(vmg->name,name)==0) break;
+
+ return vmg;
+}
+
+/* lookup a method group based on its group_id */
+struct VMethodGroup *lookup_vmethodgroup(ListBase *lb, uint16 group_id) {
+ struct VMethodGroup *vmg;
+
+ for(vmg= lb->first; vmg; vmg= vmg->next)
+ if(vmg->group_id==group_id) break;
+
+ return vmg;
+}
+
+/* lookup a method based on its name */
+struct VMethod *lookup_vmethod_name(ListBase *lb, const char *name) {
+ struct VMethod *vm;
+ for(vm= lb->first; vm; vm= vm->next)
+ if(strcmp(vm->name,name)==0) break;
+
+ return vm;
+}
+
+/* lookup a method based on its method_id */
+struct VMethod *lookup_vmethod(ListBase *lb, uint8 method_id) {
+ struct VMethod *vm;
+ for(vm= lb->first; vm; vm= vm->next)
+ if(vm->id==method_id) break;
+
+ return vm;
+}
+
+#ifdef VERSECHAT
+/*
+ * send say command
+ */
+void send_say(const char *chan, const char *utter)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ VNOPackedParams *utterpack;
+ VNOParam args[2];
+
+ vnode= (VNode *)(session->nodes.lb.first);
+
+ for( ; vnode; vnode= vnode->next) {
+ if(strcmp(vnode->name, "tawksrv")==0) {
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
+ if(!vmg) break;
+ vm= lookup_vmethod_name(&(vmg->methods), "say");
+ if(!vm) break;
+ args[0].vstring= (char *)chan;
+ args[1].vstring= (char *)utter;
+ if((utterpack= verse_method_call_pack(vm->param_count, vm->param_type, args))!=NULL) {
+ verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, utterpack);
+ }
+ break;
+ }
+
+ }
+}
+
+/*
+ * send logout command
+ */
+void send_logout(VNode *vnode)
+{
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ VNOPackedParams *pack;
+
+ vnode->chat_flag = CHAT_LOGGED;
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
+ if(!vmg) return;
+ vm= lookup_vmethod_name(&(vmg->methods), "logout");
+ if(!vm) return;
+
+ if((pack= verse_method_call_pack(vm->param_count, vm->param_type, NULL))!=NULL) {
+ verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, pack);
+ }
+ vnode->chat_flag = CHAT_NOTLOGGED;
+}
+
+/*
+ * send join command
+ */
+void send_join(VNode *vnode, const char *chan)
+{
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ VNOPackedParams *join;
+ VNOParam channel[1];
+
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
+ if(!vmg) return;
+ vm= lookup_vmethod_name(&(vmg->methods), "join");
+ if(!vm) return;
+
+ channel[0].vstring= (char *)chan;
+ if((join= verse_method_call_pack(vm->param_count, vm->param_type, channel))!=NULL) {
+ verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, join);
+ }
+}
+
+/*
+ * send leave command
+ */
+void send_leave(VNode *vnode, const char *chan)
+{
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ VNOPackedParams *leave;
+ VNOParam channel[1];
+
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
+ if(!vmg) return;
+ vm= lookup_vmethod_name(&(vmg->methods), "leave");
+ if(!vm) return;
+
+ channel[0].vstring= (char *)chan;
+ if((leave= verse_method_call_pack(vm->param_count, vm->param_type, channel))!=NULL) {
+ verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, leave);
+ }
+}
+
+/*
+ * send login command
+ */
+void send_login(VNode *vnode)
+{
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ VNOPackedParams *login;
+ VNOParam param[1];
+
+ vnode->chat_flag = CHAT_LOGGED;
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk");
+ if(!vmg) return;
+ vm= lookup_vmethod_name(&(vmg->methods), "login");
+ if(!vm) return;
+
+ param[0].vstring= U.verseuser;
+
+ if((login= verse_method_call_pack(vm->param_count, vm->param_type, param))!=NULL) {
+ verse_send_o_method_call(vnode->id, vmg->group_id, vm->id, vnode->session->avatar, login);
+ }
+ vnode->chat_flag = CHAT_LOGGED;
+
+ vnode= lookup_vnode(vnode->session, vnode->session->avatar);
+ vmg= lookup_vmethodgroup_name(&(vnode->methodgroups), "tawk-client");
+ if(!vmg)
+ verse_send_o_method_group_create(vnode->session->avatar, ~0, "tawk-client");
+}
+#endif
+
+/*
+ * Free a VMethod
+ */
+void free_verse_method(VMethod *vm) {
+ if(!vm) return;
+
+ MEM_freeN(vm->param_type);
+}
+
+/*
+ * Free methods for VMethodGroup
+ */
+void free_verse_methodgroup(VMethodGroup *vmg)
+{
+ struct VMethod *vm, *tmpvm;
+
+ if(!vmg) return;
+
+ vm= vmg->methods.first;
+ while(vm) {
+ tmpvm=vm->next;
+ free_verse_method(vm);
+ vm= tmpvm;
+ }
+ BLI_freelistN(&(vmg->methods));
+}
+
+/* callback for method group creation */
+static void cb_o_method_group_create(
+ void *user_data,
+ VNodeID node_id,
+ uint16 group_id,
+ const char *name)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+
+ if(!session) return;
+
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ vmg = lookup_vmethodgroup(&(vnode->methodgroups), group_id);
+
+ /* create method group holder in node node_id */
+ if(!vmg) {
+ vmg= MEM_mallocN(sizeof(VMethodGroup), "VMethodGroup");
+ vmg->group_id = group_id;
+ vmg->methods.first = vmg->methods.last = NULL;
+ BLI_addtail(&(vnode->methodgroups), vmg);
+ printf("new method group with name %s (group_id %d) for node %u created\n", name, group_id, node_id);
+ }
+
+ /* this ensures name of an existing group gets updated, in case it is changed */
+ BLI_strncpy(vmg->name, (char *)name, 16);
+
+ /* subscribe to method group */
+ verse_send_o_method_group_subscribe(node_id, group_id);
+
+#ifdef VERSECHAT
+ /* if this is our own method group, register our methods */
+ if(node_id==session->avatar) {
+ verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[0].name,
+ vmethod_info[0].param_count,
+ (VNOParamType *)vmethod_info[0].param_type,
+ (const char **)vmethod_info[0].param_name);
+ b_verse_update();
+ verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[1].name,
+ vmethod_info[1].param_count,
+ (VNOParamType *)vmethod_info[1].param_type,
+ (const char **)vmethod_info[1].param_name);
+ b_verse_update();
+ verse_send_o_method_create(node_id, group_id, (uint8)~0u, vmethod_info[2].name,
+ vmethod_info[2].param_count,
+ (VNOParamType *)vmethod_info[2].param_type,
+ (const char **)vmethod_info[2].param_name);
+ b_verse_update();
+ }
+#endif
+}
+
+/* callback for method group destruction */
+static void cb_o_method_group_destroy(
+ void *user_data,
+ VNodeID node_id,
+ uint16 group_id,
+ const char *name)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+
+ printf("method group %d destroyed\n", group_id);
+
+ if(!session) return;
+
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+ for(vmg= vnode->methodgroups.first; vmg; vmg= vmg->next)
+ if(vmg->group_id==group_id) break;
+
+ if(!vmg) return; /* method group doesn't exist? */
+
+ vmg->group_id = 0;
+ vmg->name[0] = '\0';
+ vm= vmg->methods.first;
+ while(vm) {
+ /* free vm */
+
+ }
+
+ /* TODO: unsubscribe from method group */
+ BLI_remlink(&(vnode->methodgroups),vmg);
+ MEM_freeN(vmg);
+}
+
+/* callback for method creation */
+static void cb_o_method_create(
+ void *user_data,
+ VNodeID node_id,
+ uint16 group_id,
+ uint16 method_id,
+ const char *name,
+ uint8 param_count,
+ const VNOParamType *param_type,
+ const char *param_name[])
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ unsigned int size;
+ unsigned int i;
+ char *put;
+
+ if(!session) return;
+
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ vmg= lookup_vmethodgroup((&vnode->methodgroups), group_id);
+
+ if(!vmg) return;
+
+ vm= lookup_vmethod((&vmg->methods), method_id);
+
+ if(!vm) {
+ vm= MEM_mallocN(sizeof(VMethod), "VMethod");
+ vm->id= method_id;
+ vm->param_count= param_count;
+ size= param_count* (sizeof(*vm->param_type) + sizeof(*vm->param_name));
+ for(i= 0; i <param_count; i++) {
+ size+=strlen(param_name[i])+1;
+ }
+ vm->param_type= MEM_mallocN(size, "param_type and param_name");
+ memcpy(vm->param_type, param_type, sizeof(VNOParamType)*param_count);
+ vm->param_name= (char **)(vm->param_type + param_count);
+ put= (char *)(vm->param_name + param_count);
+ for(i= 0; i < param_count; i++) {
+ vm->param_name[i]= put;
+ strcpy(put, param_name[i]);
+ put += strlen(param_name[i]) + 1;
+ }
+
+ BLI_addtail(&(vmg->methods), vm);
+#ifdef VERSECHAT
+ if(strcmp(vmethod_info[0].name, name)==0) {
+ vmethod_info[0].id = method_id;
+ }
+#endif
+ printf("method %s in group %d of node %u created\n", name, group_id, node_id);
+ }
+
+ BLI_strncpy(vm->name, (char *)name, 500);
+}
+
+/* callback for method destruction */
+static void cb_o_method_destroy(
+ void *user_data,
+ VNodeID node_id,
+ uint16 group_id,
+ uint16 method_id,
+ const char *name,
+ uint8 param_count,
+ const VNOParamType *param_type,
+ const char *param_name[])
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+
+ if(!session) return;
+
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+ for(vmg= vnode->methodgroups.first; vmg; vmg= vmg->next)
+ if(vmg->group_id==group_id) break;
+
+ if(!vmg) return; /* method group doesn't exist? */
+
+ for(vm= vmg->methods.first; vm; vm= vm->next)
+ if(vm->id==method_id) break;
+
+ if(!vm) return;
+
+ BLI_remlink(&(vmg->methods), vm);
+ MEM_freeN(vm->param_type);
+ MEM_freeN(vm);
+}
+
+/* callback for method calls */
+static void cb_o_method_call(void *user_data, VNodeID node_id, uint8 group_id, uint8 method_id, VNodeID sender, VNOPackedParams *params)
+{
+ struct VerseSession *session = (VerseSession*)current_verse_session();
+ struct VNode *vnode;
+ struct VMethodGroup *vmg;
+ struct VMethod *vm;
+ Text *text;
+ int method_idx= -1;
+
+ VNOParam arg[3];
+
+ if(!session) return;
+
+ if(session->avatar!=node_id) return;
+
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+ vmg= lookup_vmethodgroup(&(vnode->methodgroups), group_id);
+ if(!vmg) return;
+
+ vm= lookup_vmethod(&(vmg->methods), method_id);
+ if(!vm) return;
+#ifdef VERSECHAT
+ if(strcmp(vm->name, "join")==0) method_idx=0;
+ if(strcmp(vm->name, "leave")==0) method_idx=1;
+ if(strcmp(vm->name, "hear")==0) method_idx=2;
+ if(method_idx>-1)
+ verse_method_call_unpack(params, vmethod_info[method_idx].param_count, vmethod_info[method_idx].param_type, arg);
+
+ switch(method_idx) {
+ case 0:
+ printf("Joining channel %s\n",arg[0].vstring);
+ text=add_empty_text();
+ text->flags |= TXT_ISCHAT;
+ rename_id(&(text->id), arg[0].vstring);
+ break;
+ case 1:
+ printf("Leaving channel %s\n",arg[0].vstring);
+ break;
+ case 2:
+ {
+ ListBase lb = G.main->text;
+ ID *id= (ID *)lb.first;
+ char showstr[1024];
+ showstr[0]='\0';
+ text = NULL;
+ sprintf(showstr, "%s: %s\n", arg[1].vstring, arg[2].vstring);
+ for(; id; id= id->next) {
+ if(strcmp(id->name+2, arg[0].vstring)==0 && strcmp(arg[0].vstring, "#server")!=0) {
+ text = (Text *)id;
+ break;
+ }
+ }
+ if(text) {
+ txt_insert_buf(text, showstr);
+ txt_move_eof(text, 0);
+ allqueue(REDRAWCHAT, 0);
+ } else {
+ printf("%s> %s: %s\n",arg[0].vstring, arg[1].vstring, arg[2].vstring);
+ }
+ }
+ break;
+ }
+#endif
+}
+
+void set_method_callbacks(void)
+{
+ /* create and destroy method groups */
+ verse_callback_set(verse_send_o_method_group_create, cb_o_method_group_create, NULL);
+ verse_callback_set(verse_send_o_method_group_destroy, cb_o_method_group_destroy, NULL);
+
+ /* create and destroy methods */
+ verse_callback_set(verse_send_o_method_create, cb_o_method_create, NULL);
+ verse_callback_set(verse_send_o_method_destroy, cb_o_method_destroy, NULL);
+
+ /* call methods */
+ verse_callback_set(verse_send_o_method_call, cb_o_method_call, NULL);
+}
+
+#endif
diff --git a/source/blender/blenkernel/intern/verse_node.c b/source/blender/blenkernel/intern/verse_node.c
index 774917a5581..fd5a25598d3 100644
--- a/source/blender/blenkernel/intern/verse_node.c
+++ b/source/blender/blenkernel/intern/verse_node.c
@@ -306,6 +306,17 @@ void free_verse_node(VNode *vnode)
}
/*
+ * Find a Verse Node from session
+ */
+VNode* lookup_vnode(VerseSession *session, VNodeID node_id)
+{
+ struct VNode *vnode;
+ vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
+
+ return vnode;
+}
+
+/*
* create new Verse Node
*/
VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNodeID owner_id)
@@ -322,12 +333,16 @@ VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNo
BLI_dlist_init(&(vnode->taggroups));
vnode->queue.first = vnode->queue.last = NULL;
+ vnode->methodgroups.first = vnode->methodgroups.last = NULL;
vnode->data = NULL;
vnode->counter = 0;
vnode->flag = 0;
+#ifdef VERSECHAT
+ vnode->chat_flag = CHAT_NOTLOGGED;
+#endif
vnode->post_node_create = post_node_create;
vnode->post_node_destroy = post_node_destroy;
diff --git a/source/blender/blenkernel/intern/verse_object_node.c b/source/blender/blenkernel/intern/verse_object_node.c
index ce66109723e..d8be38cd00f 100644
--- a/source/blender/blenkernel/intern/verse_object_node.c
+++ b/source/blender/blenkernel/intern/verse_object_node.c
@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
+#include "DNA_userdef_types.h"
#include "BLI_dynamiclist.h"
#include "BLI_blenlib.h"
@@ -260,6 +261,7 @@ void free_object_data(VNode *vnode)
struct VerseSession *session = vnode->session;
struct VObjectData *obj = (VObjectData*)vnode->data;
struct VLink *vlink;
+ struct VMethodGroup *vmg;
if(!obj) return;
@@ -279,6 +281,12 @@ void free_object_data(VNode *vnode)
/* free dynamic list and sendig queue of links */
BLI_dlist_destroy(&(obj->links));
BLI_freelistN(&(obj->queue));
+
+ /* free method groups and their methods */
+ for(vmg = vnode->methodgroups.first; vmg; vmg= vmg->next) {
+ free_verse_methodgroup(vmg);
+ }
+ BLI_freelistN(&(vnode->methodgroups));
/* free constraint between VerseNode and Object */
obj->post_object_free_constraint(vnode);
diff --git a/source/blender/blenkernel/intern/verse_session.c b/source/blender/blenkernel/intern/verse_session.c
index 288bfd01a9d..1226fffd929 100644
--- a/source/blender/blenkernel/intern/verse_session.c
+++ b/source/blender/blenkernel/intern/verse_session.c
@@ -185,6 +185,10 @@ static void cb_connect_accept(
for(i = 0; i < V_NT_NUM_TYPES; i++)
mask = mask | (1 << i);
verse_send_node_index_subscribe(mask);
+ verse_send_node_subscribe(session->avatar); /* subscribe to avatar node, as well */
+
+ /* create our own method group and method */
+ /*verse_send_o_method_group_create(session->avatar, ~0, "tawk-client");*/
}
/*
@@ -218,6 +222,9 @@ static void set_all_callbacks(void)
/* set up all callbacks for bitmap nodes */
set_bitmap_callbacks();
+
+ /* set up all callbacks for method groups and methods */
+ set_method_callbacks();
}
/*
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 612c095aac7..8d3234475a4 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -75,6 +75,8 @@ void free_world(World *wrld)
if(mtex && mtex->tex) mtex->tex->id.us--;
if(mtex) MEM_freeN(mtex);
}
+ BKE_previewimg_free(&wrld->preview);
+
wrld->ipo= 0;
BKE_icon_delete((struct ID*)wrld);
wrld->id.icon_id = 0;
@@ -96,13 +98,16 @@ World *add_world(char *name)
wrld->exp= 0.0f;
wrld->exposure=wrld->range= 1.0f;
- wrld->aodist= 10.0;
+ wrld->aodist= 5.0f;
wrld->aosamp= 5;
- wrld->aoenergy= 1.0;
- wrld->aobias= 0.05;
+ wrld->aoenergy= 1.0f;
+ wrld->aobias= 0.05f;
+ wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY;
+ wrld->ao_approx_error= 0.25f;
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
-
+ wrld->preview = NULL;
+
return wrld;
}
@@ -121,6 +126,8 @@ World *copy_world(World *wrld)
}
}
+ if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview);
+
BPY_copy_scriptlink(&wrld->scriptlink);
id_us_plus((ID *)wrldn->ipo);
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index 39f9af4c3d3..bd6859973b1 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -138,7 +138,8 @@ void start_avi(RenderData *rd, int rectx, int recty)
int x, y;
char name[256];
AviFormat format;
- int quality, framerate;
+ int quality;
+ double framerate;
makeavistring(rd, name);
@@ -147,7 +148,7 @@ void start_avi(RenderData *rd, int rectx, int recty)
y = recty;
quality= rd->quality;
- framerate= rd->frs_sec;
+ framerate= (double) rd->frs_sec / (double) rd->frs_sec_base;
avi = MEM_mallocN (sizeof(AviMovie), "avimovie");
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 703f2803ede..e4b9940d135 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -32,6 +32,7 @@
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
#include <ffmpeg/rational.h>
+#include <ffmpeg/swscale.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
@@ -40,6 +41,12 @@
#define FFMPEG_CODEC_TIME_BASE 1
#endif
+#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
+#define OUTFILE_PB (outfile->pb)
+#else
+#define OUTFILE_PB (&outfile->pb)
+#endif
+
#if defined(WIN32) && (!(defined snprintf))
#define snprintf _snprintf
#endif
@@ -81,6 +88,7 @@ static AVFormatContext* outfile = 0;
static AVStream* video_stream = 0;
static AVStream* audio_stream = 0;
static AVFrame* current_frame = 0;
+static struct SwsContext *img_convert_ctx = 0;
static uint8_t* video_buffer = 0;
static int video_buffersize = 0;
@@ -317,8 +325,9 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
}
if (c->pix_fmt != PIX_FMT_RGBA32) {
- img_convert((AVPicture*)current_frame, c->pix_fmt,
- (AVPicture*)rgb_frame, PIX_FMT_RGBA32, width, height);
+ sws_scale(img_convert_ctx, rgb_frame->data,
+ rgb_frame->linesize, 0, c->height,
+ current_frame->data, current_frame->linesize);
delete_picture(rgb_frame);
}
return current_frame;
@@ -352,18 +361,26 @@ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of,
if (ffmpeg_type == FFMPEG_DV && G.scene->r.frs_sec != 25) {
c->time_base.den = 2997;
c->time_base.num = 100;
- } else {
+ } else if ((double) ((int) G.scene->r.frs_sec_base) ==
+ G.scene->r.frs_sec_base) {
c->time_base.den = G.scene->r.frs_sec;
- c->time_base.num = 1;
+ c->time_base.num = (int) G.scene->r.frs_sec_base;
+ } else {
+ c->time_base.den = G.scene->r.frs_sec * 100000;
+ c->time_base.num = ((double) G.scene->r.frs_sec_base) * 100000;
}
#else
/* FIXME: Really bad hack (tm) for NTSC support */
if (ffmpeg_type == FFMPEG_DV && G.scene->r.frs_sec != 25) {
c->frame_rate = 2997;
c->frame_rate_base = 100;
- } else {
+ } else if ((double) ((int) G.scene->r.frs_sec_base) ==
+ G.scene->r.frs_sec_base) {
c->frame_rate = G.scene->r.frs_sec;
- c->frame_rate_base = 1;
+ c->frame_rate_base = G.scene->r.frs_sec_base;
+ } else {
+ c->frame_rate = G.scene->r.frs_sec * 100000;
+ c->frame_rate_base = ((double) G.scene->r.frs_sec_base)*100000;
}
#endif
@@ -420,6 +437,13 @@ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of,
"FFMPEG video buffer");
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
+
+ img_convert_ctx = sws_getContext(c->width, c->height,
+ PIX_FMT_RGBA32,
+ c->width, c->height,
+ c->pix_fmt,
+ SWS_BICUBIC,
+ NULL, NULL, NULL);
return st;
}
@@ -733,7 +757,7 @@ void append_ffmpeg(int frame, int *pixels, int rectx, int recty)
write_video_frame(generate_video_frame((unsigned char*) pixels));
if (ffmpeg_autosplit) {
- if (url_ftell(&outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
+ if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) {
end_ffmpeg();
ffmpeg_autosplit_count++;
start_ffmpeg_impl(ffmpeg_renderdata,
@@ -749,8 +773,10 @@ void end_ffmpeg(void)
fprintf(stderr, "Closing ffmpeg...\n");
- write_audio_frames();
-
+ if (audio_stream) {
+ write_audio_frames();
+ }
+
if (outfile) {
av_write_trailer(outfile);
}
@@ -778,7 +804,7 @@ void end_ffmpeg(void)
}
if (outfile && outfile->oformat) {
if (!(outfile->oformat->flags & AVFMT_NOFILE)) {
- url_fclose(&outfile->pb);
+ url_fclose(OUTFILE_PB);
}
}
if (outfile) {
@@ -797,6 +823,11 @@ void end_ffmpeg(void)
MEM_freeN(audio_input_buffer);
audio_input_buffer = 0;
}
+
+ if (img_convert_ctx) {
+ sws_freeContext(img_convert_ctx);
+ img_convert_ctx = 0;
+ }
}
#endif
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index cebeff5c3e1..99e30bc91c0 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -54,6 +54,13 @@ extern "C" {
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifdef WIN32
+ #ifndef FREE_WINDOWS
+ #define isnan(n) _isnan(n)
+ #define finite _finite
+ #endif
+#endif
+
#define MAT4_UNITY {{ 1.0, 0.0, 0.0, 0.0},\
{ 0.0, 1.0, 0.0, 0.0},\
{ 0.0, 0.0, 1.0, 0.0},\
@@ -64,577 +71,216 @@ extern "C" {
{ 0.0, 0.0, 1.0}}
-/* matrix operations */
-/* void Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]); */
-/* void Mat3MulVecfl(float mat[][3], float *vec); */
-/* or **mat, but it's the same */
-/*void Mat3MulVecd(float mat[][3], double *vec); */
-
-/* void Mat4MulVecfl(float mat[][4], float *vec); */
-/* void Mat4MulSerie(float answ[][4], float m1[][4], float m2[][4], */
-/* float m3[][4], float m4[][4], float m5[][4], */
-/* float m6[][4], float m7[][4], float m8[][4]); */
-/* int Mat4Invert(float inverse[][4], float mat[][4]); */
-
-/* m2 to m1 */
-/* void Mat3CpyMat4(float m1p[][3], float m2p[][4]); */
-/* void Mat3CpyMat4(float *m1p, float *m2p); */
-
-/* m1 to m2 */
-/* void Mat3CpyMat3(float m1p[][3], float m2p[][3]); */
-/* void Mat3CpyMat3(float *m1p, float *m2p); */
-
-/* m2 to m1 */
-/* void Mat4CpyMat3(float m1p[][4], float m2p[][3]); */
+void CalcCent3f(float *cent, float *v1, float *v2, float *v3);
+void CalcCent4f(float *cent, float *v1, float *v2, float *v3, float *v4);
-/* M1 = M3*M2 */
-/* void Mat3MulMat3(float m1[][3], float m2[][3], float m3[][3]); */
-/*void Mat3MulMat3(float *m1, float *m3, float *m2); */
+void Crossf(float *c, float *a, float *b);
+void Projf(float *c, float *v1, float *v2);
-/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
-/*void Mat3IsMat3MulMat4(float m1[][3], float m2[][3], float m3[][4]); */
+float Inpf(float *v1, float *v2);
+float Inp2f(float *v1, float *v2);
-/* m1 to m2 */
-/* void Mat4CpyMat4(float m1[][4], float m2[][4]); */
-/* void Mat4CpyMat4(float *m1, float *m2); */
+float Normalize(float *n);
+float Normalize2(float *n);
+float Sqrt3f(float f);
+double Sqrt3d(double d);
-/* void Mat4Ortho(float mat[][4]); */
-/* void Mat4Mul3Vecfl(float mat[][4], float *vec); */
-/* void Mat4MulVec4fl(float mat[][4], float *vec); */
-/* void Mat4SwapMat4(float *m1, float *m2); */
+float saacos(float fac);
+float saasin(float fac);
+float sasqrt(float fac);
-/* void Mat3Inv(float m1[][3], float m2[][3]); */
-/* void Mat4One(float m[][4]); */
-/* void Mat3One(float m[][3]); */
+int FloatCompare(float *v1, float *v2, float limit);
+float FloatLerpf(float target, float origin, float fac);
+float CalcNormFloat(float *v1, float *v2, float *v3, float *n);
+float CalcNormFloat4(float *v1, float *v2, float *v3, float *v4, float *n);
- void
-CalcCent3f(
- float *cent, float *v1, float *v2, float *v3
-);
-
- void
-CalcCent4f(
- float *cent, float *v1,
- float *v2, float *v3,
- float *v4
-);
+void CalcNormLong(int *v1, int *v2, int *v3, float *n);
+/* CalcNormShort: is ook uitprodukt - (translates as 'is also out/cross product') */
+void CalcNormShort(short *v1, short *v2, short *v3, float *n);
- void
-Crossf(
- float *c, float *a, float *b
-);
-
- void
-Projf(
- float *c, float *v1, float *v2
-);
/**
- * Euler conversion routines
+ * @section Euler conversion routines
*/
- void
-EulToMat3(
- float *eul,
- float mat[][3]
-);
- void
-EulToMat4(
- float* eul,
- float mat[][4]
-);
+void EulToMat3(float *eul, float mat[][3]);
+void EulToMat4(float *eul, float mat[][4]);
- void
-Mat3ToEul(
- float tmat[][3],
- float *eul
-);
+void Mat3ToEul(float tmat[][3], float *eul);
+void Mat4ToEul(float tmat[][4],float *eul);
- void
-Mat4ToEul(
- float tmat[][4],
- float *eul
-);
+void EulToQuat(float *eul, float *quat);
void compatible_eul(float *eul, float *oldrot);
void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
+
/**
* @section Quaternion arithmetic routines
*/
- void
-QuatToEul(
- float *quat,
- float *eul
-);
- void
-QuatOne(
- float *
-);
- void
-QuatMul(
- float *,
- float *,
- float *
-);
- void
-QuatMulVecf(
- float *q,
- float *v
-);
- void
-NormalQuat(
- float *
-);
- void
-VecRotToQuat(
- float *vec,
- float phi,
- float *quat
-);
- void
-QuatSub(
- float *q,
- float *q1,
- float *q2
-);
- void
-QuatConj(
- float *q
-);
- void
-QuatInv(
- float *q
-);
- void
-QuatMulf(
- float *q,
- float f
-);
- float
-QuatDot(
- float *q1,
- float *q2
-);
- void
-printquat(
- char *str,
- float q[4]
-);
+void QuatToEul(float *quat, float *eul);
+void QuatOne(float *);
+void QuatMul(float *, float *, float *);
+void QuatMulVecf(float *q, float *v);
+void QuatMulf(float *q, float f);
+void QuatMulFac(float *q, float fac);
+void NormalQuat(float *);
+void VecRotToQuat(float *vec, float phi, float *quat);
+
+void QuatSub(float *q, float *q1, float *q2);
+void QuatConj(float *q);
+void QuatInv(float *q);
+float QuatDot(float *q1, float *q2);
+void QuatCopy(float *q1, float *q2);
+
+void printquat(char *str, float q[4]);
void QuatInterpol(float *result, float *quat1, float *quat2, float t);
void QuatAdd(float *result, float *quat1, float *quat2, float t);
/**
- * @section matrix multiplication can copying routines
+ * @section matrix multiplication and copying routines
*/
- void
-Mat3MulFloat(
- float *m,
- float f
-);
- void
-Mat4MulFloat(
- float *m,
- float f
-);
- void
-Mat4MulFloat3(
- float *m,
- float f
-);
- void
-Mat3Transp(
- float mat[][3]
-);
- void
-Mat4Transp(
- float mat[][4]
-);
- int
-Mat4Invert(
- float inverse[][4],
- float mat[][4]
-);
- void
-Mat4InvertSimp(
- float inverse[][4],
- float mat[][4]
-);
- void
-Mat4Inv(
- float *m1,
- float *m2
-);
- void
-Mat4InvGG(
- float out[][4],
- float in[][4]
-);
- void
-Mat3CpyMat4(
- float m1[][3],
- float m2[][4]
-);
+void Mat3MulFloat(float *m, float f);
+void Mat4MulFloat(float *m, float f);
+void Mat4MulFloat3(float *m, float f);
- void
-Mat3Inv(
- float m1[][3],
- float m2[][3]
-);
+void Mat3Transp(float mat[][3]);
+void Mat4Transp(float mat[][4]);
- void
-Mat4CpyMat3(
- float m1[][4],
- float m2[][3]
-);
+int Mat4Invert(float inverse[][4], float mat[][4]);
+void Mat4InvertSimp(float inverse[][4], float mat[][4]);
+void Mat4Inv(float *m1, float *m2);
+void Mat4InvGG(float out[][4], float in[][4]);
+void Mat3Inv(float m1[][3], float m2[][3]);
- float
-Det2x2(
- float a,float b,float c,float d
-);
+void Mat3CpyMat4(float m1[][3],float m2[][4]);
+void Mat4CpyMat3(float m1[][4], float m2[][3]);
- float
-Det3x3(
+void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight);
+
+float Det2x2(float a,float b,float c, float d);
+
+float Det3x3(
float a1, float a2, float a3,
float b1, float b2, float b3,
float c1, float c2, float c3
);
- float
-Det4x4(
- float m[][4]
-);
+float Det4x4(float m[][4]);
- void
-Mat4Adj(
- float out[][4],
- float in[][4]
-);
- void
-Mat3Adj(
- float m1[][3],
- float m[][3]
-);
- void
-Mat4MulMat4(
- float m1[][4],
- float m2[][4],
- float m3[][4]
-);
- void
-subMat4MulMat4(
- float *m1,
- float *m2,
- float *m3
-);
+void Mat3Adj(float m1[][3], float m[][3]);
+void Mat4Adj(float out[][4], float in[][4]);
+
+void Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]);
+void subMat4MulMat4(float *m1, float *m2, float *m3);
#ifndef TEST_ACTIVE
- void
-Mat3MulMat3(
- float m1[][3],
- float m3[][3],
- float m2[][3]
-);
+void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]);
#else
- void
-Mat3MulMat3(
- float *m1,
- float *m3,
- float *m2
-);
+void Mat3MulMat3(float *m1, float *m3, float *m2);
#endif
- void
-Mat4MulMat34(
- float (*m1)[4],
- float (*m3)[3],
- float (*m2)[4]
-);
- void
-Mat4CpyMat4(
- float m1[][4],
- float m2[][4]
-);
- void
-Mat4SwapMat4(
- float *m1,
- float *m2
-);
- void
-Mat3CpyMat3(
- float m1[][3],
- float m2[][3]
-);
- void
-Mat3MulSerie(
- float answ[][3],
+void Mat4MulMat34(float (*m1)[4], float (*m3)[3], float (*m2)[4]);
+void Mat4CpyMat4(float m1[][4], float m2[][4]);
+void Mat4SwapMat4(float *m1, float *m2);
+void Mat3CpyMat3(float m1[][3], float m2[][3]);
+
+void Mat3MulSerie(float answ[][3],
float m1[][3], float m2[][3], float m3[][3],
float m4[][3], float m5[][3], float m6[][3],
float m7[][3], float m8[][3]
);
- void
-Mat4MulSerie(
- float answ[][4],
- float m1[][4],
+
+void Mat4MulSerie(float answ[][4], float m1[][4],
float m2[][4], float m3[][4], float m4[][4],
float m5[][4], float m6[][4], float m7[][4],
float m8[][4]
);
- void
-Mat4Clr(
- float *m
-);
- void
-Mat3Clr(
- float *m
-);
- void
-Mat3One(
- float m[][3]
-);
- void
-Mat4MulVec3Project(
- float mat[][4],
- float *vec
-);
- void
-Mat4MulVec(
- float mat[][4],
- int *vec
-);
- void
-VecMat4MulVecfl(
- float *in,
- float mat[][4],
- float *vec
-);
- void
-Mat4MulMat43(
- float (*m1)[4],
- float (*m3)[4],
- float (*m2)[3]
-);
-
- void
-Mat3IsMat3MulMat4(
- float m1[][3],
- float m2[][3],
- float m3[][4]
-);
- void
-Mat4One(
- float m[][4]
-);
- void
-Mat4Mul3Vecfl(
- float mat[][4],
- float *vec
-);
- void
-Mat4MulVec4fl(
- float mat[][4],
- float *vec
-);
- void
-Mat3MulVec(
- float mat[][3],
- int *vec
-);
- void
-Mat4MulVecfl(
- float mat[][4],
- float *vec
-);
- void
-Mat4ToQuat(
- float m[][4],
- float *q
-);
- void
-VecUpMat3old(
- float *vec,
- float mat[][3],
- short axis
-);
- int
-FloatCompare(
- float *v1,
- float *v2,
- float limit
-);
- float
-FloatLerpf(
- float target,
- float origin,
- float fac
-);
- float
-Normalize(
- float *n
-);
- float
-CalcNormFloat(
- float *v1,
- float *v2,
- float *v3,
- float *n
-);
-
- float
-CalcNormFloat4(
- float *v1,
- float *v2,
- float *v3,
- float *v4,
- float *n
-);
- float
-VecLenf(
- float *v1,
- float *v2
-);
- float
-VecLength(
- float *v
-);
- void
-VecMulf(
- float *v1,
- float f
-);
- int
-VecLenCompare(
- float *v1,
- float *v2,
- float limit
-);
- int
-VecCompare(
- float *v1,
- float *v2,
- float limit
-);
- int
-VecEqual(
- float *v1,
- float *v2
-);
- float
-Sqrt3f(
- float f
-);
- double
-Sqrt3d(
- double d
-);
+
+void Mat4Clr(float *m);
+void Mat3Clr(float *m);
+
+void Mat3One(float m[][3]);
+void Mat4One(float m[][4]);
+
+void Mat3Ortho(float mat[][3]);
+void Mat4Ortho(float mat[][4]);
+
+void VecMat4MulVecfl(float *in, float mat[][4], float *vec);
+void Mat4MulMat43(float (*m1)[4], float (*m3)[4], float (*m2)[3]);
+void Mat3IsMat3MulMat4(float m1[][3], float m2[][3], float m3[][4]);
+
+void Mat4MulVec(float mat[][4],int *vec);
+void Mat4MulVecfl(float mat[][4], float *vec);
+void Mat4Mul3Vecfl(float mat[][4], float *vec);
+void Mat4MulVec3Project(float mat[][4],float *vec);
+void Mat4MulVec4fl(float mat[][4], float *vec);
+void Mat3MulVec(float mat[][3],int *vec);
+void Mat3MulVecfl(float mat[][3], float *vec);
+void Mat3MulVecd(float mat[][3], double *vec);
+void Mat3TransMulVecfl(float mat[][3], float *vec);
+
+void Mat3AddMat3(float m1[][3], float m2[][3], float m3[][3]);
+void Mat4AddMat4(float m1[][4], float m2[][4], float m3[][4]);
+
+void VecUpMat3old(float *vec, float mat[][3], short axis);
+void VecUpMat3(float *vec, float mat[][3], short axis);
+void VecRotToMat3(float *vec, float phi, float mat[][3]);
+void VecRotToMat4(float *vec, float phi, float mat[][4]);
+
+void VecCopyf(float *v1, float *v2);
+int VecLen(int *v1, int *v2);
+float VecLenf(float *v1, float *v2);
+float VecLength(float *v);
+void VecMulf(float *v1, float f);
+
+int VecLenCompare(float *v1, float *v2, float limit);
+int VecCompare(float *v1, float *v2, float limit);
+int VecEqual(float *v1, float *v2);
+
+void printvecf(char *str,float v[3]);
+void printvec4f(char *str, float v[4]);
+
+void VecAddf(float *v, float *v1, float *v2);
+void VecSubf(float *v, float *v1, float *v2);
+void VecLerpf(float *target, float *a, float *b, float t);
+void VecMidf(float *v, float *v1, float *v2);
+
+void VecOrthoBasisf(float *v, float *v1, float *v2);
+
+float Vec2Lenf(float *v1, float *v2);
+float Vec2Length(float *v);
+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 vectoquat(float *vec, short axis, short upflag, float *q);
+
+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 NormalizedVecAngle2_2D(float *v1, float *v2);
+
+void euler_rot(float *beul, float ang, char axis);
+
- void
-euler_rot(
- float *beul,
- float ang,
- char axis
-);
- float
-saacos(
- float fac
-);
- float
-saasin(
- float fac
-);
- float
-sasqrt(
- float fac
-);
- void
-printvecf(
- char *str,
- float v[3]
-);
- void
-printvec4f(
- char *str,
- float v[4]
-);
- float
-Inpf(
- float *v1,
- float *v2
-);
- void
-VecSubf(
- float *v,
- float *v1,
- float *v2
-);
- void
-VecAddf(
- float *v,
- float *v1,
- float *v2
-);
- void
-VecLerpf(
- float *target,
- float *a,
- float *b,
- float t
-);
- void
-VecUpMat3(
- float *vec,
- float mat[][3],
- short axis
-);
- float
-DistVL2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-PdistVL2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaF2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaQ3Dfl(
- float *v1,
- float *v2,
- float *v3,
- float *v4
-);
- float
-AreaT3Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaPoly3Dfl(
- int nr,
- float *verts,
- float *normal
-);
- void
-VecRotToMat3(
- float *vec,
- float phi,
- float mat[][3]
-);
+float DistVL2Dfl(float *v1, float *v2, float *v3);
+float PdistVL2Dfl(float *v1, float *v2, float *v3);
+float PdistVL3Dfl(float *v1, float *v2, float *v3);
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3);
+float AreaF2Dfl(float *v1, float *v2, float *v3);
+float AreaQ3Dfl(float *v1, float *v2, float *v3, float *v4);
+float AreaT3Dfl(float *v1, float *v2, float *v3);
+float AreaPoly3Dfl(int nr, float *verts, float *normal);
/* intersect Line-Line
return:
@@ -646,313 +292,113 @@ VecRotToMat3(
extern short IsectLL2Df(float *v1, float *v2, float *v3, float *v4);
extern short IsectLL2Ds(short *v1, short *v2, short *v3, short *v4);
-/* interpolation weights of point in a triangle or quad, v4 may be NULL */
- void
-InterpWeightsQ3Dfl(
- float *v1, float *v2, float *v3, float *v4,
- float *co,
- float *w
-);
-
- float *
-vectoquat(
- float *vec,
- short axis,
- short upflag
-);
+/*point in tri, 0 no intersection, 1 intersect */
+int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2]);
+/* point in quad, 0 no intersection, 1 intersect */
+int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2]);
- float
-VecAngle3(
- float *v1,
- float *v2,
- float *v3
-);
-
- float
-VecAngle2(
- float *v1,
- float *v2
-);
- float
-NormalizedVecAngle2(
- float *v1,
- float *v2
-);
+/* interpolation weights of point in a triangle or quad, v4 may be NULL */
+void InterpWeightsQ3Dfl(float *v1, float *v2, float *v3, float *v4, float *co, float *w);
+/* interpolation weights of point in a polygon with >= 3 vertices */
+void MeanValueWeights(float v[][3], int n, float *co, float *w);
- void
-i_lookat(
+void i_lookat(
float vx, float vy,
float vz, float px,
float py, float pz,
float twist, float mat[][4]
);
- void
-i_window(
+
+void i_window(
float left, float right,
float bottom, float top,
float nearClip, float farClip,
float mat[][4]
);
- void
-hsv_to_rgb(
- float h, float s,
- float v, float *r,
- float *g, float *b
-);
+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);
+void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
+void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
+void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
+void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
+unsigned int hsv_to_cpack(float h, float s, float v);
+unsigned int rgb_to_cpack(float r, float g, float b);
+void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
+void MinMaxRGB(short c[]);
- 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
-);
- void
-yuv_to_rgb(
- float y, float u, float v,
- float *lr, float *lg, float *lb
-);
+void VecStar(float mat[][3],float *vec);
- void
-ycc_to_rgb(
- float y, float cb, float cr,
- float *lr, float *lg, float *lb
-);
+short EenheidsMat(float mat[][3]);
- void
-rgb_to_ycc(
- float r, float g, float b,
- float *ly, float *lcb, float *lcr
-);
- void
-rgb_to_hsv(
- float r, float g, float b,
- float *lh, float *ls, float *lv
-);
- unsigned int
-hsv_to_cpack(
- float h, float s, float v
-);
- unsigned int
-rgb_to_cpack(
- float r, float g, float b
-);
- void
-cpack_to_rgb(
- unsigned int col,
- float *r, float *g, float *b
-);
+void QuatToMat3(float *q, float m[][3]);
+void QuatToMat4(float *q, float m[][4]);
- void
-EulToQuat(
- float *eul,
- float *quat
-);
+void Mat3ToQuat_is_ok(float wmat[][3], float *q);
- void
-Mat3MulVecfl(
- float mat[][3],
- float *vec
-);
- void
-Mat3MulVecd(
- float mat[][3],
- double *vec
-);
- void
-Mat3TransMulVecfl(
- float mat[][3],
- float *vec
-);
- void
-VecStar(
- float mat[][3],
- float *vec
-);
- short
-EenheidsMat(
- float mat[][3]
-);
- void
-printmatrix3(
- char *str, float m[][3]
-);
- void
-QuatToMat3(
- float *q,
- float m[][3]
-);
- void
-QuatToMat4(
- float *q,
- float m[][4]
-);
- void
-Mat3ToQuat_is_ok(
- float wmat[][3],
- float *q
-);
- void
-i_ortho(
- float left, float right,
- float bottom, float top,
- float nearClip, float farClip,
- float matrix[][4]
-);
- void
-i_polarview(
- float dist, float azimuth, float incidence, float twist,
- float Vm[][4]
-);
- void
-Mat3Ortho(
- float mat[][3]
-);
- void
-Mat4Ortho(
- float mat[][4]
-);
- void
-VecCopyf(
- float *v1,
- float *v2
-);
- int
-VecLen(
- int *v1,
- int *v2
-);
- void
-CalcNormShort(
- short *v1,
- short *v2,
- short *v3,
- float *n
-) /* is ook uitprodukt */;
-
- void
-CalcNormLong(
- int* v1,
- int*v2,
- int*v3,
- float *n
-);
- void
-MinMax3(
- float *min,
- float *max,
- float *vec
-);
+void i_ortho(float left, float right, float bottom, float top, float nearClip, float farClip, float matrix[][4]);
+void i_polarview(float dist, float azimuth, float incidence, float twist, float Vm[][4]);
+void i_translate(float Tx, float Ty, float Tz, float mat[][4]);
+void i_multmatrix(float icand[][4], float Vm[][4]);
+void i_rotate(float angle, char axis, float mat[][4]);
+
+
+
+
+
+void MinMax3(float *min, float *max, float *vec);
+void SizeToMat3(float *size, float mat[][3]);
+void SizeToMat4(float *size, float mat[][4]);
+
+float Mat3ToScalef(float mat[][3]);
+float Mat4ToScalef(float mat[][4]);
+
+void printmatrix3(char *str, float m[][3]);
+void printmatrix4(char *str, float m[][4]);
- void
-SizeToMat3(
- float *size,
- float mat[][3]
-);
- void
-printmatrix4(
- char *str,
- float m[][4]
-);
/* uit Sig.Proc.85 pag 253 */
- void
-Mat3ToQuat(
- float wmat[][3],
- float *q
-);
- void
-i_translate(
- float Tx,
- float Ty,
- float Tz,
- float mat[][4]
-);
- void
-i_multmatrix(
- float icand[][4],
- float Vm[][4]
-);
- void
-i_rotate(
- float angle,
- char axis,
- float mat[][4]
-);
- void
-VecMidf(
- float *v, float *v1, float *v2
-);
- void
-Mat3ToSize(
- float mat[][3], float *size
-);
- void
-Mat4ToSize(
- float mat[][4], float *size
-);
- void
-triatoquat(
- float *v1,
- float *v2,
- float *v3, float *quat
-);
- void
-MinMaxRGB(
- short c[]
-);
- float
-Vec2Lenf(
- float *v1,
- float *v2
-);
- 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
-);
- float
-Inp2f(
- float *v1,
- float *v2
-);
- float
-Normalize2(
- float *n
-);
+void Mat3ToQuat(float wmat[][3], float *q);
+void Mat4ToQuat(float m[][4], float *q);
+
+void Mat3ToSize(float mat[][3], float *size);
+void Mat4ToSize(float mat[][4], float *size);
+
+void triatoquat(float *v1, float *v2, float *v3, float *quat);
void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]);
void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3]);
void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
-
-int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda);
+
+int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
+int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
+int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda);
+int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]);
+void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v);
+void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
+void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
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]);
+
+typedef struct DualQuat {
+ float quat[4];
+ float trans[4];
+
+ float scale[4][4];
+ float scale_weight;
+} DualQuat;
+
+void Mat4ToDQuat(float basemat[][4], float mat[][4], DualQuat *dq);
+void DQuatToMat4(DualQuat *dq, float mat[][4]);
+void DQuatAddWeighted(DualQuat *dqsum, DualQuat *dq, float weight);
+void DQuatNormalize(DualQuat *dq, float totweight);
+void DQuatMulVecfl(DualQuat *dq, float *co, float mat[][3]);
+void DQuatCpyDQuat(DualQuat *dq1, DualQuat *dq2);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h
index 75a0e7b49a1..7d401cf2fc3 100644
--- a/source/blender/blenlib/BLI_blenlib.h
+++ b/source/blender/blenlib/BLI_blenlib.h
@@ -70,7 +70,6 @@
#include "DNA_listBase.h"
#include <stdlib.h>
-
extern ListBase fillfacebase;
extern ListBase fillvertbase;
/**
@@ -79,6 +78,8 @@ extern ListBase fillvertbase;
extern ListBase filledgebase;
extern int totblock;
+extern char btempdir[]; /* creator.c temp dir used instead of U.tempdir, set with BLI_where_is_temp( btempdir, 1 ); */
+
struct chardesc;
struct direntry;
struct rctf;
@@ -97,20 +98,24 @@ char *BLI_gethome(void);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
void BLI_make_exist(char *dir);
void BLI_make_existing_file(char *name);
-void BLI_split_dirfile(const char *string, char *dir, char *file);
+void BLI_split_dirfile(char *string, char *dir, char *file);
void BLI_join_dirfile(char *string, const char *dir, const char *file);
int BLI_testextensie(const char *str, const char *ext);
void addlisttolist(ListBase *list1, ListBase *list2);
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
-void * BLI_findlink(struct ListBase *listbase, int number);
+void *BLI_findlink(struct ListBase *listbase, int number);
+int BLI_findindex(struct ListBase *listbase, void *vlink);
void BLI_freelistN(struct ListBase *listbase);
void BLI_addtail(struct ListBase *listbase, void *vlink);
void BLI_remlink(struct ListBase *listbase, void *vlink);
+void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], short name_offs, short len);
void BLI_newname(char * name, int add);
-int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen);
-void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen, int pic);
+int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen);
+void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic);
void BLI_addhead(struct ListBase *listbase, void *vlink);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink);
+void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink);
+void BLI_sortlist(struct ListBase *listbase, int (*cmp)(void *, void *));
void BLI_freelist(struct ListBase *listbase);
int BLI_countlist(struct ListBase *listbase);
void BLI_freelinkN(ListBase *listbase, void *vlink);
@@ -132,7 +137,8 @@ void BLI_dlist_reinit(struct DynamicList *dlist);
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
-void BLI_cleanup_dir(const char *relabase, char *dir);
+void BLI_cleanup_file(const char *relabase, char *dir);
+void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */
/**
* Blender's path code replacement function.
@@ -173,7 +179,7 @@ void BLI_clean(char *path);
* @param str The string to be duplicated
* @retval Returns the duplicated string
*/
-char* BLI_strdup(char *str);
+char *BLI_strdup(const char *str);
/**
* Duplicates the first @a len bytes of cstring @a str
@@ -184,7 +190,7 @@ char* BLI_strdup(char *str);
* @param len The number of bytes to duplicate
* @retval Returns the duplicated string
*/
-char* BLI_strdupn(char *str, int len);
+char *BLI_strdupn(const char *str, int len);
/**
* Like strncpy but ensures dst is always
@@ -196,7 +202,7 @@ char* BLI_strdupn(char *str, int len);
* the size of dst)
* @retval Returns dst
*/
-char* BLI_strncpy(char *dst, const char *src, int maxncpy);
+char *BLI_strncpy(char *dst, const char *src, int maxncpy);
/*
* Replacement for snprintf
@@ -217,6 +223,11 @@ int BLI_streq(char *a, char *b);
*/
int BLI_strcaseeq(char *a, char *b);
+/* in util.c */
+#ifdef WITH_ICONV
+void BLI_string_to_utf8(char *original, char *utf_8, char *code);
+#endif
+
/**
* Read a file as ASCII lines. An empty list is
* returned if the file cannot be opened or read.
@@ -245,10 +256,21 @@ void BLI_free_file_lines(struct LinkNode *lines);
* @param fullname The full path and full name of the executable
* @param name The name of the executable (usually argv[0]) to be checked
*/
-void BLI_where_am_i(char *fullname, char *name);
+void BLI_where_am_i(char *fullname, const char *name);
char *get_install_dir(void);
/**
+ * Gets the temp directory when blender first runs.
+ * If the default path is not found, use try $TEMP
+ *
+ * Also make sure the temp dir has a trailing slash
+ *
+ * @param fullname The full path to the temp directory
+ */
+void BLI_where_is_temp(char *fullname, int usertemp);
+
+
+ /**
* determines the full path to the application bundle on OS X
*
* @return path to application bundle
@@ -258,15 +280,16 @@ char* BLI_getbundle(void);
#endif
#ifdef WIN32
-int BLI_getInstallationDir( char * str );
+int BLI_getInstallationDir(char *str);
#endif
/* BLI_storage.h */
int BLI_filesize(int file);
+int BLI_filepathsize(const char *path);
double BLI_diskfree(char *dir);
-char * BLI_getwdN(char * dir);
+char *BLI_getwdN(char *dir);
void BLI_hide_dot_files(int set);
-unsigned int BLI_getdir(char *dirname, struct direntry **filelist);
+unsigned int BLI_getdir(char *dirname, struct direntry **filelist);
/**
* @attention Do not confuse with BLI_exists
@@ -288,8 +311,10 @@ int BLI_rename(char *from, char *to);
int BLI_gzip(char *from, char *to);
int BLI_delete(char *file, int dir, int recursive);
int BLI_move(char *file, char *to);
-int BLI_touch(char *file);
-char *BLI_last_slash(char *string);
+int BLI_touch(const char *file);
+char *BLI_last_slash(const char *string);
+void BLI_add_slash(char *string);
+void BLI_del_slash(char *string);
/* BLI_rct.c */
/**
@@ -299,12 +324,12 @@ char *BLI_last_slash(char *string);
*
* @return True if @a rect is empty.
*/
-int BLI_rcti_is_empty(struct rcti * rect);
+int BLI_rcti_is_empty(struct rcti *rect);
void BLI_init_rctf(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_init_rcti(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
void BLI_translate_rctf(struct rctf *rect, float x, float y);
void BLI_translate_rcti(struct rcti *rect, int x, int y);
-int BLI_in_rcti(struct rcti * rect, int x, int y);
+int BLI_in_rcti(struct rcti *rect, int x, int y);
int BLI_in_rctf(struct rctf *rect, float x, float y);
int BLI_isect_rctf(struct rctf *src1, struct rctf *src2, struct rctf *dest);
int BLI_isect_rcti(struct rcti *src1, struct rcti *src2, struct rcti *dest);
@@ -361,7 +386,7 @@ void BLI_setInterruptCallBack(int (*f)(void));
char *BLI_strcasestr(const char *s, const char *find);
int BLI_strcasecmp(const char *s1, const char *s2);
int BLI_strncasecmp(const char *s1, const char *s2, int n);
-void BLI_timestr(double time, char *str);
+void BLI_timestr(double _time, char *str); /* time var is global */
/**
* Trick to address 32 GB with an int (only for malloced pointers)
diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack2d.h
index b5cf9cd81e9..50b864df5f8 100644
--- a/source/blender/blenlib/BLI_boxpack2d.h
+++ b/source/blender/blenlib/BLI_boxpack2d.h
@@ -28,10 +28,7 @@
* Contributor(s): Campbell Barton
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
- *
- * The old math stuff from Ton. These will slowly phase out in favour
- * of MTC calls. (or even MoTO :) )
- * */
+ */
/* Box Packer */
diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h
new file mode 100644
index 00000000000..e932c39eb06
--- /dev/null
+++ b/source/blender/blenlib/BLI_bpath.h
@@ -0,0 +1,60 @@
+/**
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Campbell Barton
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/* Based on ghash, difference is ghash is not a fixed size,
+ * so for BPath we dont need to malloc */
+
+struct BPathIterator {
+ char* path;
+ char* lib;
+ char* name;
+ void* data;
+ int len;
+ int type;
+};
+
+void BLI_bpathIterator_init (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getPath (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getLib (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getName (struct BPathIterator *bpi);
+int BLI_bpathIterator_getType (struct BPathIterator *bpi);
+int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi);
+void BLI_bpathIterator_step (struct BPathIterator *bpi);
+int BLI_bpathIterator_isDone (struct BPathIterator *bpi);
+void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded);
+
+/* high level funcs */
+
+/* creates a text file with missing files if there are any */
+void checkMissingFiles(char *txtname );
+void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked);
+void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked);
+void findMissingFiles(char *str);
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h
index a763ad53f1f..f9b73d521c9 100644
--- a/source/blender/blenlib/BLI_editVert.h
+++ b/source/blender/blenlib/BLI_editVert.h
@@ -55,9 +55,9 @@ typedef struct EditVert
struct EditVert *v;
struct EditEdge *e;
struct EditFace *f;
- float *fp;
void *p;
long l;
+ float fp;
} tmp;
float no[3]; /*vertex normal */
float co[3]; /*vertex location */
@@ -67,6 +67,7 @@ typedef struct EditVert
h for hidden. if (!eve->h) {...
f1 and f2 can be used for temp data, clear them first*/
unsigned char f, h, f1, f2;
+ float bweight;
short fast; /* only 0 or 1, for editmesh_fastmalloc, do not store temp data here! */
int hash;
int keyindex; /* original index #, for restoring key information */
@@ -103,9 +104,11 @@ typedef struct EditEdge
short f1, f2; /* short, f1 is (ab)used in subdiv */
unsigned char f, h, dir, seam, sharp;
float crease;
+ float bweight;
short fast; /* only 0 or 1, for editmesh_fastmalloc */
short fgoni; /* index for fgon, for search */
HashEdge hash;
+ void *data; /*custom edge data*/
} EditEdge;
/* note; changing this also might affect the undo copy in editmesh.c */
@@ -163,6 +166,13 @@ typedef struct EditMesh
/* DerivedMesh caches... note that derived cage can be equivalent
* to derived final, care should be taken on release.
*/
+
+ /* used for keeping track of the last clicked on face - so the space image
+ * when using the last selected face - (EditSelection) the space image flickered too much
+ *
+ * never access this directly, use EM_set_actFace and EM_get_actFace */
+ EditFace *act_face;
+
struct DerivedMesh *derivedCage, *derivedFinal;
/* the custom data layer mask that was last used to calculate
* derivedCage and derivedFinal
@@ -171,7 +181,7 @@ typedef struct EditMesh
struct RetopoPaintData *retopo_paint_data;
- CustomData vdata, fdata;
+ CustomData vdata, edata, fdata;
#ifdef WITH_VERSE
void *vnode;
diff --git a/source/blender/blenlib/BLI_fnmatch.h b/source/blender/blenlib/BLI_fnmatch.h
new file mode 100644
index 00000000000..af1dcf523bf
--- /dev/null
+++ b/source/blender/blenlib/BLI_fnmatch.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You 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. */
+
+#ifndef _FNMATCH_H
+
+#define _FNMATCH_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define __P(protos) protos
+#else /* Not C++ or ANSI C. */
+#undef __P
+#define __P(protos) ()
+/* We can get away without defining `const' here only because in this file
+ it is used only inside the prototype for `fnmatch', which is elided in
+ non-ANSI C where `const' is problematical. */
+#endif /* C++ or ANSI C. */
+
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
+#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+ int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
new file mode 100644
index 00000000000..d32e85c150c
--- /dev/null
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -0,0 +1,63 @@
+/**
+ * A kd-tree for nearest neighbour search.
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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: none of this file.
+ *
+ * Contributor(s): Janne Karhu
+ * Brecht Van Lommel
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BLI_KDTREE_H
+#define BLI_KDTREE_H
+
+struct KDTree;
+typedef struct KDTree KDTree;
+
+typedef struct KDTreeNearest {
+ int index;
+ float dist;
+ float co[3];
+} KDTreeNearest;
+
+/* Creates or free a kdtree */
+KDTree* BLI_kdtree_new(int maxsize);
+void BLI_kdtree_free(KDTree *tree);
+
+/* Construction: first insert points, then call balance. Normal is optional. */
+void BLI_kdtree_insert(KDTree *tree, int index, float *co, float *nor);
+void BLI_kdtree_balance(KDTree *tree);
+
+/* Find nearest returns index, and -1 if no node is found.
+ * Find n nearest returns number of points found, with results in nearest.
+ * Normal is optional. */
+int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest);
+int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest);
+
+#endif
+
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index da2ecb79651..638f36b7414 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -52,6 +52,9 @@ double rng_getDouble (struct RNG* rng);
float rng_getFloat (struct RNG* rng);
void rng_shuffleArray(struct RNG *rng, void *data, int elemSize, int numElems);
+ /** Note that skipping is as slow as generating n numbers! */
+void rng_skip (struct RNG *rng, int n);
+
/** Seed the random number generator */
void BLI_srand (unsigned int seed);
diff --git a/source/blender/blenlib/BLI_storage_types.h b/source/blender/blenlib/BLI_storage_types.h
index 825a8bc9cbd..ebce33852a1 100644
--- a/source/blender/blenlib/BLI_storage_types.h
+++ b/source/blender/blenlib/BLI_storage_types.h
@@ -52,6 +52,8 @@ struct header{
typedef unsigned int mode_t;
#endif
+struct ImBuf;
+
struct direntry{
char *string;
mode_t type;
@@ -68,6 +70,7 @@ struct direntry{
char extra[16];
void *poin;
int nr;
+ struct ImBuf *image;
};
struct dirlink
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 60ecce3f9d8..39162b8bd91 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -50,5 +50,6 @@ void BLI_end_threads (struct ListBase *threadbase);
void BLI_lock_thread (int type);
void BLI_unlock_thread (int type);
+int BLI_system_thread_count( void ); /* gets the number of threads the system can make use of */
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 4812cad033d..ac2f3235646 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -36,6 +36,13 @@ SET(INC
${ZLIB_INC}
)
+IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+SET(INC
+ ${INC}
+ ${BINRELOC_INC}
+)
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+
IF(WITH_VERSE)
ADD_DEFINITIONS(-DWITH_VERSE)
SET(INC ${INC} ${VERSE_INC})
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index e11934d968e..649d3cb5659 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -19,6 +19,7 @@ if env['WITH_BF_VERSE']:
if env['OURPLATFORM'] == 'linux2':
cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 5846bbda40e..6af377edfba 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -117,14 +117,16 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val) {
}
}
-void* BLI_ghash_lookup(GHash *gh, void *key) {
- unsigned int hash= gh->hashfp(key)%gh->nbuckets;
- Entry *e;
-
- for (e= gh->buckets[hash]; e; e= e->next)
- if (gh->cmpfp(key, e->key)==0)
- return e->val;
-
+void* BLI_ghash_lookup(GHash *gh, void *key)
+{
+ if(gh) {
+ unsigned int hash= gh->hashfp(key)%gh->nbuckets;
+ Entry *e;
+
+ for (e= gh->buckets[hash]; e; e= e->next)
+ if (gh->cmpfp(key, e->key)==0)
+ return e->val;
+ }
return NULL;
}
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
new file mode 100644
index 00000000000..80e92cb8809
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -0,0 +1,341 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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: none of this file.
+ *
+ * Contributor(s): Janne Karhu
+ * Brecht Van Lommel
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_kdtree.h"
+
+#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+
+typedef struct KDTreeNode {
+ struct KDTreeNode *left, *right;
+ float co[3], nor[3];
+ int index;
+ short d;
+} KDTreeNode;
+
+struct KDTree {
+ KDTreeNode *nodes;
+ int totnode;
+ KDTreeNode *root;
+};
+
+KDTree *BLI_kdtree_new(int maxsize)
+{
+ KDTree *tree;
+
+ tree= MEM_callocN(sizeof(KDTree), "KDTree");
+ tree->nodes= MEM_callocN(sizeof(KDTreeNode)*maxsize, "KDTreeNode");
+ tree->totnode= 0;
+
+ return tree;
+}
+
+void BLI_kdtree_free(KDTree *tree)
+{
+ if(tree) {
+ MEM_freeN(tree->nodes);
+ MEM_freeN(tree);
+ }
+}
+
+void BLI_kdtree_insert(KDTree *tree, int index, float *co, float *nor)
+{
+ KDTreeNode *node= &tree->nodes[tree->totnode++];
+
+ node->index= index;
+ VecCopyf(node->co, co);
+ if(nor) VecCopyf(node->nor, nor);
+}
+
+static KDTreeNode *kdtree_balance(KDTreeNode *nodes, int totnode, int axis)
+{
+ KDTreeNode *node;
+ float co;
+ int left, right, median, i, j;
+
+ if(totnode <= 0)
+ return NULL;
+ else if(totnode == 1)
+ return nodes;
+
+ /* quicksort style sorting around median */
+ left= 0;
+ right= totnode-1;
+ median= totnode/2;
+
+ while(right > left) {
+ co= nodes[right].co[axis];
+ i= left-1;
+ j= right;
+
+ while(1) {
+ while(nodes[++i].co[axis] < co);
+ while(nodes[--j].co[axis] > co && j>left);
+
+ if(i >= j) break;
+ SWAP(KDTreeNode, nodes[i], nodes[j]);
+ }
+
+ SWAP(KDTreeNode, nodes[i], nodes[right]);
+ if(i >= median)
+ right= i-1;
+ if(i <= median)
+ left= i+1;
+ }
+
+ /* set node and sort subnodes */
+ node= &nodes[median];
+ node->d= axis;
+ node->left= kdtree_balance(nodes, median, (axis+1)%3);
+ node->right= kdtree_balance(nodes+median+1, (totnode-(median+1)), (axis+1)%3);
+
+ return node;
+}
+
+void BLI_kdtree_balance(KDTree *tree)
+{
+ tree->root= kdtree_balance(tree->nodes, tree->totnode, 0);
+}
+
+static float squared_distance(float *v1, float *v2, float *n1, float *n2)
+{
+ float d[3], dist;
+
+ d[0]= v2[0]-v1[0];
+ d[1]= v2[1]-v1[1];
+ d[2]= v2[2]-v1[2];
+
+ dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
+
+ if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f)
+ dist *= 10.0f;
+
+ return dist;
+}
+
+int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest)
+{
+ KDTreeNode *root, *node, *min_node;
+ KDTreeNode **stack, *defaultstack[100];
+ float min_dist, cur_dist;
+ int totstack, cur=0;
+
+ if(!tree->root)
+ return -1;
+
+ stack= defaultstack;
+ totstack= 100;
+
+ root= tree->root;
+ min_node= root;
+ min_dist= squared_distance(root->co,co,root->nor,nor);
+
+ if(co[root->d] < root->co[root->d]) {
+ if(root->right)
+ stack[cur++]=root->right;
+ if(root->left)
+ stack[cur++]=root->left;
+ }
+ else {
+ if(root->left)
+ stack[cur++]=root->left;
+ if(root->right)
+ stack[cur++]=root->right;
+ }
+
+ while(cur--){
+ node=stack[cur];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if(cur_dist<0.0){
+ cur_dist= -cur_dist*cur_dist;
+
+ if(-cur_dist<min_dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(cur_dist<min_dist){
+ min_dist=cur_dist;
+ min_node=node;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ else{
+ cur_dist= cur_dist*cur_dist;
+
+ if(cur_dist<min_dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(cur_dist<min_dist){
+ min_dist=cur_dist;
+ min_node=node;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(cur+3 > totstack){
+ KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
+ memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+ stack=temp;
+ totstack+=100;
+ }
+ }
+
+ if(nearest) {
+ nearest->index= min_node->index;
+ nearest->dist= sqrt(min_dist);
+ VecCopyf(nearest->co, min_node->co);
+ }
+
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+
+ return min_node->index;
+}
+
+static void add_nearest(KDTreeNearest *ptn, int *found, int n, int index, float dist, float *co)
+{
+ int i;
+
+ if(*found<n) (*found)++;
+
+ for(i=*found-1; i>0; i--) {
+ if(dist >= ptn[i-1].dist)
+ break;
+ else
+ ptn[i]= ptn[i-1];
+ }
+
+ ptn[i].index= index;
+ ptn[i].dist= dist;
+ VecCopyf(ptn[i].co, co);
+}
+
+/* finds the nearest n entries in tree to specified coordinates */
+int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest)
+{
+ KDTreeNode *root, *node=0;
+ KDTreeNode **stack, *defaultstack[100];
+ float cur_dist;
+ int i, totstack, cur=0, found=0;
+
+ if(!tree->root)
+ return 0;
+
+ stack= defaultstack;
+ totstack= 100;
+
+ root= tree->root;
+
+ cur_dist= squared_distance(root->co,co,root->nor,nor);
+ add_nearest(nearest,&found,n,root->index,cur_dist,root->co);
+
+ if(co[root->d] < root->co[root->d]) {
+ if(root->right)
+ stack[cur++]=root->right;
+ if(root->left)
+ stack[cur++]=root->left;
+ }
+ else {
+ if(root->left)
+ stack[cur++]=root->left;
+ if(root->right)
+ stack[cur++]=root->right;
+ }
+
+ while(cur--){
+ node=stack[cur];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if(cur_dist<0.0){
+ cur_dist= -cur_dist*cur_dist;
+
+ if(found<n || -cur_dist<nearest[found-1].dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+
+ if(found<n || cur_dist<nearest[found-1].dist)
+ add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
+
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ else{
+ cur_dist= cur_dist*cur_dist;
+
+ if(found<n || cur_dist<nearest[found-1].dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(found<n || cur_dist<nearest[found-1].dist)
+ add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
+
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(cur+3 > totstack){
+ KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
+ memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+ stack=temp;
+ totstack+=100;
+ }
+ }
+
+ for(i=0; i<found; i++)
+ nearest[i].dist= sqrt(nearest[i].dist);
+
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+
+ return found;
+}
+
diff --git a/source/blender/blenlib/intern/BLI_storage.h b/source/blender/blenlib/intern/BLI_storage.h
index 5e9c377c410..9cbdfa327cd 100644
--- a/source/blender/blenlib/intern/BLI_storage.h
+++ b/source/blender/blenlib/intern/BLI_storage.h
@@ -31,6 +31,11 @@
#ifndef BLI_STORAGE_H
#define BLI_STORAGE_H
+#ifndef WIN32
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
+#endif
+
#include "BLI_storage_types.h"
void BLI_adddirstrings(void);
diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile
index 0c3f4a486be..9f40710209d 100644
--- a/source/blender/blenlib/intern/Makefile
+++ b/source/blender/blenlib/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
# CPPFLAGS += $(LEVEL_2_CPP_WARNINGS)
# path to SDNA types
@@ -63,3 +59,6 @@ endif
ifeq ($(WITH_FREETYPE2), true)
CPPFLAGS += -DWITH_FREETYPE2
endif
+ifeq ($(OS),linux)
+ CPPFLAGS += -I$(OCGDIR)/extern/binreloc/include
+endif \ No newline at end of file
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 182607740a5..cd7de83b9c0 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -760,7 +760,28 @@ void Mat4MulSerie(float answ[][4], float m1[][4],
}
}
+void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight)
+{
+ float squat[4], dquat[4], fquat[4];
+ float ssize[3], dsize[3], fsize[4];
+ float sloc[3], dloc[3], floc[3];
+
+ Mat4ToQuat(dst, dquat);
+ Mat4ToSize(dst, dsize);
+ VecCopyf(dloc, dst[3]);
+
+ Mat4ToQuat(src, squat);
+ Mat4ToSize(src, ssize);
+ VecCopyf(sloc, src[3]);
+
+ /* do blending */
+ VecLerpf(floc, dloc, sloc, srcweight);
+ QuatInterpol(fquat, dquat, squat, srcweight);
+ VecLerpf(fsize, dsize, ssize, srcweight);
+ /* compose new matrix */
+ LocQuatSizeToMat4(out, floc, fquat, fsize);
+}
void Mat4Clr(float *m)
{
@@ -915,7 +936,7 @@ void Mat4MulFloat(float *m, float f)
{
int i;
- for(i=0;i<12;i++) m[i]*=f; /* count to 12: without vector component */
+ for(i=0;i<16;i++) m[i]*=f; /* count to 12: without vector component */
}
@@ -931,6 +952,24 @@ void Mat4MulFloat3(float *m, float f) /* only scale component */
}
}
+void Mat3AddMat3(float m1[][3], float m2[][3], float m3[][3])
+{
+ int i, j;
+
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++)
+ m1[i][j]= m2[i][j] + m3[i][j];
+}
+
+void Mat4AddMat4(float m1[][4], float m2[][4], float m3[][4])
+{
+ int i, j;
+
+ for(i=0;i<4;i++)
+ for(j=0;j<4;j++)
+ m1[i][j]= m2[i][j] + m3[i][j];
+}
+
void VecStar(float mat[][3], float *vec)
{
@@ -1070,6 +1109,7 @@ void QuatInv(float *q)
QuatMulf(q, 1.0f/f);
}
+/* simple mult */
void QuatMulf(float *q, float f)
{
q[0] *= f;
@@ -1085,6 +1125,20 @@ void QuatSub(float *q, float *q1, float *q2)
q2[0]= -q2[0];
}
+/* angular mult factor */
+void QuatMulFac(float *q, float fac)
+{
+ float angle= fac*saacos(q[0]); /* quat[0]= cos(0.5*angle), but now the 0.5 and 2.0 rule out */
+
+ float co= (float)cos(angle);
+ float si= (float)sin(angle);
+ q[0]= co;
+ Normalize(q+1);
+ q[1]*= si;
+ q[2]*= si;
+ q[3]*= si;
+
+}
void QuatToMat3( float *q, float m[][3])
{
@@ -1157,7 +1211,7 @@ void QuatToMat4( float *q, float m[][4])
m[3][3]= 1.0f;
}
-void Mat3ToQuat( float wmat[][3], float *q) /* from Sig.Proc.85 pag 253 */
+void Mat3ToQuat(float wmat[][3], float *q)
{
double tr, s;
float mat[3][3];
@@ -1171,34 +1225,38 @@ void Mat3ToQuat( float wmat[][3], float *q) /* from Sig.Proc.85 pag 253 */
if(tr>FLT_EPSILON) {
s= sqrt( tr);
q[0]= (float)s;
- s*= 4.0;
- q[1]= (float)((mat[1][2]-mat[2][1])/s);
- q[2]= (float)((mat[2][0]-mat[0][2])/s);
- q[3]= (float)((mat[0][1]-mat[1][0])/s);
+ s= 1.0/(4.0*s);
+ q[1]= (float)((mat[1][2]-mat[2][1])*s);
+ q[2]= (float)((mat[2][0]-mat[0][2])*s);
+ q[3]= (float)((mat[0][1]-mat[1][0])*s);
}
else {
- q[0]= 0.0f;
- s= -0.5*(mat[1][1]+mat[2][2]);
-
- if(s>FLT_EPSILON) {
- s= sqrt(s);
- q[1]= (float)s;
- q[2]= (float)(mat[0][1]/(2*s));
- q[3]= (float)(mat[0][2]/(2*s));
+ if(mat[0][0] > mat[1][1] && mat[0][0] > mat[2][2]) {
+ s= 2.0*sqrtf(1.0 + mat[0][0] - mat[1][1] - mat[2][2]);
+ q[1]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[2][1] - mat[1][2])*s);
+ q[2]= (float)((mat[1][0] + mat[0][1])*s);
+ q[3]= (float)((mat[2][0] + mat[0][2])*s);
+ }
+ else if(mat[1][1] > mat[2][2]) {
+ s= 2.0*sqrtf(1.0 + mat[1][1] - mat[0][0] - mat[2][2]);
+ q[2]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[2][0] - mat[0][2])*s);
+ q[1]= (float)((mat[1][0] + mat[0][1])*s);
+ q[3]= (float)((mat[2][1] + mat[1][2])*s);
}
else {
- q[1]= 0.0f;
- s= 0.5*(1.0-mat[2][2]);
-
- if(s>FLT_EPSILON) {
- s= sqrt(s);
- q[2]= (float)s;
- q[3]= (float)(mat[1][2]/(2*s));
- }
- else {
- q[2]= 0.0f;
- q[3]= 1.0f;
- }
+ s= 2.0*sqrtf(1.0 + mat[2][2] - mat[0][0] - mat[1][1]);
+ q[3]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[1][0] - mat[0][1])*s);
+ q[1]= (float)((mat[2][0] + mat[0][2])*s);
+ q[2]= (float)((mat[2][1] + mat[1][2])*s);
}
}
NormalQuat(q);
@@ -1279,9 +1337,8 @@ void NormalQuat(float *q)
}
}
-float *vectoquat( float *vec, short axis, short upflag)
+void vectoquat(float *vec, short axis, short upflag, float *q)
{
- static float q1[4];
float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;
/* first rotate to axis */
@@ -1293,11 +1350,11 @@ float *vectoquat( float *vec, short axis, short upflag)
x2= -vec[0] ; y2= -vec[1] ; z2= -vec[2];
}
- q1[0]=1.0;
- q1[1]=q1[2]=q1[3]= 0.0;
+ q[0]=1.0;
+ q[1]=q[2]=q[3]= 0.0;
len1= (float)sqrt(x2*x2+y2*y2+z2*z2);
- if(len1 == 0.0) return(q1);
+ if(len1 == 0.0) return;
/* nasty! I need a good routine for this...
* problem is a rotation of an Y axis to the negative Y-axis for example.
@@ -1308,9 +1365,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= -z2;
nor[2]= y2;
- if( fabs(y2)+fabs(z2)<0.0001 ) {
+ if(fabs(y2)+fabs(z2)<0.0001)
nor[1]= 1.0;
- }
co= x2;
}
@@ -1319,9 +1375,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= 0.0;
nor[2]= -x2;
- if( fabs(x2)+fabs(z2)<0.0001 ) {
+ if(fabs(x2)+fabs(z2)<0.0001)
nor[2]= 1.0;
- }
co= y2;
}
@@ -1330,9 +1385,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= x2;
nor[2]= 0.0;
- if( fabs(x2)+fabs(y2)<0.0001 ) {
+ if(fabs(x2)+fabs(y2)<0.0001)
nor[0]= 1.0;
- }
co= z2;
}
@@ -1342,13 +1396,13 @@ float *vectoquat( float *vec, short axis, short upflag)
angle= 0.5f*saacos(co);
si= (float)sin(angle);
- q1[0]= (float)cos(angle);
- q1[1]= nor[0]*si;
- q1[2]= nor[1]*si;
- q1[3]= nor[2]*si;
+ q[0]= (float)cos(angle);
+ q[1]= nor[0]*si;
+ q[2]= nor[1]*si;
+ q[3]= nor[2]*si;
if(axis!=upflag) {
- QuatToMat3(q1, mat);
+ QuatToMat3(q, mat);
fp= mat[2];
if(axis==0) {
@@ -1371,10 +1425,8 @@ float *vectoquat( float *vec, short axis, short upflag)
q2[2]= y2*si;
q2[3]= z2*si;
- QuatMul(q1,q2,q1);
+ QuatMul(q,q2,q);
}
-
- return(q1);
}
void VecUpMat3old( float *vec, float mat[][3], short axis)
@@ -1558,6 +1610,225 @@ void QuatAdd(float *result, float *quat1, float *quat2, float t)
result[3]= quat1[3] + t*quat2[3];
}
+void QuatCopy(float *q1, float *q2)
+{
+ q1[0]= q2[0];
+ q1[1]= q2[1];
+ q1[2]= q2[2];
+ q1[3]= q2[3];
+}
+
+/* **************** DUAL QUATERNIONS ************** */
+
+/*
+ Conversion routines between (regular quaternion, translation) and
+ dual quaternion.
+
+ Version 1.0.0, February 7th, 2007
+
+ Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights
+ Reserved
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author(s) be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+ Changes for Blender:
+ - renaming, style changes and optimizations
+ - added support for scaling
+*/
+
+void Mat4ToDQuat(float basemat[][4], float mat[][4], DualQuat *dq)
+{
+ float *t, *q, dscale[3], scale[3], basequat[4];
+ float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
+ float R[4][4], S[4][4];
+
+ /* split scaling and rotation, there is probably a faster way to do
+ this, it's done like this now to correctly get negative scaling */
+ Mat4MulMat4(baseRS, basemat, mat);
+ Mat4ToSize(baseRS, scale);
+
+ VecCopyf(dscale, scale);
+ dscale[0] -= 1.0f; dscale[1] -= 1.0f; dscale[2] -= 1.0f;
+
+ if((Det4x4(mat) < 0.0f) || VecLength(dscale) > 1e-4) {
+ /* extract R and S */
+ Mat4ToQuat(baseRS, basequat);
+ QuatToMat4(basequat, baseR);
+ VecCopyf(baseR[3], baseRS[3]);
+
+ Mat4Invert(baseinv, basemat);
+ Mat4MulMat4(R, baseinv, baseR);
+
+ Mat4Invert(baseRinv, baseR);
+ Mat4MulMat4(S, baseRS, baseRinv);
+
+ /* set scaling part */
+ Mat4MulSerie(dq->scale, basemat, S, baseinv, 0, 0, 0, 0, 0);
+ dq->scale_weight= 1.0f;
+ }
+ else {
+ /* matrix does not contain scaling */
+ Mat4CpyMat4(R, mat);
+ dq->scale_weight= 0.0f;
+ }
+
+ /* non-dual part */
+ Mat4ToQuat(R, dq->quat);
+
+ /* dual part */
+ t= R[3];
+ q= dq->quat;
+ dq->trans[0]= -0.5f*( t[0]*q[1] + t[1]*q[2] + t[2]*q[3]);
+ dq->trans[1]= 0.5f*( t[0]*q[0] + t[1]*q[3] - t[2]*q[2]);
+ dq->trans[2]= 0.5f*(-t[0]*q[3] + t[1]*q[0] + t[2]*q[1]);
+ dq->trans[3]= 0.5f*( t[0]*q[2] - t[1]*q[1] + t[2]*q[0]);
+}
+
+void DQuatToMat4(DualQuat *dq, float mat[][4])
+{
+ float len, *t, q0[4];
+
+ /* regular quaternion */
+ QuatCopy(q0, dq->quat);
+
+ /* normalize */
+ len= sqrt(QuatDot(q0, q0));
+ if(len != 0.0f)
+ QuatMulf(q0, 1.0f/len);
+
+ /* rotation */
+ QuatToMat4(q0, mat);
+
+ /* translation */
+ t= dq->trans;
+ mat[3][0]= 2.0*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]);
+ mat[3][1]= 2.0*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]);
+ mat[3][2]= 2.0*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]);
+
+ /* note: this does not handle scaling */
+}
+
+void DQuatAddWeighted(DualQuat *dqsum, DualQuat *dq, float weight)
+{
+ /* make sure we interpolate quats in the right direction */
+ if (QuatDot(dq->quat, dqsum->quat) < 0)
+ weight = -weight;
+
+ /* interpolate rotation and translation */
+ dqsum->quat[0] += weight*dq->quat[0];
+ dqsum->quat[1] += weight*dq->quat[1];
+ dqsum->quat[2] += weight*dq->quat[2];
+ dqsum->quat[3] += weight*dq->quat[3];
+
+ dqsum->trans[0] += weight*dq->trans[0];
+ dqsum->trans[1] += weight*dq->trans[1];
+ dqsum->trans[2] += weight*dq->trans[2];
+ dqsum->trans[3] += weight*dq->trans[3];
+
+ /* interpolate scale - but only if needed */
+ if (dq->scale_weight) {
+ float wmat[4][4];
+
+ Mat4CpyMat4(wmat, dq->scale);
+ Mat4MulFloat((float*)wmat, weight);
+ Mat4AddMat4(dqsum->scale, dqsum->scale, wmat);
+ dqsum->scale_weight += weight;
+ }
+}
+
+void DQuatNormalize(DualQuat *dq, float totweight)
+{
+ float scale= 1.0f/totweight;
+
+ QuatMulf(dq->quat, scale);
+ QuatMulf(dq->trans, scale);
+
+ if(dq->scale_weight) {
+ float addweight= totweight - dq->scale_weight;
+
+ if(addweight) {
+ dq->scale[0][0] += addweight;
+ dq->scale[1][1] += addweight;
+ dq->scale[2][2] += addweight;
+ dq->scale[3][3] += addweight;
+ }
+
+ Mat4MulFloat((float*)dq->scale, scale);
+ dq->scale_weight= 1.0f;
+ }
+}
+
+void DQuatMulVecfl(DualQuat *dq, float *co, float mat[][3])
+{
+ float M[3][3], t[3], scalemat[3][3], len2;
+ float w= dq->quat[0], x= dq->quat[1], y= dq->quat[2], z= dq->quat[3];
+ float t0= dq->trans[0], t1= dq->trans[1], t2= dq->trans[2], t3= dq->trans[3];
+
+ /* rotation matrix */
+ M[0][0]= w*w + x*x - y*y - z*z;
+ M[1][0]= 2*(x*y - w*z);
+ M[2][0]= 2*(x*z + w*y);
+
+ M[0][1]= 2*(x*y + w*z);
+ M[1][1]= w*w + y*y - x*x - z*z;
+ M[2][1]= 2*(y*z - w*x);
+
+ M[0][2]= 2*(x*z - w*y);
+ M[1][2]= 2*(y*z + w*x);
+ M[2][2]= w*w + z*z - x*x - y*y;
+
+ len2= QuatDot(dq->quat, dq->quat);
+ if(len2 > 0.0f)
+ len2= 1.0f/len2;
+
+ /* translation */
+ t[0]= 2*(-t0*x + w*t1 - t2*z + y*t3);
+ t[1]= 2*(-t0*y + t1*z - x*t3 + w*t2);
+ t[2]= 2*(-t0*z + x*t2 + w*t3 - t1*y);
+
+ /* apply scaling */
+ if(dq->scale_weight)
+ Mat4MulVecfl(dq->scale, co);
+
+ /* apply rotation and translation */
+ Mat3MulVecfl(M, co);
+ co[0]= (co[0] + t[0])*len2;
+ co[1]= (co[1] + t[1])*len2;
+ co[2]= (co[2] + t[2])*len2;
+
+ /* compute crazyspace correction mat */
+ if(mat) {
+ if(dq->scale_weight) {
+ Mat3CpyMat4(scalemat, dq->scale);
+ Mat3MulMat3(mat, M, scalemat);
+ }
+ else
+ Mat3CpyMat3(mat, M);
+ Mat3MulFloat((float*)mat, len2);
+ }
+}
+
+void DQuatCpyDQuat(DualQuat *dq1, DualQuat *dq2)
+{
+ memcpy(dq1, dq2, sizeof(DualQuat));
+}
+
/* **************** VIEW / PROJECTION ******************************** */
@@ -1767,7 +2038,6 @@ void Mat4Ortho(float mat[][4])
void VecCopyf(float *v1, float *v2)
{
-
v1[0]= v2[0];
v1[1]= v2[1];
v1[2]= v2[2];
@@ -1836,6 +2106,30 @@ void VecMulf(float *v1, float f)
v1[2]*= f;
}
+void VecOrthoBasisf(float *v, float *v1, float *v2)
+{
+ if (v[0] == 0.0f && v[1] == 0.0f)
+ {
+ // degenerate case
+ v1[0] = 0.0f; v1[1] = 1.0f; v1[2] = 0.0f;
+ if (v[2] > 0.0f) {
+ v2[0] = 1.0f; v2[1] = v2[2] = 0.0f;
+ }
+ else {
+ v2[0] = -1.0f; v2[1] = v2[2] = 0.0f;
+ }
+ }
+ else
+ {
+ float f = 1.0f/sqrt(v[0]*v[0] + v[1]*v[1]);
+ v1[0] = v[1]*f;
+ v1[1] = -v[0]*f;
+ v1[2] = 0.0f;
+
+ Crossf(v2, v, v1);
+ }
+}
+
int VecLenCompare(float *v1, float *v2, float limit)
{
float x,y,z;
@@ -2125,6 +2419,98 @@ short IsectLL2Df(float *v1, float *v2, float *v3, float *v4)
return 0;
}
+/*
+-1: colliniar
+ 1: intersection
+
+*/
+short IsectLLPt2Df(float x0,float y0,float x1,float y1,
+ float x2,float y2,float x3,float y3, float *xi,float *yi)
+
+{
+ /*
+ this function computes the intersection of the sent lines
+ and returns the intersection point, note that the function assumes
+ the lines intersect. the function can handle vertical as well
+ as horizontal lines. note the function isn't very clever, it simply
+ applies the math, but we don't need speed since this is a
+ pre-processing step
+ */
+ float c1,c2, // constants of linear equations
+ det_inv, // the inverse of the determinant of the coefficient
+ m1,m2; // the slopes of each line
+ /*
+ compute slopes, note the cludge for infinity, however, this will
+ be close enough
+ */
+ if ( fabs( x1-x0 ) > 0.000001 )
+ m1 = ( y1-y0 ) / ( x1-x0 );
+ else
+ return -1; /*m1 = ( float ) 1e+10;*/ // close enough to infinity
+
+ if ( fabs( x3-x2 ) > 0.000001 )
+ m2 = ( y3-y2 ) / ( x3-x2 );
+ else
+ return -1; /*m2 = ( float ) 1e+10;*/ // close enough to infinity
+
+ if (fabs(m1-m2) < 0.000001)
+ return -1; /* paralelle lines */
+
+// compute constants
+
+ c1 = ( y0-m1*x0 );
+ c2 = ( y2-m2*x2 );
+
+// compute the inverse of the determinate
+
+ det_inv = 1.0f / ( -m1 + m2 );
+
+// use Kramers rule to compute xi and yi
+
+ *xi= ( ( -c2 + c1 ) *det_inv );
+ *yi= ( ( m2*c1 - m1*c2 ) *det_inv );
+
+ return 1;
+} // end Intersect_Lines
+
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+#define ISECT_EPSILON 1e-6
+
+/* point in tri */
+int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2])
+{
+ if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v3,v1,pt)>=-ISECT_EPSILON))
+ return 1;
+ else {
+ return 0;
+ }
+}
+/* point in quad - only convex quads */
+int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
+{
+ if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v3,v4,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v4,v1,pt)>=-ISECT_EPSILON))
+ return 1;
+ else
+ return 0;
+}
+
+
+
+ /* copied from Geometry.c - todo - move to arithb.c or some other generic place we can reuse */
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
+
+/**
+ *
+ * @param min
+ * @param max
+ * @param vec
+ */
void MinMax3(float *min, float *max, float *vec)
{
if(min[0]>vec[0]) min[0]= vec[0];
@@ -2225,7 +2611,53 @@ void InterpWeightsQ3Dfl(float *v1, float *v2, float *v3, float *v4, float *co, f
else
BarycentricWeights(v1, v2, v3, co, n, w);
}
-}
+}
+
+/* Mean value weights - smooth interpolation weights for polygons with
+ * more than 3 vertices */
+static float MeanValueHalfTan(float *v1, float *v2, float *v3)
+{
+ float d2[3], d3[3], cross[3], area, dot, len;
+
+ VecSubf(d2, v2, v1);
+ VecSubf(d3, v3, v1);
+ Crossf(cross, d2, d3);
+
+ area= VecLength(cross);
+ dot= Inpf(d2, d3);
+ len= VecLength(d2)*VecLength(d3);
+
+ if(area == 0.0f)
+ return 0.0f;
+ else
+ return (len - dot)/area;
+}
+
+void MeanValueWeights(float v[][3], int n, float *co, float *w)
+{
+ float totweight, t1, t2, len, *vmid, *vprev, *vnext;
+ int i;
+
+ totweight= 0.0f;
+
+ for(i=0; i<n; i++) {
+ vmid= v[i];
+ vprev= (i == 0)? v[n-1]: v[i-1];
+ vnext= (i == n-1)? v[0]: v[i+1];
+
+ t1= MeanValueHalfTan(co, vprev, vmid);
+ t2= MeanValueHalfTan(co, vmid, vnext);
+
+ len= VecLenf(co, vmid);
+ w[i]= (t1+t2)/len;
+ totweight += w[i];
+ }
+
+ if(totweight != 0.0f)
+ for(i=0; i<n; i++)
+ w[i] /= totweight;
+}
+
/* ************ EULER *************** */
@@ -2391,6 +2823,15 @@ void VecRotToMat3( float *vec, float phi, float mat[][3])
}
+void VecRotToMat4( float *vec, float phi, float mat[][4])
+{
+ float tmat[3][3];
+
+ VecRotToMat3(vec, phi, tmat);
+ Mat4One(mat);
+ Mat4CpyMat3(mat, tmat);
+}
+
void VecRotToQuat( float *vec, float phi, float *quat)
{
/* rotation of phi radials around vec */
@@ -2399,7 +2840,7 @@ void VecRotToQuat( float *vec, float phi, float *quat)
quat[1]= vec[0];
quat[2]= vec[1];
quat[3]= vec[2];
-
+
if( Normalize(quat+1) == 0.0) {
QuatOne(quat);
}
@@ -2427,6 +2868,22 @@ float VecAngle3(float *v1, float *v2, float *v3)
return NormalizedVecAngle2(vec1, vec2) * 180.0/M_PI;
}
+float VecAngle3_2D(float *v1, float *v2, float *v3)
+{
+ float vec1[2], vec2[2];
+
+ vec1[0] = v2[0]-v1[0];
+ vec1[1] = v2[1]-v1[1];
+
+ vec2[0] = v2[0]-v3[0];
+ vec2[1] = v2[1]-v3[1];
+
+ Normalize2(vec1);
+ Normalize2(vec2);
+
+ return NormalizedVecAngle2_2D(vec1, vec2) * 180.0/M_PI;
+}
+
/* Return the shortest angle in degrees between the 2 vectors */
float VecAngle2(float *v1, float *v2)
{
@@ -2456,6 +2913,21 @@ float NormalizedVecAngle2(float *v1, float *v2)
return 2.0f*saasin(VecLenf(v2, v1)/2.0);
}
+float NormalizedVecAngle2_2D(float *v1, float *v2)
+{
+ /* this is the same as acos(Inpf(v1, v2)), but more accurate */
+ if (Inp2f(v1, v2) < 0.0f) {
+ float vec[2];
+
+ vec[0]= -v2[0];
+ vec[1]= -v2[1];
+
+ return (float)M_PI - 2.0f*saasin(Vec2Lenf(vec, v1)/2.0f);
+ }
+ else
+ return 2.0f*saasin(Vec2Lenf(v2, v1)/2.0);
+}
+
void euler_rot(float *beul, float ang, char axis)
{
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
@@ -2577,32 +3049,48 @@ void SizeToMat3( float *size, float mat[][3])
mat[2][0]= 0.0;
}
-void Mat3ToSize( float mat[][3], float *size)
+void SizeToMat4( float *size, float mat[][4])
{
- 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);
+ float tmat[3][3];
+
+ SizeToMat3(size, tmat);
+ Mat4One(mat);
+ Mat4CpyMat3(mat, tmat);
+}
+void Mat3ToSize( float mat[][3], float *size)
+{
+ size[0]= VecLength(mat[0]);
+ size[1]= VecLength(mat[1]);
+ size[2]= VecLength(mat[2]);
}
void Mat4ToSize( float mat[][4], float *size)
{
- float vec[3];
-
+ size[0]= VecLength(mat[0]);
+ size[1]= VecLength(mat[1]);
+ size[2]= VecLength(mat[2]);
+}
+
+/* this gets the average scale of a matrix, only use when your scaling
+ * data that has no idea of scale axis, examples are bone-envelope-radius
+ * and curve radius */
+float Mat3ToScalef(float mat[][3])
+{
+ /* unit length vector */
+ float unit_vec[3] = {0.577350269189626, 0.577350269189626, 0.577350269189626};
+ Mat3MulVecfl(mat, unit_vec);
+ return VecLength(unit_vec);
+}
- VecCopyf(vec, mat[0]);
- size[0]= Normalize(vec);
- VecCopyf(vec, mat[1]);
- size[1]= Normalize(vec);
- VecCopyf(vec, mat[2]);
- size[2]= Normalize(vec);
+float Mat4ToScalef(float mat[][4])
+{
+ float tmat[3][3];
+ Mat3CpyMat4(tmat, mat);
+ return Mat3ToScalef(tmat);
}
+
/* ************* SPECIALS ******************* */
void triatoquat( float *v1, float *v2, float *v3, float *quat)
@@ -2668,6 +3156,11 @@ float Vec2Lenf(float *v1, float *v2)
return (float)sqrt(x*x+y*y);
}
+float Vec2Length(float *v)
+{
+ return (float)sqrt(v[0]*v[0] + v[1]*v[1]);
+}
+
void Vec2Mulf(float *v1, float f)
{
v1[0]*= f;
@@ -2947,6 +3440,8 @@ void tubemap(float x, float y, float z, float *u, float *v)
len= sqrt(x*x+y*y);
if(len>0) {
*u = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0;
+ } else {
+ *v = *u = 0.0f; /* to avoid un-initialized variables */
}
}
@@ -2964,6 +3459,8 @@ void spheremap(float x, float y, float z, float *u, float *v)
z/=len;
*v = 1.0- saacos(z)/M_PI;
+ } else {
+ *v = *u = 0.0f; /* to avoid un-initialized variables */
}
}
@@ -3134,7 +3631,7 @@ void mul_v3_v3m4(float *v1, float *v2, float mat[][4])
test if the line starting at p1 ending at p2 intersects the triangle v0..v2
return non zero if it does
*/
-int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
+int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv)
{
float p[3], s[3], d[3], e1[3], e2[3], q[3];
@@ -3160,15 +3657,318 @@ int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], f
v = f * Inpf(d, q);
if ((v < 0.0)||((u + v) > 1.0)) return 0;
+
+ if(uv) {
+ uv[0]= u;
+ uv[1]= v;
+ }
return 1;
}
+/* Adapted from the paper by Kasper Fauerby */
+/* "Improved Collision detection and Response" */
+int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
+{
+ float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
+ float a, b, c, d, e, x, y, z, t, t0, t1, radius2=radius*radius;
+ float elen2,edotv,edotbv,nordotv,vel2;
+ int embedded_in_plane=0, found_by_sweep=0;
-/*
-find closest point to p on line through l1,l2
-and return lambda, where (0 <= lambda <= 1) when cp is in the line segement l1,l2
-*/
+ VecSubf(e1,v1,v0);
+ VecSubf(e2,v2,v0);
+ VecSubf(vel,p2,p1);
+
+/*---test plane of tri---*/
+ Crossf(nor,e1,e2);
+ Normalize(nor);
+ /* flip normal */
+ if(Inpf(nor,vel)>0.0f) VecMulf(nor,-1.0f);
+
+ a=Inpf(p1,nor)-Inpf(v0,nor);
+
+ nordotv=Inpf(nor,vel);
+
+ if ((nordotv > -0.000001) && (nordotv < 0.000001)) {
+ if(fabs(a)>=1.0f)
+ return 0;
+ else{
+ embedded_in_plane=1;
+ t0=0.0f;
+ t1=1.0f;
+ }
+ }
+ else{
+ t0=(radius-a)/nordotv;
+ t1=(-radius-a)/nordotv;
+ /* make t0<t1 */
+ if(t0>t1){b=t1; t1=t0; t0=b;}
+
+ if(t0>1.0f || t1<0.0f) return 0;
+
+ /* clamp to [0,1] */
+ t0=(t0<0.0f)?0.0f:((t0>1.0f)?1.0:t0);
+ t1=(t1<0.0f)?0.0f:((t1>1.0f)?1.0:t1);
+ }
+
+/*---test inside of tri---*/
+ if(embedded_in_plane==0){
+ /* plane intersection point */
+ VecCopyf(point,vel);
+ VecMulf(point,t0);
+ VecAddf(point,point,p1);
+ VecCopyf(temp,nor);
+ VecMulf(temp,radius);
+ VecSubf(point,point,temp);
+
+ /* is the point in the tri? */
+ a=Inpf(e1,e1);
+ b=Inpf(e1,e2);
+ c=Inpf(e2,e2);
+
+ VecSubf(temp,point,v0);
+ d=Inpf(temp,e1);
+ e=Inpf(temp,e2);
+
+ x=d*c-e*b;
+ y=e*a-d*b;
+ z=x+y-(a*c-b*b);
+
+ if(( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
+ *lambda=t0;
+ VecCopyf(ipoint,point);
+ return 1;
+ }
+ }
+
+ *lambda=1.0f;
+/*---test points---*/
+ a=vel2=Inpf(vel,vel);
+
+ /*v0*/
+ VecSubf(temp,p1,v0);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+
+ /*v1*/
+ VecSubf(temp,p1,v1);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v1);
+ found_by_sweep=1;
+ }
+ }
+ /*v2*/
+ VecSubf(temp,p1,v2);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v2);
+ found_by_sweep=1;
+ }
+ }
+
+/*---test edges---*/
+ /*e1*/
+ VecSubf(bv,v0,p1);
+ elen2 = Inpf(e1,e1);
+ edotv = Inpf(e1,vel);
+ edotbv = Inpf(e1,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e1);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ /*e2*/
+ /*bv is same*/
+ elen2 = Inpf(e2,e2);
+ edotv = Inpf(e2,vel);
+ edotbv = Inpf(e2,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e2);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ /*e3*/
+ VecSubf(e3,v2,v1);
+ VecSubf(bv,v1,p1);
+ elen2 = Inpf(e3,e3);
+ edotv = Inpf(e3,vel);
+ edotbv = Inpf(e3,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e3);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v1);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ return found_by_sweep;
+}
+int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
+{
+ float p[3], e1[3], e2[3];
+ float u, v, f;
+ int a0=axis, a1=(axis+1)%3, a2=(axis+2)%3;
+
+ //return LineIntersectsTriangle(p1,p2,v0,v1,v2,lambda);
+
+ ///* first a simple bounding box test */
+ //if(MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
+ //if(MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
+ //if(MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
+ //if(MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
+
+ ///* then a full intersection test */
+
+ VecSubf(e1,v1,v0);
+ VecSubf(e2,v2,v0);
+ VecSubf(p,v0,p1);
+
+ f= (e2[a1]*e1[a2]-e2[a2]*e1[a1]);
+ if ((f > -0.000001) && (f < 0.000001)) return 0;
+
+ v= (p[a2]*e1[a1]-p[a1]*e1[a2])/f;
+ if ((v < 0.0)||(v > 1.0)) return 0;
+
+ f= e1[a1];
+ if((f > -0.000001) && (f < 0.000001)){
+ f= e1[a2];
+ if((f > -0.000001) && (f < 0.000001)) return 0;
+ u= (-p[a2]-v*e2[a2])/f;
+ }
+ else
+ u= (-p[a1]-v*e2[a1])/f;
+
+ if ((u < 0.0)||((u + v) > 1.0)) return 0;
+
+ *lambda = (p[a0]+u*e1[a0]+v*e2[a0])/(p2[a0]-p1[a0]);
+
+ if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
+
+ return 1;
+}
+
+int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
+{
+ return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
+ min2[0]<max1[0] && min2[1]<max1[1] && min2[2]<max1[2]);
+}
+
+/* find closest point to p on line through l1,l2 and return lambda,
+ * where (0 <= lambda <= 1) when cp is in the line segement l1,l2
+ */
float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3])
{
float h[3],u[3],lambda;
@@ -3180,6 +3980,7 @@ float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3])
cp[2] = l1[2] + u[2] * lambda;
return lambda;
}
+
/* little sister we only need to know lambda */
float lambda_cp_line(float p[3], float l1[3], float l2[3])
{
@@ -3189,7 +3990,156 @@ float lambda_cp_line(float p[3], float l1[3], float l2[3])
return(Inpf(u,h)/Inpf(u,u));
}
+/* 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)
+{
+ float x0,y0, x1,y1, wtot, v2d[2], w1, w2;
+
+ /* used for paralelle lines */
+ float pt3d[3], l1[3], l2[3], pt_on_line[3];
+
+ /* compute 2 edges of the quad intersection point */
+ if (IsectLLPt2Df(v0[0],v0[1],v1[0],v1[1], v2[0],v2[1],v3[0],v3[1], &x0,&y0) == 1) {
+ /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */
+ /* should never be paralle !! */
+ /*printf("\tnot paralelle 1\n");*/
+ IsectLLPt2Df(pt[0],pt[1],x0,y0, v0[0],v0[1],v3[0],v3[1], &x1,&y1);
+
+ /* Get the weights from the new intersection point, to each edge */
+ v2d[0] = x1-v0[0];
+ v2d[1] = y1-v0[1];
+ w1 = Vec2Length(v2d);
+
+ v2d[0] = x1-v3[0]; /* some but for the other vert */
+ v2d[1] = y1-v3[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ /*w1 = w1/wtot;*/
+ /*w2 = w2/wtot;*/
+ uv[0] = w1/wtot;
+ } else {
+ /* lines are paralelle, lambda_cp_line_ex is 3d grrr */
+ /*printf("\tparalelle1\n");*/
+ pt3d[0] = pt[0];
+ pt3d[1] = pt[1];
+ pt3d[2] = l1[2] = l2[2] = 0.0f;
+
+ l1[0] = v0[0]; l1[1] = v0[1];
+ l2[0] = v1[0]; l2[1] = v1[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w1 = Vec2Length(v2d);
+
+ l1[0] = v2[0]; l1[1] = v2[1];
+ l2[0] = v3[0]; l2[1] = v3[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[0] = w1/wtot;
+ }
+
+ /* Same as above to calc the uv[1] value, alternate calculation */
+
+ if (IsectLLPt2Df(v0[0],v0[1],v3[0],v3[1], v1[0],v1[1],v2[0],v2[1], &x0,&y0) == 1) { /* was v0,v1 v2,v3 now v0,v3 v1,v2*/
+ /* never paralle if above was not */
+ /*printf("\tnot paralelle2\n");*/
+ IsectLLPt2Df(pt[0],pt[1],x0,y0, v0[0],v0[1],v1[0],v1[1], &x1,&y1);/* was v0,v3 now v0,v1*/
+
+ v2d[0] = x1-v0[0];
+ v2d[1] = y1-v0[1];
+ w1 = Vec2Length(v2d);
+
+ v2d[0] = x1-v1[0];
+ v2d[1] = y1-v1[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[1] = w1/wtot;
+ } else {
+ /* lines are paralelle, lambda_cp_line_ex is 3d grrr */
+ /*printf("\tparalelle2\n");*/
+ pt3d[0] = pt[0];
+ pt3d[1] = pt[1];
+ pt3d[2] = l1[2] = l2[2] = 0.0f;
+
+
+ l1[0] = v0[0]; l1[1] = v0[1];
+ l2[0] = v3[0]; l2[1] = v3[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w1 = Vec2Length(v2d);
+
+ l1[0] = v1[0]; l1[1] = v1[1];
+ l2[0] = v2[0]; l2[1] = v2[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[1] = w1/wtot;
+ }
+ /* may need to flip UV's here */
+}
+
+/* same as above but does tri's and quads, tri's are a bit of a hack */
+void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
+{
+ if (isquad) {
+ PointInQuad2DUV(v0, v1, v2, v3, pt, uv);
+ }
+ else {
+ /* not for quads, use for our abuse of LineIntersectsTriangleUV */
+ float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda;
+
+ p1_3d[0] = p2_3d[0] = uv[0];
+ p1_3d[1] = p2_3d[1] = uv[1];
+ p1_3d[2] = 1.0f;
+ p2_3d[2] = -1.0f;
+ v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
+
+ /* generate a new fuv, (this is possibly a non optimal solution,
+ * since we only need 2d calculation but use 3d func's)
+ *
+ * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
+ * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
+ * This means the new values will be correct in relation to the derived meshes face.
+ */
+ Vec2Copyf(v0_3d, v0);
+ Vec2Copyf(v1_3d, v1);
+ Vec2Copyf(v2_3d, v2);
+
+ /* Doing this in 3D is not nice */
+ LineIntersectsTriangle(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
+ }
+}
+
+/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
+void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v)
+{
+ float a[3],b[3];
+ float t2= t*t;
+ float t3= t2*t;
+ /* cubic interpolation */
+ a[0]= v1[0] + v2[0] + 2*(x1[0] - x2[0]);
+ a[1]= v1[1] + v2[1] + 2*(x1[1] - x2[1]);
+ a[2]= v1[2] + v2[2] + 2*(x1[2] - x2[2]);
+
+ b[0]= -2*v1[0] - v2[0] - 3*(x1[0] - x2[0]);
+ b[1]= -2*v1[1] - v2[1] - 3*(x1[1] - x2[1]);
+ b[2]= -2*v1[2] - v2[2] - 3*(x1[2] - x2[2]);
+
+ x[0]= a[0]*t3 + b[0]*t2 + v1[0]*t + x1[0];
+ x[1]= a[1]*t3 + b[1]*t2 + v1[1]*t + x1[1];
+ x[2]= a[2]*t3 + b[2]*t2 + v1[2]*t + x1[2];
+
+ v[0]= 3*a[0]*t2 + 2*b[0]*t + v1[0];
+ v[1]= 3*a[1]*t2 + 2*b[1]*t + v1[1];
+ v[2]= 3*a[2]*t2 + 2*b[2]*t + v1[2];
+}
int point_in_slice(float p[3], float v1[3], float l1[3], float l2[3])
{
@@ -3246,46 +4196,75 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3])
return 1;
}
+/* point closest to v1 on line v2-v3 in 3D */
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3)
+{
+ float lambda, cp[3];
+
+ lambda= lambda_cp_line_ex(v1, v2, v3, cp);
+
+ if(lambda <= 0.0f)
+ VecCopyf(closest, v2);
+ else if(lambda >= 1.0f)
+ VecCopyf(closest, v3);
+ else
+ VecCopyf(closest, cp);
+}
+
+/* distance v1 to line-piece v2-v3 in 3D */
+float PdistVL3Dfl(float *v1, float *v2, float *v3)
+{
+ float closest[3];
+
+ PclosestVL3Dfl(closest, v1, v2, v3);
+
+ return VecLenf(closest, v1);
+}
+
/********************************************************/
/* make a 4x4 matrix out of 3 transform components */
+/* matrices are made in the order: scale * rot * loc */
void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3])
{
- float tmat[3][3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* make base matrix */
- EulToMat3(eul, tmat);
-
- /* make new matrix */
+ /* initialise new matrix */
Mat4One(mat);
- mat[0][0] = tmat[0][0] * size[0];
- mat[0][1] = tmat[0][1] * size[1];
- mat[0][2] = tmat[0][2] * size[2];
-
- mat[1][0] = tmat[1][0] * size[0];
- mat[1][1] = tmat[1][1] * size[1];
- mat[1][2] = tmat[1][2] * size[2];
+ /* make rotation + scaling part */
+ EulToMat3(eul, rmat);
+ SizeToMat3(size, smat);
+ Mat3MulMat3(tmat, rmat, smat);
- mat[2][0] = tmat[2][0] * size[0];
- mat[2][1] = tmat[2][1] * size[1];
- mat[2][2] = tmat[2][2] * size[2];
+ /* copy rot/scale part to output matrix*/
+ Mat4CpyMat3(mat, tmat);
+ /* copy location to matrix */
mat[3][0] = loc[0];
mat[3][1] = loc[1];
mat[3][2] = loc[2];
}
/* make a 4x4 matrix out of 3 transform components */
+/* matrices are made in the order: scale * rot * loc */
void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3])
{
- float eul[3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* convert quaternion component to euler
- * NOTE: not as good as using quat directly. Todo for later.
- */
- QuatToEul(quat, eul);
+ /* initialise new matrix */
+ Mat4One(mat);
- /* make into matrix using exisiting code */
- LocEulSizeToMat4(mat, loc, eul, size);
+ /* make rotation + scaling part */
+ QuatToMat3(quat, rmat);
+ SizeToMat3(size, smat);
+ Mat3MulMat3(tmat, rmat, smat);
+
+ /* copy rot/scale part to output matrix*/
+ Mat4CpyMat3(mat, tmat);
+
+ /* copy location to matrix */
+ mat[3][0] = loc[0];
+ mat[3][1] = loc[1];
+ mat[3][2] = loc[2];
}
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
new file mode 100644
index 00000000000..219ca424df8
--- /dev/null
+++ b/source/blender/blenlib/intern/bpath.c
@@ -0,0 +1,556 @@
+/**
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Campbell barton
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BLI_bpath.h"
+#include "BKE_global.h"
+#include "DNA_ID.h" /* Library */
+#include "DNA_vfont_types.h"
+#include "DNA_image_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_scene_types.h" /* to get the current frame */
+#include <stdlib.h>
+#include <string.h>
+
+#include "BKE_main.h" /* so we can access G.main->*.first */
+#include "BKE_image.h" /* so we can check the image's type */
+
+#include "blendef.h"
+#include "BKE_utildefines.h"
+
+/* for writing to a textblock */
+#include "BKE_text.h"
+#include "BLI_blenlib.h"
+#include "DNA_text_types.h"
+
+/* path/file handeling stuff */
+#ifndef WIN32
+ #include <dirent.h>
+ #include <unistd.h>
+#else
+ #include "BLI_winstuff.h"
+ #include <io.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#define FILE_MAX 240
+
+
+/* TODO - BPATH_PLUGIN, BPATH_SEQ */
+enum BPathTypes {
+ BPATH_IMAGE = 0,
+ BPATH_SOUND,
+ BPATH_FONT,
+ BPATH_LIB,
+
+ BPATH_DONE
+};
+
+
+void BLI_bpathIterator_init( struct BPathIterator *bpi ) {
+ bpi->type = BPATH_IMAGE;
+ bpi->data = NULL;
+ BLI_bpathIterator_step(bpi);
+}
+
+char* BLI_bpathIterator_getPath( struct BPathIterator *bpi) {
+ return bpi->path;
+}
+void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded) {
+ char *filepath, *libpath;
+
+ filepath = BLI_bpathIterator_getPath(bpi);
+ libpath = BLI_bpathIterator_getLib(bpi);
+
+ BLI_strncpy(path_expanded, filepath, FILE_MAXDIR*2);
+
+ if (libpath) { /* check the files location relative to its library path */
+ BLI_convertstringcode(path_expanded, libpath, G.scene->r.cfra);
+ } else { /* local data, use the blend files path */
+ BLI_convertstringcode(path_expanded, G.sce, G.scene->r.cfra);
+ }
+}
+char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
+ return bpi->lib;
+}
+char* BLI_bpathIterator_getName( struct BPathIterator *bpi) {
+ return bpi->name;
+}
+int BLI_bpathIterator_getType( struct BPathIterator *bpi) {
+ return bpi->type;
+}
+int BLI_bpathIterator_getPathMaxLen( struct BPathIterator *bpi) {
+ return bpi->len;
+}
+
+/* gets the first or the next image that has a path - not a viewer node or generated image */
+static struct Image *ima_getpath__internal(struct Image *ima, int step_next) {
+ if (ima==NULL)
+ return NULL;
+
+ if (step_next)
+ ima = ima->id.next;
+
+ while (ima) {
+ if (ima->packedfile==NULL && ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+ break;
+ /* image is not a image with a path, skip it */
+ ima = ima->id.next;
+ }
+ return ima;
+}
+
+static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) {
+ if (vf==NULL)
+ return NULL;
+
+ if (step_next)
+ vf = vf->id.next;
+
+ while (vf) {
+ if (vf->packedfile==NULL && BLI_streq(vf->name, "<builtin>")==0) {
+ break;
+ }
+
+ /* font with no path, skip it */
+ vf = vf->id.next;
+ }
+ return vf;
+}
+
+static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) {
+ if (snd==NULL)
+ return NULL;
+
+ if (step_next)
+ snd = snd->id.next;
+
+ while (snd) {
+ if (snd->packedfile==NULL) {
+ break;
+ }
+
+ /* font with no path, skip it */
+ snd = snd->id.next;
+ }
+ return snd;
+}
+
+void BLI_bpathIterator_step( struct BPathIterator *bpi) {
+ while (bpi->type != BPATH_DONE) {
+
+ if ((bpi->type) == BPATH_IMAGE) {
+ /*if (bpi->data) bpi->data = ((ID *)bpi->data)->next;*/
+ if (bpi->data) bpi->data = ima_getpath__internal( (Image *)bpi->data, 1 ); /* must skip images that have no path */
+ else bpi->data = ima_getpath__internal(G.main->image.first, 0);
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ Image *ima = (Image *)bpi->data;
+
+ bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL;
+ bpi->path = ima->name;
+ bpi->name = ima->id.name+2;
+ bpi->len = sizeof(ima->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_SOUND) {
+ if (bpi->data) bpi->data = snd_getpath__internal( (bSound *)bpi->data, 1 ); /* must skip images that have no path */
+ else bpi->data = snd_getpath__internal(G.main->sound.first, 0);
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ bSound *snd = (bSound *)bpi->data;
+
+ bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL;
+ bpi->path = snd->sample->name;
+ bpi->name = snd->id.name+2;
+ bpi->len = sizeof(snd->sample->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_FONT) {
+
+ if (bpi->data) bpi->data = vf_getpath__internal( (VFont *)bpi->data, 1 );
+ else bpi->data = vf_getpath__internal( G.main->vfont.first, 0 );
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ VFont *vf = (VFont *)bpi->data;
+
+ bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL;
+ bpi->path = vf->name;
+ bpi->name = vf->id.name+2;
+ bpi->len = sizeof(vf->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_LIB) {
+
+ if (bpi->data) bpi->data = ((ID *)bpi->data)->next;
+ else bpi->data = G.main->library.first;
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ Library *lib = (Library *)bpi->data;
+
+ bpi->lib = NULL;
+ bpi->path = lib->name;
+ bpi->name = NULL;
+ bpi->len = sizeof(lib->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+ }
+ }
+}
+
+int BLI_bpathIterator_isDone( struct BPathIterator *bpi) {
+ return bpi->type==BPATH_DONE;
+}
+
+/* include the path argument */
+static void bpathToText(Text *btxt, struct BPathIterator *bpi)
+{
+ char *name;
+ char path_expanded[FILE_MAXDIR*2];
+
+ switch(BLI_bpathIterator_getType(bpi)) {
+ case BPATH_IMAGE:
+ txt_insert_buf( btxt, "Image \"" );
+ break;
+ case BPATH_SOUND:
+ txt_insert_buf( btxt, "Sound \"" );
+ break;
+ case BPATH_FONT:
+ txt_insert_buf( btxt, "Font \"" );
+ break;
+ case BPATH_LIB:
+ txt_insert_buf( btxt, "Library \"" );
+ break;
+ default:
+ txt_insert_buf( btxt, "Unknown \"" );
+ break;
+ }
+
+ name = BLI_bpathIterator_getName(bpi);
+
+ if (name) {
+ txt_insert_buf( btxt, name );
+ }
+ txt_insert_buf( btxt, "\" " );
+
+ BLI_bpathIterator_copyPathExpanded(bpi, path_expanded);
+
+ txt_insert_buf( btxt, path_expanded );
+ txt_insert_buf( btxt, "\n" );
+ txt_move_eof( btxt, 0 );
+}
+
+/* high level function */
+void checkMissingFiles( char *txtname ) {
+ Text *btxt = NULL;
+ struct BPathIterator bpi;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_expanded[FILE_MAXDIR*2];
+ char *filepath, *libpath;
+ int files_missing = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+
+ if (!BLI_exists(filepath_expanded)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_files.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ files_missing = 1;
+ }
+ BLI_bpathIterator_step(&bpi);
+ }
+}
+
+/* dont log any errors at the moment, should probably do this */
+void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+ struct BPathIterator bpi;
+ char *filepath, *libpath;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+
+ Text *btxt = NULL;
+
+ *tot = *changed = *failed = *linked = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if(strncmp(filepath, "//", 2)) {
+ if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
+ (*linked)++;
+ } else { /* local data, use the blend files path */
+ BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
+ /* Important BLI_cleanup_dir runs before the path is made relative
+ * because it wont work for paths that start with "//../" */
+ BLI_cleanup_file(G.sce, filepath_relative); /* fix any /foo/../foo/ */
+ BLI_makestringcode(G.sce, filepath_relative);
+ /* be safe and check the length */
+ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_rel.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ } else {
+ if(strncmp(filepath_relative, "//", 2)==0) {
+ strcpy(filepath, filepath_relative);
+ (*changed)++;
+ } else {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_rel.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ (*tot)++;
+ }
+}
+
+/* dont log any errors at the moment, should probably do this -
+ * Verry similar to makeFilesRelative - keep in sync! */
+void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+ struct BPathIterator bpi;
+ char *filepath, *libpath;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+
+ Text *btxt = NULL;
+
+ *tot = *changed = *failed = *linked = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if(strncmp(filepath, "//", 2)==0) {
+ if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
+ (*linked)++;
+ } else { /* get the expanded path and check it is relative or too long */
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_absolute );
+ BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */
+ /* to be safe, check the length */
+ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_abs.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ } else {
+ if(strncmp(filepath_absolute, "//", 2)) {
+ strcpy(filepath, filepath_absolute);
+ (*changed)++;
+ } else {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_abs.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ (*tot)++;
+ }
+}
+
+
+/* find this file recursively, use the biggest file so thumbnails dont get used by mistake
+ - dir: subdir to search
+ - filename: set this filename
+ - filesize: filesize for the file
+*/
+#define MAX_RECUR 16
+static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth)
+{
+ /* file searching stuff */
+ DIR *dir;
+ struct dirent *de;
+ struct stat status;
+ char path[FILE_MAX];
+ int size;
+
+ dir = opendir(dirname);
+
+ if (dir==0)
+ return 0;
+
+ if (*filesize == -1)
+ *filesize = 0; /* dir opened fine */
+
+ while ((de = readdir(dir)) != NULL) {
+
+ if (strncmp(".", de->d_name, 2)==0 || strncmp("..", de->d_name, 3)==0)
+ continue;
+
+ BLI_join_dirfile(path, dirname, de->d_name);
+
+ if (stat(path, &status) != 0)
+ continue; /* cant stat, dont bother with this file, could print debug info here */
+
+ if (S_ISREG(status.st_mode)) { /* is file */
+ if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */
+ /* open the file to read its size */
+ size = BLI_filepathsize(path);
+ if ((size > 0) && (size > *filesize)) { /* find the biggest file */
+ *filesize = size;
+ BLI_strncpy(filename_new, path, FILE_MAX);
+ }
+ }
+ } else if (S_ISDIR(status.st_mode)) { /* is subdir */
+ if (*recur_depth <= MAX_RECUR) {
+ (*recur_depth)++;
+ findFileRecursive(filename_new, path, filename, filesize, recur_depth);
+ (*recur_depth)--;
+ }
+ }
+ }
+ closedir(dir);
+ return 1;
+}
+
+/* high level function - call from fileselector */
+void findMissingFiles(char *str) {
+ struct BPathIterator bpi;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_expanded[FILE_MAXDIR*2];
+ char *filepath, *libpath;
+ int filesize, recur_depth;
+
+ char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX], dummyname[FILE_MAX];
+
+ BLI_split_dirfile(str, dirname, dummyname);
+
+ BLI_bpathIterator_init(&bpi);
+
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if (libpath==NULL) {
+
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+
+ if (!BLI_exists(filepath_expanded)) {
+ /* can the dir be opened? */
+ filesize = -1;
+ recur_depth = 0;
+ BLI_split_dirfile(filepath, dummyname, filename); /* the file to find */
+
+ findFileRecursive(filename_new, dirname, filename, &filesize, &recur_depth);
+ if (filesize == -1) { /* could not open dir */
+ printf("Could not open dir \"%s\"\n", dirname);
+ return;
+ }
+
+ if (filesize > 0) {
+
+ if (BLI_bpathIterator_getPathMaxLen( &bpi ) < strlen(filename_new)) {
+ printf("cannot set path \"%s\" too long!", filename_new);
+ } else {
+ /* copy the found path into the old one */
+ if (G.relbase_valid)
+ BLI_makestringcode(G.sce, filename_new);
+
+ strcpy( BLI_bpathIterator_getPath( &bpi ), filename_new );
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ }
+}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index fcea30982bd..e5b11412aa1 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -79,7 +79,7 @@ char *first_slash(char *string) {
else return fbslash;
}
-char *BLI_last_slash(char *string) {
+char *BLI_last_slash(const char *string) {
char *lfslash, *lbslash;
lfslash= strrchr(string, '/');
@@ -92,6 +92,39 @@ char *BLI_last_slash(char *string) {
else return lfslash;
}
+/* adds a slash if there isnt one there alredy */
+void BLI_add_slash(char *string) {
+ int len = strlen(string);
+#ifdef WIN32
+ if (string[len-1]!='\\') {
+ string[len] = '\\';
+ string[len+1] = '\0';
+ }
+#else
+ if (string[len-1]!='/') {
+ string[len] = '/';
+ string[len+1] = '\0';
+ }
+#endif
+}
+
+/* removes a slash if there is one */
+void BLI_del_slash(char *string) {
+ int len = strlen(string);
+ while (len) {
+#ifdef WIN32
+ if (string[len-1]=='\\') {
+#else
+ if (string[len-1]=='/') {
+#endif
+ string[len-1] = '\0';
+ len--;
+ } else {
+ break;
+ }
+ }
+}
+
/* gzip the file in from and write it to "to".
return -1 if zlib fails, -2 if the originating file does not exist
note: will remove the "from" file
@@ -140,6 +173,23 @@ int BLI_is_writable(char *filename)
}
}
+int BLI_touch(const char *file)
+{
+ FILE *f = fopen(file,"r+b");
+ if (f != NULL) {
+ char c = getc(f);
+ rewind(f);
+ putc(c,f);
+ } else {
+ f = fopen(file,"wb");
+ }
+ if (f) {
+ fclose(f);
+ return 1;
+ }
+ return 0;
+}
+
#ifdef WIN32
static char str[MAXPATHLEN+12];
@@ -161,12 +211,6 @@ int BLI_delete(char *file, int dir, int recursive) {
return err;
}
-int BLI_touch(char *file) {
- callLocalErrorCallBack("Touching files is unsupported on Windows");
-
- return 1;
-}
-
int BLI_move(char *file, char *to) {
int err;
@@ -296,17 +340,6 @@ int BLI_delete(char *file, int dir, int recursive)
return -1;
}
-int BLI_touch(char *file)
-{
-
- if( BLI_exists("/bin/touch") )
- sprintf(str, "/bin/touch %s", file);
- else
- sprintf(str, "/usr/bin/touch %s", file);
-
- return system(str);
-}
-
int BLI_move(char *file, char *to) {
sprintf(str, "/bin/mv -f \"%s\" \"%s\"", file, to);
diff --git a/source/blender/blenlib/intern/fnmatch.c b/source/blender/blenlib/intern/fnmatch.c
new file mode 100644
index 00000000000..54114ad3448
--- /dev/null
+++ b/source/blender/blenlib/intern/fnmatch.c
@@ -0,0 +1,250 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You 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. */
+
+#ifdef WIN32
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Enable GNU extensions in fnmatch.h. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+#include <errno.h>
+#include <BLI_fnmatch.h>
+#include <ctype.h>
+
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined _LIBC || !defined __GNU_LIBRARY__
+
+
+# if defined STDC_HEADERS || !defined isascii
+# define ISASCII(c) 1
+# else
+# define ISASCII(c) isascii(c)
+# endif
+
+# define ISUPPER(c) (ISASCII (c) && isupper (c))
+
+
+# ifndef errno
+extern int errno;
+# endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, nonzero if not. */
+int
+fnmatch (const char *pattern, const char *string, int flags)
+{
+ register const char *p = pattern, *n = string;
+ register char c;
+
+/* Note that this evaluates C many times. */
+# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
+
+ while ((c = *p++) != '\0')
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_FILE_NAME) && *n == '/')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ if (c == '\0')
+ /* Trailing \ loses. */
+ return FNM_NOMATCH;
+ c = FOLD (c);
+ }
+ if (FOLD (*n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++)
+ {
+ if ((flags & FNM_FILE_NAME) && *n == '/')
+ /* A slash does not match a wildcard under FNM_FILE_NAME. */
+ return FNM_NOMATCH;
+ else if (c == '?')
+ {
+ /* A ? needs to match one character. */
+ if (*n == '\0')
+ /* There isn't another character; no match. */
+ return FNM_NOMATCH;
+ else
+ /* One character of the string is consumed in matching
+ this ? wildcard, so *??? won't match if there are
+ less than three characters. */
+ ++n;
+ }
+ }
+
+ if (c == '\0')
+ return 0;
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ c1 = FOLD (c1);
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || FOLD (*n) == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ return FNM_NOMATCH;
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ cstart = cend = *p++;
+ }
+
+ cstart = cend = FOLD (cstart);
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ c = FOLD (c);
+
+ if ((flags & FNM_FILE_NAME) && c == '/')
+ /* [/] can never match. */
+ return FNM_NOMATCH;
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+ cend = FOLD (cend);
+
+ c = *p++;
+ }
+
+ if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:;
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD (*n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return 0;
+
+ if ((flags & FNM_LEADING_DIR) && *n == '/')
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
+
+ return FNM_NOMATCH;
+
+# undef FOLD
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#else
+
+static void BLI_FNMATCH_C_IS_EMPTY_FOR_UNIX(void)
+{
+ /*intentionally empty*/
+}
+
+#endif /* WIN32 */
+
+
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 941bf4204a8..1fcb6653dc9 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -1949,7 +1949,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt)
chardesc *cd;
short *_data, *data;
int a, i, count, stop, ready, meet;
- short first[2], last[2];
+ short first[2]={0,0}, last[2]={0,0};
struct Nurb *nu;
struct BezTriple *bezt, *bez2;
float scale, dx, dy;
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index df01288aab8..71df0ede037 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -116,6 +116,14 @@ void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems)
free(temp);
}
+void rng_skip(RNG *rng, int n)
+{
+ int i;
+
+ for(i=0; i<n; i++)
+ rng_getInt(rng);
+}
+
/***/
static RNG theBLI_rng = {0};
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index a6b91bf489d..9d70d85939e 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -50,7 +50,9 @@
#include <time.h>
#include <sys/stat.h>
-#if !defined(linux) && (defined(__sgi) || defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__))
+#if defined (__sun__) || defined (__sun)
+#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
+#elif !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__))
#include <sys/statfs.h>
#endif
@@ -179,13 +181,21 @@ double BLI_diskfree(char *dir)
return (double) (freec*bytesps*sectorspc);
#else
- struct statfs disk;
- char name[100],*slash;
-
+#if defined (__sun__) || defined (__sun)
+ struct statvfs disk;
+#else
+ struct statfs disk;
+#endif
+ char name[FILE_MAXDIR],*slash;
+ int len = strlen(dir);
+
+ if (len >= FILE_MAXDIR) /* path too long */
+ return -1;
+
strcpy(name,dir);
- if(strlen(name)){
+ if(len){
slash = strrchr(name,'/');
if (slash) slash[1] = 0;
} else strcpy(name,"/");
@@ -196,12 +206,12 @@ double BLI_diskfree(char *dir)
#ifdef __BeOS
return -1;
#endif
-#if !defined(linux) && (defined (__sgi) || defined (__sun__) || defined (__sun) || defined(__sparc) || defined(__sparc__))
- if (statfs(name, &disk, sizeof(struct statfs), 0)){
- /* printf("diskfree: Couldn't get information about %s.\n",dir); */
- return(-1);
- }
+#if defined (__sun__) || defined (__sun)
+ if (statvfs(name, &disk)) return(-1);
+#elif !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__))
+ /* WARNING - This may not be supported by geeneric unix os's - Campbell */
+ if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
#endif
return ( ((double) disk.f_bsize) * ((double) disk.f_bfree));
@@ -326,11 +336,11 @@ void BLI_adddirstrings()
char size[250];
static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
int num, mode;
- int num1, num2, num3, num4;
+ off_t num1, num2, num3, num4, num5;
#ifdef WIN32
__int64 st_size;
#else
- long long st_size;
+ off_t st_size;
#endif
struct direntry * file;
@@ -392,7 +402,7 @@ void BLI_adddirstrings()
* will buy us some time until files get bigger than 4GB or until
* everyone starts using __USE_FILE_OFFSET64 or equivalent.
*/
- st_size= (unsigned int)files[num].s.st_size;
+ st_size= (off_t)files[num].s.st_size;
num1= st_size % 1000;
num2= st_size/1000;
@@ -401,11 +411,15 @@ void BLI_adddirstrings()
num3= num3 % 1000;
num4= st_size/(1000*1000*1000);
num4= num4 % 1000;
-
- if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", num4, num3, num2, num1);
- else if(num3) sprintf(files[num].size, "%7d %03d %03d", num3, num2, num1);
- else if(num2) sprintf(files[num].size, "%11d %03d", num2, num1);
- else if(num1) sprintf(files[num].size, "%15d", num1);
+ num5= st_size/(1000000000000LL);
+ num5= num5 % 1000;
+
+ if(num5)
+ sprintf(files[num].size, "%1d %03d %03d %03d K", (int)num5, (int)num4, (int)num3, (int)num2);
+ else if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", (int)num4, (int)num3, (int)num2, (int)num1);
+ else if(num3) sprintf(files[num].size, "%7d %03d %03d", (int)num3, (int)num2, (int)num1);
+ else if(num2) sprintf(files[num].size, "%11d %03d", (int)num2, (int)num1);
+ else if(num1) sprintf(files[num].size, "%15d", (int)num1);
else sprintf(files[num].size, "0");
strftime(datum, 32, "%d-%b-%y %H:%M", tm);
@@ -469,6 +483,17 @@ int BLI_filesize(int file)
return (buf.st_size);
}
+int BLI_filepathsize(const char *path)
+{
+ int size, file = open(path, O_BINARY|O_RDONLY);
+
+ if (file <= 0)
+ return -1;
+
+ size = BLI_filesize(file);
+ close(file);
+ return size;
+}
int BLI_exist(char *name)
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index cb10185386a..f4a44b3a0db 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -38,6 +38,15 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
+/* for checking system threads - BLI_system_thread_count */
+#ifdef WIN32
+#include "Windows.h"
+#elif defined(__APPLE__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#else
+#include <unistd.h>
+#endif
/* ********** basic thread control API ************
@@ -109,22 +118,26 @@ static void BLI_unlock_malloc_thread(void)
pthread_mutex_unlock(&_malloc_lock);
}
+/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
+ problem otherwise: scene render will kill of the mutex!
+*/
+
void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
{
int a;
- if(threadbase==NULL)
- return;
- threadbase->first= threadbase->last= NULL;
+ if(threadbase != NULL && tot > 0) {
+ threadbase->first= threadbase->last= NULL;
- if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
- else if(tot<1) tot= 1;
+ if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
+ else if(tot<1) tot= 1;
- for(a=0; a<tot; a++) {
- ThreadSlot *tslot= MEM_callocN(sizeof(ThreadSlot), "threadslot");
- BLI_addtail(threadbase, tslot);
- tslot->do_thread= do_thread;
- tslot->avail= 1;
+ for(a=0; a<tot; a++) {
+ ThreadSlot *tslot= MEM_callocN(sizeof(ThreadSlot), "threadslot");
+ BLI_addtail(threadbase, tslot);
+ tslot->do_thread= do_thread;
+ tslot->avail= 1;
+ }
}
MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
@@ -190,12 +203,14 @@ void BLI_end_threads(ListBase *threadbase)
{
ThreadSlot *tslot;
- for(tslot= threadbase->first; tslot; tslot= tslot->next) {
- if(tslot->avail==0) {
- pthread_join(tslot->pthread, NULL);
+ if (threadbase) {
+ for(tslot= threadbase->first; tslot; tslot= tslot->next) {
+ if(tslot->avail==0) {
+ pthread_join(tslot->pthread, NULL);
+ }
}
+ BLI_freelistN(threadbase);
}
- BLI_freelistN(threadbase);
thread_levels--;
if(thread_levels==0)
@@ -218,4 +233,34 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_custom1_lock);
}
+/* how many threads are native on this system? */
+int BLI_system_thread_count( void )
+{
+ int t;
+#ifdef WIN32
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ t = (int) info.dwNumberOfProcessors;
+#else
+# ifdef __APPLE__
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ len = sizeof(t);
+ sysctl(mib, 2, &t, &len, NULL, 0);
+# else
+ t = (int)sysconf(_SC_NPROCESSORS_ONLN);
+# endif
+#endif
+
+ if (t>RE_MAX_THREAD)
+ return RE_MAX_THREAD;
+ if (t<1)
+ return 1;
+
+ return t;
+}
+
/* eof */
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index cfce8e3dafa..51691499ba8 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -44,8 +44,10 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "DNA_listBase.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_blenlib.h"
#include "BLI_storage.h"
#include "BLI_storage_types.h"
#include "BLI_dynamiclist.h"
@@ -84,37 +86,39 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
+#ifdef __linux__
+#include "binreloc.h"
+#endif
+
/* local */
static int add_win32_extension(char *name);
/* implementation */
-/* Ripped this from blender.c
- */
+/* Ripped this from blender.c */
void addlisttolist(ListBase *list1, ListBase *list2)
{
+ if (list2->first==0) return;
- if(list2->first==0) return;
-
- if(list1->first==0) {
+ if (list1->first==0) {
list1->first= list2->first;
list1->last= list2->last;
}
else {
- ((struct Link *)list1->last)->next= list2->first;
- ((struct Link *)list2->first)->prev= list1->last;
+ ((Link *)list1->last)->next= list2->first;
+ ((Link *)list2->first)->prev= list1->last;
list1->last= list2->last;
}
list2->first= list2->last= 0;
}
-int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
+int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen)
{
unsigned short len, len2, nums = 0, nume = 0;
short i, found = 0;
- len2 = len = strlen( string);
+ len2 = len = strlen(string);
if (len > 6) {
if (BLI_strncasecmp(string + len - 6, ".blend", 6) == 0) len -= 6;
@@ -125,7 +129,6 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
if (BLI_strncasecmp(string + len - 9, ".blend.gz", 9) == 0) len -= 9;
}
-
if (len == len2) {
if (len > 4) {
/* handle .jf0 en .jf1 for jstreams */
@@ -143,7 +146,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
}
}
- for (i = len - 1; i >= 0; i--){
+ for (i = len - 1; i >= 0; i--) {
if (string[i] == '/') break;
if (isdigit(string[i])) {
if (found){
@@ -155,12 +158,12 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
found = 1;
}
}
- else{
+ else {
if (found) break;
}
}
if (found){
- if (staart) strcpy(staart,&string[nume+1]);
+ if (start) strcpy(start,&string[nume+1]);
if (kop) {
strcpy(kop,string);
kop[nums]=0;
@@ -168,7 +171,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
if (numlen) *numlen = nume-nums+1;
return ((int)atoi(&(string[nums])));
}
- if (staart) strcpy(staart, string + len);
+ if (start) strcpy(start, string + len);
if (kop) {
strncpy(kop, string, len);
kop[len] = 0;
@@ -178,7 +181,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
}
-void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen, int pic)
+void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic)
{
char numstr[10]="";
unsigned short len,i;
@@ -187,17 +190,17 @@ void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen,
if (pic>0 || numlen==4) {
len= sprintf(numstr,"%d",pic);
-
+
for(i=len;i<numlen;i++){
strcat(string,"0");
}
strcat(string,numstr);
}
- strcat(string,staart);
+ strcat(string, start);
}
-void BLI_newname(char * name, int add)
+void BLI_newname(char *name, int add)
{
char head[128], tail[128];
int pic;
@@ -215,38 +218,111 @@ void BLI_newname(char * name, int add)
pic += add;
- if(digits==4 && pic<0) pic= 0;
+ if (digits==4 && pic<0) pic= 0;
BLI_stringenc(name, head, tail, digits, pic);
}
+/* little helper macro for BLI_uniquename */
+#ifndef GIVE_STRADDR
+ #define GIVE_STRADDR(data, offset) ( ((char *)data) + offset )
+#endif
+
+/* Generic function to set a unique name. It is only designed to be used in situations
+ * where the name is part of the struct, and also that the name is at most 128 chars long.
+ *
+ * For places where this is used, see constraint.c for example...
+ *
+ * name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h
+ * len: maximum length of string (to prevent overflows, etc.)
+ * defname: the name that should be used by default if none is specified already
+ */
+void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs, short len)
+{
+ Link *link;
+ char tempname[128];
+ int number = 1, exists = 0;
+ char *dot;
+
+ /* Make sure length can be handled */
+ if ((len < 0) || (len > 128))
+ return;
+
+ /* See if we are given an empty string */
+ if (ELEM(NULL, vlink, defname))
+ return;
+
+ if (GIVE_STRADDR(vlink, name_offs) == '\0') {
+ /* give it default name first */
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len);
+ }
+
+ /* See if we even need to do this */
+ if (list == NULL)
+ return;
+
+ for (link = list->first; link; link= link->next) {
+ if (link != vlink) {
+ if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) {
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (exists == 0)
+ return;
+
+ /* Strip off the suffix */
+ dot = strchr(GIVE_STRADDR(vlink, name_offs), '.');
+ if (dot)
+ *dot=0;
+
+ for (number = 1; number <= 999; number++) {
+ BLI_snprintf(tempname, 128, "%s.%03d", GIVE_STRADDR(vlink, name_offs), number);
+
+ exists = 0;
+ for (link= list->first; link; link= link->next) {
+ if (vlink != link) {
+ if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) {
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (exists == 0) {
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len);
+ return;
+ }
+ }
+}
+
void BLI_addhead(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
link->next = listbase->first;
- link->prev = 0;
+ link->prev = NULL;
- if (listbase->first) ((struct Link *)listbase->first)->prev = link;
- if (listbase->last == 0) listbase->last = link;
+ if (listbase->first) ((Link *)listbase->first)->prev = link;
+ if (listbase->last == NULL) listbase->last = link;
listbase->first = link;
}
void BLI_addtail(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
- link->next = 0;
+ link->next = NULL;
link->prev = listbase->last;
- if (listbase->last) ((struct Link *)listbase->last)->next = link;
+ if (listbase->last) ((Link *)listbase->last)->next = link;
if (listbase->first == 0) listbase->first = link;
listbase->last = link;
}
@@ -254,10 +330,10 @@ void BLI_addtail(ListBase *listbase, void *vlink)
void BLI_remlink(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
if (link->next) link->next->prev = link->prev;
if (link->prev) link->prev->next = link->next;
@@ -269,10 +345,10 @@ void BLI_remlink(ListBase *listbase, void *vlink)
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
BLI_remlink(listbase,link);
MEM_freeN(link);
@@ -281,19 +357,23 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink)
{
- struct Link *prevlink= vprevlink, *newlink= vnewlink;
+ Link *prevlink= vprevlink;
+ Link *newlink= vnewlink;
/* newlink comes after prevlink */
-
- if (newlink == 0) return;
- if (listbase == 0) return;
-
- if(listbase->first==0) { /* empty list */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
+
+ /* empty list */
+ if (listbase->first == NULL) {
+
listbase->first= newlink;
listbase->last= newlink;
return;
}
- if (prevlink== 0) { /* insert before first element */
+
+ /* insert before first element */
+ if (prevlink == NULL) {
newlink->next= listbase->first;
newlink->prev= 0;
newlink->next->prev= newlink;
@@ -301,96 +381,170 @@ void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink)
return;
}
- if (listbase->last== prevlink) /* at end of list */
+ /* at end of list */
+ if (listbase->last== prevlink)
listbase->last = newlink;
newlink->next= prevlink->next;
prevlink->next= newlink;
- if(newlink->next) newlink->next->prev= newlink;
+ if (newlink->next) newlink->next->prev= newlink;
newlink->prev= prevlink;
}
-void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
+/* This uses insertion sort, so NOT ok for large list */
+void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *))
+{
+ Link *current = NULL;
+ Link *previous = NULL;
+ Link *next = NULL;
+
+ if (cmp == NULL) return;
+ if (listbase == NULL) return;
+
+ if (listbase->first != listbase->last)
+ {
+ for( previous = listbase->first, current = previous->next; current; current = next )
+ {
+ next = current->next;
+ previous = current->prev;
+
+ BLI_remlink(listbase, current);
+
+ while(previous && cmp(previous, current) == 1)
+ {
+ previous = previous->prev;
+ }
+
+ BLI_insertlinkafter(listbase, previous, current);
+ }
+ }
+}
+
+void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
{
- struct Link *nextlink= vnextlink, *newlink= vnewlink;
+ Link *prevlink= vprevlink;
+ Link *newlink= vnewlink;
/* newlink before nextlink */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
- if (newlink == 0) return;
- if (listbase == 0) return;
+ /* empty list */
+ if (listbase->first == NULL) {
+ listbase->first= newlink;
+ listbase->last= newlink;
+ return;
+ }
+
+ /* insert at head of list */
+ if (prevlink == NULL) {
+ newlink->prev = NULL;
+ newlink->next = listbase->first;
+ ((Link *)listbase->first)->prev = newlink;
+ listbase->first = newlink;
+ return;
+ }
+
+ /* at end of list */
+ if (listbase->last == prevlink)
+ listbase->last = newlink;
+
+ newlink->next = prevlink->next;
+ newlink->prev = prevlink;
+ prevlink->next = newlink;
+ if (newlink->next) newlink->next->prev = newlink;
+}
- if(listbase->first==0) { /* empty list */
+void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
+{
+ Link *nextlink= vnextlink;
+ Link *newlink= vnewlink;
+
+ /* newlink before nextlink */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
+
+ /* empty list */
+ if (listbase->first == NULL) {
listbase->first= newlink;
listbase->last= newlink;
return;
}
- if (nextlink== 0) { /* insert at end of list */
+
+ /* insert at end of list */
+ if (nextlink == NULL) {
newlink->prev= listbase->last;
newlink->next= 0;
- ((struct Link *)listbase->last)->next= newlink;
+ ((Link *)listbase->last)->next= newlink;
listbase->last= newlink;
return;
}
- if (listbase->first== nextlink) /* at beginning of list */
+ /* at beginning of list */
+ if (listbase->first== nextlink)
listbase->first = newlink;
newlink->next= nextlink;
newlink->prev= nextlink->prev;
nextlink->prev= newlink;
- if(newlink->prev) newlink->prev->next= newlink;
+ if (newlink->prev) newlink->prev->next= newlink;
}
void BLI_freelist(ListBase *listbase)
{
- struct Link *link,*next;
+ Link *link, *next;
- if (listbase == 0) return;
+ if (listbase == NULL)
+ return;
+
link= listbase->first;
- while(link) {
+ while (link) {
next= link->next;
free(link);
link= next;
}
- listbase->first=0;
- listbase->last=0;
+
+ listbase->first= NULL;
+ listbase->last= NULL;
}
void BLI_freelistN(ListBase *listbase)
{
- struct Link *link,*next;
+ Link *link, *next;
- if (listbase == 0) return;
+ if (listbase == NULL) return;
+
link= listbase->first;
- while(link) {
+ while (link) {
next= link->next;
MEM_freeN(link);
link= next;
}
- listbase->first=0;
- listbase->last=0;
+
+ listbase->first= NULL;
+ listbase->last= NULL;
}
int BLI_countlist(ListBase *listbase)
{
- Link * link;
+ Link *link;
int count = 0;
- if (listbase){
+ if (listbase) {
link = listbase->first;
- while(link) {
+ while (link) {
count++;
link= link->next;
}
}
- return(count);
+ return count;
}
-void * BLI_findlink(ListBase *listbase, int number)
+void *BLI_findlink(ListBase *listbase, int number)
{
- Link * link = NULL;
+ Link *link = NULL;
if (number >= 0) {
link = listbase->first;
@@ -400,7 +554,27 @@ void * BLI_findlink(ListBase *listbase, int number)
}
}
- return (link);
+ return link;
+}
+
+int BLI_findindex(ListBase *listbase, void *vlink)
+{
+ Link *link= NULL;
+ int number= 0;
+
+ if (listbase == NULL) return -1;
+ if (vlink == NULL) return -1;
+
+ link= listbase->first;
+ while (link) {
+ if (link == vlink)
+ return number;
+
+ number++;
+ link= link->next;
+ }
+
+ return -1;
}
/*=====================================================================================*/
@@ -626,14 +800,14 @@ void BLI_dlist_reinit(DynamicList *dlist)
/*=====================================================================================*/
-char *BLI_strdupn(char *str, int len) {
+char *BLI_strdupn(const char *str, int len) {
char *n= MEM_mallocN(len+1, "strdup");
memcpy(n, str, len);
n[len]= '\0';
return n;
}
-char *BLI_strdup(char *str) {
+char *BLI_strdup(const char *str) {
return BLI_strdupn(str, strlen(str));
}
@@ -682,6 +856,16 @@ int BLI_strcaseeq(char *a, char *b) {
void BLI_cleanup_dir(const char *relabase, char *dir)
{
+ BLI_cleanup_file(relabase, dir);
+#ifdef WIN32
+ strcat(dir, "\\");
+#else
+ strcat(dir, "/");
+#endif
+}
+
+void BLI_cleanup_file(const char *relabase, char *dir)
+{
short a;
char *start, *eind;
@@ -719,9 +903,7 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
dir[a] = 0;
}
}
-
- strcat(dir, "\\");
-#else
+#else
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
dir[0]= '/';
dir[1]= 0;
@@ -755,8 +937,6 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
if (a<=0) break;
}
}
-
- strcat(dir, "/");
#endif
}
@@ -922,6 +1102,7 @@ int BLI_convertstringcode(char *path, const char *basepath, int framenum)
return wasrelative;
}
+/* copy di to fi, filename only */
void BLI_splitdirstring(char *di, char *fi)
{
char *lslash= BLI_last_slash(di);
@@ -1167,35 +1348,37 @@ int BLI_testextensie(const char *str, const char *ext)
}
-
-void BLI_split_dirfile(const char *string, char *dir, char *file)
+/* warning, can modify 'string' */
+void BLI_split_dirfile(char *string, char *dir, char *file)
{
int a;
#ifdef WIN32
int sl;
short is_relative = 0;
+ char path[FILE_MAX];
#endif
dir[0]= 0;
file[0]= 0;
#ifdef WIN32
- BLI_char_switch(string, '/', '\\'); /* make sure we have a valid path format */
- sl = strlen(string);
+ BLI_strncpy(path, string, FILE_MAX);
+ BLI_char_switch(path, '/', '\\'); /* make sure we have a valid path format */
+ sl = strlen(path);
if (sl) {
int len;
- if (string[0] == '/' || string[0] == '\\') {
- BLI_strncpy(dir, string, FILE_MAXDIR);
- if (sl > 1 && string[0] == '\\' && string[1] == '\\') is_relative = 1;
- } else if (sl > 2 && string[1] == ':' && string[2] == '\\') {
- BLI_strncpy(dir, string, FILE_MAXDIR);
+ if (path[0] == '/' || path[0] == '\\') {
+ BLI_strncpy(dir, path, FILE_MAXDIR);
+ if (sl > 1 && path[0] == '\\' && path[1] == '\\') is_relative = 1;
+ } else if (sl > 2 && path[1] == ':' && path[2] == '\\') {
+ BLI_strncpy(dir, path, FILE_MAXDIR);
} else {
BLI_getwdN(dir);
strcat(dir,"\\");
- strcat(dir,string);
- BLI_strncpy(string,dir,FILE_MAXDIR+FILE_MAXFILE);
+ strcat(dir,path);
+ BLI_strncpy(path,dir,FILE_MAXDIR+FILE_MAXFILE);
}
-
+
// BLI_exist doesn't recognize a slashed dirname as a dir
// check if a trailing slash exists, and remove it. Do not do this
// when we are already at root. -jesterKing
@@ -1203,7 +1386,7 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
if(a>=4 && dir[a-1]=='\\') dir[a-1] = 0;
if (is_relative) {
- printf("WARNING: BLI_split_dirfile needs absolute dir");
+ printf("WARNING: BLI_split_dirfile needs absolute dir\n");
}
else {
BLI_make_exist(dir);
@@ -1214,18 +1397,18 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
/* copy from end of string into file, to ensure filename itself isn't truncated
if string is too long. (aphex) */
- len = FILE_MAXFILE - strlen(string);
+ len = FILE_MAXFILE - strlen(path);
if (len < 0)
- BLI_strncpy(file,string + abs(len),FILE_MAXFILE);
+ BLI_strncpy(file,path + abs(len),FILE_MAXFILE);
else
- BLI_strncpy(file,string,FILE_MAXFILE);
+ BLI_strncpy(file,path,FILE_MAXFILE);
- if (strrchr(string,'\\')){
- BLI_strncpy(file,strrchr(string,'\\')+1,FILE_MAXFILE);
+ if (strrchr(path,'\\')) {
+ BLI_strncpy(file,strrchr(path,'\\')+1,FILE_MAXFILE);
}
-
- if (a = strlen(dir)) {
+
+ if ( (a = strlen(dir)) ) {
if (dir[a-1] != '\\') strcat(dir,"\\");
}
}
@@ -1233,7 +1416,7 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
a = strlen(dir) - 1;
while(a>0 && dir[a] != '\\') a--;
dir[a + 1] = 0;
- BLI_strncpy(file, string + strlen(dir),FILE_MAXFILE);
+ BLI_strncpy(file, path + strlen(dir),FILE_MAXFILE);
}
}
@@ -1288,12 +1471,20 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
int sl_dir = strlen(dir);
BLI_strncpy(string, dir, FILE_MAX);
if (sl_dir > FILE_MAX-1) sl_dir = FILE_MAX-1;
+
+ /* only add seperator if needed */
#ifdef WIN32
- string[sl_dir] = '\\';
+ if (string[sl_dir-1] != '\\') {
+ string[sl_dir] = '\\';
+ sl_dir++;
+ }
#else
- string[sl_dir] = '/';
+ if (string[sl_dir-1] != '/') {
+ string[sl_dir] = '/';
+ sl_dir++;
+ }
#endif
- sl_dir++;
+
if (sl_dir <FILE_MAX) {
BLI_strncpy(string + sl_dir, file, FILE_MAX-sl_dir);
}
@@ -1340,10 +1531,10 @@ static int add_win32_extension(char *name)
return (retval);
}
-void BLI_where_am_i(char *fullname, char *name)
+void BLI_where_am_i(char *fullname, const char *name)
{
char filename[FILE_MAXDIR+FILE_MAXFILE];
- char *path, *temp;
+ char *path = NULL, *temp;
int len;
#ifdef _WIN32
char *seperator = ";";
@@ -1353,6 +1544,17 @@ void BLI_where_am_i(char *fullname, char *name)
char *slash = "/";
#endif
+
+#ifdef __linux__
+ /* linux uses binreloc since argv[0] is not relyable, call br_init( NULL ) first */
+ path = br_find_exe( NULL );
+ if (path) {
+ strcpy(fullname, path);
+ return;
+ }
+#endif
+
+ /* unix and non linux */
if (name && fullname && strlen(name)) {
strcpy(fullname, name);
if (name[0] == '.') {
@@ -1413,6 +1615,47 @@ void BLI_where_am_i(char *fullname, char *name)
}
}
+void BLI_where_is_temp(char *fullname, int usertemp)
+{
+ fullname[0] = '\0';
+
+ if (usertemp && BLI_exists(U.tempdir)) {
+ strcpy(fullname, U.tempdir);
+ }
+
+
+#ifdef WIN32
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TEMP"); /* Windows */
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+#else
+ /* Other OS's - Try TMP and TMPDIR */
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TMP");
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TMPDIR");
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+#endif
+
+ if (fullname[0] == '\0') {
+ strcpy(fullname, "/tmp/");
+ } else {
+ /* add a trailing slash if needed */
+ BLI_add_slash(fullname);
+ }
+}
+
/*
* returns absolute path to the app bundle
* only useful on OS X
@@ -1491,13 +1734,45 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) {
return 0;
}
-void BLI_timestr(double time, char *str)
+
+#ifdef WITH_ICONV
+#include "iconv.h"
+#include "localcharset.h"
+
+void BLI_string_to_utf8(char *original, char *utf_8, char *code)
+{
+ size_t inbytesleft=strlen(original);
+ size_t outbytesleft=512;
+ size_t rv=0;
+ iconv_t cd;
+
+ if (NULL == code) {
+ code = locale_charset();
+ }
+ cd=iconv_open("UTF-8", code);
+
+ if (cd == (iconv_t)(-1)) {
+ printf("iconv_open Error");
+ *utf_8='\0';
+ return ;
+ }
+ rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
+ if (rv == (size_t) -1) {
+ printf("iconv Error\n");
+ return ;
+ }
+ *utf_8 = '\0';
+ iconv_close(cd);
+}
+#endif // WITH_ICONV
+
+void BLI_timestr(double _time, char *str)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- int hr= ((int) time) / (60*60);
- int min= ( ((int) time) / 60 ) % 60;
- int sec= ((int) (time)) % 60;
- int hun= ((int) (time * 100.0)) % 100;
+ int hr= ( (int) _time) / (60*60);
+ int min= (((int) _time) / 60 ) % 60;
+ int sec= ( (int) (_time)) % 60;
+ int hun= ( (int) (_time * 100.0)) % 100;
if (hr) {
sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun);
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 7f621410a4f..09edfe90d02 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -38,12 +38,15 @@ extern "C" {
#endif
struct SpaceFile;
+struct SpaceImaSel;
+struct FileList;
struct LinkNode;
struct Main;
struct UserDef;
struct bScreen;
struct Scene;
struct MemFile;
+struct direntry;
typedef struct BlendHandle BlendHandle;
@@ -192,6 +195,21 @@ BLO_blendhandle_get_datablock_names(
int ofblocktype);
/**
+ * Gets the previews of all the datablocks in a file
+ * of a certain type (ie. All the scene names in
+ * a file).
+ *
+ * @param bh The blendhandle to access.
+ * @param ofblocktype The type of names to get.
+ * @return A BLI_linklist of PreviewImage. The PreviewImage links
+ * should be freed with malloc.
+ */
+ struct LinkNode*
+BLO_blendhandle_get_previews(
+ BlendHandle *bh,
+ int ofblocktype);
+
+/**
* Gets the names of all the datablock groups in a
* file. (ie. file contains Scene, Mesh, and Lamp
* datablocks).
@@ -219,6 +237,7 @@ BLO_blendhandle_close(
char *BLO_gethome(void);
int BLO_has_bfile_extension(char *str);
void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode);
+void BLO_library_append_(BlendHandle **libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode);
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
diff --git a/source/blender/blenloader/intern/Makefile b/source/blender/blenloader/intern/Makefile
index 86ccd607d63..4fcb0e8db47 100644
--- a/source/blender/blenloader/intern/Makefile
+++ b/source/blender/blenloader/intern/Makefile
@@ -38,10 +38,6 @@ include nan_compile.mk
# CFLAGS += $(LEVEL_2_C_WARNINGS)
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
# OpenGL and Python
CPPFLAGS += $(OGL_CPPFLAGS)
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 5f67c060c04..ef287428a19 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -50,6 +50,7 @@
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_ID.h"
+#include "DNA_material_types.h"
#include "BKE_utildefines.h" // for ENDB
@@ -61,6 +62,7 @@
#include "BLO_undofile.h"
#include "readfile.h"
+#include "genfile.h"
#include "BLO_readblenfile.h"
@@ -218,6 +220,70 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
return names;
}
+LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype)
+{
+ FileData *fd= (FileData*) bh;
+ LinkNode *previews= NULL;
+ BHead *bhead;
+ int looking=0;
+ int npreviews = 0;
+ PreviewImage* prv = NULL;
+ PreviewImage* new_prv = NULL;
+
+ for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
+ if (bhead->code==ofblocktype) {
+ ID *id= (ID*) (bhead+1);
+ if ( (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) {
+ new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
+ BLI_linklist_prepend(&previews, new_prv);
+ looking = 1;
+ }
+ } else if (bhead->code==DATA) {
+ if (looking) {
+ if (bhead->SDNAnr == dna_findstruct_nr(fd->filesdna, "PreviewImage") ) {
+ prv = (PreviewImage*) (bhead+1);
+ npreviews = 0;
+ memcpy(new_prv, prv, sizeof(PreviewImage));
+ if (prv->rect[0]) {
+ unsigned int *rect = NULL;
+ int rectlen = 0;
+ new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
+ bhead= blo_nextbhead(fd, bhead);
+ rect = (unsigned int*)(bhead+1);
+ rectlen = new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int);
+ memcpy(new_prv->rect[0], rect, bhead->len);
+ } else {
+ new_prv->rect[0] = NULL;
+ }
+
+ if (prv->rect[1]) {
+ unsigned int *rect = NULL;
+ int rectlen = 0;
+ new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
+ bhead= blo_nextbhead(fd, bhead);
+ rect = (unsigned int*)(bhead+1);
+ rectlen = new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int);
+ memcpy(new_prv->rect[1], rect, bhead->len);
+ } else {
+ new_prv->rect[1] = NULL;
+ }
+ }
+ }
+ } else if (bhead->code==ENDB) {
+ break;
+ } else if (bhead->code==DATA) {
+ /* DATA blocks between IDBlock and Preview */
+ } else {
+ looking = 0;
+ new_prv = NULL;
+ prv = NULL;
+ }
+
+ }
+
+ return previews;
+}
+
LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
{
FileData *fd= (FileData*) bh;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1b595b1e3fc..4567da932ee 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -60,6 +60,7 @@
#include "DNA_actuator_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_color_types.h"
#include "DNA_controller_types.h"
#include "DNA_constraint_types.h"
@@ -86,6 +87,7 @@
#include "DNA_oops_types.h"
#include "DNA_object_force.h"
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
@@ -112,6 +114,8 @@
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_cloth.h"
+#include "BKE_colortools.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
@@ -121,6 +125,7 @@
#include "BKE_global.h" // for G
#include "BKE_group.h"
#include "BKE_image.h"
+#include "BKE_key.h" //void set_four_ipo
#include "BKE_lattice.h"
#include "BKE_library.h" // for wich_libbase
#include "BKE_main.h" // for Main
@@ -128,22 +133,23 @@
#include "BKE_modifier.h"
#include "BKE_node.h" // for tree type defines
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_property.h" // for get_property
#include "BKE_sca.h" // for init_actuator
#include "BKE_scene.h"
#include "BKE_softbody.h" // sbNew()
+#include "BKE_sculpt.h"
#include "BKE_texture.h" // for open_plugin_tex
#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
#include "BKE_idprop.h"
#include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
+#include "BIF_filelist.h" // badlevel too, where to move this? - elubie
#include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
#include "BLO_readfile.h"
#include "BLO_undofile.h"
#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory
-#include "multires.h"
-
#include "readfile.h"
#include "genfile.h"
@@ -474,7 +480,27 @@ static void cleanup_path(const char *relabase, char *name)
strcat(name, filename);
}
-static Main *blo_find_main(ListBase *mainlist, const char *name, const char *relabase)
+static void read_file_version(FileData *fd, Main *main)
+{
+ BHead *bhead;
+
+ for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
+ if (bhead->code==GLOB) {
+ FileGlobal *fg= read_struct(fd, bhead, "Global");
+ if(fg) {
+ main->subversionfile= fg->subversion;
+ main->minversionfile= fg->minversion;
+ main->minsubversionfile= fg->minsubversion;
+ MEM_freeN(fg);
+ }
+ else if (bhead->code==ENDB)
+ break;
+ }
+ }
+}
+
+
+static Main *blo_find_main(FileData *fd, ListBase *mainlist, const char *name, const char *relabase)
{
Main *m;
Library *lib;
@@ -503,6 +529,8 @@ static Main *blo_find_main(ListBase *mainlist, const char *name, const char *rel
m->curlib= lib;
+ read_file_version(fd, m);
+
if(G.f & G_DEBUG) printf("blo_find_main: added new lib %s\n", name);
return m;
}
@@ -699,8 +727,8 @@ BHead *blo_prevbhead(FileData *fd, BHead *thisblock)
BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
{
- BHeadN *new_bhead = 0;
- BHead *bhead = 0;
+ BHeadN *new_bhead = NULL;
+ BHead *bhead = NULL;
if (thisblock) {
// bhead is actually a sub part of BHeadN
@@ -723,26 +751,6 @@ BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
return(bhead);
}
-#if 0
-static void get_blender_subversion(FileData *fd)
-{
- BHead *bhead;
-
- for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
- if (bhead->code==GLOB) {
- FileGlobal *fg= read_struct(fd, bhead, "Global");
- fd->filesubversion= fg->subversion;
- fd->fileminversion= fg->minversion;
- fd->fileminsubversion= fg->minsubversion;
- MEM_freeN(fg);
- return;
- }
- else if (bhead->code==ENDB)
- break;
- }
-}
-#endif
-
static void decode_blender_header(FileData *fd)
{
char header[SIZEOFBLENDERHEADER], num[4];
@@ -850,6 +858,7 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
static unsigned int seek= 1<<30; /* the current position */
static unsigned int offset= 0; /* size of previous chunks */
static MemFileChunk *chunk=NULL;
+ unsigned int chunkoffset, readsize, totread;
if(size==0) return 0;
@@ -867,29 +876,39 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, int size)
}
if(chunk) {
- /* first check if it's on the end if current chunk */
- if( seek-offset == chunk->size) {
- offset+= chunk->size;
- chunk= chunk->next;
- }
-
- /* debug, should never happen */
- if(chunk==NULL) {
- printf("illegal read, chunk zero\n");
- return 0;
- }
- else if( (seek-offset)+size > chunk->size) {
- size= chunk->size - (seek-offset);
- printf("chunk too large, clipped to %d\n", size);
- }
-
- memcpy(buffer, chunk->buf + (seek-offset), size);
- filedata->seek += size;
- seek+= size;
-
- return (size);
+ totread= 0;
+
+ do {
+ /* first check if it's on the end if current chunk */
+ if(seek-offset == chunk->size) {
+ offset+= chunk->size;
+ chunk= chunk->next;
+ }
+
+ /* debug, should never happen */
+ if(chunk==NULL) {
+ printf("illegal read, chunk zero\n");
+ return 0;
+ }
+
+ chunkoffset= seek-offset;
+ readsize= size-totread;
+
+ /* data can be spread over multiple chunks, so clamp size
+ * to within this chunk, and then it will read further in
+ * the next chunk */
+ if(chunkoffset+readsize > chunk->size)
+ readsize= chunk->size-chunkoffset;
+
+ memcpy((char*)buffer+totread, chunk->buf+chunkoffset, readsize);
+ totread += readsize;
+ filedata->seek += readsize;
+ seek += readsize;
+ } while(totread < size);
+ return totread;
}
+
return 0;
}
@@ -1025,7 +1044,9 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->imamap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
-
+ if (fd->bheadmap)
+ MEM_freeN(fd->bheadmap);
+
MEM_freeN(fd);
}
}
@@ -1401,6 +1422,12 @@ static void direct_link_brush(FileData *fd, Brush *brush)
brush->mtex[a]= newdataadr(fd, brush->mtex[a]);
}
+static void direct_link_script(FileData *fd, Script *script)
+{
+ script->id.us = 1;
+ SCRIPT_SET_NULL(script)
+}
+
/* ************ READ CurveMapping *************** */
/* cuma itself has been read! */
@@ -1443,11 +1470,18 @@ static void lib_link_nodetree(FileData *fd, Main *main)
}
/* verify types for nodes and groups, all data has to be read */
-static void lib_verify_nodetree(Main *main)
+/* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
+ * typedefs*/
+static void lib_verify_nodetree(Main *main, int open)
{
Scene *sce;
Material *ma;
bNodeTree *ntree;
+
+ /* this crashes blender on undo/redo
+ if(open==1) {
+ reinit_nodesystem();
+ }*/
/* now create the own typeinfo structs an verify nodes */
/* here we still assume no groups in groups */
@@ -1484,6 +1518,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
link_list(fd, &ntree->nodes);
for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type == NODE_DYNAMIC) {
+ node->custom1= 0;
+ node->custom1= BSET(node->custom1, NODE_DYNAMIC_LOADED);
+ node->typeinfo= NULL;
+ }
+
node->storage= newdataadr(fd, node->storage);
if(node->storage) {
@@ -1518,6 +1558,22 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
link->tosock= newdataadr(fd, link->tosock);
}
+ /* set selin and selout */
+ for(node= ntree->nodes.first; node; node= node->next) {
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ntree->selin= sock;
+ break;
+ }
+ }
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ if(sock->flag & SOCK_SEL) {
+ ntree->selout= sock;
+ break;
+ }
+ }
+ }
+
/* type verification is in lib-link */
}
@@ -1541,7 +1597,12 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
PreviewImage *prv= newdataadr(fd, old_prv);
if (prv) {
- prv->rect = newdataadr(fd, prv->rect);
+ int i;
+ for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+ if (prv->rect[i]) {
+ prv->rect[i] = newdataadr(fd, prv->rect[i]);
+ }
+ }
}
return prv;
@@ -1609,8 +1670,22 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
if(con->data==NULL) {
con->type= CONSTRAINT_TYPE_NULL;
}
-
+ /* own ipo, all constraints have it */
+ con->ipo= newlibadr_us(fd, id->lib, con->ipo);
+
switch (con->type) {
+ case CONSTRAINT_TYPE_PYTHON:
+ {
+ bPythonConstraint *data= (bPythonConstraint*)con->data;
+ bConstraintTarget *ct;
+
+ for (ct= data->targets.first; ct; ct= ct->next)
+ ct->tar = newlibadr(fd, id->lib, ct->tar);
+
+ data->text = newlibadr(fd, id->lib, data->text);
+ //IDP_LibLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
+ break;
case CONSTRAINT_TYPE_ACTION:
{
bActionConstraint *data;
@@ -1624,27 +1699,28 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
bLocateLikeConstraint *data;
data= ((bLocateLikeConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_ROTLIKE:
{
bRotateLikeConstraint *data;
data= ((bRotateLikeConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_SIZELIKE:
{
bSizeLikeConstraint *data;
data= ((bSizeLikeConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data;
data = ((bKinematicConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
+ data->poletar = newlibadr(fd, id->lib, data->poletar);
}
break;
case CONSTRAINT_TYPE_TRACKTO:
@@ -1666,44 +1742,57 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
bLockTrackConstraint *data;
data= ((bLockTrackConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_FOLLOWPATH:
{
bFollowPathConstraint *data;
data= ((bFollowPathConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
- break;
- case CONSTRAINT_TYPE_DISTANCELIMIT:
- {
- bDistanceLimitConstraint *data;
- data= ((bDistanceLimitConstraint*)con->data);
- data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
data= ((bStretchToConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
{
bRigidBodyJointConstraint *data;
data= ((bRigidBodyJointConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
break;
case CONSTRAINT_TYPE_CLAMPTO:
{
bClampToConstraint *data;
data= ((bClampToConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
- };
+ }
+ break;
+ case CONSTRAINT_TYPE_CHILDOF:
+ {
+ bChildOfConstraint *data;
+ data= ((bChildOfConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ bTransformConstraint *data;
+ data= ((bTransformConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data;
+ data= ((bDistLimitConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
break;
-
case CONSTRAINT_TYPE_NULL:
break;
}
@@ -1717,6 +1806,13 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
link_list(fd, lb);
for (cons=lb->first; cons; cons=cons->next) {
cons->data = newdataadr(fd, cons->data);
+
+ if (cons->type == CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data= cons->data;
+ link_list(fd, &data->targets);
+ data->prop = newdataadr(fd, data->prop);
+ IDP_DirectLinkProperty(data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
}
}
@@ -1777,12 +1873,12 @@ static void lib_link_action(FileData *fd, Main *main)
while(act) {
if(act->id.flag & LIB_NEEDLINK) {
act->id.flag -= LIB_NEEDLINK;
-
+
for (chan=act->chanbase.first; chan; chan=chan->next) {
chan->ipo= newlibadr_us(fd, act->id.lib, chan->ipo);
lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
}
-
+
}
act= act->id.next;
}
@@ -1805,12 +1901,24 @@ static void direct_link_bones(FileData *fd, Bone* bone)
static void direct_link_action(FileData *fd, bAction *act)
{
bActionChannel *achan;
+ bActionGroup *agrp;
link_list(fd, &act->chanbase);
+ link_list(fd, &act->groups);
+ link_list(fd, &act->markers);
- for (achan = act->chanbase.first; achan; achan=achan->next)
+ for (achan = act->chanbase.first; achan; achan=achan->next) {
+ achan->grp= newdataadr(fd, achan->grp);
+
link_list(fd, &achan->constraintChannels);
-
+ }
+
+ for (agrp = act->groups.first; agrp; agrp= agrp->next) {
+ if (agrp->channels.first) {
+ agrp->channels.first= newdataadr(fd, agrp->channels.first);
+ agrp->channels.last= newdataadr(fd, agrp->channels.last);
+ }
+ }
}
static void direct_link_armature(FileData *fd, bArmature *arm)
@@ -1837,7 +1945,9 @@ static void lib_link_camera(FileData *fd, Main *main)
if(ca->id.flag & LIB_NEEDLINK) {
ca->ipo= newlibadr_us(fd, ca->id.lib, ca->ipo);
-
+
+ ca->dof_ob= newlibadr_us(fd, ca->id.lib, ca->dof_ob);
+
lib_link_scriptlink(fd, &ca->id, &ca->scriptlink);
ca->id.flag -= LIB_NEEDLINK;
@@ -1891,6 +2001,12 @@ static void direct_link_lamp(FileData *fd, Lamp *la)
for(a=0; a<MAX_MTEX; a++) {
la->mtex[a]= newdataadr(fd, la->mtex[a]);
}
+
+ la->curfalloff= newdataadr(fd, la->curfalloff);
+ if(la->curfalloff)
+ direct_link_curvemapping(fd, la->curfalloff);
+
+ la->preview = direct_link_preview_image(fd, la->preview);
}
/* ************ READ keys ***************** */
@@ -2038,6 +2154,7 @@ static void direct_link_world(FileData *fd, World *wrld)
for(a=0; a<MAX_MTEX; a++) {
wrld->mtex[a]= newdataadr(fd, wrld->mtex[a]);
}
+ wrld->preview = direct_link_preview_image(fd, wrld->preview);
}
@@ -2347,6 +2464,8 @@ static void direct_link_texture(FileData *fd, Tex *tex)
memset(tex->env->cube, 0, 6*sizeof(void *));
tex->env->ok= 0;
}
+ tex->preview = direct_link_preview_image(fd, tex->preview);
+
tex->iuser.ok= 1;
}
@@ -2404,6 +2523,86 @@ static void direct_link_material(FileData *fd, Material *ma)
ma->nodetree= newdataadr(fd, ma->nodetree);
if(ma->nodetree)
direct_link_nodetree(fd, ma->nodetree);
+
+ ma->preview = direct_link_preview_image(fd, ma->preview);
+}
+
+/* ************ READ PARTICLE SETTINGS ***************** */
+
+static void lib_link_particlesettings(FileData *fd, Main *main)
+{
+ ParticleSettings *part;
+
+ part= main->particle.first;
+ while(part) {
+ if(part->id.flag & LIB_NEEDLINK) {
+ part->ipo= newlibadr_us(fd, part->id.lib, part->ipo);
+ part->dup_ob = newlibadr(fd, part->id.lib, part->dup_ob);
+ 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);
+ part->id.flag -= LIB_NEEDLINK;
+ }
+ part= part->id.next;
+ }
+}
+
+static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
+{
+ part->pd= newdataadr(fd, part->pd);
+}
+
+static void lib_link_particlesystems(FileData *fd, ID *id, ListBase *particles)
+{
+ ParticleSystem *psys;
+ int a;
+
+ for(psys=particles->first; psys; psys=psys->next){
+ ParticleData *pa;
+ psys->part = newlibadr_us(fd, id->lib, psys->part);
+ psys->target_ob = newlibadr(fd, id->lib, psys->target_ob);
+ psys->keyed_ob = newlibadr(fd, id->lib, psys->keyed_ob);
+
+ for(a=0,pa=psys->particles; a<psys->totpart; a++,pa++){
+ pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
+ }
+ }
+}
+static void direct_link_particlesystems(FileData *fd, ListBase *particles)
+{
+ ParticleSystem *psys;
+ int a;
+
+ for(psys=particles->first; psys; psys=psys->next) {
+ psys->particles=newdataadr(fd,psys->particles);
+ if(psys->particles && psys->particles->hair){
+ ParticleData *pa = psys->particles;
+ for(a=0; a<psys->totpart; a++, pa++)
+ pa->hair=newdataadr(fd,pa->hair);
+ }
+ if(psys->particles && psys->particles->keys){
+ ParticleData *pa = psys->particles;
+ for(a=0; a<psys->totpart; a++, pa++)
+ pa->keys=newdataadr(fd,pa->keys);
+ }
+ psys->child=newdataadr(fd,psys->child);
+ psys->effectors.first=psys->effectors.last=0;
+
+ psys->soft= newdataadr(fd, psys->soft);
+ if(psys->soft) {
+ SoftBody *sb = psys->soft;
+ sb->particles = psys;
+ sb->bpoint= NULL; // init pointers so it gets rebuilt nicely
+ sb->bspring= NULL;
+ sb->scratch= NULL;
+ }
+
+ psys->edit = 0;
+ psys->pathcache = 0;
+ psys->childcache = 0;
+ psys->reactevents.first = psys->reactevents.last = 0;
+ }
+ return;
}
/* ************ READ MESH ***************** */
@@ -2530,8 +2729,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
mesh->bb= NULL;
- mesh->oc= 0;
- mesh->mselect= NULL;
+ mesh->mselect = NULL;
/* Multires data */
mesh->mr= newdataadr(fd, mesh->mr);
@@ -2562,9 +2760,9 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
lvl->faces= newdataadr(fd, lvl->faces);
lvl->edges= newdataadr(fd, lvl->edges);
lvl->colfaces= newdataadr(fd, lvl->colfaces);
-
- /* Recalculating the maps is faster than reading them from the file */
- multires_calc_level_maps(lvl);
+ lvl->edge_boundary_states= NULL;
+ lvl->vert_face_map = lvl->vert_edge_map = NULL;
+ lvl->map_mem= NULL;
}
}
@@ -2645,6 +2843,7 @@ static void lib_link_object(FileData *fd, Main *main)
ob->track= newlibadr(fd, ob->id.lib, ob->track);
ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo);
ob->action = newlibadr_us(fd, ob->id.lib, ob->action);
+ ob->poselib= newlibadr_us(fd, ob->id.lib, ob->poselib);
ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group);
ob->proxy= newlibadr_us(fd, ob->id.lib, ob->proxy);
@@ -2673,8 +2872,7 @@ static void lib_link_object(FileData *fd, Main *main)
else printf("Object %s lost data.", ob->id.name+2);
if(ob->pose) {
- free_pose_channels(ob->pose);
- MEM_freeN(ob->pose);
+ free_pose(ob->pose);
ob->pose= NULL;
ob->flag &= ~OB_POSEMODE;
}
@@ -2780,14 +2978,24 @@ static void lib_link_object(FileData *fd, Main *main)
bMessageActuator *ma= act->data;
ma->toObject= newlibadr(fd, ob->id.lib, ma->toObject);
}
+ else if(act->type==ACT_2DFILTER){
+ bTwoDFilterActuator *_2dfa = act->data;
+ _2dfa->text= newlibadr(fd, ob->id.lib, _2dfa->text);
+ }
act= act->next;
}
if(ob->fluidsimSettings) {
ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
}
+
+ /* texture field */
+ if(ob->pd)
+ if(ob->pd->tex)
+ ob->pd->tex=newlibadr_us(fd, ob->id.lib, ob->pd->tex);
lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
+ lib_link_particlesystems(fd, &ob->id, &ob->particlesystem);
lib_link_modifiers(fd, ob);
}
ob= ob->id.next;
@@ -2805,6 +3013,7 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
return;
link_list(fd, &pose->chanbase);
+ link_list(fd, &pose->agroups);
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
pchan->bone= NULL;
@@ -2814,7 +3023,6 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
pchan->iktree.first= pchan->iktree.last= NULL;
pchan->path= NULL;
}
-
}
static void direct_link_modifiers(FileData *fd, ListBase *lb)
@@ -2834,7 +3042,49 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
SubsurfModifierData *smd = (SubsurfModifierData*) md;
smd->emCache = smd->mCache = 0;
- } else if (md->type==eModifierType_Hook) {
+ }
+ else if (md->type==eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ clmd->clothObject = NULL;
+
+ clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
+ clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
+
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+
+ if(clmd->sim_parms->presets > 10)
+ clmd->sim_parms->presets = 0;
+
+ }
+ else if (md->type==eModifierType_Collision) {
+
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+ /*
+ // TODO: CollisionModifier should use pointcache
+ // + have proper reset events before enabling this
+ collmd->x = newdataadr(fd, collmd->x);
+ collmd->xnew = newdataadr(fd, collmd->xnew);
+ collmd->mfaces = newdataadr(fd, collmd->mfaces);
+
+ collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x");
+ collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew");
+ collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v");
+ */
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time = -1;
+ collmd->numverts = 0;
+ collmd->tree = NULL;
+ collmd->mfaces = NULL;
+
+ }
+ else if (md->type==eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData*) md;
hmd->indexar= newdataadr(fd, hmd->indexar);
@@ -2844,6 +3094,39 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
SWITCH_INT(hmd->indexar[a]);
}
}
+ } else if (md->type==eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData*) md;
+
+ psmd->dm=0;
+ psmd->psys=newdataadr(fd, psmd->psys);
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ } else if (md->type==eModifierType_Explode) {
+ ExplodeModifierData *psmd = (ExplodeModifierData*) md;
+
+ psmd->facepa=0;
+ }
+ else if (md->type==eModifierType_MeshDeform) {
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ mmd->bindweights= newdataadr(fd, mmd->bindweights);
+ mmd->bindcos= newdataadr(fd, mmd->bindcos);
+ mmd->dyngrid= newdataadr(fd, mmd->dyngrid);
+ mmd->dyninfluences= newdataadr(fd, mmd->dyninfluences);
+ mmd->dynverts= newdataadr(fd, mmd->dynverts);
+
+ if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ int a;
+
+ if(mmd->bindweights)
+ for(a=0; a<mmd->totcagevert*mmd->totvert; a++)
+ SWITCH_INT(mmd->bindweights[a])
+ if(mmd->bindcos)
+ for(a=0; a<mmd->totcagevert*3; a++)
+ SWITCH_INT(mmd->bindcos[a])
+ if(mmd->dynverts)
+ for(a=0; a<mmd->totvert; a++)
+ SWITCH_INT(mmd->dynverts[a])
+ }
}
}
}
@@ -2946,8 +3229,8 @@ static void direct_link_object(FileData *fd, Object *ob)
sb->bpoint= NULL; // init pointers so it gets rebuilt nicely
sb->bspring= NULL;
sb->scratch= NULL;
-
-
+ /* although not used anymore */
+ /* still have to be loaded to be compatible with old files */
sb->keys= newdataadr(fd, sb->keys);
test_pointer_array(fd, (void **)&sb->keys);
if(sb->keys) {
@@ -2964,6 +3247,9 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->fluidsimSettings->meshBB = NULL;
ob->fluidsimSettings->meshSurfNormals = NULL;
}
+
+ link_list(fd, &ob->particlesystem);
+ direct_link_particlesystems(fd,&ob->particlesystem);
link_list(fd, &ob->prop);
prop= ob->prop.first;
@@ -3137,7 +3423,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
Editing *ed;
Sequence *seq;
MetaStack *ms;
- StripElem *se;
int a;
sce->theDag = NULL;
@@ -3157,6 +3442,12 @@ static void direct_link_scene(FileData *fd, Scene *sce)
/* SculptData textures */
for(a=0; a<MAX_MTEX; ++a)
sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
+ /* Sculpt intensity curve */
+ sce->sculptdata.cumap= newdataadr(fd, sce->sculptdata.cumap);
+ if(sce->sculptdata.cumap)
+ direct_link_curvemapping(fd, sce->sculptdata.cumap);
+ else
+ sculpt_reset_curve(&sce->sculptdata);
if(sce->ed) {
ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase;
@@ -3173,8 +3464,6 @@ static void direct_link_scene(FileData *fd, Scene *sce)
/* a patch: after introduction of effects with 3 input strips */
if(seq->seq3==0) seq->seq3= seq->seq2;
- seq->curelem= 0;
-
seq->plugin= newdataadr(fd, seq->plugin);
seq->effectdata= newdataadr(fd, seq->effectdata);
@@ -3185,59 +3474,45 @@ static void direct_link_scene(FileData *fd, Scene *sce)
seq->strip= newdataadr(fd, seq->strip);
if(seq->strip && seq->strip->done==0) {
seq->strip->done= 1;
-
- /* standard: strips from effects/metas are not written, but are mallocced */
-
- if(seq->type==SEQ_IMAGE) {
- seq->strip->stripdata= newdataadr(fd, seq->strip->stripdata);
- se= seq->strip->stripdata;
- if(se) {
- for(a=0; a<seq->strip->len; a++, se++) {
- se->ok= 1;
- se->ibuf= 0;
- }
- }
+ seq->strip->tstripdata = 0;
+ seq->strip->tstripdata_startstill = 0;
+ seq->strip->tstripdata_endstill = 0;
+ seq->strip->ibuf_startstill = 0;
+ seq->strip->ibuf_endstill = 0;
+
+ if(seq->type == SEQ_IMAGE ||
+ seq->type == SEQ_MOVIE ||
+ seq->type == SEQ_RAM_SOUND ||
+ seq->type == SEQ_HD_SOUND) {
+ seq->strip->stripdata = newdataadr(
+ fd, seq->strip->stripdata);
+ } else {
+ seq->strip->stripdata = 0;
}
- else if(seq->type==SEQ_MOVIE) {
- /* only first stripelem is in file */
- se= newdataadr(fd, seq->strip->stripdata);
-
- if(se) {
- seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- *seq->strip->stripdata= *se;
- MEM_freeN(se);
-
- se= seq->strip->stripdata;
-
- for(a=0; a<seq->strip->len; a++, se++) {
- se->ok= 1;
- se->ibuf= 0;
- se->nr= a + 1;
- }
- }
+ if (seq->flag & SEQ_USE_CROP) {
+ seq->strip->crop = newdataadr(
+ fd, seq->strip->crop);
+ } else {
+ seq->strip->crop = 0;
}
- else if(seq->type==SEQ_RAM_SOUND
- || seq->type == SEQ_HD_SOUND) {
- /* only first stripelem is in file */
- se= newdataadr(fd, seq->strip->stripdata);
-
- if(se) {
- seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- *seq->strip->stripdata= *se;
- MEM_freeN(se);
-
- se= seq->strip->stripdata;
-
- for(a=0; a<seq->strip->len; a++, se++) {
- se->ok= 2; /* why? */
- se->ibuf= 0;
- se->nr= a + 1;
- }
- }
+ if (seq->flag & SEQ_USE_TRANSFORM) {
+ seq->strip->transform = newdataadr(
+ fd, seq->strip->transform);
+ } else {
+ seq->strip->transform = 0;
+ }
+ if (seq->flag & SEQ_USE_PROXY) {
+ seq->strip->proxy = newdataadr(
+ fd, seq->strip->proxy);
+ } else {
+ seq->strip->proxy = 0;
+ }
+ if (seq->flag & SEQ_USE_COLOR_BALANCE) {
+ seq->strip->color_balance = newdataadr(
+ fd, seq->strip->color_balance);
+ } else {
+ seq->strip->color_balance = 0;
}
- else if(seq->len>0)
- seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-
}
}
END_SEQ
@@ -3296,6 +3571,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
link_list(fd, &(sce->markers));
+ link_list(fd, &(sce->transform_spaces));
link_list(fd, &(sce->r.layers));
sce->nodetree= newdataadr(fd, sce->nodetree);
@@ -3429,7 +3705,13 @@ static void lib_link_screen(FileData *fd, Main *main)
sfile->pupmenu= NULL;
}
else if(sl->spacetype==SPACE_IMASEL) {
- check_imasel_copy((SpaceImaSel *)sl);
+ SpaceImaSel *simasel= (SpaceImaSel *)sl;
+
+ simasel->files = NULL;
+ simasel->returnfunc= NULL;
+ simasel->menup= NULL;
+ simasel->pupmenu= NULL;
+ simasel->img= NULL;
}
else if(sl->spacetype==SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)sl;
@@ -3450,9 +3732,15 @@ static void lib_link_screen(FileData *fd, Main *main)
}
else if(sl->spacetype==SPACE_SCRIPT) {
- SpaceScript *sc= (SpaceScript *)sl;
- sc->script = NULL;
+ SpaceScript *scpt= (SpaceScript *)sl;
+ /*scpt->script = NULL; - 2.45 set to null, better re-run the script */
+ if (scpt->script) {
+ scpt->script= newlibadr(fd, sc->id.lib, scpt->script);
+ if (scpt->script) {
+ SCRIPT_SET_NULL(scpt->script)
+ }
+ }
}
else if(sl->spacetype==SPACE_OOPS) {
SpaceOops *so= (SpaceOops *)sl;
@@ -3599,7 +3887,10 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
sfile->libfiledata= 0;
}
else if(sl->spacetype==SPACE_IMASEL) {
- ;
+ SpaceImaSel *simasel= (SpaceImaSel *)sl;
+ if (simasel->files) {
+ BIF_filelist_freelib(simasel->files);
+ }
}
else if(sl->spacetype==SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)sl;
@@ -3620,9 +3911,14 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
if(st->text==NULL) st->text= newmain->text.first;
}
else if(sl->spacetype==SPACE_SCRIPT) {
- SpaceScript *sc= (SpaceScript *)sl;
-
- sc->script = NULL;
+ SpaceScript *scpt= (SpaceScript *)sl;
+
+ scpt->script= restore_pointer_by_name(newmain, (ID *)scpt->script, 1);
+
+ /*sc->script = NULL; - 2.45 set to null, better re-run the script */
+ if (scpt->script) {
+ SCRIPT_SET_NULL(scpt->script)
+ }
}
else if(sl->spacetype==SPACE_OOPS) {
SpaceOops *so= (SpaceOops *)sl;
@@ -3757,8 +4053,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sima->cumap= newdataadr(fd, sima->cumap);
if(sima->cumap)
direct_link_curvemapping(fd, sima->cumap);
- sima->info_str= sima->info_spare= NULL;
- sima->spare= NULL;
sima->iuser.ok= 1;
}
else if(sl->spacetype==SPACE_NODE) {
@@ -3825,11 +4119,26 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
static void lib_link_library(FileData *fd, Main *main)
{
Library *lib;
-
- lib= main->library.first;
- while(lib) {
+ for(lib= main->library.first; lib; lib= lib->id.next) {
lib->id.us= 1;
- lib= lib->id.next;
+ }
+}
+
+/* Always call this once you havbe loaded new library data to set the relative paths correctly in relation to the blend file */
+static void fix_relpaths_library(const char *basepath, Main *main)
+{
+ Library *lib;
+ /* BLO_read_from_memory uses a blank filename */
+ if (basepath==NULL || basepath[0] == '\0')
+ return;
+
+ for(lib= main->library.first; lib; lib= lib->id.next) {
+ /* Libraries store both relative and abs paths, recreate relative paths,
+ * relative to the blend file since indirectly linked libs will be relative to their direct linked library */
+ if (strncmp(lib->name, "//", 2)==0) { /* if this is relative to begin with? */
+ strncpy(lib->name, lib->filename, sizeof(lib->name));
+ BLI_makestringcode(basepath, lib->name);
+ }
}
}
@@ -3927,6 +4236,7 @@ static char *dataname(short id_code)
case ID_SO: return "Data from SO";
case ID_NT: return "Data from NT";
case ID_BR: return "Data from BR";
+ case ID_PA: return "Data from PA";
}
return "Data from Lib Block";
@@ -4063,12 +4373,20 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
case ID_BR:
direct_link_brush(fd, (Brush*)id);
break;
+ case ID_PA:
+ direct_link_particlesettings(fd, (ParticleSettings*)id);
+ break;
+ case ID_SCRIPT:
+ direct_link_script(fd, (Script*)id);
+ break;
}
/*link direct data of ID properties*/
if (id->properties) {
id->properties = newdataadr(fd, id->properties);
- IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ if (id->properties) { /* this case means the data was written incorrectly, it should not happen */
+ IDP_DirectLinkProperty(id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
}
oldnewmap_free_unused(fd->datamap);
@@ -4364,6 +4682,69 @@ static void do_version_ntree_242_2(bNodeTree *ntree)
}
}
+static void ntree_version_245(FileData *fd, Library *lib, bNodeTree *ntree)
+{
+ bNode *node;
+ NodeTwoFloats *ntf;
+ ID *nodeid;
+ Image *image;
+ ImageUser *iuser;
+
+ if(ntree->type==NTREE_COMPOSIT) {
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type == CMP_NODE_ALPHAOVER) {
+ if(!node->storage) {
+ ntf= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
+ node->storage= ntf;
+ if(node->custom1)
+ ntf->x= 1.0f;
+ }
+ }
+
+ /* fix for temporary flag changes during 245 cycle */
+ nodeid= newlibadr(fd, lib, node->id);
+ if(node->storage && nodeid && GS(nodeid->name) == ID_IM) {
+ image= (Image*)nodeid;
+ iuser= node->storage;
+ if(iuser->flag & IMA_OLD_PREMUL) {
+ iuser->flag &= ~IMA_OLD_PREMUL;
+ iuser->flag |= IMA_DO_PREMUL;
+ }
+ if(iuser->flag & IMA_DO_PREMUL) {
+ image->flag &= ~IMA_OLD_PREMUL;
+ image->flag |= IMA_DO_PREMUL;
+ }
+ }
+ }
+ }
+}
+
+void idproperties_fix_groups_lengths_recurse(IDProperty *prop)
+{
+ IDProperty *loop;
+ int i;
+
+ for (loop=prop->data.group.first, i=0; loop; loop=loop->next, i++) {
+ if (loop->type == IDP_GROUP) idproperties_fix_groups_lengths_recurse(loop);
+ }
+
+ if (prop->len != i) {
+ printf("Found and fixed bad id property group length.\n");
+ prop->len = i;
+ }
+}
+
+void idproperties_fix_group_lengths(ListBase idlist)
+{
+ ID *id;
+
+ for (id=idlist.first; id; id=id->next) {
+ if (id->properties) {
+ idproperties_fix_groups_lengths_recurse(id->properties);
+ }
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -5209,7 +5590,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (ob->track){
bConstraint *con;
+ bConstraintTypeInfo *cti;
bTrackToConstraint *data;
+ void *cdata;
list = &ob->constraints;
if (list)
@@ -5220,9 +5603,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
con->flag |= CONSTRAINT_EXPAND;
con->enforce=1.0F;
con->type = CONSTRAINT_TYPE_TRACKTO;
- data = (bTrackToConstraint *)
- new_constraint_data(CONSTRAINT_TYPE_TRACKTO);
-
+
+ cti= get_constraint_typeinfo(CONSTRAINT_TYPE_TRACKTO);
+ cdata= MEM_callocN(cti->size, cti->structName);
+ cti->new_data(cdata);
+ data = (bTrackToConstraint *)cdata;
+
data->tar = ob->track;
data->reserved1 = ob->trackflag;
data->reserved2 = ob->upflag;
@@ -5231,7 +5617,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
ob->track = 0;
}
-
+
ob = ob->id.next;
}
@@ -6021,8 +6407,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if(arm->layer==0) arm->layer= 1;
}
for(sce= main->scene.first; sce; sce= sce->id.next) {
- bScreen *sc;
-
if(sce->jumpframe==0) sce->jumpframe= 10;
if(sce->audio.mixrate==0) sce->audio.mixrate= 44100;
@@ -6055,20 +6439,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sce->toolsettings->unwrapper = 1;
}
- /* enable uv editor local sticky by default */
- for (sc= main->screen.first; sc; sc= sc->id.next) {
- ScrArea *sa;
- for (sa= sc->areabase.first; sa; sa= sa->next) {
- SpaceLink *sl;
- for (sl= sa->spacedata.first; sl; sl= sl->next) {
- if(sl->spacetype==SPACE_IMAGE) {
- SpaceImage *sima= (SpaceImage*)sl;
- if(!(sima->flag & SI_STICKYUVS))
- sima->flag |= SI_LOCALSTICKY;
- }
- }
- }
- }
if(sce->r.mode & R_PANORAMA) {
/* all these checks to ensure saved files with cvs version keep working... */
if(sce->r.xsch < sce->r.ysch) {
@@ -6462,35 +6832,707 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Mesh *me;
for(me=main->mesh.first; me; me=me->id.next)
customdata_version_243(me);
- }
+ }
+
}
+
if(main->versionfile <= 244) {
Scene *sce;
-
+ bScreen *sc;
+ Lamp *la;
+ World *wrld;
+
if(main->versionfile != 244 || main->subversionfile < 2) {
- Mesh *me;
for(sce= main->scene.first; sce; sce= sce->id.next)
sce->r.mode |= R_SSS;
- /* Copy over old per-level multires vertex data
- into a single vertex array in struct Multires */
+ /* correct older action editors - incorrect scrolling */
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
+ ScrArea *sa;
+ sa= sc->areabase.first;
+ while(sa) {
+ SpaceLink *sl;
+
+ for (sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_ACTION) {
+ SpaceAction *saction= (SpaceAction*) sl;
+
+ saction->v2d.tot.ymin= -1000.0;
+ saction->v2d.tot.ymax= 0.0;
+
+ saction->v2d.cur.ymin= -75.0;
+ saction->v2d.cur.ymax= 5.0;
+ }
+ }
+ sa = sa->next;
+ }
+ }
+ }
+ if (main->versionfile != 244 || main->subversionfile < 3) {
+ /* constraints recode version patch used to be here. Moved to 245 now... */
+
+
+ for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
+ if (wrld->mode & WO_AMB_OCC)
+ wrld->ao_samp_method = WO_AOSAMP_CONSTANT;
+ else
+ wrld->ao_samp_method = WO_AOSAMP_HAMMERSLEY;
+
+ wrld->ao_adapt_thresh = 0.005f;
+ }
+
+ for(la=main->lamp.first; la; la= la->id.next) {
+ if (la->type == LA_AREA)
+ la->ray_samp_method = LA_SAMP_CONSTANT;
+ else
+ la->ray_samp_method = LA_SAMP_HALTON;
+
+ la->adapt_thresh = 0.001;
+ }
+ }
+ }
+ if(main->versionfile <= 245) {
+ Scene *sce;
+ bScreen *sc;
+ Object *ob;
+ Image *ima;
+ Lamp *la;
+ Material *ma;
+ ParticleSettings *part;
+ World *wrld;
+ Mesh *me;
+ bNodeTree *ntree;
+ Tex *tex;
+
+ /* unless the file was created 2.44.3 but not 2.45, update the constraints */
+ if ( !(main->versionfile==244 && main->subversionfile==3) &&
+ ((main->versionfile<245) || (main->versionfile==245 && main->subversionfile==0)) )
+ {
+ for (ob = main->object.first; ob; ob= ob->id.next) {
+ ListBase *list;
+ list = &ob->constraints;
+
+ /* fix up constraints due to constraint recode changes (originally at 2.44.3) */
+ if (list) {
+ bConstraint *curcon;
+ for (curcon = list->first; curcon; curcon=curcon->next) {
+ /* old CONSTRAINT_LOCAL check -> convert to CONSTRAINT_SPACE_LOCAL */
+ if (curcon->flag & 0x20) {
+ curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+ curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+ }
+
+ switch (curcon->type) {
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ {
+ bLocLimitConstraint *data= (bLocLimitConstraint *)curcon->data;
+
+ /* old limit without parent option for objects */
+ if (data->flag2)
+ curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+ }
+ break;
+ }
+ }
+ }
+
+ /* correctly initialise constinv matrix */
+ Mat4One(ob->constinv);
+
+ if (ob->type == OB_ARMATURE) {
+ if (ob->pose) {
+ bConstraint *curcon;
+ bPoseChannel *pchan;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ /* make sure constraints are all up to date */
+ for (curcon = pchan->constraints.first; curcon; curcon=curcon->next) {
+ /* old CONSTRAINT_LOCAL check -> convert to CONSTRAINT_SPACE_LOCAL */
+ if (curcon->flag & 0x20) {
+ curcon->ownspace = CONSTRAINT_SPACE_LOCAL;
+ curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+ }
+
+ switch (curcon->type) {
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data= (bActionConstraint *)curcon->data;
+
+ /* 'data->local' used to mean that target was in local-space */
+ if (data->local)
+ curcon->tarspace = CONSTRAINT_SPACE_LOCAL;
+ }
+ break;
+ }
+ }
+
+ /* correctly initialise constinv matrix */
+ Mat4One(pchan->constinv);
+ }
+ }
+ }
+ }
+ }
+
+ /* fix all versions before 2.45 */
+ if (main->versionfile != 245) {
+
+ /* repair preview from 242 - 244*/
+ for(ima= main->image.first; ima; ima= ima->id.next) {
+ ima->preview = NULL;
+ }
- for(me = main->mesh.first; me; me=me->id.next) {
- if(me->mr) {
- MultiresLevel *lvl = me->mr->levels.last;
- if(lvl) {
- me->mr->verts = lvl->verts;
+ /* repair imasel space - completely reworked */
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
+ ScrArea *sa;
+ sa= sc->areabase.first;
+ while(sa) {
+ SpaceLink *sl;
+
+ for (sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_IMASEL) {
+ SpaceImaSel *simasel= (SpaceImaSel*) sl;
+ simasel->blockscale= 0.7;
+ /* view 2D */
+ simasel->v2d.tot.xmin= -10.0;
+ simasel->v2d.tot.ymin= -10.0;
+ simasel->v2d.tot.xmax= (float)sa->winx + 10.0f;
+ simasel->v2d.tot.ymax= (float)sa->winy + 10.0f;
+ simasel->v2d.cur.xmin= 0.0;
+ simasel->v2d.cur.ymin= 0.0;
+ simasel->v2d.cur.xmax= (float)sa->winx;
+ simasel->v2d.cur.ymax= (float)sa->winy;
+ simasel->v2d.min[0]= 1.0;
+ simasel->v2d.min[1]= 1.0;
+ simasel->v2d.max[0]= 32000.0f;
+ simasel->v2d.max[1]= 32000.0f;
+ simasel->v2d.minzoom= 0.5f;
+ simasel->v2d.maxzoom= 1.21f;
+ simasel->v2d.scroll= 0;
+ simasel->v2d.keepaspect= 1;
+ simasel->v2d.keepzoom= 1;
+ simasel->v2d.keeptot= 0;
+ simasel->prv_h = 96;
+ simasel->prv_w = 96;
+ simasel->flag = 7; /* ??? elubie */
+ strcpy (simasel->dir, U.textudir); /* TON */
+ strcpy (simasel->file, "");
+
+ simasel->returnfunc = 0;
+ simasel->title[0] = 0;
+ }
+ }
+ sa = sa->next;
+ }
+ }
+ }
+
+ /* Copy over old per-level multires vertex data
+ into a single vertex array in struct Multires */
+ for(me = main->mesh.first; me; me=me->id.next) {
+ if(me->mr && !me->mr->verts) {
+ MultiresLevel *lvl = me->mr->levels.last;
+ if(lvl) {
+ me->mr->verts = lvl->verts;
+ lvl->verts = NULL;
+ /* Don't need the other vert arrays */
+ for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
+ MEM_freeN(lvl->verts);
lvl->verts = NULL;
- /* Don't need the other vert arrays */
- for(lvl = lvl->prev; lvl; lvl = lvl->prev) {
- MEM_freeN(lvl->verts);
- lvl->verts = NULL;
+ }
+ }
+ }
+ }
+
+ if (main->versionfile != 245 || main->subversionfile < 1) {
+ for(la=main->lamp.first; la; la= la->id.next) {
+ if (la->mode & LA_QUAD) la->falloff_type = LA_FALLOFF_SLIDERS;
+ else la->falloff_type = LA_FALLOFF_INVLINEAR;
+
+ if (la->curfalloff == NULL) {
+ la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
+ curvemapping_initialize(la->curfalloff);
+ }
+ }
+ }
+
+ for(ma=main->mat.first; ma; ma= ma->id.next) {
+ if(ma->samp_gloss_mir == 0) {
+ ma->gloss_mir = ma->gloss_tra= 1.0;
+ ma->aniso_gloss_mir = 1.0;
+ ma->samp_gloss_mir = ma->samp_gloss_tra= 18;
+ ma->adapt_thresh_mir = ma->adapt_thresh_tra = 0.005;
+ ma->dist_mir = 0.0;
+ ma->fadeto_mir = MA_RAYMIR_FADETOSKY;
+ }
+
+ if(ma->strand_min == 0.0f)
+ ma->strand_min= 1.0f;
+ }
+
+ for(part=main->particle.first; part; part=part->id.next) {
+ if(part->ren_child_nbr==0)
+ part->ren_child_nbr= part->child_nbr;
+
+ if(part->simplify_refsize==0) {
+ part->simplify_refsize= 1920;
+ part->simplify_rate= 1.0f;
+ part->simplify_transition= 0.1f;
+ part->simplify_viewport= 0.8f;
+ }
+ }
+
+ for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
+ if(wrld->ao_approx_error == 0.0f)
+ wrld->ao_approx_error= 0.25f;
+ }
+
+ for(sce= main->scene.first; sce; sce= sce->id.next) {
+ if(sce->nodetree)
+ ntree_version_245(fd, lib, sce->nodetree);
+
+ if(sce->r.simplify_shadowsamples == 0) {
+ sce->r.simplify_subsurf= 6;
+ sce->r.simplify_particles= 1.0f;
+ sce->r.simplify_shadowsamples= 16;
+ sce->r.simplify_aosss= 1.0f;
+ }
+
+ if(sce->r.cineongamma == 0) {
+ sce->r.cineonblack= 95;
+ sce->r.cineonwhite= 685;
+ sce->r.cineongamma= 1.7f;
+ }
+ }
+
+ for(ntree=main->nodetree.first; ntree; ntree= ntree->id.next)
+ ntree_version_245(fd, lib, ntree);
+
+ /* fix for temporary flag changes during 245 cycle */
+ for(ima= main->image.first; ima; ima= ima->id.next) {
+ if(ima->flag & IMA_OLD_PREMUL) {
+ ima->flag &= ~IMA_OLD_PREMUL;
+ ima->flag |= IMA_DO_PREMUL;
+ }
+ }
+
+ for(tex=main->tex.first; tex; tex=tex->id.next) {
+ if(tex->iuser.flag & IMA_OLD_PREMUL) {
+ tex->iuser.flag &= ~IMA_OLD_PREMUL;
+ tex->iuser.flag |= IMA_DO_PREMUL;
+
+ }
+
+ ima= newlibadr(fd, lib, tex->ima);
+ if(ima && (tex->iuser.flag & IMA_DO_PREMUL)) {
+ ima->flag &= ~IMA_OLD_PREMUL;
+ ima->flag |= IMA_DO_PREMUL;
+ }
+ }
+
+ if (main->versionfile < 245 || main->subversionfile < 12)
+ {
+ /* initialize skeleton generation toolsettings */
+ for(sce=main->scene.first; sce; sce = sce->id.next)
+ {
+ sce->toolsettings->skgen_resolution = 50;
+ sce->toolsettings->skgen_threshold_internal = 0.01f;
+ sce->toolsettings->skgen_threshold_external = 0.01f;
+ sce->toolsettings->skgen_angle_limit = 45.0f;
+ sce->toolsettings->skgen_length_ratio = 1.3f;
+ sce->toolsettings->skgen_length_limit = 1.5f;
+ sce->toolsettings->skgen_correlation_limit = 0.98f;
+ sce->toolsettings->skgen_symmetry_limit = 0.1f;
+ sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
+ sce->toolsettings->skgen_postpro_passes = 1;
+ sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_SUB_CORRELATION;
+ sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
+ sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
+ sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
+ }
+ }
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 2)) {
+ Image *ima;
+
+ /* initialize 1:1 Aspect */
+ for(ima= main->image.first; ima; ima= ima->id.next) {
+ ima->aspx = ima->aspy = 1.0f;
+ }
+
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 4)) {
+ bArmature *arm;
+ ModifierData *md;
+ Object *ob;
+
+ for(arm= main->armature.first; arm; arm= arm->id.next)
+ arm->deformflag |= ARM_DEF_B_BONE_REST;
+
+ for(ob = main->object.first; ob; ob= ob->id.next) {
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type==eModifierType_Armature)
+ ((ArmatureModifierData*)md)->deformflag |= ARM_DEF_B_BONE_REST;
+ }
+ }
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 5)) {
+ /* foreground color needs to be somthing other then black */
+ Scene *sce;
+ for(sce= main->scene.first; sce; sce=sce->id.next) {
+ sce->r.fg_stamp[0] = sce->r.fg_stamp[1] = sce->r.fg_stamp[2] = 0.8;
+ sce->r.fg_stamp[3] = 1.0; /* dont use text alpha yet */
+ sce->r.bg_stamp[3] = 0.25; /* make sure the background has full alpha */
+ }
+ }
+
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 6)) {
+ Scene *sce;
+ /* fix frs_sec_base */
+ for(sce= main->scene.first; sce; sce= sce->id.next) {
+ if (sce->r.frs_sec_base == 0) {
+ sce->r.frs_sec_base = 1;
+ }
+ }
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 7)) {
+ Object *ob;
+ bPoseChannel *pchan;
+ bConstraint *con;
+ bConstraintTarget *ct;
+
+ for (ob = main->object.first; ob; ob= ob->id.next) {
+ if (ob->pose) {
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ for (con=pchan->constraints.first; con; con=con->next) {
+ if (con->type == CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data= (bPythonConstraint *)con->data;
+ if (data->tar) {
+ /* version patching needs to be done */
+ ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
+
+ ct->tar = data->tar;
+ strcpy(ct->subtarget, data->subtarget);
+ ct->space = con->tarspace;
+
+ BLI_addtail(&data->targets, ct);
+ data->tarnum++;
+
+ /* clear old targets to avoid problems */
+ data->tar = NULL;
+ strcpy(data->subtarget, "");
+ }
+ }
+ else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
+ bLocateLikeConstraint *data= (bLocateLikeConstraint *)con->data;
+
+ /* new headtail functionality makes Bone-Tip function obsolete */
+ if (data->flag & LOCLIKE_TIP)
+ con->headtail = 1.0f;
}
}
}
}
+
+ for (con=ob->constraints.first; con; con=con->next) {
+ if (con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data= (bPythonConstraint *)con->data;
+ if (data->tar) {
+ /* version patching needs to be done */
+ ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
+
+ ct->tar = data->tar;
+ strcpy(ct->subtarget, data->subtarget);
+ ct->space = con->tarspace;
+
+ BLI_addtail(&data->targets, ct);
+ data->tarnum++;
+
+ /* clear old targets to avoid problems */
+ data->tar = NULL;
+ strcpy(data->subtarget, "");
+ }
+ }
+ else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
+ bLocateLikeConstraint *data= (bLocateLikeConstraint *)con->data;
+
+ /* new headtail functionality makes Bone-Tip function obsolete */
+ if (data->flag & LOCLIKE_TIP)
+ con->headtail = 1.0f;
+ }
+ }
+
+ if(ob->soft && ob->soft->keys) {
+ SoftBody *sb = ob->soft;
+ int k;
+
+ for(k=0; k<sb->totkey; k++) {
+ if(sb->keys[k])
+ MEM_freeN(sb->keys[k]);
+ }
+
+ MEM_freeN(sb->keys);
+
+ sb->keys = NULL;
+ sb->totkey = 0;
+ ob->softflag &= ~OB_SB_BAKESET;
+ }
+ }
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 8)) {
+ Scene *sce;
+ Object *ob;
+ PartEff *paf=0;
+
+ for(ob = main->object.first; ob; ob= ob->id.next) {
+ if(ob->soft && ob->soft->keys) {
+ SoftBody *sb = ob->soft;
+ int k;
+
+ for(k=0; k<sb->totkey; k++) {
+ if(sb->keys[k])
+ MEM_freeN(sb->keys[k]);
+ }
+
+ MEM_freeN(sb->keys);
+
+ sb->keys = NULL;
+ sb->totkey = 0;
+ ob->softflag &= ~OB_SB_BAKESET;
+ }
+
+ /* convert old particles to new system */
+ if((paf = give_parteff(ob))) {
+ ParticleSystem *psys;
+ ModifierData *md;
+ ParticleSystemModifierData *psmd;
+ ParticleSettings *part;
+
+ /* create new particle system */
+ psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+
+ part = psys->part = psys_new_settings("PSys", main);
+
+ /* needed for proper libdata lookup */
+ oldnewmap_insert(fd->libmap, psys->part, psys->part, 0);
+
+ part->id.us--;
+ part->id.flag |= (ob->id.flag & LIB_NEEDLINK);
+
+ psys->totpart=0;
+ psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+
+ BLI_addtail(&ob->particlesystem, psys);
+
+ md= modifier_new(eModifierType_ParticleSystem);
+ sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+ psmd= (ParticleSystemModifierData*) md;
+ psmd->psys=psys;
+ BLI_addtail(&ob->modifiers, md);
+
+ /* convert settings from old particle system */
+ /* general settings */
+ part->totpart = MIN2(paf->totpart, 100000);
+ part->sta = paf->sta;
+ part->end = paf->end;
+ part->lifetime = paf->lifetime;
+ part->randlife = paf->randlife;
+ psys->seed = paf->seed;
+ part->disp = paf->disp;
+ part->omat = paf->mat[0];
+ part->hair_step = paf->totkey;
+
+ part->eff_group = paf->group;
+
+ /* old system didn't interpolate between keypoints at render time */
+ part->draw_step = part->ren_step = 0;
+
+ /* physics */
+ part->normfac = paf->normfac * 25.0f;
+ part->obfac = paf->obfac;
+ part->randfac = paf->randfac * 25.0f;
+ part->dampfac = paf->damp;
+ VECCOPY(part->acc, paf->force);
+
+ /* flags */
+ if(paf->stype & PAF_VECT) {
+ if(paf->flag & PAF_STATIC) {
+ /* new hair lifetime is always 100.0f */
+ float fac = paf->lifetime / 100.0f;
+
+ part->draw_as = PART_DRAW_PATH;
+ part->type = PART_HAIR;
+ psys->recalc |= PSYS_RECALC_HAIR;
+
+ part->normfac *= fac;
+ part->randfac *= fac;
+ }
+ else {
+ part->draw_as = PART_DRAW_LINE;
+ part->draw |= PART_DRAW_VEL_LENGTH;
+ part->draw_line[1] = 0.04f;
+ }
+ }
+
+ part->rotmode = PART_ROT_VEL;
+
+ part->flag |= (paf->flag & PAF_BSPLINE) ? PART_HAIR_BSPLINE : 0;
+ part->flag |= (paf->flag & PAF_TRAND) ? PART_TRAND : 0;
+ part->flag |= (paf->flag & PAF_EDISTR) ? PART_EDISTR : 0;
+ part->flag |= (paf->flag & PAF_UNBORN) ? PART_UNBORN : 0;
+ part->flag |= (paf->flag & PAF_DIED) ? PART_DIED : 0;
+ part->from |= (paf->flag & PAF_FACE) ? PART_FROM_FACE : 0;
+ part->draw |= (paf->flag & PAF_SHOWE) ? PART_DRAW_EMITTER : 0;
+
+ psys->vgroup[PSYS_VG_DENSITY] = paf->vertgroup;
+ psys->vgroup[PSYS_VG_VEL] = paf->vertgroup_v;
+ psys->vgroup[PSYS_VG_LENGTH] = paf->vertgroup_v;
+
+ /* dupliobjects */
+ if(ob->transflag & OB_DUPLIVERTS) {
+ Object *dup = main->object.first;
+
+ for(; dup; dup= dup->id.next) {
+ if(ob == newlibadr(fd, lib, dup->parent)) {
+ part->dup_ob = dup;
+ ob->transflag |= OB_DUPLIPARTS;
+ ob->transflag &= ~OB_DUPLIVERTS;
+
+ part->draw_as = PART_DRAW_OB;
+ }
+ }
+ }
+
+ free_effects(&ob->effect);
+
+ printf("Old particle system converted to new system.\n");
+ }
+ }
+
+ for(sce= main->scene.first; sce; sce=sce->id.next) {
+ ParticleEditSettings *pset= &sce->toolsettings->particle;
+ int a;
+
+ if(pset->brush[0].size == 0) {
+ pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
+ pset->emitterdist= 0.25f;
+ pset->totrekey= 5;
+ pset->totaddkey= 5;
+ pset->brushtype= PE_BRUSH_NONE;
+
+ for(a=0; a<PE_TOT_BRUSH; a++) {
+ pset->brush[a].strength= 50;
+ pset->brush[a].size= 50;
+ pset->brush[a].step= 10;
+ }
+
+ pset->brush[PE_BRUSH_CUT].strength= 100;
+ }
+ }
+ }
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 9)) {
+ Material *ma;
+ int a;
+
+ for(ma=main->mat.first; ma; ma= ma->id.next)
+ if(ma->mode & MA_NORMAP_TANG)
+ for(a=0; a<MAX_MTEX; a++)
+ if(ma->mtex[a] && ma->mtex[a]->tex)
+ ma->mtex[a]->normapspace = MTEX_NSPACE_TANGENT;
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 10)) {
+ Object *ob;
+
+ /* dupliface scale */
+ for(ob= main->object.first; ob; ob= ob->id.next)
+ ob->dupfacesca = 1.0f;
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 11)) {
+ Object *ob;
+ bActionStrip *strip;
+
+ /* nla-strips - scale */
+ for (ob= main->object.first; ob; ob= ob->id.next) {
+ for (strip= ob->nlastrips.first; strip; strip= strip->next) {
+ float length, actlength, repeat;
+
+ if (strip->flag & ACTSTRIP_USESTRIDE)
+ repeat= 1.0f;
+ else
+ repeat= strip->repeat;
+
+ length = strip->end-strip->start;
+ if (length == 0.0f) length= 1.0f;
+ actlength = strip->actend-strip->actstart;
+
+ strip->scale = length / (repeat * actlength);
+ if (strip->scale == 0.0f) strip->scale= 1.0f;
+ }
+ if(ob->soft){
+ ob->soft->inpush = ob->soft->inspring;
+ ob->soft->shearstiff = 1.0f;
+ }
+ }
+ }
+
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 14)) {
+ Scene *sce= main->scene.first;
+ Sequence *seq;
+ Editing *ed;
+
+ while(sce) {
+ ed= sce->ed;
+ if(ed) {
+ WHILE_SEQ(&ed->seqbase) {
+ if (seq->blend_mode == 0) {
+ seq->blend_opacity = 100.0;
+ }
+ }
+ END_SEQ
+ }
+
+ sce= sce->id.next;
}
}
+
+ /*fix broken group lengths in id properties*/
+ if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 15)) {
+ idproperties_fix_group_lengths(main->scene);
+ idproperties_fix_group_lengths(main->library);
+ idproperties_fix_group_lengths(main->object);
+ idproperties_fix_group_lengths(main->mesh);
+ idproperties_fix_group_lengths(main->curve);
+ idproperties_fix_group_lengths(main->mball);
+ idproperties_fix_group_lengths(main->mat);
+ idproperties_fix_group_lengths(main->tex);
+ idproperties_fix_group_lengths(main->image);
+ idproperties_fix_group_lengths(main->wave);
+ idproperties_fix_group_lengths(main->latt);
+ idproperties_fix_group_lengths(main->lamp);
+ idproperties_fix_group_lengths(main->camera);
+ idproperties_fix_group_lengths(main->ipo);
+ idproperties_fix_group_lengths(main->key);
+ idproperties_fix_group_lengths(main->world);
+ idproperties_fix_group_lengths(main->screen);
+ idproperties_fix_group_lengths(main->script);
+ idproperties_fix_group_lengths(main->vfont);
+ idproperties_fix_group_lengths(main->text);
+ idproperties_fix_group_lengths(main->sound);
+ idproperties_fix_group_lengths(main->group);
+ idproperties_fix_group_lengths(main->armature);
+ idproperties_fix_group_lengths(main->action);
+ idproperties_fix_group_lengths(main->nodetree);
+ idproperties_fix_group_lengths(main->brush);
+ idproperties_fix_group_lengths(main->particle);
+ }
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
@@ -6525,6 +7567,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_screen_sequence_ipos(main);
lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */
lib_link_brush(fd, main);
+ lib_link_particlesettings(fd, main);
lib_link_mesh(fd, main); /* as last: tpage images with users at zero */
@@ -6604,13 +7647,14 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
/* do before read_libraries, but skip undo case */
// if(fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton)
do_versions(fd, NULL, bfd->main);
-
+
read_libraries(fd, &fd->mainlist);
blo_join_main(&fd->mainlist);
lib_link_all(fd, bfd->main);
- lib_verify_nodetree(bfd->main);
+ lib_verify_nodetree(bfd->main, 1);
+ fix_relpaths_library(fd->filename, bfd->main); /* make all relative paths, relative to the open blend file */
if(fg)
link_global(fd, bfd, fg); /* as last */
@@ -6623,6 +7667,43 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r)
/* ************* APPEND LIBRARY ************** */
+struct bheadsort {
+ BHead *bhead;
+ void *old;
+};
+
+static int verg_bheadsort(const void *v1, const void *v2)
+{
+ const struct bheadsort *x1=v1, *x2=v2;
+
+ if( x1->old > x2->old) return 1;
+ else if( x1->old < x2->old) return -1;
+ return 0;
+}
+
+static void sort_bhead_old_map(FileData *fd)
+{
+ BHead *bhead;
+ struct bheadsort *bhs;
+ int tot= 0;
+
+ for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
+ tot++;
+
+ fd->tot_bheadmap= tot;
+ if(tot==0) return;
+
+ bhs= fd->bheadmap= MEM_mallocN(tot*sizeof(struct bheadsort), "bheadsort");
+
+ for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead), bhs++) {
+ bhs->bhead= bhead;
+ bhs->old= bhead->old;
+ }
+
+ qsort(fd->bheadmap, tot, sizeof(struct bheadsort), verg_bheadsort);
+
+}
+
static BHead *find_previous_lib(FileData *fd, BHead *bhead)
{
for (; bhead; bhead= blo_prevbhead(fd, bhead))
@@ -6634,14 +7715,28 @@ static BHead *find_previous_lib(FileData *fd, BHead *bhead)
static BHead *find_bhead(FileData *fd, void *old)
{
+#if 0
BHead *bhead;
-
+#endif
+ struct bheadsort *bhs, bhs_s;
+
if (!old)
return NULL;
+ if (fd->bheadmap==NULL)
+ sort_bhead_old_map(fd);
+
+ bhs_s.old= old;
+ bhs= bsearch(&bhs_s, fd->bheadmap, fd->tot_bheadmap, sizeof(struct bheadsort), verg_bheadsort);
+
+ if(bhs)
+ return bhs->bhead;
+
+#if 0
for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead))
if (bhead->old==old)
return bhead;
+#endif
return NULL;
}
@@ -6682,7 +7777,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
if(bheadlib) {
Library *lib= read_struct(fd, bheadlib, "Library");
- Main *ptr= blo_find_main(&fd->mainlist, lib->name, fd->filename);
+ Main *ptr= blo_find_main(fd, &fd->mainlist, lib->name, fd->filename);
id= is_yet_read(fd, ptr, bhead);
@@ -6718,6 +7813,14 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
}
}
+static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part)
+{
+ expand_doit(fd, mainvar, part->dup_ob);
+ expand_doit(fd, mainvar, part->dup_group);
+ expand_doit(fd, mainvar, part->eff_group);
+ expand_doit(fd, mainvar, part->bb_ob);
+}
+
static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo)
{
IpoCurve *icu;
@@ -6884,7 +7987,24 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
bConstraint *curcon;
for (curcon=lb->first; curcon; curcon=curcon->next) {
+
+ if (curcon->ipo)
+ expand_doit(fd, mainvar, curcon->ipo);
+
switch (curcon->type) {
+ case CONSTRAINT_TYPE_NULL:
+ break;
+ case CONSTRAINT_TYPE_PYTHON:
+ {
+ bPythonConstraint *data = (bPythonConstraint*)curcon->data;
+ bConstraintTarget *ct;
+
+ for (ct= data->targets.first; ct; ct= ct->next)
+ expand_doit(fd, mainvar, ct->tar);
+
+ expand_doit(fd, mainvar, data->text);
+ }
+ break;
case CONSTRAINT_TYPE_ACTION:
{
bActionConstraint *data = (bActionConstraint*)curcon->data;
@@ -6896,75 +8016,86 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
{
bLocateLikeConstraint *data = (bLocateLikeConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_ROTLIKE:
{
bRotateLikeConstraint *data = (bRotateLikeConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_SIZELIKE:
{
bSizeLikeConstraint *data = (bSizeLikeConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data = (bKinematicConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
+ expand_doit(fd, mainvar, data->poletar);
}
+ break;
case CONSTRAINT_TYPE_TRACKTO:
{
bTrackToConstraint *data = (bTrackToConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_MINMAX:
{
bMinMaxConstraint *data = (bMinMaxConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_LOCKTRACK:
{
bLockTrackConstraint *data = (bLockTrackConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_FOLLOWPATH:
{
bFollowPathConstraint *data = (bFollowPathConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
- }
- case CONSTRAINT_TYPE_DISTANCELIMIT:
- {
- bDistanceLimitConstraint *data = (bDistanceLimitConstraint*)curcon->data;
- expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = (bStretchToConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
{
bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
+ break;
case CONSTRAINT_TYPE_CLAMPTO:
{
bClampToConstraint *data = (bClampToConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
- break;
}
- case CONSTRAINT_TYPE_NULL:
+ break;
+ case CONSTRAINT_TYPE_CHILDOF:
+ {
+ bChildOfConstraint *data = (bChildOfConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ bTransformConstraint *data = (bTransformConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
break;
default:
break;
@@ -7039,6 +8170,17 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
expand_doit(fd, mainvar, amd->curve_ob);
expand_doit(fd, mainvar, amd->offset_ob);
}
+ else if (md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ expand_doit(fd, mainvar, mmd->mirror_ob);
+ }
+ else if (md->type==eModifierType_Displace) {
+ DisplaceModifierData *dmd = (DisplaceModifierData*) md;
+
+ expand_doit(fd, mainvar, dmd->map_object);
+ expand_doit(fd, mainvar, dmd->texture);
+ }
}
static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
@@ -7053,6 +8195,7 @@ static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)
static void expand_object(FileData *fd, Main *mainvar, Object *ob)
{
ModifierData *md;
+ ParticleSystem *psys;
bSensor *sens;
bController *cont;
bActuator *act;
@@ -7064,6 +8207,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
expand_doit(fd, mainvar, ob->data);
expand_doit(fd, mainvar, ob->ipo);
expand_doit(fd, mainvar, ob->action);
+ expand_doit(fd, mainvar, ob->poselib);
for (md=ob->modifiers.first; md; md=md->next) {
expand_modifier(fd, mainvar, md);
@@ -7095,6 +8239,9 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
if(ob->proxy_group)
expand_doit(fd, mainvar, ob->proxy_group);
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ expand_doit(fd, mainvar, psys->part);
+
sens= ob->sensors.first;
while(sens) {
for(a=0; a<sens->totlinks; a++) {
@@ -7159,6 +8306,9 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
}
act= act->next;
}
+
+ if(ob->pd && ob->pd->tex)
+ expand_doit(fd, mainvar, ob->pd->tex);
expand_scriptlink(fd, mainvar, &ob->scriptlink);
}
@@ -7272,6 +8422,8 @@ static void expand_main(FileData *fd, Main *mainvar)
case ID_IP:
expand_ipo(fd, mainvar, (Ipo *)id);
break;
+ case ID_PA:
+ expand_particlesettings(fd, mainvar, (ParticleSettings *)id);
}
doit= 1;
@@ -7295,34 +8447,42 @@ static int object_in_any_scene(Object *ob)
}
/* when *lib set, it also does objects that were in the appended group */
-static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib)
+static void give_base_to_objects(Scene *sce, ListBase *lb, Library *lib, int is_group_append)
{
Object *ob;
Base *base;
/* give all objects which are LIB_INDIRECT a base, or for a group when *lib has been set */
for(ob= lb->first; ob; ob= ob->id.next) {
-
+
if( ob->id.flag & LIB_INDIRECT ) {
- int do_it= 0;
- if(ob->id.us==0)
- do_it= 1;
- else if(ob->id.us==1 && lib)
- if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0)
+ /* IF below is quite confusing!
+ if we are appending, but this object wasnt just added allong with a group,
+ then this is alredy used indirectly in the scene somewhere else and we didnt just append it.
+
+ (ob->id.flag & LIB_APPEND_TAG)==0 means that this is a newly appended object - Campbell */
+ if (is_group_append==0 || (ob->id.flag & LIB_APPEND_TAG)==0) {
+
+ int do_it= 0;
+
+ if(ob->id.us==0)
do_it= 1;
+ else if(ob->id.us==1 && lib)
+ if(ob->id.lib==lib && (ob->flag & OB_FROMGROUP) && object_in_any_scene(ob)==0)
+ do_it= 1;
+
+ if(do_it) {
+ base= MEM_callocN( sizeof(Base), "add_ext_base");
+ BLI_addtail(&(sce->base), base);
+ base->lay= ob->lay;
+ base->object= ob;
+ base->flag= ob->flag;
+ ob->id.us= 1;
- if(do_it) {
- base= MEM_callocN( sizeof(Base), "add_ext_base");
- BLI_addtail(&(sce->base), base);
- base->lay= ob->lay;
- base->object= ob;
- base->flag= ob->flag;
- ob->id.us= 1;
-
- ob->id.flag -= LIB_INDIRECT;
- ob->id.flag |= LIB_EXTERN;
-
+ ob->id.flag -= LIB_INDIRECT;
+ ob->id.flag |= LIB_EXTERN;
+ }
}
}
}
@@ -7411,8 +8571,8 @@ 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( Scene *scene, SpaceFile *sfile, char *dir, int idcode,
- int totsel, FileData *fd)
+static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
+ int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag)
{
Main *mainl;
Library *curlib;
@@ -7421,20 +8581,20 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
blo_split_main(&fd->mainlist, G.main);
/* which one do we need? */
- mainl = blo_find_main(&fd->mainlist, dir, G.sce);
+ mainl = blo_find_main(fd, &fd->mainlist, dir, G.sce);
mainl->versionfile= fd->fileversion; /* needed for do_version */
curlib= mainl->curlib;
if(totsel==0) {
- append_named_part(fd, mainl, scene, sfile->file, idcode, sfile->flag);
+ append_named_part(fd, mainl, scene, file, idcode, flag);
}
else {
int a;
- for(a=0; a<sfile->totfile; a++) {
- if(sfile->filelist[a].flags & ACTIVE) {
- append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag);
+ for(a=0; a<totfile; a++) {
+ if(filelist[a].flags & ACTIVE) {
+ append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag);
}
}
}
@@ -7445,7 +8605,7 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
/* do this when expand found other libs */
read_libraries(fd, &fd->mainlist);
- if(sfile->flag & FILE_STRINGCODE) {
+ if(flag & FILE_STRINGCODE) {
/* use the full path, this could have been read by other library even */
BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name));
@@ -7458,14 +8618,19 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
G.main= fd->mainlist.first;
lib_link_all(fd, G.main);
- lib_verify_nodetree(G.main);
+ lib_verify_nodetree(G.main, 0);
+ fix_relpaths_library(G.sce, G.main); /* make all relative paths, relative to the open blend file */
/* give a base to loose objects. If group append, do it for objects too */
- if(idcode==ID_GR)
- give_base_to_objects(scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
- else
- give_base_to_objects(scene, &(G.main->object), NULL);
-
+ if(idcode==ID_GR) {
+ if (flag & FILE_LINK) {
+ give_base_to_objects(scene, &(G.main->object), NULL, 0);
+ } else {
+ give_base_to_objects(scene, &(G.main->object), curlib, 1);
+ }
+ } else {
+ give_base_to_objects(scene, &(G.main->object), NULL, 0);
+ }
/* has been removed... erm, why? s..ton) */
/* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
/* 20041208: put back. It only linked direct, not indirect objects (ton) */
@@ -7473,8 +8638,7 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
/* patch to prevent switch_endian happens twice */
if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
blo_freefiledata( fd );
- sfile->libfiledata= 0;
- }
+ }
return curlib;
}
@@ -7487,16 +8651,8 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
int idcode, short flag, Scene *scene )
{
- SpaceFile sfile;
-
- /* build a minimal "fake" SpaceFile object */
- sfile.flag = flag;
- sfile.totfile = 0;
- strcpy(sfile.file, name);
-
/* try to append the requested object */
-
- library_append( scene, &sfile, dir, idcode, 0, (FileData *)bh );
+ library_append( scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag );
/* do we need to do this? */
DAG_scene_sort(G.scene);
@@ -7506,26 +8662,31 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
/* dir is a full path */
void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
{
- FileData *fd= (FileData*) sfile->libfiledata;
+ BLO_library_append_(&sfile->libfiledata, sfile->filelist, sfile->totfile, dir, sfile->file, sfile->flag, idcode);
+}
+
+void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode)
+{
+ FileData *fd= (FileData*) (*libfiledata);
Library *curlib;
Base *centerbase;
Object *ob;
int a, totsel=0;
/* are there files selected? */
- for(a=0; a<sfile->totfile; a++) {
- if(sfile->filelist[a].flags & ACTIVE) {
+ for(a=0; a<totfile; a++) {
+ if(filelist[a].flags & ACTIVE) {
totsel++;
}
}
if(totsel==0) {
/* is the indicated file in the filelist? */
- if(sfile->file[0]) {
- for(a=0; a<sfile->totfile; a++) {
- if( strcmp(sfile->filelist[a].relname, sfile->file)==0) break;
+ if(file[0]) {
+ for(a=0; a<totfile; a++) {
+ if( strcmp(filelist[a].relname, file)==0) break;
}
- if(a==sfile->totfile) {
+ if(a==totfile) {
error("Wrong indicated name");
return;
}
@@ -7537,13 +8698,18 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
}
/* now we have or selected, or an indicated file */
- if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
+ if(flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
- curlib = library_append( G.scene, sfile, dir, idcode, totsel, fd );
+ curlib = library_append( G.scene, file, dir, idcode, totsel, fd, filelist, totfile,flag );
+
+ /* patch to prevent switch_endian happens twice */
+ if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ (*libfiledata)= 0;
+ }
/* when not linking (appending)... */
- if((sfile->flag & FILE_LINK)==0) {
- if(sfile->flag & FILE_ATCURSOR) {
+ if((flag & FILE_LINK)==0) {
+ if(flag & FILE_ATCURSOR) {
float *curs, centerloc[3], vec[3], min[3], max[3];
int count= 0;
@@ -7629,6 +8795,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
mainptr->curlib->filedata= fd;
mainptr->versionfile= fd->fileversion;
+
+ /* subversion */
+ read_file_version(fd, mainptr);
}
else mainptr->curlib->filedata= NULL;
@@ -7710,10 +8879,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata);
mainptr->curlib->filedata= NULL;
-
}
}
+
/* reading runtime */
BlendFileData *blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r)
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index 79392023a56..d8644ca52f2 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -37,6 +37,7 @@
struct OldNewMap;
struct MemFile;
+struct bheadsort;
typedef struct FileData {
// linked list of BHeadN's
@@ -76,6 +77,9 @@ typedef struct FileData {
struct OldNewMap *libmap;
struct OldNewMap *imamap;
+ struct bheadsort *bheadmap;
+ int tot_bheadmap;
+
ListBase mainlist;
/* ick ick, used to return
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 9ab1321b45e..d70fe17c67f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -107,6 +107,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include "DNA_actuator_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_color_types.h"
#include "DNA_constraint_types.h"
#include "DNA_controller_types.h"
@@ -132,6 +133,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include "DNA_object_force.h"
#include "DNA_oops_types.h"
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_sdna_types.h"
@@ -154,6 +156,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include "BKE_action.h"
#include "BKE_bad_level_calls.h" // build_seqar (from WHILE_SEQ) free_oops error
#include "BKE_blender.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_constraint.h"
@@ -184,7 +187,10 @@ Important to know is that 'streaming' has been added to files, for Blender Publi
#include <errno.h>
-/* ********* my write, buffered writing with minimum 50k chunks ************ */
+/* ********* my write, buffered writing with minimum size chunks ************ */
+
+#define MYWRITE_BUFFER_SIZE 100000
+#define MYWRITE_MAX_CHUNK 32768
typedef struct {
struct SDNA *sdna;
@@ -213,7 +219,7 @@ static WriteData *writedata_new(int file)
wd->file= file;
- wd->buf= MEM_mallocN(100000, "wd->buf");
+ wd->buf= MEM_mallocN(MYWRITE_BUFFER_SIZE, "wd->buf");
return wd;
}
@@ -253,12 +259,13 @@ int mywfile;
* @warning Talks to other functions with global parameters
*/
-#define MYWRITE_FLUSH NULL
+#define MYWRITE_FLUSH NULL
static void mywrite( WriteData *wd, void *adr, int len)
{
if (wd->error) return;
+ /* flush helps compression for undo-save */
if(adr==MYWRITE_FLUSH) {
if(wd->count) {
writedata_do_write(wd, wd->buf, wd->count);
@@ -269,21 +276,33 @@ static void mywrite( WriteData *wd, void *adr, int len)
wd->tot+= len;
- if(len>50000) {
+ /* if we have a single big chunk, write existing data in
+ * buffer and write out big chunk in smaller pieces */
+ if(len>MYWRITE_MAX_CHUNK) {
if(wd->count) {
writedata_do_write(wd, wd->buf, wd->count);
wd->count= 0;
}
- writedata_do_write(wd, adr, len);
+
+ do {
+ int writelen= MIN2(len, MYWRITE_MAX_CHUNK);
+ writedata_do_write(wd, adr, writelen);
+ adr = (char*)adr + writelen;
+ len -= writelen;
+ } while(len > 0);
+
return;
}
- if(len+wd->count>99999) {
+
+ /* if data would overflow buffer, write out the buffer */
+ if(len+wd->count>MYWRITE_BUFFER_SIZE-1) {
writedata_do_write(wd, wd->buf, wd->count);
wd->count= 0;
}
+
+ /* append data at end of buffer */
memcpy(&wd->buf[wd->count], adr, len);
wd->count+= len;
-
}
/**
@@ -449,7 +468,7 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
writestruct(wd, DATA, "bNode", 1, node);
for(node= ntree->nodes.first; node; node= node->next) {
- if(node->storage) {
+ if(node->storage && node->type!=NODE_DYNAMIC) {
/* could be handlerized at some point, now only 1 exception still */
if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB))
write_curvemapping(wd, node->storage);
@@ -526,6 +545,50 @@ static void write_effects(WriteData *wd, ListBase *lb)
}
}
+static void write_particlesettings(WriteData *wd, ListBase *idbase)
+{
+ ParticleSettings *part;
+
+ part= idbase->first;
+ while(part) {
+ if(part->id.us>0 || wd->current) {
+ /* write LibData */
+ writestruct(wd, ID_PA, "ParticleSettings", 1, part);
+ writestruct(wd, DATA, "PartDeflect", 1, part->pd);
+ }
+ part= part->id.next;
+ }
+}
+static void write_particlesystems(WriteData *wd, ListBase *particles)
+{
+ ParticleSystem *psys= particles->first;
+ int a;
+
+ for(; psys; psys=psys->next) {
+ writestruct(wd, DATA, "ParticleSystem", 1, psys);
+
+ if(psys->particles) {
+ writestruct(wd, DATA, "ParticleData", psys->totpart ,psys->particles);
+
+ if(psys->particles->hair) {
+ ParticleData *pa = psys->particles;
+
+ for(a=0; a<psys->totpart; a++, pa++)
+ writestruct(wd, DATA, "HairKey", pa->totkey, pa->hair);
+ }
+
+ if(psys->particles->keys) {
+ ParticleData *pa = psys->particles;
+
+ for(a=0; a<psys->totpart; a++, pa++)
+ writestruct(wd, DATA, "ParticleKey", pa->totkey, pa->keys);
+ }
+ }
+ if(psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
+ writestruct(wd, DATA, "SoftBody", 1, psys->soft);
+ }
+}
+
static void write_properties(WriteData *wd, ListBase *lb)
{
bProperty *prop;
@@ -672,6 +735,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
case ACT_VISIBILITY:
writestruct(wd, DATA, "bVisibilityActuator", 1, act->data);
break;
+ case ACT_2DFILTER:
+ writestruct(wd, DATA, "bTwoDFilterActuator", 1, act->data);
+ break;
default:
; /* error: don't know how to write this file */
}
@@ -698,58 +764,32 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
bConstraint *con;
for (con=conlist->first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
/* Write the specific data */
- switch (con->type) {
- case CONSTRAINT_TYPE_NULL:
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- writestruct(wd, DATA, "bTrackToConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- writestruct(wd, DATA, "bKinematicConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- writestruct(wd, DATA, "bRotateLikeConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- writestruct(wd, DATA, "bLocateLikeConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- writestruct(wd, DATA, "bSizeLikeConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_ACTION:
- writestruct(wd, DATA, "bActionConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- writestruct(wd, DATA, "bLockTrackConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- writestruct(wd, DATA, "bStretchToConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_MINMAX:
- writestruct(wd, DATA, "bMinMaxConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
- writestruct(wd, DATA, "bLocLimitConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
- writestruct(wd, DATA, "bRotLimitConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- writestruct(wd, DATA, "bSizeLimitConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- writestruct(wd, DATA, "bRigidBodyJointConstraint", 1, con->data);
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- writestruct(wd, DATA, "bClampToConstraint", 1, con->data);
- break;
- default:
- break;
+ if (cti && con->data) {
+ /* firstly, just write the plain con->data struct */
+ writestruct(wd, DATA, cti->structName, 1, con->data);
+
+ /* do any constraint specific stuff */
+ switch (con->type) {
+ case CONSTRAINT_TYPE_PYTHON:
+ {
+ bPythonConstraint *data = (bPythonConstraint *)con->data;
+ bConstraintTarget *ct;
+
+ /* write targets */
+ for (ct= data->targets.first; ct; ct= ct->next)
+ writestruct(wd, DATA, "bConstraintTarget", 1, ct);
+
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ of library blocks that implement this.*/
+ IDP_WriteProperty(data->prop, wd);
+ }
+ break;
+ }
}
+
/* Write the constraint */
writestruct(wd, DATA, "bConstraint", 1, con);
}
@@ -757,21 +797,29 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
static void write_pose(WriteData *wd, bPose *pose)
{
- bPoseChannel *chan;
+ bPoseChannel *chan;
+ bActionGroup *grp;
/* Write each channel */
-
if (!pose)
return;
- // Write channels
+ /* Write channels */
for (chan=pose->chanbase.first; chan; chan=chan->next) {
write_constraints(wd, &chan->constraints);
- chan->selectflag= chan->bone->flag & (BONE_SELECTED|BONE_ACTIVE); // gets restored on read, for library armatures
+
+ /* prevent crashes with autosave, when a bone duplicated in editmode has not yet been assigned to its posechannel */
+ if (chan->bone)
+ chan->selectflag= chan->bone->flag & (BONE_SELECTED|BONE_ACTIVE); /* gets restored on read, for library armatures */
+
writestruct(wd, DATA, "bPoseChannel", 1, chan);
}
+
+ /* Write groups */
+ for (grp=pose->agroups.first; grp; grp=grp->next)
+ writestruct(wd, DATA, "bActionGroup", 1, grp);
- // Write this pose
+ /* Write this pose */
writestruct(wd, DATA, "bPose", 1, pose);
}
@@ -800,21 +848,50 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
for (md=modbase->first; md; md= md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (mti == NULL) return;
-
+
writestruct(wd, DATA, mti->structName, 1, md);
-
+
if (md->type==eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData*) md;
-
+
writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar);
}
+ else if(md->type==eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ writestruct(wd, DATA, "SimulationSettings", 1, clmd->sim_parms);
+ writestruct(wd, DATA, "CollisionSettings", 1, clmd->coll_parms);
+
+ }
+ else if (md->type==eModifierType_Collision) {
+
+ /*
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+ // TODO: CollisionModifier should use pointcache
+ // + have proper reset events before enabling this
+ writestruct(wd, DATA, "MVert", collmd->numverts, collmd->x);
+ writestruct(wd, DATA, "MVert", collmd->numverts, collmd->xnew);
+ writestruct(wd, DATA, "MFace", collmd->numfaces, collmd->mfaces);
+ */
+ }
+ else if (md->type==eModifierType_MeshDeform) {
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+ int size = mmd->dyngridsize;
+
+ writedata(wd, DATA, sizeof(float)*mmd->totvert*mmd->totcagevert,
+ mmd->bindweights);
+ writedata(wd, DATA, sizeof(float)*3*mmd->totcagevert,
+ mmd->bindcos);
+ writestruct(wd, DATA, "MDefCell", size*size*size, mmd->dyngrid);
+ writestruct(wd, DATA, "MDefInfluence", mmd->totinfluence, mmd->dyninfluences);
+ writedata(wd, DATA, sizeof(int)*mmd->totvert, mmd->dynverts);
+ }
}
}
static void write_objects(WriteData *wd, ListBase *idbase)
{
Object *ob;
- int a;
ob= idbase->first;
while(ob) {
@@ -850,17 +927,9 @@ 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) {
- SoftBody *sb= ob->soft;
- if(sb->keys) {
- writedata(wd, DATA, sizeof(void *)*sb->totkey, sb->keys);
- for(a=0; a<sb->totkey; a++) {
- writestruct(wd, DATA, "SBVertex", sb->totpoint, sb->keys[a]);
- }
- }
- }
writestruct(wd, DATA, "FluidsimSettings", 1, ob->fluidsimSettings); // NT
+ write_particlesystems(wd, &ob->particlesystem);
write_modifiers(wd, &ob->modifiers);
}
ob= ob->id.next;
@@ -1203,11 +1272,36 @@ static void write_lattices(WriteData *wd, ListBase *idbase)
}
}
+static void write_previews(WriteData *wd, PreviewImage *prv)
+{
+ if (prv) {
+ short w = prv->w[1];
+ short h = prv->h[1];
+ unsigned int *rect = prv->rect[1];
+ /* don't write out large previews if not requested */
+ if (!(U.flag & USER_SAVE_PREVIEWS) ) {
+ prv->w[1] = 0;
+ prv->h[1] = 0;
+ prv->rect[1] = NULL;
+ }
+ writestruct(wd, DATA, "PreviewImage", 1, prv);
+ if (prv->rect[0]) writedata(wd, DATA, prv->w[0]*prv->h[0]*sizeof(unsigned int), prv->rect[0]);
+ if (prv->rect[1]) writedata(wd, DATA, prv->w[1]*prv->h[1]*sizeof(unsigned int), prv->rect[1]);
+
+ /* restore preview, we still want to keep it in memory even if not saved to file */
+ if (!(U.flag & USER_SAVE_PREVIEWS) ) {
+ prv->w[1] = w;
+ prv->h[1] = h;
+ prv->rect[1] = rect;
+ }
+ }
+}
+
static void write_images(WriteData *wd, ListBase *idbase)
{
Image *ima;
PackedFile * pf;
- PreviewImage *prv;
+
ima= idbase->first;
while(ima) {
@@ -1222,12 +1316,9 @@ static void write_images(WriteData *wd, ListBase *idbase)
writedata(wd, DATA, pf->size, pf->data);
}
- if (ima->preview) {
- prv = ima->preview;
- writestruct(wd, DATA, "PreviewImage", 1, prv);
- writedata(wd, DATA, prv->w*prv->h*sizeof(unsigned int), prv->rect);
+ write_previews(wd, ima->preview);
+
}
- }
ima= ima->id.next;
}
/* flush helps the compression for undo-save */
@@ -1249,6 +1340,8 @@ static void write_textures(WriteData *wd, ListBase *idbase)
if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+
+ write_previews(wd, tex->preview);
}
tex= tex->id.next;
}
@@ -1288,6 +1381,8 @@ static void write_materials(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree);
write_nodetree(wd, ma->nodetree);
}
+
+ write_previews(wd, ma->preview);
}
ma= ma->id.next;
}
@@ -1310,6 +1405,9 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
}
write_scriptlink(wd, &wrld->scriptlink);
+
+ write_previews(wd, wrld->preview);
+
}
wrld= wrld->id.next;
}
@@ -1332,7 +1430,13 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
if(la->mtex[a]) writestruct(wd, DATA, "MTex", 1, la->mtex[a]);
}
+ if(la->curfalloff)
+ write_curvemapping(wd, la->curfalloff);
+
write_scriptlink(wd, &la->scriptlink);
+
+ write_previews(wd, la->preview);
+
}
la= la->id.next;
}
@@ -1348,6 +1452,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
MetaStack *ms;
Strip *strip;
TimeMarker *marker;
+ TransformOrientation *ts;
SceneRenderLayer *srl;
int a;
@@ -1369,6 +1474,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
for(a=0; a<MAX_MTEX; ++a)
writestruct(wd, DATA, "MTex", 1, sce->sculptdata.mtex[a]);
+ if(sce->sculptdata.cumap)
+ write_curvemapping(wd, sce->sculptdata.cumap);
ed= sce->ed;
if(ed) {
@@ -1408,7 +1515,18 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
strip= seq->strip;
writestruct(wd, DATA, "Strip", 1, strip);
-
+ if(seq->flag & SEQ_USE_CROP && strip->crop) {
+ writestruct(wd, DATA, "StripCrop", 1, strip->crop);
+ }
+ if(seq->flag & SEQ_USE_TRANSFORM && strip->transform) {
+ writestruct(wd, DATA, "StripTransform", 1, strip->transform);
+ }
+ if(seq->flag & SEQ_USE_PROXY && strip->proxy) {
+ writestruct(wd, DATA, "StripProxy", 1, strip->proxy);
+ }
+ if(seq->flag & SEQ_USE_COLOR_BALANCE && strip->color_balance) {
+ writestruct(wd, DATA, "StripColorBalance", 1, strip->color_balance);
+ }
if(seq->type==SEQ_IMAGE)
writestruct(wd, DATA, "StripElem", strip->len, strip->stripdata);
else if(seq->type==SEQ_MOVIE || seq->type==SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND)
@@ -1442,6 +1560,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
for(marker= sce->markers.first; marker; marker= marker->next)
writestruct(wd, DATA, "TimeMarker", 1, marker);
+ /* writing dynamic list of TransformOrientations to the blend file */
+ for(ts = sce->transform_spaces.first; ts; ts = ts->next)
+ writestruct(wd, DATA, "TransformOrientation", 1, ts);
+
for(srl= sce->r.layers.first; srl; srl= srl->next)
writestruct(wd, DATA, "SceneRenderLayer", 1, srl);
@@ -1563,6 +1685,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceText", 1, sl);
}
else if(sl->spacetype==SPACE_SCRIPT) {
+ SpaceScript *sc = (SpaceScript*)sl;
+ sc->but_refs = NULL;
writestruct(wd, DATA, "SpaceScript", 1, sl);
}
else if(sl->spacetype==SPACE_ACTION) {
@@ -1673,16 +1797,26 @@ static void write_actions(WriteData *wd, ListBase *idbase)
{
bAction *act;
bActionChannel *chan;
+ bActionGroup *grp;
+ TimeMarker *marker;
for(act=idbase->first; act; act= act->id.next) {
if (act->id.us>0 || wd->current) {
writestruct(wd, ID_AC, "bAction", 1, act);
if (act->id.properties) IDP_WriteProperty(act->id.properties, wd);
-
+
for (chan=act->chanbase.first; chan; chan=chan->next) {
writestruct(wd, DATA, "bActionChannel", 1, chan);
write_constraint_channels(wd, &chan->constraintChannels);
}
+
+ for (grp=act->groups.first; grp; grp=grp->next) {
+ writestruct(wd, DATA, "bActionGroup", 1, grp);
+ }
+
+ for (marker=act->markers.first; marker; marker=marker->next) {
+ writestruct(wd, DATA, "TimeMarker", 1, marker);
+ }
}
}
}
@@ -1731,7 +1865,7 @@ static void write_sounds(WriteData *wd, ListBase *idbase)
// set all samples to unsaved status
- sample = samples->first;
+ sample = samples->first; // samples is a global defined in sound.c
while (sample) {
sample->flags |= SAMPLE_NEEDS_SAVE;
sample = sample->id.next;
@@ -1821,6 +1955,18 @@ static void write_brushes(WriteData *wd, ListBase *idbase)
}
}
+static void write_scripts(WriteData *wd, ListBase *idbase)
+{
+ Script *script;
+
+ for(script=idbase->first; script; script= script->id.next) {
+ if(script->id.us>0 || wd->current) {
+ writestruct(wd, ID_SCRIPT, "Script", 1, script);
+ if (script->id.properties) IDP_WriteProperty(script->id.properties, wd);
+ }
+ }
+}
+
static void write_global(WriteData *wd)
{
FileGlobal fg;
@@ -1883,8 +2029,10 @@ static int write_file_handle(int handle, MemFile *compare, MemFile *current, int
write_materials(wd, &G.main->mat);
write_textures (wd, &G.main->tex);
write_meshs (wd, &G.main->mesh);
+ write_particlesettings(wd, &G.main->particle);
write_nodetrees(wd, &G.main->nodetree);
write_brushes (wd, &G.main->brush);
+ write_scripts (wd, &G.main->script);
if(current==NULL)
write_libraries(wd, G.main->next); /* no library save in undo */
diff --git a/source/blender/blenpluginapi/iff.h b/source/blender/blenpluginapi/iff.h
index 8e5b538eda6..5eb52158a1a 100644
--- a/source/blender/blenpluginapi/iff.h
+++ b/source/blender/blenpluginapi/iff.h
@@ -208,6 +208,8 @@ LIBEXPORT void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf,
int destx, int desty, int srcx, int srcy, int width, int height);
LIBEXPORT void IMB_rectfill(struct ImBuf *drect, float col[4]);
+LIBEXPORT void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
+LIBEXPORT void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, float *col, int x1, int y1, int x2, int y2);
#endif /* IFF_H */
diff --git a/source/blender/blenpluginapi/intern/Makefile b/source/blender/blenpluginapi/intern/Makefile
index 00052d36cfd..e493ea40aa5 100644
--- a/source/blender/blenpluginapi/intern/Makefile
+++ b/source/blender/blenpluginapi/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris"))
CFLAGS += -shared
endif
diff --git a/source/blender/ftfont/CMakeLists.txt b/source/blender/ftfont/CMakeLists.txt
index 6587fcd7582..7b89416bbe1 100644
--- a/source/blender/ftfont/CMakeLists.txt
+++ b/source/blender/ftfont/CMakeLists.txt
@@ -30,7 +30,7 @@
FILE(GLOB SRC intern/*.cpp)
SET(INC
- . intern ../blenkernel ../blenlib ../makesdna
+ . intern ../blenkernel ../blenlib ../makesdna ../include
${FTGL_INC}
${FREETYPE_INC}
${GETTEXT_INC}
diff --git a/source/blender/ftfont/FTF_Api.h b/source/blender/ftfont/FTF_Api.h
index 15fa55c905d..0793c4b6dfb 100644
--- a/source/blender/ftfont/FTF_Api.h
+++ b/source/blender/ftfont/FTF_Api.h
@@ -106,12 +106,12 @@ FTF_EXPORT float FTF_GetStringWidth(char* str, unsigned int flag);
/**
* Get Bounding Box
- * @param llx
- * @param lly
- * @param llz
- * @param urx
- * @param ury
- * @param urz
+ * @param llx Lower left near x coord
+ * @param lly Lower left near y coord
+ * @param llz Lower left near z coord
+ * @param urx Upper right far x coord
+ * @param ury Upper right far y coord
+ * @param urz Upper right far z coord
* @param mode flag to forward to FTF_TransConvString()
* not test yet.
*/
@@ -154,6 +154,10 @@ FTF_EXPORT void FTF_SetScale(float fsize);
FTF_EXPORT void FTF_End(void);
+/* Font preview functions */
+FTF_EXPORT int FTF_GetNewFont (const unsigned char *str, int datasize, int fontsize);
+FTF_EXPORT float FTF_DrawNewFontString(char* str, unsigned int flag);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/ftfont/SConscript b/source/blender/ftfont/SConscript
index cf6805d6bb3..615b274677c 100644
--- a/source/blender/ftfont/SConscript
+++ b/source/blender/ftfont/SConscript
@@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.cpp')
-incs = '. intern ../blenkernel ../blenlib ../makesdna'
+incs = '. intern ../blenkernel ../blenlib ../makesdna ../include'
incs += ' ' + env['BF_FTGL_INC']
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_GETTEXT_INC']
diff --git a/source/blender/ftfont/intern/FTF_Api.cpp b/source/blender/ftfont/intern/FTF_Api.cpp
index 52fc9378f00..bf6698a1cde 100644
--- a/source/blender/ftfont/intern/FTF_Api.cpp
+++ b/source/blender/ftfont/intern/FTF_Api.cpp
@@ -43,8 +43,18 @@
#include "../FTF_Api.h"
#include "FTF_TTFont.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+ #include "datatoc.h"
+#ifdef __cplusplus
+}
+#endif
+
#define FTF_EXPORT
+FTF_TTFont *newfont= 0; // preview font
+
static FTF_TTFont *_FTF_GetFont(void) {
static FTF_TTFont *theFont = NULL;
@@ -55,8 +65,28 @@ static FTF_TTFont *_FTF_GetFont(void) {
return theFont;
}
+FTF_EXPORT int FTF_GetNewFont (const unsigned char *str, int datasize, int fontsize) {
+
+ if (newfont) delete newfont;
+ newfont= new FTF_TTFont();
+
+ if (!(newfont->SetFont((unsigned char*)str, datasize, fontsize))) {
+ newfont->SetFont((unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size, fontsize);
+ return 0;
+ }
+ return 1;
+}
+
+FTF_EXPORT float FTF_DrawNewFontString(char* str, unsigned int flag)
+{
+ if (newfont)
+ return newfont->DrawString(str, flag);
+ return 0.0f;
+}
+
FTF_EXPORT void FTF_End(void) {
delete _FTF_GetFont();
+ delete newfont;
}
FTF_EXPORT void FTF_SetSize(int size)
@@ -174,3 +204,5 @@ FTF_EXPORT void FTF_SetScale(float fsize)
{
_FTF_GetFont()->SetScale(fsize);
}
+
+
diff --git a/source/blender/ftfont/intern/FTF_TTFont.cpp b/source/blender/ftfont/intern/FTF_TTFont.cpp
index a4d81fe0133..34b22e5c9d2 100644
--- a/source/blender/ftfont/intern/FTF_TTFont.cpp
+++ b/source/blender/ftfont/intern/FTF_TTFont.cpp
@@ -335,6 +335,8 @@ float FTF_TTFont::DrawString(char* str, unsigned int flag)
removes special characters completely. So, for now we just skip that then. (ton) */
if (FTF_USE_GETTEXT & flag)
utf8towchar(wstr, gettext(str));
+ else if (FTF_INPUT_UTF8 & flag)
+ utf8towchar(wstr, str);
glGetFloatv(GL_CURRENT_COLOR, color);
@@ -344,7 +346,7 @@ float FTF_TTFont::DrawString(char* str, unsigned int flag)
glPixelTransferf(GL_GREEN_SCALE, color[1]);
glPixelTransferf(GL_BLUE_SCALE, color[2]);
- if (FTF_USE_GETTEXT & flag)
+ if ((FTF_USE_GETTEXT | FTF_INPUT_UTF8) & flag)
font->Render(wstr);
else
font->Render(str);
@@ -362,7 +364,7 @@ float FTF_TTFont::DrawString(char* str, unsigned int flag)
glTranslatef(pen_x, pen_y, 0.0);
glScalef(fsize, fsize, 1.0);
- if (FTF_USE_GETTEXT & flag)
+ if ((FTF_USE_GETTEXT | FTF_INPUT_UTF8) & flag)
font->Render(wstr);
else
font->Render(str);
@@ -373,7 +375,7 @@ float FTF_TTFont::DrawString(char* str, unsigned int flag)
glDisable(GL_TEXTURE_2D);
}
- if (FTF_USE_GETTEXT & flag)
+ if ((FTF_USE_GETTEXT | FTF_INPUT_UTF8) & flag)
return font->Advance(wstr);
else
return font->Advance(str);
diff --git a/source/blender/ftfont/intern/FTF_TTFont.h b/source/blender/ftfont/intern/FTF_TTFont.h
index c4dee93c5dc..b5ff1cc54bf 100644
--- a/source/blender/ftfont/intern/FTF_TTFont.h
+++ b/source/blender/ftfont/intern/FTF_TTFont.h
@@ -78,6 +78,17 @@ public:
float GetStringWidth(char* str, unsigned int flag);
+ /**
+ * Get the bounding box for a string.
+ *
+ * @param str The string
+ * @param llx Lower left near x coord
+ * @param lly Lower left near y coord
+ * @param llz Lower left near z coord
+ * @param urx Upper right far x coord
+ * @param ury Upper right far y coord
+ * @param urz Upper right far z coord
+ */
void GetBoundingBox(char* str, float *llx, float *lly, float *llz, float *urx, float *ury, float *urz, unsigned int flag);
/**
diff --git a/source/blender/ftfont/intern/Makefile b/source/blender/ftfont/intern/Makefile
index d3a1977994b..4668241c5c8 100644
--- a/source/blender/ftfont/intern/Makefile
+++ b/source/blender/ftfont/intern/Makefile
@@ -36,20 +36,18 @@ DIR = $(OCGDIR)/blender/ftfont
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
#CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../include
CPPFLAGS += -I$(NAN_FTGL)/include
CPPFLAGS += -I$(NAN_FTGL)/include/FTGL
CPPFLAGS += -I$(NAN_GETTEXT)/include
CPPFLAGS += -I$(NAN_FREETYPE)/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
ifeq ($(OS), windows)
CPPFLAGS += -I$(NAN_ICONV)/include
ifeq ($(FREE_WINDOWS), true)
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index d6ca21830aa..7cbdfbe32d1 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -158,7 +158,7 @@ struct ImBuf *IMB_testiffname(char *naam,int flags);
*
* @attention Defined in readimage.c
*/
-struct ImBuf *IMB_loadiffname(char *naam, int flags);
+struct ImBuf *IMB_loadiffname(const char *naam, int flags);
/**
*
@@ -258,7 +258,7 @@ int IMB_anim_get_duration(struct anim *anim);
*
* @attention Defined in anim.c
*/
-struct anim * IMB_open_anim(char * name, int ib_flags);
+struct anim * IMB_open_anim(const char * name, int ib_flags);
void IMB_close_anim(struct anim * anim);
/**
@@ -280,6 +280,13 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position);
/**
*
* @attention Defined in anim.c
+ * fetches a define previewframe, usually half way into the movie
+ */
+struct ImBuf * IMB_anim_previewframe(struct anim * anim);
+
+/**
+ *
+ * @attention Defined in anim.c
*/
void IMB_free_anim_ibuf(struct anim * anim);
@@ -314,7 +321,7 @@ void IMB_antialias(struct ImBuf * ibuf);
*/
void IMB_filter(struct ImBuf *ibuf);
void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
-void IMB_filter_extend(struct ImBuf *ibuf);
+void IMB_filter_extend(struct ImBuf *ibuf, char *mask);
void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
/**
@@ -395,7 +402,13 @@ void IMB_float_from_rect(struct ImBuf *ibuf);
* @attention Defined in imageprocess.c
*/
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf);
-
+/**
+ *
+ * @attention defined in imageprocess.c
+ */
+void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float x, float y, int xout, int yout);
+void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
+void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
/**
* Change the ordering of the color bytes pointed to by rect from
* rgba to abgr. size * 4 color bytes are reordered.
@@ -511,6 +524,7 @@ extern float rgb_to_bw[4][4];
*
* @attention Defined in rotate.c
*/
+void IMB_flipx(struct ImBuf *ibuf);
void IMB_flipy(struct ImBuf * ibuf);
/**
@@ -531,6 +545,13 @@ void IMB_freezbuffloatImBuf(struct ImBuf * ibuf);
* @attention Defined in rectop.c
*/
void IMB_rectfill(struct ImBuf *drect, float col[4]);
+void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2);
+
+/* this should not be here, really, we needed it for operating on render data, IMB_rectfill_area calls it */
+void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, float *col, int x1, int y1, int x2, int y2);
+
+/* defined in imginfo.c */
+int IMB_imginfo_change_field(struct ImBuf *img, const char *key, const char *field);
/* exported for image tools in blender, to quickly allocate 32 bits rect */
short imb_addrectImBuf(struct ImBuf * ibuf);
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index f5487bb9ac0..a46fdf4af2d 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -56,6 +56,8 @@
struct _AviMovie;
struct Mdec;
+struct ImgInfo;
+
#define IB_MIPMAP_LEVELS 10
/**
@@ -93,7 +95,7 @@ typedef struct ImBuf {
int userflags; /**< Used to set imbuf to Dirty and other stuff */
int *zbuf; /**< z buffer data, original zbuffer */
float *zbuf_float; /**< z buffer data, camera coordinates */
- void *userdata;
+ void *userdata; /**< temporary storage, only used by baking at the moment */
unsigned char *encodedbuffer; /**< Compressed image only used with png currently */
unsigned int encodedsize; /**< Size of data written to encodedbuffer */
unsigned int encodedbuffersize; /**< Size of encodedbuffer */
@@ -103,6 +105,7 @@ typedef struct ImBuf {
float dither; /**< random dither value, for conversion from float -> byte rect */
struct MEM_CacheLimiterHandle_s * c_handle; /**< handle for cache limiter */
+ struct ImgInfo * img_info;
int refcounter; /**< Refcounter for multiple users */
int index; /**< reference index for ImBuf lists */
@@ -148,6 +151,7 @@ typedef enum {
#define IB_rectfloat (1 << 15)
#define IB_zbuffloat (1 << 16)
#define IB_multilayer (1 << 17)
+#define IB_imginfo (1 << 18)
/*
* The bit flag is stored in the ImBuf.ftype variable.
@@ -166,6 +170,7 @@ typedef enum {
#define RADHDR (1 << 24)
#define TIF (1 << 23)
+#define TIF_16BIT (1 << 8 )
#define OPENEXR (1 << 22)
#define OPENEXR_HALF (1 << 8 )
@@ -174,6 +179,10 @@ typedef enum {
#define CINEON (1 << 21)
#define DPX (1 << 20)
+#ifdef WITH_DDS
+#define DDS (1 << 19)
+#endif
+
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
@@ -216,6 +225,10 @@ typedef enum {
#define IS_tiff(x) (x->ftype & TIF)
#define IS_radhdr(x) (x->ftype & RADHDR)
+#ifdef WITH_DDS
+#define IS_dds(x) (x->ftype & DDS)
+#endif
+
#define IMAGIC 0732
#define IS_iris(x) (x->ftype == IMAGIC)
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
new file mode 100644
index 00000000000..4f4b77ff000
--- /dev/null
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -0,0 +1,74 @@
+/**
+ * $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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Andrea Weikert.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _IMB_THUMBS_H
+#define _IMB_THUMBS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ImBuf;
+
+/** Thumbnail creation and retrieval according to the 'Thumbnail Management Standard'
+ * supported by Gimp, Gnome (Nautilus), KDE etc.
+ * Reference: http://jens.triq.net/thumbnail-spec/index.html
+ */
+
+
+typedef enum ThumbSize {
+ THB_NORMAL,
+ THB_LARGE,
+ THB_FAIL
+} ThumbSize;
+
+typedef enum ThumbSource {
+ THB_SOURCE_IMAGE,
+ THB_SOURCE_MOVIE
+} ThumbSource;
+
+// IB_imginfo
+
+/* create thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, ThumbSource source);
+
+/* read thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_read(const char* dir, const char* file, ThumbSize size);
+
+/* delete all thumbs for the file */
+void IMB_thumb_delete(const char* dir, const char* file, ThumbSize size);
+
+/* return the state of the thumb, needed to determine how to manage the thumb */
+ImBuf* IMB_thumb_manage(const char* dir, const char* file, ThumbSize size, ThumbSource source);
+
+
+
+
+#endif /* _IMB_THUMBS_H */
+
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index 7d3503dfe2d..f9e46b20d9a 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -20,6 +20,9 @@ if env['WITH_BF_VERSE']:
if env['WITH_BF_OPENEXR'] == 1:
defs.append('WITH_OPENEXR')
+if env['WITH_BF_DDS'] == 1:
+ defs.append('WITH_DDS')
+
if env['WITH_BF_FFMPEG'] == 1:
defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC']
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 602b13df4ca..f3514a92ae4 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -81,6 +81,7 @@
#ifdef WITH_FFMPEG
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
+#include <ffmpeg/swscale.h>
#endif
#include "IMB_imbuf_types.h"
@@ -181,7 +182,8 @@ struct anim {
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrameRGB;
- AVFrame *pFrame;
+ AVFrame *pFrame;
+ struct SwsContext *img_convert_ctx;
int videoStream;
#endif
diff --git a/source/blender/imbuf/intern/IMB_imginfo.h b/source/blender/imbuf/intern/IMB_imginfo.h
new file mode 100644
index 00000000000..e82cc5f32af
--- /dev/null
+++ b/source/blender/imbuf/intern/IMB_imginfo.h
@@ -0,0 +1,85 @@
+/**
+ * $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) 2005 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Austin Benesh. Ton Roosendaal.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _IMB_IMGINFO_H
+#define _IMB_IMGINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ImBuf;
+
+typedef struct ImgInfo {
+ struct ImgInfo *next, *prev;
+ char* key;
+ char* value;
+ int len;
+} ImgInfo;
+
+/** The imginfo is a list of key/value pairs (both char*) that can me
+ saved in the header of several image formats.
+ Apart from some common keys like
+ 'Software' and 'Description' (png standard) we'll use keys within the
+ Blender namespace, so should be called 'Blender::StampInfo' or 'Blender::FrameNum'
+ etc...
+*/
+
+
+/* free blender ImgInfo struct */
+void IMB_imginfo_free(struct ImBuf* img);
+
+/** read the field from the image info into the field
+ * @param img - the ImBuf that contains the image data
+ * @param key - the key of the field
+ * @param value - the data in the field, first one found with key is returned,
+ memory has to be allocated by user.
+ * @param len - length of value buffer allocated by user.
+ * @return - 1 (true) if ImageInfo present and value for the key found, 0 (false) otherwise
+ */
+int IMB_imginfo_get_field(struct ImBuf* img, const char* key, char* value, int len);
+
+/** set user data in the ImgInfo struct, which has to be allocated with IMB_imginfo_create
+ * before calling this function.
+ * @param img - the ImBuf that contains the image data
+ * @param key - the key of the field
+ * @param value - the data to be written to the field. zero terminated string
+ * @return - 1 (true) if ImageInfo present, 0 (false) otherwise
+ */
+int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field);
+
+/** delete the key/field par in the ImgInfo struct.
+ * @param img - the ImBuf that contains the image data
+ * @param key - the key of the field
+ * @return - 1 (true) if delete the key/field, 0 (false) otherwise
+ */
+int IMB_imginfo_del_field(struct ImBuf *img, const char *key);
+
+#endif /* _IMB_IMGINFO_H */
+
diff --git a/source/blender/imbuf/intern/IMB_jpeg.h b/source/blender/imbuf/intern/IMB_jpeg.h
index 4a86a72ca77..f78810d27ee 100644
--- a/source/blender/imbuf/intern/IMB_jpeg.h
+++ b/source/blender/imbuf/intern/IMB_jpeg.h
@@ -45,7 +45,7 @@ struct jpeg_compress_struct;
int imb_is_a_jpeg(unsigned char *mem);
int imb_savejpeg(struct ImBuf * ibuf, char * name, int flags);
-struct ImBuf * imb_ibJpegImageFromFilename (char * filename, int flags);
+struct ImBuf * imb_ibJpegImageFromFilename (const char * filename, int flags);
struct ImBuf * imb_ibJpegImageFromMemory (unsigned char * buffer, int size, int flags);
#endif
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index f51844aad96..09eb487b3a6 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -46,9 +46,9 @@ ifeq ($(WITH_OPENEXR), true)
CFLAGS += -DWITH_OPENEXR
endif
-
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
+ifeq ($(WITH_DDS), true)
+ DIRS += dds
+ CPPFLAGS += -DWITH_DDS
endif
CFLAGS += $(LEVEL_1_C_WARNINGS)
@@ -80,4 +80,3 @@ ifeq ($(WITH_FFMPEG), true)
CPPFLAGS += -DWITH_FFMPEG
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
endif
-
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 003d377389b..bc750e455a6 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -43,6 +43,7 @@
#include "IMB_divers.h"
#include "IMB_allocimbuf.h"
+#include "IMB_imginfo.h"
#include "MEM_CacheLimiterC-Api.h"
static unsigned int dfltcmap[16] = {
@@ -163,6 +164,7 @@ void IMB_freeImBuf(struct ImBuf * ibuf)
IMB_freecmapImBuf(ibuf);
freeencodedbufferImBuf(ibuf);
IMB_cache_limiter_unmanage(ibuf);
+ IMB_imginfo_free(ibuf);
MEM_freeN(ibuf);
}
}
@@ -278,6 +280,7 @@ short imb_addrectfloatImBuf(struct ImBuf * ibuf)
size = ibuf->x * ibuf->y;
size = size * 4 * sizeof(float);
+ ibuf->channels= 4;
if ( (ibuf->rect_float = MEM_mapallocN(size, "imb_addrectfloatImBuf")) ){
ibuf->mall |= IB_rectfloat;
@@ -443,7 +446,7 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int));
if (flags & IB_rectfloat)
- memcpy(ibuf2->rect_float, ibuf1->rect_float, 4 * x * y * sizeof(float));
+ memcpy(ibuf2->rect_float, ibuf1->rect_float, ibuf1->channels * x * y * sizeof(float));
if (flags & IB_planes)
memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int));
@@ -476,6 +479,9 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
tbuf.mall = ibuf2->mall;
tbuf.c_handle = 0;
+ // for now don't duplicate image info
+ tbuf.img_info = 0;
+
*ibuf2 = tbuf;
if (ibuf1->cmap){
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index a1ef735ffdb..1700790c4fa 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -89,6 +89,7 @@
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
#include <ffmpeg/rational.h>
+#include <ffmpeg/swscale.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
@@ -338,12 +339,12 @@ void IMB_close_anim(struct anim * anim) {
}
-struct anim * IMB_open_anim(char * name, int ib_flags) {
+struct anim * IMB_open_anim( const char * name, int ib_flags) {
struct anim * anim;
anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct");
if (anim != NULL) {
- strcpy(anim->name, name);
+ strcpy(anim->name, name); /* fixme: possible buffer overflow here? */
anim->ib_flags = ib_flags;
}
return(anim);
@@ -593,7 +594,7 @@ static int startffmpeg(struct anim * anim) {
anim->pFrame = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
- if (avpicture_get_size(PIX_FMT_RGBA32, anim->x, anim->y)
+ if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
!= anim->x * anim->y * 4) {
fprintf (stderr,
"ffmpeg has changed alloc scheme ... ARGHHH!\n");
@@ -609,7 +610,17 @@ static int startffmpeg(struct anim * anim) {
} else {
anim->preseek = 0;
}
-
+
+ anim->img_convert_ctx = sws_getContext(
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height,
+ anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height,
+ PIX_FMT_BGR32,
+ SWS_FAST_BILINEAR | SWS_PRINT_INFO,
+ NULL, NULL, NULL);
+
return (0);
}
@@ -626,7 +637,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
avpicture_fill((AVPicture *)anim->pFrameRGB,
(unsigned char*) ibuf->rect,
- PIX_FMT_RGBA32, anim->x, anim->y);
+ PIX_FMT_BGR32, anim->x, anim->y);
if (position != anim->curposition + 1) {
if (position > anim->curposition + 1
@@ -703,36 +714,98 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
}
if(frameFinished && pos_found == 1) {
- unsigned char * p =(unsigned char*) ibuf->rect;
- unsigned char * e = p + anim->x * anim->y * 4;
-
- img_convert((AVPicture *)anim->pFrameRGB,
- PIX_FMT_RGBA32,
- (AVPicture*)anim->pFrame,
- anim->pCodecCtx->pix_fmt,
- anim->pCodecCtx->width,
- anim->pCodecCtx->height);
- IMB_flipy(ibuf);
- if (G.order == L_ENDIAN) {
- /* BGRA -> RGBA */
- while (p != e) {
- unsigned char a = p[0];
- p[0] = p[2];
- p[2] = a;
- p += 4;
+ if (G.order == B_ENDIAN) {
+ int * dstStride
+ = anim->pFrameRGB->linesize;
+ uint8_t** dst = anim->pFrameRGB->data;
+ int dstStride2[4]
+ = { dstStride[0], 0, 0, 0 };
+ uint8_t* dst2[4]= {
+ dst[0], 0, 0, 0 };
+ int x,y,h,w;
+ unsigned char* bottom;
+ unsigned char* top;
+
+ sws_scale(anim->img_convert_ctx,
+ anim->pFrame->data,
+ anim->pFrame->linesize,
+ 0,
+ anim->pCodecCtx->height,
+ dst2,
+ dstStride2);
+
+ /* workaround: sws_scale
+ sets alpha = 0 and compensate
+ for altivec-bugs and flipy... */
+
+ bottom = (unsigned char*) ibuf->rect;
+ top = bottom
+ + ibuf->x * (ibuf->y-1) * 4;
+
+ h = (ibuf->y + 1) / 2;
+ w = ibuf->x;
+
+ for (y = 0; y < h; y++) {
+ unsigned char tmp[4];
+ unsigned long * tmp_l =
+ (unsigned long*) tmp;
+ tmp[3] = 0xff;
+
+ for (x = 0; x < w; x++) {
+ tmp[0] = bottom[3];
+ tmp[1] = bottom[2];
+ tmp[2] = bottom[1];
+
+ bottom[0] = top[3];
+ bottom[1] = top[2];
+ bottom[2] = top[1];
+ bottom[3] = 0xff;
+
+ *(unsigned long*) top
+ = *tmp_l;
+
+ bottom +=4;
+ top += 4;
+ }
+ top -= 8 * w;
}
+
+ av_free_packet(&packet);
+ break;
} else {
- /* ARGB -> RGBA */
- while (p != e) {
- unsigned long a =
- *(unsigned long*) p;
- a = (a << 8) | p[0];
- *(unsigned long*) p = a;
- p += 4;
+ int * dstStride
+ = anim->pFrameRGB->linesize;
+ uint8_t** dst = anim->pFrameRGB->data;
+ int dstStride2[4]
+ = { -dstStride[0], 0, 0, 0 };
+ uint8_t* dst2[4]= {
+ dst[0]
+ + (anim->y - 1)*dstStride[0],
+ 0, 0, 0 };
+ int i;
+ unsigned char* r;
+
+ sws_scale(anim->img_convert_ctx,
+ anim->pFrame->data,
+ anim->pFrame->linesize,
+ 0,
+ anim->pCodecCtx->height,
+ dst2,
+ dstStride2);
+
+ /* workaround: sws_scale
+ sets alpha = 0... */
+
+ r = (unsigned char*) ibuf->rect;
+
+ for (i = 0; i < ibuf->x * ibuf->y;i++){
+ r[3] = 0xff;
+ r+=4;
}
+
+ av_free_packet(&packet);
+ break;
}
- av_free_packet(&packet);
- break;
}
}
@@ -750,6 +823,7 @@ static void free_anim_ffmpeg(struct anim * anim) {
av_close_input_file(anim->pFormatCtx);
av_free(anim->pFrameRGB);
av_free(anim->pFrame);
+ sws_freeContext(anim->img_convert_ctx);
}
anim->duration = 0;
}
@@ -819,6 +893,18 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
return(ibuf);
}
+struct ImBuf * IMB_anim_previewframe(struct anim * anim) {
+ struct ImBuf * ibuf = 0;
+ int position = 0;
+
+ ibuf = IMB_anim_absolute(anim, 0);
+ if (ibuf) {
+ IMB_freeImBuf(ibuf);
+ position = anim->duration / 2;
+ ibuf = IMB_anim_absolute(anim, position);
+ }
+ return ibuf;
+}
struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
struct ImBuf * ibuf = 0;
diff --git a/source/blender/imbuf/intern/cineon/Makefile b/source/blender/imbuf/intern/cineon/Makefile
index 596a6647093..e61c8dd59ed 100644
--- a/source/blender/imbuf/intern/cineon/Makefile
+++ b/source/blender/imbuf/intern/cineon/Makefile
@@ -38,10 +38,6 @@ SOURCEDIR = source/blender/imbuf/intern/cineon
include nan_compile.mk
include nan_definitions.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_JPEG)/include
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 691b81745e0..f00f6bc38c5 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -42,14 +42,29 @@
#include "MEM_guardedalloc.h"
+/* ugly bad level, should be fixed */
+#include "DNA_scene_types.h"
+#include "BKE_global.h"
+
+static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
+{
+ params->blackPoint = G.scene->r.cineonblack;
+ params->whitePoint = G.scene->r.cineonwhite;
+ params->gamma = G.scene->r.cineongamma;
+ params->doLogarithm = G.scene->r.subimtype & R_CINEON_LOG;
+}
+
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
{
+ LogImageByteConversionParameters conversion;
ImBuf *ibuf;
LogImageFile *image;
int x, y;
unsigned short *row, *upix;
int width, height, depth;
float *frow;
+
+ cineon_conversion_parameters(&conversion);
image = logImageOpenFromMem(mem, size, use_cineon);
@@ -70,6 +85,8 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
return NULL;
}
+ logImageSetByteConversion(image, &conversion);
+
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags, 0);
row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
@@ -107,10 +124,9 @@ static int imb_save_dpx_cineon(ImBuf *buf, char *filename, int use_cineon, int f
int i, j;
int index;
float *fline;
-
- conversion.blackPoint = 95;
- conversion.whitePoint = 685;
- conversion.gamma = 1;
+
+ cineon_conversion_parameters(&conversion);
+
/*
* Get the drawable for the current image...
*/
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 20f4e0d4de4..3b45a9de822 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -350,8 +350,10 @@ cineonGetRowBytes(CineonFile* cineon, unsigned short* row, int y) {
/* extract required pixels */
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- /* row[pixelIndex] = cineon->lut10[cineon->pixelBuffer[pixelIndex]]; */
- row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
+ if(cineon->params.doLogarithm)
+ row[pixelIndex] = cineon->lut10_16[cineon->pixelBuffer[pixelIndex]];
+ else
+ row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
}
return 0;
@@ -367,8 +369,10 @@ cineonSetRowBytes(CineonFile* cineon, const unsigned short* row, int y) {
/* put new pixels into pixelBuffer */
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- /* cineon->pixelBuffer[pixelIndex] = cineon->lut8[row[pixelIndex]]; */
- cineon->pixelBuffer[pixelIndex] = row[pixelIndex] >> 6;
+ if(cineon->params.doLogarithm)
+ cineon->pixelBuffer[pixelIndex] = cineon->lut16_16[row[pixelIndex]];
+ else
+ cineon->pixelBuffer[pixelIndex] = row[pixelIndex] >> 6;
}
/* pack into longwords */
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index b769d1e6132..a81e632a797 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -199,7 +199,7 @@ dumpDpxMainHeader(DpxMainHeader* header) {
#endif
}
-static int verbose = 0;
+static int verbose = 1;
void
dpxSetVerbose(int verbosity) {
verbose = verbosity;
@@ -275,8 +275,10 @@ dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) {
/* extract required pixels */
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- /* row[pixelIndex] = dpx->lut10[dpx->pixelBuffer[pixelIndex]]; */
- row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6;
+ if(dpx->params.doLogarithm)
+ row[pixelIndex] = dpx->lut10_16[dpx->pixelBuffer[pixelIndex]];
+ else
+ row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6;
}
/* save remaining pixels */
@@ -316,8 +318,10 @@ dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y) {
/* put new pixels into pixelBuffer */
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
- /* dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut8[row[pixelIndex]]; */
- dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6;
+ if(dpx->params.doLogarithm)
+ dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut16_16[row[pixelIndex]];
+ else
+ dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6;
}
dpx->pixelBufferUsed += numPixels;
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index e88e9241443..6032f342ed8 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -93,6 +93,35 @@ setupLut(LogImageFile *logImage) {
}
}
+/* set up the 10 bit to 16 bit and 16 bit to 10 bit tables */
+void
+setupLut16(LogImageFile *logImage) {
+
+ int i;
+ double f_black;
+ double scale;
+
+ f_black = convertTo(logImage->params.blackPoint, logImage->params.whitePoint, logImage->params.gamma);
+ scale = 65535.0 / (1.0 - f_black);
+
+ for (i = 0; i <= logImage->params.blackPoint; ++i) {
+ logImage->lut10_16[i] = 0;
+ }
+ for (; i < logImage->params.whitePoint; ++i) {
+ double f_i;
+ f_i = convertTo(i, logImage->params.whitePoint, logImage->params.gamma);
+ logImage->lut10_16[i] = (int)rint(scale * (f_i - f_black));
+ }
+ for (; i < 1024; ++i) {
+ logImage->lut10_16[i] = 65535;
+ }
+
+ for (i = 0; i < 65536; ++i) {
+ double f_i = f_black + (i / 65535.0) * (1.0 - f_black);
+ logImage->lut16_16[i] = convertFrom(f_i, logImage->params.whitePoint, logImage->params.gamma);
+ }
+}
+
/* how many longwords to hold this many pixels? */
int
pixelsToLongs(int numPixels) {
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
index 1af18d5e3b8..01eff8d570d 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.h
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -71,6 +71,9 @@ struct _Log_Image_File_t_
unsigned char lut10[1024];
unsigned short lut8[256];
+ unsigned short lut10_16[1024];
+ unsigned short lut16_16[65536];
+
/* pixel access functions */
GetRowFn* getRow;
SetRowFn* setRow;
@@ -82,6 +85,7 @@ struct _Log_Image_File_t_
};
void setupLut(LogImageFile*);
+void setupLut16(LogImageFile*);
int pixelsToLongs(int numPixels);
diff --git a/source/blender/imbuf/intern/cineon/logImageLib.c b/source/blender/imbuf/intern/cineon/logImageLib.c
index ff209d5ebd0..2fc52959ff6 100644
--- a/source/blender/imbuf/intern/cineon/logImageLib.c
+++ b/source/blender/imbuf/intern/cineon/logImageLib.c
@@ -89,6 +89,7 @@ logImageGetByteConversionDefaults(LogImageByteConversionParameters* params) {
params->gamma = DEFAULT_GAMMA;
params->blackPoint = DEFAULT_BLACK_POINT;
params->whitePoint = DEFAULT_WHITE_POINT;
+ params->doLogarithm = 0;
return 0;
}
@@ -97,6 +98,7 @@ logImageGetByteConversion(const LogImageFile* logImage, LogImageByteConversionPa
params->gamma = logImage->params.gamma;
params->blackPoint = logImage->params.blackPoint;
params->whitePoint = logImage->params.whitePoint;
+ params->doLogarithm = 0;
return 0;
}
@@ -110,7 +112,8 @@ logImageSetByteConversion(LogImageFile* logImage, const LogImageByteConversionPa
logImage->params.gamma = params->gamma;
logImage->params.blackPoint = params->blackPoint;
logImage->params.whitePoint = params->whitePoint;
- setupLut(logImage);
+ logImage->params.doLogarithm = params->doLogarithm;
+ setupLut16(logImage);
return 0;
}
return 1;
diff --git a/source/blender/imbuf/intern/cineon/logImageLib.h b/source/blender/imbuf/intern/cineon/logImageLib.h
index ea45c675fe2..617da1d0d92 100644
--- a/source/blender/imbuf/intern/cineon/logImageLib.h
+++ b/source/blender/imbuf/intern/cineon/logImageLib.h
@@ -47,6 +47,7 @@ typedef struct {
float gamma;
int blackPoint;
int whitePoint;
+ int doLogarithm;
} LogImageByteConversionParameters;
/* int functions return 0 for OK */
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
new file mode 100644
index 00000000000..24a090d93f6
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -0,0 +1,591 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#include <Common.h>
+#include <Stream.h>
+#include <ColorBlock.h>
+#include <BlockDXT.h>
+
+/*----------------------------------------------------------------------------
+ BlockDXT1
+----------------------------------------------------------------------------*/
+
+uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
+{
+ // Does bit expansion before interpolation.
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
+
+ // @@ Same as above, but faster?
+// Color32 c;
+// c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000);
+// c.u |= (c.u >> 5) & 0x070007;
+// c.u |= (c.u >> 6) & 0x000300;
+// color_array[0].u = c.u;
+
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
+
+ // @@ Same as above, but faster?
+// c.u = ((col1.u << 3) & 0xf8) | ((col1.u << 5) & 0xfc00) | ((col1.u << 8) & 0xf80000);
+// c.u |= (c.u >> 5) & 0x070007;
+// c.u |= (c.u >> 6) & 0x000300;
+// color_array[1].u = c.u;
+
+ if( col0.u > col1.u ) {
+ // Four-color block: derive the other two colors.
+ color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
+
+ return 4;
+ }
+ else {
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
+ }
+}
+
+// Evaluate palette assuming 3 color block.
+void BlockDXT1::evaluatePalette3(Color32 color_array[4]) const
+{
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
+
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
+
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+}
+
+// Evaluate palette assuming 4 color block.
+void BlockDXT1::evaluatePalette4(Color32 color_array[4]) const
+{
+ color_array[0].b = (col0.b << 3) | (col0.b >> 2);
+ color_array[0].g = (col0.g << 2) | (col0.g >> 4);
+ color_array[0].r = (col0.r << 3) | (col0.r >> 2);
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = (col1.r << 3) | (col1.r >> 2);
+ color_array[1].g = (col1.g << 2) | (col1.g >> 4);
+ color_array[1].b = (col1.b << 3) | (col1.b >> 2);
+ color_array[1].a = 0xFF;
+
+ // Four-color block: derive the other two colors.
+ color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
+}
+
+void BlockDXT1::decodeBlock(ColorBlock * block) const
+{
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePalette(color_array);
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
+}
+
+void BlockDXT1::setIndices(int * idx)
+{
+ indices = 0;
+ for(uint i = 0; i < 16; i++) {
+ indices |= (idx[i] & 3) << (2 * i);
+ }
+}
+
+
+/// Flip DXT1 block vertically.
+inline void BlockDXT1::flip4()
+{
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
+}
+
+/// Flip half DXT1 block vertically.
+inline void BlockDXT1::flip2()
+{
+ swap(row[0], row[1]);
+}
+
+
+/*----------------------------------------------------------------------------
+ BlockDXT3
+----------------------------------------------------------------------------*/
+
+void BlockDXT3::decodeBlock(ColorBlock * block) const
+{
+ // Decode color.
+ color.decodeBlock(block);
+
+ // Decode alpha.
+ alpha.decodeBlock(block);
+}
+
+void AlphaBlockDXT3::decodeBlock(ColorBlock * block) const
+{
+ block->color(0x0).a = (alpha0 << 4) | alpha0;
+ block->color(0x1).a = (alpha1 << 4) | alpha1;
+ block->color(0x2).a = (alpha2 << 4) | alpha2;
+ block->color(0x3).a = (alpha3 << 4) | alpha3;
+ block->color(0x4).a = (alpha4 << 4) | alpha4;
+ block->color(0x5).a = (alpha5 << 4) | alpha5;
+ block->color(0x6).a = (alpha6 << 4) | alpha6;
+ block->color(0x7).a = (alpha7 << 4) | alpha7;
+ block->color(0x8).a = (alpha8 << 4) | alpha8;
+ block->color(0x9).a = (alpha9 << 4) | alpha9;
+ block->color(0xA).a = (alphaA << 4) | alphaA;
+ block->color(0xB).a = (alphaB << 4) | alphaB;
+ block->color(0xC).a = (alphaC << 4) | alphaC;
+ block->color(0xD).a = (alphaD << 4) | alphaD;
+ block->color(0xE).a = (alphaE << 4) | alphaE;
+ block->color(0xF).a = (alphaF << 4) | alphaF;
+}
+
+/// Flip DXT3 alpha block vertically.
+void AlphaBlockDXT3::flip4()
+{
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
+}
+
+/// Flip half DXT3 alpha block vertically.
+void AlphaBlockDXT3::flip2()
+{
+ swap(row[0], row[1]);
+}
+
+/// Flip DXT3 block vertically.
+void BlockDXT3::flip4()
+{
+ alpha.flip4();
+ color.flip4();
+}
+
+/// Flip half DXT3 block vertically.
+void BlockDXT3::flip2()
+{
+ alpha.flip2();
+ color.flip2();
+}
+
+
+/*----------------------------------------------------------------------------
+ BlockDXT5
+----------------------------------------------------------------------------*/
+
+void AlphaBlockDXT5::evaluatePalette(uint8 alpha[8]) const
+{
+ if (alpha0 > alpha1) {
+ evaluatePalette8(alpha);
+ }
+ else {
+ evaluatePalette6(alpha);
+ }
+}
+
+void AlphaBlockDXT5::evaluatePalette8(uint8 alpha[8]) const
+{
+ // 8-alpha block: derive the other six alphas.
+ // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+ alpha[0] = alpha0;
+ alpha[1] = alpha1;
+ alpha[2] = (6 * alpha[0] + 1 * alpha[1]) / 7; // bit code 010
+ alpha[3] = (5 * alpha[0] + 2 * alpha[1]) / 7; // bit code 011
+ alpha[4] = (4 * alpha[0] + 3 * alpha[1]) / 7; // bit code 100
+ alpha[5] = (3 * alpha[0] + 4 * alpha[1]) / 7; // bit code 101
+ alpha[6] = (2 * alpha[0] + 5 * alpha[1]) / 7; // bit code 110
+ alpha[7] = (1 * alpha[0] + 6 * alpha[1]) / 7; // bit code 111
+}
+
+void AlphaBlockDXT5::evaluatePalette6(uint8 alpha[8]) const
+{
+ // 6-alpha block.
+ // Bit code 000 = alpha0, 001 = alpha1, others are interpolated.
+ alpha[0] = alpha0;
+ alpha[1] = alpha1;
+ alpha[2] = (4 * alpha[0] + 1 * alpha[1]) / 5; // Bit code 010
+ alpha[3] = (3 * alpha[0] + 2 * alpha[1]) / 5; // Bit code 011
+ alpha[4] = (2 * alpha[0] + 3 * alpha[1]) / 5; // Bit code 100
+ alpha[5] = (1 * alpha[0] + 4 * alpha[1]) / 5; // Bit code 101
+ alpha[6] = 0x00; // Bit code 110
+ alpha[7] = 0xFF; // Bit code 111
+}
+
+void AlphaBlockDXT5::indices(uint8 index_array[16]) const
+{
+ index_array[0x0] = bits0;
+ index_array[0x1] = bits1;
+ index_array[0x2] = bits2;
+ index_array[0x3] = bits3;
+ index_array[0x4] = bits4;
+ index_array[0x5] = bits5;
+ index_array[0x6] = bits6;
+ index_array[0x7] = bits7;
+ index_array[0x8] = bits8;
+ index_array[0x9] = bits9;
+ index_array[0xA] = bitsA;
+ index_array[0xB] = bitsB;
+ index_array[0xC] = bitsC;
+ index_array[0xD] = bitsD;
+ index_array[0xE] = bitsE;
+ index_array[0xF] = bitsF;
+}
+
+uint AlphaBlockDXT5::index(uint index) const
+{
+ int offset = (3 * index + 16);
+ return uint((this->u >> offset) & 0x7);
+}
+
+void AlphaBlockDXT5::setIndex(uint index, uint value)
+{
+ int offset = (3 * index + 16);
+ uint64 mask = uint64(0x7) << offset;
+ this->u = (this->u & ~mask) | (uint64(value) << offset);
+}
+
+void AlphaBlockDXT5::decodeBlock(ColorBlock * block) const
+{
+ uint8 alpha_array[8];
+ evaluatePalette(alpha_array);
+
+ uint8 index_array[16];
+ indices(index_array);
+
+ for(uint i = 0; i < 16; i++) {
+ block->color(i).a = alpha_array[index_array[i]];
+ }
+}
+
+void AlphaBlockDXT5::flip4()
+{
+ uint64 * b = (uint64 *)this;
+
+ // @@ The masks might have to be byte swapped.
+ uint64 tmp = (*b & (uint64)(0x000000000000FFFFLL));
+ tmp |= (*b & (uint64)(0x000000000FFF0000LL)) << 36;
+ tmp |= (*b & (uint64)(0x000000FFF0000000LL)) << 12;
+ tmp |= (*b & (uint64)(0x000FFF0000000000LL)) >> 12;
+ tmp |= (*b & (uint64)(0xFFF0000000000000LL)) >> 36;
+
+ *b = tmp;
+}
+
+void AlphaBlockDXT5::flip2()
+{
+ uint * b = (uint *)this;
+
+ // @@ The masks might have to be byte swapped.
+ uint tmp = (*b & 0xFF000000);
+ tmp |= (*b & 0x00000FFF) << 12;
+ tmp |= (*b & 0x00FFF000) >> 12;
+
+ *b = tmp;
+}
+
+void BlockDXT5::decodeBlock(ColorBlock * block) const
+{
+ // Decode color.
+ color.decodeBlock(block);
+
+ // Decode alpha.
+ alpha.decodeBlock(block);
+
+}
+
+/// Flip DXT5 block vertically.
+void BlockDXT5::flip4()
+{
+ alpha.flip4();
+ color.flip4();
+}
+
+/// Flip half DXT5 block vertically.
+void BlockDXT5::flip2()
+{
+ alpha.flip2();
+ color.flip2();
+}
+
+
+/// Decode ATI1 block.
+void BlockATI1::decodeBlock(ColorBlock * block) const
+{
+ uint8 alpha_array[8];
+ alpha.evaluatePalette(alpha_array);
+
+ uint8 index_array[16];
+ alpha.indices(index_array);
+
+ for(uint i = 0; i < 16; i++) {
+ Color32 & c = block->color(i);
+ c.b = c.g = c.r = alpha_array[index_array[i]];
+ c.a = 255;
+ }
+}
+
+/// Flip ATI1 block vertically.
+void BlockATI1::flip4()
+{
+ alpha.flip4();
+}
+
+/// Flip half ATI1 block vertically.
+void BlockATI1::flip2()
+{
+ alpha.flip2();
+}
+
+
+/// Decode ATI2 block.
+void BlockATI2::decodeBlock(ColorBlock * block) const
+{
+ uint8 alpha_array[8];
+ uint8 index_array[16];
+
+ x.evaluatePalette(alpha_array);
+ x.indices(index_array);
+
+ for(uint i = 0; i < 16; i++) {
+ Color32 & c = block->color(i);
+ c.r = alpha_array[index_array[i]];
+ }
+
+ y.evaluatePalette(alpha_array);
+ y.indices(index_array);
+
+ for(uint i = 0; i < 16; i++) {
+ Color32 & c = block->color(i);
+ c.g = alpha_array[index_array[i]];
+ c.b = 0;
+ c.a = 255;
+ }
+}
+
+/// Flip ATI2 block vertically.
+void BlockATI2::flip4()
+{
+ x.flip4();
+ y.flip4();
+}
+
+/// Flip half ATI2 block vertically.
+void BlockATI2::flip2()
+{
+ x.flip2();
+ y.flip2();
+}
+
+
+void BlockCTX1::evaluatePalette(Color32 color_array[4]) const
+{
+ // Does bit expansion before interpolation.
+ color_array[0].b = 0x00;
+ color_array[0].g = col0[1];
+ color_array[0].r = col0[0];
+ color_array[0].a = 0xFF;
+
+ color_array[1].r = 0x00;
+ color_array[1].g = col0[1];
+ color_array[1].b = col1[0];
+ color_array[1].a = 0xFF;
+
+ color_array[2].r = 0x00;
+ color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3;
+ color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3;
+ color_array[2].a = 0xFF;
+
+ color_array[3].r = 0x00;
+ color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3;
+ color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3;
+ color_array[3].a = 0xFF;
+}
+
+void BlockCTX1::decodeBlock(ColorBlock * block) const
+{
+ // Decode color block.
+ Color32 color_array[4];
+ evaluatePalette(color_array);
+
+ // Write color block.
+ for( uint j = 0; j < 4; j++ ) {
+ for( uint i = 0; i < 4; i++ ) {
+ uint idx = (row[j] >> (2 * i)) & 3;
+ block->color(i, j) = color_array[idx];
+ }
+ }
+}
+
+void BlockCTX1::setIndices(int * idx)
+{
+ indices = 0;
+ for(uint i = 0; i < 16; i++) {
+ indices |= (idx[i] & 3) << (2 * i);
+ }
+}
+
+
+/// Flip CTX1 block vertically.
+inline void BlockCTX1::flip4()
+{
+ swap(row[0], row[3]);
+ swap(row[1], row[2]);
+}
+
+/// Flip half CTX1 block vertically.
+inline void BlockCTX1::flip2()
+{
+ swap(row[0], row[1]);
+}
+
+void mem_read(Stream & mem, BlockDXT1 & block)
+{
+ mem_read(mem, block.col0.u);
+ mem_read(mem, block.col1.u);
+ mem_read(mem, block.indices);
+}
+
+void mem_read(Stream & mem, AlphaBlockDXT3 & block)
+{
+ for (unsigned int i = 0; i < 4; i++) mem_read(mem, block.row[i]);
+}
+
+void mem_read(Stream & mem, BlockDXT3 & block)
+{
+ mem_read(mem, block.alpha);
+ mem_read(mem, block.color);
+}
+
+void mem_read(Stream & mem, AlphaBlockDXT5 & block)
+{
+ mem_read(mem, block.u);
+}
+
+void mem_read(Stream & mem, BlockDXT5 & block)
+{
+ mem_read(mem, block.alpha);
+ mem_read(mem, block.color);
+}
+
+void mem_read(Stream & mem, BlockATI1 & block)
+{
+ mem_read(mem, block.alpha);
+}
+
+void mem_read(Stream & mem, BlockATI2 & block)
+{
+ mem_read(mem, block.x);
+ mem_read(mem, block.y);
+}
+
+void mem_read(Stream & mem, BlockCTX1 & block)
+{
+ mem_read(mem, block.col0[0]);
+ mem_read(mem, block.col0[1]);
+ mem_read(mem, block.col1[0]);
+ mem_read(mem, block.col1[1]);
+ mem_read(mem, block.indices);
+}
+
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
new file mode 100644
index 00000000000..5c232201f0c
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -0,0 +1,248 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef _DDS_BLOCKDXT_H
+#define _DDS_BLOCKDXT_H
+
+#include <Common.h>
+#include <Color.h>
+#include <ColorBlock.h>
+#include <Stream.h>
+
+/// DXT1 block.
+struct BlockDXT1
+{
+ Color16 col0;
+ Color16 col1;
+ union {
+ uint8 row[4];
+ uint indices;
+ };
+
+ bool isFourColorMode() const;
+
+ uint evaluatePalette(Color32 color_array[4]) const;
+ uint evaluatePaletteFast(Color32 color_array[4]) const;
+ void evaluatePalette3(Color32 color_array[4]) const;
+ void evaluatePalette4(Color32 color_array[4]) const;
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void setIndices(int * idx);
+
+ void flip4();
+ void flip2();
+};
+
+/// Return true if the block uses four color mode, false otherwise.
+inline bool BlockDXT1::isFourColorMode() const
+{
+ return col0.u > col1.u;
+}
+
+
+/// DXT3 alpha block with explicit alpha.
+struct AlphaBlockDXT3
+{
+ union {
+ struct {
+ uint alpha0 : 4;
+ uint alpha1 : 4;
+ uint alpha2 : 4;
+ uint alpha3 : 4;
+ uint alpha4 : 4;
+ uint alpha5 : 4;
+ uint alpha6 : 4;
+ uint alpha7 : 4;
+ uint alpha8 : 4;
+ uint alpha9 : 4;
+ uint alphaA : 4;
+ uint alphaB : 4;
+ uint alphaC : 4;
+ uint alphaD : 4;
+ uint alphaE : 4;
+ uint alphaF : 4;
+ };
+ uint16 row[4];
+ };
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+
+/// DXT3 block.
+struct BlockDXT3
+{
+ AlphaBlockDXT3 alpha;
+ BlockDXT1 color;
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+
+/// DXT5 alpha block.
+struct AlphaBlockDXT5
+{
+ union {
+ struct {
+ unsigned int alpha0 : 8; // 8
+ unsigned int alpha1 : 8; // 16
+ unsigned int bits0 : 3; // 3 - 19
+ unsigned int bits1 : 3; // 6 - 22
+ unsigned int bits2 : 3; // 9 - 25
+ unsigned int bits3 : 3; // 12 - 28
+ unsigned int bits4 : 3; // 15 - 31
+ unsigned int bits5 : 3; // 18 - 34
+ unsigned int bits6 : 3; // 21 - 37
+ unsigned int bits7 : 3; // 24 - 40
+ unsigned int bits8 : 3; // 27 - 43
+ unsigned int bits9 : 3; // 30 - 46
+ unsigned int bitsA : 3; // 33 - 49
+ unsigned int bitsB : 3; // 36 - 52
+ unsigned int bitsC : 3; // 39 - 55
+ unsigned int bitsD : 3; // 42 - 58
+ unsigned int bitsE : 3; // 45 - 61
+ unsigned int bitsF : 3; // 48 - 64
+ };
+ uint64 u;
+ };
+
+ void evaluatePalette(uint8 alpha[8]) const;
+ void evaluatePalette8(uint8 alpha[8]) const;
+ void evaluatePalette6(uint8 alpha[8]) const;
+ void indices(uint8 index_array[16]) const;
+
+ uint index(uint index) const;
+ void setIndex(uint index, uint value);
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+
+/// DXT5 block.
+struct BlockDXT5
+{
+ AlphaBlockDXT5 alpha;
+ BlockDXT1 color;
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+/// ATI1 block.
+struct BlockATI1
+{
+ AlphaBlockDXT5 alpha;
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+/// ATI2 block.
+struct BlockATI2
+{
+ AlphaBlockDXT5 x;
+ AlphaBlockDXT5 y;
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+/// CTX1 block.
+struct BlockCTX1
+{
+ uint8 col0[2];
+ uint8 col1[2];
+ union {
+ uint8 row[4];
+ uint indices;
+ };
+
+ void evaluatePalette(Color32 color_array[4]) const;
+ void setIndices(int * idx);
+
+ void decodeBlock(ColorBlock * block) const;
+
+ void flip4();
+ void flip2();
+};
+
+void mem_read(Stream & mem, BlockDXT1 & block);
+void mem_read(Stream & mem, AlphaBlockDXT3 & block);
+void mem_read(Stream & mem, BlockDXT3 & block);
+void mem_read(Stream & mem, AlphaBlockDXT5 & block);
+void mem_read(Stream & mem, BlockDXT5 & block);
+void mem_read(Stream & mem, BlockATI1 & block);
+void mem_read(Stream & mem, BlockATI2 & block);
+void mem_read(Stream & mem, BlockCTX1 & block);
+
+#endif // _DDS_BLOCKDXT_H
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
new file mode 100644
index 00000000000..f8055afdfc9
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Color.h
@@ -0,0 +1,99 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_COLOR_H
+#define _DDS_COLOR_H
+
+/// 32 bit color stored as BGRA.
+class Color32
+{
+public:
+ Color32() { }
+ Color32(const Color32 & c) : u(c.u) { }
+ Color32(unsigned char R, unsigned char G, unsigned char B) { setRGBA(R, G, B, 0xFF); }
+ Color32(unsigned char R, unsigned char G, unsigned char B, unsigned char A) { setRGBA( R, G, B, A); }
+ //Color32(unsigned char c[4]) { setRGBA(c[0], c[1], c[2], c[3]); }
+ //Color32(float R, float G, float B) { setRGBA(uint(R*255), uint(G*255), uint(B*255), 0xFF); }
+ //Color32(float R, float G, float B, float A) { setRGBA(uint(R*255), uint(G*255), uint(B*255), uint(A*255)); }
+ Color32(unsigned int U) : u(U) { }
+
+ void setRGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A)
+ {
+ r = R;
+ g = G;
+ b = B;
+ a = A;
+ }
+
+ void setBGRA(unsigned char B, unsigned char G, unsigned char R, unsigned char A = 0xFF)
+ {
+ r = R;
+ g = G;
+ b = B;
+ a = A;
+ }
+
+ operator unsigned int () const {
+ return u;
+ }
+
+ union {
+ struct {
+ unsigned char b, g, r, a;
+ };
+ unsigned int u;
+ };
+};
+
+/// 16 bit 565 BGR color.
+class Color16
+{
+public:
+ Color16() { }
+ Color16(const Color16 & c) : u(c.u) { }
+ explicit Color16(unsigned short U) : u(U) { }
+
+ union {
+ struct {
+ unsigned short b : 5;
+ unsigned short g : 6;
+ unsigned short r : 5;
+ };
+ unsigned short u;
+ };
+};
+
+#endif // _DDS_COLOR_H
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
new file mode 100644
index 00000000000..0199d15ada7
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -0,0 +1,317 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#include <ColorBlock.h>
+#include <Image.h>
+#include <Common.h>
+
+ // Get approximate luminance.
+ inline static uint colorLuminance(Color32 c)
+ {
+ return c.r + c.g + c.b;
+ }
+
+ // Get the euclidean distance between the given colors.
+ inline static uint colorDistance(Color32 c0, Color32 c1)
+ {
+ return (c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b);
+ }
+
+
+/// Default constructor.
+ColorBlock::ColorBlock()
+{
+}
+
+/// Init the color block with the contents of the given block.
+ColorBlock::ColorBlock(const ColorBlock & block)
+{
+ for(uint i = 0; i < 16; i++) {
+ color(i) = block.color(i);
+ }
+}
+
+
+/// Initialize this color block.
+ColorBlock::ColorBlock(const Image * img, uint x, uint y)
+{
+ init(img, x, y);
+}
+
+void ColorBlock::init(const Image * img, uint x, uint y)
+{
+ const uint bw = min(img->width() - x, 4U);
+ const uint bh = min(img->height() - y, 4U);
+
+ static int remainder[] = {
+ 0, 0, 0, 0,
+ 0, 1, 0, 1,
+ 0, 1, 2, 0,
+ 0, 1, 2, 3,
+ };
+
+ // Blocks that are smaller than 4x4 are handled by repeating the pixels.
+ // @@ Thats only correct when block size is 1, 2 or 4, but not with 3. :(
+
+ for(uint i = 0; i < 4; i++) {
+ //const int by = i % bh;
+ const int by = remainder[(bh - 1) * 4 + i];
+ for(uint e = 0; e < 4; e++) {
+ //const int bx = e % bw;
+ const int bx = remainder[(bw - 1) * 4 + e];
+ color(e, i) = img->pixel(x + bx, y + by);
+ }
+ }
+}
+
+
+void ColorBlock::swizzleDXT5n()
+{
+ for(int i = 0; i < 16; i++)
+ {
+ Color32 c = m_color[i];
+ m_color[i] = Color32(0, c.g, 0, c.r);
+ }
+}
+
+void ColorBlock::splatX()
+{
+ for(int i = 0; i < 16; i++)
+ {
+ uint8 x = m_color[i].r;
+ m_color[i] = Color32(x, x, x, x);
+ }
+}
+
+void ColorBlock::splatY()
+{
+ for(int i = 0; i < 16; i++)
+ {
+ uint8 y = m_color[i].g;
+ m_color[i] = Color32(y, y, y, y);
+ }
+}
+
+
+/// Count number of unique colors in this color block.
+uint ColorBlock::countUniqueColors() const
+{
+ uint count = 0;
+
+ // @@ This does not have to be o(n^2)
+ for(int i = 0; i < 16; i++)
+ {
+ bool unique = true;
+ for(int j = 0; j < i; j++) {
+ if( m_color[i] != m_color[j] ) {
+ unique = false;
+ }
+ }
+
+ if( unique ) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+/// Get average color of the block.
+Color32 ColorBlock::averageColor() const
+{
+ uint r, g, b, a;
+ r = g = b = a = 0;
+
+ for(uint i = 0; i < 16; i++) {
+ r += m_color[i].r;
+ g += m_color[i].g;
+ b += m_color[i].b;
+ a += m_color[i].a;
+ }
+
+ return Color32(uint8(r / 16), uint8(g / 16), uint8(b / 16), uint8(a / 16));
+}
+
+/// Return true if the block is not fully opaque.
+bool ColorBlock::hasAlpha() const
+{
+ for (uint i = 0; i < 16; i++)
+ {
+ if (m_color[i].a != 255) return true;
+ }
+ return false;
+}
+
+
+/// Get diameter color range.
+void ColorBlock::diameterRange(Color32 * start, Color32 * end) const
+{
+ Color32 c0, c1;
+ uint best_dist = 0;
+
+ for(int i = 0; i < 16; i++) {
+ for (int j = i+1; j < 16; j++) {
+ uint dist = colorDistance(m_color[i], m_color[j]);
+ if( dist > best_dist ) {
+ best_dist = dist;
+ c0 = m_color[i];
+ c1 = m_color[j];
+ }
+ }
+ }
+
+ *start = c0;
+ *end = c1;
+}
+
+/// Get luminance color range.
+void ColorBlock::luminanceRange(Color32 * start, Color32 * end) const
+{
+ Color32 minColor, maxColor;
+ uint minLuminance, maxLuminance;
+
+ maxLuminance = minLuminance = colorLuminance(m_color[0]);
+
+ for(uint i = 1; i < 16; i++)
+ {
+ uint luminance = colorLuminance(m_color[i]);
+
+ if (luminance > maxLuminance) {
+ maxLuminance = luminance;
+ maxColor = m_color[i];
+ }
+ else if (luminance < minLuminance) {
+ minLuminance = luminance;
+ minColor = m_color[i];
+ }
+ }
+
+ *start = minColor;
+ *end = maxColor;
+}
+
+/// Get color range based on the bounding box.
+void ColorBlock::boundsRange(Color32 * start, Color32 * end) const
+{
+ Color32 minColor(255, 255, 255);
+ Color32 maxColor(0, 0, 0);
+
+ for(uint i = 0; i < 16; i++)
+ {
+ if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
+ if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
+ if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
+ if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
+ if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
+ if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
+ }
+
+ // Offset range by 1/16 of the extents
+ Color32 inset;
+ inset.r = (maxColor.r - minColor.r) >> 4;
+ inset.g = (maxColor.g - minColor.g) >> 4;
+ inset.b = (maxColor.b - minColor.b) >> 4;
+
+ minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
+ minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
+ minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
+
+ maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
+ maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
+ maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
+
+ *start = minColor;
+ *end = maxColor;
+}
+
+/// Get color range based on the bounding box.
+void ColorBlock::boundsRangeAlpha(Color32 * start, Color32 * end) const
+{
+ Color32 minColor(255, 255, 255, 255);
+ Color32 maxColor(0, 0, 0, 0);
+
+ for(uint i = 0; i < 16; i++)
+ {
+ if (m_color[i].r < minColor.r) { minColor.r = m_color[i].r; }
+ if (m_color[i].g < minColor.g) { minColor.g = m_color[i].g; }
+ if (m_color[i].b < minColor.b) { minColor.b = m_color[i].b; }
+ if (m_color[i].a < minColor.a) { minColor.a = m_color[i].a; }
+ if (m_color[i].r > maxColor.r) { maxColor.r = m_color[i].r; }
+ if (m_color[i].g > maxColor.g) { maxColor.g = m_color[i].g; }
+ if (m_color[i].b > maxColor.b) { maxColor.b = m_color[i].b; }
+ if (m_color[i].a > maxColor.a) { maxColor.a = m_color[i].a; }
+ }
+
+ // Offset range by 1/16 of the extents
+ Color32 inset;
+ inset.r = (maxColor.r - minColor.r) >> 4;
+ inset.g = (maxColor.g - minColor.g) >> 4;
+ inset.b = (maxColor.b - minColor.b) >> 4;
+ inset.a = (maxColor.a - minColor.a) >> 4;
+
+ minColor.r = (minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255;
+ minColor.g = (minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255;
+ minColor.b = (minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255;
+ minColor.a = (minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255;
+
+ maxColor.r = (maxColor.r >= inset.r) ? maxColor.r - inset.r : 0;
+ maxColor.g = (maxColor.g >= inset.g) ? maxColor.g - inset.g : 0;
+ maxColor.b = (maxColor.b >= inset.b) ? maxColor.b - inset.b : 0;
+ maxColor.a = (maxColor.a >= inset.a) ? maxColor.a - inset.a : 0;
+
+ *start = minColor;
+ *end = maxColor;
+}
+
+/// Sort colors by abosolute value in their 16 bit representation.
+void ColorBlock::sortColorsByAbsoluteValue()
+{
+ // Dummy selection sort.
+ for( uint a = 0; a < 16; a++ ) {
+ uint max = a;
+ Color16 cmax(m_color[a]);
+
+ for( uint b = a+1; b < 16; b++ ) {
+ Color16 cb(m_color[b]);
+
+ if( cb.u > cmax.u ) {
+ max = b;
+ cmax = cb;
+ }
+ }
+ swap( m_color[a], m_color[max] );
+ }
+}
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
new file mode 100644
index 00000000000..72049be5f3c
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -0,0 +1,116 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_COLORBLOCK_H
+#define _DDS_COLORBLOCK_H
+
+#include <Color.h>
+#include <Image.h>
+
+/// Uncompressed 4x4 color block.
+struct ColorBlock
+{
+ ColorBlock();
+ ColorBlock(const ColorBlock & block);
+ ColorBlock(const Image * img, uint x, uint y);
+
+ void init(const Image * img, uint x, uint y);
+
+ void swizzleDXT5n();
+ void splatX();
+ void splatY();
+
+ uint countUniqueColors() const;
+ Color32 averageColor() const;
+ bool hasAlpha() const;
+
+ void diameterRange(Color32 * start, Color32 * end) const;
+ void luminanceRange(Color32 * start, Color32 * end) const;
+ void boundsRange(Color32 * start, Color32 * end) const;
+ void boundsRangeAlpha(Color32 * start, Color32 * end) const;
+ void bestFitRange(Color32 * start, Color32 * end) const;
+
+ void sortColorsByAbsoluteValue();
+
+ float volume() const;
+
+ // Accessors
+ const Color32 * colors() const;
+
+ Color32 color(uint i) const;
+ Color32 & color(uint i);
+
+ Color32 color(uint x, uint y) const;
+ Color32 & color(uint x, uint y);
+
+private:
+
+ Color32 m_color[4*4];
+
+};
+
+
+/// Get pointer to block colors.
+inline const Color32 * ColorBlock::colors() const
+{
+ return m_color;
+}
+
+/// Get block color.
+inline Color32 ColorBlock::color(uint i) const
+{
+ return m_color[i];
+}
+
+/// Get block color.
+inline Color32 & ColorBlock::color(uint i)
+{
+ return m_color[i];
+}
+
+/// Get block color.
+inline Color32 ColorBlock::color(uint x, uint y) const
+{
+ return m_color[y * 4 + x];
+}
+
+/// Get block color.
+inline Color32 & ColorBlock::color(uint x, uint y)
+{
+ return m_color[y * 4 + x];
+}
+
+#endif // _DDS_COLORBLOCK_H
diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h
new file mode 100644
index 00000000000..0c687e2ca9a
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Common.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef _DDS_COMMON_H
+#define _DDS_COMMON_H
+
+#ifndef min
+#define min(a,b) ((a) <= (b) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) ((a) >= (b) ? (a) : (b))
+#endif
+#ifndef clamp
+#define clamp(x,a,b) min(max((x), (a)), (b))
+#endif
+
+template<typename T>
+inline void
+swap(T & a, T & b)
+{
+ T tmp = a;
+ a = b;
+ b = tmp;
+}
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+#endif
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
new file mode 100644
index 00000000000..f842c756ce1
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -0,0 +1,1023 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#include <DirectDrawSurface.h>
+#include <BlockDXT.h>
+#include <PixelFormat.h>
+
+#include <stdio.h> // printf
+#include <math.h> // sqrt
+#include <sys/types.h>
+
+/*** declarations ***/
+
+#if !defined(MAKEFOURCC)
+# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((uint)((unsigned char)(ch0)) | \
+ ((uint)((unsigned char)(ch1)) << 8) | \
+ ((uint)((unsigned char)(ch2)) << 16) | \
+ ((uint)((unsigned char)(ch3)) << 24 ))
+#endif
+
+static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
+static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
+static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
+static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
+static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
+static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
+static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
+static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1');
+static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
+
+// 32 bit RGB formats.
+static const uint D3DFMT_R8G8B8 = 20;
+static const uint D3DFMT_A8R8G8B8 = 21;
+static const uint D3DFMT_X8R8G8B8 = 22;
+static const uint D3DFMT_R5G6B5 = 23;
+static const uint D3DFMT_X1R5G5B5 = 24;
+static const uint D3DFMT_A1R5G5B5 = 25;
+static const uint D3DFMT_A4R4G4B4 = 26;
+static const uint D3DFMT_R3G3B2 = 27;
+static const uint D3DFMT_A8 = 28;
+static const uint D3DFMT_A8R3G3B2 = 29;
+static const uint D3DFMT_X4R4G4B4 = 30;
+static const uint D3DFMT_A2B10G10R10 = 31;
+static const uint D3DFMT_A8B8G8R8 = 32;
+static const uint D3DFMT_X8B8G8R8 = 33;
+static const uint D3DFMT_G16R16 = 34;
+static const uint D3DFMT_A2R10G10B10 = 35;
+
+static const uint D3DFMT_A16B16G16R16 = 36;
+
+// Palette formats.
+static const uint D3DFMT_A8P8 = 40;
+static const uint D3DFMT_P8 = 41;
+
+// Luminance formats.
+static const uint D3DFMT_L8 = 50;
+static const uint D3DFMT_A8L8 = 51;
+static const uint D3DFMT_A4L4 = 52;
+static const uint D3DFMT_L16 = 81;
+
+// Floating point formats
+static const uint D3DFMT_R16F = 111;
+static const uint D3DFMT_G16R16F = 112;
+static const uint D3DFMT_A16B16G16R16F = 113;
+static const uint D3DFMT_R32F = 114;
+static const uint D3DFMT_G32R32F = 115;
+static const uint D3DFMT_A32B32G32R32F = 116;
+
+static const uint DDSD_CAPS = 0x00000001U;
+static const uint DDSD_PIXELFORMAT = 0x00001000U;
+static const uint DDSD_WIDTH = 0x00000004U;
+static const uint DDSD_HEIGHT = 0x00000002U;
+static const uint DDSD_PITCH = 0x00000008U;
+static const uint DDSD_MIPMAPCOUNT = 0x00020000U;
+static const uint DDSD_LINEARSIZE = 0x00080000U;
+static const uint DDSD_DEPTH = 0x00800000U;
+
+static const uint DDSCAPS_COMPLEX = 0x00000008U;
+static const uint DDSCAPS_TEXTURE = 0x00001000U;
+static const uint DDSCAPS_MIPMAP = 0x00400000U;
+static const uint DDSCAPS2_VOLUME = 0x00200000U;
+static const uint DDSCAPS2_CUBEMAP = 0x00000200U;
+
+static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U;
+static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U;
+static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U;
+static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U;
+static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U;
+static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U;
+static const uint DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U;
+
+static const uint DDPF_ALPHAPIXELS = 0x00000001U;
+static const uint DDPF_ALPHA = 0x00000002U;
+static const uint DDPF_FOURCC = 0x00000004U;
+static const uint DDPF_RGB = 0x00000040U;
+static const uint DDPF_PALETTEINDEXED1 = 0x00000800U;
+static const uint DDPF_PALETTEINDEXED2 = 0x00001000U;
+static const uint DDPF_PALETTEINDEXED4 = 0x00000008U;
+static const uint DDPF_PALETTEINDEXED8 = 0x00000020U;
+static const uint DDPF_LUMINANCE = 0x00020000U;
+static const uint DDPF_ALPHAPREMULT = 0x00008000U;
+static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag.
+
+ // DX10 formats.
+ enum DXGI_FORMAT
+ {
+ DXGI_FORMAT_UNKNOWN = 0,
+
+ DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
+ DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
+ DXGI_FORMAT_R32G32B32A32_UINT = 3,
+ DXGI_FORMAT_R32G32B32A32_SINT = 4,
+
+ DXGI_FORMAT_R32G32B32_TYPELESS = 5,
+ DXGI_FORMAT_R32G32B32_FLOAT = 6,
+ DXGI_FORMAT_R32G32B32_UINT = 7,
+ DXGI_FORMAT_R32G32B32_SINT = 8,
+
+ DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+ DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+ DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+ DXGI_FORMAT_R16G16B16A16_UINT = 12,
+ DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+ DXGI_FORMAT_R16G16B16A16_SINT = 14,
+
+ DXGI_FORMAT_R32G32_TYPELESS = 15,
+ DXGI_FORMAT_R32G32_FLOAT = 16,
+ DXGI_FORMAT_R32G32_UINT = 17,
+ DXGI_FORMAT_R32G32_SINT = 18,
+
+ DXGI_FORMAT_R32G8X24_TYPELESS = 19,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
+ DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
+
+ DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
+ DXGI_FORMAT_R10G10B10A2_UNORM = 24,
+ DXGI_FORMAT_R10G10B10A2_UINT = 25,
+
+ DXGI_FORMAT_R11G11B10_FLOAT = 26,
+
+ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+ DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+ DXGI_FORMAT_R8G8B8A8_UINT = 30,
+ DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+ DXGI_FORMAT_R8G8B8A8_SINT = 32,
+
+ DXGI_FORMAT_R16G16_TYPELESS = 33,
+ DXGI_FORMAT_R16G16_FLOAT = 34,
+ DXGI_FORMAT_R16G16_UNORM = 35,
+ DXGI_FORMAT_R16G16_UINT = 36,
+ DXGI_FORMAT_R16G16_SNORM = 37,
+ DXGI_FORMAT_R16G16_SINT = 38,
+
+ DXGI_FORMAT_R32_TYPELESS = 39,
+ DXGI_FORMAT_D32_FLOAT = 40,
+ DXGI_FORMAT_R32_FLOAT = 41,
+ DXGI_FORMAT_R32_UINT = 42,
+ DXGI_FORMAT_R32_SINT = 43,
+
+ DXGI_FORMAT_R24G8_TYPELESS = 44,
+ DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
+
+ DXGI_FORMAT_R8G8_TYPELESS = 48,
+ DXGI_FORMAT_R8G8_UNORM = 49,
+ DXGI_FORMAT_R8G8_UINT = 50,
+ DXGI_FORMAT_R8G8_SNORM = 51,
+ DXGI_FORMAT_R8G8_SINT = 52,
+
+ DXGI_FORMAT_R16_TYPELESS = 53,
+ DXGI_FORMAT_R16_FLOAT = 54,
+ DXGI_FORMAT_D16_UNORM = 55,
+ DXGI_FORMAT_R16_UNORM = 56,
+ DXGI_FORMAT_R16_UINT = 57,
+ DXGI_FORMAT_R16_SNORM = 58,
+ DXGI_FORMAT_R16_SINT = 59,
+
+ DXGI_FORMAT_R8_TYPELESS = 60,
+ DXGI_FORMAT_R8_UNORM = 61,
+ DXGI_FORMAT_R8_UINT = 62,
+ DXGI_FORMAT_R8_SNORM = 63,
+ DXGI_FORMAT_R8_SINT = 64,
+ DXGI_FORMAT_A8_UNORM = 65,
+
+ DXGI_FORMAT_R1_UNORM = 66,
+
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
+
+ DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
+ DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
+
+ DXGI_FORMAT_BC1_TYPELESS = 70,
+ DXGI_FORMAT_BC1_UNORM = 71,
+ DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+
+ DXGI_FORMAT_BC2_TYPELESS = 73,
+ DXGI_FORMAT_BC2_UNORM = 74,
+ DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+
+ DXGI_FORMAT_BC3_TYPELESS = 76,
+ DXGI_FORMAT_BC3_UNORM = 77,
+ DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+
+ DXGI_FORMAT_BC4_TYPELESS = 79,
+ DXGI_FORMAT_BC4_UNORM = 80,
+ DXGI_FORMAT_BC4_SNORM = 81,
+
+ DXGI_FORMAT_BC5_TYPELESS = 82,
+ DXGI_FORMAT_BC5_UNORM = 83,
+ DXGI_FORMAT_BC5_SNORM = 84,
+
+ DXGI_FORMAT_B5G6R5_UNORM = 85,
+ DXGI_FORMAT_B5G5R5A1_UNORM = 86,
+ DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+ DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+ };
+
+ enum D3D10_RESOURCE_DIMENSION
+ {
+ D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
+ D3D10_RESOURCE_DIMENSION_BUFFER = 1,
+ D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
+ D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
+ D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
+ };
+
+/*** implementation ***/
+
+void mem_read(Stream & mem, DDSPixelFormat & pf)
+{
+ mem_read(mem, pf.size);
+ mem_read(mem, pf.flags);
+ mem_read(mem, pf.fourcc);
+ mem_read(mem, pf.bitcount);
+ mem_read(mem, pf.rmask);
+ mem_read(mem, pf.gmask);
+ mem_read(mem, pf.bmask);
+ mem_read(mem, pf.amask);
+}
+
+void mem_read(Stream & mem, DDSCaps & caps)
+{
+ mem_read(mem, caps.caps1);
+ mem_read(mem, caps.caps2);
+ mem_read(mem, caps.caps3);
+ mem_read(mem, caps.caps4);
+}
+
+void mem_read(Stream & mem, DDSHeader10 & header)
+{
+ mem_read(mem, header.dxgiFormat);
+ mem_read(mem, header.resourceDimension);
+ mem_read(mem, header.miscFlag);
+ mem_read(mem, header.arraySize);
+ mem_read(mem, header.reserved);
+}
+
+void mem_read(Stream & mem, DDSHeader & header)
+{
+ mem_read(mem, header.fourcc);
+ mem_read(mem, header.size);
+ mem_read(mem, header.flags);
+ mem_read(mem, header.height);
+ mem_read(mem, header.width);
+ mem_read(mem, header.pitch);
+ mem_read(mem, header.depth);
+ mem_read(mem, header.mipmapcount);
+ for (uint i = 0; i < 11; i++) mem_read(mem, header.reserved[i]);
+ mem_read(mem, header.pf);
+ mem_read(mem, header.caps);
+ mem_read(mem, header.notused);
+
+ if (header.hasDX10Header())
+ {
+ mem_read(mem, header.header10);
+ }
+}
+
+
+
+DDSHeader::DDSHeader()
+{
+ this->fourcc = FOURCC_DDS;
+ this->size = 124;
+ this->flags = (DDSD_CAPS|DDSD_PIXELFORMAT);
+ this->height = 0;
+ this->width = 0;
+ this->pitch = 0;
+ this->depth = 0;
+ this->mipmapcount = 0;
+ for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
+
+ // Store version information on the reserved header attributes.
+ this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T');
+ this->reserved[10] = (0 << 16) | (9 << 8) | (5); // major.minor.revision
+
+ this->pf.size = 32;
+ this->pf.flags = 0;
+ this->pf.fourcc = 0;
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
+ this->caps.caps1 = DDSCAPS_TEXTURE;
+ this->caps.caps2 = 0;
+ this->caps.caps3 = 0;
+ this->caps.caps4 = 0;
+ this->notused = 0;
+
+ this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN;
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN;
+ this->header10.miscFlag = 0;
+ this->header10.arraySize = 0;
+ this->header10.reserved = 0;
+}
+
+void DDSHeader::setWidth(uint w)
+{
+ this->flags |= DDSD_WIDTH;
+ this->width = w;
+}
+
+void DDSHeader::setHeight(uint h)
+{
+ this->flags |= DDSD_HEIGHT;
+ this->height = h;
+}
+
+void DDSHeader::setDepth(uint d)
+{
+ this->flags |= DDSD_DEPTH;
+ this->height = d;
+}
+
+void DDSHeader::setMipmapCount(uint count)
+{
+ if (count == 0 || count == 1)
+ {
+ this->flags &= ~DDSD_MIPMAPCOUNT;
+ this->mipmapcount = 0;
+
+ if (this->caps.caps2 == 0) {
+ this->caps.caps1 = DDSCAPS_TEXTURE;
+ }
+ else {
+ this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
+ }
+ }
+ else
+ {
+ this->flags |= DDSD_MIPMAPCOUNT;
+ this->mipmapcount = count;
+
+ this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
+ }
+}
+
+void DDSHeader::setTexture2D()
+{
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+}
+
+void DDSHeader::setTexture3D()
+{
+ this->caps.caps2 = DDSCAPS2_VOLUME;
+
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+}
+
+void DDSHeader::setTextureCube()
+{
+ this->caps.caps1 |= DDSCAPS_COMPLEX;
+ this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES;
+
+ this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ this->header10.arraySize = 6;
+}
+
+void DDSHeader::setLinearSize(uint size)
+{
+ this->flags &= ~DDSD_PITCH;
+ this->flags |= DDSD_LINEARSIZE;
+ this->pitch = size;
+}
+
+void DDSHeader::setPitch(uint pitch)
+{
+ this->flags &= ~DDSD_LINEARSIZE;
+ this->flags |= DDSD_PITCH;
+ this->pitch = pitch;
+}
+
+void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
+{
+ // set fourcc pixel format.
+ this->pf.flags = DDPF_FOURCC;
+ this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
+}
+
+void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
+{
+ // Make sure the masks are correct.
+ if ((rmask & gmask) || \
+ (rmask & bmask) || \
+ (rmask & amask) || \
+ (gmask & bmask) || \
+ (gmask & amask) || \
+ (bmask & amask)) {
+ printf("DDS: bad RGBA masks, pixel format not set\n");
+ return;
+ }
+
+ this->pf.flags = DDPF_RGB;
+
+ if (amask != 0) {
+ this->pf.flags |= DDPF_ALPHAPIXELS;
+ }
+
+ if (bitcount == 0)
+ {
+ // Compute bit count from the masks.
+ uint total = rmask | gmask | bmask | amask;
+ while(total != 0) {
+ bitcount++;
+ total >>= 1;
+ }
+ }
+
+ if (!(bitcount > 0 && bitcount <= 32)) {
+ printf("DDS: bad bit count, pixel format not set\n");
+ return;
+ }
+
+ // Align to 8.
+ if (bitcount < 8) bitcount = 8;
+ else if (bitcount < 16) bitcount = 16;
+ else if (bitcount < 24) bitcount = 24;
+ else bitcount = 32;
+
+ this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
+ this->pf.bitcount = bitcount;
+ this->pf.rmask = rmask;
+ this->pf.gmask = gmask;
+ this->pf.bmask = bmask;
+ this->pf.amask = amask;
+}
+
+void DDSHeader::setDX10Format(uint format)
+{
+ this->pf.flags = 0;
+ this->header10.dxgiFormat = format;
+}
+
+void DDSHeader::setNormalFlag(bool b)
+{
+ if (b) this->pf.flags |= DDPF_NORMAL;
+ else this->pf.flags &= ~DDPF_NORMAL;
+}
+
+bool DDSHeader::hasDX10Header() const
+{
+ return this->pf.flags == 0;
+}
+
+DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
+{
+ mem_read(stream, header);
+}
+
+DirectDrawSurface::~DirectDrawSurface()
+{
+}
+
+bool DirectDrawSurface::isValid() const
+{
+ if (header.fourcc != FOURCC_DDS || header.size != 124)
+ {
+ return false;
+ }
+
+ const uint required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT);
+ if( (header.flags & required) != required ) {
+ return false;
+ }
+
+ if (header.pf.size != 32) {
+ return false;
+ }
+
+ /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
+ /*
+ if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
+ return false;
+ }
+ */
+
+ return true;
+}
+
+bool DirectDrawSurface::isSupported() const
+{
+ if (header.pf.flags & DDPF_FOURCC)
+ {
+ if (header.pf.fourcc != FOURCC_DXT1 &&
+ header.pf.fourcc != FOURCC_DXT2 &&
+ header.pf.fourcc != FOURCC_DXT3 &&
+ header.pf.fourcc != FOURCC_DXT4 &&
+ header.pf.fourcc != FOURCC_DXT5 &&
+ header.pf.fourcc != FOURCC_RXGB &&
+ header.pf.fourcc != FOURCC_ATI1 &&
+ header.pf.fourcc != FOURCC_ATI2)
+ {
+ // Unknown fourcc code.
+ return false;
+ }
+ }
+ else if (header.pf.flags & DDPF_RGB)
+ {
+ // All RGB formats are supported now.
+ }
+ else
+ {
+ return false;
+ }
+
+ if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES)
+ {
+ // Cubemaps must contain all faces.
+ return false;
+ }
+
+ if (isTexture3D())
+ {
+ // @@ 3D textures not supported yet.
+ return false;
+ }
+
+ return true;
+}
+
+
+uint DirectDrawSurface::mipmapCount() const
+{
+ if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount;
+ else return 0;
+}
+
+
+uint DirectDrawSurface::width() const
+{
+ if (header.flags & DDSD_WIDTH) return header.width;
+ else return 1;
+}
+
+uint DirectDrawSurface::height() const
+{
+ if (header.flags & DDSD_HEIGHT) return header.height;
+ else return 1;
+}
+
+uint DirectDrawSurface::depth() const
+{
+ if (header.flags & DDSD_DEPTH) return header.depth;
+ else return 1;
+}
+
+bool DirectDrawSurface::hasAlpha() const
+{
+ if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
+ {
+ return false;
+ }
+ else if (header.pf.fourcc == FOURCC_DXT1)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool DirectDrawSurface::isTexture2D() const
+{
+ return !isTexture3D() && !isTextureCube();
+}
+
+bool DirectDrawSurface::isTexture3D() const
+{
+ return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
+}
+
+bool DirectDrawSurface::isTextureCube() const
+{
+ return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
+}
+
+void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
+{
+ stream.seek(offset(face, mipmap));
+
+ uint w = width();
+ uint h = height();
+
+ // Compute width and height.
+ for (uint m = 0; m < mipmap; m++)
+ {
+ w = max(1U, w / 2);
+ h = max(1U, h / 2);
+ }
+
+ img->allocate(w, h);
+
+ if (header.pf.flags & DDPF_RGB)
+ {
+ readLinearImage(img);
+ }
+ else if (header.pf.flags & DDPF_FOURCC)
+ {
+ readBlockImage(img);
+ }
+}
+
+void DirectDrawSurface::readLinearImage(Image * img)
+{
+
+ const uint w = img->width();
+ const uint h = img->height();
+
+ uint rshift, rsize;
+ PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
+
+ uint gshift, gsize;
+ PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
+
+ uint bshift, bsize;
+ PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
+
+ uint ashift, asize;
+ PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize);
+
+ uint byteCount = (header.pf.bitcount + 7) / 8;
+
+ if (byteCount > 4)
+ {
+ /* just in case... we could have segfaults later on if byteCount > 4 */
+ printf("DDS: bitcount too large");
+ return;
+ }
+
+ if (header.pf.amask != 0)
+ {
+ img->setFormat(Image::Format_ARGB);
+ }
+
+ // Read linear RGB images.
+ for (uint y = 0; y < h; y++)
+ {
+ for (uint x = 0; x < w; x++)
+ {
+ uint c = 0;
+ mem_read(stream, (unsigned char *)(&c), byteCount);
+
+ Color32 pixel(0, 0, 0, 0xFF);
+ pixel.r = PixelFormat::convert(c >> rshift, rsize, 8);
+ pixel.g = PixelFormat::convert(c >> gshift, gsize, 8);
+ pixel.b = PixelFormat::convert(c >> bshift, bsize, 8);
+ pixel.a = PixelFormat::convert(c >> ashift, asize, 8);
+
+ img->pixel(x, y) = pixel;
+ }
+ }
+}
+
+void DirectDrawSurface::readBlockImage(Image * img)
+{
+ const uint w = img->width();
+ const uint h = img->height();
+
+ const uint bw = (w + 3) / 4;
+ const uint bh = (h + 3) / 4;
+
+ for (uint by = 0; by < bh; by++)
+ {
+ for (uint bx = 0; bx < bw; bx++)
+ {
+ ColorBlock block;
+
+ // Read color block.
+ readBlock(&block);
+
+ // Write color block.
+ for (uint y = 0; y < min(4U, h-4*by); y++)
+ {
+ for (uint x = 0; x < min(4U, w-4*bx); x++)
+ {
+ img->pixel(4*bx+x, 4*by+y) = block.color(x, y);
+ }
+ }
+ }
+ }
+}
+
+static Color32 buildNormal(uint8 x, uint8 y)
+{
+ float nx = 2 * (x / 255.0f) - 1;
+ float ny = 2 * (y / 255.0f) - 1;
+ float nz = 0.0f;
+ if (1 - nx*nx - ny*ny > 0) nz = sqrt(1 - nx*nx - ny*ny);
+ uint8 z = clamp(int(255.0f * (nz + 1) / 2.0f), 0, 255);
+
+ return Color32(x, y, z);
+}
+
+
+void DirectDrawSurface::readBlock(ColorBlock * rgba)
+{
+ if (header.pf.fourcc == FOURCC_DXT1)
+ {
+ BlockDXT1 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (header.pf.fourcc == FOURCC_DXT2 ||
+ header.pf.fourcc == FOURCC_DXT3)
+ {
+ BlockDXT3 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (header.pf.fourcc == FOURCC_DXT4 ||
+ header.pf.fourcc == FOURCC_DXT5 ||
+ header.pf.fourcc == FOURCC_RXGB)
+ {
+ BlockDXT5 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+
+ if (header.pf.fourcc == FOURCC_RXGB)
+ {
+ // Swap R & A.
+ for (int i = 0; i < 16; i++)
+ {
+ Color32 & c = rgba->color(i);
+ uint tmp = c.r;
+ c.r = c.a;
+ c.a = tmp;
+ }
+ }
+ }
+ else if (header.pf.fourcc == FOURCC_ATI1)
+ {
+ BlockATI1 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+ else if (header.pf.fourcc == FOURCC_ATI2)
+ {
+ BlockATI2 block;
+ mem_read(stream, block);
+ block.decodeBlock(rgba);
+ }
+
+ // If normal flag set, convert to normal.
+ if (header.pf.flags & DDPF_NORMAL)
+ {
+ if (header.pf.fourcc == FOURCC_ATI2)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ Color32 & c = rgba->color(i);
+ c = buildNormal(c.r, c.g);
+ }
+ }
+ else if (header.pf.fourcc == FOURCC_DXT5)
+ {
+ for (int i = 0; i < 16; i++)
+ {
+ Color32 & c = rgba->color(i);
+ c = buildNormal(c.a, c.g);
+ }
+ }
+ }
+}
+
+
+uint DirectDrawSurface::blockSize() const
+{
+ switch(header.pf.fourcc)
+ {
+ case FOURCC_DXT1:
+ case FOURCC_ATI1:
+ return 8;
+ case FOURCC_DXT2:
+ case FOURCC_DXT3:
+ case FOURCC_DXT4:
+ case FOURCC_DXT5:
+ case FOURCC_RXGB:
+ case FOURCC_ATI2:
+ return 16;
+ };
+
+ // Not a block image.
+ return 0;
+}
+
+uint DirectDrawSurface::mipmapSize(uint mipmap) const
+{
+ uint w = width();
+ uint h = height();
+ uint d = depth();
+
+ for (uint m = 0; m < mipmap; m++)
+ {
+ w = max(1U, w / 2);
+ h = max(1U, h / 2);
+ d = max(1U, d / 2);
+ }
+
+ if (header.pf.flags & DDPF_FOURCC)
+ {
+ // @@ How are 3D textures aligned?
+ w = (w + 3) / 4;
+ h = (h + 3) / 4;
+ return blockSize() * w * h;
+ }
+ else if (header.pf.flags & DDPF_RGB)
+ {
+ // Align pixels to bytes.
+ uint byteCount = (header.pf.bitcount + 7) / 8;
+
+ // Align pitch to 4 bytes.
+ uint pitch = 4 * ((w * byteCount + 3) / 4);
+
+ return pitch * h * d;
+ }
+ else {
+ printf("DDS: mipmap format not supported\n");
+ return(0);
+ };
+}
+
+uint DirectDrawSurface::faceSize() const
+{
+ const uint count = mipmapCount();
+ uint size = 0;
+
+ for (uint m = 0; m < count; m++)
+ {
+ size += mipmapSize(m);
+ }
+
+ return size;
+}
+
+uint DirectDrawSurface::offset(const uint face, const uint mipmap)
+{
+ uint size = 128; //sizeof(DDSHeader);
+
+ if (face != 0)
+ {
+ size += face * faceSize();
+ }
+
+ for (uint m = 0; m < mipmap; m++)
+ {
+ size += mipmapSize(m);
+ }
+
+ return size;
+}
+
+
+void DirectDrawSurface::printInfo() const
+{
+ /* printf("FOURCC: %c%c%c%c\n", ((unsigned char *)&header.fourcc)[0], ((unsigned char *)&header.fourcc)[1], ((unsigned char *)&header.fourcc)[2], ((unsigned char *)&header.fourcc)[3]); */
+ printf("Flags: 0x%.8X\n", header.flags);
+ if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n");
+ if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n");
+ if (header.flags & DDSD_WIDTH) printf("\tDDSD_WIDTH\n");
+ if (header.flags & DDSD_HEIGHT) printf("\tDDSD_HEIGHT\n");
+ if (header.flags & DDSD_DEPTH) printf("\tDDSD_DEPTH\n");
+ if (header.flags & DDSD_PITCH) printf("\tDDSD_PITCH\n");
+ if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n");
+ if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n");
+
+ printf("Height: %d\n", header.height);
+ printf("Width: %d\n", header.width);
+ printf("Depth: %d\n", header.depth);
+ if (header.flags & DDSD_PITCH) printf("Pitch: %d\n", header.pitch);
+ else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %d\n", header.pitch);
+ printf("Mipmap count: %d\n", header.mipmapcount);
+
+ printf("Pixel Format:\n");
+ /* printf("\tSize: %d\n", header.pf.size); */
+ printf("\tFlags: 0x%.8X\n", header.pf.flags);
+ if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
+ if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
+ if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
+ if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED1) printf("\t\tDDPF_PALETTEINDEXED1\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED2) printf("\t\tDDPF_PALETTEINDEXED2\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED4) printf("\t\tDDPF_PALETTEINDEXED4\n");
+ if (header.pf.flags & DDPF_PALETTEINDEXED8) printf("\t\tDDPF_PALETTEINDEXED8\n");
+ if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
+ if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
+
+ printf("\tFourCC: '%c%c%c%c'\n", ((header.pf.fourcc >> 0) & 0xFF), ((header.pf.fourcc >> 8) & 0xFF), ((header.pf.fourcc >> 16) & 0xFF), ((header.pf.fourcc >> 24) & 0xFF));
+ printf("\tBit count: %d\n", header.pf.bitcount);
+ printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
+ printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
+ printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
+ printf("\tAlpha mask: 0x%.8X\n", header.pf.amask);
+
+ printf("Caps:\n");
+ printf("\tCaps 1: 0x%.8X\n", header.caps.caps1);
+ if (header.caps.caps1 & DDSCAPS_COMPLEX) printf("\t\tDDSCAPS_COMPLEX\n");
+ if (header.caps.caps1 & DDSCAPS_TEXTURE) printf("\t\tDDSCAPS_TEXTURE\n");
+ if (header.caps.caps1 & DDSCAPS_MIPMAP) printf("\t\tDDSCAPS_MIPMAP\n");
+
+ printf("\tCaps 2: 0x%.8X\n", header.caps.caps2);
+ if (header.caps.caps2 & DDSCAPS2_VOLUME) printf("\t\tDDSCAPS2_VOLUME\n");
+ else if (header.caps.caps2 & DDSCAPS2_CUBEMAP)
+ {
+ printf("\t\tDDSCAPS2_CUBEMAP\n");
+ if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n");
+ else {
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n");
+ if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n");
+ }
+ }
+
+ printf("\tCaps 3: 0x%.8X\n", header.caps.caps3);
+ printf("\tCaps 4: 0x%.8X\n", header.caps.caps4);
+
+ if (header.pf.flags == 0)
+ {
+ printf("DX10 Header:\n");
+ printf("\tDXGI Format: %u\n", header.header10.dxgiFormat);
+ printf("\tResource dimension: %u\n", header.header10.resourceDimension);
+ printf("\tMisc flag: %u\n", header.header10.miscFlag);
+ printf("\tArray size: %u\n", header.header10.arraySize);
+ }
+
+ if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T'))
+ {
+ int major = (header.reserved[10] >> 16) & 0xFF;
+ int minor = (header.reserved[10] >> 8) & 0xFF;
+ int revision= header.reserved[10] & 0xFF;
+
+ printf("Version:\n");
+ printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
+ }
+}
+
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
new file mode 100644
index 00000000000..d29d82f53f9
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -0,0 +1,181 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef _DDS_DIRECTDRAWSURFACE_H
+#define _DDS_DIRECTDRAWSURFACE_H
+
+#include <Common.h>
+#include <Stream.h>
+#include <ColorBlock.h>
+#include <Image.h>
+
+struct DDSPixelFormat
+{
+ uint size;
+ uint flags;
+ uint fourcc;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
+};
+
+struct DDSCaps
+{
+ uint caps1;
+ uint caps2;
+ uint caps3;
+ uint caps4;
+};
+
+/// DDS file header for DX10.
+struct DDSHeader10
+{
+ uint dxgiFormat;
+ uint resourceDimension;
+ uint miscFlag;
+ uint arraySize;
+ uint reserved;
+};
+
+/// DDS file header.
+struct DDSHeader
+{
+ uint fourcc;
+ uint size;
+ uint flags;
+ uint height;
+ uint width;
+ uint pitch;
+ uint depth;
+ uint mipmapcount;
+ uint reserved[11];
+ DDSPixelFormat pf;
+ DDSCaps caps;
+ uint notused;
+ DDSHeader10 header10;
+
+
+ // Helper methods.
+ DDSHeader();
+
+ void setWidth(uint w);
+ void setHeight(uint h);
+ void setDepth(uint d);
+ void setMipmapCount(uint count);
+ void setTexture2D();
+ void setTexture3D();
+ void setTextureCube();
+ void setLinearSize(uint size);
+ void setPitch(uint pitch);
+ void setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3);
+ void setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask);
+ void setDX10Format(uint format);
+ void setNormalFlag(bool b);
+
+ bool hasDX10Header() const;
+};
+
+/// DirectDraw Surface. (DDS)
+class DirectDrawSurface
+{
+public:
+ DirectDrawSurface(unsigned char *mem, uint size);
+ ~DirectDrawSurface();
+
+ bool isValid() const;
+ bool isSupported() const;
+
+ uint mipmapCount() const;
+ uint width() const;
+ uint height() const;
+ uint depth() const;
+ bool isTexture2D() const;
+ bool isTexture3D() const;
+ bool isTextureCube() const;
+ bool hasAlpha() const; /* false for DXT1, true for all other DXTs */
+
+ void mipmap(Image * img, uint f, uint m);
+ // void mipmap(FloatImage * img, uint f, uint m);
+
+ void printInfo() const;
+
+private:
+
+ uint blockSize() const;
+ uint faceSize() const;
+ uint mipmapSize(uint m) const;
+
+ uint offset(uint f, uint m);
+
+ void readLinearImage(Image * img);
+ void readBlockImage(Image * img);
+ void readBlock(ColorBlock * rgba);
+
+
+private:
+ Stream stream; // memory where DDS file resides
+ DDSHeader header;
+};
+
+void mem_read(Stream & mem, DDSPixelFormat & pf);
+void mem_read(Stream & mem, DDSCaps & caps);
+void mem_read(Stream & mem, DDSHeader & header);
+void mem_read(Stream & mem, DDSHeader10 & header);
+
+#endif // _DDS_DIRECTDRAWSURFACE_H
diff --git a/source/blender/imbuf/intern/dds/Image.cpp b/source/blender/imbuf/intern/dds/Image.cpp
new file mode 100644
index 00000000000..d8be7857c3f
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Image.cpp
@@ -0,0 +1,132 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#include <Color.h>
+#include <Image.h>
+
+#include <stdio.h> // printf
+
+Image::Image() : m_width(0), m_height(0), m_format(Format_RGB), m_data(0)
+{
+}
+
+Image::~Image()
+{
+ free();
+}
+
+void Image::allocate(uint w, uint h)
+{
+ free();
+ m_width = w;
+ m_height = h;
+ m_data = new Color32[w * h];
+}
+
+void Image::free()
+{
+ if (m_data) delete [] m_data;
+ m_data = 0;
+}
+
+
+uint Image::width() const
+{
+ return m_width;
+}
+
+uint Image::height() const
+{
+ return m_height;
+}
+
+const Color32 * Image::scanline(uint h) const
+{
+ if (h >= m_height) {
+ printf("DDS: scanline beyond dimensions of image");
+ return m_data;
+ }
+ return m_data + h * m_width;
+}
+
+Color32 * Image::scanline(uint h)
+{
+ if (h >= m_height) {
+ printf("DDS: scanline beyond dimensions of image");
+ return m_data;
+ }
+ return m_data + h * m_width;
+}
+
+const Color32 * Image::pixels() const
+{
+ return m_data;
+}
+
+Color32 * Image::pixels()
+{
+ return m_data;
+}
+
+const Color32 & Image::pixel(uint idx) const
+{
+ if (idx >= m_width * m_height) {
+ printf("DDS: pixel beyond dimensions of image");
+ return m_data[0];
+ }
+ return m_data[idx];
+}
+
+Color32 & Image::pixel(uint idx)
+{
+ if (idx >= m_width * m_height) {
+ printf("DDS: pixel beyond dimensions of image");
+ return m_data[0];
+ }
+ return m_data[idx];
+}
+
+
+Image::Format Image::format() const
+{
+ return m_format;
+}
+
+void Image::setFormat(Image::Format f)
+{
+ m_format = f;
+}
+
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
new file mode 100644
index 00000000000..0241839d01d
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Image.h
@@ -0,0 +1,104 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// This code is in the public domain -- castanyo@yahoo.es
+
+#ifndef _DDS_IMAGE_H
+#define _DDS_IMAGE_H
+
+#include <Common.h>
+#include <Color.h>
+
+/// 32 bit RGBA image.
+class Image
+{
+public:
+
+ enum Format
+ {
+ Format_RGB,
+ Format_ARGB,
+ };
+
+ Image();
+ ~Image();
+
+ void allocate(uint w, uint h);
+ /*
+ bool load(const char * name);
+
+ void wrap(void * data, uint w, uint h);
+ void unwrap();
+ */
+
+ uint width() const;
+ uint height() const;
+
+ const Color32 * scanline(uint h) const;
+ Color32 * scanline(uint h);
+
+ const Color32 * pixels() const;
+ Color32 * pixels();
+
+ const Color32 & pixel(uint idx) const;
+ Color32 & pixel(uint idx);
+
+ const Color32 & pixel(uint x, uint y) const;
+ Color32 & pixel(uint x, uint y);
+
+ Format format() const;
+ void setFormat(Format f);
+
+private:
+ void free();
+
+private:
+ uint m_width;
+ uint m_height;
+ Format m_format;
+ Color32 * m_data;
+};
+
+
+inline const Color32 & Image::pixel(uint x, uint y) const
+{
+ return pixel(y * width() + x);
+}
+
+inline Color32 & Image::pixel(uint x, uint y)
+{
+ return pixel(y * width() + x);
+}
+
+#endif // _DDS_IMAGE_H
diff --git a/intern/action/intern/Makefile b/source/blender/imbuf/intern/dds/Makefile
index 29f82bb7c0d..88d59080a47 100644
--- a/intern/action/intern/Makefile
+++ b/source/blender/imbuf/intern/dds/Makefile
@@ -1,5 +1,5 @@
#
-# $Id$
+# $Id: Makefile 7037 2006-03-12 14:11:23Z ton $
#
# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
#
@@ -28,15 +28,36 @@
# Contributor(s): none yet.
#
# ***** END GPL/BL DUAL LICENSE BLOCK *****
-# action intern Makefile
+#
#
-LIBNAME = action
-DIR = $(OCGDIR)/intern/$(LIBNAME)
+LIBNAME = dds
+DIR = $(OCGDIR)/blender/imbuf/dds
+SOURCEDIR = source/blender/imbuf/intern/dds
include nan_compile.mk
+include nan_definitions.mk
-CPPFLAGS += -I..
-CPPFLAGS += -I$(NAN_STRING)/include
-CPPFLAGS += -I$(NAN_MEMUTIL)/include
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+CPPFLAGS += -I$(NAN_JPEG)/include
+CPPFLAGS += -I$(NAN_PNG)/include
+CPPFLAGS += -I$(NAN_ZLIB)/include
+CPPFLAGS += -I$(NAN_TIFF)/include
+CPPFLAGS += -I../../../include
+CPPFLAGS += -I../../../blenkernel
+CPPFLAGS += -I../../../blenlib
+CPPFLAGS += -I../../../avi
+CPPFLAGS += -I../../../quicktime
+# path to the guarded memory allocator
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_MEMUTIL)/include
+# This is not really needed, but until /include is cleaned, it must be
+# there for proper compilation.
+# - No, it is also needed in antialias, for listbase (nzc)
+CPPFLAGS += -I../../../makesdna
+# external interface of this module
+CPPFLAGS += -I../..
+CPPFLAGS += -I..
+CPPFLAGS += -I.
+CPPFLAGS += -DWITH_DDS
diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h
new file mode 100644
index 00000000000..93f55f8266a
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/PixelFormat.h
@@ -0,0 +1,110 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/*
+ * This file is based on a similar file from the NVIDIA texture tools
+ * (http://nvidia-texture-tools.googlecode.com/)
+ *
+ * Original license from NVIDIA follows.
+ */
+
+// Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef _DDS_PIXELFORMAT_H
+#define _DDS_PIXELFORMAT_H
+
+#include <Common.h>
+
+ namespace PixelFormat
+ {
+
+ // Convert component @a c having @a inbits to the returned value having @a outbits.
+ inline uint convert(uint c, uint inbits, uint outbits)
+ {
+ if (inbits == 0)
+ {
+ return 0;
+ }
+ else if (inbits >= outbits)
+ {
+ // truncate
+ return c >> (inbits - outbits);
+ }
+ else
+ {
+ // bitexpand
+ return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
+ }
+ }
+
+ // Get pixel component shift and size given its mask.
+ inline void maskShiftAndSize(uint mask, uint * shift, uint * size)
+ {
+ if (!mask)
+ {
+ *shift = 0;
+ *size = 0;
+ return;
+ }
+
+ *shift = 0;
+ while((mask & 1) == 0) {
+ ++(*shift);
+ mask >>= 1;
+ }
+
+ *size = 0;
+ while((mask & 1) == 1) {
+ ++(*size);
+ mask >>= 1;
+ }
+ }
+
+ } // PixelFormat namespace
+
+#endif // _DDS_IMAGE_PIXELFORMAT_H
diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript
new file mode 100644
index 00000000000..d005bae02be
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/SConscript
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+Import ('env')
+
+source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp']
+
+incs = ['.',
+ '../../',
+ '../..',
+ '..',
+ '../../../makesdna',
+ '../../../blenkernel',
+ '../../../blenlib',
+ 'intern/include',
+ '#/intern/guardedalloc']
+
+
+defs = ['WITH_DDS']
+
+env.BlenderLib ('bf_dds', source_files, incs, defs, libtype=['core','player'], priority = [90, 200])
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
new file mode 100644
index 00000000000..2340598b4fa
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -0,0 +1,99 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <Stream.h>
+
+#include <stdio.h> // printf
+#include <string.h> // memcpy
+
+unsigned int Stream::seek(unsigned int p)
+{
+ if (p > size) {
+ printf("DDS: trying to seek beyond end of stream (corrupt file?)");
+ }
+ else {
+ pos = p;
+ }
+
+ return pos;
+}
+
+unsigned int mem_read(Stream & mem, unsigned long long & i)
+{
+ if (mem.pos + 8 > mem.size) {
+ printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ return(0);
+ };
+ memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
+ mem.pos += 8;
+ return(8);
+}
+
+unsigned int mem_read(Stream & mem, unsigned int & i)
+{
+ if (mem.pos + 4 > mem.size) {
+ printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ return(0);
+ };
+ memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
+ mem.pos += 4;
+ return(4);
+}
+
+unsigned int mem_read(Stream & mem, unsigned short & i)
+{
+ if (mem.pos + 2 > mem.size) {
+ printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ return(0);
+ };
+ memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
+ mem.pos += 2;
+ return(2);
+}
+
+unsigned int mem_read(Stream & mem, unsigned char & i)
+{
+ if (mem.pos + 1 > mem.size) {
+ printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ return(0);
+ };
+ i = (mem.mem + mem.pos)[0];
+ mem.pos += 1;
+ return(1);
+}
+
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
+{
+ if (mem.pos + cnt > mem.size) {
+ printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ return(0);
+ };
+ memcpy(i, mem.mem + mem.pos, cnt);
+ mem.pos += cnt;
+ return(cnt);
+}
+
diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h
new file mode 100644
index 00000000000..373e68db44e
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/Stream.h
@@ -0,0 +1,49 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/* simple memory stream functions with buffer overflow check */
+
+#ifndef _STREAM_H
+#define _STREAM_H
+
+struct Stream
+{
+ unsigned char *mem; // location in memory
+ unsigned int size; // size
+ unsigned int pos; // current position
+ Stream(unsigned char *m, unsigned int s) : mem(m), size(s), pos(0) {};
+ unsigned int seek(unsigned int p);
+};
+
+unsigned int mem_read(Stream & mem, unsigned long long & i);
+unsigned int mem_read(Stream & mem, unsigned int & i);
+unsigned int mem_read(Stream & mem, unsigned short & i);
+unsigned int mem_read(Stream & mem, unsigned char & i);
+unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt);
+
+#endif // _STREAM_H
+
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
new file mode 100644
index 00000000000..3de30b9f183
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -0,0 +1,132 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <dds_api.h>
+#include <Stream.h>
+#include <DirectDrawSurface.h>
+#include <stdio.h> // printf
+#include <fstream>
+
+extern "C" {
+
+#include "imbuf.h"
+#include "imbuf_patch.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_allocimbuf.h"
+
+
+short imb_save_dds(struct ImBuf * ibuf, char *name, int flags)
+{
+ return(0); /* todo: finish this function */
+
+ /* check image buffer */
+ if (ibuf == 0) return (0);
+ if (ibuf->rect == 0) return (0);
+
+ /* open file for writing */
+ std::ofstream fildes(name);
+
+ /* write header */
+ fildes << "DDS ";
+ fildes.close();
+
+ return(1);
+}
+
+int imb_is_a_dds(unsigned char *mem) // note: use at most first 32 bytes
+{
+ /* heuristic check to see if mem contains a DDS file */
+ /* header.fourcc == FOURCC_DDS */
+ if ((mem[0] != 'D') || (mem[1] != 'D') || (mem[2] != 'S') || (mem[3] != ' ')) return(0);
+ /* header.size == 124 */
+ if ((mem[4] != 124) || mem[5] || mem[6] || mem[7]) return(0);
+ return(1);
+}
+
+struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags)
+{
+ struct ImBuf * ibuf = 0;
+ DirectDrawSurface dds(mem, size); /* reads header */
+ unsigned char bits_per_pixel;
+ unsigned int *rect;
+ Image img;
+ unsigned int numpixels = 0;
+ int col;
+ unsigned char *cp = (unsigned char *) &col;
+ Color32 pixel;
+ Color32 *pixels = 0;
+
+ /* check if DDS is valid and supported */
+ if (!dds.isValid()) {
+ printf("DDS: not valid; header follows\n");
+ dds.printInfo();
+ return(0);
+ }
+ if (!dds.isSupported()) {
+ printf("DDS: format not supported\n");
+ return(0);
+ }
+ if ((dds.width() > 65535) || (dds.height() > 65535)) {
+ printf("DDS: dimensions too large\n");
+ return(0);
+ }
+
+ /* convert DDS into ImBuf */
+ if (dds.hasAlpha()) bits_per_pixel = 32;
+ else bits_per_pixel = 24;
+ ibuf = IMB_allocImBuf(dds.width(), dds.height(), bits_per_pixel, 0, 0);
+ if (ibuf == 0) return(0); /* memory allocation failed */
+
+ ibuf->ftype = DDS;
+
+ if ((flags & IB_test) == 0) {
+ if (!imb_addrectImBuf(ibuf)) return(ibuf);
+ if (ibuf->rect == 0) return(ibuf);
+
+ rect = ibuf->rect;
+ dds.mipmap(&img, 0, 0); /* load first face, first mipmap */
+ pixels = img.pixels();
+ numpixels = dds.width() * dds.height();
+ cp[3] = 0xff; /* default alpha if alpha channel is not present */
+
+ for (unsigned int i = 0; i < numpixels; i++) {
+ pixel = pixels[i];
+ cp[0] = pixel.r; /* set R component of col */
+ cp[1] = pixel.g; /* set G component of col */
+ cp[2] = pixel.b; /* set B component of col */
+ if (bits_per_pixel == 32)
+ cp[3] = pixel.a; /* set A component of col */
+ rect[i] = col;
+ }
+ IMB_flipy(ibuf);
+ }
+
+ return(ibuf);
+}
+
+} // extern "C"
diff --git a/source/blender/imbuf/intern/dds/dds_api.h b/source/blender/imbuf/intern/dds/dds_api.h
new file mode 100644
index 00000000000..8a0f966dd68
--- /dev/null
+++ b/source/blender/imbuf/intern/dds/dds_api.h
@@ -0,0 +1,43 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * Contributors: Amorilia (amorilia@gamebox.net)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef _DDS_API_H
+#define _DDS_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+short imb_save_dds(struct ImBuf *ibuf, char *name, int flags);
+int imb_is_a_dds(unsigned char *mem); /* use only first 32 bytes of mem */
+struct ImBuf *imb_load_dds(unsigned char *mem, int size, int flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DDS_API_H */
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index a4fab4a3572..8db07f581f5 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -174,7 +174,7 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
}
}
-#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.99f*val))
void IMB_rect_from_float(struct ImBuf *ibuf)
{
diff --git a/source/blender/imbuf/intern/dynlibtiff.c b/source/blender/imbuf/intern/dynlibtiff.c
index cdcb995bcff..4a96af8bf2b 100644
--- a/source/blender/imbuf/intern/dynlibtiff.c
+++ b/source/blender/imbuf/intern/dynlibtiff.c
@@ -83,13 +83,19 @@ void libtiff_loadlibtiff(void)
/* Try to find libtiff in a couple of standard places */
libtiff = PIL_dynlib_open("libtiff.so");
if (libtiff != NULL) return;
+ libtiff = PIL_dynlib_open("libtiff.so.3");
+ if (libtiff != NULL) return;
libtiff = PIL_dynlib_open("libtiff.dll");
if (libtiff != NULL) return;
libtiff = PIL_dynlib_open("/usr/lib/libtiff.so");
if (libtiff != NULL) return;
- /* OSX has version specific library */
libtiff = PIL_dynlib_open("/usr/lib/libtiff.so.3");
if (libtiff != NULL) return;
+ /* OSX has version specific library */
+#ifdef __x86_64__
+ libtiff = PIL_dynlib_open("/usr/lib64/libtiff.so.3");
+ if (libtiff != NULL) return;
+#endif
libtiff = PIL_dynlib_open("/usr/local/lib/libtiff.so");
if (libtiff != NULL) return;
/* For solaris */
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index fd9dac1af2b..1be5cf99e19 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -240,18 +240,72 @@ void IMB_filter(struct ImBuf *ibuf)
imb_filterx(ibuf);
}
-#define EXTEND_PIXEL(a, w) if((a)[3]) {r+= w*(a)[0]; g+= w*(a)[1]; b+= w*(a)[2]; tot+=w;}
+#define EXTEND_PIXEL(color, w) if((color)[3]) {r+= w*(color)[0]; g+= w*(color)[1]; b+= w*(color)[2]; a+= w*(color)[3]; tot+=w;}
-/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 255 */
-void IMB_filter_extend(struct ImBuf *ibuf)
+/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
+ *
+ * When a mask is given, only effect pixels with a mask value of 1, defined as BAKE_MASK_MARGIN in rendercore.c
+ * */
+void IMB_filter_extend(struct ImBuf *ibuf, char *mask)
{
register char *row1, *row2, *row3;
- register char *cp;
+ register char *cp;
int rowlen, x, y;
rowlen= ibuf->x;
- if(ibuf->rect) {
+
+ if (ibuf->rect_float) {
+ float *temprect;
+ float *row1f, *row2f, *row3f;
+ float *fp;
+ temprect= MEM_dupallocN(ibuf->rect_float);
+
+ for(y=1; y<=ibuf->y; y++) {
+ /* setup rows */
+ row1f= (float *)(temprect + (y-2)*rowlen*4);
+ row2f= row1f + 4*rowlen;
+ row3f= row2f + 4*rowlen;
+ if(y==1)
+ row1f= row2f;
+ else if(y==ibuf->y)
+ row3f= row2f;
+
+ fp= (float *)(ibuf->rect_float + (y-1)*rowlen*4);
+
+ for(x=0; x<rowlen; x++) {
+ if((mask==NULL && fp[3]==0.0f) || (mask && mask[((y-1)*rowlen)+x]==1)) {
+ int tot= 0;
+ float r=0.0f, g=0.0f, b=0.0f, a=0.0f;
+
+ EXTEND_PIXEL(row1f, 1);
+ EXTEND_PIXEL(row2f, 2);
+ EXTEND_PIXEL(row3f, 1);
+ EXTEND_PIXEL(row1f+4, 2);
+ EXTEND_PIXEL(row3f+4, 2);
+ if(x!=rowlen-1) {
+ EXTEND_PIXEL(row1f+8, 1);
+ EXTEND_PIXEL(row2f+8, 2);
+ EXTEND_PIXEL(row3f+8, 1);
+ }
+ if(tot) {
+ fp[0]= r/tot;
+ fp[1]= g/tot;
+ fp[2]= b/tot;
+ fp[3]= a/tot;
+ }
+ }
+ fp+=4;
+
+ if(x!=0) {
+ row1f+=4; row2f+=4; row3f+=4;
+ }
+ }
+ }
+
+ MEM_freeN(temprect);
+ }
+ else if(ibuf->rect) {
int *temprect;
/* make a copy, to prevent flooding */
@@ -270,8 +324,9 @@ void IMB_filter_extend(struct ImBuf *ibuf)
cp= (char *)(ibuf->rect + (y-1)*rowlen);
for(x=0; x<rowlen; x++) {
- if(cp[3]==0) {
- int tot= 0, r=0, g=0, b=0;
+ /*if(cp[3]==0) {*/
+ if((mask==NULL && cp[3]==0) || (mask && mask[((y-1)*rowlen)+x]==1)) {
+ int tot= 0, r=0, g=0, b=0, a=0;
EXTEND_PIXEL(row1, 1);
EXTEND_PIXEL(row2, 2);
@@ -287,10 +342,10 @@ void IMB_filter_extend(struct ImBuf *ibuf)
cp[0]= r/tot;
cp[1]= g/tot;
cp[2]= b/tot;
- cp[3]= 255;
+ cp[3]= a/tot;
}
}
- cp+=4;
+ cp+=4;
if(x!=0) {
row1+=4; row2+=4; row3+=4;
diff --git a/source/blender/imbuf/intern/gen_dynlibtiff.py b/source/blender/imbuf/intern/gen_dynlibtiff.py
index 1ee0275854a..de3236da6c2 100755
--- a/source/blender/imbuf/intern/gen_dynlibtiff.py
+++ b/source/blender/imbuf/intern/gen_dynlibtiff.py
@@ -125,13 +125,19 @@ void libtiff_loadlibtiff(void)
/* Try to find libtiff in a couple of standard places */
libtiff = PIL_dynlib_open("libtiff.so");
if (libtiff != NULL) return;
+ libtiff = PIL_dynlib_open("libtiff.so.3");
+ if (libtiff != NULL) return;
libtiff = PIL_dynlib_open("libtiff.dll");
if (libtiff != NULL) return;
libtiff = PIL_dynlib_open("/usr/lib/libtiff.so");
if (libtiff != NULL) return;
- /* OSX has version specific library */
libtiff = PIL_dynlib_open("/usr/lib/libtiff.so.3");
if (libtiff != NULL) return;
+ /* OSX has version specific library */
+#ifdef __x86_64__
+ libtiff = PIL_dynlib_open("/usr/lib64/libtiff.so.3");
+ if (libtiff != NULL) return;
+#endif
libtiff = PIL_dynlib_open("/usr/local/lib/libtiff.so");
if (libtiff != NULL) return;
/* For solaris */
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index f98244c5a0f..aa09fc3ee38 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -42,26 +42,37 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "math.h"
+
+/* This define should be relocated to a global header some where Kent Mein
+I stole it from util.h in the plugins api */
+#define MAX2(x,y) ( (x)>(y) ? (x) : (y) )
/* Only this one is used liberally here, and in imbuf */
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
{
- int size, do_float=0;
+ int size;
unsigned char rt, *cp = (unsigned char *)ibuf->rect;
float rtf, *cpf = ibuf->rect_float;
-
- if (ibuf->rect_float) do_float = 1;
- size = ibuf->x * ibuf->y;
-
- while(size-- > 0) {
- rt= cp[0];
- cp[0]= cp[3];
- cp[3]= rt;
- rt= cp[1];
- cp[1]= cp[2];
- cp[2]= rt;
- cp+= 4;
- if (do_float) {
+
+ if (ibuf->rect) {
+ size = ibuf->x * ibuf->y;
+
+ while(size-- > 0) {
+ rt= cp[0];
+ cp[0]= cp[3];
+ cp[3]= rt;
+ rt= cp[1];
+ cp[1]= cp[2];
+ cp[2]= rt;
+ cp+= 4;
+ }
+ }
+
+ if (ibuf->rect_float) {
+ size = ibuf->x * ibuf->y;
+
+ while(size-- > 0) {
rtf= cpf[0];
cpf[0]= cpf[3];
cpf[3]= rtf;
@@ -73,3 +84,224 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
}
}
+/**************************************************************************
+* INTERPOLATIONS
+*
+* Reference and docs:
+* http://wiki.blender.org/index.php/User:Damiles#Interpolations_Algorithms
+***************************************************************************/
+
+/* BICUBIC Interpolation functions */
+/* More info: http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation
+*/
+/* function assumes out to be zero'ed, only does RGBA */
+static float P(float k){
+ float aux;
+ aux=(float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
+ return aux ;
+}
+
+void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
+{
+ int i,j,n,m,x1,y1;
+ unsigned char *dataI,*outI;
+ float a,b, outR,outG,outB,outA,*dataF,*outF;
+ int do_rect, do_float;
+
+ if (in == NULL) return;
+ if (in->rect == NULL && in->rect_float == NULL) return;
+
+ do_rect= (out->rect != NULL);
+ do_float= (out->rect_float != NULL);
+
+ i= (int)floor(x);
+ j= (int)floor(y);
+ a= x - i;
+ b= y - j;
+
+ outR= 0.0f;
+ outG= 0.0f;
+ outB= 0.0f;
+ outA= 0.0f;
+ for(n= -1; n<= 2; n++){
+ for(m= -1; m<= 2; m++){
+ x1= i+n;
+ y1= j+m;
+ if (x1>0 && x1 < in->x && y1>0 && y1<in->y) {
+ if (do_float) {
+ dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
+ outR+= dataF[0] * P(n-a) * P(b-m);
+ outG+= dataF[1] * P(n-a) * P(b-m);
+ outB+= dataF[2] * P(n-a) * P(b-m);
+ outA+= dataF[3] * P(n-a) * P(b-m);
+ }
+ if (do_rect) {
+ dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
+ outR+= dataI[0] * P(n-a) * P(b-m);
+ outG+= dataI[1] * P(n-a) * P(b-m);
+ outB+= dataI[2] * P(n-a) * P(b-m);
+ outA+= dataI[3] * P(n-a) * P(b-m);
+ }
+ }
+ }
+ }
+ if (do_rect) {
+ outI= (unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
+ outI[0]= (int)outR;
+ outI[1]= (int)outG;
+ outI[2]= (int)outB;
+ outI[3]= (int)outA;
+ }
+ if (do_float) {
+ outF= (float *)out->rect_float + out->x * yout * 4 + 4*xout;
+ outF[0]= outR;
+ outF[1]= outG;
+ outF[2]= outB;
+ outF[3]= outA;
+ }
+}
+
+/* function assumes out to be zero'ed, only does RGBA */
+/* BILINEAR INTERPOLATION */
+void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
+{
+ float *row1, *row2, *row3, *row4, a, b, *outF;
+ unsigned char *row1I, *row2I, *row3I, *row4I, *outI;
+ float a_b, ma_b, a_mb, ma_mb;
+ float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+ unsigned char emptyI[4]= {0, 0, 0, 0};
+ int y1, y2, x1, x2;
+ int do_rect, do_float;
+
+ if (in==NULL) return;
+ if (in->rect==NULL && in->rect_float==NULL) return;
+
+ do_rect= (out->rect != NULL);
+ do_float= (out->rect_float != NULL);
+
+ x1= (int)floor(u);
+ x2= (int)ceil(u);
+ y1= (int)floor(v);
+ y2= (int)ceil(v);
+
+ // sample area entirely outside image?
+ if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return;
+
+ if (do_rect)
+ outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
+ else
+ outI= NULL;
+ if (do_float)
+ outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
+ else
+ outF= NULL;
+
+ if (do_float) {
+ // sample including outside of edges of image
+ if (x1<0 || y1<0) row1= empty;
+ else row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1;
+
+ if (x1<0 || y2>in->y-1) row2= empty;
+ else row2= (float *)in->rect_float + in->x * y2 * 4 + 4*x1;
+
+ if (x2>in->x-1 || y1<0) row3= empty;
+ else row3= (float *)in->rect_float + in->x * y1 * 4 + 4*x2;
+
+ if (x2>in->x-1 || y2>in->y-1) row4= empty;
+ else row4= (float *)in->rect_float + in->x * y2 * 4 + 4*x2;
+
+ a= u-floor(u);
+ b= v-floor(v);
+ a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+
+ outF[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0];
+ outF[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1];
+ outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
+ outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
+ }
+ if (do_rect) {
+ // sample including outside of edges of image
+ if (x1<0 || y1<0) row1I= emptyI;
+ else row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
+
+ if (x1<0 || y2>in->y-1) row2I= emptyI;
+ else row2I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x1;
+
+ if (x2>in->x-1 || y1<0) row3I= emptyI;
+ else row3I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x2;
+
+ if (x2>in->x-1 || y2>in->y-1) row4I= emptyI;
+ else row4I= (unsigned char *)in->rect + in->x * y2 * 4 + 4*x2;
+
+ a= u-floor(u);
+ b= v-floor(v);
+ a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
+
+ outI[0]= ma_mb*row1I[0] + a_mb*row3I[0] + ma_b*row2I[0]+ a_b*row4I[0];
+ outI[1]= ma_mb*row1I[1] + a_mb*row3I[1] + ma_b*row2I[1]+ a_b*row4I[1];
+ outI[2]= ma_mb*row1I[2] + a_mb*row3I[2] + ma_b*row2I[2]+ a_b*row4I[2];
+ outI[3]= ma_mb*row1I[3] + a_mb*row3I[3] + ma_b*row2I[3]+ a_b*row4I[3];
+ }
+}
+
+/* function assumes out to be zero'ed, only does RGBA */
+/* NEAREST INTERPOLATION */
+void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, int yout)
+{
+ float *outF,*dataF;
+ unsigned char *dataI,*outI;
+ int y1, x1;
+ int do_rect, do_float;
+
+ if (in==NULL) return;
+ if (in->rect==NULL && in->rect_float==NULL) return;
+
+ do_rect= (out->rect != NULL);
+ do_float= (out->rect_float != NULL);
+
+ x1= (int)(u);
+ y1= (int)(v);
+
+ if (do_rect)
+ outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout;
+ else
+ outI= NULL;
+ if (do_float)
+ outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout;
+ else
+ outF= NULL;
+
+ // sample area entirely outside image?
+ if (x1<0 || x1>in->x-1 || y1<0 || y1>in->y-1) return;
+
+ // sample including outside of edges of image
+ if (x1<0 || y1<0) {
+ if (do_rect) {
+ outI[0]= 0;
+ outI[1]= 0;
+ outI[2]= 0;
+ outI[3]= 0;
+ }
+ if (do_float) {
+ outF[0]= 0.0f;
+ outF[1]= 0.0f;
+ outF[2]= 0.0f;
+ outF[3]= 0.0f;
+ }
+ } else {
+ dataI= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1;
+ if (do_rect) {
+ outI[0]= dataI[0];
+ outI[1]= dataI[1];
+ outI[2]= dataI[2];
+ outI[3]= dataI[3];
+ }
+ dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
+ if (do_float) {
+ outF[0]= dataF[0];
+ outF[1]= dataF[1];
+ outF[2]= dataF[2];
+ outF[3]= dataF[3];
+ }
+ }
+}
diff --git a/source/blender/imbuf/intern/imginfo.c b/source/blender/imbuf/intern/imginfo.c
new file mode 100644
index 00000000000..37bde9e5ac3
--- /dev/null
+++ b/source/blender/imbuf/intern/imginfo.c
@@ -0,0 +1,158 @@
+/**
+ * $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) 2005 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Austin Benesh. Ton Roosendaal.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "BLI_blenlib.h"
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "IMB_imginfo.h"
+
+
+
+void IMB_imginfo_free(struct ImBuf* img)
+{
+ ImgInfo *info;
+
+ if (!img)
+ return;
+ if (!img->img_info) {
+ return;
+ }
+ info = img->img_info;
+ while (info) {
+ ImgInfo* next = info->next;
+ MEM_freeN(info->key);
+ MEM_freeN(info->value);
+ MEM_freeN(info);
+ info = next;
+ }
+}
+
+int IMB_imginfo_get_field(struct ImBuf* img, const char* key, char* field, int len)
+{
+ ImgInfo *info;
+ int retval = 0;
+
+ if (!img)
+ return 0;
+ if (!img->img_info) {
+ return 0;
+ }
+ info = img->img_info;
+ while (info) {
+ if (strcmp(key, info->key) == 0) {
+ BLI_strncpy(field, info->value, len);
+ retval = 1;
+ break;
+ }
+ info = info->next;
+ }
+ return retval;
+}
+
+int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field)
+{
+ ImgInfo *info;
+ ImgInfo *last;
+
+ if (!img)
+ return 0;
+
+ if (!img->img_info) {
+ img->img_info = MEM_callocN(sizeof(ImgInfo), "ImgInfo");
+ info = img->img_info;
+ } else {
+ info = img->img_info;
+ last = info;
+ while (info) {
+ last = info;
+ info = info->next;
+ }
+ info = MEM_callocN(sizeof(ImgInfo), "ImgInfo");
+ last->next = info;
+ }
+ info->key = BLI_strdup(key);
+ info->value = BLI_strdup(field);
+ return 1;
+}
+
+int IMB_imginfo_del_field(struct ImBuf *img, const char *key)
+{
+ ImgInfo *p, *p1;
+
+ if ((!img) || (!img->img_info))
+ return (0);
+
+ p = img->img_info;
+ p1 = NULL;
+ while (p) {
+ if (!strcmp (key, p->key)) {
+ if (p1)
+ p1->next = p->next;
+ else
+ img->img_info = p->next;
+
+ MEM_freeN(p->key);
+ MEM_freeN(p->value);
+ MEM_freeN(p);
+ return (1);
+ }
+ p1 = p;
+ p = p->next;
+ }
+ return (0);
+}
+
+int IMB_imginfo_change_field(struct ImBuf *img, const char *key, const char *field)
+{
+ ImgInfo *p;
+
+ if (!img)
+ return (0);
+
+ if (!img->img_info)
+ return (IMB_imginfo_add_field (img, key, field));
+
+ p = img->img_info;
+ while (p) {
+ if (!strcmp (key, p->key)) {
+ MEM_freeN (p->value);
+ p->value = BLI_strdup (field);
+ return (1);
+ }
+ p = p->next;
+ }
+
+ return (IMB_imginfo_add_field (img, key, field));
+}
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index cd90adda27a..eab07c19265 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -41,6 +41,7 @@
#include "imbuf_patch.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "IMB_imginfo.h"
#include "IMB_jpeg.h"
#include "jpeglib.h"
@@ -244,11 +245,14 @@ static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int f
int x, y, depth, r, g, b, k;
struct ImBuf * ibuf = 0;
uchar * rect;
+ jpeg_saved_marker_ptr marker;
+ char *str, *key, *value;
/* install own app1 handler */
ibuf_ftype = 0;
jpeg_set_marker_processor(cinfo, 0xe1, handle_app1);
cinfo->dct_method = JDCT_FLOAT;
+ jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) {
x = cinfo->image_width;
@@ -335,6 +339,64 @@ static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int f
}
}
}
+
+ marker= cinfo->marker_list;
+ while(marker) {
+ if(marker->marker != JPEG_COM)
+ goto next_stamp_marker;
+
+ /*
+ * Because JPEG format don't support the
+ * pair "key/value" like PNG, we store the
+ * stampinfo in a single "encode" string:
+ * "Blender:key:value"
+ *
+ * That is why we need split it to the
+ * common key/value here.
+ */
+ if(strncmp((char *) marker->data, "Blender", 7)) {
+ /*
+ * Maybe the file have text that
+ * we don't know "what it's", in that
+ * case we keep the text (with a
+ * key "None").
+ * This is only for don't "lose"
+ * the information when we write
+ * it back to disk.
+ */
+ IMB_imginfo_add_field(ibuf, "None", (char *) marker->data);
+ ibuf->flags |= IB_imginfo;
+ goto next_stamp_marker;
+ }
+
+ str = BLI_strdup ((char *) marker->data);
+ key = strchr (str, ':');
+ /*
+ * A little paranoid, but the file maybe
+ * is broken... and a "extra" check is better
+ * that a segfaul ;)
+ */
+ if (!key) {
+ MEM_freeN(str);
+ goto next_stamp_marker;
+ }
+
+ key++;
+ value = strchr (key, ':');
+ if (!value) {
+ MEM_freeN(str);
+ goto next_stamp_marker;
+ }
+
+ *value = '\0'; /* need finish the key string */
+ value++;
+ IMB_imginfo_add_field(ibuf, key, value);
+ ibuf->flags |= IB_imginfo;
+ MEM_freeN(str);
+next_stamp_marker:
+ marker= marker->next;
+ }
+
jpeg_finish_decompress(cinfo);
}
@@ -345,7 +407,7 @@ static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int f
return(ibuf);
}
-ImBuf * imb_ibJpegImageFromFilename (char * filename, int flags)
+ImBuf * imb_ibJpegImageFromFilename (const char * filename, int flags)
{
struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
struct jpeg_error_mgr jerr;
@@ -391,7 +453,8 @@ static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf)
uchar * rect;
int x, y;
char neogeo[128];
-
+ ImgInfo *iptr;
+ char *text;
jpeg_start_compress(cinfo, TRUE);
@@ -401,6 +464,33 @@ static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf)
memcpy(neogeo + 6, &ibuf_ftype, 4);
jpeg_write_marker(cinfo, 0xe1, (JOCTET*) neogeo, 10);
+ if(ibuf->img_info) {
+ /* key + max value + "Blender" */
+ text= MEM_mallocN(530, "stamp info read");
+ iptr= ibuf->img_info;
+ while(iptr) {
+ if (!strcmp (iptr->key, "None")) {
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) iptr->value, strlen (iptr->value) + 1);
+ goto next_stamp_info;
+ }
+
+ /*
+ * The JPEG format don't support a pair "key/value"
+ * like PNG, so we "encode" the stamp in a
+ * single string:
+ * "Blender:key:value"
+ *
+ * The first "Blender" is a simple identify to help
+ * in the read process.
+ */
+ sprintf (text, "Blender:%s:%s", iptr->key, iptr->value);
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, strlen (text)+1);
+next_stamp_info:
+ iptr = iptr->next;
+ }
+ MEM_freeN(text);
+ }
+
row_pointer[0] =
mallocstruct(JSAMPLE,
cinfo->input_components *
diff --git a/source/blender/imbuf/intern/md5.c b/source/blender/imbuf/intern/md5.c
new file mode 100644
index 00000000000..a3165467b53
--- /dev/null
+++ b/source/blender/imbuf/intern/md5.c
@@ -0,0 +1,361 @@
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+ according to the definition of MD5 in RFC 1321 from April 1992.
+ Copyright (C) 1995 Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+# include <stdlib.h>
+# include <string.h>
+
+#include "md5.h"
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n) \
+ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+
+/* This array contains the bytes used to pad the buffer to the next
+ 64-byte boundary. (RFC 1321, 3.1: Step 1) */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
+
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+void
+md5_init_ctx (ctx)
+ struct md5_ctx *ctx;
+{
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF. The result must
+ be in little endian byte order. */
+void *
+md5_read_ctx (ctx, resbuf)
+ const struct md5_ctx *ctx;
+ void *resbuf;
+{
+ ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+ ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+ ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+ ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+ return resbuf;
+}
+
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+int
+md5_stream (stream, resblock)
+ FILE *stream;
+ void *resblock;
+{
+ /* Important: BLOCKSIZE must be a multiple of 64. */
+#define BLOCKSIZE 4096
+ struct md5_ctx ctx;
+ md5_uint32 len[2];
+ char buffer[BLOCKSIZE + 72];
+ size_t pad, sum;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ len[0] = 0;
+ len[1] = 0;
+
+ /* Iterate over full file contents. */
+ while (1)
+ {
+ /* We read the file in blocks of BLOCKSIZE bytes. One call of the
+ computation function processes the whole buffer so that with the
+ next round of the loop another block can be read. */
+ size_t n;
+ sum = 0;
+
+ /* Read block. Take care for partial reads. */
+ do
+ {
+ n = fread (buffer, 1, BLOCKSIZE - sum, stream);
+
+ sum += n;
+ }
+ while (sum < BLOCKSIZE && n != 0);
+ if (n == 0 && ferror (stream))
+ return 1;
+
+ /* RFC 1321 specifies the possible length of the file up to 2^64 bits.
+ Here we only compute the number of bytes. Do a double word
+ increment. */
+ len[0] += sum;
+ if (len[0] < sum)
+ ++len[1];
+
+ /* If end of file is reached, end the loop. */
+ if (n == 0)
+ break;
+
+ /* Process buffer with BLOCKSIZE bytes. Note that
+ BLOCKSIZE % 64 == 0
+ */
+ md5_process_block (buffer, BLOCKSIZE, &ctx);
+ }
+
+ /* We can copy 64 byte because the buffer is always big enough. FILLBUF
+ contains the needed bits. */
+ memcpy (&buffer[sum], fillbuf, 64);
+
+ /* Compute amount of padding bytes needed. Alignment is done to
+ (N + PAD) % 64 == 56
+ There is always at least one byte padded. I.e. even the alignment
+ is correctly aligned 64 padding bytes are added. */
+ pad = sum & 63;
+ pad = pad >= 56 ? 64 + 56 - pad : 56 - pad;
+
+ /* Put the 64-bit file length in *bits* at the end of the buffer. */
+ *(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3);
+ *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3)
+ | (len[0] >> 29));
+
+ /* Process last bytes. */
+ md5_process_block (buffer, sum + pad + 8, &ctx);
+
+ /* Construct result in desired memory. */
+ md5_read_ctx (&ctx, resblock);
+ return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+void *
+md5_buffer (buffer, len, resblock)
+ const char *buffer;
+ size_t len;
+ void *resblock;
+{
+ struct md5_ctx ctx;
+ char restbuf[64 + 72];
+ size_t blocks = len & ~63;
+ size_t pad, rest;
+
+ /* Initialize the computation context. */
+ md5_init_ctx (&ctx);
+
+ /* Process whole buffer but last len % 64 bytes. */
+ md5_process_block (buffer, blocks, &ctx);
+
+ /* REST bytes are not processed yet. */
+ rest = len - blocks;
+ /* Copy to own buffer. */
+ memcpy (restbuf, &buffer[blocks], rest);
+ /* Append needed fill bytes at end of buffer. We can copy 64 byte
+ because the buffer is always big enough. */
+ memcpy (&restbuf[rest], fillbuf, 64);
+
+ /* PAD bytes are used for padding to correct alignment. Note that
+ always at least one byte is padded. */
+ pad = rest >= 56 ? 64 + 56 - rest : 56 - rest;
+
+ /* Put length of buffer in *bits* in last eight bytes. */
+ *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP (len << 3);
+ *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP (len >> 29);
+
+ /* Process last bytes. */
+ md5_process_block (restbuf, rest + pad + 8, &ctx);
+
+ /* Put result in desired memory area. */
+ return md5_read_ctx (&ctx, resblock);
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+ It is assumed that LEN % 64 == 0. */
+
+void
+md5_process_block (buffer, len, ctx)
+ const void *buffer;
+ size_t len;
+ struct md5_ctx *ctx;
+{
+ md5_uint32 correct_words[16];
+ const md5_uint32 *words = buffer;
+ size_t nwords = len / sizeof (md5_uint32);
+ const md5_uint32 *endp = words + nwords;
+ md5_uint32 A = ctx->A;
+ md5_uint32 B = ctx->B;
+ md5_uint32 C = ctx->C;
+ md5_uint32 D = ctx->D;
+
+ /* Process all bytes in the buffer with 64 bytes in each round of
+ the loop. */
+ while (words < endp)
+ {
+ md5_uint32 *cwp = correct_words;
+ md5_uint32 A_save = A;
+ md5_uint32 B_save = B;
+ md5_uint32 C_save = C;
+ md5_uint32 D_save = D;
+
+ /* First round: using the given function, the context and a constant
+ the next context is computed. Because the algorithms processing
+ unit is a 32-bit word and it is determined to work on words in
+ little endian byte order we perhaps have to change the byte order
+ before the computation. To reduce the work for the next steps
+ we store the swapped words in the array CORRECT_WORDS. */
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
+ ++words; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* It is unfortunate that C does not provide an operator for
+ cyclic rotation. Hope the C compiler is smart enough. */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+ /* Before we start, one word to the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+ /* For the second to fourth round we have the possibly swapped words
+ in CORRECT_WORDS. Redefine the macro to take an additional first
+ argument specifying the function to use. */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ CYCLIC (a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Add the starting values of the context. */
+ A += A_save;
+ B += B_save;
+ C += C_save;
+ D += D_save;
+ }
+
+ /* Put checksum in context given as argument. */
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
+}
+
diff --git a/source/blender/imbuf/intern/md5.h b/source/blender/imbuf/intern/md5.h
new file mode 100644
index 00000000000..8b0d946430e
--- /dev/null
+++ b/source/blender/imbuf/intern/md5.h
@@ -0,0 +1,116 @@
+/* md5.h - Declaration of functions and data types used for MD5 sum
+ computing library functions.
+ Copyright (C) 1995 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You 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. */
+
+#ifndef _MD5_H
+#define _MD5_H
+
+#include <stdio.h>
+
+#if defined HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+/* The following contortions are an attempt to use the C preprocessor
+ to determine an unsigned integral type that is 32 bits wide. An
+ alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+ doing that would require that the configure script compile and *run*
+ the resulting executable. Locally running cross-compiled executables
+ is usually not possible. */
+
+#if defined __STDC__ && __STDC__
+# define UINT_MAX_32_BITS 4294967295U
+#else
+# define UINT_MAX_32_BITS 0xFFFFFFFF
+#endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+ This should be valid for all systems GNU cares about because
+ that doesn't include 16-bit systems, and only modern systems
+ (that certainly have <limits.h>) have 64+-bit integral types. */
+
+#ifndef UINT_MAX
+# define UINT_MAX UINT_MAX_32_BITS
+#endif
+
+#if UINT_MAX == UINT_MAX_32_BITS
+ typedef unsigned int md5_uint32;
+#else
+# if USHRT_MAX == UINT_MAX_32_BITS
+ typedef unsigned short md5_uint32;
+# else
+# if ULONG_MAX == UINT_MAX_32_BITS
+ typedef unsigned long md5_uint32;
+# else
+ /* The following line is intended to evoke an error.
+ Using #error is not portable enough. */
+ "Cannot determine unsigned 32-bit data type."
+# endif
+# endif
+#endif
+
+#undef __P
+#if defined (__STDC__) && __STDC__
+#define __P(x) x
+#else
+#define __P(x) ()
+#endif
+
+/* Structure to save state of computation between the single steps. */
+struct md5_ctx
+{
+ md5_uint32 A;
+ md5_uint32 B;
+ md5_uint32 C;
+ md5_uint32 D;
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+ (RFC 1321, 3.3: Step 3) */
+void md5_init_ctx __P ((struct md5_ctx *ctx));
+
+/* Starting with the result of former calls of this function (or the
+ initialzation function update the context for the next LEN bytes
+ starting at BUFFER.
+ It is necessary that LEN is a multiple of 64!!! */
+void md5_process_block __P ((const void *buffer, size_t len,
+ struct md5_ctx *ctx));
+
+/* Put result from CTX in first 16 bytes following RESBUF. The result is
+ always in little endian byte order, so that a byte-wise output yields
+ to the wanted ASCII representation of the message digest. */
+void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
+
+
+/* Compute MD5 message digest for bytes read from STREAM. The
+ resulting message digest number will be written into the 16 bytes
+ beginning at RESBLOCK. */
+int md5_stream __P ((FILE *stream, void *resblock));
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
+ result is always in little endian byte order, so that a byte-wise
+ output yields to the wanted ASCII representation of the message
+ digest. */
+void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
+
+#endif
+
diff --git a/source/blender/imbuf/intern/openexr/Makefile b/source/blender/imbuf/intern/openexr/Makefile
index 65b9a058e01..a3b79c951dd 100644
--- a/source/blender/imbuf/intern/openexr/Makefile
+++ b/source/blender/imbuf/intern/openexr/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/imbuf/openexr
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I../../../makesdna
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 3cbada812b9..8f94c2cec3d 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -362,6 +362,7 @@ typedef struct ExrHandle {
OutputFile *ofile;
int tilex, tiley;
int width, height;
+ int mipmap;
ListBase channels; /* flattened out, ExrChannel */
ListBase layers; /* hierarchical, pointing in end to ExrChannel */
@@ -450,7 +451,7 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in
data->ofile = new OutputFile(filename, header);
}
-void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height, int tilex, int tiley)
+void IMB_exrtile_begin_write(void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley)
{
ExrHandle *data= (ExrHandle *)handle;
Header header (width, height);
@@ -460,11 +461,12 @@ void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height
data->tiley= tiley;
data->width= width;
data->height= height;
+ data->mipmap= mipmap;
for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
header.channels().insert (echan->name, Channel (FLOAT));
- header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
+ header.setTileDescription (TileDescription (tilex, tiley, (mipmap)? MIPMAP_LEVELS: ONE_LEVEL));
header.lineOrder() = RANDOM_Y;
header.compression() = RLE_COMPRESSION;
@@ -478,7 +480,7 @@ int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
{
ExrHandle *data= (ExrHandle *)handle;
- if(BLI_exists(filename)) {
+ if(BLI_exists(filename) && BLI_filepathsize(filename)>32) { /* 32 is arbitrary, but zero length files crashes exr */
data->ifile = new InputFile(filename);
if(data->ifile) {
Box2i dw = data->ifile->header().dataWindow();
@@ -533,7 +535,7 @@ void IMB_exrtile_clear_channels(void *handle)
BLI_freelistN(&data->channels);
}
-void IMB_exrtile_write_channels(void *handle, int partx, int party)
+void IMB_exrtile_write_channels(void *handle, int partx, int party, int level)
{
ExrHandle *data= (ExrHandle *)handle;
FrameBuffer frameBuffer;
@@ -547,9 +549,14 @@ void IMB_exrtile_write_channels(void *handle, int partx, int party)
}
data->tofile->setFrameBuffer (frameBuffer);
- // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
- data->tofile->writeTile (partx/data->tilex, party/data->tiley);
-
+
+ try {
+ // printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
+ data->tofile->writeTile (partx/data->tilex, party/data->tiley, level);
+ }
+ catch (const std::exception &exc) {
+ std::cerr << "OpenEXR-writeTile: ERROR: " << exc.what() << std::endl;
+ }
}
void IMB_exr_write_channels(void *handle)
@@ -615,7 +622,6 @@ void IMB_exr_multilayer_convert(void *handle, void *base,
void IMB_exr_close(void *handle)
{
ExrHandle *data= (ExrHandle *)handle;
- ExrChannel *echan;
ExrLayer *lay;
ExrPass *pass;
@@ -778,28 +784,28 @@ static ExrHandle *imb_exr_begin_read_mem(InputFile *file, int width, int height)
/* we can have RGB(A), XYZ(W), UVA */
if(pass->totchan==3 || pass->totchan==4) {
if(pass->chan[0]->chan_id=='B' || pass->chan[1]->chan_id=='B' || pass->chan[2]->chan_id=='B') {
- lookup['R']= 0;
- lookup['G']= 1;
- lookup['B']= 2;
- lookup['A']= 3;
+ lookup[(unsigned int)'R']= 0;
+ lookup[(unsigned int)'G']= 1;
+ lookup[(unsigned int)'B']= 2;
+ lookup[(unsigned int)'A']= 3;
}
else if(pass->chan[0]->chan_id=='Y' || pass->chan[1]->chan_id=='Y' || pass->chan[2]->chan_id=='Y') {
- lookup['X']= 0;
- lookup['Y']= 1;
- lookup['Z']= 2;
- lookup['W']= 3;
+ lookup[(unsigned int)'X']= 0;
+ lookup[(unsigned int)'Y']= 1;
+ lookup[(unsigned int)'Z']= 2;
+ lookup[(unsigned int)'W']= 3;
}
else {
- lookup['U']= 0;
- lookup['V']= 1;
- lookup['A']= 2;
+ lookup[(unsigned int)'U']= 0;
+ lookup[(unsigned int)'V']= 1;
+ lookup[(unsigned int)'A']= 2;
}
for(a=0; a<pass->totchan; a++) {
echan= pass->chan[a];
- echan->rect= pass->rect + lookup[echan->chan_id];
+ echan->rect= pass->rect + lookup[(unsigned int)echan->chan_id];
echan->xstride= pass->totchan;
echan->ystride= width*pass->totchan;
- pass->chan_id[ lookup[echan->chan_id] ]= echan->chan_id;
+ pass->chan_id[ (unsigned int)lookup[(unsigned int)echan->chan_id] ]= echan->chan_id;
}
}
else { /* unknown */
@@ -831,6 +837,7 @@ typedef struct RGBA
} RGBA;
+#if 0
static void exr_print_filecontents(InputFile *file)
{
const ChannelList &channels = file->header().channels();
@@ -841,6 +848,7 @@ static void exr_print_filecontents(InputFile *file)
printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
}
}
+#endif
static int exr_has_zbuffer(InputFile *file)
{
@@ -848,7 +856,6 @@ static int exr_has_zbuffer(InputFile *file)
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
{
- const Channel &channel = i.channel();
if(strcmp("Z", i.name())==0)
return 1;
}
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
index ca4f7405f44..be4d1314a80 100644
--- a/source/blender/imbuf/intern/openexr/openexr_multi.h
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -46,13 +46,13 @@ void IMB_exr_add_channel (void *handle, const char *layname, const char *passn
int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height);
void IMB_exr_begin_write (void *handle, char *filename, int width, int height, int compress);
-void IMB_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley);
+void IMB_exrtile_begin_write (void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley);
void IMB_exr_set_channel (void *handle, char *layname, char *passname, int xstride, int ystride, float *rect);
void IMB_exr_read_channels (void *handle);
void IMB_exr_write_channels (void *handle);
-void IMB_exrtile_write_channels (void *handle, int partx, int party);
+void IMB_exrtile_write_channels (void *handle, int partx, int party, int level);
void IMB_exrtile_clear_channels (void *handle);
void IMB_exr_multilayer_convert (void *handle, void *base,
@@ -71,13 +71,13 @@ void IMB_exr_add_channel (void *handle, const char *layname, const char *chann
int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height) {return 0;}
void IMB_exr_begin_write (void *handle, char *filename, int width, int height, int compress) {}
-void IMB_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley) {}
+void IMB_exrtile_begin_write (void *handle, char *filename, int mipmap, int width, int height, int tilex, int tiley) {}
void IMB_exr_set_channel (void *handle, char *layname, char *channame, int xstride, int ystride, float *rect) {}
void IMB_exr_read_channels (void *handle) {}
void IMB_exr_write_channels (void *handle) {}
-void IMB_exrtile_write_channels (void *handle, int partx, int party) {}
+void IMB_exrtile_write_channels (void *handle, int partx, int party, int level) {}
void IMB_exrtile_clear_channels (void *handle) {}
void IMB_exr_multilayer_convert (void *handle, void *base,
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 46c5232a61a..c77ff7ea56f 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -43,6 +43,7 @@
#include "IMB_allocimbuf.h"
#include "IMB_cmap.h"
+#include "IMB_imginfo.h"
#include "IMB_png.h"
typedef struct PNGReadStruct {
@@ -100,6 +101,7 @@ short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
{
png_structp png_ptr;
png_infop info_ptr;
+
unsigned char *pixels = 0;
unsigned char *from, *to;
png_bytepp row_pointers = 0;
@@ -219,6 +221,34 @@ short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
+ /* image text info */
+ if (ibuf->img_info) {
+ png_text* imginfo;
+ ImgInfo* iptr;
+ int num_text = 0;
+ iptr = ibuf->img_info;
+ while (iptr) {
+ num_text++;
+ iptr = iptr->next;
+ }
+
+ imginfo = MEM_callocN(num_text*sizeof(png_text), "png_imginfo");
+ iptr = ibuf->img_info;
+ num_text = 0;
+ while (iptr) {
+
+ imginfo[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+ imginfo[num_text].key = iptr->key;
+ imginfo[num_text].text = iptr->value;
+ num_text++;
+ iptr = iptr->next;
+ }
+
+ png_set_text(png_ptr, info_ptr, imginfo, num_text);
+ MEM_freeN(imginfo);
+
+ }
+
// write the file header information
png_write_info(png_ptr, info_ptr);
@@ -409,6 +439,15 @@ struct ImBuf *imb_loadpng(unsigned char *mem, int size, int flags)
break;
}
+ if (flags & IB_imginfo) {
+ png_text* text_chunks;
+ int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
+ for(i = 0; i < count; i++) {
+ IMB_imginfo_add_field(ibuf, text_chunks[i].key, text_chunks[i].text);
+ ibuf->flags |= IB_imginfo;
+ }
+ }
+
png_read_end(png_ptr, info_ptr);
}
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 75be790a4cc..3cb9ca79ffc 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -161,8 +161,10 @@ static void FLOAT2RGBE(fCOLOR fcol, RGBE rgbe)
int imb_is_a_hdr(void *buf)
{
- /* For recognition, Blender only loades first 32 bytes, so use #?RADIANCE id instead */
- if (strstr((char*)buf, "#?RADIANCE")) return 1;
+ // For recognition, Blender only loads first 32 bytes, so use #?RADIANCE id instead
+ // update: actually, the 'RADIANCE' part is just an optional program name, the magic word is really only the '#?' part
+ //if (strstr((char*)buf, "#?RADIANCE")) return 1;
+ if (strstr((char*)buf, "#?")) return 1;
// if (strstr((char*)buf, "32-bit_rle_rgbe")) return 1;
return 0;
}
@@ -176,7 +178,6 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
int found=0;
int width=0, height=0;
int x, y;
- int ir, ig, ib;
unsigned char* ptr;
unsigned char* rect;
char oriY[80], oriX[80];
@@ -225,18 +226,14 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
*rect_float++ = fcol[GRN];
*rect_float++ = fcol[BLU];
*rect_float++ = 1.0f;
-
/* Also old oldstyle for the rest of blender which is not using floats yet */
-/* very weird mapping! (ton) */
- fcol[RED] = 1.f-exp(fcol[RED]*-1.414213562f);
- fcol[GRN] = 1.f-exp(fcol[GRN]*-1.414213562f);
- fcol[BLU] = 1.f-exp(fcol[BLU]*-1.414213562f);
- ir = (int)(255.f*pow(fcol[RED], 0.45454545f));
- ig = (int)(255.f*pow(fcol[GRN], 0.45454545f));
- ib = (int)(255.f*pow(fcol[BLU], 0.45454545f));
- *rect++ = (unsigned char)((ir<0) ? 0 : ((ir>255) ? 255 : ir));
- *rect++ = (unsigned char)((ig<0) ? 0 : ((ig>255) ? 255 : ig));
- *rect++ = (unsigned char)((ib<0) ? 0 : ((ib>255) ? 255 : ib));
+ // e: changed to simpler tonemapping, previous code was rather slow (is this actually still relevant at all?)
+ fcol[RED] = fcol[RED]/(1.f + fcol[RED]);
+ fcol[GRN] = fcol[GRN]/(1.f + fcol[GRN]);
+ fcol[BLU] = fcol[BLU]/(1.f + fcol[BLU]);
+ *rect++ = (unsigned char)((fcol[RED] < 0.f) ? 0 : ((fcol[RED] > 1.f) ? 255 : (255.f*fcol[RED])));
+ *rect++ = (unsigned char)((fcol[GRN] < 0.f) ? 0 : ((fcol[GRN] > 1.f) ? 255 : (255.f*fcol[GRN])));
+ *rect++ = (unsigned char)((fcol[BLU] < 0.f) ? 0 : ((fcol[BLU] > 1.f) ? 255 : (255.f*fcol[BLU])));
*rect++ = 255;
}
}
@@ -328,10 +325,10 @@ static void writeHeader(FILE *file, int width, int height)
fputc(10, file);
fprintf(file, "# %s", "Created with Blender");
fputc(10, file);
- fprintf(file, "FORMAT=32-bit_rle_rgbe");
- fputc(10, file);
fprintf(file, "EXPOSURE=%25.13f", 1.0);
fputc(10, file);
+ fprintf(file, "FORMAT=32-bit_rle_rgbe");
+ fputc(10, file);
fputc(10, file);
fprintf(file, "-Y %d +X %d", height, width);
fputc(10, file);
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index bfa6200d23b..ec0f17a8c2b 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -59,6 +59,10 @@
#include "openexr/openexr_api.h"
#endif
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
+
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
#include "quicktime_import.h"
@@ -153,6 +157,11 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) {
ibuf = imb_load_openexr((uchar *)mem, size, flags);
if (ibuf) return (ibuf);
#endif
+
+#ifdef WITH_DDS
+ ibuf = imb_load_dds((uchar *)mem, size, flags);
+ if (ibuf) return (ibuf);
+#endif
#ifdef WITH_QUICKTIME
#if defined(_WIN32) || defined (__APPLE__)
@@ -259,7 +268,7 @@ struct ImBuf *IMB_loadifffile(int file, int flags) {
}
-struct ImBuf *IMB_loadiffname(char *naam, int flags) {
+struct ImBuf *IMB_loadiffname(const char *naam, int flags) {
int file;
struct ImBuf *ibuf;
int buf[1];
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 85c5e07bb8e..5a907e71258 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -517,3 +517,87 @@ void IMB_rectfill(struct ImBuf *drect, float col[4])
}
}
+/* maybe we should use BKE_utildefines.h */
+#define FTOCHAR(val) (val<=0.0f ? 0: (val>=1.0f ? 255: (char)(255.99f*val)))
+#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
+#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+
+void buf_rectfill_area(unsigned char *rect, float *rectf, int width, int height, float *col, int x1, int y1, int x2, int y2)
+{
+ int i, j;
+ float a; /* alpha */
+ float ai; /* alpha inverted */
+ float aich; /* alpha, inverted, ai/255.0 - Convert char to float at the same time */
+ if ((!rect && !rectf) || (!col) || col[3]==0.0)
+ return;
+
+ /* sanity checks for coords */
+ CLAMP(x1, 0, width);
+ CLAMP(x2, 0, width);
+ CLAMP(y1, 0, height);
+ CLAMP(y2, 0, height);
+
+ if (x1>x2) SWAP(int,x1,x2);
+ if (y1>y2) SWAP(int,y1,y2);
+ if (x1==x2 || y1==y2) return;
+
+ a = col[3];
+ ai = 1-a;
+ aich = ai/255.0f;
+
+ if (rect) {
+ unsigned char *pixel;
+ unsigned char chr=0, chg=0, chb=0;
+ float fr=0, fg=0, fb=0;
+
+ if (a == 1.0) {
+ chr = FTOCHAR(col[0]);
+ chg = FTOCHAR(col[1]);
+ chb = FTOCHAR(col[2]);
+ } else {
+ fr = col[0]*a;
+ fg = col[1]*a;
+ fb = col[2]*a;
+ }
+ for (j = 0; j < y2-y1; j++) {
+ for (i = 0; i < x2-x1; i++) {
+ pixel = rect + 4 * (((y1 + j) * width) + (x1 + i));
+ if (pixel >= rect && pixel < rect+ (4 * (width * height))) {
+ if (a == 1.0) {
+ pixel[0] = chr;
+ pixel[1] = chg;
+ pixel[2] = chb;
+ } else {
+ pixel[0] = (char)((fr + ((float)pixel[0]*aich))*255.0f);
+ pixel[1] = (char)((fg + ((float)pixel[1]*aich))*255.0f);
+ pixel[2] = (char)((fb + ((float)pixel[2]*aich))*255.0f);
+ }
+ }
+ }
+ }
+ }
+
+ if (rectf) {
+ float *pixel;
+ for (j = 0; j < y2-y1; j++) {
+ for (i = 0; i < x2-x1; i++) {
+ pixel = rectf + 4 * (((y1 + j) * width) + (x1 + i));
+ if (a == 1.0) {
+ pixel[0] = col[0];
+ pixel[1] = col[1];
+ pixel[2] = col[2];
+ } else {
+ pixel[0] = (col[0]*a) + (pixel[0]*ai);
+ pixel[1] = (col[1]*a) + (pixel[1]*ai);
+ pixel[2] = (col[2]*a) + (pixel[2]*ai);
+ }
+ }
+ }
+ }
+}
+
+void IMB_rectfill_area(struct ImBuf *ibuf, float *col, int x1, int y1, int x2, int y2)
+{
+ if (!ibuf) return;
+ buf_rectfill_area((unsigned char *) ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, x1, y1, x2, y2);
+}
diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c
index 13edfbf0a33..8f5fb39d956 100644
--- a/source/blender/imbuf/intern/rotate.c
+++ b/source/blender/imbuf/intern/rotate.c
@@ -43,46 +43,85 @@
void IMB_flipy(struct ImBuf * ibuf)
{
- short x, y;
- unsigned int *top, *bottom, do_float=0, *line;
- float *topf=NULL, *bottomf=NULL, *linef=NULL;
+ int x, y;
if (ibuf == NULL) return;
- if (ibuf->rect == NULL) return;
-
- if (ibuf->rect_float) do_float =1;
- x = ibuf->x;
- y = ibuf->y;
+ if (ibuf->rect) {
+ unsigned int *top, *bottom, *line;
+
+ x = ibuf->x;
+ y = ibuf->y;
- top = ibuf->rect;
- bottom = top + ((y-1) * x);
- line= MEM_mallocN(x*sizeof(int), "linebuf");
+ top = ibuf->rect;
+ bottom = top + ((y-1) * x);
+ line= MEM_mallocN(x*sizeof(int), "linebuf");
- if (do_float) {
+ y >>= 1;
+
+ for(;y>0;y--) {
+ memcpy(line, top, x*sizeof(int));
+ memcpy(top, bottom, x*sizeof(int));
+ memcpy(bottom, line, x*sizeof(int));
+ bottom -= x;
+ top+= x;
+ }
+
+ MEM_freeN(line);
+ }
+
+ if (ibuf->rect_float) {
+ float *topf=NULL, *bottomf=NULL, *linef=NULL;
+
+ x = ibuf->x;
+ y = ibuf->y;
+
topf= ibuf->rect_float;
bottomf = topf + 4*((y-1) * x);
linef= MEM_mallocN(4*x*sizeof(float), "linebuff");
- }
- y >>= 1;
-
- for(;y>0;y--) {
-
- memcpy(line, top, x*sizeof(int));
- memcpy(top, bottom, x*sizeof(int));
- memcpy(bottom, line, x*sizeof(int));
- bottom -= x;
- top+= x;
-
- if(do_float) {
+
+ y >>= 1;
+
+ for(;y>0;y--) {
memcpy(linef, topf, 4*x*sizeof(float));
memcpy(topf, bottomf, 4*x*sizeof(float));
memcpy(bottomf, linef, 4*x*sizeof(float));
bottomf -= 4*x;
topf+= 4*x;
}
+
+ MEM_freeN(linef);
+ }
+}
+
+void IMB_flipx(struct ImBuf * ibuf)
+{
+ short x, y, xr, xl, yi;
+ unsigned int px;
+ float px_f[4];
+
+ if (ibuf == NULL) return;
+
+ x = ibuf->x;
+ y = ibuf->y;
+
+ if (ibuf->rect) {
+ for(yi=y-1;yi>=0;yi--) {
+ for(xr=x-1, xl=0; xr>=xl; xr--, xl++) {
+ px = ibuf->rect[(x*yi)+xr];
+ ibuf->rect[(x*yi)+xr] = ibuf->rect[(x*yi)+xl];
+ ibuf->rect[(x*yi)+xl] = px;
+ }
+ }
}
- MEM_freeN(line);
- if(linef) MEM_freeN(linef);
+ if (ibuf->rect_float) {
+ for(yi=y-1;yi>=0;yi--) {
+ for(xr=x-1, xl=0; xr>=xl; xr--, xl++) {
+ memcpy(&px_f, &ibuf->rect_float[((x*yi)+xr)*4], 4*sizeof(float));
+ memcpy(&ibuf->rect_float[((x*yi)+xr)*4], &ibuf->rect_float[((x*yi)+xl)*4], 4*sizeof(float));
+ memcpy(&ibuf->rect_float[((x*yi)+xl)*4], &px_f, 4*sizeof(float));
+ }
+ }
+ }
}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index cd933cb0767..80731213140 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -483,6 +483,468 @@ struct ImBuf *IMB_halflace(struct ImBuf *ibuf1)
return (ibuf2);
}
+/* q_scale_linear_interpolation helper functions */
+
+static void enlarge_picture_byte(
+ unsigned char* src, unsigned char* dst, int src_width,
+ int src_height, int dst_width, int dst_height)
+{
+ double ratiox = (double) (dst_width - 1.0)
+ / (double) (src_width - 1.001);
+ double ratioy = (double) (dst_height - 1.0)
+ / (double) (src_height - 1.001);
+ unsigned long x_src, dx_src, x_dst;
+ unsigned long y_src, dy_src, y_dst;
+
+ dx_src = 65536.0 / ratiox;
+ dy_src = 65536.0 / ratioy;
+
+ y_src = 0;
+ for (y_dst = 0; y_dst < dst_height; y_dst++) {
+ unsigned char* line1 = src + (y_src >> 16) * 4 * src_width;
+ unsigned char* line2 = line1 + 4 * src_width;
+ unsigned long weight1y = 65536 - (y_src & 0xffff);
+ unsigned long weight2y = 65536 - weight1y;
+
+ if ((y_src >> 16) == src_height - 1) {
+ line2 = line1;
+ }
+
+ x_src = 0;
+ for (x_dst = 0; x_dst < dst_width; x_dst++) {
+ unsigned long weight1x = 65536 - (x_src & 0xffff);
+ unsigned long weight2x = 65536 - weight1x;
+
+ unsigned long x = (x_src >> 16) * 4;
+
+ *dst++ = ((((line1[x] * weight1y) >> 16)
+ * weight1x) >> 16)
+ + ((((line2[x] * weight2y) >> 16)
+ * weight1x) >> 16)
+ + ((((line1[4 + x] * weight1y) >> 16)
+ * weight2x) >> 16)
+ + ((((line2[4 + x] * weight2y) >> 16)
+ * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 1] * weight1y) >> 16)
+ * weight1x) >> 16)
+ + ((((line2[x + 1] * weight2y) >> 16)
+ * weight1x) >> 16)
+ + ((((line1[4 + x + 1] * weight1y) >> 16)
+ * weight2x) >> 16)
+ + ((((line2[4 + x + 1] * weight2y) >> 16)
+ * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 2] * weight1y) >> 16)
+ * weight1x) >> 16)
+ + ((((line2[x + 2] * weight2y) >> 16)
+ * weight1x) >> 16)
+ + ((((line1[4 + x + 2] * weight1y) >> 16)
+ * weight2x) >> 16)
+ + ((((line2[4 + x + 2] * weight2y) >> 16)
+ * weight2x) >> 16);
+
+ *dst++ = ((((line1[x + 3] * weight1y) >> 16)
+ * weight1x) >> 16)
+ + ((((line2[x + 3] * weight2y) >> 16)
+ * weight1x) >> 16)
+ + ((((line1[4 + x + 3] * weight1y) >> 16)
+ * weight2x) >> 16)
+ + ((((line2[4 + x + 3] * weight2y) >> 16)
+ * weight2x) >> 16);
+
+ x_src += dx_src;
+ }
+ y_src += dy_src;
+ }
+}
+
+struct scale_outpix_byte {
+ unsigned long r;
+ unsigned long g;
+ unsigned long b;
+ unsigned long a;
+
+ unsigned long weight;
+};
+
+static void shrink_picture_byte(
+ unsigned char* src, unsigned char* dst, int src_width,
+ int src_height, int dst_width, int dst_height)
+{
+ double ratiox = (double) (dst_width) / (double) (src_width);
+ double ratioy = (double) (dst_height) / (double) (src_height);
+ unsigned long x_src, dx_dst, x_dst;
+ unsigned long y_src, dy_dst, y_dst;
+ long y_counter;
+ unsigned char * dst_begin = dst;
+
+ struct scale_outpix_byte * dst_line1 = NULL;
+ struct scale_outpix_byte * dst_line2 = NULL;
+
+ dst_line1 = (struct scale_outpix_byte*) MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_byte),
+ "shrink_picture_byte 1");
+ dst_line2 = (struct scale_outpix_byte*) MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_byte),
+ "shrink_picture_byte 2");
+
+ dx_dst = 65536.0 * ratiox;
+ dy_dst = 65536.0 * ratioy;
+
+ y_dst = 0;
+ y_counter = 65536;
+ for (y_src = 0; y_src < src_height; y_src++) {
+ unsigned char* line = src + y_src * 4 * src_width;
+ unsigned long weight1y = 65536 - (y_dst & 0xffff);
+ unsigned long weight2y = 65536 - weight1y;
+ x_dst = 0;
+ for (x_src = 0; x_src < src_width; x_src++) {
+ unsigned long weight1x = 65536 - (x_dst & 0xffff);
+ unsigned long weight2x = 65536 - weight1x;
+
+ unsigned long x = x_dst >> 16;
+
+ unsigned long w;
+
+ w = (weight1y * weight1x) >> 16;
+
+ dst_line1[x].r += (line[0] * w) >> 16;
+ dst_line1[x].g += (line[1] * w) >> 16;
+ dst_line1[x].b += (line[2] * w) >> 16;
+ dst_line1[x].a += (line[3] * w) >> 16;
+ dst_line1[x].weight += w;
+
+ w = (weight2y * weight1x) >> 16;
+
+ dst_line2[x].r += (line[0] * w) >> 16;
+ dst_line2[x].g += (line[1] * w) >> 16;
+ dst_line2[x].b += (line[2] * w) >> 16;
+ dst_line2[x].a += (line[3] * w) >> 16;
+ dst_line2[x].weight += w;
+
+ w = (weight1y * weight2x) >> 16;
+
+ dst_line1[x+1].r += (line[0] * w) >> 16;
+ dst_line1[x+1].g += (line[1] * w) >> 16;
+ dst_line1[x+1].b += (line[2] * w) >> 16;
+ dst_line1[x+1].a += (line[3] * w) >> 16;
+ dst_line1[x+1].weight += w;
+
+ w = (weight2y * weight2x) >> 16;
+
+ dst_line2[x+1].r += (line[0] * w) >> 16;
+ dst_line2[x+1].g += (line[1] * w) >> 16;
+ dst_line2[x+1].b += (line[2] * w) >> 16;
+ dst_line2[x+1].a += (line[3] * w) >> 16;
+ dst_line2[x+1].weight += w;
+
+ x_dst += dx_dst;
+ line += 4;
+ }
+
+ y_dst += dy_dst;
+ y_counter -= dy_dst;
+ if (y_counter < 0) {
+ unsigned long x;
+ struct scale_outpix_byte * temp;
+
+ y_counter += 65536;
+
+ for (x=0; x < dst_width; x++) {
+ unsigned long f = 0x80000000UL
+ / dst_line1[x].weight;
+ *dst++ = (dst_line1[x].r * f) >> 15;
+ *dst++ = (dst_line1[x].g * f) >> 15;
+ *dst++ = (dst_line1[x].b * f) >> 15;
+ *dst++ = (dst_line1[x].a * f) >> 15;
+ }
+ memset(dst_line1, 0, dst_width *
+ sizeof(struct scale_outpix_byte));
+ temp = dst_line1;
+ dst_line1 = dst_line2;
+ dst_line2 = temp;
+ }
+ }
+ if (dst - dst_begin < dst_width * dst_height * 4) {
+ unsigned long x;
+ for (x = 0; x < dst_width; x++) {
+ unsigned long f = 0x80000000UL / dst_line1[x].weight;
+ *dst++ = (dst_line1[x].r * f) >> 15;
+ *dst++ = (dst_line1[x].g * f) >> 15;
+ *dst++ = (dst_line1[x].b * f) >> 15;
+ *dst++ = (dst_line1[x].a * f) >> 15;
+ }
+ }
+ MEM_freeN(dst_line1);
+ MEM_freeN(dst_line2);
+}
+
+
+static void q_scale_byte(unsigned char* in, unsigned char* out, int in_width,
+ int in_height, int dst_width, int dst_height)
+{
+ if (dst_width > in_width && dst_height > in_height) {
+ enlarge_picture_byte(in, out, in_width, in_height,
+ dst_width, dst_height);
+ } else if (dst_width < in_width && dst_height < in_height) {
+ shrink_picture_byte(in, out, in_width, in_height,
+ dst_width, dst_height);
+ }
+}
+
+static void enlarge_picture_float(
+ float* src, float* dst, int src_width,
+ int src_height, int dst_width, int dst_height)
+{
+ double ratiox = (double) (dst_width - 1.0)
+ / (double) (src_width - 1.001);
+ double ratioy = (double) (dst_height - 1.0)
+ / (double) (src_height - 1.001);
+ unsigned long x_dst;
+ unsigned long y_dst;
+ double x_src, dx_src;
+ double y_src, dy_src;
+
+ dx_src = 1.0 / ratiox;
+ dy_src = 1.0 / ratioy;
+
+ y_src = 0;
+ for (y_dst = 0; y_dst < dst_height; y_dst++) {
+ float* line1 = src + ((int) y_src) * 4 * src_width;
+ float* line2 = line1 + 4 * src_width;
+ float weight1y = 1.0 - (y_src - (int) y_src);
+ float weight2y = 1.0 - weight1y;
+
+ if ((int) y_src == src_height - 1) {
+ line2 = line1;
+ }
+
+ x_src = 0;
+ for (x_dst = 0; x_dst < dst_width; x_dst++) {
+ float weight1x = 1.0 - (x_src - (int) x_src);
+ float weight2x = 1.0 - weight1x;
+
+ float w11 = weight1y * weight1x;
+ float w21 = weight2y * weight1x;
+ float w12 = weight1y * weight2x;
+ float w22 = weight2y * weight2x;
+
+ unsigned long x = ((int) x_src) * 4;
+
+ *dst++ = line1[x] * w11
+ + line2[x] * w21
+ + line1[4 + x] * w12
+ + line2[4 + x] * w22;
+
+ *dst++ = line1[x + 1] * w11
+ + line2[x + 1] * w21
+ + line1[4 + x + 1] * w12
+ + line2[4 + x + 1] * w22;
+
+ *dst++ = line1[x + 2] * w11
+ + line2[x + 2] * w21
+ + line1[4 + x + 2] * w12
+ + line2[4 + x + 2] * w22;
+
+ *dst++ = line1[x + 3] * w11
+ + line2[x + 3] * w21
+ + line1[4 + x + 3] * w12
+ + line2[4 + x + 3] * w22;
+
+ x_src += dx_src;
+ }
+ y_src += dy_src;
+ }
+}
+
+struct scale_outpix_float {
+ float r;
+ float g;
+ float b;
+ float a;
+
+ float weight;
+};
+
+static void shrink_picture_float(
+ float* src, float* dst, int src_width,
+ int src_height, int dst_width, int dst_height)
+{
+ double ratiox = (double) (dst_width) / (double) (src_width);
+ double ratioy = (double) (dst_height) / (double) (src_height);
+ unsigned long x_src;
+ unsigned long y_src;
+ float dx_dst, x_dst;
+ float dy_dst, y_dst;
+ float y_counter;
+ float * dst_begin = dst;
+
+ struct scale_outpix_float * dst_line1;
+ struct scale_outpix_float * dst_line2;
+
+ dst_line1 = (struct scale_outpix_float*) MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_float),
+ "shrink_picture_float 1");
+ dst_line2 = (struct scale_outpix_float*) MEM_callocN(
+ (dst_width + 1) * sizeof(struct scale_outpix_float),
+ "shrink_picture_float 2");
+
+ dx_dst = ratiox;
+ dy_dst = ratioy;
+
+ y_dst = 0;
+ y_counter = 1.0;
+ for (y_src = 0; y_src < src_height; y_src++) {
+ float* line = src + y_src * 4 * src_width;
+ unsigned long weight1y = 1.0 - (y_dst - (int) y_dst);
+ unsigned long weight2y = 1.0 - weight1y;
+ x_dst = 0;
+ for (x_src = 0; x_src < src_width; x_src++) {
+ unsigned long weight1x = 1.0 - (x_dst - (int) x_dst);
+ unsigned long weight2x = 1.0 - weight1x;
+
+ unsigned long x = (int) x_dst;
+
+ float w;
+
+ w = weight1y * weight1x;
+
+ dst_line1[x].r += line[0] * w;
+ dst_line1[x].g += line[1] * w;
+ dst_line1[x].b += line[2] * w;
+ dst_line1[x].a += line[3] * w;
+ dst_line1[x].weight += w;
+
+ w = weight2y * weight1x;
+
+ dst_line2[x].r += line[0] * w;
+ dst_line2[x].g += line[1] * w;
+ dst_line2[x].b += line[2] * w;
+ dst_line2[x].a += line[3] * w;
+ dst_line2[x].weight += w;
+
+ w = weight1y * weight2x;
+
+ dst_line1[x+1].r += line[0] * w;
+ dst_line1[x+1].g += line[1] * w;
+ dst_line1[x+1].b += line[2] * w;
+ dst_line1[x+1].a += line[3] * w;
+ dst_line1[x+1].weight += w;
+
+ w = weight2y * weight2x;
+
+ dst_line2[x+1].r += line[0] * w;
+ dst_line2[x+1].g += line[1] * w;
+ dst_line2[x+1].b += line[2] * w;
+ dst_line2[x+1].a += line[3] * w;
+ dst_line2[x+1].weight += w;
+
+ x_dst += dx_dst;
+ line += 4;
+ }
+
+ y_dst += dy_dst;
+ y_counter -= dy_dst;
+ if (y_counter < 0) {
+ unsigned long x;
+ struct scale_outpix_float * temp;
+
+ y_counter += 1.0;
+
+ for (x=0; x < dst_width; x++) {
+ float f = 1.0 / dst_line1[x].weight;
+ *dst++ = dst_line1[x].r * f;
+ *dst++ = dst_line1[x].g * f;
+ *dst++ = dst_line1[x].b * f;
+ *dst++ = dst_line1[x].a * f;
+ }
+ memset(dst_line1, 0, dst_width *
+ sizeof(struct scale_outpix_float));
+ temp = dst_line1;
+ dst_line1 = dst_line2;
+ dst_line2 = temp;
+ }
+ }
+ if (dst - dst_begin < dst_width * dst_height * 4) {
+ unsigned long x;
+ for (x = 0; x < dst_width; x++) {
+ float f = 1.0 / dst_line1[x].weight;
+ *dst++ = dst_line1[x].r * f;
+ *dst++ = dst_line1[x].g * f;
+ *dst++ = dst_line1[x].b * f;
+ *dst++ = dst_line1[x].a * f;
+ }
+ }
+ MEM_freeN(dst_line1);
+ MEM_freeN(dst_line2);
+}
+
+
+static void q_scale_float(float* in, float* out, int in_width,
+ int in_height, int dst_width, int dst_height)
+{
+ if (dst_width > in_width && dst_height > in_height) {
+ enlarge_picture_float(in, out, in_width, in_height,
+ dst_width, dst_height);
+ } else if (dst_width < in_width && dst_height < in_height) {
+ shrink_picture_float(in, out, in_width, in_height,
+ dst_width, dst_height);
+ }
+}
+
+/* q_scale_linear_interpolation (derived from ppmqscale, http://libdv.sf.net)
+
+ q stands for quick _and_ quality :)
+
+ only handles common cases when we either
+
+ scale both, x and y or
+ shrink both, x and y
+
+ but that is pretty fast:
+ * does only blit once instead of two passes like the old code
+ (fewer cache misses)
+ * uses fixed point integer arithmetic for byte buffers
+ * doesn't branch in tight loops
+
+ Should be comparable in speed to the ImBuf ..._fast functions at least
+ for byte-buffers.
+
+*/
+static int q_scale_linear_interpolation(
+ struct ImBuf *ibuf, int newx, int newy)
+{
+ if ((newx > ibuf->x && newy < ibuf->y) ||
+ (newx < ibuf->x && newy > ibuf->y)) {
+ return FALSE;
+ }
+
+ if (ibuf->rect) {
+ unsigned char * newrect =
+ MEM_mallocN(newx * newy * sizeof(int), "q_scale rect");
+ q_scale_byte((unsigned char *)ibuf->rect, newrect, ibuf->x, ibuf->y,
+ newx, newy);
+
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *) newrect;
+ }
+ if (ibuf->rect_float) {
+ float * newrect =
+ MEM_mallocN(newx * newy * 4 *sizeof(float),
+ "q_scale rectfloat");
+ q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y,
+ newx, newy);
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = newrect;
+ }
+ ibuf->x = newx;
+ ibuf->y = newy;
+
+ return TRUE;
+}
static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
{
@@ -1113,11 +1575,18 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy)
{
if (ibuf==NULL) return (0);
if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf);
+
+ if (newx == ibuf->x && newy == ibuf->y) { return ibuf; }
- // scaleup / scaledown functions below change ibuf->x and ibuf->y
- // so we first scale the Z-buffer (if any)
+ /* scaleup / scaledown functions below change ibuf->x and ibuf->y
+ so we first scale the Z-buffer (if any) */
scalefast_Z_ImBuf(ibuf, newx, newy);
+ /* try to scale common cases in a fast way */
+ if (q_scale_linear_interpolation(ibuf, newx, newy)) {
+ return ibuf;
+ }
+
if (newx < ibuf->x) if (newx) scaledownx(ibuf,newx);
if (newy < ibuf->y) if (newy) scaledowny(ibuf,newy);
if (newx > ibuf->x) if (newx) scaleupx(ibuf,newx);
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
new file mode 100644
index 00000000000..718b0537b48
--- /dev/null
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -0,0 +1,459 @@
+/**
+ * $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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Andrea Weikert.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* also defined in BKE_utildefines, repeated here to avoid dependency */
+#define FILE_MAX 240
+
+#include "BLI_blenlib.h"
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_thumbs.h"
+#include "IMB_imginfo.h"
+
+
+#include "md5.h"
+
+#ifdef WIN32
+#include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
+#endif
+#include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
+#include "BLI_winstuff.h"
+#include <process.h> /* getpid */
+#include <direct.h> /* chdir */
+#else
+#include <unistd.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#define URI_MAX FILE_MAX*3 + 8
+
+static int get_thumb_dir( char* dir , ThumbSize size)
+{
+#ifdef WIN32
+ /* yes, applications shouldn't store data there, but so does GIMP :)*/
+ SHGetSpecialFolderPath(0, dir, CSIDL_PROFILE, 0);
+#else
+ char* home = getenv("HOME");
+ if (!home) return 0;
+ BLI_strncpy(dir, home, FILE_MAX);
+#endif
+ switch(size) {
+ case THB_NORMAL:
+ strcat(dir, "/.thumbnails/normal/");
+ break;
+ case THB_LARGE:
+ strcat(dir, "/.thumbnails/large/");
+ break;
+ case THB_FAIL:
+ strcat(dir, "/.thumbnails/fail/blender/");
+ break;
+ default:
+ return 0; /* unknown size */
+ }
+ return 1;
+}
+
+/** ----- begin of adapted code from glib ---
+ * The following code is adapted from function g_escape_uri_string from the gnome glib
+ * Source: http://svn.gnome.org/viewcvs/glib/trunk/glib/gconvert.c?view=markup
+ * released under the Gnu General Public License.
+ */
+typedef enum {
+ UNSAFE_ALL = 0x1, /* Escape all unsafe characters */
+ UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */
+ UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
+ UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */
+ UNSAFE_SLASHES = 0x20 /* Allows all characters except for '/' and '%' */
+} UnsafeCharacterSet;
+
+static const unsigned char acceptable[96] = {
+ /* A table of the ASCII chars from space (32) to DEL (127) */
+ /* ! " # $ % & ' ( ) * + , - . / */
+ 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
+ /* @ A B C D E F G H I J K L M N O */
+ 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
+ /* ` a b c d e f g h i j k l m n o */
+ 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ /* p q r s t u v w x y z { | } ~ DEL */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20
+};
+
+static const char hex[17] = "0123456789abcdef";
+
+/* Note: This escape function works on file: URIs, but if you want to
+ * escape something else, please read RFC-2396 */
+void escape_uri_string (const char *string, char* escaped_string, int len,UnsafeCharacterSet mask)
+{
+#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
+
+ const char *p;
+ char *q;
+ int c;
+ UnsafeCharacterSet use_mask;
+ use_mask = mask;
+
+ for (q = escaped_string, p = string; (*p != '\0') && len; p++) {
+ c = (unsigned char) *p;
+ len--;
+
+ if (!ACCEPTABLE (c)) {
+ *q++ = '%'; /* means hex coming */
+ *q++ = hex[c >> 4];
+ *q++ = hex[c & 15];
+ } else {
+ *q++ = *p;
+ }
+ }
+
+ *q = '\0';
+}
+
+void to_hex_char(char* hexbytes, const unsigned char* bytes, int len)
+{
+ const unsigned char *p;
+ char *q;
+
+ for (q = hexbytes, p = bytes; len; p++) {
+ const unsigned char c = (unsigned char) *p;
+ len--;
+ *q++ = hex[c >> 4];
+ *q++ = hex[c & 15];
+ }
+}
+
+/** ----- end of adapted code from glib --- */
+
+static int uri_from_filename( const char *dir, const char *file, char *uri )
+{
+ char orig_uri[URI_MAX];
+ const char* dirstart = dir;
+
+#ifdef WIN32
+ {
+ char vol[3];
+
+ BLI_strncpy(orig_uri, "file:///", FILE_MAX);
+ if (strlen(dir) < 2 && dir[1] != ':') {
+ /* not a correct absolute path */
+ return 0;
+ }
+ /* on windows, using always uppercase drive/volume letter in uri */
+ vol[0] = (unsigned char)toupper(dir[0]);
+ vol[1] = ':';
+ vol[2] = '\0';
+ strcat(orig_uri, vol);
+ dirstart += 2;
+ }
+#else
+ BLI_strncpy(orig_uri, "file://", FILE_MAX);
+#endif
+ strcat(orig_uri, dirstart);
+ strcat(orig_uri, file);
+ BLI_char_switch(orig_uri, '\\', '/');
+
+#ifdef WITH_ICONV
+ {
+ char uri_utf8[FILE_MAX*3+8];
+ escape_uri_string(orig_uri, uri_utf8, FILE_MAX*3+8, UNSAFE_PATH);
+ BLI_string_to_utf8(uri_utf8, uri, NULL);
+ }
+#else
+ escape_uri_string(orig_uri, uri, FILE_MAX*3+8, UNSAFE_PATH);
+#endif
+ return 1;
+}
+
+static void thumbname_from_uri(const char* uri, char* thumb)
+{
+ char hexdigest[33];
+ unsigned char digest[16];
+
+ md5_buffer( uri, strlen(uri), digest);
+ hexdigest[0] = '\0';
+ to_hex_char(hexdigest, digest, 16);
+ hexdigest[32] = '\0';
+ sprintf(thumb, "%s.png", hexdigest);
+}
+
+static int thumbpath_from_uri(const char* uri, char* path, ThumbSize size)
+{
+ char tmppath[FILE_MAX];
+ int rv = 0;
+
+ if (get_thumb_dir(tmppath, size)) {
+ char thumb[40];
+ thumbname_from_uri(uri, thumb);
+ BLI_snprintf(path, FILE_MAX, "%s%s", tmppath, thumb);
+ rv = 1;
+ }
+ return rv;
+}
+
+
+/* create thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, ThumbSource source)
+{
+ ImBuf *img = 0;
+ char uri[URI_MAX];
+ char desc[URI_MAX+22];
+ char tpath[FILE_MAX];
+ char tdir[FILE_MAX];
+ char wdir[FILE_MAX];
+ char temp[FILE_MAX];
+ char mtime[40];
+ char cwidth[40];
+ char cheight[40];
+ char thumb[40];
+ short tsize = 128;
+ short ex, ey;
+ float scaledx, scaledy;
+ struct stat info;
+
+ switch(size) {
+ case THB_NORMAL:
+ tsize = 128;
+ break;
+ case THB_LARGE:
+ tsize = 256;
+ break;
+ case THB_FAIL:
+ tsize = 0;
+ break;
+ default:
+ return 0; /* unknown size */
+ }
+
+ uri_from_filename(dir, file,uri);
+ thumbname_from_uri(uri, thumb);
+ if (get_thumb_dir(tdir, size)) {
+ BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb);
+ thumb[8] = '\0'; /* shorten for tempname, not needed anymore */
+ BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb);
+ if (strncmp(thumb, dir, strlen(dir)) == 0) {
+ return NULL;
+ }
+ if (size == THB_FAIL) {
+ img = IMB_allocImBuf(0,0,32, IB_rect | IB_imginfo, 0);
+ if (!img) return 0;
+ } else {
+ if (THB_SOURCE_IMAGE == source) {
+ BLI_getwdN(wdir);
+ chdir(dir);
+ img = IMB_loadiffname(file, IB_rect | IB_imginfo);
+ if (img != NULL) {
+ stat(file, &info);
+ sprintf(mtime, "%ld", info.st_mtime);
+ sprintf(cwidth, "%d", img->x);
+ sprintf(cheight, "%d", img->y);
+ chdir(wdir);
+ }
+ } else if (THB_SOURCE_MOVIE == source) {
+ struct anim * anim = NULL;
+ BLI_getwdN(wdir);
+ chdir(dir);
+ anim = IMB_open_anim(file, IB_rect | IB_imginfo);
+ if (anim != NULL) {
+ img = IMB_anim_absolute(anim, 0);
+ if (img == NULL) {
+ printf("not an anim; %s\n", file);
+ } else {
+ IMB_freeImBuf(img);
+ img = IMB_anim_previewframe(anim);
+ }
+ IMB_free_anim(anim);
+ }
+ stat(file, &info);
+ sprintf(mtime, "%ld", info.st_mtime);
+ chdir(wdir);
+ }
+ if (!img) return 0;
+
+ if (img->x > img->y) {
+ scaledx = (float)tsize;
+ scaledy = ( (float)img->y/(float)img->x )*tsize;
+ }
+ else {
+ scaledy = (float)tsize;
+ scaledx = ( (float)img->x/(float)img->y )*tsize;
+ }
+ ex = (short)scaledx;
+ ey = (short)scaledy;
+
+ IMB_scaleImBuf(img, ex, ey);
+ }
+ sprintf(desc, "Thumbnail for %s", uri);
+ IMB_imginfo_change_field(img, "Description", desc);
+ IMB_imginfo_change_field(img, "Software", "Blender");
+ IMB_imginfo_change_field(img, "Thumb::URI", uri);
+ IMB_imginfo_change_field(img, "Thumb::MTime", mtime);
+ if (THB_SOURCE_IMAGE == source) {
+ IMB_imginfo_change_field(img, "Thumb::Image::Width", cwidth);
+ IMB_imginfo_change_field(img, "Thumb::Image::Height", cheight);
+ }
+ img->ftype = PNG;
+ img->depth = 32;
+ if (IMB_saveiff(img, temp, IB_rect | IB_imginfo)) {
+#ifndef WIN32
+ chmod(temp, S_IRUSR | S_IWUSR);
+#endif
+ BLI_rename(temp, tpath);
+ }
+
+ return img;
+ }
+ return img;
+}
+
+/* read thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_read(const char* dir, const char* file, ThumbSize size)
+{
+ char thumb[FILE_MAX];
+ char uri[FILE_MAX*3+8];
+ ImBuf *img = 0;
+
+ if (!uri_from_filename(dir, file,uri)) {
+ return NULL;
+ }
+ if (thumbpath_from_uri(uri, thumb, size)) {
+ img = IMB_loadiffname(thumb, IB_rect | IB_imginfo);
+ }
+
+ return img;
+}
+
+/* delete all thumbs for the file */
+void IMB_thumb_delete(const char* dir, const char* file, ThumbSize size)
+{
+ char thumb[FILE_MAX];
+ char uri[FILE_MAX*3+8];
+
+ if (!uri_from_filename(dir, file,uri)) {
+ return;
+ }
+ if (thumbpath_from_uri(uri, thumb, size)) {
+ if (strncmp(thumb, dir, strlen(dir)) == 0) {
+ return;
+ }
+ if (BLI_exists(thumb)) {
+ BLI_delete(thumb, 0, 0);
+ }
+ }
+}
+
+
+/* create the thumb if necessary and manage failed and old thumbs */
+ImBuf* IMB_thumb_manage(const char* dir, const char* file, ThumbSize size, ThumbSource source)
+{
+ char path[FILE_MAX];
+ char thumb[FILE_MAX];
+ char uri[FILE_MAX*3+8];
+ struct stat st;
+ ImBuf* img = NULL;
+
+ BLI_join_dirfile(path, dir, file);
+ if (stat(path, &st)) {
+ return NULL;
+ }
+ if (!uri_from_filename(dir, file,uri)) {
+ return NULL;
+ }
+ if (thumbpath_from_uri(uri, thumb, THB_FAIL)) {
+ /* failure thumb exists, don't try recreating */
+ if (BLI_exists(thumb)) {
+ return NULL;
+ }
+ }
+
+ if (thumbpath_from_uri(uri, thumb, size)) {
+ if (strncmp(thumb, dir, strlen(dir)) == 0) {
+ img = IMB_loadiffname(path, IB_rect);
+ } else {
+ img = IMB_loadiffname(thumb, IB_rect | IB_imginfo);
+ if (img) {
+ char mtime[40];
+ if (!IMB_imginfo_get_field(img, "Thumb::MTime", mtime, 40)) {
+ /* illegal thumb, forget it! */
+ IMB_freeImBuf(img);
+ img = 0;
+ } else {
+ time_t t = atol(mtime);
+ if (st.st_mtime != t) {
+ /* recreate all thumbs */
+ IMB_freeImBuf(img);
+ img = 0;
+ IMB_thumb_delete(dir, file, THB_NORMAL);
+ IMB_thumb_delete(dir, file, THB_LARGE);
+ IMB_thumb_delete(dir, file, THB_FAIL);
+ img = IMB_thumb_create(dir, file, size, source);
+ if(!img){
+ /* thumb creation failed, write fail thumb */
+ img = IMB_thumb_create(dir, file, THB_FAIL, source);
+ if (img) {
+ /* we don't need failed thumb anymore */
+ IMB_freeImBuf(img);
+ img = 0;
+ }
+ }
+ }
+ }
+ } else {
+ img = IMB_thumb_create(dir, file, size, source);
+ if(!img){
+ /* thumb creation failed, write fail thumb */
+ img = IMB_thumb_create(dir, file, THB_FAIL, source);
+ if (img) {
+ /* we don't need failed thumb anymore */
+ IMB_freeImBuf(img);
+ img = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return img;
+}
+
+
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 6fc5fb99f8b..dfa4e5831ba 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -43,7 +43,6 @@
* used to compress images.
*/
-#include <assert.h>
#include <string.h>
#include "imbuf.h"
@@ -108,7 +107,6 @@ int imb_tiff_DummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
*
* @return: Number of bytes actually read.
* 0 = EOF.
- * -1 = Error (never returned).
*/
tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
{
@@ -118,8 +116,10 @@ tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
/* get the pointer to the in-memory file */
mfile = IMB_TIFF_GET_MEMFILE(handle);
- assert(mfile != NULL);
- assert(mfile->mem != NULL);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n");
+ return 0;
+ }
/* find the actual number of bytes to read (copy) */
nCopy = n;
@@ -136,7 +136,6 @@ tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n)
return (0);
/* all set -> do the read (copy) */
- assert(sizeof(unsigned char) == 1);
srcAddr = (void*)(&(mfile->mem[mfile->offset]));
memcpy((void*)data, srcAddr, nCopy);
mfile->offset += nCopy; /* advance file ptr by copied bytes */
@@ -180,8 +179,10 @@ toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence)
/* get the pointer to the in-memory file */
mfile = IMB_TIFF_GET_MEMFILE(handle);
- assert(mfile != NULL);
- assert(mfile->mem != NULL);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n");
+ return (-1);
+ }
/* find the location we plan to seek to */
switch (whence) {
@@ -193,7 +194,9 @@ toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence)
break;
default:
/* no other types are supported - return an error */
- printf("Unsupported TIFF SEEK type.\n");
+ fprintf(stderr,
+ "imb_tiff_SeekProc: "
+ "Unsupported TIFF SEEK type.\n");
return (-1);
}
@@ -222,8 +225,10 @@ int imb_tiff_CloseProc(thandle_t handle)
/* get the pointer to the in-memory file */
mfile = IMB_TIFF_GET_MEMFILE(handle);
- assert(mfile != NULL);
- assert(mfile->mem != NULL); /* the file has not been closed yet */
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr,"imb_tiff_CloseProc: !mfile || !mfile->mem!\n");
+ return (0);
+ }
/* virtually close the file */
mfile->mem = NULL;
@@ -246,8 +251,10 @@ toff_t imb_tiff_SizeProc(thandle_t handle)
/* get the pointer to the in-memory file */
mfile = IMB_TIFF_GET_MEMFILE(handle);
- assert(mfile != NULL);
- assert(mfile->mem != NULL);
+ if (!mfile || !mfile->mem) {
+ fprintf(stderr,"imb_tiff_SizeProc: !mfile || !mfile->mem!\n");
+ return (0);
+ }
/* return the size */
return (toff_t)(mfile->size);
@@ -305,7 +312,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
struct ImBuf *ibuf = NULL;
struct ImbTIFFMemFile memFile;
uint32 width, height;
- int bytesperpixel;
+ int bytesperpixel, bitspersample;
int success;
unsigned int pixel_i, byte_i;
uint32 *raster = NULL;
@@ -317,7 +324,10 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
memFile.size = size;
/* check whether or not we have a TIFF file */
- assert(size >= IMB_TIFF_NCB);
+ if (size < IMB_TIFF_NCB) {
+ fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
+ return NULL;
+ }
if (imb_is_a_tiff(mem) == 0)
return NULL;
@@ -336,11 +346,13 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
bytesperpixel = 4; /* 1 byte per channel, 4 channels */
libtiff_TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
libtiff_TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
+ libtiff_TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
ibuf = IMB_allocImBuf(width, height, 8*bytesperpixel, 0, 0);
if (ibuf) {
ibuf->ftype = TIF;
} else {
- printf("imb_loadtiff: could not allocate memory for TIFF " \
+ fprintf(stderr,
+ "imb_loadtiff: could not allocate memory for TIFF " \
"image.\n");
libtiff_TIFFClose(image);
return NULL;
@@ -362,7 +374,8 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
success = libtiff_TIFFReadRGBAImage(
image, width, height, raster, 0);
if (!success) {
- printf("imb_loadtiff: This TIFF format is not " \
+ fprintf(stderr,
+ "imb_loadtiff: This TIFF format is not "
"currently supported by Blender.\n");
libtiff__TIFFfree(raster);
libtiff_TIFFClose(image);
@@ -378,7 +391,8 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
/* this may not be entirely necessary, but is put here
* in case sizeof(unsigned int) is not a 32-bit
* quantity */
- printf("imb_loadtiff: using (slower) component-wise " \
+ fprintf(stderr,
+ "imb_loadtiff: using (slower) component-wise "
"buffer copy.\n");
to = (unsigned char*)ibuf->rect;
for (pixel_i=0; pixel_i < width*height; pixel_i++)
@@ -405,8 +419,6 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
return (ibuf);
}
-
-
/**
* Saves a TIFF file.
*
@@ -422,14 +434,19 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
*
* @return: 1 if the function is successful, 0 on failure.
*/
+
+#define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*65535.0f + 0.5f))
+
short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
{
TIFF *image = NULL;
- uint16 samplesperpixel;
+ uint16 samplesperpixel, bitspersample;
size_t npixels;
unsigned char *pixels = NULL;
unsigned char *from = NULL, *to = NULL;
- int x, y, from_i, to_i;
+ unsigned short *pixels16 = NULL, *to16 = NULL;
+ float *fromf = NULL;
+ int x, y, from_i, to_i, i;
int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
/* check for a valid number of bytes per pixel. Like the PNG writer,
@@ -437,15 +454,22 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
* to gray, RGB, RGBA respectively. */
samplesperpixel = (uint16)((ibuf->depth + 7) >> 3);
if ((samplesperpixel > 4) || (samplesperpixel == 2)) {
- printf("imb_savetiff: unsupported number of bytes per " \
+ fprintf(stderr,
+ "imb_savetiff: unsupported number of bytes per "
"pixel: %d\n", samplesperpixel);
return (0);
}
+ if((ibuf->ftype & TIF_16BIT) && ibuf->rect_float)
+ bitspersample = 16;
+ else
+ bitspersample = 8;
+
/* open TIFF file for writing */
if (flags & IB_mem) {
/* bork at the creation of a TIFF in memory */
- printf("imb_savetiff: creation of in-memory TIFF files is " \
+ fprintf(stderr,
+ "imb_savetiff: creation of in-memory TIFF files is "
"not yet supported.\n");
return (0);
} else {
@@ -453,72 +477,74 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
image = libtiff_TIFFOpen(name, "w");
}
if (image == NULL) {
- printf("imb_savetiff: could not open TIFF for writing.\n");
+ fprintf(stderr,
+ "imb_savetiff: could not open TIFF for writing.\n");
return (0);
}
/* allocate array for pixel data */
npixels = ibuf->x * ibuf->y;
- pixels = (unsigned char*)libtiff__TIFFmalloc(npixels *
- samplesperpixel * sizeof(unsigned char));
- if (pixels == NULL) {
- printf("imb_savetiff: could not allocate pixels array.\n");
+ if(ibuf->ftype & TIF_16BIT)
+ pixels16 = (unsigned short*)libtiff__TIFFmalloc(npixels *
+ samplesperpixel * sizeof(unsigned short));
+ else
+ pixels = (unsigned char*)libtiff__TIFFmalloc(npixels *
+ samplesperpixel * sizeof(unsigned char));
+
+ if (pixels == NULL && pixels16 == NULL) {
+ fprintf(stderr,
+ "imb_savetiff: could not allocate pixels array.\n");
libtiff_TIFFClose(image);
return (0);
}
- /* copy pixel data. While copying, we flip the image
- * vertically. */
- from = (unsigned char*)ibuf->rect;
- to = pixels;
+ /* setup pointers */
+ if(ibuf->ftype & TIF_16BIT) {
+ fromf = ibuf->rect_float;
+ to16 = pixels16;
+ }
+ else {
+ from = (unsigned char*)ibuf->rect;
+ to = pixels;
+ }
+
+ /* setup samples per pixel */
+ libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample);
libtiff_TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
- switch (samplesperpixel) {
- case 4: /* RGBA images, 8 bits per channel */
- libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
- extraSampleTypes);
- libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
- libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_RGB);
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- from_i = 4*(y*ibuf->x+x);
- to_i = 4*((ibuf->y-y-1)*ibuf->x+x);
-
- to[to_i++] = from[from_i++];
- to[to_i++] = from[from_i++];
- to[to_i++] = from[from_i++];
- to[to_i] = from[from_i];
- }
- }
- break;
- case 3: /* RGB images, 8 bits per channel */
- libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
- libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_RGB);
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- from_i = 4*(y*ibuf->x+x);
- to_i = 3*((ibuf->y-y-1)*ibuf->x+x);
-
- to[to_i++] = from[from_i++];
- to[to_i++] = from[from_i++];
- to[to_i] = from[from_i];
- }
- }
- break;
- case 1: /* greyscale images, 1 channel with 8 bits */
- libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
- libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
- PHOTOMETRIC_MINISBLACK);
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- from_i = 4*(y*ibuf->x+x);
- to_i = 1*((ibuf->y-y-1)*ibuf->x+x);
+ if(samplesperpixel == 4) {
+ /* RGBA images */
+ libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
+ extraSampleTypes);
+ libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
+ PHOTOMETRIC_RGB);
+ }
+ else if(samplesperpixel == 3) {
+ /* RGB images */
+ libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
+ PHOTOMETRIC_RGB);
+ }
+ else if(samplesperpixel == 1) {
+ /* greyscale images, 1 channel */
+ libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
+ PHOTOMETRIC_MINISBLACK);
+ }
+
+ /* copy pixel data. While copying, we flip the image vertically. */
+ for (x = 0; x < ibuf->x; x++) {
+ for (y = 0; y < ibuf->y; y++) {
+ from_i = 4*(y*ibuf->x+x);
+ to_i = samplesperpixel*((ibuf->y-y-1)*ibuf->x+x);
+
+ if(pixels16) {
+ for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
+ to16[to_i] = FTOUSHORT(fromf[from_i]);
+ }
+ else {
+ for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
to[to_i] = from[from_i];
- }
}
- break;
+ }
}
/* write the actual TIFF file */
@@ -531,17 +557,21 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
libtiff_TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0);
libtiff_TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0);
libtiff_TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
- if (libtiff_TIFFWriteEncodedStrip(image, 0, pixels,
- ibuf->x*ibuf->y*samplesperpixel) == -1) {
- printf("imb_savetiff: Could not write encoded TIFF.\n");
+ if (libtiff_TIFFWriteEncodedStrip(image, 0,
+ (bitspersample == 16)? (unsigned char*)pixels16: pixels,
+ ibuf->x*ibuf->y*samplesperpixel*bitspersample/8) == -1) {
+ fprintf(stderr,
+ "imb_savetiff: Could not write encoded TIFF.\n");
libtiff_TIFFClose(image);
- libtiff__TIFFfree(pixels);
+ if(pixels) libtiff__TIFFfree(pixels);
+ if(pixels16) libtiff__TIFFfree(pixels16);
return (1);
}
/* close the TIFF file */
libtiff_TIFFClose(image);
- libtiff__TIFFfree(pixels);
+ if(pixels) libtiff__TIFFfree(pixels);
+ if(pixels16) libtiff__TIFFfree(pixels16);
return (1);
}
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 69390951a25..acf15c04ed9 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -44,6 +44,11 @@
#include "IMB_targa.h"
#include "IMB_png.h"
+
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
+
#include "IMB_bmp.h"
#include "IMB_tiff.h"
#include "IMB_radiance_hdr.h"
@@ -113,6 +118,9 @@ static int IMB_ispic_name(char *name)
}
if (imb_is_a_png(buf)) return(PNG);
+#ifdef WITH_DDS
+ if (imb_is_a_dds((uchar *)buf)) return(DDS);
+#endif
if (imb_is_a_targa(buf)) return(TGA);
#ifdef WITH_OPENEXR
if (imb_is_a_openexr((uchar *)buf)) return(OPENEXR);
@@ -162,6 +170,9 @@ int IMB_ispic(char *filename)
|| BLI_testextensie(filename, ".rgb")
|| BLI_testextensie(filename, ".bmp")
|| BLI_testextensie(filename, ".png")
+#ifdef WITH_DDS
+ || BLI_testextensie(filename, ".dds")
+#endif
|| BLI_testextensie(filename, ".iff")
|| BLI_testextensie(filename, ".lbm")
|| BLI_testextensie(filename, ".gif")
@@ -188,6 +199,9 @@ int IMB_ispic(char *filename)
|| BLI_testextensie(filename, ".bmp")
|| BLI_testextensie(filename, ".png")
|| BLI_testextensie(filename, ".cin")
+#ifdef WITH_DDS
+ || BLI_testextensie(filename, ".dds")
+#endif
#ifdef WITH_BF_OPENEXR
|| BLI_testextensie(filename, ".exr")
#endif
@@ -251,6 +265,7 @@ static int isffmpeg (char *filename) {
if( BLI_testextensie(filename, ".swf") ||
BLI_testextensie(filename, ".jpg") ||
BLI_testextensie(filename, ".png") ||
+ BLI_testextensie(filename, ".dds") ||
BLI_testextensie(filename, ".tga") ||
BLI_testextensie(filename, ".bmp") ||
BLI_testextensie(filename, ".exr") ||
@@ -274,8 +289,9 @@ static int isffmpeg (char *filename) {
/* Find the first video stream */
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
- if(get_codec_from_stream(pFormatCtx->streams[i])
- ->codec_type==CODEC_TYPE_VIDEO)
+ if(pFormatCtx->streams[i] &&
+ get_codec_from_stream(pFormatCtx->streams[i]) &&
+ (get_codec_from_stream(pFormatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO))
{
videoStream=i;
break;
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index 2e922c65827..ccca8e9f859 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -61,6 +61,9 @@
#ifdef WITH_OPENEXR
#include "openexr/openexr_api.h"
#endif
+#ifdef WITH_DDS
+#include "dds/dds_api.h"
+#endif
#include "IMB_iff.h"
#include "IMB_bitplanes.h"
@@ -115,6 +118,13 @@ short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags)
return imb_save_openexr(ibuf, name, flags);
}
#endif
+/* not supported yet
+#ifdef WITH_DDS
+ if (IS_dds(ibuf)) {
+ return imb_save_dds(ibuf, name, flags);
+ }
+#endif
+*/
if (IS_cineon(ibuf)) {
return imb_savecineon(ibuf, name, flags);
diff --git a/source/blender/include/BDR_drawaction.h b/source/blender/include/BDR_drawaction.h
index fdbd710c59f..72b3de1e54d 100644
--- a/source/blender/include/BDR_drawaction.h
+++ b/source/blender/include/BDR_drawaction.h
@@ -38,9 +38,23 @@ struct Ipo;
struct IpoCurve;
struct gla2DDrawInfo;
struct bAction;
+struct bActionGroup;
struct Object;
struct ListBase;
+/* ****************************** Base Structs ****************************** */
+
+/* Keyframe Column Struct */
+typedef struct ActKeyColumn {
+ struct ActKeyColumn *next, *prev;
+ short sel, handle_type;
+ float cfra;
+
+ /* only while drawing - used to determine if long-keyframe needs to be drawn */
+ short modified;
+ short totcurve;
+} ActKeyColumn;
+
/* 'Long Keyframe' Struct */
typedef struct ActKeyBlock {
struct ActKeyBlock *next, *prev;
@@ -53,21 +67,31 @@ typedef struct ActKeyBlock {
short totcurve;
} ActKeyBlock;
-/*Action Generics */
+
+/* Inclusion-Range Limiting Struct (optional) */
+typedef struct ActKeysInc {
+ struct Object *ob; /* if present, used to find action-scaled time */
+ float start, end; /* frames (global-time) to only consider keys between */
+} ActKeysInc;
+
+/* ******************************* Methods ****************************** */
+
+/* Action Generics */
void draw_cfra_action(void);
-int count_action_levels (struct bAction *act);
/* Channel Drawing */
void draw_icu_channel(struct gla2DDrawInfo *di, struct IpoCurve *icu, float ypos);
void draw_ipo_channel(struct gla2DDrawInfo *di, struct Ipo *ipo, float ypos);
-void draw_action_channel(struct gla2DDrawInfo *di, bAction *act, float ypos);
-void draw_object_channel(struct gla2DDrawInfo *di, Object *ob, float ypos);
+void draw_agroup_channel(struct gla2DDrawInfo *di, struct bActionGroup *agrp, float ypos);
+void draw_action_channel(struct gla2DDrawInfo *di, struct bAction *act, float ypos);
+void draw_object_channel(struct gla2DDrawInfo *di, struct Object *ob, float ypos);
/* Keydata Generation */
-void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks);
-int ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks);
-int action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks);
-int ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks);
+void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
+void ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
+void agroup_to_keylist(struct bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
+void action_to_keylist(struct bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
+void ob_to_keylist(struct Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki);
#endif /* BDR_DRAWACTION_H */
diff --git a/source/blender/include/BDR_drawmesh.h b/source/blender/include/BDR_drawmesh.h
index 60c87308e20..998cadc18a3 100644
--- a/source/blender/include/BDR_drawmesh.h
+++ b/source/blender/include/BDR_drawmesh.h
@@ -36,6 +36,7 @@
struct Image;
struct MTFace;
struct Object;
+struct DerivedMesh;
struct Mesh;
struct EdgeHash;
@@ -75,7 +76,7 @@ int set_tpage(struct MTFace *tface);
void texpaint_enable_mipmap(void);
void texpaint_disable_mipmap(void);
-void draw_tface_mesh(struct Object *ob, struct Mesh *me, int dt);
+void draw_mesh_textured(struct Object *ob, struct DerivedMesh *dm, int facesel);
struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me);
void init_realtime_GL(void);
diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h
index a6319f2333c..70282aeb0c8 100644
--- a/source/blender/include/BDR_editcurve.h
+++ b/source/blender/include/BDR_editcurve.h
@@ -78,11 +78,13 @@ void extrude_nurb(void);
void makecyclicNurb(void);
void selectconnected_nurb(void);
void selectrow_nurb(void);
-void selectends_nurb(int selFirst);
+void selectend_nurb(short selfirst, short doswap, short selstatus);
void select_more_nurb(void);
void select_less_nurb(void);
void select_next_nurb(void);
void select_prev_nurb(void);
+void select_random_nurb(void);
+void select_every_nth_nurb(void);
void adduplicate_nurb(void);
void delNurb(void);
void nurb_set_smooth(short event);
@@ -94,8 +96,10 @@ void add_primitiveNurb(int type);
void clear_tilt(void);
void clever_numbuts_curve(void);
int bezt_compare (const void *e1, const void *e2);
+void setweightNurb( void );
+void setradiusNurb( void );
+void smoothradiusNurb( void );
extern void undo_push_curve(char *name);
#endif /* BDR_EDITCURVE_H */
-
diff --git a/source/blender/include/BDR_editface.h b/source/blender/include/BDR_editface.h
index 31971da292b..72b0e7352da 100644
--- a/source/blender/include/BDR_editface.h
+++ b/source/blender/include/BDR_editface.h
@@ -34,10 +34,11 @@
#define BDR_EDITFACE_H
struct MTFace;
+struct EditFace;
struct Mesh;
struct MCol;
-struct MTFace *get_active_tface(struct MCol **mcol);
+struct MTFace *get_active_mtface(struct EditFace **efa, struct MCol **mcol, short sloppy);
void calculate_uv_map(unsigned short mapmode);
void default_uv(float uv[][2], float size);
void make_tfaces(struct Mesh *me);
@@ -52,7 +53,6 @@ int minmax_tface(float *min, float *max);
void face_select(void);
void face_borderselect(void);
void uv_autocalc_tface(void);
-void set_faceselect(void);
void set_texturepaint(void);
void get_same_uv(void);
void seam_mark_clear_tface(short mode);
diff --git a/source/blender/include/BDR_editmball.h b/source/blender/include/BDR_editmball.h
index c3e9eaaf66c..e2b529acaf8 100644
--- a/source/blender/include/BDR_editmball.h
+++ b/source/blender/include/BDR_editmball.h
@@ -42,6 +42,8 @@ void load_editMball(void);
*/
void add_primitiveMball(int);
void deselectall_mball(void);
+void selectinverse_mball(void);
+void selectrandom_mball(void);
void mouse_mball(void);
void adduplicate_mball(void);
void delete_mball(void);
diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h
index 2a96a8d65cb..3bc725f5662 100644
--- a/source/blender/include/BDR_editobject.h
+++ b/source/blender/include/BDR_editobject.h
@@ -65,6 +65,8 @@ void exit_editmode(int flag);
void check_editmode(int type);
void enter_editmode(int wc);
+void exit_paint_modes(void);
+
void docenter(int centermode);
void docenter_new(void);
void docenter_cursor(void);
@@ -77,6 +79,8 @@ void link_to_scene(unsigned short nr);
void make_links_menu(void);
void make_links(short event);
void make_duplilist_real(void);
+void apply_objects_locrot(void);
+void apply_objects_visual_tx(void);
void apply_object(void);
/* old transform */
@@ -93,6 +97,7 @@ void single_object_users(int flag);
void new_id_matar(struct Material **matar, int totcol);
void single_obdata_users(int flag);
void single_mat_users(int flag);
+void single_ipo_users(int flag);
void do_single_tex_user(struct Tex **from);
void single_tex_users_expand(void);
void single_mat_users_expand(void);
@@ -107,16 +112,20 @@ void set_ob_ipoflags(void);
void select_select_keys(void);
int vergbaseco(const void *a1, const void *a2);
void auto_timeoffs(void);
+void ofs_timeoffs(void);
+void rand_timeoffs(void);
void texspace_edit(void);
void flip_subdivison(int);
void mirrormenu(void);
void hookmenu(void); /* object mode hook menu */
-void add_hook(void);
+void add_hook_menu(void);
+void add_hook(int mode);
void hook_select(struct HookModifierData *hmd);
int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r);
+int object_is_libdata(struct Object *ob);
int object_data_is_libdata(struct Object *ob);
void hide_objects(int select);
void show_objects(void);
diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h
index 0e80a7f0185..e36b8674612 100644
--- a/source/blender/include/BDR_sculptmode.h
+++ b/source/blender/include/BDR_sculptmode.h
@@ -30,12 +30,12 @@
#ifndef BDR_SCULPTMODE_H
#define BDR_SCULPTMODE_H
-/* For bglMats */
-#include "BIF_glutil.h"
-
-#include "transform.h"
+#include "DNA_listBase.h"
+#include "DNA_vec_types.h"
+#include "BKE_sculpt.h"
struct uiBlock;
+struct BrushAction;
struct BrushData;
struct IndexNode;
struct KeyBlock;
@@ -45,77 +45,43 @@ struct PartialVisibility;
struct Scene;
struct ScrArea;
struct SculptData;
+struct SculptStroke;
-typedef enum PropsetMode {
- PropsetNone = 0,
- PropsetSize,
- PropsetStrength,
- PropsetTexRot
-} PropsetMode;
-typedef struct PropsetData {
- PropsetMode mode;
- unsigned int tex;
- short origloc[2];
- float *texdata;
-
- short origsize;
- char origstrength;
- float origtexrot;
-
- NumInput num;
-} PropsetData;
-
-typedef struct SculptSession {
- bglMats mats;
-
- /* An array of lists; array is sized as
- large as the number of verts in the mesh,
- the list for each vert contains the index
- for all the faces that use that vertex */
- struct ListBase *vertex_users;
- struct IndexNode *vertex_users_mem;
- int vertex_users_size;
-
- /* Used to cache the render of the active texture */
- unsigned int texcache_w, texcache_h, *texcache;
-
- PropsetData *propset;
-
- /* For rotating around a pivot point */
- vec3f pivot;
-} SculptSession;
-
-SculptSession *sculpt_session(void);
+struct SculptSession *sculpt_session(void);
struct SculptData *sculpt_data(void);
/* Memory */
-void sculptmode_init(struct Scene *);
-void sculptmode_free_all(struct Scene *);
void sculptmode_correct_state(void);
/* Interface */
void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy);
+void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy);
void sculptmode_rem_tex(void*,void*);
-void sculptmode_propset_init(PropsetMode mode);
-void sculptmode_propset(const unsigned short event);
void sculptmode_selectbrush_menu(void);
void sculptmode_draw_mesh(int);
void sculpt_paint_brush(char clear);
+void sculpt_stroke_draw();
+void sculpt_radialcontrol_start(int mode);
struct BrushData *sculptmode_brush(void);
-float tex_angle(void);
+void do_symmetrical_brush_actions(struct BrushAction *a, short *, short *);
void sculptmode_update_tex(void);
char sculpt_modifiers_active(struct Object *ob);
void sculpt(void);
void set_sculptmode(void);
+/* Stroke */
+void sculpt_stroke_new(const int max);
+void sculpt_stroke_free();
+void sculpt_stroke_add_point(const short x, const short y);
+void sculpt_stroke_apply(struct BrushAction *);
+void sculpt_stroke_apply_all(struct BrushAction *);
+void sculpt_stroke_draw();
+
+
/* Partial Mesh Visibility */
-struct PartialVisibility *sculptmode_copy_pmv(struct PartialVisibility *);
-void sculptmode_pmv_free(struct PartialVisibility *);
-void sculptmode_revert_pmv(struct Mesh *me);
-void sculptmode_pmv_off(struct Mesh *me);
void sculptmode_pmv(int mode);
#endif
diff --git a/source/blender/include/BDR_unwrapper.h b/source/blender/include/BDR_unwrapper.h
index 6a2b54409c3..a6ff1b614a5 100644
--- a/source/blender/include/BDR_unwrapper.h
+++ b/source/blender/include/BDR_unwrapper.h
@@ -41,6 +41,7 @@ void select_linked_tfaces_with_seams(int mode, struct Mesh *me, unsigned int ind
void unwrap_lscm(short seamcut); /* unwrap faces selected in 3d view */
void minimize_stretch_tface_uv(void); /* optimize faces selected in uv editor */
void pack_charts_tface_uv(void);
+void average_charts_tface_uv(void);
/* for live mode: no undo pushes, caching for quicky re-unwrap */
void unwrap_lscm_live_begin(void);
diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h
index f87e9797cb3..9d5e1961178 100644
--- a/source/blender/include/BIF_butspace.h
+++ b/source/blender/include/BIF_butspace.h
@@ -83,11 +83,13 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev);
#define TAB_OBJECT_OBJECT 0
#define TAB_OBJECT_PHYSICS 1
+#define TAB_OBJECT_PARTICLE 2
#define TAB_SCENE_RENDER 0
-#define TAB_SCENE_WORLD 1
+#define TAB_SCENE_WORLD 1
#define TAB_SCENE_ANIM 2
#define TAB_SCENE_SOUND 3
+#define TAB_SCENE_SEQUENCER 4
/* buts->scaflag */
@@ -102,6 +104,38 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev);
#define BUTS_ACT_LINK 256
+/* buttons grid */
+#define PANELX 320
+#define PANELY 0
+#define PANELW 318
+#define PANELH 204
+
+#define BUTW1 300
+#define BUTW2 145
+#define BUTW3 93
+#define BUTW4 67
+#define ICONBUTW 20
+#define BUTH 22
+
+#define YSPACE 6
+#define XSPACE 10
+#define PANEL_YMAX 210
+#define PANEL_XMAX 310
+
+#define X1CLM1 10
+
+#define X2CLM1 X1CLM1
+#define X2CLM2 165
+
+#define X3CLM1 X1CLM1
+#define X3CLM2 113
+#define X3CLM3 217
+
+#define X4CLM1 X1CLM1
+#define X4CLM2 77
+#define X4CLM3 165
+#define X4CLM4 232
+
#endif
diff --git a/source/blender/include/BIF_drawimage.h b/source/blender/include/BIF_drawimage.h
index 72562b76beb..5ad1978a6e2 100644
--- a/source/blender/include/BIF_drawimage.h
+++ b/source/blender/include/BIF_drawimage.h
@@ -39,12 +39,16 @@ struct Render;
struct Image;
struct ImBuf;
struct uiBlock;
+struct MTFace;
void do_imagebuts(unsigned short event);
void calc_image_view(struct SpaceImage *sima, char mode);
void drawimagespace(struct ScrArea *sa, void *spacedata);
-void draw_tfaces(void);
-void image_changed(struct SpaceImage *sima, int dotile);
+void image_changed(struct SpaceImage *sima, struct Image *image);
+int draw_uvs_face_check(void);
+void tface_center(struct MTFace *tf, float cent[2], void * isquad);
+void draw_uvs_sima(void);
+void image_set_tile(struct SpaceImage *sima, int dotile);
void image_home(void);
void image_viewmove(int mode);
void image_viewzoom(unsigned short event, int invert);
@@ -59,11 +63,10 @@ void imagespace_composite_flipbook(struct ScrArea *sa);
void imagewindow_render_callbacks(struct Render *re);
void imagewindow_toggle_render(void);
-void imagewindow_swap_render_rects(void);
-void imagewin_store_spare(void);
struct ImBuf *imagewindow_get_ibuf(struct SpaceImage *sima);
void image_editvertex_buts(struct uiBlock *block);
+void image_editcursor_buts(struct uiBlock *block);
#endif
diff --git a/source/blender/include/BIF_drawseq.h b/source/blender/include/BIF_drawseq.h
index 986044d9c7e..4571267a09c 100644
--- a/source/blender/include/BIF_drawseq.h
+++ b/source/blender/include/BIF_drawseq.h
@@ -36,6 +36,7 @@
struct ScrArea;
struct Sequence;
+void drawprefetchseqspace(struct ScrArea *sa, void *spacedata);
void drawseqspace(struct ScrArea *sa, void *spacedata);
void set_special_seq_update(int val);
diff --git a/source/blender/include/BIF_drawtext.h b/source/blender/include/BIF_drawtext.h
index a63e2bb264d..6950f3ba215 100644
--- a/source/blender/include/BIF_drawtext.h
+++ b/source/blender/include/BIF_drawtext.h
@@ -47,7 +47,7 @@ void add_text_fs(char *file);
void free_txt_data(void);
void pop_space_text(struct SpaceText *st);
-void get_format_string(void);
+void get_format_string(struct SpaceText *st);
void do_brackets(void);
#endif
diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h
index 6e180418cd8..7fb2a6b2dde 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung, Action Editor Recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -33,32 +33,32 @@
#ifndef BIF_EDITACTION_H
#define BIF_EDITACTION_H
-#define SET_IPO_POPUP 0
-#define SET_IPO_CONSTANT 1
-#define SET_IPO_LINEAR 2
-#define SET_IPO_BEZIER 3
-
-#define SET_EXTEND_POPUP 0
-#define SET_EXTEND_CONSTANT 1
-#define SET_EXTEND_EXTRAPOLATION 2
-#define SET_EXTEND_CYCLIC 3
-#define SET_EXTEND_CYCLICEXTRAPOLATION 4
-
+/* some interface related sizes*/
#define CHANNELHEIGHT 16
#define CHANNELSKIP 2
-#define NAMEWIDTH 164
-#define SLIDERWIDTH 125
+#define NAMEWIDTH 164
+#define SLIDERWIDTH 125
#define ACTWIDTH (G.saction->actwidth)
/* Some types for easier type-testing */
-#define ACTTYPE_NONE 0
-#define ACTTYPE_ACHAN 1
-#define ACTTYPE_CONCHAN 2
-#define ACTTYPE_ICU 3
-#define ACTTYPE_FILLIPO 4
-#define ACTTYPE_FILLCON 5
+enum {
+ ACTTYPE_NONE= 0,
+ ACTTYPE_GROUP,
+ ACTTYPE_ACHAN,
+ ACTTYPE_CONCHAN,
+ ACTTYPE_CONCHAN2,
+ ACTTYPE_ICU,
+ ACTTYPE_FILLIPO,
+ ACTTYPE_FILLCON,
+ ACTTYPE_IPO,
+ ACTTYPE_SHAPEKEY
+};
/* Macros for easier/more consistant state testing */
+#define EDITABLE_AGRP(agrp) ((agrp->flag & AGRP_PROTECTED)==0)
+#define EXPANDED_AGRP(agrp) (agrp->flag & AGRP_EXPANDED)
+#define SEL_AGRP(agrp) ((agrp->flag & AGRP_SELECTED) || (agrp->flag & AGRP_ACTIVE))
+
#define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
#define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0))
#define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED))
@@ -72,75 +72,127 @@
#define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
#define SEL_ICU(icu) (icu->flag & IPO_SELECT)
+#define NLA_ACTION_SCALED (G.saction->pin==0 && OBACT && OBACT->action)
+#define NLA_IPO_SCALED (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname)
+
+/* constants for setting ipo-interpolation type */
+enum {
+ SET_IPO_MENU = -1,
+ SET_IPO_POPUP = 0,
+
+ SET_IPO_CONSTANT,
+ SET_IPO_LINEAR,
+ SET_IPO_BEZIER,
+};
+
+/* constants for setting ipo-extrapolation type */
+enum {
+ SET_EXTEND_MENU = 9,
+ SET_EXTEND_POPUP = 10,
+
+ SET_EXTEND_CONSTANT,
+ SET_EXTEND_EXTRAPOLATION,
+ SET_EXTEND_CYCLIC,
+ SET_EXTEND_CYCLICEXTRAPOLATION
+};
+
+/* constants for channel rearranging */
+/* WARNING: don't change exising ones without modifying rearrange func accordingly */
+enum {
+ REARRANGE_ACTCHAN_TOP= -2,
+ REARRANGE_ACTCHAN_UP= -1,
+ REARRANGE_ACTCHAN_DOWN= 1,
+ REARRANGE_ACTCHAN_BOTTOM= 2
+};
+
+
struct bAction;
struct bActionChannel;
+struct bActionGroup;
+struct bPose;
struct bPoseChannel;
struct Object;
struct Ipo;
struct BWinEvent;
struct Key;
struct ListBase;
+struct TimeMarker;
/* Key operations */
-void delete_meshchannel_keys(struct Key *key);
-void delete_actionchannel_keys(void);
-void duplicate_meshchannel_keys(struct Key *key);
-void duplicate_actionchannel_keys(void);
-void transform_actionchannel_keys(int mode, int dummy);
-void transform_meshchannel_keys(char mode, struct Key *key);
-void snap_keys_to_frame(int snap_mode);
-void mirror_action_keys(short mirror_mode);
-void clean_shapekeys(struct Key *key);
-void clean_actionchannels(struct bAction *act);
+void transform_action_keys(int mode, int dummy);
+void duplicate_action_keys(void);
+void snap_cfra_action(void);
+void snap_action_keys(short mode);
+void mirror_action_keys(short mode);
void insertkey_action(void);
-
-/* Marker Operations */
-void column_select_shapekeys(struct Key *key, int mode);
-void column_select_actionkeys(struct bAction *act, int mode);
+void delete_action_keys(void);
+void delete_action_channels(void);
+void clean_action(void);
+void sample_action_keys(void);
+
+/* Column/Channel Key select */
+void column_select_action_keys(int mode);
+void selectall_action_keys(short mval[], short mode, short selectmode);
void markers_selectkeys_between(void);
+void nextprev_action_keyframe(short dir);
+
+/* Action Data Copying */
+void free_actcopybuf(void);
+void copy_actdata(void);
+void paste_actdata(void);
+
+/* Group/Channel Operations */
+struct bActionGroup *get_active_actiongroup(struct bAction *act);
+void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
+void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
+void action_groups_group(short add_group);
+void action_groups_ungroup(void);
-/* channel/strip operations */
-void up_sel_action(void);
-void down_sel_action(void);
-void top_sel_action(void);
-void bottom_sel_action(void);
+/* Channel/Strip Operations */
+void rearrange_action_channels(short mode);
-/* Handles */
-void sethandles_meshchannel_keys(int code, struct Key *key);
-void sethandles_actionchannel_keys(int code);
+void expand_all_action(void);
+void expand_obscuregroups_action(void);
+void openclose_level_action(short mode);
+void setflag_action_channels(short mode);
-/* Ipo type */
-void set_ipotype_actionchannels(int ipotype);
-void set_extendtype_actionchannels(int extendtype);
+/* IPO/Handle Types */
+void sethandles_action_keys(int code);
+void action_set_ipo_flags(short mode, short event);
/* Select */
-void borderselect_mesh(struct Key *key);
void borderselect_action(void);
-void deselect_actionchannel_keys(struct bAction *act, int test, int sel);
-void deselect_actionchannels (struct bAction *act, int test);
-void deselect_meshchannel_keys (struct Key *key, int test, int sel);
+void deselect_action_keys(short test, short sel);
+void deselect_action_channels(short mode);
+void deselect_actionchannels(struct bAction *act, short mode);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
-void select_actionchannel_by_name (struct bAction *act, char *name, int select);
+void select_actionchannel_by_name(struct bAction *act, char *name, int select);
+void selectkeys_leftright (short leftright, short select_mode);
-/* */
+/* Action Markers */
+void action_set_activemarker(struct bAction *act, struct TimeMarker *active, short deselect);
+void action_add_localmarker(struct bAction *act, int frame);
+void action_rename_localmarker(struct bAction *act);
+void action_remove_localmarkers(struct bAction *act);
+
+/* ShapeKey stuff */
struct Key *get_action_mesh_key(void);
int get_nearest_key_num(struct Key *key, short *mval, float *x);
+
void *get_nearest_act_channel(short mval[], short *ret_type);
/* Action */
-struct bActionChannel* get_hilighted_action_channel(struct bAction* action);
+struct bActionChannel *get_hilighted_action_channel(struct bAction* action);
struct bAction *add_empty_action(char *name);
-
-void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
-
-/* contextual get action */
struct bAction *ob_get_action(struct Object *ob);
+void actdata_filter(ListBase *act_data, int filter_mode, void *data, short datatype);
+void *get_action_context(short *datatype);
+
void remake_action_ipos(struct bAction *act);
-/* this needs review badly! (ton) */
-struct bAction *bake_action_with_client (struct bAction *act, struct Object *arm, float tolerance);
-void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4]);
+/* event handling */
+void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
#endif
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index b8ae90b7cfa..935b93c8626 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -84,8 +84,11 @@ void delete_armature(void);
void deselectall_armature(int toggle, int doundo);
void deselectall_posearmature (struct Object *ob, int test, int doundo);
int draw_armature(struct Base *base, int dt);
+
void extrude_armature(int forked);
-void subdivide_armature(void);
+void subdivide_armature(int numcuts);
+void fill_bones_armature(void);
+void merge_armature(void);
void free_editArmature(void);
@@ -101,26 +104,32 @@ void make_trans_bones (char mode);
int do_pose_selectbuffer(struct Base *base, unsigned int *buffer, short hits);
+void generateSkeleton(void);
+
void mouse_armature(void);
void remake_editArmature(void);
void selectconnected_armature(void);
void selectconnected_posearmature(void);
void select_bone_parent(void);
-void unique_editbone_name (struct ListBase *ebones, char* name);
+void setflag_armature(short mode);
+void unique_editbone_name (struct ListBase *ebones, char *name);
-void auto_align_armature(void);
-void create_vgroups_from_armature(Object *ob, Object *par);
+void auto_align_armature(short mode);
+
+void create_vgroups_from_armature(struct Object *ob, struct Object *par);
+void add_verts_to_dgroups(struct Object *ob, struct Object *par, int heat, int mirror);
void hide_selected_pose_bones(void);
void hide_unselected_pose_bones(void);
void show_all_pose_bones(void);
-int bone_looper(Object *ob, struct Bone *bone, void *data,
- int (*bone_func)(Object *, struct Bone *, void *));
+int bone_looper(struct Object *ob, struct Bone *bone, void *data,
+ int (*bone_func)(struct Object *, struct Bone *, void *));
void undo_push_armature(char *name);
void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
void armature_flip_names(void);
+void armature_autoside_names(short axis);
EditBone *armature_bone_get_mirrored(EditBone *ebo);
void transform_armature_mirror_update(void);
@@ -137,3 +146,4 @@ void show_all_armature_bones(void);
#endif
+
diff --git a/source/blender/include/BIF_editconstraint.h b/source/blender/include/BIF_editconstraint.h
index db55bc5c7d7..81e2356e6cb 100644
--- a/source/blender/include/BIF_editconstraint.h
+++ b/source/blender/include/BIF_editconstraint.h
@@ -38,25 +38,30 @@ struct ListBase;
struct Object;
struct bConstraint;
struct bConstraintChannel;
+struct Text;
-struct bConstraint *add_new_constraint(short type);
-
-void add_constraint_to_object(struct bConstraint *con, struct Object *ob);
-
+/* generic constraint editing functions */
struct ListBase *get_active_constraints(struct Object *ob);
struct bConstraint *get_active_constraint(struct Object *ob);
struct ListBase *get_active_constraint_channels (struct Object *ob, int forcevalid);
struct bConstraintChannel *get_active_constraint_channel(struct Object *ob);
-void object_test_constraints(struct Object *owner);
-
-void add_constraint(int only_IK);
+void add_constraint_to_object(struct bConstraint *con, struct Object *ob);
+struct bConstraint *add_new_constraint(short type);
+void add_constraint(short only_IK);
void ob_clear_constraints(void);
+void rename_constraint(struct Object *ob, struct bConstraint *con, char *newname);
-char *get_con_subtarget_name(struct bConstraint *con, struct Object *target);
+void object_test_constraints(struct Object *owner);
-void rename_constraint(struct Object *ob, struct bConstraint *con, char *newname);
+/* a few special functions for PyConstraints */
+char *buildmenu_pyconstraints(struct Text *con_text, int *pyconindex);
+void validate_pyconstraint_cb(void *arg1, void *arg2);
+void update_pyconstraint_cb(void *arg1, void *arg2);
+/* two special functions for ChildOf Constriant */
+void childof_const_setinv (void *conv, void *unused);
+void childof_const_clearinv(void *conv, void *unused);
#endif
diff --git a/source/blender/include/BIF_editdeform.h b/source/blender/include/BIF_editdeform.h
index 2a8f43c14e7..84deb134be9 100644
--- a/source/blender/include/BIF_editdeform.h
+++ b/source/blender/include/BIF_editdeform.h
@@ -50,6 +50,7 @@ void del_defgroup (struct Object *ob);
void duplicate_defgroup ( struct Object *ob );
void assign_verts_defgroup (void);
void remove_verts_defgroup (int allverts);
+void remove_verts_defgroups (int allverts);
void sel_verts_defgroup (int select);
struct MDeformWeight *get_defweight (struct MDeformVert *dv, int defgroup);
@@ -61,6 +62,8 @@ void add_vert_to_defgroup (struct Object *ob, struct bDeformGroup *dg,
int assignmode);
void remove_vert_defgroup (struct Object *ob, struct bDeformGroup *dg,
int vertnum);
+float get_vert_defgroup (struct Object *ob, struct bDeformGroup *dg,
+ int vertnum);
void create_dverts(ID *id);
void vertexgroup_select_by_name(struct Object *ob, char *name);
diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h
index 931693f0889..42d581ee758 100644
--- a/source/blender/include/BIF_editmesh.h
+++ b/source/blender/include/BIF_editmesh.h
@@ -35,6 +35,8 @@
#ifndef BIF_EDITMESH_H
#define BIF_EDITMESH_H
+#include "BKE_mesh.h"
+
struct EditMesh;
struct EditFace;
struct EditEdge;
@@ -141,7 +143,10 @@ extern void righthandfaces(int select);
extern void mouse_mesh(void);
extern void deselectall_mesh(void);
-extern void selectconnected_mesh(int qual);
+extern void selectconnected_mesh_all(void);
+extern void selectconnected_mesh(void);
+extern void selectconnected_delimit_mesh(void);
+extern void selectconnected_delimit_mesh_all(void);
extern void selectswap_mesh(void);
extern void hide_mesh(int swap);
@@ -169,7 +174,9 @@ extern void selectrandom_mesh(void);
extern void editmesh_select_by_material(int index);
extern void editmesh_deselect_by_material(int index);
+extern void Vertex_Menu(void);
extern void Edge_Menu(void);
+extern void Face_Menu(void);
extern void select_mesh_group_menu(void);
extern void editmesh_mark_seam(int clear);
extern void loop_multiselect(int looptype);
@@ -199,7 +206,7 @@ extern short sharesFace(struct EditEdge* e1, struct EditEdge* e2);
#define SUBDIV_SELECT_LOOPCUT 3
extern void convert_to_triface(int direction);
-extern int removedoublesflag(short flag, float limit);
+extern int removedoublesflag(short flag, short automerge, float limit);
extern void xsortvert_flag(int flag);
extern void hashvert_flag(int flag);
@@ -216,7 +223,13 @@ extern void join_triangles(void);
extern void edge_flip(void);
extern void fill_mesh(void);
extern void bevel_menu();
+void mesh_set_face_flags(short mode);
extern void mesh_set_smooth_faces(short event);
+extern void mesh_rotate_uvs(void);
+extern void mesh_mirror_uvs(void);
+extern void mesh_rotate_colors(void);
+extern void mesh_mirror_colors(void);
+void mesh_copy_menu(void);
void edge_rotate_selected(int dir);
int EdgeSlide(short immediate, float imperc);
int EdgeLoopDelete(void);
@@ -238,4 +251,15 @@ int merge_target( int target, int uvmerge);
void pathselect(void);
void loop_to_region(void);
void region_to_loop(void);
+
+UvVertMap *make_uv_vert_map_EM(int selected, int do_face_idx_array, float *limit);
+UvMapVert *get_uv_map_vert_EM(UvVertMap *vmap, unsigned int v);
+void free_uv_vert_map_EM(UvVertMap *vmap);
+
+int EM_texFaceCheck(void); /* can we edit UV's for this mesh?*/
+int EM_vertColorCheck(void); /* can we edit colors for this mesh?*/
+
+void EM_set_actFace(struct EditFace *efa);
+struct EditFace * EM_get_actFace(void);
+
#endif
diff --git a/source/blender/include/BIF_editmode_undo.h b/source/blender/include/BIF_editmode_undo.h
index b03b4160166..5b445fef17b 100644
--- a/source/blender/include/BIF_editmode_undo.h
+++ b/source/blender/include/BIF_editmode_undo.h
@@ -39,7 +39,8 @@
extern void undo_editmode_push(char *name,
void (*freedata)(void *), // pointer to function freeing data
void (*to_editmode)(void *), // data to editmode conversion
- void *(*from_editmode)(void)); // editmode to data conversion
+ void *(*from_editmode)(void), // editmode to data conversion
+ int (*validate_undo)(void *)); // check if undo data is still valid
// Further exported for UI is:
diff --git a/source/blender/include/BIF_editparticle.h b/source/blender/include/BIF_editparticle.h
new file mode 100644
index 00000000000..6074dcd4fec
--- /dev/null
+++ b/source/blender/include/BIF_editparticle.h
@@ -0,0 +1,98 @@
+/* BIF_editparticle.h
+ *
+ *
+ * $Id: BIF_editparticle.h $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_EDITPARTICLE_H
+#define BIF_EDITPARTICLE_H
+
+struct Object;
+struct ParticleSystem;
+struct ParticleEditSettings;
+struct RadialControl;
+
+/* particle edit mode */
+void PE_set_particle_edit(void);
+void PE_create_particle_edit(struct Object *ob, struct ParticleSystem *psys);
+void PE_free_particle_edit(struct ParticleSystem *psys);
+
+void PE_change_act(void *ob_v, void *act_v);
+int PE_can_edit(struct ParticleSystem *psys);
+
+/* access */
+struct ParticleSystem *PE_get_current(struct Object *ob);
+short PE_get_current_num(struct Object *ob);
+int PE_minmax(float *min, float *max);
+void PE_get_colors(char sel[4], char nosel[4]);
+struct ParticleEditSettings *PE_settings(void);
+struct RadialControl **PE_radialcontrol();
+
+/* update calls */
+void PE_hide_keys_time(struct ParticleSystem *psys, float cfra);
+void PE_update_object(struct Object *ob, int useflag);
+void PE_update_selection(struct Object *ob, int useflag);
+void PE_recalc_world_cos(struct Object *ob, struct ParticleSystem *psys);
+
+/* selection tools */
+void PE_select_root(void);
+void PE_select_tip(void);
+void PE_deselectall(void);
+void PE_select_linked(void);
+void PE_select_less(void);
+void PE_select_more(void);
+
+void PE_mouse_particles(void);
+void PE_borderselect(void);
+void PE_selectionCB(short selecting, struct Object *editobj, short *mval, float rad);
+void PE_do_lasso_select(short mcords[][2], short moves, short select);
+
+/* tools */
+void PE_hide(int mode);
+void PE_rekey(void);
+void PE_subdivide(void);
+int PE_brush_particles(void);
+void PE_delete_particle(void);
+void PE_remove_doubles(void);
+void PE_mirror_x(int tagged);
+void PE_selectbrush_menu(void);
+void PE_remove_doubles(void);
+void PE_radialcontrol_start(const int mode);
+
+/* undo */
+void PE_undo_push(char *str);
+void PE_undo_step(int step);
+void PE_undo(void);
+void PE_redo(void);
+void PE_undo_menu(void);
+
+#endif
+
diff --git a/source/blender/include/BIF_editseq.h b/source/blender/include/BIF_editseq.h
index 3999b4311d4..ff6c7882b76 100644
--- a/source/blender/include/BIF_editseq.h
+++ b/source/blender/include/BIF_editseq.h
@@ -40,32 +40,74 @@ void add_sequence(int type);
void borderselect_seq(void);
void boundbox_seq(void);
void change_sequence(void);
+void reload_sequence(void);
void update_seq_ipo_rect(struct Sequence * seq);
void update_seq_icu_rects(struct Sequence * seq);
struct Sequence* get_last_seq();
+struct Sequence* get_forground_frame_seq( int frame );
void set_last_seq(struct Sequence * seq);
void clear_last_seq();
void del_seq(void);
void enter_meta(void);
void exit_meta(void);
+struct Sequence* find_neighboring_sequence(struct Sequence *test, int lr, int sel);
+struct Sequence* find_next_prev_sequence(struct Sequence *test, int lr, int sel);
struct Sequence* find_nearest_seq(int *hand);
int insert_gap(int gap, int cfra);
void make_meta(void);
+void select_channel_direction(struct Sequence *test,int lr);
+void select_more_seq(void);
+void select_less_seq(void);
void mouse_select_seq(void);
void no_gaps(void);
void seq_snap(short event);
void seq_snap_menu(void);
+void seq_mute_sel( int mute );
+void seq_lock_sel(int lock);
void set_filter_seq(void);
void swap_select_seq(void);
void touch_seq_files(void);
+void seq_remap_paths(void);
void transform_seq(int mode, int context);
+void transform_seq_nomarker(int mode, int context);
void un_meta(void);
void seq_cut(int cutframe);
+void seq_separate_images(void);
void reassign_inputs_seq_effect(void);
+void select_surrounding_handles(struct Sequence *test);
+void select_surround_from_last();
+void select_dir_from_last(int lr);
+void select_neighbor_from_last(int lr);
+void select_linked_seq(int mode);
+int test_overlap_seq(struct Sequence *test);
+void shuffle_seq(struct Sequence *test);
struct Sequence* alloc_sequence(ListBase *lb, int cfra, int machine); /*used from python*/
+int check_single_seq(struct Sequence *seq);
+
+/* seq funcs for transform
+ notice the difference between start/end and left/right.
+
+ left and right are the bounds at which the setuence is rendered,
+start and end are from the start and fixed length of the sequence.
+*/
+
+/* sequence transform functions, for internal used */
+int seq_tx_get_start(struct Sequence *seq);
+int seq_tx_get_end(struct Sequence *seq);
+
+int seq_tx_get_final_left(struct Sequence *seq);
+int seq_tx_get_final_right(struct Sequence *seq);
+
+void seq_tx_set_final_left(struct Sequence *seq, int i);
+void seq_tx_set_final_right(struct Sequence *seq, int i);
+
+/* check if one side can be transformed */
+int seq_tx_check_left(struct Sequence *seq);
+int seq_tx_check_right(struct Sequence *seq);
+
+#define SEQ_DEBUG_INFO(seq) printf("seq into '%s' -- len:%i start:%i startstill:%i endstill:%i startofs:%i endofs:%i depth:%i\n",\
+ seq->name, seq->len, seq->start, seq->startstill, seq->endstill, seq->startofs, seq->endofs, seq->depth)
-/* drawseq.c */
-void do_seqbuttons(short);
#endif
diff --git a/source/blender/include/BIF_editsima.h b/source/blender/include/BIF_editsima.h
index 6a67ebc7009..fe6846e4b36 100644
--- a/source/blender/include/BIF_editsima.h
+++ b/source/blender/include/BIF_editsima.h
@@ -31,7 +31,12 @@
*/
struct Mesh;
+struct EditMesh;
+struct SpaceImage;
+struct EditFace;
+struct MTFace;
+/* id can be from 0 to 3 */
#define TF_PIN_MASK(id) (TF_PIN1 << id)
#define TF_SEL_MASK(id) (TF_SEL1 << id)
@@ -45,27 +50,34 @@ int is_uv_tface_editing_allowed_silent(void);
void get_connected_limit_tface_uv(float *limit);
int minmax_tface_uv(float *min, float *max);
+int cent_tface_uv(float *cent, int mode);
void transform_width_height_tface_uv(int *width, int *height);
void transform_aspect_ratio_tface_uv(float *aspx, float *aspy);
+void mouseco_to_cursor_sima(void);
void borderselect_sima(short whichuvs);
void mouseco_to_curtile(void);
void mouse_select_sima(void);
+void snap_menu_sima(void);
+void aspect_sima(struct SpaceImage *sima, float *x, float *y);
+
+void select_invert_tface_uv(void);
void select_swap_tface_uv(void);
void mirrormenu_tface_uv(void);
-void mirror_tface_uv(char mirroraxis);
void hide_tface_uv(int swap);
void reveal_tface_uv(void);
-void stitch_uv_tface(int mode);
+void stitch_limit_uv_tface(void);
+void stitch_vert_uv_tface(void);
void unlink_selection(void);
+void uvface_setsel__internal(short select);
void select_linked_tface_uv(int mode);
-void toggle_uv_select(int mode);
void pin_tface_uv(int mode);
void weld_align_menu_tface_uv(void);
void weld_align_tface_uv(char tool);
-void be_square_tface_uv(struct Mesh *me);
+void be_square_tface_uv(struct EditMesh *em);
void select_pinned_tface_uv(void);
+void select_edgeloop_tface_uv(struct EditFace *efa, int a, int shift, int *flush);
void sima_sample_color(void);
@@ -83,3 +95,18 @@ void pack_image_sima(void);
/* checks images for forced updates on frame change */
void BIF_image_update_frame(void);
+
+void find_nearest_uv(struct MTFace **nearesttf, struct EditFace **nearestefa, unsigned int *nearestv, int *nearestuv);
+
+/* face selection check functions */
+
+int simaFaceDraw_Check_nolocal( struct EditFace *efa );
+int simaFaceDraw_Check( struct EditFace *efa, struct MTFace *tf );
+
+int simaFaceSel_Check( struct EditFace *efa, struct MTFace *tf );
+void simaFaceSel_Set( struct EditFace *efa, struct MTFace *tf );
+void simaFaceSel_UnSet( struct EditFace *efa, struct MTFace *tf );
+
+int simaUVSel_Check( struct EditFace *efa, struct MTFace *tf, int i);
+void simaUVSel_Set( struct EditFace *efa, struct MTFace *tf, int i);
+void simaUVSel_UnSet( struct EditFace *efa, struct MTFace *tf, int i);
diff --git a/source/blender/include/BIF_editsound.h b/source/blender/include/BIF_editsound.h
index abeabdc3e06..6e341bfb204 100644
--- a/source/blender/include/BIF_editsound.h
+++ b/source/blender/include/BIF_editsound.h
@@ -71,7 +71,7 @@ void sound_set_position(void *object,
struct hdaudio * sound_open_hdaudio(char * name);
struct hdaudio * sound_copy_hdaudio(struct hdaudio * c);
-long sound_hdaudio_get_duration(struct hdaudio * hdaudio, int frame_rate);
+long sound_hdaudio_get_duration(struct hdaudio * hdaudio, double frame_rate);
void sound_hdaudio_extract(struct hdaudio * hdaudio,
short * target_buffer,
int sample_position /* units of target_rate */,
diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h
index 676bc3bd9f0..d47bd82332f 100644
--- a/source/blender/include/BIF_editview.h
+++ b/source/blender/include/BIF_editview.h
@@ -39,10 +39,12 @@ struct Camera;
struct View3D;
void arrows_move_cursor(unsigned short event);
+int lasso_inside(short mcords[][2], short moves, short sx, short sy);
void borderselect(void);
void circle_select(void);
void deselectall(void);
void selectswap(void);
+void selectrandom(void);
void selectall_type(short obtype);
void selectall_layer(unsigned int layernum);
void draw_sel_circle(short *mval, short *mvalo, float rad, float rado, int selecting);
diff --git a/source/blender/include/BIF_filelist.h b/source/blender/include/BIF_filelist.h
new file mode 100644
index 00000000000..730a41c22e9
--- /dev/null
+++ b/source/blender/include/BIF_filelist.h
@@ -0,0 +1,86 @@
+/**
+ * $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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_FILELIST_H
+#define BIF_FILELIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct FileList;
+struct direntry;
+struct BlendHandle;
+
+struct FileList * BIF_filelist_new();
+void BIF_filelist_init_icons();
+void BIF_filelist_free_icons();
+struct FileList * BIF_filelist_copy(struct FileList* filelist);
+int BIF_filelist_find(struct FileList* filelist, char *file);
+void BIF_filelist_free(struct FileList* filelist);
+void BIF_filelist_freelib(struct FileList* filelist);
+void BIF_filelist_sort(struct FileList* filelist, short sort);
+int BIF_filelist_numfiles(struct FileList* filelist);
+const char * BIF_filelist_dir(struct FileList* filelist);
+void BIF_filelist_setdir(struct FileList* filelist, const char *dir);
+struct direntry * BIF_filelist_file(struct FileList* filelist, int index);
+void BIF_filelist_hidedot(struct FileList* filelist, short hide);
+void BIF_filelist_setfilter(struct FileList* filelist, unsigned int filter);
+void BIF_filelist_filter(struct FileList* filelist);
+void BIF_filelist_swapselect(struct FileList* filelist);
+void BIF_filelist_imgsize(struct FileList* filelist, short w, short h);
+void BIF_filelist_loadimage(struct FileList* filelist, int index);
+struct ImBuf * BIF_filelist_getimage(struct FileList* filelist, int index);
+
+void BIF_filelist_readdir(struct FileList* filelist);
+
+int BIF_filelist_empty(struct FileList* filelist);
+void BIF_filelist_parent(struct FileList* filelist);
+void BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
+int BIF_filelist_islibrary (struct FileList* filelist, char* dir, char* group);
+void BIF_filelist_from_main(struct FileList* filelist);
+void BIF_filelist_from_library(struct FileList* filelist);
+void BIF_filelist_append_library(struct FileList* filelist, char *dir, char* file, short flag, int idcode);
+void BIF_filelist_settype(struct FileList* filelist, int type);
+short BIF_filelist_gettype(struct FileList* filelist);
+void BIF_filelist_setipotype(struct FileList* filelist, short ipotype);
+void BIF_filelist_hasfunc(struct FileList* filelist, int has_func);
+
+struct BlendHandle *BIF_filelist_lib(struct FileList* filelist);
+int BIF_groupname_to_code(char *group); /* TODO: where should this go */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/include/BIF_fsmenu.h b/source/blender/include/BIF_fsmenu.h
index b32dee01854..1c5280c14f8 100644
--- a/source/blender/include/BIF_fsmenu.h
+++ b/source/blender/include/BIF_fsmenu.h
@@ -55,17 +55,20 @@ char* fsmenu_build_menu (void);
/** Append a seperator to the FSMenu, inserts always follow the
* last seperator.
*/
-void fsmenu_append_seperator (void);
+void fsmenu_append_separator (void);
/** Inserts a new fsmenu entry with the given @a path.
* Duplicate entries are not added.
* @param sorted Should entry be inserted in sorted order?
*/
-void fsmenu_insert_entry (char *path, int sorted);
+void fsmenu_insert_entry (char *path, int sorted, short save);
/** Removes the fsmenu entry at the given @a index. */
void fsmenu_remove_entry (int index);
+ /** saves the 'favourites' to the specified file */
+void fsmenu_write_file(const char *filename);
+
/** Free's all the memory associated with the fsmenu */
void fsmenu_free (void);
diff --git a/source/blender/include/BIF_gl.h b/source/blender/include/BIF_gl.h
index 215e88dc002..67d51edc531 100644
--- a/source/blender/include/BIF_gl.h
+++ b/source/blender/include/BIF_gl.h
@@ -53,11 +53,16 @@
#endif
#ifdef __APPLE__
-#include <OpenGL/gl.h>
-#include <OpenGL/glu.h>
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glu.h>
#else
-#include <GL/gl.h>
-#include <GL/glu.h>
+ #if defined (__sun) || defined (__sun__)
+ #include <GL/gl.h>
+ #include <mesa/glu.h>
+ #else
+ #include <GL/gl.h>
+ #include <GL/glu.h>
+ #endif
#endif
/*
* these should be phased out. cpack should be replaced in
diff --git a/source/blender/include/BIF_imasel.h b/source/blender/include/BIF_imasel.h
index d6a1800730b..fb332022ba4 100644
--- a/source/blender/include/BIF_imasel.h
+++ b/source/blender/include/BIF_imasel.h
@@ -33,28 +33,20 @@
#define BIF_IMASEL_H
struct SpaceImaSel;
-struct OneSelectableIma;
struct ScrArea;
-struct ImaDir;
+struct ID;
-void imadir_parent(struct SpaceImaSel *simasel);
-int bitset(int l, int bit);
-void free_sel_ima(struct OneSelectableIma *firstima);
-
-void write_new_pib(struct SpaceImaSel *simasel);
-void free_ima_dir(struct ImaDir *firstdir);
-void check_for_pib(struct SpaceImaSel *simasel);
-void clear_ima_dir(struct SpaceImaSel *simasel);
-void check_ima_dir_name(char *dir);
-int get_ima_dir(char *dirname, int dtype, int *td, struct ImaDir **first);
-void get_next_image(struct SpaceImaSel *simasel);
-void get_file_info(struct SpaceImaSel *simasel);
-void get_pib_file(struct SpaceImaSel *simasel);
-void change_imadir(struct SpaceImaSel *simasel);
-void check_imasel_copy(struct SpaceImaSel *simasel);
void free_imasel(struct SpaceImaSel *simasel);
void clever_numbuts_imasel(void);
+void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
+void activate_imageselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
+void activate_imageselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
+void activate_databrowse_imasel(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
+/*
+void activate_databrowse_imasel_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+*/
#endif
diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h
index ad2c8988343..4fadfe12297 100644
--- a/source/blender/include/BIF_interface.h
+++ b/source/blender/include/BIF_interface.h
@@ -166,6 +166,7 @@ struct AutoComplete;
#define BUT_CURVE (32<<9)
#define BUT_TOGDUAL (33<<9)
#define ICONTOGN (34<<9)
+#define FTPREVIEW (35<<9)
#define BUTTYPE (63<<9)
@@ -187,7 +188,7 @@ void uiGetMouse(int win, short *adr);
void uiComposeLinks(uiBlock *block);
void uiSetButLock(int val, char *lockstr);
void uiClearButLock(void);
-int uiDoBlocks(struct ListBase *lb, int event);
+int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit);
void uiSetCurFont(uiBlock *block, int index);
void uiDefFont(unsigned int index, void *xl, void *large, void *medium, void *small);
void uiFreeBlock(uiBlock *block);
diff --git a/source/blender/include/BIF_interface_icons.h b/source/blender/include/BIF_interface_icons.h
index c69fa122099..c628d68e9db 100644
--- a/source/blender/include/BIF_interface_icons.h
+++ b/source/blender/include/BIF_interface_icons.h
@@ -48,6 +48,7 @@ typedef struct IconFile {
#define ICON_DEFAULT_HEIGHT 16
+#define PREVIEW_DEFAULT_HEIGHT 96
/*
Resizable Icons for Blender
@@ -57,6 +58,8 @@ int BIF_icon_get_width(int icon_id);
int BIF_icon_get_height(int icon_id);
void BIF_icon_draw(float x, float y, int icon_id);
+void BIF_icon_draw_preview(float x, float y, int icon_id, int nocreate);
+
void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect);
void BIF_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade);
void BIF_icons_free();
diff --git a/source/blender/include/BIF_language.h b/source/blender/include/BIF_language.h
index 9a6ddfc7fc5..6ed8a8d1574 100644
--- a/source/blender/include/BIF_language.h
+++ b/source/blender/include/BIF_language.h
@@ -33,6 +33,8 @@
#ifndef BIF_LANGUAGE_H
#define BIF_LANGUAGE_H
+#include "DNA_vec_types.h"
+
struct BMF_Font;
int read_languagefile(void); /* usiblender.c */
@@ -47,6 +49,7 @@ char *fontsize_pup(void);
int BIF_DrawString(struct BMF_Font* font, char *str, int translate);
float BIF_GetStringWidth(struct BMF_Font* font, char *str, int translate);
+void BIF_GetBoundingBox(struct BMF_Font* font, char* str, int translate, rctf* bbox);
void BIF_RasterPos(float x, float y);
void BIF_SetScale(float aspect);
diff --git a/source/blender/include/BIF_meshlaplacian.h b/source/blender/include/BIF_meshlaplacian.h
new file mode 100644
index 00000000000..74e4fef0937
--- /dev/null
+++ b/source/blender/include/BIF_meshlaplacian.h
@@ -0,0 +1,87 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ * BIF_meshlaplacian.h: Algorithms using the mesh laplacian.
+ */
+
+#ifndef BIF_MESHLAPLACIAN_H
+#define BIF_MESHLAPLACIAN_H
+
+//#define RIGID_DEFORM
+
+struct Object;
+struct Mesh;
+struct bDeformGroup;
+struct MeshDeformModifierData;
+
+#ifdef RIGID_DEFORM
+struct EditMesh;
+#endif
+
+/* Laplacian System */
+
+struct LaplacianSystem;
+typedef struct LaplacianSystem LaplacianSystem;
+
+LaplacianSystem *laplacian_construct_begin(int totvert, int totface);
+
+void laplacian_add_vertex(LaplacianSystem *sys, float *co, int pinned);
+void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3);
+
+void laplacian_construct_end(LaplacianSystem *sys);
+void laplacian_delete(LaplacianSystem *sys);
+
+void laplacian_begin_solve(LaplacianSystem *sys, int index);
+void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value);
+int laplacian_system_solve(LaplacianSystem *sys);
+float laplacian_system_get_solution(int v);
+
+/* Heat Weighting */
+
+void heat_bone_weighting(struct Object *ob, struct Mesh *me, float (*verts)[3],
+ int numbones, struct bDeformGroup **dgrouplist,
+ struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3],
+ int *selected);
+
+#ifdef RIGID_DEFORM
+/* As-Rigid-As-Possible Deformation */
+
+void rigid_deform_begin(struct EditMesh *em);
+void rigid_deform_iteration(void);
+void rigid_deform_end(int cancel);
+#endif
+
+/* Harmonic Coordinates */
+
+void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
+ float (*vertexcos)[3], int totvert, float cagemat[][4]);
+
+#endif
+
diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h
index a08f800d7b6..15782aa8f3c 100644
--- a/source/blender/include/BIF_meshtools.h
+++ b/source/blender/include/BIF_meshtools.h
@@ -40,11 +40,13 @@ extern int join_mesh(void);
extern void sort_faces(void);
extern void objects_bake_render_menu(void);
-extern void objects_bake_render(short event);
+extern void objects_bake_render_ui(short event);
+extern void objects_bake_render(short event, char **error_msg);
extern long mesh_octree_table(struct Object *ob, float *co, char mode);
extern int mesh_get_x_mirror_vert(struct Object *ob, int index);
extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, float *co);
+extern int *mesh_get_x_mirror_faces(struct Object *ob);
#endif
diff --git a/source/blender/include/BIF_outliner.h b/source/blender/include/BIF_outliner.h
index 34ed7950421..582b2cc1ada 100644
--- a/source/blender/include/BIF_outliner.h
+++ b/source/blender/include/BIF_outliner.h
@@ -78,6 +78,8 @@ typedef struct TreeElement {
#define TSE_LINKED_MAT 22
/* NOTE, is used for light group */
#define TSE_LINKED_LAMP 23
+#define TSE_POSEGRP_BASE 24
+#define TSE_POSEGRP 25
/* outliner search flags */
#define OL_FIND 0
@@ -97,6 +99,9 @@ extern void outliner_show_hierarchy(struct ScrArea *sa);
extern void outliner_one_level(struct ScrArea *sa, int add);
extern void outliner_select(struct ScrArea *sa);
extern void outliner_toggle_selected(struct ScrArea *sa);
+extern void outliner_toggle_visibility(struct ScrArea *sa);
+extern void outliner_toggle_selectability(struct ScrArea *sa);
+extern void outliner_toggle_renderability(struct ScrArea *sa);
extern void outliner_del(struct ScrArea *sa);
extern void outliner_operation_menu(struct ScrArea *sa);
extern void outliner_page_up_down(struct ScrArea *sa, int up);
diff --git a/source/blender/include/BIF_poselib.h b/source/blender/include/BIF_poselib.h
new file mode 100644
index 00000000000..209c386d2d6
--- /dev/null
+++ b/source/blender/include/BIF_poselib.h
@@ -0,0 +1,55 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ * The Original Code is: this is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_POSELIB_H
+#define BIF_POSELIB_H
+
+struct Object;
+struct bAction;
+struct TimeMarker;
+
+char *poselib_build_poses_menu(struct bAction *act, char title[]);
+int poselib_get_free_index(struct bAction *act);
+struct TimeMarker *poselib_get_active_pose(struct bAction *act);
+
+struct bAction *poselib_init_new(struct Object *ob);
+struct bAction *poselib_validate(struct Object *ob);
+
+void poselib_validate_act(struct bAction *act);
+
+void poselib_remove_pose(struct Object *ob, struct TimeMarker *marker);
+void poselib_rename_pose(struct Object *ob);
+void poselib_add_current_pose(struct Object *ob, int mode);
+
+void poselib_preview_poses(struct Object *ob, short apply_active);
+
+#endif
diff --git a/source/blender/include/BIF_poseobject.h b/source/blender/include/BIF_poseobject.h
index 835b808c9ba..bf60fdb6038 100644
--- a/source/blender/include/BIF_poseobject.h
+++ b/source/blender/include/BIF_poseobject.h
@@ -35,6 +35,7 @@
struct Object;
+struct bPose;
struct bPoseChannel;
void enter_posemode(void);
@@ -58,14 +59,28 @@ void free_posebuf(void);
void copy_posebuf (void);
void paste_posebuf (int flip);
-void pose_adds_vgroups(struct Object *meshobj);
+void pose_adds_vgroups(struct Object *meshobj, int heatweights);
+
+void pose_add_posegroup(void);
+void pose_remove_posegroup(void);
+char *build_posegroups_menustr(struct bPose *pose, short for_pupmenu);
+void pose_assign_to_posegroup(short active);
+void pose_remove_from_posegroups(void);
+void pgroup_operation_with_menu(void);
+
+void pose_select_grouped(short nr);
+void pose_select_grouped_menu(void);
void pose_calculate_path(struct Object *ob);
+void pose_recalculate_paths(struct Object *ob);
void pose_clear_paths(struct Object *ob);
void pose_flip_names(void);
+void pose_autoside_names(short axis);
void pose_activate_flipped_bone(void);
void pose_movetolayer(void);
+void pose_relax(void);
+void pose_flipquats(void);
#endif
diff --git a/source/blender/include/BIF_radialcontrol.h b/source/blender/include/BIF_radialcontrol.h
new file mode 100644
index 00000000000..81181a3a91e
--- /dev/null
+++ b/source/blender/include/BIF_radialcontrol.h
@@ -0,0 +1,62 @@
+/*
+ * $Id: multires.h 13015 2007-12-27 07:27:03Z nicholasbishop $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RADIALCONTROL_H
+#define RADIALCONTROL_H
+
+struct NumInput;
+
+#define RADIALCONTROL_NONE 0
+#define RADIALCONTROL_SIZE 1
+#define RADIALCONTROL_STRENGTH 2
+#define RADIALCONTROL_ROTATION 3
+
+typedef void (*RadialControlCallback)(const int, const int);
+
+typedef struct RadialControl {
+ int mode;
+ short origloc[2];
+
+ unsigned int tex;
+
+ int new_value;
+ int original_value;
+ int max_value;
+ RadialControlCallback callback;
+
+ struct NumInput *num;
+} RadialControl;
+
+RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
+ const int original_value, const int max_value,
+ const unsigned int tex);
+void radialcontrol_do_events(RadialControl *rc, const unsigned short event);
+void radialcontrol_draw(RadialControl *rc);
+
+#endif
diff --git a/source/blender/include/BIF_renderwin.h b/source/blender/include/BIF_renderwin.h
index 789c3661db7..9bddafac701 100644
--- a/source/blender/include/BIF_renderwin.h
+++ b/source/blender/include/BIF_renderwin.h
@@ -33,6 +33,7 @@
struct Render;
struct ScrArea;
struct RenderStats;
+struct ImBuf;
void calc_renderwin_rectangle(int rectx, int recty, int posmask, int renderpos_r[2], int rendersize_r[2]);
@@ -40,6 +41,15 @@ void BIF_close_render_display(void);
void BIF_do_render(int anim);
+/* render text */
+void BIF_make_render_text(struct RenderStats *rs);
+char *BIF_render_text(void);
+
+/* render spare buffer */
+int BIF_show_render_spare(void);
+struct ImBuf *BIF_render_spare_imbuf(void);
+void BIF_free_render_spare(void);
+
/**
* @param v3d The View3D space to render.
*/
diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h
index 7f3b27fcf2f..1649287297b 100644
--- a/source/blender/include/BIF_resources.h
+++ b/source/blender/include/BIF_resources.h
@@ -58,24 +58,24 @@ typedef enum {
ICON_SPACE4,
ICON_TRIA_LEFT,
ICON_TRIA_UP,
- ICON_NDOF_TURN,
- ICON_NDOF_FLY,
- ICON_NDOF_TRANS,
- ICON_NDOF_DOM,
+ ICON_FONTPREVIEW,
+ ICON_BLANK4,
+ ICON_BLANK5,
+ ICON_BLANK6,
ICON_ORTHO,
ICON_PERSP,
ICON_CAMERA,
- ICON_EFFECTS,
+ ICON_PARTICLES,
ICON_BBOX,
ICON_WIRE,
ICON_SOLID,
ICON_SMOOTH,
ICON_POTATO,
ICON_MARKER_HLT,
- ICON_NORMALVIEW,
- ICON_LOCALVIEW,
- ICON_UNUSEDVIEW,
+ ICON_PMARKER_ACT,
+ ICON_PMARKER_SEL,
+ ICON_PMARKER,
ICON_VIEWZOOM,
ICON_SORTALPHA,
ICON_SORTTIME,
@@ -84,10 +84,10 @@ typedef enum {
ICON_SHORTDISPLAY,
ICON_TRIA_DOWN,
ICON_TRIA_RIGHT,
- ICON_BLANK7,
- ICON_BLANK8,
- ICON_BLANK9,
- ICON_BLANK10,
+ ICON_NDOF_TURN,
+ ICON_NDOF_FLY,
+ ICON_NDOF_TRANS,
+ ICON_NDOF_DOM,
ICON_VIEW_AXIS_ALL,
ICON_VIEW_AXIS_NONE,
@@ -123,9 +123,9 @@ typedef enum {
ICON_AXIS_SIDE,
ICON_AXIS_FRONT,
ICON_AXIS_TOP,
- ICON_DRAW_UVFACES,
- ICON_STICKY_UVS,
- ICON_STICKY2_UVS,
+ ICON_STICKY_UVS_LOC,
+ ICON_STICKY_UVS_DISABLE,
+ ICON_STICKY_UVS_VERT,
ICON_PREV_KEYFRAME,
ICON_NEXT_KEYFRAME,
ICON_ENVMAP,
@@ -164,7 +164,7 @@ typedef enum {
ICON_FACESEL_DEHLT,
ICON_FACESEL_HLT,
ICON_EDIT_DEHLT,
- ICON_BLANK19,
+ ICON_BOOKMARKS,
ICON_BLANK20,
ICON_BLANK21,
ICON_BLANK22,
@@ -268,7 +268,7 @@ typedef enum {
ICON_EYEDROPPER,
ICON_WINDOW_WINDOW,
ICON_PANEL_CLOSE,
- ICON_BLANK35,
+ ICON_PHYSICS,
ICON_BLANK36,
ICON_BLANK37,
ICON_BLANK38,
@@ -317,13 +317,13 @@ typedef enum {
ICON_HOME,
ICON_CLIPUV_DEHLT,
ICON_CLIPUV_HLT,
- ICON_SOME_WACKY_VERTS_AND_LINES,
- ICON_A_WACKY_VERT_AND_SOME_LINES,
+ ICON_BLANK2,
+ ICON_BLANK3,
ICON_VPAINT_COL,
ICON_RESTRICT_SELECT_OFF,
ICON_RESTRICT_SELECT_ON,
- ICON_BLANK45,
- ICON_BLANK46,
+ ICON_MUTE_IPO_OFF,
+ ICON_MUTE_IPO_ON,
ICON_MAN_TRANS,
ICON_MAN_ROT,
@@ -494,6 +494,7 @@ enum {
TH_NORMAL,
TH_FACE_DOT,
TH_FACEDOT_SIZE,
+ TH_CFRAME,
TH_SYNTAX_B,
TH_SYNTAX_V,
@@ -525,6 +526,7 @@ enum {
TH_SEQ_META,
TH_EDGE_SHARP,
+ TH_EDITMESH_ACTIVE,
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h
index 884f0459abf..43f0629f935 100644
--- a/source/blender/include/BIF_space.h
+++ b/source/blender/include/BIF_space.h
@@ -55,6 +55,7 @@ struct SpaceOops;
#define VIEW3D_HANDLER_OBJECT 3
#define VIEW3D_HANDLER_PREVIEW 4
#define VIEW3D_HANDLER_MULTIRES 5
+#define VIEW3D_HANDLER_TRANSFORM 6
/* ipo handler codes */
#define IPO_HANDLER_PROPERTIES 20
@@ -65,6 +66,8 @@ struct SpaceOops;
#define IMAGE_HANDLER_CURVES 32
#define IMAGE_HANDLER_PREVIEW 33
#define IMAGE_HANDLER_GAME_PROPERTIES 34
+#define IMAGE_HANDLER_VIEW_PROPERTIES 35
+/*#define IMAGE_HANDLER_TRANSFORM_PROPERTIES 36*/
/* action handler codes */
#define ACTION_HANDLER_PROPERTIES 40
@@ -75,6 +78,9 @@ struct SpaceOops;
/* sequence handler codes */
#define SEQ_HANDLER_PROPERTIES 60
+/* imasel handler codes */
+#define IMASEL_HANDLER_IMAGE 70
+
/* theme codes */
#define B_ADD_THEME 3301
#define B_DEL_THEME 3302
@@ -89,6 +95,7 @@ struct SpaceOops;
#define B_RECALCLIGHT 3310
+void scrarea_do_winprefetchdraw (struct ScrArea *sa);
void scrarea_do_windraw (struct ScrArea *sa);
void scrarea_do_winchange (struct ScrArea *sa);
void scrarea_do_winhandle (struct ScrArea *sa, struct BWinEvent *evt);
@@ -114,6 +121,7 @@ extern void force_draw_plus(int type, int header);
extern void freespacelist(struct ScrArea *sa);
extern void handle_view3d_around(void);
extern void handle_view3d_lock(void);
+extern void handle_view_middlemouse(void);
extern void init_v2d_oops(struct ScrArea *, struct SpaceOops *);
extern void initipo(struct ScrArea *sa);
extern void newspace(struct ScrArea *sa, int type);
diff --git a/source/blender/include/BIF_spacetypes.h b/source/blender/include/BIF_spacetypes.h
index e825acf676f..6125cfd5926 100644
--- a/source/blender/include/BIF_spacetypes.h
+++ b/source/blender/include/BIF_spacetypes.h
@@ -35,6 +35,7 @@ struct BWinEvent;
typedef struct _SpaceType SpaceType;
+typedef void (*SpacePrefetchDrawFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceDrawFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceChangeFP) (struct ScrArea *sa, void *spacedata);
typedef void (*SpaceHandleFP) (struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
@@ -43,7 +44,7 @@ typedef void (*SpaceHandleFP) (struct ScrArea *sa, void *spacedata, struct BWinE
SpaceType* spacetype_new (char *name);
-void spacetype_set_winfuncs (SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
+void spacetype_set_winfuncs (SpaceType *st, SpacePrefetchDrawFP prefetch, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
/***/
diff --git a/source/blender/include/BIF_toolbox.h b/source/blender/include/BIF_toolbox.h
index 72867cbfa05..39f86aefe73 100644
--- a/source/blender/include/BIF_toolbox.h
+++ b/source/blender/include/BIF_toolbox.h
@@ -65,4 +65,14 @@ void replace_names_but (void);
void BIF_screendump(int fscreen);
void write_screendump(char *name);
+typedef struct TBitem {
+ int icon;
+ char *name;
+ int retval;
+ void *poin;
+} TBitem;
+void toolbox_generic( struct TBitem *generic_menu ); /* for external toolbox - python only for now */
+
+void toolbox_mousepos( short *mpos, int save ); /* saves/restores mouse position when entering/exiting menus */
+
#endif
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index a8abcabc4cb..82d6bb84281 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -55,6 +55,14 @@
#define TFM_BONE_ENVELOPE 16
#define TFM_CURVE_SHRINKFATTEN 17
#define TFM_BONE_ROLL 18
+#define TFM_TIME_TRANSLATE 19
+#define TFM_TIME_SLIDE 20
+#define TFM_TIME_SCALE 21
+#define TFM_TIME_EXTEND 22
+#define TFM_BAKE_TIME 23
+#define TFM_BEVEL 24
+#define TFM_BWEIGHT 25
+#define TFM_ALIGN 26
/* TRANSFORM CONTEXTS */
#define CTX_NONE 0
@@ -62,11 +70,13 @@
#define CTX_EDGE 2
#define CTX_NO_PET 4
#define CTX_TWEAK 8
-#define CTX_NDOF 16
+#define CTX_NO_MIRROR 16
+#define CTX_AUTOCONFIRM 32
+#define CTX_BMESH 64
+#define CTX_NDOF 128
void initTransform(int mode, int context);
void Transform(void);
-void Mirror(short mode);
void NDofTransform();
/* Standalone call to get the transformation center corresponding to the current situation
@@ -77,6 +87,8 @@ int calculateTransformCenter(int centerMode, float *vec);
struct TransInfo;
struct ScrArea;
+struct Base;
+struct Scene;
struct TransInfo * BIF_GetTransInfo(void);
void BIF_setSingleAxisConstraint(float vec[3], char *text);
@@ -84,6 +96,20 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text);
void BIF_setLocalAxisConstraint(char axis, char *text);
void BIF_setLocalLockConstraint(char axis, char *text);
+int BIF_snappingSupported(void);
+
+struct TransformOrientation;
+
+void BIF_clearTransformOrientation(void);
+void BIF_removeTransformOrientation(struct TransformOrientation *ts);
+void BIF_manageTransformOrientation(int confirm, int set);
+int BIF_menuselectTransformOrientation(void);
+void BIF_selectTransformOrientation(struct TransformOrientation *ts);
+void BIF_selectTransformOrientationFromIndex(int index);
+
+char * BIF_menustringTransformOrientation(); /* the returned value was allocated and needs to be freed after use */
+int BIF_countTransformOrientation();
+
/* Drawing callbacks */
void BIF_drawConstraint(void);
void BIF_drawPropCircle(void);
diff --git a/source/blender/include/BIF_usiblender.h b/source/blender/include/BIF_usiblender.h
index e7475af3ab7..42261ce09d3 100644
--- a/source/blender/include/BIF_usiblender.h
+++ b/source/blender/include/BIF_usiblender.h
@@ -49,6 +49,7 @@ void BIF_read_autosavefile(void);
void BIF_write_file(char *target);
void BIF_write_homefile(void);
void BIF_write_autosave(void);
+void BIF_clear_tempfiles(void);
#endif
diff --git a/source/blender/include/BPI_script.h b/source/blender/include/BPI_script.h
deleted file mode 100644
index 80ac8b46900..00000000000
--- a/source/blender/include/BPI_script.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * include/BPI_script.h (jan-2004 ianwill)
- *
- * $Id$
- *
- * Header for BPython's script structure. BPI: Blender Python external include
- * file.
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You 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.
- *
- * This is a new part of Blender.
- *
- * Contributor(s): Willian P. Germano.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BPI_SCRIPT_H
-#define BPI_SCRIPT_H
-
-//#include "DNA_listBase.h"
-#include "DNA_ID.h"
-
-typedef struct Script {
- ID id;
-
- void *py_draw;
- void *py_event;
- void *py_button;
- void *py_browsercallback;
- void *py_globaldict;
-
- int flags, lastspace;
-
-} Script;
-
-/* Note: a script that registers callbacks in the script->py_* pointers
- * above (or calls the file or image selectors) needs to keep its global
- * dictionary until Draw.Exit() is called and the callbacks removed.
- * Unsetting SCRIPT_RUNNING means the interpreter reached the end of the
- * script and returned control to Blender, but we can't get rid of its
- * namespace (global dictionary) while SCRIPT_GUI or SCRIPT_FILESEL is set,
- * because of the callbacks. The flags and the script name are saved in
- * each running script's global dictionary, under '__script__'. */
-
-/* Flags */
-#define SCRIPT_RUNNING 0x01
-#define SCRIPT_GUI 0x02
-#define SCRIPT_FILESEL 0x04
-
-#endif /* BPI_SCRIPT_H */
diff --git a/source/blender/include/BSE_drawimasel.h b/source/blender/include/BSE_drawimasel.h
index f412ca08584..6c68ba79bb9 100644
--- a/source/blender/include/BSE_drawimasel.h
+++ b/source/blender/include/BSE_drawimasel.h
@@ -33,27 +33,28 @@
#ifndef BSE_DRAWIMASEL_H
#define BSE_DRAWIMASEL_H
+
+/* button events */
+#define B_FS_FILENAME 1
+#define B_FS_DIRNAME 2
+#define B_FS_DIR_MENU 3
+#define B_FS_PARDIR 4
+#define B_FS_LOAD 5
+#define B_FS_CANCEL 6
+#define B_FS_LIBNAME 7
+#define B_FS_BOOKMARK 8
+
+/* ui geometry */
+#define IMASEL_BUTTONS_HEIGHT 60
+#define TILE_BORDER_X 8
+#define TILE_BORDER_Y 8
+
struct ScrArea;
struct SpaceImaSel;
-void viewgate(short sx, short sy, short ex, short ey);
-void areaview (void);
-void calc_hilite(struct SpaceImaSel *simasel);
-void make_sima_area(struct SpaceImaSel *simasel);
-void draw_sima_area(struct SpaceImaSel *simasel);
-void select_ima_files(struct SpaceImaSel *simasel);
-void move_imadir_sli(struct SpaceImaSel *simasel);
-void move_imafile_sli(struct SpaceImaSel *simasel);
-void ima_select_all(struct SpaceImaSel *simasel);
-void pibplay(struct SpaceImaSel *simasel);
void drawimaselspace(struct ScrArea *sa, void *spacedata);
-
-/* void calc_hilite(SpaceImaSel *simasel); */
-/* void ima_select_all(SpaceImaSel *simasel); */
-/* void move_imadir_sli(SpaceImaSel *simasel); */
-/* void move_imafile_sli(SpaceImaSel *simasel); */
-/* void pibplay(SpaceImaSel *simasel); */
-/* void select_ima_files(SpaceImaSel *simasel); */
+void calc_imasel_rcts(SpaceImaSel *simasel, int winx, int winy);
+void do_imasel_buttonevents(short event, SpaceImaSel *simasel);
#endif /* BSE_DRAWIMASEL_H */
diff --git a/source/blender/include/BSE_drawipo.h b/source/blender/include/BSE_drawipo.h
index 07f116d8d67..2053f41a178 100644
--- a/source/blender/include/BSE_drawipo.h
+++ b/source/blender/include/BSE_drawipo.h
@@ -55,6 +55,7 @@ void ipoco_to_areaco_noclip (struct View2D *v2d, float *vec, short *mval);
void view2d_do_locks (struct ScrArea *cursa, int flag);
void view2d_zoom (struct View2D *v2d, float factor, int winx, int winy);
+void view2d_getscale (struct View2D *v2d, float *x, float *y);
void test_view2d (struct View2D *v2d, int winx, int winy);
void calc_scrollrcts (struct ScrArea *sa, struct View2D *v2d, int winx, int winy);
diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h
index 9c577746da9..c425cbc62ea 100644
--- a/source/blender/include/BSE_drawview.h
+++ b/source/blender/include/BSE_drawview.h
@@ -58,7 +58,7 @@ struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax);
unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, unsigned int (*indextest)(unsigned int index));
void drawview3dspace(struct ScrArea *sa, void *spacedata);
-void drawview3d_render(struct View3D *v3d, int winx, int winy);
+void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]);
int update_time(void);
void calc_viewborder(struct View3D *v3d, struct rctf *viewborder_r);
diff --git a/source/blender/include/BSE_edit.h b/source/blender/include/BSE_edit.h
index 048d4d012b2..71f6b275fd8 100644
--- a/source/blender/include/BSE_edit.h
+++ b/source/blender/include/BSE_edit.h
@@ -50,6 +50,7 @@ void snap_sel_to_curs(void);
void snap_curs_to_grid(void);
void snap_curs_to_sel(void);
void snap_to_center(void);
+void snap_curs_to_active(void);
#endif /* BSE_EDIT_H */
diff --git a/source/blender/include/BSE_editaction_types.h b/source/blender/include/BSE_editaction_types.h
new file mode 100644
index 00000000000..c347c04d7c2
--- /dev/null
+++ b/source/blender/include/BSE_editaction_types.h
@@ -0,0 +1,87 @@
+/**
+ * $Id: BIF_editaction.h 10519 2007-04-13 11:15:08Z aligorith $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): 2007, Joshua Leung (major Action Editor recode)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_EDITACTION_TYPES_H
+#define BIF_EDITACTION_TYPES_H
+
+/******************************************************* */
+/* FILTERED ACTION DATA - TYPES */
+
+/* types of keyframe data in ActListElem */
+typedef enum ALE_KEYTYPE {
+ ALE_NONE = 0,
+ ALE_IPO,
+ ALE_ICU,
+ ALE_GROUP
+} ALE_KEYTYPE;
+
+/* This struct defines a structure used for quick access */
+typedef struct bActListElem {
+ struct bActListElem *next, *prev;
+
+ void *data; /* source data this elem represents */
+ int type; /* one of the ACTTYPE_* values */
+ int flag; /* copy of elem's flags for quick access */
+ int index; /* copy of adrcode where applicable */
+
+ void *key_data; /* motion data - ipo or ipo-curve */
+ short datatype; /* type of motion data to expect */
+
+ struct bActionGroup *grp; /* action group that owns the channel */
+
+ void *owner; /* will either be an action channel or fake ipo-channel (for keys) */
+ short ownertype; /* type of owner */
+} bActListElem;
+
+/******************************************************* */
+/* FILTER ACTION DATA - METHODS/TYPES */
+
+/* filtering flags - under what circumstances should a channel be added */
+typedef enum ACTFILTER_FLAGS {
+ ACTFILTER_VISIBLE = (1<<0), /* should channels be visible */
+ ACTFILTER_SEL = (1<<1), /* should channels be selected */
+ ACTFILTER_FOREDIT = (1<<2), /* does editable status matter */
+ ACTFILTER_CHANNELS = (1<<3), /* do we only care that it is a channel */
+ ACTFILTER_IPOKEYS = (1<<4), /* only channels referencing ipo's */
+ ACTFILTER_ONLYICU = (1<<5), /* only reference ipo-curves */
+ ACTFILTER_FORDRAWING = (1<<6), /* make list for interface drawing */
+ ACTFILTER_ACTGROUPED = (1<<7) /* belongs to the active group */
+} ACTFILTER_FLAGS;
+
+/* Action Editor - Main Data types */
+typedef enum ACTCONT_TYPES {
+ ACTCONT_NONE = 0,
+ ACTCONT_ACTION,
+ ACTCONT_SHAPEKEY
+} ACTCONT_TYPES;
+
+#endif
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 01f985018ed..99a7930ddb1 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -44,6 +44,7 @@ struct Object;
struct IpoKey;
struct TransOb;
struct Tex;
+struct TransInfo;
void remake_object_ipos(struct Object *ob);
char *getname_ac_ei(int nr);
@@ -59,14 +60,15 @@ char *getname_la_ei(int nr);
char *getname_cam_ei(int nr);
char *getname_snd_ei(int nr);
char *getname_fluidsim_ei(int nr);
+char *getname_part_ei(int nr);
-char *getname_ipocurve(struct IpoCurve *icu);
+char *getname_ipocurve(struct IpoCurve *icu, struct Object *ob);
int geticon_ipo_blocktype(short blocktype);
struct EditIpo *get_active_editipo(void);
-void boundbox_ipocurve(struct IpoCurve *icu);
-void boundbox_ipo(struct Ipo *ipo, struct rctf *bb);
+void boundbox_ipocurve(struct IpoCurve *icu, int selectedonly);
+void boundbox_ipo(struct Ipo *ipo, struct rctf *bb, int selectedonly);
void editipo_changed(struct SpaceIpo *si, int doredraw);
void scale_editipo(void);
@@ -87,12 +89,14 @@ void do_ipo_selectbuttons(void);
/* gets ipo curve, creates if needed */
-struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, int);
-struct Ipo *verify_ipo(struct ID *, short, char *, char *);
+struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
+struct Ipo *verify_ipo(struct ID *, short, char *, char *, char *);
int texchannel_to_adrcode(int channel);
-void insert_vert_ipo(struct IpoCurve *icu, float x, float y);
+int insert_bezt_icu(struct IpoCurve *icu, struct BezTriple *bezt);
+void insert_vert_icu(struct IpoCurve *icu, float x, float y, short fast);
void add_vert_ipo(void);
+
void add_duplicate_editipo(void);
void remove_doubles_ipo(void);
void clean_ipo(void);
@@ -107,6 +111,7 @@ void ipo_mirror(short event);
void mouse_select_ipo(void);
void sethandles_ipo(int code);
void select_ipo_bezier_keys(struct Ipo *ipo, int selectmode);
+void select_icu_bezier_keys(struct IpoCurve *icu, int selectmode);
void set_ipotype(void);
void borderselect_ipo(void);
void del_ipo(int need_check);
@@ -118,7 +123,7 @@ void paste_editipo(void);
void set_exprap_ipo(int mode);
void set_speed_editipo(float speed);
-void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode);
+void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, short fast);
void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, int adrcode);
void insertkey_editipo(void);
void common_insertkey(void);
@@ -135,21 +140,24 @@ void movekey_ipo(int dir);
void movekey_obipo(int dir);
void nextkey_ipo(int dir);
void nextkey_obipo(int dir);
-void remake_ipo_transverts(struct TransVert *transmain, float *dvec, int tot);
-void transform_ipo(int mode);
void filter_sampledata(float *data, int sfra, int efra);
void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *icu);
-void ipo_record(void);
+void ipo_record(void);
+
+void make_ipo_transdata(struct TransInfo *t);
+void remake_ipo_transdata(struct TransInfo *t);
+void transform_ipo(int mode);
void actstrip_map_ipo_keys(struct Object *ob, struct Ipo *ipo, short restore, short only_keys);
void sethandles_ipo_keys(struct Ipo *ipo, int code);
+void snap_cfra_ipo_keys(struct Ipo *ipo, short mode);
void snap_ipo_keys(struct Ipo *ipo, short snaptype);
void mirror_ipo_keys(struct Ipo *ipo, short mirror_mode);
void setipotype_ipo(struct Ipo *ipo, int code);
void set_ipo_key_selection(struct Ipo *ipo, int sel);
int is_ipo_key_selected(struct Ipo *ipo);
-void delete_icu_key(struct IpoCurve *icu, int index);
+void delete_icu_key(struct IpoCurve *icu, int index, short do_recalc);
void delete_ipo_keys(struct Ipo *ipo);
int fullselect_ipo_keys(struct Ipo *ipo);
int add_trans_ipo_keys(struct Ipo *ipo, struct TransVert *tv, int tvtot);
@@ -157,8 +165,8 @@ void duplicate_ipo_keys(struct Ipo *ipo);
void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, int val);
void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax,
int (*select_function)(struct BezTriple *));
-void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue);
-
+int insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode);
+void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float floatkey);
void select_ipo_key(struct Ipo *ipo, float selx, int sel);
void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
void setexprap_ipoloop(struct Ipo *ipo, int code);
diff --git a/source/blender/include/BSE_filesel.h b/source/blender/include/BSE_filesel.h
index 6934899062e..a41eea32040 100644
--- a/source/blender/include/BSE_filesel.h
+++ b/source/blender/include/BSE_filesel.h
@@ -53,8 +53,6 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *)
void activate_fileselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
void activate_fileselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
-void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
-
void activate_databrowse(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
diff --git a/source/blender/include/BSE_headerbuttons.h b/source/blender/include/BSE_headerbuttons.h
index b0daf106ca8..112517dbe7f 100644
--- a/source/blender/include/BSE_headerbuttons.h
+++ b/source/blender/include/BSE_headerbuttons.h
@@ -141,6 +141,7 @@ void do_view3d_select_object_typemenu(void *arg, int event);
void do_view3d_select_faceselmenu(void *arg, int event);
void do_view3d_select_meshmenu(void *arg, int event);
void do_view3d_select_curvemenu(void *arg, int event);
+void do_view3d_select_metaballmenu(void *arg, int event);
void do_view3d_edit_snapmenu(void *arg, int event);
void do_view3d_edit_mirrormenu(void *arg, int event);
void do_view3d_transform_moveaxismenu(void *arg, int event);
diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h
index 243cac56152..0e9e511e9e6 100644
--- a/source/blender/include/BSE_node.h
+++ b/source/blender/include/BSE_node.h
@@ -54,6 +54,8 @@ struct Material *editnode_get_active_material(struct Material *ma);
struct bNode *editnode_get_active_idnode(struct bNodeTree *ntree, short id_code);
struct bNode *editnode_get_active(struct bNodeTree *ntree);
+void node_rename(struct SpaceNode *snode);
+
void snode_tag_dirty(struct SpaceNode *snode);
void snode_set_context(struct SpaceNode *snode);
@@ -71,6 +73,10 @@ void node_ungroup(struct SpaceNode *snode);
void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode);
void node_hide(struct SpaceNode *snode);
void node_read_renderlayers(struct SpaceNode *snode);
+void node_read_fullsamplelayers(struct SpaceNode *snode);
+void clear_scene_in_nodes(struct Scene *sce);
+void node_make_link(struct SpaceNode *snode);
+void node_active_link_viewer(struct SpaceNode *snode);
void node_transform_ext(int mode, int unused);
void node_shader_default(struct Material *ma);
@@ -95,8 +101,13 @@ struct SpaceNode;
struct bNodeLink;
void node_draw_link(struct SpaceNode *snode, struct bNodeLink *link);
+void node_rename_but(char *s);
+
void init_node_butfuncs(void);
+void node_curvemap_sample(float *col);
+
+
/* exported to CMP and SHD nodes */
//void node_ID_title_cb(void *node_v, void *unused_v);
//void node_but_title_cb(void *node_v, void *but_v);
diff --git a/source/blender/include/BSE_seqeffects.h b/source/blender/include/BSE_seqeffects.h
index 2962bbf3676..2dde9d3cc79 100644
--- a/source/blender/include/BSE_seqeffects.h
+++ b/source/blender/include/BSE_seqeffects.h
@@ -89,6 +89,7 @@ struct SeqEffectHandle {
};
struct SeqEffectHandle get_sequence_effect(struct Sequence * seq);
+struct SeqEffectHandle get_sequence_blend(struct Sequence * seq);
int get_sequence_effect_num_inputs(int seq_type);
void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force);
diff --git a/source/blender/include/BSE_seqscopes.h b/source/blender/include/BSE_seqscopes.h
index 3dd5e495928..a2b3c65d6e9 100644
--- a/source/blender/include/BSE_seqscopes.h
+++ b/source/blender/include/BSE_seqscopes.h
@@ -32,7 +32,10 @@
struct ImBuf;
struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf * ibuf);
+struct ImBuf *make_sep_waveform_view_from_ibuf(struct ImBuf * ibuf);
struct ImBuf *make_vectorscope_view_from_ibuf(struct ImBuf * ibuf);
+struct ImBuf *make_zebra_view_from_ibuf(struct ImBuf * ibuf, float perc);
+struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf * ibuf);
#endif
diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h
index c975e8de8ff..9f15b729e1c 100644
--- a/source/blender/include/BSE_sequence.h
+++ b/source/blender/include/BSE_sequence.h
@@ -37,6 +37,7 @@
struct PluginSeq;
struct StripElem;
+struct TStripElem;
struct Strip;
struct Sequence;
struct ListBase;
@@ -44,21 +45,46 @@ struct Editing;
struct ImBuf;
struct Scene;
-void free_stripdata(int len, struct StripElem *se);
+void free_tstripdata(int len, struct TStripElem *se);
void free_strip(struct Strip *strip);
-void new_stripdata(struct Sequence *seq);
+void new_tstripdata(struct Sequence *seq);
void free_sequence(struct Sequence *seq);
void build_seqar(struct ListBase *seqbase, struct Sequence ***seqar, int *totseq);
+
+#define BUILD_SEQAR_COUNT_NOTHING 0
+#define BUILD_SEQAR_COUNT_CURRENT 1
+#define BUILD_SEQAR_COUNT_CHILDREN 2
+
+void build_seqar_cb(struct ListBase *seqbase, struct Sequence ***seqar,
+ int *totseq, int (*test_func)(struct Sequence * seq));
void free_editing(struct Editing *ed);
void calc_sequence(struct Sequence *seq);
+void calc_sequence_disp(struct Sequence *seq);
+void reload_sequence_new_file(struct Sequence * seq);
+void seq_proxy_rebuild(struct Sequence * seq);
void sort_seq(void);
void clear_scene_in_allseqs(struct Scene *sce);
+char *give_seqname_by_type(int type);
+char *give_seqname(struct Sequence *seq);
+
int evaluate_seq_frame(int cfra);
struct StripElem *give_stripelem(struct Sequence *seq, int cfra);
+struct TStripElem *give_tstripelem(struct Sequence *seq, int cfra);
void set_meta_stripdata(struct Sequence *seqm);
struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel);
/* chansel: render this channel. Default=0 (renders end result)*/
+struct ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
+ struct Sequence * seq);
+
+/* sequence prefetch API */
+void seq_start_threads();
+void seq_stop_threads();
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown);
+void seq_wait_for_prefetch_ready();
+struct ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra,
+ int chanshown);
+
void free_imbuf_seq_except(int cfra);
void free_imbuf_seq_with_ipo(struct Ipo * ipo);
diff --git a/source/blender/include/BSE_time.h b/source/blender/include/BSE_time.h
index 459101f592d..27560c09e75 100644
--- a/source/blender/include/BSE_time.h
+++ b/source/blender/include/BSE_time.h
@@ -35,8 +35,14 @@
struct ListBase;
struct View2D;
+struct TimeMarker;
-/* ******** Markers - General Api ********* */
+/* ****** Marker Macros - General API ****** */
+
+/* macro for getting the scene's set of markers */
+#define SCE_MARKERS (&(G.scene->markers))
+
+/* ******** Markers - General API ********* */
void add_marker(int frame);
void duplicate_marker(void);
void remove_marker(void);
@@ -45,16 +51,25 @@ void transform_markers(int mode, int smode);
void borderselect_markers(void);
void deselect_markers(short test, short sel);
-struct TimeMarker *find_nearest_marker(int clip_y);
+struct TimeMarker *find_nearest_marker(struct ListBase *markers, int clip_y);
void nextprev_marker(short dir);
void get_minmax_markers(short sel, float *first, float *last);
int find_nearest_marker_time(float dx);
+struct TimeMarker *get_frame_marker(int frame);
void add_marker_to_cfra_elem(struct ListBase *lb, struct TimeMarker *marker, short only_sel);
void make_marker_cfra_list(struct ListBase *lb, short only_sel);
-void draw_markers_timespace(void);
+/* ********* Markers - Drawing API ********* */
+
+/* flags for drawing markers */
+enum {
+ DRAW_MARKERS_LINES = (1<<0),
+ DRAW_MARKERS_LOCAL = (1<<1)
+};
+
+void draw_markers_timespace(struct ListBase *markers, int flag);
/* ******** Animation - Preview Range ************* */
void anim_previewrange_set(void);
diff --git a/source/blender/include/BSE_trans_types.h b/source/blender/include/BSE_trans_types.h
index d75da302436..9c8b9e5595f 100644
--- a/source/blender/include/BSE_trans_types.h
+++ b/source/blender/include/BSE_trans_types.h
@@ -35,6 +35,7 @@
struct Object;
struct MDeformVert;
+struct ColorBand;
typedef struct TransOb {
float *loc;
diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h
index 94834d2c771..0e88b2467f7 100644
--- a/source/blender/include/BSE_view.h
+++ b/source/blender/include/BSE_view.h
@@ -78,6 +78,7 @@ void calctrackballvec(struct rcti *area, short *mval, float *vec);
void viewmove(int mode);
void viewmoveNDOFfly(int mode);
void viewmoveNDOF(int mode);
+void view_zoom_mouseloc(float dfac, short *mouseloc);
int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
void setwinmatrixview3d(int winx, int winy, struct rctf *rect);
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index e2d4d0c67ad..8ed23e10641 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -40,7 +40,6 @@
#define MINFRAME 1
#define MINFRAMEF 1.0
-#define MAXLAMP 32765
/* max length material array, 16 because of bits in matfrom */
#define MAXPICKBUF 10000
#define MAXSEQ 32
@@ -54,7 +53,7 @@
/* also fill in structs itself, dna cannot handle defines, duplicate with utildefines.h still */
#ifndef FILE_MAXDIR
-#define FILE_MAXDIR 160
+#define FILE_MAXDIR 160
#define FILE_MAXFILE 80
#endif
@@ -87,13 +86,16 @@
#endif
#define SELECT 1
+#define HIDDEN 1
+#define FIRST 1
#define ACTIVE 2
/*#ifdef WITH_VERSE*/
#define VERSE 3
/*#endif*/
#define DESELECT 0
#define NOT_YET 0
-
+#define VISIBLE 0
+#define LAST 0
#define TESTBASE(base) ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0) )
#define TESTBASELIB(base) ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0) && (((base)->object->restrictflag & OB_RESTRICT_VIEW)==0))
@@ -111,12 +113,17 @@
#define EFRA (G.scene->r.efra)
#define PSFRA ((G.scene->r.psfra != 0)? (G.scene->r.psfra): (G.scene->r.sfra))
#define PEFRA ((G.scene->r.psfra != 0)? (G.scene->r.pefra): (G.scene->r.efra))
+#define FRA2TIME(a) ((((double) G.scene->r.frs_sec_base) * (a)) / G.scene->r.frs_sec)
+#define TIME2FRA(a) ((((double) G.scene->r.frs_sec) * (a)) / G.scene->r.frs_sec_base)
+#define FPS (((double) G.scene->r.frs_sec) / G.scene->r.frs_sec_base)
#define ISPOIN(a, b, c) ( (a->b) && (a->c) )
#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) )
#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) )
-#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1))
+#define BEZSELECTED(bezt) (((bezt)->f1 & SELECT) || ((bezt)->f2 & SELECT) || ((bezt)->f3 & SELECT))
+/* for curve objects in editmode that can have hidden handles - may use for IPO's later */
+#define BEZSELECTED_HIDDENHANDLES(bezt) ((G.f & G_HIDDENHANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt))
/* psfont */
#define FNT_PDRAW 1
@@ -158,7 +165,6 @@
#define B_TEXALONE 47
#define B_MESHALONE 48
#define B_CURVEALONE 49
-#define B_HEMESHALONE 50
/* EVENT < 50: alones en locals */
@@ -171,7 +177,7 @@
#define B_PLAINMENUS 66
-#define B_GLRESLIMITCHANGED 69
+#define B_GLRESLIMITCHANGED 69
#define B_SHOWSPLASH 70
#define B_RESETAUTOSAVE 71
#define B_SOUNDTOGGLE 72
@@ -212,17 +218,15 @@
#define B_AUTOKEY 139
#define B_SCENELOCK 140
#define B_LOCALVIEW 141
-#define B_U_CAPSLOCK 142
+#define B_U_CAPSLOCK 142
#define B_VIEWBUT 146
#define B_PERSP 147
#define B_PROPTOOL 148
-#define B_VIEWRENDER 149
-#define B_VIEWTRANS 150
-#define B_VIEWZOOM 151
-#define B_STARTGAME 152
+#define B_VIEWRENDER 149
+#define B_STARTGAME 150
-#define B_MODESELECT 156
+#define B_MODESELECT 156
#define B_AROUND 157
#define B_SEL_VERT 158
#define B_SEL_EDGE 159
@@ -230,9 +234,11 @@
#define B_MAN_TRANS 161
#define B_MAN_ROT 162
#define B_MAN_SCALE 163
-#define B_HEMESHBROWSE 164
-#define B_HEMESHLOCAL 165
-#define B_NDOF 166
+#define B_SEL_PATH 166
+#define B_SEL_POINT 167
+#define B_SEL_END 168
+#define B_MAN_MODE 169
+#define B_NDOF 170
/* IPO: 200 */
#define B_IPOHOME 201
@@ -243,14 +249,16 @@
#define B_IPOEXTRAP 206
#define B_IPOCYCLIC 207
#define B_IPOMAIN 208
-#define B_IPOSHOWKEY 209
-#define B_IPOCYCLICX 210
+#define B_IPOSHOWKEY 209
+#define B_IPOCYCLICX 210
/* warn: also used for oops and seq */
-#define B_VIEW2DZOOM 211
+#define B_VIEW2DZOOM 211
#define B_IPOPIN 212
#define B_IPO_ACTION_OB 213
#define B_IPO_ACTION_KEY 214
-
+#define B_IPOVIEWCENTER 215
+#define B_IPOVIEWALL 216
+#define B_IPOREDRAW 217
/* OOPS: 250 */
#define B_OOPSHOME 251
@@ -261,15 +269,15 @@
/* INFO: 300 */
/* watch: also in filesel.c and editobject.c */
#define B_INFOSCR 301
-#define B_INFODELSCR 302
+#define B_INFODELSCR 302
#define B_INFOSCE 304
-#define B_INFODELSCE 305
+#define B_INFODELSCE 305
#define B_FILEMENU 306
#define B_PACKFILE 307
#define B_CONSOLEOUT 308
#define B_CONSOLENUMLINES 309
-#define B_USERPREF 310
+#define B_USERPREF 310
#define B_LOADUIFONT 311
#define B_SETLANGUAGE 312
#define B_SETFONTSIZE 313
@@ -285,32 +293,33 @@
#define B_UITHEMEIMPORT 323
#define B_UITHEMEEXPORT 324
-#define B_MEMCACHELIMIT 325
+#define B_MEMCACHELIMIT 325
+#define B_WPAINT_RANGE 326
/* Definitions for the fileselect buttons in user prefs */
#define B_FONTDIRFILESEL 330
#define B_TEXTUDIRFILESEL 331
-#define B_PLUGTEXDIRFILESEL 332
-#define B_PLUGSEQDIRFILESEL 333
-#define B_RENDERDIRFILESEL 334
-#define B_PYTHONDIRFILESEL 335
+#define B_PLUGTEXDIRFILESEL 332
+#define B_PLUGSEQDIRFILESEL 333
+#define B_RENDERDIRFILESEL 334
+#define B_PYTHONDIRFILESEL 335
#define B_SOUNDDIRFILESEL 336
#define B_TEMPDIRFILESEL 337
/* yafray: for exportdir select */
#define B_YAFRAYDIRFILESEL 338
-#define B_PYMENUEVAL 339 /* re-eval scripts registration in menus */
+#define B_PYMENUEVAL 339 /* re-eval scripts registration in menus */
/* END Definitions for the fileselect buttons in user prefs */
/* IMAGE: 350 */
#define B_SIMAGEHOME 351
#define B_SIMABROWSE 352
#define B_SIMAGELOAD 353
-#define B_SIMAGEDRAW 354
-#define B_BE_SQUARE 355
-#define B_SIMAGEDRAW1 356
-#define B_TWINANIM 357
+#define B_SIMA_REDR_IMA_3D 354
+#define B_SIMAGETILE 355
+#define B_BE_SQUARE 356
+#define B_TWINANIM 357
#define B_SIMAGEREPLACE 358
-#define B_CLIP_UV 359
+#define B_CLIP_UV 359
#define B_SIMAGELOAD1 360
#define B_SIMAGEREPLACE1 361
#define B_SIMAGEPAINTTOOL 362
@@ -334,20 +343,27 @@
#define B_SIMANAME 381
#define B_SIMAMULTI 382
#define B_TRANS_IMAGE 383
-#define B_SIMA_REPACK 384
-#define B_SIMA_PLAY 385
-#define B_SIMA_RECORD 386
+#define B_CURSOR_IMAGE 384
+#define B_SIMA_REPACK 385
+#define B_SIMA_PLAY 386
+#define B_SIMA_RECORD 387
+#define B_SIMAPIN 388
+#define B_SIMA3DVIEWDRAW 389
+
/* BUTS: 400 */
-#define B_BUTSHOME 401
-#define B_BUTSPREVIEW 402
-#define B_MATCOPY 403
-#define B_MATPASTE 404
-#define B_MESHTYPE 405
+#define B_BUTSHOME 401
+#define B_BUTSPREVIEW 402
+#define B_MATCOPY 403
+#define B_MATPASTE 404
+#define B_MESHTYPE 405
#define B_CONTEXT_SWITCH 406
/* IMASEL: 450 */
-/* in imasel.h */
+/* in imasel.h - not any more - elubie */
+#define B_SORTIMASELLIST 451
+#define B_RELOADIMASELDIR 452
+#define B_FILTERIMASELDIR 453
/* TEXT: 500 */
#define B_TEXTBROWSE 501
@@ -361,8 +377,8 @@
#define B_SYNTAX 509
/* SCRIPT: 525 */
-#define B_SCRIPTBROWSE 526
-#define B_SCRIPT2PREV 527
+#define B_SCRIPTBROWSE 526
+#define B_SCRIPT2PREV 527
/* FILE: 550 */
#define B_SORTFILELIST 551
@@ -382,34 +398,35 @@
#define B_ACTHOME 701
#define B_ACTCOPY 702
#define B_ACTPASTE 703
-#define B_ACTPASTEFLIP 704
+#define B_ACTPASTEFLIP 704
#define B_ACTCYCLIC 705
#define B_ACTCONT 706
#define B_ACTMAIN 707
#define B_ACTPIN 708
#define B_ACTBAKE 709
+#define B_ACTCOPYKEYS 710
+#define B_ACTPASTEKEYS 711
/* TIME: 751 - 800 */
#define B_TL_REW 751
#define B_TL_PLAY 752
#define B_TL_FF 753
-#define B_TL_PREVKEY 754
-#define B_TL_NEXTKEY 755
+#define B_TL_PREVKEY 754
+#define B_TL_NEXTKEY 755
#define B_TL_STOP 756
-#define B_TL_PREVIEWON 757
+#define B_TL_PREVIEWON 757
/* NLA: 801-850 */
#define B_NLAHOME 801
/* NODE: 851-900 */
-#define B_NODEHOME 851
+#define B_NODEHOME 851
#define B_NODE_USEMAT 852
#define B_NODE_USESCENE 853
/* FREE 901 - 999 */
-#define B_NOTHING -1
#define B_NOP -1
@@ -418,22 +435,22 @@
#define B_KEEPORIG 2
#define B_BEAUTY 4
#define B_SMOOTH 8
-#define B_BEAUTY_SHORT 16
+#define B_BEAUTY_SHORT 16
#define B_AUTOFGON 32
#define B_KNIFE 0x80
-#define B_PERCENTSUBD 0x40
-#define B_MESH_X_MIRROR 0x100
-#define B_JOINTRIA_UV 0x200
-#define B_JOINTRIA_VCOL 0X400
-#define B_JOINTRIA_SHARP 0X800
-#define B_JOINTRIA_MAT 0X1000
+#define B_PERCENTSUBD 0x40
+#define B_MESH_X_MIRROR 0x100
+#define B_JOINTRIA_UV 0x200
+#define B_JOINTRIA_VCOL 0X400
+#define B_JOINTRIA_SHARP 0X800
+#define B_JOINTRIA_MAT 0X1000
/* DISPLAYMODE */
#define R_DISPLAYIMAGE 0
#define R_DISPLAYWIN 1
#define R_DISPLAYSCREEN 2
- /* Gvp.flag and Gwp.flag */
+/* Gvp.flag and Gwp.flag */
#define VP_COLINDEX 1
#define VP_AREA 2
#define VP_SOFT 4
@@ -441,10 +458,11 @@
#define VP_SPRAY 16
#define VP_MIRROR_X 32
#define VP_HARD 64
-#define VP_ONLYVGROUP 128
+#define VP_ONLYVGROUP 128
/* Error messages */
#define ERROR_LIBDATA_MESSAGE "Can't edit external libdata"
+#define MAX_RENDER_PASS 100
#endif
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 142d2ae1d0b..739cec7b9f3 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -64,10 +64,13 @@ extern void do_render_panels(unsigned short event);
extern void anim_panels(void);
extern void sound_panels(void);
extern void do_soundbuts(unsigned short event);
+extern void sequencer_panels(void);
+extern void do_sequencer_panels(unsigned short event);
/* object */
extern void object_panels(void);
extern void physics_panels(void);
+extern void particle_panels(void);
extern void do_object_panels(unsigned short event);
extern void do_constraintbuts(unsigned short event);
extern void object_panel_constraint(char *context);
@@ -86,8 +89,6 @@ extern int mod_moveDown(void *ob_v, void *md_v);
extern void const_moveUp(void *ob_v, void *con_v);
extern void const_moveDown(void *ob_v, void *con_v);
extern void del_constr_func (void *ob_v, void *con_v);
-extern void get_constraint_typestring(char *str, void *con_v);
-extern void get_constraint_ipo_context(void *ob_v, char *actname);
/* editing */
extern void editing_panels(void);
@@ -103,6 +104,7 @@ extern void do_cambuts(unsigned short event);
extern void do_armbuts(unsigned short event);
extern void do_uvcalculationbuts(unsigned short event);
extern void weight_paint_buttons(struct uiBlock *);
+extern void particle_edit_buttons(struct uiBlock *);
extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons
@@ -168,6 +170,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_ARMATUREPANEL3 1013
#define B_OBJECTPANELSCALE 1014
#define B_OBJECTPANELDIMS 1015
+#define B_TRANSFORMSPACEADD 1016
+#define B_TRANSFORMSPACECLEAR 1017
/* *********************** */
#define B_LAMPBUTS 1200
@@ -180,6 +184,9 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SHADRAY 1106
#define B_LMTEXPASTE 1107
#define B_LMTEXCOPY 1108
+#define B_LFALLOFFCHANGED 1109
+#define B_LMTEXMOVEUP 1110
+#define B_LMTEXMOVEDOWN 1111
/* *********************** */
#define B_MATBUTS 1300
@@ -209,6 +216,14 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_MAT_VCOL_PAINT 1222
#define B_MAT_VCOL_LIGHT 1223
+ /* world buttons: buttons-preview update, and redraw 3dview */
+#define B_WORLDPRV2 1224
+
+#define B_MAT_PARTICLE 1225
+
+#define B_MTEXMOVEUP 1226
+#define B_MTEXMOVEDOWN 1227
+
/* *********************** */
#define B_TEXBUTS 1400
@@ -277,6 +292,15 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_FLUIDSIM_MAKEPART 1453
#define B_GROUP_RELINK 1460
+#define B_OBJECT_IPOFLAG 1461
+
+#define B_BAKEABLE_CHANGE 1470
+
+/* Cloth sim button defines */
+#define B_CLOTH_CLEARCACHEALL 1480
+#define B_CLOTH_CLEARCACHEFRAME 1481
+#define B_CLOTH_CHANGEPREROLL 1482
+#define B_CLOTH_RENEW 1483
/* *********************** */
#define B_WORLDBUTS 1600
@@ -286,15 +310,18 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_COLZEN 1503
#define B_WMTEXPASTE 1504
#define B_WMTEXCOPY 1505
-#define B_AO_DISTANCES 1506
+#define B_AO_FALLOFF 1506
+#define B_WMTEXMOVEUP 1507
+#define B_WMTEXMOVEDOWN 1508
/* *********************** */
-#define B_RENDERBUTS 1700
+#define B_RENDERBUTS 1690
+#define B_SEQUENCERBUTS 1699
#define B_FS_PIC 1601
#define B_FS_BACKBUF 1602
-#define B_FS_FTYPE 1604
+#define B_FS_FTYPE 1604 /* FTYPE is no more */
#define B_DORENDER 1605
#define B_DOANIM 1606
#define B_PLAYANIM 1607
@@ -311,7 +338,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_PR_PANO 1619
#define B_PR_NTSC 1620
-#define B_IS_FTYPE 1622
+#define B_IS_FTYPE 1622 /* FTYPE is nomore */
#define B_IS_BACKBUF 1623
#define B_PR_PC 1624
@@ -338,6 +365,14 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_ADD_RENDERLAYER 1645
#define B_SET_PASS 1646
+#define B_SEQ_BUT_PLUGIN 1691
+#define B_SEQ_BUT_RELOAD 1692
+#define B_SEQ_BUT_EFFECT 1693
+#define B_SEQ_BUT_RELOAD_ALL 1694
+#define B_SEQ_BUT_TRANSFORM 1695
+#define B_SEQ_BUT_RELOAD_FILE 1696
+#define B_SEQ_BUT_REBUILD_PROXY 1697
+
/* *********************** */
#define B_ARMATUREBUTS 1800
#define B_POSE 1701
@@ -361,6 +396,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_DOCENTER 2015
#define B_DOCENTERNEW 2016
#define B_DOCENTERCURSOR 2017
+#define B_MATASS_BROWSE 2018
/* 20 values! */
#define B_OBLAY 2019
@@ -372,6 +408,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_PREVKEY 2045
#define B_NEXTKEY 2046
#define B_LOCKKEY 2047
+#define B_MATCOL2 2048
#define B_MESHBUTS 2090
@@ -408,6 +445,9 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_JOINTRIA 2081
#define B_SETTFACE_RND 2082
#define B_SETMCOL_RND 2083
+#define B_DRAWBWEIGHTS 2084
+
+#define B_GEN_SKELETON 2090
/* *********************** */
#define B_VGROUPBUTS 2100
@@ -450,6 +490,11 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SETRESOLU 2121
#define B_SETW4 2122
#define B_SUBSURFTYPE 2123
+#define B_TILTINTERP 2124
+#define B_SETPT_AUTO 2125
+#define B_SETPT_VECTOR 2126
+#define B_SETPT_ALIGN 2127
+#define B_SETPT_FREE 2128
/* *********************** */
#define B_FONTBUTS 2300
@@ -483,6 +528,23 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_ARM_CALCPATHS 2303
#define B_ARM_CLEARPATHS 2304
+#define B_POSELIB_VALIDATE 2310
+#define B_POSELIB_ADDPOSE 2311
+#define B_POSELIB_REPLACEP 2312
+#define B_POSELIB_REMOVEP 2313
+#define B_POSELIB_APPLYP 2314
+
+ /* these shouldn't be here... */
+#define B_POSELIB_BROWSE 2320
+#define B_POSELIB_ALONE 2321
+#define B_POSELIB_DELETE 2322
+
+
+#define B_POSEGRP_RECALC 2330
+#define B_POSEGRP_ADD 2331
+#define B_POSEGRP_REMOVE 2332
+#define B_POSEGRP_MCUSTOM 2333
+
/* *********************** */
#define B_CAMBUTS 2500
@@ -569,6 +631,14 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
/* Sculptmode */
#define B_SCULPT_TEXBROWSE 2860
+/* Particles */
+#define B_BAKE_OLENGTH 2870
+#define B_BAKE_APPLY_AV 2871
+#define B_BAKE_KEYTIME 2872
+#define B_BAKE_AV_CHANGE 2873
+#define B_BAKE_REDRAWEDIT 2874
+#define B_BAKE_RECACHE 2875
+
/* *********************** */
#define B_RADIOBUTS 3000
@@ -640,7 +710,7 @@ enum {
B_CONSTRAINT_ADD_ACTION,
B_CONSTRAINT_ADD_LOCKTRACK,
B_CONSTRAINT_ADD_FOLLOWPATH,
- B_CONSTRAINT_ADD_DISTANCELIMIT,
+ B_CONSTRAINT_ADD_DISTLIMIT,
B_CONSTRAINT_ADD_STRETCHTO,
B_CONSTRAINT_ADD_LOCLIMIT,
B_CONSTRAINT_ADD_ROTLIMIT,
@@ -649,6 +719,7 @@ enum {
B_CONSTRAINT_ADD_CHILDOF,
B_CONSTRAINT_ADD_PYTHON,
B_CONSTRAINT_ADD_CLAMPTO,
+ B_CONSTRAINT_ADD_TRANSFORM,
B_CONSTRAINT_INF
};
@@ -675,7 +746,7 @@ enum {
#define B_EFFECTSBUTS 3500
-#define B_AUTOTIMEOFS 3403
+#define B_AUTOTIMEOFS 3403 /* see B_OFSTIMEOFS, B_RANDTIMEOFS also */
#define B_FRAMEMAP 3404
#define B_NEWEFFECT 3405
#define B_PREVEFFECT 3406
@@ -690,6 +761,29 @@ enum {
#define B_FIELD_CHANGE 3415
#define B_PAF_SET_VG 3416
#define B_PAF_SET_VG1 3417
+#define B_PARTBROWSE 3418
+#define B_PARTDELETE 3419
+#define B_PARTALONE 3420
+#define B_PARTLOCAL 3421
+#define B_PARTAUTONAME 3422
+#define B_PART_ALLOC 3423
+#define B_PART_DISTR 3424
+#define B_PART_INIT 3425
+#define B_PART_RECALC 3426
+#define B_PART_REDRAW 3427
+#define B_PARTTYPE 3428
+#define B_PARTACT 3429
+#define B_PARTTARGET 3430
+#define B_PART_ALLOC_CHILD 3431
+#define B_PART_DISTR_CHILD 3432
+#define B_PART_INIT_CHILD 3433
+#define B_PART_RECALC_CHILD 3434
+#define B_PART_EDITABLE 3435
+#define B_PART_REKEY 3436
+#define B_PART_ENABLE 3437
+#define B_OFSTIMEOFS 3438 /* see B_AUTOTIMEOFS too */
+#define B_RANDTIMEOFS 3439
+#define B_PART_REDRAW_DEPS 3440
#define B_MODIFIER_BUTS 3600
@@ -700,7 +794,9 @@ enum {
#define B_NODE_BUTS 4000
/* 400 slots reserved, we want an exec event for each node */
#define B_NODE_LOADIMAGE 3601
-#define B_NODE_TREE_EXEC 3602
+#define B_NODE_SETIMAGE 3602
+#define B_NODE_TREE_EXEC 3603
+
/* exec should be last in this list */
#define B_NODE_EXEC 3610
diff --git a/source/blender/include/datatoc.h b/source/blender/include/datatoc.h
index d7a1aa5c78c..7afd4428d70 100644
--- a/source/blender/include/datatoc.h
+++ b/source/blender/include/datatoc.h
@@ -44,6 +44,9 @@ extern char datatoc_Bfs[];
extern int datatoc_blenderbuttons_size;
extern char datatoc_blenderbuttons[];
+extern int datatoc_prvicons_size;
+extern char datatoc_prvicons[];
+
extern int datatoc_Bfont_size;
extern char datatoc_Bfont[];
diff --git a/source/blender/include/editmesh.h b/source/blender/include/editmesh.h
index 50115e52a21..1b2d91e22b8 100644
--- a/source/blender/include/editmesh.h
+++ b/source/blender/include/editmesh.h
@@ -90,6 +90,7 @@ extern int convex(float *v1, float *v2, float *v3, float *v4);
/* ******************* editmesh_mods.c */
extern EditEdge *findnearestedge(int *dist);
+extern void EM_automerge(int update);
/**
* findnearestvert
@@ -104,5 +105,6 @@ extern EditVert *findnearestvert(int *dist, short sel, short strict);
/* ******************* editmesh_tools.c */
+
#endif
diff --git a/source/blender/include/interface.h b/source/blender/include/interface.h
index d7be02c6fc5..d8e779b9af8 100644
--- a/source/blender/include/interface.h
+++ b/source/blender/include/interface.h
@@ -230,7 +230,7 @@ extern void ui_draw_but(uiBut *but);
extern void ui_rasterpos_safe(float x, float y, float aspect);
extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
extern void ui_draw_anti_x(float x1, float y1, float x2, float y2);
-
+extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
#endif
diff --git a/source/blender/include/multires.h b/source/blender/include/multires.h
index 069dbee802f..e4726c02d7e 100644
--- a/source/blender/include/multires.h
+++ b/source/blender/include/multires.h
@@ -43,37 +43,17 @@ struct uiBlock;
int multires_test();
int multires_level1_test();
-struct MultiresLevel *multires_level_n(struct Multires *mr, int n);
-
void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned short cy);
-void multires_disp_map(void *, void*);
void multires_make(void *ob, void *me);
void multires_delete(void *ob, void *me);
-struct Multires *multires_copy(struct Multires *orig);
-void multires_free(struct Multires *mr);
-void multires_free_level(struct MultiresLevel *lvl);
+void multires_level_to_editmesh(struct Object *ob, struct Mesh *me, const int render);
+void multires_finish_mesh_update(struct Object *ob);
+void multires_subdivide(void *ob, void *me);
void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me);
-void multires_add_level(void *ob, void *me);
void multires_set_level_cb(void *ob, void *me);
-void multires_set_level(struct Object *ob, struct Mesh *me, const int render);
-void multires_update_levels(struct Mesh *me, const int render);
-void multires_level_to_mesh(struct Object *ob, struct Mesh *me, const int render);
-void multires_calc_level_maps(struct MultiresLevel *lvl);
-void multires_edge_level_update(void *ob, void *me);
+void multires_edge_level_update_cb(void *ob, void *me);
int multires_modifier_warning();
-/* multires-firstlevel.c */
-/* Generic */
-void multires_update_first_level(struct Mesh *me, struct EditMesh *em);
-void multires_update_customdata(struct MultiresLevel *lvl1, struct CustomData *src,
- struct CustomData *dst, const int type);
-void multires_customdata_to_mesh(struct Mesh *me, struct EditMesh *em, struct MultiresLevel *lvl,
- struct CustomData *src, struct CustomData *dst, const int type);
-void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl);
-
-void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n);
-void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n);
-
#endif
diff --git a/source/blender/include/mydevice.h b/source/blender/include/mydevice.h
index 9a8d154e030..949c9f57851 100644
--- a/source/blender/include/mydevice.h
+++ b/source/blender/include/mydevice.h
@@ -257,6 +257,8 @@
#define REDRAWANIM 0x4037
#define REDRAWNODE 0x4038
#define RECALC_COMPOSITE 0x4039
+#define REDRAWMARKER 0x4040 /* all views that display markers */
+#define REDRAWVIEW3D_IMAGE 0x4041
#endif /* !__MYDEVICE_H__ */
diff --git a/source/blender/include/reeb.h b/source/blender/include/reeb.h
new file mode 100644
index 00000000000..c8352aedec5
--- /dev/null
+++ b/source/blender/include/reeb.h
@@ -0,0 +1,127 @@
+/**
+ * $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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Martin Poirier
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef REEB_H_
+#define REEB_H_
+
+#include "DNA_listBase.h"
+
+struct EdgeHash;
+struct ReebArc;
+struct ReebEdge;
+struct ReebNode;
+
+typedef struct ReebGraph {
+ ListBase arcs;
+ ListBase nodes;
+ int totnodes;
+ struct EdgeHash *emap;
+} ReebGraph;
+
+typedef struct EmbedBucket {
+ float val;
+ int nv;
+ float p[3];
+} EmbedBucket;
+
+typedef struct ReebNode {
+ struct ReebNode *next, *prev;
+ struct ReebArc **arcs;
+ int index;
+ int degree;
+ float weight;
+ float p[3];
+ int flags;
+} ReebNode;
+
+typedef struct ReebEdge {
+ struct ReebEdge *next, *prev;
+ struct ReebArc *arc;
+ struct ReebNode *v1, *v2;
+ struct ReebEdge *nextEdge;
+} ReebEdge;
+
+typedef struct ReebArc {
+ struct ReebArc *next, *prev;
+ ListBase edges;
+ struct ReebNode *v1, *v2;
+ struct EmbedBucket *buckets;
+ int bcount;
+ int flags;
+} ReebArc;
+
+typedef struct ReebArcIterator {
+ struct ReebArc *arc;
+ int index;
+ int start;
+ int end;
+ int stride;
+} ReebArcIterator;
+
+struct EditMesh;
+
+int weightToHarmonic(struct EditMesh *em);
+int weightFromDistance(struct EditMesh *em);
+int weightFromLoc(struct EditMesh *me, int axis);
+void weightToVCol(struct EditMesh *em);
+void renormalizeWeight(struct EditMesh *em, float newmax);
+
+ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions);
+void freeGraph(ReebGraph *rg);
+void exportGraph(ReebGraph *rg, int count);
+
+#define OTHER_NODE(arc, node) ((arc->v1 == node) ? arc->v2 : arc->v1)
+
+void initArcIterator(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
+void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end);
+struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
+
+/* Filtering */
+void filterNullReebGraph(ReebGraph *rg);
+int filterExternalReebGraph(ReebGraph *rg, float threshold);
+int filterInternalReebGraph(ReebGraph *rg, float threshold);
+
+/* Post-Build processing */
+void repositionNodes(ReebGraph *rg);
+void postprocessGraph(ReebGraph *rg, char mode);
+void removeNormalNodes(ReebGraph *rg);
+
+/* Graph processing */
+void buildAdjacencyList(ReebGraph *rg);
+
+void sortNodes(ReebGraph *rg);
+void sortArcs(ReebGraph *rg);
+
+int subtreeDepth(ReebNode *node, ReebArc *rootArc);
+int countConnectedArcs(ReebGraph *rg, ReebNode *node);
+int hasAdjacencyList(ReebGraph *rg);
+int isGraphCyclic(ReebGraph *rg);
+
+/* Sanity check */
+void verifyBuckets(ReebGraph *rg);
+
+#endif /*REEB_H_*/
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 6f3ba36a497..cfe85916eb4 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -44,6 +44,8 @@ struct NumInput;
struct Object;
struct View3D;
struct ScrArea;
+struct bPose;
+struct bConstraint;
typedef struct NDofInput {
@@ -127,7 +129,7 @@ typedef struct TransDataExtension {
float iquat[4]; /* Initial rotation quaternion */
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
- float obmat[3][3]; /* Object matrix */
+ float obmat[4][4]; /* Object matrix */
} TransDataExtension;
typedef struct TransData2D {
@@ -148,6 +150,7 @@ typedef struct TransData {
float smtx[3][3]; /* Transformation matrix from global space to data space */
float axismtx[3][3];/* Axis orientation matrix of the data */
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 */
void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */
@@ -238,7 +241,7 @@ typedef struct TransInfo {
// for manipulator exceptions, like scaling using center point, drawing help lines
#define T_USES_MANIPULATOR (1 << 7)
-/* restrictions flags */
+ /* restrictions flags */
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
#define T_NO_CONSTRAINT (1 << 8)
#define T_NULL_ONE (1 << 9)
@@ -247,14 +250,17 @@ typedef struct TransInfo {
#define T_PROP_EDIT (1 << 11)
#define T_PROP_CONNECTED (1 << 12)
-/* if MMB is pressed or not */
+ /* if MMB is pressed or not */
#define T_MMB_PRESSED (1 << 13)
#define T_V3D_ALIGN (1 << 14)
-#define T_2D_EDIT (1 << 15) /* for 2d views like uv or ipo */
+ /* for 2d views like uv or ipo */
+#define T_2D_EDIT (1 << 15)
#define T_CLIP_UV (1 << 16)
#define T_FREE_CUSTOMDATA (1 << 17)
+ /* auto-ik is on */
+#define T_AUTOIK (1 << 18)
/* ******************************************************************************** */
@@ -270,14 +276,19 @@ typedef struct TransInfo {
/* transdata->flag */
#define TD_SELECTED 1
-#define TD_NOACTION 2
-#define TD_USEQUAT 4
-#define TD_NOTCONNECTED 8
-#define TD_SINGLESIZE 16 /* used for scaling of MetaElem->rad */
+#define TD_ACTIVE (1 << 1)
+#define TD_NOACTION (1 << 2)
+#define TD_USEQUAT (1 << 3)
+#define TD_NOTCONNECTED (1 << 4)
+#define TD_SINGLESIZE (1 << 5) /* used for scaling of MetaElem->rad */
#ifdef WITH_VERSE
-#define TD_VERSE_OBJECT 32
-#define TD_VERSE_VERT 64
+ #define TD_VERSE_OBJECT (1 << 6)
+ #define TD_VERSE_VERT (1 << 7)
#endif
+#define TD_TIMEONLY (1 << 8)
+#define TD_NOCENTER (1 << 9)
+#define TD_NO_EXT (1 << 10) /* ext abused for particle key timing */
+#define TD_SKIP (1 << 11) /* don't transform this data */
/* transsnap->status */
#define SNAP_ON 1
@@ -292,6 +303,7 @@ typedef struct TransInfo {
#define SNAP_CLOSEST 0
#define SNAP_CENTER 1
#define SNAP_MEDIAN 2
+#define SNAP_ACTIVE 3
void checkFirstTime(void);
@@ -304,6 +316,7 @@ void convertVecToDisplayNum(float *vec, float *num);
void convertDisplayNumToVec(float *num, float *vec);
void initWarp(TransInfo *t);
+int handleEventWarp(TransInfo *t, unsigned short event, short val);
int Warp(TransInfo *t, short mval[2]);
void initShear(TransInfo *t);
@@ -337,6 +350,13 @@ int Trackball(TransInfo *t, short mval[2]);
void initPushPull(TransInfo *t);
int PushPull(TransInfo *t, short mval[2]);
+void initBevel(TransInfo *t);
+int handleEventBevel(TransInfo *t, unsigned short evenl, short val);
+int Bevel(TransInfo *t, short mval[2]);
+
+void initBevelWeight(TransInfo *t);
+int BevelWeight(TransInfo *t, short mval[2]);
+
void initCrease(TransInfo *t);
int Crease(TransInfo *t, short mval[2]);
@@ -349,15 +369,35 @@ int BoneEnvelope(TransInfo *t, short mval[2]);
void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, short mval[2]);
+void initTimeTranslate(TransInfo *t);
+int TimeTranslate(TransInfo *t, short mval[2]);
+
+void initTimeSlide(TransInfo *t);
+int TimeSlide(TransInfo *t, short mval[2]);
+
+void initTimeScale(TransInfo *t);
+int TimeScale(TransInfo *t, short mval[2]);
+
+void initBakeTime(TransInfo *t);
+int BakeTime(TransInfo *t, short mval[2]);
+
+void initMirror(TransInfo *t);
+int Mirror(TransInfo *t, short mval[2]);
+
+void initAlign(TransInfo *t);
+int Align(TransInfo *t, short mval[2]);
+
/*********************** transform_conversions.c ********** */
struct ListBase;
+void flushTransIpoData(TransInfo *t);
void flushTransUVs(TransInfo *t);
+void flushTransParticles(TransInfo *t);
int clipUVTransform(TransInfo *t, float *vec, int resize);
/*********************** exported from transform_manipulator.c ********** */
void draw_manipulator_ext(struct ScrArea *sa, int type, char axis, int col, float vec[3], float mat[][3]);
int calc_manipulator_stats(struct ScrArea *sa);
-float get_drawsize(struct View3D *v3d);
+float get_drawsize(struct View3D *v3d, float *co);
/*********************** TransData Creation and General Handling *********** */
void createTransData(TransInfo *t);
@@ -365,6 +405,13 @@ void sort_trans_data_dist(TransInfo *t);
void add_tdi_poin(float *poin, float *old, float delta);
void special_aftertrans_update(TransInfo *t);
+void transform_autoik_update(TransInfo *t, short mode);
+
+/* auto-keying stuff used by special_aftertrans_update */
+short autokeyframe_cfra_can_key(struct Object *ob);
+void autokeyframe_ob_cb_func(struct Object *ob, int tmode);
+void autokeyframe_pose_cb_func(struct Object *ob, int tmode, short targetless_ik);
+
/*********************** Constraints *****************************/
void getConstraintMatrix(TransInfo *t);
@@ -428,6 +475,7 @@ void calculateCenterBound(TransInfo *t);
void calculateCenterMedian(TransInfo *t);
void calculateCenterCursor(TransInfo *t);
+void calculateCenterCursor2D(TransInfo *t);
void calculatePropRatio(TransInfo *t);
void getViewVector(float coord[3], float vec[3]);
@@ -455,5 +503,30 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val);
#define NDOF_CANCEL 4
+/*********************** TransSpace ******************************/
+
+int manageObjectSpace(int confirm, int set);
+int manageMeshSpace(int confirm, int set);
+
+/* 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(float mat[3][3], char name[]);
+int addObjectSpace(struct Object *ob);
+void applyTransformOrientation(void);
+
+
+#define ORIENTATION_NONE 0
+#define ORIENTATION_NORMAL 1
+#define ORIENTATION_VERT 2
+#define ORIENTATION_EDGE 3
+#define ORIENTATION_FACE 4
+
+int getTransformOrientation(float normal[3], float plane[3], int activeOnly);
+int createSpaceNormal(float mat[3][3], float normal[3]);
+int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
+
#endif
+
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 14e39faf2c6..57aec75700f 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -65,7 +65,7 @@ typedef struct IDProperty {
/*totallen is total length of allocated array/string, including a buffer.
Note that the buffering is mild; the code comes from python's list implementation.*/
int totallen; /*strings and arrays are both buffered, though the buffer isn't
- saved. at least it won't be when I write that code. :)*/
+ saved.*/
} IDProperty;
#define MAX_IDPROP_NAME 32
@@ -75,21 +75,12 @@ typedef struct IDProperty {
#define IDP_STRING 0
#define IDP_INT 1
#define IDP_FLOAT 2
-#define IDP_VECTOR 3
-#define IDP_MATRIX 4
#define IDP_ARRAY 5
#define IDP_GROUP 6
+/*the ID link property type hasn't been implemented yet, this will require
+ some cleanup of blenkernel, most likely.*/
#define IDP_ID 7
-/*special types for vector, matrices and arrays
- these arn't quite completely implemented, and
- may be removed.*/
-#define IDP_MATRIX4X4 9
-#define IDP_MATRIX3X3 10
-#define IDP_VECTOR2D 11
-#define IDP_VECTOR3D 12
-#define IDP_VECTOR4D 13
-#define IDP_FILE 14
/*add any future new id property types here.*/
/* watch it: Sequence has identical beginning. */
@@ -129,6 +120,18 @@ typedef struct Library {
struct Library *parent; /* for outliner, showing dependency */
} Library;
+#define PREVIEW_MIPMAPS 2
+#define PREVIEW_MIPMAP_ZERO 0
+#define PREVIEW_MIPMAP_LARGE 1
+
+typedef struct PreviewImage {
+ unsigned int w[2];
+ unsigned int h[2];
+ short changed[2];
+ short pad0, pad1;
+ unsigned int * rect[2];
+} PreviewImage;
+
/**
* Defines for working with IDs.
*
@@ -180,6 +183,7 @@ typedef struct Library {
#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')
/* 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 259167b6e6e..d1951e67661 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -33,17 +33,18 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_view2d_types.h"
+#include "DNA_userdef_types.h"
struct SpaceLink;
-struct ListBase;
struct Object;
+/* -------------- Poses ----------------- */
+
/* PoseChannel stores the results of Actions (ipos) and transform information
with respect to the restposition of Armature bones */
-
typedef struct bPoseChannel {
struct bPoseChannel *next, *prev;
- ListBase constraints;
+ ListBase constraints;/* Constraints that act on this PoseChannel */
char name[32]; /* Channels need longer names than normal blender objects */
short flag; /* dynamic, for detecting transform changes */
@@ -51,7 +52,7 @@ typedef struct bPoseChannel {
short ikflag; /* settings for IK bones */
short selectflag; /* copy of bone flag, so you can work with library armatures */
short protectflag; /* protect channels from being transformed */
- short pad2;
+ short agrp_index; /* index of action-group this bone belongs to (0 = default/no group) */
int pathlen; /* for drawing paths, the amount of frames */
int pathsf; /* for drawing paths, the start frame number */
@@ -61,7 +62,12 @@ typedef struct bPoseChannel {
struct bPoseChannel *parent; /* set on read file or rebuild pose */
struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */
struct ListBase iktree; /* only while evaluating pose */
- void *b_bone_mats; /* only while deform, stores precalculated b_bone deform mats */
+
+ /* only while deform, stores precalculated b_bone deform mats,
+ dual quaternions */
+ void *b_bone_mats;
+ void *dual_quat;
+ void *b_bone_dual_quats;
float loc[3]; /* written in by actions or transform */
float size[3];
@@ -69,6 +75,7 @@ typedef struct bPoseChannel {
float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */
float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat */
+ float constinv[4][4]; /* inverse result of constraints. doesn't include effect of restposition, parent, and local transform*/
float pose_head[3]; /* actually pose_mat[3] */
float pose_tail[3]; /* also used for drawing help lines... */
@@ -79,33 +86,92 @@ typedef struct bPoseChannel {
float *path; /* totpath x 3 x float */
struct Object *custom; /* draws custom object instead of this channel */
-
} bPoseChannel;
-
-typedef struct bPose{
- ListBase chanbase;
+/* Pose-Object. It is only found under ob->pose. It is not library data, even
+ * though there is a define for it (hack for the outliner).
+ */
+typedef struct bPose {
+ ListBase chanbase; /* list of pose channels */
+
short flag, proxy_layer; /* proxy layer: copy from armature, gets synced */
+
float ctime; /* local action time of this pose */
float stride_offset[3]; /* applied to object */
float cyclic_offset[3]; /* result of match and cycles, applied in where_is_pose() */
+
+
+ ListBase agroups; /* list of bActionGroups */
+
+ int active_group; /* index of active group (starts from 1) */
+ int pad;
} bPose;
+
+/* ------------- Action ---------------- */
+
+/* Action-Channel Group. These are stored as a list per-Action, and are only used to
+ * group that Action's Action-Channels when displayed in the Action Editor.
+ *
+ * Even though all Action-Channels live in a big list per Action, each group they are in also
+ * holds references to the achans within that list which belong to it. Care must be taken to
+ * ensure that action-groups never end up being the sole 'owner' of a channel.
+ *
+ *
+ * This is also exploited for bone-groups. Bone-Groups are stored per bPose, and are used
+ * primarily to colour bones in the 3d-view. There are other benefits too, but those are mostly related
+ * to Action-Groups.
+ */
+typedef struct bActionGroup {
+ struct bActionGroup *next, *prev;
+
+ ListBase channels; /* Note: this must not be touched by standard listbase functions */
+
+ int flag; /* settings for this action-group */
+ int customCol; /* index of custom color set to use when used for bones (0=default - used for all old files, -1=custom set) */
+ char name[32]; /* name of the group */
+
+ ThemeWireColor cs; /* color set to use when customCol == -1 */
+} bActionGroup;
+
+/* Action Channels belong to Actions. They are linked with an IPO block, and can also own
+ * Constraint Channels in certain situations.
+ *
+ * Action-Channels can only belong to one group at a time, but they still live the Action's
+ * list of achans (to preserve backwards compatability, and also minimise the code
+ * that would need to be recoded). Grouped achans are stored at the start of the list, according
+ * to the position of the group in the list, and their position within the group.
+ */
typedef struct bActionChannel {
struct bActionChannel *next, *prev;
- struct Ipo *ipo;
- ListBase constraintChannels;
+ bActionGroup *grp; /* Action Group this Action Channel belongs to */
+
+ struct Ipo *ipo; /* IPO block this action channel references */
+ ListBase constraintChannels; /* Constraint Channels (when Action Channel represents an Object or Bone) */
- int flag;
- char name[32]; /* Channel name */
+ int flag; /* settings accessed via bitmapping */
+ char name[32]; /* channel name */
int reserved1;
} bActionChannel;
+/* Action. A recyclable block that contains a series of Action Channels (ipo), which define
+ * a clip of reusable animation for use in the NLA.
+ */
typedef struct bAction {
ID id;
- ListBase chanbase; /* Action Channels in this action */
+
+ ListBase chanbase; /* Action Channels in this Action */
+ ListBase groups; /* Action Groups in the Action */
+ ListBase markers; /* TimeMarkers local to this Action for labelling 'poses' */
+
+ int active_marker; /* Index of active-marker (first marker = 1) */
+ int pad;
} bAction;
+
+/* ------------- Action Editor --------------------- */
+
+/* Action Editor Space. This is defined here instead of in DNA_space_types.h */
typedef struct SpaceAction {
struct SpaceLink *next, *prev;
int spacetype;
@@ -115,35 +181,85 @@ typedef struct SpaceAction {
short blockhandler[8];
View2D v2d;
- bAction *action;
- short flag, autosnap;
- short pin, actnr, lock, actwidth;
- float timeslide;
+
+ bAction *action; /* the currently active action */
+ short flag, autosnap; /* flag: bitmapped settings; autosnap: automatic keyframe snapping mode */
+ short pin, actnr, lock; /* pin: keep showing current action; actnr: used for finding chosen action from menu; lock: lock time to other windows */
+ short actwidth; /* width of the left-hand side name panel (in pixels?) */
+ float timeslide; /* for Time-Slide transform mode drawing - current frame? */
} SpaceAction;
+
+/* -------------- Action Flags -------------- */
+
/* Action Channel flags */
-#define ACHAN_SELECTED 0x00000001
-#define ACHAN_HILIGHTED 0x00000002
-#define ACHAN_HIDDEN 0x00000004
-#define ACHAN_PROTECTED 0x00000008
-#define ACHAN_EXPANDED 0x00000010
-#define ACHAN_SHOWIPO 0x00000020
-#define ACHAN_SHOWCONS 0x00000040
-#define ACHAN_MOVED 0x80000000
+typedef enum ACHAN_FLAG {
+ ACHAN_SELECTED = (1<<0),
+ ACHAN_HILIGHTED = (1<<1),
+ ACHAN_HIDDEN = (1<<2),
+ ACHAN_PROTECTED = (1<<3),
+ ACHAN_EXPANDED = (1<<4),
+ ACHAN_SHOWIPO = (1<<5),
+ ACHAN_SHOWCONS = (1<<6),
+ ACHAN_MOVED = (1<<31),
+} ACHAN_FLAG;
+
+
+/* Action Group flags */
+typedef enum AGRP_FLAG {
+ AGRP_SELECTED = (1<<0),
+ AGRP_ACTIVE = (1<<1),
+ AGRP_PROTECTED = (1<<2),
+ AGRP_EXPANDED = (1<<3),
+
+ AGRP_TEMP = (1<<30),
+ AGRP_MOVED = (1<<31)
+} AGRP_FLAG;
+
+/* ------------ Action Editor Flags -------------- */
/* SpaceAction flag */
-#define SACTION_MOVING 1 /* during transform */
-#define SACTION_SLIDERS 2 /* show sliders (if relevant) - limited to shape keys for now */
+typedef enum SACTION_FLAG {
+ /* during transform (only set for TimeSlide) */
+ SACTION_MOVING = (1<<0),
+ /* show sliders (if relevant) */
+ SACTION_SLIDERS = (1<<1),
+ /* draw time in seconds instead of time in frames */
+ SACTION_DRAWTIME = (1<<2),
+ /* don't filter action channels according to visibility */
+ SACTION_NOHIDE = (1<<3),
+ /* don't kill overlapping keyframes after transform */
+ SACTION_NOTRANSKEYCULL = (1<<4),
+ /* don't include keyframes that are out of view */
+ SACTION_HORIZOPTIMISEON = (1<<5),
+ /* hack for moving pose-markers (temp flag) */
+ SACTION_POSEMARKERS_MOVE = (1<<6)
+} SACTION_FLAG;
-/* SpaceAction AutoSnap Settings */
-#define SACTSNAP_OFF 0 /* no auto-snap */
-#define SACTSNAP_STEP 1 /* snap to 1.0 frame intervals */
-#define SACTSNAP_FRAME 2 /* snap to actual frames (nla-action time) */
+/* SpaceAction AutoSnap Settings (also used by SpaceNLA) */
+typedef enum SACTSNAP_MODES {
+ /* no auto-snap */
+ SACTSNAP_OFF = 0,
+ /* snap to 1.0 frame/second intervals */
+ SACTSNAP_STEP,
+ /* snap to actual frames/seconds (nla-action time) */
+ SACTSNAP_FRAME,
+ /* snap to nearest marker */
+ SACTSNAP_MARKER,
+} SACTSNAP_MODES;
+
+
+/* --------- Pose Flags --------------- */
/* Pose->flag */
-#define POSE_RECALC 1
-#define POSE_LOCKED 2
-#define POSE_DO_UNLOCK 4
+typedef enum POSE_FLAG {
+ /* results in armature_rebuild_pose being called */
+ POSE_RECALC = (1<<0),
+ /* prevents any channel from getting overridden by anim from IPO */
+ POSE_LOCKED = (1<<1),
+ /* clears the POSE_LOCKED flag for the next time the pose is evaluated */
+ POSE_DO_UNLOCK = (1<<2)
+} POSE_FLAG;
/* PoseChannel (transform) flags */
enum {
@@ -163,22 +279,30 @@ enum {
};
/* PoseChannel constflag (constraint detection) */
-#define PCHAN_HAS_IK 1
-#define PCHAN_HAS_CONST 2
- /* only used for drawing Posemode, not stored in channel */
-#define PCHAN_HAS_ACTION 4
-#define PCHAN_HAS_TARGET 8
- /* only for drawing Posemode too */
-#define PCHAN_HAS_STRIDE 16
+typedef enum PCHAN_CONSTFLAG {
+ PCHAN_HAS_IK = (1<<0),
+ PCHAN_HAS_CONST = (1<<1),
+ /* only used for drawing Posemode, not stored in channel */
+ PCHAN_HAS_ACTION = (1<<2),
+ PCHAN_HAS_TARGET = (1<<3),
+ /* only for drawing Posemode too */
+ PCHAN_HAS_STRIDE = (1<<4)
+} PCHAN_CONSTFLAG;
/* PoseChannel->ikflag */
-#define BONE_IK_NO_XDOF 1
-#define BONE_IK_NO_YDOF 2
-#define BONE_IK_NO_ZDOF 4
+typedef enum PCHAN_IKFLAG {
+ BONE_IK_NO_XDOF = (1<<0),
+ BONE_IK_NO_YDOF = (1<<1),
+ BONE_IK_NO_ZDOF = (1<<2),
-#define BONE_IK_XLIMIT 8
-#define BONE_IK_YLIMIT 16
-#define BONE_IK_ZLIMIT 32
+ BONE_IK_XLIMIT = (1<<3),
+ BONE_IK_YLIMIT = (1<<4),
+ BONE_IK_ZLIMIT = (1<<5),
+
+ BONE_IK_NO_XDOF_TEMP = (1<<10),
+ BONE_IK_NO_YDOF_TEMP = (1<<11),
+ BONE_IK_NO_ZDOF_TEMP = (1<<12)
+} PCHAN_IKFLAG;
#endif
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 0531e70bb97..0d324b7d5d3 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -38,6 +38,7 @@ struct Object;
struct Mesh;
struct Scene;
struct Group;
+struct Text;
/* ****************** ACTUATORS ********************* */
@@ -191,6 +192,19 @@ typedef struct bVisibilityActuator {
int flag;
} bVisibilityActuator;
+typedef struct bTwoDFilterActuator{
+ char pad[4];
+ /* Tells what type of 2D Filter*/
+ short type;
+ /* (flag == 0) means 2D filter is activate and
+ (flag != 0) means 2D filter is inactive*/
+ short flag;
+ int int_arg;
+ /* a float argument */
+ float float_arg;
+ struct Text *text;
+}bTwoDFilterActuator;
+
typedef struct bActuator {
struct bActuator *next, *prev, *mynew;
short type;
@@ -259,6 +273,7 @@ typedef struct FreeCamera {
#define ACT_CD 16
#define ACT_GAME 17
#define ACT_VISIBILITY 18
+#define ACT_2DFILTER 19
/* actuator flag */
#define ACT_SHOW 1
@@ -391,5 +406,23 @@ typedef struct FreeCamera {
/* Set means the object will become invisible */
#define ACT_VISIBILITY_INVISIBLE (1 << 0)
+/* twodfilter->type */
+#define ACT_2DFILTER_ENABLED -2
+#define ACT_2DFILTER_DISABLED -1
+#define ACT_2DFILTER_NOFILTER 0
+#define ACT_2DFILTER_MOTIONBLUR 1
+#define ACT_2DFILTER_BLUR 2
+#define ACT_2DFILTER_SHARPEN 3
+#define ACT_2DFILTER_DILATION 4
+#define ACT_2DFILTER_EROSION 5
+#define ACT_2DFILTER_LAPLACIAN 6
+#define ACT_2DFILTER_SOBEL 7
+#define ACT_2DFILTER_PREWITT 8
+#define ACT_2DFILTER_GRAYSCALE 9
+#define ACT_2DFILTER_SEPIA 10
+#define ACT_2DFILTER_INVERT 11
+#define ACT_2DFILTER_CUSTOMFILTER 12
+#define ACT_2DFILTER_NUMBER_OF_FILTERS 13
#endif
+
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index b3235fc71f3..fcc847a1b30 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -68,7 +68,7 @@ typedef struct Bone {
float size[3]; /* patch for upward compat, UNUSED! */
short layer;
short segments; /* for B-bones */
-}Bone;
+} Bone;
typedef struct bArmature {
ID id;
@@ -79,71 +79,84 @@ typedef struct bArmature {
short deformflag;
short pathflag;
short layer, layer_protected; /* for buttons to work, both variables in this order together */
- short ghostep, ghostsize; /*number of frames to ghosts to show, and step between them */
+ short ghostep, ghostsize; /* number of frames to ghosts to show, and step between them */
short ghosttype, pathsize; /* ghost drawing options and number of frames between points of path */
int ghostsf, ghostef; /* start and end frames of ghost-drawing range */
- int pathsf, pathef; /* start and end frames of path-calculation range for all bones */
-}bArmature;
+ int pathsf, pathef; /* start and end frames of path-calculation range for all bones */
+ int pathbc, pathac; /* number of frames before/after current frame of path-calculation for all bones */
+} bArmature;
/* armature->flag */
/* dont use bit 7, was saved in files to disable stuff */
-
-/* armature->flag */
-#define ARM_RESTPOS 0x001
- /* XRAY is here only for backwards converting */
-#define ARM_DRAWXRAY 0x002
-#define ARM_DRAWAXES 0x004
-#define ARM_DRAWNAMES 0x008
-#define ARM_POSEMODE 0x010
-#define ARM_EDITMODE 0x020
-#define ARM_DELAYDEFORM 0x040
-#define ARM_DONT_USE 0x080
-#define ARM_MIRROR_EDIT 0x100
-#define ARM_AUTO_IK 0x200
- /* made option negative, for backwards compat */
-#define ARM_NO_CUSTOM 0x400
-#define ARM_COL_CUSTOM 0x800
+typedef enum eArmature_Flag {
+ ARM_RESTPOS = (1<<0),
+ ARM_DRAWXRAY = (1<<1), /* XRAY is here only for backwards converting */
+ ARM_DRAWAXES = (1<<2),
+ ARM_DRAWNAMES = (1<<3),
+ ARM_POSEMODE = (1<<4),
+ ARM_EDITMODE = (1<<5),
+ ARM_DELAYDEFORM = (1<<6),
+ ARM_DONT_USE = (1<<7),
+ ARM_MIRROR_EDIT = (1<<8),
+ 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) */
+} eArmature_Flag;
/* armature->drawtype */
-#define ARM_OCTA 0
-#define ARM_LINE 1
-#define ARM_B_BONE 2
-#define ARM_ENVELOPE 3
+typedef enum eArmature_Drawtype {
+ ARM_OCTA = 0,
+ ARM_LINE,
+ ARM_B_BONE,
+ ARM_ENVELOPE
+} eArmature_Drawtype;
/* armature->deformflag */
-#define ARM_DEF_VGROUP 1
-#define ARM_DEF_ENVELOPE 2
+typedef enum eArmature_DeformFlag {
+ ARM_DEF_VGROUP = (1<<0),
+ ARM_DEF_ENVELOPE = (1<<1),
+ ARM_DEF_QUATERNION = (1<<2),
+ ARM_DEF_B_BONE_REST = (1<<3),
+ ARM_DEF_INVERT_VGROUP = (1<<4)
+} eArmature_DeformFlag;
/* armature->pathflag */
-#define ARM_PATH_FNUMS 0x001
-#define ARM_PATH_KFRAS 0x002
-#define ARM_PATH_HEADS 0x004
+typedef enum eArmature_PathFlag {
+ ARM_PATH_FNUMS = (1<<0),
+ ARM_PATH_KFRAS = (1<<1),
+ ARM_PATH_HEADS = (1<<2),
+ ARM_PATH_ACFRA = (1<<3),
+ ARM_PATH_KFNOS = (1<<4)
+} eArmature_PathFlag;
/* armature->ghosttype */
-#define ARM_GHOST_CUR 0
-#define ARM_GHOST_RANGE 1
+typedef enum eArmature_GhostType {
+ ARM_GHOST_CUR = 0,
+ ARM_GHOST_RANGE,
+ ARM_GHOST_KEYS
+} eArmature_GhostType;
/* bone->flag */
-#define BONE_SELECTED 1
-#define BONE_ROOTSEL 2
-#define BONE_TIPSEL 4
- /* Used instead of BONE_SELECTED during transform */
-#define BONE_TRANSFORM 8
-#define BONE_CONNECTED 16
- /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
- /* hidden Bones when drawing Posechannels */
-#define BONE_HIDDEN_P 64
- /* For detecting cyclic dependancies */
-#define BONE_DONE 128
- /* active is on mouse clicks only */
-#define BONE_ACTIVE 256
- /* No parent rotation or scale */
-#define BONE_HINGE 512
- /* hidden Bones when drawing Armature Editmode */
-#define BONE_HIDDEN_A 1024
- /* multiplies vgroup with envelope */
-#define BONE_MULT_VG_ENV 2048
-#define BONE_NO_DEFORM 4096
-
+typedef enum eBone_Flag {
+ BONE_SELECTED = (1<<0),
+ BONE_ROOTSEL = (1<<1),
+ BONE_TIPSEL = (1<<2),
+ BONE_TRANSFORM = (1<<3), /* Used instead of BONE_SELECTED during transform */
+ BONE_CONNECTED = (1<<4),
+ /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
+ BONE_HIDDEN_P = (1<<6), /* hidden Bones when drawing PoseChannels */
+ BONE_DONE = (1<<7), /* For detecting cyclic dependancies */
+ BONE_ACTIVE = (1<<8), /* active is on mouse clicks only */
+ BONE_HINGE = (1<<9), /* No parent rotation or scale */
+ BONE_HIDDEN_A = (1<<10), /* hidden Bones when drawing Armature Editmode */
+ BONE_MULT_VG_ENV = (1<<11), /* multiplies vgroup with envelope */
+ BONE_NO_DEFORM = (1<<12),
+ BONE_UNKEYED = (1<<13), /* set to prevent destruction of its unkeyframed pose (after transform) */
+ BONE_HINGE_CHILD_TRANSFORM = (1<<14), /* set to prevent hinge child bones from influencing the transform center */
+ BONE_NO_SCALE = (1<<15), /* No parent scale */
+ BONE_HIDDEN_PG = (1<<16), /* hidden bone when drawing PoseChannels (for ghost drawing) */
+ BONE_DRAWWIRE = (1<<17) /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */
+} eBone_Flag;
#endif
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index f25d8fd6412..4cb8ec25ebc 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -42,6 +42,7 @@ extern "C" {
#endif
struct Ipo;
+struct Object;
typedef struct Camera {
ID id;
@@ -62,6 +63,7 @@ typedef struct Camera {
struct Ipo *ipo;
ScriptLink scriptlink;
+ struct Object *dof_ob;
} Camera;
/* **************** CAMERA ********************* */
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
new file mode 100644
index 00000000000..4ba1f4f02e8
--- /dev/null
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -0,0 +1,135 @@
+/**
+* $Id: DNA_cloth_types.h,v 1.1 2007/08/01 02:28:34 daniel Exp $
+*
+* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You 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 by NaN Holding BV.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): Daniel (Genscher)
+*
+* ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+#ifndef DNA_CLOTH_TYPES_H
+#define DNA_CLOTH_TYPES_H
+
+
+/**
+* This struct contains all the global data required to run a simulation.
+* At the time of this writing, this structure contains data appropriate
+* to run a simulation as described in Deformation Constraints in a
+* Mass-Spring Model to Describe Rigid Cloth Behavior by Xavier Provot.
+*
+* I've tried to keep similar, if not exact names for the variables as
+* are presented in the paper. Where I've changed the concept slightly,
+* as in stepsPerFrame comapred to the time step in the paper, I've used
+* variables with different names to minimize confusion.
+**/
+typedef struct SimulationSettings
+{
+ short vgroup_mass; /* optional vertexgroup name for assigning weight.*/
+ short vgroup_struct; /* vertex group for scaling structural stiffness */
+ float mingoal; /* see SB */
+ int preroll; /* How many frames of simulation to do before we start. */
+ float Cdis; /* Mechanical damping of springs. */
+ float Cvi; /* Viscous/fluid damping. */
+ int stepsPerFrame; /* Number of time steps per frame. */
+ float gravity [3]; /* Gravity/external force vector. */
+ float ufluid [3]; /* Velocity vector of the fluid. */
+ float dt; /* This is the duration of our time step, computed. */
+ float mass; /* The mass of the entire cloth. */
+ float structural; /* Structural spring stiffness. */
+ float shear; /* Shear spring stiffness. */
+ float bending; /* Flexion spring stiffness. */
+ float sim_time;
+ int flags; /* flags, see CSIMSETT_FLAGS enum above. */
+ short solver_type; /* which solver should be used? txold */
+ short vgroup_bend; /* vertex group for scaling bending stiffness */
+ float maxgoal; /* see SB */
+ float eff_force_scale;/* Scaling of effector forces (see softbody_calc_forces).*/
+ float eff_wind_scale; /* Scaling of effector wind (see softbody_calc_forces). */
+ float sim_time_old;
+ struct LinkNode *cache; /* UNUSED atm */
+ float defgoal;
+ int goalfrict;
+ float goalspring;
+ int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */
+ int lastframe; /* frame on which simulation stops */
+ int firstframe; /* frame on which simulation starts */
+ int lastcachedframe;
+ int editedframe; /* which frame is in buffer */
+ int autoprotect; /* starting from this frame, cache gets protected */
+ float max_bend; /* max bending scaling value, min is "bending" */
+ float max_struct; /* max structural scaling value, min is "structural" */
+ float max_shear; /* max shear scaling value, UNUSED */
+ int firstcachedframe;
+ float avg_spring_len; /* used for normalized springs */
+ short presets; /* used for presets on GUI */
+ short pad;
+ int pad2;
+}
+SimulationSettings;
+
+
+typedef struct CollisionSettings
+{
+ float epsilon; /* min distance for collisions. */
+ float self_friction; /* Fiction/damping with self contact. */
+ float friction; /* Friction/damping applied on contact with other object.*/
+ short self_loop_count; /* How many iterations for the selfcollision loop */
+ short loop_count; /* How many iterations for the collision loop. */
+ struct LinkNode *collision_list; /* e.g. pointer to temp memory for collisions */
+ int flags; /* collision flags defined in BKE_cloth.h */
+ float selfepsilon; /* for selfcollision */
+}
+CollisionSettings;
+
+
+/**
+* This structure describes a cloth object against which the
+* simulation can run.
+*
+* The m and n members of this structure represent the assumed
+* rectangular ordered grid for which the original paper is written.
+* At some point they need to disappear and we need to determine out
+* own connectivity of the mesh based on the actual edges in the mesh.
+*
+**/
+typedef struct Cloth
+{
+ struct ClothVertex *verts; /* The vertices that represent this cloth. */
+ struct LinkNode *springs; /* The springs connecting the mesh. */
+ unsigned int numverts; /* The number of verts == m * n. */
+ unsigned int numsprings; /* The count of springs. */
+ unsigned int numfaces;
+ unsigned char old_solver_type; /* unused, only 1 solver here */
+ unsigned char pad2;
+ short pad3;
+ struct BVH *tree; /* collision tree for this cloth object */
+ struct MFace *mfaces;
+ struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
+ struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */
+ struct EdgeHash *edgehash; /* used for selfcollisions */
+}
+Cloth;
+
+#endif
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index a4224976f5f..3caa74c9a72 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -69,13 +69,16 @@ typedef struct CurveMapping {
CurveMap cm[4]; /* max 4 builtin curves per mapping struct now */
float black[3], white[3]; /* black/white point (black[0] abused for current frame) */
- float bwmul[3], padf; /* black/white point multiply value, for speed */
+ float bwmul[3]; /* black/white point multiply value, for speed */
+
+ float sample[3]; /* sample values, if flag set it draws line and intersection */
} CurveMapping;
/* cumapping->flag */
#define CUMA_DO_CLIP 1
#define CUMA_PREMULLED 2
#define CUMA_DRAW_CFRA 4
+#define CUMA_DRAW_SAMPLE 8
#endif
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 74307454187..2bcf2412588 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung, major recode
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
* Constraint DNA data
@@ -36,44 +36,113 @@
#include "DNA_ID.h"
#include "DNA_ipo_types.h"
+#include "DNA_listBase.h"
#include "DNA_object_types.h"
struct Action;
+struct Text;
+struct Ipo;
/* channels reside in Object or Action (ListBase) constraintChannels */
-typedef struct bConstraintChannel{
+typedef struct bConstraintChannel {
struct bConstraintChannel *next, *prev;
Ipo *ipo;
short flag;
char name[30];
} bConstraintChannel;
-typedef struct bConstraint{
+/* A Constraint */
+typedef struct bConstraint {
struct bConstraint *next, *prev;
+
void *data; /* Constraint data (a valid constraint type) */
short type; /* Constraint type */
- short flag; /* Flag */
- short reserved1;
- char name[30]; /* Constraint name */
-
- float enforce;
+ short flag; /* Flag - General Settings */
+
+ char ownspace; /* Space that owner should be evaluated in */
+ char tarspace; /* Space that target should be evaluated in (only used if 1 target) */
+
+ char name[30]; /* Constraint name */
+
+ float enforce; /* Amount of influence exherted by constraint (0.0-1.0) */
+ float headtail; /* Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail*/
+ int pad;
+ struct Ipo *ipo; /* local influence ipo or driver */
} bConstraint;
-/* Single-target subobject constraints */
-typedef struct bKinematicConstraint{
+
+/* Multiple-target constraints --------------------- */
+
+/* This struct defines a constraint target.
+ * It is used during constraint solving regardless of how many targets the
+ * constraint has.
+ */
+typedef struct bConstraintTarget {
+ struct bConstraintTarget *next, *prev;
+
+ Object *tar; /* object to use as target */
+ char subtarget[32]; /* subtarget - pchan or vgroup name */
+
+ float matrix[4][4]; /* matrix used during constraint solving - should be cleared before each use */
+
+ short space; /* space that target should be evaluated in (overrides bConstraint->tarspace) */
+ short flag; /* runtime settings (for editor, etc.) */
+ short type; /* type of target (B_CONSTRAINT_OB_TYPE) */
+ short pad;
+} bConstraintTarget;
+
+/* bConstraintTarget -> flag */
+typedef enum B_CONSTRAINT_TARGET_FLAG {
+ CONSTRAINT_TAR_TEMP = (1<<0), /* temporary target-struct that needs to be freed after use */
+} B_CONSTRAINT_TARGET_FLAG;
+
+/* bConstraintTarget/bConstraintOb -> type */
+typedef enum B_CONSTRAINT_OB_TYPE {
+ CONSTRAINT_OBTYPE_OBJECT = 1, /* string is "" */
+ CONSTRAINT_OBTYPE_BONE, /* string is bone-name */
+ CONSTRAINT_OBTYPE_VERT, /* string is vertex-group name */
+ CONSTRAINT_OBTYPE_CV /* string is vertex-group name - is not available until curves get vgroups */
+} B_CONSTRAINT_OB_TYPE;
+
+
+
+/* Python Script Constraint */
+typedef struct bPythonConstraint {
+ struct Text *text; /* text-buffer (containing script) to execute */
+ IDProperty *prop; /* 'id-properties' used to store custom properties for constraint */
+
+ int flag; /* general settings/state indicators accessed by bitmapping */
+ int tarnum; /* number of targets - usually only 1-3 are needed */
+
+ ListBase targets; /* a list of targets that this constraint has (bConstraintTarget-s) */
+
+ Object *tar; /* target from previous implementation (version-patch sets this to NULL on file-load) */
+ char subtarget[32]; /* subtarger from previous implentation (version-patch sets this to "" on file-load) */
+} bPythonConstraint;
+
+
+/* Inverse-Kinematics (IK) constraint */
+typedef struct bKinematicConstraint {
Object *tar;
short iterations; /* Maximum number of iterations to try */
short flag; /* Like CONSTRAINT_IK_TIP */
- int rootbone; /* index to rootbone, if zero go all the way to mother bone */
+ 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 */
- int pad;
} bKinematicConstraint;
-typedef struct bTrackToConstraint{
+
+/* Single-target subobject constraints --------------------- */
+/* Track To Constraint */
+typedef struct bTrackToConstraint {
Object *tar;
int reserved1; /* I'll be using reserved1 and reserved2 as Track and Up flags, not sure if that's what they were intented for anyway. Not sure either if it would create backward incompatibility if I were to rename them. - theeth*/
int reserved2;
@@ -82,52 +151,57 @@ typedef struct bTrackToConstraint{
char subtarget[32];
} bTrackToConstraint;
-typedef struct bRotateLikeConstraint{
+/* Copy Rotation Constraint */
+typedef struct bRotateLikeConstraint {
Object *tar;
int flag;
int reserved1;
char subtarget[32];
} bRotateLikeConstraint;
-typedef struct bLocateLikeConstraint{
+/* Copy Location Constraint */
+typedef struct bLocateLikeConstraint {
Object *tar;
int flag;
int reserved1;
char subtarget[32];
} bLocateLikeConstraint;
-typedef struct bMinMaxConstraint{
+/* Floor Constraint */
+typedef struct bMinMaxConstraint {
Object *tar;
int minmaxflag;
- float offset;
- int flag;
- short sticky, stuck, pad1, pad2; /* for backward compatability */
- float cache[3];
+ float offset;
+ int flag;
+ short sticky, stuck, pad1, pad2; /* for backward compatability */
+ float cache[3];
char subtarget[32];
} bMinMaxConstraint;
-typedef struct bSizeLikeConstraint{
+/* Copy Scale Constraint */
+typedef struct bSizeLikeConstraint {
Object *tar;
int flag;
int reserved1;
char subtarget[32];
} bSizeLikeConstraint;
-typedef struct bActionConstraint{
+/* Action Constraint */
+typedef struct bActionConstraint {
Object *tar;
- short type;
- short local;
- int start;
- int end;
+ short type; /* what transform 'channel' drives the result */
+ short local; /* was used in versions prior to the Constraints recode */
+ int start;
+ int end;
float min;
float max;
- int pad;
+ int pad;
struct bAction *act;
char subtarget[32];
} bActionConstraint;
/* Locked Axis Tracking constraint */
-typedef struct bLockTrackConstraint{
+typedef struct bLockTrackConstraint {
Object *tar;
int trackflag;
int lockflag;
@@ -135,7 +209,7 @@ typedef struct bLockTrackConstraint{
} bLockTrackConstraint;
/* Follow Path constraints */
-typedef struct bFollowPathConstraint{
+typedef struct bFollowPathConstraint {
Object *tar; /* Must be path object */
float offset; /* Offset in time on the path (in frame) */
int followflag;
@@ -143,26 +217,8 @@ typedef struct bFollowPathConstraint{
int upflag;
} bFollowPathConstraint;
-/* Distance Limiting constraints */
-typedef struct bDistanceLimitConstraint{
- Object *tar;
- char subtarget[32];
- float pad1;
- float pad2;
- float distance;
- float offset[3];
-} bDistanceLimitConstraint;
-
-
-/* Zero-target constraints */
-typedef struct bRotationConstraint{
- float xmin, xmax;
- float ymin, ymax;
- float zmin, zmax;
-} bRotationConstraint;
-
/* Stretch to constraint */
-typedef struct bStretchToConstraint{
+typedef struct bStretchToConstraint {
Object *tar;
int volmode;
int plane;
@@ -171,33 +227,8 @@ typedef struct bStretchToConstraint{
char subtarget[32];
} bStretchToConstraint;
-/* transform limiting constraints - zero target */
-typedef struct bLocLimitConstraint{
- float xmin, xmax;
- float ymin, ymax;
- float zmin, zmax;
- short flag;
- short flag2;
-} bLocLimitConstraint;
-
-typedef struct bRotLimitConstraint{
- float xmin, xmax;
- float ymin, ymax;
- float zmin, zmax;
- short flag;
- short pad1;
-} bRotLimitConstraint;
-
-typedef struct bSizeLimitConstraint{
- float xmin, xmax;
- float ymin, ymax;
- float zmin, zmax;
- short flag;
- short pad1;
-} bSizeLimitConstraint;
-
/* Rigid Body constraint */
-typedef struct bRigidBodyJointConstraint{
+typedef struct bRigidBodyJointConstraint {
Object *tar;
Object *child;
int type;
@@ -216,49 +247,151 @@ typedef struct bRigidBodyJointConstraint{
short pad2;
} bRigidBodyJointConstraint;
-/* ClampTo Constraint */
+/* Clamp-To Constraint */
typedef struct bClampToConstraint {
Object *tar; /* 'target' must be a curve */
int flag; /* which axis/plane to compare owner's location on */
- int pad;
+ int flag2; /* for legacy reasons, this is flag2. used for any extra settings */
} bClampToConstraint;
-/* bConstraint.type */
-#define CONSTRAINT_TYPE_NULL 0
-#define CONSTRAINT_TYPE_CHILDOF 1 /* Unimplemented */
-#define CONSTRAINT_TYPE_TRACKTO 2
-#define CONSTRAINT_TYPE_KINEMATIC 3
-#define CONSTRAINT_TYPE_FOLLOWPATH 4
-#define CONSTRAINT_TYPE_ROTLIMIT 5 /* Unimplemented no longer :) - Aligorith */
-#define CONSTRAINT_TYPE_LOCLIMIT 6 /* Unimplemented no longer :) - Aligorith */
-#define CONSTRAINT_TYPE_SIZELIMIT 7 /* Unimplemented no longer :) - Aligorith */
-#define CONSTRAINT_TYPE_ROTLIKE 8
-#define CONSTRAINT_TYPE_LOCLIKE 9
-#define CONSTRAINT_TYPE_SIZELIKE 10
-#define CONSTRAINT_TYPE_PYTHON 11 /* Unimplemented */
-#define CONSTRAINT_TYPE_ACTION 12
-#define CONSTRAINT_TYPE_LOCKTRACK 13 /* New Tracking constraint that locks an axis in place - theeth */
-#define CONSTRAINT_TYPE_DISTANCELIMIT 14
-#define CONSTRAINT_TYPE_STRETCHTO 15 /* claiming this to be mine :) is in tuhopuu bjornmose */
-#define CONSTRAINT_TYPE_MINMAX 16 /* floor constraint */
-#define CONSTRAINT_TYPE_RIGIDBODYJOINT 17 /* rigidbody constraint */
-#define CONSTRAINT_TYPE_CLAMPTO 18 /* clampto constraint */
-
-/* bConstraint.flag */
+/* Child Of Constraint */
+typedef struct bChildOfConstraint {
+ Object *tar; /* object which will act as parent (or target comes from) */
+ int flag; /* settings */
+ int pad;
+ float invmat[4][4]; /* parent-inverse matrix to use */
+ char subtarget[32]; /* string to specify a subobject target */
+} bChildOfConstraint;
+
+/* Generic Transform->Transform Constraint */
+typedef struct bTransformConstraint {
+ Object *tar; /* target (i.e. 'driver' object/bone) */
+ char subtarget[32];
+
+ short from, to; /* can be loc(0) , rot(1), or size(2) */
+ char map[3]; /* defines which target-axis deform is copied by each owner-axis */
+ char expo; /* extrapolate motion? if 0, confine to ranges */
+
+ float from_min[3]; /* from_min/max defines range of target transform */
+ float from_max[3]; /* to map on to to_min/max range. */
+
+ float to_min[3]; /* range of motion on owner caused by target */
+ float to_max[3];
+} bTransformConstraint;
+
+/* transform limiting constraints - zero target ---------------------------- */
+/* Limit Location Constraint */
+typedef struct bLocLimitConstraint {
+ float xmin, xmax;
+ float ymin, ymax;
+ float zmin, zmax;
+ short flag;
+ short flag2;
+} bLocLimitConstraint;
+
+/* Limit Rotation Constraint */
+typedef struct bRotLimitConstraint {
+ float xmin, xmax;
+ float ymin, ymax;
+ float zmin, zmax;
+ short flag;
+ short flag2;
+} bRotLimitConstraint;
+
+/* Limit Scaling Constraint */
+typedef struct bSizeLimitConstraint {
+ float xmin, xmax;
+ float ymin, ymax;
+ float zmin, zmax;
+ short flag;
+ short flag2;
+} bSizeLimitConstraint;
+
+/* Limit Distance Constraint */
+typedef struct bDistLimitConstraint {
+ Object *tar;
+ char subtarget[32];
+
+ float dist; /* distance (radius of clamping sphere) from target */
+ float soft; /* distance from clamping-sphere to start applying 'fade' */
+
+ short flag; /* settings */
+ short mode; /* how to limit in relation to clamping sphere */
+ int pad;
+} bDistLimitConstraint;
+
+/* ------------------------------------------ */
+
+/* bConstraint->type
+ * - Do not ever change the order of these, or else files could get
+ * broken as their correct value cannot be resolved
+ */
+typedef enum B_CONSTAINT_TYPES {
+ CONSTRAINT_TYPE_NULL = 0, /* Invalid/legacy constraint */
+ CONSTRAINT_TYPE_CHILDOF, /* Unimplemented non longer :) - during constraints recode, Aligorith */
+ CONSTRAINT_TYPE_TRACKTO,
+ CONSTRAINT_TYPE_KINEMATIC,
+ CONSTRAINT_TYPE_FOLLOWPATH,
+ CONSTRAINT_TYPE_ROTLIMIT, /* Unimplemented no longer :) - Aligorith */
+ CONSTRAINT_TYPE_LOCLIMIT, /* Unimplemented no longer :) - Aligorith */
+ CONSTRAINT_TYPE_SIZELIMIT, /* Unimplemented no longer :) - Aligorith */
+ CONSTRAINT_TYPE_ROTLIKE,
+ CONSTRAINT_TYPE_LOCLIKE,
+ CONSTRAINT_TYPE_SIZELIKE,
+ CONSTRAINT_TYPE_PYTHON, /* Unimplemented no longer :) - Aligorith. Scripts */
+ CONSTRAINT_TYPE_ACTION,
+ CONSTRAINT_TYPE_LOCKTRACK, /* New Tracking constraint that locks an axis in place - theeth */
+ CONSTRAINT_TYPE_DISTLIMIT, /* limit distance */
+ CONSTRAINT_TYPE_STRETCHTO, /* claiming this to be mine :) is in tuhopuu bjornmose */
+ CONSTRAINT_TYPE_MINMAX, /* floor constraint */
+ CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */
+ CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */
+ CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */
+
+
+ /* NOTE: everytime a new constraint is added, update this */
+ NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM
+} B_CONSTRAINT_TYPES;
+
+/* bConstraint->flag */
+/* flags 0x2 (1<<1) and 0x8 (1<<3) were used in past */
+/* flag 0x20 (1<<5) was used to indicate that a constraint was evaluated using a 'local' hack for posebones only */
+typedef enum B_CONSTRAINT_FLAG {
/* expand for UI */
-#define CONSTRAINT_EXPAND 0x01
+ CONSTRAINT_EXPAND = (1<<0),
/* pre-check for illegal object name or bone name */
-#define CONSTRAINT_DISABLE 0x04
- /* flags 0x2 and 0x8 were used in past, skip this */
- /* to indicate which Ipo should be shown, maybe for 3d access later too */
-#define CONSTRAINT_ACTIVE 0x10
- /* only for Pose, evaluates constraints in posechannel local space */
-#define CONSTRAINT_LOCAL 0x20
-
+ CONSTRAINT_DISABLE = (1<<2),
+ /* to indicate which Ipo should be shown, maybe for 3d access later too */
+ CONSTRAINT_ACTIVE = (1<<4),
+ /* to indicate that the owner's space should only be changed into ownspace, but not out of it */
+ CONSTRAINT_SPACEONCE = (1<<6),
+ /* 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)
+} B_CONSTRAINT_FLAG;
+
+/* bConstraint->ownspace/tarspace */
+typedef enum B_CONSTRAINT_SPACETYPES {
+ /* default for all - worldspace */
+ CONSTRAINT_SPACE_WORLD = 0,
+ /* for objects (relative to parent/without parent influence),
+ * for bones (along normals of bone, without parent/restpositions)
+ */
+ CONSTRAINT_SPACE_LOCAL,
+ /* for posechannels - pose space */
+ CONSTRAINT_SPACE_POSE,
+ /* for posechannels - local with parent */
+ CONSTRAINT_SPACE_PARLOCAL,
+} B_CONSTRAINT_SPACETYPES;
/* bConstraintChannel.flag */
-#define CONSTRAINT_CHANNEL_SELECT 0x01
-#define CONSTRAINT_CHANNEL_PROTECTED 0x02
+typedef enum B_CONSTRAINTCHANNEL_FLAG {
+ CONSTRAINT_CHANNEL_SELECT = (1<<0),
+ CONSTRAINT_CHANNEL_PROTECTED = (1<<1)
+} B_CONSTRAINTCHANNEL_FLAG;
+
+/* -------------------------------------- */
/**
* The flags for ROTLIKE, LOCLIKE and SIZELIKE should be kept identical
@@ -278,6 +411,7 @@ typedef struct bClampToConstraint {
#define LOCLIKE_X 0x01
#define LOCLIKE_Y 0x02
#define LOCLIKE_Z 0x04
+ /* LOCLIKE_TIP is a depreceated option... use headtail=1.0f instead */
#define LOCLIKE_TIP 0x08
#define LOCLIKE_X_INVERT 0x10
#define LOCLIKE_Y_INVERT 0x20
@@ -318,11 +452,15 @@ typedef struct bClampToConstraint {
#define PLANE_Y 0x01
#define PLANE_Z 0x02
+/* Clamp-To Constraint ->flag */
#define CLAMPTO_AUTO 0
#define CLAMPTO_X 1
#define CLAMPTO_Y 2
#define CLAMPTO_Z 3
+/* ClampTo Constraint ->flag2 */
+#define CLAMPTO_CYCLIC 1
+
/* bKinematicConstraint->flag */
#define CONSTRAINT_IK_TIP 1
#define CONSTRAINT_IK_ROT 2
@@ -330,6 +468,8 @@ typedef struct bClampToConstraint {
#define CONSTRAINT_IK_TEMP 8
#define CONSTRAINT_IK_STRETCH 16
#define CONSTRAINT_IK_POS 32
+#define CONSTRAINT_IK_SETANGLE 64
+#define CONSTRAINT_IK_GETANGLE 128
/* MinMax (floor) flags */
#define MINMAX_STICKY 0x01
@@ -348,13 +488,42 @@ typedef struct bClampToConstraint {
#define LIMIT_YROT 0x02
#define LIMIT_ZROT 0x04
+ /* not used anymore - for older Limit Location constraints only */
#define LIMIT_NOPARENT 0x01
-
+ /* for all Limit constraints - allow to be used during transform? */
+#define LIMIT_TRANSFORM 0x02
+
+/* distance limit constraint */
+ /* bDistLimitConstraint->flag */
+#define LIMITDIST_USESOFT (1<<0)
+
+ /* bDistLimitConstraint->mode */
+#define LIMITDIST_INSIDE 0
+#define LIMITDIST_OUTSIDE 1
+#define LIMITDIST_ONSURFACE 2
+
+/* python constraint -> flag */
+#define PYCON_USETARGETS 0x01
+#define PYCON_SCRIPTERROR 0x02
+
+/* ChildOf Constraint -> flag */
+#define CHILDOF_LOCX 0x001
+#define CHILDOF_LOCY 0x002
+#define CHILDOF_LOCZ 0x004
+#define CHILDOF_ROTX 0x008
+#define CHILDOF_ROTY 0x010
+#define CHILDOF_ROTZ 0x020
+#define CHILDOF_SIZEX 0x040
+#define CHILDOF_SIZEY 0x080
+#define CHILDOF_SIZEZ 0x100
+
+/* Rigid-Body Constraint */
#define CONSTRAINT_DRAW_PIVOT 0x40
/* important: these defines need to match up with PHY_DynamicTypes headerfile */
#define CONSTRAINT_RB_BALL 1
#define CONSTRAINT_RB_HINGE 2
+#define CONSTRAINT_RB_CONETWIST 4
#define CONSTRAINT_RB_VEHICLE 11
#define CONSTRAINT_RB_GENERIC6DOF 12
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 5439c65aa81..807fc2add07 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -75,7 +75,8 @@ typedef struct BevPoint {
short f1, f2;
} BevPoint;
-/* note; alfa location in struct is abused by Key system */
+/* Keyframes on IPO curves and Points on Bezier Curves/Paths are generally BezTriples */
+/* note: alfa location in struct is abused by Key system */
/* vec in BezTriple looks like this:
vec[0][0]=x location of handle 1
vec[0][1]=y location of handle 1
@@ -90,15 +91,15 @@ typedef struct BevPoint {
typedef struct BezTriple {
float vec[3][3];
float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
- short h1, h2;
- char f1, f2, f3, hide;
+ short h1, h2; /* h1, h2: the handle type of the two handles */
+ char f1, f2, f3, hide; /* f1, f2, f3: used for selection status, hide: used to indicate whether BezTriple is hidden */
} BezTriple;
/* note; alfa location in struct is abused by Key system */
typedef struct BPoint {
float vec[4];
float alfa, weight; /* alfa: tilt in 3D View, weight: used for softbody goal weight */
- short f1, hide;
+ short f1, hide; /* f1: selection status, hide: is point hidden or not */
float radius, pad; /* user-set radius per point for bevelling etc */
} BPoint;
@@ -115,9 +116,11 @@ typedef struct Nurb {
float *knotsu, *knotsv;
BPoint *bp;
BezTriple *bezt;
+
+ short tilt_interp; /* KEY_LINEAR, KEY_CARDINAL, KEY_BSPLINE */
+ short pad;
int charidx;
- int pad;
} Nurb;
typedef struct CharInfo {
@@ -190,9 +193,12 @@ typedef struct Curve {
typedef struct IpoDriver {
struct Object *ob;
short blocktype, adrcode, type, flag;
- char name[128]; /* bone or constraint(?), or python expression here */
+ char name[128]; /* bone or constraint(?), or python expression here */
} IpoDriver;
+/* temp? we store more bone names in 1 driver... */
+#define DRIVER_NAME_OFFS 32
+
typedef struct IpoCurve {
struct IpoCurve *next, *prev;
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index b9f6ab0e60b..09af11fa64b 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -64,7 +64,12 @@ typedef struct CustomData {
#define CD_ORIGINDEX 7
#define CD_NORMAL 8
#define CD_FLAGS 9
-#define CD_NUMTYPES 10
+#define CD_PROP_FLT 10
+#define CD_PROP_INT 11
+#define CD_PROP_STR 12
+#define CD_ORIGSPACE 13 /* for modifier stack face location mapping */
+#define CD_ORCO 14
+#define CD_NUMTYPES 15
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@@ -77,6 +82,12 @@ typedef struct CustomData {
#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX)
#define CD_MASK_NORMAL (1 << CD_NORMAL)
#define CD_MASK_FLAGS (1 << CD_FLAGS)
+#define CD_MASK_PROP_FLT (1 << CD_PROP_FLT)
+#define CD_MASK_PROP_INT (1 << CD_PROP_INT)
+#define CD_MASK_PROP_STR (1 << CD_PROP_STR)
+#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
+#define CD_MASK_ORCO (1 << CD_ORCO)
+
/* CustomData.flag */
diff --git a/source/blender/makesdna/DNA_group_types.h b/source/blender/makesdna/DNA_group_types.h
index 34764fac47d..3a074dd63bc 100644
--- a/source/blender/makesdna/DNA_group_types.h
+++ b/source/blender/makesdna/DNA_group_types.h
@@ -52,6 +52,10 @@ typedef struct Group {
ID id;
ListBase gobject; /* GroupObject */
+
+ /* Bad design, since layers stored in the scenes 'Base'
+ * the objects that show in the group can change depending
+ * on the last used scene */
unsigned int layer;
int pad;
} Group;
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index a18493ea189..ef79f2e941f 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -41,11 +41,6 @@ struct anim;
struct ImBuf;
struct RenderResult;
-typedef struct PreviewImage {
- unsigned int w;
- unsigned int h;
- unsigned int * rect;
-} PreviewImage;
/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
/* should be used in conjunction with an ID * to Image. */
@@ -63,11 +58,12 @@ typedef struct ImageUser {
/* iuser->flag */
#define IMA_ANIM_ALWAYS 1
#define IMA_ANIM_REFRESHED 2
+/* #define IMA_DO_PREMUL 4 */
typedef struct Image {
ID id;
- char name[240];
+ char name[240]; /* file path */
ListBase ibufs; /* not written in file */
@@ -95,6 +91,9 @@ typedef struct Image {
short gen_x, gen_y, gen_type; /* for generated images */
+ /* display aspect - for UV editing images resized for faster openGL display */
+ float aspx, aspy;
+
/*#ifdef WITH_VERSE*/
void *vnode; /* pointer at verse bitmap node */
/*#endif*/
@@ -106,11 +105,12 @@ typedef struct Image {
/* flag */
#define IMA_FIELDS 1
#define IMA_STD_FIELD 2
+#define IMA_DO_PREMUL 4
#define IMA_REFLECT 16
#define IMA_NOCOLLECT 32
#define IMA_ANTIALI 64
-
+#define IMA_OLD_PREMUL 128
/* tpageflag */
#define IMA_TILES 1
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index 441a3fc43fc..8ec412a3534 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -39,18 +39,20 @@
#include "DNA_ID.h"
+/* IPO Data-Block */
typedef struct Ipo {
ID id;
- ListBase curve;
- rctf cur;
- short blocktype, showkey;
- int pad;
-
+ ListBase curve; /* A list of IpoCurve structs in a linked list. */
+ rctf cur; /* Rect defining extents of keyframes? */
+
+ short blocktype, showkey; /* blocktype: self-explanatory; showkey: either 0 or 1 (show vertical yellow lines for editing) */
+ short muteipo, pad; /* muteipo: either 0 or 1 (whether ipo block is muted) */
} Ipo;
-/* sometimes used */
+/* NOTE: IpoCurve struct is defined in DNA_curve_types.h, not in here... */
+/* sometimes used */
typedef short IPO_Channel;
/* defines: are these duped or new? */
@@ -67,8 +69,8 @@ typedef short IPO_Channel;
/* ******************** */
-#define OB_TOTIPO 29
-#define OB_TOTNAM 29
+#define OB_TOTIPO 30
+#define OB_TOTNAM 30
#define OB_LOC_X 1
#define OB_LOC_Y 2
@@ -105,7 +107,10 @@ typedef short IPO_Channel;
#define OB_PD_SDAMP 27
#define OB_PD_RDAMP 28
#define OB_PD_PERM 29
+#define OB_PD_FMAXD 30
+/* exception: driver channel, for bone driver only */
+#define OB_ROT_DIFF 100
/* ******************** */
@@ -315,10 +320,11 @@ typedef short IPO_Channel;
#define AC_QUAT_Z 28
/* ******************** */
-#define CO_TOTIPO 1 /* Constraint Ipos */
-#define CO_TOTNAM 1
+#define CO_TOTIPO 2 /* Constraint Ipos */
+#define CO_TOTNAM 2
#define CO_ENFORCE 1
+#define CO_HEADTAIL 2
/*
#define CO_TIME 2
#define CO_OFFSET_X 3
@@ -349,6 +355,35 @@ typedef short IPO_Channel;
#define FLUIDSIM_ACTIVE 9
+/* ******************** */
+/* particle ipos */
+#define PART_TOTIPO 19
+#define PART_TOTNAM 19
+
+#define PART_EMIT_FREQ 1
+#define PART_EMIT_LIFE 2
+#define PART_EMIT_VEL 3
+#define PART_EMIT_AVE 4
+#define PART_EMIT_SIZE 5
+
+#define PART_AVE 6
+#define PART_SIZE 7
+#define PART_DRAG 8
+#define PART_BROWN 9
+#define PART_DAMP 10
+#define PART_LENGTH 11
+#define PART_CLUMP 12
+
+#define PART_GRAV_X 13
+#define PART_GRAV_Y 14
+#define PART_GRAV_Z 15
+
+#define PART_KINK_AMP 16
+#define PART_KINK_FREQ 17
+#define PART_KINK_SHAPE 18
+
+#define PART_BB_TILT 19
+
/* these are IpoCurve specific */
/* **************** IPO ********************* */
@@ -391,6 +426,9 @@ typedef short IPO_Channel;
#define IPO_AUTO_HORIZ 16
#define IPO_ACTIVE 32
#define IPO_PROTECT 64
+#define IPO_MUTE 128
#endif
+
+
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index 3292e07f80e..87c09fb0ee4 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -44,8 +44,8 @@ typedef struct KeyBlock {
float pos;
float curval;
- short type, adrcode;
- int totelem;
+ short type, adrcode, relative, flag; /* relative == 0 means first key is reference */
+ int totelem, pad2;
void *data;
float *weights;
@@ -87,5 +87,8 @@ typedef struct Key {
#define KEY_CARDINAL 1
#define KEY_BSPLINE 2
+/* keyblock->flag */
+#define KEYBLOCK_MUTE 1
+
#endif
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index 22696c48878..f8cc2378cb1 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -43,6 +43,7 @@
struct MTex;
struct Ipo;
+struct CurveMapping;
typedef struct Lamp {
ID id;
@@ -54,16 +55,26 @@ typedef struct Lamp {
float energy, dist, spotsize, spotblend;
float haint;
- float att1, att2;
+
+
+ float att1, att2; /* Quad1 and Quad2 attenuation */
+ int pad2;
+ struct CurveMapping *curfalloff;
+ short falloff_type;
+ short pad3;
float clipsta, clipend, shadspotsize;
float bias, soft;
short bufsize, samp, buffers, filtertype;
char bufflag, buftype;
- short ray_samp, ray_sampy, ray_sampz, ray_samp_type;
+ short ray_samp, ray_sampy, ray_sampz;
+ short ray_samp_type;
short area_shape;
float area_size, area_sizey, area_sizez;
+ float adapt_thresh;
+ short ray_samp_method;
+ short pad1;
/* texact is for buttons */
short texact, shadhalostep;
@@ -79,6 +90,9 @@ typedef struct Lamp {
struct MTex *mtex[10];
struct Ipo *ipo;
+ /* preview */
+ struct PreviewImage *preview;
+
ScriptLink scriptlink;
} Lamp;
@@ -97,7 +111,7 @@ typedef struct Lamp {
#define LA_SHAD_BUF 1
#define LA_HALO 2
#define LA_LAYER 4
-#define LA_QUAD 8
+#define LA_QUAD 8 /* no longer used */
#define LA_NEG 16
#define LA_ONLYSHADOW 32
#define LA_SPHERE 64
@@ -112,6 +126,14 @@ typedef struct Lamp {
/* Since it is used with LOCAL lamp, can't use LA_SHAD */
#define LA_YF_SOFT 16384
+/* falloff_type */
+#define LA_FALLOFF_CONSTANT 0
+#define LA_FALLOFF_INVLINEAR 1
+#define LA_FALLOFF_INVSQUARE 2
+#define LA_FALLOFF_CURVE 3
+#define LA_FALLOFF_SLIDERS 4
+
+
/* buftype, no flag */
#define LA_SHADBUF_REGULAR 0
#define LA_SHADBUF_IRREGULAR 1
@@ -132,6 +154,12 @@ typedef struct Lamp {
#define LA_AREA_CUBE 2
#define LA_AREA_BOX 3
+/* ray_samp_method */
+#define LA_SAMP_CONSTANT 0
+#define LA_SAMP_HALTON 1
+#define LA_SAMP_HAMMERSLEY 2
+
+
/* ray_samp_type */
#define LA_SAMP_ROUND 1
#define LA_SAMP_UMBRA 2
diff --git a/source/blender/makesdna/DNA_listBase.h b/source/blender/makesdna/DNA_listBase.h
index 10a1b59fb01..e81cb886d6f 100644
--- a/source/blender/makesdna/DNA_listBase.h
+++ b/source/blender/makesdna/DNA_listBase.h
@@ -43,11 +43,20 @@
extern "C" {
#endif
+/* generic - all structs which are used in linked-lists used this */
typedef struct Link
{
struct Link *next,*prev;
} Link;
+
+/* use this when it is not worth defining a custom one... */
+typedef struct LinkData
+{
+ struct LinkData *next, *prev;
+ void *data;
+} LinkData;
+
/* never change the size of this! genfile.c detects pointerlen with it */
typedef struct ListBase
{
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 0fad110d64b..a4c6120374a 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -73,13 +73,25 @@ typedef struct Material {
short har;
char seed1, seed2;
+ float gloss_mir, gloss_tra;
+ short samp_gloss_mir, samp_gloss_tra;
+ float adapt_thresh_mir, adapt_thresh_tra;
+ float aniso_gloss_mir;
+ float dist_mir;
+ short fadeto_mir;
+ short shade_flag; /* like Cubic interpolation */
+
int mode, mode_l; /* mode_l is the or-ed result of all layer modes */
short flarec, starc, linec, ringc;
float hasize, flaresize, subsize, flareboost;
- float strand_sta, strand_end, strand_ease;
+ float strand_sta, strand_end, strand_ease, strand_surfnor;
+ float strand_min, strand_widthfade;
+ char strand_uvname[32];
- float sbias; /* shadow bias */
- float shad_alpha, padf; /* in use for irregular shadowbuffer */
+ float sbias; /* shadow bias to prevent terminator prob */
+ float lbias; /* factor to multiply lampbias with (0.0 = no mult) */
+ float shad_alpha; /* in use for irregular shadowbuffer */
+ float padf; /* free padding, take me! */
/* for buttons and render*/
char rgbsel, texact, pr_type, use_nodes;
@@ -105,12 +117,14 @@ typedef struct Material {
struct bNodeTree *nodetree;
struct Ipo *ipo;
struct Group *group; /* light group */
-
+ struct PreviewImage * preview;
+
/* dynamic properties */
float friction, fh, reflect;
float fhdist, xyfrict;
short dynamode, pad2;
+ /* subsurface scattering */
float sss_radius[3], sss_col[3];
float sss_error, sss_scale, sss_ior;
float sss_colfac, sss_texfac;
@@ -179,8 +193,18 @@ typedef struct Material {
/* qdn: a bit clumsy this, tangents needed for normal maps separated from shading */
#define MA_NORMAP_TANG 0x8000000
#define MA_GROUP_NOLAY 0x10000000
+#define MA_FACETEXTURE_ALPHA 0x20000000
+#define MA_STR_B_UNITS 0x40000000
+#define MA_STR_SURFDIFF 0x80000000
+
+#define MA_MODE_MASK 0x6fffffff /* all valid mode bits */
-#define MA_MODE_MASK 0x1fffffff /* all valid mode bits */
+/* ray mirror fadeout */
+#define MA_RAYMIR_FADETOSKY 0
+#define MA_RAYMIR_FADETOMAT 1
+
+/* shade_flag */
+#define MA_CUBIC 1
/* diff_shader */
#define MA_DIFF_LAMBERT 0
@@ -260,6 +284,31 @@ typedef struct Material {
#define MAP_WARP 8192
#define MAP_LAYER 16384
+/* mapto for halo */
+//#define MAP_HA_COL 1
+//#define MAP_HA_ALPHA 128
+//#define MAP_HA_HAR 256
+//#define MAP_HA_SIZE 2
+//#define MAP_HA_ADD 64
+
+/* pmapto */
+/* init */
+#define MAP_PA_INIT 31
+#define MAP_PA_TIME 1
+#define MAP_PA_LIFE 2
+#define MAP_PA_DENS 4
+#define MAP_PA_SIZE 8
+#define MAP_PA_LENGTH 16
+/* reset */
+#define MAP_PA_IVEL 32
+/* physics */
+#define MAP_PA_PVEL 64
+/* path cache */
+#define MAP_PA_CACHE 912
+#define MAP_PA_CLUMP 128
+#define MAP_PA_KINK 256
+#define MAP_PA_ROUGH 512
+
/* pr_type */
#define MA_FLAT 0
#define MA_SPHERE 1
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 5f2a77b8349..59f3a64ba5e 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -61,23 +61,27 @@ typedef struct Mesh {
struct Key *key;
struct Material **mat;
- struct MFace *mface;
- struct MTFace *mtface;
+ struct MFace *mface; /* array of mesh object mode faces */
+ struct MTFace *mtface; /* store face UV's and texture here */
struct TFace *tface; /* depecrated, use mtface */
- struct MVert *mvert;
- struct MEdge *medge;
+ struct MVert *mvert; /* array of verts */
+ struct MEdge *medge; /* array of edges */
struct MDeformVert *dvert; /* __NLA */
- struct MCol *mcol;
+ struct MCol *mcol; /* array of colors, this must be the number of faces * 4 */
struct MSticky *msticky;
struct Mesh *texcomesh;
struct MSelect *mselect;
-
- struct OcInfo *oc; /* not written in file */
- void *sumohandle;
struct CustomData vdata, edata, fdata;
- int totvert, totedge, totface, totselect, pad2;
+ int totvert, totedge, totface, totselect;
+
+ /* the last selected vertex/edge/face are used for the active face however
+ * this means the active face must always be selected, this is to keep track
+ * of the last selected face and is similar to the old active face flag where
+ * the face does not need to be selected, -1 is inactive */
+ int act_face;
+
int texflag;
/* texture space, copied as one block in editobject.c */
@@ -91,7 +95,7 @@ typedef struct Mesh {
short subdiv, subdivr;
short totcol;
- short subsurftype;
+ short subsurftype; /* only kept for backwards compat, not used anymore */
struct Multires *mr; /* Multiresolution modeling data */
struct PartialVisibility *pv;
@@ -103,7 +107,7 @@ typedef struct Mesh {
/* deprecated by MTFace, only here for file reading */
typedef struct TFace {
- void *tpage;
+ void *tpage; /* the faces image for the active UVLayer */
float uv[4][2];
unsigned int col[4];
char flag, transp;
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index af9c1ae629d..7970ccd073c 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -45,7 +45,7 @@ typedef struct MFace {
typedef struct MEdge {
unsigned int v1, v2;
- char crease, pad;
+ char crease, bweight;
short flag;
} MEdge;
@@ -63,11 +63,13 @@ typedef struct MDeformVert {
typedef struct MVert {
float co[3];
short no[3];
- char flag, mat_nr;
+ char flag, mat_nr, bweight, pad[3];
} MVert;
+/* at the moment alpha is abused for vertex painting
+ * and not used for transperency, note that red and blue are swapped */
typedef struct MCol {
- char a, r, g, b;
+ char a, r, g, b;
} MCol;
typedef struct MSticky {
@@ -86,6 +88,21 @@ typedef struct MTFace {
short mode, tile, unwrap;
} MTFace;
+/*Custom Data Properties*/
+typedef struct MFloatProperty{
+ float f;
+} MFloatProperty;
+typedef struct MIntProperty{
+ int i;
+} MIntProperty;
+typedef struct MStringProperty{
+ char s[256];
+} MStringProperty;
+
+typedef struct OrigSpaceFace {
+ float uv[4][2];
+} OrigSpaceFace;
+
/* Multiresolution modeling */
typedef struct MultiresCol {
float a, r, g, b;
@@ -97,7 +114,6 @@ typedef struct MultiresColFace {
typedef struct MultiresFace {
unsigned int v[4];
unsigned int mid;
- unsigned int childrenstart;
char flag, mat_nr, pad[2];
} MultiresFace;
typedef struct MultiresEdge {
@@ -112,6 +128,9 @@ typedef struct MultiresLevel {
MultiresFace *faces;
MultiresColFace *colfaces;
MultiresEdge *edges;
+
+ /* Temporary connectivity data */
+ char *edge_boundary_states;
struct ListBase *vert_edge_map;
struct ListBase *vert_face_map;
struct MultiresMapNode *map_mem;
@@ -127,7 +146,7 @@ typedef struct Multires {
MVert *verts;
unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl;
- unsigned char use_col, pad;
+ unsigned char use_col, flag;
/* Special level 1 data that cannot be modified from other levels */
CustomData vdata;
@@ -188,7 +207,7 @@ typedef struct PartialVisibility {
/* mtface->flag */
#define TF_SELECT 1 /* use MFace hide flag (after 2.43), should be able to reuse after 2.44 */
-#define TF_ACTIVE 2
+#define TF_ACTIVE 2 /* deprecated! */
#define TF_SEL1 4
#define TF_SEL2 8
#define TF_SEL3 16
@@ -217,6 +236,8 @@ typedef struct PartialVisibility {
#define TF_SOLID 0
#define TF_ADD 1
#define TF_ALPHA 2
+
+/* sub is not available in the user interface anymore */
#define TF_SUB 3
/* mtface->unwrap */
@@ -229,4 +250,7 @@ typedef struct PartialVisibility {
#define TF_PIN3 64
#define TF_PIN4 128
+/* multires->flag */
+#define MULTIRES_NO_RENDER 1
+
#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 2d296ad10fa..dd1d8eb01b3 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -28,6 +28,13 @@ typedef enum ModifierType {
eModifierType_UVProject,
eModifierType_Smooth,
eModifierType_Cast,
+ eModifierType_MeshDeform,
+ eModifierType_ParticleSystem,
+ eModifierType_ParticleInstance,
+ eModifierType_Explode,
+ eModifierType_Cloth,
+ eModifierType_Collision,
+ eModifierType_Bevel,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -38,6 +45,7 @@ typedef enum ModifierMode {
eModifierMode_OnCage = (1<<3),
eModifierMode_Expanded = (1<<4),
eModifierMode_Virtual = (1<<5),
+ eModifierMode_DisableTemporary = (1 << 31)
} ModifierMode;
typedef struct ModifierData {
@@ -158,6 +166,7 @@ typedef struct MirrorModifierData {
short axis, flag;
float tolerance;
+ struct Object *mirror_ob;
} MirrorModifierData;
/* MirrorModifierData->flag */
@@ -179,6 +188,27 @@ typedef struct EdgeSplitModifierData {
#define MOD_EDGESPLIT_FROMANGLE 1<<1
#define MOD_EDGESPLIT_FROMFLAG 1<<2
+typedef struct BevelModifierData {
+ ModifierData modifier;
+
+ float value; /* the "raw" bevel value (distance/amount to bevel) */
+ int res; /* the resolution (as originally coded, it is the number of recursive bevels) */
+ int pad;
+ short flags; /* general option flags */
+ short val_flags; /* flags used to interpret the bevel value */
+ short lim_flags; /* flags to tell the tool how to limit the bevel */
+ short e_flags; /* flags to direct how edge weights are applied to verts */
+ float bevel_angle; /* if the BME_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */
+ char defgrp_name[32]; /* if the BME_BEVEL_VWEIGHT option is set, this will be the name of the vert group */
+} BevelModifierData;
+
+typedef struct BMeshModifierData {
+ ModifierData modifier;
+
+ float pad;
+ int type;
+} BMeshModifierData;
+
typedef struct DisplaceModifierData {
ModifierData modifier;
@@ -310,9 +340,10 @@ typedef struct WaveModifierData {
typedef struct ArmatureModifierData {
ModifierData modifier;
- short deformflag, pad1; /* deformflag replaces armature->deformflag */
+ short deformflag, multi; /* deformflag replaces armature->deformflag */
int pad2;
struct Object *object;
+ float *prevCos; /* stored input of previous modifier, for vertexgroup blending */
char defgrp_name[32];
} ArmatureModifierData;
@@ -334,6 +365,33 @@ typedef struct SoftbodyModifierData {
ModifierData modifier;
} SoftbodyModifierData;
+typedef struct ClothModifierData {
+ ModifierData modifier;
+
+ struct Cloth *clothObject; /* The internal data structure for cloth. */
+ struct SimulationSettings *sim_parms; /* definition is in DNA_cloth_types.h */
+ struct CollisionSettings *coll_parms; /* definition is in DNA_cloth_types.h */
+} ClothModifierData;
+
+typedef struct CollisionModifierData {
+ ModifierData modifier;
+
+ struct MVert *x; /* position at the beginning of the frame */
+ struct MVert *xnew; /* position at the end of the frame */
+ struct MVert *xold; /* unsued atm, but was discussed during sprint */
+ struct MVert *current_xnew; /* new position at the actual inter-frame step */
+ struct MVert *current_x; /* position at the actual inter-frame step */
+ struct MVert *current_v; /* position at the actual inter-frame step */
+
+ struct MFace *mfaces; /* object face data */
+
+ unsigned int numverts;
+ unsigned int numfaces;
+ int pad;
+ float time;
+ struct BVH *tree; /* collision tree for this cloth object */
+} CollisionModifierData;
+
typedef enum {
eBooleanModifierOp_Intersect,
eBooleanModifierOp_Union,
@@ -346,4 +404,87 @@ typedef struct BooleanModifierData {
int operation, pad;
} BooleanModifierData;
+#define MOD_MDEF_INVERT_VGROUP (1<<0)
+#define MOD_MDEF_DYNAMIC_BIND (1<<1)
+
+typedef struct MDefInfluence {
+ int vertex;
+ float weight;
+} MDefInfluence;
+
+typedef struct MDefCell {
+ int offset;
+ int totinfluence;
+} MDefCell;
+
+typedef struct MeshDeformModifierData {
+ ModifierData modifier;
+
+ struct Object *object; /* mesh object */
+ char defgrp_name[32]; /* optional vertexgroup name */
+
+ short gridsize, needbind;
+ short flag, pad;
+
+ /* variables filled in when bound */
+ float *bindweights, *bindcos; /* computed binding weights */
+ int totvert, totcagevert; /* total vertices in mesh and cage */
+ MDefCell *dyngrid; /* grid with dynamic binding cell points */
+ MDefInfluence *dyninfluences; /* dynamic binding vertex influences */
+ int *dynverts, *pad2; /* is this vertex bound or not? */
+ int dyngridsize; /* size of the dynamic bind grid */
+ int totinfluence; /* total number of vertex influences */
+ float dyncellmin[3]; /* offset of the dynamic bind grid */
+ float dyncellwidth; /* width of dynamic bind cell */
+ float bindmat[4][4]; /* matrix of cage at binding time */
+} MeshDeformModifierData;
+
+typedef enum {
+ eParticleSystemFlag_Loaded = (1<<0),
+ eParticleSystemFlag_Pars = (1<<1),
+ eParticleSystemFlag_FromCurve = (1<<2),
+ eParticleSystemFlag_DM_changed = (1<<3),
+ eParticleSystemFlag_Disabled = (1<<4),
+ eParticleSystemFlag_psys_updated = (1<<5),
+} ParticleSystemModifierFlag;
+
+typedef struct ParticleSystemModifierData {
+ ModifierData modifier;
+ struct ParticleSystem *psys;
+ struct DerivedMesh *dm;
+ int totdmvert, totdmedge, totdmface;
+ short flag, rt;
+} ParticleSystemModifierData;
+
+typedef enum {
+ eParticleInstanceFlag_Parents = (1<<0),
+ eParticleInstanceFlag_Children = (1<<1),
+ eParticleInstanceFlag_Path = (1<<2),
+ eParticleInstanceFlag_Unborn = (1<<3),
+ eParticleInstanceFlag_Alive = (1<<4),
+ eParticleInstanceFlag_Dead = (1<<5),
+} ParticleInstanceModifierFlag;
+
+typedef struct ParticleInstanceModifierData {
+ ModifierData modifier;
+ struct Object *ob;
+ short psys, flag, rt[2];
+} ParticleInstanceModifierData;
+
+typedef enum {
+ eExplodeFlag_CalcFaces = (1<<0),
+ //eExplodeFlag_PaSize = (1<<1),
+ eExplodeFlag_EdgeSplit = (1<<2),
+ eExplodeFlag_Unborn = (1<<3),
+ eExplodeFlag_Alive = (1<<4),
+ eExplodeFlag_Dead = (1<<5),
+} ExplodeModifierFlag;
+
+typedef struct ExplodeModifierData {
+ ModifierData modifier;
+ int *facepa;
+ short flag, vgroup;
+ float protect;
+} ExplodeModifierData;
+
#endif
diff --git a/source/blender/makesdna/DNA_nla_types.h b/source/blender/makesdna/DNA_nla_types.h
index 914e6337474..e9a0a3d0602 100644
--- a/source/blender/makesdna/DNA_nla_types.h
+++ b/source/blender/makesdna/DNA_nla_types.h
@@ -54,6 +54,7 @@ typedef struct bActionModifier {
struct Object *ob;
} bActionModifier;
+/* NLA-Modifier Types */
#define ACTSTRIP_MOD_DEFORM 0
#define ACTSTRIP_MOD_NOISE 1
#define ACTSTRIP_MOD_OOMPH 2
@@ -64,40 +65,43 @@ typedef struct bActionStrip {
short stride_axis; /* axis 0=x, 1=y, 2=z */
short curmod; /* current modifier for buttons */
- struct Ipo *ipo; /* Blending ipo */
+ struct Ipo *ipo; /* Blending ipo - was used for some old NAN era experiments. Non-functional currently. */
struct bAction *act; /* The action referenced by this strip */
struct Object *object; /* For groups, the actual object being nla'ed */
float start, end; /* The range of frames covered by this strip */
float actstart, actend; /* The range of frames taken from the action */
- float actoffs, padf; /* Offset within action, for cycles and striding */
+ float actoffs; /* Offset within action, for cycles and striding */
float stridelen; /* The stridelength (considered when flag & ACT_USESTRIDE) */
float repeat; /* The number of times to repeat the action range */
+ float scale; /* The amount the action range is scaled by */
- float blendin, blendout;
+ float blendin, blendout; /* The number of frames on either end of the strip's length to fade in/out */
char stridechannel[32]; /* Instead of stridelen, it uses an action channel */
char offs_bone[32]; /* if repeat, use this bone/channel for defining offset */
- struct ListBase modifiers; /* modifier stack */
-
+ ListBase modifiers; /* modifier stack */
} bActionStrip;
+/* strip->mode (these defines aren't really used, but are here for reference) */
#define ACTSTRIPMODE_BLEND 0
#define ACTSTRIPMODE_ADD 1
/* strip->flag */
-#define ACTSTRIP_SELECT 0x01
-#define ACTSTRIP_USESTRIDE 0x02
-#define ACTSTRIP_BLENDTONEXT 0x04
-#define ACTSTRIP_HOLDLASTFRAME 0x08
-#define ACTSTRIP_ACTIVE 0x10
-#define ACTSTRIP_LOCK_ACTION 0x20
-#define ACTSTRIP_MUTE 0x40
-#define ACTSTRIP_REVERSE 0x80
-#define ACTSTRIP_CYCLIC_USEX 0x100
-#define ACTSTRIP_CYCLIC_USEY 0x200
-#define ACTSTRIP_CYCLIC_USEZ 0x400
-#define ACTSTRIP_AUTO_BLENDS 0x800
+typedef enum eActStrip_Flag {
+ ACTSTRIP_SELECT = (1<<0),
+ ACTSTRIP_USESTRIDE = (1<<1),
+ ACTSTRIP_BLENDTONEXT = (1<<2), /* Not implemented. Is not used anywhere */
+ ACTSTRIP_HOLDLASTFRAME = (1<<3),
+ ACTSTRIP_ACTIVE = (1<<4),
+ ACTSTRIP_LOCK_ACTION = (1<<5),
+ ACTSTRIP_MUTE = (1<<6),
+ ACTSTRIP_REVERSE = (1<<7), /* This has yet to be implemented. To indicate that a strip should be played backwards */
+ ACTSTRIP_CYCLIC_USEX = (1<<8),
+ ACTSTRIP_CYCLIC_USEY = (1<<9),
+ ACTSTRIP_CYCLIC_USEZ = (1<<10),
+ ACTSTRIP_AUTO_BLENDS = (1<<11)
+} eActStrip_Flag;
#endif
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 63ead419766..f74e858c0e4 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -58,7 +58,7 @@ typedef struct bNodeStack {
#define NS_OSA_VALUES 2
typedef struct bNodeSocket {
- struct bNodeSocket *next, *prev;
+ struct bNodeSocket *next, *prev, *new_sock;
char name[32];
bNodeStack ns; /* custom data for inputs, only UI writes in this */
@@ -92,7 +92,8 @@ typedef struct bNodeSocket {
#define SOCK_IN_USE 4
/* unavailable is for dynamic sockets */
#define SOCK_UNAVAIL 8
-
+ /* flag for selection status */
+#define SOCK_SEL 16
#
#
typedef struct bNodePreview {
@@ -106,6 +107,7 @@ typedef struct bNode {
struct bNode *next, *prev, *new_node;
char name[32];
+ char username[32]; /* custom name defined by user */
short type, flag;
short done, level; /* both for dependency and sorting */
short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */
@@ -142,6 +144,8 @@ typedef struct bNode {
#define NODE_GROUP_EDIT 128
/* free test flag, undefined */
#define NODE_TEST 256
+ /* composite: don't do node but pass on buffer(s) */
+#define NODE_MUTED 512
typedef struct bNodeLink {
struct bNodeLink *next, *prev;
@@ -167,6 +171,10 @@ typedef struct bNodeTree {
ListBase alltypes; /* type definitions */
struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */
+ /* selected input/output socket */
+ bNodeSocket *selin;
+ bNodeSocket *selout;
+
/* callbacks */
void (*timecursor)(int nr);
void (*stats_draw)(char *str);
@@ -191,13 +199,27 @@ typedef struct NodeImageAnim {
} NodeImageAnim;
typedef struct NodeBlurData {
- short sizex, sizey, samples, maxspeed, minspeed, pad1;
- float fac;
+ short sizex, sizey;
+ short samples, maxspeed, minspeed, relative;
+ float fac, percentx, percenty;
short filtertype;
char bokeh, gamma;
- int pad2;
+ short curved;
+ short pad;
+ int image_in_width, image_in_height; /* needed for absolute/relative conversions */
} NodeBlurData;
+typedef struct NodeDBlurData {
+ float center_x, center_y, distance, angle, spin, zoom;
+ short iter;
+ char wrap, pad;
+} NodeDBlurData;
+
+typedef struct NodeBilateralBlurData {
+ float sigma_color, sigma_space;
+ short iter, pad;
+} NodeBilateralBlurData;
+
typedef struct NodeHueSat {
float hue, sat, val;
} NodeHueSat;
@@ -214,6 +236,14 @@ typedef struct NodeChroma {
float key[4];
} NodeChroma;
+typedef struct NodeTwoXYs {
+ short x1, x2, y1, y2;
+} NodeTwoXYs;
+
+typedef struct NodeTwoFloats {
+ float x, y;
+} NodeTwoFloats;
+
typedef struct NodeGeometry {
char uvname[32];
char colname[32];
@@ -230,4 +260,28 @@ typedef struct NodeDefocus {
float fstop, maxblur, bthresh, scale;
} NodeDefocus;
+typedef struct NodeScriptDict {
+ void *dict; /* for PyObject *dict */
+ void *node; /* for BPy_Node *node */
+} NodeScriptDict;
+
+/* qdn: glare node */
+typedef struct NodeGlare {
+ char quality, type, iter;
+ char angle, angle_ofs, size, pad[2];
+ float colmod, mix, threshold, fade;
+} NodeGlare;
+
+/* qdn: tonemap node */
+typedef struct NodeTonemap {
+ float key, offset, gamma;
+ float f, m, a, c;
+ int type;
+} NodeTonemap;
+
+/* qdn: lens distortion node */
+typedef struct NodeLensDist {
+ short jit, proj, fit, pad;
+} NodeLensDist;
+
#endif
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index a821e209ef0..cdee50cfef4 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -41,19 +41,35 @@ 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 pad;
+ short falloff; /* fall-off type*/
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 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 */
+ 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 */
} PartDeflect;
@@ -62,6 +78,8 @@ typedef struct SBVertex {
} SBVertex;
typedef struct SoftBody {
+ struct ParticleSystem *particles; /* particlesystem softbody */
+
/* dynamic data */
int totpoint, totspring;
struct BodyPoint *bpoint; /* not saved in file */
@@ -96,8 +114,10 @@ typedef struct SoftBody {
int interval;
short local, solverflags; /* local==1: use local coords for baking */
+ /* -- these must be kept for backwards compatibility -- */
SBVertex **keys; /* array of size totpointkey */
int totpointkey, totkey; /* if totpointkey != totpoint or totkey!- (efra-sfra)/interval -> free keys */
+ /* ---------------------------------------------------- */
float secondspring;
/* self collision*/
@@ -109,10 +129,13 @@ typedef struct SoftBody {
minloops,
maxloops,
choke,
- pad3,pad4,pad5
+ solver_ID,
+ plastic,pad5
;
struct SBScratch *scratch; /* scratch pad/cache on live time not saved in file */
+ float shearstiff;
+ float inpush;
} SoftBody;
@@ -122,11 +145,37 @@ typedef struct SoftBody {
#define PFIELD_MAGNET 3
#define PFIELD_WIND 4
#define PFIELD_GUIDE 5
+#define PFIELD_TEXTURE 6
+#define PFIELD_HARMONIC 7
+#define PFIELD_NUCLEAR 8
+#define PFIELD_MDIPOLE 9
+
/* pd->flag: various settings */
#define PFIELD_USEMAX 1
#define PDEFLE_DEFORM 2
#define PFIELD_GUIDE_PATH_ADD 4
+#define PFIELD_PLANAR 8
+#define PDEFLE_KILL_PART 16
+#define PFIELD_POSZ 32
+#define PFIELD_TEX_OBJECT 64
+#define PFIELD_TEX_2D 128
+#define PFIELD_USEMIN 256
+#define PFIELD_USEMAXR 512
+#define PFIELD_USEMINR 1024
+#define PFIELD_TEX_ROOTCO 2048
+
+/* 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->tex_mode */
+#define PFIELD_TEX_RGB 0
+#define PFIELD_TEX_GRAD 1
+#define PFIELD_TEX_CURL 2
/* ob->softflag */
#define OB_SB_ENABLE 1
@@ -142,10 +191,20 @@ typedef struct SoftBody {
#define OB_SB_FACECOLL 1024
#define OB_SB_EDGECOLL 2048
#define OB_SB_COLLFINAL 4096
+#define OB_SB_PROTECT_CACHE 8192
+#define OB_SB_AERO_ANGLE 16384
+/* sb->solverflags */
#define SBSO_MONITOR 1
#define SBSO_OLDERR 2
+/* sb->sbc_mode */
+#define SBC_MODE_MANUAL 0
+#define SBC_MODE_AVG 1
+#define SBC_MODE_MIN 2
+#define SBC_MODE_MAX 3
+#define SBC_MODE_AVGMINMAX 4
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 228b9bcc90e..f3a0dfdfdc7 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -54,6 +54,7 @@ struct bConstraintChannel;
struct PartDeflect;
struct SoftBody;
struct FluidsimSettings;
+struct ParticleSystem;
struct DerivedMesh;
typedef struct bDeformGroup {
@@ -69,20 +70,6 @@ typedef struct BoundBox {
/* boundbox flag */
#define OB_BB_DISABLED 1
-/* OcInfo and LBuf structs are for the Enji gameengine */
-
-typedef struct OcInfo {
- float dvec[3];
- float size[3];
-} OcInfo;
-
-typedef struct LBuf {
- short tot, max;
- int pad;
- struct Object **ob;
-} LBuf;
-
-
typedef struct Object {
ID id;
@@ -97,12 +84,12 @@ typedef struct Object {
struct Path *path;
struct BoundBox *bb;
struct bAction *action;
+ struct bAction *poselib;
struct bPose *pose;
void *data;
ListBase constraintChannels;
ListBase effect;
- ListBase network;
ListBase disp;
ListBase defbase;
ListBase modifiers; /* list of ModifierData structures */
@@ -115,7 +102,8 @@ typedef struct Object {
float rot[3], drot[3];
float quat[4], dquat[4];
float obmat[4][4];
- float parentinv[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 */
float imat[4][4]; /* for during render, old game engine, temporally: ipokeys of transform */
unsigned int lay; /* copy of Base */
@@ -131,7 +119,7 @@ typedef struct Object {
int dupon, dupoff, dupsta, dupend;
- float sf, ctime;
+ float sf, ctime; /* sf is time-offset, ctime is the objects current time */
/* during realtime */
@@ -153,9 +141,10 @@ typedef struct Object {
char dt, dtx;
char totcol; /* copy of mesh or curve or meta */
- char actcol;
- char empty_drawtype, pad1[7];
+ char actcol; /* currently selected material in the user interface */
+ char empty_drawtype, pad1[3];
float empty_drawsize;
+ float dupfacesca; /* dupliface scale */
ScriptLink scriptlink;
ListBase prop;
@@ -163,12 +152,14 @@ typedef struct Object {
ListBase controllers;
ListBase actuators;
- void *sumohandle;
+ /* now used to store cache particles,
+ * should be renamed see effect.c (Campbell) */
+ void *sumohandle;
float bbsize[3];
short index; /* custom index, for renderpasses */
unsigned short actdef; /* current deformation group */
- float col[4];
+ float col[4]; /* object color, adjusted via IPO's only */
/**
* Settings for game objects
* bit 0: Object has dynamic behaviour
@@ -193,6 +184,7 @@ typedef struct Object {
ListBase constraints;
ListBase nlastrips;
ListBase hooks;
+ ListBase particlesystem; /* particle systems */
struct PartDeflect *pd; /* particle deflector/attractor/collision data */
struct SoftBody *soft; /* if exists, saved in file */
@@ -204,10 +196,10 @@ typedef struct Object {
short shapenr, shapeflag; /* current shape key for menu or pinned, flag for pinning */
float smoothresh; /* smoothresh is phong interpolation ray_shadow correction in render */
- int pad4;
+ short recalco, pad4; /* recalco for temp storage of ob->recalc, bad design warning */
struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */
-
+
struct DerivedMesh *derivedDeform, *derivedFinal;
int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
int pad;
@@ -217,6 +209,7 @@ typedef struct Object {
/*#endif*/
} Object;
+/* Warning, this is not used anymore because hooks are now modifiers */
typedef struct ObHook {
struct ObHook *next, *prev;
@@ -277,7 +270,7 @@ extern Object workob;
#define OB_OFFS_LOCAL 1
#define OB_QUAT 2
#define OB_NEG_SCALE 4
-#define OB_DUPLI (8+16+256+512)
+#define OB_DUPLI (8+16+256+512+2048)
#define OB_DUPLIFRAMES 8
#define OB_DUPLIVERTS 16
#define OB_DUPLIROT 32
@@ -286,6 +279,8 @@ extern Object workob;
#define OB_DUPLIGROUP 256
#define OB_DUPLIFACES 512
#define OB_DUPLIFACES_SCALE 1024
+#define OB_DUPLIPARTS 2048
+#define OB_RENDER_DUPLI 4096
/* (short) ipoflag */
#define OB_DRAWKEY 1
@@ -302,6 +297,9 @@ extern Object workob;
/* for stride edit */
#define OB_DISABLE_PATH 1024
+#define OB_OFFS_PARENTADD 2048
+
+
/* (short) trackflag / upflag */
#define OB_POSX 0
#define OB_POSY 1
@@ -319,6 +317,18 @@ extern Object workob;
#define OB_SHADED 4
#define OB_TEXTURE 5
+/* this condition has been made more complex since editmode can draw textures */
+#define CHECK_OB_DRAWTEXTURE(vd, dt) \
+ ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
+ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
+
+#define CHECK_OB_DRAWFACEDOT(sce, vd, dt) \
+ ( (sce->selectmode & SCE_SELECT_FACE) && \
+ (vd->drawtype<=OB_SOLID) && \
+ (((vd->drawtype==OB_SOLID) && (dt>=OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX) && (vd->flag & V3D_ZBUF_SELECT)) == 0) \
+ )
+
+
/* dtx: flags, char! */
#define OB_AXIS 2
#define OB_TEXSPACE 4
@@ -336,6 +346,9 @@ extern Object workob;
#define OB_PLAINAXES 2
#define OB_CIRCLE 3
#define OB_SINGLE_ARROW 4
+#define OB_CUBE 5
+#define OB_EMPTY_SPHERE 6
+#define OB_EMPTY_CONE 7
/* boundtype */
#define OB_BOUND_BOX 0
@@ -447,3 +460,4 @@ extern Object workob;
#endif
+
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
new file mode 100644
index 00000000000..18dba7f398d
--- /dev/null
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -0,0 +1,449 @@
+/* DNA_particle_types.h
+ *
+ *
+ * $Id: DNA_particle_types.h $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef DNA_PARTICLE_TYPES_H
+#define DNA_PARTICLE_TYPES_H
+
+#include "DNA_ID.h"
+
+typedef struct HairKey {
+ float co[3]; /* location of hair vertex */
+ float time; /* time along hair, default 0-100 */
+ float weight; /* softbody weight */
+ short editflag; /* saved particled edit mode flags */
+ short pad;
+} HairKey;
+
+typedef struct ParticleKey { /* when changed update size of struct to copy_particleKey()!! */
+ float co[3]; /* location */
+ float vel[3]; /* velocity */
+ float rot[4]; /* rotation quaternion */
+ float ave[3]; /* angular velocity */
+ float time; /* when this key happens */
+} ParticleKey;
+
+/* Child particles are created around or between parent particles */
+typedef struct ChildParticle {
+ int num, parent; /* num is face index on the final derived mesh */
+ 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];
+} ChildParticle;
+
+/* Everything that's non dynamic for a particle: */
+typedef struct ParticleData {
+ struct Object *stick_ob;/* object that particle sticks to when dead */
+
+ ParticleKey state; /* normally current global coordinates or */
+ /* in sticky object space if dead & sticky */
+
+ HairKey *hair; /* hair vertices */
+
+ ParticleKey *keys; /* keyed states */
+
+ float i_rot[4],r_rot[4];/* initial & random values (i_rot should be removed as it's not used anymore)*/
+ float r_ave[3],r_ve[3];
+
+ float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/
+ /* face normal for volume emission */
+
+ float time, lifetime; /* dietime is not nescessarily time+lifetime as */
+ float dietime; /* particles can die unnaturally (collision) */
+
+ float bank; /* banking angle for boids */
+
+ float size, sizemul; /* size and multiplier so that we can update size when ever */
+
+ int num; /* index to vert/edge/face */
+ int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */
+ int pad;
+
+ int totkey;
+ int bpi; /* softbody body point start index */
+
+ short flag;
+ short alive; /* the life state of a particle */
+ short loop; /* how many times particle life has looped */
+ short rt2;
+} ParticleData;
+
+typedef struct ParticleSettings {
+ ID id;
+
+ int flag;
+ short type, from, distr;
+ /* physics modes */
+ short phystype, rotmode, avemode, reactevent;
+ short draw, draw_as, draw_size, childtype;
+ /* number of path segments, power of 2 except */
+ short draw_step, ren_step;
+ short hair_step, keys_step;
+
+ /* adaptive path rendering */
+ short adapt_angle, adapt_pix;
+
+ short disp, omat, interpolation, rotfrom, integrator;
+ short kink, kink_axis, nbetween, boidneighbours;
+
+ /* billboards */
+ short bb_align, bb_uv_split, bb_anim, bb_split_offset;
+ float bb_tilt, bb_rand_tilt, bb_offset[2];
+
+ /* simplification */
+ short simplify_flag, simplify_refsize;
+ float simplify_rate, simplify_transition;
+ float simplify_viewport;
+
+ /* general values */
+ float sta, end, lifetime, randlife;
+ float timetweak, jitfac, keyed_time, eff_hair, rt;
+ int totpart, userjit, grid_res;
+
+ /* initial velocity factors */
+ float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
+ float avefac, phasefac, randrotfac, randphasefac;
+ /* physical properties */
+ float mass, size, randsize, reactshape;
+ /* global physical properties */
+ float acc[3], dragfac, brownfac, dampfac;
+ /* length */
+ float length, abslength, randlength;
+ /* children */
+ int child_nbr, ren_child_nbr;
+ float parents, childsize, childrandsize;
+ float childrad, childflat, childspread;
+ /* clumping */
+ float clumpfac, clumppow;
+ /* kink */
+ float kink_amp, kink_freq, kink_shape;
+ /* rough */
+ float rough1, rough1_size;
+ float rough2, rough2_size, rough2_thres;
+ float rough_end, rough_end_shape;
+ /* branching */
+ float branch_thres;
+ /* drawing stuff */
+ float draw_line[2];
+
+ /* boids */
+ float max_vel, max_lat_acc, max_tan_acc;
+ float average_vel, banking, max_bank, groundz;
+ float boidfac[8];
+ char boidrule[8];
+
+ struct Group *dup_group;
+ struct Group *eff_group;
+ struct Object *dup_ob;
+ struct Object *bb_ob;
+ struct Ipo *ipo;
+ struct PartDeflect *pd;
+} ParticleSettings;
+
+typedef struct ParticleSystem{
+ struct ParticleSystem *next, *prev;
+
+ ParticleSettings *part;
+
+ ParticleData *particles;
+
+ ChildParticle *child;
+
+ struct ParticleEdit *edit;
+
+ struct ParticleCacheKey **pathcache;
+ struct ParticleCacheKey **childcache;
+
+ struct SoftBody *soft;
+
+ struct Object *target_ob;
+ struct Object *keyed_ob;
+ struct Object *lattice;
+
+ struct ListBase effectors, reactevents;
+
+ float imat[4][4]; /* used for duplicators */
+ float cfra;
+ int seed;
+ int flag, totpart, totchild, totcached, totchildcache, rt;
+ short recalc, target_psys, keyed_psys, totkeyed, softflag, bakespace;
+
+ char bb_uvname[3][32];
+
+ /* if you change these remember to update array lengths to PSYS_TOT_VG! */
+ short vgroup[11], vg_neg, rt3[2];
+
+ /* temporary storage during render */
+ void *renderdata;
+}ParticleSystem;
+
+/* general particle maximums */
+/* no special why's, just seem reasonable */
+/* changing these (atleast upwards) should not cause any major problems */
+#define MAX_PARTS 100000 /* real particles/system */
+#define MAX_PART_CHILDREN 10000 /* child particles/real particles */
+#define MAX_BOIDNEIGHBOURS 10 /* neigbours considered/boid */
+
+/* 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_HAIR 2
+
+/* part->flag */
+#define PART_REACT_STA_END 1
+#define PART_REACT_MULTIPLE 2
+
+#define PART_LOOP 4
+//#define PART_LOOP_INSTANT 8
+
+#define PART_HAIR_GEOMETRY 16
+
+#define PART_UNBORN 32 /*show unborn particles*/
+#define PART_DIED 64 /*show died particles*/
+
+#define PART_TRAND 128
+#define PART_EDISTR 256 /* particle/face from face areas */
+
+#define PART_STICKY 512 /*collided particles can stick to collider*/
+#define PART_DIE_ON_COL (1<<12)
+#define PART_SIZE_DEFL (1<<13) /* swept sphere deflections */
+#define PART_ROT_DYN (1<<14) /* dynamic rotation */
+#define PART_SIZEMASS (1<<16)
+
+#define PART_ABS_LENGTH (1<<15)
+
+#define PART_ABS_TIME (1<<17)
+#define PART_GLOB_TIME (1<<18)
+
+#define PART_BOIDS_2D (1<<19)
+
+#define PART_BRANCHING (1<<20)
+#define PART_ANIM_BRANCHING (1<<21)
+#define PART_SYMM_BRANCHING (1<<24)
+
+#define PART_HAIR_BSPLINE 1024
+
+#define PART_GRID_INVERT (1<<26)
+
+#define PART_CHILD_EFFECT (1<<27)
+#define PART_CHILD_SEAMS (1<<28)
+#define PART_CHILD_RENDER (1<<29)
+#define PART_CHILD_GUIDE (1<<30)
+
+/* part->rotfrom */
+#define PART_ROT_KEYS 0 /* interpolate directly from keys */
+#define PART_ROT_ZINCR 1 /* same as zdir but done incrementally from previous position */
+#define PART_ROT_IINCR 2 /* same as idir but done incrementally from previous position */
+
+/* part->from */
+#define PART_FROM_VERT 0
+#define PART_FROM_FACE 1
+#define PART_FROM_VOLUME 2
+#define PART_FROM_PARTICLE 3
+#define PART_FROM_CHILD 4
+
+/* part->distr */
+#define PART_DISTR_JIT 0
+#define PART_DISTR_RAND 1
+#define PART_DISTR_GRID 2
+
+/* part->phystype */
+#define PART_PHYS_NO 0
+#define PART_PHYS_NEWTON 1
+#define PART_PHYS_KEYED 2
+#define PART_PHYS_BOIDS 3
+
+/* part->kink */
+#define PART_KINK_NO 0
+#define PART_KINK_CURL 1
+#define PART_KINK_RADIAL 2
+#define PART_KINK_WAVE 3
+#define PART_KINK_BRAID 4
+
+/* part->draw */
+#define PART_DRAW_VEL 1
+#define PART_DRAW_ANG 2
+#define PART_DRAW_SIZE 4
+#define PART_DRAW_EMITTER 8 /* render emitter also */
+#define PART_DRAW_KEYS 16
+#define PART_DRAW_ADAPT 32
+#define PART_DRAW_COS 64
+#define PART_DRAW_BB_LOCK 128
+#define PART_DRAW_PARENT 256
+#define PART_DRAW_NUM 512
+#define PART_DRAW_RAND_GR 1024
+#define PART_DRAW_REN_ADAPT 2048
+#define PART_DRAW_VEL_LENGTH (1<<12)
+#define PART_DRAW_MAT_COL (1<<13)
+#define PART_DRAW_WHOLE_GR (1<<14)
+#define PART_DRAW_REN_STRAND (1<<15)
+
+/* part->simplify_flag */
+#define PART_SIMPLIFY_ENABLE 1
+#define PART_SIMPLIFY_VIEWPORT 2
+
+/* part->bb_align */
+#define PART_BB_X 0
+#define PART_BB_Y 1
+#define PART_BB_Z 2
+#define PART_BB_VIEW 3
+#define PART_BB_VEL 4
+
+/* part->bb_anim */
+#define PART_BB_ANIM_NONE 0
+#define PART_BB_ANIM_TIME 1
+#define PART_BB_ANIM_ANGLE 2
+#define PART_BB_ANIM_OFF_TIME 3
+#define PART_BB_ANIM_OFF_ANGLE 4
+
+/* part->bb_split_offset */
+#define PART_BB_OFF_NONE 0
+#define PART_BB_OFF_LINEAR 1
+#define PART_BB_OFF_RANDOM 2
+
+/* part->draw as */
+#define PART_DRAW_NOT 0
+#define PART_DRAW_DOT 1
+#define PART_DRAW_CIRC 2
+#define PART_DRAW_CROSS 3
+#define PART_DRAW_AXIS 4
+#define PART_DRAW_LINE 5
+#define PART_DRAW_PATH 6
+#define PART_DRAW_OB 7
+#define PART_DRAW_GR 8
+#define PART_DRAW_BB 9
+
+/* part->integrator */
+#define PART_INT_EULER 0
+#define PART_INT_MIDPOINT 1
+#define PART_INT_RK4 2
+
+/* part->rotmode */
+#define PART_ROT_NOR 1
+#define PART_ROT_VEL 2
+#define PART_ROT_GLOB_X 3
+#define PART_ROT_GLOB_Y 4
+#define PART_ROT_GLOB_Z 5
+#define PART_ROT_OB_X 6
+#define PART_ROT_OB_Y 7
+#define PART_ROT_OB_Z 8
+
+/* part->avemode */
+#define PART_AVE_SPIN 1
+#define PART_AVE_RAND 2
+
+/* part->reactevent */
+#define PART_EVENT_DEATH 0
+#define PART_EVENT_COLLIDE 1
+#define PART_EVENT_NEAR 2
+
+/* part->childtype */
+#define PART_CHILD_PARTICLES 1
+#define PART_CHILD_FACES 2
+
+/* psys->recalc */
+#define PSYS_INIT 1
+#define PSYS_DISTR 2
+#define PSYS_ALLOC 4
+#define PSYS_TYPE 8
+#define PSYS_RECALC_HAIR 16
+
+/* psys->flag */
+#define PSYS_CURRENT 1
+//#define PSYS_BAKING 2
+//#define PSYS_BAKE_UI 4
+#define PSYS_KEYED_TIME 8
+#define PSYS_ENABLED 16
+#define PSYS_FIRST_KEYED 32
+#define PSYS_DRAWING 64
+//#define PSYS_SOFT_BAKE 128
+#define PSYS_DELETE 256 /* remove particlesystem as soon as possible */
+#define PSYS_HAIR_DONE 512
+#define PSYS_KEYED 1024
+#define PSYS_EDITED 2048
+#define PSYS_PROTECT_CACHE 4096
+
+/* pars->flag */
+#define PARS_UNEXIST 1
+#define PARS_NO_DISP 2
+#define PARS_STICKY 4
+#define PARS_TRANSFORM 8
+#define PARS_HIDE 16
+#define PARS_TAG 32
+#define PARS_REKEY 64
+#define PARS_EDIT_RECALC 128
+
+/* pars->alive */
+#define PARS_KILLED 0
+#define PARS_DEAD 1
+#define PARS_UNBORN 2
+#define PARS_ALIVE 3
+
+/* psys->vg */
+#define PSYS_TOT_VG 12
+
+#define PSYS_VG_DENSITY 0
+#define PSYS_VG_VEL 1
+#define PSYS_VG_LENGTH 2
+#define PSYS_VG_CLUMP 3
+#define PSYS_VG_KINK 4
+#define PSYS_VG_ROUGH1 5
+#define PSYS_VG_ROUGH2 6
+#define PSYS_VG_ROUGHE 7
+#define PSYS_VG_SIZE 8
+#define PSYS_VG_TAN 9
+#define PSYS_VG_ROT 10
+#define PSYS_VG_EFFECTOR 11
+
+/* part->boidrules */
+#define BOID_TOT_RULES 8
+
+#define BOID_COLLIDE 0
+#define BOID_AVOID 1
+#define BOID_CROWD 2
+#define BOID_CENTER 3
+#define BOID_AV_VEL 4
+#define BOID_VEL_MATCH 5
+#define BOID_GOAL 6
+#define BOID_LEVEL 7
+
+
+//#define PSYS_INTER_CUBIC 0
+//#define PSYS_INTER_LINEAR 1
+//#define PSYS_INTER_CARDINAL 2
+//#define PSYS_INTER_BSPLINE 3
+
+#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 250c600fcaf..869f1cb426d 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -120,7 +120,11 @@ typedef struct SceneRenderLayer {
struct Group *light_override;
unsigned int lay; /* scene->lay itself has priority over this */
+ unsigned int lay_zmask; /* has to be after lay, this is for Z-masking */
int layflag;
+
+ int pad;
+
int passflag; /* pass_xor has to be after passflag */
int pass_xor;
} SceneRenderLayer;
@@ -134,9 +138,11 @@ typedef struct SceneRenderLayer {
#define SCE_LAY_STRAND 32
/* flags between 32 and 0x8000 are set to 1 already, for future options */
-#define SCE_LAY_ALL_Z 0x8000
-#define SCE_LAY_XOR 0x10000
-#define SCE_LAY_DISABLE 0x20000
+#define SCE_LAY_ALL_Z 0x8000
+#define SCE_LAY_XOR 0x10000
+#define SCE_LAY_DISABLE 0x20000
+#define SCE_LAY_ZMASK 0x40000
+#define SCE_LAY_NEG_ZMASK 0x80000
/* srl->passflag */
#define SCE_PASS_COMBINED 1
@@ -153,6 +159,8 @@ typedef struct SceneRenderLayer {
#define SCE_PASS_INDEXOB 2048
#define SCE_PASS_UV 4096
#define SCE_PASS_RADIO 8192
+#define SCE_PASS_MIST 16384
+
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -240,9 +248,9 @@ typedef struct RenderData {
* The number of samples to use per pixel.
*/
short osa;
-
- short frs_sec, edgeint;
+ short frs_sec, edgeint;
+
/* safety, border and display rect */
rctf safety, border;
rcti disprect;
@@ -250,7 +258,8 @@ typedef struct RenderData {
/* information on different layers to be rendered */
ListBase layers;
short actlay, pad;
- int pad2;
+
+ float frs_sec_base;
/**
* Value used to define filter size for all filter options */
@@ -264,6 +273,8 @@ typedef struct RenderData {
/* Bake Render options */
short bake_osa, bake_filter, bake_mode, bake_flag;
+ short bake_normal_space, bpad;
+ float bake_maxdist, bake_biasdist, bake_pad;
/* yafray: global panel params. TODO: move elsewhere */
short GIquality, GIcache, GImethod, GIphotons, GIdirect;
@@ -271,15 +282,48 @@ typedef struct RenderData {
int GIdepth, GIcausdepth, GIpixelspersample;
int GIphotoncount, GImixphotons;
float GIphotonradius;
- int YF_numprocs, YF_raydepth, YF_AApasses, YF_AAsamples;
+ int YF_raydepth, YF_AApasses, YF_AAsamples, yfpad2;
float GIshadowquality, GIrefinement, GIpower, GIindirpower;
float YF_gamma, YF_exposure, YF_raybias, YF_AApixelsize, YF_AAthreshold;
/* paths to backbufffer, output, ftype */
- char backbuf[160], pic[160], ftype[160];
+ char backbuf[160], pic[160];
+
+ /* stamps flags. */
+ int stamp;
+ short stamp_font_id, pad3; /* select one of blenders bitmap fonts */
+
+ /* stamp info user data. */
+ char stamp_udata[160];
+ /* foreground/background color. */
+ float fg_stamp[4];
+ float bg_stamp[4];
+
+ /* render simplify */
+ int simplify_subsurf;
+ int simplify_shadowsamples;
+ float simplify_particles;
+ float simplify_aosss;
+
+ /* cineon */
+ short cineonwhite, cineonblack;
+ float cineongamma;
} RenderData;
+/* control render convert and shading engine */
+typedef struct RenderProfile {
+ struct RenderProfile *next, *prev;
+ char name[32];
+
+ short particle_perc;
+ short subsurf_max;
+ short shadbufsample_max;
+ short pad1;
+
+ float ao_error, pad2;
+
+} RenderProfile;
typedef struct GameFraming {
float col[3];
@@ -297,11 +341,34 @@ typedef struct TimeMarker {
unsigned int flag;
} TimeMarker;
-struct ImagePaintSettings {
+typedef struct ImagePaintSettings {
struct Brush *brush;
short flag, tool;
int pad3;
-};
+} ImagePaintSettings;
+
+typedef struct ParticleBrushData {
+ short size, strength; /* common settings */
+ short step, invert; /* for specific brushes only */
+} ParticleBrushData;
+
+typedef struct ParticleEditSettings {
+ short flag;
+ short totrekey;
+ short totaddkey;
+ short brushtype;
+
+ ParticleBrushData brush[7]; /* 7 = PE_TOT_BRUSH */
+
+ float emitterdist;
+ int draw_timed;
+} ParticleEditSettings;
+
+typedef struct TransformOrientation {
+ struct TransformOrientation *next, *prev;
+ char name[36];
+ float mat[3][3];
+} TransformOrientation;
typedef struct ToolSettings {
/* Subdivide Settings */
@@ -333,10 +400,14 @@ typedef struct ToolSettings {
short uvcalc_mapalign;
short uvcalc_flag;
- short pad2;
-
- /* Image Paint (8 byte aligned please!) */
+ /* Auto-IK */
+ short autoik_chainlen;
+
+ /* Image Paint (8 byttse aligned please!) */
struct ImagePaintSettings imapaint;
+
+ /* Particle Editing */
+ struct ParticleEditSettings particle;
/* Select Group Threshold */
float select_thresh;
@@ -352,7 +423,21 @@ typedef struct ToolSettings {
/* Multires */
char multires_subdiv_type;
- char pad4[2];
+ /* Skeleton generation */
+ short skgen_resolution;
+ float skgen_threshold_internal;
+ float skgen_threshold_external;
+ float skgen_length_ratio;
+ float skgen_length_limit;
+ float skgen_angle_limit;
+ float skgen_correlation_limit;
+ float skgen_symmetry_limit;
+ short skgen_options;
+ char skgen_postpro;
+ char skgen_postpro_passes;
+ char skgen_subdivisions[3];
+
+ char pad3[5];
} ToolSettings;
/* Used by all brushes to store their properties, which can be directly set
@@ -362,20 +447,25 @@ typedef struct BrushData
{
short size;
char strength, dir; /* Not used for smooth brush */
- char airbrush;
char view;
+ char flag;
char pad[2];
} BrushData;
struct SculptSession;
typedef struct SculptData
{
+ /* Note! all pointers in this struct must be duplicated header_info.c's copy_scene function */
+
/* Data stored only from entering sculptmode until exiting sculptmode */
struct SculptSession *session;
/* Pointers to all of sculptmodes's textures */
struct MTex *mtex[10];
+ /* Editable brush shape */
+ struct CurveMapping *cumap;
+
/* Settings for each brush */
BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush, flattenbrush;
short brush_type;
@@ -388,8 +478,7 @@ typedef struct SculptData
char texsep;
char averaging;
-
- char draw_flag;
+ char flags;
/* Control tablet input */
char tablet_size, tablet_strength;
@@ -397,6 +486,10 @@ typedef struct SculptData
/* Symmetry is separate from the other BrushData because the same
settings are always used for all brush types */
char symm;
+
+ /* Added to store if the 'Rake' setting has been set */
+ char rake;
+ char pad[7];
} SculptData;
typedef struct Scene {
@@ -417,15 +510,16 @@ typedef struct Scene {
/* editmode stuff */
float editbutsize; /* size of normals */
- short selectmode;
+ short selectmode; /* for mesh only! */
short proportional, prop_mode;
+ short automerge, pad5, pad6, pad7;
short use_nodes;
+
struct bNodeTree *nodetree;
- void *ed;
+ void *ed; /* sequence editor data is allocated here */
struct Radio *radio;
- void *sumohandle;
struct GameFraming framing;
@@ -439,9 +533,10 @@ typedef struct Scene {
ScriptLink scriptlink;
ListBase markers;
+ ListBase transform_spaces;
- short jumpframe;
- short pad1, pad2, pad3;
+ short jumpframe, pad1;
+ short snap_flag, snap_target;
/* none of the dependancy graph vars is mean to be saved */
struct DagForest *theDag;
@@ -483,10 +578,17 @@ typedef struct Scene {
#define R_GAUSS 0x20000
/* fbuf obsolete... */
#define R_FBUF 0x40000
- /* threads obsolete... is there for old files */
+ /* threads obsolete... is there for old files, now use for autodetect threads */
#define R_THREADS 0x80000
+ /* Use the same flag for autothreads */
+#define R_FIXED_THREADS 0x80000
+
#define R_SPEED 0x100000
#define R_SSS 0x200000
+#define R_NO_OVERWRITE 0x400000 /* skip existing files */
+#define R_TOUCH 0x800000 /* touch files before rendering */
+#define R_SIMPLIFY 0x1000000
+
/* filtertype */
#define R_FILTER_BOX 0
@@ -496,6 +598,7 @@ typedef struct Scene {
#define R_FILTER_CATROM 4
#define R_FILTER_GAUSS 5
#define R_FILTER_MITCH 6
+#define R_FILTER_FAST_GAUSS 7 /* note, this is only used for nodes at the moment */
/* yafray: renderer flag (not only exclusive to yafray) */
#define R_INTERN 0
@@ -516,8 +619,21 @@ typedef struct Scene {
#define R_EXR_TILE_FILE 0x0400
#define R_COMP_FREE 0x0800
#define R_NO_IMAGE_LOAD 0x1000
-#define R_NO_TEX 0x2000
-
+#define R_NO_TEX 0x2000
+#define R_STAMP_INFO 0x4000
+#define R_FULL_SAMPLE 0x8000
+
+/* r->stamp */
+#define R_STAMP_TIME 0x0001
+#define R_STAMP_FRAME 0x0002
+#define R_STAMP_DATE 0x0004
+#define R_STAMP_CAMERA 0x0008
+#define R_STAMP_SCENE 0x0010
+#define R_STAMP_NOTE 0x0020
+#define R_STAMP_DRAW 0x0040 /* draw in the image */
+#define R_STAMP_MARKER 0x0080
+#define R_STAMP_FILENAME 0x0100
+#define R_STAMP_SEQSTRIP 0x0200
/* alphamode */
#define R_ADDSKY 0
@@ -533,7 +649,7 @@ typedef struct Scene {
#define R_TARGA 0
#define R_IRIS 1
#define R_HAMX 2
-#define R_FTYPE 3
+#define R_FTYPE 3 /* ftype is nomore */
#define R_JPEG90 4
#define R_MOVIE 5
#define R_IRIZ 7
@@ -552,16 +668,27 @@ typedef struct Scene {
#define R_CINEON 26
#define R_DPX 27
#define R_MULTILAYER 28
+#define R_DDS 29
/* subimtype, flag options for imtype */
#define R_OPENEXR_HALF 1
#define R_OPENEXR_ZBUF 2
#define R_PREVIEW_JPG 4
+#define R_CINEON_LOG 8
+#define R_TIFF_16BIT 16
/* bake_mode: same as RE_BAKE_xxx defines */
/* bake_flag: */
-#define R_BAKE_CLEAR 1
-#define R_BAKE_OSA 2
+#define R_BAKE_CLEAR 1
+#define R_BAKE_OSA 2
+#define R_BAKE_TO_ACTIVE 4
+#define R_BAKE_NORMALIZE 8
+
+/* bake_normal_space */
+#define R_BAKE_SPACE_CAMERA 0
+#define R_BAKE_SPACE_WORLD 1
+#define R_BAKE_SPACE_OBJECT 2
+#define R_BAKE_SPACE_TANGENT 3
/* **************** SCENE ********************* */
#define RAD_PHASE_PATCHES 1
@@ -569,14 +696,24 @@ typedef struct Scene {
/* base->flag is in DNA_object_types.h */
-/* sce->flag */
-#define SCE_ADDSCENAME 1
+/* scene->snap_flag */
+#define SCE_SNAP 1
+/* scene->snap_target */
+#define SCE_SNAP_TARGET_CLOSEST 0
+#define SCE_SNAP_TARGET_CENTER 1
+#define SCE_SNAP_TARGET_MEDIAN 2
+#define SCE_SNAP_TARGET_ACTIVE 3
/* sce->selectmode */
-#define SCE_SELECT_VERTEX 1
+#define SCE_SELECT_VERTEX 1 /* for mesh */
#define SCE_SELECT_EDGE 2
#define SCE_SELECT_FACE 4
+/* sce->selectmode for particles */
+#define SCE_SELECT_PATH 1
+#define SCE_SELECT_POINT 2
+#define SCE_SELECT_END 4
+
/* sce->recalc (now in use by previewrender) */
#define SCE_PRV_CHANGED 1
@@ -603,21 +740,25 @@ typedef struct Scene {
#define FFMPEG_MULTIPLEX_AUDIO 1
#define FFMPEG_AUTOSPLIT_OUTPUT 2
+/* Sculpt brush flags */
+#define SCULPT_BRUSH_AIRBRUSH 1
+#define SCULPT_BRUSH_ANCHORED 2
+/* SculptData.flags */
+#define SCULPT_INPUT_SMOOTH 1
+#define SCULPT_DRAW_FAST 2
+#define SCULPT_DRAW_BRUSH 4
/* SculptData.brushtype */
-#define DRAW_BRUSH 1
-#define SMOOTH_BRUSH 2
-#define PINCH_BRUSH 3
+#define DRAW_BRUSH 1
+#define SMOOTH_BRUSH 2
+#define PINCH_BRUSH 3
#define INFLATE_BRUSH 4
-#define GRAB_BRUSH 5
-#define LAYER_BRUSH 6
+#define GRAB_BRUSH 5
+#define LAYER_BRUSH 6
#define FLATTEN_BRUSH 7
/* SculptData.texrept */
#define SCULPTREPT_DRAG 1
#define SCULPTREPT_TILE 2
#define SCULPTREPT_3D 3
-/* SculptData.draw_flag */
-#define SCULPTDRAW_FAST 1
-#define SCULPTDRAW_BRUSH 2
#define SYMM_X 1
#define SYMM_Y 2
@@ -628,6 +769,28 @@ typedef struct Scene {
#define IMAGEPAINT_DRAW_TOOL 2
#define IMAGEPAINT_DRAW_TOOL_DRAWING 4
+/* toolsettings->particle flag */
+#define PE_KEEP_LENGTHS 1
+#define PE_LOCK_FIRST 2
+#define PE_DEFLECT_EMITTER 4
+#define PE_INTERPOLATE_ADDED 8
+#define PE_SHOW_CHILD 16
+#define PE_SHOW_TIME 32
+#define PE_X_MIRROR 64
+
+/* toolsetting->particle brushtype */
+#define PE_BRUSH_NONE -1
+#define PE_BRUSH_COMB 0
+#define PE_BRUSH_CUT 1
+#define PE_BRUSH_LENGTH 2
+#define PE_BRUSH_PUFF 3
+#define PE_BRUSH_ADD 4
+#define PE_BRUSH_WEIGHT 5
+#define PE_BRUSH_SMOOTH 6
+
+/* this must equal ParticleEditSettings.brush array size */
+#define PE_TOT_BRUSH 7
+
/* toolsettings->retopo_mode */
#define RETOPO 1
#define RETOPO_PAINT 2
@@ -637,6 +800,24 @@ typedef struct Scene {
#define RETOPO_LINE 2
#define RETOPO_ELLIPSE 4
+/* toolsettings->skgen_options */
+#define SKGEN_FILTER_INTERNAL 1
+#define SKGEN_FILTER_EXTERNAL 2
+#define SKGEN_SYMMETRY 4
+#define SKGEN_CUT_LENGTH 8
+#define SKGEN_CUT_ANGLE 16
+#define SKGEN_CUT_CORRELATION 32
+
+#define SKGEN_SUB_LENGTH 0
+#define SKGEN_SUB_ANGLE 1
+#define SKGEN_SUB_CORRELATION 2
+#define SKGEN_SUB_TOTAL 3
+
+/* toolsettings->skgen_postpro */
+#define SKGEN_SMOOTH 0
+#define SKGEN_AVERAGE 1
+#define SKGEN_SHARPEN 2
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index cf3c2eaa168..65374983af5 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -147,7 +147,9 @@ typedef struct ScrArea {
#define VERT_SCROLL 3
#define T_SCROLL 4
#define B_SCROLL 8
-#define HOR_SCROLL 12
+#define HOR_SCROLL 12
+#define B_SCROLLO 16 /* special hack for outliner hscroll - prevent hanging */
+#define HOR_SCROLLO 20 /* in older versions of blender */
/* Panel->snap - for snapping to screen edges */
#define PNL_SNAP_NONE 0
diff --git a/source/blender/makesdna/DNA_scriptlink_types.h b/source/blender/makesdna/DNA_scriptlink_types.h
index 8a08d3f12c1..a21c67fc5e8 100644
--- a/source/blender/makesdna/DNA_scriptlink_types.h
+++ b/source/blender/makesdna/DNA_scriptlink_types.h
@@ -61,6 +61,9 @@ typedef struct ScriptLink {
* RENDER script links for clean-up actions */
#define SCRIPT_POSTRENDER 32
+#define SCRIPT_OBJECTUPDATE 64
+#define SCRIPT_OBDATAUPDATE 128
+
/* **************** SPACE HANDLERS ********************* */
/* these are special scriptlinks that can be assigned to
* a given space in a given ScrArea to:
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index 5bb9f61f71e..8dad33c411b 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -46,19 +46,59 @@ struct Scene;
typedef struct StripElem {
char name[80];
+} StripElem;
+
+typedef struct TStripElem {
struct ImBuf *ibuf;
- struct StripElem *se1, *se2, *se3;
+ struct ImBuf *ibuf_comp;
+ struct TStripElem *se1, *se2, *se3;
short ok;
- short pad;
+ short flag;
int nr;
-} StripElem;
+} TStripElem;
+
+typedef struct StripCrop {
+ int top;
+ int bottom;
+ int left;
+ int right;
+} StripCrop;
+
+typedef struct StripTransform {
+ int xofs;
+ int yofs;
+} StripTransform;
+
+typedef struct StripColorBalance {
+ float lift[3];
+ float gamma[3];
+ float gain[3];
+ int flag;
+ int pad;
+ float exposure;
+ float saturation;
+} StripColorBalance;
+
+typedef struct StripProxy {
+ char dir[160];
+} StripProxy;
typedef struct Strip {
struct Strip *next, *prev;
int rt, len, us, done;
+ int startstill, endstill;
StripElem *stripdata;
char dir[160];
int orx, ory;
+ StripProxy *proxy;
+ StripCrop *crop;
+ StripTransform *transform;
+ StripColorBalance *color_balance;
+ TStripElem *tstripdata;
+ TStripElem *tstripdata_startstill;
+ TStripElem *tstripdata_endstill;
+ struct ImBuf *ibuf_startstill;
+ struct ImBuf *ibuf_endstill;
} Strip;
@@ -87,22 +127,23 @@ typedef struct PluginSeq {
/* WATCH IT: first part identical to ID (for use in ipo's) */
typedef struct Sequence {
+ struct Sequence *next, *prev;
+ void *tmp; /* tmp var for copying, and tagging for linked selection */
+ void *lib; /* needed (to be like ipo), else it will raise libdata warnings, this should never be used */
+ char name[24]; /* name, not set by default and dosnt need to be unique as with ID's */
- struct Sequence *next, *prev, *newseq;
- void *lib;
- char name[24];
-
- short flag, type; /*flags bitmap (see below) and the type of sequence*/
- int len;
+ int flag, type; /*flags bitmap (see below) and the type of sequence*/
+ int len; /* the length of the contense of this strip - before handles are applied */
int start, startofs, endofs;
int startstill, endstill;
- int machine, depth;
+ int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */
int startdisp, enddisp; /*starting and ending points in the sequence*/
float mul, handsize;
- int sfra; /* starting frame according to the timeline of the scene */
+ /* is sfra needed anymore? - it looks like its only used in one place */
+ int sfra; /* starting frame according to the timeline of the scene. */
+ int anim_preseek;
Strip *strip;
- StripElem *curelem;
struct Ipo *ipo;
struct Scene *scene;
@@ -114,8 +155,7 @@ typedef struct Sequence {
/* pointers for effects: */
struct Sequence *seq1, *seq2, *seq3;
- /* meta */
- ListBase seqbase;
+ ListBase seqbase; /* list of strips for metastrips */
struct bSound *sound; /* the linked "bSound" object */
struct hdaudio *hdaudio; /* external hdaudio object */
@@ -125,7 +165,13 @@ typedef struct Sequence {
void *effectdata; /* Struct pointer for effect settings */
- int anim_preseek;
+ int anim_startofs; /* only use part of animation file */
+ int anim_endofs; /* is subtle different to startofs / endofs */
+
+ int blend_mode;
+ float blend_opacity;
+
+ int scenenr; /* for scene selection */
int pad;
} Sequence;
@@ -170,6 +216,8 @@ typedef struct TransformVars {
float yFin;
float rotIni;
float rotFin;
+ int percent;
+ int interpolation;
} TransformVars;
typedef struct SolidColorVars {
@@ -182,7 +230,7 @@ typedef struct SpeedControlVars {
float globalSpeed;
int flags;
int length;
- int pad;
+ int lastValidFrame;
} SpeedControlVars;
/* SpeedControlVars->flags */
@@ -203,6 +251,19 @@ typedef struct SpeedControlVars {
#define SEQ_IPO_FRAME_LOCKED 256
#define SEQ_EFFECT_NOT_LOADED 512
#define SEQ_FLAG_DELETE 1024
+#define SEQ_FLIPX 2048
+#define SEQ_FLIPY 4096
+#define SEQ_MAKE_FLOAT 8192
+#define SEQ_LOCK 16384
+#define SEQ_USE_PROXY 32768
+#define SEQ_USE_TRANSFORM 65536
+#define SEQ_USE_CROP 131072
+#define SEQ_USE_COLOR_BALANCE 262144
+#define SEQ_USE_PROXY_CUSTOM_DIR 524288
+
+#define SEQ_COLOR_BALANCE_INVERSE_GAIN 1
+#define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2
+#define SEQ_COLOR_BALANCE_INVERSE_LIFT 4
/* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */
#define SEQ_IMAGE 0
@@ -228,7 +289,19 @@ typedef struct SpeedControlVars {
#define SEQ_TRANSFORM 27
#define SEQ_COLOR 28
#define SEQ_SPEED 29
+#define SEQ_EFFECT_MAX 29
+
+#define STRIPELEM_FAILED 0
+#define STRIPELEM_OK 1
+#define STRIPELEM_META 2
+
+#define STRIPELEM_PREVIEW_DONE 1
+#define SEQ_BLEND_REPLACE 0
+/* all other BLEND_MODEs are simple SEQ_EFFECT ids and therefore identical
+ to the table above. (Only those effects that handle _exactly_ two inputs,
+ otherwise, you can't really blend, right :) !)
+*/
#endif
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 53a64fa574f..fbc30f5efcc 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -52,6 +52,7 @@ struct BlendHandle;
struct RenderInfo;
struct bNodeTree;
struct uiBlock;
+struct FileList;
/**
* The base structure all the other spaces
@@ -93,7 +94,7 @@ typedef struct SpaceIpo {
/* the ipo context we need to store */
struct Ipo *ipo;
struct ID *from;
- char actname[32], constname[32];
+ char actname[32], constname[32], bonename[32];
short totipo, pin;
short butofs, channel;
@@ -147,11 +148,11 @@ typedef struct SpaceSeq {
View2D v2d;
float xof, yof; /* offset for drawing the image preview */
- short mainb, zoom;
+ short mainb, pad;
short chanshown;
- short pad2;
+ short zebra;
int flag;
- int pad;
+ float zoom;
} SpaceSeq;
typedef struct SpaceFile {
@@ -170,8 +171,10 @@ typedef struct SpaceFile {
char file[80];
short type, ofs, flag, sort;
- short maxnamelen, collums;
-
+ short maxnamelen, collums, f_fp, pad1;
+ int pad2;
+ char fp_str[8];
+
struct BlendHandle *libfiledata;
unsigned short retval; /* event */
@@ -229,20 +232,23 @@ typedef struct SpaceImage {
struct CurveMapping *cumap;
short mode, menunr;
- short imanr, curtile;
+ short imanr;
+ short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */
int flag;
short imtypenr, lock;
- short showspare, pad2;
+ short pin, pad2;
float zoom;
+ char dt_uv; /* UV draw type */
+ char sticky; /* sticky selection type */
+ char dt_uvstretch;
+ char pad[5];
float xof, yof; /* user defined offset, image is centered */
float centx, centy; /* storage for offset while render drawing */
- char *info_str, *info_spare; /* info string for render */
- struct ImBuf *spare;
} SpaceImage;
-typedef struct SpaceNla{
+typedef struct SpaceNla {
struct SpaceLink *next, *prev;
int spacetype;
float blockscale;
@@ -251,7 +257,8 @@ typedef struct SpaceNla{
short blockhandler[8];
short menunr, lock;
- int flag;
+ short autosnap; /* this uses the same settings as autosnap for Action Editor */
+ short flag;
View2D v2d;
} SpaceNla;
@@ -285,6 +292,24 @@ typedef struct SpaceText {
} SpaceText;
+typedef struct Script {
+ ID id;
+
+ void *py_draw;
+ void *py_event;
+ void *py_button;
+ void *py_browsercallback;
+ void *py_globaldict;
+
+ int flags, lastspace;
+ char scriptname[256]; /* store the script file here so we can re-run it on loading blender, if "Enable Scripts" is on */
+ char scriptarg[256];
+} Script;
+#define SCRIPT_SET_NULL(_script) _script->py_draw = _script->py_event = _script->py_button = _script->py_browsercallback = _script->py_globaldict = NULL; _script->flags = 0;
+#define SCRIPT_RUNNING 0x01
+#define SCRIPT_GUI 0x02
+#define SCRIPT_FILESEL 0x04
+
typedef struct SpaceScript {
SpaceLink *next, *prev;
int spacetype;
@@ -292,9 +317,10 @@ typedef struct SpaceScript {
struct ScrArea *area;
struct Script *script;
- int pad2;
short flags, menunr;
-
+ int pad1;
+
+ void *but_refs;
} SpaceScript;
typedef struct SpaceTime {
@@ -333,89 +359,63 @@ typedef struct SpaceNode {
#define SNODE_DO_PREVIEW 1
#define SNODE_BACKDRAW 2
-#
-#
-typedef struct OneSelectableIma {
- int header;
- int ibuf_type;
- struct ImBuf *pict;
- struct OneSelectableIma *next;
- struct OneSelectableIma *prev;
-
- short cmap, image, draw_me, rt;
- short sx, sy, ex, ey, dw, dh;
- short selectable, selected;
- int mtime, disksize;
- char file_name[64];
-
- short orgx, orgy, orgd, anim; /* same as ibuf->x...*/
- char dummy[4]; /* 128 */
-
- char pict_rect[3968]; /* 4096 (RECT = 64 * 62) */
-
-} OneSelectableIma;
-
-#
-#
-typedef struct ImaDir {
- struct ImaDir *next, *prev;
- int selected, hilite;
- int type, size;
- int mtime;
- char name[100];
-} ImaDir;
-
typedef struct SpaceImaSel {
SpaceLink *next, *prev;
int spacetype;
float blockscale;
struct ScrArea *area;
- char title[28];
-
- int fase;
- short mode, subfase;
- short mouse_move_redraw, imafase;
- short mx, my;
-
- short dirsli, dirsli_lines;
- short dirsli_sx, dirsli_ey , dirsli_ex, dirsli_h;
- short imasli, fileselmenuitem;
- short imasli_sx, imasli_ey , imasli_ex, imasli_h;
-
- short dssx, dssy, dsex, dsey;
- short desx, desy, deex, deey;
- short fssx, fssy, fsex, fsey;
- short dsdh, fsdh;
- short fesx, fesy, feex, feey;
- short infsx, infsy, infex, infey;
- short dnsx, dnsy, dnw, dnh;
- short fnsx, fnsy, fnw, fnh;
-
-
- char fole[128], dor[128];
- char file[128], dir[128];
- ImaDir *firstdir, *firstfile;
- int topdir, totaldirs, hilite;
- int topfile, totalfiles;
-
- float image_slider;
- float slider_height;
- float slider_space;
- short topima, totalima;
- short curimax, curimay;
- OneSelectableIma *first_sel_ima;
- OneSelectableIma *hilite_ima;
- short total_selected, ima_redraw;
- int pad2;
+ short blockhandler[8];
+
+ View2D v2d;
+
+ struct FileList *files;
+
+ /* specific stuff for drawing */
+ char title[24];
+ char dir[160];
+ char file[80];
+
+ short type, menu, flag, sort;
+
+ void *curfont;
+ int active_file;
+
+ int numtilesx;
+ int numtilesy;
+
+ int selstate;
+
+ struct rcti viewrect;
+ struct rcti bookmarkrect;
+
+ float scrollpos; /* current position of scrollhandle */
+ float scrollheight; /* height of the scrollhandle */
+ float scrollarea; /* scroll region, scrollpos is from 0 to scrollarea */
+
+ float aspect;
+ unsigned short retval; /* event */
+
+ short ipotype;
+
+ short filter;
+ short active_bookmark;
+ short pad, pad1;
+
+ /* view settings */
+ short prv_w;
+ short prv_h;
+
+ /* one day we'll add unions to dna */
+ void (*returnfunc)(char *);
+ void (*returnfunc_event)(unsigned short);
+ void (*returnfunc_args)(char *, void *, void *);
- struct ImBuf *cmap;
+ void *arg1, *arg2;
+ short *menup; /* pointer to menu result or ID browsing */
+ char *pupmenu; /* optional menu in header */
- /* Also fucked. Needs to change so things compile, but breaks sdna
- * ... */
-/* void (*returnfunc)(void); */
- void (*returnfunc)(char*);
- void *arg1;
+ struct ImBuf *img;
} SpaceImaSel;
@@ -437,13 +437,14 @@ typedef struct SpaceImaSel {
/* filesel types */
#define FILE_UNIX 8
-#define FILE_BLENDER 8
+#define FILE_BLENDER 8 /* dont display relative paths */
#define FILE_SPECIAL 9
#define FILE_LOADLIB 1
#define FILE_MAIN 2
+#define FILE_LOADFONT 3
-/* sfile->flag */
+/* sfile->flag and simasel->flag */
#define FILE_SHOWSHORT 1
#define FILE_STRINGCODE 2
#define FILE_LINK 4
@@ -452,6 +453,8 @@ typedef struct SpaceImaSel {
#define FILE_ACTIVELAY 32
#define FILE_ATCURSOR 64
#define FILE_SYNCPOSE 128
+#define FILE_FILTER 256
+#define FILE_BOOKMARKS 512
/* sfile->sort */
#define FILE_SORTALPHA 0
@@ -468,6 +471,9 @@ typedef struct SpaceImaSel {
#define PYSCRIPTFILE 64
#define FTFONTFILE 128
#define SOUNDFILE 256
+#define TEXTFILE 512
+#define MOVIEFILE_ICON 1024 /* movie file that preview can't load */
+#define FOLDERFILE 2048 /* represents folders for filtering */
#define SCROLLH 16 /* height scrollbar */
#define SCROLLB 16 /* width scrollbar */
@@ -476,25 +482,49 @@ typedef struct SpaceImaSel {
#define SI_TEXTURE 0
#define SI_SHOW 1
+/* SpaceImage->dt_uv */
+#define SI_UVDT_DASH 0
+#define SI_UVDT_BLACK 1
+#define SI_UVDT_WHITE 2
+#define SI_UVDT_OUTLINE 3
+
+/* SpaceImage->dt_uvstretch */
+#define SI_UVDT_STRETCH_ANGLE 0
+#define SI_UVDT_STRETCH_AREA 1
+
+/* SpaceImage->sticky
+ * Note DISABLE should be 0, however would also need to re-arrange icon order,
+ * also, sticky loc is the default mode so this means we dont need to 'do_versons' */
+#define SI_STICKY_LOC 0
+#define SI_STICKY_DISABLE 1
+#define SI_STICKY_VERTEX 2
+
/* SpaceImage->flag */
-#define SI_BE_SQUARE 1
-#define SI_EDITTILE 2
-#define SI_CLIP_UV 4
-#define SI_DRAWTOOL 8
-#define SI_STICKYUVS 16
-#define SI_DRAWSHADOW 32
-#define SI_SELACTFACE 64
-#define SI_DEPRECATED 128
-#define SI_LOCALSTICKY 256
-#define SI_COORDFLOATS 512
-#define SI_PIXELSNAP 1024
-#define SI_LIVE_UNWRAP 2048
-#define SI_USE_ALPHA 0x1000
-#define SI_SHOW_ALPHA 0x2000
-#define SI_SHOW_ZBUF 0x4000
+#define SI_BE_SQUARE 1<<0
+#define SI_EDITTILE 1<<1
+#define SI_CLIP_UV 1<<2
+#define SI_DRAWTOOL 1<<3
+#define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */
+#define SI_DRAWSHADOW 1<<5
+#define SI_SELACTFACE 1<<6
+#define SI_DEPRECATED2 1<<7
+#define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */
+#define SI_COORDFLOATS 1<<9
+#define SI_PIXELSNAP 1<<10
+#define SI_LIVE_UNWRAP 1<<11
+#define SI_USE_ALPHA 1<<12
+#define SI_SHOW_ALPHA 1<<13
+#define SI_SHOW_ZBUF 1<<14
/* next two for render window dislay */
-#define SI_PREVSPACE 0x8000
-#define SI_FULLWINDOW 0x10000
+#define SI_PREVSPACE 1<<15
+#define SI_FULLWINDOW 1<<16
+#define SI_SYNC_UVSEL 1<<17
+#define SI_LOCAL_UV 1<<18
+ /* this means that the image is drawn until it reaches the view edge,
+ * in the image view, its unrelated to the 'tile' mode for texface */
+#define SI_DRAW_TILE 1<<19
+#define SI_SMOOTH_UV 1<<20
+#define SI_DRAW_STRETCH 1<<21
/* SpaceText flags (moved from DNA_text_types.h) */
@@ -527,6 +557,7 @@ typedef struct SpaceImaSel {
#define OOPS_LI 2048
#define OOPS_IM 4096
#define OOPS_AR 8192
+#define OOPS_GR 16384
/* SpaceOops->outlinevis */
#define SO_ALL_SCENES 0
@@ -584,10 +615,15 @@ typedef struct SpaceImaSel {
/* nla->flag */
#define SNLA_ALLKEYED 1
#define SNLA_ACTIVELAYERS 2
+#define SNLA_DRAWTIME 4
/* time->flag */
+ /* show timing in frames instead of in seconds */
#define TIME_DRAWFRAMES 1
+ /* temporary flag set when scrubbing time */
#define TIME_CFRA_NUM 2
+ /* only keyframes from active/selected channels get shown */
+#define TIME_ONLYACTSEL 4
/* time->redraws */
#define TIME_LEFTMOST_3D_WIN 1
@@ -603,9 +639,13 @@ typedef struct SpaceImaSel {
#define SEQ_DRAW_IMG_IMBUF 1
#define SEQ_DRAW_IMG_WAVEFORM 2
#define SEQ_DRAW_IMG_VECTORSCOPE 3
+#define SEQ_DRAW_IMG_HISTOGRAM 4
/* sseq->flag */
-#define SEQ_DRAWFRAMES 1
+#define SEQ_DRAWFRAMES 1
+#define SEQ_MARKER_TRANS 2
+#define SEQ_DRAW_COLOR_SEPERATED 4
+#define SEQ_DRAW_SAFE_MARGINS 8
/* space types, moved from DNA_screen_types.h */
enum {
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index a5a2e36125f..bc2b0521d4f 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -44,6 +44,7 @@ struct EnvMap;
struct Object;
struct Tex;
struct Image;
+struct PreviewImage;
struct ImBuf;
typedef struct MTex {
@@ -56,9 +57,10 @@ typedef struct MTex {
char projx, projy, projz, mapping;
float ofs[3], size[3];
- short texflag, colormodel;
+ short texflag, colormodel, pmapto, pmaptoneg;
+ short normapspace, pad[3];
float r, g, b, k;
- float def_var;
+ float def_var, rt;
float colfac, norfac, varfac;
float dispfac;
@@ -106,6 +108,7 @@ typedef struct CBData {
} CBData;
/* 32 = MAXCOLORBAND */
+/* note that this has to remain a single struct, for UserDef */
typedef struct ColorBand {
short flag, tot, cur, ipotype;
CBData data[32];
@@ -155,7 +158,7 @@ typedef struct Tex {
float cropxmin, cropymin, cropxmax, cropymax;
short xrepeat, yrepeat;
short extend;
-
+
/* variables disabled, moved to struct iuser */
short fie_ima;
int len;
@@ -171,7 +174,7 @@ typedef struct Tex {
struct PluginTex *plugin;
struct ColorBand *coba;
struct EnvMap *env;
-
+ struct PreviewImage * preview;
} Tex;
@@ -245,6 +248,7 @@ typedef struct TexMapping {
#define TEX_CALCALPHA 32
#define TEX_NORMALMAP 2048
#define TEX_GAUSS_MIP 4096
+#define TEX_FILTER_MIN 8192
/* imaflag unused, only for version check */
#define TEX_FIELDS_ 8
@@ -264,6 +268,7 @@ typedef struct TexMapping {
#define TEX_PRV_NOR 64
#define TEX_REPEAT_XMIR 128
#define TEX_REPEAT_YMIR 256
+#define TEX_FLAG_MASK ( TEX_COLORBAND | TEX_FLIPBLEND | TEX_NEGALPHA | TEX_CHECKER_ODD | TEX_CHECKER_EVEN | TEX_PRV_ALPHA | TEX_PRV_NOR | TEX_REPEAT_XMIR | TEX_REPEAT_YMIR )
/* extend (starts with 1 because of backward comp.) */
#define TEX_EXTEND 1
@@ -287,6 +292,10 @@ typedef struct TexMapping {
#define TEX_BANDNOISE 2
#define TEX_RINGNOISE 3
+/* tex->stype in texture.c - cloud types */
+#define TEX_DEFAULT 0
+#define TEX_COLOR 1
+
/* tex->stype in texture.c - marble types */
#define TEX_SOFT 0
#define TEX_SHARP 1
@@ -301,6 +310,23 @@ typedef struct TexMapping {
#define TEX_HALO 5
#define TEX_RAD 6
+/* tex->stype in texture.c - stucci types */
+#define TEX_PLASTIC 0
+#define TEX_WALLIN 1
+#define TEX_WALLOUT 2
+
+/* tex->stype in texture.c - voronoi types */
+#define TEX_INTENSITY 0
+#define TEX_COL1 1
+#define TEX_COL2 2
+#define TEX_COL3 3
+
+/* mtex->normapspace */
+#define MTEX_NSPACE_CAMERA 0
+#define MTEX_NSPACE_WORLD 1
+#define MTEX_NSPACE_OBJECT 2
+#define MTEX_NSPACE_TANGENT 3
+
/* wrap */
#define MTEX_FLAT 0
#define MTEX_CUBE 1
@@ -321,11 +347,12 @@ typedef struct TexMapping {
#define PROJ_Z 3
/* texflag */
-#define MTEX_RGBTOINT 1
-#define MTEX_STENCIL 2
-#define MTEX_NEGATIVE 4
-#define MTEX_ALPHAMIX 8
-#define MTEX_VIEWSPACE 16
+#define MTEX_RGBTOINT 1
+#define MTEX_STENCIL 2
+#define MTEX_NEGATIVE 4
+#define MTEX_ALPHAMIX 8
+#define MTEX_VIEWSPACE 16
+#define MTEX_DUPLI_MAPTO 32
/* blendtype */
#define MTEX_BLEND 0
@@ -338,6 +365,10 @@ typedef struct TexMapping {
#define MTEX_LIGHT 7
#define MTEX_SCREEN 8
#define MTEX_OVERLAY 9
+#define MTEX_BLEND_HUE 10
+#define MTEX_BLEND_SAT 11
+#define MTEX_BLEND_VAL 12
+#define MTEX_BLEND_COLOR 13
/* **************** EnvMap ********************* */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 7567ab6921c..07072104fbc 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -36,11 +36,12 @@
#define DNA_USERDEF_TYPES_H
#include "DNA_listBase.h"
+#include "DNA_texture_types.h"
/* themes; defines in BIF_resource.h */
+struct ColorBand;
-// global, button colors
-
+/* global, button colors */
typedef struct ThemeUI {
char outline[4];
char neutral[4];
@@ -63,11 +64,11 @@ typedef struct ThemeUI {
char but_drawtype;
char pad[3];
char iconfile[80]; // FILE_MAXFILE length
-
} ThemeUI;
-// try to put them all in one, if needed a special struct can be created as well
-// for example later on, when we introduce wire colors for ob types or so...
+/* try to put them all in one, if needed a special struct can be created as well
+ * for example later on, when we introduce wire colors for ob types or so...
+ */
typedef struct ThemeSpace {
char back[4];
char text[4];
@@ -92,6 +93,7 @@ typedef struct ThemeSpace {
char normal[4];
char bone_solid[4], bone_pose[4];
char strip[4], strip_select[4];
+ char cframe[4], pad[4];
char vertex_size, facedot_size;
char bpad[2];
@@ -101,17 +103,32 @@ typedef struct ThemeSpace {
char movie[4], image[4], scene[4], audio[4]; // for sequence editor
char effect[4], plugin[4], transition[4], meta[4];
- char bpad1[4];
-
+ char editmesh_active[4];
} ThemeSpace;
+/* set of colors for use as a custom color set for Objects/Bones wire drawing */
+typedef struct ThemeWireColor {
+ char solid[4];
+ char select[4];
+ char active[4];
+
+ short flag;
+ short pad;
+} ThemeWireColor;
+
+/* flags for ThemeWireColor */
+#define TH_WIRECOLOR_CONSTCOLS (1<<0)
+
+/* A theme */
typedef struct bTheme {
struct bTheme *next, *prev;
char name[32];
+ /* Interface Elements (buttons, menus, icons) */
ThemeUI tui;
+ /* Individual Spacetypes */
ThemeSpace tbuts;
ThemeSpace tv3d;
ThemeSpace tfile;
@@ -127,9 +144,12 @@ typedef struct bTheme {
ThemeSpace toops;
ThemeSpace ttime;
ThemeSpace tnode;
+
+ /* 20 sets of bone colors for this theme */
+ ThemeWireColor tarm[20];
+ /*ThemeWireColor tobj[20];*/
unsigned char bpad[4], bpad1[4];
-
} bTheme;
typedef struct SolidLight {
@@ -171,19 +191,26 @@ typedef struct UserDef {
short tw_hotspot, tw_flag, tw_handlesize, tw_size;
int textimeout, texcollectrate;
int memcachelimit;
+ int prefetchframes;
short frameserverport;
short pad_rot_angle; /*control the rotation step of the view when PAD2,PAD4,PAD6&PAD8 is use*/
short obcenter_dia;
short rvisize; /* rotating view icon size */
short rvibright; /* rotating view icon brightness */
- char versemaster[160];
- char verseuser[160];
short recent_files; /* maximum number of recently used files to remember */
short smooth_viewtx; /* miliseconds to spend spinning the view */
short glreslimit;
short ndof_pan, ndof_rotate;
// short pads[4];
// char pad[8];
+ char versemaster[160];
+ char verseuser[160];
+ float glalphaclip;
+
+ short autokey_mode; /* autokeying mode */
+ short autokey_flag; /* flags for autokeying */
+
+ struct ColorBand coba_weight; /* from texture.h */
} UserDef;
extern UserDef U; /* from usiblender.c !!!! */
@@ -191,22 +218,28 @@ extern UserDef U; /* from usiblender.c !!!! */
/* ***************** USERDEF ****************** */
/* flag */
-#define USER_AUTOSAVE 1
-#define USER_AUTOGRABGRID 2
-#define USER_AUTOROTGRID 4
-#define USER_AUTOSIZEGRID 8
-#define USER_SCENEGLOBAL 16
-#define USER_TRACKBALL 32
-#define USER_DUPLILINK 64
-#define USER_FSCOLLUM 128
-#define USER_MAT_ON_OB 256
-#define USER_NO_CAPSLOCK 512
-#define USER_VIEWMOVE 1024
-#define USER_TOOLTIPS 2048
-#define USER_TWOBUTTONMOUSE 4096
-#define USER_NONUMPAD 8192
-#define USER_LMOUSESELECT 16384
-#define USER_FILECOMPRESS 32768
+#define USER_AUTOSAVE (1 << 0)
+#define USER_AUTOGRABGRID (1 << 1)
+#define USER_AUTOROTGRID (1 << 2)
+#define USER_AUTOSIZEGRID (1 << 3)
+#define USER_SCENEGLOBAL (1 << 4)
+#define USER_TRACKBALL (1 << 5)
+#define USER_DUPLILINK (1 << 6)
+#define USER_FSCOLLUM (1 << 7)
+#define USER_MAT_ON_OB (1 << 8)
+#define USER_NO_CAPSLOCK (1 << 9)
+#define USER_VIEWMOVE (1 << 10)
+#define USER_TOOLTIPS (1 << 11)
+#define USER_TWOBUTTONMOUSE (1 << 12)
+#define USER_NONUMPAD (1 << 13)
+#define USER_LMOUSESELECT (1 << 14)
+#define USER_FILECOMPRESS (1 << 15)
+#define USER_SAVE_PREVIEWS (1 << 16)
+#define USER_CUSTOM_RANGE (1 << 17)
+#define USER_ADD_EDITMODE (1 << 18)
+#define USER_ADD_VIEWALIGNED (1 << 19)
+#define USER_RELPATHS (1 << 20)
+#define USER_DRAGIMMEDIATE (1 << 21)
/* viewzom */
#define USER_ZOOM_CONT 0
@@ -214,60 +247,76 @@ extern UserDef U; /* from usiblender.c !!!! */
#define USER_ZOOM_DOLLY 2
/* uiflag */
-
-#define USER_KEYINSERTACT 1
-#define USER_KEYINSERTOBJ 2
-#define USER_WHEELZOOMDIR 4
-#define USER_FILTERFILEEXTS 8
-#define USER_DRAWVIEWINFO 16
-#define USER_PLAINMENUS 32 // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase
+// old flag for #define USER_KEYINSERTACT (1 << 0)
+// old flag for #define USER_KEYINSERTOBJ (1 << 1)
+#define USER_WHEELZOOMDIR (1 << 2)
+#define USER_FILTERFILEEXTS (1 << 3)
+#define USER_DRAWVIEWINFO (1 << 4)
+#define USER_PLAINMENUS (1 << 5) // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase
// old flag for hide pulldown was here
-#define USER_FLIPFULLSCREEN 128
-#define USER_ALLWINCODECS 256
-#define USER_MENUOPENAUTO 512
-#define USER_PANELPINNED 1024
-#define USER_AUTOPERSP 2048
-#define USER_LOCKAROUND 4096
-#define USER_GLOBALUNDO 8192
-#define USER_ORBIT_SELECTION 16384
-#define USER_KEYINSERTAVAI 32768
-#define USER_HIDE_DOT 65536
-#define USER_SHOW_ROTVIEWICON 131072
-#define USER_SHOW_VIEWPORTNAME 262144
-#define USER_KEYINSERTNEED 524288
+#define USER_FLIPFULLSCREEN (1 << 7)
+#define USER_ALLWINCODECS (1 << 8)
+#define USER_MENUOPENAUTO (1 << 9)
+#define USER_PANELPINNED (1 << 10)
+#define USER_AUTOPERSP (1 << 11)
+#define USER_LOCKAROUND (1 << 12)
+#define USER_GLOBALUNDO (1 << 13)
+#define USER_ORBIT_SELECTION (1 << 14)
+// old flag for #define USER_KEYINSERTAVAI (1 << 15)
+#define USER_HIDE_DOT (1 << 16)
+#define USER_SHOW_ROTVIEWICON (1 << 17)
+#define USER_SHOW_VIEWPORTNAME (1 << 18)
+// old flag for #define USER_KEYINSERTNEED (1 << 19)
+#define USER_ZOOM_TO_MOUSEPOS (1 << 20)
+#define USER_SHOW_FPS (1 << 21)
+#define USER_MMB_PASTE (1 << 22)
-/* transopts */
+/* Auto-Keying mode */
+ /* AUTOKEY_ON is a bitflag */
+#define AUTOKEY_ON 1
+ /* AUTOKEY_ON + 2**n... (i.e. AUTOKEY_MODE_NORMAL = AUTOKEY_ON + 2) to preserve setting, even when autokey turned off */
+#define AUTOKEY_MODE_NORMAL 3
+#define AUTOKEY_MODE_EDITKEYS 5
-#define USER_TR_TOOLTIPS 1
-#define USER_TR_BUTTONS 2
-#define USER_TR_MENUS 4
-#define USER_TR_FILESELECT 8
-#define USER_TR_TEXTEDIT 16
-#define USER_DOTRANSLATE 32
-#define USER_USETEXTUREFONT 64
+/* Auto-Keying flag */
+#define AUTOKEY_FLAG_INSERTAVAIL (1<<0)
+#define AUTOKEY_FLAG_INSERTNEEDED (1<<1)
+#define AUTOKEY_FLAG_AUTOMATKEY (1<<2)
-/* dupflag */
+/* Auto-Keying macros */
+#define IS_AUTOKEY_ON (U.autokey_mode & AUTOKEY_ON)
+#define IS_AUTOKEY_MODE(mode) (U.autokey_mode == AUTOKEY_MODE_##mode)
+#define IS_AUTOKEY_FLAG(flag) (U.autokey_flag == AUTOKEY_FLAG_##flag)
-#define USER_DUP_MESH 1
-#define USER_DUP_CURVE 2
-#define USER_DUP_SURF 4
-#define USER_DUP_FONT 8
-#define USER_DUP_MBALL 16
-#define USER_DUP_LAMP 32
-#define USER_DUP_IPO 64
-#define USER_DUP_MAT 128
-#define USER_DUP_TEX 256
-#define USER_DUP_ARM 512
-#define USER_DUP_ACT 1024
+/* transopts */
+#define USER_TR_TOOLTIPS (1 << 0)
+#define USER_TR_BUTTONS (1 << 1)
+#define USER_TR_MENUS (1 << 2)
+#define USER_TR_FILESELECT (1 << 3)
+#define USER_TR_TEXTEDIT (1 << 4)
+#define USER_DOTRANSLATE (1 << 5)
+#define USER_USETEXTUREFONT (1 << 6)
+#define CONVERT_TO_UTF8 (1 << 7)
-/* gameflags */
+/* dupflag */
+#define USER_DUP_MESH (1 << 0)
+#define USER_DUP_CURVE (1 << 1)
+#define USER_DUP_SURF (1 << 2)
+#define USER_DUP_FONT (1 << 3)
+#define USER_DUP_MBALL (1 << 4)
+#define USER_DUP_LAMP (1 << 5)
+#define USER_DUP_IPO (1 << 6)
+#define USER_DUP_MAT (1 << 7)
+#define USER_DUP_TEX (1 << 8)
+#define USER_DUP_ARM (1 << 9)
+#define USER_DUP_ACT (1 << 10)
+/* gameflags */
#define USER_VERTEX_ARRAYS 1
#define USER_DISABLE_SOUND 2
#define USER_DISABLE_MIPMAP 4
/* vrml flag */
-
#define USER_VRML_LAYERS 1
#define USER_VRML_AUTOSCALE 2
#define USER_VRML_TWOSIDED 4
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index cfd6f682e71..3ed82ddc793 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -45,6 +45,10 @@ typedef struct View2D {
short keepaspect, keepzoom;
short oldwinx, oldwiny;
int flag;
+
+ float cursor[2]; /* only used in the UV view for now*/
+ short around;
+ char pad[6];
} View2D;
/* v2d->keepzoom */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 72140e5e46e..180cbd2af37 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -137,7 +137,7 @@ typedef struct View3D {
short gridsubdiv; /* Number of subdivisions in the grid between each highlighted grid line */
- short snap_target;
+ short pad3;
char ndofmode; /* mode of transform for 6DOF devices -1 not found, 0 normal, 1 fly, 2 ob transform */
char ndoffilter; /*filter for 6DOF devices 0 normal, 1 dominant */
@@ -165,16 +165,12 @@ typedef struct View3D {
#define V3D_CLIPPING 16384
#define V3D_DRAW_CENTERS 32768
+
/* View3d->flag2 (short) */
#define V3D_OPP_DIRECTION_NAME 1
#define V3D_FLYMODE 2
-#define V3D_TRANSFORM_SNAP 4
-
-/* View3d->snap_target */
-#define V3D_SNAP_TARGET_CLOSEST 0
-#define V3D_SNAP_TARGET_CENTER 1
-#define V3D_SNAP_TARGET_MEDIAN 2
-
+#define V3D_DEPRECATED 4 /* V3D_TRANSFORM_SNAP, moved to a scene setting */
+#define V3D_SOLID_TEX 8
/* View3D->around */
#define V3D_CENTER 0
@@ -205,6 +201,7 @@ typedef struct View3D {
#define V3D_MANIP_LOCAL 1
#define V3D_MANIP_NORMAL 2
#define V3D_MANIP_VIEW 3
+#define V3D_MANIP_CUSTOM 4 /* anything of value 4 or higher is custom */
/* View3d->twflag */
/* USE = user setting, DRAW = based on selection */
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 03b6871b8e0..e7a8d839227 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -55,6 +55,7 @@ typedef struct World {
short colormodel, totex;
short texact, mistype;
+ /* TODO - hork, zenk and ambk are not used, should remove at some point (Campbell) */
float horr, horg, horb, hork;
float zenr, zeng, zenb, zenk;
float ambr, ambg, ambb, ambk;
@@ -102,11 +103,19 @@ typedef struct World {
/* ambient occlusion */
float aodist, aodistfac, aoenergy, aobias;
short aomode, aosamp, aomix, aocolor;
+ float ao_adapt_thresh, ao_adapt_speed_fac;
+ float ao_approx_error, ao_approx_correction;
+ short ao_samp_method, ao_gather_method, ao_approx_passes, pad1;
+
float *aosphere, *aotables;
+
struct Ipo *ipo;
struct MTex *mtex[10];
+ /* previews */
+ struct PreviewImage *preview;
+
ScriptLink scriptlink;
} World;
@@ -133,15 +142,25 @@ typedef struct World {
#define WO_AOSUB 1
#define WO_AOADDSUB 2
+/* ao_samp_method - methods for sampling the AO hemi */
+#define WO_AOSAMP_CONSTANT 0
+#define WO_AOSAMP_HALTON 1
+#define WO_AOSAMP_HAMMERSLEY 2
+
/* aomode (use distances & random sampling modes) */
#define WO_AODIST 1
#define WO_AORNDSMP 2
+#define WO_AOCACHE 4
/* aocolor */
#define WO_AOPLAIN 0
#define WO_AOSKYCOL 1
#define WO_AOSKYTEX 2
+/* ao_gather_method */
+#define WO_AOGATHER_RAYTRACE 0
+#define WO_AOGATHER_APPROX 1
+
/* texco (also in DNA_material_types.h) */
#define TEXCO_ANGMAP 64
#define TEXCO_H_SPHEREMAP 256
diff --git a/source/blender/makesdna/intern/Makefile b/source/blender/makesdna/intern/Makefile
index 84d854064d7..bd498961e7a 100644
--- a/source/blender/makesdna/intern/Makefile
+++ b/source/blender/makesdna/intern/Makefile
@@ -38,10 +38,6 @@ ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)makesdna $(DIR)/$(SHARED_DIR)$(DEBUG_DIR
include nan_compile.mk
-ifneq ($(OS),irix)
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index fe712afbeeb..872fd515f1d 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -25,6 +25,8 @@ if sys.platform != 'cygwin':
makesdna_tool.Append (CCFLAGS = cflags)
makesdna_tool.Append (CPPDEFINES = defines)
makesdna_tool.Append (LIBPATH = '#'+root_build_dir+'/lib')
+if env['BF_PROFILE']:
+ makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_FLAGS'])
if env['OURPLATFORM'] == 'linux2' and root_build_dir[0]==os.sep:
makesdna = makesdna_tool.Program (target = root_build_dir+'/makesdna', source = source_files, LIBS=['bf_guardedalloc'])
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 4d437861751..ecf2a8e73b0 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -127,6 +127,8 @@ char *includefiles[] = {
"DNA_color_types.h",
"DNA_brush_types.h",
"DNA_customdata_types.h",
+ "DNA_particle_types.h",
+ "DNA_cloth_types.h",
// if you add files here, please add them at the end
// of makesdna.c (this file) as well
@@ -714,8 +716,10 @@ static int calculate_structlens(int firststruct)
/* struct alignment */
if(type >= firststruct) {
- if(sizeof(void *)==8 && (len % 8) )
+ if(sizeof(void *)==8 && (len % 8) ) {
printf("Align struct error: %s %s\n", types[structtype],cp);
+ dna_error = 1;
+ }
}
/* 2-4 aligned/ */
@@ -1144,4 +1148,6 @@ int main(int argc, char ** argv)
#include "DNA_color_types.h"
#include "DNA_brush_types.h"
#include "DNA_customdata_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_cloth_types.h"
/* end of list */
diff --git a/source/blender/nodes/CMP_node.h b/source/blender/nodes/CMP_node.h
index 3410238c0a2..020bbdebfa2 100644
--- a/source/blender/nodes/CMP_node.h
+++ b/source/blender/nodes/CMP_node.h
@@ -62,9 +62,12 @@ extern bNodeType cmp_node_zcombine;
extern bNodeType cmp_node_normal;
extern bNodeType cmp_node_curve_vec;
extern bNodeType cmp_node_map_value;
+extern bNodeType cmp_node_normalize;
extern bNodeType cmp_node_filter;
extern bNodeType cmp_node_blur;
+extern bNodeType cmp_node_dblur;
+extern bNodeType cmp_node_bilateralblur;
extern bNodeType cmp_node_vecblur;
extern bNodeType cmp_node_dilateerode;
extern bNodeType cmp_node_defocus;
@@ -82,6 +85,7 @@ extern bNodeType cmp_node_sepyuva;
extern bNodeType cmp_node_combyuva;
extern bNodeType cmp_node_sepycca;
extern bNodeType cmp_node_combycca;
+extern bNodeType cmp_node_premulkey;
extern bNodeType cmp_node_diff_matte;
extern bNodeType cmp_node_chroma;
@@ -93,9 +97,12 @@ extern bNodeType cmp_node_translate;
extern bNodeType cmp_node_rotate;
extern bNodeType cmp_node_scale;
extern bNodeType cmp_node_flip;
+extern bNodeType cmp_node_crop;
extern bNodeType cmp_node_displace;
extern bNodeType cmp_node_mapuv;
-#endif
-
+extern bNodeType cmp_node_glare;
+extern bNodeType cmp_node_tonemap;
+extern bNodeType cmp_node_lensdist;
+#endif
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 6729d5099f0..eab47eaeb02 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -36,6 +36,7 @@ SET(INC
../blenkernel
${SDL_INC}
${ZLIB_INC}
+ ${PYTHON_INC}
)
IF(WITH_VERSE)
diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript
index 0460848b4a5..8682f626b80 100644
--- a/source/blender/nodes/SConscript
+++ b/source/blender/nodes/SConscript
@@ -13,7 +13,7 @@ incs += ' ../blenloader ../quicktime'
incs += ' ../blenkernel ../renderconverter '
-
+incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC']
incs += ' ' + env['BF_SDL_INC']
@@ -41,6 +41,6 @@ if env['WITH_BF_QUICKTIME'] == 1:
defs += ' WITH_QUICKTIME'
incs += ' ' + env['BF_QUICKTIME_INC']
-defs += ' WITH_CCGSUBSURF'
+defs += ' WITH_CCGSUBSURF '
env.BlenderLib ( libname = 'nodes', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core','player'], priority = [65, 20] )
diff --git a/source/blender/nodes/SHD_node.h b/source/blender/nodes/SHD_node.h
index 688494d6de5..d75d7c9f568 100644
--- a/source/blender/nodes/SHD_node.h
+++ b/source/blender/nodes/SHD_node.h
@@ -56,8 +56,12 @@ extern bNodeType sh_node_curve_rgb;
extern bNodeType sh_node_math;
extern bNodeType sh_node_vect_math;
extern bNodeType sh_node_squeeze;
+extern bNodeType node_dynamic_typeinfo;
extern bNodeType sh_node_material_ext;
extern bNodeType sh_node_invert;
+extern bNodeType sh_node_seprgb;
+extern bNodeType sh_node_combrgb;
+extern bNodeType sh_node_hue_sat;
#endif
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c
index f108098750c..4972ff4ae5a 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_alphaOver.c
@@ -47,16 +47,16 @@ static void do_alphaover_premul(bNode *node, float *out, float *src, float *over
if(over[3]<=0.0f) {
QUATCOPY(out, src);
}
- else if(*fac==1.0f && over[3]>=1.0f) {
+ else if(fac[0]==1.0f && over[3]>=1.0f) {
QUATCOPY(out, over);
}
else {
- float mul= 1.0f - *fac*over[3];
+ float mul= 1.0f - fac[0]*over[3];
- out[0]= (mul*src[0]) + *fac*over[0];
- out[1]= (mul*src[1]) + *fac*over[1];
- out[2]= (mul*src[2]) + *fac*over[2];
- out[3]= (mul*src[3]) + *fac*over[3];
+ out[0]= (mul*src[0]) + fac[0]*over[0];
+ out[1]= (mul*src[1]) + fac[0]*over[1];
+ out[2]= (mul*src[2]) + fac[0]*over[2];
+ out[3]= (mul*src[3]) + fac[0]*over[3];
}
}
@@ -67,7 +67,7 @@ static void do_alphaover_key(bNode *node, float *out, float *src, float *over, f
if(over[3]<=0.0f) {
QUATCOPY(out, src);
}
- else if(*fac==1.0f && over[3]>=1.0f) {
+ else if(fac[0]==1.0f && over[3]>=1.0f) {
QUATCOPY(out, over);
}
else {
@@ -81,6 +81,31 @@ static void do_alphaover_key(bNode *node, float *out, float *src, float *over, f
}
}
+/* result will be still premul, but the over part is premulled */
+static void do_alphaover_mixed(bNode *node, float *out, float *src, float *over, float *fac)
+{
+
+ if(over[3]<=0.0f) {
+ QUATCOPY(out, src);
+ }
+ else if(fac[0]==1.0f && over[3]>=1.0f) {
+ QUATCOPY(out, over);
+ }
+ else {
+ NodeTwoFloats *ntf= node->storage;
+ float addfac= 1.0f - ntf->x + over[3]*ntf->x;
+ float premul= fac[0]*addfac;
+ float mul= 1.0f - fac[0]*over[3];
+
+ out[0]= (mul*src[0]) + premul*over[0];
+ out[1]= (mul*src[1]) + premul*over[1];
+ out[2]= (mul*src[2]) + premul*over[2];
+ out[3]= (mul*src[3]) + fac[0]*over[3];
+ }
+}
+
+
+
static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
@@ -97,8 +122,11 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i
/* make output size of input image */
CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
+ NodeTwoFloats *ntf= node->storage;
- if(node->custom1)
+ if(ntf->x != 0.0f)
+ composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_mixed, CB_RGBA, CB_RGBA, CB_VAL);
+ else if(node->custom1)
composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL);
else
composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL);
@@ -107,6 +135,11 @@ static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **i
}
}
+static void node_alphaover_init(bNode* node)
+{
+ node->storage= MEM_callocN(sizeof(NodeTwoFloats), "NodeTwoFloats");
+}
+
bNodeType cmp_node_alphaover= {
/* *next,*prev */ NULL, NULL,
/* type code */ CMP_NODE_ALPHAOVER,
@@ -115,12 +148,12 @@ bNodeType cmp_node_alphaover= {
/* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
/* input sock */ cmp_node_alphaover_in,
/* output sock */ cmp_node_alphaover_out,
- /* storage */ "",
+ /* storage */ "NodeTwoFloats",
/* execfunc */ node_composit_exec_alphaover,
/* butfunc */ NULL,
- /* initfunc */ NULL,
- /* freestoragefunc */ NULL,
- /* copystoragefunc */ NULL,
+ /* initfunc */ node_alphaover_init,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
/* id */ NULL
};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c
new file mode 100644
index 00000000000..b954e876ea1
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_bilateralblur.c
@@ -0,0 +1,272 @@
+/**
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Vilem Novak
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "../CMP_util.h"
+
+/* **************** BILATERALBLUR ******************** */
+static bNodeSocketType cmp_node_bilateralblur_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType cmp_node_bilateralblur_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+#define INIT_C3\
+ mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];mean1[3] = src[3];
+
+/* finds color distances */
+#define COLOR_DISTANCE_C3(c1, c2)\
+ ((c1[0] - c2[0])*(c1[0] - c2[0]) + \
+ (c1[1] - c2[1])*(c1[1] - c2[1]) + \
+ (c1[2] - c2[2])*(c1[2] - c2[2]) + \
+ (c1[3] - c2[3])*(c1[3] - c2[3]))
+
+/* this is the main kernel function for comparing color distances
+ and adding them weighted to the final color */
+#define KERNEL_ELEMENT_C3(k)\
+ temp_color = src + deltas[k];\
+ ref_color = ref + deltas[k];\
+ w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color;\
+ w = 1./(w*w + 1); \
+ mean0 += w;\
+ mean1[0] += temp_color[0]*w; \
+ mean1[1] += temp_color[1]*w; \
+ mean1[2] += temp_color[2]*w; \
+ mean1[3] += temp_color[3]*w;
+
+/* write blurred values to image */
+#define UPDATE_OUTPUT_C3\
+ mean0 = 1./mean0;\
+ dest[x*pix + 0] = mean1[0]*mean0; \
+ dest[x*pix + 1] = mean1[1]*mean0; \
+ dest[x*pix + 2] = mean1[2]*mean0; \
+ dest[x*pix + 3] = mean1[3]*mean0;
+
+/* initializes deltas for fast access to neighbour pixels */
+#define INIT_3X3_DELTAS( deltas, step, nch ) \
+ ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \
+ (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \
+ (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \
+ (deltas)[6] = (step), (deltas)[7] = (step) + (nch));
+
+
+/* code of this node was heavily inspired by the smooth function of opencv library.
+The main change is an optional image input */
+static void node_composit_exec_bilateralblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ NodeBilateralBlurData *nbbd= node->storage;
+ CompBuf *new, *source, *img= in[0]->data , *refimg= in[1]->data;
+ double mean0, w, i2sigma_color, i2sigma_space;
+ double mean1[4];
+ double weight_tab[8];
+ float *src, *dest, *ref, *temp_color, *ref_color;
+ float sigma_color, sigma_space;
+ int imgx, imgy, x, y, pix, i, step;
+ int deltas[8];
+ short found_determinator= 0;
+
+ if(img == NULL || out[0]->hasoutput == 0)
+ return;
+
+ if(img->type != CB_RGBA) {
+ img= typecheck_compbuf(in[0]->data, CB_RGBA);
+ }
+
+ imgx= img->x;
+ imgy= img->y;
+ pix= img->type;
+ step= pix * imgx;
+
+ if(refimg) {
+ if(refimg->x == imgx && refimg->y == imgy) {
+ if(ELEM3(refimg->type, CB_VAL, CB_VEC2, CB_VEC3)) {
+ refimg= typecheck_compbuf(in[1]->data, CB_RGBA);
+ found_determinator= 1;
+ }
+ }
+ }
+ else {
+ refimg= img;
+ }
+
+ /* allocs */
+ source= dupalloc_compbuf(img);
+ new= alloc_compbuf(imgx, imgy, pix, 1);
+
+ /* accept image offsets from other nodes */
+ new->xof= img->xof;
+ new->yof= img->yof;
+
+ /* bilateral code properties */
+ sigma_color= nbbd->sigma_color;
+ sigma_space= nbbd->sigma_space;
+
+ i2sigma_color= 1. / (sigma_color * sigma_color);
+ i2sigma_space= 1. / (sigma_space * sigma_space);
+
+ INIT_3X3_DELTAS(deltas, step, pix);
+
+ weight_tab[0] = weight_tab[2] = weight_tab[4] = weight_tab[6] = i2sigma_space;
+ weight_tab[1] = weight_tab[3] = weight_tab[5] = weight_tab[7] = i2sigma_space * 2;
+
+ /* iterations */
+ for(i= 0; i < nbbd->iter; i++) {
+ src= source->rect;
+ ref= refimg->rect;
+ dest= new->rect;
+ /*goes through image, there are more loops for 1st/last line and all other lines*/
+ /*kernel element accumulates surrounding colors, which are then written with the update_output function*/
+ for(x= 0; x < imgx; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(6);
+
+ if(x > 0) {
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(4);
+ }
+
+ if(x < imgx - 1) {
+ KERNEL_ELEMENT_C3(7);
+ KERNEL_ELEMENT_C3(0);
+ }
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ dest+= step;
+
+ for(y= 1; y < imgy - 1; y++, dest+= step, src+= pix, ref+= pix) {
+ x= 0;
+
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(0);
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(6);
+ KERNEL_ELEMENT_C3(7);
+
+ UPDATE_OUTPUT_C3;
+
+ src+= pix;
+ ref+= pix;
+
+ for(x= 1; x < imgx - 1; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(0);
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(6);
+ KERNEL_ELEMENT_C3(7);
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(2);
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ KERNEL_ELEMENT_C3(5);
+ KERNEL_ELEMENT_C3(6);
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ for(x= 0; x < imgx; x++, src+= pix, ref+= pix) {
+ INIT_C3;
+
+ KERNEL_ELEMENT_C3(2);
+
+ if(x > 0) {
+ KERNEL_ELEMENT_C3(3);
+ KERNEL_ELEMENT_C3(4);
+ }
+ if(x < imgx - 1) {
+ KERNEL_ELEMENT_C3(1);
+ KERNEL_ELEMENT_C3(0);
+ }
+
+ UPDATE_OUTPUT_C3;
+ }
+
+ if(node->exec & NODE_BREAK) break;
+
+ SWAP(CompBuf, *source, *new);
+ }
+
+ if(node->exec & NODE_BREAK)
+ free_compbuf(source);
+
+ if(img != in[0]->data)
+ free_compbuf(img);
+
+ if(found_determinator == 1) {
+ if(refimg != in[1]->data)
+ free_compbuf(refimg);
+ }
+
+ out[0]->data= source;
+
+ free_compbuf(new);
+}
+
+static void node_composit_init_bilateralblur(bNode* node)
+{
+ NodeBilateralBlurData *nbbd= MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data");
+ node->storage= nbbd;
+ nbbd->sigma_color= 0.3;
+ nbbd->sigma_space= 5.0;
+}
+
+bNodeType cmp_node_bilateralblur= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_BILATERALBLUR,
+ /* name */ "Bilateral Blur",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS,
+ /* input sock */ cmp_node_bilateralblur_in,
+ /* output sock */ cmp_node_bilateralblur_out,
+ /* storage */ "NodeBilateralBlurData",
+ /* execfunc */ node_composit_exec_bilateralblur,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_bilateralblur,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
index 91a04e3128a..e7e799b6e76 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
@@ -22,15 +22,14 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Campbell Barton, Alfredo de Greef, David Millan Escriva,
+ * Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "../CMP_util.h"
-
-
/* **************** BLUR ******************** */
static bNodeSocketType cmp_node_blur_in[]= {
{ SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
@@ -399,7 +398,7 @@ static void bokeh_single_image(bNode *node, CompBuf *new, CompBuf *img, float fa
int maxyr= y+rady>imgy-1?imgy-y-1:rady;
float *destd= new->rect + pix*( (y + minyr)*imgx + x + minxr);
- float *dgausd= gausstab + (minyr+rady)*2*radx + minxr+radx;
+ float *dgausd= gausstab + (minyr+rady)*(2*radx+1) + minxr+radx;
if(x<=0) src= srcd;
else if(x<imgx) src+= pix;
@@ -555,44 +554,59 @@ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf
free_compbuf(ref_use);
}
-
-
static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
CompBuf *new, *img= in[0]->data;
+ NodeBlurData *nbd= node->storage;
- if(img==NULL || out[0]->hasoutput==0)
- return;
+ if(img==NULL) return;
- if(img->type==CB_VEC2 || img->type==CB_VEC3) {
- img= typecheck_compbuf(in[0]->data, CB_RGBA);
- }
+ /* store image in size that is needed for absolute/relative conversions on ui level */
+ nbd->image_in_width= img->x;
+ nbd->image_in_height= img->y;
- /* if fac input, we do it different */
- if(in[1]->data) {
-
- /* make output size of input image */
- new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */
-
- /* accept image offsets from other nodes */
- new->xof = img->xof;
- new->yof = img->yof;
-
- blur_with_reference(node, new, img, in[1]->data);
- if(node->exec & NODE_BREAK) {
- free_compbuf(new);
- new= NULL;
+ if(out[0]->hasoutput==0) return;
+
+ if (((NodeBlurData *)node->storage)->filtertype == R_FILTER_FAST_GAUSS) {
+ CompBuf *new, *img = in[0]->data;
+ /*from eeshlo's original patch, removed to fit in with the existing blur node */
+ /*const float sx = in[1]->vec[0], sy = in[2]->vec[0];*/
+ const float sx = ((float)nbd->sizex)/2.0f, sy = ((float)nbd->sizey)/2.0f;
+ int c;
+
+ if ((img==NULL) || (out[0]->hasoutput==0)) return;
+
+ if (img->type == CB_VEC2)
+ new = typecheck_compbuf(img, CB_VAL);
+ else if (img->type == CB_VEC3)
+ new = typecheck_compbuf(img, CB_RGBA);
+ else
+ new = dupalloc_compbuf(img);
+
+ if ((sx == sy) && (sx > 0.f)) {
+ for (c=0; c<new->type; ++c)
+ IIR_gauss(new, sx, c, 3);
}
- out[0]->data= new;
- }
- else {
+ else {
+ if (sx > 0.f) {
+ for (c=0; c<new->type; ++c)
+ IIR_gauss(new, sx, c, 1);
+ }
+ if (sy > 0.f) {
+ for (c=0; c<new->type; ++c)
+ IIR_gauss(new, sy, c, 2);
+ }
+ }
+ out[0]->data = new;
- if(in[1]->vec[0]<=0.001f) { /* time node inputs can be a tiny value */
- new= pass_on_compbuf(img);
+ } else {
+ /* All non fast gauss blur methods */
+ if(img->type==CB_VEC2 || img->type==CB_VEC3) {
+ img= typecheck_compbuf(in[0]->data, CB_RGBA);
}
- else {
- NodeBlurData *nbd= node->storage;
- CompBuf *gammabuf;
+
+ /* if fac input, we do it different */
+ if(in[1]->data) {
/* make output size of input image */
new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */
@@ -600,33 +614,57 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN
/* accept image offsets from other nodes */
new->xof = img->xof;
new->yof = img->yof;
-
- if(nbd->gamma) {
- gammabuf= dupalloc_compbuf(img);
- gamma_correct_compbuf(gammabuf, 0);
- }
- else gammabuf= img;
-
- if(nbd->bokeh)
- bokeh_single_image(node, new, gammabuf, in[1]->vec[0]);
- else if(1)
- blur_single_image(node, new, gammabuf, in[1]->vec[0]);
- else /* bloom experimental... */
- bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd);
- if(nbd->gamma) {
- gamma_correct_compbuf(new, 1);
- free_compbuf(gammabuf);
- }
+ blur_with_reference(node, new, img, in[1]->data);
if(node->exec & NODE_BREAK) {
free_compbuf(new);
new= NULL;
}
+ out[0]->data= new;
+ }
+ else {
+
+ if(in[1]->vec[0]<=0.001f) { /* time node inputs can be a tiny value */
+ new= pass_on_compbuf(img);
+ }
+ else {
+ NodeBlurData *nbd= node->storage;
+ CompBuf *gammabuf;
+
+ /* make output size of input image */
+ new= alloc_compbuf(img->x, img->y, img->type, 1); /* allocs */
+
+ /* accept image offsets from other nodes */
+ new->xof = img->xof;
+ new->yof = img->yof;
+
+ if(nbd->gamma) {
+ gammabuf= dupalloc_compbuf(img);
+ gamma_correct_compbuf(gammabuf, 0);
+ }
+ else gammabuf= img;
+
+ if(nbd->bokeh)
+ bokeh_single_image(node, new, gammabuf, in[1]->vec[0]);
+ else if(1)
+ blur_single_image(node, new, gammabuf, in[1]->vec[0]);
+ else /* bloom experimental... */
+ bloom_with_reference(new, gammabuf, NULL, in[1]->vec[0], nbd);
+
+ if(nbd->gamma) {
+ gamma_correct_compbuf(new, 1);
+ free_compbuf(gammabuf);
+ }
+ if(node->exec & NODE_BREAK) {
+ free_compbuf(new);
+ new= NULL;
+ }
+ }
+ out[0]->data= new;
}
- out[0]->data= new;
+ if(img!=in[0]->data)
+ free_compbuf(img);
}
- if(img!=in[0]->data)
- free_compbuf(img);
}
static void node_composit_init_blur(bNode* node)
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
index d836a829696..6a40018e659 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_chromaMatte.c
@@ -89,8 +89,8 @@ static void do_chroma_key(bNode *node, float *out, float *in)
if(kfg>0.0) { /* found a pixel that is within key color */
newY=in[0]-(1-c->t3)*kfg;
- newCb=in[1]-kfg*cosf(theta);
- newCr=in[2]-kfg*sinf(theta);
+ newCb=in[1]-kfg*cos((double)theta);
+ newCr=in[2]-kfg*sin((double)theta);
alpha=(kfg+c->fsize)*(c->fstrength);
beta=atan2(newCr,newCb);
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_crop.c b/source/blender/nodes/intern/CMP_nodes/CMP_crop.c
new file mode 100644
index 00000000000..f3a00dec084
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_crop.c
@@ -0,0 +1,119 @@
+/**
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Juho Vepsäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+/* **************** Crop ******************** */
+
+static bNodeSocketType cmp_node_crop_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_crop_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_composit_exec_crop(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ if(in[0]->data) {
+ NodeTwoXYs *ntxy= node->storage;
+ CompBuf *cbuf= in[0]->data;
+ CompBuf *stackbuf;
+ int x, y;
+ float *srcfp, *outfp;
+ rcti outputrect;
+
+ /* check input image size */
+ if(cbuf->x <= ntxy->x1 + 1)
+ ntxy->x1= cbuf->x - 1;
+
+ if(cbuf->y <= ntxy->y1 + 1)
+ ntxy->y1= cbuf->y - 1;
+
+ if(cbuf->x <= ntxy->x2 + 1)
+ ntxy->x2= cbuf->x - 1;
+
+ if(cbuf->y <= ntxy->y2 + 1)
+ ntxy->y2= cbuf->y - 1;
+
+ /* figure out the minimums and maximums */
+ outputrect.xmax=MAX2(ntxy->x1, ntxy->x2) + 1;
+ outputrect.xmin=MIN2(ntxy->x1, ntxy->x2);
+ outputrect.ymax=MAX2(ntxy->y1, ntxy->y2) + 1;
+ outputrect.ymin=MIN2(ntxy->y1, ntxy->y2);
+
+ if(node->custom1) {
+ /* this option crops the image size too */
+ stackbuf= get_cropped_compbuf(&outputrect, cbuf->rect, cbuf->x, cbuf->y, cbuf->type);
+ }
+ else {
+ /* this option won't crop the size of the image as well */
+ /* allocate memory for the output image */
+ stackbuf = alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);
+
+ /* select the cropped part of the image and set it to the output */
+ for(y=outputrect.ymin; y<outputrect.ymax; y++){
+ srcfp= cbuf->rect + (y * cbuf->x + outputrect.xmin) * cbuf->type;
+ outfp= stackbuf->rect + (y * stackbuf->x + outputrect.xmin) * stackbuf->type;
+ for(x=outputrect.xmin; x<outputrect.xmax; x++, outfp+= stackbuf->type, srcfp+= cbuf->type)
+ memcpy(outfp, srcfp, sizeof(float)*stackbuf->type);
+ }
+ }
+
+ out[0]->data= stackbuf;
+ }
+}
+
+static void node_composit_init_crop(bNode* node)
+{
+ NodeTwoXYs *nxy= MEM_callocN(sizeof(NodeTwoXYs), "node xy data");
+ node->storage= nxy;
+ nxy->x1= 0;
+ nxy->x2= 0;
+ nxy->y1= 0;
+ nxy->y2= 0;
+}
+
+bNodeType cmp_node_crop= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_CROP,
+ /* name */ "Crop",
+ /* width+range */ 140, 100, 320,
+ /* class+opts */ NODE_CLASS_DISTORT, NODE_OPTIONS,
+ /* input sock */ cmp_node_crop_in,
+ /* output sock */ cmp_node_crop_out,
+ /* storage */ "NodeTwoXYs",
+ /* execfunc */ node_composit_exec_crop,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_crop,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
index 17d9821a5ef..01af0e1db1d 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_curves.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Björn C. Schaefer
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -123,6 +123,8 @@ bNodeType cmp_node_curve_vec= {
static bNodeSocketType cmp_node_curve_rgb_in[]= {
{ SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
{ SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f},
{ -1, 0, "" }
};
@@ -157,7 +159,7 @@ static void do_curves_fac(bNode *node, float *out, float *in, float *fac)
static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
- /* stack order input: fac, image */
+ /* stack order input: fac, image, black level, white level */
/* stack order output: image */
if(out[0]->hasoutput==0)
@@ -172,6 +174,8 @@ static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **i
CompBuf *cbuf= in[1]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
+ curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec);
+
if(in[0]->vec[0] == 1.0)
composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
else
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c
index 1eecbf3b63e..f8be69d8092 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_defocus.c
@@ -143,7 +143,7 @@ static float RI_vdC(unsigned int bits, unsigned int r)
// single channel IIR gaussian filtering
// much faster than anything else, constant time independent of width
// should extend to multichannel and make this a node, could be useful
-static void IIR_gauss(CompBuf* buf, float sigma)
+static void IIR_gauss_single(CompBuf* buf, float sigma)
{
double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
float *X, *Y, *W;
@@ -257,7 +257,8 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf,
if (camob && camob->type==OB_CAMERA) {
Camera* cam = (Camera*)camob->data;
cam_lens = cam->lens;
- cam_fdist = (cam->YF_dofdist==0.f) ? 1e10f : cam->YF_dofdist;
+ cam_fdist = dof_camera(camob);
+ if (cam_fdist==0.0) cam_fdist = 1e10f; /* if the dof is 0.0 then set it be be far away */
cam_invfdist = 1.f/cam_fdist;
}
@@ -321,8 +322,8 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf,
// bug #6656 part 1, probably when previous node_composite.c was split into separate files, it was not properly updated
// to include recent cvs commits (well, at least not defocus node), so this part was missing...
wt = aperture*128.f;
- IIR_gauss(crad, wt);
- IIR_gauss(wts, wt);
+ IIR_gauss_single(crad, wt);
+ IIR_gauss_single(wts, wt);
// bug #6656 part 2a, although foreground blur is not based anymore on closest object,
// the rescaling op below was still based on that anyway, and unlike the comment in below code,
@@ -375,8 +376,10 @@ static void defocus_blur(bNode *node, CompBuf *new, CompBuf *img, CompBuf *zbuf,
// some sort of visual feedback would be nice, or at least this text in the renderwin header
// but for now just print some info in the console every 8 scanlines.
if (((y & 7)==0) || (y==(img->y-1))) {
- printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y);
- fflush(stdout);
+ if(G.background==0) {
+ printf("\rdefocus: Processing Line %d of %d ... ", y+1, img->y);
+ fflush(stdout);
+ }
}
// esc set by main calling process
if(node->exec & NODE_BREAK)
@@ -776,9 +779,7 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in,
// if image not valid type or fstop==infinite (128), nothing to do, pass in to out
if (((img->type!=CB_RGBA) && (img->type!=CB_VAL)) || ((nqd->no_zbuf==0) && (nqd->fstop==128.f))) {
- new = alloc_compbuf(img->x, img->y, img->type, 0);
- new->rect = img->rect;
- out[0]->data = new;
+ out[0]->data = pass_on_compbuf(img);
return;
}
@@ -797,16 +798,22 @@ static void node_composit_exec_defocus(void *data, bNode *node, bNodeStack **in,
// ok, process
old = img;
if (nqd->gamco) {
- // gamma correct, blender func is simplified, fixed value & RGBA only, should make user param
+ // gamma correct, blender func is simplified, fixed value & RGBA only,
+ // should make user param. also depremul and premul afterwards, gamma
+ // correction can't work with premul alpha
old = dupalloc_compbuf(img);
+ premul_compbuf(old, 1);
gamma_correct_compbuf(old, 0);
+ premul_compbuf(old, 0);
}
new = alloc_compbuf(old->x, old->y, old->type, 1);
defocus_blur(node, new, old, zbuf_use, in[1]->vec[0]*nqd->scale);
if (nqd->gamco) {
+ premul_compbuf(new, 1);
gamma_correct_compbuf(new, 1);
+ premul_compbuf(new, 0);
free_compbuf(old);
}
if(node->exec & NODE_BREAK) {
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c
new file mode 100644
index 00000000000..27f535186db
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_directionalblur.c
@@ -0,0 +1,143 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Alfredo de Greef (eeshlo)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+static bNodeSocketType cmp_node_dblur_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f, 0.f, 1.f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType cmp_node_dblur_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static CompBuf *dblur(bNode *node, CompBuf *img, int iterations, int wrap,
+ float center_x, float center_y, float dist, float angle, float spin, float zoom)
+{
+ if ((dist != 0.f) || (spin != 0.f) || (zoom != 0.f)) {
+ void (*getpix)(CompBuf*, float, float, float*) = wrap ? qd_getPixelLerpWrap : qd_getPixelLerp;
+ const float a= angle * (float)M_PI / 180.f;
+ const float itsc= 1.f / pow(2.f, (float)iterations);
+ float D;
+ float center_x_pix, center_y_pix;
+ float tx, ty;
+ float sc, rot;
+ CompBuf *tmp;
+ int i, j;
+
+ tmp= dupalloc_compbuf(img);
+
+ D= dist * sqrtf(img->x * img->x + img->y * img->y);
+ center_x_pix= center_x * img->x;
+ center_y_pix= center_y * img->y;
+
+ tx= itsc * D * cos(a);
+ ty= -itsc * D * sin(a);
+ sc= itsc * zoom;
+ rot= itsc * spin * (float)M_PI / 180.f;
+
+ /* blur the image */
+ for(i= 0; i < iterations; ++i) {
+ const float cs= cos(rot), ss= sin(rot);
+ const float isc= 1.f / (1.f + sc);
+ unsigned int x, y;
+ float col[4]= {0,0,0,0};
+
+ for(y= 0; y < img->y; ++y) {
+ const float v= isc * (y - center_y_pix) + ty;
+
+ for(x= 0; x < img->x; ++x) {
+ const float u= isc * (x - center_x_pix) + tx;
+ unsigned int p= (x + y * img->x) * img->type;
+
+ getpix(tmp, cs * u + ss * v + center_x_pix, cs * v - ss * u + center_y_pix, col);
+
+ /* mix img and transformed tmp */
+ for(j= 0; j < 4; ++j)
+ img->rect[p + j]= AVG2(img->rect[p + j], col[j]);
+ }
+ }
+
+ /* copy img to tmp */
+ if(i != (iterations - 1))
+ memcpy(tmp->rect, img->rect, sizeof(float) * img->x * img->y * img->type);
+
+ /* double transformations */
+ tx *= 2.f, ty *= 2.f;
+ sc *= 2.f, rot *= 2.f;
+
+ if(node->exec & NODE_BREAK) break;
+ }
+
+ free_compbuf(tmp);
+ }
+
+ return img;
+}
+
+static void node_composit_exec_dblur(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ NodeDBlurData *ndbd= node->storage;
+ CompBuf *new, *img= in[0]->data;
+
+ if((img == NULL) || (out[0]->hasoutput == 0)) return;
+
+ if (img->type != CB_RGBA)
+ new = typecheck_compbuf(img, CB_RGBA);
+ else
+ new = dupalloc_compbuf(img);
+
+ out[0]->data= dblur(node, new, ndbd->iter, ndbd->wrap, ndbd->center_x, ndbd->center_y, ndbd->distance, ndbd->angle, ndbd->spin, ndbd->zoom);
+}
+
+static void node_composit_init_dblur(bNode* node)
+{
+ NodeDBlurData *ndbd= MEM_callocN(sizeof(NodeDBlurData), "node dblur data");
+ node->storage= ndbd;
+ ndbd->center_x= 0.5;
+ ndbd->center_y= 0.5;
+}
+
+bNodeType cmp_node_dblur = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_DBLUR,
+ /* name */ "Directional Blur",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS,
+ /* input sock */ cmp_node_dblur_in,
+ /* output sock */ cmp_node_dblur_out,
+ /* storage */ "NodeDBlurData",
+ /* execfunc */ node_composit_exec_dblur,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_dblur,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c
index 0ec15d9eb77..67b04750056 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_displace.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_displace.c
@@ -47,7 +47,7 @@ static bNodeSocketType cmp_node_displace_out[]= {
static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *veccol, float *xscale, float *yscale)
{
ImBuf *ibuf;
- int x, y, sx, sy;
+ int x, y, vx, vy, sx, sy;
float dx=0.0, dy=0.0;
float dspx, dspy;
float uv[2];
@@ -72,16 +72,21 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float
/* the x-xrad stuff is a bit weird, but i seem to need it otherwise
* my returned pixels are offset weirdly */
vp = compbuf_get_pixel(vecbuf, veccol, x-vecbuf->xrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad);
+
+ /* this happens in compbuf_get_pixel, need to make sure the following
+ * check takes them into account */
+ vx= x-vecbuf->xof;
+ vy= y-vecbuf->yof;
/* find the new displaced co-ords, also correcting for translate offset */
- dspx = x - (*xscale * vp[0]);
- dspy = y - (*yscale * vp[1]);
+ dspx = vx - (*xscale * vp[0]);
+ dspy = vy - (*yscale * vp[1]);
/* convert image space to 0.0-1.0 UV space for sampling, correcting for translate offset */
uv[0] = dspx / (float)sx;
uv[1] = dspy / (float)sy;
-
- if(x>0 && x< vecbuf->x-1 && y>0 && y< vecbuf->y-1) {
+
+ if(vx>0 && vx< vecbuf->x-1 && vy>0 && vy< vecbuf->y-1) {
vpnext = vp+row;
vpprev = vp-row;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_glare.c b/source/blender/nodes/intern/CMP_nodes/CMP_glare.c
new file mode 100644
index 00000000000..9ab4038607f
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_glare.c
@@ -0,0 +1,502 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Alfredo de Greef (eeshlo)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+static bNodeSocketType cmp_node_glare_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_glare_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+
+// mix two images, src buffer does not have to be same size,
+static void mixImages(CompBuf *dst, CompBuf *src, float mix)
+{
+ int x, y;
+ fRGB c1, c2, *dcolp, *scolp;
+ const float mf = 2.f - 2.f*fabsf(mix - 0.5f);
+ if ((dst->x == src->x) && (dst->y == src->y)) {
+ for (y=0; y<dst->y; y++) {
+ dcolp = (fRGB*)&dst->rect[y*dst->x*dst->type];
+ scolp = (fRGB*)&src->rect[y*dst->x*dst->type];
+ for (x=0; x<dst->x; x++) {
+ fRGB_copy(c1, dcolp[x]);
+ fRGB_copy(c2, scolp[x]);
+ c1[0] += mix*(c2[0] - c1[0]);
+ c1[1] += mix*(c2[1] - c1[1]);
+ c1[2] += mix*(c2[2] - c1[2]);
+ if (c1[0] < 0.f) c1[0] = 0.f;
+ if (c1[1] < 0.f) c1[1] = 0.f;
+ if (c1[2] < 0.f) c1[2] = 0.f;
+ fRGB_mult(c1, mf);
+ fRGB_copy(dcolp[x], c1);
+ }
+ }
+ }
+ else {
+ float xr = src->x / (float)dst->x;
+ float yr = src->y / (float)dst->y;
+ for (y=0; y<dst->y; y++) {
+ dcolp = (fRGB*)&dst->rect[y*dst->x*dst->type];
+ for (x=0; x<dst->x; x++) {
+ fRGB_copy(c1, dcolp[x]);
+ qd_getPixelLerp(src, (x + 0.5f)*xr - 0.5f, (y + 0.5f)*yr - 0.5f, c2);
+ c1[0] += mix*(c2[0] - c1[0]);
+ c1[1] += mix*(c2[1] - c1[1]);
+ c1[2] += mix*(c2[2] - c1[2]);
+ if (c1[0] < 0.f) c1[0] = 0.f;
+ if (c1[1] < 0.f) c1[1] = 0.f;
+ if (c1[2] < 0.f) c1[2] = 0.f;
+ fRGB_mult(c1, mf);
+ fRGB_copy(dcolp[x], c1);
+ }
+ }
+ }
+}
+
+
+// adds src to dst image, must be of same size
+static void addImage(CompBuf* dst, CompBuf* src, float scale)
+{
+ if ((dst->x == src->x) && (dst->y == src->y)) {
+ int p = dst->x*dst->y*dst->type;
+ float *dcol = dst->rect, *scol = src->rect;
+ while (p--) *dcol++ += *scol++ * scale;
+ }
+}
+
+
+// returns possibly downscaled copy of all pixels above threshold
+static CompBuf* BTP(CompBuf* src, float threshold, int scaledown)
+{
+ int x, y;
+ CompBuf* bsrc = qd_downScaledCopy(src, scaledown);
+ float* cr = bsrc->rect;
+ for (y=0; y<bsrc->y; ++y)
+ for (x=0; x<bsrc->x; ++x, cr+=4) {
+ if ((0.212671f*cr[0] + 0.71516f*cr[1] + 0.072169f*cr[2]) >= threshold) {
+ cr[0] -= threshold, cr[1] -= threshold, cr[2] -= threshold;
+ cr[0] = MAX2(cr[0], 0.f);
+ cr[1] = MAX2(cr[1], 0.f);
+ cr[2] = MAX2(cr[2], 0.f);
+ }
+ else cr[0] = cr[1] = cr[2] = 0.f;
+ }
+ return bsrc;
+}
+
+//--------------------------------------------------------------------------------------------
+// simple 4-point star filter
+
+static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
+{
+ int x, y, i, xm, xp, ym, yp;
+ float c[4] = {0,0,0,0}, tc[4] = {0,0,0,0};
+ CompBuf *tbuf1, *tbuf2, *tsrc;
+ const float f1 = 1.f - ndg->fade, f2 = (1.f - f1)*0.5f;
+ //const float t3 = ndg->threshold*3.f;
+ const float sc = (float)(1 << ndg->quality);
+ const float isc = 1.f/sc;
+
+ tsrc = BTP(src, ndg->threshold, (int)sc);
+
+ tbuf1 = dupalloc_compbuf(tsrc);
+ tbuf2 = dupalloc_compbuf(tsrc);
+
+ for (i=0; i<ndg->iter; i++) {
+ // (x || x-1, y-1) to (x || x+1, y+1)
+ // F
+ for (y=0; y<tbuf1->y; y++) {
+ ym = y - i;
+ yp = y + i;
+ for (x=0; x<tbuf1->x; x++) {
+ xm = x - i;
+ xp = x + i;
+ qd_getPixel(tbuf1, x, y, c);
+ fRGB_mult(c, f1);
+ qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
+ fRGB_madd(c, tc, f2);
+ qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
+ fRGB_madd(c, tc, f2);
+ qd_setPixel(tbuf1, x, y, c);
+ }
+ }
+ // B
+ for (y=tbuf1->y-1; y>=0; y--) {
+ ym = y - i;
+ yp = y + i;
+ for (x=tbuf1->x-1; x>=0; x--) {
+ xm = x - i;
+ xp = x + i;
+ qd_getPixel(tbuf1, x, y, c);
+ fRGB_mult(c, f1);
+ qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
+ fRGB_madd(c, tc, f2);
+ qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
+ fRGB_madd(c, tc, f2);
+ qd_setPixel(tbuf1, x, y, c);
+ }
+ }
+ // (x-1, y || y+1) to (x+1, y || y-1)
+ // F
+ for (y=0; y<tbuf2->y; y++) {
+ ym = y - i;
+ yp = y + i;
+ for (x=0; x<tbuf2->x; x++) {
+ xm = x - i;
+ xp = x + i;
+ qd_getPixel(tbuf2, x, y, c);
+ fRGB_mult(c, f1);
+ qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
+ fRGB_madd(c, tc, f2);
+ qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
+ fRGB_madd(c, tc, f2);
+ qd_setPixel(tbuf2, x, y, c);
+ }
+ }
+ // B
+ for (y=tbuf2->y-1; y>=0; y--) {
+ ym = y - i;
+ yp = y + i;
+ for (x=tbuf2->x-1; x>=0; x--) {
+ xm = x - i;
+ xp = x + i;
+ qd_getPixel(tbuf2, x, y, c);
+ fRGB_mult(c, f1);
+ qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
+ fRGB_madd(c, tc, f2);
+ qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
+ fRGB_madd(c, tc, f2);
+ qd_setPixel(tbuf2, x, y, c);
+ }
+ }
+ }
+
+ for (y=0; y<tbuf1->y; ++y)
+ for (x=0; x<tbuf1->x; ++x) {
+ unsigned int p = (x + y*tbuf1->x)*tbuf1->type;
+ tbuf1->rect[p] += tbuf2->rect[p];
+ tbuf1->rect[p+1] += tbuf2->rect[p+1];
+ tbuf1->rect[p+2] += tbuf2->rect[p+2];
+ }
+
+ for (y=0; y<dst->y; ++y) {
+ const float m = 0.5f + 0.5f*ndg->mix;
+ for (x=0; x<dst->x; ++x) {
+ unsigned int p = (x + y*dst->x)*dst->type;
+ qd_getPixelLerp(tbuf1, x*isc, y*isc, tc);
+ dst->rect[p] = src->rect[p] + m*(tc[0] - src->rect[p]);
+ dst->rect[p+1] = src->rect[p+1] + m*(tc[1] - src->rect[p+1]);
+ dst->rect[p+2] = src->rect[p+2] + m*(tc[2] - src->rect[p+2]);
+ }
+ }
+
+ free_compbuf(tbuf1);
+ free_compbuf(tbuf2);
+ free_compbuf(tsrc);
+}
+
+//--------------------------------------------------------------------------------------------
+// streak filter
+
+static void streaks(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
+{
+ CompBuf *bsrc, *tsrc, *tdst, *sbuf;
+ int x, y, n;
+ unsigned int nump=0;
+ fRGB c1, c2, c3, c4;
+ float a, ang = 360.f/(float)ndg->angle;
+
+ bsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
+ tsrc = dupalloc_compbuf(bsrc); // sample from buffer
+ tdst = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1); // sample to buffer
+ sbuf = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1); // streak sum buffer
+
+
+ for (a=0.f; a<360.f; a+=ang) {
+ const float an = (a + (float)ndg->angle_ofs)*(float)M_PI/180.f;
+ const float vx = cos((double)an), vy = sin((double)an);
+ for (n=0; n<ndg->iter; ++n) {
+ const float p4 = pow(4.0, (double)n);
+ const float vxp = vx*p4, vyp = vy*p4;
+ const float wt = pow((double)ndg->fade, (double)p4);
+ const float cmo = 1.f - pow((double)ndg->colmod, (double)n+1); // colormodulation amount relative to current pass
+ float* tdstcol = tdst->rect;
+ for (y=0; y<tsrc->y; ++y) {
+ for (x=0; x<tsrc->x; ++x, tdstcol+=4) {
+ // first pass no offset, always same for every pass, exact copy,
+ // otherwise results in uneven brightness, only need once
+ if (n==0) qd_getPixel(tsrc, x, y, c1); else c1[0]=c1[1]=c1[2]=0;
+ qd_getPixelLerp(tsrc, x + vxp, y + vyp, c2);
+ qd_getPixelLerp(tsrc, x + vxp*2.f, y + vyp*2.f, c3);
+ qd_getPixelLerp(tsrc, x + vxp*3.f, y + vyp*3.f, c4);
+ // modulate color to look vaguely similar to a color spectrum
+ fRGB_rgbmult(c2, 1.f, cmo, cmo);
+ fRGB_rgbmult(c3, cmo, cmo, 1.f);
+ fRGB_rgbmult(c4, cmo, 1.f, cmo);
+ tdstcol[0] = 0.5f*(tdstcol[0] + c1[0] + wt*(c2[0] + wt*(c3[0] + wt*c4[0])));
+ tdstcol[1] = 0.5f*(tdstcol[1] + c1[1] + wt*(c2[1] + wt*(c3[1] + wt*c4[1])));
+ tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2])));
+ }
+ }
+ memcpy(tsrc->rect, tdst->rect, sizeof(float)*tdst->x*tdst->y*tdst->type);
+ }
+
+ addImage(sbuf, tsrc, 1.f/(float)(6 - ndg->iter));
+ memset(tdst->rect, 0, tdst->x*tdst->y*tdst->type*sizeof(float));
+ memcpy(tsrc->rect, bsrc->rect, bsrc->x*bsrc->y*bsrc->type*sizeof(float));
+ nump++;
+ }
+
+ mixImages(dst, sbuf, 0.5f + 0.5f*ndg->mix);
+
+ free_compbuf(tsrc);
+ free_compbuf(tdst);
+ free_compbuf(sbuf);
+ free_compbuf(bsrc);
+}
+
+
+//--------------------------------------------------------------------------------------------
+// Ghosts (lensflare)
+
+static float smoothMask(float x, float y)
+{
+ float t;
+ x = 2.f*x - 1.f, y = 2.f*y - 1.f;
+ if ((t = 1.f - sqrtf(x*x + y*y)) <= 0.f) return 0.f;
+ return t;
+}
+
+static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
+{
+ // colormodulation and scale factors (cm & scalef) for 16 passes max: 64
+ int x, y, n, p, np;
+ fRGB c, tc, cm[64];
+ float sc, isc, u, v, sm, s, t, ofs, scalef[64];
+ CompBuf *tbuf1, *tbuf2, *gbuf;
+ const float cmo = 1.f - ndg->colmod;
+ const int qt = 1 << ndg->quality;
+ const float s1 = 4.f/(float)qt, s2 = 2.f*s1;
+
+ gbuf = BTP(src, ndg->threshold, qt);
+ tbuf1 = dupalloc_compbuf(gbuf);
+ IIR_gauss(tbuf1, s1, 0, 3);
+ IIR_gauss(tbuf1, s1, 1, 3);
+ IIR_gauss(tbuf1, s1, 2, 3);
+ tbuf2 = dupalloc_compbuf(tbuf1);
+ IIR_gauss(tbuf2, s2, 0, 3);
+ IIR_gauss(tbuf2, s2, 1, 3);
+ IIR_gauss(tbuf2, s2, 2, 3);
+
+ if (ndg->iter & 1) ofs = 0.5f; else ofs = 0.f;
+ for (x=0; x<(ndg->iter*4); x++) {
+ y = x & 3;
+ cm[x][0] = cm[x][1] = cm[x][2] = 1;
+ if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo);
+ if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f);
+ if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo);
+ scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(ndg->iter*4));
+ if (x & 1) scalef[x] = -0.99f/scalef[x];
+ }
+
+ sc = 2.13;
+ isc = -0.97;
+ for (y=0; y<gbuf->y; y++) {
+ v = (float)(y+0.5f) / (float)gbuf->y;
+ for (x=0; x<gbuf->x; x++) {
+ u = (float)(x+0.5f) / (float)gbuf->x;
+ s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f;
+ qd_getPixelLerp(tbuf1, s*gbuf->x, t*gbuf->y, c);
+ sm = smoothMask(s, t);
+ fRGB_mult(c, sm);
+ s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f;
+ qd_getPixelLerp(tbuf2, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, tc);
+ sm = smoothMask(s, t);
+ fRGB_madd(c, tc, sm);
+ qd_setPixel(gbuf, x, y, c);
+ }
+ }
+
+ memset(tbuf1->rect, 0, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
+ for (n=1; n<ndg->iter; n++) {
+ for (y=0; y<gbuf->y; y++) {
+ v = (float)(y+0.5f) / (float)gbuf->y;
+ for (x=0; x<gbuf->x; x++) {
+ u = (float)(x+0.5f) / (float)gbuf->x;
+ tc[0] = tc[1] = tc[2] = 0.f;
+ for (p=0;p<4;p++) {
+ np = (n<<2) + p;
+ s = (u-0.5f)*scalef[np] + 0.5f;
+ t = (v-0.5f)*scalef[np] + 0.5f;
+ qd_getPixelLerp(gbuf, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, c);
+ fRGB_colormult(c, cm[np]);
+ sm = smoothMask(s, t)*0.25f;
+ fRGB_madd(tc, c, sm);
+ }
+ p = (x + y*tbuf1->x)*tbuf1->type;
+ tbuf1->rect[p] += tc[0];
+ tbuf1->rect[p+1] += tc[1];
+ tbuf1->rect[p+2] += tc[2];
+ }
+ }
+ memcpy(gbuf->rect, tbuf1->rect, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
+ }
+
+ free_compbuf(tbuf1);
+ free_compbuf(tbuf2);
+
+ mixImages(dst, gbuf, 0.5f + 0.5f*ndg->mix);
+ free_compbuf(gbuf);
+}
+
+//--------------------------------------------------------------------------------------------
+// Fog glow (convolution with kernel of exponential falloff)
+
+static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
+{
+ int x, y;
+ float scale, u, v, r, w, d;
+ fRGB fcol;
+ CompBuf *tsrc, *ckrn;
+ unsigned int sz = 1 << ndg->size;
+ const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f;
+
+ // temp. src image
+ tsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
+ // make the convolution kernel
+ ckrn = alloc_compbuf(sz, sz, CB_RGBA, 1);
+
+ scale = 0.25f*sqrtf(sz*sz);
+
+ for (y=0; y<sz; ++y) {
+ v = 2.f*(y / (float)sz) - 1.f;
+ for (x=0; x<sz; ++x) {
+ u = 2.f*(x / (float)sz) - 1.f;
+ r = (u*u + v*v)*scale;
+ d = -sqrtf(sqrtf(sqrtf(r)))*9.f;
+ fcol[0] = expf(d*cs_r), fcol[1] = expf(d*cs_g), fcol[2] = expf(d*cs_b);
+ // linear window good enough here, visual result counts, not scientific analysis
+ //w = (1.f-fabs(u))*(1.f-fabs(v));
+ // actually, Hanning window is ok, cos^2 for some reason is slower
+ w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI));
+ fRGB_mult(fcol, w);
+ qd_setPixel(ckrn, x, y, fcol);
+ }
+ }
+
+ convolve(tsrc, tsrc, ckrn);
+ free_compbuf(ckrn);
+ mixImages(dst, tsrc, 0.5f + 0.5f*ndg->mix);
+ free_compbuf(tsrc);
+}
+
+//--------------------------------------------------------------------------------------------
+
+static void node_composit_exec_glare(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf *new, *src, *img = in[0]->data;
+ NodeGlare* ndg = node->storage;
+
+ if ((img == NULL) || (out[0]->hasoutput == 0)) return;
+
+ if (img->type != CB_RGBA) {
+ new = typecheck_compbuf(img, CB_RGBA);
+ src = typecheck_compbuf(img, CB_RGBA);
+ } else {
+ new = dupalloc_compbuf(img);
+ src = dupalloc_compbuf(img);
+ }
+
+ {
+ int x, y;
+ for (y=0; y<new->y; ++y) {
+ fRGB* col = (fRGB*)&new->rect[y*new->x*new->type];
+ for (x=0; x<new->x; ++x) {
+ col[x][0] = MAX2(col[x][0], 0.f);
+ col[x][1] = MAX2(col[x][1], 0.f);
+ col[x][2] = MAX2(col[x][2], 0.f);
+ }
+ }
+ }
+
+ switch (ndg->type) {
+ case 0:
+ star4(ndg, new, src);
+ break;
+ case 1:
+ fglow(ndg, new, src);
+ break;
+ case 3:
+ ghosts(ndg, new, src);
+ break;
+ case 2:
+ default:
+ streaks(ndg, new, src);
+ }
+
+ free_compbuf(src);
+ out[0]->data = new;
+}
+
+static void node_composit_init_glare(bNode* node)
+{
+ NodeGlare *ndg = MEM_callocN(sizeof(NodeGlare), "node glare data");
+ ndg->quality = 1;
+ ndg->type = 2;
+ ndg->iter = 3;
+ ndg->colmod = 0.25;
+ ndg->mix = 0;
+ ndg->threshold = 1;
+ ndg->angle = 4;
+ ndg->angle_ofs = 0;
+ ndg->fade = 0.9;
+ ndg->size = 8;
+ node->storage = ndg;
+}
+
+bNodeType cmp_node_glare = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_GLARE,
+ /* name */ "Glare",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_OP_FILTER, NODE_OPTIONS,
+ /* input sock */ cmp_node_glare_in,
+ /* output sock */ cmp_node_glare_out,
+ /* storage */ "NodeGlare",
+ /* execfunc */ node_composit_exec_glare,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_glare,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c b/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c
index abb9fa98d97..a40579ac3b2 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_idMask.c
@@ -63,8 +63,25 @@ static void do_idmask(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
MEM_freeN(abuf);
}
+/* full sample version */
+static void do_idmask_fsa(CompBuf *stackbuf, CompBuf *cbuf, float idnr)
+{
+ float *rect, *rs;
+ int x;
+
+ rect= cbuf->rect;
+ rs= stackbuf->rect;
+ for(x= cbuf->x*cbuf->y - 1; x>=0; x--)
+ if(rect[x]==idnr)
+ rs[x]= 1.0f;
+
+}
+
+
static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
+ RenderData *rd= data;
+
if(out[0]->hasoutput==0)
return;
@@ -77,7 +94,10 @@ static void node_composit_exec_idmask(void *data, bNode *node, bNodeStack **in,
stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */;
- do_idmask(stackbuf, cbuf, (float)node->custom1);
+ if(rd->scemode & R_FULL_SAMPLE)
+ do_idmask_fsa(stackbuf, cbuf, (float)node->custom1);
+ else
+ do_idmask(stackbuf, cbuf, (float)node->custom1);
out[0]->data= stackbuf;
}
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_image.c b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
index 20308e968d3..be5a1d7241b 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_image.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_image.c
@@ -48,6 +48,7 @@ static bNodeSocketType cmp_node_rlayers_out[]= {
{ SOCK_RGBA, 0, "Refract", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, "Radio", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 0, "IndexOB", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 0, "Mist", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@@ -78,6 +79,21 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
stackbuf->rect= ibuf->rect_float;
}
+ /*code to respect the premul flag of images; I'm
+ not sure if this is a good idea for multilayer images,
+ since it never worked before for them.
+ if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
+ //premul the image
+ int i;
+ float *pixel = stackbuf->rect;
+
+ for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
+ pixel[0] *= pixel[3];
+ pixel[1] *= pixel[3];
+ pixel[2] *= pixel[3];
+ }
+ }
+ */
return stackbuf;
};
@@ -149,6 +165,8 @@ void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, I
out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO);
if(out[RRES_OUT_INDEXOB]->hasoutput)
out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB);
+ if(out[RRES_OUT_MIST]->hasoutput)
+ out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST);
};
@@ -184,11 +202,32 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
else {
stackbuf= node_composit_get_image(rd, ima, iuser);
- /* put image on stack */
- out[0]->data= stackbuf;
+ if (stackbuf) {
+ /*respect image premul option*/
+ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
+ int i;
+ float *pixel;
+
+ /*first duplicate stackbuf->rect, since it's just a pointer
+ to the source imbuf, and we don't want to change that.*/
+ stackbuf->rect = MEM_dupallocN(stackbuf->rect);
+
+ /*premul the image*/
+
+ pixel = stackbuf->rect;
+ for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
+ pixel[0] *= pixel[3];
+ pixel[1] *= pixel[3];
+ pixel[2] *= pixel[3];
+ }
+ }
- if(out[2]->hasoutput)
- out[2]->data= node_composit_get_zimage(node, rd);
+ /* put image on stack */
+ out[0]->data= stackbuf;
+
+ if(out[2]->hasoutput)
+ out[2]->data= node_composit_get_zimage(node, rd);
+ }
}
/* alpha and preview for both types */
@@ -205,6 +244,7 @@ static void node_composit_init_image(bNode* node)
{
ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
node->storage= iuser;
+ iuser->frames= 1;
iuser->sfra= 1;
iuser->fie_ima= 2;
iuser->ok= 1;
@@ -236,7 +276,7 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
CompBuf *buf;
int buftype= CB_VEC3;
- if(ELEM(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB))
+ if(ELEM3(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST))
buftype= CB_VAL;
else if(passcode==SCE_PASS_VECTOR)
buftype= CB_VEC4;
@@ -282,7 +322,9 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out
if(out[RRES_OUT_RADIO]->hasoutput)
out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO);
if(out[RRES_OUT_INDEXOB]->hasoutput)
- out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+ out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+ if(out[RRES_OUT_MIST]->hasoutput)
+ out[RRES_OUT_MIST]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_MIST);
};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_invert.c b/source/blender/nodes/intern/CMP_nodes/CMP_invert.c
index 1d4be2bc09f..4d8f5d63e75 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_invert.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_invert.c
@@ -1,5 +1,5 @@
/**
- * $Id: CMP_mixrgb.c,v 1.4 2007/04/04 13:58:10 jesterking Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c b/source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c
new file mode 100644
index 00000000000..5dec6115fba
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_lensdist.c
@@ -0,0 +1,192 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Alfredo de Greef (eeshlo)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+static bNodeSocketType cmp_node_lensdist_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "Distort", 0.f, 0.f, 0.f, 0.f, -0.999f, 1.f},
+ { SOCK_VALUE, 1, "Dispersion", 0.f, 0.f, 0.f, 0.f, 0.f, 1.f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_lensdist_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+
+static void lensDistort(CompBuf* dst, CompBuf* src, float kr, float kg, float kb, int jit, int proj, int fit)
+{
+ int x, y, z;
+ const float cx = 0.5f*(float)dst->x, cy = 0.5f*(float)dst->y;
+
+ if (proj) {
+ // shift
+ CompBuf* tsrc = dupalloc_compbuf(src);
+ for (z=0; z<tsrc->type; ++z)
+ IIR_gauss(tsrc, (kr+0.5f)*(kr+0.5f), z, 1);
+ kr *= 20.f;
+ for (y=0; y<dst->y; y++) {
+ fRGB* colp = (fRGB*)&dst->rect[y*dst->x*dst->type];
+ const float v = (y + 0.5f)/(float)dst->y;
+ for (x=0; x<dst->x; x++) {
+ const float u = (x + 0.5f)/(float)dst->x;
+ qd_getPixelLerpChan(tsrc, (u*dst->x + kr) - 0.5f, v*dst->y - 0.5f, 0, colp[x]);
+ if (tsrc->type == CB_VAL)
+ colp[x][1] = tsrc->rect[x + y*tsrc->x];
+ else
+ colp[x][1] = tsrc->rect[(x + y*tsrc->x)*tsrc->type + 1];
+ qd_getPixelLerpChan(tsrc, (u*dst->x - kr) - 0.5f, v*dst->y - 0.5f, 2, colp[x]+2);
+ }
+ }
+ free_compbuf(tsrc);
+ }
+ else {
+ // Spherical
+ // Scale factor to make bottom/top & right/left sides fit in window after deform
+ // so in the case of pincushion (kn < 0), corners will be outside window.
+ // Now also optionally scales image such that black areas are not visible when distort factor is positive
+ // (makes distorted corners match window corners, but really only valid if mk<=0.5)
+ const float mk = MAX3(kr, kg, kb);
+ const float sc = (fit && (mk > 0.f)) ? (1.f/(1.f + 2.f*mk)) : (1.f/(1.f + mk));
+ const float drg = 4.f*(kg - kr), dgb = 4.f*(kb - kg);
+ kr *= 4.f, kg *= 4.f, kb *= 4.f;
+
+ for (y=0; y<dst->y; y++) {
+ fRGB* colp = (fRGB*)&dst->rect[y*dst->x*dst->type];
+ const float v = sc*((y + 0.5f) - cy)/cy;
+ for (x=0; x<dst->x; x++) {
+ int dr = 0, dg = 0, db = 0;
+ float d, t, ln[6] = {0, 0, 0, 0, 0, 0};
+ fRGB c1, tc = {0, 0, 0, 0};
+ const float u = sc*((x + 0.5f) - cx)/cx;
+ int sta = 0, mid = 0, end = 0;
+ if ((t = 1.f - kr*(u*u + v*v)) >= 0.f) {
+ d = 1.f/(1.f + sqrtf(t));
+ ln[0] = (u*d + 0.5f)*dst->x - 0.5f, ln[1] = (v*d + 0.5f)*dst->y - 0.5f;
+ sta = 1;
+ }
+ if ((t = 1.f - kg*(u*u + v*v)) >= 0.f) {
+ d = 1.f/(1.f + sqrtf(t));
+ ln[2] = (u*d + 0.5f)*dst->x - 0.5f, ln[3] = (v*d + 0.5f)*dst->y - 0.5f;
+ mid = 1;
+ }
+ if ((t = 1.f - kb*(u*u + v*v)) >= 0.f) {
+ d = 1.f/(1.f + sqrtf(t));
+ ln[4] = (u*d + 0.5f)*dst->x - 0.5f, ln[5] = (v*d + 0.5f)*dst->y - 0.5f;
+ end = 1;
+ }
+
+ if (sta && mid && end) {
+ // RG
+ const int dx = ln[2] - ln[0], dy = ln[3] - ln[1];
+ const float dsf = sqrtf(dx*dx + dy*dy) + 1.f;
+ const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+ const float sd = 1.f/(float)ds;
+ for (z=0; z<ds; ++z) {
+ const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd;
+ t = 1.f - (kr + tz*drg)*(u*u + v*v);
+ d = 1.f / (1.f + sqrtf(t));
+ qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1);
+ if (src->type == CB_VAL) c1[1] = c1[2] = c1[0];
+ tc[0] += (1.f-tz)*c1[0], tc[1] += tz*c1[1];
+ dr++, dg++;
+ }
+ // GB
+ {
+ const int dx = ln[4] - ln[2], dy = ln[5] - ln[3];
+ const float dsf = sqrtf(dx*dx + dy*dy) + 1.f;
+ const int ds = (int)(jit ? ((dsf < 4.f) ? 2.f : sqrtf(dsf)) : dsf);
+ const float sd = 1.f/(float)ds;
+ for (z=0; z<ds; ++z) {
+ const float tz = ((float)z + (jit ? BLI_frand() : 0.5f))*sd;
+ t = 1.f - (kg + tz*dgb)*(u*u + v*v);
+ d = 1.f / (1.f + sqrtf(t));
+ qd_getPixelLerp(src, (u*d + 0.5f)*dst->x - 0.5f, (v*d + 0.5f)*dst->y - 0.5f, c1);
+ if (src->type == CB_VAL) c1[1] = c1[2] = c1[0];
+ tc[1] += (1.f-tz)*c1[1], tc[2] += tz*c1[2];
+ dg++, db++;
+ }
+ }
+ }
+
+ if (dr) colp[x][0] = 2.f*tc[0] / (float)dr;
+ if (dg) colp[x][1] = 2.f*tc[1] / (float)dg;
+ if (db) colp[x][2] = 2.f*tc[2] / (float)db;
+
+ }
+ }
+
+ }
+
+}
+
+
+static void node_composit_exec_lensdist(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf *new, *img = in[0]->data;
+ NodeLensDist* nld = node->storage;
+ const float k = MAX2(MIN2(in[1]->vec[0], 1.f), -0.999f);
+ // smaller dispersion range for somewhat more control
+ const float d = 0.25f*MAX2(MIN2(in[2]->vec[0], 1.f), 0.f);
+ const float kr = MAX2(MIN2((k+d), 1.f), -0.999f), kb = MAX2(MIN2((k-d), 1.f), -0.999f);
+
+ if ((img==NULL) || (out[0]->hasoutput==0)) return;
+
+ new = alloc_compbuf(img->x, img->y, CB_RGBA, 1);
+
+ lensDistort(new, img, (nld->proj ? d : kr), k, kb, nld->jit, nld->proj, nld->fit);
+
+ out[0]->data = new;
+}
+
+
+static void node_composit_init_lensdist(bNode* node)
+{
+ NodeLensDist *nld = MEM_callocN(sizeof(NodeLensDist), "node lensdist data");
+ nld->jit = nld->proj = nld->fit = 0;
+ node->storage = nld;
+}
+
+
+bNodeType cmp_node_lensdist = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_LENSDIST,
+ /* name */ "Lens Distortion",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_DISTORT, NODE_OPTIONS,
+ /* input sock */ cmp_node_lensdist_in,
+ /* output sock */ cmp_node_lensdist_out,
+ /* storage */ "NodeLensDist",
+ /* execfunc */ node_composit_exec_lensdist,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_lensdist,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
index 27d7da16a59..cf2af9bbc11 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
@@ -137,25 +137,33 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
static void node_composit_exec_math(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
- /* stack order out: bw */
- /* stack order in: col */
-
- if(out[0]->hasoutput==0)
- return;
-
- /* input no image? then only color operation */
- if(in[0]->data==NULL) {
+ CompBuf *cbuf=in[0]->data;
+ CompBuf *cbuf2=in[1]->data;
+ CompBuf *stackbuf;
+
+ /* check for inputs and outputs for early out*/
+ if(in[0]->hasinput==0 && in[1]->hasinput==0) return;
+ if(out[0]->hasoutput==0) return;
+
+ /* no image-color operation */
+ if(in[0]->data==NULL && in[1]->data==NULL) {
do_math(node, out[0]->vec, in[0]->vec, in[1]->vec);
+ return;
}
- else {
- /* make output size of input image */
- CompBuf *cbuf= in[0]->data;
- CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
-
- composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_math, CB_VAL, CB_VAL);
-
- out[0]->data= stackbuf;
+
+ /*create output based on first input */
+ if(cbuf) {
+ stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
+ }
+ /* and if it doesn't exist use the second input since we
+ know that one of them must exist at this point*/
+ else {
+ stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1);
}
+
+ /* operate in case there's valid size */
+ composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_math, CB_VAL, CB_VAL);
+ out[0]->data= stackbuf;
}
bNodeType cmp_node_math= {
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c
new file mode 100644
index 00000000000..a62e4be4015
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_normalize.c
@@ -0,0 +1,113 @@
+/**
+ * $Id: CMP_normalize.c,v 1.0 2007/03/24 06:57:29 scourage Exp $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): gsr b3d, and a very minor edit from Robert Holcomb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+
+/* **************** NORMALIZE single channel, useful for Z buffer ******************** */
+static bNodeSocketType cmp_node_normalize_in[]= {
+ { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_normalize_out[]= {
+ { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void do_normalize(bNode *node, float *out, float *src, float *min, float *mult)
+{
+ float res;
+ res = (src[0] - min[0]) * mult[0];
+ if (res > 1.0f) {
+ out[0] = 1.0f;
+ }
+ else if (res < 0.0f) {
+ out[0] = 0.0f;
+ }
+ else {
+ out[0] = res;
+ }
+}
+
+#define BLENDER_ZMAX 10000.0f
+
+static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ /* stack order in: valbuf */
+ /* stack order out: valbuf */
+ if(out[0]->hasoutput==0) return;
+
+ /* input no image? then only value operation */
+ if(in[0]->data==NULL) {
+ QUATCOPY(out[0]->vec, in[0]->vec);
+ }
+ else {
+ float min = 1.0f+BLENDER_ZMAX;
+ float max = -1.0f-BLENDER_ZMAX;
+ float mult = 1.0f;
+ float *val;
+ /* make output size of input image */
+ CompBuf *cbuf= in[0]->data;
+ int tot= cbuf->x*cbuf->y;
+ CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
+
+ for (val = cbuf->rect; tot; tot--, val++) {
+ if ((*val > max) && (*val < BLENDER_ZMAX)) {
+ max = *val;
+ }
+ if (*val < min) {
+ min = *val;
+ }
+ }
+ mult = 1.0f/(max-min);
+
+ printf("min %f max %f\n", min, max);
+
+ composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL);
+
+ out[0]->data= stackbuf;
+ }
+}
+
+bNodeType cmp_node_normalize= {
+ /* *next, *prev*/ NULL, NULL,
+ /* type code */ CMP_NODE_NORMALIZE,
+ /* name */ "Normalize",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_OP_VECTOR, NODE_OPTIONS,
+ /* input sock */ cmp_node_normalize_in,
+ /* output sock */ cmp_node_normalize_out,
+ /* storage */ "TexMapping",
+ /* execfunc */ node_composit_exec_normalize,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c b/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c
new file mode 100644
index 00000000000..4fde652c59d
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_premulkey.c
@@ -0,0 +1,77 @@
+/**
+* $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) 2006 Blender Foundation.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL LICENSE BLOCK *****
+
+*/
+
+#include "../CMP_util.h"
+
+/* **************** Premul and Key Alpha Convert ******************** */
+
+static bNodeSocketType cmp_node_premulkey_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_premulkey_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_composit_exec_premulkey(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ if(out[0]->hasoutput==0)
+ return;
+
+ if(in[0]->data) {
+ CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
+
+ stackbuf= dupalloc_compbuf(cbuf);
+ premul_compbuf(stackbuf, node->custom1 == 1);
+
+ out[0]->data = stackbuf;
+ if(cbuf != in[0]->data)
+ free_compbuf(cbuf);
+ }
+}
+
+bNodeType cmp_node_premulkey= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_PREMULKEY,
+ /* name */ "Alpha Convert",
+ /* width+range */ 140, 100, 320,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ cmp_node_premulkey_in,
+ /* output sock */ cmp_node_premulkey_out,
+ /* storage */ "",
+ /* execfunc */ node_composit_exec_premulkey,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copysotragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c
index a8477f4264e..cc6f9249495 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_scale.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_scale.c
@@ -52,6 +52,7 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b
return;
if(in[0]->data) {
+ RenderData *rd= data;
CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
ImBuf *ibuf;
int newx, newy;
@@ -60,7 +61,10 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b
newx= MAX2((int)(in[1]->vec[0]*cbuf->x), 1);
newy= MAX2((int)(in[2]->vec[0]*cbuf->y), 1);
}
- else { /* CMP_SCALE_ABSOLUTE */
+ else if(node->custom1==CMP_SCALE_SCENEPERCENT) {
+ newx = cbuf->x * (rd->size / 100.0f);
+ newy = cbuf->y * (rd->size / 100.0f);
+ } else { /* CMP_SCALE_ABSOLUTE */
newx= (int)in[1]->vec[0];
newy= (int)in[2]->vec[0];
}
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c
index 9bf9777ebe0..c0845a582d3 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_texture.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_texture.c
@@ -45,16 +45,15 @@ static bNodeSocketType cmp_node_texture_out[]= {
static void texture_procedural(CompBuf *cbuf, float *col, float xco, float yco)
{
bNode *node= cbuf->node;
- bNodeSocket *sock= node->inputs.first;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f};
int retval, type= cbuf->type;
- size= sock->next->ns.vec;
+ size= cbuf->procedural_size;
- vec[0]= size[0]*(xco + sock->ns.vec[0]);
- vec[1]= size[1]*(yco + sock->ns.vec[1]);
- vec[2]= size[2]*sock->ns.vec[2];
+ vec[0]= size[0]*(xco + cbuf->procedural_offset[0]);
+ vec[1]= size[1]*(yco + cbuf->procedural_offset[1]);
+ vec[2]= size[2]*cbuf->procedural_offset[2];
retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
@@ -89,28 +88,46 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in,
/* outputs: value, color, normal */
if(node->id) {
+ RenderData *rd= data;
+ RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); /* G.scene is WEAK! */
+ short sizex, sizey;
+
/* first make the preview image */
CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); /* alloc */
+ if (rr) {
+ sizex = rr->rectx;
+ sizey = rr->recty;
+ } else {
+ sizex = rd->xsch;
+ sizey = rd->ysch;
+ }
+
prevbuf->rect_procedural= texture_procedural;
prevbuf->node= node;
+ VECCOPY(prevbuf->procedural_offset, in[0]->vec);
+ VECCOPY(prevbuf->procedural_size, in[1]->vec);
composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
generate_preview(node, prevbuf);
free_compbuf(prevbuf);
if(out[0]->hasoutput) {
- CompBuf *stackbuf= alloc_compbuf(140, 140, CB_VAL, 1); /* alloc */
+ CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_VAL, 1); /* alloc */
stackbuf->rect_procedural= texture_procedural;
stackbuf->node= node;
+ VECCOPY(stackbuf->procedural_offset, in[0]->vec);
+ VECCOPY(stackbuf->procedural_size, in[1]->vec);
- out[0]->data= stackbuf;
+ out[0]->data= stackbuf;
}
if(out[1]->hasoutput) {
- CompBuf *stackbuf= alloc_compbuf(140, 140, CB_RGBA, 1); /* alloc */
+ CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_RGBA, 1); /* alloc */
stackbuf->rect_procedural= texture_procedural;
stackbuf->node= node;
+ VECCOPY(stackbuf->procedural_offset, in[0]->vec);
+ VECCOPY(stackbuf->procedural_size, in[1]->vec);
out[1]->data= stackbuf;
}
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c
new file mode 100644
index 00000000000..662d8e8dde9
--- /dev/null
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_tonemap.c
@@ -0,0 +1,173 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 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): Alfredo de Greef (eeshlo)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../CMP_util.h"
+
+static bNodeSocketType cmp_node_tonemap_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType cmp_node_tonemap_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+
+static float avgLogLum(CompBuf *src, float* auto_key, float* Lav, float* Cav)
+{
+ float lsum = 0;
+ int p = src->x*src->y;
+ fRGB* bc = (fRGB*)src->rect;
+ float avl, maxl = -1e10f, minl = 1e10f;
+ const float sc = 1.f/(src->x*src->y);
+ *Lav = 0.f;
+ while (p--) {
+ float L = 0.212671f*bc[0][0] + 0.71516f*bc[0][1] + 0.072169f*bc[0][2];
+ *Lav += L;
+ fRGB_add(Cav, bc[0]);
+ lsum += (float)log((double)MAX2(L, 0.0) + 1e-5);
+ maxl = (L > maxl) ? L : maxl;
+ minl = (L < minl) ? L : minl;
+ bc++;
+ }
+ *Lav *= sc;
+ fRGB_mult(Cav, sc);
+ maxl = log((double)maxl + 1e-5); minl = log((double)minl + 1e-5f); avl = lsum*sc;
+ *auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.f;
+ return exp((double)avl);
+}
+
+
+void static tonemap(NodeTonemap* ntm, CompBuf* dst, CompBuf* src)
+{
+ int x, y;
+ float dr, dg, db, al, igm = (ntm->gamma==0.f) ? 1 : (1.f / ntm->gamma);
+ float auto_key, Lav, Cav[3] = {0, 0, 0};
+
+ al = avgLogLum(src, &auto_key, &Lav, Cav);
+ al = (al == 0.f) ? 0.f : (ntm->key / al);
+
+ if (ntm->type == 1) {
+ // Reinhard/Devlin photoreceptor
+ const float f = exp((double)-ntm->f);
+ const float m = (ntm->m > 0.f) ? ntm->m : (0.3f + 0.7f*pow((double)auto_key, 1.4));
+ const float ic = 1.f - ntm->c, ia = 1.f - ntm->a;
+ if (ntm->m == 0.f) printf("tonemap node, M: %g\n", m);
+ for (y=0; y<src->y; ++y) {
+ fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type];
+ fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type];
+ for (x=0; x<src->x; ++x) {
+ const float L = 0.212671f*sp[x][0] + 0.71516f*sp[x][1] + 0.072169f*sp[x][2];
+ float I_l = sp[x][0] + ic*(L - sp[x][0]);
+ float I_g = Cav[0] + ic*(Lav - Cav[0]);
+ float I_a = I_l + ia*(I_g - I_l);
+ dp[x][0] /= (dp[x][0] + pow((double)f*I_a, (double)m));
+ I_l = sp[x][1] + ic*(L - sp[x][1]);
+ I_g = Cav[1] + ic*(Lav - Cav[1]);
+ I_a = I_l + ia*(I_g - I_l);
+ dp[x][1] /= (dp[x][1] + pow((double)f*I_a,(double)m));
+ I_l = sp[x][2] + ic*(L - sp[x][2]);
+ I_g = Cav[2] + ic*(Lav - Cav[2]);
+ I_a = I_l + ia*(I_g - I_l);
+ dp[x][2] /= (dp[x][2] + pow((double)f*I_a, (double)m));
+ }
+ }
+ return;
+ }
+
+ // Reinhard simple photographic tm (simplest, not using whitepoint var)
+ for (y=0; y<src->y; y++) {
+ fRGB* sp = (fRGB*)&src->rect[y*src->x*src->type];
+ fRGB* dp = (fRGB*)&dst->rect[y*src->x*src->type];
+ for (x=0; x<src->x; x++) {
+ fRGB_copy(dp[x], sp[x]);
+ fRGB_mult(dp[x], al);
+ dr = dp[x][0] + ntm->offset;
+ dg = dp[x][1] + ntm->offset;
+ db = dp[x][2] + ntm->offset;
+ dp[x][0] /= ((dr == 0.f) ? 1.f : dr);
+ dp[x][1] /= ((dg == 0.f) ? 1.f : dg);
+ dp[x][2] /= ((db == 0.f) ? 1.f : db);
+ if (igm != 0.f) {
+ dp[x][0] = pow((double)MAX2(dp[x][0], 0.), igm);
+ dp[x][1] = pow((double)MAX2(dp[x][1], 0.), igm);
+ dp[x][2] = pow((double)MAX2(dp[x][2], 0.), igm);
+ }
+ }
+ }
+}
+
+
+static void node_composit_exec_tonemap(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ CompBuf *new, *img = in[0]->data;
+
+ if ((img==NULL) || (out[0]->hasoutput==0)) return;
+
+ if (img->type != CB_RGBA)
+ new = typecheck_compbuf(img, CB_RGBA);
+ else
+ new = dupalloc_compbuf(img);
+
+ tonemap(node->storage, new, img);
+
+ out[0]->data = new;
+}
+
+static void node_composit_init_tonemap(bNode* node)
+{
+ NodeTonemap *ntm = MEM_callocN(sizeof(NodeTonemap), "node tonemap data");
+ ntm->type = 1;
+ ntm->key = 0.18;
+ ntm->offset = 1;
+ ntm->gamma = 1;
+ ntm->f = 0;
+ ntm->m = 0; // actual value is set according to input
+ // default a of 1 works well with natural HDR images, but not always so for cgi.
+ // Maybe should use 0 or at least lower initial value instead
+ ntm->a = 1;
+ ntm->c = 0;
+ node->storage = ntm;
+}
+
+bNodeType cmp_node_tonemap = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ CMP_NODE_TONEMAP,
+ /* name */ "Tonemap",
+ /* width+range */ 150, 120, 200,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ cmp_node_tonemap_in,
+ /* output sock */ cmp_node_tonemap_out,
+ /* storage */ "NodeTonemap",
+ /* execfunc */ node_composit_exec_tonemap,
+ /* butfunc */ NULL,
+ /* initfunc */ node_composit_init_tonemap,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c
index 29cf8f34d54..daf61609692 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_zcombine.c
@@ -45,6 +45,19 @@ static bNodeSocketType cmp_node_zcombine_out[]= {
{ -1, 0, "" }
};
+static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float *src2, float *z2)
+{
+ if(*z1 <= *z2) {
+ QUATCOPY(out, src1);
+ }
+ else {
+ QUATCOPY(out, src2);
+
+ if(node->custom1)
+ *z1= *z2;
+ }
+}
+
static void do_zcombine_mask(bNode *node, float *out, float *z1, float *z2)
{
if(*z1 > *z2) {
@@ -67,43 +80,58 @@ static void do_zcombine_add(bNode *node, float *out, float *col1, float *col2, f
static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
+ RenderData *rd= data;
+ CompBuf *cbuf= in[0]->data;
+ CompBuf *zbuf;
+
/* stack order in: col z col z */
/* stack order out: col z */
- if(out[0]->hasoutput==0)
+ if(out[0]->hasoutput==0 && out[1]->hasoutput==0)
return;
/* no input image; do nothing now */
if(in[0]->data==NULL) {
return;
}
+
+ if(out[1]->hasoutput) {
+ /* copy or make a buffer for for the first z value, here we write result in */
+ if(in[1]->data)
+ zbuf= dupalloc_compbuf(in[1]->data);
+ else {
+ float *zval;
+ int tot= cbuf->x*cbuf->y;
+
+ zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
+ for(zval= zbuf->rect; tot; tot--, zval++)
+ *zval= in[1]->vec[0];
+ }
+ /* lazy coder hack */
+ node->custom1= 1;
+ out[1]->data= zbuf;
+ }
+ else {
+ node->custom1= 0;
+ zbuf= in[1]->data;
+ }
+
+ if(rd->scemode & R_FULL_SAMPLE) {
+ /* make output size of first input image */
+ CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
+
+ composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, zbuf, in[1]->vec, in[2]->data, in[2]->vec,
+ in[3]->data, in[3]->vec, do_zcombine, CB_RGBA, CB_VAL, CB_RGBA, CB_VAL);
+
+ out[0]->data= stackbuf;
+ }
else {
/* make output size of first input image */
- CompBuf *cbuf= in[0]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
- CompBuf *zbuf, *mbuf;
+ CompBuf *mbuf;
float *fp;
int x;
char *aabuf;
- if(out[1]->hasoutput) {
- /* copy or make a buffer for for the first z value, here we write result in */
- if(in[1]->data)
- zbuf= dupalloc_compbuf(in[1]->data);
- else {
- float *zval;
- int tot= cbuf->x*cbuf->y;
-
- zbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
- for(zval= zbuf->rect; tot; tot--, zval++)
- *zval= in[1]->vec[0];
- }
- /* lazy coder hack */
- node->custom1= 1;
- }
- else {
- node->custom1= 0;
- zbuf= in[1]->data;
- }
/* make a mask based on comparison, optionally write zvalue */
mbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
@@ -131,9 +159,8 @@ static void node_composit_exec_zcombine(void *data, bNode *node, bNodeStack **in
MEM_freeN(aabuf);
out[0]->data= stackbuf;
- if(node->custom1)
- out[1]->data= zbuf;
}
+
}
bNodeType cmp_node_zcombine= {
diff --git a/source/blender/nodes/intern/CMP_nodes/Makefile b/source/blender/nodes/intern/CMP_nodes/Makefile
index f4de13f2825..3564bf9034b 100644
--- a/source/blender/nodes/intern/CMP_nodes/Makefile
+++ b/source/blender/nodes/intern/CMP_nodes/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd openbsd linux solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I../../../blenkernel
@@ -49,3 +45,4 @@ CPPFLAGS += -I../../../blenlib
CPPFLAGS += -I../../../include
CPPFLAGS += -I../../../imbuf
CPPFLAGS += -I../../../render/extern/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c
index 0c6834315aa..a2629aa396e 100644
--- a/source/blender/nodes/intern/CMP_util.c
+++ b/source/blender/nodes/intern/CMP_util.c
@@ -29,9 +29,6 @@
#include "CMP_util.h"
-
-
-
CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
{
CompBuf *cbuf= MEM_callocN(sizeof(CompBuf), "compbuf");
@@ -125,6 +122,48 @@ void print_compbuf(char *str, CompBuf *cbuf)
}
+/* used for disabling node (similar code in drawnode.c for disable line) */
+void node_compo_pass_on(bNode *node, bNodeStack **nsin, bNodeStack **nsout)
+{
+ CompBuf *valbuf= NULL, *colbuf= NULL, *vecbuf= NULL;
+ bNodeSocket *sock;
+ int a;
+
+ /* connect the first value buffer in with first value out */
+ /* connect the first RGBA buffer in with first RGBA out */
+
+ /* test the inputs */
+ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+ if(nsin[a]->data) {
+ CompBuf *cbuf= nsin[a]->data;
+ if(cbuf->type==1 && valbuf==NULL) valbuf= cbuf;
+ if(cbuf->type==3 && vecbuf==NULL) vecbuf= cbuf;
+ if(cbuf->type==4 && colbuf==NULL) colbuf= cbuf;
+ }
+ }
+
+ /* outputs */
+ if(valbuf || colbuf || vecbuf) {
+ for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+ if(nsout[a]->hasoutput) {
+ if(sock->type==SOCK_VALUE && valbuf) {
+ nsout[a]->data= pass_on_compbuf(valbuf);
+ valbuf= NULL;
+ }
+ if(sock->type==SOCK_VECTOR && vecbuf) {
+ nsout[a]->data= pass_on_compbuf(vecbuf);
+ vecbuf= NULL;
+ }
+ if(sock->type==SOCK_RGBA && colbuf) {
+ nsout[a]->data= pass_on_compbuf(colbuf);
+ colbuf= NULL;
+ }
+ }
+ }
+ }
+}
+
+
CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type)
{
CompBuf *cbuf;
@@ -577,3 +616,623 @@ void gamma_correct_compbuf(CompBuf *img, int inversed)
}
}
}
+
+void premul_compbuf(CompBuf *img, int inversed)
+{
+ float *drect;
+ int x;
+
+ if(img->type!=CB_RGBA) return;
+
+ drect= img->rect;
+ if(inversed) {
+ for(x=img->x*img->y; x>0; x--, drect+=4) {
+ if(fabs(drect[3]) < 1e-5f) {
+ drect[0]= 0.0f;
+ drect[1]= 0.0f;
+ drect[2]= 0.0f;
+ }
+ else {
+ drect[0] /= drect[3];
+ drect[1] /= drect[3];
+ drect[2] /= drect[3];
+ }
+ }
+ }
+ else {
+ for(x=img->x*img->y; x>0; x--, drect+=4) {
+ drect[0] *= drect[3];
+ drect[1] *= drect[3];
+ drect[2] *= drect[3];
+ }
+ }
+}
+
+
+
+/*
+ * 2D Fast Hartley Transform, used for convolution
+ */
+
+typedef float fREAL;
+
+// returns next highest power of 2 of x, as well it's log2 in L2
+static unsigned int nextPow2(unsigned int x, unsigned int* L2)
+{
+ unsigned int pw, x_notpow2 = x & (x-1);
+ *L2 = 0;
+ while (x>>=1) ++(*L2);
+ pw = 1 << (*L2);
+ if (x_notpow2) { (*L2)++; pw<<=1; }
+ return pw;
+}
+
+//------------------------------------------------------------------------------
+
+// from FXT library by Joerg Arndt, faster in order bitreversal
+// use: r = revbin_upd(r, h) where h = N>>1
+static unsigned int revbin_upd(unsigned int r, unsigned int h)
+{
+ while (!((r^=h)&h)) h >>= 1;
+ return r;
+}
+//------------------------------------------------------------------------------
+static void FHT(fREAL* data, unsigned int M, unsigned int inverse)
+{
+ double tt, fc, dc, fs, ds, a = M_PI;
+ fREAL t1, t2;
+ int n2, bd, bl, istep, k, len = 1 << M, n = 1;
+
+ int i, j = 0;
+ unsigned int Nh = len >> 1;
+ for (i=1;i<(len-1);++i) {
+ j = revbin_upd(j, Nh);
+ if (j>i) {
+ t1 = data[i];
+ data[i] = data[j];
+ data[j] = t1;
+ }
+ }
+
+ do {
+ fREAL* data_n = &data[n];
+
+ istep = n << 1;
+ for (k=0; k<len; k+=istep) {
+ t1 = data_n[k];
+ data_n[k] = data[k] - t1;
+ data[k] += t1;
+ }
+
+ n2 = n >> 1;
+ if (n>2) {
+ fc = dc = cos(a);
+ fs = ds = sqrt(1.0 - fc*fc); //sin(a);
+ bd = n-2;
+ for (bl=1; bl<n2; bl++) {
+ fREAL* data_nbd = &data_n[bd];
+ fREAL* data_bd = &data[bd];
+ for (k=bl; k<len; k+=istep) {
+ t1 = fc*data_n[k] + fs*data_nbd[k];
+ t2 = fs*data_n[k] - fc*data_nbd[k];
+ data_n[k] = data[k] - t1;
+ data_nbd[k] = data_bd[k] - t2;
+ data[k] += t1;
+ data_bd[k] += t2;
+ }
+ tt = fc*dc - fs*ds;
+ fs = fs*dc + fc*ds;
+ fc = tt;
+ bd -= 2;
+ }
+ }
+
+ if (n>1) {
+ for (k=n2; k<len; k+=istep) {
+ t1 = data_n[k];
+ data_n[k] = data[k] - t1;
+ data[k] += t1;
+ }
+ }
+
+ n = istep;
+ a *= 0.5;
+ } while (n<len);
+
+ if (inverse) {
+ fREAL sc = (fREAL)1 / (fREAL)len;
+ for (k=0; k<len; ++k)
+ data[k] *= sc;
+ }
+}
+//------------------------------------------------------------------------------
+/* 2D Fast Hartley Transform, Mx/My -> log2 of width/height,
+ nzp -> the row where zero pad data starts,
+ inverse -> see above */
+static void FHT2D(fREAL *data, unsigned int Mx, unsigned int My,
+ unsigned int nzp, unsigned int inverse)
+{
+ unsigned int i, j, Nx, Ny, maxy;
+ fREAL t;
+
+ Nx = 1 << Mx;
+ Ny = 1 << My;
+
+ // rows (forward transform skips 0 pad data)
+ maxy = inverse ? Ny : nzp;
+ for (j=0; j<maxy; ++j)
+ FHT(&data[Nx*j], Mx, inverse);
+
+ // transpose data
+ if (Nx==Ny) { // square
+ for (j=0; j<Ny; ++j)
+ for (i=j+1; i<Nx; ++i) {
+ unsigned int op = i + (j << Mx), np = j + (i << My);
+ t=data[op], data[op]=data[np], data[np]=t;
+ }
+ }
+ else { // rectangular
+ unsigned int k, Nym = Ny-1, stm = 1 << (Mx + My);
+ for (i=0; stm>0; i++) {
+ #define pred(k) (((k & Nym) << Mx) + (k >> My))
+ for (j=pred(i); j>i; j=pred(j));
+ if (j < i) continue;
+ for (k=i, j=pred(i); j!=i; k=j, j=pred(j), stm--)
+ { t=data[j], data[j]=data[k], data[k]=t; }
+ #undef pred
+ stm--;
+ }
+ }
+ // swap Mx/My & Nx/Ny
+ i = Nx, Nx = Ny, Ny = i;
+ i = Mx, Mx = My, My = i;
+
+ // now columns == transposed rows
+ for (j=0; j<Ny; ++j)
+ FHT(&data[Nx*j], Mx, inverse);
+
+ // finalize
+ for (j=0; j<=(Ny >> 1); j++) {
+ unsigned int jm = (Ny - j) & (Ny-1);
+ unsigned int ji = j << Mx;
+ unsigned int jmi = jm << Mx;
+ for (i=0; i<=(Nx >> 1); i++) {
+ unsigned int im = (Nx - i) & (Nx-1);
+ fREAL A = data[ji + i];
+ fREAL B = data[jmi + i];
+ fREAL C = data[ji + im];
+ fREAL D = data[jmi + im];
+ fREAL E = (fREAL)0.5*((A + D) - (B + C));
+ data[ji + i] = A - E;
+ data[jmi + i] = B + E;
+ data[ji + im] = C + E;
+ data[jmi + im] = D - E;
+ }
+ }
+
+}
+
+//------------------------------------------------------------------------------
+
+/* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height */
+static void fht_convolve(fREAL* d1, fREAL* d2, unsigned int M, unsigned int N)
+{
+ fREAL a, b;
+ unsigned int i, j, k, L, mj, mL;
+ unsigned int m = 1 << M, n = 1 << N;
+ unsigned int m2 = 1 << (M-1), n2 = 1 << (N-1);
+ unsigned int mn2 = m << (N-1);
+
+ d1[0] *= d2[0];
+ d1[mn2] *= d2[mn2];
+ d1[m2] *= d2[m2];
+ d1[m2 + mn2] *= d2[m2 + mn2];
+ for (i=1; i<m2; i++) {
+ k = m - i;
+ a = d1[i]*d2[i] - d1[k]*d2[k];
+ b = d1[k]*d2[i] + d1[i]*d2[k];
+ d1[i] = (b + a)*(fREAL)0.5;
+ d1[k] = (b - a)*(fREAL)0.5;
+ a = d1[i + mn2]*d2[i + mn2] - d1[k + mn2]*d2[k + mn2];
+ b = d1[k + mn2]*d2[i + mn2] + d1[i + mn2]*d2[k + mn2];
+ d1[i + mn2] = (b + a)*(fREAL)0.5;
+ d1[k + mn2] = (b - a)*(fREAL)0.5;
+ }
+ for (j=1; j<n2; j++) {
+ L = n - j;
+ mj = j << M;
+ mL = L << M;
+ a = d1[mj]*d2[mj] - d1[mL]*d2[mL];
+ b = d1[mL]*d2[mj] + d1[mj]*d2[mL];
+ d1[mj] = (b + a)*(fREAL)0.5;
+ d1[mL] = (b - a)*(fREAL)0.5;
+ a = d1[m2 + mj]*d2[m2 + mj] - d1[m2 + mL]*d2[m2 + mL];
+ b = d1[m2 + mL]*d2[m2 + mj] + d1[m2 + mj]*d2[m2 + mL];
+ d1[m2 + mj] = (b + a)*(fREAL)0.5;
+ d1[m2 + mL] = (b - a)*(fREAL)0.5;
+ }
+ for (i=1; i<m2; i++) {
+ k = m - i;
+ for (j=1; j<n2; j++) {
+ L = n - j;
+ mj = j << M;
+ mL = L << M;
+ a = d1[i + mj]*d2[i + mj] - d1[k + mL]*d2[k + mL];
+ b = d1[k + mL]*d2[i + mj] + d1[i + mj]*d2[k + mL];
+ d1[i + mj] = (b + a)*(fREAL)0.5;
+ d1[k + mL] = (b - a)*(fREAL)0.5;
+ a = d1[i + mL]*d2[i + mL] - d1[k + mj]*d2[k + mj];
+ b = d1[k + mj]*d2[i + mL] + d1[i + mL]*d2[k + mj];
+ d1[i + mL] = (b + a)*(fREAL)0.5;
+ d1[k + mj] = (b - a)*(fREAL)0.5;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2)
+{
+ fREAL *data1, *data2, *fp;
+ unsigned int w2, h2, hw, hh, log2_w, log2_h;
+ fRGB wt, *colp;
+ int x, y, ch;
+ int xbl, ybl, nxb, nyb, xbsz, ybsz;
+ int in2done = 0;
+
+ CompBuf* rdst = alloc_compbuf(in1->x, in1->y, in1->type, 1);
+
+ // convolution result width & height
+ w2 = 2*in2->x - 1;
+ h2 = 2*in2->y - 1;
+ // FFT pow2 required size & log2
+ w2 = nextPow2(w2, &log2_w);
+ h2 = nextPow2(h2, &log2_h);
+
+ // alloc space
+ data1 = (fREAL*)MEM_callocN(3*w2*h2*sizeof(fREAL), "convolve_fast FHT data1");
+ data2 = (fREAL*)MEM_callocN(w2*h2*sizeof(fREAL), "convolve_fast FHT data2");
+
+ // normalize convolutor
+ wt[0] = wt[1] = wt[2] = 0.f;
+ for (y=0; y<in2->y; y++) {
+ colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
+ for (x=0; x<in2->x; x++)
+ fRGB_add(wt, colp[x]);
+ }
+ if (wt[0] != 0.f) wt[0] = 1.f/wt[0];
+ if (wt[1] != 0.f) wt[1] = 1.f/wt[1];
+ if (wt[2] != 0.f) wt[2] = 1.f/wt[2];
+ for (y=0; y<in2->y; y++) {
+ colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
+ for (x=0; x<in2->x; x++)
+ fRGB_colormult(colp[x], wt);
+ }
+
+ // copy image data, unpacking interleaved RGBA into separate channels
+ // only need to calc data1 once
+
+ // block add-overlap
+ hw = in2->x >> 1;
+ hh = in2->y >> 1;
+ xbsz = (w2 + 1) - in2->x;
+ ybsz = (h2 + 1) - in2->y;
+ nxb = in1->x / xbsz;
+ if (in1->x % xbsz) nxb++;
+ nyb = in1->y / ybsz;
+ if (in1->y % ybsz) nyb++;
+ for (ybl=0; ybl<nyb; ybl++) {
+ for (xbl=0; xbl<nxb; xbl++) {
+
+ // each channel one by one
+ for (ch=0; ch<3; ch++) {
+ fREAL* data1ch = &data1[ch*w2*h2];
+
+ // only need to calc fht data from in2 once, can re-use for every block
+ if (!in2done) {
+ // in2, channel ch -> data1
+ for (y=0; y<in2->y; y++) {
+ fp = &data1ch[y*w2];
+ colp = (fRGB*)&in2->rect[y*in2->x*in2->type];
+ for (x=0; x<in2->x; x++)
+ fp[x] = colp[x][ch];
+ }
+ }
+
+ // in1, channel ch -> data2
+ memset(data2, 0, w2*h2*sizeof(fREAL));
+ for (y=0; y<ybsz; y++) {
+ int yy = ybl*ybsz + y;
+ if (yy >= in1->y) continue;
+ fp = &data2[y*w2];
+ colp = (fRGB*)&in1->rect[yy*in1->x*in1->type];
+ for (x=0; x<xbsz; x++) {
+ int xx = xbl*xbsz + x;
+ if (xx >= in1->x) continue;
+ fp[x] = colp[xx][ch];
+ }
+ }
+
+ // forward FHT
+ // zero pad data start is different for each == height+1
+ if (!in2done) FHT2D(data1ch, log2_w, log2_h, in2->y+1, 0);
+ FHT2D(data2, log2_w, log2_h, in2->y+1, 0);
+
+ // FHT2D transposed data, row/col now swapped
+ // convolve & inverse FHT
+ fht_convolve(data2, data1ch, log2_h, log2_w);
+ FHT2D(data2, log2_h, log2_w, 0, 1);
+ // data again transposed, so in order again
+
+ // overlap-add result
+ for (y=0; y<(int)h2; y++) {
+ const int yy = ybl*ybsz + y - hh;
+ if ((yy < 0) || (yy >= in1->y)) continue;
+ fp = &data2[y*w2];
+ colp = (fRGB*)&rdst->rect[yy*in1->x*in1->type];
+ for (x=0; x<(int)w2; x++) {
+ const int xx = xbl*xbsz + x - hw;
+ if ((xx < 0) || (xx >= in1->x)) continue;
+ colp[xx][ch] += fp[x];
+ }
+ }
+
+ }
+ in2done = 1;
+ }
+ }
+
+ MEM_freeN(data2);
+ MEM_freeN(data1);
+ memcpy(dst->rect, rdst->rect, sizeof(float)*dst->x*dst->y*dst->type);
+ free_compbuf(rdst);
+}
+
+
+/*
+ *
+ * Utility functions qd_* should probably be intergrated better with other functions here.
+ *
+ */
+// sets fcol to pixelcolor at (x, y)
+void qd_getPixel(CompBuf* src, int x, int y, float* col)
+{
+ if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
+ float* bc = &src->rect[(x + y*src->x)*src->type];
+ col[0] = bc[0], col[1] = bc[1], col[2] = bc[2];
+ }
+ else col[0] = col[1] = col[2] = 0.f;
+}
+
+// sets pixel (x, y) to color col
+void qd_setPixel(CompBuf* src, int x, int y, float* col)
+{
+ if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
+ float* bc = &src->rect[(x + y*src->x)*src->type];
+ bc[0] = col[0], bc[1] = col[1], bc[2] = col[2];
+ }
+}
+
+// adds fcol to pixelcolor (x, y)
+void qd_addPixel(CompBuf* src, int x, int y, float* col)
+{
+ if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
+ float* bc = &src->rect[(x + y*src->x)*src->type];
+ bc[0] += col[0], bc[1] += col[1], bc[2] += col[2];
+ }
+}
+
+// multiplies pixel by factor value f
+void qd_multPixel(CompBuf* src, int x, int y, float f)
+{
+ if ((x >= 0) && (x < src->x) && (y >= 0) && (y < src->y)) {
+ float* bc = &src->rect[(x + y*src->x)*src->type];
+ bc[0] *= f, bc[1] *= f, bc[2] *= f;
+ }
+}
+
+// bilinear interpolation with wraparound
+void qd_getPixelLerpWrap(CompBuf* src, float u, float v, float* col)
+{
+ const float ufl = floor(u), vfl = floor(v);
+ const int nx = (int)ufl % src->x, ny = (int)vfl % src->y;
+ const int x1 = (nx < 0) ? (nx + src->x) : nx;
+ const int y1 = (ny < 0) ? (ny + src->y) : ny;
+ const int x2 = (x1 + 1) % src->x, y2 = (y1 + 1) % src->y;
+ const float* c00 = &src->rect[(x1 + y1*src->x)*src->type];
+ const float* c10 = &src->rect[(x2 + y1*src->x)*src->type];
+ const float* c01 = &src->rect[(x1 + y2*src->x)*src->type];
+ const float* c11 = &src->rect[(x2 + y2*src->x)*src->type];
+ const float uf = u - ufl, vf = v - vfl;
+ const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
+ col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
+ if (src->type != CB_VAL) {
+ col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
+ col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
+ col[3] = w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
+ }
+}
+
+// as above, without wrap around
+void qd_getPixelLerp(CompBuf* src, float u, float v, float* col)
+{
+ const float ufl = floor(u), vfl = floor(v);
+ const int x1 = (int)ufl, y1 = (int)vfl;
+ const int x2 = (int)ceil(u), y2 = (int)ceil(v);
+ if ((x2 >= 0) && (y2 >= 0) && (x1 < src->x) && (y1 < src->y)) {
+ const float B[4] = {0,0,0,0};
+ const int ox1 = (x1 < 0), oy1 = (y1 < 0), ox2 = (x2 >= src->x), oy2 = (y2 >= src->y);
+ const float* c00 = (ox1 || oy1) ? B : &src->rect[(x1 + y1*src->x)*src->type];
+ const float* c10 = (ox2 || oy1) ? B : &src->rect[(x2 + y1*src->x)*src->type];
+ const float* c01 = (ox1 || oy2) ? B : &src->rect[(x1 + y2*src->x)*src->type];
+ const float* c11 = (ox2 || oy2) ? B : &src->rect[(x2 + y2*src->x)*src->type];
+ const float uf = u - ufl, vf = v - vfl;
+ const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
+ col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
+ if (src->type != CB_VAL) {
+ col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
+ col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
+ col[3] = w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
+ }
+ }
+ else col[0] = col[1] = col[2] = col[3] = 0.f;
+}
+
+// as above, sampling only one channel
+void qd_getPixelLerpChan(CompBuf* src, float u, float v, int chan, float* out)
+{
+ const float ufl = floor(u), vfl = floor(v);
+ const int x1 = (int)ufl, y1 = (int)vfl;
+ const int x2 = (int)ceil(u), y2 = (int)ceil(v);
+ if (chan >= src->type) chan = 0;
+ if ((x2 >= 0) && (y2 >= 0) && (x1 < src->x) && (y1 < src->y)) {
+ const float B[4] = {0,0,0,0};
+ const int ox1 = (x1 < 0), oy1 = (y1 < 0), ox2 = (x2 >= src->x), oy2 = (y2 >= src->y);
+ const float* c00 = (ox1 || oy1) ? B : &src->rect[(x1 + y1*src->x)*src->type + chan];
+ const float* c10 = (ox2 || oy1) ? B : &src->rect[(x2 + y1*src->x)*src->type + chan];
+ const float* c01 = (ox1 || oy2) ? B : &src->rect[(x1 + y2*src->x)*src->type + chan];
+ const float* c11 = (ox2 || oy2) ? B : &src->rect[(x2 + y2*src->x)*src->type + chan];
+ const float uf = u - ufl, vf = v - vfl;
+ const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
+ out[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
+ }
+ else *out = 0.f;
+}
+
+
+CompBuf* qd_downScaledCopy(CompBuf* src, int scale)
+{
+ CompBuf* fbuf;
+ if (scale <= 1)
+ fbuf = dupalloc_compbuf(src);
+ else {
+ int nw = src->x/scale, nh = src->y/scale;
+ if ((2*(src->x % scale)) > scale) nw++;
+ if ((2*(src->y % scale)) > scale) nh++;
+ fbuf = alloc_compbuf(nw, nh, src->type, 1);
+ {
+ int x, y, xx, yy, sx, sy, mx, my;
+ float colsum[4];
+ float fscale = 1.f/(float)(scale*scale);
+ for (y=0; y<nh; y++) {
+ fRGB* fcolp = (fRGB*)&fbuf->rect[y*fbuf->x*fbuf->type];
+ yy = y*scale;
+ my = yy + scale;
+ if (my > src->y) my = src->y;
+ for (x=0; x<nw; x++) {
+ xx = x*scale;
+ mx = xx + scale;
+ if (mx > src->x) mx = src->x;
+ colsum[0] = colsum[1] = colsum[2] = 0.f;
+ for (sy=yy; sy<my; sy++) {
+ fRGB* scolp = (fRGB*)&src->rect[sy*src->x*src->type];
+ for (sx=xx; sx<mx; sx++)
+ fRGB_add(colsum, scolp[sx]);
+ }
+ fRGB_mult(colsum, fscale);
+ fRGB_copy(fcolp[x], colsum);
+ }
+ }
+ }
+ }
+ return fbuf;
+}
+
+// fast g.blur, per channel
+// xy var. bits 1 & 2 ca be used to blur in x or y direction separately
+void IIR_gauss(CompBuf* src, float sigma, int chan, int xy)
+{
+ double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
+ float *X, *Y, *W;
+ int i, x, y, sz;
+
+ // <0.5 not valid, though can have a possibly useful sort of sharpening effect
+ if (sigma < 0.5) return;
+
+ if ((xy < 1) || (xy > 3)) xy = 3;
+
+ // see "Recursive Gabor Filtering" by Young/VanVliet
+ // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
+ if (sigma >= 3.556)
+ q = 0.9804*(sigma - 3.556) + 2.5091;
+ else // sigma >= 0.5
+ q = (0.0561*sigma + 0.5784)*sigma - 0.2568;
+ q2 = q*q;
+ sc = (1.1668 + q)*(3.203729649 + (2.21566 + q)*q);
+ // no gabor filtering here, so no complex multiplies, just the regular coefs.
+ // all negated here, so as not to have to recalc Triggs/Sdika matrix
+ cf[1] = q*(5.788961737 + (6.76492 + 3.0*q)*q)/ sc;
+ cf[2] = -q2*(3.38246 + 3.0*q)/sc;
+ // 0 & 3 unchanged
+ cf[3] = q2*q/sc;
+ cf[0] = 1.0 - cf[1] - cf[2] - cf[3];
+
+ // Triggs/Sdika border corrections,
+ // it seems to work, not entirely sure if it is actually totally correct,
+ // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
+ // found one other implementation by Cristoph Lampert,
+ // but neither seem to be quite the same, result seems to be ok sofar anyway.
+ // Extra scale factor here to not have to do it in filter,
+ // though maybe this had something to with the precision errors
+ sc = cf[0]/((1.0 + cf[1] - cf[2] + cf[3])*(1.0 - cf[1] - cf[2] - cf[3])*(1.0 + cf[2] + (cf[1] - cf[3])*cf[3]));
+ tsM[0] = sc*(-cf[3]*cf[1] + 1.0 - cf[3]*cf[3] - cf[2]);
+ tsM[1] = sc*((cf[3] + cf[1])*(cf[2] + cf[3]*cf[1]));
+ tsM[2] = sc*(cf[3]*(cf[1] + cf[3]*cf[2]));
+ tsM[3] = sc*(cf[1] + cf[3]*cf[2]);
+ tsM[4] = sc*(-(cf[2] - 1.0)*(cf[2] + cf[3]*cf[1]));
+ tsM[5] = sc*(-(cf[3]*cf[1] + cf[3]*cf[3] + cf[2] - 1.0)*cf[3]);
+ tsM[6] = sc*(cf[3]*cf[1] + cf[2] + cf[1]*cf[1] - cf[2]*cf[2]);
+ tsM[7] = sc*(cf[1]*cf[2] + cf[3]*cf[2]*cf[2] - cf[1]*cf[3]*cf[3] - cf[3]*cf[3]*cf[3] - cf[3]*cf[2] + cf[3]);
+ tsM[8] = sc*(cf[3]*(cf[1] + cf[3]*cf[2]));
+
+#define YVV(L)\
+{\
+ W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0];\
+ W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0];\
+ W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0];\
+ for (i=3; i<L; i++)\
+ W[i] = cf[0]*X[i] + cf[1]*W[i-1] + cf[2]*W[i-2] + cf[3]*W[i-3];\
+ tsu[0] = W[L-1] - X[L-1];\
+ tsu[1] = W[L-2] - X[L-1];\
+ tsu[2] = W[L-3] - X[L-1];\
+ tsv[0] = tsM[0]*tsu[0] + tsM[1]*tsu[1] + tsM[2]*tsu[2] + X[L-1];\
+ tsv[1] = tsM[3]*tsu[0] + tsM[4]*tsu[1] + tsM[5]*tsu[2] + X[L-1];\
+ tsv[2] = tsM[6]*tsu[0] + tsM[7]*tsu[1] + tsM[8]*tsu[2] + X[L-1];\
+ Y[L-1] = cf[0]*W[L-1] + cf[1]*tsv[0] + cf[2]*tsv[1] + cf[3]*tsv[2];\
+ Y[L-2] = cf[0]*W[L-2] + cf[1]*Y[L-1] + cf[2]*tsv[0] + cf[3]*tsv[1];\
+ Y[L-3] = cf[0]*W[L-3] + cf[1]*Y[L-2] + cf[2]*Y[L-1] + cf[3]*tsv[0];\
+ for (i=L-4; i>=0; i--)\
+ Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3];\
+}
+
+ // intermediate buffers
+ sz = MAX2(src->x, src->y);
+ X = MEM_callocN(sz*sizeof(float), "IIR_gauss X buf");
+ Y = MEM_callocN(sz*sizeof(float), "IIR_gauss Y buf");
+ W = MEM_callocN(sz*sizeof(float), "IIR_gauss W buf");
+ if (xy & 1) { // H
+ for (y=0; y<src->y; ++y) {
+ const int yx = y*src->x;
+ for (x=0; x<src->x; ++x)
+ X[x] = src->rect[(x + yx)*src->type + chan];
+ YVV(src->x);
+ for (x=0; x<src->x; ++x)
+ src->rect[(x + yx)*src->type + chan] = Y[x];
+ }
+ }
+ if (xy & 2) { // V
+ for (x=0; x<src->x; ++x) {
+ for (y=0; y<src->y; ++y)
+ X[y] = src->rect[(x + y*src->x)*src->type + chan];
+ YVV(src->y);
+ for (y=0; y<src->y; ++y)
+ src->rect[(x + y*src->x)*src->type + chan] = Y[y];
+ }
+ }
+
+ MEM_freeN(X);
+ MEM_freeN(W);
+ MEM_freeN(Y);
+#undef YVV
+}
+
diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h
index 515980bc563..0d7bda0604c 100644
--- a/source/blender/nodes/intern/CMP_util.h
+++ b/source/blender/nodes/intern/CMP_util.h
@@ -60,6 +60,7 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "BKE_library.h"
+#include "BKE_object.h"
#include "../CMP_node.h"
#include "node_util.h"
@@ -106,6 +107,7 @@ typedef struct CompBuf {
int xof, yof; /* relative to center of target image */
void (*rect_procedural)(struct CompBuf *, float *, float, float);
+ float procedural_size[3], procedural_offset[3];
bNode *node; /* only in use for procedural bufs */
struct CompBuf *next, *prev; /* for pass-on, works nicer than reference counting */
@@ -131,6 +133,7 @@ CompBuf *dupalloc_compbuf(CompBuf *cbuf);
CompBuf *pass_on_compbuf(CompBuf *cbuf);
void free_compbuf(CompBuf *cbuf);
void print_compbuf(char *str, CompBuf *cbuf);
+void node_compo_pass_on(struct bNode *node, struct bNodeStack **nsin, struct bNodeStack **nsout);
CompBuf *get_cropped_compbuf(rcti *drect, float *rectf, int rectx, int recty, int type);
CompBuf *scalefast_compbuf(CompBuf *inbuf, int newx, int newy);
@@ -175,7 +178,47 @@ void do_hsva_to_rgba(bNode *node, float *out, float *in);
void do_ycca_to_rgba(bNode *node, float *out, float *in);
void gamma_correct_compbuf(CompBuf *img, int inversed);
+void premul_compbuf(CompBuf *img, int inversed);
+void convolve(CompBuf* dst, CompBuf* in1, CompBuf* in2);
extern void node_ID_title_cb(void *node_v, void *unused_v);
+
+/* utility functions used by glare, tonemap and lense distortion */
+/* soms macros for color handling */
+typedef float fRGB[4];
+/* clear color */
+#define fRGB_clear(c) { c[0]=c[1]=c[2]=0.f; }
+/* copy c2 to c1 */
+#define fRGB_copy(c1, c2) { c1[0]=c2[0]; c1[1]=c2[1]; c1[2]=c2[2]; }
+/* add c2 to c1 */
+#define fRGB_add(c1, c2) { c1[0]+=c2[0]; c1[1]+=c2[1]; c1[2]+=c2[2]; }
+/* subtract c2 from c1 */
+#define fRGB_sub(c1, c2) { c1[0]-=c2[0]; c1[1]-=c2[1]; c1[2]-=c2[2]; }
+/* multiply c by float value s */
+#define fRGB_mult(c, s) { c[0]*=s; c[1]*=s; c[2]*=s; }
+/* multiply c2 by s and add to c1 */
+#define fRGB_madd(c1, c2, s) { c1[0]+=c2[0]*s; c1[1]+=c2[1]*s; c1[2]+=c2[2]*s; }
+/* multiply c2 by color c1 */
+#define fRGB_colormult(c, cs) { c[0]*=cs[0]; c[1]*=cs[1]; c[2]*=cs[2]; }
+/* multiply c2 by color c3 and add to c1 */
+#define fRGB_colormadd(c1, c2, c3) { c1[0]+=c2[0]*c3[0]; c1[1]+=c2[1]*c3[1]; c1[2]+=c2[2]*c3[2]; }
+/* multiply c2 by color rgb, rgb as separate arguments */
+#define fRGB_rgbmult(c, r, g, b) { c[0]*=(r); c[1]*=(g); c[2]*=(b); }
+/* swap colors c1 & c2 */
+#define fRGB_swap(c1, c2) { float _t=c1[0]; c1[0]=c2[0]; c2[0]=_t;\
+ _t=c1[1]; c1[1]=c2[1]; c2[1]=_t;\
+ _t=c1[2]; c1[2]=c2[2]; c2[2]=_t; }
+
+void qd_getPixel(CompBuf* src, int x, int y, float* col);
+void qd_setPixel(CompBuf* src, int x, int y, float* col);
+void qd_addPixel(CompBuf* src, int x, int y, float* col);
+void qd_multPixel(CompBuf* src, int x, int y, float f);
+void qd_getPixelLerpWrap(CompBuf* src, float u, float v, float* col);
+void qd_getPixelLerp(CompBuf* src, float u, float v, float* col);
+void qd_getPixelLerpChan(CompBuf* src, float u, float v, int chan, float* out);
+CompBuf* qd_downScaledCopy(CompBuf* src, int scale);
+void IIR_gauss(CompBuf* src, float sigma, int chan, int xy);
+/* end utility funcs */
+
#endif
diff --git a/source/blender/nodes/intern/Makefile b/source/blender/nodes/intern/Makefile
index d4053f13f6e..71290bf03cd 100644
--- a/source/blender/nodes/intern/Makefile
+++ b/source/blender/nodes/intern/Makefile
@@ -36,12 +36,10 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd openbsd linux solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I../../python
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../../makesdna
@@ -49,3 +47,4 @@ CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../include
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../render/extern/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/nodes/intern/SHD_nodes/Makefile b/source/blender/nodes/intern/SHD_nodes/Makefile
index 46e297bce46..04e042cee76 100644
--- a/source/blender/nodes/intern/SHD_nodes/Makefile
+++ b/source/blender/nodes/intern/SHD_nodes/Makefile
@@ -36,12 +36,10 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd openbsd linux solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I../../../python
CPPFLAGS += -I../../../blenkernel
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
CPPFLAGS += -I../../../makesdna
@@ -49,3 +47,4 @@ CPPFLAGS += -I../../../blenlib
CPPFLAGS += -I../../../include
CPPFLAGS += -I../../../imbuf
CPPFLAGS += -I../../../render/extern/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
index 1ba777a0533..ec3a9f3e5d6 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
@@ -27,13 +27,13 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifdef USE_PYNODES /* note: won't work without patch */
-
#include <Python.h>
+#include <compile.h>
#include <eval.h>
#include "DNA_text_types.h"
#include "BKE_text.h"
+#include "BKE_utildefines.h"
#include "api2_2x/Node.h"
#include "api2_2x/gen_utils.h"
@@ -41,207 +41,697 @@
#include "../SHD_util.h"
+static void node_dynamic_setup(bNode *node);
+static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out);
+static void node_dynamic_free_storage_cb(bNode *node);
+
static PyObject *init_dynamicdict(void) {
- PyObject *newscriptdict= PyDict_New();
+ PyObject *newscriptdict;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ newscriptdict= PyDict_New();
+
PyDict_SetItemString(newscriptdict, "__builtins__", PyEval_GetBuiltins());
EXPP_dict_set_item_str(newscriptdict, "__name__", PyString_FromString("__main__"));
+
+ PyGILState_Release(gilstate);
+
return newscriptdict;
}
+/* unused for now
static void free_dynamicdict(PyObject *dict) {
- if(dict!=NULL) {
+ if (dict!=NULL) {
Py_DECREF(dict);
}
}
+*/
-static void node_dynamic_init(bNode *node) {
- NodeScriptDict *nsd= MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
- int type= node->custom2;
- node->custom2= 0;
- node->storage= nsd;
- if(type>=NODE_DYNAMIC_MENU) {
- if(type==NODE_DYNAMIC_MENU) {
- nodeMakeDynamicType(node);
- node->custom1= SH_NODE_DYNAMIC_NEW;
- } else {
- node->custom1= SH_NODE_DYNAMIC_ADDEXIST;
+static bNodeType *node_dynamic_find_typeinfo(ListBase *list, ID *id)
+{
+ bNodeType *ntype = list->first;
+
+ while(ntype) {
+ if (ntype->type == NODE_DYNAMIC && ntype->id == id)
+ break;
+ ntype = ntype->next;
+ }
+
+ return ntype; /* NULL if doesn't exist */
+}
+
+static void node_dynamic_free_typeinfo_sockets(bNodeType *tinfo)
+{
+ bNodeSocketType *sock;
+
+ if (!tinfo) return;
+
+ if (tinfo->inputs) {
+ sock = tinfo->inputs;
+ while (sock->type != -1) {
+ MEM_freeN(sock->name);
+ sock++;
}
- node->id= node->typeinfo->id;
- nodeDynamicParse(node);
- } else {
- if(node->custom1== SH_NODE_DYNAMIC_LOADED) {
- nodeMakeDynamicType(node);
- nodeDynamicParse(node);
- } else if(node->custom1== SH_NODE_DYNAMIC_ADDEXIST)
- nodeDynamicParse(node);
+ MEM_freeN(tinfo->inputs);
+ tinfo->inputs = NULL;
+ }
+ if (tinfo->outputs) {
+ sock = tinfo->outputs;
+ while (sock->type != -1) {
+ MEM_freeN(sock->name);
+ sock++;
+ }
+ MEM_freeN(tinfo->outputs);
+ tinfo->outputs = NULL;
}
}
-static void node_dynamic_free(bNode *node)
+static void node_dynamic_free_typeinfo(bNodeType *tinfo)
{
- NodeScriptDict *nsd= (NodeScriptDict *)(node->storage);
- BPy_Node *pynode= nsd->node;
- Py_XDECREF(pynode);
- free_dynamicdict((PyObject *)(nsd->dict));
+ if (!tinfo) return;
+
+ node_dynamic_free_typeinfo_sockets(tinfo);
+
+ if (tinfo->name) { MEM_freeN(tinfo->name); }
+
+ MEM_freeN(tinfo);
+}
+
+static void node_dynamic_free_sockets(bNode *node)
+{
+ BLI_freelistN(&node->inputs);
+ BLI_freelistN(&node->outputs);
+}
+
+/* For now we just remove the socket links. It's the safest
+ * route, since an update in the script may change completely the
+ * inputs and outputs. Trying to recreate the node links would be
+ * nicer for pynode authors, though. */
+static void node_dynamic_update_socket_links(bNode *node, bNodeTree *ntree)
+{
+ if (ntree) {
+ nodeVerifyType(ntree, node);
+ }
+ else {
+ Material *ma;
+
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if (nd == node) nodeVerifyType(ma->nodetree, node);
+ }
+ }
+ }
+ }
+}
+
+static void node_dynamic_free_storage_cb(bNode *node)
+{
+ NodeScriptDict *nsd;
+ PyObject *pydict;
+ BPy_Node *pynode;
+
+ if (!node->storage) return;
+
+ nsd = (NodeScriptDict *)(node->storage);
+ pydict = nsd->dict;
+ if (pydict) {
+ Py_DECREF(pydict);
+ }
+ pynode = nsd->node;
+ if (pynode) {
+ Py_DECREF(pynode);
+ }
MEM_freeN(node->storage);
+ node->storage = NULL;
}
-static void node_dynamic_copy(bNode *orig_node, bNode *new_node)
+/* Disable pynode when its script fails */
+static void node_dynamic_disable(bNode *node)
{
- NodeScriptDict *nsd= (NodeScriptDict *)(orig_node->storage);
- new_node->storage= MEM_dupallocN(orig_node->storage);
- if(nsd->node)
- Py_INCREF((PyObject *)(nsd->node));
- if(nsd->dict)
- Py_INCREF((PyObject *)(nsd->dict));
+ node->custom1 = 0;
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
}
-static void node_dynamic_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) {
- BPy_Node *mynode = NULL;
- NodeScriptDict *nsd = NULL;
- PyObject *pyresult = NULL;
- PyObject *args = NULL;
- ShadeInput *shi= ((ShaderCallData *)data)->shi;
+/* Disable all pynodes using the given text (script) id */
+static void node_dynamic_disable_all_by_id(ID *id)
+{
+ Material *ma; /* XXX hardcoded for shaders */
- if(node->custom1==SH_NODE_DYNAMIC_NEW) {
- nodeDynamicParse(node);
- return;
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ bNodeTree *ntree = ma->nodetree;
+ for (nd= ntree->nodes.first; nd; nd= nd->next) {
+ if (nd->id == id) {
+ nd->custom1 = 0;
+ nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_ERROR);
+ }
+ }
+ }
}
+}
- if(node->custom2<0)
- return;
+static void node_rem_socklist_links(bNodeTree *ntree, ListBase *lb)
+{
+ bNodeLink *link, *next;
+ bNodeSocket *sock;
- if(node->custom1==SH_NODE_DYNAMIC_READY || node->custom1==SH_NODE_DYNAMIC_UPDATED) {
- if(node->custom1== SH_NODE_DYNAMIC_UPDATED)
- node->custom1= SH_NODE_DYNAMIC_READY;
+ if (!lb) return;
- nsd = (NodeScriptDict *)node->storage;
+ for (sock= lb->first; sock; sock= sock->next) {
+ for (link= ntree->links.first; link; link= next) {
+ next= link->next;
+ if (link->fromsock==sock || link->tosock==sock) {
+ nodeRemLink(ntree, link);
+ }
+ }
+ }
+}
- mynode = (BPy_Node *)(nsd->node);
- if(mynode && PyCallable_Check((PyObject *)mynode)) {
- mynode->node= node;
- Node_SetStack(mynode, in, NODE_INPUTSTACK);
- Node_SetStack(mynode, out, NODE_OUTPUTSTACK);
- Node_SetShi(mynode, shi);
- args=Py_BuildValue("()");
- pyresult= PyObject_Call((PyObject *)mynode, args, NULL);
- if(!pyresult) {
- if(PyErr_Occurred()) {
- PyErr_Print();
- node->custom2= -1;
- } else {
- printf("PyObject_Call __call__ failed\n");
+/* XXX hardcoded for shaders */
+static void node_dynamic_rem_all_links(bNodeType *tinfo)
+{
+ Material *ma;
+ int in, out;
+
+ in = tinfo->inputs ? 1 : 0;
+ out = tinfo->outputs ? 1 : 0;
+
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ bNodeTree *ntree = ma->nodetree;
+ for (nd= ntree->nodes.first; nd; nd= nd->next) {
+ if (nd->typeinfo == tinfo) {
+ if (in)
+ node_rem_socklist_links(ntree, &nd->inputs);
+ if (out)
+ node_rem_socklist_links(ntree, &nd->outputs);
+ }
+ }
+ }
+ }
+}
+
+/* node_dynamic_reset: clean a pynode, getting rid of all
+ * data dynamically created for it. */
+static void node_dynamic_reset(bNode *node, int unlink_text)
+{
+ bNodeType *tinfo, *tinfo_default;
+ Material *ma;
+
+ tinfo = node->typeinfo;
+ tinfo_default = node_dynamic_find_typeinfo(&node_all_shaders, NULL);
+
+ node_dynamic_rem_all_links(tinfo);
+ node_dynamic_free_typeinfo_sockets(tinfo);
+
+ /* reset all other XXX shader nodes sharing this typeinfo */
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if (nd->typeinfo == tinfo) {
+ node_dynamic_free_storage_cb(nd);
+ node_dynamic_free_sockets(nd);
+ nd->typeinfo = tinfo_default;
+ if (unlink_text) {
+ nd->id = NULL;
+ nd->custom1 = 0;
+ nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_NEW);
+ BLI_strncpy(nd->name, "Dynamic", 8);
+ }
+ }
+ }
+ }
+ }
+
+ /* XXX hardcoded for shaders: */
+ if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); }
+ node_dynamic_free_typeinfo(tinfo);
+}
+
+/* Special case of the above function: for working pynodes
+ * that were saved on a .blend but fail for some reason when
+ * the file is opened. We need this because pynodes are initialized
+ * before G.main. */
+static void node_dynamic_reset_loaded(bNode *node)
+{
+ bNodeType *tinfo = node->typeinfo;
+
+ node_dynamic_rem_all_links(tinfo);
+ node_dynamic_free_typeinfo_sockets(tinfo);
+ node_dynamic_free_storage_cb(node);
+ /* XXX hardcoded for shaders: */
+ if (tinfo->id) { BLI_remlink(&node_all_shaders, tinfo); }
+
+ node_dynamic_free_typeinfo(tinfo);
+ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, NULL);
+}
+
+int nodeDynamicUnlinkText(ID *txtid) {
+ Material *ma;
+ bNode *nd;
+
+ /* find one node that uses this text */
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if ((nd->type == NODE_DYNAMIC) && (nd->id == txtid)) {
+ node_dynamic_reset(nd, 1); /* found, reset all */
+ return 1;
+ }
+ }
+ }
+ }
+ return 0; /* no pynodes used this text */
+}
+
+/*
+static void node_dynamic_free_all_typeinfos(ListBase *list)
+{
+ bNodeType *ntype, *ntnext;
+
+ ntype = list->first;
+
+ while (ntype) {
+ ntnext = ntype->next;
+ if (ntype->type == NODE_DYNAMIC && ntype->id) {
+ BLI_remlink(list, ntype);
+ node_dynamic_free_typeinfo_sockets(ntype);
+ node_dynamic_free_typeinfo(ntype);
+ }
+ ntype = ntnext;
+ }
+}
+*/
+/* Unload all pynodes: since the Game Engine restarts Python, we need
+ * to recreate pynodes dicts and objects. First we get rid of them here: */
+/*
+void nodeDynamicUnloadAll(void)
+{
+ Material *ma;
+ bNode *nd;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if ((nd->type == NODE_DYNAMIC) && nd->id) {
+ node_dynamic_free_storage_cb(nd);
+ nd->typeinfo = NULL;
+ nd->custom1 = 0;
+ nd->custom1 = BSET(nd->custom1, NODE_DYNAMIC_LOADED);
}
}
- Py_XDECREF(pyresult);
- Py_DECREF(args);
}
}
+
+ node_dynamic_free_all_typeinfos(&node_all_shaders);
+
+ PyGILState_Release(gilstate);
+}
+
+void nodeDynamicReloadAll(void)
+{
+ Material *ma;
+ bNode *nd;
+
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ for (nd= ma->nodetree->nodes.first; nd; nd = nd->next) {
+ if ((nd->type == NODE_DYNAMIC) && nd->id) {
+ node_dynamic_setup(nd);
+ }
+ }
+ }
+ }
+}
+*/
+
+static void node_dynamic_pyerror_print(bNode *node)
+{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ fprintf(stderr, "\nError in dynamic node script \"%s\":\n", node->name);
+ if (PyErr_Occurred()) { PyErr_Print(); }
+ else { fprintf(stderr, "Not a valid dynamic node Python script.\n"); }
+
+ PyGILState_Release(gilstate);
}
-void nodeDynamicParse(struct bNode *node)
+static int node_dynamic_parse(struct bNode *node)
{
- BPy_Node *pynode= NULL;
PyObject *dict= NULL;
PyObject *key= NULL;
PyObject *value= NULL;
- PyObject *testinst= NULL;
+ PyObject *pynode= NULL;
PyObject *args= NULL;
- int pos = 0;
- NodeScriptDict *nsd= NULL;
+ NodeScriptDict *nsd = NULL;
PyObject *pyresult = NULL;
- PyObject *pycompiled = NULL;
- Text *txt = NULL;
- char *buf= NULL;
+ char *buf = NULL;
+ Py_ssize_t pos = 0;
+ int is_valid_script = 0;
+ PyGILState_STATE gilstate;
+
+ if (!node->id || !node->storage)
+ return 0;
+
+ /* READY, no need to be here */
+ if (BTST(node->custom1, NODE_DYNAMIC_READY))
+ return 0;
+
+ /* for threading */
+ gilstate = PyGILState_Ensure();
+
+ nsd = (NodeScriptDict *)node->storage;
+
+ dict = (PyObject *)(nsd->dict);
+ buf = txt_to_buf((Text *)node->id);
+
+ pyresult = PyRun_String(buf, Py_file_input, dict, dict);
+
+ MEM_freeN(buf);
+
+ if (!pyresult) {
+ node_dynamic_disable(node);
+ node_dynamic_pyerror_print(node);
+ PyGILState_Release(gilstate);
+ return -1;
+ }
+
+ Py_DECREF(pyresult);
+
+ while (PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value)) {
+ /* look for the node object */
+ if (PyObject_TypeCheck(value, &PyType_Type)==1) {
+ BPy_NodeSockets *sockets = Node_CreateSockets(node);
+
+ args = Py_BuildValue("(O)", sockets);
- if(! node->id) {
+ /* init it to get the input and output sockets */
+ pynode = PyObject_Call(value, args, NULL);
+
+ Py_DECREF(sockets);
+ Py_DECREF(args);
+
+ if (!PyErr_Occurred() && pynode && pytype_is_pynode(pynode)) {
+ InitNode((BPy_Node *)(pynode), node);
+ nsd->node = pynode;
+ node->typeinfo->execfunc = node_dynamic_exec_cb;
+ is_valid_script = 1;
+
+ /* for NEW, LOADED, REPARSE */
+ if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
+ node->typeinfo->pydict = dict;
+ node->typeinfo->pynode = pynode;
+ node->typeinfo->id = node->id;
+ if (BNTST(node->custom1, NODE_DYNAMIC_LOADED))
+ nodeAddSockets(node, node->typeinfo);
+ if (BNTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
+ nodeRegisterType(&node_all_shaders, node->typeinfo);
+ /* nodeRegisterType copied it to a new one, so we
+ * free the typeinfo itself, but not what it
+ * points to: */
+ MEM_freeN(node->typeinfo);
+ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
+ MEM_freeN(node->typeinfo->name);
+ node->typeinfo->name = BLI_strdup(node->name);
+ }
+ }
+
+ node->custom1 = 0;
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY);
+ break;
+ }
+ break;
+ }
+ }
+
+ PyGILState_Release(gilstate);
+
+ if (!is_valid_script) { /* not a valid pynode script */
+ node_dynamic_disable(node);
+ node_dynamic_pyerror_print(node);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* node_dynamic_setup: prepare for execution (state: NODE_DYNAMIC_READY)
+ * pynodes already linked to a script (node->id != NULL). */
+static void node_dynamic_setup(bNode *node)
+{
+ NodeScriptDict *nsd = NULL;
+ bNodeTree *nodetree = NULL;
+ bNodeType *ntype = NULL;
+ PyGILState_STATE gilstate;
+
+ /* Possible cases:
+ * NEW
+ * ADDEXIST
+ * LOADED
+ * REPARSE
+ * ERROR
+ * READY
+ */
+
+ /* NEW, but not linked to a script: link default (empty) typeinfo */
+ if (!node->id) {
+ node->typeinfo = node_dynamic_find_typeinfo(&node_all_shaders,
+ NULL);
return;
}
- if(node->custom1!=SH_NODE_DYNAMIC_READY) {
- txt = (Text *)node->id;
- nsd = (NodeScriptDict *)node->storage;
+ /* READY, no need to be here */
+ if (BTST(node->custom1, NODE_DYNAMIC_READY))
+ return;
+
+ gilstate = PyGILState_Ensure();
+
+ /* ERROR, reset to (empty) defaults */
+ if (BCLR(node->custom1, NODE_DYNAMIC_ERROR) == 0) {
+ node_dynamic_reset(node, 0);
+ PyGILState_Release(gilstate);
+ return;
+ }
+
+ /* User asked to update this pynode, prepare it for reparsing */
+ if (BTST(node->custom1, NODE_DYNAMIC_REPARSE)) {
+ int needs_parsing = 1;
+
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW);
+
+ if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
+ node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_REPARSE);
+ ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
+
+ if (ntype) {
+ node->typeinfo = ntype;
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
+ node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ERROR);
+ needs_parsing = 0;
+ }
+ else { nodeMakeDynamicType(node); }
+
+ } else {
+ node_dynamic_free_typeinfo_sockets(node->typeinfo);
+ node_dynamic_update_socket_links(node, NULL);
+ node_dynamic_free_storage_cb(node);
+ }
- if(nsd->dict==NULL && (node->custom1==SH_NODE_DYNAMIC_NEW||node->custom1==SH_NODE_DYNAMIC_LOADED)) {
- nsd->dict= init_dynamicdict();
- } else if(nsd->dict==NULL && node->custom1==SH_NODE_DYNAMIC_ADDEXIST) {
- nsd->dict= node->typeinfo->pydict;
- nsd->node= node->typeinfo->pynode;
- Py_INCREF((PyObject *)(nsd->dict));
- Py_INCREF((PyObject *)(nsd->node));
- node->custom1= SH_NODE_DYNAMIC_READY;
+ if (needs_parsing) {
+ nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
+ nsd->dict = init_dynamicdict();
+ node->storage = nsd;
+ /* prepared, now reparse: */
+ node_dynamic_parse(node);
+ PyGILState_Release(gilstate);
return;
}
- dict= (PyObject *)(nsd->dict);
+ }
+ else if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) {
+ /* when loading from a .blend we don't have G.main yet, so we
+ * quickly abuse node->storage in ntreeInitTypes (node.c) to have
+ * our nodetree ptr (needed if a pynode script that worked before
+ * saving the .blend for some reason fails upon loading): */
+ nodetree = (bNodeTree *)node->storage;
+ node->storage = NULL;
+ }
- if(node->custom1!=SH_NODE_DYNAMIC_ADDEXIST) {
- buf = txt_to_buf( txt );
- /*printf("Running script (%s, %d)...", node->name, node->custom1);*/
- pyresult = PyRun_String(buf, Py_file_input, dict, dict);
- /*printf(" done\n");*/
+ if (node->storage)
+ fprintf(stderr, "\nDEBUG: PYNODES ERROR: non NULL node->storage in node_dynamic_setup()\n");
- MEM_freeN(buf);
+ nsd = MEM_callocN(sizeof(NodeScriptDict), "node script dictionary");
+ node->storage = nsd;
+
+ /* NEW, LOADED or REPARSE */
+ if (BNTST(node->custom1, NODE_DYNAMIC_ADDEXIST)) {
+ /* check if there's already a bNodeType linked to this script */
+ /* (XXX hardcoded for shader nodes for now) */
+ ntype = node_dynamic_find_typeinfo(&node_all_shaders, node->id);
- if(!pyresult) {
- if(PyErr_Occurred()) {
- PyErr_Print();
- }
- Py_XDECREF(pyresult);
- return;
+ if (ntype) { /* if so, reuse it */
+ node->typeinfo = ntype;
+ /* so this is actually an ADDEXIST type */
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
+ }
+ else { /* create bNodeType for this pynode */
+ nodeMakeDynamicType(node);
+ nsd->dict = init_dynamicdict();
+ if ((node_dynamic_parse(node) == -1) && nodetree) {
+ node_dynamic_reset_loaded(node);
}
+ PyGILState_Release(gilstate);
+ return;
+ }
+ }
- Py_DECREF(pyresult);
+ /* ADDEXIST: new pynode linked to an already registered dynamic type,
+ * we just reuse existing py dict and pynode */
+ nsd->dict = node->typeinfo->pydict;
+ nsd->node = node->typeinfo->pynode;
- while(PyDict_Next( (PyObject *)(nsd->dict), &pos, &key, &value) ) {
- if(PyObject_TypeCheck(value, &PyType_Type)==1) {
- BPy_DefinitionMap *outputdef= Node_CreateOutputDefMap(node);
- BPy_DefinitionMap *inputdef= Node_CreateInputDefMap(node);
-
- args= Py_BuildValue("(OO)", inputdef, outputdef);
- testinst= PyObject_Call(value, args, NULL);
-
- Py_DECREF(outputdef);
- Py_DECREF(inputdef);
- if(testinst && PyObject_TypeCheck(testinst, &Node_Type)==1) {
- Py_INCREF(testinst);
- Py_INCREF(dict);
- InitNode((BPy_Node *)(testinst), node);
- nsd->node= testinst;
- node->typeinfo->execfunc= node_dynamic_exec;
- if(node->custom1== SH_NODE_DYNAMIC_NEW || node->custom1== SH_NODE_DYNAMIC_LOADED) {
- node->typeinfo->pynode= testinst;
- node->typeinfo->pydict= nsd->dict;
- node->typeinfo->id= node->id;
- nodeAddSockets(node, node->typeinfo);
- nodeRegisterType(&node_all_shaders, node->typeinfo);
- node->custom1= SH_NODE_DYNAMIC_READY;
- }
- break;
- }
- Py_DECREF(args);
- }
- }
+ Py_INCREF((PyObject *)(nsd->dict));
+ Py_INCREF((PyObject *)(nsd->node));
+
+ if (BTST(node->custom1, NODE_DYNAMIC_NEW)) {
+ nodeAddSockets(node, node->typeinfo);
+ node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_NEW);
+ }
+
+ node->custom1 = BCLR(node->custom1, NODE_DYNAMIC_ADDEXIST);
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_READY);
+
+ PyGILState_Release(gilstate);
+
+ return;
+}
+
+/* node_dynamic_init_cb callback: called when a pynode is created.
+ * The pynode type is passed via node->custom2. It can be:
+ * 0: for loaded empty nodes
+ * NODE_DYNAMIC_MENU: for the default Dynamic node type
+ * > NODE_DYNAMIC_MENU: for the new types defined by scripts
+*/
+static void node_dynamic_init_cb(bNode *node) {
+ int type = node->custom2;
+
+ node->custom2 = 0;
+
+ if (type >= NODE_DYNAMIC_MENU) {
+ node->custom1 = 0;
+
+ if (type == NODE_DYNAMIC_MENU) {
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_NEW);
+ return;
}
+
+ node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ADDEXIST);
+ node->id = node->typeinfo->id;
}
+
+ node_dynamic_setup(node);
}
+/* node_dynamic_copy_cb: pynode copy callback */
+static void node_dynamic_copy_cb(bNode *orig_node, bNode *new_node)
+{
+ NodeScriptDict *nsd;
+ PyGILState_STATE gilstate;
+
+ if (!orig_node->storage) return;
+
+ nsd = (NodeScriptDict *)(orig_node->storage);
+ new_node->storage = MEM_dupallocN(orig_node->storage);
+
+ gilstate = PyGILState_Ensure();
+
+ if (nsd->node)
+ Py_INCREF((PyObject *)(nsd->node));
+ if (nsd->dict)
+ Py_INCREF((PyObject *)(nsd->dict));
+
+ PyGILState_Release(gilstate);
+}
+
+/* node_dynamic_exec_cb: the execution callback called per pixel
+ * during rendering. */
+static void node_dynamic_exec_cb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) {
+ BPy_Node *mynode = NULL;
+ NodeScriptDict *nsd = NULL;
+ PyObject *pyresult = NULL;
+ PyObject *args = NULL;
+ ShadeInput *shi;
+ PyGILState_STATE gilstate;
+
+ if (!node->id)
+ return;
+
+ /*if (G.scene->r.threads > 1)
+ return;*/
+
+ if (BTST2(node->custom1, NODE_DYNAMIC_NEW, NODE_DYNAMIC_REPARSE)) {
+ node_dynamic_setup(node);
+ return;
+ }
+
+ if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) {
+ if (node->storage) node_dynamic_setup(node);
+ return;
+ }
+
+ if (BTST(node->custom1, NODE_DYNAMIC_READY)) {
+ nsd = (NodeScriptDict *)node->storage;
+ mynode = (BPy_Node *)(nsd->node);
+
+
+ if (mynode && PyCallable_Check((PyObject *)mynode)) {
+
+ gilstate = PyGILState_Ensure();
+
+ mynode->node = node;
+ shi = ((ShaderCallData *)data)->shi;
+
+ Node_SetStack(mynode, in, NODE_INPUTSTACK);
+ Node_SetStack(mynode, out, NODE_OUTPUTSTACK);
+ Node_SetShi(mynode, shi);
+
+ args=Py_BuildValue("()");
+ pyresult= PyObject_Call((PyObject *)mynode, args, NULL);
+ Py_DECREF(args);
+
+ if (!pyresult) {
+ PyGILState_Release(gilstate);
+ node_dynamic_disable_all_by_id(node->id);
+ node_dynamic_pyerror_print(node);
+ node_dynamic_setup(node);
+ return;
+ }
+ Py_DECREF(pyresult);
+ PyGILState_Release(gilstate);
+ }
+ }
+}
-bNodeType sh_node_dynamic = {
+bNodeType node_dynamic_typeinfo = {
/* next, prev */ NULL, NULL,
- /* type code */ SH_NODE_DYNAMIC,
+ /* type code */ NODE_DYNAMIC,
/* name */ "Dynamic",
/* width+range */ 150, 60, 300,
/* class+opts */ NODE_CLASS_OP_DYNAMIC, NODE_OPTIONS,
/* input sock */ NULL,
/* output sock */ NULL,
/* storage */ "NodeScriptDict",
- /* execfunc */ node_dynamic_exec,
+ /* execfunc */ node_dynamic_exec_cb,
/* butfunc */ NULL,
- /* initfunc */ node_dynamic_init,
- /* freefunc */ node_dynamic_free,
- /* copyfunc */ node_dynamic_copy,
+ /* initfunc */ node_dynamic_init_cb,
+ /* freefunc */ node_dynamic_free_storage_cb,
+ /* copyfunc */ node_dynamic_copy_cb,
/* id */ NULL
};
-#endif /* USE_PYNODES */
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c b/source/blender/nodes/intern/SHD_nodes/SHD_geom.c
index b15aa6802f3..24395059c60 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_geom.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_geom.c
@@ -51,7 +51,7 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNod
if(data) {
ShadeInput *shi= ((ShaderCallData *)data)->shi;
NodeGeometry *ngeo= (NodeGeometry*)node->storage;
- ShadeInputUV *suv= &shi->uv[0];
+ ShadeInputUV *suv= &shi->uv[shi->actuv];
static float defaultvcol[4] = {1.0f, 1.0f, 1.0f, 1.0f};
static float front= 0.0;
int i;
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c
new file mode 100644
index 00000000000..8c07a2d1dc8
--- /dev/null
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c
@@ -0,0 +1,94 @@
+/**
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 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): Juho Vepsäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../SHD_util.h"
+
+
+/* **************** Hue Saturation ******************** */
+static bNodeSocketType sh_node_hue_sat_in[]= {
+ { SOCK_VALUE, 1, "Hue", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
+ { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
+ { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType sh_node_hue_sat_out[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+/* note: it would be possible to use CMP version for both nodes */
+static void do_hue_sat_fac(bNode *node, float *out, float *hue, float *sat, float *val, float *in, float *fac)
+{
+ if(*fac!=0.0f && (*hue!=0.5f || *sat!=1.0 || *val!=1.0)) {
+ float col[3], hsv[3], mfac= 1.0f - *fac;
+
+ rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
+ hsv[0]+= (*hue - 0.5f);
+ if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
+ hsv[1]*= *sat;
+ if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
+ hsv[2]*= *val;
+ if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
+
+ out[0]= mfac*in[0] + *fac*col[0];
+ out[1]= mfac*in[1] + *fac*col[1];
+ out[2]= mfac*in[2] + *fac*col[2];
+ }
+ else {
+ QUATCOPY(out, in);
+ }
+}
+
+static void node_shader_exec_hue_sat(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ do_hue_sat_fac(node, out[0]->vec, in[0]->vec, in[1]->vec, in[2]->vec, in[4]->vec, in[3]->vec);
+}
+
+bNodeType sh_node_hue_sat= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ SH_NODE_HUE_SAT,
+ /* name */ "Hue Saturation Value",
+ /* width+range */ 150, 80, 250,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ sh_node_hue_sat_in,
+ /* output sock */ sh_node_hue_sat_out,
+ /* storage */ "",
+ /* execfunc */ node_shader_exec_hue_sat,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
+
+
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c b/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c
new file mode 100644
index 00000000000..2b52a8e2229
--- /dev/null
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_sepcombRGB.c
@@ -0,0 +1,105 @@
+/**
+ *
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Juho Vepsäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../SHD_util.h"
+
+/* **************** SEPARATE RGBA ******************** */
+static bNodeSocketType sh_node_seprgb_in[]= {
+ { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType sh_node_seprgb_out[]= {
+ { SOCK_VALUE, 0, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 0, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 0, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_seprgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ out[0]->vec[0] = in[0]->vec[0];
+ out[1]->vec[0] = in[0]->vec[1];
+ out[2]->vec[0] = in[0]->vec[2];
+}
+
+bNodeType sh_node_seprgb= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ SH_NODE_SEPRGB,
+ /* name */ "Separate RGB",
+ /* width+range */ 80, 40, 140,
+ /* class+opts */ NODE_CLASS_CONVERTOR, 0,
+ /* input sock */ sh_node_seprgb_in,
+ /* output sock */ sh_node_seprgb_out,
+ /* storage */ "",
+ /* execfunc */ node_shader_exec_seprgb,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
+
+
+/* **************** COMBINE RGB ******************** */
+static bNodeSocketType sh_node_combrgb_in[]= {
+ { SOCK_VALUE, 1, "R", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "G", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "B", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType sh_node_combrgb_out[]= {
+ { SOCK_RGBA, 0, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_combrgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ out[0]->vec[0] = in[0]->vec[0];
+ out[0]->vec[1] = in[1]->vec[0];
+ out[0]->vec[2] = in[2]->vec[0];
+}
+
+bNodeType sh_node_combrgb= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ SH_NODE_COMBRGB,
+ /* name */ "Combine RGB",
+ /* width+range */ 80, 40, 140,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ sh_node_combrgb_in,
+ /* output sock */ sh_node_combrgb_out,
+ /* storage */ "",
+ /* execfunc */ node_shader_exec_combrgb,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index d7db680a458..d7bd4f22fc6 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -34,6 +34,7 @@
#define BPY_EXTERN_H
extern char bprogname[]; /* holds a copy of argv[0], from creator.c */
+extern char btempdir[]; /* use this to store a valid temp directory */
struct Text; /* defined in DNA_text_types.h */
struct ID; /* DNA_ID.h */
@@ -43,19 +44,49 @@ struct ScriptLink; /* DNA_scriptlink_types.h */
struct ListBase; /* DNA_listBase.h */
struct SpaceText; /* DNA_space_types.h */
struct SpaceScript; /* DNA_space_types.h */
-struct Script; /* BPI_script.h */
struct ScrArea; /* DNA_screen_types.h */
struct bScreen; /* DNA_screen_types.h */
-
+struct bConstraint; /* DNA_constraint_types.h */
+struct bPythonConstraint; /* DNA_constraint_types.h */
+struct bConstraintOb; /* DNA_constraint_types.h */
+struct bConstraintTarget; /* DNA_constraint_types.h*/
+struct Script; /* DNA_screen_types.h */
#ifdef __cplusplus
extern "C" {
#endif
+ /*These two next functions are important for making sure the Draw module
+ works correctly. Before calling any gui callback using the Draw module,
+ the following code must be executed:
+
+ if (some_drawspace_pylist) {
+ BPy_Set_DrawButtonsList(some_drawspace_pylist->but_refs);
+ BPy_Free_DrawButtonsList();
+ }
+ some_drawspace_pylist = PyList_New(0);
+ BPy_Set_DrawButtonsList(some_drawspace_pylist);
+
+ Also, BPy_Free_DrawButtonsList() must be called as necassary when a drawspace
+ with python callbacks is destroyed.
+
+ This is necassary to avoid blender buttons storing invalid pointers to freed
+ python data.*/
+ void BPy_Set_DrawButtonsList(void *list);
+ void BPy_Free_DrawButtonsList(void);
+
+ void BPY_pyconstraint_eval(struct bPythonConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
+ void BPY_pyconstraint_settings(void *arg1, void *arg2);
+ void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTarget *ct);
+ void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con);
+ int BPY_is_pyconstraint(struct Text *text);
+ void BPY_free_pyconstraint_links(struct Text *text);
+
void BPY_start_python( int argc, char **argv );
void BPY_end_python( void );
void BPY_post_start_python( void );
void init_syspath( int first_time );
void syspath_append( char *dir );
+ void BPY_rebuild_syspath( void );
int BPY_Err_getLinenumber( void );
const char *BPY_Err_getFilename( void );
@@ -63,6 +94,7 @@ extern "C" {
int BPY_txt_do_python_Text( struct Text *text );
int BPY_menu_do_python( short menutype, int event );
void BPY_run_python_script( char *filename );
+ int BPY_run_script(struct Script *script);
void BPY_free_compiled_text( struct Text *text );
void BPY_clear_bad_scriptlinks( struct Text *byebye );
@@ -95,6 +127,7 @@ extern "C" {
unsigned short event, short val, char ascii );
void BPY_clear_script( struct Script *script );
void BPY_free_finished_script( struct Script *script );
+ void BPY_scripts_clear_pyobjects( void );
/* void BPY_Err_Handle(struct Text *text); */
/* void BPY_clear_bad_scriptlink(struct ID *id, struct Text *byebye); */
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c
index cef83c327ab..febf5e3ff31 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -40,22 +40,28 @@
#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
+#include "BKE_action.h" /* for get_pose_channel() */
#include "BKE_library.h"
#include "BKE_object.h" /* during_scriptlink() */
#include "BKE_text.h"
+#include "BKE_constraint.h" /* for bConstraintOb */
+#include "BKE_idprop.h"
#include "DNA_curve_types.h" /* for struct IpoDriver */
#include "DNA_ID.h" /* ipo driver */
#include "DNA_object_types.h" /* ipo driver */
+#include "DNA_constraint_types.h" /* for pyconstraint */
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h" /* for U.pythondir */
#include "MEM_guardedalloc.h"
#include "BPY_extern.h"
#include "BPY_menus.h"
-#include "BPI_script.h"
+#include "DNA_space_types.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_armature.h"
+#include "BKE_depsgraph.h"
#include "api2_2x/EXPP_interface.h"
#include "api2_2x/constant.h"
#include "api2_2x/gen_utils.h"
@@ -66,8 +72,13 @@
#include "api2_2x/Draw.h"
#include "api2_2x/Object.h"
#include "api2_2x/Registry.h"
+#include "api2_2x/Pose.h"
#include "api2_2x/bpy.h" /* for the new "bpy" module */
+/*these next two are for pyconstraints*/
+#include "api2_2x/IDProp.h"
+#include "api2_2x/matrix.h"
+
/* for scriptlinks */
#include "DNA_lamp_types.h"
#include "DNA_camera_types.h"
@@ -85,7 +96,7 @@
/* for pydrivers (ipo drivers defined by one-line Python expressions) */
PyObject *bpy_pydriver_Dict = NULL;
-
+PyObject *bpy_orig_syspath_List = NULL;
/*
* set up a weakref list for Armatures
@@ -100,7 +111,18 @@ int setup_armature_weakrefs()
main_module = PyImport_AddModule( "__main__");
if(main_module){
+ PyObject *weakreflink;
maindict= PyModule_GetDict(main_module);
+
+ /* check if there is already a dict entry for the armature weakrefs,
+ * and delete if so before making another one */
+
+ weakreflink= PyDict_GetItemString(maindict,list_name);
+ if( weakreflink != NULL ) {
+ PyDict_DelItemString(maindict,list_name);
+ Py_XDECREF( weakreflink );
+ }
+
if (PyDict_SetItemString(maindict,
list_name,
PyList_New(0)) == -1){
@@ -149,6 +171,7 @@ PyObject *importText( char *name );
void init_ourImport( void );
void init_ourReload( void );
PyObject *blender_import( PyObject * self, PyObject * args );
+PyObject *RunPython2( Text * text, PyObject * globaldict, PyObject *localdict );
void BPY_Err_Handle( char *script_name );
@@ -160,6 +183,7 @@ PyObject *traceback_getFilename( PyObject * tb );
****************************************************************************/
void BPY_start_python( int argc, char **argv )
{
+ PyThreadState *py_tstate = NULL;
static int argc_copy = 0;
static char **argv_copy = NULL;
int first_time = argc;
@@ -205,6 +229,16 @@ void BPY_start_python( int argc, char **argv )
Py_Initialize( );
PySys_SetArgv( argc_copy, argv_copy );
+ /* Initialize thread support (also acquires lock) */
+ PyEval_InitThreads();
+
+ /* Don't allow the Python Interpreter to release the GIL on
+ * its own, to guarantee PyNodes work properly. For Blender this
+ * is currently the best default behavior.
+ * The following code in C is equivalent in Python to:
+ * "import sys; sys.setcheckinterval(sys.maxint)" */
+ _Py_CheckInterval = PyInt_GetMax();
+
//Overrides __import__
init_ourImport( );
init_ourReload( );
@@ -215,6 +249,9 @@ void BPY_start_python( int argc, char **argv )
//Look for a python installation
init_syspath( first_time ); /* not first_time: some msgs are suppressed */
+ py_tstate = PyGILState_GetThisThreadState();
+ PyEval_ReleaseThread(py_tstate);
+
return;
}
@@ -225,6 +262,8 @@ void BPY_end_python( void )
{
Script *script = NULL;
+ PyGILState_Ensure(); /* finalizing, no need to grab the state */
+
if( bpy_registryDict ) {
Py_DECREF( bpy_registryDict );
bpy_registryDict = NULL;
@@ -234,6 +273,11 @@ void BPY_end_python( void )
Py_DECREF( bpy_pydriver_Dict );
bpy_pydriver_Dict = NULL;
}
+
+ if( bpy_orig_syspath_List ) {
+ Py_DECREF( bpy_orig_syspath_List );
+ bpy_orig_syspath_List = NULL;
+ }
/* Freeing all scripts here prevents problems with the order in which
* Python is finalized and G.main is freed in exit_usiblender() */
@@ -254,25 +298,33 @@ void BPY_end_python( void )
void syspath_append( char *dirname )
{
- PyObject *mod_sys, *dict, *path, *dir;
-
+ PyObject *mod_sys= NULL, *dict= NULL, *path= NULL, *dir= NULL;
+ short ok=1;
PyErr_Clear( );
dir = Py_BuildValue( "s", dirname );
mod_sys = PyImport_ImportModule( "sys" ); /* new ref */
- dict = PyModule_GetDict( mod_sys ); /* borrowed ref */
- path = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
-
- if( !PyList_Check( path ) )
- return;
-
- PyList_Append( path, dir );
-
- if( PyErr_Occurred( ) )
- Py_FatalError( "could not build sys.path" );
-
- Py_DECREF( mod_sys );
+
+ if (mod_sys) {
+ dict = PyModule_GetDict( mod_sys ); /* borrowed ref */
+ path = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
+ if ( !PyList_Check( path ) ) {
+ ok = 0;
+ }
+ } else {
+ /* cant get the sys module */
+ ok = 0;
+ }
+
+ if (PySequence_Contains(path, dir)==0) { /* Only add if we need to */
+ if (ok && PyList_Append( path, dir ) != 0)
+ ok = 0; /* append failed */
+
+ if( (ok==0) || PyErr_Occurred( ) )
+ Py_FatalError( "could import or build sys.path, can't continue" );
+ }
+ Py_XDECREF( mod_sys );
}
void init_syspath( int first_time )
@@ -283,7 +335,8 @@ void init_syspath( int first_time )
char execdir[FILE_MAXDIR]; /*defines from DNA_space_types.h */
int n;
-
+
+
path = Py_BuildValue( "s", bprogname );
mod = PyImport_ImportModule( "Blender.sys" );
@@ -305,9 +358,10 @@ void init_syspath( int first_time )
execdir[n] = '\0';
syspath_append( execdir ); /* append to module search path */
- } else
+ } else {
printf( "Warning: could not determine argv[0] path\n" );
-
+ }
+
/*
attempt to import 'site' module as a check for valid
python install found.
@@ -338,28 +392,48 @@ void init_syspath( int first_time )
if( mod ) {
d = PyModule_GetDict( mod ); /* borrowed ref */
- EXPP_dict_set_item_str( d, "executable",
- Py_BuildValue( "s", bprogname ) );
+ EXPP_dict_set_item_str( d, "executable", Py_BuildValue( "s", bprogname ) );
+
+ if (bpy_orig_syspath_List == NULL) {
+ /* backup the original sys.path to rebuild later */
+ PyObject *syspath = PyDict_GetItemString( d, "path" ); /* borrowed ref */
+ if (bpy_orig_syspath_List) { /* This should never happen but just incase, be nice */
+ Py_DECREF(bpy_orig_syspath_List);
+ }
+ bpy_orig_syspath_List = PyList_GetSlice(syspath, 0, PyList_Size(syspath));
+ }
+
Py_DECREF( mod );
} else{
printf("import of sys module failed\n");
}
}
-/****************************************************************************
-* Description: This function finishes Python initialization in Blender.
-
-Because U.pythondir (user defined dir for scripts) isn't
-initialized when BPY_start_Python needs to be executed, we
-postpone adding U.pythondir to sys.path and also BPyMenus
-(mechanism to register scripts in Blender menus) for when
-that dir info is available.
-****************************************************************************/
-void BPY_post_start_python( void )
+void BPY_rebuild_syspath( void )
{
+ PyObject *mod, *dict, *syspath;
char dirpath[FILE_MAX];
char *sdir = NULL;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+ mod = PyImport_ImportModule( "sys" );
+ if (!mod) {
+ printf("error: could not import python sys module. some modules may not import.\n");
+ return;
+ }
+
+ if (!bpy_orig_syspath_List) { /* should never happen */
+ printf("error refershing python path\n");
+ Py_DECREF(mod);
+ return;
+ }
+
+ dict = PyModule_GetDict( mod ); /* borrowed ref */
+
+ /* Reset sys.path */
+ syspath = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
+ PyList_SetSlice(syspath, 0, PyList_Size(syspath), bpy_orig_syspath_List);
+
if(U.pythondir[0] != '\0' ) {
char modpath[FILE_MAX];
int upyslen = strlen(U.pythondir);
@@ -368,10 +442,7 @@ void BPY_post_start_python( void )
* (for eventual implementations of c library's stat function that might
* not like it) */
if (upyslen > 2) { /* avoids doing anything if dir == '//' */
- char ending = U.pythondir[upyslen - 1];
-
- if (ending == '/' || ending == '\\')
- U.pythondir[upyslen - 1] = '\0';
+ BLI_add_slash(U.pythondir);
}
BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
@@ -381,19 +452,35 @@ void BPY_post_start_python( void )
BLI_make_file_string("/", modpath, dirpath, "bpymodules");
if (BLI_exists(modpath)) syspath_append(modpath);
}
-
+
sdir = bpy_gethome(1);
if (sdir) {
-
syspath_append(sdir);
-
BLI_make_file_string("/", dirpath, sdir, "bpymodules");
if (BLI_exists(dirpath)) syspath_append(dirpath);
}
+
+ Py_DECREF(mod);
+ PyGILState_Release(gilstate);
+}
+/****************************************************************************
+* Description: This function finishes Python initialization in Blender.
+
+Because U.pythondir (user defined dir for scripts) isn't
+initialized when BPY_start_Python needs to be executed, we
+postpone adding U.pythondir to sys.path and also BPyMenus
+(mechanism to register scripts in Blender menus) for when
+that dir info is available.
+****************************************************************************/
+void BPY_post_start_python( void )
+{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ BPY_rebuild_syspath();
BPyMenu_Init( 0 ); /* get dynamic menus (registered scripts) data */
- return;
+ PyGILState_Release(gilstate);
}
/****************************************************************************
@@ -451,10 +538,11 @@ void BPY_Err_Handle( char *script_name )
PyErr_Fetch( &exception, &err, &tb );
- if( !exception && !tb ) {
- printf( "FATAL: spurious exception\n" );
- return;
- }
+ if (!script_name) script_name = "untitled";
+ //if( !exception && !tb ) {
+ // printf( "FATAL: spurious exception\n" );
+ // return;
+ //}
strcpy( g_script_error.filename, script_name );
@@ -533,6 +621,7 @@ int BPY_txt_do_python_Text( struct Text *text )
BPy_constant *info;
char textname[24];
Script *script = G.main->script.first;
+ PyGILState_STATE gilstate;
if( !text )
return 0;
@@ -572,11 +661,14 @@ int BPY_txt_do_python_Text( struct Text *text )
script->py_event = NULL;
script->py_button = NULL;
script->py_browsercallback = NULL;
+ strncpy(script->scriptname, text->id.name+2, sizeof(script->scriptname));
+ gilstate = PyGILState_Ensure();
py_dict = CreateGlobalDictionary( );
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict\n");
+ PyGILState_Release(gilstate);
return 0;
}
@@ -601,7 +693,7 @@ int BPY_txt_do_python_Text( struct Text *text )
script->py_globaldict = NULL;
if( G.main->script.first )
free_libblock( &G.main->script, script );
-
+ PyGILState_Release(gilstate);
return 0;
} else {
Py_DECREF( py_result );
@@ -613,6 +705,8 @@ int BPY_txt_do_python_Text( struct Text *text )
}
}
+ PyGILState_Release(gilstate);
+
return 1; /* normal return */
}
@@ -674,6 +768,178 @@ void BPY_run_python_script( char *fn )
}
}
+int BPY_run_script(Script *script)
+{
+ PyObject *py_dict, *py_res, *pyarg;
+ Text *text = NULL;
+ BPy_constant *info;
+ int len;
+ char *buffer=NULL, *s;
+
+ FILE *fp = NULL;
+
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ if (!BLI_exists(script->scriptname)) {
+ /* The file dosnt exist, maybe this blend file was made on some other persons computer? */
+ char fname[FILE_MAX];
+ char fpath[FILE_MAX];
+ char ftmp[FILE_MAX];
+
+ strcpy(ftmp, script->scriptname);
+ BLI_split_dirfile(ftmp, fpath, fname);
+ BLI_make_file_string("/", fpath, bpy_gethome(1), fname);
+
+ if (BLI_exists(fpath)) {
+ strncpy(script->scriptname, fpath, sizeof(script->scriptname));
+ } else if (U.pythondir[0]) {
+ BLI_make_file_string("/", fpath, U.pythondir, fname);
+ if (BLI_exists(fpath)) {
+ strncpy(script->scriptname, fpath, sizeof(script->scriptname));
+ }
+ }
+
+ /* cant find the file?, fallback to text block */
+ if (!BLI_exists(script->scriptname)) {
+ for (text=G.main->text.first; text; text=text->id.next) {
+ if (strcmp(script->scriptname, text->id.name+2)==0) {
+ break;
+ }
+ }
+ }
+ }
+ if (text) {
+ Py_INCREF( Py_None );
+ pyarg = Py_None;
+ } else {
+ fp = fopen( script->scriptname, "rb" );
+ if( !fp ) {
+ printf( "Error loading script: couldn't open file %s\n", script->scriptname );
+ if( G.main->script.first )
+ free_libblock( &G.main->script, script );
+ PyGILState_Release(gilstate);
+ return 0;
+ }
+
+ if( script->scriptarg[0] == '\0' ) { /* no submenus */
+ Py_INCREF( Py_None );
+ pyarg = Py_None;
+ } else {
+ pyarg = PyString_FromString( script->scriptarg );
+ }
+ }
+
+ script->id.us = 1;
+ script->flags = SCRIPT_RUNNING;
+ script->py_draw = NULL;
+ script->py_event = NULL;
+ script->py_button = NULL;
+ script->py_browsercallback = NULL;
+
+ py_dict = CreateGlobalDictionary( );
+
+ script->py_globaldict = py_dict;
+
+ if( !setup_armature_weakrefs()){
+ printf("Oops - weakref dict\n");
+ if( G.main->script.first )
+ free_libblock( &G.main->script, script );
+ ReleaseGlobalDictionary( py_dict );
+ MEM_freeN( buffer );
+ PyGILState_Release(gilstate);
+ return 0;
+ }
+
+ info = ( BPy_constant * ) PyConstant_New( );
+ if( info ) {
+ PyConstant_Insert( info, "name",
+ PyString_FromString( script->id.name + 2 ) );
+ PyConstant_Insert( info, "arg", pyarg );
+ EXPP_dict_set_item_str( py_dict, "__script__",
+ ( PyObject * ) info );
+ }
+
+ if (text) {
+ py_res = RunPython( text, py_dict );
+ } else {
+ /* Previously we used PyRun_File to run directly the code on a FILE
+ * object, but as written in the Python/C API Ref Manual, chapter 2,
+ * 'FILE structs for different C libraries can be different and
+ * incompatible'.
+ * So now we load the script file data to a buffer */
+
+ fseek( fp, 0L, SEEK_END );
+ len = ftell( fp );
+ fseek( fp, 0L, SEEK_SET );
+
+ buffer = MEM_mallocN( len + 2, "pyfilebuf" ); /* len+2 to add '\n\0' */
+ len = fread( buffer, 1, len, fp );
+
+ buffer[len] = '\n'; /* fix syntax error in files w/o eol */
+ buffer[len + 1] = '\0';
+
+ /* fast clean-up of dos cr/lf line endings: change '\r' to space */
+
+ /* we also have to check for line splitters: '\\' */
+ /* to avoid possible syntax errors on dos files on win */
+ /**/
+ /* but first make sure we won't disturb memory below &buffer[0]: */
+ if( *buffer == '\r' )
+ *buffer = ' ';
+
+ /* now handle the whole buffer */
+ for( s = buffer + 1; *s != '\0'; s++ ) {
+ if( *s == '\r' ) {
+ if( *( s - 1 ) == '\\' ) { /* special case: long lines split with '\': */
+ *( s - 1 ) = ' '; /* we write ' \', because '\ ' is a syntax error */
+ *s = '\\';
+ } else
+ *s = ' '; /* not a split line, just replace '\r' with ' ' */
+ }
+ }
+
+ fclose( fp );
+
+
+ py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
+ MEM_freeN( buffer );
+ }
+
+ if( !py_res ) { /* Failed execution of the script */
+
+ BPY_Err_Handle( script->id.name + 2 );
+ ReleaseGlobalDictionary( py_dict );
+ script->py_globaldict = NULL;
+ if( G.main->script.first )
+ free_libblock( &G.main->script, script );
+ error( "Python script error: check console" );
+
+ PyGILState_Release(gilstate);
+ return 0;
+ } else {
+ Py_DECREF( py_res );
+ script->flags &= ~SCRIPT_RUNNING;
+
+ if( !script->flags ) {
+ ReleaseGlobalDictionary( py_dict );
+ script->py_globaldict = NULL;
+ free_libblock( &G.main->script, script );
+
+ /* special case: called from the menu in the Scripts window
+ * we have to change sc->script pointer, since it'll be freed here.*/
+ if( curarea->spacetype == SPACE_SCRIPT ) {
+ SpaceScript *sc = curarea->spacedata.first;
+ sc->script = G.main->script.first; /* can be null, which is ok ... */
+ /* ... meaning no other script is running right now. */
+ }
+
+ }
+ }
+
+ PyGILState_Release(gilstate);
+ return 1;
+}
+
/****************************************************************************
* Description: This function executes the script chosen from a menu.
* Notes: It is called by the ui code in src/header_???.c when a user
@@ -683,22 +949,22 @@ void BPY_run_python_script( char *fn )
*****************************************************************************/
int BPY_menu_do_python( short menutype, int event )
{
- PyObject *py_dict, *py_res, *pyarg = NULL;
- BPy_constant *info;
+ char *argstr = NULL;
BPyMenu *pym;
BPySubMenu *pysm;
- FILE *fp = NULL;
- char *buffer, *s;
- char filestr[FILE_MAXDIR + FILE_MAXFILE];
char scriptname[21];
Script *script = NULL;
- int len;
+ int ret, len;
+ PyGILState_STATE gilstate;
+ char filestr[FILE_MAX];
pym = BPyMenu_GetEntry( menutype, ( short ) event );
if( !pym )
return 0;
+ gilstate = PyGILState_Ensure();
+
if( pym->version > G.version )
notice( "Version mismatch: script was written for Blender %d. "
"It may fail with yours: %d.", pym->version,
@@ -720,17 +986,14 @@ int BPY_menu_do_python( short menutype, int event )
if( arg >= 0 ) {
while( arg-- )
pysm = pysm->next;
- pyarg = PyString_FromString( pysm->arg );
- } else
+ argstr = pysm->arg;
+ } else {
+ PyGILState_Release(gilstate);
return 0;
+ }
}
}
- if( !pyarg ) { /* no submenus */
- Py_INCREF( Py_None );
- pyarg = Py_None;
- }
-
if( pym->dir ) { /* script is in U.pythondir */
char upythondir[FILE_MAXDIR];
@@ -744,19 +1007,13 @@ int BPY_menu_do_python( short menutype, int event )
if (!scriptsdir) {
printf("Error loading script: can't find default scripts dir!");
+ PyGILState_Release(gilstate);
return 0;
}
BLI_make_file_string( "/", filestr, scriptsdir, pym->filename );
}
- fp = fopen( filestr, "rb" );
- if( !fp ) {
- printf( "Error loading script: couldn't open file %s\n",
- filestr );
- return 0;
- }
-
BLI_strncpy(scriptname, pym->name, 21);
len = strlen(scriptname) - 1;
/* by convention, scripts that open the file browser or have submenus
@@ -771,7 +1028,7 @@ int BPY_menu_do_python( short menutype, int event )
if( !script ) {
printf( "couldn't allocate memory for Script struct!" );
- fclose( fp );
+ PyGILState_Release(gilstate);
return 0;
}
@@ -815,107 +1072,12 @@ int BPY_menu_do_python( short menutype, int event )
}
break;
}
-
- script->id.us = 1;
- script->flags = SCRIPT_RUNNING;
- script->py_draw = NULL;
- script->py_event = NULL;
- script->py_button = NULL;
- script->py_browsercallback = NULL;
-
- py_dict = CreateGlobalDictionary( );
-
- script->py_globaldict = py_dict;
-
- info = ( BPy_constant * ) PyConstant_New( );
- if( info ) {
- PyConstant_Insert( info, "name",
- PyString_FromString( script->id.name + 2 ) );
- PyConstant_Insert( info, "arg", pyarg );
- EXPP_dict_set_item_str( py_dict, "__script__",
- ( PyObject * ) info );
- }
-
- /* Previously we used PyRun_File to run directly the code on a FILE
- * object, but as written in the Python/C API Ref Manual, chapter 2,
- * 'FILE structs for different C libraries can be different and
- * incompatible'.
- * So now we load the script file data to a buffer */
-
- fseek( fp, 0L, SEEK_END );
- len = ftell( fp );
- fseek( fp, 0L, SEEK_SET );
-
- buffer = MEM_mallocN( len + 2, "pyfilebuf" ); /* len+2 to add '\n\0' */
- len = fread( buffer, 1, len, fp );
-
- buffer[len] = '\n'; /* fix syntax error in files w/o eol */
- buffer[len + 1] = '\0';
-
- /* fast clean-up of dos cr/lf line endings: change '\r' to space */
-
- /* we also have to check for line splitters: '\\' */
- /* to avoid possible syntax errors on dos files on win */
- /**/
- /* but first make sure we won't disturb memory below &buffer[0]: */
- if( *buffer == '\r' )
- *buffer = ' ';
-
- /* now handle the whole buffer */
- for( s = buffer + 1; *s != '\0'; s++ ) {
- if( *s == '\r' ) {
- if( *( s - 1 ) == '\\' ) { /* special case: long lines split with '\': */
- *( s - 1 ) = ' '; /* we write ' \', because '\ ' is a syntax error */
- *s = '\\';
- } else
- *s = ' '; /* not a split line, just replace '\r' with ' ' */
- }
- }
-
- fclose( fp );
-
-
- if( !setup_armature_weakrefs()){
- printf("Oops - weakref dict\n");
- MEM_freeN( buffer );
- return 0;
- }
-
- /* run the string buffer */
-
- py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
-
- MEM_freeN( buffer );
-
- if( !py_res ) { /* Failed execution of the script */
-
- BPY_Err_Handle( script->id.name + 2 );
- ReleaseGlobalDictionary( py_dict );
- script->py_globaldict = NULL;
- if( G.main->script.first )
- free_libblock( &G.main->script, script );
- error( "Python script error: check console" );
-
- return 0;
- } else {
- Py_DECREF( py_res );
- script->flags &= ~SCRIPT_RUNNING;
-
- if( !script->flags ) {
- ReleaseGlobalDictionary( py_dict );
- script->py_globaldict = NULL;
- free_libblock( &G.main->script, script );
-
- /* special case: called from the menu in the Scripts window
- * we have to change sc->script pointer, since it'll be freed here.*/
- if( curarea->spacetype == SPACE_SCRIPT ) {
- SpaceScript *sc = curarea->spacedata.first;
- sc->script = G.main->script.first; /* can be null, which is ok ... */
- /* ... meaning no other script is running right now. */
- }
-
- }
- }
+
+ strncpy(script->scriptname, filestr, sizeof(script->scriptname));
+ if (argstr!=NULL && argstr[0] != '\0')
+ strncpy(script->scriptarg, argstr, sizeof(script->scriptarg));
+
+ ret = BPY_run_script(script);
return 1; /* normal return */
}
@@ -939,14 +1101,20 @@ void BPY_free_compiled_text( struct Text *text )
*****************************************************************************/
void BPY_free_finished_script( Script * script )
{
+ PyGILState_STATE gilstate;
+
if( !script )
return;
+ gilstate = PyGILState_Ensure();
+
if( PyErr_Occurred( ) ) { /* if script ended after filesel */
PyErr_Print( ); /* eventual errors are handled now */
error( "Python script error: check console" );
}
+ PyGILState_Release(gilstate);
+
free_libblock( &G.main->script, script );
return;
}
@@ -981,13 +1149,17 @@ static void unlink_script( Script * script )
void BPY_clear_script( Script * script )
{
PyObject *dict;
+ PyGILState_STATE gilstate;
if( !script )
return;
+ gilstate = PyGILState_Ensure();
+
if (!Py_IsInitialized()) {
printf("\nError: trying to free script data after finalizing Python!");
printf("\nScript name: %s\n", script->id.name+2);
+ PyGILState_Release(gilstate);
return;
}
@@ -999,7 +1171,9 @@ void BPY_clear_script( Script * script )
script->py_event = NULL;
script->py_button = NULL;
script->py_browsercallback = NULL;
-
+ script->scriptname[0] = '\0';
+ script->scriptarg[0] = '\0';
+
dict = script->py_globaldict;
if( dict ) {
@@ -1008,6 +1182,8 @@ void BPY_clear_script( Script * script )
script->py_globaldict = NULL;
}
+ PyGILState_Release(gilstate);
+
unlink_script( script );
}
@@ -1042,10 +1218,13 @@ static int bpy_pydriver_create_dict(void)
mod = PyImport_ImportModule("math");
if (mod) {
+ PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
+
+ /* Only keep for backwards compat! - just import all math into root, they are standard */
PyDict_SetItemString(d, "math", mod);
PyDict_SetItemString(d, "m", mod);
Py_DECREF(mod);
- }
+ }
mod = PyImport_ImportModule("Blender.Noise");
if (mod) {
@@ -1077,7 +1256,8 @@ static int bpy_pydriver_create_dict(void)
Py_DECREF(fcn);
}
}
-
+
+ /* TODO - change these */
/* me(meshname) == Blender.Mesh.Get(meshname) */
mod = PyImport_ImportModule("Blender.Mesh");
if (mod) {
@@ -1127,18 +1307,629 @@ static float pydriver_error(IpoDriver *driver) {
return 0.0f;
}
+
+/********PyConstraints*********/
+
+/* This function checks whether a text-buffer is a PyConstraint candidate.
+ * It uses simple text parsing that could be easily confused!
+ */
+int BPY_is_pyconstraint(Text *text)
+{
+ TextLine *tline = text->lines.first;
+
+ if (tline && (tline->len > 10)) {
+ char *line = tline->line;
+
+ /* Expected format: #BPYCONSTRAINT
+ * The actual checks are forgiving, so slight variations also work. */
+ if (line && line[0] == '#' && strstr(line, "BPYCONSTRAINT")) return 1;
+ }
+ return 0;
+}
+
+/* This function frees links from pyconstraints to a given text-buffer.
+ * Used when a text-buffer is unlinked!
+ */
+void BPY_free_pyconstraint_links(Text *text)
+{
+ Object *ob;
+ bConstraint *con;
+ short update;
+
+ /*check all pyconstraints*/
+ for (ob=G.main->object.first; ob; ob=ob->id.next) {
+ update = 0;
+ if(ob->type==OB_ARMATURE && ob->pose) {
+ bPoseChannel *pchan;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (con = pchan->constraints.first; con; con=con->next) {
+ if (con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) data->text = NULL;
+ update = 1;
+
+ }
+ }
+ }
+ }
+ for (con = ob->constraints.first; con; con=con->next) {
+ if (con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) data->text = NULL;
+ update = 1;
+ }
+ }
+
+ if (update) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+}
+
+/* This function is called to update PyConstraint data so that it is compatible with the script.
+ * Some of the allocating/freeing of memory for constraint targets occurs here, espcially
+ * if the number of targets changes.
+ */
+void BPY_pyconstraint_update(Object *owner, bConstraint *con)
+{
+ bPythonConstraint *data= con->data;
+
+ if (data->text) {
+ /* script does exist. it is assumed that this is a valid pyconstraint script */
+ PyObject *globals;
+ PyObject *retval, *gval;
+ PyGILState_STATE gilstate;
+ int num, i;
+
+ /* clear the relevant flags first */
+ data->flag = 0;
+
+ gilstate = PyGILState_Ensure();
+
+ /* populate globals dictionary */
+ globals = CreateGlobalDictionary();
+ retval = RunPython(data->text, globals);
+
+ if (retval == NULL) {
+ BPY_Err_Handle(data->text->id.name);
+ ReleaseGlobalDictionary(globals);
+ data->flag |= PYCON_SCRIPTERROR;
+ PyGILState_Release(gilstate);
+ return;
+ }
+
+ Py_XDECREF(retval);
+ retval = NULL;
+
+ /* try to find NUM_TARGETS */
+ gval = PyDict_GetItemString(globals, "NUM_TARGETS");
+ if ( (gval) && (num= PyInt_AsLong(gval)) ) {
+ /* NUM_TARGETS is defined... and non-zero */
+ bConstraintTarget *ct;
+
+ /* check if it is valid (just make sure it is not negative)
+ * TODO: PyInt_AsLong may return -1 as sign of invalid input...
+ */
+ num = abs(num);
+ data->flag |= PYCON_USETARGETS;
+
+ /* check if the number of targets has changed */
+ if (num < data->tarnum) {
+ /* free a few targets */
+ num= data->tarnum - num;
+ for (i = 0; i < num; i++, data->tarnum--) {
+ ct= data->targets.last;
+ BLI_freelinkN(&data->targets, ct);
+ }
+ }
+ else if (num > data->tarnum) {
+ /* add a few targets */
+ num = num - data->tarnum;
+ for (i = 0; i < num; i++, data->tarnum++) {
+ ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
+ BLI_addtail(&data->targets, ct);
+ }
+ }
+
+ /* validate targets */
+ con->flag &= ~CONSTRAINT_DISABLE;
+ for (ct= data->targets.first; ct; ct= ct->next) {
+ if (!exist_object(ct->tar)) {
+ ct->tar = NULL;
+ con->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+
+ if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
+ if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
+ con->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ }
+
+ /* clear globals */
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+ else {
+ /* NUM_TARGETS is not defined or equals 0 */
+ ReleaseGlobalDictionary(globals);
+
+ /* free all targets */
+ BLI_freelistN(&data->targets);
+ data->tarnum = 0;
+ data->flag &= ~PYCON_USETARGETS;
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+ }
+ else {
+ /* no script, so clear any settings/data now */
+ data->tarnum = 0;
+ data->flag = 0;
+ con->flag &= ~CONSTRAINT_DISABLE;
+
+ BLI_freelistN(&data->targets);
+
+ /* supposedly this should still leave the base struct... */
+ IDP_FreeProperty(data->prop);
+ }
+}
+
+/* PyConstraints Evaluation Function (only called from evaluate_constraint)
+ * This function is responsible for modifying the ownermat that it is passed.
+ */
+void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ PyObject *srcmat, *tarmat, *tarmats, *idprop;
+ PyObject *globals;
+ PyObject *gval;
+ PyObject *pyargs, *retval;
+ bConstraintTarget *ct;
+ MatrixObject *retmat;
+ int row, col, index;
+ PyGILState_STATE gilstate;
+
+ if (!con->text) return;
+ if (con->flag & PYCON_SCRIPTERROR) return;
+
+ gilstate = PyGILState_Ensure();
+
+ globals = CreateGlobalDictionary();
+
+ /* wrap blender-data as PyObjects for evaluation
+ * - we expose the owner's matrix as pymatrix
+ * - id-properties are wrapped using the id-properties pyapi
+ * - targets are presented as a list of matrices
+ */
+ srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
+ idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
+
+ tarmats= PyList_New(con->tarnum);
+ for (ct=targets->first, index=0; ct; ct=ct->next, index++) {
+ tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
+ PyList_SET_ITEM(tarmats, index, tarmat);
+ }
+
+ if (!setup_armature_weakrefs()) {
+ fprintf(stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ retval = RunPython(con->text, globals);
+
+ if (retval == NULL) {
+ BPY_Err_Handle(con->text->id.name);
+ con->flag |= PYCON_SCRIPTERROR;
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (retval) {Py_XDECREF( retval );}
+ retval = NULL;
+
+ gval = PyDict_GetItemString(globals, "doConstraint");
+ if (!gval) {
+ printf("ERROR: no doConstraint function in constraint!\n");
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ /* Now for the fun part! Try and find the functions we need. */
+ if (PyFunction_Check(gval)) {
+ pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
+ retval = PyObject_CallObject(gval, pyargs);
+ Py_XDECREF(pyargs);
+ }
+ else {
+ printf("ERROR: doConstraint is supposed to be a function!\n");
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (!retval) {
+ BPY_Err_Handle(con->text->id.name);
+ con->flag |= PYCON_SCRIPTERROR;
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+
+ if (!PyObject_TypeCheck(retval, &matrix_Type)) {
+ printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+ Py_XDECREF(retval);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ retmat = (MatrixObject *)retval;
+ if (retmat->rowSize != 4 || retmat->colSize != 4) {
+ printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+ Py_XDECREF(retval);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ /* this is the reverse of code taken from newMatrix() */
+ for(row = 0; row < 4; row++) {
+ for(col = 0; col < 4; col++) {
+ cob->matrix[row][col] = retmat->contigPtr[row*4+col];
+ }
+ }
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+ Py_XDECREF(srcmat);
+ Py_XDECREF(tarmats);
+ Py_XDECREF(retval);
+
+ /* clear globals */
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+}
+
+/* This evaluates the target matrix for each target the PyConstraint uses.
+ * NOTE: it only does one target at a time!
+ */
+void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
+{
+ PyObject *tar, *subtar;
+ PyObject *tarmat, *idprop;
+ PyObject *globals;
+ PyObject *gval;
+ PyObject *pyargs, *retval;
+ MatrixObject *retmat;
+ int row, col;
+ PyGILState_STATE gilstate;
+
+ if (!con->text) return;
+ if (con->flag & PYCON_SCRIPTERROR) return;
+ if (!ct) return;
+
+ gilstate = PyGILState_Ensure();
+
+ globals = CreateGlobalDictionary();
+
+ tar = Object_CreatePyObject(ct->tar);
+ if ((ct->tar) && (ct->tar->type==OB_ARMATURE)) {
+ bPoseChannel *pchan;
+ pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
+ subtar = PyPoseBone_FromPosechannel(pchan);
+ }
+ else
+ subtar = PyString_FromString(ct->subtarget);
+
+ tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
+ idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
+
+ if (!setup_armature_weakrefs()) {
+ fprintf(stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
+ return;
+ }
+
+ retval = RunPython(con->text, globals);
+
+ if (retval == NULL) {
+ BPY_Err_Handle(con->text->id.name);
+ con->flag |= PYCON_SCRIPTERROR;
+
+ /* free temp objects */
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ Py_XDECREF(retval);
+ retval = NULL;
+
+ /* try to find doTarget function to set the target matrix */
+ gval = PyDict_GetItemString(globals, "doTarget");
+ if (!gval) {
+ /* free temp objects */
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ /* Now for the fun part! Try and find the functions we need.*/
+ if (PyFunction_Check(gval)) {
+ pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
+ retval = PyObject_CallObject(gval, pyargs);
+ Py_XDECREF(pyargs);
+ }
+ else {
+ printf("ERROR: doTarget is supposed to be a function!\n");
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (!retval) {
+ BPY_Err_Handle(con->text->id.name);
+ con->flag |= PYCON_SCRIPTERROR;
+
+
+ /* free temp objects */
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (!PyObject_TypeCheck(retval, &matrix_Type)) {
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+ Py_XDECREF(retval);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ retmat = (MatrixObject *)retval;
+ if (retmat->rowSize != 4 || retmat->colSize != 4) {
+ printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
+ con->flag |= PYCON_SCRIPTERROR;
+
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+ Py_XDECREF(retval);
+
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ /* this is the reverse of code taken from newMatrix() */
+ for(row = 0; row < 4; row++) {
+ for(col = 0; col < 4; col++) {
+ ct->matrix[row][col] = retmat->contigPtr[row*4+col];
+ }
+ }
+
+ /* free temp objects */
+ Py_XDECREF(tar);
+ Py_XDECREF(subtar);
+ Py_XDECREF(idprop);
+ Py_XDECREF(tarmat);
+ Py_XDECREF(retval);
+
+ /* clear globals */
+ ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+}
+
+/* This draws+handles the user-defined interface for editing pyconstraints idprops */
+void BPY_pyconstraint_settings(void *arg1, void *arg2)
+{
+ bPythonConstraint *con= (bPythonConstraint *)arg1;
+ PyObject *idprop;
+ PyObject *globals;
+ PyObject *gval;
+ PyObject *retval;
+ PyGILState_STATE gilstate;
+
+ if (!con->text) return;
+ if (con->flag & PYCON_SCRIPTERROR) return;
+
+ gilstate = PyGILState_Ensure();
+
+ globals = CreateGlobalDictionary();
+
+ idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
+
+ retval = RunPython(con->text, globals);
+
+ if (retval == NULL) {
+ BPY_Err_Handle(con->text->id.name);
+ ReleaseGlobalDictionary(globals);
+ con->flag |= PYCON_SCRIPTERROR;
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (retval) {Py_XDECREF( retval );}
+ retval = NULL;
+
+ gval = PyDict_GetItemString(globals, "getSettings");
+ if (!gval) {
+ printf("ERROR: no getSettings function in constraint!\n");
+
+ /* free temp objects */
+ ReleaseGlobalDictionary( globals );
+ Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ /* Now for the fun part! Try and find the functions we need. */
+ if (PyFunction_Check(gval)) {
+ retval = PyObject_CallFunction(gval, "O", idprop);
+ }
+ else {
+ printf("ERROR: getSettings is supposed to be a function!\n");
+ ReleaseGlobalDictionary( globals );
+
+ Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+
+ if (!retval) {
+ BPY_Err_Handle(con->text->id.name);
+ con->flag |= PYCON_SCRIPTERROR;
+
+ /* free temp objects */
+ ReleaseGlobalDictionary(globals);
+ Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+ else {
+ /* clear globals */
+ ReleaseGlobalDictionary(globals);
+
+ /* free temp objects */
+ Py_XDECREF(idprop);
+ Py_DECREF(retval);
+
+ PyGILState_Release(gilstate);
+
+ return;
+ }
+}
+
/* Update function, it gets rid of pydrivers global dictionary, forcing
* BPY_pydriver_eval to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
* updates in it reach pydriver evaluation. */
void BPY_pydriver_update(void)
{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
PyDict_Clear(bpy_pydriver_Dict);
Py_DECREF(bpy_pydriver_Dict);
bpy_pydriver_Dict = NULL;
}
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1178,18 +1969,22 @@ struct Object **BPY_pydriver_get_objects(IpoDriver *driver)
float BPY_pydriver_eval(IpoDriver *driver)
{
char *expr = NULL;
- PyObject *retval, *floatval, *bpy_ob = NULL;
+ PyObject *retval, *bpy_ob = NULL;
float result = 0.0f; /* default return */
int setitem_retval;
+ PyGILState_STATE gilstate;
if (!driver) return result;
expr = driver->name; /* the py expression to be evaluated */
if (!expr || expr[0]=='\0') return result;
+ gilstate = PyGILState_Ensure();
+
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
+ PyGILState_Release(gilstate);
return result;
}
}
@@ -1206,6 +2001,7 @@ float BPY_pydriver_eval(IpoDriver *driver)
if( !setup_armature_weakrefs()){
fprintf( stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
return result;
}
@@ -1213,17 +2009,18 @@ float BPY_pydriver_eval(IpoDriver *driver)
bpy_pydriver_Dict);
if (retval == NULL) {
- return pydriver_error(driver);
+ result = pydriver_error(driver);
+ PyGILState_Release(gilstate);
+ return result;
}
- floatval = PyNumber_Float(retval);
- Py_DECREF(retval);
-
- if (floatval == NULL)
- return pydriver_error(driver);
-
- result = (float)PyFloat_AsDouble(floatval);
- Py_DECREF(floatval);
+ result = ( float )PyFloat_AsDouble( retval );
+
+ if (result == -1 && PyErr_Occurred()) {
+ result = pydriver_error(driver);
+ PyGILState_Release(gilstate);
+ return result;
+ }
/* remove 'self', since this dict is also used by py buttons */
if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
@@ -1231,6 +2028,8 @@ float BPY_pydriver_eval(IpoDriver *driver)
/* all fine, make sure the "invalid expression" flag is cleared */
driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
+ PyGILState_Release(gilstate);
+
return result;
}
@@ -1267,15 +2066,20 @@ static int bpy_button_eval_error(char *expr) {
int BPY_button_eval(char *expr, double *value)
{
PyObject *retval, *floatval;
+ PyGILState_STATE gilstate;
+ int ret;
if (!value || !expr || expr[0]=='\0') return -1;
*value = 0.0; /* default value */
+ gilstate = PyGILState_Ensure();
+
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
fprintf(stderr,
"Button Python Eval error: couldn't create Python dictionary");
+ PyGILState_Release(gilstate);
return -1;
}
}
@@ -1283,6 +2087,7 @@ int BPY_button_eval(char *expr, double *value)
if( !setup_armature_weakrefs()){
fprintf(stderr, "Oops - weakref dict\n");
+ PyGILState_Release(gilstate);
return -1;
}
@@ -1290,20 +2095,26 @@ int BPY_button_eval(char *expr, double *value)
bpy_pydriver_Dict);
if (retval == NULL) {
- return bpy_button_eval_error(expr);
+ ret = bpy_button_eval_error(expr);
+ PyGILState_Release(gilstate);
+ return ret;
}
else {
floatval = PyNumber_Float(retval);
Py_DECREF(retval);
}
- if (floatval == NULL)
- return bpy_button_eval_error(expr);
- else {
+ if (floatval == NULL) {
+ ret = bpy_button_eval_error(expr);
+ PyGILState_Release(gilstate);
+ return ret;
+ } else {
*value = (float)PyFloat_AsDouble(floatval);
Py_DECREF(floatval);
}
+ PyGILState_Release(gilstate);
+
return 0; /* successful exit */
}
@@ -1404,14 +2215,31 @@ void BPY_do_pyscript( ID * id, short event )
scriptlink = ID_getScriptlink( id );
if( scriptlink && scriptlink->totscript ) {
+ PyObject *value;
PyObject *dict;
PyObject *ret;
int index, during_slink = during_scriptlink( );
+ PyGILState_STATE gilstate;
/* invalid scriptlinks (new .blend was just loaded), return */
if( during_slink < 0 )
return;
+ gilstate = PyGILState_Ensure();
+
+ if( !setup_armature_weakrefs()){
+ printf("Oops - weakref dict, this is a bug\n");
+ PyGILState_Release(gilstate);
+ return;
+ }
+
+ value = GetPyObjectFromID( id );
+ if( !value){
+ printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
+ PyGILState_Release(gilstate);
+ return;
+ }
+
/* tell we're running a scriptlink. The sum also tells if this script
* is running nested inside another. Blender.Load needs this info to
* avoid trouble with invalid slink pointers. */
@@ -1419,13 +2247,11 @@ void BPY_do_pyscript( ID * id, short event )
disable_where_scriptlink( (short)during_slink );
/* set globals in Blender module to identify scriptlink */
- EXPP_dict_set_item_str( g_blenderdict, "bylink", EXPP_incr_ret_True() );
- EXPP_dict_set_item_str( g_blenderdict, "link",
- GetPyObjectFromID( id ) );
+ PyDict_SetItemString( g_blenderdict, "bylink", Py_True);
+ EXPP_dict_set_item_str( g_blenderdict, "link", value );
EXPP_dict_set_item_str( g_blenderdict, "event",
PyString_FromString( event_to_name
( event ) ) );
-
if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
for( index = 0; index < scriptlink->totscript; index++ ) {
@@ -1461,10 +2287,11 @@ void BPY_do_pyscript( ID * id, short event )
/* cleanup bylink flag and clear link so PyObject
* can be released
*/
- EXPP_dict_set_item_str( g_blenderdict, "bylink", EXPP_incr_ret_False() );
+ PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
PyDict_SetItemString( g_blenderdict, "link", Py_None );
- EXPP_dict_set_item_str( g_blenderdict, "event",
- PyString_FromString( "" ) );
+ EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
+
+ PyGILState_Release(gilstate);
}
}
@@ -1616,6 +2443,7 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
{
ScriptLink *scriptlink;
int retval = 0;
+ PyGILState_STATE gilstate;
if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
@@ -1638,17 +2466,24 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
during_slink++;
disable_where_scriptlink( (short)during_slink );
}
-
+
+ gilstate = PyGILState_Ensure();
+
+ if( !setup_armature_weakrefs()){
+ printf("Oops - weakref dict, this is a bug\n");
+ PyGILState_Release(gilstate);
+ return 0;
+ }
+
/* set globals in Blender module to identify space handler scriptlink */
- EXPP_dict_set_item_str(g_blenderdict, "bylink", EXPP_incr_ret_True());
+ PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
/* unlike normal scriptlinks, here Blender.link is int (space event type) */
EXPP_dict_set_item_str(g_blenderdict, "link", PyInt_FromLong(space_event));
/* note: DRAW space_events set event to 0 */
EXPP_dict_set_item_str(g_blenderdict, "event", PyInt_FromLong(event));
-
/* now run all assigned space handlers for this space and space_event */
for( index = 0; index < scriptlink->totscript; index++ ) {
-
+
/* for DRAW handlers: */
if (event == 0) {
glPushAttrib(GL_ALL_ATTRIB_BITS);
@@ -1657,7 +2492,7 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}
-
+
if( ( scriptlink->flag[index] == space_event ) &&
( scriptlink->scripts[index] != NULL ) ) {
dict = CreateGlobalDictionary();
@@ -1677,7 +2512,7 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
retval = 1; /* event was swallowed */
}
-
+
/* If a scriptlink has just loaded a new .blend file, the
* scriptlink pointer became invalid (see api2_2x/Blender.c),
* so we stop here. */
@@ -1687,7 +2522,7 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
break;
}
}
-
+
/* for DRAW handlers: */
if (event == 0) {
glMatrixMode(GL_PROJECTION);
@@ -1697,12 +2532,14 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
glPopAttrib();
disable_where_scriptlink( (short)(during_slink - 1) );
}
-
+
}
-
- EXPP_dict_set_item_str(g_blenderdict, "bylink", EXPP_incr_ret_False());
+
+ PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
PyDict_SetItemString(g_blenderdict, "link", Py_None );
EXPP_dict_set_item_str(g_blenderdict, "event", PyString_FromString(""));
+
+ PyGILState_Release(gilstate);
}
/* retval:
@@ -2110,3 +2947,17 @@ void init_ourReload( void )
d = PyModule_GetDict( m );
EXPP_dict_set_item_str( d, "reload", reload );
}
+
+
+void BPY_scripts_clear_pyobjects( void )
+{
+ Script *script;
+ for (script=G.main->script.first; script; script=script->id.next) {
+ Py_XDECREF((PyObject *)script->py_draw);
+ Py_XDECREF((PyObject *)script->py_event);
+ Py_XDECREF((PyObject *)script->py_button);
+ Py_XDECREF((PyObject *)script->py_browsercallback);
+ Py_XDECREF((PyObject *)script->py_globaldict);
+ SCRIPT_SET_NULL(script)
+ }
+}
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c
index 5f16aa0241b..202c4e40b51 100644
--- a/source/blender/python/BPY_menus.c
+++ b/source/blender/python/BPY_menus.c
@@ -457,6 +457,7 @@ static int bpymenu_CreateFromFile( void )
{
FILE *fp;
char line[255], w1[255], w2[255], tooltip[255], *tip;
+ char upythondir[FILE_MAXDIR];
char *homedir = NULL;
int parsing, version, is_userdir;
short group;
@@ -492,15 +493,14 @@ static int bpymenu_CreateFromFile( void )
* current one. If so, return to force updating from dirs */
w1[0] = '\0';
fscanf( fp, "# User defined scripts dir: %[^\n]\n", w1 );
- if( w1 ) {
- char upythondir[FILE_MAXDIR];
- BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
- BLI_convertstringcode(upythondir, G.sce, 0);
- if( strcmp( w1, upythondir ) != 0 )
- return -1;
- w1[0] = '\0';
- }
+ BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
+ BLI_convertstringcode(upythondir, G.sce, 0);
+
+ if( strcmp( w1, upythondir ) != 0 )
+ return -1;
+
+ w1[0] = '\0';
while( fgets( line, 255, fp ) ) { /* parsing file lines */
@@ -933,13 +933,25 @@ static int bpymenu_ParseDir(char *dirname, char *parentdir, int is_userdir )
return 0;
}
-static int bpymenu_GetStatMTime( char *name, int is_file, time_t * mtime )
+static int bpymenu_GetStatMTime( const char *name, int is_file, time_t * mtime )
{
struct stat st;
int result;
+#ifdef WIN32
+ if (is_file) {
+ result = stat( name, &st );
+ } else {
+ /* needed for win32 only, remove trailing slash */
+ char name_stat[FILE_MAX];
+ BLI_strncpy(name_stat, name, FILE_MAX);
+ BLI_del_slash(name_stat);
+ result = stat( name_stat, &st );
+ }
+#else
result = stat( name, &st );
-
+#endif
+
if( result == -1 )
return -1;
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index 59fc6746d86..481fdcbe13e 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -3,7 +3,7 @@ Import ('env')
sources = Split('BPY_interface.c BPY_menus.c') + env.Glob('api2_2x/*.c')
-incs = 'api2_2x ../blenkernel ../blenlib ../blenloader'
+incs = 'api2_2x ../blenkernel ../nodes ../blenlib ../blenloader'
incs += ' ../render/extern/include ../radiosity/extern/include'
incs += ' ../makesdna #intern/guardedalloc #intern/bmfont ../imbuf ../include'
incs += ' ' + env['BF_PYTHON_INC']
@@ -20,4 +20,7 @@ if env['WITH_BF_QUICKTIME']==1:
if env['WITH_BF_OPENEXR'] == 1:
defs.append('WITH_OPENEXR')
+if env['WITH_BF_FFMPEG'] == 1:
+ defs.append('WITH_FFMPEG')
+
env.BlenderLib ( libname='blender_python', sources = Split(sources), includes = Split(incs), defines = defs, libtype=['core','game2'], priority = [60,115] )
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index c82597f9b00..05caca1cc2f 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -60,6 +60,10 @@ static const char sArmatureBadArgs[] = "ArmatureType - Bad Arguments: ";
static const char sModuleError[] = "Blender.Armature - Error: ";
static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
+PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref);
+/* python callable */
+PyObject * arm_weakref_callback_weakref_dealloc__pyfunc;
+
//################## BonesDict_Type (internal) ########################
/*This is an internal psuedo-dictionary type that allows for manipulation
* of bones inside of an armature. It is a subobject of armature.
@@ -118,18 +122,19 @@ static PyMethodDef BPy_BonesDict_methods[] = {
//-----------------(internal)
static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
Bone *bone = NULL;
- PyObject *py_bone = NULL, *str;
+ PyObject *py_bone = NULL;
for (bone = bones->first; bone; bone = bone->next){
py_bone = PyBone_FromBone(bone);
if (!py_bone)
return -1;
- str = PyString_FromString(bone->name);
- if(PyDict_SetItem(dictionary, str, py_bone) == -1)
+ if(PyDict_SetItemString(dictionary, bone->name, py_bone) == -1) {
+ /* unlikely but possible */
+ Py_DECREF(py_bone);
return -1;
+ }
- Py_DECREF(str);
Py_DECREF(py_bone);
if (bone->childbase.first)
BoneMapping_Init(dictionary, &bone->childbase);
@@ -139,18 +144,17 @@ static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
//-----------------(internal)
static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){
EditBone *editbone = NULL;
- PyObject *py_editbone = NULL, *str;
+ PyObject *py_editbone = NULL;
for (editbone = editbones->first; editbone; editbone = editbone->next){
py_editbone = PyEditBone_FromEditBone(editbone);
if (!py_editbone)
return -1;
- str = PyString_FromString(editbone->name);
- if(PyDict_SetItem(dictionary, str, py_editbone) == -1)
+ if(PyDict_SetItemString(dictionary, editbone->name, py_editbone) == -1) {
+ Py_DECREF(py_editbone);
return -1;
-
- Py_DECREF(str);
+ }
Py_DECREF(py_editbone);
}
return 0;
@@ -242,17 +246,14 @@ static PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
value = PyDict_GetItem(self->bonesMap, key);
}
if(value == NULL){ /* item not found in dict. throw exception */
- char buffer[128];
- char* key_str;
- key_str = PyString_AsString( key );
- if( !key_str ){ /* key not a py string */
- key_str = ""; /* use empty string for printing */
+ char* key_str = PyString_AsString( key );
+ if (key_str) {
+ return EXPP_ReturnPyObjError(PyExc_KeyError, "bone key must be a string" );
+ } else {
+ char buffer[128];
+ PyOS_snprintf( buffer, sizeof(buffer), "bone %s not found", key_str);
+ return EXPP_ReturnPyObjError(PyExc_KeyError, buffer );
}
-
- PyOS_snprintf( buffer, sizeof(buffer),
- "bone %s not found", key_str);
-
- return EXPP_ReturnPyObjError(PyExc_KeyError, buffer );
}
return EXPP_incr_ret(value);
}
@@ -262,107 +263,96 @@ static int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value
{
BPy_EditBone *editbone_for_deletion;
struct EditBone *editbone = NULL;
- char *key_str = "";
-
- if (self->editmode_flag){
- //Get the key name
- if(key && PyString_Check(key)){
- key_str = PyString_AsString(key);
- }else{
- goto AttributeError;
- }
- //parse value for assignment
- if (value && EditBoneObject_Check(value)){
- //create a new editbone
- editbone = MEM_callocN(sizeof(EditBone), "eBone");
- BLI_strncpy(editbone->name, key_str, 32);
- unique_editbone_name(NULL, editbone->name);
- editbone->dist = ((BPy_EditBone*)value)->dist;
- editbone->ease1 = ((BPy_EditBone*)value)->ease1;
- editbone->ease2 = ((BPy_EditBone*)value)->ease2;
- editbone->flag = ((BPy_EditBone*)value)->flag;
- editbone->parent = ((BPy_EditBone*)value)->parent;
- editbone->rad_head = ((BPy_EditBone*)value)->rad_head;
- editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail;
- editbone->roll = ((BPy_EditBone*)value)->roll;
- editbone->segments = ((BPy_EditBone*)value)->segments;
- editbone->weight = ((BPy_EditBone*)value)->weight;
- editbone->xwidth = ((BPy_EditBone*)value)->xwidth;
- editbone->zwidth = ((BPy_EditBone*)value)->zwidth;
- VECCOPY(editbone->head, ((BPy_EditBone*)value)->head);
- VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail);
-
- // FIXME, should be exposed via python. this avoids creating bones with no layers.
- editbone->layer= 1;
-
- //set object pointer
- ((BPy_EditBone*)value)->editbone = editbone;
-
- //fix the bone's head position if flags indicate that it is 'connected'
- if (editbone->flag & BONE_CONNECTED){
- if(!editbone->parent){
- ((BPy_EditBone*)value)->editbone = NULL;
- MEM_freeN(editbone);
- goto AttributeError3;
- }else{
- VECCOPY(editbone->head, editbone->parent->tail);
- }
- }
+ char *key_str = PyString_AsString(key);
- //set in editbonelist
- BLI_addtail(&self->editbones, editbone);
+ if (!self->editmode_flag)
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "You must call makeEditable() first");
+
+ if (!key_str)
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "The key must be the name of an editbone");
+
+ if (value && !EditBoneObject_Check(value))
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "Can only assign editbones as values");
+
+ //parse value for assignment
+ if (value){ /* we know this must be an editbone from the above check */
+ //create a new editbone
+ editbone = MEM_callocN(sizeof(EditBone), "eBone");
+ BLI_strncpy(editbone->name, key_str, 32);
+ unique_editbone_name(NULL, editbone->name);
+ editbone->dist = ((BPy_EditBone*)value)->dist;
+ editbone->ease1 = ((BPy_EditBone*)value)->ease1;
+ editbone->ease2 = ((BPy_EditBone*)value)->ease2;
+ editbone->flag = ((BPy_EditBone*)value)->flag;
+ editbone->parent = ((BPy_EditBone*)value)->parent;
+ editbone->rad_head = ((BPy_EditBone*)value)->rad_head;
+ editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail;
+ editbone->roll = ((BPy_EditBone*)value)->roll;
+ editbone->segments = ((BPy_EditBone*)value)->segments;
+ editbone->weight = ((BPy_EditBone*)value)->weight;
+ editbone->xwidth = ((BPy_EditBone*)value)->xwidth;
+ editbone->zwidth = ((BPy_EditBone*)value)->zwidth;
+ VECCOPY(editbone->head, ((BPy_EditBone*)value)->head);
+ VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail);
+ editbone->layer= ((BPy_EditBone*)value)->layer;
+
+ //set object pointer
+ ((BPy_EditBone*)value)->editbone = editbone;
- //set the new editbone in the mapping
- if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){
+ //fix the bone's head position if flags indicate that it is 'connected'
+ if (editbone->flag & BONE_CONNECTED){
+ if(!editbone->parent){
((BPy_EditBone*)value)->editbone = NULL;
- BLI_freelinkN(&self->editbones, editbone);
- goto RuntimeError;
- }
- }else if(!value){
- //they are trying to delete the bone using 'del'
- if(PyDict_GetItem(self->editbonesMap, key) != NULL){
- /*first kill the datastruct then remove the item from the dict
- and wait for GC to pick it up.
- We have to delete the datastruct here because the tp_dealloc
- doesn't handle it*/
- editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
- /*this is ugly but you have to set the parent to NULL for else
- editbones_to_armature will crash looking for this bone*/
- for (editbone = self->editbones.first; editbone; editbone = editbone->next){
- if (editbone->parent == editbone_for_deletion->editbone) {
- editbone->parent = NULL;
- /* remove the connected flag or else the 'root' ball
- * doesn't get drawn */
- editbone->flag &= ~BONE_CONNECTED;
- }
- }
- BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
- if(PyDict_DelItem(self->editbonesMap, key) == -1)
- goto RuntimeError;
+ MEM_freeN(editbone);
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!");
}else{
- goto KeyError;
+ VECCOPY(editbone->head, editbone->parent->tail);
}
}
- return 0;
- }else{
- goto AttributeError2;
- }
-KeyError:
-return EXPP_intError(PyExc_KeyError, "%s%s%s%s",
- sBoneDictError, "The key: ", key_str, " is not present in this dictionary!");
-RuntimeError:
- return EXPP_intError(PyExc_RuntimeError, "%s%s",
- sBoneDictError, "Unable to access dictionary!");
-AttributeError:
- return EXPP_intError(PyExc_AttributeError, "%s%s",
- sBoneDictBadArgs, "Expects EditboneType Object");
-AttributeError2:
- return EXPP_intError(PyExc_AttributeError, "%s%s",
- sBoneDictBadArgs, "You must call makeEditable() first");
-AttributeError3:
- return EXPP_intError(PyExc_AttributeError, "%s%s",
- sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!");
+ //set in editbonelist
+ BLI_addtail(&self->editbones, editbone);
+
+ //set the new editbone in the mapping
+ if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){
+ ((BPy_EditBone*)value)->editbone = NULL;
+ BLI_freelinkN(&self->editbones, editbone);
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Unable to access dictionary!");
+ }
+ }else {
+ //they are trying to delete the bone using 'del'
+ editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
+
+ if (!editbone_for_deletion)
+ return EXPP_intError(PyExc_KeyError, "%s%s%s%s",
+ sBoneDictError, "The key: ", key_str, " is not present in this dictionary!");
+
+ /*first kill the datastruct then remove the item from the dict
+ and wait for GC to pick it up.
+ We have to delete the datastruct here because the tp_dealloc
+ doesn't handle it*/
+
+ /*this is ugly but you have to set the parent to NULL for else
+ editbones_to_armature will crash looking for this bone*/
+ for (editbone = self->editbones.first; editbone; editbone = editbone->next){
+ if (editbone->parent == editbone_for_deletion->editbone) {
+ editbone->parent = NULL;
+ /* remove the connected flag or else the 'root' ball
+ * doesn't get drawn */
+ editbone->flag &= ~BONE_CONNECTED;
+ }
+ }
+ BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
+ if(PyDict_DelItem(self->editbonesMap, key) == -1)
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Unable to access dictionary!");
+ }
+ return 0;
}
//------------------TYPE_OBJECT DEFINITION--------------------------
//Mapping Protocol
@@ -892,9 +882,9 @@ AttributeError:
static PyObject *Armature_getVertexGroups(BPy_Armature *self, void *closure)
{
if (self->armature->deformflag & ARM_DEF_VGROUP)
- return EXPP_incr_ret(Py_True);
+ Py_RETURN_TRUE;
else
- return EXPP_incr_ret(Py_False);
+ Py_RETURN_FALSE;
}
//------------------------Armature.vertexGroups (setter)
static int Armature_setVertexGroups(BPy_Armature *self, PyObject *value, void *closure)
@@ -935,6 +925,36 @@ AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s",
sArmatureError, "You are not allowed to change the .Bones attribute");
}
+
+//------------------------Bone.layerMask (get)
+static PyObject *Armature_getLayerMask(BPy_Armature *self)
+{
+ /* do this extra stuff because the short's bits can be negative values */
+ unsigned short laymask = 0;
+ laymask |= self->armature->layer;
+ return PyInt_FromLong((int)laymask);
+}
+//------------------------Bone.layerMask (set)
+static int Armature_setLayerMask(BPy_Armature *self, PyObject *value)
+{
+ int laymask;
+ if (!PyInt_Check(value)) {
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "expected an integer (bitmask) as argument" );
+ }
+
+ laymask = PyInt_AsLong(value);
+
+ if (laymask <= 0 || laymask > (1<<16) - 1)
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "bitmask must have from 1 up to 16 bits set");
+
+ self->armature->layer = 0;
+ self->armature->layer |= laymask;
+
+ return 0;
+}
+
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
//------------------------tp_doc
//The __doc__ string for this object
@@ -982,6 +1002,8 @@ static PyGetSetDef BPy_Armature_getset[] = {
"Adds temporal IK chains while grabbing bones", NULL},
{"layers", (getter)Armature_getLayers, (setter)Armature_setLayers,
"List of layers for the armature", NULL},
+ {"layerMask", (getter)Armature_getLayerMask, (setter)Armature_setLayerMask,
+ "Layer bitmask", NULL },
{NULL, NULL, NULL, NULL, NULL}
};
//------------------------tp_new
@@ -1068,7 +1090,7 @@ static PyObject *Armature_repr(BPy_Armature *self)
static void Armature_dealloc(BPy_Armature * self)
{
if (self->weaklist != NULL)
- PyObject_ClearWeakRefs((PyObject *) self);
+ PyObject_ClearWeakRefs((PyObject *) self); /* this causes the weakref dealloc func to be called */
Py_DECREF(self->Bones);
PyObject_DEL( self );
@@ -1180,6 +1202,10 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
data = G.main->armature.first; //get the first data ID from the armature library
while (data){
py_armature = Armature_CreatePyObject(data); //*new*
+ if (!py_armature) {
+ EXPP_decr2(seq, dict);
+ return NULL; /* error is set from Armature_CreatePyObject */
+ }
sprintf(buffer, "%s", ((bArmature*)data)->id.name +2);
if(PyDict_SetItemString(dict, buffer, py_armature) == -1){ //add to dictionary
EXPP_decr3(seq, dict, py_armature);
@@ -1197,6 +1223,11 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
data = find_id("AR", name); //get data from library
if (data != NULL){
py_armature = Armature_CreatePyObject(data); //*new*
+ if (!py_armature) {
+ EXPP_decr2(seq, dict);
+ return NULL; /* error is set from Armature_CreatePyObject */
+ }
+
if(PyDict_SetItemString(dict, name, py_armature) == -1){ //add to dictionary
EXPP_decr3(seq, dict, py_armature);
goto RuntimeError;
@@ -1293,11 +1324,32 @@ PyObject *Armature_RebuildBones(PyObject *pyarmature)
{
return Armature_update((BPy_Armature*)pyarmature);
}
+
+/* internal func to remove weakref from weakref list */
+PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref)
+{
+ char *list_name = ARM_WEAKREF_LIST_NAME;
+ PyObject *maindict = NULL, *armlist = NULL;
+ int i;
+
+ maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
+ armlist = PyDict_GetItemString(maindict, list_name);
+ if( !armlist){
+ printf("Oops - update_armature_weakrefs()\n");
+ Py_RETURN_NONE;
+ }
+
+ i = PySequence_Index(armlist, weakref);
+ if (i==-1) {
+ printf("callback weakref internal error, weakref not in list\n\tthis should never happen.\n");
+ Py_RETURN_NONE;
+ }
+ PySequence_DelItem(armlist, i);
+ Py_RETURN_NONE;
+}
+
/*-----------------(internal)
- * Converts a bArmature to a PyArmature
- *
- * WARNING!!! - MEMORY LEAK HERE, Run in a loop and loose your ram.
- * cannot find out why but doesn't seem to be the weakref */
+ * Converts a bArmature to a PyArmature */
PyObject *Armature_CreatePyObject(struct bArmature *armature)
{
@@ -1305,7 +1357,28 @@ PyObject *Armature_CreatePyObject(struct bArmature *armature)
PyObject *maindict = NULL, *weakref = NULL;
PyObject *armlist = NULL; /* list of armature weak refs */
char *list_name = ARM_WEAKREF_LIST_NAME;
+ int i;
+
+ //put a weakreference in __main__
+ maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
+ armlist = PyDict_GetItemString(maindict, list_name);
+ if(!armlist) {
+ printf("Oops - can't get the armature weakref list\n");
+ goto RuntimeError;
+ }
+
+ /* see if we alredy have it */
+ for (i=0; i< PyList_Size(armlist); i++) {
+ py_armature = (BPy_Armature *)PyWeakref_GetObject(PyList_GET_ITEM(armlist, i));
+ if (BPy_Armature_Check(py_armature) && py_armature->armature == armature) {
+ Py_INCREF(py_armature);
+ /*printf("reusing armature\n");*/
+ return (PyObject *)py_armature;
+ }
+ }
+
+
/*create armature type*/
py_armature = PyObject_NEW( BPy_Armature, &Armature_Type );
@@ -1323,18 +1396,14 @@ PyObject *Armature_CreatePyObject(struct bArmature *armature)
printf("Oops - creating armature.bones\n");
goto RuntimeError;
}
-
- //put a weakreference in __main__
- maindict= PyModule_GetDict(PyImport_AddModule( "__main__"));
-
- armlist = PyDict_GetItemString(maindict, list_name);
- if( armlist){
- weakref = PyWeakref_NewProxy((PyObject*)py_armature, Py_None);
- if (PyList_Append(armlist, weakref) == -1){
- printf("Oops - list-append failed\n");
- goto RuntimeError;
- }
+
+ weakref = PyWeakref_NewRef((PyObject*)py_armature, arm_weakref_callback_weakref_dealloc__pyfunc);
+ if (PyList_Append(armlist, weakref) == -1){
+ printf("Oops - list-append failed\n");
+ goto RuntimeError;
}
+ Py_DECREF(weakref);
+
return (PyObject *) py_armature;
RuntimeError:
@@ -1353,7 +1422,10 @@ struct bArmature *Armature_FromPyObject( PyObject * py_obj )
return PyArmature_AsArmature((BPy_Armature*)py_obj);
}
-
+/* internal use only */
+static PyMethodDef bpy_arm_weakref_callback_weakref_dealloc[] = {
+ {"arm_weakref_callback_weakref_dealloc", arm_weakref_callback_weakref_dealloc, METH_O, ""}
+};
//-------------------MODULE INITIALIZATION--------------------------------
PyObject *Armature_Init(void)
@@ -1366,6 +1438,11 @@ PyObject *Armature_Init(void)
return EXPP_incr_ret(Py_None);
}
+ /* Weakref management - used for callbacks so we can
+ * tell when a callback has been removed that a UI button referenced */
+ arm_weakref_callback_weakref_dealloc__pyfunc = PyCFunction_New(bpy_arm_weakref_callback_weakref_dealloc, NULL);
+
+
//Register the module
module = Py_InitModule3("Blender.Armature", M_Armature_methods,
"The Blender Armature module");
diff --git a/source/blender/python/api2_2x/BGL.c b/source/blender/python/api2_2x/BGL.c
index b18b71b39fa..c67ae7f59ef 100644
--- a/source/blender/python/api2_2x/BGL.c
+++ b/source/blender/python/api2_2x/BGL.c
@@ -618,10 +618,12 @@ BGL_Wrap(2, PolygonMode, void, (GLenum, GLenum))
BGL_Wrap(2, PolygonOffset, void, (GLfloat, GLfloat))
BGL_Wrap(1, PolygonStipple, void, (GLubyteP))
BGL_Wrap(1, PopAttrib, void, (void))
+BGL_Wrap(1, PopClientAttrib, void, (void))
BGL_Wrap(1, PopMatrix, void, (void))
BGL_Wrap(1, PopName, void, (void))
BGL_Wrap(3, PrioritizeTextures, void, (GLsizei, GLuintP, GLclampfP))
BGL_Wrap(1, PushAttrib, void, (GLbitfield))
+BGL_Wrap(1, PushClientAttrib, void, (GLbitfield))
BGL_Wrap(1, PushMatrix, void, (void))
BGL_Wrap(1, PushName, void, (GLuint))
BGL_Wrap(2, RasterPos2d, void, (GLdouble, GLdouble))
@@ -951,10 +953,12 @@ static struct PyMethodDef BGL_methods[] = {
MethodDef(PolygonOffset),
MethodDef(PolygonStipple),
MethodDef(PopAttrib),
+ MethodDef(PopClientAttrib),
MethodDef(PopMatrix),
MethodDef(PopName),
MethodDef(PrioritizeTextures),
MethodDef(PushAttrib),
+ MethodDef(PushClientAttrib),
MethodDef(PushMatrix),
MethodDef(PushName),
MethodDef(RasterPos2d),
@@ -1095,7 +1099,7 @@ PyObject *BGL_Init(void)
if( PyType_Ready( &buffer_Type) < 0)
Py_RETURN_NONE;
-#define EXPP_ADDCONST(x) EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
+#define EXPP_ADDCONST(x) EXPP_dict_set_item_str(dict, #x, PyInt_FromLong((int)x))
/* So, for example:
* EXPP_ADDCONST(GL_CURRENT_BIT) becomes
@@ -1122,7 +1126,8 @@ PyObject *BGL_Init(void)
EXPP_ADDCONST(GL_TEXTURE_BIT);
EXPP_ADDCONST(GL_SCISSOR_BIT);
EXPP_ADDCONST(GL_ALL_ATTRIB_BITS);
-
+ EXPP_ADDCONST(GL_CLIENT_ALL_ATTRIB_BITS);
+
EXPP_ADDCONST(GL_FALSE);
EXPP_ADDCONST(GL_TRUE);
diff --git a/source/blender/python/api2_2x/BezTriple.c b/source/blender/python/api2_2x/BezTriple.c
index aabc33e6f95..2aa908ff2b0 100644
--- a/source/blender/python/api2_2x/BezTriple.c
+++ b/source/blender/python/api2_2x/BezTriple.c
@@ -350,7 +350,12 @@ static PyObject *BezTriple_getHide( BPy_BezTriple * self )
static int BezTriple_setHide( BPy_BezTriple * self, PyObject *value )
{
- if( PyObject_IsTrue( value ) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->beztriple->hide = IPO_BEZ;
else
self->beztriple->hide = 0;
@@ -368,6 +373,7 @@ static int BezTriple_setSelects( BPy_BezTriple * self, PyObject *args )
{
struct BezTriple *bezt = self->beztriple;
PyObject *ob1, *ob2, *ob3;
+ int param1, param2, param3;
/* only accept a sequence of three booleans */
@@ -379,15 +385,22 @@ static int BezTriple_setSelects( BPy_BezTriple * self, PyObject *args )
ob2 = PySequence_ITEM( args, 1 );
ob3 = PySequence_ITEM( args, 2 );
+ param1 = PyObject_IsTrue( ob1 );
+ param2 = PyObject_IsTrue( ob2 );
+ param3 = PyObject_IsTrue( ob3 );
+
+ if (param1==-1 || param2==-1 || param3==-1)
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a sequence of 3 items: True/False or 0/1" );
+
/* assign the selects */
- bezt->f1 = ( char )PyObject_IsTrue( ob1 );
- bezt->f2 = ( char )PyObject_IsTrue( ob2 );
- bezt->f3 = ( char )PyObject_IsTrue( ob3 );
+ bezt->f1 = (char)param1;
+ bezt->f2 = (char)param2;
+ bezt->f3 = (char)param3;
Py_DECREF( ob1 );
Py_DECREF( ob2 );
Py_DECREF( ob3 );
-
return 0;
}
@@ -413,7 +426,7 @@ static int BezTriple_setHandles( BPy_BezTriple * self, PyObject *args )
ob1 = PySequence_ITEM( args, 0 );
ob2 = PySequence_ITEM( args, 1 );
- if( !PyInt_CheckExact( ob1 ) || !PyInt_CheckExact( ob2 ) ) {
+ if( !PyInt_Check( ob1 ) || !PyInt_Check( ob2 ) ) {
Py_DECREF( ob1 );
Py_DECREF( ob2 );
return EXPP_ReturnIntError( PyExc_TypeError,
diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c
index 9a5163022ff..d520dded486 100644
--- a/source/blender/python/api2_2x/Blender.c
+++ b/source/blender/python/api2_2x/Blender.c
@@ -1,5 +1,6 @@
/*
* $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -36,8 +37,10 @@ struct ID; /*keep me up here */
/* for open, close in Blender_Load */
#include <fcntl.h>
#include "BDR_editobject.h" /* exit_editmode() */
+#include "BDR_drawmesh.h" /* set_mipmap() */
#include "BIF_usiblender.h"
#include "BLI_blenlib.h"
+#include "BLI_bpath.h"
#include "BLO_writefile.h"
#include "BKE_blender.h"
#include "BKE_exotic.h"
@@ -50,7 +53,8 @@ struct ID; /*keep me up here */
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BPI_script.h"
+#include "BIF_space.h"
+#include "DNA_space_types.h" /* script struct */
#include "BSE_headerbuttons.h"
#include "DNA_screen_types.h" /* for SPACE_VIEW3D */
#include "DNA_userdef_types.h"
@@ -82,6 +86,7 @@ struct ID; /*keep me up here */
#include "Metaball.h"
#include "Modifier.h"
#include "NMesh.h"
+#include "Node.h"
#include "Object.h"
#include "Group.h"
#include "Registry.h"
@@ -99,18 +104,19 @@ struct ID; /*keep me up here */
/* Python API function prototypes for the Blender module. */
/**********************************************************/
static PyObject *Blender_Set( PyObject * self, PyObject * args );
-static PyObject *Blender_Get( PyObject * self, PyObject * args );
+static PyObject *Blender_Get( PyObject * self, PyObject * value );
static PyObject *Blender_Redraw( PyObject * self, PyObject * args );
static PyObject *Blender_Quit( PyObject * self );
static PyObject *Blender_Load( PyObject * self, PyObject * args );
static PyObject *Blender_Save( PyObject * self, PyObject * args );
-static PyObject *Blender_Run( PyObject * self, PyObject * args );
-static PyObject *Blender_ShowHelp( PyObject * self, PyObject * args );
+static PyObject *Blender_Run( PyObject * self, PyObject * value );
+static PyObject *Blender_ShowHelp( PyObject * self, PyObject * script );
static PyObject *Blender_UpdateMenus( PyObject * self);
static PyObject *Blender_PackAll( PyObject * self);
-static PyObject *Blender_UnpackAll( PyObject * self, PyObject * args);
+static PyObject *Blender_UnpackAll( PyObject * self, PyObject * value);
static PyObject *Blender_CountPackedFiles( PyObject * self );
-
+static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *keywds );
+static PyObject *Blender_SaveUndoState( PyObject * self, PyObject *args );
extern PyObject *Text3d_Init( void ); /* missing in some include */
/*****************************************************************************/
@@ -194,23 +200,30 @@ All files will be unpacked using specified mode.\n\n\
static char Blender_CountPackedFiles_doc[] =
"() - Returns the number of packed files.";
+static char Blender_GetPaths_doc[] =
+"() - Returns a list of paths used in this blend file.";
+
+static char Blender_SaveUndoState_doc[] =
+"(s) - Push an undo with blenders current state.";
+
/*****************************************************************************/
/* Python method structure definition. */
/*****************************************************************************/
static struct PyMethodDef Blender_methods[] = {
{"Set", Blender_Set, METH_VARARGS, Blender_Set_doc},
- {"Get", Blender_Get, METH_VARARGS, Blender_Get_doc},
+ {"Get", Blender_Get, METH_O, Blender_Get_doc},
{"Redraw", Blender_Redraw, METH_VARARGS, Blender_Redraw_doc},
{"Quit", ( PyCFunction ) Blender_Quit, METH_NOARGS, Blender_Quit_doc},
{"Load", Blender_Load, METH_VARARGS, Blender_Load_doc},
{"Save", Blender_Save, METH_VARARGS, Blender_Save_doc},
- {"Run", Blender_Run, METH_VARARGS, Blender_Run_doc},
- {"ShowHelp", Blender_ShowHelp, METH_VARARGS, Blender_ShowHelp_doc},
+ {"Run", Blender_Run, METH_O, Blender_Run_doc},
+ {"ShowHelp", Blender_ShowHelp, METH_O, Blender_ShowHelp_doc},
{"CountPackedFiles", ( PyCFunction ) Blender_CountPackedFiles, METH_NOARGS, Blender_CountPackedFiles_doc},
+ {"GetPaths", ( PyCFunction ) Blender_GetPaths, METH_VARARGS|METH_KEYWORDS, Blender_GetPaths_doc},
{"PackAll", ( PyCFunction ) Blender_PackAll, METH_NOARGS, Blender_PackAll_doc},
- {"UnpackAll", Blender_UnpackAll, METH_VARARGS, Blender_UnpackAll_doc},
- {"UpdateMenus", ( PyCFunction ) Blender_UpdateMenus, METH_NOARGS,
- Blender_UpdateMenus_doc},
+ {"UnpackAll", Blender_UnpackAll, METH_O, Blender_UnpackAll_doc},
+ {"UpdateMenus", ( PyCFunction ) Blender_UpdateMenus, METH_NOARGS, Blender_UpdateMenus_doc},
+ {"SaveUndoState", Blender_SaveUndoState, METH_VARARGS, Blender_SaveUndoState_doc},
{NULL, NULL, 0, NULL}
};
@@ -278,7 +291,32 @@ static PyObject *Blender_Set( PyObject * self, PyObject * args )
if ( !PyArg_Parse( arg , "s" , &dir ))
return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string" );
BLI_strncpy(U.tempdir, dir, FILE_MAXDIR);
- } else
+ BLI_where_is_temp( btempdir, 1 );
+ } else if (StringEqual( name , "compressfile" ) ) {
+ int value = PyObject_IsTrue( arg );
+
+ if (value==-1)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "expected an integer" );
+
+ if (value)
+ U.flag |= USER_FILECOMPRESS;
+ else
+ U.flag &= ~USER_FILECOMPRESS;
+ } else if (StringEqual( name , "mipmap" ) ) {
+ int value = PyObject_IsTrue( arg );
+
+ if (value==-1)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "expected an integer" );
+
+ if (value)
+ U.gameflags &= ~USER_DISABLE_MIPMAP;
+ else
+ U.gameflags |= USER_DISABLE_MIPMAP;
+
+ set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
+ }else
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"value given is not a blender setting" ) );
Py_RETURN_NONE;
@@ -288,12 +326,12 @@ static PyObject *Blender_Set( PyObject * self, PyObject * args )
/* Function: Blender_Get */
/* Python equivalent: Blender.Get */
/*****************************************************************************/
-static PyObject *Blender_Get( PyObject * self, PyObject * args )
+static PyObject *Blender_Get( PyObject * self, PyObject * value )
{
PyObject *ret = NULL;
- char *str = NULL;
+ char *str = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &str ) )
+ if( !str )
return EXPP_ReturnPyObjError (PyExc_TypeError,
"expected string argument");
@@ -308,10 +346,10 @@ static PyObject *Blender_Get( PyObject * self, PyObject * args )
else if( StringEqual( str, "endframe" ) )
ret = PyInt_FromLong( G.scene->r.efra );
else if( StringEqual( str, "filename" ) ) {
- if ( strstr(G.main->name, ".B.blend") != 0)
+ if (!G.relbase_valid)
ret = PyString_FromString("");
else
- ret = PyString_FromString(G.main->name);
+ ret = PyString_FromString(G.sce);
}
else if( StringEqual( str, "homedir" ) ) {
char *hdir = bpy_gethome(0);
@@ -506,13 +544,18 @@ static PyObject *Blender_Get( PyObject * self, PyObject * args )
} /* End 'quick hack' part. */
else if(StringEqual( str, "version" ))
ret = PyInt_FromLong( G.version );
+
+ else if(StringEqual( str, "compressfile" ))
+ ret = PyInt_FromLong( (U.flag & USER_FILECOMPRESS) >> 15 );
+ else if(StringEqual( str, "mipmap" ))
+ ret = PyInt_FromLong( (U.gameflags & USER_DISABLE_MIPMAP) == 0 );
else
return EXPP_ReturnPyObjError( PyExc_AttributeError, "unknown attribute" );
if (ret) return ret;
else
return EXPP_ReturnPyObjError (PyExc_MemoryError,
- "could not create pystring!");
+ "could not create the PyObject!");
}
/*****************************************************************************/
@@ -676,7 +719,7 @@ static PyObject *Blender_Save( PyObject * self, PyObject * args )
len = strlen( fname );
- if( len > FILE_MAXFILE )
+ if( len > FILE_MAXDIR + FILE_MAXFILE )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"filename is too long!" );
else if( BLI_exists( fname ) && !overwrite )
@@ -685,10 +728,16 @@ static PyObject *Blender_Save( PyObject * self, PyObject * args )
disable_where_script( 1 ); /* to avoid error popups in the write_* functions */
- if( BLI_testextensie( fname, ".blend" ) ) {
+ if( BLI_testextensie( fname, ".blend" ) ) {
+ int writeflags;
if( G.fileflags & G_AUTOPACK )
packAll( );
- if( !BLO_write_file( fname, G.fileflags, &error ) ) {
+
+ writeflags= G.fileflags & ~G_FILE_COMPRESS;
+ if(U.flag & USER_FILECOMPRESS)
+ writeflags |= G_FILE_COMPRESS;
+
+ if( !BLO_write_file( fname, writeflags, &error ) ) {
disable_where_script( 0 );
return EXPP_ReturnPyObjError( PyExc_SystemError,
error );
@@ -712,14 +761,13 @@ static PyObject *Blender_Save( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Blender_ShowHelp(PyObject *self, PyObject *args)
+static PyObject *Blender_ShowHelp(PyObject *self, PyObject *script)
{
- PyObject *script = NULL;
char hspath[FILE_MAXDIR + FILE_MAXFILE]; /* path to help_browser.py */
char *sdir = bpy_gethome(1);
PyObject *rkeyd = NULL, *arglist = NULL;
- if (!PyArg_ParseTuple(args, "O!", &PyString_Type, &script))
+ if (!PyString_Check(script))
return EXPP_ReturnPyObjError(PyExc_TypeError,
"expected a script filename as argument");
@@ -752,21 +800,21 @@ static PyObject *Blender_ShowHelp(PyObject *self, PyObject *args)
EXPP_dict_set_item_str(bpy_registryDict, "__help_browser", rkeyd);
- arglist = Py_BuildValue("(s)", hspath);
+ arglist = Py_BuildValue("s", hspath);
Blender_Run(self, arglist);
Py_DECREF(arglist);
Py_RETURN_NONE;
}
-static PyObject *Blender_Run(PyObject *self, PyObject *args)
+static PyObject *Blender_Run(PyObject *self, PyObject *value)
{
- char *fname = NULL;
+ char *fname = PyString_AsString(value);
Text *text = NULL;
int is_blender_text = 0;
Script *script = NULL;
- if (!PyArg_ParseTuple(args, "s", &fname))
+ if (!fname)
return EXPP_ReturnPyObjError(PyExc_TypeError,
"expected a filename or a Blender Text name as argument");
@@ -848,10 +896,12 @@ static PyObject *Blender_PackAll( PyObject * self)
/* Function: Blender_UnpackAll */
/* Python equivalent: Blender.UnpackAll */
/*****************************************************************************/
-static PyObject *Blender_UnpackAll( PyObject * self, PyObject *args)
+static PyObject *Blender_UnpackAll( PyObject * self, PyObject *value)
{
- int mode;
- PyArg_ParseTuple( args, "i", &mode );
+ int mode = PyInt_AsLong(value);
+
+ if (mode==-1)
+ return EXPP_ReturnPyObjError( PyExc_ValueError, "expected an int Blender.UnpackModes");
unpackAll(mode);
Py_RETURN_NONE;
}
@@ -865,6 +915,55 @@ static PyObject *Blender_CountPackedFiles( PyObject * self )
int nfiles = countPackedFiles();
return PyInt_FromLong( nfiles );
}
+
+/*****************************************************************************/
+/* Function: Blender_GetPaths */
+/* Python equivalent: Blender.GetPaths */
+/*****************************************************************************/
+static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *keywds )
+{
+ struct BPathIterator bpi;
+ PyObject *list = PyList_New(0), *st;
+ /* be sure there is low chance of the path being too short */
+ char filepath_expanded[FILE_MAXDIR*2];
+
+ int absolute = 0;
+ static char *kwlist[] = {"absolute", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "|i", kwlist, &absolute ) )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "expected nothing or one bool (0 or 1) as argument" );
+
+ BLI_bpathIterator_init(&bpi);
+
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+
+ /* build the list */
+ if (absolute) {
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+ st = PyString_FromString(filepath_expanded);
+ } else {
+ st = PyString_FromString(BLI_bpathIterator_getPath(&bpi));
+ }
+
+ PyList_Append(list, st);
+ Py_DECREF(st);
+
+ BLI_bpathIterator_step(&bpi);
+ }
+
+ return list;
+}
+
+static PyObject *Blender_SaveUndoState( PyObject * self, PyObject *args )
+{
+ char *str;
+ if ( !PyArg_ParseTuple( args , "s" , &str ))
+ return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a string" );
+ BIF_undo_push(str);
+ Py_RETURN_NONE;
+}
+
static PyObject *Blender_UnpackModesDict( void )
{
PyObject *UnpackModes = PyConstant_New( );
@@ -963,6 +1062,7 @@ void M_Blender_Init(void)
PyDict_SetItemString(dict, "Geometry", Geometry_Init());
PyDict_SetItemString(dict, "Modifier", Modifier_Init());
PyDict_SetItemString(dict, "NMesh", NMesh_Init());
+ PyDict_SetItemString(dict, "Node", Node_Init());
PyDict_SetItemString(dict, "Noise", Noise_Init());
PyDict_SetItemString(dict, "Object", Object_Init());
PyDict_SetItemString(dict, "Group", Group_Init());
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index ad589615b7d..5eeb4bb2817 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -709,6 +709,40 @@ AttributeError:
sEditBoneError, ".tailRadius: ", "expects a float");
}
+//------------------------Bone.layerMask (get)
+static PyObject *EditBone_getLayerMask(BPy_EditBone *self)
+{
+ /* do this extra stuff because the short's bits can be negative values */
+ unsigned short laymask = 0;
+ if (self->editbone) laymask |= self->editbone->layer;
+ else laymask |= self->layer;
+ return PyInt_FromLong((int)laymask);
+}
+//------------------------Bone.layerMask (set)
+static int EditBone_setLayerMask(BPy_EditBone *self, PyObject *value)
+{
+ int laymask;
+ if (!PyInt_Check(value)) {
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "expected an integer (bitmask) as argument" );
+ }
+
+ laymask = PyInt_AsLong(value);
+
+ if (laymask <= 0 || laymask > (1<<16) - 1)
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "bitmask must have from 1 up to 16 bits set");
+
+ if (self->editbone) {
+ self->editbone->layer = 0;
+ self->editbone->layer |= laymask;
+ } else {
+ self->layer = 0;
+ self->layer |= laymask;
+ }
+
+ return 0;
+}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
//------------------------tp_methods
@@ -749,6 +783,8 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"Set the radius of this bones tip", NULL},
{"headRadius", (getter)EditBone_getHeadRadius, (setter)EditBone_setHeadRadius,
"Set the radius of this bones head", NULL},
+ {"layerMask", (getter)EditBone_getLayerMask, (setter)EditBone_setLayerMask,
+ "Layer bitmask", NULL },
{NULL, NULL, NULL, NULL,NULL}
};
@@ -762,6 +798,14 @@ static PyObject *EditBone_repr(BPy_EditBone *self)
return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
}
+static int EditBone_compare( BPy_EditBone * a, BPy_EditBone * b )
+{
+ /* if they are not wrapped, then they cant be the same */
+ if (a->editbone==NULL && b->editbone==NULL) return -1;
+ return ( a->editbone == b->editbone ) ? 0 : -1;
+}
+
+
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_EditBone_doc[] = "This is an internal subobject of armature\
@@ -795,6 +839,7 @@ static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds
py_editBone->rad_head= 0.10f;
py_editBone->rad_tail= 0.05f;
py_editBone->segments= 1;
+ py_editBone->layer= 1;
py_editBone->flag = 0;
py_editBone->roll = 0.0f;
@@ -829,7 +874,7 @@ PyTypeObject EditBone_Type = {
0, //tp_print
0, //tp_getattr
0, //tp_setattr
- 0, //tp_compare
+ (cmpfunc)EditBone_compare, //tp_compare
(reprfunc)EditBone_repr, //tp_repr
0, //tp_as_number
0, //tp_as_sequence
@@ -1195,6 +1240,35 @@ AttributeError:
sEditBoneError, ".headRadius: ", "expects a float");
}
+//------------------------Bone.layerMask (get)
+static PyObject *Bone_getLayerMask(BPy_Bone *self)
+{
+ /* do this extra stuff because the short's bits can be negative values */
+ unsigned short laymask = 0;
+ laymask |= self->bone->layer;
+ return PyInt_FromLong((int)laymask);
+}
+//------------------------Bone.layerMask (set)
+static int Bone_setLayerMask(BPy_Bone *self, PyObject *value)
+{
+ int laymask;
+ if (!PyInt_Check(value)) {
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "expected an integer (bitmask) as argument" );
+ }
+
+ laymask = PyInt_AsLong(value);
+
+ if (laymask <= 0 || laymask > (1<<16) - 1)
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "bitmask must have from 1 up to 16 bits set");
+
+ self->bone->layer = 0;
+ self->bone->layer |= laymask;
+
+ return 0;
+}
+
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
//------------------------tp_methods
//This contains a list of all methods the object contains
@@ -1238,6 +1312,8 @@ static PyGetSetDef BPy_Bone_getset[] = {
"Set the radius of this bones tip", NULL},
{"headRadius", (getter)Bone_getHeadRadius, (setter)Bone_setHeadRadius,
"Set the radius of this bones head", NULL},
+ {"layerMask", (getter)Bone_getLayerMask, (setter)Bone_setLayerMask,
+ "Layer bitmask", NULL },
{NULL, NULL, NULL, NULL,NULL}
};
//------------------------tp_repr
@@ -1246,6 +1322,10 @@ static PyObject *Bone_repr(BPy_Bone *self)
{
return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name );
}
+static int Bone_compare( BPy_Bone * a, BPy_Bone * b )
+{
+ return ( a->bone == b->bone ) ? 0 : -1;
+}
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
static void Bone_dealloc(BPy_Bone * self)
@@ -1262,15 +1342,15 @@ static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
PyTypeObject Bone_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
0, //tp_internal
- "Bone", //tp_name
- sizeof(BPy_Bone), //tp_basicsize
+ "Bone", //tp_name
+ sizeof(BPy_Bone), //tp_basicsize
0, //tp_itemsize
- (destructor)Bone_dealloc, //tp_dealloc
+ (destructor)Bone_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
- 0, //tp_compare
- (reprfunc) Bone_repr, //tp_repr
+ (cmpfunc) Bone_compare, //tp_compare
+ (reprfunc) Bone_repr, //tp_repr
0, //tp_as_number
0, //tp_as_sequence
0, //tp_as_mapping
diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h
index c3f5de81714..aa076afbed7 100644
--- a/source/blender/python/api2_2x/Bone.h
+++ b/source/blender/python/api2_2x/Bone.h
@@ -65,6 +65,7 @@ typedef struct {
float rad_head;
float rad_tail;
short segments;
+ short layer;
} BPy_EditBone;
/*-------------------VISIBLE PROTOTYPES-------------------------*/
PyObject *PyBone_FromBone(struct Bone *bone);
diff --git a/source/blender/python/api2_2x/Camera.c b/source/blender/python/api2_2x/Camera.c
index 3ed11288980..5558b179e23 100644
--- a/source/blender/python/api2_2x/Camera.c
+++ b/source/blender/python/api2_2x/Camera.c
@@ -129,7 +129,7 @@ static PyObject *Camera_oldsetClipStart( BPy_Camera * self, PyObject * args );
static PyObject *Camera_oldsetClipEnd( BPy_Camera * self, PyObject * args );
static PyObject *Camera_oldsetDrawSize( BPy_Camera * self, PyObject * args );
static PyObject *Camera_oldsetScale( BPy_Camera * self, PyObject * args );
-static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * args );
+static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * value );
static PyObject *Camera_addScriptLink( BPy_Camera * self, PyObject * args );
static PyObject *Camera_oldclearIpo( BPy_Camera * self );
static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args );
@@ -169,21 +169,21 @@ static PyMethodDef BPy_Camera_methods[] = {
"( Camera IPO type ) - Inserts a key into IPO"},
{"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
"(s) - Set Camera Data name"},
- {"setType", ( PyCFunction ) Camera_oldsetType, METH_VARARGS,
+ {"setType", ( PyCFunction ) Camera_oldsetType, METH_O,
"(s) - Set Camera type, which can be 'persp' or 'ortho'"},
{"setMode", ( PyCFunction ) Camera_oldsetMode, METH_VARARGS,
"(<s<,s>>) - Set Camera mode flag(s): 'showLimits' and 'showMist'"},
- {"setLens", ( PyCFunction ) Camera_oldsetLens, METH_VARARGS,
+ {"setLens", ( PyCFunction ) Camera_oldsetLens, METH_O,
"(f) - Set *perpective* Camera lens value"},
- {"setScale", ( PyCFunction ) Camera_oldsetScale, METH_VARARGS,
+ {"setScale", ( PyCFunction ) Camera_oldsetScale, METH_O,
"(f) - Set *ortho* Camera scale value"},
- {"setClipStart", ( PyCFunction ) Camera_oldsetClipStart, METH_VARARGS,
+ {"setClipStart", ( PyCFunction ) Camera_oldsetClipStart, METH_O,
"(f) - Set Camera clip start value"},
- {"setClipEnd", ( PyCFunction ) Camera_oldsetClipEnd, METH_VARARGS,
+ {"setClipEnd", ( PyCFunction ) Camera_oldsetClipEnd, METH_O,
"(f) - Set Camera clip end value"},
- {"setDrawSize", ( PyCFunction ) Camera_oldsetDrawSize, METH_VARARGS,
+ {"setDrawSize", ( PyCFunction ) Camera_oldsetDrawSize, METH_O,
"(f) - Set Camera draw size value"},
- {"getScriptLinks", ( PyCFunction ) Camera_oldgetScriptLinks, METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) Camera_oldgetScriptLinks, METH_O,
"(eventname) - Get a list of this camera's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, Redraw or Render."},
@@ -363,79 +363,37 @@ Camera *Camera_FromPyObject( PyObject * pyobj )
static PyObject *Camera_oldgetType( BPy_Camera * self )
{
- PyObject *attr = PyInt_FromLong( self->camera->type );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.type attribute" );
+ return PyInt_FromLong( self->camera->type );
}
static PyObject *Camera_oldgetMode( BPy_Camera * self )
{
- PyObject *attr = PyInt_FromLong( self->camera->flag );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.Mode attribute" );
+ return PyInt_FromLong( self->camera->flag );
}
static PyObject *Camera_oldgetLens( BPy_Camera * self )
{
- PyObject *attr = PyFloat_FromDouble( self->camera->lens );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.lens attribute" );
+ return PyFloat_FromDouble( self->camera->lens );
}
static PyObject *Camera_oldgetScale( BPy_Camera * self )
{
- PyObject *attr = PyFloat_FromDouble( self->camera->ortho_scale );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.scale attribute" );
+ return PyFloat_FromDouble( self->camera->ortho_scale );
}
static PyObject *Camera_oldgetClipStart( BPy_Camera * self )
{
- PyObject *attr = PyFloat_FromDouble( self->camera->clipsta );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.clipStart attribute" );
+ return PyFloat_FromDouble( self->camera->clipsta );
}
static PyObject *Camera_oldgetClipEnd( BPy_Camera * self )
{
- PyObject *attr = PyFloat_FromDouble( self->camera->clipend );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.clipEnd attribute" );
+ return PyFloat_FromDouble( self->camera->clipend );
}
static PyObject *Camera_oldgetDrawSize( BPy_Camera * self )
{
- PyObject *attr = PyFloat_FromDouble( self->camera->drawsize );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Camera.drawSize attribute" );
+ return PyFloat_FromDouble( self->camera->drawsize );
}
@@ -462,11 +420,11 @@ static PyObject *Camera_oldclearIpo( BPy_Camera * self )
return EXPP_incr_ret_False(); /* no ipo found */
}
-static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetType( BPy_Camera * self, PyObject * value )
{
- char *type;
+ char *type = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &type ) )
+ if(!value)
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -516,75 +474,75 @@ static PyObject *Camera_oldsetMode( BPy_Camera * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Camera_oldsetLens( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetLens( BPy_Camera * self, PyObject * value )
{
- float value;
+ float param = PyFloat_AsDouble(value);
- if( !PyArg_ParseTuple( args, "f", &value ) )
+ if (PyErr_Occurred())
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected float argument" );
- self->camera->lens = EXPP_ClampFloat( value,
+ self->camera->lens = EXPP_ClampFloat( param,
EXPP_CAM_LENS_MIN,
EXPP_CAM_LENS_MAX );
Py_RETURN_NONE;
}
-static PyObject *Camera_oldsetScale( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetScale( BPy_Camera * self, PyObject * value )
{
- float value;
+ float param = PyFloat_AsDouble(value);
- if( !PyArg_ParseTuple( args, "f", &value ) )
+ if (PyErr_Occurred())
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected float argument" );
- self->camera->ortho_scale = EXPP_ClampFloat( value,
+ self->camera->ortho_scale = EXPP_ClampFloat( param,
EXPP_CAM_SCALE_MIN,
EXPP_CAM_SCALE_MAX );
Py_RETURN_NONE;
}
-static PyObject *Camera_oldsetClipStart( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetClipStart( BPy_Camera * self, PyObject * value )
{
- float value;
+ float param = PyFloat_AsDouble(value);
- if( !PyArg_ParseTuple( args, "f", &value ) )
+ if (PyErr_Occurred())
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected float argument" );
- self->camera->clipsta = EXPP_ClampFloat( value,
+ self->camera->clipsta = EXPP_ClampFloat( param,
EXPP_CAM_CLIPSTART_MIN,
EXPP_CAM_CLIPSTART_MAX );
Py_RETURN_NONE;
}
-static PyObject *Camera_oldsetClipEnd( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetClipEnd( BPy_Camera * self, PyObject * value )
{
- float value;
+ float param = PyFloat_AsDouble(value);
- if( !PyArg_ParseTuple( args, "f", &value ) )
+ if (PyErr_Occurred())
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected float argument" );
- self->camera->clipend = EXPP_ClampFloat( value,
+ self->camera->clipend = EXPP_ClampFloat( param,
EXPP_CAM_CLIPEND_MIN,
EXPP_CAM_CLIPEND_MAX );
Py_RETURN_NONE;
}
-static PyObject *Camera_oldsetDrawSize( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldsetDrawSize( BPy_Camera * self, PyObject * value )
{
- float value;
+ float param = PyFloat_AsDouble(value);
- if( !PyArg_ParseTuple( args, "f", &value ) )
+ if (PyErr_Occurred())
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a float number as argument" );
+ "expected float argument" );
- self->camera->drawsize = EXPP_ClampFloat( value,
+ self->camera->drawsize = EXPP_ClampFloat( param,
EXPP_CAM_DRAWSIZE_MIN,
EXPP_CAM_DRAWSIZE_MAX );
@@ -614,7 +572,7 @@ static PyObject *Camera_clearScriptLinks( BPy_Camera * self, PyObject * args )
}
/* cam.getScriptLinks */
-static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * args )
+static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * value )
{
Camera *cam = self->camera;
ScriptLink *slink = NULL;
@@ -622,7 +580,7 @@ static PyObject *Camera_oldgetScriptLinks( BPy_Camera * self, PyObject * args )
slink = &( cam )->scriptlink;
- ret = EXPP_getScriptLinks( slink, args, 0 );
+ ret = EXPP_getScriptLinks( slink, value, 0 );
if( ret )
return ret;
@@ -694,7 +652,7 @@ static int Camera_setMode( BPy_Camera * self, PyObject * value )
{
unsigned int flag = 0;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected an integer (bitmask) as argument" );
@@ -866,7 +824,12 @@ static PyObject *getFlagAttr( BPy_Camera *self, void *type )
static int setFlagAttr( BPy_Camera *self, PyObject *value, void *type )
{
- if (PyObject_IsTrue(value))
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param)
self->camera->flag |= (int)type;
else
self->camera->flag &= ~(int)type;
@@ -1077,11 +1040,11 @@ static PyObject *Camera_insertIpoKey( BPy_Camera * self, PyObject * args )
"expected int argument" ) );
if (key == IPOKEY_LENS){
- insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_LENS);
+ insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_LENS, 0);
}
else if (key == IPOKEY_CLIPPING){
- insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_STA);
- insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_END);
+ insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_STA, 0);
+ insertkey((ID *)self->camera, ID_CA, NULL, NULL, CAM_END, 0);
}
allspace(REMAKEIPO, 0);
diff --git a/source/blender/python/api2_2x/Constraint.c b/source/blender/python/api2_2x/Constraint.c
index 37c24dbbda6..9ca0d8d2545 100644
--- a/source/blender/python/api2_2x/Constraint.c
+++ b/source/blender/python/api2_2x/Constraint.c
@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
- * Contributor(s): Joseph Gilbert, Ken Hughes
+ * Contributor(s): Joseph Gilbert, Ken Hughes, Joshua Leung
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -36,12 +36,14 @@
#include "DNA_effect_types.h"
#include "DNA_vec_types.h"
#include "DNA_curve_types.h"
+#include "DNA_text_types.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_constraint.h"
#include "BLI_blenlib.h"
#include "BIF_editconstraint.h"
#include "BSE_editipo.h"
@@ -50,14 +52,22 @@
#include "blendef.h"
#include "mydevice.h"
+#include "IDProp.h"
#include "Object.h"
#include "NLA.h"
+#include "Text.h"
#include "gen_utils.h"
enum constraint_constants {
EXPP_CONSTR_XROT = 0,
EXPP_CONSTR_YROT = 1,
EXPP_CONSTR_ZROT = 2,
+ EXPP_CONSTR_XSIZE = 10,
+ EXPP_CONSTR_YSIZE = 11,
+ EXPP_CONSTR_ZSIZE = 12,
+ EXPP_CONSTR_XLOC = 20,
+ EXPP_CONSTR_YLOC = 21,
+ EXPP_CONSTR_ZLOC = 22,
EXPP_CONSTR_MAXX = TRACK_X,
EXPP_CONSTR_MAXY = TRACK_Y,
@@ -77,7 +87,6 @@ enum constraint_constants {
EXPP_CONSTR_USETIP,
EXPP_CONSTR_ACTION,
- EXPP_CONSTR_LOCAL,
EXPP_CONSTR_START,
EXPP_CONSTR_END,
EXPP_CONSTR_MIN,
@@ -116,6 +125,8 @@ enum constraint_constants {
EXPP_CONSTR_LIMYROT = LIMIT_YROT,
EXPP_CONSTR_LIMZROT = LIMIT_ZROT,
+ EXPP_CONSTR_CLAMPCYCLIC,
+
EXPP_CONSTR_XMIN,
EXPP_CONSTR_XMAX,
EXPP_CONSTR_YMIN,
@@ -123,9 +134,31 @@ enum constraint_constants {
EXPP_CONSTR_ZMIN,
EXPP_CONSTR_ZMAX,
- EXPP_CONSTR_LIMLOCALBONE,
- EXPP_CONSTR_LIMLOCALNOPAR,
+ EXPP_CONSTR_SCRIPT,
+ EXPP_CONSTR_PROPS,
+
+ EXPP_CONSTR_FROM,
+ EXPP_CONSTR_TO,
+ EXPP_CONSTR_EXPO,
+ EXPP_CONSTR_FROMMINX,
+ EXPP_CONSTR_FROMMAXX,
+ EXPP_CONSTR_FROMMINY,
+ EXPP_CONSTR_FROMMAXY,
+ EXPP_CONSTR_FROMMINZ,
+ EXPP_CONSTR_FROMMAXZ,
+ EXPP_CONSTR_TOMINX,
+ EXPP_CONSTR_TOMAXX,
+ EXPP_CONSTR_TOMINY,
+ EXPP_CONSTR_TOMAXY,
+ EXPP_CONSTR_TOMINZ,
+ EXPP_CONSTR_TOMAXZ,
+ EXPP_CONSTR_MAPX,
+ EXPP_CONSTR_MAPY,
+ EXPP_CONSTR_MAPZ,
+ EXPP_CONSTR_OWNSPACE,
+ EXPP_CONSTR_TARSPACE,
+
EXPP_CONSTR_RB_TYPE,
EXPP_CONSTR_RB_BALL,
EXPP_CONSTR_RB_HINGE,
@@ -174,7 +207,7 @@ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
/*****************************************************************************/
static PyMethodDef BPy_Constraint_methods[] = {
/* name, method, flags, doc */
- {"insertKey", ( PyCFunction ) Constraint_insertKey, METH_VARARGS,
+ {"insertKey", ( PyCFunction ) Constraint_insertKey, METH_O,
"Insert influence keyframe for constraint"},
{NULL, NULL, 0, NULL}
};
@@ -374,40 +407,226 @@ static PyObject *Constraint_getType( BPy_Constraint * self )
* add keyframe for influence
base on code in add_influence_key_to_constraint_func()
*/
-
-static PyObject *Constraint_insertKey( BPy_Constraint * self, PyObject * arg )
+static PyObject *Constraint_insertKey( BPy_Constraint * self, PyObject * value )
{
+ bConstraint *con = self->con;
+ Object *ob = self->obj;
+ bPoseChannel *pchan = self->pchan;
IpoCurve *icu;
- float cfra;
+ float cfra = (float)PyFloat_AsDouble(value);
char actname[32] = "";
- Object *ob = self->obj;
- bConstraint *con = self->con;
-
+
if( !self->con )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This constraint has been removed!" );
/* get frame for inserting key */
- if( !PyArg_ParseTuple( arg, "f", &cfra ) )
+ if( PyFloat_Check(value) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a float argument" );
-
- /* constraint_active_func(ob_v, con_v); */
- get_constraint_ipo_context( ob, actname );
- icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, CO_ENFORCE);
+
+ /* find actname for locating that action-channel that a constraint channel should be added to */
+ if (ob) {
+ if (pchan) {
+ /* actname is the name of the pchan that this constraint belongs to */
+ BLI_strncpy(actname, pchan->name, 32);
+ }
+ else {
+ /* hardcoded achan name -> "Object" (this may change in future) */
+ strcpy(actname, "Object");
+ }
+ }
+ else {
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "constraint doesn't belong to anything" );
+ }
+ icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, NULL, CO_ENFORCE);
if (!icu)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"cannot get a curve from this IPO, may be using libdata" );
if( ob->action )
- insert_vert_ipo( icu, get_action_frame(ob, cfra), con->enforce);
+ insert_vert_icu( icu, get_action_frame(ob, cfra), con->enforce, 0);
else
- insert_vert_ipo( icu, cfra, con->enforce);
+ insert_vert_icu( icu, cfra, con->enforce, 0);
Py_RETURN_NONE;
}
+/******************************************************************************/
+/* Constraint Space Conversion get/set procedures */
+/* - These are called before/instead of individual constraint */
+/* get/set procedures when OWNERSPACE or TARGETSPACE are chosen */
+/* - They are only called from Constraint_g/setData */
+/******************************************************************************/
+
+static PyObject *constspace_getter( BPy_Constraint * self, int type )
+{
+ bConstraint *con= (bConstraint *)(self->con);
+
+ /* depends on type being asked for
+ * NOTE: not all constraints support all space types
+ */
+ if (type == EXPP_CONSTR_OWNSPACE) {
+ switch (con->type) {
+ /* all of these support this... */
+ case CONSTRAINT_TYPE_PYTHON:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ case CONSTRAINT_TYPE_TRANSFORM:
+ return PyInt_FromLong( (long)con->ownspace );
+ }
+ }
+ else if (type == EXPP_CONSTR_TARSPACE) {
+ switch (con->type) {
+ /* all of these support this... */
+ case CONSTRAINT_TYPE_PYTHON:
+ case CONSTRAINT_TYPE_ACTION:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ bConstraintTarget *ct;
+ PyObject *tlist=NULL, *val;
+
+ if (cti) {
+ /* change space of targets */
+ if (cti->get_constraint_targets) {
+ ListBase targets = {NULL, NULL};
+ int num_tars=0, i=0;
+
+ /* get targets, and create py-list for use temporarily */
+ num_tars= cti->get_constraint_targets(con, &targets);
+ if (num_tars) {
+ tlist= PyList_New(num_tars);
+
+ for (ct=targets.first; ct; ct=ct->next, i++) {
+ val= PyInt_FromLong((long)ct->space);
+ PyList_SET_ITEM(tlist, i, val);
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
+ }
+ }
+
+ return tlist;
+ }
+ }
+ }
+
+ /* raise error if failed */
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+}
+
+static int constspace_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+ bConstraint *con= (bConstraint *)(self->con);
+
+ /* depends on type being asked for
+ * NOTE: not all constraints support all space types
+ */
+ if (type == EXPP_CONSTR_OWNSPACE) {
+ switch (con->type) {
+ /* all of these support this... */
+ case CONSTRAINT_TYPE_PYTHON:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ /* only copy depending on ownertype */
+ if (self->pchan) {
+ return EXPP_setIValueClamped( value, &con->ownspace,
+ CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, 'h' );
+ }
+ else {
+ return EXPP_setIValueClamped( value, &con->ownspace,
+ CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, 'h' );
+ }
+ }
+ break;
+ }
+ }
+ else if (type == EXPP_CONSTR_TARSPACE) {
+ switch (con->type) {
+ /* all of these support this... */
+ case CONSTRAINT_TYPE_PYTHON:
+ case CONSTRAINT_TYPE_ACTION:
+ case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_SIZELIKE:
+ case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ bConstraintTarget *ct;
+ int ok= 0;
+
+ if (cti) {
+ /* change space of targets */
+ if (cti->get_constraint_targets) {
+ ListBase targets = {NULL, NULL};
+ int num_tars=0, i=0;
+
+ /* get targets, and extract values from the given list */
+ num_tars= cti->get_constraint_targets(con, &targets);
+ if (num_tars) {
+ if ((PySequence_Check(value) == 0) || (PySequence_Size(value) != num_tars)) {
+ char errorstr[64];
+ sprintf(errorstr, "expected sequence of %d integer(s)", num_tars);
+ return EXPP_ReturnIntError(PyExc_TypeError, errorstr);
+ }
+
+ for (ct=targets.first; ct; ct=ct->next, i++) {
+ if (ct->tar && ct->subtarget[0]) {
+ PyObject *val= PySequence_ITEM(value, i);
+
+ ok += EXPP_setIValueClamped(val, &ct->space,
+ CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL, 'h' );
+
+ Py_DECREF(val);
+ }
+ else if (ct->tar) {
+ PyObject *val= PySequence_ITEM(value, i);
+
+ ok += EXPP_setIValueClamped(val, &ct->space,
+ CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, 'h' );
+
+ Py_DECREF(val);
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+
+ return ok;
+ }
+ break;
+ }
+ }
+
+ /* raise error if failed */
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+}
+
/*****************************************************************************/
/* Specific constraint get/set procedures */
/*****************************************************************************/
@@ -493,8 +712,6 @@ static PyObject *action_getter( BPy_Constraint * self, int type )
return PyString_FromString( con->subtarget );
case EXPP_CONSTR_ACTION:
return Action_CreatePyObject( con->act );
- case EXPP_CONSTR_LOCAL:
- return PyBool_FromLong( (long)( con->local & SELECT ) );
case EXPP_CONSTR_START:
return PyInt_FromLong( (long)con->start );
case EXPP_CONSTR_END:
@@ -541,19 +758,27 @@ static int action_setter( BPy_Constraint *self, int type, PyObject *value )
con->act = act;
return 0;
}
- case EXPP_CONSTR_LOCAL:
- return EXPP_setBitfield( value, &con->local, SELECT, 'h' );
case EXPP_CONSTR_START:
return EXPP_setIValueClamped( value, &con->start, 1, MAXFRAME, 'h' );
case EXPP_CONSTR_END:
return EXPP_setIValueClamped( value, &con->end, 1, MAXFRAME, 'h' );
case EXPP_CONSTR_MIN:
- return EXPP_setFloatClamped( value, &con->min, -180.0, 180.0 );
+ if (con->type < 10)
+ return EXPP_setFloatClamped( value, &con->min, -180.0, 180.0 );
+ else if (con->type < 20)
+ return EXPP_setFloatClamped( value, &con->min, 0.0001, 1000.0 );
+ else
+ return EXPP_setFloatClamped( value, &con->min, -1000.0, 1000.0 );
case EXPP_CONSTR_MAX:
- return EXPP_setFloatClamped( value, &con->max, -180.0, 180.0 );
+ if (con->type < 10)
+ return EXPP_setFloatClamped( value, &con->max, -180.0, 180.0 );
+ else if (con->type < 20)
+ return EXPP_setFloatClamped( value, &con->max, 0.0001, 1000.0 );
+ else
+ return EXPP_setFloatClamped( value, &con->max, -1000.0, 1000.0 );
case EXPP_CONSTR_KEYON:
return EXPP_setIValueRange( value, &con->type,
- EXPP_CONSTR_XROT, EXPP_CONSTR_ZROT, 'h' );
+ EXPP_CONSTR_XROT, EXPP_CONSTR_ZLOC, 'h' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}
@@ -737,6 +962,8 @@ static PyObject *clampto_getter( BPy_Constraint * self, int type )
return Object_CreatePyObject( con->tar );
case EXPP_CONSTR_CLAMP:
return PyInt_FromLong( (long)con->flag );
+ case EXPP_CONSTR_CLAMPCYCLIC:
+ return PyBool_FromLong( (long)(con->flag2 & CLAMPTO_CYCLIC) );
default:
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
}
@@ -758,6 +985,8 @@ static int clampto_setter( BPy_Constraint *self, int type, PyObject *value )
case EXPP_CONSTR_CLAMP:
return EXPP_setIValueRange( value, &con->flag,
CLAMPTO_AUTO, CLAMPTO_Z, 'i' );
+ case EXPP_CONSTR_CLAMPCYCLIC:
+ return EXPP_setBitfield( value, &con->flag2, CLAMPTO_CYCLIC, 'i' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}
@@ -880,11 +1109,6 @@ static PyObject *locatelike_getter( BPy_Constraint * self, int type )
return PyString_FromString( con->subtarget );
case EXPP_CONSTR_COPY:
return PyInt_FromLong( (long)con->flag );
- case EXPP_CONSTR_LOCAL:
- if( get_armature( con->tar ) )
- return PyBool_FromLong( (long)
- ( self->con->flag & CONSTRAINT_LOCAL ) ) ;
- Py_RETURN_NONE;
default:
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
}
@@ -916,12 +1140,6 @@ static int locatelike_setter( BPy_Constraint *self, int type, PyObject *value )
case EXPP_CONSTR_COPY:
return EXPP_setIValueRange( value, &con->flag,
0, LOCLIKE_X | LOCLIKE_Y | LOCLIKE_Z | LOCLIKE_X_INVERT | LOCLIKE_Y_INVERT | LOCLIKE_Z_INVERT, 'i' );
- case EXPP_CONSTR_LOCAL:
- if( !get_armature( con->tar ) )
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "only armature targets have LOCAL key" );
- return EXPP_setBitfield( value, &self->con->flag,
- CONSTRAINT_LOCAL, 'h' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}
@@ -938,11 +1156,6 @@ static PyObject *rotatelike_getter( BPy_Constraint * self, int type )
return PyString_FromString( con->subtarget );
case EXPP_CONSTR_COPY:
return PyInt_FromLong( (long)con->flag );
- case EXPP_CONSTR_LOCAL:
- if( get_armature( con->tar ) )
- return PyBool_FromLong( (long)
- ( self->con->flag & CONSTRAINT_LOCAL ) ) ;
- Py_RETURN_NONE;
default:
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
}
@@ -973,13 +1186,7 @@ static int rotatelike_setter( BPy_Constraint *self, int type, PyObject *value )
}
case EXPP_CONSTR_COPY:
return EXPP_setIValueRange( value, &con->flag,
- 0, LOCLIKE_X | LOCLIKE_Y | LOCLIKE_Z | LOCLIKE_X_INVERT | LOCLIKE_Y_INVERT | LOCLIKE_Z_INVERT, 'i' );
- case EXPP_CONSTR_LOCAL:
- if( !get_armature( con->tar ) )
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "only armature targets have LOCAL key" );
- return EXPP_setBitfield( value, &self->con->flag,
- CONSTRAINT_LOCAL, 'h' );
+ 0, ROTLIKE_X | ROTLIKE_Y | ROTLIKE_Z | ROTLIKE_X_INVERT | ROTLIKE_Y_INVERT | ROTLIKE_Z_INVERT, 'i' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}
@@ -996,13 +1203,6 @@ static PyObject *sizelike_getter( BPy_Constraint * self, int type )
return PyString_FromString( con->subtarget );
case EXPP_CONSTR_COPY:
return PyInt_FromLong( (long)con->flag );
-#if 0
- case EXPP_CONSTR_LOCAL:
- if( get_armature( con->tar ) )
- return PyBool_FromLong( (long)
- ( self->con->flag & CONSTRAINT_LOCAL ) ) ;
- Py_RETURN_NONE;
-#endif
default:
return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
}
@@ -1033,15 +1233,7 @@ static int sizelike_setter( BPy_Constraint *self, int type, PyObject *value )
}
case EXPP_CONSTR_COPY:
return EXPP_setIValueRange( value, &con->flag,
- 0, LOCLIKE_X | LOCLIKE_Y | LOCLIKE_Z | LOCLIKE_X_INVERT | LOCLIKE_Y_INVERT | LOCLIKE_Z_INVERT, 'i' );
-#if 0
- case EXPP_CONSTR_LOCAL:
- if( !get_armature( con->tar ) )
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "only armature targets have LOCAL key" );
- return EXPP_setBitfield( value, &self->con->flag,
- CONSTRAINT_LOCAL, 'h' );
-#endif
+ 0, SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z, 'i' );
default:
return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
}
@@ -1054,12 +1246,6 @@ static PyObject *loclimit_getter( BPy_Constraint * self, int type)
switch( type ) {
case EXPP_CONSTR_LIMIT:
return PyInt_FromLong( (long)con->flag );
- case EXPP_CONSTR_LIMLOCALBONE:
- return PyBool_FromLong( (long)
- ( self->con->flag & CONSTRAINT_LOCAL ) ) ;
- case EXPP_CONSTR_LIMLOCALNOPAR:
- return PyBool_FromLong( (long)
- ( con->flag2 & LIMIT_NOPARENT ) ) ;
case EXPP_CONSTR_XMIN:
return PyFloat_FromDouble( (double)con->xmin );
case EXPP_CONSTR_XMAX:
@@ -1085,12 +1271,6 @@ static int loclimit_setter( BPy_Constraint *self, int type, PyObject *value )
case EXPP_CONSTR_LIMIT:
return EXPP_setIValueRange( value, &con->flag, 0,
LIMIT_XMIN | LIMIT_XMAX | LIMIT_YMIN | LIMIT_YMAX | LIMIT_ZMIN | LIMIT_ZMAX , 'i' );
- case EXPP_CONSTR_LIMLOCALBONE:
- return EXPP_setBitfield( value, &self->con->flag,
- CONSTRAINT_LOCAL, 'h' );
- case EXPP_CONSTR_LIMLOCALNOPAR:
- return EXPP_setBitfield( value, &con->flag2,
- LIMIT_NOPARENT, 'h' );
case EXPP_CONSTR_XMIN:
return EXPP_setFloatClamped( value, &con->xmin, -1000.0, 1000.0 );
case EXPP_CONSTR_XMAX:
@@ -1115,9 +1295,6 @@ static PyObject *rotlimit_getter( BPy_Constraint * self, int type )
switch( type ) {
case EXPP_CONSTR_LIMIT:
return PyInt_FromLong( (long)con->flag );
- case EXPP_CONSTR_LIMLOCALBONE:
- return PyBool_FromLong( (long)
- (self->con->flag & CONSTRAINT_LOCAL ) );
case EXPP_CONSTR_XMIN:
return PyFloat_FromDouble( (double)con->xmin );
case EXPP_CONSTR_XMAX:
@@ -1143,9 +1320,6 @@ static int rotlimit_setter( BPy_Constraint *self, int type, PyObject *value )
case EXPP_CONSTR_LIMIT:
return EXPP_setIValueRange( value, &con->flag, 0,
LIMIT_XROT | LIMIT_YROT | LIMIT_ZROT, 'i' );
- case EXPP_CONSTR_LIMLOCALBONE:
- return EXPP_setBitfield( value, &self->con->flag,
- CONSTRAINT_LOCAL, 'h' );
case EXPP_CONSTR_XMIN:
return EXPP_setFloatClamped( value, &con->xmin, -360.0, 360.0 );
case EXPP_CONSTR_XMAX:
@@ -1212,6 +1386,65 @@ static int sizelimit_setter( BPy_Constraint *self, int type, PyObject *value )
}
}
+static PyObject *script_getter( BPy_Constraint * self, int type )
+{
+ bPythonConstraint *con = (bPythonConstraint *)(self->con->data);
+
+ switch( type ) {
+ // FIXME!!!
+ //case EXPP_CONSTR_TARGET:
+ // return Object_CreatePyObject( con->tar );
+ //case EXPP_CONSTR_BONE:
+ // return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_SCRIPT:
+ return Text_CreatePyObject( con->text );
+ case EXPP_CONSTR_PROPS:
+ return BPy_Wrap_IDProperty( NULL, con->prop, NULL);
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+}
+
+static int script_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+ bPythonConstraint *con = (bPythonConstraint *)(self->con->data);
+
+ switch( type ) {
+ // FIXME!!!
+ //case EXPP_CONSTR_TARGET: {
+ // Object *obj = (( BPy_Object * )value)->object;
+ // if( !BPy_Object_Check( value ) )
+ // return EXPP_ReturnIntError( PyExc_TypeError,
+ // "expected BPy object argument" );
+ // con->tar = obj;
+ // return 0;
+ // }
+ //case EXPP_CONSTR_BONE: {
+ // char *name = PyString_AsString( value );
+ // if( !name )
+ // return EXPP_ReturnIntError( PyExc_TypeError,
+ // "expected string arg" );
+ //
+ // BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
+ //
+ // return 0;
+ // }
+ case EXPP_CONSTR_SCRIPT: {
+ Text *text = (( BPy_Text * )value)->text;
+ if( !BPy_Object_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy text argument" );
+ con->text = text;
+ return 0;
+ }
+ case EXPP_CONSTR_PROPS:
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "setting ID-Properties of PyConstraints this way is not supported" );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+}
+
static PyObject *rigidbody_getter( BPy_Constraint * self, int type)
{
@@ -1331,6 +1564,195 @@ static int rigidbody_setter( BPy_Constraint *self, int type, PyObject *value )
}
}
+static PyObject *childof_getter( BPy_Constraint * self, int type )
+{
+ bChildOfConstraint *con = (bChildOfConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET:
+ return Object_CreatePyObject( con->tar );
+ case EXPP_CONSTR_BONE:
+ return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_COPY:
+ return PyInt_FromLong( (long)con->flag );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+}
+
+static int childof_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+ bChildOfConstraint *con = (bChildOfConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy object argument" );
+ con->tar = obj;
+ return 0;
+ }
+ case EXPP_CONSTR_BONE: {
+ char *name = PyString_AsString( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string arg" );
+
+ BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
+
+ return 0;
+ }
+ case EXPP_CONSTR_COPY:
+ return EXPP_setIValueRange( value, &con->flag,
+ 0, CHILDOF_LOCX| CHILDOF_LOCY | CHILDOF_LOCZ | CHILDOF_ROTX | CHILDOF_ROTY | CHILDOF_ROTZ |
+ CHILDOF_SIZEX |CHILDOF_SIZEY| CHILDOF_SIZEZ, 'i' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+}
+
+static PyObject *transf_getter( BPy_Constraint * self, int type )
+{
+ bTransformConstraint *con = (bTransformConstraint *)(self->con->data);
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET:
+ return Object_CreatePyObject( con->tar );
+ case EXPP_CONSTR_BONE:
+ return PyString_FromString( con->subtarget );
+ case EXPP_CONSTR_FROM:
+ return PyInt_FromLong( (long)con->from );
+ case EXPP_CONSTR_TO:
+ return PyInt_FromLong( (long)con->to );
+ case EXPP_CONSTR_MAPX:
+ return PyInt_FromLong( (long)con->map[0] );
+ case EXPP_CONSTR_MAPY:
+ return PyInt_FromLong( (long)con->map[1] );
+ case EXPP_CONSTR_MAPZ:
+ return PyInt_FromLong( (long)con->map[2] );
+ case EXPP_CONSTR_FROMMINX:
+ return PyFloat_FromDouble( (double)con->from_min[0] );
+ case EXPP_CONSTR_FROMMAXX:
+ return PyFloat_FromDouble( (double)con->from_max[0] );
+ case EXPP_CONSTR_FROMMINY:
+ return PyFloat_FromDouble( (double)con->from_min[1] );
+ case EXPP_CONSTR_FROMMAXY:
+ return PyFloat_FromDouble( (double)con->from_max[1] );
+ case EXPP_CONSTR_FROMMINZ:
+ return PyFloat_FromDouble( (double)con->from_min[2] );
+ case EXPP_CONSTR_FROMMAXZ:
+ return PyFloat_FromDouble( (double)con->from_max[2] );
+ case EXPP_CONSTR_TOMINX:
+ return PyFloat_FromDouble( (double)con->to_min[0] );
+ case EXPP_CONSTR_TOMAXX:
+ return PyFloat_FromDouble( (double)con->to_max[0] );
+ case EXPP_CONSTR_TOMINY:
+ return PyFloat_FromDouble( (double)con->to_min[1] );
+ case EXPP_CONSTR_TOMAXY:
+ return PyFloat_FromDouble( (double)con->to_max[1] );
+ case EXPP_CONSTR_TOMINZ:
+ return PyFloat_FromDouble( (double)con->to_min[2] );
+ case EXPP_CONSTR_TOMAXZ:
+ return PyFloat_FromDouble( (double)con->to_max[2] );
+ case EXPP_CONSTR_EXPO:
+ return PyBool_FromLong( (long)con->expo );
+ default:
+ return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" );
+ }
+}
+
+static int transf_setter( BPy_Constraint *self, int type, PyObject *value )
+{
+ bTransformConstraint *con = (bTransformConstraint *)(self->con->data);
+ float fmin, fmax, tmin, tmax;
+
+ if (con->from == 2) {
+ fmin = 0.0001;
+ fmax = 1000.0;
+ }
+ else if (con->from == 1) {
+ fmin = -360.0;
+ fmax = 360.0;
+ }
+ else {
+ fmin = -1000.0;
+ fmax = 1000.0;
+ }
+
+ if (con->to == 2) {
+ tmin = 0.0001;
+ tmax = 1000.0;
+ }
+ else if (con->to == 1) {
+ tmin = -360.0;
+ tmax = 360.0;
+ }
+ else {
+ tmin = -1000.0;
+ tmax = 1000.0;
+ }
+
+ switch( type ) {
+ case EXPP_CONSTR_TARGET: {
+ Object *obj = (( BPy_Object * )value)->object;
+ if( !BPy_Object_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected BPy object argument" );
+ con->tar = obj;
+ return 0;
+ }
+ case EXPP_CONSTR_BONE: {
+ char *name = PyString_AsString( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string arg" );
+
+ BLI_strncpy( con->subtarget, name, sizeof( con->subtarget ) );
+
+ return 0;
+ }
+ case EXPP_CONSTR_FROM:
+ return EXPP_setIValueClamped( value, &con->from, 0, 3, 'h' );
+ case EXPP_CONSTR_TO:
+ return EXPP_setIValueClamped( value, &con->to, 0, 3, 'h' );
+ case EXPP_CONSTR_MAPX:
+ return EXPP_setIValueClamped( value, &con->map[0], 0, 3, 'h' );
+ case EXPP_CONSTR_MAPY:
+ return EXPP_setIValueClamped( value, &con->map[1], 0, 3, 'h' );
+ case EXPP_CONSTR_MAPZ:
+ return EXPP_setIValueClamped( value, &con->map[2], 0, 3, 'h' );
+ case EXPP_CONSTR_FROMMINX:
+ return EXPP_setFloatClamped( value, &con->from_min[0], fmin, fmax );
+ case EXPP_CONSTR_FROMMAXX:
+ return EXPP_setFloatClamped( value, &con->from_max[0], fmin, fmax );
+ case EXPP_CONSTR_FROMMINY:
+ return EXPP_setFloatClamped( value, &con->from_min[1], fmin, fmax );
+ case EXPP_CONSTR_FROMMAXY:
+ return EXPP_setFloatClamped( value, &con->from_max[1], fmin, fmax );
+ case EXPP_CONSTR_FROMMINZ:
+ return EXPP_setFloatClamped( value, &con->from_min[2], fmin, fmax );
+ case EXPP_CONSTR_FROMMAXZ:
+ return EXPP_setFloatClamped( value, &con->from_max[2], fmin, fmax );
+ case EXPP_CONSTR_TOMINX:
+ return EXPP_setFloatClamped( value, &con->to_min[0], tmin, tmax );
+ case EXPP_CONSTR_TOMAXX:
+ return EXPP_setFloatClamped( value, &con->to_max[0], tmin, tmax );
+ case EXPP_CONSTR_TOMINY:
+ return EXPP_setFloatClamped( value, &con->to_min[1], tmin, tmax );
+ case EXPP_CONSTR_TOMAXY:
+ return EXPP_setFloatClamped( value, &con->to_max[1], tmin, tmax );
+ case EXPP_CONSTR_TOMINZ:
+ return EXPP_setFloatClamped( value, &con->to_min[2], tmin, tmax );
+ case EXPP_CONSTR_TOMAXZ:
+ return EXPP_setFloatClamped( value, &con->to_max[2], tmin, tmax );
+ case EXPP_CONSTR_EXPO:
+ return EXPP_setBitfield( value, &con->expo, 1, 'h' );
+ default:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ }
+}
+
/*
* get data from a constraint
*/
@@ -1339,7 +1761,7 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
{
int setting;
- if( !PyInt_CheckExact( key ) )
+ if( !PyInt_Check( key ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an int arg" );
@@ -1348,6 +1770,13 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
"This constraint has been removed!" );
setting = PyInt_AsLong( key );
+
+ /* bypass doing settings of individual constraints, if we're just doing
+ * constraint space access-stuff
+ */
+ if ((setting==EXPP_CONSTR_OWNSPACE) || (setting==EXPP_CONSTR_TARSPACE)) {
+ return constspace_getter( self, setting );
+ }
switch( self->con->type ) {
case CONSTRAINT_TYPE_NULL:
Py_RETURN_NONE;
@@ -1381,8 +1810,12 @@ static PyObject *Constraint_getData( BPy_Constraint * self, PyObject * key )
return rigidbody_getter( self, setting );
case CONSTRAINT_TYPE_CLAMPTO:
return clampto_getter( self, setting );
- case CONSTRAINT_TYPE_CHILDOF: /* Unimplemented */
case CONSTRAINT_TYPE_PYTHON:
+ return script_getter( self, setting );
+ case CONSTRAINT_TYPE_CHILDOF:
+ return childof_getter( self, setting );
+ case CONSTRAINT_TYPE_TRANSFORM:
+ return transf_getter( self, setting );
default:
return EXPP_ReturnPyObjError( PyExc_KeyError,
"unknown constraint type" );
@@ -1402,59 +1835,75 @@ static int Constraint_setData( BPy_Constraint * self, PyObject * key,
"This constraint has been removed!" );
key_int = PyInt_AsLong( key );
- switch( self->con->type ) {
- case CONSTRAINT_TYPE_KINEMATIC:
- result = kinematic_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_ACTION:
- result = action_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- result = trackto_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- result = stretchto_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- result = followpath_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- result = locktrack_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_MINMAX:
- result = floor_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- result = locatelike_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- result = rotatelike_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- result = sizelike_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
- result = rotlimit_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
- result = loclimit_setter( self, key_int, arg );
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- result = sizelimit_setter( self, key_int, arg);
- break;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- result = rigidbody_setter( self, key_int, arg);
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- result = clampto_setter( self, key_int, arg);
- break;
- case CONSTRAINT_TYPE_NULL:
- return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
- case CONSTRAINT_TYPE_CHILDOF: /* Unimplemented */
- case CONSTRAINT_TYPE_PYTHON:
- default:
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "unsupported constraint setting" );
+
+ /* bypass doing settings of individual constraints, if we're just doing
+ * constraint space access-stuff
+ */
+ if ((key_int==EXPP_CONSTR_OWNSPACE) || (key_int==EXPP_CONSTR_TARSPACE)) {
+ result = constspace_setter( self, key_int, arg );
+ }
+ else {
+ switch( self->con->type ) {
+ case CONSTRAINT_TYPE_KINEMATIC:
+ result = kinematic_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_ACTION:
+ result = action_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ result = trackto_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ result = stretchto_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ result = followpath_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ result = locktrack_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_MINMAX:
+ result = floor_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ result = locatelike_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ result = rotatelike_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_SIZELIKE:
+ result = sizelike_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ result = rotlimit_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ result = loclimit_setter( self, key_int, arg );
+ break;
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ result = sizelimit_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_RIGIDBODYJOINT:
+ result = rigidbody_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_CLAMPTO:
+ result = clampto_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_PYTHON:
+ result = script_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_CHILDOF:
+ result = childof_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ result = transf_setter( self, key_int, arg);
+ break;
+ case CONSTRAINT_TYPE_NULL:
+ return EXPP_ReturnIntError( PyExc_KeyError, "key not found" );
+ default:
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "unsupported constraint setting" );
+ }
}
if( !result && self->pchan )
update_pose_constraint_flags( self->obj->pose );
@@ -1478,14 +1927,20 @@ static int Constraint_compare( BPy_Constraint * a, BPy_Constraint * b )
static PyObject *Constraint_repr( BPy_Constraint * self )
{
- char type[32];
+ bConstraintTypeInfo *cti;
- if( !self->con )
- return PyString_FromString( "[Constraint - Removed]");
-
- get_constraint_typestring (type, self->con);
- return PyString_FromFormat( "[Constraint \"%s\", Type \"%s\"]",
- self->con->name, type );
+ if (!self->con)
+ return PyString_FromString("[Constraint - Removed]");
+ else
+ cti= constraint_get_typeinfo(self->con);
+
+ if (cti) {
+ return PyString_FromFormat("[Constraint \"%s\", Type \"%s\"]",
+ self->con->name, cti->name);
+ }
+ else {
+ return PyString_FromString("[Constraint \"%s\", Type \"Unknown\"]");
+ }
}
/* Three Python Constraint_Type helper functions needed by the Object module: */
@@ -1613,18 +2068,17 @@ static PySequenceMethods ConstraintSeq_as_sequence = {
* helper function to check for a valid constraint argument
*/
-static bConstraint *locate_constr( BPy_ConstraintSeq *self, PyObject * args )
+static bConstraint *locate_constr( BPy_ConstraintSeq *self, BPy_Constraint * value )
{
- BPy_Constraint *pyobj;
bConstraint *con;
/* check that argument is a modifier */
- if( !PyArg_ParseTuple( args, "O!", &Constraint_Type, &pyobj ) )
+ if (!BPy_Constraint_Check(value))
return (bConstraint *)EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a constraint as an argument" );
/* check whether constraint has been removed */
- if( !pyobj->con )
+ if( !value->con )
return (bConstraint *)EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This constraint has been removed!" );
@@ -1633,7 +2087,7 @@ static bConstraint *locate_constr( BPy_ConstraintSeq *self, PyObject * args )
con = self->pchan->constraints.first;
else
con = self->obj->constraints.first;
- while( con && con != pyobj->con )
+ while( con && con != value->con )
con = con->next;
/* if we didn't find it, exception */
@@ -1647,18 +2101,16 @@ static bConstraint *locate_constr( BPy_ConstraintSeq *self, PyObject * args )
/* create a new constraint at the end of the list */
-static PyObject *ConstraintSeq_append( BPy_ConstraintSeq *self, PyObject *args )
+static PyObject *ConstraintSeq_append( BPy_ConstraintSeq *self, PyObject *value )
{
- int type;
+ int type = (int)PyInt_AsLong(value);
bConstraint *con;
- if( !PyArg_ParseTuple( args, "i", &type ) )
- EXPP_ReturnPyObjError( PyExc_TypeError, "expected int argument" );
-
- /* type 0 is CONSTRAINT_TYPE_NULL, should we be able to add one of these? */
+ /* type 0 is CONSTRAINT_TYPE_NULL, should we be able to add one of these?
+ * if the value is not an int it will be -1 */
if( type < CONSTRAINT_TYPE_NULL || type > CONSTRAINT_TYPE_RIGIDBODYJOINT )
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "int argument out of range" );
+ "arg not in int or out of range" );
con = add_new_constraint( type );
if( self->pchan ) {
@@ -1673,9 +2125,9 @@ static PyObject *ConstraintSeq_append( BPy_ConstraintSeq *self, PyObject *args )
/* move the constraint up in the stack */
-static PyObject *ConstraintSeq_moveUp( BPy_ConstraintSeq *self, PyObject *args )
+static PyObject *ConstraintSeq_moveUp( BPy_ConstraintSeq *self, BPy_Constraint *value )
{
- bConstraint *con = locate_constr( self, args );
+ bConstraint *con = locate_constr( self, value );
/* if we can't locate the constraint, return (exception already set) */
if( !con )
@@ -1687,9 +2139,9 @@ static PyObject *ConstraintSeq_moveUp( BPy_ConstraintSeq *self, PyObject *args )
/* move the constraint down in the stack */
-static PyObject *ConstraintSeq_moveDown( BPy_ConstraintSeq *self, PyObject *args )
+static PyObject *ConstraintSeq_moveDown( BPy_ConstraintSeq *self, BPy_Constraint *value )
{
- bConstraint *con = locate_constr( self, args );
+ bConstraint *con = locate_constr( self, value );
/* if we can't locate the constraint, return (exception already set) */
if( !con )
@@ -1701,10 +2153,9 @@ static PyObject *ConstraintSeq_moveDown( BPy_ConstraintSeq *self, PyObject *args
/* remove an existing constraint */
-static PyObject *ConstraintSeq_remove( BPy_ConstraintSeq *self, PyObject *args )
+static PyObject *ConstraintSeq_remove( BPy_ConstraintSeq *self, BPy_Constraint *value )
{
- BPy_Constraint *pyobj;
- bConstraint *con = locate_constr( self, args );
+ bConstraint *con = locate_constr( self, value );
/* if we can't locate the constraint, return (exception already set) */
if( !con )
@@ -1718,8 +2169,7 @@ static PyObject *ConstraintSeq_remove( BPy_ConstraintSeq *self, PyObject *args )
del_constr_func( self->obj, con );
/* erase the link to the constraint */
- pyobj = ( BPy_Constraint * )PyTuple_GET_ITEM( args, 0 );
- pyobj->con = NULL;
+ value->con = NULL;
Py_RETURN_NONE;
}
@@ -1739,13 +2189,13 @@ static void ConstraintSeq_dealloc( BPy_Constraint * self )
/*****************************************************************************/
static PyMethodDef BPy_ConstraintSeq_methods[] = {
/* name, method, flags, doc */
- {"append", ( PyCFunction ) ConstraintSeq_append, METH_VARARGS,
+ {"append", ( PyCFunction ) ConstraintSeq_append, METH_O,
"(type) - add a new constraint, where type is the constraint type"},
- {"remove", ( PyCFunction ) ConstraintSeq_remove, METH_VARARGS,
+ {"remove", ( PyCFunction ) ConstraintSeq_remove, METH_O,
"(con) - remove an existing constraint, where con is a constraint from this object."},
- {"moveUp", ( PyCFunction ) ConstraintSeq_moveUp, METH_VARARGS,
+ {"moveUp", ( PyCFunction ) ConstraintSeq_moveUp, METH_O,
"(con) - Move constraint up in stack"},
- {"moveDown", ( PyCFunction ) ConstraintSeq_moveDown, METH_VARARGS,
+ {"moveDown", ( PyCFunction ) ConstraintSeq_moveDown, METH_O,
"(con) - Move constraint down in stack"},
{NULL, NULL, 0, NULL}
};
@@ -1924,6 +2374,12 @@ static PyObject *M_Constraint_TypeDict( void )
PyInt_FromLong( CONSTRAINT_TYPE_RIGIDBODYJOINT ) );
PyConstant_Insert( d, "CLAMPTO",
PyInt_FromLong( CONSTRAINT_TYPE_CLAMPTO ) );
+ PyConstant_Insert( d, "PYTHON",
+ PyInt_FromLong( CONSTRAINT_TYPE_PYTHON ) );
+ PyConstant_Insert( d, "CHILDOF",
+ PyInt_FromLong( CONSTRAINT_TYPE_CHILDOF ) );
+ PyConstant_Insert( d, "TRANSFORM",
+ PyInt_FromLong( CONSTRAINT_TYPE_TRANSFORM ) );
}
return S;
}
@@ -1940,6 +2396,18 @@ static PyObject *M_Constraint_SettingsDict( void )
PyInt_FromLong( EXPP_CONSTR_YROT ) );
PyConstant_Insert( d, "ZROT",
PyInt_FromLong( EXPP_CONSTR_ZROT ) );
+ PyConstant_Insert( d, "XSIZE",
+ PyInt_FromLong( EXPP_CONSTR_XSIZE ) );
+ PyConstant_Insert( d, "YSIZE",
+ PyInt_FromLong( EXPP_CONSTR_YSIZE ) );
+ PyConstant_Insert( d, "ZSIZE",
+ PyInt_FromLong( EXPP_CONSTR_ZSIZE ) );
+ PyConstant_Insert( d, "XLOC",
+ PyInt_FromLong( EXPP_CONSTR_XLOC ) );
+ PyConstant_Insert( d, "YLOC",
+ PyInt_FromLong( EXPP_CONSTR_YLOC ) );
+ PyConstant_Insert( d, "ZLOC",
+ PyInt_FromLong( EXPP_CONSTR_ZLOC ) );
PyConstant_Insert( d, "UPX",
PyInt_FromLong( UP_X ) );
@@ -2010,6 +2478,25 @@ static PyObject *M_Constraint_SettingsDict( void )
PyConstant_Insert( d, "COPYZINVERT",
PyInt_FromLong( LOCLIKE_Z_INVERT ) );
+ PyConstant_Insert( d, "PARLOCX",
+ PyInt_FromLong( CHILDOF_LOCX ) );
+ PyConstant_Insert( d, "PARLOCY",
+ PyInt_FromLong( CHILDOF_LOCY ) );
+ PyConstant_Insert( d, "PARLOCZ",
+ PyInt_FromLong( CHILDOF_LOCZ ) );
+ PyConstant_Insert( d, "PARROTX",
+ PyInt_FromLong( CHILDOF_ROTX ) );
+ PyConstant_Insert( d, "PARROTY",
+ PyInt_FromLong( CHILDOF_ROTY ) );
+ PyConstant_Insert( d, "PARROTZ",
+ PyInt_FromLong( CHILDOF_ROTZ ) );
+ PyConstant_Insert( d, "PARSIZEX",
+ PyInt_FromLong( CHILDOF_LOCX ) );
+ PyConstant_Insert( d, "PARSIZEY",
+ PyInt_FromLong( CHILDOF_SIZEY ) );
+ PyConstant_Insert( d, "PARSIZEZ",
+ PyInt_FromLong( CHILDOF_SIZEZ ) );
+
PyConstant_Insert( d, "CLAMPAUTO",
PyInt_FromLong( CLAMPTO_AUTO ) );
PyConstant_Insert( d, "CLAMPX",
@@ -2018,6 +2505,8 @@ static PyObject *M_Constraint_SettingsDict( void )
PyInt_FromLong( CLAMPTO_Y ) );
PyConstant_Insert( d, "CLAMPZ",
PyInt_FromLong( CLAMPTO_Z ) );
+ PyConstant_Insert( d, "CLAMPCYCLIC",
+ PyInt_FromLong( EXPP_CONSTR_CLAMPCYCLIC ));
PyConstant_Insert( d, "TARGET",
PyInt_FromLong( EXPP_CONSTR_TARGET ) );
@@ -2040,8 +2529,6 @@ static PyObject *M_Constraint_SettingsDict( void )
PyConstant_Insert( d, "ACTION",
PyInt_FromLong( EXPP_CONSTR_ACTION ) );
- PyConstant_Insert( d, "LOCAL",
- PyInt_FromLong( EXPP_CONSTR_LOCAL ) );
PyConstant_Insert( d, "START",
PyInt_FromLong( EXPP_CONSTR_START ) );
PyConstant_Insert( d, "END",
@@ -2116,13 +2603,56 @@ static PyObject *M_Constraint_SettingsDict( void )
PyInt_FromLong( EXPP_CONSTR_ZMIN ) );
PyConstant_Insert( d, "ZMAX",
PyInt_FromLong( EXPP_CONSTR_ZMAX ) );
-
- PyConstant_Insert( d, "LIMIT_LOCAL_BONE",
- PyInt_FromLong( EXPP_CONSTR_LIMLOCALBONE ) );
- PyConstant_Insert( d, "LIMIT_LOCAL_NOPARENT",
- PyInt_FromLong( EXPP_CONSTR_LIMLOCALNOPAR ) );
-
-
+
+ PyConstant_Insert( d, "SCRIPT",
+ PyInt_FromLong( EXPP_CONSTR_SCRIPT ) );
+ PyConstant_Insert( d, "PROPERTIES",
+ PyInt_FromLong( EXPP_CONSTR_PROPS ) );
+
+ PyConstant_Insert( d, "FROM",
+ PyInt_FromLong( EXPP_CONSTR_FROM ) );
+ PyConstant_Insert( d, "TO",
+ PyInt_FromLong( EXPP_CONSTR_TO ) );
+ PyConstant_Insert( d, "EXTRAPOLATE",
+ PyInt_FromLong( EXPP_CONSTR_EXPO ) );
+ PyConstant_Insert( d, "MAPX",
+ PyInt_FromLong( EXPP_CONSTR_MAPX ) );
+ PyConstant_Insert( d, "MAPY",
+ PyInt_FromLong( EXPP_CONSTR_MAPY ) );
+ PyConstant_Insert( d, "MAPZ",
+ PyInt_FromLong( EXPP_CONSTR_MAPZ ) );
+ PyConstant_Insert( d, "FROM_MINX",
+ PyInt_FromLong( EXPP_CONSTR_FROMMINX ) );
+ PyConstant_Insert( d, "FROM_MAXX",
+ PyInt_FromLong( EXPP_CONSTR_FROMMAXX ) );
+ PyConstant_Insert( d, "FROM_MINY",
+ PyInt_FromLong( EXPP_CONSTR_FROMMINY ) );
+ PyConstant_Insert( d, "FROM_MAXY",
+ PyInt_FromLong( EXPP_CONSTR_FROMMAXY ) );
+ PyConstant_Insert( d, "FROM_MINZ",
+ PyInt_FromLong( EXPP_CONSTR_FROMMINZ ) );
+ PyConstant_Insert( d, "FROM_MAXZ",
+ PyInt_FromLong( EXPP_CONSTR_FROMMAXZ ) );
+ PyConstant_Insert( d, "TO_MINX",
+ PyInt_FromLong( EXPP_CONSTR_TOMINX ) );
+ PyConstant_Insert( d, "TO_MAXX",
+ PyInt_FromLong( EXPP_CONSTR_TOMAXX ) );
+ PyConstant_Insert( d, "TO_MINY",
+ PyInt_FromLong( EXPP_CONSTR_TOMINY ) );
+ PyConstant_Insert( d, "TO_MAXY",
+ PyInt_FromLong( EXPP_CONSTR_TOMAXY ) );
+ PyConstant_Insert( d, "TO_MINZ",
+ PyInt_FromLong( EXPP_CONSTR_TOMINZ ) );
+ PyConstant_Insert( d, "TO_MAXZ",
+ PyInt_FromLong( EXPP_CONSTR_TOMAXZ ) );
+
+ PyConstant_Insert( d, "LOC",
+ PyInt_FromLong( 0 ) );
+ PyConstant_Insert( d, "ROT",
+ PyInt_FromLong( 1 ) );
+ PyConstant_Insert( d, "SCALE",
+ PyInt_FromLong( 2 ) );
+
PyConstant_Insert( d, "CONSTR_RB_TYPE",
PyInt_FromLong( EXPP_CONSTR_RB_TYPE ) );
PyConstant_Insert( d, "CONSTR_RB_BALL",
@@ -2173,6 +2703,21 @@ static PyObject *M_Constraint_SettingsDict( void )
PyInt_FromLong( EXPP_CONSTR_RB_EXTRAFZ ) );
PyConstant_Insert( d, "CONSTR_RB_FLAG",
PyInt_FromLong( EXPP_CONSTR_RB_FLAG ) );
+
+
+ PyConstant_Insert( d, "OWNERSPACE",
+ PyInt_FromLong( EXPP_CONSTR_OWNSPACE ) );
+ PyConstant_Insert( d, "TARGETSPACE",
+ PyInt_FromLong( EXPP_CONSTR_TARSPACE ) );
+
+ PyConstant_Insert( d, "SPACE_WORLD",
+ PyInt_FromLong( CONSTRAINT_SPACE_WORLD) );
+ PyConstant_Insert( d, "SPACE_LOCAL",
+ PyInt_FromLong( CONSTRAINT_SPACE_LOCAL ) );
+ PyConstant_Insert( d, "SPACE_POSE",
+ PyInt_FromLong( CONSTRAINT_SPACE_POSE) );
+ PyConstant_Insert( d, "SPACE_PARLOCAL",
+ PyInt_FromLong( CONSTRAINT_SPACE_PARLOCAL ) );
}
return S;
}
diff --git a/source/blender/python/api2_2x/CurNurb.c b/source/blender/python/api2_2x/CurNurb.c
index 9d930fee1ca..6b334c01c41 100644
--- a/source/blender/python/api2_2x/CurNurb.c
+++ b/source/blender/python/api2_2x/CurNurb.c
@@ -37,6 +37,9 @@
#include "gen_utils.h"
#include "BezTriple.h"
+/* Only for ME_SMOOTH */
+#include "DNA_meshdata_types.h"
+
/*
* forward declarations go here
*/
@@ -62,14 +65,15 @@ static int CurNurb_setPoint( BPy_CurNurb * self, int index, PyObject * ob );
static int CurNurb_length( PyInstanceObject * inst );
static PyObject *CurNurb_getIter( BPy_CurNurb * self );
static PyObject *CurNurb_iterNext( BPy_CurNurb * self );
-PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * args );
+PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * value );
static PyObject *CurNurb_isNurb( BPy_CurNurb * self );
static PyObject *CurNurb_isCyclic( BPy_CurNurb * self );
static PyObject *CurNurb_dump( BPy_CurNurb * self );
static PyObject *CurNurb_switchDirection( BPy_CurNurb * self );
static PyObject *CurNurb_recalc( BPy_CurNurb * self );
-
+static PyObject *CurNurb_getFlagBits( BPy_CurNurb * self, void *type );
+static int CurNurb_setFlagBits( BPy_CurNurb * self, PyObject *value, void *type );
char M_CurNurb_doc[] = "CurNurb";
@@ -124,7 +128,7 @@ static PyMethodDef BPy_CurNurb_methods[] = {
"( type ) - change the type of the curve (Poly: 0, Bezier: 1, NURBS: 4)"},
{"getType", ( PyCFunction ) CurNurb_getType, METH_NOARGS,
"( ) - get the type of the curve (Poly: 0, Bezier: 1, NURBS: 4)"},
- {"append", ( PyCFunction ) CurNurb_append, METH_VARARGS,
+ {"append", ( PyCFunction ) CurNurb_append, METH_O,
"( point ) - add a new point. arg is BezTriple or list of x,y,z,w floats"},
{"isNurb", ( PyCFunction ) CurNurb_isNurb, METH_NOARGS,
"( ) - boolean function tests if this spline is type nurb or bezier"},
@@ -185,7 +189,10 @@ static PyGetSetDef BPy_CurNurb_getseters[] = {
(getter)CurNurb_getKnotsV, (setter)NULL,
"The The knot vector in the V direction",
NULL},
-
+ {"smooth",
+ (getter)CurNurb_getFlagBits, (setter)CurNurb_setFlagBits,
+ "The smooth bool setting",
+ (void *)ME_SMOOTH},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -420,13 +427,20 @@ static PyObject *CurNurb_getKnotsV( BPy_CurNurb * self )
static PyObject *CurNurb_getPoints( BPy_CurNurb * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->nurb->pntsu );
+ return PyInt_FromLong( ( long ) self->nurb->pntsu );
+}
- if( attr )
- return attr;
+static PyObject *CurNurb_getFlagBits( BPy_CurNurb * self, void *type )
+{
+ return EXPP_getBitfield( (void *)&self->nurb->flag,
+ (int)type, 'h' );
+}
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "could not get number of points" );
+static int CurNurb_setFlagBits( BPy_CurNurb * self, PyObject *value,
+ void *type )
+{
+ return EXPP_setBitfield( value, (void *)&self->nurb->flag,
+ (int)type, 'h' );
}
/*
@@ -435,11 +449,9 @@ static PyObject *CurNurb_getPoints( BPy_CurNurb * self )
* arg is BezTriple or list of xyzw floats
*/
-PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * args )
+PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * value )
{
- Nurb *nurb = self->nurb;
-
- return CurNurb_appendPointToNurb( nurb, args );
+ return CurNurb_appendPointToNurb( self->nurb, value );
}
@@ -449,29 +461,22 @@ PyObject *CurNurb_append( BPy_CurNurb * self, PyObject * args )
* notice the first arg is Nurb*.
*/
-PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args )
+PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * value )
{
int i;
int size;
- PyObject *pyOb;
int npoints = nurb->pntsu;
/*
do we have a list of four floats or a BezTriple?
*/
- if( !PyArg_ParseTuple( args, "O", &pyOb ))
- return EXPP_ReturnPyObjError
- ( PyExc_RuntimeError,
- "Internal error parsing arguments" );
-
-
-
+
/* if curve is empty, adjust type depending on input type */
if (nurb->bezt==NULL && nurb->bp==NULL) {
- if (BPy_BezTriple_Check( pyOb ))
+ if (BPy_BezTriple_Check( value ))
nurb->type |= CU_BEZIER;
- else if (PySequence_Check( pyOb ))
+ else if (PySequence_Check( value ))
nurb->type |= CU_NURBS;
else
return( EXPP_ReturnPyObjError( PyExc_TypeError,
@@ -483,7 +488,7 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args )
if ((nurb->type & 7)==CU_BEZIER) {
BezTriple *tmp;
- if( !BPy_BezTriple_Check( pyOb ) )
+ if( !BPy_BezTriple_Check( value ) )
return( EXPP_ReturnPyObjError( PyExc_TypeError,
"Expected a BezTriple\n" ) );
@@ -507,11 +512,11 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args )
nurb->pntsu++;
/* add new point to end of list */
memcpy( nurb->bezt + npoints,
- BezTriple_FromPyObject( pyOb ), sizeof( BezTriple ) );
+ BezTriple_FromPyObject( value ), sizeof( BezTriple ) );
}
- else if( PySequence_Check( pyOb ) ) {
- size = PySequence_Size( pyOb );
+ else if( PySequence_Check( value ) ) {
+ size = PySequence_Size( value );
/* printf("\ndbg: got a sequence of size %d\n", size ); */
if( size == 4 || size == 5 ) {
BPoint *tmp;
@@ -537,7 +542,7 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args )
sizeof( BPoint ) );
for( i = 0; i < 4; ++i ) {
- PyObject *item = PySequence_GetItem( pyOb, i );
+ PyObject *item = PySequence_GetItem( value, i );
if (item == NULL)
return NULL;
@@ -548,7 +553,7 @@ PyObject *CurNurb_appendPointToNurb( Nurb * nurb, PyObject * args )
}
if (size == 5) {
- PyObject *item = PySequence_GetItem( pyOb, i );
+ PyObject *item = PySequence_GetItem( value, i );
if (item == NULL)
return NULL;
@@ -771,9 +776,9 @@ static PyObject *CurNurb_isNurb( BPy_CurNurb * self )
*/
if( self->nurb->bp ) {
- return EXPP_incr_ret_True();
+ Py_RETURN_TRUE;
} else {
- return EXPP_incr_ret_False();
+ Py_RETURN_FALSE;
}
}
@@ -787,9 +792,9 @@ static PyObject *CurNurb_isCyclic( BPy_CurNurb * self )
/* supposing that the flagu is always set */
if( self->nurb->flagu & CU_CYCLIC ) {
- return EXPP_incr_ret_True();
+ Py_RETURN_TRUE;
} else {
- return EXPP_incr_ret_False();
+ Py_RETURN_FALSE;
}
}
diff --git a/source/blender/python/api2_2x/Curve.c b/source/blender/python/api2_2x/Curve.c
index 109a4572387..adf7c39b45c 100644
--- a/source/blender/python/api2_2x/Curve.c
+++ b/source/blender/python/api2_2x/Curve.c
@@ -1,5 +1,6 @@
/*
* $Id$
+ *
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -31,6 +32,7 @@
#include "Curve.h" /*This must come first*/
+#include "BLI_blenlib.h"
#include "BKE_main.h"
#include "BKE_displist.h"
#include "BKE_global.h"
@@ -122,6 +124,7 @@ static PyObject *Curve_getIter( BPy_Curve * self );
static PyObject *Curve_iterNext( BPy_Curve * self );
PyObject *Curve_getNurb( BPy_Curve * self, int n );
+static int Curve_setNurb( BPy_Curve * self, int n, PyObject * value );
static int Curve_length( PyInstanceObject * inst );
@@ -138,13 +141,7 @@ struct chartrans *text_to_curve( Object * ob, int mode );
PyObject *Curve_getName( BPy_Curve * self )
{
- PyObject *attr = PyString_FromString( self->curve->id.name + 2 );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.name attribute" );
+ return PyString_FromString( self->curve->id.name + 2 );
}
static int Curve_newsetName( BPy_Curve * self, PyObject * args )
@@ -164,13 +161,7 @@ static int Curve_newsetName( BPy_Curve * self, PyObject * args )
static PyObject *Curve_getPathLen( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->pathlen );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.pathlen attribute" );
+ return PyInt_FromLong( ( long ) self->curve->pathlen );
}
@@ -191,25 +182,13 @@ static int Curve_newsetPathLen( BPy_Curve * self, PyObject * args )
static PyObject *Curve_getTotcol( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->totcol );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.totcol attribute" );
+ return PyInt_FromLong( ( long ) self->curve->totcol );
}
PyObject *Curve_getMode( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->flag );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.flag attribute" );
+ return PyInt_FromLong( ( long ) self->curve->flag );
}
@@ -230,13 +209,7 @@ static int Curve_newsetMode( BPy_Curve * self, PyObject * args )
PyObject *Curve_getBevresol( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->bevresol );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.bevresol attribute" );
+ return PyInt_FromLong( ( long ) self->curve->bevresol );
}
static int Curve_newsetBevresol( BPy_Curve * self, PyObject * args )
@@ -263,13 +236,7 @@ static int Curve_newsetBevresol( BPy_Curve * self, PyObject * args )
PyObject *Curve_getResolu( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->resolu );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.resolu attribute" );
+ return PyInt_FromLong( ( long ) self->curve->resolu );
}
@@ -301,13 +268,7 @@ static int Curve_newsetResolu( BPy_Curve * self, PyObject * args )
PyObject *Curve_getResolv( BPy_Curve * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->curve->resolv );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.resolv attribute" );
+ return PyInt_FromLong( ( long ) self->curve->resolv );
}
static int Curve_newsetResolv( BPy_Curve * self, PyObject * args )
@@ -333,13 +294,7 @@ static int Curve_newsetResolv( BPy_Curve * self, PyObject * args )
PyObject *Curve_getWidth( BPy_Curve * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->curve->width );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.width attribute" );
+ return PyFloat_FromDouble( ( double ) self->curve->width );
}
@@ -367,13 +322,7 @@ static int Curve_newsetWidth( BPy_Curve * self, PyObject * args )
PyObject *Curve_getExt1( BPy_Curve * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->curve->ext1 );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.ext1 attribute" );
+ return PyFloat_FromDouble( ( double ) self->curve->ext1 );
}
@@ -390,9 +339,9 @@ static int Curve_newsetExt1( BPy_Curve * self, PyObject * args )
value = (float)PyFloat_AS_DOUBLE( num );
Py_DECREF( num );
- if(value > 5.0f || value < 0.0f)
+ if(value > 100.0f || value < 0.0f)
return EXPP_ReturnIntError( PyExc_ValueError,
- "acceptable values are between 0.0 and 5.0" );
+ "acceptable values are between 0.0 and 100.0" );
self->curve->ext1 = value;
return 0;
@@ -400,13 +349,7 @@ static int Curve_newsetExt1( BPy_Curve * self, PyObject * args )
PyObject *Curve_getExt2( BPy_Curve * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->curve->ext2 );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.ext2 attribute" );
+ return PyFloat_FromDouble( ( double ) self->curve->ext2 );
}
@@ -535,14 +478,8 @@ static PyObject *Curve_getControlPoint( BPy_Curve * self, PyObject * args )
static PyObject *Curve_getLoc( BPy_Curve * self )
{
- PyObject *attr = Py_BuildValue( "[f,f,f]", self->curve->loc[0],
+ return Py_BuildValue( "[f,f,f]", self->curve->loc[0],
self->curve->loc[1], self->curve->loc[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.loc attribute" );
}
static int Curve_newsetLoc( BPy_Curve * self, PyObject * args )
@@ -573,14 +510,8 @@ TypeError:
static PyObject *Curve_getRot( BPy_Curve * self )
{
- PyObject *attr = Py_BuildValue( "[f,f,f]", self->curve->rot[0],
+ return Py_BuildValue( "[f,f,f]", self->curve->rot[0],
self->curve->rot[1], self->curve->rot[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.rot attribute" );
}
static int Curve_newsetRot( BPy_Curve * self, PyObject * args )
@@ -611,14 +542,8 @@ TypeError:
static PyObject *Curve_getSize( BPy_Curve * self )
{
- PyObject *attr = Py_BuildValue( "[f,f,f]", self->curve->size[0],
+ return Py_BuildValue( "[f,f,f]", self->curve->size[0],
self->curve->size[1], self->curve->size[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Curve.size attribute" );
}
static int Curve_newsetSize( BPy_Curve * self, PyObject * args )
@@ -845,8 +770,6 @@ static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
int i;
int nurb_num; /* index of curve we append to */
PyObject *coord_args; /* coords for new point */
- PyObject *retval = NULL;
- PyObject *valtuple;
Nurb *nurb = self->curve->nurb.first; /* first nurb in Curve */
/* fixme - need to malloc new Nurb */
@@ -868,14 +791,7 @@ static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"curve index out of range" );
}
-
- /* rebuild our arg tuple for appendPointToNurb() */
- valtuple = Py_BuildValue( "(O)", coord_args );
-
- retval = CurNurb_appendPointToNurb( nurb, valtuple );
- Py_DECREF( valtuple );
-
- return retval;
+ return CurNurb_appendPointToNurb( nurb, coord_args );
}
@@ -885,29 +801,16 @@ static PyObject *Curve_appendPoint( BPy_Curve * self, PyObject * args )
returns a refernce to the newly created nurb.
*****/
-static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * args )
+static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * value )
{
- Nurb *nurb_ptr = self->curve->nurb.first;
- Nurb **pptr = ( Nurb ** ) & ( self->curve->nurb.first );
Nurb *new_nurb;
-
-
- /* walk to end of nurblist */
- if( nurb_ptr ) {
- while( nurb_ptr->next ) {
- nurb_ptr = nurb_ptr->next;
- }
- pptr = &nurb_ptr->next;
- }
-
/* malloc new nurb */
new_nurb = ( Nurb * ) MEM_callocN( sizeof( Nurb ), "appendNurb" );
if( !new_nurb )
return EXPP_ReturnPyObjError
( PyExc_MemoryError, "unable to malloc Nurb" );
-
- if( CurNurb_appendPointToNurb( new_nurb, args ) ) {
- *pptr = new_nurb;
+
+ if( CurNurb_appendPointToNurb( new_nurb, value ) ) {
new_nurb->resolu = self->curve->resolu;
new_nurb->resolv = self->curve->resolv;
new_nurb->hide = 0;
@@ -918,9 +821,9 @@ static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * args )
new_nurb->type = CU_BEZIER;
new_nurb->bezt->h1 = HD_ALIGN;
new_nurb->bezt->h2 = HD_ALIGN;
- new_nurb->bezt->f1 = 1;
- new_nurb->bezt->f2 = 1;
- new_nurb->bezt->f3 = 1;
+ new_nurb->bezt->f1 = SELECT;
+ new_nurb->bezt->f2 = SELECT;
+ new_nurb->bezt->f3 = SELECT;
new_nurb->bezt->hide = 0;
/* calchandlesNurb( new_nurb ); */
} else { /* set up bp */
@@ -934,6 +837,7 @@ static PyObject *Curve_appendNurb( BPy_Curve * self, PyObject * args )
new_nurb->knotsu = 0;
/*makenots( new_nurb, 1, new_nurb->flagu >> 1); */
}
+ BLI_addtail( &self->curve->nurb, new_nurb);
} else {
freeNurb( new_nurb );
@@ -1208,6 +1112,42 @@ PyObject *Curve_getNurb( BPy_Curve * self, int n )
}
+/*
+ * Curve_setNurb
+ * In this case only remove the item, we could allow adding later.
+ */
+static int Curve_setNurb( BPy_Curve * self, int n, PyObject * value )
+{
+ Nurb *pNurb;
+ int i;
+
+ /* bail if index < 0 */
+ if( n < 0 )
+ return ( EXPP_ReturnIntError( PyExc_IndexError,
+ "index less than 0" ) );
+ /* bail if no Nurbs in Curve */
+ if( self->curve->nurb.first == 0 )
+ return ( EXPP_ReturnIntError( PyExc_IndexError,
+ "no Nurbs in this Curve" ) );
+ /* set pointer to nth Nurb */
+ for( pNurb = self->curve->nurb.first, i = 0;
+ pNurb != 0 && i < n; pNurb = pNurb->next, ++i )
+ /**/;
+
+ if( !pNurb ) /* we came to the end of the list */
+ return ( EXPP_ReturnIntError( PyExc_IndexError,
+ "index out of range" ) );
+
+ if (value) {
+ return ( EXPP_ReturnIntError( PyExc_RuntimeError,
+ "assigning curves is not yet supported" ) );
+ } else {
+ BLI_remlink(&self->curve->nurb, pNurb);
+ freeNurb(pNurb);
+ }
+ return 0;
+}
+
/*****************************************************************************/
/* Function: Curve_compare */
/* Description: This compares 2 curve python types, == or != only. */
@@ -1493,7 +1433,7 @@ Sets a control point "},
"(nothing or integer) - returns the number of points of the specified curve"},
{"appendPoint", ( PyCFunction ) Curve_appendPoint, METH_VARARGS,
"( int numcurve, list of coordinates) - adds a new point to end of curve"},
- {"appendNurb", ( PyCFunction ) Curve_appendNurb, METH_VARARGS,
+ {"appendNurb", ( PyCFunction ) Curve_appendNurb, METH_O,
"( new_nurb ) - adds a new nurb to the Curve"},
{"update", ( PyCFunction ) Curve_update, METH_NOARGS,
"( ) - updates display lists after changes to Curve"},
@@ -1527,7 +1467,7 @@ static PySequenceMethods Curve_as_sequence = {
( intargfunc ) 0, /* sq_repeat */
( intargfunc ) Curve_getNurb, /* sq_item */
( intintargfunc ) 0, /* sq_slice */
- 0, /* sq_ass_item */
+ ( intobjargproc ) Curve_setNurb, /* sq_ass_item - only so you can do del curve[i] */
0, /* sq_ass_slice */
( objobjproc ) 0, /* sq_contains */
0,
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index ede780294ef..a4bbeba65ac 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -52,7 +52,7 @@
#include "BIF_space.h"
#include "BIF_interface.h"
#include "BIF_toolbox.h"
-#include "BPI_script.h" /* script struct */
+#include "DNA_space_types.h" /* script struct */
#include "Image.h" /* for accessing Blender.Image objects */
#include "IMB_imbuf_types.h" /* for the IB_rect define */
#include "interface.h"
@@ -103,10 +103,10 @@ static void exec_callback( SpaceScript * sc, PyObject * callback,
static void spacescript_do_pywin_buttons( SpaceScript * sc,
unsigned short event );
-static PyObject *Method_Exit( PyObject * self, PyObject * args );
+static PyObject *Method_Exit( PyObject * self );
static PyObject *Method_Register( PyObject * self, PyObject * args );
static PyObject *Method_Redraw( PyObject * self, PyObject * args );
-static PyObject *Method_Draw( PyObject * self, PyObject * args );
+static PyObject *Method_Draw( PyObject * self );
static PyObject *Method_Create( PyObject * self, PyObject * args );
static PyObject *Method_UIBlock( PyObject * self, PyObject * args );
@@ -124,6 +124,7 @@ static PyObject *Method_Text( PyObject * self, PyObject * args );
static PyObject *Method_Label( PyObject * self, PyObject * args );
/* by Campbell: */
static PyObject *Method_PupMenu( PyObject * self, PyObject * args );
+static PyObject *Method_PupTreeMenu( PyObject * self, PyObject * args );
static PyObject *Method_PupIntInput( PyObject * self, PyObject * args );
static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args );
static PyObject *Method_PupStrInput( PyObject * self, PyObject * args );
@@ -135,6 +136,7 @@ static PyObject *Method_Image( PyObject * self, PyObject * args);
static PyObject *Method_PupBlock( PyObject * self, PyObject * args );
static uiBlock *Get_uiBlock( void );
+
static void py_slider_update( void *butv, void *data2_unused );
/* hack to get 1 block for the UIBlock, only ever 1 at a time */
@@ -282,12 +284,12 @@ new String button\n\n\
static char Method_GetStringWidth_doc[] =
"(text, font = 'normal') - Return the width in pixels of the given string\n\
-(font) The font size: 'normal' (default), 'small' or 'tiny'.";
+(font) The font size: 'large','normal' (default), 'normalfix', 'small' or 'tiny'.";
static char Method_Text_doc[] =
"(text, font = 'normal') - Draw text onscreen\n\n\
(text) The text to draw\n\
-(font) The font size: 'normal' (default), 'small' or 'tiny'.\n\n\
+(font) The font size: 'large','normal' (default), 'normalfix', 'small' or 'tiny'.\n\n\
This function returns the width of the drawn string.";
static char Method_Label_doc[] =
@@ -307,6 +309,9 @@ Valid format codes are\n\
%xN - The option should set the integer N in the button value.\n\n\
Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ...";
+static char Method_PupTreeMenu_doc[] =
+"each item in the menu list should be - (str, event), separator - None or submenu - (str, [...]).";
+
static char Method_PupIntInput_doc[] =
"(text, default, min, max) - Display an int pop-up input.\n\
(text) - text string to display on the button;\n\
@@ -355,47 +360,41 @@ Warning: On cancel, the value objects are brought back to there previous values,
static char Method_Exit_doc[] = "() - Exit the windowing interface";
-/*
-* here we engage in some macro trickery to define the PyMethodDef table
+/*This is needed for button callbacks. Any button that uses a callback gets added to this list.
+ On the C side of drawing begin, this list should be cleared.
+ Each entry is a tuple of the form (button, callback py object)
*/
-
-#define _MethodDef(func, prefix) \
- {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
-
-/* So that _MethodDef(delete, Scene) expands to:
- * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
-
-#undef MethodDef
-#define MethodDef(func) _MethodDef(func, Method)
+PyObject *M_Button_List = NULL;
static struct PyMethodDef Draw_methods[] = {
- MethodDef( Create ),
- MethodDef( UIBlock ),
- MethodDef( Button ),
- MethodDef( Toggle ),
- MethodDef( Menu ),
- MethodDef( Slider ),
- MethodDef( Scrollbar ),
- MethodDef( ColorPicker ),
- MethodDef( Normal ),
- MethodDef( Number ),
- MethodDef( String ),
- MethodDef( GetStringWidth ),
- MethodDef( Text ),
- MethodDef( Label ),
- MethodDef( PupMenu ),
- MethodDef( PupIntInput ),
- MethodDef( PupFloatInput ),
- MethodDef( PupStrInput ),
- MethodDef( PupBlock ),
- MethodDef( Image ),
- MethodDef( Exit ),
- MethodDef( Redraw ),
- MethodDef( Draw ),
- MethodDef( Register ),
- {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
- MethodDef( BeginAlign ),
- MethodDef( EndAlign),
+ {"Create", (PyCFunction)Method_Create, METH_VARARGS, Method_Create_doc},
+ {"UIBlock", (PyCFunction)Method_UIBlock, METH_VARARGS, Method_UIBlock_doc},
+ {"Button", (PyCFunction)Method_Button, METH_VARARGS, Method_Button_doc},
+ {"Toggle", (PyCFunction)Method_Toggle, METH_VARARGS, Method_Toggle_doc},
+ {"Menu", (PyCFunction)Method_Menu, METH_VARARGS, Method_Menu_doc},
+ {"Slider", (PyCFunction)Method_Slider, METH_VARARGS, Method_Slider_doc},
+ {"Scrollbar", (PyCFunction)Method_Scrollbar, METH_VARARGS, Method_Scrollbar_doc},
+ {"ColorPicker", (PyCFunction)Method_ColorPicker, METH_VARARGS, Method_ColorPicker_doc},
+ {"Normal", (PyCFunction)Method_Normal, METH_VARARGS, Method_Normal_doc},
+ {"Number", (PyCFunction)Method_Number, METH_VARARGS, Method_Number_doc},
+ {"String", (PyCFunction)Method_String, METH_VARARGS, Method_String_doc},
+ {"GetStringWidth", (PyCFunction)Method_GetStringWidth, METH_VARARGS, Method_GetStringWidth_doc},
+ {"Text", (PyCFunction)Method_Text, METH_VARARGS, Method_Text_doc},
+ {"Label", (PyCFunction)Method_Label, METH_VARARGS, Method_Label_doc},
+ {"PupMenu", (PyCFunction)Method_PupMenu, METH_VARARGS, Method_PupMenu_doc},
+ {"PupTreeMenu", (PyCFunction)Method_PupTreeMenu, METH_VARARGS, Method_PupTreeMenu_doc},
+ {"PupIntInput", (PyCFunction)Method_PupIntInput, METH_VARARGS, Method_PupIntInput_doc},
+ {"PupFloatInput", (PyCFunction)Method_PupFloatInput, METH_VARARGS, Method_PupFloatInput_doc},
+ {"PupStrInput", (PyCFunction)Method_PupStrInput, METH_VARARGS, Method_PupStrInput_doc},
+ {"PupBlock", (PyCFunction)Method_PupBlock, METH_VARARGS, Method_PupBlock_doc},
+ {"Image", (PyCFunction)Method_Image, METH_VARARGS, Method_Image_doc},
+ {"Exit", (PyCFunction)Method_Exit, METH_NOARGS, Method_Exit_doc},
+ {"Redraw", (PyCFunction)Method_Redraw, METH_VARARGS, Method_Redraw_doc},
+ {"Draw", (PyCFunction)Method_Draw, METH_NOARGS, Method_Draw_doc},
+ {"Register", (PyCFunction)Method_Register, METH_VARARGS, Method_Register_doc},
+ {"PushButton", (PyCFunction)Method_Button, METH_VARARGS, Method_Button_doc},
+ {"BeginAlign", (PyCFunction)Method_BeginAlign, METH_VARARGS, Method_BeginAlign_doc},
+ {"EndAlign", (PyCFunction)Method_EndAlign, METH_VARARGS, Method_EndAlign_doc},
{NULL, NULL, 0, NULL}
};
@@ -581,11 +580,15 @@ static PyObject *Button_repr( PyObject * self )
static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
{
+ PyObject *ret, *valA=NULL, *valB=NULL;
if (ButtonObject_Check(objectA))
- objectA = Button_getattr( objectA, "val" );
+ objectA = valA = Button_getattr( objectA, "val" );
if (ButtonObject_Check(objectB))
- objectB = Button_getattr( objectB, "val" );
- return PyObject_RichCompare(objectA, objectB, comparison_type);
+ objectB = valB = Button_getattr( objectB, "val" );
+ ret = PyObject_RichCompare(objectA, objectB, comparison_type);
+ Py_XDECREF(valA); /* Button_getattr created with 1 ref, we dont care about them now */
+ Py_XDECREF(valB);
+ return ret;
}
@@ -594,7 +597,9 @@ static Button *newbutton( void )
Button *but = NULL;
but = ( Button * ) PyObject_NEW( Button, &Button_Type );
-
+ but->tooltip[0] = 0; /*NULL-terminate tooltip string*/
+ but->tooltip[255] = 0; /*necassary to insure we always have a NULL-terminated string, as
+ according to the docs strncpy doesn't do this for us.*/
return but;
}
@@ -616,6 +621,10 @@ static void exit_pydraw( SpaceScript * sc, short err )
scrarea_queue_redraw( sc->area );
}
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
+ sc->but_refs = NULL;
+
Py_XDECREF( ( PyObject * ) script->py_draw );
Py_XDECREF( ( PyObject * ) script->py_event );
Py_XDECREF( ( PyObject * ) script->py_button );
@@ -663,12 +672,20 @@ void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
uiBlock *block;
char butblock[20];
Script *script = sc->script;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
sprintf( butblock, "win %d", curarea->win );
block = uiNewBlock( &curarea->uiblocks, butblock, UI_EMBOSSX,
UI_HELV, curarea->win );
if( script->py_draw ) {
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
+ }
+ sc->but_refs = PyList_New(0);
+ BPy_Set_DrawButtonsList(sc->but_refs);
+
glPushAttrib( GL_ALL_ATTRIB_BITS );
exec_callback( sc, script->py_draw, Py_BuildValue( "()" ) );
glPopAttrib( );
@@ -680,6 +697,8 @@ void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
uiDrawBlock( block );
curarea->win_swap = WIN_BACK_OK;
+
+ PyGILState_Release(gilstate);
}
static void spacescript_do_pywin_buttons( SpaceScript * sc,
@@ -693,6 +712,8 @@ static void spacescript_do_pywin_buttons( SpaceScript * sc,
void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
short val, char ascii )
{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
if( event == QKEY && G.qual & ( LR_ALTKEY | LR_CTRLKEY ) ) {
/* finish script: user pressed ALT+Q or CONTROL+Q */
Script *script = sc->script;
@@ -701,18 +722,23 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
script->flags &= ~SCRIPT_GUI; /* we're done with this script */
+ PyGILState_Release(gilstate);
+
return;
}
if (val) {
- if (uiDoBlocks( &curarea->uiblocks, event ) != UI_NOTHING) event = 0;
+ if (uiDoBlocks( &curarea->uiblocks, event, 1 ) != UI_NOTHING) event = 0;
if (event == UI_BUT_EVENT) {
/* check that event is in free range for script button events;
* read the comment before check_button_event() below to understand */
if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
+
+ PyGILState_Release(gilstate);
+
return;
}
}
@@ -733,14 +759,16 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
EXPP_dict_set_item_str(g_blenderdict, "event",
PyString_FromString(""));
}
+
+ PyGILState_Release(gilstate);
}
static void exec_but_callback(void *pyobj, void *data)
{
PyObject *result;
- PyObject * pyvalue;
+ PyObject *pyvalue = NULL;
uiBut *but = (uiBut *)data;
- PyObject *arg = PyTuple_New( 2 );
+ PyObject *arg;
PyObject *callback = (PyObject *)pyobj;
double value = ui_get_but_val(but);
@@ -795,6 +823,7 @@ static void exec_but_callback(void *pyobj, void *data)
printf("Error, no button type matched.");
}
+ arg = PyTuple_New( 2 );
if (uiblock==NULL)
PyTuple_SetItem( arg, 0, PyInt_FromLong(but->retval - EXPP_BUTTON_EVENTS_OFFSET) );
else
@@ -803,6 +832,8 @@ static void exec_but_callback(void *pyobj, void *data)
PyTuple_SetItem( arg, 1, pyvalue );
result = PyObject_CallObject( callback, arg );
+ Py_DECREF(arg);
+
if (!result) {
Py_DECREF(pyvalue);
PyErr_Print( );
@@ -811,13 +842,59 @@ static void exec_but_callback(void *pyobj, void *data)
Py_XDECREF( result );
}
-static void set_pycallback(uiBut *ubut, PyObject *callback)
+/*note that this function populates the drawbutton ref lists.*/
+static void set_pycallback(uiBut *ubut, PyObject *callback, Button *but)
+{
+ PyObject *tuple;
+ if (!callback || !PyCallable_Check(callback)) {
+ if (M_Button_List && but) {
+ PyList_Append(M_Button_List, (PyObject*)but);
+ }
+ return;
+ }
+
+ if (M_Button_List) {
+ if (but) tuple = PyTuple_New(2);
+ else tuple = PyTuple_New(1);
+
+ /*the tuple API mandates this*/
+ Py_XINCREF(callback);
+ Py_XINCREF(but); /*this checks for NULL*/
+
+ PyTuple_SET_ITEM(tuple, 0, callback);
+ if (but) PyTuple_SET_ITEM(tuple, 1, (PyObject*)but);
+
+ PyList_Append(M_Button_List, tuple);
+ Py_DECREF(tuple); /*we have to do this to aovid double references.*/
+
+ uiButSetFunc(ubut, exec_but_callback, callback, ubut);
+ }
+}
+
+void BPy_Set_DrawButtonsList(void *list)
{
- if (!callback || !PyCallable_Check(callback)) return;
- uiButSetFunc(ubut, exec_but_callback, callback, ubut);
+ M_Button_List = list;
}
-static PyObject *Method_Exit( PyObject * self, PyObject * args )
+/*this MUST be called after doing UI stuff.*/
+void BPy_Free_DrawButtonsList(void)
+{
+ /*Clear the list.*/
+ if (M_Button_List) {
+ PyGILState_STATE gilstate = {0};
+ int py_is_on = Py_IsInitialized();
+
+ if (py_is_on) gilstate = PyGILState_Ensure();
+
+ PyList_SetSlice(M_Button_List, 0, PyList_Size(M_Button_List), NULL);
+ Py_DECREF(M_Button_List);
+ M_Button_List = NULL;
+
+ if (py_is_on) PyGILState_Release(gilstate);
+ }
+}
+
+static PyObject *Method_Exit( PyObject * self )
{
SpaceScript *sc;
Script *script;
@@ -829,16 +906,14 @@ static PyObject *Method_Exit( PyObject * self, PyObject * args )
else
Py_RETURN_NONE;
- if( !PyArg_ParseTuple( args, "" ) )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected empty argument list" );
-
exit_pydraw( sc, 0 );
script = sc->script;
/* remove our lock to the current namespace */
script->flags &= ~SCRIPT_GUI;
+ script->scriptname[0] = '\0';
+ script->scriptarg[0] = '\0';
Py_RETURN_NONE;
}
@@ -947,7 +1022,7 @@ static PyObject *Method_Redraw( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Method_Draw( PyObject * self, PyObject * args )
+static PyObject *Method_Draw( PyObject * self )
{
/*@ If forced drawing is disable queue a redraw event instead */
if( EXPP_disable_force_draw ) {
@@ -955,10 +1030,6 @@ static PyObject *Method_Draw( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
- if( !PyArg_ParseTuple( args, "" ) )
- return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "expected empty argument list" );
-
scrarea_do_windraw( curarea );
screen_swapbuffers( );
@@ -973,21 +1044,24 @@ static PyObject *Method_Create( PyObject * self, PyObject * args )
char *newstr;
but = newbutton();
-
+ /* If this function dosnt sucseed this will need to be deallocated,
+ * make sure the type is NOT BSTRING_TYPE before deallocing -1 is ok.
+ * so we dont dealloc with an uninitialized value wich would be bad! */
if ( PyArg_ParseTuple( args, "fff", but->val.asvec, but->val.asvec+1, but->val.asvec+2 ) ) {
but->type = BVECTOR_TYPE;
- }
- else if ( PyArg_ParseTuple( args, "O!", &PyFloat_Type, &val ) ) {
+
+ } else if ( PyArg_ParseTuple( args, "O!", &PyFloat_Type, &val ) ) {
but->val.asfloat = (float)PyFloat_AS_DOUBLE(val);
but->type = BFLOAT_TYPE;
- }
- else if ( PyArg_ParseTuple( args, "O!", &PyInt_Type, &val ) ) {
+
+ } else if ( PyArg_ParseTuple( args, "O!", &PyInt_Type, &val ) ) {
but->val.asint = (int)PyInt_AS_LONG(val);
but->type = BINT_TYPE;
- }
- else if ( PyArg_ParseTuple( args, "s#", &newstr, &but->slen ) ) {
+
+ } else if ( PyArg_ParseTuple( args, "s#", &newstr, &but->slen ) ) {
if (but->slen + 1 > UI_MAX_DRAW_STR) {
- PyObject_DEL( (PyObject *) but );
+ but->type = -1;
+ Py_DECREF((PyObject *)but); /* will remove */
but = NULL;
PyErr_SetString( PyExc_TypeError, "string is longer then 399 chars");
} else {
@@ -995,9 +1069,10 @@ static PyObject *Method_Create( PyObject * self, PyObject * args )
but->val.asstr = MEM_mallocN( but->slen + 1, "button string" );
BLI_strncpy( but->val.asstr, newstr, but->slen+1 );
}
- }
- else {
- PyObject_DEL( (PyObject *) but );
+
+ } else {
+ but->type = -1;
+ Py_DECREF((PyObject *)but); /* will remove */
but = NULL;
PyErr_SetString( PyExc_TypeError, "expected string, float, int or 3-float tuple argument" );
}
@@ -1009,6 +1084,7 @@ static PyObject *Method_Create( PyObject * self, PyObject * args )
return (PyObject*) but;
}
+
static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
{
PyObject *val = NULL;
@@ -1022,27 +1098,53 @@ static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
if (uiblock)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"cannot run more then 1 UIBlock at a time" );
+
+ BPy_Set_DrawButtonsList(PyList_New(0));
mywinset(G.curscreen->mainwin);
uiblock= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
uiBlockSetFlag(uiblock, UI_BLOCK_LOOP|UI_BLOCK_REDRAW);
result = PyObject_CallObject( val, Py_BuildValue( "()" ) );
-
+
if (!result) {
PyErr_Print( );
error( "Python script error: check console" );
} else {
+ /* copied from do_clever_numbuts in toolbox.c */
+
+ /* Clear all events so tooltips work, this is not ideal and
+ only needed because calls from the menu still have some events
+ left over when do_clever_numbuts is called.
+ Calls from keyshortcuts do not have this problem.*/
+ ScrArea *sa;
+ BWinEvent temp_bevt;
+ for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ if(sa->win) {
+ while( bwin_qread( sa->win, &temp_bevt ) ) {}
+ }
+ if(sa->headwin) {
+ while( bwin_qread( sa->headwin, &temp_bevt ) ) {}
+ }
+ }
+ /* Done clearing events */
+
uiBoundsBlock(uiblock, 5);
- uiDoBlocks(&listb, 0);
+ uiDoBlocks(&listb, 0, 1);
}
uiFreeBlocks(&listb);
uiblock = NULL;
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
Py_XDECREF( result );
Py_RETURN_NONE;
}
+void Set_uiBlock(uiBlock *block)
+{
+ uiblock = block;
+}
+
static uiBlock *Get_uiBlock( void )
{
char butblock[32];
@@ -1111,7 +1213,7 @@ static PyObject *Method_Button( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefBut( block, BUT, event, name, (short)x, (short)y, (short)w, (short)h, 0, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, NULL);
}
Py_RETURN_NONE;
}
@@ -1135,12 +1237,13 @@ static PyObject *Method_Menu( PyObject * self, PyObject * args )
but = newbutton( );
but->type = BINT_TYPE;
but->val.asint = def;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefButI( block, MENU, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ &but->val.asint, 0, 0, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -1164,12 +1267,13 @@ static PyObject *Method_Toggle( PyObject * self, PyObject * args )
but = newbutton( );
but->type = BINT_TYPE;
but->val.asint = def;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefButI( block, TOG, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ &but->val.asint, 0, 0, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -1197,13 +1301,13 @@ static void py_slider_update( void *butv, void *data2_unused )
disable_where_script( 1 );
spacescript_do_pywin_buttons( curarea->spacedata.first,
- (unsigned short)uiButGetRetVal( but ) );
+ (unsigned short)uiButGetRetVal( but ) - EXPP_BUTTON_EVENTS_OFFSET );
/* XXX useless right now, investigate better before a bcon 5 */
ret = M_Window_Redraw( 0, ref );
- Py_DECREF(ref);
- if (ret) { Py_DECREF(ret); }
+ Py_XDECREF(ref);
+ Py_XDECREF(ret);
disable_where_script( 0 );
@@ -1227,6 +1331,9 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
"expected a string, five ints, three PyObjects\n\
and optionally int, string and callback arguments" );
+ if(realtime && uiblock)
+ realtime = 0; /* realtime dosnt work with UIBlock */
+
UI_METHOD_ERRORCHECK;
but = newbutton( );
@@ -1240,17 +1347,18 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
but->type = BFLOAT_TYPE;
but->val.asfloat = ini;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
ubut = uiDefButF( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
(short)h, &but->val.asfloat, min, max, 0, 0,
- tip );
+ but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
else
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, but);
}
} else {
int ini, min, max;
@@ -1261,17 +1369,18 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
but->type = BINT_TYPE;
but->val.asint = ini;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
ubut = uiDefButI( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
(short)h, &but->val.asint, (float)min, (float)max, 0, 0,
- tip );
+ but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
else
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, but);
}
}
return ( PyObject * ) but;
@@ -1304,7 +1413,8 @@ another int and string as arguments" );
"button event argument must be in the range [0, 16382]");
but = newbutton( );
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
if( PyFloat_Check( inio ) )
but->type = BFLOAT_TYPE;
else
@@ -1320,13 +1430,13 @@ another int and string as arguments" );
if( but->type == BFLOAT_TYPE ) {
but->val.asfloat = ini;
ubut = uiDefButF( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
- &but->val.asfloat, min, max, 0, 0, tip );
+ &but->val.asfloat, min, max, 0, 0, but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
} else {
but->val.asint = (int)ini;
ubut = uiDefButI( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, min, max, 0, 0, tip );
+ &but->val.asint, min, max, 0, 0, but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
}
@@ -1370,12 +1480,13 @@ static PyObject *Method_ColorPicker( PyObject * self, PyObject * args )
but->val.asvec[0] = col[0];
but->val.asvec[1] = col[1];
but->val.asvec[2] = col[2];
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
- ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, tip);
- set_pycallback(ubut, callback);
+ ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, but->tooltip);
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
@@ -1409,7 +1520,8 @@ static PyObject *Method_Normal( PyObject * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
but = newbutton();
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
but->type = BVECTOR_TYPE;
but->val.asvec[0] = nor[0];
but->val.asvec[1] = nor[1];
@@ -1418,8 +1530,8 @@ static PyObject *Method_Normal( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
- ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, tip);
- set_pycallback(ubut, callback);
+ ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, but->tooltip);
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
@@ -1445,6 +1557,7 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
UI_METHOD_ERRORCHECK;
but = newbutton( );
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
block = Get_uiBlock( );
if( PyFloat_Check( inio ) ) {
@@ -1458,18 +1571,18 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
if (!range) range= 1.0f; /* avoid any odd errors */
/* set the precission to display*/
- if (range>=100.0f) precission=1.0f;
- else if (range>=10.0f) precission=2.0f;
- else if (range>=1.0f) precission=3.0f;
- else precission=4.0f;
-
+ if (range>=1000.0f) precission=1.0f;
+ else if (range>=100.0f) precission=2.0f;
+ else if (range>=10.0f) precission=3.0f;
+ else precission=4.0f;
+
but->type = BFLOAT_TYPE;
but->val.asfloat = ini;
if( block )
ubut= uiDefButF( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asfloat, min, max, 10*range, precission, tip );
+ &but->val.asfloat, min, max, 10*range, precission, but->tooltip );
} else {
int ini, min, max;
@@ -1482,10 +1595,10 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
if( block )
ubut= uiDefButI( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, (float)min, (float)max, 0, 0, tip );
+ &but->val.asint, (float)min, (float)max, 0, 0, but->tooltip );
}
- if (ubut) set_pycallback(ubut, callback);
+ if (ubut) set_pycallback(ubut, callback, but);
return ( PyObject * ) but;
}
@@ -1514,11 +1627,12 @@ static PyObject *Method_String( PyObject * self, PyObject * args )
real_len = strlen(newstr);
if (real_len > len) real_len = len;
-
+
but = newbutton( );
but->type = BSTRING_TYPE;
but->slen = len;
but->val.asstr = MEM_mallocN( len + 1, "pybutton str" );
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
BLI_strncpy( but->val.asstr, newstr, len + 1); /* adds '\0' */
but->val.asstr[real_len] = '\0';
@@ -1529,8 +1643,8 @@ static PyObject *Method_String( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefBut( block, TEX, event, info_str, (short)x, (short)y, (short)w, (short)h,
- but->val.asstr, 0, (float)len, 0, 0, tip );
- set_pycallback(ubut, callback);
+ but->val.asstr, 0, (float)len, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -1548,6 +1662,8 @@ static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args )
if( !strcmp( font_str, "normal" ) )
font = ( &G )->font;
+ else if( !strcmp( font_str, "normalfix" ) )
+ font = BMF_GetFont(BMF_kScreen12);
else if( !strcmp( font_str, "large" ) )
font = BMF_GetFont(BMF_kScreen15);
else if( !strcmp( font_str, "small" ) )
@@ -1556,7 +1672,7 @@ static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args )
font = ( &G )->fontss;
else
return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "\"font\" must be: 'large', 'normal' (default), 'small' or 'tiny'." );
+ "\"font\" must be: 'large','normal' (default), 'normalfix', 'small' or 'tiny'." );
width = PyInt_FromLong( BMF_GetStringWidth( font, text ) );
@@ -1581,6 +1697,8 @@ static PyObject *Method_Text( PyObject * self, PyObject * args )
font = ( &G )->font;
else if( !strcmp( font_str, "large" ) )
font = BMF_GetFont(BMF_kScreen15);
+ else if( !strcmp( font_str, "normalfix" ) )
+ font = BMF_GetFont(BMF_kScreen12);
else if( !strcmp( font_str, "normal" ) )
font = ( &G )->font;
else if( !strcmp( font_str, "small" ) )
@@ -1589,7 +1707,7 @@ static PyObject *Method_Text( PyObject * self, PyObject * args )
font = ( &G )->fontss;
else
return EXPP_ReturnPyObjError( PyExc_AttributeError,
- "\"font\" must be: 'normal' (default), 'large', 'small' or 'tiny'." );
+ "\"font\" must be: 'large','normal' (default), 'normalfix', 'small' or 'tiny'." );
BMF_DrawString( font, text );
@@ -1635,6 +1753,99 @@ static PyObject *Method_PupMenu( PyObject * self, PyObject * args )
"couldn't create a PyInt" );
}
+static int current_menu_ret;
+static void toolbox_event(void *arg, int event)
+{
+ current_menu_ret = event;
+}
+
+static TBitem * menu_from_pylist( PyObject * current_menu, ListBase *storage )
+{
+ TBitem *tbarray, *tbitem;
+ Link *link;
+ PyObject *item, *submenu;
+ int size, i;
+
+ char *menutext;
+ int event;
+
+ size = PyList_Size( current_menu );
+
+ link= MEM_callocN(sizeof(Link) + sizeof(TBitem)*(size+1), "python menu");
+
+ if (link==NULL) {
+ PyErr_SetString( PyExc_MemoryError, "Could not allocate enough memory for the menu" );
+ BLI_freelistN(storage);
+ return NULL;
+ }
+
+ BLI_addtail(storage, link);
+
+ tbarray = tbitem = (TBitem *)(link+1);
+
+ for (i=0; i<size; i++, tbitem++) {
+ /* need to get these in */
+ item = PyList_GET_ITEM( current_menu, i);
+
+ if (item == Py_None) {
+ tbitem->name = "SEPR";
+ } else if( PyArg_ParseTuple( item, "si", &menutext, &event ) ) {
+ tbitem->name = menutext;
+ tbitem->retval = event;
+ //current_menu_index
+ } else if( PyArg_ParseTuple( item, "sO!", &menutext, &PyList_Type, &submenu ) ) {
+ PyErr_Clear(); /* from PyArg_ParseTuple above */
+ tbitem->name = menutext;
+ tbitem->poin = menu_from_pylist(submenu, storage);
+ if (tbitem->poin == NULL) {
+ BLI_freelistN(storage);
+ return NULL; /* error should be set */
+ }
+ } else {
+ PyErr_Clear(); /* from PyArg_ParseTuple above */
+
+ PyErr_SetString( PyExc_TypeError, "Expected a list of name,event tuples, None, or lists for submenus" );
+ BLI_freelistN(storage);
+ return NULL;
+ }
+ }
+ tbitem->icon= -1; /* end signal */
+ tbitem->name= "";
+ tbitem->retval= 0;
+ tbitem->poin= toolbox_event;
+
+ return tbarray;
+}
+
+static PyObject *Method_PupTreeMenu( PyObject * self, PyObject * args )
+{
+ PyObject * current_menu;
+ ListBase storage = {NULL, NULL};
+ TBitem *tb;
+
+ if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &current_menu ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "Expected a list" );
+
+ mywinset(G.curscreen->mainwin); // we go to screenspace
+
+ tb = menu_from_pylist(current_menu, &storage);
+
+ if (!tb) {
+ /* Error is set */
+ return NULL;
+ }
+
+ current_menu_ret = -1;
+ toolbox_generic(tb);
+
+ /* free all dynamic entries... */
+ BLI_freelistN(&storage);
+
+ mywinset(curarea->win);
+ return PyInt_FromLong( current_menu_ret ); /* current_menu_ret is set by toolbox_event callback */
+}
+
static PyObject *Method_PupIntInput( PyObject * self, PyObject * args )
{
char *text = NULL;
diff --git a/source/blender/python/api2_2x/Draw.h b/source/blender/python/api2_2x/Draw.h
index d852c15d28d..12712713d1d 100644
--- a/source/blender/python/api2_2x/Draw.h
+++ b/source/blender/python/api2_2x/Draw.h
@@ -57,11 +57,13 @@ typedef struct _Button {
char *asstr;
float asvec[3];
} val;
- char *tooltip;
+ char tooltip[256];
} Button;
-#define BINT_TYPE 1
-#define BFLOAT_TYPE 2
+#define BPY_MAX_TOOLTIP 255
+
+#define BINT_TYPE 1
+#define BFLOAT_TYPE 2
#define BSTRING_TYPE 3
#define BVECTOR_TYPE 4
diff --git a/source/blender/python/api2_2x/Effect.c b/source/blender/python/api2_2x/Effect.c
index 8c23a4d1544..43c86ebe634 100644
--- a/source/blender/python/api2_2x/Effect.c
+++ b/source/blender/python/api2_2x/Effect.c
@@ -774,11 +774,7 @@ PyObject *Effect_Init( void )
static PyObject *Effect_getType( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->effect->type );
- if( attr )
- return attr;
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get mode attribute" ) );
+ return PyInt_FromLong( ( long ) self->effect->type );
}
/* does nothing since there is only one type of effect */
@@ -800,28 +796,12 @@ static int Effect_setStype( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getStype( BPy_Effect * self )
{
- PyObject *attr;
- long stype = (long)( self->effect->stype );
-
- attr = PyInt_FromLong( stype );
- if( attr ) return attr;
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.stype attribute" );
+ return PyInt_FromLong( (long)( self->effect->stype ) );
}
static PyObject *Effect_getFlag( BPy_Effect * self )
{
- PyObject *attr;
- /* toggle "Verts" setting because clear is "on" */
- long flag = (long)( self->effect->flag ^ PAF_OFACE );
-
- attr = PyInt_FromLong( flag );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.flag attribute" );
+ return PyInt_FromLong( (long)( self->effect->flag ^ PAF_OFACE ) );
}
static int Effect_setFlag( BPy_Effect * self, PyObject * args )
@@ -852,13 +832,7 @@ static int Effect_setFlag( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getSta( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->sta );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.sta attribute" );
+ return PyFloat_FromDouble( self->effect->sta );
}
static int Effect_setSta( BPy_Effect * self, PyObject * args )
@@ -869,15 +843,7 @@ static int Effect_setSta( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getEnd( BPy_Effect * self )
{
- PyObject *attr;
- PartEff *ptr = ( PartEff * ) self->effect;
-
- attr = PyFloat_FromDouble( ptr->end );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.end attribute" );
+ return PyFloat_FromDouble( ((PartEff *) self->effect)->end );
}
static int Effect_setEnd( BPy_Effect * self, PyObject * args )
@@ -895,13 +861,7 @@ static int Effect_setEnd( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getLifetime( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->lifetime );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.lifetime attribute" );
+ return PyFloat_FromDouble( self->effect->lifetime );
}
static int Effect_setLifetime( BPy_Effect * self, PyObject * args )
@@ -912,13 +872,7 @@ static int Effect_setLifetime( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getNormfac( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->normfac );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.normfac attribute" );
+ return PyFloat_FromDouble( self->effect->normfac );
}
static int Effect_setNormfac( BPy_Effect * self, PyObject * args )
@@ -929,13 +883,7 @@ static int Effect_setNormfac( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getObfac( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->obfac );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.obfac attribute" );
+ return PyFloat_FromDouble( self->effect->obfac );
}
static int Effect_setObfac( BPy_Effect * self, PyObject * args )
@@ -946,13 +894,7 @@ static int Effect_setObfac( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getRandfac( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->randfac );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.randfac attribute" );
+ return PyFloat_FromDouble( self->effect->randfac );
}
static int Effect_setRandfac( BPy_Effect * self, PyObject * args )
@@ -963,13 +905,7 @@ static int Effect_setRandfac( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getTexfac( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->texfac );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.texfac attribute" );
+ return PyFloat_FromDouble( self->effect->texfac );
}
static int Effect_setTexfac( BPy_Effect * self, PyObject * args )
@@ -980,13 +916,7 @@ static int Effect_setTexfac( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getRandlife( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->randlife );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.randlife attribute" );
+ return PyFloat_FromDouble( self->effect->randlife );
}
static int Effect_setRandlife( BPy_Effect * self, PyObject * args )
@@ -997,13 +927,7 @@ static int Effect_setRandlife( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getNabla( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->nabla );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.nabla attribute" );
+ return PyFloat_FromDouble( self->effect->nabla );
}
static int Effect_setNabla( BPy_Effect * self, PyObject * args )
@@ -1014,13 +938,7 @@ static int Effect_setNabla( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getVectsize( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( self->effect->vectsize );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.vectsize attribute" );
+ return PyFloat_FromDouble( self->effect->vectsize );
}
static int Effect_setVectsize( BPy_Effect * self, PyObject * args )
@@ -1031,13 +949,7 @@ static int Effect_setVectsize( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getTotpart( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( self->effect->totpart );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.totpart attribute" );
+ return PyInt_FromLong( self->effect->totpart );
}
static int Effect_setTotpart( BPy_Effect * self, PyObject * args )
@@ -1048,13 +960,7 @@ static int Effect_setTotpart( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getTotkey( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( self->effect->totkey );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.totkey attribute" );
+ return PyInt_FromLong( self->effect->totkey );
}
static int Effect_setTotkey( BPy_Effect * self, PyObject * args )
@@ -1065,13 +971,7 @@ static int Effect_setTotkey( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getSeed( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( self->effect->seed );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.seed attribute" );
+ return PyInt_FromLong( self->effect->seed );
}
static int Effect_setSeed( BPy_Effect * self, PyObject * args )
@@ -1082,14 +982,8 @@ static int Effect_setSeed( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getForce( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(f,f,f)", self->effect->force[0],
+ return Py_BuildValue( "(f,f,f)", self->effect->force[0],
self->effect->force[1], self->effect->force[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.force attribute" );
}
static int Effect_setForce( BPy_Effect * self, PyObject * args )
@@ -1111,15 +1005,9 @@ static int Effect_setForce( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getMult( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(f,f,f,f)", self->effect->mult[0],
+ return Py_BuildValue( "(f,f,f,f)", self->effect->mult[0],
self->effect->mult[1], self->effect->mult[2],
self->effect->mult[3] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.mult attribute" );
}
static int Effect_setMult( BPy_Effect * self, PyObject * args )
@@ -1141,15 +1029,9 @@ static int Effect_setMult( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getLife( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(f,f,f,f)", self->effect->life[0],
+ return Py_BuildValue( "(f,f,f,f)", self->effect->life[0],
self->effect->life[1], self->effect->life[2],
self->effect->life[3] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.life attribute" );
}
static int Effect_setLife( BPy_Effect * self, PyObject * args )
@@ -1171,15 +1053,9 @@ static int Effect_setLife( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getChild( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(h,h,h,h)", self->effect->child[0],
+ return Py_BuildValue( "(h,h,h,h)", self->effect->child[0],
self->effect->child[1], self->effect->child[2],
self->effect->child[3] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.child attribute" );
}
@@ -1202,15 +1078,9 @@ static int Effect_setChild( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getChildMat( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(h,h,h,h)", self->effect->mat[0],
+ return Py_BuildValue( "(h,h,h,h)", self->effect->mat[0],
self->effect->mat[1], self->effect->mat[2],
self->effect->mat[3] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.childMat attribute" );
}
static int Effect_setChildMat( BPy_Effect * self, PyObject * args )
@@ -1232,14 +1102,8 @@ static int Effect_setChildMat( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getDefvec( BPy_Effect * self )
{
- PyObject *attr = Py_BuildValue( "(f,f,f)", self->effect->defvec[0],
+ return Py_BuildValue( "(f,f,f)", self->effect->defvec[0],
self->effect->defvec[1], self->effect->defvec[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.defvec attribute" );
}
static int Effect_setDefvec( BPy_Effect * self, PyObject * args )
@@ -1262,13 +1126,7 @@ static int Effect_setDefvec( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getJitter( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->userjit );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.jitter attribute" );
+ return PyInt_FromLong( ( long )self->effect->userjit );
}
static int Effect_setJitter( BPy_Effect * self, PyObject * args )
@@ -1279,13 +1137,7 @@ static int Effect_setJitter( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getDispMat( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->omat );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.dispMat attribute" );
+ return PyInt_FromLong( ( long )self->effect->omat );
}
static int Effect_setDispMat( BPy_Effect * self, PyObject * args )
@@ -1296,13 +1148,7 @@ static int Effect_setDispMat( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getEmissionTex( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->timetex );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.emissionTex attribute" );
+ return PyInt_FromLong( ( long )self->effect->timetex );
}
static int Effect_setEmissionTex( BPy_Effect * self, PyObject * args )
@@ -1313,13 +1159,7 @@ static int Effect_setEmissionTex( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getForceTex( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->speedtex );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.forceTex attribute" );
+ return PyInt_FromLong( ( long )self->effect->speedtex );
}
static int Effect_setForceTex( BPy_Effect * self, PyObject * args )
@@ -1330,13 +1170,7 @@ static int Effect_setForceTex( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getSpeedType( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->texmap );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.speedType attribute" );
+ return PyInt_FromLong( ( long )self->effect->texmap );
}
static int Effect_setSpeedType( BPy_Effect * self, PyObject * args )
@@ -1348,13 +1182,7 @@ static int Effect_setSpeedType( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getDamping( BPy_Effect * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double )self->effect->damp );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.damping attribute" );
+ return PyFloat_FromDouble( ( double )self->effect->damp );
}
static int Effect_setDamping( BPy_Effect * self, PyObject * args )
@@ -1365,13 +1193,7 @@ static int Effect_setDamping( BPy_Effect * self, PyObject * args )
static PyObject *Effect_getVertGroup( BPy_Effect * self )
{
- PyObject *attr = PyString_FromString( self->effect->vgroupname );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.vGroup attribute" );
+ return PyString_FromString( self->effect->vgroupname );
}
@@ -1399,13 +1221,7 @@ static int Effect_setVertGroup( BPy_Effect * self, PyObject * value )
static PyObject *Effect_getSpeedVertGroup( BPy_Effect * self )
{
- PyObject *attr = PyString_FromString( self->effect->vgroupname_v );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.speedVGroup attribute" );
+ return PyString_FromString( self->effect->vgroupname_v );
}
static int Effect_setSpeedVertGroup( BPy_Effect * self, PyObject * value )
@@ -1438,13 +1254,7 @@ static int Effect_setSpeedVertGroup( BPy_Effect * self, PyObject * value )
/*****************************************************************************/
static PyObject *Effect_getDisp( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->disp );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.disp attribute" );
+ return PyInt_FromLong( ( long )self->effect->disp );
}
static int Effect_setDisp( BPy_Effect * self, PyObject * args )
@@ -1461,13 +1271,7 @@ static int Effect_setDisp( BPy_Effect * self, PyObject * args )
/*****************************************************************************/
static PyObject *Effect_getStaticStep( BPy_Effect * self )
{
- PyObject *attr = PyInt_FromLong( ( long )self->effect->staticstep );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Effect.staticStep attribute" );
+ return PyInt_FromLong( ( long )self->effect->staticstep );
}
static int Effect_setStaticStep( BPy_Effect * self , PyObject * args )
@@ -1526,7 +1330,7 @@ static PyObject *Effect_getParticlesLoc( BPy_Effect * self )
/* if object is in motion */
if( ob->ipoflag & OB_OFFS_PARTICLE )
- p_time= ob->sf;
+ p_time= give_timeoffset(ob);
else
p_time= 0.0;
@@ -1534,7 +1338,7 @@ static PyObject *Effect_getParticlesLoc( BPy_Effect * self )
if( !list )
return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
- c_time= bsystem_time( ob, 0, cfra, p_time );
+ c_time= bsystem_time( ob, cfra, p_time );
for( a=0; a < paf->totpart; a++, pa += paf->totkey ) {
@@ -1563,7 +1367,7 @@ static PyObject *Effect_getParticlesLoc( BPy_Effect * self )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't append item to PyList" );
}
-
+ Py_DECREF( strand_list );
} else {
if(c_time > pa->time && c_time < pa->time+pa->lifetime ) {
/* vector particles are a tuple of 2 vectors */
diff --git a/source/blender/python/api2_2x/Font.c b/source/blender/python/api2_2x/Font.c
index 08af60fd9e0..61edac2841a 100644
--- a/source/blender/python/api2_2x/Font.c
+++ b/source/blender/python/api2_2x/Font.c
@@ -44,7 +44,7 @@
extern PyObject *M_Text3d_LoadFont( PyObject * self, PyObject * args );
/*--------------------Python API function prototypes for the Font module----*/
-static PyObject *M_Font_Load( PyObject * self, PyObject * args );
+static PyObject *M_Font_Load( PyObject * self, PyObject * value );
static PyObject *M_Font_Get( PyObject * self, PyObject * args );
/*------------------------Python API Doc strings for the Font module--------*/
@@ -62,7 +62,7 @@ returns None if not found.\n";
/*----- Python method structure definition for Blender.Text3d.Font module---*/
struct PyMethodDef M_Font_methods[] = {
{"Get", ( PyCFunction ) M_Font_Get, METH_VARARGS, M_Font_Get_doc},
- {"Load", ( PyCFunction ) M_Font_Load, METH_VARARGS, M_Font_Load_doc},
+ {"Load", ( PyCFunction ) M_Font_Load, METH_O, M_Font_Load_doc},
{NULL, NULL, 0, NULL}
};
@@ -74,7 +74,7 @@ static PyObject *Font_unpack( BPy_Font * self, PyObject * args );
static PyMethodDef BPy_Font_methods[] = {
{"pack", ( PyCFunction ) Font_pack, METH_NOARGS,
"() - pack this Font"},
- {"unpack", ( PyCFunction ) Font_unpack, METH_VARARGS,
+ {"unpack", ( PyCFunction ) Font_unpack, METH_O,
"(mode) - unpack this packed font"},
{NULL, NULL, 0, NULL}
};
@@ -154,21 +154,18 @@ static PyObject *M_Font_Get( PyObject * self, PyObject * args )
/*--------------- Blender.Text3d.Font.New()-----------------------*/
-PyObject *M_Font_Load( PyObject * self, PyObject * args )
+PyObject *M_Font_Load( PyObject * self, PyObject * value )
{
- char *filename_str;
+ char *filename_str = PyString_AsString(value);
BPy_Font *py_font = NULL; /* for Font Data object wrapper in Python */
- PyObject *tmp;
- if( !PyArg_ParseTuple( args, "s", &filename_str ) )
+ if( !value )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected string or empty argument" ) );
/*create python font*/
if( !S_ISDIR(BLI_exist(filename_str)) ) {
- tmp= Py_BuildValue("(s)", filename_str);
- py_font= (BPy_Font *) M_Text3d_LoadFont (self, tmp);
- Py_DECREF (tmp);
+ py_font= (BPy_Font *) M_Text3d_LoadFont (self, value);
}
else
Py_RETURN_NONE;
@@ -181,15 +178,7 @@ PyObject *M_Font_Load( PyObject * self, PyObject * args )
/*--------------- BPy_Font.filename-------------------------------------*/
static PyObject *Font_getFilename( BPy_Font * self )
{
- PyObject *attr = NULL;
-
- if( self->font )
- attr = PyString_FromString( self->font->name );
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Font.filename attribute" ) );
+ return PyString_FromString( self->font->name );
}
static int Font_setFilename( BPy_Font * self, PyObject * value )
@@ -218,12 +207,12 @@ static PyObject *Font_pack( BPy_Font * self )
}
/*--------------- BPy_Font.unpack()---------------------------------*/
-static PyObject *Font_unpack( BPy_Font * self, PyObject * args )
+static PyObject *Font_unpack( BPy_Font * self, PyObject * value )
{
- int mode= 0;
+ int mode= PyInt_AsLong(value);
VFont *font= self->font;
- if( !PyArg_ParseTuple( args, "i", &mode ) )
+ if( mode==-1 )
return ( EXPP_ReturnPyObjError
( PyExc_AttributeError,
"expected int argument from Blender.UnpackModes" ) );
diff --git a/source/blender/python/api2_2x/Geometry.c b/source/blender/python/api2_2x/Geometry.c
index 816fa03ac30..842479e35fb 100644
--- a/source/blender/python/api2_2x/Geometry.c
+++ b/source/blender/python/api2_2x/Geometry.c
@@ -47,28 +47,33 @@
#include "BKE_utildefines.h"
#include "BLI_boxpack2d.h"
+#include "BLI_arithb.h"
#define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp
#define eul 0.000001
/*-- forward declarations -- */
-static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args );
+static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq );
static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args );
+static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args );
static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args );
static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args );
+
/*-------------------------DOC STRINGS ---------------------------*/
static char M_Geometry_doc[] = "The Blender Geometry module\n\n";
static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles";
static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None";
+static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, Bool) for the point on the line, and the bool so you can know if the point was between the 2 points";
static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triabgle, only the x and y are used from the vectors";
static char M_Geometry_BoxPack2D_doc[] = "";
/*-----------------------METHOD DEFINITIONS ----------------------*/
struct PyMethodDef M_Geometry_methods[] = {
- {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_VARARGS, M_Geometry_PolyFill_doc},
+ {"PolyFill", ( PyCFunction ) M_Geometry_PolyFill, METH_O, M_Geometry_PolyFill_doc},
{"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc},
+ {"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc},
{"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_doc},
- {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_VARARGS, M_Geometry_BoxPack2D_doc},
+ {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc},
{NULL, NULL, 0, NULL}
};
/*----------------------------MODULE INIT-------------------------*/
@@ -83,10 +88,10 @@ PyObject *Geometry_Init(void)
/*----------------------------------Geometry.PolyFill() -------------------*/
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
-static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args )
+static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq )
{
PyObject *tri_list; /*return this list of tri's */
- PyObject *polyLineSeq, *polyLine, *polyVec;
+ PyObject *polyLine, *polyVec;
int i, len_polylines, len_polypoints;
/* display listbase */
@@ -99,7 +104,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * args )
dispbase.first= dispbase.last= NULL;
- if(!PyArg_ParseTuple ( args, "O", &polyLineSeq) || !PySequence_Check(polyLineSeq)) {
+ if(!PySequence_Check(polyLineSeq)) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a sequence of poly lines" );
}
@@ -277,6 +282,40 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
+static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args )
+{
+ VectorObject *pt, *line_1, *line_2;
+ float pt_in[3], pt_out[3], l1[3], l2[3];
+ float lambda;
+ PyObject *ret;
+
+ if( !PyArg_ParseTuple ( args, "O!O!O!",
+ &vector_Type, &pt,
+ &vector_Type, &line_1,
+ &vector_Type, &line_2)
+ )
+ return ( EXPP_ReturnPyObjError
+ ( PyExc_TypeError, "expected 3 vector types\n" ) );
+
+ /* accept 2d verts */
+ if (pt->size==3) { VECCOPY(pt_in, pt->vec);}
+ else { pt_in[2]=0.0; VECCOPY2D(pt_in, pt->vec) }
+
+ if (line_1->size==3) { VECCOPY(l1, line_1->vec);}
+ else { l1[2]=0.0; VECCOPY2D(l1, line_1->vec) }
+
+ if (line_2->size==3) { VECCOPY(l2, line_2->vec);}
+ else { l2[2]=0.0; VECCOPY2D(l2, line_2->vec) }
+
+ /* do the calculation */
+ lambda = lambda_cp_line_ex(pt_in, l1, l2, pt_out);
+
+ ret = PyTuple_New(2);
+ PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW) );
+ PyTuple_SET_ITEM( ret, 1, PyFloat_FromDouble(lambda) );
+ return ret;
+}
+
#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
@@ -361,18 +400,16 @@ void boxPack_ToPyObject(PyObject * value, boxPack **boxarray)
}
-static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args )
+static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * boxlist )
{
- PyObject *boxlist; /*return this list of tri's */
boxPack *boxarray;
float tot_width, tot_height;
int len;
int error;
- if(!PyArg_ParseTuple ( args, "O", &boxlist) || !PyList_Check(boxlist)) {
+ if(!PyList_Check(boxlist))
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a sequence of boxes [[x,y,w,h], ... ]" );
- }
len = PyList_Size( boxlist );
diff --git a/source/blender/python/api2_2x/Group.c b/source/blender/python/api2_2x/Group.c
index 7a6a1562d8b..b4819a425f3 100755..100644
--- a/source/blender/python/api2_2x/Group.c
+++ b/source/blender/python/api2_2x/Group.c
@@ -58,7 +58,7 @@
/*****************************************************************************/
static PyObject *M_Group_New( PyObject * self, PyObject * args );
PyObject *M_Group_Get( PyObject * self, PyObject * args );
-PyObject *M_Group_Unlink( PyObject * self, PyObject * args );
+PyObject *M_Group_Unlink( PyObject * self, BPy_Group * pygrp );
/* internal */
static PyObject *GroupObSeq_CreatePyObject( BPy_Group *self, GroupObject *iter );
@@ -72,7 +72,7 @@ struct PyMethodDef M_Group_methods[] = {
{"Get", ( PyCFunction ) M_Group_Get, METH_VARARGS,
"(name) - return the group with the name 'name',\
returns None if notfound.\nIf 'name' is not specified, it returns a list of all groups."},
- {"Unlink", ( PyCFunction ) M_Group_Unlink, METH_VARARGS,
+ {"Unlink", ( PyCFunction ) M_Group_Unlink, METH_O,
"(group) - Unlink (delete) this group from Blender."},
{NULL, NULL, 0, NULL}
};
@@ -220,7 +220,7 @@ static int Group_setLayers( BPy_Group * self, PyObject * value )
GROUP_DEL_CHECK_INT(self);
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected an integer (bitmask) as argument" );
@@ -447,17 +447,13 @@ PyObject *M_Group_Get( PyObject * self, PyObject * args )
/* Function: M_Group_Unlink */
/* Python equivalent: Blender.Group.Unlink */
/*****************************************************************************/
-PyObject *M_Group_Unlink( PyObject * self, PyObject * args )
+PyObject *M_Group_Unlink( PyObject * self, BPy_Group * pygrp )
{
- PyObject *pyob=NULL;
- BPy_Group *pygrp=NULL;
Group *group;
- if( !PyArg_ParseTuple( args, "O!", &Group_Type, &pyob) )
+ if( !BPy_Group_Check(pygrp) )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a group" ) );
- pygrp= (BPy_Group *)pyob;
-
GROUP_DEL_CHECK_PY(pygrp);
group= pygrp->group;
@@ -661,14 +657,13 @@ static PyObject *GroupObSeq_nextIter( BPy_GroupObSeq * self )
}
-static PyObject *GroupObSeq_link( BPy_GroupObSeq * self, PyObject *args )
+static PyObject *GroupObSeq_link( BPy_GroupObSeq * self, BPy_Object *value )
{
- PyObject *pyobj;
Object *blen_ob;
GROUP_DEL_CHECK_PY(self->bpygroup);
- if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
+ if( !BPy_Object_Check(value) )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a python object as an argument" ) );
@@ -678,32 +673,31 @@ static PyObject *GroupObSeq_link( BPy_GroupObSeq * self, PyObject *args )
"Cannot modify group objects while iterating" );
*/
- blen_ob = ( ( BPy_Object * ) pyobj )->object;
+ blen_ob = value->object;
add_to_group_wraper(self->bpygroup->group, blen_ob); /* this checks so as not to add the object into the group twice*/
Py_RETURN_NONE;
}
-static PyObject *GroupObSeq_unlink( BPy_GroupObSeq * self, PyObject *args )
+static PyObject *GroupObSeq_unlink( BPy_GroupObSeq * self, BPy_Object *value )
{
- PyObject *pyobj;
Object *blen_ob;
Base *base= NULL;
GROUP_DEL_CHECK_PY(self->bpygroup);
- if( !PyArg_ParseTuple( args, "O!", &Object_Type, &pyobj ) )
+ if( !BPy_Object_Check(value) )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a python object as an argument" ) );
- blen_ob = ( ( BPy_Object * ) pyobj )->object;
+ blen_ob = value->object;
rem_from_group(self->bpygroup->group, blen_ob);
- if(find_group(blen_ob)==NULL) {
+ if(find_group(blen_ob, NULL)==NULL) {
blen_ob->flag &= ~OB_FROMGROUP;
base= object_in_scene(blen_ob, G.scene);
@@ -714,9 +708,9 @@ static PyObject *GroupObSeq_unlink( BPy_GroupObSeq * self, PyObject *args )
}
static struct PyMethodDef BPy_GroupObSeq_methods[] = {
- {"link", (PyCFunction)GroupObSeq_link, METH_VARARGS,
+ {"link", (PyCFunction)GroupObSeq_link, METH_O,
"make the object a part of this group"},
- {"unlink", (PyCFunction)GroupObSeq_unlink, METH_VARARGS,
+ {"unlink", (PyCFunction)GroupObSeq_unlink, METH_O,
"unlink an object from this group"},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/IDProp.c b/source/blender/python/api2_2x/IDProp.c
index 5372e569d41..3358b06d30b 100644
--- a/source/blender/python/api2_2x/IDProp.c
+++ b/source/blender/python/api2_2x/IDProp.c
@@ -384,16 +384,15 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
"eek!! a property exists with a bad type code!!!" );
}
-PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *vars)
+PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value)
{
IDProperty *loop;
PyObject *pyform;
- char *name;
- int ok = PyArg_ParseTuple(vars, "s", &name);
+ char *name = PyString_AsString(value);
- if (!ok) {
+ if (!name) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "pop expected at least 1 arguments, got 0" );
+ "pop expected at least 1 argument, got 0" );
}
for (loop=self->prop->data.group.first; loop; loop=loop->next) {
@@ -434,7 +433,7 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
{
PyObject *seq = PyList_New(self->prop->len);
IDProperty *loop;
- int i;
+ int i, j;
if (!seq)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -443,6 +442,25 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++)
PyList_SetItem(seq, i, PyString_FromString(loop->name));
+ if (i != self->prop->len) {
+ printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys!\n");
+
+ /*fill rest of list with valid references to None*/
+ for (j=i; j<self->prop->len; j++) {
+ Py_INCREF(Py_None);
+ PyList_SetItem(seq, j, Py_None);
+ }
+
+ /*set correct group length*/
+ self->prop->len = i;
+
+ /*free the old list*/
+ Py_DECREF(seq);
+
+ /*call self again*/
+ return BPy_IDGroup_GetKeys(self);
+ }
+
return seq;
}
@@ -450,7 +468,7 @@ PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
{
PyObject *seq = PyList_New(self->prop->len);
IDProperty *loop;
- int i;
+ int i, j;
if (!seq)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -459,16 +477,35 @@ PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self)
for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) {
PyList_SetItem(seq, i, BPy_IDGroup_WrapData(self->id, loop));
}
-
+
+ if (i != self->prop->len) {
+ printf("ID Property Error found and corrected in BPy_IDGroup_GetValues!\n");
+
+ /*fill rest of list with valid references to None*/
+ for (j=i; j<self->prop->len; j++) {
+ Py_INCREF(Py_None);
+ PyList_SetItem(seq, j, Py_None);
+ }
+
+ /*set correct group length*/
+ self->prop->len = i;
+
+ /*free the old list*/
+ Py_DECREF(seq);
+
+ /*call self again*/
+ return BPy_IDGroup_GetValues(self);
+ }
+
return seq;
}
-PyObject *BPy_IDGroup_HasKey(BPy_IDProperty *self, PyObject *vars)
+PyObject *BPy_IDGroup_HasKey(BPy_IDProperty *self, PyObject *value)
{
IDProperty *loop;
- char *name;
+ char *name = PyString_AsString(value);
- if (!PyArg_ParseTuple(vars, "s", &name))
+ if (!name)
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string");
@@ -507,7 +544,7 @@ PyObject *BPy_IDGroup_ConvertToPy(BPy_IDProperty *self)
}
static struct PyMethodDef BPy_IDGroup_methods[] = {
- {"pop", (PyCFunction)BPy_IDGroup_Pop, METH_VARARGS,
+ {"pop", (PyCFunction)BPy_IDGroup_Pop, METH_O,
"pop an item from the group; raises KeyError if the item doesn't exist."},
{"iteritems", (PyCFunction)BPy_IDGroup_IterItems, METH_NOARGS,
"iterate through the items in the dict; behaves like dictionary method iteritems."},
@@ -515,7 +552,7 @@ static struct PyMethodDef BPy_IDGroup_methods[] = {
"get the keys associated with this group as a list of strings."},
{"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS,
"get the values associated with this group."},
- {"has_key", (PyCFunction)BPy_IDGroup_HasKey, METH_VARARGS,
+ {"has_key", (PyCFunction)BPy_IDGroup_HasKey, METH_O,
"returns true if the group contains a key, false if not."},
{"update", (PyCFunction)BPy_IDGroup_Update, METH_VARARGS,
"updates the values in the group with the values of another or a dict."},
diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c
index 4a7ba22a084..c8217eba2b2 100644
--- a/source/blender/python/api2_2x/Image.c
+++ b/source/blender/python/api2_2x/Image.c
@@ -38,6 +38,7 @@
#include "BKE_library.h"
#include "BKE_image.h"
#include "BKE_idprop.h"
+#include "BKE_utildefines.h"
#include "BIF_drawimage.h"
#include "BLI_blenlib.h"
#include "DNA_space_types.h" /* FILE_MAXDIR = 160 */
@@ -83,7 +84,7 @@ enum img_consts {
static PyObject *M_Image_New( PyObject * self, PyObject * args );
static PyObject *M_Image_Get( PyObject * self, PyObject * args );
static PyObject *M_Image_GetCurrent( PyObject * self );
-static PyObject *M_Image_Load( PyObject * self, PyObject * args );
+static PyObject *M_Image_Load( PyObject * self, PyObject * value );
/*****************************************************************************/
@@ -100,22 +101,25 @@ static PyObject *Image_getEnd( BPy_Image * self );
static PyObject *Image_getSpeed( BPy_Image * self );
static int Image_setFilename( BPy_Image * self, PyObject * args );
static PyObject *Image_oldsetFilename( BPy_Image * self, PyObject * args );
-static PyObject *Image_setXRep( BPy_Image * self, PyObject * args );
-static PyObject *Image_setYRep( BPy_Image * self, PyObject * args );
+static PyObject *Image_setXRep( BPy_Image * self, PyObject * value );
+static PyObject *Image_setYRep( BPy_Image * self, PyObject * value );
static PyObject *Image_setStart( BPy_Image * self, PyObject * args );
static PyObject *Image_setEnd( BPy_Image * self, PyObject * args );
static PyObject *Image_setSpeed( BPy_Image * self, PyObject * args );
static PyObject *Image_reload( BPy_Image * self );
+static PyObject *Image_updateDisplay( BPy_Image * self );
static PyObject *Image_glLoad( BPy_Image * self );
static PyObject *Image_glFree( BPy_Image * self );
static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args );
+static PyObject *Image_getPixelHDR( BPy_Image * self, PyObject * args );
static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args );
static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args );
+static PyObject *Image_setPixelHDR( BPy_Image * self, PyObject * args );
static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args );
static PyObject *Image_getMaxXY( BPy_Image * self );
static PyObject *Image_getMinXY( BPy_Image * self );
static PyObject *Image_save( BPy_Image * self );
-static PyObject *Image_unpack( BPy_Image * self, PyObject * args );
+static PyObject *Image_unpack( BPy_Image * self, PyObject * value );
static PyObject *Image_pack( BPy_Image * self );
static PyObject *Image_makeCurrent( BPy_Image * self );
@@ -126,11 +130,15 @@ static PyObject *Image_makeCurrent( BPy_Image * self );
static PyMethodDef BPy_Image_methods[] = {
/* name, method, flags, doc */
{"getPixelF", ( PyCFunction ) Image_getPixelF, METH_VARARGS,
- "(int, int) - Get pixel color as floats 0.0-1.0 returns [r,g,b,a]"},
+ "(int, int) - Get pixel color as floats returns [r,g,b,a]"},
+ {"getPixelHDR", ( PyCFunction ) Image_getPixelHDR, METH_VARARGS,
+ "(int, int) - Get pixel color as floats returns [r,g,b,a]"},
{"getPixelI", ( PyCFunction ) Image_getPixelI, METH_VARARGS,
"(int, int) - Get pixel color as ints 0-255 returns [r,g,b,a]"},
{"setPixelF", ( PyCFunction ) Image_setPixelF, METH_VARARGS,
- "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats 0.0-1.0"},
+ "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats"},
+ {"setPixelHDR", ( PyCFunction ) Image_setPixelHDR, METH_VARARGS,
+ "(int, int, [f r,f g,f b,f a]) - Set pixel color using floats"},
{"setPixelI", ( PyCFunction ) Image_setPixelI, METH_VARARGS,
"(int, int, [i r, i g, i b, i a]) - Set pixel color using ints 0-255"},
{"getMaxXY", ( PyCFunction ) Image_getMaxXY, METH_NOARGS,
@@ -159,6 +167,8 @@ static PyMethodDef BPy_Image_methods[] = {
"() - Return Image object's bind code value"},
{"reload", ( PyCFunction ) Image_reload, METH_NOARGS,
"() - Reload the image from the filesystem"},
+ {"updateDisplay", ( PyCFunction ) Image_updateDisplay, METH_NOARGS,
+ "() - Update the display image from the floating point buffer (if it exists)"},
{"glLoad", ( PyCFunction ) Image_glLoad, METH_NOARGS,
"() - Load the image data in OpenGL texture memory.\n\
The bindcode (int) is returned."},
@@ -169,9 +179,9 @@ static PyMethodDef BPy_Image_methods[] = {
"(str) - Change Image object name"},
{"setFilename", ( PyCFunction ) Image_oldsetFilename, METH_VARARGS,
"(str) - Change Image file name"},
- {"setXRep", ( PyCFunction ) Image_setXRep, METH_VARARGS,
+ {"setXRep", ( PyCFunction ) Image_setXRep, METH_O,
"(int) - Change Image object x repetition value"},
- {"setYRep", ( PyCFunction ) Image_setYRep, METH_VARARGS,
+ {"setYRep", ( PyCFunction ) Image_setYRep, METH_O,
"(int) - Change Image object y repetition value"},
{"setStart", ( PyCFunction ) Image_setStart, METH_VARARGS,
"(int) - Change Image object animation start value"},
@@ -199,7 +209,7 @@ static PyMethodDef BPy_Image_methods[] = {
static char M_Image_doc[] = "The Blender Image module\n\n";
static char M_Image_New_doc[] =
- "() - return a new Image object";
+ "(name, width, height, depth) - all args are optional, return a new Image object";
static char M_Image_Get_doc[] =
"(name) - return the image with the name 'name', \
@@ -222,7 +232,7 @@ struct PyMethodDef M_Image_methods[] = {
{"Get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
{"GetCurrent", ( PyCFunction ) M_Image_GetCurrent, METH_NOARGS, M_Image_GetCurrent_doc},
{"get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
- {"Load", M_Image_Load, METH_VARARGS, M_Image_Load_doc},
+ {"Load", M_Image_Load, METH_O, M_Image_Load_doc},
{NULL, NULL, 0, NULL}
};
@@ -243,7 +253,7 @@ static PyObject *M_Image_New( PyObject * self, PyObject * args)
if (width > 5000 || height > 5000 || width < 1 || height < 1)
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"Image width and height must be between 1 and 5000" ) );
- image = BKE_add_image_size(width, height, name, 0, color);
+ image = BKE_add_image_size(width, height, name, depth==128 ? 1 : 0, 0, color);
if( !image )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyObject Image_Type" ) );
@@ -349,13 +359,13 @@ static PyObject *M_Image_GetCurrent( PyObject * self )
/* Description: Receives a string and returns the image object */
/* whose filename matches the string. */
/*****************************************************************************/
-static PyObject *M_Image_Load( PyObject * self, PyObject * args )
+static PyObject *M_Image_Load( PyObject * self, PyObject * value )
{
- char *fname;
+ char *fname = PyString_AsString(value);
Image *img_ptr;
BPy_Image *image;
- if( !PyArg_ParseTuple( args, "s", &fname ) )
+ if( !value )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" ) );
@@ -380,29 +390,27 @@ static PyObject *M_Image_Load( PyObject * self, PyObject * args )
/**
- * getPixelF( x, y )
+ * getPixelHDR( x, y )
* returns float list of pixel colors in rgba order.
- * returned values are floats normalized to 0.0 - 1.0.
- * blender images are all 4x8 bit at the moment apr-2005
- */
+ * returned values are floats , in the full range of the float image source.
+ */
-static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
+static PyObject *Image_getPixelHDR( BPy_Image * self, PyObject * args )
{
PyObject *attr;
ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
- char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
int y = 0;
- int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
+ int pixel_size = 4; /* each pixel is 4 x 32 bit float */
int i;
if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 2 integers" );
- if( !ibuf || !ibuf->rect ) /* loading didn't work */
+ if( !ibuf || (!ibuf->rect_float && !ibuf->rect)) /* loading didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
@@ -428,15 +436,26 @@ static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
"couldn't allocate memory for color list" );
index = ( x + y * ibuf->x ) * pixel_size;
-
- pixel = ( char * ) ibuf->rect;
- for (i=0; i<4; i++) {
- PyList_SetItem( attr, i, PyFloat_FromDouble( ( ( double ) pixel[index+i] ) / 255.0 ));
+
+ /* if a float buffer exists, use it, otherwise convert the 8bpc buffer to float values */
+ if (ibuf->rect_float) {
+ float *pixelf; /* image data */
+
+ pixelf = ibuf->rect_float;
+ for (i=0; i<4; i++) {
+ PyList_SetItem( attr, i, PyFloat_FromDouble( (double)pixelf[index+i] ) );
+ }
+ } else {
+ char *pixelc; /* image data */
+
+ pixelc = ( char * ) ibuf->rect;
+ for (i=0; i<4; i++) {
+ PyList_SetItem( attr, i, PyFloat_FromDouble( ( ( double ) pixelc[index+i] ) / 255.0 ));
+ }
}
return attr;
}
-
/**
* getPixelI( x, y )
* returns integer list of pixel colors in rgba order.
@@ -492,25 +511,30 @@ static PyObject *Image_getPixelI( BPy_Image * self, PyObject * args )
}
-/* set pixel as floats */
+/**
+ * getPixelF( x, y )
+ * returns float list of pixel colors in rgba order.
+ * returned values are floats normalized to 0.0 - 1.0.
+ * blender images are all 4x8 bit at the moment apr-2005
+ */
-static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
+static PyObject *Image_getPixelF( BPy_Image * self, PyObject * args )
{
+
+ PyObject *attr;
ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
char *pixel; /* image data */
int index; /* offset into image data */
int x = 0;
int y = 0;
- int a = 0;
int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
- float p[4];
-
- if( !PyArg_ParseTuple
- ( args, "ii(ffff)", &x, &y, &p[0], &p[1], &p[2], &p[3] ) )
+ int i;
+
+ if( !PyArg_ParseTuple( args, "ii", &x, &y ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected 2 integers and an array of 4 floats" );
+ "expected 2 integers" );
- if( !ibuf || !ibuf->rect ) /* didn't work */
+ if( !ibuf || !ibuf->rect ) /* loading didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
@@ -522,28 +546,67 @@ static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
|| y > ( ibuf->y - 1 )
|| x < ibuf->xorig || y < ibuf->yorig )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "x or y is out of ruange" );
-
- for( a = 0; a < 4; a++ ) {
- if( p[a] > 1.0 || p[a] < 0.0 )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "r, g, b, or a is out of range" );
- }
-
+ "x or y is out of range" );
/*
assumption: from looking at source, skipx is often not set,
so we calc ourselves
*/
+ attr = PyList_New(4);
+
+ if (!attr)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "couldn't allocate memory for color list" );
+
index = ( x + y * ibuf->x ) * pixel_size;
pixel = ( char * ) ibuf->rect;
+ for (i=0; i<4; i++) {
+ PyList_SetItem( attr, i, PyFloat_FromDouble( ( ( double ) pixel[index+i] ) / 255.0 ));
+ }
+ return attr;
+}
- pixel[index] = ( char ) ( p[0] * 255.0 );
- pixel[index + 1] = ( char ) ( p[1] * 255.0 );
- pixel[index + 2] = ( char ) ( p[2] * 255.0 );
- pixel[index + 3] = ( char ) ( p[3] * 255.0 );
+/* set pixel as floats */
+
+static PyObject *Image_setPixelHDR( BPy_Image * self, PyObject * args )
+{
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+ float *pixel; /* image data */
+ int index; /* offset into image data */
+ int x = 0;
+ int y = 0;
+ int pixel_size = 4; /* each pixel is 4 x 32 bit float */
+ float p[4];
+
+ if( !PyArg_ParseTuple
+ ( args, "ii(ffff)", &x, &y, &p[0], &p[1], &p[2], &p[3] ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected 2 integers and an array of 4 floats" );
+
+ if( !ibuf ) /* didn't work */
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "couldn't load image data in Blender" );
+
+ if( ibuf->type == 1 ) /* bitplane image */
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported bitplane image format" );
+
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "x or y is out of range" );
+
+ /* if no float buffer already exists, add it */
+ if (!ibuf->rect_float) imb_addrectfloatImBuf(ibuf);
+
+ index = ( x + y * ibuf->x ) * pixel_size;
+
+ pixel = ibuf->rect_float + index;
+
+ QUATCOPY(pixel, p);
ibuf->userflags |= IB_BITMAPDIRTY;
Py_RETURN_NONE;
@@ -606,25 +669,74 @@ static PyObject *Image_setPixelI( BPy_Image * self, PyObject * args )
Py_RETURN_NONE;
}
+/* set pixel as floats */
+
+static PyObject *Image_setPixelF( BPy_Image * self, PyObject * args )
+{
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+ char *pixel; /* image data */
+ int index; /* offset into image data */
+ int x = 0;
+ int y = 0;
+ int a = 0;
+ int pixel_size = 4; /* each pixel is 4 x 8-bits packed in unsigned int */
+ float p[4];
+
+ if( !PyArg_ParseTuple
+ ( args, "ii(ffff)", &x, &y, &p[0], &p[1], &p[2], &p[3] ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected 2 integers and an array of 4 floats" );
+
+ if( !ibuf || !ibuf->rect ) /* didn't work */
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "couldn't load image data in Blender" );
+
+ if( ibuf->type == 1 ) /* bitplane image */
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "unsupported bitplane image format" );
+
+ if( x > ( ibuf->x - 1 )
+ || y > ( ibuf->y - 1 )
+ || x < ibuf->xorig || y < ibuf->yorig )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "x or y is out of ruange" );
+
+ for( a = 0; a < 4; a++ ) {
+ if( p[a] > 1.0 || p[a] < 0.0 )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "r, g, b, or a is out of range" );
+ }
+
+
+ /*
+ assumption: from looking at source, skipx is often not set,
+ so we calc ourselves
+ */
+
+ index = ( x + y * ibuf->x ) * pixel_size;
+
+ pixel = ( char * ) ibuf->rect;
+
+ pixel[index] = ( char ) ( p[0] * 255.0 );
+ pixel[index + 1] = ( char ) ( p[1] * 255.0 );
+ pixel[index + 2] = ( char ) ( p[2] * 255.0 );
+ pixel[index + 3] = ( char ) ( p[3] * 255.0 );
+
+ ibuf->userflags |= IB_BITMAPDIRTY;
+ Py_RETURN_NONE;
+}
/* get max extent of image */
static PyObject *Image_getMaxXY( BPy_Image * self )
{
ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
- PyObject *attr;
if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "[i,i]", ibuf->x, ibuf->y );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "could not determine max x or y" );
+ return Py_BuildValue( "[i,i]", ibuf->x, ibuf->y );
}
@@ -633,30 +745,23 @@ static PyObject *Image_getMaxXY( BPy_Image * self )
static PyObject *Image_getMinXY( BPy_Image * self )
{
ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
- PyObject *attr;
if( !ibuf || !ibuf->rect ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
- attr = Py_BuildValue( "[i,i]", ibuf->xorig, ibuf->yorig );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "could not determine min x or y" );
+ return Py_BuildValue( "[i,i]", ibuf->xorig, ibuf->yorig );
}
/* unpack image */
-static PyObject *Image_unpack( BPy_Image * self, PyObject * args )
+static PyObject *Image_unpack( BPy_Image * self, PyObject * value )
{
Image *image = self->image;
- int mode;
+ int mode = (int)PyInt_AsLong(value);
/*get the absolute path */
- if( !PyArg_ParseTuple( args, "i", &mode ) )
+ if( mode==-1 )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected 1 integer from Blender.UnpackModes" );
@@ -805,13 +910,7 @@ Image *Image_FromPyObject( PyObject * pyobj )
static PyObject *Image_getFilename( BPy_Image * self )
{
- PyObject *attr = PyString_FromString( self->image->name );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.filename attribute" ) );
+ return PyString_FromString( self->image->name );
}
static PyObject *Image_getSize( BPy_Image * self )
@@ -837,86 +936,46 @@ static PyObject *Image_getSize( BPy_Image * self )
static PyObject *Image_getDepth( BPy_Image * self )
{
ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
- PyObject *attr;
if( !ibuf ) /* didn't work */
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't load image data in Blender" );
-
- attr = PyInt_FromLong( (long)ibuf->depth );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.depth attribute" );
+ if (ibuf->rect_float) {
+ return PyInt_FromLong( (long)128 );
+ } else {
+ return PyInt_FromLong( (long)ibuf->depth );
+ }
}
static PyObject *Image_getXRep( BPy_Image * self )
{
- PyObject *attr = PyInt_FromLong( self->image->xrep );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.xrep attribute" );
+ return PyInt_FromLong( self->image->xrep );
}
static PyObject *Image_getYRep( BPy_Image * self )
{
- PyObject *attr = PyInt_FromLong( self->image->yrep );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.yrep attribute" );
+ return PyInt_FromLong( self->image->yrep );
}
static PyObject *Image_getStart( BPy_Image * self )
{
- PyObject *attr = PyInt_FromLong( self->image->twsta );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.start attribute" );
+ return PyInt_FromLong( self->image->twsta );
}
static PyObject *Image_getEnd( BPy_Image * self )
{
- PyObject *attr = PyInt_FromLong( self->image->twend );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.end attribute" );
+ return PyInt_FromLong( self->image->twend );
}
static PyObject *Image_getSpeed( BPy_Image * self )
{
- PyObject *attr = PyInt_FromLong( self->image->animspeed );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.speed attribute" );
+ return PyInt_FromLong( self->image->animspeed );
}
static PyObject *Image_getBindCode( BPy_Image * self )
{
- PyObject *attr = PyLong_FromUnsignedLong( self->image->bindcode );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Image.bindcode attribute" );
+ return PyLong_FromUnsignedLong( self->image->bindcode );
}
static PyObject *Image_reload( BPy_Image * self )
@@ -928,6 +987,21 @@ static PyObject *Image_reload( BPy_Image * self )
Py_RETURN_NONE;
}
+static PyObject *Image_updateDisplay( BPy_Image * self )
+{
+ ImBuf *ibuf= BKE_image_get_ibuf(self->image, NULL);
+
+ if( !ibuf ) /* didn't work */
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "couldn't load image data in Blender" );
+
+ IMB_rect_from_float(ibuf);
+
+ Py_RETURN_NONE;
+}
+
+
+
static PyObject *Image_glFree( BPy_Image * self )
{
Image *image = self->image;
@@ -1000,37 +1074,27 @@ static PyObject *Image_oldsetFilename( BPy_Image * self, PyObject * args )
return EXPP_setterWrapper( (void *)self, args, (setter)Image_setFilename );
}
-static PyObject *Image_setXRep( BPy_Image * self, PyObject * args )
+static PyObject *Image_setXRep( BPy_Image * self, PyObject * value )
{
- short value;
+ short param = (short)PyInt_AsLong(value);
- if( !PyArg_ParseTuple( args, "h", &value ) )
+ if( param !=-1 && param >= EXPP_IMAGE_REP_MIN && param <= EXPP_IMAGE_REP_MAX)
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument in [1,16]" ) );
- if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
- self->image->xrep = value;
- else
- return ( EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected int argument in [1,16]" ) );
-
+ self->image->xrep = param;
Py_RETURN_NONE;
}
-static PyObject *Image_setYRep( BPy_Image * self, PyObject * args )
+static PyObject *Image_setYRep( BPy_Image * self, PyObject * value )
{
- short value;
+ short param = (short)PyInt_AsLong(value);
- if( !PyArg_ParseTuple( args, "h", &value ) )
+ if( param !=-1 && param >= EXPP_IMAGE_REP_MIN && param <= EXPP_IMAGE_REP_MAX)
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument in [1,16]" ) );
- if( value >= EXPP_IMAGE_REP_MIN && value <= EXPP_IMAGE_REP_MAX )
- self->image->yrep = value;
- else
- return ( EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected int argument in [1,16]" ) );
-
+ self->image->yrep = param;
Py_RETURN_NONE;
}
@@ -1168,7 +1232,12 @@ static int Image_setSource( BPy_Image *self, PyObject *args)
static int Image_setFlag(BPy_Image *self, PyObject *value, void *flag)
{
- if ( PyObject_IsTrue(value) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if ( param )
self->image->flag |= (int)flag;
else
self->image->flag &= ~(int)flag;
@@ -1177,7 +1246,12 @@ static int Image_setFlag(BPy_Image *self, PyObject *value, void *flag)
static int Image_setFlagTpage(BPy_Image *self, PyObject *value, void *flag)
{
- if ( PyObject_IsTrue(value) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if ( param )
self->image->tpageflag |= (int)flag;
else
self->image->tpageflag &= ~(int)flag;
@@ -1189,7 +1263,6 @@ static int Image_setFlagTpage(BPy_Image *self, PyObject *value, void *flag)
*/
static PyObject *getIntAttr( BPy_Image *self, void *type )
{
- PyObject *attr = NULL;
int param;
struct Image *image = self->image;
@@ -1220,13 +1293,7 @@ static PyObject *getIntAttr( BPy_Image *self, void *type )
"undefined type in getIntAttr" );
}
- attr = PyInt_FromLong( param );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "PyInt_FromLong() failed!" );
+ return PyInt_FromLong( param );
}
diff --git a/source/blender/python/api2_2x/Ipo.c b/source/blender/python/api2_2x/Ipo.c
index 466337ff914..9b2fd082bee 100644
--- a/source/blender/python/api2_2x/Ipo.c
+++ b/source/blender/python/api2_2x/Ipo.c
@@ -86,7 +86,7 @@ struct PyMethodDef M_Ipo_methods[] = {
M_Ipo_New_doc},
{"Get", M_Ipo_Get, METH_VARARGS, M_Ipo_Get_doc},
{"get", M_Ipo_Get, METH_VARARGS, M_Ipo_Get_doc},
- {"Recalc", M_Ipo_Recalc, METH_VARARGS, M_Ipo_Get_doc},
+ {"Recalc", M_Ipo_Recalc, METH_O, M_Ipo_Get_doc},
{NULL, NULL, 0, NULL}
};
@@ -103,7 +103,7 @@ static int Ipo_setRctf( BPy_Ipo * self, PyObject * args );
static PyObject *Ipo_getCurve( BPy_Ipo * self, PyObject * args );
static PyObject *Ipo_getCurves( BPy_Ipo * self );
static PyObject *Ipo_getCurveNames( BPy_Ipo * self );
-static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args );
+static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * value );
static PyObject *Ipo_delCurve( BPy_Ipo * self, PyObject * args );
static PyObject *Ipo_getNcurves( BPy_Ipo * self );
static PyObject *Ipo_getNBezPoints( BPy_Ipo * self, PyObject * args );
@@ -142,7 +142,7 @@ static PyMethodDef BPy_Ipo_methods[] = {
"() - Return Ipo rctf"},
{"setRctf", ( PyCFunction ) Ipo_oldsetRctf, METH_VARARGS,
"(flt,flt,flt,flt) - Change Ipo rctf"},
- {"addCurve", ( PyCFunction ) Ipo_addCurve, METH_VARARGS,
+ {"addCurve", ( PyCFunction ) Ipo_addCurve, METH_O,
"() - Add a curve to Ipo"},
{"delCurve", ( PyCFunction ) Ipo_delCurve, METH_VARARGS,
"(str) - Delete curve from Ipo"},
@@ -790,15 +790,13 @@ static PyObject *M_Ipo_Get( PyObject * self_unused, PyObject * args )
/* Description: Receives (presumably) an IpoCurve object and */
/* updates the curve after changes to control points. */
/*****************************************************************************/
-static PyObject *M_Ipo_Recalc( PyObject * self_unused, PyObject * args )
+static PyObject *M_Ipo_Recalc( PyObject * self_unused, PyObject * value )
{
- PyObject *pyobj;
-
- if( !PyArg_ParseTuple( args, "O!", &IpoCurve_Type, &pyobj ) )
+ if( !BPy_IpoCurve_Check(value) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Ipo curve argument" );
- testhandles_ipocurve( IpoCurve_FromPyObject( pyobj ) );
+ testhandles_ipocurve( IpoCurve_FromPyObject( value ) );
Py_RETURN_NONE;
}
@@ -808,18 +806,12 @@ static PyObject *M_Ipo_Recalc( PyObject * self_unused, PyObject * args )
/*****************************************************************************/
static PyObject *Ipo_getBlocktype( BPy_Ipo * self )
{
- PyObject *attr = PyInt_FromLong( self->ipo->blocktype );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Ipo.blocktype attribute" );
+ return PyInt_FromLong( self->ipo->blocktype );
}
static int Ipo_setBlocktype( BPy_Ipo * self, PyObject * args )
{
- if( !PyInt_CheckExact( args ) )
+ if( !PyInt_Check( args ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -882,15 +874,15 @@ static PyObject *Ipo_getNcurves( BPy_Ipo * self )
cu = ipo.addCurve('LocX')
*/
-static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args )
+static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * value )
{
short param; /* numeric curve name constant */
- char *cur_name = 0; /* input arg: curve name */
+ char *cur_name = PyString_AsString(value); /* input arg: curve name */
Ipo *ipo = 0;
IpoCurve *icu = 0;
Link *link;
- if( !PyArg_ParseTuple( args, "s", &cur_name ) )
+ if( !cur_name )
return ( EXPP_ReturnPyObjError
( PyExc_TypeError, "expected string argument" ) );
@@ -959,12 +951,12 @@ static PyObject *Ipo_addCurve( BPy_Ipo * self, PyObject * args )
cu = ipo.delCurve('LocX')
*/
-static PyObject *Ipo_delCurve( BPy_Ipo * self, PyObject * args )
+static PyObject *Ipo_delCurve( BPy_Ipo * self, PyObject * value )
{
IpoCurve *icu;
- char *strname;
+ char *strname = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &strname ) )
+ if( !strname )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -1491,7 +1483,7 @@ static int Ipo_setIpoCurveByName( BPy_Ipo * self, PyObject * key,
icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
set_icu_vars( icu );
BLI_addtail( &(ipo->curve), icu);
- insert_vert_ipo( icu, time, curval );
+ insert_vert_icu( icu, time, curval, 0);
allspace( REMAKEIPO, 0 );
EXPP_allqueue( REDRAWIPO, 0 );
diff --git a/source/blender/python/api2_2x/Ipocurve.c b/source/blender/python/api2_2x/Ipocurve.c
index 7b071ab1f76..b8f3c3f6dd0 100644
--- a/source/blender/python/api2_2x/Ipocurve.c
+++ b/source/blender/python/api2_2x/Ipocurve.c
@@ -67,16 +67,16 @@ struct PyMethodDef M_IpoCurve_methods[] = {
/*****************************************************************************/
static PyObject *IpoCurve_getName( C_IpoCurve * self );
static PyObject *IpoCurve_Recalc( C_IpoCurve * self );
-static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * args );
-static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args );
+static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * value );
+static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * value );
static PyObject *IpoCurve_delBezier( C_IpoCurve * self, PyObject * args );
static PyObject *IpoCurve_setInterpolation( C_IpoCurve * self,
- PyObject * args );
+ PyObject * value );
static PyObject *IpoCurve_getInterpolation( C_IpoCurve * self );
static PyObject *IpoCurve_newgetInterp( C_IpoCurve * self );
static int IpoCurve_newsetInterp( C_IpoCurve * self, PyObject * args );
static PyObject *IpoCurve_setExtrapolation( C_IpoCurve * self,
- PyObject * args );
+ PyObject * value );
static PyObject *IpoCurve_getExtrapolation( C_IpoCurve * self );
static PyObject *IpoCurve_newgetExtend( C_IpoCurve * self );
static int IpoCurve_newsetExtend( C_IpoCurve * self, PyObject * args );
@@ -110,18 +110,18 @@ static PyMethodDef C_IpoCurve_methods[] = {
"() - Recomputes the curve after changes"},
{"update", ( PyCFunction ) IpoCurve_Recalc, METH_NOARGS,
"() - deprecated method: use recalc method instead."},
- {"append", ( PyCFunction ) IpoCurve_append, METH_VARARGS,
+ {"append", ( PyCFunction ) IpoCurve_append, METH_O,
"(coordlist) - Adds a Bezier point to a curve"},
- {"addBezier", ( PyCFunction ) IpoCurve_addBezier, METH_VARARGS,
+ {"addBezier", ( PyCFunction ) IpoCurve_addBezier, METH_O,
"() - deprecated method. use append() instead"},
{"delBezier", ( PyCFunction ) IpoCurve_delBezier, METH_VARARGS,
"() - deprecated method. use \"del icu[index]\" instead"},
{"setInterpolation", ( PyCFunction ) IpoCurve_setInterpolation,
- METH_VARARGS, "(str) - Sets the interpolation type of the curve"},
+ METH_O, "(str) - Sets the interpolation type of the curve"},
{"getInterpolation", ( PyCFunction ) IpoCurve_getInterpolation,
METH_NOARGS, "() - Gets the interpolation type of the curve"},
{"setExtrapolation", ( PyCFunction ) IpoCurve_setExtrapolation,
- METH_VARARGS, "(str) - Sets the extend mode of the curve"},
+ METH_O, "(str) - Sets the extend mode of the curve"},
{"getExtrapolation", ( PyCFunction ) IpoCurve_getExtrapolation,
METH_NOARGS, "() - Gets the extend mode of the curve"},
{"getPoints", ( PyCFunction ) IpoCurve_getPoints, METH_NOARGS,
@@ -394,12 +394,12 @@ static void del_beztriple( IpoCurve *icu, int index )
/*****************************************************************************/
static PyObject *IpoCurve_setInterpolation( C_IpoCurve * self,
- PyObject * args )
+ PyObject * value )
{
- char *interpolationtype = 0;
+ char *interpolationtype = PyString_AsString(value);
short id;
- if( !PyArg_ParseTuple( args, "s", &interpolationtype ) )
+ if( !interpolationtype )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -441,12 +441,12 @@ static PyObject *IpoCurve_getInterpolation( C_IpoCurve * self )
}
static PyObject * IpoCurve_setExtrapolation( C_IpoCurve * self,
- PyObject * args )
+ PyObject * value )
{
- char *extrapolationtype = 0;
+ char *extrapolationtype = PyString_AsString(value);
short id;
- if( !PyArg_ParseTuple( args, "s", &extrapolationtype ) )
+ if( !extrapolationtype )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -496,19 +496,14 @@ static PyObject *IpoCurve_getExtrapolation( C_IpoCurve * self )
* append a new BezTriple to curve
*/
-static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * args )
+static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * value )
{
float x, y;
IpoCurve *icu = self->ipocurve;
- PyObject *obj = NULL;
-
- if( !PyArg_ParseTuple( args, "O", &obj ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected tuple or BezTriple argument" );
/* if args is a already a beztriple, tack onto end of list */
- if( BPy_BezTriple_Check ( obj ) ) {
- BPy_BezTriple *bobj = (BPy_BezTriple *)obj;
+ if( BPy_BezTriple_Check ( value ) ) {
+ BPy_BezTriple *bobj = (BPy_BezTriple *)value;
BezTriple *newb = MEM_callocN( (icu->totvert+1)*sizeof(BezTriple),
"BPyBeztriple" );
@@ -525,8 +520,8 @@ static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * args )
/* otherwise try to get two floats and add to list */
} else {
PyObject *xobj, *yobj;
- xobj = PyNumber_Float( PyTuple_GetItem( obj, 0 ) );
- yobj = PyNumber_Float( PyTuple_GetItem( obj, 1 ) );
+ xobj = PyNumber_Float( PyTuple_GetItem( value, 0 ) );
+ yobj = PyNumber_Float( PyTuple_GetItem( value, 1 ) );
if( !xobj || !yobj )
return EXPP_ReturnPyObjError( PyExc_TypeError,
@@ -536,7 +531,7 @@ static PyObject *IpoCurve_append( C_IpoCurve * self, PyObject * args )
Py_DECREF( xobj );
y = (float)PyFloat_AsDouble( yobj );
Py_DECREF( yobj );
- insert_vert_ipo( icu, x, y);
+ insert_vert_icu( icu, x, y, 0);
}
Py_RETURN_NONE;
@@ -750,7 +745,7 @@ static int IpoCurve_setCurval( C_IpoCurve * self, PyObject * key,
/* insert a key at the specified time */
- insert_vert_ipo( self->ipocurve, time, curval );
+ insert_vert_icu( self->ipocurve, time, curval, 0);
allspace(REMAKEIPO, 0);
return 0;
}
@@ -801,7 +796,7 @@ static int IpoCurve_setDriver( C_IpoCurve * self, PyObject * args )
{
IpoCurve *ipo = self->ipocurve;
int type;
- if( !PyInt_CheckExact( args ) )
+ if( !PyInt_Check( args ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument 0 or 1 " );
@@ -884,7 +879,7 @@ static int IpoCurve_setDriverChannel( C_IpoCurve * self, PyObject * args )
return EXPP_ReturnIntError( PyExc_RuntimeError,
"This IpoCurve does not have an active driver" );
- if( !PyInt_CheckExact( args ) )
+ if( !PyInt_Check( args ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -1003,13 +998,7 @@ PyObject *IpoCurve_Init( void )
static PyObject *IpoCurve_newgetInterp( C_IpoCurve * self )
{
- PyObject *attr = PyInt_FromLong( self->ipocurve->ipo );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get IpoCurve.interp atrtribute" );
+ return PyInt_FromLong( self->ipocurve->ipo );
}
static int IpoCurve_newsetInterp( C_IpoCurve * self, PyObject * value )
@@ -1020,13 +1009,7 @@ static int IpoCurve_newsetInterp( C_IpoCurve * self, PyObject * value )
static PyObject *IpoCurve_newgetExtend( C_IpoCurve * self )
{
- PyObject *attr = PyInt_FromLong( self->ipocurve->extrap );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get IpoCurve.extend atrtribute" );
+ return PyInt_FromLong( self->ipocurve->extrap );
}
static int IpoCurve_newsetExtend( C_IpoCurve * self, PyObject * value )
@@ -1046,6 +1029,9 @@ static PyObject *IpoCurve_getFlag( C_IpoCurve * self, void *type )
static int IpoCurve_setFlag( C_IpoCurve * self, PyObject *value, void *type )
{
int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
if (param)
self->ipocurve->flag |= (int)type;
@@ -1058,20 +1044,17 @@ static int IpoCurve_setFlag( C_IpoCurve * self, PyObject *value, void *type )
/* #####DEPRECATED###### */
-static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args )
+static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * value )
{
float x, y;
int npoints;
IpoCurve *icu;
BezTriple *bzt, *tmp;
static char name[10] = "mlml";
- PyObject *popo = 0;
- if( !PyArg_ParseTuple( args, "O", &popo ) )
+ if( !PyArg_ParseTuple( value, "ff", &x, &y ) )
return ( EXPP_ReturnPyObjError
- ( PyExc_TypeError, "expected tuple argument" ) );
+ ( PyExc_TypeError, "expected a tuple of 2 floats" ) );
- x = (float)PyFloat_AsDouble( PyTuple_GetItem( popo, 0 ) );
- y = (float)PyFloat_AsDouble( PyTuple_GetItem( popo, 1 ) );
icu = self->ipocurve;
npoints = icu->totvert;
tmp = icu->bezt;
@@ -1093,6 +1076,5 @@ static PyObject *IpoCurve_addBezier( C_IpoCurve * self, PyObject * args )
bzt->h1 = HD_AUTO;
bzt->h2 = HD_AUTO;
- Py_INCREF( Py_None );
- return Py_None;
+ Py_RETURN_NONE;
}
diff --git a/source/blender/python/api2_2x/Ipocurve.h b/source/blender/python/api2_2x/Ipocurve.h
index c79dc5d35f1..0844e11b04b 100644
--- a/source/blender/python/api2_2x/Ipocurve.h
+++ b/source/blender/python/api2_2x/Ipocurve.h
@@ -47,6 +47,8 @@ typedef struct {
extern PyTypeObject IpoCurve_Type;
+#define BPy_IpoCurve_Check(v) ((v)->ob_type == &IpoCurve_Type) /* for type checking */
+
PyObject *IpoCurve_Init( void );
PyObject *IpoCurve_CreatePyObject( IpoCurve * ipo );
IpoCurve *IpoCurve_FromPyObject( PyObject * pyobj );
diff --git a/source/blender/python/api2_2x/Key.c b/source/blender/python/api2_2x/Key.c
index 4e5d4278fd3..90a628152e0 100644
--- a/source/blender/python/api2_2x/Key.c
+++ b/source/blender/python/api2_2x/Key.c
@@ -32,6 +32,7 @@
*/
#include "Key.h" /*This must come first*/
+#include "vector.h"
#include "DNA_scene_types.h"
@@ -40,6 +41,7 @@
#include <BKE_main.h>
#include <BKE_curve.h>
#include <BKE_library.h>
+#include <BKE_utildefines.h>
#include "BIF_space.h"
#include "Ipocurve.h"
@@ -59,9 +61,6 @@
#define KEY_TYPE_CURVE 1
#define KEY_TYPE_LATTICE 2
-/* macro from blenkernel/intern/key.c:98 */
-#define GS(a) (*((short *)(a)))
-
static int Key_compare( BPy_Key * a, BPy_Key * b );
static PyObject *Key_repr( BPy_Key * self );
static void Key_dealloc( BPy_Key * self );
@@ -334,7 +333,12 @@ static PyObject *Key_getRelative( BPy_Key * self )
static int Key_setRelative( BPy_Key * self, PyObject * value )
{
- if( PyObject_IsTrue( value ) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->key->type = KEY_RELATIVE;
else
self->key->type = KEY_NORMAL;
@@ -514,23 +518,12 @@ static PyObject *KeyBlock_getData( PyObject * self )
case ID_ME:
for (i=0, datap = kb->keyblock->data; i<kb->keyblock->totelem; i++) {
+ PyObject *vec = newVectorObject((float*)datap, 3, Py_WRAP);
+
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "could not allocate memory for Blender.Mathutils.Vector wrapper!" );
- BPy_NMVert *mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
- MVert *vert = (MVert *) datap;
-
- mv->co[0]=vert->co[0];
- mv->co[1]=vert->co[1];
- mv->co[2]=vert->co[2];
- mv->no[0] = 0.0;
- mv->no[1] = 0.0;
- mv->no[2] = 0.0;
-
- mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
- mv->index = i;
- mv->flag = 0;
-
- PyList_SetItem(l, i, ( PyObject * ) mv);
-
+ PyList_SetItem(l, i, vec);
datap += kb->key->elemsize;
}
break;
@@ -547,44 +540,63 @@ static PyObject *KeyBlock_getData( PyObject * self )
Py_DECREF (l);
l = PyList_New( datasize );
for( i = 0, datap = kb->keyblock->data; i < datasize;
- i++, datap += sizeof(float)*12 ) {
- /*
- * since the key only stores the control point and not the
- * other BezTriple attributes, build a Py_NEW BezTriple
- */
- PyObject *pybt = newBezTriple( (float *)datap );
- PyList_SetItem( l, i, pybt );
+ i++, datap += sizeof(float)*3*4) {
+ PyObject *tuple = PyTuple_New(4), *vec;
+ float *vecs = (float*)datap;
+
+ if (!tuple) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "PyTuple_New() failed!" );
+
+ vec = newVectorObject(vecs, 3, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyTuple_SET_ITEM( tuple, 0, vec);
+
+ vecs += 3;
+ vec = newVectorObject(vecs, 3, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyTuple_SET_ITEM( tuple, 1, vec);
+
+ vecs += 3;
+ vec = newVectorObject(vecs, 3, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyTuple_SET_ITEM( tuple, 2, vec);
+
+ /*tilts*/
+ vecs += 3;
+ vec = newVectorObject(vecs, 3, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyTuple_SET_ITEM( tuple, 3, vec);
+
+ PyList_SetItem( l, i, tuple );
}
} else {
for( i = 0, datap = kb->keyblock->data; i < datasize;
i++, datap += kb->key->elemsize ) {
- PyObject *pybt;
- float *fp = (float *)datap;
- pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
- if( !pybt ) {
- Py_DECREF( l );
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "Py_BuildValue() failed" );
- }
- PyList_SetItem( l, i, pybt );
+ PyObject *vec = newVectorObject((float*)datap, 4, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyList_SetItem( l, i, vec );
}
}
break;
case ID_LT:
-
for( i = 0, datap = kb->keyblock->data; i < kb->keyblock->totelem;
i++, datap += kb->key->elemsize ) {
- /* Lacking a python class for BPoint, use a list of three floats */
- PyObject *pybt;
- float *fp = (float *)datap;
- pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
- if( !pybt ) {
- Py_DECREF( l );
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "Py_BuildValue() failed" );
- }
- PyList_SetItem( l, i, pybt );
+ PyObject *vec = newVectorObject((float*)datap, 3, Py_WRAP);
+ if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+ "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+ PyList_SetItem( l, i, vec );
}
break;
}
diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c
index 84e755b64a0..16b93430d25 100644
--- a/source/blender/python/api2_2x/Lamp.c
+++ b/source/blender/python/api2_2x/Lamp.c
@@ -118,6 +118,8 @@
#define EXPP_LAMP_QUAD2_MAX 1.0
#define EXPP_LAMP_COL_MIN 0.0
#define EXPP_LAMP_COL_MAX 1.0
+#define EXPP_LAMP_FALLOFF_MIN LA_FALLOFF_CONSTANT
+#define EXPP_LAMP_FALLOFF_MAX LA_FALLOFF_SLIDERS
/* Raytracing settings */
#define EXPP_LAMP_RAYSAMPLES_MIN 1
@@ -207,7 +209,7 @@ static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure );
static PyObject *Lamp_clearIpo( BPy_Lamp * self );
static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_oldsetIpo( BPy_Lamp * self, PyObject * args );
-static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args );
+static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value );
static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_oldsetSamples( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_oldsetRaySamplesX( BPy_Lamp * self, PyObject * args );
@@ -251,10 +253,12 @@ static int Lamp_setHaloInt( BPy_Lamp * self, PyObject * args );
static int Lamp_setQuad1( BPy_Lamp * self, PyObject * args );
static int Lamp_setQuad2( BPy_Lamp * self, PyObject * args );
static int Lamp_setCol( BPy_Lamp * self, PyObject * args );
-static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args );
+static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * value );
static PyObject *Lamp_addScriptLink( BPy_Lamp * self, PyObject * args );
static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args );
static int Lamp_setComponent( BPy_Lamp * self, PyObject * value, void * closure );
+static PyObject *Lamp_getFalloffType( BPy_Lamp * self );
+static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value );
/*****************************************************************************/
/* Python BPy_Lamp methods table: */
@@ -306,7 +310,7 @@ static PyMethodDef BPy_Lamp_methods[] = {
"() - return light rgb color triplet"},
{"setName", ( PyCFunction ) GenericLib_setName_with_method, METH_VARARGS,
"(str) - rename Lamp"},
- {"setType", ( PyCFunction ) Lamp_oldsetType, METH_VARARGS,
+ {"setType", ( PyCFunction ) Lamp_oldsetType, METH_O,
"(str) - change Lamp type, which can be 'Lamp', 'Sun', 'Spot', 'Hemi', 'Area', 'Photon'"},
{"setMode", ( PyCFunction ) Lamp_oldsetMode, METH_VARARGS,
"([up to eight str's]) - Set Lamp mode flag(s)"},
@@ -348,7 +352,7 @@ static PyMethodDef BPy_Lamp_methods[] = {
"(float) - change light intensity value #2 for a Quad Lamp"},
{"setCol", ( PyCFunction ) Lamp_oldsetCol, METH_VARARGS,
"(f,f,f) or ([f,f,f]) - change light's rgb color triplet"},
- {"getScriptLinks", ( PyCFunction ) Lamp_getScriptLinks, METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) Lamp_getScriptLinks, METH_O,
"(eventname) - Get a list of this lamp's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, Redraw or Render."},
@@ -468,6 +472,10 @@ static PyGetSetDef BPy_Lamp_getseters[] = {
(getter)Lamp_getType, (setter)Lamp_setType,
"Lamp type",
NULL},
+ {"falloffType",
+ (getter)Lamp_getFalloffType, (setter)Lamp_setFalloffType,
+ "Lamp falloff type",
+ NULL},
{"R",
(getter)Lamp_getComponent, (setter)Lamp_setComponent,
"Lamp color red component",
@@ -779,19 +787,42 @@ static PyObject *Lamp_ModesDict( void )
return Modes;
}
+static PyObject *Lamp_FalloffsDict( void )
+{ /* create the Blender.Lamp.Modes constant dict */
+ PyObject *Falloffs = PyConstant_New( );
+
+ if( Falloffs ) {
+ BPy_constant *c = ( BPy_constant * ) Falloffs;
+
+ PyConstant_Insert( c, "CONSTANT",
+ PyInt_FromLong( LA_FALLOFF_CONSTANT ) );
+ PyConstant_Insert( c, "INVLINEAR",
+ PyInt_FromLong( LA_FALLOFF_INVLINEAR ) );
+ PyConstant_Insert( c, "INVSQUARE",
+ PyInt_FromLong( LA_FALLOFF_INVSQUARE ) );
+ PyConstant_Insert( c, "CUSTOM",
+ PyInt_FromLong( LA_FALLOFF_CURVE ) );
+ PyConstant_Insert( c, "LINQUAD",
+ PyInt_FromLong( LA_FALLOFF_SLIDERS ) );
+ }
+
+ return Falloffs;
+}
+
/*****************************************************************************/
/* Function: Lamp_Init */
/*****************************************************************************/
/* Needed by the Blender module, to register the Blender.Lamp submodule */
PyObject *Lamp_Init( void )
{
- PyObject *submodule, *Types, *Modes;
+ PyObject *submodule, *Types, *Modes, *Falloffs;
if( PyType_Ready( &Lamp_Type ) < 0)
return NULL;
Types = Lamp_TypesDict( );
Modes = Lamp_ModesDict( );
+ Falloffs = Lamp_FalloffsDict( );
submodule =
Py_InitModule3( "Blender.Lamp", M_Lamp_methods, M_Lamp_doc );
@@ -800,6 +831,8 @@ PyObject *Lamp_Init( void )
PyModule_AddObject( submodule, "Types", Types );
if( Modes )
PyModule_AddObject( submodule, "Modes", Modes );
+ if( Falloffs )
+ PyModule_AddObject( submodule, "Falloffs", Falloffs );
PyModule_AddIntConstant( submodule, "RGB", IPOKEY_RGB );
PyModule_AddIntConstant( submodule, "ENERGY", IPOKEY_ENERGY );
@@ -864,221 +897,102 @@ static PyObject *Lamp_copy( BPy_Lamp * self )
static PyObject *Lamp_getType( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->type );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.type attribute" ) );
+ return PyInt_FromLong( self->lamp->type );
}
static PyObject *Lamp_getMode( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->mode );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.mode attribute" ) );
+ return PyInt_FromLong( self->lamp->mode );
}
static PyObject *Lamp_getSamples( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->samp );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.samples attribute" ) );
+ return PyInt_FromLong( self->lamp->samp );
}
static PyObject *Lamp_getRaySamplesX( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->ray_samp );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.raySamplesX attribute" ) );
+ return PyInt_FromLong( self->lamp->ray_samp );
}
static PyObject *Lamp_getRaySamplesY( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->ray_sampy );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.raySamplesY attribute" ) );
+ return PyInt_FromLong( self->lamp->ray_sampy );
}
static PyObject *Lamp_getAreaSizeX( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->area_size );
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.areaSizeX attribute" ) );
+ return PyFloat_FromDouble( self->lamp->area_size );
}
static PyObject *Lamp_getAreaSizeY( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->area_sizey );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.areaSizeY attribute" ) );
+ return PyFloat_FromDouble( self->lamp->area_sizey );
}
static PyObject *Lamp_getBufferSize( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->bufsize );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.bufferSize attribute" ) );
+ return PyInt_FromLong( self->lamp->bufsize );
}
static PyObject *Lamp_getHaloStep( BPy_Lamp * self )
{
- PyObject *attr = PyInt_FromLong( self->lamp->shadhalostep );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.haloStep attribute" ) );
+ return PyInt_FromLong( self->lamp->shadhalostep );
}
static PyObject *Lamp_getEnergy( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->energy );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.energy attribute" ) );
+ return PyFloat_FromDouble( self->lamp->energy );
}
static PyObject *Lamp_getDist( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->dist );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.dist attribute" ) );
+ return PyFloat_FromDouble( self->lamp->dist );
}
static PyObject *Lamp_getSpotSize( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->spotsize );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.spotSize attribute" ) );
+ return PyFloat_FromDouble( self->lamp->spotsize );
}
static PyObject *Lamp_getSpotBlend( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->spotblend );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.spotBlend attribute" ) );
+ return PyFloat_FromDouble( self->lamp->spotblend );
}
static PyObject *Lamp_getClipStart( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->clipsta );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.clipStart attribute" ) );
+ return PyFloat_FromDouble( self->lamp->clipsta );
}
static PyObject *Lamp_getClipEnd( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->clipend );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.clipEnd attribute" ) );
+ return PyFloat_FromDouble( self->lamp->clipend );
}
static PyObject *Lamp_getBias( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->bias );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.bias attribute" ) );
+ return PyFloat_FromDouble( self->lamp->bias );
}
static PyObject *Lamp_getSoftness( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->soft );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.softness attribute" ) );
+ return PyFloat_FromDouble( self->lamp->soft );
}
static PyObject *Lamp_getHaloInt( BPy_Lamp * self )
{
- PyObject *attr = PyFloat_FromDouble( self->lamp->haint );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.haloInt attribute" ) );
+ return PyFloat_FromDouble( self->lamp->haint );
}
static PyObject *Lamp_getQuad1( BPy_Lamp * self )
{ /* should we complain if Lamp is not of type Quad? */
- PyObject *attr = PyFloat_FromDouble( self->lamp->att1 );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.quad1 attribute" ) );
+ return PyFloat_FromDouble( self->lamp->att1 );
}
static PyObject *Lamp_getQuad2( BPy_Lamp * self )
{ /* should we complain if Lamp is not of type Quad? */
- PyObject *attr = PyFloat_FromDouble( self->lamp->att2 );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.quad2 attribute" ) );
+ return PyFloat_FromDouble( self->lamp->att2 );
}
static PyObject *Lamp_getCol( BPy_Lamp * self )
@@ -1086,6 +1000,11 @@ static PyObject *Lamp_getCol( BPy_Lamp * self )
return rgbTuple_getCol( self->color );
}
+static PyObject *Lamp_getFalloffType( BPy_Lamp * self )
+{
+ return PyInt_FromLong( (int)self->lamp->falloff_type );
+}
+
static int Lamp_setType( BPy_Lamp * self, PyObject * value )
{
return EXPP_setIValueRange ( value, &self->lamp->type,
@@ -1107,7 +1026,7 @@ static int Lamp_setMode( BPy_Lamp * self, PyObject * value )
| EXPP_LAMP_MODE_NOSPECULAR
| EXPP_LAMP_MODE_SHAD_RAY;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check ( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -1250,29 +1169,26 @@ static int Lamp_setQuad2( BPy_Lamp * self, PyObject * value )
EXPP_LAMP_QUAD2_MAX );
}
-static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure )
+static int Lamp_setFalloffType( BPy_Lamp * self, PyObject * value )
{
- PyObject *attr = NULL;
+ return EXPP_setIValueRange ( value, &self->lamp->falloff_type,
+ EXPP_LAMP_FALLOFF_MIN, EXPP_LAMP_FALLOFF_MAX, 'h' );
+}
+
+static PyObject *Lamp_getComponent( BPy_Lamp * self, void * closure )
+{
switch ( (int)closure ) {
case EXPP_LAMP_COMP_R:
- attr = PyFloat_FromDouble( self->lamp->r );
- break;
+ return PyFloat_FromDouble( self->lamp->r );
case EXPP_LAMP_COMP_G:
- attr = PyFloat_FromDouble( self->lamp->g );
- break;
+ return PyFloat_FromDouble( self->lamp->g );
case EXPP_LAMP_COMP_B:
- attr = PyFloat_FromDouble( self->lamp->b );
- break;
+ return PyFloat_FromDouble( self->lamp->b );
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"unknown color component specified" );
}
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyFloat_FromDouble() failed" );
- return attr;
}
static int Lamp_setComponent( BPy_Lamp * self, PyObject * value,
@@ -1330,7 +1246,7 @@ static PyObject *Lamp_clearScriptLinks( BPy_Lamp * self, PyObject * args )
}
/* mat.getScriptLinks */
-static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args )
+static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * value )
{
Lamp *lamp = self->lamp;
ScriptLink *slink = NULL;
@@ -1338,7 +1254,7 @@ static PyObject *Lamp_getScriptLinks( BPy_Lamp * self, PyObject * args )
slink = &( lamp )->scriptlink;
- ret = EXPP_getScriptLinks( slink, args, 0 );
+ ret = EXPP_getScriptLinks( slink, value, 0 );
if( ret )
return ret;
@@ -1416,25 +1332,25 @@ static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
map = texchannel_to_adrcode(self->lamp->texact);
if (key == IPOKEY_RGB ) {
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, LA_COL_R);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_G);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_B);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, LA_COL_R, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_G, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_COL_B, 0);
}
if (key == IPOKEY_ENERGY ) {
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_ENERGY);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_ENERGY, 0);
}
if (key == IPOKEY_SPOTSIZE ) {
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_SPOTSI);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL,LA_SPOTSI, 0);
}
if (key == IPOKEY_OFFSET ) {
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_X);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Y);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Z);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_OFS_Z, 0);
}
if (key == IPOKEY_SIZE ) {
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_X);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Y);
- insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey((ID *)self->lamp, ID_LA, NULL, NULL, map+MAP_SIZE_Z, 0);
}
allspace(REMAKEIPO, 0);
@@ -1448,7 +1364,7 @@ static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
static PyObject *Lamp_getModesConst( void )
{
- PyObject * attr = Py_BuildValue
+ return Py_BuildValue
( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
"Shadows", EXPP_LAMP_MODE_SHADOWS, "Halo",
EXPP_LAMP_MODE_HALO, "Layer", EXPP_LAMP_MODE_LAYER,
@@ -1460,29 +1376,17 @@ static PyObject *Lamp_getModesConst( void )
EXPP_LAMP_MODE_NODIFFUSE, "NoSpecular",
EXPP_LAMP_MODE_NOSPECULAR, "RayShadow",
EXPP_LAMP_MODE_SHAD_RAY);
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.Modes attribute" );
-
- return attr;
}
static PyObject *Lamp_getTypesConst( void )
{
- PyObject *attr = Py_BuildValue( "{s:h,s:h,s:h,s:h,s:h,s:h}",
+ return Py_BuildValue( "{s:h,s:h,s:h,s:h,s:h,s:h}",
"Lamp", EXPP_LAMP_TYPE_LAMP,
"Sun", EXPP_LAMP_TYPE_SUN,
"Spot", EXPP_LAMP_TYPE_SPOT,
"Hemi", EXPP_LAMP_TYPE_HEMI,
"Area", EXPP_LAMP_TYPE_AREA,
"Photon", EXPP_LAMP_TYPE_YF_PHOTON );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Lamp.Types attribute" );
-
- return attr;
}
/* #####DEPRECATED###### */
@@ -1613,14 +1517,14 @@ static PyObject *Lamp_clearIpo( BPy_Lamp * self )
* setType() accepts a string while mode setter takes an integer
*/
-static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args )
+static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
{
- char *type;
- PyObject *value, *error;
+ char *type = PyString_AsString(value);
+ PyObject *arg, *error;
/* parse string argument */
- if( !PyArg_ParseTuple( args, "s", &type ) )
+ if( !value )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" ) );
@@ -1644,9 +1548,9 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * args )
/* build tuple, call wrapper */
- value = PyInt_FromLong( (long)type );
- error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setType );
- Py_DECREF ( value );
+ arg = Py_BuildValue( "(i)", type );
+ error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
+ Py_DECREF ( arg );
return error;
}
@@ -1703,7 +1607,7 @@ static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args )
/* build tuple, call wrapper */
- value = PyInt_FromLong( (long)flag );
+ value = Py_BuildValue( "(i)", flag );
error = EXPP_setterWrapper ( (void *)self, value, (setter)Lamp_setMode );
Py_DECREF ( value );
return error;
diff --git a/source/blender/python/api2_2x/Lattice.c b/source/blender/python/api2_2x/Lattice.c
index 7ea8aabfc04..070e8225531 100644
--- a/source/blender/python/api2_2x/Lattice.c
+++ b/source/blender/python/api2_2x/Lattice.c
@@ -69,7 +69,7 @@ static char M_Lattice_doc[] = "The Blender Lattice module\n\n";
static char M_Lattice_New_doc[] = "() - return a new Lattice object";
-static char M_Lattice_Get_doc[] = "() - geta a Lattice from blender";
+static char M_Lattice_Get_doc[] = "() - get a Lattice from blender";
/*****************************************************************************/
/* Python method structure definition for Blender.Lattice module: */
@@ -708,13 +708,13 @@ static PyObject *Lattice_getAxisType(BPy_Lattice * self, void * type)
static PyGetSetDef BPy_Lattice_getseters[] = {
GENERIC_LIB_GETSETATTR,
{"width", (getter)Lattice_getWidth, (setter)NULL,
- "lattice U sibdivision ", NULL},
+ "lattice U subdivision ", NULL},
{"height", (getter)Lattice_getHeight, (setter)NULL,
- "lattice V sibdivision", NULL},
+ "lattice V subdivision", NULL},
{"depth", (getter)Lattice_getDepth, (setter)NULL,
- "lattice W sibdivision", NULL},
+ "lattice W subdivision", NULL},
{"latSize", (getter)Lattice_getLatSize, (setter)NULL,
- "lattice W sibdivision", NULL},
+ "lattice W subdivision", NULL},
{"widthType", (getter)Lattice_getAxisType, NULL,
"lattice U interpolation type", (void *)0},
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 495f6eabf44..1aacaf56786 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -67,7 +67,7 @@ static PyObject *M_Library_Open( PyObject * self, PyObject * args );
static PyObject *M_Library_Close( PyObject * self );
static PyObject *M_Library_GetName( PyObject * self );
static PyObject *M_Library_Update( PyObject * self );
-static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args );
+static PyObject *M_Library_Datablocks( PyObject * self, PyObject * value );
static PyObject *oldM_Library_Load( PyObject * self, PyObject * args );
static PyObject *M_Library_LinkableGroups( PyObject * self );
static PyObject *M_Library_LinkedLibs( PyObject * self );
@@ -123,14 +123,14 @@ static char Library_LinkedLibs_doc[] =
* Python method structure definition for Blender.Library submodule.
*/
struct PyMethodDef oldM_Library_methods[] = {
- {"Open", M_Library_Open, METH_VARARGS, Library_Open_doc},
+ {"Open", M_Library_Open, METH_O, Library_Open_doc},
{"Close", ( PyCFunction ) M_Library_Close, METH_NOARGS,
Library_Close_doc},
{"GetName", ( PyCFunction ) M_Library_GetName, METH_NOARGS,
Library_GetName_doc},
{"Update", ( PyCFunction ) M_Library_Update, METH_NOARGS,
Library_Update_doc},
- {"Datablocks", M_Library_Datablocks, METH_VARARGS,
+ {"Datablocks", M_Library_Datablocks, METH_O,
Library_Datablocks_doc},
{"Load", oldM_Library_Load, METH_VARARGS, Library_Load_doc},
{"LinkableGroups", ( PyCFunction ) M_Library_LinkableGroups,
@@ -147,9 +147,9 @@ struct PyMethodDef oldM_Library_methods[] = {
* Only one can be open at a time, so this function also closes
* the previously opened file, if any.
*/
-static PyObject *M_Library_Open( PyObject * self, PyObject * args )
+static PyObject *M_Library_Open( PyObject * self, PyObject * value )
{
- char *fname = NULL;
+ char *fname = PyString_AsString(value);
char filename[FILE_MAXDIR+FILE_MAXFILE];
char fname1[FILE_MAXDIR+FILE_MAXFILE];
@@ -157,7 +157,7 @@ static PyObject *M_Library_Open( PyObject * self, PyObject * args )
bpy_relative= 0; /* assume non relative each time we load */
- if( !PyArg_ParseTuple( args, "s", &fname ) ) {
+ if( !fname ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a .blend filename" );
}
@@ -244,9 +244,9 @@ static PyObject *M_Library_GetName( PyObject * self )
* Return a list with all items of a given datablock type
* (like 'Object', 'Mesh', etc.) in the open library file.
*/
-static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args )
+static PyObject *M_Library_Datablocks( PyObject * self, PyObject * value )
{
- char *name = NULL;
+ char *name = PyString_AsString(value);
int blocktype = 0;
LinkNode *l = NULL, *names = NULL;
PyObject *list = NULL;
@@ -256,7 +256,7 @@ static PyObject *M_Library_Datablocks( PyObject * self, PyObject * args )
"no library file: open one first with Blender.Lib_Open(filename)" );
}
- if( !PyArg_ParseTuple( args, "s", &name ) ) {
+ if( !name ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string (datablock type) as argument." );
}
@@ -526,13 +526,13 @@ static PyObject *CreatePyObject_LibData( int idtype, int kind,
* which can be linked/appended to a scene.
*/
-static PyObject *lib_link_or_append( BPy_LibraryData *self, PyObject * args,
+static PyObject *lib_link_or_append( BPy_LibraryData *self, PyObject * value,
int mode )
{
- char *name;
+ char *name = PyString_AsString(value);
/* get the name of the data used wants to append */
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string" );
@@ -672,16 +672,16 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
/* .append(): make a local copy of the library's data (except for objects) */
-static PyObject *LibraryData_getAppend( BPy_LibraryData *self, PyObject * args)
+static PyObject *LibraryData_getAppend( BPy_LibraryData *self, PyObject * value)
{
- return lib_link_or_append( self, args, OBJECT_IS_APPEND );
+ return lib_link_or_append( self, value, OBJECT_IS_APPEND );
}
/* .link(): make a link to the library's data (except for objects) */
-static PyObject *LibraryData_getLink( BPy_LibraryData *self, PyObject * args)
+static PyObject *LibraryData_getLink( BPy_LibraryData *self, PyObject * value)
{
- return lib_link_or_append( self, args, OBJECT_IS_LINK );
+ return lib_link_or_append( self, value, OBJECT_IS_LINK );
}
/************************************************************************
@@ -745,9 +745,9 @@ static PyObject *LibraryData_nextIter( BPy_LibraryData * self )
************************************************************************/
static struct PyMethodDef BPy_LibraryData_methods[] = {
- {"append", (PyCFunction)LibraryData_getAppend, METH_VARARGS,
+ {"append", (PyCFunction)LibraryData_getAppend, METH_O,
"(str) - create new data from library"},
- {"link", (PyCFunction)LibraryData_getLink, METH_VARARGS,
+ {"link", (PyCFunction)LibraryData_getLink, METH_O,
"(str) - link data from library"},
{NULL, NULL, 0, NULL}
};
@@ -1060,12 +1060,12 @@ static PyGetSetDef Library_getseters[] = {
* actually accessed later.
*/
-static PyObject *M_Library_Load(PyObject *self, PyObject * args)
+static PyObject *M_Library_Load(PyObject *self, PyObject * value)
{
- char *filename;
+ char *filename = PyString_AsString(value);
BPy_Library *lib;
- if( !PyArg_ParseTuple( args, "s", &filename ) )
+ if( !filename )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string" );
@@ -1081,7 +1081,7 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * args)
}
static struct PyMethodDef M_Library_methods[] = {
- {"load", (PyCFunction)M_Library_Load, METH_VARARGS,
+ {"load", (PyCFunction)M_Library_Load, METH_O,
"(string) - declare a .blend file for use as a library"},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/Makefile b/source/blender/python/api2_2x/Makefile
index f49d7c3320e..488c81c7100 100644
--- a/source/blender/python/api2_2x/Makefile
+++ b/source/blender/python/api2_2x/Makefile
@@ -38,13 +38,15 @@ CSRCS ?= $(wildcard *.c) $(wildcard ../*.c)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
- CFLAGS += -fno-strict-aliasing
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
+ifeq ($(WITH_FFMPEG), true)
+ CPPFLAGS += -DWITH_FFMPEG
+endif
+
+ifeq ($(WITH_OPENEXR),true)
+ CPPFLAGS += -DWITH_OPENEXR
+endif
CPPFLAGS += -I$(OPENGL_HEADERS)
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c
index 019c3d750b9..fc697bee343 100644
--- a/source/blender/python/api2_2x/Material.c
+++ b/source/blender/python/api2_2x/Material.c
@@ -367,6 +367,8 @@ static PyObject *Material_ModesDict( void )
PyConstant_Insert(c, "TANGENT_V", PyInt_FromLong(MA_TANGENT_V));
PyConstant_Insert(c, "NMAP_TS", PyInt_FromLong(MA_NORMAP_TANG));
PyConstant_Insert(c, "GROUP_EXCLUSIVE", PyInt_FromLong(MA_GROUP_NOLAY));
+ PyConstant_Insert(c, "TEXFACE_ALPHA", PyInt_FromLong(MA_FACETEXTURE_ALPHA));
+
}
return Modes;
@@ -621,9 +623,9 @@ static PyObject *Material_getTextures( BPy_Material * self );
static PyObject *Material_clearIpo( BPy_Material * self );
static PyObject *Material_setTexture( BPy_Material * self, PyObject * args );
-static PyObject *Material_clearTexture( BPy_Material * self, PyObject * args );
+static PyObject *Material_clearTexture( BPy_Material * self, PyObject * value );
-static PyObject *Material_getScriptLinks(BPy_Material *self, PyObject * args );
+static PyObject *Material_getScriptLinks(BPy_Material *self, PyObject * value );
static PyObject *Material_addScriptLink(BPy_Material * self, PyObject * args );
static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args);
@@ -840,10 +842,9 @@ static PyMethodDef BPy_Material_methods[] = {
"(f) - Set fresnel power for refractions factor- [0.0, 5.0]"},
{"setTexture", ( PyCFunction ) Material_setTexture, METH_VARARGS,
"(n,tex,texco=0,mapto=0) - Set numbered texture to tex"},
- {"clearTexture", ( PyCFunction ) Material_clearTexture, METH_VARARGS,
+ {"clearTexture", ( PyCFunction ) Material_clearTexture, METH_O,
"(n) - Remove texture from numbered slot"},
- {"getScriptLinks", ( PyCFunction ) Material_getScriptLinks,
- METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) Material_getScriptLinks, METH_O,
"(eventname) - Get a list of this material's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, Redraw or Render."},
@@ -1114,11 +1115,11 @@ static PyGetSetDef BPy_Material_getseters[] = {
(void *) EXPP_MAT_COMP_B },
{"colorbandDiffuse",
(getter)Material_getColorband, (setter)Material_setColorband,
- "Set the light group for this material",
+ "The diffuse colorband for this material",
(void *) 0},
{"colorbandSpecular",
(getter)Material_getColorband, (setter)Material_setColorband,
- "Set the light group for this material",
+ "The specular colorband for this material",
(void *) 1},
/* SSS settings */
@@ -1320,12 +1321,6 @@ PyObject *Material_CreatePyObject( struct Material *mat )
pymat->spec = ( BPy_rgbTuple * ) rgbTuple_New( spec );
pymat->mir = ( BPy_rgbTuple * ) rgbTuple_New( mir );
pymat->sss = ( BPy_rgbTuple * ) rgbTuple_New( sss );
-
- Py_INCREF(pymat->col);
- Py_INCREF(pymat->amb);
- Py_INCREF(pymat->spec);
- Py_INCREF(pymat->mir);
- Py_INCREF(pymat->sss);
return ( PyObject * ) pymat;
}
@@ -1352,13 +1347,7 @@ static PyObject *Material_getIpo( BPy_Material * self )
static PyObject *Material_getMode( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->mode );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.Mode attribute" );
+ return PyInt_FromLong( ( long ) self->material->mode );
}
static PyObject *Material_getRGBCol( BPy_Material * self )
@@ -1389,494 +1378,217 @@ static PyObject *Material_getSssCol( BPy_Material * self )
static PyObject *Material_getSpecShader( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->spec_shader );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.specShader attribute" );
+ return PyInt_FromLong( ( long ) self->material->spec_shader );
}
static PyObject *Material_getDiffuseShader( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->diff_shader );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.diffuseShader attribute" );
+ return PyInt_FromLong( ( long ) self->material->diff_shader );
}
static PyObject *Material_getRoughness( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->roughness );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.roughness attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->roughness );
}
static PyObject *Material_getSpecSize( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.specSize attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->param[2] );
}
static PyObject *Material_getDiffuseSize( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[0] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.diffuseSize attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->param[0] );
}
static PyObject *Material_getSpecSmooth( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[3] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.specSmooth attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->param[3] );
}
static PyObject *Material_getDiffuseSmooth( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->param[1] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.diffuseSmooth( attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->param[1] );
}
static PyObject *Material_getDiffuseDarkness( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->darkness );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.diffuseDarkness attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->darkness );
}
static PyObject *Material_getRefracIndex( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->refrac );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.refracIndex attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->refrac );
}
static PyObject *Material_getRms( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->rms );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.rms attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->rms );
}
static PyObject *Material_getAmb( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->amb );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.amb attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->amb );
}
static PyObject *Material_getEmit( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->emit );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.emit attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->emit );
}
static PyObject *Material_getAlpha( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->alpha );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.alpha attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->alpha );
}
static PyObject *Material_getShadAlpha( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->shad_alpha );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.shad_alpha attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->shad_alpha );
}
static PyObject *Material_getRef( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->ref );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.ref attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->ref );
}
static PyObject *Material_getSpec( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->spec );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.spec attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->spec );
}
static PyObject *Material_getSpecTransp( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->spectra );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.specTransp attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->spectra );
}
static PyObject *Material_getAdd( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->add );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.add attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->add );
}
static PyObject *Material_getZOffset( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->zoffs );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.zOffset attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->zoffs );
}
static PyObject *Material_getLightGroup( BPy_Material * self )
{
- PyObject *attr =
- Group_CreatePyObject( self->material->group );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.lightGroup attribute" );
+ return Group_CreatePyObject( self->material->group );
}
static PyObject *Material_getHaloSize( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->hasize );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.haloSize attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->hasize );
}
static PyObject *Material_getFlareSize( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->flaresize );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.flareSize attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->flaresize );
}
static PyObject *Material_getFlareBoost( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->flareboost );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.flareBoost attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->flareboost );
}
static PyObject *Material_getSubSize( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->subsize );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.subSize attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->subsize );
}
static PyObject *Material_getHaloSeed( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->seed1 );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.haloSeed attribute" );
+ return PyInt_FromLong( ( long ) self->material->seed1 );
}
static PyObject *Material_getFlareSeed( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->seed2 );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.flareSeed attribute" );
+ return PyInt_FromLong( ( long ) self->material->seed2 );
}
static PyObject *Material_getHardness( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->har );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.hard attribute" );
+ return PyInt_FromLong( ( long ) self->material->har );
}
static PyObject *Material_getNFlares( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->flarec );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.nFlares attribute" );
+ return PyInt_FromLong( ( long ) self->material->flarec );
}
static PyObject *Material_getNStars( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->starc );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.nStars attribute" );
+ return PyInt_FromLong( ( long ) self->material->starc );
}
static PyObject *Material_getNLines( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->linec );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.nLines attribute" );
+ return PyInt_FromLong( ( long ) self->material->linec );
}
static PyObject *Material_getNRings( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->ringc );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.nRings attribute" );
+ return PyInt_FromLong( ( long ) self->material->ringc );
}
static PyObject *Material_getRayMirr( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->ray_mirror );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.rayMirr attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->ray_mirror );
}
static PyObject *Material_getMirrDepth( BPy_Material * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->material->ray_depth );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.rayMirrDepth attribute" );
+ return PyInt_FromLong( ( long ) self->material->ray_depth );
}
static PyObject *Material_getFresnelMirr( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->fresnel_mir );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.fresnelDepth attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->fresnel_mir );
}
static PyObject *Material_getFresnelMirrFac( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->fresnel_mir_i );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.fresnelDepthFac attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->fresnel_mir_i );
}
static PyObject *Material_getFilter( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->filter );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.filter attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->filter );
}
static PyObject *Material_getTranslucency( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->translucency );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.translucency attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->translucency );
}
static PyObject *Material_getIOR( BPy_Material * self )
{
- PyObject *attr = PyFloat_FromDouble( ( double ) self->material->ang );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.IOR attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->ang );
}
static PyObject *Material_getTransDepth( BPy_Material * self )
{
- PyObject *attr =
- PyInt_FromLong( ( long ) self->material->ray_depth_tra );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.transDepth attribute" );
+ return PyInt_FromLong( ( long ) self->material->ray_depth_tra );
}
static PyObject *Material_getFresnelTrans( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->fresnel_tra );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.fresnelTrans attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->fresnel_tra );
}
static PyObject *Material_getFresnelTransFac( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->fresnel_tra_i );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.fresnelTransFac attribute" );
+ return PyFloat_FromDouble( ( double ) self->material->fresnel_tra_i );
}
static PyObject* Material_getRigidBodyFriction( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->friction );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.friction" );
+ return PyFloat_FromDouble( ( double ) self->material->friction );
}
static PyObject* Material_getRigidBodyRestitution( BPy_Material * self )
{
- PyObject *attr =
- PyFloat_FromDouble( ( double ) self->material->reflect );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Material.reflect" );
+ return PyFloat_FromDouble( ( double ) self->material->reflect );
}
/* SSS */
@@ -1981,58 +1693,58 @@ static PyObject *Material_insertIpoKey( BPy_Material * self, PyObject * args )
map = texchannel_to_adrcode(self->material->texact);
if(key==IPOKEY_RGB || key==IPOKEY_ALLCOLOR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_R);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_G);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_B);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_R, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_G, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_COL_B, 0);
}
if(key==IPOKEY_ALPHA || key==IPOKEY_ALLCOLOR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_ALPHA);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_ALPHA, 0);
}
if(key==IPOKEY_HALOSIZE || key==IPOKEY_ALLCOLOR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_HASIZE);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_HASIZE, 0);
}
if(key==IPOKEY_MODE || key==IPOKEY_ALLCOLOR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_MODE);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_MODE, 0);
}
if(key==IPOKEY_ALLCOLOR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_R);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_G);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_B);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_REF);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_EMIT);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_AMB);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_HARD);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_MODE);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_TRANSLU);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_ADD);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_R, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_G, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC_B, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_REF, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_EMIT, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_AMB, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_SPEC, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_HARD, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_MODE, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_TRANSLU, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_ADD, 0);
}
if(key==IPOKEY_ALLMIRROR) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_RAYM);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESMIR);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESMIRI);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESTRA);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESTRAI);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_RAYM, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESMIR, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESMIRI, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESTRA, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, MA_FRESTRAI, 0);
}
if(key==IPOKEY_OFS || key==IPOKEY_ALLMAPPING) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_X);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_Y);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_Z);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_OFS_Z, 0);
}
if(key==IPOKEY_SIZE || key==IPOKEY_ALLMAPPING) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_X);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_Y);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_SIZE_Z, 0);
}
if(key==IPOKEY_ALLMAPPING) {
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_R);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_G);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_B);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_DVAR);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_COLF);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_NORF);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_VARF);
- insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_DISP);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_R, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_G, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_B, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_DVAR, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_COLF, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_NORF, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_VARF, 0);
+ insertkey((ID *)self->material, ID_MA, NULL, NULL, map+MAP_DISP, 0);
}
allspace(REMAKEIPO, 0);
@@ -2048,7 +1760,7 @@ static int Material_setMode( BPy_Material * self, PyObject * value )
{
int param;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%08x", MA_MODE_MASK );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -2548,14 +2260,11 @@ static PyObject *Material_setTexture( BPy_Material * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Material_clearTexture( BPy_Material * self, PyObject * args )
+static PyObject *Material_clearTexture( BPy_Material * self, PyObject * value )
{
- int texnum;
+ int texnum = (int)PyInt_AsLong(value);
struct MTex *mtex;
-
- if( !PyArg_ParseTuple( args, "i", &texnum ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected int in [0,9]" );
+ /* non ints will be -1 */
if( ( texnum < 0 ) || ( texnum >= MAX_MTEX ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int in [0,9]" );
@@ -2595,7 +2304,7 @@ static PyObject *Material_clearScriptLinks(BPy_Material *self, PyObject *args )
/* mat.getScriptLinks */
static PyObject *Material_getScriptLinks( BPy_Material * self,
- PyObject * args )
+ PyObject * value )
{
Material *mat = self->material;
ScriptLink *slink = NULL;
@@ -2606,7 +2315,7 @@ static PyObject *Material_getScriptLinks( BPy_Material * self,
/* can't this just return? EXP_getScriptLinks() returns a PyObject*
* or NULL anyway */
- ret = EXPP_getScriptLinks( slink, args, 0 );
+ ret = EXPP_getScriptLinks( slink, value, 0 );
if( ret )
return ret;
@@ -2930,54 +2639,35 @@ void EXPP_incr_mats_us( Material ** matlist, int len )
static PyObject *Material_getColorComponent( BPy_Material * self,
void * closure )
{
- PyObject *attr = NULL;
-
switch ( (int)closure ) {
case EXPP_MAT_COMP_R:
- attr = PyFloat_FromDouble( ( double ) self->material->r );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->r );
case EXPP_MAT_COMP_G:
- attr = PyFloat_FromDouble( ( double ) self->material->g );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->g );
case EXPP_MAT_COMP_B:
- attr = PyFloat_FromDouble( ( double ) self->material->b );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->b );
case EXPP_MAT_COMP_SPECR:
- attr = PyFloat_FromDouble( ( double ) self->material->specr );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->specr );
case EXPP_MAT_COMP_SPECG:
- attr = PyFloat_FromDouble( ( double ) self->material->specg );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->specg );
case EXPP_MAT_COMP_SPECB:
- attr = PyFloat_FromDouble( ( double ) self->material->specb );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->specb );
case EXPP_MAT_COMP_MIRR:
- attr = PyFloat_FromDouble( ( double ) self->material->mirr );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->mirr );
case EXPP_MAT_COMP_MIRG:
- attr = PyFloat_FromDouble( ( double ) self->material->mirg );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->mirg );
case EXPP_MAT_COMP_MIRB:
- attr = PyFloat_FromDouble( ( double ) self->material->mirb );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->mirb );
case EXPP_MAT_COMP_SSSR:
- attr = PyFloat_FromDouble( ( double ) self->material->sss_col[0] );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->sss_col[0] );
case EXPP_MAT_COMP_SSSG:
- attr = PyFloat_FromDouble( ( double ) self->material->sss_col[1] );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->sss_col[1] );
case EXPP_MAT_COMP_SSSB:
- attr = PyFloat_FromDouble( ( double ) self->material->sss_col[2] );
- break;
+ return PyFloat_FromDouble( ( double ) self->material->sss_col[2] );
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"unknown color component specified" );
}
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyFloat_FromDouble() failed" );
- return attr;
}
static PyObject *Material_getColorband( BPy_Material * self, void * type)
@@ -3330,7 +3020,7 @@ static PyObject *Matr_oldsetMode( BPy_Material * self, PyObject * args )
"expected nothing, an integer or up to 22 string argument(s)" ) );
/* build tuple, call wrapper */
- value = PyInt_FromLong( (long)flag );
+ value = Py_BuildValue("(i)", flag);
error = EXPP_setterWrapper( (void *)self, value, (setter)Material_setMode );
Py_DECREF ( value );
return error;
diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c
index 35db6bfcadf..65ae46ffccd 100644
--- a/source/blender/python/api2_2x/Mathutils.c
+++ b/source/blender/python/api2_2x/Mathutils.c
@@ -59,7 +59,7 @@ static char M_Mathutils_ScaleMatrix_doc[] = "() - construct a scaling matrix fro
static char M_Mathutils_OrthoProjectionMatrix_doc[] = "() - construct a orthographic projection matrix from a selected plane";
static char M_Mathutils_ShearMatrix_doc[] = "() - construct a shearing matrix from a plane of shear and a shear factor";
static char M_Mathutils_CopyMat_doc[] = "() - create a copy of a matrix";
-static char M_Mathutils_TranslationMatrix_doc[] = "() - create a translation matrix from a vector";
+static char M_Mathutils_TranslationMatrix_doc[] = "(vec) - create a translation matrix from a vector";
static char M_Mathutils_CopyQuat_doc[] = "() - copy quatB to quatA";
static char M_Mathutils_CopyEuler_doc[] = "() - copy eulB to eultA";
static char M_Mathutils_CrossQuats_doc[] = "() - return the mutliplication of two quaternions";
@@ -88,7 +88,7 @@ struct PyMethodDef M_Mathutils_methods[] = {
{"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc},
{"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc},
{"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc},
- {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_VARARGS, M_Mathutils_TranslationMatrix_doc},
+ {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc},
{"CopyMat", (PyCFunction) M_Mathutils_CopyMat, METH_VARARGS, M_Mathutils_CopyMat_doc},
{"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix, METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
{"MatMultVec", (PyCFunction) M_Mathutils_MatMultVec, METH_VARARGS, M_Mathutils_MatMultVec_doc},
@@ -460,10 +460,10 @@ PyObject *M_Mathutils_DotVecs(PyObject * self, PyObject * args)
if(!PyArg_ParseTuple(args, "O!O!", &vector_Type, &vec1, &vector_Type, &vec2))
return EXPP_ReturnPyObjError(PyExc_TypeError,
- "Mathutils.DotVec(): expects (2) vector objects of the same size\n");
+ "Mathutils.DotVecs(): expects (2) vector objects of the same size\n");
if(vec1->size != vec2->size)
return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Mathutils.DotVec(): expects (2) vector objects of the same size\n");
+ "Mathutils.DotVecs(): expects (2) vector objects of the same size\n");
for(x = 0; x < vec1->size; x++) {
dot += vec1->vec[x] * vec2->vec[x];
@@ -500,10 +500,7 @@ PyObject *M_Mathutils_AngleBetweenVecs(PyObject * self, PyObject * args)
}
dot /= (sqrt(test_v1) * sqrt(test_v2));
- if (dot < -1.0f || dot > 1.0f) {
- CLAMP(dot,-1.0f,1.0f);
- }
- angleRads = (double)acos(dot);
+ angleRads = (double)saacos(dot);
return PyFloat_FromDouble(angleRads * (180/ Py_PI));
@@ -773,13 +770,12 @@ PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
}
//----------------------------------Mathutils.TranslationMatrix() -------
//creates a translation matrix
-PyObject *M_Mathutils_TranslationMatrix(PyObject * self, PyObject * args)
+PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
{
- VectorObject *vec = NULL;
float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-
- if(!PyArg_ParseTuple(args, "O!", &vector_Type, &vec)) {
+
+ if(!VectorObject_Check(vec)) {
return EXPP_ReturnPyObjError(PyExc_TypeError,
"Mathutils.TranslationMatrix(): expected vector\n");
}
diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h
index 84890267ed2..901cb2139d7 100644
--- a/source/blender/python/api2_2x/Mathutils.h
+++ b/source/blender/python/api2_2x/Mathutils.h
@@ -57,7 +57,7 @@ PyObject *M_Mathutils_MidpointVecs(PyObject * self, PyObject * args);
PyObject *M_Mathutils_ProjectVecs(PyObject * self, PyObject * args);
PyObject *M_Mathutils_Matrix(PyObject * self, PyObject * args);
PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args);
-PyObject *M_Mathutils_TranslationMatrix(PyObject * self, PyObject * args);
+PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * value);
PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args);
PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args);
PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args);
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index bd78900f625..803c0b96ef3 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -60,6 +60,7 @@
#include "BKE_mesh.h"
#include "BKE_material.h"
#include "BKE_main.h"
+#include "BKE_multires.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_DerivedMesh.h"
@@ -125,6 +126,8 @@ static PyObject *MEdgeSeq_CreatePyObject( Mesh * mesh );
static PyObject *MFace_CreatePyObject( Mesh * mesh, int i );
static PyObject *MEdge_CreatePyObject( Mesh * mesh, int i );
+#define MFACE_VERT_BADRANGE_CHECK(me, face) ((int)face->v1 >= me->totvert || (int)face->v2 >= me->totvert || (int)face->v3 >= me->totvert || (int)face->v4 >= me->totvert)
+#define MEDGE_VERT_BADRANGE_CHECK(me, edge) ((int)edge->v1 >= me->totvert || (int)edge->v2 >= me->totvert)
/************************************************************************
*
@@ -587,7 +590,6 @@ static unsigned int make_vertex_table( unsigned int *vert_table, int count )
static PyObject *MCol_getAttr( BPy_MCol * self, void *type )
{
unsigned char param;
- PyObject *attr;
switch( (long)type ) {
case 'R': /* these are backwards, but that how it works */
@@ -611,12 +613,7 @@ static PyObject *MCol_getAttr( BPy_MCol * self, void *type )
}
}
- attr = PyInt_FromLong( param );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed");
+ return PyInt_FromLong( param );
}
/*
@@ -684,7 +681,6 @@ static PyGetSetDef BPy_MCol_getseters[] = {
static PyObject *MCol_item(BPy_MCol * self, int i)
{
unsigned char param;
- PyObject *attr;
switch (i) {
case 0:
param = self->color->b;
@@ -703,12 +699,7 @@ static PyObject *MCol_item(BPy_MCol * self, int i)
"vector[index] = x: assignment index out of range\n");
}
- attr = PyInt_FromLong( param );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed");
+ return PyInt_FromLong( param );
}
/*----------------------------object[]-------------------------
@@ -924,18 +915,11 @@ static int MVert_setCoord( BPy_MVert * self, VectorObject * value )
static PyObject *MVert_getIndex( BPy_MVert * self )
{
- PyObject *attr;
-
if( self->index >= ((Mesh *)self->data)->totvert )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"MVert is no longer valid" );
- attr = PyInt_FromLong( self->index );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->index );
}
@@ -947,11 +931,9 @@ static PyObject *MVert_getMFlagBits( BPy_MVert * self, void * type )
{
MVert *v;
- v = MVert_get_pointer( self );
-
- if( self->index >= ((Mesh *)self->data)->totvert )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "MVert is no longer valid" );
+ v = MVert_get_pointer( self );
+ if (!v)
+ return NULL; /* error is set */
return EXPP_getBitfield( &v->flag, (int)((long)type & 0xff), 'b' );
}
@@ -968,9 +950,8 @@ static int MVert_setMFlagBits( BPy_MVert * self, PyObject * value,
v = MVert_get_pointer( self );
- if( self->index >= ((Mesh *)self->data)->totvert )
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "MVert is no longer valid" );
+ if (!v)
+ return -1; /* error is set */
return EXPP_setBitfield( value, &v->flag,
(int)((long)type & 0xff), 'b' );
@@ -989,7 +970,7 @@ static PyObject *MVert_getNormal( BPy_MVert * self )
v = MVert_get_pointer( self );
if( !v )
- return NULL;
+ return NULL; /* error set */
for( i = 0; i < 3; ++i )
no[i] = (float)(v->no[i] / 32767.0);
@@ -1008,7 +989,7 @@ static int MVert_setNormal( BPy_MVert * self, VectorObject * value )
v = MVert_get_pointer( self );
if( !v )
- return -1;
+ return -1; /* error set */
if( !VectorObject_Check( value ) || value->size != 3 )
return EXPP_ReturnIntError( PyExc_TypeError,
@@ -1037,7 +1018,7 @@ static PyObject *MVert_getSel( BPy_MVert *self )
v = MVert_get_pointer( self );
if( !v )
- return NULL;
+ return NULL; /* error is set */
return EXPP_getBitfield( &v->flag, SELECT, 'b' );
}
@@ -1050,6 +1031,8 @@ static int MVert_setSel( BPy_MVert *self, PyObject *value )
{
MVert *v = MVert_get_pointer( self );
Mesh *me = (Mesh *)self->data;
+ if (!v)
+ return -1; /* error is set */
/*
* if vertex exists and setting status is OK, delete select storage
@@ -1226,6 +1209,239 @@ static long MVert_hash( BPy_MVert *self )
return (long)self->index;
}
+static PyObject *Mesh_addPropLayer_internal(Mesh *mesh, CustomData *data, int tot, PyObject *args)
+{
+ char *name=NULL;
+ int type = -1;
+
+ if( !PyArg_ParseTuple( args, "si", &name, &type) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected a string and an int" );
+ if (strlen(name)>31)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum name length is 31");
+ if((type != CD_PROP_FLT) && (type != CD_PROP_INT) && (type != CD_PROP_STR))
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, unknown layer type");
+ if (name)
+ CustomData_add_layer_named(data, type, CD_DEFAULT, NULL,tot,name);
+
+ mesh_update_customdata_pointers(mesh);
+ Py_RETURN_NONE;
+}
+
+static PyObject *Mesh_removePropLayer_internal(Mesh *mesh, CustomData *data, int tot,PyObject *value)
+{
+ CustomDataLayer *layer;
+ char *name=PyString_AsString(value);
+ int i;
+
+ if( !name )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected string argument" );
+
+ if (strlen(name)>31)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum name length is 31" );
+
+ i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name);
+ if (i==-1)
+ return EXPP_ReturnPyObjError(PyExc_ValueError,
+ "No matching layers to remove" );
+ layer = &data->layers[i];
+ CustomData_free_layer(data, layer->type, tot, i);
+ mesh_update_customdata_pointers(mesh);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *Mesh_renamePropLayer_internal(Mesh *mesh, CustomData *data, PyObject *args)
+{
+ CustomDataLayer *layer;
+ int i;
+ char *name_from, *name_to;
+
+ if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected 2 strings" );
+
+ if (strlen(name_from)>31 || strlen(name_to)>31)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum name length is 31" );
+
+ i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name_from);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name_from);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name_from);
+ if(i == -1)
+ return EXPP_ReturnPyObjError(PyExc_ValueError,
+ "No matching layers to rename" );
+
+ layer = &data->layers[i];
+
+ strcpy(layer->name, name_to); /* we alredy know the string sizes are under 32 */
+ CustomData_set_layer_unique_name(data, i);
+ Py_RETURN_NONE;
+}
+
+static PyObject *Mesh_propList_internal(CustomData *data)
+{
+ CustomDataLayer *layer;
+ PyObject *list = PyList_New( 0 ), *item;
+ int i;
+ for(i=0; i<data->totlayer; i++) {
+ layer = &data->layers[i];
+ if( (layer->type == CD_PROP_FLT) || (layer->type == CD_PROP_INT) || (layer->type == CD_PROP_STR)) {
+ item = PyString_FromString(layer->name);
+ PyList_Append( list, item );
+ Py_DECREF(item);
+ }
+ }
+ return list;
+}
+
+static PyObject *Mesh_getProperty_internal(CustomData *data, int eindex, PyObject *value)
+{
+ CustomDataLayer *layer;
+ char *name=PyString_AsString(value);
+ int i;
+ MFloatProperty *pf;
+ MIntProperty *pi;
+ MStringProperty *ps;
+
+ if(!name)
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected an string argument" );
+
+ if (strlen(name)>31)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum name length is 31" );
+
+ i = CustomData_get_named_layer_index(data, CD_PROP_FLT, name);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_INT, name);
+ if(i == -1) i = CustomData_get_named_layer_index(data, CD_PROP_STR, name);
+ if(i == -1)
+ return EXPP_ReturnPyObjError(PyExc_ValueError,
+ "No matching layers" );
+
+ layer = &data->layers[i];
+
+ if(layer->type == CD_PROP_FLT){
+ pf = layer->data;
+ return PyFloat_FromDouble(pf[eindex].f);
+ }
+ else if(layer->type == CD_PROP_INT){
+ pi = layer->data;
+ return PyInt_FromLong(pi[eindex].i);
+
+ }
+ else if(layer->type == CD_PROP_STR){
+ ps = layer->data;
+ return PyString_FromString(ps[eindex].s);
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *Mesh_setProperty_internal(CustomData *data, int eindex, PyObject *args)
+{
+ CustomDataLayer *layer;
+ int i = 0, index, type = -1;
+ float f = 0.0f;
+ char *s=NULL, *name=NULL;
+ MFloatProperty *pf;
+ MIntProperty *pi;
+ MStringProperty *ps;
+ PyObject *val;
+
+ if(PyArg_ParseTuple(args, "sO", &name, &val)){
+ if (strlen(name)>31)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum name length is 31" );
+
+ if(PyInt_Check(val)){
+ type = CD_PROP_INT;
+ i = (int)PyInt_AS_LONG(val);
+ }
+ else if(PyFloat_Check(val)){
+ type = CD_PROP_FLT;
+ f = (float)PyFloat_AsDouble(val);
+ }
+ else if(PyString_Check(val)){
+ type = CD_PROP_STR;
+ s = PyString_AsString(val);
+ }
+ else
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected an name plus either float/int/string" );
+
+ }
+
+ index = CustomData_get_named_layer_index(data, type, name);
+ if(index == -1)
+ return EXPP_ReturnPyObjError(PyExc_ValueError,
+ "No matching layers or type mismatch" );
+
+ layer = &data->layers[index];
+
+ if(type==CD_PROP_STR){
+ if (strlen(s)>255){
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, maximum string length is 255");
+ }
+ else{
+ ps = layer->data;
+ strcpy(ps[eindex].s,s);
+ }
+ }
+ else if(type==CD_PROP_FLT){
+ pf = layer->data;
+ pf[eindex].f = f;
+ }
+ else{
+ pi = layer->data;
+ pi[eindex].i = i;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *MVert_getProp( BPy_MVert *self, PyObject *args)
+{
+ if( BPy_MVert_Check( self ) ){
+ Mesh *me = (Mesh *)self->data;
+ if(self->index >= me->totvert)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, MVert is no longer valid part of mesh!");
+ else
+ return Mesh_getProperty_internal(&(me->vdata), self->index, args);
+ }
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, Vertex not part of a mesh!");
+}
+
+static PyObject *MVert_setProp( BPy_MVert *self, PyObject *args)
+{
+ if( BPy_MVert_Check( self ) ){
+ Mesh *me = (Mesh *)self->data;
+ if(self->index >= me->totvert)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, MVert is no longer valid part of mesh!");
+ else
+ return Mesh_setProperty_internal(&(me->vdata), self->index, args);
+ }
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "error, Vertex not part of a mesh!");
+}
+
+static struct PyMethodDef BPy_MVert_methods[] = {
+ {"getProperty", (PyCFunction)MVert_getProp, METH_O,
+ "get property indicated by name"},
+ {"setProperty", (PyCFunction)MVert_setProp, METH_VARARGS,
+ "set property indicated by name"},
+ {NULL, NULL, 0, NULL}
+};
+
+
/************************************************************************
*
* Python MVert_Type structure definition
@@ -1290,7 +1506,7 @@ PyTypeObject MVert_Type = {
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
+ BPy_MVert_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
BPy_MVert_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
@@ -1870,7 +2086,7 @@ static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
"MVert belongs to a different mesh" );
}
index = ((BPy_MVert*)tmp)->index;
- } else if( PyInt_CheckExact( tmp ) ) {
+ } else if( PyInt_Check( tmp ) ) {
index = PyInt_AsLong ( tmp );
} else {
MEM_freeN( vert_table );
@@ -1955,6 +2171,37 @@ static PyObject *MVertSeq_selected( BPy_MVertSeq * self )
}
return list;
}
+static PyObject *MVertSeq_add_layertype(BPy_MVertSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_addPropLayer_internal(me, &(me->vdata), me->totvert, args);
+}
+static PyObject *MVertSeq_del_layertype(BPy_MVertSeq *self, PyObject *value)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_removePropLayer_internal(me, &(me->vdata), me->totvert, value);
+}
+static PyObject *MVertSeq_rename_layertype(BPy_MVertSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_renamePropLayer_internal(me,&(me->vdata),args);
+}
+static PyObject *MVertSeq_PropertyList(BPy_MVertSeq *self)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_propList_internal(&(me->vdata));
+}
+static PyObject *M_Mesh_PropertiesTypeDict(void)
+{
+ PyObject *Types = PyConstant_New( );
+ if(Types) {
+ BPy_constant *d = (BPy_constant *) Types;
+ PyConstant_Insert(d, "FLOAT", PyInt_FromLong(CD_PROP_FLT));
+ PyConstant_Insert(d, "INT" , PyInt_FromLong(CD_PROP_INT));
+ PyConstant_Insert(d, "STRING", PyInt_FromLong(CD_PROP_STR));
+ }
+ return Types;
+}
static struct PyMethodDef BPy_MVertSeq_methods[] = {
{"extend", (PyCFunction)MVertSeq_extend, METH_VARARGS,
@@ -1963,9 +2210,25 @@ static struct PyMethodDef BPy_MVertSeq_methods[] = {
"delete vertices from mesh"},
{"selected", (PyCFunction)MVertSeq_selected, METH_NOARGS,
"returns a list containing indices of selected vertices"},
+ {"addPropertyLayer",(PyCFunction)MVertSeq_add_layertype, METH_VARARGS,
+ "add a new property layer"},
+ {"removePropertyLayer",(PyCFunction)MVertSeq_del_layertype, METH_O,
+ "removes a property layer"},
+ {"renamePropertyLayer",(PyCFunction)MVertSeq_rename_layertype, METH_VARARGS,
+ "renames an existing property layer"},
{NULL, NULL, 0, NULL}
};
+static PyGetSetDef BPy_MVertSeq_getseters[] = {
+ {"properties",
+ (getter)MVertSeq_PropertyList, (setter)NULL,
+ "vertex property layers, read only",
+ NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
+
+
/************************************************************************
*
* Python MVertSeq_Type standard operations
@@ -2035,7 +2298,7 @@ PyTypeObject MVertSeq_Type = {
/*** Attribute descriptor and subclassing stuff ***/
BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ BPy_MVertSeq_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -2077,18 +2340,12 @@ static MEdge * MEdge_get_pointer( BPy_MEdge * self )
static PyObject *MEdge_getCrease( BPy_MEdge * self )
{
- PyObject *attr;
MEdge *edge = MEdge_get_pointer( self );
if( !edge )
return NULL;
- attr = PyInt_FromLong( edge->crease );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( edge->crease );
}
/*
@@ -2111,19 +2368,12 @@ static int MEdge_setCrease( BPy_MEdge * self, PyObject * value )
static PyObject *MEdge_getFlag( BPy_MEdge * self )
{
- PyObject *attr;
MEdge *edge = MEdge_get_pointer( self );
if( !edge )
return NULL;
- attr = PyInt_FromLong( edge->flag );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( edge->flag );
}
/*
@@ -2147,7 +2397,7 @@ static int MEdge_setFlag( BPy_MEdge * self, PyObject * value )
if( !edge )
return -1;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check ( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -2203,8 +2453,8 @@ static PyObject *MEdge_getV2( BPy_MEdge * self )
MEdge *edge = MEdge_get_pointer( self );
if( !edge )
- return NULL;
-
+ return NULL; /* error is set */
+ /* if v2 is out of range, the python mvert will complain, no need to check here */
return MVert_CreatePyObject( self->mesh, edge->v2 );
}
@@ -2217,10 +2467,13 @@ static int MEdge_setV2( BPy_MEdge * self, BPy_MVert * value )
MEdge *edge = MEdge_get_pointer( self );
if( !edge )
- return -1;
+ return -1; /* error is set */
if( !BPy_MVert_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, "expected an MVert" );
+ if ( edge->v1 == value->index )
+ return EXPP_ReturnIntError( PyExc_ValueError, "an edge cant use the same vertex for each end" );
+
edge->v2 = value->index;
return 0;
}
@@ -2231,18 +2484,10 @@ static int MEdge_setV2( BPy_MEdge * self, BPy_MVert * value )
static PyObject *MEdge_getIndex( BPy_MEdge * self )
{
- PyObject *attr;
-
if( !MEdge_get_pointer( self ) )
- return NULL;
+ return NULL; /* error is set */
- attr = PyInt_FromLong( self->index );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->index );
}
/*
@@ -2254,7 +2499,7 @@ static PyObject *MEdge_getMFlagBits( BPy_MEdge * self, void * type )
MEdge *edge = MEdge_get_pointer( self );
if( !edge )
- return NULL;
+ return NULL; /* error is set */
return EXPP_getBitfield( &edge->flag, (int)((long)type & 0xff), 'b' );
}
@@ -2271,6 +2516,12 @@ static PyObject *MEdge_getLength( BPy_MEdge * self )
int i;
float *v1, *v2;
+ if (!edge)
+ return NULL; /* error is set */
+
+ if MEDGE_VERT_BADRANGE_CHECK(self->mesh, edge)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError, "This edge uses removed vert(s)" );
+
/* get the 2 edges vert locations */
v1= (&((Mesh *)self->mesh)->mvert[edge->v1])->co;
v2= (&((Mesh *)self->mesh)->mvert[edge->v2])->co;
@@ -2291,14 +2542,18 @@ static PyObject *MEdge_getLength( BPy_MEdge * self )
static PyObject *MEdge_getKey( BPy_MEdge * self )
{
+ PyObject *attr;
MEdge *edge = MEdge_get_pointer( self );
- PyObject *attr = PyTuple_New( 2 );
+ if (!edge)
+ return NULL; /* error is set */
+
+ attr = PyTuple_New( 2 );
if (edge->v1 > edge->v2) {
- PyTuple_SetItem( attr, 0, PyInt_FromLong(edge->v2) );
- PyTuple_SetItem( attr, 1, PyInt_FromLong(edge->v1) );
+ PyTuple_SET_ITEM( attr, 0, PyInt_FromLong(edge->v2) );
+ PyTuple_SET_ITEM( attr, 1, PyInt_FromLong(edge->v1) );
} else {
- PyTuple_SetItem( attr, 0, PyInt_FromLong(edge->v1) );
- PyTuple_SetItem( attr, 1, PyInt_FromLong(edge->v2) );
+ PyTuple_SET_ITEM( attr, 0, PyInt_FromLong(edge->v1) );
+ PyTuple_SET_ITEM( attr, 1, PyInt_FromLong(edge->v2) );
}
return attr;
}
@@ -2312,16 +2567,17 @@ static int MEdge_setSel( BPy_MEdge * self,PyObject * value,
{
MEdge *edge = MEdge_get_pointer( self );
int param = PyObject_IsTrue( value );
- Mesh *me;
+ Mesh *me = self->mesh;
if( !edge )
return -1;
-
+
+ if MEDGE_VERT_BADRANGE_CHECK(me, edge)
+ return EXPP_ReturnIntError( PyExc_RuntimeError, "This edge uses removed vert(s)" );
+
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected true/false argument" );
-
- me = self->mesh;
+ "expected True/False or 0/1" );
if( param ) {
edge->flag |= SELECT;
@@ -2452,7 +2708,25 @@ static long MEdge_hash( BPy_MEdge *self )
{
return (long)self->index;
}
+static PyObject *MEdge_getProp( BPy_MEdge *self, PyObject *args)
+{
+ Mesh *me = (Mesh *)self->mesh;
+ return Mesh_getProperty_internal(&(me->edata), self->index, args);
+}
+
+static PyObject *MEdge_setProp( BPy_MEdge *self, PyObject *args)
+{
+ Mesh *me = (Mesh *)self->mesh;
+ return Mesh_setProperty_internal(&(me->edata), self->index, args);
+}
+static struct PyMethodDef BPy_MEdge_methods[] = {
+ {"getProperty", (PyCFunction)MEdge_getProp, METH_O,
+ "get property indicated by name"},
+ {"setProperty", (PyCFunction)MEdge_setProp, METH_VARARGS,
+ "set property indicated by name"},
+ {NULL, NULL, 0, NULL}
+};
/************************************************************************
*
* Python MEdge_Type structure definition
@@ -2517,7 +2791,7 @@ PyTypeObject MEdge_Type = {
( iternextfunc ) MEdge_nextIter, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
+ BPy_MEdge_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
BPy_MEdge_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
@@ -2745,7 +3019,7 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
ok = 0;
for( j = 0; ok == 0 && j < nverts; ++j ) {
PyObject *item = PySequence_ITEM( tmp, j );
- if( !PyInt_CheckExact( item ) )
+ if( !PyInt_Check( item ) )
ok = 1;
else {
int index = PyInt_AsLong ( item );
@@ -2979,7 +3253,7 @@ static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
PyObject *tmp = PySequence_GetItem( args, i );
if( BPy_MEdge_Check( tmp ) )
edge_table[i] = ((BPy_MEdge *)tmp)->index;
- else if( PyInt_CheckExact( tmp ) )
+ else if( PyInt_Check( tmp ) )
edge_table[i] = PyInt_AsLong ( tmp );
else {
MEM_freeN( edge_table );
@@ -3189,7 +3463,7 @@ static PyObject *MEdgeSeq_collapse( BPy_MEdgeSeq * self, PyObject *args )
tmp1 = PySequence_GetItem( tmp, 0 );
tmp2 = PySequence_GetItem( tmp, 1 );
Py_DECREF( tmp );
- if( !(BPy_MEdge_Check( tmp1 ) || PyInt_CheckExact( tmp1 )) ||
+ if( !(BPy_MEdge_Check( tmp1 ) || PyInt_Check( tmp1 )) ||
!VectorObject_Check ( tmp2 ) ) {
MEM_freeN( edge_table );
MEM_freeN( vert_list );
@@ -3201,7 +3475,7 @@ static PyObject *MEdgeSeq_collapse( BPy_MEdgeSeq * self, PyObject *args )
}
/* store edge index, new vertex location */
- if( PyInt_CheckExact( tmp1 ) )
+ if( PyInt_Check( tmp1 ) )
edge_table[i] = PyInt_AsLong ( tmp1 );
else
edge_table[i] = ((BPy_MEdge *)tmp1)->index;
@@ -3253,7 +3527,7 @@ static PyObject *MEdgeSeq_collapse( BPy_MEdgeSeq * self, PyObject *args )
basact = BASACT;
BASACT = base;
- removedoublesflag( 1, 0.0 );
+ removedoublesflag( 1, 0, 0.0 );
/* make mesh's object active, enter mesh edit mode */
G.obedit = object;
@@ -3311,6 +3585,28 @@ static PyObject *MEdgeSeq_selected( BPy_MEdgeSeq * self )
return list;
}
+static PyObject *MEdgeSeq_add_layertype(BPy_MEdgeSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_addPropLayer_internal(me, &(me->edata), me->totedge, args);
+}
+static PyObject *MEdgeSeq_del_layertype(BPy_MEdgeSeq *self, PyObject *value)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_removePropLayer_internal(me, &(me->edata), me->totedge, value);
+}
+static PyObject *MEdgeSeq_rename_layertype(BPy_MEdgeSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_renamePropLayer_internal(me,&(me->edata),args);
+}
+static PyObject *MEdgeSeq_PropertyList(BPy_MEdgeSeq *self)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_propList_internal(&(me->edata));
+}
+
+
static struct PyMethodDef BPy_MEdgeSeq_methods[] = {
{"extend", (PyCFunction)MEdgeSeq_extend, METH_VARARGS,
"add edges to mesh"},
@@ -3320,8 +3616,23 @@ static struct PyMethodDef BPy_MEdgeSeq_methods[] = {
"returns a list containing indices of selected edges"},
{"collapse", (PyCFunction)MEdgeSeq_collapse, METH_VARARGS,
"collapse one or more edges to a vertex"},
+ {"addPropertyLayer",(PyCFunction)MEdgeSeq_add_layertype, METH_VARARGS,
+ "add a new property layer"},
+ {"removePropertyLayer",(PyCFunction)MEdgeSeq_del_layertype, METH_O,
+ "removes a property layer"},
+ {"renamePropertyLayer",(PyCFunction)MEdgeSeq_rename_layertype, METH_VARARGS,
+ "renames an existing property layer"},
+
{NULL, NULL, 0, NULL}
};
+static PyGetSetDef BPy_MEdgeSeq_getseters[] = {
+ {"properties",
+ (getter)MEdgeSeq_PropertyList, (setter)NULL,
+ "edge property layers, read only",
+ NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
/************************************************************************
*
@@ -3392,7 +3703,7 @@ PyTypeObject MEdgeSeq_Type = {
/*** Attribute descriptor and subclassing stuff ***/
BPy_MEdgeSeq_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ BPy_MEdgeSeq_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -3472,7 +3783,26 @@ static int MFace_setVerts( BPy_MFace * self, PyObject * args )
&MVert_Type, &v2, &MVert_Type, &v3, &MVert_Type, &v4 ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected tuple of 3 or 4 MVerts" );
-
+
+ if( v1->index == v2->index ||
+ v1->index == v3->index ||
+ v2->index == v3->index )
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "cannot assign 2 or move verts that are the same" );
+
+ if(v4 && ( v1->index == v4->index ||
+ v2->index == v4->index ||
+ v3->index == v4->index ))
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "cannot assign 2 or move verts that are the same" );
+
+ if( v1->index >= self->mesh->totvert ||
+ v2->index >= self->mesh->totvert ||
+ v3->index >= self->mesh->totvert ||
+ (v4 &&( v4->index >= self->mesh->totvert)))
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "cannot assign verts that have been removed" );
+
face->v1 = v1->index;
face->v2 = v2->index;
face->v3 = v3->index;
@@ -3487,19 +3817,12 @@ static int MFace_setVerts( BPy_MFace * self, PyObject * args )
static PyObject *MFace_getMat( BPy_MFace * self )
{
- PyObject *attr;
MFace *face = MFace_get_pointer( self );
if( !face )
return NULL;
- attr = PyInt_FromLong( face->mat_nr );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( face->mat_nr );
}
/*
@@ -3511,7 +3834,7 @@ static int MFace_setMat( BPy_MFace * self, PyObject * value )
MFace *face = MFace_get_pointer( self );
if( !face )
- return -1;
+ return -1; /* error is set */
return EXPP_setIValueRange( value, &face->mat_nr, 0, 15, 'b' );
}
@@ -3522,19 +3845,12 @@ static int MFace_setMat( BPy_MFace * self, PyObject * value )
static PyObject *MFace_getIndex( BPy_MFace * self )
{
- PyObject *attr;
MFace *face = MFace_get_pointer( self );
if( !face )
- return NULL;
-
- attr = PyInt_FromLong( self->index );
+ return NULL; /* error is set */
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->index );
}
/*
@@ -3547,21 +3863,20 @@ static PyObject *MFace_getNormal( BPy_MFace * self )
float no[3];
MFace *face = MFace_get_pointer( self );
+ Mesh *me = self->mesh;
+
if( !face )
- return NULL;
-
- if( (int)face->v1 >= self->mesh->totvert ||
- (int)face->v2 >= self->mesh->totvert ||
- (int)face->v3 >= self->mesh->totvert ||
- (int)face->v4 >= self->mesh->totvert )
+ return NULL; /* error is set */
+
+ if MFACE_VERT_BADRANGE_CHECK(me, face)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"one or more MFace vertices are no longer valid" );
- vert[0] = self->mesh->mvert[face->v1].co;
- vert[1] = self->mesh->mvert[face->v2].co;
- vert[2] = self->mesh->mvert[face->v3].co;
+ vert[0] = me->mvert[face->v1].co;
+ vert[1] = me->mvert[face->v2].co;
+ vert[2] = me->mvert[face->v3].co;
if( face->v4 ) {
- vert[3] = self->mesh->mvert[face->v4].co;
+ vert[3] = me->mvert[face->v4].co;
CalcNormFloat4( vert[0], vert[1], vert[2], vert[3], no );
} else
CalcNormFloat( vert[0], vert[1], vert[2], no );
@@ -3578,23 +3893,22 @@ static PyObject *MFace_getCent( BPy_MFace * self )
float *vert[4];
float cent[3]= {0,0,0};
int i=3, j, k;
+ Mesh *me = self->mesh;
MFace *face = MFace_get_pointer( self );
if( !face )
- return NULL;
+ return NULL; /* error is set */
+
- if( (int)face->v1 >= self->mesh->totvert ||
- (int)face->v2 >= self->mesh->totvert ||
- (int)face->v3 >= self->mesh->totvert ||
- (int)face->v4 >= self->mesh->totvert )
+ if MFACE_VERT_BADRANGE_CHECK(me, face)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"one or more MFace vertices are no longer valid" );
- vert[0] = self->mesh->mvert[face->v1].co;
- vert[1] = self->mesh->mvert[face->v2].co;
- vert[2] = self->mesh->mvert[face->v3].co;
+ vert[0] = me->mvert[face->v1].co;
+ vert[1] = me->mvert[face->v2].co;
+ vert[2] = me->mvert[face->v3].co;
if( face->v4 ) {
- vert[3] = self->mesh->mvert[face->v4].co;
+ vert[3] = me->mvert[face->v4].co;
i=4;
}
@@ -3617,23 +3931,21 @@ static PyObject *MFace_getArea( BPy_MFace * self )
{
float *v1,*v2,*v3,*v4;
MFace *face = MFace_get_pointer( self );
+ Mesh *me = self->mesh;
if( !face )
- return NULL;
+ return NULL; /* error is set */
- if( (int)face->v1 >= self->mesh->totvert ||
- (int)face->v2 >= self->mesh->totvert ||
- (int)face->v3 >= self->mesh->totvert ||
- (int)face->v4 >= self->mesh->totvert )
+ if MFACE_VERT_BADRANGE_CHECK(me, face)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"one or more MFace vertices are no longer valid" );
- v1 = self->mesh->mvert[face->v1].co;
- v2 = self->mesh->mvert[face->v2].co;
- v3 = self->mesh->mvert[face->v3].co;
+ v1 = me->mvert[face->v1].co;
+ v2 = me->mvert[face->v2].co;
+ v3 = me->mvert[face->v3].co;
if( face->v4 ) {
- v4 = self->mesh->mvert[face->v4].co;
+ v4 = me->mvert[face->v4].co;
return PyFloat_FromDouble( AreaQ3Dfl(v1, v2, v3, v4));
} else
return PyFloat_FromDouble( AreaT3Dfl(v1, v2, v3));
@@ -3648,7 +3960,7 @@ static PyObject *MFace_getMFlagBits( BPy_MFace * self, void * type )
MFace *face = MFace_get_pointer( self );
if( !face )
- return NULL;
+ return NULL; /* error is set */
return EXPP_getBitfield( &face->flag, (int)((long)type & 0xff), 'b' );
}
@@ -3663,7 +3975,7 @@ static int MFace_setMFlagBits( BPy_MFace * self, PyObject * value,
MFace *face = MFace_get_pointer( self );
if( !face )
- return -1;
+ return -1; /* error is set */
return EXPP_setBitfield( value, &face->flag,
(int)((long)type & 0xff), 'b' );
@@ -3677,11 +3989,11 @@ static int MFace_setSelect( BPy_MFace * self, PyObject * value,
Mesh *me;
if( !face )
- return -1;
+ return -1; /* error is set */
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected true/false argument" );
+ "expected True/False or 0/1" );
me = self->mesh;
if( param ) {
@@ -3766,7 +4078,7 @@ static int MFace_setImage( BPy_MFace *self, PyObject *value )
return 0;
}
-#define MFACE_FLAG_BITMASK ( TF_SELECT | TF_ACTIVE | TF_SEL1 | \
+#define MFACE_FLAG_BITMASK ( TF_SELECT | TF_SEL1 | \
TF_SEL2 | TF_SEL3 | TF_SEL4 | TF_HIDE )
/*
@@ -3775,6 +4087,7 @@ static int MFace_setImage( BPy_MFace *self, PyObject *value )
static PyObject *MFace_getFlag( BPy_MFace *self )
{
+ int flag;
if( !self->mesh->mtface )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"face has no texture values" );
@@ -3782,8 +4095,13 @@ static PyObject *MFace_getFlag( BPy_MFace *self )
if( !MFace_get_pointer( self ) )
return NULL;
- return PyInt_FromLong( (long) ( self->mesh->mtface[self->index].flag
- & MFACE_FLAG_BITMASK ) );
+ flag = self->mesh->mtface[self->index].flag & MFACE_FLAG_BITMASK;
+
+ /* so old scripts still work */
+ if (self->index == self->mesh->act_face)
+ flag |= TF_ACTIVE;
+
+ return PyInt_FromLong( (long)( flag ) );
}
/*
@@ -3801,7 +4119,7 @@ static int MFace_setFlag( BPy_MFace *self, PyObject *value )
if( !MFace_get_pointer( self ) )
return -1;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check ( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%04x", MFACE_FLAG_BITMASK );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -3817,7 +4135,7 @@ static int MFace_setFlag( BPy_MFace *self, PyObject *value )
"invalid bit(s) set in mask" );
/* merge active setting with other new params */
- param |= (self->mesh->mtface[self->index].flag & TF_ACTIVE);
+ param |= (self->mesh->mtface[self->index].flag);
self->mesh->mtface[self->index].flag = (char)param;
return 0;
@@ -3829,8 +4147,6 @@ static int MFace_setFlag( BPy_MFace *self, PyObject *value )
static PyObject *MFace_getMode( BPy_MFace *self )
{
- PyObject *attr;
-
if( !self->mesh->mtface )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"face has no texture values" );
@@ -3838,13 +4154,7 @@ static PyObject *MFace_getMode( BPy_MFace *self )
if( !MFace_get_pointer( self ) )
return NULL;
- attr = PyInt_FromLong( self->mesh->mtface[self->index].mode );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->mesh->mtface[self->index].mode );
}
/*
@@ -3875,7 +4185,7 @@ static int MFace_setMode( BPy_MFace *self, PyObject *value )
if( !MFace_get_pointer( self ) )
return -1;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check ( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -3906,7 +4216,6 @@ static int MFace_setMode( BPy_MFace *self, PyObject *value )
static PyObject *MFace_getTransp( BPy_MFace *self )
{
- PyObject *attr;
if( !self->mesh->mtface )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"face has no texture values" );
@@ -3914,13 +4223,7 @@ static PyObject *MFace_getTransp( BPy_MFace *self )
if( !MFace_get_pointer( self ) )
return NULL;
- attr = PyInt_FromLong( self->mesh->mtface[self->index].transp );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->mesh->mtface[self->index].transp );
}
/*
@@ -4089,7 +4392,7 @@ static int MFace_setUVSel( BPy_MFace * self, PyObject * value )
mask = TF_SEL1;
for( i=0; i<length; ++i, mask <<= 1 ) {
PyObject *tmp = PySequence_GetItem( value, i ); /* adds a reference, remove below */
- if( !PyInt_CheckExact( tmp ) ) {
+ if( !PyInt_Check( tmp ) ) {
Py_DECREF(tmp);
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a tuple of integers" );
@@ -4196,80 +4499,84 @@ static PyObject *MFace_getEdgeKeys( BPy_MFace * self )
{
MFace *face = MFace_get_pointer( self );
PyObject *attr, *edpair;
+
+ if (!face)
+ return NULL; /* error set */
+
if (face->v4) {
attr = PyTuple_New( 4 );
edpair = PyTuple_New( 2 );
if (face->v1 > face->v2) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v1) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v2) );
}
- PyTuple_SetItem( attr, 0, edpair );
+ PyTuple_SET_ITEM( attr, 0, edpair );
edpair = PyTuple_New( 2 );
if (face->v2 > face->v3) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v2) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v3) );
}
- PyTuple_SetItem( attr, 1, edpair );
+ PyTuple_SET_ITEM( attr, 1, edpair );
edpair = PyTuple_New( 2 );
if (face->v3 > face->v4) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v4) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v4) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v3) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v4) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v4) );
}
- PyTuple_SetItem( attr, 2, edpair );
+ PyTuple_SET_ITEM( attr, 2, edpair );
edpair = PyTuple_New( 2 );
if (face->v4 > face->v1) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v4) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v4) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v4) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v4) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v1) );
}
- PyTuple_SetItem( attr, 3, edpair );
+ PyTuple_SET_ITEM( attr, 3, edpair );
} else {
attr = PyTuple_New( 3 );
edpair = PyTuple_New( 2 );
if (face->v1 > face->v2) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v1) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v2) );
}
- PyTuple_SetItem( attr, 0, edpair );
+ PyTuple_SET_ITEM( attr, 0, edpair );
edpair = PyTuple_New( 2 );
if (face->v2 > face->v3) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v2) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v2) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v3) );
}
- PyTuple_SetItem( attr, 1, edpair );
+ PyTuple_SET_ITEM( attr, 1, edpair );
edpair = PyTuple_New( 2 );
if (face->v3 > face->v1) {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v3) );
} else {
- PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
- PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
+ PyTuple_SET_ITEM( edpair, 0, PyInt_FromLong(face->v3) );
+ PyTuple_SET_ITEM( edpair, 1, PyInt_FromLong(face->v1) );
}
- PyTuple_SetItem( attr, 2, edpair );
+ PyTuple_SET_ITEM( attr, 2, edpair );
}
return attr;
@@ -4469,6 +4776,36 @@ static PySequenceMethods MFace_as_sequence = {
0,0,0,
};
+static PyObject *MFace_getProp( BPy_MFace *self, PyObject *args)
+{
+ Mesh *me = (Mesh *)self->mesh;
+ MFace *face = MFace_get_pointer( self );
+ if( !face )
+ return NULL;
+ mesh_update_customdata_pointers(me); //!
+ return Mesh_getProperty_internal(&(me->fdata), self->index, args);
+}
+
+static PyObject *MFace_setProp( BPy_MFace *self, PyObject *args)
+{
+ Mesh *me = (Mesh *)self->mesh;
+ PyObject *obj;
+ MFace *face = MFace_get_pointer( self );
+ if( !face )
+ return NULL; /* error set */
+
+ obj = Mesh_setProperty_internal(&(me->fdata), self->index, args);
+ mesh_update_customdata_pointers(me); //!
+ return obj;
+}
+
+static struct PyMethodDef BPy_MFace_methods[] = {
+ {"getProperty", (PyCFunction)MFace_getProp, METH_O,
+ "get property indicated by name"},
+ {"setProperty", (PyCFunction)MFace_setProp, METH_VARARGS,
+ "set property indicated by name"},
+ {NULL, NULL, 0, NULL}
+};
/************************************************************************
*
* Python MFace_Type structure definition
@@ -4533,7 +4870,7 @@ PyTypeObject MFace_Type = {
( iternextfunc ) MFace_nextIter, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
+ BPy_MFace_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
BPy_MFace_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
@@ -4668,7 +5005,8 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args,
Mesh *mesh = self->mesh;
int ignore_dups = 0;
PyObject *return_list = NULL;
-
+ char flag = ME_FACE_SEL;
+
/* before we try to add faces, add edges; if it fails; exit */
tmp = MEdgeSeq_extend( self, args );
@@ -4679,12 +5017,39 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args,
/* process any keyword arguments */
if( keywds ) {
PyObject *res = PyDict_GetItemString( keywds, "ignoreDups" );
- if( res )
+ if( res ) {
ignore_dups = PyObject_IsTrue( res );
-
+ if (ignore_dups==-1) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "keyword argument \"ignoreDups\" expected True/False or 0/1" );
+ }
+ }
res = PyDict_GetItemString( keywds, "indexList" );
- if( res && PyObject_IsTrue( res ) )
- return_list = PyList_New( 0 );
+ if (res) {
+ switch( PyObject_IsTrue( res ) ) {
+ case 0:
+ break;
+ case -1:
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "keyword argument \"indexList\" expected True/False or 0/1" );
+ default:
+ return_list = PyList_New( 0 );
+ }
+ }
+
+ res = PyDict_GetItemString( keywds, "smooth" );
+ if (res) {
+ switch( PyObject_IsTrue( res ) ) {
+ case 0:
+ break;
+ case -1:
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "keyword argument \"smooth\" expected True/False or 0/1" );
+ default:
+ flag |= ME_SMOOTH;
+
+ }
+ }
}
/* make sure we get a tuple of sequences of something */
@@ -4970,7 +5335,7 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args,
tmpface->v3 = tmppair->v[index[2]];
tmpface->v4 = tmppair->v[index[3]];
- tmpface->flag = ME_FACE_SEL;
+ tmpface->flag = flag;
if( return_list ) {
tmp = PyInt_FromLong( mesh->totface );
@@ -5030,7 +5395,7 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"sequence must contain at least one int or MFace" );
- face_table = (unsigned int *)MEM_callocN( len*sizeof( unsigned int ),
+ face_table = MEM_callocN( len*sizeof( unsigned int ),
"face_table" );
/* get the indices of faces to be removed */
@@ -5038,7 +5403,7 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
PyObject *tmp = PySequence_GetItem( args, i );
if( BPy_MFace_Check( tmp ) )
face_table[i] = ((BPy_MFace *)tmp)->index;
- else if( PyInt_CheckExact( tmp ) )
+ else if( PyInt_Check( tmp ) )
face_table[i] = PyInt_AsLong( tmp );
else {
MEM_freeN( face_table );
@@ -5153,15 +5518,12 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
++face_count;
}
}
-
- /* for each face, deselect each edge */
+
+ /* for each remaining face, select all edges */
tmpface = mesh->mface;
fface = (struct fourEdges *)face_edges;
for( i = mesh->totface; i--; ++tmpface, ++fface ) {
if( tmpface->v1 != UINT_MAX ) {
- FaceEdges (*face)[4];
- face = (void *)face_edges;
- face += face_table[i];
fface->v[0]->sel = 1;
fface->v[1]->sel = 1;
fface->v[2]->sel = 1;
@@ -5169,7 +5531,6 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
fface->v[3]->sel = 1;
}
}
-
/* now mark the selected edges for deletion */
edge_count = 0;
@@ -5205,6 +5566,70 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
Py_RETURN_NONE;
}
+/* copied from meshtools.c - should make generic? */
+static void permutate(void *list, int num, int size, int *index)
+{
+ void *buf;
+ int len;
+ int i;
+
+ len = num * size;
+
+ buf = MEM_mallocN(len, "permutate");
+ memcpy(buf, list, len);
+
+ for (i = 0; i < num; i++) {
+ memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
+ }
+ MEM_freeN(buf);
+}
+
+/* this wrapps list sorting then applies back to the mesh */
+static PyObject *MFaceSeq_sort( BPy_MEdgeSeq * self, PyObject *args,
+ PyObject *keywds )
+{
+ PyObject *ret, *sort_func, *newargs;
+
+ Mesh *mesh = self->mesh;
+ PyObject *sorting_list;
+ CustomDataLayer *layer;
+ int i, *index;
+
+ /* get a list for internal use */
+ sorting_list = PySequence_List( (PyObject *)self );
+ if( !sorting_list )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "PyList_New() failed" );
+
+ /* create index list */
+ index = (int *) MEM_mallocN(sizeof(int) * mesh->totface, "sort faces");
+ if (!index)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "faces.sort(...) failed to allocate memory" );
+
+ newargs = EXPP_PyTuple_New_Prepend(args, sorting_list);
+ sort_func = PyObject_GetAttrString( ((PyObject *)&PyList_Type), "sort");
+
+ ret = PyObject_Call(sort_func, newargs, keywds);
+
+ Py_DECREF(newargs);
+ Py_DECREF(sort_func);
+
+ if (ret) {
+ /* copy the faces indicies to index */
+ for (i = 0; i < mesh->totface; i++)
+ index[i] = ((BPy_MFace *)PyList_GET_ITEM(sorting_list, i))->index;
+
+ for(i = 0; i < mesh->fdata.totlayer; i++) {
+ layer = &mesh->fdata.layers[i];
+ permutate(layer->data, mesh->totface, CustomData_sizeof(layer->type), index);
+ }
+ }
+ Py_DECREF(sorting_list);
+ MEM_freeN(index);
+ return ret;
+}
+
static PyObject *MFaceSeq_selected( BPy_MFaceSeq * self )
{
int i, count;
@@ -5242,15 +5667,52 @@ static PyObject *MFaceSeq_selected( BPy_MFaceSeq * self )
return list;
}
+static PyObject *MFaceSeq_add_layertype(BPy_MFaceSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_addPropLayer_internal(me, &(me->fdata), me->totface, args);
+}
+static PyObject *MFaceSeq_del_layertype(BPy_MFaceSeq *self, PyObject *value)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_removePropLayer_internal(me, &(me->fdata), me->totface, value);
+}
+static PyObject *MFaceSeq_rename_layertype(BPy_MFaceSeq *self, PyObject *args)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_renamePropLayer_internal(me,&(me->fdata),args);
+}
+static PyObject *MFaceSeq_PropertyList(BPy_MFaceSeq *self)
+{
+ Mesh *me = (Mesh*)self->mesh;
+ return Mesh_propList_internal(&(me->fdata));
+}
+
static struct PyMethodDef BPy_MFaceSeq_methods[] = {
{"extend", (PyCFunction)MFaceSeq_extend, METH_VARARGS|METH_KEYWORDS,
"add faces to mesh"},
{"delete", (PyCFunction)MFaceSeq_delete, METH_VARARGS,
"delete faces from mesh"},
+ {"sort", (PyCFunction)MFaceSeq_sort, METH_VARARGS|METH_KEYWORDS,
+ "sort the faces using list sorts syntax"},
{"selected", (PyCFunction)MFaceSeq_selected, METH_NOARGS,
"returns a list containing indices of selected faces"},
+ {"addPropertyLayer",(PyCFunction)MFaceSeq_add_layertype, METH_VARARGS,
+ "add a new property layer"},
+ {"removePropertyLayer",(PyCFunction)MFaceSeq_del_layertype, METH_O,
+ "removes a property layer"},
+ {"renamePropertyLayer",(PyCFunction)MFaceSeq_rename_layertype, METH_VARARGS,
+ "renames an existing property layer"},
{NULL, NULL, 0, NULL}
};
+static PyGetSetDef BPy_MFaceSeq_getseters[] = {
+ {"properties",
+ (getter)MFaceSeq_PropertyList, (setter)NULL,
+ "vertex property layers, read only",
+ NULL},
+ {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
+};
+
/************************************************************************
*
@@ -5321,7 +5783,7 @@ PyTypeObject MFaceSeq_Type = {
/*** Attribute descriptor and subclassing stuff ***/
BPy_MFaceSeq_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
+ BPy_MFaceSeq_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -5581,7 +6043,7 @@ static PyObject *Mesh_findEdges( PyObject * self, PyObject *args )
}
index1 = v1->index;
index2 = v2->index;
- } else if( PyInt_CheckExact( v1 ) && PyInt_CheckExact( v2 ) ) {
+ } else if( PyInt_Check( v1 ) && PyInt_Check( v2 ) ) {
index1 = PyInt_AsLong( (PyObject *)v1 );
index2 = PyInt_AsLong( (PyObject *)v2 );
if( (int)index1 >= mesh->totvert
@@ -5702,13 +6164,16 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
/* get updated display list, and convert to a mesh */
makeDispListCurveTypes( tmpobj, 0 );
nurbs_to_mesh( tmpobj );
- tmpmesh = tmpobj->data;
- free_libblock_us( &G.main->object, tmpobj );
- if (ob->type != OB_MESH)
+ /* nurbs_to_mesh changes the type tp a mesh, check it worked */
+ if (tmpobj->type != OB_MESH) {
+ free_libblock_us( &G.main->object, tmpobj );
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"cant convert curve to mesh. Does the curve have any segments?" );
- break;
+ }
+ 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( ob );
@@ -5926,21 +6391,21 @@ static PyObject *Mesh_transform( BPy_Mesh *self, PyObject *args, PyObject *kwd )
Py_RETURN_NONE;
}
-static PyObject *Mesh_addVertGroup( PyObject * self, PyObject * args )
+static PyObject *Mesh_addVertGroup( PyObject * self, PyObject * value )
{
- char *groupStr;
+ char *groupStr = PyString_AsString(value);
struct Object *object;
- if( !PyArg_ParseTuple( args, "s", &groupStr ) )
+ if( !groupStr )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
- if( ( ( BPy_Mesh * ) self )->object == NULL )
+ object = ( ( BPy_Mesh * ) self )->object;
+
+ if( object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh not linked to an object" );
- object = ( ( BPy_Mesh * ) self )->object;
-
/* add_defgroup_name clamps the name to 32, make sure that dosnt change */
add_defgroup_name( object, groupStr );
@@ -5949,14 +6414,18 @@ static PyObject *Mesh_addVertGroup( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Mesh_removeVertGroup( PyObject * self, PyObject * args )
+static PyObject *Mesh_removeVertGroup( PyObject * self, PyObject * value )
{
- char *groupStr;
+ char *groupStr = PyString_AsString(value);
struct Object *object;
int nIndex;
bDeformGroup *pGroup;
- if( !PyArg_ParseTuple( args, "s", &groupStr ) )
+ if( G.obedit )
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+ "can't use removeVertGroup() while in edit mode" );
+
+ if( !groupStr )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -5978,8 +6447,8 @@ static PyObject *Mesh_removeVertGroup( PyObject * self, PyObject * args )
nIndex++;
object->actdef = (unsigned short)nIndex;
- del_defgroup( object );
-
+ del_defgroup_in_object_mode( object );
+
EXPP_allqueue( REDRAWBUTSALL, 1 );
Py_RETURN_NONE;
@@ -6137,7 +6606,6 @@ static PyObject *Mesh_getVertsFromGroup( BPy_Mesh* self, PyObject * args )
PyObject *vertexList;
Object *object;
Mesh *mesh;
- PyObject *tempVertexList;
int num = 0;
int weightRet = 0;
@@ -6176,15 +6644,14 @@ static PyObject *Mesh_getVertsFromGroup( BPy_Mesh* self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no deform groups assigned to mesh" );
- /* temporary list */
- tempVertexList = PyList_New( mesh->totvert );
- if( !tempVertexList )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "getVertsFromGroup: can't create pylist!" );
-
count = 0;
if( !listObject ) { /* do entire group */
+ vertexList = PyList_New( mesh->totvert );
+ if( !vertexList )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "getVertsFromGroup: can't create pylist!" );
+
dvert = mesh->dvert;
for( num = 0; num < mesh->totvert; num++, ++dvert ) {
for( i = 0; i < dvert->totweight; i++ ) {
@@ -6195,23 +6662,31 @@ static PyObject *Mesh_getVertsFromGroup( BPy_Mesh* self, PyObject * args )
dvert->dw[i].weight );
else
attr = PyInt_FromLong ( num );
- PyList_SetItem( tempVertexList, count, attr );
+ PyList_SetItem( vertexList, count, attr );
count++;
}
}
}
+
+ if (count < mesh->totvert)
+ PyList_SetSlice(vertexList, count, mesh->totvert, NULL);
+
} else { /* do individual vertices */
- for( i = 0; i < PyList_Size( listObject ); i++ ) {
+ int listObjectLen = PyList_Size( listObject );
+
+ vertexList = PyList_New( listObjectLen );
+ for( i = 0; i < listObjectLen; i++ ) {
PyObject *attr = NULL;
- if( !PyArg_Parse( PyList_GetItem( listObject, i ), "i", &num ) ) {
- Py_DECREF(tempVertexList);
+ num = PyInt_AsLong( PyList_GetItem( listObject, i ) );
+ if (num == -1) {/* -1 is an error AND an invalid range, we dont care which */
+ Py_DECREF(vertexList);
return EXPP_ReturnPyObjError( PyExc_TypeError,
"python list integer not parseable" );
}
if( num < 0 || num >= mesh->totvert ) {
- Py_DECREF(tempVertexList);
+ Py_DECREF(vertexList);
return EXPP_ReturnPyObjError( PyExc_ValueError,
"bad vertex index in list" );
}
@@ -6223,17 +6698,15 @@ static PyObject *Mesh_getVertsFromGroup( BPy_Mesh* self, PyObject * args )
dvert->dw[k].weight );
else
attr = PyInt_FromLong ( num );
- PyList_SetItem( tempVertexList, count, attr );
+ PyList_SetItem( vertexList, count, attr );
count++;
}
}
}
+ if (count < listObjectLen)
+ PyList_SetSlice(vertexList, count, listObjectLen, NULL);
}
- /* only return what we need */
- vertexList = PyList_GetSlice( tempVertexList, 0, count );
-
- Py_DECREF( tempVertexList );
-
+
return vertexList;
}
@@ -6443,14 +6916,14 @@ static PyObject *Mesh_addColorLayer( BPy_Mesh * self, PyObject * args )
return Mesh_addCustomLayer_internal(self->mesh, args, CD_MCOL);
}
-static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * args, int type )
+static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * value, int type )
{
Mesh *me = self->mesh;
CustomData *data = &me->fdata;
- char *name;
+ char *name = PyString_AsString(value);
int i;
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -6474,7 +6947,7 @@ static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * args, in
if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
if(type == CD_MTFACE && (G.f & G_FACESELECT))
- set_faceselect(); /* get out of faceselect mode */
+ G.f |= ~G_FACESELECT; /* get out of faceselect mode */
}
}
@@ -6482,14 +6955,14 @@ static PyObject *Mesh_removeLayer_internal( BPy_Mesh * self, PyObject * args, in
}
-static PyObject *Mesh_removeUVLayer( BPy_Mesh * self, PyObject * args )
+static PyObject *Mesh_removeUVLayer( BPy_Mesh * self, PyObject * value )
{
- return Mesh_removeLayer_internal(self, args, CD_MTFACE);
+ return Mesh_removeLayer_internal(self, value, CD_MTFACE);
}
-static PyObject *Mesh_removeColorLayer( BPy_Mesh * self, PyObject * args )
+static PyObject *Mesh_removeColorLayer( BPy_Mesh * self, PyObject * value )
{
- return Mesh_removeLayer_internal(self, args, CD_MCOL);
+ return Mesh_removeLayer_internal(self, value, CD_MCOL);
}
@@ -6663,7 +7136,7 @@ static PyObject *Mesh_getMultires( BPy_Mesh * self, void *type )
static int Mesh_setMultires( BPy_Mesh * self, PyObject *value, void *type )
{
int i;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected integer argument" );
@@ -6688,7 +7161,7 @@ static int Mesh_setMultires( BPy_Mesh * self, PyObject *value, void *type )
switch ((int)type) {
case MESH_MULTIRES_LEVEL:
self->mesh->mr->newlvl = i;
- multires_set_level(self->object, self->mesh, 0);
+ multires_set_level_cb(self->object, self->mesh);
break;
case MESH_MULTIRES_EDGE:
self->mesh->mr->edgelvl = i;
@@ -6705,6 +7178,36 @@ static int Mesh_setMultires( BPy_Mesh * self, PyObject *value, void *type )
return 0;
}
+static PyObject *Mesh_addMultiresLevel( BPy_Mesh * self, PyObject * args )
+{
+ char typenum;
+ int i, levels = 1;
+ char *type = NULL;
+ if( G.obedit )
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+ "can't add multires level while in edit mode" );
+ if( !PyArg_ParseTuple( args, "|is", &levels, &type ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected nothing or an int and optionally a string as arguments" );
+ if( !type || !strcmp( type, "catmull-clark" ) )
+ typenum = 0;
+ else if( !strcmp( type, "simple" ) )
+ typenum = 1;
+ else
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "if given, type should be 'catmull-clark' or 'simple'" );
+ if (!self->mesh->mr)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "the mesh has no multires data" );
+ for( i = 0; i < levels; i++ ) {
+ multires_add_level(self->object, self->mesh, typenum);
+ };
+ multires_update_levels(self->mesh, 0);
+ multires_level_to_editmesh(self->object, self->mesh, 0);
+ multires_finish_mesh_update(self->object);
+ Py_RETURN_NONE;
+}
+
/* end multires */
@@ -6757,7 +7260,7 @@ static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args )
esubdivideflag( 1, 0.0, *((int *)args[0]), 1, 0 );
break;
case MESH_TOOL_REMDOUB:
- result = removedoublesflag( 1, *((float *)args[0]) );
+ result = removedoublesflag( 1, 0, *((float *)args[0]) );
attr = PyInt_FromLong( result );
if( !attr )
@@ -6922,53 +7425,66 @@ static PyObject *Mesh_fill( BPy_Mesh * self )
/*
* "pointInside" function
*/
+/* Warning - this is ordered - need to test both orders to be sure */
#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
static short pointInside_internal(float *vec, float *v1, float *v2, float *v3 )
{
float z,w1,w2,w3,wtot;
- if (!POINT_IN_TRI(vec, v1,v2,v3))
+
+ if (vec[2] > MAX3(v1[2], v2[2], v3[2]))
return 0;
- if (vec[2] < MAX3(v1[2], v2[2], v3[2])) {
- w1= AreaF2Dfl(vec, v2, v3);
- w2= AreaF2Dfl(v1, vec, v3);
- w3= AreaF2Dfl(v1, v2, vec);
- wtot = w1+w2+w3;
- w1/=wtot; w2/=wtot; w3/=wtot;
- z =((v1[2] * (w2+w3)) +
- (v2[2] * (w1+w3)) +
- (v3[2] * (w1+w2))) * 0.5;
- /* only return true if the face is above vec*/
- if (vec[2] < z )
- return 1;
- }
+ /* need to test both orders */
+ if (!POINT_IN_TRI(vec, v1,v2,v3) && !POINT_IN_TRI(vec, v3,v2,v1))
+ return 0;
+
+ w1= AreaF2Dfl(vec, v2, v3);
+ w2= AreaF2Dfl(v1, vec, v3);
+ w3= AreaF2Dfl(v1, v2, vec);
+ wtot = w1+w2+w3;
+ w1/=wtot; w2/=wtot; w3/=wtot;
+ z =((v1[2] * w1) +
+ (v2[2] * w2) +
+ (v3[2] * w3));
+
+ /* only return true if the face is above vec*/
+ if (vec[2] < z )
+ return 1;
+
return 0;
}
-static PyObject *Mesh_pointInside( BPy_Mesh * self, PyObject *args )
+static PyObject *Mesh_pointInside( BPy_Mesh * self, PyObject * args, PyObject *kwd )
{
- VectorObject *vec = NULL;
Mesh *mesh = self->mesh;
MFace *mf = mesh->mface;
MVert *mvert = mesh->mvert;
int i;
int isect_count=0;
+ int selected_only = 0;
+ VectorObject *vec;
+ static char *kwlist[] = {"point", "selected_only", NULL};
- if(!PyArg_ParseTuple(args, "O!", &vector_Type, &vec))
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected one or 2 vector types" );
+ if( !PyArg_ParseTupleAndKeywords(args, kwd, "|O!i", kwlist,
+ &vector_Type, &vec, &selected_only) ) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a vector and an optional bool argument");
+ }
if(vec->size < 3)
return EXPP_ReturnPyObjError(PyExc_AttributeError,
- "Mesh.pointInside(vec) expects a 3D vector objects\n");
+ "Mesh.pointInside(vec) expects a 3D vector object\n");
- for( i = 0; i < mesh->totface; ++mf, ++i ) {
- if (pointInside_internal(vec->vec, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co))
- isect_count++;
- else if (mf->v4 && pointInside_internal(vec->vec,mvert[mf->v1].co, mvert[mf->v3].co, mvert[mf->v4].co))
- isect_count++;
+ for( i = 0; i < mesh->totface; mf++, i++ ) {
+ if (!selected_only || mf->flag & ME_FACE_SEL) {
+ if (pointInside_internal(vec->vec, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co)) {
+ isect_count++;
+ } else if (mf->v4 && pointInside_internal(vec->vec,mvert[mf->v1].co, mvert[mf->v3].co, mvert[mf->v4].co)) {
+
+ isect_count++;
+ }
+ }
}
if (isect_count % 2)
@@ -7013,9 +7529,9 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Update display lists after changes to mesh"},
{"transform", (PyCFunction)Mesh_transform, METH_VARARGS | METH_KEYWORDS,
"Applies a transformation matrix to mesh's vertices"},
- {"addVertGroup", (PyCFunction)Mesh_addVertGroup, METH_VARARGS,
+ {"addVertGroup", (PyCFunction)Mesh_addVertGroup, METH_O,
"Assign vertex group name to the object linked to the mesh"},
- {"removeVertGroup", (PyCFunction)Mesh_removeVertGroup, METH_VARARGS,
+ {"removeVertGroup", (PyCFunction)Mesh_removeVertGroup, METH_O,
"Delete vertex group name from the object linked to the mesh"},
{"assignVertsToGroup", (PyCFunction)Mesh_assignVertsToGroup, METH_VARARGS,
"Assigns vertices to a vertex group"},
@@ -7053,7 +7569,7 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Removes duplicates from selected vertices (experimental)"},
{"recalcNormals", (PyCFunction)Mesh_recalcNormals, METH_VARARGS,
"Recalculates inside or outside normals (experimental)"},
- {"pointInside", (PyCFunction)Mesh_pointInside, METH_VARARGS,
+ {"pointInside", (PyCFunction)Mesh_pointInside, METH_VARARGS|METH_KEYWORDS,
"Recalculates inside or outside normals (experimental)"},
/* mesh custom data layers */
@@ -7061,9 +7577,9 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"adds a UV layer to this mesh"},
{"addColorLayer", (PyCFunction)Mesh_addColorLayer, METH_VARARGS,
"adds a color layer to this mesh "},
- {"removeUVLayer", (PyCFunction)Mesh_removeUVLayer, METH_VARARGS,
+ {"removeUVLayer", (PyCFunction)Mesh_removeUVLayer, METH_O,
"removes a UV layer to this mesh"},
- {"removeColorLayer", (PyCFunction)Mesh_removeColorLayer, METH_VARARGS,
+ {"removeColorLayer", (PyCFunction)Mesh_removeColorLayer, METH_O,
"removes a color layer to this mesh"},
{"getUVLayerNames", (PyCFunction)Mesh_getUVLayerNames, METH_NOARGS,
"Get names of UV layers"},
@@ -7073,6 +7589,9 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Rename a UV Layer"},
{"renameColorLayer", (PyCFunction)Mesh_renameColorLayer, METH_VARARGS,
"Rename a Color Layer"},
+ /* mesh multires */
+ {"addMultiresLevel", (PyCFunction)Mesh_addMultiresLevel, METH_VARARGS,
+ "(levels=1, type='catmull-clark') - adds multires levels of given type"},
/* python standard class functions */
{"__copy__", (PyCFunction)Mesh_copy, METH_NOARGS,
@@ -7121,7 +7640,7 @@ static int Mesh_setVerts( BPy_Mesh * self, PyObject * args )
free_mesh( me );
me->mvert = NULL; me->medge = NULL; me->mface = NULL;
me->mtface = NULL; me->dvert = NULL; me->mcol = NULL;
- me->msticky = NULL; me->mat = NULL; me->bb = NULL;
+ me->msticky = NULL; me->mat = NULL; me->bb = NULL; me->mselect = NULL;
me->totvert = me->totedge = me->totface = me->totcol = 0;
mesh_update( me );
return 0;
@@ -7240,13 +7759,7 @@ static int Mesh_setMaterials( BPy_Mesh *self, PyObject * value )
static PyObject *Mesh_getMaxSmoothAngle( BPy_Mesh * self )
{
- PyObject *attr = PyInt_FromLong( self->mesh->smoothresh );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->mesh->smoothresh );
}
static int Mesh_setMaxSmoothAngle( BPy_Mesh *self, PyObject *value )
@@ -7258,14 +7771,8 @@ static int Mesh_setMaxSmoothAngle( BPy_Mesh *self, PyObject *value )
static PyObject *Mesh_getSubDivLevels( BPy_Mesh * self )
{
- PyObject *attr = Py_BuildValue( "(h,h)",
+ return Py_BuildValue( "(h,h)",
self->mesh->subdiv, self->mesh->subdivr );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "Py_BuildValue() failed" );
}
static int Mesh_setSubDivLevels( BPy_Mesh *self, PyObject *value )
@@ -7295,34 +7802,23 @@ static int Mesh_setSubDivLevels( BPy_Mesh *self, PyObject *value )
static PyObject *Mesh_getFlag( BPy_Mesh * self, void *type )
{
- PyObject *attr;
-
switch( (long)type ) {
case MESH_HASFACEUV:
- attr = self->mesh->mtface ? EXPP_incr_ret_True() :
+ return self->mesh->mtface ? EXPP_incr_ret_True() :
EXPP_incr_ret_False();
- break;
case MESH_HASMCOL:
- attr = self->mesh->mcol ? EXPP_incr_ret_True() :
+ return self->mesh->mcol ? EXPP_incr_ret_True() :
EXPP_incr_ret_False();
- break;
case MESH_HASVERTUV:
- attr = self->mesh->msticky ? EXPP_incr_ret_True() :
+ return self->mesh->msticky ? EXPP_incr_ret_True() :
EXPP_incr_ret_False();
- break;
case MESH_HASMULTIRES:
- attr = self->mesh->mr ? EXPP_incr_ret_True() :
+ return self->mesh->mr ? EXPP_incr_ret_True() :
EXPP_incr_ret_False();
- break;
default:
- attr = NULL;
- }
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get attribute" );
+ }
}
static int Mesh_setFlag( BPy_Mesh * self, PyObject *value, void *type )
@@ -7334,7 +7830,7 @@ static int Mesh_setFlag( BPy_Mesh * self, PyObject *value, void *type )
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected int argument in range [0,1]" );
+ "expected True/False or 0/1" );
/* sticky is independent of faceUV and vertUV */
@@ -7405,13 +7901,7 @@ static int Mesh_setFlag( BPy_Mesh * self, PyObject *value, void *type )
static PyObject *Mesh_getMode( BPy_Mesh * self )
{
- PyObject *attr = PyInt_FromLong( self->mesh->flag );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Mesh.mode attribute" );
+ return PyInt_FromLong( self->mesh->flag );
}
static int Mesh_setMode( BPy_Mesh *self, PyObject *value )
@@ -7421,7 +7911,7 @@ static int Mesh_setMode( BPy_Mesh *self, PyObject *value )
ME_UVEFFECT | ME_VCOLEFFECT | ME_AUTOSMOOTH | ME_SMESH |
ME_SUBSURF | ME_OPT_EDGES;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check ( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%04x", bitmask );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -7448,33 +7938,19 @@ static PyObject *Mesh_getKey( BPy_Mesh * self )
static PyObject *Mesh_getActiveFace( BPy_Mesh * self )
{
- MTFace *face;
- int i, totface;
-
+ /* not needed but keep incase exceptions make use of it */
if( !self->mesh->mtface )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"face has no texture values" );
- face = self->mesh->mtface;
- totface = self->mesh->totface;
-
- for( i = 0; i < totface; ++face, ++i )
- if( face->flag & TF_ACTIVE ) {
- PyObject *attr = PyInt_FromLong( i );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
- }
-
+ if (self->mesh->act_face != -1 && self->mesh->act_face <= self->mesh->totface)
+ return PyInt_FromLong( self->mesh->act_face );
+
Py_RETURN_NONE;
}
static int Mesh_setActiveFace( BPy_Mesh * self, PyObject * value )
{
- MTFace *face;
int param;
/* if no texture faces, error */
@@ -7485,7 +7961,7 @@ static int Mesh_setActiveFace( BPy_Mesh * self, PyObject * value )
/* if param isn't an int, error */
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected an int argument" );
@@ -7495,18 +7971,8 @@ static int Mesh_setActiveFace( BPy_Mesh * self, PyObject * value )
if( param < 0 || param > self->mesh->totface )
return EXPP_ReturnIntError( PyExc_TypeError,
"face index out of range" );
-
- face = self->mesh->mtface;
-
- /* if requested face isn't already active, then inactivate all
- * faces and activate the requested one */
-
- if( !( face[param].flag & TF_ACTIVE ) ) {
- int i;
- for( i = self->mesh->totface; i > 0; ++face, --i )
- face->flag &= ~TF_ACTIVE;
- self->mesh->mtface[param].flag |= TF_ACTIVE;
- }
+
+ self->mesh->act_face = param;
return 0;
}
@@ -7570,18 +8036,22 @@ static int Mesh_setTexMesh( BPy_Mesh * self, PyObject * value )
if (ret==0 && value!=Py_None) /*This must be a mesh type*/
(( BPy_Mesh * ) value)->new= 0;
- return 0;
+ return ret;
}
-static int Mesh_setSel( BPy_Mesh * self, PyObject * arg )
+static int Mesh_setSel( BPy_Mesh * self, PyObject * value )
{
- int i;
+ int i, param = PyObject_IsTrue( value );
Mesh *me = self->mesh;
MVert *mvert = me->mvert;
MEdge *medge = me->medge;
MFace *mface = me->mface;
- if( PyObject_IsTrue( arg ) ) {
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param ) {
for( i = 0; i < me->totvert; ++mvert, ++i )
mvert->flag |= SELECT;
for( i = 0; i < me->totedge; ++medge, ++i )
@@ -7600,15 +8070,19 @@ static int Mesh_setSel( BPy_Mesh * self, PyObject * arg )
return 0;
}
-static int Mesh_setHide( BPy_Mesh * self, PyObject * arg )
+static int Mesh_setHide( BPy_Mesh * self, PyObject * value )
{
- int i;
+ int i, param = PyObject_IsTrue( value );
Mesh *me = self->mesh;
MVert *mvert = me->mvert;
MEdge *medge = me->medge;
MFace *mface = me->mface;
- if( PyObject_IsTrue( arg ) ) {
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param ) {
for( i = 0; i < me->totvert; ++mvert, ++i )
mvert->flag |= ME_HIDE;
for( i = 0; i < me->totedge; ++medge, ++i )
@@ -8077,7 +8551,7 @@ static PyObject *M_Mesh_FaceFlagsDict( void )
PyConstant_Insert( d, "SELECT", PyInt_FromLong( TF_SELECT ) );
PyConstant_Insert( d, "HIDE", PyInt_FromLong( TF_HIDE ) );
- PyConstant_Insert( d, "ACTIVE", PyInt_FromLong( TF_ACTIVE ) );
+ PyConstant_Insert( d, "ACTIVE", PyInt_FromLong( TF_ACTIVE ) ); /* deprecated */
}
return FF;
@@ -8156,7 +8630,8 @@ PyObject *Mesh_Init( void )
PyObject *EdgeFlags = M_Mesh_EdgeFlagsDict( );
PyObject *AssignModes = M_Mesh_VertAssignDict( );
PyObject *SelectModes = M_Mesh_SelectModeDict( );
-
+ PyObject *PropertyTypes = M_Mesh_PropertiesTypeDict( );
+
if( PyType_Ready( &MCol_Type ) < 0 )
return NULL;
if( PyType_Ready( &MVert_Type ) < 0 )
@@ -8196,6 +8671,9 @@ PyObject *Mesh_Init( void )
PyModule_AddObject( submodule, "AssignModes", AssignModes );
if( SelectModes )
PyModule_AddObject( submodule, "SelectModes", SelectModes );
+ if( PropertyTypes )
+ PyModule_AddObject( submodule, "PropertyTypes", PropertyTypes );
+
return submodule;
diff --git a/source/blender/python/api2_2x/Metaball.c b/source/blender/python/api2_2x/Metaball.c
index aeb935c72e1..98dc7ea1127 100644
--- a/source/blender/python/api2_2x/Metaball.c
+++ b/source/blender/python/api2_2x/Metaball.c
@@ -661,7 +661,7 @@ static int Metaball_setUpdate( BPy_Metaball * self, PyObject * value )
{
int param;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"metaball.update - expected an int argument" );
@@ -744,24 +744,15 @@ static void Metaelem_dealloc( BPy_Metaelem * self )
* elem.type - int to set the shape of the element
*/
static PyObject *Metaelem_getType( BPy_Metaelem *self )
-{
- PyObject *attr = NULL;
-
+{
METAELEM_DEL_CHECK_PY(self);
- attr = PyInt_FromLong( self->metaelem->type );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "metaelem.type - PyInt_FromLong() failed!" );
+ return PyInt_FromLong( self->metaelem->type );
}
static int Metaelem_setType( BPy_Metaelem * self, PyObject * value )
{
-
int type;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"metaelem.type - expected an integer (bitmask) as argument" );
@@ -1066,12 +1057,11 @@ static PyObject *MetaElemSeq_add( BPy_MetaElemSeq * self )
* no args are taken so the returned metaball must be modified after adding.
* Accessed as mball.elements.add() where mball is a python metaball data type.
*/
-static PyObject *MetaElemSeq_remove( BPy_MetaElemSeq * self, PyObject *args )
+static PyObject *MetaElemSeq_remove( BPy_MetaElemSeq * self, BPy_Metaelem *elem )
{
- BPy_Metaelem *elem;
MetaElem *ml_iter, *ml_py;
- if( !PyArg_ParseTuple( args, "O!", &Metaelem_Type, &elem) )
+ if( !BPy_Metaelem_Check(elem) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"elements.remove(metaelem) - expected a Metaball element" );
@@ -1095,7 +1085,7 @@ static PyObject *MetaElemSeq_remove( BPy_MetaElemSeq * self, PyObject *args )
static struct PyMethodDef BPy_MetaElemSeq_methods[] = {
{"add", (PyCFunction)MetaElemSeq_add, METH_NOARGS,
"add metaelem to metaball data"},
- {"remove", (PyCFunction)MetaElemSeq_remove, METH_VARARGS,
+ {"remove", (PyCFunction)MetaElemSeq_remove, METH_O,
"remove element from metaball data"},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/Modifier.c b/source/blender/python/api2_2x/Modifier.c
index 5a820ae4bdc..f965bfee91b 100644
--- a/source/blender/python/api2_2x/Modifier.c
+++ b/source/blender/python/api2_2x/Modifier.c
@@ -44,6 +44,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "MEM_guardedalloc.h"
+#include "BDR_editobject.h"
#include "butspace.h"
#include "blendef.h"
#include "mydevice.h"
@@ -749,11 +750,11 @@ static int wave_setter( BPy_Modifier *self, int type, PyObject *value )
case EXPP_MOD_SPEED:
return EXPP_setFloatClamped( value, &md->speed, -2.0, 2.0 );
case EXPP_MOD_DAMP:
- return EXPP_setFloatClamped( value, &md->damp, -1000.0, 1000.0 );
+ return EXPP_setFloatClamped( value, &md->damp, -MAXFRAMEF, MAXFRAMEF );
case EXPP_MOD_LIFETIME:
- return EXPP_setFloatClamped( value, &md->lifetime, -1000.0, 1000.0 );
+ return EXPP_setFloatClamped( value, &md->lifetime, -MAXFRAMEF, MAXFRAMEF );
case EXPP_MOD_TIMEOFFS:
- return EXPP_setFloatClamped( value, &md->timeoffs, -1000.0, 1000.0 );
+ return EXPP_setFloatClamped( value, &md->timeoffs, -MAXFRAMEF, MAXFRAMEF );
case EXPP_MOD_FLAG:
return EXPP_setIValueRange( value, &md->flag, 0,
MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL, 'h' );
@@ -776,8 +777,6 @@ static PyObject *array_getter( BPy_Modifier * self, int type )
return PyFloat_FromDouble( md->length );
else if( type == EXPP_MOD_MERGE_DIST )
return PyFloat_FromDouble( md->merge_dist );
- else if( type == EXPP_MOD_MERGE_DIST )
- return PyFloat_FromDouble( md->merge_dist );
else if( type == EXPP_MOD_OFFSET_VEC)
return newVectorObject( md->offset, 3, Py_NEW );
else if( type == EXPP_MOD_SCALE_VEC)
@@ -987,7 +986,7 @@ static PyObject *Modifier_getData( BPy_Modifier * self, PyObject * key )
{
int setting;
- if( !PyInt_CheckExact( key ) )
+ if( !PyInt_Check( key ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an int arg as stored in Blender.Modifier.Settings" );
@@ -1261,24 +1260,23 @@ static PySequenceMethods ModSeq_as_sequence = {
* helper function to check for a valid modifier argument
*/
-static ModifierData *locate_modifier( BPy_ModSeq *self, PyObject * args )
+static ModifierData *locate_modifier( BPy_ModSeq *self, BPy_Modifier * value )
{
- BPy_Modifier *pyobj;
ModifierData *md;
/* check that argument is a modifier */
- if( !PyArg_ParseTuple( args, "O!", &Modifier_Type, &pyobj ) )
+ if( !BPy_Modifier_Check(value) )
return (ModifierData *)EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an modifier as an argument" );
/* check whether modifier has been removed */
- if( !pyobj->md )
+ if( !value->md )
return (ModifierData *)EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This modifier has been removed!" );
/* find the modifier in the object's list */
for( md = self->object->modifiers.first; md; md = md->next )
- if( md == pyobj->md )
+ if( md == value->md )
return md;
/* return exception if we can't find the modifier */
@@ -1288,18 +1286,14 @@ static ModifierData *locate_modifier( BPy_ModSeq *self, PyObject * args )
/* create a new modifier at the end of the list */
-static PyObject *ModSeq_append( BPy_ModSeq *self, PyObject *args )
+static PyObject *ModSeq_append( BPy_ModSeq *self, PyObject *value )
{
- int type;
-
- if( !PyArg_ParseTuple( args, "i", &type ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected int argument" );
-
+ int type = PyInt_AsLong(value);
+
/* type 0 is eModifierType_None, should we be able to add one of these? */
if( type <= 0 || type >= NUM_MODIFIER_TYPES )
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "int argument out of range, expected an int from Blender.Modifier.Type" );
+ "Not an int or argument out of range, expected an int from Blender.Modifier.Type" );
BLI_addtail( &self->object->modifiers, modifier_new( type ) );
return Modifier_CreatePyObject( self->object, self->object->modifiers.last );
@@ -1307,10 +1301,9 @@ static PyObject *ModSeq_append( BPy_ModSeq *self, PyObject *args )
/* remove an existing modifier */
-static PyObject *ModSeq_remove( BPy_ModSeq *self, PyObject *args )
+static PyObject *ModSeq_remove( BPy_ModSeq *self, BPy_Modifier *value )
{
- ModifierData *md = locate_modifier( self, args );
- BPy_Modifier *py_obj;
+ ModifierData *md = locate_modifier( self, value );
/* if we can't locate the modifier, return (exception already set) */
if( !md )
@@ -1321,17 +1314,16 @@ static PyObject *ModSeq_remove( BPy_ModSeq *self, PyObject *args )
modifier_free( md );
/* erase the link to the modifier */
- py_obj = ( BPy_Modifier * )PyTuple_GET_ITEM( args, 0 );
- py_obj->md = NULL;
+ value->md = NULL;
Py_RETURN_NONE;
}
/* move the modifier up in the stack */
-static PyObject *ModSeq_moveUp( BPy_ModSeq * self, PyObject * args )
+static PyObject *ModSeq_moveUp( BPy_ModSeq * self, BPy_Modifier * value )
{
- ModifierData *md = locate_modifier( self, args );
+ ModifierData *md = locate_modifier( self, value );
/* if we can't locate the modifier, return (exception already set) */
if( !md )
@@ -1346,9 +1338,9 @@ static PyObject *ModSeq_moveUp( BPy_ModSeq * self, PyObject * args )
/* move the modifier down in the stack */
-static PyObject *ModSeq_moveDown( BPy_ModSeq * self, PyObject *args )
+static PyObject *ModSeq_moveDown( BPy_ModSeq * self, BPy_Modifier *value )
{
- ModifierData *md = locate_modifier( self, args );
+ ModifierData *md = locate_modifier( self, value );
/* if we can't locate the modifier, return (exception already set) */
if( !md )
@@ -1361,19 +1353,33 @@ static PyObject *ModSeq_moveDown( BPy_ModSeq * self, PyObject *args )
Py_RETURN_NONE;
}
+
+/* quick hack for ZanQdo: add new hook modifier for selected verts */
+static PyObject *ModSeq_ZanQdoHack(BPy_ModSeq *self)
+{
+ /* this should add the hook (assumes that modifier stack is on same ob!) */
+ if ((self) && (G.obedit) && (self->object==G.obedit)) {
+ add_hook(1);
+ }
+
+ Py_RETURN_NONE;
+}
+
/*****************************************************************************/
/* Python BPy_ModSeq methods table: */
/*****************************************************************************/
static PyMethodDef BPy_ModSeq_methods[] = {
/* name, method, flags, doc */
- {"append", ( PyCFunction ) ModSeq_append, METH_VARARGS,
+ {"append", ( PyCFunction ) ModSeq_append, METH_O,
"(type) - add a new modifier, where type is the type of modifier"},
- {"remove", ( PyCFunction ) ModSeq_remove, METH_VARARGS,
+ {"remove", ( PyCFunction ) ModSeq_remove, METH_O,
"(modifier) - remove an existing modifier, where modifier is a modifier from this object."},
- {"moveUp", ( PyCFunction ) ModSeq_moveUp, METH_VARARGS,
+ {"moveUp", ( PyCFunction ) ModSeq_moveUp, METH_O,
"(modifier) - Move a modifier up in stack"},
- {"moveDown", ( PyCFunction ) ModSeq_moveDown, METH_VARARGS,
+ {"moveDown", ( PyCFunction ) ModSeq_moveDown, METH_O,
"(modifier) - Move a modifier down in stack"},
+ {"ZanQdoHack", (PyCFunction)ModSeq_ZanQdoHack, METH_NOARGS,
+ "while in editmode, adds a hook for the selected verts (adds new modifier, and deselects object)"},
{NULL, NULL, 0, NULL}
};
@@ -1512,6 +1518,8 @@ static PyObject *M_Modifier_TypeDict( void )
PyInt_FromLong( eModifierType_Smooth ) );
PyConstant_Insert( d, "CAST",
PyInt_FromLong( eModifierType_Cast ) );
+ PyConstant_Insert( d, "DISPLACE",
+ PyInt_FromLong( eModifierType_Displace ) );
}
return S;
}
diff --git a/source/blender/python/api2_2x/NLA.c b/source/blender/python/api2_2x/NLA.c
index 12d948120dd..8fbb468de88 100644
--- a/source/blender/python/api2_2x/NLA.c
+++ b/source/blender/python/api2_2x/NLA.c
@@ -87,11 +87,11 @@ struct PyMethodDef M_NLA_methods[] = {
/*****************************************************************************/
static PyObject *Action_setActive( BPy_Action * self, PyObject * args );
static PyObject *Action_getFrameNumbers(BPy_Action *self);
-static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args );
+static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * value );
static PyObject *Action_getChannelNames( BPy_Action * self );
static PyObject *Action_renameChannel( BPy_Action * self, PyObject * args );
-static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args );
-static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args );
+static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * value );
+static PyObject *Action_removeChannel( BPy_Action * self, PyObject * value );
static PyObject *Action_getAllChannelIpos( BPy_Action * self );
/*****************************************************************************/
@@ -107,15 +107,15 @@ static PyMethodDef BPy_Action_methods[] = {
"(str) -set this action as the active action for an object"},
{"getFrameNumbers", (PyCFunction) Action_getFrameNumbers, METH_NOARGS,
"() - get the frame numbers at which keys have been inserted"},
- {"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_VARARGS,
+ {"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_O,
"(str) -get the Ipo from a named action channel in this action"},
{"getChannelNames", ( PyCFunction ) Action_getChannelNames, METH_NOARGS,
"() -get the channel names for this action"},
{"renameChannel", ( PyCFunction ) Action_renameChannel, METH_VARARGS,
"(from, to) -rename the channel from string to string"},
- {"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_VARARGS,
+ {"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_O,
"(str) -verify the channel in this action"},
- {"removeChannel", ( PyCFunction ) Action_removeChannel, METH_VARARGS,
+ {"removeChannel", ( PyCFunction ) Action_removeChannel, METH_O,
"(str) -remove the channel from the action"},
{"getAllChannelIpos", ( PyCFunction ) Action_getAllChannelIpos,
METH_NOARGS,
@@ -221,18 +221,20 @@ static PyObject *Action_getFrameNumbers(BPy_Action *self)
py_list = PyList_New(0);
for(achan = self->action->chanbase.first; achan; achan = achan->next){
- for (icu = achan->ipo->curve.first; icu; icu = icu->next){
- bezt= icu->bezt;
- if(bezt) {
- verts = icu->totvert;
- while(verts--) {
- PyObject *value;
- value = PyInt_FromLong((int)bezt->vec[1][0]);
- if ( PySequence_Contains(py_list, value) == 0){
- PyList_Append(py_list, value);
+ if (achan->ipo) {
+ for (icu = achan->ipo->curve.first; icu; icu = icu->next){
+ bezt= icu->bezt;
+ if(bezt) {
+ verts = icu->totvert;
+ while(verts--) {
+ PyObject *value;
+ value = PyInt_FromLong((int)bezt->vec[1][0]);
+ if ( PySequence_Contains(py_list, value) == 0){
+ PyList_Append(py_list, value);
+ }
+ Py_DECREF(value);
+ bezt++;
}
- Py_DECREF(value);
- bezt++;
}
}
}
@@ -268,12 +270,12 @@ static PyObject *Action_setActive( BPy_Action * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args )
+static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * value )
{
- char *chanName;
+ char *chanName = PyString_AsString(value);
bActionChannel *chan;
- if( !PyArg_ParseTuple( args, "s", &chanName ) )
+ if( !chanName )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"string expected" );
@@ -328,16 +330,16 @@ static PyObject *Action_renameChannel( BPy_Action * self, PyObject * args )
}
/*----------------------------------------------------------------------*/
-static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args )
+static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * value )
{
- char *chanName;
+ char *chanName = PyString_AsString(value);
bActionChannel *chan;
if( !self->action )
( EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't create channel for a NULL action" ) );
- if( !PyArg_ParseTuple( args, "s", &chanName ) )
+ if( !chanName )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected string argument" ) );
@@ -347,16 +349,15 @@ static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args )
}
-static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args )
+static PyObject *Action_removeChannel( BPy_Action * self, PyObject * value )
{
- char *chanName;
+ char *chanName = PyString_AsString(value);
bActionChannel *chan;
- if( !PyArg_ParseTuple( args, "s", &chanName ) ) {
- EXPP_ReturnPyObjError( PyExc_AttributeError,
- "string expected" );
- return NULL;
- }
+ if( !chanName )
+ return (EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "string expected" ));
+
chan = get_action_channel( self->action, chanName );
if( chan == NULL ) {
@@ -804,7 +805,8 @@ static int ActionStrip_setBlendMode( BPy_ActionStrip * self, PyObject * value )
*/
#define ACTIONSTRIP_MASK (ACTSTRIP_SELECT | ACTSTRIP_USESTRIDE \
- | ACTSTRIP_HOLDLASTFRAME | ACTSTRIP_ACTIVE | ACTSTRIP_LOCK_ACTION)
+ | ACTSTRIP_HOLDLASTFRAME | ACTSTRIP_ACTIVE | ACTSTRIP_LOCK_ACTION \
+ | ACTSTRIP_MUTE)
static PyObject *ActionStrip_getFlag( BPy_ActionStrip * self )
{
@@ -1180,6 +1182,8 @@ static PyObject *M_ActionStrip_FlagsDict( void )
PyInt_FromLong( ACTSTRIP_ACTIVE ) );
PyConstant_Insert( d, "LOCK_ACTION",
PyInt_FromLong( ACTSTRIP_LOCK_ACTION ) );
+ PyConstant_Insert( d, "MUTE",
+ PyInt_FromLong( ACTSTRIP_MUTE ) );
}
return S;
}
diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c
index 0a4e8b50406..b443952d1d2 100644
--- a/source/blender/python/api2_2x/NMesh.c
+++ b/source/blender/python/api2_2x/NMesh.c
@@ -1554,13 +1554,7 @@ Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh )
static PyObject *NMesh_getMaxSmoothAngle( BPy_NMesh * self )
{
- PyObject *attr = PyInt_FromLong( self->smoothresh );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get NMesh.maxSmoothAngle attribute" );
+ return PyInt_FromLong( self->smoothresh );
}
static PyObject *NMesh_setMaxSmoothAngle( PyObject * self, PyObject * args )
@@ -1581,14 +1575,7 @@ static PyObject *NMesh_setMaxSmoothAngle( PyObject * self, PyObject * args )
static PyObject *NMesh_getSubDivLevels( BPy_NMesh * self )
{
- PyObject *attr =
- Py_BuildValue( "[h,h]", self->subdiv[0], self->subdiv[1] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get NMesh.subDivLevels attribute" );
+ return Py_BuildValue( "[h,h]", self->subdiv[0], self->subdiv[1] );
}
static PyObject *NMesh_setSubDivLevels( PyObject * self, PyObject * args )
@@ -1613,13 +1600,7 @@ static PyObject *NMesh_setSubDivLevels( PyObject * self, PyObject * args )
static PyObject *NMesh_getMode( BPy_NMesh * self )
{
- PyObject *attr = PyInt_FromLong( self->mode );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get NMesh.mode attribute" );
+ return PyInt_FromLong( self->mode );
}
static PyObject *NMesh_setMode( PyObject * self, PyObject * args )
@@ -1997,20 +1978,11 @@ static BPy_NMVert *nmvert_from_data( MVert * vert, MSticky * st, float *co,
static int get_active_faceindex( Mesh * me )
{
- MTFace *tf;
- int i;
-
if( me == NULL )
return -1;
- tf = me->mtface;
- if( tf == 0 )
- return -1;
-
- for( i = 0; i < me->totface; i++ )
- if( tf[i].flag & TF_ACTIVE )
- return i;
-
+ if (me->act_face != -1 && me->act_face < me->totface)
+ return me->act_face;
return -1;
}
@@ -2571,13 +2543,15 @@ static int assignFaceUV( MTFace * tf, BPy_NMFace * nmface )
/* fuv = [(u_1, v_1), ... (u_n, v_n)] */
for( i = 0; i < len; i++ ) {
- tmp = PyList_GetItem( fuv, i ); /* stolen reference ! */
+ tmp = PySequence_GetItem( fuv, i ); /* stolen reference ! */
if( !PyArg_ParseTuple
( tmp, "ff", &( tf->uv[i][0] ), &( tf->uv[i][1] ) ) ) {
PyErr_SetString ( PyExc_TypeError,
"expected tuple of two floats for uv" );
+ Py_DECREF( tmp );
return 0;
}
+ Py_DECREF( tmp );
}
if( nmface->image ) { /* image assigned ? */
tf->tpage = ( void * ) nmface->image;
diff --git a/source/blender/python/api2_2x/Node.c b/source/blender/python/api2_2x/Node.c
index 296a30dea4e..0a68509d287 100644
--- a/source/blender/python/api2_2x/Node.c
+++ b/source/blender/python/api2_2x/Node.c
@@ -30,12 +30,12 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#ifdef USE_PYNODES /* note: won't work without patch */
#include "Node.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_utildefines.h"
#include "DNA_material_types.h"
@@ -48,138 +48,199 @@ static PyObject *Node_repr( BPy_Node * self );
static int Node_compare(BPy_Node *a, BPy_Node *b);
static PyObject *ShadeInput_repr( BPy_ShadeInput * self );
static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b);
+static BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi);
/**
- * Take the descriptions from dict and create sockets for those in socks
+ * Take the descriptions from list and create sockets for those in socks
* socks is a socketstack from a bNodeTypeInfo
*/
-static int dict_socks_to_typeinfo(PyObject *dict, bNodeSocketType **socks, int len, int stage) {
- int a = 0, pos = 0;
- PyObject *key = NULL, *value = NULL;
+static int list_socks_to_typeinfo(PyObject *tuple, bNodeSocketType **socks, int stage, int limit) {
+ int len = 0, a = 0, pos = 0, retval = 0;
+ //wPyObject *key = NULL, *value = NULL;
+ PyObject *item, *arg;
bNodeSocketType *newsocks = NULL;
+ char *s_name = NULL;
+ int s_type = SOCK_VALUE;
+ float s_val[4], s_min, s_max;
- if(stage!=SH_NODE_DYNAMIC_READY && stage!=SH_NODE_DYNAMIC_ADDEXIST) {
- newsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType");
-
- if (dict) {
- if(PyDict_Check(dict)) {
- while(PyDict_Next(dict, &pos, &key, &value)) {
- if(PyTuple_Check(value) && PyTuple_Size(value)==7) {
- newsocks[a].name = BLI_strdup(PyString_AsString(key));
- newsocks[a].type = (int)(PyInt_AsLong(PyTuple_GetItem(value, 0)));
- newsocks[a].val1 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 1)));
- newsocks[a].val2 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 2)));
- newsocks[a].val3 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 3)));
- newsocks[a].val4 = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 4)));
- newsocks[a].min = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 5)));
- newsocks[a].max = (float)(PyFloat_AsDouble(PyTuple_GetItem(value, 6)));
- a++;
- }
- }
- } else {
- return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a dict"));
- }
+ if (BTST2(stage, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
+ return 0; /* already has sockets */
+
+ len = PyTuple_Size(tuple);
+
+ newsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
+
+ for (pos = 0, a = 0; pos< len; pos++, a++) {
+ /* default socket values: */
+ s_name = NULL;
+ s_type = SOCK_VALUE;
+ s_min = 0.0f;
+ s_max = 1.0f;
+ s_val[0] = s_val[1] = s_val[2] = s_val[3] = 1.0f;
+
+ item = PyTuple_GetItem(tuple, pos);
+
+ if (!PySequence_Check(item)) {
+ PyErr_SetString(PyExc_AttributeError, "a socket must be a List of Lists or Tuples");
+ retval = -1;
+ break;
}
- newsocks[a].type = -1;
- if(*socks) {
- int b = 0;
- while((*socks)[b].type!=-1) {
- MEM_freeN((*socks)[b].name);
- (*socks)[b].name = NULL;
- b++;
- }
- MEM_freeN(*socks);
+
+ arg = PySequence_Tuple(item);
+
+ if (!PyArg_ParseTuple(arg, "s|iffffff", &s_name, &s_type,
+ &s_min, &s_max,
+ &s_val[0], &s_val[1], &s_val[2], &s_val[3] )) {
+ PyErr_SetString(PyExc_AttributeError, "socket definitions require a string and optionally an int and 6 floats");
+ retval = -1;
+ Py_DECREF(arg);
+ break;
}
- *socks = newsocks;
+
+ newsocks[a].name = BLI_strdupn(s_name, NODE_MAXSTR);
+ newsocks[a].type = s_type;
+ newsocks[a].min = s_min;
+ newsocks[a].max = s_max;
+ newsocks[a].val1 = s_val[0];
+ newsocks[a].val2 = s_val[1];
+ newsocks[a].val3 = s_val[2];
+ newsocks[a].val4 = s_val[3];
+ newsocks[a].limit = limit;
+
+ Py_DECREF(arg);
}
- return 0;
+
+ newsocks[a].type = -1;
+
+ *socks = newsocks;
+
+ return retval;
}
-/* Get number of complying entries in a dict.
+/* Get number of complying entries in a list.
*
*/
-static int num_dict_sockets(PyObject *dict) {
- int a = 0, pos = 0;
- PyObject *key = NULL, *value = NULL;
- while(PyDict_Next(dict, &pos, &key, &value)) {
- if(PyTuple_Check(value) && PyTuple_Size(value)==7)
- a++;
+/* unused
+static int num_list_sockets(PyObject *list) {
+ int size = 0;
+ int i = 0, count = 0;
+ PyObject *element = NULL;
+
+ size = PyList_Size(list);
+ for(i = 0; i < size; i++) {
+ element = PyList_GetItem(list, i);
+ //wPy_INCREF(element);
+ if(PyList_Check(element) && PyList_Size(element) == 8)
+ count++;
+ //wPy_DECREF(element);
}
- return a;
+ return count;
+}
+*/
+static void NodeSockets_dealloc(BPy_NodeSockets *self)
+{
+ Py_DECREF(self->input);
+ Py_DECREF(self->output);
+ self->ob_type->tp_free((PyObject *)self);
}
-static int Map_socketdef(PyObject *self, PyObject *args, void *closure)
+static PyObject *Map_socketdef_getter(BPy_NodeSockets *self, void *closure)
{
- int newincnt = 0, newoutcnt = 0;
- bNode *node = NULL;
- BPy_DefinitionMap *defs= NULL;
+ PyObject *sockets = NULL;
- Py_INCREF(args);
- Py_INCREF(self);
+ switch ((int)closure) {
+ case 'I': /* inputs */
+ Py_INCREF(self->input);
+ sockets = self->input;
+ break;
+ case 'O': /* outputs */
+ Py_INCREF(self->output);
+ sockets = self->output;
+ break;
+ default:
+ fprintf(stderr, "DEBUG pynodes: wrong option in Map_socketdef_getter\n");
+ Py_INCREF(Py_None);
+ sockets = Py_None;
+ break;
+ }
+
+ return sockets;
+}
+
+static int Map_socketdef(BPy_NodeSockets *self, PyObject *args, void *closure)
+{
+ bNode *node = NULL;
+ PyObject *tuple = NULL;
- defs= (BPy_DefinitionMap *)self;
- node= defs->node;
+ node = self->node;
if(!node) {
- fprintf(stderr,"! no bNode in BPy_Node (Map_socketdef)\n");
+ fprintf(stderr,"DEBUG pynodes: No bNode in BPy_Node (Map_socketdef)\n");
return 0;
}
- if(node->custom1==SH_NODE_DYNAMIC_READY && node->custom1==SH_NODE_DYNAMIC_ADDEXIST)
+ if(BTST2(node->custom1, NODE_DYNAMIC_READY, NODE_DYNAMIC_ADDEXIST))
return 0;
switch((int)closure) {
case 'I':
if (args) {
- if(PyDict_Check(args)) {
- newincnt = num_dict_sockets(args);
- dict_socks_to_typeinfo(args, &(node->typeinfo->inputs), newincnt, node->custom1);
+ if(PySequence_Check(args)) {
+ tuple = PySequence_Tuple(args);
+ list_socks_to_typeinfo(tuple, &(node->typeinfo->inputs), node->custom1, 1);
+ Py_DECREF(self->input);
+ self->input = tuple;
} else {
- Py_DECREF(self);
- Py_DECREF(args);
- return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a dict"));
+ return(EXPP_ReturnIntError( PyExc_AttributeError, "INPUT must be a List of Lists or Tuples"));
}
}
break;
case 'O':
if (args) {
- if(PyDict_Check(args)) {
- newoutcnt = num_dict_sockets(args);
- dict_socks_to_typeinfo(args, &(node->typeinfo->outputs), newoutcnt, node->custom1);
+ if(PyList_Check(args)) {
+ tuple = PySequence_Tuple(args);
+ list_socks_to_typeinfo(tuple, &(node->typeinfo->outputs), node->custom1, 0);
+ Py_DECREF(self->output);
+ self->output = tuple;
} else {
- Py_DECREF(self);
- Py_DECREF(args);
- return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a dict"));
+ return(EXPP_ReturnIntError( PyExc_AttributeError, "OUTPUT must be a List of Lists or Tuples"));
}
}
break;
default:
- fprintf(stderr, "Hrm, why we got no dict? Todo: figure out proper complaint to scripter\n");
+ fprintf(stderr,"DEBUG pynodes: got no list in Map_socketdef\n");
break;
}
- Py_DECREF(self);
- Py_DECREF(args);
return 0;
}
-static PyGetSetDef InputDefMap_getseters[] = {
- {"definitions", (getter)NULL, (setter)Map_socketdef,
- "Set the inputs definition (dictionary)",
+static PyGetSetDef NodeSockets_getseters[] = {
+ {"input", (getter)Map_socketdef_getter, (setter)Map_socketdef,
+ "Set this node's input sockets (list of lists or tuples)",
+ (void *)'I'},
+ {"i" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
+ "Set this node's input sockets (list of lists or tuples)",
(void *)'I'},
+ {"output", (getter)Map_socketdef_getter, (setter)Map_socketdef,
+ "Set this node's output sockets (list of lists or tuples)",
+ (void *)'O'},
+ {"o" /*alias*/, (getter)Map_socketdef_getter, (setter)Map_socketdef,
+ "Set this node's output sockets (list of lists or tuples)",
+ (void *)'O'},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
-PyTypeObject InputDefMap_Type = {
+PyTypeObject NodeSockets_Type = {
PyObject_HEAD_INIT( NULL ) /* required py macro */
0, /* ob_size */
/* For printing, in format "<module>.<name>" */
- "Blender.Node.InputDefinitions", /* char *tp_name; */
- sizeof( BPy_DefinitionMap ), /* int tp_basicsize; */
+ "Blender.Node.Sockets", /* char *tp_name; */
+ sizeof( BPy_NodeSockets ), /* int tp_basicsize; */
0, /* tp_itemsize; For allocation */
/* Methods to implement standard operations */
- NULL,/* destructor tp_dealloc; */
+ (destructor)NodeSockets_dealloc,/* destructor tp_dealloc; */
NULL, /* printfunc tp_print; */
NULL, /* getattrfunc tp_getattr; */
NULL, /* setattrfunc tp_setattr; */
@@ -229,7 +290,7 @@ PyTypeObject InputDefMap_Type = {
/*** Attribute descriptor and subclassing stuff ***/
0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
- InputDefMap_getseters, /* struct PyGetSetDef *tp_getset; */
+ NodeSockets_getseters, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
NULL, /* PyObject *tp_dict; */
NULL, /* descrgetfunc tp_descr_get; */
@@ -251,127 +312,48 @@ PyTypeObject InputDefMap_Type = {
NULL
};
-BPy_DefinitionMap *Node_CreateInputDefMap(bNode *node) {
- BPy_DefinitionMap *map = PyObject_NEW(BPy_DefinitionMap, &InputDefMap_Type);
- map->node = node;
- return map;
+BPy_NodeSockets *Node_CreateSockets(bNode *node) {
+ BPy_NodeSockets *sockets = PyObject_NEW(BPy_NodeSockets, &NodeSockets_Type);
+ sockets->node = node;
+ sockets->input = PyList_New(0);
+ sockets->output = PyList_New(0);
+ return sockets;
}
/***************************************/
-static PyGetSetDef OutputDefMap_getseters[] = {
- {"definitions", (getter)NULL, (setter)Map_socketdef,
- "Set the outputs definition (dictionary)",
- (void *)'O'},
- {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
-};
-
-PyTypeObject OutputDefMap_Type = {
- PyObject_HEAD_INIT( NULL ) /* required py macro */
- 0, /* ob_size */
- /* For printing, in format "<module>.<name>" */
- "Blender.Node.OutputDefinitions", /* char *tp_name; */
- sizeof( BPy_DefinitionMap ), /* int tp_basicsize; */
- 0, /* tp_itemsize; For allocation */
-
- /* Methods to implement standard operations */
-
- NULL,/* destructor tp_dealloc; */
- NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- NULL, /* reprfunc tp_repr; */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- 0, //( getiterfunc) MVertSeq_getIter, /* getiterfunc tp_iter; */
- 0, //( iternextfunc ) MVertSeq_nextIter, /* iternextfunc tp_iternext; */
+static int sockinmap_len ( BPy_SockMap * self) {
+ bNode *node = self->node;
+ bNodeType *tinfo;
+ int a = 0;
- /*** Attribute descriptor and subclassing stuff ***/
- 0, //BPy_MVertSeq_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- OutputDefMap_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL
-};
+ if (!node) return 0;
-BPy_DefinitionMap *Node_CreateOutputDefMap(bNode *node) {
- BPy_DefinitionMap *map = PyObject_NEW(BPy_DefinitionMap, &OutputDefMap_Type);
- map->node = node;
- return map;
-}
+ tinfo = node->typeinfo;
-/***************************************/
+ if (BNTST(node->custom1, NODE_DYNAMIC_READY)) return 0;
-static int sockinmap_len ( BPy_SockMap * self) {
- int a = 0;
- if(self->typeinfo) {
- while(self->typeinfo->inputs[a].type!=-1)
+ if (tinfo && tinfo->inputs) {
+ while(self->node->typeinfo->inputs[a].type!=-1)
a++;
}
return a;
}
static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
+ bNode *node = self->node;
+ bNodeType *tinfo;
+ char *strkey = NULL;
int a = 0;
- char *strkey = PyString_AsString(key);
- if(self->typeinfo){
- while(self->typeinfo->inputs[a].type!=-1) {
- if(BLI_strcaseeq(self->typeinfo->inputs[a].name, strkey)) {
+ if (!node) return -1;
+
+ tinfo = node->typeinfo;
+ strkey = PyString_AsString(key);
+
+ if(tinfo && tinfo->inputs){
+ while(self->node->typeinfo->inputs[a].type!=-1) {
+ if(BLI_strcaseeq(self->node->typeinfo->inputs[a].name, strkey)) {
return a;
}
a++;
@@ -380,39 +362,46 @@ static int sockinmap_has_key( BPy_SockMap *self, PyObject *key) {
return -1;
}
-PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *idx) {
- int a, _idx;
- a = sockinmap_len(self);
+PyObject *sockinmap_subscript(BPy_SockMap *self, PyObject *pyidx) {
+ int idx;
- if (PyString_Check(idx)) {
- _idx = sockinmap_has_key( self, idx);
+ if (!self->node)
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError, "no access to Blender node data!");
+
+ if (PyString_Check(pyidx)) {
+ idx = sockinmap_has_key(self, pyidx);
}
- else if(PyInt_Check(idx)) {
- PyErr_SetString(PyExc_ValueError, "int index not implemented");
- Py_RETURN_NONE;
+ else if(PyInt_Check(pyidx)) {
+ int len = sockinmap_len(self);
+ idx = (int)PyInt_AsLong(pyidx);
+ if (idx < 0 || idx >= len)
+ return EXPP_ReturnPyObjError(PyExc_IndexError, "index out of range");
}
- else if (PySlice_Check(idx)) {
- PyErr_SetString(PyExc_ValueError, "slices not implemented");
- Py_RETURN_NONE;
+ else if (PySlice_Check(pyidx)) {
+ return EXPP_ReturnPyObjError(PyExc_ValueError, "slices not implemented");
} else {
- PyErr_SetString(PyExc_IndexError, "Index must be string");
- Py_RETURN_NONE;
+ return EXPP_ReturnPyObjError(PyExc_IndexError, "index must be an int or a string");
}
+ if(idx<0) { /* we're not as nice as Python */
+ return EXPP_ReturnPyObjError(PyExc_IndexError, "invalid socket index");
+ }
- switch(self->typeinfo->inputs[_idx].type) {
+ switch(self->node->typeinfo->inputs[idx].type) {
case SOCK_VALUE:
- return Py_BuildValue("f", self->stack[_idx]->vec[0]);
+ return Py_BuildValue("f", self->stack[idx]->vec[0]);
break;
case SOCK_VECTOR:
- return Py_BuildValue("(fff)", self->stack[_idx]->vec[0], self->stack[_idx]->vec[1], self->stack[_idx]->vec[2]);
+ return Py_BuildValue("(fff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2]);
break;
case SOCK_RGBA:
- return Py_BuildValue("(ffff)", self->stack[_idx]->vec[0], self->stack[_idx]->vec[1], self->stack[_idx]->vec[2], self->stack[_idx]->vec[3]);
+ /* otherwise RGBA tuple */
+ return Py_BuildValue("(ffff)", self->stack[idx]->vec[0], self->stack[idx]->vec[1], self->stack[idx]->vec[2], self->stack[idx]->vec[3]);
break;
default:
break;
}
+
Py_RETURN_NONE;
}
@@ -506,21 +495,35 @@ PyTypeObject SockInMap_Type = {
};
static int sockoutmap_len ( BPy_SockMap * self) {
+ bNode *node = self->node;
+ bNodeType *tinfo;
int a = 0;
- if(self->typeinfo) {
- while(self->typeinfo->outputs[a].type!=-1)
+
+ if (!node) return 0;
+
+ tinfo = node->typeinfo;
+
+ if (tinfo && tinfo->outputs) {
+ while(self->node->typeinfo->outputs[a].type!=-1)
a++;
}
return a;
}
static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
+ bNode *node = self->node;
+ bNodeType *tinfo;
int a = 0;
- char *strkey = PyString_AsString(key);
+ char *strkey = NULL;
- if(self->typeinfo){
- while(self->typeinfo->outputs[a].type!=-1) {
- if(BLI_strcaseeq(self->typeinfo->outputs[a].name, strkey)) {
+ if (!node) return -1;
+
+ tinfo = node->typeinfo;
+ strkey = PyString_AsString(key);
+
+ if(tinfo && tinfo->outputs){
+ while(self->node->typeinfo->outputs[a].type!=-1) {
+ if(BLI_strcaseeq(self->node->typeinfo->outputs[a].name, strkey)) {
return a;
}
a++;
@@ -529,51 +532,88 @@ static int sockoutmap_has_key( BPy_SockMap *self, PyObject *key) {
return -1;
}
-static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *idx, PyObject *value) {
- int a, _idx;
- a = sockoutmap_len(self);
- if(PyInt_Check(idx)) {
- _idx = (int)PyInt_AsLong(idx);
+static int sockoutmap_assign_subscript(BPy_SockMap *self, PyObject *pyidx, PyObject *value) {
+ int i, idx, len, wanted_len = 0, ret = -1;
+ PyObject *val;
+ PyObject *items[4];
+
+ if (!self->node)
+ return EXPP_ReturnIntError(PyExc_RuntimeError, "no access to Blender node data!");
+
+ if (PyInt_Check(pyidx)) {
+ idx = (int)PyInt_AsLong(pyidx);
+ if (idx < 0 || idx >= sockinmap_len(self))
+ return EXPP_ReturnIntError(PyExc_IndexError, "index out of range");
}
- else if (PyString_Check(idx)) {
- _idx = sockoutmap_has_key( self, idx);
+ else if (PyString_Check(pyidx)) {
+ idx = sockoutmap_has_key(self, pyidx);
}
- else if (PySlice_Check(idx)) {
- PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
- return -1;
- } else {
- PyErr_SetString(PyExc_IndexError, "Index must be int or string");
- return -1;
- }
- if(_idx > -1) {
- switch(self->typeinfo->outputs[_idx].type) {
- case SOCK_VALUE:
- if(PyTuple_Size(value)==1)
- self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
- return 0;
- break;
- case SOCK_VECTOR:
- if(PyTuple_Size(value)==3) {
- self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
- self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1));
- self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2));
- }
- return 0;
- break;
- case SOCK_RGBA:
- if(PyTuple_Size(value)==4) {
- self->stack[_idx]->vec[0] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 0));
- self->stack[_idx]->vec[1] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 1));
- self->stack[_idx]->vec[2] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 2));
- self->stack[_idx]->vec[3] = (float)PyFloat_AsDouble(PyTuple_GetItem(value, 3));
- }
- return 0;
- break;
- default:
- break;
+ else if (PySlice_Check(pyidx)) {
+ return EXPP_ReturnIntError(PyExc_ValueError, "slices not yet implemented");
+ } else {
+ return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
+ }
+
+ if (idx < 0)
+ return EXPP_ReturnIntError(PyExc_IndexError, "index must be a positive int or a string");
+
+ val = PySequence_Fast(value, "expected a numeric tuple or list");
+ if (!val) return -1;
+
+ len = PySequence_Fast_GET_SIZE(val);
+
+ if (len == 0) {
+ Py_DECREF(val);
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a non-empty numeric tuple or list");
+ }
+
+ for (i = 0; i < len; i++) {
+ items[i] = PySequence_Fast_GET_ITEM(val, i); /* borrowed */
+ if (!PyNumber_Check(items[i])) {
+ Py_DECREF(val);
+ return EXPP_ReturnIntError(PyExc_AttributeError, "expected a *numeric* tuple or list");
}
}
- return 0;
+
+ switch(self->node->typeinfo->outputs[idx].type) {
+ case SOCK_VALUE:
+ wanted_len = 1;
+ if (len == 1) {
+ self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+ ret = 0;
+ }
+ break;
+ case SOCK_VECTOR:
+ wanted_len = 3;
+ if (len == 3) {
+ self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+ self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+ self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
+ ret = 0;
+ }
+ break;
+ case SOCK_RGBA:
+ wanted_len = 4;
+ if (len == 4) {
+ self->stack[idx]->vec[0] = (float)PyFloat_AsDouble(items[0]);
+ self->stack[idx]->vec[1] = (float)PyFloat_AsDouble(items[1]);
+ self->stack[idx]->vec[2] = (float)PyFloat_AsDouble(items[2]);
+ self->stack[idx]->vec[3] = (float)PyFloat_AsDouble(items[3]);
+ ret = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ Py_DECREF(val);
+
+ if (ret == -1) {
+ PyErr_SetString(PyExc_AttributeError, "wrong number of items in list or tuple");
+ fprintf(stderr, "\nExpected %d numeric values, got %d.", wanted_len, len);
+ }
+
+ return ret;
}
/* write only */
@@ -667,14 +707,14 @@ PyTypeObject SockOutMap_Type = {
static BPy_SockMap *Node_CreateInputMap(bNode *node, bNodeStack **stack) {
- BPy_SockMap *map= PyObject_NEW(BPy_SockMap, &SockInMap_Type);
- map->typeinfo= node->typeinfo;
- map->stack= stack;
+ BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockInMap_Type);
+ map->node = node;
+ map->stack = stack;
return map;
}
static PyObject *Node_GetInputMap(BPy_Node *self) {
- BPy_SockMap *inmap= Node_CreateInputMap(self->node, self->in);
+ BPy_SockMap *inmap = Node_CreateInputMap(self->node, self->in);
return (PyObject *)(inmap);
}
@@ -685,11 +725,11 @@ static PyObject *Node_GetInputMap(BPy_Node *self) {
#define TEXTURE 4
#define PIXEL 5
#define COLOR 6
-#define SPECULAR 7
-#define MIRROR 8
-#define AMBIENT 9
-#define AMBIENTFACTOR 10
-#define EMITFACTOR 11
+#define SPECULAR_COLOR 7
+#define MIRROR_COLOR 8
+#define AMBIENT_COLOR 9
+#define AMBIENT 10
+#define EMIT 11
#define DISPLACE 12
#define STRAND 13
#define STRESS 14
@@ -704,80 +744,80 @@ static PyObject *Node_GetInputMap(BPy_Node *self) {
#define STRAND_D 37
static PyObject *ShadeInput_getAttribute(BPy_ShadeInput *self, void *type) {
- PyObject *obj= NULL;
+ PyObject *obj = NULL;
if(self->shi) {
switch((int)type) {
case SURFACEVIEWVECTOR:
- obj= Py_BuildValue("(fff)", self->shi->view[0], self->shi->view[1], self->shi->view[2]);
+ obj = Py_BuildValue("(fff)", self->shi->view[0], self->shi->view[1], self->shi->view[2]);
break;
case VIEWNORMAL:
- obj= Py_BuildValue("(fff)", self->shi->vn[0], self->shi->vn[1], self->shi->vn[2]);
+ obj = Py_BuildValue("(fff)", self->shi->vn[0], self->shi->vn[1], self->shi->vn[2]);
break;
case SURFACENORMAL:
- obj= Py_BuildValue("(fff)", self->shi->facenor[0], self->shi->facenor[1], self->shi->facenor[2]);
+ obj = Py_BuildValue("(fff)", self->shi->facenor[0], self->shi->facenor[1], self->shi->facenor[2]);
break;
case GLOBALTEXTURE:
- obj= Py_BuildValue("(fff)", self->shi->gl[0], self->shi->gl[1], self->shi->gl[2]);
+ obj = Py_BuildValue("(fff)", self->shi->gl[0], self->shi->gl[1], self->shi->gl[2]);
break;
case TEXTURE:
- obj= Py_BuildValue("(fff)", self->shi->lo[0], self->shi->lo[1], self->shi->lo[2]);
+ obj = Py_BuildValue("(fff)", self->shi->lo[0], self->shi->lo[1], self->shi->lo[2]);
break;
case PIXEL:
- obj= Py_BuildValue("(ii)", self->shi->xs, self->shi->ys);
+ obj = Py_BuildValue("(ii)", self->shi->xs, self->shi->ys);
break;
case COLOR:
- obj= Py_BuildValue("(fff)", self->shi->r, self->shi->g, self->shi->b);
+ obj = Py_BuildValue("(fff)", self->shi->r, self->shi->g, self->shi->b);
break;
- case SPECULAR:
- obj= Py_BuildValue("(fff)", self->shi->specr, self->shi->specg, self->shi->specb);
+ case SPECULAR_COLOR:
+ obj = Py_BuildValue("(fff)", self->shi->specr, self->shi->specg, self->shi->specb);
break;
- case MIRROR:
- obj= Py_BuildValue("(fff)", self->shi->mirr, self->shi->mirg, self->shi->mirb);
+ case MIRROR_COLOR:
+ obj = Py_BuildValue("(fff)", self->shi->mirr, self->shi->mirg, self->shi->mirb);
break;
- case AMBIENT:
- obj= Py_BuildValue("(fff)", self->shi->ambr, self->shi->ambg, self->shi->ambb);
+ case AMBIENT_COLOR:
+ obj = Py_BuildValue("(fff)", self->shi->ambr, self->shi->ambg, self->shi->ambb);
break;
- case AMBIENTFACTOR:
- obj= PyFloat_FromDouble((double)(self->shi->amb));
+ case AMBIENT:
+ obj = PyFloat_FromDouble((double)(self->shi->amb));
break;
- case EMITFACTOR:
- obj= PyFloat_FromDouble((double)(self->shi->emit));
+ case EMIT:
+ obj = PyFloat_FromDouble((double)(self->shi->emit));
break;
case DISPLACE:
- obj= Py_BuildValue("(fff)", self->shi->displace[0], self->shi->displace[1], self->shi->displace[2]);
+ obj = Py_BuildValue("(fff)", self->shi->displace[0], self->shi->displace[1], self->shi->displace[2]);
break;
case STRAND:
- obj= PyFloat_FromDouble((double)(self->shi->strand));
+ obj = PyFloat_FromDouble((double)(self->shi->strandco));
break;
case STRESS:
- obj= PyFloat_FromDouble((double)(self->shi->stress));
+ obj = PyFloat_FromDouble((double)(self->shi->stress));
break;
case TANGENT:
- obj= Py_BuildValue("(fff)", self->shi->tang[0], self->shi->tang[1], self->shi->tang[2]);
+ obj = Py_BuildValue("(fff)", self->shi->tang[0], self->shi->tang[1], self->shi->tang[2]);
break;
case SURFACE_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxco[0], self->shi->dxco[1], self->shi->dxco[2], self->shi->dyco[0], self->shi->dyco[1], self->shi->dyco[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxco[0], self->shi->dxco[1], self->shi->dxco[2], self->shi->dyco[0], self->shi->dyco[1], self->shi->dyco[2]);
break;
case TEXTURE_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxlo[0], self->shi->dxlo[1], self->shi->dxlo[2], self->shi->dylo[0], self->shi->dylo[1], self->shi->dylo[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxlo[0], self->shi->dxlo[1], self->shi->dxlo[2], self->shi->dylo[0], self->shi->dylo[1], self->shi->dylo[2]);
break;
case GLOBALTEXTURE_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxgl[0], self->shi->dxgl[1], self->shi->dxgl[2], self->shi->dygl[0], self->shi->dygl[1], self->shi->dygl[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxgl[0], self->shi->dxgl[1], self->shi->dxgl[2], self->shi->dygl[0], self->shi->dygl[1], self->shi->dygl[2]);
break;
case REFLECTION_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxref[0], self->shi->dxref[1], self->shi->dxref[2], self->shi->dyref[0], self->shi->dyref[1], self->shi->dyref[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxref[0], self->shi->dxref[1], self->shi->dxref[2], self->shi->dyref[0], self->shi->dyref[1], self->shi->dyref[2]);
break;
case NORMAL_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxno[0], self->shi->dxno[1], self->shi->dxno[2], self->shi->dyno[0], self->shi->dyno[1], self->shi->dyno[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxno[0], self->shi->dxno[1], self->shi->dxno[2], self->shi->dyno[0], self->shi->dyno[1], self->shi->dyno[2]);
break;
case STICKY_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxsticky[0], self->shi->dxsticky[1], self->shi->dxsticky[2], self->shi->dysticky[0], self->shi->dysticky[1], self->shi->dysticky[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxsticky[0], self->shi->dxsticky[1], self->shi->dxsticky[2], self->shi->dysticky[0], self->shi->dysticky[1], self->shi->dysticky[2]);
break;
case REFRACT_D:
- obj= Py_BuildValue("(fff)(fff)", self->shi->dxrefract[0], self->shi->dxrefract[1], self->shi->dxrefract[2], self->shi->dyrefract[0], self->shi->dyrefract[1], self->shi->dyrefract[2]);
+ obj = Py_BuildValue("(fff)(fff)", self->shi->dxrefract[0], self->shi->dxrefract[1], self->shi->dxrefract[2], self->shi->dyrefract[0], self->shi->dyrefract[1], self->shi->dyrefract[2]);
break;
case STRAND_D:
- obj= Py_BuildValue("(ff)", self->shi->dxstrand, self->shi->dystrand);
+ obj = Py_BuildValue("(ff)", self->shi->dxstrand, self->shi->dystrand);
break;
default:
break;
@@ -792,27 +832,26 @@ static PyObject *ShadeInput_getAttribute(BPy_ShadeInput *self, void *type) {
static BPy_SockMap *Node_CreateOutputMap(bNode *node, bNodeStack **stack) {
BPy_SockMap *map = PyObject_NEW(BPy_SockMap, &SockOutMap_Type);
- map->typeinfo= node->typeinfo;
- map->stack= stack;
+ map->node = node;
+ map->stack = stack;
return map;
}
static PyObject *Node_GetOutputMap(BPy_Node *self) {
- BPy_SockMap *outmap= Node_CreateOutputMap(self->node, self->out);
+ BPy_SockMap *outmap = Node_CreateOutputMap(self->node, self->out);
return (PyObject *)outmap;
}
static PyObject *Node_GetShi(BPy_Node *self) {
- BPy_ShadeInput *shi= ShadeInput_CreatePyObject(self->shi);
+ BPy_ShadeInput *shi = ShadeInput_CreatePyObject(self->shi);
return (PyObject *)shi;
-
}
static PyObject *node_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *self;
assert(type!=NULL && type->tp_alloc!=NULL);
- self= type->tp_alloc(type, 1);
+ self = type->tp_alloc(type, 1);
return self;
}
@@ -822,17 +861,29 @@ static int node_init(BPy_Node *self, PyObject *args, PyObject *kwds)
}
static PyGetSetDef BPy_Node_getseters[] = {
- {"ins",
+ {"input",
+ (getter)Node_GetInputMap, (setter)NULL,
+ "Get the input sockets mapping (dictionary)",
+ NULL},
+ {"i", /* alias */
(getter)Node_GetInputMap, (setter)NULL,
- "Get the ShadeInput mapping (dictionary)",
+ "Get the input sockets mapping (dictionary)",
+ NULL},
+ {"output",
+ (getter)Node_GetOutputMap, (setter)NULL,
+ "Get the output sockets mapping (dictionary)",
NULL},
- {"outs",
+ {"o", /* alias */
(getter)Node_GetOutputMap, (setter)NULL,
- "Get the ShadeInput mapping (dictionary)",
+ "Get the output sockets mapping (dictionary)",
NULL},
{"shi",
(getter)Node_GetShi, (setter)NULL,
- "Get the ShadeInput (ShadeInput)",
+ "Get the Shade Input data (ShadeInput)",
+ NULL},
+ {"s", /* alias */
+ (getter)Node_GetShi, (setter)NULL,
+ "Get the Shade Input data (ShadeInput)",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -842,19 +893,19 @@ static PyGetSetDef BPy_ShadeInput_getseters[] = {
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the current texture coordinate (tuple)",
(void*)TEXTURE},
- {"texture_global",
+ {"textureGlobal",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the current global texture coordinate (tuple)",
(void*)GLOBALTEXTURE},
- {"surface_normal",
+ {"surfaceNormal",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the current surface normal (tuple)",
(void*)SURFACENORMAL},
- {"view_normal",
+ {"viewNormal",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the current view normal (tuple)",
(void*)VIEWNORMAL},
- {"surface_view_vec",
+ {"surfaceViewVector",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the vector pointing to the viewpoint from the point being shaded (tuple)",
(void*)SURFACEVIEWVECTOR},
@@ -866,26 +917,26 @@ static PyGetSetDef BPy_ShadeInput_getseters[] = {
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the color for the point being shaded (tuple)",
(void*)COLOR},
- {"specular",
+ {"specularColor",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the specular color for the point being shaded (tuple)",
- (void*)SPECULAR},
- {"mirror",
+ (void*)SPECULAR_COLOR},
+ {"mirrorColor",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the mirror color for the point being shaded (tuple)",
- (void*)MIRROR},
- {"ambient",
+ (void*)MIRROR_COLOR},
+ {"ambientColor",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the ambient color for the point being shaded (tuple)",
- (void*)AMBIENT},
- {"ambient_factor",
+ (void*)AMBIENT_COLOR},
+ {"ambient",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the ambient factor for the point being shaded (float)",
- (void*)AMBIENTFACTOR},
- {"emit_factor",
+ (void*)AMBIENT},
+ {"emit",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the emit factor for the point being shaded (float)",
- (void*)EMITFACTOR},
+ (void*)EMIT},
{"displace",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the displace vector for the point being shaded (tuple)",
@@ -902,38 +953,38 @@ static PyGetSetDef BPy_ShadeInput_getseters[] = {
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the tangent vector (tuple)",
(void*)TANGENT},
- {"surface_d",
+ {"surfaceD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the surface d (tuple of tuples)",
(void*)SURFACE_D},
- {"texture_d",
+ {"textureD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the texture d (tuple of tuples)",
(void*)TEXTURE_D},
- {"texture_global_d",
+ {"textureGlobalD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the global texture d (tuple of tuples)",
(void*)GLOBALTEXTURE_D},
- {"reflection_d",
+ {"reflectionD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the reflection d (tuple of tuples)",
(void*)REFLECTION_D},
- {"normal_d",
+ {"normalD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the normal d (tuple of tuples)",
(void*)NORMAL_D},
- {"sticky_d",
+ {"stickyD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the sticky d (tuple of tuples)",
(void*)STICKY_D},
- {"refract_d",
+ {"refractD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the refract d (tuple of tuples)",
(void*)REFRACT_D},
- {"strand_d",
+ {"strandD",
(getter)ShadeInput_getAttribute, (setter)NULL,
"Get the strand d (tuple)",
- (void*)REFRACT_D},
+ (void*)STRAND_D},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -1101,7 +1152,6 @@ PyTypeObject ShadeInput_Type = {
NULL
};
-
/* Initialise Node module */
PyObject *Node_Init(void)
{
@@ -1111,9 +1161,7 @@ PyObject *Node_Init(void)
return NULL;
if( PyType_Ready( &ShadeInput_Type ) < 0 )
return NULL;
- if( PyType_Ready( &OutputDefMap_Type ) < 0 )
- return NULL;
- if( PyType_Ready( &InputDefMap_Type ) < 0 )
+ if( PyType_Ready( &NodeSockets_Type ) < 0 )
return NULL;
if( PyType_Ready( &SockInMap_Type ) < 0 )
return NULL;
@@ -1135,7 +1183,7 @@ PyObject *Node_Init(void)
static int Node_compare(BPy_Node *a, BPy_Node *b)
{
bNode *pa = a->node, *pb = b->node;
- return (pa==pb) ? 0 : -1;
+ return (pa == pb) ? 0 : -1;
}
static PyObject *Node_repr(BPy_Node *self)
@@ -1154,13 +1202,18 @@ BPy_Node *Node_CreatePyObject(bNode *node)
return (BPy_Node *)(EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create BPy_Node object"));
}
- pynode->node= node;
+ pynode->node = node;
return pynode;
}
+int pytype_is_pynode(PyObject *pyob)
+{
+ return PyObject_TypeCheck(pyob, &Node_Type);
+}
+
void InitNode(BPy_Node *self, bNode *node) {
- self->node= node;
+ self->node = node;
}
bNode *Node_FromPyObject(PyObject *pyobj)
@@ -1170,16 +1223,16 @@ bNode *Node_FromPyObject(PyObject *pyobj)
void Node_SetStack(BPy_Node *self, bNodeStack **stack, int type)
{
- if(type==NODE_INPUTSTACK) {
- self->in= stack;
- } else if(type==NODE_OUTPUTSTACK) {
- self->out= stack;
+ if(type == NODE_INPUTSTACK) {
+ self->in = stack;
+ } else if(type == NODE_OUTPUTSTACK) {
+ self->out = stack;
}
}
void Node_SetShi(BPy_Node *self, ShadeInput *shi)
{
- self->shi= shi;
+ self->shi = shi;
}
/*********************/
@@ -1187,12 +1240,12 @@ void Node_SetShi(BPy_Node *self, ShadeInput *shi)
static int ShadeInput_compare(BPy_ShadeInput *a, BPy_ShadeInput *b)
{
ShadeInput *pa = a->shi, *pb = b->shi;
- return (pa==pb) ? 0 : -1;
+ return (pa == pb) ? 0 : -1;
}
static PyObject *ShadeInput_repr(BPy_ShadeInput *self)
{
- return PyString_FromFormat( "[ShadeInput @ \"%p\"]", self);
+ return PyString_FromFormat( "[ShadeInput at \"%p\"]", self);
}
BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi)
@@ -1209,5 +1262,4 @@ BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi)
return pyshi;
}
-#endif
diff --git a/source/blender/python/api2_2x/Node.h b/source/blender/python/api2_2x/Node.h
index f4796d1b80b..e229e678fe9 100644
--- a/source/blender/python/api2_2x/Node.h
+++ b/source/blender/python/api2_2x/Node.h
@@ -30,7 +30,6 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#ifdef USE_PYNODES /* note: won't work without patch */
#ifndef __NODE_H__
#define __NODE_H__
@@ -56,14 +55,16 @@ typedef struct BPy_ShadeInput {
typedef struct {
PyObject_VAR_HEAD
- bNodeType *typeinfo;
+ bNode* node;
bNodeStack **stack;
} BPy_SockMap;
typedef struct {
PyObject_HEAD
bNode *node;
-} BPy_DefinitionMap;
+ PyObject *input;
+ PyObject *output;
+} BPy_NodeSockets;
typedef struct BPy_Node {
PyObject_HEAD
@@ -76,16 +77,13 @@ typedef struct BPy_Node {
extern PyObject *Node_Init(void);
extern void InitNode(BPy_Node *self, bNode *node);
extern BPy_Node *Node_CreatePyObject(bNode *node);
-extern BPy_DefinitionMap *Node_CreateOutputDefMap(bNode *node);
-extern BPy_DefinitionMap *Node_CreateInputDefMap(bNode *node);
+extern BPy_NodeSockets *Node_CreateSockets(bNode *node);
extern void Node_SetStack(BPy_Node *self, bNodeStack **stack, int type);
extern void Node_SetShi(BPy_Node *self, ShadeInput *shi);
-extern BPy_ShadeInput *ShadeInput_CreatePyObject(ShadeInput *shi);
-extern void Node_dealloc(BPy_Node *self);
-extern void ShadeInput_dealloc(BPy_ShadeInput *self);
+extern int pytype_is_pynode(PyObject *pyob);
#define NODE_INPUTSTACK 0
#define NODE_OUTPUTSTACK 1
#endif /* __NODE_H__*/
-#endif /* USE_PYNODES */
+
diff --git a/source/blender/python/api2_2x/Noise.c b/source/blender/python/api2_2x/Noise.c
index 821c541b4ac..c1a41d46714 100644
--- a/source/blender/python/api2_2x/Noise.c
+++ b/source/blender/python/api2_2x/Noise.c
@@ -199,7 +199,7 @@ static PyObject *Noise_random( PyObject * self )
static PyObject *Noise_randuvec( PyObject * self )
{
- float v[3];
+ float v[3] = {0.0f, 0.0f, 0.0f};
randuvec( v );
return Py_BuildValue( "[fff]", v[0], v[1], v[2] );
}
@@ -434,7 +434,7 @@ static PyObject *Noise_voronoi( PyObject * self, PyObject * args )
da[0], da[1], da[2], da[3],
pa[0], pa[1], pa[2],
pa[3], pa[4], pa[5],
- pa[6], pa[7], pa[8], pa[9], pa[10], pa[12] );
+ pa[6], pa[7], pa[8], pa[9], pa[10], pa[11] );
}
/*-------------------------------------------------------------------------*/
diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c
index 9be64fc72a6..a7a651e4465 100644
--- a/source/blender/python/api2_2x/Object.c
+++ b/source/blender/python/api2_2x/Object.c
@@ -70,6 +70,7 @@ struct rctf;
#include "BKE_idprop.h"
#include "BKE_object.h"
#include "BKE_key.h" /* for setting the activeShape */
+#include "BKE_displist.h"
#include "BSE_editipo.h"
#include "BSE_edit.h"
@@ -133,6 +134,7 @@ struct rctf;
#define IPOKEY_PI_SURFACEDAMP 8
#define IPOKEY_PI_RANDOMDAMP 9
#define IPOKEY_PI_PERM 10
+#define IPOKEY_LAYER 19
#define PFIELD_FORCE 1
#define PFIELD_VORTEX 2
@@ -171,6 +173,7 @@ enum obj_consts {
EXPP_OBJ_ATTR_DUPOFF,
EXPP_OBJ_ATTR_DUPSTA,
EXPP_OBJ_ATTR_DUPEND,
+ EXPP_OBJ_ATTR_DUPFACESCALEFAC,
EXPP_OBJ_ATTR_TIMEOFFSET,
EXPP_OBJ_ATTR_DRAWSIZE,
EXPP_OBJ_ATTR_PARENT_TYPE,
@@ -275,6 +278,8 @@ enum obj_consts {
#define EXPP_OBJECT_SBINSPRINGMAX 0.999f
#define EXPP_OBJECT_SBINFRICTMIN 0.0f
#define EXPP_OBJECT_SBINFRICTMAX 10.0f
+#define EXPP_OBJECT_DUPFACESCALEFACMIN 0.001f
+#define EXPP_OBJECT_DUPFACESCALEFACMAX 10000.0f
/*****************************************************************************/
/* Python API function prototypes for the Blender module. */
@@ -394,7 +399,7 @@ static PyObject *Object_getProperty( BPy_Object * self, PyObject * args );
static PyObject *Object_removeAllProperties( BPy_Object * self );
static PyObject *Object_copyAllPropertiesTo( BPy_Object * self,
PyObject * args );
-static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args );
+static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * value );
static PyObject *Object_addScriptLink( BPy_Object * self, PyObject * args );
static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject *args );
static PyObject *Object_getPIStrength( BPy_Object * self );
@@ -744,7 +749,7 @@ works only if self and the object specified are of the same type."},
{"copyAllPropertiesTo", ( PyCFunction ) Object_copyAllPropertiesTo,
METH_VARARGS,
"() - copy all properties from this object to another object"},
- {"getScriptLinks", ( PyCFunction ) Object_getScriptLinks, METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) Object_getScriptLinks, METH_O,
"(eventname) - Get a list of this object's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, Redraw or Render."},
@@ -1209,16 +1214,16 @@ static PyObject *Object_getSelected( BPy_Object * self )
static int Object_setSelect( BPy_Object * self, PyObject * value )
{
Base *base;
- int setting = PyObject_IsTrue( value );
+ int param = PyObject_IsTrue( value );
- if( setting == -1 )
+ if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected true/false argument" );
+ "expected True/False or 0/1" );
base = FIRSTBASE;
while( base ) {
if( base->object == self->object ) {
- if( setting == 1 ) {
+ if( param ) {
base->flag |= SELECT;
self->object->flag = (short)base->flag;
set_active_base( base );
@@ -1230,7 +1235,9 @@ static int Object_setSelect( BPy_Object * self, PyObject * value )
}
base = base->next;
}
- countall( );
+ if (base) { /* was the object selected? */
+ countall( );
+ }
return 0;
}
@@ -1330,7 +1337,7 @@ static PyObject *Object_getParent( BPy_Object * self )
static PyObject *Object_getParentBoneName( BPy_Object * self )
{
- if( self->object->parent && self->object->parsubstr[0] != '\0' )
+ if( self->object->parent && self->object->parent->type==OB_ARMATURE && self->object->parsubstr[0] != '\0' )
return PyString_FromString( self->object->parsubstr );
Py_RETURN_NONE;
}
@@ -1364,22 +1371,30 @@ static int Object_setParentBoneName( BPy_Object * self, PyObject *value )
static PyObject *Object_getSize( BPy_Object * self, PyObject * args )
{
- PyObject *attr;
char *space = "localspace"; /* default to local */
-
+ PyObject *attr;
if( !PyArg_ParseTuple( args, "|s", &space ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string or nothing" );
if( BLI_streq( space, "worldspace" ) ) { /* Worldspace matrix */
- float scale[3];
+ float rot[3];
+ float mat[3][3], imat[3][3], tmat[3][3];
disable_where_script( 1 );
where_is_object( self->object );
- Mat4ToSize(self->object->obmat, scale);
+
+ Mat3CpyMat4(mat, self->object->obmat);
+
+ /* functionality copied from editobject.c apply_obmat */
+ Mat3ToEul(mat, rot);
+ EulToMat3(rot, tmat);
+ Mat3Inv(imat, tmat);
+ Mat3MulMat3(tmat, imat, mat);
+
attr = Py_BuildValue( "fff",
- self->object->size[0],
- self->object->size[1],
- self->object->size[2] );
+ tmat[0][0],
+ tmat[1][1],
+ tmat[2][2] );
disable_where_script( 0 );
} else if( BLI_streq( space, "localspace" ) ) { /* Localspace matrix */
attr = Py_BuildValue( "fff",
@@ -1388,9 +1403,8 @@ static PyObject *Object_getSize( BPy_Object * self, PyObject * args )
self->object->size[2] );
} else {
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected either nothing, 'localspace' (default) or 'worldspace'" );
+ "expected either nothing, 'localspace' (default) or 'worldspace'" );
}
-
return attr;
}
@@ -1471,7 +1485,7 @@ static PyObject *Object_getBoundBox( BPy_Object * self )
switch ( self->object->type ) {
case OB_MESH:
me = self->object->data;
- vec = (float*) mesh_get_bb(me)->vec;
+ vec = (float*) mesh_get_bb(self->object)->vec;
break;
case OB_CURVE:
case OB_FONT:
@@ -1561,8 +1575,11 @@ static PyObject *Object_makeDisplayList( BPy_Object * self )
{
Object *ob = self->object;
- if( ob->type == OB_FONT )
+ if( ob->type == OB_FONT ) {
+ Curve *cu = ob->data;
+ freedisplist( &cu->disp );
text_to_curve( ob, 0 );
+ }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
@@ -1667,9 +1684,11 @@ static PyObject *Object_link( BPy_Object * self, PyObject * args )
self->object->data = data;
/* creates the curve for the text object */
- if (self->object->type == OB_FONT)
+ if (self->object->type == OB_FONT) {
text_to_curve(self->object, 0);
-
+ } else if (self->object->type == OB_ARMATURE) {
+ armature_rebuild_pose(self->object, (bArmature *)data);
+ }
id_us_plus( id );
if( oldid ) {
if( oldid->us > 0 ) {
@@ -2327,7 +2346,7 @@ static int Object_setMatrix( BPy_Object * self, MatrixObject * mat )
/*
* Object_insertIpoKey()
- * inserts Object IPO key for LOC, ROT, SIZE, LOCROT, or LOCROTSIZE
+ * inserts Object IPO key for LOC, ROT, SIZE, LOCROT, LOCROTSIZE, or LAYER
* Note it also inserts actions!
*/
@@ -2345,31 +2364,34 @@ static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args )
actname= "Object";
if (key == IPOKEY_LOC || key == IPOKEY_LOCROT || key == IPOKEY_LOCROTSIZE){
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_X);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Y);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Z);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_X, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Y, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_LOC_Z, 0);
}
if (key == IPOKEY_ROT || key == IPOKEY_LOCROT || key == IPOKEY_LOCROTSIZE){
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_X);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Y);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Z);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_X, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Y, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_ROT_Z, 0);
}
if (key == IPOKEY_SIZE || key == IPOKEY_LOCROTSIZE ){
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_X);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Y);
- insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Z);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_X, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Y, 0);
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_SIZE_Z, 0);
+ }
+ if (key == IPOKEY_LAYER ){
+ insertkey((ID *)ob, ID_OB, actname, NULL,OB_LAY, 0);
}
if (key == IPOKEY_PI_STRENGTH ){
- insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FSTR);
+ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FSTR, 0);
} else if (key == IPOKEY_PI_FALLOFF ){
- insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FFALL);
+ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_FFALL, 0);
} else if (key == IPOKEY_PI_SURFACEDAMP ){
- insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_SDAMP);
+ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_SDAMP, 0);
} else if (key == IPOKEY_PI_RANDOMDAMP ){
- insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_RDAMP);
+ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_RDAMP, 0);
} else if (key == IPOKEY_PI_PERM ){
- insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_PERM);
+ insertkey((ID *)ob, ID_OB, actname, NULL, OB_PD_PERM, 0);
}
allspace(REMAKEIPO, 0);
@@ -2412,16 +2434,16 @@ static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args )
/* XXX: must check chanName actually exists, otherwise segfaults! */
//achan = get_action_channel(sourceact->action, chanName);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z, 0);
G.scene->r.cfra = oldframe;
@@ -2458,16 +2480,16 @@ static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args
/* XXX: must check chanName actually exists, otherwise segfaults! */
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y);
- insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y, 0);
+ insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z, 0);
G.scene->r.cfra = oldframe;
@@ -2497,14 +2519,14 @@ static PyObject *Object_setConstraintInfluenceForBone( BPy_Object * self,
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expects bonename, constraintname, influenceval" );
- icu = verify_ipocurve((ID *)self->object, ID_CO, boneName, constName,
+ icu = verify_ipocurve((ID *)self->object, ID_CO, boneName, constName, NULL,
CO_ENFORCE);
if (!icu)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"cannot get a curve from this IPO, may be using libdata" );
- insert_vert_ipo(icu, (float)CFRA, influence);
+ insert_vert_icu(icu, (float)CFRA, influence, 0);
self->object->recalc |= OB_RECALC_OB;
Py_RETURN_NONE;
@@ -2929,11 +2951,11 @@ static PyObject *Object_clearScriptLinks( BPy_Object * self, PyObject * args )
return EXPP_clearScriptLinks( slink, args );
}
-static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * args )
+static PyObject *Object_getScriptLinks( BPy_Object * self, PyObject * value )
{
Object *obj = self->object;
ScriptLink *slink = &obj->scriptlink;
- return EXPP_getScriptLinks( slink, args, 0 );
+ return EXPP_getScriptLinks( slink, value, 0 );
}
static PyObject *Object_getNLAflagBits ( BPy_Object * self )
@@ -2944,20 +2966,20 @@ static PyObject *Object_getNLAflagBits ( BPy_Object * self )
Py_RETURN_FALSE;
}
-static int Object_setNLAflagBits ( BPy_Object * self, PyObject * args )
+static int Object_setNLAflagBits ( BPy_Object * self, PyObject * value )
{
- int value;
+ int param;
- value = PyObject_IsTrue( args );
- if( value == -1 )
+ param = PyObject_IsTrue( value );
+ if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected 1/0 for true/false" );
+ "expected True/False or 0/1" );
- if (value==1)
+ if (param)
self->object->nlaflag |= OB_NLA_OVERRIDE;
else
self->object->nlaflag &= ~OB_NLA_OVERRIDE;
-
+
self->object->recalc |= OB_RECALC_OB;
return 0;
@@ -2966,7 +2988,6 @@ static int Object_setNLAflagBits ( BPy_Object * self, PyObject * args )
static PyObject *Object_getDupliObjects( BPy_Object * self )
{
Object *ob= self->object;
- PyObject *pair;
if(ob->transflag & OB_DUPLI) {
/* before make duplis, update particle for current frame */
@@ -2988,6 +3009,7 @@ static PyObject *Object_getDupliObjects( BPy_Object * self )
"PyList_New() failed" );
for(dupob= duplilist->first, index=0; dupob; dupob= dupob->next, index++) {
+ PyObject *pair;
pair = PyTuple_New( 2 );
PyTuple_SET_ITEM( pair, 0, Object_CreatePyObject(dupob->ob) );
@@ -3189,20 +3211,20 @@ static PyObject *Object_getPIDeflection( BPy_Object * self )
return PyBool_FromLong( ( long ) self->object->pd->deflect );
}
-static int Object_setPIDeflection( BPy_Object * self, PyObject * args )
+static int Object_setPIDeflection( BPy_Object * self, PyObject * value )
{
- int value;
+ int param;
if( !self->object->pd && !setupPI(self->object) )
return EXPP_ReturnIntError( PyExc_RuntimeError,
"particle deflection could not be accessed" );
- value = PyObject_IsTrue( args );
- if( value == -1 )
+ param = PyObject_IsTrue( value );
+ if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected true/false argument" );
- self->object->pd->deflect = (short)value;
+ self->object->pd->deflect = (short)param;
self->object->recalc |= OB_RECALC_OB;
return 0;
@@ -3254,20 +3276,20 @@ static PyObject *Object_getPIUseMaxDist( BPy_Object * self )
return PyBool_FromLong( ( long )self->object->pd->flag );
}
-static int Object_setPIUseMaxDist( BPy_Object * self, PyObject * args )
+static int Object_setPIUseMaxDist( BPy_Object * self, PyObject * value )
{
- int value;
+ int param;
if( !self->object->pd && !setupPI(self->object) )
return EXPP_ReturnIntError( PyExc_RuntimeError,
"particle deflection could not be accessed" );
- value = PyObject_IsTrue( args );
- if( value == -1 )
+ param = PyObject_IsTrue( value );
+ if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected true/false argument" );
- self->object->pd->flag = (short)value;
+ self->object->pd->flag = (short)param;
self->object->recalc |= OB_RECALC_OB;
return 0;
@@ -3368,9 +3390,9 @@ static PyObject *Object_getSBUseGoal( BPy_Object * self )
Py_RETURN_FALSE;
}
-static int Object_setSBUseGoal( BPy_Object * self, PyObject * args )
+static int Object_setSBUseGoal( BPy_Object * self, PyObject * value )
{
- int setting = PyObject_IsTrue( args );
+ int setting = PyObject_IsTrue( value );
if( !self->object->soft && !setupSB(self->object) )
return EXPP_ReturnIntError( PyExc_RuntimeError,
@@ -3401,9 +3423,9 @@ static PyObject *Object_getSBUseEdges( BPy_Object * self )
Py_RETURN_FALSE;
}
-static int Object_setSBUseEdges( BPy_Object * self, PyObject * args )
+static int Object_setSBUseEdges( BPy_Object * self, PyObject * value )
{
- int setting = PyObject_IsTrue( args );
+ int setting = PyObject_IsTrue( value );
if( !self->object->soft && !setupSB(self->object) )
return EXPP_ReturnIntError( PyExc_RuntimeError,
@@ -3434,9 +3456,9 @@ static PyObject *Object_getSBStiffQuads( BPy_Object * self )
Py_RETURN_FALSE;
}
-static int Object_setSBStiffQuads( BPy_Object * self, PyObject * args )
+static int Object_setSBStiffQuads( BPy_Object * self, PyObject * value )
{
- int setting = PyObject_IsTrue( args );
+ int setting = PyObject_IsTrue( value );
if( !self->object->soft && !setupSB(self->object) )
return EXPP_ReturnIntError( PyExc_RuntimeError,
@@ -3533,7 +3555,6 @@ void Object_updateDag( void *data )
static PyObject *getIntAttr( BPy_Object *self, void *type )
{
- PyObject *attr = NULL;
int param;
struct Object *object = self->object;
@@ -3580,13 +3601,7 @@ static PyObject *getIntAttr( BPy_Object *self, void *type )
"undefined type in getIntAttr" );
}
- attr = PyInt_FromLong( param );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "PyInt_FromLong() failed!" );
+ return PyInt_FromLong( param );
}
/*
@@ -3669,7 +3684,7 @@ static int setIntAttrRange( BPy_Object *self, PyObject *value, void *type )
struct Object *object = self->object;
int min, max, size;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected integer argument" );
@@ -3837,6 +3852,9 @@ static PyObject *getFloatAttr( BPy_Object *self, void *type )
case EXPP_OBJ_ATTR_SB_INFRICT:
param = object->soft->infrict;
break;
+ case EXPP_OBJ_ATTR_DUPFACESCALEFAC:
+ param = object->dupfacesca;
+ break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type in getFloatAttr" );
@@ -3984,6 +4002,12 @@ static int setFloatAttrClamp( BPy_Object *self, PyObject *value, void *type )
max = EXPP_OBJECT_SBINFRICTMAX;
param = &self->object->soft->infrict;
break;
+ case EXPP_OBJ_ATTR_DUPFACESCALEFAC:
+ min = EXPP_OBJECT_DUPFACESCALEFACMIN;
+ max = EXPP_OBJECT_DUPFACESCALEFACMAX;
+ param = &self->object->dupfacesca;
+ break;
+
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type in setFloatAttrClamp" );
@@ -4077,7 +4101,6 @@ static int setFloatAttr( BPy_Object *self, PyObject *value, void *type )
static PyObject *getFloat3Attr( BPy_Object *self, void *type )
{
- PyObject *attr = NULL;
float *param;
struct Object *object = self->object;
@@ -4102,13 +4125,7 @@ static PyObject *getFloat3Attr( BPy_Object *self, void *type )
"undefined type in getFloat3Attr" );
}
- attr = Py_BuildValue( "(fff)", param[0], param[1], param[2] );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "Py_BuildValue() failed!" );
+ return Py_BuildValue( "(fff)", param[0], param[1], param[2] );
}
/*
@@ -4193,7 +4210,12 @@ static PyObject *Object_getRestricted( BPy_Object *self, void *type )
static int Object_setRestricted( BPy_Object *self, PyObject *value,
void *type )
{
- if (PyObject_IsTrue(value) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if ( param )
self->object->restrictflag |= (int)type;
else
self->object->restrictflag &= ~(int)type;
@@ -4297,13 +4319,16 @@ static int Object_setLayers( BPy_Object * self, PyObject *value )
local = base->lay;
base->lay = local | layers;
self->object->lay = base->lay;
+ break;
}
base = base->next;
}
/* these to calls here are overkill! (ton) */
- countall();
- DAG_scene_sort( G.scene );
+ if (base) { /* The object was found? */
+ countall();
+ DAG_scene_sort( G.scene );
+ }
return 0;
}
@@ -4312,7 +4337,7 @@ static int Object_setLayersMask( BPy_Object *self, PyObject *value )
int layers = 0, local;
Base *base;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected an integer (bitmask) as argument" );
@@ -4333,11 +4358,14 @@ static int Object_setLayersMask( BPy_Object *self, PyObject *value )
local = base->lay;
base->lay = local | layers;
self->object->lay = base->lay;
+ break;
}
base = base->next;
}
- countall();
- DAG_scene_sort( G.scene );
+ if (base) { /* The object was found? */
+ countall();
+ DAG_scene_sort( G.scene );
+ }
return 0;
}
@@ -4974,6 +5002,10 @@ static PyGetSetDef BPy_Object_getseters[] = {
(getter)Object_getTransflagBits, (setter)Object_setTransflagBits,
"Use face scale to scale all dupliFaces",
(void *)OB_DUPLIFACES_SCALE},
+ {"dupFacesScaleFac",
+ (getter)getFloatAttr, (setter)setFloatAttr,
+ "Use face scale to scale all dupliFaces",
+ (void *)EXPP_OBJ_ATTR_DUPFACESCALEFAC},
{"enableDupFrames",
(getter)Object_getTransflagBits, (setter)Object_setTransflagBits,
"Make copy of object for every frame",
@@ -5044,10 +5076,6 @@ static PyGetSetDef BPy_Object_getseters[] = {
(getter)Object_getRBHalfExtents, (setter)NULL,
"Rigid body physics bounds object type",
NULL},
- {"type",
- (getter)Object_getType, (setter)NULL,
- "String describing Object type",
- NULL},
{"restrictDisplay",
(getter)Object_getRestricted, (setter)Object_setRestricted,
@@ -5301,6 +5329,7 @@ static PyObject *M_Object_IpoKeyTypesDict( void )
PyConstant_Insert( d, "SIZE", PyInt_FromLong( IPOKEY_SIZE ) );
PyConstant_Insert( d, "LOCROT", PyInt_FromLong( IPOKEY_LOCROT ) );
PyConstant_Insert( d, "LOCROTSIZE", PyInt_FromLong( IPOKEY_LOCROTSIZE ) );
+ PyConstant_Insert( d, "LAYER", PyInt_FromLong( IPOKEY_LAYER ) );
PyConstant_Insert( d, "PI_STRENGTH", PyInt_FromLong( IPOKEY_PI_STRENGTH ) );
PyConstant_Insert( d, "PI_FALLOFF", PyInt_FromLong( IPOKEY_PI_FALLOFF ) );
@@ -5338,7 +5367,8 @@ PyObject *Object_Init( void )
PyModule_AddIntConstant( module, "SIZE", IPOKEY_SIZE );
PyModule_AddIntConstant( module, "LOCROT", IPOKEY_LOCROT );
PyModule_AddIntConstant( module, "LOCROTSIZE", IPOKEY_LOCROTSIZE );
-
+ PyModule_AddIntConstant( module, "LAYER", IPOKEY_LAYER );
+
PyModule_AddIntConstant( module, "PI_STRENGTH", IPOKEY_PI_STRENGTH );
PyModule_AddIntConstant( module, "PI_FALLOFF", IPOKEY_PI_FALLOFF );
PyModule_AddIntConstant( module, "PI_SURFACEDAMP", IPOKEY_PI_SURFACEDAMP );
diff --git a/source/blender/python/api2_2x/Pose.c b/source/blender/python/api2_2x/Pose.c
index fe60b04b5ff..01fbe591a74 100644
--- a/source/blender/python/api2_2x/Pose.c
+++ b/source/blender/python/api2_2x/Pose.c
@@ -57,6 +57,8 @@
#include "DNA_armature_types.h" /*used for pose bone select*/
+#include "MEM_guardedalloc.h"
+
extern void chan_calc_mat(bPoseChannel *chan);
//------------------------ERROR CODES---------------------------------
@@ -143,11 +145,14 @@ static int PoseBonesDict_InitBones(BPy_PoseBonesDict *self)
//This is the string representation of the object
static PyObject *PoseBonesDict_repr(BPy_PoseBonesDict *self)
{
- char buffer[128], str[4096];
+ char buffer[128], *str;
PyObject *key, *value;
int pos = 0;
-
- BLI_strncpy(str,"",4096);
+
+ /* probably a bit of overkill but better then crashing */
+ str = MEM_mallocN( 64 + ( PyDict_Size( self->bonesMap ) * 128), "PoseBonesDict_repr" );
+ str[0] = '\0';
+
sprintf(buffer, "[Pose Bone Dict: {");
strcat(str,buffer);
while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
@@ -157,6 +162,9 @@ static PyObject *PoseBonesDict_repr(BPy_PoseBonesDict *self)
}
sprintf(buffer, "}]\n");
strcat(str,buffer);
+
+ MEM_freeN( str );
+
return PyString_FromString(str);
}
@@ -414,7 +422,11 @@ static PyObject *PoseBone_insertKey(BPy_PoseBone *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!i|Oi", &Object_Type, &parent_object, &frame, &constants, &no_ipo_update ))
goto AttributeError;
-
+
+ /* incase we ever have a value other then 1 for fast */
+ if (no_ipo_update)
+ no_ipo_update = 1;
+
//verify that this pchannel is part of the object->pose
for (pchan = ((BPy_Object*)parent_object)->object->pose->chanbase.first;
pchan; pchan = pchan->next){
@@ -479,40 +491,40 @@ static PyObject *PoseBone_insertKey(BPy_PoseBone *self, PyObject *args)
//add the action channel if it's not there
verify_action_channel(((BPy_Object*)parent_object)->object->action,
self->posechannel->name);
-
+
//insert the pose keys
if (self->posechannel->flag & POSE_ROT){
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_QUAT_X);
+ ID_PO, self->posechannel->name, NULL, AC_QUAT_X, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_QUAT_Y);
+ ID_PO, self->posechannel->name, NULL, AC_QUAT_Y, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_QUAT_Z);
+ ID_PO, self->posechannel->name, NULL, AC_QUAT_Z, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_QUAT_W);
+ ID_PO, self->posechannel->name, NULL, AC_QUAT_W, no_ipo_update);
}
if (self->posechannel->flag & POSE_LOC){
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_LOC_X);
+ ID_PO, self->posechannel->name, NULL, AC_LOC_X, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_LOC_Y);
+ ID_PO, self->posechannel->name, NULL, AC_LOC_Y, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_LOC_Z);
+ ID_PO, self->posechannel->name, NULL, AC_LOC_Z, no_ipo_update);
}
if (self->posechannel->flag & POSE_SIZE){
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_SIZE_X);
+ ID_PO, self->posechannel->name, NULL, AC_SIZE_X, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_SIZE_Y);
+ ID_PO, self->posechannel->name, NULL, AC_SIZE_Y, no_ipo_update);
insertkey(&((BPy_Object*)parent_object)->object->id,
- ID_PO, self->posechannel->name, NULL, AC_SIZE_Z);
+ ID_PO, self->posechannel->name, NULL, AC_SIZE_Z, no_ipo_update);
}
//flip the frame back
G.scene->r.cfra = oldframe;
//update the IPOs
- if (!no_ipo_update)
+ if (no_ipo_update==0)
remake_action_ipos (((BPy_Object*)parent_object)->object->action);
Py_RETURN_NONE;
@@ -685,9 +697,12 @@ static int PoseBone_setLocalMatrix(BPy_PoseBone *self, PyObject *value, void *cl
}
//get loc
- if (matsize == 4){
+ if (matsize == 4) {
VECCOPY(loc, matrix->matrix[3]);
}
+ else {
+ loc[0]= loc[1]= loc[2]= 0.0f;
+ }
//copy new attributes
VECCOPY(self->posechannel->size, size);
@@ -712,10 +727,35 @@ static PyObject *PoseBone_getPoseMatrix(BPy_PoseBone *self, void *closure)
}
//------------------------PoseBone.poseMatrix (setter)
//Sets the pose_mat
-static int PoseBone_setPoseMatrix(BPy_PoseBone *self, PyObject *value, void *closure)
+static int PoseBone_setPoseMatrix(BPy_PoseBone *self, MatrixObject *value, void *closure)
{
- return EXPP_intError(PyExc_AttributeError, "%s%s%s",
- sPoseBoneError, ".poseMatrix: ", "not able to set this property");
+ float delta_mat[4][4], quat[4]; /* rotation */
+ float size[4]; /* size only */
+
+ if( !MatrixObject_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected matrix object as argument" );
+
+ if( value->colSize != 4 || value->rowSize != 4 )
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "matrix must be a 4x4 transformation matrix\n"
+ "for example as returned by object.matrixWorld" );
+
+ /* get bone-space cursor matrix and extract location */
+ armature_mat_pose_to_bone(self->posechannel, (float (*)[4]) *value->matrix, delta_mat);
+
+ /* Visual Location */
+ VECCOPY(self->posechannel->loc, delta_mat[3]);
+
+ /* Visual Size */
+ Mat4ToSize(delta_mat, size);
+ VECCOPY(self->posechannel->size, size);
+
+ /* Visual Rotation */
+ Mat4ToQuat(delta_mat, quat);
+ QUATCOPY(self->posechannel->quat, quat);
+
+ return 0;
}
//------------------------PoseBone.constraints (getter)
//Gets the constraints sequence
@@ -931,7 +971,12 @@ static PyObject *PoseBone_getSelect(BPy_PoseBone *self, void *closure)
//Sets the pose bones selection
static int PoseBone_setSelect(BPy_PoseBone *self, PyObject *value, void *closure)
{
- if (PyObject_IsTrue( value ))
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if ( param )
self->posechannel->bone->flag |= BONE_SELECTED;
else
self->posechannel->bone->flag &= ~(BONE_SELECTED | BONE_ACTIVE);
@@ -1071,13 +1116,46 @@ static PyObject *PoseBone_getIKFlag(BPy_PoseBone *self, void *flag)
//Sets the pose bones ikflag
static int PoseBone_setIKFlag(BPy_PoseBone *self, PyObject *value, void *flag)
{
- if ( PyObject_IsTrue(value) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if ( param )
self->posechannel->ikflag |= (int)flag;
else
self->posechannel->ikflag &= ~(int)flag;
return 0;
}
+//------------------------Bone.layerMask (get)
+static PyObject *PoseBone_getLayerMask(BPy_PoseBone *self)
+{
+ /* do this extra stuff because the short's bits can be negative values */
+ unsigned short laymask = 0;
+ laymask |= self->posechannel->bone->layer;
+ return PyInt_FromLong((int)laymask);
+}
+//------------------------Bone.layerMask (set)
+static int PoseBone_setLayerMask(BPy_PoseBone *self, PyObject *value)
+{
+ int laymask;
+ if (!PyInt_Check(value)) {
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "expected an integer (bitmask) as argument" );
+ }
+
+ laymask = PyInt_AsLong(value);
+
+ if (laymask <= 0 || laymask > (1<<16) - 1)
+ return EXPP_ReturnIntError( PyExc_AttributeError,
+ "bitmask must have from 1 up to 16 bits set");
+
+ self->posechannel->bone->layer = 0;
+ self->posechannel->bone->layer |= laymask;
+
+ return 0;
+}
//------------------TYPE_OBECT IMPLEMENTATION---------------------------
//------------------------tp_getset
@@ -1138,7 +1216,8 @@ static PyGetSetDef BPy_PoseBone_getset[] = {
"disable Y DoF when part of an IK", (void *)BONE_IK_NO_YDOF },
{"lockZRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,
"disable Z DoF when part of an IK", (void *)BONE_IK_NO_ZDOF },
-
+ {"layerMask", (getter)PoseBone_getLayerMask, (setter)PoseBone_setLayerMask,
+ "Layer bitmask", NULL },
{NULL, NULL, NULL, NULL, NULL}
};
//------------------------tp_dealloc
diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c
index fd139c4fe6e..c5bd7ef9056 100644
--- a/source/blender/python/api2_2x/Scene.c
+++ b/source/blender/python/api2_2x/Scene.c
@@ -42,6 +42,7 @@ struct View3D;
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h" /* U.userdefs */
#include "DNA_object_types.h" /* SceneObSeq_new */
+#include "BKE_armature.h"
#include "BKE_depsgraph.h"
#include "BKE_library.h"
#include "BKE_object.h"
@@ -51,12 +52,15 @@ struct View3D;
#include "BLI_blenlib.h" /* only for SceneObSeq_new */
#include "BSE_drawview.h" /* for play_anim */
#include "BSE_headerbuttons.h" /* for copy_scene */
+#include "BSE_sequence.h" /* to clear_scene_in_allseqs */
+#include "BSE_node.h" /* to clear_scene_in_nodes */
#include "BIF_drawscene.h" /* for set_scene */
#include "BIF_space.h" /* for copy_view3d_lock() */
#include "BIF_screen.h" /* curarea */
#include "BDR_editobject.h" /* free_and_unlink_base() */
#include "mydevice.h" /* for #define REDRAW */
#include "DNA_view3d_types.h"
+
/* python types */
#include "Object.h"
#include "Camera.h"
@@ -145,7 +149,7 @@ static PyObject *Scene_getCurrentCamera( BPy_Scene * self );
static PyObject *Scene_setCurrentCamera( BPy_Scene * self, PyObject * args );
static PyObject *Scene_getRenderingContext( BPy_Scene * self );
static PyObject *Scene_getRadiosityContext( BPy_Scene * self );
-static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args );
+static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * value );
static PyObject *Scene_getSequence( BPy_Scene * self );
static PyObject *Scene_addScriptLink( BPy_Scene * self, PyObject * args );
static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args );
@@ -194,7 +198,7 @@ static PyMethodDef BPy_Scene_methods[] = {
{"getCurrentCamera", ( PyCFunction ) Scene_getCurrentCamera,
METH_NOARGS,
"() - Return current active Camera"},
- {"getScriptLinks", ( PyCFunction ) Scene_getScriptLinks, METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) Scene_getScriptLinks, METH_O,
"(eventname) - Get a list of this scene's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, OnLoad, OnSave, Redraw or Render."},
@@ -249,7 +253,7 @@ static int Scene_setLayerMask( BPy_Scene * self, PyObject * value )
SCENE_DEL_CHECK_INT(self);
- if (!PyInt_CheckExact(value)) {
+ if (!PyInt_Check(value)) {
return EXPP_ReturnIntError( PyExc_AttributeError,
"expected an integer (bitmask) as argument" );
}
@@ -718,8 +722,9 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
{
PyObject *pyobj;
BPy_Scene *pyscn;
- Scene *scene;
-
+ Scene *scene, *sce;
+ bScreen *sc;
+
if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Scene PyType object" );
@@ -733,6 +738,23 @@ static PyObject *M_Scene_Unlink( PyObject * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_SystemError,
"current Scene cannot be removed!" );
+ /* Copied from header_info.c */
+
+ /* check all sets */
+ for (sce= G.main->scene.first; sce; sce= sce->id.next) {
+ if(sce->set == scene) sce->set= 0;
+ }
+
+ /* check all sequences */
+ clear_scene_in_allseqs(scene);
+
+ /* check render layer nodes in other scenes */
+ clear_scene_in_nodes(scene);
+
+ for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
+ if(sc->scene == scene) sc->scene= G.scene;
+ }
+
free_libblock( &G.main->scene, scene );
pyscn->scene= NULL;
@@ -753,16 +775,16 @@ static PyObject *Scene_oldsetLayers( BPy_Scene * self, PyObject * args )
/*-----------------------Scene.copy()------------------------------------*/
static PyObject *Scene_copy( BPy_Scene * self, PyObject * args )
{
- short dup_objs = 1;
+ short dup_objs = 2;
Scene *scene = self->scene;
SCENE_DEL_CHECK_PY(self);
- if( !PyArg_ParseTuple( args, "|h", &dup_objs ) )
+ if( !PyArg_ParseTuple( args, "|h", &dup_objs ) || dup_objs < 0 || dup_objs > 2)
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int in [0,2] or nothing as argument" );
-
- return Scene_CreatePyObject( copy_scene( scene, dup_objs ) );
+
+ return Scene_CreatePyObject( copy_scene( scene, dup_objs+1 ) );
}
/*-----------------------Scene.makeCurrent()-----------------------------*/
@@ -805,10 +827,18 @@ static PyObject *Scene_update( BPy_Scene * self, PyObject * args )
if( !full )
DAG_scene_sort( scene );
- else if( full == 1 )
+ else if( full == 1 ) {
+ int enablescripts = G.f & G_DOSCRIPTLINKS;
+
+ /*Disable scriptlinks to prevent firing off newframe scriptlink
+ events.*/
+ G.f &= ~G_DOSCRIPTLINKS;
set_scene_bg( scene );
-
- else
+ scene_update_for_newframe( scene, scene->lay );
+
+ /*re-enabled scriptlinks if necassary.*/
+ if (enablescripts) G.f |= G_DOSCRIPTLINKS;
+ } else
return EXPP_ReturnPyObjError( PyExc_ValueError,
"in method scene.update(full), full should be:\n"
"0: to only sort scene elements (old behavior); or\n"
@@ -999,9 +1029,6 @@ static PyObject *Scene_getActiveObject(BPy_Scene *self)
/*-----------------------Scene.getCurrentCamera()------------------------*/
static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
{
- Object *cam_obj;
- PyObject *pyob;
- Scene *scene = self->scene;
static char warning = 1;
if( warning ) {
@@ -1010,18 +1037,8 @@ static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
}
SCENE_DEL_CHECK_PY(self);
-
- cam_obj = scene->camera;
-
- if( cam_obj ) { /* if found, return a wrapper for it */
- pyob = Object_CreatePyObject( cam_obj );
- if (!pyob)
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "couldn't create new object wrapper!");
- return pyob;
- }
-
- Py_RETURN_NONE; /* none found */
+ /* None is ok */
+ return Object_CreatePyObject( self->scene->camera );
}
/*-----------------------Scene.setCurrentCamera()------------------------*/
@@ -1076,10 +1093,7 @@ static PyObject *Scene_getRadiosityContext( BPy_Scene * self )
static PyObject *Scene_getSequence( BPy_Scene * self )
{
SCENE_DEL_CHECK_PY(self);
- if (self->scene->ed) /* we should create this if its not there :/ */
- return SceneSeq_CreatePyObject( self->scene, NULL );
- else
- Py_RETURN_NONE;
+ return SceneSeq_CreatePyObject( self->scene, NULL );
}
/* scene.addScriptLink */
@@ -1109,7 +1123,7 @@ static PyObject *Scene_clearScriptLinks( BPy_Scene * self, PyObject * args )
}
/* scene.getScriptLinks */
-static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
+static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * value )
{
Scene *scene = self->scene;
ScriptLink *slink = NULL;
@@ -1119,7 +1133,7 @@ static PyObject *Scene_getScriptLinks( BPy_Scene * self, PyObject * args )
slink = &( scene )->scriptlink;
- ret = EXPP_getScriptLinks( slink, args, 1 );
+ ret = EXPP_getScriptLinks( slink, value, 1 );
if( ret )
return ret;
@@ -1333,7 +1347,6 @@ static int SceneObSeq_len( BPy_SceneObSeq * self )
static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
{
int index=0;
- PyObject *bpy_obj;
Base *base= NULL;
Scene *scene= self->bpyscene->scene;
@@ -1360,13 +1373,7 @@ static PyObject *SceneObSeq_item( BPy_SceneObSeq * self, int i )
return EXPP_ReturnPyObjError( PyExc_IndexError,
"array index out of range" );
- bpy_obj = Object_CreatePyObject( base->object );
-
- if( !bpy_obj )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyObject_New() failed" );
-
- return (PyObject *)bpy_obj;
+ return Object_CreatePyObject( base->object );
}
static PySequenceMethods SceneObSeq_as_sequence = {
@@ -1556,8 +1563,11 @@ typeError:
object->flag = SELECT;
/* creates the curve for the text object */
- if (type == OB_FONT)
+ if (type == OB_FONT) {
text_to_curve(object, 0);
+ } else if (object->type == OB_ARMATURE) {
+ armature_rebuild_pose(object, (bArmature *)data);
+ }
/* link to scene */
base = MEM_callocN( sizeof( Base ), "pynewbase" );
@@ -1630,9 +1640,7 @@ static PyObject *SceneObSeq_unlink( BPy_SceneObSeq * self, PyObject *args )
PyObject *SceneObSeq_getActive(BPy_SceneObSeq *self)
{
- PyObject *pyob;
Base *base;
-
SCENE_DEL_CHECK_PY(self->bpyscene);
if (self->mode!=EXPP_OBSEQ_NORMAL)
@@ -1643,13 +1651,7 @@ PyObject *SceneObSeq_getActive(BPy_SceneObSeq *self)
if (!base)
Py_RETURN_NONE;
- pyob = Object_CreatePyObject( base->object );
-
- if (!pyob)
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "couldn't create new object wrapper!");
-
- return pyob;
+ return Object_CreatePyObject( base->object );
}
static int SceneObSeq_setActive(BPy_SceneObSeq *self, PyObject *value)
@@ -1683,26 +1685,13 @@ static int SceneObSeq_setActive(BPy_SceneObSeq *self, PyObject *value)
PyObject *SceneObSeq_getCamera(BPy_SceneObSeq *self)
{
- PyObject *pyob;
- Object *ob;
-
SCENE_DEL_CHECK_PY(self->bpyscene);
if (self->mode!=EXPP_OBSEQ_NORMAL)
return (EXPP_ReturnPyObjError( PyExc_TypeError,
"cannot get camera from objects.selected or objects.context" ));
- ob= self->bpyscene->scene->camera;
- if (!ob)
- Py_RETURN_NONE;
-
- pyob = Object_CreatePyObject( ob );
-
- if (!pyob)
- return EXPP_ReturnPyObjError(PyExc_MemoryError,
- "couldn't create new object wrapper!");
-
- return pyob;
+ return Object_CreatePyObject( self->bpyscene->scene->camera );
}
static int SceneObSeq_setCamera(BPy_SceneObSeq *self, PyObject *value)
diff --git a/source/blender/python/api2_2x/Sound.c b/source/blender/python/api2_2x/Sound.c
index 350d04e5a63..6e20e4c3ee5 100644
--- a/source/blender/python/api2_2x/Sound.c
+++ b/source/blender/python/api2_2x/Sound.c
@@ -59,7 +59,7 @@
/* Python API function prototypes for the Sound module. */
/*****************************************************************************/
static PyObject *M_Sound_Get( PyObject * self, PyObject * args );
-static PyObject *M_Sound_Load( PyObject * self, PyObject * args );
+static PyObject *M_Sound_Load( PyObject * self, PyObject * value );
/************************************************************************/
/* The following string definitions are used for documentation strings. */
@@ -82,7 +82,7 @@ returns None if not found.";
/*****************************************************************************/
struct PyMethodDef M_Sound_methods[] = {
{"Get", M_Sound_Get, METH_VARARGS, M_Sound_Get_doc},
- {"Load", M_Sound_Load, METH_VARARGS, M_Sound_Load_doc},
+ {"Load", M_Sound_Load, METH_O, M_Sound_Load_doc},
{NULL, NULL, 0, NULL}
};
@@ -92,29 +92,24 @@ struct PyMethodDef M_Sound_methods[] = {
static int Sound_compare( BPy_Sound * a, BPy_Sound * b );
static PyObject *Sound_repr( BPy_Sound * self );
-#define SOUND_FLOAT_METHODS(funcname, varname) \
-static PyObject *Sound_get ## funcname(BPy_Sound *self) { \
- char e[256]; \
- PyObject *attr = PyFloat_FromDouble(self->sound->varname); \
- if (attr) return attr; \
- sprintf(e, "couldn't get Sound.%s attribute", #varname); \
- return EXPP_ReturnPyObjError (PyExc_RuntimeError, e); \
-} \
+#define SOUND_FLOAT_METHODS(funcname, varname) \
+static PyObject *Sound_get ## funcname(BPy_Sound *self) { \
+ return PyFloat_FromDouble(self->sound->varname); \
+} \
static PyObject *Sound_set ## funcname(BPy_Sound *self, PyObject *args) { \
- float f = 0; \
- if (!PyArg_ParseTuple(args, "f", &f)) \
- return (EXPP_ReturnPyObjError (PyExc_TypeError, \
- "expected float argument")); \
- self->sound->varname = EXPP_ClampFloat(f,\
- EXPP_SND_##varname##_MIN, EXPP_SND_##varname##_MAX);\
- Py_INCREF(Py_None); \
- return Py_None; \
+ float f = 0; \
+ if (!PyArg_ParseTuple(args, "f", &f)) \
+ return (EXPP_ReturnPyObjError (PyExc_TypeError, \
+ "expected float argument")); \
+ self->sound->varname = EXPP_ClampFloat(f, \
+ EXPP_SND_##varname##_MIN, EXPP_SND_##varname##_MAX); \
+ Py_RETURN_NONE; \
}
-#define SOUND_FLOAT_METHOD_FUNCS(varname) \
-{"get"#varname, (PyCFunction)Sound_get ## varname, METH_NOARGS, \
-"() - Return Sound object "#varname}, \
-{"set"#varname, (PyCFunction)Sound_set ## varname, METH_VARARGS, \
+#define SOUND_FLOAT_METHOD_FUNCS(varname) \
+{"get"#varname, (PyCFunction)Sound_get ## varname, METH_NOARGS, \
+"() - Return Sound object "#varname}, \
+{"set"#varname, (PyCFunction)Sound_set ## varname, METH_VARARGS, \
"(float) - Change Sound object "#varname},
@@ -265,13 +260,13 @@ static PyObject *M_Sound_Get( PyObject * self, PyObject * args )
/* Description: Receives a string and returns the Sound object */
/* whose filename matches the string. */
/*****************************************************************************/
-static PyObject *M_Sound_Load( PyObject * self, PyObject * args )
+static PyObject *M_Sound_Load( PyObject * self, PyObject * value )
{
- char *fname;
+ char *fname = PyString_AsString(value);
bSound *snd_ptr;
BPy_Sound *snd;
- if( !PyArg_ParseTuple( args, "s", &fname ) )
+ if( !fname )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" ) );
@@ -354,24 +349,12 @@ bSound *Sound_FromPyObject( PyObject * pyobj )
/*****************************************************************************/
static PyObject *Sound_getName( BPy_Sound * self )
{
- PyObject *attr = PyString_FromString( self->sound->id.name + 2 );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Sound.name attribute" ) );
+ return PyString_FromString( self->sound->id.name + 2 );
}
static PyObject *Sound_getFilename( BPy_Sound * self )
{
- PyObject *attr = PyString_FromString( self->sound->name );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Sound.filename attribute" ) );
+ return PyString_FromString( self->sound->name );
}
static PyObject *Sound_getPacked( BPy_Sound * self )
diff --git a/source/blender/python/api2_2x/SurfNurb.c b/source/blender/python/api2_2x/SurfNurb.c
index 0cac359dcf9..3499ec09936 100644
--- a/source/blender/python/api2_2x/SurfNurb.c
+++ b/source/blender/python/api2_2x/SurfNurb.c
@@ -457,9 +457,14 @@ static PyObject *SurfNurb_getCyclicV( BPy_SurfNurb * self )
Py_RETURN_FALSE;
}
-static int SurfNurb_setCyclicU( BPy_SurfNurb * self, PyObject * args )
+static int SurfNurb_setCyclicU( BPy_SurfNurb * self, PyObject * value )
{
- if( PyObject_IsTrue( args ) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->nurb->flagu |= CU_CYCLIC;
else
self->nurb->flagu &= ~CU_CYCLIC;
@@ -467,9 +472,14 @@ static int SurfNurb_setCyclicU( BPy_SurfNurb * self, PyObject * args )
return 0;
}
-static int SurfNurb_setCyclicV( BPy_SurfNurb * self, PyObject * args )
+static int SurfNurb_setCyclicV( BPy_SurfNurb * self, PyObject * value )
{
- if( PyObject_IsTrue( args ) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->nurb->flagv |= CU_CYCLIC;
else
self->nurb->flagv &= ~CU_CYCLIC;
@@ -762,7 +772,7 @@ PyTypeObject SurfNurb_Type = {
/* More standard operations (here for binary compatibility) */
- ( hashfunc ) GenericLib_hash, /* hashfunc tp_hash; */
+ NULL, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
NULL, /* reprfunc tp_str; */
NULL, /* getattrofunc tp_getattro; */
diff --git a/source/blender/python/api2_2x/Sys.c b/source/blender/python/api2_2x/Sys.c
index db74ce40b4a..7dc841e9d68 100644
--- a/source/blender/python/api2_2x/Sys.c
+++ b/source/blender/python/api2_2x/Sys.c
@@ -51,16 +51,16 @@
/*****************************************************************************/
/* Python API function prototypes for the sys module. */
/*****************************************************************************/
-static PyObject *M_sys_basename( PyObject * self, PyObject * args );
-static PyObject *M_sys_dirname( PyObject * self, PyObject * args );
+static PyObject *M_sys_basename( PyObject * self, PyObject * value );
+static PyObject *M_sys_dirname( PyObject * self, PyObject * value );
static PyObject *M_sys_join( PyObject * self, PyObject * args );
-static PyObject *M_sys_splitext( PyObject * self, PyObject * args );
+static PyObject *M_sys_splitext( PyObject * self, PyObject * value );
static PyObject *M_sys_makename( PyObject * self, PyObject * args,
PyObject * kw );
-static PyObject *M_sys_exists( PyObject * self, PyObject * args );
+static PyObject *M_sys_exists( PyObject * self, PyObject * value );
static PyObject *M_sys_time( PyObject * self );
static PyObject *M_sys_sleep( PyObject * self, PyObject * args );
-static PyObject *M_sys_expandpath( PyObject *self, PyObject *args);
+static PyObject *M_sys_expandpath( PyObject *self, PyObject *value);
/*****************************************************************************/
/* The following string definitions are used for documentation strings. */
@@ -131,17 +131,17 @@ If the special chars are not found in the given path, it is simply returned.";
/* Python method structure definition for Blender.sys module: */
/*****************************************************************************/
struct PyMethodDef M_sys_methods[] = {
- {"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
- {"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
+ {"basename", M_sys_basename, METH_O, M_sys_basename_doc},
+ {"dirname", M_sys_dirname, METH_O, M_sys_dirname_doc},
{"join", M_sys_join, METH_VARARGS, M_sys_join_doc},
- {"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
+ {"splitext", M_sys_splitext, METH_O, M_sys_splitext_doc},
{"makename", ( PyCFunction ) M_sys_makename,
METH_VARARGS | METH_KEYWORDS,
M_sys_makename_doc},
- {"exists", M_sys_exists, METH_VARARGS, M_sys_exists_doc},
+ {"exists", M_sys_exists, METH_O, M_sys_exists_doc},
{"sleep", M_sys_sleep, METH_VARARGS, M_sys_sleep_doc},
{"time", ( PyCFunction ) M_sys_time, METH_NOARGS, M_sys_time_doc},
- {"expandpath", M_sys_expandpath, METH_VARARGS, M_sys_expandpath_doc},
+ {"expandpath", M_sys_expandpath, METH_O, M_sys_expandpath_doc},
{NULL, NULL, 0, NULL}
};
@@ -165,12 +165,13 @@ PyObject *sys_Init( void )
return submodule;
}
-static PyObject *M_sys_basename( PyObject * self, PyObject * args )
+static PyObject *M_sys_basename( PyObject * self, PyObject * value )
{
- char *name, *p, basename[FILE_MAXDIR + FILE_MAXFILE];
+ char *name = PyString_AsString(value);
+ char *p, basename[FILE_MAXDIR + FILE_MAXFILE];
int n, len;
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -196,12 +197,13 @@ static PyObject *M_sys_basename( PyObject * self, PyObject * args )
return PyString_FromString( name );
}
-static PyObject *M_sys_dirname( PyObject * self, PyObject * args )
+static PyObject *M_sys_dirname( PyObject * self, PyObject * value )
{
- char *name, *p, dirname[FILE_MAXDIR + FILE_MAXFILE];
+ char *name = PyString_AsString(value);
+ char *p, dirname[FILE_MAXDIR + FILE_MAXFILE];
int n;
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -254,12 +256,13 @@ static PyObject *M_sys_join( PyObject * self, PyObject * args )
return PyString_FromString( filename );
}
-static PyObject *M_sys_splitext( PyObject * self, PyObject * args )
+static PyObject *M_sys_splitext( PyObject * self, PyObject * value )
{
- char *name, *dot, *p, path[FILE_MAXDIR + FILE_MAXFILE], ext[FILE_MAXDIR + FILE_MAXFILE];
+ char *name = PyString_AsString(value);
+ char *dot, *p, path[FILE_MAXDIR + FILE_MAXFILE], ext[FILE_MAXDIR + FILE_MAXFILE];
int n, len;
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -358,12 +361,13 @@ static PyObject *M_sys_sleep( PyObject * self, PyObject * args )
return EXPP_incr_ret( Py_None );
}
-static PyObject *M_sys_exists( PyObject * self, PyObject * args )
+static PyObject *M_sys_exists( PyObject * self, PyObject * value )
{
- char *fname = NULL;
+ char *fname = PyString_AsString(value);
+
int mode = 0, i = -1;
- if( !PyArg_ParseTuple( args, "s", &fname ) )
+ if( !fname )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string (pathname) argument" );
@@ -380,12 +384,12 @@ static PyObject *M_sys_exists( PyObject * self, PyObject * args )
return PyInt_FromLong(i);
}
-static PyObject *M_sys_expandpath( PyObject * self, PyObject * args )
+static PyObject *M_sys_expandpath( PyObject * self, PyObject * value )
{
- char *path = NULL;
+ char *path = PyString_AsString(value);
char expanded[FILE_MAXDIR + FILE_MAXFILE];
- if (!PyArg_ParseTuple( args, "s", &path))
+ if (!path)
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
diff --git a/source/blender/python/api2_2x/Text.c b/source/blender/python/api2_2x/Text.c
index da4fbe44eb0..6c577285266 100644
--- a/source/blender/python/api2_2x/Text.c
+++ b/source/blender/python/api2_2x/Text.c
@@ -51,7 +51,7 @@
/*****************************************************************************/
static PyObject *M_Text_New( PyObject * self, PyObject * args);
static PyObject *M_Text_Get( PyObject * self, PyObject * args );
-static PyObject *M_Text_Load( PyObject * self, PyObject * args );
+static PyObject *M_Text_Load( PyObject * self, PyObject * value );
static PyObject *M_Text_unlink( PyObject * self, PyObject * args );
/*****************************************************************************/
@@ -81,7 +81,7 @@ struct PyMethodDef M_Text_methods[] = {
{"New", M_Text_New, METH_VARARGS, M_Text_New_doc},
{"Get", M_Text_Get, METH_VARARGS, M_Text_Get_doc},
{"get", M_Text_Get, METH_VARARGS, M_Text_Get_doc},
- {"Load", M_Text_Load, METH_VARARGS, M_Text_Load_doc},
+ {"Load", M_Text_Load, METH_O, M_Text_Load_doc},
{"unlink", M_Text_unlink, METH_VARARGS, M_Text_unlink_doc},
{NULL, NULL, 0, NULL}
};
@@ -93,7 +93,7 @@ struct PyMethodDef M_Text_methods[] = {
static PyObject *Text_getFilename( BPy_Text * self );
static PyObject *Text_getNLines( BPy_Text * self );
static PyObject *Text_clear( BPy_Text * self );
-static PyObject *Text_write( BPy_Text * self, PyObject * args );
+static PyObject *Text_write( BPy_Text * self, PyObject * value );
static PyObject *Text_set( BPy_Text * self, PyObject * args );
static PyObject *Text_asLines( BPy_Text * self );
@@ -112,7 +112,7 @@ static PyMethodDef BPy_Text_methods[] = {
"(str) - Change Text Object name"},
{"clear", ( PyCFunction ) Text_clear, METH_NOARGS,
"() - Clear Text buffer"},
- {"write", ( PyCFunction ) Text_write, METH_VARARGS,
+ {"write", ( PyCFunction ) Text_write, METH_O,
"(line) - Append string 'str' to Text buffer"},
{"set", ( PyCFunction ) Text_set, METH_VARARGS,
"(name, val) - Set attribute 'name' to value 'val'"},
@@ -240,14 +240,14 @@ static PyObject *M_Text_Get( PyObject * self, PyObject * args )
/* Description: Receives a filename and returns the text object */
/* created from the corresponding file. */
/*****************************************************************************/
-static PyObject *M_Text_Load( PyObject * self, PyObject * args )
+static PyObject *M_Text_Load( PyObject * self, PyObject * value )
{
- char *fname = NULL;
+ char *fname = PyString_AsString(value);
char fpath[FILE_MAXDIR + FILE_MAXFILE];
Text *txt_ptr = NULL;
unsigned int maxlen = FILE_MAXDIR + FILE_MAXFILE;
- if( !PyArg_ParseTuple( args, "s", &fname ) )
+ if( !fname )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" ) );
@@ -289,6 +289,7 @@ static PyObject *M_Text_unlink( PyObject * self, PyObject * args )
"this text was already unlinked!" );
BPY_clear_bad_scriptlinks( text );
+ BPY_free_pyconstraint_links( text );
free_text_controllers( text );
unlink_text( text );
@@ -338,26 +339,16 @@ PyObject *Text_CreatePyObject( Text * txt )
/*****************************************************************************/
static PyObject *Text_getFilename( BPy_Text * self )
{
- PyObject *attr;
- char *name = self->text->name;
-
- if( name )
- attr = PyString_FromString( self->text->name );
- else
- attr = Py_None;
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Text.filename attribute" );
+ if( self->text->name )
+ return PyString_FromString( self->text->name );
+
+ Py_RETURN_NONE;
}
static PyObject *Text_getNLines( BPy_Text * self )
{ /* text->nlines isn't updated in Blender (?) */
int nlines = 0;
TextLine *line;
- PyObject *attr;
line = self->text->lines.first;
@@ -368,13 +359,7 @@ static PyObject *Text_getNLines( BPy_Text * self )
self->text->nlines = nlines; /* and update Blender, too (should we?) */
- attr = PyInt_FromLong( nlines );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Text.nlines attribute" );
+ return PyInt_FromLong( nlines );
}
static PyObject *Text_clear( BPy_Text * self)
@@ -413,16 +398,16 @@ static PyObject *Text_set( BPy_Text * self, PyObject * args )
Py_RETURN_NONE;
}
-static PyObject *Text_write( BPy_Text * self, PyObject * args )
+static PyObject *Text_write( BPy_Text * self, PyObject * value )
{
- char *str;
+ char *str = PyString_AsString(value);
int oldstate;
if( !self->text )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This object isn't linked to a Blender Text Object" );
- if( !PyArg_ParseTuple( args, "s", &str ) )
+ if( !str )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
diff --git a/source/blender/python/api2_2x/Text3d.c b/source/blender/python/api2_2x/Text3d.c
index 4e860113ac8..57a9c74b71d 100644
--- a/source/blender/python/api2_2x/Text3d.c
+++ b/source/blender/python/api2_2x/Text3d.c
@@ -83,7 +83,7 @@ static PyObject *generate_ModuleIntConstant(char *name, int value);
struct PyMethodDef M_Text3d_methods[] = {
{"New", ( PyCFunction ) M_Text3d_New, METH_VARARGS, NULL},
{"Get", ( PyCFunction ) M_Text3d_Get, METH_VARARGS, NULL},
- {"LoadFont", ( PyCFunction ) M_Text3d_LoadFont, METH_VARARGS, NULL},
+ {"LoadFont", ( PyCFunction ) M_Text3d_LoadFont, METH_O, NULL},
{NULL, NULL, 0, NULL}
};
@@ -102,7 +102,7 @@ static int Text3d_compare( BPy_Text3d * a, BPy_Text3d * b );
/*PyObject *Text3d_getType(BPy_Text3d *self);*/
static PyObject *Text3d_getName( BPy_Text3d * self );
static PyObject *Text3d_setName( BPy_Text3d * self, PyObject * args );
-static PyObject *Text3d_setText( BPy_Text3d * self, PyObject * args );
+static PyObject *Text3d_setText( BPy_Text3d * self, PyObject * value );
static PyObject *Text3d_getText( BPy_Text3d * self );
static PyObject *Text3d_getDrawMode( BPy_Text3d * self );
static PyObject *Text3d_setDrawMode( BPy_Text3d * self, PyObject * args );
@@ -149,7 +149,7 @@ static PyMethodDef BPy_Text3d_methods[] = {
{"setName", ( PyCFunction ) Text3d_setName,
METH_VARARGS, "() - Sets Text3d Data name"},
{"setText", ( PyCFunction ) Text3d_setText,
- METH_VARARGS, "() - Sets Text3d Data"},
+ METH_O, "() - Sets Text3d Data"},
{"getText", ( PyCFunction ) Text3d_getText,
METH_NOARGS, "() - Gets Text3d Data"},
{"getDrawMode", ( PyCFunction ) Text3d_getDrawMode,
@@ -664,11 +664,11 @@ static PyObject *Text3d_setName( BPy_Text3d * self, PyObject * args )
return Curve_setName( (BPy_Curve*)self,args );
}
-static PyObject *Text3d_setText( BPy_Text3d * self, PyObject * args )
+static PyObject *Text3d_setText( BPy_Text3d * self, PyObject * value )
{
- char *text;
+ char *text = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &text ) )
+ if( !text )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected string argument" );
@@ -1173,13 +1173,13 @@ static PyObject *Text3d_removeFrame( BPy_Text3d * self, PyObject * args )
}
-PyObject *M_Text3d_LoadFont( PyObject * self, PyObject * args )
+PyObject *M_Text3d_LoadFont( PyObject * self, PyObject * value )
{
- char *fontfile= NULL;
+ char *fontfile= PyString_AsString(value);
FILE *file= NULL;
VFont *vf= NULL;
- if( !PyArg_ParseTuple( args, "s", &fontfile ) )
+ if( !fontfile )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a string" );
vf= exist_vfont(fontfile);
diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c
index 607ff6fe008..ffd2653d330 100644
--- a/source/blender/python/api2_2x/Texture.c
+++ b/source/blender/python/api2_2x/Texture.c
@@ -32,6 +32,7 @@
#include "Texture.h" /*This must come first*/
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
@@ -203,11 +204,14 @@ static const EXPP_map_pair tex_type_map[] = {
static const EXPP_map_pair tex_flag_map[] = {
/* NOTE "CheckerOdd" and "CheckerEven" are new */
- {"ColorBand", TEX_COLORBAND },
+ {"ColorBand", TEX_COLORBAND },
{"FlipBlend", TEX_FLIPBLEND},
{"NegAlpha", TEX_NEGALPHA},
{"CheckerOdd",TEX_CHECKER_ODD},
{"CheckerEven",TEX_CHECKER_EVEN},
+ {"PreviewAlpha",TEX_PRV_ALPHA},
+ {"RepeatXMirror",TEX_REPEAT_XMIR},
+ {"RepeatYMirror",TEX_REPEAT_YMIR},
{NULL, 0}
};
@@ -438,7 +442,10 @@ GETFUNC( getWeight1 );
GETFUNC( getWeight2 );
GETFUNC( getWeight3 );
GETFUNC( getWeight4 );
+#if 0
+/* not defined */
GETFUNC( getUsers );
+#endif
OLDSETFUNC( setDistMetric );
OLDSETFUNC( setDistNoise ); /* special case used for ".noisebasis = ... */
@@ -498,7 +505,7 @@ static int Texture_setNoiseBasis2( BPy_Texture *self, PyObject *args,
static PyObject *Texture_getColorband( BPy_Texture * self);
int Texture_setColorband( BPy_Texture * self, PyObject * value);
-static PyObject *Texture_evaluate( BPy_Texture *self, PyObject *args );
+static PyObject *Texture_evaluate( BPy_Texture *self, PyObject *value );
static PyObject *Texture_copy( BPy_Texture *self );
/*****************************************************************************/
@@ -542,7 +549,7 @@ static PyMethodDef BPy_Texture_methods[] = {
"(s) - Set Dist Noise"},
{"setDistMetric", ( PyCFunction ) Texture_oldsetDistMetric, METH_VARARGS,
"(s) - Set Dist Metric"},
- {"evaluate", ( PyCFunction ) Texture_evaluate, METH_VARARGS,
+ {"evaluate", ( PyCFunction ) Texture_evaluate, METH_O,
"(vector) - evaluate the texture at this position"},
{"__copy__", ( PyCFunction ) Texture_copy, METH_NOARGS,
"() - return a copy of the the texture"},
@@ -687,10 +694,6 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(getter)Texture_getType, (setter)Texture_setType,
"Texture's 'Type' mode",
NULL},
- {"users",
- (getter)Texture_getUsers, (setter)NULL,
- "Number of texture users",
- NULL},
{"weight1",
(getter)Texture_getWeight1, (setter)Texture_setWeight1,
"Weight 1 (for Voronoi textures)",
@@ -772,8 +775,8 @@ static PyGetSetDef BPy_Texture_getseters[] = {
(void *)TEX_NORMALMAP},
{"colorband",
(getter)Texture_getColorband, (setter)Texture_setColorband,
- "Use of image RGB values for normal mapping enabled ('ImageFlags')",
- (void *)TEX_NORMALMAP},
+ "The colorband for this texture",
+ NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -1163,6 +1166,9 @@ static PyObject *M_Texture_FlagsDict( void )
PyConstant_Insert(d, "NEGALPHA", PyInt_FromLong(TEX_NEGALPHA));
PyConstant_Insert(d, "CHECKER_ODD", PyInt_FromLong(TEX_CHECKER_ODD));
PyConstant_Insert(d, "CHECKER_EVEN", PyInt_FromLong(TEX_CHECKER_EVEN));
+ PyConstant_Insert(d, "PREVIEW_ALPHA", PyInt_FromLong(TEX_PRV_ALPHA));
+ PyConstant_Insert(d, "REPEAT_XMIR", PyInt_FromLong(TEX_REPEAT_XMIR));
+ PyConstant_Insert(d, "REPEAT_YMIR", PyInt_FromLong(TEX_REPEAT_YMIR));
}
return Flags;
}
@@ -1340,18 +1346,14 @@ Tex *Texture_FromPyObject( PyObject * pyobj )
static PyObject *Texture_getExtend( BPy_Texture * self )
{
- PyObject *attr = NULL;
const char *extend = NULL;
if( EXPP_map_getStrVal
( tex_extend_map, self->texture->extend, &extend ) )
- attr = PyString_FromString( extend );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "invalid internal extend mode" );
+ return PyString_FromString( extend );
- return attr;
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "invalid internal extend mode" );
}
static PyObject *Texture_getImage( BPy_Texture * self )
@@ -1367,7 +1369,6 @@ static PyObject *Texture_getImage( BPy_Texture * self )
static PyObject *Texture_oldgetSType( BPy_Texture * self )
{
- PyObject *attr = NULL;
const char *stype = NULL;
int n_stype;
@@ -1384,28 +1385,22 @@ static PyObject *Texture_oldgetSType( BPy_Texture * self )
if( EXPP_map_getStrVal( tex_stype_map[self->texture->type],
n_stype, &stype ) )
- attr = PyString_FromString( stype );
+ return PyString_FromString( stype );
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"invalid texture stype internally" );
-
- return attr;
}
static PyObject *Texture_oldgetType( BPy_Texture * self )
{
- PyObject *attr = NULL;
const char *type = NULL;
if( EXPP_map_getStrVal( tex_type_map, self->texture->type, &type ) )
- attr = PyString_FromString( type );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ return PyString_FromString( type );
+
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"invalid texture type internally" );
-
- return attr;
}
static int Texture_setAnimFrames( BPy_Texture * self, PyObject * value )
@@ -1417,7 +1412,12 @@ static int Texture_setAnimFrames( BPy_Texture * self, PyObject * value )
static int Texture_setIUserCyclic( BPy_Texture * self, PyObject * value )
{
- if( PyObject_IsTrue( value ) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->texture->iuser.cycl = 1;
else
self->texture->iuser.cycl = 0;
@@ -1535,20 +1535,15 @@ static int Texture_setFilterSize( BPy_Texture * self, PyObject * value )
static int Texture_setFlags( BPy_Texture * self, PyObject * value )
{
int param;
- int bitmask = TEX_FLIPBLEND
- | TEX_COLORBAND
- | TEX_NEGALPHA
- | TEX_CHECKER_ODD
- | TEX_CHECKER_EVEN;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check( value ) ) {
char errstr[128];
- sprintf ( errstr , "expected int bitmask of 0x%08x", bitmask );
+ sprintf ( errstr , "expected int bitmask of 0x%08x", TEX_FLAG_MASK );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
}
param = PyInt_AS_LONG ( value );
- if ( ( param & bitmask ) != param )
+ if ( ( param & TEX_FLAG_MASK ) != param )
return EXPP_ReturnIntError( PyExc_ValueError,
"invalid bit(s) set in mask" );
@@ -1568,16 +1563,24 @@ static int Texture_setImage( BPy_Texture * self, PyObject * value )
{
Image *blimg = NULL;
- if( !BPy_Image_Check (value) )
+ if ( value != Py_None && !BPy_Image_Check (value) )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected an Image" );
- blimg = Image_FromPyObject( value );
+ "expected an Image or None" );
+
if( self->texture->ima ) {
self->texture->ima->id.us--;
+ self->texture->ima = NULL;
}
+ if ( value == Py_None )
+ return 0;
+
+ blimg = Image_FromPyObject( value );
+
self->texture->ima = blimg;
+ self->texture->type = TEX_IMAGE;
+ BKE_image_signal(blimg, &self->texture->iuser, IMA_SIGNAL_RELOAD );
id_us_plus( &blimg->id );
return 0;
@@ -1613,7 +1616,7 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
| TEX_CALCALPHA
| TEX_NORMALMAP;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check( value ) ) {
char errstr[128];
sprintf ( errstr , "expected int bitmask of 0x%08x", bitmask );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -1634,7 +1637,12 @@ static int Texture_setImageFlags( BPy_Texture * self, PyObject * value,
static int Texture_setIUserFlags( BPy_Texture * self, PyObject * value,
void *flag )
{
- if( PyObject_IsTrue(value) )
+ int param = PyObject_IsTrue( value );
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if( param )
self->texture->iuser.flag |= (int)flag;
else
self->texture->iuser.flag &= ~(int)flag;
@@ -1685,7 +1693,7 @@ static int Texture_setNoiseBasis( BPy_Texture * self, PyObject * value )
{
int param;
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int (see 'Noise' constant dictionary)" );
@@ -1711,7 +1719,7 @@ static int Texture_setNoiseBasis2( BPy_Texture * self, PyObject * value,
if( (int)type == EXPP_TEX_NOISEBASIS2 ) {
int param;
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int (see 'Noise' constant dictionary)" );
@@ -1731,7 +1739,7 @@ static int Texture_setNoiseBasis2( BPy_Texture * self, PyObject * value,
*/
} else {
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int value of 1" );
@@ -1783,7 +1791,7 @@ static int Texture_setSType( BPy_Texture * self, PyObject * value )
short param;
const char *dummy = NULL;
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -1992,13 +2000,7 @@ static int Texture_setIpo( BPy_Texture * self, PyObject * value )
static PyObject *Texture_getAnimFrames( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->iuser.frames );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->iuser.frames );
}
static PyObject *Texture_getIUserCyclic( BPy_Texture *self )
@@ -2013,20 +2015,12 @@ static PyObject *Texture_getIUserCyclic( BPy_Texture *self )
/* disabled. this option was too stupid! (ton) */
static PyObject *Texture_getAnimLength( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->len );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->len );
}
static PyObject *Texture_getAnimMontage( BPy_Texture *self )
-{
- PyObject *attr;
-
- attr = Py_BuildValue( "((i,i),(i,i),(i,i),(i,i))",
+{
+ return Py_BuildValue( "((i,i),(i,i),(i,i),(i,i))",
self->texture->fradur[0][0],
self->texture->fradur[0][1],
self->texture->fradur[1][0],
@@ -2035,182 +2029,88 @@ static PyObject *Texture_getAnimMontage( BPy_Texture *self )
self->texture->fradur[2][1],
self->texture->fradur[3][0],
self->texture->fradur[3][1] );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
}
#endif
static PyObject *Texture_getAnimOffset( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->iuser.offset );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->iuser.offset );
}
static PyObject *Texture_getAnimStart( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->iuser.sfra );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->iuser.sfra );
}
static PyObject *Texture_getBrightness( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble ( self->texture->bright );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble ( self->texture->bright );
}
static PyObject *Texture_getContrast( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->contrast );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->contrast );
}
static PyObject *Texture_getCrop( BPy_Texture *self )
{
- PyObject *attr;
-
- attr = Py_BuildValue( "(f,f,f,f)",
+ return Py_BuildValue( "(f,f,f,f)",
self->texture->cropxmin,
self->texture->cropymin,
self->texture->cropxmax,
self->texture->cropymax );
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
}
static PyObject *Texture_getDistAmnt( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->dist_amount );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->dist_amount );
}
static PyObject *Texture_getDistMetric( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->vn_distm );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->vn_distm );
}
static PyObject *Texture_getExp( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->vn_mexp );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->vn_mexp );
}
static PyObject *Texture_getIntExtend( BPy_Texture * self )
{
- PyObject *attr = PyInt_FromLong( self->texture->extend );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->extend );
}
static PyObject *Texture_getFieldsPerImage( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->iuser.fie_ima );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->iuser.fie_ima );
}
static PyObject *Texture_getFilterSize( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->filtersize );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->filtersize );
}
static PyObject *Texture_getFlags( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->flag );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->flag );
}
static PyObject *Texture_getHFracDim( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( (long)self->texture->mg_H );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( (long)self->texture->mg_H );
}
static PyObject *Texture_getImageFlags( BPy_Texture *self, void *type )
{
- PyObject *attr;
-
- /*
- * type == 0 means attribute "imageFlags"
+ /* type == 0 means attribute "imageFlags"
* other types means attribute "mipmap", "calcAlpha", etc
*/
if( (int)type )
- attr = EXPP_getBitfield( &self->texture->imaflag, (int)type, 'h' );
+ return EXPP_getBitfield( &self->texture->imaflag, (int)type, 'h' );
else
- attr = PyInt_FromLong( self->texture->imaflag );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->imaflag );
}
static PyObject *Texture_getIUserFlags( BPy_Texture *self, void *flag )
@@ -2223,231 +2123,108 @@ static PyObject *Texture_getIUserFlags( BPy_Texture *self, void *flag )
static PyObject *Texture_getIScale( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->ns_outscale );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->ns_outscale );
}
static PyObject *Texture_getLacunarity( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->mg_lacunarity );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->mg_lacunarity );
}
static PyObject *Texture_getNoiseBasis( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->noisebasis );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->noisebasis );
}
static PyObject *Texture_getNoiseBasis2( BPy_Texture *self, void *type )
{
- PyObject *attr;
-
- /*
- * type == EXPP_TEX_NOISEBASIS2 means attribute "noiseBasis2"
+ /* type == EXPP_TEX_NOISEBASIS2 means attribute "noiseBasis2"
* other types means attribute "sine", "saw", or "tri" attribute
*/
if( (int)type == EXPP_TEX_NOISEBASIS2 )
- attr = PyInt_FromLong( self->texture->noisebasis2 );
+ return PyInt_FromLong( self->texture->noisebasis2 );
else
- attr = PyInt_FromLong( ( self->texture->noisebasis2 == (int)type ) ? 1 : 0 );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( ( self->texture->noisebasis2 == (int)type ) ? 1 : 0 );
}
static PyObject *Texture_getNoiseDepth( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->noisedepth );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->noisedepth );
}
static PyObject *Texture_getNoiseSize( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->noisesize );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->noisesize );
}
static PyObject *Texture_getNoiseType( BPy_Texture *self )
{
- PyObject *attr;
-
if ( self->texture->noisetype == TEX_NOISESOFT )
- attr = PyString_FromString( "soft" );
+ return PyString_FromString( "soft" );
else
- attr = PyString_FromString( "hard" );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyString_FromString( "hard" );
}
static PyObject *Texture_getOcts( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->mg_octaves );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->mg_octaves );
}
static PyObject *Texture_getRepeat( BPy_Texture *self )
{
- PyObject *attr;
-
- attr = Py_BuildValue( "(i,i)", self->texture->xrepeat,
+ return Py_BuildValue( "(i,i)", self->texture->xrepeat,
self->texture->yrepeat );
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
}
static PyObject *Texture_getRGBCol( BPy_Texture *self )
{
- PyObject *attr;
-
- attr = Py_BuildValue( "(f,f,f)", self->texture->rfac,
+ return Py_BuildValue( "(f,f,f)", self->texture->rfac,
self->texture->gfac, self->texture->bfac );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
}
static PyObject *Texture_getSType( BPy_Texture *self )
{
- PyObject *attr;
-
if( self->texture->type == TEX_VORONOI )
- attr = PyInt_FromLong( self->texture->vn_coltype );
+ return PyInt_FromLong( self->texture->vn_coltype );
#if 0
- else if( self->texture->type == TEX_MUSGRAVE )
- attr = PyInt_FromLong( self->texture->noisebasis );
+ if( self->texture->type == TEX_MUSGRAVE )
+ return PyInt_FromLong( self->texture->noisebasis );
#endif
- else if( self->texture->type == TEX_ENVMAP )
- attr = PyInt_FromLong( self->texture->env->stype );
- else
- attr = PyInt_FromLong( self->texture->stype );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
+ if( self->texture->type == TEX_ENVMAP )
+ return PyInt_FromLong( self->texture->env->stype );
- return attr;
+ return PyInt_FromLong( self->texture->stype );
}
static PyObject *Texture_getTurbulence( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->turbul );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->turbul );
}
static PyObject *Texture_getType( BPy_Texture *self )
{
- PyObject *attr = PyInt_FromLong( self->texture->type );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
-}
-
-static PyObject *Texture_getUsers( BPy_Texture *self )
-{
- PyObject *attr = PyInt_FromLong( self->texture->id.us );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyInt_FromLong( self->texture->type );
}
static PyObject *Texture_getWeight1( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->vn_w1 );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->vn_w1 );
}
static PyObject *Texture_getWeight2( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->vn_w2 );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->vn_w2 );
}
static PyObject *Texture_getWeight3( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->vn_w3 );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->vn_w3 );
}
static PyObject *Texture_getWeight4( BPy_Texture *self )
{
- PyObject *attr = PyFloat_FromDouble( self->texture->vn_w4 );
-
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get attribute" );
-
- return attr;
+ return PyFloat_FromDouble( self->texture->vn_w4 );
}
/* #####DEPRECATED###### */
@@ -2704,20 +2481,34 @@ int Texture_setColorband( BPy_Texture * self, PyObject * value)
return EXPP_Colorband_fromPyList( &self->texture->coba, value );
}
-static PyObject *Texture_evaluate( BPy_Texture * self, PyObject * args )
+static PyObject *Texture_evaluate( BPy_Texture * self, PyObject * value )
{
- VectorObject *vec_in = NULL;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float vec[4];
/* int rgbnor; dont use now */
- if(!PyArg_ParseTuple(args, "O!", &vector_Type, &vec_in) || vec_in->size < 3)
- return EXPP_ReturnPyObjError(PyExc_TypeError,
- "expects a 3D vector object");
-
- /* rgbnor = .. we don't need this now */
- multitex_ext(self->texture, vec_in->vec, NULL, NULL, 1, &texres);
-
+ if (VectorObject_Check(value)) {
+ if(((VectorObject *)value)->size < 3)
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "expects a 3D vector object or a tuple of 3 numbers");
+
+ /* rgbnor = .. we don't need this now */
+ multitex_ext(self->texture, ((VectorObject *)value)->vec, NULL, NULL, 1, &texres);
+ } else {
+ float vec_in[3];
+ if (!PyTuple_Check(value) || PyTuple_Size(value) < 3)
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "expects a 3D vector object or a tuple of 3 numbers");
+
+ vec_in[0] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 0));
+ vec_in[1] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 1));
+ vec_in[2] = PyFloat_AsDouble(PyTuple_GET_ITEM(value, 2));
+ if (PyErr_Occurred())
+ return EXPP_ReturnPyObjError(PyExc_TypeError,
+ "expects a 3D vector object or a tuple of 3 numbers");
+
+ multitex_ext(self->texture, vec_in, NULL, NULL, 1, &texres);
+ }
vec[0] = texres.tr;
vec[1] = texres.tg;
vec[2] = texres.tb;
diff --git a/source/blender/python/api2_2x/Types.c b/source/blender/python/api2_2x/Types.c
index bff227e440a..8b51c590a5b 100644
--- a/source/blender/python/api2_2x/Types.c
+++ b/source/blender/python/api2_2x/Types.c
@@ -128,7 +128,7 @@ void types_InitAll( void )
euler_Type.ob_type = &PyType_Type;
matrix_Type.ob_type = &PyType_Type;
quaternion_Type.ob_type = &PyType_Type;
- rgbTuple_Type.ob_type = &PyType_Type;
+ PyType_Ready( &rgbTuple_Type );
vector_Type.ob_type = &PyType_Type;
property_Type.ob_type = &PyType_Type;
point_Type.ob_type = &PyType_Type;
diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c
index 9c53a005d6f..5cfe796add8 100644
--- a/source/blender/python/api2_2x/Window.c
+++ b/source/blender/python/api2_2x/Window.c
@@ -38,14 +38,15 @@
#include "BKE_main.h"
#include "BKE_object.h" /* for during_script() and during_scriptlink() */
#include "BKE_scene.h" /* scene_find_camera() */
-#include "BPI_script.h"
#include "BIF_mywindow.h"
+#include "BIF_imasel.h"
#include "BSE_headerbuttons.h"
#include "BSE_filesel.h"
#include "BIF_editmesh.h" /* for undo_push_mesh() */
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_drawtext.h"
+#include "BIF_poseobject.h"
#include "DNA_view3d_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@@ -59,6 +60,19 @@
#include "gen_utils.h"
#include "Armature.h"
+/* Pivot Types
+-0 for Bounding Box Center; \n\
+-1 for 3D Cursor\n\
+-2 for Individual Centers\n\
+-3 for Median Point\n\
+-4 for Active Object"; */
+
+#define PIVOT_BOUNDBOX 0
+#define PIVOT_CURSOR 1
+#define PIVOT_INDIVIDUAL 2
+#define PIVOT_MEDIAN 3
+#define PIVOT_ACTIVE 4
+
/* See Draw.c */
extern int EXPP_disable_force_draw;
extern void setcameratoview3d(void);
@@ -85,12 +99,14 @@ static PyObject *M_Window_GetPerspMatrix( PyObject * self );
static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args );
static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args );
static PyObject *M_Window_EditMode( PyObject * self, PyObject * args );
+static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args );
static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args );
static PyObject *M_Window_CameraView( PyObject * self, PyObject * args );
static PyObject *M_Window_QTest( PyObject * self );
static PyObject *M_Window_QRead( PyObject * self );
static PyObject *M_Window_QAdd( PyObject * self, PyObject * args );
static PyObject *M_Window_QHandle( PyObject * self, PyObject * args );
+static PyObject *M_Window_TestBreak( PyObject * self );
static PyObject *M_Window_GetMouseCoords( PyObject * self );
static PyObject *M_Window_SetMouseCoords( PyObject * self, PyObject * args );
static PyObject *M_Window_GetMouseButtons( PyObject * self );
@@ -100,9 +116,12 @@ static PyObject *M_Window_GetAreaSize( PyObject * self );
static PyObject *M_Window_GetAreaID( PyObject * self );
static PyObject *M_Window_GetScreenSize( PyObject * self );
static PyObject *M_Window_GetScreens( PyObject * self );
-static PyObject *M_Window_SetScreen( PyObject * self, PyObject * args );
+static PyObject *M_Window_SetScreen( PyObject * self, PyObject * value );
static PyObject *M_Window_GetScreenInfo( PyObject * self, PyObject * args,
PyObject * kwords );
+static PyObject *M_Window_GetPivot( PyObject * self );
+static PyObject *M_Window_SetPivot( PyObject * self, PyObject * value );
+
PyObject *Window_Init( void );
@@ -178,11 +197,15 @@ static char M_Window_EditMode_doc[] =
Returns the current status. This function is mostly useful to leave\n\
edit mode before applying changes to a mesh (otherwise the changes will\n\
be lost) and then returning to it upon leaving.";
+static char M_Window_PoseMode_doc[] =
+ "() - Get the current status -- 0: not in pose mode; 1: in edit mode";
static char M_Window_ViewLayers_doc[] =
- "(layers = []) - Get/set active layers in all 3d View windows.\n\
+ "(layers = [], winid = None) - Get/set active layers in all 3d View windows.\n\
() - Make no changes, only return currently visible layers.\n\
(layers = []) - a list of integers, each in the range [1, 20].\n\
+(layers = [], winid = int) - layers as above, winid is an optional.\n\
+arg that makes the function only set layers for that view.\n\
This function returns the currently visible layers as a list of ints.";
static char M_Window_GetViewQuat_doc[] =
@@ -228,6 +251,9 @@ static char M_Window_QHandle_doc[] =
(win) - int: the window id, see Blender.Window.GetScreenInfo().\n\n\
See Blender.Window.QAdd() for how to send events to a particular window.";
+static char M_Window_TestBreak_doc[] =
+ "() - Returns true if the user has pressed escape.";
+
static char M_Window_GetMouseCoords_doc[] =
"() - Get mouse pointer's current screen coordinates.";
@@ -279,6 +305,18 @@ Each dictionary has keys:\n\
'win': window type, see Blender.Window.Types dict;\n\
'id': area's id.";
+static char M_Window_SetPivot_doc[] =
+ "(Pivot) - Set Pivot Mode for 3D Viewport:\n\
+Options are: \n\
+-PivotTypes.BOUNDBOX for Bounding Box Center; \n\
+-PivotTypes.CURSOR for 3D Cursor\n\
+-PivotTypes.INDIVIDUAL for Individual Centers\n\
+-PivotTypes.MEDIAN for Median Point\n\
+-PivotTypes.ACTIVE for Active Object";
+
+static char M_Window_GetPivot_doc[] =
+ "Return the pivot for the active 3d window";
+
/*****************************************************************************/
/* Python method structure definition for Blender.Window module: */
/*****************************************************************************/
@@ -322,6 +360,8 @@ struct PyMethodDef M_Window_methods[] = {
M_Window_GetPerspMatrix_doc},
{"EditMode", ( PyCFunction ) M_Window_EditMode, METH_VARARGS,
M_Window_EditMode_doc},
+ {"PoseMode", ( PyCFunction ) M_Window_PoseMode, METH_VARARGS,
+ M_Window_PoseMode_doc},
{"ViewLayers", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS,
M_Window_ViewLayers_doc},
/* typo, deprecate someday: */
@@ -337,6 +377,8 @@ struct PyMethodDef M_Window_methods[] = {
M_Window_QAdd_doc},
{"QHandle", ( PyCFunction ) M_Window_QHandle, METH_VARARGS,
M_Window_QHandle_doc},
+ {"TestBreak", ( PyCFunction ) M_Window_TestBreak, METH_NOARGS,
+ M_Window_TestBreak_doc},
{"GetMouseCoords", ( PyCFunction ) M_Window_GetMouseCoords,
METH_NOARGS,
M_Window_GetMouseCoords_doc},
@@ -360,10 +402,14 @@ struct PyMethodDef M_Window_methods[] = {
M_Window_GetScreenSize_doc},
{"GetScreens", ( PyCFunction ) M_Window_GetScreens, METH_NOARGS,
M_Window_GetScreens_doc},
- {"SetScreen", ( PyCFunction ) M_Window_SetScreen, METH_VARARGS,
+ {"SetScreen", ( PyCFunction ) M_Window_SetScreen, METH_O,
M_Window_SetScreen_doc},
{"GetScreenInfo", ( PyCFunction ) M_Window_GetScreenInfo,
METH_VARARGS | METH_KEYWORDS, M_Window_GetScreenInfo_doc},
+ {"GetPivot", ( PyCFunction ) M_Window_GetPivot, METH_NOARGS,
+ M_Window_GetPivot_doc},
+ {"SetPivot", ( PyCFunction ) M_Window_SetPivot, METH_O,
+ M_Window_SetPivot_doc},
{NULL, NULL, 0, NULL}
};
@@ -423,7 +469,10 @@ PyObject *M_Window_Redraw( PyObject * self, PyObject * args )
/*****************************************************************************/
static PyObject *M_Window_RedrawAll( PyObject * self, PyObject * args )
{
- return M_Window_Redraw( self, Py_BuildValue( "(i)", -1 ) );
+ PyObject *arg = Py_BuildValue( "(i)", -1 );
+ PyObject *ret = M_Window_Redraw( self, arg );
+ Py_DECREF(arg);
+ return ret;
}
/*****************************************************************************/
@@ -468,6 +517,8 @@ static void getSelectedFile( char *name )
pycallback = script->py_browsercallback;
if (pycallback) {
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
result = PyObject_CallFunction( pycallback, "s", name );
if (!result) {
@@ -476,11 +527,14 @@ static void getSelectedFile( char *name )
}
else Py_DECREF(result);
- if (script->py_browsercallback == pycallback)
- script->py_browsercallback = NULL;
+ if (script->py_browsercallback == pycallback) {
+ SCRIPT_SET_NULL(script);
+ }
/* else another call to selector was made inside pycallback */
Py_DECREF(pycallback);
+
+ PyGILState_Release(gilstate);
}
return;
@@ -546,8 +600,12 @@ static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args )
}
script->py_browsercallback = pycallback;
+ /* if were not running a script GUI here alredy, then dont make this script persistant */
+ if ((script->flags & SCRIPT_GUI)==0) {
+ script->scriptname[0] = '\0';
+ script->scriptarg[0] = '\0';
+ }
activate_fileselect( FILE_BLENDER, title, filename, getSelectedFile );
-
Py_RETURN_NONE;
}
@@ -717,20 +775,13 @@ static PyObject *M_Window_WaitCursor( PyObject * self, PyObject * args )
static PyObject *M_Window_GetViewVector( PyObject * self )
{
float *vec = NULL;
- PyObject *pylist;
if( !G.vd )
Py_RETURN_NONE;
vec = G.vd->viewinv[2];
- pylist = Py_BuildValue( "[fff]", vec[0], vec[1], vec[2] );
-
- if( !pylist )
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "GetViewVector: couldn't create pylist" ) );
-
- return pylist;
+ return Py_BuildValue( "[fff]", vec[0], vec[1], vec[2] );
}
/*****************************************************************************/
@@ -781,20 +832,13 @@ static PyObject *M_Window_SetActiveLayer( PyObject * self, PyObject * args )
static PyObject *M_Window_GetViewQuat( PyObject * self )
{
float *vec = NULL;
- PyObject *pylist;
if( !G.vd )
Py_RETURN_NONE;
vec = G.vd->viewquat;
- pylist = Py_BuildValue( "[ffff]", vec[0], vec[1], vec[2], vec[3] );
-
- if( !pylist )
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "GetViewQuat: couldn't create pylist" ) );
-
- return pylist;
+ return Py_BuildValue( "[ffff]", vec[0], vec[1], vec[2], vec[3] );
}
static PyObject *M_Window_SetViewQuat( PyObject * self, PyObject * args )
@@ -826,21 +870,9 @@ static PyObject *M_Window_SetViewQuat( PyObject * self, PyObject * args )
static PyObject *M_Window_GetViewOffset( PyObject * self )
{
- float *vec = NULL;
- PyObject *pylist;
-
if( !G.vd )
Py_RETURN_NONE;
-
- vec = G.vd->ofs;
-
- pylist = Py_BuildValue( "[fff]", vec[0], vec[1], vec[2] );
-
- if( !pylist )
- return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
- "GetViewQuat: couldn't create pylist" ) );
-
- return pylist;
+ return Py_BuildValue( "[fff]", G.vd->ofs[0], G.vd->ofs[1], G.vd->ofs[2] );
}
static PyObject *M_Window_SetViewOffset( PyObject * self, PyObject * args )
@@ -876,20 +908,10 @@ static PyObject *M_Window_SetViewOffset( PyObject * self, PyObject * args )
/*****************************************************************************/
static PyObject *M_Window_GetViewMatrix( PyObject * self )
{
- PyObject *viewmat;
-
if( !G.vd )
Py_RETURN_NONE;
- viewmat =
- ( PyObject * ) newMatrixObject( ( float * ) G.vd->viewmat, 4,
- 4, Py_WRAP );
-
- if( !viewmat )
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "GetViewMatrix: couldn't create matrix pyobject" );
-
- return viewmat;
+ return newMatrixObject( ( float * ) G.vd->viewmat, 4, 4, Py_WRAP );
}
/*****************************************************************************/
@@ -898,20 +920,10 @@ static PyObject *M_Window_GetViewMatrix( PyObject * self )
/*****************************************************************************/
static PyObject *M_Window_GetPerspMatrix( PyObject * self )
{
- PyObject *perspmat;
-
if( !G.vd )
Py_RETURN_NONE;
- perspmat =
- ( PyObject * ) newMatrixObject( ( float * ) G.vd->persmat, 4,
- 4, Py_WRAP );
-
- if( !perspmat )
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "GetPerspMatrix: couldn't create matrix pyobject" );
-
- return perspmat;
+ return newMatrixObject( ( float * ) G.vd->persmat, 4, 4, Py_WRAP );
}
@@ -989,23 +1001,54 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
return Py_BuildValue( "h", G.obedit ? 1 : 0 );
}
+static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args )
+{
+ short status = -1;
+ short is_posemode = 0;
+ Base *base;
+
+ if( !PyArg_ParseTuple( args, "|h", &status ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected optional int (bool) as argument" );
+
+ if( status >= 0 ) {
+ if( status ) {
+ enter_posemode();
+ } else if( G.obedit ) {
+ exit_posemode();
+ }
+ }
+
+ base= BASACT;
+ if (base && base->object->flag & OB_POSEMODE) {
+ is_posemode = 1;
+ }
+
+ return Py_BuildValue( "h", is_posemode );
+}
+
static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args )
{
PyObject *item = NULL;
PyObject *list = NULL, *resl = NULL;
- int val, i, bit = 0, layer = 0;
+ int val, i, bit = 0, layer = 0, len_list;
+ short winid = -1;
if( !G.scene ) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"can't get pointer to global scene" );
}
- if( !PyArg_ParseTuple( args, "|O!", &PyList_Type, &list ) )
- return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected nothing or a list of ints as argument" );
-
+ /* Pase Args, Nothing, One list, Or a list and an int */
+ if (PyTuple_GET_SIZE(args)!=0) {
+ if( !PyArg_ParseTuple ( args, "O!|h", &PyList_Type, &list, &winid) ) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "nothing or a list and optionaly a window ID argument" );
+ }
+ }
+
if( list ) {
- int len_list = PyList_Size(list);
+ len_list = PyList_Size(list);
if (len_list == 0)
return EXPP_ReturnPyObjError( PyExc_AttributeError,
@@ -1026,17 +1069,58 @@ static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args )
layer |= 1 << ( val - 1 );
}
- G.scene->lay = layer;
- if (G.vd) {
- G.vd->lay = layer;
-
- while( bit < 20 ) {
- val = 1 << bit;
- if( layer & val ) {
- G.vd->layact = val;
- break;
+
+ if (winid==-1) {
+ /* set scene and viewport */
+ G.scene->lay = layer;
+ if (G.vd) {
+ G.vd->lay = layer;
+
+ while( bit < 20 ) {
+ val = 1 << bit;
+ if( layer & val ) {
+ G.vd->layact = val;
+ break;
+ }
+ bit++;
}
- bit++;
+ }
+ } else {
+ /* only set the windows layer */
+ ScrArea *sa;
+ SpaceLink *sl;
+ View3D *vd;
+
+ if (G.curscreen) { /* can never be too careful */
+ for (sa=G.curscreen->areabase.first; sa; sa= sa->next) {
+ if (winid == sa->win) {
+
+ for (sl= sa->spacedata.first; sl; sl= sl->next)
+ if(sl->spacetype==SPACE_VIEW3D)
+ break;
+
+ if (!sl)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "The window matching the winid has no 3d viewport" );
+
+ vd= (View3D *) sl;
+ vd->lay = layer;
+
+ for(bit= 0; bit < 20; bit++) {
+ val = 1 << bit;
+ if( layer & val ) {
+ vd->layact = val;
+ break;
+ }
+ }
+
+ winid = -1; /* so we know its done */
+ break;
+ }
+ }
+ if (winid!=-1)
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "The winid argument did not match any window" );
}
}
}
@@ -1140,22 +1224,24 @@ static PyObject *M_Window_QAdd( PyObject * self, PyObject * args )
static PyObject *M_Window_QHandle( PyObject * self, PyObject * args )
{
short win;
- ScrArea *sa = G.curscreen->areabase.first;
+ ScrArea *sa;
ScrArea *oldsa = NULL;
if (G.background)
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
"QHandle is not available in background mode");
+ if (!G.curscreen)
+ return EXPP_ReturnPyObjError(PyExc_RuntimeError,
+ "No screens available");
+
if( !PyArg_ParseTuple( args, "h", &win ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an int as argument" );
-
- while( sa ) {
+
+ for (sa= G.curscreen->areabase.first; sa; sa= sa->next)
if( sa->win == win )
break;
- sa = sa->next;
- }
if( sa ) {
BWinEvent evt;
@@ -1187,6 +1273,15 @@ static PyObject *M_Window_QHandle( PyObject * self, PyObject * args )
Py_RETURN_NONE;
}
+static PyObject *M_Window_TestBreak( PyObject * self )
+{
+ if (blender_test_break()) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+}
+
static PyObject *M_Window_GetMouseCoords( PyObject * self )
{
short mval[2];
@@ -1283,12 +1378,12 @@ static PyObject *M_Window_GetScreenSize( PyObject * self )
}
-static PyObject *M_Window_SetScreen( PyObject * self, PyObject * args )
+static PyObject *M_Window_SetScreen( PyObject * self, PyObject * value )
{
bScreen *scr = G.main->screen.first;
- char *name = NULL;
+ char *name = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string as argument" );
@@ -1413,12 +1508,37 @@ static PyObject *M_Window_GetScreenInfo( PyObject * self, PyObject * args,
return list;
}
+static PyObject *M_Window_GetPivot( PyObject * self )
+{
+ if (G.vd) {
+ return PyInt_FromLong( G.vd->around );
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *M_Window_SetPivot( PyObject * self, PyObject * value)
+
+{
+ short pivot;
+ if (G.vd) {
+ pivot = (short)PyInt_AsLong( value );
+
+ if ( pivot > 4 || pivot < 0 )
+ return EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "Expected a constant from Window.PivotTypes" );
+
+ G.vd->around = pivot;
+ }
+ Py_RETURN_NONE;
+}
+
+
/*****************************************************************************/
/* Function: Window_Init */
/*****************************************************************************/
PyObject *Window_Init( void )
{
- PyObject *submodule, *Types, *Qual, *MButs, *dict;
+ PyObject *submodule, *Types, *Qual, *MButs, *PivotTypes, *dict;
submodule =
Py_InitModule3( "Blender.Window", M_Window_methods,
@@ -1431,6 +1551,7 @@ PyObject *Window_Init( void )
Types = PyConstant_New( );
Qual = PyConstant_New( );
MButs = PyConstant_New( );
+ PivotTypes = PyConstant_New( );
if( Types ) {
BPy_constant *d = ( BPy_constant * ) Types;
@@ -1481,5 +1602,16 @@ PyObject *Window_Init( void )
PyModule_AddObject( submodule, "MButs", MButs );
}
+ if( PivotTypes ) {
+ BPy_constant *d = ( BPy_constant * ) PivotTypes;
+
+ PyConstant_Insert(d, "BOUNDBOX", PyInt_FromLong( PIVOT_BOUNDBOX ) );
+ PyConstant_Insert(d, "CURSOR", PyInt_FromLong( PIVOT_CURSOR ) );
+ PyConstant_Insert(d, "MEDIAN", PyInt_FromLong( PIVOT_MEDIAN ) );
+ PyConstant_Insert(d, "ACTIVE", PyInt_FromLong( PIVOT_ACTIVE ) );
+ PyConstant_Insert(d, "INDIVIDUAL", PyInt_FromLong( PIVOT_INDIVIDUAL ) );
+
+ PyModule_AddObject( submodule, "PivotTypes", PivotTypes );
+ }
return submodule;
}
diff --git a/source/blender/python/api2_2x/World.c b/source/blender/python/api2_2x/World.c
index ec73caa962b..7804a443639 100644
--- a/source/blender/python/api2_2x/World.c
+++ b/source/blender/python/api2_2x/World.c
@@ -98,7 +98,7 @@ static int World_setStar( BPy_World * self, PyObject * args );
static PyObject *World_getMist( BPy_World * self );
static PyObject *World_oldsetMist( BPy_World * self, PyObject * args );
static int World_setMist( BPy_World * self, PyObject * args );
-static PyObject *World_getScriptLinks( BPy_World * self, PyObject * args );
+static PyObject *World_getScriptLinks( BPy_World * self, PyObject * value );
static PyObject *World_addScriptLink( BPy_World * self, PyObject * args );
static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args );
static PyObject *World_setCurrent( BPy_World * self );
@@ -209,7 +209,7 @@ static PyMethodDef BPy_World_methods[] = {
"() - Return World Data mist"},
{"setMist", ( PyCFunction ) World_oldsetMist, METH_VARARGS,
"() - Return World Data mist"},
- {"getScriptLinks", ( PyCFunction ) World_getScriptLinks, METH_VARARGS,
+ {"getScriptLinks", ( PyCFunction ) World_getScriptLinks, METH_O,
"(eventname) - Get a list of this world's scriptlinks (Text names) "
"of the given type\n"
"(eventname) - string: FrameChanged, Redraw or Render."},
@@ -561,13 +561,7 @@ static PyObject *World_clearIpo( BPy_World * self )
static PyObject *World_getSkytype( BPy_World * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->world->skytype );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get World.skytype attribute" ) );
+ return PyInt_FromLong( ( long ) self->world->skytype );
}
@@ -579,7 +573,7 @@ static PyObject *World_getSkytype( BPy_World * self )
static int World_setSkytype( BPy_World * self, PyObject * value )
{
- if( !PyInt_CheckExact(value) )
+ if( !PyInt_Check(value) )
return ( EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" ) );
self->world->skytype = (short)PyInt_AsLong(value);
@@ -600,13 +594,7 @@ static PyObject *World_oldsetSkytype( BPy_World * self, PyObject * args )
static PyObject *World_getMode( BPy_World * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->world->mode );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get World.mode attribute" ) );
+ return PyInt_FromLong( ( long ) self->world->mode );
}
@@ -618,7 +606,7 @@ static PyObject *World_getMode( BPy_World * self )
static int World_setMode( BPy_World * self, PyObject * value )
{
- if( !PyInt_CheckExact(value) )
+ if( !PyInt_Check(value) )
return ( EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" ) );
self->world->mode = (short)PyInt_AsLong(value);
@@ -640,13 +628,7 @@ static PyObject *World_oldsetMode( BPy_World * self, PyObject * args )
static PyObject *World_getMistype( BPy_World * self )
{
- PyObject *attr = PyInt_FromLong( ( long ) self->world->mistype );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get World.mistype attribute" ) );
+ return PyInt_FromLong( ( long ) self->world->mistype );
}
@@ -658,7 +640,7 @@ static PyObject *World_getMistype( BPy_World * self )
static int World_setMistype( BPy_World * self, PyObject * value )
{
- if( !PyInt_CheckExact(value) )
+ if( !PyInt_Check(value) )
return ( EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" ) );
self->world->mistype = (short)PyInt_AsLong(value);
@@ -874,7 +856,7 @@ static PyObject *World_clearScriptLinks( BPy_World * self, PyObject * args )
}
/* world.getScriptLinks */
-static PyObject *World_getScriptLinks( BPy_World * self, PyObject * args )
+static PyObject *World_getScriptLinks( BPy_World * self, PyObject * value )
{
World *world = self->world;
ScriptLink *slink = NULL;
@@ -882,7 +864,7 @@ static PyObject *World_getScriptLinks( BPy_World * self, PyObject * args )
slink = &( world )->scriptlink;
- ret = EXPP_getScriptLinks( slink, args, 0 );
+ ret = EXPP_getScriptLinks( slink, value, 0 );
if( ret )
return ret;
@@ -1009,37 +991,37 @@ static PyObject *World_insertIpoKey( BPy_World * self, PyObject * args )
map = texchannel_to_adrcode(self->world->texact);
if(key == IPOKEY_ZENITH) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_R);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_G);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_B);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_R, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_G, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_ZEN_B, 0);
}
if(key == IPOKEY_HORIZON) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_R);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_G);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_B);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_R, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_G, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_HOR_B, 0);
}
if(key == IPOKEY_MIST) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISI);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTDI);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTSTA);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTHI);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISI, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTDI, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTSTA, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_MISTHI, 0);
}
if(key == IPOKEY_STARS) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_R);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_G);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_B);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STARDIST);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STARSIZE);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_R, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_G, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STAR_B, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STARDIST, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, WO_STARSIZE, 0);
}
if(key == IPOKEY_OFFSET) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_X);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_Y);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_Z);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_OFS_Z, 0);
}
if(key == IPOKEY_SIZE) {
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_X);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_Y);
- insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey((ID *)self->world, ID_WO, NULL, NULL, map+MAP_SIZE_Z, 0);
}
allspace(REMAKEIPO, 0);
diff --git a/source/blender/python/api2_2x/bpy_config.c b/source/blender/python/api2_2x/bpy_config.c
index 5942ee56256..a061f31d8a0 100644
--- a/source/blender/python/api2_2x/bpy_config.c
+++ b/source/blender/python/api2_2x/bpy_config.c
@@ -89,10 +89,8 @@ static struct PyMethodDef BPy_Config_methods[] = {
*/
static PyObject *getStrAttr( BPy_Config *self, void *type )
{
- PyObject *attr = NULL;
char *param = NULL;
-
switch( (int)type ) {
case EXPP_CONF_ATTR_PATH_YF_EXPORT:
param = U.yfexportdir;
@@ -127,13 +125,7 @@ static PyObject *getStrAttr( BPy_Config *self, void *type )
"undefined type in getStrAttr" );
}
- attr = PyString_FromString( param );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "PyString_FromString() failed!" );
+ return PyString_FromString( param );
}
/*
@@ -195,7 +187,6 @@ static int setStrAttr( BPy_Config *self, PyObject *value, void *type )
static PyObject *getIntAttr( BPy_Config *self, void *type )
{
- PyObject *attr = NULL;
int param;
switch( (int)type ) {
@@ -220,13 +211,7 @@ static PyObject *getIntAttr( BPy_Config *self, void *type )
"undefined type in getIntAttr" );
}
- attr = PyInt_FromLong( param );
-
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "PyInt_FromLong() failed!" );
+ return PyInt_FromLong( param );
}
/*
diff --git a/source/blender/python/api2_2x/bpy_data.c b/source/blender/python/api2_2x/bpy_data.c
index d2cd650a814..428f8cc6d9a 100644
--- a/source/blender/python/api2_2x/bpy_data.c
+++ b/source/blender/python/api2_2x/bpy_data.c
@@ -352,12 +352,12 @@ static int LibBlockSeq_setActive(BPy_LibBlockSeq *self, PyObject *value)
static int LibBlockSeq_setTag(BPy_LibBlockSeq *self, PyObject *value)
{
- int param = PyObject_IsTrue( value );
ID *id;
+ int param = PyObject_IsTrue( value );
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected int argument in range [0,1]" );
+ "expected True/False or 0/1" );
id = (ID *)wich_libbase(G.main, self->type)->first;
@@ -394,7 +394,7 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
{
ID *id = NULL;
char *name=NULL, *filename=NULL, *data_type=NULL;
- int img_width=256, img_height=256;
+ int img_width=256, img_height=256, img_depth=32;
float color[] = {0, 0, 0, 1};
short data_code = 0;
int user_count = 0;
@@ -407,7 +407,7 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
static char *kwlist[] = {"name", "filename", NULL};
if(PyArg_ParseTupleAndKeywords(args, kwd, "|ss", kwlist, &name, &filename) && filename ) {
- PyObject *ret;
+ PyObject *ret= NULL;
if (strlen(filename) > FILE_MAXDIR + FILE_MAXFILE - 1)
return ( EXPP_ReturnPyObjError( PyExc_IOError,
@@ -456,8 +456,8 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
/* New Data */
if (self->type == ID_IM) {
- /* Image, accepts width and height*/
- if( !PyArg_ParseTuple( args, "|sii", &name, &img_width, &img_height ) )
+ /* Image, accepts width and height, depth */
+ if( !PyArg_ParseTuple( args, "|siii", &name, &img_width, &img_height, &img_depth ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"one string and two ints expected as arguments" );
CLAMP(img_width, 4, 5000);
@@ -538,7 +538,7 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
break;
case ID_IM:
{
- id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, color);
+ id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", img_depth==128 ? 1:0, 0, color);
if( !id )
return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyObject Image_Type" ) );
@@ -562,14 +562,14 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
break;
case ID_VF:
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "Cannot create new fonts, use the load() function to load from a file" );
+ "Cannot create new fonts, use the new(name, filename) function to load from a file" );
case ID_TXT:
id = (ID *)add_empty_text( name?name:"Text" );
user_count = 1;
break;
case ID_SO:
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "Cannot create new sounds, use the load() function to load from a file" );
+ "Cannot create new sounds, use the new(name, filename) function to load from a file" );
case ID_GR:
id = (ID *)add_group( name?name:"Group" );
user_count = 1;
@@ -593,21 +593,15 @@ PyObject *LibBlockSeq_new(BPy_LibBlockSeq *self, PyObject * args, PyObject *kwd)
}
-PyObject *LibBlockSeq_unlink(BPy_LibBlockSeq *self, PyObject * args)
+PyObject *LibBlockSeq_unlink(BPy_LibBlockSeq *self, PyObject * value)
{
- PyObject *pyobj;
-
switch (self->type) {
case ID_SCE:
- if( !PyArg_ParseTuple( args, "O!", &Scene_Type, &pyobj ) ) {
+ if( !BPy_Scene_Check(value) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Scene object" );
} else {
- BPy_Scene *bpydata;
- Scene *data;
-
- bpydata = (BPy_Scene *)pyobj;
- data = bpydata->scene;
+ Scene *data = ((BPy_Scene *)value)->scene;
if (!data)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -615,55 +609,48 @@ PyObject *LibBlockSeq_unlink(BPy_LibBlockSeq *self, PyObject * args)
/* Run the removal code */
free_libblock( &G.main->scene, data );
- bpydata->scene= NULL;
-
+ ((BPy_Scene *)value)->scene = NULL;
Py_RETURN_NONE;
}
case ID_GR:
- if( !PyArg_ParseTuple( args, "O!", &Group_Type, &pyobj ) ) {
+ if( !BPy_Group_Check(value) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Group object" );
} else {
- BPy_Group *bpydata;
- Group *data;
-
- bpydata = (BPy_Group *)pyobj;
- data = bpydata->group;
+ Group *data = ((BPy_Group *)value)->group;
if (!data)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "This Group has been removed alredy" );
+ "This Group has been removed already" );
/* Run the removal code */
free_group(data);
unlink_group(data);
data->id.us= 0;
free_libblock( &G.main->group, data );
- bpydata->group= NULL;
+ ((BPy_Group *)value)->group = NULL;
Py_RETURN_NONE;
}
case ID_TXT:
- if( !PyArg_ParseTuple( args, "O!", &Text_Type, &pyobj ) ) {
+ if( !BPy_Text_Check(value) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Text object" );
} else {
- BPy_Text *bpydata;
- Text *data;
- bpydata = (BPy_Text *)pyobj;
- data = bpydata->text;
+ Text *data = ((BPy_Text *)value)->text;
if (!data)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "This Group has been removed alredy" );
+ "This Group has been removed already" );
/* Run the removal code */
BPY_clear_bad_scriptlinks( data );
+ BPY_free_pyconstraint_links( data );
free_text_controllers( data );
unlink_text( data );
free_libblock( &G.main->text, data );
- bpydata->text = NULL;
+ ((BPy_Text *)value)->text = NULL;
Py_RETURN_NONE;
}
@@ -701,7 +688,7 @@ static PyGetSetDef LibBlockSeq_getseters[] = {
static struct PyMethodDef BPy_LibBlockSeq_methods[] = {
{"new", (PyCFunction)LibBlockSeq_new, METH_VARARGS | METH_KEYWORDS,
"(name) - Create a new object in this scene from the obdata given and return a new object"},
- {"unlink", (PyCFunction)LibBlockSeq_unlink, METH_VARARGS,
+ {"unlink", (PyCFunction)LibBlockSeq_unlink, METH_O,
"unlinks the object from the scene"},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py
index 157e8b28656..68916af6166 100644
--- a/source/blender/python/api2_2x/doc/Armature.py
+++ b/source/blender/python/api2_2x/doc/Armature.py
@@ -156,6 +156,11 @@ class Armature:
@type mirrorEdit: Bool
@ivar autoIK: Adds temporary IK chains while grabbing bones
@type autoIK: Bool
+ @ivar layerMask: Layer bitmask
+ Example::
+ # set armature to layers 14 and 16
+ armature.layerMask = (1<<13) + (1<<15)
+ @type layerMask: Int
"""
def __init__(name = 'myArmature'):
@@ -187,6 +192,16 @@ class Armature:
@note: Must have called makeEditable() first.
@rtype: None
"""
+ def copy():
+ """
+ Return a copy of this armature.
+ @rtype: Armature
+ """
+ def __copy__():
+ """
+ Return a copy of this armature.
+ @rtype: Armature
+ """
import id_generics
Armature.__doc__ += id_generics.attributes
@@ -282,6 +297,11 @@ class Bone:
@type headRadius: Float
@ivar tailRadius: The radius of this bones head (used for envalope bones)
@type tailRadius: Float
+ @ivar layerMask: Layer bitmask
+ Example::
+ # set bone to layers 14 and 16
+ bone.layerMask = (1<<13) + (1<<15)
+ @type layerMask: Int
"""
def hasParent():
diff --git a/source/blender/python/api2_2x/doc/BGL.py b/source/blender/python/api2_2x/doc/BGL.py
index 26bbfe0def6..661042f341b 100644
--- a/source/blender/python/api2_2x/doc/BGL.py
+++ b/source/blender/python/api2_2x/doc/BGL.py
@@ -1213,6 +1213,12 @@ def glPopAttrib():
@see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushattrib.html}
"""
+def glPopClientAttrib():
+ """
+ Pop the client attribute stack
+ @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html}
+ """
+
def glPopMatrix():
"""
Pop the current matrix stack
@@ -1248,6 +1254,15 @@ def glPushAttrib(mask):
@param mask: Specifies a mask that indicates which attributes to save.
"""
+def glPushClientAttrib(mask):
+ """
+ Push the client attribute stack
+ @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushclientattrib.html}
+
+ @type mask: Enumerated constant(s)
+ @param mask: Specifies a mask that indicates which attributes to save.
+ """
+
def glPushMatrix():
"""
Push the current matrix stack
diff --git a/source/blender/python/api2_2x/doc/Blender.py b/source/blender/python/api2_2x/doc/Blender.py
index e4ba4dbcf31..40bf9001a76 100644
--- a/source/blender/python/api2_2x/doc/Blender.py
+++ b/source/blender/python/api2_2x/doc/Blender.py
@@ -60,6 +60,7 @@ def Set (request, data):
@type request: string
@param request: The setting to change:
- 'curframe': the current animation frame
+ - 'compressfile' : compress file writing a blend file (Use a boolean value True/False).
- 'uscriptsdir': user scripts dir
- 'yfexportdir': yafray temp xml storage dir
- 'fontsdir': font dir
@@ -68,6 +69,7 @@ def Set (request, data):
- 'renderdir': default render output dir
- 'soundsdir': sound dir
- 'tempdir': temp file storage dir
+ - 'mipmap' : Use mipmapping in the 3d view (Use a boolean value True/False).
@type data: int or string
@param data: The new value.
"""
@@ -79,6 +81,7 @@ def Get (request):
@param request: The setting data to be returned:
- 'curframe': the current animation frame.
- 'curtime' : the current animation time.
+ - 'compressfile' : compress setting from the file menu, return 0 for false or 1 for true.
- 'staframe': the start frame of the animation.
- 'endframe': the end frame of the animation.
- 'rt': the value of the 'rt' button for general debugging
@@ -104,6 +107,7 @@ def Get (request):
- 'soundsdir': the path to the user defined dir for sound files. (*)
- 'tempdir': the path to the user defined dir for storage of Blender
temporary files. (*)
+ - 'mipmap' : Use mipmapping in the 3d view. (*)
- 'version' : the Blender version number.
@note: (*) these can be set in Blender at the User Preferences window -> File
Paths tab.
@@ -222,7 +226,7 @@ def PackAll ():
Pack all files.
"""
-def Blender_CountPackedFiles():
+def CountPackedFiles():
"""
Returns the number of packed files.
"""
@@ -236,3 +240,9 @@ def Quit ():
upon exiting) when this function is called, so the data in Blender isn't
lost.
"""
+def SaveUndoState (message):
+ """
+ Sets an undo at the current state.
+ @param message: Message that appiers in the undo menu
+ @type message: string
+ """ \ No newline at end of file
diff --git a/source/blender/python/api2_2x/doc/Constraint.py b/source/blender/python/api2_2x/doc/Constraint.py
index 2176c9903c2..61ee3c36700 100644
--- a/source/blender/python/api2_2x/doc/Constraint.py
+++ b/source/blender/python/api2_2x/doc/Constraint.py
@@ -32,7 +32,7 @@ Or to print all the constraints attached to each bone in a pose::
for comparison with L{Constraint.type}. Values are
TRACKTO, IKSOLVER, FOLLOWPATH, COPYROT, COPYLOC, COPYSIZE, ACTION,
LOCKTRACK, STRETCHTO, FLOOR, LIMITLOC, LIMITROT, LIMITSIZE, CLAMPTO,
- NULL
+ PYTHON, CHILDOF, TRANSFORM, NULL
@type Settings: readonly dictionary
@var Settings: Constant dict used for changing constraint settings.
@@ -42,6 +42,14 @@ Or to print all the constraints attached to each bone in a pose::
- BONE (string): name of Bone sub-target (for armature targets) (Note: not
used by Stretch To (STRETCHTO), Limit Location (LIMITLOC), Limit Rotation
(LIMITROT), Limit Scale (LIMITSIZE), Follow Path (FOLLOWPATH), Clamp To (CLAMPTO))
+ - Used by some constraints:
+ - OWNERSPACE (int): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, LIMITLOC, LIMITROT, LIMITSIZE, PYTHON, TRANSFORM
+ If the owner is an object, values are SPACE_WORLD, SPACE_LOCAL
+ If the owner is a bone, values are SPACE_WORLD, SPACE_POSE, SPACE_PARLOCAL, SPACE_LOCAL
+ - TARGETSPACE (list of ints): for TRACKTO, COPYLOC, COPYROT, COPYSIZE, PYTHON, TRANSFORM, ACTION
+ For every target that the Constraint can have, the target space can be set
+ If the target is an object, values are SPACE_WORLD, SPACE_LOCAL
+ If the target is a bone, values are SPACE_WORLD, SPACE_POSE, SPACE_PARLOCAL, SPACE_LOCAL
- Used by IK Solver (IKSOLVER) constraint:
- TOLERANCE (float): clamped to [0.0001:1.0]
- ITERATIONS (int): clamped to [1,10000]
@@ -52,12 +60,11 @@ Or to print all the constraints attached to each bone in a pose::
- USETIP (bool)
- Used by Action (ACTION) constraint:
- ACTION (Action Object)
- - LOCAL (bool)
- START (int): clamped to [1,maxframe]
- END (int): clamped to [1,maxframe]
- - MIN (float): clamped to [-180.0,180.0]
- - MAX (float): clamped to [-180.0,180.0]
- - KEYON (int): values are XROT, YROT, ZROT
+ - MIN (float): clamped to [-1000.0,1000.0] for Location, [-180.0,180.0] for Rotation, [0.0001,1000.0] for Scaling
+ - MAX (float): clamped to [-1000.0,1000.0] for Location, [-180.0,180.0] for Rotation, [0.0001,1000.0] for Scaling
+ - KEYON (int): values are XLOC, YLOC, ZLOC, XROT, YROT, ZROT, XSIZE, YSIZE, ZSIZE
- Used by Track To (TRACKTO) constraint:
- TRACK (int): values are TRACKX, TRACKY, TRACKZ, TRACKNEGX,
TRACKNEGY, TRACKNEGZ
@@ -80,23 +87,18 @@ Or to print all the constraints attached to each bone in a pose::
- LOCK (int): values are LOCKX, LOCKY, LOCKZ
- Used by Clamp To (CLAMPTO) constraint:
- CLAMP (int): values are CLAMPAUTO, CLAMPX, CLAMPY, CLAMPZ
+ - CLAMPCYCLIC (bool)
- Used by Floor (FLOOR) constraint:
- MINMAX (int): values are MINX, MINY, MINZ, MAXX, MAXY, MAXZ
- OFFSET (float): clamped to [-100.0,100.0]
- STICKY (bool)
- Used by Copy Location (COPYLOC) and Copy Rotation (COPYROT)
- COPY (bitfield): any combination of COPYX, COPYY and COPYZ with possible addition of COPYXINVERT, COPYYINVERT and COPYZINVERT to invert that particular input (if on).
- - LOCAL (bool): Only for constraints which Armature targets.
- Used by Copy Size (COPYSIZE) constraint:
- COPY (bitfield): any combination of COPYX, COPYY and COPYZ
- Used by Limit Location (LIMITLOC) constraint:
- LIMIT (bitfield): any combination of LIMIT_XMIN, LIMIT_XMAX,
LIMIT_YMIN, LIMIT_YMAX, LIMIT_ZMIN, LIMIT_ZMAX
- - LIMIT_LOCAL_BONE (boolean): USE WITH CAUTION. Only do something
- with this value if constraint is assigned to a bone.
- - LIMIT_LOCAL_NOPARENT (boolean): USE WITH CAUTION. Only do something
- with this value if constraint is assigned to an object with that
- has been parented to something.
- XMIN (float): clamped to [-1000.0,1000.0]
- XMAX (float): clamped to [-1000.0,1000.0]
- YMIN (float): clamped to [-1000.0,1000.0]
@@ -106,8 +108,6 @@ Or to print all the constraints attached to each bone in a pose::
- Used by Limit Rotation (LIMITROT) constraint:
- LIMIT (bitfield): any combination of LIMIT_XROT, LIMIT_YROT,
LIMIT_ZROT
- - LIMIT_LOCAL_BONE (boolean): USE WITH CAUTION. Only do something
- with this value if constraint is assigned to a bone.
- XMIN (float): clamped to [-360.0,360.0]
- XMAX (float): clamped to [-360.0,360.0]
- YMIN (float): clamped to [-360.0,360.0]
@@ -117,12 +117,32 @@ Or to print all the constraints attached to each bone in a pose::
- Used by Limit Scale (LIMITSIZE) constraint:
- LIMIT (bitfield): any combination of LIMIT_XMIN, LIMIT_XMAX,
LIMIT_YMIN, LIMIT_YMAX, LIMIT_ZMIN, LIMIT_ZMAX
- - XMIN (float): clamped to [-1000.0,1000.0]
- - XMAX (float): clamped to [-1000.0,1000.0]
- - YMIN (float): clamped to [-1000.0,1000.0]
- - YMAX (float): clamped to [-1000.0,1000.0]
- - ZMIN (float): clamped to [-1000.0,1000.0]
- - ZMAX (float): clamped to [-1000.0,1000.0]
+ - XMIN (float): clamped to [0.0001,1000.0]
+ - XMAX (float): clamped to [0.0001,1000.0]
+ - YMIN (float): clamped to [0.0001,1000.0]
+ - YMAX (float): clamped to [0.0001,1000.0]
+ - ZMIN (float): clamped to [0.0001,1000.0]
+ - ZMAX (float): clamped to [0.0001,1000.0]
+ - Used by Python Script (PYTHON) constraint:
+ - SCRIPT (Text): script to use
+ - PROPERTIES (IDProperties): ID-Properties of constraint
+ - Used by Child Of (CHILDOF) constraint:
+ - COPY (bitfield): any combination of PARLOCX, PARLOCY, PARLOCZ,
+ PARROTX, PARROTY, PARROTZ, PARSIZEX, PARSIZEY, PARSIZEZ.
+ - Used by Transformation (TRANSFORM) constraint:
+ - FROM (int): values are LOC, ROT, SCALE
+ - TO (int): values are LOC, ROT, SCALE
+ - MAPX, MAPY, MAPZ (int): values are LOC, ROT, SCALE
+ - EXTRAPOLATE (bool)
+ - FROM_MINX, FROM_MINY, FROM_MINZ, FROM_MAXX,
+ FROM_MAXY, FROM_MAXZ (float):
+ If FROM==LOC, then is clamped to [-1000.0, 1000.0]
+ If FROM==ROT, then is clamped to [-360.0, 360.0]
+ If FROM==SCALE, then is clamped to [0.0001, 1000.0]
+ - TO_MINX, TO_MINY, TO_MINZ, TO_MAXX, TO_MAXY, TO_MAXZ (float):
+ If TO==LOC, then is clamped to [-1000.0, 1000.0]
+ If TO==ROT, then is clamped to [-360.0, 360.0]
+ If TO==SCALE, then is clamped to [0.0001, 1000.0]
"""
diff --git a/source/blender/python/api2_2x/doc/Curve.py b/source/blender/python/api2_2x/doc/Curve.py
index d8ab28524fb..c3760bc2c1d 100644
--- a/source/blender/python/api2_2x/doc/Curve.py
+++ b/source/blender/python/api2_2x/doc/Curve.py
@@ -10,7 +10,7 @@ This module provides access to B{Curve Data} objects in Blender.
A Blender Curve Data consists of multiple L{CurNurb}(s). Try converting a Text object to a Curve to see an example of this. Each curve is of
type Bezier or Nurb. The underlying L{CurNurb}(s) can be accessed with
-the [] operator. Operator [] returns an object of type L{CurNurb}.
+the [] operator. Operator [] returns an object of type L{CurNurb}. Removing a L{CurNurb} can be done this way too. del curve[0] removes the first curve.
Note that L{CurNurb} can be used to acces a curve of any type (Poly, Bezier or Nurb)
@@ -115,9 +115,9 @@ class Curve:
@type resolv: int
@ivar width: The Curve Data width [0 - 2].
@type width: float
- @ivar ext1: The Curve Data extent1 (for bevels).
+ @ivar ext1: The Curve Data extent1 Called "Extrude" in the user interface (for bevels only).
@type ext1: float
- @ivar ext2: The Curve Data extent2 (for bevels).
+ @ivar ext2: The Curve Data extent2 - Called "Bevel Depth" in the user interface (for bevels only).
@type ext2: float
@ivar loc: The Curve Data location(from the center).
@type loc: list of 3 floats
@@ -543,6 +543,8 @@ class CurNurb:
@ivar knotsV: The knot vector in the V direction. The tuple will be empty
if the curve isn't a NURB or doesn't have knots in this direction.
@type knotsV: tuple of floats
+ @ivar smooth: Set the smoothing for this curve (applies to cuve objects that have a bevel)
+ @type smooth: bool
"""
def __setitem__( n, point ):
diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py
index 70006048a61..18234754315 100644
--- a/source/blender/python/api2_2x/doc/Draw.py
+++ b/source/blender/python/api2_2x/doc/Draw.py
@@ -249,8 +249,9 @@ def UIBlock(draw):
@note: Within this popup, Redraw events and the registered button callback will not work.
For buttons to run events, use per button callbacks.
@note: OpenGL drawing functions wont work within this popup, for text use L{Label} rather then L{Text}
+ @warning: L{Menu} will not work properly within a UIBlock, this is a limitation with blenders user interface internals.
"""
-
+
def Register(draw = None, event = None, button = None):
"""
Register callbacks for windowing.
@@ -352,6 +353,23 @@ def PupMenu(name, maxrow = None):
@return: the chosen entry number or -1 if none was chosen.
"""
+def PupTreeMenu( menu ):
+ """
+ Create a popup menu tree.
+
+ Each item in the list is a menu item - (str, event), separator - None or submenu - (str, [...]).
+
+ Submenus list uses the same syntax as the menu list.
+
+ Example::
+ result = Draw.PupTreeMenu( [ ("Menu Item 1", 10), ("Menu Item 2", 12), ("SubMenu", [("Menu Item 3", 100), ("MenuItem4", 101) ] ) ] )
+
+ @type menu: string
+ @param menu: A menu list
+ @rtype: int
+ @return: the chosen entry number or -1 if none was chosen.
+ """
+
def PupIntInput(text, default, min, max):
"""
Create an integer number input pop-up.
@@ -768,7 +786,7 @@ def GetStringWidth(string, fontsize = 'normal'):
@type string: string
@param string: A string.
@type fontsize: string
- @param fontsize: The size of the font: 'large', 'normal', 'small' or 'tiny'.
+ @param fontsize: The size of the font: 'large', 'normal', 'normalfix', 'small' or 'tiny'.
@rtype: int
@return: The width of I{string} with the chosen I{fontsize}.
"""
@@ -785,7 +803,7 @@ def Text(string, fontsize = 'normal'):
@type string: string
@param string: The text string to draw.
@type fontsize: string
- @param fontsize: The size of the font: 'large', 'normal', 'small' or 'tiny'.
+ @param fontsize: The size of the font: 'large', 'normal', 'normalfix', 'small' or 'tiny'.
@rtype: int
@return: The width of I{string} drawn with the chosen I{fontsize}.
@note: For drawing text in the 3d view see the workaround in L{BGL.glRasterPos}
diff --git a/source/blender/python/api2_2x/doc/Font.py b/source/blender/python/api2_2x/doc/Font.py
index c0ad66d0462..44fa3d81f91 100644
--- a/source/blender/python/api2_2x/doc/Font.py
+++ b/source/blender/python/api2_2x/doc/Font.py
@@ -52,17 +52,17 @@ class Font:
def pack():
"""
- Packs the sound into the current blend file.
- @note: An error will be raised if the sound is already packed or the filename path does not exist.
+ Packs the font into the current blend file.
+ @note:
@returns: nothing
@rtype: none
"""
def unpack(mode):
"""
- Unpacks the sound to the samples filename.
+ Unpacks the font.
@param mode: One of the values in Blender.UnpackModes dict.
- @note: An error will be raised if the sound is not packed or the filename path does not exist.
+ @note: An error will be raised if the font is not packed or the filename path does not exist.
@returns: nothing
@rtype: none
@type mode: int
diff --git a/source/blender/python/api2_2x/doc/Geometry.py b/source/blender/python/api2_2x/doc/Geometry.py
index 7c7e91a1a71..f882f4b3b57 100644
--- a/source/blender/python/api2_2x/doc/Geometry.py
+++ b/source/blender/python/api2_2x/doc/Geometry.py
@@ -48,6 +48,13 @@ def LineIntersect2D(vec1, vec2, vec3, vec4):
@return: a 2D Vector for the intersection or None where there is no intersection.
"""
+def ClosestPointOnLine(pt, vec1, vec2):
+ """
+ Takes 2 lines vec1, vec2 for the 2 points of the first line and vec2, vec3 for the 2 points of the second line.
+ @rtype: tuple
+ @return: a tuple containing a vector and a float, the vector is the closest point on the line, the float is the position on the line, between 0 and 1 the point is on the line.
+ """
+
def PointInTriangle2D(pt, tri_pt1, tri_pt2, tri_pt3):
"""
Takes 4 vectors (one for the test point and 3 for the triangle)
diff --git a/source/blender/python/api2_2x/doc/Group.py b/source/blender/python/api2_2x/doc/Group.py
index aca7c56b4a5..6bd6e105ec3 100644
--- a/source/blender/python/api2_2x/doc/Group.py
+++ b/source/blender/python/api2_2x/doc/Group.py
@@ -121,6 +121,12 @@ class Group:
@rtype: Group
@return: a copy of this group
"""
+ def copy ():
+ """
+ Make a copy of this group
+ @rtype: Group
+ @return: a copy of this group
+ """
import id_generics
Group.__doc__ += id_generics.attributes
diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py
index 6d613b3c8fe..92a05c2604d 100644
--- a/source/blender/python/api2_2x/doc/Image.py
+++ b/source/blender/python/api2_2x/doc/Image.py
@@ -48,7 +48,7 @@ def New (name, width, height, depth):
@type height: int
@param height: The height of the new Image object, between 1 and 5000.
@type depth: int
- @param depth: The colour depth of the new Image object. (8:Grey, 24:RGB, 32:RGBA). (Not implimented yet, all new images will be 24bit)
+ @param depth: The colour depth of the new Image object. (32:RGBA 8bit channels, 128:RGBA 32bit high dynamic range float channels).
@rtype: Blender Image
@return: A new Blender Image object.
"""
@@ -83,7 +83,7 @@ class Image:
@type filename: string
@ivar size: The [width, height] dimensions of the image (in pixels).
@type size: list
- @ivar depth: The pixel depth of the image. [8, 16, 18, 24, 32]
+ @ivar depth: The pixel depth of the image, read only. [8, 16, 18, 24, 32, 128 (for 32bit float color channels)]
@type depth: int
@ivar xrep: Texture tiling: the number of repetitions in the x (horizontal)
axis. [1, 16].
@@ -137,10 +137,23 @@ class Image:
def getDepth():
"""
- Get the pixel depth of this image.
+ Get the pixel depth of this image. [8,16,24,32,128 for 32bit float images]
@rtype: int
"""
+ def getPixelHDR(x, y):
+ """
+ Get the the colors of the current pixel in the form [r,g,b,a].
+ For float image types, returned values can be greater then the useual [0.0, 1.0] range.
+ Pixel coordinates are in the range from 0 to N-1. See L{getMaxXY}
+ @returns: [ r, g, b, a]
+ @rtype: list of 4 floats
+ @type x: int
+ @type y: int
+ @param x: the x coordinate of pixel.
+ @param y: the y coordinate of pixel.
+ """
+
def getPixelF(x, y):
"""
Get the the colors of the current pixel in the form [r,g,b,a].
@@ -153,6 +166,7 @@ class Image:
@param x: the x coordinate of pixel.
@param y: the y coordinate of pixel.
"""
+
def getPixelI(x, y):
"""
Get the the colors of the current pixel in the form [r,g,b,a].
@@ -229,6 +243,12 @@ class Image:
@returns: None
"""
+ def updateDisplay():
+ """
+ Update the display image from the floating point buffer (if it exists)
+ @returns: None
+ """
+
def glLoad():
"""
Load this image's data into OpenGL texture memory, if it is not already
@@ -303,6 +323,21 @@ class Image:
@param speed: The new value in [1, 100].
"""
+ def setPixelHDR(x, y, (r, g, b,a )):
+ """
+ Set the the colors of the current pixel in the form [r,g,b,a].
+ For float image types, returned values can be greater then the useual [0.0, 1.0] range.
+ Pixel coordinates are in the range from 0 to N-1. See L{getMaxXY}
+ @type x: int
+ @type y: int
+ @type r: float
+ @type g: float
+ @type b: float
+ @type a: float
+ @returns: nothing
+ @rtype: none
+ """
+
def setPixelF(x, y, (r, g, b,a )):
"""
Set the the colors of the current pixel in the form [r,g,b,a].
diff --git a/source/blender/python/api2_2x/doc/Ipo.py b/source/blender/python/api2_2x/doc/Ipo.py
index 8658f9cda1c..c479926ccf3 100644
--- a/source/blender/python/api2_2x/doc/Ipo.py
+++ b/source/blender/python/api2_2x/doc/Ipo.py
@@ -14,12 +14,12 @@ several IpoCurves, and an IpoCurve is composed of several BezTriples.
Example::
from Blender import Ipo
- ob = Ipo.Get('ObIpo') # retrieves an Ipo object
- ob.name = 'ipo1' # change the Ipo's name
- icu = ipo[Ipo.OB_LOCX] # request X Location Ipo curve object
+ ipo = Ipo.Get('ObIpo') # retrieves an Ipo object
+ ipo.name = 'ipo1' # change the Ipo's name
+ icu = ipo[Ipo.OB_LOCX] # request X Location Ipo curve
if icu != None and len(icu.bezierPoints) > 0: # if curve exists and has BezTriple points
- val = icu[2.5] # get the curve's value at time 2.5
- icu[Ipo.OB_LOCX] = None # delete the ipo curve
+ val = icu[2.5] # get the curve's value at time 2.5
+ ipo[Ipo.OB_LOCX] = None # delete the Ipo curve
Each type of Ipo has different types Ipocurves. With the exception of Shape
Key Ipos, constants are used to specify all Ipocurves. There are two ways
@@ -47,7 +47,7 @@ The valid IpoCurve constants are:
4. Camera Ipo: CA_LENS, CA_CLSTA, CA_CLEND, CA_APERT, CA_FDIST
5. Object Ipo: OB_LOCX, OB_LOCY, OB_LOCZ, OB_DLOCX, OB_DLOCY, OB_DLOCZ,
OB_ROTX, OB_ROTY, OB_ROTZ, OB_DROTX, OB_DROTY, OB_DROTZ,
- OB_SIZEX, OB_SIZEY, OB_SIZEZ, OB_DSIZEX, OB_DSIZEY, OB_DSIZEZ,
+ OB_SCALEX, OB_SCALEY, OB_SCALEZ, OB_DSCALEX, OB_DSCALEY, OB_DSCALEZ,
OB_LAYER, OB_TIME, OB_COLR, OB_COLG, OB_COLB, OB_COLA,
OB_FSTRENG, OB_FFALL, OB_RDAMP, OB_DAMPING, OB_PERM
6. Curve Ipo: CU_SPEED
diff --git a/source/blender/python/api2_2x/doc/Key.py b/source/blender/python/api2_2x/doc/Key.py
index 584a7f066b1..53f289d2e8b 100644
--- a/source/blender/python/api2_2x/doc/Key.py
+++ b/source/blender/python/api2_2x/doc/Key.py
@@ -89,16 +89,36 @@ class KeyBlock:
def getData():
"""
Get the data of a KeyBlock, as a list of data items. Each item
- will have a different data type depending on the type of this
+ will have a different data format depending on the type of this
Key.
- - Mesh keys have a list of L{NMVert<NMesh.NMVert>} objects in the data
+
+ Note that prior to 2.45 the behaviour of this function
+ was different (and very wrong). Old scripts might need to be
+ updated.
+
+ - Mesh keys have a list of L{Vectors<Mathutils.Vector>} objects in the data
block.
- - Lattice keys have a list of BPoints in the data block. These
- don't have corresponding Python objects yet, so each BPoint is
- represented using a list of three floating-point numbers (the
- coordinate for each lattice vertex).
- - Curve keys return either a list of L{BezTriple<BezTriple.BezTriple>}
- objects in the data if the curve is a Bezier curve, otherwise it
- returns lists of three floats for each NURB or poly coordinate.
+ - Lattice keys have a list of L{Vectors<Mathutils.Vector>} objects in the data
+ block.
+ - Curve keys return either a list of tuples, eacn containing
+ four L{Vectors<Mathutils.Vector>} (if the curve is a Bezier curve),
+ or otherwise just a list of L{Vectors<Mathutils.Vector>}.
+
+ For bezier keys, the first three vectors in the tuple are the Bezier
+ triple vectors, while the fourth vector's first element is the curve tilt
+ (the other two elements are reserved and are currently unused).
+
+ For non-Bezier keys, the first three elements of the returned vector is
+ the curve handle point, while the fourth element is the tilt.
+
+
+ A word on relative shape keys; relative shape keys are not actually
+ stored as offsets to the base shape key (like you'd expect). Instead,
+ each shape key stores an entire model (actually the state of the mesh
+ vertices after exiting editmode with any given key active).
+
+ The additive offset for a shape key is calculated (when needed) by
+ comparing the shape key with its base key, which is always the very
+ first in the keyblock list.
"""
diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py
index b65fe253530..a7a1fb94620 100644
--- a/source/blender/python/api2_2x/doc/Lamp.py
+++ b/source/blender/python/api2_2x/doc/Lamp.py
@@ -26,6 +26,13 @@ Example::
- 'Hemi': 3
- 'Area': 4
- 'Photon': 5
+@type Falloffs: read-only dictionary
+@var Falloffs: The lamp falloff types.
+ - CONSTANT - Constant falloff
+ - INVLINEAR - Inverse linear
+ - INVSQUARE - Inverse square
+ - CUSTOM - Custom curve
+ - LINQUAD - Lin/Quad weighted
@type Modes: read-only dictionary
@var Modes: The lamp modes. Modes may be ORed together.
- 'Shadows'
@@ -152,6 +159,8 @@ class Lamp:
@type spotSize: float
@ivar type: Lamp type. See L{Types} for values.
@type type: int
+ @ivar falloffType: Lamp falloff type. See L{Falloffs} for values.
+ @type falloffType: int
@warning: Most member variables assume values in some [Min, Max] interval.
When trying to set them, the given parameter will be clamped to lie in
diff --git a/source/blender/python/api2_2x/doc/LibData.py b/source/blender/python/api2_2x/doc/LibData.py
index 7884ea50659..7b6f4950c76 100644
--- a/source/blender/python/api2_2x/doc/LibData.py
+++ b/source/blender/python/api2_2x/doc/LibData.py
@@ -18,7 +18,7 @@ which module is supported in the end.
Example::
import bpy
- scn= bpy.scenes.active # get current scene
+ scn= bpy.data.scenes.active # get current scene
lib = bpy.libraries.load('//file.blend') # open file.blend
ob = scn.objects.link(lib.objects.append('Cube')) # append Cube object from library to current scene
mat = lib.objects.link('Material') # get a link to a material
@@ -103,17 +103,17 @@ class LibData:
B{Note}: Blender Objects cannot be appended or linked without linking
them to a scene. For this reason, lib.objects.append() returns a
special "wrapper object" which must be passed to Scene.objects.link()
- or bpy.scenes.active.link() in order to actually create the object.
+ or bpy.data.scenes.active.link() in order to actually create the object.
So the following code will not create a new object::
import bpy
- scn= bpy.scenes.active # get current scene
+ scn= bpy.data.scenes.active # get current scene
lib = bpy.libraries.load('//file.blend') # open file.blend
pseudoOb = lib.objects.append('Cube')) # get an object wrapper
But this code will::
import bpy
- scn= bpy.scenes.active # get current scene
+ scn= bpy.data.scenes.active # get current scene
lib = bpy.libraries.load('//file.blend') # open file.blend
pseudoOb = lib.objects.append('Cube')) # get an object wrapper
ob = scn.objects.link(pseudoOb) # link to scene
diff --git a/source/blender/python/api2_2x/doc/Material.py b/source/blender/python/api2_2x/doc/Material.py
index 40207dd92c0..edcdbbb959b 100644
--- a/source/blender/python/api2_2x/doc/Material.py
+++ b/source/blender/python/api2_2x/doc/Material.py
@@ -50,6 +50,7 @@ Example::
- ONLYSHADOW - Let alpha be determined on the degree of shadow.
- + HALOXALPHA - Use extreme alpha.
- TEXFACE - UV-Editor assigned texture gives color and texture info for faces.
+ - TEXFACE_ALPHA - When TEXFACE is enabled, use the alpha as well.
- + HALOSTAR - Render halo as a star.
- NOMIST - Set the Material insensitive to mist.
- + HALOSHADED - Let halo receive light.
diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py
index 7546bb5b6d5..8b0c41b9a69 100644
--- a/source/blender/python/api2_2x/doc/Mathutils.py
+++ b/source/blender/python/api2_2x/doc/Mathutils.py
@@ -28,15 +28,15 @@ Example::
print angle
"""
-def Rand (high = 1, low = 0):
+def Rand (low=0.0, high = 1.0):
"""
Return a random number within a range.
- High and low represent the range from which the random
- number must return its result.
- @type high: float
- @param high: The upper range.
+ low and high represent are optional parameters which represent the range
+ from which the random number must return its result.
@type low: float
@param low: The lower range.
+ @type high: float
+ @param high: The upper range.
"""
def Intersect(vec1, vec2, vec3, ray, orig, clip=1):
diff --git a/source/blender/python/api2_2x/doc/Mesh.py b/source/blender/python/api2_2x/doc/Mesh.py
index 2b858ab7748..0690b94712b 100644
--- a/source/blender/python/api2_2x/doc/Mesh.py
+++ b/source/blender/python/api2_2x/doc/Mesh.py
@@ -17,6 +17,7 @@ face's attributes (the vertex color):
Example::
from Blender import *
+ import bpy
editmode = Window.EditMode() # are we in edit mode? If so ...
if editmode: Window.EditMode(0) # leave edit mode before getting the mesh
@@ -25,7 +26,7 @@ Example::
coords=[ [-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1], [0,0,1] ]
faces= [ [3,2,1,0], [0,1,4], [1,2,4], [2,3,4], [3,0,4] ]
- me = Mesh.New('myMesh') # create a new mesh
+ me = bpy.data.meshes.new('myMesh') # create a new mesh
me.verts.extend(coords) # add vertices to mesh
me.faces.extend(faces) # add faces to the mesh (also adds edges)
@@ -35,7 +36,7 @@ Example::
me.faces[1].col[1].g = 255
me.faces[1].col[2].b = 255
- scn = Scene.GetCurrent() # link object to current scene
+ scn = bpy.data.scenes.active # link object to current scene
ob = scn.objects.new(me, 'myObj')
if editmode: Window.EditMode(1) # optional, just being nice
@@ -518,7 +519,7 @@ class MFace:
me= ob.getData(mesh=1) # thin wrapper doesn't copy mesh data like nmesh
me.vertexColors= True # Enable face, vertex colors
for f in me.faces:
- for i, v in enumerate(f.v):
+ for i, v in enumerate(f):
no= v.no
col= f.col[i]
col.r= int((no.x+1)*128)
@@ -689,6 +690,22 @@ class MFaceSeq:
- a integer, specifying an index into the mesh's face list
"""
+ def sort():
+ """
+ Sorts the faces using exactly the same syntax as pythons own list sorting function.
+
+ Example::
+ import Blender
+ from Blender import Mesh
+ me = Mesh.Get('mymesh')
+
+ me.faces.sort(key=lambda f: f.area)
+
+ me.faces.sort(key=lambda f: f.cent)
+
+ @note: Internally faces only refer to their index, so after sorting, faces you alredy have will not have their index changed to match the new sorted order.
+ """
+
def selected():
"""
Get selected faces.
@@ -740,19 +757,9 @@ class Mesh:
@type hide: boolean
@ivar subDivLevels: The [display, rendering] subdivision levels in [1, 6].
@type subDivLevels: list of 2 ints
-
- @ivar faceUV: The mesh contains UV-mapped textured faces. Enabling faceUV
- does not initialize the face colors like the Blender UI does; this must
- be done in the script. B{Note}: if faceUV is set, L{vertexColors} cannot
- be set. Furthermore, if vertexColors is already set when faceUV is set,
- vertexColors is cleared. This is because the vertex color information
- is stored with UV faces, so enabling faceUV implies enabling vertexColors.
- In addition, faceUV cannot be set when the mesh has no faces defined
- (this is the same behavior as the UI). Attempting to do so will throw
- a RuntimeError exception.
+ @ivar faceUV: The mesh contains UV-mapped textured faces.
@type faceUV: bool
- @ivar vertexColors: The mesh contains vertex colors. See L{faceUV} for the
- use of vertex colors when UV-mapped texture faces are enabled.
+ @ivar vertexColors: The mesh contains vertex colors. Set True to add vertex colors.
@type vertexColors: bool
@ivar vertexUV: The mesh contains "sticky" per-vertex UV coordinates.
@type vertexUV: bool
@@ -827,10 +834,15 @@ class Mesh:
Recalculates the vertex normals using face data.
"""
- def pointInside(vector):
+ def pointInside(point, selected_only=False):
"""
+ @type point: vector
+ @param point: Test if this point is inside the mesh
+ @type selected_only: bool
+ @param selected_only: if True or 1, only the selected faces are taken into account.
Returns true if vector is inside the mesh.
@note: Only returns a valid result for mesh data that has no holes.
+ @note: Bubbles in the mesh work as expect.
"""
def transform(matrix, recalc_normals = False, selected_only=False):
@@ -862,7 +874,7 @@ class Mesh:
@param matrix: 4x4 Matrix which can contain location, scale and rotation.
@type recalc_normals: int
@param recalc_normals: if True or 1, also transform vertex normals.
- @type selected_only: int
+ @type selected_only: bool
@param selected_only: if True or 1, only the selected verts will be transformed.
@warn: unlike L{NMesh.transform()<NMesh.NMesh.transform>}, this method
I{will immediately modify the mesh data} when it is used. If you
@@ -1001,7 +1013,8 @@ class Mesh:
@type group: string
@param group: the group name.
@type weightsFlag: bool
- @param weightsFlag: if 1, the weight is returned along with the index.
+ @param weightsFlag: if 1, each item in the list returned contains a
+ tuple pair (index, weight), the weight is a float between 0.0 and 1.0.
@type vertList: list of ints
@param vertList: if given, only those vertex points that are both in the
list and group passed in are returned.
@@ -1089,6 +1102,15 @@ class Mesh:
@param name: The name of the new Color layer, 31 characters max.
"""
+ def addMultiresLevel(levels = 1, type = 'catmull-clark'):
+ """
+ Adds multires levels to this mesh.
+ @type levels: int
+ @param levels: The number of levels to add
+ @type type: string
+ @param type: The type of multires level, 'catmull-clark' or 'simple'.
+ """
+
def removeUVLayer(name):
"""
Removes the active UV/Image layer.
diff --git a/source/blender/python/api2_2x/doc/Modifier.py b/source/blender/python/api2_2x/doc/Modifier.py
index 2770f66b318..1d7d2e121c9 100644
--- a/source/blender/python/api2_2x/doc/Modifier.py
+++ b/source/blender/python/api2_2x/doc/Modifier.py
@@ -49,6 +49,7 @@ Example::
@var Types: Constant Modifier dict used for L{ModSeq.append} to a
modifier sequence and comparing with L{Modifier.type}:
- ARMATURE - type value for Armature modifiers
+ - ARRAY - type value for Array modifiers
- BOOLEAN - type value for Boolean modifiers
- BUILD - type value for Build modifiers
- CURVE - type value for Curve modifiers
@@ -110,9 +111,9 @@ Example::
- WIDTH - Used for Wave only (float [0.0 - 5.0])
- NARROW - Used for Wave only (float [0.0 - 10.0])
- SPEED - Used for Wave only (float [-2.0 - 2.0])
- - DAMP - Used for Wave only (float [-1000.0 - 1000.0])
- - LIFETIME - Used for Wave only (float [-1000.0 - 1000.0])
- - TIMEOFFS - Used for Wave only (float [-1000.0 - 1000.0])
+ - DAMP - Used for Wave only (float [-MAXFRAME - MAXFRAME])
+ - LIFETIME - Used for Wave only (float [-MAXFRAME - MAXFRAME])
+ - TIMEOFFS - Used for Wave only (float [-MAXFRAME - MAXFRAME])
- OPERATION - Used for boolean only (int 0,1,2 : Intersect, Union, Difference)
diff --git a/source/blender/python/api2_2x/doc/NLA.py b/source/blender/python/api2_2x/doc/NLA.py
index adfcf77d965..aeb5178f3d7 100644
--- a/source/blender/python/api2_2x/doc/NLA.py
+++ b/source/blender/python/api2_2x/doc/NLA.py
@@ -18,6 +18,7 @@ It is a bitmask and settings are ORed together.
- HOLD: continue displaying the last frame past the end of the strip
- ACTIVE: action strip is active in NLA window
- LOCK_ACTION: action start/end are automatically mapped to strip duration
+ - MUTE: action strip does not contribute to the NLA solution
@type StrideAxes: readonly dictionary
@var StrideAxes: Constant dict used by the L{ActionStrip.strideAxis} attribute.
diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py
index 34cdd4b7821..4228f6de1a8 100644
--- a/source/blender/python/api2_2x/doc/Object.py
+++ b/source/blender/python/api2_2x/doc/Object.py
@@ -105,6 +105,7 @@ Example::
- SIZE
- LOCROT
- LOCROTSIZE
+ - LAYER
- PI_STRENGTH
- PI_FALLOFF
- PI_SURFACEDAMP
@@ -428,6 +429,8 @@ class Object:
@type enableDupFaces: boolean
@ivar enableDupFacesScale: The DupliFacesScale status of the object.
@type enableDupFacesScale: boolean
+ @ivar dupFacesScaleFac: Scale factor for dupliface instance, 1.0 by default.
+ @type dupFacesScaleFac: float
@ivar enableDupFrames: The DupliFrames status of the object.
Does not indicate that this object has any dupliFrames,
(as returned by L{DupObjects}) just that dupliFrames are enabled.
diff --git a/source/blender/python/api2_2x/doc/Pose.py b/source/blender/python/api2_2x/doc/Pose.py
index 677141d3dfd..ad1b44da5e2 100644
--- a/source/blender/python/api2_2x/doc/Pose.py
+++ b/source/blender/python/api2_2x/doc/Pose.py
@@ -175,12 +175,14 @@ class PoseBone:
@type localMatrix: Matrix object
@ivar poseMatrix: The total transformation of this PoseBone including constraints.
- (not settable).
-
This matrix is in armature space, for the current worldspace location of this pose bone, multiply
- it with its objects worldspace matrix
+ it with its objects worldspace matrix.
eg. pose_bone.poseMatrix * object.matrixWorld
+
+ Setting the poseMatrix only sets the loc/size/rot, before constraints are applied (similar to actions).
+ After setting pose matrix, run pose.update() to re-evaluate the pose and see the changes in the 3d view.
+
@type poseMatrix: Matrix object
@type constraints: BPy_ConstraintSeq
@ivar constraints: a sequence of constraints for the object
@@ -215,7 +217,11 @@ class PoseBone:
@ivar lockYRot: Disable Y DoF when part of an IK.
@type lockZRot: bool
@ivar lockZRot: Disable Z DoF when part of an IK.
-
+ @ivar layerMask: Layer bitmask
+ Example::
+ # set bone to layers 14 and 16
+ bone.layerMask = (1<<13) + (1<<15)
+ @type layerMask: Int
"""
def insertKey(parentObject, frameNumber, type = "[Pose.LOC, Pose.ROT, Pose.SIZE]", fast = False):
diff --git a/source/blender/python/api2_2x/doc/Render.py b/source/blender/python/api2_2x/doc/Render.py
index 9c9f58f6074..42fd5b564fe 100644
--- a/source/blender/python/api2_2x/doc/Render.py
+++ b/source/blender/python/api2_2x/doc/Render.py
@@ -74,6 +74,24 @@ attribute. One of the following modes can be active:
horizontally or vertically
- SCALE: Stretch or squeeze the viewport to fill the display window.
+@type BakeModes: readonly dictionary
+@var BakeModes: Constant dict used for with L{RenderData.bakeMode}
+attribute. One of the following modes can be active:
+ - LIGHT: Bake lighting only.
+ - ALL: Bake all render lighting.
+ - AO: Bake ambient occlusion.
+ - NORMALS: Bake a normal map.
+ - TEXTURE: Bake textures.
+ - DISPLACEMENT: Bake displacement.
+
+@type BakeNormalSpaceModes: readonly dictionary
+@var BakeNormalSpaceModes: Constant dict used for with L{RenderData.bakeNormalSpace}
+attribute. One of the following modes can be active:
+ - CAMERA: Bake normals relative to the camera.
+ - WORLD: Bake normals in worldspace.
+ - OBJECT: Bake normals relative to the object.
+ - TANGENT: Bake tangent space normals.
+
@var INTERNAL: The internal rendering engine. Use with setRenderer()
@var YAFRAY: Yafray rendering engine. Use with setRenderer()
@@ -92,6 +110,7 @@ attribute. One of the following modes can be active:
@var IRISZ: Output format. Use with renderdata.imageType / setImageType()
@var FTYPE: Output format. Use with renderdata.imageType / setImageType()
@var OPENEXR: Output format. Use with renderdata.imageType / setImageType()
+@var MULTILAYER: Output format. Use with renderdata.imageType / setImageType()
@var TIFF: Output format. Use with renderdata.imageType / setImageType()
@var FFMPEG: Output format. Use with renderdata.imageType / setImageType()
@var CINEON: Output format. Use with renderdata.imageType / setImageType()
@@ -105,14 +124,15 @@ attribute. One of the following modes can be active:
@var PAL169: Output format. Use with renderdata.sizePreset()
@var B_PR_FULL: Output format. Use with renderdata.sizePreset()
-@var NONE: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
+@var NONE: Yafray GI Quality / Method. Use with renderdata.setYafrayGIQuality()
@var LOW: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
@var MEDIUM: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
@var HIGH: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
@var HIGHER: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
@var BEST: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
-@var SKYDOME: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
-@var GIFULL: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
+@var USEAOSETTINGS: Yafray GI Quality. Use with renderdata.setYafrayGIQuality()
+@var SKYDOME: Yafray GI Method. Use with renderdata.setYafrayGIMethod()
+@var GIFULL: Yafray GI Method. Use with renderdata.setYafrayGIMethod()
"""
def CloseRenderWindow():
@@ -245,10 +265,12 @@ class RenderData:
@type extensions: boolean
@ivar compositor: 'Do Compositor' enabled.
@type compositor: boolean
- @ivar freeImages: 'Do Compositor' enabled.
+ @ivar freeImages: Texture images are freed after render.
@type freeImages: boolean
@ivar singleLayer: Only render the active layer.
@type singleLayer: boolean
+ @ivar activeLayer: The active render layer. Must be in range[0,num render layers-1]
+ @type activeLayer: int
@ivar saveBuffers: Save render buffers to disk while rendering, saves memory.
@type saveBuffers: boolean
@ivar compositeFree: Free nodes that are not used while composite.
@@ -292,7 +314,11 @@ class RenderData:
@type oversampling: boolean
@ivar fps: Frames per second.
Values are clamped to the range [1,120].
- @type fps: int
+ @ivar fpsBase: Frames per second base: used to generate fractional frames
+ per second values. For example, setting fps to 30 and fps_base to 1.001
+ will approximate the NTSC frame rate of 29.97 fps.
+ Values are clamped to the range [1,120].
+ @type fpsBase: float
@ivar timeCode: Get the current frame in HH:MM:SS:FF format. Read-only.
@type timeCode: string
@ivar environmentMap: Environment map rendering enabled.
@@ -324,8 +350,57 @@ class RenderData:
scene or None (setting to None clears the set). The scene argument cannot
cause a circular link.
@type set: BPy_Scene or None
+ @ivar yafrayGIMethod: Global Illumination method.
+ Valid values are NONE (0), SKYDOME (1) or FULL (2).
+ @type yafrayGIMethod: int {NONE (0), SKYDOME (1), GIFULL (2)}
+ @ivar yafrayGIQuality: Global Illumination quality.
+ @type yafrayGIQuality: int {NONE (0), LOW (1), MEDIUM (2), HIGH (3), HIGHER (4), BEST (5), USEAOSETTINGS (6)}
+ @ivar yafrayExportToXML: If true export to an xml file and call yafray instead of plugin.
+ @type yafrayExportToXML: boolean
+ @ivar yafrayAutoAntiAliasing: Automatic anti-aliasing enabled/disabled.
+ @type yafrayAutoAntiAliasing: boolean
+ @ivar yafrayClampRGB: Clamp RGB enabled/disabled.
+ @type yafrayClampRGB: boolean
+ @ivar yafrayAntiAliasingPasses: Number of anti-aliasing passes (0 is no Anti-Aliasing).
+ @type yafrayAntiAliasingPasses: int [0, 64]
+ @ivar yafrayAntiAliasingSamples: Number of samples per pass.
+ @type yafrayAntiAliasingSamples: int [0, 2048]
+ @ivar yafrayAntiAliasingPixelSize: Anti-aliasing pixel filter size.
+ @type yafrayAntiAliasingPixelSize: float [1.0, 2.0]
+ @ivar yafrayAntiAliasingThreshold: Anti-aliasing threshold.
+ @type yafrayAntiAliasingThreshold: float [0.05, 1.0]
+ @ivar yafrayGICache: Cache occlusion/irradiance samples (faster).
+ @type yafrayGICache: boolean
+ @ivar yafrayGICacheBumpNormals: Enable/disable bumpnormals for cache.
+ @type yafrayGICacheBumpNormals: boolean
+ @ivar yafrayGICacheShadowQuality: Shadow quality, keep it under 0.95 :-).
+ @type yafrayGICacheShadowQuality: float [0.01, 1.0]
+ @ivar yafrayGICachePixelsPerSample: Maximum number of pixels without samples, the lower the better and slower.
+ @type yafrayGICachePixelsPerSample: int [1, 50]
+ @ivar yafrayGICacheRefinement: Threshold to refine shadows EXPERIMENTAL. 1 = no refinement.
+ @type yafrayGICacheRefinement: float [0.001, 1.0]
+ @ivar yafrayGIPhotons: Enable/disable use of global photons to help in GI.
+ @type yafrayGIPhotons: boolean
+ @ivar yafrayGITunePhotons: If true the photonmap is shown directly in the render for tuning.
+ @type yafrayGITunePhotons: boolean
+ @ivar bakeMode: The method used when baking, see L{BakeModes}.
+ @type bakeMode: int
+ @ivar bakeNormalSpace: The method used when baking, see L{BakeNormalSpaceModes}.
+ @type bakeNormalSpace: int
+ @ivar bakeClear: When enabled, baking clears the image first.
+ @type bakeClear: bool
+ @ivar bakeToActive: When enabled, selected objects are baked onto the active object.
+ @type bakeToActive: bool
+ @ivar bakeNormalizeAO: Normalize AO bake values.
+ @type bakeNormalizeAO: bool
+ @ivar bakeMargin: The pixel distance to extend baked pixels past the boundry (reduces bleeding when mipmapping)
+ @type bakeMargin: int
+ @ivar bakeDist: The distance in blender units to use when bakeToActive is enabled and geomtry does not overlap.
+ @type bakeDist: float
+ @ivar bakeBias: The distance in blender units to bias faces further away from the object.
+ @type bakeBias: float
"""
-
+
def currentFrame(frame = None):
"""
Get/set the current frame.
@@ -340,6 +415,11 @@ class RenderData:
Render the scene.
"""
+ def bake():
+ """
+ Bake selected objects in the scene.
+ """
+
def renderAnim():
"""
Render a series of frames to an output directory.
@@ -390,6 +470,15 @@ class RenderData:
sequences.
"""
+ def getFrameFilename( frame ):
+ """
+ Get the filename used for the remdered image.
+ @type frame: int
+ @param frame: the frame to use in the filename, if no argument given, use the current frame.
+ @rtype: string
+ @return: Returns the filename that blender would render to, taking into account output path, extension and frame number.
+ """
+
def setBackbufPath(path):
"""
Set the path to a background image and load it.
@@ -824,6 +913,21 @@ class RenderData:
- HIGH
- HIGHER
- BEST
+ - USEAOSETTINGS
+ """
+
+ def getYafrayGIQuality():
+ """
+ Get yafray global Illumination quality.
+ @rtype: enum constant
+ @return: one of 6 constants:
+ - NONE
+ - LOW
+ - MEDIUM
+ - HIGH
+ - HIGHER
+ - BEST
+ - USEAOSETTINGS
"""
def setYafrayGIMethod(type):
@@ -836,6 +940,17 @@ class RenderData:
- GIFULL: Use Full method
"""
+ def getYafrayGIMethod():
+ # (dietrich) 2007/06/01
+ """
+ Get yafray global Illumination method.
+ @rtype: enum constant -
+ @return: Current yafray global illumination method:
+ - NONE: Do not use GI illumination
+ - SKYDOME: Use Skydome method
+ - GIFULL: Use Full method
+ """
+
def yafrayGIPower(power = None):
"""
Get/set GI lighting intensity scale.
@@ -1005,15 +1120,6 @@ class RenderData:
@return: Current exposure adjustment for the scene.
"""
- def yafrayProcessorCount(count = None):
- """
- Get/set number of processors to use.
- @type count: int (optional)
- @param count: must be between 1 - 8
- @rtype: int (if prototype is empty)
- @return: Current number of processors for the scene.
- """
-
def enableGameFrameStretch():
"""
Enable stretch or squeeze the viewport to fill the display window.
diff --git a/source/blender/python/api2_2x/doc/Scene.py b/source/blender/python/api2_2x/doc/Scene.py
index 93d3e7d830e..caa5b56e8d5 100644
--- a/source/blender/python/api2_2x/doc/Scene.py
+++ b/source/blender/python/api2_2x/doc/Scene.py
@@ -117,6 +117,16 @@ class Scene:
@ivar render: The scenes L{render<Render.RenderData>} settings. (read only)
@type radiosity: RenderData
@ivar radiosity: The scenes L{radiosity<Radio>} settings. (read only)
+ @type halfFloat: OpenEXR's half float option
+ @ivar halfFloat: boolean
+ @type zbuf: OpenEXR's save zbuf option
+ @ivar zbuf: boolean
+ @type preview: OpenEXR's save preview option
+ @ivar preview: boolean
+ @type touch: enable creating empty image files while they are rendered.
+ @ivar touch: boolean
+ @type noOverwrite: Skip rendering existing image files
+ @ivar noOverwrite: boolean
"""
def getName():
@@ -357,6 +367,8 @@ class SceneObjects:
@type context: sequence of L{Object}
@ivar active: the active object in the scene.
@type active: L{Object}
+ @ivar camera: the active camera in the scene.
+ @type camera: L{Object}
"""
def new(data):
diff --git a/source/blender/python/api2_2x/doc/Text3d.py b/source/blender/python/api2_2x/doc/Text3d.py
index 78993b9e8f3..a7d8c585078 100644
--- a/source/blender/python/api2_2x/doc/Text3d.py
+++ b/source/blender/python/api2_2x/doc/Text3d.py
@@ -153,13 +153,13 @@ class Text3d:
@param width: The new text3d's width value.
"""
- def getgetExtrudeDepth():
+ def getExtrudeDepth():
"""
Get the text3d's ext1 value.
@rtype: float
"""
- def setgetExtrudeDepth(ext1):
+ def setExtrudeDepth(ext1):
"""
Set the text3d's ext1 value.
@rtype: None
diff --git a/source/blender/python/api2_2x/doc/Texture.py b/source/blender/python/api2_2x/doc/Texture.py
index 9b1c3e0d7d3..184d769171f 100644
--- a/source/blender/python/api2_2x/doc/Texture.py
+++ b/source/blender/python/api2_2x/doc/Texture.py
@@ -59,6 +59,10 @@ Example::
- NEGALPHA - Reverse the alpha value
- CHECKER_ODD - Fill the "odd" checkerboard tiles
- CHECKER_EVEN - Fill the "even" checkerboard tiles
+ - COLORBAND - Enable colorband for this texture
+ - PREVIEW_ALPHA - Show alpha in preview
+ - REPEAT_XMIR - Mirrors X direction repeat
+ - REPEAT_YMIR - Mirrors Y direction repeat
@type ImageFlags: readonly dictionary
@var ImageFlags: The available image flags for Texture.imageFlags:
@@ -428,7 +432,7 @@ class Texture:
"""
Set the Image of this texture.
@param image: The new Image.
- @type image: Blender Image
+ @type image: Blender Image or None.
@warning: This sets the texture's type to 'Image' if it is not already.
"""
@@ -476,7 +480,7 @@ class Texture:
The return value is a 4D vector where (x,y,z,w) are (red, green, blue, intensity)
For greyscale textures, often intensity only will be used.
- @type coord: vector
+ @type coord: vector or tuple of 3 numbers
"""
import id_generics
@@ -528,6 +532,8 @@ class MTex:
@ivar mtAmb: How texture maps to ambient value
@ivar mtDisp: How texture maps to displacement
@ivar mtWarp: How texture maps to warp
+ @ivar uvlayer: The name of the UV Layer this texture is mapped to (when left blank uses render layer)
+ @type uvlayer: string
"""
def getIpo():
diff --git a/source/blender/python/api2_2x/doc/Window.py b/source/blender/python/api2_2x/doc/Window.py
index 7624a983e79..1625e4d4082 100644
--- a/source/blender/python/api2_2x/doc/Window.py
+++ b/source/blender/python/api2_2x/doc/Window.py
@@ -210,6 +210,20 @@ def SetCursorPos (coords):
can be done with L{Redraw}.
"""
+def GetPivot ():
+ """
+ Get the pivot for the active 3D view.
+ @rtype: int
+ @return: constant - Window.PivotTypes
+ """
+
+def SetPivot (pivot):
+ """
+ Set the pivot on the active 3D view.
+ @type pivot: int
+ @param pivot: constant - Window.PivotTypes
+ """
+
def WaitCursor (bool):
"""
Set cursor to wait or back to normal mode.
@@ -284,13 +298,31 @@ def EditMode(enable = -1, undo_msg = 'From script', undo = 1):
because the normal mesh will be rebuilt based on its unchanged edit mesh.
"""
-def ViewLayers (layers = []):
+def PoseMode(enable = -1):
+ """
+ Get and optionally set the current pose mode status: in or out.
+ @type enable: int
+ @param enable: get/set current status:
+ - -1: just return current status (default);
+ - 0: leave edit mode;
+ - 1: enter edit mode.
+
+ @return: 0 if Blender is not in edit mode right now, 1 otherwise.
+ @warn: This uses the active armature objects posemode status, enabling pose
+ mode for non armature objects will always fail.
+ """
+
+def ViewLayers (layers = [], winid = None):
"""
Get and optionally set the currently visible layers in all 3d Views.
@type layers: list of ints
@param layers: a list with indexes of the layers that will be visible. Each
index must be in the range [1, 20]. If not given or equal to [], the
function simply returns the visible ones without changing anything.
+ @type winid: window id from as redurned by GetScreenInfo
+ @param winid: An optional argument to set the layer of a window
+ rather then setting the scene layers. For this to display in the 3d view
+ the layer lock must be disabled (unlocked).
@rtype: list of ints
@return: the currently visible layers.
"""
@@ -402,6 +434,12 @@ def QHandle (winId):
@param winId: the window id, see L{GetScreenInfo}.
@note: see L{QAdd} for how to send events to a particular window.
"""
+def TestBreak ():
+ """
+ Return true if the user has pressed escape
+ @rtype: bool
+ @return: a boolean from a test if the user pressed escape
+ """
def GetMouseCoords ():
"""
diff --git a/source/blender/python/api2_2x/doc/epy_docgen-3.sh b/source/blender/python/api2_2x/doc/epy_docgen-3.sh
new file mode 100644
index 00000000000..ce2bdfef0f8
--- /dev/null
+++ b/source/blender/python/api2_2x/doc/epy_docgen-3.sh
@@ -0,0 +1,12 @@
+# epy_docgen.sh
+# generates blender python doc using epydoc
+# requires epydoc in your PATH.
+# run from the doc directory containing the .py files
+# usage: sh epy_docgen.sh
+
+# set posix locale so regex works properly for [A-Z]*.py
+LC_ALL=POSIX
+
+epydoc -v -o BPY_API --url "http://www.blender.org" --top API_intro \
+ --name "Blender" --no-private --no-frames \
+$( ls [A-Z]*.py )
diff --git a/source/blender/python/api2_2x/euler.c b/source/blender/python/api2_2x/euler.c
index 8816c286943..53489e0f737 100644
--- a/source/blender/python/api2_2x/euler.c
+++ b/source/blender/python/api2_2x/euler.c
@@ -347,6 +347,7 @@ static PyObject *Euler_slice(EulerObject * self, int begin, int end)
int count;
CLAMP(begin, 0, 3);
+ if (end<0) end= 4+end;
CLAMP(end, 0, 3);
begin = MIN2(begin,end);
@@ -368,6 +369,7 @@ static int Euler_ass_slice(EulerObject * self, int begin, int end,
PyObject *e, *f;
CLAMP(begin, 0, 3);
+ if (end<0) end= 4+end;
CLAMP(end, 0, 3);
begin = MIN2(begin,end);
diff --git a/source/blender/python/api2_2x/gen_library.c b/source/blender/python/api2_2x/gen_library.c
index 1e9470f8dcf..8673fefdbb5 100644
--- a/source/blender/python/api2_2x/gen_library.c
+++ b/source/blender/python/api2_2x/gen_library.c
@@ -76,7 +76,7 @@ int GenericLib_setFakeUser( void *self, PyObject *value )
param = PyObject_IsTrue( value );
if( param == -1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected int argument in range [0,1]" );
+ "expected True/False or 0/1" );
if (param) {
if (!(id->flag & LIB_FAKEUSER)) {
@@ -325,14 +325,8 @@ PyObject *GetPyObjectFromID( ID * id )
Py_RETURN_NONE;
}
-/* return a unique tuple for this libdata*/
-long GenericLib_hash(PyObject * pydata)
+long GenericLib_hash(BPy_GenericLib * pydata)
{
- ID *id = ((BPy_GenericLib *)pydata)->id;
- PyObject *pyhash = PyTuple_New( 2 );
- PyTuple_SetItem( pyhash, 0, PyString_FromString(id->name) );
- if (id->lib) PyTuple_SetItem( pyhash, 0, PyString_FromString(id->lib->name) );
- else PyTuple_SetItem( pyhash, 1, Py_None );
- return PyObject_Hash(pyhash);
+ return (long)pydata->id;
}
diff --git a/source/blender/python/api2_2x/gen_library.h b/source/blender/python/api2_2x/gen_library.h
index 74f34fd0019..277421ec089 100644
--- a/source/blender/python/api2_2x/gen_library.h
+++ b/source/blender/python/api2_2x/gen_library.h
@@ -62,7 +62,7 @@
NULL},\
{"tag",\
(getter)GenericLib_getTag, (setter)GenericLib_setTag,\
- "temproary tag",\
+ "temporary tag",\
NULL}
/* Dummy struct for getting the ID from a libdata BPyObject */
@@ -90,5 +90,5 @@ short GenericLib_getType(PyObject * pydata);
/* Other ID functions */
ID *GetIdFromList( ListBase * list, char *name );
PyObject *GetPyObjectFromID( ID * id );
-long GenericLib_hash(PyObject * pydata);
+long GenericLib_hash(BPy_GenericLib * pydata);
#endif /* EXPP_gen_library_h */
diff --git a/source/blender/python/api2_2x/gen_utils.c b/source/blender/python/api2_2x/gen_utils.c
index c38e9daeb3f..780712dac7b 100644
--- a/source/blender/python/api2_2x/gen_utils.c
+++ b/source/blender/python/api2_2x/gen_utils.c
@@ -238,6 +238,10 @@ char *event_to_name( short event )
switch ( event ) {
case SCRIPT_FRAMECHANGED:
return "FrameChanged";
+ case SCRIPT_OBJECTUPDATE:
+ return "ObjectUpdate";
+ case SCRIPT_OBDATAUPDATE:
+ return "ObDataUpdate";
case SCRIPT_ONLOAD:
return "OnLoad";
case SCRIPT_ONSAVE:
@@ -383,29 +387,33 @@ void EXPP_allqueue(unsigned short event, short val)
/************************************************************************/
/* Scriptlink-related functions, used by scene, object, etc. bpyobjects */
/************************************************************************/
-PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
+PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * value,
int is_scene )
{
PyObject *list = NULL, *tmpstr;
- char *eventname = NULL;
+ char *eventname = PyString_AsString(value);
int i, event = 0;
- if( !PyArg_ParseTuple( args, "s", &eventname ) )
+ if( !eventname )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected event name (string) as argument" );
-
- /* actually !scriptlink shouldn't happen ... */
- if( !slink || !slink->totscript )
- return list;
list = PyList_New( 0 );
if( !list )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyList!" );
+ /* actually !scriptlink shouldn't happen ... */
+ if( !slink || !slink->totscript )
+ return list;
+
if( !strcmp( eventname, "FrameChanged" ) )
event = SCRIPT_FRAMECHANGED;
+ else if( !strcmp( eventname, "ObjectUpdate" ) )
+ event = SCRIPT_OBJECTUPDATE;
+ else if( !strcmp( eventname, "ObDataUpdate" ) )
+ event = SCRIPT_OBDATAUPDATE;
else if( !strcmp( eventname, "Redraw" ) )
event = SCRIPT_REDRAW;
else if( !strcmp( eventname, "Render" ) )
@@ -415,7 +423,7 @@ PyObject *EXPP_getScriptLinks( ScriptLink * slink, PyObject * args,
else if( is_scene && !strcmp( eventname, "OnSave" ) )
event = SCRIPT_ONSAVE;
else {
- Py_XDECREF(list);
+ Py_DECREF(list);
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"invalid event name" );
}
@@ -562,6 +570,10 @@ PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene)
if( !strcmp( eventname, "FrameChanged" ) )
event = SCRIPT_FRAMECHANGED;
+ else if( !strcmp( eventname, "ObjectUpdate" ) )
+ event = SCRIPT_OBJECTUPDATE;
+ else if( !strcmp( eventname, "ObDataUpdate" ) )
+ event = SCRIPT_OBDATAUPDATE;
else if( !strcmp( eventname, "Redraw" ) )
event = SCRIPT_REDRAW;
else if( !strcmp( eventname, "Render" ) )
@@ -638,7 +650,7 @@ int EXPP_setIValueClamped( PyObject *value, void *param,
{
int number;
- if( !PyInt_CheckExact ( value ) ) {
+ if( !PyInt_Check( value ) ) {
char errstr[128];
sprintf ( errstr, "expected int argument in [%d,%d]", min, max );
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
@@ -729,7 +741,7 @@ int EXPP_setIValueRange( PyObject *value, void *param,
sprintf ( errstr, "expected int argument in [%d,%d]", min, max );
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check ( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
number = PyInt_AS_LONG( value );
@@ -828,23 +840,27 @@ PyObject *EXPP_getBitfield( void *param, int setting, char type )
int EXPP_setBitfield( PyObject * value, void *param, int setting, char type )
{
- int flag = PyObject_IsTrue( value );
+ int param_bool = PyObject_IsTrue( value );
+ if( param_bool == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
switch ( type ) {
case 'b':
- if ( flag )
+ if ( param_bool )
*(char *)param |= setting;
else
*(char *)param &= ~setting;
return 0;
case 'h':
- if ( flag )
+ if ( param_bool )
*(short *)param |= setting;
else
*(short *)param &= ~setting;
return 0;
case 'i':
- if ( flag )
+ if ( param_bool )
*(int *)param |= setting;
else
*(int *)param &= ~setting;
@@ -914,3 +930,31 @@ int EXPP_dict_set_item_str( PyObject *dict, char *key, PyObject *value)
Py_DECREF( value ); /* delete original */
return ret;
}
+
+/*
+ * Helper function for subtypes that what the base types methods.
+ * The command below needs to have args modified to have 'self' added at the start
+ * ret = PyObject_Call(PyDict_GetItemString(PyList_Type.tp_dict, "sort"), newargs, keywds);
+ *
+ * This is not easy with the python API so adding a function here,
+ * remember to Py_DECREF the tuple after
+ */
+
+PyObject * EXPP_PyTuple_New_Prepend(PyObject *tuple, PyObject *value)
+{
+ PyObject *item;
+ PyObject *new_tuple;
+ int i;
+
+ i = PyTuple_Size(tuple);
+ new_tuple = PyTuple_New(i+1);
+ PyTuple_SetItem(new_tuple, 0, value);
+ Py_INCREF(value);
+ while (i) {
+ i--;
+ item = PyTuple_GetItem(tuple, i);
+ PyTuple_SetItem(new_tuple, i+1, item);
+ Py_INCREF(item);
+ }
+ return new_tuple;
+}
diff --git a/source/blender/python/api2_2x/gen_utils.h b/source/blender/python/api2_2x/gen_utils.h
index 519c7ba9d22..f13722e03d0 100644
--- a/source/blender/python/api2_2x/gen_utils.h
+++ b/source/blender/python/api2_2x/gen_utils.h
@@ -161,7 +161,7 @@ PyObject *EXPP_setterWrapperTuple ( PyObject * self, PyObject * args,
setter func);
/* scriplinks-related: */
-PyObject *EXPP_getScriptLinks(ScriptLink *slink, PyObject *args, int is_scene);
+PyObject *EXPP_getScriptLinks(ScriptLink *slink, PyObject *value, int is_scene);
PyObject *EXPP_addScriptLink(ScriptLink *slink, PyObject *args, int is_scene);
PyObject *EXPP_clearScriptLinks(ScriptLink *slink, PyObject *args);
@@ -170,6 +170,7 @@ void EXPP_allqueue(unsigned short event, short val);
/* helper to keep dictionaries from causing memory leaks */
int EXPP_dict_set_item_str( PyObject *dict, char *key, PyObject *value);
+PyObject * EXPP_PyTuple_New_Prepend(PyObject *tuple, PyObject *value);
#endif /* EXPP_gen_utils_h */
diff --git a/source/blender/python/api2_2x/logic.c b/source/blender/python/api2_2x/logic.c
index f7e8e27c2f5..a09b7fa48e7 100644
--- a/source/blender/python/api2_2x/logic.c
+++ b/source/blender/python/api2_2x/logic.c
@@ -38,7 +38,7 @@
//--------------- Python BPy_Property methods declarations:---------------
static PyObject *Property_getName( BPy_Property * self );
-static PyObject *Property_setName( BPy_Property * self, PyObject * args );
+static PyObject *Property_setName( BPy_Property * self, PyObject * value );
static PyObject *Property_getData( BPy_Property * self );
static PyObject *Property_setData( BPy_Property * self, PyObject * args );
static PyObject *Property_getType( BPy_Property * self );
@@ -46,7 +46,7 @@ static PyObject *Property_getType( BPy_Property * self );
static PyMethodDef BPy_Property_methods[] = {
{"getName", ( PyCFunction ) Property_getName, METH_NOARGS,
"() - return Property name"},
- {"setName", ( PyCFunction ) Property_setName, METH_VARARGS,
+ {"setName", ( PyCFunction ) Property_setName, METH_O,
"() - set the name of this Property"},
{"getData", ( PyCFunction ) Property_getData, METH_NOARGS,
"() - return Property data"},
@@ -175,53 +175,43 @@ static void Property_dealloc( BPy_Property * self )
//---------------getattr--------------------------------------------
static PyObject *Property_getAttr( BPy_Property * self, char *name )
{
- PyObject *attr = Py_None;
-
checkValidData_ptr( self );
if( strcmp( name, "name" ) == 0 )
- attr = Property_getName( self );
+ return Property_getName( self );
else if( strcmp( name, "data" ) == 0 )
- attr = Property_getData( self );
+ return Property_getData( self );
else if( strcmp( name, "type" ) == 0 )
- attr = Property_getType( self );
+ return Property_getType( self );
else if( strcmp( name, "__members__" ) == 0 ) {
- attr = Py_BuildValue( "[s,s,s]", "name", "data", "type" );
+ return Py_BuildValue( "[s,s,s]", "name", "data", "type" );
}
- if( !attr )
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError, "couldn't create PyObject" ) );
-
- if( attr != Py_None )
- return attr;
-
- return Py_FindMethod( BPy_Property_methods, ( PyObject * ) self,
- name );
+ return Py_FindMethod( BPy_Property_methods, ( PyObject * ) self, name );
}
//--------------- setattr-------------------------------------------
static int
Property_setAttr( BPy_Property * self, char *name, PyObject * value )
{
- PyObject *valtuple;
PyObject *error = NULL;
checkValidData_ptr( self );
- valtuple = Py_BuildValue( "(O)", value );
- if( !valtuple )
- return EXPP_ReturnIntError( PyExc_MemoryError,
- "PropertySetAttr: couldn't create tuple" );
- if( strcmp( name, "name" ) == 0 )
- error = Property_setName( self, valtuple );
- else if( strcmp( name, "data" ) == 0 )
+ if( strcmp( name, "name" ) == 0 ) {
+ error = Property_setName( self, value );
+ } else if( strcmp( name, "data" ) == 0 ) {
+ PyObject *valtuple = Py_BuildValue( "(O)", value );
+ if( !valtuple )
+ return EXPP_ReturnIntError( PyExc_MemoryError,
+ "PropertySetAttr: couldn't create tuple" );
+
error = Property_setData( self, valtuple );
- else {
Py_DECREF( valtuple );
+ } else {
return ( EXPP_ReturnIntError
( PyExc_KeyError, "attribute not found" ) );
}
- Py_DECREF( valtuple );
+
if( error != Py_None )
return -1;
@@ -380,26 +370,18 @@ PyObject *newPropertyObject( char *name, PyObject * data, int type )
//--------------- BPy_Property.getName()----------------------------
static PyObject *Property_getName( BPy_Property * self )
{
- PyObject *attr = NULL;
-
if( !self->property )
- attr = PyString_FromString( self->name );
+ return PyString_FromString( self->name );
else
- attr = PyString_FromString( self->property->name );
-
- if( attr )
- return attr;
-
- return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Property.name attribute" ) );
+ return PyString_FromString( self->property->name );
}
//--------------- BPy_Property.setName()----------------------------
-static PyObject *Property_setName( BPy_Property * self, PyObject * args )
+static PyObject *Property_setName( BPy_Property * self, PyObject * value )
{
- char *name;
+ char *name = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected string argument" ) );
@@ -410,7 +392,7 @@ static PyObject *Property_setName( BPy_Property * self, PyObject * args )
updatePyProperty( self );
}
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
//--------------- BPy_Property.getData()----------------------------
@@ -441,7 +423,7 @@ static PyObject *Property_getData( BPy_Property * self )
return attr;
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "couldn't get Property.name attribute" ) );
+ "couldn't get Property.data attribute" ) );
}
//--------------- BPy_Property.setData()----------------------------
@@ -520,13 +502,12 @@ static PyObject *Property_setData( BPy_Property * self, PyObject * args )
} else {
self->data = data;
}
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
//--------------- BPy_Property.getType()----------------------------
static PyObject *Property_getType( BPy_Property * self )
{
- PyObject *attr = Py_None;
int type;
if( self->property )
@@ -535,15 +516,14 @@ static PyObject *Property_getType( BPy_Property * self )
type = self->type;
if( type == PROP_BOOL )
- attr = PyString_FromString( "BOOL" );
+ return PyString_FromString( "BOOL" );
else if( type == PROP_INT )
- attr = PyString_FromString( "INT" );
+ return PyString_FromString( "INT" );
else if( type == PROP_FLOAT )
- attr = PyString_FromString( "FLOAT" );
+ return PyString_FromString( "FLOAT" );
else if( type == PROP_STRING )
- attr = PyString_FromString( "STRING" );
+ return PyString_FromString( "STRING" );
else if( type == PROP_TIME )
- attr = PyString_FromString( "TIME" );
-
- return attr;
+ return PyString_FromString( "TIME" );
+ Py_RETURN_NONE;
}
diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c
index 6a427bfe7f6..fadadbb5c6a 100644
--- a/source/blender/python/api2_2x/matrix.c
+++ b/source/blender/python/api2_2x/matrix.c
@@ -202,16 +202,27 @@ PyObject *Matrix_RotationPart(MatrixObject * self)
/*---------------------------Matrix.scalePart() --------------------*/
PyObject *Matrix_scalePart(MatrixObject * self)
{
- float scale[3];
-
+ float scale[3], rot[3];
+ float mat[3][3], imat[3][3], tmat[3][3];
+
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- Mat4ToSize((float (*)[4])*self->matrix, scale);
+ Mat3CpyMat4(mat, (float (*)[4])*self->matrix);
else if(self->colSize == 3 && self->rowSize == 3)
- Mat3ToSize((float (*)[3])*self->matrix, scale);
+ Mat3CpyMat3(mat, (float (*)[3])*self->matrix);
else
return EXPP_ReturnPyObjError(PyExc_AttributeError,
"Matrix.scalePart(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
+
+ /* functionality copied from editobject.c apply_obmat */
+ Mat3ToEul(mat, rot);
+ EulToMat3(rot, tmat);
+ Mat3Inv(imat, tmat);
+ Mat3MulMat3(tmat, imat, mat);
+
+ scale[0]= tmat[0][0];
+ scale[1]= tmat[1][1];
+ scale[2]= tmat[2][2];
return newVectorObject(scale, 3, Py_NEW);
}
/*---------------------------Matrix.invert() ---------------------*/
diff --git a/source/blender/python/api2_2x/quat.c b/source/blender/python/api2_2x/quat.c
index 09b7ef5fe3c..a4a99c28d72 100644
--- a/source/blender/python/api2_2x/quat.c
+++ b/source/blender/python/api2_2x/quat.c
@@ -184,13 +184,13 @@ static PyObject *Quaternion_getattr(QuaternionObject * self, char *name)
}
if(STREQ(name, "angle")) {
mag = self->quat[0];
- mag = 2 * (acos(mag));
+ mag = 2 * (saacos(mag));
mag *= (180 / Py_PI);
return PyFloat_FromDouble(mag);
}
if(STREQ(name, "axis")) {
mag = self->quat[0] * (Py_PI / 180);
- mag = 2 * (acos(mag));
+ mag = 2 * (saacos(mag));
mag = sin(mag / 2);
for(x = 0; x < 3; x++) {
vec[x] = (float)(self->quat[x + 1] / mag);
@@ -350,6 +350,7 @@ static PyObject *Quaternion_slice(QuaternionObject * self, int begin, int end)
int count;
CLAMP(begin, 0, 4);
+ if (end<0) end= 5+end;
CLAMP(end, 0, 4);
begin = MIN2(begin,end);
@@ -371,6 +372,7 @@ static int Quaternion_ass_slice(QuaternionObject * self, int begin, int end,
PyObject *q, *f;
CLAMP(begin, 0, 4);
+ if (end<0) end= 5+end;
CLAMP(end, 0, 4);
begin = MIN2(begin,end);
diff --git a/source/blender/python/api2_2x/rgbTuple.c b/source/blender/python/api2_2x/rgbTuple.c
index cdd05a60917..d8bfd930752 100644
--- a/source/blender/python/api2_2x/rgbTuple.c
+++ b/source/blender/python/api2_2x/rgbTuple.c
@@ -86,10 +86,10 @@ PyTypeObject rgbTuple_Type = {
PyObject_HEAD_INIT( NULL )
0, /* ob_size */
"rgbTuple", /* tp_name */
- sizeof( BPy_rgbTuple ), /* tp_basicsize */
+ sizeof( BPy_rgbTuple ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- NULL, /* tp_dealloc */
+ 0, /* tp_dealloc */
0, /* tp_print */
( getattrfunc ) rgbTuple_getAttr, /* tp_getattr */
( setattrfunc ) rgbTuple_setAttr, /* tp_setattr */
@@ -99,11 +99,31 @@ PyTypeObject rgbTuple_Type = {
&rgbTupleAsSequence, /* tp_as_sequence */
&rgbTupleAsMapping, /* tp_as_mapping */
0, /* tp_as_hash */
- 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, Py_TPFLAGS_DEFAULT,
0, /* tp_doc */
0, 0, 0, 0, 0, 0,
0, /* tp_methods */
0, /* tp_members */
+ 0, /* struct PyGetSetDef *tp_getset; */
+ 0, /* struct _typeobject *tp_base; */
+ 0, /* PyObject *tp_dict; */
+ 0, /* descrgetfunc tp_descr_get; */
+ 0, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ 0, /* initproc tp_init; */
+ 0, /* allocfunc tp_alloc; */
+ 0, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ 0, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ 0, /* inquiry tp_is_gc; */
+ 0, /* PyObject *tp_bases; */
+ /* method resolution order */
+ 0, /* PyObject *tp_mro; */
+ 0, /* PyObject *tp_cache; */
+ 0, /* PyObject *tp_subclasses; */
+ 0, /* PyObject *tp_weaklist; */
+ 0
};
/*****************************************************************************/
@@ -111,13 +131,7 @@ PyTypeObject rgbTuple_Type = {
/*****************************************************************************/
PyObject *rgbTuple_New( float *rgb[3] )
{
- BPy_rgbTuple *rgbTuple;
-
- rgbTuple_Type.ob_type = &PyType_Type;
-
- rgbTuple =
- ( BPy_rgbTuple * ) PyObject_NEW( BPy_rgbTuple,
- &rgbTuple_Type );
+ BPy_rgbTuple *rgbTuple = PyObject_NEW( BPy_rgbTuple, &rgbTuple_Type );
if( rgbTuple == NULL )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
@@ -138,12 +152,8 @@ PyObject *rgbTuple_New( float *rgb[3] )
/*****************************************************************************/
PyObject *rgbTuple_getCol( BPy_rgbTuple * self )
{
- PyObject *attr = Py_BuildValue( "[fff]", *(self->rgb[0]),
+ return Py_BuildValue( "[fff]", *(self->rgb[0]),
*(self->rgb[1]), *(self->rgb[2]));
- if( !attr )
- return EXPP_ReturnPyObjError( PyExc_MemoryError,
- "Py_BuildValue() failed" );
- return attr;
}
int rgbTuple_setCol( BPy_rgbTuple * self, PyObject * args )
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index 89e25e790de..4bf823bc938 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
- * Contributor(s): Joseph Gilbert
+ * Contributor(s): Joseph Gilbert, Dietrich Bollmann
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -33,16 +33,21 @@ struct View3D; /* keep me up here */
#include "sceneRender.h" /*This must come first*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_image_types.h"
+#include "DNA_node_types.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_scene.h"
+#include "BKE_node.h"
#include "BIF_drawscene.h"
#include "BIF_renderwin.h"
#include "BIF_writeimage.h"
+#include "BIF_meshtools.h"
#include "BLI_blenlib.h"
@@ -52,18 +57,21 @@ struct View3D; /* keep me up here */
#include "butspace.h"
#include "blendef.h"
#include "gen_utils.h"
+#include "gen_library.h"
#include "Scene.h"
+#include "Group.h"
/* local defines */
-#define PY_NONE 0
-#define PY_LOW 1
-#define PY_MEDIUM 2
-#define PY_HIGH 3
-#define PY_HIGHER 4
-#define PY_BEST 5
-#define PY_SKYDOME 1
-#define PY_FULL 2
+#define PY_NONE 0
+#define PY_LOW 1
+#define PY_MEDIUM 2
+#define PY_HIGH 3
+#define PY_HIGHER 4
+#define PY_BEST 5
+#define PY_USEAOSETTINGS 6
+#define PY_SKYDOME 1
+#define PY_FULL 2
enum rend_constants {
EXPP_RENDER_ATTR_XPARTS = 0,
@@ -74,10 +82,16 @@ enum rend_constants {
EXPP_RENDER_ATTR_SFRAME,
EXPP_RENDER_ATTR_EFRAME,
EXPP_RENDER_ATTR_FPS,
+ EXPP_RENDER_ATTR_FPS_BASE,
EXPP_RENDER_ATTR_SIZEX,
EXPP_RENDER_ATTR_SIZEY,
EXPP_RENDER_ATTR_GAUSSFILTER,
EXPP_RENDER_ATTR_MBLURFACTOR,
+ EXPP_RENDER_ATTR_BAKEMARGIN,
+ EXPP_RENDER_ATTR_BAKEMODE,
+ EXPP_RENDER_ATTR_BAKEDIST,
+ EXPP_RENDER_ATTR_BAKENORMALSPACE,
+ EXPP_RENDER_ATTR_BAKEBIAS
};
#define EXPP_RENDER_ATTR_CFRA 2
@@ -114,8 +128,6 @@ static PyObject *RenderData_SetRenderPath( BPy_RenderData *self,
PyObject *args );
static PyObject *RenderData_SetBackbufPath( BPy_RenderData *self,
PyObject *args );
-static PyObject *RenderData_SetFtypePath( BPy_RenderData *self,
- PyObject *args );
static PyObject *RenderData_SetOversamplingLevel( BPy_RenderData * self,
PyObject * args );
static PyObject *RenderData_SetRenderWinSize( BPy_RenderData * self,
@@ -127,6 +139,7 @@ static PyObject *RenderData_SetRenderer( BPy_RenderData * self,
static PyObject *RenderData_SetImageType( BPy_RenderData * self,
PyObject * args );
static PyObject *RenderData_Render( BPy_RenderData * self );
+static PyObject *RenderData_Bake( BPy_RenderData * self );
/* BPy_RenderData Internal Protocols */
@@ -284,7 +297,8 @@ static PyObject *M_Render_GetSetAttributeInt( PyObject * args, int *structure,
static void M_Render_DoSizePreset( BPy_RenderData * self, short xsch,
short ysch, short xasp, short yasp,
short size, short xparts, short yparts,
- short frames, float a, float b, float c,
+ short fps, float fps_base,
+ float a, float b, float c,
float d )
{
self->renderContext->xsch = xsch;
@@ -292,7 +306,8 @@ static void M_Render_DoSizePreset( BPy_RenderData * self, short xsch,
self->renderContext->xasp = xasp;
self->renderContext->yasp = yasp;
self->renderContext->size = size;
- self->renderContext->frs_sec = frames;
+ self->renderContext->frs_sec = fps;
+ self->renderContext->frs_sec_base = fps_base;
self->renderContext->xparts = xparts;
self->renderContext->yparts = yparts;
@@ -301,6 +316,85 @@ static void M_Render_DoSizePreset( BPy_RenderData * self, short xsch,
EXPP_allqueue( REDRAWVIEWCAM, 0 );
}
+/** set / get boolean */
+
+static int M_Render_setBooleanShort( BPy_RenderData * self, PyObject *value, short* var )
+{
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected boolean value" );
+
+ *var = (PyInt_AsLong( value )) ? 1 : 0;
+
+ EXPP_allqueue( REDRAWBUTSSCENE, 0 );
+ return 0;
+}
+
+static PyObject *M_Render_getBooleanShort( BPy_RenderData * self, short var )
+{
+ return PyInt_FromLong( (long) var );
+}
+
+/** set / get float */
+
+static int M_Render_setFloat( BPy_RenderData *self, PyObject *value, float *var, float min, float max )
+{
+ float val;
+ char error[48];
+
+ if( !PyFloat_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected float value" );
+
+ val = (float) PyFloat_AsDouble( value );
+
+ /* check range */
+ if ( val < min || val > max ) {
+ sprintf( error, "out of range - expected %f to %f", min, max );
+ return EXPP_ReturnIntError( PyExc_TypeError,error );
+ }
+
+ *var = val;
+
+ EXPP_allqueue( REDRAWBUTSSCENE, 0 );
+ return 0;
+}
+
+static PyObject *M_Render_getFloat( BPy_RenderData *self, float var )
+{
+ return PyFloat_FromDouble( (double) var );
+}
+
+/** set / get integer */
+
+static int M_Render_setInt( BPy_RenderData *self, PyObject *value, int *var, int min, int max )
+{
+ int val;
+ char error[48];
+
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected integer value" );
+
+ val = (int) PyInt_AsLong( value );
+
+ /* check range */
+ if ( val < min || val > max ) {
+ sprintf( error, "out of range - expected %d to %d", min, max );
+ return EXPP_ReturnIntError( PyExc_TypeError,error );
+ }
+
+ *var = val;
+
+ EXPP_allqueue( REDRAWBUTSSCENE, 0 );
+ return 0;
+}
+
+static PyObject *M_Render_getInt( BPy_RenderData *self, int var )
+{
+ return PyInt_FromLong( (long) var );
+}
+
/***************************************************************************/
/* Render Module Function Definitions */
/***************************************************************************/
@@ -405,6 +499,28 @@ PyObject *RenderData_Render( BPy_RenderData * self )
Py_RETURN_NONE;
}
+/***************************************************************************/
+/* BPy_Bake Function Definitions */
+/***************************************************************************/
+
+PyObject *RenderData_Bake( BPy_RenderData * self )
+{
+ char *error_msg = NULL;
+ Scene *oldsce;
+
+ oldsce = G.scene;
+ set_scene( self->scene );
+
+ objects_bake_render(0, &error_msg);
+
+ set_scene( oldsce );
+
+ if (error_msg)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError, error_msg );
+
+ Py_RETURN_NONE;
+}
+
/*
* This will save the rendered image to an output file path already defined.
*/
@@ -614,7 +730,7 @@ static int RenderData_setOSALevel( BPy_RenderData * self,
{
int level;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -845,7 +961,7 @@ static int RenderData_setRenderer( BPy_RenderData * self, PyObject * value )
{
int type;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected constant INTERNAL or YAFRAY" );
@@ -876,7 +992,7 @@ static int RenderData_setImageType( BPy_RenderData *self, PyObject *value )
{
int type;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int constant" );
@@ -899,7 +1015,6 @@ static int RenderData_setImageType( BPy_RenderData *self, PyObject *value )
case R_HAMX :
case R_IRIS :
case R_IRIZ :
- case R_FTYPE :
case R_TIFF :
case R_CINEON :
case R_DPX :
@@ -908,6 +1023,7 @@ static int RenderData_setImageType( BPy_RenderData *self, PyObject *value )
#endif
#ifdef WITH_OPENEXR
case R_OPENEXR :
+ case R_MULTILAYER :
#endif
#ifdef WITH_FFMPEG
case R_FFMPEG :
@@ -977,20 +1093,24 @@ PyObject *RenderData_SizePreset( BPy_RenderData * self, PyObject * args )
if( type == B_PR_PAL ) {
M_Render_DoSizePreset( self, 720, 576, 54, 51, 100,
self->renderContext->xparts,
- self->renderContext->yparts, 25, 0.1f,
+ self->renderContext->yparts, 25, 1.0f,
+ 0.1f,
0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_NTSC ) {
M_Render_DoSizePreset( self, 720, 480, 10, 11, 100, 1, 1,
- 30, 0.1f, 0.9f, 0.1f, 0.9f );
+ 30, 1.001f,
+ 0.1f, 0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PRESET ) {
M_Render_DoSizePreset( self, 720, 576, 54, 51, 100, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode = R_OSA + R_SHADOW + R_FIELDS;
self->renderContext->imtype = R_TARGA;
@@ -998,34 +1118,42 @@ PyObject *RenderData_SizePreset( BPy_RenderData * self, PyObject * args )
0.9f );
} else if( type == B_PR_PRV ) {
M_Render_DoSizePreset( self, 640, 512, 1, 1, 50, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PC ) {
M_Render_DoSizePreset( self, 640, 480, 100, 100, 100, 1, 1,
- self->renderContext->frs_sec, 0.0f, 1.0f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.0f, 1.0f,
0.0f, 1.0f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.0f, 1.0f, 0.0f,
1.0f );
} else if( type == B_PR_PAL169 ) {
M_Render_DoSizePreset( self, 720, 576, 64, 45, 100, 1, 1,
- 25, 0.1f, 0.9f, 0.1f, 0.9f );
+ 25, 1.0f, 0.1f, 0.9f, 0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_PANO ) {
M_Render_DoSizePreset( self, 36, 176, 115, 100, 100, 16, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode |= R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
0.9f );
} else if( type == B_PR_FULL ) {
M_Render_DoSizePreset( self, 1280, 1024, 1, 1, 100, 1, 1,
- self->renderContext->frs_sec, 0.1f, 0.9f,
+ self->renderContext->frs_sec,
+ self->renderContext->frs_sec_base,
+ 0.1f, 0.9f,
0.1f, 0.9f );
self->renderContext->mode &= ~R_PANORAMA;
BLI_init_rctf( &self->renderContext->safety, 0.1f, 0.9f, 0.1f,
@@ -1038,6 +1166,8 @@ PyObject *RenderData_SizePreset( BPy_RenderData * self, PyObject * args )
Py_RETURN_NONE;
}
+/*
+
PyObject *RenderData_SetYafrayGIQuality( BPy_RenderData * self,
PyObject * args )
{
@@ -1077,6 +1207,264 @@ PyObject *RenderData_SetYafrayGIMethod( BPy_RenderData * self,
EXPP_allqueue( REDRAWBUTSSCENE, 0 );
Py_RETURN_NONE;
}
+*/
+
+/* (die) beg */
+
+/* YafRay - Yafray GI Method */
+
+static int RenderData_setYafrayGIQuality( BPy_RenderData * self, PyObject * value )
+{
+ long type;
+
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected constant" );
+
+ type = PyInt_AsLong( value );
+
+ if( type == PY_NONE || type == PY_LOW ||
+ type == PY_MEDIUM || type == PY_HIGH ||
+ type == PY_HIGHER || type == PY_BEST ||
+ type == PY_USEAOSETTINGS
+ ) {
+ self->renderContext->GIquality = (short)type;
+ } else {
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected constant NONE, LOW, MEDIUM, HIGHER or BEST" );
+ }
+
+ EXPP_allqueue( REDRAWBUTSSCENE, 0 );
+ return 0;
+}
+
+static PyObject *RenderData_getYafrayGIQuality( BPy_RenderData * self )
+{
+ return PyInt_FromLong( (long) self->renderContext->GIquality );
+}
+
+static PyObject *RenderData_SetYafrayGIQuality( BPy_RenderData * self,
+ PyObject * args )
+{
+ return EXPP_setterWrapper( (void*) self, args,
+ (setter) RenderData_setYafrayGIQuality );
+}
+
+static PyObject *RenderData_GetYafrayGIQuality( BPy_RenderData * self )
+{
+ return RenderData_getYafrayGIQuality(self);
+}
+
+/* YafRay - Yafray GI Method */
+
+static int RenderData_setYafrayGIMethod( BPy_RenderData * self, PyObject * value )
+{
+ int type;
+
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected constant NONE, SKYDOME or FULL" );
+
+ type = PyInt_AsLong( value );
+ if( type == PY_NONE || type == PY_SKYDOME || type == PY_FULL ) {
+ self->renderContext->GImethod = (short)type;
+ } else {
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected constant NONE, SKYDOME or FULL" );
+ }
+
+ EXPP_allqueue( REDRAWBUTSSCENE, 0 );
+ return 0;
+}
+
+static PyObject *RenderData_getYafrayGIMethod( BPy_RenderData * self )
+{
+ return PyInt_FromLong( (long)self->renderContext->GImethod );
+}
+
+static PyObject *RenderData_GetYafrayGIMethod( BPy_RenderData * self )
+{
+ return RenderData_getYafrayGIMethod(self);
+}
+
+static PyObject *RenderData_SetYafrayGIMethod( BPy_RenderData * self,
+ PyObject * args )
+{
+ return EXPP_setterWrapper( (void *)self, args,
+ (setter)RenderData_setYafrayGIMethod );
+}
+
+
+/* YafRay - Export to XML */
+
+static int RenderData_setYafrayExportToXML( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->YFexportxml );
+}
+
+static PyObject *RenderData_getYafrayExportToXML( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->YFexportxml );
+}
+
+/** Auto AA */
+
+static int RenderData_setYafrayAutoAntiAliasing( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->YF_AA );
+}
+
+static PyObject *RenderData_getYafrayAutoAntiAliasing( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->YF_AA );
+}
+
+/** Clamp RGB */
+
+static int RenderData_setYafrayClampRGB( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->YF_clamprgb );
+}
+
+static PyObject *RenderData_getYafrayClampRGB( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->YF_clamprgb );
+}
+
+/** YafRay - Anti-Aliasing Passes */
+
+static int RenderData_setYafrayAntiAliasingPasses( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setInt( self, value, &self->renderContext->YF_AApasses, 0, 64 );
+}
+
+static PyObject *RenderData_getYafrayAntiAliasingPasses( BPy_RenderData * self )
+{
+ return M_Render_getInt( self, self->renderContext->YF_AApasses );
+}
+
+/** YafRay - Anti-Aliasing Samples */
+
+static int RenderData_setYafrayAntiAliasingSamples( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setInt( self, value, &self->renderContext->YF_AAsamples, 0, 2048 );
+}
+
+static PyObject *RenderData_getYafrayAntiAliasingSamples( BPy_RenderData * self )
+{
+ return M_Render_getInt( self, self->renderContext->YF_AAsamples );
+}
+
+/* YafRay - Anti-Aliasing Pixel Filter Size */
+
+static int RenderData_setYafrayAntiAliasingPixelSize( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setFloat( self, value, &self->renderContext->YF_AApixelsize, 1.0, 2.0 );
+}
+
+static PyObject *RenderData_getYafrayAntiAliasingPixelSize( BPy_RenderData * self )
+{
+ return M_Render_getFloat( self, self->renderContext->YF_AApixelsize );
+}
+
+/* YafRay - Anti-Aliasing threshold */
+
+static int RenderData_setYafrayAntiAliasingThreshold( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setFloat( self, value, &self->renderContext->YF_AAthreshold, 0.05, 1.0 );
+}
+
+static PyObject *RenderData_getYafrayAntiAliasingThreshold( BPy_RenderData * self )
+{
+ return M_Render_getFloat( self, self->renderContext->YF_AAthreshold );
+}
+
+/* YafRay - Cache occlusion/irradiance samples (faster) */
+
+static int RenderData_setYafrayGICache( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->GIcache );
+}
+
+static PyObject *RenderData_getYafrayGICache( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->GIcache );
+}
+
+/* YafRay - Enable/disable bumpnormals for cache
+ (faster, but no bumpmapping in total indirectly lit areas) */
+
+static int RenderData_setYafrayGICacheBumpNormals( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->YF_nobump );
+}
+
+static PyObject *RenderData_getYafrayGICacheBumpNormals( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->YF_nobump );
+}
+
+/* YafRay - Shadow quality, keep it under 0.95 :-) */
+
+static int RenderData_setYafrayGICacheShadowQuality( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setFloat( self, value, &self->renderContext->GIshadowquality, 0.01, 1.0 );
+}
+
+static PyObject *RenderData_getYafrayGICacheShadowQuality( BPy_RenderData * self )
+{
+ return M_Render_getFloat( self, self->renderContext->GIshadowquality );
+}
+
+/* YafRay - Threshold to refine shadows EXPERIMENTAL. 1 = no refinement */
+
+static int RenderData_setYafrayGICacheRefinement( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setFloat( self, value, &self->renderContext->GIrefinement, 0.001, 1.0 );
+}
+
+static PyObject *RenderData_getYafrayGICacheRefinement( BPy_RenderData * self )
+{
+ return M_Render_getFloat( self, self->renderContext->GIrefinement );
+}
+
+/* YafRay - Maximum number of pixels without samples, the lower the better and slower */
+
+static int RenderData_setYafrayGICachePixelsPerSample( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setInt( self, value, &self->renderContext->GIpixelspersample, 1, 50 );
+}
+
+static PyObject *RenderData_getYafrayGICachePixelsPerSample( BPy_RenderData * self )
+{
+ return M_Render_getInt( self, self->renderContext->GIpixelspersample );
+}
+
+/** YafRay - Enable/disable use of global photons to help in GI */
+
+static int RenderData_setYafrayGIPhotons( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->GIphotons );
+}
+
+static PyObject *RenderData_getYafrayGIPhotons( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->GIphotons );
+}
+
+/** YafRay - If true the photonmap is shown directly in the render for tuning */
+
+static int RenderData_setYafrayGITunePhotons( BPy_RenderData * self, PyObject * value )
+{
+ return M_Render_setBooleanShort( self, value, &self->renderContext->GIdirect );
+}
+
+static PyObject *RenderData_getYafrayGITunePhotons( BPy_RenderData * self )
+{
+ return M_Render_getBooleanShort( self, self->renderContext->GIdirect );
+}
+
+/* (die) end */
PyObject *RenderData_YafrayGIPower( BPy_RenderData * self, PyObject * args )
{
@@ -1103,7 +1491,7 @@ PyObject *RenderData_YafrayGIDepth( BPy_RenderData * self, PyObject * args )
if( self->renderContext->GImethod == 2 ) {
return M_Render_GetSetAttributeInt( args,
&self->renderContext->
- GIdepth, 1, 8 );
+ GIdepth, 1, 100 );
} else
return ( EXPP_ReturnPyObjError( PyExc_StandardError,
"YafrayGIMethod must be set to 'FULL'" ) );
@@ -1114,7 +1502,7 @@ PyObject *RenderData_YafrayGICDepth( BPy_RenderData * self, PyObject * args )
if( self->renderContext->GImethod == 2 ) {
return M_Render_GetSetAttributeInt( args,
&self->renderContext->
- GIcausdepth, 1, 8 );
+ GIcausdepth, 1, 100 );
} else
return ( EXPP_ReturnPyObjError( PyExc_StandardError,
"YafrayGIMethod must be set to 'FULL'" ) );
@@ -1151,7 +1539,7 @@ PyObject *RenderData_YafrayGIPhotonCount( BPy_RenderData * self,
&& self->renderContext->GIphotons == 1 ) {
return M_Render_GetSetAttributeInt( args,
&self->renderContext->
- GIphotoncount, 0,
+ GIphotoncount, 100000,
10000000 );
} else
return ( EXPP_ReturnPyObjError( PyExc_StandardError,
@@ -1179,7 +1567,7 @@ PyObject *RenderData_YafrayGIPhotonMixCount( BPy_RenderData * self,
&& self->renderContext->GIphotons == 1 ) {
return M_Render_GetSetAttributeInt( args,
&self->renderContext->
- GImixphotons, 0, 1000 );
+ GImixphotons, 100, 1000 );
} else
return ( EXPP_ReturnPyObjError( PyExc_StandardError,
"YafrayGIMethod must be set to 'FULL' and GIPhotons must be enabled" ) );
@@ -1267,14 +1655,6 @@ PyObject *RenderData_YafrayExposure( BPy_RenderData * self, PyObject * args )
YF_exposure, 0.0f, 10.0f );
}
-PyObject *RenderData_YafrayProcessorCount( BPy_RenderData * self,
- PyObject * args )
-{
- return M_Render_GetSetAttributeInt( args,
- &self->renderContext->YF_numprocs,
- 1, 8 );
-}
-
PyObject *RenderData_EnableGameFrameStretch( BPy_RenderData * self )
{
self->scene->framing.type = SCE_GAMEFRAMING_SCALE;
@@ -1377,9 +1757,11 @@ PyObject *RenderData_NewMapValue( BPy_RenderData * self, PyObject * args )
static PyObject *RenderData_getTimeCode( BPy_RenderData * self) {
char tc[12];
- int h, m, s, fps, cfa;
+ int h, m, s, cfa;
+ double fps;
- fps = self->renderContext->frs_sec;
+ fps = (double) self->renderContext->frs_sec /
+ self->renderContext->frs_sec_base;
cfa = self->renderContext->cfra-1;
s = cfa / fps;
m = s / 60;
@@ -1387,10 +1769,73 @@ static PyObject *RenderData_getTimeCode( BPy_RenderData * self) {
if( h > 99 )
return PyString_FromString("Time Greater than 99 Hours!");
- sprintf( tc, "%02d:%02d:%02d:%02d", h%60, m%60, s%60, cfa%fps);
+ sprintf( tc, "%02d:%02d:%02d:%02d", h%60, m%60, s%60,
+ (int) (cfa - ((int) (cfa / fps) * fps)));
return PyString_FromString(tc);
}
+
+/***************************************************************************/
+/* Render layer functions */
+/***************************************************************************/
+PyObject *RenderData_getRenderLayers(BPy_RenderData * self)
+{
+ PyObject *list, *layer;
+ SceneRenderLayer *srl;
+
+ list = PyList_New(0);
+
+ for(srl= self->renderContext->layers.first; srl; srl= srl->next) {
+ layer = RenderLayer_CreatePyObject( self->scene, srl );
+ PyList_Append(list, layer);
+ Py_DECREF(layer);
+ }
+ return list;
+}
+
+PyObject *RenderData_removeRenderLayer(BPy_RenderData * self, BPy_RenderLayer *value)
+{
+ int index;
+ if (!BPy_RenderLayer_Check(value))
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "can only remove a render layer" );
+
+ index = BLI_findindex(&self->renderContext->layers, value->renderLayer);
+
+ if (index == -1)
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "render layer is not in this scene" );
+
+ if (BLI_countlist(&self->renderContext->layers)<=1)
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "cannot remove the last render layer" );
+
+ BLI_remlink(&self->scene->r.layers, value->renderLayer);
+ MEM_freeN(value->renderLayer);
+ self->scene->r.actlay= 0;
+
+ if(self->scene->nodetree) {
+ bNode *node;
+ for(node= self->scene->nodetree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
+ if(node->custom1==index)
+ node->custom1= 0;
+ else if(node->custom1 > index)
+ node->custom1--;
+ }
+ }
+ }
+
+ value->renderLayer = NULL;
+ Py_RETURN_NONE;
+}
+
+PyObject *RenderData_addRenderLayer(BPy_RenderData * self ) {
+ scene_add_render_layer(self->scene);
+ return RenderLayer_CreatePyObject( self->scene, self->renderContext->layers.last );
+
+}
+
/***************************************************************************/
/* generic handlers for getting/setting attributes */
/***************************************************************************/
@@ -1410,6 +1855,15 @@ static PyObject *RenderData_getFloatAttr( BPy_RenderData *self, void *type )
case EXPP_RENDER_ATTR_MBLURFACTOR:
param = self->renderContext->blurfac;
break;
+ case EXPP_RENDER_ATTR_FPS_BASE:
+ param = self->renderContext->frs_sec_base;
+ break;
+ case EXPP_RENDER_ATTR_BAKEDIST:
+ param = self->renderContext->bake_maxdist;
+ break;
+ case EXPP_RENDER_ATTR_BAKEBIAS:
+ param = self->renderContext->bake_biasdist;
+ break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type constant in RenderData_getFloatAttr" );
@@ -1438,6 +1892,21 @@ static int RenderData_setFloatAttrClamp( BPy_RenderData *self, PyObject *value,
max = 5.0f;
param = &self->renderContext->blurfac;
break;
+ case EXPP_RENDER_ATTR_FPS_BASE:
+ min = 1.0f;
+ max = 120.0f;
+ param = &self->renderContext->frs_sec_base;
+ break;
+ case EXPP_RENDER_ATTR_BAKEDIST:
+ min = 0.0f;
+ max = 1000.0f;
+ param = &self->renderContext->bake_maxdist;
+ break;
+ case EXPP_RENDER_ATTR_BAKEBIAS:
+ min = 0.0f;
+ max = 1000.0f;
+ param = &self->renderContext->bake_biasdist;
+ break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type constant in RenderData_setFloatAttrClamp" );
@@ -1484,6 +1953,15 @@ static PyObject *RenderData_getIValueAttr( BPy_RenderData *self, void *type )
case EXPP_RENDER_ATTR_SIZEY:
param = self->renderContext->ysch;
break;
+ case EXPP_RENDER_ATTR_BAKEMARGIN:
+ param = self->renderContext->bake_filter;
+ break;
+ case EXPP_RENDER_ATTR_BAKEMODE:
+ param = self->renderContext->bake_mode;
+ break;
+ case EXPP_RENDER_ATTR_BAKENORMALSPACE:
+ param = self->renderContext->bake_normal_space;
+ break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"undefined type constant in RenderData_setIValueAttrClamp" );
@@ -1562,6 +2040,24 @@ static int RenderData_setIValueAttrClamp( BPy_RenderData *self, PyObject *value,
size = 'h';
param = &self->renderContext->ysch;
break;
+ case EXPP_RENDER_ATTR_BAKEMARGIN:
+ min = 0;
+ max = 32;
+ size = 'h';
+ param = &self->renderContext->bake_filter;
+ break;
+ case EXPP_RENDER_ATTR_BAKEMODE:
+ min = RE_BAKE_LIGHT;
+ max = RE_BAKE_DISPLACEMENT;
+ size = 'h';
+ param = &self->renderContext->bake_mode;
+ break;
+ case EXPP_RENDER_ATTR_BAKENORMALSPACE:
+ min = R_BAKE_SPACE_CAMERA;
+ max = R_BAKE_SPACE_TANGENT;
+ size = 'h';
+ param = &self->renderContext->bake_normal_space;
+ break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type constant in RenderData_setIValueAttrClamp" );
@@ -1573,6 +2069,18 @@ static int RenderData_setIValueAttrClamp( BPy_RenderData *self, PyObject *value,
/* handlers for other getting/setting attributes */
/***************************************************************************/
+static PyObject *RenderData_getSubImTypeBits( BPy_RenderData *self, void* type )
+{
+ return EXPP_getBitfield( &self->renderContext->subimtype, (int)type, 'h' );
+}
+
+static int RenderData_setSubImTypeBits( BPy_RenderData* self, PyObject *value,
+ void* type )
+{
+ return EXPP_setBitfield( value, &self->renderContext->subimtype,
+ (int)type, 'h' );
+}
+
static PyObject *RenderData_getModeBit( BPy_RenderData *self, void* type )
{
return EXPP_getBitfield( &self->renderContext->mode,
@@ -1588,7 +2096,7 @@ static int RenderData_setModeBit( BPy_RenderData* self, PyObject *value,
#define MODE_MASK ( R_OSA | R_SHADOW | R_GAMMA | R_ENVMAP | R_EDGE | \
R_FIELDS | R_FIELDSTILL | R_RADIO | R_BORDER | R_PANORAMA | R_CROP | \
- R_ODDFIELD | R_MBLUR | R_RAYTRACE | R_THREADS )
+ R_ODDFIELD | R_MBLUR | R_RAYTRACE | R_FIXED_THREADS )
static PyObject *RenderData_getMode( BPy_RenderData *self )
{
@@ -1599,7 +2107,7 @@ static int RenderData_setMode( BPy_RenderData* self, PyObject *arg )
{
int value;
- if( !PyInt_CheckExact( arg ) )
+ if( !PyInt_Check( arg ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -1635,7 +2143,7 @@ static int RenderData_setSceMode( BPy_RenderData* self, PyObject *arg )
{
int value;
- if( !PyInt_CheckExact( arg ) )
+ if( !PyInt_Check( arg ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
@@ -1750,7 +2258,7 @@ static int RenderData_setImagePlanes( BPy_RenderData *self, PyObject *value )
int depth;
char *errstr = "expected int argument of 8, 24, or 32";
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
depth = PyInt_AsLong( value );
@@ -1814,6 +2322,19 @@ static int RenderData_setRenderPath( BPy_RenderData * self, PyObject * value )
return 0;
}
+static PyObject *RenderData_getFrameFilename( BPy_RenderData * self, PyObject *args )
+{
+ char name[FILE_MAX];
+ int frame = self->renderContext->cfra;
+
+ if( !PyArg_ParseTuple( args, "|i", &( frame ) ) )
+ return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "expected int argument or nothing" ) );
+
+ BKE_makepicstring(name, self->renderContext->pic, frame, self->renderContext->imtype);
+ return PyString_FromString( name );
+}
+
PyObject *RenderData_getBackbufPath( BPy_RenderData * self )
{
return PyString_FromString( self->renderContext->backbuf );
@@ -1842,29 +2363,6 @@ static int RenderData_setBackbufPath( BPy_RenderData *self, PyObject *value )
return 0;
}
-PyObject *RenderData_getFtypePath( BPy_RenderData * self )
-{
- return PyString_FromString( self->renderContext->ftype );
-}
-
-static int RenderData_setFtypePath( BPy_RenderData *self, PyObject *value )
-{
- char *name;
-
- name = PyString_AsString( value );
- if( !name )
- return EXPP_ReturnIntError( PyExc_TypeError, "expected a string" );
-
- if( strlen( name ) >= sizeof(self->renderContext->ftype) )
- return EXPP_ReturnIntError( PyExc_ValueError,
- "ftype path is too long" );
-
- strcpy( self->renderContext->ftype, name );
- EXPP_allqueue( REDRAWBUTSSCENE, 0 );
-
- return 0;
-}
-
PyObject *RenderData_getRenderWinSize( BPy_RenderData * self )
{
return PyInt_FromLong( (long) self->renderContext->size );
@@ -1875,7 +2373,7 @@ static int RenderData_setRenderWinSize( BPy_RenderData *self, PyObject *value )
int size;
char *errstr = "expected int argument of 25, 50, 75, or 100";
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, errstr );
size = PyInt_AsLong( value );
@@ -1967,7 +2465,7 @@ static int RenderData_setThreads( BPy_RenderData *self, PyObject *value )
{
int threads;
- if( !PyInt_CheckExact( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, "Error, threads must be an int" );
threads = PyInt_AsLong( value );
@@ -1979,6 +2477,58 @@ static int RenderData_setThreads( BPy_RenderData *self, PyObject *value )
return 0;
}
+PyObject *RenderData_getActiveLayer( BPy_RenderData * self )
+{
+ return PyInt_FromLong( (long) self->renderContext->actlay );
+}
+
+static int RenderData_setActiveLayer( BPy_RenderData *self, PyObject *value )
+{
+ int layer;
+ short nr;
+ SceneRenderLayer *srl;
+
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError, "active layer must be an int" );
+
+ layer = PyInt_AsLong( value );
+ for(nr=0, srl= self->renderContext->layers.first; srl; srl= srl->next, nr++) {
+ }
+ if(layer >= nr)
+ return EXPP_ReturnIntError( PyExc_ValueError, "value larger than number of render layers" );
+
+ self->renderContext->actlay = layer;
+ EXPP_allqueue(REDRAWBUTSSCENE, 0);
+ EXPP_allqueue(REDRAWNODE, 0);
+ return 0;
+}
+
+static int RenderData_setBakeMode( BPy_RenderData *self, PyObject *value,
+ void *type )
+{
+ /* use negative numbers to flip truth */
+ int param = PyObject_IsTrue( value );
+
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param) {
+ self->renderContext->bake_flag |= (int)type;
+ } else {
+ self->renderContext->bake_flag &= ~(int)type;
+ }
+ return 0;
+}
+
+static PyObject *RenderData_getBakeMode( BPy_RenderData *self, void *type )
+{
+ int itype = (int)type;
+ /* use negative numbers to flip truth */
+ if (self->renderContext->bake_flag & itype) Py_RETURN_TRUE;
+ else Py_RETURN_FALSE;
+}
+
/***************************************************************************/
/* BPy_RenderData attribute def */
/***************************************************************************/
@@ -2041,9 +2591,21 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
"Ray tracing enabled",
(void *)R_RAYTRACE},
+
+ {"touch",
+ (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
+ "Create an empry file with the frame name before rendering",
+ (void *)R_TOUCH},
+ {"noOverwrite",
+ (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
+ "Skip rendering existing image files",
+ (void *)R_NO_OVERWRITE},
+ {"fixedThreads",
+ (getter)RenderData_getModeBit, (setter)RenderData_setModeBit,
+ "Use the number of threads defined by the blend file",
+ (void *)R_FIXED_THREADS},
/* R_GAUSS unused */
/* R_FBUF unused */
-/* R_THREADS unused */
{"threads",
(getter)RenderData_getThreads, (setter)RenderData_setThreads,
"Number of threads used to render",
@@ -2103,10 +2665,6 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getBackbufPath, (setter)RenderData_setBackbufPath,
"Path to a background image (setting loads image)",
NULL},
- {"ftypePath",
- (getter)RenderData_getFtypePath, (setter)RenderData_setFtypePath,
- "The path to Ftype file",
- NULL},
{"edgeColor",
(getter)RenderData_getEdgeColor, (setter)RenderData_setEdgeColor,
"RGB color triplet for edges in Toon shading",
@@ -2188,6 +2746,10 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"Frames per second",
(void *)EXPP_RENDER_ATTR_FPS},
+ {"fpsBase",
+ (getter)RenderData_getFloatAttr, (setter)RenderData_setFloatAttrClamp,
+ "Frames per second base",
+ (void *)EXPP_RENDER_ATTR_FPS_BASE},
{"sizeX",
(getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
"Image width (in pixels)",
@@ -2217,6 +2779,128 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
(getter)RenderData_getSet, (setter)RenderData_setSet,
"Scene link 'set' value",
NULL},
+
+ /* renderlayers */
+ {"activeLayer",
+ (getter)RenderData_getActiveLayer, (setter)RenderData_setActiveLayer,
+ "Active rendering layer",
+ NULL},
+ {"renderLayers",
+ (getter)RenderData_getRenderLayers, (setter)NULL,
+ "Active rendering layer",
+ NULL},
+
+ {"halfFloat",
+ (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+ "'Half' openexr option enabled",
+ (void *)R_OPENEXR_HALF},
+ {"zbuf",
+ (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+ "'ZBuf' openexr option enabled",
+ (void *)R_OPENEXR_ZBUF},
+ {"preview",
+ (getter)RenderData_getSubImTypeBits, (setter)RenderData_setSubImTypeBits,
+ "'preview' openexr option enabled",
+ (void *)R_PREVIEW_JPG},
+
+ {"yafrayGIMethod",
+ (getter)RenderData_getYafrayGIMethod, (setter)RenderData_setYafrayGIMethod,
+ "Global illumination method",
+ NULL},
+ {"yafrayGIQuality",
+ (getter)RenderData_getYafrayGIQuality, (setter)RenderData_setYafrayGIQuality,
+ "Global Illumination quality",
+ NULL},
+ {"yafrayExportToXML",
+ (getter)RenderData_getYafrayExportToXML, (setter)RenderData_setYafrayExportToXML,
+ "If true export to an xml file and call yafray instead of plugin",
+ NULL},
+ {"yafrayAutoAntiAliasing",
+ (getter)RenderData_getYafrayAutoAntiAliasing, (setter)RenderData_setYafrayAutoAntiAliasing,
+ "Automatic anti-aliasing enabled/disabled",
+ NULL},
+ {"yafrayClampRGB",
+ (getter)RenderData_getYafrayClampRGB, (setter)RenderData_setYafrayClampRGB,
+ "Clamp RGB enabled/disabled",
+ NULL},
+ {"yafrayAntiAliasingPasses",
+ (getter)RenderData_getYafrayAntiAliasingPasses, (setter)RenderData_setYafrayAntiAliasingPasses,
+ "Number of anti-aliasing passes (0 is no anti-aliasing)",
+ NULL},
+ {"yafrayAntiAliasingSamples",
+ (getter)RenderData_getYafrayAntiAliasingSamples, (setter)RenderData_setYafrayAntiAliasingSamples,
+ "Number of samples per pass",
+ NULL},
+ {"yafrayAntiAliasingPixelSize",
+ (getter)RenderData_getYafrayAntiAliasingPixelSize, (setter)RenderData_setYafrayAntiAliasingPixelSize,
+ "Anti-aliasing pixel filter size",
+ NULL},
+ {"yafrayAntiAliasingThreshold",
+ (getter)RenderData_getYafrayAntiAliasingThreshold, (setter)RenderData_setYafrayAntiAliasingThreshold,
+ "Anti-aliasing threshold",
+ NULL},
+ {"yafrayGICache",
+ (getter)RenderData_getYafrayGICache, (setter)RenderData_setYafrayGICache,
+ "Cache occlusion/irradiance samples (faster)",
+ NULL},
+ {"yafrayGICacheBumpNormals",
+ (getter)RenderData_getYafrayGICacheBumpNormals, (setter)RenderData_setYafrayGICacheBumpNormals,
+ "Enable/disable bumpnormals for cache",
+ NULL},
+ {"yafrayGICacheShadowQuality",
+ (getter)RenderData_getYafrayGICacheShadowQuality, (setter)RenderData_setYafrayGICacheShadowQuality,
+ "Shadow quality, keep it under 0.95 :-)",
+ NULL},
+ {"yafrayGICachePixelsPerSample",
+ (getter)RenderData_getYafrayGICachePixelsPerSample, (setter)RenderData_setYafrayGICachePixelsPerSample,
+ "Maximum number of pixels without samples, the lower the better and slower",
+ NULL},
+ {"yafrayGICacheRefinement",
+ (getter)RenderData_getYafrayGICacheRefinement, (setter)RenderData_setYafrayGICacheRefinement,
+ "Threshold to refine shadows EXPERIMENTAL. 1 = no refinement",
+ NULL},
+ {"yafrayGIPhotons",
+ (getter)RenderData_getYafrayGIPhotons, (setter)RenderData_setYafrayGIPhotons,
+ "Enable/disable use of global photons to help in GI",
+ NULL},
+ {"yafrayGITunePhotons",
+ (getter)RenderData_getYafrayGITunePhotons, (setter)RenderData_setYafrayGITunePhotons,
+ "If true the photonmap is shown directly in the render for tuning",
+ NULL},
+
+ /* Bake stuff */
+ {"bakeClear",
+ (getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
+ "Clear the image before baking",
+ (void *)R_BAKE_CLEAR},
+ {"bakeToActive",
+ (getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
+ "Bake selection to active",
+ (void *)R_BAKE_TO_ACTIVE},
+ {"bakeNormalizeAO",
+ (getter)RenderData_getBakeMode, (setter)RenderData_setBakeMode,
+ "Bake selection to active",
+ (void *)R_BAKE_NORMALIZE},
+ {"bakeMargin",
+ (getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
+ "number of pixels to use as a margin for the edges of the image",
+ (void *)EXPP_RENDER_ATTR_BAKEMARGIN},
+ {"bakeMode",
+ (getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
+ "The mode for baking, see Blender.Scene.Render.BakeModes",
+ (void *)EXPP_RENDER_ATTR_BAKEMODE},
+ {"bakeNormalSpace",
+ (getter)RenderData_getIValueAttr, (setter)RenderData_setIValueAttrClamp,
+ "The mode for baking, see Blender.Scene.Render.BakeNormalSpaceModes",
+ (void *)EXPP_RENDER_ATTR_BAKENORMALSPACE},
+ {"bakeDist",
+ (getter)RenderData_getFloatAttr, (setter)RenderData_setFloatAttrClamp,
+ "Distance (in blender units)",
+ (void *)EXPP_RENDER_ATTR_BAKEDIST},
+ {"bakeBias",
+ (getter)RenderData_getFloatAttr, (setter)RenderData_setFloatAttrClamp,
+ "Bias towards faces further away from the object (in blender units)",
+ (void *)EXPP_RENDER_ATTR_BAKEDIST},
{NULL,NULL,NULL,NULL,NULL}
};
@@ -2226,6 +2910,8 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
static PyMethodDef BPy_RenderData_methods[] = {
{"render", ( PyCFunction ) RenderData_Render, METH_NOARGS,
"() - render the scene"},
+ {"bake", ( PyCFunction ) RenderData_Bake, METH_NOARGS,
+ "() - bake current selection"},
{"saveRenderedImage", (PyCFunction)RenderData_SaveRenderedImage, METH_VARARGS,
"(filename) - save an image generated by a call to render() (set output path first)"},
{"renderAnim", ( PyCFunction ) RenderData_RenderAnim, METH_NOARGS,
@@ -2238,6 +2924,9 @@ static PyMethodDef BPy_RenderData_methods[] = {
{"getRenderPath", ( PyCFunction ) RenderData_getRenderPath,
METH_NOARGS,
"() - get the path to directory where rendered images will go"},
+ {"getFrameFilename", ( PyCFunction ) RenderData_getFrameFilename,
+ METH_VARARGS,
+ "() - get the filename of the frame this will be rendered, taking into account extension and frame range"},
{"setBackbufPath", ( PyCFunction ) RenderData_SetBackbufPath,
METH_VARARGS,
"(string) - get/set the path to a background image and load it"},
@@ -2247,10 +2936,6 @@ static PyMethodDef BPy_RenderData_methods[] = {
{"enableBackbuf", ( PyCFunction ) RenderData_EnableBackbuf,
METH_VARARGS,
"(bool) - enable/disable the backbuf image"},
- {"setFtypePath", ( PyCFunction ) RenderData_SetFtypePath, METH_VARARGS,
- "(string) - get/set the path to output the Ftype file"},
- {"getFtypePath", ( PyCFunction ) RenderData_getFtypePath, METH_NOARGS,
- "() - get the path to Ftype file"},
{"enableExtensions", ( PyCFunction ) RenderData_EnableExtensions,
METH_VARARGS,
"(bool) - enable/disable windows extensions for output files"},
@@ -2373,10 +3058,16 @@ static PyMethodDef BPy_RenderData_methods[] = {
"(enum) - get/set the render to one of a few preget/sets"},
{"setYafrayGIQuality", ( PyCFunction ) RenderData_SetYafrayGIQuality,
METH_VARARGS,
- "(enum) - get/set yafray global Illumination quality"},
+ "(enum) - set yafray global Illumination quality"},
+ {"getYafrayGIQuality", ( PyCFunction ) RenderData_GetYafrayGIQuality,
+ METH_VARARGS,
+ "(enum) - get yafray global Illumination quality"},
{"setYafrayGIMethod", ( PyCFunction ) RenderData_SetYafrayGIMethod,
METH_VARARGS,
- "(enum) - get/set yafray global Illumination method"},
+ "(enum) - set yafray global Illumination method"},
+ {"getYafrayGIMethod", ( PyCFunction ) RenderData_GetYafrayGIMethod,
+ METH_VARARGS,
+ "(enum) - get yafray global Illumination method"},
{"yafrayGIPower", ( PyCFunction ) RenderData_YafrayGIPower,
METH_VARARGS,
"(float) - get/set GI lighting intensity scale"},
@@ -2403,7 +3094,7 @@ static PyMethodDef BPy_RenderData_methods[] = {
"(float) - get/set radius to search for photons to mix (blur)"},
{"yafrayGIPhotonMixCount",
( PyCFunction ) RenderData_YafrayGIPhotonMixCount, METH_VARARGS,
- "(int) - get/set number of photons to shoot"},
+ "(int) - get/set number of photons to mix"},
{"enableYafrayGITunePhotons",
( PyCFunction ) RenderData_EnableYafrayGITunePhotons, METH_VARARGS,
"(bool) - enable/disable show the photonmap directly in the render for tuning"},
@@ -2427,9 +3118,6 @@ static PyMethodDef BPy_RenderData_methods[] = {
{"yafrayExposure", ( PyCFunction ) RenderData_YafrayExposure,
METH_VARARGS,
"(float) - get/set exposure adjustment, 0 is off"},
- {"yafrayProcessorCount",
- ( PyCFunction ) RenderData_YafrayProcessorCount, METH_VARARGS,
- "(int) - get/set number of processors to use"},
{"enableGameFrameStretch",
( PyCFunction ) RenderData_EnableGameFrameStretch, METH_NOARGS,
"(l) - enble stretch or squeeze the viewport to fill the display window"},
@@ -2454,6 +3142,11 @@ static PyMethodDef BPy_RenderData_methods[] = {
"(int) - get/set specify old map value in frames"},
{"newMapValue", ( PyCFunction ) RenderData_NewMapValue, METH_VARARGS,
"(int) - get/set specify new map value in frames"},
+ /* renderlayers */
+ {"addRenderLayer", ( PyCFunction ) RenderData_addRenderLayer, METH_VARARGS,
+ "(string) - add a new render layer"},
+ {"removeRenderLayer", ( PyCFunction ) RenderData_removeRenderLayer, METH_O,
+ "(renderLayer) - remove a render layer from this scene"},
{NULL, NULL, 0, NULL}
};
@@ -2540,6 +3233,470 @@ PyTypeObject RenderData_Type = {
NULL
};
+
+
+
+/* render layers */
+
+static PyObject *RenderLayer_repr( BPy_RenderLayer * self )
+{
+ if( self->renderLayer )
+ return PyString_FromFormat( "[RenderLayer \"%s\"]",
+ self->renderLayer->name );
+ else
+ return PyString_FromString( "NULL" );
+}
+
+static PyObject *RenderLayer_getName( BPy_RenderLayer * self )
+{
+ if( !self->renderLayer )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ return PyString_FromString( self->renderLayer->name );
+}
+
+static int RenderLayer_setName( BPy_RenderLayer * self, PyObject *value )
+{
+ char *name = NULL;
+ int index = BLI_findindex(&self->scene->r.layers, self->renderLayer);
+
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ name = PyString_AsString ( value );
+ if( !name )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string argument" );
+
+ /* No check for doubles? - blender dosnt so we dont have to! */
+ BLI_strncpy( self->renderLayer->name, name, sizeof( self->renderLayer->name ) );
+
+ if(self->scene->nodetree) {
+ bNode *node;
+ for(node= self->scene->nodetree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS && node->id==NULL) {
+ if(node->custom1==index)
+ BLI_strncpy(node->name, self->renderLayer->name, NODE_MAXSTR);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static PyObject *RenderLayer_getLightGroup( BPy_RenderLayer * self )
+{
+ if( !self->renderLayer )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+ return Group_CreatePyObject( self->renderLayer->light_override );
+}
+static int RenderLayer_setLightGroup( BPy_RenderLayer * self, PyObject * value )
+{
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+ return GenericLib_assignData(value, (void **) &self->renderLayer->light_override, NULL, 1, ID_GR, 0);
+}
+
+
+/*****************************************************************************/
+/* Python BPy_Render getsetattr funcs: */
+/*****************************************************************************/
+static int RenderLayer_setLayers( BPy_RenderLayer * self, PyObject * value, void *zlay )
+{
+ unsigned int laymask = 0;
+
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ if( !PyInt_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected an integer (bitmask) as argument" );
+
+ laymask = ( unsigned int )PyInt_AS_LONG( value );
+
+ if((laymask < 0) || (!zlay && laymask == 0))
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "layer value too low" );
+
+ if (zlay) {
+ self->renderLayer->lay_zmask= laymask & ((1<<20) - 1);
+ } else {
+ self->renderLayer->lay= laymask & ((1<<20) - 1);
+ }
+ return 0;
+}
+
+static PyObject *RenderLayer_getLayers( BPy_RenderLayer * self, void *zlay )
+{
+ if (zlay) {
+ return PyInt_FromLong( self->renderLayer->lay_zmask );
+ } else {
+ return PyInt_FromLong( self->renderLayer->lay );
+ }
+}
+
+static PyObject *RenderLayer_getLayflagBits( BPy_RenderLayer *self, void *type )
+{
+ int itype = (int)type;
+ if( !self->renderLayer )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ /* use negative numbers to flip truth */
+ if (self->renderLayer->lay & itype) Py_RETURN_TRUE;
+ else Py_RETURN_FALSE;
+}
+
+static int RenderLayer_setLayflagBits( BPy_RenderLayer *self, PyObject *value,
+ void *type )
+{
+ /* use negative numbers to flip truth */
+ int param = PyObject_IsTrue( value );
+
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param) {
+ self->renderLayer->lay |= (int)type;
+ } else {
+ self->renderLayer->lay &= ~(int)type;
+ }
+ return 0;
+}
+
+static PyObject *RenderLayer_getPassBits( BPy_RenderLayer *self, void *type )
+{
+ int itype = (int)type;
+ if( !self->renderLayer )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ /* use negative numbers to flip truth */
+ if (self->renderLayer->passflag & itype) Py_RETURN_TRUE;
+ else Py_RETURN_FALSE;
+}
+
+static int RenderLayer_setPassBits( BPy_RenderLayer *self, PyObject *value,
+ void *type )
+{
+ /* use negative numbers to flip truth */
+ int param = PyObject_IsTrue( value );
+
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param) {
+ self->renderLayer->passflag |= ((int)type);
+ } else {
+ self->renderLayer->passflag &= ~((int)type);
+ }
+ return 0;
+}
+
+static PyObject *RenderLayer_getPassXorBits( BPy_RenderLayer *self, void *type )
+{
+ if( !self->renderLayer )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ /* use negative numbers to flip truth */
+ if (self->renderLayer->pass_xor & (int)type) Py_RETURN_TRUE;
+ else Py_RETURN_FALSE;
+}
+
+static int RenderLayer_setPassXorBits( BPy_RenderLayer *self, PyObject *value,
+ void *type )
+{
+ int param = PyObject_IsTrue( value );
+
+ if( !self->renderLayer )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This render layer has been removed!" );
+
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param) {
+ self->renderLayer->passflag |= (int)type;
+ } else {
+ self->renderLayer->passflag &= ~(int)type;
+ }
+ return 0;
+}
+
+/***************************************************************************/
+/* BPy_RenderData attribute def */
+/***************************************************************************/
+static PyGetSetDef BPy_RenderLayer_getseters[] = {
+ {"name",
+ (getter)RenderLayer_getName, (setter)RenderLayer_setName,
+ "",
+ (void *)NULL},
+ {"lightGroup",
+ (getter)RenderLayer_getLightGroup, (setter)RenderLayer_setLightGroup,
+ "",
+ (void *)NULL},
+ /*{"material",
+ (getter)RenderLayer_getMaterial, (setter)RenderLayer_setMaterial,
+ "",
+ (void *)NULL},*/
+ {"enable",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "enable this render layer",
+ (void *)SCE_LAY_DISABLE},
+ {"enableZMask",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Only render what's in front of the solid z values",
+ (void *)SCE_LAY_ZMASK},
+ {"enableZMaskAll",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Fill in Z values for solid faces in invisible layers, for masking",
+ (void *)SCE_LAY_ALL_Z},
+
+ {"enableSolid",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Solid faces in this Layer",
+ (void *)SCE_LAY_SOLID},
+ {"enableZTra",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Z-Transparent faces in this Layer (On top of Solid and Halos)",
+ (void *)SCE_LAY_ZTRA},
+ {"enableHalo",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Halos in this Layer (on top of Solid)",
+ (void *)SCE_LAY_HALO},
+ {"enableEdge",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Edge-enhance in this Layer (only works for Solid faces)",
+ (void *)SCE_LAY_EDGE},
+ {"enableSky",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Sky or backbuffer in this Layer",
+ (void *)SCE_LAY_SKY},
+ {"enableStrand",
+ (getter)RenderLayer_getLayflagBits, (setter)RenderLayer_setLayflagBits,
+ "Render Strands in this Layer",
+ (void *)SCE_LAY_STRAND},
+
+ {"layerMask",
+ (getter)RenderLayer_getLayers, (setter)RenderLayer_setLayers,
+ "",
+ (void *)0},
+ {"zLayerMask",
+ (getter)RenderLayer_getLayers, (setter)RenderLayer_setLayers,
+ "",
+ (void *)1},
+
+ /* passes */
+ {"passCombined",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver full combined RGBA buffer",
+ (void *)SCE_PASS_COMBINED},
+ {"passZ",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Z values pass",
+ (void *)SCE_PASS_Z},
+ {"passSpeed",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Speed Vector pass",
+ (void *)SCE_PASS_VECTOR},
+ {"passNormal",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Normal pass",
+ (void *)SCE_PASS_NORMAL},
+ {"passUV",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Texture UV pass",
+ (void *)SCE_PASS_UV},
+ {"passMist",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Mist factor pass (0-1)",
+ (void *)SCE_PASS_MIST},
+ {"passIndex",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Object Index pass",
+ (void *)SCE_PASS_INDEXOB},
+ {"passColor",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver shade-less Color pass",
+ (void *)SCE_PASS_RGBA},
+ {"passDiffuse",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Diffuse pass",
+ (void *)SCE_PASS_DIFFUSE},
+ {"passSpecular",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Specular pass",
+ (void *)SCE_PASS_SPEC},
+ {"passShadow",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Shadow pass",
+ (void *)SCE_PASS_SHADOW},
+ {"passAO",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver AO pass",
+ (void *)SCE_PASS_AO},
+ {"passReflect",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Raytraced Reflection pass",
+ (void *)SCE_PASS_REFLECT},
+ {"passRefract",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Raytraced Reflection pass",
+ (void *)SCE_PASS_REFRACT},
+ {"passRadiosiy",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Radiosity pass",
+ (void *)SCE_PASS_RADIO},
+
+ /* xor */
+ {"passSpecularXOR",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Specular pass XOR",
+ (void *)SCE_PASS_SPEC},
+ {"passShadowXOR",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver Shadow pass XOR",
+ (void *)SCE_PASS_SHADOW},
+ {"passAOXOR",
+ (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
+ "Deliver AO pass XOR",
+ (void *)SCE_PASS_AO},
+ {"passRefractXOR",
+ (getter)RenderLayer_getPassXorBits, (setter)RenderLayer_setPassXorBits,
+ "Deliver Raytraced Reflection pass XOR",
+ (void *)SCE_PASS_REFRACT},
+ {"passRadiosiyXOR",
+ (getter)RenderLayer_getPassXorBits, (setter)RenderLayer_setPassXorBits,
+ "Deliver Radiosity pass XOR",
+ (void *)SCE_PASS_RADIO},
+
+ {NULL,NULL,NULL,NULL,NULL}
+};
+
+/* no methods */
+
+/*------------------------------------BPy_RenderData Type defintion------ */
+PyTypeObject RenderLayer_Type = {
+ PyObject_HEAD_INIT( NULL ) /* required py macro */
+ 0, /* ob_size */
+ /* For printing, in format "<module>.<name>" */
+ "Blender RenderLayer", /* char *tp_name; */
+ sizeof( BPy_RenderLayer ), /* int tp_basicsize; */
+ 0, /* tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ NULL, /* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ ( reprfunc ) RenderLayer_repr, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0, /* long tp_weaklistoffset; */
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ NULL, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ BPy_RenderLayer_getseters, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
+/***************************************************************************/
+/* BPy_RenderData Callbacks */
+/***************************************************************************/
+
+PyObject *RenderLayer_CreatePyObject( struct Scene * scene, struct SceneRenderLayer * renderLayer )
+{
+ BPy_RenderLayer *py_renderlayer;
+
+ py_renderlayer =
+ ( BPy_RenderLayer * ) PyObject_NEW( BPy_RenderLayer,
+ &RenderLayer_Type );
+
+ if( py_renderlayer == NULL ) {
+ return ( NULL );
+ }
+ py_renderlayer->renderLayer = renderLayer;
+ py_renderlayer->scene = scene;
+
+ return ( ( PyObject * ) py_renderlayer );
+}
+
+
/***************************************************************************/
/* Render method def */
/***************************************************************************/
@@ -2578,7 +3735,7 @@ static PyObject *M_Render_ModesDict( void )
PyConstant_Insert( d, "ODDFIELD", PyInt_FromLong( R_ODDFIELD ) );
PyConstant_Insert( d, "MBLUR", PyInt_FromLong( R_MBLUR ) );
PyConstant_Insert( d, "RAYTRACING", PyInt_FromLong( R_RAYTRACE ) );
- PyConstant_Insert( d, "THREADS", PyInt_FromLong( R_THREADS ) );
+ PyConstant_Insert( d, "FIXEDTHREADS", PyInt_FromLong( R_FIXED_THREADS ) );
}
return M;
}
@@ -2611,6 +3768,39 @@ static PyObject *M_Render_GameFramingDict( void )
return M;
}
+static PyObject *M_Render_BakeModesDict( void )
+{
+ PyObject *M = PyConstant_New( );
+
+ if( M ) {
+ BPy_constant *d = ( BPy_constant * ) M;
+
+ PyConstant_Insert( d, "LIGHT", PyInt_FromLong( RE_BAKE_LIGHT ) );
+ PyConstant_Insert( d, "ALL", PyInt_FromLong( RE_BAKE_ALL ) );
+ PyConstant_Insert( d, "AO", PyInt_FromLong( RE_BAKE_AO ) );
+ PyConstant_Insert( d, "NORMALS", PyInt_FromLong( RE_BAKE_NORMALS ) );
+ PyConstant_Insert( d, "TEXTURE", PyInt_FromLong( RE_BAKE_TEXTURE ) );
+ PyConstant_Insert( d, "DISPLACEMENT", PyInt_FromLong( RE_BAKE_DISPLACEMENT ) );
+ }
+ return M;
+}
+
+
+static PyObject *M_Render_BakeNormalSpaceDict( void )
+{
+ PyObject *M = PyConstant_New( );
+
+ if( M ) {
+ BPy_constant *d = ( BPy_constant * ) M;
+
+ PyConstant_Insert( d, "CAMERA", PyInt_FromLong( R_BAKE_SPACE_CAMERA ) );
+ PyConstant_Insert( d, "WORLS", PyInt_FromLong( R_BAKE_SPACE_WORLD ) );
+ PyConstant_Insert( d, "OBJECT", PyInt_FromLong( R_BAKE_SPACE_OBJECT ) );
+ PyConstant_Insert( d, "TANGENT", PyInt_FromLong( R_BAKE_SPACE_TANGENT ) );
+ }
+ return M;
+}
+
/***************************************************************************/
/* Render Module Init */
/***************************************************************************/
@@ -2620,10 +3810,15 @@ PyObject *Render_Init( void )
PyObject *ModesDict = M_Render_ModesDict( );
PyObject *SceModesDict = M_Render_SceModesDict( );
PyObject *GFramingDict = M_Render_GameFramingDict( );
-
+ PyObject *BakeModesDict = M_Render_BakeModesDict( );
+ PyObject *BakeNormalSpaceDict = M_Render_BakeNormalSpaceDict( );
+
if( PyType_Ready( &RenderData_Type ) < 0 )
return NULL;
+ if( PyType_Ready( &RenderLayer_Type ) < 0 )
+ return NULL;
+
submodule = Py_InitModule3( "Blender.Scene.Render",
M_Render_methods, M_Render_doc );
@@ -2633,7 +3828,11 @@ PyObject *Render_Init( void )
PyModule_AddObject( submodule, "SceModes", SceModesDict );
if( GFramingDict )
PyModule_AddObject( submodule, "FramingModes", GFramingDict );
-
+ if( BakeModesDict )
+ PyModule_AddObject( submodule, "BakeModes", BakeModesDict );
+ if( BakeNormalSpaceDict )
+ PyModule_AddObject( submodule, "BakeNormalSpaceModes", BakeNormalSpaceDict );
+
/* ugh: why aren't these in a constant dict? */
PyModule_AddIntConstant( submodule, "INTERNAL", R_INTERN );
@@ -2651,7 +3850,6 @@ PyObject *Render_Init( void )
PyModule_AddIntConstant( submodule, "HAMX", R_HAMX );
PyModule_AddIntConstant( submodule, "IRIS", R_IRIS );
PyModule_AddIntConstant( submodule, "IRISZ", R_IRIZ );
- PyModule_AddIntConstant( submodule, "FTYPE", R_FTYPE );
PyModule_AddIntConstant( submodule, "PAL", B_PR_PAL );
PyModule_AddIntConstant( submodule, "NTSC", B_PR_NTSC );
PyModule_AddIntConstant( submodule, "DEFAULT", B_PR_PRESET );
@@ -2666,9 +3864,11 @@ PyObject *Render_Init( void )
PyModule_AddIntConstant( submodule, "HIGH", PY_HIGH );
PyModule_AddIntConstant( submodule, "HIGHER", PY_HIGHER );
PyModule_AddIntConstant( submodule, "BEST", PY_BEST );
+ PyModule_AddIntConstant( submodule, "USEAOSETTINGS", PY_USEAOSETTINGS );
PyModule_AddIntConstant( submodule, "SKYDOME", PY_SKYDOME );
PyModule_AddIntConstant( submodule, "GIFULL", PY_FULL );
PyModule_AddIntConstant( submodule, "OPENEXR", R_OPENEXR );
+ PyModule_AddIntConstant( submodule, "MULTILAYER", R_MULTILAYER );
PyModule_AddIntConstant( submodule, "TIFF", R_TIFF );
PyModule_AddIntConstant( submodule, "FFMPEG", R_FFMPEG );
PyModule_AddIntConstant( submodule, "CINEON", R_CINEON );
@@ -2714,13 +3914,6 @@ static PyObject *RenderData_SetBackbufPath( BPy_RenderData *self,
(setter)RenderData_setBackbufPath );
}
-static PyObject *RenderData_SetFtypePath( BPy_RenderData *self,
- PyObject *args )
-{
- return EXPP_setterWrapperTuple( (void *)self, args,
- (setter)RenderData_setFtypePath );
-}
-
static PyObject *RenderData_SetOversamplingLevel( BPy_RenderData * self,
PyObject * args )
{
diff --git a/source/blender/python/api2_2x/sceneRender.h b/source/blender/python/api2_2x/sceneRender.h
index 73bf71f5c06..1200bb87af2 100644
--- a/source/blender/python/api2_2x/sceneRender.h
+++ b/source/blender/python/api2_2x/sceneRender.h
@@ -36,17 +36,27 @@
#include <Python.h>
#include "DNA_scene_types.h"
+PyTypeObject RenderLayer_Type;
+
#define BPy_RenderData_Check(v) ((v)->ob_type == &RenderData_Type)
+#define BPy_RenderLayer_Check(v) ((v)->ob_type == &RenderLayer_Type)
//------------------------------------Struct definitions-------
typedef struct {
PyObject_HEAD
struct RenderData *renderContext;
- Scene *scene;
+ struct Scene *scene;
} BPy_RenderData;
+
+typedef struct {
+ PyObject_HEAD
+ struct SceneRenderLayer *renderLayer; /* this is totally weak, pointer can become invalid */
+ struct Scene *scene;
+} BPy_RenderLayer;
+
//------------------------------------Visible prototypes-------
PyObject *Render_Init( void );
PyObject *RenderData_CreatePyObject( struct Scene *scene );
-
+PyObject *RenderLayer_CreatePyObject( struct Scene *scene, struct SceneRenderLayer * renderLayer );
#endif /* EXPP_SCENERENDER_H */
diff --git a/source/blender/python/api2_2x/sceneSequence.c b/source/blender/python/api2_2x/sceneSequence.c
index e7c8abe72a2..6bcf074068d 100644
--- a/source/blender/python/api2_2x/sceneSequence.c
+++ b/source/blender/python/api2_2x/sceneSequence.c
@@ -57,7 +57,9 @@ enum seq_consts {
EXPP_SEQ_ATTR_LENGTH,
EXPP_SEQ_ATTR_START,
EXPP_SEQ_ATTR_STARTOFS,
- EXPP_SEQ_ATTR_ENDOFS
+ EXPP_SEQ_ATTR_ENDOFS,
+ EXPP_SEQ_ATTR_STARTSTILL,
+ EXPP_SEQ_ATTR_ENDSTILL
};
@@ -154,7 +156,6 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
for(a=0; a<seq->len; a++) {
name = PyString_AsString(PyList_GetItem( list, a ));
strncpy(se->name, name, FILE_MAXFILE-1);
- se->ok= 1;
se++;
}
@@ -167,7 +168,7 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
seq->type= SEQ_RAM_SOUND;
seq->sound = sound;
- totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec);
+ totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec / sce->r.frs_sec_base);
sound->flags |= SOUND_FLAGS_SEQUENCE;
@@ -177,16 +178,10 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
strip->len= totframe;
strip->us= 1;
strncpy(strip->dir, sound->name, FILE_MAXDIR-1);
- strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+ strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
/* name sound in first strip */
strncpy(se->name, sound->name, FILE_MAXFILE-1);
-
- for(a=1; a<=totframe; a++, se++) {
- se->ok= 2; /* why? */
- se->ibuf= 0;
- se->nr= a;
- }
} else if (BPy_Scene_Check(py_data)) {
/* scene */
@@ -203,8 +198,6 @@ static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
sizeof(seq->name) - 2);
strip->len= seq->len;
strip->us= 1;
- if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-
} else {
/* movie, pydata is a path to a movie file */
char *name = PyString_AsString ( py_data );
@@ -538,7 +531,46 @@ static PyObject *Sequence_getImages( BPy_Sequence * self )
return ret;
}
-
+static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
+{
+ Strip *strip;
+ StripElem *se;
+ int i;
+ PyObject *list;
+ char *basepath, *name;
+
+ if (self->seq->type != SEQ_IMAGE) {
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "Sequence is not an image type" );
+ }
+
+ if( !PyArg_ParseTuple
+ ( value, "sO!", &basepath, &PyList_Type, &list ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected string and optional list argument" );
+
+ strip = self->seq->strip;
+ se = strip->stripdata;
+
+ /* for now dont support different image list sizes */
+ if (PyList_Size(list) != strip->len) {
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "at the moment only image lista with the same number of images as the strip are supported" );
+ }
+
+ strncpy(strip->dir, basepath, sizeof(strip->dir));
+
+ for (i=0; i<strip->len; i++, se++) {
+ name = PyString_AsString(PyList_GetItem(list, i));
+ if (name) {
+ strncpy(se->name, name, sizeof(se->name));
+ } else {
+ PyErr_Clear();
+ }
+ }
+
+ return 0;
+}
/*
* get floating point attributes
@@ -568,20 +600,24 @@ static PyObject *getIntAttr( BPy_Sequence *self, void *type )
case EXPP_SEQ_ATTR_ENDOFS:
param = seq->endofs;
break;
+ case EXPP_SEQ_ATTR_STARTSTILL:
+ param = seq->startstill;
+ break;
+ case EXPP_SEQ_ATTR_ENDSTILL:
+ param = seq->endstill;
+ break;
default:
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "undefined type in getFloatAttr" );
+ "undefined type in getIntAttr" );
}
return PyInt_FromLong( param );
}
-
/* internal functions for recursivly updating metastrip locatons */
static void intern_pos_update(Sequence * seq) {
/* update startdisp and enddisp */
- seq->startdisp = seq->start + seq->startofs - seq->startstill;
- seq->enddisp = ((seq->start + seq->len) - seq->endofs )+ seq->endstill;
+ calc_sequence_disp(seq);
}
void intern_recursive_pos_update(Sequence * seq, int offset) {
@@ -601,7 +637,7 @@ static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
struct Sequence *seq= self->seq;
int number, origval=0;
- if( !PyInt_CheckExact ( value ) )
+ if( !PyInt_Check( value ) )
return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
number = PyInt_AS_LONG( value );
@@ -621,9 +657,10 @@ static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
break;
case EXPP_SEQ_ATTR_STARTOFS:
- CLAMP(number, 0, seq->len - seq->endofs);
+ if (self->seq->type == SEQ_EFFECT)
return EXPP_ReturnIntError( PyExc_RuntimeError,
"This property dosnt apply to an effect" );
+ CLAMP(number, 0, seq->len - seq->endofs);
seq->startofs = number;
break;
case EXPP_SEQ_ATTR_ENDOFS:
@@ -633,7 +670,28 @@ static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
CLAMP(number, 0, seq->len - seq->startofs);
seq->endofs = number;
break;
-
+ case EXPP_SEQ_ATTR_STARTSTILL:
+ if (self->seq->type == SEQ_EFFECT)
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This property dosnt apply to an effect" );
+ CLAMP(number, 1, MAXFRAME);
+ seq->startstill = number;
+ break;
+ case EXPP_SEQ_ATTR_ENDSTILL:
+ if (self->seq->type == SEQ_EFFECT)
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "This property dosnt apply to an effect" );
+ CLAMP(number, seq->startstill+1, MAXFRAME);
+ seq->endstill = number;
+ break;
+ case EXPP_SEQ_ATTR_LENGTH:
+ if (self->seq->type == SEQ_EFFECT)
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "cannot set the length of an effect directly" );
+ CLAMP(number, 1, MAXFRAME);
+ origval = seq->len;
+ seq->start = number;
+ break;
default:
return EXPP_ReturnIntError( PyExc_RuntimeError,
"undefined type in setFloatAttrClamp" );
@@ -664,11 +722,15 @@ static PyObject *getFlagAttr( BPy_Sequence *self, void *type )
static int setFlagAttr( BPy_Sequence *self, PyObject *value, void *type )
{
int t = (int)type;
+ int param = PyObject_IsTrue( value );
- if (PyObject_IsTrue(value))
+ if( param == -1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected True/False or 0/1" );
+
+ if (param)
self->seq->flag |= t;
else {
-
/* dont allow leftsel and rightsel when its not selected */
if (t == SELECT)
t = t + SEQ_LEFTSEL + SEQ_RIGHTSEL;
@@ -701,7 +763,7 @@ static PyGetSetDef BPy_Sequence_getseters[] = {
"Sequence name",
NULL},
{"images",
- (getter)Sequence_getImages, (setter)NULL,
+ (getter)Sequence_getImages, (setter)Sequence_setImages,
"Sequence scene",
NULL},
@@ -730,7 +792,15 @@ static PyGetSetDef BPy_Sequence_getseters[] = {
(getter)getIntAttr, (setter)setIntAttrClamp,
"",
(void *) EXPP_SEQ_ATTR_ENDOFS},
-
+ {"startStill",
+ (getter)getIntAttr, (setter)setIntAttrClamp,
+ "",
+ (void *) EXPP_SEQ_ATTR_STARTSTILL},
+ {"endStill",
+ (getter)getIntAttr, (setter)setIntAttrClamp,
+ "",
+ (void *) EXPP_SEQ_ATTR_ENDSTILL},
+
{"sel",
(getter)getFlagAttr, (setter)setFlagAttr,
"Sequence audio mute option",
@@ -1029,6 +1099,12 @@ PyObject *SceneSeq_CreatePyObject( struct Scene * scn, struct Sequence * iter)
if( !scn )
Py_RETURN_NONE;
+ if ( !scn->ed ) {
+ Editing *ed;
+ ed= scn->ed= MEM_callocN( sizeof(Editing), "addseq");
+ ed->seqbasep= &ed->seqbase;
+ }
+
pysceseq =
( BPy_SceneSeq * ) PyObject_NEW( BPy_SceneSeq, &SceneSeq_Type );
diff --git a/source/blender/python/api2_2x/sceneSequence.h b/source/blender/python/api2_2x/sceneSequence.h
index 49890043966..952e861f46d 100644
--- a/source/blender/python/api2_2x/sceneSequence.h
+++ b/source/blender/python/api2_2x/sceneSequence.h
@@ -41,7 +41,7 @@ extern PyTypeObject Sequence_Type;
extern PyTypeObject SceneSeq_Type;
#define BPy_Sequence_Check(v) ((v)->ob_type == &Sequence_Type)
-#define BPy_SceneSeq_Check(v) ((v)->ob_type == &Sequence_Type)
+#define BPy_SceneSeq_Check(v) ((v)->ob_type == &SceneSeq_Type)
/*****************************************************************************/
diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c
index 64ff035fa1f..b3bcdf17762 100644
--- a/source/blender/python/api2_2x/vector.c
+++ b/source/blender/python/api2_2x/vector.c
@@ -168,7 +168,7 @@ PyObject *Vector_Resize4D(VectorObject * self)
extract a quaternion from the vector and the track and up axis */
PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
{
- float vec[3];
+ float vec[3], quat[4];
char *strack, *sup;
short track = 2, up = 1;
@@ -271,7 +271,9 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
vec[1] = -self->vec[1];
vec[2] = -self->vec[2];
- return newQuaternionObject(vectoquat(vec, track, up), Py_NEW);
+ vectoquat(vec, track, up, quat);
+
+ return newQuaternionObject(quat, Py_NEW);
}
@@ -359,6 +361,7 @@ static PyObject *Vector_slice(VectorObject * self, int begin, int end)
int count;
CLAMP(begin, 0, self->size);
+ if (end<0) end= self->size+end+1;
CLAMP(end, 0, self->size);
begin = MIN2(begin,end);
@@ -380,6 +383,7 @@ static int Vector_ass_slice(VectorObject * self, int begin, int end,
PyObject *v;
CLAMP(begin, 0, self->size);
+ if (end<0) end= self->size+end+1;
CLAMP(end, 0, self->size);
begin = MIN2(begin,end);
diff --git a/source/blender/python/api2_2x/windowTheme.c b/source/blender/python/api2_2x/windowTheme.c
index 7ae7a0a32de..b345cd0ae0f 100644
--- a/source/blender/python/api2_2x/windowTheme.c
+++ b/source/blender/python/api2_2x/windowTheme.c
@@ -172,6 +172,7 @@ static PyObject *ThemeSpace_getAttr( BPy_ThemeSpace * self, char *name )
ELSEIF_TSP_RGBA( edge_select )
ELSEIF_TSP_RGBA( edge_seam )
ELSEIF_TSP_RGBA( edge_sharp )
+ ELSEIF_TSP_RGBA( editmesh_active )
ELSEIF_TSP_RGBA( edge_facesel )
ELSEIF_TSP_RGBA( face )
ELSEIF_TSP_RGBA( face_select )
@@ -199,13 +200,13 @@ static PyObject *ThemeSpace_getAttr( BPy_ThemeSpace * self, char *name )
else if( !strcmp( name, "facedot_size" ) )
attrib = Py_BuildValue( "i", tsp->facedot_size );
else if( !strcmp( name, "__members__" ) )
- attrib = Py_BuildValue("[sssssssssssssssssssssssssssssssssssssssssssssss]", "theme",
+ attrib = Py_BuildValue("[ssssssssssssssssssssssssssssssssssssssssssssssss]", "theme",
"back", "text", "text_hi", "header",
"panel", "shade1", "shade2", "hilite",
"grid", "wire", "select", "lamp", "active",
"group", "group_active",
"transform", "vertex", "vertex_select",
- "edge", "edge_select", "edge_seam", "edge_sharp",
+ "edge", "edge_select", "edge_seam", "edge_sharp", "editmesh_active",
"edge_facesel", "face", "face_select",
"face_dot", "normal", "bone_solid", "bone_pose",
"strip", "strip_select",
@@ -251,6 +252,7 @@ static int ThemeSpace_setAttr( BPy_ThemeSpace * self, char *name,
ELSEIF_TSP_RGBA( edge_select )
ELSEIF_TSP_RGBA( edge_seam )
ELSEIF_TSP_RGBA( edge_sharp )
+ ELSEIF_TSP_RGBA( editmesh_active )
ELSEIF_TSP_RGBA( edge_facesel )
ELSEIF_TSP_RGBA( face )
ELSEIF_TSP_RGBA( face_select )
@@ -519,7 +521,7 @@ static PyObject *Theme_repr( BPy_Theme * self );
static PyObject *Theme_get( BPy_Theme * self, PyObject * args );
static PyObject *Theme_getName( BPy_Theme * self );
-static PyObject *Theme_setName( BPy_Theme * self, PyObject * args );
+static PyObject *Theme_setName( BPy_Theme * self, PyObject * value );
static PyMethodDef BPy_Theme_methods[] = {
{"get", ( PyCFunction ) Theme_get, METH_VARARGS,
@@ -530,7 +532,7 @@ static PyMethodDef BPy_Theme_methods[] = {
- (s) - string: 'UI' or a space name, like 'VIEW3D', etc."},
{"getName", ( PyCFunction ) Theme_getName, METH_NOARGS,
"() - Return Theme name"},
- {"setName", ( PyCFunction ) Theme_setName, METH_VARARGS,
+ {"setName", ( PyCFunction ) Theme_setName, METH_O,
"(s) - Set Theme name"},
{NULL, NULL, 0, NULL}
};
@@ -775,11 +777,11 @@ static PyObject *Theme_getName( BPy_Theme * self )
return PyString_FromString( self->theme->name );
}
-static PyObject *Theme_setName( BPy_Theme * self, PyObject * args )
+static PyObject *Theme_setName( BPy_Theme * self, PyObject * value )
{
- char *name = NULL;
+ char *name = PyString_AsString(value);
- if( !PyArg_ParseTuple( args, "s", &name ) )
+ if( !name )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
@@ -807,15 +809,10 @@ static void Theme_dealloc( BPy_Theme * self )
static PyObject *Theme_getAttr( BPy_Theme * self, char *name )
{
- PyObject *attr = Py_None;
-
if( !strcmp( name, "name" ) )
- attr = PyString_FromString( self->theme->name );
+ return PyString_FromString( self->theme->name );
else if( !strcmp( name, "__members__" ) )
- attr = Py_BuildValue( "[s]", "name" );
-
- if( attr != Py_None )
- return attr;
+ return Py_BuildValue( "[s]", "name" );
return Py_FindMethod( BPy_Theme_methods, ( PyObject * ) self, name );
}
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index 7d6d3f32f14..e1f893f0d9d 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -566,20 +566,21 @@ static void check_renderbutton_framerate(void) {
(qtdata->gTemporalSettings.frameRate == 1571553 ||
qtdata->gTemporalSettings.frameRate == 1964113 ||
qtdata->gTemporalSettings.frameRate == 3928227)) {;} else
- qtdata->gTemporalSettings.frameRate = G.scene->r.frs_sec << 16;
+ qtdata->gTemporalSettings.frameRate =
+ (G.scene->r.frs_sec << 16) / G.scene->r.frs_sec_base ;
err = SCSetInfo(qtdata->theComponent, scTemporalSettingsType, &qtdata->gTemporalSettings);
CheckError( err, "SCSetInfo error" );
if(qtdata->gTemporalSettings.frameRate == 1571553) { // 23.98 fps
- qtdata->kVideoTimeScale = 2398;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 24000;
+ qtdata->duration = 1001;
} else if (qtdata->gTemporalSettings.frameRate == 1964113) { // 29.97 fps
- qtdata->kVideoTimeScale = 2997;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 30000;
+ qtdata->duration = 1001;
} else if (qtdata->gTemporalSettings.frameRate == 3928227) { // 59.94 fps
- qtdata->kVideoTimeScale = 5994;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 60000;
+ qtdata->duration = 1001;
} else {
qtdata->kVideoTimeScale = (qtdata->gTemporalSettings.frameRate >> 16) * 100;
qtdata->duration = 100;
@@ -641,25 +642,37 @@ int get_qtcodec_settings(void)
// framerate jugglin'
if(qtdata->gTemporalSettings.frameRate == 1571553) { // 23.98 fps
- qtdata->kVideoTimeScale = 2398;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 24000;
+ qtdata->duration = 1001;
G.scene->r.frs_sec = 24;
+ G.scene->r.frs_sec_base = 1.001;
} else if (qtdata->gTemporalSettings.frameRate == 1964113) { // 29.97 fps
- qtdata->kVideoTimeScale = 2997;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 30000;
+ qtdata->duration = 1001;
G.scene->r.frs_sec = 30;
+ G.scene->r.frs_sec_base = 1.001;
} else if (qtdata->gTemporalSettings.frameRate == 3928227) { // 59.94 fps
- qtdata->kVideoTimeScale = 5994;
- qtdata->duration = 100;
+ qtdata->kVideoTimeScale = 60000;
+ qtdata->duration = 1001;
G.scene->r.frs_sec = 60;
+ G.scene->r.frs_sec_base = 1.001;
} else {
- qtdata->kVideoTimeScale = 600;
+ double fps = qtdata->gTemporalSettings.frameRate;
+
+ qtdata->kVideoTimeScale = 60000;
qtdata->duration = qtdata->kVideoTimeScale / (qtdata->gTemporalSettings.frameRate / 65536);
- G.scene->r.frs_sec = (qtdata->gTemporalSettings.frameRate / 65536);
+ if ((qtdata->gTemporalSettings.frameRate & 0xffff) == 0) {
+ G.scene->r.frs_sec = fps / 65536;
+ G.scene->r.frs_sec_base = 1;
+ } else {
+ /* we do our very best... */
+ G.scene->r.frs_sec = (fps * 10000 / 65536);
+ G.scene->r.frs_sec_base = 10000;
+ }
}
return 1;
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index c701d4d41d0..862b20b5260 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -244,6 +244,7 @@ static OSErr QT_get_frameIndexes(struct anim *anim)
TimeValue nextTime = 0;
TimeValue startPoint;
TimeValue tmpstartPoint;
+ long sampleCount = 0;
startPoint = -1;
@@ -254,12 +255,12 @@ static OSErr QT_get_frameIndexes(struct anim *anim)
anim->qtime->framecount = 0;
- while(tmpstartPoint != -1) {
- nextTime = 0;
- GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, tmpstartPoint, 0, &nextTime, NULL);
- tmpstartPoint = nextTime;
- anim->qtime->framecount ++;
- }
+ sampleCount = GetMediaSampleCount(anim->qtime->theMedia);
+ anErr = GetMoviesError();
+ if (anErr != noErr) return anErr;
+
+ anim->qtime->framecount = sampleCount;
+
anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
//rewind
@@ -403,6 +404,7 @@ int startquicktime (struct anim *anim)
char *qtname;
Str255 dst;
#endif
+ short depth = 0;
anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
anim->qtime->have_gw = FALSE;
@@ -483,6 +485,9 @@ int startquicktime (struct anim *anim)
anim->qtime->offscreenGWorld,
GetGWorldDevice(anim->qtime->offscreenGWorld));
SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality);
+
+ // sets Media and Track!
+ depth = GetFirstVideoTrackPixelDepth(anim);
QT_get_frameIndexes(anim);
}
@@ -491,7 +496,7 @@ int startquicktime (struct anim *anim)
LockPixels(anim->qtime->offscreenPixMap);
//fill blender's anim struct
- anim->qtime->depth = GetFirstVideoTrackPixelDepth(anim);
+ anim->qtime->depth = depth;
anim->duration = anim->qtime->framecount;
anim->params = 0;
diff --git a/source/blender/radiosity/intern/source/Makefile b/source/blender/radiosity/intern/source/Makefile
index 54a3af8e098..7791866eeaa 100644
--- a/source/blender/radiosity/intern/source/Makefile
+++ b/source/blender/radiosity/intern/source/Makefile
@@ -37,10 +37,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/radiosity/intern/source/radfactors.c b/source/blender/radiosity/intern/source/radfactors.c
index 46fb6b2c910..d2d1b581ae8 100644
--- a/source/blender/radiosity/intern/source/radfactors.c
+++ b/source/blender/radiosity/intern/source/radfactors.c
@@ -744,11 +744,9 @@ void subdivideshootElements(int it)
}
}
if(rn) {
- min[0]= min[1]= min[2]= 1.0e10;
- max[0]= max[1]= max[2]= -1.0e10;
+ INIT_MINMAX(min, max);
/* errmin and max are the filtered colors */
- errmin[0]= errmin[1]= errmin[2]= 1.0e10;
- errmax[0]= errmax[1]= errmax[2]= -1.0e10;
+ INIT_MINMAX(errmin, errmax);
minmaxradelemfilt(rp->first, min, max, errmin, errmax);
/* if small difference between colors: no subdiv */
@@ -912,8 +910,8 @@ void inithemiwindows()
memset(vw, 0, sizeof(RadView));
vw->rectx= RG.hemires;
vw->recty= RG.hemires;
- vw->rectz= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
- vw->rect= MEM_mallocN(4*vw->rectx*vw->recty, "initwindows");
+ vw->rectz= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows");
+ vw->rect= MEM_mallocN(sizeof(int)*vw->rectx*vw->recty, "initwindows");
vw->mynear= RG.maxsize/2000.0;
vw->myfar= 2.0*RG.maxsize;
vw->wx1= -vw->mynear;
diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c
index 42c7fa58da5..aca5a0885f4 100644
--- a/source/blender/radiosity/intern/source/radrender.c
+++ b/source/blender/radiosity/intern/source/radrender.c
@@ -84,60 +84,69 @@ static float maxenergy;
/* find the face with maximum energy to become shooter */
/* nb: _rr means rad-render version of existing radio call */
-static VlakRen *findshoot_rr(Render *re)
+static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p)
{
- RadFace *rf;
+ RadFace *rf, *shootrf, **radface;
+ ObjectRen *obr;
VlakRen *vlr=NULL, *shoot;
float energy;
int a;
shoot= NULL;
+ shootrf= NULL;
maxenergy= 0.0;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
- if(vlr->radface) {
- rf= vlr->radface;
- rf->flag &= ~RAD_SHOOT;
-
- energy= rf->unshot[0]*rf->area;
- energy+= rf->unshot[1]*rf->area;
- energy+= rf->unshot[2]*rf->area;
-
- if(energy>maxenergy) {
- shoot= vlr;
- maxenergy= energy;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ rf->flag &= ~RAD_SHOOT;
+
+ energy= rf->unshot[0]*rf->area;
+ energy+= rf->unshot[1]*rf->area;
+ energy+= rf->unshot[2]*rf->area;
+
+ if(energy>maxenergy) {
+ shoot= vlr;
+ shootrf= rf;
+ maxenergy= energy;
+ }
}
}
}
- if(shoot) {
+ if(shootrf) {
maxenergy/= RG.totenergy;
- if(maxenergy<RG.convergence) return NULL;
- shoot->radface->flag |= RAD_SHOOT;
+ if(maxenergy<RG.convergence) {
+ *shoot_p= NULL;
+ *shootrf_p= NULL;
+ }
+ shootrf->flag |= RAD_SHOOT;
}
- return shoot;
+ *shoot_p= shoot;
+ *shootrf_p= shootrf;
}
-static void backface_test_rr(Render *re, VlakRen *shoot)
+static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
{
+ ObjectRen *obr;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
float tvec[3];
int a;
/* backface testing */
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
- if(vlr->radface) {
- if(vlr!=shoot) {
- rf= vlr->radface;
- VecSubf(tvec, shoot->radface->cent, rf->cent);
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+ if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ VecSubf(tvec, shootrf->cent, rf->cent);
- if( tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) {
+ if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0)
rf->flag |= RAD_BACKFACE;
- }
}
}
}
@@ -145,17 +154,20 @@ static void backface_test_rr(Render *re, VlakRen *shoot)
static void clear_backface_test_rr(Render *re)
{
+ ObjectRen *obr;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
int a;
/* backface flag clear */
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->radface) {
- rf= vlr->radface;
- rf->flag &= ~RAD_BACKFACE;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ rf->flag &= ~RAD_BACKFACE;
+ }
}
}
}
@@ -163,10 +175,11 @@ static void clear_backface_test_rr(Render *re)
extern RadView hemitop, hemiside; // radfactors.c
/* hemi-zbuffering, delivers formfactors array */
-static void makeformfactors_rr(Render *re, VlakRen *shoot)
+static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
{
+ ObjectRen *obr;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
float len, vec[3], up[3], side[3], tar[5][3], *fp;
int a;
@@ -175,25 +188,25 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
/* set up hemiview */
/* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */
- VecSubf(vec, shoot->v1->co, shoot->radface->cent);
- Crossf(up, shoot->radface->norm, vec);
+ VecSubf(vec, shoot->v1->co, shootrf->cent);
+ Crossf(up, shootrf->norm, vec);
len= Normalize(up);
VECCOPY(hemitop.up, up);
- VECCOPY(hemiside.up, shoot->radface->norm);
+ VECCOPY(hemiside.up, shootrf->norm);
- Crossf(side, shoot->radface->norm, up);
+ Crossf(side, shootrf->norm, up);
/* five targets */
- VecAddf(tar[0], shoot->radface->cent, shoot->radface->norm);
- VecAddf(tar[1], shoot->radface->cent, up);
- VecSubf(tar[2], shoot->radface->cent, up);
- VecAddf(tar[3], shoot->radface->cent, side);
- VecSubf(tar[4], shoot->radface->cent, side);
+ VecAddf(tar[0], shootrf->cent, shootrf->norm);
+ VecAddf(tar[1], shootrf->cent, up);
+ VecSubf(tar[2], shootrf->cent, up);
+ VecAddf(tar[3], shootrf->cent, side);
+ VecSubf(tar[4], shootrf->cent, side);
/* camera */
- VECCOPY(hemiside.cam, shoot->radface->cent);
- VECCOPY(hemitop.cam, shoot->radface->cent);
+ VECCOPY(hemiside.cam, shootrf->cent);
+ VECCOPY(hemitop.cam, shootrf->cent);
/* do it! */
VECCOPY(hemitop.tar, tar[0]);
@@ -207,62 +220,67 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
/* convert factors to real radiosity */
fp= RG.formfactors;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->radface) {
- rf= vlr->radface;
- if(*fp!=0.0 && rf->area!=0.0) {
- *fp *= shoot->radface->area/rf->area;
- if(*fp>1.0) *fp= 1.0001;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ if(*fp!=0.0 && rf->area!=0.0) {
+ *fp *= shootrf->area/rf->area;
+ if(*fp>1.0) *fp= 1.0001;
+ }
+ fp++;
}
- fp++;
}
}
}
/* based at RG.formfactors array, distribute shoot energy over other faces */
-static void applyformfactors_rr(Render *re, VlakRen *shoot)
+static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf)
{
+ ObjectRen *obr;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
float *fp, *ref, unr, ung, unb, r, g, b;
int a;
- unr= shoot->radface->unshot[0];
- ung= shoot->radface->unshot[1];
- unb= shoot->radface->unshot[2];
+ unr= shootrf->unshot[0];
+ ung= shootrf->unshot[1];
+ unb= shootrf->unshot[2];
fp= RG.formfactors;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->radface) {
- rf= vlr->radface;
- if(*fp!= 0.0) {
-
- ref= &(vlr->mat->r);
-
- r= (*fp)*unr*ref[0];
- g= (*fp)*ung*ref[1];
- b= (*fp)*unb*ref[2];
-
- // if(rf->flag & RAD_BACKFACE) {
-
- rf->totrad[0]+= r;
- rf->totrad[1]+= g;
- rf->totrad[2]+= b;
-
- rf->unshot[0]+= r;
- rf->unshot[1]+= g;
- rf->unshot[2]+= b;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ if(*fp!= 0.0) {
+
+ ref= &(vlr->mat->r);
+
+ r= (*fp)*unr*ref[0];
+ g= (*fp)*ung*ref[1];
+ b= (*fp)*unb*ref[2];
+
+ // if(rf->flag & RAD_BACKFACE) {
+
+ rf->totrad[0]+= r;
+ rf->totrad[1]+= g;
+ rf->totrad[2]+= b;
+
+ rf->unshot[0]+= r;
+ rf->unshot[1]+= g;
+ rf->unshot[2]+= b;
+ }
+ fp++;
}
- fp++;
}
}
/* shoot energy has been shot */
- shoot->radface->unshot[0]= shoot->radface->unshot[1]= shoot->radface->unshot[2]= 0.0;
+ shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0;
}
@@ -270,29 +288,30 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
static void progressiverad_rr(Render *re)
{
VlakRen *shoot;
+ RadFace *shootrf;
float unshot[3];
int it= 0;
- shoot= findshoot_rr(re);
+ findshoot_rr(re, &shoot, &shootrf);
while( shoot ) {
/* backfaces receive no energy, but are zbuffered... */
- backface_test_rr(re, shoot);
+ backface_test_rr(re, shoot, shootrf);
/* ...unless it's two sided */
- if(shoot->radface->flag & RAD_TWOSIDED) {
- VECCOPY(unshot, shoot->radface->unshot);
- VecMulf(shoot->radface->norm, -1.0);
- makeformfactors_rr(re, shoot);
- applyformfactors_rr(re, shoot);
- VecMulf(shoot->radface->norm, -1.0);
- VECCOPY(shoot->radface->unshot, unshot);
+ if(shootrf->flag & RAD_TWOSIDED) {
+ VECCOPY(unshot, shootrf->unshot);
+ VecMulf(shootrf->norm, -1.0);
+ makeformfactors_rr(re, shoot, shootrf);
+ applyformfactors_rr(re, shoot, shootrf);
+ VecMulf(shootrf->norm, -1.0);
+ VECCOPY(shootrf->unshot, unshot);
}
/* hemi-zbuffers */
- makeformfactors_rr(re, shoot);
+ makeformfactors_rr(re, shoot, shootrf);
/* based at RG.formfactors array, distribute shoot energy over other faces */
- applyformfactors_rr(re, shoot);
+ applyformfactors_rr(re, shoot, shootrf);
it++;
re->timecursor(it);
@@ -302,7 +321,7 @@ static void progressiverad_rr(Render *re)
if(re->test_break()) break;
if(RG.maxiter && RG.maxiter<=it) break;
- shoot= findshoot_rr(re);
+ findshoot_rr(re, &shoot, &shootrf);
}
printf(" Unshot energy:%f\n", 1000.0*maxenergy);
@@ -313,8 +332,9 @@ static RadFace *radfaces=NULL;
static void initradfaces(Render *re)
{
+ ObjectRen *obr;
VlakRen *vlr= NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
int a, b;
/* globals */
@@ -326,58 +346,63 @@ static void initradfaces(Render *re)
RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20;
/* count first for fast malloc */
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->mat->mode & MA_RADIO) {
- if(vlr->mat->emit > 0.0) {
- RG.totpatch++;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+
+ if(vlr->mat->mode & MA_RADIO) {
+ if(vlr->mat->emit > 0.0) {
+ RG.totpatch++;
+ }
+ RG.totelem++;
}
- RG.totelem++;
}
}
-
+
printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
if(RG.totelem==0 || RG.totpatch==0) return;
/* make/init radfaces */
rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces");
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->mat->mode & MA_RADIO) {
-
- /* during render, vlr->n gets flipped/corrected, we cannot have that */
- if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
- else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
-
- rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
- rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
- rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
- VECCOPY(rf->unshot, rf->totrad);
-
- if(vlr->v4) {
- rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
- CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
- }
- else {
- rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co);
- CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
- }
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
- RG.totenergy+= rf->unshot[0]*rf->area;
- RG.totenergy+= rf->unshot[1]*rf->area;
- RG.totenergy+= rf->unshot[2]*rf->area;
-
- for(b=0; b<3; b++) {
- RG.min[b]= MIN2(RG.min[b], rf->cent[b]);
- RG.max[b]= MAX2(RG.max[b], rf->cent[b]);
- }
+ if(vlr->mat->mode & MA_RADIO) {
+
+ /* during render, vlr->n gets flipped/corrected, we cannot have that */
+ if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
+ else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
+
+ rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
+ rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
+ rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
+ VECCOPY(rf->unshot, rf->totrad);
+
+ if(vlr->v4) {
+ rf->area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
+ CalcCent4f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
+ }
+ else {
+ rf->area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co);
+ CalcCent3f(rf->cent, vlr->v1->co, vlr->v2->co, vlr->v3->co);
+ }
+
+ RG.totenergy+= rf->unshot[0]*rf->area;
+ RG.totenergy+= rf->unshot[1]*rf->area;
+ RG.totenergy+= rf->unshot[2]*rf->area;
+
+ for(b=0; b<3; b++) {
+ RG.min[b]= MIN2(RG.min[b], rf->cent[b]);
+ RG.max[b]= MAX2(RG.max[b], rf->cent[b]);
+ }
-// uncommented; this isnt satisfying, but i leave it in the code for now (ton)
-// if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
-
- vlr->radface= rf++;
+ // uncommented; this isnt satisfying, but i leave it in the code for now (ton)
+ // if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED;
+
+ radface=RE_vlakren_get_radface(obr, vlr, 1);
+ *radface= rf++;
+ }
}
}
RG.size[0]= (RG.max[0]- RG.min[0]);
@@ -408,9 +433,10 @@ static void vecaddfac(float *vec, float *v1, float *v2, float fac)
static void make_vertex_rad_values(Render *re)
{
+ ObjectRen *obr;
VertRen *v1=NULL;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace *rf, **radface;
float *col;
int a;
@@ -418,54 +444,55 @@ static void make_vertex_rad_values(Render *re)
RG.radfactor= RG.radfac*pow(64*64, RG.igamma)/128.0; /* compatible with radio-tool */
/* accumulate vertexcolors */
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->radface) {
- rf= vlr->radface;
-
- /* apply correction */
- rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
- rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma);
- rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma);
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
- /* correct rf->rad values for color */
- if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r;
- if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g;
- if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b;
-
- col= RE_vertren_get_rad(re, vlr->v1, 1);
- vecaddfac(col, col, rf->totrad, rf->area);
- col[3]+= rf->area;
-
- col= RE_vertren_get_rad(re, vlr->v2, 1);
- vecaddfac(col, col, rf->totrad, rf->area);
- col[3]+= rf->area;
-
- col= RE_vertren_get_rad(re, vlr->v3, 1);
- vecaddfac(col, col, rf->totrad, rf->area);
- col[3]+= rf->area;
-
- if(vlr->v4) {
- col= RE_vertren_get_rad(re, vlr->v4, 1);
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+
+ /* apply correction */
+ rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);
+ rf->totrad[1]= RG.radfactor*pow( rf->totrad[1], RG.igamma);
+ rf->totrad[2]= RG.radfactor*pow( rf->totrad[2], RG.igamma);
+
+ /* correct rf->rad values for color */
+ if(vlr->mat->r > 0.0) rf->totrad[0]/= vlr->mat->r;
+ if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g;
+ if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b;
+
+ col= RE_vertren_get_rad(obr, vlr->v1, 1);
+ vecaddfac(col, col, rf->totrad, rf->area);
+ col[3]+= rf->area;
+
+ col= RE_vertren_get_rad(obr, vlr->v2, 1);
+ vecaddfac(col, col, rf->totrad, rf->area);
+ col[3]+= rf->area;
+
+ col= RE_vertren_get_rad(obr, vlr->v3, 1);
vecaddfac(col, col, rf->totrad, rf->area);
col[3]+= rf->area;
+
+ if(vlr->v4) {
+ col= RE_vertren_get_rad(obr, vlr->v4, 1);
+ vecaddfac(col, col, rf->totrad, rf->area);
+ col[3]+= rf->area;
+ }
}
}
- }
- /* make vertex colors */
- for(a=0; a<re->totvert; a++) {
- if((a & 255)==0) v1= RE_findOrAddVert(re, a); else v1++;
-
- col= RE_vertren_get_rad(re, v1, 0);
- if(col && col[3]>0.0) {
- col[0]/= col[3];
- col[1]/= col[3];
- col[2]/= col[3];
+ /* make vertex colors */
+ for(a=0; a<obr->totvert; a++) {
+ if((a & 255)==0) v1= RE_findOrAddVert(obr, a); else v1++;
+
+ col= RE_vertren_get_rad(obr, v1, 0);
+ if(col && col[3]>0.0) {
+ col[0]/= col[3];
+ col[1]/= col[3];
+ col[2]/= col[3];
+ }
}
}
-
}
/* main call, extern */
diff --git a/source/blender/readblenfile/intern/Makefile b/source/blender/readblenfile/intern/Makefile
index 6c6683eb07d..fa9875b8403 100644
--- a/source/blender/readblenfile/intern/Makefile
+++ b/source/blender/readblenfile/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_2_C_WARNINGS)
# path to our own external headerfiles
diff --git a/source/blender/readblenfile/stub/Makefile b/source/blender/readblenfile/stub/Makefile
index c5a9570522f..ed96e56b8af 100644
--- a/source/blender/readblenfile/stub/Makefile
+++ b/source/blender/readblenfile/stub/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_2_C_WARNINGS)
CFLAGS += $(FIX_STUBS_WARNINGS)
diff --git a/source/blender/readblenfile/test/Makefile b/source/blender/readblenfile/test/Makefile
index 2d7b7c7fff8..235abad36b5 100644
--- a/source/blender/readblenfile/test/Makefile
+++ b/source/blender/readblenfile/test/Makefile
@@ -37,10 +37,6 @@ ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)test$(EXT)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_2_C_WARNINGS)
# path to our own external headerfiles
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 9abc873172f..d8f6836005b 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -37,6 +37,8 @@
struct Scene;
struct RenderData;
struct NodeBlurData;
+struct Object;
+struct bNodeTree;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* this include is what is exposed of render to outside world */
@@ -72,7 +74,7 @@ typedef struct RenderLayer {
/* copy of RenderData */
char name[RE_MAXNAME];
- unsigned int lay;
+ unsigned int lay, lay_zmask;
int layflag, passflag, pass_xor;
struct Material *mat_override;
@@ -80,16 +82,18 @@ typedef struct RenderLayer {
float *rectf; /* 4 float, standard rgba buffer (read not above!) */
float *acolrect; /* 4 float, optional transparent buffer, needs storage for display updates */
+ float *scolrect; /* 4 float, optional strand buffer, needs storage for display updates */
ListBase passes;
} RenderLayer;
typedef struct RenderResult {
+ struct RenderResult *next, *prev;
/* target image size */
int rectx, recty;
- short crop, pad;
+ short crop, sample_nr;
/* optional, 32 bits version of picture, used for ogl render and image curves */
int *rect32;
@@ -111,7 +115,6 @@ typedef struct RenderResult {
volatile RenderLayer *renlay;
/* optional saved endresult on disk */
- char exrfile[FILE_MAXDIR];
void *exrhandle;
/* for render results in Image, verify validity for sequences */
@@ -119,8 +122,9 @@ typedef struct RenderResult {
} RenderResult;
+
typedef struct RenderStats {
- int totface, totvert, tothalo, totlamp, totpart;
+ int totface, totvert, totstrand, tothalo, totlamp, totpart;
short curfield, curblur, curpart, partsdone, convertdone;
double starttime, lastframetime;
char *infostr;
@@ -149,7 +153,7 @@ struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name)
float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype);
/* obligatory initialize call, disprect is optional */
-void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect);
+void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, int winx, int winy, rcti *disprect);
/* use this to change disprect of active render */
void RE_SetDispRect (struct Render *re, rcti *disprect);
@@ -184,6 +188,9 @@ void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode);
void RE_WriteRenderResult(RenderResult *rr, char *filename, int compress);
struct RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty);
+/* do a full sample buffer compo */
+void RE_MergeFullSample(struct Render *re, struct Scene *sce, struct bNodeTree *ntree);
+
/* ancient stars function... go away! */
void RE_make_stars(struct Render *re, void (*initfunc)(void),
void (*vertexfunc)(float*), void (*termfunc)(void));
@@ -204,14 +211,16 @@ float RE_filter_value(int type, float x);
void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect);
/* shaded view or baking options */
-#define RE_BAKE_LIGHT 0
-#define RE_BAKE_ALL 1
-#define RE_BAKE_AO 2
-#define RE_BAKE_NORMALS 3
-#define RE_BAKE_TEXTURE 4
-void RE_Database_Baking(struct Render *re, struct Scene *scene, int type);
+#define RE_BAKE_LIGHT 0
+#define RE_BAKE_ALL 1
+#define RE_BAKE_AO 2
+#define RE_BAKE_NORMALS 3
+#define RE_BAKE_TEXTURE 4
+#define RE_BAKE_DISPLACEMENT 5
+void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob);
void RE_DataBase_GetView(struct Render *re, float mat[][4]);
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]);
#endif /* RE_PIPELINE_H */
diff --git a/source/blender/render/extern/include/RE_raytrace.h b/source/blender/render/extern/include/RE_raytrace.h
new file mode 100644
index 00000000000..aec1c69b3dc
--- /dev/null
+++ b/source/blender/render/extern/include/RE_raytrace.h
@@ -0,0 +1,114 @@
+/**
+ * $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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * RE_raytrace.h: ray tracing api, can be used independently from the renderer.
+ */
+
+#ifndef RE_RAYTRACE_H
+#define RE_RAYTRACE_H
+
+/* ray types */
+#define RE_RAY_SHADOW 0
+#define RE_RAY_MIRROR 1
+#define RE_RAY_SHADOW_TRA 2
+
+/* spatial tree for raytracing acceleration */
+typedef void RayTree;
+/* abstraction of face type */
+typedef void RayFace;
+
+/* object numbers above this are transformed */
+#define RE_RAY_TRANSFORM_OFFS 0x8000000
+
+/* convert from pointer to index in array and back, with offset if the
+ * instance is transformed */
+#define RAY_OBJECT_SET(re, obi) \
+ ((obi == NULL)? 0: \
+ ((obi - (re)->objectinstance) + ((obi->flag & R_TRANSFORMED)? RE_RAY_TRANSFORM_OFFS: 0)))
+
+#define RAY_OBJECT_GET(re, i) \
+ ((re)->objectinstance + ((i >= RE_RAY_TRANSFORM_OFFS)? i-RE_RAY_TRANSFORM_OFFS: i))
+
+
+/* struct for intersection data */
+typedef struct Isect {
+ float start[3]; /* start+vec = end, in ray_tree_intersect */
+ float vec[3];
+ float end[3];
+
+ float labda, u, v; /* distance to hitpoint, uv weights */
+
+ RayFace *face; /* face is where to intersect with */
+ int ob;
+ RayFace *faceorig; /* start face */
+ int oborig;
+ RayFace *face_last; /* for shadow optimize, last intersected face */
+ int ob_last;
+
+ short isect; /* which half of quad */
+ short mode; /* RE_RAYSHADOW, RE_RAYMIRROR, RE_RAYSHADOW_TRA */
+ int lay; /* -1 default, set for layer lamps */
+
+ /* only used externally */
+ float col[4]; /* RGBA for shadow_tra */
+
+ /* octree only */
+ RayFace *facecontr;
+ int obcontr;
+ float ddalabda;
+ short faceisect; /* flag if facecontr was done or not */
+
+ /* custom pointer to be used in the RayCheckFunc */
+ void *userdata;
+} Isect;
+
+/* function callbacks for face type abstraction */
+typedef void (*RayCoordsFunc)(RayFace *face,
+ float **v1, float **v2, float **v3, float **v4);
+typedef int (*RayCheckFunc)(Isect *is, int ob, RayFace *face);
+typedef float *(*RayObjectTransformFunc)(void *userdata, int ob);
+
+/* tree building and freeing */
+RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max,
+ RayCoordsFunc coordfunc, RayCheckFunc checkfunc,
+ RayObjectTransformFunc transformfunc, void *userdata);
+void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face);
+void RE_ray_tree_done(RayTree *tree);
+void RE_ray_tree_free(RayTree *tree);
+
+/* intersection with full tree and single face */
+int RE_ray_tree_intersect(RayTree *tree, Isect *is);
+int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc check);
+int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc,
+ RayCoordsFunc coordsfunc);
+
+/* retrieve the diameter of the tree structure, for setting intersection
+ end distance */
+float RE_ray_tree_max_size(RayTree *tree);
+
+#endif /*__RE_RAYTRACE_H__*/
+
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 910be84b795..e61de5bc3e6 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -46,9 +46,13 @@ struct ImBuf;
void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re);
-/* effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */
+/* particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */
int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta);
+/* 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);
+
/* node_composite.c */
void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result);
void antialias_tagbuf(int xsize, int ysize, char *rectmove);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 364535736ae..e8403053e0b 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -47,7 +47,7 @@ typedef struct ShadeResult
{
float combined[4];
float col[4];
- float alpha;
+ float alpha, mist, z;
float diff[3]; /* no ramps, shadow, etc */
float spec[3];
float shad[3];
@@ -64,8 +64,12 @@ struct ShadeInputCopy {
struct Material *mat;
struct VlakRen *vlr;
+ struct StrandRen *strand;
+ struct ObjectInstanceRen *obi;
+ struct ObjectRen *obr;
int facenr;
float facenor[3]; /* copy from face */
+ short flippednor; /* is facenor flipped? */
struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */
short i1, i2, i3; /* original vertex indices */
short puno;
@@ -93,8 +97,12 @@ typedef struct ShadeInput
struct Material *mat;
struct VlakRen *vlr;
+ struct StrandRen *strand;
+ struct ObjectInstanceRen *obi;
+ struct ObjectRen *obr;
int facenr;
float facenor[3]; /* copy from face */
+ short flippednor; /* is facenor flipped? */
struct VertRen *v1, *v2, *v3; /* vertices can be in any order for quads... */
short i1, i2, i3; /* original vertex indices */
short puno;
@@ -120,17 +128,18 @@ typedef struct ShadeInput
/* end direct copy from material */
/* individual copies: */
- int har;
+ int har; /* hardness */
float layerfac;
/* texture coordinates */
- float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3];
+ float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4], rad[3];
float refcol[4], displace[3];
- float strand, tang[3], stress, winspeed[4];
+ float strandco, tang[3], nmaptang[3], stress, winspeed[4];
+ float duplilo[3], dupliuv[3];
ShadeInputUV uv[8]; /* 8 = MAX_MTFACE */
ShadeInputCol col[8]; /* 8 = MAX_MCOL */
- int totuv, totcol;
+ int totuv, totcol, actuv, actcol;
/* dx/dy OSA coordinates */
float dxco[3], dyco[3];
@@ -148,16 +157,20 @@ typedef struct ShadeInput
int xs, ys; /* pixel to be rendered */
int mask; /* subsample mask */
+
int samplenr; /* sample counter, to detect if we should do shadow again */
int depth; /* 1 or larger on raytrace shading */
/* stored copy of original face normal (facenor)
* before flipping. Used in Front/back output on geometry node */
float orignor[3];
+ /* for strand shading, normal at the surface */
+ float surfnor[3], surfdist;
/* from initialize, part or renderlayer */
short do_preview; /* for nodes, in previewrender */
short thread, sample; /* sample: ShadeSample array index */
+
unsigned int lay;
int layflag, passflag, combinedflag;
struct Group *light_override;
@@ -173,9 +186,10 @@ int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osa
/* shaded view and bake */
struct Render;
struct Image;
+struct Object;
void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr);
-int RE_bake_shade_all_selected(struct Render *re, int type);
+int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob);
struct Image *RE_bake_shade_get_image(void);
#endif /* RE_SHADER_EXT_H */
diff --git a/source/blender/render/intern/include/occlusion.h b/source/blender/render/intern/include/occlusion.h
new file mode 100644
index 00000000000..646ad30b318
--- /dev/null
+++ b/source/blender/render/intern/include/occlusion.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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef OCCLUSION_H
+#define OCCLUSION_H
+
+struct Render;
+struct ShadeInput;
+struct ShadeResult;
+struct RenderPart;
+struct ShadeSample;
+struct DerivedMesh;
+struct ObjectRen;
+
+void make_occ_tree(struct Render *re);
+void free_occ(struct Render *re);
+void sample_occ(struct Render *re, struct ShadeInput *shi);
+
+void cache_occ_samples(struct Render *re, struct RenderPart *pa, struct ShadeSample *ssamp);
+void free_occ_samples(struct Render *re, struct RenderPart *pa);
+
+#endif
+
diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h
index 04c5a3977a3..f7f4bc76eae 100644
--- a/source/blender/render/intern/include/pixelblending.h
+++ b/source/blender/render/intern/include/pixelblending.h
@@ -35,6 +35,8 @@
*/
void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w);
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
+void add_filt_fmask_coord(float filt[][3], float *col, float *rowbuf, int row_w, int col_h, int x, int y);
+void mask_array(unsigned int mask, float filt[][3]);
/**
* Alpha-over blending for floats.
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 45aff8e8b60..2aa6cc10468 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -32,6 +32,7 @@
/* exposed internal in render module only! */
/* ------------------------------------------------------------------------- */
+#include "DNA_color_types.h"
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
@@ -46,8 +47,9 @@ struct Object;
struct MemArena;
struct VertTableNode;
struct VlakTableNode;
-struct Octree;
struct GHash;
+struct RenderBuckets;
+struct ObjectInstanceRen;
#define TABLEINITSIZE 1024
#define LAMPINITSIZE 256
@@ -60,21 +62,36 @@ typedef struct SampleTables
} SampleTables;
+typedef struct QMCSampler
+{
+ int type;
+ int tot;
+ double *samp2d;
+ double offs[BLENDER_MAX_THREADS][2];
+} QMCSampler;
+
+#define SAMP_TYPE_JITTERED 0
+#define SAMP_TYPE_HALTON 1
+#define SAMP_TYPE_HAMMERSLEY 2
+
/* this is handed over to threaded hiding/passes/shading engine */
typedef struct RenderPart
{
struct RenderPart *next, *prev;
- /* result of part rendering */
- RenderResult *result;
+ RenderResult *result; /* result of part rendering */
+ ListBase fullresult; /* optional full sample buffers */
+ int *recto; /* object table for objects */
int *rectp; /* polygon index table */
int *rectz; /* zbuffer */
+ int *rectmask; /* negative zmask */
long *rectdaps; /* delta acum buffer for pixel structs */
+ int *rectbacko; /* object table for backside sss */
int *rectbackp; /* polygon index table for backside sss */
int *rectbackz; /* zbuffer for backside sss */
long *rectall; /* buffer for all faces for sss */
-
+
rcti disprect; /* part coordinates within total picture */
int rectx, recty; /* the size */
short crop, ready; /* crop is amount of pixels we crop, for filter */
@@ -84,16 +101,6 @@ typedef struct RenderPart
char *clipflag; /* clipflags for part zbuffering */
} RenderPart;
-typedef struct Octree {
- struct Branch **adrbranch;
- struct Node **adrnode;
- float ocsize; /* ocsize: mult factor, max size octree */
- float ocfacx,ocfacy,ocfacz;
- float min[3], max[3];
- int ocres;
- int branchcount, nodecount;
-} Octree;
-
/* controls state of render, everything that's read-only during render stage */
struct Render
{
@@ -107,6 +114,8 @@ struct Render
RenderResult *result;
/* if render with single-layer option, other rendered layers are stored here */
RenderResult *pushedresult;
+ /* a list of RenderResults, for fullsample */
+ ListBase fullresult;
/* window size, display rect, viewplane */
int winx, winy;
@@ -141,6 +150,10 @@ struct Render
/* samples */
SampleTables *samples;
float jit[32][2];
+ QMCSampler *qsa;
+
+ /* shadow counter, detect shadow-reuse for shaders */
+ int shadowsamplenr[BLENDER_MAX_THREADS];
/* scene, and its full copy of renderdata and world */
Scene *scene;
@@ -150,24 +163,28 @@ struct Render
ListBase parts;
/* octree tables and variables for raytrace */
- Octree oc;
+ void *raytree;
+
+ /* occlusion tree */
+ void *occlusiontree;
+ ListBase strandsurface;
/* use this instead of R.r.cfra */
float cfra;
/* render database */
- int totvlak, totvert, tothalo, totlamp;
+ int totvlak, totvert, tothalo, totstrand, totlamp;
+ struct HaloRen **sortedhalos;
+
ListBase lights; /* GroupObject pointers */
ListBase lampren; /* storage, for free */
- int vertnodeslen;
- struct VertTableNode *vertnodes;
- int vlaknodeslen;
- struct VlakTableNode *vlaknodes;
- int blohalen;
- struct HaloRen **bloha;
ListBase objecttable;
+ struct ObjectInstanceRen *objectinstance;
+ ListBase instancetable;
+ int totinstance;
+
struct Image *backbuf, *bakebuf;
struct GHash *orco_hash;
@@ -178,6 +195,8 @@ struct Render
ListBase customdata_names;
+ struct Object *excludeob;
+
/* arena for allocating data for use during render, for
* example dynamic TFaces to go in the VlakRen structure.
*/
@@ -225,23 +244,55 @@ typedef struct ShadBuf {
} ShadBuf;
/* ------------------------------------------------------------------------- */
-/* lookup of objects in database */
+
typedef struct ObjectRen {
struct ObjectRen *next, *prev;
struct Object *ob, *par;
- int index, startvert, endvert, startface, endface;
- float *vectors;
+ struct Scene *sce;
+ int index, psysindex, flag, lay;
+
+ float boundbox[2][3];
+
+ int totvert, totvlak, totstrand, tothalo;
+ int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
+ struct VertTableNode *vertnodes;
+ struct VlakTableNode *vlaknodes;
+ struct StrandTableNode *strandnodes;
+ struct HaloRen **bloha;
+ struct StrandBuffer *strandbuf;
+
+ char (*mtface)[32];
+ char (*mcol)[32];
+ int actmtface, actmcol;
+
+ float obmat[4][4]; /* only used in convertblender.c, for instancing */
} ObjectRen;
+typedef struct ObjectInstanceRen {
+ struct ObjectInstanceRen *next, *prev;
+
+ ObjectRen *obr;
+ Object *ob, *par;
+ int index, psysindex, lay;
+
+ float mat[4][4], nmat[3][3]; /* nmat is inverse mat tranposed */
+ short flag;
+
+ float dupliorco[3], dupliuv[2];
+ float (*duplitexmat)[4];
+
+ float *vectors;
+ int totvector;
+} ObjectInstanceRen;
+
/* ------------------------------------------------------------------------- */
typedef struct VertRen
{
float co[3];
float n[3];
- float ho[4];
float *orco;
- short clip;
+ short clip;
unsigned short flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c */
float accum; /* accum for radio weighting, and for strand texco static particles */
int index; /* index allows extending vertren with any property */
@@ -266,13 +317,10 @@ typedef struct RadFace {
typedef struct VlakRen {
struct VertRen *v1, *v2, *v3, *v4; /* keep in order for ** addressing */
- unsigned int lay;
float n[3];
struct Material *mat;
- char noflag, puno;
+ char puno;
char flag, ec;
- RadFace *radface;
- Object *ob;
int index;
} VlakRen;
@@ -292,6 +340,57 @@ typedef struct HaloRen
struct Material *mat;
} HaloRen;
+/* ------------------------------------------------------------------------- */
+
+typedef struct StrandVert {
+ float co[3];
+ float strandco;
+} StrandVert;
+
+typedef struct StrandSurface {
+ struct StrandSurface *next, *prev;
+ ObjectRen obr;
+ int (*face)[4];
+ float (*co)[3];
+ /* for occlusion caching */
+ float (*col)[3];
+ /* for speedvectors */
+ float (*prevco)[3], (*nextco)[3];
+ int totvert, totface;
+} StrandSurface;
+
+typedef struct StrandBound {
+ int start, end;
+ float boundbox[2][3];
+} StrandBound;
+
+typedef struct StrandBuffer {
+ struct StrandBuffer *next, *prev;
+ struct StrandVert *vert;
+ struct StrandBound *bound;
+ int totvert, totbound;
+
+ struct ObjectRen *obr;
+ struct Material *ma;
+ struct StrandSurface *surface;
+ unsigned int lay;
+ int overrideuv;
+ int flag, maxdepth;
+ float adaptcos, minwidth, widthfade;
+
+ float winmat[4][4];
+ int winx, winy;
+} StrandBuffer;
+
+typedef struct StrandRen {
+ StrandVert *vert;
+ StrandBuffer *buffer;
+ int totvert, flag;
+ int clip, index;
+ float orco[3];
+} StrandRen;
+
+
struct LampRen;
struct MTex;
@@ -322,7 +421,10 @@ typedef struct LampRen {
float vec[3];
float xsp, ysp, distkw, inpr;
float halokw, halo;
+
+ short falloff_type;
float ld1,ld2;
+ struct CurveMapping *curfalloff;
/* copied from Lamp, to decouple more rendering stuff */
/** Size of the shadowbuffer */
@@ -346,12 +448,14 @@ typedef struct LampRen {
/** A small depth offset to prevent self-shadowing. */
float bias;
- short ray_samp, ray_sampy, ray_sampz, ray_samp_type, area_shape, ray_totsamp;
+ short ray_samp, ray_sampy, ray_sampz, ray_samp_method, ray_samp_type, area_shape, ray_totsamp;
short xold[BLENDER_MAX_THREADS], yold[BLENDER_MAX_THREADS]; /* last jitter table for area lights */
float area_size, area_sizey, area_sizez;
-
+ float adapt_thresh;
+
struct ShadBuf *shb;
float *jitter;
+ QMCSampler *qsa;
float imat[3][3];
float spottexfac;
@@ -362,7 +466,7 @@ typedef struct LampRen {
/* passes & node shader support: all shadow info for a pixel */
LampShadowSample *shadsamp;
-
+
/* yafray: photonlight params */
int YF_numphotons, YF_numsearch;
short YF_phdepth, YF_useqmc, YF_bufsize;
@@ -372,8 +476,13 @@ typedef struct LampRen {
/* ray optim */
VlakRen *vlr_last[BLENDER_MAX_THREADS];
+ ObjectInstanceRen *obi_last[BLENDER_MAX_THREADS];
struct MTex *mtex[MAX_MTEX];
+
+ /* threading */
+ int thread_assigned;
+ int thread_ready;
} LampRen;
/* **************** defines ********************* */
@@ -386,10 +495,12 @@ typedef struct LampRen {
#define R_SEC_FIELD 4
#define R_LAMPHALO 8
#define R_GLOB_NOPUNOFLIP 16
+#define R_NEED_TANGENT 32
+#define R_SKIP_MULTIRES 64
/* vlakren->flag (vlak = face in dutch) char!!! */
#define R_SMOOTH 1
-#define R_VISIBLE 2
+#define R_HIDDEN 2
/* strand flag, means special handling */
#define R_STRAND 4
#define R_NOPUNOFLIP 8
@@ -400,13 +511,18 @@ typedef struct LampRen {
/* vertex normals are tangent or view-corrected vector, for hair strands */
#define R_TANGENT 128
-/* vlakren->noflag (char) */
-#define R_SNPROJ_X 1
-#define R_SNPROJ_Y 2
-#define R_SNPROJ_Z 4
-#define R_FLIPPED_NO 8
+/* strandbuffer->flag */
+#define R_STRAND_BSPLINE 1
+#define R_STRAND_B_UNITS 2
+/* objectren->flag */
+#define R_INSTANCEABLE 1
+/* objectinstance->flag */
+#define R_DUPLI_TRANSFORMED 1
+#define R_ENV_TRANSFORMED 2
+#define R_TRANSFORMED (1|2)
+#define R_NEED_VECTORS 4
#endif /* RENDER_TYPES_H */
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 651fd423e5d..cf1eeae58ec 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -49,13 +49,15 @@ struct ShadeResult;
struct World;
struct RenderPart;
struct RenderLayer;
+struct ObjectRen;
+struct ListBase;
/* ------------------------------------------------------------------------- */
typedef struct PixStr
{
struct PixStr *next;
- int facenr, z;
+ int obi, facenr, z, maskz;
unsigned short mask;
short shadfac;
} PixStr;
@@ -89,16 +91,23 @@ void zbufshadeDA_tile(struct RenderPart *pa);
void zbufshade_sss_tile(struct RenderPart *pa);
+int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp);
+
+
/* -------- ray.c ------- */
-extern void freeoctree(Render *re);
-extern void makeoctree(Render *re);
+extern void freeraytree(Render *re);
+extern void makeraytree(Render *re);
extern void ray_shadow(ShadeInput *, LampRen *, float *);
extern void ray_trace(ShadeInput *, ShadeResult *);
extern void ray_ao(ShadeInput *, float *);
extern void init_jitter_plane(LampRen *lar);
extern void init_ao_sphere(struct World *wrld);
+extern void init_lamp_hammersley(LampRen *lar);
+extern void free_lamp_qmcsampler(LampRen *lar);
+extern void init_render_hammersley(Render *re);
+extern void free_render_qmcsampler(Render *re);
#endif /* RENDER_EXT_H */
diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h
index 75aea05fee2..dc28eae1cc2 100644
--- a/source/blender/render/intern/include/renderdatabase.h
+++ b/source/blender/render/intern/include/renderdatabase.h
@@ -39,6 +39,10 @@ struct Render;
struct MCol;
struct MTFace;
struct CustomData;
+struct StrandBuffer;
+struct StrandRen;
+struct ObjectInstanceRen;
+struct RadFace;
#define RE_QUAD_MASK 0x7FFFFFF
#define RE_QUAD_OFFS 0x8000000
@@ -56,50 +60,74 @@ typedef struct VertTableNode {
typedef struct VlakTableNode {
struct VlakRen *vlak;
- struct MTFace **mtface;
- struct MCol **mcol;
+ struct MTFace *mtface;
+ struct MCol *mcol;
int totmtface, totmcol;
- struct CustomDataNames **names;
+ float *surfnor;
+ float *tangent;
+ struct RadFace **radface;
} VlakTableNode;
-typedef struct CustomDataNames{
- struct CustomDataNames *next, *prev;
-
- char (*mtface)[32];
- char (*mcol)[32];
-} CustomDataNames;
+typedef struct StrandTableNode {
+ struct StrandRen *strand;
+ float *winspeed;
+ float *surfnor;
+ float *simplify;
+ int *face;
+ struct MCol *mcol;
+ float *uv;
+ int totuv, totmcol;
+} StrandTableNode;
/* renderdatabase.c */
void free_renderdata_tables(struct Render *re);
void free_renderdata_vertnodes(struct VertTableNode *vertnodes);
void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes);
-void set_normalflags(Render *re);
-void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs);
+void set_normalflags(struct Render *re, struct ObjectRen *obr);
+void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets);
+int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]);
/* functions are not exported... so wrong names */
-struct VlakRen *RE_findOrAddVlak(struct Render *re, int nr);
-struct VertRen *RE_findOrAddVert(struct Render *re, int nr);
-struct HaloRen *RE_findOrAddHalo(struct Render *re, int nr);
-struct HaloRen *RE_inithalo(struct Render *re, struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
- float vectsize, int seed);
-void RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int sve, int eve, int sfa, int efa);
-
-float *RE_vertren_get_sticky(struct Render *re, struct VertRen *ver, int verify);
-float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify);
-float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify);
-float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify);
-float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify);
-float *RE_vertren_get_winspeed(struct Render *re, struct VertRen *ver, int verify);
-
-struct MTFace *RE_vlakren_get_tface(struct Render *re, VlakRen *ren, int n, char **name, int verify);
-struct MCol *RE_vlakren_get_mcol(struct Render *re, VlakRen *ren, int n, char **name, int verify);
-
-struct VertRen *RE_vertren_copy(struct Render *re, struct VertRen *ver);
-struct VlakRen *RE_vlakren_copy(struct Render *re, struct VlakRen *vlr);
-
-void RE_vlakren_set_customdata_names(struct Render *re, struct CustomData *data);
+struct VlakRen *RE_findOrAddVlak(struct ObjectRen *obr, int nr);
+struct VertRen *RE_findOrAddVert(struct ObjectRen *obr, int nr);
+struct StrandRen *RE_findOrAddStrand(struct ObjectRen *obr, int nr);
+struct HaloRen *RE_findOrAddHalo(struct ObjectRen *obr, int nr);
+struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Material *ma, float *vec, float *vec1, float *orco, float hasize, float vectsize, int seed);
+struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma, float *vec, float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed);
+struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
+
+struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
+struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay);
+void RE_makeRenderInstances(struct Render *re);
+void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor);
+
+float *RE_vertren_get_sticky(struct ObjectRen *obr, struct VertRen *ver, int verify);
+float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify);
+float *RE_vertren_get_rad(struct ObjectRen *obr, struct VertRen *ver, int verify);
+float *RE_vertren_get_strand(struct ObjectRen *obr, struct VertRen *ver, int verify);
+float *RE_vertren_get_tangent(struct ObjectRen *obr, struct VertRen *ver, int verify);
+float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ver, int verify);
+
+struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
+struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify);
+float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify);
+float *RE_vlakren_get_nmap_tangent(struct ObjectRen *obr, VlakRen *ren, int verify);
+RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify);
+int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor);
+
+float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify);
+float *RE_strandren_get_uv(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
+struct MCol *RE_strandren_get_mcol(struct ObjectRen *obr, struct StrandRen *strand, int n, char **name, int verify);
+float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify);
+int *RE_strandren_get_face(struct ObjectRen *obr, struct StrandRen *strand, int verify);
+float *RE_strandren_get_winspeed(struct ObjectInstanceRen *obi, struct StrandRen *strand, int verify);
+
+struct VertRen *RE_vertren_copy(struct ObjectRen *obr, struct VertRen *ver);
+struct VlakRen *RE_vlakren_copy(struct ObjectRen *obr, struct VlakRen *vlr);
+
+void RE_set_customdata_names(struct ObjectRen *obr, struct CustomData *data);
/* haloren->type: flags */
#define HA_ONLYSKY 1
diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h
index 8b786c6e098..9a0a5296341 100644
--- a/source/blender/render/intern/include/shadbuf.h
+++ b/source/blender/render/intern/include/shadbuf.h
@@ -37,6 +37,8 @@
#include "render_types.h"
+struct ObjectRen;
+
/**
* Calculates shadowbuffers for a vector of shadow-giving lamps
* @param lar The vector of lamps
@@ -44,6 +46,8 @@
void makeshadowbuf(struct Render *re, LampRen *lar);
void freeshadowbuf(struct LampRen *lar);
+void threaded_makeshadowbufs(struct Render *re);
+
/**
* Determines the shadow factor for a face and lamp. There is some
* communication with global variables here.
@@ -53,7 +57,7 @@ void freeshadowbuf(struct LampRen *lar);
* @param inp The inproduct between viewvector and ?
*
*/
-float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp);
+float testshadowbuf(struct Render *re, struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp, float mat_bias);
/**
* Determines the shadow factor for lamp <lar>, between <p1>
@@ -80,6 +84,7 @@ float ISB_getshadow(ShadeInput *shi, ShadBuf *shb);
typedef struct ISBSample {
float zco[3]; /* coordinate in lampview projection */
short *shadfac; /* initialized zero = full lighted */
+ int obi; /* object for face lookup */
int facenr; /* index in faces list */
} ISBSample;
@@ -87,6 +92,7 @@ typedef struct ISBSample {
typedef struct ISBSampleA {
float zco[3]; /* coordinate in lampview projection */
short *shadfac; /* NULL = full lighted */
+ int obi; /* object for face lookup */
int facenr; /* index in faces list */
struct ISBSampleA *next; /* in end, we want the first items to align with ISBSample */
} ISBSampleA;
@@ -94,6 +100,7 @@ typedef struct ISBSampleA {
/* used for transparent storage only */
typedef struct ISBShadfacA {
struct ISBShadfacA *next;
+ int obi;
int facenr;
float shadfac;
} ISBShadfacA;
diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h
index 902899bce94..6f1cb8dd7a9 100644
--- a/source/blender/render/intern/include/shading.h
+++ b/source/blender/render/intern/include/shading.h
@@ -29,6 +29,10 @@ struct RenderPart;
struct RenderLayer;
struct PixStr;
struct LampRen;
+struct VlakRen;
+struct StrandSegment;
+struct StrandPoint;
+struct ObjectInstanceRen obi;
/* shadeinput.c */
@@ -36,32 +40,36 @@ struct LampRen;
/* needed to calculate shadow and AO for an entire pixel */
typedef struct ShadeSample {
- int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
+ int tot; /* amount of shi in use, can be 1 for not FULL_OSA */
+
+ RenderLayer *rlpp[RE_MAX_OSA]; /* fast lookup from sample to renderlayer (fullsample buf) */
/* could be malloced once */
ShadeInput shi[RE_MAX_OSA];
ShadeResult shr[RE_MAX_OSA];
-
- int samplenr; /* counter, detect shadow-reuse for shaders */
} ShadeSample;
/* also the node shader callback */
void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr);
-void shade_input_set_triangle_i(struct ShadeInput *shi, struct VlakRen *vlr, short i1, short i2, short i3);
-void shade_input_set_triangle(struct ShadeInput *shi, volatile int facenr, int normal_flip);
+void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3);
+void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip);
void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from);
void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float z);
void shade_input_set_uv(struct ShadeInput *shi);
void shade_input_set_normals(struct ShadeInput *shi);
+void shade_input_flip_normals(struct ShadeInput *shi);
void shade_input_set_shade_texco(struct ShadeInput *shi);
+void shade_input_set_strand(struct ShadeInput *shi, struct StrandRen *strand, struct StrandPoint *spoint);
+void shade_input_set_strand_texco(struct ShadeInput *shi, struct StrandRen *strand, struct StrandVert *svert, struct StrandPoint *spoint);
void shade_input_do_shade(struct ShadeInput *shi, struct ShadeResult *shr);
void shade_input_initialize(struct ShadeInput *shi, struct RenderPart *pa, struct RenderLayer *rl, int sample);
void shade_sample_initialize(struct ShadeSample *ssamp, struct RenderPart *pa, struct RenderLayer *rl);
void shade_samples_do_AO(struct ShadeSample *ssamp);
+void shade_samples_fill_with_ps(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
int shade_samples(struct ShadeSample *ssamp, struct PixStr *ps, int x, int y);
void vlr_set_uv_indices(struct VlakRen *vlr, int *i1, int *i2, int *i3);
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
new file mode 100644
index 00000000000..ebe026e3fec
--- /dev/null
+++ b/source/blender/render/intern/include/strand.h
@@ -0,0 +1,116 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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: none of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef STRAND_H
+#define STRAND_H
+
+struct StrandVert;
+struct StrandRen;
+struct StrandBuffer;
+struct ShadeSample;
+struct StrandPart;
+struct Render;
+struct RenderPart;
+struct RenderBuckets;
+struct RenderPrimitiveIterator;
+struct ZSpan;
+struct ObjectInstanceRen;
+struct StrandSurface;
+struct DerivedMesh;
+struct ObjectRen;
+
+typedef struct StrandPoint {
+ /* position within segment */
+ float t;
+
+ /* camera space */
+ float co[3];
+ float nor[3];
+ float tan[3];
+ float strandco;
+ float width;
+
+ /* derivatives */
+ float dtco[3], dsco[3];
+ float dtstrandco;
+
+ /* outer points */
+ float co1[3], co2[3];
+ float hoco1[4], hoco2[4];
+ float zco1[3], zco2[3];
+ int clip1, clip2;
+
+ /* screen space */
+ float hoco[4];
+ float x, y;
+
+ /* simplification */
+ float alpha;
+} StrandPoint;
+
+typedef struct StrandSegment {
+ struct StrandVert *v[4];
+ struct StrandRen *strand;
+ struct StrandBuffer *buffer;
+ struct ObjectInstanceRen *obi;
+ float sqadaptcos;
+
+ StrandPoint point1, point2;
+ int shaded;
+} StrandSegment;
+
+struct StrandShadeCache;
+typedef struct StrandShadeCache StrandShadeCache;
+
+void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
+void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
+void strand_minmax(struct StrandRen *strand, float *min, float *max);
+
+struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
+void free_strand_surface(struct Render *re);
+
+struct StrandShadeCache *strand_shade_cache_create(void);
+void strand_shade_cache_free(struct StrandShadeCache *cache);
+void strand_shade_segment(struct Render *re, struct StrandShadeCache *cache, struct StrandSegment *sseg, struct ShadeSample *ssamp, float t, float s, int addpassflag);
+void strand_shade_unref(struct StrandShadeCache *cache, struct StrandVert *svert);
+
+struct RenderBuckets *init_buckets(struct Render *re);
+void add_buckets_primitive(struct RenderBuckets *buckets, float *min, float *max, void *prim);
+void free_buckets(struct RenderBuckets *buckets);
+void project_hoco_to_bucket(struct RenderBuckets *buckets, float *hoco, float *bucketco);
+
+struct RenderPrimitiveIterator *init_primitive_iterator(struct Render *re, struct RenderBuckets *buckets, struct RenderPart *pa);
+void *next_primitive_iterator(struct RenderPrimitiveIterator *iter);
+void free_primitive_iterator(struct RenderPrimitiveIterator *iter);
+
+#endif
+
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index ed3f93adfdd..346ed653977 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -35,6 +35,9 @@ struct RenderLayer;
struct LampRen;
struct VlakRen;
struct ListBase;
+struct ZSpan;
+struct APixstrand;
+struct StrandShadeCache;
void fillrect(int *rect, int x, int y, int val);
@@ -46,25 +49,37 @@ void projectvert(float *v1, float winmat[][4], float *adr);
void projectverto(float *v1, float winmat[][4], float *adr);
int testclip(float *v);
-void set_part_zbuf_clipflag(struct RenderPart *pa);
-void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size, float jitx, float jity);
-void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag);
-unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass);
+void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
+void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
+
+unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
-void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void *, int, int, int, int));
+void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
+int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, struct APixstrand *apixbuf, struct ListBase *apsmbase, struct StrandShadeCache *cache);
typedef struct APixstr {
- unsigned short mask[4]; /* jitter mask */
- int z[4]; /* distance */
- int p[4]; /* index */
- short shadfac[4]; /* optimize storage for irregular shadow */
+ unsigned short mask[4]; /* jitter mask */
+ int z[4]; /* distance */
+ int p[4]; /* index */
+ int obi[4]; /* object instance */
+ short shadfac[4]; /* optimize storage for irregular shadow */
struct APixstr *next;
} APixstr;
+typedef struct APixstrand {
+ unsigned short mask[4]; /* jitter mask */
+ int z[4]; /* distance */
+ int p[4]; /* index */
+ int obi[4]; /* object instance */
+ int seg[4]; /* for strands, segment number */
+ float u[4], v[4]; /* for strands, u,v coordinate in segment */
+ struct APixstrand *next;
+} APixstrand;
+
typedef struct APixstrMain
{
struct APixstrMain *next, *prev;
- struct APixstr *ps;
+ void *ps;
} APixstrMain;
/* span fill in method, is also used to localize data for zbuffering */
@@ -80,32 +95,42 @@ typedef struct ZSpan {
int *rectz, *arectz; /* zbuffers, arectz is for transparant */
int *rectz1; /* seconday z buffer for shadowbuffer (2nd closest z) */
int *rectp; /* polygon index buffer */
+ int *recto; /* object buffer */
+ int *rectmask; /* negative zmask buffer */
APixstr *apixbuf, *curpstr; /* apixbuf for transparent */
+ APixstrand *curpstrand; /* same for strands */
struct ListBase *apsmbase;
int polygon_offset; /* offset in Z */
float shad_alpha; /* copy from material, used by irregular shadbuf */
int mask, apsmcounter; /* in use by apixbuf */
+ int apstrandmcounter;
+
+ float clipcrop; /* for shadow, was in R global before */
void *sss_handle; /* used by sss */
- void (*sss_func)(void *, int, int, int, int);
+ void (*sss_func)(void *, int, int, int, int, int);
- void (*zbuffunc)(struct ZSpan *, int, float *, float *, float *, float *);
- void (*zbuflinefunc)(struct ZSpan *, int, float *, float *);
+ void (*zbuffunc)(struct ZSpan *, int, int, float *, float *, float *, float *);
+ void (*zbuflinefunc)(struct ZSpan *, int, int, float *, float *);
} ZSpan;
/* exported to shadbuf.c */
-void zbufclip4(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4);
+void zbufclip4(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4);
void zbuf_free_span(struct ZSpan *zspan);
/* to rendercore.c */
void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) );
/* exported to edge render... */
-void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
-void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty);
-void zbufclipwire(struct ZSpan *zspan, int zvlnr, struct VlakRen *vlr);
+void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3);
+void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop);
+void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4);
+
+/* exported to shadeinput.c */
+void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4]);
+void zbuf_render_project(float winmat[][4], float *co, float *ho);
#endif
diff --git a/source/blender/render/intern/source/Makefile b/source/blender/render/intern/source/Makefile
index f9b3dfc482a..95835f212e8 100644
--- a/source/blender/render/intern/source/Makefile
+++ b/source/blender/render/intern/source/Makefile
@@ -36,11 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
- CCFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
# first /include is my own includes, second is the external interface.
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index cdeddca5216..dc62f37731a 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -44,6 +44,7 @@
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_material_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
@@ -54,9 +55,11 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
@@ -64,8 +67,10 @@
#include "BKE_anim.h"
#include "BKE_armature.h"
#include "BKE_action.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
+#include "BKE_colortools.h"
#include "BKE_constraint.h"
#include "BKE_displist.h"
#include "BKE_deform.h"
@@ -82,8 +87,10 @@
#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
#include "BKE_texture.h"
@@ -95,6 +102,7 @@
#include "envmap.h"
#include "multires.h"
+#include "occlusion.h"
#include "render_types.h"
#include "rendercore.h"
#include "renderdatabase.h"
@@ -102,8 +110,10 @@
#include "radio.h"
#include "shadbuf.h"
#include "shading.h"
+#include "strand.h"
#include "texture.h"
#include "sss.h"
+#include "strand.h"
#include "zbuf.h"
#ifndef DISABLE_YAFRAY /* disable yafray */
@@ -114,22 +124,15 @@
* Same is true for lamp coords & vec.
* Duplicated data objects & dupliframe/duplivert objects are only stored once,
* only the matrix is stored for all others, in yafray these objects are instances of the original.
- * The main changes are in RE_rotateBlenderScene().
+ * The main changes are in RE_Database_FromScene().
*/
#endif /* disable yafray */
-/* ------------------------------------------------------------------------- */
-/* Local functions */
-/* ------------------------------------------------------------------------- */
-static short test_for_displace(Render *re, Object *ob);
-static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert );
-
/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */
/* or for checking vertex normal flips */
#define FLT_EPSILON10 1.19209290e-06F
-
/* ------------------------------------------------------------------------- */
/* Stuff for stars. This sits here because it uses gl-things. Part of
@@ -137,14 +140,14 @@ this code may move down to the converter. */
/* ------------------------------------------------------------------------- */
/* this is a bad beast, since it is misused by the 3d view drawing as well. */
-static HaloRen *initstar(Render *re, float *vec, float hasize)
+static HaloRen *initstar(Render *re, ObjectRen *obr, float *vec, float hasize)
{
HaloRen *har;
float hoco[4];
projectverto(vec, re->winmat, hoco);
- har= RE_findOrAddHalo(re, re->tothalo++);
+ har= RE_findOrAddHalo(obr, obr->tothalo++);
/* projectvert is done in function zbufvlaggen again, because of parts */
VECCOPY(har->co, vec);
@@ -165,6 +168,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
void (*vertexfunc)(float*), void (*termfunc)(void))
{
extern unsigned char hash[512];
+ ObjectRen *obr= NULL;
World *wrld= NULL;
HaloRen *har;
Scene *scene;
@@ -228,11 +232,14 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
if (initfunc) {
initfunc();
}
+
+ if(re) /* add render object for stars */
+ obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0);
for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) {
for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) {
-
+
BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8));
vec[0] = fx + (hlfrand * BLI_drand()) - dblrand;
vec[1] = fy + (hlfrand * BLI_drand()) - dblrand;
@@ -275,7 +282,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
if (alpha != 0.0) {
fac = force * BLI_drand();
- har = initstar(re, vec, fac);
+ har = initstar(re, obr, vec, fac);
if (har) {
har->alfa = sqrt(sqrt(alpha));
@@ -299,6 +306,9 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
}
}
if (termfunc) termfunc();
+
+ if(obr)
+ re->tothalo += obr->tothalo;
}
@@ -322,35 +332,35 @@ u | | F1 | F2 |
/* ------------------------------------------------------------------------- */
-static void split_v_renderfaces(Render *re, int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
+static void split_v_renderfaces(ObjectRen *obr, int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv)
{
int vLen = vsize-1+(!!cyclv);
int v;
for (v=0; v<vLen; v++) {
- VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v);
- VertRen *vert = RE_vertren_copy(re, vlr->v2);
+ VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v);
+ VertRen *vert = RE_vertren_copy(obr, vlr->v2);
if (cyclv) {
vlr->v2 = vert;
if (v==vLen-1) {
- VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + 0);
+ VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + 0);
vlr->v1 = vert;
} else {
- VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
+ VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1);
vlr->v1 = vert;
}
} else {
vlr->v2 = vert;
if (v<vLen-1) {
- VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1);
+ VlakRen *vlr = RE_findOrAddVlak(obr, startvlak + vLen*uIndex + v+1);
vlr->v1 = vert;
}
if (v==0) {
- vlr->v1 = RE_vertren_copy(re, vlr->v1);
+ vlr->v1 = RE_vertren_copy(obr, vlr->v1);
}
}
}
@@ -368,6 +378,8 @@ static int check_vnormal(float *n, float *veno)
}
/* ------------------------------------------------------------------------- */
+/* Stress, tangents and normals */
+/* ------------------------------------------------------------------------- */
static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
{
@@ -383,20 +395,20 @@ static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2)
acc[1]+= 1.0f;
}
-static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
+static void calc_edge_stress(Render *re, ObjectRen *obr, Mesh *me)
{
float loc[3], size[3], *accum, *acc, *accumoffs, *stress;
int a;
- if(startvert==re->totvert) return;
+ if(obr->totvert==0) return;
mesh_get_texspace(me, loc, NULL, size);
- accum= MEM_callocN(2*sizeof(float)*(re->totvert-startvert), "temp accum for stress");
+ accum= MEM_callocN(2*sizeof(float)*obr->totvert, "temp accum for stress");
/* de-normalize orco */
- for(a=startvert; a<re->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
if(ver->orco) {
ver->orco[0]= ver->orco[0]*size[0] +loc[0];
ver->orco[1]= ver->orco[1]*size[1] +loc[1];
@@ -405,9 +417,9 @@ static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
}
/* add stress values */
- accumoffs= accum - 2*startvert; /* so we can use vertex index */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
+ accumoffs= accum; /* so we can use vertex index */
+ for(a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
if(vlr->v1->orco && vlr->v4) {
calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2);
@@ -421,14 +433,14 @@ static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
}
}
- for(a=startvert; a<re->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
if(ver->orco) {
/* find stress value */
acc= accumoffs + 2*ver->index;
if(acc[1]!=0.0f)
acc[0]/= acc[1];
- stress= RE_vertren_get_stress(re, ver, 1);
+ stress= RE_vertren_get_stress(obr, ver, 1);
*stress= *acc;
/* restore orcos */
@@ -441,14 +453,84 @@ static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak)
MEM_freeN(accum);
}
+void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang)
+{
+ float tangv[3], ct[3], e1[3], e2[3], s1, t1, s2, t2, det;
+
+ s1= uv2[0] - uv1[0];
+ s2= uv3[0] - uv1[0];
+ t1= uv2[1] - uv1[1];
+ t2= uv3[1] - uv1[1];
+ det= 1.0f / (s1 * t2 - s2 * t1);
+
+ /* normals in render are inversed... */
+ VecSubf(e1, co1, co2);
+ VecSubf(e2, co1, co3);
+ tang[0] = (t2*e1[0] - t1*e2[0])*det;
+ tang[1] = (t2*e1[1] - t1*e2[1])*det;
+ tang[2] = (t2*e1[2] - t1*e2[2])*det;
+ tangv[0] = (s1*e2[0] - s2*e1[0])*det;
+ tangv[1] = (s1*e2[1] - s2*e1[1])*det;
+ tangv[2] = (s1*e2[2] - s2*e1[2])*det;
+ Crossf(ct, tang, tangv);
+
+ /* check flip */
+ if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
+ VecMulf(tang, -1.0f);
+}
+
+/* For normal map tangents we need to detect uv boundaries, and only average
+ * tangents in case the uvs are connected. Alternative would be to store 1
+ * tangent per face rather than 4 per face vertex, but that's not compatible
+ * with games */
+
+typedef struct VertexTangent {
+ float tang[3], uv[2];
+ struct VertexTangent *next;
+} VertexTangent;
+
+static void sum_or_add_vertex_tangent(MemArena *arena, VertexTangent **vtang, float *tang, float *uv)
+{
+ VertexTangent *vt;
+
+ /* find a tangent with connected uvs */
+ for(vt= *vtang; vt; vt=vt->next) {
+ if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
+ VECADD(vt->tang, vt->tang, tang);
+ return;
+ }
+ }
+
+ /* if not found, append a new one */
+ vt= BLI_memarena_alloc(arena, sizeof(VertexTangent));
+ VECCOPY(vt->tang, tang);
+ vt->uv[0]= uv[0];
+ vt->uv[1]= uv[1];
+
+ if(*vtang)
+ vt->next= *vtang;
+ *vtang= vt;
+}
+
+static float *find_vertex_tangent(VertexTangent *vtang, float *uv)
+{
+ VertexTangent *vt;
+ static float nulltang[3] = {0.0f, 0.0f, 0.0f};
+
+ for(vt= vtang; vt; vt=vt->next)
+ if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT)
+ return vt->tang;
+
+ return nulltang; /* shouldn't happen, except for nan or so */
+}
+
/* gets tangent from tface or orco */
-static void calc_tangent_vector(Render *re, VlakRen *vlr)
+static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemArena *arena, VlakRen *vlr, int do_nmap_tangent, int do_tangent)
{
- MTFace *tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
+ MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
- float tang[3], tangv[3], ct[3], e1[3], e2[3], *tav;
+ float tang[3], *tav;
float *uv1, *uv2, *uv3, *uv4;
- float s1, s2, t1, t2, det;
float uv[4][2];
if(tface) {
@@ -466,78 +548,68 @@ static void calc_tangent_vector(Render *re, VlakRen *vlr)
spheremap(v4->orco[0], v4->orco[1], v4->orco[2], &uv[3][0], &uv[3][1]);
}
else return;
+
+ tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, vlr->n, tang);
- s1= uv2[0] - uv1[0];
- s2= uv3[0] - uv1[0];
- t1= uv2[1] - uv1[1];
- t2= uv3[1] - uv1[1];
- det= 1.0f / (s1 * t2 - s2 * t1);
-
- /* normals in render are inversed... */
- VecSubf(e1, v1->co, v2->co);
- VecSubf(e2, v1->co, v3->co);
- tang[0] = (t2*e1[0] - t1*e2[0])*det;
- tang[1] = (t2*e1[1] - t1*e2[1])*det;
- tang[2] = (t2*e1[2] - t1*e2[2])*det;
- tangv[0] = (s1*e2[0] - s2*e1[0])*det;
- tangv[1] = (s1*e2[1] - s2*e1[1])*det;
- tangv[2] = (s1*e2[2] - s2*e1[2])*det;
- Crossf(ct, tang, tangv);
- /* check flip */
- if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
- VecMulf(tang, -1.f);
-
- tav= RE_vertren_get_tangent(re, v1, 1);
- VECADD(tav, tav, tang);
- tav= RE_vertren_get_tangent(re, v2, 1);
- VECADD(tav, tav, tang);
- tav= RE_vertren_get_tangent(re, v3, 1);
- VECADD(tav, tav, tang);
-
- if(v4) {
- s1= uv3[0] - uv1[0];
- s2= uv4[0] - uv1[0];
- t1= uv3[1] - uv1[1];
- t2= uv4[1] - uv1[1];
- det= 1.0f / (s1 * t2 - s2 * t1);
-
- /* normals in render are inversed... */
- VecSubf(e1, v1->co, v3->co);
- VecSubf(e2, v1->co, v4->co);
- tang[0] = (t2*e1[0] - t1*e2[0])*det;
- tang[1] = (t2*e1[1] - t1*e2[1])*det;
- tang[2] = (t2*e1[2] - t1*e2[2])*det;
- tangv[0] = (s1*e2[0] - s2*e1[0])*det;
- tangv[1] = (s1*e2[1] - s2*e1[1])*det;
- tangv[2] = (s1*e2[2] - s2*e1[2])*det;
- Crossf(ct, tang, tangv);
- if ((ct[0]*vlr->n[0] + ct[1]*vlr->n[1] + ct[2]*vlr->n[2]) < 0.f)
- VecMulf(tang, -1.f);
-
- tav= RE_vertren_get_tangent(re, v1, 1);
+ if(do_tangent) {
+ tav= RE_vertren_get_tangent(obr, v1, 1);
VECADD(tav, tav, tang);
- tav= RE_vertren_get_tangent(re, v3, 1);
+ tav= RE_vertren_get_tangent(obr, v2, 1);
VECADD(tav, tav, tang);
- tav= RE_vertren_get_tangent(re, v4, 1);
+ tav= RE_vertren_get_tangent(obr, v3, 1);
VECADD(tav, tav, tang);
}
+
+ if(do_nmap_tangent) {
+ sum_or_add_vertex_tangent(arena, &vtangents[v1->index], tang, uv1);
+ sum_or_add_vertex_tangent(arena, &vtangents[v2->index], tang, uv2);
+ sum_or_add_vertex_tangent(arena, &vtangents[v3->index], tang, uv3);
+ }
+
+ if(v4) {
+ tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, vlr->n, tang);
+
+ if(do_tangent) {
+ tav= RE_vertren_get_tangent(obr, v1, 1);
+ VECADD(tav, tav, tang);
+ tav= RE_vertren_get_tangent(obr, v3, 1);
+ VECADD(tav, tav, tang);
+ tav= RE_vertren_get_tangent(obr, v4, 1);
+ VECADD(tav, tav, tang);
+ }
+
+ if(do_nmap_tangent) {
+ sum_or_add_vertex_tangent(arena, &vtangents[v1->index], tang, uv1);
+ sum_or_add_vertex_tangent(arena, &vtangents[v3->index], tang, uv3);
+ sum_or_add_vertex_tangent(arena, &vtangents[v4->index], tang, uv4);
+ }
+ }
}
-static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_tangent)
+static void calc_vertexnormals(Render *re, ObjectRen *obr, int do_tangent, int do_nmap_tangent)
{
+ MemArena *arena= NULL;
+ VertexTangent **vtangents= NULL;
int a;
+ if(do_nmap_tangent) {
+ arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ BLI_memarena_use_calloc(arena);
+
+ vtangents= MEM_callocN(sizeof(VertexTangent*)*obr->totvert, "VertexTangent");
+ }
+
/* clear all vertex normals */
- for(a=startvert; a<re->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
ver->n[0]=ver->n[1]=ver->n[2]= 0.0f;
}
/* calculate cos of angles and point-masses, use as weight factor to
add face normal to vertex */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
if(vlr->flag & ME_SMOOTH) {
VertRen *v1= vlr->v1;
VertRen *v2= vlr->v2;
@@ -600,16 +672,16 @@ static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_
v3->n[2] +=fac3*vlr->n[2];
}
- if(do_tangent) {
+ if(do_nmap_tangent || do_tangent) {
/* tangents still need to be calculated for flat faces too */
/* weighting removed, they are not vertexnormals */
- calc_tangent_vector(re, vlr);
+ calc_tangent_vector(obr, vtangents, arena, vlr, do_nmap_tangent, do_tangent);
}
}
/* do solid faces */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
if((vlr->flag & ME_SMOOTH)==0) {
float *f1= vlr->v1->n;
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
@@ -622,14 +694,38 @@ static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
}
}
+
+ if(do_nmap_tangent) {
+ VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4;
+ MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
+
+ if(tface) {
+ float *vtang, *ftang= RE_vlakren_get_nmap_tangent(obr, vlr, 1);
+
+ vtang= find_vertex_tangent(vtangents[v1->index], tface->uv[0]);
+ VECCOPY(ftang, vtang);
+ Normalize(ftang);
+ vtang= find_vertex_tangent(vtangents[v2->index], tface->uv[1]);
+ VECCOPY(ftang+3, vtang);
+ Normalize(ftang+3);
+ vtang= find_vertex_tangent(vtangents[v3->index], tface->uv[2]);
+ VECCOPY(ftang+6, vtang);
+ Normalize(ftang+6);
+ if(v4) {
+ vtang= find_vertex_tangent(vtangents[v4->index], tface->uv[3]);
+ VECCOPY(ftang+9, vtang);
+ Normalize(ftang+9);
+ }
+ }
+ }
}
/* normalize vertex normals */
- for(a=startvert; a<re->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
Normalize(ver->n);
if(do_tangent) {
- float *tav= RE_vertren_get_tangent(re, ver, 0);
+ float *tav= RE_vertren_get_tangent(obr, ver, 0);
if (tav) {
/* orthonorm. */
float tdn = tav[0]*ver->n[0] + tav[1]*ver->n[1] + tav[2]*ver->n[2];
@@ -641,39 +737,25 @@ static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_
}
}
- /* vertex normal (puno) switch flags for during render */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
-
- if((vlr->flag & R_NOPUNOFLIP)==0) {
- float *v1= vlr->v1->n;
- float *v2= vlr->v2->n;
- float *v3= vlr->v3->n;
- float *v4= vlr->v4?vlr->v4->n:NULL;
- float *nor= vlr->n;
- vlr->puno &= ~15;
- if ((nor[0]*v1[0] + nor[1]*v1[1] + nor[2]*v1[2]) < -FLT_EPSILON10) vlr->puno= 1;
- if ((nor[0]*v2[0] + nor[1]*v2[1] + nor[2]*v2[2]) < -FLT_EPSILON10) vlr->puno+= 2;
- if ((nor[0]*v3[0] + nor[1]*v3[1] + nor[2]*v3[2]) < -FLT_EPSILON10) vlr->puno+= 4;
- if(v4) {
- if((nor[0]*v4[0] + nor[1]*v4[1] + nor[2]*v4[2]) < -FLT_EPSILON10 ) vlr->puno+= 8;
- }
- }
- }
+
+ if(arena)
+ BLI_memarena_free(arena);
+ if(vtangents)
+ MEM_freeN(vtangents);
}
// NT same as calc_vertexnormals, but dont modify the existing vertex normals
// only recalculate other render data. If this is at some point used for other things than fluidsim,
// this could be made on option for the normal calc_vertexnormals
-static void calc_fluidsimnormals(Render *re, int startvert, int startvlak, int do_tangent)
+static void calc_fluidsimnormals(Render *re, ObjectRen *obr, int do_nmap_tangent)
{
int a;
/* dont clear vertex normals here */
- // OFF for(a=startvert; a<re->totvert; a++) { VertRen *ver= RE_findOrAddVert(re, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
+ // OFF for(a=0; a<obr->totvert; a++) { VertRen *ver= RE_findOrAddVert(obr, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
/* calculate cos of angles and point-masses, use as weight factor to add face normal to vertex */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
if(vlr->flag & ME_SMOOTH) {
VertRen *v1= vlr->v1;
VertRen *v2= vlr->v2;
@@ -712,19 +794,19 @@ static void calc_fluidsimnormals(Render *re, int startvert, int startvlak, int d
}
}
- //if(do_tangent)
- // calc_tangent_vector(re, vlr, fac1, fac2, fac3, fac4);
+ //if(do_nmap_tangent)
+ // calc_tangent_vector(obr, vlr, fac1, fac2, fac3, fac4);
}
- if(do_tangent) {
+ if(do_nmap_tangent) {
/* tangents still need to be calculated for flat faces too */
/* weighting removed, they are not vertexnormals */
- calc_tangent_vector(re, vlr);
+ //calc_tangent_vector(obr, vlr);
}
}
/* do solid faces */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(obr, a);
if((vlr->flag & ME_SMOOTH)==0) {
float *f1= vlr->v1->n;
if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
@@ -740,32 +822,14 @@ static void calc_fluidsimnormals(Render *re, int startvert, int startvlak, int d
}
/* normalize vertex normals */
- for(a=startvert; a<re->totvert; a++) {
- VertRen *ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(obr, a);
Normalize(ver->n);
- if(do_tangent) {
- float *tav= RE_vertren_get_tangent(re, ver, 0);
+ if(do_nmap_tangent) {
+ float *tav= RE_vertren_get_tangent(obr, ver, 0);
if(tav) Normalize(tav);
}
}
-
- /* vertex normal (puno) switch flags for during render */
- for(a=startvlak; a<re->totvlak; a++) {
- VlakRen *vlr= RE_findOrAddVlak(re, a);
- if((vlr->flag & R_NOPUNOFLIP)==0) {
- VertRen *v1= vlr->v1;
- VertRen *v2= vlr->v2;
- VertRen *v3= vlr->v3;
- VertRen *v4= vlr->v4;
- vlr->puno &= ~15;
- if ((vlr->n[0]*v1->n[0]+vlr->n[1]*v1->n[1]+vlr->n[2]*v1->n[2])<0.0) vlr->puno= 1;
- if ((vlr->n[0]*v2->n[0]+vlr->n[1]*v2->n[1]+vlr->n[2]*v2->n[2])<0.0) vlr->puno+= 2;
- if ((vlr->n[0]*v3->n[0]+vlr->n[1]*v3->n[1]+vlr->n[2]*v3->n[2])<0.0) vlr->puno+= 4;
- if(v4) {
- if((vlr->n[0]*v4->n[0]+vlr->n[1]*v4->n[1]+vlr->n[2]*v4->n[2])<0.0) vlr->puno+= 8;
- }
- }
- }
}
/* ------------------------------------------------------------------------- */
@@ -864,18 +928,17 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thr
/* note; autosmooth happens in object space still, after applying autosmooth we rotate */
/* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */
-static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak, int degr)
+static void autosmooth(Render *re, ObjectRen *obr, float mat[][4], int degr)
{
- ASvert *asv, *asverts, *asvertoffs;
+ ASvert *asv, *asverts;
ASface *asf;
VertRen *ver, *v1;
VlakRen *vlr;
float thresh;
int a, b, totvert;
- if(startvert==re->totvert) return;
- asverts= MEM_callocN(sizeof(ASvert)*(re->totvert-startvert), "all smooth verts");
- asvertoffs= asverts-startvert; /* se we can use indices */
+ if(obr->totvert==0) return;
+ asverts= MEM_callocN(sizeof(ASvert)*obr->totvert, "all smooth verts");
thresh= cos( M_PI*(0.5f+(float)degr)/180.0 );
@@ -883,24 +946,24 @@ static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak,
/* step one: construct listbase of all vertices and pointers to faces */
- for(a=startvlak; a<re->totvlak; a++) {
- vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
/* skip wire faces */
if(vlr->v2 != vlr->v3) {
- as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr);
- as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr);
- as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr);
+ as_addvert(asverts+vlr->v1->index, vlr->v1, vlr);
+ as_addvert(asverts+vlr->v2->index, vlr->v2, vlr);
+ as_addvert(asverts+vlr->v3->index, vlr->v3, vlr);
if(vlr->v4)
- as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr);
+ as_addvert(asverts+vlr->v4->index, vlr->v4, vlr);
}
}
+ totvert= obr->totvert;
/* we now test all vertices, when faces have a normal too much different: they get a new vertex */
- totvert= re->totvert;
- for(a=startvert, asv=asverts; a<totvert; a++, asv++) {
+ for(a=0, asv=asverts; a<totvert; a++, asv++) {
if(asv && asv->totface>1) {
- ver= RE_findOrAddVert(re, a);
-
+ ver= RE_findOrAddVert(obr, a);
+
asf= asv->faces.first;
while(asf) {
for(b=0; b<4; b++) {
@@ -913,7 +976,7 @@ static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak,
v1= as_findvertex(vlr, ver, asv, thresh);
if(v1==NULL) {
/* make a new vertex */
- v1= RE_vertren_copy(re, ver);
+ v1= RE_vertren_copy(obr, ver);
}
asf->nver[b]= v1;
if(vlr->v1==ver) vlr->v1= v1;
@@ -928,18 +991,18 @@ static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak,
}
/* free */
- for(a=0; a<totvert-startvert; a++) {
+ for(a=0; a<totvert; a++) {
BLI_freelistN(&asverts[a].faces);
}
MEM_freeN(asverts);
/* rotate vertices and calculate normal of faces */
- for(a=startvert; a<re->totvert; a++) {
- ver= RE_findOrAddVert(re, a);
+ for(a=0; a<obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
MTC_Mat4MulVecfl(mat, ver->co);
}
- for(a=startvlak; a<re->totvlak; a++) {
- vlr= RE_findOrAddVlak(re, a);
+ for(a=0; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
/* skip wire faces */
if(vlr->v2 != vlr->v3) {
@@ -952,14 +1015,9 @@ static void autosmooth(Render *re, float mat[][4], int startvert, int startvlak,
}
/* ------------------------------------------------------------------------- */
-/* End of autosmoothing: */
+/* Orco hash and Materials */
/* ------------------------------------------------------------------------- */
-/* ------------------------------------------------------------------------- */
-/* Orco hash */
-/* ------------------------------------------------------------------------- */
-
-
static float *get_object_orco(Render *re, Object *ob)
{
float *orco;
@@ -970,12 +1028,12 @@ static float *get_object_orco(Render *re, Object *ob)
orco = BLI_ghash_lookup(re->orco_hash, ob);
if (!orco) {
- if (ob->type==OB_MESH) {
- orco = mesh_create_orco_render(ob);
- } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
+ if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
orco = make_orco_curve(ob);
} else if (ob->type==OB_SURF) {
orco = make_orco_surf(ob);
+ } else if (ob->type==OB_MBALL) {
+ orco = make_orco_mball(ob);
}
if (orco)
@@ -985,6 +1043,14 @@ static float *get_object_orco(Render *re, Object *ob)
return orco;
}
+static void set_object_orco(Render *re, void *ob, float *orco)
+{
+ if (!re->orco_hash)
+ re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ BLI_ghash_insert(re->orco_hash, ob, orco);
+}
+
static void free_mesh_orco_hash(Render *re)
{
if (re->orco_hash) {
@@ -993,59 +1059,6 @@ static void free_mesh_orco_hash(Render *re)
}
}
-/* ******************** END ORCO HASH ***************** */
-
-
-static void make_render_halos(Render *re, Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
-{
- HaloRen *har;
- float xn, yn, zn, nor[3], view[3];
- float vec[3], hasize, mat[4][4], imat[3][3];
- int a, ok, seed= ma->seed1;
-
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat3CpyMat4(imat, ob->imat);
-
- re->flag |= R_HALO;
-
- for(a=0; a<totvert; a++, mvert++) {
- ok= 1;
-
- if(ok) {
- hasize= ma->hasize;
-
- VECCOPY(vec, mvert->co);
- MTC_Mat4MulVecfl(mat, vec);
-
- if(ma->mode & MA_HALOPUNO) {
- xn= mvert->no[0];
- yn= mvert->no[1];
- zn= mvert->no[2];
-
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalize(nor);
-
- VECCOPY(view, vec);
- Normalize(view);
-
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
- }
-
- if(orco) har= RE_inithalo(re, ma, vec, NULL, orco, hasize, 0.0, seed);
- else har= RE_inithalo(re, ma, vec, NULL, mvert->co, hasize, 0.0, seed);
- if(har) har->lay= ob->lay;
- }
- if(orco) orco+= 3;
- seed++;
- }
-}
-
-/* ------------------------------------------------------------------------- */
static Material *give_render_material(Render *re, Object *ob, int nr)
{
extern Material defmaterial; /* material.c */
@@ -1066,176 +1079,32 @@ static Material *give_render_material(Render *re, Object *ob, int nr)
return ma;
}
-
-
-static void render_particle_system(Render *re, Object *ob, Object *par, PartEff *paf)
-{
- Particle *pa=0;
- HaloRen *har=0;
- Material *ma=0;
- float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
- float haloScale = 1.0; //NT scale halos
- float iniAlpha = 0.0; // restore material alpha
- int a, mat_nr=1, seed;
- int useFluidsimParticles = 0; // FSPARTICLE
-
- ma= give_render_material(re, ob, paf->omat);
-
- if( (ob->fluidsimSettings) && (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)) {
- useFluidsimParticles = 1;
- iniAlpha = ma->alpha;
- }
-
- pa= paf->keys;
- if(pa==NULL || paf->disp!=100 || useFluidsimParticles) {
- build_particle_system(ob);
- pa= paf->keys;
- if(pa==NULL) return;
- }
-
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */
-
- /* enable duplicators to work */
- if(par) {
- Mat4MulMat4(tmat, paf->imat, ob->obmat);
- MTC_Mat4MulMat4(mat, tmat, re->viewmat);
-
- MTC_Mat4Invert(tmat, mat);
- MTC_Mat3CpyMat4(imat, tmat);
- }
- else {
- MTC_Mat4CpyMat4(mat, re->viewmat);
-
- MTC_Mat4Invert(tmat, re->viewmat);
- MTC_Mat3CpyMat4(imat, tmat);
-
- }
-
- re->flag |= R_HALO;
-
- if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
- else ptime= 0.0;
- ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
- seed= ma->seed1;
-
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
-
- /* offset time for calculating normal */
- stime= ctime;
- ptime= ctime+1.0f;
- if(ctime < pa->time) {
- if(paf->flag & PAF_UNBORN)
- ptime= pa->time+1.0f;
- else
- continue;
- }
- if(ctime > pa->time+pa->lifetime) {
- if(paf->flag & PAF_DIED)
- stime= pa->time+pa->lifetime-1.0f;
- else
- continue;
- }
-
- /* watch it: also calculate the normal of a particle */
- if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
- where_is_particle(paf, pa, stime, vec);
- MTC_Mat4MulVecfl(mat, vec);
- where_is_particle(paf, pa, ptime, vec1);
- MTC_Mat4MulVecfl(mat, vec1);
- }
- else {
- where_is_particle(paf, pa, ctime, vec);
- MTC_Mat4MulVecfl(mat, vec);
- }
-
- if(pa->mat_nr != mat_nr) {
- mat_nr= pa->mat_nr;
- ma= give_render_material(re, ob, mat_nr);
- }
-
- if(ma->ipo) {
- /* correction for lifetime */
- ptime= 100.0*(ctime-pa->time)/pa->lifetime;
- calc_ipo(ma->ipo, ptime);
- execute_ipo((ID *)ma, ma->ipo);
- }
-
- //NT scale halos FSPARTICLE
- if(useFluidsimParticles) {
- // rescale to 1.0-10.0, then div by 5 afterwards, gives values in range 0.2-2.0
- double fspsize = ((double)pa->rt / 1000.0f) / 5.0 ;
- haloScale = 1.0/(float)pow(fspsize, (double)ob->fluidsimSettings->particleInfSize);
- ma->alpha = iniAlpha / (float)pow( fspsize, (double)ob->fluidsimSettings->particleInfAlpha);
- if(ma->alpha>1.) ma->alpha = 1.;
- }
-
- hasize= ma->hasize * haloScale;
-
- if(ma->mode & MA_HALOPUNO) {
- xn= pa->no[0];
- yn= pa->no[1];
- zn= pa->no[2];
-
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalize(nor);
-
- VECCOPY(view, vec);
- Normalize(view);
-
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
- }
-
- if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
- else {
- har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
- if(har && ma->mode & MA_HALO_SHADE) {
- VecSubf(har->no, vec, vec1);
- Normalize(har->no);
- }
- }
- if(har) har->lay= ob->lay;
- }
-
- /* restore material */
- for(a=1; a<=ob->totcol; a++) {
- ma= give_render_material(re, ob, a);
- if(ma) do_mat_ipo(ma);
- }
-
- if(paf->disp!=100) {
- MEM_freeN(paf->keys);
- paf->keys= NULL;
- }
-
- if(useFluidsimParticles) { ma->alpha = iniAlpha; }// FSPARTICLE restore...
-}
-
-
+/* ------------------------------------------------------------------------- */
+/* Particles */
/* ------------------------------------------------------------------------- */
/* future thread problem... */
-static void static_particle_strand(Render *re, Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first)
+static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, float *orco, float *surfnor,
+ float *uvco, int totuv, MCol *mcol, int totcol, float *vec, float *vec1, float ctime,
+ int first, int line, int adapt, float adapt_angle, float adapt_pix, int override_uv)
{
static VertRen *v1= NULL, *v2= NULL;
VlakRen *vlr;
- float nor[3], cross[3], w, dx, dy, width;
- int flag;
+ float nor[3], cross[3], crosslen, w, dx, dy, width;
+ static float anor[3], avec[3];
+ int flag, i;
+ static int second=0;
VecSubf(nor, vec, vec1);
Normalize(nor); // nor needed as tangent
Crossf(cross, vec, nor);
-
+
/* turn cross in pixelsize */
w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
- dx= re->winx*cross[0]*re->winmat[0][0]/w;
- dy= re->winy*cross[1]*re->winmat[1][1]/w;
- w= sqrt(dx*dx + dy*dy);
+ dx= re->winx*cross[0]*re->winmat[0][0];
+ dy= re->winy*cross[1]*re->winmat[1][1];
+ w= sqrt(dx*dx + dy*dy)/w;
+
if(w!=0.0f) {
float fac;
if(ma->strand_ease!=0.0f) {
@@ -1245,8 +1114,23 @@ static void static_particle_strand(Render *re, Object *ob, Material *ma, float *
fac= pow(ctime, 1.0/(1.0f-ma->strand_ease));
}
else fac= ctime;
-
- width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w;
+
+ width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end);
+
+ /* use actual Blender units for strand width and fall back to minimum width */
+ if(ma->mode & MA_STR_B_UNITS){
+ crosslen= VecLength(cross);
+ w= 2.0f*crosslen*ma->strand_min/w;
+
+ if(width < w)
+ width= w;
+
+ /*cross is the radius of the strand so we want it to be half of full width */
+ VecMulf(cross,0.5/crosslen);
+ }
+ else
+ width/=w;
+
VecMulf(cross, width);
}
else width= 1.0f;
@@ -1260,10 +1144,88 @@ static void static_particle_strand(Render *re, Object *ob, Material *ma, float *
if(ma->strand_sta==1.0f)
flag |= R_STRAND;
- /* first two vertices */
- if(first) {
- v1= RE_findOrAddVert(re, re->totvert++);
- v2= RE_findOrAddVert(re, re->totvert++);
+ /* single face line */
+ if(line) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ VECCOPY(vlr->v1->co, vec);
+ VecAddf(vlr->v1->co, vlr->v1->co, cross);
+ VECCOPY(vlr->v1->n, nor);
+ vlr->v1->orco= orco;
+ vlr->v1->accum= -1.0f; // accum abuse for strand texco
+
+ VECCOPY(vlr->v2->co, vec);
+ VecSubf(vlr->v2->co, vlr->v2->co, cross);
+ VECCOPY(vlr->v2->n, nor);
+ vlr->v2->orco= orco;
+ vlr->v2->accum= vlr->v1->accum;
+
+ VECCOPY(vlr->v4->co, vec1);
+ VecAddf(vlr->v4->co, vlr->v4->co, cross);
+ VECCOPY(vlr->v4->n, nor);
+ vlr->v4->orco= orco;
+ vlr->v4->accum= 1.0f; // accum abuse for strand texco
+
+ VECCOPY(vlr->v3->co, vec1);
+ VecSubf(vlr->v3->co, vlr->v3->co, cross);
+ VECCOPY(vlr->v3->n, nor);
+ vlr->v3->orco= orco;
+ vlr->v3->accum= vlr->v4->accum;
+
+ CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
+
+ if(surfnor) {
+ float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
+ VECCOPY(snor, surfnor);
+ }
+
+ if(uvco){
+ for(i=0; i<totuv; i++){
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1);
+ mtf->uv[0][0]=mtf->uv[1][0]=
+ mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0];
+ mtf->uv[0][1]=mtf->uv[1][1]=
+ mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1];
+ }
+ if(override_uv>=0){
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0);
+
+ mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
+ mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
+
+ mtf->uv[0][1]=mtf->uv[1][1]=0.0f;
+ mtf->uv[2][1]=mtf->uv[3][1]=1.0f;
+ }
+ }
+ if(mcol){
+ for(i=0; i<totcol; i++){
+ MCol *mc;
+ mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1);
+ mc[0]=mc[1]=mc[2]=mc[3]=mcol[i];
+ mc[0]=mc[1]=mc[2]=mc[3]=mcol[i];
+ }
+ }
+ }
+ /* first two vertices of a strand */
+ else if(first) {
+ if(adapt){
+ VECCOPY(anor, nor);
+ VECCOPY(avec, vec);
+ second=1;
+ }
+
+ v1= RE_findOrAddVert(obr, obr->totvert++);
+ v2= RE_findOrAddVert(obr, obr->totvert++);
VECCOPY(v1->co, vec);
VecAddf(v1->co, v1->co, cross);
@@ -1277,19 +1239,56 @@ static void static_particle_strand(Render *re, Object *ob, Material *ma, float *
v2->orco= orco;
v2->accum= v1->accum;
}
+ /* more vertices & faces to strand */
else {
-
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->flag= flag;
- vlr->ob= ob;
- vlr->v1= v1;
- vlr->v2= v2;
- vlr->v3= RE_findOrAddVert(re, re->totvert++);
- vlr->v4= RE_findOrAddVert(re, re->totvert++);
-
- v1= vlr->v4; // cycle
- v2= vlr->v3; // cycle
-
+ if(adapt==0 || second){
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= v1;
+ vlr->v2= v2;
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ v1= vlr->v4; // cycle
+ v2= vlr->v3; // cycle
+
+
+ if(adapt){
+ second=0;
+ VECCOPY(anor,nor);
+ VECCOPY(avec,vec);
+ }
+
+ }
+ else if(adapt){
+ float dvec[3],pvec[3];
+ VecSubf(dvec,avec,vec);
+ Projf(pvec,dvec,vec);
+ VecSubf(dvec,dvec,pvec);
+
+ w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
+ dx= re->winx*dvec[0]*re->winmat[0][0]/w;
+ dy= re->winy*dvec[1]*re->winmat[1][1]/w;
+ w= sqrt(dx*dx + dy*dy);
+ if(Inpf(anor,nor)<adapt_angle && w>adapt_pix){
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->flag= flag;
+ vlr->v1= v1;
+ vlr->v2= v2;
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ v1= vlr->v4; // cycle
+ v2= vlr->v3; // cycle
+
+ VECCOPY(anor,nor);
+ VECCOPY(avec,vec);
+ }
+ else{
+ vlr= RE_findOrAddVlak(obr, obr->totvlak-1);
+ }
+ }
+
VECCOPY(vlr->v4->co, vec);
VecAddf(vlr->v4->co, vlr->v4->co, cross);
VECCOPY(vlr->v4->n, nor);
@@ -1306,250 +1305,1153 @@ static void static_particle_strand(Render *re, Object *ob, Material *ma, float *
vlr->mat= ma;
vlr->ec= ME_V2V3;
- vlr->lay= ob->lay;
+
+ if(surfnor) {
+ float *snor= RE_vlakren_get_surfnor(obr, vlr, 1);
+ VECCOPY(snor, surfnor);
+ }
+
+ if(uvco){
+ for(i=0; i<totuv; i++){
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1);
+ mtf->uv[0][0]=mtf->uv[1][0]=
+ mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0];
+ mtf->uv[0][1]=mtf->uv[1][1]=
+ mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1];
+ }
+ if(override_uv>=0){
+ MTFace *mtf;
+ mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0);
+
+ mtf->uv[0][0]=mtf->uv[3][0]=0.0f;
+ mtf->uv[1][0]=mtf->uv[2][0]=1.0f;
+
+ mtf->uv[0][1]=mtf->uv[1][1]=(vlr->v1->accum+1.0f)/2.0f;
+ mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f;
+ }
+ }
+ if(mcol){
+ for(i=0; i<totcol; i++){
+ MCol *mc;
+ mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1);
+ mc[0]=mc[1]=mc[2]=mc[3]=mcol[i];
+ mc[0]=mc[1]=mc[2]=mc[3]=mcol[i];
+ }
+ }
}
}
-static void render_static_particle_system(Render *re, Object *ob, PartEff *paf)
+static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float *vec1, int first, int line)
{
- Particle *pa=0;
- HaloRen *har=0;
- Material *ma=0;
- VertRen *v1= NULL;
VlakRen *vlr;
- float xn, yn, zn, imat[3][3], mat[4][4], hasize;
- float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
- float *orco= NULL, loc_tex[3], size_tex[3];
- int a, mat_nr=1, seed, totvlako, totverto, first;
+ static VertRen *v1;
+
+ if(line) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ VECCOPY(vlr->v1->co, vec);
+ VECCOPY(vlr->v2->co, vec1);
+
+ VecSubf(vlr->n, vec, vec1);
+ Normalize(vlr->n);
+ VECCOPY(vlr->v1->n, vlr->n);
+ VECCOPY(vlr->v2->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V1V2;
- pa= paf->keys;
- if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) {
- build_particle_system(ob);
- pa= paf->keys;
- if(pa==NULL) return;
}
+ else if(first) {
+ v1= RE_findOrAddVert(obr, obr->totvert++);
+ VECCOPY(v1->co, vec);
+ }
+ else {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= v1;
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= vlr->v2;
+ vlr->v4= NULL;
+
+ v1= vlr->v2; // cycle
+ VECCOPY(v1->co, vec);
+
+ VecSubf(vlr->n, vec, vec1);
+ Normalize(vlr->n);
+ VECCOPY(v1->n, vlr->n);
+
+ vlr->mat= ma;
+ vlr->ec= ME_V1V2;
+ }
+
+}
+static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object *bb_ob, float *vec, float *vel, float size, float tilt, short align,
+ int lock, int p, int totpart, short uv_split, short anim, short split_offset, float random, float pa_time, float offset[2], int uv[3])
+{
+ VlakRen *vlr;
+ MTFace *mtf;
+ float xvec[3]={1.0f,0.0f,0.0f}, yvec[3]={0.0f,1.0f,0.0f}, zvec[3];
+ float onevec[3]={0.0f,0.0f,0.0f}, tvec[3],tvec2[3], bb_center[3];
+ float uvx=0.0f, uvy=0.0f, uvdx=1.0f, uvdy=1.0f, time=0.0f;
+
+ if(align<PART_BB_VIEW)
+ onevec[align]=1.0f;
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
+ vlr->v4= RE_findOrAddVert(obr, obr->totvert++);
+
+ if(lock && align==PART_BB_VIEW){
+ VECCOPY(xvec,bb_ob->obmat[0]);
+ Normalize(xvec);
+ VECCOPY(yvec,bb_ob->obmat[1]);
+ Normalize(yvec);
+ VECCOPY(zvec,bb_ob->obmat[2]);
+ Normalize(zvec);
+ }
+ else if(align==PART_BB_VEL){
+ float temp[3];
+ VECCOPY(temp,vel);
+ Normalize(temp);
+ VECSUB(zvec,bb_ob->obmat[3],vec);
+ if(lock){
+ float fac=-Inpf(zvec,temp);
+ VECADDFAC(zvec,zvec,temp,fac);
+ }
+ Normalize(zvec);
+ Crossf(xvec,temp,zvec);
+ Normalize(xvec);
+ Crossf(yvec,zvec,xvec);
+ }
+ else{
+ VECSUB(zvec,bb_ob->obmat[3],vec);
+ if(lock)
+ zvec[align]=0.0f;
+ Normalize(zvec);
+
+ if(align<PART_BB_VIEW)
+ Crossf(xvec,onevec,zvec);
+ else
+ Crossf(xvec,bb_ob->obmat[1],zvec);
+ Normalize(xvec);
+ Crossf(yvec,zvec,xvec);
+ }
+
+ VECCOPY(tvec,xvec);
+ VECCOPY(tvec2,yvec);
+
+ VecMulf(xvec,cos(tilt*(float)M_PI));
+ VecMulf(tvec2,sin(tilt*(float)M_PI));
+ VECADD(xvec,xvec,tvec2);
+
+ VecMulf(yvec,cos(tilt*(float)M_PI));
+ VecMulf(tvec,-sin(tilt*(float)M_PI));
+ VECADD(yvec,yvec,tvec);
+
+ VecMulf(xvec,size);
+ VecMulf(yvec,size);
- totvlako= re->totvlak;
- totverto= re->totvert;
+ VECADDFAC(bb_center,vec,xvec,offset[0]);
+ VECADDFAC(bb_center,bb_center,yvec,offset[1]);
+
+ VECADD(vlr->v1->co,bb_center,xvec);
+ VECADD(vlr->v1->co,vlr->v1->co,yvec);
+ MTC_Mat4MulVecfl(re->viewmat,vlr->v1->co);
+
+ VECSUB(vlr->v2->co,bb_center,xvec);
+ VECADD(vlr->v2->co,vlr->v2->co,yvec);
+ MTC_Mat4MulVecfl(re->viewmat,vlr->v2->co);
+
+ VECSUB(vlr->v3->co,bb_center,xvec);
+ VECSUB(vlr->v3->co,vlr->v3->co,yvec);
+ MTC_Mat4MulVecfl(re->viewmat,vlr->v3->co);
+
+ VECADD(vlr->v4->co,bb_center,xvec);
+ VECSUB(vlr->v4->co,vlr->v4->co,yvec);
+ MTC_Mat4MulVecfl(re->viewmat,vlr->v4->co);
+
+ CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ VECCOPY(vlr->v1->n,vlr->n);
+ VECCOPY(vlr->v2->n,vlr->n);
+ VECCOPY(vlr->v3->n,vlr->n);
+ VECCOPY(vlr->v4->n,vlr->n);
- ma= give_render_material(re, ob, paf->omat);
- if(ma->mode & MA_HALO)
- re->flag |= R_HALO;
+ vlr->mat= ma;
+ vlr->ec= ME_V2V3;
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */
+ if(uv_split>1){
+ uvdx=uvdy=1.0f/(float)uv_split;
+ if(anim==PART_BB_ANIM_TIME){
+ if(split_offset==PART_BB_OFF_NONE)
+ time=pa_time;
+ else if(split_offset==PART_BB_OFF_LINEAR)
+ time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f);
+ else /* split_offset==PART_BB_OFF_RANDOM */
+ time=(float)fmod(pa_time+random,1.0f);
- MTC_Mat3CpyMat4(imat, ob->imat);
+ }
+ else if(anim==PART_BB_ANIM_ANGLE){
+ if(align==PART_BB_VIEW){
+ time=(float)fmod((tilt+1.0f)/2.0f,1.0);
+ }
+ else{
+ float axis1[3]={0.0f,0.0f,0.0f};
+ float axis2[3]={0.0f,0.0f,0.0f};
+ axis1[(align+1)%3]=1.0f;
+ axis2[(align+2)%3]=1.0f;
+ if(lock==0){
+ zvec[align]=0.0f;
+ Normalize(zvec);
+ }
+ time=saacos(Inpf(zvec,axis1))/(float)M_PI;
+ if(Inpf(zvec,axis2)<0.0f)
+ time=1.0f-time/2.0f;
+ else
+ time=time/2.0f;
+ }
+ if(split_offset==PART_BB_OFF_LINEAR)
+ time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f);
+ else if(split_offset==PART_BB_OFF_RANDOM)
+ time=(float)fmod(pa_time+random,1.0f);
+ }
+ else{
+ if(split_offset==PART_BB_OFF_NONE)
+ time=0.0f;
+ else if(split_offset==PART_BB_OFF_LINEAR)
+ time=(float)fmod((float)p/(float)(uv_split*uv_split),1.0f);
+ else /* split_offset==PART_BB_OFF_RANDOM */
+ time=random;
+ }
+ uvx=uvdx*floor((float)(uv_split*uv_split)*(float)fmod((double)time,(double)uvdx));
+ uvy=uvdy*floor((1.0f-time)*(float)uv_split);
+ if(fmod(time,1.0f/uv_split)==0.0f)
+ uvy-=uvdy;
+ }
+
+ /* normal UVs */
+ if(uv[0]>=0){
+ mtf=RE_vlakren_get_tface(obr,vlr,uv[0],NULL,1);
+ mtf->uv[0][0]=1.0f;
+ mtf->uv[0][1]=1.0f;
+ mtf->uv[1][0]=0.0f;
+ mtf->uv[1][1]=1.0f;
+ mtf->uv[2][0]=0.0f;
+ mtf->uv[2][1]=0.0f;
+ mtf->uv[3][0]=1.0f;
+ mtf->uv[3][1]=0.0f;
+ }
+
+ /* time-index UVs */
+ if(uv[1]>=0){
+ mtf=RE_vlakren_get_tface(obr,vlr,uv[1],NULL,1);
+ mtf->uv[0][0]=mtf->uv[1][0]=mtf->uv[2][0]=mtf->uv[3][0]=pa_time;
+ mtf->uv[0][1]=mtf->uv[1][1]=mtf->uv[2][1]=mtf->uv[3][1]=(float)p/(float)totpart;
+ }
+
+ /* split UVs */
+ if(uv_split>1 && uv[2]>=0){
+ mtf=RE_vlakren_get_tface(obr,vlr,uv[2],NULL,1);
+ mtf->uv[0][0]=uvx+uvdx;
+ mtf->uv[0][1]=uvy+uvdy;
+ mtf->uv[1][0]=uvx;
+ mtf->uv[1][1]=uvy+uvdy;
+ mtf->uv[2][0]=uvx;
+ mtf->uv[2][1]=uvy;
+ mtf->uv[3][0]=uvx+uvdx;
+ mtf->uv[3][1]=uvy;
+ }
+}
+static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, int path, int first, int line,
+ float time, float *loc, float *loc1, float *orco, float *surfnor, int totuv, float *uvco,
+ int totcol, MCol *mcol, float size, int seed, int override_uv,
+ int adapt, float adapt_angle, float adapt_pix)
+{
+ HaloRen *har=0;
+ if(path){
+ if(ma->mode&MA_WIRE)
+ static_particle_wire(obr, ma, loc, loc1, first, line);
+ else if(ma->mode & MA_HALO){
+ har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, orco, uvco, size, 1.0, seed);
+ if(har) har->lay= obr->ob->lay;
+ }
+ else
+ static_particle_strand(re, obr, ma, orco, surfnor, uvco, totuv, mcol, totcol, loc, loc1, time, first, line, adapt, adapt_angle, adapt_pix, override_uv);
+ }
+ else{
+ har= RE_inithalo_particle(re, obr, dm, ma, loc, NULL, orco, uvco, size, 0.0, seed);
+ if(har) har->lay= obr->ob->lay;
+ }
+}
+static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
+{
+ Object *ob= obr->ob;
+ Object *tob=0, *bb_ob=re->scene->camera;
+ Material *ma=0;
+ MTFace *mtface;
+ ParticleSystemModifierData *psmd;
+ ParticleSystem *tpsys=0;
+ ParticleSettings *part, *tpart=0;
+ ParticleData *pars, *pa=0,*tpa=0;
+ ParticleKey *states=0;
+ ParticleKey state;
+ ParticleCacheKey *cache=0;
+ StrandBuffer *strandbuf=0;
+ StrandVert *svert=0;
+ StrandBound *sbound= 0;
+ StrandRen *strand=0;
+ RNG *rng= 0;
+ MCol *mcol= 0;
+ float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
+ float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
+ float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
+ float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
+ int i, a, k, max_k=0, totpart, totuv=0, totcol=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
+ int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
+ int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
+ int totface, *origindex = 0;
+ char **uv_name=0;
+
+/* 1. check that everything is ok & updated */
+ if(psys==NULL)
+ return 0;
+
+ part=psys->part;
+ pars=psys->particles;
+
+ if(part==NULL || pars==NULL || !psys_check_enabled(ob, psys))
+ return 0;
- /* orcos */
- if(!(ma->mode & (MA_HALO|MA_WIRE))) {
- orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos");
- if (!re->orco_hash)
- re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- BLI_ghash_insert(re->orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */
+ if(part->draw_as==PART_DRAW_OB || part->draw_as==PART_DRAW_GR || part->draw_as==PART_DRAW_NOT)
+ return 1;
+
+/* 2. start initialising things */
+ if(part->phystype==PART_PHYS_KEYED){
+ if(psys->flag & PSYS_FIRST_KEYED)
+ psys_count_keyed_targets(ob,psys);
+ else
+ return 1;
+ }
+
+ psmd= psys_get_modifier(ob,psys);
+ if(!(psmd->modifier.mode & eModifierMode_Render))
+ return 0;
+
+ if(G.rendering == 0) { /* preview render */
+ totchild = (int)((float)totchild * (float)part->disp / 100.0f);
}
+
+ psys->flag|=PSYS_DRAWING;
+
+ rng= rng_new(psys->seed);
- mesh_get_texspace(ob->data, loc_tex, NULL, size_tex);
+ ma= give_render_material(re, ob, part->omat);
+
+ if(part->bb_ob)
+ bb_ob=part->bb_ob;
- if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
- else ptime= 0.0;
- ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
- seed= ma->seed1;
+ if(ma->ipo){
+ calc_ipo(ma->ipo, cfra);
+ execute_ipo((ID *)ma, ma->ipo);
+ }
- for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
-
- where_is_particle(paf, pa, pa->time, vec1);
- if(orco) {
- orco[0] = (vec1[0]-loc_tex[0])/size_tex[0];
- orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
- orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
+ RE_set_customdata_names(obr, &psmd->dm->faceData);
+ totuv=CustomData_number_of_layers(&psmd->dm->faceData,CD_MTFACE);
+ totcol=CustomData_number_of_layers(&psmd->dm->faceData,CD_MCOL);
+
+ if(ma->texco & TEXCO_UV && totuv) {
+ uvco = MEM_callocN(totuv*2*sizeof(float),"particle_uvs");
+
+ if(ma->strand_uvname[0]) {
+ override_uv= CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,ma->strand_uvname);
+ override_uv-= CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE);
}
- MTC_Mat4MulVecfl(mat, vec1);
- mtime= pa->time+pa->lifetime+paf->staticstep-1;
-
- first= 1;
- for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
-
- /* make sure hair grows until the end.. */
- if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
-
- /* watch it: also calc the normal of a particle */
- if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
- where_is_particle(paf, pa, ctime+1.0, vec);
- MTC_Mat4MulVecfl(mat, vec);
+ }
+
+ if(totcol)
+ mcol = MEM_callocN(totcol*sizeof(MCol),"particle_mcols");
+
+ if(part->draw_as==PART_DRAW_BB){
+ int first_uv=CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE);
+
+ uv[0]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[0]);
+ if(uv[0]<0)
+ uv[0]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE);
+
+ uv[1]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[1]);
+ //if(uv[1]<0)
+ // uv[1]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE);
+
+ uv[2]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[2]);
+ //if(uv[2]<0)
+ // uv[2]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE);
+
+ if(first_uv>=0){
+ uv[0]-=first_uv;
+ uv[1]-=first_uv;
+ uv[2]-=first_uv;
+ }
+ }
+
+ if(part->flag&PART_ABS_TIME && part->ipo){
+ calc_ipo(part->ipo, cfra);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ if(part->flag&PART_GLOB_TIME)
+ cfra=bsystem_time(0,(float)CFRA,0.0);
+
+ 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;
+ }
+ }
+
+ hasize = ma->hasize;
+ seed = ma->seed1;
+
+ re->flag |= R_HALO;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */
+ Mat3CpyMat4(nmat, ob->imat);
+ Mat3Transp(nmat);
+
+ totpart=psys->totpart;
+
+ if(psys->pathcache){
+ path_possible=1;
+ keys_possible=1;
+ }
+ if(part->draw_as==PART_DRAW_PATH){
+ if(path_possible){
+ path_nbr=(int)pow(2.0,(double) part->ren_step);
+ //if(part->phystype==PART_PHYS_KEYED && (psys->flag&PSYS_BAKED)==0)
+ // path_nbr*=psys->totkeyed;
+
+ if(path_nbr) {
+ if((ma->mode & (MA_HALO|MA_WIRE))==0) {
+ orco= MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos");
+ set_object_orco(re, psys, orco);
+ }
+ path=1;
}
- else {
- where_is_particle(paf, pa, ctime, vec);
- MTC_Mat4MulVecfl(mat, vec);
+
+ if(part->draw&PART_DRAW_REN_ADAPT) {
+ adapt=1;
+ adapt_pix=(float)part->adapt_pix;
+ adapt_angle=cos((float)part->adapt_angle*(float)(M_PI/180.0));
}
- if(pa->mat_nr != mat_nr) {
- mat_nr= pa->mat_nr;
- ma= give_render_material(re, ob, mat_nr);
+ if(re->r.renderer==R_INTERN && part->draw&PART_DRAW_REN_STRAND) {
+ strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1));
+ strandbuf->ma= ma;
+ strandbuf->lay= ob->lay;
+ Mat4CpyMat4(strandbuf->winmat, re->winmat);
+ strandbuf->winx= re->winx;
+ strandbuf->winy= re->winy;
+ strandbuf->maxdepth= 2;
+ strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0));
+ strandbuf->overrideuv= override_uv;
+ strandbuf->minwidth= ma->strand_min;
+
+ if(ma->strand_widthfade == 0.0f)
+ strandbuf->widthfade= 0.0f;
+ else if(ma->strand_widthfade >= 1.0f)
+ strandbuf->widthfade= 2.0f - ma->strand_widthfade;
+ else
+ strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f);
+
+ if(part->flag & PART_HAIR_BSPLINE)
+ strandbuf->flag |= R_STRAND_BSPLINE;
+ if(ma->mode & MA_STR_B_UNITS)
+ strandbuf->flag |= R_STRAND_B_UNITS;
+
+ svert= strandbuf->vert;
+
+ if(re->r.mode & R_SPEED)
+ dosurfacecache= 1;
+ else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ if(ma->amb != 0.0f)
+ dosurfacecache= 1;
+
+ totface= psmd->dm->getNumFaces(psmd->dm);
+ origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX);
+ if(origindex) {
+ for(a=0; a<totface; a++)
+ strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]);
+ strandbuf->totbound++;
+ }
+ strandbuf->totbound++;
+ strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound");
+ sbound= strandbuf->bound;
+ sbound->start= sbound->end= 0;
}
-
- /* wires */
- if(ma->mode & MA_WIRE) {
- if(ctime == pa->time) {
- v1= RE_findOrAddVert(re, re->totvert++);
- VECCOPY(v1->co, vec);
+ }
+ }
+ else if(keys_possible && part->draw&PART_DRAW_KEYS){
+ path_nbr=part->keys_step;
+ if(path_nbr==0)
+ baked_keys=1;
+ }
+
+ if(orco==0){
+ orco=MEM_mallocN(3*sizeof(float),"particle orco");
+ orco1=1;
+ }
+
+ if(path_nbr==0)
+ psys->lattice=psys_get_lattice(ob,psys);
+
+/* 3. start creating renderable things */
+ for(a=0,pa=pars; a<totpart+totchild; a++, pa++) {
+ random = rng_getFloat(rng);
+
+ if(a<totpart){
+ if(pa->flag & PARS_UNEXIST) continue;
+
+ pa_time=(cfra-pa->time)/pa->lifetime;
+ if((part->flag&PART_ABS_TIME)==0){
+ if(ma->ipo){
+ /* correction for lifetime */
+ calc_ipo(ma->ipo, 100.0f*pa_time);
+ execute_ipo((ID *)ma, ma->ipo);
}
- else {
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= v1;
- vlr->v2= RE_findOrAddVert(re, re->totvert++);
- vlr->v3= vlr->v2;
- vlr->v4= NULL;
-
- v1= vlr->v2; // cycle
- VECCOPY(v1->co, vec);
-
- VecSubf(vlr->n, vec, vec1);
- Normalize(vlr->n);
- VECCOPY(v1->n, vlr->n);
-
- vlr->mat= ma;
- vlr->ec= ME_V1V2;
- vlr->lay= ob->lay;
+ if(part->ipo){
+ /* correction for lifetime */
+ calc_ipo(part->ipo, 100.0f*pa_time);
+ execute_ipo((ID *)part, part->ipo);
}
}
- else {
- if(ma->ipo) {
+
+ hasize = ma->hasize;
+
+ /* get orco */
+ if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
+ tpa=tpsys->particles+pa->num;
+ psys_particle_on_emitter(ob, psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0);
+ }
+ else
+ psys_particle_on_emitter(ob, psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0);
+
+ num= pa->num_dmcache;
+
+ if(num == DMCACHE_NOTFOUND)
+ if(pa->num < psmd->dm->getNumFaces(psmd->dm))
+ num= pa->num;
+
+ if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
+ for(i=0; i<totuv; i++){
+ if(num != DMCACHE_NOTFOUND) {
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE);
+ mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
+ mtface+=num;
+
+ psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i);
+ }
+ else {
+ uvco[2*i]= 0.0f;
+ uvco[2*i + 1]= 0.0f;
+ }
+ }
+ }
+ if(mcol && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
+ for(i=0; i<totcol; i++){
+ if(num != DMCACHE_NOTFOUND) {
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE);
+ MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i);
+ mc+=num*4;
+
+ psys_interpolate_mcol(mc,mface->v4,pa->fuv,mcol+i);
+ }
+ else
+ memset(&mcol[i], 0, sizeof(MCol));
+ }
+ }
+
+ pa_size=pa->size;
+
+ r_tilt=1.0f+pa->r_ave[0];
+
+ if(path_nbr){
+ cache = psys->pathcache[a];
+ max_k = (int)cache->steps;
+ }
+
+ if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
+ }
+ else {
+ ChildParticle *cpa= psys->child+a-totpart;
+
+ pa_time=psys_get_child_time(psys, cpa, cfra);
+
+ if((part->flag&PART_ABS_TIME)==0){
+ if(ma->ipo){
/* correction for lifetime */
- ptime= 100.0*(ctime-pa->time)/pa->lifetime;
- calc_ipo(ma->ipo, ptime);
+ calc_ipo(ma->ipo, 100.0f*pa_time);
execute_ipo((ID *)ma, ma->ipo);
}
-
- if(ma->mode & MA_HALO) {
- hasize= ma->hasize;
+ if(part->ipo){
+ /* correction for lifetime */
+ calc_ipo(part->ipo, 100.0f*pa_time);
+ execute_ipo((ID *)part, part->ipo);
+ }
+ }
- if(ma->mode & MA_HALOPUNO) {
- xn= pa->no[0];
- yn= pa->no[1];
- zn= pa->no[2];
+ pa_size=psys_get_child_size(psys, cpa, cfra, &pa_time);
- /* transpose ! */
- nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
- nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
- nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
- Normalize(nor);
+ r_tilt=2.0f*cpa->rand[2];
+
+ num= cpa->num;
+
+ /* get orco */
+ psys_particle_on_emitter(ob, psmd,
+ (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+ cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,nor,0,0,orco,0);
- VECCOPY(view, vec);
- Normalize(view);
+ if(uvco){
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ for(i=0; i<totuv; i++){
+ if(part->childtype==PART_CHILD_FACES){
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE);
- zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
- if(zn>=0.0) hasize= 0.0;
- else hasize*= zn*zn*zn*zn;
+ mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
+ mtface+=cpa->num;
+
+ psys_interpolate_uvs(mtface,mface->v4,cpa->fuv,uvco+2*i);
+ }
+ else{
+ uvco[2*i]=uvco[2*i+1]=0.0f;
+ }
}
+ }
+ else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
+ for(i=0; i<totuv; i++){
+ ParticleData *parent = psys->particles+cpa->parent;
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,parent->num,CD_MFACE);
- if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed);
- else {
- har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed);
- if(har && (ma->mode & MA_HALO_SHADE)) {
- VecSubf(har->no, vec, vec1);
- Normalize(har->no);
- har->lay= ob->lay;
+ mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
+ mtface+=parent->num;
+
+ psys_interpolate_uvs(mtface,mface->v4,parent->fuv,uvco+2*i);
+ }
+ }
+ }
+
+ if(mcol){
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ for(i=0; i<totcol; i++){
+ if(part->childtype==PART_CHILD_FACES){
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE);
+ MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i);
+ mc+=cpa->num*4;
+
+ psys_interpolate_mcol(mc,mface->v4,cpa->fuv,mcol+i);
}
+ else
+ memset(&mcol[i], 0, sizeof(MCol));
}
- if(har) har->lay= ob->lay;
}
- else { /* generate pixel sized hair strand */
- float strandco= 1.0f;
-
- /* last strand, texco to end */
- if(ctime + paf->staticstep < mtime)
- strandco= (ctime-pa->time)/(mtime-pa->time);
-
- static_particle_strand(re, ob, ma, orco, vec, vec1, strandco, first);
+ else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
+ for(i=0; i<totcol; i++){
+ ParticleData *parent = psys->particles+cpa->parent;
+ MFace *mface=psmd->dm->getFaceData(psmd->dm,parent->num,CD_MFACE);
+ MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i);
+ mc+=parent->num*4;
+
+ psys_interpolate_mcol(mc,mface->v4,parent->fuv,mcol+i);
+ }
+ }
+ }
+
+ dosimplify= psys_render_simplify_params(psys, cpa, simplify);
+
+ if(path_nbr) {
+ cache = psys->childcache[a-totpart];
+ max_k = (int)cache->steps;
+ }
+
+ if(strandbuf) {
+ if(origindex[cpa->num]+1 > sbound - strandbuf->bound) {
+ sbound= strandbuf->bound + origindex[cpa->num]+1;
+ sbound->start= sbound->end= obr->totstrand;
}
}
-
- VECCOPY(vec1, vec);
- first= 0;
}
-
- seed++;
- if(orco) orco+=3;
+
+ /* surface normal shading setup */
+ if(ma->mode_l & MA_STR_SURFDIFF) {
+ Mat3MulVecfl(nmat, nor);
+ surfnor= nor;
+ }
+ else
+ surfnor= NULL;
+
+ /* strand render setup */
+ if(strandbuf) {
+ strand= RE_findOrAddStrand(obr, obr->totstrand++);
+ strand->buffer= strandbuf;
+ strand->vert= svert;
+ VECCOPY(strand->orco, orco);
+
+ if(dosimplify) {
+ float *ssimplify= RE_strandren_get_simplify(obr, strand, 1);
+ ssimplify[0]= simplify[0];
+ ssimplify[1]= simplify[1];
+ }
+
+ if(surfnor) {
+ float *snor= RE_strandren_get_surfnor(obr, strand, 1);
+ VECCOPY(snor, surfnor);
+ }
+
+ if(dosurfacecache && num >= 0) {
+ int *facenum= RE_strandren_get_face(obr, strand, 1);
+ *facenum= num;
+ }
+
+ if(uvco) {
+ for(i=0; i<totuv; i++) {
+ if(i != override_uv) {
+ float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1);
+
+ uv[0]= uvco[2*i];
+ uv[1]= uvco[2*i+1];
+ }
+ }
+ }
+ if(mcol) {
+ for(i=0; i<totcol; i++) {
+ MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1);
+ *mc = mcol[i];
+ }
+ }
+
+ sbound->end++;
+ }
+
+ /* strandco computation setup */
+ if(path_nbr) {
+ strandlen= 0.0f;
+ curlen= 0.0f;
+ for(k=1; k<=path_nbr; k++)
+ if(k<=max_k)
+ strandlen += VecLenf((cache+k-1)->co, (cache+k)->co);
+ }
+
+ for(k=0; k<=path_nbr; k++){
+ if(path_nbr){
+ if(k<=max_k){
+ //bti->convert_bake_key(bsys,cache+k,0,(void*)&state);
+ //copy_particle_key(&state,cache+k,0);
+ VECCOPY(state.co,(cache+k)->co);
+ VECCOPY(state.vel,(cache+k)->vel);
+ }
+ else
+ continue;
+
+ if(k > 0)
+ curlen += VecLenf((cache+k-1)->co, (cache+k)->co);
+ time= curlen/strandlen;
+ }
+ else{
+ time=0.0f;
+ state.time=cfra;
+ if(psys_get_particle_state(ob,psys,a,&state,0)==0)
+ continue;
+ }
+
+ VECCOPY(loc,state.co);
+ if(part->draw_as!=PART_DRAW_BB)
+ MTC_Mat4MulVecfl(re->viewmat,loc);
+
+ if(part->draw_as==PART_DRAW_LINE) {
+ VECCOPY(vel,state.vel);
+ //VECADD(vel,vel,state.co);
+ MTC_Mat4Mul3Vecfl(re->viewmat,vel);
+ //VECSUB(vel,vel,loc);
+ Normalize(vel);
+ if(part->draw & PART_DRAW_VEL_LENGTH)
+ VecMulf(vel,VecLength(state.vel));
+ VECADDFAC(loc0,loc,vel,-part->draw_line[0]);
+ VECADDFAC(loc1,loc,vel,part->draw_line[1]);
+
+ render_new_particle(re,obr,psmd->dm,ma,1,0,1,0.0f,loc0,loc1,
+ orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv,0,0,0);
+ }
+ else if(part->draw_as==PART_DRAW_BB) {
+ VECCOPY(vel,state.vel);
+ //MTC_Mat4Mul3Vecfl(re->viewmat,vel);
+ particle_billboard(re,obr,ma,bb_ob,loc,vel,pa_size,part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt),
+ part->bb_align,part->draw&PART_DRAW_BB_LOCK,
+ a,totpart+totchild,part->bb_uv_split,part->bb_anim,part->bb_split_offset,random,pa_time,part->bb_offset,uv);
+ }
+ else if(strandbuf) {
+ VECCOPY(svert->co, loc);
+ svert->strandco= -1.0f + 2.0f*time;
+ svert++;
+ strand->totvert++;
+ }
+ else{
+ if(k==1){
+ VECSUB(loc0,loc1,loc);
+ VECADD(loc0,loc1,loc0);
+ render_new_particle(re,obr,psmd->dm,ma,path,1,0,0.0f,loc1,loc0,
+ orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv,
+ adapt,adapt_angle,adapt_pix);
+ }
+
+ if(path_nbr==0 || k)
+ render_new_particle(re,obr,psmd->dm,ma,path,0,0,time,loc,loc1,
+ orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv,
+ adapt,adapt_angle,adapt_pix);
+
+ VECCOPY(loc1,loc);
+ }
+ }
+
+ if(orco1==0)
+ orco+=3;
+
+ if(re->test_break())
+ break;
}
- if(paf->disp!=100) {
- MEM_freeN(paf->keys);
- paf->keys= NULL;
+ if(dosurfacecache)
+ strandbuf->surface= cache_strand_surface(re, obr, psmd->dm, mat, timeoffset);
+
+/* 4. clean up */
+ if(ma) do_mat_ipo(ma);
+
+ if(orco1)
+ MEM_freeN(orco);
+
+ if(uvco)
+ MEM_freeN(uvco);
+
+ if(mcol)
+ MEM_freeN(mcol);
+
+ if(uv_name)
+ MEM_freeN(uv_name);
+
+ if(states)
+ MEM_freeN(states);
+
+ rng_free(rng);
+
+ psys->flag &= ~PSYS_DRAWING;
+
+ if(psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
}
- if((ma->mode & MA_TANGENT_STR)==0)
- calc_vertexnormals(re, totverto, totvlako, 0);
-}
+ if(path && (ma->mode_l & MA_TANGENT_STR)==0)
+ calc_vertexnormals(re, obr, 0, 0);
+ return 1;
+}
/* ------------------------------------------------------------------------- */
+/* Halo's */
+/* ------------------------------------------------------------------------- */
+
+static void make_render_halos(Render *re, ObjectRen *obr, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco)
+{
+ Object *ob= obr->ob;
+ HaloRen *har;
+ float xn, yn, zn, nor[3], view[3];
+ float vec[3], hasize, mat[4][4], imat[3][3];
+ int a, ok, seed= ma->seed1;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat3CpyMat4(imat, ob->imat);
+
+ re->flag |= R_HALO;
+
+ for(a=0; a<totvert; a++, mvert++) {
+ ok= 1;
+
+ if(ok) {
+ hasize= ma->hasize;
+
+ VECCOPY(vec, mvert->co);
+ MTC_Mat4MulVecfl(mat, vec);
+
+ if(ma->mode & MA_HALOPUNO) {
+ xn= mvert->no[0];
+ yn= mvert->no[1];
+ zn= mvert->no[2];
+
+ /* transpose ! */
+ nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ Normalize(nor);
+
+ VECCOPY(view, vec);
+ Normalize(view);
+
+ zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
+ if(zn>=0.0) hasize= 0.0;
+ else hasize*= zn*zn*zn*zn;
+ }
+
+ if(orco) har= RE_inithalo(re, obr, ma, vec, NULL, orco, hasize, 0.0, seed);
+ else har= RE_inithalo(re, obr, ma, vec, NULL, mvert->co, hasize, 0.0, seed);
+ if(har) har->lay= ob->lay;
+ }
+ if(orco) orco+= 3;
+ seed++;
+ }
+}
static int verghalo(const void *a1, const void *a2)
{
- const struct halosort *x1=a1, *x2=a2;
+ const HaloRen *har1= *(const HaloRen**)a1;
+ const HaloRen *har2= *(const HaloRen**)a2;
- if( x1->z < x2->z ) return 1;
- else if( x1->z > x2->z) return -1;
+ if(har1->zs < har2->zs) return 1;
+ else if(har1->zs > har2->zs) return -1;
return 0;
}
-/* ------------------------------------------------------------------------- */
-static void sort_halos(Render *re)
+static void sort_halos(Render *re, int totsort)
{
- struct halosort *hablock, *haso;
- HaloRen *har = NULL, **bloha;
+ ObjectRen *obr;
+ HaloRen *har= NULL, **haso;
int a;
if(re->tothalo==0) return;
- /* make datablock with halo pointers, sort */
- haso= hablock= MEM_mallocN(sizeof(struct halosort)*re->tothalo, "hablock");
+ re->sortedhalos= MEM_callocN(sizeof(HaloRen*)*re->tothalo, "sorthalos");
+ haso= re->sortedhalos;
- for(a=0; a<re->tothalo; a++) {
- if((a & 255)==0) har= re->bloha[a>>8];
- else har++;
- haso->har= har;
- haso->z= har->zs;
- haso++;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->tothalo; a++) {
+ if((a & 255)==0) har= obr->bloha[a>>8];
+ else har++;
+
+ *(haso++)= har;
+ }
}
- qsort(hablock, re->tothalo, sizeof(struct halosort), verghalo);
+ qsort(re->sortedhalos, totsort, sizeof(HaloRen*), verghalo);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Displacement Mapping */
+/* ------------------------------------------------------------------------- */
+
+static short test_for_displace(Render *re, Object *ob)
+{
+ /* return 1 when this object uses displacement textures. */
+ Material *ma;
+ int i;
+
+ for (i=1; i<=ob->totcol; i++) {
+ ma=give_render_material(re, ob, i);
+ /* ma->mapto is ORed total of all mapto channels */
+ if(ma && (ma->mapto & MAP_DISPLACE)) return 1;
+ }
+ return 0;
+}
+
+static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3])
+{
+ MTFace *tface;
+ short texco= shi->mat->texco;
+ float sample=0, displace[3];
+ char *name;
+ int i;
+
+ /* shi->co is current render coord, just make sure at least some vector is here */
+ VECCOPY(shi->co, vr->co);
+ /* vertex normal is used for textures type 'col' and 'var' */
+ VECCOPY(shi->vn, vr->n);
+
+ if(mat)
+ Mat4MulVecfl(mat, shi->co);
- /* re-assamble re->bloha */
+ if(imat) {
+ shi->vn[0]= imat[0][0]*vr->n[0]+imat[0][1]*vr->n[1]+imat[0][2]*vr->n[2];
+ shi->vn[1]= imat[1][0]*vr->n[0]+imat[1][1]*vr->n[1]+imat[1][2]*vr->n[2];
+ shi->vn[2]= imat[2][0]*vr->n[0]+imat[2][1]*vr->n[1]+imat[2][2]*vr->n[2];
+ }
- bloha= re->bloha;
- re->bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(re->blohalen),"Bloha");
+ if (texco & TEXCO_UV) {
+ shi->totuv= 0;
+ shi->actuv= obr->actmtface;
- haso= hablock;
- for(a=0; a<re->tothalo; a++) {
- har= RE_findOrAddHalo(re, a);
- *har= *(haso->har);
+ for (i=0; (tface=RE_vlakren_get_tface(obr, shi->vlr, i, &name, 0)); i++) {
+ ShadeInputUV *suv= &shi->uv[i];
- haso++;
+ /* shi.uv needs scale correction from tface uv */
+ suv->uv[0]= 2*tface->uv[vindex][0]-1.0f;
+ suv->uv[1]= 2*tface->uv[vindex][1]-1.0f;
+ suv->uv[2]= 0.0f;
+ suv->name= name;
+ shi->totuv++;
+ }
}
- /* free */
- a= 0;
- while(bloha[a]) {
- MEM_freeN(bloha[a]);
- a++;
+ /* set all rendercoords, 'texco' is an ORed value for all textures needed */
+ if ((texco & TEXCO_ORCO) && (vr->orco)) {
+ VECCOPY(shi->lo, vr->orco);
+ }
+ if (texco & TEXCO_STICKY) {
+ float *sticky= RE_vertren_get_sticky(obr, vr, 0);
+ if(sticky) {
+ shi->sticky[0]= sticky[0];
+ shi->sticky[1]= sticky[1];
+ shi->sticky[2]= 0.0f;
+ }
+ }
+ if (texco & TEXCO_GLOB) {
+ VECCOPY(shi->gl, shi->co);
+ MTC_Mat4MulVecfl(re->viewinv, shi->gl);
+ }
+ if (texco & TEXCO_NORM) {
+ VECCOPY(shi->orn, shi->vn);
+ }
+ if(texco & TEXCO_REFL) {
+ /* not (yet?) */
+ }
+
+ shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
+
+ do_material_tex(shi);
+
+ //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2],
+ //vr->co[0], vr->co[1], vr->co[2]);
+
+ displace[0]= shi->displace[0] * scale[0];
+ displace[1]= shi->displace[1] * scale[1];
+ displace[2]= shi->displace[2] * scale[2];
+
+ if(mat)
+ Mat3MulVecfl(imat, displace);
+
+ /* 0.5 could become button once? */
+ vr->co[0] += displace[0];
+ vr->co[1] += displace[1];
+ vr->co[2] += displace[2];
+
+ //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]);
+
+ /* we just don't do this vertex again, bad luck for other face using same vertex with
+ different material... */
+ vr->flag |= 1;
+
+ /* Pass sample back so displace_face can decide which way to split the quad */
+ sample = shi->displace[0]*shi->displace[0];
+ sample += shi->displace[1]*shi->displace[1];
+ sample += shi->displace[2]*shi->displace[2];
+
+ vr->accum=sample;
+ /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */
+ return;
+}
+
+static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3])
+{
+ ShadeInput shi;
+
+ /* Warning, This is not that nice, and possibly a bit slow,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ /* set up shadeinput struct for multitex() */
+
+ /* memset above means we dont need this */
+ /*shi.osatex= 0;*/ /* signal not to use dx[] and dy[] texture AA vectors */
+
+ shi.vlr= vlr; /* current render face */
+ shi.mat= vlr->mat; /* current input material */
+
+ /* Displace the verts, flag is set when done */
+ if (!vlr->v1->flag)
+ displace_render_vert(re, obr, &shi, vlr->v1,0, scale, mat, imat);
+
+ if (!vlr->v2->flag)
+ displace_render_vert(re, obr, &shi, vlr->v2, 1, scale, mat, imat);
+
+ if (!vlr->v3->flag)
+ displace_render_vert(re, obr, &shi, vlr->v3, 2, scale, mat, imat);
+
+ if (vlr->v4) {
+ if (!vlr->v4->flag)
+ displace_render_vert(re, obr, &shi, vlr->v4, 3, scale, mat, imat);
+
+ /* closest in displace value. This will help smooth edges. */
+ if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
+ vlr->flag |= R_DIVIDE_24;
+ else vlr->flag &= ~R_DIVIDE_24;
+ }
+
+ /* Recalculate the face normal - if flipped before, flip now */
+ if(vlr->v4) {
+ CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ }
+ else {
+ CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
+ }
+}
+
+static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3])
+{
+ VertRen *vr;
+ VlakRen *vlr;
+// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30};
+ float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn
+ int i; //, texflag=0;
+ Object *obt;
+
+ /* Object Size with parenting */
+ obt=obr->ob;
+ while(obt){
+ VecAddf(temp, obt->size, obt->dsize);
+ scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2];
+ obt=obt->parent;
+ }
+
+ /* Clear all flags */
+ for(i=0; i<obr->totvert; i++){
+ vr= RE_findOrAddVert(obr, i);
+ vr->flag= 0;
}
- MEM_freeN(bloha);
- MEM_freeN(hablock);
+ for(i=0; i<obr->totvlak; i++){
+ vlr=RE_findOrAddVlak(obr, i);
+ displace_render_face(re, obr, vlr, scale, mat, imat);
+ }
+
+ /* Recalc vertex normals */
+ calc_vertexnormals(re, obr, 0, 0);
}
/* ------------------------------------------------------------------------- */
-static void init_render_mball(Render *re, Object *ob)
+/* Metaball */
+/* ------------------------------------------------------------------------- */
+
+static void init_render_mball(Render *re, ObjectRen *obr)
{
+ Object *ob= obr->ob;
DispList *dl;
VertRen *ver;
VlakRen *vlr, *vlr1;
Material *ma;
- float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn;
- int a, need_orco, startvert, *index;
+ float *data, *nors, *orco, mat[4][4], imat[3][3], xn, yn, zn;
+ int a, need_orco, vlakindex, *index;
if (ob!=find_basis_mball(ob))
return;
@@ -1569,19 +2471,20 @@ static void init_render_mball(Render *re, Object *ob)
dl= ob->disp.first;
if(dl==0) return;
- startvert= re->totvert;
data= dl->verts;
nors= dl->nors;
+ orco= get_object_orco(re, ob);
- for(a=0; a<dl->nr; a++, data+=3, nors+=3) {
+ for(a=0; a<dl->nr; a++, data+=3, nors+=3, orco+=3) {
- ver= RE_findOrAddVert(re, re->totvert++);
+ ver= RE_findOrAddVert(obr, obr->totvert++);
VECCOPY(ver->co, data);
MTC_Mat4MulVecfl(mat, ver->co);
- xn= nors[0];
- yn= nors[1];
- zn= nors[2];
+ /* render normals are inverted */
+ xn= -nors[0];
+ yn= -nors[1];
+ zn= -nors[2];
/* transpose ! */
ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
@@ -1590,17 +2493,16 @@ static void init_render_mball(Render *re, Object *ob)
Normalize(ver->n);
//if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0);
- if(need_orco) ver->orco= data;
+ if(need_orco) ver->orco= orco;
}
index= dl->index;
for(a=0; a<dl->parts; a++, index+=4) {
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
- vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
- vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, index[0]);
+ vlr->v2= RE_findOrAddVert(obr, index[1]);
+ vlr->v3= RE_findOrAddVert(obr, index[2]);
vlr->v4= 0;
if(ob->transflag & OB_NEG_SCALE)
@@ -1611,14 +2513,15 @@ static void init_render_mball(Render *re, Object *ob)
vlr->mat= ma;
vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
vlr->ec= 0;
- vlr->lay= ob->lay;
/* mball -too bad- always has triangles, because quads can be non-planar */
if(index[3] && index[3]!=index[2]) {
- vlr1= RE_findOrAddVlak(re, re->totvlak++);
+ vlr1= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlakindex= vlr1->index;
*vlr1= *vlr;
+ vlr1->index= vlakindex;
vlr1->v2= vlr1->v3;
- vlr1->v3= RE_findOrAddVert(re, startvert+index[3]);
+ vlr1->v3= RE_findOrAddVert(obr, index[3]);
if(ob->transflag & OB_NEG_SCALE)
CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n);
else
@@ -1626,29 +2529,451 @@ static void init_render_mball(Render *re, Object *ob)
}
}
- if(need_orco) {
- /* store displist and scale */
- make_orco_mball(ob);
- }
- else {
- /* enforce display lists remade */
- freedisplist(&ob->disp);
- }
+ /* enforce display lists remade */
+ freedisplist(&ob->disp);
/* this enforces remake for real, orco displist is small (in scale) */
ob->recalc |= OB_RECALC_DATA;
}
+
+/* ------------------------------------------------------------------------- */
+/* Surfaces and Curves */
/* ------------------------------------------------------------------------- */
-/* convert */
-static int vlakren_customdata_layer_num(int n, int active)
+/* returns amount of vertices added for orco */
+static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, float *orco, float mat[4][4])
{
- /* make the active layer the first */
- if (n == active) return 0;
- else if (n < active) return n+1;
- else return n;
+ Object *ob= obr->ob;
+ VertRen *v1, *v2, *v3, *v4, *ver;
+ VlakRen *vlr, *vlr1, *vlr2, *vlr3;
+ Curve *cu= ob->data;
+ float *data, n1[3], flen;
+ int u, v, orcoret= 0;
+ int p1, p2, p3, p4, a;
+ int sizeu, nsizeu, sizev, nsizev;
+ int startvert, startvlak;
+
+ startvert= obr->totvert;
+ nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr;
+
+ data= dl->verts;
+ for (u = 0; u < sizeu; u++) {
+ v1 = RE_findOrAddVert(obr, obr->totvert++); /* save this for possible V wrapping */
+ VECCOPY(v1->co, data); data += 3;
+ if(orco) {
+ v1->orco= orco; orco+= 3; orcoret++;
+ }
+ MTC_Mat4MulVecfl(mat, v1->co);
+
+ for (v = 1; v < sizev; v++) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ VECCOPY(ver->co, data); data += 3;
+ if(orco) {
+ ver->orco= orco; orco+= 3; orcoret++;
+ }
+ MTC_Mat4MulVecfl(mat, ver->co);
+ }
+ /* if V-cyclic, add extra vertices at end of the row */
+ if (dl->flag & DL_CYCL_U) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ VECCOPY(ver->co, v1->co);
+ if(orco) {
+ ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
+ }
+ }
+ }
+
+ /* Done before next loop to get corner vert */
+ if (dl->flag & DL_CYCL_U) nsizev++;
+ if (dl->flag & DL_CYCL_V) nsizeu++;
+
+ /* if U cyclic, add extra row at end of column */
+ if (dl->flag & DL_CYCL_V) {
+ for (v = 0; v < nsizev; v++) {
+ v1= RE_findOrAddVert(obr, startvert + v);
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ VECCOPY(ver->co, v1->co);
+ if(orco) {
+ ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v);
+ }
+ }
+ }
+
+ sizeu = nsizeu;
+ sizev = nsizev;
+
+ startvlak= obr->totvlak;
+
+ for(u = 0; u < sizeu - 1; u++) {
+ p1 = startvert + u * sizev; /* walk through face list */
+ p2 = p1 + 1;
+ p3 = p2 + sizev;
+ p4 = p3 - 1;
+
+ for(v = 0; v < sizev - 1; v++) {
+ v1= RE_findOrAddVert(obr, p1);
+ v2= RE_findOrAddVert(obr, p2);
+ v3= RE_findOrAddVert(obr, p3);
+ v4= RE_findOrAddVert(obr, p4);
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
+
+ flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
+ VECCOPY(vlr->n, n1);
+
+ vlr->mat= matar[ dl->col];
+ vlr->ec= ME_V1V2+ME_V2V3;
+ vlr->flag= dl->rt;
+ if( (cu->flag & CU_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+
+ VecAddf(v1->n, v1->n, n1);
+ VecAddf(v2->n, v2->n, n1);
+ VecAddf(v3->n, v3->n, n1);
+ VecAddf(v4->n, v4->n, n1);
+
+ p1++; p2++; p3++; p4++;
+ }
+ }
+ /* fix normals for U resp. V cyclic faces */
+ sizeu--; sizev--; /* dec size for face array */
+ if (dl->flag & DL_CYCL_V) {
+
+ for (v = 0; v < sizev; v++)
+ {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, v));
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0, v));
+ VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
+ VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
+ VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
+ }
+ }
+ if (dl->flag & DL_CYCL_U) {
+
+ for (u = 0; u < sizeu; u++)
+ {
+ /* optimize! :*/
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(u, 0));
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(u, sizev-1));
+ VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
+ VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
+ VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
+ }
+ }
+ /* last vertex is an extra case:
+
+ ^ ()----()----()----()
+ | | | || |
+ u | |(0,n)||(0,0)|
+ | | || |
+ ()====()====[]====()
+ | | || |
+ | |(m,n)||(m,0)|
+ | | || |
+ ()----()----()----()
+ v ->
+
+ vertex [] is no longer shared, therefore distribute
+ normals of the surrounding faces to all of the duplicates of []
+ */
+
+ if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
+ {
+ vlr= RE_findOrAddVlak(obr, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
+ vlr1= RE_findOrAddVlak(obr, UVTOINDEX(0,0)); /* (0,0) */
+ VecAddf(n1, vlr->n, vlr1->n);
+ vlr2= RE_findOrAddVlak(obr, UVTOINDEX(0, sizev-1)); /* (0,n) */
+ VecAddf(n1, n1, vlr2->n);
+ vlr3= RE_findOrAddVlak(obr, UVTOINDEX(sizeu-1, 0)); /* (m,0) */
+ VecAddf(n1, n1, vlr3->n);
+ VECCOPY(vlr->v3->n, n1);
+ VECCOPY(vlr1->v1->n, n1);
+ VECCOPY(vlr2->v2->n, n1);
+ VECCOPY(vlr3->v4->n, n1);
+ }
+ for(a = startvert; a < obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
+ Normalize(ver->n);
+ }
+
+
+ return orcoret;
+}
+
+static void init_render_surf(Render *re, ObjectRen *obr)
+{
+ Object *ob= obr->ob;
+ Nurb *nu=0;
+ Curve *cu;
+ ListBase displist;
+ DispList *dl;
+ Material *matar[32];
+ float *orco=NULL, *orcobase=NULL, mat[4][4];
+ int a, need_orco=0;
+
+ cu= ob->data;
+ nu= cu->nurb.first;
+ if(nu==0) return;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+
+ /* material array */
+ memset(matar, 0, 4*32);
+ matar[0]= give_render_material(re, ob, 0);
+ for(a=0; a<ob->totcol; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+ if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+ }
+
+ if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
+
+ if(need_orco) orcobase= orco= get_object_orco(re, ob);
+
+ displist.first= displist.last= 0;
+ makeDispListSurf(ob, &displist, 1);
+
+ dl= displist.first;
+ /* walk along displaylist and create rendervertices/-faces */
+ while(dl) {
+ /* watch out: u ^= y, v ^= x !! */
+ if(dl->type==DL_SURF) {
+ orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
+ }
+
+ dl= dl->next;
+ }
+ freedisplist(&displist);
+}
+
+static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ Curve *cu;
+ VertRen *ver;
+ VlakRen *vlr;
+ DispList *dl;
+ ListBase olddl={NULL, NULL};
+ Material *matar[32];
+ float len, *data, *fp, *orco=NULL, *orcobase= NULL;
+ float n[3], mat[4][4];
+ int nr, startvert, startvlak, a, b;
+ int frontside, need_orco=0;
+
+ cu= ob->data;
+ if(ob->type==OB_FONT && cu->str==NULL) return;
+ else if(ob->type==OB_CURVE && cu->nurb.first==NULL) return;
+
+ /* no modifier call here, is in makedisp */
+
+ if(cu->resolu_ren)
+ SWAP(ListBase, olddl, cu->disp);
+
+ /* test displist */
+ if(cu->disp.first==NULL)
+ makeDispListCurveTypes(ob, 0);
+ dl= cu->disp.first;
+ if(cu->disp.first==NULL) return;
+
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+
+ /* material array */
+ memset(matar, 0, 4*32);
+ matar[0]= give_render_material(re, ob, 0);
+ for(a=0; a<ob->totcol; a++) {
+ matar[a]= give_render_material(re, ob, a+1);
+ if(matar[a]->texco & TEXCO_ORCO) {
+ need_orco= 1;
+ }
+ }
+
+ if(need_orco) orcobase=orco= get_object_orco(re, ob);
+
+ dl= cu->disp.first;
+ while(dl) {
+ if(dl->type==DL_INDEX3) {
+ int *index;
+
+ startvert= obr->totvert;
+ data= dl->verts;
+
+ n[0]= ob->imat[0][2];
+ n[1]= ob->imat[1][2];
+ n[2]= ob->imat[2][2];
+ Normalize(n);
+
+ for(a=0; a<dl->nr; a++, data+=3) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+ VECCOPY(ver->co, data);
+
+ /* flip normal if face is backfacing, also used in face loop below */
+ if(ver->co[2] < 0.0) {
+ VECCOPY(ver->n, n);
+ ver->flag = 1;
+ }
+ else {
+ ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
+ ver->flag = 0;
+ }
+
+ MTC_Mat4MulVecfl(mat, ver->co);
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ if(timeoffset==0) {
+ startvlak= obr->totvlak;
+ index= dl->index;
+ for(a=0; a<dl->parts; a++, index+=3) {
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
+ vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
+ vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
+ vlr->v4= NULL;
+
+ if(vlr->v1->flag) {
+ VECCOPY(vlr->n, n);
+ }
+ else {
+ vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
+ }
+
+ vlr->mat= matar[ dl->col ];
+ vlr->flag= 0;
+ if( (cu->flag & CU_NOPUNOFLIP) ) {
+ vlr->flag |= R_NOPUNOFLIP;
+ }
+ vlr->ec= 0;
+ }
+ }
+ }
+ else if (dl->type==DL_SURF) {
+
+ /* cyclic U means an extruded full circular curve, we skip bevel splitting then */
+ if (dl->flag & DL_CYCL_U) {
+ orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
+ }
+ else {
+ int p1,p2,p3,p4;
+
+ fp= dl->verts;
+ startvert= obr->totvert;
+ nr= dl->nr*dl->parts;
+
+ while(nr--) {
+ ver= RE_findOrAddVert(obr, obr->totvert++);
+
+ VECCOPY(ver->co, fp);
+ MTC_Mat4MulVecfl(mat, ver->co);
+ fp+= 3;
+
+ if (orco) {
+ ver->orco = orco;
+ orco += 3;
+ }
+ }
+
+ if(dl->bevelSplitFlag || timeoffset==0) {
+ startvlak= obr->totvlak;
+
+ for(a=0; a<dl->parts; a++) {
+
+ frontside= (a >= dl->nr/2);
+
+ DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
+ p1+= startvert;
+ p2+= startvert;
+ p3+= startvert;
+ p4+= startvert;
+
+ for(; b<dl->nr; b++) {
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, p2);
+ vlr->v2= RE_findOrAddVert(obr, p1);
+ vlr->v3= RE_findOrAddVert(obr, p3);
+ vlr->v4= RE_findOrAddVert(obr, p4);
+ vlr->ec= ME_V2V3+ME_V3V4;
+ if(a==0) vlr->ec+= ME_V1V2;
+
+ vlr->flag= dl->rt;
+
+ /* this is not really scientific: the vertices
+ * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
+ * front and backside treated different!!
+ */
+
+ if(frontside)
+ CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
+ else
+ CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
+
+ vlr->mat= matar[ dl->col ];
+
+ p4= p3;
+ p3++;
+ p2= p1;
+ p1++;
+ }
+ }
+
+ if (dl->bevelSplitFlag) {
+ for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
+ if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
+ split_v_renderfaces(obr, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
+ }
+
+ /* vertex normals */
+ for(a= startvlak; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
+
+ VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
+ VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
+ VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
+ VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
+ }
+ for(a=startvert; a<obr->totvert; a++) {
+ ver= RE_findOrAddVert(obr, a);
+ len= Normalize(ver->n);
+ if(len==0.0) ver->flag= 1; /* flag abuse, its only used in zbuf now */
+ else ver->flag= 0;
+ }
+ for(a= startvlak; a<obr->totvlak; a++) {
+ vlr= RE_findOrAddVlak(obr, a);
+ if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
+ if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
+ if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
+ if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
+ }
+ }
+ }
+ }
+
+ dl= dl->next;
+ }
+
+ /* not very elegant... but we want original displist in UI */
+ if(cu->resolu_ren) {
+ freedisplist(&cu->disp);
+ SWAP(ListBase, olddl, cu->disp);
+ }
}
+/* ------------------------------------------------------------------------- */
+/* Mesh */
+/* ------------------------------------------------------------------------- */
+
struct edgesort {
int v1, v2;
int f;
@@ -1726,13 +3051,13 @@ static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
return edsort;
}
-static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
+static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
{
struct edgesort ed, *edp;
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn, mcn, n;
+ int index, mtfn, mcn;
char *name;
if(medge->v1 < medge->v2) {
@@ -1756,8 +3081,7 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak
if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
mtface= &((MTFace*)layer->data)[edp->f];
- n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd);
- mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1);
+ mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
*mtf= *mtface;
@@ -1768,8 +3092,7 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak
}
else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
mcol= &((MCol*)layer->data)[edp->f*4];
- n= vlakren_customdata_layer_num(mcn++, layer->active_rnd);
- mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1);
+ mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
mc[0]= mcol[edp->i1];
mc[1]= mc[2]= mc[3]= mcol[edp->i2];
@@ -1778,8 +3101,9 @@ static void use_mesh_edge_lookup(Render *re, DerivedMesh *dm, MEdge *medge, Vlak
}
}
-static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts)
+static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
{
+ Object *ob= obr->ob;
Mesh *me;
MVert *mvert = NULL;
MFace *mface;
@@ -1787,35 +3111,24 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
VertRen *ver;
Material *ma;
MSticky *ms = NULL;
- PartEff *paf;
DerivedMesh *dm;
+ CustomDataMask mask;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco=0;
- int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
+ int need_orco=0, need_stress=0, need_nmap_tangent=0, need_tangent=0;
+ int a, a1, ok, vertofs;
int end, do_autosmooth=0, totvert = 0;
int useFluidmeshNormals= 0; // NT fluidsim, use smoothed normals?
int use_original_normals= 0;
me= ob->data;
- paf = give_parteff(ob);
- if(paf) {
- /* warning; build_particle_system does modifier calls itself */
- if(paf->flag & PAF_STATIC) render_static_particle_system(re, ob, paf);
- else render_particle_system(re, ob, par, paf);
- if((paf->flag & PAF_SHOWE)==0) return;
- }
-
MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
MTC_Mat4Invert(ob->imat, mat);
MTC_Mat3CpyMat4(imat, ob->imat);
- if(me->totvert==0) {
+ if(me->totvert==0)
return;
- }
-
- totvlako= re->totvlak;
- totverto= re->totvert;
need_orco= 0;
for(a=1; a<=ob->totcol; a++) {
@@ -1826,33 +3139,65 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
if(ma->texco & TEXCO_STRESS)
need_stress= 1;
/* normalmaps, test if tangents needed, separated from shading */
- if ((ma->mode_l & MA_TANGENT_V) || (ma->mode_l & MA_NORMAP_TANG)) {
+ if(ma->mode_l & MA_TANGENT_V) {
need_tangent= 1;
if(me->mtface==NULL)
need_orco= 1;
}
+ if(ma->mode_l & MA_NORMAP_TANG) {
+ if(me->mtface==NULL) {
+ need_orco= 1;
+ need_tangent= 1;
+ }
+ need_nmap_tangent= 1;
+ }
+
/* radio faces need autosmooth, to separate shared vertices in corners */
if(re->r.mode & R_RADIO)
if(ma->mode & MA_RADIO)
do_autosmooth= 1;
}
}
+
+ if(re->flag & R_NEED_TANGENT) {
+ /* exception for tangent space baking */
+ if(me->mtface==NULL) {
+ need_orco= 1;
+ need_tangent= 1;
+ }
+ need_nmap_tangent= 1;
+ }
/* check autosmooth and displacement, we then have to skip only-verts optimize */
do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
if(do_autosmooth)
- only_verts= 0;
+ timeoffset= 0;
if(test_for_displace(re, ob ) )
- only_verts= 0;
+ timeoffset= 0;
- if(!only_verts)
- if(need_orco) orco = get_object_orco(re, ob);
+ mask= CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL;
+ if(!timeoffset)
+ if(need_orco)
+ mask |= CD_MASK_ORCO;
- dm = mesh_create_derived_render(ob,
- CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
-
+ if(me->mr) {
+ if(re->flag & R_SKIP_MULTIRES)
+ me->mr->flag |= MULTIRES_NO_RENDER;
+ else
+ me->mr->flag &= ~MULTIRES_NO_RENDER;
+ }
+
+ dm= mesh_create_derived_render(ob, mask);
if(dm==NULL) return; /* in case duplicated object fails? */
+ if(mask & CD_MASK_ORCO) {
+ orco= dm->getVertDataArray(dm, CD_ORCO);
+ if(orco) {
+ orco= MEM_dupallocN(orco);
+ set_object_orco(re, ob, orco);
+ }
+ }
+
if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
(ob->fluidsimSettings->meshSurface) ) {
@@ -1871,20 +3216,21 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
ma= give_render_material(re, ob, 1);
if(ma->mode & MA_HALO) {
- make_render_halos(re, ob, me, totvert, mvert, ma, orco);
+ make_render_halos(re, obr, me, totvert, mvert, ma, orco);
}
else {
for(a=0; a<totvert; a++, mvert++) {
- ver= RE_findOrAddVert(re, re->totvert++);
+ ver= RE_findOrAddVert(obr, obr->totvert++);
VECCOPY(ver->co, mvert->co);
if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */
MTC_Mat4MulVecfl(mat, ver->co);
-
+
if(useFluidmeshNormals) {
- xn = mvert->no[0]/ 32767.0;
- yn = mvert->no[1]/ 32767.0;
- zn = mvert->no[2]/ 32767.0;
+ /* normals are inverted in render */
+ xn = -mvert->no[0]/ 32767.0;
+ yn = -mvert->no[1]/ 32767.0;
+ zn = -mvert->no[2]/ 32767.0;
/* transfor to cam space */
ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
@@ -1896,21 +3242,21 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
orco+=3;
}
if(ms) {
- float *sticky= RE_vertren_get_sticky(re, ver, 1);
+ float *sticky= RE_vertren_get_sticky(obr, ver, 1);
sticky[0]= ms->co[0];
sticky[1]= ms->co[1];
ms++;
}
}
- if(!only_verts) {
+ if(!timeoffset) {
/* store customdata names, because DerivedMesh is freed */
- RE_vlakren_set_customdata_names(re, &dm->faceData);
+ RE_set_customdata_names(obr, &dm->faceData);
/* still to do for keys: the correct local texture coordinate */
/* faces in order of color blocks */
- vertofs= re->totvert - totvert;
+ vertofs= obr->totvert - totvert;
for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
ma= give_render_material(re, ob, a1+1);
@@ -1948,13 +3294,12 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
v3= mface->v3;
v4= mface->v4;
flag= mface->flag & ME_SMOOTH;
-
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, vertofs+v1);
- vlr->v2= RE_findOrAddVert(re, vertofs+v2);
- vlr->v3= RE_findOrAddVert(re, vertofs+v3);
- if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4);
+
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
+ vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
+ vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
+ if(v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
else vlr->v4= 0;
/* render normals are inverted in render */
@@ -1980,14 +3325,13 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
vlr->flag |= R_NOPUNOFLIP;
}
vlr->ec= 0; /* mesh edges rendered separately */
- vlr->lay= ob->lay;
- if(len==0) re->totvlak--;
+ if(len==0) obr->totvlak--;
else {
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn= 0, mcn= 0, n;
+ int index, mtfn= 0, mcn= 0;
char *name;
for(index=0; index<dm->faceData.totlayer; index++) {
@@ -1995,14 +3339,12 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
name= layer->name;
if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
- n= vlakren_customdata_layer_num(mtfn++, layer->active_rnd);
- mtf= RE_vlakren_get_tface(re, vlr, n, &name, 1);
+ mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
mtface= (MTFace*)layer->data;
*mtf= mtface[a];
}
else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
- n= vlakren_customdata_layer_num(mcn++, layer->active_rnd);
- mc= RE_vlakren_get_mcol(re, vlr, n, &name, 1);
+ mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
mcol= (MCol*)layer->data;
memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
}
@@ -2032,16 +3374,14 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
MVert *v0 = &mvert[medge->v1];
MVert *v1 = &mvert[medge->v2];
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1);
- vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2);
+ vlr= RE_findOrAddVlak(obr, obr->totvlak++);
+ vlr->v1= RE_findOrAddVert(obr, vertofs+medge->v1);
+ vlr->v2= RE_findOrAddVert(obr, vertofs+medge->v2);
vlr->v3= vlr->v2;
vlr->v4= NULL;
- if(edgetable) {
- use_mesh_edge_lookup(re, dm, medge, vlr, edgetable, totedge);
- }
+ if(edgetable)
+ use_mesh_edge_lookup(obr, dm, medge, vlr, edgetable, totedge);
xn= -(v0->no[0]+v1->no[0]);
yn= -(v0->no[1]+v1->no[1]);
@@ -2055,7 +3395,6 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
vlr->mat= ma;
vlr->flag= 0;
vlr->ec= ME_V1V2;
- vlr->lay= ob->lay;
}
}
if(edgetable)
@@ -2064,31 +3403,36 @@ static void init_render_mesh(Render *re, Object *ob, Object *par, int only_verts
}
}
- if(!only_verts) {
+ if(!timeoffset) {
if (test_for_displace(re, ob ) ) {
- calc_vertexnormals(re, totverto, totvlako, 0);
- do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto);
+ calc_vertexnormals(re, obr, 0, 0);
+ if(do_autosmooth)
+ do_displacement(re, obr, mat, imat);
+ else
+ do_displacement(re, obr, NULL, NULL);
}
if(do_autosmooth) {
- autosmooth(re, mat, totverto, totvlako, me->smoothresh);
+ autosmooth(re, obr, mat, me->smoothresh);
}
if(useFluidmeshNormals) {
// do not recalculate, only init render data
- calc_fluidsimnormals(re, totverto, totvlako, need_tangent);
+ calc_fluidsimnormals(re, obr, need_tangent||need_nmap_tangent);
} else {
- calc_vertexnormals(re, totverto, totvlako, need_tangent);
+ calc_vertexnormals(re, obr, need_tangent, need_nmap_tangent);
}
if(need_stress)
- calc_edge_stress(re, me, totverto, totvlako);
+ calc_edge_stress(re, obr, me);
}
dm->release(dm);
}
/* ------------------------------------------------------------------------- */
+/* Lamps and Shadowbuffers */
+/* ------------------------------------------------------------------------- */
static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
{
@@ -2108,8 +3452,6 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
/* percentage render: keep track of min and max */
shb->size= (lar->bufsize*re->r.size)/100;
- if(lar->buffers>1) shb->size/= 2;
-
if(shb->size<512) shb->size= 512;
else if(shb->size > lar->bufsize) shb->size= lar->bufsize;
@@ -2142,11 +3484,15 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
}
-
static void area_lamp_vectors(LampRen *lar)
{
- float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
+ float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
+ /* make it smaller, so area light can be multisampled */
+ multifac= 1.0f/sqrt((float)lar->ray_totsamp);
+ xsize *= multifac;
+ ysize *= multifac;
+
/* corner vectors */
lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
@@ -2221,7 +3567,6 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
lar->mode= la->mode;
lar->energy= la->energy;
- lar->energy= la->energy;
if(la->mode & LA_NEG) lar->energy= -lar->energy;
lar->vec[0]= -mat[2][0];
@@ -2243,15 +3588,30 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
lar->ray_samp= la->ray_samp;
lar->ray_sampy= la->ray_sampy;
lar->ray_sampz= la->ray_sampz;
-
+
lar->area_size= la->area_size;
lar->area_sizey= la->area_sizey;
lar->area_sizez= la->area_sizez;
lar->area_shape= la->area_shape;
+
+ /* Annoying, lamp UI does this, but the UI might not have been used? - add here too.
+ * make sure this matches buttons_shading.c's logic */
+ if(ELEM4(la->type, LA_AREA, LA_SPOT, LA_SUN, LA_LOCAL) && (la->mode & LA_SHAD_RAY))
+ if (ELEM3(la->type, LA_SPOT, LA_SUN, LA_LOCAL))
+ if (la->ray_samp_method == LA_SAMP_CONSTANT) la->ray_samp_method = LA_SAMP_HALTON;
+
+ lar->ray_samp_method= la->ray_samp_method;
lar->ray_samp_type= la->ray_samp_type;
-
- if(lar->type==LA_AREA) {
+
+ lar->adapt_thresh= la->adapt_thresh;
+
+ if( ELEM3(lar->type, LA_SPOT, LA_SUN, LA_LOCAL)) {
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->area_shape = LA_AREA_SQUARE;
+ lar->area_sizey= lar->area_size;
+ }
+ else if(lar->type==LA_AREA) {
switch(lar->area_shape) {
case LA_AREA_SQUARE:
lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
@@ -2274,6 +3634,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
}
area_lamp_vectors(lar);
+ init_jitter_plane(lar); // subsamples
}
else lar->ray_totsamp= 0;
@@ -2304,8 +3665,10 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
lar->lay= ob->lay & 0xFFFFFF; // higher 8 bits are localview layers
+ lar->falloff_type = la->falloff_type;
lar->ld1= la->att1;
lar->ld2= la->att2;
+ lar->curfalloff = curvemapping_copy(la->curfalloff);
if(lar->type==LA_SPOT) {
@@ -2369,28 +3732,41 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
if(re->r.mode & R_SHADOW) {
- if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
+
+ if ((lar->mode & LA_SHAD_RAY) && (lar->ray_samp_method == LA_SAMP_HAMMERSLEY)) {
+ init_lamp_hammersley(lar);
+ }
+ if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) && (lar->ray_samp_method == LA_SAMP_CONSTANT)) {
+ init_jitter_plane(lar);
+ }
+ else if (la->type==LA_SPOT && (lar->mode & LA_SHAD_BUF) ) {
/* Per lamp, one shadow buffer is made. */
lar->bufflag= la->bufflag;
Mat4CpyMat4(mat, ob->obmat);
initshadowbuf(re, lar, mat); // mat is altered
}
- else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
- init_jitter_plane(lar);
- }
+
/* this is the way used all over to check for shadow */
if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
+ LampShadowSample *ls;
LampShadowSubSample *lss;
- int a, b, tot= re->r.threads*re->r.osa;
+ int a, b;
+
+ memset(re->shadowsamplenr, 0, sizeof(re->shadowsamplenr));
lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
- lss= lar->shadsamp[0].s;
+ ls= lar->shadsamp;
+
/* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
- for(a=0; a<tot; a++, lss++) {
- for(b=0; b<4; b++) {
+ for(a=0; a<re->r.threads; a++, ls++) {
+ lss= ls->s;
+ for(b=0; b<re->r.osa; b++, lss++) {
lss->samplenr= -1; /* used to detect whether we store or read */
- lss->shadfac[b]= 1.0f;
+ lss->shadfac[0]= 1.0f;
+ lss->shadfac[1]= 1.0f;
+ lss->shadfac[2]= 1.0f;
+ lss->shadfac[3]= 1.0f;
}
}
}
@@ -2400,442 +3776,123 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
return go;
}
-/* ------------------------------------------------------------------------- */
-
-/* returns amount of vertices added for orco */
-static int dl_surf_to_renderdata(Render *re, Object *ob, DispList *dl, Material **matar, float *orco, float mat[4][4])
+/* layflag: allows material group to ignore layerflag */
+static void add_lightgroup(Render *re, Group *group, int exclusive)
{
- VertRen *v1, *v2, *v3, *v4, *ver;
- VlakRen *vlr, *vlr1, *vlr2, *vlr3;
- Curve *cu= ob->data;
- float *data, n1[3], flen;
- int u, v, orcoret= 0;
- int p1, p2, p3, p4, a;
- int sizeu, nsizeu, sizev, nsizev;
- int startvert, startvlak;
-
- startvert= re->totvert;
- nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr;
+ GroupObject *go, *gol;
- data= dl->verts;
- for (u = 0; u < sizeu; u++) {
- v1 = RE_findOrAddVert(re, re->totvert++); /* save this for possible V wrapping */
- VECCOPY(v1->co, data); data += 3;
- if(orco) {
- v1->orco= orco; orco+= 3; orcoret++;
- }
- MTC_Mat4MulVecfl(mat, v1->co);
+ group->id.flag &= ~LIB_DOIT;
+
+ /* it's a bit too many loops in loops... but will survive */
+ /* note that 'exclusive' will remove it from the global list */
+ for(go= group->gobject.first; go; go= go->next) {
+ go->lampren= NULL;
- for (v = 1; v < sizev; v++) {
- ver= RE_findOrAddVert(re, re->totvert++);
- VECCOPY(ver->co, data); data += 3;
- if(orco) {
- ver->orco= orco; orco+= 3; orcoret++;
- }
- MTC_Mat4MulVecfl(mat, ver->co);
- }
- /* if V-cyclic, add extra vertices at end of the row */
- if (dl->flag & DL_CYCL_U) {
- ver= RE_findOrAddVert(re, re->totvert++);
- VECCOPY(ver->co, v1->co);
- if(orco) {
- ver->orco= orco; orco+=3; orcoret++; //orcobase + 3*(u*sizev + 0);
- }
- }
- }
-
- /* Done before next loop to get corner vert */
- if (dl->flag & DL_CYCL_U) nsizev++;
- if (dl->flag & DL_CYCL_V) nsizeu++;
-
- /* if U cyclic, add extra row at end of column */
- if (dl->flag & DL_CYCL_V) {
- for (v = 0; v < nsizev; v++) {
- v1= RE_findOrAddVert(re, startvert + v);
- ver= RE_findOrAddVert(re, re->totvert++);
- VECCOPY(ver->co, v1->co);
- if(orco) {
- ver->orco= orco; orco+=3; orcoret++; //ver->orco= orcobase + 3*(0*sizev + v);
+ if(go->ob->lay & re->scene->lay) {
+ if(go->ob && go->ob->type==OB_LAMP) {
+ for(gol= re->lights.first; gol; gol= gol->next) {
+ if(gol->ob==go->ob) {
+ go->lampren= gol->lampren;
+ break;
+ }
+ }
+ if(go->lampren==NULL)
+ gol= add_render_lamp(re, go->ob);
+ if(gol && exclusive) {
+ BLI_remlink(&re->lights, gol);
+ MEM_freeN(gol);
+ }
}
}
}
+}
+
+static void set_material_lightgroups(Render *re)
+{
+ Group *group;
+ Material *ma;
- sizeu = nsizeu;
- sizev = nsizev;
-
- startvlak= re->totvlak;
+ /* not for preview render */
+ if(re->scene->r.scemode & R_PREVIEWBUTS)
+ return;
- for(u = 0; u < sizeu - 1; u++) {
- p1 = startvert + u * sizev; /* walk through face list */
- p2 = p1 + 1;
- p3 = p2 + sizev;
- p4 = p3 - 1;
-
- for(v = 0; v < sizev - 1; v++) {
- v1= RE_findOrAddVert(re, p1);
- v2= RE_findOrAddVert(re, p2);
- v3= RE_findOrAddVert(re, p3);
- v4= RE_findOrAddVert(re, p4);
-
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
-
- flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
- VECCOPY(vlr->n, n1);
-
- vlr->lay= ob->lay;
- vlr->mat= matar[ dl->col];
- vlr->ec= ME_V1V2+ME_V2V3;
- vlr->flag= dl->rt;
- if( (cu->flag & CU_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
- }
-
- VecAddf(v1->n, v1->n, n1);
- VecAddf(v2->n, v2->n, n1);
- VecAddf(v3->n, v3->n, n1);
- VecAddf(v4->n, v4->n, n1);
-
- p1++; p2++; p3++; p4++;
- }
- }
- /* fix normals for U resp. V cyclic faces */
- sizeu--; sizev--; /* dec size for face array */
- if (dl->flag & DL_CYCL_V) {
-
- for (v = 0; v < sizev; v++)
- {
- /* optimize! :*/
- vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, v));
- vlr1= RE_findOrAddVlak(re, UVTOINDEX(0, v));
- VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
- VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
- VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
- }
- }
- if (dl->flag & DL_CYCL_U) {
-
- for (u = 0; u < sizeu; u++)
- {
- /* optimize! :*/
- vlr= RE_findOrAddVlak(re, UVTOINDEX(u, 0));
- vlr1= RE_findOrAddVlak(re, UVTOINDEX(u, sizev-1));
- VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
- VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
- VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
- }
- }
- /* last vertex is an extra case:
-
- ^ ()----()----()----()
- | | | || |
- u | |(0,n)||(0,0)|
- | | || |
- ()====()====[]====()
- | | || |
- | |(m,n)||(m,0)|
- | | || |
- ()----()----()----()
- v ->
-
- vertex [] is no longer shared, therefore distribute
- normals of the surrounding faces to all of the duplicates of []
- */
+ for(group= G.main->group.first; group; group=group->id.next)
+ group->id.flag |= LIB_DOIT;
- if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U))
- {
- vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
- vlr1= RE_findOrAddVlak(re, UVTOINDEX(0,0)); /* (0,0) */
- VecAddf(n1, vlr->n, vlr1->n);
- vlr2= RE_findOrAddVlak(re, UVTOINDEX(0, sizev-1)); /* (0,n) */
- VecAddf(n1, n1, vlr2->n);
- vlr3= RE_findOrAddVlak(re, UVTOINDEX(sizeu-1, 0)); /* (m,0) */
- VecAddf(n1, n1, vlr3->n);
- VECCOPY(vlr->v3->n, n1);
- VECCOPY(vlr1->v1->n, n1);
- VECCOPY(vlr2->v2->n, n1);
- VECCOPY(vlr3->v4->n, n1);
- }
- for(a = startvert; a < re->totvert; a++) {
- ver= RE_findOrAddVert(re, a);
- Normalize(ver->n);
+ /* it's a bit too many loops in loops... but will survive */
+ /* hola! materials not in use...? */
+ for(ma= G.main->mat.first; ma; ma=ma->id.next) {
+ if(ma->group && (ma->group->id.flag & LIB_DOIT))
+ add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY);
}
-
-
- return orcoret;
}
-static void init_render_surf(Render *re, Object *ob)
+static void set_renderlayer_lightgroups(Render *re, Scene *sce)
{
- Nurb *nu=0;
- Curve *cu;
- ListBase displist;
- DispList *dl;
- Material *matar[32];
- float *orco=NULL, *orcobase=NULL, mat[4][4];
- int a, need_orco=0;
-
- cu= ob->data;
- nu= cu->nurb.first;
- if(nu==0) return;
-
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
-
- /* material array */
- memset(matar, 0, 4*32);
- matar[0]= give_render_material(re, ob, 0);
- for(a=0; a<ob->totcol; a++) {
- matar[a]= give_render_material(re, ob, a+1);
- if(matar[a] && matar[a]->texco & TEXCO_ORCO) {
- need_orco= 1;
- }
- }
-
- if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
-
- if(need_orco) orcobase= orco= get_object_orco(re, ob);
-
- displist.first= displist.last= 0;
- makeDispListSurf(ob, &displist, 1);
-
- dl= displist.first;
- /* walk along displaylist and create rendervertices/-faces */
- while(dl) {
- /* watch out: u ^= y, v ^= x !! */
- if(dl->type==DL_SURF) {
- orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
- }
-
- dl= dl->next;
+ SceneRenderLayer *srl;
+
+ for(srl= sce->r.layers.first; srl; srl= srl->next) {
+ if(srl->light_override)
+ add_lightgroup(re, srl->light_override, 0);
}
- freedisplist(&displist);
}
-static void init_render_curve(Render *re, Object *ob, int only_verts)
-{
- Curve *cu;
- VertRen *ver;
- VlakRen *vlr;
- DispList *dl;
- ListBase olddl={NULL, NULL};
- Material *matar[32];
- float len, *data, *fp, *orco=NULL, *orcobase= NULL;
- float n[3], mat[4][4];
- int nr, startvert, startvlak, a, b;
- int frontside, need_orco=0;
-
- cu= ob->data;
- if(cu->nurb.first==NULL) return;
-
- /* no modifier call here, is in makedisp */
+/* ------------------------------------------------------------------------- */
+/* World */
+/* ------------------------------------------------------------------------- */
- if(cu->resolu_ren)
- SWAP(ListBase, olddl, cu->disp);
-
- /* test displist */
- if(cu->disp.first==NULL)
- makeDispListCurveTypes(ob, 0);
- dl= cu->disp.first;
- if(cu->disp.first==NULL) return;
+void init_render_world(Render *re)
+{
+ int a;
+ char *cp;
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
-
- /* material array */
- memset(matar, 0, 4*32);
- matar[0]= give_render_material(re, ob, 0);
- for(a=0; a<ob->totcol; a++) {
- matar[a]= give_render_material(re, ob, a+1);
- if(matar[a]->texco & TEXCO_ORCO) {
- need_orco= 1;
- }
+ if(re->scene && re->scene->world) {
+ re->wrld= *(re->scene->world);
+
+ cp= (char *)&re->wrld.fastcol;
+
+ cp[0]= 255.0*re->wrld.horr;
+ cp[1]= 255.0*re->wrld.horg;
+ cp[2]= 255.0*re->wrld.horb;
+ cp[3]= 1;
+
+ VECCOPY(re->grvec, re->viewmat[2]);
+ Normalize(re->grvec);
+ Mat3CpyMat4(re->imat, re->viewinv);
+
+ for(a=0; a<MAX_MTEX; a++)
+ if(re->wrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX;
+
+ /* AO samples should be OSA minimum */
+ if(re->osa)
+ while(re->wrld.aosamp*re->wrld.aosamp < re->osa)
+ re->wrld.aosamp++;
+ if(!(re->r.mode & R_RAYTRACE) && (re->wrld.ao_gather_method == WO_AOGATHER_RAYTRACE))
+ re->wrld.mode &= ~WO_AMB_OCC;
}
-
- if(need_orco) orcobase=orco= get_object_orco(re, ob);
-
- dl= cu->disp.first;
- while(dl) {
- if(dl->type==DL_INDEX3) {
- int *index;
-
- startvert= re->totvert;
- data= dl->verts;
-
- n[0]= ob->imat[0][2];
- n[1]= ob->imat[1][2];
- n[2]= ob->imat[2][2];
- Normalize(n);
-
- for(a=0; a<dl->nr; a++, data+=3) {
- ver= RE_findOrAddVert(re, re->totvert++);
- VECCOPY(ver->co, data);
-
- /* flip normal if face is backfacing, also used in face loop below */
- if(ver->co[2] < 0.0) {
- VECCOPY(ver->n, n);
- ver->flag = 1;
- }
- else {
- ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
- ver->flag = 0;
- }
-
- MTC_Mat4MulVecfl(mat, ver->co);
-
- if (orco) {
- ver->orco = orco;
- orco += 3;
- }
- }
-
- if(only_verts==0) {
- startvlak= re->totvlak;
- index= dl->index;
- for(a=0; a<dl->parts; a++, index+=3) {
-
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob = ob;
- vlr->v1= RE_findOrAddVert(re, startvert+index[0]);
- vlr->v2= RE_findOrAddVert(re, startvert+index[1]);
- vlr->v3= RE_findOrAddVert(re, startvert+index[2]);
- vlr->v4= NULL;
-
- if(vlr->v1->flag) {
- VECCOPY(vlr->n, n);
- }
- else {
- vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
- }
-
- vlr->mat= matar[ dl->col ];
- vlr->flag= 0;
- if( (cu->flag & CU_NOPUNOFLIP) ) {
- vlr->flag |= R_NOPUNOFLIP;
- }
- vlr->ec= 0;
- vlr->lay= ob->lay;
- }
- }
- }
- else if (dl->type==DL_SURF) {
-
- /* cyclic U means an extruded full circular curve, we skip bevel splitting then */
- if (dl->flag & DL_CYCL_U) {
- orco+= 3*dl_surf_to_renderdata(re, ob, dl, matar, orco, mat);
- }
- else {
- int p1,p2,p3,p4;
-
- fp= dl->verts;
- startvert= re->totvert;
- nr= dl->nr*dl->parts;
-
- while(nr--) {
- ver= RE_findOrAddVert(re, re->totvert++);
-
- VECCOPY(ver->co, fp);
- MTC_Mat4MulVecfl(mat, ver->co);
- fp+= 3;
-
- if (orco) {
- ver->orco = orco;
- orco += 3;
- }
- }
-
- if(dl->bevelSplitFlag || only_verts==0) {
- startvlak= re->totvlak;
-
- for(a=0; a<dl->parts; a++) {
-
- frontside= (a >= dl->nr/2);
-
- DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
- p1+= startvert;
- p2+= startvert;
- p3+= startvert;
- p4+= startvert;
-
- for(; b<dl->nr; b++) {
- vlr= RE_findOrAddVlak(re, re->totvlak++);
- vlr->ob= ob;
- vlr->v1= RE_findOrAddVert(re, p2);
- vlr->v2= RE_findOrAddVert(re, p1);
- vlr->v3= RE_findOrAddVert(re, p3);
- vlr->v4= RE_findOrAddVert(re, p4);
- vlr->ec= ME_V2V3+ME_V3V4;
- if(a==0) vlr->ec+= ME_V1V2;
-
- vlr->flag= dl->rt;
- vlr->lay= ob->lay;
-
- /* this is not really scientific: the vertices
- * 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
- * front and backside treated different!!
- */
-
- if(frontside)
- CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n);
- else
- CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n);
-
- vlr->mat= matar[ dl->col ];
-
- p4= p3;
- p3++;
- p2= p1;
- p1++;
- }
- }
-
- if (dl->bevelSplitFlag) {
- for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
- if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
- split_v_renderfaces(re, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
- }
-
- /* vertex normals */
- for(a= startvlak; a<re->totvlak; a++) {
- vlr= RE_findOrAddVlak(re, a);
-
- VecAddf(vlr->v1->n, vlr->v1->n, vlr->n);
- VecAddf(vlr->v3->n, vlr->v3->n, vlr->n);
- VecAddf(vlr->v2->n, vlr->v2->n, vlr->n);
- VecAddf(vlr->v4->n, vlr->v4->n, vlr->n);
- }
- for(a=startvert; a<re->totvert; a++) {
- ver= RE_findOrAddVert(re, a);
- len= Normalize(ver->n);
- if(len==0.0) ver->flag= 1; /* flag abuse, its only used in zbuf now */
- else ver->flag= 0;
- }
- for(a= startvlak; a<re->totvlak; a++) {
- vlr= RE_findOrAddVlak(re, a);
- if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
- if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
- if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
- if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
- }
- }
- }
- }
-
- dl= dl->next;
+ else {
+ memset(&re->wrld, 0, sizeof(World));
+ re->wrld.exp= 0.0f;
+ re->wrld.range= 1.0f;
+
+ /* for mist pass */
+ re->wrld.miststa= re->clipsta;
+ re->wrld.mistdist= re->clipend-re->clipsta;
+ re->wrld.misi= 1.0f;
}
- /* not very elegant... but we want original displist in UI */
- if(cu->resolu_ren) {
- freedisplist(&cu->disp);
- SWAP(ListBase, olddl, cu->disp);
- }
+ re->wrld.linfac= 1.0 + pow((2.0*re->wrld.exp + 0.5), -10);
+ re->wrld.logfac= log( (re->wrld.linfac-1.0)/re->wrld.linfac )/re->wrld.range;
}
+
+
+/* ------------------------------------------------------------------------- */
+/* Object Finalization */
+/* ------------------------------------------------------------------------- */
+
/* prevent phong interpolation for giving ray shadow errors (terminator problem) */
-static void set_phong_threshold(Render *re, Object *ob, int startface, int numface, int startvert, int numvert )
+static void set_phong_threshold(ObjectRen *obr)
{
// VertRen *ver;
VlakRen *vlr;
@@ -2846,8 +3903,8 @@ static void set_phong_threshold(Render *re, Object *ob, int startface, int numfa
are taken into account. This threshold is meant to work on smooth geometry, not
for extreme cases (ton) */
- for(i=startface; i<startface+numface; i++) {
- vlr= RE_findOrAddVlak(re, i);
+ for(i=0; i<obr->totvlak; i++) {
+ vlr= RE_findOrAddVlak(obr, i);
if(vlr->flag & R_SMOOTH) {
dot= INPR(vlr->n, vlr->v1->n);
dot= ABS(dot);
@@ -2878,137 +3935,13 @@ static void set_phong_threshold(Render *re, Object *ob, int startface, int numfa
if(tot) {
thresh/= (float)tot;
- ob->smoothresh= cos(0.5*M_PI-saacos(thresh));
- }
-}
-
-/* par = pointer to duplicator parent, needed for object lookup table */
-/* index = when duplicater copies same object (particle), the counter */
-static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts)
-{
- static double lasttime= 0.0;
- double time;
- float mat[4][4];
- int startface, startvert;
-
- startface=re->totvlak;
- startvert=re->totvert;
-
- ob->flag |= OB_DONE;
-
- if(ob->type==OB_LAMP)
- add_render_lamp(re, ob);
- else if ELEM(ob->type, OB_FONT, OB_CURVE)
- init_render_curve(re, ob, only_verts);
- else if(ob->type==OB_SURF)
- init_render_surf(re, ob);
- else if(ob->type==OB_MESH)
- init_render_mesh(re, ob, par, only_verts);
- else if(ob->type==OB_MBALL)
- init_render_mball(re, ob);
- else {
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- }
-
- /* generic post process here */
- if(startvert!=re->totvert) {
-
- RE_addRenderObject(re, ob, par, index, startvert, re->totvert, startface, re->totvlak);
-
- /* the exception below is because displace code now is in init_render_mesh call,
- I will look at means to have autosmooth enabled for all object types
- and have it as general postprocess, like displace */
- if (ob->type!=OB_MESH && test_for_displace(re, ob ) )
- do_displacement(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert);
-
- /* phong normal interpolation can cause error in tracing (terminator prob) */
- ob->smoothresh= 0.0;
- if( (re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW) )
- set_phong_threshold(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert);
- }
-
- time= PIL_check_seconds_timer();
- if(time - lasttime > 1.0) {
- lasttime= time;
- /* clumsy copying still */
- re->i.totvert= re->totvert;
- re->i.totface= re->totvlak;
- re->i.tothalo= re->tothalo;
- re->i.totlamp= re->totlamp;
- re->stats_draw(&re->i);
- }
-}
-
-void RE_Database_Free(Render *re)
-{
- Object *ob = NULL;
- LampRen *lar;
-
- /* FREE */
-
- for(lar= re->lampren.first; lar; lar= lar->next) {
- freeshadowbuf(lar);
- if(lar->jitter) MEM_freeN(lar->jitter);
- if(lar->shadsamp) MEM_freeN(lar->shadsamp);
- }
-
- BLI_freelistN(&re->lampren);
- BLI_freelistN(&re->lights);
-
- free_renderdata_tables(re);
-
- /* free orco. check all objects because of duplis and sets */
- ob= G.main->object.first;
- while(ob) {
- if(ob->type==OB_MBALL) {
- if(ob->disp.first && ob->disp.first!=ob->disp.last) {
- DispList *dl= ob->disp.first;
- BLI_remlink(&ob->disp, dl);
- freedisplist(&ob->disp);
- BLI_addtail(&ob->disp, dl);
- }
- }
- ob= ob->id.next;
- }
-
- free_mesh_orco_hash(re);
-
- end_radio_render();
- end_render_materials();
-
- if(re->wrld.aosphere) {
- MEM_freeN(re->wrld.aosphere);
- re->wrld.aosphere= NULL;
- re->scene->world->aosphere= NULL;
- }
- if(re->wrld.aotables) {
- MEM_freeN(re->wrld.aotables);
- re->wrld.aotables= NULL;
- re->scene->world->aotables= NULL;
- }
-
- if(re->r.mode & R_RAYTRACE) freeoctree(re);
-
- free_sss(re);
-
- re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
- re->i.convertdone= 0;
-
- if(re->scene)
- if(re->scene->r.scemode & R_FREE_IMAGE)
- if((re->r.scemode & R_PREVIEWBUTS)==0)
- BKE_image_free_all_textures();
-
- if(re->memArena) {
- BLI_memarena_free(re->memArena);
- re->memArena = NULL;
+ obr->ob->smoothresh= cos(0.5*M_PI-saacos(thresh));
}
}
/* per face check if all samples should be taken.
- if raytrace, do always for raytraced material, or when material full_osa set */
-static void set_fullsample_flag(Render *re)
+ if raytrace or multisample, do always for raytraced material, or when material full_osa set */
+static void set_fullsample_flag(Render *re, ObjectRen *obr)
{
VlakRen *vlr;
int a, trace;
@@ -3018,27 +3951,31 @@ static void set_fullsample_flag(Render *re)
trace= re->r.mode & R_RAYTRACE;
- for(a=re->totvlak-1; a>=0; a--) {
- vlr= RE_findOrAddVlak(re, a);
+ for(a=obr->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(obr, a);
- if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA;
+ if(vlr->mat->mode & MA_FULL_OSA)
+ vlr->flag |= R_FULL_OSA;
else if(trace) {
if(vlr->mat->mode & MA_SHLESS);
- else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR|MA_SHADOW))
- vlr->flag |= R_FULL_OSA;
+ else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR))
+ /* for blurry reflect/refract, better to take more samples
+ * inside the raytrace than as OSA samples */
+ if ((vlr->mat->gloss_mir == 1.0) && (vlr->mat->gloss_tra == 1.0))
+ vlr->flag |= R_FULL_OSA;
}
}
}
-static void check_non_flat_quads(Render *re)
+static void check_non_flat_quads(ObjectRen *obr)
{
VlakRen *vlr, *vlr1;
VertRen *v1, *v2, *v3, *v4;
float nor[3], xn, flen;
int a;
- for(a=re->totvlak-1; a>=0; a--) {
- vlr= RE_findOrAddVlak(re, a);
+ for(a=obr->totvlak-1; a>=0; a--) {
+ vlr= RE_findOrAddVlak(obr, a);
/* test if rendering as a quad or triangle, skip wire */
if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) {
@@ -3094,7 +4031,7 @@ static void check_non_flat_quads(Render *re)
if(ABS(xn) < 0.999995 ) { // checked on noisy fractal grid
float d1, d2;
- vlr1= RE_vlakren_copy(re, vlr);
+ vlr1= RE_vlakren_copy(obr, vlr);
vlr1->flag |= R_FACE_SPLIT;
/* split direction based on vnorms */
@@ -3137,112 +4074,732 @@ static void check_non_flat_quads(Render *re)
}
}
-/* layflag: allows material group to ignore layerflag */
-static void add_lightgroup(Render *re, Group *group, int exclusive)
+static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
{
- GroupObject *go, *gol;
-
- group->id.flag &= ~LIB_DOIT;
+ Object *ob= obr->ob;
+ VertRen *ver= NULL;
+ StrandRen *strand= NULL;
+ StrandBound *sbound= NULL;
+ float min[3], max[3], smin[3], smax[3];
+ int a, b;
- /* it's a bit too many loops in loops... but will survive */
- /* note that 'exclusive' will remove it from the global list */
- for(go= group->gobject.first; go; go= go->next) {
- go->lampren= NULL;
-
- if(go->ob->lay & re->scene->lay) {
- if(go->ob && go->ob->type==OB_LAMP) {
- for(gol= re->lights.first; gol; gol= gol->next) {
- if(gol->ob==go->ob) {
- go->lampren= gol->lampren;
- break;
+ if(obr->totvert || obr->totvlak || obr->tothalo || obr->totstrand) {
+ /* the exception below is because displace code now is in init_render_mesh call,
+ I will look at means to have autosmooth enabled for all object types
+ and have it as general postprocess, like displace */
+ if(ob->type!=OB_MESH && test_for_displace(re, ob))
+ do_displacement(re, obr, NULL, NULL);
+
+ if(!timeoffset) {
+ /* phong normal interpolation can cause error in tracing
+ * (terminator problem) */
+ ob->smoothresh= 0.0;
+ if((re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW))
+ set_phong_threshold(obr);
+
+ check_non_flat_quads(obr);
+ set_fullsample_flag(re, obr);
+
+ /* compute bounding boxes for clipping */
+ INIT_MINMAX(min, max);
+ for(a=0; a<obr->totvert; a++) {
+ if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ DO_MINMAX(ver->co, min, max);
+ }
+
+ if(obr->strandbuf) {
+ sbound= obr->strandbuf->bound;
+ for(b=0; b<obr->strandbuf->totbound; b++, sbound++) {
+ INIT_MINMAX(smin, smax);
+
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ strand_minmax(strand, smin, smax);
}
- }
- if(go->lampren==NULL)
- gol= add_render_lamp(re, go->ob);
- if(gol && exclusive) {
- BLI_remlink(&re->lights, gol);
- MEM_freeN(gol);
+
+ VECCOPY(sbound->boundbox[0], smin);
+ VECCOPY(sbound->boundbox[1], smax);
+
+ DO_MINMAX(smin, min, max);
+ DO_MINMAX(smax, min, max);
}
}
+
+ VECCOPY(obr->boundbox[0], min);
+ VECCOPY(obr->boundbox[1], max);
}
}
}
-static void set_material_lightgroups(Render *re)
+/* ------------------------------------------------------------------------- */
+/* Database */
+/* ------------------------------------------------------------------------- */
+
+static int render_object_type(int type)
{
- Group *group;
- Material *ma;
+ return ELEM5(type, OB_FONT, OB_CURVE, OB_SURF, OB_MESH, OB_MBALL);
+}
+
+static void find_dupli_instances(Render *re, ObjectRen *obr)
+{
+ ObjectInstanceRen *obi;
+ float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
+ int first = 1;
+
+ Mat4MulMat4(obmat, obr->obmat, re->viewmat);
+ Mat4Invert(imat, obmat);
+
+ /* for objects instanced by dupliverts/faces/particles, we go over the
+ * list of instances to find ones that instance obr, and setup their
+ * matrices and obr pointer */
+ for(obi=re->instancetable.last; obi; obi=obi->prev) {
+ if(!obi->obr && obi->ob == obr->ob && obi->psysindex == obr->psysindex) {
+ obi->obr= obr;
+
+ /* compute difference between object matrix and
+ * object matrix with dupli transform, in viewspace */
+ Mat4CpyMat4(obimat, obi->mat);
+ Mat4MulMat4(obi->mat, imat, obimat);
+
+ Mat3CpyMat4(nmat, obi->mat);
+ Mat3Inv(obi->nmat, nmat);
+ Mat3Transp(obi->nmat);
+
+ if(!first) {
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+ }
+ else
+ first= 0;
+ }
+ }
+}
+
+static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRen *obr)
+{
+ float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3];
+
+ Mat4MulMat4(obmat, obr->obmat, re->viewmat);
+ Mat4Invert(imat, obmat);
+
+ obi->obr= obr;
+
+ /* compute difference between object matrix and
+ * object matrix with dupli transform, in viewspace */
+ Mat4CpyMat4(obimat, obi->mat);
+ Mat4MulMat4(obi->mat, imat, obimat);
+
+ Mat3CpyMat4(nmat, obi->mat);
+ Mat3Inv(obi->nmat, nmat);
+ Mat3Transp(obi->nmat);
+
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+}
+
+static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex)
+{
+ ObjectRen *obr;
+
+ /* if the object is itself instanced, we don't want to create an instance
+ * for it */
+ if(ob->transflag & OB_RENDER_DUPLI)
+ return NULL;
+
+ /* try to find an object that was already created so we can reuse it
+ * and save memory */
+ for(obr=re->objecttable.first; obr; obr=obr->next)
+ if(obr->ob == ob && obr->psysindex == psysindex && (obr->flag & R_INSTANCEABLE))
+ return obr;
- /* not for preview render */
- if(re->scene->r.scemode & R_PREVIEWBUTS)
+ return NULL;
+}
+
+static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob)
+{
+ /* For duplis we need to have a matrix that transform the coordinate back
+ * to it's original position, without the dupli transforms. We also check
+ * the matrix is actually needed, to save memory on lots of dupliverts for
+ * example */
+ static Object *lastob= NULL;
+ static int needtexmat= 0;
+
+ /* init */
+ if(!re) {
+ lastob= NULL;
+ needtexmat= 0;
return;
+ }
+
+ /* check if we actually need it */
+ if(lastob != dob->ob) {
+ Material ***material;
+ short a, *totmaterial;
+
+ lastob= dob->ob;
+ needtexmat= 0;
+
+ totmaterial= give_totcolp(dob->ob);
+ material= give_matarar(dob->ob);
+
+ if(totmaterial && material)
+ for(a= 0; a<*totmaterial; a++)
+ if((*material)[a] && (*material)[a]->texco & TEXCO_OBJECT)
+ needtexmat= 1;
+ }
+
+ if(needtexmat) {
+ float imat[4][4];
+
+ obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4);
+ Mat4Invert(imat, dob->mat);
+ MTC_Mat4MulSerie(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv, 0, 0, 0, 0);
+ }
+}
+
+static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
+{
+ Object *ob= obr->ob;
+ ParticleSystem *psys;
+ int i;
+
+ if(obr->psysindex) {
+ if((!obr->prev || obr->prev->ob != ob) && ob->type==OB_MESH) {
+ /* the emitter mesh wasn't rendered so the modifier stack wasn't
+ * evaluated with render settings */
+ DerivedMesh *dm;
+ dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+ dm->release(dm);
+ }
+
+ for(psys=ob->particlesystem.first, i=0; i<obr->psysindex-1; i++)
+ psys= psys->next;
+
+ render_new_particle_system(re, obr, psys, timeoffset);
+ }
+ else {
+ if ELEM(ob->type, OB_FONT, OB_CURVE)
+ init_render_curve(re, obr, timeoffset);
+ else if(ob->type==OB_SURF)
+ init_render_surf(re, obr);
+ else if(ob->type==OB_MESH)
+ init_render_mesh(re, obr, timeoffset);
+ else if(ob->type==OB_MBALL)
+ init_render_mball(re, obr);
+ }
+
+ finalize_render_object(re, obr, timeoffset);
+
+ re->totvert += obr->totvert;
+ re->totvlak += obr->totvlak;
+ re->tothalo += obr->tothalo;
+ re->totstrand += obr->totstrand;
+}
+
+static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, int timeoffset, int vectorlay)
+{
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
+ ParticleSystem *psys;
+ int show_emitter, allow_render= 1, index, psysindex;
+
+ index= (dob)? dob->index: 0;
+
+ /* the emitter has to be processed first (render levels of modifiers) */
+ /* so here we only check if the emitter should be rendered */
+ if(ob->particlesystem.first) {
+ show_emitter= 0;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ show_emitter += psys->part->draw & PART_DRAW_EMITTER;
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
+ }
+
+ /* if no psys has "show emitter" selected don't render emitter */
+ if(show_emitter == 0)
+ allow_render= 0;
+ }
+
+ /* one render object for the data itself */
+ if(allow_render) {
+ obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
+ if((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
+ obr->flag |= R_INSTANCEABLE;
+ Mat4CpyMat4(obr->obmat, ob->obmat);
+ }
+ if(obr->lay & vectorlay)
+ obr->flag |= R_NEED_VECTORS;
+ init_render_object_data(re, obr, timeoffset);
+
+ /* only add instance for objects that have not been used for dupli */
+ if(!(ob->transflag & OB_RENDER_DUPLI)) {
+ obi= RE_addRenderInstance(re, obr, ob, par, index, 0, NULL, ob->lay);
+ if(dob) set_dupli_tex_mat(re, obi, dob);
+ }
+ else
+ find_dupli_instances(re, obr);
+ }
+
+ /* and one render object per particle system */
+ if(ob->particlesystem.first) {
+ psysindex= 1;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) {
+ obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay);
+ if((dob && !dob->animated) || (ob->transflag & OB_RENDER_DUPLI)) {
+ obr->flag |= R_INSTANCEABLE;
+ Mat4CpyMat4(obr->obmat, ob->obmat);
+ }
+ if(obr->lay & vectorlay)
+ obr->flag |= R_NEED_VECTORS;
+ init_render_object_data(re, obr, timeoffset);
+ psys_render_restore(ob, psys);
+
+ /* only add instance for objects that have not been used for dupli */
+ if(!(ob->transflag & OB_RENDER_DUPLI)) {
+ obi= RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL, ob->lay);
+ if(dob) set_dupli_tex_mat(re, obi, dob);
+ }
+ else
+ find_dupli_instances(re, obr);
+ }
+ }
+}
+
+/* par = pointer to duplicator parent, needed for object lookup table */
+/* index = when duplicater copies same object (particle), the counter */
+static void init_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, int timeoffset, int vectorlay)
+{
+ static double lasttime= 0.0;
+ double time;
+ float mat[4][4];
+
+ if(ob->type==OB_LAMP)
+ add_render_lamp(re, ob);
+ else if(render_object_type(ob->type))
+ add_render_object(re, ob, par, dob, timeoffset, vectorlay);
+ else {
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ }
- for(group= G.main->group.first; group; group=group->id.next)
- group->id.flag |= LIB_DOIT;
+ time= PIL_check_seconds_timer();
+ if(time - lasttime > 1.0) {
+ lasttime= time;
+ /* clumsy copying still */
+ re->i.totvert= re->totvert;
+ re->i.totface= re->totvlak;
+ re->i.totstrand= re->totstrand;
+ re->i.tothalo= re->tothalo;
+ re->i.totlamp= re->totlamp;
+ re->stats_draw(&re->i);
+ }
+
+ ob->flag |= OB_DONE;
+}
+
+void RE_Database_Free(Render *re)
+{
+ Object *ob = NULL;
+ LampRen *lar;
- /* it's a bit too many loops in loops... but will survive */
- /* hola! materials not in use...? */
- for(ma= G.main->mat.first; ma; ma=ma->id.next) {
- if(ma->group && (ma->group->id.flag & LIB_DOIT))
- add_lightgroup(re, ma->group, ma->mode & MA_GROUP_NOLAY);
+ /* statistics for debugging render memory usage */
+ if(G.f & G_DEBUG) {
+ if((re->r.scemode & R_PREVIEWBUTS)==0) {
+ BKE_image_print_memlist();
+ MEM_printmemlist_stats();
+ }
+ }
+
+ /* FREE */
+
+ for(lar= re->lampren.first; lar; lar= lar->next) {
+ freeshadowbuf(lar);
+ if(lar->jitter) MEM_freeN(lar->jitter);
+ if(lar->shadsamp) MEM_freeN(lar->shadsamp);
+ if(lar->qsa) free_lamp_qmcsampler(lar);
+ curvemapping_free(lar->curfalloff);
+ }
+
+ BLI_freelistN(&re->lampren);
+ BLI_freelistN(&re->lights);
+
+ free_renderdata_tables(re);
+
+ /* free orco. check all objects because of duplis and sets */
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->type==OB_MBALL) {
+ if(ob->disp.first && ob->disp.first!=ob->disp.last) {
+ DispList *dl= ob->disp.first;
+ BLI_remlink(&ob->disp, dl);
+ freedisplist(&ob->disp);
+ BLI_addtail(&ob->disp, dl);
+ }
+ }
+ ob= ob->id.next;
+ }
+
+ free_mesh_orco_hash(re);
+
+ end_radio_render();
+ end_render_materials();
+
+ if(re->wrld.aosphere) {
+ MEM_freeN(re->wrld.aosphere);
+ re->wrld.aosphere= NULL;
+ re->scene->world->aosphere= NULL;
+ }
+ if(re->wrld.aotables) {
+ MEM_freeN(re->wrld.aotables);
+ re->wrld.aotables= NULL;
+ re->scene->world->aotables= NULL;
+ }
+ if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC) &&
+ (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY) && (re->qsa))
+ free_render_qmcsampler(re);
+
+ if(re->r.mode & R_RAYTRACE) freeraytree(re);
+
+ free_sss(re);
+ free_occ(re);
+ free_strand_surface(re);
+
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->i.convertdone= 0;
+
+ if(re->scene)
+ if(re->scene->r.scemode & R_FREE_IMAGE)
+ if((re->r.scemode & R_PREVIEWBUTS)==0)
+ BKE_image_free_all_textures();
+
+ if(re->memArena) {
+ BLI_memarena_free(re->memArena);
+ re->memArena = NULL;
}
}
-static void set_renderlayer_lightgroups(Render *re, Scene *sce)
+static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object *actob)
{
- SceneRenderLayer *srl;
+ /* override not showing object when duplis are used with particles */
+ if(ob->transflag & OB_DUPLIPARTS){
+ int allow= 0;
+
+ if(ob->particlesystem.first) {
+ ParticleSystem *psys;
+ ParticleSettings *part;
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ part=psys->part;
+
+ if(part->draw & PART_DRAW_EMITTER)
+ allow= 1;
+ }
+ }
+
+ if(!allow)
+ return 0;
+ }
+ else if((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES))
+ return 0;
- for(srl= sce->r.layers.first; srl; srl= srl->next) {
- if(srl->light_override)
- add_lightgroup(re, srl->light_override, 0);
+ if(nolamps && (ob->type==OB_LAMP))
+ return 0;
+
+ if(onlyselected && (ob!=actob && !(ob->flag & SELECT)))
+ return 0;
+
+ return 1;
+}
+
+static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd)
+{
+ ParticleSystem *psys;
+ Material ***material;
+ short a, *totmaterial;
+
+ /* don't allow objects with halos */
+ totmaterial= give_totcolp(obd);
+ material= give_matarar(obd);
+
+ if(totmaterial && material) {
+ for(a= 0; a<*totmaterial; a++)
+ if((*material)[a] && (*material)[a]->mode & MA_HALO)
+ return 0;
}
+
+ for(psys=obd->particlesystem.first; psys; psys=psys->next)
+ if(!ELEM5(psys->part->draw_as, PART_DRAW_BB, PART_DRAW_LINE, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR))
+ return 0;
+
+ /* don't allow lamp, animated duplis, or radio render */
+ return (render_object_type(obd->type) &&
+ (!(dob->type == OB_DUPLIGROUP) || !dob->animated) &&
+ !(re->r.mode & R_RADIO));
}
-void init_render_world(Render *re)
+static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, int level, int enable)
{
- int a;
- char *cp;
+ /* ugly function, but we need to set particle systems to their render
+ * settings before calling object_duplilist, to get render level duplis */
+ Group *group;
+ GroupObject *go;
+ ParticleSystem *psys;
+ DerivedMesh *dm;
+
+ if(level >= MAX_DUPLI_RECUR)
+ return;
- if(re->scene && re->scene->world) {
- re->wrld= *(re->scene->world);
-
- cp= (char *)&re->wrld.fastcol;
-
- cp[0]= 255.0*re->wrld.horr;
- cp[1]= 255.0*re->wrld.horg;
- cp[2]= 255.0*re->wrld.horb;
- cp[3]= 1;
-
- VECCOPY(re->grvec, re->viewmat[2]);
- Normalize(re->grvec);
- Mat3CpyMat4(re->imat, re->viewinv);
-
- for(a=0; a<MAX_MTEX; a++)
- if(re->wrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX;
-
- /* AO samples should be OSA minimum */
- if(re->osa)
- while(re->wrld.aosamp*re->wrld.aosamp < re->osa)
- re->wrld.aosamp++;
- if(!(re->r.mode & R_RAYTRACE))
- re->wrld.mode &= ~WO_AMB_OCC;
+ if(ob->transflag & OB_DUPLIPARTS) {
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ if(ELEM(psys->part->draw_as, PART_DRAW_OB, PART_DRAW_GR)) {
+ if(enable)
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
+ else
+ psys_render_restore(ob, psys);
+ }
+ }
+
+ if(level == 0 && enable) {
+ /* this is to make sure we get render level duplis in groups:
+ * the derivedmesh must be created before init_render_mesh,
+ * since object_duplilist does dupliparticles before that */
+ dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
+ dm->release(dm);
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
+ }
}
- else {
- memset(&re->wrld, 0, sizeof(World));
- re->wrld.exp= 0.0;
- re->wrld.range= 1.0;
+
+ if(ob->dup_group==NULL) return;
+ group= ob->dup_group;
+
+ for(go= group->gobject.first; go; go= go->next)
+ dupli_render_particle_set(re, go->ob, timeoffset, level+1, enable);
+}
+
+static int get_vector_renderlayers(Scene *sce)
+{
+ SceneRenderLayer *srl;
+ int lay= 0;
+
+ for(srl= sce->r.layers.first; srl; srl= srl->next)
+ if(srl->passflag & SCE_PASS_VECTOR)
+ lay |= srl->lay;
+
+ return lay;
+}
+
+static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, int onlyselected, Object *actob, int timeoffset, int vectorlay, int level)
+{
+ GroupObject *go;
+ Object *ob;
+
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+
+ /* recursively go into dupligroups to find objects with OB_RENDER_DUPLI
+ * that were not created yet */
+ for(go= group->gobject.first; go; go= go->next) {
+ ob= go->ob;
+
+ if(ob->flag & OB_DONE) {
+ if(ob->transflag & OB_RENDER_DUPLI) {
+ if(allow_render_object(ob, nolamps, onlyselected, actob)) {
+ init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
+ ob->transflag &= ~OB_RENDER_DUPLI;
+
+ if(ob->dup_group)
+ add_group_render_dupli_obs(re, ob->dup_group, nolamps, onlyselected, actob, timeoffset, vectorlay, level+1);
+ }
+ }
+ }
}
-
- re->wrld.linfac= 1.0 + pow((2.0*re->wrld.exp + 0.5), -10);
- re->wrld.logfac= log( (re->wrld.linfac-1.0)/re->wrld.linfac )/re->wrld.range;
+}
+
+static void database_init_objects(Render *re, unsigned int renderlay, int nolamps, int onlyselected, Object *actob, int timeoffset)
+{
+ Base *base;
+ Object *ob;
+ Group *group;
+ ObjectInstanceRen *obi;
+ Scene *sce;
+ float mat[4][4];
+ int lay, vectorlay, redoimat= 0;
+
+ /* for duplis we need the Object texture mapping to work as if
+ * untransformed, set_dupli_tex_mat sets the matrix to allow that
+ * NULL is just for init */
+ set_dupli_tex_mat(NULL, NULL, NULL);
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+ /* imat objects has to be done here, since displace can have texture using Object map-input */
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ /* each object should only be rendered once */
+ ob->flag &= ~OB_DONE;
+ ob->transflag &= ~OB_RENDER_DUPLI;
+ }
+
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+
+ /* in the prev/next pass for making speed vectors, avoid creating
+ * objects that are not on a renderlayer with a vector pass, can
+ * save a lot of time in complex scenes */
+ vectorlay= get_vector_renderlayers(sce);
+ lay= (timeoffset)? renderlay & vectorlay: renderlay;
+
+ /* if the object has been restricted from rendering in the outliner, ignore it */
+ if(ob->restrictflag & OB_RESTRICT_RENDER) continue;
+
+ /* OB_DONE means the object itself got duplicated, so was already converted */
+ if(ob->flag & OB_DONE) {
+ /* OB_RENDER_DUPLI means instances for it were already created, now
+ * it still needs to create the ObjectRen containing the data */
+ if(ob->transflag & OB_RENDER_DUPLI) {
+ if(allow_render_object(ob, nolamps, onlyselected, actob)) {
+ init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
+ ob->transflag &= ~OB_RENDER_DUPLI;
+ }
+ }
+ }
+ else if((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
+ if((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
+ DupliObject *dob;
+ ListBase *lb;
+
+ redoimat= 1;
+
+ /* create list of duplis generated by this object, particle
+ * system need to have render settings set for dupli particles */
+ dupli_render_particle_set(re, ob, timeoffset, 0, 1);
+ lb= object_duplilist(sce, ob);
+ dupli_render_particle_set(re, ob, timeoffset, 0, 0);
+
+ for(dob= lb->first; dob; dob= dob->next) {
+ Object *obd= dob->ob;
+
+ Mat4CpyMat4(obd->obmat, dob->mat);
+
+ /* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
+ if(!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw)
+ continue;
+
+ if(obd->restrictflag & OB_RESTRICT_RENDER)
+ continue;
+
+ if(obd->type==OB_MBALL)
+ continue;
+
+ if(!allow_render_object(obd, nolamps, onlyselected, actob))
+ continue;
+
+ if(allow_render_dupli_instance(re, dob, obd)) {
+ ParticleSystem *psys;
+ ObjectRen *obr = NULL;
+ int psysindex;
+ float mat[4][4];
+
+ /* instances instead of the actual object are added in two cases, either
+ * this is a duplivert/face/particle, or it is a non-animated object in
+ * a dupligroup that has already been created before */
+ if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) {
+ Mat4MulMat4(mat, dob->mat, re->viewmat);
+ obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat, obd->lay);
+
+ /* fill in instance variables for texturing */
+ set_dupli_tex_mat(re, obi, dob);
+ if(dob->type != OB_DUPLIGROUP) {
+ VECCOPY(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+ else {
+ /* for the second case, setup instance to point to the already
+ * created object, and possibly setup instances if this object
+ * itself was duplicated. for the first case find_dupli_instances
+ * will be called later. */
+ assign_dupligroup_dupli(re, obi, obr);
+ if(obd->transflag & OB_RENDER_DUPLI)
+ find_dupli_instances(re, obr);
+ }
+ }
+ else
+ /* can't instance, just create the object */
+ init_render_object(re, obd, ob, dob, timeoffset, vectorlay);
+
+ /* same logic for particles, each particle system has it's own object, so
+ * need to go over them separately */
+ psysindex= 1;
+ for(psys=obd->particlesystem.first; psys; psys=psys->next) {
+ if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, ob, psysindex))) {
+ obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat, obd->lay);
+
+ set_dupli_tex_mat(re, obi, dob);
+ if(dob->type != OB_DUPLIGROUP) {
+ VECCOPY(obi->dupliorco, dob->orco);
+ obi->dupliuv[0]= dob->uv[0];
+ obi->dupliuv[1]= dob->uv[1];
+ }
+ else {
+ assign_dupligroup_dupli(re, obi, obr);
+ if(obd->transflag & OB_RENDER_DUPLI)
+ find_dupli_instances(re, obr);
+ }
+ }
+ }
+
+ if(dob->type != OB_DUPLIGROUP) {
+ obd->flag |= OB_DONE;
+ obd->transflag |= OB_RENDER_DUPLI;
+ }
+ }
+ else
+ init_render_object(re, obd, ob, dob, timeoffset, vectorlay);
+
+ if(re->test_break()) break;
+ }
+ free_object_duplilist(lb);
+
+ if(allow_render_object(ob, nolamps, onlyselected, actob))
+ init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
+ }
+ else if(allow_render_object(ob, nolamps, onlyselected, actob))
+ init_render_object(re, ob, NULL, 0, timeoffset, vectorlay);
+ }
+
+ if(re->test_break()) break;
+ }
+
+ /* objects in groups with OB_RENDER_DUPLI set still need to be created,
+ * since they may not be part of the scene */
+ for(group= G.main->group.first; group; group=group->id.next)
+ add_group_render_dupli_obs(re, group, nolamps, onlyselected, actob, timeoffset, renderlay, 0);
+
+ /* imat objects has to be done again, since groups can mess it up */
+ if(redoimat) {
+ for(SETLOOPER(re->scene, base)) {
+ ob= base->object;
+ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
+ MTC_Mat4Invert(ob->imat, mat);
+ }
+ }
+
+ if(!re->test_break())
+ RE_makeRenderInstances(re);
}
/* used to be 'rotate scene' */
void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
{
extern int slurph_opt; /* key.c */
- Base *base;
- Object *ob;
Scene *sce;
float mat[4][4];
unsigned int lay;
@@ -3255,7 +4812,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* XXX add test if dbase was filled already? */
re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
- re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->lights.first= re->lights.last= NULL;
re->lampren.first= re->lampren.last= NULL;
@@ -3278,156 +4835,24 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
}
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
- if(re->wrld.mode & WO_AMB_OCC)
- init_ao_sphere(&re->wrld);
+ if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
+ if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
+ init_render_hammersley(re);
+ else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ init_ao_sphere(&re->wrld);
+ }
/* still bad... doing all */
init_render_textures(re);
init_render_materials(re->r.mode, &re->wrld.ambr);
set_node_shader_lamp_loop(shade_material_loop);
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
- /* imat objects has to be done here, since displace can have texture using Object map-input */
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- /* each object should only be rendered once */
- ob->flag &= ~OB_DONE;
- }
-
/* MAKE RENDER DATA */
-
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
-
- /* if the object has been restricted from rendering in the outliner, ignore it */
- if (ob->restrictflag & OB_RESTRICT_RENDER) continue;
-
- /* OB_DONE means the object itself got duplicated, so was already converted */
- if (ob->flag & OB_DONE) {
-#ifndef DISABLE_YAFRAY
- /* yafray: for some reason this part was removed, but yafray really needs it...
- Dupliverts objects are treated as instances of an original 'sourceobject',
- which needs to be included in the renderlist here.
- exception: lamps, lattices, armatures & camera's */
- if ((re->r.renderer==R_YAFRAY) && ((ob->type!=OB_LATTICE) && (ob->type!=OB_ARMATURE) &&
- (ob->type!=OB_LAMP) && (ob->type!=OB_CAMERA)))
- {
- printf("Duplivert object %s, adding to renderlist\n", ob->id.name);
- ob->flag &= ~OB_DONE;
- init_render_object(re, ob, NULL, 0, 0);
- ob->flag |= OB_DONE;
- }
-#endif /* disable yafray */
- }
- else if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
- if(ob->transflag & OB_DUPLI) {
-
- /* exception: mballs! */
-#ifndef DISABLE_YAFRAY
- /* yafray: except for mballs, include at least one copy of a dupliframe object in the renderlist. */
- if (re->r.renderer==R_YAFRAY) {
- if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) {
- printf("Dupliframe Object %s, adding to renderlist\n", ob->id.name);
- init_render_object(re, ob, NULL, 0, 0);
- }
- }
-#endif /* disable yafray */
- /* before make duplis, update particle for current frame */
- if(ob->transflag & OB_DUPLIVERTS) {
- PartEff *paf= give_parteff(ob);
- if(paf) {
- if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
- }
- }
-
- if(ob->type==OB_MBALL) {
- init_render_object(re, ob, NULL, 0, 0);
- }
- else {
- DupliObject *dob;
- ListBase *lb= object_duplilist(sce, ob);
-
- for(dob= lb->first; dob; dob= dob->next) {
- Object *obd= dob->ob;
-
- if (obd->restrictflag & OB_RESTRICT_RENDER) continue;
-
- Mat4CpyMat4(obd->obmat, dob->mat);
-
- /* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
- if(dob->no_draw)
- continue;
-
- if(obd->type!=OB_MBALL) {
-#ifndef DISABLE_YAFRAY
- /* yafray: special case handling of duplivert/dupligroup objects.
- Only one copy included in renderlist(see above), all others treated as instance of that.
- So only need to store name and matrix. Exception are lamps. lattices, armatures and camera's */
- if (re->r.renderer==R_YAFRAY) {
- /* dupligroup obs are included directly */
- if (obd->flag & OB_FROMGROUP) {
- printf("Dupligroup object %s, adding to renderlist\n", obd->id.name);
- init_render_object(re, obd, ob, dob->index, 0);
- }
- else if ((obd->type!=OB_LATTICE) && (obd->type!=OB_ARMATURE) &&
- (obd->type!=OB_LAMP) && (obd->type!=OB_CAMERA))
- {
- printf("Adding dupli matrix for object %s\n", obd->id.name);
- YAF_addDupliMtx(obd);
- }
- else init_render_object(re, obd, ob, dob->index, 0);
- }
- else init_render_object(re, obd, ob, dob->index, 0);
-#else
- init_render_object(re, obd, ob, dob->index, 0);
-#endif /* disable yafray */
- }
-
- if(re->test_break()) break;
- }
- free_object_duplilist(lb);
- }
- }
- else {
-#ifndef DISABLE_YAFRAY
- /* yafray: linked data objects treated similarly to dupliverts,
- If object not known yet (not in renderlist), include in the renderlist,
- otherwise treat as instance of it, so only name and matrix are stored
- Exception: objects which have materials linked to object instead of mesh */
- if ((re->r.renderer==R_YAFRAY) && (ob->colbits==0))
- {
- /* Special case, parent object dupli's: ignore if object itself is lamp or parent is lattice or empty */
- if (ob->parent) {
- if ((ob->type!=OB_LAMP) && (ob->parent->type!=OB_EMPTY) &&
- (ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob))
- printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name);
- else
- init_render_object(re, ob, NULL, 0, 0);
- }
- else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) &&
- (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob))
- printf("Added dupli matrix for linked data object %s\n", ob->id.name);
- else
- init_render_object(re, ob, NULL, 0, 0);
- }
- else init_render_object(re, ob, NULL, 0, 0);
-#else
- init_render_object(re, ob, NULL, 0, 0);
-#endif /* disable yafray */
- }
-
- }
-
- if(re->test_break()) break;
- }
+ database_init_objects(re, lay, 0, 0, 0, 0);
-
if(!re->test_break()) {
- LampRen *lar;
-
- sort_halos(re);
-
+ int tothalo;
+
set_material_lightgroups(re);
for(sce= re->scene; sce; sce= sce->set)
set_renderlayer_lightgroups(re, sce);
@@ -3437,41 +4862,35 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
/* for now some clumsy copying still */
re->i.totvert= re->totvert;
re->i.totface= re->totvlak;
+ re->i.totstrand= re->totstrand;
re->i.tothalo= re->tothalo;
re->i.totlamp= re->totlamp;
re->stats_draw(&re->i);
- set_fullsample_flag(re);
- check_non_flat_quads(re);
- set_normalflags(re);
-
+ /* don't sort stars */
+ tothalo= re->tothalo;
if(!re->test_break())
- if(re->wrld.mode & WO_STARS)
+ if(re->wrld.mode & WO_STARS)
RE_make_stars(re, NULL, NULL, NULL);
+ sort_halos(re, tothalo);
re->i.infostr= "Creating Shadowbuffers";
re->stats_draw(&re->i);
/* SHADOW BUFFER */
- for(lar=re->lampren.first; lar; lar= lar->next) {
- if(re->test_break()) break;
- if(lar->shb) {
- /* if type is irregular, this only sets the perspective matrix and autoclips */
- makeshadowbuf(re, lar);
- }
- }
+ threaded_makeshadowbufs(re);
- /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */
+ /* yafray: 'direct' radiosity, environment maps and raytree init not needed for yafray render */
/* although radio mode could be useful at some point, later */
if (re->r.renderer==R_INTERN) {
/* RADIO (uses no R anymore) */
if(!re->test_break())
if(re->r.mode & R_RADIO) do_radio_render(re);
- /* octree */
+ /* raytree */
if(!re->test_break()) {
if(re->r.mode & R_RAYTRACE) {
- makeoctree(re);
+ makeraytree(re);
}
}
/* ENVIRONMENT MAPS */
@@ -3480,11 +4899,18 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
}
if(!re->test_break())
- project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0);
+ project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
+
+ /* Occlusion */
+ if((re->wrld.mode & WO_AMB_OCC) && !re->test_break())
+ if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
+ if(re->r.renderer==R_INTERN)
+ if(re->r.mode & R_SHADOW)
+ make_occ_tree(re);
/* SSS */
if((re->r.mode & R_SSS) && !re->test_break())
- if (re->r.renderer==R_INTERN)
+ if(re->r.renderer==R_INTERN)
make_sss_tree(re);
}
@@ -3497,12 +4923,24 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
re->stats_draw(&re->i);
}
+/* exported call to recalculate hoco for vertices, when winmat changed */
+void RE_DataBase_ApplyWindow(Render *re)
+{
+ project_renderdata(re, projectverto, 0, 0, 0);
+}
+
+void RE_DataBase_GetView(Render *re, float mat[][4])
+{
+ Mat4CpyMat4(mat, re->viewmat);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Speed Vectors */
+/* ------------------------------------------------------------------------- */
+
static void database_fromscene_vectors(Render *re, Scene *scene, int timeoffset)
{
extern int slurph_opt; /* key.c */
- Base *base;
- Object *ob;
- Scene *sce;
float mat[4][4];
unsigned int lay;
@@ -3511,8 +4949,8 @@ static void database_fromscene_vectors(Render *re, Scene *scene, int timeoffset)
/* XXX add test if dbase was filled already? */
re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
- re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
- re->i.totface=re->i.totvert=re->i.totlamp=re->i.tothalo= 0;
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
+ re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0;
re->lights.first= re->lights.last= NULL;
slurph_opt= 0;
@@ -3532,73 +4970,18 @@ static void database_fromscene_vectors(Render *re, Scene *scene, int timeoffset)
RE_SetView(re, mat);
}
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
- /* imat objects has to be done here, since displace can have texture using Object map-input */
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- /* each object should only be rendered once */
- ob->flag &= ~OB_DONE;
- }
-
/* MAKE RENDER DATA */
-
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
-
- if (ob->restrictflag & OB_RESTRICT_RENDER) continue;
-
- /* OB_DONE means the object itself got duplicated, so was already converted */
- if(ob->flag & OB_DONE);
- else if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
- if(ob->transflag & OB_DUPLI) {
-
- /* before make duplis, update particle for current frame */
- if(ob->transflag & OB_DUPLIVERTS) {
- PartEff *paf= give_parteff(ob);
- if(paf) {
- if(paf->flag & PAF_ANIMATED) build_particle_system(ob);
- }
- }
-
- if(ob->type==OB_MBALL) {
- init_render_object(re, ob, NULL, 0, 1);
- }
- else {
- DupliObject *dob;
- ListBase *lb= object_duplilist(sce, ob);
-
- for(dob= lb->first; dob; dob= dob->next) {
- Object *obd= dob->ob;
-
- if (obd->restrictflag & OB_RESTRICT_RENDER) continue;
-
- Mat4CpyMat4(obd->obmat, dob->mat);
-
- if(obd->type!=OB_MBALL) {
- init_render_object(re, obd, ob, dob->index, 1);
- }
- }
- free_object_duplilist(lb);
- }
- }
- else {
- init_render_object(re, ob, NULL, 0, 1);
- }
-
- }
- if(re->test_break()) break;
- }
+ database_init_objects(re, lay, 0, 0, 0, timeoffset);
if(!re->test_break())
- project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0);
+ project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
/* do this in end, particles for example need cfra */
G.scene->r.cfra-=timeoffset;
}
/* choose to use static, to prevent giving too many args to this call */
-static void speedvector_project(Render *re, float *zco, VertRen *ver)
+static void speedvector_project(Render *re, float *zco, float *co, float *ho)
{
static float pixelphix=0.0f, pixelphiy=0.0f, zmulx=0.0f, zmuly=0.0f;
static int pano= 0;
@@ -3626,14 +5009,14 @@ static void speedvector_project(Render *re, float *zco, VertRen *ver)
}
/* now map hocos to screenspace, uses very primitive clip still */
- if(ver->ho[3]<0.1f) div= 10.0f;
- else div= 1.0f/ver->ho[3];
+ if(ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ho[3];
/* use cylinder projection */
if(pano) {
float vec[3], ang;
- /* angle between (0,0,-1) and (ver->co) */
- VECCOPY(vec, ver->co);
+ /* angle between (0,0,-1) and (co) */
+ VECCOPY(vec, co);
ang= saacos(-vec[2]/sqrt(vec[0]*vec[0] + vec[2]*vec[2]));
if(vec[0]<0.0f) ang= -ang;
@@ -3644,72 +5027,256 @@ static void speedvector_project(Render *re, float *zco, VertRen *ver)
}
else {
- zco[0]= zmulx*(1.0f+ver->ho[0]*div);
- zco[1]= zmuly*(1.0f+ver->ho[1]*div);
+ zco[0]= zmulx*(1.0f+ho[0]*div);
+ zco[1]= zmuly*(1.0f+ho[1]*div);
+ }
+}
+
+static void calculate_speedvector(float *vectors, int step, float winsq, float winroot, float *co, float *ho, float *speed)
+{
+ float zco[2], len;
+
+ speedvector_project(NULL, zco, co, ho);
+
+ zco[0]= vectors[0] - zco[0];
+ zco[1]= vectors[1] - zco[1];
+
+ /* enable nice masks for hardly moving stuff or float inaccuracy */
+ if(zco[0]<0.1f && zco[0]>-0.1f && zco[1]<0.1f && zco[1]>-0.1f ) {
+ zco[0]= 0.0f;
+ zco[1]= 0.0f;
+ }
+
+ /* maximize speed for image width, otherwise it never looks good */
+ len= zco[0]*zco[0] + zco[1]*zco[1];
+ if(len > winsq) {
+ len= winroot/sqrt(len);
+ zco[0]*= len;
+ zco[1]*= len;
+ }
+
+ /* note; in main vecblur loop speedvec is negated again */
+ if(step) {
+ speed[2]= -zco[0];
+ speed[3]= -zco[1];
+ }
+ else {
+ speed[0]= zco[0];
+ speed[1]= zco[1];
}
}
-static void calculate_speedvectors(Render *re, float *vectors, int startvert, int endvert, int step)
+static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen *obi, StrandSurface *mesh)
{
+ float winsq= re->winx*re->winy, winroot= sqrt(winsq), (*winspeed)[4];
+ float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
+ int a;
+
+ if(mesh->co && mesh->prevco && mesh->nextco) {
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
+
+ winspeed= MEM_callocN(sizeof(float)*4*mesh->totvert, "StrandSurfWin");
+
+ for(a=0; a<mesh->totvert; a++) {
+ projectvert(mesh->co[a], winmat, ho);
+
+ projectvert(mesh->prevco[a], winmat, prevho);
+ speedvector_project(NULL, vec, mesh->prevco[a], prevho);
+ calculate_speedvector(vec, 0, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+
+ projectvert(mesh->nextco[a], winmat, nextho);
+ speedvector_project(NULL, vec, mesh->nextco[a], nextho);
+ calculate_speedvector(vec, 1, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+ }
+
+ return (float*)winspeed;
+ }
+
+ return NULL;
+}
+
+static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
+{
+ ObjectRen *obr= obi->obr;
VertRen *ver= NULL;
- float *speed, zco[2];
- float len;
+ StrandRen *strand= NULL;
+ StrandBuffer *strandbuf;
+ StrandSurface *mesh= NULL;
+ float *speed, (*winspeed)[4]=NULL, ho[4], winmat[4][4];
+ float *co1, *co2, *co3, *co4, w[4];
float winsq= re->winx*re->winy, winroot= sqrt(winsq);
- int a;
+ int a, *face, *index;
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
+
+ if(obr->vertnodes) {
+ for(a=0; a<obr->totvert; a++, vectors+=2) {
+ if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
+
+ speed= RE_vertren_get_winspeed(obi, ver, 1);
+ projectvert(ver->co, winmat, ho);
+ calculate_speedvector(vectors, step, winsq, winroot, ver->co, ho, speed);
+ }
+ }
+
+ if(obr->strandnodes) {
+ strandbuf= obr->strandbuf;
+ mesh= (strandbuf)? strandbuf->surface: NULL;
+
+ /* compute speed vectors at surface vertices */
+ if(mesh)
+ winspeed= (float(*)[4])calculate_strandsurface_speedvectors(re, obi, mesh);
+
+ if(winspeed) {
+ for(a=0; a<obr->totstrand; a++, vectors+=2) {
+ if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
+ else strand++;
+
+ index= RE_strandren_get_face(obr, strand, 0);
+ if(index && *index < mesh->totface) {
+ speed= RE_strandren_get_winspeed(obi, strand, 1);
+
+ /* interpolate speed vectors from strand surface */
+ face= mesh->face[*index];
+
+ co1= mesh->co[face[0]];
+ co2= mesh->co[face[1]];
+ co3= mesh->co[face[2]];
+ co4= (face[3])? mesh->co[face[3]]: NULL;
+
+ InterpWeightsQ3Dfl(co1, co2, co3, co4, strand->vert->co, w);
+
+ speed[0]= speed[1]= speed[2]= speed[3]= 0.0f;
+ QUATADDFAC(speed, speed, winspeed[face[0]], w[0]);
+ QUATADDFAC(speed, speed, winspeed[face[1]], w[1]);
+ QUATADDFAC(speed, speed, winspeed[face[2]], w[2]);
+ if(face[3])
+ QUATADDFAC(speed, speed, winspeed[face[3]], w[3]);
+ }
+ }
+
+ MEM_freeN(winspeed);
+ }
+ }
+}
+
+static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
+{
+ ObjectRen *obr= obi->obr;
+ Object *fsob= obr->ob;
+ VertRen *ver= NULL;
+ float *speed, div, zco[2], avgvel[4] = {0.0, 0.0, 0.0, 0.0};
+ float zmulx= re->winx/2, zmuly= re->winy/2, len;
+ float winsq= re->winx*re->winy, winroot= sqrt(winsq);
+ int a, j;
+ float hoco[4], ho[4], fsvec[4], camco[4];
+ float mat[4][4], winmat[4][4];
+ float imat[4][4];
+ MVert *vverts;
+
+ /* only one step needed */
+ if(step) return 1;
+ Mat4CpyMat4(mat, re->viewmat);
+ MTC_Mat4Invert(imat, mat);
+
/* set first vertex OK */
- a= startvert-1;
- ver= re->vertnodes[a>>8].vert + (a & 255);
+ if( (!fsob->fluidsimSettings) || (!fsob->fluidsimSettings->meshSurfNormals) ) return 0;
+ vverts = fsob->fluidsimSettings->meshSurfNormals;
+ //fprintf(stderr, "GZ_VEL obj '%s', calc load_fluidsimspeedvectors\n",fsob->id.name); // NT DEBUG
+
+ if( obr->totvert != fsob->fluidsimSettings->meshSurface->totvert ) {
+ //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", obr->totvert, fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
+ return 0;
+ }
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
- for(a=startvert; a<endvert; a++, vectors+=2) {
+ /* (bad) HACK calculate average velocity */
+ /* better solution would be fixing getVelocityAt() in intern/elbeem/intern/solver_util.cpp
+ so that also small drops/little water volumes return a velocity != 0.
+ But I had no luck in fixing that function - DG */
+ for(a=0; a<obr->totvert; a++) {
+ for(j=0;j<3;j++) avgvel[j] += vverts[a].co[j];
+ }
+ for(j=0;j<3;j++) avgvel[j] /= (float)(obr->totvert);
+
+
+ for(a=0; a<obr->totvert; a++, vectors+=2) {
if((a & 255)==0)
- ver= re->vertnodes[a>>8].vert;
+ ver= obr->vertnodes[a>>8].vert;
else
ver++;
+
+ // get fluid velocity
+ fsvec[3] = 0.;
+ //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
+ for(j=0;j<3;j++) fsvec[j] = vverts[a].co[j];
- speedvector_project(NULL, zco, ver);
+ /* (bad) HACK insert average velocity if none is there (see previous comment */
+ if((fsvec[0] == 0.0) && (fsvec[1] == 0.0) && (fsvec[2] == 0.0))
+ {
+ fsvec[0] = avgvel[0];
+ fsvec[1] = avgvel[1];
+ fsvec[2] = avgvel[2];
+ }
- zco[0]= vectors[0] - zco[0];
- zco[1]= vectors[1] - zco[1];
+ // transform (=rotate) to cam space
+ camco[0]= imat[0][0]*fsvec[0] + imat[0][1]*fsvec[1] + imat[0][2]*fsvec[2];
+ camco[1]= imat[1][0]*fsvec[0] + imat[1][1]*fsvec[1] + imat[1][2]*fsvec[2];
+ camco[2]= imat[2][0]*fsvec[0] + imat[2][1]*fsvec[1] + imat[2][2]*fsvec[2];
+
+ // get homogenous coordinates
+ projectvert(camco, winmat, hoco);
+ projectvert(ver->co, winmat, ho);
- /* enable nice masks for hardly moving stuff or float inaccuracy */
- if(zco[0]<0.1f && zco[0]>-0.1f && zco[1]<0.1f && zco[1]>-0.1f ) {
- zco[0]= 0.0f;
- zco[1]= 0.0f;
- }
+ /* now map hocos to screenspace, uses very primitive clip still */
+ // use ho[3] of original vertex, xy component of vel. direction
+ if(ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ho[3];
+ zco[0]= zmulx*hoco[0]*div;
+ zco[1]= zmuly*hoco[1]*div;
- /* maximize speed for image width, otherwise it never looks good */
+ // maximize speed as usual
len= zco[0]*zco[0] + zco[1]*zco[1];
if(len > winsq) {
len= winroot/sqrt(len);
- zco[0]*= len;
- zco[1]*= len;
+ zco[0]*= len; zco[1]*= len;
}
- speed= RE_vertren_get_winspeed(re, ver, 1);
- /* note; in main vecblur loop speedvec is negated again */
- if(step) {
- speed[2]= -zco[0];
- speed[3]= -zco[1];
- }
- else {
- speed[0]= zco[0];
- speed[1]= zco[1];
- }
+ speed= RE_vertren_get_winspeed(obi, ver, 1);
+ // set both to the same value
+ speed[0]= speed[2]= zco[0];
+ speed[1]= speed[3]= zco[1];
+ //if(a<20) fprintf(stderr,"speed %d %f,%f | camco %f,%f,%f | hoco %f,%f,%f,%f \n", a, speed[0], speed[1], camco[0],camco[1], camco[2], hoco[0],hoco[1], hoco[2],hoco[3]); // NT DEBUG
}
+
+ return 1;
}
-static int load_fluidsimspeedvectors(Render *re, float *vectors, int startvert, int endvert, int step, Object *fsob)
+static int load_clothsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
{
+ ObjectRen *obr= obi->obr;
VertRen *ver= NULL;
float *speed, div, zco[2];
float zmulx= re->winx/2, zmuly= re->winy/2, len;
float winsq= re->winx*re->winy, winroot= sqrt(winsq);
int a, j;
- float hoco[4], fsvec[4], camco[4];
- float mat[4][4];
+ float hoco[4], ho[4], csvec[4], camco[4];
+ float mat[4][4], winmat[4][4];
float imat[4][4];
- MVert *vverts;
+ ClothModifierData *clmd = NULL;
+ Cloth *cloth = NULL;
/* only one step needed */
if(step) return 1;
@@ -3718,41 +5285,43 @@ static int load_fluidsimspeedvectors(Render *re, float *vectors, int startvert,
MTC_Mat4Invert(imat, mat);
/* set first vertex OK */
- a= startvert-1;
- ver= re->vertnodes[a>>8].vert + (a & 255);
-
- if( (!fsob->fluidsimSettings) || (!fsob->fluidsimSettings->meshSurfNormals) ) return 0;
- vverts = fsob->fluidsimSettings->meshSurfNormals;
- //fprintf(stderr, "GZ_VEL obj '%s', calc load_fluidsimspeedvectors\n",fsob->id.name); // NT DEBUG
-
- if( endvert-startvert != fsob->fluidsimSettings->meshSurface->totvert ) {
- //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", endvert-startvert , fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
+ clmd = (ClothModifierData *)modifiers_findByType(obr->ob, eModifierType_Cloth);
+ if( !clmd || !(clmd->clothObject) ) return 0;
+
+ cloth = clmd->clothObject;
+
+ if( obr->totvert != cloth->numverts ) {
return 0;
}
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
- for(a=startvert; a<endvert; a++, vectors+=2) {
+ for(a=0; a<obr->totvert; a++, vectors+=2) {
if((a & 255)==0)
- ver= re->vertnodes[a>>8].vert;
+ ver= obr->vertnodes[a>>8].vert;
else
ver++;
- // get fluid velocity
- fsvec[3] = 0.;
- //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
- for(j=0;j<3;j++) fsvec[j] = vverts[a-startvert].co[j];
+ // get cloth velocity
+ csvec[3] = 0.;
+ for(j=0;j<3;j++) csvec[j] = cloth->verts[a].v[j];
// transform (=rotate) to cam space
- camco[0]= imat[0][0]*fsvec[0] + imat[0][1]*fsvec[1] + imat[0][2]*fsvec[2];
- camco[1]= imat[1][0]*fsvec[0] + imat[1][1]*fsvec[1] + imat[1][2]*fsvec[2];
- camco[2]= imat[2][0]*fsvec[0] + imat[2][1]*fsvec[1] + imat[2][2]*fsvec[2];
+ camco[0]= imat[0][0]*csvec[0] + imat[0][1]*csvec[1] + imat[0][2]*csvec[2];
+ camco[1]= imat[1][0]*csvec[0] + imat[1][1]*csvec[1] + imat[1][2]*csvec[2];
+ camco[2]= imat[2][0]*csvec[0] + imat[2][1]*csvec[1] + imat[2][2]*csvec[2];
// get homogenous coordinates
- projectverto(camco, re->winmat, hoco);
+ projectvert(camco, winmat, hoco);
+ projectvert(ver->co, winmat, ho);
/* now map hocos to screenspace, uses very primitive clip still */
// use ho[3] of original vertex, xy component of vel. direction
- if(ver->ho[3]<0.1f) div= 10.0f;
- else div= 1.0f/ver->ho[3];
+ if(ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ho[3];
zco[0]= zmulx*hoco[0]*div;
zco[1]= zmuly*hoco[1]*div;
@@ -3763,11 +5332,10 @@ static int load_fluidsimspeedvectors(Render *re, float *vectors, int startvert,
zco[0]*= len; zco[1]*= len;
}
- speed= RE_vertren_get_winspeed(re, ver, 1);
+ speed= RE_vertren_get_winspeed(obi, ver, 1);
// set both to the same value
speed[0]= speed[2]= zco[0];
speed[1]= speed[3]= zco[1];
- //if(a<20) fprintf(stderr,"speed %d %f,%f | camco %f,%f,%f | hoco %f,%f,%f,%f \n", a, speed[0], speed[1], camco[0],camco[1], camco[2], hoco[0],hoco[1], hoco[2],hoco[3]); // NT DEBUG
}
return 1;
@@ -3777,28 +5345,35 @@ static int load_fluidsimspeedvectors(Render *re, float *vectors, int startvert,
/* result should be that we can free entire database */
static void copy_dbase_object_vectors(Render *re, ListBase *lb)
{
- ObjectRen *obren, *obrenlb;
- VertRen *ver;
- float *vec;
- int a;
-
- for(obren= re->objecttable.first; obren; obren= obren->next) {
- obrenlb= MEM_dupallocN(obren);
- BLI_addtail(lb, obrenlb);
- if(obren->endvert>obren->startvert) {
- vec= obrenlb->vectors= MEM_mallocN(2*sizeof(float)*(obren->endvert- obren->startvert), "vector array");
+ ObjectInstanceRen *obi, *obilb;
+ ObjectRen *obr;
+ VertRen *ver= NULL;
+ float *vec, ho[4], winmat[4][4];
+ int a, totvector;
- /* first vertex */
- a= obren->startvert-1;
- ver= re->vertnodes[a>>8].vert + (a & 255);
+ for(obi= re->instancetable.first; obi; obi= obi->next) {
+ obr= obi->obr;
- for(a=obren->startvert; a<obren->endvert; a++, vec+=2) {
- if((a & 255)==0)
- ver= re->vertnodes[a>>8].vert;
- else
- ver++;
+ obilb= MEM_mallocN(sizeof(ObjectInstanceRen), "ObInstanceVector");
+ memcpy(obilb, obi, sizeof(ObjectInstanceRen));
+ BLI_addtail(lb, obilb);
+
+ obilb->totvector= totvector= obr->totvert;
+
+ if(totvector > 0) {
+ vec= obilb->vectors= MEM_mallocN(2*sizeof(float)*totvector, "vector array");
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
+
+ for(a=0; a<obr->totvert; a++, vec+=2) {
+ if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+ else ver++;
- speedvector_project(NULL, vec, ver);
+ projectvert(ver->co, winmat, ho);
+ speedvector_project(NULL, vec, ver->co, ho);
}
}
}
@@ -3806,25 +5381,28 @@ static void copy_dbase_object_vectors(Render *re, ListBase *lb)
static void free_dbase_object_vectors(ListBase *lb)
{
- ObjectRen *obren;
+ ObjectInstanceRen *obi;
- for(obren= lb->first; obren; obren= obren->next)
- if(obren->vectors)
- MEM_freeN(obren->vectors);
+ for(obi= lb->first; obi; obi= obi->next)
+ if(obi->vectors)
+ MEM_freeN(obi->vectors);
BLI_freelistN(lb);
}
void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
{
- ObjectRen *obren, *oldobren;
+ ObjectInstanceRen *obi, *oldobi;
+ StrandSurface *mesh;
ListBase *table;
ListBase oldtable= {NULL, NULL}, newtable= {NULL, NULL};
+ ListBase strandsurface;
int step;
+ ModifierData *md = NULL;
re->i.infostr= "Calculating previous vectors";
re->r.mode |= R_SPEED;
- speedvector_project(re, NULL, NULL); /* initializes projection code */
+ speedvector_project(re, NULL, NULL, NULL); /* initializes projection code */
/* creates entire dbase */
database_fromscene_vectors(re, sce, -1);
@@ -3833,7 +5411,10 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
copy_dbase_object_vectors(re, &oldtable);
/* free dbase and make the future one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
RE_Database_Free(re);
+ re->strandsurface= strandsurface;
if(!re->test_break()) {
/* creates entire dbase */
@@ -3845,7 +5426,10 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
copy_dbase_object_vectors(re, &newtable);
/* free dbase and make the real one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
RE_Database_Free(re);
+ re->strandsurface= strandsurface;
if(!re->test_break())
RE_Database_FromScene(re, sce, 1);
@@ -3858,57 +5442,75 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
else
table= &oldtable;
- oldobren= table->first;
- for(obren= re->objecttable.first; obren && oldobren; obren= obren->next, oldobren= oldobren->next) {
+ oldobi= table->first;
+ for(obi= re->instancetable.first; obi && oldobi; obi= obi->next) {
int ok= 1;
+ if(!(obi->obr->flag & R_NEED_VECTORS))
+ continue;
+
+ obi->totvector= obi->obr->totvert;
+
/* find matching object in old table */
- if(oldobren->ob!=obren->ob || oldobren->par!=obren->par || oldobren->index!=obren->index) {
+ if(oldobi->ob!=obi->ob || oldobi->par!=obi->par || oldobi->index!=obi->index || oldobi->psysindex!=obi->psysindex) {
ok= 0;
- for(oldobren= table->first; oldobren; oldobren= oldobren->next)
- if(oldobren->ob==obren->ob && oldobren->par==obren->par && oldobren->index==obren->index)
+ for(oldobi= table->first; oldobi; oldobi= oldobi->next)
+ if(oldobi->ob==obi->ob && oldobi->par==obi->par && oldobi->index==obi->index && oldobi->psysindex==obi->psysindex)
break;
- if(oldobren==NULL)
- oldobren= table->first;
+ if(oldobi==NULL)
+ oldobi= table->first;
else
ok= 1;
}
if(ok==0) {
- printf("speed table: missing object %s\n", obren->ob->id.name+2);
+ printf("speed table: missing object %s\n", obi->ob->id.name+2);
continue;
}
// NT check for fluidsim special treatment
- if((obren->ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obren->ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)) {
+ if((obi->ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obi->ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)) {
// use preloaded per vertex simulation data , only does calculation for step=1
// NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls...
- load_fluidsimspeedvectors(re, oldobren->vectors, obren->startvert, obren->endvert, step, obren->ob);
- } else {
+ load_fluidsimspeedvectors(re, obi, oldobi->vectors, step);
+ }
+ else if((md = modifiers_findByType(obi->ob, eModifierType_Cloth)) && (md->mode & eModifierMode_Render) ) {
+ load_clothsimspeedvectors(re, obi, oldobi->vectors, step);
+ }
+ else {
/* check if both have same amounts of vertices */
- if(obren->endvert-obren->startvert != oldobren->endvert-oldobren->startvert) {
- printf("Warning: object %s has different amount of vertices on other frame\n", obren->ob->id.name+2);
- continue;
- }
-
- calculate_speedvectors(re, oldobren->vectors, obren->startvert, obren->endvert, step);
+ if(obi->totvector==oldobi->totvector)
+ calculate_speedvectors(re, obi, oldobi->vectors, step);
+ else
+ printf("Warning: object %s has different amount of vertices or strands on other frame\n", obi->ob->id.name+2);
} // not fluidsim
+
+ oldobi= oldobi->next;
}
}
}
free_dbase_object_vectors(&oldtable);
free_dbase_object_vectors(&newtable);
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if(mesh->prevco) {
+ MEM_freeN(mesh->prevco);
+ mesh->prevco= NULL;
+ }
+ if(mesh->nextco) {
+ MEM_freeN(mesh->nextco);
+ mesh->nextco= NULL;
+ }
+ }
re->i.infostr= NULL;
re->stats_draw(&re->i);
}
-/* exported call to recalculate hoco for vertices, when winmat changed */
-void RE_DataBase_ApplyWindow(Render *re)
-{
- project_renderdata(re, projectverto, 0, 0);
-}
+/* ------------------------------------------------------------------------- */
+/* Baking */
+/* ------------------------------------------------------------------------- */
/* setup for shaded view or bake, so only lamps and materials are initialized */
/* type:
@@ -3917,32 +5519,35 @@ void RE_DataBase_ApplyWindow(Render *re)
RE_BAKE_NORMALS:for baking, no lamps and only selected objects
RE_BAKE_AO: for baking, no lamps, but all objects
RE_BAKE_TEXTURE:for baking, no lamps, only selected objects
+ RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects
*/
-void RE_Database_Baking(Render *re, Scene *scene, int type)
+void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob)
{
- Base *base;
- Object *ob;
- Scene *sce;
float mat[4][4];
unsigned int lay;
+ int onlyselected, nolamps;
re->scene= scene;
/* renderdata setup and exceptions */
re->r= scene->r;
- re->r.mode &= ~R_OSA;
re->flag |= R_GLOB_NOPUNOFLIP;
+ re->excludeob= actob;
+ if(type == RE_BAKE_LIGHT)
+ re->flag |= R_SKIP_MULTIRES;
+
+ if(type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT)
+ re->flag |= R_NEED_TANGENT;
- if( ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE) ) {
+ if(!actob && ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT)) {
re->r.mode &= ~R_SHADOW;
re->r.mode &= ~R_RAYTRACE;
}
/* setup render stuff */
- if(type!=RE_BAKE_LIGHT)
- re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
- re->totvlak=re->totvert=re->totlamp=re->tothalo= 0;
+ re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->lights.first= re->lights.last= NULL;
re->lampren.first= re->lampren.last= NULL;
@@ -3962,112 +5567,46 @@ void RE_Database_Baking(Render *re, Scene *scene, int type)
}
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
- if(re->wrld.mode & WO_AMB_OCC)
- init_ao_sphere(&re->wrld);
+ if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
+ if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
+ init_render_hammersley(re);
+ else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ init_ao_sphere(&re->wrld);
+ }
/* still bad... doing all */
init_render_textures(re);
init_render_materials(re->r.mode, &re->wrld.ambr);
set_node_shader_lamp_loop(shade_material_loop);
-
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
- /* imat objects has to be done here, since displace can have texture using Object map-input */
- MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
- MTC_Mat4Invert(ob->imat, mat);
- /* each object should only be rendered once */
- ob->flag &= ~OB_DONE;
- }
/* MAKE RENDER DATA */
- for(SETLOOPER(re->scene, base)) {
- ob= base->object;
-
- /* if the object has been restricted from rendering in the outliner, ignore it */
- if (ob->restrictflag & OB_RESTRICT_RENDER) continue;
-
- /* OB_DONE means the object itself got duplicated, so was already converted */
- if(ob->flag & OB_DONE);
- else if( (base->lay & lay) || ((base->lay & re->scene->lay)) ) {
-
- /* check for dupli lamps or non selected groups */
- if(ob->transflag & OB_DUPLI) {
- DupliObject *dob;
- ListBase *lb= object_duplilist(sce, ob);
-
- for(dob= lb->first; dob; dob= dob->next) {
- Object *obd= dob->ob;
-
- if(obd->type==OB_LAMP) {
- if( ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL) ) {
- Mat4CpyMat4(obd->obmat, dob->mat);
- init_render_object(re, obd, ob, dob->index, 0);
- }
- }
- else if( ELEM(type, RE_BAKE_AO, RE_BAKE_ALL) ) {
- if((base->flag & SELECT)==0) {
- Mat4CpyMat4(obd->obmat, dob->mat);
- init_render_object(re, obd, ob, dob->index, 0);
- }
- }
- }
- free_object_duplilist(lb);
- }
- else {
- if(ob->type==OB_LAMP) {
- if( ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL) )
- init_render_object(re, ob, NULL, 0, 0);
- }
- else if(type!=RE_BAKE_LIGHT) {
- if( !ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE) || (ob->flag & SELECT))
- init_render_object(re, ob, NULL, 0, 0);
- }
- }
- }
- }
+ nolamps= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL);
+ onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT);
+
+ database_init_objects(re, lay, nolamps, onlyselected, actob, 0);
+
set_material_lightgroups(re);
- check_non_flat_quads(re);
- /* don't call set_normalflags(), no flipping */
-
- if(type!=RE_BAKE_LIGHT) {
- if(re->r.mode & R_SHADOW) {
- LampRen *lar;
-
- /* SHADOW BUFFER */
- for(lar=re->lampren.first; lar; lar= lar->next) {
-
- if(re->test_break()) break;
- if(lar->shb) {
- /* if type is irregular, this only sets the perspective matrix and autoclips */
- /* but, that's not supported for bake... */
- makeshadowbuf(re, lar);
- }
- }
- }
- }
-
- if(type!=RE_BAKE_LIGHT) {
- /* octree */
- if(!re->test_break()) {
- if(re->r.mode & R_RAYTRACE) {
- makeoctree(re);
- }
- }
- }
-}
+ /* SHADOW BUFFER */
+ if(type!=RE_BAKE_LIGHT)
+ if(re->r.mode & R_SHADOW)
+ threaded_makeshadowbufs(re);
-void RE_DataBase_GetView(Render *re, float mat[][4])
-{
- Mat4CpyMat4(mat, re->viewmat);
+ /* raytree */
+ if(!re->test_break())
+ if(re->r.mode & R_RAYTRACE)
+ makeraytree(re);
+
+ /* occlusion */
+ if((re->wrld.mode & WO_AMB_OCC) && !re->test_break())
+ if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
+ if(re->r.mode & R_SHADOW)
+ make_occ_tree(re);
}
-
-
-
-/* **************************************************************** */
-/* sticky texture coords */
-/* **************************************************************** */
+/* ------------------------------------------------------------------------- */
+/* Sticky texture coords */
+/* ------------------------------------------------------------------------- */
void RE_make_sticky(void)
{
@@ -4095,7 +5634,7 @@ void RE_make_sticky(void)
}
re= RE_NewRender("_make sticky_");
- RE_InitState(re, &G.scene->r, G.scene->r.xsch, G.scene->r.ysch, NULL);
+ RE_InitState(re, NULL, &G.scene->r, G.scene->r.xsch, G.scene->r.ysch, NULL);
/* use renderdata and camera to set viewplane */
RE_SetCamera(re, G.scene->camera);
@@ -4133,172 +5672,3 @@ void RE_make_sticky(void)
}
}
-
-
-/* **************************************************************** */
-/* Displacement mapping */
-/* **************************************************************** */
-static short test_for_displace(Render *re, Object *ob)
-{
- /* return 1 when this object uses displacement textures. */
- Material *ma;
- int i;
-
- for (i=1; i<=ob->totcol; i++) {
- ma=give_render_material(re, ob, i);
- /* ma->mapto is ORed total of all mapto channels */
- if(ma && (ma->mapto & MAP_DISPLACE)) return 1;
- }
- return 0;
-}
-
-static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, int vindex, float *scale)
-{
- MTFace *tface;
- short texco= shi->mat->texco;
- float sample=0;
- char *name;
- int i;
-
- /* shi->co is current render coord, just make sure at least some vector is here */
- VECCOPY(shi->co, vr->co);
- /* vertex normal is used for textures type 'col' and 'var' */
- VECCOPY(shi->vn, vr->n);
-
- if (texco & TEXCO_UV) {
- shi->totuv= 0;
-
- for (i=0; (tface=RE_vlakren_get_tface(re, shi->vlr, i, &name, 0)); i++) {
- ShadeInputUV *suv= &shi->uv[i];
-
- /* shi.uv needs scale correction from tface uv */
- suv->uv[0]= 2*tface->uv[vindex][0]-1.0f;
- suv->uv[1]= 2*tface->uv[vindex][1]-1.0f;
- suv->uv[2]= 0.0f;
- suv->name= name;
- shi->totuv++;
- }
- }
-
- /* set all rendercoords, 'texco' is an ORed value for all textures needed */
- if ((texco & TEXCO_ORCO) && (vr->orco)) {
- VECCOPY(shi->lo, vr->orco);
- }
- if (texco & TEXCO_STICKY) {
- float *sticky= RE_vertren_get_sticky(re, vr, 0);
- if(sticky) {
- shi->sticky[0]= sticky[0];
- shi->sticky[1]= sticky[1];
- shi->sticky[2]= 0.0f;
- }
- }
- if (texco & TEXCO_GLOB) {
- VECCOPY(shi->gl, shi->co);
- MTC_Mat4MulVecfl(re->viewinv, shi->gl);
- }
- if (texco & TEXCO_NORM) {
- VECCOPY(shi->orn, shi->vn);
- }
- if(texco & TEXCO_REFL) {
- /* not (yet?) */
- }
-
- shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
-
- do_material_tex(shi);
-
- //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2],
- //vr->co[0], vr->co[1], vr->co[2]);
-
- /* 0.5 could become button once? */
- vr->co[0] += shi->displace[0] * scale[0] ;
- vr->co[1] += shi->displace[1] * scale[1] ;
- vr->co[2] += shi->displace[2] * scale[2] ;
-
- //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]);
-
- /* we just don't do this vertex again, bad luck for other face using same vertex with
- different material... */
- vr->flag |= 1;
-
- /* Pass sample back so displace_face can decide which way to split the quad */
- sample = shi->displace[0]*shi->displace[0];
- sample += shi->displace[1]*shi->displace[1];
- sample += shi->displace[2]*shi->displace[2];
-
- vr->accum=sample;
- /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */
- return;
-}
-
-static void displace_render_face(Render *re, VlakRen *vlr, float *scale)
-{
- ShadeInput shi;
-
- /* set up shadeinput struct for multitex() */
- shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */
- shi.vlr= vlr; /* current render face */
- shi.mat= vlr->mat; /* current input material */
-
- /* Displace the verts, flag is set when done */
- if (!vlr->v1->flag)
- displace_render_vert(re, &shi, vlr->v1,0, scale);
-
- if (!vlr->v2->flag)
- displace_render_vert(re, &shi, vlr->v2, 1, scale);
-
- if (!vlr->v3->flag)
- displace_render_vert(re, &shi, vlr->v3, 2, scale);
-
- if (vlr->v4) {
- if (!vlr->v4->flag)
- displace_render_vert(re, &shi, vlr->v4, 3, scale);
-
- /* closest in displace value. This will help smooth edges. */
- if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
- vlr->flag |= R_DIVIDE_24;
- else vlr->flag &= ~R_DIVIDE_24; // E: typo?, was missing '='
- }
-
- /* Recalculate the face normal - if flipped before, flip now */
- if(vlr->v4) {
- CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
- }
- else {
- CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n);
- }
-}
-
-
-static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert )
-{
- VertRen *vr;
- VlakRen *vlr;
-// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30};
- float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn
- int i; //, texflag=0;
- Object *obt;
-
- /* Object Size with parenting */
- obt=ob;
- while(obt){
- VecAddf(temp, obt->size, obt->dsize);
- scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2];
- obt=obt->parent;
- }
-
- /* Clear all flags */
- for(i=startvert; i<startvert+numvert; i++){
- vr= RE_findOrAddVert(re, i);
- vr->flag= 0;
- }
-
- for(i=startface; i<startface+numface; i++){
- vlr=RE_findOrAddVlak(re, i);
- displace_render_face(re, vlr, scale);
- }
-
- /* Recalc vertex normals */
- calc_vertexnormals(re, startvert, startface, 0);
-}
-
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index ec55bc0a5e2..26151ff8b91 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -127,7 +127,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->r.size= 100;
envre->r.yasp= envre->r.xasp= 1;
- RE_InitState(envre, &envre->r, cuberes, cuberes, NULL);
+ RE_InitState(envre, NULL, &envre->r, cuberes, cuberes, NULL);
envre->scene= re->scene; /* unsure about this... */
/* view stuff in env render */
@@ -148,16 +148,16 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->totvlak= re->totvlak;
envre->totvert= re->totvert;
envre->tothalo= re->tothalo;
+ envre->totstrand= re->totstrand;
envre->totlamp= re->totlamp;
+ envre->sortedhalos= re->sortedhalos;
envre->lights= re->lights;
- envre->vertnodeslen= re->vertnodeslen;
- envre->vertnodes= re->vertnodes;
- envre->blohalen= re->blohalen;
- envre->bloha= re->bloha;
- envre->vlaknodeslen= re->vlaknodeslen;
- envre->vlaknodes= re->vlaknodes;
+ envre->objecttable= re->objecttable;
envre->customdata_names= re->customdata_names;
- envre->oc= re->oc;
+ envre->raytree= re->raytree;
+ envre->totinstance= re->totinstance;
+ envre->instancetable= re->instancetable;
+ envre->objectinstance= re->objectinstance;
return envre;
}
@@ -168,17 +168,16 @@ static void envmap_free_render_copy(Render *envre)
envre->totvlak= 0;
envre->totvert= 0;
envre->tothalo= 0;
+ envre->totstrand= 0;
envre->totlamp= 0;
+ envre->totinstance= 0;
+ envre->sortedhalos= NULL;
envre->lights.first= envre->lights.last= NULL;
- envre->vertnodeslen= 0;
- envre->vertnodes= NULL;
- envre->blohalen= 0;
- envre->bloha= NULL;
- envre->vlaknodeslen= 0;
- envre->vlaknodes= NULL;
+ envre->objecttable.first= envre->objecttable.last= NULL;
envre->customdata_names.first= envre->customdata_names.last= NULL;
- envre->oc.adrbranch= NULL;
- envre->oc.adrnode= NULL;
+ envre->raytree= NULL;
+ envre->instancetable.first= envre->instancetable.last= NULL;
+ envre->objectinstance= NULL;
RE_FreeRender(envre);
}
@@ -220,11 +219,11 @@ static void envmap_transmatrix(float mat[][4], int part)
static void env_rotate_scene(Render *re, float mat[][4], int mode)
{
GroupObject *go;
- VlakRen *vlr = NULL;
- VertRen *ver = NULL;
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
LampRen *lar = NULL;
HaloRen *har = NULL;
- float xn, yn, zn, imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3];
+ float imat[3][3], pmat[4][4], smat[4][4], tmat[4][4], cmat[3][3];
int a;
if(mode==0) {
@@ -235,46 +234,37 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode)
MTC_Mat4CpyMat4(tmat, mat);
MTC_Mat3CpyMat4(imat, mat);
}
-
- for(a=0; a<re->totvert; a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(re, a);
- else ver++;
-
- MTC_Mat4MulVecfl(tmat, ver->co);
-
- xn= ver->n[0];
- yn= ver->n[1];
- zn= ver->n[2];
- /* no transpose ! */
- ver->n[0]= imat[0][0]*xn+imat[1][0]*yn+imat[2][0]*zn;
- ver->n[1]= imat[0][1]*xn+imat[1][1]*yn+imat[2][1]*zn;
- ver->n[2]= imat[0][2]*xn+imat[1][2]*yn+imat[2][2]*zn;
- Normalize(ver->n);
+
+ for(obi=re->instancetable.first; obi; obi=obi->next) {
+ /* append or set matrix depending on dupli */
+ if(obi->flag & R_DUPLI_TRANSFORMED)
+ Mat4MulMat4(obi->mat, tmat, obi->mat);
+ else if(mode==1)
+ Mat4CpyMat4(obi->mat, tmat);
+ else
+ Mat4One(obi->mat);
+
+ Mat3CpyMat4(cmat, obi->mat);
+ Mat3Inv(obi->nmat, cmat);
+ Mat3Transp(obi->nmat);
+
+ /* indicate the renderer has to use transform matrices */
+ if(mode==0)
+ obi->flag &= ~R_ENV_TRANSFORMED;
+ else
+ obi->flag |= R_ENV_TRANSFORMED;
}
- for(a=0; a<re->tothalo; a++) {
- if((a & 255)==0) har= re->bloha[a>>8];
- else har++;
-
- MTC_Mat4MulVecfl(tmat, har->co);
- }
-
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
+
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->tothalo; a++) {
+ if((a & 255)==0) har= obr->bloha[a>>8];
+ else har++;
- xn= vlr->n[0];
- yn= vlr->n[1];
- zn= vlr->n[2];
- /* no transpose ! */
- vlr->n[0]= imat[0][0]*xn+imat[1][0]*yn+imat[2][0]*zn;
- vlr->n[1]= imat[0][1]*xn+imat[1][1]*yn+imat[2][1]*zn;
- vlr->n[2]= imat[0][2]*xn+imat[1][2]*yn+imat[2][2]*zn;
- Normalize(vlr->n);
+ MTC_Mat4MulVecfl(tmat, har->co);
+ }
}
- set_normalflags(re);
-
for(go=re->lights.first; go; go= go->next) {
lar= go->lampren;
@@ -309,6 +299,7 @@ static void env_rotate_scene(Render *re, float mat[][4], int mode)
static void env_layerflags(Render *re, unsigned int notlay)
{
+ ObjectRen *obr;
VlakRen *vlr = NULL;
int a;
@@ -322,23 +313,48 @@ static void env_layerflags(Render *re, unsigned int notlay)
notlay= ~notlay;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
- if((vlr->lay & notlay)==0)
- vlr->flag &= ~R_VISIBLE;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ if((obr->lay & notlay)==0) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ vlr->flag |= R_HIDDEN;
+ }
+ }
}
}
static void env_hideobject(Render *re, Object *ob)
{
+ ObjectRen *obr;
VlakRen *vlr = NULL;
int a;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
- if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE;
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ if(obr->ob == ob)
+ vlr->flag |= R_HIDDEN;
+ }
+ }
+}
+
+static void env_showobjects(Render *re)
+{
+ ObjectRen *obr;
+ VlakRen *vlr = NULL;
+ int a;
+
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ vlr->flag &= ~R_HIDDEN;
+ }
}
}
@@ -404,7 +420,7 @@ static void render_envmap(Render *re, EnvMap *env)
env_rotate_scene(envre, tmat, 1);
init_render_world(envre);
- project_renderdata(envre, projectverto, 0, 0);
+ project_renderdata(envre, projectverto, 0, 0, 1);
env_layerflags(envre, env->notlay);
env_hideobject(envre, env->object);
env_set_imats(envre);
@@ -414,6 +430,7 @@ static void render_envmap(Render *re, EnvMap *env)
}
/* rotate back */
+ env_showobjects(envre);
env_rotate_scene(envre, tmat, 0);
if(re->test_break()==0) {
@@ -619,7 +636,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
/* texvec should be the already reflected normal */
EnvMap *env;
ImBuf *ibuf;
- float fac, vec[3], sco[3], dxts[3], dyts[3];
+ float fac, vec[3], sco[3], dxts[3], dyts[3], w[3];
int face, face1;
env= tex->env;
@@ -700,10 +717,16 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
fac= (texres->ta+texr1.ta+texr2.ta);
if(fac!=0.0) {
fac= 1.0/fac;
+
+ /* weight contributions based on alpha */
+ w[0]= texres->ta*fac;
+ w[1]= texr1.ta*fac;
+ w[2]= texr2.ta*fac;
- texres->tr= fac*(texres->ta*texres->tr + texr1.ta*texr1.tr + texr2.ta*texr2.tr );
- texres->tg= fac*(texres->ta*texres->tg + texr1.ta*texr1.tg + texr2.ta*texr2.tg );
- texres->tb= fac*(texres->ta*texres->tb + texr1.ta*texr1.tb + texr2.ta*texr2.tb );
+ /* interpolate premultiplied result (imagewraposa returns key) */
+ texres->tr= (w[0]*texres->ta*texres->tr + w[1]*texr1.ta*texr1.tr + w[2]*texr2.ta*texr2.tr);
+ texres->tg= (w[0]*texres->ta*texres->tg + w[1]*texr1.ta*texr1.tg + w[2]*texr2.ta*texr2.tg);
+ texres->tb= (w[0]*texres->ta*texres->tb + w[1]*texr1.ta*texr1.tb + w[2]*texr2.ta*texr2.tb);
}
texres->ta= 1.0;
}
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 82abab62637..7dc205e2794 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -93,10 +93,10 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
else {
char *rect = (char *)( ibuf->rect+ ofs);
- col[0] = ((float)rect[0])/255.0f;
- col[1] = ((float)rect[1])/255.0f;
- col[2] = ((float)rect[2])/255.0f;
- col[3] = ((float)rect[3])/255.0f;
+ col[0] = ((float)rect[0])*(1.0f/255.0f);
+ col[1] = ((float)rect[1])*(1.0f/255.0f);
+ col[2] = ((float)rect[2])*(1.0f/255.0f);
+ col[3] = ((float)rect[3])*(1.0f/255.0f);
}
}
@@ -244,6 +244,14 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre
if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
+ /* de-premul, this is being premulled in shade_input_do_shade() */
+ if(texres->ta!=1.0f && texres->ta!=0.0f) {
+ fx= 1.0f/texres->ta;
+ texres->tr*= fx;
+ texres->tg*= fx;
+ texres->tb*= fx;
+ }
+
return retval;
}
@@ -691,10 +699,22 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f
maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
/* tex_sharper has been removed */
- minx= tex->filtersize*(maxx-minx)/2.0f;
- miny= tex->filtersize*(maxy-miny)/2.0f;
+ minx= (maxx-minx)/2.0f;
+ miny= (maxy-miny)/2.0f;
- if(tex->filtersize!=1.0f) {
+ if(tex->imaflag & TEX_FILTER_MIN) {
+ /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
+ float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
+
+ if(addval > minx)
+ minx= addval;
+ if(addval > miny)
+ miny= addval;
+ }
+ else if(tex->filtersize!=1.0f) {
+ minx*= tex->filtersize;
+ miny*= tex->filtersize;
+
dxt[0]*= tex->filtersize;
dxt[1]*= tex->filtersize;
dyt[0]*= tex->filtersize;
@@ -968,5 +988,13 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, f
texres->nor[2] = 2.f*(texres->tb - 0.5f);
}
+ /* de-premul, this is being premulled in shade_input_do_shade() */
+ if(texres->ta!=1.0f && texres->ta!=0.0f) {
+ fx= 1.0f/texres->ta;
+ texres->tr*= fx;
+ texres->tg*= fx;
+ texres->tb*= fx;
+ }
+
return retval;
}
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 83c0be6283b..add89d6249f 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -543,7 +543,7 @@ void RE_SetCamera(Render *re, Object *camera)
re->viewdx= pixsize;
re->viewdy= re->ycor*pixsize;
-
+
if(re->r.mode & R_ORTHO)
RE_SetOrtho(re, &viewplane, clipsta, clipend);
else
@@ -557,6 +557,13 @@ void RE_SetPixelSize(Render *re, float pixsize)
re->viewdy= re->ycor*pixsize;
}
+void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4])
+{
+ re->r.cfra= frame;
+ RE_SetCamera(re, camera);
+ Mat4CpyMat4(mat, re->winmat);
+}
+
/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
@@ -596,24 +603,20 @@ void initparts(Render *re)
/* mininum part size, but for exr tile saving it was checked already */
if(!(re->r.scemode & R_EXR_TILE_FILE)) {
if(re->r.mode & R_PANORAMA) {
- if(re->rectx/xparts < 8)
+ if(ceil(re->rectx/(float)xparts) < 8)
xparts= 1 + re->rectx/8;
}
else
- if(re->rectx/xparts < 64)
+ if(ceil(re->rectx/(float)xparts) < 64)
xparts= 1 + re->rectx/64;
- if(re->recty/yparts < 64)
+ if(ceil(re->recty/(float)yparts) < 64)
yparts= 1 + re->recty/64;
}
/* part size */
- partx= re->rectx/xparts;
- party= re->recty/yparts;
-
- /* if remainder pixel, add one, then parts are more equal in size for large panoramas */
- if(re->rectx % partx)
- partx++;
+ partx= ceil(re->rectx/(float)xparts);
+ party= ceil(re->recty/(float)yparts);
re->xparts= xparts;
re->yparts= yparts;
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
new file mode 100644
index 00000000000..a4d75c032e5
--- /dev/null
+++ b/source/blender/render/intern/source/occlusion.c
@@ -0,0 +1,1760 @@
+/*
+ * $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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_memarena.h"
+#include "BLI_threads.h"
+
+#include "BKE_global.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h"
+
+#include "RE_shader_ext.h"
+
+/* local includes */
+#include "occlusion.h"
+#include "render_types.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "pixelshading.h"
+#include "shading.h"
+#include "zbuf.h"
+
+/* ------------------------- Declarations --------------------------- */
+
+#define INVALID_INDEX ((int)(~0))
+#define INVPI 0.31830988618379069f
+#define TOTCHILD 8
+#define CACHE_STEP 3
+
+typedef struct OcclusionCacheSample {
+ float co[3], n[3], col[3], intensity, dist2;
+ int x, y, filled;
+} OcclusionCacheSample;
+
+typedef struct OcclusionCache {
+ OcclusionCacheSample *sample;
+ int x, y, w, h, step;
+} OcclusionCache;
+
+typedef struct OccFace {
+ int obi;
+ int facenr;
+} OccFace;
+
+typedef struct OccNode {
+ float co[3], area;
+ float sh[9], dco;
+ float occlusion;
+ int childflag;
+ union {
+ //OccFace face;
+ int face;
+ struct OccNode *node;
+ } child[TOTCHILD];
+} OccNode;
+
+typedef struct OcclusionTree {
+ MemArena *arena;
+
+ float (*co)[3]; /* temporary during build */
+
+ OccFace *face; /* instance and face indices */
+ float *occlusion; /* occlusion for faces */
+
+ OccNode *root;
+
+ OccNode **stack[BLENDER_MAX_THREADS];
+ int maxdepth;
+
+ int totface;
+
+ float error;
+ float distfac;
+
+ int dothreadedbuild;
+ int totbuildthread;
+
+ OcclusionCache *cache;
+} OcclusionTree;
+
+typedef struct OcclusionThread {
+ Render *re;
+ StrandSurface *mesh;
+ float (*facecol)[3];
+ int begin, end;
+ int thread;
+} OcclusionThread;
+
+typedef struct OcclusionBuildThread {
+ OcclusionTree *tree;
+ int begin, end, depth;
+ OccNode *node;
+} OcclusionBuildThread;
+
+/* ------------------------- Shading --------------------------- */
+
+extern Render R; // meh
+
+#if 0
+static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, float *rad)
+{
+ ShadeInput *shi= ssamp->shi;
+ ShadeResult *shr= ssamp->shr;
+ float l, u, v, *v1, *v2, *v3;
+
+ /* init */
+ if(vlr->v4) {
+ shi->u= u= 0.5f;
+ shi->v= v= 0.5f;
+ }
+ else {
+ shi->u= u= 1.0f/3.0f;
+ shi->v= v= 1.0f/3.0f;
+ }
+
+ /* setup render coordinates */
+ v1= vlr->v1->co;
+ v2= vlr->v2->co;
+ v3= vlr->v3->co;
+
+ /* renderco */
+ l= 1.0f-u-v;
+
+ shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
+ shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
+ shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
+
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+
+ /* set up view vector */
+ VECCOPY(shi->view, shi->co);
+ Normalize(shi->view);
+
+ /* cache for shadow */
+ shi->samplenr++;
+
+ shi->xs= 0; // TODO
+ shi->ys= 0;
+
+ shade_input_set_normals(shi);
+
+ /* no normal flip */
+ if(shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* not a pretty solution, but fixes common cases */
+ if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
+ VecMulf(shi->vn, -1.0f);
+ VecMulf(shi->vno, -1.0f);
+ }
+
+ /* init material vars */
+ // note, keep this synced with render_types.h
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
+ shi->har= shi->mat->har;
+
+ /* render */
+ shade_input_set_shade_texco(shi);
+ shade_material_loop(shi, shr); /* todo: nodes */
+
+ VECCOPY(rad, shr->combined);
+}
+
+static void occ_build_shade(Render *re, OcclusionTree *tree)
+{
+ ShadeSample ssamp;
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ int a;
+
+ R= *re;
+
+ /* setup shade sample with correct passes */
+ memset(&ssamp, 0, sizeof(ShadeSample));
+ ssamp.shi[0].lay= re->scene->lay;
+ ssamp.shi[0].passflag= SCE_PASS_DIFFUSE|SCE_PASS_RGBA;
+ ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
+ ssamp.tot= 1;
+
+ for(a=0; a<tree->totface; a++) {
+ obi= &R.objectinstance[tree->face[a].obi];
+ vlr= RE_findOrAddVlak(obi->obr, tree->face[a].vlr);
+
+ occ_shade(&ssamp, obi, vlr, tree->rad[a]);
+ }
+}
+#endif
+
+/* ------------------------- Spherical Harmonics --------------------------- */
+
+/* Use 2nd order SH => 9 coefficients, stored in this order:
+ 0 = (0,0),
+ 1 = (1,-1), 2 = (1,0), 3 = (1,1),
+ 4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */
+
+static void sh_copy(float *shresult, float *sh)
+{
+ memcpy(shresult, sh, sizeof(float)*9);
+}
+
+static void sh_mul(float *sh, float f)
+{
+ int i;
+
+ for(i=0; i<9; i++)
+ sh[i] *= f;
+}
+
+static void sh_add(float *shresult, float *sh1, float *sh2)
+{
+ int i;
+
+ for(i=0; i<9; i++)
+ shresult[i]= sh1[i] + sh2[i];
+}
+
+static void sh_from_disc(float *n, float area, float *shresult)
+{
+ /* See formula (3) in:
+ "An Efficient Representation for Irradiance Environment Maps" */
+ float sh[9], x, y, z;
+
+ x= n[0];
+ y= n[1];
+ z= n[2];
+
+ sh[0]= 0.282095f;
+
+ sh[1]= 0.488603f*y;
+ sh[2]= 0.488603f*z;
+ sh[3]= 0.488603f*x;
+
+ sh[4]= 1.092548f*x*y;
+ sh[5]= 1.092548f*y*z;
+ sh[6]= 0.315392f*(3.0f*z*z - 1.0f);
+ sh[7]= 1.092548f*x*z;
+ sh[8]= 0.546274f*(x*x - y*y);
+
+ sh_mul(sh, area);
+ sh_copy(shresult, sh);
+}
+
+static float sh_eval(float *sh, float *v)
+{
+ /* See formula (13) in:
+ "An Efficient Representation for Irradiance Environment Maps" */
+ static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
+ static const float c4 = 0.886227f, c5 = 0.247708f;
+ float x, y, z, sum;
+
+ x= v[0];
+ y= v[1];
+ z= v[2];
+
+ sum= c1*sh[8]*(x*x - y*y);
+ sum += c3*sh[6]*z*z;
+ sum += c4*sh[0];
+ sum += -c5*sh[6];
+ sum += 2.0f*c1*(sh[4]*x*y + sh[7]*x*z + sh[5]*y*z);
+ sum += 2.0f*c2*(sh[3]*x + sh[1]*y + sh[2]*z);
+
+ return sum;
+}
+
+/* ------------------------------ Building --------------------------------- */
+
+static void occ_face(const OccFace *face, float *co, float *normal, float *area)
+{
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ float v1[3], v2[3], v3[3], v4[3];
+
+ obi= &R.objectinstance[face->obi];
+ vlr= RE_findOrAddVlak(obi->obr, face->facenr);
+
+ if(co) {
+ if(vlr->v4)
+ VecLerpf(co, vlr->v1->co, vlr->v3->co, 0.5f);
+ else
+ CalcCent3f(co, vlr->v1->co, vlr->v2->co, vlr->v3->co);
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, co);
+ }
+
+ if(normal) {
+ normal[0]= -vlr->n[0];
+ normal[1]= -vlr->n[1];
+ normal[2]= -vlr->n[2];
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat3MulVecfl(obi->nmat, normal);
+ }
+
+ if(area) {
+ VECCOPY(v1, vlr->v1->co);
+ VECCOPY(v2, vlr->v2->co);
+ VECCOPY(v3, vlr->v3->co);
+ if(vlr->v4) VECCOPY(v4, vlr->v4->co);
+
+ if(obi->flag & R_TRANSFORMED) {
+ Mat4MulVecfl(obi->mat, v1);
+ Mat4MulVecfl(obi->mat, v2);
+ Mat4MulVecfl(obi->mat, v3);
+ if(vlr->v4) Mat4MulVecfl(obi->mat, v4);
+ }
+
+ /* todo: correct area for instances */
+ if(vlr->v4)
+ *area= AreaQ3Dfl(v1, v2, v3, v4);
+ else
+ *area= AreaT3Dfl(v1, v2, v3);
+ }
+}
+
+static void occ_sum_occlusion(OcclusionTree *tree, OccNode *node)
+{
+ OccNode *child;
+ float occ, area, totarea;
+ int a, b;
+
+ occ= 0.0f;
+ totarea= 0.0f;
+
+ for(b=0; b<TOTCHILD; b++) {
+ if(node->childflag & (1<<b)) {
+ a= node->child[b].face;
+ occ_face(&tree->face[a], 0, 0, &area);
+ occ += area*tree->occlusion[a];
+ totarea += area;
+ }
+ else if(node->child[b].node) {
+ child= node->child[b].node;
+ occ_sum_occlusion(tree, child);
+
+ occ += child->area*child->occlusion;
+ totarea += child->area;
+ }
+ }
+
+ if(totarea != 0.0f)
+ occ /= totarea;
+
+ node->occlusion= occ;
+}
+
+static int occ_find_bbox_axis(OcclusionTree *tree, int begin, int end, float *min, float *max)
+{
+ float len, maxlen= -1.0f;
+ int a, axis = 0;
+
+ INIT_MINMAX(min, max);
+
+ for(a=begin; a<end; a++)
+ DO_MINMAX(tree->co[a], min, max)
+
+ for(a=0; a<3; a++) {
+ len= max[a] - min[a];
+
+ if(len > maxlen) {
+ maxlen= len;
+ axis= a;
+ }
+ }
+
+ return axis;
+}
+
+void occ_node_from_face(OccFace *face, OccNode *node)
+{
+ float n[3];
+
+ occ_face(face, node->co, n, &node->area);
+ node->dco= 0.0f;
+ sh_from_disc(n, node->area, node->sh);
+}
+
+static void occ_build_dco(OcclusionTree *tree, OccNode *node, float *co, float *dco)
+{
+ OccNode *child;
+ float dist, d[3], nco[3];
+ int b;
+
+ for(b=0; b<TOTCHILD; b++) {
+ if(node->childflag & (1<<b)) {
+ occ_face(tree->face+node->child[b].face, nco, 0, 0);
+ }
+ else if(node->child[b].node) {
+ child= node->child[b].node;
+ occ_build_dco(tree, child, co, dco);
+ VECCOPY(nco, child->co);
+ }
+
+ VECSUB(d, nco, co);
+ dist= INPR(d, d);
+ if(dist > *dco)
+ *dco= dist;
+ }
+}
+
+static void occ_build_split(OcclusionTree *tree, int begin, int end, int *split)
+{
+ float min[3], max[3], mid;
+ int axis, a, enda;
+
+ /* split in middle of boundbox. this seems faster than median split
+ * on complex scenes, possibly since it avoids two distant faces to
+ * be in the same node better? */
+ axis= occ_find_bbox_axis(tree, begin, end, min, max);
+ mid= 0.5f*(min[axis]+max[axis]);
+
+ a= begin;
+ enda= end;
+ while(a<enda) {
+ if(tree->co[a][axis] > mid) {
+ enda--;
+ SWAP(OccFace, tree->face[a], tree->face[enda]);
+ SWAP(float, tree->co[a][0], tree->co[enda][0]);
+ SWAP(float, tree->co[a][1], tree->co[enda][1]);
+ SWAP(float, tree->co[a][2], tree->co[enda][2]);
+ }
+ else
+ a++;
+ }
+
+ *split= enda;
+}
+
+static void occ_build_8_split(OcclusionTree *tree, int begin, int end, int *offset, int *count)
+{
+ /* split faces into eight groups */
+ int b, splitx, splity[2], splitz[4];
+
+ occ_build_split(tree, begin, end, &splitx);
+
+ /* force split if none found, to deal with degenerate geometry */
+ if(splitx == begin || splitx == end)
+ splitx= (begin+end)/2;
+
+ occ_build_split(tree, begin, splitx, &splity[0]);
+ occ_build_split(tree, splitx, end, &splity[1]);
+
+ occ_build_split(tree, begin, splity[0], &splitz[0]);
+ occ_build_split(tree, splity[0], splitx, &splitz[1]);
+ occ_build_split(tree, splitx, splity[1], &splitz[2]);
+ occ_build_split(tree, splity[1], end, &splitz[3]);
+
+ offset[0]= begin;
+ offset[1]= splitz[0];
+ offset[2]= splity[0];
+ offset[3]= splitz[1];
+ offset[4]= splitx;
+ offset[5]= splitz[2];
+ offset[6]= splity[1];
+ offset[7]= splitz[3];
+
+ for(b=0; b<7; b++)
+ count[b]= offset[b+1] - offset[b];
+ count[7]= end - offset[7];
+}
+
+static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth);
+
+static void *exec_occ_build(void *data)
+{
+ OcclusionBuildThread *othread= (OcclusionBuildThread*)data;
+
+ occ_build_recursive(othread->tree, othread->node, othread->begin, othread->end, othread->depth);
+
+ return 0;
+}
+
+static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, int end, int depth)
+{
+ ListBase threads;
+ OcclusionBuildThread othreads[BLENDER_MAX_THREADS];
+ OccNode *child, tmpnode;
+ OccFace *face;
+ int a, b, totthread=0, offset[TOTCHILD], count[TOTCHILD];
+
+ /* keep track of maximum depth for stack */
+ if(depth > tree->maxdepth)
+ tree->maxdepth= depth;
+
+ /* add a new node */
+ node->occlusion= 1.0f;
+
+ /* leaf node with only children */
+ if(end - begin <= TOTCHILD) {
+ for(a=begin, b=0; a<end; a++, b++) {
+ face= &tree->face[a];
+ node->child[b].face= a;
+ node->childflag |= (1<<b);
+ }
+ }
+ else {
+ /* order faces */
+ occ_build_8_split(tree, begin, end, offset, count);
+
+ if(depth == 1 && tree->dothreadedbuild)
+ BLI_init_threads(&threads, exec_occ_build, tree->totbuildthread);
+
+ for(b=0; b<TOTCHILD; b++) {
+ if(count[b] == 0) {
+ node->child[b].node= NULL;
+ }
+ else if(count[b] == 1) {
+ face= &tree->face[offset[b]];
+ node->child[b].face= offset[b];
+ node->childflag |= (1<<b);
+ }
+ else {
+ if(tree->dothreadedbuild)
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ child= BLI_memarena_alloc(tree->arena, sizeof(OccNode));
+ node->child[b].node= child;
+
+ if(tree->dothreadedbuild)
+ BLI_unlock_thread(LOCK_CUSTOM1);
+
+ if(depth == 1 && tree->dothreadedbuild) {
+ othreads[totthread].tree= tree;
+ othreads[totthread].node= child;
+ othreads[totthread].begin= offset[b];
+ othreads[totthread].end= offset[b]+count[b];
+ othreads[totthread].depth= depth+1;
+ BLI_insert_thread(&threads, &othreads[totthread]);
+ totthread++;
+ }
+ else
+ occ_build_recursive(tree, child, offset[b], offset[b]+count[b], depth+1);
+ }
+ }
+
+ if(depth == 1 && tree->dothreadedbuild)
+ BLI_end_threads(&threads);
+ }
+
+ /* combine area, position and sh */
+ for(b=0; b<TOTCHILD; b++) {
+ if(node->childflag & (1<<b)) {
+ child= &tmpnode;
+ occ_node_from_face(tree->face+node->child[b].face, &tmpnode);
+ }
+ else {
+ child= node->child[b].node;
+ }
+
+ if(child) {
+ node->area += child->area;
+ sh_add(node->sh, node->sh, child->sh);
+ VECADDFAC(node->co, node->co, child->co, child->area);
+ }
+ }
+
+ if(node->area != 0.0f)
+ VecMulf(node->co, 1.0f/node->area);
+
+ /* compute maximum distance from center */
+ node->dco= 0.0f;
+ occ_build_dco(tree, node, node->co, &node->dco);
+}
+
+static void occ_build_sh_normalize(OccNode *node)
+{
+ /* normalize spherical harmonics to not include area, so
+ * we can clamp the dot product and then mutliply by area */
+ int b;
+
+ if(node->area != 0.0f)
+ sh_mul(node->sh, 1.0f/node->area);
+
+ for(b=0; b<TOTCHILD; b++) {
+ if(node->childflag & (1<<b));
+ else if(node->child[b].node)
+ occ_build_sh_normalize(node->child[b].node);
+ }
+}
+
+static OcclusionTree *occ_tree_build(Render *re)
+{
+ OcclusionTree *tree;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ VlakRen *vlr= NULL;
+ int a, b, c, totface;
+
+ /* count */
+ totface= 0;
+ for(obi=re->instancetable.first; obi; obi=obi->next) {
+ obr= obi->obr;
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ if(vlr->mat->mode & MA_TRACEBLE)
+ totface++;
+ }
+ }
+
+ if(totface == 0)
+ return NULL;
+
+ tree= MEM_callocN(sizeof(OcclusionTree), "OcclusionTree");
+ tree->totface= totface;
+
+ /* parameters */
+ tree->error= get_render_aosss_error(&re->r, re->wrld.ao_approx_error);
+ tree->distfac= (re->wrld.aomode & WO_AODIST)? re->wrld.aodistfac: 0.0f;
+
+ /* allocation */
+ tree->arena= BLI_memarena_new(0x8000 * sizeof(OccNode));
+ BLI_memarena_use_calloc(tree->arena);
+
+ if(re->wrld.aomode & WO_AOCACHE)
+ tree->cache= MEM_callocN(sizeof(OcclusionCache)*BLENDER_MAX_THREADS, "OcclusionCache");
+
+ tree->face= MEM_callocN(sizeof(OccFace)*totface, "OcclusionFace");
+ tree->co= MEM_callocN(sizeof(float)*3*totface, "OcclusionCo");
+ tree->occlusion= MEM_callocN(sizeof(float)*totface, "OcclusionOcclusion");
+
+ /* make array of face pointers */
+ for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) {
+ obr= obi->obr;
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ if(vlr->mat->mode & MA_TRACEBLE) {
+ tree->face[b].obi= c;
+ tree->face[b].facenr= a;
+ tree->occlusion[b]= 1.0f;
+ occ_face(&tree->face[b], tree->co[b], NULL, NULL);
+ b++;
+ }
+ }
+ }
+
+ /* threads */
+ tree->totbuildthread= (re->r.threads > 1 && totface > 10000)? 8: 1;
+ tree->dothreadedbuild= (tree->totbuildthread > 1);
+
+ /* recurse */
+ tree->root= BLI_memarena_alloc(tree->arena, sizeof(OccNode));
+ occ_build_recursive(tree, tree->root, 0, totface, 1);
+
+#if 0
+ if(tree->doindirect) {
+ occ_build_shade(re, tree);
+ occ_sum_occlusion(tree, tree->root);
+ }
+#endif
+
+ MEM_freeN(tree->co);
+ tree->co= NULL;
+
+ occ_build_sh_normalize(tree->root);
+
+ for(a=0; a<BLENDER_MAX_THREADS; a++)
+ tree->stack[a]= MEM_callocN(sizeof(OccNode)*TOTCHILD*(tree->maxdepth+1), "OccStack");
+
+ return tree;
+}
+
+static void occ_free_tree(OcclusionTree *tree)
+{
+ int a;
+
+ if(tree) {
+ if(tree->arena) BLI_memarena_free(tree->arena);
+ for(a=0; a<BLENDER_MAX_THREADS; a++)
+ if(tree->stack[a])
+ MEM_freeN(tree->stack[a]);
+ if(tree->occlusion) MEM_freeN(tree->occlusion);
+ if(tree->face) MEM_freeN(tree->face);
+ if(tree->cache) MEM_freeN(tree->cache);
+ MEM_freeN(tree);
+ }
+}
+
+/* ------------------------- Traversal --------------------------- */
+
+static float occ_solid_angle(OccNode *node, float *v, float d2, float invd2, float *receivenormal)
+{
+ float dotreceive, dotemit;
+ float ev[3];
+
+ ev[0]= -v[0]*invd2;
+ ev[1]= -v[1]*invd2;
+ ev[2]= -v[2]*invd2;
+ dotemit= sh_eval(node->sh, ev);
+ dotreceive= INPR(receivenormal, v)*invd2;
+
+ CLAMP(dotemit, 0.0f, 1.0f);
+ CLAMP(dotreceive, 0.0f, 1.0f);
+
+ return ((node->area*dotemit*dotreceive)/(d2 + node->area*INVPI))*INVPI;
+}
+
+static void VecAddDir(float *result, float *v1, float *v2, float fac)
+{
+ result[0]= v1[0] + fac*(v2[0] - v1[0]);
+ result[1]= v1[1] + fac*(v2[1] - v1[1]);
+ result[2]= v1[2] + fac*(v2[2] - v1[2]);
+}
+
+static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, float *q0, float *q1, float *q2, float *q3)
+{
+ static const float epsilon = 1e-6f;
+ float c, sd[3];
+
+ c= INPR(n, p);
+
+ /* signed distances from the vertices to the plane. */
+ sd[0]= INPR(n, v0) - c;
+ sd[1]= INPR(n, v1) - c;
+ sd[2]= INPR(n, v2) - c;
+
+ if(fabs(sd[0]) < epsilon) sd[0] = 0.0f;
+ if(fabs(sd[1]) < epsilon) sd[1] = 0.0f;
+ if(fabs(sd[2]) < epsilon) sd[2] = 0.0f;
+
+ if(sd[0] > 0) {
+ if(sd[1] > 0) {
+ if(sd[2] > 0) {
+ // +++
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // ++-
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VecAddDir(q3, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ }
+ else {
+ // ++0
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ }
+ else if(sd[1] < 0) {
+ if(sd[2] > 0) {
+ // +-+
+ VECCOPY(q0, v0);
+ VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VECCOPY(q3, v2);
+ }
+ else if(sd[2] < 0) {
+ // +--
+ VECCOPY(q0, v0);
+ VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VecAddDir(q2, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ VECCOPY(q3, q2);
+ }
+ else {
+ // +-0
+ VECCOPY(q0, v0);
+ VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ }
+ else {
+ if(sd[2] > 0) {
+ // +0+
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // +0-
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VecAddDir(q2, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ VECCOPY(q3, q2);
+ }
+ else {
+ // +00
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ }
+ }
+ else if(sd[0] < 0) {
+ if(sd[1] > 0) {
+ if(sd[2] > 0) {
+ // -++
+ VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VecAddDir(q3, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ }
+ else if(sd[2] < 0) {
+ // -+-
+ VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VECCOPY(q1, v1);
+ VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VECCOPY(q3, q2);
+ }
+ else {
+ // -+0
+ VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ }
+ else if(sd[1] < 0) {
+ if(sd[2] > 0) {
+ // --+
+ VecAddDir(q0, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ VecAddDir(q1, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // ---
+ return 0;
+ }
+ else {
+ // --0
+ return 0;
+ }
+ }
+ else {
+ if(sd[2] > 0) {
+ // -0+
+ VecAddDir(q0, v0, v2, (sd[0]/(sd[0]-sd[2])));
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // -0-
+ return 0;
+ }
+ else {
+ // -00
+ return 0;
+ }
+ }
+ }
+ else {
+ if(sd[1] > 0) {
+ if(sd[2] > 0) {
+ // 0++
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // 0+-
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VECCOPY(q3, q2);
+ }
+ else {
+ // 0+0
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ }
+ else if(sd[1] < 0) {
+ if(sd[2] > 0) {
+ // 0-+
+ VECCOPY(q0, v0);
+ VecAddDir(q1, v1, v2, (sd[1]/(sd[1]-sd[2])));
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // 0--
+ return 0;
+ }
+ else {
+ // 0-0
+ return 0;
+ }
+ }
+ else {
+ if(sd[2] > 0) {
+ // 00+
+ VECCOPY(q0, v0);
+ VECCOPY(q1, v1);
+ VECCOPY(q2, v2);
+ VECCOPY(q3, q2);
+ }
+ else if(sd[2] < 0) {
+ // 00-
+ return 0;
+ }
+ else {
+ // 000
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* altivec optimization, this works, but is unused */
+
+#if 0
+#include <Accelerate/Accelerate.h>
+
+typedef union {
+ vFloat v;
+ float f[4];
+} vFloatResult;
+
+static vFloat vec_splat_float(float val)
+{
+ return (vFloat){val, val, val, val};
+}
+
+static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
+{
+ vFloat vcos, rlen, vrx, vry, vrz, vsrx, vsry, vsrz, gx, gy, gz, vangle;
+ vUInt8 rotate = (vUInt8){4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3};
+ vFloatResult vresult;
+ float result;
+
+ /* compute r* */
+ vrx = (vFloat){q0[0], q1[0], q2[0], q3[0]} - vec_splat_float(p[0]);
+ vry = (vFloat){q0[1], q1[1], q2[1], q3[1]} - vec_splat_float(p[1]);
+ vrz = (vFloat){q0[2], q1[2], q2[2], q3[2]} - vec_splat_float(p[2]);
+
+ /* normalize r* */
+ rlen = vec_rsqrte(vrx*vrx + vry*vry + vrz*vrz + vec_splat_float(1e-16f));
+ vrx = vrx*rlen;
+ vry = vry*rlen;
+ vrz = vrz*rlen;
+
+ /* rotate r* for cross and dot */
+ vsrx= vec_perm(vrx, vrx, rotate);
+ vsry= vec_perm(vry, vry, rotate);
+ vsrz= vec_perm(vrz, vrz, rotate);
+
+ /* cross product */
+ gx = vsry*vrz - vsrz*vry;
+ gy = vsrz*vrx - vsrx*vrz;
+ gz = vsrx*vry - vsry*vrx;
+
+ /* normalize */
+ rlen = vec_rsqrte(gx*gx + gy*gy + gz*gz + vec_splat_float(1e-16f));
+ gx = gx*rlen;
+ gy = gy*rlen;
+ gz = gz*rlen;
+
+ /* angle */
+ vcos = vrx*vsrx + vry*vsry + vrz*vsrz;
+ vcos= vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f));
+ vangle= vacosf(vcos);
+
+ /* dot */
+ vresult.v = (vec_splat_float(n[0])*gx +
+ vec_splat_float(n[1])*gy +
+ vec_splat_float(n[2])*gz)*vangle;
+
+ result= (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3])*(0.5f/(float)M_PI);
+ result= MAX2(result, 0.0f);
+
+ return result;
+}
+
+#endif
+
+/* SSE optimization, acos code doesn't work */
+
+#if 0
+
+#include <xmmintrin.h>
+
+static __m128 sse_approx_acos(__m128 x)
+{
+ /* needs a better approximation than taylor expansion of acos, since that
+ * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work
+ * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */
+
+ return _mm_set_ps1(1.0f);
+}
+
+static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
+{
+ float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
+ float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
+ float fresult[4] __attribute__((aligned(16)));
+ __m128 qx, qy, qz, rx, ry, rz, rlen, srx, sry, srz, gx, gy, gz, glen, rcos, angle, aresult;
+
+ /* compute r */
+ qx = _mm_set_ps(q3[0], q2[0], q1[0], q0[0]);
+ qy = _mm_set_ps(q3[1], q2[1], q1[1], q0[1]);
+ qz = _mm_set_ps(q3[2], q2[2], q1[2], q0[2]);
+
+ rx = qx - _mm_set_ps1(p[0]);
+ ry = qy - _mm_set_ps1(p[1]);
+ rz = qz - _mm_set_ps1(p[2]);
+
+ /* normalize r */
+ rlen = _mm_rsqrt_ps(rx*rx + ry*ry + rz*rz + _mm_set_ps1(1e-16f));
+ rx = rx*rlen;
+ ry = ry*rlen;
+ rz = rz*rlen;
+
+ /* cross product */
+ srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0,3,2,1));
+ sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0,3,2,1));
+ srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0,3,2,1));
+
+ gx = sry*rz - srz*ry;
+ gy = srz*rx - srx*rz;
+ gz = srx*ry - sry*rx;
+
+ /* normalize g */
+ glen = _mm_rsqrt_ps(gx*gx + gy*gy + gz*gz + _mm_set_ps1(1e-16f));
+ gx = gx*glen;
+ gy = gy*glen;
+ gz = gz*glen;
+
+ /* compute angle */
+ rcos = rx*srx + ry*sry + rz*srz;
+ rcos= _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f));
+
+ angle = sse_approx_cos(rcos);
+ aresult = (_mm_set_ps1(n[0])*gx + _mm_set_ps1(n[1])*gy + _mm_set_ps1(n[2])*gz)*angle;
+
+ /* sum together */
+ result= (fresult[0] + fresult[1] + fresult[2] + fresult[3])*(0.5f/(float)M_PI);
+ result= MAX2(result, 0.0f);
+
+ return result;
+}
+
+#endif
+
+static float saacosf(float fac)
+{
+ if(fac<= -1.0f) return (float)M_PI;
+ else if(fac>=1.0f) return 0.0f;
+ else return acos(fac); /* acosf(fac) */
+}
+
+static void normalizef(float *n)
+{
+ float d;
+
+ d= INPR(n, n);
+
+ if(d > 1.0e-35F) {
+ d= 1.0f/sqrt(d); /* sqrtf(d) */
+
+ n[0] *= d;
+ n[1] *= d;
+ n[2] *= d;
+ }
+}
+
+static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
+{
+ float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
+ float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
+
+ VECSUB(r0, q0, p);
+ VECSUB(r1, q1, p);
+ VECSUB(r2, q2, p);
+ VECSUB(r3, q3, p);
+
+ normalizef(r0);
+ normalizef(r1);
+ normalizef(r2);
+ normalizef(r3);
+
+ Crossf(g0, r1, r0); normalizef(g0);
+ Crossf(g1, r2, r1); normalizef(g1);
+ Crossf(g2, r3, r2); normalizef(g2);
+ Crossf(g3, r0, r3); normalizef(g3);
+
+ a1= saacosf(INPR(r0, r1));
+ a2= saacosf(INPR(r1, r2));
+ a3= saacosf(INPR(r2, r3));
+ a4= saacosf(INPR(r3, r0));
+
+ dot1= INPR(n, g0);
+ dot2= INPR(n, g1);
+ dot3= INPR(n, g2);
+ dot4= INPR(n, g3);
+
+ result= (a1*dot1 + a2*dot2 + a3*dot3 + a4*dot4)*0.5f/(float)M_PI;
+ result= MAX2(result, 0.0f);
+
+ return result;
+}
+
+float occ_form_factor(OccFace *face, float *p, float *n)
+{
+ ObjectInstanceRen *obi;
+ VlakRen *vlr;
+ float v1[3], v2[3], v3[3], v4[3], q0[3], q1[3], q2[3], q3[3], contrib= 0.0f;
+
+ obi= &R.objectinstance[face->obi];
+ vlr= RE_findOrAddVlak(obi->obr, face->facenr);
+
+ VECCOPY(v1, vlr->v1->co);
+ VECCOPY(v2, vlr->v2->co);
+ VECCOPY(v3, vlr->v3->co);
+
+ if(obi->flag & R_TRANSFORMED) {
+ Mat4MulVecfl(obi->mat, v1);
+ Mat4MulVecfl(obi->mat, v2);
+ Mat4MulVecfl(obi->mat, v3);
+ }
+
+ if(occ_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3))
+ contrib += occ_quad_form_factor(p, n, q0, q1, q2, q3);
+
+ if(vlr->v4) {
+ VECCOPY(v4, vlr->v4->co);
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, v4);
+
+ if(occ_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3))
+ contrib += occ_quad_form_factor(p, n, q0, q1, q2, q3);
+ }
+
+ return contrib;
+}
+
+static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float *pp, float *pn, float *occ, float *bentn)
+{
+ OccNode *node, **stack;
+ OccFace *face;
+ float resultocc, v[3], p[3], n[3], co[3], invd2;
+ float distfac, fac, error, d2, weight, emitarea;
+ int b, totstack;
+
+ /* init variables */
+ VECCOPY(p, pp);
+ VECCOPY(n, pn);
+ VECADDFAC(p, p, n, 1e-4f);
+
+ if(bentn)
+ VECCOPY(bentn, n);
+
+ error= tree->error;
+ distfac= tree->distfac;
+
+ resultocc= 0.0f;
+
+ /* init stack */
+ stack= tree->stack[thread];
+ stack[0]= tree->root;
+ totstack= 1;
+
+ while(totstack) {
+ /* pop point off the stack */
+ node= stack[--totstack];
+
+ VECSUB(v, node->co, p);
+ d2= INPR(v, v) + 1e-16f;
+ emitarea= MAX2(node->area, node->dco);
+
+ if(d2*error > emitarea) {
+ if(distfac != 0.0f) {
+ fac= 1.0f/(1.0f + distfac*d2);
+ if(fac < 0.01f)
+ continue;
+ }
+ else
+ fac= 1.0f;
+
+ /* accumulate occlusion from spherical harmonics */
+ invd2 = 1.0f/sqrt(d2);
+ weight= occ_solid_angle(node, v, d2, invd2, n);
+ weight *= node->occlusion;
+
+ if(bentn) {
+ bentn[0] -= weight*invd2*v[0];
+ bentn[1] -= weight*invd2*v[1];
+ bentn[2] -= weight*invd2*v[2];
+ }
+
+ resultocc += weight*fac;
+ }
+ else {
+ /* traverse into children */
+ for(b=0; b<TOTCHILD; b++) {
+ if(node->childflag & (1<<b)) {
+ face= tree->face+node->child[b].face;
+
+ /* accumulate occlusion with face form factor */
+ if(!exclude || !(face->obi == exclude->obi && face->facenr == exclude->facenr)) {
+ if(bentn || distfac != 0.0f) {
+ occ_face(face, co, NULL, NULL);
+ VECSUB(v, co, p);
+ d2= INPR(v, v) + 1e-16f;
+
+ fac= (distfac == 0.0f)? 1.0f: 1.0f/(1.0f + distfac*d2);
+ if(fac < 0.01f)
+ continue;
+ }
+ else
+ fac= 1.0f;
+
+ weight= occ_form_factor(face, p, n);
+ weight *= tree->occlusion[node->child[b].face];
+
+ if(bentn) {
+ invd2= 1.0f/sqrt(d2);
+ bentn[0] -= weight*invd2*v[0];
+ bentn[1] -= weight*invd2*v[1];
+ bentn[2] -= weight*invd2*v[2];
+ }
+
+ resultocc += weight*fac;
+ }
+ }
+ else if(node->child[b].node) {
+ /* push child on the stack */
+ stack[totstack++]= node->child[b].node;
+ }
+ }
+ }
+ }
+
+ if(occ) *occ= resultocc;
+ if(bentn) Normalize(bentn);
+}
+
+static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
+{
+ float *occ, co[3], n[3];
+ int pass, i;
+
+ occ= MEM_callocN(sizeof(float)*tree->totface, "OcclusionPassOcc");
+
+ for(pass=0; pass<totpass; pass++) {
+ for(i=0; i<tree->totface; i++) {
+ occ_face(&tree->face[i], co, n, NULL);
+ VecMulf(n, -1.0f);
+ VECADDFAC(co, co, n, 1e-8f);
+
+ occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL);
+ if(re->test_break())
+ break;
+ }
+
+ if(re->test_break())
+ break;
+
+ for(i=0; i<tree->totface; i++) {
+ tree->occlusion[i] -= occ[i]; //MAX2(1.0f-occ[i], 0.0f);
+ if(tree->occlusion[i] < 0.0f)
+ tree->occlusion[i]= 0.0f;
+ }
+
+ occ_sum_occlusion(tree, tree->root);
+ }
+
+ MEM_freeN(occ);
+}
+
+static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *skycol)
+{
+ float nn[3], bn[3], fac, occ, occlusion, correction;
+ int aocolor;
+
+ aocolor= re->wrld.aocolor;
+ if(onlyshadow)
+ aocolor= WO_AOPLAIN;
+
+ VECCOPY(nn, n);
+ VecMulf(nn, -1.0f);
+
+ occ_lookup(tree, thread, exclude, co, nn, &occ, (aocolor)? bn: NULL);
+
+ correction= re->wrld.ao_approx_correction;
+
+ occlusion= (1.0f-correction)*(1.0f-occ);
+ CLAMP(occlusion, 0.0f, 1.0f);
+ if(correction != 0.0f)
+ occlusion += correction*exp(-occ);
+
+ if(aocolor) {
+ /* sky shading using bent normal */
+ if(ELEM(aocolor, WO_AOSKYCOL, WO_AOSKYTEX)) {
+ fac= 0.5*(1.0f+bn[0]*re->grvec[0]+ bn[1]*re->grvec[1]+ bn[2]*re->grvec[2]);
+ skycol[0]= (1.0f-fac)*re->wrld.horr + fac*re->wrld.zenr;
+ skycol[1]= (1.0f-fac)*re->wrld.horg + fac*re->wrld.zeng;
+ skycol[2]= (1.0f-fac)*re->wrld.horb + fac*re->wrld.zenb;
+ }
+#if 0
+ else { /* WO_AOSKYTEX */
+ float dxyview[3];
+ bn[0]= -bn[0];
+ bn[1]= -bn[1];
+ bn[2]= -bn[2];
+ dxyview[0]= 1.0f;
+ dxyview[1]= 1.0f;
+ dxyview[2]= 0.0f;
+ shadeSkyView(skycol, co, bn, dxyview);
+ }
+#endif
+
+ VecMulf(skycol, occlusion);
+ }
+ else {
+ skycol[0]= occlusion;
+ skycol[1]= occlusion;
+ skycol[2]= occlusion;
+ }
+}
+
+/* ---------------------------- Caching ------------------------------- */
+
+static OcclusionCacheSample *find_occ_sample(OcclusionCache *cache, int x, int y)
+{
+ x -= cache->x;
+ y -= cache->y;
+
+ x /= cache->step;
+ y /= cache->step;
+ x *= cache->step;
+ y *= cache->step;
+
+ if(x < 0 || x >= cache->w || y < 0 || y >= cache->h)
+ return NULL;
+ else
+ return &cache->sample[y*cache->w + x];
+}
+
+static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int y, int thread, float *col)
+{
+ OcclusionCache *cache;
+ OcclusionCacheSample *samples[4], *sample;
+ float wn[4], wz[4], wb[4], tx, ty, w, totw, mino, maxo;
+ float d[3], dist2;
+ int i, x1, y1, x2, y2;
+
+ if(!tree->cache)
+ return 0;
+
+ /* first try to find a sample in the same pixel */
+ cache= &tree->cache[thread];
+
+ if(cache->sample && cache->step) {
+ sample= &cache->sample[(y-cache->y)*cache->w + (x-cache->x)];
+ if(sample->filled) {
+ VECSUB(d, sample->co, co);
+ dist2= INPR(d, d);
+ if(dist2 < 0.5f*sample->dist2 && INPR(sample->n, n) > 0.98f) {
+ VECCOPY(col, sample->col);
+ return 1;
+ }
+ }
+ }
+ else
+ return 0;
+
+ /* try to interpolate between 4 neighbouring pixels */
+ samples[0]= find_occ_sample(cache, x, y);
+ samples[1]= find_occ_sample(cache, x+cache->step, y);
+ samples[2]= find_occ_sample(cache, x, y+cache->step);
+ samples[3]= find_occ_sample(cache, x+cache->step, y+cache->step);
+
+ for(i=0; i<4; i++)
+ if(!samples[i] || !samples[i]->filled)
+ return 0;
+
+ /* require intensities not being too different */
+ mino= MIN4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+ maxo= MAX4(samples[0]->intensity, samples[1]->intensity, samples[2]->intensity, samples[3]->intensity);
+
+ if(maxo - mino > 0.05f)
+ return 0;
+
+ /* compute weighted interpolation between samples */
+ col[0]= col[1]= col[2]= 0.0f;
+ totw= 0.0f;
+
+ x1= samples[0]->x;
+ y1= samples[0]->y;
+ x2= samples[3]->x;
+ y2= samples[3]->y;
+
+ tx= (float)(x2 - x)/(float)(x2 - x1);
+ ty= (float)(y2 - y)/(float)(y2 - y1);
+
+ wb[3]= (1.0f-tx)*(1.0f-ty);
+ wb[2]= (tx)*(1.0f-ty);
+ wb[1]= (1.0f-tx)*(ty);
+ wb[0]= tx*ty;
+
+ for(i=0; i<4; i++) {
+ VECSUB(d, samples[i]->co, co);
+ dist2= INPR(d, d);
+
+ wz[i]= 1.0f; //(samples[i]->dist2/(1e-4f + dist2));
+ wn[i]= pow(INPR(samples[i]->n, n), 32.0f);
+
+ w= wb[i]*wn[i]*wz[i];
+
+ totw += w;
+ col[0] += w*samples[i]->col[0];
+ col[1] += w*samples[i]->col[1];
+ col[2] += w*samples[i]->col[2];
+ }
+
+ if(totw >= 0.9f) {
+ totw= 1.0f/totw;
+ col[0] *= totw;
+ col[1] *= totw;
+ col[2] *= totw;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void sample_occ_surface(ShadeInput *shi)
+{
+ StrandRen *strand= shi->strand;
+ StrandSurface *mesh= strand->buffer->surface;
+ int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
+ float w[4], *co1, *co2, *co3, *co4;
+
+ if(mesh && index) {
+ face= mesh->face[*index];
+
+ co1= mesh->co[face[0]];
+ co2= mesh->co[face[1]];
+ co3= mesh->co[face[2]];
+ co4= (face[3])? mesh->co[face[3]]: NULL;
+
+ InterpWeightsQ3Dfl(co1, co2, co3, co4, strand->vert->co, w);
+
+ shi->ao[0]= shi->ao[1]= shi->ao[2]= 0.0f;
+ VECADDFAC(shi->ao, shi->ao, mesh->col[face[0]], w[0]);
+ VECADDFAC(shi->ao, shi->ao, mesh->col[face[1]], w[1]);
+ VECADDFAC(shi->ao, shi->ao, mesh->col[face[2]], w[2]);
+ if(face[3])
+ VECADDFAC(shi->ao, shi->ao, mesh->col[face[3]], w[3]);
+ }
+ else {
+ shi->ao[0]= 1.0f;
+ shi->ao[1]= 1.0f;
+ shi->ao[2]= 1.0f;
+ }
+}
+
+/* ------------------------- External Functions --------------------------- */
+
+static void *exec_strandsurface_sample(void *data)
+{
+ OcclusionThread *othread= (OcclusionThread*)data;
+ Render *re= othread->re;
+ StrandSurface *mesh= othread->mesh;
+ float col[3], co[3], n[3], *co1, *co2, *co3, *co4;
+ int a, *face;
+
+ for(a=othread->begin; a<othread->end; a++) {
+ face= mesh->face[a];
+ co1= mesh->co[face[0]];
+ co2= mesh->co[face[1]];
+ co3= mesh->co[face[2]];
+
+ if(face[3]) {
+ co4= mesh->co[face[3]];
+
+ VecLerpf(co, co1, co3, 0.5f);
+ CalcNormFloat4(co1, co2, co3, co4, n);
+ }
+ else {
+ CalcCent3f(co, co1, co2, co3);
+ CalcNormFloat(co1, co2, co3, n);
+ }
+ VecMulf(n, -1.0f);
+
+ sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, col);
+ VECCOPY(othread->facecol[a], col);
+ }
+
+ return 0;
+}
+
+void make_occ_tree(Render *re)
+{
+ OcclusionThread othreads[BLENDER_MAX_THREADS];
+ StrandSurface *mesh;
+ ListBase threads;
+ float col[3], (*facecol)[3];
+ int a, totface, totthread, *face, *count;
+
+ /* ugly, needed for occ_face */
+ R= *re;
+
+ re->i.infostr= "Occlusion preprocessing";
+ re->stats_draw(&re->i);
+
+ re->occlusiontree= occ_tree_build(re);
+
+ if(re->occlusiontree) {
+ if(re->wrld.ao_approx_passes)
+ occ_compute_passes(re, re->occlusiontree, re->wrld.ao_approx_passes);
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ count= MEM_callocN(sizeof(int)*mesh->totvert, "OcclusionCount");
+ facecol= MEM_callocN(sizeof(float)*3*mesh->totface, "StrandSurfFaceCol");
+
+ totthread= (mesh->totface > 10000)? re->r.threads: 1;
+ totface= mesh->totface/totthread;
+ for(a=0; a<totthread; a++) {
+ othreads[a].re= re;
+ othreads[a].facecol= facecol;
+ othreads[a].thread= a;
+ othreads[a].mesh= mesh;
+ othreads[a].begin= a*totface;
+ othreads[a].end= (a == totthread-1)? mesh->totface: (a+1)*totface;
+ }
+
+ if(totthread == 1) {
+ exec_strandsurface_sample(&othreads[0]);
+ }
+ else {
+ BLI_init_threads(&threads, exec_strandsurface_sample, totthread);
+
+ for(a=0; a<totthread; a++)
+ BLI_insert_thread(&threads, &othreads[a]);
+
+ BLI_end_threads(&threads);
+ }
+
+ for(a=0; a<mesh->totface; a++) {
+ face= mesh->face[a];
+
+ VECCOPY(col, facecol[a]);
+ VECADD(mesh->col[face[0]], mesh->col[face[0]], col);
+ count[face[0]]++;
+ VECADD(mesh->col[face[1]], mesh->col[face[1]], col);
+ count[face[1]]++;
+ VECADD(mesh->col[face[2]], mesh->col[face[2]], col);
+ count[face[2]]++;
+
+ if(face[3]) {
+ VECADD(mesh->col[face[3]], mesh->col[face[3]], col);
+ count[face[3]]++;
+ }
+ }
+
+ for(a=0; a<mesh->totvert; a++)
+ if(count[a])
+ VecMulf(mesh->col[a], 1.0f/count[a]);
+
+ MEM_freeN(count);
+ MEM_freeN(facecol);
+ }
+ }
+}
+
+void free_occ(Render *re)
+{
+ if(re->occlusiontree) {
+ occ_free_tree(re->occlusiontree);
+ re->occlusiontree = NULL;
+ }
+}
+
+void sample_occ(Render *re, ShadeInput *shi)
+{
+ OcclusionTree *tree= re->occlusiontree;
+ OcclusionCache *cache;
+ OcclusionCacheSample *sample;
+ OccFace exclude;
+ int onlyshadow;
+
+ if(tree) {
+ if(shi->strand) {
+ sample_occ_surface(shi);
+ }
+ /* try to get result from the cache if possible */
+ else if(!sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) {
+ /* no luck, let's sample the occlusion */
+ exclude.obi= shi->obi - re->objectinstance;
+ exclude.facenr= shi->vlr->index;
+ onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao);
+
+ /* fill result into sample, each time */
+ if(tree->cache) {
+ cache= &tree->cache[shi->thread];
+
+ if(cache->sample && cache->step) {
+ sample= &cache->sample[(shi->ys-cache->y)*cache->w + (shi->xs-cache->x)];
+ VECCOPY(sample->co, shi->co);
+ VECCOPY(sample->n, shi->vno);
+ VECCOPY(sample->col, shi->ao);
+ sample->intensity= MAX3(sample->col[0], sample->col[1], sample->col[2]);
+ sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
+ sample->filled= 1;
+ }
+ }
+ }
+ }
+ else {
+ shi->ao[0]= 1.0f;
+ shi->ao[1]= 1.0f;
+ shi->ao[2]= 1.0f;
+ }
+}
+
+void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
+{
+ OcclusionTree *tree= re->occlusiontree;
+ PixStr ps;
+ OcclusionCache *cache;
+ OcclusionCacheSample *sample;
+ OccFace exclude;
+ ShadeInput *shi;
+ long *rd=NULL;
+ int *ro=NULL, *rp=NULL, *rz=NULL, onlyshadow;
+ int x, y, step = CACHE_STEP;
+
+ if(!tree->cache)
+ return;
+
+ cache= &tree->cache[pa->thread];
+ cache->w= pa->rectx;
+ cache->h= pa->recty;
+ cache->x= pa->disprect.xmin;
+ cache->y= pa->disprect.ymin;
+ cache->step= step;
+ cache->sample= MEM_callocN(sizeof(OcclusionCacheSample)*cache->w*cache->h, "OcclusionCacheSample");
+ sample= cache->sample;
+
+ if(re->osa) {
+ rd= pa->rectdaps;
+ }
+ else {
+ /* fake pixel struct for non-osa */
+ ps.next= NULL;
+ ps.mask= 0xFFFF;
+
+ ro= pa->recto;
+ rp= pa->rectp;
+ rz= pa->rectz;
+ }
+
+ /* compute a sample at every step pixels */
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, sample++, rd++, ro++, rp++, rz++) {
+ if(!(((x - pa->disprect.xmin + step) % step) == 0 || x == pa->disprect.xmax-1))
+ continue;
+ if(!(((y - pa->disprect.ymin + step) % step) == 0 || y == pa->disprect.ymax-1))
+ continue;
+
+ if(re->osa) {
+ if(!*rd) continue;
+
+ shade_samples_fill_with_ps(ssamp, (PixStr *)(*rd), x, y);
+ }
+ else {
+ if(!*rp) continue;
+
+ ps.obi= *ro;
+ ps.facenr= *rp;
+ ps.z= *rz;
+ shade_samples_fill_with_ps(ssamp, &ps, x, y);
+ }
+
+ shi= ssamp->shi;
+ if(shi->vlr) {
+ onlyshadow= (shi->mat->mode & MA_ONLYSHADOW);
+ exclude.obi= shi->obi - re->objectinstance;
+ exclude.facenr= shi->vlr->index;
+ sample_occ_tree(re, tree, &exclude, shi->co, shi->vno, shi->thread, onlyshadow, shi->ao);
+
+ VECCOPY(sample->co, shi->co);
+ VECCOPY(sample->n, shi->vno);
+ VECCOPY(sample->col, shi->ao);
+ sample->intensity= MAX3(sample->col[0], sample->col[1], sample->col[2]);
+ sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco);
+ sample->x= shi->xs;
+ sample->y= shi->ys;
+ sample->filled= 1;
+ }
+
+ if(re->test_break())
+ break;
+ }
+ }
+}
+
+void free_occ_samples(Render *re, RenderPart *pa)
+{
+ OcclusionTree *tree= re->occlusiontree;
+ OcclusionCache *cache;
+
+ if(tree->cache) {
+ cache= &tree->cache[pa->thread];
+
+ if(cache->sample)
+ MEM_freeN(cache->sample);
+
+ cache->w= 0;
+ cache->h= 0;
+ cache->step= 0;
+ }
+}
+
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 02396091a17..a3368f0496d 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -78,6 +78,7 @@
#include "envmap.h"
#include "initrender.h"
#include "shadbuf.h"
+#include "pixelblending.h"
#include "zbuf.h"
@@ -116,7 +117,7 @@ static struct ListBase RenderList= {NULL, NULL};
Render R;
/* commandline thread override */
-static int commandline_threads= 0;
+static int commandline_threads= -1;
/* ********* alloc and free ******** */
@@ -141,26 +142,23 @@ static void stats_background(RenderStats *rs)
float megs_used_memory= mem_in_use/(1024.0*1024.0);
char str[400], *spos= str;
- if(rs->convertdone) {
-
- spos+= sprintf(spos, "Fra:%d Mem:%.2fM ", G.scene->r.cfra, megs_used_memory);
-
- if(rs->curfield)
- spos+= sprintf(spos, "Field %d ", rs->curfield);
- if(rs->curblur)
- spos+= sprintf(spos, "Blur %d ", rs->curblur);
-
- if(rs->infostr) {
- spos+= sprintf(spos, "| %s", rs->infostr);
- }
- else {
- if(rs->tothalo)
- spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
- else
- spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->totlamp);
- }
- printf(str); printf("\n");
- }
+ spos+= sprintf(spos, "Fra:%d Mem:%.2fM ", G.scene->r.cfra, megs_used_memory);
+
+ if(rs->curfield)
+ spos+= sprintf(spos, "Field %d ", rs->curfield);
+ if(rs->curblur)
+ spos+= sprintf(spos, "Blur %d ", rs->curblur);
+
+ if(rs->infostr) {
+ spos+= sprintf(spos, "| %s", rs->infostr);
+ }
+ else {
+ if(rs->tothalo)
+ spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
+ else
+ spos+= sprintf(spos, "Sce: %s Ve:%d Fa:%d La:%d", G.scene->id.name+2, rs->totvert, rs->totface, rs->totlamp);
+ }
+ printf(str); printf("\n");
}
void RE_FreeRenderResult(RenderResult *res)
@@ -171,8 +169,9 @@ void RE_FreeRenderResult(RenderResult *res)
RenderLayer *rl= res->layers.first;
if(rl->rectf) MEM_freeN(rl->rectf);
- /* acolrect is optionally allocated in shade_tile, only free here since it can be used for drawing */
+ /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
if(rl->acolrect) MEM_freeN(rl->acolrect);
+ if(rl->scolrect) MEM_freeN(rl->scolrect);
while(rl->passes.first) {
RenderPass *rpass= rl->passes.first;
@@ -194,6 +193,22 @@ void RE_FreeRenderResult(RenderResult *res)
MEM_freeN(res);
}
+/* version that's compatible with fullsample buffers */
+static void free_render_result(ListBase *lb, RenderResult *rr)
+{
+ RenderResult *rrnext;
+
+ for(; rr; rr= rrnext) {
+ rrnext= rr->next;
+
+ if(lb && lb->first)
+ BLI_remlink(lb, rr);
+
+ RE_FreeRenderResult(rr);
+ }
+}
+
+
/* all layers except the active one get temporally pushed away */
static void push_render_result(Render *re)
{
@@ -330,6 +345,10 @@ static char *get_pass_name(int passtype, int channel)
if(channel==-1) return "IndexOB";
return "IndexOB.X";
}
+ if(passtype == SCE_PASS_MIST) {
+ if(channel==-1) return "Mist";
+ return "Mist.Z";
+ }
return "Unknown";
}
@@ -378,23 +397,25 @@ static int passtype_from_name(char *str)
if(strcmp(str, "IndexOB")==0)
return SCE_PASS_INDEXOB;
+ if(strcmp(str, "Mist")==0)
+ return SCE_PASS_MIST;
+
return 0;
}
-
-
-static void render_unique_exr_name(Render *re, char *str)
+static void render_unique_exr_name(Render *re, char *str, int sample)
{
char di[FILE_MAX], name[FILE_MAXFILE], fi[FILE_MAXFILE];
BLI_strncpy(di, G.sce, FILE_MAX);
BLI_splitdirstring(di, fi);
- sprintf(name, "%s_%s.exr", fi, re->scene->id.name+2);
- if(G.background)
- BLI_make_file_string("/", str, "/tmp/", name);
+
+ if(sample==0)
+ sprintf(name, "%s_%s.exr", fi, re->scene->id.name+2);
else
- BLI_make_file_string("/", str, U.tempdir, name);
-
+ sprintf(name, "%s_%s%d.exr", fi, re->scene->id.name+2, sample);
+
+ BLI_make_file_string("/", str, btempdir, name);
}
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
@@ -413,17 +434,22 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
}
else {
+ float *rect;
+ int x;
+
+ rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
+
if(passtype==SCE_PASS_VECTOR) {
- float *rect;
- int x;
-
/* initialize to max speed */
- rect= rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
+ rect= rpass->rect;
for(x= rectsize-1; x>=0; x--)
rect[x]= PASS_VECTOR_MAX;
}
- else
- rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
+ else if(passtype==SCE_PASS_Z) {
+ rect= rpass->rect;
+ for(x= rectsize-1; x>=0; x--)
+ rect[x]= 10e10;
+ }
}
}
@@ -497,6 +523,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
strcpy(rl->name, srl->name);
rl->lay= srl->lay;
+ rl->lay_zmask= srl->lay_zmask;
rl->layflag= srl->layflag;
rl->passflag= srl->passflag;
rl->pass_xor= srl->pass_xor;
@@ -526,22 +553,20 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
if(srl->passflag & SCE_PASS_SPEC)
render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
- if(re->r.mode & R_SHADOW)
- if(srl->passflag & SCE_PASS_SHADOW)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
- if(re->r.mode & R_RAYTRACE) {
- if(srl->passflag & SCE_PASS_AO)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
- if(srl->passflag & SCE_PASS_REFLECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
- if(srl->passflag & SCE_PASS_REFRACT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
- }
- if(re->r.mode & R_RADIO)
- if(srl->passflag & SCE_PASS_RADIO)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_RADIO);
+ if(srl->passflag & SCE_PASS_AO)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
+ if(srl->passflag & SCE_PASS_SHADOW)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
+ if(srl->passflag & SCE_PASS_REFLECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
+ if(srl->passflag & SCE_PASS_REFRACT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
+ if(srl->passflag & SCE_PASS_RADIO)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_RADIO);
if(srl->passflag & SCE_PASS_INDEXOB)
render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
+ if(srl->passflag & SCE_PASS_MIST)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
}
/* sss, previewrender and envmap don't do layers, so we make a default one */
@@ -576,14 +601,13 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
static int render_scene_needs_vector(Render *re)
{
- if(re->r.scemode & R_DOCOMP) {
- SceneRenderLayer *srl;
+ SceneRenderLayer *srl;
- for(srl= re->scene->r.layers.first; srl; srl= srl->next)
- if(!(srl->layflag & SCE_LAY_DISABLE))
- if(srl->passflag & SCE_PASS_VECTOR)
- return 1;
- }
+ for(srl= re->scene->r.layers.first; srl; srl= srl->next)
+ if(!(srl->layflag & SCE_LAY_DISABLE))
+ if(srl->passflag & SCE_PASS_VECTOR)
+ return 1;
+
return 0;
}
@@ -641,9 +665,8 @@ static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
}
-static void save_render_result_tile(Render *re, RenderPart *pa)
+static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
{
- RenderResult *rrpart= pa->result;
RenderLayer *rlp;
RenderPass *rpassp;
int offs, partx, party;
@@ -663,23 +686,23 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
if(rlp->rectf) {
int a, xstride= 4;
for(a=0; a<xstride; a++)
- IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride*pa->rectx, rlp->rectf+a + xstride*offs);
+ IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
}
/* passes are allocated in sync */
for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
int a, xstride= rpassp->channels;
for(a=0; a<xstride; a++)
- IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
- xstride, xstride*pa->rectx, rpassp->rect+a + xstride*offs);
+ IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
+ xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
}
}
party= rrpart->tilerect.ymin + rrpart->crop;
partx= rrpart->tilerect.xmin + rrpart->crop;
- IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
+ IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
BLI_unlock_thread(LOCK_IMAGE);
@@ -688,14 +711,17 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
static void save_empty_result_tiles(Render *re)
{
RenderPart *pa;
+ RenderResult *rr;
- IMB_exrtile_clear_channels(re->result->exrhandle);
+ for(rr= re->result; rr; rr= rr->next) {
+ IMB_exrtile_clear_channels(rr->exrhandle);
- for(pa= re->parts.first; pa; pa= pa->next) {
- if(pa->ready==0) {
- int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
- int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
- IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ if(pa->ready==0) {
+ int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
+ int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
+ IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
+ }
}
}
}
@@ -723,6 +749,8 @@ void RE_WriteRenderResult(RenderResult *rr, char *filename, int compress)
RenderLayer *rl;
RenderPass *rpass;
void *exrhandle= IMB_exr_get_handle();
+
+ BLI_make_existing_file(filename);
/* composite result */
if(rr->rectf) {
@@ -822,7 +850,7 @@ static void renderresult_add_names(RenderResult *rr)
/* only for temp buffer files, makes exact copy of render result */
-static void read_render_result(Render *re)
+static void read_render_result(Render *re, int sample)
{
RenderLayer *rl;
RenderPass *rpass;
@@ -833,13 +861,15 @@ static void read_render_result(Render *re)
RE_FreeRenderResult(re->result);
re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
- render_unique_exr_name(re, str);
+ render_unique_exr_name(re, str, sample);
if(IMB_exr_begin_read(exrhandle, str, &rectx, &recty)==0) {
IMB_exr_close(exrhandle);
printf("cannot read: %s\n", str);
return;
}
+ printf("read exr tmp file: %s\n", str);
+
if(rectx!=re->result->rectx || recty!=re->result->recty) {
printf("error in reading render result\n");
}
@@ -1023,7 +1053,7 @@ void RE_FreeAllRender(void)
/* what doesn't change during entire render sequence */
/* disprect is optional, if NULL it assumes full window render */
-void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect)
+void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy, rcti *disprect)
{
re->ok= TRUE; /* maybe flag */
@@ -1045,18 +1075,33 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
re->recty= winy;
}
- if(re->rectx < 2 || re->recty < 2) {
+ if(re->rectx < 2 || re->recty < 2 || (BKE_imtype_is_movie(rd->imtype) &&
+ (re->rectx < 16 || re->recty < 16) )) {
re->error("Image too small");
re->ok= 0;
}
else {
- /* check state variables, osa? */
- if(re->r.mode & (R_OSA)) {
- re->osa= re->r.osa;
- if(re->osa>16) re->osa= 16;
- }
- else re->osa= 0;
+ if(!(re->r.scemode & R_EXR_TILE_FILE))
+ re->r.scemode &= ~R_FULL_SAMPLE; /* clear, so we can use this flag for test both */
+
+ /* fullsample wants uniform osa levels */
+ if(source && (re->r.scemode & R_FULL_SAMPLE)) {
+ /* but, if source has no full sample we disable it */
+ if((source->r.scemode & R_FULL_SAMPLE)==0)
+ re->r.scemode &= ~R_FULL_SAMPLE;
+ else
+ re->r.osa= re->osa= source->osa;
+ }
+ else {
+ /* check state variables, osa? */
+ if(re->r.mode & (R_OSA)) {
+ re->osa= re->r.osa;
+ if(re->osa>16) re->osa= 16;
+ }
+ else re->osa= 0;
+ }
+
/* always call, checks for gamma, gamma tables and jitter too */
make_sample_tables(re);
@@ -1069,11 +1114,15 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
/* 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);
- if(commandline_threads>0 && commandline_threads<=BLENDER_MAX_THREADS)
+ if ((rd->mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+ re->r.threads = BLI_system_thread_count();
+ } else if(commandline_threads >= 1 && commandline_threads<=BLENDER_MAX_THREADS) {
re->r.threads= commandline_threads;
+ }
}
}
+/* part of external api, not called for regular render pipeline */
void RE_SetDispRect (struct Render *re, rcti *disprect)
{
re->disprect= *disprect;
@@ -1174,13 +1223,36 @@ static int render_display_draw_enabled(Render *re)
return 1;
}
+/* allocate osa new results for samples */
+static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop)
+{
+ int a;
+
+ if(re->osa==0)
+ return new_render_result(re, partrct, crop, RR_USEMEM);
+
+ for(a=0; a<re->osa; a++) {
+ RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM);
+ BLI_addtail(lb, rr);
+ rr->sample_nr= a;
+ }
+
+ return lb->first;
+}
+
+
+/* the main thread call, renders an entire part */
static void *do_part_thread(void *pa_v)
{
RenderPart *pa= pa_v;
/* need to return nicely all parts on esc */
if(R.test_break()==0) {
- pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM);
+
+ if(!R.sss_points && (R.r.scemode & R_FULL_SAMPLE))
+ pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop);
+ else
+ pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM);
if(R.sss_points)
zbufshade_sss_tile(pa);
@@ -1190,8 +1262,13 @@ static void *do_part_thread(void *pa_v)
zbufshade_tile(pa);
/* merge too on break! */
- if(R.result->exrhandle)
- save_render_result_tile(&R, pa);
+ if(R.result->exrhandle) {
+ RenderResult *rr, *rrpart;
+
+ for(rr= R.result, rrpart= pa->result; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
+ save_render_result_tile(rr, rrpart);
+
+ }
else if(render_display_draw_enabled(&R))
merge_render_result(R.result, pa->result);
}
@@ -1307,7 +1384,7 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
Mat4CpyMat4(R.winmat, re->winmat);
/* rotate database according to part coordinates */
- project_renderdata(re, projectverto, 1, -R.panodxp*phi);
+ project_renderdata(re, projectverto, 1, -R.panodxp*phi, 1);
R.panosi= sin(R.panodxp*phi);
R.panoco= cos(R.panodxp*phi);
}
@@ -1365,33 +1442,54 @@ static void print_part_stats(Render *re, RenderPart *pa)
re->i.infostr= NULL;
}
+/* make osa new results for samples */
+static RenderResult *new_full_sample_buffers_exr(Render *re)
+{
+ int a;
+
+ for(a=0; a<re->osa; a++) {
+ RenderResult *rr= new_render_result(re, &re->disprect, 0, 1);
+ BLI_addtail(&re->fullresult, rr);
+ rr->sample_nr= a;
+ }
+
+ return re->fullresult.first;
+}
+
static void threaded_tile_processor(Render *re)
{
ListBase threads;
RenderPart *pa, *nextpa;
- RenderResult *rr;
rctf viewplane= re->viewplane;
int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
- /* first step; the entire render result, or prepare exr buffer saving */
+ /* first step; free the entire render result, make new, and/or prepare exr buffer saving */
RE_FreeRenderResult(re->result);
- rr= re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & R_EXR_TILE_FILE);
- if(rr==NULL)
+ if(re->sss_points)
+ 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);
+
+ if(re->result==NULL)
return;
+
/* warning; no return here without closing exr file */
-// if(re->re->test_break())
-// return;
initparts(re);
- if(rr->exrhandle) {
+ if(re->result->exrhandle) {
+ RenderResult *rr;
char str[FILE_MAX];
- render_unique_exr_name(re, str);
+ for(rr= re->result; rr; rr= rr->next) {
+ render_unique_exr_name(re, str, rr->sample_nr);
- printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
- IMB_exrtile_begin_write(rr->exrhandle, str, rr->rectx, rr->recty, rr->rectx/re->xparts, rr->recty/re->yparts);
+ printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
+ IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
+ }
}
BLI_init_threads(&threads, do_part_thread, re->r.threads);
@@ -1446,7 +1544,7 @@ static void threaded_tile_processor(Render *re)
re->display_draw(pa->result, NULL);
print_part_stats(re, pa);
- RE_FreeRenderResult(pa->result);
+ free_render_result(&pa->fullresult, pa->result);
pa->result= NULL;
re->i.partsdone++;
hasdrawn= 1;
@@ -1470,11 +1568,20 @@ static void threaded_tile_processor(Render *re)
}
- if(rr->exrhandle) {
+ if(re->result->exrhandle) {
+ RenderResult *rr;
+
save_empty_result_tiles(re);
- IMB_exr_close(rr->exrhandle);
- rr->exrhandle= NULL;
- read_render_result(re);
+
+ for(rr= re->result; rr; rr= rr->next) {
+ IMB_exr_close(rr->exrhandle);
+ rr->exrhandle= NULL;
+ }
+
+ free_render_result(&re->fullresult, re->result);
+ re->result= NULL;
+
+ read_render_result(re, 0);
}
/* unset threadsafety */
@@ -1483,7 +1590,6 @@ static void threaded_tile_processor(Render *re)
BLI_end_threads(&threads);
freeparts(re);
re->viewplane= viewplane; /* restore viewplane, modified by pano render */
-
}
/* currently only called by preview renders and envmap */
@@ -1493,14 +1599,16 @@ void RE_TileProcessor(Render *re, int firsttile, int threaded)
re->i.partsdone= firsttile;
- re->i.starttime= PIL_check_seconds_timer();
+ if(!re->sss_points)
+ re->i.starttime= PIL_check_seconds_timer();
if(threaded)
threaded_tile_processor(re);
else
render_tile_processor(re, firsttile);
- re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
+ if(!re->sss_points)
+ re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(&re->i);
}
@@ -1808,14 +1916,18 @@ static void do_render_fields_blur_3d(Render *re)
static void render_scene(Render *re, Scene *sce, int cfra)
{
Render *resc= RE_NewRender(sce->id.name);
+ int winx= re->winx, winy= re->winy;
sce->r.cfra= cfra;
- /* initial setup */
- RE_InitState(resc, &sce->r, re->winx, re->winy, &re->disprect);
+ /* exception: scene uses own size (unfinished code) */
+ if(0) {
+ winx= (sce->r.size*sce->r.xsch)/100;
+ winy= (sce->r.size*sce->r.ysch)/100;
+ }
- /* this to enable this scene to create speed vectors */
- resc->r.scemode |= R_DOCOMP;
+ /* initial setup */
+ RE_InitState(resc, re, &sce->r, winx, winy, &re->disprect);
/* still unsure entity this... */
resc->scene= sce;
@@ -1831,10 +1943,15 @@ static void render_scene(Render *re, Scene *sce, int cfra)
do_render_fields_blur_3d(resc);
}
-static void ntree_render_scenes(Render *re)
+static void tag_scenes_for_render(Render *re)
{
bNode *node;
- int cfra= re->scene->r.cfra;
+ Scene *sce;
+
+ for(sce= G.main->scene.first; sce; sce= sce->id.next)
+ sce->id.flag &= ~LIB_DOIT;
+
+ re->scene->id.flag |= LIB_DOIT;
if(re->scene->nodetree==NULL) return;
@@ -1844,12 +1961,21 @@ static void ntree_render_scenes(Render *re)
if(node->id) {
if(node->id != (ID *)re->scene)
node->id->flag |= LIB_DOIT;
- else
- node->id->flag &= ~LIB_DOIT;
}
}
}
+}
+
+static void ntree_render_scenes(Render *re)
+{
+ bNode *node;
+ int cfra= re->scene->r.cfra;
+
+ if(re->scene->nodetree==NULL) return;
+
+ tag_scenes_for_render(re);
+
/* now foreach render-result node tagged we do a full render */
/* results are stored in a way compisitor will find it */
for(node= re->scene->nodetree->nodes.first; node; node= node->next) {
@@ -1895,6 +2021,115 @@ static void render_composit_stats(char *str)
R.i.infostr= NULL;
}
+
+/* reads all buffers, calls optional composite, merges in first result->rectf */
+static void do_merge_fullsample(Render *re, bNodeTree *ntree)
+{
+ float *rectf, filt[3][3];
+ int sample;
+
+ /* filtmask needs it */
+ R= *re;
+
+ /* we accumulate in here */
+ rectf= MEM_mapallocN(re->rectx*re->recty*sizeof(float)*4, "fullsample rgba");
+
+ for(sample=0; sample<re->r.osa; sample++) {
+ RenderResult rres;
+ int x, y, mask;
+
+ /* set all involved renders on the samplebuffers (first was done by render itself) */
+ /* also function below assumes this */
+ if(sample) {
+ Render *re1;
+
+ tag_scenes_for_render(re);
+ for(re1= RenderList.first; re1; re1= re1->next) {
+ if(re1->scene->id.flag & LIB_DOIT)
+ if(re1->r.scemode & R_FULL_SAMPLE)
+ read_render_result(re1, sample);
+ }
+ }
+
+ /* composite */
+ if(ntree) {
+ ntreeCompositTagRender(re->scene);
+ ntreeCompositTagAnimated(ntree);
+
+ ntreeCompositExecTree(ntree, &re->r, G.background==0);
+ }
+
+ /* ensure we get either composited result or the active layer */
+ RE_GetResultImage(re, &rres);
+
+ /* accumulate with filter, and clip */
+ mask= (1<<sample);
+ mask_array(mask, filt);
+
+ for(y=0; y<re->recty; y++) {
+ float *rf= rectf + 4*y*re->rectx;
+ float *col= rres.rectf + 4*y*re->rectx;
+
+ for(x=0; x<re->rectx; x++, rf+=4, col+=4) {
+ if(col[0]<0.0f) col[0]=0.0f; else if(col[0] > 1.0f) col[0]= 1.0f;
+ if(col[1]<0.0f) col[1]=0.0f; else if(col[1] > 1.0f) col[1]= 1.0f;
+ if(col[2]<0.0f) col[2]=0.0f; else if(col[2] > 1.0f) col[2]= 1.0f;
+
+ add_filt_fmask_coord(filt, col, rf, re->rectx, re->recty, x, y);
+ }
+ }
+
+ /* show stuff */
+ if(sample!=re->osa-1) {
+ /* weak... the display callback wants an active renderlayer pointer... */
+ re->result->renlay= render_get_active_layer(re, re->result);
+ re->display_draw(re->result, NULL);
+ }
+
+ if(re->test_break())
+ break;
+ }
+
+ if(re->result->rectf)
+ MEM_freeN(re->result->rectf);
+ re->result->rectf= rectf;
+}
+
+void RE_MergeFullSample(Render *re, Scene *sce, bNodeTree *ntree)
+{
+ Scene *scene;
+ bNode *node;
+
+ /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */
+
+ /* tag scenes unread */
+ for(scene= G.main->scene.first; scene; scene= scene->id.next)
+ scene->id.flag |= LIB_DOIT;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS) {
+ Scene *nodescene= (Scene *)node->id;
+
+ if(nodescene==NULL) nodescene= sce;
+ if(nodescene->id.flag & LIB_DOIT) {
+ nodescene->r.mode |= R_OSA; /* render struct needs tables */
+ RE_ReadRenderResult(sce, nodescene);
+ nodescene->id.flag &= ~LIB_DOIT;
+ }
+ }
+ }
+
+ /* own render result should be read/allocated */
+ if(G.scene->id.flag & LIB_DOIT)
+ RE_ReadRenderResult(G.scene, G.scene);
+
+ /* and now we can draw (result is there) */
+ re->display_init(re->result);
+ re->display_clear(re->result);
+
+ do_merge_fullsample(re, ntree);
+}
+
/* returns fully composited render-result on given time step (in RenderData) */
static void do_render_composite_fields_blur_3d(Render *re)
{
@@ -1914,11 +2149,14 @@ static void do_render_composite_fields_blur_3d(Render *re)
if(re->r.scemode & R_SINGLE_LAYER)
pop_render_result(re);
- if(!re->test_break() && ntree) {
- ntreeCompositTagRender(re->scene);
- ntreeCompositTagAnimated(ntree);
+ if(!re->test_break()) {
- if(re->r.scemode & R_DOCOMP) {
+ if(ntree) {
+ ntreeCompositTagRender(re->scene);
+ ntreeCompositTagAnimated(ntree);
+ }
+
+ if(ntree && re->r.scemode & R_DOCOMP) {
/* checks if there are render-result nodes that need scene */
if((re->r.scemode & R_SINGLE_LAYER)==0)
ntree_render_scenes(re);
@@ -1929,13 +2167,23 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* in case it was never initialized */
R.stats_draw= re->stats_draw;
- ntreeCompositExecTree(ntree, &re->r, G.background==0);
+ if(re->r.scemode & R_FULL_SAMPLE)
+ do_merge_fullsample(re, ntree);
+ else
+ ntreeCompositExecTree(ntree, &re->r, G.background==0);
+
ntree->stats_draw= NULL;
ntree->test_break= NULL;
}
}
+ else
+ if(re->r.scemode & R_FULL_SAMPLE)
+ do_merge_fullsample(re, NULL);
+
}
+ /* weak... the display callback wants an active renderlayer pointer... */
+ re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->result, NULL);
}
@@ -1998,8 +2246,17 @@ static void yafrayRender(Render *re)
RE_Database_Free(re);
}
+
+
#endif /* disable yafray */
+static void renderresult_stampinfo()
+{
+ RenderResult rres;
+ /* this is the basic trick to get the displayed float or char rect from render result */
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+ BKE_stamp_buf((unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4);
+}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -2035,7 +2292,14 @@ static void do_render_all_options(Render *re)
renderresult_add_names(re->result);
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
+
re->stats_draw(&re->i);
+
+ /* stamp image info here */
+ if((G.scene->r.scemode & R_STAMP_INFO) && (G.scene->r.stamp & R_STAMP_DRAW)) {
+ renderresult_stampinfo();
+ re->display_draw(re->result, NULL);
+ }
}
static int is_rendering_allowed(Render *re)
@@ -2069,14 +2333,20 @@ static int is_rendering_allowed(Render *re)
if(re->r.scemode & R_EXR_TILE_FILE) {
char str[FILE_MAX];
- render_unique_exr_name(re, str);
+ render_unique_exr_name(re, str, 0);
if (BLI_is_writable(str)==0) {
re->error("Can not save render buffers, check the temp default path");
return 0;
}
+ /* no osa + fullsample won't work... */
+ if(re->osa==0)
+ re->r.scemode &= ~R_FULL_SAMPLE;
+
}
+ else
+ re->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */
if(re->r.scemode & R_DOCOMP) {
if(re->scene->use_nodes) {
@@ -2161,29 +2431,21 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
disprect.ymax= winy;
}
- if(scene->r.scemode & R_EXR_TILE_FILE) {
- int partx= winx/scene->r.xparts, party= winy/scene->r.yparts;
-
- /* stupid exr tiles dont like different sizes */
- if(winx != partx*scene->r.xparts || winy != party*scene->r.yparts) {
- re->error("Sorry... exr tile saving only allowed with equally sized parts");
- return 0;
- }
- if((scene->r.mode & R_FIELDS) && (party & 1)) {
- re->error("Sorry... exr tile saving only allowed with equally sized parts");
- return 0;
- }
- }
+ re->scene= scene;
+
+ /* check all scenes involved */
+ tag_scenes_for_render(re);
if(scene->r.scemode & R_SINGLE_LAYER)
push_render_result(re);
- RE_InitState(re, &scene->r, winx, winy, &disprect);
+ RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
+ if(!re->ok) /* if an error was printed, abort */
+ return 0;
/* initstate makes new result, have to send changed tags around */
ntreeCompositTagRender(re->scene);
- re->scene= scene;
if(!is_rendering_allowed(re))
return 0;
@@ -2314,17 +2576,37 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
}
}
} else {
- for(scene->r.cfra= sfra;
- scene->r.cfra<=efra; scene->r.cfra++) {
+ for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
+ char name[FILE_MAX];
+ if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH) ) {
+ BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+ }
+
+ if (scene->r.mode & R_NO_OVERWRITE && BLI_exist(name)) {
+ printf("skipping existing frame \"%s\"\n", name);
+ continue;
+ }
+ if (scene->r.mode & R_TOUCH && !BLI_exist(name)) {
+ BLI_make_existing_file(name); /* makes the dir if its not there */
+ BLI_touch(name);
+ }
+
re->r.cfra= scene->r.cfra; /* weak.... */
-
+
do_render_all_options(re);
-
+
if(re->test_break() == 0) {
do_write_image_or_movie(re, scene, mh);
}
- if(G.afbreek==1) break;
+ if(G.afbreek==1) {
+ /* remove touched file */
+ if (scene->r.mode & R_TOUCH && BLI_exist(name) && BLI_filepathsize(name) == 0) {
+ BLI_delete(name, 0, 0);
+ }
+
+ break;
+ }
}
}
@@ -2340,7 +2622,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
/* note; repeated win/disprect calc... solve that nicer, also in compo */
-/* only temp file! */
+/* only the temp file! */
void RE_ReadRenderResult(Scene *scene, Scene *scenode)
{
Render *re;
@@ -2368,17 +2650,23 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
if(scenode)
scene= scenode;
- re= RE_NewRender(scene->id.name);
- RE_InitState(re, &scene->r, winx, winy, &disprect);
+ /* get render: it can be called from UI with draw callbacks */
+ re= RE_GetRender(scene->id.name);
+ if(re==NULL)
+ re= RE_NewRender(scene->id.name);
+ RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
re->scene= scene;
- read_render_result(re);
+ read_render_result(re, 0);
}
void RE_set_max_threads(int threads)
{
- if(threads>0 && threads<=BLENDER_MAX_THREADS)
+ if (threads==0) {
+ commandline_threads = BLI_system_thread_count();
+ } else if(threads>=1 && threads<=BLENDER_MAX_THREADS) {
commandline_threads= threads;
- else
+ } else {
printf("Error, threads has to be in range 1-%d\n", BLENDER_MAX_THREADS);
+ }
}
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 119cceaf3c2..0e453d461ab 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -31,6 +31,7 @@
*/
#include <math.h>
+#include <string.h>
/* global includes */
#include "BLI_arithb.h"
@@ -91,15 +92,6 @@ void addAlphaOverFloat(float *dest, float *source)
void addAlphaUnderFloat(float *dest, float *source)
{
float mul;
-
- if( (-RE_EMPTY_COLOR_FLOAT < dest[3])
- && (dest[3] < RE_EMPTY_COLOR_FLOAT) ) {
- dest[0] = source[0];
- dest[1] = source[1];
- dest[2] = source[2];
- dest[3] = source[3];
- return;
- }
mul= 1.0 - dest[3];
@@ -212,6 +204,121 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
}
}
+
+void mask_array(unsigned int mask, float filt[][3])
+{
+ float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
+ unsigned int maskand= (mask & 255);
+ unsigned int maskshift= (mask >>8);
+ int a, j;
+
+ for(j=2; j>=0; j--) {
+
+ a= j;
+
+ filt[2][2-j]= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+
+ a+=3;
+
+ filt[1][2-j]= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+
+ a+=3;
+
+ filt[0][2-j]= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
+ }
+}
+
+
+/*
+
+index ordering, scanline based:
+
+ --- --- ---
+| 2,0 | 2,1 | 2,2 |
+ --- --- ---
+| 1,0 | 1,1 | 1,2 |
+ --- --- ---
+| 0,0 | 0,1 | 0,2 |
+ --- --- ---
+*/
+
+void add_filt_fmask_coord(float filt[][3], float *col, float *rowbuf, int row_w, int col_h, int x, int y)
+{
+ float *fpoin[3][3];
+ float val, r, g, b, al, lfilt[3][3];
+
+ r= col[0];
+ g= col[1];
+ b= col[2];
+ al= col[3];
+
+ memcpy(lfilt, filt, sizeof(lfilt));
+
+ fpoin[0][1]= rowbuf-4*row_w;
+ fpoin[1][1]= rowbuf;
+ fpoin[2][1]= rowbuf+4*row_w;
+
+ fpoin[0][0]= fpoin[0][1] - 4;
+ fpoin[1][0]= fpoin[1][1] - 4;
+ fpoin[2][0]= fpoin[2][1] - 4;
+
+ fpoin[0][2]= fpoin[0][1] + 4;
+ fpoin[1][2]= fpoin[1][1] + 4;
+ fpoin[2][2]= fpoin[2][1] + 4;
+
+ if(y==0) {
+ fpoin[0][0]= fpoin[1][0];
+ fpoin[0][1]= fpoin[1][1];
+ fpoin[0][2]= fpoin[1][2];
+ /* filter needs the opposite value yes! */
+ lfilt[0][0]= filt[2][0];
+ lfilt[0][1]= filt[2][1];
+ lfilt[0][2]= filt[2][2];
+ }
+ else if(y==col_h-1) {
+ fpoin[2][0]= fpoin[1][0];
+ fpoin[2][1]= fpoin[1][1];
+ fpoin[2][2]= fpoin[1][2];
+
+ lfilt[2][0]= filt[0][0];
+ lfilt[2][1]= filt[0][1];
+ lfilt[2][2]= filt[0][2];
+ }
+
+ if(x==0) {
+ fpoin[2][0]= fpoin[2][1];
+ fpoin[1][0]= fpoin[1][1];
+ fpoin[0][0]= fpoin[0][1];
+
+ lfilt[2][0]= filt[2][2];
+ lfilt[1][0]= filt[1][2];
+ lfilt[0][0]= filt[0][2];
+ }
+ else if(x==row_w-1) {
+ fpoin[2][2]= fpoin[2][1];
+ fpoin[1][2]= fpoin[1][1];
+ fpoin[0][2]= fpoin[0][1];
+
+ lfilt[2][2]= filt[2][0];
+ lfilt[1][2]= filt[1][0];
+ lfilt[0][2]= filt[0][0];
+ }
+
+
+ /* loop unroll */
+#define MASKFILT(i, j) val= lfilt[i][j]; if(val!=0.0f) {float *fp= fpoin[i][j]; fp[0]+= val*r; fp[1]+= val*g; fp[2]+= val*b; fp[3]+= val*al; }
+
+ MASKFILT(0, 0)
+ MASKFILT(0, 1)
+ MASKFILT(0, 2)
+ MASKFILT(1, 0)
+ MASKFILT(1, 1)
+ MASKFILT(1, 2)
+ MASKFILT(2, 0)
+ MASKFILT(2, 1)
+ MASKFILT(2, 2)
+}
+
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize)
{
/* calc the value of mask */
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index cffed99c738..6871a066c4f 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -25,6 +25,7 @@
*/
#include <math.h>
+#include <string.h>
#include "BLI_arithb.h"
/* External modules: */
@@ -130,6 +131,12 @@ static void render_lighting_halo(HaloRen *har, float *colf)
if(lar->mode & LA_TEXTURE) {
ShadeInput shi;
+
+ /* Warning, This is not that nice, and possibly a bit slow,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
VECCOPY(shi.co, rco);
shi.osatex= 0;
do_lamp_tex(lar, lv, &shi, lacol);
@@ -175,7 +182,7 @@ static void render_lighting_halo(HaloRen *har, float *colf)
inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2];
if(inp>0.0) {
/* testshadowbuf==0.0 : 100% shadow */
- shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
if( shadfac>0.0 ) {
shadfac*= inp*soft*lar->energy;
ir -= shadfac;
@@ -212,7 +219,7 @@ static void render_lighting_halo(HaloRen *har, float *colf)
if(i> -0.41) { /* heuristic valua! */
shadfac= 1.0;
if(lar->shb) {
- shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp);
+ shadfac = testshadowbuf(&R, lar->shb, rco, dco, dco, inp, 0.0f);
if(shadfac==0.0) continue;
i*= shadfac;
}
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
deleted file mode 100644
index 128a4a900ec..00000000000
--- a/source/blender/render/intern/source/ray.c
+++ /dev/null
@@ -1,2469 +0,0 @@
-/**
- * $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) 1990-1998 NeoGeo BV.
- * All rights reserved.
- *
- * Contributors: 2004/2005 Blender Foundation, full recode
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-#include <float.h>
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_material_types.h"
-#include "DNA_lamp_types.h"
-
-#include "BKE_global.h"
-#include "BKE_node.h"
-#include "BKE_utildefines.h"
-
-#include "BLI_arithb.h"
-#include "BLI_rand.h"
-#include "BLI_jitter.h"
-
-#include "PIL_time.h"
-
-#include "render_types.h"
-#include "renderpipeline.h"
-#include "rendercore.h"
-#include "renderdatabase.h"
-#include "pixelblending.h"
-#include "pixelshading.h"
-#include "shading.h"
-#include "texture.h"
-
-#define DDA_SHADOW 0
-#define DDA_MIRROR 1
-#define DDA_SHADOW_TRA 2
-
-#define RAY_TRA 1
-#define RAY_TRAFLIP 2
-
-#define DEPTH_SHADOW_TRA 10
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
-/* only to be used here in this file, it's for speed */
-extern struct Render R;
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-/* ********** structs *************** */
-
-#define BRANCH_ARRAY 1024
-#define NODE_ARRAY 4096
-
-typedef struct Isect {
- float start[3], vec[3], end[3]; /* start+vec = end, in d3dda */
- float labda, u, v;
- struct VlakRen *vlr, *vlrcontr, *vlrorig; /* vlr is where to intersect with */
- short isect, mode; /* isect: which half of quad, mode: DDA_SHADOW, DDA_MIRROR, DDA_SHADOW_TRA */
- float ddalabda;
- float col[4]; /* RGBA for shadow_tra */
- int lay; /* -1 default, set for layer lamps */
- short vlrisect; /* flag whether vlrcontr was done or not */
- /* for optimize, last intersected face */
- VlakRen *vlr_last;
-} Isect;
-
-typedef struct Branch
-{
- struct Branch *b[8];
-} Branch;
-
-typedef struct OcVal
-{
- short ocx, ocy, ocz;
-} OcVal;
-
-typedef struct Node
-{
- struct VlakRen *v[8];
- struct OcVal ov[8];
- struct Node *next;
-} Node;
-
-
-/* ******** globals ***************** */
-
-/* just for statistics */
-static int raycount;
-static int accepted, rejected, coherent_ray;
-
-
-/* **************** ocval method ******************* */
-/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */
-
-#define OCVALRES 15
-#define BROW16(min, max) (((max)>=OCVALRES? 0xFFFF: (1<<(max+1))-1) - ((min>0)? ((1<<(min))-1):0) )
-
-static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov)
-{
- float min[3], max[3];
- int ocmin, ocmax;
-
- VECCOPY(min, v1);
- VECCOPY(max, v1);
- DO_MINMAX(v2, min, max);
- DO_MINMAX(v3, min, max);
- if(v4) {
- DO_MINMAX(v4, min, max);
- }
-
- ocmin= OCVALRES*(min[0]-x);
- ocmax= OCVALRES*(max[0]-x);
- ov->ocx= BROW16(ocmin, ocmax);
-
- ocmin= OCVALRES*(min[1]-y);
- ocmax= OCVALRES*(max[1]-y);
- ov->ocy= BROW16(ocmin, ocmax);
-
- ocmin= OCVALRES*(min[2]-z);
- ocmax= OCVALRES*(max[2]-z);
- ov->ocz= BROW16(ocmin, ocmax);
-
-}
-
-static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2)
-{
- int ocmin, ocmax;
-
- if(vec1[0]<vec2[0]) {
- ocmin= OCVALRES*(vec1[0] - xo);
- ocmax= OCVALRES*(vec2[0] - xo);
- } else {
- ocmin= OCVALRES*(vec2[0] - xo);
- ocmax= OCVALRES*(vec1[0] - xo);
- }
- ov->ocx= BROW16(ocmin, ocmax);
-
- if(vec1[1]<vec2[1]) {
- ocmin= OCVALRES*(vec1[1] - yo);
- ocmax= OCVALRES*(vec2[1] - yo);
- } else {
- ocmin= OCVALRES*(vec2[1] - yo);
- ocmax= OCVALRES*(vec1[1] - yo);
- }
- ov->ocy= BROW16(ocmin, ocmax);
-
- if(vec1[2]<vec2[2]) {
- ocmin= OCVALRES*(vec1[2] - zo);
- ocmax= OCVALRES*(vec2[2] - zo);
- } else {
- ocmin= OCVALRES*(vec2[2] - zo);
- ocmax= OCVALRES*(vec1[2] - zo);
- }
- ov->ocz= BROW16(ocmin, ocmax);
-}
-
-/* ************* octree ************** */
-
-static Branch *addbranch(Octree *oc, Branch *br, short ocb)
-{
- int index;
-
- if(br->b[ocb]) return br->b[ocb];
-
- oc->branchcount++;
- index= oc->branchcount>>12;
-
- if(oc->adrbranch[index]==NULL)
- oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch");
-
- if(oc->branchcount>= BRANCH_ARRAY*4096) {
- printf("error; octree branches full\n");
- oc->branchcount=0;
- }
-
- return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095);
-}
-
-static Node *addnode(Octree *oc)
-{
- int index;
-
- oc->nodecount++;
- index= oc->nodecount>>12;
-
- if(oc->adrnode[index]==NULL)
- oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode");
-
- if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) {
- printf("error; octree nodes full\n");
- oc->nodecount=0;
- }
-
- return oc->adrnode[index]+(oc->nodecount & 4095);
-}
-
-static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3])
-{
- static float nor[3], d;
- float fx, fy, fz;
-
- // init static vars
- if(vlr) {
- CalcNormFloat(rtf[0], rtf[1], rtf[2], nor);
- d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2];
- return 0;
- }
-
- fx= x;
- fy= y;
- fz= z;
-
- if((fx)*nor[0] + (fy)*nor[1] + (fz)*nor[2] + d > 0.0f) {
- if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
- if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
- if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
-
- if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
- if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
- if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
- if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
- }
- else {
- if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
- if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
- if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
-
- if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
- if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
- if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
- if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
- }
-
- return 0;
-}
-
-static void ocwrite(Octree *oc, VlakRen *vlr, short x, short y, short z, float rtf[][3])
-{
- Branch *br;
- Node *no;
- short a, oc0, oc1, oc2, oc3, oc4, oc5;
-
- x<<=2;
- y<<=1;
-
- br= oc->adrbranch[0];
-
- if(oc->ocres==512) {
- oc0= ((x & 1024)+(y & 512)+(z & 256))>>8;
- br= addbranch(oc, br, oc0);
- }
- if(oc->ocres>=256) {
- oc0= ((x & 512)+(y & 256)+(z & 128))>>7;
- br= addbranch(oc, br, oc0);
- }
- if(oc->ocres>=128) {
- oc0= ((x & 256)+(y & 128)+(z & 64))>>6;
- br= addbranch(oc, br, oc0);
- }
-
- oc0= ((x & 128)+(y & 64)+(z & 32))>>5;
- oc1= ((x & 64)+(y & 32)+(z & 16))>>4;
- oc2= ((x & 32)+(y & 16)+(z & 8))>>3;
- oc3= ((x & 16)+(y & 8)+(z & 4))>>2;
- oc4= ((x & 8)+(y & 4)+(z & 2))>>1;
- oc5= ((x & 4)+(y & 2)+(z & 1));
-
- br= addbranch(oc, br,oc0);
- br= addbranch(oc, br,oc1);
- br= addbranch(oc, br,oc2);
- br= addbranch(oc, br,oc3);
- br= addbranch(oc, br,oc4);
- no= (Node *)br->b[oc5];
- if(no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc));
-
- while(no->next) no= no->next;
-
- a= 0;
- if(no->v[7]) { /* node full */
- no->next= addnode(oc);
- no= no->next;
- }
- else {
- while(no->v[a]!=NULL) a++;
- }
-
- no->v[a]= vlr;
-
- if(vlr->v4)
- calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]);
- else
- calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x>>2, y>>1, z, &no->ov[a]);
-}
-
-static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3])
-{
- int ocx1,ocx2,ocy1,ocy2;
- int x,y,dx=0,dy=0;
- float ox1,ox2,oy1,oy2;
- float labda,labdao,labdax,labday,ldx,ldy;
-
- ocx1= rts[b1][c1];
- ocy1= rts[b1][c2];
- ocx2= rts[b2][c1];
- ocy2= rts[b2][c2];
-
- if(ocx1==ocx2 && ocy1==ocy2) {
- ocface[oc->ocres*ocx1+ocy1]= 1;
- return;
- }
-
- ox1= rtf[b1][c1];
- oy1= rtf[b1][c2];
- ox2= rtf[b2][c1];
- oy2= rtf[b2][c2];
-
- if(ox1!=ox2) {
- if(ox2-ox1>0.0f) {
- labdax= (ox1-ocx1-1.0f)/(ox1-ox2);
- ldx= -1.0f/(ox1-ox2);
- dx= 1;
- } else {
- labdax= (ox1-ocx1)/(ox1-ox2);
- ldx= 1.0f/(ox1-ox2);
- dx= -1;
- }
- } else {
- labdax=1.0f;
- ldx=0;
- }
-
- if(oy1!=oy2) {
- if(oy2-oy1>0.0f) {
- labday= (oy1-ocy1-1.0f)/(oy1-oy2);
- ldy= -1.0f/(oy1-oy2);
- dy= 1;
- } else {
- labday= (oy1-ocy1)/(oy1-oy2);
- ldy= 1.0f/(oy1-oy2);
- dy= -1;
- }
- } else {
- labday=1.0f;
- ldy=0;
- }
-
- x=ocx1; y=ocy1;
- labda= MIN2(labdax, labday);
-
- while(TRUE) {
-
- if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres);
- else ocface[oc->ocres*x+y]= 1;
-
- labdao=labda;
- if(labdax==labday) {
- labdax+=ldx;
- x+=dx;
- labday+=ldy;
- y+=dy;
- } else {
- if(labdax<labday) {
- labdax+=ldx;
- x+=dx;
- } else {
- labday+=ldy;
- y+=dy;
- }
- }
- labda=MIN2(labdax,labday);
- if(labda==labdao) break;
- if(labda>=1.0f) break;
- }
- ocface[oc->ocres*ocx2+ocy2]=1;
-}
-
-static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin)
-{
- short *ocmax;
- int a, x, y, y1, y2;
-
- ocmax=ocmin+3;
-
- for(x=ocmin[c1];x<=ocmax[c1];x++) {
- a= oc->ocres*x;
- for(y=ocmin[c2];y<=ocmax[c2];y++) {
- if(ocface[a+y]) {
- y++;
- while(ocface[a+y] && y!=ocmax[c2]) y++;
- for(y1=ocmax[c2];y1>y;y1--) {
- if(ocface[a+y1]) {
- for(y2=y;y2<=y1;y2++) ocface[a+y2]=1;
- y1=0;
- }
- }
- y=ocmax[c2];
- }
- }
- }
-}
-
-void freeoctree(Render *re)
-{
- Octree *oc= &re->oc;
-
-#if 0
- printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount);
- printf("raycount %d \n", raycount);
- printf("ray coherent %d \n", coherent_ray);
- printf("accepted %d rejected %d\n", accepted, rejected);
-#endif
-
- if(oc->adrbranch) {
- int a= 0;
- while(oc->adrbranch[a]) {
- MEM_freeN(oc->adrbranch[a]);
- oc->adrbranch[a]= NULL;
- a++;
- }
- MEM_freeN(oc->adrbranch);
- oc->adrbranch= NULL;
- }
- oc->branchcount= 0;
-
- if(oc->adrnode) {
- int a= 0;
- while(oc->adrnode[a]) {
- MEM_freeN(oc->adrnode[a]);
- oc->adrnode[a]= NULL;
- a++;
- }
- MEM_freeN(oc->adrnode);
- oc->adrnode= NULL;
- }
- oc->nodecount= 0;
-}
-
-void makeoctree(Render *re)
-{
- Octree *oc;
- VlakRen *vlr=NULL;
- VertRen *v1, *v2, *v3, *v4;
- float ocfac[3], t00, t01, t02;
- float rtf[4][3];
- int v;
- int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2;
- short rts[4][3], ocmin[6], *ocmax;
- char *ocface; // front, top, size view of face, to fill in
- double lasttime= PIL_check_seconds_timer();
-
- oc= &re->oc;
- oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches");
- oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes");
-
- ocmax= ocmin+3;
-
- /* only for debug info */
- raycount=0;
- accepted= 0;
- rejected= 0;
- coherent_ray= 0;
-
- /* fill main octree struct */
- oc->ocres= re->r.ocres;
- ocres2= oc->ocres*oc->ocres;
- INIT_MINMAX(oc->min, oc->max);
-
- /* first min max octree space */
- for(v=0;v<re->totvlak;v++) {
- if((v & 255)==0) vlr= re->vlaknodes[v>>8].vlak;
- else vlr++;
- if(vlr->mat->mode & MA_TRACEBLE) {
- if((vlr->mat->mode & MA_WIRE)==0) {
-
- DO_MINMAX(vlr->v1->co, oc->min, oc->max);
- DO_MINMAX(vlr->v2->co, oc->min, oc->max);
- DO_MINMAX(vlr->v3->co, oc->min, oc->max);
- if(vlr->v4) {
- DO_MINMAX(vlr->v4->co, oc->min, oc->max);
- }
- }
- }
- }
-
- if(oc->min[0] > oc->max[0]) return; /* empty octree */
-
- oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree");
-
- /* the lookup table, per face, for which nodes to fill in */
- ocface= MEM_callocN( 3*ocres2 + 8, "ocface");
- memset(ocface, 0, 3*ocres2);
-
- for(c=0;c<3;c++) { /* octree enlarge, still needed? */
- oc->min[c]-= 0.01f;
- oc->max[c]+= 0.01f;
- }
-
- t00= oc->max[0]-oc->min[0];
- t01= oc->max[1]-oc->min[1];
- t02= oc->max[2]-oc->min[2];
-
- /* this minus 0.1 is old safety... seems to be needed? */
- oc->ocfacx=ocfac[0]= (oc->ocres-0.1)/t00;
- oc->ocfacy=ocfac[1]= (oc->ocres-0.1)/t01;
- oc->ocfacz=ocfac[2]= (oc->ocres-0.1)/t02;
-
- oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */
-
- for(v=0; v<re->totvlak; v++) {
- if((v & 255)==0) {
- double time= PIL_check_seconds_timer();
-
- vlr= re->vlaknodes[v>>8].vlak;
- if(re->test_break())
- break;
- if(time-lasttime>1.0f) {
- char str[32];
- sprintf(str, "Filling Octree: %d", v);
- re->i.infostr= str;
- re->stats_draw(&re->i);
- re->i.infostr= NULL;
- lasttime= time;
- }
- }
- else vlr++;
-
- if(vlr->mat->mode & MA_TRACEBLE) {
- if((vlr->mat->mode & MA_WIRE)==0) {
-
- v1= vlr->v1;
- v2= vlr->v2;
- v3= vlr->v3;
- v4= vlr->v4;
-
- for(c=0;c<3;c++) {
- rtf[0][c]= (v1->co[c]-oc->min[c])*ocfac[c] ;
- rts[0][c]= (short)rtf[0][c];
- rtf[1][c]= (v2->co[c]-oc->min[c])*ocfac[c] ;
- rts[1][c]= (short)rtf[1][c];
- rtf[2][c]= (v3->co[c]-oc->min[c])*ocfac[c] ;
- rts[2][c]= (short)rtf[2][c];
- if(v4) {
- rtf[3][c]= (v4->co[c]-oc->min[c])*ocfac[c] ;
- rts[3][c]= (short)rtf[3][c];
- }
- }
-
- for(c=0;c<3;c++) {
- oc1= rts[0][c];
- oc2= rts[1][c];
- oc3= rts[2][c];
- if(v4==NULL) {
- ocmin[c]= MIN3(oc1,oc2,oc3);
- ocmax[c]= MAX3(oc1,oc2,oc3);
- }
- else {
- oc4= rts[3][c];
- ocmin[c]= MIN4(oc1,oc2,oc3,oc4);
- ocmax[c]= MAX4(oc1,oc2,oc3,oc4);
- }
- if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1;
- if(ocmin[c]<0) ocmin[c]=0;
- }
-
- if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) {
- ocwrite(oc, vlr, ocmin[0], ocmin[1], ocmin[2], rtf);
- }
- else {
-
- d2dda(oc, 0,1,0,1,ocface+ocres2,rts,rtf);
- d2dda(oc, 0,1,0,2,ocface,rts,rtf);
- d2dda(oc, 0,1,1,2,ocface+2*ocres2,rts,rtf);
- d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf);
- d2dda(oc, 1,2,0,2,ocface,rts,rtf);
- d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf);
- if(v4==NULL) {
- d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf);
- d2dda(oc, 2,0,0,2,ocface,rts,rtf);
- d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf);
- }
- else {
- d2dda(oc, 2,3,0,1,ocface+ocres2,rts,rtf);
- d2dda(oc, 2,3,0,2,ocface,rts,rtf);
- d2dda(oc, 2,3,1,2,ocface+2*ocres2,rts,rtf);
- d2dda(oc, 3,0,0,1,ocface+ocres2,rts,rtf);
- d2dda(oc, 3,0,0,2,ocface,rts,rtf);
- d2dda(oc, 3,0,1,2,ocface+2*ocres2,rts,rtf);
- }
- /* nothing todo with triangle..., just fills :) */
- filltriangle(oc, 0,1,ocface+ocres2,ocmin);
- filltriangle(oc, 0,2,ocface,ocmin);
- filltriangle(oc, 1,2,ocface+2*ocres2,ocmin);
-
- /* init static vars here */
- face_in_node(vlr, 0,0,0, rtf);
-
- for(x=ocmin[0];x<=ocmax[0];x++) {
- a= oc->ocres*x;
- for(y=ocmin[1];y<=ocmax[1];y++) {
- if(ocface[a+y+ocres2]) {
- b= oc->ocres*y+2*ocres2;
- for(z=ocmin[2];z<=ocmax[2];z++) {
- if(ocface[b+z] && ocface[a+z]) {
- if(face_in_node(NULL, x, y, z, rtf))
- ocwrite(oc, vlr, x,y,z, rtf);
- }
- }
- }
- }
- }
-
- /* same loops to clear octree, doubt it can be done smarter */
- for(x=ocmin[0];x<=ocmax[0];x++) {
- a= oc->ocres*x;
- for(y=ocmin[1];y<=ocmax[1];y++) {
- /* x-y */
- ocface[a+y+ocres2]= 0;
-
- b= oc->ocres*y + 2*ocres2;
- for(z=ocmin[2];z<=ocmax[2];z++) {
- /* y-z */
- ocface[b+z]= 0;
- /* x-z */
- ocface[a+z]= 0;
- }
- }
- }
- }
- }
- }
- }
-
- MEM_freeN(ocface);
- re->i.infostr= NULL;
- re->stats_draw(&re->i);
-}
-
-/* ************ raytracer **************** */
-
-/* only for self-intersecting test with current render face (where ray left) */
-static int intersection2(VlakRen *vlr, float r0, float r1, float r2, float rx1, float ry1, float rz1)
-{
- VertRen *v1,*v2,*v3,*v4=NULL;
- float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
- float m0, m1, m2, divdet, det, det1;
- float u1, v, u2;
-
- /* happens for baking with non existing face */
- if(vlr->v1==NULL)
- return 1;
-
- v1= vlr->v1;
- v2= vlr->v2;
- if(vlr->v4) {
- v3= vlr->v4;
- v4= vlr->v3;
- }
- else v3= vlr->v3;
-
- t00= v3->co[0]-v1->co[0];
- t01= v3->co[1]-v1->co[1];
- t02= v3->co[2]-v1->co[2];
- t10= v3->co[0]-v2->co[0];
- t11= v3->co[1]-v2->co[1];
- t12= v3->co[2]-v2->co[2];
-
- x0= t11*r2-t12*r1;
- x1= t12*r0-t10*r2;
- x2= t10*r1-t11*r0;
-
- divdet= t00*x0+t01*x1+t02*x2;
-
- m0= rx1-v3->co[0];
- m1= ry1-v3->co[1];
- m2= rz1-v3->co[2];
- det1= m0*x0+m1*x1+m2*x2;
-
- if(divdet!=0.0f) {
- u1= det1/divdet;
-
- if(u1<=0.0f) {
- det= t00*(m1*r2-m2*r1);
- det+= t01*(m2*r0-m0*r2);
- det+= t02*(m0*r1-m1*r0);
- v= det/divdet;
-
- if(v<=0.0f && (u1 + v) >= -1.0f) {
- return 1;
- }
- }
- }
-
- if(v4) {
-
- t20= v3->co[0]-v4->co[0];
- t21= v3->co[1]-v4->co[1];
- t22= v3->co[2]-v4->co[2];
-
- divdet= t20*x0+t21*x1+t22*x2;
- if(divdet!=0.0f) {
- u2= det1/divdet;
-
- if(u2<=0.0f) {
- det= t20*(m1*r2-m2*r1);
- det+= t21*(m2*r0-m0*r2);
- det+= t22*(m0*r1-m1*r0);
- v= det/divdet;
-
- if(v<=0.0f && (u2 + v) >= -1.0f) {
- return 2;
- }
- }
- }
- }
- return 0;
-}
-
-#if 0
-/* ray - line intersection */
-/* disabled until i got real & fast cylinder checking, this code doesnt work proper
-for faster strands */
-
-static int intersection_strand(Isect *is)
-{
- float v1[3], v2[3]; /* length of strand */
- float axis[3], rc[3], nor[3], radline, dist, len;
-
- /* radius strand */
- radline= 0.5f*VecLenf(is->vlr->v1->co, is->vlr->v2->co);
-
- VecMidf(v1, is->vlr->v1->co, is->vlr->v2->co);
- VecMidf(v2, is->vlr->v3->co, is->vlr->v4->co);
-
- VECSUB(rc, v1, is->start); /* vector from base ray to base cylinder */
- VECSUB(axis, v2, v1); /* cylinder axis */
-
- CROSS(nor, is->vec, axis);
- len= VecLength(nor);
-
- if(len<FLT_EPSILON)
- return 0;
-
- dist= INPR(rc, nor)/len; /* distance between ray and axis cylinder */
-
- if(dist<radline && dist>-radline) {
- float dot1, dot2, dot3, rlen, alen, div;
- float labda;
-
- /* calculating the intersection point of shortest distance */
- dot1 = INPR(rc, is->vec);
- dot2 = INPR(is->vec, axis);
- dot3 = INPR(rc, axis);
- rlen = INPR(is->vec, is->vec);
- alen = INPR(axis, axis);
-
- div = alen * rlen - dot2 * dot2;
- if (ABS(div) < FLT_EPSILON)
- return 0;
-
- labda = (dot1*dot2 - dot3*rlen)/div;
-
- radline/= sqrt(alen);
-
- /* labda: where on axis do we have closest intersection? */
- if(labda >= -radline && labda <= 1.0f+radline) {
- VlakRen *vlr= is->vlrorig;
- VertRen *v1= is->vlr->v1, *v2= is->vlr->v2, *v3= is->vlr->v3, *v4= is->vlr->v4;
- /* but we dont do shadows from faces sharing edge */
-
- if(v1==vlr->v1 || v2==vlr->v1 || v3==vlr->v1 || v4==vlr->v1) return 0;
- if(v1==vlr->v2 || v2==vlr->v2 || v3==vlr->v2 || v4==vlr->v2) return 0;
- if(v1==vlr->v3 || v2==vlr->v3 || v3==vlr->v3 || v4==vlr->v3) return 0;
- if(vlr->v4) {
- if(v1==vlr->v4 || v2==vlr->v4 || v3==vlr->v4 || v4==vlr->v4) return 0;
- }
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-/* ray - triangle or quad intersection */
-static int intersection(Isect *is)
-{
- VertRen *v1,*v2,*v3,*v4=NULL;
- float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
- float m0, m1, m2, divdet, det1;
- short ok=0;
-
- /* disabled until i got real & fast cylinder checking, this code doesnt work proper
- for faster strands */
-// if(is->mode==DDA_SHADOW && is->vlr->flag & R_STRAND)
-// return intersection_strand(is);
-
- v1= is->vlr->v1;
- v2= is->vlr->v2;
- if(is->vlr->v4) {
- v3= is->vlr->v4;
- v4= is->vlr->v3;
- }
- else v3= is->vlr->v3;
-
- t00= v3->co[0]-v1->co[0];
- t01= v3->co[1]-v1->co[1];
- t02= v3->co[2]-v1->co[2];
- t10= v3->co[0]-v2->co[0];
- t11= v3->co[1]-v2->co[1];
- t12= v3->co[2]-v2->co[2];
-
- r0= is->vec[0];
- r1= is->vec[1];
- r2= is->vec[2];
-
- x0= t12*r1-t11*r2;
- x1= t10*r2-t12*r0;
- x2= t11*r0-t10*r1;
-
- divdet= t00*x0+t01*x1+t02*x2;
-
- m0= is->start[0]-v3->co[0];
- m1= is->start[1]-v3->co[1];
- m2= is->start[2]-v3->co[2];
- det1= m0*x0+m1*x1+m2*x2;
-
- if(divdet!=0.0f) {
- float u;
-
- divdet= 1.0f/divdet;
- u= det1*divdet;
- if(u<0.0f && u>-1.0f) {
- float v, cros0, cros1, cros2;
-
- cros0= m1*t02-m2*t01;
- cros1= m2*t00-m0*t02;
- cros2= m0*t01-m1*t00;
- v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
-
- if(v<0.0f && (u + v) > -1.0f) {
- float labda;
- labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
-
- if(labda>0.0f && labda<1.0f) {
- is->labda= labda;
- is->u= u; is->v= v;
- ok= 1;
- }
- }
- }
- }
-
- if(ok==0 && v4) {
-
- t20= v3->co[0]-v4->co[0];
- t21= v3->co[1]-v4->co[1];
- t22= v3->co[2]-v4->co[2];
-
- divdet= t20*x0+t21*x1+t22*x2;
- if(divdet!=0.0f) {
- float u;
- divdet= 1.0f/divdet;
- u = det1*divdet;
-
- if(u<0.0f && u>-1.0f) {
- float v, cros0, cros1, cros2;
- cros0= m1*t22-m2*t21;
- cros1= m2*t20-m0*t22;
- cros2= m0*t21-m1*t20;
- v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
-
- if(v<0.0f && (u + v) > -1.0f) {
- float labda;
- labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
-
- if(labda>0.0f && labda<1.0f) {
- ok= 2;
- is->labda= labda;
- is->u= u; is->v= v;
- }
- }
- }
- }
- }
-
- if(ok) {
- is->isect= ok; // wich half of the quad
-
- if(is->mode!=DDA_SHADOW) {
- /* for mirror & tra-shadow: large faces can be filled in too often, this prevents
- a face being detected too soon... */
- if(is->labda > is->ddalabda) {
- return 0;
- }
- }
-
- /* when a shadow ray leaves a face, it can be little outside the edges of it, causing
- intersection to be detected in its neighbour face */
-
- if(is->vlrcontr && is->vlrisect); // optimizing, the tests below are not needed
- else if(is->labda< .1) {
- VlakRen *vlr= is->vlrorig;
- short de= 0;
-
- if(v1==vlr->v1 || v2==vlr->v1 || v3==vlr->v1 || v4==vlr->v1) de++;
- if(v1==vlr->v2 || v2==vlr->v2 || v3==vlr->v2 || v4==vlr->v2) de++;
- if(v1==vlr->v3 || v2==vlr->v3 || v3==vlr->v3 || v4==vlr->v3) de++;
- if(vlr->v4) {
- if(v1==vlr->v4 || v2==vlr->v4 || v3==vlr->v4 || v4==vlr->v4) de++;
- }
- if(de) {
-
- /* so there's a shared edge or vertex, let's intersect ray with vlr
- itself, if that's true we can safely return 1, otherwise we assume
- the intersection is invalid, 0 */
-
- if(is->vlrcontr==NULL) {
- is->vlrcontr= vlr;
- is->vlrisect= intersection2(vlr, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]);
- }
-
- if(is->vlrisect) return 1;
- return 0;
- }
- }
-
- return 1;
- }
-
- return 0;
-}
-
-/* check all faces in this node */
-static int testnode(Isect *is, Node *no, OcVal ocval)
-{
- VlakRen *vlr;
- short nr=0;
- OcVal *ov;
-
- /* return on any first hit */
- if(is->mode==DDA_SHADOW) {
-
- vlr= no->v[0];
- while(vlr) {
-
- if(is->vlrorig != vlr) {
-
- if(is->lay & vlr->lay) {
-
- ov= no->ov+nr;
- if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
- //accepted++;
- is->vlr= vlr;
-
- if(intersection(is)) {
- is->vlr_last= vlr;
- return 1;
- }
- }
- //else rejected++;
- }
- }
-
- nr++;
- if(nr==8) {
- no= no->next;
- if(no==0) return 0;
- nr=0;
- }
- vlr= no->v[nr];
- }
- }
- else { /* else mirror or glass or shadowtra, return closest face */
- Isect isect;
- int found= 0;
-
- is->labda= 1.0f; /* needed? */
- isect= *is; /* copy for sorting */
-
- vlr= no->v[0];
- while(vlr) {
-
- if(is->vlrorig != vlr) {
- /* I now... cpu cycle waste, might do smarter once */
- if(is->mode==DDA_MIRROR && (vlr->mat->mode & MA_ONLYCAST));
- else if(is->mode==DDA_SHADOW_TRA && !(is->lay & vlr->lay));
- else {
- ov= no->ov+nr;
- if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
- //accepted++;
-
- isect.vlr= vlr;
- if(intersection(&isect)) {
- if(isect.labda<is->labda) *is= isect;
- found= 1;
- }
- }
- //else rejected++;
- }
- }
-
- nr++;
- if(nr==8) {
- no= no->next;
- if(no==NULL) break;
- nr=0;
- }
- vlr= no->v[nr];
- }
-
- return found;
- }
-
- return 0;
-}
-
-/* find the Node for the octree coord x y z */
-static Node *ocread(int x, int y, int z)
-{
- Branch *br;
- int oc1;
-
- x<<=2;
- y<<=1;
-
- br= R.oc.adrbranch[0];
-
- if(R.oc.ocres==512) {
- oc1= ((x & 1024)+(y & 512)+(z & 256))>>8;
- br= br->b[oc1];
- if(br==NULL) {
- return NULL;
- }
- }
- if(R.oc.ocres>=256) {
- oc1= ((x & 512)+(y & 256)+(z & 128))>>7;
- br= br->b[oc1];
- if(br==NULL) {
- return NULL;
- }
- }
- if(R.oc.ocres>=128) {
- oc1= ((x & 256)+(y & 128)+(z & 64))>>6;
- br= br->b[oc1];
- if(br==NULL) {
- return NULL;
- }
- }
-
- oc1= ((x & 128)+(y & 64)+(z & 32))>>5;
- br= br->b[oc1];
- if(br) {
- oc1= ((x & 64)+(y & 32)+(z & 16))>>4;
- br= br->b[oc1];
- if(br) {
- oc1= ((x & 32)+(y & 16)+(z & 8))>>3;
- br= br->b[oc1];
- if(br) {
- oc1= ((x & 16)+(y & 8)+(z & 4))>>2;
- br= br->b[oc1];
- if(br) {
- oc1= ((x & 8)+(y & 4)+(z & 2))>>1;
- br= br->b[oc1];
- if(br) {
- oc1= ((x & 4)+(y & 2)+(z & 1));
- return (Node *)br->b[oc1];
- }
- }
- }
- }
- }
-
- return NULL;
-}
-
-static int cliptest(float p, float q, float *u1, float *u2)
-{
- float r;
-
- if(p<0.0f) {
- if(q<p) return 0;
- else if(q<0.0f) {
- r= q/p;
- if(r>*u2) return 0;
- else if(r>*u1) *u1=r;
- }
- }
- else {
- if(p>0.0f) {
- if(q<0.0f) return 0;
- else if(q<p) {
- r= q/p;
- if(r<*u1) return 0;
- else if(r<*u2) *u2=r;
- }
- }
- else if(q<0.0f) return 0;
- }
- return 1;
-}
-
-/* extensive coherence checks/storage cancels out the benefit of it, and gives errors... we
- need better methods, sample code commented out below (ton) */
-
-/*
-
-in top: static int coh_nodes[16*16*16][6];
-in makeoctree: memset(coh_nodes, 0, sizeof(coh_nodes));
-
-static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
-{
- short *sp;
-
- sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ];
- sp[0]= ocx1; sp[1]= ocy1; sp[2]= ocz1;
- sp[3]= ocx2; sp[4]= ocy2; sp[5]= ocz2;
-
-}
-
-static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
-{
- short *sp;
-
- sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ];
- if(sp[0]==ocx1 && sp[1]==ocy1 && sp[2]==ocz1 &&
- sp[3]==ocx2 && sp[4]==ocy2 && sp[5]==ocz2) return 1;
- return 0;
-}
-
-*/
-
-/* return 1: found valid intersection */
-/* starts with is->vlrorig */
-static int d3dda(Isect *is)
-{
- Node *no;
- OcVal ocval;
- float vec1[3], vec2[3];
- float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2;
- float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda;
- int dx,dy,dz;
- int xo,yo,zo,c1=0;
- int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2;
-
- /* clip with octree */
- if(R.oc.branchcount==0) return 0;
-
- /* do this before intersect calls */
- is->vlrcontr= NULL; /* to check shared edge */
- is->vlrisect= is->isect= 0; /* shared edge, quad half flag */
-
- /* only for shadow! */
- if(is->mode==DDA_SHADOW) {
-
- /* check with last intersected shadow face */
- if(is->vlr_last!=NULL && is->vlr_last!=is->vlrorig) {
- if(is->lay & is->vlr_last->lay) {
- is->vlr= is->vlr_last;
- VECSUB(is->vec, is->end, is->start);
- if(intersection(is)) return 1;
- }
- }
- }
-
- ldx= is->end[0] - is->start[0];
- u1= 0.0f;
- u2= 1.0f;
-
- /* clip with octree cube */
- if(cliptest(-ldx, is->start[0]-R.oc.min[0], &u1,&u2)) {
- if(cliptest(ldx, R.oc.max[0]-is->start[0], &u1,&u2)) {
- ldy= is->end[1] - is->start[1];
- if(cliptest(-ldy, is->start[1]-R.oc.min[1], &u1,&u2)) {
- if(cliptest(ldy, R.oc.max[1]-is->start[1], &u1,&u2)) {
- ldz= is->end[2] - is->start[2];
- if(cliptest(-ldz, is->start[2]-R.oc.min[2], &u1,&u2)) {
- if(cliptest(ldz, R.oc.max[2]-is->start[2], &u1,&u2)) {
- c1=1;
- if(u2<1.0f) {
- is->end[0]= is->start[0]+u2*ldx;
- is->end[1]= is->start[1]+u2*ldy;
- is->end[2]= is->start[2]+u2*ldz;
- }
- if(u1>0.0f) {
- is->start[0]+=u1*ldx;
- is->start[1]+=u1*ldy;
- is->start[2]+=u1*ldz;
- }
- }
- }
- }
- }
- }
- }
-
- if(c1==0) return 0;
-
- /* reset static variables in ocread */
- //ocread(R.oc.ocres, 0, 0);
-
- /* setup 3dda to traverse octree */
- ox1= (is->start[0]-R.oc.min[0])*R.oc.ocfacx;
- oy1= (is->start[1]-R.oc.min[1])*R.oc.ocfacy;
- oz1= (is->start[2]-R.oc.min[2])*R.oc.ocfacz;
- ox2= (is->end[0]-R.oc.min[0])*R.oc.ocfacx;
- oy2= (is->end[1]-R.oc.min[1])*R.oc.ocfacy;
- oz2= (is->end[2]-R.oc.min[2])*R.oc.ocfacz;
-
- ocx1= (int)ox1;
- ocy1= (int)oy1;
- ocz1= (int)oz1;
- ocx2= (int)ox2;
- ocy2= (int)oy2;
- ocz2= (int)oz2;
-
- /* for intersection */
- VECSUB(is->vec, is->end, is->start);
-
- if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) {
- no= ocread(ocx1, ocy1, ocz1);
- if(no) {
- /* exact intersection with node */
- vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1;
- vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2;
- calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2);
- is->ddalabda= 1.0f;
- if( testnode(is, no, ocval) ) return 1;
- }
- }
- else {
- //static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2;
- float dox, doy, doz;
- int eqval;
-
- /* calc labda en ld */
- dox= ox1-ox2;
- doy= oy1-oy2;
- doz= oz1-oz2;
-
- if(dox<-FLT_EPSILON) {
- ldx= -1.0f/dox;
- labdax= (ocx1-ox1+1.0f)*ldx;
- dx= 1;
- } else if(dox>FLT_EPSILON) {
- ldx= 1.0f/dox;
- labdax= (ox1-ocx1)*ldx;
- dx= -1;
- } else {
- labdax=1.0f;
- ldx=0;
- dx= 0;
- }
-
- if(doy<-FLT_EPSILON) {
- ldy= -1.0f/doy;
- labday= (ocy1-oy1+1.0f)*ldy;
- dy= 1;
- } else if(doy>FLT_EPSILON) {
- ldy= 1.0f/doy;
- labday= (oy1-ocy1)*ldy;
- dy= -1;
- } else {
- labday=1.0f;
- ldy=0;
- dy= 0;
- }
-
- if(doz<-FLT_EPSILON) {
- ldz= -1.0f/doz;
- labdaz= (ocz1-oz1+1.0f)*ldz;
- dz= 1;
- } else if(doz>FLT_EPSILON) {
- ldz= 1.0f/doz;
- labdaz= (oz1-ocz1)*ldz;
- dz= -1;
- } else {
- labdaz=1.0f;
- ldz=0;
- dz= 0;
- }
-
- xo=ocx1; yo=ocy1; zo=ocz1;
- labdao= ddalabda= MIN3(labdax,labday,labdaz);
-
- vec2[0]= ox1;
- vec2[1]= oy1;
- vec2[2]= oz1;
-
- /* this loop has been constructed to make sure the first and last node of ray
- are always included, even when ddalabda==1.0f or larger */
-
- while(TRUE) {
-
- no= ocread(xo, yo, zo);
- if(no) {
-
- /* calculate ray intersection with octree node */
- VECCOPY(vec1, vec2);
- // dox,y,z is negative
- vec2[0]= ox1-ddalabda*dox;
- vec2[1]= oy1-ddalabda*doy;
- vec2[2]= oz1-ddalabda*doz;
- calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
-
- is->ddalabda= ddalabda;
- if( testnode(is, no, ocval) ) return 1;
- }
-
- labdao= ddalabda;
-
- /* traversing ocree nodes need careful detection of smallest values, with proper
- exceptions for equal labdas */
- eqval= (labdax==labday);
- if(labday==labdaz) eqval += 2;
- if(labdax==labdaz) eqval += 4;
-
- if(eqval) { // only 4 cases exist!
- if(eqval==7) { // x=y=z
- xo+=dx; labdax+=ldx;
- yo+=dy; labday+=ldy;
- zo+=dz; labdaz+=ldz;
- }
- else if(eqval==1) { // x=y
- if(labday < labdaz) {
- xo+=dx; labdax+=ldx;
- yo+=dy; labday+=ldy;
- }
- else {
- zo+=dz; labdaz+=ldz;
- }
- }
- else if(eqval==2) { // y=z
- if(labdax < labday) {
- xo+=dx; labdax+=ldx;
- }
- else {
- yo+=dy; labday+=ldy;
- zo+=dz; labdaz+=ldz;
- }
- }
- else { // x=z
- if(labday < labdax) {
- yo+=dy; labday+=ldy;
- }
- else {
- xo+=dx; labdax+=ldx;
- zo+=dz; labdaz+=ldz;
- }
- }
- }
- else { // all three different, just three cases exist
- eqval= (labdax<labday);
- if(labday<labdaz) eqval += 2;
- if(labdax<labdaz) eqval += 4;
-
- if(eqval==7 || eqval==5) { // x smallest
- xo+=dx; labdax+=ldx;
- }
- else if(eqval==2 || eqval==6) { // y smallest
- yo+=dy; labday+=ldy;
- }
- else { // z smallest
- zo+=dz; labdaz+=ldz;
- }
-
- }
-
- ddalabda=MIN3(labdax,labday,labdaz);
- if(ddalabda==labdao) break;
- /* to make sure the last node is always checked */
- if(labdao>=1.0f) break;
- }
- }
-
- /* reached end, no intersections found */
- is->vlr_last= NULL;
- return 0;
-}
-
-
-static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
-{
- VlakRen *vlr= is->vlr;
- int osatex= 0, norflip;
-
- /* set up view vector */
- VECCOPY(shi->view, is->vec);
-
- /* render co */
- shi->co[0]= is->start[0]+is->labda*(shi->view[0]);
- shi->co[1]= is->start[1]+is->labda*(shi->view[1]);
- shi->co[2]= is->start[2]+is->labda*(shi->view[2]);
-
- Normalize(shi->view);
-
- shi->vlr= vlr;
- shi->mat= vlr->mat;
- memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
- shi->har= shi->mat->har;
-
- // Osa structs we leave unchanged now
- SWAP(int, osatex, shi->osatex);
-
- shi->dxco[0]= shi->dxco[1]= shi->dxco[2]= 0.0f;
- shi->dyco[0]= shi->dyco[1]= shi->dyco[2]= 0.0f;
-
- // but, set Osa stuff to zero where it can confuse texture code
- if(shi->mat->texco & (TEXCO_NORM|TEXCO_REFL) ) {
- shi->dxno[0]= shi->dxno[1]= shi->dxno[2]= 0.0f;
- shi->dyno[0]= shi->dyno[1]= shi->dyno[2]= 0.0f;
- }
-
- /* face normal, check for flip, need to set puno here */
- norflip= (vlr->n[0]*shi->view[0]+vlr->n[1]*shi->view[1]+vlr->n[2]*shi->view[2]) < 0.0f;
-
- if(norflip)
- shi->puno= vlr->puno ^ 15;// only flip lower 4 bits
- else
- shi->puno= vlr->puno;
-
- if(vlr->v4) {
- if(is->isect==2)
- shade_input_set_triangle_i(shi, vlr, 2, 1, 3);
- else
- shade_input_set_triangle_i(shi, vlr, 0, 1, 3);
- }
- else {
- shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
- }
-
- /* shade_input_set_triangle_i() sets facenor, now we flip */
- if(norflip) {
- shi->facenor[0]= -vlr->n[0];
- shi->facenor[1]= -vlr->n[1];
- shi->facenor[2]= -vlr->n[2];
- }
-
- shi->u= is->u;
- shi->v= is->v;
- shi->dx_u= shi->dx_v= shi->dy_u= shi->dy_v= 0.0f;
- shade_input_set_normals(shi);
- shade_input_set_shade_texco(shi);
-
- if(is->mode==DDA_SHADOW_TRA)
- shade_color(shi, shr);
- else {
- if(shi->mat->nodetree && shi->mat->use_nodes) {
- ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
- shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
- }
- else
- shade_material_loop(shi, shr);
-
- /* raytrace likes to separate the spec color */
- VECSUB(shr->diff, shr->combined, shr->spec);
- }
-
- SWAP(int, osatex, shi->osatex); // XXXXX!!!!
-
-}
-
-static int refraction(float *refract, float *n, float *view, float index)
-{
- float dot, fac;
-
- VECCOPY(refract, view);
-
- dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
-
- if(dot>0.0f) {
- index = 1.0f/index;
- fac= 1.0f - (1.0f - dot*dot)*index*index;
- if(fac<= 0.0f) return 0;
- fac= -dot*index + sqrt(fac);
- }
- else {
- fac= 1.0f - (1.0f - dot*dot)*index*index;
- if(fac<= 0.0f) return 0;
- fac= -dot*index - sqrt(fac);
- }
-
- refract[0]= index*view[0] + fac*n[0];
- refract[1]= index*view[1] + fac*n[1];
- refract[2]= index*view[2] + fac*n[2];
-
- return 1;
-}
-
-/* orn = original face normal */
-static void reflection(float *ref, float *n, float *view, float *orn)
-{
- float f1;
-
- f1= -2.0f*(n[0]*view[0]+ n[1]*view[1]+ n[2]*view[2]);
-
- ref[0]= (view[0]+f1*n[0]);
- ref[1]= (view[1]+f1*n[1]);
- ref[2]= (view[2]+f1*n[2]);
-
- if(orn) {
- /* test phong normals, then we should prevent vector going to the back */
- f1= ref[0]*orn[0]+ ref[1]*orn[1]+ ref[2]*orn[2];
- if(f1>0.0f) {
- f1+= .01f;
- ref[0]-= f1*orn[0];
- ref[1]-= f1*orn[1];
- ref[2]-= f1*orn[2];
- }
- }
-}
-
-#if 0
-static void color_combine(float *result, float fac1, float fac2, float *col1, float *col2)
-{
- float col1t[3], col2t[3];
-
- col1t[0]= sqrt(col1[0]);
- col1t[1]= sqrt(col1[1]);
- col1t[2]= sqrt(col1[2]);
- col2t[0]= sqrt(col2[0]);
- col2t[1]= sqrt(col2[1]);
- col2t[2]= sqrt(col2[2]);
-
- result[0]= (fac1*col1t[0] + fac2*col2t[0]);
- result[0]*= result[0];
- result[1]= (fac1*col1t[1] + fac2*col2t[1]);
- result[1]*= result[1];
- result[2]= (fac1*col1t[2] + fac2*col2t[2]);
- result[2]*= result[2];
-}
-#endif
-
-static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
-{
- float dx, dy, dz, d, p;
-
- if (0 == (shi->mat->mode & (MA_RAYTRANSP|MA_ZTRA)))
- return -1;
-
- if (shi->mat->tx_limit <= 0.0f) {
- d= 1.0f;
- }
- else {
- /* shi.co[] calculated by shade_ray() */
- dx= shi->co[0] - is->start[0];
- dy= shi->co[1] - is->start[1];
- dz= shi->co[2] - is->start[2];
- d= sqrt(dx*dx+dy*dy+dz*dz);
- if (d > shi->mat->tx_limit)
- d= shi->mat->tx_limit;
-
- p = shi->mat->tx_falloff;
- if(p < 0.0f) p= 0.0f;
- else if (p > 10.0f) p= 10.0f;
-
- shr->alpha *= pow(d, p);
- if (shr->alpha > 1.0f)
- shr->alpha= 1.0f;
- }
-
- return d;
-}
-
-/* the main recursive tracer itself */
-static void traceray(ShadeInput *origshi, short depth, float *start, float *vec, float *col, VlakRen *vlr, int traflag)
-{
- ShadeInput shi;
- ShadeResult shr;
- Isect isec;
- float f, f1, fr, fg, fb;
- float ref[3];
-
- VECCOPY(isec.start, start);
- isec.end[0]= start[0]+R.oc.ocsize*vec[0];
- isec.end[1]= start[1]+R.oc.ocsize*vec[1];
- isec.end[2]= start[2]+R.oc.ocsize*vec[2];
- isec.mode= DDA_MIRROR;
- isec.vlrorig= vlr;
-
- if( d3dda(&isec) ) {
- float d= 1.0f;
-
- shi.mask= origshi->mask;
- shi.osatex= origshi->osatex;
- shi.depth= 1; /* only used to indicate tracing */
- shi.thread= origshi->thread;
- shi.sample= 0;
- shi.xs= origshi->xs;
- shi.ys= origshi->ys;
- shi.lay= origshi->lay;
- shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
- shi.combinedflag= 0xFFFFFF; /* ray trace does all options */
- shi.do_preview= 0;
- shi.light_override= origshi->light_override;
- shi.mat_override= origshi->mat_override;
-
- memset(&shr, 0, sizeof(ShadeResult));
-
- shade_ray(&isec, &shi, &shr);
- if (traflag & RAY_TRA)
- d= shade_by_transmission(&isec, &shi, &shr);
-
- if(depth>0) {
-
- if(shi.mat->mode_l & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha < 1.0f) {
- float nf, f, f1, refract[3], tracol[4];
-
- tracol[0]= shi.r;
- tracol[1]= shi.g;
- tracol[2]= shi.b;
- tracol[3]= col[3]; // we pass on and accumulate alpha
-
- if(shi.mat->mode & MA_RAYTRANSP) {
- /* odd depths: use normal facing viewer, otherwise flip */
- if(traflag & RAY_TRAFLIP) {
- float norm[3];
- norm[0]= - shi.vn[0];
- norm[1]= - shi.vn[1];
- norm[2]= - shi.vn[2];
- if (!refraction(refract, norm, shi.view, shi.ang))
- reflection(refract, norm, shi.view, shi.vn);
- }
- else {
- if (!refraction(refract, shi.vn, shi.view, shi.ang))
- reflection(refract, shi.vn, shi.view, shi.vn);
- }
- traflag |= RAY_TRA;
- traceray(origshi, depth-1, shi.co, refract, tracol, shi.vlr, traflag ^ RAY_TRAFLIP);
- }
- else
- traceray(origshi, depth-1, shi.co, shi.view, tracol, shi.vlr, 0);
-
- f= shr.alpha; f1= 1.0f-f;
- nf= d * shi.mat->filter;
- fr= 1.0f+ nf*(shi.r-1.0f);
- fg= 1.0f+ nf*(shi.g-1.0f);
- fb= 1.0f+ nf*(shi.b-1.0f);
- shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0];
- shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1];
- shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2];
-
- shr.spec[0] *=f;
- shr.spec[1] *=f;
- shr.spec[2] *=f;
-
- col[3]= f1*tracol[3] + f;
- }
- else
- col[3]= 1.0f;
-
- if(shi.mat->mode_l & MA_RAYMIRROR) {
- f= shi.ray_mirror;
- if(f!=0.0f) f*= fresnel_fac(shi.view, shi.vn, shi.mat->fresnel_mir_i, shi.mat->fresnel_mir);
- }
- else f= 0.0f;
-
- if(f!=0.0f) {
- float mircol[4];
-
- reflection(ref, shi.vn, shi.view, NULL);
- traceray(origshi, depth-1, shi.co, ref, mircol, shi.vlr, 0);
-
- f1= 1.0f-f;
-
- /* combine */
- //color_combine(col, f*fr*(1.0f-shr.spec[0]), f1, col, shr.diff);
- //col[0]+= shr.spec[0];
- //col[1]+= shr.spec[1];
- //col[2]+= shr.spec[2];
-
- fr= shi.mirr;
- fg= shi.mirg;
- fb= shi.mirb;
-
- col[0]= f*fr*(1.0f-shr.spec[0])*mircol[0] + f1*shr.diff[0] + shr.spec[0];
- col[1]= f*fg*(1.0f-shr.spec[1])*mircol[1] + f1*shr.diff[1] + shr.spec[1];
- col[2]= f*fb*(1.0f-shr.spec[2])*mircol[2] + f1*shr.diff[2] + shr.spec[2];
- }
- else {
- col[0]= shr.diff[0] + shr.spec[0];
- col[1]= shr.diff[1] + shr.spec[1];
- col[2]= shr.diff[2] + shr.spec[2];
- }
- }
- else {
- col[0]= shr.diff[0] + shr.spec[0];
- col[1]= shr.diff[1] + shr.spec[1];
- col[2]= shr.diff[2] + shr.spec[2];
- }
-
- }
- else { /* sky */
- VECCOPY(shi.view, vec);
- Normalize(shi.view);
-
- shadeSkyView(col, isec.start, shi.view, NULL);
- }
-}
-
-/* **************** jitter blocks ********** */
-
-/* calc distributed planar energy */
-
-static void DP_energy(float *table, float *vec, int tot, float xsize, float ysize)
-{
- int x, y, a;
- float *fp, force[3], result[3];
- float dx, dy, dist, min;
-
- min= MIN2(xsize, ysize);
- min*= min;
- result[0]= result[1]= 0.0f;
-
- for(y= -1; y<2; y++) {
- dy= ysize*y;
- for(x= -1; x<2; x++) {
- dx= xsize*x;
- fp= table;
- for(a=0; a<tot; a++, fp+= 2) {
- force[0]= vec[0] - fp[0]-dx;
- force[1]= vec[1] - fp[1]-dy;
- dist= force[0]*force[0] + force[1]*force[1];
- if(dist < min && dist>0.0f) {
- result[0]+= force[0]/dist;
- result[1]+= force[1]/dist;
- }
- }
- }
- }
- vec[0] += 0.1*min*result[0]/(float)tot;
- vec[1] += 0.1*min*result[1]/(float)tot;
- // cyclic clamping
- vec[0]= vec[0] - xsize*floor(vec[0]/xsize + 0.5);
- vec[1]= vec[1] - ysize*floor(vec[1]/ysize + 0.5);
-}
-
-// random offset of 1 in 2
-static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy)
-{
- float dsizex= sizex*ofsx;
- float dsizey= sizey*ofsy;
- float hsizex= 0.5*sizex, hsizey= 0.5*sizey;
- int x;
-
- for(x=tot; x>0; x--, jitter1+=2, jitter2+=2) {
- jitter2[0]= jitter1[0] + dsizex;
- jitter2[1]= jitter1[1] + dsizey;
- if(jitter2[0] > hsizex) jitter2[0]-= sizex;
- if(jitter2[1] > hsizey) jitter2[1]-= sizey;
- }
-}
-
-/* called from convertBlenderScene.c */
-/* we do this in advance to get consistant random, not alter the render seed, and be threadsafe */
-void init_jitter_plane(LampRen *lar)
-{
- float *fp;
- int x, iter=12, tot= lar->ray_totsamp;
-
- /* at least 4, or max threads+1 tables */
- if(BLENDER_MAX_THREADS < 4) x= 4;
- else x= BLENDER_MAX_THREADS+1;
- fp= lar->jitter= MEM_mallocN(x*tot*2*sizeof(float), "lamp jitter tab");
-
- /* set per-lamp fixed seed */
- BLI_srandom(tot);
-
- /* fill table with random locations, area_size large */
- for(x=0; x<tot; x++, fp+=2) {
- fp[0]= (BLI_frand()-0.5)*lar->area_size;
- fp[1]= (BLI_frand()-0.5)*lar->area_sizey;
- }
-
- while(iter--) {
- fp= lar->jitter;
- for(x=tot; x>0; x--, fp+=2) {
- DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey);
- }
- }
-
- /* create the dithered tables (could just check lamp type!) */
- jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.0f);
- jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.5f);
- jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0f, 0.5f);
-}
-
-/* table around origin, -0.5*size to 0.5*size */
-static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
-{
- int tot;
-
- tot= lar->ray_totsamp;
-
- if(lar->ray_samp_type & LA_SAMP_JITTER) {
- /* made it threadsafe */
-
- if(lar->xold[thread]!=xs || lar->yold[thread]!=ys) {
- jitter_plane_offset(lar->jitter, lar->jitter+2*(thread+1)*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(thread), BLI_thread_frand(thread));
- lar->xold[thread]= xs;
- lar->yold[thread]= ys;
- }
- return lar->jitter+2*(thread+1)*tot;
- }
- if(lar->ray_samp_type & LA_SAMP_DITHER) {
- return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1));
- }
-
- return lar->jitter;
-}
-
-
-/* ***************** main calls ************** */
-
-
-/* extern call from render loop */
-void ray_trace(ShadeInput *shi, ShadeResult *shr)
-{
- VlakRen *vlr;
- float i, f, f1, fr, fg, fb, vec[3], mircol[4], tracol[4];
- float diff[3];
- int do_tra, do_mir;
-
- do_tra= ((shi->mat->mode & (MA_RAYTRANSP)) && shr->alpha!=1.0f);
- do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f);
- vlr= shi->vlr;
-
- /* raytrace mirror amd refract like to separate the spec color */
- if(shi->combinedflag & SCE_PASS_SPEC)
- VECSUB(diff, shr->combined, shr->spec) /* no ; */
- else
- VECCOPY(diff, shr->combined);
-
- if(do_tra) {
- float refract[3];
- float olddiff[3];
-
- tracol[3]= shr->alpha;
-
- refraction(refract, shi->vn, shi->view, shi->ang);
- traceray(shi, shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, RAY_TRA|RAY_TRAFLIP);
-
- f= shr->alpha; f1= 1.0f-f;
- fr= 1.0f+ shi->mat->filter*(shi->r-1.0f);
- fg= 1.0f+ shi->mat->filter*(shi->g-1.0f);
- fb= 1.0f+ shi->mat->filter*(shi->b-1.0f);
-
- /* for refract pass */
- VECCOPY(olddiff, diff);
-
- diff[0]= f*diff[0] + f1*fr*tracol[0];
- diff[1]= f*diff[1] + f1*fg*tracol[1];
- diff[2]= f*diff[2] + f1*fb*tracol[2];
-
- if(shi->passflag & SCE_PASS_REFRACT)
- VECSUB(shr->refr, diff, olddiff);
-
- if(shi->combinedflag & SCE_PASS_REFRACT)
- VECCOPY(olddiff, diff);
-
- shr->alpha= tracol[3];
- }
-
- if(do_mir) {
-
- i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir);
- if(i!=0.0f) {
-
- fr= i*shi->mirr;
- fg= i*shi->mirg;
- fb= i*shi->mirb;
-
- if(vlr->flag & R_SMOOTH)
- reflection(vec, shi->vn, shi->view, shi->facenor);
- else
- reflection(vec, shi->vn, shi->view, NULL);
-
- traceray(shi, shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, 0);
-
- if(shi->passflag & SCE_PASS_REFLECT) {
- /* mirror pass is not blocked out with spec */
- shr->refl[0]= fr*mircol[0] - fr*diff[0];
- shr->refl[1]= fg*mircol[1] - fg*diff[1];
- shr->refl[2]= fb*mircol[2] - fb*diff[2];
- }
-
- if(shi->combinedflag & SCE_PASS_REFLECT) {
-
- f= fr*(1.0f-shr->spec[0]); f1= 1.0f-i;
- diff[0]= f*mircol[0] + f1*diff[0];
-
- f= fg*(1.0f-shr->spec[1]); f1= 1.0f-i;
- diff[1]= f*mircol[1] + f1*diff[1];
-
- f= fb*(1.0f-shr->spec[2]); f1= 1.0f-i;
- diff[2]= f*mircol[2] + f1*diff[2];
- }
- }
- }
- /* put back together */
- if(shi->combinedflag & SCE_PASS_SPEC)
- VECADD(shr->combined, diff, shr->spec) /* no ; */
- else
- VECCOPY(shr->combined, diff);
-}
-
-/* color 'shadfac' passes through 'col' with alpha and filter */
-/* filter is only applied on alpha defined transparent part */
-static void addAlphaLight(float *shadfac, float *col, float alpha, float filter)
-{
- float fr, fg, fb;
-
- fr= 1.0f+ filter*(col[0]-1.0f);
- fg= 1.0f+ filter*(col[1]-1.0f);
- fb= 1.0f+ filter*(col[2]-1.0f);
-
- shadfac[0]= alpha*col[0] + fr*(1.0f-alpha)*shadfac[0];
- shadfac[1]= alpha*col[1] + fg*(1.0f-alpha)*shadfac[1];
- shadfac[2]= alpha*col[2] + fb*(1.0f-alpha)*shadfac[2];
-
- shadfac[3]= (1.0f-alpha)*shadfac[3];
-}
-
-static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
-{
- /* ray to lamp, find first face that intersects, check alpha properties,
- if it has col[3]>0.0f continue. so exit when alpha is full */
- ShadeInput shi;
- ShadeResult shr;
-
- if( d3dda(is)) {
- float d= 1.0f;
- /* we got a face */
-
- shi.depth= 1; /* only used to indicate tracing */
- shi.mask= 1;
- shi.osatex= 0;
- shi.thread= shi.sample= 0;
- shi.lay= 0;
- shi.passflag= 0;
- shi.combinedflag= 0;
- shi.do_preview= 0;
- shi.light_override= NULL;
- shi.mat_override= NULL;
-
- shade_ray(is, &shi, &shr);
- if (traflag & RAY_TRA)
- d= shade_by_transmission(is, &shi, &shr);
-
- /* mix colors based on shadfac (rgb + amount of light factor) */
- addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
-
- if(depth>0 && is->col[3]>0.0f) {
-
- /* adapt isect struct */
- VECCOPY(is->start, shi.co);
- is->vlrorig= shi.vlr;
-
- ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA);
- }
- }
-}
-
-/* not used, test function for ambient occlusion (yaf: pathlight) */
-/* main problem; has to be called within shading loop, giving unwanted recursion */
-int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
-{
- static int counter=0, only_one= 0;
- extern float hashvectf[];
- Isect isec;
- ShadeInput shi;
- ShadeResult shr_t;
- float vec[3], accum[3], div= 0.0f;
- int a;
-
- if(only_one) {
- return 0;
- }
- only_one= 1;
-
- accum[0]= accum[1]= accum[2]= 0.0f;
- isec.mode= DDA_MIRROR;
- isec.vlrorig= ship->vlr;
-
- for(a=0; a<8*8; a++) {
-
- counter+=3;
- counter %= 768;
- VECCOPY(vec, hashvectf+counter);
- if(ship->vn[0]*vec[0]+ship->vn[1]*vec[1]+ship->vn[2]*vec[2]>0.0f) {
- vec[0]-= vec[0];
- vec[1]-= vec[1];
- vec[2]-= vec[2];
- }
- VECCOPY(isec.start, ship->co);
- isec.end[0]= isec.start[0] + R.oc.ocsize*vec[0];
- isec.end[1]= isec.start[1] + R.oc.ocsize*vec[1];
- isec.end[2]= isec.start[2] + R.oc.ocsize*vec[2];
-
- if( d3dda(&isec)) {
- float fac;
- shade_ray(&isec, &shi, &shr_t);
- fac= isec.labda*isec.labda;
- fac= 1.0f;
- accum[0]+= fac*(shr_t.diff[0]+shr_t.spec[0]);
- accum[1]+= fac*(shr_t.diff[1]+shr_t.spec[1]);
- accum[2]+= fac*(shr_t.diff[2]+shr_t.spec[2]);
- div+= fac;
- }
- else div+= 1.0f;
- }
-
- if(div!=0.0f) {
- shr->diff[0]+= accum[0]/div;
- shr->diff[1]+= accum[1]/div;
- shr->diff[2]+= accum[2]/div;
- }
- shr->alpha= 1.0f;
-
- only_one= 0;
- return 1;
-}
-
-/* aolight: function to create random unit sphere vectors for total random sampling */
-static void RandomSpherical(float *v)
-{
- float r;
- v[2] = 2.f*BLI_frand()-1.f;
- if ((r = 1.f - v[2]*v[2])>0.f) {
- float a = 6.283185307f*BLI_frand();
- r = sqrt(r);
- v[0] = r * cos(a);
- v[1] = r * sin(a);
- }
- else v[2] = 1.f;
-}
-
-/* calc distributed spherical energy */
-static void DS_energy(float *sphere, int tot, float *vec)
-{
- float *fp, fac, force[3], res[3];
- int a;
-
- res[0]= res[1]= res[2]= 0.0f;
-
- for(a=0, fp=sphere; a<tot; a++, fp+=3) {
- VecSubf(force, vec, fp);
- fac= force[0]*force[0] + force[1]*force[1] + force[2]*force[2];
- if(fac!=0.0f) {
- fac= 1.0f/fac;
- res[0]+= fac*force[0];
- res[1]+= fac*force[1];
- res[2]+= fac*force[2];
- }
- }
-
- VecMulf(res, 0.5);
- VecAddf(vec, vec, res);
- Normalize(vec);
-
-}
-
-/* called from convertBlenderScene.c */
-/* creates an equally distributed spherical sample pattern */
-/* and allocates threadsafe memory */
-void init_ao_sphere(World *wrld)
-{
- float *fp;
- int a, tot, iter= 16;
-
- /* we make twice the amount of samples, because only a hemisphere is used */
- tot= 2*wrld->aosamp*wrld->aosamp;
-
- wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere");
-
- /* fixed random */
- BLI_srandom(tot);
-
- /* init */
- fp= wrld->aosphere;
- for(a=0; a<tot; a++, fp+= 3) {
- RandomSpherical(fp);
- }
-
- while(iter--) {
- for(a=0, fp= wrld->aosphere; a<tot; a++, fp+= 3) {
- DS_energy(wrld->aosphere, tot, fp);
- }
- }
-
- /* tables */
- wrld->aotables= MEM_mallocN(BLENDER_MAX_THREADS*3*tot*sizeof(float), "AO tables");
-}
-
-/* give per thread a table, we have to compare xs ys because of way OSA works... */
-static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot)
-{
- static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS];
- static int firsttime= 1;
-
- if(firsttime) {
- memset(xso, 255, sizeof(xso));
- memset(yso, 255, sizeof(yso));
- firsttime= 0;
- }
-
- if(xs==xso[thread] && ys==yso[thread]) return R.wrld.aotables+ thread*tot*3;
- if(test) return NULL;
- xso[thread]= xs; yso[thread]= ys;
- return R.wrld.aotables+ thread*tot*3;
-}
-
-static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
-{
- int tot;
- float *vec;
-
- if(resol>16) resol= 16;
-
- tot= 2*resol*resol;
-
- if (type & WO_AORNDSMP) {
- static float sphere[2*3*256];
- int a;
-
- /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */
- vec= sphere;
- for (a=0; a<tot; a++, vec+=3) {
- RandomSpherical(vec);
- }
-
- return sphere;
- }
- else {
- float *sphere;
- float cosfi, sinfi, cost, sint;
- float ang, *vec1;
- int a;
-
- sphere= threadsafe_table_sphere(1, thread, xs, ys, tot); // returns table if xs and ys were equal to last call
- if(sphere==NULL) {
- sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
-
- // random rotation
- ang= BLI_thread_frand(thread);
- sinfi= sin(ang); cosfi= cos(ang);
- ang= BLI_thread_frand(thread);
- sint= sin(ang); cost= cos(ang);
-
- vec= R.wrld.aosphere;
- vec1= sphere;
- for (a=0; a<tot; a++, vec+=3, vec1+=3) {
- vec1[0]= cost*cosfi*vec[0] - sinfi*vec[1] + sint*cosfi*vec[2];
- vec1[1]= cost*sinfi*vec[0] + cosfi*vec[1] + sint*sinfi*vec[2];
- vec1[2]= -sint*vec[0] + cost*vec[2];
- }
- }
- return sphere;
- }
-}
-
-
-/* extern call from shade_lamp_loop, ambient occlusion calculus */
-void ray_ao(ShadeInput *shi, float *shadfac)
-{
- Isect isec;
- float *vec, *nrm, div, bias, sh=0.0f;
- float maxdist = R.wrld.aodist;
- float dxyview[3];
- int j= -1, tot, actual=0, skyadded=0, aocolor;
-
- isec.vlrorig= shi->vlr;
- isec.vlr_last= NULL;
- isec.mode= (R.wrld.aomode & WO_AODIST)?DDA_SHADOW_TRA:DDA_SHADOW;
- isec.lay= -1;
-
- shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
-
- /* bias prevents smoothed faces to appear flat */
- if(shi->vlr->flag & R_SMOOTH) {
- bias= G.scene->world->aobias;
- nrm= shi->vn;
- }
- else {
- bias= 0.0f;
- nrm= shi->facenor;
- }
-
- /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
- aocolor= R.wrld.aocolor;
- if(shi->mat->mode & MA_ONLYSHADOW)
- aocolor= WO_AOPLAIN;
-
- vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
-
- // warning: since we use full sphere now, and dotproduct is below, we do twice as much
- tot= 2*R.wrld.aosamp*R.wrld.aosamp;
-
- if(aocolor == WO_AOSKYTEX) {
- dxyview[0]= 1.0f/(float)R.wrld.aosamp;
- dxyview[1]= 1.0f/(float)R.wrld.aosamp;
- dxyview[2]= 0.0f;
- }
-
- while(tot--) {
-
- if ((vec[0]*nrm[0] + vec[1]*nrm[1] + vec[2]*nrm[2]) > bias) {
- /* only ao samples for mask */
- if(R.r.mode & R_OSA) {
- j++;
- if(j==R.osa) j= 0;
- if(!(shi->mask & (1<<j))) {
- vec+=3;
- continue;
- }
- }
-
- actual++;
-
- /* always set start/end, 3dda clips it */
- VECCOPY(isec.start, shi->co);
- isec.end[0] = shi->co[0] - maxdist*vec[0];
- isec.end[1] = shi->co[1] - maxdist*vec[1];
- isec.end[2] = shi->co[2] - maxdist*vec[2];
-
- /* do the trace */
- if (d3dda(&isec)) {
- if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac);
- else sh+= 1.0f;
- }
- else if(aocolor!=WO_AOPLAIN) {
- float skycol[4];
- float fac, view[3];
-
- view[0]= -vec[0];
- view[1]= -vec[1];
- view[2]= -vec[2];
- Normalize(view);
-
- if(aocolor==WO_AOSKYCOL) {
- fac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
- shadfac[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
- shadfac[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
- shadfac[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
- }
- else { /* WO_AOSKYTEX */
- shadeSkyView(skycol, isec.start, view, dxyview);
- shadfac[0]+= skycol[0];
- shadfac[1]+= skycol[1];
- shadfac[2]+= skycol[2];
- }
- skyadded++;
- }
- }
- // samples
- vec+= 3;
- }
-
- if(actual==0) sh= 1.0f;
- else sh = 1.0f - sh/((float)actual);
-
- if(aocolor!=WO_AOPLAIN && skyadded) {
- div= sh/((float)skyadded);
-
- shadfac[0]*= div; // average color times distances/hits formula
- shadfac[1]*= div; // average color times distances/hits formula
- shadfac[2]*= div; // average color times distances/hits formula
- }
- else {
- shadfac[0]= shadfac[1]= shadfac[2]= sh;
- }
-}
-
-
-
-/* extern call from shade_lamp_loop */
-void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
-{
- Isect isec;
- float lampco[3];
-
- /* setup isec */
- if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= DDA_SHADOW_TRA;
- else isec.mode= DDA_SHADOW;
-
- if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
-
- /* only when not mir tracing, first hit optimm */
- if(shi->depth==0)
- isec.vlr_last= lar->vlr_last[shi->thread];
- else
- isec.vlr_last= NULL;
-
-
- if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0];
- lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1];
- lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2];
- }
- else {
- VECCOPY(lampco, lar->co);
- }
-
- if(lar->ray_totsamp<2) {
-
- isec.vlrorig= shi->vlr;
- shadfac[3]= 1.0f; // 1.0=full light
-
- /* set up isec vec */
- VECCOPY(isec.start, shi->co);
- VECCOPY(isec.end, lampco);
-
- if(isec.mode==DDA_SHADOW_TRA) {
- /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
- isec.col[0]= isec.col[1]= isec.col[2]= 1.0f;
- isec.col[3]= 1.0f;
-
- ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0);
- QUATCOPY(shadfac, isec.col);
- //printf("shadfac %f %f %f %f\n", shadfac[0], shadfac[1], shadfac[2], shadfac[3]);
- }
- else if( d3dda(&isec)) shadfac[3]= 0.0f;
- }
- else {
- /* area soft shadow */
- float *jitlamp;
- float fac=0.0f, div=0.0f, vec[3];
- int a, j= -1, mask;
-
- if(isec.mode==DDA_SHADOW_TRA) {
- shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
- }
- else shadfac[3]= 1.0f; // 1.0=full light
-
- fac= 0.0f;
- jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys);
-
- a= lar->ray_totsamp;
-
- /* this correction to make sure we always take at least 1 sample */
- mask= shi->mask;
- if(a==4) mask |= (mask>>4)|(mask>>8);
- else if(a==9) mask |= (mask>>9);
-
- while(a--) {
-
- if(R.r.mode & R_OSA) {
- j++;
- if(j>=R.osa) j= 0;
- if(!(mask & (1<<j))) {
- jitlamp+= 2;
- continue;
- }
- }
-
- isec.vlrorig= shi->vlr; // ray_trace_shadow_tra changes it
-
- vec[0]= jitlamp[0];
- vec[1]= jitlamp[1];
- vec[2]= 0.0f;
- Mat3MulVecfl(lar->mat, vec);
-
- /* set start and end, d3dda clips it */
- VECCOPY(isec.start, shi->co);
- isec.end[0]= lampco[0]+vec[0];
- isec.end[1]= lampco[1]+vec[1];
- isec.end[2]= lampco[2]+vec[2];
-
- if(isec.mode==DDA_SHADOW_TRA) {
- /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
- isec.col[0]= isec.col[1]= isec.col[2]= 1.0f;
- isec.col[3]= 1.0f;
-
- ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0);
- shadfac[0] += isec.col[0];
- shadfac[1] += isec.col[1];
- shadfac[2] += isec.col[2];
- shadfac[3] += isec.col[3];
- }
- else if( d3dda(&isec) ) fac+= 1.0f;
-
- div+= 1.0f;
- jitlamp+= 2;
- }
-
- if(isec.mode==DDA_SHADOW_TRA) {
- shadfac[0] /= div;
- shadfac[1] /= div;
- shadfac[2] /= div;
- shadfac[3] /= div;
- }
- else {
- // sqrt makes nice umbra effect
- if(lar->ray_samp_type & LA_SAMP_UMBRA)
- shadfac[3]= sqrt(1.0f-fac/div);
- else
- shadfac[3]= 1.0f-fac/div;
- }
- }
-
- /* for first hit optim, set last interesected shadow face */
- if(shi->depth==0)
- lar->vlr_last[shi->thread]= isec.vlr_last;
-
-}
-
-/* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */
-void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co)
-{
- Isect isec;
- float lampco[3];
-
- /* setup isec */
- isec.mode= DDA_SHADOW_TRA;
-
- if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
-
- if(lar->type==LA_SUN || lar->type==LA_HEMI) {
- lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0];
- lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1];
- lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2];
- }
- else {
- VECCOPY(lampco, lar->co);
- }
-
- isec.vlrorig= shi->vlr;
-
- /* set up isec vec */
- VECCOPY(isec.start, shi->co);
- VECCOPY(isec.end, lampco);
-
- if( d3dda(&isec)) {
- /* we got a face */
-
- /* render co */
- co[0]= isec.start[0]+isec.labda*(isec.vec[0]);
- co[1]= isec.start[1]+isec.labda*(isec.vec[1]);
- co[2]= isec.start[2]+isec.labda*(isec.vec[2]);
-
- *distfac= VecLength(isec.vec);
- }
- else
- *distfac= 0.0f;
-}
-
-
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
new file mode 100644
index 00000000000..d0f9be3fd79
--- /dev/null
+++ b/source/blender/render/intern/source/rayshade.c
@@ -0,0 +1,2112 @@
+/**
+ * $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) 1990-1998 NeoGeo BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+#include "DNA_lamp_types.h"
+
+#include "BKE_global.h"
+#include "BKE_node.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_arithb.h"
+#include "BLI_rand.h"
+#include "BLI_jitter.h"
+
+#include "PIL_time.h"
+
+#include "render_types.h"
+#include "renderpipeline.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "pixelblending.h"
+#include "pixelshading.h"
+#include "shading.h"
+#include "texture.h"
+
+#include "RE_raytrace.h"
+
+#define RAY_TRA 1
+#define RAY_TRAFLIP 2
+
+#define DEPTH_SHADOW_TRA 10
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
+/* only to be used here in this file, it's for speed */
+extern struct Render R;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, float **v4)
+{
+ VlakRen *vlr= (VlakRen*)face;
+
+ *v1 = (vlr->v1)? vlr->v1->co: NULL;
+ *v2 = (vlr->v2)? vlr->v2->co: NULL;
+ *v3 = (vlr->v3)? vlr->v3->co: NULL;
+ *v4 = (vlr->v4)? vlr->v4->co: NULL;
+}
+
+static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
+{
+ ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob);
+ VlakRen *vlr = (VlakRen*)face;
+
+ /* I know... cpu cycle waste, might do smarter once */
+ if(is->mode==RE_RAY_MIRROR)
+ return !(vlr->mat->mode & MA_ONLYCAST);
+ else
+ return (is->lay & obi->lay);
+}
+
+static float *vlr_get_transform(void *userdata, int i)
+{
+ ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)userdata, i);
+
+ return (obi->flag & R_TRANSFORMED)? (float*)obi->mat: NULL;
+}
+
+void freeraytree(Render *re)
+{
+ if(re->raytree) {
+ RE_ray_tree_free(re->raytree);
+ re->raytree= NULL;
+ }
+}
+
+void makeraytree(Render *re)
+{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ VlakRen *vlr= NULL;
+ float min[3], max[3], co1[3], co2[3], co3[3], co4[3];
+ double lasttime= PIL_check_seconds_timer();
+ int v, totface = 0;
+
+ INIT_MINMAX(min, max);
+
+ /* first min max raytree space */
+ for(obi=re->instancetable.first; obi; obi=obi->next) {
+ obr= obi->obr;
+
+ if(re->excludeob && obr->ob == re->excludeob)
+ continue;
+
+ for(v=0;v<obr->totvlak;v++) {
+ if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
+ else vlr++;
+ if(vlr->mat->mode & MA_TRACEBLE) {
+ if((vlr->mat->mode & MA_WIRE)==0) {
+ VECCOPY(co1, vlr->v1->co);
+ VECCOPY(co2, vlr->v2->co);
+ VECCOPY(co3, vlr->v3->co);
+
+ if(obi->flag & R_TRANSFORMED) {
+ Mat4MulVecfl(obi->mat, co1);
+ Mat4MulVecfl(obi->mat, co2);
+ Mat4MulVecfl(obi->mat, co3);
+ }
+
+ DO_MINMAX(co1, min, max);
+ DO_MINMAX(co2, min, max);
+ DO_MINMAX(co3, min, max);
+
+ if(vlr->v4) {
+ VECCOPY(co4, vlr->v4->co);
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, co4);
+ DO_MINMAX(co4, min, max);
+ }
+
+ totface++;
+ }
+ }
+ }
+ }
+
+ re->raytree= RE_ray_tree_create(re->r.ocres, totface, min, max,
+ vlr_face_coords, vlr_check_intersect, vlr_get_transform, re);
+
+ if(min[0] > max[0]) { /* empty raytree */
+ RE_ray_tree_done(re->raytree);
+ return;
+ }
+
+ for(obi=re->instancetable.first; obi; obi=obi->next) {
+ obr= obi->obr;
+
+ if(re->excludeob && obr->ob == re->excludeob)
+ continue;
+
+ for(v=0; v<obr->totvlak; v++) {
+ if((v & 255)==0) {
+ double time= PIL_check_seconds_timer();
+
+ vlr= obr->vlaknodes[v>>8].vlak;
+ if(re->test_break())
+ break;
+ if(time-lasttime>1.0f) {
+ char str[32];
+ sprintf(str, "Filling Octree: %d", v);
+ re->i.infostr= str;
+ re->stats_draw(&re->i);
+ re->i.infostr= NULL;
+ lasttime= time;
+ }
+ }
+ else vlr++;
+
+ if(vlr->mat->mode & MA_TRACEBLE)
+ if((vlr->mat->mode & MA_WIRE)==0)
+ RE_ray_tree_add_face(re->raytree, RAY_OBJECT_SET(re, obi), vlr);
+ }
+ }
+
+ RE_ray_tree_done(re->raytree);
+
+ re->i.infostr= NULL;
+ re->stats_draw(&re->i);
+}
+
+static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
+{
+ VlakRen *vlr= (VlakRen*)is->face;
+ ObjectInstanceRen *obi= RAY_OBJECT_GET(&R, is->ob);
+ int osatex= 0;
+
+ /* set up view vector */
+ VECCOPY(shi->view, is->vec);
+
+ /* render co */
+ shi->co[0]= is->start[0]+is->labda*(shi->view[0]);
+ shi->co[1]= is->start[1]+is->labda*(shi->view[1]);
+ shi->co[2]= is->start[2]+is->labda*(shi->view[2]);
+
+ Normalize(shi->view);
+
+ shi->obi= obi;
+ shi->obr= obi->obr;
+ shi->vlr= vlr;
+ shi->mat= vlr->mat;
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
+ shi->har= shi->mat->har;
+
+ // Osa structs we leave unchanged now
+ SWAP(int, osatex, shi->osatex);
+
+ shi->dxco[0]= shi->dxco[1]= shi->dxco[2]= 0.0f;
+ shi->dyco[0]= shi->dyco[1]= shi->dyco[2]= 0.0f;
+
+ // but, set Osa stuff to zero where it can confuse texture code
+ if(shi->mat->texco & (TEXCO_NORM|TEXCO_REFL) ) {
+ shi->dxno[0]= shi->dxno[1]= shi->dxno[2]= 0.0f;
+ shi->dyno[0]= shi->dyno[1]= shi->dyno[2]= 0.0f;
+ }
+
+ if(vlr->v4) {
+ if(is->isect==2)
+ shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
+ }
+ else {
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
+ }
+
+ shi->u= is->u;
+ shi->v= is->v;
+ shi->dx_u= shi->dx_v= shi->dy_u= shi->dy_v= 0.0f;
+
+ shade_input_set_normals(shi);
+
+ /* point normals to viewing direction */
+ if(INPR(shi->facenor, shi->view) < 0.0f)
+ shade_input_flip_normals(shi);
+
+ shade_input_set_shade_texco(shi);
+
+ if(is->mode==RE_RAY_SHADOW_TRA)
+ shade_color(shi, shr);
+ else {
+ if(shi->mat->nodetree && shi->mat->use_nodes) {
+ ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
+ shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
+ }
+ else
+ shade_material_loop(shi, shr);
+
+ /* raytrace likes to separate the spec color */
+ VECSUB(shr->diff, shr->combined, shr->spec);
+ }
+
+ SWAP(int, osatex, shi->osatex); // XXXXX!!!!
+
+}
+
+static int refraction(float *refract, float *n, float *view, float index)
+{
+ float dot, fac;
+
+ VECCOPY(refract, view);
+
+ dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
+
+ if(dot>0.0f) {
+ index = 1.0f/index;
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if(fac<= 0.0f) return 0;
+ fac= -dot*index + sqrt(fac);
+ }
+ else {
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if(fac<= 0.0f) return 0;
+ fac= -dot*index - sqrt(fac);
+ }
+
+ refract[0]= index*view[0] + fac*n[0];
+ refract[1]= index*view[1] + fac*n[1];
+ refract[2]= index*view[2] + fac*n[2];
+
+ return 1;
+}
+
+/* orn = original face normal */
+static void reflection(float *ref, float *n, float *view, float *orn)
+{
+ float f1;
+
+ f1= -2.0f*(n[0]*view[0]+ n[1]*view[1]+ n[2]*view[2]);
+
+ ref[0]= (view[0]+f1*n[0]);
+ ref[1]= (view[1]+f1*n[1]);
+ ref[2]= (view[2]+f1*n[2]);
+
+ if(orn) {
+ /* test phong normals, then we should prevent vector going to the back */
+ f1= ref[0]*orn[0]+ ref[1]*orn[1]+ ref[2]*orn[2];
+ if(f1>0.0f) {
+ f1+= .01f;
+ ref[0]-= f1*orn[0];
+ ref[1]-= f1*orn[1];
+ ref[2]-= f1*orn[2];
+ }
+ }
+}
+
+#if 0
+static void color_combine(float *result, float fac1, float fac2, float *col1, float *col2)
+{
+ float col1t[3], col2t[3];
+
+ col1t[0]= sqrt(col1[0]);
+ col1t[1]= sqrt(col1[1]);
+ col1t[2]= sqrt(col1[2]);
+ col2t[0]= sqrt(col2[0]);
+ col2t[1]= sqrt(col2[1]);
+ col2t[2]= sqrt(col2[2]);
+
+ result[0]= (fac1*col1t[0] + fac2*col2t[0]);
+ result[0]*= result[0];
+ result[1]= (fac1*col1t[1] + fac2*col2t[1]);
+ result[1]*= result[1];
+ result[2]= (fac1*col1t[2] + fac2*col2t[2]);
+ result[2]*= result[2];
+}
+#endif
+
+static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
+{
+ float dx, dy, dz, d, p;
+
+ if (0 == (shi->mat->mode & (MA_RAYTRANSP|MA_ZTRA)))
+ return -1;
+
+ if (shi->mat->tx_limit <= 0.0f) {
+ d= 1.0f;
+ }
+ else {
+ /* shi.co[] calculated by shade_ray() */
+ dx= shi->co[0] - is->start[0];
+ dy= shi->co[1] - is->start[1];
+ dz= shi->co[2] - is->start[2];
+ d= sqrt(dx*dx+dy*dy+dz*dz);
+ if (d > shi->mat->tx_limit)
+ d= shi->mat->tx_limit;
+
+ p = shi->mat->tx_falloff;
+ if(p < 0.0f) p= 0.0f;
+ else if (p > 10.0f) p= 10.0f;
+
+ shr->alpha *= pow(d, p);
+ if (shr->alpha > 1.0f)
+ shr->alpha= 1.0f;
+ }
+
+ return d;
+}
+
+static void ray_fadeout_endcolor(float *col, ShadeInput *origshi, ShadeInput *shi, ShadeResult *shr, Isect *isec, float *vec)
+{
+ /* un-intersected rays get either rendered material colour or sky colour */
+ if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOMAT) {
+ VECCOPY(col, shr->combined);
+ } else if (origshi->mat->fadeto_mir == MA_RAYMIR_FADETOSKY) {
+ VECCOPY(shi->view, vec);
+ Normalize(shi->view);
+
+ shadeSkyView(col, isec->start, shi->view, NULL);
+ }
+}
+
+static void ray_fadeout(Isect *is, ShadeInput *shi, float *col, float *blendcol, float dist_mir)
+{
+ /* if fading out, linear blend against fade colour */
+ float blendfac;
+
+ blendfac = 1.0 - VecLenf(shi->co, is->start)/dist_mir;
+
+ col[0] = col[0]*blendfac + (1.0 - blendfac)*blendcol[0];
+ col[1] = col[1]*blendfac + (1.0 - blendfac)*blendcol[1];
+ col[2] = col[2]*blendfac + (1.0 - blendfac)*blendcol[2];
+}
+
+/* the main recursive tracer itself */
+static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, float *start, float *vec, float *col, ObjectInstanceRen *obi, VlakRen *vlr, int traflag)
+{
+ ShadeInput shi;
+ ShadeResult shr;
+ Isect isec;
+ float f, f1, fr, fg, fb;
+ float ref[3], maxsize=RE_ray_tree_max_size(R.raytree);
+ float dist_mir = origshi->mat->dist_mir;
+
+ /* Warning, This is not that nice, and possibly a bit slow for every ray,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ VECCOPY(isec.start, start);
+ if (dist_mir > 0.0) {
+ isec.end[0]= start[0]+dist_mir*vec[0];
+ isec.end[1]= start[1]+dist_mir*vec[1];
+ isec.end[2]= start[2]+dist_mir*vec[2];
+ } else {
+ isec.end[0]= start[0]+maxsize*vec[0];
+ isec.end[1]= start[1]+maxsize*vec[1];
+ isec.end[2]= start[2]+maxsize*vec[2];
+ }
+ isec.mode= RE_RAY_MIRROR;
+ isec.faceorig= (RayFace*)vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, obi);
+
+ if(RE_ray_tree_intersect(R.raytree, &isec)) {
+ float d= 1.0f;
+
+ shi.mask= origshi->mask;
+ shi.osatex= origshi->osatex;
+ shi.depth= 1; /* only used to indicate tracing */
+ shi.thread= origshi->thread;
+ //shi.sample= 0; // memset above, so dont need this
+ shi.xs= origshi->xs;
+ shi.ys= origshi->ys;
+ shi.lay= origshi->lay;
+ shi.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
+ shi.combinedflag= 0xFFFFFF; /* ray trace does all options */
+ //shi.do_preview= 0; // memset above, so dont need this
+ shi.light_override= origshi->light_override;
+ shi.mat_override= origshi->mat_override;
+
+ memset(&shr, 0, sizeof(ShadeResult));
+
+ shade_ray(&isec, &shi, &shr);
+ if (traflag & RAY_TRA)
+ d= shade_by_transmission(&isec, &shi, &shr);
+
+ if(depth>0) {
+
+ if(shi.mat->mode_l & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha < 1.0f) {
+ float nf, f, f1, refract[3], tracol[4];
+
+ tracol[0]= shi.r;
+ tracol[1]= shi.g;
+ tracol[2]= shi.b;
+ tracol[3]= col[3]; // we pass on and accumulate alpha
+
+ if(shi.mat->mode & MA_RAYTRANSP) {
+ /* odd depths: use normal facing viewer, otherwise flip */
+ if(traflag & RAY_TRAFLIP) {
+ float norm[3];
+ norm[0]= - shi.vn[0];
+ norm[1]= - shi.vn[1];
+ norm[2]= - shi.vn[2];
+ if (!refraction(refract, norm, shi.view, shi.ang))
+ reflection(refract, norm, shi.view, shi.vn);
+ }
+ else {
+ if (!refraction(refract, shi.vn, shi.view, shi.ang))
+ reflection(refract, shi.vn, shi.view, shi.vn);
+ }
+ traflag |= RAY_TRA;
+ traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag ^ RAY_TRAFLIP);
+ }
+ else
+ traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);
+
+ f= shr.alpha; f1= 1.0f-f;
+ nf= d * shi.mat->filter;
+ fr= 1.0f+ nf*(shi.r-1.0f);
+ fg= 1.0f+ nf*(shi.g-1.0f);
+ fb= 1.0f+ nf*(shi.b-1.0f);
+ shr.diff[0]= f*shr.diff[0] + f1*fr*tracol[0];
+ shr.diff[1]= f*shr.diff[1] + f1*fg*tracol[1];
+ shr.diff[2]= f*shr.diff[2] + f1*fb*tracol[2];
+
+ shr.spec[0] *=f;
+ shr.spec[1] *=f;
+ shr.spec[2] *=f;
+
+ col[3]= f1*tracol[3] + f;
+ }
+ else
+ col[3]= 1.0f;
+
+ if(shi.mat->mode_l & MA_RAYMIRROR) {
+ f= shi.ray_mirror;
+ if(f!=0.0f) f*= fresnel_fac(shi.view, shi.vn, shi.mat->fresnel_mir_i, shi.mat->fresnel_mir);
+ }
+ else f= 0.0f;
+
+ if(f!=0.0f) {
+ float mircol[4];
+
+ reflection(ref, shi.vn, shi.view, NULL);
+ traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0);
+
+ f1= 1.0f-f;
+
+ /* combine */
+ //color_combine(col, f*fr*(1.0f-shr.spec[0]), f1, col, shr.diff);
+ //col[0]+= shr.spec[0];
+ //col[1]+= shr.spec[1];
+ //col[2]+= shr.spec[2];
+
+ fr= shi.mirr;
+ fg= shi.mirg;
+ fb= shi.mirb;
+
+ col[0]= f*fr*(1.0f-shr.spec[0])*mircol[0] + f1*shr.diff[0] + shr.spec[0];
+ col[1]= f*fg*(1.0f-shr.spec[1])*mircol[1] + f1*shr.diff[1] + shr.spec[1];
+ col[2]= f*fb*(1.0f-shr.spec[2])*mircol[2] + f1*shr.diff[2] + shr.spec[2];
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
+ }
+
+ if (dist_mir > 0.0) {
+ float blendcol[3];
+
+ /* max ray distance set, but found an intersection, so fade this colour
+ * out towards the sky/material colour for a smooth transition */
+ ray_fadeout_endcolor(blendcol, origshi, &shi, origshr, &isec, vec);
+ ray_fadeout(&isec, &shi, col, blendcol, dist_mir);
+ }
+ }
+ else {
+ col[0]= shr.diff[0] + shr.spec[0];
+ col[1]= shr.diff[1] + shr.spec[1];
+ col[2]= shr.diff[2] + shr.spec[2];
+ }
+
+ }
+ else {
+ ray_fadeout_endcolor(col, origshi, &shi, origshr, &isec, vec);
+ }
+}
+
+/* **************** jitter blocks ********** */
+
+/* calc distributed planar energy */
+
+static void DP_energy(float *table, float *vec, int tot, float xsize, float ysize)
+{
+ int x, y, a;
+ float *fp, force[3], result[3];
+ float dx, dy, dist, min;
+
+ min= MIN2(xsize, ysize);
+ min*= min;
+ result[0]= result[1]= 0.0f;
+
+ for(y= -1; y<2; y++) {
+ dy= ysize*y;
+ for(x= -1; x<2; x++) {
+ dx= xsize*x;
+ fp= table;
+ for(a=0; a<tot; a++, fp+= 2) {
+ force[0]= vec[0] - fp[0]-dx;
+ force[1]= vec[1] - fp[1]-dy;
+ dist= force[0]*force[0] + force[1]*force[1];
+ if(dist < min && dist>0.0f) {
+ result[0]+= force[0]/dist;
+ result[1]+= force[1]/dist;
+ }
+ }
+ }
+ }
+ vec[0] += 0.1*min*result[0]/(float)tot;
+ vec[1] += 0.1*min*result[1]/(float)tot;
+ // cyclic clamping
+ vec[0]= vec[0] - xsize*floor(vec[0]/xsize + 0.5);
+ vec[1]= vec[1] - ysize*floor(vec[1]/ysize + 0.5);
+}
+
+// random offset of 1 in 2
+static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy)
+{
+ float dsizex= sizex*ofsx;
+ float dsizey= sizey*ofsy;
+ float hsizex= 0.5*sizex, hsizey= 0.5*sizey;
+ int x;
+
+ for(x=tot; x>0; x--, jitter1+=2, jitter2+=2) {
+ jitter2[0]= jitter1[0] + dsizex;
+ jitter2[1]= jitter1[1] + dsizey;
+ if(jitter2[0] > hsizex) jitter2[0]-= sizex;
+ if(jitter2[1] > hsizey) jitter2[1]-= sizey;
+ }
+}
+
+/* called from convertBlenderScene.c */
+/* we do this in advance to get consistant random, not alter the render seed, and be threadsafe */
+void init_jitter_plane(LampRen *lar)
+{
+ float *fp;
+ int x, iter=12, tot= lar->ray_totsamp;
+
+ /* test if already initialized */
+ if(lar->jitter) return;
+
+ /* at least 4, or max threads+1 tables */
+ if(BLENDER_MAX_THREADS < 4) x= 4;
+ else x= BLENDER_MAX_THREADS+1;
+ fp= lar->jitter= MEM_mallocN(x*tot*2*sizeof(float), "lamp jitter tab");
+
+ /* set per-lamp fixed seed */
+ BLI_srandom(tot);
+
+ /* fill table with random locations, area_size large */
+ for(x=0; x<tot; x++, fp+=2) {
+ fp[0]= (BLI_frand()-0.5)*lar->area_size;
+ fp[1]= (BLI_frand()-0.5)*lar->area_sizey;
+ }
+
+ while(iter--) {
+ fp= lar->jitter;
+ for(x=tot; x>0; x--, fp+=2) {
+ DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey);
+ }
+ }
+
+ /* create the dithered tables (could just check lamp type!) */
+ jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.0f);
+ jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.5f);
+ jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0f, 0.5f);
+}
+
+/* table around origin, -0.5*size to 0.5*size */
+static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
+{
+ int tot;
+
+ tot= lar->ray_totsamp;
+
+ if(lar->ray_samp_type & LA_SAMP_JITTER) {
+ /* made it threadsafe */
+
+ if(lar->xold[thread]!=xs || lar->yold[thread]!=ys) {
+ jitter_plane_offset(lar->jitter, lar->jitter+2*(thread+1)*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(thread), BLI_thread_frand(thread));
+ lar->xold[thread]= xs;
+ lar->yold[thread]= ys;
+ }
+ return lar->jitter+2*(thread+1)*tot;
+ }
+ if(lar->ray_samp_type & LA_SAMP_DITHER) {
+ return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1));
+ }
+
+ return lar->jitter;
+}
+
+
+/* **************** QMC sampling *************** */
+
+static void halton_sample(double *ht_invprimes, double *ht_nums, double *v)
+{
+ // incremental halton sequence generator, from:
+ // "Instant Radiosity", Keller A.
+ unsigned int i;
+
+ for (i = 0; i < 2; i++)
+ {
+ double r = fabs((1.0 - ht_nums[i]) - 1e-10);
+
+ if (ht_invprimes[i] >= r)
+ {
+ double lasth;
+ double h = ht_invprimes[i];
+
+ do {
+ lasth = h;
+ h *= ht_invprimes[i];
+ } while (h >= r);
+
+ ht_nums[i] += ((lasth + h) - 1.0);
+ }
+ else
+ ht_nums[i] += ht_invprimes[i];
+
+ v[i] = (float)ht_nums[i];
+ }
+}
+
+/* Generate Hammersley points in [0,1)^2
+ * From Lucille renderer */
+static void hammersley_create(double *out, int n)
+{
+ double p, t;
+ int k, kk;
+
+ for (k = 0; k < n; k++) {
+ t = 0;
+ for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1) {
+ if (kk & 1) { /* kk mod 2 = 1 */
+ t += p;
+ }
+ }
+
+ out[2 * k + 0] = (double)k / (double)n;
+ out[2 * k + 1] = t;
+ }
+}
+
+struct QMCSampler *QMC_initSampler(int type, int tot)
+{
+ QMCSampler *qsa = MEM_mallocN(sizeof(QMCSampler), "qmc sampler");
+ qsa->samp2d = MEM_mallocN(2*sizeof(double)*tot, "qmc sample table");
+
+ qsa->tot = tot;
+ qsa->type = type;
+
+ if (qsa->type==SAMP_TYPE_HAMMERSLEY)
+ hammersley_create(qsa->samp2d, qsa->tot);
+
+ return qsa;
+}
+
+static void QMC_initPixel(QMCSampler *qsa, int thread)
+{
+ if (qsa->type==SAMP_TYPE_HAMMERSLEY)
+ {
+ /* hammersley sequence is fixed, already created in QMCSampler init.
+ * per pixel, gets a random offset. We create separate offsets per thread, for write-safety */
+ qsa->offs[thread][0] = 0.5 * BLI_thread_frand(thread);
+ qsa->offs[thread][1] = 0.5 * BLI_thread_frand(thread);
+ }
+ else { /* SAMP_TYPE_HALTON */
+
+ /* generate a new randomised halton sequence per pixel
+ * to alleviate qmc artifacts and make it reproducable
+ * between threads/frames */
+ double ht_invprimes[2], ht_nums[2];
+ double r[2];
+ int i;
+
+ ht_nums[0] = BLI_thread_frand(thread);
+ ht_nums[1] = BLI_thread_frand(thread);
+ ht_invprimes[0] = 0.5;
+ ht_invprimes[1] = 1.0/3.0;
+
+ for (i=0; i< qsa->tot; i++) {
+ halton_sample(ht_invprimes, ht_nums, r);
+ qsa->samp2d[2*i+0] = r[0];
+ qsa->samp2d[2*i+1] = r[1];
+ }
+ }
+}
+
+static void QMC_freeSampler(QMCSampler *qsa)
+{
+ MEM_freeN(qsa->samp2d);
+ MEM_freeN(qsa);
+}
+
+static void QMC_getSample(double *s, QMCSampler *qsa, int thread, int num)
+{
+ if (qsa->type == SAMP_TYPE_HAMMERSLEY) {
+ s[0] = fmod(qsa->samp2d[2*num+0] + qsa->offs[thread][0], 1.0f);
+ s[1] = fmod(qsa->samp2d[2*num+1] + qsa->offs[thread][1], 1.0f);
+ }
+ else { /* SAMP_TYPE_HALTON */
+ s[0] = qsa->samp2d[2*num+0];
+ s[1] = qsa->samp2d[2*num+1];
+ }
+}
+
+/* phong weighted disc using 'blur' for exponent, centred on 0,0 */
+static void QMC_samplePhong(float *vec, QMCSampler *qsa, int thread, int num, float blur)
+{
+ double s[2];
+ float phi, pz, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2*M_PI;
+ pz = pow(s[1], blur);
+ sqr = sqrt(1.0f-pz*pz);
+
+ vec[0] = cos(phi)*sqr;
+ vec[1] = sin(phi)*sqr;
+ vec[2] = 0.0f;
+}
+
+/* rect of edge lengths sizex, sizey, centred on 0.0,0.0 i.e. ranging from -sizex/2 to +sizey/2 */
+static void QMC_sampleRect(float *vec, QMCSampler *qsa, int thread, int num, float sizex, float sizey)
+{
+ double s[2];
+
+ QMC_getSample(s, qsa, thread, num);
+
+ vec[0] = (s[0] - 0.5) * sizex;
+ vec[1] = (s[1] - 0.5) * sizey;
+ vec[2] = 0.0f;
+}
+
+/* disc of radius 'radius', centred on 0,0 */
+static void QMC_sampleDisc(float *vec, QMCSampler *qsa, int thread, int num, float radius)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2*M_PI;
+ sqr = sqrt(s[1]);
+
+ vec[0] = cos(phi)*sqr* radius/2.0;
+ vec[1] = sin(phi)*sqr* radius/2.0;
+ vec[2] = 0.0f;
+}
+
+/* uniform hemisphere sampling */
+static void QMC_sampleHemi(float *vec, QMCSampler *qsa, int thread, int num)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2.f*M_PI;
+ sqr = sqrt(s[1]);
+
+ vec[0] = cos(phi)*sqr;
+ vec[1] = sin(phi)*sqr;
+ vec[2] = 1.f - s[1]*s[1];
+}
+
+#if 0 /* currently not used */
+/* cosine weighted hemisphere sampling */
+static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)
+{
+ double s[2];
+ float phi, sqr;
+
+ QMC_getSample(s, qsa, thread, num);
+
+ phi = s[0]*2.f*M_PI;
+ sqr = s[1]*sqrt(2-s[1]*s[1]);
+
+ vec[0] = cos(phi)*sqr;
+ vec[1] = sin(phi)*sqr;
+ vec[2] = 1.f - s[1]*s[1];
+
+}
+#endif
+
+/* called from convertBlenderScene.c */
+/* samples don't change per pixel, so build the samples in advance for efficiency */
+void init_lamp_hammersley(LampRen *lar)
+{
+ lar->qsa = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, lar->ray_totsamp);
+}
+
+void init_render_hammersley(Render *re)
+{
+ re->qsa = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, (re->wrld.aosamp * re->wrld.aosamp));
+}
+
+void free_lamp_qmcsampler(LampRen *lar)
+{
+ QMC_freeSampler(lar->qsa);
+ lar->qsa = NULL;
+}
+
+void free_render_qmcsampler(Render *re)
+{
+ QMC_freeSampler(re->qsa);
+ re->qsa = NULL;
+}
+
+static int adaptive_sample_variance(int samples, float *col, float *colsq, float thresh)
+{
+ float var[3], mean[3];
+
+ /* scale threshold just to give a bit more precision in input rather than dealing with
+ * tiny tiny numbers in the UI */
+ thresh /= 2;
+
+ mean[0] = col[0] / (float)samples;
+ mean[1] = col[1] / (float)samples;
+ mean[2] = col[2] / (float)samples;
+
+ var[0] = (colsq[0] / (float)samples) - (mean[0]*mean[0]);
+ var[1] = (colsq[1] / (float)samples) - (mean[1]*mean[1]);
+ var[2] = (colsq[2] / (float)samples) - (mean[2]*mean[2]);
+
+ if ((var[0] * 0.4 < thresh) && (var[1] * 0.3 < thresh) && (var[2] * 0.6 < thresh))
+ return 1;
+ else
+ return 0;
+}
+
+static int adaptive_sample_contrast_val(int samples, float prev, float val, float thresh)
+{
+ /* if the last sample's contribution to the total value was below a small threshold
+ * (i.e. the samples taken are very similar), then taking more samples that are probably
+ * going to be the same is wasting effort */
+ if (fabs( prev/(float)(samples-1) - val/(float)samples ) < thresh) {
+ return 1;
+ } else
+ return 0;
+}
+
+static float get_avg_speed(ShadeInput *shi)
+{
+ float pre_x, pre_y, post_x, post_y, speedavg;
+
+ pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0:shi->winspeed[0];
+ pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0:shi->winspeed[1];
+ post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0:shi->winspeed[2];
+ post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0:shi->winspeed[3];
+
+ speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;
+
+ return speedavg;
+}
+
+/* ***************** main calls ************** */
+
+
+static void trace_refract(float *col, ShadeInput *shi, ShadeResult *shr)
+{
+ QMCSampler *qsa=NULL;
+ int samp_type;
+
+ float samp3d[3], orthx[3], orthy[3];
+ float v_refract[3], v_refract_new[3];
+ float sampcol[4], colsq[4];
+
+ float blur = pow(1.0 - shi->mat->gloss_tra, 3);
+ short max_samples = shi->mat->samp_gloss_tra;
+ float adapt_thresh = shi->mat->adapt_thresh_tra;
+
+ int samples=0;
+
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+ col[0] = col[1] = col[2] = 0.0;
+ col[3]= shr->alpha;
+
+ if (blur > 0.0) {
+ if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON;
+ else samp_type = SAMP_TYPE_HAMMERSLEY;
+
+ /* all samples are generated per pixel */
+ qsa = QMC_initSampler(samp_type, max_samples);
+ QMC_initPixel(qsa, shi->thread);
+ } else
+ max_samples = 1;
+
+
+ while (samples < max_samples) {
+ refraction(v_refract, shi->vn, shi->view, shi->ang);
+
+ if (max_samples > 1) {
+ /* get a quasi-random vector from a phong-weighted disc */
+ QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur);
+
+ VecOrthoBasisf(v_refract, orthx, orthy);
+ VecMulf(orthx, samp3d[0]);
+ VecMulf(orthy, samp3d[1]);
+
+ /* and perturb the refraction vector in it */
+ VecAddf(v_refract_new, v_refract, orthx);
+ VecAddf(v_refract_new, v_refract_new, orthy);
+
+ Normalize(v_refract_new);
+ } else {
+ /* no blurriness, use the original normal */
+ VECCOPY(v_refract_new, v_refract);
+ }
+
+ traceray(shi, shr, shi->mat->ray_depth_tra, shi->co, v_refract_new, sampcol, shi->obi, shi->vlr, RAY_TRA|RAY_TRAFLIP);
+
+ col[0] += sampcol[0];
+ col[1] += sampcol[1];
+ col[2] += sampcol[2];
+ col[3] += sampcol[3];
+
+ /* for variance calc */
+ colsq[0] += sampcol[0]*sampcol[0];
+ colsq[1] += sampcol[1]*sampcol[1];
+ colsq[2] += sampcol[2]*sampcol[2];
+
+ samples++;
+
+ /* adaptive sampling */
+ if (adapt_thresh < 1.0 && samples > max_samples/2)
+ {
+ if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))
+ break;
+
+ /* if the pixel so far is very dark, we can get away with less samples */
+ if ( (col[0] + col[1] + col[2])/3.0/(float)samples < 0.01 )
+ max_samples--;
+ }
+ }
+
+ col[0] /= (float)samples;
+ col[1] /= (float)samples;
+ col[2] /= (float)samples;
+ col[3] /= (float)samples;
+
+ if (qsa) QMC_freeSampler(qsa);
+}
+
+static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float fresnelfac)
+{
+ QMCSampler *qsa=NULL;
+ int samp_type;
+
+ float samp3d[3], orthx[3], orthy[3];
+ float v_nor_new[3], v_reflect[3];
+ float sampcol[4], colsq[4];
+
+ float blur = pow(1.0 - shi->mat->gloss_mir, 3);
+ short max_samples = shi->mat->samp_gloss_mir;
+ float adapt_thresh = shi->mat->adapt_thresh_mir;
+ float aniso = 1.0 - shi->mat->aniso_gloss_mir;
+
+ int samples=0;
+
+ col[0] = col[1] = col[2] = 0.0;
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+
+ if (blur > 0.0) {
+ if (adapt_thresh != 0.0) samp_type = SAMP_TYPE_HALTON;
+ else samp_type = SAMP_TYPE_HAMMERSLEY;
+
+ /* all samples are generated per pixel */
+ qsa = QMC_initSampler(samp_type, max_samples);
+ QMC_initPixel(qsa, shi->thread);
+ } else
+ max_samples = 1;
+
+ while (samples < max_samples) {
+
+ if (max_samples > 1) {
+ /* get a quasi-random vector from a phong-weighted disc */
+ QMC_samplePhong(samp3d, qsa, shi->thread, samples, blur);
+
+ /* find the normal's perpendicular plane, blurring along tangents
+ * if tangent shading enabled */
+ if (shi->mat->mode & (MA_TANGENT_V)) {
+ Crossf(orthx, shi->vn, shi->tang); // bitangent
+ VECCOPY(orthy, shi->tang);
+ VecMulf(orthx, samp3d[0]);
+ VecMulf(orthy, samp3d[1]*aniso);
+ } else {
+ VecOrthoBasisf(shi->vn, orthx, orthy);
+ VecMulf(orthx, samp3d[0]);
+ VecMulf(orthy, samp3d[1]);
+ }
+
+ /* and perturb the normal in it */
+ VecAddf(v_nor_new, shi->vn, orthx);
+ VecAddf(v_nor_new, v_nor_new, orthy);
+ Normalize(v_nor_new);
+ } else {
+ /* no blurriness, use the original normal */
+ VECCOPY(v_nor_new, shi->vn);
+ }
+
+ if((shi->vlr->flag & R_SMOOTH))
+ reflection(v_reflect, v_nor_new, shi->view, shi->facenor);
+ else
+ reflection(v_reflect, v_nor_new, shi->view, NULL);
+
+ traceray(shi, shr, shi->mat->ray_depth, shi->co, v_reflect, sampcol, shi->obi, shi->vlr, 0);
+
+
+ col[0] += sampcol[0];
+ col[1] += sampcol[1];
+ col[2] += sampcol[2];
+
+ /* for variance calc */
+ colsq[0] += sampcol[0]*sampcol[0];
+ colsq[1] += sampcol[1]*sampcol[1];
+ colsq[2] += sampcol[2]*sampcol[2];
+
+ samples++;
+
+ /* adaptive sampling */
+ if (adapt_thresh > 0.0 && samples > max_samples/3)
+ {
+ if (adaptive_sample_variance(samples, col, colsq, adapt_thresh))
+ break;
+
+ /* if the pixel so far is very dark, we can get away with less samples */
+ if ( (col[0] + col[1] + col[2])/3.0/(float)samples < 0.01 )
+ max_samples--;
+
+ /* reduce samples when reflection is dim due to low ray mirror blend value or fresnel factor
+ * and when reflection is blurry */
+ if (fresnelfac < 0.1 * (blur+1)) {
+ max_samples--;
+
+ /* even more for very dim */
+ if (fresnelfac < 0.05 * (blur+1))
+ max_samples--;
+ }
+ }
+ }
+
+ col[0] /= (float)samples;
+ col[1] /= (float)samples;
+ col[2] /= (float)samples;
+
+ if (qsa) QMC_freeSampler(qsa);
+}
+
+/* extern call from render loop */
+void ray_trace(ShadeInput *shi, ShadeResult *shr)
+{
+ VlakRen *vlr;
+ float i, f, f1, fr, fg, fb;
+ float mircol[4], tracol[4];
+ float diff[3];
+ int do_tra, do_mir;
+
+ do_tra= ((shi->mat->mode & (MA_RAYTRANSP)) && shr->alpha!=1.0f);
+ do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f);
+ vlr= shi->vlr;
+
+ /* raytrace mirror amd refract like to separate the spec color */
+ if(shi->combinedflag & SCE_PASS_SPEC)
+ VECSUB(diff, shr->combined, shr->spec) /* no ; */
+ else
+ VECCOPY(diff, shr->combined);
+
+ if(do_tra) {
+ float olddiff[3];
+
+ trace_refract(tracol, shi, shr);
+
+ f= shr->alpha; f1= 1.0f-f;
+ fr= 1.0f+ shi->mat->filter*(shi->r-1.0f);
+ fg= 1.0f+ shi->mat->filter*(shi->g-1.0f);
+ fb= 1.0f+ shi->mat->filter*(shi->b-1.0f);
+
+ /* for refract pass */
+ VECCOPY(olddiff, diff);
+
+ diff[0]= f*diff[0] + f1*fr*tracol[0];
+ diff[1]= f*diff[1] + f1*fg*tracol[1];
+ diff[2]= f*diff[2] + f1*fb*tracol[2];
+
+ if(shi->passflag & SCE_PASS_REFRACT)
+ VECSUB(shr->refr, diff, olddiff);
+
+ if(!(shi->combinedflag & SCE_PASS_REFRACT))
+ VECSUB(diff, diff, shr->refr);
+
+ shr->alpha= tracol[3];
+ }
+
+ if(do_mir) {
+
+ i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir);
+ if(i!=0.0f) {
+
+ trace_reflect(mircol, shi, shr, i);
+
+ fr= i*shi->mirr;
+ fg= i*shi->mirg;
+ fb= i*shi->mirb;
+
+ if(shi->passflag & SCE_PASS_REFLECT) {
+ /* mirror pass is not blocked out with spec */
+ shr->refl[0]= fr*mircol[0] - fr*diff[0];
+ shr->refl[1]= fg*mircol[1] - fg*diff[1];
+ shr->refl[2]= fb*mircol[2] - fb*diff[2];
+ }
+
+ if(shi->combinedflag & SCE_PASS_REFLECT) {
+
+ f= fr*(1.0f-shr->spec[0]); f1= 1.0f-i;
+ diff[0]= f*mircol[0] + f1*diff[0];
+
+ f= fg*(1.0f-shr->spec[1]); f1= 1.0f-i;
+ diff[1]= f*mircol[1] + f1*diff[1];
+
+ f= fb*(1.0f-shr->spec[2]); f1= 1.0f-i;
+ diff[2]= f*mircol[2] + f1*diff[2];
+ }
+ }
+ }
+ /* put back together */
+ if(shi->combinedflag & SCE_PASS_SPEC)
+ VECADD(shr->combined, diff, shr->spec) /* no ; */
+ else
+ VECCOPY(shr->combined, diff);
+}
+
+/* color 'shadfac' passes through 'col' with alpha and filter */
+/* filter is only applied on alpha defined transparent part */
+static void addAlphaLight(float *shadfac, float *col, float alpha, float filter)
+{
+ float fr, fg, fb;
+
+ fr= 1.0f+ filter*(col[0]-1.0f);
+ fg= 1.0f+ filter*(col[1]-1.0f);
+ fb= 1.0f+ filter*(col[2]-1.0f);
+
+ shadfac[0]= alpha*col[0] + fr*(1.0f-alpha)*shadfac[0];
+ shadfac[1]= alpha*col[1] + fg*(1.0f-alpha)*shadfac[1];
+ shadfac[2]= alpha*col[2] + fb*(1.0f-alpha)*shadfac[2];
+
+ shadfac[3]= (1.0f-alpha)*shadfac[3];
+}
+
+static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
+{
+ /* ray to lamp, find first face that intersects, check alpha properties,
+ if it has col[3]>0.0f continue. so exit when alpha is full */
+ ShadeInput shi;
+ ShadeResult shr;
+
+ if(RE_ray_tree_intersect(R.raytree, is)) {
+ float d= 1.0f;
+ /* we got a face */
+
+ /* Warning, This is not that nice, and possibly a bit slow for every ray,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ shi.depth= 1; /* only used to indicate tracing */
+ shi.mask= 1;
+
+ /*shi.osatex= 0;
+ shi.thread= shi.sample= 0;
+ shi.lay= 0;
+ shi.passflag= 0;
+ shi.combinedflag= 0;
+ shi.do_preview= 0;
+ shi.light_override= NULL;
+ shi.mat_override= NULL;*/
+
+ shade_ray(is, &shi, &shr);
+ if (traflag & RAY_TRA)
+ d= shade_by_transmission(is, &shi, &shr);
+
+ /* mix colors based on shadfac (rgb + amount of light factor) */
+ addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
+
+ if(depth>0 && is->col[3]>0.0f) {
+
+ /* adapt isect struct */
+ VECCOPY(is->start, shi.co);
+ is->oborig= RAY_OBJECT_SET(&R, shi.obi);
+ is->faceorig= (RayFace*)shi.vlr;
+
+ ray_trace_shadow_tra(is, depth-1, traflag | RAY_TRA);
+ }
+ }
+}
+
+/* not used, test function for ambient occlusion (yaf: pathlight) */
+/* main problem; has to be called within shading loop, giving unwanted recursion */
+int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
+{
+ static int counter=0, only_one= 0;
+ extern float hashvectf[];
+ Isect isec;
+ ShadeInput shi;
+ ShadeResult shr_t;
+ float vec[3], accum[3], div= 0.0f, maxsize= RE_ray_tree_max_size(R.raytree);
+ int a;
+
+ if(only_one) {
+ return 0;
+ }
+ only_one= 1;
+
+ accum[0]= accum[1]= accum[2]= 0.0f;
+ isec.mode= RE_RAY_MIRROR;
+ isec.faceorig= (RayFace*)ship->vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, ship->obi);
+
+ for(a=0; a<8*8; a++) {
+
+ counter+=3;
+ counter %= 768;
+ VECCOPY(vec, hashvectf+counter);
+ if(ship->vn[0]*vec[0]+ship->vn[1]*vec[1]+ship->vn[2]*vec[2]>0.0f) {
+ vec[0]-= vec[0];
+ vec[1]-= vec[1];
+ vec[2]-= vec[2];
+ }
+ VECCOPY(isec.start, ship->co);
+ isec.end[0]= isec.start[0] + maxsize*vec[0];
+ isec.end[1]= isec.start[1] + maxsize*vec[1];
+ isec.end[2]= isec.start[2] + maxsize*vec[2];
+
+ if(RE_ray_tree_intersect(R.raytree, &isec)) {
+ float fac;
+
+ /* Warning, This is not that nice, and possibly a bit slow for every ray,
+ however some variables were not initialized properly in, unless using shade_input_initialize(...), we need to do a memset */
+ memset(&shi, 0, sizeof(ShadeInput));
+ /* end warning! - Campbell */
+
+ shade_ray(&isec, &shi, &shr_t);
+ fac= isec.labda*isec.labda;
+ fac= 1.0f;
+ accum[0]+= fac*(shr_t.diff[0]+shr_t.spec[0]);
+ accum[1]+= fac*(shr_t.diff[1]+shr_t.spec[1]);
+ accum[2]+= fac*(shr_t.diff[2]+shr_t.spec[2]);
+ div+= fac;
+ }
+ else div+= 1.0f;
+ }
+
+ if(div!=0.0f) {
+ shr->diff[0]+= accum[0]/div;
+ shr->diff[1]+= accum[1]/div;
+ shr->diff[2]+= accum[2]/div;
+ }
+ shr->alpha= 1.0f;
+
+ only_one= 0;
+ return 1;
+}
+
+/* aolight: function to create random unit sphere vectors for total random sampling */
+static void RandomSpherical(float *v)
+{
+ float r;
+ v[2] = 2.f*BLI_frand()-1.f;
+ if ((r = 1.f - v[2]*v[2])>0.f) {
+ float a = 6.283185307f*BLI_frand();
+ r = sqrt(r);
+ v[0] = r * cos(a);
+ v[1] = r * sin(a);
+ }
+ else v[2] = 1.f;
+}
+
+/* calc distributed spherical energy */
+static void DS_energy(float *sphere, int tot, float *vec)
+{
+ float *fp, fac, force[3], res[3];
+ int a;
+
+ res[0]= res[1]= res[2]= 0.0f;
+
+ for(a=0, fp=sphere; a<tot; a++, fp+=3) {
+ VecSubf(force, vec, fp);
+ fac= force[0]*force[0] + force[1]*force[1] + force[2]*force[2];
+ if(fac!=0.0f) {
+ fac= 1.0f/fac;
+ res[0]+= fac*force[0];
+ res[1]+= fac*force[1];
+ res[2]+= fac*force[2];
+ }
+ }
+
+ VecMulf(res, 0.5);
+ VecAddf(vec, vec, res);
+ Normalize(vec);
+
+}
+
+/* called from convertBlenderScene.c */
+/* creates an equally distributed spherical sample pattern */
+/* and allocates threadsafe memory */
+void init_ao_sphere(World *wrld)
+{
+ float *fp;
+ int a, tot, iter= 16;
+
+ /* we make twice the amount of samples, because only a hemisphere is used */
+ tot= 2*wrld->aosamp*wrld->aosamp;
+
+ wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere");
+
+ /* fixed random */
+ BLI_srandom(tot);
+
+ /* init */
+ fp= wrld->aosphere;
+ for(a=0; a<tot; a++, fp+= 3) {
+ RandomSpherical(fp);
+ }
+
+ while(iter--) {
+ for(a=0, fp= wrld->aosphere; a<tot; a++, fp+= 3) {
+ DS_energy(wrld->aosphere, tot, fp);
+ }
+ }
+
+ /* tables */
+ wrld->aotables= MEM_mallocN(BLENDER_MAX_THREADS*3*tot*sizeof(float), "AO tables");
+}
+
+/* give per thread a table, we have to compare xs ys because of way OSA works... */
+static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot)
+{
+ static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS];
+ static int firsttime= 1;
+
+ if(firsttime) {
+ memset(xso, 255, sizeof(xso));
+ memset(yso, 255, sizeof(yso));
+ firsttime= 0;
+ }
+
+ if(xs==xso[thread] && ys==yso[thread]) return R.wrld.aotables+ thread*tot*3;
+ if(test) return NULL;
+ xso[thread]= xs; yso[thread]= ys;
+ return R.wrld.aotables+ thread*tot*3;
+}
+
+static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
+{
+ int tot;
+ float *vec;
+
+ if(resol>16) resol= 16;
+
+ tot= 2*resol*resol;
+
+ if (type & WO_AORNDSMP) {
+ static float sphere[2*3*256];
+ int a;
+
+ /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */
+ vec= sphere;
+ for (a=0; a<tot; a++, vec+=3) {
+ RandomSpherical(vec);
+ }
+
+ return sphere;
+ }
+ else {
+ float *sphere;
+ float cosfi, sinfi, cost, sint;
+ float ang, *vec1;
+ int a;
+
+ sphere= threadsafe_table_sphere(1, thread, xs, ys, tot); // returns table if xs and ys were equal to last call
+ if(sphere==NULL) {
+ sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
+
+ // random rotation
+ ang= BLI_thread_frand(thread);
+ sinfi= sin(ang); cosfi= cos(ang);
+ ang= BLI_thread_frand(thread);
+ sint= sin(ang); cost= cos(ang);
+
+ vec= R.wrld.aosphere;
+ vec1= sphere;
+ for (a=0; a<tot; a++, vec+=3, vec1+=3) {
+ vec1[0]= cost*cosfi*vec[0] - sinfi*vec[1] + sint*cosfi*vec[2];
+ vec1[1]= cost*sinfi*vec[0] + cosfi*vec[1] + sint*sinfi*vec[2];
+ vec1[2]= -sint*vec[0] + cost*vec[2];
+ }
+ }
+ return sphere;
+ }
+}
+
+void ray_ao_qmc(ShadeInput *shi, float *shadfac)
+{
+ Isect isec;
+ QMCSampler *qsa=NULL;
+ float samp3d[3];
+ float up[3], side[3], dir[3], nrm[3];
+
+ float maxdist = R.wrld.aodist;
+ float fac=0.0f, prev=0.0f;
+ float adapt_thresh = G.scene->world->ao_adapt_thresh;
+ float adapt_speed_fac = G.scene->world->ao_adapt_speed_fac;
+ float bias = G.scene->world->aobias;
+
+ int samples=0;
+ int max_samples = R.wrld.aosamp*R.wrld.aosamp;
+
+ float dxyview[3], skyadded=0, div;
+ int aocolor;
+
+ isec.faceorig= (RayFace*)shi->vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
+ isec.face_last= NULL;
+ isec.ob_last= 0;
+ isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
+ isec.lay= -1;
+
+ shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
+
+ /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
+ aocolor= R.wrld.aocolor;
+ if(shi->mat->mode & MA_ONLYSHADOW)
+ aocolor= WO_AOPLAIN;
+
+ if(aocolor == WO_AOSKYTEX) {
+ dxyview[0]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[1]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[2]= 0.0f;
+ }
+
+ /* bias prevents smoothed faces to appear flat */
+ if(shi->vlr->flag & R_SMOOTH) {
+ bias= G.scene->world->aobias;
+ VECCOPY(nrm, shi->vn);
+ }
+ else {
+ bias= 0.0f;
+ VECCOPY(nrm, shi->facenor);
+ }
+
+ VecOrthoBasisf(nrm, up, side);
+
+ /* sampling init */
+ if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {
+ float speedfac;
+
+ speedfac = get_avg_speed(shi) * adapt_speed_fac;
+ CLAMP(speedfac, 1.0, 1000.0);
+ max_samples /= speedfac;
+ if (max_samples < 5) max_samples = 5;
+
+ qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
+ } else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
+ qsa = R.qsa;
+
+ QMC_initPixel(qsa, shi->thread);
+
+ while (samples < max_samples) {
+
+ /* sampling, returns quasi-random vector in unit hemisphere */
+ QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
+
+ dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);
+ dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);
+ dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);
+
+ Normalize(dir);
+
+ VECCOPY(isec.start, shi->co);
+ isec.end[0] = shi->co[0] - maxdist*dir[0];
+ isec.end[1] = shi->co[1] - maxdist*dir[1];
+ isec.end[2] = shi->co[2] - maxdist*dir[2];
+
+ prev = fac;
+
+ if(RE_ray_tree_intersect(R.raytree, &isec)) {
+ if (R.wrld.aomode & WO_AODIST) fac+= exp(-isec.labda*R.wrld.aodistfac);
+ else fac+= 1.0f;
+ }
+ else if(aocolor!=WO_AOPLAIN) {
+ float skycol[4];
+ float skyfac, view[3];
+
+ view[0]= -dir[0];
+ view[1]= -dir[1];
+ view[2]= -dir[2];
+ Normalize(view);
+
+ if(aocolor==WO_AOSKYCOL) {
+ skyfac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
+ shadfac[0]+= (1.0f-skyfac)*R.wrld.horr + skyfac*R.wrld.zenr;
+ shadfac[1]+= (1.0f-skyfac)*R.wrld.horg + skyfac*R.wrld.zeng;
+ shadfac[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
+ }
+ else { /* WO_AOSKYTEX */
+ shadeSkyView(skycol, isec.start, view, dxyview);
+ shadfac[0]+= skycol[0];
+ shadfac[1]+= skycol[1];
+ shadfac[2]+= skycol[2];
+ }
+ skyadded++;
+ }
+
+ samples++;
+
+ if (qsa->type == SAMP_TYPE_HALTON) {
+ /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
+ if (adapt_thresh > 0.0 && (samples > max_samples/2) ) {
+
+ if (adaptive_sample_contrast_val(samples, prev, fac, adapt_thresh)) {
+ break;
+ }
+ }
+ }
+ }
+
+ if(aocolor!=WO_AOPLAIN && skyadded) {
+ div= (1.0f - fac/(float)samples)/((float)skyadded);
+
+ shadfac[0]*= div; // average color times distances/hits formula
+ shadfac[1]*= div; // average color times distances/hits formula
+ shadfac[2]*= div; // average color times distances/hits formula
+ } else {
+ shadfac[0]= shadfac[1]= shadfac[2]= 1.0f - fac/(float)samples;
+ }
+
+ if ((qsa) && (qsa->type == SAMP_TYPE_HALTON)) QMC_freeSampler(qsa);
+}
+
+/* extern call from shade_lamp_loop, ambient occlusion calculus */
+void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
+{
+ Isect isec;
+ float *vec, *nrm, div, bias, sh=0.0f;
+ float maxdist = R.wrld.aodist;
+ float dxyview[3];
+ int j= -1, tot, actual=0, skyadded=0, aocolor;
+
+ isec.faceorig= (RayFace*)shi->vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
+ isec.face_last= NULL;
+ isec.ob_last= 0;
+ isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
+ isec.lay= -1;
+
+
+ shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
+
+ /* bias prevents smoothed faces to appear flat */
+ if(shi->vlr->flag & R_SMOOTH) {
+ bias= G.scene->world->aobias;
+ nrm= shi->vn;
+ }
+ else {
+ bias= 0.0f;
+ nrm= shi->facenor;
+ }
+
+ /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
+ aocolor= R.wrld.aocolor;
+ if(shi->mat->mode & MA_ONLYSHADOW)
+ aocolor= WO_AOPLAIN;
+
+ vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
+
+ // warning: since we use full sphere now, and dotproduct is below, we do twice as much
+ tot= 2*R.wrld.aosamp*R.wrld.aosamp;
+
+ if(aocolor == WO_AOSKYTEX) {
+ dxyview[0]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[1]= 1.0f/(float)R.wrld.aosamp;
+ dxyview[2]= 0.0f;
+ }
+
+ while(tot--) {
+
+ if ((vec[0]*nrm[0] + vec[1]*nrm[1] + vec[2]*nrm[2]) > bias) {
+ /* only ao samples for mask */
+ if(R.r.mode & R_OSA) {
+ j++;
+ if(j==R.osa) j= 0;
+ if(!(shi->mask & (1<<j))) {
+ vec+=3;
+ continue;
+ }
+ }
+
+ actual++;
+
+ /* always set start/end, RE_ray_tree_intersect clips it */
+ VECCOPY(isec.start, shi->co);
+ isec.end[0] = shi->co[0] - maxdist*vec[0];
+ isec.end[1] = shi->co[1] - maxdist*vec[1];
+ isec.end[2] = shi->co[2] - maxdist*vec[2];
+
+ /* do the trace */
+ if(RE_ray_tree_intersect(R.raytree, &isec)) {
+ if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac);
+ else sh+= 1.0f;
+ }
+ else if(aocolor!=WO_AOPLAIN) {
+ float skycol[4];
+ float fac, view[3];
+
+ view[0]= -vec[0];
+ view[1]= -vec[1];
+ view[2]= -vec[2];
+ Normalize(view);
+
+ if(aocolor==WO_AOSKYCOL) {
+ fac= 0.5*(1.0f+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]);
+ shadfac[0]+= (1.0f-fac)*R.wrld.horr + fac*R.wrld.zenr;
+ shadfac[1]+= (1.0f-fac)*R.wrld.horg + fac*R.wrld.zeng;
+ shadfac[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
+ }
+ else { /* WO_AOSKYTEX */
+ shadeSkyView(skycol, isec.start, view, dxyview);
+ shadfac[0]+= skycol[0];
+ shadfac[1]+= skycol[1];
+ shadfac[2]+= skycol[2];
+ }
+ skyadded++;
+ }
+ }
+ // samples
+ vec+= 3;
+ }
+
+ if(actual==0) sh= 1.0f;
+ else sh = 1.0f - sh/((float)actual);
+
+ if(aocolor!=WO_AOPLAIN && skyadded) {
+ div= sh/((float)skyadded);
+
+ shadfac[0]*= div; // average color times distances/hits formula
+ shadfac[1]*= div; // average color times distances/hits formula
+ shadfac[2]*= div; // average color times distances/hits formula
+ }
+ else {
+ shadfac[0]= shadfac[1]= shadfac[2]= sh;
+ }
+}
+
+void ray_ao(ShadeInput *shi, float *shadfac)
+{
+ /* Unfortunately, the unusual way that the sphere sampler calculates roughly twice as many
+ * samples as are actually traced, and skips them based on bias and OSA settings makes it very difficult
+ * to reuse code between these two functions. This is the easiest way I can think of to do it
+ * --broken */
+ if (ELEM(R.wrld.ao_samp_method, WO_AOSAMP_HAMMERSLEY, WO_AOSAMP_HALTON))
+ ray_ao_qmc(shi, shadfac);
+ else if (R.wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+ ray_ao_spheresamp(shi, shadfac);
+}
+
+
+static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
+{
+ QMCSampler *qsa=NULL;
+ QMCSampler *qsa_jit=NULL;
+ int samples=0;
+ float samp3d[3], jit[3], jitbias= 0.0f;
+
+ float fac=0.0f, vec[3];
+ float colsq[4];
+ float adapt_thresh = lar->adapt_thresh;
+ int max_samples = lar->ray_totsamp;
+ float pos[3];
+ int do_soft=1, full_osa=0;
+
+ colsq[0] = colsq[1] = colsq[2] = 0.0;
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
+ } else
+ shadfac[3]= 1.0f;
+
+ if (lar->ray_totsamp < 2) do_soft = 0;
+ if ((R.r.mode & R_OSA) && (R.osa > 0) && (shi->vlr->flag & R_FULL_OSA)) full_osa = 1;
+
+ if (full_osa) {
+ if (do_soft) max_samples = max_samples/R.osa + 1;
+ else max_samples = 1;
+ } else {
+ if (do_soft) max_samples = lar->ray_totsamp;
+ else max_samples = (R.osa > 4)?R.osa:5;
+ }
+
+ if(shi->vlr && ((shi->vlr->flag & R_FULL_OSA) == 0))
+ jitbias= 0.5f*(VecLength(shi->dxco) + VecLength(shi->dyco));
+
+ /* sampling init */
+ if (lar->ray_samp_method==LA_SAMP_HALTON) {
+ qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
+ qsa_jit = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
+ } else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY) {
+ qsa = lar->qsa;
+ qsa_jit = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, max_samples);
+ }
+
+ QMC_initPixel(qsa, shi->thread);
+ QMC_initPixel(qsa_jit, shi->thread);
+
+ VECCOPY(vec, lampco);
+
+
+ while (samples < max_samples) {
+ isec->faceorig= (RayFace*)shi->vlr;
+ isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
+
+ /* manually jitter the start shading co-ord per sample
+ * based on the pre-generated OSA texture sampling offsets,
+ * for anti-aliasing sharp shadow edges. */
+ VECCOPY(pos, shi->co);
+ if (shi->vlr && !full_osa) {
+ QMC_sampleRect(jit, qsa_jit, shi->thread, samples, 1.0, 1.0);
+
+ pos[0] += shi->dxco[0]*jit[0] + shi->dyco[0]*jit[1];
+ pos[1] += shi->dxco[1]*jit[0] + shi->dyco[1]*jit[1];
+ pos[2] += shi->dxco[2]*jit[0] + shi->dyco[2]*jit[1];
+ }
+
+ if (do_soft) {
+ /* sphere shadow source */
+ if (lar->type == LA_LOCAL) {
+ float ru[3], rv[3], v[3], s[3];
+
+ /* calc tangent plane vectors */
+ v[0] = pos[0] - lampco[0];
+ v[1] = pos[1] - lampco[1];
+ v[2] = pos[2] - lampco[2];
+ Normalize(v);
+ VecOrthoBasisf(v, ru, rv);
+
+ /* sampling, returns quasi-random vector in area_size disc */
+ QMC_sampleDisc(samp3d, qsa, shi->thread, samples,lar->area_size);
+
+ /* distribute disc samples across the tangent plane */
+ s[0] = samp3d[0]*ru[0] + samp3d[1]*rv[0];
+ s[1] = samp3d[0]*ru[1] + samp3d[1]*rv[1];
+ s[2] = samp3d[0]*ru[2] + samp3d[1]*rv[2];
+
+ VECCOPY(samp3d, s);
+
+ if(jitbias != 0.0f) {
+ /* bias away somewhat to avoid self intersection */
+ pos[0] -= jitbias*v[0];
+ pos[1] -= jitbias*v[1];
+ pos[2] -= jitbias*v[2];
+ }
+ }
+ else {
+ /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
+ QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey);
+
+ /* align samples to lamp vector */
+ Mat3MulVecfl(lar->mat, samp3d);
+ }
+ isec->end[0]= vec[0]+samp3d[0];
+ isec->end[1]= vec[1]+samp3d[1];
+ isec->end[2]= vec[2]+samp3d[2];
+ } else {
+ VECCOPY(isec->end, vec);
+ }
+
+ if(jitbias != 0.0f && !(do_soft && lar->type==LA_LOCAL)) {
+ /* bias away somewhat to avoid self intersection */
+ float v[3];
+
+ VECSUB(v, pos, isec->end);
+ Normalize(v);
+
+ pos[0] -= jitbias*v[0];
+ pos[1] -= jitbias*v[1];
+ pos[2] -= jitbias*v[2];
+ }
+
+ VECCOPY(isec->start, pos);
+
+
+ /* trace the ray */
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ isec->col[0]= isec->col[1]= isec->col[2]= 1.0f;
+ isec->col[3]= 1.0f;
+
+ ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0);
+ shadfac[0] += isec->col[0];
+ shadfac[1] += isec->col[1];
+ shadfac[2] += isec->col[2];
+ shadfac[3] += isec->col[3];
+
+ /* for variance calc */
+ colsq[0] += isec->col[0]*isec->col[0];
+ colsq[1] += isec->col[1]*isec->col[1];
+ colsq[2] += isec->col[2]*isec->col[2];
+ }
+ else {
+ if( RE_ray_tree_intersect(R.raytree, isec) ) fac+= 1.0f;
+ }
+
+ samples++;
+
+ if ((lar->ray_samp_method == LA_SAMP_HALTON)) {
+
+ /* adaptive sampling - consider samples below threshold as in shadow (or vice versa) and exit early */
+ if ((max_samples > 4) && (adapt_thresh > 0.0) && (samples > max_samples / 3)) {
+ if (isec->mode==RE_RAY_SHADOW_TRA) {
+ if ((shadfac[3] / samples > (1.0-adapt_thresh)) || (shadfac[3] / samples < adapt_thresh))
+ break;
+ else if (adaptive_sample_variance(samples, shadfac, colsq, adapt_thresh))
+ break;
+ } else {
+ if ((fac / samples > (1.0-adapt_thresh)) || (fac / samples < adapt_thresh))
+ break;
+ }
+ }
+ }
+ }
+
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0] /= samples;
+ shadfac[1] /= samples;
+ shadfac[2] /= samples;
+ shadfac[3] /= samples;
+ } else
+ shadfac[3]= 1.0f-fac/samples;
+
+ if (qsa_jit) QMC_freeSampler(qsa_jit);
+ if ((qsa) && (qsa->type == SAMP_TYPE_HALTON)) QMC_freeSampler(qsa);
+}
+
+static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
+{
+ /* area soft shadow */
+ float *jitlamp;
+ float fac=0.0f, div=0.0f, vec[3];
+ int a, j= -1, mask;
+
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
+ }
+ else shadfac[3]= 1.0f;
+
+ fac= 0.0f;
+ jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys);
+
+ a= lar->ray_totsamp;
+
+ /* this correction to make sure we always take at least 1 sample */
+ mask= shi->mask;
+ if(a==4) mask |= (mask>>4)|(mask>>8);
+ else if(a==9) mask |= (mask>>9);
+
+ while(a--) {
+
+ if(R.r.mode & R_OSA) {
+ j++;
+ if(j>=R.osa) j= 0;
+ if(!(mask & (1<<j))) {
+ jitlamp+= 2;
+ continue;
+ }
+ }
+
+ isec->faceorig= (RayFace*)shi->vlr;
+ isec->oborig= RAY_OBJECT_SET(&R, shi->obi);
+
+ vec[0]= jitlamp[0];
+ vec[1]= jitlamp[1];
+ vec[2]= 0.0f;
+ Mat3MulVecfl(lar->mat, vec);
+
+ /* set start and end, RE_ray_tree_intersect clips it */
+ VECCOPY(isec->start, shi->co);
+ isec->end[0]= lampco[0]+vec[0];
+ isec->end[1]= lampco[1]+vec[1];
+ isec->end[2]= lampco[2]+vec[2];
+
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
+ isec->col[0]= isec->col[1]= isec->col[2]= 1.0f;
+ isec->col[3]= 1.0f;
+
+ ray_trace_shadow_tra(isec, DEPTH_SHADOW_TRA, 0);
+ shadfac[0] += isec->col[0];
+ shadfac[1] += isec->col[1];
+ shadfac[2] += isec->col[2];
+ shadfac[3] += isec->col[3];
+ }
+ else if( RE_ray_tree_intersect(R.raytree, isec) ) fac+= 1.0f;
+
+ div+= 1.0f;
+ jitlamp+= 2;
+ }
+
+ if(isec->mode==RE_RAY_SHADOW_TRA) {
+ shadfac[0] /= div;
+ shadfac[1] /= div;
+ shadfac[2] /= div;
+ shadfac[3] /= div;
+ }
+ else {
+ // sqrt makes nice umbra effect
+ if(lar->ray_samp_type & LA_SAMP_UMBRA)
+ shadfac[3]= sqrt(1.0f-fac/div);
+ else
+ shadfac[3]= 1.0f-fac/div;
+ }
+}
+/* extern call from shade_lamp_loop */
+void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
+{
+ Isect isec;
+ float lampco[3], maxsize;
+
+ /* setup isec */
+ if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
+ else isec.mode= RE_RAY_SHADOW;
+
+ if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
+
+ /* only when not mir tracing, first hit optimm */
+ if(shi->depth==0) {
+ isec.face_last= (RayFace*)lar->vlr_last[shi->thread];
+ isec.ob_last= RAY_OBJECT_SET(&R, lar->obi_last[shi->thread]);
+ }
+ else {
+ isec.face_last= NULL;
+ isec.ob_last= 0;
+ }
+
+ if(lar->type==LA_SUN || lar->type==LA_HEMI) {
+ maxsize= RE_ray_tree_max_size(R.raytree);
+ lampco[0]= shi->co[0] - maxsize*lar->vec[0];
+ lampco[1]= shi->co[1] - maxsize*lar->vec[1];
+ lampco[2]= shi->co[2] - maxsize*lar->vec[2];
+ }
+ else {
+ VECCOPY(lampco, lar->co);
+ }
+
+ if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) {
+
+ ray_shadow_qmc(shi, lar, lampco, shadfac, &isec);
+
+ } else {
+ if(lar->ray_totsamp<2) {
+
+ isec.faceorig= (RayFace*)shi->vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
+ shadfac[3]= 1.0f; // 1.0=full light
+
+ /* set up isec vec */
+ VECCOPY(isec.start, shi->co);
+ VECCOPY(isec.end, lampco);
+
+ if(isec.mode==RE_RAY_SHADOW_TRA) {
+ /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
+ isec.col[0]= isec.col[1]= isec.col[2]= 1.0f;
+ isec.col[3]= 1.0f;
+
+ ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA, 0);
+ QUATCOPY(shadfac, isec.col);
+ }
+ else if(RE_ray_tree_intersect(R.raytree, &isec)) shadfac[3]= 0.0f;
+ }
+ else {
+ ray_shadow_jitter(shi, lar, lampco, shadfac, &isec);
+ }
+ }
+
+ /* for first hit optim, set last interesected shadow face */
+ if(shi->depth==0) {
+ lar->vlr_last[shi->thread]= (VlakRen*)isec.face_last;
+ lar->obi_last[shi->thread]= RAY_OBJECT_GET(&R, isec.ob_last);
+ }
+
+}
+
+/* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */
+void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co)
+{
+ Isect isec;
+ float lampco[3], maxsize;
+
+ /* setup isec */
+ isec.mode= RE_RAY_SHADOW_TRA;
+
+ if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
+
+ if(lar->type==LA_SUN || lar->type==LA_HEMI) {
+ maxsize= RE_ray_tree_max_size(R.raytree);
+ lampco[0]= shi->co[0] - maxsize*lar->vec[0];
+ lampco[1]= shi->co[1] - maxsize*lar->vec[1];
+ lampco[2]= shi->co[2] - maxsize*lar->vec[2];
+ }
+ else {
+ VECCOPY(lampco, lar->co);
+ }
+
+ isec.faceorig= (RayFace*)shi->vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, shi->obi);
+
+ /* set up isec vec */
+ VECCOPY(isec.start, shi->co);
+ VECCOPY(isec.end, lampco);
+
+ if(RE_ray_tree_intersect(R.raytree, &isec)) {
+ /* we got a face */
+
+ /* render co */
+ co[0]= isec.start[0]+isec.labda*(isec.vec[0]);
+ co[1]= isec.start[1]+isec.labda*(isec.vec[1]);
+ co[2]= isec.start[2]+isec.labda*(isec.vec[2]);
+
+ *distfac= VecLength(isec.vec);
+ }
+ else
+ *distfac= 0.0f;
+}
+
+
diff --git a/source/blender/render/intern/source/raytrace.c b/source/blender/render/intern/source/raytrace.c
new file mode 100644
index 00000000000..7423a11764d
--- /dev/null
+++ b/source/blender/render/intern/source/raytrace.c
@@ -0,0 +1,1439 @@
+/**
+ * $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) 1990-1998 NeoGeo BV.
+ * All rights reserved.
+ *
+ * Contributors: 2004/2005 Blender Foundation, full recode
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* IMPORTANT NOTE: this code must be independent of any other render code
+ to use it outside the renderer! */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_material_types.h"
+
+#include "BKE_utildefines.h"
+
+#include "BLI_arithb.h"
+
+#include "RE_raytrace.h"
+
+/* ********** structs *************** */
+
+#define BRANCH_ARRAY 1024
+#define NODE_ARRAY 4096
+
+typedef struct Branch
+{
+ struct Branch *b[8];
+} Branch;
+
+typedef struct OcVal
+{
+ short ocx, ocy, ocz;
+} OcVal;
+
+typedef struct Node
+{
+ struct RayFace *v[8];
+ int ob[8];
+ struct OcVal ov[8];
+ struct Node *next;
+} Node;
+
+typedef struct Octree {
+ struct Branch **adrbranch;
+ struct Node **adrnode;
+ float ocsize; /* ocsize: mult factor, max size octree */
+ float ocfacx,ocfacy,ocfacz;
+ float min[3], max[3];
+ int ocres;
+ int branchcount, nodecount;
+ char *ocface; /* during building only */
+ RayCoordsFunc coordsfunc;
+ RayCheckFunc checkfunc;
+ RayObjectTransformFunc transformfunc;
+ void *userdata;
+} Octree;
+
+/* ******** globals ***************** */
+
+/* just for statistics */
+static int raycount;
+static int accepted, rejected, coherent_ray;
+
+
+/* **************** ocval method ******************* */
+/* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */
+
+#define OCVALRES 15
+#define BROW16(min, max) (((max)>=OCVALRES? 0xFFFF: (1<<(max+1))-1) - ((min>0)? ((1<<(min))-1):0) )
+
+static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, short y, short z, OcVal *ov)
+{
+ float min[3], max[3];
+ int ocmin, ocmax;
+
+ VECCOPY(min, v1);
+ VECCOPY(max, v1);
+ DO_MINMAX(v2, min, max);
+ DO_MINMAX(v3, min, max);
+ if(v4) {
+ DO_MINMAX(v4, min, max);
+ }
+
+ ocmin= OCVALRES*(min[0]-x);
+ ocmax= OCVALRES*(max[0]-x);
+ ov->ocx= BROW16(ocmin, ocmax);
+
+ ocmin= OCVALRES*(min[1]-y);
+ ocmax= OCVALRES*(max[1]-y);
+ ov->ocy= BROW16(ocmin, ocmax);
+
+ ocmin= OCVALRES*(min[2]-z);
+ ocmax= OCVALRES*(max[2]-z);
+ ov->ocz= BROW16(ocmin, ocmax);
+
+}
+
+static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2)
+{
+ int ocmin, ocmax;
+
+ if(vec1[0]<vec2[0]) {
+ ocmin= OCVALRES*(vec1[0] - xo);
+ ocmax= OCVALRES*(vec2[0] - xo);
+ } else {
+ ocmin= OCVALRES*(vec2[0] - xo);
+ ocmax= OCVALRES*(vec1[0] - xo);
+ }
+ ov->ocx= BROW16(ocmin, ocmax);
+
+ if(vec1[1]<vec2[1]) {
+ ocmin= OCVALRES*(vec1[1] - yo);
+ ocmax= OCVALRES*(vec2[1] - yo);
+ } else {
+ ocmin= OCVALRES*(vec2[1] - yo);
+ ocmax= OCVALRES*(vec1[1] - yo);
+ }
+ ov->ocy= BROW16(ocmin, ocmax);
+
+ if(vec1[2]<vec2[2]) {
+ ocmin= OCVALRES*(vec1[2] - zo);
+ ocmax= OCVALRES*(vec2[2] - zo);
+ } else {
+ ocmin= OCVALRES*(vec2[2] - zo);
+ ocmax= OCVALRES*(vec1[2] - zo);
+ }
+ ov->ocz= BROW16(ocmin, ocmax);
+}
+
+/* ************* octree ************** */
+
+static Branch *addbranch(Octree *oc, Branch *br, short ocb)
+{
+ int index;
+
+ if(br->b[ocb]) return br->b[ocb];
+
+ oc->branchcount++;
+ index= oc->branchcount>>12;
+
+ if(oc->adrbranch[index]==NULL)
+ oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch");
+
+ if(oc->branchcount>= BRANCH_ARRAY*4096) {
+ printf("error; octree branches full\n");
+ oc->branchcount=0;
+ }
+
+ return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095);
+}
+
+static Node *addnode(Octree *oc)
+{
+ int index;
+
+ oc->nodecount++;
+ index= oc->nodecount>>12;
+
+ if(oc->adrnode[index]==NULL)
+ oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode");
+
+ if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) {
+ printf("error; octree nodes full\n");
+ oc->nodecount=0;
+ }
+
+ return oc->adrnode[index]+(oc->nodecount & 4095);
+}
+
+static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3])
+{
+ static float nor[3], d;
+ float fx, fy, fz;
+
+ // init static vars
+ if(face) {
+ CalcNormFloat(rtf[0], rtf[1], rtf[2], nor);
+ d= -nor[0]*rtf[0][0] - nor[1]*rtf[0][1] - nor[2]*rtf[0][2];
+ return 0;
+ }
+
+ fx= x;
+ fy= y;
+ fz= z;
+
+ if((fx)*nor[0] + (fy)*nor[1] + (fz)*nor[2] + d > 0.0f) {
+ if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
+ if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d < 0.0f) return 1;
+
+ if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
+ if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d < 0.0f) return 1;
+ }
+ else {
+ if((fx+1)*nor[0] + (fy )*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
+ if((fx )*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz )*nor[2] + d > 0.0f) return 1;
+
+ if((fx )*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy )*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
+ if((fx )*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
+ if((fx+1)*nor[0] + (fy+1)*nor[1] + (fz+1)*nor[2] + d > 0.0f) return 1;
+ }
+
+ return 0;
+}
+
+static void ocwrite(Octree *oc, int ob, RayFace *face, int quad, short x, short y, short z, float rtf[][3])
+{
+ Branch *br;
+ Node *no;
+ short a, oc0, oc1, oc2, oc3, oc4, oc5;
+
+ x<<=2;
+ y<<=1;
+
+ br= oc->adrbranch[0];
+
+ if(oc->ocres==512) {
+ oc0= ((x & 1024)+(y & 512)+(z & 256))>>8;
+ br= addbranch(oc, br, oc0);
+ }
+ if(oc->ocres>=256) {
+ oc0= ((x & 512)+(y & 256)+(z & 128))>>7;
+ br= addbranch(oc, br, oc0);
+ }
+ if(oc->ocres>=128) {
+ oc0= ((x & 256)+(y & 128)+(z & 64))>>6;
+ br= addbranch(oc, br, oc0);
+ }
+
+ oc0= ((x & 128)+(y & 64)+(z & 32))>>5;
+ oc1= ((x & 64)+(y & 32)+(z & 16))>>4;
+ oc2= ((x & 32)+(y & 16)+(z & 8))>>3;
+ oc3= ((x & 16)+(y & 8)+(z & 4))>>2;
+ oc4= ((x & 8)+(y & 4)+(z & 2))>>1;
+ oc5= ((x & 4)+(y & 2)+(z & 1));
+
+ br= addbranch(oc, br,oc0);
+ br= addbranch(oc, br,oc1);
+ br= addbranch(oc, br,oc2);
+ br= addbranch(oc, br,oc3);
+ br= addbranch(oc, br,oc4);
+ no= (Node *)br->b[oc5];
+ if(no==NULL) br->b[oc5]= (Branch *)(no= addnode(oc));
+
+ while(no->next) no= no->next;
+
+ a= 0;
+ if(no->v[7]) { /* node full */
+ no->next= addnode(oc);
+ no= no->next;
+ }
+ else {
+ while(no->v[a]!=NULL) a++;
+ }
+
+ no->v[a]= face;
+ no->ob[a]= ob;
+
+ if(quad)
+ calc_ocval_face(rtf[0], rtf[1], rtf[2], rtf[3], x>>2, y>>1, z, &no->ov[a]);
+ else
+ calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x>>2, y>>1, z, &no->ov[a]);
+}
+
+static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3])
+{
+ int ocx1,ocx2,ocy1,ocy2;
+ int x,y,dx=0,dy=0;
+ float ox1,ox2,oy1,oy2;
+ float labda,labdao,labdax,labday,ldx,ldy;
+
+ ocx1= rts[b1][c1];
+ ocy1= rts[b1][c2];
+ ocx2= rts[b2][c1];
+ ocy2= rts[b2][c2];
+
+ if(ocx1==ocx2 && ocy1==ocy2) {
+ ocface[oc->ocres*ocx1+ocy1]= 1;
+ return;
+ }
+
+ ox1= rtf[b1][c1];
+ oy1= rtf[b1][c2];
+ ox2= rtf[b2][c1];
+ oy2= rtf[b2][c2];
+
+ if(ox1!=ox2) {
+ if(ox2-ox1>0.0f) {
+ labdax= (ox1-ocx1-1.0f)/(ox1-ox2);
+ ldx= -1.0f/(ox1-ox2);
+ dx= 1;
+ } else {
+ labdax= (ox1-ocx1)/(ox1-ox2);
+ ldx= 1.0f/(ox1-ox2);
+ dx= -1;
+ }
+ } else {
+ labdax=1.0f;
+ ldx=0;
+ }
+
+ if(oy1!=oy2) {
+ if(oy2-oy1>0.0f) {
+ labday= (oy1-ocy1-1.0f)/(oy1-oy2);
+ ldy= -1.0f/(oy1-oy2);
+ dy= 1;
+ } else {
+ labday= (oy1-ocy1)/(oy1-oy2);
+ ldy= 1.0f/(oy1-oy2);
+ dy= -1;
+ }
+ } else {
+ labday=1.0f;
+ ldy=0;
+ }
+
+ x=ocx1; y=ocy1;
+ labda= MIN2(labdax, labday);
+
+ while(TRUE) {
+
+ if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres);
+ else ocface[oc->ocres*x+y]= 1;
+
+ labdao=labda;
+ if(labdax==labday) {
+ labdax+=ldx;
+ x+=dx;
+ labday+=ldy;
+ y+=dy;
+ } else {
+ if(labdax<labday) {
+ labdax+=ldx;
+ x+=dx;
+ } else {
+ labday+=ldy;
+ y+=dy;
+ }
+ }
+ labda=MIN2(labdax,labday);
+ if(labda==labdao) break;
+ if(labda>=1.0f) break;
+ }
+ ocface[oc->ocres*ocx2+ocy2]=1;
+}
+
+static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin)
+{
+ short *ocmax;
+ int a, x, y, y1, y2;
+
+ ocmax=ocmin+3;
+
+ for(x=ocmin[c1];x<=ocmax[c1];x++) {
+ a= oc->ocres*x;
+ for(y=ocmin[c2];y<=ocmax[c2];y++) {
+ if(ocface[a+y]) {
+ y++;
+ while(ocface[a+y] && y!=ocmax[c2]) y++;
+ for(y1=ocmax[c2];y1>y;y1--) {
+ if(ocface[a+y1]) {
+ for(y2=y;y2<=y1;y2++) ocface[a+y2]=1;
+ y1=0;
+ }
+ }
+ y=ocmax[c2];
+ }
+ }
+ }
+}
+
+void RE_ray_tree_free(RayTree *tree)
+{
+ Octree *oc= (Octree*)tree;
+
+#if 0
+ printf("branches %d nodes %d\n", oc->branchcount, oc->nodecount);
+ printf("raycount %d \n", raycount);
+ printf("ray coherent %d \n", coherent_ray);
+ printf("accepted %d rejected %d\n", accepted, rejected);
+#endif
+ if(oc->ocface)
+ MEM_freeN(oc->ocface);
+
+ if(oc->adrbranch) {
+ int a= 0;
+ while(oc->adrbranch[a]) {
+ MEM_freeN(oc->adrbranch[a]);
+ oc->adrbranch[a]= NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrbranch);
+ oc->adrbranch= NULL;
+ }
+ oc->branchcount= 0;
+
+ if(oc->adrnode) {
+ int a= 0;
+ while(oc->adrnode[a]) {
+ MEM_freeN(oc->adrnode[a]);
+ oc->adrnode[a]= NULL;
+ a++;
+ }
+ MEM_freeN(oc->adrnode);
+ oc->adrnode= NULL;
+ }
+ oc->nodecount= 0;
+
+ MEM_freeN(oc);
+}
+
+RayTree *RE_ray_tree_create(int ocres, int totface, float *min, float *max, RayCoordsFunc coordsfunc, RayCheckFunc checkfunc, RayObjectTransformFunc transformfunc, void *userdata)
+{
+ Octree *oc;
+ float t00, t01, t02;
+ int c, ocres2;
+
+ oc= MEM_callocN(sizeof(Octree), "Octree");
+ oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches");
+ oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes");
+
+ oc->coordsfunc= coordsfunc;
+ oc->checkfunc= checkfunc;
+ oc->transformfunc= transformfunc;
+ oc->userdata= userdata;
+
+ /* only for debug info */
+ raycount=0;
+ accepted= 0;
+ rejected= 0;
+ coherent_ray= 0;
+
+ /* fill main octree struct */
+ oc->ocres= ocres;
+ ocres2= oc->ocres*oc->ocres;
+
+ VECCOPY(oc->min, min);
+ VECCOPY(oc->max, max);
+
+ oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree");
+
+ /* the lookup table, per face, for which nodes to fill in */
+ oc->ocface= MEM_callocN( 3*ocres2 + 8, "ocface");
+ memset(oc->ocface, 0, 3*ocres2);
+
+ for(c=0;c<3;c++) { /* octree enlarge, still needed? */
+ oc->min[c]-= 0.01f;
+ oc->max[c]+= 0.01f;
+ }
+
+ t00= oc->max[0]-oc->min[0];
+ t01= oc->max[1]-oc->min[1];
+ t02= oc->max[2]-oc->min[2];
+
+ /* this minus 0.1 is old safety... seems to be needed? */
+ oc->ocfacx= (oc->ocres-0.1)/t00;
+ oc->ocfacy= (oc->ocres-0.1)/t01;
+ oc->ocfacz= (oc->ocres-0.1)/t02;
+
+ oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */
+
+ return (RayTree*)oc;
+}
+
+void RE_ray_tree_add_face(RayTree *tree, int ob, RayFace *face)
+{
+ Octree *oc = (Octree*)tree;
+ float *v1, *v2, *v3, *v4, ocfac[3], rtf[4][3];
+ float co1[3], co2[3], co3[3], co4[3];
+ short rts[4][3], ocmin[6], *ocmax;
+ char *ocface= oc->ocface; // front, top, size view of face, to fill in
+ int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2;
+
+ ocfac[0]= oc->ocfacx;
+ ocfac[1]= oc->ocfacy;
+ ocfac[2]= oc->ocfacz;
+
+ ocres2= oc->ocres*oc->ocres;
+
+ ocmax= ocmin+3;
+
+ oc->coordsfunc(face, &v1, &v2, &v3, &v4);
+
+ VECCOPY(co1, v1);
+ VECCOPY(co2, v2);
+ VECCOPY(co3, v3);
+ if(v4)
+ VECCOPY(co4, v4);
+
+ if(ob >= RE_RAY_TRANSFORM_OFFS) {
+ float (*mat)[4]= (float(*)[4])oc->transformfunc(oc->userdata, ob);
+
+ if(mat) {
+ Mat4MulVecfl(mat, co1);
+ Mat4MulVecfl(mat, co2);
+ Mat4MulVecfl(mat, co3);
+ if(v4)
+ Mat4MulVecfl(mat, co4);
+ }
+ }
+
+ for(c=0;c<3;c++) {
+ rtf[0][c]= (co1[c]-oc->min[c])*ocfac[c] ;
+ rts[0][c]= (short)rtf[0][c];
+ rtf[1][c]= (co2[c]-oc->min[c])*ocfac[c] ;
+ rts[1][c]= (short)rtf[1][c];
+ rtf[2][c]= (co3[c]-oc->min[c])*ocfac[c] ;
+ rts[2][c]= (short)rtf[2][c];
+ if(v4) {
+ rtf[3][c]= (co4[c]-oc->min[c])*ocfac[c] ;
+ rts[3][c]= (short)rtf[3][c];
+ }
+ }
+
+ for(c=0;c<3;c++) {
+ oc1= rts[0][c];
+ oc2= rts[1][c];
+ oc3= rts[2][c];
+ if(v4==NULL) {
+ ocmin[c]= MIN3(oc1,oc2,oc3);
+ ocmax[c]= MAX3(oc1,oc2,oc3);
+ }
+ else {
+ oc4= rts[3][c];
+ ocmin[c]= MIN4(oc1,oc2,oc3,oc4);
+ ocmax[c]= MAX4(oc1,oc2,oc3,oc4);
+ }
+ if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1;
+ if(ocmin[c]<0) ocmin[c]=0;
+ }
+
+ if(ocmin[0]==ocmax[0] && ocmin[1]==ocmax[1] && ocmin[2]==ocmax[2]) {
+ ocwrite(oc, ob, face, (v4 != NULL), ocmin[0], ocmin[1], ocmin[2], rtf);
+ }
+ else {
+
+ d2dda(oc, 0,1,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 0,1,0,2,ocface,rts,rtf);
+ d2dda(oc, 0,1,1,2,ocface+2*ocres2,rts,rtf);
+ d2dda(oc, 1,2,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 1,2,0,2,ocface,rts,rtf);
+ d2dda(oc, 1,2,1,2,ocface+2*ocres2,rts,rtf);
+ if(v4==NULL) {
+ d2dda(oc, 2,0,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 2,0,0,2,ocface,rts,rtf);
+ d2dda(oc, 2,0,1,2,ocface+2*ocres2,rts,rtf);
+ }
+ else {
+ d2dda(oc, 2,3,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 2,3,0,2,ocface,rts,rtf);
+ d2dda(oc, 2,3,1,2,ocface+2*ocres2,rts,rtf);
+ d2dda(oc, 3,0,0,1,ocface+ocres2,rts,rtf);
+ d2dda(oc, 3,0,0,2,ocface,rts,rtf);
+ d2dda(oc, 3,0,1,2,ocface+2*ocres2,rts,rtf);
+ }
+ /* nothing todo with triangle..., just fills :) */
+ filltriangle(oc, 0,1,ocface+ocres2,ocmin);
+ filltriangle(oc, 0,2,ocface,ocmin);
+ filltriangle(oc, 1,2,ocface+2*ocres2,ocmin);
+
+ /* init static vars here */
+ face_in_node(face, 0,0,0, rtf);
+
+ for(x=ocmin[0];x<=ocmax[0];x++) {
+ a= oc->ocres*x;
+ for(y=ocmin[1];y<=ocmax[1];y++) {
+ if(ocface[a+y+ocres2]) {
+ b= oc->ocres*y+2*ocres2;
+ for(z=ocmin[2];z<=ocmax[2];z++) {
+ if(ocface[b+z] && ocface[a+z]) {
+ if(face_in_node(NULL, x, y, z, rtf))
+ ocwrite(oc, ob, face, (v4 != NULL), x,y,z, rtf);
+ }
+ }
+ }
+ }
+ }
+
+ /* same loops to clear octree, doubt it can be done smarter */
+ for(x=ocmin[0];x<=ocmax[0];x++) {
+ a= oc->ocres*x;
+ for(y=ocmin[1];y<=ocmax[1];y++) {
+ /* x-y */
+ ocface[a+y+ocres2]= 0;
+
+ b= oc->ocres*y + 2*ocres2;
+ for(z=ocmin[2];z<=ocmax[2];z++) {
+ /* y-z */
+ ocface[b+z]= 0;
+ /* x-z */
+ ocface[a+z]= 0;
+ }
+ }
+ }
+ }
+}
+
+void RE_ray_tree_done(RayTree *tree)
+{
+ Octree *oc= (Octree*)tree;
+
+ MEM_freeN(oc->ocface);
+ oc->ocface= NULL;
+}
+
+/* ************ raytracer **************** */
+
+#define ISECT_EPSILON ((float)FLT_EPSILON)
+
+/* only for self-intersecting test with current render face (where ray left) */
+static int intersection2(RayFace *face, int ob, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc, void *userdata, float r0, float r1, float r2, float rx1, float ry1, float rz1)
+{
+ float *v1, *v2, *v3, *v4, co1[3], co2[3], co3[3], co4[3];
+ float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22;
+ float m0, m1, m2, divdet, det, det1;
+ float u1, v, u2;
+
+ coordsfunc(face, &v1, &v2, &v3, &v4);
+
+ /* happens for baking with non existing face */
+ if(v1==NULL)
+ return 1;
+
+ if(v4) {
+ SWAP(float*, v3, v4);
+ }
+
+ VECCOPY(co1, v1);
+ VECCOPY(co2, v2);
+ VECCOPY(co3, v3);
+ if(v4)
+ VECCOPY(co4, v4);
+
+ if(ob >= RE_RAY_TRANSFORM_OFFS) {
+ float (*mat)[4]= (float(*)[4])transformfunc(userdata, ob);
+
+ if(mat) {
+ Mat4MulVecfl(mat, co1);
+ Mat4MulVecfl(mat, co2);
+ Mat4MulVecfl(mat, co3);
+ if(v4)
+ Mat4MulVecfl(mat, co4);
+ }
+ }
+
+ t00= co3[0]-co1[0];
+ t01= co3[1]-co1[1];
+ t02= co3[2]-co1[2];
+ t10= co3[0]-co2[0];
+ t11= co3[1]-co2[1];
+ t12= co3[2]-co2[2];
+
+ x0= t11*r2-t12*r1;
+ x1= t12*r0-t10*r2;
+ x2= t10*r1-t11*r0;
+
+ divdet= t00*x0+t01*x1+t02*x2;
+
+ m0= rx1-co3[0];
+ m1= ry1-co3[1];
+ m2= rz1-co3[2];
+ det1= m0*x0+m1*x1+m2*x2;
+
+ if(divdet!=0.0f) {
+ u1= det1/divdet;
+
+ if(u1<ISECT_EPSILON) {
+ det= t00*(m1*r2-m2*r1);
+ det+= t01*(m2*r0-m0*r2);
+ det+= t02*(m0*r1-m1*r0);
+ v= det/divdet;
+
+ if(v<ISECT_EPSILON && (u1 + v) > -(1.0f+ISECT_EPSILON)) {
+ return 1;
+ }
+ }
+ }
+
+ if(v4) {
+
+ t20= co3[0]-co4[0];
+ t21= co3[1]-co4[1];
+ t22= co3[2]-co4[2];
+
+ divdet= t20*x0+t21*x1+t22*x2;
+ if(divdet!=0.0f) {
+ u2= det1/divdet;
+
+ if(u2<ISECT_EPSILON) {
+ det= t20*(m1*r2-m2*r1);
+ det+= t21*(m2*r0-m0*r2);
+ det+= t22*(m0*r1-m1*r0);
+ v= det/divdet;
+
+ if(v<ISECT_EPSILON && (u2 + v) >= -(1.0f+ISECT_EPSILON)) {
+ return 2;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+#if 0
+/* ray - line intersection */
+/* disabled until i got real & fast cylinder checking, this code doesnt work proper
+for faster strands */
+
+static int intersection_strand(Isect *is)
+{
+ float v1[3], v2[3]; /* length of strand */
+ float axis[3], rc[3], nor[3], radline, dist, len;
+
+ /* radius strand */
+ radline= 0.5f*VecLenf(is->vlr->v1->co, is->vlr->v2->co);
+
+ VecMidf(v1, is->vlr->v1->co, is->vlr->v2->co);
+ VecMidf(v2, is->vlr->v3->co, is->vlr->v4->co);
+
+ VECSUB(rc, v1, is->start); /* vector from base ray to base cylinder */
+ VECSUB(axis, v2, v1); /* cylinder axis */
+
+ CROSS(nor, is->vec, axis);
+ len= VecLength(nor);
+
+ if(len<FLT_EPSILON)
+ return 0;
+
+ dist= INPR(rc, nor)/len; /* distance between ray and axis cylinder */
+
+ if(dist<radline && dist>-radline) {
+ float dot1, dot2, dot3, rlen, alen, div;
+ float labda;
+
+ /* calculating the intersection point of shortest distance */
+ dot1 = INPR(rc, is->vec);
+ dot2 = INPR(is->vec, axis);
+ dot3 = INPR(rc, axis);
+ rlen = INPR(is->vec, is->vec);
+ alen = INPR(axis, axis);
+
+ div = alen * rlen - dot2 * dot2;
+ if (ABS(div) < FLT_EPSILON)
+ return 0;
+
+ labda = (dot1*dot2 - dot3*rlen)/div;
+
+ radline/= sqrt(alen);
+
+ /* labda: where on axis do we have closest intersection? */
+ if(labda >= -radline && labda <= 1.0f+radline) {
+ VlakRen *vlr= is->faceorig;
+ VertRen *v1= is->vlr->v1, *v2= is->vlr->v2, *v3= is->vlr->v3, *v4= is->vlr->v4;
+ /* but we dont do shadows from faces sharing edge */
+
+ if(v1==vlr->v1 || v2==vlr->v1 || v3==vlr->v1 || v4==vlr->v1) return 0;
+ if(v1==vlr->v2 || v2==vlr->v2 || v3==vlr->v2 || v4==vlr->v2) return 0;
+ if(v1==vlr->v3 || v2==vlr->v3 || v3==vlr->v3 || v4==vlr->v3) return 0;
+ if(vlr->v4) {
+ if(v1==vlr->v4 || v2==vlr->v4 || v3==vlr->v4 || v4==vlr->v4) return 0;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif
+
+/* ray - triangle or quad intersection */
+int RE_ray_face_intersection(Isect *is, RayObjectTransformFunc transformfunc, RayCoordsFunc coordsfunc)
+{
+ RayFace *face= is->face;
+ int ob= is->ob;
+ float *v1,*v2,*v3,*v4,co1[3],co2[3],co3[3],co4[3];
+ float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2;
+ float m0, m1, m2, divdet, det1;
+ short ok=0;
+
+ /* disabled until i got real & fast cylinder checking, this code doesnt work proper
+ for faster strands */
+// if(is->mode==RE_RAY_SHADOW && is->vlr->flag & R_STRAND)
+// return intersection_strand(is);
+
+ coordsfunc(face, &v1, &v2, &v3, &v4);
+
+ if(v4) {
+ SWAP(float*, v3, v4);
+ }
+
+ VECCOPY(co1, v1);
+ VECCOPY(co2, v2);
+ VECCOPY(co3, v3);
+ if(v4)
+ VECCOPY(co4, v4);
+
+ if(ob) {
+ float (*mat)[4]= (float(*)[4])transformfunc(is->userdata, ob);
+
+ if(mat) {
+ Mat4MulVecfl(mat, co1);
+ Mat4MulVecfl(mat, co2);
+ Mat4MulVecfl(mat, co3);
+ if(v4)
+ Mat4MulVecfl(mat, co4);
+ }
+ }
+
+ t00= co3[0]-co1[0];
+ t01= co3[1]-co1[1];
+ t02= co3[2]-co1[2];
+ t10= co3[0]-co2[0];
+ t11= co3[1]-co2[1];
+ t12= co3[2]-co2[2];
+
+ r0= is->vec[0];
+ r1= is->vec[1];
+ r2= is->vec[2];
+
+ x0= t12*r1-t11*r2;
+ x1= t10*r2-t12*r0;
+ x2= t11*r0-t10*r1;
+
+ divdet= t00*x0+t01*x1+t02*x2;
+
+ m0= is->start[0]-co3[0];
+ m1= is->start[1]-co3[1];
+ m2= is->start[2]-co3[2];
+ det1= m0*x0+m1*x1+m2*x2;
+
+ if(divdet!=0.0f) {
+ float u;
+
+ divdet= 1.0f/divdet;
+ u= det1*divdet;
+ if(u<ISECT_EPSILON && u>-(1.0f+ISECT_EPSILON)) {
+ float v, cros0, cros1, cros2;
+
+ cros0= m1*t02-m2*t01;
+ cros1= m2*t00-m0*t02;
+ cros2= m0*t01-m1*t00;
+ v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
+
+ if(v<ISECT_EPSILON && (u + v) > -(1.0f+ISECT_EPSILON)) {
+ float labda;
+ labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
+
+ if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) {
+ is->labda= labda;
+ is->u= u; is->v= v;
+ ok= 1;
+ }
+ }
+ }
+ }
+
+ if(ok==0 && v4) {
+
+ t20= co3[0]-co4[0];
+ t21= co3[1]-co4[1];
+ t22= co3[2]-co4[2];
+
+ divdet= t20*x0+t21*x1+t22*x2;
+ if(divdet!=0.0f) {
+ float u;
+ divdet= 1.0f/divdet;
+ u = det1*divdet;
+
+ if(u<ISECT_EPSILON && u>-(1.0f+ISECT_EPSILON)) {
+ float v, cros0, cros1, cros2;
+ cros0= m1*t22-m2*t21;
+ cros1= m2*t20-m0*t22;
+ cros2= m0*t21-m1*t20;
+ v= divdet*(cros0*r0 + cros1*r1 + cros2*r2);
+
+ if(v<ISECT_EPSILON && (u + v) >-(1.0f+ISECT_EPSILON)) {
+ float labda;
+ labda= divdet*(cros0*t10 + cros1*t11 + cros2*t12);
+
+ if(labda>-ISECT_EPSILON && labda<1.0f+ISECT_EPSILON) {
+ ok= 2;
+ is->labda= labda;
+ is->u= u; is->v= v;
+ }
+ }
+ }
+ }
+ }
+
+ if(ok) {
+ is->isect= ok; // wich half of the quad
+
+ if(is->mode!=RE_RAY_SHADOW) {
+ /* for mirror & tra-shadow: large faces can be filled in too often, this prevents
+ a face being detected too soon... */
+ if(is->labda > is->ddalabda) {
+ return 0;
+ }
+ }
+
+ /* when a shadow ray leaves a face, it can be little outside the edges of it, causing
+ intersection to be detected in its neighbour face */
+
+ if(is->facecontr && is->faceisect); // optimizing, the tests below are not needed
+ else if(is->labda< .1) {
+ RayFace *face= is->faceorig;
+ float *origv1, *origv2, *origv3, *origv4;
+ short de= 0;
+
+ coordsfunc(face, &origv1, &origv2, &origv3, &origv4);
+
+ if(ob == is->oborig) {
+ if(v1==origv1 || v2==origv1 || v3==origv1 || v4==origv1) de++;
+ if(v1==origv2 || v2==origv2 || v3==origv2 || v4==origv2) de++;
+ if(v1==origv3 || v2==origv3 || v3==origv3 || v4==origv3) de++;
+ if(origv4) {
+ if(v1==origv4 || v2==origv4 || v3==origv4 || v4==origv4) de++;
+ }
+ }
+ if(de) {
+ /* so there's a shared edge or vertex, let's intersect ray with face
+ itself, if that's true we can safely return 1, otherwise we assume
+ the intersection is invalid, 0 */
+
+ if(is->facecontr==NULL) {
+ is->obcontr= is->oborig;
+ is->facecontr= face;
+ is->faceisect= intersection2(face, is->oborig, transformfunc, coordsfunc, is->userdata, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]);
+ }
+
+ if(is->faceisect) return 1;
+ return 0;
+ }
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* check all faces in this node */
+static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc checkfunc)
+{
+ RayFace *face;
+ int ob;
+ short nr=0;
+ OcVal *ov;
+
+ /* return on any first hit */
+ if(is->mode==RE_RAY_SHADOW) {
+
+ face= no->v[0];
+ ob= no->ob[0];
+ while(face) {
+
+ if(!(is->faceorig == face && is->oborig == ob)) {
+
+ if(checkfunc(is, ob, face)) {
+
+ ov= no->ov+nr;
+ if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
+ //accepted++;
+ is->ob= ob;
+ is->face= face;
+
+ if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) {
+ is->ob_last= ob;
+ is->face_last= face;
+ return 1;
+ }
+ }
+ //else rejected++;
+ }
+ }
+
+ nr++;
+ if(nr==8) {
+ no= no->next;
+ if(no==0) return 0;
+ nr=0;
+ }
+ face= no->v[nr];
+ ob= no->ob[nr];
+ }
+ }
+ else { /* else mirror or glass or shadowtra, return closest face */
+ Isect isect;
+ int found= 0;
+
+ is->labda= 1.0f; /* needed? */
+ isect= *is; /* copy for sorting */
+
+ face= no->v[0];
+ ob= no->ob[0];
+ while(face) {
+
+ if(!(is->faceorig == face && is->oborig == ob)) {
+ if(checkfunc(is, ob, face)) {
+ ov= no->ov+nr;
+ if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
+ //accepted++;
+
+ isect.ob= ob;
+ isect.face= face;
+ if(RE_ray_face_intersection(&isect, oc->transformfunc, oc->coordsfunc)) {
+ if(isect.labda<is->labda) *is= isect;
+ found= 1;
+ }
+ }
+ //else rejected++;
+ }
+ }
+
+ nr++;
+ if(nr==8) {
+ no= no->next;
+ if(no==NULL) break;
+ nr=0;
+ }
+ face= no->v[nr];
+ ob= no->ob[nr];
+ }
+
+ return found;
+ }
+
+ return 0;
+}
+
+/* find the Node for the octree coord x y z */
+static Node *ocread(Octree *oc, int x, int y, int z)
+{
+ Branch *br;
+ int oc1;
+
+ x<<=2;
+ y<<=1;
+
+ br= oc->adrbranch[0];
+
+ if(oc->ocres==512) {
+ oc1= ((x & 1024)+(y & 512)+(z & 256))>>8;
+ br= br->b[oc1];
+ if(br==NULL) {
+ return NULL;
+ }
+ }
+ if(oc->ocres>=256) {
+ oc1= ((x & 512)+(y & 256)+(z & 128))>>7;
+ br= br->b[oc1];
+ if(br==NULL) {
+ return NULL;
+ }
+ }
+ if(oc->ocres>=128) {
+ oc1= ((x & 256)+(y & 128)+(z & 64))>>6;
+ br= br->b[oc1];
+ if(br==NULL) {
+ return NULL;
+ }
+ }
+
+ oc1= ((x & 128)+(y & 64)+(z & 32))>>5;
+ br= br->b[oc1];
+ if(br) {
+ oc1= ((x & 64)+(y & 32)+(z & 16))>>4;
+ br= br->b[oc1];
+ if(br) {
+ oc1= ((x & 32)+(y & 16)+(z & 8))>>3;
+ br= br->b[oc1];
+ if(br) {
+ oc1= ((x & 16)+(y & 8)+(z & 4))>>2;
+ br= br->b[oc1];
+ if(br) {
+ oc1= ((x & 8)+(y & 4)+(z & 2))>>1;
+ br= br->b[oc1];
+ if(br) {
+ oc1= ((x & 4)+(y & 2)+(z & 1));
+ return (Node *)br->b[oc1];
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static int cliptest(float p, float q, float *u1, float *u2)
+{
+ float r;
+
+ if(p<0.0f) {
+ if(q<p) return 0;
+ else if(q<0.0f) {
+ r= q/p;
+ if(r>*u2) return 0;
+ else if(r>*u1) *u1=r;
+ }
+ }
+ else {
+ if(p>0.0f) {
+ if(q<0.0f) return 0;
+ else if(q<p) {
+ r= q/p;
+ if(r<*u1) return 0;
+ else if(r<*u2) *u2=r;
+ }
+ }
+ else if(q<0.0f) return 0;
+ }
+ return 1;
+}
+
+/* extensive coherence checks/storage cancels out the benefit of it, and gives errors... we
+ need better methods, sample code commented out below (ton) */
+
+/*
+
+in top: static int coh_nodes[16*16*16][6];
+in makeoctree: memset(coh_nodes, 0, sizeof(coh_nodes));
+
+static void add_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
+{
+ short *sp;
+
+ sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ];
+ sp[0]= ocx1; sp[1]= ocy1; sp[2]= ocz1;
+ sp[3]= ocx2; sp[4]= ocy2; sp[5]= ocz2;
+
+}
+
+static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, int ocz2)
+{
+ short *sp;
+
+ sp= coh_nodes[ (ocx2 & 15) + 16*(ocy2 & 15) + 256*(ocz2 & 15) ];
+ if(sp[0]==ocx1 && sp[1]==ocy1 && sp[2]==ocz1 &&
+ sp[3]==ocx2 && sp[4]==ocy2 && sp[5]==ocz2) return 1;
+ return 0;
+}
+
+*/
+
+int RE_ray_tree_intersect(RayTree *tree, Isect *is)
+{
+ Octree *oc= (Octree*)tree;
+
+ return RE_ray_tree_intersect_check(tree, is, oc->checkfunc);
+}
+
+/* return 1: found valid intersection */
+/* starts with is->faceorig */
+int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc)
+{
+ Octree *oc= (Octree*)tree;
+ Node *no;
+ OcVal ocval;
+ float vec1[3], vec2[3];
+ float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2;
+ float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda;
+ int dx,dy,dz;
+ int xo,yo,zo,c1=0;
+ int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2;
+
+ /* clip with octree */
+ if(oc->branchcount==0) return 0;
+
+ /* do this before intersect calls */
+ is->facecontr= NULL; /* to check shared edge */
+ is->obcontr= 0;
+ is->faceisect= is->isect= 0; /* shared edge, quad half flag */
+ is->userdata= oc->userdata;
+
+ /* only for shadow! */
+ if(is->mode==RE_RAY_SHADOW) {
+
+ /* check with last intersected shadow face */
+ if(is->face_last!=NULL && !(is->face_last==is->faceorig && is->ob_last==is->oborig)) {
+ if(checkfunc(is, is->ob_last, is->face_last)) {
+ is->ob= is->ob_last;
+ is->face= is->face_last;
+ VECSUB(is->vec, is->end, is->start);
+ if(RE_ray_face_intersection(is, oc->transformfunc, oc->coordsfunc)) return 1;
+ }
+ }
+ }
+
+ ldx= is->end[0] - is->start[0];
+ u1= 0.0f;
+ u2= 1.0f;
+
+ /* clip with octree cube */
+ if(cliptest(-ldx, is->start[0]-oc->min[0], &u1,&u2)) {
+ if(cliptest(ldx, oc->max[0]-is->start[0], &u1,&u2)) {
+ ldy= is->end[1] - is->start[1];
+ if(cliptest(-ldy, is->start[1]-oc->min[1], &u1,&u2)) {
+ if(cliptest(ldy, oc->max[1]-is->start[1], &u1,&u2)) {
+ ldz= is->end[2] - is->start[2];
+ if(cliptest(-ldz, is->start[2]-oc->min[2], &u1,&u2)) {
+ if(cliptest(ldz, oc->max[2]-is->start[2], &u1,&u2)) {
+ c1=1;
+ if(u2<1.0f) {
+ is->end[0]= is->start[0]+u2*ldx;
+ is->end[1]= is->start[1]+u2*ldy;
+ is->end[2]= is->start[2]+u2*ldz;
+ }
+ if(u1>0.0f) {
+ is->start[0]+=u1*ldx;
+ is->start[1]+=u1*ldy;
+ is->start[2]+=u1*ldz;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(c1==0) return 0;
+
+ /* reset static variables in ocread */
+ //ocread(oc, oc->ocres, 0, 0);
+
+ /* setup 3dda to traverse octree */
+ ox1= (is->start[0]-oc->min[0])*oc->ocfacx;
+ oy1= (is->start[1]-oc->min[1])*oc->ocfacy;
+ oz1= (is->start[2]-oc->min[2])*oc->ocfacz;
+ ox2= (is->end[0]-oc->min[0])*oc->ocfacx;
+ oy2= (is->end[1]-oc->min[1])*oc->ocfacy;
+ oz2= (is->end[2]-oc->min[2])*oc->ocfacz;
+
+ ocx1= (int)ox1;
+ ocy1= (int)oy1;
+ ocz1= (int)oz1;
+ ocx2= (int)ox2;
+ ocy2= (int)oy2;
+ ocz2= (int)oz2;
+
+ /* for intersection */
+ VECSUB(is->vec, is->end, is->start);
+
+ if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) {
+ no= ocread(oc, ocx1, ocy1, ocz1);
+ if(no) {
+ /* exact intersection with node */
+ vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1;
+ vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2;
+ calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2);
+ is->ddalabda= 1.0f;
+ if( testnode(oc, is, no, ocval, checkfunc) ) return 1;
+ }
+ }
+ else {
+ //static int coh_ocx1,coh_ocx2,coh_ocy1, coh_ocy2,coh_ocz1,coh_ocz2;
+ float dox, doy, doz;
+ int eqval;
+
+ /* calc labda en ld */
+ dox= ox1-ox2;
+ doy= oy1-oy2;
+ doz= oz1-oz2;
+
+ if(dox<-FLT_EPSILON) {
+ ldx= -1.0f/dox;
+ labdax= (ocx1-ox1+1.0f)*ldx;
+ dx= 1;
+ } else if(dox>FLT_EPSILON) {
+ ldx= 1.0f/dox;
+ labdax= (ox1-ocx1)*ldx;
+ dx= -1;
+ } else {
+ labdax=1.0f;
+ ldx=0;
+ dx= 0;
+ }
+
+ if(doy<-FLT_EPSILON) {
+ ldy= -1.0f/doy;
+ labday= (ocy1-oy1+1.0f)*ldy;
+ dy= 1;
+ } else if(doy>FLT_EPSILON) {
+ ldy= 1.0f/doy;
+ labday= (oy1-ocy1)*ldy;
+ dy= -1;
+ } else {
+ labday=1.0f;
+ ldy=0;
+ dy= 0;
+ }
+
+ if(doz<-FLT_EPSILON) {
+ ldz= -1.0f/doz;
+ labdaz= (ocz1-oz1+1.0f)*ldz;
+ dz= 1;
+ } else if(doz>FLT_EPSILON) {
+ ldz= 1.0f/doz;
+ labdaz= (oz1-ocz1)*ldz;
+ dz= -1;
+ } else {
+ labdaz=1.0f;
+ ldz=0;
+ dz= 0;
+ }
+
+ xo=ocx1; yo=ocy1; zo=ocz1;
+ labdao= ddalabda= MIN3(labdax,labday,labdaz);
+
+ vec2[0]= ox1;
+ vec2[1]= oy1;
+ vec2[2]= oz1;
+
+ /* this loop has been constructed to make sure the first and last node of ray
+ are always included, even when ddalabda==1.0f or larger */
+
+ while(TRUE) {
+
+ no= ocread(oc, xo, yo, zo);
+ if(no) {
+
+ /* calculate ray intersection with octree node */
+ VECCOPY(vec1, vec2);
+ // dox,y,z is negative
+ vec2[0]= ox1-ddalabda*dox;
+ vec2[1]= oy1-ddalabda*doy;
+ vec2[2]= oz1-ddalabda*doz;
+ calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2);
+
+ is->ddalabda= ddalabda;
+ if( testnode(oc, is, no, ocval, checkfunc) ) return 1;
+ }
+
+ labdao= ddalabda;
+
+ /* traversing ocree nodes need careful detection of smallest values, with proper
+ exceptions for equal labdas */
+ eqval= (labdax==labday);
+ if(labday==labdaz) eqval += 2;
+ if(labdax==labdaz) eqval += 4;
+
+ if(eqval) { // only 4 cases exist!
+ if(eqval==7) { // x=y=z
+ xo+=dx; labdax+=ldx;
+ yo+=dy; labday+=ldy;
+ zo+=dz; labdaz+=ldz;
+ }
+ else if(eqval==1) { // x=y
+ if(labday < labdaz) {
+ xo+=dx; labdax+=ldx;
+ yo+=dy; labday+=ldy;
+ }
+ else {
+ zo+=dz; labdaz+=ldz;
+ }
+ }
+ else if(eqval==2) { // y=z
+ if(labdax < labday) {
+ xo+=dx; labdax+=ldx;
+ }
+ else {
+ yo+=dy; labday+=ldy;
+ zo+=dz; labdaz+=ldz;
+ }
+ }
+ else { // x=z
+ if(labday < labdax) {
+ yo+=dy; labday+=ldy;
+ }
+ else {
+ xo+=dx; labdax+=ldx;
+ zo+=dz; labdaz+=ldz;
+ }
+ }
+ }
+ else { // all three different, just three cases exist
+ eqval= (labdax<labday);
+ if(labday<labdaz) eqval += 2;
+ if(labdax<labdaz) eqval += 4;
+
+ if(eqval==7 || eqval==5) { // x smallest
+ xo+=dx; labdax+=ldx;
+ }
+ else if(eqval==2 || eqval==6) { // y smallest
+ yo+=dy; labday+=ldy;
+ }
+ else { // z smallest
+ zo+=dz; labdaz+=ldz;
+ }
+
+ }
+
+ ddalabda=MIN3(labdax,labday,labdaz);
+ if(ddalabda==labdao) break;
+ /* to make sure the last node is always checked */
+ if(labdao>=1.0f) break;
+ }
+ }
+
+ /* reached end, no intersections found */
+ is->ob_last= 0;
+ is->face_last= NULL;
+ return 0;
+}
+
+float RE_ray_tree_max_size(RayTree *tree)
+{
+ return ((Octree*)tree)->ocsize;
+}
+
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 4e32cd16acf..36ee4daaa64 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -29,6 +29,7 @@
/* system includes */
#include <stdio.h>
#include <math.h>
+#include <float.h>
#include <string.h>
/* External modules: */
@@ -60,12 +61,14 @@
#include "renderpipeline.h"
#include "render_types.h"
#include "renderdatabase.h"
+#include "occlusion.h"
#include "pixelblending.h"
#include "pixelshading.h"
#include "shadbuf.h"
#include "shading.h"
#include "sss.h"
#include "zbuf.h"
+#include "RE_raytrace.h"
#include "PIL_time.h"
@@ -162,10 +165,10 @@ static int calchalo_z(HaloRen *har, int zz)
return zz;
}
-static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps)
+static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
{
float col[4], accol[4];
- int amount, amountm, zz, flarec;
+ int amount, amountm, zz, flarec, sample;
amount= 0;
accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
@@ -207,19 +210,21 @@ static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, floa
col[2]= accol[2];
col[3]= accol[3];
- addalphaAddfacFloat(rb, col, har->add);
-
+ for(sample=0; sample<totsample; sample++)
+ addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
}
-static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
+static void halo_tile(RenderPart *pa, RenderLayer *rl)
{
- HaloRen *har = NULL;
+ RenderLayer *rlpp[RE_MAX_OSA];
+ HaloRen *har;
rcti disprect= pa->disprect, testrect= pa->disprect;
- float dist, xsq, ysq, xn, yn, *rb;
+ float dist, xsq, ysq, xn, yn;
float col[4];
long *rd= NULL;
- int a, *rz, zz, y;
+ int a, *rz, zz, y, sample, totsample, od;
short minx, maxx, miny, maxy, x;
+ unsigned int lay= rl->lay;
/* we don't render halos in the cropped area, gives errors in flare counter */
if(pa->crop) {
@@ -229,10 +234,10 @@ static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
testrect.ymax-= pa->crop;
}
+ totsample= get_sample_layers(pa, rl, rlpp);
+
for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0)
- har= R.bloha[a>>8];
- else har++;
+ har= R.sortedhalos[a];
/* layer test, clip halo with y */
if((har->lay & lay)==0);
@@ -255,8 +260,8 @@ static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
for(y=miny; y<maxy; y++) {
int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
- rb= pass + 4*rectofs;
rz= pa->rectz + rectofs;
+ od= rectofs;
if(pa->rectdaps)
rd= pa->rectdaps + rectofs;
@@ -264,19 +269,21 @@ static void halo_tile(RenderPart *pa, float *pass, unsigned int lay)
yn= (y-har->ys)*R.ycor;
ysq= yn*yn;
- for(x=minx; x<maxx; x++, rb+=4, rz++) {
+ for(x=minx; x<maxx; x++, rz++, od++) {
xn= x- har->xs;
xsq= xn*xn;
dist= xsq+ysq;
if(dist<har->radsq) {
if(rd && *rd) {
- halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd);
+ halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
}
else {
zz= calchalo_z(har, *rz);
if(zz> har->zs) {
shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
- addalphaAddfacFloat(rb, col, har->add);
+
+ for(sample=0; sample<totsample; sample++)
+ addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
}
}
}
@@ -297,7 +304,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
long *rd= pa->rectdaps;
int x, y, *rz= pa->rectz;
- shade_input_initialize(&shi, pa, rl, 0);
+ shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, pass+=4) {
@@ -348,12 +355,19 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
{
RenderPass *rpass;
+
+ /* combined rgb */
+ add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
float *fp, *col= NULL;
int pixsize= 3;
switch(rpass->passtype) {
+ case SCE_PASS_Z:
+ fp= rpass->rect + offset;
+ *fp= shr->z;
+ break;
case SCE_PASS_RGBA:
col= shr->col;
pixsize= 4;
@@ -387,8 +401,8 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
if(shi->totuv) {
float mult= (float)count_mask(curmask)/(float)R.osa;
fp= rpass->rect + 3*offset;
- fp[0]+= mult*(0.5f + 0.5f*shi->uv[0].uv[0]);
- fp[1]+= mult*(0.5f + 0.5f*shi->uv[0].uv[1]);
+ fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
+ fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
fp[2]+= mult;
}
break;
@@ -397,9 +411,15 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
if(shi->vlr) {
fp= rpass->rect + offset;
if(*fp==0.0f)
- *fp= (float)shi->vlr->ob->index;
+ *fp= (float)shi->obr->ob->index;
}
break;
+ case SCE_PASS_MIST:
+ /* */
+ col= &shr->mist;
+ pixsize= 1;
+ break;
+
case SCE_PASS_VECTOR:
{
/* add minimum speed in pixel, no filter */
@@ -426,12 +446,20 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
{
RenderPass *rpass;
+ float *fp;
+
+ fp= rl->rectf + 4*offset;
+ QUATCOPY(fp, shr->combined);
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
- float *fp, *col= NULL, uvcol[3];
+ float *col= NULL, uvcol[3];
int a, pixsize= 3;
switch(rpass->passtype) {
+ case SCE_PASS_Z:
+ fp= rpass->rect + offset;
+ *fp= shr->z;
+ break;
case SCE_PASS_RGBA:
col= shr->col;
pixsize= 4;
@@ -462,8 +490,8 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
break;
case SCE_PASS_UV:
if(shi->totuv) {
- uvcol[0]= 0.5f + 0.5f*shi->uv[0].uv[0];
- uvcol[1]= 0.5f + 0.5f*shi->uv[0].uv[1];
+ uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
+ uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
uvcol[2]= 1.0f;
col= uvcol;
}
@@ -475,9 +503,13 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
case SCE_PASS_INDEXOB:
if(shi->vlr) {
fp= rpass->rect + offset;
- *fp= (float)shi->vlr->ob->index;
+ *fp= (float)shi->obr->ob->index;
}
break;
+ case SCE_PASS_MIST:
+ fp= rpass->rect + offset;
+ *fp= shr->mist;
+ break;
}
if(col) {
fp= rpass->rect + pixsize*offset;
@@ -487,26 +519,60 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
}
}
+int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
+{
+
+ if(pa->fullresult.first) {
+ int sample, nr= BLI_findindex(&pa->result->layers, rl);
+
+ for(sample=0; sample<R.osa; sample++) {
+ RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
+
+ rlpp[sample]= BLI_findlink(&rr->layers, nr);
+ }
+ return R.osa;
+ }
+ else {
+ rlpp[0]= rl;
+ return 1;
+ }
+}
+
+
/* only do sky, is default in the solid layer (shade_tile) btw */
-static void sky_tile(RenderPart *pa, float *pass)
+static void sky_tile(RenderPart *pa, RenderLayer *rl)
{
- float col[4];
- int x, y;
+ RenderLayer *rlpp[RE_MAX_OSA];
+ int x, y, od=0, totsample;
if(R.r.alphamode!=R_ADDSKY)
return;
+ totsample= get_sample_layers(pa, rl, rlpp);
+
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
- for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, pass+=4) {
- if(pass[3]<1.0f) {
- if(pass[3]==0.0f)
- shadeSkyPixel(pass, x, y);
- else {
- shadeSkyPixel(col, x, y);
- addAlphaOverFloat(col, pass);
- QUATCOPY(pass, col);
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
+ float col[4];
+ int sample, done= 0;
+
+ for(sample= 0; sample<totsample; sample++) {
+ float *pass= rlpp[sample]->rectf + od;
+
+ if(pass[3]<1.0f) {
+
+ if(done==0) {
+ shadeSkyPixel(col, x, y);
+ done= 1;
+ }
+
+ if(pass[3]==0.0f) {
+ QUATCOPY(pass, col);
+ }
+ else {
+ addAlphaUnderFloat(pass, col);
+ }
}
- }
+ }
}
if(y&1)
@@ -518,10 +584,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
RenderResult *rr= pa->result;
ShadeSample ssamp;
- float *fcol, *rf, *rectf= rl->rectf;
long *rd, *rectdaps= pa->rectdaps;
int samp;
- int x, y, seed, crop=0, offs=0, od, addpassflag;
+ int x, y, seed, crop=0, offs=0, od;
if(R.test_break()) return;
@@ -534,12 +599,14 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
/* general shader info, passes */
shade_sample_initialize(&ssamp, pa, rl);
- addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
-
+
+ /* occlusion caching */
+ if(R.occlusiontree)
+ cache_occ_samples(&R, pa, &ssamp);
+
/* filtered render, for now we assume only 1 filter size */
if(pa->crop) {
crop= 1;
- rectf+= 4*(pa->rectx + 1);
rectdaps+= pa->rectx + 1;
offs= pa->rectx + 1;
}
@@ -550,28 +617,35 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
rr->renlay= rl;
for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
- rf= rectf;
rd= rectdaps;
od= offs;
- for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, rf+=4, od++) {
+ for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
BLI_thread_srandom(pa->thread, seed++);
if(*rd) {
if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
- for(samp=0; samp<ssamp.tot; samp++) {
-
- fcol= ssamp.shr[samp].combined;
- add_filt_fmask(ssamp.shi[samp].mask, fcol, rf, pa->rectx);
-
- if(addpassflag)
+
+ /* multisample buffers or filtered mask filling? */
+ if(pa->fullresult.first) {
+ int a;
+ for(samp=0; samp<ssamp.tot; samp++) {
+ int smask= ssamp.shi[samp].mask;
+ for(a=0; a<R.osa; a++) {
+ int mask= 1<<a;
+ if(smask & mask)
+ add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
+ }
+ }
+ }
+ else {
+ for(samp=0; samp<ssamp.tot; samp++)
add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
}
}
}
}
- rectf+= 4*pa->rectx;
rectdaps+= pa->rectx;
offs+= pa->rectx;
@@ -583,6 +657,9 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
if(R.r.mode & R_SHADOW)
ISB_free(pa);
+
+ if(R.occlusiontree)
+ free_occ_samples(&R, pa);
}
/* ************* pixel struct ******** */
@@ -614,7 +691,7 @@ static void freeps(ListBase *lb)
lb->first= lb->last= NULL;
}
-static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask)
+static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
{
PixStrMain *psm;
PixStr *ps, *last= NULL;
@@ -623,7 +700,7 @@ static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask
ps= (PixStr *)(*rd);
while(ps) {
- if( ps->facenr == facenr ) {
+ if( ps->obi == obi && ps->facenr == facenr ) {
ps->mask |= mask;
return;
}
@@ -644,30 +721,14 @@ static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask
else *rd= (long)ps;
ps->next= NULL;
+ ps->obi= obi;
ps->facenr= facenr;
ps->z= z;
+ ps->maskz= maskz;
ps->mask = mask;
ps->shadfac= 0;
}
-static void make_pixelstructs(RenderPart *pa, ListBase *lb)
-{
- long *rd= pa->rectdaps;
- int *rp= pa->rectp;
- int *rz= pa->rectz;
- int x, y;
- int mask= 1<<pa->sample;
-
- for(y=0; y<pa->recty; y++) {
- for(x=0; x<pa->rectx; x++, rd++, rp++) {
- if(*rp) {
- addps(lb, rd, *rp, *(rz+x), mask);
- }
- }
- rz+= pa->rectx;
- }
-}
-
static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
{
float addcol[4];
@@ -703,7 +764,7 @@ static void convert_to_key_alpha(RenderPart *pa, float *rectf)
}
/* adds only alpha values */
-static void edge_enhance_tile(RenderPart *pa, float *rectf)
+void edge_enhance_tile(RenderPart *pa, float *rectf)
{
/* use zbuffer to define edges, add it to the image */
int y, x, col, *rz, *rz1, *rz2, *rz3;
@@ -766,16 +827,20 @@ static void edge_enhance_tile(RenderPart *pa, float *rectf)
static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
{
/* for all pixels with max speed, set to zero */
+ RenderLayer *rlpp[RE_MAX_OSA];
float *fp;
- int a;
-
- fp= RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR);
- if(fp==NULL) return;
+ int a, sample, totsample;
- for(a= 4*pa->rectx*pa->recty; a>0; a--)
- if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
-}
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ for(sample= 0; sample<totsample; sample++) {
+ fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR);
+ if(fp==NULL) break;
+ for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
+ if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
+ }
+}
static unsigned short *make_solid_mask(RenderPart *pa)
{
@@ -834,6 +899,36 @@ static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dma
dest[3]= (mul*dest[3]) + source[3];
}
+typedef struct ZbufSolidData {
+ RenderLayer *rl;
+ ListBase *psmlist;
+ float *edgerect;
+} ZbufSolidData;
+
+void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
+{
+ ZbufSolidData *sdata= (ZbufSolidData*)data;
+ ListBase *lb= sdata->psmlist;
+ long *rd= pa->rectdaps;
+ int *ro= zspan->recto;
+ int *rp= zspan->rectp;
+ int *rz= zspan->rectz;
+ int *rm= zspan->rectmask;
+ int x, y;
+ int mask= 1<<sample;
+
+ for(y=0; y<pa->recty; y++) {
+ for(x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
+ if(*rp) {
+ addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
+ }
+ }
+ }
+
+ if(sdata->rl->layflag & SCE_LAY_EDGE)
+ if(R.r.mode & R_EDGE)
+ edge_enhance_tile(pa, sdata->edgerect);
+}
/* main call for shading Delta Accum, for OSA */
/* supposed to be fully threadable! */
@@ -844,15 +939,15 @@ void zbufshadeDA_tile(RenderPart *pa)
ListBase psmlist= {NULL, NULL};
float *edgerect= NULL;
- set_part_zbuf_clipflag(pa);
-
/* allocate the necessary buffers */
/* zbuffer inits these rects */
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
-
for(rl= rr->layers.first; rl; rl= rl->next) {
-
+ if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
+
/* initialize pixelstructs and edge buffer */
addpsmain(&psmlist);
pa->rectdaps= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
@@ -862,14 +957,13 @@ void zbufshadeDA_tile(RenderPart *pa)
edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
/* always fill visibility */
- for(pa->sample=0; pa->sample<R.osa; pa->sample++) {
- zbuffer_solid(pa, rl->lay, rl->layflag);
- make_pixelstructs(pa, &psmlist);
-
- if(rl->layflag & SCE_LAY_EDGE)
- if(R.r.mode & R_EDGE)
- edge_enhance_tile(pa, edgerect);
-
+ for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
+ ZbufSolidData sdata;
+
+ sdata.rl= rl;
+ sdata.psmlist= &psmlist;
+ sdata.edgerect= edgerect;
+ zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
if(R.test_break()) break;
}
@@ -885,61 +979,64 @@ void zbufshadeDA_tile(RenderPart *pa)
/* halo before ztra, because ztra fills in zbuffer now */
if(R.flag & R_HALO)
if(rl->layflag & SCE_LAY_HALO)
- halo_tile(pa, rl->rectf, rl->lay);
-
+ halo_tile(pa, rl);
+
/* transp layer */
- if(R.flag & R_ZTRA) {
- if(rl->layflag & SCE_LAY_ZTRA) {
- unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
-
- /* allocate, but not free here, for asynchronous display of this rect in main thread */
- rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
-
- /* swap for live updates, and it is used in zbuf.c!!! */
- SWAP(float *, rl->acolrect, rl->rectf);
- ztramask= zbuffer_transp_shade(pa, rl, rl->rectf);
- SWAP(float *, rl->acolrect, rl->rectf);
-
- /* zbuffer transp only returns ztramask if there's solid rendered */
- if(ztramask)
- solidmask= make_solid_mask(pa);
-
- if(ztramask && solidmask) {
- unsigned short *sps= solidmask, *spz= ztramask;
- unsigned short fullmask= (1<<R.osa)-1;
- float *fcol= rl->rectf; float *acol= rl->acolrect;
- int x;
+ if(R.flag & R_ZTRA || R.totstrand) {
+ if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
+ if(pa->fullresult.first) {
+ zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
+ }
+ else {
+ unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
- for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
- if(*sps == fullmask)
- addAlphaOverFloat(fcol, acol);
- else
- addAlphaOverFloatMask(fcol, acol, *sps, *spz);
+ /* allocate, but not free here, for asynchronous display of this rect in main thread */
+ rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
+
+ /* swap for live updates, and it is used in zbuf.c!!! */
+ SWAP(float *, rl->acolrect, rl->rectf);
+ ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
+ SWAP(float *, rl->acolrect, rl->rectf);
+
+ /* zbuffer transp only returns ztramask if there's solid rendered */
+ if(ztramask)
+ solidmask= make_solid_mask(pa);
+
+ if(ztramask && solidmask) {
+ unsigned short *sps= solidmask, *spz= ztramask;
+ unsigned short fullmask= (1<<R.osa)-1;
+ float *fcol= rl->rectf; float *acol= rl->acolrect;
+ int x;
+
+ for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
+ if(*sps == fullmask)
+ addAlphaOverFloat(fcol, acol);
+ else
+ addAlphaOverFloatMask(fcol, acol, *sps, *spz);
+ }
}
- }
- else {
- float *fcol= rl->rectf; float *acol= rl->acolrect;
- int x;
- for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
- addAlphaOverFloat(fcol, acol);
+ else {
+ float *fcol= rl->rectf; float *acol= rl->acolrect;
+ int x;
+ for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
+ addAlphaOverFloat(fcol, acol);
+ }
}
+ if(solidmask) MEM_freeN(solidmask);
+ if(ztramask) MEM_freeN(ztramask);
}
- if(solidmask) MEM_freeN(solidmask);
- if(ztramask) MEM_freeN(ztramask);
}
}
+
/* sky before edge */
if(rl->layflag & SCE_LAY_SKY)
- sky_tile(pa, rl->rectf);
+ sky_tile(pa, rl);
/* extra layers */
if(rl->layflag & SCE_LAY_EDGE)
if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect);
- if(rl->passflag & SCE_PASS_Z)
- convert_zbuf_to_distbuf(pa, rl);
-
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
@@ -953,12 +1050,17 @@ void zbufshadeDA_tile(RenderPart *pa)
if(edgerect) MEM_freeN(edgerect);
edgerect= NULL;
+
+ if(pa->rectmask) {
+ MEM_freeN(pa->rectmask);
+ pa->rectmask= NULL;
+ }
}
/* free all */
+ MEM_freeN(pa->recto); pa->recto= NULL;
MEM_freeN(pa->rectp); pa->rectp= NULL;
MEM_freeN(pa->rectz); pa->rectz= NULL;
- MEM_freeN(pa->clipflag); pa->clipflag= NULL;
/* display active layer */
rr->renrect.ymin=rr->renrect.ymax= 0;
@@ -977,25 +1079,24 @@ void zbufshade_tile(RenderPart *pa)
RenderLayer *rl;
PixStr ps;
float *edgerect= NULL;
- int addpassflag;
/* fake pixel struct, to comply to osa render */
ps.next= NULL;
ps.mask= 0xFFFF;
- set_part_zbuf_clipflag(pa);
-
/* zbuffer code clears/inits rects */
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
for(rl= rr->layers.first; rl; rl= rl->next) {
-
+ if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
+
/* general shader info, passes */
shade_sample_initialize(&ssamp, pa, rl);
- addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
- zbuffer_solid(pa, rl->lay, rl->layflag);
+ zbuffer_solid(pa, rl, NULL, NULL);
if(!R.test_break()) { /* NOTE: this if() is not consistant */
@@ -1013,7 +1114,8 @@ void zbufshade_tile(RenderPart *pa)
if(rl->layflag & SCE_LAY_SOLID) {
float *fcol= rl->rectf;
- int x, y, *rp= pa->rectp, *rz= pa->rectz, offs=0, seed;
+ int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
+ int x, y, offs=0, seed;
/* we set per pixel a fixed seed, for random AO and shadow samples */
seed= pa->rectx*pa->disprect.ymin;
@@ -1021,21 +1123,22 @@ void zbufshade_tile(RenderPart *pa)
/* irregular shadowb buffer creation */
if(R.r.mode & R_SHADOW)
ISB_create(pa, NULL);
+
+ if(R.occlusiontree)
+ cache_occ_samples(&R, pa, &ssamp);
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
- for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, rp++, fcol+=4, offs++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
/* per pixel fixed seed */
BLI_thread_srandom(pa->thread, seed++);
if(*rp) {
+ ps.obi= *ro;
ps.facenr= *rp;
ps.z= *rz;
if(shade_samples(&ssamp, &ps, x, y)) {
- QUATCOPY(fcol, ssamp.shr[0].combined);
-
- /* passes */
- if(addpassflag)
- add_passes(rl, offs, ssamp.shi, ssamp.shr);
+ /* combined and passes */
+ add_passes(rl, offs, ssamp.shi, ssamp.shr);
}
}
}
@@ -1043,6 +1146,9 @@ void zbufshade_tile(RenderPart *pa)
if(R.test_break()) break;
}
+ if(R.occlusiontree)
+ free_occ_samples(&R, pa);
+
if(R.r.mode & R_SHADOW)
ISB_free(pa);
}
@@ -1059,10 +1165,10 @@ void zbufshade_tile(RenderPart *pa)
/* halo before ztra, because ztra fills in zbuffer now */
if(R.flag & R_HALO)
if(rl->layflag & SCE_LAY_HALO)
- halo_tile(pa, rl->rectf, rl->lay);
+ halo_tile(pa, rl);
- if(R.flag & R_ZTRA) {
- if(rl->layflag & SCE_LAY_ZTRA) {
+ if(R.flag & R_ZTRA || R.totstrand) {
+ if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
float *fcol, *acol;
int x;
@@ -1071,7 +1177,7 @@ void zbufshade_tile(RenderPart *pa)
/* swap for live updates */
SWAP(float *, rl->acolrect, rl->rectf);
- zbuffer_transp_shade(pa, rl, rl->rectf);
+ zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
SWAP(float *, rl->acolrect, rl->rectf);
fcol= rl->rectf; acol= rl->acolrect;
@@ -1083,7 +1189,7 @@ void zbufshade_tile(RenderPart *pa)
/* sky before edge */
if(rl->layflag & SCE_LAY_SKY)
- sky_tile(pa, rl->rectf);
+ sky_tile(pa, rl);
if(!R.test_break()) {
if(rl->layflag & SCE_LAY_EDGE)
@@ -1091,9 +1197,6 @@ void zbufshade_tile(RenderPart *pa)
edge_enhance_add(pa, rl->rectf, edgerect);
}
- if(rl->passflag & SCE_PASS_Z)
- convert_zbuf_to_distbuf(pa, rl);
-
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
@@ -1103,15 +1206,20 @@ void zbufshade_tile(RenderPart *pa)
if(edgerect) MEM_freeN(edgerect);
edgerect= NULL;
+
+ if(pa->rectmask) {
+ MEM_freeN(pa->rectmask);
+ pa->rectmask= NULL;
+ }
}
/* display active layer */
rr->renrect.ymin=rr->renrect.ymax= 0;
rr->renlay= render_get_active_layer(&R, rr);
+ MEM_freeN(pa->recto); pa->recto= NULL;
MEM_freeN(pa->rectp); pa->rectp= NULL;
MEM_freeN(pa->rectz); pa->rectz= NULL;
- MEM_freeN(pa->clipflag); pa->clipflag= NULL;
}
/* SSS preprocess tile render, fully threadable */
@@ -1121,7 +1229,7 @@ typedef struct ZBufSSSHandle {
int totps;
} ZBufSSSHandle;
-static void addps_sss(void *cb_handle, int facenr, int x, int y, int z)
+static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
{
ZBufSSSHandle *handle = cb_handle;
RenderPart *pa= handle->pa;
@@ -1136,57 +1244,50 @@ static void addps_sss(void *cb_handle, int facenr, int x, int y, int z)
if(pa->rectall) {
long *rs= pa->rectall + pa->rectx*y + x;
- addps(&handle->psmlist, rs, facenr, z, 0);
+ addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
handle->totps++;
}
if(pa->rectz) {
int *rz= pa->rectz + pa->rectx*y + x;
int *rp= pa->rectp + pa->rectx*y + x;
+ int *ro= pa->recto + pa->rectx*y + x;
if(z < *rz) {
if(*rp == 0)
handle->totps++;
*rz= z;
*rp= facenr;
+ *ro= obi;
}
}
if(pa->rectbackz) {
int *rz= pa->rectbackz + pa->rectx*y + x;
int *rp= pa->rectbackp + pa->rectx*y + x;
+ int *ro= pa->rectbacko + pa->rectx*y + x;
if(z >= *rz) {
if(*rp == 0)
handle->totps++;
*rz= z;
*rp= facenr;
+ *ro= obi;
}
}
}
-static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
+static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
{
ShadeInput *shi= ssamp->shi;
ShadeResult shr;
float texfac, orthoarea, nor[3];
- /* normal flipping must be disabled to make back scattering work, so that
- backside faces actually face any lighting from the back */
- shi->puno= 0;
-
/* cache for shadow */
- shi->samplenr++;
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
if(quad)
- shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
else
- shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
-
- /* we don't want flipped normals, they screw up back scattering */
- if(vlr->noflag & R_FLIPPED_NO) {
- shi->facenor[0]= -shi->facenor[0];
- shi->facenor[1]= -shi->facenor[1];
- shi->facenor[2]= -shi->facenor[2];
- }
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
/* center pixel */
x += 0.5f;
@@ -1209,11 +1310,19 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, in
*area= VecLength(shi->dxco)*VecLength(shi->dyco);
*area= MIN2(*area, 2.0f*orthoarea);
- shi->osatex= 0;
-
shade_input_set_uv(shi);
shade_input_set_normals(shi);
+ /* we don't want flipped normals, they screw up back scattering */
+ if(shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* not a pretty solution, but fixes common cases */
+ if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
+ VecMulf(shi->vn, -1.0f);
+ VecMulf(shi->vno, -1.0f);
+ }
+
/* if nodetree, use the material that we are currently preprocessing
instead of the node material */
if(shi->mat->nodetree && shi->mat->use_nodes)
@@ -1250,15 +1359,16 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, VlakRen *vlr, in
static void zbufshade_sss_free(RenderPart *pa)
{
- MEM_freeN(pa->clipflag); pa->clipflag= NULL;
#if 0
MEM_freeN(pa->rectall); pa->rectall= NULL;
freeps(&handle.psmlist);
#else
MEM_freeN(pa->rectz); pa->rectz= NULL;
MEM_freeN(pa->rectp); pa->rectp= NULL;
+ MEM_freeN(pa->recto); pa->recto= NULL;
MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
+ MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
#endif
}
@@ -1268,20 +1378,18 @@ void zbufshade_sss_tile(RenderPart *pa)
ShadeSample ssamp;
ZBufSSSHandle handle;
RenderResult *rr= pa->result;
- RenderLayer *rl= rr->layers.first;
+ RenderLayer *rl;
VlakRen *vlr;
Material *mat= re->sss_mat;
- float (*co)[3], (*color)[3], *area, *fcol= rl->rectf;
+ float (*co)[3], (*color)[3], *area, *fcol;
int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
- int *rz, *rp, *rbz, *rbp;
+ int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
#if 0
PixStr *ps;
long *rs;
int z;
#endif
- set_part_zbuf_clipflag(pa);
-
/* setup pixelstr list and buffer for zbuffering */
handle.pa= pa;
handle.totps= 0;
@@ -1292,19 +1400,40 @@ void zbufshade_sss_tile(RenderPart *pa)
pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
#else
+ pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
#endif
+ /* setup shade sample with correct passes */
+ memset(&ssamp, 0, sizeof(ssamp));
+ shade_sample_initialize(&ssamp, pa, rr->layers.first);
+ ssamp.tot= 1;
+
+ for(rl=rr->layers.first; rl; rl=rl->next) {
+ ssamp.shi[0].lay |= rl->lay;
+ ssamp.shi[0].layflag |= rl->layflag;
+ ssamp.shi[0].passflag |= rl->passflag;
+ ssamp.shi[0].combinedflag |= ~rl->pass_xor;
+ }
+
+ rl= rr->layers.first;
+ ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
+ ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
+ lay= ssamp.shi[0].lay;
+
/* create the pixelstrs to be used later */
- zbuffer_sss(pa, rl->lay, &handle, addps_sss);
+ zbuffer_sss(pa, lay, &handle, addps_sss);
if(handle.totps==0) {
zbufshade_sss_free(pa);
return;
}
+
+ fcol= rl->rectf;
co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
@@ -1316,14 +1445,6 @@ void zbufshade_sss_tile(RenderPart *pa)
ISB_create(pa, NULL);
#endif
- /* setup shade sample with correct passes */
- memset(&ssamp, 0, sizeof(ssamp));
- shade_sample_initialize(&ssamp, pa, rl);
- ssamp.shi[0].passflag= SCE_PASS_DIFFUSE|SCE_PASS_AO|SCE_PASS_RADIO;
- ssamp.shi[0].passflag |= SCE_PASS_RGBA;
- ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
- ssamp.tot= 1;
-
if(display) {
/* initialize scanline updates for main thread */
rr->renrect.ymin= 0;
@@ -1336,8 +1457,10 @@ void zbufshade_sss_tile(RenderPart *pa)
#else
rz= pa->rectz;
rp= pa->rectp;
+ ro= pa->recto;
rbz= pa->rectbackz;
rbp= pa->rectbackp;
+ rbo= pa->rectbacko;
#endif
totpoint= 0;
@@ -1350,11 +1473,13 @@ void zbufshade_sss_tile(RenderPart *pa)
if(rs) {
/* for each sample in this pixel, shade it */
for(ps=(PixStr*)*rs; ps; ps=ps->next) {
- vlr= RE_findOrAddVlak(re, (ps->facenr-1) & RE_QUAD_MASK);
+ ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
+ ObjectRen *obr= obi->obr;
+ vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
quad= (ps->facenr & RE_QUAD_OFFS);
z= ps->z;
- shade_sample_sss(&ssamp, mat, vlr, quad, x, y, z,
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
co[totpoint], color[totpoint], &area[totpoint]);
totpoint++;
@@ -1368,11 +1493,14 @@ void zbufshade_sss_tile(RenderPart *pa)
#else
if(rp) {
if(*rp != 0) {
+ ObjectInstanceRen *obi= &re->objectinstance[*ro];
+ ObjectRen *obr= obi->obr;
+
/* shade front */
- vlr= RE_findOrAddVlak(re, (*rp-1) & RE_QUAD_MASK);
+ vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
quad= ((*rp) & RE_QUAD_OFFS);
- shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rz,
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
co[totpoint], color[totpoint], &area[totpoint]);
VECADD(fcol, fcol, color[totpoint]);
@@ -1380,16 +1508,19 @@ void zbufshade_sss_tile(RenderPart *pa)
totpoint++;
}
- rp++; rz++;
+ rp++; rz++; ro++;
}
if(rbp) {
- if(*rbp != 0 && *rbp != *(rp-1)) {
+ if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
+ ObjectInstanceRen *obi= &re->objectinstance[*rbo];
+ ObjectRen *obr= obi->obr;
+
/* shade back */
- vlr= RE_findOrAddVlak(re, (*rbp-1) & RE_QUAD_MASK);
+ vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
quad= ((*rbp) & RE_QUAD_OFFS);
- shade_sample_sss(&ssamp, mat, vlr, quad, x, y, *rbz,
+ shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
co[totpoint], color[totpoint], &area[totpoint]);
/* to indicate this is a back sample */
@@ -1400,7 +1531,7 @@ void zbufshade_sss_tile(RenderPart *pa)
totpoint++;
}
- rbz++; rbp++;
+ rbz++; rbp++; rbo++;
}
#endif
}
@@ -1576,7 +1707,7 @@ void add_halo_flare(Render *re)
{
RenderResult *rr= re->result;
RenderLayer *rl;
- HaloRen *har = NULL;
+ HaloRen *har;
int a, mode, do_draw=0;
/* for now, we get the first renderlayer in list with halos set */
@@ -1590,11 +1721,10 @@ void add_halo_flare(Render *re)
mode= R.r.mode;
R.r.mode &= ~R_PANORAMA;
- project_renderdata(&R, projectverto, 0, 0);
+ project_renderdata(&R, projectverto, 0, 0, 0);
for(a=0; a<R.tothalo; a++) {
- if((a & 255)==0) har= R.bloha[a>>8];
- else har++;
+ har= R.sortedhalos[a];
if(har->flarec) {
do_draw= 1;
@@ -1617,6 +1747,8 @@ void add_halo_flare(Render *re)
void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
{
static VlakRen vlr;
+ static ObjectRen obr;
+ static ObjectInstanceRen obi;
/* init */
if(re) {
@@ -1624,11 +1756,16 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
/* fake render face */
memset(&vlr, 0, sizeof(VlakRen));
- vlr.lay= -1;
+ memset(&obr, 0, sizeof(ObjectRen));
+ memset(&obi, 0, sizeof(ObjectInstanceRen));
+ obr.lay= -1;
+ obi.obr= &obr;
return;
}
shi->vlr= &vlr;
+ shi->obr= &obr;
+ shi->obi= &obi;
if(shi->mat->nodetree && shi->mat->use_nodes)
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
@@ -1647,6 +1784,7 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
typedef struct BakeShade {
ShadeSample ssamp;
+ ObjectInstanceRen *obi;
VlakRen *vlr;
ZSpan *zspan;
@@ -1654,78 +1792,156 @@ typedef struct BakeShade {
ImBuf *ibuf;
int rectx, recty, quad, type, vdone, ready;
+
+ float dir[3];
+ Object *actob;
unsigned int *rect;
float *rect_float;
+
+ int usemask;
+ char *rect_mask; /* bake pixel mask */
+
+ float dxco[3], dyco[3];
} BakeShade;
-static void do_bake_shade(void *handle, int x, int y, float u, float v)
+/* bake uses a char mask to know what has been baked */
+#define BAKE_MASK_NULL 0
+#define BAKE_MASK_MARGIN 1
+#define BAKE_MASK_BAKED 2
+static void bake_mask_filter_extend( char *mask, int width, int height )
{
- BakeShade *bs= handle;
- ShadeSample *ssamp= &bs->ssamp;
- ShadeInput *shi= ssamp->shi;
- ShadeResult shr;
- VlakRen *vlr= bs->vlr;
- float l, *v1, *v2, *v3;
-
- /* fast threadsafe break test */
- if(R.test_break())
- return;
-
- /* setup render coordinates */
- if(bs->quad) {
- v1= vlr->v1->co;
- v2= vlr->v3->co;
- v3= vlr->v4->co;
+ char *row1, *row2, *row3;
+ int rowlen, x, y;
+ char *temprect;
+
+ rowlen= width;
+
+ /* make a copy, to prevent flooding */
+ temprect= MEM_dupallocN(mask);
+
+ for(y=1; y<=height; y++) {
+ /* setup rows */
+ row1= (char *)(temprect + (y-2)*rowlen);
+ row2= row1 + rowlen;
+ row3= row2 + rowlen;
+ if(y==1)
+ row1= row2;
+ else if(y==height)
+ row3= row2;
+
+ for(x=0; x<rowlen; x++) {
+ if (mask[((y-1)*rowlen)+x]==0) {
+ if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
+ mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
+ } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
+ mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
+ }
+ }
+
+ if(x!=0) {
+ row1++; row2++; row3++;
+ }
+ }
+ }
+ MEM_freeN(temprect);
+}
+
+static void bake_mask_clear( ImBuf *ibuf, char *mask, char val )
+{
+ int x,y;
+ if (ibuf->rect_float) {
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0.0f;
+ }
+ }
+ }
+
+ } else {
+ /* char buffer */
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ char *col= (char *)(ibuf->rect + ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0;
+ }
+ }
+ }
+ }
+}
+
+static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
+{
+ if(isect) {
+ /* raytrace intersection with different u,v than scanconvert */
+ if(vlr->v4) {
+ if(quad)
+ shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
+ }
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
}
else {
- v1= vlr->v1->co;
- v2= vlr->v2->co;
- v3= vlr->v3->co;
+ /* regular scanconvert */
+ if(quad)
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
+ else
+ shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
}
-
- /* renderco */
- l= 1.0f-u-v;
-
- shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
- shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
- shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
-
- /* set up view vector */
- VECCOPY(shi->view, shi->co);
- Normalize(shi->view);
-
- /* no face normal flip */
- shi->puno= 0;
-
+
/* cache for shadow */
- shi->samplenr++;
-
- if(bs->quad)
- shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
- else
- shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
+
+ shi->mask= 0xFFFF; /* all samples */
shi->u= -u;
shi->v= -v;
shi->xs= x;
shi->ys= y;
+ shade_input_set_uv(shi);
shade_input_set_normals(shi);
+ /* no normal flip */
+ if(shi->flippednor)
+ shade_input_flip_normals(shi);
+
+ /* set up view vector to look right at the surface (note that the normal
+ * is negated in the renderer so it does not need to be done here) */
+ shi->view[0]= shi->vn[0];
+ shi->view[1]= shi->vn[1];
+ shi->view[2]= shi->vn[2];
+}
+
+static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
+{
+ BakeShade *bs= handle;
+ ShadeSample *ssamp= &bs->ssamp;
+ ShadeResult shr;
+ VlakRen *vlr= shi->vlr;
+
/* init material vars */
memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
shi->har= shi->mat->har;
if(bs->type==RE_BAKE_AO) {
ambient_occlusion(shi);
- ambient_occlusion_to_diffuse(shi, shr.combined);
+
+ if(R.r.bake_flag & R_BAKE_NORMALIZE)
+ VECCOPY(shr.combined, shi->ao)
+ else
+ ambient_occlusion_to_diffuse(shi, shr.combined);
}
else {
-
shade_input_set_shade_texco(shi);
- shade_samples_do_AO(ssamp);
+ if(!ELEM(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE))
+ shade_samples_do_AO(ssamp);
if(shi->mat->nodetree && shi->mat->use_nodes) {
ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
@@ -1735,87 +1951,359 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v)
shade_material_loop(shi, &shr);
if(bs->type==RE_BAKE_NORMALS) {
- shr.combined[0]= shi->vn[0]/2.0f + 0.5f;
- shr.combined[1]= 0.5f - shi->vn[1]/2.0f;
- shr.combined[2]= shi->vn[2]/2.0f + 0.5f;
+ float nor[3];
+
+ VECCOPY(nor, shi->vn);
+
+ if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
+ else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
+ float mat[3][3], imat[3][3];
+
+ /* bitangent */
+ if(tvn && ttang) {
+ VECCOPY(mat[0], ttang);
+ Crossf(mat[1], tvn, ttang);
+ VECCOPY(mat[2], tvn);
+ }
+ else {
+ VECCOPY(mat[0], shi->nmaptang);
+ Crossf(mat[1], shi->vn, shi->nmaptang);
+ VECCOPY(mat[2], shi->vn);
+ }
+
+ Mat3Inv(imat, mat);
+ Mat3MulVecfl(imat, nor);
+ }
+ else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
+ Mat4Mul3Vecfl(ob->imat, nor); /* ob->imat includes viewinv! */
+ else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
+ Mat4Mul3Vecfl(R.viewinv, nor);
+
+ Normalize(nor); /* in case object has scaling */
+
+ shr.combined[0]= nor[0]/2.0f + 0.5f;
+ shr.combined[1]= 0.5f - nor[1]/2.0f;
+ shr.combined[2]= nor[2]/2.0f + 0.5f;
}
else if(bs->type==RE_BAKE_TEXTURE) {
shr.combined[0]= shi->r;
shr.combined[1]= shi->g;
shr.combined[2]= shi->b;
+ shr.alpha = shi->alpha;
}
}
- if(bs->rect) {
+ if(bs->rect_float) {
+ float *col= bs->rect_float + 4*(bs->rectx*y + x);
+ VECCOPY(col, shr.combined);
+ if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
+ col[3]= shr.alpha;
+ } else {
+ col[3]= 1.0;
+ }
+ }
+ else {
char *col= (char *)(bs->rect + bs->rectx*y + x);
col[0]= FTOCHAR(shr.combined[0]);
col[1]= FTOCHAR(shr.combined[1]);
col[2]= FTOCHAR(shr.combined[2]);
- col[3]= 255;
+
+
+ if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
+ col[3]= FTOCHAR(shr.alpha);
+ } else {
+ col[3]= 255;
+ }
}
- else {
+
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
+ }
+}
+
+static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y)
+{
+ BakeShade *bs= handle;
+ float disp;
+
+ if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
+ disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
+ } else {
+ disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
+ }
+
+ if(bs->rect_float) {
float *col= bs->rect_float + 4*(bs->rectx*y + x);
- VECCOPY(col, shr.combined);
+ col[0] = col[1] = col[2] = disp;
col[3]= 1.0f;
+ } else {
+ char *col= (char *)(bs->rect + bs->rectx*y + x);
+ col[0]= FTOCHAR(disp);
+ col[1]= FTOCHAR(disp);
+ col[2]= FTOCHAR(disp);
+ col[3]= 255;
+ }
+ if (bs->rect_mask) {
+ bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
+ }
+}
+
+static int bake_check_intersect(Isect *is, int ob, RayFace *face)
+{
+ BakeShade *bs = (BakeShade*)is->userdata;
+
+ /* no direction checking for now, doesn't always improve the result
+ * (INPR(shi->facenor, bs->dir) > 0.0f); */
+
+ return (R.objectinstance[ob].obr->ob != bs->actob);
+}
+
+static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
+{
+ float maxdist;
+ int hit;
+
+ /* might be useful to make a user setting for maxsize*/
+ if(R.r.bake_maxdist > 0.0f)
+ maxdist= R.r.bake_maxdist;
+ else
+ maxdist= RE_ray_tree_max_size(R.raytree) + R.r.bake_biasdist;
+
+ VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
+
+ isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
+ isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
+ isect->end[2] = isect->start[2] + dir[2]*maxdist*sign;
+
+ hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
+ if(hit) {
+ hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
+ hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
+ hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
+
+ *dist= VecLenf(start, hitco);
+ }
+
+ return hit;
+}
+
+static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
+{
+ VlakRen *vlr= bs->vlr;
+ float A, d1, d2, d3, *v1, *v2, *v3;
+
+ if(bs->quad) {
+ v1= vlr->v1->co;
+ v2= vlr->v3->co;
+ v3= vlr->v4->co;
+ }
+ else {
+ v1= vlr->v1->co;
+ v2= vlr->v2->co;
+ v3= vlr->v3->co;
+ }
+
+ /* formula derived from barycentric coordinates:
+ * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
+ * then taking u and v partial derivatives to get dxco and dyco */
+ A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
+
+ if(fabs(A) > FLT_EPSILON) {
+ A= 0.5f/A;
+
+ d1= uv2[1] - uv3[1];
+ d2= uv3[1] - uv1[1];
+ d3= uv1[1] - uv2[1];
+ bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
+ bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
+ bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
+
+ d1= uv3[0] - uv2[0];
+ d2= uv1[0] - uv3[0];
+ d3= uv2[0] - uv1[0];
+ bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
+ bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
+ bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
+ }
+ else {
+ bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
+ bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
+ }
+
+ if(bs->obi->flag & R_TRANSFORMED) {
+ Mat3MulVecfl(bs->obi->nmat, bs->dxco);
+ Mat3MulVecfl(bs->obi->nmat, bs->dyco);
+ }
+}
+
+static void do_bake_shade(void *handle, int x, int y, float u, float v)
+{
+ BakeShade *bs= handle;
+ VlakRen *vlr= bs->vlr;
+ ObjectInstanceRen *obi= bs->obi;
+ Object *ob= obi->obr->ob;
+ float l, *v1, *v2, *v3, tvn[3], ttang[3];
+ int quad;
+ ShadeSample *ssamp= &bs->ssamp;
+ ShadeInput *shi= ssamp->shi;
+
+ /* fast threadsafe break test */
+ if(R.test_break())
+ return;
+
+ /* setup render coordinates */
+ if(bs->quad) {
+ v1= vlr->v1->co;
+ v2= vlr->v3->co;
+ v3= vlr->v4->co;
+ }
+ else {
+ v1= vlr->v1->co;
+ v2= vlr->v2->co;
+ v3= vlr->v3->co;
+ }
+
+ /* renderco */
+ l= 1.0f-u-v;
+
+ shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
+ shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
+ shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, shi->co);
+
+ VECCOPY(shi->dxco, bs->dxco);
+ VECCOPY(shi->dyco, bs->dyco);
+
+ quad= bs->quad;
+ bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
+
+ if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
+ shade_input_set_shade_texco(shi);
+ VECCOPY(tvn, shi->vn);
+ VECCOPY(ttang, shi->nmaptang);
+ }
+
+ /* if we are doing selected to active baking, find point on other face */
+ if(bs->actob) {
+ Isect isec, minisec;
+ float co[3], minco[3], dist, mindist=0.0f;
+ int hit, sign, dir=1;
+
+ /* intersect with ray going forward and backward*/
+ hit= 0;
+ memset(&minisec, 0, sizeof(minisec));
+ minco[0]= minco[1]= minco[2]= 0.0f;
+
+ VECCOPY(bs->dir, shi->vn);
+
+ for(sign=-1; sign<=1; sign+=2) {
+ memset(&isec, 0, sizeof(isec));
+ isec.mode= RE_RAY_MIRROR;
+ isec.faceorig= (RayFace*)vlr;
+ isec.oborig= RAY_OBJECT_SET(&R, obi);
+ isec.userdata= bs;
+
+ if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
+ if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
+ minisec= isec;
+ mindist= dist;
+ VECCOPY(minco, co);
+ hit= 1;
+ dir = sign;
+ }
+ }
+ }
+
+ if (hit && bs->type==RE_BAKE_DISPLACEMENT) {;
+ bake_displacement(handle, shi, (dir==-1)? -mindist:mindist, x, y);
+ return;
+ }
+
+ /* if hit, we shade from the new point, otherwise from point one starting face */
+ if(hit) {
+ vlr= (VlakRen*)minisec.face;
+ obi= RAY_OBJECT_GET(&R, minisec.ob);
+ quad= (minisec.isect == 2);
+ VECCOPY(shi->co, minco);
+
+ u= -minisec.u;
+ v= -minisec.v;
+ bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
+ }
}
+
+ if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
+ bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
+ else
+ bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
}
static int get_next_bake_face(BakeShade *bs)
{
+ ObjectRen *obr;
VlakRen *vlr;
MTFace *tface;
static int v= 0, vdone= 0;
+ static ObjectInstanceRen *obi= NULL;
if(bs==NULL) {
vlr= NULL;
v= vdone= 0;
+ obi= R.instancetable.first;
return 0;
}
BLI_lock_thread(LOCK_CUSTOM1);
-
- for(; v<R.totvlak; v++) {
- vlr= RE_findOrAddVlak(&R, v);
-
- if(vlr->ob->flag & SELECT) {
- tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
- if(tface && tface->tpage) {
- Image *ima= tface->tpage;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
- float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
-
- if(ibuf==NULL)
- continue;
-
- if(ibuf->rect==NULL && ibuf->rect_float==NULL)
- continue;
-
- if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
- continue;
-
- /* find the image for the first time? */
- if(ima->id.flag & LIB_DOIT) {
- ima->id.flag &= ~LIB_DOIT;
+ for(; obi; obi=obi->next, v=0) {
+ obr= obi->obr;
+
+ for(; v<obr->totvlak; v++) {
+ vlr= RE_findOrAddVlak(obr, v);
+
+ if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
+ tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
+
+ if(tface && tface->tpage) {
+ Image *ima= tface->tpage;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
- /* we either fill in float or char, this ensures things go fine */
- if(ibuf->rect_float)
- imb_freerectImBuf(ibuf);
- /* clear image */
- if(R.r.bake_flag & R_BAKE_CLEAR)
- IMB_rectfill(ibuf, vec);
-
- /* might be read by UI to set active image for display */
- R.bakebuf= ima;
- }
-
- bs->vlr= vlr;
-
- bs->vdone++; /* only for error message if nothing was rendered */
- v++;
-
- BLI_unlock_thread(LOCK_CUSTOM1);
- return 1;
+ if(ibuf==NULL)
+ continue;
+
+ if(ibuf->rect==NULL && ibuf->rect_float==NULL)
+ continue;
+
+ if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
+ continue;
+
+ /* find the image for the first time? */
+ if(ima->id.flag & LIB_DOIT) {
+ ima->id.flag &= ~LIB_DOIT;
+
+ /* we either fill in float or char, this ensures things go fine */
+ if(ibuf->rect_float)
+ imb_freerectImBuf(ibuf);
+ /* clear image */
+ if(R.r.bake_flag & R_BAKE_CLEAR)
+ IMB_rectfill(ibuf, vec);
+
+ /* might be read by UI to set active image for display */
+ R.bakebuf= ima;
+ }
+
+ bs->obi= obi;
+ bs->vlr= vlr;
+
+ bs->vdone++; /* only for error message if nothing was rendered */
+ v++;
+
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 1;
+ }
}
}
}
@@ -1828,7 +2316,9 @@ static int get_next_bake_face(BakeShade *bs)
static void shade_tface(BakeShade *bs)
{
VlakRen *vlr= bs->vlr;
- MTFace *tface= RE_vlakren_get_tface(&R, vlr, 0, NULL, 0);
+ ObjectInstanceRen *obi= bs->obi;
+ ObjectRen *obr= obi->obr;
+ MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
Image *ima= tface->tpage;
float vec[4][2];
int a, i1, i2, i3;
@@ -1839,7 +2329,7 @@ static void shade_tface(BakeShade *bs)
bs->ibuf= BKE_image_get_ibuf(ima, NULL);
/* note, these calls only free/fill contents of zspan struct, not zspan itself */
zbuf_free_span(bs->zspan);
- zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y);
+ zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
}
bs->rectx= bs->ibuf->x;
@@ -1848,6 +2338,19 @@ static void shade_tface(BakeShade *bs)
bs->rect_float= bs->ibuf->rect_float;
bs->quad= 0;
+ if (bs->usemask) {
+ if (bs->ibuf->userdata==NULL) {
+ BLI_lock_thread(LOCK_CUSTOM1);
+ if (bs->ibuf->userdata==NULL) { /* since the thread was locked, its possible another thread alloced the value */
+ bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
+ bs->rect_mask= (char *)bs->ibuf->userdata;
+ }
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ } else {
+ bs->rect_mask= (char *)bs->ibuf->userdata;
+ }
+ }
+
/* get pixel level vertex coordinates */
for(a=0; a<4; a++) {
vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f;
@@ -1857,10 +2360,12 @@ static void shade_tface(BakeShade *bs)
/* UV indices have to be corrected for possible quad->tria splits */
i1= 0; i2= 1; i3= 2;
vlr_set_uv_indices(vlr, &i1, &i2, &i3);
+ bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
if(vlr->v4) {
bs->quad= 1;
+ bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
}
}
@@ -1884,23 +2389,31 @@ static void *do_bake_thread(void *bs_v)
/* using object selection tags, the faces with UV maps get baked */
/* render should have been setup */
/* returns 0 if nothing was handled */
-int RE_bake_shade_all_selected(Render *re, int type)
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
{
BakeShade handles[BLENDER_MAX_THREADS];
ListBase threads;
Image *ima;
- int a, vdone=0;
+ int a, vdone=0, usemask=0;
+
+ /* initialize render global */
+ R= *re;
+ R.bakebuf= NULL;
/* initialize static vars */
get_next_bake_face(NULL);
+ /* do we need a mask? */
+ if (re->r.bake_filter && (re->r.bake_flag & R_BAKE_CLEAR)==0)
+ usemask = 1;
+
/* baker uses this flag to detect if image was initialized */
- for(ima= G.main->image.first; ima; ima= ima->id.next)
+ for(ima= G.main->image.first; ima; ima= ima->id.next) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
ima->id.flag |= LIB_DOIT;
-
- /* initialize render global */
- R= *re;
- R.bakebuf= NULL;
+ if (ibuf)
+ ibuf->userdata = NULL; /* use for masking if needed */
+ }
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
@@ -1916,8 +2429,11 @@ int RE_bake_shade_all_selected(Render *re, int type)
handles[a].ssamp.tot= 1;
handles[a].type= type;
+ handles[a].actob= actob;
handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
+ handles[a].usemask = usemask;
+
BLI_insert_thread(&threads, &handles[a]);
}
@@ -1932,23 +2448,52 @@ int RE_bake_shade_all_selected(Render *re, int type)
break;
}
- /* filter images */
+ /* filter and refresh images */
for(ima= G.main->image.first; ima; ima= ima->id.next) {
if((ima->id.flag & LIB_DOIT)==0) {
ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
- for(a=0; a<re->r.bake_filter; a++)
- IMB_filter_extend(ibuf);
+ if (re->r.bake_filter) {
+ if (usemask) {
+ /* extend the mask +2 pixels from the image,
+ * this is so colors dont blend in from outside */
+ char *temprect;
+
+ for(a=0; a<re->r.bake_filter; a++)
+ bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
+
+ temprect = MEM_dupallocN(ibuf->userdata);
+
+ /* expand twice to clear this many pixels, so they blend back in */
+ bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+ bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+
+ /* clear all pixels in the margin*/
+ bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN);
+ MEM_freeN(temprect);
+ }
+
+ for(a=0; a<re->r.bake_filter; a++) {
+ /*the mask, ibuf->userdata - can be null, in this case only zero alpha is used */
+ IMB_filter_extend(ibuf, (char *)ibuf->userdata);
+ }
+
+ if (ibuf->userdata) {
+ MEM_freeN(ibuf->userdata);
+ ibuf->userdata= NULL;
+ }
+ }
ibuf->userflags |= IB_BITMAPDIRTY;
+ if (ibuf->rect_float) IMB_rect_from_float(ibuf);
}
}
/* calculate return value */
- for(a=0; a<re->r.threads; a++) {
+ for(a=0; a<re->r.threads; a++) {
vdone+= handles[a].vdone;
zbuf_free_span(handles[a].zspan);
MEM_freeN(handles[a].zspan);
- }
+ }
BLI_end_threads(&threads);
return vdone;
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 6d9f0e4eb01..441aa9336be 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -62,6 +62,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_memarena.h"
#include "DNA_material_types.h"
@@ -71,6 +72,7 @@
#include "BKE_customdata.h"
#include "BKE_texture.h"
+#include "BKE_DerivedMesh.h"
#include "RE_render_ext.h" /* externtex */
@@ -78,6 +80,7 @@
#include "render_types.h"
#include "renderdatabase.h"
#include "texture.h"
+#include "strand.h"
#include "zbuf.h"
/* ------------------------------------------------------------------------- */
@@ -99,31 +102,37 @@
#define RE_WINSPEED_ELEMS 4
#define RE_MTFACE_ELEMS 1
#define RE_MCOL_ELEMS 4
-
-float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify)
+#define RE_UV_ELEMS 2
+#define RE_SURFNOR_ELEMS 3
+#define RE_RADFACE_ELEMS 1
+#define RE_SIMPLIFY_ELEMS 2
+#define RE_FACE_ELEMS 1
+#define RE_NMAP_TANGENT_ELEMS 12
+
+float *RE_vertren_get_sticky(ObjectRen *obr, VertRen *ver, int verify)
{
float *sticky;
int nr= ver->index>>8;
- sticky= re->vertnodes[nr].sticky;
+ sticky= obr->vertnodes[nr].sticky;
if(sticky==NULL) {
if(verify)
- sticky= re->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
+ sticky= obr->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table");
else
return NULL;
}
return sticky + (ver->index & 255)*RE_STICKY_ELEMS;
}
-float *RE_vertren_get_stress(Render *re, VertRen *ver, int verify)
+float *RE_vertren_get_stress(ObjectRen *obr, VertRen *ver, int verify)
{
float *stress;
int nr= ver->index>>8;
- stress= re->vertnodes[nr].stress;
+ stress= obr->vertnodes[nr].stress;
if(stress==NULL) {
if(verify)
- stress= re->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
+ stress= obr->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table");
else
return NULL;
}
@@ -131,30 +140,30 @@ float *RE_vertren_get_stress(Render *re, VertRen *ver, int verify)
}
/* this one callocs! */
-float *RE_vertren_get_rad(Render *re, VertRen *ver, int verify)
+float *RE_vertren_get_rad(ObjectRen *obr, VertRen *ver, int verify)
{
float *rad;
int nr= ver->index>>8;
- rad= re->vertnodes[nr].rad;
+ rad= obr->vertnodes[nr].rad;
if(rad==NULL) {
if(verify)
- rad= re->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
+ rad= obr->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table");
else
return NULL;
}
return rad + (ver->index & 255)*RE_RAD_ELEMS;
}
-float *RE_vertren_get_strand(Render *re, VertRen *ver, int verify)
+float *RE_vertren_get_strand(ObjectRen *obr, VertRen *ver, int verify)
{
float *strand;
int nr= ver->index>>8;
- strand= re->vertnodes[nr].strand;
+ strand= obr->vertnodes[nr].strand;
if(strand==NULL) {
if(verify)
- strand= re->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
+ strand= obr->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table");
else
return NULL;
}
@@ -162,15 +171,15 @@ float *RE_vertren_get_strand(Render *re, VertRen *ver, int verify)
}
/* needs calloc */
-float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify)
+float *RE_vertren_get_tangent(ObjectRen *obr, VertRen *ver, int verify)
{
float *tangent;
int nr= ver->index>>8;
- tangent= re->vertnodes[nr].tangent;
+ tangent= obr->vertnodes[nr].tangent;
if(tangent==NULL) {
if(verify)
- tangent= re->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
+ tangent= obr->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table");
else
return NULL;
}
@@ -178,64 +187,62 @@ float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify)
}
/* needs calloc! not all renderverts have them */
-float *RE_vertren_get_winspeed(Render *re, VertRen *ver, int verify)
+/* also winspeed is exception, it is stored per instance */
+float *RE_vertren_get_winspeed(ObjectInstanceRen *obi, VertRen *ver, int verify)
{
float *winspeed;
- int nr= ver->index>>8;
+ int totvector;
- winspeed= re->vertnodes[nr].winspeed;
+ winspeed= obi->vectors;
if(winspeed==NULL) {
- if(verify)
- winspeed= re->vertnodes[nr].winspeed= MEM_callocN(256*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+ if(verify) {
+ totvector= obi->obr->totvert + obi->obr->totstrand;
+ winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed table");
+ }
else
return NULL;
}
- return winspeed + (ver->index & 255)*RE_WINSPEED_ELEMS;
+ return winspeed + ver->index*RE_WINSPEED_ELEMS;
}
-VertRen *RE_vertren_copy(Render *re, VertRen *ver)
+VertRen *RE_vertren_copy(ObjectRen *obr, VertRen *ver)
{
- VertRen *v1= RE_findOrAddVert(re, re->totvert++);
+ VertRen *v1= RE_findOrAddVert(obr, obr->totvert++);
float *fp1, *fp2;
int index= v1->index;
*v1= *ver;
v1->index= index;
- fp1= RE_vertren_get_sticky(re, ver, 0);
+ fp1= RE_vertren_get_sticky(obr, ver, 0);
if(fp1) {
- fp2= RE_vertren_get_sticky(re, v1, 1);
+ fp2= RE_vertren_get_sticky(obr, v1, 1);
memcpy(fp2, fp1, RE_STICKY_ELEMS*sizeof(float));
}
- fp1= RE_vertren_get_stress(re, ver, 0);
+ fp1= RE_vertren_get_stress(obr, ver, 0);
if(fp1) {
- fp2= RE_vertren_get_stress(re, v1, 1);
+ fp2= RE_vertren_get_stress(obr, v1, 1);
memcpy(fp2, fp1, RE_STRESS_ELEMS*sizeof(float));
}
- fp1= RE_vertren_get_rad(re, ver, 0);
+ fp1= RE_vertren_get_rad(obr, ver, 0);
if(fp1) {
- fp2= RE_vertren_get_rad(re, v1, 1);
+ fp2= RE_vertren_get_rad(obr, v1, 1);
memcpy(fp2, fp1, RE_RAD_ELEMS*sizeof(float));
}
- fp1= RE_vertren_get_strand(re, ver, 0);
+ fp1= RE_vertren_get_strand(obr, ver, 0);
if(fp1) {
- fp2= RE_vertren_get_strand(re, v1, 1);
+ fp2= RE_vertren_get_strand(obr, v1, 1);
memcpy(fp2, fp1, RE_STRAND_ELEMS*sizeof(float));
}
- fp1= RE_vertren_get_tangent(re, ver, 0);
+ fp1= RE_vertren_get_tangent(obr, ver, 0);
if(fp1) {
- fp2= RE_vertren_get_tangent(re, v1, 1);
+ fp2= RE_vertren_get_tangent(obr, v1, 1);
memcpy(fp2, fp1, RE_TANGENT_ELEMS*sizeof(float));
}
- fp1= RE_vertren_get_winspeed(re, ver, 0);
- if(fp1) {
- fp2= RE_vertren_get_winspeed(re, v1, 1);
- memcpy(fp2, fp1, RE_WINSPEED_ELEMS*sizeof(float));
- }
return v1;
}
-VertRen *RE_findOrAddVert(Render *re, int nr)
+VertRen *RE_findOrAddVert(ObjectRen *obr, int nr)
{
VertTableNode *temp;
VertRen *v;
@@ -247,23 +254,23 @@ VertRen *RE_findOrAddVert(Render *re, int nr)
}
a= nr>>8;
- if (a>=re->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
- temp= re->vertnodes;
+ if (a>=obr->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->vertnodes;
- re->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(re->vertnodeslen+TABLEINITSIZE) , "vertnodes");
- if(temp) memcpy(re->vertnodes, temp, re->vertnodeslen*sizeof(VertTableNode));
- memset(re->vertnodes+re->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
+ obr->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(obr->vertnodeslen+TABLEINITSIZE) , "vertnodes");
+ if(temp) memcpy(obr->vertnodes, temp, obr->vertnodeslen*sizeof(VertTableNode));
+ memset(obr->vertnodes+obr->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode));
- re->vertnodeslen+=TABLEINITSIZE;
+ obr->vertnodeslen+=TABLEINITSIZE;
if(temp) MEM_freeN(temp);
}
- v= re->vertnodes[a].vert;
+ v= obr->vertnodes[a].vert;
if(v==NULL) {
int i;
v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert");
- re->vertnodes[a].vert= v;
+ obr->vertnodes[a].vert= v;
for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) {
v[a].index= i;
@@ -275,171 +282,234 @@ VertRen *RE_findOrAddVert(Render *re, int nr)
/* ------------------------------------------------------------------------ */
-MTFace *RE_vlakren_get_tface(Render *re, VlakRen *vlr, int n, char **name, int verify)
+MTFace *RE_vlakren_get_tface(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
{
VlakTableNode *node;
int nr= vlr->index>>8, vlakindex= (vlr->index&255);
int index= (n<<8) + vlakindex;
- node= &re->vlaknodes[nr];
+ node= &obr->vlaknodes[nr];
if(verify) {
if(n>=node->totmtface) {
- MTFace **mtface= node->mtface;
+ MTFace *mtface= node->mtface;
int size= size= (n+1)*256;
- node->mtface= MEM_callocN(size*sizeof(MTFace*), "Vlak mtface");
+ node->mtface= MEM_callocN(size*sizeof(MTFace), "Vlak mtface");
if(mtface) {
size= node->totmtface*256;
- memcpy(node->mtface, mtface, size*sizeof(MTFace*));
+ memcpy(node->mtface, mtface, size*sizeof(MTFace));
MEM_freeN(mtface);
}
node->totmtface= n+1;
-
- if (!node->names) {
- size= sizeof(*node->names)*256;
- node->names= MEM_callocN(size, "Vlak names");
- }
- }
-
- if(node->mtface[index]==NULL) {
- node->mtface[index]= BLI_memarena_alloc(re->memArena,
- sizeof(MTFace)*RE_MTFACE_ELEMS);
-
- node->names[vlakindex]= re->customdata_names.last;
}
}
else {
- if(n>=node->totmtface || node->mtface[index]==NULL)
+ if(n>=node->totmtface)
return NULL;
- if(name) *name= node->names[vlakindex]->mtface[n];
+ if(name) *name= obr->mtface[n];
}
- return node->mtface[index];
+ return node->mtface + index;
}
-MCol *RE_vlakren_get_mcol(Render *re, VlakRen *vlr, int n, char **name, int verify)
+MCol *RE_vlakren_get_mcol(ObjectRen *obr, VlakRen *vlr, int n, char **name, int verify)
{
VlakTableNode *node;
int nr= vlr->index>>8, vlakindex= (vlr->index&255);
int index= (n<<8) + vlakindex;
- node= &re->vlaknodes[nr];
+ node= &obr->vlaknodes[nr];
if(verify) {
if(n>=node->totmcol) {
- MCol **mcol= node->mcol;
+ MCol *mcol= node->mcol;
int size= (n+1)*256;
- node->mcol= MEM_callocN(size*sizeof(MCol*), "Vlak mcol");
+ node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "Vlak mcol");
if(mcol) {
size= node->totmcol*256;
- memcpy(node->mcol, mcol, size*sizeof(MCol*));
+ memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
MEM_freeN(mcol);
}
node->totmcol= n+1;
-
- if (!node->names) {
- size= sizeof(*node->names)*256;
- node->names= MEM_callocN(size, "Vlak names");
- }
- }
-
- if(node->mcol[index]==NULL) {
- node->mcol[index]= BLI_memarena_alloc(re->memArena,
- sizeof(MCol)*RE_MCOL_ELEMS);
-
- node->names[vlakindex]= re->customdata_names.last;
}
}
else {
- if(n>=node->totmcol || node->mcol[index]==NULL)
+ if(n>=node->totmcol)
+ return NULL;
+
+ if(name) *name= obr->mcol[n];
+ }
+
+ return node->mcol + index*RE_MCOL_ELEMS;
+}
+
+float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ float *surfnor;
+ int nr= vlak->index>>8;
+
+ surfnor= obr->vlaknodes[nr].surfnor;
+ if(surfnor==NULL) {
+ if(verify)
+ surfnor= obr->vlaknodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor table");
+ else
return NULL;
+ }
+ return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
+}
- if(name) *name= node->names[vlakindex]->mcol[n];
+float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ float *tangent;
+ int nr= vlak->index>>8;
+
+ tangent= obr->vlaknodes[nr].tangent;
+ if(tangent==NULL) {
+ if(verify)
+ tangent= obr->vlaknodes[nr].tangent= MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
+ else
+ return NULL;
}
+ return tangent + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
+}
- return node->mcol[index];
+RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
+{
+ RadFace **radface;
+ int nr= vlak->index>>8;
+
+ radface= obr->vlaknodes[nr].radface;
+ if(radface==NULL) {
+ if(verify)
+ radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table");
+ else
+ return NULL;
+ }
+ return radface + (vlak->index & 255)*RE_RADFACE_ELEMS;
}
-VlakRen *RE_vlakren_copy(Render *re, VlakRen *vlr)
+VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
{
- VlakRen *vlr1 = RE_findOrAddVlak(re, re->totvlak++);
+ VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
MTFace *mtface, *mtface1;
MCol *mcol, *mcol1;
- VlakTableNode *node = &re->vlaknodes[vlr->index>>8];
- VlakTableNode *node1 = &re->vlaknodes[vlr1->index>>8];
+ float *surfnor, *surfnor1, *tangent, *tangent1;
+ RadFace **radface, **radface1;
int i, index = vlr1->index;
char *name;
*vlr1= *vlr;
vlr1->index= index;
- for (i=0; (mtface=RE_vlakren_get_tface(re, vlr, i, &name, 0)) != NULL; i++) {
- mtface1= RE_vlakren_get_tface(re, vlr1, i, &name, 1);
+ for (i=0; (mtface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)) != NULL; i++) {
+ mtface1= RE_vlakren_get_tface(obr, vlr1, i, &name, 1);
memcpy(mtface1, mtface, sizeof(MTFace)*RE_MTFACE_ELEMS);
}
- for (i=0; (mcol=RE_vlakren_get_mcol(re, vlr, i, &name, 0)) != NULL; i++) {
- mcol1= RE_vlakren_get_mcol(re, vlr1, i, &name, 1);
+ for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)) != NULL; i++) {
+ mcol1= RE_vlakren_get_mcol(obr, vlr1, i, &name, 1);
memcpy(mcol1, mcol, sizeof(MCol)*RE_MCOL_ELEMS);
}
- if (node->names && node1->names)
- node1->names[vlr1->index&255] = node->names[vlr->index&255];
+ surfnor= RE_vlakren_get_surfnor(obr, vlr, 0);
+ if(surfnor) {
+ surfnor1= RE_vlakren_get_surfnor(obr, vlr1, 1);
+ VECCOPY(surfnor1, surfnor);
+ }
+
+ tangent= RE_vlakren_get_nmap_tangent(obr, vlr, 0);
+ if(tangent) {
+ tangent1= RE_vlakren_get_nmap_tangent(obr, vlr1, 1);
+ memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS);
+ }
+
+ radface= RE_vlakren_get_radface(obr, vlr, 0);
+ if(radface) {
+ radface1= RE_vlakren_get_radface(obr, vlr1, 1);
+ *radface1= *radface;
+ }
return vlr1;
}
-static int vlakren_remap_layer_num(int n, int active)
+int RE_vlakren_get_normal(Render *re, ObjectInstanceRen *obi, VlakRen *vlr, float *nor)
{
- /* make the active layer the first */
- if (n == active) return 0;
- else if (n < active) return n+1;
- else return n;
+ float v1[3], (*nmat)[3]= obi->nmat;
+ int flipped= 0;
+
+ if(obi->flag & R_TRANSFORMED) {
+ VECCOPY(nor, vlr->n);
+
+ Mat3MulVecfl(nmat, nor);
+ Normalize(nor);
+ }
+ else
+ VECCOPY(nor, vlr->n);
+
+ if((vlr->flag & R_NOPUNOFLIP)==0) {
+ if(re->r.mode & R_ORTHO) {
+ if(nor[2] > 0.0f)
+ flipped= 1;
+ }
+ else {
+ VECCOPY(v1, vlr->v1->co);
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, v1);
+ if(INPR(v1, nor) < 0.0f) {
+ flipped= 1;
+ }
+ }
+
+ if(flipped) {
+ nor[0]= -nor[0];
+ nor[1]= -nor[1];
+ nor[2]= -nor[2];
+ }
+ }
+
+ return flipped;
}
-void RE_vlakren_set_customdata_names(Render *re, CustomData *data)
+void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
{
/* CustomData layer names are stored per object here, because the
DerivedMesh which stores the layers is freed */
- CustomDataNames *cdn= MEM_callocN(sizeof(*cdn), "CustomDataNames");
CustomDataLayer *layer;
- int numlayers, i, mtfn, mcn, n;
-
- BLI_addtail(&re->customdata_names, cdn);
+ int numlayers, i, mtfn, mcn;
if (CustomData_has_layer(data, CD_MTFACE)) {
numlayers= CustomData_number_of_layers(data, CD_MTFACE);
- cdn->mtface= MEM_callocN(sizeof(*cdn->mtface)*numlayers, "mtfacenames");
+ obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numlayers, "mtfacenames");
}
if (CustomData_has_layer(data, CD_MCOL)) {
numlayers= CustomData_number_of_layers(data, CD_MCOL);
- cdn->mcol= MEM_callocN(sizeof(*cdn->mcol)*numlayers, "mcolnames");
+ obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numlayers, "mcolnames");
}
for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
layer= &data->layers[i];
if (layer->type == CD_MTFACE) {
- n= vlakren_remap_layer_num(mtfn++, layer->active_rnd);
- strcpy(cdn->mtface[n], layer->name);
+ strcpy(obr->mtface[mtfn++], layer->name);
+ obr->actmtface= layer->active_rnd;
}
else if (layer->type == CD_MCOL) {
- n= vlakren_remap_layer_num(mcn++, layer->active_rnd);
- strcpy(cdn->mcol[n], layer->name);
+ strcpy(obr->mcol[mcn++], layer->name);
+ obr->actmcol= layer->active_rnd;
}
}
}
-VlakRen *RE_findOrAddVlak(Render *re, int nr)
+VlakRen *RE_findOrAddVlak(ObjectRen *obr, int nr)
{
VlakTableNode *temp;
VlakRen *v;
@@ -447,28 +517,28 @@ VlakRen *RE_findOrAddVlak(Render *re, int nr)
if(nr<0) {
printf("error in findOrAddVlak: %d\n",nr);
- return re->vlaknodes[0].vlak;
+ return obr->vlaknodes[0].vlak;
}
a= nr>>8;
- if (a>=re->vlaknodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
- temp= re->vlaknodes;
+ if (a>=obr->vlaknodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->vlaknodes;
- re->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(re->vlaknodeslen+TABLEINITSIZE) , "vlaknodes");
- if(temp) memcpy(re->vlaknodes, temp, re->vlaknodeslen*sizeof(VlakTableNode));
- memset(re->vlaknodes+re->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
+ obr->vlaknodes= MEM_mallocN(sizeof(VlakTableNode)*(obr->vlaknodeslen+TABLEINITSIZE) , "vlaknodes");
+ if(temp) memcpy(obr->vlaknodes, temp, obr->vlaknodeslen*sizeof(VlakTableNode));
+ memset(obr->vlaknodes+obr->vlaknodeslen, 0, TABLEINITSIZE*sizeof(VlakTableNode));
- re->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ obr->vlaknodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
if(temp) MEM_freeN(temp);
}
- v= re->vlaknodes[a].vlak;
+ v= obr->vlaknodes[a].vlak;
if(v==NULL) {
int i;
v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak");
- re->vlaknodes[a].vlak= v;
+ obr->vlaknodes[a].vlak= v;
for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
v[a].index= i;
@@ -479,18 +549,203 @@ VlakRen *RE_findOrAddVlak(Render *re, int nr)
/* ------------------------------------------------------------------------ */
-void RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int sve, int eve, int sfa, int efa)
+float *RE_strandren_get_surfnor(ObjectRen *obr, StrandRen *strand, int verify)
{
- ObjectRen *obr= MEM_mallocN(sizeof(ObjectRen), "object render struct");
+ float *surfnor;
+ int nr= strand->index>>8;
+
+ surfnor= obr->strandnodes[nr].surfnor;
+ if(surfnor==NULL) {
+ if(verify)
+ surfnor= obr->strandnodes[nr].surfnor= MEM_callocN(256*RE_SURFNOR_ELEMS*sizeof(float), "surfnor strand table");
+ else
+ return NULL;
+ }
+ return surfnor + (strand->index & 255)*RE_SURFNOR_ELEMS;
+}
+
+float *RE_strandren_get_uv(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
+{
+ StrandTableNode *node;
+ int nr= strand->index>>8, strandindex= (strand->index&255);
+ int index= (n<<8) + strandindex;
+
+ node= &obr->strandnodes[nr];
+
+ if(verify) {
+ if(n>=node->totuv) {
+ float *uv= node->uv;
+ int size= (n+1)*256;
+
+ node->uv= MEM_callocN(size*sizeof(float)*RE_UV_ELEMS, "strand uv table");
+
+ if(uv) {
+ size= node->totuv*256;
+ memcpy(node->uv, uv, size*sizeof(float)*RE_UV_ELEMS);
+ MEM_freeN(uv);
+ }
+
+ node->totuv= n+1;
+ }
+ }
+ else {
+ if(n>=node->totuv)
+ return NULL;
+
+ if(name) *name= obr->mtface[n];
+ }
+
+ return node->uv + index*RE_UV_ELEMS;
+}
+
+MCol *RE_strandren_get_mcol(ObjectRen *obr, StrandRen *strand, int n, char **name, int verify)
+{
+ StrandTableNode *node;
+ int nr= strand->index>>8, strandindex= (strand->index&255);
+ int index= (n<<8) + strandindex;
+
+ node= &obr->strandnodes[nr];
+
+ if(verify) {
+ if(n>=node->totmcol) {
+ MCol *mcol= node->mcol;
+ int size= (n+1)*256;
+
+ node->mcol= MEM_callocN(size*sizeof(MCol)*RE_MCOL_ELEMS, "strand mcol table");
+
+ if(mcol) {
+ size= node->totmcol*256;
+ memcpy(node->mcol, mcol, size*sizeof(MCol)*RE_MCOL_ELEMS);
+ MEM_freeN(mcol);
+ }
+
+ node->totmcol= n+1;
+ }
+ }
+ else {
+ if(n>=node->totmcol)
+ return NULL;
+
+ if(name) *name= obr->mcol[n];
+ }
+
+ return node->mcol + index*RE_MCOL_ELEMS;
+}
+
+float *RE_strandren_get_simplify(struct ObjectRen *obr, struct StrandRen *strand, int verify)
+{
+ float *simplify;
+ int nr= strand->index>>8;
+
+ simplify= obr->strandnodes[nr].simplify;
+ if(simplify==NULL) {
+ if(verify)
+ simplify= obr->strandnodes[nr].simplify= MEM_callocN(256*RE_SIMPLIFY_ELEMS*sizeof(float), "simplify strand table");
+ else
+ return NULL;
+ }
+ return simplify + (strand->index & 255)*RE_SIMPLIFY_ELEMS;
+}
+
+int *RE_strandren_get_face(ObjectRen *obr, StrandRen *strand, int verify)
+{
+ int *face;
+ int nr= strand->index>>8;
+
+ face= obr->strandnodes[nr].face;
+ if(face==NULL) {
+ if(verify)
+ face= obr->strandnodes[nr].face= MEM_callocN(256*RE_FACE_ELEMS*sizeof(int), "face strand table");
+ else
+ return NULL;
+ }
+ return face + (strand->index & 255)*RE_FACE_ELEMS;
+}
+
+/* winspeed is exception, it is stored per instance */
+float *RE_strandren_get_winspeed(ObjectInstanceRen *obi, StrandRen *strand, int verify)
+{
+ float *winspeed;
+ int totvector;
+
+ winspeed= obi->vectors;
+ if(winspeed==NULL) {
+ if(verify) {
+ totvector= obi->obr->totvert + obi->obr->totstrand;
+ winspeed= obi->vectors= MEM_callocN(totvector*RE_WINSPEED_ELEMS*sizeof(float), "winspeed strand table");
+ }
+ else
+ return NULL;
+ }
+ return winspeed + (obi->obr->totvert + strand->index)*RE_WINSPEED_ELEMS;
+}
+
+StrandRen *RE_findOrAddStrand(ObjectRen *obr, int nr)
+{
+ StrandTableNode *temp;
+ StrandRen *v;
+ int a;
+
+ if(nr<0) {
+ printf("error in findOrAddStrand: %d\n",nr);
+ return obr->strandnodes[0].strand;
+ }
+ a= nr>>8;
+
+ if (a>=obr->strandnodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
+ temp= obr->strandnodes;
+
+ obr->strandnodes= MEM_mallocN(sizeof(StrandTableNode)*(obr->strandnodeslen+TABLEINITSIZE) , "strandnodes");
+ if(temp) memcpy(obr->strandnodes, temp, obr->strandnodeslen*sizeof(StrandTableNode));
+ memset(obr->strandnodes+obr->strandnodeslen, 0, TABLEINITSIZE*sizeof(StrandTableNode));
+
+ obr->strandnodeslen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ if(temp) MEM_freeN(temp);
+ }
+
+ v= obr->strandnodes[a].strand;
+
+ if(v==NULL) {
+ int i;
+
+ v= (StrandRen *)MEM_callocN(256*sizeof(StrandRen),"findOrAddStrand");
+ obr->strandnodes[a].strand= v;
+
+ for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++)
+ v[a].index= i;
+ }
+ v+= (nr & 255);
+ return v;
+}
+
+StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert)
+{
+ StrandBuffer *strandbuf;
+
+ strandbuf= MEM_callocN(sizeof(StrandBuffer), "StrandBuffer");
+ strandbuf->vert= MEM_callocN(sizeof(StrandVert)*totvert, "StrandVert");
+ strandbuf->totvert= totvert;
+ strandbuf->obr= obr;
+
+ obr->strandbuf= strandbuf;
+
+ return strandbuf;
+}
+
+/* ------------------------------------------------------------------------ */
+
+ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay)
+{
+ ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct");
BLI_addtail(&re->objecttable, obr);
obr->ob= ob;
obr->par= par;
obr->index= index;
- obr->startvert= sve;
- obr->endvert= eve;
- obr->startface= sfa;
- obr->endface= efa;
+ obr->psysindex= psysindex;
+ obr->lay= lay;
+
+ return obr;
}
void free_renderdata_vertnodes(VertTableNode *vertnodes)
@@ -532,54 +787,116 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
MEM_freeN(vlaknodes[a].mtface);
if(vlaknodes[a].mcol)
MEM_freeN(vlaknodes[a].mcol);
- if(vlaknodes[a].names)
- MEM_freeN(vlaknodes[a].names);
+ if(vlaknodes[a].surfnor)
+ MEM_freeN(vlaknodes[a].surfnor);
+ if(vlaknodes[a].tangent)
+ MEM_freeN(vlaknodes[a].tangent);
+ if(vlaknodes[a].radface)
+ MEM_freeN(vlaknodes[a].radface);
}
MEM_freeN(vlaknodes);
}
+void free_renderdata_strandnodes(StrandTableNode *strandnodes)
+{
+ int a;
+
+ if(strandnodes==NULL) return;
+
+ for(a=0; strandnodes[a].strand; a++) {
+ MEM_freeN(strandnodes[a].strand);
+
+ if(strandnodes[a].uv)
+ MEM_freeN(strandnodes[a].uv);
+ if(strandnodes[a].mcol)
+ MEM_freeN(strandnodes[a].mcol);
+ if(strandnodes[a].winspeed)
+ MEM_freeN(strandnodes[a].winspeed);
+ if(strandnodes[a].surfnor)
+ MEM_freeN(strandnodes[a].surfnor);
+ if(strandnodes[a].simplify)
+ MEM_freeN(strandnodes[a].simplify);
+ if(strandnodes[a].face)
+ MEM_freeN(strandnodes[a].face);
+ }
+
+ MEM_freeN(strandnodes);
+}
+
void free_renderdata_tables(Render *re)
{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ StrandBuffer *strandbuf;
int a=0;
- CustomDataNames *cdn;
- if(re->bloha) {
- for(a=0; re->bloha[a]; a++)
- MEM_freeN(re->bloha[a]);
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ if(obr->vertnodes) {
+ free_renderdata_vertnodes(obr->vertnodes);
+ obr->vertnodes= NULL;
+ obr->vertnodeslen= 0;
+ }
- MEM_freeN(re->bloha);
- re->bloha= NULL;
- re->blohalen= 0;
- }
+ if(obr->vlaknodes) {
+ free_renderdata_vlaknodes(obr->vlaknodes);
+ obr->vlaknodes= NULL;
+ obr->vlaknodeslen= 0;
+ obr->totvlak= 0;
+ }
+
+ if(obr->bloha) {
+ for(a=0; obr->bloha[a]; a++)
+ MEM_freeN(obr->bloha[a]);
+
+ MEM_freeN(obr->bloha);
+ obr->bloha= NULL;
+ obr->blohalen= 0;
+ }
+
+ if(obr->strandnodes) {
+ free_renderdata_strandnodes(obr->strandnodes);
+ obr->strandnodes= NULL;
+ obr->strandnodeslen= 0;
+ }
+
+ strandbuf= obr->strandbuf;
+ if(strandbuf) {
+ if(strandbuf->vert) MEM_freeN(strandbuf->vert);
+ if(strandbuf->bound) MEM_freeN(strandbuf->bound);
+ MEM_freeN(strandbuf);
+ }
- if(re->vertnodes) {
- free_renderdata_vertnodes(re->vertnodes);
- re->vertnodes= NULL;
- re->vertnodeslen= 0;
+ if(obr->mtface)
+ MEM_freeN(obr->mtface);
+ if(obr->mcol)
+ MEM_freeN(obr->mcol);
}
- if(re->vlaknodes) {
- free_renderdata_vlaknodes(re->vlaknodes);
- re->vlaknodes= NULL;
- re->vlaknodeslen= 0;
+ if(re->objectinstance) {
+ for(obi=re->instancetable.first; obi; obi=obi->next)
+ if(obi->vectors)
+ MEM_freeN(obi->vectors);
+
+ MEM_freeN(re->objectinstance);
+ re->objectinstance= NULL;
+ re->totinstance= 0;
+ re->instancetable.first= re->instancetable.last= NULL;
}
- for(cdn=re->customdata_names.first; cdn; cdn=cdn->next) {
- if(cdn->mtface)
- MEM_freeN(cdn->mtface);
- if(cdn->mcol)
- MEM_freeN(cdn->mcol);
+ if(re->sortedhalos) {
+ MEM_freeN(re->sortedhalos);
+ re->sortedhalos= NULL;
}
BLI_freelistN(&re->customdata_names);
BLI_freelistN(&re->objecttable);
+ BLI_freelistN(&re->instancetable);
}
-
/* ------------------------------------------------------------------------ */
-HaloRen *RE_findOrAddHalo(Render *re, int nr)
+HaloRen *RE_findOrAddHalo(ObjectRen *obr, int nr)
{
HaloRen *h, **temp;
int a;
@@ -590,22 +907,22 @@ HaloRen *RE_findOrAddHalo(Render *re, int nr)
}
a= nr>>8;
- if (a>=re->blohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
+ if (a>=obr->blohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */
//printf("Allocating %i more halo groups. %i total.\n",
- // TABLEINITSIZE, re->blohalen+TABLEINITSIZE );
- temp=re->bloha;
+ // TABLEINITSIZE, obr->blohalen+TABLEINITSIZE );
+ temp=obr->bloha;
- re->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(re->blohalen+TABLEINITSIZE) , "Bloha");
- if(temp) memcpy(re->bloha, temp, re->blohalen*sizeof(void*));
- memset(&(re->bloha[re->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
- re->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
+ obr->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(obr->blohalen+TABLEINITSIZE) , "Bloha");
+ if(temp) memcpy(obr->bloha, temp, obr->blohalen*sizeof(void*));
+ memset(&(obr->bloha[obr->blohalen]), 0, TABLEINITSIZE*sizeof(void*));
+ obr->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/
if(temp) MEM_freeN(temp);
}
- h= re->bloha[a];
+ h= obr->bloha[a];
if(h==NULL) {
h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo");
- re->bloha[a]= h;
+ obr->bloha[a]= h;
}
h+= (nr & 255);
return h;
@@ -613,7 +930,7 @@ HaloRen *RE_findOrAddHalo(Render *re, int nr)
/* ------------------------------------------------------------------------- */
-HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1,
+HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, float *vec, float *vec1,
float *orco, float hasize, float vectsize, int seed)
{
HaloRen *har;
@@ -630,7 +947,7 @@ HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1,
if(hoco1[3]==0.0) return NULL;
}
- har= RE_findOrAddHalo(re, re->tothalo++);
+ har= RE_findOrAddHalo(obr, obr->tothalo++);
VECCOPY(har->co, vec);
har->hasize= hasize;
@@ -723,6 +1040,152 @@ HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1,
return har;
}
+HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, float *vec, float *vec1,
+ float *orco, float *uvco, float hasize, float vectsize, int seed)
+{
+ HaloRen *har;
+ MTex *mtex;
+ float tin, tr, tg, tb, ta;
+ float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3],tex[3],out[3];
+ int i;
+
+ if(hasize==0.0) return NULL;
+
+ projectverto(vec, re->winmat, hoco);
+ if(hoco[3]==0.0) return NULL;
+ if(vec1) {
+ projectverto(vec1, re->winmat, hoco1);
+ if(hoco1[3]==0.0) return NULL;
+ }
+
+ har= RE_findOrAddHalo(obr, obr->tothalo++);
+ VECCOPY(har->co, vec);
+ har->hasize= hasize;
+
+ /* actual projectvert is done in function project_renderdata() because of parts/border/pano */
+ /* we do it here for sorting of halos */
+ zn= hoco[3];
+ har->xs= 0.5*re->winx*(hoco[0]/zn);
+ har->ys= 0.5*re->winy*(hoco[1]/zn);
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ /* halovect */
+ if(vec1) {
+
+ har->type |= HA_VECT;
+
+ xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]);
+ yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]);
+ if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0;
+ else zn= atan2(yn, xn);
+
+ har->sin= sin(zn);
+ har->cos= cos(zn);
+ zn= VecLenf(vec1, vec)*0.5;
+
+ har->hasize= vectsize*zn + (1.0-vectsize)*hasize;
+
+ VecSubf(har->no, vec, vec1);
+ Normalize(har->no);
+ }
+
+ if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA;
+
+ har->alfa= ma->alpha;
+ har->r= ma->r;
+ har->g= ma->g;
+ har->b= ma->b;
+ har->add= (255.0*ma->add);
+ har->mat= ma;
+ har->hard= ma->har;
+ har->seed= seed % 256;
+
+ if(ma->mode & MA_STAR) har->starpoints= ma->starc;
+ if(ma->mode & MA_HALO_LINES) har->linec= ma->linec;
+ if(ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc;
+ if(ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec;
+
+ if((ma->mode & MA_HALOTEX) && ma->mtex[0]){
+ har->tex= 1;
+ i=1;
+ }
+
+ for(i=0; i<MAX_MTEX; i++)
+ if(ma->mtex[i] && (ma->septex & (1<<i))==0) {
+ mtex= ma->mtex[i];
+ VECCOPY(texvec, vec);
+
+ if(mtex->texco & TEXCO_NORM) {
+ ;
+ }
+ else if(mtex->texco & TEXCO_OBJECT) {
+ if(mtex->object){
+ float imat[4][4];
+ /* imat should really be cached somewhere before this */
+ Mat4Invert(imat,mtex->object->obmat);
+ Mat4MulVecfl(imat,texvec);
+ }
+ /* texvec[0]+= imatbase->ivec[0]; */
+ /* texvec[1]+= imatbase->ivec[1]; */
+ /* texvec[2]+= imatbase->ivec[2]; */
+ /* Mat3MulVecfl(imatbase->imat, texvec); */
+ }
+ else if(mtex->texco & TEXCO_GLOB){
+ VECCOPY(texvec,vec);
+ }
+ else if(mtex->texco & TEXCO_UV && uvco){
+ int uv_index=CustomData_get_named_layer_index(&dm->faceData,CD_MTFACE,mtex->uvname);
+ if(uv_index<0)
+ uv_index=CustomData_get_active_layer_index(&dm->faceData,CD_MTFACE);
+
+ uv_index-=CustomData_get_layer_index(&dm->faceData,CD_MTFACE);
+
+ texvec[0]=2.0f*uvco[2*uv_index]-1.0f;
+ texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
+ texvec[2]=0.0f;
+ }
+ else if(orco) {
+ VECCOPY(texvec, orco);
+ }
+
+ externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta);
+
+ //yn= tin*mtex->colfac;
+ //zn= tin*mtex->varfac;
+ if(mtex->mapto & MAP_COL) {
+ tex[0]=tr;
+ tex[1]=tg;
+ tex[2]=tb;
+ out[0]=har->r;
+ out[1]=har->g;
+ out[2]=har->b;
+
+ texture_rgb_blend(in,tex,out,tin,mtex->colfac,mtex->blendtype);
+ // zn= 1.0-yn;
+ //har->r= (yn*tr+ zn*ma->r);
+ //har->g= (yn*tg+ zn*ma->g);
+ //har->b= (yn*tb+ zn*ma->b);
+ har->r= in[0];
+ har->g= in[1];
+ 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);
+ 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);
+ 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);
+ /* now what on earth is this good for?? */
+ //if(mtex->texco & 16) {
+ // har->alfa= tin;
+ //}
+ }
+
+ return har;
+}
+
/* -------------------------- operations on entire database ----------------------- */
/* ugly function for halos in panorama */
@@ -759,180 +1222,183 @@ static int panotestclip(Render *re, int do_pano, float *v)
- shadow buffering (shadbuf.c)
*/
-void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs)
+void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets)
{
- VlakRen *vlr = NULL;
- VertRen *ver = NULL;
+ ObjectRen *obr;
HaloRen *har = NULL;
float zn, vec[3], hoco[4];
int a;
-
+
if(do_pano) {
float panophi= xoffs;
re->panosi= sin(panophi);
re->panoco= cos(panophi);
}
-
- /* calculate view coordinates (and zbuffer value) */
- for(a=0; a< re->totvert;a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(re, a);
- else ver++;
- if(do_pano) {
- vec[0]= re->panoco*ver->co[0] + re->panosi*ver->co[2];
- vec[1]= ver->co[1];
- vec[2]= -re->panosi*ver->co[0] + re->panoco*ver->co[2];
- }
- else {
- VECCOPY(vec, ver->co);
- }
- /* Go from wcs to hcs ... */
- projectfunc(vec, re->winmat, ver->ho);
- /* ... and clip in that system. */
- ver->clip = testclip(ver->ho);
- /*
- Because all other ops are performed in other systems, this is
- the only thing that has to be done.
- */
- }
-
- /* calculate view coordinates (and zbuffer value) */
- for(a=0; a<re->tothalo; a++) {
- if((a & 255)==0) har= re->bloha[a>>8];
- else har++;
-
- if(do_pano) {
- vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
- vec[1]= har->co[1];
- vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
- }
- else {
- VECCOPY(vec, har->co);
- }
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ /* calculate view coordinates (and zbuffer value) */
+ for(a=0; a<obr->tothalo; a++) {
+ if((a & 255)==0) har= obr->bloha[a>>8];
+ else har++;
- projectfunc(vec, re->winmat, hoco);
-
- /* we clip halos less critical, but not for the Z */
- hoco[0]*= 0.5;
- hoco[1]*= 0.5;
-
- if( panotestclip(re, do_pano, hoco) ) {
- har->miny= har->maxy= -10000; /* that way render clips it */
- }
- else if(hoco[3]<0.0) {
- har->miny= har->maxy= -10000; /* render clips it */
- }
- else /* do the projection...*/
- {
- /* bring back hocos */
- hoco[0]*= 2.0;
- hoco[1]*= 2.0;
+ if(do_pano) {
+ vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2];
+ vec[1]= har->co[1];
+ vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2];
+ }
+ else {
+ VECCOPY(vec, har->co);
+ }
+
+ projectfunc(vec, re->winmat, hoco);
- zn= hoco[3];
- har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
- har->ys= 0.5*re->winy*(1.0+hoco[1]/zn);
-
- /* this should be the zbuffer coordinate */
- har->zs= 0x7FFFFF*(hoco[2]/zn);
- /* taking this from the face clip functions? seems ok... */
- har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+ /* we clip halos less critical, but not for the Z */
+ hoco[0]*= 0.5;
+ hoco[1]*= 0.5;
- vec[0]+= har->hasize;
- projectfunc(vec, re->winmat, hoco);
- vec[0]-= har->hasize;
- zn= hoco[3];
- har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn));
-
- /* this clip is not really OK, to prevent stars to become too large */
- if(har->type & HA_ONLYSKY) {
- if(har->rad>3.0) har->rad= 3.0;
+ if( panotestclip(re, do_pano, hoco) ) {
+ har->miny= har->maxy= -10000; /* that way render clips it */
}
-
- har->radsq= har->rad*har->rad;
-
- har->miny= har->ys - har->rad/re->ycor;
- har->maxy= har->ys + har->rad/re->ycor;
-
- /* the Zd value is still not really correct for pano */
-
- vec[2]-= har->hasize; /* z negative, otherwise it's clipped */
- projectfunc(vec, re->winmat, hoco);
- zn= hoco[3];
- zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
- har->zd= CLAMPIS(zn, 0, INT_MAX);
-
+ else if(hoco[3]<0.0) {
+ har->miny= har->maxy= -10000; /* render clips it */
+ }
+ else /* do the projection...*/
+ {
+ /* bring back hocos */
+ hoco[0]*= 2.0;
+ hoco[1]*= 2.0;
+
+ zn= hoco[3];
+ har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/
+ har->ys= 0.5*re->winy*(1.0+hoco[1]/zn);
+
+ /* this should be the zbuffer coordinate */
+ har->zs= 0x7FFFFF*(hoco[2]/zn);
+ /* taking this from the face clip functions? seems ok... */
+ har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn);
+
+ vec[0]+= har->hasize;
+ projectfunc(vec, re->winmat, hoco);
+ vec[0]-= har->hasize;
+ zn= hoco[3];
+ har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn));
+
+ /* this clip is not really OK, to prevent stars to become too large */
+ if(har->type & HA_ONLYSKY) {
+ if(har->rad>3.0) har->rad= 3.0;
+ }
+
+ har->radsq= har->rad*har->rad;
+
+ har->miny= har->ys - har->rad/re->ycor;
+ har->maxy= har->ys + har->rad/re->ycor;
+
+ /* the Zd value is still not really correct for pano */
+
+ vec[2]-= har->hasize; /* z negative, otherwise it's clipped */
+ projectfunc(vec, re->winmat, hoco);
+ zn= hoco[3];
+ zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn));
+ har->zd= CLAMPIS(zn, 0, INT_MAX);
+
+ }
+
}
-
}
+}
- /* set flags at 0 if clipped away */
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
+/* ------------------------------------------------------------------------- */
- vlr->flag |= R_VISIBLE;
- if(vlr->v4) {
- if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE;
- }
- else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE;
+ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay)
+{
+ ObjectInstanceRen *obi;
+ float mat3[3][3];
+
+ obi= MEM_callocN(sizeof(ObjectInstanceRen), "ObjectInstanceRen");
+ obi->obr= obr;
+ obi->ob= ob;
+ obi->par= par;
+ obi->index= index;
+ obi->psysindex= psysindex;
+ obi->lay= lay;
+
+ if(mat) {
+ Mat4CpyMat4(obi->mat, mat);
+ Mat3CpyMat4(mat3, mat);
+ Mat3Inv(obi->nmat, mat3);
+ Mat3Transp(obi->nmat);
+ obi->flag |= R_DUPLI_TRANSFORMED;
+ }
- }
+ BLI_addtail(&re->instancetable, obi);
+ return obi;
}
-/* ------------------------------------------------------------------------- */
-
-void set_normalflags(Render *re)
+void RE_makeRenderInstances(Render *re)
{
- VlakRen *vlr = NULL;
- float *v1, xn, yn, zn;
- int a1, doflip;
-
- /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */
- for(a1=0; a1<re->totvlak; a1++) {
- if((a1 & 255)==0) vlr= re->vlaknodes[a1>>8].vlak;
- else vlr++;
-
- vlr->noflag= 0;
-
- /* abuse of this flag... this is code that just sets face normal in direction of camera */
- /* that convention we should get rid of */
- if((vlr->flag & R_NOPUNOFLIP)==0) {
-
- doflip= 0;
- if(re->r.mode & R_ORTHO) {
- if(vlr->n[2]>0.0) doflip= 1;
- }
- else {
- v1= vlr->v1->co;
- if( (v1[0]*vlr->n[0] +v1[1]*vlr->n[1] +v1[2]*vlr->n[2])<0.0 ) doflip= 1;
- }
- if(doflip) {
- vlr->n[0]= -vlr->n[0];
- vlr->n[1]= -vlr->n[1];
- vlr->n[2]= -vlr->n[2];
- vlr->noflag |= R_FLIPPED_NO;
- }
+ ObjectInstanceRen *obi, *oldobi;
+ ListBase newlist;
+ int tot;
+
+ /* convert list of object instances to an array for index based lookup */
+ tot= BLI_countlist(&re->instancetable);
+ re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
+ re->totinstance= tot;
+ newlist.first= newlist.last= NULL;
+
+ obi= re->objectinstance;
+ for(oldobi=re->instancetable.first; oldobi; oldobi=oldobi->next) {
+ *obi= *oldobi;
+
+ if(obi->obr) {
+ obi->prev= obi->next= NULL;
+ BLI_addtail(&newlist, obi);
+ obi++;
}
-
- /* recalculate puno. Displace & flipped matrices can screw up */
- vlr->puno= 0;
- if(!(vlr->flag & R_TANGENT)) {
- if( Inpf(vlr->n, vlr->v1->n) < 0.0 ) vlr->puno |= ME_FLIPV1;
- if( Inpf(vlr->n, vlr->v2->n) < 0.0 ) vlr->puno |= ME_FLIPV2;
- if( Inpf(vlr->n, vlr->v3->n) < 0.0 ) vlr->puno |= ME_FLIPV3;
- if(vlr->v4 && Inpf(vlr->n, vlr->v4->n) < 0.0 ) vlr->puno |= ME_FLIPV4;
- }
- xn= fabs(vlr->n[0]);
- yn= fabs(vlr->n[1]);
- zn= fabs(vlr->n[2]);
- if(zn>=xn && zn>=yn) vlr->noflag |= R_SNPROJ_X;
- else if(yn>=xn && yn>=zn) vlr->noflag |= R_SNPROJ_Y;
- else vlr->noflag |= R_SNPROJ_Z;
-
+ else
+ re->totinstance--;
}
+
+ BLI_freelistN(&re->instancetable);
+ re->instancetable= newlist;
}
+int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4])
+{
+ float mat[4][4], vec[4];
+ int a, fl, flag= -1;
+
+ Mat4CpyMat4(mat, winmat);
+
+ for(a=0; a<8; a++) {
+ vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
+ vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
+ vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
+ vec[3]= 1.0;
+ Mat4MulVec4fl(mat, vec);
+
+ fl= 0;
+ if(bounds) {
+ if(vec[0] > bounds[1]*vec[3]) fl |= 1;
+ if(vec[0]< bounds[0]*vec[3]) fl |= 2;
+ if(vec[1] > bounds[3]*vec[3]) fl |= 4;
+ if(vec[1]< bounds[2]*vec[3]) fl |= 8;
+ }
+ else {
+ if(vec[0] < -vec[3]) fl |= 1;
+ if(vec[0] > vec[3]) fl |= 2;
+ if(vec[1] < -vec[3]) fl |= 4;
+ if(vec[1] > vec[3]) fl |= 8;
+ }
+ if(vec[2] < -vec[3]) fl |= 16;
+ if(vec[2] > vec[3]) fl |= 32;
+
+ flag &= fl;
+ if(flag==0) return 0;
+ }
+ return flag;
+}
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 5e010080ac0..95c9311b8af 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -34,6 +34,7 @@
#include "DNA_material_types.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
@@ -42,6 +43,8 @@
#include "BLI_memarena.h"
#include "BLI_rand.h"
+#include "PIL_time.h"
+
#include "renderpipeline.h"
#include "render_types.h"
#include "renderdatabase.h"
@@ -138,10 +141,11 @@ static float *give_jitter_tab(int samp)
}
-static void make_jitter_weight_tab(ShadBuf *shb, short filtertype)
+static void make_jitter_weight_tab(Render *re, ShadBuf *shb, short filtertype)
{
float *jit, totw= 0.0f;
- int a, tot=shb->samp*shb->samp;
+ int samp= get_render_shadow_samples(&re->r, shb->samp);
+ int a, tot=samp*samp;
shb->weight= MEM_mallocN(sizeof(float)*tot, "weight tab lamp");
@@ -279,72 +283,86 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
/* sets start/end clipping. lar->shb should be initialized */
static void shadowbuf_autoclip(Render *re, LampRen *lar)
{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
VlakRen *vlr= NULL;
VertRen *ver= NULL;
Material *ma= NULL;
- float minz, maxz, vec[3], viewmat[4][4];
+ float minz, maxz, vec[3], viewmat[4][4], obviewmat[4][4];
unsigned int lay = -1;
- int a, ok= 1;
+ int i, a, maxtotvert, ok= 1;
+ char *clipflag;
minz= 1.0e30f; maxz= -1.0e30f;
Mat4CpyMat4(viewmat, lar->shb->viewmat);
if(lar->mode & LA_LAYER) lay= lar->lay;
-
- /* clear clip, is being set if face is visible (clip is calculated for real later) */
- for(a=0; a<re->totvert; a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(re, a);
- else ver++;
-
- ver->clip= 0;
- }
-
+
+ maxtotvert= 0;
+ for(obr=re->objecttable.first; obr; obr=obr->next)
+ maxtotvert= MAX2(obr->totvert, maxtotvert);
+
+ clipflag= MEM_callocN(sizeof(char)*maxtotvert, "autoclipflag");
+
/* set clip in vertices when face visible */
- for(a=0; a<re->totvlak; a++) {
-
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
-
- /* note; these conditions are copied from zbuffer_shadow() */
- if(vlr->mat!= ma) {
- ma= vlr->mat;
- ok= 1;
- if((ma->mode & MA_SHADBUF)==0) ok= 0;
- }
-
- if(ok && (vlr->lay & lay)) {
- vlr->v1->clip= 1;
- vlr->v2->clip= 1;
- vlr->v3->clip= 1;
- if(vlr->v4) vlr->v4->clip= 1;
- }
- }
-
- /* calculate min and max */
- for(a=0; a< re->totvert;a++) {
- if((a & 255)==0) ver= RE_findOrAddVert(re, a);
- else ver++;
+ for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(obviewmat, obi->mat, viewmat);
+ else
+ Mat4CpyMat4(obviewmat, viewmat);
+
+ memset(clipflag, 0, sizeof(char)*obr->totvert);
+
+ /* clear clip, is being set if face is visible (clip is calculated for real later) */
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ /* note; these conditions are copied from zbuffer_shadow() */
+ if(vlr->mat!= ma) {
+ ma= vlr->mat;
+ ok= 1;
+ if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ }
+
+ if(ok && (obi->lay & lay)) {
+ clipflag[vlr->v1->index]= 1;
+ clipflag[vlr->v2->index]= 1;
+ clipflag[vlr->v3->index]= 1;
+ if(vlr->v4) clipflag[vlr->v4->index]= 1;
+ }
+ }
- if(ver->clip) {
- VECCOPY(vec, ver->co);
- Mat4MulVecfl(viewmat, vec);
- /* Z on visible side of lamp space */
- if(vec[2] < 0.0f) {
- float inpr, z= -vec[2];
-
- /* since vec is rotated in lampspace, this is how to get the cosine of angle */
- /* precision is set 20% larger */
- vec[2]*= 1.2f;
- Normalize(vec);
- inpr= - vec[2];
-
- if(inpr>=lar->spotsi) {
- if(z<minz) minz= z;
- if(z>maxz) maxz= z;
+ /* calculate min and max */
+ for(a=0; a< obr->totvert;a++) {
+ if((a & 255)==0) ver= RE_findOrAddVert(obr, a);
+ else ver++;
+
+ if(clipflag[a]) {
+ VECCOPY(vec, ver->co);
+ Mat4MulVecfl(obviewmat, vec);
+ /* Z on visible side of lamp space */
+ if(vec[2] < 0.0f) {
+ float inpr, z= -vec[2];
+
+ /* since vec is rotated in lampspace, this is how to get the cosine of angle */
+ /* precision is set 20% larger */
+ vec[2]*= 1.2f;
+ Normalize(vec);
+ inpr= - vec[2];
+
+ if(inpr>=lar->spotsi) {
+ if(z<minz) minz= z;
+ if(z>maxz) maxz= z;
+ }
}
}
}
}
+
+ MEM_freeN(clipflag);
/* set clipping min and max */
if(minz < maxz) {
@@ -369,9 +387,6 @@ void makeshadowbuf(Render *re, LampRen *lar)
float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp;
int *rectz, samples;
- /* XXXX EVIL! this global is used in clippyra(), zbuf.c */
- R.clipcrop= 1.0f;
-
if(lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END))
shadowbuf_autoclip(re, lar);
@@ -391,38 +406,132 @@ void makeshadowbuf(Render *re, LampRen *lar)
MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat);
if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) {
- /* jitter, weights */
- shb->jit= give_jitter_tab(shb->samp);
- make_jitter_weight_tab(shb, lar->filtertype);
+ /* jitter, weights - not threadsafe! */
+ BLI_lock_thread(LOCK_CUSTOM1);
+ shb->jit= give_jitter_tab(get_render_shadow_samples(&re->r, shb->samp));
+ make_jitter_weight_tab(re, shb, lar->filtertype);
+ BLI_unlock_thread(LOCK_CUSTOM1);
shb->totbuf= lar->buffers;
if(shb->totbuf==4) jitbuf= give_jitter_tab(2);
else if(shb->totbuf==9) jitbuf= give_jitter_tab(3);
else jitbuf= twozero;
- /* temp, will be restored */
- MTC_Mat4SwapMat4(shb->persmat, re->winmat);
-
- project_renderdata(re, projectvert, 0, 0);
-
/* zbuffering */
rectz= MEM_mapallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf");
for(samples=0; samples<shb->totbuf; samples++) {
- zbuffer_shadow(re, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
+ zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]);
/* create Z tiles (for compression): this system is 24 bits!!! */
compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE);
+
+ if(re->test_break())
+ break;
}
MEM_freeN(rectz);
-
- /* old matrix back */
- MTC_Mat4SwapMat4(shb->persmat, re->winmat);
/* printf("lampbuf %d\n", sizeoflampbuf(shb)); */
}
}
+static void *do_shadow_thread(void *re_v)
+{
+ Render *re= (Render*)re_v;
+ LampRen *lar;
+
+ do {
+ BLI_lock_thread(LOCK_CUSTOM1);
+ for(lar=re->lampren.first; lar; lar=lar->next) {
+ if(lar->shb && !lar->thread_assigned) {
+ lar->thread_assigned= 1;
+ break;
+ }
+ }
+ BLI_unlock_thread(LOCK_CUSTOM1);
+
+ /* if type is irregular, this only sets the perspective matrix and autoclips */
+ if(lar) {
+ makeshadowbuf(re, lar);
+ BLI_lock_thread(LOCK_CUSTOM1);
+ lar->thread_ready= 1;
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ }
+ } while(lar && !re->test_break());
+
+ return NULL;
+}
+
+static volatile int g_break= 0;
+static int thread_break(void)
+{
+ return g_break;
+}
+
+void threaded_makeshadowbufs(Render *re)
+{
+ ListBase threads;
+ LampRen *lar;
+ int a, totthread= 0;
+ int (*test_break)(void);
+
+ /* count number of threads to use */
+ if(G.rendering) {
+ for(lar=re->lampren.first; lar; lar= lar->next)
+ if(lar->shb)
+ totthread++;
+
+ totthread= MIN2(totthread, re->r.threads);
+ }
+ else
+ totthread= 1; /* preview render */
+
+ if(totthread <= 1) {
+ for(lar=re->lampren.first; lar; lar= lar->next) {
+ if(re->test_break()) break;
+ if(lar->shb) {
+ /* if type is irregular, this only sets the perspective matrix and autoclips */
+ makeshadowbuf(re, lar);
+ }
+ }
+ }
+ else {
+ /* swap test break function */
+ test_break= re->test_break;
+ re->test_break= thread_break;
+
+ for(lar=re->lampren.first; lar; lar= lar->next) {
+ lar->thread_assigned= 0;
+ lar->thread_ready= 0;
+ }
+
+ BLI_init_threads(&threads, do_shadow_thread, totthread);
+
+ for(a=0; a<totthread; a++)
+ BLI_insert_thread(&threads, re);
+
+ /* keep rendering as long as there are shadow buffers not ready */
+ do {
+ if((g_break=test_break()))
+ break;
+
+ PIL_sleep_ms(50);
+
+ BLI_lock_thread(LOCK_CUSTOM1);
+ for(lar=re->lampren.first; lar; lar= lar->next)
+ if(lar->shb && !lar->thread_ready)
+ break;
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ } while(lar);
+
+ BLI_end_threads(&threads);
+
+ /* unset threadsafety */
+ re->test_break= test_break;
+ g_break= 0;
+ }
+}
+
void freeshadowbuf(LampRen *lar)
{
if(lar->shb) {
@@ -545,11 +654,11 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int
/* the externally called shadow testing (reading) function */
/* return 1.0: no shadow at all */
-float testshadowbuf(ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp)
+float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp, float mat_bias)
{
ShadSampleBuf *shsample;
float fac, co[4], dx[3], dy[3], shadfac=0.0f;
- float xs1,ys1, siz, *jit, *weight, xres, yres;
+ float xs1,ys1, siz, *jit, *weight, xres, yres, biasf;
int xs, ys, zs, bias, *rz;
short a, num;
@@ -583,13 +692,16 @@ float testshadowbuf(ShadBuf *shb, float *rco, float *dxco, float *dyco, float in
zs= ((float)0x7FFFFFFF)*fac;
/* take num*num samples, increase area with fac */
- num= shb->samp*shb->samp;
+ num= get_render_shadow_samples(&re->r, shb->samp);
+ num= num*num;
fac= shb->soft;
+ if(mat_bias!=0.0f) biasf= shb->bias*mat_bias;
+ else biasf= shb->bias;
/* with inp==1.0, bias is half the size. correction value was 1.1, giving errors
on cube edges, with one side being almost frontal lighted (ton) */
- bias= (1.5f-inp*inp)*shb->bias;
-
+ bias= (1.5f-inp*inp)*biasf;
+
if(num==1) {
for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
@@ -884,6 +996,7 @@ typedef struct ISBBranch {
typedef struct BSPFace {
Boxf box;
float *v1, *v2, *v3, *v4;
+ int obi; /* object for face lookup */
int facenr; /* index to retrieve VlakRen */
int type; /* only for strand now */
short shad_alpha, is_full;
@@ -1063,7 +1176,7 @@ static int isb_bsp_insert(ISBBranch *root, MemArena *memarena, ISBSample *sample
/* insert */
bspn->samples[bspn->totsamp]= sample;
bspn->totsamp++;
-
+
/* split if allowed and needed */
if(bspn->totsamp==BSPMAX_SAMPLE) {
if(i==BSPMAX_DEPTH) {
@@ -1262,7 +1375,7 @@ static void isb_bsp_face_inside(ISBBranch *bspn, BSPFace *face)
for(a=bspn->totsamp-1; a>=0; a--) {
ISBSample *samp= bspn->samples[a];
- if(samp->facenr!=face->facenr && samp->shadfac) {
+ if((samp->facenr!=face->facenr || samp->obi!=face->obi) && samp->shadfac) {
if(face->box.zmin < samp->zco[2]) {
if(BLI_in_rctf((rctf *)&face->box, samp->zco[0], samp->zco[1])) {
int inshadow= 0;
@@ -1308,7 +1421,7 @@ static void isb_bsp_recalc_box(ISBBranch *root)
}
/* callback function for zbuf clip */
-static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void isb_bsp_test_strand(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
BSPFace face;
@@ -1316,6 +1429,7 @@ static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, f
face.v2= v2;
face.v3= v3;
face.v4= v4;
+ face.obi= obi;
face.facenr= zvlnr & ~RE_QUAD_OFFS;
face.type= R_STRAND;
if(R.osa)
@@ -1341,7 +1455,7 @@ static void isb_bsp_test_strand(ZSpan *zspan, int zvlnr, float *v1, float *v2, f
}
/* callback function for zbuf clip */
-static void isb_bsp_test_face(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void isb_bsp_test_face(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
BSPFace face;
@@ -1349,6 +1463,7 @@ static void isb_bsp_test_face(ZSpan *zspan, int zvlnr, float *v1, float *v2, flo
face.v2= v2;
face.v3= v3;
face.v4= v4;
+ face.obi= obi;
face.facenr= zvlnr & ~RE_QUAD_OFFS;
face.type= 0;
if(R.osa)
@@ -1386,13 +1501,15 @@ static int testclip_minmax(float *ho, float *minmax)
/* main loop going over all faces and check in bsp overlaps, fill in shadfac values */
static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
ShadBuf *shb= lar->shb;
ZSpan zspan, zspanstrand;
VlakRen *vlr= NULL;
Material *ma= NULL;
- float minmaxf[4];
+ float minmaxf[4], winmat[4][4];
int size= shb->size;
- int a, ok=1, lay= -1;
+ int i, a, ok=1, lay= -1;
/* further optimize, also sets minz maxz */
isb_bsp_recalc_box(root);
@@ -1406,7 +1523,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
if(lar->mode & LA_LAYER) lay= lar->lay;
/* (ab)use zspan, since we use zbuffer clipping code */
- zbuf_alloc_span(&zspan, size, size);
+ zbuf_alloc_span(&zspan, size, size, re->clipcrop);
zspan.zmulx= ((float)size)/2.0f;
zspan.zmuly= ((float)size)/2.0f;
@@ -1422,74 +1539,90 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
zspan.zbuffunc= isb_bsp_test_face;
zspanstrand.zbuffunc= isb_bsp_test_strand;
- for(a=0; a<re->totvlak; a++) {
-
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
-
- /* note, these conditions are copied in shadowbuf_autoclip() */
- if(vlr->mat!= ma) {
- ma= vlr->mat;
- ok= 1;
- if((ma->mode & MA_SHADBUF)==0) ok= 0;
- if(ma->mode & MA_WIRE) ok= 0;
- zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
- }
-
- if(ok && (vlr->lay & lay)) {
- float hoco[4][4];
- int c1, c2, c3, c4=0;
- int d1, d2, d3, d4=0;
- int partclip;
+ for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, shb->persmat);
+ else
+ Mat4CpyMat4(winmat, shb->persmat);
+
+ for(a=0; a<obr->totvlak; a++) {
- /* create hocos per face, it is while render */
- projectvert(vlr->v1->co, shb->persmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
- projectvert(vlr->v2->co, shb->persmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
- projectvert(vlr->v3->co, shb->persmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
- if(vlr->v4) {
- projectvert(vlr->v4->co, shb->persmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
- }
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
- /* minmax clipping */
- if(vlr->v4) partclip= d1 & d2 & d3 & d4;
- else partclip= d1 & d2 & d3;
+ /* note, these conditions are copied in shadowbuf_autoclip() */
+ if(vlr->mat!= ma) {
+ ma= vlr->mat;
+ ok= 1;
+ if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if(ma->mode & MA_WIRE) ok= 0;
+ zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
+ }
- if(partclip==0) {
+ if(ok && (obi->lay & lay)) {
+ float hoco[4][4];
+ int c1, c2, c3, c4=0;
+ int d1, d2, d3, d4=0;
+ int partclip;
- /* window clipping */
- c1= testclip(hoco[0]);
- c2= testclip(hoco[1]);
- c3= testclip(hoco[2]);
- if(vlr->v4)
- c4= testclip(hoco[3]);
+ /* create hocos per face, it is while render */
+ projectvert(vlr->v1->co, winmat, hoco[0]); d1= testclip_minmax(hoco[0], minmaxf);
+ projectvert(vlr->v2->co, winmat, hoco[1]); d2= testclip_minmax(hoco[1], minmaxf);
+ projectvert(vlr->v3->co, winmat, hoco[2]); d3= testclip_minmax(hoco[2], minmaxf);
+ if(vlr->v4) {
+ projectvert(vlr->v4->co, winmat, hoco[3]); d4= testclip_minmax(hoco[3], minmaxf);
+ }
+
+ /* minmax clipping */
+ if(vlr->v4) partclip= d1 & d2 & d3 & d4;
+ else partclip= d1 & d2 & d3;
- /* ***** NO WIRE YET */
- if(ma->mode & MA_WIRE)
- zbufclipwire(&zspan, a+1, vlr);
- else if(vlr->v4) {
- if(vlr->flag & R_STRAND)
- zbufclip4(&zspanstrand, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ if(partclip==0) {
+
+ /* window clipping */
+ c1= testclip(hoco[0]);
+ c2= testclip(hoco[1]);
+ c3= testclip(hoco[2]);
+ if(vlr->v4)
+ c4= testclip(hoco[3]);
+
+ /* ***** NO WIRE YET */
+ if(ma->mode & MA_WIRE) {
+ if(vlr->v4)
+ zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclipwire(&zspan, i, a+1, vlr->ec, hoco[0], hoco[1], hoco[2], 0, c1, c2, c3, 0);
+ }
+ else if(vlr->v4) {
+ if(vlr->flag & R_STRAND)
+ zbufclip4(&zspanstrand, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclip4(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ }
else
- zbufclip4(&zspan, a+1, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ zbufclip(&zspan, i, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
+
}
- else
- zbufclip(&zspan, a+1, hoco[0], hoco[1], hoco[2], c1, c2, c3);
-
}
}
}
zbuf_free_span(&zspan);
-
}
-
/* returns 1 when the viewpixel is visible in lampbuffer */
-static int viewpixel_to_lampbuf(ShadBuf *shb, VlakRen *vlr, float x, float y, float *co)
+static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *vlr, float x, float y, float *co)
{
- float hoco[4], *v1= vlr->v1->co, *nor= vlr->n;
+ float hoco[4], v1[3], nor[3];
float dface, fac, siz;
+ RE_vlakren_get_normal(&R, obi, vlr, nor);
+ VECCOPY(v1, vlr->v1->co);
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(obi->mat, v1);
+
/* from shadepixel() */
dface= v1[0]*nor[0] + v1[1]*nor[1] + v1[2]*nor[2];
hoco[3]= 1.0f;
@@ -1550,7 +1683,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, VlakRen *vlr, float x, float y, fl
}
/* storage of shadow results, solid osa and transp case */
-static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int facenr, short shadfac, short samples)
+static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int obi, int facenr, short shadfac, short samples)
{
ISBShadfacA *new;
float shadfacf;
@@ -1562,6 +1695,7 @@ static void isb_add_shadfac(ISBShadfacA **isbsapp, MemArena *mem, int facenr, sh
shadfacf= ((float)shadfac)/(4096.0);
new= BLI_memarena_alloc(mem, sizeof(ISBShadfacA));
+ new->obi= obi;
new->facenr= facenr & ~RE_QUAD_OFFS;
new->shadfac= shadfacf;
if(*isbsapp)
@@ -1619,7 +1753,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
ISBBranch root;
MemArena *memarena;
long *rd;
- int *rectp, x, y, sindex, sample, bsp_err=0;
+ int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
/* storage for shadow, per thread */
isbdata= shb->isb_result[pa->thread];
@@ -1669,11 +1803,14 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
ps= ps->next;
}
if(ps && ps->facenr>0) {
- VlakRen *vlr= RE_findOrAddVlak(&R, (ps->facenr-1) & RE_QUAD_MASK);
+ ObjectInstanceRen *obi= &R.objectinstance[ps->obi];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
samp= samplebuf[sample] + sindex;
/* convert image plane pixel location to lamp buffer space */
- if(viewpixel_to_lampbuf(shb, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
+ if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], samp->zco)) {
+ samp->obi= ps->obi;
samp->facenr= ps->facenr & ~RE_QUAD_OFFS;
ps->shadfac= 0;
samp->shadfac= &ps->shadfac;
@@ -1685,14 +1822,18 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
}
else {
rectp= pa->rectp + sindex;
+ recto= pa->recto + sindex;
if(*rectp>0) {
- VlakRen *vlr= RE_findOrAddVlak(&R, (*rectp-1) & RE_QUAD_MASK);
+ ObjectInstanceRen *obi= &R.objectinstance[*recto];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (*rectp-1) & RE_QUAD_MASK);
float xs= (float)(x + pa->disprect.xmin);
float ys= (float)(y + pa->disprect.ymin);
samp= samplebuf[0] + sindex;
/* convert image plane pixel location to lamp buffer space */
- if(viewpixel_to_lampbuf(shb, vlr, xs, ys, samp->zco)) {
+ if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, samp->zco)) {
+ samp->obi= *recto;
samp->facenr= *rectp & ~RE_QUAD_OFFS;
samp->shadfac= isbdata->shadfacs + sindex;
bound_rectf((rctf *)&root.box, samp->zco);
@@ -1729,7 +1870,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
PixStr *ps= (PixStr *)(*rd);
while(ps) {
if(ps->shadfac)
- isb_add_shadfac(isbsa, isbdata->memarena, ps->facenr, ps->shadfac, count_mask(ps->mask));
+ isb_add_shadfac(isbsa, isbdata->memarena, ps->obi, ps->facenr, ps->shadfac, count_mask(ps->mask));
ps= ps->next;
}
}
@@ -1857,7 +1998,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
int a;
for(a=0; a<4; a++) {
if(apn->p[a]) {
- VlakRen *vlr= RE_findOrAddVlak(&R, (apn->p[a]-1) & RE_QUAD_MASK);
+ ObjectInstanceRen *obi= &R.objectinstance[apn->obi[a]];
+ ObjectRen *obr= obi->obr;
+ VlakRen *vlr= RE_findOrAddVlak(obr, (apn->p[a]-1) & RE_QUAD_MASK);
float zco[3];
/* here we store shadfac, easier to create the end storage buffer. needs zero'ed, multiple shadowbufs use it */
@@ -1870,8 +2013,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
if(apn->mask[a] & mask) {
/* convert image plane pixel location to lamp buffer space */
- if(viewpixel_to_lampbuf(shb, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
+ if(viewpixel_to_lampbuf(shb, obi, vlr, xs + R.jit[sample][0], ys + R.jit[sample][1], zco)) {
samp= isb_alloc_sample_transp(samplebuf[sample] + sindex, memarena);
+ samp->obi= apn->obi[a];
samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
samp->shadfac= &apn->shadfac[a];
@@ -1884,9 +2028,10 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
else {
/* convert image plane pixel location to lamp buffer space */
- if(viewpixel_to_lampbuf(shb, vlr, xs, ys, zco)) {
+ if(viewpixel_to_lampbuf(shb, obi, vlr, xs, ys, zco)) {
samp= isb_alloc_sample_transp(samplebuf[0] + sindex, memarena);
+ samp->obi= apn->obi[a];
samp->facenr= apn->p[a] & ~RE_QUAD_OFFS;
samp->shadfac= &apn->shadfac[a];
@@ -1930,9 +2075,9 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la
for(a=0; a<4; a++) {
if(apn->p[a] && apn->shadfac[a]) {
if(R.osa)
- isb_add_shadfac(isbsa, isbdata->memarena, apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
+ isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], count_mask(apn->mask[a]));
else
- isb_add_shadfac(isbsa, isbdata->memarena, apn->p[a], apn->shadfac[a], 0);
+ isb_add_shadfac(isbsa, isbdata->memarena, apn->obi[a], apn->p[a], apn->shadfac[a], 0);
}
}
}
@@ -1977,10 +2122,11 @@ float ISB_getshadow(ShadeInput *shi, ShadBuf *shb)
}
else {
int sindex= y*isbdata->rectx + x;
+ int obi= shi->obi - R.objectinstance;
ISBShadfacA *isbsa= *(isbdata->shadfaca + sindex);
while(isbsa) {
- if(isbsa->facenr==shi->facenr+1)
+ if(isbsa->facenr==shi->facenr+1 && isbsa->obi==obi)
return isbsa->shadfac>=1.0f?0.0f:1.0f - isbsa->shadfac;
isbsa= isbsa->next;
}
@@ -2044,7 +2190,3 @@ void ISB_free(RenderPart *pa)
}
}
-
-
-
-
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index ca661469b36..bedce5e36ee 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -31,6 +31,7 @@
#include "MTC_matrixops.h"
#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
@@ -48,7 +49,9 @@
#include "rendercore.h"
#include "shadbuf.h"
#include "shading.h"
+#include "strand.h"
#include "texture.h"
+#include "zbuf.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@@ -121,14 +124,13 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr)
if(shi->depth==0) {
if(R.r.mode & R_RAYTRACE) {
if(shi->ray_mirror!=0.0f || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0f)) {
-
/* ray trace works on combined, but gives pass info */
ray_trace(shi, shr);
}
}
/* disable adding of sky for raytransp */
if(shi->mat->mode & MA_RAYTRANSP)
- if(shi->layflag & SCE_LAY_SKY)
+ if((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode==R_ADDSKY))
shr->alpha= 1.0f;
}
}
@@ -160,11 +162,16 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
}
/* MIST */
- if((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST)==0 ) {
+ if((shi->passflag & SCE_PASS_MIST) || ((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST)==0)) {
if(R.r.mode & R_ORTHO)
- alpha= mistfactor(-shi->co[2], shi->co);
+ shr->mist= mistfactor(-shi->co[2], shi->co);
else
- alpha= mistfactor(VecLength(shi->co), shi->co);
+ shr->mist= mistfactor(VecLength(shi->co), shi->co);
+ }
+ else shr->mist= 0.0f;
+
+ if((R.wrld.mode & WO_MIST) && (shi->mat->mode & MA_NOMIST)==0 ) {
+ alpha= shr->mist;
}
else alpha= 1.0f;
@@ -179,6 +186,8 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
}
else shr->combined[3]= 1.0f;
+ /* add z */
+ shr->z= -shi->co[2];
}
/* **************************************************************************** */
@@ -208,15 +217,16 @@ void vlr_set_uv_indices(VlakRen *vlr, int *i1, int *i2, int *i3)
}
}
-
/* copy data from face to ShadeInput, general case */
-/* indices 0 1 2 3 only. shi->puno should be set! */
-void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i2, short i3)
+/* indices 0 1 2 3 only */
+void shade_input_set_triangle_i(ShadeInput *shi, ObjectInstanceRen *obi, VlakRen *vlr, short i1, short i2, short i3)
{
VertRen **vpp= &vlr->v1;
shi->vlr= vlr;
-
+ shi->obi= obi;
+ shi->obr= obi->obr;
+
shi->v1= vpp[i1];
shi->v2= vpp[i2];
shi->v3= vpp[i3];
@@ -230,40 +240,45 @@ void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i
shi->osatex= (shi->mat->texco & TEXCO_OSA);
shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */
+
+ /* facenormal copy, can get flipped */
+ shi->flippednor= RE_vlakren_get_normal(&R, obi, vlr, shi->facenor);
+
+ /* copy of original pre-flipped normal, for geometry->front/back node output */
+ VECCOPY(shi->orignor, shi->facenor);
+ if(shi->flippednor)
+ VECMUL(shi->orignor, -1.0f);
/* calculate vertexnormals */
if(vlr->flag & R_SMOOTH) {
- float *n1= shi->v1->n, *n2= shi->v2->n, *n3= shi->v3->n;
- char p1, p2, p3;
-
- p1= 1<<i1;
- p2= 1<<i2;
- p3= 1<<i3;
-
- if(shi->puno & p1) {
- shi->n1[0]= -n1[0]; shi->n1[1]= -n1[1]; shi->n1[2]= -n1[2];
- } else {
- VECCOPY(shi->n1, n1);
- }
- if(shi->puno & p2) {
- shi->n2[0]= -n2[0]; shi->n2[1]= -n2[1]; shi->n2[2]= -n2[2];
- } else {
- VECCOPY(shi->n2, n2);
+ VECCOPY(shi->n1, shi->v1->n);
+ VECCOPY(shi->n2, shi->v2->n);
+ VECCOPY(shi->n3, shi->v3->n);
+
+ if(obi->flag & R_TRANSFORMED) {
+ Mat3MulVecfl(obi->nmat, shi->n1);
+ Mat3MulVecfl(obi->nmat, shi->n2);
+ Mat3MulVecfl(obi->nmat, shi->n3);
}
- if(shi->puno & p3) {
- shi->n3[0]= -n3[0]; shi->n3[1]= -n3[1]; shi->n3[2]= -n3[2];
- } else {
- VECCOPY(shi->n3, n3);
+
+ if(!(vlr->flag & (R_NOPUNOFLIP|R_TANGENT))) {
+ if(INPR(shi->facenor, shi->n1) < 0.0f) {
+ shi->n1[0]= -shi->n1[0];
+ shi->n1[1]= -shi->n1[1];
+ shi->n1[2]= -shi->n1[2];
+ }
+ if(INPR(shi->facenor, shi->n2) < 0.0f) {
+ shi->n2[0]= -shi->n2[0];
+ shi->n2[1]= -shi->n2[1];
+ shi->n2[2]= -shi->n2[2];
+ }
+ if(INPR(shi->facenor, shi->n3) < 0.0f) {
+ shi->n3[0]= -shi->n3[0];
+ shi->n3[1]= -shi->n3[1];
+ shi->n3[2]= -shi->n3[2];
+ }
}
}
- /* facenormal copy, can get flipped */
- VECCOPY(shi->facenor, vlr->n);
-
- /* copy of original pre-flipped normal, for geometry->front/back node output */
- VECCOPY(shi->orignor, vlr->n);
- if (vlr->noflag & R_FLIPPED_NO) {
- VECMUL(shi->orignor, -1.0f);
- }
}
/* note, facenr declared volatile due to over-eager -O2 optimizations
@@ -271,26 +286,25 @@ void shade_input_set_triangle_i(ShadeInput *shi, VlakRen *vlr, short i1, short i
*/
/* copy data from face to ShadeInput, scanline case */
-void shade_input_set_triangle(ShadeInput *shi, volatile int facenr, int normal_flip)
+void shade_input_set_triangle(ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip)
{
if(facenr>0) {
+ shi->obi= &R.objectinstance[obi];
+ shi->obr= shi->obi->obr;
shi->facenr= (facenr-1) & RE_QUAD_MASK;
- if( shi->facenr < R.totvlak ) {
- VlakRen *vlr= RE_findOrAddVlak(&R, shi->facenr);
-
- shi->puno= normal_flip?vlr->puno:0;
+ if( shi->facenr < shi->obr->totvlak ) {
+ VlakRen *vlr= RE_findOrAddVlak(shi->obr, shi->facenr);
if(facenr & RE_QUAD_OFFS)
- shade_input_set_triangle_i(shi, vlr, 0, 2, 3);
+ shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 2, 3);
else
- shade_input_set_triangle_i(shi, vlr, 0, 1, 2);
+ shade_input_set_triangle_i(shi, shi->obi, vlr, 0, 1, 2);
}
else
shi->vlr= NULL; /* general signal we got sky */
}
else
shi->vlr= NULL; /* general signal we got sky */
-
}
/* full osa case: copy static info */
@@ -300,6 +314,253 @@ void shade_input_copy_triangle(ShadeInput *shi, ShadeInput *from)
memcpy(shi, from, sizeof(struct ShadeInputCopy));
}
+/* copy data from strand to shadeinput */
+void shade_input_set_strand(ShadeInput *shi, StrandRen *strand, StrandPoint *spoint)
+{
+ /* note, shi->mat is set in node shaders */
+ shi->mat= shi->mat_override? shi->mat_override: strand->buffer->ma;
+
+ shi->osatex= (shi->mat->texco & TEXCO_OSA);
+ shi->mode= shi->mat->mode_l; /* or-ed result for all nodes */
+
+ /* shade_input_set_viewco equivalent */
+ VECCOPY(shi->co, spoint->co);
+ VECCOPY(shi->view, shi->co);
+ Normalize(shi->view);
+
+ shi->xs= (int)spoint->x;
+ shi->ys= (int)spoint->y;
+
+ if(shi->osatex || (R.r.mode & R_SHADOW)) {
+ VECCOPY(shi->dxco, spoint->dtco);
+ VECCOPY(shi->dyco, spoint->dsco);
+ }
+
+ /* dxview, dyview, not supported */
+
+ /* facenormal, simply viewco flipped */
+ VECCOPY(shi->facenor, spoint->nor);
+ VECCOPY(shi->orignor, shi->facenor);
+
+ /* shade_input_set_normals equivalent */
+ if(shi->mat->mode & MA_TANGENT_STR)
+ VECCOPY(shi->vn, spoint->tan)
+ else
+ VECCOPY(shi->vn, spoint->nor)
+
+ VECCOPY(shi->vno, shi->vn);
+}
+
+void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert *svert, StrandPoint *spoint)
+{
+ StrandBuffer *strandbuf= strand->buffer;
+ ObjectRen *obr= strandbuf->obr;
+ StrandVert *sv;
+ int mode= shi->mode; /* or-ed result for all nodes */
+ short texco= shi->mat->texco;
+
+ if((shi->mat->texco & TEXCO_REFL)) {
+ /* shi->dxview, shi->dyview, not supported */
+ }
+
+ if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL))) {
+ /* not supported */
+ }
+
+ if(mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
+ VECCOPY(shi->tang, spoint->tan);
+ VECCOPY(shi->nmaptang, spoint->tan);
+ }
+
+ if(mode & MA_STR_SURFDIFF) {
+ float *surfnor= RE_strandren_get_surfnor(obr, strand, 0);
+
+ if(surfnor)
+ VECCOPY(shi->surfnor, surfnor)
+ else
+ VECCOPY(shi->surfnor, shi->vn)
+
+ if(shi->mat->strand_surfnor > 0.0f) {
+ shi->surfdist= 0.0f;
+ for(sv=strand->vert; sv!=svert; sv++)
+ shi->surfdist+=VecLenf(sv->co, (sv+1)->co);
+ shi->surfdist += spoint->t*VecLenf(sv->co, (sv+1)->co);
+ }
+ }
+
+ if(R.r.mode & R_SPEED) {
+ float *speed;
+
+ speed= RE_strandren_get_winspeed(shi->obi, strand, 0);
+ if(speed)
+ QUATCOPY(shi->winspeed, speed)
+ else
+ shi->winspeed[0]= shi->winspeed[1]= shi->winspeed[2]= shi->winspeed[3]= 0.0f;
+ }
+
+ /* shade_input_set_shade_texco equivalent */
+ if(texco & NEED_UV) {
+ if(texco & TEXCO_ORCO) {
+ VECCOPY(shi->lo, strand->orco);
+ /* no shi->osatex, orco derivatives are zero */
+ }
+
+ if(texco & TEXCO_GLOB) {
+ VECCOPY(shi->gl, shi->co);
+ MTC_Mat4MulVecfl(R.viewinv, shi->gl);
+
+ if(shi->osatex) {
+ VECCOPY(shi->dxgl, shi->dxco);
+ MTC_Mat3MulVecfl(R.imat, shi->dxco);
+ VECCOPY(shi->dygl, shi->dyco);
+ MTC_Mat3MulVecfl(R.imat, shi->dyco);
+ }
+ }
+
+ if(texco & TEXCO_STRAND) {
+ shi->strandco= spoint->strandco;
+
+ if(shi->osatex) {
+ shi->dxstrand= spoint->dtstrandco;
+ shi->dystrand= 0.0f;
+ }
+ }
+
+ if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE))) {
+ MCol *mcol;
+ float *uv;
+ char *name;
+ int i;
+
+ shi->totuv= 0;
+ shi->totcol= 0;
+
+ if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
+ for (i=0; (mcol=RE_strandren_get_mcol(obr, strand, i, &name, 0)); i++) {
+ ShadeInputCol *scol= &shi->col[i];
+ char *cp= (char*)mcol;
+
+ shi->totcol++;
+ scol->name= name;
+
+ scol->col[0]= cp[3]/255.0f;
+ scol->col[1]= cp[2]/255.0f;
+ scol->col[2]= cp[1]/255.0f;
+ }
+
+ if(shi->totcol) {
+ shi->vcol[0]= shi->col[0].col[0];
+ shi->vcol[1]= shi->col[0].col[1];
+ shi->vcol[2]= shi->col[0].col[2];
+ }
+ else {
+ shi->vcol[0]= 0.0f;
+ shi->vcol[1]= 0.0f;
+ shi->vcol[2]= 0.0f;
+ }
+ }
+
+ for (i=0; (uv=RE_strandren_get_uv(obr, strand, i, &name, 0)); i++) {
+ ShadeInputUV *suv= &shi->uv[i];
+
+ shi->totuv++;
+ suv->name= name;
+
+ if(strandbuf->overrideuv == i) {
+ suv->uv[0]= -1.0f;
+ suv->uv[1]= spoint->strandco;
+ suv->uv[2]= 0.0f;
+ }
+ else {
+ suv->uv[0]= -1.0f + 2.0f*uv[0];
+ suv->uv[1]= -1.0f + 2.0f*uv[1];
+ suv->uv[2]= 0.0f; /* texture.c assumes there are 3 coords */
+ }
+
+ if(shi->osatex) {
+ suv->dxuv[0]= 0.0f;
+ suv->dxuv[1]= 0.0f;
+ suv->dyuv[0]= 0.0f;
+ suv->dyuv[1]= 0.0f;
+ }
+
+ if((mode & MA_FACETEXTURE) && i==0) {
+ if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
+ shi->vcol[0]= 1.0f;
+ shi->vcol[1]= 1.0f;
+ shi->vcol[2]= 1.0f;
+ }
+ }
+ }
+
+ if(shi->totuv == 0) {
+ ShadeInputUV *suv= &shi->uv[0];
+
+ suv->uv[0]= 0.0f;
+ suv->uv[1]= spoint->strandco;
+ suv->uv[2]= 0.0f; /* texture.c assumes there are 3 coords */
+
+ if(mode & MA_FACETEXTURE) {
+ /* no tface? set at 1.0f */
+ shi->vcol[0]= 1.0f;
+ shi->vcol[1]= 1.0f;
+ shi->vcol[2]= 1.0f;
+ }
+ }
+
+ }
+
+ if(texco & TEXCO_NORM) {
+ shi->orn[0]= -shi->vn[0];
+ shi->orn[1]= -shi->vn[1];
+ shi->orn[2]= -shi->vn[2];
+ }
+
+ if(mode & MA_RADIO) {
+ /* not supported */
+ }
+
+ if(texco & TEXCO_REFL) {
+ /* mirror reflection color textures (and envmap) */
+ calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */
+ }
+
+ if(texco & TEXCO_STRESS) {
+ /* not supported */
+ }
+
+ if(texco & TEXCO_TANGENT) {
+ if((mode & MA_TANGENT_V)==0) {
+ /* just prevent surprises */
+ shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
+ shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
+ }
+ }
+ }
+
+ shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
+
+ /* this only avalailable for scanline renders */
+ if(shi->depth==0) {
+ if(texco & TEXCO_WINDOW) {
+ shi->winco[0]= -1.0f + 2.0f*spoint->x/(float)R.winx;
+ shi->winco[1]= -1.0f + 2.0f*spoint->y/(float)R.winy;
+ shi->winco[2]= 0.0f;
+
+ /* not supported */
+ if(shi->osatex) {
+ shi->dxwin[0]= 0.0f;
+ shi->dywin[1]= 0.0f;
+ shi->dxwin[0]= 0.0f;
+ shi->dywin[1]= 0.0f;
+ }
+ }
+
+ if(texco & TEXCO_STICKY) {
+ /* not supported */
+ }
+ }
+}
/* scanline pixel coordinates */
/* requires set_triangle */
@@ -322,7 +583,12 @@ void shade_input_set_viewco(ShadeInput *shi, float x, float y, float z)
calc_renderco_zbuf(shi->co, shi->view, z);
}
else {
- float dface, *v1= shi->v1->co;
+ float dface, v1[3];
+
+ VECCOPY(v1, shi->v1->co);
+
+ if(shi->obi->flag & R_TRANSFORMED)
+ Mat4MulVecfl(shi->obi->mat, v1);
dface= v1[0]*shi->facenor[0]+v1[1]*shi->facenor[1]+v1[2]*shi->facenor[2];
@@ -405,9 +671,19 @@ void shade_input_set_uv(ShadeInput *shi)
{
VlakRen *vlr= shi->vlr;
- if( (vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
- float *v1= shi->v1->co, *v2= shi->v2->co, *v3= shi->v3->co;
-
+ if((vlr->flag & R_SMOOTH) || (shi->mat->texco & NEED_UV) || (shi->passflag & SCE_PASS_UV)) {
+ float v1[3], v2[3], v3[3];
+
+ VECCOPY(v1, shi->v1->co);
+ VECCOPY(v2, shi->v2->co);
+ VECCOPY(v3, shi->v3->co);
+
+ if(shi->obi->flag & R_TRANSFORMED) {
+ Mat4MulVecfl(shi->obi->mat, v1);
+ Mat4MulVecfl(shi->obi->mat, v2);
+ Mat4MulVecfl(shi->obi->mat, v3);
+ }
+
/* exception case for wire render of edge */
if(vlr->v2==vlr->v3) {
float lend, lenc;
@@ -432,55 +708,35 @@ void shade_input_set_uv(ShadeInput *shi)
}
else {
/* most of this could become re-used for faces */
- float detsh, t00, t10, t01, t11;
-
- if(vlr->noflag & R_SNPROJ_X) {
- t00= v3[0]-v1[0]; t01= v3[1]-v1[1];
- t10= v3[0]-v2[0]; t11= v3[1]-v2[1];
- }
- else if(vlr->noflag & R_SNPROJ_Y) {
- t00= v3[0]-v1[0]; t01= v3[2]-v1[2];
- t10= v3[0]-v2[0]; t11= v3[2]-v2[2];
- }
- else {
- t00= v3[1]-v1[1]; t01= v3[2]-v1[2];
- t10= v3[1]-v2[1]; t11= v3[2]-v2[2];
- }
-
+ float detsh, t00, t10, t01, t11, xn, yn, zn;
+ int axis1, axis2;
+
+ /* find most stable axis to project */
+ xn= fabs(shi->facenor[0]);
+ yn= fabs(shi->facenor[1]);
+ zn= fabs(shi->facenor[2]);
+
+ if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; }
+ else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; }
+ else { axis1= 1; axis2= 2; }
+
+ /* compute u,v and derivatives */
+ t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
+ t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
+
detsh= 1.0f/(t00*t11-t10*t01);
t00*= detsh; t01*=detsh;
t10*=detsh; t11*=detsh;
-
- if(vlr->noflag & R_SNPROJ_X) {
- shi->u= (shi->co[0]-v3[0])*t11-(shi->co[1]-v3[1])*t10;
- shi->v= (shi->co[1]-v3[1])*t00-(shi->co[0]-v3[0])*t01;
- if(shi->osatex) {
- shi->dx_u= shi->dxco[0]*t11- shi->dxco[1]*t10;
- shi->dx_v= shi->dxco[1]*t00- shi->dxco[0]*t01;
- shi->dy_u= shi->dyco[0]*t11- shi->dyco[1]*t10;
- shi->dy_v= shi->dyco[1]*t00- shi->dyco[0]*t01;
- }
- }
- else if(vlr->noflag & R_SNPROJ_Y) {
- shi->u= (shi->co[0]-v3[0])*t11-(shi->co[2]-v3[2])*t10;
- shi->v= (shi->co[2]-v3[2])*t00-(shi->co[0]-v3[0])*t01;
- if(shi->osatex) {
- shi->dx_u= shi->dxco[0]*t11- shi->dxco[2]*t10;
- shi->dx_v= shi->dxco[2]*t00- shi->dxco[0]*t01;
- shi->dy_u= shi->dyco[0]*t11- shi->dyco[2]*t10;
- shi->dy_v= shi->dyco[2]*t00- shi->dyco[0]*t01;
- }
- }
- else {
- shi->u= (shi->co[1]-v3[1])*t11-(shi->co[2]-v3[2])*t10;
- shi->v= (shi->co[2]-v3[2])*t00-(shi->co[1]-v3[1])*t01;
- if(shi->osatex) {
- shi->dx_u= shi->dxco[1]*t11- shi->dxco[2]*t10;
- shi->dx_v= shi->dxco[2]*t00- shi->dxco[1]*t01;
- shi->dy_u= shi->dyco[1]*t11- shi->dyco[2]*t10;
- shi->dy_v= shi->dyco[2]*t00- shi->dyco[1]*t01;
- }
+
+ shi->u= (shi->co[axis1]-v3[axis1])*t11-(shi->co[axis2]-v3[axis2])*t10;
+ shi->v= (shi->co[axis2]-v3[axis2])*t00-(shi->co[axis1]-v3[axis1])*t01;
+ if(shi->osatex) {
+ shi->dx_u= shi->dxco[axis1]*t11- shi->dxco[axis2]*t10;
+ shi->dx_v= shi->dxco[axis2]*t00- shi->dxco[axis1]*t01;
+ shi->dy_u= shi->dyco[axis1]*t11- shi->dyco[axis2]*t10;
+ shi->dy_v= shi->dyco[axis2]*t00- shi->dyco[axis1]*t01;
}
+
/* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
CLAMP(shi->u, -2.0f, 1.0f);
CLAMP(shi->v, -2.0f, 1.0f);
@@ -503,24 +759,43 @@ void shade_input_set_normals(ShadeInput *shi)
Normalize(shi->vn);
}
- else {
+ else
VECCOPY(shi->vn, shi->facenor);
- }
/* used in nodes */
VECCOPY(shi->vno, shi->vn);
}
+/* use by raytrace, sss, bake to flip into the right direction */
+void shade_input_flip_normals(ShadeInput *shi)
+{
+ shi->facenor[0]= -shi->facenor[0];
+ shi->facenor[1]= -shi->facenor[1];
+ shi->facenor[2]= -shi->facenor[2];
+
+ shi->vn[0]= -shi->vn[0];
+ shi->vn[1]= -shi->vn[1];
+ shi->vn[2]= -shi->vn[2];
+
+ shi->vno[0]= -shi->vno[0];
+ shi->vno[1]= -shi->vno[1];
+ shi->vno[2]= -shi->vno[2];
+
+ shi->flippednor= !shi->flippednor;
+}
+
void shade_input_set_shade_texco(ShadeInput *shi)
{
+ ObjectInstanceRen *obi= shi->obi;
+ ObjectRen *obr= shi->obr;
VertRen *v1= shi->v1, *v2= shi->v2, *v3= shi->v3;
float u= shi->u, v= shi->v;
float l= 1.0f+u+v, dl;
int mode= shi->mode; /* or-ed result for all nodes */
short texco= shi->mat->texco;
- /* calculate dxno and tangents */
+ /* calculate dxno */
if(shi->vlr->flag & R_SMOOTH) {
if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL)) ) {
@@ -536,47 +811,87 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->dyno[2]= dl*n3[2]-shi->dy_u*n1[2]-shi->dy_v*n2[2];
}
-
- /* qdn: normalmap tangent space */
- if (mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
- float *s1, *s2, *s3;
-
- s1= RE_vertren_get_tangent(&R, v1, 0);
- s2= RE_vertren_get_tangent(&R, v2, 0);
- s3= RE_vertren_get_tangent(&R, v3, 0);
- if(s1 && s2 && s3) {
- shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
- shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
- shi->tang[2]= (l*s3[2] - u*s1[2] - v*s2[2]);
- /* qdn: normalize just in case */
- Normalize(shi->tang);
- }
- else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
- }
}
- else {
- /* qdn: normalmap tangent space */
- if (mode & (MA_TANGENT_V|MA_NORMAP_TANG)) {
+
+ /* calc tangents */
+ if (mode & (MA_TANGENT_V|MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
+ float *tangent, *s1, *s2, *s3;
+ float tl, tu, tv;
+
+ if(shi->vlr->flag & R_SMOOTH) {
+ tl= l;
+ tu= u;
+ tv= v;
+ }
+ else {
/* qdn: flat faces have tangents too,
could pick either one, using average here */
- float *s1 = RE_vertren_get_tangent(&R, v1, 0);
- float *s2 = RE_vertren_get_tangent(&R, v2, 0);
- float *s3 = RE_vertren_get_tangent(&R, v3, 0);
- if (s1 && s2 && s3) {
- shi->tang[0] = (s1[0] + s2[0] + s3[0]);
- shi->tang[1] = (s1[1] + s2[1] + s3[1]);
- shi->tang[2] = (s1[2] + s2[2] + s3[2]);
+ tl= 1.0f;
+ tu= 1.0f/3.0f;
+ tv= 1.0f/3.0f;
+ }
+
+ shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
+ shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
+
+ if(mode & MA_TANGENT_V) {
+ s1 = RE_vertren_get_tangent(obr, v1, 0);
+ s2 = RE_vertren_get_tangent(obr, v2, 0);
+ s3 = RE_vertren_get_tangent(obr, v3, 0);
+
+ if(s1 && s2 && s3) {
+ shi->tang[0]= (tl*s3[0] - tu*s1[0] - tv*s2[0]);
+ shi->tang[1]= (tl*s3[1] - tu*s1[1] - tv*s2[1]);
+ shi->tang[2]= (tl*s3[2] - tu*s1[2] - tv*s2[2]);
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat3MulVecfl(obi->nmat, shi->tang);
+
Normalize(shi->tang);
+ VECCOPY(shi->nmaptang, shi->tang);
}
}
+
+ if(mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT) {
+ tangent= RE_vlakren_get_nmap_tangent(obr, shi->vlr, 0);
+
+ if(tangent) {
+ s1= &tangent[shi->i1*3];
+ s2= &tangent[shi->i2*3];
+ s3= &tangent[shi->i3*3];
+
+ shi->nmaptang[0]= (tl*s3[0] - tu*s1[0] - tv*s2[0]);
+ shi->nmaptang[1]= (tl*s3[1] - tu*s1[1] - tv*s2[1]);
+ shi->nmaptang[2]= (tl*s3[2] - tu*s1[2] - tv*s2[2]);
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat3MulVecfl(obi->nmat, shi->nmaptang);
+
+ Normalize(shi->nmaptang);
+ }
+ }
+ }
+
+ if(mode & MA_STR_SURFDIFF) {
+ float *surfnor= RE_vlakren_get_surfnor(obr, shi->vlr, 0);
+
+ if(surfnor) {
+ VECCOPY(shi->surfnor, surfnor)
+ if(obi->flag & R_TRANSFORMED)
+ Mat3MulVecfl(obi->nmat, shi->surfnor);
+ }
+ else
+ VECCOPY(shi->surfnor, shi->vn)
+
+ shi->surfdist= 0.0f;
}
if(R.r.mode & R_SPEED) {
float *s1, *s2, *s3;
- s1= RE_vertren_get_winspeed(&R, v1, 0);
- s2= RE_vertren_get_winspeed(&R, v2, 0);
- s3= RE_vertren_get_winspeed(&R, v3, 0);
+ s1= RE_vertren_get_winspeed(obi, v1, 0);
+ s2= RE_vertren_get_winspeed(obi, v2, 0);
+ s3= RE_vertren_get_winspeed(obi, v3, 0);
if(s1 && s2 && s3) {
shi->winspeed[0]= (l*s3[0] - u*s1[0] - v*s2[0]);
shi->winspeed[1]= (l*s3[1] - u*s1[1] - v*s2[1]);
@@ -618,6 +933,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->dylo[2]= dl*o3[2]-shi->dy_u*o1[2]-shi->dy_v*o2[2];
}
}
+
+ VECCOPY(shi->duplilo, obi->dupliorco);
}
if(texco & TEXCO_GLOB) {
@@ -632,7 +949,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
if(texco & TEXCO_STRAND) {
- shi->strand= (l*v3->accum - u*v1->accum - v*v2->accum);
+ shi->strandco= (l*v3->accum - u*v1->accum - v*v2->accum);
if(shi->osatex) {
dl= shi->dx_u+shi->dx_v;
shi->dxstrand= dl*v3->accum-shi->dx_u*v1->accum-shi->dx_v*v2->accum;
@@ -653,9 +970,11 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->totuv= 0;
shi->totcol= 0;
+ shi->actuv= obr->actmtface;
+ shi->actcol= obr->actmcol;
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP)) {
- for (i=0; (mcol=RE_vlakren_get_mcol(&R, vlr, i, &name, 0)); i++) {
+ for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) {
ShadeInputCol *scol= &shi->col[i];
char *cp1, *cp2, *cp3;
@@ -675,15 +994,17 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->vcol[0]= shi->col[0].col[0];
shi->vcol[1]= shi->col[0].col[1];
shi->vcol[2]= shi->col[0].col[2];
+ shi->vcol[3]= 1.0f;
}
else {
shi->vcol[0]= 0.0f;
shi->vcol[1]= 0.0f;
shi->vcol[2]= 0.0f;
+ shi->vcol[3]= 1.0f;
}
}
- for (i=0; (tface=RE_vlakren_get_tface(&R, vlr, i, &name, 0)); i++) {
+ for (i=0; (tface=RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) {
ShadeInputUV *suv= &shi->uv[i];
float *uv1, *uv2, *uv3;
@@ -716,17 +1037,22 @@ void shade_input_set_shade_texco(ShadeInput *shi)
suv->dyuv[1]= 2.0f*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]);
}
- if((mode & MA_FACETEXTURE) && i==0) {
+ if((mode & MA_FACETEXTURE) && i==obr->actmtface) {
if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
shi->vcol[0]= 1.0f;
shi->vcol[1]= 1.0f;
shi->vcol[2]= 1.0f;
+ shi->vcol[3]= 1.0f;
}
if(tface && tface->tpage)
render_realtime_texture(shi, tface->tpage);
}
}
+ shi->dupliuv[0]= -1.0f + 2.0f*obi->dupliuv[0];
+ shi->dupliuv[1]= -1.0f + 2.0f*obi->dupliuv[1];
+ shi->dupliuv[2]= 0.0f;
+
if(shi->totuv == 0) {
ShadeInputUV *suv= &shi->uv[0];
@@ -739,6 +1065,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->vcol[0]= 1.0f;
shi->vcol[1]= 1.0f;
shi->vcol[2]= 1.0f;
+ shi->vcol[3]= 1.0f;
}
}
}
@@ -752,22 +1079,20 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if(mode & MA_RADIO) {
float *r1, *r2, *r3;
- r1= RE_vertren_get_rad(&R, v1, 0);
- r2= RE_vertren_get_rad(&R, v2, 0);
- r3= RE_vertren_get_rad(&R, v3, 0);
+ r1= RE_vertren_get_rad(obr, v1, 0);
+ r2= RE_vertren_get_rad(obr, v2, 0);
+ r3= RE_vertren_get_rad(obr, v3, 0);
if(r1 && r2 && r3) {
shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]);
shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]);
shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]);
}
- else {
+ else
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
- }
}
- else {
+ else
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
- }
if(texco & TEXCO_REFL) {
/* mirror reflection color textures (and envmap) */
@@ -777,9 +1102,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if(texco & TEXCO_STRESS) {
float *s1, *s2, *s3;
- s1= RE_vertren_get_stress(&R, v1, 0);
- s2= RE_vertren_get_stress(&R, v2, 0);
- s3= RE_vertren_get_stress(&R, v3, 0);
+ s1= RE_vertren_get_stress(obr, v1, 0);
+ s2= RE_vertren_get_stress(obr, v2, 0);
+ s3= RE_vertren_get_stress(obr, v3, 0);
if(s1 && s2 && s3) {
shi->stress= l*s3[0] - u*s1[0] - v*s2[0];
if(shi->stress<1.0f) shi->stress-= 1.0f;
@@ -792,12 +1117,12 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if((mode & MA_TANGENT_V)==0) {
/* just prevent surprises */
shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f;
+ shi->nmaptang[0]= shi->nmaptang[1]= shi->nmaptang[2]= 0.0f;
}
}
}
- else {
+ else
shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0f;
- }
/* this only avalailable for scanline renders */
if(shi->depth==0) {
@@ -819,22 +1144,32 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if(texco & TEXCO_STICKY) {
float *s1, *s2, *s3;
- s1= RE_vertren_get_sticky(&R, v1, 0);
- s2= RE_vertren_get_sticky(&R, v2, 0);
- s3= RE_vertren_get_sticky(&R, v3, 0);
+ s1= RE_vertren_get_sticky(obr, v1, 0);
+ s2= RE_vertren_get_sticky(obr, v2, 0);
+ s3= RE_vertren_get_sticky(obr, v3, 0);
if(s1 && s2 && s3) {
+ float winmat[4][4], ho1[4], ho2[4], ho3[4];
float Zmulx, Zmuly;
float hox, hoy, l, dl, u, v;
float s00, s01, s10, s11, detsh;
/* old globals, localized now */
Zmulx= ((float)R.winx)/2.0f; Zmuly= ((float)R.winy)/2.0f;
+
+ if(shi->obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(&R, shi->obi->mat, winmat);
+ else
+ zbuf_make_winmat(&R, NULL, winmat);
+
+ zbuf_render_project(winmat, v1->co, ho1);
+ zbuf_render_project(winmat, v2->co, ho2);
+ zbuf_render_project(winmat, v3->co, ho3);
- s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3];
- s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3];
- s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3];
- s11= v3->ho[1]/v3->ho[3] - v2->ho[1]/v2->ho[3];
+ s00= ho3[0]/ho3[3] - ho1[0]/ho1[3];
+ s01= ho3[1]/ho3[3] - ho1[1]/ho1[3];
+ s10= ho3[0]/ho3[3] - ho2[0]/ho2[3];
+ s11= ho3[1]/ho3[3] - ho2[1]/ho2[3];
detsh= s00*s11-s10*s01;
s00/= detsh; s01/=detsh;
@@ -843,8 +1178,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
/* recalc u and v again */
hox= x/Zmulx -1.0f;
hoy= y/Zmuly -1.0f;
- u= (hox - v3->ho[0]/v3->ho[3])*s11 - (hoy - v3->ho[1]/v3->ho[3])*s10;
- v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01;
+ u= (hox - ho3[0]/ho3[3])*s11 - (hoy - ho3[1]/ho3[3])*s10;
+ v= (hoy - ho3[1]/ho3[3])*s00 - (hox - ho3[0]/ho3[3])*s01;
l= 1.0f+u+v;
shi->sticky[0]= l*s3[0]-u*s1[0]-v*s2[0];
@@ -867,7 +1202,9 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
}
}
- }
+ } /* else {
+ Note! For raytracing winco is not set, important because thus means all shader input's need to have their variables set to zero else in-initialized values are used
+ */
}
/* ****************** ShadeSample ************************************** */
@@ -887,8 +1224,9 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in
shi->combinedflag= ~rl->pass_xor;
shi->mat_override= rl->mat_override;
shi->light_override= rl->light_override;
-
+// shi->rl= rl;
/* note shi.depth==0 means first hit, not raytracing */
+
}
/* initialize per part, not per pixel! */
@@ -903,7 +1241,7 @@ void shade_sample_initialize(ShadeSample *ssamp, RenderPart *pa, RenderLayer *rl
memset(&ssamp->shr[a], 0, sizeof(ShadeResult));
}
- ssamp->samplenr= 0; /* counter, detect shadow-reuse for shaders */
+ get_sample_layers(pa, rl, ssamp->rlpp);
}
/* Do AO or (future) GI */
@@ -914,19 +1252,22 @@ void shade_samples_do_AO(ShadeSample *ssamp)
if(!(R.r.mode & R_SHADOW))
return;
- if(!(R.r.mode & R_RAYTRACE))
+ if(!(R.r.mode & R_RAYTRACE) && !(R.wrld.ao_gather_method == WO_AOGATHER_APPROX))
return;
- if(R.wrld.mode & WO_AMB_OCC)
- if(ssamp->shi[0].passflag & (SCE_PASS_COMBINED|SCE_PASS_AO))
+ if(R.wrld.mode & WO_AMB_OCC) {
+ shi= &ssamp->shi[0];
+
+ if(((shi->passflag & SCE_PASS_COMBINED) && (shi->combinedflag & SCE_PASS_AO))
+ || (shi->passflag & SCE_PASS_AO))
for(sample=0, shi= ssamp->shi; sample<ssamp->tot; shi++, sample++)
if(!(shi->mode & MA_SHLESS))
ambient_occlusion(shi); /* stores in shi->ao[] */
-
+ }
}
-static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
+void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, int y)
{
ShadeInput *shi;
float xs, ys;
@@ -934,7 +1275,7 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
ssamp->tot= 0;
for(shi= ssamp->shi; ps; ps= ps->next) {
- shade_input_set_triangle(shi, ps->facenr, 1);
+ shade_input_set_triangle(shi, ps->obi, ps->facenr, 1);
if(shi->vlr) { /* NULL happens for env material or for 'all z' */
unsigned short curmask= ps->mask;
@@ -952,7 +1293,8 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
shade_input_copy_triangle(shi, shi-1);
shi->mask= (1<<samp);
- shi->samplenr= ssamp->samplenr++;
+// shi->rl= ssamp->rlpp[samp];
+ shi->samplenr= R.shadowsamplenr[shi->thread]++; /* this counter is not being reset per pixel */
shade_input_set_viewco(shi, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -973,7 +1315,7 @@ static void shade_samples_fill_with_ps(ShadeSample *ssamp, PixStr *ps, int x, in
ys= (float)y + 0.5f;
}
shi->mask= curmask;
- shi->samplenr= ssamp->samplenr++;
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
shade_input_set_viewco(shi, xs, ys, (float)ps->z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 7dd7383c60c..315ca58efc8 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -26,12 +26,14 @@
*/
#include <stdio.h>
+#include <float.h>
#include <math.h>
#include <string.h>
#include "MTC_matrixops.h"
#include "BLI_arithb.h"
+#include "BKE_colortools.h"
#include "BKE_material.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -41,6 +43,7 @@
#include "DNA_material_types.h"
/* local include */
+#include "occlusion.h"
#include "renderpipeline.h"
#include "render_types.h"
#include "pixelblending.h"
@@ -165,6 +168,9 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
p1[2]= -lar->co[2];
MTC_Mat3MulVecfl(lar->imat, p1);
VECCOPY(npos, p1); // npos is double!
+
+ /* pre-scale */
+ npos[2]*= lar->sh_zfac;
}
else {
VECCOPY(npos, lar->sh_invcampos); /* in initlamp calculated */
@@ -194,7 +200,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
maxz*= lar->sh_zfac;
maxy= lar->imat[0][1]*p1[0]+lar->imat[1][1]*p1[1]+lar->imat[2][1]*p1[2];
- if( fabs(nray[2]) <0.000001f ) use_yco= 1;
+ if( fabs(nray[2]) < DBL_EPSILON ) use_yco= 1;
}
/* scale z to make sure volume is normalized */
@@ -209,7 +215,7 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
c = npos[0] * npos[0] + npos[1] * npos[1] - npos[2]*npos[2];
snijp= 0;
- if (fabs(a) < 0.00000001) {
+ if (fabs(a) < DBL_EPSILON) {
/*
* Only one intersection point...
*/
@@ -349,7 +355,7 @@ void renderspothalo(ShadeInput *shi, float *col, float alpha)
if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
if(lar->mode & LA_LAYER)
- if(shi->vlr && (lar->lay & shi->vlr->lay)==0)
+ if(shi->vlr && (lar->lay & shi->obi->lay)==0)
continue;
if((lar->lay & shi->lay)==0)
continue;
@@ -416,17 +422,21 @@ static double saacos_d(double fac)
}
/* Stoke's form factor. Need doubles here for extreme small area sizes */
-static float area_lamp_energy(float *co, float *vn, LampRen *lar)
+static float area_lamp_energy(float (*area)[3], float *co, float *vn)
{
double fac;
double vec[4][3]; /* vectors of rendered co to vertices lamp */
double cross[4][3]; /* cross products of this */
double rad[4]; /* angles between vecs */
- VECSUB(vec[0], co, lar->area[0]);
- VECSUB(vec[1], co, lar->area[1]);
- VECSUB(vec[2], co, lar->area[2]);
- VECSUB(vec[3], co, lar->area[3]);
+ /* extra test for dot */
+ if ( INPR(co, vn) <= 0.0f)
+ return 0.0f;
+
+ VECSUB(vec[0], co, area[0]);
+ VECSUB(vec[1], co, area[1]);
+ VECSUB(vec[2], co, area[2]);
+ VECSUB(vec[3], co, area[3]);
Normalize_d(vec[0]);
Normalize_d(vec[1]);
@@ -462,7 +472,35 @@ static float area_lamp_energy(float *co, float *vn, LampRen *lar)
fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]);
if(fac<=0.0) return 0.0;
- return pow(fac*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
+ return fac;
+}
+
+static float area_lamp_energy_multisample(LampRen *lar, float *co, float *vn)
+{
+ /* corner vectors are moved around according lamp jitter */
+ float *jitlamp= lar->jitter, vec[3];
+ float area[4][3], intens= 0.0f;
+ int a= lar->ray_totsamp;
+
+
+ while(a--) {
+ vec[0]= jitlamp[0];
+ vec[1]= jitlamp[1];
+ vec[2]= 0.0f;
+ Mat3MulVecfl(lar->mat, vec);
+
+ VECADD(area[0], lar->area[0], vec);
+ VECADD(area[1], lar->area[1], vec);
+ VECADD(area[2], lar->area[2], vec);
+ VECADD(area[3], lar->area[3], vec);
+
+ intens+= area_lamp_energy(area, co, vn);
+
+ jitlamp+= 2;
+ }
+ intens /= (float)lar->ray_totsamp;
+
+ return pow(intens*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2
}
static float spec(float inp, int hard)
@@ -824,6 +862,8 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
shi->r= shi->vcol[0];
shi->g= shi->vcol[1];
shi->b= shi->vcol[2];
+ if(ma->mode & (MA_FACETEXTURE_ALPHA))
+ shi->alpha= shi->vcol[3];
}
if(ma->texco)
@@ -967,8 +1007,9 @@ static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec)
/* pure AO, check for raytrace and world should have been done */
void ambient_occlusion(ShadeInput *shi)
{
-
- if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
+ if((R.wrld.ao_gather_method == WO_AOGATHER_APPROX) && shi->mat->amb!=0.0f)
+ sample_occ(&R, shi);
+ else if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f)
ray_ao(shi, shi->ao);
else
shi->ao[0]= shi->ao[1]= shi->ao[2]= 1.0f;
@@ -978,25 +1019,28 @@ void ambient_occlusion(ShadeInput *shi)
/* wrld mode was checked for */
void ambient_occlusion_to_diffuse(ShadeInput *shi, float *diff)
{
-
- if((R.r.mode & R_RAYTRACE) && shi->mat->amb!=0.0f) {
- float f= R.wrld.aoenergy*shi->mat->amb;
-
- if (R.wrld.aomix==WO_AOADDSUB) {
- diff[0] = 2.0f*shi->ao[0]-1.0f;
- diff[1] = 2.0f*shi->ao[1]-1.0f;
- diff[2] = 2.0f*shi->ao[2]-1.0f;
- }
- else if (R.wrld.aomix==WO_AOSUB) {
- diff[0] = shi->ao[0]-1.0f;
- diff[1] = shi->ao[1]-1.0f;
- diff[2] = shi->ao[2]-1.0f;
- }
- else {
- VECCOPY(diff, shi->ao);
+ if((R.r.mode & R_RAYTRACE) || R.wrld.ao_gather_method == WO_AOGATHER_APPROX) {
+ if(shi->mat->amb!=0.0f) {
+ float f= R.wrld.aoenergy*shi->mat->amb;
+
+ if (R.wrld.aomix==WO_AOADDSUB) {
+ diff[0] = 2.0f*shi->ao[0]-1.0f;
+ diff[1] = 2.0f*shi->ao[1]-1.0f;
+ diff[2] = 2.0f*shi->ao[2]-1.0f;
+ }
+ else if (R.wrld.aomix==WO_AOSUB) {
+ diff[0] = shi->ao[0]-1.0f;
+ diff[1] = shi->ao[1]-1.0f;
+ diff[2] = shi->ao[2]-1.0f;
+ }
+ else {
+ VECCOPY(diff, shi->ao);
+ }
+
+ VECMUL(diff, f);
}
-
- VECMUL(diff, f);
+ else
+ diff[0]= diff[1]= diff[2]= 0.0f;
}
else
diff[0]= diff[1]= diff[2]= 0.0f;
@@ -1015,7 +1059,7 @@ void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float *shadfac, i
if(lar->buftype==LA_SHADBUF_IRREGULAR)
shadfac[3]= ISB_getshadow(shi, lar->shb);
else
- shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp);
+ shadfac[3] = testshadowbuf(&R, lar->shb, shi->co, shi->dxco, shi->dyco, inp, shi->mat->lbias);
}
else if(lar->mode & LA_SHAD_RAY) {
ray_shadow(shi, lar, shadfac);
@@ -1050,20 +1094,32 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist)
/* area type has no quad or sphere option */
if(lar->type==LA_AREA) {
/* area is single sided */
- if(INPR(lv, lar->vec) > 0.0f)
- visifac= 1.0f;
- else
- visifac= 0.0f;
+ //if(INPR(lv, lar->vec) > 0.0f)
+ // visifac= 1.0f;
+ //else
+ // visifac= 0.0f;
}
else {
- if(lar->mode & LA_QUAD) {
- if(lar->ld1>0.0f)
- visifac= lar->dist/(lar->dist+lar->ld1*dist[0]);
- if(lar->ld2>0.0f)
- visifac*= lar->distkw/(lar->distkw+lar->ld2*dist[0]*dist[0]);
- }
- else {
- visifac= (lar->dist/(lar->dist+dist[0]));
+ switch(lar->falloff_type)
+ {
+ case LA_FALLOFF_CONSTANT:
+ visifac = 1.0f;
+ break;
+ case LA_FALLOFF_INVLINEAR:
+ visifac = lar->dist/(lar->dist + dist[0]);
+ break;
+ case LA_FALLOFF_INVSQUARE:
+ visifac = lar->dist / (lar->dist + dist[0]*dist[0]);
+ break;
+ case LA_FALLOFF_SLIDERS:
+ if(lar->ld1>0.0f)
+ visifac= lar->dist/(lar->dist+lar->ld1*dist[0]);
+ if(lar->ld2>0.0f)
+ visifac*= lar->distkw/(lar->distkw+lar->ld2*dist[0]*dist[0]);
+ break;
+ case LA_FALLOFF_CURVE:
+ visifac = curvemapping_evaluateF(lar->curfalloff, 0, dist[0]/lar->dist);
+ break;
}
if(lar->mode & LA_SPHERE) {
@@ -1113,6 +1169,7 @@ float lamp_get_visibility(LampRen *lar, float *co, float *lv, float *dist)
}
}
}
+ if (visifac <= 0.001) visifac = 0.0f;
return visifac;
}
}
@@ -1129,6 +1186,15 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
vn= shi->vn;
view= shi->view;
+
+ if (lar->energy == 0.0) return;
+ /* only shadow lamps shouldn't affect shadow-less materials at all */
+ if ((lar->mode & LA_ONLYSHADOW) && (!(ma->mode & MA_SHADOW) || !(R.r.mode & R_SHADOW)))
+ return;
+ /* optimisation, don't render fully black lamps */
+ if (!(lar->mode & LA_TEXTURE) && (lar->r + lar->g + lar->b == 0.0f))
+ return;
+
/* lampdist, spot angle, area side, ... */
visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist);
if(visifac==0.0f)
@@ -1154,13 +1220,36 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
lacol[2]= lar->b;
if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol);
-
- /* tangent case; calculate fake face normal, aligned with lampvector */
- /* note, vnor==vn is used as tangent trigger for buffer shadow */
+
+ /* tangent case; calculate fake face normal, aligned with lampvector */
+ /* note, vnor==vn is used as tangent trigger for buffer shadow */
if(vlr->flag & R_TANGENT) {
- float cross[3];
- Crossf(cross, lv, vn);
- Crossf(vnor, cross, vn);
+ float cross[3], nstrand[3], blend;
+
+ if(ma->mode & MA_STR_SURFDIFF) {
+ Crossf(cross, shi->surfnor, vn);
+ Crossf(nstrand, vn, cross);
+
+ blend= INPR(nstrand, shi->surfnor);
+ blend= 1.0f - blend;
+ CLAMP(blend, 0.0f, 1.0f);
+
+ VecLerpf(vnor, nstrand, shi->surfnor, blend);
+ Normalize(vnor);
+ }
+ else {
+ Crossf(cross, lv, vn);
+ Crossf(vnor, cross, vn);
+ }
+
+ if(ma->strand_surfnor > 0.0f) {
+ if(ma->strand_surfnor > shi->surfdist) {
+ blend= (ma->strand_surfnor - shi->surfdist)/ma->strand_surfnor;
+ VecLerpf(vnor, vnor, shi->surfnor, blend);
+ Normalize(vnor);
+ }
+ }
+
vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2];
vn= vnor;
}
@@ -1180,9 +1269,9 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
/* this complex construction screams for a nicer implementation! (ton) */
if(R.r.mode & R_SHADOW) {
if(ma->mode & MA_SHADOW) {
- if(lar->type==LA_HEMI);
+ if(lar->type==LA_HEMI || lar->type==LA_AREA);
else if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
- float thresh= vlr->ob->smoothresh;
+ float thresh= shi->obr->ob->smoothresh;
if(inp>thresh)
phongcorr= (inp-thresh)/(inp*(1.0f-thresh));
else
@@ -1207,7 +1296,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
else {
if(lar->type==LA_AREA)
- inp= area_lamp_energy(shi->co, vn, lar);
+ inp= area_lamp_energy_multisample(lar, shi->co, vn);
/* diffuse shaders (oren nayer gets inp from area light) */
if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);
@@ -1217,7 +1306,10 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
else is= inp; // Lambert
}
- /* i is diffuse */
+ /* 'is' is diffuse */
+ if((ma->shade_flag & MA_CUBIC) && is>0.0f)
+ is= 3.0*is*is - 2.0*is*is*is; // nicer termination of shades
+
i= is*phongcorr;
if(i>0.0f) {
@@ -1235,7 +1327,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
/* shadow and spec, (visifac==0 outside spot) */
if(visifac> 0.0f) {
- if(i>0.0f && (R.r.mode & R_SHADOW)) {
+ if((R.r.mode & R_SHADOW)) {
if(ma->mode & MA_SHADOW) {
if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
@@ -1245,12 +1337,17 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
lamp_get_shadow(lar, shi, inp, shadfac, shi->depth);
/* warning, here it skips the loop */
- if(lar->mode & LA_ONLYSHADOW) {
+ if((lar->mode & LA_ONLYSHADOW) && i>0.0) {
shadfac[3]= i*lar->energy*(1.0f-shadfac[3]);
shr->shad[0] -= shadfac[3]*shi->r;
shr->shad[1] -= shadfac[3]*shi->g;
shr->shad[2] -= shadfac[3]*shi->b;
+
+ shr->spec[0] -= shadfac[3]*shi->specr;
+ shr->spec[1] -= shadfac[3]*shi->specg;
+ shr->spec[2] -= shadfac[3]*shi->specb;
+
return;
}
@@ -1259,7 +1356,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
}
}
- /* in case 'no diffuse' we still do most calculus, spec can be in shadow */
+ /* in case 'no diffuse' we still do most calculus, spec can be in shadow.*/
if(!(lar->mode & LA_NO_DIFF)) {
if(i>0.0f) {
if(ma->mode & MA_SHADOW_TRA)
@@ -1280,7 +1377,7 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
}
/* specularity */
- if(shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC)) {
+ if(shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) {
if(!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC)));
else if(lar->type==LA_HEMI) {
@@ -1366,7 +1463,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
/* yafray: ignore shading by photonlights, not used in Blender */
if (lar->type==LA_YF_PHOTON) continue;
- if(lar->mode & LA_LAYER) if((lar->lay & shi->vlr->lay)==0) continue;
+ if(lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) continue;
if((lar->lay & shi->lay)==0) continue;
if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
@@ -1416,8 +1513,10 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
}
}
+/* let's map negative light as if it mirrors positive light, otherwise negative values disappear */
static void wrld_exposure_correct(float *diff)
{
+
diff[0]= R.wrld.linfac*(1.0f-exp( diff[0]*R.wrld.logfac) );
diff[1]= R.wrld.linfac*(1.0f-exp( diff[1]*R.wrld.logfac) );
diff[2]= R.wrld.linfac*(1.0f-exp( diff[2]*R.wrld.logfac) );
@@ -1426,7 +1525,6 @@ static void wrld_exposure_correct(float *diff)
void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
{
Material *ma= shi->mat;
- VlakRen *vlr= shi->vlr;
int passflag= shi->passflag;
memset(shr, 0, sizeof(ShadeResult));
@@ -1446,6 +1544,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shi->r= shi->vcol[0];
shi->g= shi->vcol[1];
shi->b= shi->vcol[2];
+ if(ma->mode & (MA_FACETEXTURE_ALPHA))
+ shi->alpha= shi->vcol[3];
}
if(ma->texco)
do_material_tex(shi);
@@ -1478,7 +1578,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* AO pass */
if(R.wrld.mode & WO_AMB_OCC) {
- if(passflag & (SCE_PASS_COMBINED|SCE_PASS_AO)) {
+ if(((passflag & SCE_PASS_COMBINED) && (shi->combinedflag & SCE_PASS_AO))
+ || (passflag & SCE_PASS_AO)) {
/* AO was calculated for scanline already */
if(shi->depth)
ambient_occlusion(shi);
@@ -1501,13 +1602,23 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if (lar->type==LA_YF_PHOTON) continue;
/* test for lamp layer */
- if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue;
+ if(lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) continue;
if((lar->lay & shi->lay)==0) continue;
/* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */
shade_one_light(lar, shi, shr, passflag);
}
+ /*this check is to prevent only shadow lamps from producing negative
+ colors.*/
+ if (shr->spec[0] < 0) shr->spec[0] = 0;
+ if (shr->spec[1] < 0) shr->spec[1] = 0;
+ if (shr->spec[2] < 0) shr->spec[2] = 0;
+
+ if (shr->shad[0] < 0) shr->shad[0] = 0;
+ if (shr->shad[1] < 0) shr->shad[1] = 0;
+ if (shr->shad[2] < 0) shr->shad[2] = 0;
+
if(ma->sss_flag & MA_DIFF_SSS) {
float sss[3], col[3], texfac= ma->sss_texfac;
@@ -1575,9 +1686,15 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* from now stuff everything in shr->combined: ambient, AO, radio, ramps, exposure */
if(!(ma->sss_flag & MA_DIFF_SSS) || !has_sss_tree(&R, ma)) {
- shr->combined[0]+= shi->ambr + shi->r*shi->amb*shi->rad[0];
- shr->combined[1]+= shi->ambg + shi->g*shi->amb*shi->rad[1];
- shr->combined[2]+= shi->ambb + shi->b*shi->amb*shi->rad[2];
+ shr->combined[0]+= shi->ambr;
+ shr->combined[1]+= shi->ambg;
+ shr->combined[2]+= shi->ambb;
+
+ if(shi->combinedflag & SCE_PASS_RADIO) {
+ shr->combined[0]+= shi->r*shi->amb*shi->rad[0];
+ shr->combined[1]+= shi->g*shi->amb*shi->rad[1];
+ shr->combined[2]+= shi->b*shi->amb*shi->rad[2];
+ }
/* add AO in combined? */
if(R.wrld.mode & WO_AMB_OCC) {
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index f0d56a18994..e41c7c38069 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -59,6 +59,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
+#include "BKE_scene.h"
#include "BKE_utildefines.h"
/* this module */
@@ -234,11 +235,7 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd)
float indexf, t, idxf;
int index;
- if(rr > (RD_TABLE_RANGE_2*RD_TABLE_RANGE_2)) {
- rd[0]= Rd_rsquare(ss[0], rr);
- rd[1]= Rd_rsquare(ss[1], rr);
- rd[2]= Rd_rsquare(ss[2], rr);
- }
+ if(rr > (RD_TABLE_RANGE_2*RD_TABLE_RANGE_2));
else if(rr > RD_TABLE_RANGE) {
rr= sqrt(rr);
indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2);
@@ -246,9 +243,12 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd)
idxf= (float)index;
t= indexf - idxf;
- rd[0]= (ss[0]->tableRd2[index]*(1-t) + ss[0]->tableRd2[index+1]*t);
- rd[1]= (ss[1]->tableRd2[index]*(1-t) + ss[1]->tableRd2[index+1]*t);
- rd[2]= (ss[2]->tableRd2[index]*(1-t) + ss[2]->tableRd2[index+1]*t);
+ if(index >= 0 && index < RD_TABLE_SIZE) {
+ rd[0]= (ss[0]->tableRd2[index]*(1-t) + ss[0]->tableRd2[index+1]*t);
+ rd[1]= (ss[1]->tableRd2[index]*(1-t) + ss[1]->tableRd2[index+1]*t);
+ rd[2]= (ss[2]->tableRd2[index]*(1-t) + ss[2]->tableRd2[index+1]*t);
+ return;
+ }
}
else {
indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE);
@@ -256,10 +256,18 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd)
idxf= (float)index;
t= indexf - idxf;
- rd[0]= (ss[0]->tableRd[index]*(1-t) + ss[0]->tableRd[index+1]*t);
- rd[1]= (ss[1]->tableRd[index]*(1-t) + ss[1]->tableRd[index+1]*t);
- rd[2]= (ss[2]->tableRd[index]*(1-t) + ss[2]->tableRd[index+1]*t);
+ if(index >= 0 && index < RD_TABLE_SIZE) {
+ rd[0]= (ss[0]->tableRd[index]*(1-t) + ss[0]->tableRd[index+1]*t);
+ rd[1]= (ss[1]->tableRd[index]*(1-t) + ss[1]->tableRd[index+1]*t);
+ rd[2]= (ss[2]->tableRd[index]*(1-t) + ss[2]->tableRd[index+1]*t);
+ return;
+ }
}
+
+ /* fallback to slow Rd computation */
+ rd[0]= Rd_rsquare(ss[0], rr);
+ rd[1]= Rd_rsquare(ss[1], rr);
+ rd[2]= Rd_rsquare(ss[2], rr);
}
static void build_Rd_table(ScatterSettings *ss)
@@ -473,7 +481,7 @@ static void sum_leaf_radiance(ScatterTree *tree, ScatterNode *node)
for(i=0; i<node->totpoint; i++) {
p= &node->points[i];
- rad= p->area*(p->rad[0] + p->rad[1] + p->rad[2]);
+ rad= p->area*fabs(p->rad[0] + p->rad[1] + p->rad[2]);
totrad += rad;
node->co[0] += rad*p->co[0];
@@ -550,8 +558,8 @@ static void sum_branch_radiance(ScatterTree *tree, ScatterNode *node)
subnode= node->child[i];
- rad= subnode->area*(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]);
- rad += subnode->backarea*(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]);
+ rad= subnode->area*fabs(subnode->rad[0] + subnode->rad[1] + subnode->rad[2]);
+ rad += subnode->backarea*fabs(subnode->backrad[0] + subnode->backrad[1] + subnode->backrad[2]);
totrad += rad;
node->co[0] += rad*subnode->co[0];
@@ -840,7 +848,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
{
SSSPoints *p;
RenderResult *rr;
- ListBase layers, points;
+ ListBase points;
float (*co)[3] = NULL, (*color)[3] = NULL, *area = NULL;
int totpoint = 0, osa, osaflag, partsdone;
@@ -853,13 +861,11 @@ 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 */
- layers= re->r.layers;
+ rr= re->result;
osa= re->osa;
osaflag= re->r.mode & R_OSA;
partsdone= re->i.partsdone;
- rr= re->result;
- re->r.layers.first= re->r.layers.last= NULL;
re->osa= 0;
re->r.mode &= ~R_OSA;
re->sss_points= &points;
@@ -874,7 +880,6 @@ static void sss_create_tree_mat(Render *re, Material *mat)
re->i.partsdone= partsdone;
re->sss_mat= NULL;
re->sss_points= NULL;
- re->r.layers= layers;
re->osa= osa;
if (osaflag) re->r.mode |= R_OSA;
@@ -914,7 +919,8 @@ static void sss_create_tree_mat(Render *re, Material *mat)
float *col= mat->sss_col, *radius= mat->sss_radius;
float fw= mat->sss_front, bw= mat->sss_back;
float error = mat->sss_error;
-
+
+ error= get_render_aosss_error(&re->r, error);
if((re->r.scemode & R_PREVIEWBUTS) && error < 0.5f)
error= 0.5f;
@@ -978,7 +984,7 @@ void make_sss_tree(Render *re)
re->stats_draw(&re->i);
for(mat= G.main->mat.first; mat; mat= mat->id.next)
- if(mat->id.us && (mat->sss_flag & MA_DIFF_SSS))
+ if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS))
sss_create_tree_mat(re, mat);
}
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
new file mode 100644
index 00000000000..1c5d793dbc9
--- /dev/null
+++ b/source/blender/render/intern/source/strand.c
@@ -0,0 +1,1012 @@
+/**
+ * $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: none of this file.
+ *
+ * Contributors: Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_key_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_key.h"
+#include "BKE_utildefines.h"
+
+#include "render_types.h"
+#include "initrender.h"
+#include "rendercore.h"
+#include "renderdatabase.h"
+#include "renderpipeline.h"
+#include "pixelblending.h"
+#include "shading.h"
+#include "strand.h"
+#include "zbuf.h"
+
+/* to be removed */
+void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco);
+void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) );
+void zbufsinglewire(ZSpan *zspan, int obi, int zvlnr, float *ho1, float *ho2);
+
+/* *************** */
+
+static float strand_eval_width(Material *ma, float strandco)
+{
+ float fac;
+
+ strandco= 0.5f*(strandco + 1.0f);
+
+ if(ma->strand_ease!=0.0f) {
+ if(ma->strand_ease<0.0f)
+ fac= pow(strandco, 1.0+ma->strand_ease);
+ else
+ fac= pow(strandco, 1.0/(1.0f-ma->strand_ease));
+ }
+ else fac= strandco;
+
+ return ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end);
+}
+
+void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
+{
+ Material *ma;
+ StrandBuffer *strandbuf;
+ float *simplify;
+ float p[4][3], data[4], cross[3], crosslen, w, dx, dy, t;
+ int type;
+
+ strandbuf= sseg->buffer;
+ ma= sseg->buffer->ma;
+ t= spoint->t;
+ type= (strandbuf->flag & R_STRAND_BSPLINE)? KEY_BSPLINE: KEY_CARDINAL;
+
+ VECCOPY(p[0], sseg->v[0]->co);
+ VECCOPY(p[1], sseg->v[1]->co);
+ VECCOPY(p[2], sseg->v[2]->co);
+ VECCOPY(p[3], sseg->v[3]->co);
+
+ if(sseg->obi->flag & R_TRANSFORMED) {
+ Mat4MulVecfl(sseg->obi->mat, p[0]);
+ Mat4MulVecfl(sseg->obi->mat, p[1]);
+ Mat4MulVecfl(sseg->obi->mat, p[2]);
+ Mat4MulVecfl(sseg->obi->mat, p[3]);
+ }
+
+ if(t == 0.0f) {
+ VECCOPY(spoint->co, p[1]);
+ spoint->strandco= sseg->v[1]->strandco;
+
+ spoint->dtstrandco= (sseg->v[2]->strandco - sseg->v[0]->strandco);
+ if(sseg->v[0] != sseg->v[1])
+ spoint->dtstrandco *= 0.5f;
+ }
+ else if(t == 1.0f) {
+ VECCOPY(spoint->co, p[2]);
+ spoint->strandco= sseg->v[2]->strandco;
+
+ spoint->dtstrandco= (sseg->v[3]->strandco - sseg->v[1]->strandco);
+ if(sseg->v[3] != sseg->v[2])
+ spoint->dtstrandco *= 0.5f;
+ }
+ else {
+ set_four_ipo(t, data, type);
+ spoint->co[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0];
+ spoint->co[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1];
+ spoint->co[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2];
+ spoint->strandco= (1.0f-t)*sseg->v[1]->strandco + t*sseg->v[2]->strandco;
+ }
+
+ set_afgeleide_four_ipo(t, data, type);
+ spoint->dtco[0]= data[0]*p[0][0] + data[1]*p[1][0] + data[2]*p[2][0] + data[3]*p[3][0];
+ spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1];
+ spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2];
+
+ VECCOPY(spoint->tan, spoint->dtco);
+ Normalize(spoint->tan);
+
+ VECCOPY(spoint->nor, spoint->co);
+ VECMUL(spoint->nor, -1.0f);
+ Normalize(spoint->nor);
+
+ spoint->width= strand_eval_width(ma, spoint->strandco);
+
+ /* simplification */
+ simplify= RE_strandren_get_simplify(strandbuf->obr, sseg->strand, 0);
+ spoint->alpha= (simplify)? simplify[1]: 1.0f;
+
+ /* outer points */
+ Crossf(cross, spoint->co, spoint->tan);
+
+ w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3];
+ dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w;
+ dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w;
+ w= sqrt(dx*dx + dy*dy);
+
+ if(w > 0.0f) {
+ if(strandbuf->flag & R_STRAND_B_UNITS) {
+ crosslen= VecLength(cross);
+ w= 2.0f*crosslen*strandbuf->minwidth/w;
+
+ if(spoint->width < w) {
+ spoint->alpha= spoint->width/w;
+ spoint->width= w;
+ }
+
+ if(simplify)
+ /* squared because we only change width, not length */
+ spoint->width *= simplify[0]*simplify[0];
+
+ VecMulf(cross, spoint->width*0.5f/crosslen);
+ }
+ else
+ VecMulf(cross, spoint->width/w);
+ }
+
+ VecSubf(spoint->co1, spoint->co, cross);
+ VecAddf(spoint->co2, spoint->co, cross);
+
+ VECCOPY(spoint->dsco, cross);
+}
+
+/* *************** */
+
+static void interpolate_vec1(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+}
+
+static void interpolate_vec3(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+ v[1]= negt*v1[1] + t*v2[1];
+ v[2]= negt*v1[2] + t*v2[2];
+}
+
+static void interpolate_vec4(float *v1, float *v2, float t, float negt, float *v)
+{
+ v[0]= negt*v1[0] + t*v2[0];
+ v[1]= negt*v1[1] + t*v2[1];
+ v[2]= negt*v1[2] + t*v2[2];
+ v[3]= negt*v1[3] + t*v2[3];
+}
+
+void interpolate_shade_result(ShadeResult *shr1, ShadeResult *shr2, float t, ShadeResult *shr, int addpassflag)
+{
+ float negt= 1.0f - t;
+
+ interpolate_vec4(shr1->combined, shr2->combined, t, negt, shr->combined);
+
+ if(addpassflag & SCE_PASS_VECTOR) {
+ interpolate_vec4(shr1->winspeed, shr2->winspeed, t, negt, shr->winspeed);
+ }
+ /* optim... */
+ if(addpassflag & ~(SCE_PASS_VECTOR)) {
+ if(addpassflag & SCE_PASS_Z)
+ interpolate_vec1(&shr1->z, &shr2->z, t, negt, &shr->z);
+ if(addpassflag & SCE_PASS_RGBA)
+ interpolate_vec4(shr1->col, shr2->col, t, negt, shr->col);
+ if(addpassflag & SCE_PASS_NORMAL) {
+ interpolate_vec3(shr1->nor, shr2->nor, t, negt, shr->nor);
+ Normalize(shr->nor);
+ }
+ if(addpassflag & SCE_PASS_DIFFUSE)
+ interpolate_vec3(shr1->diff, shr2->diff, t, negt, shr->diff);
+ if(addpassflag & SCE_PASS_SPEC)
+ interpolate_vec3(shr1->spec, shr2->spec, t, negt, shr->spec);
+ if(addpassflag & SCE_PASS_SHADOW)
+ interpolate_vec3(shr1->shad, shr2->shad, t, negt, shr->shad);
+ if(addpassflag & SCE_PASS_AO)
+ interpolate_vec3(shr1->ao, shr2->ao, t, negt, shr->ao);
+ if(addpassflag & SCE_PASS_REFLECT)
+ interpolate_vec3(shr1->refl, shr2->refl, t, negt, shr->refl);
+ if(addpassflag & SCE_PASS_REFRACT)
+ interpolate_vec3(shr1->refr, shr2->refr, t, negt, shr->refr);
+ if(addpassflag & SCE_PASS_RADIO)
+ interpolate_vec3(shr1->rad, shr2->rad, t, negt, shr->rad);
+ if(addpassflag & SCE_PASS_MIST)
+ interpolate_vec1(&shr1->mist, &shr2->mist, t, negt, &shr->mist);
+ }
+}
+
+void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha)
+{
+ if(alpha < 1.0f) {
+ shr->combined[0] *= alpha;
+ shr->combined[1] *= alpha;
+ shr->combined[2] *= alpha;
+ shr->combined[3] *= alpha;
+
+ shr->col[0] *= alpha;
+ shr->col[1] *= alpha;
+ shr->col[2] *= alpha;
+ shr->col[3] *= alpha;
+
+ shr->alpha *= alpha;
+ }
+}
+
+void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint)
+{
+ ShadeInput *shi= ssamp->shi;
+ ShadeResult *shr= ssamp->shr;
+ VlakRen vlr;
+
+ memset(&vlr, 0, sizeof(vlr));
+ vlr.flag= R_SMOOTH;
+ if(sseg->buffer->ma->mode & MA_TANGENT_STR)
+ vlr.flag |= R_TANGENT;
+
+ shi->vlr= &vlr;
+ shi->strand= sseg->strand;
+ shi->obi= sseg->obi;
+ shi->obr= sseg->obi->obr;
+
+ /* cache for shadow */
+ shi->samplenr= re->shadowsamplenr[shi->thread]++;
+
+ shade_input_set_strand(shi, sseg->strand, spoint);
+ shade_input_set_strand_texco(shi, sseg->strand, sseg->v[1], spoint);
+
+ /* init material vars */
+ // note, keep this synced with render_types.h
+ memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
+ shi->har= shi->mat->har;
+
+ /* shade */
+ shade_samples_do_AO(ssamp);
+ shade_input_do_shade(shi, shr);
+
+ /* apply simplification */
+ strand_apply_shaderesult_alpha(shr, spoint->alpha);
+
+ /* include lamphalos for strand, since halo layer was added already */
+ if(re->flag & R_LAMPHALO)
+ if(shi->layflag & SCE_LAY_HALO)
+ renderspothalo(shi, shr->combined, shr->combined[3]);
+
+ shi->strand= NULL;
+}
+
+/* *************** */
+
+struct StrandShadeCache {
+ GHash *resulthash;
+ GHash *refcounthash;
+ MemArena *memarena;
+};
+
+StrandShadeCache *strand_shade_cache_create()
+{
+ StrandShadeCache *cache;
+
+ cache= MEM_callocN(sizeof(StrandShadeCache), "StrandShadeCache");
+ cache->resulthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ cache->refcounthash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ cache->memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+
+ return cache;
+}
+
+void strand_shade_cache_free(StrandShadeCache *cache)
+{
+ BLI_ghash_free(cache->refcounthash, NULL, NULL);
+ BLI_ghash_free(cache->resulthash, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_memarena_free(cache->memarena);
+ MEM_freeN(cache);
+}
+
+static void strand_shade_get(Render *re, StrandShadeCache *cache, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert)
+{
+ ShadeResult *hashshr;
+ StrandPoint p;
+ int *refcount;
+
+ hashshr= BLI_ghash_lookup(cache->resulthash, svert);
+ refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+
+ if(!hashshr) {
+ /* not shaded yet, shade and insert into hash */
+ p.t= (sseg->v[1] == svert)? 0.0f: 1.0f;
+ strand_eval_point(sseg, &p);
+ strand_shade_point(re, ssamp, sseg, &p);
+
+ hashshr= MEM_callocN(sizeof(ShadeResult), "HashShadeResult");
+ *hashshr= ssamp->shr[0];
+ BLI_ghash_insert(cache->resulthash, svert, hashshr);
+ }
+ else
+ /* already shaded, just copy previous result from hash */
+ ssamp->shr[0]= *hashshr;
+
+ /* lower reference count and remove if not needed anymore by any samples */
+ (*refcount)--;
+ if(*refcount == 0) {
+ BLI_ghash_remove(cache->resulthash, svert, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_ghash_remove(cache->refcounthash, svert, NULL, NULL);
+ }
+}
+
+void strand_shade_segment(Render *re, StrandShadeCache *cache, StrandSegment *sseg, ShadeSample *ssamp, float t, float s, int addpassflag)
+{
+ ShadeResult shr1, shr2;
+
+ /* get shading for two endpoints and interpolate */
+ strand_shade_get(re, cache, ssamp, sseg, sseg->v[1]);
+ shr1= ssamp->shr[0];
+ strand_shade_get(re, cache, ssamp, sseg, sseg->v[2]);
+ shr2= ssamp->shr[0];
+
+ interpolate_shade_result(&shr1, &shr2, t, ssamp->shr, addpassflag);
+
+ /* apply alpha along width */
+ if(sseg->buffer->widthfade != 0.0f) {
+ s = 1.0f - pow(fabs(s), sseg->buffer->widthfade);
+
+ strand_apply_shaderesult_alpha(ssamp->shr, s);
+ }
+}
+
+void strand_shade_unref(StrandShadeCache *cache, StrandVert *svert)
+{
+ int *refcount;
+
+ /* lower reference count and remove if not needed anymore by any samples */
+ refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+
+ (*refcount)--;
+ if(*refcount == 0) {
+ BLI_ghash_remove(cache->resulthash, svert, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_ghash_remove(cache->refcounthash, svert, NULL, NULL);
+ }
+}
+
+static void strand_shade_refcount(StrandShadeCache *cache, StrandVert *svert)
+{
+ int *refcount= BLI_ghash_lookup(cache->refcounthash, svert);
+
+ if(!refcount) {
+ refcount= BLI_memarena_alloc(cache->memarena, sizeof(int));
+ *refcount= 1;
+ BLI_ghash_insert(cache->refcounthash, svert, refcount);
+ }
+ else
+ (*refcount)++;
+}
+
+/* *************** */
+
+typedef struct StrandPart {
+ Render *re;
+ ZSpan *zspan;
+
+ APixstrand *apixbuf;
+ int *totapixbuf;
+ int *rectz;
+ int *rectmask;
+ long *rectdaps;
+ int rectx, recty;
+ int sample;
+
+ StrandSegment *segment;
+ float t[3], s[3];
+
+ StrandShadeCache *cache;
+} StrandPart;
+
+typedef struct StrandSortSegment {
+ struct StrandSortSegment *next;
+ int obi, strand, segment;
+ float z;
+} StrandSortSegment;
+
+static int compare_strand_segment(const void *poin1, const void *poin2)
+{
+ const StrandSortSegment *seg1= (const StrandSortSegment*)poin1;
+ const StrandSortSegment *seg2= (const StrandSortSegment*)poin2;
+
+ if(seg1->z < seg2->z)
+ return -1;
+ else if(seg1->z == seg2->z)
+ return 0;
+ else
+ return 1;
+}
+
+static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
+{
+ projectvert(co, winmat, hoco);
+ hoco_to_zco(zspan, zco, hoco);
+}
+
+static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint)
+{
+ float div;
+
+ projectvert(spoint->co, winmat, spoint->hoco);
+
+ div= 1.0f/spoint->hoco[3];
+ spoint->x= spoint->hoco[0]*div*winx*0.5f;
+ spoint->y= spoint->hoco[1]*div*winy*0.5f;
+}
+
+static APixstrand *addpsmainAstrand(ListBase *lb)
+{
+ APixstrMain *psm;
+
+ psm= MEM_mallocN(sizeof(APixstrMain), "addpsmainA");
+ BLI_addtail(lb, psm);
+ psm->ps= MEM_callocN(4096*sizeof(APixstrand),"pixstr");
+
+ return psm->ps;
+}
+
+static APixstrand *addpsAstrand(ZSpan *zspan)
+{
+ /* make new PS */
+ if(zspan->apstrandmcounter==0) {
+ zspan->curpstrand= addpsmainAstrand(zspan->apsmbase);
+ zspan->apstrandmcounter= 4095;
+ }
+ else {
+ zspan->curpstrand++;
+ zspan->apstrandmcounter--;
+ }
+ return zspan->curpstrand;
+}
+
+#define MAX_ZROW 2000
+
+static void do_strand_fillac(void *handle, int x, int y, float u, float v, float z)
+{
+ StrandPart *spart= (StrandPart*)handle;
+ StrandShadeCache *cache= spart->cache;
+ StrandSegment *sseg= spart->segment;
+ APixstrand *apn, *apnew;
+ float t, s;
+ int offset, mask, obi, strnr, seg, zverg, bufferz, maskz=0;
+
+ offset = y*spart->rectx + x;
+ obi= sseg->obi - spart->re->objectinstance;
+ strnr= sseg->strand->index + 1;
+ seg= sseg->v[1] - sseg->strand->vert;
+ mask= (1<<spart->sample);
+
+ /* check against solid z-buffer */
+ zverg= (int)z;
+
+ if(spart->rectdaps) {
+ /* find the z of the sample */
+ PixStr *ps;
+ long *rd= spart->rectdaps + offset;
+
+ bufferz= 0x7FFFFFFF;
+ if(spart->rectmask) maskz= 0x7FFFFFFF;
+
+ if(*rd) {
+ for(ps= (PixStr *)(*rd); ps; ps= ps->next) {
+ if(mask & ps->mask) {
+ bufferz= ps->z;
+ if(spart->rectmask)
+ maskz= ps->maskz;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ bufferz= spart->rectz[offset];
+ if(spart->rectmask)
+ maskz= spart->rectmask[offset];
+ }
+
+#define CHECK_ADD(n) \
+ if(apn->p[n]==strnr && apn->obi[n]==obi && apn->seg[n]==seg) \
+ { if(!(apn->mask[n] & mask)) { apn->mask[n] |= mask; apn->v[n] += t; apn->u[n] += s; } break; }
+#define CHECK_ASSIGN(n) \
+ if(apn->p[n]==0) \
+ {apn->obi[n]= obi; apn->p[n]= strnr; apn->z[n]= zverg; apn->mask[n]= mask; apn->v[n]= t; apn->u[n]= s; apn->seg[n]= seg; break; }
+
+ /* add to pixel list */
+ if(zverg < bufferz && (spart->totapixbuf[offset] < MAX_ZROW)) {
+ if(!spart->rectmask || zverg > maskz) {
+ t = u*spart->t[0] + v*spart->t[1] + (1.0f-u-v)*spart->t[2];
+ s = fabs(u*spart->s[0] + v*spart->s[1] + (1.0f-u-v)*spart->s[2]);
+
+ apn= spart->apixbuf + offset;
+ while(apn) {
+ CHECK_ADD(0);
+ CHECK_ADD(1);
+ CHECK_ADD(2);
+ CHECK_ADD(3);
+ CHECK_ASSIGN(0);
+ CHECK_ASSIGN(1);
+ CHECK_ASSIGN(2);
+ CHECK_ASSIGN(3);
+
+ apnew= addpsAstrand(spart->zspan);
+ SWAP(APixstrand, *apnew, *apn);
+ apn->next= apnew;
+ CHECK_ASSIGN(0);
+ }
+
+ strand_shade_refcount(cache, sseg->v[1]);
+ strand_shade_refcount(cache, sseg->v[2]);
+ spart->totapixbuf[offset]++;
+ }
+ }
+}
+
+static int strand_test_clip(float winmat[][4], ZSpan *zspan, float *bounds, float *co, float *zcomp)
+{
+ float hoco[4];
+ int clipflag= 0;
+
+ projectvert(co, winmat, hoco);
+
+ /* we compare z without perspective division for segment sorting */
+ *zcomp= hoco[2];
+
+ if(hoco[0] > bounds[1]*hoco[3]) clipflag |= 1;
+ else if(hoco[0]< bounds[0]*hoco[3]) clipflag |= 2;
+ else if(hoco[1] > bounds[3]*hoco[3]) clipflag |= 4;
+ else if(hoco[1]< bounds[2]*hoco[3]) clipflag |= 8;
+
+ clipflag |= testclip(hoco);
+
+ return clipflag;
+}
+
+static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, float t, float dt, float *co1, float *co2, float *co3, float *co4, int sample)
+{
+ float jco1[3], jco2[3], jco3[3], jco4[3], jx, jy;
+
+ VECCOPY(jco1, co1);
+ VECCOPY(jco2, co2);
+ VECCOPY(jco3, co3);
+ VECCOPY(jco4, co4);
+
+ if(re->osa) {
+ jx= -re->jit[sample][0];
+ jy= -re->jit[sample][1];
+
+ jco1[0] += jx; jco1[1] += jy;
+ jco2[0] += jx; jco2[1] += jy;
+ jco3[0] += jx; jco3[1] += jy;
+ jco4[0] += jx; jco4[1] += jy;
+ }
+ else if(re->i.curblur) {
+ jx= -re->jit[re->i.curblur-1][0];
+ jy= -re->jit[re->i.curblur-1][1];
+
+ jco1[0] += jx; jco1[1] += jy;
+ jco2[0] += jx; jco2[1] += jy;
+ jco3[0] += jx; jco3[1] += jy;
+ jco4[0] += jx; jco4[1] += jy;
+ }
+
+ spart->sample= sample;
+
+ spart->t[0]= t-dt;
+ spart->s[0]= -1.0f;
+ spart->t[1]= t-dt;
+ spart->s[1]= 1.0f;
+ spart->t[2]= t;
+ spart->s[2]= 1.0f;
+ zspan_scanconvert_strand(zspan, spart, jco1, jco2, jco3, do_strand_fillac);
+ spart->t[0]= t-dt;
+ spart->s[0]= -1.0f;
+ spart->t[1]= t;
+ spart->s[1]= 1.0f;
+ spart->t[2]= t;
+ spart->s[2]= -1.0f;
+ zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac);
+}
+
+static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2)
+{
+ if(spart) {
+ float t= p2->t;
+ float dt= p2->t - p1->t;
+ int a;
+
+ if(re->osa) {
+ for(a=0; a<re->osa; a++)
+ do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a);
+ }
+ else
+ do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, 0);
+ }
+ else {
+ float hoco1[4], hoco2[3];
+ int a, obi, index;
+
+ obi= sseg->obi - re->objectinstance;
+ index= sseg->strand->index;
+
+ projectvert(p1->co, winmat, hoco1);
+ projectvert(p2->co, winmat, hoco2);
+
+ for(a=0; a<totzspan; a++) {
+#if 0
+ /* render both strand and single pixel wire to counter aliasing */
+ zbufclip4(re, &zspan[a], obi, index, p1->hoco2, p1->hoco1, p2->hoco1, p2->hoco2, p1->clip2, p1->clip1, p2->clip1, p2->clip2);
+#endif
+ /* only render a line for now, which makes the shadow map more
+ similiar across frames, and so reduces flicker */
+ zbufsinglewire(&zspan[a], obi, index, hoco1, hoco2);
+ }
+ }
+}
+
+static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth)
+{
+ StrandPoint p;
+ StrandBuffer *buffer= sseg->buffer;
+ float dot, d1[2], d2[2], len1, len2;
+
+ if(depth == buffer->maxdepth)
+ return 0;
+
+ p.t= (p1->t + p2->t)*0.5f;
+ strand_eval_point(sseg, &p);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, &p);
+
+ d1[0]= (p.x - p1->x);
+ d1[1]= (p.y - p1->y);
+ len1= d1[0]*d1[0] + d1[1]*d1[1];
+
+ d2[0]= (p2->x - p.x);
+ d2[1]= (p2->y - p.y);
+ len2= d2[0]*d2[0] + d2[1]*d2[1];
+
+ if(len1 == 0.0f || len2 == 0.0f)
+ return 0;
+
+ dot= d1[0]*d2[0] + d1[1]*d2[1];
+ if(dot*dot > sseg->sqadaptcos*len1*len2)
+ return 0;
+
+ if(spart) {
+ do_strand_point_project(winmat, zspan, p.co1, p.hoco1, p.zco1);
+ do_strand_point_project(winmat, zspan, p.co2, p.hoco2, p.zco2);
+ }
+ else {
+#if 0
+ projectvert(p.co1, winmat, p.hoco1);
+ projectvert(p.co2, winmat, p.hoco2);
+ p.clip1= testclip(p.hoco1);
+ p.clip2= testclip(p.hoco2);
+#endif
+ }
+
+ if(!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, &p, depth+1))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, &p);
+ if(!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, &p, p2, depth+1))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, &p, p2);
+
+ return 1;
+}
+
+void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg)
+{
+ StrandBuffer *buffer= sseg->buffer;
+ StrandPoint *p1= &sseg->point1;
+ StrandPoint *p2= &sseg->point2;
+
+ p1->t= 0.0f;
+ p2->t= 1.0f;
+
+ strand_eval_point(sseg, p1);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p1);
+ strand_eval_point(sseg, p2);
+ strand_project_point(buffer->winmat, buffer->winx, buffer->winy, p2);
+
+ if(spart) {
+ do_strand_point_project(winmat, zspan, p1->co1, p1->hoco1, p1->zco1);
+ do_strand_point_project(winmat, zspan, p1->co2, p1->hoco2, p1->zco2);
+ do_strand_point_project(winmat, zspan, p2->co1, p2->hoco1, p2->zco1);
+ do_strand_point_project(winmat, zspan, p2->co2, p2->hoco2, p2->zco2);
+ }
+ else {
+#if 0
+ projectvert(p1->co1, winmat, p1->hoco1);
+ projectvert(p1->co2, winmat, p1->hoco2);
+ projectvert(p2->co1, winmat, p2->hoco1);
+ projectvert(p2->co2, winmat, p2->hoco2);
+ p1->clip1= testclip(p1->hoco1);
+ p1->clip2= testclip(p1->hoco2);
+ p2->clip1= testclip(p2->hoco1);
+ p2->clip2= testclip(p2->hoco2);
+#endif
+ }
+
+ if(!strand_segment_recursive(re, winmat, spart, zspan, totzspan, sseg, p1, p2, 0))
+ strand_render(re, sseg, winmat, spart, zspan, totzspan, p1, p2);
+}
+
+/* render call to fill in strands */
+int zbuffer_strands_abuf(Render *re, RenderPart *pa, RenderLayer *rl, APixstrand *apixbuf, ListBase *apsmbase, StrandShadeCache *cache)
+{
+ ObjectRen *obr;
+ ObjectInstanceRen *obi;
+ ZSpan zspan;
+ StrandRen *strand=0;
+ StrandVert *svert;
+ StrandBound *sbound;
+ StrandPart spart;
+ StrandSegment sseg;
+ StrandSortSegment *sortsegments = NULL, *sortseg, *firstseg;
+ MemArena *memarena;
+ float z[4], bounds[4], winmat[4][4];
+ int a, b, c, i, totsegment, clip[4];
+
+ if(re->test_break())
+ return 0;
+ if(re->totstrand == 0)
+ return 0;
+
+ /* setup StrandPart */
+ memset(&spart, 0, sizeof(spart));
+
+ spart.re= re;
+ spart.rectx= pa->rectx;
+ spart.recty= pa->recty;
+ spart.apixbuf= apixbuf;
+ spart.zspan= &zspan;
+ spart.rectdaps= pa->rectdaps;
+ spart.rectz= pa->rectz;
+ spart.rectmask= pa->rectmask;
+ spart.cache= cache;
+
+ zbuf_alloc_span(&zspan, pa->rectx, pa->recty, re->clipcrop);
+
+ /* needed for transform from hoco to zbuffer co */
+ zspan.zmulx= ((float)re->winx)/2.0;
+ zspan.zmuly= ((float)re->winy)/2.0;
+
+ zspan.zofsx= -pa->disprect.xmin;
+ zspan.zofsy= -pa->disprect.ymin;
+
+ /* to center the sample position */
+ zspan.zofsx -= 0.5f;
+ zspan.zofsy -= 0.5f;
+
+ zspan.apsmbase= apsmbase;
+
+ /* clipping setup */
+ bounds[0]= (2*pa->disprect.xmin - re->winx-1)/(float)re->winx;
+ bounds[1]= (2*pa->disprect.xmax - re->winx+1)/(float)re->winx;
+ bounds[2]= (2*pa->disprect.ymin - re->winy-1)/(float)re->winy;
+ bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy;
+
+ memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ firstseg= NULL;
+ sortseg= sortsegments;
+ totsegment= 0;
+
+ /* for all object instances */
+ for(obi=re->instancetable.first, i=0; obi; obi=obi->next, i++) {
+ obr= obi->obr;
+
+ if(!obr->strandbuf || !(obr->strandbuf->lay & rl->lay))
+ continue;
+
+ /* compute matrix and try clipping whole object */
+ if(obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(re, obi->mat, winmat);
+ else
+ zbuf_make_winmat(re, NULL, winmat);
+
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
+ /* for each bounding box containing a number of strands */
+ sbound= obr->strandbuf->bound;
+ for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
+ if(clip_render_object(sbound->boundbox, bounds, winmat))
+ continue;
+
+ /* for each strand in this bounding box */
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+ svert= strand->vert;
+
+ /* keep clipping and z depth for 4 control points */
+ clip[1]= strand_test_clip(winmat, &zspan, bounds, svert->co, &z[1]);
+ clip[2]= strand_test_clip(winmat, &zspan, bounds, (svert+1)->co, &z[2]);
+ clip[0]= clip[1]; z[0]= z[1];
+
+ for(b=0; b<strand->totvert-1; b++, svert++) {
+ /* compute 4th point clipping and z depth */
+ if(b < strand->totvert-2) {
+ clip[3]= strand_test_clip(winmat, &zspan, bounds, (svert+2)->co, &z[3]);
+ }
+ else {
+ clip[3]= clip[2]; z[3]= z[2];
+ }
+
+ /* check clipping and add to sortsegments buffer */
+ if(!(clip[0] & clip[1] & clip[2] & clip[3])) {
+ sortseg= BLI_memarena_alloc(memarena, sizeof(StrandSortSegment));
+ sortseg->obi= i;
+ sortseg->strand= strand->index;
+ sortseg->segment= b;
+
+ sortseg->z= 0.5f*(z[1] + z[2]);
+
+ sortseg->next= firstseg;
+ firstseg= sortseg;
+ totsegment++;
+ }
+
+ /* shift clipping and z depth */
+ clip[0]= clip[1]; z[0]= z[1];
+ clip[1]= clip[2]; z[1]= z[2];
+ clip[2]= clip[3]; z[2]= z[3];
+ }
+ }
+ }
+ }
+
+ if(!re->test_break()) {
+ /* convert list to array and sort */
+ sortsegments= MEM_mallocN(sizeof(StrandSortSegment)*totsegment, "StrandSortSegment");
+ for(a=0, sortseg=firstseg; a<totsegment; a++, sortseg=sortseg->next)
+ sortsegments[a]= *sortseg;
+ qsort(sortsegments, totsegment, sizeof(StrandSortSegment), compare_strand_segment);
+ }
+
+ BLI_memarena_free(memarena);
+
+ spart.totapixbuf= MEM_callocN(sizeof(int)*pa->rectx*pa->recty, "totapixbuf");
+
+ if(!re->test_break()) {
+ /* render segments in sorted order */
+ sortseg= sortsegments;
+ for(a=0; a<totsegment; a++, sortseg++) {
+ if(re->test_break())
+ break;
+
+ obi= &re->objectinstance[sortseg->obi];
+ obr= obi->obr;
+ zbuf_make_winmat(re, NULL, winmat);
+
+ sseg.obi= obi;
+ sseg.strand= RE_findOrAddStrand(obr, sortseg->strand);
+ sseg.buffer= sseg.strand->buffer;
+ sseg.sqadaptcos= sseg.buffer->adaptcos;
+ sseg.sqadaptcos *= sseg.sqadaptcos;
+
+ svert= sseg.strand->vert + sortseg->segment;
+ sseg.v[0]= (sortseg->segment > 0)? (svert-1): svert;
+ sseg.v[1]= svert;
+ sseg.v[2]= svert+1;
+ sseg.v[3]= (sortseg->segment < sseg.strand->totvert-2)? svert+2: svert+1;
+ sseg.shaded= 0;
+
+ spart.segment= &sseg;
+
+ render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg);
+ }
+ }
+
+ if(sortsegments)
+ MEM_freeN(sortsegments);
+ MEM_freeN(spart.totapixbuf);
+
+ zbuf_free_span(&zspan);
+
+ return totsegment;
+}
+
+/* *************** */
+
+StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset)
+{
+ StrandSurface *mesh;
+ MFace *mface;
+ MVert *mvert;
+ float (*co)[3];
+ int a, totvert, totface;
+
+ totvert= dm->getNumVerts(dm);
+ totface= dm->getNumFaces(dm);
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next)
+ if(mesh->obr.ob == obr->ob && mesh->obr.par == obr->par
+ && mesh->obr.index == obr->index && mesh->totvert==totvert && mesh->totface==totface)
+ break;
+
+ if(!mesh) {
+ mesh= MEM_callocN(sizeof(StrandSurface), "StrandSurface");
+ mesh->obr= *obr;
+ mesh->totvert= totvert;
+ mesh->totface= totface;
+ mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
+ mesh->col= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCol");
+ BLI_addtail(&re->strandsurface, mesh);
+ }
+
+ if(timeoffset == -1 && !mesh->prevco)
+ mesh->prevco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if(timeoffset == 0 && !mesh->co)
+ mesh->co= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if(timeoffset == 1 && !mesh->nextco)
+ mesh->nextco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else
+ return mesh;
+
+ mvert= dm->getVertArray(dm);
+ for(a=0; a<mesh->totvert; a++, mvert++) {
+ VECCOPY(co[a], mvert->co);
+ Mat4MulVecfl(mat, co[a]);
+ }
+
+ mface= dm->getFaceArray(dm);
+ for(a=0; a<mesh->totface; a++, mface++) {
+ mesh->face[a][0]= mface->v1;
+ mesh->face[a][1]= mface->v2;
+ mesh->face[a][2]= mface->v3;
+ mesh->face[a][3]= mface->v4;
+ }
+
+ return mesh;
+}
+
+void free_strand_surface(Render *re)
+{
+ StrandSurface *mesh;
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if(mesh->co) MEM_freeN(mesh->co);
+ if(mesh->prevco) MEM_freeN(mesh->prevco);
+ if(mesh->nextco) MEM_freeN(mesh->nextco);
+ if(mesh->col) MEM_freeN(mesh->col);
+ if(mesh->face) MEM_freeN(mesh->face);
+ }
+
+ BLI_freelistN(&re->strandsurface);
+}
+
+void strand_minmax(StrandRen *strand, float *min, float *max)
+{
+ StrandVert *svert;
+ int a;
+
+ for(a=0, svert=strand->vert; a<strand->totvert; a++, svert++)
+ DO_MINMAX(svert->co, min, max)
+}
+
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 1e6a98d482d..377d72325f0 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -53,6 +53,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_library.h"
#include "BKE_image.h"
@@ -98,7 +99,7 @@ void init_render_texture(Render *re, Tex *tex)
}
else if(tex->type==TEX_ENVMAP) {
/* just in case */
- tex->imaflag= TEX_INTERPOL | TEX_MIPMAP;
+ tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP;
tex->extend= TEX_CLIP;
if(tex->env) {
@@ -200,7 +201,7 @@ static int blend(Tex *tex, float *texvec, TexResult *texres)
else { /* sphere TEX_SPHERE */
texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]);
if(texres->tin<0.0) texres->tin= 0.0;
- if(tex->stype==5) texres->tin*= texres->tin; /* halo */
+ if(tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */
}
BRICONT;
@@ -229,7 +230,7 @@ static int clouds(Tex *tex, float *texvec, TexResult *texres)
rv |= TEX_NOR;
}
- if (tex->stype==1) {
+ if (tex->stype==TEX_COLOR) {
// in this case, int. value should really be computed from color,
// and bumpnormal from that, would be too slow, looks ok as is
texres->tr = texres->tin;
@@ -480,7 +481,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres)
VECCOPY(texres->nor, nor);
tex_normal_derivate(tex, texres);
- if(tex->stype==2) {
+ if(tex->stype==TEX_WALLOUT) {
texres->nor[0]= -texres->nor[0];
texres->nor[1]= -texres->nor[1];
texres->nor[2]= -texres->nor[2];
@@ -489,7 +490,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres)
retval |= TEX_NOR;
}
- if(tex->stype==2)
+ if(tex->stype==TEX_WALLOUT)
texres->tin= 1.0f-texres->tin;
if(texres->tin<0.0f)
@@ -755,16 +756,16 @@ static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex
}
-static int cubemap_glob(VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
+static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float *adr2)
{
float x1, y1, z1, nor[3];
int ret;
- if(vlr==NULL) {
+ if(n==NULL) {
nor[0]= x; nor[1]= y; nor[2]= z; // use local render coord
}
else {
- VECCOPY(nor, vlr->n);
+ VECCOPY(nor, n);
}
MTC_Mat4Mul3Vecfl(R.viewinv, nor);
@@ -793,7 +794,7 @@ static int cubemap_glob(VlakRen *vlr, float x, float y, float z, float *adr1, fl
/* ------------------------------------------------------------------------- */
/* mtex argument only for projection switches */
-static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
+static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z, float *adr1, float *adr2)
{
int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
@@ -811,7 +812,7 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
else vlr->puno |= ME_PROJYZ;
}
- else return cubemap_glob(vlr, x, y, z, adr1, adr2);
+ else return cubemap_glob(n, x, y, z, adr1, adr2);
}
if(mtex) {
@@ -843,7 +844,7 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
}
}
else {
- return cubemap_glob(vlr, x, y, z, adr1, adr2);
+ return cubemap_glob(n, x, y, z, adr1, adr2);
}
return ret;
@@ -851,14 +852,14 @@ static int cubemap(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *a
/* ------------------------------------------------------------------------- */
-static int cubemap_ob(Object *ob, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2)
+static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *adr1, float *adr2)
{
float x1, y1, z1, nor[3];
int ret;
- if(vlr==NULL) return 0;
+ if(n==NULL) return 0;
- VECCOPY(nor, vlr->n);
+ VECCOPY(nor, n);
if(ob) MTC_Mat4Mul3Vecfl(ob->imat, nor);
x1= fabs(nor[0]);
@@ -885,7 +886,7 @@ static int cubemap_ob(Object *ob, VlakRen *vlr, float x, float y, float z, float
/* ------------------------------------------------------------------------- */
-static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float *dyt)
+static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *dxt, float *dyt)
{
Tex *tex;
Object *ob= NULL;
@@ -907,9 +908,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
else if(wrap==MTEX_TUBE) tubemap(t[0], t[1], t[2], &fx, &fy);
else if(wrap==MTEX_SPHERE) spheremap(t[0], t[1], t[2], &fx, &fy);
else {
- if(texco==TEXCO_OBJECT) cubemap_ob(ob, vlr, t[0], t[1], t[2], &fx, &fy);
- else if(texco==TEXCO_GLOB) cubemap_glob(vlr, t[0], t[1], t[2], &fx, &fy);
- else cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
+ if(texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
+ else if(texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
+ else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
}
/* repeat */
@@ -998,9 +999,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
}
else {
- if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, vlr, t[0], t[1], t[2], &fx, &fy);
- else if (texco==TEXCO_GLOB) proj = cubemap_glob(vlr, t[0], t[1], t[2], &fx, &fy);
- else proj = cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
+ if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
+ else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
+ else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
if(proj==1) {
SWAP(float, dxt[1], dxt[2]);
@@ -1202,6 +1203,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
return retval;
}
+/* Warning, if the texres's values are not declared zero, check the return value to be sure
+ * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
{
@@ -1230,7 +1233,7 @@ int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, Te
dyt_l[0]= dyt_l[1]= dyt_l[2]= 0.0f;
}
- do_2d_mapping(&mtex, texvec_l, NULL, dxt_l, dyt_l);
+ do_2d_mapping(&mtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres);
}
@@ -1242,7 +1245,7 @@ int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, Te
/* in = destination, tex = texture, out = previous color */
/* fact = texture strength, facg = button strength value */
-static void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype)
+void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype)
{
float facm, col;
@@ -1255,7 +1258,7 @@ static void texture_rgb_blend(float *in, float *tex, float *out, float fact, flo
in[1]= (fact*tex[1] + facm*out[1]);
in[2]= (fact*tex[2] + facm*out[2]);
break;
-
+
case MTEX_MUL:
fact*= facg;
facm= 1.0-facg;
@@ -1272,6 +1275,24 @@ static void texture_rgb_blend(float *in, float *tex, float *out, float fact, flo
in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]);
break;
+ case MTEX_OVERLAY:
+ fact*= facg;
+ facm= 1.0-facg;
+
+ if(out[0] < 0.5f)
+ in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
+ else
+ in[0] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[0])) * (1.0 - out[0]);
+ if(out[1] < 0.5f)
+ in[1] = out[1] * (facm + 2.0f*fact*tex[1]);
+ else
+ in[1] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[1])) * (1.0 - out[1]);
+ if(out[2] < 0.5f)
+ in[2] = out[2] * (facm + 2.0f*fact*tex[2]);
+ else
+ in[2] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[2])) * (1.0 - out[2]);
+ break;
+
case MTEX_SUB:
fact= -fact;
case MTEX_ADD:
@@ -1325,12 +1346,31 @@ static void texture_rgb_blend(float *in, float *tex, float *out, float fact, flo
col= fact*tex[2];
if(col > out[2]) in[2]= col; else in[2]= out[2];
break;
+
+ case MTEX_BLEND_HUE:
+ fact*= facg;
+ VECCOPY(in, out);
+ ramp_blend(MA_RAMP_HUE, in, in+1, in+2, fact, tex);
+ break;
+ case MTEX_BLEND_SAT:
+ fact*= facg;
+ VECCOPY(in, out);
+ ramp_blend(MA_RAMP_SAT, in, in+1, in+2, fact, tex);
+ break;
+ case MTEX_BLEND_VAL:
+ fact*= facg;
+ VECCOPY(in, out);
+ ramp_blend(MA_RAMP_VAL, in, in+1, in+2, fact, tex);
+ break;
+ case MTEX_BLEND_COLOR:
+ fact*= facg;
+ VECCOPY(in, out);
+ ramp_blend(MA_RAMP_COLOR, in, in+1, in+2, fact, tex);
+ break;
}
-
-
}
-static 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, int flip)
{
float in=0.0, facm, col;
@@ -1390,7 +1430,7 @@ void do_material_tex(ShadeInput *shi)
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float *co = NULL, *dx = NULL, *dy = NULL;
float fact, facm, factt, facmm, stencilTin=1.0;
- float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3], Tnor=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;
if (R.r.scemode & R_NO_TEX) return;
@@ -1406,10 +1446,17 @@ void do_material_tex(ShadeInput *shi)
tex= mtex->tex;
if(tex==0) continue;
-
+
/* which coords */
if(mtex->texco==TEXCO_ORCO) {
- co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
+ if(mtex->texflag & MTEX_DUPLI_MAPTO) {
+ co= shi->duplilo; dx= dxt; dy= dyt;
+ dxt[0]= dxt[1]= dxt[2]= 0.0f;
+ dyt[0]= dyt[1]= dyt[2]= 0.0f;
+ }
+ else {
+ co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
+ }
}
else if(mtex->texco==TEXCO_STICKY) {
co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
@@ -1421,6 +1468,8 @@ void do_material_tex(ShadeInput *shi)
dx= dxt;
dy= dyt;
VECCOPY(tempvec, shi->co);
+ if(shi->obi && shi->obi->duplitexmat)
+ MTC_Mat4MulVecfl(shi->obi->duplitexmat, tempvec);
MTC_Mat4MulVecfl(ob->imat, tempvec);
if(shi->osatex) {
VECCOPY(dxt, shi->dxco);
@@ -1448,28 +1497,35 @@ void do_material_tex(ShadeInput *shi)
co= shi->gl; dx= shi->dxco; dy= shi->dyco;
}
else if(mtex->texco==TEXCO_UV) {
- ShadeInputUV *suv= &shi->uv[0];
- int i;
-
- if(mtex->uvname[0] != 0) {
- for(i = 0; i < shi->totuv; i++) {
- if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
- suv= &shi->uv[i];
- break;
+ if(mtex->texflag & MTEX_DUPLI_MAPTO) {
+ co= shi->dupliuv; dx= dxt; dy= dyt;
+ dxt[0]= dxt[1]= dxt[2]= 0.0f;
+ dyt[0]= dyt[1]= dyt[2]= 0.0f;
+ }
+ else {
+ ShadeInputUV *suv= &shi->uv[shi->actuv];
+ int i;
+
+ if(mtex->uvname[0] != 0) {
+ for(i = 0; i < shi->totuv; i++) {
+ if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
+ suv= &shi->uv[i];
+ break;
+ }
}
}
- }
- co= suv->uv;
- dx= suv->dxuv;
- dy= suv->dyuv;
+ co= suv->uv;
+ dx= suv->dxuv;
+ dy= suv->dyuv;
+ }
}
else if(mtex->texco==TEXCO_WINDOW) {
co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
}
else if(mtex->texco==TEXCO_STRAND) {
co= tempvec; dx= dxt; dy= dyt;
- co[0]= shi->strand;
+ co[0]= shi->strandco;
co[1]= co[2]= 0.0f;
dx[0]= shi->dxstrand;
dx[1]= dx[2]= 0.0f;
@@ -1486,7 +1542,7 @@ void do_material_tex(ShadeInput *shi)
dy[1]= dy[2]= 0.0f;
}
else continue; // can happen when texco defines disappear and it renders old files
-
+
/* de pointer defines if bumping happens */
if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
texres.nor= norvec;
@@ -1531,7 +1587,7 @@ void do_material_tex(ShadeInput *shi)
else dxt[2]= dyt[2]= 0.0;
}
- do_2d_mapping(mtex, texvec, shi->vlr, dxt, dyt);
+ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
/* translate and scale */
texvec[0]= mtex->size[0]*(texvec[0]-0.5) +mtex->ofs[0]+0.5;
@@ -1651,10 +1707,10 @@ void do_material_tex(ShadeInput *shi)
if(mtex->texflag & MTEX_VIEWSPACE) {
// rotate to global coords
if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
- if(shi->vlr && shi->vlr->ob) {
+ if(shi->vlr && shi->obr->ob) {
float len= Normalize(texres.nor);
// can be optimized... (ton)
- Mat4Mul3Vecfl(shi->vlr->ob->obmat, texres.nor);
+ Mat4Mul3Vecfl(shi->obr->ob->obmat, texres.nor);
Mat4Mul3Vecfl(R.viewmat, texres.nor);
Normalize(texres.nor);
VecMulf(texres.nor, len);
@@ -1706,7 +1762,6 @@ void do_material_tex(ShadeInput *shi)
}
if( (mtex->mapto & MAP_NORM) ) {
if(texres.nor) {
-
if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
else tex->norfac= mtex->norfac;
@@ -1723,23 +1778,39 @@ void do_material_tex(ShadeInput *shi)
fact = Tnor*tex->norfac;
if (fact>1.f) fact = 1.f;
facm = 1.f-fact;
- if (shi->mat->mode & MA_NORMAP_TANG) {
+ if(mtex->normapspace == MTEX_NSPACE_TANGENT) {
/* qdn: tangent space */
float B[3], tv[3];
- Crossf(B, shi->vn, shi->tang); /* bitangent */
+ Crossf(B, shi->vn, shi->nmaptang); /* bitangent */
/* transform norvec from tangent space to object surface in camera space */
- tv[0] = texres.nor[0]*shi->tang[0] + texres.nor[1]*B[0] + texres.nor[2]*shi->vn[0];
- tv[1] = texres.nor[0]*shi->tang[1] + texres.nor[1]*B[1] + texres.nor[2]*shi->vn[1];
- tv[2] = texres.nor[0]*shi->tang[2] + texres.nor[1]*B[2] + texres.nor[2]*shi->vn[2];
+ tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*shi->vn[0];
+ tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*shi->vn[1];
+ tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*shi->vn[2];
shi->vn[0]= facm*shi->vn[0] + fact*tv[0];
shi->vn[1]= facm*shi->vn[1] + fact*tv[1];
shi->vn[2]= facm*shi->vn[2] + fact*tv[2];
}
else {
+ float nor[3];
+
+ VECCOPY(nor, texres.nor);
+
+ if(mtex->normapspace == MTEX_NSPACE_CAMERA);
+ else if(mtex->normapspace == MTEX_NSPACE_WORLD) {
+ Mat4Mul3Vecfl(R.viewmat, nor);
+ }
+ else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
+ if(shi->obr && shi->obr->ob)
+ Mat4Mul3Vecfl(shi->obr->ob->obmat, nor);
+ Mat4Mul3Vecfl(R.viewmat, nor);
+ }
+
+ Normalize(nor);
+
/* qdn: worldspace */
- shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0];
- shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1];
- shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2];
+ shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
+ shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
+ shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
}
}
else {
@@ -1952,7 +2023,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
}
- if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
+ if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres);
@@ -2123,7 +2194,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
/* texture */
- if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
+ if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres);
@@ -2303,7 +2374,7 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf)
/* texture */
if(tex->type==TEX_IMAGE) {
- do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
+ do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
@@ -2388,7 +2459,7 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t
/* texture */
if(tex->type==TEX_IMAGE) {
- do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
+ do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
rgb= multitex(tex, texvec, dxt, dyt, 0, &texr);
@@ -2421,6 +2492,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
static int firsttime= 1;
Tex *tex;
float texvec[3], dx[2], dy[2];
+ ShadeInputUV *suv= &shi->uv[shi->actuv];
if(firsttime) {
firsttime= 0;
@@ -2432,23 +2504,31 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
if(shi->ys & 1) tex= &tex1; else tex= &tex2; // threadsafe
- texvec[0]= 0.5+0.5*shi->uv[0].uv[0];
- texvec[1]= 0.5+0.5*shi->uv[0].uv[1];
+ texvec[0]= 0.5+0.5*suv->uv[0];
+ texvec[1]= 0.5+0.5*suv->uv[1];
+ texvec[2] = 0; // initalize it because imagewrap looks at it.
if(shi->osatex) {
- dx[0]= 0.5*shi->uv[0].dxuv[0];
- dx[1]= 0.5*shi->uv[0].dxuv[1];
- dy[0]= 0.5*shi->uv[0].dyuv[0];
- dy[1]= 0.5*shi->uv[0].dyuv[1];
+ dx[0]= 0.5*suv->dxuv[0];
+ dx[1]= 0.5*suv->dxuv[1];
+ dy[0]= 0.5*suv->dyuv[0];
+ dy[1]= 0.5*suv->dyuv[1];
}
texr.nor= NULL;
if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
else imagewrap(tex, ima, NULL, texvec, &texr);
-
+
+ if (tex->ima && tex->ima->flag & IMA_DO_PREMUL) {
+ texr.tr *= texr.ta;
+ texr.tg *= texr.ta;
+ texr.tb *= texr.ta;
+ }
+
shi->vcol[0]*= texr.tr;
shi->vcol[1]*= texr.tg;
shi->vcol[2]*= texr.tb;
+ shi->vcol[3]*= texr.ta;
}
/* eof */
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 80b20a8e18e..579905315bb 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -39,8 +39,8 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
-#include "BLI_threads.h"
#include "BLI_jitter.h"
+#include "BLI_threads.h"
#include "MTC_matrixops.h"
#include "MEM_guardedalloc.h"
@@ -69,6 +69,7 @@
#include "shadbuf.h"
#include "shading.h"
#include "sss.h"
+#include "strand.h"
/* own includes */
#include "zbuf.h"
@@ -83,7 +84,7 @@ extern struct Render R;
/* ****************** Spans ******************************* */
/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */
-void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
+void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop)
{
memset(zspan, 0, sizeof(ZSpan));
@@ -92,6 +93,8 @@ void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
zspan->span1= MEM_mallocN(recty*sizeof(float), "zspan");
zspan->span2= MEM_mallocN(recty*sizeof(float), "zspan");
+
+ zspan->clipcrop= clipcrop;
}
void zbuf_free_span(ZSpan *zspan)
@@ -193,7 +196,6 @@ static void zbuf_add_to_span(ZSpan *zspan, float *v1, float *v2)
/* Functions */
/*-----------------------------------------------------------*/
-
void fillrect(int *rect, int x, int y, int val)
{
int len, *drect;
@@ -297,15 +299,15 @@ static APixstr *addpsA(ZSpan *zspan)
return zspan->curpstr;
}
-static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbuffillAc4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
APixstr *ap, *apofs, *apn;
double zxd, zyd, zy0, zverg;
float x0,y0,z0;
float x1,y1,z1,x2,y2,z2,xx1;
float *span1, *span2;
- int *rz, x, y;
- int sn1, sn2, rectx, *rectzofs, my0, my2, mask;
+ int *rz, *rm, x, y;
+ int sn1, sn2, rectx, *rectzofs, *rectmaskofs, my0, my2, mask;
/* init */
zbuf_init_span(zspan);
@@ -350,6 +352,7 @@ static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
/* start-offset in rect */
rectx= zspan->rectx;
rectzofs= (int *)(zspan->arectz+rectx*(my2));
+ rectmaskofs= (int *)(zspan->rectmask+rectx*(my2));
apofs= (zspan->apixbuf+ rectx*(my2));
mask= zspan->mask;
@@ -376,6 +379,7 @@ static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
if(sn2>=sn1) {
zverg= (double)sn1*zxd + zy0;
rz= rectzofs+sn1;
+ rm= rectmaskofs+sn1;
ap= apofs+sn1;
x= sn2-sn1;
@@ -383,26 +387,29 @@ static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
while(x>=0) {
if( (int)zverg < *rz) {
-// int i= zvlnr & 3;
-
- apn= ap;
- while(apn) {
- if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
- if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
- if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
- if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
- if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
- if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
- if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
- if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
-// if(apn->p[i]==0) {apn->p[i]= zvlnr; apn->z[i]= zverg; apn->mask[i]= mask; break; }
-// if(apn->p[i]==zvlnr) {apn->mask[i]|= mask; break; }
- if(apn->next==NULL) apn->next= addpsA(zspan);
- apn= apn->next;
- }
+ if(!zspan->rectmask || (int)zverg > *rm) {
+ // int i= zvlnr & 3;
+
+ apn= ap;
+ while(apn) {
+ if(apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; }
+ if(apn->p[0]==zvlnr && apn->obi[0]==obi) {apn->mask[0]|= mask; break; }
+ if(apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; }
+ if(apn->p[1]==zvlnr && apn->obi[1]==obi) {apn->mask[1]|= mask; break; }
+ if(apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; }
+ if(apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; }
+ if(apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; }
+ if(apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; }
+ // if(apn->p[i]==0) {apn->obi[i]= obi; apn->p[i]= zvlnr; apn->z[i]= zverg; apn->mask[i]= mask; break; }
+ // if(apn->p[i]==zvlnr && apn->obi[i]==obi) {apn->mask[i]|= mask; break; }
+ if(apn->next==NULL) apn->next= addpsA(zspan);
+ apn= apn->next;
+ }
+ }
}
zverg+= zxd;
rz++;
+ rm++;
ap++;
x--;
}
@@ -410,16 +417,17 @@ static void zbuffillAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
zy0-=zyd;
rectzofs-= rectx;
+ rectmaskofs-= rectx;
apofs-= rectx;
}
}
-static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
+static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec2)
{
APixstr *ap, *apn;
- int *rectz;
+ int *rectz, *rectmask;
int start, end, x, y, oldx, oldy, ofs;
int dz, vergz, mask, maxtest=0;
float dx, dy;
@@ -456,37 +464,40 @@ static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
rectz= (int *)(zspan->arectz+zspan->rectx*(oldy) +start);
+ rectmask= (int *)(zspan->rectmask+zspan->rectx*(oldy) +start);
ap= (zspan->apixbuf+ zspan->rectx*(oldy) +start);
if(dy<0) ofs= -zspan->rectx;
else ofs= zspan->rectx;
- for(x= start; x<=end; x++, rectz++, ap++) {
+ for(x= start; x<=end; x++, rectz++, rectmask++, ap++) {
y= floor(v1[1]);
if(y!=oldy) {
oldy= y;
rectz+= ofs;
+ rectmask+= ofs;
ap+= ofs;
}
if(x>=0 && y>=0 && y<zspan->recty) {
if(vergz<*rectz) {
-
- apn= ap;
- while(apn) { /* loop unrolled */
- if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
- if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
- if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
- if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
- if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
- if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
- if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
- if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA(zspan);
- apn= apn->next;
- }
+ if(!zspan->rectmask || vergz>*rectmask) {
+ apn= ap;
+ while(apn) { /* loop unrolled */
+ if(apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
+ if(apn->p[0]==zvlnr && apn->obi[0]==obi) {apn->mask[0]|= mask; break; }
+ if(apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
+ if(apn->p[1]==zvlnr && apn->obi[1]==obi) {apn->mask[1]|= mask; break; }
+ if(apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
+ if(apn->p[2]==zvlnr && apn->obi[2]==obi) {apn->mask[2]|= mask; break; }
+ if(apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
+ if(apn->p[3]==zvlnr && apn->obi[3]==obi) {apn->mask[3]|= mask; break; }
+ if(apn->next==0) apn->next= addpsA(zspan);
+ apn= apn->next;
+ }
+ }
}
}
@@ -524,37 +535,40 @@ static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow
rectz= (int *)( zspan->arectz+ (start)*zspan->rectx+ oldx );
+ rectmask= (int *)( zspan->rectmask+ (start)*zspan->rectx+ oldx );
ap= (zspan->apixbuf+ zspan->rectx*(start) +oldx);
if(dx<0) ofs= -1;
else ofs= 1;
- for(y= start; y<=end; y++, rectz+=zspan->rectx, ap+=zspan->rectx) {
+ for(y= start; y<=end; y++, rectz+=zspan->rectx, rectmask+=zspan->rectx, ap+=zspan->rectx) {
x= floor(v1[0]);
if(x!=oldx) {
oldx= x;
rectz+= ofs;
+ rectmask+= ofs;
ap+= ofs;
}
if(x>=0 && y>=0 && x<zspan->rectx) {
if(vergz<*rectz) {
-
- apn= ap;
- while(apn) { /* loop unrolled */
- if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
- if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
- if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
- if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
- if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
- if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
- if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
- if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
- if(apn->next==0) apn->next= addpsA(zspan);
- apn= apn->next;
- }
-
+ if(!zspan->rectmask || vergz>*rectmask) {
+
+ apn= ap;
+ while(apn) { /* loop unrolled */
+ if(apn->p[0]==0) {apn->obi[0]= obi; apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; }
+ if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; }
+ if(apn->p[1]==0) {apn->obi[1]= obi; apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; }
+ if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; }
+ if(apn->p[2]==0) {apn->obi[2]= obi; apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; }
+ if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; }
+ if(apn->p[3]==0) {apn->obi[3]= obi; apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; }
+ if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; }
+ if(apn->next==0) apn->next= addpsA(zspan);
+ apn= apn->next;
+ }
+ }
}
}
@@ -567,9 +581,9 @@ static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
/* ************* NORMAL ZBUFFER ************ */
-static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
+static void zbufline(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec2)
{
- int *rectz, *rectp;
+ int *rectz, *rectp, *recto, *rectmask;
int start, end, x, y, oldx, oldy, ofs;
int dz, vergz, maxtest= 0;
float dx, dy;
@@ -604,23 +618,30 @@ static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
rectz= zspan->rectz + oldy*zspan->rectx+ start;
rectp= zspan->rectp + oldy*zspan->rectx+ start;
+ recto= zspan->recto + oldy*zspan->rectx+ start;
+ rectmask= zspan->rectmask + oldy*zspan->rectx+ start;
if(dy<0) ofs= -zspan->rectx;
else ofs= zspan->rectx;
- for(x= start; x<=end; x++, rectz++, rectp++) {
+ for(x= start; x<=end; x++, rectz++, rectp++, recto++, rectmask++) {
y= floor(v1[1]);
if(y!=oldy) {
oldy= y;
rectz+= ofs;
rectp+= ofs;
+ recto+= ofs;
+ rectmask+= ofs;
}
if(x>=0 && y>=0 && y<zspan->recty) {
if(vergz<*rectz) {
- *rectz= vergz;
- *rectp= zvlnr;
+ if(!zspan->rectmask || vergz>*rectmask) {
+ *recto= obi;
+ *rectz= vergz;
+ *rectp= zvlnr;
+ }
}
}
@@ -656,23 +677,30 @@ static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
rectz= zspan->rectz + start*zspan->rectx+ oldx;
rectp= zspan->rectp + start*zspan->rectx+ oldx;
+ recto= zspan->recto + start*zspan->rectx+ oldx;
+ rectmask= zspan->rectmask + start*zspan->rectx+ oldx;
if(dx<0) ofs= -1;
else ofs= 1;
- for(y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx) {
+ for(y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx, recto+=zspan->rectx, rectmask+=zspan->rectx) {
x= floor(v1[0]);
if(x!=oldx) {
oldx= x;
rectz+= ofs;
rectp+= ofs;
+ recto+= ofs;
+ rectmask+= ofs;
}
if(x>=0 && y>=0 && x<zspan->rectx) {
if(vergz<*rectz) {
- *rectz= vergz;
- *rectp= zvlnr;
+ if(!zspan->rectmask || vergz>*rectmask) {
+ *rectz= vergz;
+ *rectp= zvlnr;
+ *recto= obi;
+ }
}
}
@@ -683,7 +711,7 @@ static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
}
}
-static void zbufline_onlyZ(ZSpan *zspan, int zvlnr, float *vec1, float *vec2)
+static void zbufline_onlyZ(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec2)
{
int *rectz, *rectz1= NULL;
int start, end, x, y, oldx, oldy, ofs;
@@ -861,7 +889,7 @@ static int clipline(float *v1, float *v2) /* return 0: do not draw */
return 0;
}
-static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco)
+void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco)
{
float div;
@@ -871,26 +899,15 @@ static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco)
zco[2]= 0x7FFFFFFF *(hoco[2]*div);
}
-void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
+void zbufclipwire(ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4)
{
- float vez[20], *f1, *f2, *f3, *f4= 0;
- int c1, c2, c3, c4, ec, and, or;
+ float vez[20];
+ int and, or;
/* edgecode: 1= draw */
- ec = vlr->ec;
if(ec==0) return;
- c1= vlr->v1->clip;
- c2= vlr->v2->clip;
- c3= vlr->v3->clip;
- f1= vlr->v1->ho;
- f2= vlr->v2->ho;
- f3= vlr->v3->ho;
-
- if(vlr->v4) {
- f4= vlr->v4->ho;
- c4= vlr->v4->clip;
-
+ if(ho4) {
and= (c1 & c2 & c3 & c4);
or= (c1 | c2 | c3 | c4);
}
@@ -906,51 +923,51 @@ void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
else { /* clipping */
if(ec & ME_V1V2) {
- QUATCOPY(vez, f1);
- QUATCOPY(vez+4, f2);
+ QUATCOPY(vez, ho1);
+ QUATCOPY(vez+4, ho2);
if( clipline(vez, vez+4)) {
hoco_to_zco(zspan, vez, vez);
hoco_to_zco(zspan, vez+4, vez+4);
- zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
}
}
if(ec & ME_V2V3) {
- QUATCOPY(vez, f2);
- QUATCOPY(vez+4, f3);
+ QUATCOPY(vez, ho2);
+ QUATCOPY(vez+4, ho3);
if( clipline(vez, vez+4)) {
hoco_to_zco(zspan, vez, vez);
hoco_to_zco(zspan, vez+4, vez+4);
- zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
}
}
- if(vlr->v4) {
+ if(ho4) {
if(ec & ME_V3V4) {
- QUATCOPY(vez, f3);
- QUATCOPY(vez+4, f4);
+ QUATCOPY(vez, ho3);
+ QUATCOPY(vez+4, ho4);
if( clipline(vez, vez+4)) {
hoco_to_zco(zspan, vez, vez);
hoco_to_zco(zspan, vez+4, vez+4);
- zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
}
}
if(ec & ME_V4V1) {
- QUATCOPY(vez, f4);
- QUATCOPY(vez+4, f1);
+ QUATCOPY(vez, ho4);
+ QUATCOPY(vez+4, ho1);
if( clipline(vez, vez+4)) {
hoco_to_zco(zspan, vez, vez);
hoco_to_zco(zspan, vez+4, vez+4);
- zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
}
}
}
else {
if(ec & ME_V3V1) {
- QUATCOPY(vez, f3);
- QUATCOPY(vez+4, f1);
+ QUATCOPY(vez, ho3);
+ QUATCOPY(vez+4, ho1);
if( clipline(vez, vez+4)) {
hoco_to_zco(zspan, vez, vez);
hoco_to_zco(zspan, vez+4, vez+4);
- zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
}
}
}
@@ -959,24 +976,52 @@ void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
}
}
- hoco_to_zco(zspan, vez, f1);
- hoco_to_zco(zspan, vez+4, f2);
- hoco_to_zco(zspan, vez+8, f3);
- if(vlr->v4) {
- hoco_to_zco(zspan, vez+12, f4);
+ hoco_to_zco(zspan, vez, ho1);
+ hoco_to_zco(zspan, vez+4, ho2);
+ hoco_to_zco(zspan, vez+8, ho3);
+ if(ho4) {
+ hoco_to_zco(zspan, vez+12, ho4);
- if(ec & ME_V3V4) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez+12);
- if(ec & ME_V4V1) zspan->zbuflinefunc(zspan, zvlnr, vez+12, vez);
+ if(ec & ME_V3V4) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+8, vez+12);
+ if(ec & ME_V4V1) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+12, vez);
}
else {
- if(ec & ME_V3V1) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez);
+ if(ec & ME_V3V1) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+8, vez);
}
- if(ec & ME_V1V2) zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4);
- if(ec & ME_V2V3) zspan->zbuflinefunc(zspan, zvlnr, vez+4, vez+8);
+ if(ec & ME_V1V2) zspan->zbuflinefunc(zspan, obi, zvlnr, vez, vez+4);
+ if(ec & ME_V2V3) zspan->zbuflinefunc(zspan, obi, zvlnr, vez+4, vez+8);
}
+void zbufsinglewire(ZSpan *zspan, int obi, int zvlnr, float *ho1, float *ho2)
+{
+ float f1[4], f2[4];
+ int c1, c2;
+
+ c1= testclip(ho1);
+ c2= testclip(ho2);
+
+ if(c1 | c2) { /* not in the middle */
+ if(!(c1 & c2)) { /* not out completely */
+ QUATCOPY(f1, ho1);
+ QUATCOPY(f2, ho2);
+
+ if(clipline(f1, f2)) {
+ hoco_to_zco(zspan, f1, f1);
+ hoco_to_zco(zspan, f2, f2);
+ zspan->zbuflinefunc(zspan, obi, zvlnr, f1, f2);
+ }
+ }
+ }
+ else {
+ hoco_to_zco(zspan, f1, ho1);
+ hoco_to_zco(zspan, f2, ho2);
+
+ zspan->zbuflinefunc(zspan, obi, zvlnr, f1, f2);
+ }
+}
+
/**
* Fill the z buffer, but invert z order, and add the face index to
* the corresponing face buffer.
@@ -988,13 +1033,15 @@ void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr)
* @param v2 [4 floats, world coordinates] second vertex
* @param v3 [4 floats, world coordinates] third vertex
*/
-static void zbuffillGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbuffillGLinv4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
double zxd, zyd, zy0, zverg;
float x0,y0,z0;
float x1,y1,z1,x2,y2,z2,xx1;
float *span1, *span2;
+ int *rectoofs, *ro;
int *rectpofs, *rp;
+ int *rectmaskofs, *rm;
int *rz, x, y;
int sn1, sn2, rectx, *rectzofs, my0, my2;
@@ -1044,6 +1091,8 @@ static void zbuffillGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float
rectx= zspan->rectx;
rectzofs= (zspan->rectz+rectx*my2);
rectpofs= (zspan->rectp+rectx*my2);
+ rectoofs= (zspan->recto+rectx*my2);
+ rectmaskofs= (zspan->rectmask+rectx*my2);
/* correct span */
sn1= (my0 + my2)/2;
@@ -1069,16 +1118,23 @@ static void zbuffillGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float
zverg= (double)sn1*zxd + zy0;
rz= rectzofs+sn1;
rp= rectpofs+sn1;
+ ro= rectoofs+sn1;
+ rm= rectmaskofs+sn1;
x= sn2-sn1;
while(x>=0) {
if( (int)zverg > *rz || *rz==0x7FFFFFFF) {
- *rz= (int)zverg;
- *rp= zvlnr;
+ if(!zspan->rectmask || (int)zverg > *rm) {
+ *ro= obi;
+ *rz= (int)zverg;
+ *rp= zvlnr;
+ }
}
zverg+= zxd;
rz++;
rp++;
+ ro++;
+ rm++;
x--;
}
}
@@ -1086,18 +1142,22 @@ static void zbuffillGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float
zy0-=zyd;
rectzofs-= rectx;
rectpofs-= rectx;
+ rectoofs-= rectx;
+ rectmaskofs-= rectx;
}
}
/* uses spanbuffers */
-static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbuffillGL4(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
double zxd, zyd, zy0, zverg;
float x0,y0,z0;
float x1,y1,z1,x2,y2,z2,xx1;
float *span1, *span2;
+ int *rectoofs, *ro;
int *rectpofs, *rp;
+ int *rectmaskofs, *rm;
int *rz, x, y;
int sn1, sn2, rectx, *rectzofs, my0, my2;
@@ -1147,6 +1207,8 @@ static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
rectx= zspan->rectx;
rectzofs= (zspan->rectz+rectx*my2);
rectpofs= (zspan->rectp+rectx*my2);
+ rectoofs= (zspan->recto+rectx*my2);
+ rectmaskofs= (zspan->rectmask+rectx*my2);
/* correct span */
sn1= (my0 + my2)/2;
@@ -1172,16 +1234,23 @@ static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
zverg= (double)sn1*zxd + zy0;
rz= rectzofs+sn1;
rp= rectpofs+sn1;
+ ro= rectoofs+sn1;
+ rm= rectmaskofs+sn1;
x= sn2-sn1;
while(x>=0) {
- if( (int)zverg < *rz) {
- *rz= (int)zverg;
- *rp= zvlnr;
+ if((int)zverg < *rz) {
+ if(!zspan->rectmask || (int)zverg > *rm) {
+ *rz= (int)zverg;
+ *rp= zvlnr;
+ *ro= obi;
+ }
}
zverg+= zxd;
rz++;
rp++;
+ ro++;
+ rm++;
x--;
}
}
@@ -1189,6 +1258,8 @@ static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
zy0-=zyd;
rectzofs-= rectx;
rectpofs-= rectx;
+ rectoofs-= rectx;
+ rectmaskofs-= rectx;
}
}
@@ -1204,7 +1275,7 @@ static void zbuffillGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3
*/
/* now: filling two Z values, the closest and 2nd closest */
-static void zbuffillGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbuffillGL_onlyZ(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
double zxd, zyd, zy0, zverg;
float x0,y0,z0;
@@ -1312,7 +1383,105 @@ static void zbuffillGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, floa
}
/* 2d scanconvert for tria, calls func for each x,y coordinate and gives UV barycentrics */
-/* zspan should be initialized, has rect size and span buffers */
+void zspan_scanconvert_strand(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float, float) )
+{
+ float x0, y0, x1, y1, x2, y2, z0, z1, z2, z;
+ float u, v, uxd, uyd, vxd, vyd, uy0, vy0, zxd, zyd, zy0, xx1;
+ float *span1, *span2;
+ int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2;
+
+ /* init */
+ zbuf_init_span(zspan);
+
+ /* set spans */
+ zbuf_add_to_span(zspan, v1, v2);
+ zbuf_add_to_span(zspan, v2, v3);
+ zbuf_add_to_span(zspan, v3, v1);
+
+ /* clipped */
+ if(zspan->minp2==NULL || zspan->maxp2==NULL) return;
+
+ if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1;
+ if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1;
+
+ // printf("my %d %d\n", my0, my2);
+ if(my2<my0) return;
+
+ /* ZBUF DX DY, in floats still */
+ x1= v1[0]- v2[0];
+ x2= v2[0]- v3[0];
+ y1= v1[1]- v2[1];
+ y2= v2[1]- v3[1];
+ z1= v1[2]- v2[2];
+ z2= v2[2]- v3[2];
+
+ x0= y1*z2-z1*y2;
+ y0= z1*x2-x1*z2;
+ z0= x1*y2-y1*x2;
+
+ if(z0==0.0f) return;
+
+ xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2];
+ zxd= -(double)x0/(double)z0;
+ zyd= -(double)y0/(double)z0;
+ zy0= ((double)my2)*zyd + (double)xx1;
+
+ z1= 1.0f; // (u1 - u2)
+ z2= 0.0f; // (u2 - u3)
+
+ x0= y1*z2-z1*y2;
+ y0= z1*x2-x1*z2;
+
+ xx1= (x0*v1[0] + y0*v1[1])/z0 + 1.0f;
+ uxd= -(double)x0/(double)z0;
+ uyd= -(double)y0/(double)z0;
+ uy0= ((double)my2)*uyd + (double)xx1;
+
+ z1= -1.0f; // (v1 - v2)
+ z2= 1.0f; // (v2 - v3)
+
+ x0= y1*z2-z1*y2;
+ y0= z1*x2-x1*z2;
+
+ xx1= (x0*v1[0] + y0*v1[1])/z0;
+ vxd= -(double)x0/(double)z0;
+ vyd= -(double)y0/(double)z0;
+ vy0= ((double)my2)*vyd + (double)xx1;
+
+ /* correct span */
+ sn1= (my0 + my2)/2;
+ if(zspan->span1[sn1] < zspan->span2[sn1]) {
+ span1= zspan->span1+my2;
+ span2= zspan->span2+my2;
+ }
+ else {
+ span1= zspan->span2+my2;
+ span2= zspan->span1+my2;
+ }
+
+ for(y=my2; y>=my0; y--, span1--, span2--) {
+
+ sn1= floor(*span1);
+ sn2= floor(*span2);
+ sn1++;
+
+ if(sn2>=rectx) sn2= rectx-1;
+ if(sn1<0) sn1= 0;
+
+ u= (double)sn1*uxd + uy0;
+ v= (double)sn1*vxd + vy0;
+ z= (double)sn1*zxd + zy0;
+
+ for(x= sn1; x<=sn2; x++, u+=uxd, v+=vxd, z+=zxd)
+ func(handle, x, y, u, v, z);
+
+ uy0 -= uyd;
+ vy0 -= vyd;
+ zy0 -= zyd;
+ }
+}
+
+/* scanconvert for strand triangles, calls func for each x,y coordinate and gives UV barycentrics and z */
void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *v3, void (*func)(void *, int, int, float, float) )
{
@@ -1416,7 +1585,7 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
* @param a index for coordinate (x, y, or z)
*/
-static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a)
+static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop)
{
float da,dw,u1=0.0,u2=1.0;
float v13;
@@ -1432,9 +1601,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a
v13= v1[3];
}
else {
- /* XXXXX EVIL! this is a R global, whilst this function can be called for shadow, before R was set */
- dw= R.clipcrop*(v2[3]-v1[3]);
- v13= R.clipcrop*v1[3];
+ dw= clipcrop*(v2[3]-v1[3]);
+ v13= clipcrop*v1[3];
}
/* according the original article by Liang&Barsky, for clipping of
* homogenous coordinates with viewplane, the value of "0" is used instead of "-w" .
@@ -1543,9 +1711,115 @@ void projectvert(float *v1, float winmat[][4], float *adr)
adr[3]= x*winmat[0][3]+ y*winmat[1][3]+ z*winmat[2][3]+ winmat[3][3];
}
+/* ------------------------------------------------------------------------- */
+
+#define ZBUF_PROJECT_CACHE_SIZE 256
+
+typedef struct ZbufProjectCache {
+ int index, clip;
+ float ho[4];
+} ZbufProjectCache;
+
+static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size)
+{
+ int i;
+
+ if(size > ZBUF_PROJECT_CACHE_SIZE)
+ size= ZBUF_PROJECT_CACHE_SIZE;
+
+ memset(cache, 0, sizeof(ZbufProjectCache)*size);
+ for(i=0; i<size; i++)
+ cache[i].index= -1;
+}
+
+static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho)
+{
+ int clipflag, cindex= index & 255;
+
+ if(cache[cindex].index == index) {
+ QUATCOPY(ho, cache[cindex].ho);
+ return cache[cindex].clip;
+ }
+ else {
+ projectvert(co, winmat, ho);
+ clipflag= testclip(ho);
+
+ QUATCOPY(cache[cindex].ho, ho);
+ cache[cindex].clip= clipflag;
+ cache[cindex].index= index;
+
+ return clipflag;
+ }
+}
+
+static void zbuffer_part_bounds(Render *re, RenderPart *pa, float *bounds)
+{
+ bounds[0]= (2*pa->disprect.xmin - re->winx-1)/(float)re->winx;
+ bounds[1]= (2*pa->disprect.xmax - re->winx+1)/(float)re->winx;
+ bounds[2]= (2*pa->disprect.ymin - re->winy-1)/(float)re->winy;
+ bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy;
+}
+
+static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho)
+{
+ float vec[3], wco;
+ int clipflag= 0, cindex= index & 255;
+
+ if(cache[cindex].index == index) {
+ QUATCOPY(ho, cache[cindex].ho);
+ return cache[cindex].clip;
+ }
+ else {
+ VECCOPY(vec, co)
+ projectvert(co, winmat, ho);
+
+ wco= ho[3];
+ if(ho[0] > bounds[1]*wco) clipflag |= 1;
+ else if(ho[0]< bounds[0]*wco) clipflag |= 2;
+ if(ho[1] > bounds[3]*wco) clipflag |= 4;
+ else if(ho[1]< bounds[2]*wco) clipflag |= 8;
+
+ QUATCOPY(cache[cindex].ho, ho);
+ cache[cindex].clip= clipflag;
+ cache[cindex].index= index;
+
+ return clipflag;
+ }
+}
+
+void zbuf_render_project(float winmat[][4], float *co, float *ho)
+{
+ float vec[3];
+
+ VECCOPY(vec, co)
+ projectvert(vec, winmat, ho);
+}
+
+void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4])
+{
+ float panomat[4][4];
+
+ if(re->r.mode & R_PANORAMA) {
+ Mat4One(panomat);
+ panomat[0][0]= re->panoco;
+ panomat[0][2]= re->panosi;
+ panomat[2][0]= -re->panosi;
+ panomat[2][2]= re->panoco;
+
+ if(duplimat)
+ Mat4MulSerie(winmat, re->winmat, panomat, duplimat, 0, 0, 0, 0, 0);
+ else
+ Mat4MulMat4(winmat, panomat, re->winmat);
+ }
+ else if(duplimat)
+ Mat4MulMat4(winmat, duplimat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
+}
+
/* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */
-void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
+void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3)
{
float *vlzp[32][3], labda[3][2];
float vez[400], *trias[40];
@@ -1586,9 +1860,9 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
else if (b==1) arg= 0;
else arg= 1;
- clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg);
- clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg);
- clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg);
+ clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg, zspan->clipcrop);
+ clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg, zspan->clipcrop);
+ clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg, zspan->clipcrop);
if(b2==0 && b3==1) {
/* completely 'in', but we copy because of last for() loop in this section */;
@@ -1644,7 +1918,7 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
}
for(b=1;b<clvl;b++) {
if(vlzp[b][0]) {
- zspan->zbuffunc(zspan, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2], NULL);
+ zspan->zbuffunc(zspan, obi, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2], NULL);
}
}
return;
@@ -1655,10 +1929,10 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1,
hoco_to_zco(zspan, vez, f1);
hoco_to_zco(zspan, vez+4, f2);
hoco_to_zco(zspan, vez+8, f3);
- zspan->zbuffunc(zspan, zvlnr, vez,vez+4,vez+8, NULL);
+ zspan->zbuffunc(zspan, obi, zvlnr, vez,vez+4,vez+8, NULL);
}
-void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4)
+void zbufclip4(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4)
{
float vez[16];
@@ -1666,8 +1940,8 @@ void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *
if(c1 & c2 & c3 & c4) { /* completely out */
return;
} else { /* clipping */
- zbufclip(zspan, zvlnr, f1, f2, f3, c1, c2, c3);
- zbufclip(zspan, zvlnr, f1, f3, f4, c1, c3, c4);
+ zbufclip(zspan, obi, zvlnr, f1, f2, f3, c1, c2, c3);
+ zbufclip(zspan, obi, zvlnr, f1, f3, f4, c1, c3, c4);
}
return;
}
@@ -1678,150 +1952,313 @@ void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *
hoco_to_zco(zspan, vez+8, f3);
hoco_to_zco(zspan, vez+12, f4);
- zspan->zbuffunc(zspan, zvlnr, vez, vez+4, vez+8, vez+12);
+ zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, vez+12);
}
+/* ************** ZMASK ******************************** */
-/* ***************** ZBUFFER MAIN ROUTINES **************** */
+#define EXTEND_PIXEL(a) if(temprectp[a]) {z+= rectz[a]; tot++;}
-void set_part_zbuf_clipflag(RenderPart *pa)
+/* changes the zbuffer to be ready for z-masking: applies an extend-filter, and then clears */
+static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg)
{
- VertRen *ver=NULL;
- float minx, miny, maxx, maxy, wco;
- int v;
- char *clipflag;
-
- /* flags stored in part now */
- clipflag= pa->clipflag= MEM_mallocN(R.totvert+1, "part clipflags");
-
- minx= (2*pa->disprect.xmin - R.winx-1)/(float)R.winx;
- maxx= (2*pa->disprect.xmax - R.winx+1)/(float)R.winx;
- miny= (2*pa->disprect.ymin - R.winy-1)/(float)R.winy;
- maxy= (2*pa->disprect.ymax - R.winy+1)/(float)R.winy;
-
- for(v=0; v<R.totvert; v++, clipflag++) {
- if((v & 255)==0)
- ver= RE_findOrAddVert(&R, v);
- else ver++;
+ int len=0, x, y;
+ int *temprectp;
+ int row1, row2, row3, *curp, *curz;
+
+ temprectp= MEM_dupallocN(rectp);
+
+ /* extend: if pixel is not filled in, we check surrounding pixels and average z value */
+
+ for(y=1; y<=ys; y++) {
+ /* setup row indices */
+ row1= (y-2)*xs;
+ row2= row1 + xs;
+ row3= row2 + xs;
+ if(y==1)
+ row1= row2;
+ else if(y==ys)
+ row3= row2;
+
+ curp= rectp + (y-1)*xs;
+ curz= rectz + (y-1)*xs;
- wco= ver->ho[3];
+ for(x=0; x<xs; x++, curp++, curz++) {
+ if(curp[0]==0) {
+ int tot= 0;
+ float z= 0.0f;
+
+ EXTEND_PIXEL(row1);
+ EXTEND_PIXEL(row2);
+ EXTEND_PIXEL(row3);
+ EXTEND_PIXEL(row1 + 1);
+ EXTEND_PIXEL(row3 + 1);
+ if(x!=xs-1) {
+ EXTEND_PIXEL(row1 + 2);
+ EXTEND_PIXEL(row2 + 2);
+ EXTEND_PIXEL(row3 + 2);
+ }
+ if(tot) {
+ len++;
+ curz[0]= (int)(z/(float)tot);
+ curp[0]= -1; /* env */
+ }
+ }
+
+ if(x!=0) {
+ row1++; row2++; row3++;
+ }
+ }
+ }
- *clipflag= 0;
- if( ver->ho[0] > maxx*wco) *clipflag |= 1;
- else if( ver->ho[0]< minx*wco) *clipflag |= 2;
- if( ver->ho[1] > maxy*wco) *clipflag |= 4;
- else if( ver->ho[1]< miny*wco) *clipflag |= 8;
+ MEM_freeN(temprectp);
+
+ if(neg); /* z values for negative are already correct */
+ else {
+ /* clear not filled z values */
+ for(len= xs*ys -1; len>=0; len--) {
+ if(rectp[len]==0) {
+ rectz[len] = -0x7FFFFFFF;
+ rectp[len]= -1; /* env code */
+ }
+ }
}
}
-void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
+
+
+
+/* ***************** ZBUFFER MAIN ROUTINES **************** */
+
+void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, ZSpan*, int, void*), void *data)
{
- ZSpan zspan;
+ ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
+ ZSpan zspans[16], *zspan; /* 16 = RE_MAX_OSA */
VlakRen *vlr= NULL;
VertRen *v1, *v2, *v3, *v4;
Material *ma=0;
- int v, zvlnr;
- short nofill=0, env=0, wire=0, all_z= layflag & SCE_LAY_ALL_Z;
- char *clipflag= pa->clipflag;
-
- zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
-
- /* needed for transform from hoco to zbuffer co */
- zspan.zmulx= ((float)R.winx)/2.0;
- zspan.zmuly= ((float)R.winy)/2.0;
-
- if(R.osa) {
- zspan.zofsx= -pa->disprect.xmin - R.jit[pa->sample][0];
- zspan.zofsy= -pa->disprect.ymin - R.jit[pa->sample][1];
- }
- else if(R.i.curblur) {
- zspan.zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
- zspan.zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
- }
- else {
- zspan.zofsx= -pa->disprect.xmin;
- zspan.zofsy= -pa->disprect.ymin;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ unsigned int lay= rl->lay, lay_zmask= rl->lay_zmask;
+ int i, v, zvlnr, zsample, samples, c1, c2, c3, c4=0;
+ short nofill=0, env=0, wire=0, zmaskpass=0;
+ short all_z= (rl->layflag & SCE_LAY_ALL_Z) && !(rl->layflag & SCE_LAY_ZMASK);
+ short neg_zmask= (rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK);
+
+ samples= (R.osa? R.osa: 1);
+ samples= MIN2(4, samples-pa->sample);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ zbuffer_part_bounds(&R, pa, bounds);
+ zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop);
+
+ /* needed for transform from hoco to zbuffer co */
+ zspan->zmulx= ((float)R.winx)/2.0;
+ zspan->zmuly= ((float)R.winy)/2.0;
+
+ if(R.osa) {
+ zspan->zofsx= -pa->disprect.xmin - R.jit[pa->sample+zsample][0];
+ zspan->zofsy= -pa->disprect.ymin - R.jit[pa->sample+zsample][1];
+ }
+ else if(R.i.curblur) {
+ zspan->zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
+ zspan->zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
+ }
+ else {
+ zspan->zofsx= -pa->disprect.xmin;
+ zspan->zofsy= -pa->disprect.ymin;
+ }
+ /* to center the sample position */
+ zspan->zofsx -= 0.5f;
+ zspan->zofsy -= 0.5f;
+
+ /* the buffers */
+ if(zsample == samples-1) {
+ zspan->rectp= pa->rectp;
+ zspan->recto= pa->recto;
+
+ if(neg_zmask)
+ zspan->rectz= pa->rectmask;
+ else
+ zspan->rectz= pa->rectz;
+ }
+ else {
+ zspan->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
+ zspan->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
+ zspan->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ }
+
+ fillrect(zspan->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+ fillrect(zspan->rectp, pa->rectx, pa->recty, 0);
+ fillrect(zspan->recto, pa->rectx, pa->recty, 0);
}
- /* to center the sample position */
- zspan.zofsx -= 0.5f;
- zspan.zofsy -= 0.5f;
-
- /* the buffers */
- zspan.rectz= pa->rectz;
- zspan.rectp= pa->rectp;
- fillrect(pa->rectp, pa->rectx, pa->recty, 0);
- fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+
+ /* in case zmask we fill Z for objects in lay_zmask first, then clear Z, and then do normal zbuffering */
+ if(rl->layflag & SCE_LAY_ZMASK)
+ zmaskpass= 1;
- /* filling methods */
- zspan.zbuffunc= zbuffillGL4;
- zspan.zbuflinefunc= zbufline;
+ for(; zmaskpass >=0; zmaskpass--) {
+ ma= NULL;
- for(v=0; v<R.totvlak; v++) {
+ /* filling methods */
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
- if((v & 255)==0) vlr= R.vlaknodes[v>>8].vlak;
- else vlr++;
-
- if((vlr->flag & R_VISIBLE)) {
- /* three cases, visible for render, only z values and nothing */
- if(vlr->lay & lay) {
- if(vlr->mat!=ma) {
- ma= vlr->mat;
- nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
- env= (ma->mode & MA_ENV);
- wire= (ma->mode & MA_WIRE);
-
- if(ma->mode & MA_ZINV) zspan.zbuffunc= zbuffillGLinv4;
- else zspan.zbuffunc= zbuffillGL4;
- }
- }
- else if(all_z) {
- env= 1;
- nofill= 0;
- ma= NULL;
- }
- else {
- nofill= 1;
- ma= NULL; /* otherwise nofill can hang */
+ if(zmaskpass && neg_zmask)
+ zspan->zbuffunc= zbuffillGLinv4;
+ else
+ zspan->zbuffunc= zbuffillGL4;
+ zspan->zbuflinefunc= zbufline;
+ }
+
+ /* regular zbuffering loop, does all sample buffers */
+ for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ /* continue happens in 2 different ways... zmaskpass only does lay_zmask stuff */
+ if(zmaskpass) {
+ if((obi->lay & lay_zmask)==0)
+ continue;
}
+ else if(!all_z && !(obi->lay & (lay|lay_zmask)))
+ continue;
- if(nofill==0) {
- unsigned short partclip;
-
- v1= vlr->v1;
- v2= vlr->v2;
- v3= vlr->v3;
- v4= vlr->v4;
-
- /* partclipping doesn't need viewplane clipping */
- partclip= clipflag[v1->index] & clipflag[v2->index] & clipflag[v3->index];
- if(v4)
- partclip &= clipflag[v4->index];
-
- if(partclip==0) {
-
- if(env) zvlnr= -1;
- else zvlnr= v+1;
-
- if(wire) zbufclipwire(&zspan, zvlnr, vlr);
- else {
- /* strands allow to be filled in as quad */
- if(v4 && (vlr->flag & R_STRAND)) {
- zbufclip4(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v4->ho, v1->clip, v2->clip, v3->clip, v4->clip);
+ if(obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(&R, obi->mat, winmat);
+ else
+ zbuf_make_winmat(&R, NULL, winmat);
+
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
+ zbuf_project_cache_clear(cache, obr->totvert);
+
+ for(v=0; v<obr->totvlak; v++) {
+ if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
+ else vlr++;
+
+ /* the cases: visible for render, only z values, zmask, nothing */
+ if(obi->lay & lay) {
+ if(vlr->mat!=ma) {
+ ma= vlr->mat;
+ nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
+ env= (ma->mode & MA_ENV);
+ wire= (ma->mode & MA_WIRE);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ if(ma->mode & MA_ZINV || (zmaskpass && neg_zmask))
+ zspans[zsample].zbuffunc= zbuffillGLinv4;
+ else
+ zspans[zsample].zbuffunc= zbuffillGL4;
}
- else {
- zbufclip(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v1->clip, v2->clip, v3->clip);
- if(v4) {
- if(zvlnr>0) zvlnr+= RE_QUAD_OFFS;
- zbufclip(&zspan, zvlnr, v1->ho, v3->ho, v4->ho, v1->clip, v3->clip, v4->clip);
+ }
+ }
+ else if(all_z || (obi->lay & lay_zmask)) {
+ env= 1;
+ nofill= 0;
+ ma= NULL;
+ }
+ else {
+ nofill= 1;
+ ma= NULL; /* otherwise nofill can hang */
+ }
+
+ if(!(vlr->flag & R_HIDDEN) && nofill==0) {
+ unsigned short partclip;
+
+ v1= vlr->v1;
+ v2= vlr->v2;
+ v3= vlr->v3;
+ v4= vlr->v4;
+
+ c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+
+ /* partclipping doesn't need viewplane clipping */
+ partclip= c1 & c2 & c3;
+ if(v4) {
+ c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ partclip &= c4;
+ }
+
+ if(partclip==0) {
+
+ if(env) zvlnr= -1;
+ else zvlnr= v+1;
+
+ c1= testclip(ho1);
+ c2= testclip(ho2);
+ c3= testclip(ho3);
+ if(v4)
+ c4= testclip(ho4);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ if(wire) {
+ if(v4)
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ else
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
+ }
+ else {
+ /* strands allow to be filled in as quad */
+ if(v4 && (vlr->flag & R_STRAND)) {
+ zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ }
+ else {
+ zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3);
+ if(v4)
+ zbufclip(zspan, i, (env)? zvlnr: zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4);
+ }
}
}
}
}
}
}
+
+ /* clear all z to close value, so it works as mask for next passes (ztra+strand) */
+ if(zmaskpass) {
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ if(neg_zmask) {
+ zspan->rectmask= zspan->rectz;
+ if(zsample == samples-1)
+ zspan->rectz= pa->rectz;
+ else
+ zspan->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
+ fillrect(zspan->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
+
+ zmask_rect(zspan->rectmask, zspan->rectp, pa->rectx, pa->recty, 1);
+ }
+ else
+ zmask_rect(zspan->rectz, zspan->rectp, pa->rectx, pa->recty, 0);
+ }
+ }
+ }
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ if(fillfunc)
+ fillfunc(pa, zspan, pa->sample+zsample, data);
+
+ if(zsample != samples-1) {
+ MEM_freeN(zspan->rectz);
+ MEM_freeN(zspan->rectp);
+ MEM_freeN(zspan->recto);
+ if(zspan->rectmask)
+ MEM_freeN(zspan->rectmask);
+ }
+
+ zbuf_free_span(zspan);
}
-
- zbuf_free_span(&zspan);
}
typedef struct {
@@ -1869,10 +2306,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
/* needed for projectvert */
MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat);
- /* for clipping... bad stuff actually */
- R.clipcrop= 1.0f;
-
- zbuf_alloc_span(&zspan, vw->rectx, vw->recty);
+ /* 1.0f for clipping in clippyra()... bad stuff actually */
+ zbuf_alloc_span(&zspan, vw->rectx, vw->recty, 1.0f);
zspan.zmulx= ((float)vw->rectx)/2.0;
zspan.zmuly= ((float)vw->recty)/2.0;
zspan.zofsx= -0.5f;
@@ -1881,6 +2316,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
/* the buffers */
zspan.rectz= (int *)vw->rectz;
zspan.rectp= (int *)vw->rect;
+ zspan.recto= MEM_callocN(sizeof(int)*vw->rectx*vw->recty, "radiorecto");
fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF);
fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF);
@@ -1909,59 +2345,75 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re
}
if(rn->v4)
- zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
else
- zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
+ zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
}
}
}
else { /* radio render */
+ ObjectRen *obr;
VlakRen *vlr=NULL;
- RadFace *rf;
+ RadFace **radface, *rf;
int totface=0;
- for(a=0; a<re->totvlak; a++) {
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak; else vlr++;
-
- if(vlr->radface) {
- rf= vlr->radface;
- if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */
-
- if( rf->flag & RAD_TWOSIDED) zvlnr= totface;
- else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
- else zvlnr= totface;
-
- c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]);
- c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]);
- c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]);
-
- if(vlr->v4) {
- c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]);
+ /* note: radio render doesn't support duplis */
+ for(obr=re->objecttable.first; obr; obr=obr->next) {
+ hashlist_projectvert(NULL, NULL, NULL); /* clear hashlist */
+
+ for(a=0; a<obr->totvlak; a++) {
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
+
+ if((radface=RE_vlakren_get_radface(obr, vlr, 0)) && *radface) {
+ rf= *radface;
+ if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */
+
+ if( rf->flag & RAD_TWOSIDED) zvlnr= totface;
+ else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */
+ else zvlnr= totface;
+
+ c1= hashlist_projectvert(vlr->v1->co, winmat, hoco[0]);
+ c2= hashlist_projectvert(vlr->v2->co, winmat, hoco[1]);
+ c3= hashlist_projectvert(vlr->v3->co, winmat, hoco[2]);
+
+ if(vlr->v4) {
+ c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]);
+ }
+
+ if(vlr->v4)
+ zbufclip4(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
+ else
+ zbufclip(&zspan, 0, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
}
-
- if(vlr->v4)
- zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4);
- else
- zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3);
+ totface++;
}
- totface++;
}
}
}
+ MEM_freeN(zspan.recto);
zbuf_free_span(&zspan);
}
-void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx, float jity)
+void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity)
{
+ ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspan;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
VlakRen *vlr= NULL;
Material *ma= NULL;
- int a, ok=1, lay= -1;
+ StrandSegment sseg;
+ StrandRen *strand= NULL;
+ StrandVert *svert;
+ StrandBound *sbound;
+ float obwinmat[4][4], ho1[4], ho2[4], ho3[4], ho4[4];
+ int a, b, c, i, c1, c2, c3, c4, ok=1, lay= -1;
if(lar->mode & LA_LAYER) lay= lar->lay;
- zbuf_alloc_span(&zspan, size, size);
+ /* 1.0f for clipping in clippyra()... bad stuff actually */
+ zbuf_alloc_span(&zspan, size, size, 1.0f);
zspan.zmulx= ((float)size)/2.0;
zspan.zmuly= ((float)size)/2.0;
zspan.zofsx= jitx;
@@ -1979,28 +2431,117 @@ void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx,
zspan.zbuflinefunc= zbufline_onlyZ;
zspan.zbuffunc= zbuffillGL_onlyZ;
- for(a=0; a<re->totvlak; a++) {
+ for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if(obr->ob==re->excludeob)
+ continue;
+ else if(!(obi->lay & lay))
+ continue;
+
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(obwinmat, obi->mat, winmat);
+ else
+ Mat4CpyMat4(obwinmat, winmat);
+
+ if(clip_render_object(obi->obr->boundbox, NULL, obwinmat))
+ continue;
+
+ zbuf_project_cache_clear(cache, obr->totvert);
- if((a & 255)==0) vlr= re->vlaknodes[a>>8].vlak;
- else vlr++;
+ /* faces */
+ for(a=0; a<obr->totvlak; a++) {
+
+ if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
+ else vlr++;
+
+ /* note, these conditions are copied in shadowbuf_autoclip() */
+ if(vlr->mat!= ma) {
+ ma= vlr->mat;
+ ok= 1;
+ if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ }
+
+ if(ok && (obi->lay & lay) && !(vlr->flag & R_HIDDEN)) {
+ c1= zbuf_shadow_project(cache, vlr->v1->index, obwinmat, vlr->v1->co, ho1);
+ c2= zbuf_shadow_project(cache, vlr->v2->index, obwinmat, vlr->v2->co, ho2);
+ c3= zbuf_shadow_project(cache, vlr->v3->index, obwinmat, vlr->v3->co, ho3);
+
+ if((ma->mode & MA_WIRE) || (vlr->flag & R_STRAND)) {
+ if(vlr->v4) {
+ c4= zbuf_shadow_project(cache, vlr->v4->index, obwinmat, vlr->v4->co, ho4);
+ zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ }
+ else
+ zbufclipwire(&zspan, 0, a+1, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
+ }
+ else {
+ if(vlr->v4) {
+ c4= zbuf_shadow_project(cache, vlr->v4->index, obwinmat, vlr->v4->co, ho4);
+ zbufclip4(&zspan, 0, 0, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ }
+ else
+ zbufclip(&zspan, 0, 0, ho1, ho2, ho3, c1, c2, c3);
+ }
+ }
- /* note, these conditions are copied in shadowbuf_autoclip() */
- if(vlr->mat!= ma) {
- ma= vlr->mat;
- ok= 1;
- if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ if((a & 255)==255 && re->test_break())
+ break;
}
-
- if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
- if(ma->mode & MA_WIRE) zbufclipwire(&zspan, a+1, vlr);
- else if(vlr->flag & R_STRAND) zbufclipwire(&zspan, a+1, vlr);
- else {
- if(vlr->v4)
- zbufclip4(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
- else
- zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
+
+ /* strands */
+ if(obr->strandbuf) {
+ /* for each bounding box containing a number of strands */
+ sbound= obr->strandbuf->bound;
+ for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
+ if(clip_render_object(sbound->boundbox, NULL, obwinmat))
+ continue;
+
+ /* for each strand in this bounding box */
+ for(a=sbound->start; a<sbound->end; a++) {
+ strand= RE_findOrAddStrand(obr, a);
+
+ sseg.obi= obi;
+ sseg.buffer= strand->buffer;
+ sseg.sqadaptcos= sseg.buffer->adaptcos;
+ sseg.sqadaptcos *= sseg.sqadaptcos;
+ sseg.strand= strand;
+ svert= strand->vert;
+
+ /* note, these conditions are copied in shadowbuf_autoclip() */
+ if(sseg.buffer->ma!= ma) {
+ ma= sseg.buffer->ma;
+ ok= 1;
+ if((ma->mode & MA_SHADBUF)==0) ok= 0;
+ }
+
+ if(ok && (sseg.buffer->lay & lay)) {
+ zbuf_project_cache_clear(cache, strand->totvert);
+
+ for(b=0; b<strand->totvert-1; b++, svert++) {
+ sseg.v[0]= (b > 0)? (svert-1): svert;
+ sseg.v[1]= svert;
+ sseg.v[2]= svert+1;
+ sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1;
+
+ c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1);
+ c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2);
+ c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3);
+ c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4);
+
+ if(!(c1 & c2 & c3 & c4))
+ render_strand_segment(re, winmat, NULL, &zspan, 1, &sseg);
+ }
+ }
+
+ if((a & 255)==255 && re->test_break())
+ break;
+ }
}
}
+
+ if(re->test_break())
+ break;
}
/* merge buffers */
@@ -2014,12 +2555,11 @@ void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size, float jitx,
zbuf_free_span(&zspan);
}
-static void zbuffill_sss(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4)
+static void zbuffill_sss(ZSpan *zspan, int obi, int zvlnr, float *v1, float *v2, float *v3, float *v4)
{
double zxd, zyd, zy0, z;
float x0, y0, x1, y1, x2, y2, z0, z1, z2, xx1, *span1, *span2;
int x, y, sn1, sn2, rectx= zspan->rectx, my0, my2;
-
/* init */
zbuf_init_span(zspan);
@@ -2082,23 +2622,27 @@ static void zbuffill_sss(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v
z= (double)sn1*zxd + zy0;
for(x= sn1; x<=sn2; x++, z+=zxd)
- zspan->sss_func(zspan->sss_handle, zvlnr, x, y, z);
+ zspan->sss_func(zspan->sss_handle, obi, zvlnr, x, y, z);
zy0 -= zyd;
}
}
-void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void *, int, int, int, int))
+void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int))
{
+ ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspan;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
VlakRen *vlr= NULL;
VertRen *v1, *v2, *v3, *v4;
Material *ma=0, *sss_ma= R.sss_mat;
+ float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ int i, v, zvlnr, c1, c2, c3, c4=0;
short nofill=0, env=0, wire=0;
- char *clipflag= pa->clipflag;
- int v, zvlnr;
- zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
+ zbuffer_part_bounds(&R, pa, bounds);
+ zbuf_alloc_span(&zspan, pa->rectx, pa->recty, R.clipcrop);
zspan.sss_handle= handle;
zspan.sss_func= func;
@@ -2116,59 +2660,87 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
/* fill front and back zbuffer */
if(pa->rectz) {
+ fillrect(pa->recto, pa->rectx, pa->recty, 0);
fillrect(pa->rectp, pa->rectx, pa->recty, 0);
fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF);
}
if(pa->rectbackz) {
+ fillrect(pa->rectbacko, pa->rectx, pa->recty, 0);
fillrect(pa->rectbackp, pa->rectx, pa->recty, 0);
fillrect(pa->rectbackz, pa->rectx, pa->recty, -0x7FFFFFFF);
}
- for(v=0; v<R.totvlak; v++) {
- if((v & 255)==0) vlr= R.vlaknodes[v>>8].vlak;
- else vlr++;
-
- if((vlr->flag & R_VISIBLE) && material_in_material(vlr->mat, sss_ma)) {
- /* three cases, visible for render, only z values and nothing */
- if(vlr->lay & lay) {
- if(vlr->mat!=ma) {
- ma= vlr->mat;
- nofill= ma->mode & MA_ONLYCAST;
- env= (ma->mode & MA_ENV);
- wire= (ma->mode & MA_WIRE);
- }
- }
- else {
- nofill= 1;
- ma= NULL; /* otherwise nofill can hang */
- }
+ for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if(!(obi->lay & lay))
+ continue;
+
+ if(obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(&R, obi->mat, winmat);
+ else
+ zbuf_make_winmat(&R, NULL, winmat);
+
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
+ zbuf_project_cache_clear(cache, obr->totvert);
+
+ for(v=0; v<obr->totvlak; v++) {
+ if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
+ else vlr++;
- if(nofill==0 && wire==0 && env==0) {
- unsigned short partclip;
-
- v1= vlr->v1;
- v2= vlr->v2;
- v3= vlr->v3;
- v4= vlr->v4;
-
- /* partclipping doesn't need viewplane clipping */
- partclip= clipflag[v1->index] & clipflag[v2->index] & clipflag[v3->index];
- if(v4)
- partclip &= clipflag[v4->index];
+ if(material_in_material(vlr->mat, sss_ma)) {
+ /* three cases, visible for render, only z values and nothing */
+ if(obi->lay & lay) {
+ if(vlr->mat!=ma) {
+ ma= vlr->mat;
+ nofill= ma->mode & MA_ONLYCAST;
+ env= (ma->mode & MA_ENV);
+ wire= (ma->mode & MA_WIRE);
+ }
+ }
+ else {
+ nofill= 1;
+ ma= NULL; /* otherwise nofill can hang */
+ }
+ if(nofill==0 && wire==0 && env==0) {
+ unsigned short partclip;
+
+ v1= vlr->v1;
+ v2= vlr->v2;
+ v3= vlr->v3;
+ v4= vlr->v4;
- if(partclip==0) {
- zvlnr= v+1;
- zbufclip(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v1->clip, v2->clip, v3->clip);
+ c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+
+ /* partclipping doesn't need viewplane clipping */
+ partclip= c1 & c2 & c3;
if(v4) {
- zvlnr+= RE_QUAD_OFFS;
- zbufclip(&zspan, zvlnr, v1->ho, v3->ho, v4->ho, v1->clip, v3->clip, v4->clip);
+ c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ partclip &= c4;
+ }
+
+ if(partclip==0) {
+ c1= testclip(ho1);
+ c2= testclip(ho2);
+ c3= testclip(ho3);
+
+ zvlnr= v+1;
+ zbufclip(&zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3);
+ if(v4) {
+ c4= testclip(ho4);
+ zbufclip(&zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4);
+ }
}
}
}
}
}
-
+
zbuf_free_span(&zspan);
}
@@ -2374,20 +2946,51 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove)
}
}
+/* in: two vectors, first vector points from origin back in time, 2nd vector points to future */
+/* we make this into 3 points, center point is (0,0) */
+/* and offset the center point just enough to make curve go through midpoint */
+
+static void quad_bezier_2d(float *result, float *v1, float *v2, float *ipodata)
+{
+ float p1[2], p2[2], p3[2];
+
+ p3[0]= -v2[0];
+ p3[1]= -v2[1];
+
+ p1[0]= v1[0];
+ p1[1]= v1[1];
+
+ /* official formula 2*p2 - .5*p1 - .5*p3 */
+ p2[0]= -0.5*p1[0] - 0.5*p3[0];
+ p2[1]= -0.5*p1[1] - 0.5*p3[1];
+
+ result[0]= ipodata[0]*p1[0] + ipodata[1]*p2[0] + ipodata[2]*p3[0];
+ result[1]= ipodata[0]*p1[1] + ipodata[1]*p2[1] + ipodata[2]*p3[1];
+}
+
+static void set_quad_bezier_ipo(float fac, float *data)
+{
+ float mfac= (1.0f-fac);
+
+ data[0]= mfac*mfac;
+ data[1]= 2.0f*mfac*fac;
+ data[2]= fac*fac;
+}
+
void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect)
{
ZSpan zspan;
DrawBufPixel *rectdraw, *dr;
static float jit[16][2];
float v1[3], v2[3], v3[3], v4[3], fx, fy;
- float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz1, *dz2, *rectz, *minvecbufrect= NULL;
+ float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz, *dz1, *dz2, *rectz, *minvecbufrect= NULL;
float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed;
int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples;
int tsktsk= 0;
static int firsttime= 1;
char *rectmove, *dm;
- zbuf_alloc_span(&zspan, xsize, ysize);
+ zbuf_alloc_span(&zspan, xsize, ysize, 1.0f);
zspan.zmulx= ((float)xsize)/2.0;
zspan.zmuly= ((float)ysize)/2.0;
zspan.zofsx= 0.0f;
@@ -2442,29 +3045,21 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
}
/* make vertex buffer with averaged speed and zvalues */
- rectvz= MEM_mapallocN(5*sizeof(float)*(xsize+1)*(ysize+1), "vertices");
+ rectvz= MEM_mapallocN(4*sizeof(float)*(xsize+1)*(ysize+1), "vertices");
dvz= rectvz;
for(y=0; y<=ysize; y++) {
- if(y==0) {
+ if(y==0)
dvec1= vecbufrect + 4*y*xsize;
- dz1= zbufrect + y*xsize;
- }
- else {
+ else
dvec1= vecbufrect + 4*(y-1)*xsize;
- dz1= zbufrect + (y-1)*xsize;
- }
- if(y==ysize) {
+ if(y==ysize)
dvec2= vecbufrect + 4*(y-1)*xsize;
- dz2= zbufrect + (y-1)*xsize;
- }
- else {
+ else
dvec2= vecbufrect + 4*y*xsize;
- dz2= zbufrect + y*xsize;
- }
- for(x=0; x<=xsize; x++, dz1++, dz2++) {
+ for(x=0; x<=xsize; x++) {
/* two vectors, so a step loop */
for(step=0; step<2; step++, dvec1+=2, dvec2+=2, dvz+=2) {
@@ -2522,30 +3117,21 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
}
}
}
- /* the z coordinate */
- if(x!=0) {
- if(x!=xsize)
- dvz[0]= 0.25f*(dz1[-1] + dz2[-1] + dz1[0] + dz2[0]);
- else dvz[0]= 0.5f*(dz1[0] + dz2[0]);
- }
- else dvz[0]= 0.5f*(dz1[-1] + dz2[-1]);
-
- dvz++;
}
}
/* set border speeds to keep border speeds on border */
dz1= rectvz;
- dz2= rectvz+5*(ysize)*(xsize+1);
- for(x=0; x<=xsize; x++, dz1+=5, dz2+=5) {
+ dz2= rectvz+4*(ysize)*(xsize+1);
+ for(x=0; x<=xsize; x++, dz1+=4, dz2+=4) {
dz1[1]= 0.0f;
dz2[1]= 0.0f;
dz1[3]= 0.0f;
dz2[3]= 0.0f;
}
dz1= rectvz;
- dz2= rectvz+5*(xsize);
- for(y=0; y<=ysize; y++, dz1+=5*(xsize+1), dz2+=5*(xsize+1)) {
+ dz2= rectvz+4*(xsize);
+ for(y=0; y<=ysize; y++, dz1+=4*(xsize+1), dz2+=4*(xsize+1)) {
dz1[0]= 0.0f;
dz2[0]= 0.0f;
dz1[2]= 0.0f;
@@ -2572,10 +3158,10 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
samples/= 2;
for(step= 1; step<=samples; step++) {
float speedfac= 0.5f*nbd->fac*(float)step/(float)(samples+1);
- float blendfac= 1.0f/(ABS(step)+1);
- int side, z= 4;
+ int side;
for(side=0; side<2; side++) {
+ float blendfac= 1.0f/((ABS(step)*2+side)+1), ipodata[4];
/* clear zbuf, if we draw future we fill in not moving pixels */
if(0)
@@ -2593,43 +3179,61 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
dimg= imgrect;
dm= rectmove;
+ dz= zbufrect;
dz1= rectvz;
- dz2= rectvz + 5*(xsize + 1);
+ dz2= rectvz + 4*(xsize + 1);
if(side) {
- dz1+= 2;
- dz2+= 2;
- z= 2;
+ if(nbd->curved==0) {
+ dz1+= 2;
+ dz2+= 2;
+ }
speedfac= -speedfac;
}
-
+
+ set_quad_bezier_ipo(0.5f + 0.5f*speedfac, ipodata);
+
for(fy= -0.5f+jit[step & 15][0], y=0; y<ysize; y++, fy+=1.0f) {
- for(fx= -0.5f+jit[step & 15][1], x=0; x<xsize; x++, fx+=1.0f, dimg+=4, dz1+=5, dz2+=5, dm++) {
+ for(fx= -0.5f+jit[step & 15][1], x=0; x<xsize; x++, fx+=1.0f, dimg+=4, dz1+=4, dz2+=4, dm++, dz++) {
if(*dm>1) {
DrawBufPixel col;
/* make vertices */
- v1[0]= speedfac*dz1[0]+fx; v1[1]= speedfac*dz1[1]+fy; v1[2]= dz1[z];
- v2[0]= speedfac*dz1[5]+fx+1.0f; v2[1]= speedfac*dz1[6]+fy; v2[2]= dz1[z+5];
- v3[0]= speedfac*dz2[5]+fx+1.0f; v3[1]= speedfac*dz2[6]+fy+1.0f; v3[2]= dz2[z+5];
- v4[0]= speedfac*dz2[0]+fx; v4[1]= speedfac*dz2[1]+fy+1.0f; v4[2]= dz2[z];
-
+ if(nbd->curved) { /* curved */
+ quad_bezier_2d(v1, dz1, dz1+2, ipodata);
+ v1[0]+= fx; v1[1]+= fy; v1[2]= *dz;
+
+ quad_bezier_2d(v2, dz1+4, dz1+4+2, ipodata);
+ v2[0]+= fx+1.0f; v2[1]+= fy; v2[2]= *dz;
+
+ quad_bezier_2d(v3, dz2+4, dz2+4+2, ipodata);
+ v3[0]+= fx+1.0f; v3[1]+= fy+1.0f; v3[2]= *dz;
+
+ quad_bezier_2d(v4, dz2, dz2+2, ipodata);
+ v4[0]+= fx; v4[1]+= fy+1.0f; v4[2]= *dz;
+ }
+ else {
+ v1[0]= speedfac*dz1[0]+fx; v1[1]= speedfac*dz1[1]+fy; v1[2]= *dz;
+ v2[0]= speedfac*dz1[4]+fx+1.0f; v2[1]= speedfac*dz1[5]+fy; v2[2]= *dz;
+ v3[0]= speedfac*dz2[4]+fx+1.0f; v3[1]= speedfac*dz2[5]+fy+1.0f; v3[2]= *dz;
+ v4[0]= speedfac*dz2[0]+fx; v4[1]= speedfac*dz2[1]+fy+1.0f; v4[2]= *dz;
+ }
if(*dm==255) col.alpha= 1.0f;
else if(*dm<2) col.alpha= 0.0f;
else col.alpha= ((float)*dm)/255.0f;
col.colpoin= dimg;
-
+
zbuf_fill_in_rgba(&zspan, &col, v1, v2, v3, v4);
}
}
- dz1+=5;
- dz2+=5;
+ dz1+=4;
+ dz2+=4;
}
/* accum */
for(dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; x--, dr++, dz2+=4) {
if(dr->colpoin) {
- float bfac= dr->alpha*blendfac;
+ float bfac= dr->alpha*blendfac*dr->colpoin[3];
float mf= 1.0f - bfac;
dz2[0]= mf*dz2[0] + bfac*dr->colpoin[0];
@@ -2655,18 +3259,21 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
* Copy results from the solid face z buffering to the transparent
* buffer.
*/
-static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
+static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
{
PixStr *ps;
- int x, y, *rza;
+ int x, y, *rza, *rma;
long *rd;
if(R.osa==0) {
- memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty);
+ memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty);
+ if(rectmask && pa->rectmask)
+ memcpy(rectmask, pa->rectmask, sizeof(int)*pa->rectx*pa->recty);
return;
}
rza= arectz;
+ rma= rectmask;
rd= pa->rectdaps;
sample= (1<<sample);
@@ -2675,17 +3282,19 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
for(x=0; x<pa->rectx; x++) {
*rza= 0x7FFFFFFF;
+ if(rectmask) *rma= 0x7FFFFFFF;
if(*rd) {
/* when there's a sky pixstruct, fill in sky-Z, otherwise solid Z */
for(ps= (PixStr *)(*rd); ps; ps= ps->next) {
if(sample & ps->mask) {
*rza= ps->z;
+ if(rectmask) *rma= ps->maskz;
break;
}
}
}
- rd++; rza++;
+ rd++; rza++, rma++;
}
}
}
@@ -2697,58 +3306,86 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int sample)
* Do accumulation z buffering.
*/
-static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay)
+static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, RenderLayer *rl, unsigned int lay)
{
- ZSpan zspan;
+ ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
+ ZSpan zspans[16], *zspan; /* MAX_OSA */
Material *ma=NULL;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
VlakRen *vlr=NULL;
VertRen *v1, *v2, *v3, *v4;
float vec[3], hoco[4], mul, zval, fval;
- int v, zvlnr= 0, zsample, dofill= 0;
- char *clipflag= pa->clipflag;
-
- zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
-
- /* needed for transform from hoco to zbuffer co */
- zspan.zmulx= ((float)R.winx)/2.0;
- zspan.zmuly= ((float)R.winy)/2.0;
-
- /* the buffers */
- zspan.arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz");
- zspan.apixbuf= APixbuf;
- zspan.apsmbase= apsmbase;
-
- /* filling methods */
- zspan.zbuffunc= zbuffillAc4;
- zspan.zbuflinefunc= zbuflineAc;
-
- for(zsample=0; zsample<R.osa || R.osa==0; zsample++) {
+ float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ int i, v, zvlnr, c1, c2, c3, c4=0, dofill= 0;
+ int zsample, samples, polygon_offset;
+
+ zbuffer_part_bounds(&R, pa, bounds);
+ samples= (R.osa? R.osa: 1);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop);
- copyto_abufz(pa, zspan.arectz, zsample); /* init zbuffer */
- zspan.mask= 1<<zsample;
+ /* needed for transform from hoco to zbuffer co */
+ zspan->zmulx= ((float)R.winx)/2.0;
+ zspan->zmuly= ((float)R.winy)/2.0;
+ /* the buffers */
+ zspan->arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz");
+ zspan->apixbuf= APixbuf;
+ zspan->apsmbase= apsmbase;
+
+ if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ zspan->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectmask");
+
+ /* filling methods */
+ zspan->zbuffunc= zbuffillAc4;
+ zspan->zbuflinefunc= zbuflineAc;
+
+ copyto_abufz(pa, zspan->arectz, zspan->rectmask, zsample); /* init zbuffer */
+ zspan->mask= 1<<zsample;
+
if(R.osa) {
- zspan.zofsx= -pa->disprect.xmin - R.jit[zsample][0];
- zspan.zofsy= -pa->disprect.ymin - R.jit[zsample][1];
+ zspan->zofsx= -pa->disprect.xmin - R.jit[zsample][0];
+ zspan->zofsy= -pa->disprect.ymin - R.jit[zsample][1];
}
else if(R.i.curblur) {
- zspan.zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
- zspan.zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
+ zspan->zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
+ zspan->zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
}
else {
- zspan.zofsx= -pa->disprect.xmin;
- zspan.zofsy= -pa->disprect.ymin;
+ zspan->zofsx= -pa->disprect.xmin;
+ zspan->zofsy= -pa->disprect.ymin;
}
/* to center the sample position */
- zspan.zofsx -= 0.5f;
- zspan.zofsy -= 0.5f;
-
- /* we use this to test if nothing was filled in */
- zvlnr= 0;
+ zspan->zofsx -= 0.5f;
+ zspan->zofsy -= 0.5f;
+ }
+
+ /* we use this to test if nothing was filled in */
+ zvlnr= 0;
- for(v=0; v<R.totvlak; v++) {
+ for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
+
+ if(!(obi->lay & lay))
+ continue;
+
+ if(obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(&R, obi->mat, winmat);
+ else
+ zbuf_make_winmat(&R, NULL, winmat);
+
+ if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ continue;
+
+ zbuf_project_cache_clear(cache, obr->totvert);
+
+ for(v=0; v<obr->totvlak; v++) {
if((v & 255)==0)
- vlr= R.vlaknodes[v>>8].vlak;
+ vlr= obr->vlaknodes[v>>8].vlak;
else vlr++;
if(vlr->mat!=ma) {
@@ -2757,24 +3394,30 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
}
if(dofill) {
- if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
+ if(!(vlr->flag & R_HIDDEN) && (obi->lay & lay)) {
unsigned short partclip;
v1= vlr->v1;
v2= vlr->v2;
v3= vlr->v3;
v4= vlr->v4;
-
+
+ c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+
/* partclipping doesn't need viewplane clipping */
- partclip= clipflag[v1->index] & clipflag[v2->index] & clipflag[v3->index];
- if(v4)
- partclip &= clipflag[v4->index];
-
+ partclip= c1 & c2 & c3;
+ if(v4) {
+ c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ partclip &= c4;
+ }
+
if(partclip==0) {
/* a little advantage for transp rendering (a z offset) */
if( ma->zoffs != 0.0) {
mul= 0x7FFFFFFF;
- zval= mul*(1.0+v1->ho[2]/v1->ho[3]);
+ zval= mul*(1.0+ho1[2]/ho1[3]);
VECCOPY(vec, v1->co);
/* z is negative, otherwise its being clipped */
@@ -2782,40 +3425,57 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
projectverto(vec, R.winmat, hoco);
fval= mul*(1.0+hoco[2]/hoco[3]);
- zspan.polygon_offset= (int) fabs(zval - fval );
+ polygon_offset= (int) fabs(zval - fval );
}
- else zspan.polygon_offset= 0;
+ else polygon_offset= 0;
zvlnr= v+1;
-
- if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr);
- else {
- if(v4 && (vlr->flag & R_STRAND)) {
- zbufclip4(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v4->ho, v1->clip, v2->clip, v3->clip, v4->clip);
+
+ c1= testclip(ho1);
+ c2= testclip(ho2);
+ c3= testclip(ho3);
+ if(v4)
+ c4= testclip(ho4);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+ zspan->polygon_offset= polygon_offset;
+
+ if(ma->mode & (MA_WIRE)) {
+ if(v4)
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ else
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
}
else {
- zbufclip(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v1->clip, v2->clip, v3->clip);
- if(v4) {
- zvlnr+= RE_QUAD_OFFS;
- zbufclip(&zspan, zvlnr, v1->ho, v3->ho, v4->ho, v1->clip, v3->clip, v4->clip);
+ if(v4 && (vlr->flag & R_STRAND)) {
+ zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ }
+ else {
+ zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3);
+ if(v4)
+ zbufclip(zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4);
}
}
}
}
+ if((v & 255)==255)
+ if(R.test_break())
+ break;
}
- if( (v & 255)==255)
- if(R.test_break())
- break;
}
}
-
- if(R.osa==0) break;
+
if(R.test_break()) break;
- if(zvlnr==0) break;
}
- MEM_freeN(zspan.arectz);
- zbuf_free_span(&zspan);
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+ MEM_freeN(zspan->arectz);
+ if(zspan->rectmask)
+ MEM_freeN(zspan->rectmask);
+ zbuf_free_span(zspan);
+ }
return zvlnr;
}
@@ -2824,7 +3484,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
/* speed pointer NULL = sky, we clear */
/* else if either alpha is full or no solid was filled in: copy speed */
/* else fill in minimum speed */
-static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect)
+void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect)
{
RenderPass *rpass;
@@ -2852,23 +3512,23 @@ static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float al
fp[2]= speed[2];
fp[3]= speed[3];
}
-
}
break;
}
}
}
-static void add_transp_obindex(RenderLayer *rl, int offset, int facenr)
+static void add_transp_obindex(RenderLayer *rl, int offset, int obi)
{
- VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & RE_QUAD_MASK);
- if(vlr && vlr->ob) {
+ ObjectRen *obr= R.objectinstance[obi].obr;
+
+ if(obr->ob) {
RenderPass *rpass;
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
if(rpass->passtype == SCE_PASS_INDEXOB) {
float *fp= rpass->rect + offset;
- *fp= (float)vlr->ob->index;
+ *fp= (float)obr->ob->index;
break;
}
}
@@ -2877,7 +3537,7 @@ static void add_transp_obindex(RenderLayer *rl, int offset, int facenr)
/* ONLY OSA! merge all shaderesult samples to one */
/* target should have been cleared */
-static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
+void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
{
RenderPass *rpass;
float weight= 1.0f/((float)R.osa);
@@ -2916,6 +3576,10 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
case SCE_PASS_NORMAL:
col= shr->nor;
break;
+ case SCE_PASS_MIST:
+ col= &shr->mist;
+ pixsize= 1;
+ break;
case SCE_PASS_VECTOR:
{
@@ -2961,14 +3625,20 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
}
-static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alpha)
+void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, float alpha)
{
RenderPass *rpass;
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
float *fp, *col= NULL;
+ int pixsize= 3;
switch(rpass->passtype) {
+ case SCE_PASS_Z:
+ fp= rpass->rect + offset;
+ if(shr->z < *fp)
+ *fp= shr->z;
+ break;
case SCE_PASS_RGBA:
fp= rpass->rect + 4*offset;
addAlphaOverFloat(fp, shr->col);
@@ -2997,37 +3667,99 @@ static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, flo
case SCE_PASS_NORMAL:
col= shr->nor;
break;
+ case SCE_PASS_MIST:
+ col= &shr->mist;
+ pixsize= 1;
+ break;
}
if(col) {
- fp= rpass->rect + 3*offset;
- fp[0]= alpha*col[0] + (1.0f-alpha)*fp[0];
- fp[1]= alpha*col[1] + (1.0f-alpha)*fp[1];
- fp[2]= alpha*col[2] + (1.0f-alpha)*fp[2];
+ fp= rpass->rect + pixsize*offset;
+ fp[0]= col[0] + (1.0f-alpha)*fp[0];
+ if(pixsize==3) {
+ fp[1]= col[1] + (1.0f-alpha)*fp[1];
+ fp[2]= col[2] + (1.0f-alpha)*fp[2];
+ }
}
}
}
-
+typedef struct ZTranspRow {
+ int obi;
+ int z;
+ int p;
+ int mask;
+ int segment;
+ float u, v;
+} ZTranspRow;
static int vergzvlak(const void *a1, const void *a2)
{
- const int *x1=a1, *x2=a2;
+ const ZTranspRow *r1 = a1, *r2 = a2;
- if( x1[0] < x2[0] ) return 1;
- else if( x1[0] > x2[0]) return -1;
+ if(r1->z < r2->z) return 1;
+ else if(r1->z > r2->z) return -1;
return 0;
}
+static void shade_strand_samples(StrandShadeCache *cache, ShadeSample *ssamp, int x, int y, ZTranspRow *row, int addpassflag)
+{
+ StrandSegment sseg;
+ StrandVert *svert;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+
+ obi= R.objectinstance + row->obi;
+ obr= obi->obr;
+
+ sseg.obi= obi;
+ sseg.strand= RE_findOrAddStrand(obr, row->p-1);
+ sseg.buffer= sseg.strand->buffer;
+
+ svert= sseg.strand->vert + row->segment;
+ sseg.v[0]= (row->segment > 0)? (svert-1): svert;
+ sseg.v[1]= svert;
+ sseg.v[2]= svert+1;
+ sseg.v[3]= (row->segment < sseg.strand->totvert-2)? svert+2: svert+1;
+
+ ssamp->tot= 1;
+ strand_shade_segment(&R, cache, &sseg, ssamp, row->v, row->u, addpassflag);
+ ssamp->shi[0].mask= row->mask;
+}
+
+static void unref_strand_samples(StrandShadeCache *cache, ZTranspRow *row, int totface)
+{
+ StrandVert *svert;
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
+ StrandRen *strand;
+
+ /* remove references to samples that are not being rendered, but we still
+ * need to remove them so that the reference count of strand vertex shade
+ * samples correctly drops to zero */
+ while(totface > 0) {
+ totface--;
+
+ if(row[totface].segment != -1) {
+ obi= R.objectinstance + row[totface].obi;
+ obr= obi->obr;
+ strand= RE_findOrAddStrand(obr, row[totface].p-1);
+ svert= strand->vert + row[totface].segment;
+
+ strand_shade_unref(cache, svert);
+ strand_shade_unref(cache, svert+1);
+ }
+ }
+}
-static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int facenr, int curmask)
+static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int obi, int facenr, int curmask)
{
ShadeInput *shi= ssamp->shi;
float xs, ys;
ssamp->tot= 0;
- shade_input_set_triangle(shi, facenr, 1);
+ shade_input_set_triangle(shi, obi, facenr, 1);
/* officially should always be true... we have no sky info */
if(shi->vlr) {
@@ -3046,7 +3778,7 @@ static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int
shi++;
}
shi->mask= (1<<samp);
- shi->samplenr= ssamp->samplenr++;
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
shade_input_set_viewco(shi, xs, ys, (float)z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -3066,7 +3798,7 @@ static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int
ys= (float)y + 0.5f;
}
shi->mask= curmask;
- shi->samplenr= ssamp->samplenr++;
+ shi->samplenr= R.shadowsamplenr[shi->thread]++;
shade_input_set_viewco(shi, xs, ys, (float)z);
shade_input_set_uv(shi);
shade_input_set_normals(shi);
@@ -3077,9 +3809,14 @@ static void shade_tra_samples_fill(ShadeSample *ssamp, int x, int y, int z, int
}
}
-static int shade_tra_samples(ShadeSample *ssamp, int x, int y, int z, int facenr, int mask)
+static int shade_tra_samples(ShadeSample *ssamp, StrandShadeCache *cache, int x, int y, ZTranspRow *row, int addpassflag)
{
- shade_tra_samples_fill(ssamp, x, y, z, facenr, mask);
+ if(row->segment != -1) {
+ shade_strand_samples(cache, ssamp, x, y, row, addpassflag);
+ return 1;
+ }
+
+ shade_tra_samples_fill(ssamp, x, y, row->z, row->obi, row->p, row->mask);
if(ssamp->tot) {
ShadeInput *shi= ssamp->shi;
@@ -3115,9 +3852,9 @@ static void addvecmul(float *v1, float *v2, float fac)
static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassflag)
{
- int a, sample, retval = R.osa;
+ int a, sample, osa = (R.osa? R.osa: 1), retval = osa;
- for(a=0; a < R.osa; a++, samp_shr++) {
+ for(a=0; a < osa; a++, samp_shr++) {
ShadeInput *shi= ssamp->shi;
ShadeResult *shr= ssamp->shr;
@@ -3128,6 +3865,8 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf
addAlphaUnderFloat(samp_shr->combined, shr->combined);
+ samp_shr->z= MIN2(samp_shr->z, shr->z);
+
if(addpassflag & SCE_PASS_VECTOR) {
QUATCOPY(samp_shr->winspeed, shr->winspeed);
}
@@ -3159,7 +3898,11 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf
addvecmul(samp_shr->refr, shr->refr, fac);
if(addpassflag & SCE_PASS_RADIO)
- addvecmul(samp_shr->refr, shr->rad, fac);
+ addvecmul(samp_shr->rad, shr->rad, fac);
+
+ if(addpassflag & SCE_PASS_MIST)
+ samp_shr->mist= samp_shr->mist+fac*shr->mist;
+
}
}
}
@@ -3169,7 +3912,7 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf
return retval;
}
-static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
+static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf)
{
/* speed vector exception... if solid render was done, sky pixels are set to zero already */
/* for all pixels with alpha zero, we re-initialize speed again then */
@@ -3178,7 +3921,7 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
fp= RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR);
if(fp==NULL) return;
- col= rl->acolrect+3;
+ col= rectf+3;
for(a= 4*pa->rectx*pa->recty -4; a>=0; a-=4) {
if(col[a]==0.0f) {
@@ -3191,22 +3934,27 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
}
#define MAX_ZROW 2000
-/* main render call to fill in pass the full transparent layer */
+
+/* main render call to do the z-transparent layer */
/* returns a mask, only if a) transp rendered and b) solid was rendered */
-unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
+unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass, ListBase *psmlist)
{
RenderResult *rr= pa->result;
ShadeSample ssamp;
APixstr *APixbuf; /* Zbuffer: linked list of face samples */
+ APixstrand *APixbufstrand = NULL;
APixstr *ap, *aprect, *apn;
+ APixstrand *apstrand, *aprectstrand, *apnstrand;
ListBase apsmbase={NULL, NULL};
ShadeResult samp_shr[16]; /* MAX_OSA */
- float sampalpha, *passrect= pass;
+ ZTranspRow zrow[MAX_ZROW];
+ StrandShadeCache *sscache= NULL;
+ float sampalpha, alpha, *passrect= pass;
long *rdrect;
- int x, y, crop=0, a, zrow[MAX_ZROW][3], totface;
- int addpassflag, offs= 0, od, addzbuf;
- unsigned short *ztramask= NULL;
-
+ int x, y, crop=0, a, b, totface, totsample, doztra;
+ int addpassflag, offs= 0, od, addzbuf, osa = (R.osa? R.osa: 1);
+ unsigned short *ztramask= NULL, filled;
+
/* looks nicer for calling code */
if(R.test_break())
return NULL;
@@ -3218,6 +3966,10 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
}
APixbuf= MEM_callocN(pa->rectx*pa->recty*sizeof(APixstr), "APixbuf");
+ if(R.totstrand && (rl->layflag & SCE_LAY_STRAND)) {
+ APixbufstrand= MEM_callocN(pa->rectx*pa->recty*sizeof(APixstrand), "APixbufstrand");
+ sscache= strand_shade_cache_create();
+ }
/* general shader info, passes */
shade_sample_initialize(&ssamp, pa, rl);
@@ -3230,14 +3982,25 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
sampalpha= 1.0f;
/* fill the Apixbuf */
- if(0 == zbuffer_abuf(pa, APixbuf, &apsmbase, rl->lay)) {
+ doztra= 0;
+ if(rl->layflag & SCE_LAY_ZTRA)
+ doztra+= zbuffer_abuf(pa, APixbuf, &apsmbase, rl, rl->lay);
+ if((rl->layflag & SCE_LAY_STRAND) && APixbufstrand)
+ doztra+= zbuffer_strands_abuf(&R, pa, rl, APixbufstrand, &apsmbase, sscache);
+
+ if(doztra == 0) {
/* nothing filled in */
MEM_freeN(APixbuf);
+ if(APixbufstrand)
+ MEM_freeN(APixbufstrand);
+ if(sscache)
+ strand_shade_cache_free(sscache);
freepsA(&apsmbase);
return NULL;
}
aprect= APixbuf;
+ aprectstrand= APixbufstrand;
rdrect= pa->rectdaps;
/* irregular shadowb buffer creation */
@@ -3245,13 +4008,13 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
ISB_create(pa, APixbuf);
/* masks, to have correct alpha combine */
- if(R.osa && (rl->layflag & SCE_LAY_SOLID))
+ if(R.osa && (rl->layflag & SCE_LAY_SOLID) && pa->fullresult.first==NULL)
ztramask= MEM_callocN(pa->rectx*pa->recty*sizeof(short), "ztramask");
/* zero alpha pixels get speed vector max again */
if(addpassflag & SCE_PASS_VECTOR)
if(rl->layflag & SCE_LAY_SOLID)
- reset_sky_speedvectors(pa, rl);
+ reset_sky_speedvectors(pa, rl, rl->acolrect?rl->acolrect:rl->rectf); /* if acolrect is set we use it */
/* filtered render, for now we assume only 1 filter size */
if(pa->crop) {
@@ -3259,6 +4022,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
offs= pa->rectx + 1;
passrect+= 4*offs;
aprect+= offs;
+ aprectstrand+= offs;
}
/* init scanline updates */
@@ -3270,14 +4034,15 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
pass= passrect;
ap= aprect;
+ apstrand= aprectstrand;
od= offs;
if(R.test_break())
break;
- for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, pass+=4, od++) {
+ for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, ap++, apstrand++, pass+=4, od++) {
- if(ap->p[0]==0) {
+ if(ap->p[0]==0 && (!APixbufstrand || apstrand->p[0]==0)) {
if(addpassflag & SCE_PASS_VECTOR)
add_transp_speed(rl, od, NULL, 0.0f, rdrect);
}
@@ -3288,9 +4053,11 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
while(apn) {
for(a=0; a<4; a++) {
if(apn->p[a]) {
- zrow[totface][0]= apn->z[a];
- zrow[totface][1]= apn->p[a];
- zrow[totface][2]= apn->mask[a];
+ zrow[totface].obi= apn->obi[a];
+ zrow[totface].z= apn->z[a];
+ zrow[totface].p= apn->p[a];
+ zrow[totface].mask= apn->mask[a];
+ zrow[totface].segment= -1;
totface++;
if(totface>=MAX_ZROW) totface= MAX_ZROW-1;
}
@@ -3298,83 +4065,148 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
}
apn= apn->next;
}
-
+
+ apnstrand= (APixbufstrand)? apstrand: NULL;
+ while(apnstrand) {
+ for(a=0; a<4; a++) {
+ if(apnstrand->p[a]) {
+ zrow[totface].obi= apnstrand->obi[a];
+ zrow[totface].z= apnstrand->z[a];
+ zrow[totface].p= apnstrand->p[a];
+ zrow[totface].mask= apnstrand->mask[a];
+ zrow[totface].segment= apnstrand->seg[a];
+
+ if(R.osa) {
+ totsample= 0;
+ for(b=0; b<R.osa; b++)
+ if(zrow[totface].mask & (1<<b))
+ totsample++;
+ }
+ else
+ totsample= 1;
+
+ zrow[totface].u= apnstrand->u[a]/totsample;
+ zrow[totface].v= apnstrand->v[a]/totsample;
+ totface++;
+ if(totface>=MAX_ZROW) totface= MAX_ZROW-1;
+ }
+ }
+ apnstrand= apnstrand->next;
+ }
+
if(totface==2) {
- if(zrow[0][0] < zrow[1][0]) {
- a= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= a;
- a= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= a;
- a= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= a;
+ if(zrow[0].z < zrow[1].z) {
+ SWAP(ZTranspRow, zrow[0], zrow[1]);
}
}
else if(totface>2) {
- qsort(zrow, totface, sizeof(int)*3, vergzvlak);
+ qsort(zrow, totface, sizeof(ZTranspRow), vergzvlak);
}
/* zbuffer and index pass for transparent, no AA or filters */
if(addzbuf)
- if(pa->rectz[od]>zrow[totface-1][0])
- pa->rectz[od]= zrow[totface-1][0];
+ if(pa->rectz[od]>zrow[totface-1].z)
+ pa->rectz[od]= zrow[totface-1].z;
if(addpassflag & SCE_PASS_INDEXOB)
- add_transp_obindex(rl, od, zrow[totface-1][1]);
-
+ add_transp_obindex(rl, od, zrow[totface-1].obi);
+ /* for each mask-sample we alpha-under colors. then in end it's added using filter */
+ memset(samp_shr, 0, sizeof(ShadeResult)*osa);
+ for(a=0; a<osa; a++) {
+ samp_shr[a].z= 10e10f;
+ if(addpassflag & SCE_PASS_VECTOR) {
+ samp_shr[a].winspeed[0]= PASS_VECTOR_MAX;
+ samp_shr[a].winspeed[1]= PASS_VECTOR_MAX;
+ samp_shr[a].winspeed[2]= PASS_VECTOR_MAX;
+ samp_shr[a].winspeed[3]= PASS_VECTOR_MAX;
+ }
+ }
+
if(R.osa==0) {
while(totface>0) {
totface--;
- if(shade_tra_samples(&ssamp, x, y, zrow[totface][0], zrow[totface][1], zrow[totface][2])) {
- if(addpassflag)
- add_transp_passes(rl, od, ssamp.shr, (1.0f-pass[3])*ssamp.shr[0].combined[3]);
-
+ if(shade_tra_samples(&ssamp, sscache, x, y, &zrow[totface], addpassflag)) {
+ filled= addtosamp_shr(samp_shr, &ssamp, addpassflag);
addAlphaUnderFloat(pass, ssamp.shr[0].combined);
- if(pass[3]>=0.999) break;
+
+ if(filled == 0) {
+ if(sscache)
+ unref_strand_samples(sscache, zrow, totface);
+ break;
+ }
}
}
- if(addpassflag & SCE_PASS_VECTOR)
- add_transp_speed(rl, od, ssamp.shr[0].winspeed, pass[3], rdrect);
+
+ alpha= samp_shr->combined[3];
+ if(alpha!=0.0f) {
+ add_transp_passes(rl, od, samp_shr, alpha);
+ if(addpassflag & SCE_PASS_VECTOR)
+ add_transp_speed(rl, od, samp_shr->winspeed, alpha, rdrect);
+ }
}
else {
- short filled, *sp= (short *)(ztramask+od);
-
- /* for each mask-sample we alpha-under colors. then in end it's added using filter */
- memset(samp_shr, 0, sizeof(ShadeResult)*R.osa);
-
- /* nice this memset, but speed vectors are not initialized OK then. it is sufficient to only clear 1 (see merge_transp_passes) */
- if(addpassflag & SCE_PASS_VECTOR)
- samp_shr->winspeed[0]= samp_shr->winspeed[1]= samp_shr->winspeed[2]= samp_shr->winspeed[3]= PASS_VECTOR_MAX;
+ short *sp= (short *)(ztramask+od);
while(totface>0) {
totface--;
- if(shade_tra_samples(&ssamp, x, y, zrow[totface][0], zrow[totface][1], zrow[totface][2])) {
+ if(shade_tra_samples(&ssamp, sscache, x, y, &zrow[totface], addpassflag)) {
filled= addtosamp_shr(samp_shr, &ssamp, addpassflag);
if(ztramask)
- *sp |= zrow[totface][2];
- if(filled==0)
+ *sp |= zrow[totface].mask;
+ if(filled==0) {
+ if(sscache)
+ unref_strand_samples(sscache, zrow, totface);
break;
+ }
}
}
- for(a=0; a<R.osa; a++) {
- add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx);
+ /* multisample buffers or filtered mask filling? */
+ if(pa->fullresult.first) {
+ for(a=0; a<R.osa; a++) {
+ alpha= samp_shr[a].combined[3];
+ if(alpha!=0.0f) {
+ RenderLayer *rl= ssamp.rlpp[a];
+
+ addAlphaOverFloat(rl->rectf + 4*od, samp_shr[a].combined);
+
+ add_transp_passes(rl, od, &samp_shr[a], alpha);
+ if(addpassflag & SCE_PASS_VECTOR)
+ add_transp_speed(rl, od, samp_shr[a].winspeed, alpha, rdrect);
+ }
+ }
}
-
- if(addpassflag) {
- /* merge all in one, and then add */
- merge_transp_passes(rl, samp_shr);
- add_transp_passes(rl, od, samp_shr, pass[3]);
+ else {
+ alpha= 0.0f;
- if(addpassflag & SCE_PASS_VECTOR)
- add_transp_speed(rl, od, samp_shr[0].winspeed, pass[3], rdrect);
+ /* note; cannot use pass[3] for alpha due to filtermask */
+ for(a=0; a<R.osa; a++) {
+ add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx);
+ alpha+= samp_shr[a].combined[3];
+ }
+
+ if(addpassflag) {
+ alpha*= sampalpha;
+
+ /* merge all in one, and then add */
+ merge_transp_passes(rl, samp_shr);
+ add_transp_passes(rl, od, samp_shr, alpha);
+
+ if(addpassflag & SCE_PASS_VECTOR)
+ add_transp_speed(rl, od, samp_shr[0].winspeed, alpha, rdrect);
+ }
}
}
}
}
aprect+= pa->rectx;
+ aprectstrand+= pa->rectx;
passrect+= 4*pa->rectx;
offs+= pa->rectx;
}
@@ -3383,6 +4215,10 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
rr->renlay= NULL;
MEM_freeN(APixbuf);
+ if(APixbufstrand)
+ MEM_freeN(APixbufstrand);
+ if(sscache)
+ strand_shade_cache_free(sscache);
freepsA(&apsmbase);
if(R.r.mode & R_SHADOW)
diff --git a/source/blender/src/CMakeLists.txt b/source/blender/src/CMakeLists.txt
index d4a0cbf7c3d..176ec036ada 100644
--- a/source/blender/src/CMakeLists.txt
+++ b/source/blender/src/CMakeLists.txt
@@ -63,6 +63,10 @@ IF(WITH_FFMPEG)
ADD_DEFINITIONS(-DWITH_FFMPEG)
ENDIF(WITH_FFMPEG)
+IF(WIN32)
+ SET(INC ${INC} ${PTHREADS_INC})
+ENDIF(WIN32)
+
IF(WITH_VERSE)
SET(INC ${INC} ${VERSE_INC})
ADD_DEFINITIONS(-DWITH_VERSE)
diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile
index e9f4e807259..5038c294bc6 100644
--- a/source/blender/src/Makefile
+++ b/source/blender/src/Makefile
@@ -50,10 +50,6 @@ include nan_compile.mk
CFLAGS += $(LEVEL_1_C_WARNINGS)
#CFLAGS += $(LEVEL_1_C_WARNINGS) -diag_error 1196
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
# PreProcessor stuff ------------------------------------------
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
@@ -121,10 +117,18 @@ ifeq ($(WITH_FFMPEG),true)
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
endif
+ifdef NAN_PTHREADS
+ CPPFLAGS += -I$(NAN_PTHREADS)/include
+endif
+
ifeq ($(WITH_OPENEXR),true)
CPPFLAGS += -DWITH_OPENEXR
endif
+ifeq ($(WITH_DDS),true)
+ CPPFLAGS += -DWITH_DDS
+endif
+
ifeq ($(INTERNATIONAL), true)
CPPFLAGS += -DINTERNATIONAL
endif
diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript
index 729e79dcb6f..f466798c40c 100644
--- a/source/blender/src/SConscript
+++ b/source/blender/src/SConscript
@@ -5,6 +5,20 @@ Import ('env')
sources = env.Glob('*.c')
+if env['BF_SPLIT_SRC'] == 1:
+ numobj = len(sources)
+ maxobj = 30
+
+ numlibs = numobj / maxobj
+ if (numobj % maxobj):
+ numlibs = numlibs + 1
+ subsources = []
+
+ if (env['OURPLATFORM'] == 'win32-mingw'):
+ for i in range(numlibs - 1):
+ subsources.append(sources[i*maxobj:(i+1)*maxobj])
+ subsources.append(sources[(numlibs-1)*maxobj:])
+
incs = ' #/intern/guardedalloc #/intern/memutil'
incs += ' ../blenlib ../makesdna ../blenkernel'
incs += ' ../include #/intern/bmfont ../imbuf ../render/extern/include'
@@ -35,6 +49,9 @@ if env['WITH_BF_INTERNATIONAL'] == 1:
if env['WITH_BF_OPENEXR'] == 1:
defs.append('WITH_OPENEXR')
+if env['WITH_BF_DDS'] == 1:
+ defs.append('WITH_DDS')
+
if env['WITH_BF_QUICKTIME']==1:
incs += ' ' + env['BF_QUICKTIME_INC']
defs.append('WITH_QUICKTIME')
@@ -47,6 +64,9 @@ if env['WITH_BF_FFMPEG'] == 1:
defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC']
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
+ incs += ' ' + env['BF_PTHREADS_INC']
+
if env['WITH_BF_VERSE']:
defs.append('WITH_VERSE')
incs += ' ' + env['BF_VERSE_INCLUDE']
@@ -54,5 +74,9 @@ if env['WITH_BF_VERSE']:
# TODO buildinfo
if env['BF_BUILDINFO'] == 1:
defs.append('NAN_BUILDINFO')
-
-env.BlenderLib ( libname = 'src', sources = sources, includes = Split(incs), defines = defs, libtype=['core', 'intern'], priority = [5, 25] )
+
+if (env['BF_SPLIT_SRC'] == 1) and (env['OURPLATFORM'] == 'win32-mingw'):
+ for i in range(numlibs):
+ env.BlenderLib ( libname = 'src%d' % (i), sources = subsources[i], includes = Split(incs), defines = defs, libtype=['core', 'intern'], priority = [5, 25] )
+else:
+ env.BlenderLib ( libname = 'src', sources = sources, includes = Split(incs), defines = defs, libtype=['core', 'intern'], priority = [5, 25] )
diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c
index 894cd3c55b8..5504af83ceb 100644
--- a/source/blender/src/blenderbuttons.c
+++ b/source/blender/src/blenderbuttons.c
@@ -1,7 +1,16 @@
/* DataToC output of file <blenderbuttons_png> */
+<<<<<<< .working
+<<<<<<< .working
int datatoc_blenderbuttons_size= 525518;
+=======
+int datatoc_blenderbuttons_size= 65117;
+=======
+int datatoc_blenderbuttons_size= 65917;
+>>>>>>> .merge-right.r14096
+>>>>>>> .merge-right.r11522
char datatoc_blenderbuttons[]= {
+<<<<<<< .working
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72,
68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,
255,160,189,167,147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73,
@@ -16425,5 +16434,2067 @@ char datatoc_blenderbuttons[]= {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,237,237,228, 34,191, 89, 72, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+=======
+137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,
+197,144,206,103, 0, 0, 0, 1,115, 82, 71, 66, 0,174,206, 28,233, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,
+189,167,147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69,
+ 7,216, 2, 17, 21, 28, 41, 30,244,243,210, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236,125,121, 92, 84, 85,255,255,251,220,217,
+217, 23, 1, 21,151,193,125, 95,201, 37, 55, 40, 53,243,155,153, 6,148,154,100,101, 98,137,218,147,166, 61,101,143,250,211, 71,
+197,164, 50, 53,161,167,210,172, 52, 5,115,201, 45, 81, 7,245, 81, 82,113, 47, 23, 20, 69, 4, 69,150, 97, 22,102,187,115,151,
+223, 31, 51, 67, 3, 2,179,128, 91,207,188, 95,220,215,229,222,123,238,103,206, 61,219,103, 61,231,144, 30, 61,122,240,240,192,
+ 3, 15, 60,240,192, 3, 15,254,167, 64,121,138,192, 3, 15, 60,240,192, 3, 15,254,119,112,230,236, 1, 0, 0,241, 88, 0, 60,
+240,192, 3, 15, 60,240,192, 99, 1,240,192, 3, 15, 60,240,192, 3, 15, 60, 2,128, 7, 30,120,224,129, 7, 30,120,224, 17, 0,
+ 60,240,192, 3, 15, 60,240,192,131,191, 5,132,246, 23,231,206,157, 35,238, 18,170, 41,150,192, 67,207, 67,175, 54,164,166,166,
+242,107,215,174,125,100,249, 27, 55,110, 28,191,105,211, 38,226,169,143, 39,154, 30,234, 65, 15,158,242,243,208,251, 59,211,115,
+ 89, 0,248, 31, 71,245, 2, 36,143,115, 62, 83, 82, 82, 48,117,234, 84,226,169, 54,247,235,120,216,176, 97,149,215, 25, 25, 25,
+127,139,178, 28,253, 82, 66,157, 3,193,142,237,169,127,235, 54, 35, 11,220, 6,169,177, 13, 34, 64,163, 2,123,145, 99,152,247,
+ 56,183, 69, 79,255,245,224,241,177, 0, 60,140,198, 58,122,244,232,168, 29, 59,118, 40,236,174,163,119,236,216,145,249, 88,244,
+ 72,222, 50,118, 18,242,216,246, 75, 62, 47, 47, 15, 0, 32,151,203,159,164, 65,196,105,233,116,220,184,113, 78,167,221,180,105,
+147, 43,130, 26,191,101,203,150,202,139,109,219,182, 97,216,176, 97, 85,158, 63, 42, 33, 32, 59, 59,155, 7,128,200,200, 72,210,
+ 16,233,118,108, 79,125,160,245, 23, 30,209, 28, 0,112,207,104, 4, 99, 48, 89,110,170, 52, 0,128,216,216, 88,164,165,165,213,
+154,191,222,185,189,249,182,119,219,186,244,227, 63, 15,252,217,137,122,145, 33,240,221,139, 48,238,216,134,242,242, 49, 40, 7,
+208, 75,246, 41,230,201, 78,163,185, 20, 40, 49,230, 98,158, 33,206,165,223,141,141,141,141, 74, 75, 75, 83, 84,187, 23,157,150,
+150,150,249,152,245,173, 6,105,183, 79,200,247, 54, 56,154, 4, 75,136,143,200,159,152,164, 98,222,164, 50, 80, 21, 6, 13,167,
+ 51,153,255, 39,102,199, 57, 20, 0,172, 12,219,118,174,111, 67,224,119,236,216,129,133, 91, 22,195,167,185, 63, 42,110,171, 49,
+ 63,110,158,226, 49,215,184, 31, 39, 16,185, 92,206,231,229,229, 33, 47, 47, 15,251,246,237,195,212,169, 83, 31, 87, 33,192,214,
+129, 72,106,106,170, 40, 33, 33,193,188,124,249,242, 83, 0, 48,103,206,156,167,234,122,113,204,152, 49,149,255, 51, 12, 11,218,
+108, 2,109,162, 65,211,150,131, 97, 24,204,153, 51,199,165,188,216, 51,255,154, 96, 21, 6,248, 71,105, 9,112, 69,248,121,100,
+ 26,126,128, 31, 46,220,248, 25, 50, 52, 3,139, 99, 40,254,230, 12,206,231,150, 97,236,178,117, 78,189,222,246,110, 91, 39, 25,
+186, 5,175,254,247, 85,135,101, 34, 27, 57, 15, 65,163,223, 66,225,123,189, 0, 67,121,229,253, 51,134, 15,112, 6, 0, 12,192,
+ 96, 89, 44, 14, 6,158, 70, 0,128,222,229,189,157,106, 51,105,105,105,247,221,180, 99,144,228, 49,234, 99, 13, 49, 6, 60, 9,
+223,219,160, 24,208,173, 7,121, 45, 60, 66,168,106,209, 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,
+246,245, 81,195, 89, 39, 73,221,113,225,103,155, 58,145,102,150, 11,244,146, 31,168, 0,176, 99,199, 14,197,150, 79, 62, 66,220,
+162, 37,138,122, 54, 2,222,198,248, 1,160, 84, 95, 6, 4, 3,255, 60,184, 0,154, 27,229, 88,243,246,202,199,141,145,213, 54,
+240, 60,234, 60, 86, 10, 1, 35, 70,140, 64, 94, 94, 30,228,114,249, 99, 87,118, 10,133,101,220,136,142,142,230, 1, 80,169,169,
+169,225, 9, 9, 9,133,203,151, 47, 63,237, 44, 17,134, 97, 64,211,230, 74,198,111,207,252,179,179,179, 17, 25, 25,233, 82,166,
+226,226,226,236,153, 45, 50, 50, 50,170, 11, 0, 13,209, 86, 92,174,135,200,200, 72, 50,110,220, 56,126,248,240,225,247, 61,219,
+191,127,191,205,210, 97,179,122, 56, 77,191, 33,221, 1,225, 17,205, 81, 88,174,198, 47, 83, 95, 70, 48, 25,128,220,255,204, 70,
+171, 49,173,144,225, 2,243,175, 44, 44,171,169,141, 52,128,169, 45,124,203, 49,232,111, 85,160, 48, 33,162,206,116, 23,165, 7,
+176,176,235, 61, 44,189,248,113,125,235,179, 33,152,110, 67,210, 64, 3,211,122, 16,223,219, 32,136,143,143,247, 2,240, 52, 0,
+ 31,187,219, 42, 0, 23, 54,108,216,160,116,150,206, 23,107,191,160,232, 82,147,136, 54, 25,165,229, 48, 75, 69, 34,161, 80, 99,
+148, 82, 98,177,129, 19,248,121, 51,180,204,108, 22, 22,221, 49,125,255,205,122,227,235,147, 39,177,206,124,183, 74,165,250,183,
+237,255,156,156,156, 82,111,111,111, 74,167,211,113,246,105,250,244,233,243,121, 3, 51,246, 89,245, 45, 83,161, 35,237,255,242,
+229,203,104,235,227,103,111, 13,112,199, 10, 80,201,252, 75,245,101, 88,250,236,130,202, 7,111,236,120, 23, 8, 5,198, 44,143,
+195,182, 57, 91, 92,105,100,117, 13,110,245,110,168,183,111,223, 6, 0, 52,111,222,188,202,255,112,193,156,221,128,130, 8,169,
+ 77, 8, 48,155, 25, 91, 60, 64,131,104, 1, 13, 80,150,246,204, 31, 0, 72, 66, 66, 2, 0,220, 73, 77, 77, 13, 76, 72, 72, 40,
+119,154,249,155,205,160,105, 19, 76, 52, 13,115, 53,230,207,115,174, 85, 67, 92, 92, 28,178,179,179,255,234, 93,201,201,136,137,
+137,169,188, 78, 79, 79,175,183,176, 99, 39,240,212,187,253,217, 51,254,113,227,198,161,103,207,158, 54, 1,192, 85,139, 64,131,
+ 52,194,130, 27,249,208,109,251, 23,124,222, 92,137,240,136,230, 8, 11,150,225,198,182, 27, 22,230, 31,224,103,113, 1,136, 4,
+206, 73,176, 13,228, 99,107,119,233, 58,110,207, 95, 12, 67,218,250,186, 45, 4, 50, 25,140, 70, 35,114,115,115, 81,108,188,138,
+118, 8,175, 53,173,213, 12, 94, 87,219, 39,182,126, 98, 77,155,233, 70,255, 34,118,253,154,119,179,159,145, 58, 24,183,211,109,
+176,166,239,141,137,137,225, 9, 33, 54, 87, 78,125,190,215,214,151,121,161, 80, 88,175, 58,143,143,143,247, 7, 48,230,224,193,
+131,255,226, 56,206,100,215,150,132, 2,129,192, 59, 62, 62,126,242,134, 13, 27,246, 56,228,152,115,103, 9, 75,239,148, 72, 69,
+ 34,137, 55, 37, 36,126,188, 64,226,197, 9, 4, 66,142, 80,224,136,144,229, 5, 2,147,128, 35, 70,157,128,213,123,139, 69,228,
+155, 99,123,140,137, 73,147, 56,228, 59,206, 99,121,121,185, 70,175,215, 51, 0,160,211,233,184,143, 62,250,168,146,225, 47, 89,
+178,228, 31,245,109,239, 67,135, 14,157,106,251,255,192,129, 3, 41, 13,209,135, 40, 71,218,255,226, 87, 98, 96, 44, 41,193,236,
+206, 29, 96,239,187,119, 90, 11, 25, 61, 58, 10, 64, 21,230, 63,122,244,232,104, 0,100,244,232,209,209,235, 70,127,101,177, 44,
+182,111, 84, 37,189, 51,152,179, 38, 7,115,214,228, 96,218,138,203,120,125,209, 31, 24,251,207,115,245, 31,232, 10, 10,156, 18,
+ 12, 30, 22,243,183,250,252,249, 90, 44, 1, 48,211, 52,250,246,233,211, 16, 66, 6,191,101,203, 22,108,217,178, 5, 10,133,162,
+242,112, 81,224,225, 21, 10, 5,162,163,163, 43,153,191,253,195,132,132, 4,149, 51, 3, 19,195,176, 22,205,223,100, 49,253, 87,
+103,254, 44,203, 66,103,208,185,244,129, 54,139, 65,117,171, 65,122,122, 58,210,211,211,171, 8, 3, 46,125,111,102,213,241,208,
+122, 93, 47, 33,209,198,252,199,141, 27,135,229,203,151, 87, 50,127,145, 80,228, 42,243,183, 13,224,181, 29, 78,195,128,124, 84,
+140,233, 11, 62,109, 54, 10,110,228,131, 31,211,241,175, 66, 72,155, 13, 97,147, 16, 32, 32,224,161, 74,198,186,210, 92, 24,210,
+214,131,231,121, 92,188,120, 17,131, 7, 15,134, 76, 38,171,194,248, 3, 3, 3, 97, 48, 24, 96, 48, 24, 80, 88, 88,136,241,134,
+ 25,248, 38,240,189, 90,105, 58,105,242, 38,213,210,186,202,184, 27, 74, 89, 33,181, 48,127,167,219, 96,245,239,141,137,137,225,
+211,211,211,145,150,150,134,216,216, 88,190,190,223,107,101,254, 96, 24,198,237, 62, 17, 31, 31, 47, 5,240,246,129, 3, 7, 62,
+ 90,180,104,209, 9, 66,136,220,118, 0,104, 22, 28, 28,236,117,232,208,161,181,241,241,241,131,235,162,243, 85,202, 90,129,128,
+136, 36, 52,195,251,153, 76,230, 80,150,227,154,177, 28, 23,193, 18,210, 2, 2, 65, 48, 33, 36, 0, 68,224,199,241, 8,226,105,
+ 46, 64, 99, 48,123,135,250, 49, 2,170,143,214,169, 58,210,235,245, 76,117,173,255,113, 7, 85, 23,227,110,215,174, 29,218,250,
+248, 65, 95,116, 23,207,247,236,229, 50,131,182, 9, 17, 11,183, 44, 6,128, 74,230,111,179, 34,236,216,177, 35,211, 38, 4, 20,
+104,238,160,215,156,126, 46, 9, 25, 58, 3, 11,157,129,197,221, 50, 19, 10, 75,140,184,125,207,232, 22,227,179,117, 22, 71,204,
+255, 81,161, 14, 33, 0, 70,218, 4,163,209, 88, 31,242,188, 66,161,128,205, 71, 30, 18, 18, 98,175,205,194,133,193,164,138, 38,
+ 92,135, 41,209,225,160, 71,155, 77, 22,205,223, 68,131, 54, 87,101,254,102,179, 25, 58,157, 14, 90,141,246, 81, 87, 11,191,101,
+ 75, 90,213, 79,178,252,193,122,223,173, 1,207,158,249,219, 24, 63, 69, 81,144, 74,165,240,246,241,170, 87,134, 71,191,148,192,
+215,118, 56,122,119,223, 63, 23, 32, 24, 3,192, 12,157, 14, 0,240,201,186,142,243,185,101,150, 65,126,232,116,152, 47, 46, 4,
+ 74,203, 92, 43, 64, 43,220,253, 30,111,148, 2, 0,214,175, 95,143, 29, 59,118,224,211, 79, 63,197,201,147, 39, 97, 50,153, 80,
+ 92, 92,108,211,202, 42,211,135,135,135,195, 0, 64,128,155,143,164,189,212,209,238, 73, 61,132, 70, 82,135, 5,207,101,154,246,
+150,176,154, 98, 2,220, 97,254, 0,224,174, 16, 16, 31, 31,223,216,202,252,167,124,255,253,247,151,230,205,155,247,210,198,141,
+ 27,209,174, 93, 59, 0, 64,203,150, 45,161, 86,171, 37, 11, 23, 46, 60,125,232,208,161, 31,227,227,227,229,181,150, 18,199, 19,
+112,140,148,101,153, 32,150, 97,155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,
+242,140, 84, 32,240, 22, 50,180,223,205, 51,103, 37, 19, 67,190,112,152,239,156,156,156, 82,157, 78,199,213,100,230,239,222,189,
+251, 85,154,166, 27,172, 33,117,239,222,189,193,104, 9,235, 98,220,255,153,242,214, 95,204,182,224, 54,102,119,238,128, 21, 22,
+ 6,237,146,212,106,211,254,109, 76,191,218,239, 84, 94, 7,119,109,236, 82,230, 43, 12, 44,180,122, 6, 26, 29, 3,117, 5, 3,
+149,150,113,189, 87,214, 16,249,111,175,229,219,255,127,227,198, 13,168, 84,170,135, 54, 98,164,164,164, 64, 46,151,195, 22,244,
+ 87,205,215,207,167,164,164,192,104, 48,212, 71, 0,224,215,173, 91,135,130,194, 66,136, 4, 2,132, 53,110, 92,133,249, 63,251,
+236,179, 56,120,240,160,179,131, 19,137,142,142,174, 46, 4, 84,177,100, 56, 27,171, 64,155,104,208, 38, 19,204,102, 26, 12,195,
+ 86, 50,127,147,201, 4,189, 94,143,138,138, 10,104,181,174, 11, 0,246, 46, 0, 27,220,213,252,183,164,109, 1,120,160,212,202,
+104,172, 78,109, 16,158,183, 8, 1,105,105,136,179,104, 80, 46,245,149,234,204, 95, 36, 18, 65, 34,145, 64, 42,149, 66, 42,149,
+214,187, 77,213,230, 18,168,105, 94,188, 61,198,166,108, 5,255, 98, 4,238,245,239,133, 96, 12,128,236,229, 85, 96,238,150, 0,
+ 1,126, 16,150,109,194,174, 47, 78, 3, 2,129, 75,121,169,175, 43, 64, 39,176,140, 41, 75,151, 46, 69, 73, 73, 9,214,174, 93,
+139,238,221,187, 99,209,162, 69,232,213,171, 23, 12, 6, 67,117, 13,205, 38, 82, 63,108,198,239, 44,131,118,215, 29, 80,155, 32,
+225, 50, 29,235, 44,142,202,190,225,174,107,204,158,249, 87, 50, 27,171, 16,224,162, 59,192,247,194,133, 11, 95,190,243,206, 59,
+ 71,186,118,237,234, 7, 0, 11, 22, 44, 64, 78, 78, 14, 0,160, 95,191,126,248,229,151, 95, 48,112,224, 64,239,241,227,199,231,
+102,102,102, 30,120,227,141, 55,198,159, 61,123,246,190,146, 13, 10, 14,226,110,220,200,101, 50, 21, 7,247,182,105,211, 54, 51,
+162,165,252,146,192, 87, 86, 44, 32, 98, 29, 37, 17,233, 41,169,151,150, 22, 10,104,240,102, 1, 39, 53,251,106, 11,203,124, 78,
+ 30, 58,215,167, 81, 96,216, 47, 14,133, 81, 59,159,255,182,109,219, 94, 31, 51,102,204,247, 54,179,191, 70,163,161,196, 98,113,
+189, 27,146,205,236,127,224,192,129, 7,107, 1,176,105,249,145,173,219,194, 88, 82, 2, 93,129,133, 9, 14,182,106,135,174, 90,
+ 1,110,252,113,253, 62,218, 53, 93,151, 93, 44,114, 41,243,245,101,254,246,140,159,231,121,155,143,191, 18,102,179,185,242, 80,
+169, 84,208,233,116, 80, 42,149, 15,109,228,176,205,243,223,183,111, 95,117, 75, 0,159,146,146,130,110,221,186,193,104, 52, 84,
+ 14,116, 41, 41, 41, 46,153,235,215,124,181, 6,102,179, 25,205,194,195, 97,102,217,218,152,191, 43, 3, 9,169,193,244, 95, 57,
+117,177, 46, 75,198,125, 2, 0,109,174,100,254,167, 78,158,130,222, 96,128, 86,171,133, 90,173,134, 74,165,170,162,217,185, 10,
+155, 27,160, 30,126,127,148,149,150,161,172,172, 20,165,101, 74,148,150,149,161,172,172, 12,101,165, 22,141,180, 67,199,142, 80,
+ 90,255,119, 85,251, 7,128,158, 61,123,254,165,245,123,123,195,199,199, 23,190, 62,190,208,106,181,209,245,100,254,110,187, 3,
+114, 63,157, 2,209,203,171, 16,140, 1, 16,102,173,130,121,235,116, 32,192, 15, 59,223,141,193,173,157, 55, 49,106,249, 6, 64,
+248,144,151, 21, 49,222,130, 44, 92, 6,157, 78, 7,163,209, 8,189, 94,143,172,172, 44, 44, 91,182,172,198,228, 94, 94, 54, 11,
+202,117,119,152,183,187, 90,181,125,249, 18, 39,175,235, 35,100,184,218,103,171,208, 73, 75, 75, 35,177,177,177, 54,230,239,182,
+101, 66, 40, 20, 18,134, 97,170, 11, 5,112, 53, 22, 96,195,134, 13,215, 98, 99, 99,187,111,220,184,113,240,209,163, 71,125,135,
+ 14, 29,122,210,198,252,173, 10, 36, 36, 18, 9,127,235,214, 45,209,222,189,123,219, 7, 6, 6,158, 26, 48, 96, 64,110, 77,180,
+ 94,125,229, 85,174,109, 68, 59,109,191,126,253, 98, 46, 93,250,243, 25,141, 78,219,152,103,204, 12, 40,152, 25, 19,101, 50,153,
+ 76, 6, 13,138, 52,156,201,168, 45,204, 47, 98,118,237,222,147,212, 40, 56,164,152,166,245, 14,213,247,154,180,255,242,242,114,
+ 33, 0,248,249,249, 61,182,110, 1,170, 54,237,127,203, 39, 31, 89,164,230,162,187, 85,158,185, 26, 11, 48,122,244,232,232, 53,
+111,175, 4, 96, 9,248,219,177, 99,135,194,198,244,109,107, 2, 12,251,225, 37, 0,192,153,229,191,219,226, 3, 30, 22, 42, 27,
+ 99, 65, 65, 65,165,182,111, 99,250,118,149, 11,173, 86, 11,163,209,104, 55,136, 60,188, 60, 78,157,106,137,253, 48, 51, 12, 46,
+ 93,186,132,179,103,206,160,123,183,238, 48, 26,141, 48, 24,140, 48, 26, 12,248,241,135, 31, 96, 75,231, 76, 71, 79, 78, 78, 70,
+167,142,157, 96, 54,155,113,237,218, 53, 48,102, 26,133, 5,133, 13, 90,166,182,107,235,154, 5,182,181, 11, 28, 91, 0,204, 38,
+ 48,172,197,236,127,226,196,239,208, 25,116,168,208,106,160, 86,171, 81,174, 82,161,188, 92, 89, 47, 65,204,102, 9,112, 83,251,
+ 7, 0, 28, 57,114, 4, 90,173, 22, 90,173,198,122,214,162, 81,112, 48, 58,116,236,136, 43,151, 47,227,240,145, 35, 46,211,180,
+105,255, 66,161, 8, 94, 94, 94,240,241,241,129,175,143, 15,124,124,188,160, 44, 87, 70, 39, 36, 36,100, 58,213,231,234, 97,234,
+175, 13,231,115,203, 96,190,184, 16,101, 56, 6, 50,114, 5,200,128,127, 33,247,211, 41,120,113,249,247,144,138, 40, 64, 36,180,
+ 28,238,112, 29, 55, 93, 1,133, 47,124,133,160, 77, 47, 64,175,215, 35, 40, 40, 8,229,229,229, 40, 47, 47,199,241,227,199,113,
+247,238,221, 74, 51,113,101,250,194, 66,188, 27, 40, 67, 35,175,146,186, 52,224,104,123,166, 26, 27, 27, 27,101,247, 44,170,218,
+179,104, 23,251, 5, 95, 7, 3,111,136, 25, 5, 46,107,254, 53,125,111, 90, 90, 26, 73, 79, 79, 39,245,252,222, 42, 66,128, 59,
+204,223,134,143, 63,254,248,194, 75, 47,189, 52,126,233,210,165,237,207,159, 63, 63, 64, 38,147, 9, 94,124,241, 69, 34,145, 72,
+192,113, 28, 25, 57,114,228,133,153, 51,103,118,235,210,165,203,206,201,147, 39,191, 62,121,242,228, 90,125, 81, 9,211, 18,184,
+ 63, 47, 95, 59,213,165,107,183,215, 78,157, 60, 57,118,231,238, 95,151,100,159, 60,217,248, 82,206, 21,233,181,194, 92,254,199,
+149,155,101, 75,147, 63,237,116, 96,247,238,228, 54,173,219,236,242, 9,243, 62,178, 97,195, 6,214,217, 18, 29, 58,116, 40, 78,
+157, 58,213, 35, 37, 37,101,161,209,104, 20, 45, 90,180,232,179,157, 59,119,142, 43, 44, 44,124,232,140,195,169, 58,170,237, 65,
+240,205, 60, 40,129, 74,237,223,134,193, 33, 33, 88,129, 43,206,107, 29, 86, 19,255,149,211,151, 16,208,190, 17,134,253,240, 18,
+118, 76,220,174,176, 73,111, 54,230,111,211,254, 93,153,101,240,203,210, 30, 13,195, 97, 9,193,229,203,151, 97,107,172,213,205,
+203, 34,145, 8, 34,145, 8, 37, 37, 37, 24, 57,114,228,163,168, 39, 34,151,203,249,148,148, 20,244,233,211, 7, 70,147, 9, 6,
+163, 1, 70,107,112,147,193,104,113, 3,172, 94,189, 26,137,137,137,142, 6, 19,126,249,242,229, 96, 89, 22,167, 79,159,129, 72,
+104, 49,219,182,109,219, 22, 55,243,242, 80, 88, 88,136, 77,155,126,198,184,113,175, 2, 0, 95,205, 18, 80,235, 0,148,154,154,
+ 42, 6,192, 36, 36, 36,112, 53,105, 64,174, 76, 85,180,105,254, 89, 89, 89,208, 85,232, 43, 5, 48,141, 86, 3,141, 70, 13,141,
+198, 61, 23,128,189,246, 63,110,220,184, 74, 11,128,171,130,192,184,113,227,170, 92, 71,200,229,232,208,209, 18, 20,119,229,242,
+101,220,180, 90, 60,198,141, 27,231,114,212,126,255,167,251, 67, 34,150, 64, 38,147, 65, 42,149, 66, 34,145,160,168,168,200,105,
+230,111,167,237, 55,104, 3, 28,187,108, 29,126, 1, 48, 98,233,255,129, 79,155, 13, 18,151,140,243,185,101, 32, 65,129,184, 94,
+160,177,104,255, 46,186, 0,236,250, 31,177, 9, 2,246,215, 14, 97, 48, 0, 2,139,178,247,151,121,223,194,232,205,102, 51,190,
+249,230, 27, 12, 30,252, 87, 92,216,193, 73,225, 64,177, 30,237,247,148,163, 71, 72,203, 26, 73,214, 16,229,110,239,242, 84, 56,
+ 72,235, 44,195, 38,245,176, 40,212,101,141,112, 89,144,120,208,223,107, 21, 2,234, 61, 11, 96,233,210,165,155,102,204,152, 17,
+114,238,194,133, 56,131,193,208, 77,161, 56, 36,147, 72, 37, 66,138, 80, 56,116,232,144,111,167, 78,157, 54,196,198,198,254,107,
+236,216,177, 14,181,245,204, 67,251,185, 81, 47,141, 58,220,189,123,207, 57, 52, 99, 26,113, 61,231,218, 18, 46, 47,151, 1,192,
+ 75, 65,153,187,182,105,159, 22, 26, 26,178, 71, 32, 20,255,248,239,121, 73,244, 23,139, 62,119, 88, 75,125,250,244,249,124,232,
+208,161, 0,128,146,146, 18, 28, 56,112,192,239,187,239,190, 91, 2, 0,167, 78,157,234,211,185,115,231,125, 79,132, 0, 96, 91,
+248,231,217, 31, 55, 58,210,236, 93,153, 18, 72,182,205,217,194,247,154,211, 15,193, 93, 27, 87, 50,253, 74,115,234,197, 34,156,
+ 89,254,187,171,102,171,134,154,147, 74, 0,240, 29, 59,118,196,197,139, 23,171, 48, 22,149, 74,149, 11,160,181,139,210,252,131,
+180, 4,220,247,155, 63,254,240, 35,140, 70, 35, 76,180, 9, 52, 77, 99,249,242,229,117, 45,146,195, 47, 95,190,188,242,130,227,
+ 88, 72,101, 62, 48, 24,140,184,124,233, 18,132, 34, 17,204, 52, 13, 47,111, 47,108,218,180, 9, 2,129, 0,113,113,113,120,246,
+217,103,249,178,178,218, 3,188,150, 47, 95,190, 47, 33, 33,129, 78, 77, 77, 13,181,149, 77,181,117, 0, 92, 50,109,206,153, 51,
+ 7,199,142, 29, 67, 69, 69, 5, 42,116, 58,104, 53, 26, 43,243,215, 64,171,209,162, 66, 91, 1,157,221,128,239, 76,217, 69, 70,
+ 70,242,217,217,217,149,218,127, 77,211, 0,157, 93, 4,200, 58, 23,191, 74, 93,216,152,190,205,247,232,202, 42,133,182, 21,254,
+ 0,192,199,203, 7, 82,153, 20, 90,173, 54,218,230,218,113,131,249, 63,144,249,218, 54, 33, 96,204,210,239,192,111, 5, 26, 77,
+ 74, 69,230,123, 49, 24,152,244, 19, 32, 18,193, 91, 90, 63, 63,103,117, 65, 0, 0,198, 29, 27,231,224,173,123,232,186,207, 11,
+ 69,191,234, 81,190,248,175,187,102,179, 25,131, 6, 13, 2, 0,132, 7,202,240,223,212,230,248,116,217,109,124,117,198,224, 72,
+ 35,182,159, 22,135,218,254,183, 75,155,233,198,152,213, 80,115,235, 27,194,231,255, 32,191,183, 82, 8,104,136,246,247,229,151,
+ 95,126,249,198,164, 55,246, 62,213, 59,178,143, 86,163, 9, 98, 88,198, 20, 22, 22, 86, 18, 30, 30, 94,164,209,104,206,143, 29,
+ 59,214,233, 65,225,215,237,191,114, 0, 54,189, 54,225,173,172, 1, 3, 7,110,151,201,100,254, 4, 60, 71, 8, 1,199,241,106,
+131,174, 92,113,245, 66,190,214, 91, 34,118,106,156,183, 49,127,192, 18, 72, 93, 61, 80,111,217,178,101,255,122, 34, 4, 0, 43,
+ 83,119, 88, 97, 59,118,236,112,185,177,158, 89,254, 59, 15, 0, 54, 65,192,142,241, 55, 36, 67,119,187, 35,117,237,218, 21,167,
+ 78,157, 66, 73, 73,165,137,176, 53, 0,216,152,223,196,137, 19, 31,117,125, 85, 41,163,148,148, 20,254,181,137,175, 97,245,234,
+ 53, 86,159, 57,131, 57,115,230,212, 57,125,201,197, 21,244, 44,154,211,193,131,142, 54,155,232,184,124,249,242,107, 9, 9, 9,
+197,169,169,169,130,132,132,132,202,128, 64,235,180, 64,167, 7, 58,155,198, 60, 96,192,128, 6, 47,187,200,200, 72,222, 94,139,
+183,143, 1,112, 99, 5, 64, 2,128,223,180,105,211,125, 90,190,213, 66,224,114,123,222,180,105, 19,113,213, 98,224, 12,234, 50,
+253,187, 42, 44,140, 93,182, 14,176, 91,248,103,200, 71,127, 77, 71,214, 53, 84, 69,217, 89, 0, 28,173, 4, 88, 56,160, 16,133,
+ 0,122,125, 26,136,197,167,219, 33, 4, 64, 73,174, 14,109,218,180,177, 48,141,197,129,120,238,169, 16, 68, 60,151,227,172, 70,
+236,180,123,211,154,150,184, 59,222, 52,208,152, 87, 47, 90, 15,233,123, 27, 12,235,214,175,187, 6,224, 90, 67,209,251,241,167,
+111,243,208, 0, 81,161, 13, 25,152,103,197,172,135, 81,158, 15,123, 51, 32, 50,122,244,232,168, 29,203, 31,203,189, 0, 8, 0,
+254,169,167,158,194,158, 61,123,140, 86,166,207, 1,240,122, 64,150,135,122,195, 22, 36,152,152, 56,141,183,106,254,143, 36,111,
+115,230,204,105, 89,147, 89,210,110, 26,161, 43,218, 14,121,192,117, 92,153,159,250, 46,251, 91,219,170,124,174, 50,113, 71,107,
+251, 55, 4,234,227, 18,152, 59,119, 46,110,220,184,209, 96,121,113,102,121, 95, 87,113,230,131,114,156,129, 37, 48,116,112,172,
+ 12,191,157,104,135, 48, 47, 31,252,153,125, 15,237,157,100,254, 78,180,191,199,117, 57, 92,242,128,222,245, 44,207,238, 28,154,
+ 54, 48,189,228,135,149,241,135,190, 27, 96,117, 11,131, 27,150,132, 7, 46, 4,140, 28, 57, 82,250,132, 53, 64,183, 52,251,134,
+250,237,212,212, 84,219, 10, 53, 76, 66, 66, 66,125,167, 50,121,208,240,204,191, 94,117,145,148,148,212, 32,117,153,154,154, 42,
+ 76, 24,152,240,192,219,197,145, 52, 3,142,164,229, 60,246,125,214,211, 50, 61,120,228,141,208,221,125,132, 61,240,192, 3, 15,
+ 60,240,192,131, 39, 23,148,167, 8, 60,240,192, 3, 15, 60,240,192, 35, 0,120,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3,
+ 15, 60,240,192, 3, 15, 60,240, 8, 0, 30,120,224,129, 7, 30,120,224, 1, 0,156, 4, 80, 98, 61, 63,145,168, 50, 11,224,220,
+185,115,110, 71,166,214, 20, 76,232,161,231,161,231,161,231,161,231, 36,189, 58,167,137, 62, 6,244, 60,245,235,161, 87,133,249,
+159, 61,123,118, 24, 96,217, 96,146, 16, 98,124,220,190,215, 99, 1,240,192, 3, 15,224,239,239, 79,249,251,251, 19,127,127,127,
+ 17, 0,193,227,150, 63,219,190,243,118,251,207,215, 23, 53,173,143,239,193, 99,132,255,251,191,255,139,122,194, 63,161, 15, 0,
+219,178,195,162, 39,245, 35, 60, 2,192,223, 28,245,216,110,221,101, 12, 27, 54, 44,202, 58,232, 86, 30,214,123,127, 75,122,143,
+ 57, 72,203,176, 48, 2, 0,106,181,154, 83,171,213,188, 90,173, 54, 3, 96,221, 33,246,246,115, 93, 11,166,140,232, 58, 26, 0,
+166,140,232,250,195,219,207,117, 93, 3, 0,115,198, 60, 69,230,188, 28, 41,122,123,120, 23,183,214, 20,177, 95,138, 54, 45, 45,
+173,202,230, 59,245, 97,254,118,237,190, 33,215,218,175, 47,205,134,166,247,196, 50,255, 61,123,246, 40,254, 6,159,194,160,225,
+ 86,116,172, 21, 77,130, 37,164,109,227, 80,170,133,188, 25, 9, 11, 8, 22,120, 75, 68, 13,246,123,194,191, 73,155,162, 0,200,
+ 96, 49,199,112,240,160,138, 0,224,196,222, 42, 38, 0,146,250,254, 84, 70, 70, 6,146,147,147,171, 44,255, 55,107,214, 44, 91,
+ 71, 39,238,208,227, 54, 7, 86,173,232, 87, 50, 30, 23,122,143,125,213, 71,120,203,248,136, 86,114, 0, 64, 17,205, 76,104, 44,
+ 22,254,100,123,120, 69, 83, 33, 41, 42, 45,165,157, 33, 52,121,120,151, 28,150,229,195,159,238,223,200,175,125,251, 1,251, 37,
+ 18,234,214,180,164, 62,255,254, 15,185,136,123,106,253,255,137,132,228, 87,128, 92, 2,208,217,213, 76, 86, 95,138,182,158,203,
+205, 86, 97,254,118,109,223,221, 65,154,184,120,255, 97,211,123, 98,153, 63,199,113, 32,132, 96,240,224,193,252,145, 35, 71,136,
+139,117, 44, 6, 96,110,136,252, 4, 5, 5, 77, 81, 42,149, 95,187,249,186, 4,128,209,206, 18,208,160, 24,208,173, 7,121, 45,
+ 60, 66,168,106,209, 72, 16,218, 49,156, 18,146, 80,162, 87,171, 57, 41,194, 88,170,103, 51,246,245, 81,195,217,250,254,134,179,
+ 2, 64, 8,128, 72, 0,217,176, 4, 61, 60, 78,240, 3, 48, 20,192, 24, 0,219, 0, 28, 0,160,105, 0,186, 63, 3,120,181,129,
+ 24,236,163,147,140, 40,135, 70,158, 62,214, 14, 21, 10,160,216,221,129,119,230,204,153,104,209,162,197,125,219,133, 38, 39, 39,
+ 71,231,231,231, 43, 86,174, 92,233,202, 32,204,175,159,238,141,248,129,247,111, 46,195,109, 14,196,134,255,210,152,180, 74,247,
+200,232, 45, 95,190, 60,234,195, 15, 63, 84,196,197,197,225,231,159,127, 38, 0,240,206, 59,239, 68,173, 93,187, 86,209,162, 69,
+ 11,112, 28, 7,131,193,128,168,168, 40,108,221,186,213, 33,205,117,203, 63,139,106,255,225, 22, 69, 70,175,102,209,243,179,211,
+ 51, 1, 96,205,194, 53, 81, 87,231, 51, 10,182,133, 31, 52,156, 55,202, 13,126, 40,246, 63, 21,125,242,198, 39,153,142,232,181,
+106, 22,214,184,133, 88,118,119,250,180,137,166, 48,153, 88,172, 81, 26,200,242,239, 54,254,244,209,212,215, 16, 40,147,241, 70,
+ 51,203,127,178,250, 59, 83, 81,105, 41,105,220, 56, 88, 88, 84, 84, 86,107, 35, 57,179,237,229,182, 59,118,222, 14, 24,240,116,
+ 72,114,207,222, 65,162,245,235,175,203, 67, 26,201, 74, 63,127,239, 68,242,140,151,122,176, 79,247,111,148,149,115, 77,155, 63,
+ 41,190,245,200,111,246, 95,172, 15, 83,172,175, 38,197,215,100,241,170,167, 16, 80,219, 59,238,230,181,161,233, 61,177,204,127,
+214,172, 89, 24, 60,120, 48,255,223,255,254,215, 29, 82, 52, 44,102,119,166, 1,178, 85, 20, 20, 20, 52, 70,169, 84,110,115,227,
+ 93,127,171,210, 25, 8,224,110,124,124,124, 0,128, 41,214,107, 27,238, 1,248,117,195,134, 13,185,206, 18,253, 98,237, 23, 20,
+ 93,106, 18,209, 38,163,180, 28,102,169, 72, 36, 20,106,140, 82, 74, 44, 54,112, 2, 63,111,134,150,153,205,194,162, 59,166,239,
+191, 89,111,124,125,242, 36,182, 62,109,199, 25, 23, 64,115, 0, 63, 0,136,177,158,155, 63, 70,109, 42, 24,192, 38, 0,207, 3,
+ 56, 14, 96,132,245, 58,184, 1,104,191, 2, 39,252,165, 15,211,196,254,128,208, 15,192, 85, 0, 17,238,104, 35, 54, 19,186, 61,
+243,159, 53,107,150,194, 78,243,175,124,230,140,185,221,150,198,158, 89, 83,175,148,131,122,165,188,242,218,246,236, 81,208, 3,
+128, 19, 39, 78, 40,164, 82, 41,178,178,178,238, 19,182,242,243,243, 73, 65, 65, 1,233,215,175, 95,244,238,221,187,157, 42,195,
+198, 39, 46, 41,120,169, 8,221, 74,196, 85,180, 97, 66,241, 88,147,255, 6,249,161, 32,142,200, 71, 92,140,102,238,188,224,208,
+108, 26,213, 74,206,183, 16,203,238,190,255,238, 4, 83, 51, 31,177, 88,125,233, 24,241, 42,190,128, 25,131,218,162,105,128, 12,
+197,103,142,146,123,167,143, 81,179,166, 76,164,163, 90,201,249, 14, 94,190,230,186, 52,152, 70,141,196, 67,196, 98, 74,122,252,
+248,221,153,167, 78,222,233, 24,214,172,149, 57,160, 81, 51,226,235, 11,175, 86, 17, 94, 17, 65, 65,146, 54, 28,207,155,118,157,
+ 44,214, 61,194, 54,204,219, 51,123,219, 81, 67, 31,229,157,165, 85,237, 92,253,168, 41,221,195,162,247,196, 50,255,221,187,119,
+ 43, 8, 33,160, 40, 10,217,217,217, 56,122,244,168, 91,180, 88,150,189, 96,181, 0, 52, 68, 60,139, 76,169, 84,110, 11, 10, 10,
+122,217,141,119,205,214,250, 50,197,199,199,135, 1, 88,113,240,224,193,127,103,100,100,188,111, 59, 14, 28, 56,176, 92,161, 80,
+228,196,199,199,207,119,134,224,172,185,179,132,165,119, 74,188, 12,188, 41,128, 23,146, 80, 94, 34,105,204,137,196,141, 57, 66,
+133,114, 68, 24,194, 8, 4, 65, 28, 71,252,117,132,245, 97,196,148,236,155, 99,123,132,210, 23, 67, 31,168, 0,240, 5,128,131,
+ 0,102, 88,207, 95,212,163,176, 3, 1, 44, 0,176,219, 90,112,187,173,215,129,110,210, 59, 2, 96, 15,128, 4, 0,107, 1,252,
+195, 74,243, 72, 61, 27,133,191,245,236,221, 0, 26, 54,172, 26,246, 2,235,249,113,195, 83, 0,142, 1,104,108, 21,158, 94,115,
+229,229,140,140, 12,133,189,217,127,214,172, 89,138,228,228,228,232,228,228,228,104,123, 33, 32, 57, 57, 57, 58, 35, 35, 67,225,
+ 12, 61,123, 51, 61,245, 74, 57,174,237,153,136,107,123, 38, 86, 97,218,220,230, 64,184, 75,207, 42,228, 16,119,232,165,164,164,
+ 68, 29, 63,126, 28, 19, 38, 76, 64,126,126, 62, 18, 18, 18,162,106, 74, 35,149, 74, 21, 77,154, 52,113, 88,126,169, 41, 41, 81,
+ 77,142,255,129,130, 9, 3, 32,206, 87,227,235, 5,159, 71, 85, 87,142, 83, 82, 82,163, 68,198, 22,138,160, 38, 6,135,204,127,
+202,228, 87,232, 79,102, 78,228,197,183,206,136, 3,239, 93, 36, 23,239,106, 16, 30,226,141,167, 59,133,161,169,234, 42,110,104,
+ 13, 16,114, 60, 2,136, 64,244,207,183, 38,240,211,223,121,243,106, 84, 43,121,173, 76,167, 92,165, 13,234,211,199, 39,185,107,
+191,231,205,190, 65,173, 37, 62, 1,161,156,204,199,219, 20,212, 40,216, 24, 18,222, 92, 88,174,212, 74, 52,106, 6,229,106,147,
+211,131,144,213,207,239,144,113, 58, 25, 15,112,159,230, 95,147, 80,238,130, 16, 64,106, 56, 87, 63,106, 74,231, 20, 61,126, 75,
+224,125,135,139,244,158, 56, 80, 20,197,239,221,187, 87,193,113, 28,222,123,239, 61, 16, 66,112,244,232, 81, 88,182,222,229,136,
+ 27,244, 64,211,244, 89,171, 5,160,190,110,108, 37, 0, 40,149,202,173, 65, 65, 65,209,238,240, 79,154,166,133, 0,190, 62,112,
+224, 64,252,162, 69,139,238, 16, 66,196,182, 3,128, 40, 56, 56,152, 28, 58,116,104, 94,124,124,252,116, 71, 4, 5, 68, 36,161,
+ 25,222,207,100, 50,135,178, 28,215,140,229,184, 8,150,144, 22, 16, 8,130, 9, 33, 1, 32, 2, 63,142, 71, 16, 79,115, 1, 26,
+131,217, 59,212,143, 17, 80,125,180, 15, 76, 0, 8,183,106,252,159,194,178,219,231,167,214,235,112, 55,126,107, 34,128,124,107,
+ 3,159, 11, 32,200,122, 38,214,251,174,238,181,251, 47, 0,215, 1,172,177,154,131, 36,214, 6,241,149,245,126,125,246, 95, 30,
+ 12,139,171, 99, 72, 3,245,129, 55, 1,204,183,158, 31, 55,116, 6,176, 29,192,179, 86, 75, 74,103,119, 9,217,152,191, 61,211,
+183, 23, 2, 92,110,156, 86,230,111, 67,117, 33,192, 29,122,213, 6, 88,226, 42,189,195,135, 15,131,166,105,244,238,221, 59,186,
+ 67,135, 14,200,203,203,171,252, 62,142,227, 32,151,203,249,121,243,230, 41,142, 31, 63,142,145, 35, 71, 58, 28, 80,140, 89,167,
+ 64,209, 12, 84,189,229,209,166, 14,193,184,190,238,240, 95, 76,139,227, 49, 77,190,142, 63, 60, 47, 88,113,243,184, 63,134,189,
+113,205,241, 0, 69, 9, 42, 74, 46,102,113, 69, 42, 35,202, 42,104, 62,166, 71, 11,222, 95, 38,198, 29,149, 14, 37,106, 3,226,
+122,182,224, 41, 66,248,223,127,221, 7,245,145, 19,252,153,109,187,110,213, 69, 46,235,108,211,105, 33,161,126,173,155,182,136,
+ 96,188,100, 92,235,193,207,199,249,180,234,157,240, 66,227,118, 47, 14, 11,106, 26,217, 93, 89,209, 56,198, 76,155,205, 55,114,
+117,126, 78, 50,127,222,217, 45,104,211,210,210, 20, 14,102, 6,212,248,204, 9,151,156,103,118,192, 67,212,252,121,158,135,217,
+252,151,203,126,224,192,129,182,254,226, 46,227, 50,139, 68, 34, 51,199,113,199,173, 90,120,125,132,128,208, 74, 73, 64,169, 84,
+ 4, 5, 5, 37,184,240,110,185, 74,165,146, 28, 62,124,248,181, 3, 7, 14, 60,255,253,247,223,151,205,155, 55,175,197,198,141,
+ 27,209,174, 93, 59, 0, 64,203,150, 45,161, 86,171,201,194,133, 11,139, 15, 29, 58,244,121,124,124,252,192, 58, 41,114,140,148,
+101,153, 32,150, 97,155,153, 89,115, 27, 1, 69,154,138,133,148, 72, 42, 18, 24,132, 94, 98,149,183,175, 64, 35,144,242,140, 84,
+ 32,240, 22, 50,180,223,205, 51,103, 37, 19, 67,190,112,187, 61, 59, 18, 0,158,179,106,135,246, 56,102,189,239, 10,198, 3,120,
+ 15,128,220,202, 8,255, 0, 80,110, 61,207,183,222,127,207,154,206, 25,120,193,226,107,137,183, 94,155,236, 14, 88,239, 79,193,
+253, 91,249, 58,139, 87, 0,124,103, 61,215, 23,111, 0,152,102, 45,179,105,214,235,199, 5,109, 96, 9,154,220, 5, 32, 17,192,
+ 84, 0, 81,158, 97,171,118, 20, 22, 22, 42,250,246,237,139,169, 83,167,102,246,237,219, 23, 39, 78,156,192,218,181,107,163, 26,
+ 55,110,172,160, 40, 10,121,121,121,164,180,180,148, 76,159, 62, 61,250,200,145, 35,138,201,147, 39,215,217, 57,251,223,188,163,
+ 40,234,219, 17, 9, 83,167,102,254, 25,198, 70,119, 86, 7, 41, 82,215,166, 70, 89,164, 19, 96, 77,222, 27,100, 83,105, 12, 25,
+ 60,189, 48,250,104,154, 92, 17,253,244,167,181,214, 79, 1,205,172,248,250,235,141, 65, 91, 47, 20,222,222,120, 38, 95,181,238,
+248, 13,221,205, 34, 35, 79,241, 20,140,122, 22, 37, 37, 52,178,243,203,217, 29,121,133,218,221,119,138, 84,191,220, 42,184,114,
+172,168,120,248,109,147,249,179,218,104,250, 5,134, 55, 51, 84,148, 55,237, 20,249, 12, 69,147,150,131, 11,175,108, 55, 4, 6,
+121,203, 90,117,236, 81,194, 51, 37, 23,136,192, 47,132,227, 56,193,189,123, 6,103,172,120,188, 45,226,223,142, 17, 87, 55,131,
+219, 95,195,154,158,119, 66,195,174,212,244,109,135, 51,233, 61,120,176,168,168,168, 80, 0,128, 80, 40,196,236,217,179,145,157,
+157, 13, 55,253,254,246, 48, 1, 48,153, 76, 38, 83, 97, 97, 97, 6,234, 23, 16,168,173, 98, 14, 80, 42, 83,131,130,130, 70, 57,
+249,174,212,104, 52,134,207,153, 51, 39,249,157,119,222,209,119,237,218, 85, 2, 0, 11, 22, 44, 64, 78,142,101, 55,202,126,253,
+250,129,227, 56, 12, 28, 56, 80, 50,126,252,120,237,149, 43, 87, 14,189,241,198, 27,125,188,188,106,102, 77, 28,199, 51,153, 7,
+ 15,238,205,203,187, 49,158, 53,179,141, 4, 34,153, 73, 64,164, 58, 74, 34,214, 83, 82, 47, 45, 45,242,170, 0, 37, 81,115, 82,
+214,172, 85,151,249, 40,118,158, 27,197,158, 58,235,118, 0,183, 35, 1, 96, 56,128, 67,213,238, 29,178,222,119, 22, 2, 0, 31,
+ 1,136, 3, 80, 86, 75,154, 50,235,243,143,224,156, 95,103, 60,128,253, 0,212,181, 60, 87, 91,159,143,119,163, 76,158,129, 37,
+134, 96,153,245,252, 76, 61, 26, 87,140,213,106,210,207,154,159,126,214,235, 24, 23,233, 4, 2, 8,112,226,112,213,149,210, 31,
+150, 85,172,108, 65, 72,183,172,150, 30,183,226, 60,170,107,252,213, 45, 2,174,130,219, 28,136,182, 35,127,168,188,110, 59,242,
+135,251,162,248, 93,165, 87,141,153,240,174,208, 91,189,122, 53,159,157,157,192,140, 1,163, 0, 0, 32, 0, 73, 68, 65, 84,141,
+211,167, 79,163, 89,179,102,252,111,191,253, 6,141, 70,131,203,151, 47,223,167,209,126,244,209, 71,153,157, 58,117,138,222,178,
+101, 75,173,244,190, 89,189,154,111,158,125, 17,161,167,115,160,104, 54,146,239,122,149, 81, 80, 26, 51,216,203, 21,247,165,125,
+255,163,183, 50, 91, 68,158,142,190,245,199, 43,181,106,207,215, 11, 10, 62, 40,160,153, 21, 37,165, 6, 57,109, 96, 3,115,238,
+104,124,118, 95, 41, 44, 51,181,236,142, 78,161, 65, 0,128,221,231,238, 9,115,139, 42,252, 0, 4, 22,209,198, 78,183, 77,230,
+216,220,194,194, 15,106,163, 57,228,133, 56,170,195,224, 37, 93, 25,221, 31,249, 45, 58, 14,149,137, 68, 44,125,253,143, 12, 85,
+ 97,254,229,123,197,249,191,231,107,148,133, 0, 69, 17,165,150,246,159, 18,215,211, 81,187, 33,177,177,177,213,153,113,117,179,
+186,253, 53,172,233, 31, 86, 52,190, 7, 13,136,193,131, 7,243,135, 15, 31, 6,183, 57, 0, 60,207,227,243,207, 63,199,145, 35,
+ 71,108,130,154,219,117, 80, 94, 94,110, 34,132, 12, 58,117,234,148, 49, 60, 60,124, 88, 61,173, 58, 1,128,101, 54,128,245, 60,
+ 17, 0, 23, 20, 20,228,140,162,102,108,220,184,177,122,223,190,125,111,110,220,184,209,255,232,209,163,226,161, 67,135,170,109,
+204, 31,176,108,119, 47,145, 72,112,235,214, 45,106,239,222,189,126,129,129,129,119, 7, 12, 24,144,203,113, 53, 79, 86,107, 27,
+209, 78,219,175, 95,191,152, 75,151,254,124, 70,163,211, 54,230, 25, 51, 3, 10,102,198, 68,153, 76, 38,147, 65,131, 34, 13,103,
+ 50,106, 11,243,139,152, 93,187,247, 36, 53, 10, 14, 41,166,105,189,219,179, 16,168, 26, 58, 6,101, 61,154,194,226, 23, 62,108,
+119,143,178, 94, 55,182, 62,183,221,171,171,131,206,128, 37, 64,239,102, 53, 58,213,143,155,214,116, 51, 28,208,163, 0,140, 5,
+240,189, 3,122,223, 91,211, 81, 78,208,179, 29,173, 96,137,115,248, 24,150,153, 4, 31, 91,175, 91, 85, 75,231, 12,189,241, 0,
+222,177, 50, 89,131,245,158,193,122,253,142,245,185, 51,244,226, 97,137,115,112,246,136,119, 34,127,159, 1,248, 15,128, 81,214,
+ 50,167, 0, 72, 1,156,176, 90,101,250, 2, 72,178, 62,175, 43,127, 24, 54,108,216,125,190,126, 91, 16, 96,245,216,128, 97,195,
+134, 57, 20, 6,134, 13, 27, 22, 93,221, 55,223,118,228, 15,247, 49,127,234,149,114,184, 75,207,166,101,186, 74,239,220,185,115,
+104,209,162, 5,238,221,187, 71, 10, 10, 10,200,221,187,119, 73,255,254,253,239, 11, 6,172, 52, 83,121,121, 41,164, 82,105,173,
+244,228,231,206, 65,213,162, 9,122,220, 59, 65,162, 11,246,144,151,238,110, 38,103,125,138,163,217, 44,117,141, 76, 62, 63,135,
+134, 68, 90,183,178,115,189,160, 96, 78, 1,205,196, 20,208,204,138,219,180,249,243,115, 55, 75, 66,244, 12, 3,181,209, 98, 28,
+187, 84, 82,130,155, 70,122,195,109,147,121,205,109,154,249, 34,183,176, 48, 29,117, 76,157,109, 42,239, 48, 39,160,105,191,208,
+210,252, 3, 90,134, 49,149, 23, 22, 73,155, 93, 56,113,202,255,242,185,243,109,242,110,177, 61,111,223,188, 13,177, 72, 24,218,
+ 57,204,123,188, 74,107,110,227,168, 62,210,210,210, 72,108,108,172, 83, 66, 97,108,108,108,116, 90, 90,154,203,140,194, 62, 16,
+240,113,158,161,243,119,198,144, 33,131,249,204,204,204,202, 24,135,253,243,124,193,243, 60, 6, 15, 30, 92, 31,211, 63,172, 76,
+ 58, 26, 0,158,126,250,105,125, 53,193,209, 45,121, 34, 40, 40,104,130,157,114,106, 82, 42,149,187,149, 74,229,186, 58,222,177,
+165,229, 0, 84,132,133,133, 93,120,233,165,151, 86, 47, 93,186,212,235,252,249,243,254, 50,153, 12, 47,190,248, 34, 36, 18, 9,
+ 56,142,195,200,145, 35, 43,102,206,156, 25,208,165, 75,151, 43,147, 39, 79,238, 60,121,242,228, 50,163,177,230,133, 3, 19,166,
+ 37,112,127, 94,190,118,170, 75,215,110,175,157, 58,121,114,236,206,221,191, 46,201, 62,121,178,241,165,156, 43,210,107,133,185,
+252,143, 43, 55,203,150, 38,127,218,233,192,238,221,201,109, 90,183,217,229, 19,230,125,100,195,134, 13,110, 79, 7, 20,214,160,
+173, 71, 2, 24, 0, 96, 17,128,233,214,193,210,187,154,217,238, 7, 88,252,236,159,192,226, 18,200,174, 67,192,120,202,170,253,
+ 58, 99,142, 63,110,181, 46, 80,117,208, 11, 1,208, 18,192,105, 7, 52, 79, 91,211,133,162,246,169,139, 20, 44,129,121,129, 86,
+198,249, 18, 44, 83,255,114,172,180,115,172,215, 27, 97,241,147,111,128,197,117, 65, 59,160,247, 10,128,111, 0,116, 0, 80, 84,
+ 45,159,119, 97, 9, 90,188, 98, 77,187,217, 1,189,247, 96,153,221,160,119,162,252,188, 0,236, 3,240,147,131,250,120, 25,192,
+191,173,231,179,118,249, 19, 89,235, 50, 13,192, 42, 0,139,173,207,239,214,246,131, 25, 25, 25,153, 0,144,159,159,175,176, 69,
+251, 87,215,250,243,243,243, 21,246,105,235,130, 45,205,134,255,210,149,209,249,213,181,244, 13,255,165,241, 40,232,101,101,101,
+ 97,208,160, 65,184,114,229,202, 95, 76, 92, 46,143,222,178,101,139,162, 85,171, 86,209, 28,199, 41, 90,182,108,201,219,166, 1,
+238,218,181, 11,145,145,145,209,123,247,238,173,145, 94,251,172, 44,252, 28, 28, 90,165,172, 58, 38, 14,135,238,211,219,192,179,
+161,224, 57, 96, 90,203,239,248, 10,206, 7, 74,131, 31,148, 57, 65,232, 62,104,103,244,229, 95,234, 54,179, 95, 47, 40,216, 10,
+ 96,107,235, 22, 77,219, 3,248,135,137,229,144,126, 33, 15,131,194, 44,238, 78,194,243, 90, 45,195, 44, 42, 46, 46,190,231, 4,
+ 51,253,148,231,121,239,156, 43,202,215, 84,167,183, 52, 42,190,171, 68,241, 61, 45,132,194, 50,239,138,114, 30, 42, 13,203,135,
+134,136, 3,132, 28,198, 24, 76,236,207,139,222,123, 58,224,147, 47,142,171, 28, 8, 1,153, 78, 12,216,164,154,187,192, 53, 12,
+181, 90, 94, 14,196,185,250,166,205, 26,230, 40, 42,223, 62, 29,113,150, 30,137, 43, 71, 61,233, 61, 9,224, 51,167, 93, 4,210,
+ 45,147,177,246, 95, 96,176, 78, 97,233, 99, 46,206,249,175,181,109, 8, 4,130, 16,161, 80, 88,124,252,248,241,111,159,126,250,
+233,250,148, 89, 11,165, 82,185,198, 42, 88,188,162, 84, 42, 55,219,206,117,188,179, 9, 22,151, 41,111, 29,187, 43,150, 46, 93,
+ 58,125,198,140, 25, 77,207, 93,184, 48,212, 96, 48,248, 42, 20,135,136, 68, 42, 1, 69, 40, 28, 58,116, 72,212,169, 83,167,179,
+177,177,177, 35,199,142, 29, 91,225, 40, 67,153,135,246,115,163, 94, 26,117,184,123,247,158,115,104,198, 52,226,122,206,181, 37,
+ 92, 94, 46, 3,128,151,130, 50,119,109,211, 62, 45, 52, 52,100,143, 64, 40,254,241,223,243,146,232, 47, 22,125,238,118, 65,214,
+ 36, 0,252,195, 42,225,188, 0,224, 50, 0,159, 26,222,219, 99,213,216, 99, 96,153, 71, 30, 95,135,249,191,173,181,192,156, 17,
+ 0,202,172,233, 5,117,208,139, 2,112,205, 73,122,215,172,233,127,169,131,222, 20, 0,147, 0, 92, 4, 48,211,250, 93,246,180,
+ 21, 0,242, 96,241,223,239, 6,176, 30,150, 25, 7,181,209,155,104, 45,143, 30, 86, 43, 66, 77,249,212, 88,159,167, 88,133,128,
+245,117,208,251,222,218,208,188,156, 28,188,190,119, 80,126,159, 89, 45, 27,251,173, 66, 13,170,209,254, 13, 64, 39,107, 93,228,
+ 88, 5, 41,135,166, 93,235, 60,127, 69, 3, 45, 4, 68, 38,173,210,241,147, 86,233,106, 88,184,167, 28,143,138,222,159,127,254,
+ 73,254,252,243,207, 42,247,126,250,233,167, 76, 0,100,243,230,205, 0, 64,110,221,170, 26, 83, 87, 27,243, 7,128,230,127,254,
+ 73,128,170,244,222, 94, 50,203,194, 28,151, 89,243, 84, 61, 68,239, 23, 23, 70, 97,150,207,131, 16, 16, 84,160,146,249, 91,185,
+250, 61,169, 84,234,148,217,144,231,121, 66, 8, 89, 48, 39,174,179, 87, 88,179,150,163, 56,120,181, 45,200, 47, 18,152,141, 42,
+190,113,168, 15,241,241, 22, 17,198,204,161, 92, 69, 51, 68, 70,100,106, 45,211,166, 14,133,160,182, 54, 91,253,255, 71,201, 0,
+237,221, 17,206,204,219, 39, 15,153,222, 99,207,252,185,205,129,216,127,193, 50, 69,127,189,130,198,207,199,105, 91, 76, 6,105,
+168,250, 97, 89,182, 12, 0,122,245,234, 85,175, 5,129,108,204,223,138, 82,235,217, 81,223, 72,180, 27, 79,205, 0, 10, 0,224,
+203, 47,191,124,249,141, 73,111, 12,123,170,119,228, 24,173, 70, 19,194,176,140, 49, 44, 44,172, 48, 60, 60, 60, 87,163,209,108,
+ 27, 59,118,108,169,179,249,250,117,251,175, 28,128, 77,175, 77,120, 43,107,192,192,129,219,101, 50,153, 63, 1,207, 89,102, 78,
+240,106,131,174, 92,113,245, 66,190,214, 91, 34,174, 87, 64,107,117, 1,128,133, 37, 72,205, 25, 63,252, 41,235,193,162,246,229,
+ 69, 89, 88, 34,234,157,157,175,169,128,101, 33,159,186,232,237,128, 37,104,205, 25,188,230, 68,254,190, 6,240,173,163,177, 31,
+192,187,118,239,212, 69,239, 7,171,197,192, 17,242,172,154,189, 51,249,115,101,190,235,215, 14,232, 61,235, 4, 61,155,181, 97,
+189,181,108,156, 49, 49,145, 97,195,134, 69, 85,143,250, 31, 54,108, 88,180, 51,154,122,109,244,236, 86,234,123,220,232, 61,246,
+184, 81,120,215, 68, 53,107,182,254,157, 79, 83, 38,217,238,209, 34,234, 39,163,158,219, 87,148,159,175,117,170,208, 8,225,255,
+ 61,165, 31,249,248,235,223,231,236, 90, 21,186,237,196,201,187, 83, 67,252,185, 23,169, 32,191, 0,158, 7, 8,225, 77, 38,134,
+ 43,226,128, 82,218,196, 5, 20,222, 53,184,228,143,180,154,249, 21,213,174, 31,151, 34,244,172, 4,232, 38,158, 91,172,125,208,
+223,200, 1,104, 34,149, 74,239,246,234,213,235,217, 51,103,206,212,155,160, 82,169, 60, 24, 20, 20, 52, 73,169, 84,174,119,242,
+ 21,129, 53, 31,149,227,233,186,245,235, 50, 0,100, 52,212, 71,254,248,211,183,121, 86, 94,241, 64, 80,147, 0, 96,116,131, 14,
+ 95, 71, 37,153, 60,244,254,182,244,170,192,202, 72, 73,181,123,110, 55,206,199,157,222,147, 0,165, 94,255, 38,224,101, 6, 16,
+194,129, 47, 52, 26,233,141, 69, 69, 37,231,225,194, 42,106, 31,127,253, 59,191,253,179, 17,228,133,233,251,178, 0,100,197,246,
+109,255,143,160, 32,201, 92,161,128,240,119,203,140, 87,239,210,204, 6,153,136,146,202,132, 2,129,153,225,164,174,228, 47, 45,
+ 45, 45, 51, 54, 54,214,182, 15,128,205, 61,224, 58,103,173,238,235,183, 51,253,215, 35, 14,192,179, 18,160, 27,160, 94, 41, 7,
+ 33, 4, 47,142,158, 82,227, 24,178, 99,123,106, 67,125,107, 17, 0,210, 16,204,223, 78, 8, 88,239, 66,114,153,117, 76,165,159,
+212,186, 18,214,208, 16, 27,114,142,172,135,222,223,155,158, 7,143,187, 0,160, 84,242, 74,165,114, 74,125,233,188,244,254, 62,
+ 30, 0, 94, 27,220,137,252,120,228,210,231, 6,126,218,170,233,227,142,119,162,117, 36, 34, 72, 36,108, 4, 66,244, 62, 50, 97,
+ 73,151, 14,126, 57,233,251, 93,163,109, 13,244,227,221, 9,248,123,192, 26,180,199, 2,224,198, 55,166,166,166,240, 9, 9, 83,
+201,142,237,169,127,247,238,229,111, 21,164, 37,110, 42,206,143,190,178,220,221, 71,216, 3, 15, 60,120, 2, 37,126, 1,224, 37,
+ 33,224, 56, 30, 32, 4, 21, 6, 79,247,247,192,131,255,217,241,192, 83, 4, 30,120,240,191, 3,134, 5, 52,250,191,245,178,243,
+ 30,120,224,129,147,160, 60, 69,224,129, 7, 30,120,224,129, 7, 30, 1,192, 3, 15, 60,240,192, 3, 15, 60,240, 8, 0, 30,120,
+224,129, 7, 30,120,224,193,223, 17, 85, 98, 0,206,157, 59,231,118, 52,106, 77,193,132, 53,209,123,225,153,200,168, 46,221,218,
+ 40,154, 52, 11,143,214, 26,116,138,195,138,172,232,140, 67,231, 51,221,165,215,181,239,240,168, 30,221,250, 42,238, 21, 22,194,
+ 91,230,141,219, 5,185,209,217, 39,246,184, 77,175,161,191, 55,113, 60, 21,213,175,111, 43,133,204, 91, 0,161,128, 2,145, 18,
+188, 56,238, 18,113,151, 94,194,255,203,138,122,170,239, 83, 10,127, 31, 1, 32, 4, 98,251,214, 60,199,233, 81,125,175,135,222,
+ 99, 75,175,206,169,102,143,251,247,182,234,245, 50,239,199,229, 62,208,252,157,253,232,150,219, 3,105,207, 37, 45,239,187,247,
+121,163, 66,183,233,253,163,244,254, 13, 87, 61,237,249,161,208, 19,162,134, 41,178, 79,226,247,186, 44, 0,212,134,149, 81,104,
+ 11,203,122,248, 44,128,220,153,153,184,233,236, 15, 12, 31,216, 42,138,128, 67, 72, 64, 16,178, 14,159, 81,124,152, 56, 17, 3,
+134, 14, 0,163,211, 43, 58,117, 24, 12,142,131, 98,198, 91, 79, 71,247,236,217, 13,215,175,223,130, 90,165,195,234,245, 71, 50,
+107,163,215,123,208,171, 81, 60, 8, 90,182,105,165, 72,120,127, 49,222,124,245, 57,252,240,159,175, 0, 72,177,231,124, 1, 40,
+ 10,138,149, 11,230, 33, 39,231, 42,228,242,150,144,200,132,184, 83,144, 19, 13,125,205, 89,158,251, 92,119, 94, 44, 22, 67, 38,
+147, 33, 55, 55, 23, 77, 67,253,208, 72,232,131,166, 45, 2, 16, 40,243,135, 55, 97, 65, 81, 20,120,142,133, 94, 34,132,250,158,
+ 26, 99,254,147,225,176,162,150,207,233,198,251,202,212,240, 11, 16,195,199, 91, 8,177,140,130, 80, 0, 80, 98, 33, 50,119, 69,
+242,102, 94,128, 97,163, 78, 56, 93,225, 93, 95, 90, 25, 21, 30, 30,142,102,173,155, 41, 12, 70, 19, 40,137, 12, 48, 3,211,146,
+ 79, 69, 25,244, 58,124,247, 73, 84,230, 35, 20, 36,255, 86,243,152,159,112,184, 90, 23, 78,167,143,253,112,174, 55,128,167, 26,
+203,188,254, 93, 88, 88,216, 65, 36,149,128,243,242, 90, 6, 96,109,218,178,164,138,199,165, 0, 34, 58, 13,137,186,121,233,112,
+ 77,251, 41,252, 45,218,104,106,106, 42,249, 97,195,134, 43, 18,177, 88,198,113,156,191,183,143,143,207,168, 23, 95,244, 2, 64,
+ 39, 36, 36,240,143,105,158, 41, 0, 72, 72, 72,224, 26,128,156,159,191,191,255,172,246,237,219,143,149, 72, 36,205, 10, 10, 10,
+ 10, 10, 11, 11, 79,210, 52,189, 4, 64,174, 27,244, 2, 2, 3, 3, 23, 63,243,204, 51,207,135,133,133,201, 79,157, 58,117,239,
+226,197,139,199,141, 70,227, 66, 88, 86,136,253,223,176, 0,212,194,252, 5,222, 18,225, 83, 19, 7,182, 94,193,241,188,241,232,
+213,123, 95,174,140, 82,239,159,153,137, 75,142,222, 85,222, 61,200,155, 42,148, 48, 87,168, 32,100, 41,252,113,233, 42, 94,127,
+125,102,229,115,138, 2,126,207, 90,143, 70, 45,194, 21, 92,133, 6, 52, 71,112,232, 80, 86,244,234,245, 71,106,161,216,146, 63,
+125,226, 18,136,151, 31,206, 92,202,199,249, 75,111,224,187,159,127,171,124,202,113,192,136,254,253,129,138, 34, 0,190,200,189,
+120, 25,162, 70, 1, 24,208,175,139, 66,165,175, 67,102, 33, 20, 64, 40,244,232,214, 11,141,189,197,104,218, 72, 10,191,224, 32,
+ 4, 74,124, 17, 40, 21, 64, 36, 16,192,204,178, 80, 49, 28, 78,149,158,118, 88,168, 11,223,109,206,203, 4,229,240,243,242, 66,
+ 72,163, 96,248,249,121,129,167, 88, 48, 92, 5, 88,176,240,241,241, 66,163,198,205,144,123,165, 29,223,186,195, 15,117, 14, 74,
+ 61, 99, 86,241,254,190,222,240, 15, 8, 68, 72,163, 96,232,116, 58,136, 37, 82,136,140,150,197,249, 34,228, 45, 21,202,114, 21,
+158,121,107,125,116,126,193, 29,148, 23,221, 66,217,249, 84, 71,194,128,211,131,196,208, 73, 67,163, 15,172, 63,144,233, 4,173,
+ 7, 42, 4,228,229,229,241, 0, 32,151,203,201,227, 66, 47, 60, 60,252,117,154,166,215, 3,192,216,232,104, 42,117,203, 22,119,
+ 6, 95,203, 26,169,118,134, 28,158,231, 65, 8,169, 60,219,238,217,210, 57,216, 73,205,149,245,228, 93, 97,254,157,188,205,204,
+ 86,223, 0,255, 14, 0, 32,150, 73, 65, 27,140,224,116,250,229,199,143, 28, 94, 16,251,225,220,142,105,203,146,242, 29,209,249,
+242,163, 68,222,170, 97, 49,176,184, 32, 57,235, 56, 84,227, 88,212,125,200,243, 24,242,220,255,185, 84, 71, 55, 47, 29, 86,180,
+233, 18, 21,125,253,143, 76,215,133,226, 88,165, 75,201,227,226,226,176, 37,246, 64,157,105,162, 15, 84,221,138,164, 83,128,229,
+ 83,139,141, 28, 12,140,165, 94,117,214,115,106,223, 0,180,243, 21,213, 73,111,197,138, 21,153, 31,189, 55, 59,116,244,216, 49,
+ 62, 70,163, 1, 43, 63,255,140, 90,189,122,181, 49, 49, 49, 49, 28,192,157,134,238,123, 99,198,140, 25,186,109,219,182, 12, 87,
+133,168, 73,147, 38,241,121,121,121, 40, 43, 43,195,210,165, 75,225,235,235,139,168,168, 40,200,229,114,172, 95,191,222,221,126,
+ 55,184, 87,175, 94, 27,222,127,255,253,235,237,219,183, 95,223,179,103,207,203,247,238,221,107,150,149,149,213,235,205, 55,223,
+220,173,209,104,150,195,178,149,187,179,136, 30, 59,118,108, 90, 82, 82, 82,176,217,108,134, 76, 38,131,183,183,119, 19,157, 78,
+247,242,232,209,163, 71, 93,184,112, 33, 17,150,141,211,158, 56,156, 59,119,174,186,149,192, 57, 1, 96,101, 20,154, 3,104, 13,
+203, 18,135,172,206,196,220,206,186, 86,252, 69,255,182,161, 51,159,233,212,100, 65, 99,127, 89,211,149, 40,218, 4,224,234,204,
+204,218, 55,169, 49, 85, 40,209,184,205,179, 88,252,193, 88,172,183,227, 73,135,143,167, 64,167, 55, 97,228,208,153,120,122,192,
+ 36,188, 26,247, 12,100, 50, 9,104,150,129, 86, 79, 43,106,111,100,183, 0, 26, 24, 59, 97, 45,222,126,127,106,229,221, 17, 79,
+ 71, 65, 42,149, 96,251,161,223,176,231, 88, 22, 54,172,251, 10, 70,131, 9, 98,129, 16, 62, 94, 98,232,202, 10,162, 85, 5,168,
+113,135, 53,158,231, 1,158,179, 28, 20, 7,158,231, 97,162, 37,149,203, 59,240, 52, 11, 86, 0,176, 96,193,210, 28, 24,182,110,
+ 1,118,206, 91,114, 62,208,143,129,159,175, 55,194,155, 69,160, 67,215, 54,240,245,145, 65, 93, 81,130,162,146, 34,148,171,239,
+193,108, 36,240,242,242, 66, 72,200, 0,148, 22,135,240,141, 66, 63,171,217,140, 63,120, 30,207, 24,244, 48, 8, 1,177, 84, 12,
+131, 94, 12, 90, 47,134, 81, 42,129,144, 48,224, 33,128,209, 80, 1,131, 94,139,102,205,154, 42,196, 2, 33,148,208, 32,148,158,
+128,234,107,204, 87,199,167, 27, 62,117,216,128, 62,136,255,160,238,177, 50, 54,182,202,254,238,177,177,177,189,131,130,130,114,
+ 8, 33, 70,158,231,133,129,129,129, 94,185,185,185,193,214,213,221,154,186,219,144, 19, 19, 19,199,217,253, 70,148,187,171,197,
+213,200, 45, 9,225,167, 77,155, 22,189,122,245,106,151,104,134,135,135, 39,244,233,211,103,201,192, 30, 61, 96,150, 72,144,156,
+156,204, 77,125,229,149, 97, 41,155, 55, 31,112,241,247,177, 98,193,130,202,235, 89,243,231, 35,121,225,194, 58,175,157, 33, 91,
+141,185,243,189,123,247, 6, 0,126,232,208, 86,157, 1,220, 72, 74, 74, 51,184,200,252,179,186,118,238,236,103,235, 51,222, 82,
+ 25,238,150, 20, 67, 83,174, 66,175, 62,125,189,118,125,183,238, 64,236,135,115, 59,167, 45, 75,114,180, 54, 59, 51, 99,201,106,
+225,107, 47,143, 18,182,149,203, 57,171, 16,128,249,201,171,170, 10,209,179,166, 3, 0, 62,122, 47,209,173,237,164,221, 98,254,
+ 54,164, 5,185,144,120,168, 75,164,189,133, 4,231, 23,190, 5,226,215, 8,236,141,243, 48,221,248, 19, 57, 74, 29, 34,247, 22,
+ 59,245,126,207, 94,189,142, 78, 25, 31,223, 50,126,242,155, 1,105, 63,253,204,201,229,114,106,113,210,114,248, 46, 88,140,237,
+219,183, 23,166,166,166, 82, 13,101, 5, 24, 51,102,204,176,109,219,182,237,223,182,109,155,237,122,184,237,127, 7, 2, 74,212,
+254,253,251, 21,183,110,221, 66,235,214,173, 49,104,208, 32,248,251,251, 67,165, 82,225,206,157, 59,184,121,243, 38,134, 15, 31,
+206, 15, 31, 62, 60,122,246,236,217,174,212,211,152,103,158,121,102,229,138, 21, 43, 54,245,236,217,115, 37, 33,228,142,221, 56,
+ 78, 98, 98, 98,124, 0,100, 89, 15,167,232, 37, 38, 38,166, 79,155, 54,141, 58,125,250, 52, 8, 33, 8, 14, 14,174, 60,246,238,
+221, 43,238,215,175,223, 87,183,111,223, 62,241,164, 51,127,219,189,234, 66,128,176, 6,230, 31, 28, 25, 17, 28,223,163,101,208,
+ 4, 66,136,136,231,121, 51,103, 57,104,214,108, 52,136, 41,174,105,215,198,210, 15, 26,249,181,110,179,237,212,205,159, 87, 70,
+113, 71,103,102,214,190, 91, 28, 32, 70,167,142,237, 65, 81,153,200, 81,149, 1,184, 12,117,225, 53,136,164, 18,236,216,253, 37,
+244,165, 44, 38,188,241, 15,112, 28,240,226,168,254, 96,133, 62, 14, 63, 46, 39,231, 50, 56, 14, 24,217,157, 88,249, 74, 75, 24,
+ 77, 52, 98, 70, 12,135, 52,128,194,134,141,251, 64, 81, 64,250,207,235, 81,120,227,207,232,189,155, 86,100,214, 36,253, 0, 0,
+199, 3, 28,199,129,227, 56,176, 44, 11,147,136,135,153,152, 65,211, 52,244, 94, 70,128,147,130,226, 89,176, 98, 30, 21,180, 17,
+ 58,141,186,206,188,133,248,152, 32, 20,202, 16, 28, 28,140, 54,109,218, 32,172,113, 95, 64, 64,129,101, 79,131,226, 85, 48,234,
+ 24,176,156, 14, 69,119,148, 8, 9, 46, 69,112,192, 0, 44, 91,177, 43,234,231, 31,239,167, 37, 51, 50,224, 77,165,128, 81, 2,
+154, 50, 67, 39, 22,162, 66, 38,130, 80, 36, 6, 56,111, 16, 1, 65,133, 78,143,242,162, 91,200, 61,125, 12,202,252,124,112, 28,
+ 7,138, 23,184,213,104,190, 91,251,151,224,252,230, 59,111, 58, 30, 39,171,174,217,110, 76, 75, 75,155,251,254,251,239, 79,205,
+207,207,167, 8, 33, 33,169,169,169, 63,195,178,185,147,151,187, 13,121, 74,108,172,104,205,154, 53, 27,239,221,187,135,244,244,
+116, 68,182,111, 47,104,136, 14, 34,151,203, 73, 92, 92, 92, 20,207,243,138,213,171, 87,187,188, 97, 17, 77,211, 41, 3,173,109,
+ 74, 44, 22,163, 93,187,118,216,122,232, 80, 70, 72, 72, 8, 74, 74, 74,156,166, 99,211,236, 31, 0, 72,239,222,189,249,211,167,
+ 45, 22, 43,187,243,159, 67,134, 12, 41,156, 59, 55,214, 63, 41,201,241,154,251,177, 31,206,245,246, 54, 51, 91,187,118,238,236,
+ 39,160, 40,188,251,218, 4, 24,140, 38, 36,127,251, 45,188,100, 50, 24,141, 70, 24, 13, 6,116,239,217,163,237,111, 63,253, 52,
+ 13,192, 23,142,172,142, 11,103, 77,231, 0, 80,215,242,242,168,234, 12,191,122,247,116,231,195,155,119, 24, 28,125,251,202, 17,
+126,216,139,111, 69,103,236,252,214, 45, 65,192,126,215, 62,219,150,182,117,221,119,132, 78, 1, 66,220,170, 96,113,120, 88, 8,
+ 68, 51, 83,161,153, 16, 1, 97, 96,168, 75,204, 63, 46, 46,174,200,172,211,223,153,252,238,212,230, 31,254, 99, 14, 86,175, 75,
+185,212,167, 87,175, 86, 41,171, 82,188,222,155, 51, 27, 63,245,239,139,141, 27, 55, 78,132,101,215,210,250, 48,254,168,109,219,
+182, 41,108,204, 62, 53, 53, 53, 23,150,109,218, 15, 58, 35, 0,236,223,191, 95, 17, 18, 18,130,158, 61,123, 50, 20, 69, 9, 45,
+214, 89, 14, 34,145, 8, 65, 65, 65,104,220,184, 49,110,222,188,137,253,251,247, 43, 92,232,115,177, 47,188,240,194,103, 43, 86,
+172, 88,213,190,125,251,181,132, 16, 14,192, 87, 0,158, 3,112,132, 16,178, 16,150, 53,243,103, 3, 88,232, 12,189, 21,137,137,
+155, 7,198,198,146,157, 59,119, 66, 40, 20, 66,161, 80,224,252,249,243,104,211,166, 13, 22, 45, 90,132, 46, 93,186, 96,234,212,
+169,194,143, 63,254,120,197,147,200,252,167,204, 93, 86,121,239,235,164, 15,107, 20, 2,106,154, 5, 64, 9, 5,148,144,225,120,
+173,193,204,220, 33,132, 72,124, 36,130,110,126, 98, 68,202, 58, 15,105,141,232,183,129, 14,131,208,196,155, 31, 51,113, 64,196,
+135, 65,126, 94,195, 86, 70,193,191,246,236,112, 16, 8,108, 99,182, 31,128,102,240, 15,127, 1, 6,214,136,181,169,235,240,195,
+198,116, 12,143, 30, 0, 0,208,235, 1,129,176,118, 82, 50,175,246, 0, 0,150,181,223,155,166, 8, 64, 22, 40,129, 4,241,175,
+191,133,152,184, 56,236,218,109, 97,100, 94,222,128,174,226,110,157,133,101,134,160,146,249,155, 25, 22, 38,141, 25,122,149, 30,
+ 42, 51, 13,165,158, 70,185, 73, 11,149,182, 2,229,197, 90, 40, 85, 70, 40, 43,106, 95, 66,253,221, 87, 91,241,132, 16, 8, 4,
+ 4,132,146,128,101,121, 48,250,124,232, 84,215, 80, 88,164,134,178,188, 2,106, 45, 11,101,185, 17, 5, 5, 69,184,116,229, 28,
+ 84,234,115,232,219,171,183,162, 54,154, 2, 0,148,214, 8,195,245, 59, 40,251,227, 50,202,242,111, 65,163, 86, 66,163, 86,226,
+214,165,211, 56,158,246, 29,178,182,108, 64,201,245,235, 96,105,206,210,155, 4, 15,205, 13,104,219,135,155,142,137,137,233,184,
+120,241,226,247,155, 52,105,162, 75, 79, 79,239,150,150,150,246, 43,128,158,214, 74,119,123,193, 41,113, 88,216, 44, 0,232,215,
+165, 11,166, 77,155, 86,124,234,202,149, 3, 79,117,232, 16,213, 16,153,223,178,101, 75, 38, 0,146,152,104,209, 50, 19, 19, 19,
+ 93,162,107,150, 72, 0, 0, 91,183,110, 69,104,104, 40, 62, 76, 76,196,172, 89,179, 16, 18, 18,242, 88,248, 97,109, 76, 63, 53,
+ 53,181,242, 0,128,195,135, 15,135, 3, 24,229, 36,153,167, 2, 2, 3, 59, 8, 40, 10,111,196,196, 64,165,214,160,224,238, 29,
+136, 68, 66, 8,133,150, 67, 36, 18, 65, 34,243, 66,107,185,252,243,158, 67,135, 58,165,177, 95,203,203,195,143, 91,127,173, 60,
+108,152,159,188, 10,243,147, 87, 97,143,226,176,203,223, 59, 52,246,227, 40, 0,184,125,229, 72,230, 80, 11,243, 87,224, 49, 89,
+237,232,194,247, 95,160,248,237, 94, 24,146, 81,130, 78, 1, 66, 8,252,130,192,148, 23, 35,114,111, 49,188,133, 22, 30, 40,112,
+ 48, 39,235,230,245,235,101, 95,167,254,167,253,247,255,249, 30, 95,126,251,213,173,175, 86,124, 54,255,253,233, 51, 70, 45, 94,
+178, 24, 50, 95,111, 12,234, 55, 0,167, 78,158,250,254,181,248,215,220,254,102, 27,243,183, 93,239,220,185, 19, 79, 61,245, 84,
+107, 0, 19,156, 53,251,155,205,102,244,234,213,139, 99, 89, 86,168, 86,171, 97, 50,153, 96, 50,153,112,229,202, 21, 40, 20, 10,
+ 28, 59,118, 12, 77,154, 52,129,217,108,198,164, 73,147,156,201,235,184,184,184,184, 47,198,142, 29,235,183,118,237, 90, 63, 66,
+136, 24,192, 97, 0,106, 0,189, 0,252,106, 39,120, 30, 4,208,197, 17,189,109,239,191,191,121, 84,247,238,228,167,152, 24, 20,
+158, 61,139,207, 62,251,140,219,181,107,215,255,187,125,251,118,168, 66,161,120,123,238,220,185, 48,155,205, 24, 48, 96, 0,188,
+189,189,251,227, 9,135,189, 48, 80,167, 5, 96,102, 38, 74, 86,162, 36,229,247,235, 37, 25,145, 17,193,209,189,229, 65,150,117,
+196, 95, 88,132,223,125,134,227,224, 31,197,232,223, 57, 16,207,200,119,193,247,183, 37, 61, 71,244,144, 79,216,120,228,210, 31,
+ 53, 17,111,210, 54,150,240,124, 1, 63,250,245,153,152, 53,253, 43, 0, 74, 0,190, 0, 76,104,217,190, 23,164, 18, 33, 12, 58,
+ 19, 64, 91, 4, 4, 95, 95, 95, 20, 43,107,221, 47, 27, 6,253, 85, 2,128,191,244,251,183,160,168,213, 85,148, 4,206,240, 39,
+140, 38, 51,100, 62, 82, 64,108, 17, 16,180, 26, 13,250,247,239,143, 35,191,254, 84,187, 58,194,209,224, 56, 33, 24,134,129,201,
+100, 66,133, 80, 0, 33, 77, 1,119, 53, 96,188, 24,176, 98, 14,188, 72, 0,189, 64, 8, 70,167,135,202, 84,123,172,147,175,143,
+ 14, 12, 67, 96,162, 89,168,212, 26,228, 92,207, 71,193,221, 82, 24,104, 51, 52, 21, 74, 84,104, 85, 48,178, 52,136,144, 64,167,
+ 87, 67,163,191,137, 91,133,106,148,105,117,181,210,100,237,164, 52, 70,173, 67,193,185,203,184,119,249, 38, 52,218,235,208,170,
+ 84,224, 33,132, 72, 64,192, 19, 17, 40,202, 98,245,117,197,185,246, 65,252, 7, 78,185, 3, 28,224, 30,128,123,243,230,205, 51,
+ 0,192,220,185,115, 79, 37, 37, 37,121, 91,179,110, 4,144,239, 46,225, 53,107,214, 44,141,137,137, 1, 0, 68,132,132,132, 90,
+125,226,130,134,236, 28, 54,243,191,213, 18,224,176,248,194,195,195,135,210, 52,141,228,228,100,188,252,242,203, 24, 59,124,248,
+ 95, 3,253,133, 11, 22, 75, 80, 72, 8,239,108, 92,192,172,249,243, 43,125,254, 0, 48,123,193,130, 42,150, 1, 39,205,254, 85,
+ 96,211,254,109, 76,223,134,212,212, 84, 36, 36, 36,224,192,129, 27, 63, 2,248,201, 17,157, 0,161,240,223, 70,218, 4,129, 64,
+128, 43, 55,114,193,243, 60, 46,229, 92, 3, 77,155, 65,129, 64, 40, 20,130, 16, 2,142,101, 97,208,233,113,237,247,223, 15, 57,
+ 81,134,148, 61,211,127,237,229, 81,246, 26, 63, 5, 0, 39,206, 92, 64,219,136,150, 46, 77, 83, 62,144,246,239, 74,109,255,128,
+ 69,243,183,185, 66,248,231,199,188, 21,189,119,155,123,214,128, 6,129,242, 46,196, 45,218,161,120,154, 20,146,103,198,129,205,
+222, 7, 86, 99,137, 55, 40,158,246, 52, 90,166,102,129,229,234,110, 42,237,219,182,111,234,229,229,237,245,229, 55,107,140,209,
+ 67,134,136,251,246,239,247,211,254, 61,191, 61,127,229,122, 14,192,241,144, 74, 36, 24,208,123, 0,118,239,220,141, 17, 35, 70,
+240,251,246,237,115,122, 40,168,174,245,239,223,191, 31, 55,110,220,160, 1,136, 79,158, 60, 73, 79,157, 58,117,124,106,106,234,
+107,142,232,228,229,229,161,117,235,214, 0, 64,229,229,229,225,252,249,243,104,217,178, 37, 34, 34, 34, 80, 94, 94,142,236,236,
+108,180,106,213, 10,161,161,161,104,217,178, 37,242,242,242,234,110, 40, 20, 21, 31, 23, 23,183,100,240,224,193, 62,167, 78,157,
+242, 99, 24,102,178, 76, 38, 27,109, 48, 24, 86,192,178,245, 57,172, 2,192, 42, 88,182, 86,167, 81,199,244,118,145, 72, 20,159,
+ 54, 99,198,250,167, 67, 66, 72,201,156, 57,232,207,113, 88,181,115, 39, 95,168,215,191,133,191,182,101, 95,127,233,210,165,181,
+ 12,195, 8,125,124,124, 16, 30, 30,238, 99, 54,155, 33, 18,137,240,119, 67, 77, 46,128, 48, 0,173,199, 68,182,120,183,121,176,
+247, 4,152, 13, 64,251, 97, 56, 19, 50, 6,207, 36,126, 7, 67,169, 10, 2, 63, 95, 40, 86,198, 99, 80,167,223, 17,116, 33, 99,
+ 48,128, 22,181,253, 64, 27,191,102,248,227,194, 47,118, 6, 7, 29, 44, 91, 40,155, 1,179, 9, 66, 78, 0,202,202,196,183,109,
+119,188,139,200,190,139, 60, 70,244,236, 82, 77, 9, 21, 2, 16, 1, 34, 41, 24,194,194,170, 7,227,149, 9, 51, 0, 64,145,244,
+ 81, 98,173, 29,129,229,120, 48, 28, 5,138, 97, 64,209, 38,232, 41, 75,219, 49, 8, 4,240,102, 12,208, 24,120, 16, 17, 1,203,
+178,208,179, 64,177,174,246,141,159, 24,154,131, 81, 36, 0,167,103,192,112,106,104, 43,204, 16, 16, 17, 76,140, 25, 52, 79,131,
+ 49,211,128,152, 3, 69, 0, 34,225,160, 54,176, 40, 42,209, 67,103, 98,106, 84,146, 41,194, 86,238,195, 75,200, 95, 46, 93,179,
+209, 0,181, 82, 9,138, 8, 32, 20,242, 0, 47,132,128,184,175,234, 92,189,117,149,110,223,178,189,216, 25,179,127,109,178, 25,
+236,118,196, 74, 74, 74, 26, 5,224,246,220,185,115,123,250,251,251, 7,168,213,234, 91, 73, 73, 73, 46, 19, 77, 76, 76,124,115,
+205,154, 53,104,220,184,177,253, 61,213,170, 85,171, 14, 60,213,161,195,208, 83, 87,174, 28,108,168,142,144,152,152, 24,109,231,
+ 10,168,139,249, 71,245,233,211, 39,124, 96,143, 30, 32,190,190, 72, 74, 74,194,156, 57,115, 32, 18,137, 96, 46, 47,135,191,191,
+ 63, 62, 76, 76,172,140, 11, 72,136,139,115, 40, 4, 84,247,241, 59,138, 9,168,203,163, 80, 93,251,119, 96, 29,112,216,100,202,
+149,202, 14, 62,190,190, 40, 45, 47,135,226,196, 9, 8, 41, 1, 76,102, 51,244, 6, 3, 56,142,171, 20, 92, 24, 51, 13,218,100,
+114,198,165,193, 1,160,172,110, 0,206,174,225, 27,173,247, 49, 63,121,149, 24, 0,218,202,229,197, 55,107,214, 45, 92,178, 82,
+ 53,107, 29, 25,181,119,219,183,174,152,155,107, 47, 96, 23,204,254, 85,204,178, 91,254,131, 30,175,255, 3,146,136,110,150,177,
+162,244, 46,114,148, 22,193, 95,210,255, 5,228,179, 12,188, 86,215,237,106,214,104, 52, 1, 18,153, 20,109, 34, 34,164, 55, 11,
+110, 55, 41, 43, 41,195, 43,175, 77, 80,236, 57,152,129,149,203,146,211,183,237,217, 25,211, 54,162, 45,226, 95,158,136,172, 51,
+199, 48, 98,248,112,126,223,254,253, 14,191,217, 94,235,223,191,127, 63,134, 13, 27,102, 19, 22,197,119,238,220,193,212,169, 83,
+197, 0,224, 76,108, 65, 89, 89, 25, 6, 13, 26, 4,150,101,145,151,151,135, 99,199,142,161, 83,167, 78,240,247,247, 71,243,230,
+205,209,163, 71, 15, 80, 20, 5,138,162,208,164, 73, 19, 71,237,180, 83,151, 46, 93,190,232,223,191,191,224,194,133, 11,126, 44,
+203, 22,109,221,186, 85, 99, 48, 24,146, 0,216, 59, 77,223,125,254,249,231,243,247,236,217, 19, 65, 8,185,139,218, 55,230,233,
+153, 48,112,224,250,190, 66, 33, 41, 89,178, 4,188,217, 12,133, 64,192,101,233,245,147, 96,217,198,221,134,119,230,205,155, 39,
+164, 40, 10, 74,165, 18, 55,110,220, 40,238,210,165, 75, 40,254,134, 16, 86, 99,254,109,195,252,101, 3,159,239, 30, 62,213, 79,
+ 38,234,195,176, 92,185,144,103,253, 16,208, 68,112, 87,101,132,161, 84, 13,136,133, 96, 85, 90, 20,148,211, 64,112, 11, 80, 28,
+ 45,173,203,196,123, 93,163, 65,187, 0, 63, 48, 38,224,122,230,143,104, 19,245, 92,165, 2,103,166,205, 16,129, 66,133,209,178,
+ 67,237,136,168, 94,144, 5,135, 99,197,250, 95,107,205,240,136,174, 4,123,206,243, 16, 73, 1,113,139,231, 64,231, 31,173,180,
+ 2,136,196, 18,152, 97,132,143,204,178, 35,233,206, 61,155,240,199,201,204, 58, 77,146, 28,199, 65, 76, 27, 96,134, 24, 20,197,
+ 0, 70,203,192,102, 54,155, 97, 50,138, 32, 16,138, 0, 35,192,115, 22, 23, 65, 75,121, 4,144, 85,243,140, 2,189,145,131, 64,
+ 64, 96,102,204, 48,154, 56,104,180,150,118,104,230,120,208, 38, 14, 16, 2, 2,145, 0, 66, 41, 64, 12, 44, 56,194,128,131, 1,
+ 90, 3, 0, 56, 30, 88, 88, 0, 20, 7,240, 4,160, 40, 14,132, 8,192,241, 4, 20,101, 85,156, 56, 10, 28, 69,129,112,206, 41,
+200,118, 65,126,226,122,182, 35,111, 0, 33,115,231,206, 45, 78, 74, 74,138, 6,240,210,220,185,115,135, 39, 37, 37,233, 0,148,
+185,101,178,138,141, 21,175, 89,179,230,219,152,152, 24,200, 27, 53,170,188, 47,111,212, 40,192,106, 5, 8,121, 20, 29,134,166,
+105,133,205,247,207,107,181,248,228,147, 79, 96, 42, 43,131, 45,242,173,141, 85, 88, 17,153, 76, 24, 53,106, 84,113, 97,113,241,
+120,103, 52,237, 6,116,201, 84,177, 0,212, 97, 33,192,233,211,167, 73, 77,194, 67, 21,161,214, 68, 67, 69, 43, 97, 52, 26, 17,
+224,239, 15,169, 88, 2, 51,203,128,231,121,176, 44, 11,154,166, 97, 54,155,193, 49,172,179,241, 12,220,181,188, 60,170,173, 92,
+110,211, 8,184,107,121,121,212,143, 91,127,149,218, 91, 4,218,202,229,170,134, 50,223, 23,228,102, 55,152,230,239,110, 12,192,
+144,140, 18, 20,203,211, 33,110,209, 14, 36,162, 27, 90,174, 59,139, 82, 35, 7,111, 33, 1,253,223,237,184,122,227, 38, 28,237,
+ 90,108, 96,104,156,206, 58,137, 47, 86,124,142,167,163, 6, 98,222,255, 91,128,223,246,254,134,159, 54,252,128,254,131, 7,198,
+ 52,151,183,128,208, 75,132,131, 71, 15, 98,227,247, 63,224,151,237, 91, 33,150, 74,249,157, 59,119,214,185, 62,196,182,109,219,
+170, 48,126, 27, 84, 42,149,203,229,163,213,106,225,239,239,127, 2, 64, 95,185, 92,142,222,189,123, 67, 32,176,184, 89, 91,182,
+108, 9,137, 68, 2,181, 90, 13,185, 92, 14, 95, 95,223, 91, 90,173,182,101, 29,228, 46, 93,184,112, 97,233, 47,191,252, 50,178,
+109,219,182, 29,182,110,221, 90, 81, 94, 94,190, 16,192, 70,123,249,101,200,144, 33,239,175, 91,183,110, 11,128, 98, 0,177, 0,
+126, 7,208,189, 6,122,103, 87, 43, 20, 75, 3,178,179, 63,122,149, 97,240, 57,192,125, 91, 81, 49,177, 26,189,151,102,204,152,
+241,249,148, 41, 83,112,243,230, 77,236,222,189, 27, 12,195, 28, 2,240,234,147,194,212,123,244,232,129,115,231,206, 85,250,253,
+235,180,176, 84,187,110, 53, 38,178,197, 98, 63,153,168, 79,137,198,248,219,241,107, 37, 73, 16, 72,128,171, 71,241,172,156,199,
+ 63,167,143, 66,239,206,114,204, 72,120, 30, 47,182,166,129,139,251,193,139,100, 12,234, 12,214, 81, 33, 71,149, 15,161, 4, 24,
+241,226, 63,176,241,203,101, 22,101, 81,111, 2,107, 0,182, 43,206,225,192, 41,203,140,194,102, 45, 34, 64, 9, 29, 51,175,145,
+221, 9,204, 70, 96,231,238,125,136, 28, 62,221,162,253, 67, 4,129, 12,136,123, 33, 22, 35, 7,143,182,116,252, 91,185, 96,140,
+117,111,213,204,243, 60, 24, 98, 97,240, 38,218, 18,252,103, 50, 26,160,215,235, 81, 81, 81, 1,173, 70, 13,173, 86, 11,141,202,
+162,101,189, 0, 0, 32, 0, 73, 68, 65, 84,182, 2,198,138, 10, 24, 12,134,218, 27,127, 5,129,193,200,194, 96,100,161,211,155,
+161,173, 48,161, 92,107,130, 74, 67, 67,173, 53, 67,165,178,156,149,101, 12,148,229, 12,148,106, 6,165, 74, 26,247, 74,107,207,
+ 35,197,243, 96, 1, 16,150,128, 80, 28,120,194, 3, 60, 15,158, 23,128,229,254,170, 62,206, 58,122,184,106, 27,239,216,191, 35,
+142,237, 57,134,223, 14,253, 86, 41, 20, 92,189,117,213,213, 54, 23, 14,160,245,242,229,203,207, 3, 88,253,225,135, 31,190,215,
+170, 85, 43, 38, 53, 53,149, 36, 39, 39,187,172,117, 77,137,141, 37,226,176,176,109, 0, 16, 22, 22,118,223,243,105,211,166, 49,
+217, 87,175,110,106,168, 88, 0,155,249,223,217,125,227,109,190,127, 0,216,188,121, 51,174, 23, 21, 1, 0,118,101,102, 86,121,
+118,245,234,213,208,144,144,144,242, 71, 49, 8, 12, 29,218,202, 54,239,186,202,125,219,181,237,185, 35,120,249,249, 94,225, 88,
+ 22, 26,101, 57, 74, 75, 75, 81,166, 42,135, 78,175,135, 78,175,135,182,162, 2, 58,181, 6, 90,149, 10, 70,131, 30,180,209, 8,
+142, 97, 29,142, 57,109,229,114,219,152,193, 1,160,237,221, 1, 0,240,227,214, 95, 49, 63,121, 85, 0,128, 48,151, 27, 98,235,
+200,168,234,130, 67, 68,167, 33, 81,143,122, 80,190,251,138, 28, 45,215,157, 5,137,232, 6,211,225,116,220,122,163, 39,188,133,
+ 4, 71,135,133,128, 81,151, 32,114, 95, 49,132, 14,154, 95, 70, 70, 6,121,123,230, 59,184,126,245, 42,178, 50,143,194,223,215,
+ 31,227, 94, 25,135,128,224, 32,156, 57,153, 13, 31,177, 20,222,222,222,104, 34,111,138, 77, 63,111,194,135, 31,127,132, 10, 55,
+152,184, 13,189,122,245,114,249, 29, 95, 95, 95,168,213,234,190, 20, 69,209,205,155, 55, 71,159, 62,125,208,185,115,103, 52,106,
+212, 8, 82,169, 20,114,185, 28,221,187,119, 71, 64, 64, 0,180, 90,109, 75, 95, 95, 95, 71, 36, 63, 61,124,248,112,198,134, 13,
+ 27, 68,229,229,229,243,170, 49,235,216, 65,131, 6,125,177,110,221,186,239,194,194,194,150, 16, 66,124, 0,124, 8,160, 46, 51,
+217,199,139,181,218, 79,223, 98, 24,246, 91,131, 97,124, 53,122, 49,175, 38,252,235,151,233,239,205, 18, 92,189,122, 21, 39, 78,
+156,192,186,117,235, 42, 0,252,243, 73,211,236,171, 7,189,215, 22, 4, 95,125, 16,144, 8, 40,226,155, 95,166,251,105, 83,214,
+205,127,158,187,165, 60,105, 96,201,117,148,222,132,244,151,119,177,100,128, 22,217, 11,251, 96,101,116, 5,188,183, 79, 3,148,
+ 5,168,224,165, 23,173,146, 87, 45,248, 43,170,255,252,133, 95,241,175,127,109, 64, 27,191,174,248,243,248,121,236, 87, 92, 70,
+116,255,206, 24, 54,200,210,208,120,129, 16, 52,235,252, 71,142,232,217, 1,139, 63, 93,134,125, 23, 53,240,145,119,194, 11, 47,
+140,194,111,135,182, 97,247,111,155, 44, 31,199,154, 33, 17,213, 61,206,241, 28, 11,150,179,104, 51,176,106, 51, 52, 77,195,104,
+ 52,194, 96, 48, 64,167, 55,192,160,215,193,160,215, 65,111, 50,130, 54,213,190,237,115,153,193, 23,234, 10, 22, 26, 3, 7,141,
+129,179,252,175,229, 80,161, 99, 80,161,103, 80,174,100, 81,166, 52,163,172,220,140,178, 50, 51, 74, 75,105,220, 43, 53,215, 41,
+ 0,252,101,254,191, 95, 85, 19, 10,120, 8, 8, 1, 95, 45,234,159, 39,142, 21,167, 15,226, 63, 64,199,254, 29, 43,175, 15,172,
+ 63, 80,105, 17, 56,182,231, 24,174,222,186,122,211,149, 6,151,158,158,254, 95,158,231,187,196,196,196,196, 71, 68, 68,132, 0,
+160, 56,142,147,152,205,230,192,153, 51,103,250,213, 98, 10,174, 17,226,176,176,249,107,214,172, 25, 25, 19, 19,131,136,144, 16,
+167, 92, 87,245, 52,255, 71, 1, 64,100,135, 14, 14, 3,216,218, 54,110, 28,157,156,156,140, 63,111,221,210,252,178,127, 63,174,
+ 92,185, 82,169,245,183,111,223, 30,214,103,244, 47,251,247,227,214,173, 91,184,154,157,109,112, 68,115,214,252,249,152,189, 96,
+ 65,165,121,223,246,191,237,218,246,191, 43,177, 0, 73, 73,105,252,144, 33, 67,222,181,103,250,182,115,239,222,189,145,148,148,
+230,148,118,125,237, 74,110, 54,195, 48,160,105, 19,148,247,138, 81,114,183, 8,165, 69,247, 80, 90,116, 15,202,226, 18,168,202,
+202, 96,210,233, 44,241, 51, 42, 21,156, 8, 2,100,230, 39,175, 18,206, 79, 94, 37, 4,160, 1,192,245,237,213,237,190, 68,118,
+113, 1, 78,163,105,235,200,168,194,220,108, 69,247, 62,127,229,161,117,207, 23,163, 84, 37, 55, 20,245,105, 31, 36,174,188,138,
+230,239, 14,114,148, 58,228, 79,126, 10,252,205, 11, 8,253,207, 25,120,175, 61,141,187,175,200,209,123, 95, 49,136, 72, 2, 33,
+ 1,132,148, 99, 1,244,194,197,139,228,147,101,139, 49, 99,246,251, 48,115, 44,174,228, 93,195,132,113,227, 33,150, 74,177, 99,
+251, 78,192,204,194,100, 52,225,104,246,113, 24, 12, 21,152, 50,105,210,225,183,223,126,187,174,186, 38, 99,198,140,137, 30, 62,
+124, 56, 8, 33,200,200,200,184,207,164,255,193, 7, 31, 56,253,157,193,193,193,184,115,231, 14, 0, 8, 83, 82, 82, 80, 82, 82,
+130,174, 93,187, 34, 32, 32, 0, 20, 69,225,228,201,147,160, 40, 10,132, 16,220,185,115, 7,193,193,193,206,144, 93, 66,211,244,
+ 96, 0,155,237,238,141, 27, 52,104, 80,242,228,201,147, 3, 83, 82, 82,164,132, 16, 10,192, 54, 88,102, 1,220,115, 64,111,206,
+ 9,179, 57,178, 58,189, 87,231,254,178,229,229,241,211,200,200,119, 82,144,121,226, 18,146,147,147, 57,141, 70,243, 38, 44,179,
+ 11,158, 56,244,232,209,163,242,112,202, 5, 0, 32,119,211,241,155,137, 74,157,233, 52,128, 28, 0, 77,178,174,149,124, 61,184,
+ 67,216,199,194,155, 39,130,176,110, 34, 32,241, 6, 76, 58,128,231, 97, 22, 72,239, 29,253,243,238,183,168, 99,245,165,141, 63,
+125, 21, 61,126, 66,188, 2, 0,116,156, 25,215, 85,249, 0, 88,180,241,139, 64,116,116, 55,132, 53,106,140, 50,181,198, 98, 43,
+160, 25,220, 85,233,234,252,168,102, 45,250,163, 32,223, 58,205,147, 8, 49,162,187, 37, 6, 96,223, 69, 51,126,219,149,142,123,
+165,119, 16, 28, 96,153, 73, 16, 32, 22,161, 91,100, 15, 40,182,215, 97,210,133, 16, 98,142, 1, 11, 1, 56, 66, 64,177, 28, 96,
+102,192,138,132, 0,161, 96,235,147, 28, 15,203, 90, 1,117, 96,175,226, 38,121,126,160, 47,239, 37,230, 33, 20,217, 89, 24,204,
+ 0,195, 3, 70, 26, 96, 77, 44, 8, 33, 32, 98, 2,134, 5,116, 38,224,100,150,154,244,232,209,156,175,209,228,111,227,150, 20,
+ 7, 98, 53,255, 91,132, 2, 2,150,163, 64, 9,172, 51, 5, 0,240, 2, 30,224,157,179, 2,216, 51,255,154,174,143,237, 57, 22,
+225,108, 67,139,137,137,233,156,158,158,254, 57,128, 30,233,233,233,251,210,211,211,143,198,196,196, 36,182,110,221,218, 76, 8,
+ 9, 94,185,114,229,254, 15, 63,252,112,194,178,101,203, 14,215, 33,124,218,180,127,225,236,217,179,231,207,158, 61, 27,251,246,
+237,131,238,222,253,125, 57, 34, 36, 4, 55,111,222, 4, 0,133, 51, 11,249,212,182,232, 79, 98, 98, 98,212,154, 53,107, 20,171,
+ 87,175, 70,100,251,246,209,167, 46, 95,118,104, 42, 62,126,241, 98,230,128,255,207,222,151,199, 53,121,108,239, 63,147,141, 0,
+ 42,130,187,104, 85,172,168, 85,235,130, 21, 80, 43,137,162,181, 90,187,252,106,212,234,181,245,171, 45, 65,237,117,235,130,182,
+182,118,209,170,189, 23,181,171,196, 46, 87,187, 88, 37, 88, 91,183,186,160, 9, 42, 34,136, 86,235, 10, 8, 42,130, 11, 74,194,
+150, 0,217,230,247, 71,242,198, 16, 3,121, 19, 80,180,125,159,207, 39, 31,222, 45,135,201,204,188,243,156,115,230,204,153,190,
+125,159,186,112,236, 88,103, 0, 62, 0, 62, 55,250,248, 64, 88, 93,141,110,237,218, 97,193,130, 5, 72, 77, 77, 93, 25, 26, 26,
+154,146,154,154,186,191,160,160,192,141,114,119,119, 30,128,122,196, 0,212,208, 3, 83, 82, 82, 72, 92,156,236,216,209,163, 69,
+169,114,185, 92, 4, 0,113,113,178,193, 43, 87, 42,211,192, 50, 9, 80,231,190,143,189, 83,121,253,198, 40,139,201,220, 67, 87,
+ 90,138,210,219,183, 64, 8, 15,148, 90, 80, 85, 85, 5, 74, 41, 40,165,184,116,238, 60,140,134,106,252,153,156,236,174, 14, 29,
+199,156,230, 0,120, 99,164, 81,150, 49,210, 40, 56, 46, 11,180, 77, 17,176, 70,135,110,131, 36, 5, 57, 25, 42, 0,232,220,169,
+ 19, 78,101, 88,245,228,220, 63,183, 1, 0, 90, 61, 50, 64,122, 43,255, 68,163, 13,198, 3,255, 40, 66,230,211, 64,191,176,104,
+ 20,205, 30,140,182, 95, 31, 65,182, 70,135, 64, 17, 65,177, 70, 11, 1, 33,110, 61, 0,246,119, 51, 53,181,198,147, 93,187,118,
+165, 99,198, 62,141, 29,219,118, 32, 49, 49, 17, 31,188,251, 30,246,170,247,131, 47,224, 35,184, 67,112, 84,105,105,221, 75,151,
+183,110,221,170,182, 41, 2,146, 81,163, 70,213,136, 5,216,183,111, 31, 46, 94,188, 88,165, 80, 40,218, 57,123,147, 92,246,151,
+206,157,145,151,151,135,199, 30,123,204, 52,111,222, 60,209,166, 77,155, 16, 16, 16,128, 11, 23, 46,220,229,121,205,203,203, 67,
+103,246,237,236,152,120,110,234, 19, 79, 60,241,209, 75, 47,189, 20,144,153,153,217,180,170,170,234,255,124,125,125,159,177, 5,
+ 6,254,206, 82,158,227, 66,249,169,207,252,123,211,134,161, 35, 94, 32,159, 38, 3,164,253,179,248,100,205, 59, 84,147,115, 97,
+ 58, 0, 37,254,198,168,161, 0,204, 85,227,236,103,146,234,236,185,106,251,148,102,254,103,146,146, 63,202,171, 76,186,240, 71,
+ 91,142, 9,242,227, 63,193,175,174,242, 55, 81, 94,121,113,185,225,104,218,197, 27,123, 10, 53,250,148,185,106, 92,175, 77,201,
+152,242,175,197,234,131, 71,210,164, 0, 84, 22, 62, 51,205,199,199,197,178,235,120,255,245,233,208,235,171, 81, 86,105,141, 1,
+ 48,240,124,176,121,107,221,105,118, 11,242,211,200, 11,207,254,219, 74,150,102,198,114, 54, 97,116, 31,130, 73,179, 86,193,207,
+207, 7,205,124,197, 82, 0,170,156, 51, 39,164,235,191,216, 90,231,128, 36,160, 38, 24,136, 85, 9, 0, 33, 48, 83,106, 85, 4,
+ 76,182,229,126,132, 7,129,197, 2,147, 45, 56,208,157, 18, 80, 82,217, 28,149,213,197, 16, 9,120,246, 52,103, 38, 11, 96, 52,
+ 82, 24, 77, 20, 21,149, 22, 16, 62,129, 25, 4, 70,203, 29,215,189, 43,152, 45, 60,240,136, 25,196, 76, 64,121,212,238,254, 39,
+181, 24,207,140,164,179, 23, 54, 17,119,185,161,207,167,157,175,111,223,177,187, 45,250,244,233,115, 61, 36, 36,228,133,203,151,
+ 47,119, 75, 76, 76,204, 0,240, 92, 82, 82,210,115,142, 15,175, 88,177, 66,189,112,225, 66,233,138, 21, 43,220, 17,132,189, 66,
+ 98, 99, 99,107,125,232,197, 87, 94,177,250, 0, 61, 75, 12, 68,157,220,254, 0,128, 65, 61,123, 74, 51, 88,144,191,125, 0, 62,
+117,202, 30,173, 58,184, 79, 31, 75,124,124,252,151,227,198,141, 51,101,101,101, 9,174, 92,185,130,206, 45, 90,164,237,216,177,
+131, 85,128,226, 61,202, 3,224, 72,238, 55, 83, 82, 82, 28, 99, 60, 78, 59,212,179, 91, 37, 64,185, 98,165, 78,182, 48,238,197,
+ 11,251, 15,164, 53,247,247,111, 86,166, 45,129,201,100, 2,181,189, 7,218,155, 69, 40,211,106, 65, 41, 69,255,232,104,233,159,
+201,110,243, 32,153,112, 39,230,132,103, 91, 14,200, 11, 31,240, 56,198, 72,163,236,171, 0,114, 46, 95,102,173, 4, 68,143,125,
+ 73,146,188,243, 23,187,149,255,187,242, 59, 21, 0,180, 10, 25, 34,189,149,151,170, 6,128,198, 33,127,122,183, 18,128,111,208,
+ 47,246,125,220,176, 88,208,119,125, 6, 50, 70,183, 65,175, 29, 55, 33, 32, 64, 83,161,119,123,179,237,216,177,131, 76,124,105,
+ 34, 29, 62,114, 4,182,109,249, 13, 31,175, 92,129,184,210, 82, 80,139, 5,155, 55,111, 65, 97, 97,225, 51, 0,118,184,147,227,
+ 74, 17, 0,128, 23, 94,120,225, 36,128,114, 54,101, 89,191,126, 61, 25, 53,106, 20, 61,113,226,132,104,192,128, 1, 24, 49, 98,
+ 4, 84, 42, 21, 30,121,228, 17, 84, 87, 87, 35, 42, 42, 10,148, 82,203,137, 19, 39,120, 66,161,208,155,140,128,143, 5, 4, 4,
+172,158, 56,113,162,240,220,185,115,205,170,171,171,107, 11, 12,100,139,254,193,253, 38,108,232, 55,108, 34,249, 46, 5, 40,171,
+ 4, 12,151,118, 91, 52, 57,170,105,168, 25, 24,248,208,128,201, 3,224,104,249,187,186,230,210,149,234, 64,254,204,249,249,207,
+ 36, 21,249, 87,110, 87,164, 1,104,103,123,121,171, 1, 20, 2,200,155,171,134, 91, 23,167,226,235,157,234,161, 67,251, 72,205,
+180,137,202,241,229,168,208,149, 89,215,253,243,252,144, 91, 14,178,230,235,141,172,126,224,214,109, 95,144, 91,154, 60, 9,120,
+122,149, 35, 23, 54,105, 18, 0,179, 81, 11, 80, 29, 70,247, 97, 55,161,107, 4, 31,160,212, 74,212,224, 67, 68,109,138,128,141,
+252,173, 57, 0, 1,152,217,205, 77,164, 29,191, 74,194,122,183,163, 38,163, 6, 2,219,194, 94, 74, 41,204, 38,138, 42, 35, 80,
+ 86,110,130, 17, 20, 38,202,131, 64, 72,112,251,166,177,214,114, 30, 59,182,146, 0,192,224,200,183, 40, 49, 90,173,127, 10,128,
+ 82, 2, 80,155,197, 64,249, 32,124, 11, 44, 22, 1,178,115,182,176,250,205,175,126,252,170,244,114,238,229,186, 8, 88, 8,235,
+ 82,141,186,216,201, 94,243, 75,150, 44, 97,252,163,167,108, 86,241, 29,162,126,241, 69,201,150, 45, 91, 84, 54, 37, 64,229, 78,
+ 9, 88,167, 84, 26,255, 60,125, 90,214,185, 79, 31,243, 19, 61,122,232,108,125,180,218,230, 16,177, 67, 54,122,180,213,226,232,
+211,199,253,116,199, 91,111, 73, 1, 96, 96,247,238,119,221,203,204,202, 82,103,156,247, 94, 25,234,211,179,231,215, 60, 30,207,
+124,225,216, 49,255, 54,109,218,220, 78, 45, 40,216,224,206,234,191, 15,172,227,216, 15,116,182,128, 63,102,106,160,194,169,173,
+217, 40, 1,231,100, 11,227,194,183,125,251,221,150,144, 46,157, 31,171,174,174,130,217,104,130,197, 98, 65,211,192, 64,148,106,
+ 52, 12,249,179, 81,162, 74, 62,124,227,223,173, 1, 24,114, 46, 95, 22, 49,243,255,233, 39,254,194, 24,105,148,101, 73,252, 23,
+238,146, 3,217, 49,107, 78, 28,189,144,117, 65,234, 72,254, 0, 48,252,169,231,164, 7,246,252,174,190,149,151,234,125, 37,214,
+ 18,224,231,250, 58,123, 14, 27,248, 71, 17,240,199,235,246,243, 71,127,191, 97, 63, 46, 53,154,189, 46,239,230, 95, 54,147, 33,
+ 67,134, 60, 61,106,236,232, 93,175, 77,157,113,248,241,190,125,134,110,251,125, 59,210, 78, 30,199,241,227,199,119,214,229, 6,
+174, 67, 17,152,177,117,235,214,111,183,110,221, 26,177,117,235, 86,214,133, 27, 53,106,212,240,189,123,247, 30,216,177, 99, 7,
+ 66, 66, 66, 48,114,228, 72, 4, 4, 4,100,151,150,150,134,158, 61,123, 22,121,121,121, 60,161, 80,136, 81,163, 70, 69,239,221,
+187,215,211,159,122,174,180,180,116,229,246,237,219,235, 10, 12,244, 4,127, 22,158, 76, 92,254, 91,210,179,239, 84, 6, 79, 65,
+229,177,197,150,107,135,150, 77,173,135,188, 7, 78, 17, 96,237, 1,168, 13,115,213,208, 1,248,203,246,241, 10,135, 15,159, 86,
+199,198, 46,148, 38, 40, 62, 86, 5,119,234, 6,160, 26, 66, 31, 49, 10,174,151, 97,227,142, 84,226,185,188,157,234,105,175,206,
+199,250,239,127, 5, 44, 87, 0, 8, 96,170,170, 68,112,187, 0,233,178,183,102,176,182,230, 96,182, 64,192,179,192, 72, 4, 16,
+ 82,211, 29, 69, 0, 38,128,154,193, 54, 48,204, 17,199,207, 92, 39, 0,208, 54,136, 71,133, 2,171,181,111,178, 88, 19, 24,149,
+148, 83,152, 77, 0, 95, 96,129,217,196,110,228, 56,146,246, 31, 2, 0,225,131, 22, 80, 48, 57,225,121,128,133, 88,221,253, 89,
+ 57,219, 61, 42,228,183,239,125,171,110,128,254,197,202, 92, 97,200,223,193, 19,224,118, 57,214,177, 11, 23,146,142, 57,185, 12,
+235,120,214,237, 51, 13,153, 58,248, 46,229,214,186,196, 47,193,106, 91,123,183,111, 72, 3,231, 1,112,174, 91,157,155,165, 86,
+172,250,142,114,197,202, 11,178,133,113,189, 1,240, 47,164,164, 24,171,244,149,176,152,205,232, 25, 22, 38,109, 23,250, 24,142,
+253,177,157, 93, 29, 83, 50,113,207, 31, 59,237,167,131, 31, 11,177, 31,239,249, 99,231, 93,231,117,133,198,127,253,185, 85, 65,
+ 30,241,212,243,210,115, 23,114,113,253,202,105, 21, 0, 28,216,243,187,170,205, 35,189,165, 55,243,207,120,220,238, 19, 38, 76,
+128,167,233,125,205,196,167,206,251,249, 47,180,197, 31,215,170,238,249,128,159,154,154,250,135, 66,161,224,101,102,102, 90,246,
+ 31, 77, 65,139,150, 45,156, 87,122,120,132,173, 91,183,126,167, 80, 40,126,144,203,229, 70, 79,190,247,230,155,111,170, 0,144,
+105,211,166,209,220,220, 92,100,100,100,160,188,188, 60,180,105,211,166,104,209,162,133,125, 47, 0, 47,200,159,193,127, 82, 82,
+ 82,132,105,105,105,125, 12, 6,195, 98,212,156,203,247, 6,239,158,217,252, 47, 97, 64,215, 31, 22,148,230,238,157,210, 0,242,
+ 26, 21,204, 42, 0, 87,215,189, 82, 0,220, 14,130, 10,133, 96,237,218,181,238, 93, 85,123,142,168, 59,116, 30, 65,110, 22,164,
+209,214,193, 29,161, 41, 55, 97,227,182,195, 94,119,208,245,223,174,182,125,183, 13, 5,110, 34,176,169, 0,203, 22,189,230,209,
+ 75,255,205,209,156,123,182,129,205, 13,141,133, 0,128,216, 87, 72, 13,149, 70, 88, 0,248,249,249, 65,111,210, 19,179,201,115,
+121,233, 25,214, 61, 3,194,159,152, 79, 45,148,143,203,151,118, 53,230,238,102,108,151, 14,114,187, 4,178,168, 31, 71,194,111,
+224,105, 1, 67, 92,156,204, 7,128,121,229, 74,165,185, 62,130,148, 43, 86, 50, 27,249,216,219, 52,247,140,103,235,244,231, 44,
+255,194, 43,101,204,121, 43, 96, 71,236,223,243,155,218,185,175,221,204,247, 46,127,128,187,141,125,156,117, 96, 19,241, 65, 37,
+175,238, 21,169,185,229, 38,132, 54, 21,220,151, 87,197,182, 86,191,193,222, 57, 79,201,191,198,248,236,253,134, 63,108,240,137,
+193, 96,248, 13,112,191, 41, 29, 75,188, 93,154,187,119, 35,106,198, 6, 60,212, 74, 0,171,193,199,219,125,132, 57,112,112, 68,
+183,110,221,144,147,147,195, 85, 4, 7, 14, 28, 56, 60, 36,224,113, 85,192,161, 33,192,145, 63, 7, 14, 28, 56,112, 10, 0, 7,
+ 14, 28, 56,112,224,192,129, 83, 0, 56,112,224,192,129, 3, 7, 14,156, 2,192,129, 3, 7, 14, 28, 56,112,104,116,212, 8, 77,
+ 61,121,242,164,215, 81,155,174,130, 9, 57,121,156, 60, 78,222, 3, 35,175,206,232,112,174,254, 56,121,156,188,191,151, 60,143,
+ 21, 0,135,129,194, 83,184, 27,120, 26, 82, 30,135, 7, 19,148,107,183,135,178, 29, 88, 63,175, 80, 40,252, 1, 60,113,248,240,
+225,101,124, 62,127,176,143,143, 15,244,122,253,145,161, 67,135,190, 11, 32, 67, 46,151,235, 31,132, 10,176,101,135, 84,253,147,
+199, 21, 74, 41, 61,115,230, 12,250,244,233,195,189,147, 28, 60, 82, 0, 60, 90,135,204, 38, 81,142, 43,121,142,137, 79, 60,149,
+247, 15, 28,208, 89,225,169,167,158,146,238,217,179, 71,205, 86,102,112,112,240, 93, 55, 10, 11, 11,157, 7, 83, 40,149, 74,194,
+178,140,247, 76, 9,168, 45,159,127, 99,201, 91,181,106,213,136, 45, 91,182, 36,103,103,103, 3, 0, 66, 66, 66,158, 77, 79, 79,
+223,238,109,251, 58,246,123, 74,169,253,253, 96,174, 51,239,138,237, 58,113,163, 60,179,109, 7, 79,200,255,177, 51,103,206,108,
+ 41, 43, 43,235,209,169, 83, 39,220,190,125, 27, 85, 85, 85, 0, 48,120,203,150, 45, 42,127,127,255, 11, 10,133,226,121,185, 92,
+ 94,231, 86,146,103,206,156,241,200, 32, 72, 77, 77,149,202,229,114,181, 39,223, 81, 42,149, 42,153, 76, 38,245, 38, 1, 20,245,
+ 48, 9,195,132, 9, 19, 60,121, 63, 0, 0,157, 58, 89,119,192, 45, 47, 47, 71,117,181, 53, 13,186, 78,167,243,228,125,171, 19,
+167, 79,159,166,131, 7, 15, 70,207,158, 61,225,227,227, 83, 84, 93, 93,253, 8, 55,140,254,243,224,156, 12,232,158, 37, 2,226,
+172,216,123,139,223, 19, 70,187,125,230,249,153,187, 61,146,169, 82,221, 49,144,178,179,179,225,239,239,111, 31,132, 24,176,217,
+252, 67, 38,147, 81,165, 82,233,124, 78,106,121,198,171,186,141,138,186,179,157,171, 43,249,245, 1, 33,132, 14, 27, 54, 76,154,
+146,146,226, 17, 89,108,217,178, 37,185,117,235,214,120,249,229,151,161,213,106, 45,241,241,241,219, 86,172, 88, 49,105,225,194,
+133,155, 61,252,255,248,227,143, 63,236,231,163, 71,143,198,238,221,187,235, 60,103, 35,214,169, 47,211,176,176, 48, 0,160, 14,
+153,225, 60, 34,255,210,210,210,180,174, 93,187, 54, 3, 0,177, 88, 12, 95, 95, 95, 20, 21, 21,161,164,164, 4, 1, 1, 1, 40,
+ 42, 42,234,177,123,247,238, 12,133, 66,209, 93, 46,151,223,168, 75, 94,239,222,189, 33,147,201, 16, 18,114, 39,235,223,202,149,
+ 43,107, 60, 19, 23, 23, 7, 0, 56,122,244,168,202,155,126, 83,159,236,143,107,214,172,169,237,150,125,175, 2,111,225,239,239,
+143,115,231,206, 65, 40, 20,194, 96, 48, 96,247,238,221,200,201,201,193,162, 69,245,219,113, 54, 48, 48,144, 15, 32,250,224,193,
+131,187,163,162,162,110, 62,255,252,243,109,146,147,147,193,231,243, 91, 53,111,222,156, 15, 14,255,104,242,103,174, 57, 43, 1,
+127,155, 32,192,240,240,112,201,253,182,184, 27, 19,193, 3,151,218, 63,222, 66,171,213,218, 45,126,157, 78,135,117,235,214,217,
+ 63, 30, 12,180, 46,207,199,143, 31, 79,101, 50, 25, 5, 64,157,159,241, 20, 7, 15, 30, 84,189,245,214, 91,232,210,165, 75,131,
+213, 95,231,206,157,201,219,111,191, 13, 74, 41, 82, 82, 82, 84,158,182,123,118,118, 54, 70,143, 30,109, 1, 0,145, 72,196, 11,
+ 13, 13, 69,124,124,252,166, 86,173, 90,209,240,240,240, 49, 30, 88,156,247,170,139,144,176,176, 48,202,252,174,227,199,143, 51,
+251, 1, 48,237,194,218,237,175,213,106,183,136, 68,162,102, 0, 48,123,246,108, 76,153, 50, 5, 34,145, 8,190,190,190, 16,139,
+197, 32,132,128,207,231,163,180,180,180, 25,128,120,133, 66, 81,167,236,184,184, 56,132,132,132, 32, 47, 47,207,254,137,139,139,
+171,241,169, 15,100, 50,153,212,246, 59,189, 30, 19,230,207,159,111,255, 56,142,151, 78,215, 45,108,229,117,234,212, 9,254,254,
+254, 88,188,120, 49,252,253,253,177,109,219, 54, 84, 86, 86, 54, 8,249,219,222,101,170,213,106,255,111,234,212,169,232,214,173,
+ 91,155,221,187,119,227,230,205,155,184,122,245, 42, 74, 74, 74, 12,247,115,108, 82, 40, 20,146,130,130, 2,170, 80, 40, 36,174,
+238,229,228,228,208,139, 23, 47,114, 9,232,238, 3,249,199,196,173, 64, 76,220,138, 90, 21,131,251,162, 0, 16, 23,168,235,186,
+ 55, 72, 79, 79, 87, 53,132, 18, 48,101,202,148,135, 70, 9,168, 47,244,122,253, 93, 86,191, 55,205,203,144,201,248,241,227,237,
+ 86,126, 82, 82, 18,234, 75,252,142,214,191, 82,169, 36,195,134, 13,147, 42,149,202, 26, 30,129,250, 32, 49, 49,145, 0, 32, 81,
+ 81, 81, 82,103, 79, 3,203, 65,215,100,243, 6,160,117,235,214, 88,186,116,105,213, 27,111,188, 97,200,203,203,219,185, 98,197,
+138,145,141,221,190, 14,123, 0, 16,199,118,242,176, 93,158,200,201,201,233, 1, 0, 51,102,204, 64,105,105, 41,174, 93,187, 6,
+161, 80, 8,129, 64, 0,129, 64, 0,161, 80, 8, 95, 95, 95, 84, 86, 86, 34, 57, 57,121, 50,128, 64,119, 66,243,242,242,160, 84,
+ 42,237, 31, 71, 79,192,202,149, 43,145,156,156,236,245,239, 86, 42,149,106,219, 20,128,170,129,222,229,218, 18,119,179, 30, 63,
+ 47, 95,190,140,157, 59,119, 98,233,210,165,232,212,169, 19, 90,182,108,137,148,148, 20, 44, 90,180, 8,254,254,254, 0, 0, 62,
+191, 94,134,122,187,233,211,167, 79,252,207,127,254,131,244,244,116, 92,187,118, 13, 38,147,233,229, 22, 45, 90, 4, 2, 48,222,
+239,190, 23, 28, 28,140,152,152, 24, 85,110,110, 46,117, 36,255,152,152, 24,213,163,143, 62, 10,179,217, 12, 14,247, 22,142,196,
+239,120,220, 24, 30, 0,234,226, 83,215,245, 70, 83, 2,198,140, 25,211, 16, 74, 0,245,224,195, 26, 47,190,190,167,193, 26, 36,
+ 59, 59, 27, 58,157,174, 86, 55,255,145, 35, 71, 26, 66, 49,168, 55, 14, 30, 60,168,178, 41, 22, 72, 73, 73, 81, 19, 66,208,186,
+117,107, 85, 67,118, 78,198,253,111,243, 4,212,137, 85,171, 86,141, 25, 50,100, 8, 5,128,248,248,120,209,247,223,127,143,151,
+ 95,126,153,113,205,139,255,250,235, 47,145,237,222,222,240,240,240,231,216,252,255,209,163, 71,227,233,167,159,182,187,247,153,
+ 99,230,156, 57,102,233,254, 7, 0,216,172,127, 87,237, 64,156,238,215,137,221,187,119, 47,107,217,178, 37, 0,224,226,197,139,
+200,207,207,199,137, 19, 39, 96, 48, 24, 64, 8,129, 64, 32, 0, 33, 4,102,179, 25,122,189, 30, 91,183,110, 5,128,190,158,120,
+142,100, 50,153, 75,229, 37, 47, 47,175, 94, 74,128,195,111,175,151, 55, 0, 13, 48, 85,106, 52, 26, 49, 96,192, 0,168,213,106,
+ 92,190,124, 25, 3, 7, 14,180,223, 83,171,213, 8, 10, 10,178, 43, 2, 94,160,253,244,233,211, 11,190,251,238, 59, 68, 71, 91,
+ 55, 50,106,223,190, 61,204,102,243,143, 0, 74,238, 55,241,200,229,114, 53,163,124,134,132,132,224,216,177, 99,148, 33,127, 70,
+249,235,222,189, 59,155,241, 97, 16,128, 31, 96,221,243,172, 46,140, 5, 16, 3,160, 21, 71,251,247,185, 99,179, 98,195,251, 24,
+ 4,104, 83, 2,164,233,233,233,106,111,101,116,238,220, 25, 83,166, 76,193,207, 63,255,236,109, 76, 0, 1, 64,127,254,249,103,
+151, 55,119,237,218, 5,219, 61,143,101, 31,189,244, 24, 34,186,156, 67, 97,230,226,122,213,147,227,156,127,114,114, 50,162,163,
+163, 17, 19, 19, 99, 39,255,142, 29, 59, 54,132,210, 87, 47, 69, 32, 42, 42, 74,114,240,224, 65,220,190,125, 91,202, 92,147, 72,
+ 36, 82,165, 82,169,138,138,138,146,120, 58,111,239,230,127, 73,217, 40, 0, 91,182,108,217,201,204,253,235,116, 58,172, 92,185,
+ 18, 21, 21, 21, 16, 10,133,240,241,241,193,165, 75,151,176,116,233, 82,104,181, 90,196,199,199,255,182, 98,197,138,225, 11, 23,
+ 46, 84,185, 33,217, 26,202,128,187,152, 0, 22,117, 14, 55, 59, 0,218,167, 3,220,253,222,160,160,160,193,213,213,213, 48,153,
+ 76, 56,114,228, 8,248,124, 62, 12, 6, 3, 42, 43, 43, 97,177, 88,236,239,177,209,104, 68,117,117, 53,243, 78,247,118, 39,183,
+ 54, 55,127, 92, 92,156, 61, 30, 32, 36, 36, 4, 69, 69, 69,245, 86, 68, 29, 86, 5,176,237,139, 26, 0, 65,174,110,172, 94,189,
+218,171, 66,196,199,199,227,173,183,222, 66,255,254,253,237, 30, 16, 38,125,118,255,254,253,145,149,149,133,214,173, 91,123, 35,
+186,211,244,233,211, 47,127,247,221,119,142,227,103,240,181,107,215,174, 53, 38,177, 12, 28, 56,144, 48,164, 63,112,224, 64, 12,
+ 28, 56, 80, 5, 0, 89, 89, 89,232,209,163, 7,219,118, 56, 9,192, 23,192, 38, 0,147,224,180, 37,184, 13,175, 3,248,194,118,
+252, 46,128, 30,128,251, 45,234,255,206, 96,118, 3, 92,183,114,161,221,242, 95,183,114,161,253,222,125, 87, 0,238, 55, 30, 20,
+ 37, 96,202,148, 41,244,221,119,223,189,203, 21,232, 13,249, 55,164,245, 15,192,165,245,207, 88,253, 66,161, 16, 55,110,220,104,
+ 84,242,119,180,254, 29, 3,186, 84, 42,149,163, 23,224,190, 7,108,102,103,103,227,229,151, 95,214, 3,240,243,247,247,199,123,
+239,189, 7,161, 80,104,191, 63,109,218, 52, 0, 64, 96, 96, 32,198,141, 27,135,195,135, 15, 31,184,143,229, 36,142, 30,128,186,
+148,128,176,176, 48,231,173, 98, 93, 42, 3, 6,131, 1, 26,141, 6, 85, 85, 85, 8, 8, 8,128,143,143, 15, 76, 38, 19, 40,165,
+ 48,155,205, 48, 24, 12, 48, 26,141, 48,155,205,142, 10,253,237,186, 10,153,151,151, 87, 35, 0,144,153, 14,112,244, 8, 56,222,
+175, 47,188, 8, 8, 20,215,118,195, 49, 38,192, 19,101, 96,233,210,165, 24, 59,118, 44, 58,119,238, 12, 63, 63, 63, 72, 36, 18,
+104, 52, 26,248,251,251, 67,171,213, 98,253,250,245,224,241, 60,118,200,118,152, 62,125,250,229,121,243,230, 97,219,182,109,120,
+238,185,231, 0,160, 45,128,155, 15,194, 56, 44,151,203,213, 1, 1, 1,210,137, 19, 39,170, 0, 96,243,230,205,210, 73,147, 38,
+121,210, 22, 6, 0, 83, 0,252, 92,135, 18,224, 56,213,246, 8,128, 62, 0, 50, 56,219, 30, 53,136,191, 54,252, 45, 51, 1,214,
+151,252, 25,120,107,165, 59, 14,200,203,150, 45,171, 55,249, 51, 24,208,191, 31,246, 31, 80, 97,227, 1, 63,187, 82,112,244,210,
+ 99,245,250,141, 97, 97, 97,200,203,203, 67, 82, 82, 18, 58,118,236,136, 13, 27, 54,120,108,117, 41, 20, 9, 18, 7, 15, 78,131,
+144, 63, 51, 31, 95, 84, 84, 36,117,190, 55,108,216, 48,105, 82, 82, 82,131,197, 2, 0, 86,247, 63, 91,239,147, 86,171, 61, 15,
+235,188,176,101,243,230,205, 88,191,126, 61, 0, 96,211,166, 77,208,106,181,204, 99,166,172,172, 44,180,106,213, 56, 94, 73,167,
+104,255,187,148, 51,182,251,196,231,229,229, 29, 49,155,205,208,106,181,184,125,251, 54,180, 90, 45,244,122, 61,244,122, 61, 42,
+ 42, 42, 80, 86, 86,134,210,210, 82, 84, 86, 86,162,186,186,154,153,219, 77,171, 75,166, 51,185,187, 10, 36,117, 94, 21,192, 22,
+ 54, 87, 63,117,113,205, 19,248, 53,116,123,108,216,176, 1, 18,137, 4,126,126,126, 56,119,238, 28,212,106, 53,252,253,253,241,
+254,251,239,227,240,225,195, 88,180,104,145,167, 10, 64,219,233,211,167, 95,157, 52,105, 18,126,253,245, 87,134,252,219, 63, 40,
+228,111, 29, 23, 20, 18,134,252, 1, 96,226,196,137,170, 11, 23, 46,120, 58,181,202, 40, 1,176, 41, 1,206,211, 1, 23, 29,142,
+243, 1,156,230,104,255, 14,156,131, 0, 27, 69, 1,184, 31, 65,128, 13, 77,254, 54,226,110, 8,203,141, 44, 91,182,172, 94,228,
+255,226,235,123, 48,160,255, 29,215,205,150, 95,183,218, 61, 2,251, 15,168,188, 82, 2,228,114, 57,108, 75,195,160,215,235,177,
+111,223, 62, 44, 93,106, 93, 81,112,250,244,105,152, 76, 38, 15,100,197,170, 1,107,224, 31,165,148, 9, 6,172, 23,249, 51,214,
+127, 93,110,254,134,138, 5, 96, 20, 9,137, 68, 34,117,247,108, 72, 72,200,168,248,248,248,176,244,244,116,193, 15, 63,252,192,
+187,112,225, 2,166, 77,155,102, 98,234, 49, 62, 62, 30,233,233,233,248,225,135, 31, 4, 87,174, 92, 65,120,120,184, 91,153,247,
+ 34, 6,128,177,164,157,148, 0,202, 40,125,108, 17, 26, 26,154,105, 50,153, 96, 48, 24,112,235,214, 45,220,184,113, 3, 55,111,
+222,196,205,155, 55,113,235,214, 45,104, 52, 26,232,245,122, 84, 87, 87,163,180,180,148,249,159, 5,117,201,100, 2,253, 28,149,
+208, 58,202,238, 17,249, 51, 57, 0,156,175,213,167,127,184, 88, 13, 96, 87,242,216,202,200,201,201, 65, 86, 86, 22,244,122, 61,
+ 34, 35, 35,209,183,111, 95,108,216,176, 1,239,188,243, 14, 68, 34, 17,248,124, 62, 4, 2,214, 14,217, 14,211,167, 79,191, 62,
+105,210, 36,100,100,100,224,131, 15, 62, 96,172,223,235,120, 64,150, 49,103,102,102, 82,102,206,255,196,137, 19, 88,183,110,157,
+ 20, 0,186,119,239, 14,199,192,192,122, 42, 1,115, 97,157,255, 31, 15, 96, 22,128,112,252,195,221,255,192,157, 72,127, 87, 65,
+128,206,171, 0,238,215, 20, 0,245,240,250,223,133,252,237, 74, 64, 61,166, 18,106,144,191,171,243,253, 7, 60, 31,223, 28, 7,
+ 93, 63, 63, 63,244,236,217,179,198,253,244,244,116,143,228,141, 31, 63, 30, 73, 73, 73, 96, 20, 1, 0,212,118,205,227,117,231,
+ 27, 54,108, 80, 1,192,238,221,187,165,174, 34,214, 83, 82, 82,212,151, 47, 95,118,105, 61,186, 66,109, 73,127, 24, 69, 35, 37,
+ 37, 5, 81, 81, 81, 82,149, 74,229,182,239,164,167,167,239, 91,190,124,249,136,212,212,212,253,161,161,161,200,206,206,134, 86,
+171, 21, 4, 6, 6, 98,250,244,233,208,104, 52, 87, 82, 83, 83, 59,133,134,134, 34, 53, 53,149,196,198,198,186, 83,142,239,154,
+243,175, 71, 12, 64,141,119,139,201,151, 96,203,157, 96,247,204, 56,204,255,187,109,143,136,136,136,119,212,106,245, 28,179,217,
+140,178,178, 50, 24,141, 70,251,188,127, 85, 85, 21, 40,165,160,148, 34, 43, 43, 11, 6,131, 1,209,209,209, 47,201,229,114,147,
+171,164, 35,181, 33, 58, 58, 26,209,209,209, 53,130,254, 60,157, 2,112, 36,122,155,203,159, 58,246, 15,219,170,128,134, 30,215,
+ 88,143,159,204, 82,191, 55,222,120, 3,106,181, 26, 82,169, 20, 57, 57, 57,104,210,164, 9,242,243,243,193,231,243,217,122, 0,
+200,244,233,211,175, 78,157, 58, 21,135, 14, 29,194,251,239,191, 15, 0,193, 0,174,225, 78,254,135, 70,183,252,153,241, 37, 47,
+ 47, 15, 97, 97, 97, 76, 63,147,198,196,196,168, 66, 66, 66,144,149,149, 69, 89, 6, 2, 58, 42, 1,147,108, 10,192, 38, 0, 71,
+ 0,200, 1, 72, 0,220, 0,135,134,235,192, 13,157,141,207, 85,192,207,202,149, 43,107,189,222,152,228,111, 91, 1,112, 47,180,
+104,175,101, 94, 45,112,223,191,125,125, 61,243, 90,186, 11, 18,243, 20,209,209,209,210,164,164, 36,245,132, 9, 19,104, 98, 98,
+ 98, 13, 69,192, 73,225, 99, 93, 15,177,177,177,110, 53, 27, 15, 19, 3, 81, 39, 69,194, 58, 42, 73,165,172,200,223, 97, 48,183,
+207,235,135,135,135,255, 43, 62, 62,254,199,113,227,198, 33, 43, 43, 11, 87,174, 92,233,180,120,241, 98,105,108,108, 44, 43,121,
+247, 40, 15, 64,141,122,174,133,248, 88,101, 12,148,203,229,186,132,132,132, 37,187,118,237,250,208,100, 50,161,164,164,196, 30,
+ 3, 0, 0,183,110,221, 66, 73, 73, 9, 40,165,140,213,238, 17,203, 50,243,255, 97, 97, 97,246, 8,118,230, 58, 91, 37,192,133,
+149,127,215, 52,212, 61, 32,127,143,193, 40, 1, 11, 23, 46, 68, 74, 74, 10,198,141, 27,135,229,203,151,227,205, 55,223,132, 64,
+ 32,128, 88, 44,118, 59,134, 80, 74, 45, 51,102,204,192,143, 63,254,136,239,191,255, 30, 0, 58,218,200,191,193, 13,170,250,160,
+176,176, 16, 59,119,238,172,145,197,209,118, 44, 29, 62,124,184,202,203, 37,143,102,155, 18,176,195,102,253, 71,112,228, 95, 59,
+ 92, 5, 1,178, 82, 0, 60, 73,196,225, 45, 97, 55, 52, 26,130,252,235, 75,212,247, 2,115,231,206,149, 94,184,112,161, 65,101,
+218, 92,164, 13,186,148,142, 33, 60,219,218,122,198, 43, 64, 9, 33,176, 88, 44,216,178,101, 11,107, 37,224,173,183,222, 98,202,
+121, 87, 12, 0,143,199,131,197, 98,193,219,111,191,173, 98, 75,158,117,201, 75, 73, 73, 81, 59,102, 69,244,162,223,253,180,124,
+249,242, 91,169,169,169,187,217, 90,253,247,193,219, 70,156,189, 61,181, 40,124,172,148,128,216,216,216,143, 20, 10, 69,210,207,
+ 63,255,124, 86, 36, 18,129, 89, 21, 96,177, 88,208,188,121,115,104,181, 90,200,100, 50, 68, 71, 71,251,201,229,114,183, 11,188,
+153,241,197, 49,248,239,248,241,227,136,142,142,174, 49,158,184, 27,135,226,226,226,104, 94, 94,158,212,217,197,239,109, 26, 96,
+ 71,184, 8,240, 51, 1, 48,173, 94,189, 90,108,179, 70,121, 14, 31,143,148, 0,199,196, 63,179,102,205,178, 31,151,149,149,185,
+ 29,155, 8, 33,100,250,244,233,244,135, 31,126,120, 30,192,239, 15, 34,241,216,136,158,120,122,143,141,210,238,132,235, 15,195,
+ 24,126,191,193,172, 2,112, 69,252,172, 86, 1, 52, 52,169,215, 38,239, 65, 81, 30, 30,228,142,243,217,103,159,169, 27, 90,166,
+211, 26,233,123, 6, 39,247, 63,219,151,154,109, 46,116,226,193,239,189,167,191,117,209,162, 69,123,234, 83,159,163, 71,143,174,
+177, 44,246,233,167,159,174,225, 25,240,112,238,159,120,232,237, 97, 85,110,185, 92,126, 78,161, 80, 52,217,187,119,239, 39,249,
+249,249,115, 42, 43, 43, 97, 54,155,209,175, 95, 63, 12, 28, 56, 48, 62, 58, 58, 58,142, 13,249, 3,192,209,163, 71,237,199, 81,
+ 81, 81, 53,174, 59,159,187, 25, 87,136,163, 66,203, 40, 19,182, 56, 0,175,218,125,194,132, 9,181,221, 18, 56,140,151,162,123,
+ 53,174,184,241, 84, 88, 0,224,251,239,191,231, 54, 76,225,192, 90, 9,168,141,252,107, 83, 0, 26,186,115,113,157,149, 3,241,
+ 80,179,255,199,213,141, 35,225,223,131,105,129, 6,121, 7,229,114,185, 14, 86,215,235, 92,230,218,249,243,231,217, 16,151, 29,
+189,123,247,110,240,241,192,149, 66,235,173,203,255, 94, 43,139, 28, 56,254,184,159, 74,128,219,202,245,118, 31, 97, 14, 28, 56,
+112,224,192,129,195,195, 11, 30, 87, 5, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7,
+ 14, 28, 56, 60,132, 48,193,131,237,138, 57,255,124,202,173, 0, 0, 32, 0, 73, 68, 65, 84,252, 51, 33,224,170,128, 3, 7, 14,
+ 28,184,177,157,195, 63,188,147,156, 60,121,210,235,136, 75, 87,193,132,110,228,213,185,254,216, 11,121, 13, 93, 62, 78, 30, 39,
+239, 31, 45,239,207,119,174,120, 61,176,244,255,164, 19,238,181,188,227,139,188,151, 23,182,252,110,121, 76,253, 41, 20, 10,137,
+209,104,196,165, 75,151, 84, 6,131, 1, 2,129, 0, 5, 5, 5,120, 41,160, 51,246,100,102,162,242,241,142,136,136,136,144,242,
+249,124,102, 93,123,163,181,175, 66,161,120, 12, 64,235,179,103,207,238,108,223,190, 61, 79,163,209,136,219,183,111,191,212,215,
+215,119,173, 92, 46,191, 6, 0, 9, 9, 9,188,132,132, 4,115,109,242, 18, 18, 18,154,218,188, 5,250,216,216, 88, 10, 0,139,
+255,253,228, 55,242, 39,243,167,111,204, 12,189, 36,104, 61, 42,162, 73,211,102, 21, 0, 40,165, 84, 0, 32, 48, 33, 33,225, 42,
+247,190, 61,216,242,238,181,150,200,118,211, 23, 79, 83,224,122,156, 50,119,101,228, 83, 18, 65, 80,128, 42, 55,251,162,244, 81,
+159, 38, 88,112,230,160,250, 65,210,178,234,200, 71,206, 45,113,105,100,140, 29, 59, 86,178,107,215, 46, 85,252, 59,214,243,223,
+ 14, 61,137,131, 7, 15,178,106,151,127, 77,123, 69,194, 35, 68,149,117,225, 2,180, 90, 45, 58,117,234,132, 38, 77,155, 98,107,
+210, 22,214,237, 58,126,252,248, 26, 47,110, 82, 82, 82,157,123, 41,216,178, 43,122,213,111,152,141,154, 40,165,245,235,119, 50,
+ 77,205, 87, 85, 25,228,189,172,176,213, 64,200, 43,214,227,188,245,192,241, 5,245,111,212,241,183,107,150, 47,169, 37,171,175,
+ 41, 20, 10,170,211,233,164, 91,183,110, 85,229,229,229, 65, 38,108,129,182, 29, 91,161, 74, 87, 9, 95,189, 9, 67,222,124, 13,
+195,198, 77,196,142,239, 18,176,125,255,126,213,168, 81,163,164, 15, 64, 23,206, 54,155,205,237,242,242,242, 44,125,251,246, 21,
+133,134,134,226,196,137, 19,239, 84, 85, 85,141, 85, 40, 20,209,114,185, 92, 19, 27, 27,107,169,107, 73, 88,108,108,108,185,227,
+249, 87, 95,125,197,219,253, 83, 92,183, 14, 51,250,227,237, 65,189, 90, 29,221,251,223,196, 45,167, 37, 39,187,245, 30,190,156,
+ 16,162,145,203,229, 5,253,250,245,179,216,148, 6,206,211,240, 15,115, 19,121,170,105,176,202, 54,230, 13,249,127, 29,245,172,
+ 36,178, 85, 7, 21, 1, 69, 78, 69, 9,218,181,239,172, 50, 90,204, 88,212,103, 48,138, 58,181,146,126,183,227,119, 86,138, 64,
+204, 36,208, 30, 93,153, 51, 62,182,238,181,224,208, 49,138,152, 73, 64,143,174,192,130,101,245, 35,110,102,131,146,250,102, 39,
+115,165, 76, 52,148,220,250,128, 82, 74,177,132,128,124, 84,231, 51,192, 18,130, 9,231,101, 15,204, 90,235, 59,228, 79,109,228,
+ 63, 12,135, 15, 31,102,245,221,180,163, 47, 82,147,177, 7,148,202,235, 72, 79,179, 38,172,201,190,144, 5, 0,216,185,147,208,
+172,139,227,165, 11,230,178,107,151,145, 35, 71, 90,246,237,219,199, 75, 74, 74,194,129, 3, 7,106, 36,195,113,134,151, 41, 84,
+237,205,228,162, 35, 83,234,133, 66,193,164, 11,175,119,206,130,144, 87,236, 27,237,172, 94,189,186, 97, 20, 0,135,122,178,237,
+ 78,200, 10,185,185,185, 80, 39, 38,170, 62,138,158,128,126, 83,102, 65,212, 38, 16, 16,216,146,253, 89, 40, 96, 17,194, 82, 77,
+ 49,230,149, 24,228,127,190, 2, 71,142, 28, 81, 41, 20,138, 26,233,110, 27, 1,102, 30,143,215,186,101,203,150, 80,171,213,130,
+190,125,251, 98,208,160, 65,188, 27, 55,110,244, 63,117,234,212, 25,133, 66, 49, 64, 46,151,223,176,145, 53,143,101,221, 53, 25,
+ 49,124,100,200,242, 85,219,120,113,211, 78, 55,139, 24, 61, 83, 26, 17,158,252,228,155, 95, 20, 60, 19,250,196,203, 97, 0,202,
+ 97,141, 49,224,213,198, 15,142,137,173,220,245,163,122, 43,164, 28,156, 61, 9,238,188, 5,246, 99, 79,130, 0, 41,211,184,253,
+ 94,238, 3,133, 66,193,243,128, 8,157, 55,169,160, 97, 97, 97, 8, 11, 11,243, 58, 79,188, 98,114,140,100,114,255, 72, 85,247,
+118,193,232,218, 46, 24,143,183,106,143, 96,223, 38, 16, 91,128, 46, 62, 77, 16,144,115, 77, 53,253,153,231, 36,108,100,245,232,
+ 10, 92,200,229,225,252, 69, 63,156,201,109,134,231, 71,250, 99,213,187,124,244,232, 74, 26,204, 72,175, 47, 73, 51,219,156,134,
+132,132,168, 50, 51, 51,145,153,153,137, 15,127, 58,133, 71,199,196,169, 0, 80, 15,183, 60,165,108, 63, 50,153,204,253, 91,188,
+196, 90, 71, 97, 97, 97,144,201,100, 46, 63,204, 51,158, 98, 92,223, 15, 36,142,229, 25,219,103,137,164, 33,218, 99,236,216,177,
+146,157, 59,119,170, 8, 33,120,227, 19,130,223, 14, 13,195,161, 67,135, 88,125, 55, 49,113,138, 36, 34, 60, 22, 67,135, 94,199,
+231,159,127, 94,227,222,228,201,192,152, 49,192,252, 57, 73,170, 85,159,177,107, 19,134,252,213,106, 53,120, 60, 30, 38, 78,156,
+ 8, 62,159, 95, 31,178,191,203,242,119, 53, 32, 19,226, 29,249, 55, 24,194, 86, 1, 0,214,172, 89,131, 53,107,214, 88,175, 13,
+136,111,180,226, 28, 56,112, 0, 95,189, 16,131,129,207,201, 32,104, 17, 4, 34,228,131, 39,228,131, 47, 22,129,231, 43, 6, 64,
+ 65,205, 38, 80,131, 1,175,189, 50, 11,101,251, 51,145,155,155,171, 82, 40, 20, 18, 52, 30, 72,102,102,102,100,199,142, 29, 69,
+ 22,139, 5, 41, 41, 41,216,182,109, 27, 2, 2, 2, 16, 25, 25,217,110,243,230,205, 31,219,158, 99, 21, 16,168, 80, 40,248,135,
+247,255,242,191, 71,252, 10,218,232,202,249,152,188,164, 2, 95,254,247, 51,160,105,111,193,127,227, 90,119,201, 61,241,243,100,
+ 7,238,224,213,162, 24, 18, 7, 82, 39,214,203,196,126,236,120,253, 30,237,133,193,161,129, 61, 0,246, 86,218,184,251,231,146,
+174,143,118,109, 46,255,232, 53,139,135,236, 72,194,194,194, 40,147,150,212, 33, 61, 41,245, 52,109,167,226,133, 87, 36, 79,117,
+124, 84, 37,170, 50,193,247,191,111,193,164, 55, 64,252,198, 50, 4,136,196,168, 18, 86, 66, 87, 85, 9, 95, 16, 84, 95, 45, 82,
+125,250,233,167,210,183,223,126,187, 78,242,189,144, 11,172,219,100, 1,160,183,125,128, 39,159,224,225,133, 81,164,198,123, 19,
+ 51, 9, 88,183,201, 43,242,150, 42,149, 74,234,173,181,206, 88,253,153,153,153,119,234,224,176, 17,149, 6, 29, 0, 96, 68,220,
+ 62, 40, 87,142,244,200,203,144,187, 34, 23, 66,146,115,167, 35,144, 66,144,150, 61, 28,206,139,208,234,255, 94, 96,215,176, 31,
+217,243,205,147,218,210,206, 18,155,210,119,252, 56,187,118,150, 63,251,165,100,221,182,127,171,182,159,250, 0,203,231,253,134,
+112, 73, 40, 54,126,125, 8,223,238,181,110, 16, 52,243, 95, 31, 72,215,254,244,129, 87, 74, 85,252, 59,160,192, 78, 40,127, 56,
+ 11, 74, 41,154,182,126, 28,135, 14, 29,130,109,223,130, 58,203,183,234, 51,153, 68, 38,107,161, 2,190, 2,240, 27,210,211,129,
+240,240, 59,247, 63,254,248,206,241,252, 57, 73, 42, 95,191,197,210,153,175, 45,173,179,156, 12,249, 71, 69, 69,193, 98,177,224,
+203, 47,191,108, 80, 7, 13, 0, 88, 44,150,187,201,159,214,253,254,242, 38,104,107,188,252,204, 16,110,145,185,120,206,238,231,
+179, 30,244,237,123,247, 28, 59,111,162,182,134,154,111,177, 76,195,188,121,243,236,247,231,205,155,135, 53,107,214,128,215,109,
+198,157,255,106,123,222,149, 60,193, 68,215,229,115,222,201, 90, 48,145, 93,249,170,170,170,208,182, 83,103,192, 98, 0,207, 7,
+ 32, 2, 62, 76,229,165,168,202,187,132, 91, 5,133,232, 48, 88, 2, 34,106, 14, 98, 52, 0,124, 30, 86,206,124, 19, 35,215,125,
+128, 5, 11, 22, 52,244,184,204,138, 21, 21, 10, 5,161,148, 54,175,172,172, 28, 28, 20, 20,132,172,172, 44, 88, 44, 22, 92,186,
+116, 9,235,215,175, 71,207,158, 61, 17, 28, 28,252, 50,128,215,156,200,186, 86,111, 0,165,180,101, 39, 94,186,164,221, 35,163,
+ 69, 37, 41,167, 81,170,245,193,143, 59, 76,216,117,244, 39,204,145,249, 10, 4,122, 75,152, 45,166,192,165, 2,192, 17,122,227,
+163,182,233, 30, 87,158, 1, 30,139,142,200,204, 27, 66,178,104, 24,214,165, 40,154,231, 94,204,197,201, 31, 78, 67,161, 80,120,
+100, 61, 48,228,160,215,255, 12,189,126, 35, 52,154,104,198, 58,246,232, 7, 14,242,105,166,106, 93,101,134,120,201, 44,152,111,
+107, 96,186,120, 25, 2,145, 16,126,132, 15,127,194,135, 63, 95,128, 32,161, 24,180, 92,135,235, 7,142,184,221,233,197, 21,169,
+ 31, 58,102,177,191,135,171,222, 37,136, 95, 76,108, 30, 1,239,172,127, 27, 57,171,224, 69, 10, 92,103,242,135,128,143,188,235,
+ 21,184, 94,108, 64,250, 57,235, 6, 34,221,166,109,135, 39,251,158, 11, 73, 14, 4,164, 16, 62,188, 83,214,191,173, 9, 2, 39,
+ 95, 67,192,164, 51,240,121,126, 9, 16,236,239,153, 39,151,197,206,109,158,108,241,170,216,246,186, 42, 34,232, 93, 28, 63,120,
+ 9,255,111,252, 56, 4,183,236,142, 89,255,126, 21, 95, 44,222,139,136,192,197, 88,251,211,135, 94,239,224, 67, 8, 16,187,224,
+140,221, 98, 25, 58,116,168,141,144, 44,110, 27,120,202, 36,161, 10, 56, 0,224, 55,148,220,108,130,110,143, 52,193, 55,223, 88,
+ 45,255, 37, 75,128,144, 16,171,136,146,155, 77, 80,114,179, 9,250,245, 57,175,114, 71,254, 7, 14, 28,128,197, 98,177,147,244,
+230,205,155, 97, 54,155, 61,114, 95,215,225,225,185,139,252,173,239,179,123,229,157, 2,100,173, 66, 33,101, 44, 53, 11,165,176,
+ 88,238,238,190,204,117, 11,165, 88,155,144, 32, 77,176,126,199,229,255,164, 0,161, 20, 36, 33, 65, 33,165,148,226,179,207, 62,
+179,223,103,142, 19, 18, 18,164,148, 90,159,163, 0,169, 77, 94,130, 66, 1,219, 61, 98, 54,155, 97, 50,155, 97, 50,221, 93,103,
+204,117,147,217,140,175,215,174,149,174, 77, 72,168,165,124, 20,130,166, 77, 1, 33, 31,102,125, 5,206,110, 73,194,251,175,202,
+209,225,117, 57,250,175,248, 8,151,254, 60, 1,190,175, 24,198,226,155, 56,125, 84,141,237,135,246,160,244,198, 13,156, 57,115,
+166,193, 54,214,138,140,140,100,229, 77, 80, 40, 20, 1,148,210, 65,153,153,153,191,191,247,222,123,189,206,158, 61, 43, 50, 24,
+ 12,224,243,249,104,218,180, 41, 76, 38, 19, 50, 50, 50, 64, 8, 17,185, 27,235, 19, 18, 18,252, 21, 10,133,111, 66, 66, 66,112,
+ 73, 65,234,159, 31,254, 47, 63,232,175, 67, 59,160,209,241, 32, 18,240,208, 33, 80,140,210,219, 34,200, 63, 53,225,244,237,254,
+254,238,120,195, 22,107, 66, 29,251,162, 77, 49,184,235, 58, 71,215,247, 7, 12,249, 59, 43, 7, 60,119, 90, 40,179,223,119, 13,
+ 55,231,232, 41,158,123,251,108,238,126,189,126, 35, 0,130,170,170,239, 33, 62,118, 25,250, 61,143,214,184,239, 14,111, 15,136,
+146, 4,104,202, 97, 17, 9, 96, 56,126, 22,213,231,243, 80,181,247, 16, 80, 89, 13, 17,165,240, 3, 31, 2, 16, 84, 91, 76,208,
+ 84, 87,225,235,125, 59,220,202, 92,245,174,213,186,119,132,245,156, 49, 87, 40,178, 46, 82, 44, 88,230,125,127,117,202, 87,206,
+218,101, 47,147,201,236,123,107, 51,120,105, 77, 1,246, 31,215, 34,255,102, 21, 0, 32,255,102, 21,114, 10, 42,129,232, 68,102,
+ 99, 20,247,174, 31, 82,104, 85, 4,202, 79,195,223,255, 34,124,196,229,176, 88, 52, 48, 26,143,131,207, 15,129, 65, 87,220,104,
+157,117,194,232,127, 75, 0,130, 47,127,155,129, 38,188, 71, 0, 0,215,179, 40, 6,140,227,227,223, 75, 71, 98,232,200, 94, 0,
+168,237, 57,207, 16, 21, 21, 69,223,248,132,160, 73,171, 62,160, 0, 70,191, 48,147,245,188,255,218,111, 22,211,214,173,255, 2,
+112, 6, 37, 55,155,160,188,216,186, 5,115,223,190, 64,183,110,192,203, 47,223, 33,255,242, 98, 95,148, 23,251, 34,200,239,122,
+157, 50,199,143, 31, 15,169, 84,138,225,195,135,215,112,253, 59,126,188,153, 18,112,245,222,122,131, 88,135,249,109, 66,136,253,
+ 83,219,181, 88,185, 92, 45,143,113, 63, 39, 30, 19, 19,163,114,101, 57,207,155, 55, 15, 49, 49, 49, 53, 8,181, 54,121,191, 41,
+ 20, 56,115,230,140,221, 5,239, 88,103, 12,156,175,205,140,141, 85,199,202, 93,111,213, 44,162, 20, 60, 63, 31, 24,111, 92,129,
+ 98,241, 98,172,215,149, 64, 27, 21, 97,191,255,221, 79,235,241,193,155,175, 34,116,193, 75,248,232,244, 1, 36,106, 47, 97,228,
+179,207, 34, 36, 36,196,227, 96, 64, 27,209,211,240,240,240, 26,125,248,232,209,163,170,186,182, 99, 87, 40, 20, 66,133, 66, 49,
+240,244,233,211,249, 41, 41, 41,234, 55,222,120, 35,226,203, 47,191, 20, 87, 84, 84,216,183,105,174,170,170, 66,147, 38, 77,114,
+ 38, 76,152,208,125,200,144, 33,143,184, 81, 36,120,132,144, 78,167,211,182, 20,101,239, 89,112,121,193,162,248,118,219,151,180,
+199,249, 66, 1, 74, 43,248,176, 16,160,184,194, 0,218,162,107,213,252,119,150,245,122,230,249,127,189, 6, 55,241, 4, 54,247,
+127, 13, 87,191,155, 99, 14,141, 64,254,181, 77, 1, 80,182,174, 28,185, 92,238,238, 33,234,108,253, 91, 93,109,223,215,230, 29,
+112,251, 79,123,181,108,163,210, 80, 35, 68,197, 26,136,127, 59, 0, 34,224, 1, 85, 6,208,114, 29,136,201, 4, 33, 0, 51,181,
+160,202,108, 66,185,201, 0, 88,220, 91, 81, 76,144,223,170,119,107,213,105, 97, 13, 18,108, 16,133,149, 56, 4,242,185,125, 1,
+238,178,254, 1,252,242,122,187, 26,231, 3, 23,230, 65, 72,111,195, 72, 90, 66,169, 84, 30, 96,251, 98,137, 43, 84, 8,250,232,
+ 39,220,122, 35, 22,183, 53,190,104,111, 60, 11,179, 57, 15, 0,112,229,100,219, 70,235,176,137,187,191, 80,189, 58, 74, 81,131,
+252, 25, 68, 4, 46,198,224, 94,227, 17, 25,116, 22,137,187,151,170, 60, 25, 68,134, 13, 27, 70, 83, 82, 82, 80, 92, 60, 2, 45,
+ 90,236, 71,147,150,189, 65, 41, 5,143,199, 99, 21,136,148,159, 15,228,229,157,177,157, 85, 0,226, 10,104,116,192,160, 65,214,
+ 43, 57, 57,192, 87, 95, 1,229,101,128,174, 2,168,208, 1,254,129,101,172,202, 86,155,181,159,155,155, 11, 0,248,228,147, 79,
+ 0, 0,161,161,161,247,194,205,204,170, 14,231,206,157, 91,195, 98,119, 38,110,214,222, 29, 27, 97,219,231,253, 29,240,217,103,
+159, 97,205,154, 53, 80, 40, 20, 18,119,193,117, 51,130, 67,145,125,246, 28, 10, 3, 3, 85, 60, 30, 15,115,230,204,185, 43, 38,
+195,147,242, 61, 89,221, 28,212, 82,129, 87, 63,121, 23,125,198,143,135,226,147, 79,192,227,221,225, 57, 69,206,153, 59, 30,194,
+ 67,135,176,111,223, 62, 92,186,116, 73, 42,151,203,213,108, 54, 94,113, 36,255,180,180, 52, 21, 0,100,100,100,168, 34, 35, 35,
+165,105,105,105,234,240,240,112, 73,122,122, 58, 34, 35, 35,165,149,149,149,170, 90,198, 92,227,180,105,211,250, 76,153, 50,165,
+ 89,151, 46, 93,176,107,215, 46,125,105,105,169,160,178,178,210,234,237,176,205,127,108,221,186, 53,116,244,232,209,190,114,185,
+188,210,133, 24,158, 3, 89,243,242,178, 78,174,249,224,237,233, 77, 90,116, 83,226, 79,229, 43,248,235, 42, 65,254, 77, 1, 64,
+121,168, 54, 24,161,161, 45, 10,103,207,152, 21, 65, 8, 41,100,198,124, 79,126,175, 11, 15, 1, 55, 85,240,128,160, 86, 45, 46,
+ 37, 37,229,174, 79, 73,161, 22, 37,133, 90,143,218,154,249,220,177, 98,173, 13, 47, 62,118, 25, 62,103, 10, 33, 40,208, 50, 30,
+128, 26,207,215, 38,240, 92, 65, 62,142,221,190,134,179,151,242,112,243,210,101,148, 93, 46, 64,249,213, 66,152,244,149, 48, 26,
+ 77, 40, 55, 27,160, 55,155, 80, 77,205, 48,131,130, 18,246, 74,166, 99,180,255,133, 92,235,249,130,101,140,229,207, 67,252,187,
+ 13,179,226,197,211, 56,128, 56,165, 22,113, 74,109, 13,194,103, 62,145,113, 25, 16,210,219, 16, 80, 45,126,153, 97, 54,177,158,
+ 2,184,121, 12,102, 93, 19, 0,192,127, 5, 1,168,190,121, 5,153,159,182, 67,246,207, 99,113,236,211,126,200,201,186,214,168,
+ 29,179,239,160, 16,232,180,128, 78, 11,232,125,207, 1, 0,126,253,208,136,183,231, 45, 1, 0, 12,137,238,229,177,229,255,194,
+176,131,208,104,162, 17,120,116, 63, 86,191,107, 85,114,135, 13, 27,198,202,245, 15, 0,203, 63, 94, 74,186,118, 5, 28, 63, 23,
+ 46, 88,221,255, 0,208,173, 27,197,154, 53, 64,167,238, 21,120, 44,226, 22, 6,141,184,133,231, 95, 50,178, 46,163,163,197,207,
+156,135,134,134, 34, 52, 52, 20,115,230,204,105,232, 42,118,251,174, 57, 98,221,186,117, 82, 87,132,109,247,162,173, 90,133,117,
+235,214,177,178,132, 95,123,237, 53, 21, 19,249,239, 10,243,231,207,191,203, 11,224, 10, 7,207,229, 99,250,140,217, 56,190,113,
+ 35, 22, 45, 90, 84,171,114,194,148,111,255,254,253,168, 43, 96,111,216, 99,143,224,251,239,190, 66,216,228,201, 88,190,124, 57,
+234, 42,227,188,121,243, 48, 98,196, 8,120,179, 2, 32, 45, 45, 77,229, 16, 44,135,163, 71,143,170, 0, 32, 61, 61, 93, 69, 8,
+ 65, 90, 90, 90,157, 50,245,122,125,243, 29, 59,118,224,220,185,115,200,201,201,241,211,233,116, 48, 26,173,253,204, 96, 48, 96,
+247,238,221,196,166, 44, 84,178, 40,142,165,186,186, 90,116,124,203,100, 84,101,127,129, 61, 41,185,184,116,157,143, 50, 29, 15,
+102, 10, 20,234,124, 49,123,193,187,145,177,177,177, 5, 44, 12, 62,187, 94,193, 44, 57,101, 57, 29,192,161, 17,172,255,218, 20,
+ 0, 2,128, 72, 36, 18, 72, 36, 18,156, 58,117,202,254,201, 59,118, 5,165,149,165,104, 49,200,243,117,191,199,143, 31, 39, 0,
+224,231, 55, 5,226, 99,151, 33,188, 82, 12, 74, 8, 68, 51,138,107,220,119, 75, 92, 34, 62,204, 20, 40,208,149, 32,191, 84,131,
+ 91,101, 90,148, 86, 85, 65,107,168,196,173,234, 74, 92,175,210,163,176,170, 2, 26, 99, 53,180, 22, 35, 12, 22,247,193,175, 79,
+ 62,225, 98,192,115,136, 11,120,117, 98, 19, 80,136, 64, 61,222, 6,252, 78,244,190,139,107,172,145,127,179, 10,251,143,107, 49,
+112, 97, 94,205,186,160,183,225, 99,185, 2, 31,203, 21,124,240,148, 0,249,249,249, 6,182, 50,183, 92,178,160, 85,124,130,253,
+252,146,206,140,130,220, 66,100,165,158,197,141,203, 37,141,222,113, 55,126,157, 2, 0, 40, 43,162,240,171,124, 12,146, 25, 2,
+252,191, 37, 66,251, 39, 62,113, 50, 8,123,227,159, 62, 55, 52, 5,175, 44,176,146, 63, 33, 4,191,167, 90,155,128,237,154,127,
+ 6,161, 61,186,215, 44,231, 70,224,203, 47,129,139, 23,173,158,128, 15, 63,164,118,247, 59,165, 20,129,129,129,238, 71, 96, 91,
+ 31,101,230,253, 63,249,228, 19,228,230,230, 34, 59, 59, 27,217,217,217, 72, 78, 78,198,155,111,190,137,252,252,252, 70,107, 15,
+134,232, 92, 89,210,115,231,206, 5, 33,132, 53, 25, 18, 66, 80,151, 50, 81,215, 61, 71, 28,242, 41, 1,225, 53,193,183,239, 44,
+ 67,147, 29,201,136,137,137,193,100, 70, 27, 3, 32,239,214, 27,115,195, 6,195,207,207, 15,195,134, 13,195,123,239,189,135,228,
+228,100,213,242,229,203, 93,190,127,223, 21,102,227,122,175,199, 16, 28, 28, 44,181, 88, 44,117, 42, 20,117,221, 99, 65,142,118,
+143, 83,100,100,164,212,129, 40, 17, 17, 17, 33,117,227, 61, 25, 62,108,216,176,102,249,249,249, 56,116,232, 16, 30,125,244, 81,
+ 8, 4, 2,251, 20, 71,112,112, 48,219,233, 8,139,237,255,146,174, 61,250,199,173,219,219, 28,127,237, 90,130, 39, 35,123,194,
+ 95,204,131,191,159, 25,190, 62,213,120,250,185, 9, 22, 0, 26,199, 47, 38, 36, 36,184,155,139,178,175, 2, 96, 57, 29,192,225,
+ 65,243, 0, 0, 32, 10,133,162,233,220,185,115, 49,119,238, 92, 0, 48,124, 28,251, 49,140, 69, 38,248,250,138,225, 77,227,201,
+100,214,240, 97,191,167, 46,130,242,121,120,239, 87,189,163,245,207, 10,126,193,193, 82, 83, 19, 63,104,169, 25,231,116, 90,156,
+ 41, 45,198,217,178,219, 56, 91,166,193, 57,157, 6, 23,245, 90, 20, 87, 87,161,194,100,194, 53,189,206,254, 63,235,194, 11,163,
+ 8, 86,189,203,199,170,119,249,160,224,131, 18, 30, 98, 38, 17,188, 54, 73,132, 25, 19, 91,161,107,215, 54,176, 64,232,241, 79,
+102, 92,253,142,243,242,117, 36, 5,170, 77,134, 52,167,192,170,200,103,174,176, 6,209,237,121, 43, 0, 0, 32,160, 90,240,169,
+ 14,213, 60,107, 68,179, 70,163,241,147,201,100,209,158,148, 49, 44, 44, 12,201,201,201,216, 88,161, 67,165,129,135, 87, 54,125,
+139, 34,177, 47, 42, 13,141,183, 77,196,184,190, 31, 72,211, 52,203,176,241,199, 68,251,181, 95, 63, 52, 34, 34,112,177,253, 60,
+230,153,175,164, 20,172,214, 15,211,213,139,129,105, 11, 70,160,249,209,100, 72, 63,141, 2,111, 44,160, 86,171,189,234,195,157,
+ 58,213,140, 30, 31, 62, 28,104,222, 28, 8, 9, 1,194,251, 54,133, 88,196, 7,159,119, 71,172,216,215,215,237,128,204,227,241,
+236,150,127,110,110,174,221,234,103, 62, 31,125,244, 17, 62,250,232, 35, 92,187,198,222, 43,227,106,190,190,230,125,207,173,175,
+117,235,214, 73, 87,175, 94,237,146,176,217, 90,255, 14,174,231,187,226, 20,152,115,139,133, 93, 10,123, 3, 33,176,232,171, 33,
+108,219, 9,242,165, 75, 49,205,191, 57,154,171,211,236,247,103,252,107, 26, 62,248,239,183,200, 89,245, 11,222,239, 51, 28, 19,
+ 2,187, 96,223,182,109,200,203,203,115,249,254, 61, 31, 43, 71,175,222,189,165, 22, 91,153, 24,133,204,113,122,198,213,181,218,
+ 48,115,230, 76, 74, 8,161, 76, 96, 31, 51,223,239, 72,242,105,105,105,234,136,136, 8, 41,165, 20,204, 84,128,155,122, 75, 17,
+ 10,133,143, 62,255,252,243,185,165,165,165,208,106,181,240,245,245, 69,171, 86,173,208,188,121,115, 52,111,222,220, 93,229, 89,
+156, 20, 59,179,143,143,143,254,197,216,207,165,235,143, 13,196,229,171,101,104, 19,192, 71,100,119,130,199,187, 80,248, 55,107,
+ 86, 2,192, 92, 7,111,112,251, 13, 60,164,214, 63,224,102, 25,160, 92, 46,175, 80, 40, 20, 62, 0,252,229,114,185, 93, 11,236,
+ 16,213,222, 43,205,151, 89,234, 39,147,201,168,104,134, 61,242,159, 56,204,255,187, 29,144,223,217,153,168,254, 36,250, 57,232,
+ 77,213, 40,211,233,145,107, 52, 66,104,177,126,185,212, 88, 5, 11,165,160, 0,118,221,188, 4,157,201, 8, 0, 44, 6, 38,130,
+ 5,203,106,246,113,107, 60,128, 5,102, 84,227,252,197,114,124,191,185,204,163, 31,235, 72,244, 54,151, 63,181, 29,219,137,157,
+205,234, 7,235,119,149, 16,142,248, 26, 64, 8,138,139,239, 4,231,137, 44,215, 97,224,181,195,236, 62,217,184,126,221,110, 57,
+237,103, 83,190,216, 95,215,213, 80,188,148, 74, 37,152,210,108, 58,125, 4,209,209,209,141,214,113,183,159,178, 46,239, 75, 77,
+ 62, 11, 0, 24,220,203,154, 25,239,237,121, 75,112,228,108, 47,252, 55,113, 50, 20, 59,102,177,158,255,127,101, 65, 52,130,130,
+146,109,103,106,155,178, 20, 13, 74,173,214, 24, 64, 17, 20,148,204, 74,214,190, 61,123,237, 57, 45, 38, 79, 6,164, 82,130,219,
+ 87, 3,160,211,138, 81, 89, 38,194,166, 13, 4,115,231, 82, 92, 41, 42, 71,120,100, 4, 82, 14,168, 88, 89,197,102,179,217, 62,
+223,159,156,108, 45,171, 35,225, 23, 21, 21,161,168,168,136, 53,255, 59, 16, 6,229,241,120,119,145, 42,165, 32,158, 38, 1,146,
+203,229,234,215, 94,123,173, 70, 44, 0,227, 17,240,196, 21, 78, 28,180, 18,139,211,178, 2, 66,216,207,217, 17, 66, 96, 42, 47,
+135,176,101, 16,248,126, 77,208,235,197,241,248,104,212, 72,188,195, 44,219,235, 63, 0,230,202, 42, 8, 91,180, 65,159, 8, 9,
+ 58,119,232,130,207,207,167,161,119,239,222,210, 99,199,142,221,165, 4,196,202,229, 0,136, 10, 0,102,197,198,218,151, 14,154,
+156,200, 94, 32,224, 3,244,206, 66,197,218, 10,188,118,237, 90, 2,128,218, 92,252, 36, 35, 35,195,165,139, 63, 45, 45, 77,205,
+134,252, 19, 18, 18, 8, 33,100,113,243,230,205,123, 69, 68, 68,116,189,112,225, 2, 78,156, 56, 1,179,217, 12,127,127,127,232,
+245,250,162,160,160,160,203,158, 24,125, 10,133,130,215,166, 77,155,125,207, 61,247, 92,155,163,135, 51,176, 70,185, 15,205,136,
+ 8,221,219, 84,227,226,109,127, 12,237,110,188, 4,192,121, 30,203, 92, 87,155, 56,102,156, 34,132, 56,158, 58,231,125,225,208,
+200, 16,176,120,233, 13, 0, 12, 14,131, 10, 45, 72,241,120,126,184, 6,185,215, 66,124,172, 51, 6,150,105,180, 82,163,159, 88,
+ 85,202,179,224, 70, 85, 5, 96, 52,194,108, 91,215,116,190,162, 4,133,250, 50, 80, 74, 97,203, 47,160,102, 83,188,152, 73, 4,
+235, 54,221,233,147, 23,114,129, 30, 93, 77,224, 67, 87, 47,242,119,234,236,238,234,160, 86, 47,128, 82, 57, 75, 5,100, 66,163,
+209, 24,242,243,243, 5, 43, 71,130, 23,183,111, 24,230,245, 62, 98,183,194,216, 42, 21,174,188, 46,206,231, 12, 9,177,181,230,
+176,132, 96,160,109, 37,135,171,229,126,137,137,137,214, 76,128, 50, 25,101,147,243, 33,118,220,215, 82,197,246,217,170,180, 68,
+138,200,160,179, 24, 18,221, 11,135,247,157,197, 81,237, 82, 16, 16,200,199,125, 37, 77,216, 62,155, 85,249,130,130,146, 65, 8,
+193, 11, 47,188,128,111,190, 41, 3, 67, 49,214,191,148, 81, 8,104, 77,203,254,118,173,242,162,134, 75,165, 41, 7, 84,170,225,
+195, 1,195,141,142,184, 90,226, 3,139,109,182,181,157,174, 13,222,138, 41,199,190,163,221,209,180, 67,119, 41,147, 37,176, 46,
+ 48,196, 95, 80, 80, 0, 0,184,113,227,134,221, 51,112,243,230, 77,251,192,234, 37,136,131,219,217,249,165, 36,108,242, 1, 56,
+226,155,111,190,145,174, 89,179, 70,197, 40, 0,171, 87,175,246,216,250,119, 38, 12,111, 33, 22,139,113,227,202,101,116,233,218,
+ 13, 22, 83, 53,136,201, 12, 65,211,102,104, 58, 96, 32,154,244,127, 2, 22,157, 9,102,125, 53,168,201, 12,152, 45,136, 91,251,
+ 95, 76,156, 60, 17, 98,177,216,165, 60,211,166, 64, 86,255,215,213,115, 97,203, 93, 63, 27, 25, 25, 41,181, 41, 0,148, 82,138,
+ 33, 67,134, 72, 83, 83, 83,239,122,206, 29,249,219,234,202, 2, 96,119,247,238,221,251,127,241,197, 23,134, 91,183,110, 85,141,
+ 28, 57,242,185,204,204,204,247,245,122,125,113,203,150, 45,229,159,127,254,185,134,109,253, 41, 20, 10, 33,128, 71, 34,194,195,
+ 91,197,206,136,197,165,130, 75,154,169, 51, 98,159, 76,223,183, 33,254,122,185,102,240,192,168,145,150, 54, 29, 66,255,159,179,
+149, 95, 87,106, 97, 91, 31, 35, 14,250, 39,113,193, 1,206,199, 28, 30, 84, 5,160, 46,235,194, 27,242,103,200,166,150,132, 49,
+172,148,128, 21, 39, 14,170, 1,144, 73, 3, 34, 41,124,197,208, 82, 19, 12, 38, 19, 44,212,130, 22, 1, 1, 40,208,149,194,147,
+228, 66,174,150,247,221,137, 1,240,108, 45,182, 43, 23,127,125,211,245,218,242, 8,140, 27, 56,112,224,246,184,184, 56, 81, 80,
+ 80,144,229,250,245,235,152,215,251,186, 51,249,179,254, 31,181, 37,236,241, 10,182, 44,127, 46,146, 60,221,245, 12, 91, 36,108,
+159,165, 6, 64,198,246, 89, 34,217,121,250, 67, 85, 90, 34, 64, 64, 48,174,239, 7,210,237,167, 62, 80,179, 37,127,166, 47, 21,
+ 23,143,160, 64, 25, 99,253,194, 21,239,172,143,223,207,244, 7, 82,215,230, 26, 54,171,158, 20,107,123, 75,204,229,229, 42,194,
+ 7,244, 85,190, 32,229, 38, 8,120, 2,232,121, 98,233,168, 9,175, 98,118, 76,172,219,246, 72, 74, 74, 34, 73, 73, 73,244, 30,
+190,127,160,148, 18, 66, 8,117,140,104,119,244, 4,120, 34, 75, 46,151,171, 99, 98, 98, 48,111,222, 60,187, 66,209, 88,169,112,
+135, 15, 31,142,217,137,235,240, 81,121, 9,250, 69, 13, 5,175, 77,160,181, 76, 70,106, 77,221, 11, 33, 8, 95, 0, 34,226,227,
+155,132, 85,104, 54, 98, 32,186,118,237,234,113,212,126,125,224, 96,221,171,194,195,195,165,169,169,169,245,170,171,220,220,220,
+232,253,251,247, 95,225,243,249,219,158,124,242,201,143,103,205,154,117,107,237,218,181, 41,128,117,202,193, 3, 81, 60, 0,201,
+ 39, 78,156, 24,244,195,250, 13, 60, 17,223,231,234,248,151,198,247,157, 61,123,182,246,235,175,191, 30, 11, 32,192, 70,252,229,
+204, 6, 65,108, 60, 10, 28, 30, 12,176,113,255,123,171, 0,212, 91, 97,112, 67, 62,172, 7,164, 77, 39,210,136,108,188, 76, 98,
+201,202, 81,233,170, 13, 48,153,205,232, 58,104, 0, 66, 77,225,158, 18,110,131, 5,163, 48, 73,127, 0,168, 24,107,220, 22, 7,
+ 80,175, 28,248, 74,165,114,135, 66,161, 16, 36, 39, 39, 47, 88,185,114,229,167, 14,202,197,112,199,255,197,214,163, 0,160,193,
+146,151, 76, 56,207,196, 89,212,254,251, 38,156,151,121,165,233,239, 60,253,161,154,105, 31, 10,138,237,167, 62,240,170,140, 86,
+114, 39,120,101,193,240, 59,102, 47,185,115,111,193, 50,207,243,145,199,189,117, 70, 29, 7,144,181,223, 44,150, 84,234,173,251,
+ 0,220,201,255, 31,235,241, 59, 98,179,200,204,114,185,188,193,231, 85, 25, 37,160, 33,100,217, 98, 1, 84,204,113, 3,148,205,
+171,239,117,237,218, 21,109,231,204,145,174,217,187, 87,149,247,241,111,144, 9, 91,160,185,109,243,158, 74,189, 9,115,223, 92,
+ 4,190, 95, 16,118,109, 80,224, 84, 75,130, 81,131, 7,123,157,183,223,108, 54,121, 61, 76,176,117,241,179, 80,190,200,243,207,
+ 63,127,139, 82, 26,223,163, 71,143,255, 21, 23, 23,235,188, 32,126,199,122, 31,150,145,145, 1,139,137, 96,240,144,190, 31,204,
+158, 61, 91, 11, 0,179,102,205,178, 0,208,214,167, 73, 29, 60, 78, 53,142, 93,120, 69, 57, 60,100, 30,128,123,162, 20,120, 77,
+140, 73, 53, 18,236, 32, 35, 55,171,209, 43,213, 41,233, 15,115,173,222,114,229,114,185, 25,192,127,108, 31,175,229,186, 42, 95,
+ 61,127, 47,105,136,103,238, 37,172, 4, 79,177, 96, 89,114,131,203,118,151,234,215,131,246, 53,222,203, 58,104,168, 77, 87,228,
+114,185, 90, 46,151, 55,136, 44, 82,143, 57, 0,166, 12, 10,133, 2,182,237,123,145,239,176,125,111,234,254,125,246,237,123, 71,
+ 68,140,128, 77,233,173,245,255,241, 39,106,137,121,115,224,221,196,196,114, 55, 65,119, 74, 64, 67,212,215, 19, 79, 60, 81,109,
+ 50,153, 82, 0,232,222,123,239,189,122,145,104,108,108, 44,121,239,189,247,168,193, 96, 0,128,189,181, 61,183, 98,197, 10,178,
+112,225, 66,251,255,178,165, 2,174,115,108,119, 14,238,228,112,127,193,214,195, 69,188,221, 71,152, 3, 7, 14, 28, 56, 52, 10,
+ 76, 0,170, 0,136, 27,216,136,115,183, 99, 32,235, 29, 5, 57, 60, 28,224, 26,147, 3, 7, 14, 28, 30, 46, 8, 0, 52, 97, 65,
+254,122, 88, 3,184, 27,138, 15, 44,224,150,253,253,237, 58, 18, 7, 14, 28, 56,112,248,251,193,143,227, 11, 14,156, 7,128, 3,
+ 7, 14, 28, 56,112,224,192, 41, 0, 28, 56,112,224,192,129,195, 63, 29, 53, 92, 58, 39, 79,158,244, 58, 34,215, 85, 48,225,131,
+ 46, 47,100,128, 15,124,125,110, 64, 40, 42,129,197, 98, 93, 22,198,231,243,192, 35,124,235, 95, 30, 1, 33, 60, 80, 34, 0, 33,
+ 4, 60,152,176,125,167, 16,148, 82, 4,241, 90,192,147,242,217, 50, 42,182,132, 53,128,167, 28,214, 4, 3, 70,102,201,215,195,
+ 88,127,156, 60, 78, 30, 39,143,147,199,201,123, 48,229,113, 30, 0, 55, 56,120,248, 34,180,165, 90, 24,141, 20,183,110, 19,236,
+ 73,246,197,222,125,254,224, 17, 33,246,169,218, 98,239,129,118,216,171,106,135, 67,199, 90, 65, 0, 1,120, 16, 99,104, 36, 15,
+ 62, 34, 31,214,255, 99,210, 43, 83,233,164, 87,166,210,195,169,170, 42, 35,143,164,158, 61,147,121, 80,117,228,176, 46, 57, 57,
+185, 10, 64, 83, 78, 7,125,248, 49,242,169,161,146, 89,179,166, 82, 79, 55,121,122, 88,161, 80, 40, 36,212,134,186,118,215, 99,
+ 11,234, 4,174, 71,113,224,208, 8, 30, 0, 6,131,135, 12, 98,253, 18, 30, 73,205,112,171,181, 52,180,188,134, 68, 70,166, 16,
+163, 71,154,113,234, 47, 95,136,132, 2, 8,248, 2, 8,133, 20, 62,124, 35, 32,104, 10, 1, 42, 49,168,151, 9, 98,145, 15, 40,
+128,118,109,128,103,199, 88,176,127, 27, 59,242,191,120, 62, 27,143, 62,214, 21,237,131,155,163,224,202,133, 78, 1,109,187,160,
+101,123, 51,254,248,253,119, 36, 39, 39,151,160,145,119,196,146,201,100, 99,148, 74,229, 78,135,243,103, 28,207, 57,212,142,217,
+179,100,212, 84,117, 86, 58, 40, 44, 80,101,177, 20,163,180,125,165,170, 67,219, 17,168,168,110,135,111,214,253,244,183,221,233,
+ 44, 38, 38, 70, 53,111,222, 60, 16, 66,176,122,245,106, 85, 67,228, 4, 96,210, 1,112,252,127,255,225,145,210, 69, 41, 8,143,
+ 87, 87,123, 83,199,246,100,218,244, 78,242,173,154,237,236,184, 51, 34,135,134, 5,147, 13,208,193, 75,192, 78, 1,104, 44,240,
+238, 51, 23,142, 25,101, 4, 5, 31, 2,190, 16,131,195, 9, 90,183,226, 65, 32,224,193, 71,200, 71,143, 80, 30,174, 92, 53, 97,
+ 80, 24, 15, 45,130,196,248,227, 64, 51, 0, 0,159, 86,130, 82, 11,220,165, 8,158,244,202, 84,250, 87,102, 38, 58,183,239,128,
+191,210,142, 34,221, 96,132,246,182, 22, 34,159,166,232,217,127, 8,250, 14, 25, 5,213,118, 37,100, 44,115,227,223, 3,226, 31,
+174, 84, 42,247,135,132,132, 32, 51, 51,147,233, 48, 37, 0,230, 40,149,202, 29, 50,153, 44, 90,169, 84,238,255,187,189, 20, 51,
+ 99,101,212, 71,160,129,128,103, 64, 85,149, 25,165, 58, 95,252,248,243,126,143,234,127,196,200, 33,146,102,190, 26, 12, 31, 34,
+ 66,231, 78,207,170,154, 53, 11,128,209,100,194,173, 91,183,209, 38,255, 42,114,114,243,240,202,203, 99,232,134, 31,118,121,213,
+174, 97,182, 61, 21, 0,246,219,100,223, 79,235, 31,184,179, 29,238,234,213,171,161, 80, 40, 36,141,149, 14,248, 62,190, 47,116,
+203,150, 45,119,239,167,208, 72,228,165, 80, 36, 72, 8, 8, 98, 26,160,222,105,254,175, 32,233,175, 58,114,188, 45, 75,166,125,
+223, 43, 59, 94, 77,208,185, 85,228,254,248,227, 15,251,249,232,209,163,177,123,247,238, 58,207, 57,220,123,242,119,188,230,168,
+ 8,212,169, 0,164, 30, 78,199,144,161,225,247,173,208, 22,207,178, 67, 58, 62,236,213, 75,200, 19,240,161,213, 8,208,182,181,
+ 16,109, 91,139, 80, 81, 33,132, 88, 40,128, 89,224,131, 1,125, 8,250, 61,206, 7,143, 8, 65, 8,129,143, 80, 4, 33,175, 26,
+ 68, 44,130, 73, 15,152,160,171,147,252, 15, 31,216,143, 46,237, 90,225,204,169, 51,200, 47,186,126,167,124,229, 21, 16,159, 61,
+ 70,121,124,130, 1, 97, 3,240,199,110,207, 56,118,237,218,181,146,204,204, 76,213,197,139, 23,225,235,235, 11, 95, 95, 95,233,
+214,173, 91,213, 30, 14,102, 82,165, 82,185,159, 33,126,135,206,209, 28,192,168,111,191,253,246,246,171,175,190,154, 44,147,201,
+ 70, 42,149,202,228, 7,177,131,135,135,135, 75,210,211,211, 89,255,110,201,240,193,146,222,161, 77, 85, 29,218, 21, 33,160,153,
+ 15,120, 60, 63, 84, 86,154, 80,172,169,196,100, 89, 79, 42,110, 54, 0,223,127,247, 51,171,126, 36,196, 13,188,240,204,227,170,
+ 94,189,122,226,250, 13, 45,142,255,121, 2, 21, 21, 58, 4, 4, 52, 69, 72, 72, 39,240,248, 66,152,205,249,136,157, 57,149, 38,
+172,253,241,111,101,221,196,196,196,168,230,207,159,111, 63,159, 55,111, 94,131,121, 1, 30,100, 15,128, 82,169, 36, 50,153,140,
+ 38, 37, 37,193,213,198, 74,247,219,104,151,203, 99, 65, 8,193,186,117, 10,105, 76, 76,253,148, 0, 94,167, 23,237,228,157,177,
+188,137,203,193,180,109,115, 30,130,131,120, 15,109,251,253, 83,225, 72,246,174,148, 2,183, 30,128,212,195,233, 0, 80,111, 69,
+224,240,156,156, 58,239, 15,253,188,155,215,131,133, 67,142,115,143, 6,161,100,117,107, 8, 5, 66,116,108, 95,129,242,114, 33,
+142,159,233, 8, 62,159, 15, 62,225, 67, 36, 52,161, 87, 55, 61,186,119,227,131,128, 7,145,208, 7, 34, 62, 65,216,227, 6, 4,
+ 5, 90,176,241,127,117,203,238,217,165, 13,174,228, 22,213, 36,127, 27,242,175, 93, 33,132, 39,160,237, 34, 31, 71, 96,243,166,
+ 40,209,222,102, 85,222, 53,107,214, 72, 86,172, 88,161,186,114,229,138,227,101,213,152, 49, 99,176,107, 23,123,107, 83,169, 84,
+ 30,112, 36,127, 23,104, 25, 31, 31, 95,242,198, 27,111,236, 67, 35, 79, 81,212, 65,254, 42, 79,202, 22, 26, 18,164, 10,110, 83,
+134,150, 45,252,209, 33,184, 45,252,252,253,112,229, 74, 33,204,102, 11,130,219, 55,197,217,243,105,136, 28, 58, 72,146,118, 56,
+163,206,193,244,245,215,167,210,199, 67,181,120,228,145, 14, 56,119,254, 10,142, 31, 63,143, 91,183,203, 65, 41, 16, 24,232, 11,
+189,190, 2,253,251,247, 66, 73, 73, 41, 10,143,255,137, 33, 79,134, 75, 82, 15,177, 87, 84,107,134, 60,189, 0, 0, 32, 0, 73,
+ 68, 65, 84, 30,100, 48,214,191,109,219,105, 48,158,128, 53,107,214,120,236, 5, 96,166,251,157, 51, 1,187,216, 78,182,222,253,
+175, 67,135, 14,180, 99,199,142,245,206,197,175, 84, 42,201,132, 9, 19,104, 98, 98, 34,152,141,149,234, 34, 60,219, 86,184,119,
+149, 63, 50, 50, 82,194,108, 14, 84,139, 18, 75,221,200,180,255,111,185, 60, 86, 85,159,119,212, 89,222,160, 69, 21, 56,182,188,
+ 73, 13,226,231,240,112, 90,255,206, 46,255,122, 77, 1,212, 87, 17, 24,250,121,183, 90,149, 0,111,200,159, 65, 74, 74, 10, 10,
+ 11, 11, 1, 0,193,193,193,212,147,151,129, 79, 43, 33, 32,102,136,132, 66,252,121,166, 21,248, 2, 1,154, 10,117,214, 56,128,
+ 38, 60, 20, 22, 54,197,227,189, 44, 32,132, 64,246,172, 9,212,194, 3,136, 15, 8, 40,172,129,252,174,161, 47,185,138, 27,154,
+ 10,100, 23, 22,214, 90,150,146, 82, 13,180,183,110,216,100,177, 30,128,156,201, 31, 0,176,107,215, 46, 60,245,212, 83,146, 61,
+123,246,184, 29,224,100, 50,217,240,188,188, 60,151, 29,166,180,180,212,241,114,243, 37, 75,150,224,220,185,115, 35, 30,164,169,
+ 0, 7,242,103, 13,201,240,193, 18,177,224, 58,124,125,155, 67,236, 35, 66,151, 46,157,209,177,115,103,148,149,169,161,209, 84,
+ 64, 36,226, 35, 40, 80, 12,129,111,115,183,131,169,128, 22,162,105,147, 22,208, 87,154,112,230, 76, 14,174,221, 40,197,245, 27,
+ 21,168,172, 22,227,145, 96, 19,196, 62,124,228,100,231,225,209,174, 93,113,237,122, 25, 42, 77,205, 88, 13,208,142,110,255,218,
+174,123, 58, 29, 80,155, 76,111,100, 49,214,255,188,121,243,238,186, 62,127,254,124,175,188, 0,174,118, 39,116,158, 59,110, 40,
+175, 66, 90, 90,154,170,190, 27,242, 76,152, 48,129, 42,149, 74,200,100, 50,184,154, 14, 96,227,169, 98,200, 31, 0, 50, 50, 50,
+238, 42,147,237,190, 91,163,135,217, 97,176,161, 60, 46,137,243,253, 49, 97,181,206, 37,241, 7, 7,241,108,163, 20,187,230, 29,
+ 61,122,116, 13, 47,201,211, 79, 63, 93,163,174, 56,183,255,131, 3,143, 99, 0, 26,202, 35,208,144,200,201,177, 42, 22,133,133,
+133, 30, 41, 1, 2,129, 0, 66,190, 16, 66, 33,193,176, 33,128, 94, 87,141, 75,185, 34, 8, 5, 66, 8,204, 2, 68,132, 83,136,
+132, 66,240,249, 60,128, 18,104,180,192,177, 19, 2, 88, 44, 22, 0,183,106,149,123,226,207, 92, 84, 84,212,158,129,179, 75,219,
+182, 84,103, 34,168,172, 44,133,217, 98, 98,253, 59, 79,156, 56, 81,187,210,161,215,179, 34, 26,103,215,191, 43,205,112,251,246,
+237,142,207, 39, 55,134, 23,192,149,139,223,145,252,109, 3, 32, 59, 11, 48,184,141,138,199,187, 10,147,217, 2,131,209,132, 91,
+183, 53, 16,138,196,168,174, 54,194,104, 50,195,100,178,192,100,166,172, 60, 49, 34,161, 14, 98,223, 14, 40, 46, 46, 69, 89,185,
+ 30, 26,109, 37,154,181,232,139,193,143, 63,142,140,212,221,104,111, 48,161,180,172, 20,221,187,119,133,143, 72, 0, 93,185,230,
+111, 49, 80,216, 34,255,237,115,255, 78,158, 41,175, 98, 1,230,205,155, 87,195,155,224,124,143,173, 2,160,209, 68,219, 31,140,
+141, 13, 66, 98, 98, 98,141,254,202, 24, 8,249,249,249, 94,239,202, 41,147,201,104, 98, 98,162,125,155,241,218, 98, 2,156,201,
+213,217, 83,149,150,150,166, 98, 2,223, 40,165,244,232,209,163, 53,238, 31, 61,122, 84,229,206,233,193, 40, 13,140, 18,224,104,
+197,215,102,232,187,249,109, 24, 31,153,140,205, 0, 38,174,214,225,137, 69, 21,245, 82,190,156,231,248,221,197, 4,112,184,247,
+222,128,218, 60, 0,247,213,191,227,202,210,175,143,245,239,100,177, 34, 39, 39,135, 25, 80, 88,245, 94, 62, 95,128,136, 65, 22,
+240,121, 2, 28,203, 20, 35, 43, 71,140,177, 79, 1,207, 60, 13,140, 27, 77,208,174,141, 8, 98,145, 15,196, 34, 31,248,138,125,
+ 16,220,206, 7, 98,145, 24, 98, 55,203, 0, 11,242,175,146, 18,205, 77, 82,219, 64,210,181, 75, 39, 4, 52,247,135,216, 98, 64,
+133,222,120,223, 59,197,225,195,135,247, 31, 62,124,184, 6,225, 59,126, 0,160,184,184, 24,227,198,141,107, 52, 43,223,102, 29,
+ 73,156,175,217,142, 61,178,228,204,102, 64,167, 55, 66,167, 51,160,172,172, 26, 55,111,106,113,237,218,109,148,151, 87,163,162,
+194,136,138, 10, 3,116, 58, 35, 74, 75, 74,221,202,170,174, 54,161,170,202, 12,163,209,128,166, 77, 69,232, 24,220, 12,126,254,
+254, 0,128,144,174,157,209,161,125, 51, 4, 52, 19,131, 82, 51,140, 38, 11,170,171,117,127,139,129, 36, 38, 38, 70,181, 96,193,
+130, 58,201, 60, 38, 38,134,181, 69,106,219, 82,184,214,251,171, 87,175,198, 55,223,124,227,241, 86,195, 14,219,206,218, 63, 12,
+161, 22, 22, 22, 50,187,103,122,196,110, 19, 38, 76,160, 73, 73, 73,112, 84, 30,148, 74, 37, 25, 63,126,124,157,223,155, 57,115,
+ 38, 8, 33, 96,250,113,120,120,184, 4, 0, 34, 34, 34,164, 12,145, 51, 86, 63,115,159, 82,106,191,207,226,215,214,176,226, 93,
+ 41, 14,108,102, 80, 90,182,108, 9,226,160, 37,212, 87, 30,135, 7,143,252, 93,157,123,229, 1,120,144, 44,255, 59, 3,188, 25,
+124, 62,223,227,239, 13, 25,100, 65,235, 86, 62, 40, 43, 19,192, 71, 96,130,143,136, 15,117,186, 8, 99,165, 66,136,132, 66,148,
+149, 9,145,154,233,143,102, 98, 2, 30,143,135,209,209, 6, 60, 55,150,130,199,163, 88,122,210,243,114,202,100, 50,202,247, 19,
+ 67, 35,108, 9, 63, 99, 1, 46, 22, 82, 12,151, 12, 99,189,165,111,255,254,253,113,228,200, 17,151,247,252,252,252, 88, 15,150,
+ 90,173,118, 4, 0,172, 95,191, 30,211,166, 77,179, 95, 47, 46, 46,182, 31, 79,155, 54, 13, 69, 69, 69,141,210,158,233,233,233,
+106, 66, 8,152,121, 82, 30,143, 7,198,221, 89,199,188,105,173,200,191,122, 77,218,170,153, 94,229, 35,226,195, 96,180,160,170,
+186, 0, 87, 11,138,161,209,150, 65,163,209,163, 88, 83,137, 98, 77, 37,154, 7,117, 6,144, 91,167,172,155,183, 41,110,220,188,
+141,158, 61,187,162, 68,171,133, 80,192, 67, 89,121, 1,116, 37, 22, 60,246,168, 14,109, 90,181,130,159,159, 31,124,124,124,113,
+253, 70, 57, 8, 63,144, 85, 25, 29, 93,242, 13,181, 10,160,161, 87, 16,212,102,173, 3,119, 98, 1,216, 66, 46,151,171, 99, 98,
+ 98, 48,119,238,220,187,188, 10,204, 52,131,183, 43, 11, 38, 76,152, 80,195,130,101,222, 47, 66, 8, 94,124,241, 69, 36, 37, 37,
+ 17,182, 74,128,179,229,239,120,207,217,211,224,140,181,107,215, 18, 0,118, 43, 63, 35, 35, 67,101,235,215,106,155, 55,128,249,
+171, 2, 64,210,211,211,237,247,235,218,206, 53, 45, 45, 77, 53,100,200, 96,233,145, 35,214,119, 98,230,204,153, 56,121,242, 79,
+ 41, 67,225, 71,143, 30, 85, 49,191, 63, 34, 34,194,173,167,108,237,218,181,248, 74, 26,136,137,107,244,214,223, 53,223,191,198,
+253,137,107,244,246,250,156, 46, 21,226,187, 3, 6,112,120, 8,148,246,184, 21, 53,149,238,149, 11,113,242,228, 73,246,171, 0,
+238, 5,241, 59,198, 2,212,199,250,175,105,201,215, 36,127,155,155,201,237, 84, 64,203,150,124,240, 8, 31,173, 90,242,209,173,
+ 43,197,181,107, 2,240,248, 4, 66,129, 0, 66,129, 16,127,157,246, 71,144,191, 16,124, 62, 31, 67,194,205,240,245,245,129,197,
+ 66, 1,106,246,138,252,155,180,233,136,155, 21, 20,186,139,106, 8, 8, 31, 23,175,229,147,139, 44,201,223, 54,176, 73,175, 94,
+189,170,186,122,245,170,171,223,171,102, 89,142,145,197,197,197,251, 24,146, 7,128,113,227,198, 97,253,250,245,246,103,202,202,
+202, 80, 84, 84,132, 29, 59,118, 48,203, 5,239,123,231,181, 13, 92,170,140,140, 12, 21, 19, 44,102,187,230, 49, 41,164, 30, 74,
+ 87, 75, 37, 97,160,133,101,208, 87, 26,161,245,169, 2,133, 22, 85, 85, 38,148,149, 85,163,232,182, 30,215,174, 87,224, 73,105,
+ 39, 0,169,117,202,170, 52,180, 68,222,165, 91, 8,233,242, 8,186,116,233,128,226,226,219, 8,108,110, 70,183,110, 1,104,221,
+ 42, 4, 98, 95, 95,148,148, 84,224,248,137, 11, 40, 40, 44, 67,219, 14,189, 30,218, 1, 36, 65,161,160,132, 64,202,112,169, 35,
+169,214,181,110, 63, 65,161,144, 36,172, 93,203,202, 11,176,102,205, 26,149,179, 2,176,106,213, 42,172, 91,183, 78,234, 78, 94,
+ 66, 66, 2,141,141,141, 37,114,121,160, 67,153,168, 43, 98,166, 0, 48,126,252,120, 86,238,127,199, 41,133, 22, 45,146,224,237,
+180, 1, 99,229,219, 20, 0, 74, 41,197,144, 33, 67,164,169,169,169,181,222,119, 71,216,204,220,122,106,234, 17, 21, 33, 4,132,
+ 16,244,235,215, 87,186,118,237, 90,245,221,207,222, 81, 50,220,201,227, 77,208,130,145, 39, 27,222,185,134,126, 52, 97,245, 57,
+187, 60, 54,224, 98, 0, 30, 30,184, 85, 0, 30, 68,139,159,193,164, 73,147,234,245,125, 30,143, 7, 62,223,250,233, 25,202, 67,
+255, 62,102,248,136,196, 86, 5, 64, 40,196,224,112,192,199, 7, 16,242,125,208,178,165, 24,124,190, 14,102,179, 5, 22,139,231,
+110,123,189,230, 6,196, 29,122,224, 82,242, 79,104, 37,224,225,112,254, 21,143, 7,148,121,243,230,169,215,174, 93, 43,173,207,
+ 50, 64,102, 89,223,235,175,191,110,191,198, 88,250,101,101,101,208,235,245,152, 62,125, 58, 0,224,235,175,191, 6, 0, 85, 99,
+180,109, 90, 90,154,218,102,237,171, 0, 96,208,160, 65,245, 10,224,234,208,169, 59, 50,143,238, 65,235,150,126,240,243,179,118,
+251,234,106, 51,202,202, 13,208,104, 43,209,177, 75, 47,252,184, 97,163,219, 54,249,253,247,189,228,197,231, 35,232,209,140,179,
+120,114, 72, 95,116,234,212, 9, 70, 67, 21,250,247,123, 28,254, 1, 1,184,146,151,143,194,107, 37, 72, 77, 59, 15,109,121, 0,
+118,175,223,248,208,250, 76,103,198,202,109,237, 79, 48, 83, 46,183, 47, 11,183, 56,145, 62,143, 71, 0,106,167, 12, 58, 83, 46,
+ 71, 95, 23, 22, 44, 33,160,112, 80,203, 99, 99, 99,225,236, 5,152, 59,119, 46, 8, 33,136,141,149,171,108,124,142,153,177,114,
+244,237,123,183,188,216,216, 88,187, 59,222, 29,201,177, 37,127,103,140, 31, 63, 30, 35, 70,140,144,122,171, 4, 59,206,213,135,
+135,135, 75, 83, 83, 83,213,181,221,103, 19,164,104, 91, 85, 64, 25,229, 43, 50, 50, 82, 42,151,199,170,157,149, 14, 7,249,240,
+ 68, 94,226,252, 38,214, 83,113,155, 59,158,142,249,249,118,133, 96,207,169,186,199, 62, 87,121, 0,184, 24,128,135, 84, 1, 24,
+ 60,100,208, 61,153,243,105, 40,203,223,177, 35,121, 3,141,150,160, 93, 27, 30, 8,225,129,240,120,216,187,223, 58,191,239,227,
+ 35,134,143,200, 7,227,158, 38, 16,251,136,224, 43, 38,208, 20,243,145,113,188, 41,204, 22, 51, 58,118,240,108, 94, 87, 38,147,
+209,107, 5,151,160,205,220,133,110, 29,133, 56, 83,232,253,188,240,204,153, 51,213,168,103, 80,158, 76, 38,147,126,249,229,151,
+ 42,198,205, 95, 92, 92, 60, 49, 60, 60,188, 98,223,190,125, 59,159,123,238,185, 81,197,197,197,100,234,212,169,123,108,249, 2,
+ 26,173,115,166,167,167,171,195,195,195,165,204,113,125,100,253,184, 97, 35,153,250,202,100,154,125,225, 28,174,229, 93, 1,143,
+ 71, 96, 54, 83,136,125,131, 16,218,179, 55,118,255,145,204,186, 78,175,221,178, 72, 53,197,215, 84, 85, 85, 38,244,233, 29,130,
+224,246, 45,145,127,245, 38,180,167,115,145,149,157,143,253, 7,254,194,149, 66,138, 99,153,103,188,106,167, 7, 37,249,143,101,
+115,160,215,207,245,255,132,165,188,220,255, 97,205,154, 53,118, 5, 96,205,154, 53, 64,222,250,187,158,117, 37,143, 45, 40,165,
+164, 62,253, 56, 54, 54,182, 94,125,207,129,228,213,222,220,119,229, 85,112,252,174, 43,121, 30,181,243,149, 45, 72, 90,243,178,
+117,108, 24,254, 72, 13,242, 7, 0,217,152, 39,172, 7,218,147,110, 21, 0, 46, 15,192,131,131,117, 43, 23,222, 53, 13,224,145,
+ 2,240,128, 7,124,212,187,112,153, 39,124, 32, 22,137, 48,110, 12, 1,143, 16, 12, 26,104,194,233, 51,190,224, 17,235,156,127,
+ 73, 9, 15,237,219,242,193, 35, 34,156, 58, 45,130,216, 7, 48, 24, 13,184,146,239,235, 17,249,231,102,255,137,240, 17,207, 64,
+208, 50, 28,185,217, 25, 16,220, 72, 66, 64,179, 32, 90, 90,166,105,148, 10, 86, 42,149,106,153, 76, 38, 29, 56,112,160, 42, 46,
+ 46, 14,189,123,247, 46,210,106,181, 24, 56,112,160, 84,171,213, 98,206,156, 57, 42, 27,249,171, 27,187,145,235, 75,252,206, 74,
+ 0, 0, 68, 14, 29, 36,105,215,182,157,202,223,223, 31, 63,110,216, 72,206,156,205,245,108, 64, 79,205, 80, 3, 32,102,180,164,
+231,178,210,209,174, 77, 19,136,197, 66, 84, 84, 24, 80,120,189, 12, 68,208, 17,199, 50, 83,185,104, 41, 54, 56,241, 6,208,245,
+255, 80, 99,121,225,241, 5,141, 90,164,216,216, 32,135,180,181, 13, 67,104,238, 72,217, 19,210,174,111, 62, 3, 87,227,188, 44,
+210,199,250, 91, 43,175, 91, 63, 28, 30, 90,244,235,215,207, 30,240,183,110,229,194,187,238,185, 85, 0, 26, 58, 31,255,253,206,
+239,239,153, 22, 65,160,213, 18,248,181, 37,104, 17, 68, 48,112,128, 17, 98, 17, 31, 62, 34, 35, 90, 4,137,109,131, 0, 65,196,
+ 64, 51, 50, 78, 8,173,222, 2,150,138,145, 76, 38,163,189,186, 55,195, 27,115, 63, 66,165,168, 3,126, 77, 46, 68,215,208, 65,
+ 0,128, 38,199,118, 32, 59, 31,180,162,188,241,148, 0, 0, 36, 47, 47, 79,178,114,229, 74,149,163,119, 0, 0,105, 76,203,255,
+ 94,195,150,236,167,222,245,126,240,208, 9, 50,245,149,201,244, 86,241, 45, 84,222,208, 67, 44,110,129, 14, 93, 30,103, 53,149,
+240,176,195,154, 14,187,129,126,102,222,122,216, 87, 4,228,109,104,244,223,230, 46,184,239,239,134, 81,207, 76,108, 80,203,157,
+139, 1,120,176,148,128,218,200,223,173, 7,224,159, 0, 10,107, 84, 63,225, 81, 80, 80, 4, 53,167, 72, 57, 44,128, 88, 36,132,
+143, 72,128,103,199, 80, 80,106, 65, 96, 11, 19, 76,102, 2,139,197,108, 27,252,220,227,241,206, 21, 24,251,162, 12, 21,130,110,
+104,221,196, 31,147, 95, 8,194,198,173,167,237, 74,128,209,252, 43, 78, 95,104,220,117,226,140, 34,224,112,206,189, 61, 94,120,
+ 21,254,142, 32, 19,180,132, 38, 6,222,205, 12,202, 32,175,228,173,211,174, 64, 76,224,194,187,111, 28, 95,208,232, 86,255, 63,
+ 25,251,254, 50, 54,100, 31, 38, 86, 5,145, 58, 40,139,220,180, 64, 99, 41, 1,110, 27,203,219,125,132, 57,112,224,192,129, 3,
+ 7, 14, 15, 47,184, 68,207, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56,
+112,224,192, 41, 0, 28, 56,112,224,192,129, 3,135,191, 7,106,172, 2, 56,121,242,164,215,209,160,174,130, 9, 27, 90,222,148,
+233,177,110,191,167,211,220,176, 31,251, 7,181,181, 31,255,252,125,194, 93,207,182,146,190,234, 86,222,190,213,119, 50,230,141,
+156,255,165,253,248,150,234, 91,120, 83,190,218,224,109,249,106,131,171,242, 61, 63, 85,238,246,123,153,170,157,232,220,185, 51,
+ 46, 95,190,140,129,210,177,246,235,191,253,168,184,231,245,231,174,191,196, 7, 7, 75,222, 40, 44,116,204, 76, 72,238,103,255,
+115,150, 55,118,236, 88,201,174, 93,187,106,100, 74, 28, 51,102,140,116,231,206,157,234,198,120, 63, 30,100,121,245,145,245,119,
+174,191,168,168,168,151,250,244,233,179,241,244,233,211, 47,166,164,164,252,218, 0,229,163, 15,202,251,193,201,107, 92,121, 30,
+ 43, 0,206,248,234,171,175, 36, 85, 85, 85, 32,124, 33, 8, 33, 48,155,140, 16, 9, 5,152, 51,103,142,186,190,154,199, 87, 95,
+125, 37, 1,128,217,179,103,215, 75,150, 78,115, 3,254, 65,109,237,196,223,182, 99,103, 0,192,141,171,151,189,146,183,111,245,
+235, 24, 57,255, 75, 59,113,125,181, 45, 3, 0, 48,251,217, 65,127, 75, 13, 48, 83,181, 19, 3,165, 99,145,169,218,105, 37,181,
+241, 83, 0, 0,151, 47, 55,126,253,133, 2,146,108, 64, 21, 10, 72,179, 1,213, 27,133,133,200,136,123, 27, 0, 48,104,229,167,
+141, 90,111, 47,189,244, 18,221,180,105, 19,170,170,170,106, 92, 23,139,197,170,151, 94,122, 9,191,252,242,203,131,186, 60,112,
+104,247, 46,193, 27,168,217,172,207,206,191,177, 8,192, 14,206, 14,170, 29,159,127,254,249,240, 63,255,252,179,217,181,107,215,
+218, 6, 5, 5, 53, 15, 11, 11, 43,124,243,205, 55,127,244, 86, 94, 84, 84,212,136,201,147, 39,167,108,220,184,241, 85, 0, 1,
+147,254, 47,118, 58, 0,203,233,211,167, 95, 86, 40, 20,191,201,229,114,139,135, 34,153,228,202,180, 1,198, 43,103, 18,105,168,
+ 62, 76,239,129, 76, 14, 13,237, 1,112,196,127,254, 27, 47, 9,232,216, 71, 21,213,167, 7,252,124,132,160,148,194,108,166, 56,
+147,115, 5,241,171, 63,147,250,250, 8, 49,107,214, 44,175,200,251,231, 13,139, 36,189,186, 29, 84,157,201, 14,145,122, 91,112,
+134,240,125, 3, 90, 64,167,185, 97, 39,254,186, 60, 2,108, 44,213, 65, 83, 22, 98,223,234,215,237, 47, 82,109,207,213,181,198,
+210,249,127,138, 68, 34,235, 91, 64, 41, 44, 22,235,251,109, 54,155,237,229,231,241,133,172,173,104, 0,104,215,218,154,170,211,
+ 80, 86,130,106,147, 9, 0, 80, 97,178,202,235, 50,106, 6, 30,237,213,159, 21,241, 3, 64,223,193, 35,144,169,218,105, 39,254,
+218,158,187,159,245,199, 12, 26,217, 0,158,242,247,199, 30,157, 78,197, 16, 63, 0,100,237,221, 87,215,160, 85, 39, 62,253,105,
+153,228,248,237, 99, 40,204, 63,133,110,157, 34,240,191,185,191,120,220,135,199,142, 29,251,220,230,205,155, 25,242, 55, 1,168,
+ 2,224, 7,192, 82, 85, 85, 37,240,245,245,197,216,177, 99, 37,174, 60, 1,141,140, 54, 79,244,235,243,199,158, 95, 18,154,232,
+ 10,207, 99,168,108,230,198, 43, 90,227,203, 0,126,123,208, 6, 38,153, 76, 70,189,221,128,199,137, 24,189,194,151, 95,126, 41,
+201,200,200, 80,109,216,112, 39, 49,209,237,219,183,145,157,157,141,103,158,121,230, 7,137, 68, 34,125,243,205, 55, 89,181,175,
+ 66,161,224,109,220,184,241, 67, 0,255,159,189, 47,143,111,162, 90,223,127, 38, 73,147,116,223, 41,251,214, 82,217,132, 74,185,
+136,172,137, 80, 16, 11, 40, 75,209, 82,189, 34, 66, 3, 42, 10,184,160,189,126,127,122, 93, 16, 20, 41,202, 26, 22,197, 43,101,
+ 43, 92,148, 66,161, 80, 72, 41,155, 34,101,223, 44,109, 41,221,128,238,107,246,204,249,253,145, 76, 76, 67,218, 76,210,176,222,
+121, 62,159,249,180,115,102,242,102,114,230,156,243,188,239,123,222,243,158,103,134,140,126,209,125,243,230,205, 33, 47,191, 62,
+203, 27,128, 1, 64, 27,211,109, 79, 0,224, 13, 31, 62,124, 24,112,247, 86,231, 77,145,234,128,184,143,112, 42,105, 17,105,170,
+191, 57,208, 63, 72,230,201, 83,224,243, 5, 48, 24,244,168,169,171,199,212, 73, 47,144,186,186,186,150, 18, 54,113,229,123,225,
+ 96, 31,182,182,253,181,240, 20,216, 87, 0,150, 46, 91, 46,145, 60, 63, 89,209,161,149, 47, 60,196, 2,208, 52, 13, 3, 13, 8,
+248, 20, 2,124,187,163, 87,183,142,138,244,180,189,210, 85,171, 86, 73, 28, 85, 2,150, 47, 95, 46,233, 17,122, 92,209,183,251,
+ 13,240,121, 6,197,242, 21, 43,164,115,222,126,219, 33, 25, 13,149,183,225,238, 27, 8, 95, 31,111, 0, 48,255,181,117, 95,235,
+ 14,157,237,122, 3, 14, 38,190,141, 1,113, 31,225,181,151, 38, 2,128,249,175,173,251, 86,238, 62,229,144,118,205,231,243,209,
+190,125,123,240,249,124,104,181, 90, 52, 52, 52,192, 96, 48,160,170,170,202,169,151,235, 37,224,227,199,101,187, 32,242, 5,238,
+228, 3,127,214, 23,163,236,118, 14,126, 73,252,216, 33,171,191,239,160, 17,104,223,214, 56, 69,210,222, 6,249,119,238,220,217,
+ 60, 29, 0, 0, 69, 69, 69, 46,169, 63,150,201, 85,201,104, 79, 79,124,241,246, 91, 0,128, 47, 44,136,127, 83,118,118,227,193,
+196,129,108,173, 83, 63, 30, 42,169, 26,144,174,248,168,227, 43,208,208, 35, 33,162, 9,162, 94, 48,224,167,111,183, 75, 15,174,
+ 4,219,193, 92, 48,107,214,172, 95, 85, 42, 21, 54,110,220,168,158, 54,109,154, 24,128, 23, 0,122,227,198,141,218,105,211,166,
+ 9, 84, 42, 21,196, 98,177,162,165, 3,221,232,209,163, 37, 7, 14, 28, 80,152, 54,108,105, 49,188,132,188,255,183,252,139, 15,
+221,253,174,108,129,251, 95,135,241,217,179,254,222,239,164,148,125, 94,167, 37, 15,149, 2,192,108,193, 91, 85, 21, 69, 2, 2,
+210, 29,254,237, 79, 63,253,180,228,143, 63,254,112,154,108,150, 46, 93, 42,217,177, 99,135,162,174,174,206,230,245, 91,183,110,
+ 97,199,142, 29,138,215, 95,127, 93,250,211, 79, 63,101,216,105, 47,212,230,205,155,127, 25, 50,250,197, 41,217,103, 79, 8,218,
+183,109,173,127,249,245, 89,141,198,221,195,123,255,139, 39,159,124,178,251,230,205,155,199, 60,249,228,147,187, 1,224,216,177,
+ 99,205,246, 15, 54,253,205,216, 63, 40,192, 78, 34,158,167,158,122,138,236, 75, 59,136,179,151,174,152,203,212,106, 13,190, 89,
+190,182,126,246,180, 88,142,176, 31, 99,220, 21, 4,184,100,201, 18,201,144, 81, 19, 20,221, 59, 6, 66,228,198, 3, 77,211,184,
+125,251, 54, 46,158, 63, 11,173,158, 6, 77, 19, 4,250,122, 96,212,152,177, 10,149, 70,239,240, 23,138,220, 74, 17,218,241, 54,
+192,167,208,179, 91, 33, 68,130, 59, 14, 91,254,150,228,111,141,154,218, 58,220, 46,204,135,187,111, 96,147, 94,129,230,200,203,
+ 26, 63,111,251, 47,222, 26, 63, 0, 3,226, 62, 66, 51, 90,246, 93, 16, 10,133,224,243,249,240,241,241, 65, 94, 94, 30,170,170,
+170,140,138,148,147,228,223,166, 85, 8,188, 4,124, 76,152,243, 37,198, 76, 29,132, 61,151,138,113, 91,133, 22,147,191, 53,138,
+ 74,110,227,242,233,227, 8,246,247, 49,146,191,128,239,146,250,123,110,210,107, 0, 0,127,129,155, 67,228, 15, 0,255,183, 98,
+ 37,254,111,197, 74, 51,249,167, 53, 52,224,131, 81, 99,141, 23,131,133,172,126,247,160,132, 46,146,153,239, 61,163,120,189,211,
+155,112,227,121,193, 19, 30,224,129,143,118, 33,131,241,246, 23,243, 21, 11, 82,186,179, 82, 35, 50, 50, 50,116, 0,240,243,207,
+ 63, 43, 1,136,153,109,148, 55,110,220, 72, 3,240,176,220, 86, 57, 54, 54,214,169,121,185,196,196, 68,137, 35,229, 44, 48,164,
+255, 83,125,149,201,255,221, 37,123,170,119, 56,191,225,202, 33,228,151,214,225, 86,181, 18, 52, 33, 78, 5, 2, 19, 66, 72,101,
+229, 72, 50,108,216, 48,151, 38, 18,179, 32,127, 4, 4,164, 59, 37,227,212,169, 83, 10, 0, 20, 69, 81,120,250,233,167, 29,174,
+179,244,244,244,187,200,255,244,233,211,152, 58,117,170,249, 92,167,211,225,218,181,107,138,196,196,196,102,189,152,155, 55,111,
+126,123,200,232, 23,199,126,149, 48, 79,144,156,156,140,245,203,151, 8, 76, 30, 35, 51,249, 39, 39, 39, 99,197,138, 21,120,242,
+201, 39,119,219,235,111,214,228,223, 84,127, 27, 51,216,228, 5,244,246,180, 43,239,187,229,171,205,228, 95, 90, 94,129,210,242,
+ 10,212,212,213,195,205, 77,224,181,122,227, 22, 53, 92,181, 33, 2,135,251,138,136,136,136,187,142,102, 21,128, 85,171, 86,145,
+192,206,125,208,185,181, 31,212, 58, 3, 40, 10, 72, 75,219,143,255,252,188, 17, 23,206,159,199, 7,243,231,130,207,231,129, 54,
+208,240,241, 16,161,115,159, 33,138,101,203,150,177,238, 96, 43, 86,172,144,244,234,118, 83,225,227,165,196,143, 63,151,130, 71,
+ 17, 12,120,242, 47,197,138, 21, 43, 28,234,164,182,200,159, 33,126, 85, 77, 69, 35, 5,161,166,182,206,174, 60, 91,157,137,233,
+ 72,167,146, 22, 53, 34,184,159,183,253,151,213, 51,134,134,134, 34, 48, 48, 16,181,181,181, 16, 10,133,224,241,120, 80,169, 84,
+168,170,170, 2,159,111,236,228,142,108,182,180,243,215, 93,152,187,236, 0,118, 45,255, 4,109, 90,133,192,195, 51, 0,133,134,
+ 98,252,146,248, 49,188, 76,131, 6,159,165, 60, 91,228,207, 16,127, 77, 73, 46,186,183,111,133, 58,165, 26, 34, 15, 17, 96, 48,
+216,141, 7,176, 87,127, 31,175,219,131,203,103, 78,162,119,215,158,168, 49,216, 87, 26, 25,242,255,235,192, 65,252,223,138,149,
+230,242,180,134, 6,164, 53, 52, 32, 79,246,111, 28,184,114, 1,189, 6,116, 5, 42,236,111,205, 60,252,253,174,146,217,239,140,
+ 80, 4,123,246,128,138,212, 1,154, 82, 8, 53,149,208, 24,234,160,166, 85,160,133, 94,104, 55,180, 63,162,102,119, 34,246,172,
+ 57,102,222, 95, 38,147,121,200,100, 50,192, 56, 5, 0,153, 76, 6,211,185,201,130, 82, 99,235,214,173, 14,119,218,121,243,230,
+ 73,230,207,159,175,232,217,179, 39,161, 40, 74, 1, 0,175,188,242, 10,233,212,169, 19,249,228,147, 79,156,218,154,217, 91,196,
+219,184,242,163,215,221, 71,183,211,240, 79, 92,187,141, 61,249, 60,124,180,239,142,230,223, 25,245, 53, 13, 58,188,230,140,204,
+170,170,168,123,105,249, 35, 32, 32, 29,113,113,113, 14, 79, 17, 90, 18, 62, 33,132, 98,182,147,102,139,215, 94,123, 77,114,231,
+ 14, 59,163, 68,171,213,226,226,197,139,135,155,107, 47, 0, 36,237,219,182, 22,198,196,196, 0, 0,178,178,178,112,120,239,127,
+197, 69, 37,183,105,134,252, 77,191,221,220,223, 46, 94,188,152,216,146,254,246,205,180,177,184,148, 91,136,214, 93,219, 0, 13,
+ 74,214,191,189,180,188, 2, 58,157,222,164,224,232,161,211,233, 81,120, 51, 95,220,194,215, 74,217, 57,231,240, 0,209,200, 21,
+165,209,104,240, 84,247,238, 10, 15,119, 55,208, 52,129,129, 6,142, 31, 61,134,127,127,241, 37,104, 2, 92,207,201,193,133,243,
+231,208,187,119, 95,240,249, 20,158,232,218, 30,121,103,216,123, 1,132,130, 82,132,119, 46, 1, 4, 20, 10,111,233, 0, 1,133,
+ 62,221,111,226,212,197, 82,167,127,128,165,123,223,150,103, 64, 85, 83,209,104, 53,128, 61, 88,186,247,109,105,218,167,146, 22,
+ 33,106,222, 10,155, 81,236,150,208,235,245,240,240,240, 0,143,199,131,191,191, 63,148, 74, 37, 26, 26,140,219, 0, 7, 7, 7,
+163,162,162,194,161, 28,217,234, 42, 96,128,187, 59, 62, 88,126, 20, 81,125,129,155,103,129, 63, 77,215, 62, 88,126, 20, 63,204,
+147,194, 64, 27, 28,174,191,203,167,143,155,255, 31, 17,217, 29, 2,111, 30,210, 50,174,224,169,238, 29,224,227, 37,194,207, 59,
+210,209, 95, 26,141, 34, 27,171, 0,236,213,223,238, 43, 4,184, 5,140, 31, 65, 97,221,158, 60, 4,250,119,193,196,193, 20,171,
+250, 99,220,253,105, 13,127,111,157, 76, 62, 75, 4,218,213,128,154,249, 41,200,191,191, 0,120, 42, 80,167, 22, 50,131, 74,147,
+149, 25, 58,201, 75,209,201, 47, 18,181,134,122,104,170,114,240, 75,193,102, 28, 27, 95,133,158, 51,164, 24, 53,199, 11,238,254,
+ 79, 64, 44,240,135, 96,124, 13,102,232,103,144,245,235,214,219, 28,164,100, 50, 25, 97,148, 54, 30,143, 7, 66,136,214,164, 68,
+171,121, 60,158,146, 16, 18, 0,128, 70, 11,150,215, 38, 38, 38,102,140, 30, 61, 90, 90, 81, 81,161, 72, 75, 75, 51, 42, 62,105,
+105,232,209,163, 7,186,119,239, 46,101,202, 28, 65,157,134,126,103,250,255,253,144,242,109,116,107, 30, 81,215, 96,102, 82,182,
+ 78,175,211,173,208, 24,176, 16,128, 83,155, 81,188,248,162,246,158,147,127, 82, 82, 82,134, 51,214,191,229,148, 9, 69, 81, 24,
+ 48, 96,128,132,237,174,146, 6,131,193, 33,133,225,198,141, 27,144,203,229,212,234,213,171,109, 93, 22, 3,232, 9, 64,240,108,
+244,196,234,188,188, 60,191,172,172, 44, 36, 39, 39, 35, 50, 47,143,151,149,149, 5, 0,136,140,140,196,115,195,251,195,199, 75,
+132, 21, 63,237, 42,157, 58,117,106,194,234,213,171,231, 57,218,223,110,253,186, 8,222,189,196,240,234, 54, 23,219, 23,205, 64,
+223,222,173,241,196,216, 47,237,246,143,154,218, 58,136,197, 34, 0,128,155,155, 0, 74,165,218,213, 60,195,145,254, 3, 0,155,
+205,128, 26, 13, 84, 52, 77,195, 67, 36,132, 86, 79, 64, 19,128, 71, 1,159,126,254, 37, 12, 52, 80, 95, 95,143,219,183,111, 33,
+ 36,164, 53, 8,161,161,215, 27, 32,118, 19,128,239,198,206, 5,187,114,229, 74, 73,183,206, 69,138, 32,255, 90, 99,115, 48, 29,
+ 20, 69,208,175,215,117, 5,179, 42,192, 17, 48,214, 61,227,238,183, 38,127, 54,214,191,181, 22,205, 16,255,202,221,167,238, 34,
+127,182,214, 63, 96, 12, 24, 18,137, 68,240,245,245, 53,187, 12,153,192, 63, 95, 95, 95,180,110,221, 26,122, 61,123,229,233,167,
+244, 35,240,237, 12, 72,194,141,231,217,122,163,251, 31, 48,150,125,242,165, 2,213, 90,199,166,100,138, 74,140,193,138, 29, 91,
+ 5,192,219,215, 19, 2, 31, 62,212,229, 42,128,199, 67,155, 78,237,113,252,124,190, 83,245,247,218,123, 95, 97,216,192,103, 33,
+184, 13,212,135, 0, 30, 60, 30, 6,118,238, 2,217,248, 16, 86,114,172,231,250, 55,189, 52, 3, 19, 94, 28, 10,132,169,129, 11,
+ 2,192, 75, 0,140,139, 68,251, 53,235,216,121, 99,218, 5, 64,171,173, 4,165,169,192, 47, 5,155,113,114,154, 47,134, 77,152,
+134, 33,173,158,147, 94, 58,160,135,158,110,128,155,182, 1,250,238, 52,202,238,176, 11, 26, 53, 41,111,234,105,211,166,241, 0,
+ 84, 17,211, 14, 81,166,243, 22, 33, 45, 45, 45,163, 71,143, 30, 82, 15, 15, 15, 4, 5, 5,193,195,195, 3,153,153,153, 84, 90,
+ 90, 90,134, 19,226, 90,143, 29, 59,118,221,202,181, 63,242, 62,205,168,167,119,156,200,129, 70,171,107, 80, 27,240,190, 35,228,
+111,237,242,207,204,204,164,152,227, 97, 33,127, 91,238,126, 71,189, 0,245,245,245,230,255, 79,159, 62,109, 62, 0, 96,254,252,
+249,141,206, 45,238, 23, 53, 33,174, 45,128,206, 38,165,208,227,185, 73,175,168, 45, 61, 1,140,229,255,204,224,193,150,253,109,
+143, 76, 38, 83, 59,210,223,226,199, 13, 67,159,200,238,240,238,235,141,226, 67, 5,128, 88,132, 73,115,254,137, 1,175,254,192,
+234, 55,235,245, 6, 20,223,186,163,103, 44,127, 6,133, 55,243, 91,250,106, 73, 19, 7,135,135, 64, 33,128, 45, 75,133,152, 6,
+ 55,154, 0, 6,218,168, 4, 80, 20,240,223,157, 59, 48, 97,226,100, 4, 5,183, 50, 15,128,196,129,119,201,231,149,162, 87, 88,
+161,249,188, 79,111, 15,179,110,216,175,103, 30,248, 60,199,189, 0,214,238,126, 91,215, 29,177,254,173,221,253,182,174, 91,174,
+101,111, 14,181,181,181,168,171,171,131, 70,163, 1, 77,211, 40, 43, 43, 51,187,255,149, 74, 37,234,235,235, 29,154, 2,216,181,
+252, 19,100, 92, 2,106,242, 1,157, 10,248, 97,129,212,236,254, 63,115, 22, 56,119,235, 56,248, 14,214, 95, 77, 73, 46, 2,124,
+ 61, 17, 24,224,137, 39,194,123, 32,239, 70, 25,178,139, 43,208, 49,208, 23,154, 59,165,200,185,158,211, 40, 23, 0,155,250, 27,
+ 36,121, 1, 67,164,177,216,149,178, 29,138,204,237,216,188,244, 61, 76,122,111, 33, 46,232,128,178,138, 82, 86,245,103, 57,215,
+255,250,160,167, 17,215,179, 19,182,239, 58,140, 11, 23,242,177,244, 98, 22,182, 70,253, 19,216,112, 2,197,197,101,172,172,139,
+246,106, 17, 12,218,114,104,181,198,200,234,144,118, 29,208,189, 71, 15,105,173,187, 49, 22, 67, 69, 43,193,211, 52,192,189,129,
+143, 59,183,154, 87, 0,152,119,166, 86,171,161, 86,171,197, 0,180, 0,188,213,106,181,143,245,146,192, 22,120, 1, 36,153,153,
+153,138, 30, 61,122,224,149, 87, 94,145,150,151,151, 99,226,196,137,142, 12,156, 67,132, 66, 97,189,151,151,151, 62, 42, 42,234,
+214,130, 5, 11,218, 38, 36, 36,228,253,121,246,194,243, 91, 47,107,174,233,104, 56,188, 31,235,189,112,249,187,146,252,173,173,
+127, 70, 97, 97,222, 25,219, 88, 0, 55,183,191, 99, 84,150, 46, 93,106, 62,108,157, 3,230, 21, 62, 77,189, 27,161,233,224, 1,
+ 16,212,148,228,218,116,167, 51,253,237,236,153,179, 55,166, 78,157, 26,239, 72,127, 27,250,143, 39, 48,114,112, 56,190,250,124,
+ 9,190, 91,150,138,255,183,233, 48,102, 61,219, 31,183,127, 75, 69, 77, 85, 45,155,254, 65,197,140,127, 14, 58,157,254,172, 78,
+167,215, 91, 42, 0, 0,176,240,211,143, 91, 98,193,115,150,255, 3,132,173,185,127,107, 37,160,145, 2,192,227,241, 80, 83,175,
+ 4,159, 71, 65,175, 55,128, 38, 4,122,218, 24, 68,122,254,220, 89, 60, 59, 98,180,209, 77, 70, 8,248, 60, 62,234,148, 90,232,
+181, 26,251,214,255,170, 85,146, 46,237,110, 41,130, 3,106,204, 90,198,160, 1, 94,166, 24, 93, 10, 20, 69,240, 84,143, 28,197,
+202, 85,171, 88,123, 1, 24,235,190,185, 96, 64,167,172,215,102,130,107, 28,129,191,191, 63,202,202,202, 32, 18,137, 80, 87, 87,
+135,224,224, 96,115, 80,160, 90,173, 70,117,117,181, 67, 10, 64,252, 87, 91,241,195, 2, 41,124, 59, 3, 25,151,128,119, 22, 43,
+224, 37,224, 99,226,187, 95,163,136,190,141,164,165, 31,130,207, 99, 47,143,177,254, 35, 35,195, 17,220,181, 51, 90, 5, 7, 65,
+200,163,160,167, 8,202, 26, 84,168,170, 83, 59, 85,127,223, 45,250, 21, 47,246,232, 2, 31,159, 64,120, 4,183,133,174,178, 10,
+103,247,108, 65,117,101,129, 83,141,248,199, 69,111, 3,243, 70, 66,160,215,162,115, 3, 80,202,175,197, 15,183,254, 4,132, 62,
+172,101,156, 73,249, 93, 90,206, 83,161, 64,168, 68,255, 48, 41,122,254,211, 11,121,254, 25,138,224,224,179,138, 14, 3,243, 80,
+195,171,131,134,168,160,220, 68, 67,236,229,205,198,242,183, 28,224,153, 85, 0, 66, 87,117,220,253,251,247, 3, 0,226,226,226,
+164,137,137,137, 25, 19, 38, 76, 48, 91,140,108,200, 63, 56, 56,120,223,186,117,235, 60,229,114, 57,127,222,188,121,152, 59,119,
+ 46, 57,113,226,196, 64, 0,105, 42, 61,122, 0,248,195,209,103,146,201,252,155,116,251, 59, 27, 16,232, 74,242,183, 38,120, 75,
+133,133, 16, 66,153, 2, 3,237,247,139,162,162, 19,204,255,155, 55,111, 54, 31,214,101, 12, 2, 2, 2, 32,147,201,154, 26, 4,
+139, 0, 84, 3,224, 21,149,220,198,201,147, 39,205,115,254,145,145,145, 0,140,219,111,111,219,157,138,170, 58,181, 18,192, 66,
+153, 76,102,112,164,191,253,182,235, 51,140, 94, 48, 7,207, 63, 63, 2, 65, 34, 62,234, 40,130,180,236, 66,156,188, 84,236, 16,
+ 81,207,158, 22,251,143,188,156, 28, 65,225,205,124, 48,135,137,252,193, 89,237,143, 38,241, 91,151,217, 66,163, 24, 0,145, 72,
+132,235, 87, 46, 72, 59,183, 13, 80,184,187, 9, 96, 48,208,160, 40, 10, 20, 5,196,203,222, 2, 33, 52, 12,166,124, 0, 74,181,
+ 26, 87,179,243, 32, 20,218,141,234,134, 94, 87,137,167,122,222,176, 28, 49,240,230,188, 27,216,185,169,155,185,105,245,239,157,
+139,223,207,247,112,216,250,183, 69,252,170,154, 10, 0,112,202,250,183,213,209, 78, 37, 45, 2, 0,214,214, 63, 96, 92,231,223,
+186,117,107,104, 52, 26,220,185,115, 7, 6,131, 1, 65, 65, 65,168,168,168, 64, 80, 80,144,169, 94,217, 19,118,217,237, 28,124,
+242,165, 2, 53,249,192,183,239, 13, 69,189,222,128,249,139,147,241,253,130, 24,188,183,116, 15, 4, 20, 5, 7,248, 31, 53, 37,
+185,104, 19,228, 7, 55,184,193, 0, 10,183,110, 92,198,205,210, 26,132, 6, 7,224,183, 51, 39,112,245, 10, 28,182,254, 39, 77,
+159, 15,183, 0,128,199, 7, 54,166,222,192,206, 85, 31, 96,250, 34, 57,230,143,235,139,183, 70,116,114,168,254,210, 26, 26,240,
+221,248, 41, 64,181, 24,160,220,128,239,150, 96,242,159, 71,113, 96,196,108, 80, 95,207, 1,245,251,135,172, 45,140,115,183, 2,
+241,180,170, 6,245,238,124, 40,197, 98,132, 78,114,131,134,168, 80,195,115,131, 30,225, 32, 6, 37,116,229,183,112,124,121, 13,
+226,166,134, 34, 67,161,184,239,157, 54, 62, 62,158, 0,192,218,181,107, 25, 87, 63, 53,111,158,113, 26,120,211,166, 77,108,223,
+236,224,182,109,219,238,255,250,235,175, 61,175, 95,191, 14, 55, 55, 55,248,248,248,224,194,133, 11, 58, 0,101, 45,121,190,230,
+214,228, 59,227, 29,112, 37,249, 91, 91,255, 70, 98,190,123,249,160,105,121, 96,134,157,231,186,190,109,219,182, 65,108,167,231,
+196, 98,241,244,166,149, 38, 89,221,240,225,195,111, 0,136,204, 62,123, 2,150,115,254,111, 78,159,130,253, 93,187, 34, 57, 57,
+ 25, 89, 89, 89,216,215,181,171,199,212,169, 83,127, 58,114,228, 8,235,254,246,210,200,167,225, 75,251, 67, 9, 55,236, 76,156,
+131, 85,123,206,225,131,231,134, 96,218,210,205,152,188,240, 23, 71, 45,112,106,225,167, 31,219, 74, 4, 68, 44,148, 0,206,162,
+127,204,208,200, 3,240,230,155,111, 82,213,183,114,144, 91, 88, 1,129, 27, 31,122, 3, 13,157,222,128, 51,103,178,240,159,255,
+252, 4,173,153,151, 45, 33, 0, 0, 32, 0, 73, 68, 65, 84,129, 64,103,160, 33, 20,240, 80, 90, 85,143,226,171, 39,165,115,231,
+206,109,182, 67,173, 90,181, 74,210, 35,244,230,223,214,191,169, 93,237,220, 20,110,108, 79, 60, 2,240, 8,120, 60, 26, 3,251,
+ 94, 85,172, 98,225, 5,176,101,253, 91,174, 2,240, 12,104,237, 16,249,219,178,254, 45,163,106,163,230,173,112,136,188,140,131,
+ 98, 21,234,235,235,225,230,230,102,182,254,105,154, 54,255,117, 84, 1,248, 37,241, 99,156, 41, 62, 2,175,214,198,160, 63,111,
+ 1, 31,101,183,115,224, 35,114, 67,117,101, 17,248, 60, 10, 2, 30,187,233,103,198,250,239, 16,224,141, 43,121, 55,160,215,106,
+ 33, 18, 8, 81, 95,175,198,111,138, 19,232, 47,141,118,136,252,153,250,123,225,237, 47,144,244,195,247, 80,210, 64,135,208,246,
+184,116,249,119,204, 31,215,215,169,250, 3,128,249,161,253,145,114,253, 48, 80,163, 7,196, 65, 56,120,234, 10,168,175,231, 48,
+ 3, 19,235,202, 59,178, 36, 47,227,248,193, 83,128,182, 14,245, 84, 29,170,120,245,168, 17,232,160, 51,212, 66,164, 86, 66, 92,
+114, 3, 91, 19,174,163,115, 68, 56,154, 10, 0,180,134,187,187,187, 37, 9, 64, 44, 22,219,188,198, 22,235,214,173,195,186,117,
+235, 90,212,153,189,189,189,223,201,201,201,241,244,241,241,129,187,187, 59, 2, 2, 2, 80, 86, 86, 6,138,162,148,174, 28, 52,
+ 24,139, 63, 38, 38,134, 0,198,128, 64, 71,130, 2, 93, 77,254, 79, 63,253,180,196, 94, 64, 45,219, 88, 0, 79, 79,207,120,129,
+ 64,144,107, 93,190,116,233,210, 70,150, 63, 0,116,234,212, 9, 35, 71,142,220,104,207,254, 41, 42,185,221, 40,218,255,147,255,
+155, 7,145, 64,136,144,144, 16, 48, 49, 1,166,235,158,142,244,183, 25,146, 62,152,187,228,123,212,221, 41, 69,176, 79, 43, 92,
+190, 82,128,105, 75, 55, 59,220, 63,172, 8,159,178,250,188,165, 28,206, 19,240, 8,224,220,185,115,205, 38, 3,106,210, 3, 0,
+ 0,239,191,255,126,198,183, 75, 40, 41, 33,227, 21,157,219, 6,194,219, 67,132,158,189, 35,208,179, 87, 95, 8,120, 64,189,202,
+128,130, 91,149, 56,149,177, 87,234,229,233, 97,247, 11, 26,148, 74,132,119,186, 5,181, 70,108,202,218, 98,108, 70,238, 98, 53,
+ 8, 1, 42,171, 69, 0, 5,120,123,234,241,100,120, 62,142,158,182,159,197,206,210,250,183,180,248,221,125, 3,225, 70,116,128,
+254,239,241,206, 32,176,255,140,150,214,191,165,197,207,148,229, 92, 62,107,190,151, 77,150, 61, 75, 37, 0, 0, 90,183, 54, 42,
+ 35,149,149,149,240,241,241, 49,187,255, 29, 81, 0, 24, 37, 0,248, 26,179, 99,134, 3, 63, 28,197,170,127, 69, 99,242,123,223,
+ 99,243,162,183, 32,160, 40, 8, 69,236, 86,236, 48,214,255,149,130, 82,132,117, 8,194,134,245, 91,209,185,115,103,248,182, 13,
+ 69,223,182,161,208,105,254,118,255,187,177,144,201, 88,255, 95, 78, 31,129,119, 62,221,136, 14, 93,169, 22,213, 31, 99,253,143,
+218,245, 35, 14,196,197,130,106, 63, 16,128, 49, 43, 32, 0,220,104,104, 48, 43,137,217, 96,151,192,103,229,180, 92,106,248,251,
+ 68, 18, 58,177, 78,209,185, 91,111,212,186, 3, 55,112, 19,117,249,101, 40, 91,104, 64,125, 85,123, 92, 59,158,205,250,133,208,
+ 52, 77,185,187,187, 19,149, 74, 5, 11,203,147,184,187,187,131,166,105,234, 65, 12,150,117,117,117,223,190,245,214, 91,227,215,
+173, 91, 39,246,245,245,133, 66,161,192,178,101,203,106,181, 90,237,115,174,252, 30,198,226,103,150,203, 57, 26, 8,152,156,156,
+ 76,153,146,252,180,152,252, 1,192,130,216,237,214,185,189, 12,131, 50,153, 76, 43,151,203, 7,110,223,190,253, 66, 67, 67, 67,
+ 27,157,206,184,204,212,154,252,123,246,236,137,129, 3, 7,142,149,201,100,246,190, 83, 80, 83,146,139,175, 62,251, 4,255, 77,
+217,135,209, 67,250,225, 80,250,239, 70, 3,166,109, 40,124,219,134, 34, 50, 47, 15,207, 77,122,165,188,160, 66, 57, 10,192, 14,
+182,214,255,220,181, 41, 72,120, 99, 20,218,182,150,152,149, 11,235,122,104, 97, 54, 69,206, 19,240, 24, 41, 5,172, 20, 0, 0,
+248,224,253,247, 50,190,253,150,150,222,104,255, 4,186,118,235,161,240,241,116, 7, 77, 0,149, 70,139,188,188, 60,148,229,157,
+147,122,123,121, 98,246,236,217,118, 59,174,187, 88,140,237,251,135, 75,153, 8,248,102,221, 17, 60, 30, 60, 61,217, 91, 79,204,
+ 18, 64,207,128,214,160, 13, 58, 35,249,155,160,163,220,236,166,216,181, 6,179,164, 38,106,222,138, 70,164,229, 12,249, 91, 42,
+ 1,150,137,127, 42, 43, 43,237,191, 0, 59, 74,192, 47, 22,171,132,215, 45,124,243,239, 19, 93, 61,188, 88,202,233, 16,224,141,
+237,167,207,225,210,181,191,208, 95, 26,221,136,244, 29, 33,127, 6, 47,188,253, 5,118,246,243,196,219, 19,186,187,164,254,230,
+135,246,199,123,187,183,131,250,234, 83,236, 11,121, 26,203,234, 47, 53,186, 62,209,215, 15,139,106,170, 29, 34,142, 35, 75,242,
+ 50,252, 5, 81, 40,170,202, 69, 89,197, 45,220,201,246, 2,223,224,131,193,125,134, 98,235,241,173, 15,116, 80,115, 81,182,191,
+211, 63,253,244, 83, 20, 69, 81, 7,191,255,254,123,241,139, 47,190, 88,171, 84, 42, 71,193,137, 57,255,230,224,138, 37,128, 50,
+153,191, 75,200,223,134,149,106, 79,249, 96,241,108,178,114,185, 92, 30, 90, 87, 87,247, 85, 86, 86,214,188,226,226, 98, 52, 52,
+ 52, 64, 40, 20,162, 77,155, 54, 8, 14, 14,126, 81, 46,151,255,246,203, 47,172,182, 4,184, 10, 32,178, 67,128, 55,158,121,230,
+ 25,156,187, 94,140,160, 46,189, 26,245,183,231, 38,189,162, 4,176,252,171,132,121, 59,216,254,142, 25,146, 62,136, 74,255, 3,
+113,159,254, 7,195,134, 13, 67, 72, 72,136, 77, 69,203,133,175,157,114,130,252, 73, 51,229,156, 18,241, 0, 72,159, 85, 42, 96,
+ 0,248,224,131, 15, 50, 86,174, 92, 41, 57,147,145, 45, 5,140,145,180,132, 16,136, 68, 34,124,248,193,251,172, 59,237,219, 14,
+166,249,101, 11,198,213,207,215, 43, 1,189,210, 28, 1,207, 16,191,163,107,177, 24, 87,127,206,229,179,200,185,124, 22,193,193,
+193, 40, 43, 43,115,138,248,125,131,219, 66,203, 34, 56,146, 45,226,190,248, 5, 39,142,186,174, 26,243,243,243,205,187,253,233,
+ 52,234,187,200,223, 17,226,103,240,207,126,158, 46,171, 63, 0,160, 18, 63, 52, 19, 63, 67,254, 55, 26, 26,164, 19,125,253,144,
+ 6,100, 44,170,169,118,234,183,255,186,232,160,197,192,163, 2, 0,108,189,204, 62, 97, 15, 33,132, 18,137, 68,102, 47, 0,243,
+ 63, 0,136, 68, 34,202,214,255,247, 25,199,126,252,241,199, 97, 59,118,236,152, 95, 91, 91,155, 8,224,148,171,191,192, 21, 75,
+255, 92, 76, 78, 46,135, 76, 38, 83, 1,152,111, 58, 90,244, 62, 46, 94,188, 56, 24, 64,151,160, 46,189,148, 58,141,218,195,212,
+223,106, 1,212, 0,184,218, 49,208,227, 37,153, 76,230, 80,131,142,250,100,221,253, 34,126,167, 20, 45, 39,239,231,224, 2, 68,
+ 68, 68,176, 34,127,187, 6,104, 75,119,234,187, 23, 96,230,246, 25,226, 71, 11,137,159,153,155,174, 41, 45, 66, 77,105, 17,130,
+131,131, 91,100,241, 3,128,222, 64, 59,236,125,104, 14,165,149, 53, 78, 63,139, 53,152,185,125, 87, 17,255, 61,168, 63, 10, 0,
+ 70,123,122, 18, 75,171,255, 41,129, 91,139,136,255,127, 12,127,214,214,214,198,114,213,240,224,113,228,200, 17,185, 92, 46,255,
+ 79, 65,133, 82,169,211,168, 45,231, 35,125, 58, 6,122,248, 59,177,251, 31, 5, 24,167, 50, 30, 53,165,138,195,253, 85, 2, 88,
+ 53, 38,103,247, 17,230,192,129, 3, 7, 14, 28, 56, 60,186,224,113, 85,192,129, 3, 7, 14, 28, 56,112, 10, 0, 7, 14, 28, 56,
+112,224,192,129, 83, 0, 56,112,224,192,129, 3, 7, 14,156, 2,192,129, 3, 7, 14, 28, 56,112,120, 44,208,104, 21,192,185,115,
+231,156,142, 34,181, 21, 76,200,201,227,228,185, 74,158,105,111,117, 30, 0,218, 86,242, 21,174,254,154,150, 23, 17, 17,193,212,
+ 29,179,150,155,156, 59,119,142,230,234,143,147,247, 40,201,139,140,140, 20,100,101,101,233, 1, 96,192,128, 1,164, 91,183,110,
+ 72, 74, 74,162,184,250,179, 45,207, 97, 5,224, 49, 65,139,146, 76,196,196,196, 72, 0, 88,166, 12,149, 38, 39, 39,103,112,186,
+226,131,193, 55,223,124,243,234,197,139, 23,251,158, 60,121,242, 61,145, 72, 4,165, 82,249,161, 92, 46, 95,194, 34, 3, 27,135,
+191, 7, 22, 2,192,192,213,196,195,141,232,232,104,201,222,189,123, 51,156,252,172, 52, 53, 53,245,176,139, 18, 74, 33, 58, 58,
+250,165,212,212,212,173,107,214,172, 9, 0, 80, 7,192,240,160,251, 28, 67,254,113,113,113,100,211,166, 77,232,223,191, 63,215,
+104, 90,136,199,106, 10,192, 68,222, 45,250,252,246,237,219,173,243,133, 43, 90, 34, 55, 38, 38, 70, 98, 90,179, 75, 98, 98, 98,
+136,163,178,136,131,176,181, 62,184,133,242, 36, 15,226, 93,202,229,114,106,206,156, 57, 75, 46, 95,190,252, 67,167, 78,157,222,
+ 19,139,197,208,104, 52, 0,240,205,206,157, 59,233, 9, 19, 38, 72, 31, 80,151, 33,142, 31,247, 83, 94,147,123,176, 91,238,197,
+238,212,254,236, 49, 49, 49, 18, 66, 8, 33,255,207,182,108,230,154,189, 54,104, 11,249,249,249, 36, 63, 63,223,101, 4, 83, 89,
+ 57,178,209,126, 5,174, 38,106,138,162, 28,146, 75,211,132, 24, 12,132,208,180,237, 35, 58, 58, 90,146,154,154,234,212, 46, 84,
+107,215,174,125,118,223,190,125,135,135, 15, 31, 14,138,162,200,150, 45, 91, 70, 58,250,108,214,199,190,125,251,182,190, 60, 72,
+ 8,217, 44, 89,101,174, 87,222,142,153, 51,227,105,230,154, 61,121, 13, 13, 13,164,161,161,161,217,118,200,220,227,236,251,185,
+118, 90,138,244,181,231, 17, 25, 25,201, 25, 2,236, 13,129,187, 18, 4, 9,236,116,120,155,121,179,237,229,211,126,128,104,209,
+ 54,110,219,183,111, 87, 76,153, 50, 5,128, 49,169,134, 69,227, 84, 56,227, 85, 96, 20, 10, 38,231,191, 41, 13,169, 34, 38, 38,
+198, 49,175, 66,114,128, 3,223,106,191,239, 55,140,123,147,189, 56,199,247,181,105,170, 67,178,174, 63,185, 92, 78,213,212,212,
+108,235,221,187,247, 36, 0, 60, 66, 8,220,221,221, 81, 90, 90,138,234,234,106,248,250,250,162,180,180,244,240,132, 9, 19,164,
+187,118,237,202,112,240,157, 16, 38, 29, 44, 69, 81,152, 52,105, 18, 70,142, 28, 41,157, 53,107, 22,107, 57,187,119,255,106,254,
+127,252,248, 23,237,158,219,131,234,196,219,127, 87,247,160, 21,141,206,173,203,220, 7,217,223, 84,137,217, 78,216, 18,153,153,
+153, 88,184,112,225, 93,239, 98,232,208,161,228,232,209,163,172,218,114,114,114,178, 2,159, 82,204,249,221,137,103, 62,165, 90,
+ 60, 24, 63,196, 99, 75, 35, 75, 91, 46,151, 75,227,227,227, 49,108,216, 48,114,236,216, 49, 86,159, 61,209, 68, 78,198, 93,201,
+239, 33, 53, 53, 85,193,108, 18, 54,108,216, 48, 82, 91, 91,219, 28,225, 75,226,227,227,205,237,245,183,223,126,243,160, 40, 10,
+177,177,177,119, 0,132, 76,157, 58,245,160, 92, 46,231, 57, 98,177, 47, 57,184,196,252,255,237,180, 91,160, 40, 10,155,223,245,
+ 0, 64,225,219, 87,190,121, 33, 40, 40, 8, 0,176,229,231,205,172,235, 42, 50, 50, 18, 93,187,118,117, 73,189, 71, 70, 70,242,
+178,178,178,232, 1, 3, 6,144, 77,155, 54,225, 78,118,103,160,220,159, 99,117, 7,200,223, 81, 15, 0, 73, 78, 78,190, 75,195,
+178, 24, 64,137, 19,157,219,165,214,164,181,188,228,228,100,203, 13, 49, 28, 6, 69, 81, 84,114,114, 50,197, 12, 64,166,191, 78,
+ 91,154, 12,249,155,158,137,178,120, 54,135, 21, 21,106, 74,149,249, 96, 83,110, 15, 94,123, 86,155, 15, 54,229,142,144, 63, 33,
+ 4,204,238,108,132, 56,214, 76,228,114, 57,175,170,170,234, 63,190,190,190,147, 0,240,166, 79,159,142,184,184, 56, 8,133, 66,
+184,187,187, 67, 44, 22,131,162, 40,240,249,124,212,212,212,176,174,199,168,168, 40, 9, 0,178, 99,199, 14, 48,239,132, 16,130,
+157, 59,119, 98,214,172, 89, 10,211,245,135, 14,182, 20,130, 7,225, 89, 75, 78, 78, 86, 0,160, 94,186, 54, 5, 83,174,218,236,
+ 99,100,202,213, 24, 41,245,185, 83,253,142,124,240,193, 7,232,210,165,139, 75,158,151,162, 40, 34,147,249, 35, 48,240,144, 75,
+235, 97,204,152, 49, 35,210,211,211, 15, 19, 66,168,248,248,248, 12, 71,200,191, 41,236, 74,126, 15,137,137,137,160,105, 26,239,
+189,247, 30, 43,133,194,146,252, 1, 96,223,190,125, 41,195,134, 13, 3, 0,255,216,216, 88,253,240,225,195, 33,147,201,104, 83,
+220, 12, 27, 47, 99,163,243,101,203,150,225,165,103,140,182,225,230,119,221,241,242, 32, 33, 62, 28,253, 1,235,223,228,233,233,
+137, 97,195,134, 33, 43, 43,203, 60,158, 90, 31,204, 61,108,149,189,172,172, 44, 26, 48,110,179, 14, 0, 62, 30,229, 28,171,183,
+144,252,155, 85, 0, 24,178,202,202,202, 50,167,157,180,180,158, 28, 37, 90,139, 65,196,213,131,146,181, 50,224, 82,215,176,141,
+ 41, 1,135, 97,169, 80,152,172,255,199,177,157, 17,203,193,164,184,184,216,124,161,168,168,136,181,194, 88, 83, 83,243,181, 82,
+169,124,133,199,227,241,166, 78,157,138,154,154, 26,148,148,148,192,205,205, 13, 2,129, 0, 2,129, 0,110,110,110,112,119,119,
+135, 74,165, 2, 27, 23,226,154, 53,107, 36, 7, 15, 30, 84, 80, 20,133,201,147, 39,131, 16,194, 40,121,212,228,201,147, 1, 0,
+233,233,233, 10,110,168,104,158,252, 77,239, 87,106,169, 36, 51,239,222,210,171,229,140, 5,159,156,156, 76,153,222, 11,214,172,
+ 89,227, 18,101,236,227,143, 63,102,140,130, 22,123, 38, 70,143, 30, 29,117,250,244,233,244,206,157, 59, 35, 44, 44,140, 12, 30,
+ 60,216,236, 57, 49,237,254,232, 20,249, 47, 93,186, 20, 20, 69,129,199,227,225,244,233,211, 96,227,141,177,242, 72,188, 64, 81,
+ 20, 94,126,249,101,189,169, 72, 27, 27, 27, 91, 43,145, 72, 48,107,214, 44,250,249,231,159,183,251,219, 45,119, 37,189,157,118,
+ 11,160,128,164,119,254,206, 90,188,249, 93, 15,196, 14, 22, 97,193,115, 31,178,126, 46, 54,150, 63,155,123,226,226,226, 72,100,
+100,164,249, 56,125,250, 52,234, 11, 34, 1,173, 10,148,151, 30,233, 95, 94,133,229,117,230,224,122,110, 99,242,143, 95,176,200,
+230,117, 65,115, 29, 50, 50, 50,146,100,101,101,129,241, 4, 48,196, 21, 25, 25,233, 80, 39,191,215,228,111,105, 85, 63,236, 1,
+123,150, 83, 2,143,157, 6, 64, 8,138,139,139,113,251,246,109,115,153,245,185, 29,235,159,191,127,255,254,231,195,195,195,193,
+231,243,145,147,147, 3, 66, 8,254,250,235, 47,104,181, 90, 80, 20, 5,129, 64, 0,138,162, 96, 48, 24,160, 84, 42,177,107,215,
+ 46,187,114, 15, 29, 58,164, 0,128,201,147, 39,223,213,110,153,169, 30,134, 40,216,180,107,107,183,190,189,115, 54, 86, 62,131,
+166,166, 3,216,184,254,173,145,153,153, 9,147,101,216, 50, 5,248, 83, 10,212,231, 70, 5,206, 82,121, 37,132, 0,159, 82,152,
+114, 53,198,233, 64, 89,138,162,136,233,189,152,201,200,244,190,168,150,200,235,214,173,219, 93,228,230, 44, 68, 34, 17,185,124,
+249, 50,202,202,202,168,178,178, 50, 68, 68, 68,144,252,252,124,240,249,124,232,245,122,167,190, 96,248, 96, 62,163, 60,224,253,
+247,223,199,178,101,203,112,244,232, 81, 80, 20,133,113,227,103,226,102, 62,187, 13, 28,247,237,219,247,171,233, 29,171, 1,208,
+166, 3,177,177,177,213, 0,252, 82, 83, 83, 17, 29, 29, 45,177, 84,200,155,131,209,250,191,123, 31, 19,227,116, 0,176,101,243,
+ 89,135,228,181, 20,215,174, 93,195,233,211,167, 27,149, 25,170,111, 64,175,163, 1,170, 14,126,207,233,112,218,106,179,107, 46,
+ 56,144, 29,249, 55,235, 1, 48, 89,255,148,165, 39,128,177,252,179,178,178, 90, 66,254,246, 2,148,156,146,103,225,153,144,192,
+137, 0,167,123, 96, 57, 17,139,193,199,252, 60, 76,153,171,130,147,200,118,127,243,225, 10,212,143,157,109, 62, 28,176,252, 9,
+ 51,216,182,111,223, 30,253,251,247, 55,119, 66,230,220,250,222, 38,224, 23, 16, 16,208, 91,163,209,160,178,178, 18, 39, 78,156,
+192,169, 83,167, 80, 86, 86, 6,149, 74, 5,102,142,148, 16, 2,157, 78, 7,141, 70,195,106,138,129,105, 27, 77,145,123,114,114,
+ 50, 69, 81, 20,216,122,102,118,239,254,213,124,176, 57,183, 7,213,137,183, 27, 17, 61,115, 88,158, 91,222,195, 22,195,134, 13,
+ 67,102,102,102,203, 26,132,197,156, 63,140,211, 88, 82, 19, 57, 83,204, 53,180, 48,246,198,242,189, 48, 94, 0, 87,193, 21, 94,
+128,118,237,218,161,168,168,136,178, 86,118,157, 37,255, 93,201,239,153,219, 48,131, 33, 67,134, 0, 0,142, 28,103,191, 88, 35,
+ 58, 58,122,180,105,238,255, 10, 0,165,105, 60,103, 14,179,214,205, 54,184,176,241,220,191, 13,229,202, 65,121,174, 64, 86, 86,
+ 22,213,191,127,127,212, 93, 25,131,170, 19,109, 80,125,204, 29,164,170, 26,168, 7,120, 74, 61,106,143,242,160,250, 67,136,234,
+ 19,173,176,127,115, 20,250,247,239,239, 16, 63,253,175, 67,192,166,115, 50,158, 0, 71, 45,255, 5, 11, 22,144,197,139, 23,187,
+236, 97,237,201, 51, 13, 82, 46,107,156,108,231,208,154, 35, 29, 11, 89,245, 50,153,204,171,169,235,206,194,114,238,223, 21, 74,
+128,229,220, 63, 91, 37, 32, 46, 46, 14,158,158,158,240,242,242,130,183,183, 55,124,125,125,105,127,127,127, 94,106,106, 42, 94,
+125,245, 85,243,125, 98,177, 24,163, 70,141, 66, 51, 74, 64,160, 86,171, 69,101,101, 37,212,106, 53,124,125,125, 33, 18,137,160,
+215,235, 65, 8,129,193, 96,128, 86,171,133, 78,167,131,193, 96,112, 40,190,192, 20,180,214,228,117, 75, 43,244, 65,194, 94, 64,
+160,163,104,169, 18, 64,125,222,244,116,223,148,171, 49, 38,114,117, 82,182,149,245,111, 81,142,201,147, 39, 59, 28, 12,104,109,
+253, 91,202,115, 22,145,145,145,196, 96, 48, 32, 34, 34,130,156, 59,119,142,138,136,136, 32, 58,157, 14, 53, 53, 53, 45, 33, 53,
+227,224, 43, 16, 96,222,188,121, 56,125,250, 52,254,158,247,103,223,166,247,239,223,191,127,232,208,161, 0,224,109, 34,125, 37,
+ 0,108,221,186,181,213,145, 35, 71,124, 76,253,131, 50,253,181, 43,120,217,247,203,240,242,192,187,173,255,184, 31,148,216,122,
+ 66, 7, 66, 8,158,154,250, 20,206,110, 62, 75,221, 79,227, 42, 43, 43,139,146,254, 51,146,236, 95,214, 9,130,250, 90, 64,111,
+252,106, 26,128, 80, 0, 20,223,246,195,225,130, 72,195,218, 45,101,252,172,172, 44, 42, 50, 50, 82,204,196, 10,112,214,255,162,
+102,239,179,187, 12, 48, 38, 38,134, 48, 13,214, 50, 30,128, 13, 22, 47, 94,204, 88, 12, 46, 1, 11,121, 78,207,175,155,150,232,
+ 53, 58,210,211,211,105,102, 85, 64, 75, 45,246,248,248,120,175,199,185,193,173, 93,187, 22, 75,151, 46,109,212,174, 24,242, 31,
+ 63,126, 60,198,143, 31,111,180,112,142, 28,105, 78, 76, 64, 94, 94,158,218, 96, 48,160,170,170, 10,229,229,229,168,170,170,130,
+ 82,169,132, 82,169, 68,125,125, 61,106,107,107, 81, 83, 83, 3,149, 74, 5,141, 70, 3, 54, 29,157,162, 40,236,216,177,195, 33,
+133,237, 81, 70,102,102,102,163,195, 18,243,230,205,147, 88,158,179,153,115,182, 49,231,223,200,114,111, 73,212,190,173,207, 18,
+ 66,168, 29, 59,118,184, 52, 22, 96,199,142, 29, 14,247,225,126,253,250, 17,131,193, 96, 78,208, 18, 17, 17, 65,104,154,198,157,
+ 59,119,208,208,208,224,212,111,254,215,130,225, 56,114,228, 8,232,109,126, 32,132, 32, 49, 49,209,252,142, 50, 79,208, 96, 59,
+243, 17, 29, 29,253, 34, 0,196,198,198, 22,155, 20, 0,205,150, 45, 73,173,102,207,158,221,234,200,145, 35, 24, 51,102, 76,148,
+ 35, 57, 1,110,167,221, 2, 5, 10, 73, 22,214,255,212,239,149,224,191, 92,131, 45, 39,180,152, 59,119, 46, 22,239,255,230,190,
+183,229,200,200, 72, 62,163, 4, 60, 55, 87, 15,162,242, 5,106, 1,212, 2,252, 58,160,246, 14,176,239,108, 27, 88,144,191, 32,
+ 43, 43, 75,205,145,191,125,242,183,235, 1,176,158,247,183,140, 7, 96,235,102, 73, 78, 78,206, 48, 5, 8, 41,172, 60, 73,206,
+ 14, 24,119,201, 99,166, 5, 76,243,144, 46,113,255,140, 28, 57,242, 82,122,122,122,239,135,241, 5, 51, 86,191,171,220,254,140,
+213,239,128,219,191, 17,146,146,146,204,255,255,251,223,255,198, 79, 63,253, 4, 0, 90, 0, 66,134,248, 1, 96,212,168, 81,246,
+ 20, 0, 85,120,120, 56,148, 74, 37,180, 90, 45,202,202,202, 32, 18,137, 32, 16, 8,204, 30,128,134,134, 6, 40,149, 74,104, 52,
+ 26,212,212,212, 96,210,164, 73,210,157, 59,119, 54,251,124,140,149,105,103, 89, 43, 38, 79,158,108, 87, 81, 48, 42, 52,247, 46,
+ 6,192,153,235,214,176, 88,238,119, 23, 18, 19, 19, 21,243,230,205,147, 38, 38, 38,102, 60,208, 54,220,132,245,111, 9, 71, 98,
+ 1,154,178,254,157, 69,191,126,253,200,153, 51,103,168,136,136,136,207,152,166,109, 48, 24, 62,245,244,244, 68,121,121,185, 83,
+ 99,204, 39, 31, 13, 71, 70, 70, 6,168, 29,129, 0,128, 3,159,120, 99,212,151,117, 24, 54,108, 24,190, 90,124, 4,132, 16,214,
+222,138,125,251,246,237, 26, 62,124, 56, 0,148,109,221,186,185,221,145, 35, 71,253, 8, 69,240,252,152,231,199,239,221,187, 55,
+101,239,222,189, 14,121, 57,151, 45, 91,134,151, 7,185, 53,182,248, 65, 48,111,238, 60,132,140,106,141, 7, 21,183,148,149,149,
+213, 72,195, 39,117,128, 72, 11,208,132,130,222, 64, 32, 34, 64,136, 59,207,242,126, 61, 56, 24,141,178,197, 31, 53,169, 32, 68,
+ 68, 68, 52,175, 0, 88, 70,252,155,200,223, 28, 44,197,120, 2,216,106,254, 54, 72,187, 69,176, 33,207,229,115, 82,241,241,241,
+189,211,211,211, 93, 57,224, 61,174,237,140,130, 49, 10,220,108, 73,191,254,250,235, 0, 32,180,104, 75,230,107,166, 65,171, 41,
+ 92, 30, 56,112,224,171, 25, 25, 25,201, 6,131, 1,181,181,181,208,233,116,230,121,127,181, 90,109, 94, 98,200, 4, 6,238,220,
+185, 51,131, 69,123,161, 96, 90, 2,104,221,110, 99, 98, 98, 8, 67,250, 35, 71,142,148,178, 81, 0,238, 85, 30, 0,203,185,127,
+ 75,242,183,158, 22, 96,241, 62,154, 3, 73, 76, 76, 84,188,244,210, 75,216,182,109,155,179,222, 50,137,165,231,132, 57,103, 2,
+ 6,167, 92,141, 33,215,175, 95,111,242,243, 76,194,159,253,251,247, 55,233,177,187,113,227, 6,107,207, 76,101,229, 72, 2, 0,
+ 81, 81,121,200,203,203,179, 25, 93, 94, 81, 49, 2, 64, 21, 0,251,227, 86,207,158, 61,201,153, 51,103, 40,211, 96,249, 25, 0,
+240,120,188, 79,111,222,188,137,170,170, 42,167, 58, 50,143, 71, 25, 21,118,134,252, 47,232,241,147, 66, 11, 0,248,106,241, 17,
+135,199, 8,166, 79,204,158, 61, 59,130, 16,130,232,177,209,147,246,164,236,249, 47, 91,226,183, 20,245,226,132, 23,174, 80, 20,
+213,147, 16,128,255,114, 13, 8, 33,152, 55,127, 30, 90,143,106,211,194,188,170,198,101,189, 76,187,107, 73, 38,193,200,200, 72,
+178,253,163,182,240,170,184,129,220,218,246,232, 34, 42, 3, 60, 67, 32,104,184, 3,159,134, 10, 0,173,204, 30, 3,107,165,129,
+131, 19, 30, 0,203,229,126, 86,203,216, 72,114,114,178,195, 46, 83, 11,210,118,201,131, 91,202, 99,214,255, 63,166,203,235, 30,
+ 9, 88,213,125,163, 37, 98, 77, 92,187,107, 48,144,201,100,122,185, 92,190,115,248,240,225,115, 82, 83, 83,151,235,245,122, 84,
+ 87, 87,155, 99, 0, 0,160,172,172, 12,213,213,213, 32,132,192,145,246, 20, 21, 21, 37, 61,120,240,160, 34, 57, 57,185,145,245,
+201,124, 62, 42, 42,202,161,100, 64,247, 2,170, 19,111, 59, 67,248,119, 17,188,157, 33,155,162, 40,138, 56, 67,254, 38, 79, 91,
+134,173,190, 8, 0, 22, 65,129,172, 48,107,214, 44, 5,139,239, 36, 14,172, 21,111,244,183, 49, 17,177, 75,142,215,165, 75, 23,
+114,229,202, 21,198,229,255, 25,128, 79, 53, 26, 13,114,115,115, 81, 83, 83,227, 44, 21, 18,122,155, 63, 14, 92, 48, 26,167, 27,
+ 21, 90,108, 61,161, 5, 33, 4, 71, 79, 58, 63,179,152,153,153,137, 49, 99,198, 72,247,238,221,155,177, 39,101,143,179, 98,120,
+ 52, 77,187, 1,192,182,147, 58,204,157, 59, 23,173, 71,183, 97,175, 78,218, 64, 67, 67, 3, 0, 32, 47, 47,143,172, 93,187,214,
+172,144, 89,198,146,108,220,184,209,114,124, 96,245, 45,157,120, 13, 64,112, 4, 94, 93, 87, 3, 32,196, 88, 7,111, 5,161,163,
+160, 16, 95,142, 44,197,207,221, 94, 38, 91,183,110,253,159, 15, 0,100,172,123, 91,150,191,245,245,230,166, 0, 40,211, 20,192,
+ 93,203,166, 28,153, 2,176, 57, 80,184,142,116, 44,229,185,116,253, 63, 51,247,239, 44,236, 41, 36,142, 42, 44, 77,185,251,157,
+157, 6,104,202,221,239,228, 52,128,101, 80, 16,229,192, 53,216, 80, 2, 8,128, 21,114,185,124, 77, 82, 82,146, 78, 40, 20, 66,
+163,209, 64,175,215,131,166,105,248,249,249,161,170,170, 10,142,102, 83, 60,120,240, 96, 6,140,235,254,201,142, 29, 59, 96, 82,
+ 4,204, 75, 3, 15, 30, 60,248, 63, 49, 56,188,244,210, 75,164,161,161, 1,123,246,236,113,180, 61, 75,236,212, 55,153,114, 53,
+ 70,202,198, 27,247,193, 7, 31,220,101, 92, 88,227,195, 15, 63, 36,108,131, 60,101, 50,127,187,242,100, 50,127, 86,194,220,221,
+221,153, 65,146, 16, 66,160, 84, 42, 81, 82, 82,226,244,156,191, 37, 70,127, 89,215,232,188, 37,228,111, 48, 24, 40, 0,112,194,
+226,183, 6,189,251,183,148,110,150,153, 0, 93,133,230, 20, 50, 11, 5,128,149,245, 47,155, 28, 90,242, 99, 54,218,202,119,228,
+ 54,138,242, 31,182, 50,146, 28,158,245, 4,174,223,113, 71,115, 94, 39, 14, 14,122, 0, 76, 47,142,114,164,252, 1, 91,160, 25,
+ 15,217,243, 80, 14, 88,204,118, 20,145,145, 46,123,174, 41, 83,166, 72,157, 72,239,219,172,133,102,195, 2,109,206, 58,101, 21,
+ 52, 38,147,201,244, 0,168, 73,147, 38, 73, 10, 10, 10, 20, 42,149, 10, 6,131, 1, 61,123,246,148,246,239,223,223,233,247,189,
+ 99,199, 14,203, 37,103, 78,121,141,238,117, 12,128,189,115, 54,250,162, 41, 58,188, 49,225, 28, 61,234,176,219,223,180,214,159,
+ 76,185,122,183, 2, 71, 8, 33, 76,142, 0, 11,133,204, 28, 48,231,108,223, 0,128,237,219,183, 83,174,234,107,108,239, 1,128,
+202,202, 74,116,233,210,133,212,214,214,162, 83,167, 78, 56,127,254,188, 75,198, 58,222, 75, 85,160, 40, 10,227, 95,136,103,220,
+ 48, 88,178,120,150,249,127, 71, 51,102,186, 10, 50,153,140, 94,115,100,141, 75,101, 78,155, 54,205,228,117,145,123, 1,208,155,
+ 14, 34,147,201,104,139,123, 28,250,193,242, 29,185,109, 45,185,135,113,245,103,101,101, 81,178, 67, 47, 19,142,252,239,129, 2,
+240, 8,161,197,157,244, 97,205, 63,238,234,231,186, 7, 94,152,123, 90,111,166, 57,126,243,119, 92,189,122,245, 1,191, 17,154,
+122,184,229, 25,235,202,209,140,114, 77,226,211, 70,251, 88, 16, 91,215, 76,150,119,198,227, 48,144,220,190,125,219,252, 62,242,
+242,242, 92,246, 78,228,242, 53, 68, 38,155, 69,253,246,171,156,213, 7,156,221,222,213, 25,152,150,245,185,124, 76,104, 78,185,
+118,112,220,240,132, 49,166, 72,103, 97,132,154,231,249, 57,183, 63,216,182,169,187, 27,230,253,108,104, 28, 56,112,224,192,129,
+ 3,135,135, 3, 60,174, 10, 56,112,224,192,129, 3, 7, 78, 1,224,192,129, 3, 7, 14, 28, 56,112, 10, 0, 7, 14, 28, 56,112,
+224,192,129, 83, 0, 56,112,224,192,129, 3, 7, 14,143, 5, 26,173, 2, 96,114, 94, 59, 3, 91,193,132,156, 60, 78, 30, 39,239,
+254,201, 75, 72, 72,104,172,221,243,120,230,236,114,150, 75,205,152,108,138,150, 75,207,108,165, 15,246,242,242,130, 88, 44, 54,
+127,158,199,227,129,207,231,223, 37,143,217,152,137,166,141,171,188,154,218, 44,135,123,191, 77, 67, 46, 95, 43,225, 11, 68, 32,
+180, 30, 51,103,190,145,225,140,188, 53,107,214, 72,207,159, 63, 47,136,136,136, 72,183,206,186,231,164, 60,201,249,243,231,177,
+122,245,234, 12,174,191, 61,122,242, 28, 86, 0,254, 23, 17, 20,244, 70,163,138, 43, 47,223, 64, 61, 84,242,222, 8, 34, 0, 80,
+190,161,156,178,252,191, 5, 34, 91,152,220,243,158,203,251,159,197,186,229, 75, 37,101,151, 78, 96,152,127,153,162,157,190, 16,
+217,164, 11, 78, 55, 4, 72,125,194,159,198,156,249,239,103,216,251,252,177, 99,199, 48,100,200, 16, 51,241, 51,132, 77, 81,212,
+ 93,132, 77,211,180,249,184,121,243,166, 77,121,103,206,156, 65,100,100, 36,220,221,221, 33, 16, 8,192,231,243, 27,201,100, 72,
+223, 96, 48,152, 15,141, 70,131,172,172, 44,132,133,133, 61,118,239, 71, 46,151, 83, 50,153,140,172, 89,179, 70,242,215, 95,127,
+225,250,245,235, 10, 63, 63, 63,108,218,180,169, 69,237,127,237,218,117, 18,145, 56, 0,126,254, 79, 40, 26,234,139,165,107,215,
+174,151,172, 90,229, 88,238,135,213,171, 87, 75,146,147,147, 15,103,103,103, 99,207,158, 61, 8, 15, 15,199,123,239,189,199,183,
+ 92,123,239,132, 60, 69, 94,110, 14,194, 66,187, 66, 40, 18, 97,238,220,121,207,198,199,199, 43,184,158,250,152,122, 0, 30, 37,
+ 68, 69, 69,217,213,120, 14, 30, 60,104,183, 99, 50, 4,109, 77,220,206,194,213,242,238, 1, 40, 7, 73,219,110,106, 89, 23,203,
+ 99,243,121,235,239,127,180,137,101,205, 26,201,149, 99, 7, 80,176,245, 91,133, 82,169,129,238,105, 30,220,219, 83,232, 86,112,
+ 1,255,240, 38,138,170,178, 63,209,118,205,255,147, 78,154,245,121,179, 74,192,149, 43, 87,192,231,243, 49,116,232, 80, 8, 4,
+ 2,243,193, 40, 4,140,213,175,215,235, 97, 48, 24,160,211,233,112,243,230, 77, 28, 62,124,216,166, 60,165, 82,137,179,103,207,
+ 98,224,192,129, 16, 10,133,112,115,115,107, 36,147,166,105,232,245,122,232,245,122,232,116, 58,168, 84, 42,156, 61,123, 22,245,
+245,245, 15, 3, 89,243, 76,109,131, 7, 64,223,146, 60,244,114,185,156, 74, 72, 72,160, 19, 18, 18, 16, 24, 24,136,127,253,235,
+ 95,152, 60,121, 50,234,234,234, 16, 24, 24,232, 84, 6,210,192,192, 64,243,243,124,252,241, 71,248,101,115, 22,220,221, 91,129,
+207, 23, 42,234,235, 10, 29,150,121,234,212, 41,212,215,215, 99,224,192,129, 55, 71,142, 28,217,166,162,162, 2, 7, 14, 28, 48,
+204,156, 57, 19,235,214,173,107,182,143,104,242,115,238,170,155,139,215,174, 33,195,219, 3,243, 19, 63, 47,124,170, 95,239, 14,
+183,138, 74,113, 32, 53,227,240,150, 45, 91, 71,198,198,190,124,136,163,206,135, 31, 76,234, 95, 43, 79, 1, 43, 5,192, 58,117,
+171,189,243,251, 78,254,111,190,249,102,179,247, 84, 85, 85, 1, 0, 97,163, 4, 48,100,221, 82,107,253, 94,200,179,180,252, 93,
+ 96,253, 59, 74,218,108,201,218,213,242, 44,239,181,252, 11, 0,168,172, 52,102, 70, 12, 8, 72,127, 44, 58,106,254, 31,233, 8,
+ 43, 84, 40, 10,149, 52, 38,134,241,241, 68,176, 30,116, 0,129, 91, 0, 31,117, 21, 66,184,215,169,208,227,252, 10,197, 47,137,
+ 9,210, 87,231, 45,108, 82, 9,160, 40, 10, 87,175, 94,133, 80, 40,196,179,207, 62,107, 38,109, 55, 55, 55,240,120, 60, 16, 66,
+160,211,233,160,215,235,161,209,104, 80, 88, 88, 8,133, 66,209,228,150,202, 60, 30, 15, 58,157, 14,231,207,159,199,208,161, 67,
+225,238,238, 14,145, 72,100,150,199, 40, 0, 26,141, 6,245,245,245,184,120,241, 34,212,106,181,121,154,128, 13, 98, 99, 99, 37,
+124, 62, 95, 81, 87, 87, 7,161, 80,136,210,210,210,183, 39, 78,156, 88, 39, 22,139,127,113,134,180, 99, 99, 99,167,240,249,252,
+109,169,169,169,140,188,236,137, 19, 39,254, 37,151,203, 39,203,100, 50,173, 51,150,112, 66, 66,130, 98,225,194,133,165, 48,237,
+ 56,147,144,144,128, 43, 87,174,160, 85,171, 86,136,136,136,192,207, 63,255,236, 48,249,255, 56,125, 58,158,127,234, 41, 0, 64,
+235, 57,115,224,238, 17,130,250,218, 2,212,214,228, 74,227,227,103,100, 52,149,207,189, 41,244,233,211, 7,165,165,165, 56,118,
+236, 88, 39, 30,143,135,139, 23, 47, 34, 32, 32, 0,153,153,153,120,237,181,215,200,249,243,231,155,253,124,197,215,243, 27,157,
+123,105,117,104,171, 87, 99,238, 7,159,118, 72, 92,242,111,124,187,100, 21,218,241, 12, 88,181,100,105,250,107,175,189, 6,123,
+242, 56, 60,124,228,207,148,179,221, 11,224,174,252,223,246,206,239, 39, 92,185, 83,223,163, 0, 75, 37,224, 62,121, 2, 28,181,
+212, 41, 59,214,185, 51,242,108,253,125,172, 18, 87,125,191,248, 43, 73,248,249, 31, 21,165,124, 3,194,124,129, 78, 29, 9,248,
+125,132, 16,116,237, 10,161, 70, 13,205,241, 66,104,106, 4,224,211,110, 80,167,255,162, 88,183,114,137,116,230, 91,182,167, 3,
+ 24,247,124, 78, 78, 14,252,253,253, 33,149, 74, 33, 22,139, 33, 20, 10, 33, 16, 8,204, 86,191, 90,173, 70, 73, 73, 9,142, 28,
+ 57, 2, 30,143, 7, 30,143,135,230,228, 25, 12, 6, 92,190,124, 25, 67,134, 12,129,143,143, 15,196, 98, 49,248,124, 62,244,122,
+ 61,180, 90, 45,106,107,107,241,231,159,127, 66,163,209, 64, 32, 16,152, 99, 1,236, 97,232,208,161,146,107,215,174, 41,110,220,
+184,129,218,218, 90, 8,133, 66,180,110,221,122,197,209,163, 71, 49,104,208, 32,129, 92, 46,255,201, 17, 37, 96,232,208,161, 19,
+174, 93,187,182,205, 74, 94,248,209,163, 71,195, 7, 13, 26,180,197,164, 4,176,146,183,122,245,106,137, 86,171,197,237,219,183,
+ 25,151,183,185,146, 22, 46, 92, 88,156,144,144,208,110,242,228,201,207,190,251,238,187, 14,141,127,235,214,255, 36,249,104,193,
+251,141,202,110, 47, 95,142,214, 47,182,199,183,223,126, 47,157, 62,253, 21,167,198,211, 99,199,142, 41,254,248,227, 15,124,244,
+209, 71,181,124, 62,223, 71, 44, 22, 99,208,160, 65, 80, 40, 20, 72, 77, 77, 69,187,118,237, 28,232,121, 20, 54,229,220,194,206,
+235,197,216,253,219,207,224,243, 41,204,159,243, 42,221,183,117, 16,111,237,220, 79,177,206, 81,121, 28, 30, 8,249, 91, 43,145,
+182,148, 2,167, 87, 1, 60,232,237,109,187,118,237, 42,181,119,220,111,107,253, 94,200,115,161,213,207,150,180,157, 33,107, 88,
+ 90,231,140,133,110,146, 67,156,148,215,228, 64, 29, 16,144,238,148,245,191,114,229, 74,201,140, 25, 51, 72, 83,101,214,215,154,
+130,229,253, 43, 87,174,148, 88, 95,179, 46,107,182,190, 46,159, 81,148, 20,215,162,149,183, 0, 93,189, 9, 4, 65, 52, 4,207,
+ 60, 7,207,190,191,192,189,223,119, 16,249,186, 67, 88,175,130, 82,105, 64, 71,190, 18,153, 73, 77,167,146,229,241,120, 16, 8,
+ 4,112,115,115,195,245,235,215,113,241,226, 69,248,248,248, 32, 48, 48, 16,129,129,129, 8, 10, 10,130,159,159, 31,106,106,106,
+144,153,153, 9, 62,159,111,158,219,183, 5,230,186, 80, 40,132,193, 96, 64,118,118, 54, 60, 60, 60, 16, 20, 20,132, 86,173, 90,
+ 33, 56, 56, 24, 94, 94, 94,200,206,206,134, 78,167, 51, 79, 17, 52,165, 80, 88, 91,254,119,238,220, 81,228,230,230,162, 75,151,
+ 46, 24, 61,122, 52, 6, 12, 24, 0,165, 82,137,195,135, 15,227,252,249,243, 27,212,106,245, 43, 14, 88,254,210, 59,165,101,255,
+205,187, 85, 3,239,176,129, 8, 31,253, 6,218, 13, 24,143, 42, 13, 15, 7,211, 15,225,252,249,243, 19,213,106,245, 76,182,228,
+ 95, 91, 91,139, 11, 23, 46, 40,142, 29, 59,134, 62,125,250, 32, 33, 33, 33, 8, 0,109,242, 0,180, 3, 0,177, 88,204,154,172,
+215,173,255, 73,178, 41, 41, 69, 18, 16,216, 91,145,180,245, 2,166,255,248, 35, 82,207,158, 69,234,217,179,104, 61,103, 14, 0,
+ 64,167,107, 56,226, 76,159,123,225,133, 23,200,238,221,187, 49,105,210,164,155,222,222,222, 60, 15, 15,143,172, 83,167, 78,225,
+216,177, 99, 40, 47, 47, 71,120,120,184, 99, 74,233,217,235, 88,242,251, 37,172, 91,242,241, 5, 1, 95, 5,158,161, 14,223, 44,
+251,145,183, 45, 51, 11, 37, 60, 1,158,120,226, 9,142,101, 31, 19, 8,156, 37,248, 7,181,121,197, 61,179,176,255,183, 21,129,
+123, 50,175,222, 66, 87, 61,101,167,220, 33,165, 98,201,146, 37,146, 67,135, 14, 41,114,114,114,154, 44, 59,117,234, 20, 43, 89,
+204,125,167, 78,157, 66,101,101,165, 98,201,146, 37,210,247,223, 55, 90,229,182,202,154,131,143,186, 2,169, 5,106,180,171,226,
+227, 41, 31, 10,193,101, 64,152,192, 23, 60, 42, 16, 68,125, 7, 13,119, 40, 92, 46,160,113,187, 65, 13, 1,143,135, 39, 3, 68,
+138,166,126,183,165, 2, 32, 18,137,144,155,155,139,118,237,218, 33, 42, 42, 10,124, 62, 31, 52, 77,163,162,162, 2,199,142, 29,
+131,155,155, 27,132, 66, 33,180, 90,109,147, 10, 0,227, 29,195, 12, 20,226, 0, 0, 32, 0, 73, 68, 65, 84, 96,148, 0, 66, 8,
+242,242,242, 16, 22, 22, 6, 95, 95, 95,212,215,215,227,236,217,179, 48, 24, 12, 16,137, 68,208,104, 52,208,104, 52, 77,142, 29,
+ 76, 16, 29, 0,148,149,149, 41,138,138,138,208,183,111, 95, 72, 36, 18,180,111,223, 94,218,208,208,128,224,224, 96, 69,122,122,
+ 58, 78,158, 60, 9, 63, 63,191,129,114,185,124,179, 76, 38,179,187,191,123, 89, 89,217,225, 59,149, 53, 8, 8, 31,136,174, 67,
+ 95,130, 95,251,112,104, 26,170, 81,240,199, 94, 92, 63,244, 51, 35,143,213,251, 53,197, 62, 40, 74, 74, 74, 16, 18, 18, 2,177,
+ 88, 44,189,112,225,130, 34, 33, 33,129,103,242, 0, 0,192,181,132,132, 4,154, 77, 27, 92,191,225,103,137,159,255, 19, 10,191,
+128, 39,192,227,185, 65,167,107,192,134,159, 20,152,254,186,148,241, 40, 96,230,204,153, 8, 14, 14,166, 29,237,123,175,190,250,
+ 42, 73, 74, 74,194,208,161, 67,209,175, 95,191, 78, 0,244,135, 14, 29,138,204,207,207,135,187,187, 59,220,221,221, 17, 29, 29,
+253,236,246,237,219, 15,179,145,183,249,175, 66,124,247,231, 53,172, 95,180,160,178,253, 19,157,250, 52,212, 87,225,183,125,127,
+226,194,197,191,224, 71,104, 8,111,223, 65,244,219,113, 35,183,109,219,254,191,229,130,125,132, 96,107,250,168, 41,175, 64, 83,
+170, 58, 53,121,242,100, 75, 11,154,138,137,137,105,238,252,145, 69,121,249, 6,202,242,120,216,228, 1,247,196,253,223,156,213,
+222,162,103,118,214, 58,119,196, 3,224, 40, 98, 99, 99, 37, 41, 41, 41,141,200,223, 86,153, 51,200,201,201, 65, 74, 74,138, 34,
+ 54, 54, 86,210, 92, 89,147,196, 85, 94,136, 19,183, 84, 80, 26,104, 28, 45,164,113, 91, 47,128, 65,147,133,170, 43,111,226,231,
+ 57,241,216,115,160, 6, 23, 43, 8,206,149,233,113,185, 66,143,138,146,219,205,122,229, 44,149, 0,177, 88,140,155, 55,111,226,
+218,181,107, 0,140,113, 49,191,255,254,123,163,185,252,230,230,235, 41,138, 50,123, 1, 24,121,132, 16, 20, 22, 22,162, 99,199,
+142, 40, 41, 41, 1, 77,211, 16,139,197,102, 89,205, 77, 41, 88,162,160,160, 0,106,181, 26,145,145,145,104,223,190,189,148,207,
+231,195,199,199, 7, 79, 63,253,180,212,203,203, 11, 5, 5, 5,168,173,173,189,200,182, 29, 20, 20, 20,128,230, 9,209, 46, 98,
+ 36,252,218,135,131,199,119,131,187, 79, 48, 58, 62, 29, 13,161,167, 63, 35, 47,223,158,156, 53,107,214, 72,170,171,171, 21,197,
+197,197,232,208,161, 3,164, 82,169,244,151, 95,126,201,168,168,168,160, 0, 96,224,192,129,122,211,173,225,190,190,190,144,203,
+229,118, 3, 30,196,226, 64, 4, 6,247,133, 65,175, 65,233,173, 83,184, 93,124,108, 68,121,217,217,143, 77,242, 0, 0,119,110,
+223,134, 73,158, 27,219,182, 39,147,201, 38, 39, 37, 37, 33, 46, 46, 14, 83,167, 78, 5, 0,250,192,129, 3,130,148,148, 20, 76,
+159, 62,125,212,153, 51,103,168,227,199,143, 83, 9, 9, 9,172, 34,247,179,107,149, 88,112,228, 28,190,126, 47, 30, 67,199,142,
+ 12, 48, 16, 61,182,255,247, 8,126, 88,241, 11,246,205,123, 13,235,250,118, 68, 71, 95, 1, 62,254, 56,129, 11, 2,124, 68,112,
+238,220,185, 38,201,191, 89, 15,128,245,220,190,189,243,199, 17,247, 96, 9,158, 83,248,242, 31, 95, 74,103,205,154,245, 40,212,
+119,163, 41,133,123, 28,164,199,234, 61, 68, 71, 71, 75,174, 95,191,174,208,106,181,205,150,181, 4, 85, 85, 85,104,104,104, 80,
+ 68, 71, 71, 75, 11, 11, 11,239, 42,219,187,119,111,147,239,238,124,165, 10, 53, 90, 26,231,203,244, 40,169,214, 35,228,119, 1,
+250,108,207,193,205,252,203,248,235, 15, 45,244, 2, 62,180, 52,160,214, 18, 84, 17, 26,193,205,108,107,207, 44,247, 99,230,238,
+153,136,253, 59,119,238,160, 83,167, 78,200,207,207, 55,187,252, 5, 2,129,249,126, 71,167,243, 44,115, 8, 48,127,239,209,148,
+ 96, 53, 92, 27,243, 97,151,172,105,154, 70, 67, 67,131,113,112, 20, 8,164,111,190,249,102,163,119, 87, 87, 87, 39,216,189,123,
+ 55,198,143, 31,207, 91,176, 96,193,157,197,139, 23,235,237,181, 69,138, 50, 42, 68, 42,229, 29,212,215, 21, 74,103,204,120, 45,
+ 67, 46,151,103, 2,248,186,174,174, 14,187,119,239, 54, 43,142, 97, 97, 97, 90, 54,109,123,209,162, 69,227,191,253,246,219,228,
+232,232,104, 12, 25, 50, 4, 0,232,227,199,143,243,126,253,245, 87, 72, 36,146,177, 43, 87,174, 60,232, 72,197,220, 82,106,240,
+106,234,239,152, 59, 37, 26,147, 95,157, 4,165,186, 22,187,118,103, 96,217,170,205,248,207,168,127,160,107,105, 17,199,166,143,
+129, 50,192,214, 3,224,106, 16,171,142,108,239,156,131, 5,238, 53,249,187,208,106,111,202,163,224,236,252,127,115,237,130, 85,
+123,217,187,119,111, 70,183,110,221,164,254,254,254,205,150,181, 4,254,254,254,232,214,173, 91, 35,162,183, 85,102, 11, 42,131,
+ 15,116, 20,112,186, 92,131, 82,131, 1,135,242,212,216,158,172,198,225,162, 96,228, 8,125, 81, 84,163, 67, 97, 29,141, 6, 61,
+160,212, 19,136, 2, 91,219, 37,102,102,125,191,193, 96,128, 94,175, 71, 96, 96, 32,188,188,188,208,169, 83, 39,232,116, 58,115,
+185,173,132, 64,214,242,152,245,253,122,189, 30, 42,149, 10,132, 16,116,232,208, 1,197,197,197,104,211,166, 13, 4, 2, 1, 52,
+ 26, 13,180, 90,173,249,123,217, 76, 15,118,236,216, 17, 98,177, 24, 89, 89, 89, 40, 42, 42, 82, 24, 12, 6,212,214,214, 82,127,
+252,241,135,162,190,190, 30, 29, 59,118,132,143,143,207,115,108,199,168,142, 29, 59,130, 71,107, 81,124, 54, 29,213, 69,217,160,
+ 13, 58,168,106,203, 80,240,199, 94,104, 27,170, 24,121,157,217, 40, 55, 12, 2, 3, 3, 21,171, 87,175, 54,123,113, 42, 42, 42,
+168,203,151, 47,195, 68,218, 52,128, 16, 91, 9,143,172,161,215,171,160,215,213,195,221,179, 53,196,238, 1,144,203,215, 74,100,
+ 50,153,126,225,194,133,129, 22,242,176,110,221, 58,212,212,212, 48, 75, 24,239,194,194,133, 11,201,224,193,131, 73,191,126,253,
+200,231,159,127,254,219,248,241,227, 49,118,236, 88, 0,192,153, 51,103,106, 83, 82, 82, 48,121,242,228,241,135, 14, 29,218,203,
+166,206, 22, 46, 92, 72,134, 12, 25, 66, 94,126,243,109, 60,187,227, 8,222,255,231, 68,188,243,225,108,168,181,245,184,145, 91,
+ 8,185,124, 59,126, 29, 55, 8,146, 14,173,156,238, 27, 99,198,140,225,198,245, 7,136,136,136,136, 70,164,111, 29, 8,120, 95,
+ 83, 1,199,196,196, 72, 28, 57,191,111,150,126, 19,107,246,173,173,125,182,214,127, 83,242,222, 8, 10, 34,111, 4,253,237,206,
+183, 62,183,231,137,112,149,188, 38, 44,105,103,136,250,158,193, 74,137,112,218, 3, 0, 0, 91,182,108,201, 24, 55,110,156,212,
+ 50, 57,141,173, 50,103, 16, 22, 22,134,113,227,198, 73,183,108,217,146,209, 92, 89,147,159,239, 22,134,110,158,124,120, 83,128,
+142, 16, 92,173,210, 34, 41, 71,131, 45, 39, 74,240,103,110, 37, 74, 84, 64,133,218,128,220,122,130, 91, 26,130,122,173, 78,218,
+ 28,121, 49, 75,243,180, 90, 45, 84, 42, 21,218,180,105,131,222,189,123,155, 20,189, 0, 12, 24, 48,192, 76,216, 12,105, 55, 69,
+216, 12,161,235,116, 58,104,181, 90, 80, 20,133,208,208, 80, 84, 87, 87,163,176,176, 16,149,149,149,232,220,185, 51,120, 60, 30,
+180, 90, 45, 52, 26,141,249, 51,246, 16, 28, 28, 44,109,223,190, 61, 46, 95,190,140,253,251,247, 99,207,158, 61,138, 61,123,246,
+ 28, 62,122,244, 40,248,124, 62,158,121,230, 25,116,237,218, 85, 5, 83,224, 29, 11,121,227, 67, 2,124, 81,145,119, 14,127, 29,
+252, 9,151,247,174,198,213,189,114,220, 60,249, 43, 68, 60,154,145, 87,108, 79,206, 91,111,189,149, 17, 18, 18, 34,245,241,241,
+193,249,243,231, 81, 84, 84,164, 72, 76, 76,148, 88, 42, 2, 38, 79, 0, 47, 41, 41, 9,189,122,245,178,251,108, 90, 77, 13,106,
+170,115,224,230,230, 9,191,128,238, 10, 79,175,118,248,241,199, 77, 18,138,226, 13,100,238,241,174, 78,135,226, 63,239, 32,170,
+123,125,147,109,123,239,222,189,112,119,119, 71,175, 94,189,208,185,115,103,102,250, 64, 95, 85, 85, 85,191, 99,199, 14,191,136,
+136,136,241,219,182,109, 75, 97,219,118, 83, 83,247,194,199,199, 11,195,134, 63,173,140,232,215, 7, 19,222,156, 14, 37,165, 71,
+ 89,105, 37,102,205,249, 2,139,251,135,161, 95, 43,231,149,228, 49, 99,198,144,111,190,249,134, 83, 2, 30, 18, 69,192, 22, 30,
+154,189, 0, 30,244,170, 2,103, 8,216, 81,108, 40, 55, 42, 16,150, 68,205,148, 61, 12,242, 30, 86,143,130,149, 39,128, 56,226,
+ 1, 96,240,254,251,239,103,140, 24, 49, 66, 58, 96,192,128, 38,203, 44,175, 53, 7,203,251, 71,140, 24,209, 40,216,207, 86, 89,
+179,214,161,200, 83,250,100,155, 32, 12, 14, 20,225, 31,254, 66,180, 21,243, 32, 34, 4, 98,141, 30, 29,189, 4,168, 34, 4,151,
+234,245,200,110,208,163, 93,171, 64,116,254,199,240, 38,101, 49, 86, 63,179,212,175, 99,199,142,232,219,183, 47,170,170,170, 80,
+ 93, 93,141,234,234,106,120,123,123, 99,224,192,129,208,106,181,230,156, 0, 77, 17, 54,163, 76,232,116, 58, 80, 20,133,240,240,
+112,168, 84, 42,148,149,149,161,180,180, 20,101,101,101,104,104,104, 64,120,120, 56, 4, 2,129, 89, 94, 83,121, 5,172,149,178,
+144,144, 16,105,104,104, 40,110,220,184,129,180,180, 52,156, 58,117, 10, 30, 30, 30,120,246,217,103,209,183,111,223,189, 98,177,
+120, 62,219,101,123, 91,182,108, 73, 9,105, 21,252, 74,104, 27, 63,212,231,254,129,236,180, 13, 40, 62,245, 27,252, 69, 6,140,
+ 28,241, 44,250,246,237, 59,237,221,119,223,221,205, 70,150,143,143, 15,250,245,235, 7, 66, 8, 78,156, 56,129,172,172, 44, 69,
+113,113,177,226,235,175,191,150, 36, 36, 36, 72,153,204,137,253,251,247, 71,102,102,166, 93,121, 51,103, 78,207,168,169,202,145,
+ 86,150, 93,132, 72, 28,128,214,109,159, 81, 4,183, 30,160,240,246,233,188,247,219, 37, 63,140, 99,228,109,121,215, 3, 91,143,
+107,208,148,210,147,157,157,141,160,160, 32, 12, 25, 50,132,254,199, 63,254, 1,165, 82,137,134,134, 6,172, 88,177,194,171,123,
+247,238, 47, 42, 20,138, 20, 71,250,196, 95,127,101,163, 83,199,246,120,249,229,241, 30,159,252,107, 46, 42,234,106, 80, 94, 81,
+142,248,119,190,192, 23, 19, 70, 96, 68,199,144, 22,145,255,178,101,203,208,187,119,111, 44, 95,190,156, 83, 2,238, 35, 44,231,
+253,237,225,190,101, 2,116,229,170, 2, 83,114, 31,151,100, 2,180, 7,235, 68, 60,174, 80, 2, 92, 73,214,174,150,231,138, 87,
+ 13, 23,164, 7,182, 82, 32,168, 38, 60, 22, 14,225,173,183,222,202,176,254,156,101,217,250,245,235, 89,201,100,238,179,117, 63,
+ 91, 25, 12, 54,110,217,150,177,224,213, 41,208,159, 74, 69,126, 13,224, 69,185,161,147, 23, 15,197, 6, 10,124,145, 0,153,165,
+ 6,168,105, 32, 88,196, 71,104,255, 97,120,119,201,186,140,230, 20, 0,157, 78, 7, 62,159,143, 46, 93,186,160, 95,191,126,168,
+173,173,133, 90,173, 54,175,207,215,106,181, 8, 8, 8,192,144, 33, 67,144,146,146, 98,158, 18,176, 5,131,193, 96,206, 34,216,
+163, 71, 15,152,220,244, 80,171,213,230,254,204,120, 18,122,244,232,129,202,202, 74,212,215,215, 55,217,151,173,201,252,232,209,
+163, 25,177,177,177,207,246,234,213,235,176, 69, 34,160,234,161, 67,135, 30, 22,139,197,113, 50,153, 76,237, 72, 93, 30, 61,122,
+ 52, 41, 54, 54,182,182, 87,175, 94,187, 45,228,149, 15, 29, 58,116,197,187,239,190,203, 58, 91,207,236,217,179, 51, 86,175, 94,
+ 45, 29, 61,122, 52,110,220,184,161,184,118,237, 26, 10, 10, 10,224,237,237,173,240,243,243, 67, 84, 84, 20,214,175, 95,143,254,
+253,251,179,126,182, 55,222,120, 53, 99,253,250,141, 82,181,186, 18,126,254,225, 10, 47,239, 14,240,246,233,136,134,186,226,148,
+ 69,139, 55, 32,246,229,145,216,242,174,135,185,158,108, 89,108,207, 63,255, 60, 82, 83, 83, 81, 84, 84,196,171,172,172,132, 90,
+173, 70,102,102,166,192,164,116,214, 30, 63,126,220,161,254, 16, 29,253, 60,118,237, 74, 65,109,117, 5,138, 74,110,225,221,183,
+254,169,253,224,163,133,194, 9,207, 14,194, 16, 77, 45,224,230, 28, 61,140, 25, 51,134,124,246,217,103,230,116,208,161,161,161,
+248,230,155,111, 0,128,236,219,183,143, 75, 27,254,128,148,130, 7,169, 0, 80,147, 39, 79,182,116,161, 81, 86,238,126,202, 81,
+247,191, 43,200,221, 76,242,229, 27, 96, 47,219,158, 35,193,127,229,229, 27, 96,233,138,183, 36,102,107,151, 61, 27,210, 46,223,
+ 80,238, 82,121,143, 0,254,167, 6,137,206,131,164,210, 11, 26,189,162,236,240, 33,184,233, 85,184, 80, 71,144, 94,167,135,144,
+162, 16, 72, 8,164,109,252,224,223, 58, 88,218,254,105, 9,176,113,155, 93, 15, 64,231,206,157, 49, 96,192, 0,168, 84, 42,232,
+116, 58, 8,133, 66, 51, 97, 51, 86,122,112,112, 48, 6, 15, 30,140,180,180,180,102, 61, 0, 2,129, 0,125,251,246, 5, 69, 81,
+ 80, 42,149,102,239, 2,163,180, 51,217, 5,105,154,198,147, 79, 62,137,223,127,255, 29,142, 4, 87,110,217,178, 69, 1,128,146,
+203,229, 20, 0, 47, 24,179,237, 21,200,100, 50,157, 51,117,185,101,203,150, 20,147, 60, 47, 0, 1, 0, 42,101, 50,153,195,185,
+137,103,207,158,157, 1, 0, 43, 87,174,148,186,185,185, 33, 47, 47, 15, 1, 1, 1, 10, 0, 40, 46, 46,198,152, 49, 99,176,116,
+233, 82,135,100,206,152, 49, 45, 67, 46, 95, 43,209,106,107,164,238,181,249, 10, 31,191, 80,120,120,181,133,135, 87, 91, 28, 56,
+116, 7,212,136,230, 45,238,159,127,254,153,154, 57,115, 38,169,172,172,196,243,207, 63,175, 13, 12, 12, 20,210, 52,141,130,130,
+ 2,135, 61, 98, 0,176,113,227,207,148, 76, 22, 79,124,174,100,225,173,183,222, 64,251,240,110,194,111,230,190, 65,111, 92,245,
+ 51,111, 5, 95,237, 84, 91, 30, 51,102, 12, 89,176, 96, 1,252,252,252, 80, 82, 82, 2,119,119,119,208, 52, 13, 79, 79, 79,124,
+245,213, 87,156, 18,112, 31, 16, 17, 17,209,164, 23,128,109, 42, 96,151,227, 33, 95, 85, 64,149,111, 40,183,121,193, 73,235,159,
+218, 80,126,183, 60,107, 75,157,113,221,179, 32,109, 87,203,227,240, 16,193, 68, 54,212, 75,209, 99, 36,190,122,141,130,127, 51,
+ 15, 97,186, 91,240, 14, 12,193,160, 39,187, 35,176, 93,144,244,195,213,155, 51,182,158,154,109,215,139,214,165, 75, 23, 12, 25,
+ 50,196, 60, 31,207,231,243,161,209,104,204,169,123, 45,167, 9, 58,116,232,128,193,131, 7, 35, 35,195,118,215,115,119,119, 71,
+ 68, 68, 4, 4, 2, 1,180, 90,173,249,115,150, 75, 7, 45, 55, 2,226,241,120,120,234,169,167,144,149,149,229,112, 29,152,188,
+ 3,117,166,163,197, 48,145,126,139, 55, 37, 48,121,136,204,253,112,245,234,213, 18,165, 82, 9,141, 70,131,238,221,187, 35, 49,
+ 49, 81,225,216,115,197,103, 0,128, 92,190, 86,170, 82,149, 65, 36,242,135,155,208, 91,193,227, 9,176, 41,105,175,244,149,184,
+232,102,229,173, 91,183,142,146,203,229,212,119,223,125, 71,171, 84, 42, 0, 64,120,120,184, 67,233,151, 45, 33,151,175,165,214,
+175, 95, 55,102,250,103,223,165, 26,229, 17, 94,120,248, 19, 8,127,241,197, 87,222,122,235,173, 36,103,100, 46, 94,188,152,235,
+212, 15,137, 18,208, 28,249,223, 87, 5,224, 81,133, 43,151,253, 89, 19,115, 75,137,218,133,242, 92,173, 48,112, 10,136, 19,216,
+182,119, 95, 70,163,186,171, 45,192,209, 27, 5,172, 63, 31, 19, 19, 3,127,127,127,115,132, 63, 77,211,102, 23, 62,227, 1, 96,
+130,254,152, 29, 1, 67, 67, 67, 65, 81, 20,182,110,221,122,151,188,101,203,150, 33, 57, 57,217,124,175,193, 96,176,187, 29,176,
+ 80, 40, 68,255,254,253,193, 38, 58,254, 17, 86,214, 90,220,214, 25, 69,192, 72,234, 27, 96, 12,199,162, 21,108,228,153,148, 37,
+ 10, 0, 86,175, 94, 77,102,207,158, 77, 29, 58,228,252,210,252, 25, 51,102,238, 51,121, 77,120, 52, 77, 27,120, 60,158,187,163,
+211, 47, 12, 56,235,254,225, 82, 2,236, 14,212,206,238, 35,204,129, 3, 7, 14, 28, 56,112,120,116,193,227,170,128, 3, 7, 14,
+ 28, 56,112,224, 20, 0, 14, 28, 56,112,224,192,129, 3,167, 0,112,224,192,129, 3, 7, 14, 28, 56, 5,128, 3, 7, 14, 28, 56,
+112,224,240, 88,160,209, 42,128,115,231,206, 57, 29,193,105, 43,152,144,147,199,201,227,228, 61,150,242,200, 11, 47,202,240,219,
+175,114,200,229,114,158,173,108,125, 92,253,113,242, 58,118,236,104,190,167,160,160,128,226,234,239,254,202,115, 88, 1, 96, 58,
+119, 51,247, 59,243,128,143,178, 60,103,100, 62,236,191,183, 17,228,114,185, 16,128, 15, 0, 15, 83,123,160, 1,148, 59,147, 60,
+229, 30,131,184,234, 55, 55, 81,167, 15,100,249,210,146, 37, 75, 36, 39, 78,156, 80, 28, 57,114, 4, 0, 48,124,248,112, 12, 26,
+ 52,136,117, 42,225, 7,241, 30, 94,120, 81,134,231,199,244,211, 3, 50,129, 76, 38,163,193, 45,251,228, 96,133,142, 29, 59,146,
+113,227, 66,205,231, 41, 41, 32,246,148, 0, 14, 15,216, 3, 96,238,225,219,239,222, 0,130,154, 82,213,146,239,161,156, 32,222,
+251, 38,207,214,239,109,225,111,126,168,127, 47, 67,252,151, 47, 28,253,105,251,150, 21, 35, 90,183, 11, 13,169,169,209,193,215,
+215, 13,183,139,115,233, 94,189,250, 86,202,229,242, 1, 50,153,236,134, 35, 50,101,211,250,146,188,220,108,228,230,171, 81,120,
+139,160, 67, 27, 10,161,157,197,232, 26, 26, 14,249,198,243, 15, 75,231,183,165, 72, 48,123, 13,220,247,103,188,120,241,162, 34,
+ 34, 98, 63,214,172, 81, 34, 35, 3,248,244,211, 3, 40, 44, 44, 84,140, 27, 55, 14, 98,177, 24, 37, 37, 37,210, 9, 19, 38,192,
+ 21, 10,193, 43,175,188, 66,106,106,106,164, 81, 81, 81,120,231,157,119, 50,156,104, 51, 60,153, 76,134,231,199,244,163,227,227,
+227, 5,192, 90,252,246, 43, 32,151,203, 41,182, 57,251, 57,252,239, 64,171, 93,128,180,180,120,140, 30,189, 22,227,198, 45, 70,
+ 74,138,177,239,113,138,192,253, 1,151, 8,200, 17,134,181, 32,123,138, 2,232,109,254,143,237,111, 93,177,124,233,171,123,118,
+255,152, 16, 22,214,173,251,196, 23,135,163, 67, 59, 31,248,249,138, 80, 85,173, 70,241,173, 14,188,235,121, 85, 65,123,118,255,
+168, 88,177,124,233,119,111,207,153,191,220,158,188,119,223,158, 42,185,145,189, 71, 81, 90,114, 30, 47, 69, 3,131, 35,129,208,
+ 78, 64, 78, 62,193,177,211, 42,164, 42,206, 99,252, 40, 31,210, 37,124,172,244,251, 21,155,157, 37, 50, 87, 90,254,148, 13,217,
+ 15, 68, 9,168,172,172,196, 59,239, 40, 17, 28, 12,196,196, 0,139, 22,213,227,236,217,179,208,235,245, 16,139,197,104,213,170,
+149, 98,207,158, 61,152, 57,115,166,116,221,186,117, 14,213,221,236,217,179, 37,151, 46, 93, 66, 72, 72,136, 98,199,142, 29,212,
+166, 77,155, 0, 64,145,158,158,142, 55,222,120, 3, 27, 54,108,112,244,183, 10, 1, 32,117,223, 25, 30,176,150, 54,254,189, 59,
+199, 63, 7,206,250, 7,128, 73,147,118, 34, 45,205,248, 55, 62, 62, 23,140, 71,128,243, 6,220, 95,226,183, 44,183, 86, 2,184,
+ 32, 64, 27, 94,128,199,153,252,229,114,185,224, 96,218,246, 79,164,195,250,117,159, 24, 29,142,190,189, 90, 33,208,223, 29, 20,
+ 40,248,120,137, 16, 30, 26,128,168,225,157, 49,124,200, 83,157, 14,166,109,255, 68, 46,151,183,182, 39,243, 70,246, 30,197,208,
+200, 90,108, 95, 1, 76,143, 1,186,155, 60,127,158, 30, 64,143, 48,224,243,121,192,192,190,181,184,145,189, 71,209,146, 87,212,
+ 82,175,135, 29, 69,226,129, 12, 72, 1, 1, 1,216,179,199, 29,101,101, 64,114, 50, 80, 85, 37, 64, 88, 88, 24,198,142, 29,203,
+108,247,138,140,140, 12,100,101,101, 41,150, 44, 89, 34, 97, 43,119,244,232,209,146,203,151, 47, 43,132, 66,161,162,170,170,177,
+ 39, 75,165, 82, 97,195,134, 13,144, 74,165,142,214, 39, 13, 0,191,253, 42, 71,234,190, 51,188,223,126,149,183,232,183,207,152,
+ 49,131, 48, 71,115,101, 44,219, 5,113,162,172, 89,172, 93,179, 70,178,118,222, 60,201,185,153, 51, 73,225,243,207,147,147,211,
+166,145,149,239,188, 35, 89,187,102,141,164, 37,191,185,165,109,198,150, 12,182,101,247, 90, 30,227,250, 31, 55, 46, 20,241,241,
+105,141,254, 50, 24, 55, 46,180, 81,124, 0,135,123,131,136,136,136, 70,135, 45,229,128, 83, 0, 30, 6, 22,184,143,184,124,225,
+232,162,176,176,176,240, 1,253,218, 52,110, 8, 60, 10, 66, 33, 31,238, 98, 1,220,220,120, 8,237,226,143,208,208,176, 86,151,
+ 47, 28,221, 35,151,203,155,244, 20,201,166,245, 37,124,212, 98,222,116, 64,173, 1,110, 20, 2, 85, 53, 64,117, 45,176,121, 55,
+ 48,231, 51, 32, 97, 9, 48,168, 31,192, 35,181,144, 77,235,203,117,124, 11, 60,249,228,147,210,223,126,235,129, 86,173,128,169,
+ 83, 5,104,221,250, 31, 24, 62,124,184,116,207,158, 61,212,216,177, 99,165,163, 71,143, 70, 72, 72, 8,206,156, 57,131,109,219,
+182, 41, 38, 77,154, 36,249,225,135, 31,154, 37,160,161, 67,135, 74, 52, 26,141,194,205,205,173,217,239, 86, 40, 20, 24, 49, 98,
+ 4, 27, 50, 35,113,113,113, 68, 38,147,105, 77, 49, 35,176, 32,127, 10, 0,226,226,226, 28, 86,208, 78,157, 58,101, 62,154, 43,
+115,178,219, 82, 45,233,222,107,215,172,145,116,189,118, 77, 49,225,220, 57, 69,135,236, 28, 8,107,107,209, 38,251, 26, 36,191,
+159, 84, 4,159, 63,175,144, 59,169, 4,156, 58,117, 10, 51,102,204, 32,115,230,204,113, 90,137, 96,100,176, 41, 99, 43,207,154,
+232,217,148,217, 3, 67,250,204, 95,237,184, 48,174,195,223, 71,226,103,131, 71, 85, 1, 32, 54, 14,151, 9,190,135,207, 71, 92,
+252,152,196,209,186,184,124,229,252,152,240,208, 0, 51,233,219,218,166, 89, 44, 18, 64,175,167, 17, 30, 26,128,203, 87,206,135,
+ 2,240,109, 74, 94, 94,110, 54,162,159, 53,254,191, 63, 19,120,227, 35, 96,205,102,160,228, 14,112, 45, 7, 56,123,153, 32,253,
+ 56,112,232, 4, 48,122,184,241,254, 22,232,102,212, 61,124,197, 15, 68, 49,121,255,253,247, 51,234,235,141,241,150, 83,167, 78,
+197,201,147, 39, 41,185, 92,158,193, 92,171,172,172,148,246,232, 33,192,204,153,192, 83, 79,157,134,193,112, 77, 81, 84, 84,212,
+164, 39,101,246,236,217, 18,138,162, 20,108, 55,135, 41, 45, 45,181,235,149,137,139,139, 67, 82, 82, 18, 0,144,204,204, 76,173,
+197,187,160, 24,226, 79, 74, 74, 66, 92, 92,220,131, 28, 15,156, 45,179, 9,205,165, 75,232,242,199, 31,166, 77,144,180,208,211,
+ 52,104,157, 1,180, 78,143,224,163,153,168,101,185,223,122, 83,132,251,231,159,127, 42,158,121,230,153,123,174, 4, 56,227, 93,
+104, 41,249,107,199,133,217, 60,210,226,211, 56,118,126,200, 96,211,178,107, 38,248,141, 56,105, 56, 19, 23,202,163, 30,130,193,
+165,217,103,176, 19, 84, 72, 92, 81,127,206, 4, 46,202,229,114, 65,102,230,190,158,109, 91,123,129, 16,224,232,201, 66, 40, 85,
+198, 93, 87,251,245,109,141,224, 64,119, 20, 22,215,209, 57, 55,170,120, 2, 1, 15,221,186,250,163,109,219, 48, 63, 24,183,104,
+181,137,220,124, 53, 6, 71, 2, 26, 29,176,239, 8,160, 56, 73,208, 54,132, 66,215,142,192,136, 33, 64,247, 80, 10, 2,190,113,
+107,241,129, 17,192,183,114, 53,219,250,166, 28,252,159,173, 18, 65,112,119, 44, 0,121, 64,109, 11, 0,152,237, 92,209,167, 79,
+ 31,169,245, 53, 62,159,175,232,217,179, 20, 9, 9,198,199, 92,184, 48, 27,249,249,189,154,148,165, 86,171,237, 90,254,150,200,
+207,207,183,123, 79, 82, 82,146,217,202,103, 20, 1,139,107,140,130, 64,153,174, 61, 12, 78, 59,170,165,227, 70,183,242, 10,133,
+ 86,167, 3,143,199, 3,225,243, 65,211, 52,116, 52, 13,218, 96,128,193, 64,163,253,173, 91,138,150,180, 23,165, 82, 9, 0,138,
+ 25, 51,102,128,162, 40,135,227, 59, 44, 9,127,253,250,245, 84,115,101,247,147,252, 1, 32, 45, 62, 13,163,215,142,198,164,157,
+ 64,124,154,241,127,134,252,181,227,194, 32, 76,201,225,152,247, 62,194,210,237,207,106, 59,224,166, 86, 1,180, 96,117, 64, 83,
+ 81,236,206, 68,183, 19, 59,131,187,211, 74, 67, 19,164, 74, 57, 99, 69, 52, 19, 84,232,140,188, 38, 63,195,124, 15, 5,128,222,
+110, 55,118,129, 54, 70,251,139, 0, 0,133, 37,181, 80,169,244, 0,128,176,174,254, 8, 14,116,199,249,203,165,188,191,174, 87,
+ 66, 44,230, 35,180,139, 31,170,106,180, 0,208,164,224,194, 91, 4,161,157,140,223,255,220, 48, 32,162, 39, 5,145, 16,208,235,
+129, 81, 67, 1, 63,111, 32,175, 0, 24, 61, 12,232,212,222,120,255, 3, 6,101,229, 61,121, 80,138,229, 61, 65,105,105,169, 67,
+253,176,174,142,253,238,187, 73, 73, 73,148,133, 18, 96,233, 29,120,224,117,215,181,107, 87,146,151,151, 71, 57,123,221, 26,110,
+185, 57,208,232,180,160,248, 2, 24, 8, 1, 5, 64,111,160,161,211,211, 32, 6, 3,168,235,127,185,228,185, 47, 93,186,132,160,
+160, 32,197, 55,223,124, 35,253,240,195, 15,157, 86, 2,172,167, 81, 28, 37,110, 87,145,127, 65, 65, 1,213,177, 99, 71, 50,105,
+103, 99,133, 0, 0, 70,175, 29, 13, 97, 74, 14, 82, 82,114,205, 43, 1,184, 88,128, 7, 71,254, 77, 42, 0,143, 0,154, 35, 81,
+135, 9,182,133, 75, 28,155,150,123,143, 87, 19, 80, 83,170, 28,253, 14,202,215,215, 13, 85,213,106, 4, 5,120, 32,102,124,119,
+232, 13, 52, 68, 34, 62,248, 60, 30, 8, 33, 24, 59, 42, 20,209, 81,161,160, 40,160,162, 74, 5, 95, 95, 55, 0,168,108, 74, 96,
+135, 54, 20,114,111, 18,116, 15, 5,158,125,198, 88,217,215,114,128, 62,221, 1,127, 31, 96,140, 4,160,105, 64,192, 7,178,111,
+ 24,239,207, 43, 36,108,223,173, 35,255,183,116, 32,121, 32,203, 0, 87,175, 94, 45, 89,178,100, 9,114,115,115,145,153,153,169,
+248,246,219,111,165, 94, 94, 94,230,109,103, 13, 6,131,244,202,149, 86,138,127,255,187, 24, 20, 69,161,180, 52, 28,225,225,157,
+145,157,109,123, 42,133,166,105,155,229, 35, 70,140,184,219,139, 68, 8, 14, 31, 62,236,208,111,182, 84, 2, 30, 38,242,119,133,
+146, 96,137,202,246,237, 32,188,246, 23,136, 27, 32,164, 9, 40, 10,208, 25,244,208, 18, 3,148,122, 61, 84, 97,221,129, 43,215,
+ 90,252,236,189,123,247, 6, 69, 81, 78,145, 63, 0, 12, 24, 48, 0,235,215,175,167,250,244,233, 67,154, 43,179,135,245,235,215,
+ 83,214,132,111,171,204, 17,196,167,253, 77,252, 0,238,178,252,153,128,193,148,148, 92,142,169, 31, 0,249, 3, 92, 16,160, 37,
+137, 88, 31, 45,182, 10, 9, 1,120, 47, 85,221,179,135, 38,219,253,141,223,193, 94,129, 17,220, 46,206, 45, 47, 44, 54, 90,125,
+ 75, 87,255,137,115,151, 74,161,211,209,160,105, 98, 82, 90, 40,115,108, 64, 97,113, 29,110, 23,231,222, 0,208,164, 89, 25,218,
+ 89,140,227, 89,198,255,131, 34,129,179,151,129,248, 88, 32,172,147,209,237,255,229, 10, 64,232, 6,240,120,192,241, 44,227,253,
+ 45, 32,104, 87,199, 80, 88,191,239,251,110,141, 92,185,114, 5, 98,177,177, 78,246,238,221,139,164,164, 36, 69, 70,134,145, 11,
+150, 44, 89, 34, 9, 8, 8, 80, 92,189,170,199,186,117,192,217,179,253,193,231,119,151,182,111,223, 94,218,148, 60, 79, 79, 79,
+214,223,173,215,235, 31,249,142,107, 73,254, 93,187,118, 37, 77, 29,142, 42, 11,185,193,173,164, 85, 90, 13,106,181, 90,168,180,
+ 58,104,244,122,232,136, 1, 74,157, 14,117, 90, 45, 74,218,182,149,182,228,185, 61, 60, 60,224,233,233, 41, 93,191,126, 61,229,
+140,251,223,146,232,237,149, 57,162, 4, 12, 24, 48,192,110, 25, 27, 47, 64, 83,228,111,105,253,115,120,176,228,207, 41, 0,247,
+ 1,247,122, 73, 33,217,238, 15, 2,214,138,134,190, 87,175,190, 37, 57, 55,170, 64,211, 4, 31,189, 59, 16,217, 57,149,184,154,
+ 93, 1,138, 66,163,128, 64,154, 38,200,185, 81,133, 94,189,250, 94, 2,208,164,159,184,107,104, 56,246,254,255,246,190, 61,190,
+137, 42,125,255,153, 36, 77,211,146, 66, 75,185, 22,173,180,220, 68,238, 20,176,138,151, 70,185, 24, 74,185, 54,226, 34, 46,120,
+107,101, 21, 88, 45,144,202, 46,138,174,126,165, 44, 8, 43,235, 37, 40, 55,127,187, 42,166, 5, 75,129, 90, 44,166,174, 8,168,
+ 84, 46,114, 81, 75,139, 20, 41,165, 80,232, 37,105,210,100, 50,231,247, 71, 50,101,154,230, 50,147,164,180,232, 60,159, 79, 62,
+ 77,206,204, 60,157,153, 51,115,158,247,125,207, 57,239,249, 18,176,219, 1, 82, 6, 24, 14, 2,121,251, 0,245,227,128,106, 54,
+ 80,116,200,177,159,221, 14,236,254,210,177,127, 27,194, 93,255, 63,130, 97,236,249,139,171, 87,175, 26, 6, 14, 60,139,239,190,
+ 3, 14, 30,180,227,150, 91,142,227,200,145, 35,134,148,148, 20,178,107,215, 46, 67, 65, 65, 1, 46, 93,186,132,145, 35, 71, 98,
+214,172, 89,170,156,156,156, 34,111, 73,124, 8, 33, 42, 79, 81, 0, 87,176,134,135, 80,176, 93, 0,109,212,231,223, 12, 92,143,
+190,172,172,140,242,244,113,183,191, 55, 68,141, 24,129,234,123,239,195, 85,179, 5,215,108,141,176,208, 52,140, 54, 59,106,173,
+ 86,212, 63,240, 32,186, 36, 36,248, 25, 21,164, 48,102,204, 24, 12, 25, 50, 68,117,240,224,193,162, 64, 56,184, 66,239,174, 44,
+ 16, 35,128,219, 22,184, 43,227, 3,119,226,207,122,254,174,153, 2, 69,220,120,241, 23, 13,128,155, 61,108,241,240, 53, 65,221,
+ 0,233,233,233,246, 65, 67,239,125,160,180,244,204, 79,223, 22, 87,128, 97, 8,212,227,226,113,252,100, 21, 94,127,243, 32, 94,
+ 91,115,160, 73,252,191, 45,174, 64,105,233,153,115,131,134,222,251, 92,122,122,186,205, 19,167,110,203, 49,202,142,142, 88,187,
+201, 33,242,239,189, 6,124,184, 29, 80, 37, 2, 35,238, 0,138, 62,118,148,175,221, 4,216,209, 49,144,140,128,129,206, 2, 32,
+ 62,120,218,164, 47,210,100, 50, 97,200, 16, 11, 70,143, 6, 70,143, 6, 70,141, 34, 40, 43, 43, 67, 94, 94, 30, 14, 29,114, 88,
+ 79, 73, 73, 73, 72, 72, 72,224,149, 30, 56, 39, 39,167,136,143,176,211, 52,141,136,136, 8,193, 94,172,115,212,127,211,136,127,
+246,183,191, 30, 44,251,241, 86, 38,196, 8, 8,198,126, 0,144, 62,127,126,145,245,206, 59, 85,167, 39,140, 87, 85, 14, 24,128,
+202,144, 16, 84,222,126, 59,126,153, 56, 81,101,191, 43, 81,149,238,236,162, 17,138,209,163, 71, 35, 16,175,159,203,225,171,140,
+239, 61,116,231,245,143, 30, 61,218,103,153, 63, 96,115, 4, 92, 79, 10, 36, 70, 4, 90, 11,124,166, 2,138,153, 0, 91,209, 51,
+111,143,255, 35, 61, 61,189,250,223,235,223, 92, 87,240,249,182, 37,191, 93,172,239,211, 55, 46, 10,201, 19,250, 32, 42, 82,129,
+107, 53, 22, 28,249,241, 18,206,156,189,134,210,210, 51, 7, 38, 62, 52,107, 59,128,243,190, 56,227,250, 79, 86,125, 93,188,203,
+112,160,184, 14,201, 15, 0,239,191,225,200, 4, 88,122, 14,216,248,169,195,243,183,163, 35,226,250, 79, 86, 97,239, 71,193, 16,
+240, 96, 31,219,102,179, 0, 46, 94,188,168,138,138,234, 98, 56,124,248, 50, 0,224,151, 95, 58, 98,244,232, 59, 16, 29, 29, 13,
+133, 66,129,139, 23, 47,170, 38, 79,158, 44, 40, 21,112,239,222,189, 85, 63,255,252,179,193,147,199, 70,211, 52,250,246,237,139,
+141, 27, 55, 10, 18, 33,215,190,127,206,111,226,207, 88, 0,119,222,170,191, 30,172, 47,113, 23, 34,254, 92, 35,160,217,115,113,
+252,120,192,245, 29,168,135, 46,228,190,241,253, 95,193,230,243, 38,254, 92, 88, 83,250, 2, 98,255,255, 13,137, 4,120, 50, 12,
+ 4, 77, 3, 12, 96,176, 92,176,231, 94, 19, 63,183,221,144,243,243,113,159,130,114,126,129, 12, 92,124,110,193, 11, 58,157, 78,
+247,201,201,227, 95,191,179, 35,247,171,248, 30,189,250, 36,114,214, 2, 56, 52,104,208,176,239, 38, 79,121, 98, 89,122,122,186,
+137, 15,159, 51,189, 47,149, 62,111, 24,217,182,251, 23,252,223,219, 30,214, 2,240, 95,252,131, 18, 48,105,111,226, 15, 0,143,
+ 60,242, 8,142, 29, 59,134,199, 31, 63, 12, 0, 24, 53,106, 20, 30,126,120,152,234,249,231,159,111, 18,231,111,190,249, 70, 16,
+231,187,239,190, 91, 4,128, 74, 78, 78, 78,170,175,175, 55, 72,165, 82, 72, 36, 18,208, 52, 13,185, 92, 14,165, 82,169, 10, 84,
+252, 1, 4,197, 8, 16,241,251, 68,121,121, 57, 85,144, 86, 64, 98, 22,196,168,208,219,253, 62, 21,105, 5, 6,209,251,111, 91,
+200, 4, 52,148,193,110,120, 91,131,143,106,231,231,215, 30,248,216, 72, 64,173, 78,167,155, 51,104,232,189,108,198, 24, 37,128,
+ 46, 0, 46, 2, 48, 59, 87,121, 19, 4,215,240,126,217,121,130,178,243,102,224,235, 99,109,125, 31,218, 83, 94,137,102,112, 10,
+125,211, 57,156, 56,113, 34,104,220,187,119,239, 46, 10,214,245,113,250,253, 41,151,114, 10,206, 68, 64, 34, 68,184, 26, 1,229,
+ 75,202,209, 94,223,189,223, 43,248,102, 1, 4, 0,202,223,117,132, 69,136, 16, 33, 66,132, 8, 17, 55, 47,196, 65,128, 34, 68,
+136, 16, 33, 66,132,104, 0,136, 16, 33, 66,132, 8, 17, 34, 68, 3, 64,132, 8, 17, 34, 68,136, 16, 33, 26, 0, 34, 68,136, 16,
+ 33, 66,132,136,223, 7,154,205, 2, 56,122,244,168,223,163, 50,221, 13, 38, 20,249, 90,141,207,231, 34, 54,109,201,167,209,104,
+146, 0, 24,244,122,125, 80,248,102,205,154,149,196, 48, 76,208,248,196,231,207, 45, 95, 5,128,158,173,121,126,243,231,207,159,
+149,158,158,254,105,107, 94,175, 78,167, 11, 1,160,112, 62,211, 22, 0, 12, 0,146,158,158, 78,196,231, 69,228,251, 35,241, 5,
+ 43, 2, 64,120,124,132, 32,216,124, 55, 12,228,234, 42, 66,140,235,120,159,159, 83, 8,131,118,189, 28, 62,172, 89,179, 70,229,
+229,126, 10,230, 59,241,118, 71, 4,202,199, 98,218,232, 61,134,184,142,121, 0,128,132,132,132,128,235,179,127,247,109,184,173,
+235, 62,132,133,133, 97,220,184,113,237,233,249,232, 74,117, 80,126, 14,160,107, 0, 28, 17,112, 76,193,236, 4, 32, 86, 18, 26,
+ 94,224,133, 47, 4,190,167, 78,177,107, 1,119, 85, 40,194,217,115,147,242, 56,238,162,159,239,177, 16, 28,108,173,138,216,176,
+ 97,195,164, 15, 62,248, 96,113, 72, 72,200, 14,185, 92, 94, 44,151,203,127, 2,160,147, 74,165,122,138,162,222,209,233,116, 93,
+116, 58,157, 56,237, 76,132, 8, 79, 17, 0,119, 47, 57, 33,158,223,113,129,185,161,137,147, 48, 88,124,130, 60,216, 96, 34, 53,
+ 53,149,156, 57,115,198,167,184,234,245,122,131, 86,171, 69,183,110,221,220,166, 92,205,200,200, 48, 8, 17,107,189, 94,111, 88,
+179,102,141, 42, 35, 35,195,112,232,208, 33,131,139, 33,224, 23, 31,115,234, 37, 72,238,120, 21, 31,126,105, 5, 0, 48,167, 94,
+186,110, 29,222,241,170,160,251,242,241, 63, 59, 16,134, 0,159,124,238,224, 82,223, 31,130, 65,125, 79, 2,112, 24, 1,197,197,
+197,130,234,102,213,219,170,164,154, 95,171, 97,180, 70, 25, 76,141, 29,160,158, 88,131, 94, 61, 40,196,197,205, 37,117,117, 22,
+108,219,182,173, 77, 27,116,137, 66,177,144,216,172, 19, 36, 10,197, 66,198, 98, 89,238, 39,141,146, 21, 95,137, 92,177,152,216,
+233,241, 18,185, 98, 33, 99,117,203,103,227,193,103, 35,132, 80,161,161, 97, 11,105,218, 54, 65, 46, 87, 44,180,186,225, 34,132,
+ 72, 40,138, 98,110,240, 45,179,114,159,191,236,236,108,195,140, 25, 51, 84, 57, 57, 57, 69,129,144,126,240,193, 7,106,153, 76,
+118,159, 76, 38,123, 68, 42,149, 70, 73, 36, 18,101, 86, 86,150,100,201,146, 37, 79,216,237,118,208, 14, 60, 98,183,219, 83,116,
+ 58,221, 55,206,104,128,213,217,254,181,122, 55,232,148, 41, 83, 8,223,246, 46, 55, 55, 87,208, 51, 61,117,234, 84, 18,200,241,
+ 34,126,255, 96, 51, 2, 10, 93, 14,216,167,248, 39, 36, 36,160,184,184, 88,136, 56,123, 21,121,158,124, 45,248,181, 90, 45,202,
+202,202,224, 12, 17, 7,109, 89, 87, 82,145, 64, 16,214, 31, 84,212,199, 20, 0, 80,157,151, 82,169,169,169, 62,189, 30,174, 88,
+ 87, 85, 85, 25, 60,137,191, 86,171, 69, 86, 86,150, 32,241,119,254, 70, 98, 98,162, 42, 49, 49, 49, 32, 62, 86,236,217,191, 43,
+255,129,102,226,191,116,166, 2,171,114, 44,188,238,213, 39,235,148,100,112,156, 4, 38, 51,193, 11,143, 41,112,232, 36, 13,179,
+137,160,193, 10,168,134,159,196,201, 95,236, 72, 72, 72, 32,124,141, 0,237,223,111, 39,165, 71,234, 16,209, 81,142, 30, 61,149,
+232,218,189, 47,206,149, 90,209,251, 14, 27, 66, 20, 85, 40,220,113, 5, 15, 61,244, 16,249,252,243,207,219,183,203, 31,183, 0,
+ 0, 32, 0, 73, 68, 65, 84,170,193, 11,237, 28, 29,189,232, 63,135,190,163,212, 3,250, 45, 4,240, 26,128,198, 64,248,162, 59,
+ 71, 47,250,228,203, 67,212,248,225, 3, 2,226,163, 40, 74,222,163, 71,207, 69,123, 13, 95, 83,163,134, 13,114,203,213, 6,226,
+ 15, 0, 77,203, 15,234,245,122, 67, 74, 74, 10,114,114,114, 12,238,222,215,239,191,255,158,188,242,202, 43,216,181,107,151,215,
+250,221,184,113,227, 3,114,185,124,176, 92, 46, 95, 32,151,203,195,207,159, 63,143,126,253,250, 65, 42,149, 34, 34, 34, 2,103,
+206,156,129, 82,169,148,125,255,253,247,145, 7, 15, 30,252,250,217,103,159,237, 13,224, 28, 0, 57, 28,221, 3, 30, 27, 62,110,
+251,199,109,183,216,114,138,162, 64,241,240, 90,118,238,220,233,145,131, 91,238,173,189,245,132,220,220,220,128,142,111, 77,204,
+159, 63, 63,201,153,149, 82, 68, 27,137,190,191, 17, 0, 94,226,207, 23, 90,173,214,231, 62,124,132,203,147,248,175, 92,185, 18,
+153,153,153,174, 70,135, 95,194, 64, 14, 39, 16, 68,247, 7, 21,247, 49,197,245,248,179,179,179, 41, 0, 96,255,122,234,115,113,
+ 21,107,111,226,239,140, 12,248,244,218,245,122,189,193,213,195,103,203,184,247, 88, 40,159, 55, 15,127,233, 76,254, 43,197,229,
+172,235, 64,250,221, 38, 65, 88, 40,133,219, 98,164,184,114,141,129,141,150,162,186,134,160,214, 72,112,230, 55, 6,144, 0, 93,
+194,143,179,247,199,107,163,176,236,111, 3,146,250,247,137,199,193,202, 75,136,139,237,138,193, 67,227, 33, 13,237,140,219,226,
+174,225,154,217,130,170, 74, 59,126,187,100, 65,184,172,140, 23, 95, 43,225,209,199,150, 44,145,151,245,140, 65,104,194, 40,137,
+229,235,255, 61, 10, 96,147, 31, 60,151, 88,190,185, 11, 23,203,127,147,247,128,178,255, 72, 73,221,137,253,254,242, 1,192,163,
+207, 46,122, 94,142,208, 8,196, 13, 24, 36,249,249,199, 31, 2,225, 10, 38, 24,142,247, 15,133, 66,161, 2, 96,112,173,195,195,
+135, 15,243, 18,127, 0, 8, 9, 9,137, 84, 40, 20,243,174, 92,185, 18,222,191,127,127,140, 24, 49, 2, 50,153, 12,111,189,245,
+ 22,236,118, 59,134, 12, 25,130,237,219,183,227,251,239,191,199,241,227,199, 33,149, 74,223,209,233,116, 83,223,125,247, 93,111,
+ 94,117, 83, 59, 23,140,136,165, 78,167, 83,245,232,209,195, 64, 8,241,122, 76,101,101,165, 42, 61, 61, 93,208, 13,101,185,253,
+ 61,158, 21,234,211,167, 79,123,109, 55, 6, 14, 28,168, 18, 42,230,167, 79,159, 54,204,158, 61, 27,157, 58,117, 82,137,134, 64,
+251,132,204,147,199,238,203, 83,111, 47, 40, 43, 43, 67,102,102,166,191, 6,132, 71,164,166,166, 18, 42, 38,155, 74, 77,141, 35,
+250, 13, 99,128, 45,247, 16, 74,249, 87,159,111,188, 59,177,118, 21,101,111,221, 2,158,192, 53, 40, 14, 29, 58,100, 72, 76, 76,
+108, 22,250, 23,202,247,209, 18,165,199,198,237,209,213, 38,222, 60,239,190,251,110, 82,168,116, 9, 36, 18, 32, 60, 12,168,169,
+ 99,208, 72, 8, 58,132, 81,176, 48,128,185,145,224,150,174, 18, 48, 52, 80,114,222,142,178,178, 50,131, 55,227,108,209,194,241,
+ 73,113,183,133, 27,228,114,130,167,231,221, 9,187,157,160,178,202,138,242, 11, 53, 64,200,121,132, 69, 53,226, 98,213,175,144,
+200,107,113,234, 84, 13, 58, 69,121,231,107, 61,247,191,243, 75,143,252,249,207,161,127,103,128,168,204,191, 41, 47, 29, 59,186,
+156,169,171,243, 71,100, 9, 0, 40, 58,117,126,233, 79,115,254, 28,186,250,172, 29,183,204,210, 42,127, 46, 59,190,220,222,208,
+130,143, 2,143,126,247,142,157, 34, 95,122,116,206, 99,161,199,203,175, 97,202,236, 52,229,191,255,145,177,220,220, 96,242,117,
+110, 61,133, 68,242,188,148,123,171, 11, 59,251,142, 76,158, 60, 25,172,232,155,205,230,166, 58,100, 61,255,188,188, 60, 94,117,
+ 26, 26, 26,122,183,201,100,186,125,224,192,129, 80,169, 84,200,200,200,192,147, 79, 62, 9, 0,176,217,108,216,178,101, 11,138,
+139,139,241,195, 15, 63, 96,219,182,109, 48,155,205,125, 25,134, 81,251,240,216,131,250, 60,237,222,189,155, 87,215, 28, 69, 81,
+130,159,101, 46,183, 63,199, 59,223,225,162,217,179,103,163,162,162,194,237,246,152,152, 24,248, 43,224, 21, 21, 21,168,168,168,
+ 16, 13,129, 27, 12,110,184,223, 91, 52, 64, 38,212, 99, 15,182,208, 6, 10,103,216,223,111,144, 4, 16,244, 4,168, 93,142, 23,
+135, 26, 85, 76,165,166,198, 53, 53,106,217,217,217, 20, 54,140, 33,174,145, 0,190, 98, 93, 85, 85,213, 76,156,253, 17,107,190,
+224, 24, 29, 62, 69,130, 79,184,144, 19,254,119,187,243,123,239,189, 71, 46,159,124, 30, 61,251, 75, 97, 50, 95,223,197,108, 39,
+176, 88, 1,155,179,204, 70, 19, 16,137,227,251,143,199,139,161,209,104,146, 74, 74, 74,220,254,207,136,136, 90,131,201, 44, 65,
+151,206,145,168,185,218,128,154,218, 26, 28, 58, 92,137, 11,151, 8,228, 29, 26,208,171,175, 17,230,134, 43,232, 55,212,134,222,
+ 3, 27,177,237,253, 98, 76,159, 62, 61,233,236,217,179, 55,234,145,147, 0, 24, 55,121,102,106,247,138, 78, 81, 40,165,129,176,
+113, 19, 32,137,138,238,194,212,213, 77, 0,176,151, 35,132, 33,224,244,123,123,106,247, 1,140, 79,153, 62,179,251,101, 73, 39,
+156, 51,218, 16, 57,114, 28,100, 17, 81, 93,236, 13,205,248,120,213, 43,128,137,211,166,207,232, 78,164,161,168, 53, 53, 98,112,
+194, 93, 80,118,236,212,197,220, 96,114,229, 18,106, 0, 4, 5,172,247, 79, 81, 20, 38, 79,158, 76, 0, 96,215,174, 93,208,104,
+ 52, 73, 90,173,214, 32, 68,252,117, 58, 93,104, 77, 77,205, 92,155,205, 38, 9, 15, 15,199,125,247,221,135,213,171, 87, 35, 36,
+ 36, 4,233,233,233,216,186,117, 43,138,139,139,113,232,208, 33,236,219,183, 15, 63,254,248, 35,186,116,233,210,133,166,233,219,
+224, 33,252,207, 13,129,250,234, 2,144, 72, 36,188,206,179, 53,187, 0,118,238,220, 25,148, 46,128, 78,157, 58,169, 42, 42, 42,
+ 12,158,182, 5, 90,239,162, 33,112,243, 68, 0,110, 38,120,242,136, 4, 91,193,169,169,169, 68,159,121, 22,144,202,129,200, 16,
+ 32,178, 55,168,108, 39, 25,207,190,255, 86, 0,225,122,253, 0,192,245,252,221, 52,174, 72, 76, 76, 84,121, 25, 12, 40,248, 26,
+254,187,184,131,199,136, 64, 68, 93, 6,126,181, 18, 84, 94, 97, 0, 72,160, 12,119,132, 56,109, 52,129,165, 17,176, 88, 1, 75,
+ 35, 96,181, 1, 22, 51, 96,109,188, 30, 37,113, 55, 32,229,191,111,119, 32,133,135,234,113,107,156, 18, 36, 68,134, 43,102, 51,
+ 12, 95,157,199,169, 51, 23,112,245,170, 17,131, 18,236, 48, 89,104, 88, 26,237, 48, 55, 48,168, 44, 7,204, 38, 96,199,142, 29,
+ 6, 33, 11, 96, 4, 8, 70, 26, 25,249,210,227, 47,190,168,216,198,145,144,168, 23,255,166,188,154,185,120,185,189,166,102, 47,
+231, 94, 91,249,212,177, 76, 25,249,210,147,207,103, 42,242, 47,216,155, 10,111,121, 36, 83,121,110,227,139,203,105, 99,205, 94,
+ 33, 81,128,112,101,196,242,133, 47, 44, 86,148, 86, 92, 95, 45, 50,101,118,154,242,147, 13,107,150, 55, 24,235,247, 6,248,174,
+185,123,150,132,188,107,132,245,254, 21, 10,133, 74,175,215, 23,177, 83, 70,205,102,179, 97,212,168, 81, 66,184,104, 0,125, 1,
+ 48,195,135, 15,103, 20, 10,133,100,235,214,173,120,226,137, 39,240,198, 27,111,128, 16,130,111,191,253, 22, 95,125,245, 21,142,
+ 31, 63,142,218,218, 90,244,235,215, 15,117,117,117,225, 18,137,164,155, 47,242,105,211,166,121, 20, 84, 95, 93, 3,110, 12,149,
+118,221, 5,224, 45, 10, 16,136,247, 47, 26, 2,162, 1,208, 42,162,168,209,104, 84,156, 62, 67,215, 6,145,226,122, 27,206,144,
+188, 95, 33, 61, 86,244,179,179,179, 41,253,134, 49,128, 92, 14, 42, 59,251,134, 94, 44, 59,234, 95,175,215, 83, 26,141,134,248,
+138,134,184,142, 13, 16, 34,232,238,224,109,223,185, 47,154, 16,211, 93,130,217, 41,114, 88, 26,129, 78, 17, 20, 36,148,211,235,
+ 7,129,165, 1, 48, 89, 9, 76,102, 2,147,133,128, 33,128,196,203,152,235,185,139, 76, 24, 50,172, 12, 61,110,191,138, 47,242,
+171,112,245,170, 5,195,239,170,195,208,206, 70, 32,164, 17,150, 6, 6, 85, 23, 8, 76, 38, 10, 52, 77,161,115, 23, 10,184,241,
+ 99,217, 6,141, 24, 54,108, 84, 84,108, 44, 14, 92,215,107, 40,103,207,193, 85,109, 70, 2,128, 59, 0,156, 18,192, 55,112,196,
+176, 97,163,162, 99, 98,113,248,187,166, 49,114,232,170,250, 19,206,189,159,233,142, 47, 12, 64,131, 7,174, 59, 70, 12, 27, 62,
+ 42, 38,230, 22,156,250,225,122, 68,100,236,131,201,248, 88,183,218,159,115,107, 53,131,150,125,127, 93,199,111,164,164,164,180,
+ 24,127,228,102, 44, 0, 91,233,125, 1, 28, 93,186,116,233,221, 50,153, 76,249,225,135, 31, 98,243,230,205,120,252,241,199,177,
+114,229, 74, 80, 20,133, 95,127,253, 21,102,179, 25, 90,173, 22, 52, 77,227,153,103,158, 97, 40,138,242,249, 2, 4,115, 52,125,
+123,239, 2,240, 22, 5, 8,134,247, 47, 66, 52, 0,130, 10, 55,253,200,148,151,253,248,187, 56,163, 28, 35,212, 83, 83,123, 17,
+160, 4,250,183,206, 2, 97,253,155, 34, 1,172, 81,192,167, 27, 32, 88, 96,189,121,141, 70, 67,184,222, 63, 27, 17,224,254,214,
+104, 52,224, 36,203, 33, 66, 5,221, 21,156, 89, 0,110,249,104, 59, 96,106, 32,104,180, 58, 6,251, 53, 90, 9,100,161,215,183,
+ 89, 26, 0,179,141,160,250, 42,193,229,107, 4, 63,156,162,193, 48,128, 70,163, 81,149,148,148,180,168, 27,154, 6, 42,206, 91,
+113,190,244, 26,246, 31,188, 6, 66, 40,156,250,137,193,228,217, 52,228, 50,130,203,151,128,253,123,129,186, 58, 2,194, 0,247,
+ 60, 64, 65,161, 0,212,234,169, 56,119,238, 28,175,107, 82,223, 5,146,127,208,255, 70, 82,162,236,248,226,211, 43,179, 66,114,
+137,164,217, 13,233, 18, 26,138,144,231, 22,133,252,186,126,221, 50,107, 93,221, 28,190,124,210, 48,229,178,249,203, 87,134,236,
+173, 32,205,248,162, 59,132, 98,240,172,103, 67, 78,125,250,214, 50,171,201,200,229, 51,123,226, 82,132,117, 88,150,249,210,138,
+144,179,149,181,205,184, 58, 70,116,192,244,217,143,135,228,126,180,105,153,201,100,154,211,198,175, 47,181,107,215,174, 22,101,
+ 47,191,252, 50,217,181,107, 23,242,242,242,120, 87, 5,128, 19, 0,142,174, 89,179,102, 88,100,100,164, 18,112,132,193, 55,109,
+218,132, 39,158,120, 2,155, 55,111,110,242,212,215,172, 89,131,154,154, 26,212,213,213, 25, 27, 26, 26,202,156, 17, 4,185,215,
+ 80, 15,195, 52, 27, 15,197,122,240,132, 16,222,225,127,224,230,232, 2,112, 23, 5, 8,182,247,207,114,138,158,191,104, 0, 4,
+132,226,226, 98,159,163,191,157,219,249, 17,134,118,128,190,247,255,128,183,227, 8,226, 58, 0,125, 26, 65, 13,200,163,240, 86,
+ 66, 83,223,127, 32,221, 0,174, 83, 1, 61, 77, 13,116,215, 88,178,237, 5, 43,254,174, 3, 0,157, 94, 84, 83,153,143, 8, 0,
+229,234,137, 5,218,152,223,115,255,148,164, 11, 23,243, 13, 76, 87, 6, 18, 25, 16,226,108, 23,109, 12, 1, 77, 3,245,245, 4,
+ 86, 27, 64,219, 28, 70,193,212,105,142,232,141,135,144, 61,149,120,215,148,164,198, 43,123, 12,131, 6, 49,248,250, 43, 59, 40,
+ 9,112,185,146,130, 34, 12,248,234,115,192,106,166, 64, 17, 96,232,200, 16, 84,148, 51,184,255,254,100,228,230,230,242, 90,214,
+ 90,125, 23,200,170,103, 29,215,239,175, 17, 64, 24,251, 68,123,116, 23, 73, 62,115, 93,133,186, 3,232, 65, 1,230,132, 4,217,
+ 89,218, 62, 81, 16, 31, 97, 38, 34,162,179,196, 80,105,111,226,235,170, 0,186, 40, 40,132, 15, 73,144,157,252,132,153,232,201,
+139,118,199,213, 33, 34, 82,114,238, 82,141, 83, 88,128,136,176, 80, 68,132,203, 49,114,248, 8,217,142,255,144,137,109,252,234,
+186,189,231,236,168,127,238, 62,108,244,110,230,204,153,170,156,156, 28, 79,124, 70, 0,103,143, 28, 57, 98,188,247,222,123,187,
+130, 51,167,127,211,166, 77, 77,130,104,179,217, 96,183,219, 81, 82, 82,130,174, 93,187, 94, 97, 24,134,151,181, 56,109,218, 52,
+ 79,158,186,160,139,190, 25,186, 0,220, 69, 1,130,233,253,139,194,255, 59, 52, 0,156,115,246,111,232, 8,108,214,203,213,235,
+245,172,199, 75,185,217,135,176,226,207,241,138, 5,129, 59, 11,128, 45, 19,234,249,187, 14, 0,116,162,169, 44, 35, 35,195,224,
+236,206,224,197,199, 21,127,119, 99, 2,132,242,249,194,170, 28, 11,124,241,229,230,230, 22, 69, 71, 82,120, 48, 49, 4, 12, 0,
+155,149, 65,168,220,113,155,234, 77, 4,141, 54, 2,218, 14, 20,159,176,195,206, 16,248,154,178,151,155,155, 91,212,189, 43,133,
+251,147,164,152,254,168, 20,198,122,130,250, 90,192, 84, 79, 33,174, 31,129,221, 70, 65, 38, 81,160,230, 42,131,138,223,172, 40,
+249,137,223,128, 49,245, 93, 32,235, 22, 1,253, 99,129,245, 47, 0, 11,222,244,207, 8, 32, 13,166, 25,207, 37,140,216,211, 35,
+119,143, 50,106,236, 61,232, 14,160, 59, 5,216, 15,236, 71,225,220, 57, 70, 91,131,105,186, 16, 62,198,210, 48,253,233,113,163,
+242, 7,190,242,153,178,219,208,187,209, 37,148, 66, 87, 5, 5,243,233,111,176,243,239,243,140, 54,115, 3,111,190, 70,139,121,
+250,164, 7,239,205,207,120,253, 29,229, 29,195, 18, 16, 17, 46, 71, 68, 88, 40, 74, 79, 29,197, 75,218,133, 70,179, 0, 46,127,
+197,220,215,229,186, 19,255, 21, 43, 86,180, 8,243,103,103,103,179,121, 2,138, 60,120,255,128, 99,140,197,209, 1, 3, 6,148,
+ 90, 44,150, 94, 82,169, 84, 17, 30, 30, 14, 0,200,201,201,193,204,153, 51, 97, 54,155, 97,177, 88,208,216,216, 8,165, 82,105,
+177,219,237,185,132,144, 74,158,222,117, 80,218,182,155,165, 11,128, 27, 5, 96,191,139,194, 47, 26, 0, 55, 76,252,249,112, 58,
+ 5,159, 56,191, 3, 0,225, 78, 75, 44, 46, 46,110, 38,248,238, 12,132, 22,144, 82,128, 92, 2,132, 73, 1,165, 12,104,172,135,
+254,141, 16, 96,221,147, 4, 97,157,129,176,206,130,251,254, 61,136, 63,220,136, 53,175, 23,195, 85,252, 93,199, 4, 8,229, 19,
+ 32,254, 62,249,170,107, 8,181,187,200, 70, 20, 10,128, 97,128, 33, 3,164,215,235,227, 71, 59,108,118, 2, 59, 35,197,140, 25,
+ 51,120, 25, 39,151, 46, 19, 42,255,115, 59,161,105,192,106, 35,176,211,128,132, 2,146,146,129,250, 26, 10, 63, 29, 51,195,108,
+145, 96, 74,202, 12,108,223,190,157,151,248,175,120, 18,232,123,139,227,119,159, 94, 64, 0,145,128, 67, 76,125,189,186,114,234,
+164,252,216,157,123,148,177, 99,239,129,237,192,126,108, 79,153,100,180,214,215,171, 1,236, 23,200,183,223,110,174, 87,159,126,
+121, 90,126,204, 63,115,149,189, 70,143,133,233,244, 1,252,247,185,169,198,198, 6,193,124,251, 45,230, 6,245,154,191,253, 37,
+255, 31,255,218,168, 76,188,235,110,156, 57,121, 20, 11,211,230, 24, 27,140, 70,127,206,173, 85,225, 37,217, 15, 73, 78, 78,230,
+ 51, 27, 64, 26, 25, 25,121,212,108, 54,255,167,172,172,172,247,176, 97,195,226,105,154,150,133,132,132, 32, 55, 55, 23,227,199,
+143,135,197, 98, 65, 67, 67, 3, 74, 74, 74,234,162,162,162,190, 52,155,205, 31, 50, 12, 99, 2,207, 12,128,220, 1, 9, 66, 67,
+255, 28, 67,162, 69,228,160, 61,118, 1,112,163, 0,193,224,241, 39,119,128,136,155,192, 0,104, 11,207,223,141,247, 65, 92,206,
+ 39, 88, 94,138,199,136, 0,223, 8, 64,176,197,159, 53,118, 92,194,251,132, 91, 38,148,207,215, 88, 0,161,124, 38, 11,161, 76,
+ 22, 16,137, 4,216, 95,236,232,235,103, 7,252, 57,250,253,103, 8,226,171,175, 39, 20,229,236,102,167, 36, 14,142,239,254, 7,
+152,140, 12, 8, 3, 76,153,146,140,237,219,183,251,172, 15,245, 93, 32,218, 57, 64,164, 18,168,184, 2,132,133, 2, 12, 1, 58,
+ 40,128,215,211,253, 54, 2,246, 51,245,245,234,226, 41,147,242, 59,173,120, 85, 89,180,226, 37, 99,163,127,226,223,204, 8, 40,
+ 90, 58, 53, 63,236,185,151,149, 5,255,126,197, 31,241,111,226,162,109,214, 73, 47,253,245,233, 61, 11, 50,180,202,119,214,102,
+ 25, 27,140, 70, 53, 33,228,152,139, 0,201, 40,138,162,133, 6, 64,130, 25, 21,112, 39,254, 20, 69,145,228,228,100, 0,192,228,
+201,147, 9, 69, 81,222, 12, 1,165,213,106, 53, 74, 36,146,194,152,152,152, 91,234,235,235,159, 61,124,248,112,207, 17, 35, 70,
+ 48, 52, 77, 55,212,214,214, 94, 58,118,236,216,175,113,113,113,165,209,209,209,101,102,179, 57,135,166,233, 75,105,105,105,166,
+225,195,135,243, 50, 0,216,164, 64,129, 64,167,211,241, 22, 84,127,186, 0, 2, 57,222, 83, 20, 32, 24,109,166, 40,254, 55,169,
+ 1,192, 99,174,191,160, 23, 93, 64,238, 0, 33,188, 20,103,148,191,223,226, 69, 21,131, 74,141,123,136,224, 23, 0,191,184,110,
+173,117,126,132,205, 49,119, 94,175, 33, 88,226,234,114, 95, 8,155,103,192, 57, 64,144,226, 68, 67,252,226,251,239,226, 14, 92,
+163,192, 31,190, 38,222,153, 51,175,215, 9, 59,224, 79,175,215, 23,249,195, 71,152,230,117,108,172, 3,146,147,147,177,123,247,
+110,138,245,170,120,213,199,127,130,250,206,116, 2,112, 5,192,126, 91,125,189,250,171, 21, 47,111,109,172,175,159,235, 20,235,
+ 1, 0,126,246,215, 8,176, 54,212,171,247,190,243,202, 86, 75, 67,253, 60, 0, 7,224, 88, 39,192, 40,148,136,166,233,175,105,
+218,168,126,103,221,170,173, 70,163,113, 46,128,253,174,125,207,126,136,127, 48, 32,229,254,112, 21,127,118,220, 14,119,144, 96,
+ 74, 74,138, 55,190,114,171,213, 26, 74, 8,169,103, 24, 70,103,181, 90,191,141,141,141,237, 82, 83, 83, 67, 45, 95,190,188,174,
+182,182,182,186, 87,175, 94,245, 70,163,209,100,181, 90,235,108, 54, 91,227, 83, 79, 61,101, 22,232, 97, 7,236, 68,164,167,167,
+183,154, 16,182, 38,183,136, 63,166, 1, 16,108,207,190,213, 34, 5, 78, 17,165,220,121,203, 66, 16,228, 81,253,124,178, 5, 6,
+244, 15,132, 44,250, 19,140,104,128, 31,117,226,241,119,160,124,187,119,239, 22, 84, 87,129,140,248,247,128, 43, 92,209,182,212,
+215,245,225,252,254, 57, 64,238,253,102, 99, 61,151,207, 24, 8,151,177,190, 25, 87,123,120,151, 41, 0,216,176, 97, 3,145, 72,
+ 36, 96, 63,220, 16,182, 90,173, 6,195, 48, 96, 24, 6,105,105,105,148,143, 89, 1, 20, 77,211,225,132, 16, 59,195, 48,141, 54,
+155,237,127, 82,169,148,146, 72, 36,161, 0, 66, 25,134,129,221,110,151,210, 52, 45,167,105,186,231, 83, 79, 61,117,154,115,108,
+171, 47, 2, 36, 66, 68,123,128,183, 28, 41,148,191,235, 8,139, 16, 33, 66, 68, 59, 64, 3, 71,208, 25,142, 99, 35,227,148, 95,
+132, 35,114,163, 16,133, 95,132, 8,239, 17, 0, 17, 34, 68,136,184, 89,160,112, 26, 1, 12, 71,248, 37,184,190,242,160, 12,215,
+211, 28, 51,226,237, 18, 33, 66, 52, 0, 68,136, 16,241,251,128, 4,142,177, 18, 44, 88,225,151,115, 68,159,113,238, 39,122,255,
+ 34, 68,136, 6,128, 8, 17, 34,254, 32,109,154, 40,250, 34, 68,120,177,158, 69,136, 16, 33, 66,132, 8, 17,127,100,107,249,232,
+209,163,220,133,116,136, 75, 18, 29,130,230, 11,237,148,235,245,250, 88,246,183,187,193,132, 92, 62,161,248, 61,242,185,153,182,
+ 72,137,247, 79,172,143,155,133, 47, 54, 54,182,105,159,242,242,114, 74, 40,223,252,249,243,145,158,158, 78,137,207,159,127,156,
+226,251, 43,242, 9,225, 19,108, 0, 8, 68, 87,158,251, 17,141, 70, 35, 56,179,148,167,245,226,209, 50, 25,137,187,213, 0,221,
+237,115,195,193, 10,140,115, 46,188, 65,175,215, 55,101,235, 18,154, 79,188,181,144,146,146,146,148,151,151,215, 36,130,201,201,
+201,170,221,187,119, 23,253, 30,173, 93,119,245,113,250,180, 99,102,216,192,129, 3,219,250,244,200,212,105,233,200,253, 76,231,
+246,153,157, 58, 45,157, 56,183,121,124,112,166, 78, 75,247,218, 8,228,126,166,243,251,161,139,141,141, 37, 41, 41,215,103, 21,
+230,229,129,248, 50, 2,124, 97,245,154,213, 73, 59,247,238, 68,252,160,120, 3, 40,224,244,145, 83,170,187,134,223,141,117,111,
+174, 19,244,252,205,157, 59,183,197,117,111,221,186,149,130, 8, 17, 34, 90,205, 0,144,243,221, 49, 49, 49, 81, 48,185, 23, 3,
+192,173,136,186, 46,180, 33, 64,104,253,177,156,248, 52, 46, 68,175,215, 67,171,213, 34, 43, 43,203,224, 37, 77, 39,159,255,223,
+108,159, 94,113,183, 2, 0, 46, 89, 44,160,205,141,142,194,154, 58, 86,228,248,165, 63,110,106,200,243,154,229, 20,112,230, 22,
+ 23,180,198,187,132,114,100,215, 99,255, 2, 62,191,183, 69,227,220,172, 62, 88,225, 15,160, 62,130,121, 13,100,234,180,116, 76,
+ 82,143,180, 0,233, 10,167,208,251,245, 63, 56, 6, 68,208, 97,181,106, 81, 80,144,134,137, 19, 55, 32, 37, 37, 11,121,121,142,
+123,229,143, 33,240,216,194,199, 72, 77,231,171, 88,171, 91,141,168,240, 40, 48,180, 29, 22,210,104,248,252,219,189, 19,103,217,
+ 31, 38,119,199,143, 85, 45, 90,180,200,167, 33, 48,119,238, 92, 50,127,254,124,183,247, 84, 52, 2, 68,252,145,113,244,232, 81,
+215, 40, 65,139,125, 2, 25, 3, 32,232, 88,215,229,107,131,133,247,116,186,164,128, 91, 95, 66,120,127,248, 82,106,181, 90, 16,
+ 66,176,114,229, 74,111,199, 17,193,249,187, 35, 59,226,120,217, 39, 40, 41,219,143,107, 21,255, 66,233, 63,211,176,253,153,153,
+109,250,160, 29,255,241, 68,147,200,159, 56,225,248, 14, 92,255,206, 45,103, 8,239, 58,225, 5, 33,245,113,250,244,105,204,155,
+ 55, 15, 94,197,159,135,193,248,224,131,249,254, 26,142, 30, 49, 73, 61,178, 33, 45, 45, 77, 49, 73, 61,210,111, 97,119,122,248,
+222, 62,126,123,255, 0, 48,115,166, 99, 85,190,153, 51,115,144,151, 87,138,148,148, 62, 72, 73,233,211,172,107,192,231,251,250,
+222,123, 73,179,158,127,152, 60,253,220, 19, 88, 54,109, 41, 70,198,142, 70,239,142,189,209, 59,170, 55, 6,117, 27,130,231,198,
+253,165,224,197, 23, 50,113,176,234,128, 97,237,218,181,188,222,237, 43, 87,174, 52,251,220, 57,208,140, 45,139,190,193,172, 89,
+179, 8,247, 19, 72,253,168,213,234,160,214,119,176,249, 90, 19,243,231,207, 79, 10, 6, 71, 16,120,162, 1, 36, 0,120, 17,192,
+ 58, 0, 5, 0,178, 0,252,195,249,185, 93,148,125,247,226,239,169,172, 89, 4, 64,171,213,146,178,178, 50, 0, 64,124,124, 60,
+184,139,205,232,245,250,102,191, 93,183,123,243,216,171,170,170, 12,122,189,158,119, 36,192,151,177,192,245,234,159,113,166,194,
+116,147,234, 84,208, 13,219,176, 97,131,207,125, 10, 11, 11,121,137,141, 70,163,193,202,149, 43,221,110,204,204,204, 68, 86, 86,
+ 22,180, 90,173,199,125,220,161, 87,220,173,184,112,173, 22,219,159,153,137,104,106, 44, 74,223, 95,140,248,233,241,248,162,180,
+ 26, 51, 86,110,110,211,135,109,232,144,193, 77,223, 7, 15, 30,220,172,156,141, 12,112,203,131,237,217,251, 16, 55,162,209,104,
+ 48,111,222, 60,183, 27,183,108,217,130,172,172, 44,168,199,142, 64,254, 55, 71,128,136, 14, 64,157,241,134,223,195, 61,249, 63,
+132, 3, 27,176, 39,255,135,160,240, 93,250,103,180, 87,129,233,190,164,154,215, 11,194, 13,253,167,165, 21, 32, 37,165, 79,211,
+ 95, 22, 41, 41,125,120,119, 9,188,255,241,251,120,227,237,215,112,111,191, 36,216, 27, 27, 65,219,105, 80, 50, 10,128, 20, 4,
+ 12, 46, 93,174,192,192,174,183, 99,217, 51,203,240,218,170,215,120, 69,163, 92, 27,182,228,152, 45, 0,128,109,219,182, 53, 59,
+118,214,172, 89,196,181,140,175, 88,239, 89,158,143, 73, 80,147,252,252,252,128,163, 10,106,181,154,172, 90,181, 10, 0,130,194,
+215,154,194, 95, 91, 91,203, 70,203, 2, 58,207,218,218, 90,182, 77,247,151, 71, 9,224, 79, 0,142, 0,248, 16,192,120, 0, 15,
+ 1,248, 11, 28,171, 66, 2,205,179,116,138, 0,144,166,117,104,204,134,172, 76,223, 94,124, 86, 86, 22,165,215,235, 41,189, 94,
+ 79,149,149,149,129,253,206,134,148,185,191,221,109,247, 4,214,168,200,200,200, 48, 84, 85, 85, 25,220, 25, 8,220,223, 62, 82,
+229,186,243,106,188,253,190,225, 47,216,167,159,126,234, 86,248, 41,138,106, 33,254,153,153,153,188, 56,127, 43, 43,135,113,211,
+ 34,204,120, 47, 7,189,226,110, 69,247,232, 48,148,237, 40,115,136,127,100, 71,199, 78, 33, 82,193,231,154,146,146,162,242,246,
+155, 15, 24, 2,220, 18, 14,236, 76, 7,186,133, 2,131,162,174,135,253, 99, 59, 0,159,165, 93, 47, 23, 10,138,162,220,126,132,
+224,213, 87, 95,117, 43,252, 3, 7, 14, 68, 86, 86, 22, 86,205,155,140, 19,165,231,209, 35,190, 39, 96,106,224,227,253,131,103,
+ 20,128,183,151,151,251,153, 14,123,242,127,112,235,233,115,250,246, 5, 93,248,170,143,136,199,143, 63, 96, 69,159,253,107, 77,
+233, 43,232,248, 6,115, 3,198,206,186,219,144,216,243, 78, 52,154, 76,128, 84, 10,153, 76, 6,169, 84, 10,169, 84,134,179,103,
+207, 98,251,142,220, 11, 22, 91, 3,122,135,198, 98,196,253,195,199, 61,241,244, 19,130,189,198,215,247,204,195, 4,109, 92,139,
+242,109,219,182, 81, 66, 35, 1,172,248,163,247, 90,236, 89,158, 31,176,231,174, 86,171,201,186,117,235, 48,120,240, 96,172, 95,
+191,190, 93, 70, 2,230,207,159,159, 52,123,246,108,114,250,244,105, 67, 69, 69, 69, 80,248, 42, 42, 42, 80, 81, 81, 17, 72, 52,
+ 65, 5,224,126, 0,199, 0, 92, 0,208, 3,142,212,219,231, 0,156,119,126,204, 16,209,100, 16,179,226,207,253,238,106, 44,223,
+144, 60, 0,156,190, 87,148,149,149,161, 91,183,110, 45, 12, 4,182,204,157,129,192,179,113,245,123,240,223,195, 15, 63,220,106,
+215,206, 21, 43,119, 94,191,115,225, 32,202,151, 88,152, 81, 14,227,244, 59, 65, 34, 22, 3,227,150,195,136,143,129, 15, 28,222,
+ 34,209, 47, 70,200,159,215,131,166,133, 39, 58,203,203,203, 43,226,222, 39, 31,185,215,221, 71,120, 54, 1,175,188, 7,220,122,
+ 11,112,105,151, 28, 91, 55, 90, 49,239, 19,207,229,130,220,123, 18,220,246,145, 59,216,239,226,103, 43, 17, 49, 72, 1,101,191,
+191,226,211,149, 79, 97,216,224, 30, 24, 48,249, 53, 94,245,193,231,212, 31,124, 48, 31,251,246,169,249,244,229, 83, 0,136,139,
+248, 83,236,192, 63,127,250,245,249,122,248,124,224, 73,232, 11, 92, 34, 1,190,112,177,234, 34, 38,104, 38, 32,162, 99, 20,236,
+ 20,141,175,191,250, 31,234,141, 70,164, 76,153,130,203, 85, 85,200,206,217,142, 39, 31,159,215, 43, 84, 17, 10, 9, 9,193,196,
+145, 19, 11,127, 54,172,247,203,107,188,118,237, 90,192,215,205, 21,127, 0, 78, 35,224,121,191, 35, 1,106,181,154,172, 88,177,
+ 2,125,251, 58,238,103,159, 62,125,208,158, 34, 1, 46, 30,127,208,192,241,254,217,239,254, 92,235, 29,206,119, 50, 4, 64, 56,
+128, 65, 0, 78, 1,232, 5,160, 14, 64, 13,130,220, 45,247, 71,192, 13, 75, 4,212,173, 91, 55,149, 70,163,105,209, 21,224, 92,
+219, 30, 0,154,214,187, 23, 42, 14,126, 14,254,227, 27,113,240, 27,172,119,239, 41,220,207,215,251, 7,128,207, 95, 92,129,148,
+ 55,222, 4, 61,110, 44,100, 0,148, 7,207,224,139,210,106, 0, 0, 61,110, 1,108, 63,118, 1,213,245, 47,130, 69,202,139, 32,
+241, 70,245,180,143,177,224,241,243,248,229,153,165, 48,237,179,162, 71, 23,239,229,254, 26, 80,129, 26, 7, 91,182,108,113, 88,
+195, 41,247,225, 80, 69, 21, 34,134, 69,224, 66, 65, 41,160, 8,197,204, 5,127, 70,231, 91, 38,183,229,187,232,105,212,191, 95,
+117,226, 37,138,224, 46,250,224,149,187, 32,173, 0, 19, 55, 76,196,204, 28, 32,173,192,241,189, 32,173,160,201, 56,144,231,157,
+225,117, 14, 70, 75, 61,186,132, 69,131,182, 52,128, 72, 8, 70,143, 25,131, 29, 59,118, 88,214,189,249,166,130, 33, 4,143,206,
+121, 20,157,163, 59,163,193,104, 4,109,167, 17, 17,210, 17, 54,137,205,175,235,173,169,169,105, 54, 59, 64,232,128,192, 22,226,
+207,194, 79, 35, 64,173, 86, 19,173, 86,139, 49, 99,198, 52, 43, 31, 60,120, 48, 94,127,253,245, 54, 53, 2, 90, 75,248, 89,110,
+ 46, 47, 27, 5,240, 99,169,224,111, 1, 28,117,138,253, 67, 0, 38, 0, 40, 1, 48, 20, 64, 46,128,205, 0,108, 16, 17,144, 1,
+ 64, 92, 68,145, 8,220,238, 21,241,241,241, 77,162,159,152,152,168, 98,199, 6,176,209,129,248,248,120, 3,219, 93,208, 86, 13,
+111, 48,225,171,175,159,227,253,251,196,140,247,114, 64,166,196,225,210, 93, 35, 17,141,177, 8,155,185, 30,244,197,203, 64,100,
+ 71,200,170, 63,198,174,117,197,128, 84,234,207,181, 7,108, 53, 31,123,225, 79, 24, 53, 28,136, 95,112, 2,131,148,143,227,231,
+219, 52,192,191,151,122, 44,111,171, 8, 64, 86, 86, 22,238, 29, 61, 0,227,198,246, 71,202,144,165, 88,179,238, 93,156, 42,190,
+128,103, 30, 24,133,202,220, 61,168,189, 86, 23,172,231,161, 89, 87,129, 51, 10,224, 83,160,185,130, 31, 76,241,247,192,201, 11,
+229,229,229, 84,108,108, 44,113,142,255,107, 50, 8, 0, 96,226,134,137,144,231,157, 65, 94, 94,105,211, 76, 0,239, 3, 2, 41,
+ 48, 12, 3, 59, 3, 16,134, 70,104,152, 2,115, 30,123, 76,241,202,203, 47,163,123,247,238, 76,175, 30, 61, 36, 22,147, 17,118,
+ 2, 16,198, 14,134,241, 29,209,218,186,117, 43, 53,126,252,120, 82, 93, 93,141,186,186,186,102,134,163,203,236, 0,222,179, 2,
+212,106, 53, 89,243,212, 73, 64,209, 23,168,124,187,229, 14,138,190, 88,243,212, 73,128,167, 17,160, 86,171,201,212,169, 83, 85,
+131, 7, 15, 54, 84, 87, 87,183,216, 30, 27, 27,139,169, 83,167,170,208,206,199, 4, 4,234,253, 7, 24, 5,224, 26, 12, 61,225,
+232, 10,152, 14,192, 4, 17, 65, 51, 0,132, 36, 2,114,183,221, 45, 52, 26,141,219, 40, 0, 43,246,221,186,117, 83,105,181, 90,
+131, 83, 16,161,209,104,188, 14, 42,244,230, 29,250, 49,191,190, 85,166, 1,178,222,189,183,193,128, 66, 80,250,207, 52,132,204,
+ 92, 15,115,197, 47,144, 29, 92, 15, 91,206, 2, 80,147, 86, 99,231, 95, 82,113,110,231, 89,164,172,250, 16,144,181, 77,102,231,
+165,122,160, 96,213, 14, 12, 58, 55, 17,184, 98,194,146,241, 75,189,150, 7, 35, 2,224,175,247,159,187, 99, 5,164,189,238,128,
+ 18,253, 81,254,213, 6,212, 83, 4,223,253,114, 30,227, 78, 92,224,117, 58,251,246,169, 61,138, 61, 0, 56,183,187,221,143,175,
+248,123,120, 70, 3, 18,134, 64,114, 0,176, 72, 43,184, 46,252, 0, 90,120,254,236,128,193,188,188, 82,183,199, 71,132, 69,160,
+162,182, 2, 99,122,223, 9,115,163, 5, 48, 91, 64, 91,109, 88,166,213,130,146, 64,210, 96, 50,130, 97,236,160,237, 4,161,178,
+ 16, 92, 54, 94, 70,136,221,247,108,227, 47,190,248,162,233,218,230,206,157, 75,216,246,230,202,149,235, 99,194, 46, 94,188,200,
+251, 58, 29, 34,236, 48, 2, 6,198,181,252,255,167,207, 90,145,241,193, 32,240, 21,107,231,126,100,204,152, 49,136,141,141,109,
+177,253,196,137, 19,200,205,205, 53,180,149,248, 59,189,113,138,141, 4, 4,163,223,223,157,247, 31,132, 40, 0,139, 9, 78,131,
+160, 81,148,240,224, 26, 0,173, 2,214,243, 7,128,196,196, 68,149, 94,175, 55,176,161,127, 15,198,129,170,164,164,196,215, 88,
+ 0, 42, 88,222,188, 16, 49,225,107, 96,176,222,191, 59,225,103, 13, 29, 33,231,123,172,180, 26,182, 31, 95,193, 37,124,131, 30,
+147, 86, 3,181,117, 40,221,176, 24,125,230,175, 69,229,230,197, 64,136, 12,144,180, 77,102,231,114, 19, 48,176,219,116,222,229,
+109, 17, 1,200,202,202, 50,206, 26,119,231,197, 78, 76,212,173, 13, 8, 81,228,172, 93,128,119,118, 29,197,146,135,238,193,188,
+ 55, 63, 66,234,255,253,191, 86,141, 6,121,187,196,220,207,116,112, 38, 1,162, 2, 53, 78, 3, 9,245,123,139, 2,164, 21, 20,
+ 16,119,226,207,245,254,125, 33,166, 91, 12, 62,255,186, 0,119,223,122, 55,194, 59, 40,193, 48, 4, 18, 66,131,161, 40, 16, 66,
+ 96, 39, 0,205, 16,208, 52, 13,115,173, 9,187,191,223, 13,185, 93, 46,120, 80,170,235, 64,167,191, 45, 24,139,228,152, 50, 80,
+123,249,115,120, 50, 2,132,138,191,171, 17,176,106,213, 42,244,236,217,243,186, 97, 95, 90,138,172,172, 44,180, 7,207, 63,216,
+134,128, 59,239, 63,192, 40, 0, 0, 36, 1,184, 13,192,223,113,125,225, 39, 17,237,217, 0,232,214,173,155,202, 53, 34,192,246,
+187,115,141, 3,238,247, 0, 61,120,193, 15, 86, 16,167, 1,186,245,254,253, 21,126, 22, 51, 86,110,198,118, 0, 15,189,145, 12,
+162, 95, 12,234,225, 53, 56, 86, 90, 13,170,115, 20,206,252, 86,231,240,254,133,119, 1, 4, 5, 39, 78,156,104,154,242,199,231,
+123, 48, 34, 0, 66,140,131, 45, 91,182, 88, 1,212, 63,149, 52,180,238,175,171,255,101,125,113,153,214,210,181, 99,183,234,147,
+167,202,187,207, 59,245,145,178,141,132,159,143, 56,115,187,104,120, 71, 1, 90, 43, 25,144, 59,241,103, 61,127, 0, 62, 7, 4,
+ 46, 90,180,136,186,251,193,187,167, 24,198, 22,229,106,134,164,162,206, 82, 7, 74, 2, 56, 38, 35, 49,176,219, 9, 24,154, 70,
+135,208, 8, 28,168, 61,130,146,131,103,144,173,203, 46, 10,248,196, 75,159, 6, 32,124, 26, 96, 51, 35,160,103, 57, 78, 95,140,
+245, 75,252, 93,141,128,245,235,215, 35, 50, 50, 18,213,213,213, 88,177, 98, 5,218, 91,216, 63, 24,134,128, 39,239,223,207, 40,
+ 64,119, 56, 70,253, 75, 0,140, 0,144, 1,160, 84,148,239, 32, 27, 0,173,149, 7,192, 83, 68, 96,205,154, 53, 42, 87, 67, 65,
+163,209, 8, 78, 24,196, 21,130,246,144, 98,151,235,253,115,133, 95,171,213,178,221, 30,220,251,202,251,132, 89, 35, 96,250, 27,
+155, 64,114,128, 46,243,116, 40,250,107, 42,238,201,250, 47, 16, 18,130, 14, 10,121,155, 92, 47,119,142,191,187,239,126,230, 1,
+160, 1, 72,156,117, 43, 9,176, 62, 46,205, 26,119,103,197, 95, 55,228,197, 45,123,114, 66,199,152, 30, 73, 86, 0,199, 53, 26,
+ 77, 39, 56,230, 23,251, 85, 31,236, 35,183,111,159,154, 29,241,239,143,113, 71,249,242,224,133, 8,122, 48, 66,253, 66,224, 42,
+250,108, 68,160,115,231,206,110,173,179, 3,251, 14,236,140,189,253, 86,216,103,209,199,239,191,245,254,161,209, 17,209,176,216,
+ 44, 32,132, 64, 46,147,163,198,220,128, 67,191,237,195,150,255,108,133,234, 14,149, 42, 27,217, 1,159,227,235,123,230, 97,235,
+214,173, 40, 41, 17,158, 3,224,186, 17,128,128,196,159,203,183, 96,193, 2,178,106,213, 42, 44, 93,186, 20,237,185,207,159,107,
+ 8, 20, 21, 21,249,117,172,183,125, 4,112, 78,133, 99,190,191, 5,192, 11, 0,190, 7, 96, 23,229,219, 61,134, 15, 31,142,163,
+ 71,143, 98, 67, 86,102,139, 60, 0,174,217, 0,101, 46, 13,165,215, 62,126,238,111,215,237, 66, 22, 35,240, 38,244,126, 70, 1,
+ 2, 66,107, 77, 3,100,141, 17,157, 78,135,194,194, 66,166,172,172,140, 43,100, 42,189, 94, 47,216,187,153,177,114, 51,192, 73,
+252,115,255,178,247,154,190,183,209,104, 24,159, 13, 24, 67,252,186,119,235, 0, 92,133, 99,250,207,156, 0,207,177,242,169,164,
+161,141,227, 11,191,237,248,232,203, 31, 66,167,211,201, 11, 11, 11,123,162,121, 58,107,191,234,163,181, 35, 1,190,242,251,251,
+108, 57, 91,161, 75,192,147,248, 91, 83,250, 2,121,190, 29,179, 79,222,222, 70,117,144, 42,201,193,216, 67, 24,123,231, 88,244,
+138,232, 5, 48, 4,151, 45,213, 56,240,195, 1, 84,158,172,196, 3, 3, 31, 80, 45, 92,184,176,205,235,131,107, 4, 4, 75,172,
+217, 72,192,205, 50,224, 47,128,190,250, 96, 97,131,243, 35, 66,232,141,203,202,228, 31, 1,104, 45,100,100,100,184, 21,123,151,
+149,216,184, 48,184,203, 91,236, 75,104,253, 69,107, 76, 3,204,202,202,130, 78,167,163, 11, 11, 11,101,206,174, 3, 86,252, 31,
+240,114,221,110,225, 92, 76,169, 53, 82, 41, 19, 47,229,109,210, 56,233,116,186, 80,231,115,185,220, 89,100, 79, 79, 79,127, 44,
+ 64,218,208,241,127,127,191, 88,167,211,221, 87, 88, 88,136,194,194, 66, 11, 0,133,243, 19, 12,225,167,120,206,247, 23, 44,210,
+206,237,205,234, 75,168,112, 7,163, 75,160,188,188,156, 42, 72, 43, 32, 49, 11, 98, 84,232,237,126,159,138,180, 2, 3,223,241,
+ 0, 27,223,218, 72,173, 93,187, 54,105,243, 27,155, 17,219,247, 54, 3, 0,252,124,226, 39,213,228,241, 41, 88,247,238,186,162,
+ 79,240,137, 95,231,185,117,235, 86,106,194,132, 9, 45,102, 5,216,108,129,205, 16, 11,182, 88,255,222, 70,251,139,104,159, 81,
+ 0,215, 50,222, 6,128, 47,194,145,161,214, 0, 0, 0,157, 73, 68, 65, 84, 79, 92,128,167,238,239,131, 78, 90,153, 63, 88,199,
+187,229,211,104, 52,164,176,176, 80,198,189, 95,220, 8,139, 64, 3,165,168,149, 4,185, 61, 54, 66, 17, 0,140, 0, 33,112, 36,
+230, 15, 67, 96,243,123,217,250,248,181,176,176,144,157, 87, 86, 23, 31, 31,223, 53, 43, 43, 43,180, 61,220,203,214, 12,219, 7,
+147,187,188,188,156, 42, 95, 82, 30,180,123,240,252,243,207, 23,185, 30,119,224,203,131, 1,159,231,222,189,123, 69,113, 21, 33,
+ 26, 1, 60,156,104,202,223,117,132, 69,136, 16, 33, 66,132, 8, 17, 55, 47, 36,226, 45, 16, 33, 66,132, 8, 17, 34, 68, 3, 64,
+132, 8, 17, 34, 68,136, 16,241, 7,192,255, 7, 88,144, 50,208,112,133, 45, 53, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+>>>>>>> .merge-right.r11522
};
diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c
index 2640a19ebf1..fc78200ab5c 100644
--- a/source/blender/src/booleanops.c
+++ b/source/blender/src/booleanops.c
@@ -449,8 +449,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
float map_mat[4][4];
DerivedMesh *dm = NULL;
- Mesh *me1 = get_mesh(ob);
- Mesh *me2 = get_mesh(ob_select);
+ Mesh *me1 = get_mesh(ob_select);
+ Mesh *me2 = get_mesh(ob);
if (me1 == NULL || me2 == NULL) return 0;
if (!me1->totface || !me2->totface) return 0;
@@ -458,9 +458,9 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
// we map the final object back into ob's local coordinate space. For this
// we need to compute the inverse transform from global to ob (inv_mat),
// and the transform from ob to ob_select for use in interpolation (map_mat)
- Mat4Invert(inv_mat, ob_select->obmat);
- Mat4MulMat4(map_mat, ob->obmat, inv_mat);
Mat4Invert(inv_mat, ob->obmat);
+ Mat4MulMat4(map_mat, ob_select->obmat, inv_mat);
+ Mat4Invert(inv_mat, ob_select->obmat);
{
// interface with the boolean module:
@@ -484,8 +484,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
default : op_type = e_csg_intersection;
}
- BuildMeshDescriptors(ob, 0, &fd_1, &vd_1);
- BuildMeshDescriptors(ob_select, me1->totface, &fd_2, &vd_2);
+ BuildMeshDescriptors(ob_select, 0, &fd_1, &vd_1);
+ BuildMeshDescriptors(ob, me1->totface, &fd_2, &vd_2);
bool_op = CSG_NewBooleanFunction();
@@ -500,7 +500,7 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
// iterate through results of operation and insert
// into new object
dm = ConvertCSGDescriptorsToDerivedMesh(
- &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob, ob_select);
+ &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob_select, ob);
// free up the memory
CSG_FreeVertexDescriptor(&vd_o);
@@ -532,6 +532,13 @@ int NewBooleanMesh(Base *base, Base *base_select, int int_op_type)
maxmat= ob->totcol + ob_select->totcol;
mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
+ /* put some checks in for nice user feedback */
+ if((!(get_mesh(ob)->totface)) || (!(get_mesh(ob_select)->totface)))
+ {
+ MEM_freeN(mat);
+ return -1;
+ }
+
dm= NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, mat, &totmat);
if (dm == NULL) {
@@ -540,7 +547,7 @@ int NewBooleanMesh(Base *base, Base *base_select, int int_op_type)
}
/* create a new blender mesh object - using 'base' as a template */
- ob_new= AddNewBlenderMesh(base);
+ ob_new= AddNewBlenderMesh(base_select);
me_new= ob_new->data;
DM_to_mesh(dm, me_new);
diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c
index f694c9aa862..e8062422e2a 100644
--- a/source/blender/src/butspace.c
+++ b/source/blender/src/butspace.c
@@ -572,6 +572,9 @@ void do_butspace(unsigned short event)
else if(event<=B_RENDERBUTS) {
do_render_panels(event); // buttons_scene.c
}
+ else if(event<=B_SEQUENCERBUTS) {
+ do_sequencer_panels(event);
+ }
else if(event<=B_COMMONEDITBUTS) {
do_common_editbuts(event);
}
@@ -725,6 +728,8 @@ void drawbutspace(ScrArea *sa, void *spacedata)
if(tab== TAB_SCENE_RENDER)
render_panels();
+ else if(tab == TAB_SCENE_SEQUENCER)
+ sequencer_panels();
else if(tab == TAB_SCENE_ANIM)
anim_panels();
else if(tab == TAB_SCENE_SOUND)
@@ -738,6 +743,8 @@ void drawbutspace(ScrArea *sa, void *spacedata)
object_panels();
else if(tab==TAB_OBJECT_PHYSICS)
physics_panels();
+ else if(tab==TAB_OBJECT_PARTICLE)
+ particle_panels();
break;
case CONTEXT_SHADING:
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index ec2b7b3b274..edd9a2ff827 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -33,6 +33,7 @@
#include <time.h>
#include <math.h>
#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#ifdef WIN32
@@ -50,6 +51,7 @@
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_color_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
@@ -66,6 +68,7 @@
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_radio_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
@@ -77,6 +80,7 @@
#include "BKE_blender.h"
#include "BKE_brush.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_colortools.h"
@@ -86,9 +90,13 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_multires.h"
#include "BKE_packedFile.h"
+#include "BKE_particle.h"
#include "BKE_scene.h"
+#include "BKE_bmesh.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -99,15 +107,19 @@
#include "BSE_filesel.h"
#include "BIF_gl.h"
+#include "BIF_editaction.h"
#include "BIF_editarmature.h"
#include "BIF_editconstraint.h"
#include "BIF_editdeform.h"
#include "BIF_editfont.h"
#include "BIF_editkey.h"
#include "BIF_editmesh.h"
+#include "BIF_editparticle.h"
+#include "BIF_imasel.h"
#include "BIF_interface.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
+#include "BIF_poselib.h"
#include "BIF_poseobject.h"
#include "BIF_renderwin.h"
#include "BIF_resources.h"
@@ -136,6 +148,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_effect.h"
#include "BKE_font.h"
+#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_lattice.h"
@@ -383,6 +396,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
EditFace *efa;
Base *base;
Object *ob= OBACT;
+ Material *ma;
Nurb *nu;
Curve *cu;
BezTriple *bezt;
@@ -395,8 +409,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
case B_MATWICH:
if(G.obedit && G.obedit->actcol>0) {
if(G.obedit->type == OB_MESH) {
- efa= em->faces.first;
- while(efa) {
+ for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->f & SELECT) {
if(index== -1) index= efa->mat_nr;
else if(index!=efa->mat_nr) {
@@ -404,7 +417,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
return;
}
}
- efa= efa->next;
}
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
@@ -471,6 +483,30 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
BIF_undo_push("Assign material index");
}
break;
+ case B_MATASS_BROWSE:
+ /* if slot available, make that index active, and assign */
+ /* else, make new slot, and assign */
+ ma= BLI_findlink(&G.main->mat, G.buts->menunr-1);
+ if(ma) {
+ ob->actcol= find_material_index(ob, ma);
+ if(ob->actcol==0) {
+ assign_material(ob, ma, ob->totcol+1);
+ ob->actcol= ob->totcol;
+ }
+ }
+ else {
+ do_common_editbuts(B_MATNEW);
+ }
+ do_common_editbuts(B_MATASS);
+ break;
+
+ case B_MATCOL2:
+ ma= give_current_material(ob, ob->actcol);
+ BKE_icon_changed(BKE_icon_getid((ID *)ma));
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+
case B_MATSEL:
case B_MATDESEL:
if(G.obedit) {
@@ -492,14 +528,14 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
while(a--) {
if(bezt->hide==0) {
if(event==B_MATSEL) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
}
else {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
}
}
bezt++;
@@ -510,8 +546,8 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
bp= nu->bp;
while(a--) {
if(bp->hide==0) {
- if(event==B_MATSEL) bp->f1 |= 1;
- else bp->f1 &= ~1;
+ if(event==B_MATSEL) bp->f1 |= SELECT;
+ else bp->f1 &= ~SELECT;
}
bp++;
}
@@ -536,7 +572,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
if(G.obedit->type == OB_MESH) reveal_mesh();
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
}
- else if(G.f & G_FACESELECT) reveal_tface();
+ else if(FACESEL_PAINT_TEST) reveal_tface();
break;
case B_SELSWAP:
@@ -602,11 +638,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
break;
case B_ADDKEY:
- if(get_mesh(ob) && get_mesh(ob)->mr) {
- error("Cannot create shape keys on a multires mesh.");
- } else {
- insert_shapekey(ob);
- }
+ insert_shapekey(ob);
break;
case B_SETKEY:
ob->shapeflag |= OB_SHAPE_TEMPLOCK;
@@ -711,6 +743,8 @@ static void delete_customdata_layer(void *data1, void *data2)
from the data stored in multires */
if(me && me->mr) {
multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
+ multires_level_to_editmesh(OBACT, me, 0);
+ multires_finish_mesh_update(OBACT);
}
else if(G.obedit) {
EM_free_data_layer(data, type);
@@ -723,8 +757,6 @@ static void delete_customdata_layer(void *data1, void *data2)
if(!CustomData_has_layer(data, type)) {
if(type == CD_MCOL && (G.f & G_VERTEXPAINT))
G.f &= ~G_VERTEXPAINT; /* get out of vertexpaint mode */
- if(type == CD_MTFACE && (G.f & G_FACESELECT))
- set_faceselect(); /* get out of faceselect mode */
}
/*reconstruct active layer*/
@@ -955,7 +987,9 @@ static uiBlock *modifiers_add_menu(void *ob_v)
ModifierTypeInfo *mti = modifierType_getInfo(i);
/* Only allow adding through appropriate other interfaces */
- if(ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue;
+ if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
+
+ if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue;
if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@ -995,6 +1029,12 @@ static void modifiers_del(void *ob_v, void *md_v)
if (!md)
return;
+ if(md->type==eModifierType_ParticleSystem){
+ ParticleSystemModifierData *psmd=(ParticleSystemModifierData*)md;
+ BLI_remlink(&ob->particlesystem, psmd->psys);
+ psys_free(ob,psmd->psys);
+ }
+
BLI_remlink(&ob->modifiers, md_v);
modifier_free(md_v);
@@ -1206,7 +1246,93 @@ void autocomplete_meshob(char *str, void *arg_v)
autocomplete_end(autocpl, str);
}
}
+static void modifiers_convertParticles(void *obv, void *mdv)
+{
+ Object *obn;
+ ModifierData *md = mdv;
+ ParticleSystem *psys;
+ ParticleCacheKey *key, **cache;
+ Mesh *me;
+ MVert *mvert;
+ MFace *mface;
+ int a, k, kmax;
+ int totvert=0, totface=0, cvert=0;
+ int totpart=0, totchild=0;
+ if(md->type != eModifierType_ParticleSystem) return;
+
+ if(G.f & G_PARTICLEEDIT) return;
+
+ psys=((ParticleSystemModifierData *)md)->psys;
+
+ if(psys->part->draw_as != PART_DRAW_PATH || psys->pathcache == 0) return;
+
+ totpart= psys->totcached;
+ totchild= psys->totchildcache;
+
+ if(totchild && (psys->part->draw&PART_DRAW_PARENT)==0)
+ totpart= 0;
+
+ /* count */
+ cache= psys->pathcache;
+ for(a=0; a<totpart; a++) {
+ key= cache[a];
+ totvert+= (int)(key->col[3])+1;
+ totface+= (int)(key->col[3]);
+ }
+
+ cache= psys->childcache;
+ for(a=0; a<totchild; a++) {
+ key= cache[a];
+ totvert+= (int)(key->col[3])+1;
+ totface+= (int)(key->col[3]);
+ }
+
+ if(totvert==0) return;
+
+ /* add new mesh */
+ obn= add_object(OB_MESH);
+ me= obn->data;
+
+ me->totvert= totvert;
+ me->totface= totface;
+
+ me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+ me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, totface);
+
+ mvert= me->mvert;
+ mface= me->mface;
+
+ /* copy coordinates */
+ cache= psys->pathcache;
+ for(a=0; a<totpart; a++){
+ key= cache[a];
+ kmax= (int)(key->col[3]);
+ for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
+ VECCOPY(mvert->co,key->co);
+ if(k){
+ mface->v1= cvert-1;
+ mface->v2= cvert;
+ mface++;
+ }
+ }
+ }
+
+ cache=psys->childcache;
+ for(a=0; a<totchild; a++) {
+ key=cache[a];
+ kmax=(int)(key->col[3]);
+ for(k=0; k<=kmax; k++,key++,cvert++,mvert++) {
+ VECCOPY(mvert->co,key->co);
+ if(k){
+ mface->v1=cvert-1;
+ mface->v2=cvert;
+ mface++;
+ }
+ }
+ }
+ make_edges(me, 0);
+}
static void modifiers_applyModifier(void *obv, void *mdv)
{
Object *ob = obv;
@@ -1238,7 +1364,7 @@ static void modifiers_applyModifier(void *obv, void *mdv)
return;
}
- sculptmode_pmv_off(me);
+ mesh_pmv_off(ob, me);
dm = mesh_create_derived_for_modifier(ob, md);
if (!dm) {
@@ -1470,6 +1596,60 @@ void set_uvproject_uvlayer(void *arg1, void *arg2)
strcpy(umd->uvlayer_name, layer->name);
}
+static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
+{
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md_v;
+ Object *ob = (Object*)ob_v;
+
+ if(mmd->bindcos) {
+ if(mmd->bindweights) MEM_freeN(mmd->bindweights);
+ if(mmd->bindcos) MEM_freeN(mmd->bindcos);
+ if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
+ if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+ if(mmd->dynverts) MEM_freeN(mmd->dynverts);
+ mmd->bindweights= NULL;
+ mmd->bindcos= NULL;
+ mmd->dyngrid= NULL;
+ mmd->dyninfluences= NULL;
+ mmd->dynverts= NULL;
+ mmd->totvert= 0;
+ mmd->totcagevert= 0;
+ mmd->totinfluence= 0;
+ }
+ else {
+ DerivedMesh *dm;
+ int mode= mmd->modifier.mode;
+
+ /* force modifier to run, it will call binding routine */
+ mmd->needbind= 1;
+ mmd->modifier.mode |= eModifierMode_Realtime;
+
+ if(ob->type == OB_MESH) {
+ dm= mesh_create_derived_view(ob, 0);
+ dm->release(dm);
+ }
+ else if(ob->type == OB_LATTICE) {
+ lattice_calc_modifiers(ob);
+ }
+ else if(ob->type==OB_MBALL) {
+ makeDispListMBall(ob);
+ }
+ else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ makeDispListCurveTypes(ob, 0);
+ }
+
+ mmd->needbind= 0;
+ mmd->modifier.mode= mode;
+ }
+}
+
+void modifiers_explodeFacepa(void *arg1, void *arg2)
+{
+ ExplodeModifierData *emd=arg1;
+
+ emd->flag |= eExplodeFlag_CalcFaces;
+}
+
static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1488,7 +1668,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockSetCol(block, TH_AUTO);
/* open/close icon */
- if (!isVirtual) {
+ if (!isVirtual && md->type!=eModifierType_Collision) {
uiBlockSetEmboss(block, UI_EMBOSSN);
uiDefIconButBitI(block, ICONTOG, eModifierMode_Expanded, B_MODIFIER_REDRAW, VICON_DISCLOSURE_TRI_RIGHT, x-10, y-2, 20, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Modifier");
}
@@ -1505,10 +1685,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockBeginAlign(block);
uiDefBut(block, TEX, B_MODIFIER_REDRAW, "", x+10, y-1, buttonWidth-60, 19, md->name, 0.0, sizeof(md->name)-1, 0.0, 0.0, "Modifier name");
- /* Softbody not allowed in this situation, enforce! */
- if (md->type!=eModifierType_Softbody || !(ob->pd && ob->pd->deflect)) {
+ /* Softbody not allowed in this situation, enforce! */
+ if ((md->type!=eModifierType_Softbody && md->type!=eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) {
uiDefIconButBitI(block, TOG, eModifierMode_Render, B_MODIFIER_RECALC, ICON_SCENE, x+10+buttonWidth-60, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during rendering");
- uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
+ but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_MODIFIER_RECALC, VICON_VIEW3D, x+10+buttonWidth-40, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during interactive display");
if (mti->flags&eModifierTypeFlag_SupportsEditmode) {
uiDefIconButBitI(block, TOG, eModifierMode_Editmode, B_MODIFIER_RECALC, VICON_EDIT, x+10+buttonWidth-20, y-1, 19, 19,&md->mode, 0, 0, 1, 0, "Enable modifier during Editmode (only if enabled for display)");
}
@@ -1545,9 +1725,13 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiButSetFunc(but, modifiers_moveDown, ob, md);
uiBlockSetEmboss(block, UI_EMBOSSN);
-
- but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
- uiButSetFunc(but, modifiers_del, ob, md);
+
+ // deletion over the deflection panel
+ if(md->type!=eModifierType_Collision)
+ {
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_X, x+width-70+40, y, 16, 16, NULL, 0.0, 0.0, 0.0, 0.0, "Delete modifier");
+ uiButSetFunc(but, modifiers_del, ob, md);
+ }
uiBlockSetCol(block, TH_AUTO);
}
@@ -1568,7 +1752,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
} else if (md->type==eModifierType_Build) {
height = 86;
} else if (md->type==eModifierType_Mirror) {
- height = 67;
+ height = 86;
+ } else if (md->type==eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData*) md;
+ height = 105; /* height = 124; */
+ if ((bmd->lim_flags & BME_BEVEL_ANGLE) || ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT))) height += 19;
} else if (md->type==eModifierType_EdgeSplit) {
EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
height = 48;
@@ -1596,7 +1784,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
if(wmd->flag & MOD_WAVE_NORM)
height += 19;
} else if (md->type==eModifierType_Armature) {
- height = 67;
+ height = 105;
} else if (md->type==eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData*) md;
height = 86;
@@ -1605,23 +1793,42 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
if(hmd->indexar==NULL)
height += 20;
} else if (md->type==eModifierType_Softbody) {
- height = 26;
+ height = 31;
+ } else if (md->type==eModifierType_Cloth) {
+ height = 31;
+ } else if (md->type==eModifierType_Collision) {
+ height = 31;
} else if (md->type==eModifierType_Boolean) {
height = 48;
} else if (md->type==eModifierType_Array) {
height = 211;
- }
-
+ } else if (md->type==eModifierType_MeshDeform) {
+ MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
+ height = (mmd->bindcos)? 73: 93;
+ } else if (md->type==eModifierType_ParticleSystem) {
+ height = 31;
+ } else if (md->type==eModifierType_ParticleInstance) {
+ height = 94;
+ } else if (md->type==eModifierType_Explode) {
+ height = 94;
+ }
/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, "");
y -= 18;
- if (!isVirtual) {
+ if (!isVirtual && (md->type!=eModifierType_Collision)) {
uiBlockBeginAlign(block);
- but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
- uiButSetFunc(but, modifiers_applyModifier, ob, md);
- if (md->type!=eModifierType_Softbody) {
+ if (md->type==eModifierType_ParticleSystem) {
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
+ uiButSetFunc(but, modifiers_convertParticles, ob, md);
+ }
+ else{
+ but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
+ uiButSetFunc(but, modifiers_applyModifier, ob, md);
+ }
+
+ if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy", lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
uiButSetFunc(but, modifiers_copyModifier, ob, md);
}
@@ -1689,6 +1896,70 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
&mmd->flag, 0, 0, 0, 0,
"Mirror the V texture coordinate around "
"the 0.5 point");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+ "Ob: ", lx, (cy -= 19), buttonWidth, 19,
+ &mmd->mirror_ob,
+ "Object to use as mirror");
+ } else if (md->type==eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData*) md;
+ /*uiDefButS(block, ROW, B_MODIFIER_RECALC, "Distance",
+ lx, (cy -= 19), (buttonWidth/2), 19, &bmd->val_flags,
+ 11.0, 0, 0, 0,
+ "Interpret bevel value as a constant distance from each edge");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Radius",
+ (lx+buttonWidth/2), cy, (buttonWidth - buttonWidth/2), 19, &bmd->val_flags,
+ 11.0, BME_BEVEL_RADIUS, 0, 0,
+ "Interpret bevel value as a radius - smaller angles will be beveled more");*/
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->value,
+ 0.0, 0.5, 5, 2,
+ "Bevel value/amount");
+ /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->res,
+ 1, 4, 5, 2,
+ "Number of times to bevel");*/
+ uiDefButBitS(block, TOG, BME_BEVEL_VERT,
+ B_MODIFIER_RECALC, "Only Vertices",
+ lx, (cy -= 19), buttonWidth, 19,
+ &bmd->flags, 0, 0, 0, 0,
+ "Bevel only verts/corners; not edges");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 1, "Limit using:", lx, (cy-=25), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "None",
+ lx, (cy -= 19), (buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, 0, 0, 0,
+ "Bevel the entire mesh by a constant amount");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Angle",
+ (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, BME_BEVEL_ANGLE, 0, 0,
+ "Only bevel edges with sharp enough angles between faces");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "BevWeight",
+ lx+(2*buttonWidth/3), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->lim_flags,
+ 12.0, BME_BEVEL_WEIGHT, 0, 0,
+ "Use bevel weights to determine how much bevel is applied; apply them separately in vert/edge select mode");
+ if ((bmd->lim_flags & BME_BEVEL_WEIGHT) && !(bmd->flags & BME_BEVEL_VERT)) {
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Min",
+ lx, (cy -= 19), (buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, BME_BEVEL_EMIN, 0, 0,
+ "The sharpest edge's weight is used when weighting a vert");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Average",
+ (lx+buttonWidth/3), cy, (buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, 0, 0, 0,
+ "The edge weights are averaged when weighting a vert");
+ uiDefButS(block, ROW, B_MODIFIER_RECALC, "Max",
+ (lx+2*(buttonWidth/3)), cy, buttonWidth-2*(buttonWidth/3), 19, &bmd->e_flags,
+ 13.0, BME_BEVEL_EMAX, 0, 0,
+ "The largest edge's wieght is used when weighting a vert");
+ }
+ else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Angle:",
+ lx, (cy -= 19), buttonWidth, 19, &bmd->bevel_angle,
+ 0.0, 180.0, 100, 2,
+ "Angle above which to bevel edges");
+ }
} else if (md->type==eModifierType_EdgeSplit) {
EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,
@@ -1725,7 +1996,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
"Material value that gives no displacement");
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Strength:",
lx, (cy -= 19), buttonWidth, 19, &dmd->strength,
- -1000, 1000, 10, 10,
+ -1000, 1000, 10, 0.1,
"Strength of displacement");
sprintf(str, "Direction%%t|Normal%%x%d|RGB -> XYZ%%x%d|"
"Z%%x%d|Y%%x%d|X%%x%d",
@@ -1862,11 +2133,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockBeginAlign(block);
if(wmd->speed >= 0)
- uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify starting frame of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify starting frame of the wave");
else
- uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify ending frame of the wave");
- uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
- uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:", lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:", lx,(cy-=19),buttonWidth,19, &wmd->lifetime, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
+ uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:", lx,(cy-=19),buttonWidth,19, &wmd->damp, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
cy -= 9;
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
@@ -1913,11 +2184,17 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
ArmatureModifierData *amd = (ArmatureModifierData*) md;
uiDefIDPoinBut(block, modifier_testArmatureObj, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &amd->object, "Armature object to deform with");
- but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth-40,19, &amd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall armature influence");
uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ uiDefButBitS(block, TOG, ARM_DEF_INVERT_VGROUP, B_ARM_RECALCDATA, "Inv", lx+buttonWidth-40,cy, 40, 20, &amd->deformflag, 0, 0, 0, 0, "Invert vertex group influence");
+
uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vert.Groups", lx,cy-=19,buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform");
uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform");
+ uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", lx,(cy-=19),buttonWidth/2,20, &amd->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions");
+ uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA, "B-Bone Rest", lx+buttonWidth/2,cy,(buttonWidth + 1)/2,20, &amd->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position");
+ uiDefButS(block, TOG, B_ARM_RECALCDATA, "MultiModifier", lx,cy-=19, buttonWidth, 20, &amd->multi, 0, 0, 0, 0, "Use same input as previous modifier, and mix results using overall vgroup");
+
} else if (md->type==eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData*) md;
uiDefButF(block, NUM, B_MODIFIER_RECALC, "Falloff: ", lx, (cy-=19), buttonWidth,19, &hmd->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends");
@@ -1941,6 +2218,10 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
}
} else if (md->type==eModifierType_Softbody) {
uiDefBut(block, LABEL, 1, "See Softbody panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Cloth) {
+ uiDefBut(block, LABEL, 1, "See Cloth panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_Collision) {
+ uiDefBut(block, LABEL, 1, "See Deflection panel.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
} else if (md->type==eModifierType_Boolean) {
BooleanModifierData *bmd = (BooleanModifierData*) md;
uiDefButI(block, MENU, B_MODIFIER_RECALC, "Operation%t|Intersect%x0|Union%x1|Difference%x2", lx,(cy-=19),buttonWidth,19, &bmd->operation, 0.0, 1.0, 0, 0, "Boolean operation to perform");
@@ -2088,7 +2369,62 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
&amd->end_cap,
"Mesh object to use as end cap");
uiButSetCompleteFunc(but, autocomplete_meshob, (void *)ob);
+ } else if (md->type==eModifierType_MeshDeform) {
+ MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
+
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-19), buttonWidth-40,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
+
+ uiBlockBeginAlign(block);
+ if(mmd->bindcos) {
+ but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Unbind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Unbind mesh from cage");
+ uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
+ }
+ else {
+ but= uiDefBut(block, BUT, B_MODIFIER_RECALC, "Bind", lx,(cy-=24), buttonWidth,19, 0, 0, 0, 0, 0, "Bind mesh to cage");
+ uiButSetFunc(but,modifiers_bindMeshDeform,ob,md);
+ uiDefButS(block, NUM, B_NOP, "Precision:", lx,(cy-19), buttonWidth/2 + 20,19, &mmd->gridsize, 2, 10, 0.5, 0, "The grid size for binding");
+ uiDefButBitS(block, TOG, MOD_MDEF_DYNAMIC_BIND, B_MODIFIER_RECALC, "Dynamic", lx+(buttonWidth+1)/2 + 20, (cy-=19), buttonWidth/2 - 20,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
+ }
+ uiBlockEndAlign(block);
+ } else if (md->type==eModifierType_ParticleSystem) {
+ uiDefBut(block, LABEL, 1, "See Particle buttons.", lx, (cy-=19), buttonWidth,19, NULL, 0.0, 0.0, 0, 0, "");
+ } else if (md->type==eModifierType_ParticleInstance) {
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy -= 19), buttonWidth, 19, &pimd->ob, "Object that has the particlesystem");
+ uiDefButS(block, NUM, B_MODIFIER_RECALC, "PSYS:", lx, (cy -= 19), buttonWidth, 19, &pimd->psys, 1, 10, 10, 3, "Particlesystem number in the object");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Parents, B_MODIFIER_RECALC, "Normal", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from normal particles");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Children, B_MODIFIER_RECALC, "Children", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances from child particles");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Path, B_MODIFIER_RECALC, "Path", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Create instances along particle paths");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy -= 19), buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are unborn");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are alive");
+ uiDefButBitS(block, TOG, eParticleInstanceFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &pimd->flag, 0, 0, 0, 0, "Show instances when particles are dead");
+ } else if (md->type==eModifierType_Explode) {
+ ExplodeModifierData *emd = (ExplodeModifierData*) md;
+ uiBut *but;
+ char *menustr= get_vertexgroup_menustr(ob);
+ int defCount=BLI_countlist(&ob->defbase);
+ if(defCount==0) emd->vgroup=0;
+
+ but=uiDefButS(block, MENU, B_MODIFIER_RECALC, menustr, lx, (cy-=19), buttonWidth/2,19, &emd->vgroup, 0, defCount, 0, 0, "Protect this vertex group");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+ MEM_freeN(menustr);
+
+ but=uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "", lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->protect, 0.0f, 1.0f, 0, 0, "Clean vertex group edges");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+
+ but=uiDefBut(block, BUT, B_MODIFIER_RECALC, "Refresh", lx, (cy-=19), buttonWidth/2,19, 0, 0, 0, 0, 0, "Recalculate faces assigned to particles");
+ uiButSetFunc(but,modifiers_explodeFacepa,emd,0);
+
+ uiDefButBitS(block, TOG, eExplodeFlag_EdgeSplit, B_MODIFIER_RECALC, "Split Edges", lx+buttonWidth/2, cy, buttonWidth/2,19, &emd->flag, 0, 0, 0, 0, "Split face edges for nicer shrapnel");
+ uiDefButBitS(block, TOG, eExplodeFlag_Unborn, B_MODIFIER_RECALC, "Unborn", lx, (cy-=19), buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are unborn");
+ uiDefButBitS(block, TOG, eExplodeFlag_Alive, B_MODIFIER_RECALC, "Alive", lx+buttonWidth/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are alive");
+ uiDefButBitS(block, TOG, eExplodeFlag_Dead, B_MODIFIER_RECALC, "Dead", lx+buttonWidth*2/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are dead");
}
+
uiBlockEndAlign(block);
y-=height;
@@ -2108,6 +2444,8 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiDefBut(block, LABEL, B_NOP, str, x+15, y+15, width-35, 19, NULL, 0.0, 0.0, 0.0, 0.0, "");
}
+ uiClearButLock();
+
y -= 3+6;
*xco = x;
@@ -2145,7 +2483,7 @@ static void editing_panel_modifiers(Object *ob)
if(yco < 0) uiNewPanelHeight(block, 204-yco);
}
-static char *make_key_menu(Key *key)
+static char *make_key_menu(Key *key, int startindex)
{
KeyBlock *kb;
int index= 1;
@@ -2155,7 +2493,7 @@ static char *make_key_menu(Key *key)
str= MEM_mallocN(index*40, "key string");
str[0]= 0;
- index= 1;
+ index= startindex;
for (kb = key->block.first; kb; kb=kb->next, index++) {
sprintf (item, "|%s%%x%d", kb->name, index);
strcat(str, item);
@@ -2199,14 +2537,17 @@ static void editing_panel_shapes(Object *ob)
uiBlockBeginAlign(block);
if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object");
+ if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
+ uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
- uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 35,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
- strp= make_key_menu(key);
- uiDefButS(block, MENU, B_SETKEY, strp, 55,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
+ uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT, 55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
+ strp= make_key_menu(key, 1);
+ uiDefButS(block, MENU, B_SETKEY, strp, 75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
MEM_freeN(strp);
- uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 75,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
+
+ uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT, 95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
uiClearButLock();
- uiDefBut(block, TEX, B_NAMEKEY, "", 95, 150, 190, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
+ uiDefBut(block, TEX, B_NAMEKEY, "", 115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
uiDefIconBut(block, BUT, B_DELKEY, ICON_X, 285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
uiBlockEndAlign(block);
@@ -2217,9 +2558,14 @@ static void editing_panel_shapes(Object *ob)
uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
uiBlockEndAlign(block);
}
- if(key->type && ob->shapenr!=1)
+ if(key->type && ob->shapenr!=1) {
uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", 10, 90, 150,19, &kb->vgroup, 0.0, 31.0, 0, 0, "Vertex Weight Group name, to blend with Basis Shape");
+ strp= make_key_menu(key, 0);
+ uiDefButS(block, MENU, B_MODIFIER_RECALC, strp, 160, 90, 150,19, &kb->relative, 0.0, 0.0, 0, 0, "Shape used as a relative key");
+ MEM_freeN(strp);
+ }
+
if(key->type==0)
uiDefButS(block, NUM, B_DIFF, "Slurph:", 10, 60, 150, 19, &(key->slurph), -500.0, 500.0, 0, 0, "Creates a delay in amount of frames in applying keypositions, first vertex goes first");
@@ -2424,7 +2770,7 @@ void do_fontbuts(unsigned short event)
sa= closest_bigger_area();
areawinset(sa->win);
- activate_fileselect(FILE_SPECIAL, "SELECT FONT", str, load_buts_vfont);
+ activate_fileselect(FILE_LOADFONT, "SELECT FONT", str, load_buts_vfont);
break;
case B_PACKFONT:
@@ -2583,6 +2929,7 @@ void do_fontbuts(unsigned short event)
}
}
+#ifdef INTERNATIONAL
static void editing_panel_char_type(Object *ob, Curve *cu)
{
uiBlock *block;
@@ -2608,6 +2955,7 @@ static void editing_panel_char_type(Object *ob, Curve *cu)
uiDefButI(block, BUT, B_SETUPCHAR, "U", 280, 185, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table up");
uiDefButI(block, BUT, B_SETDOWNCHAR, "D", 280, 0, 15, 15, &G.charstart, 0, 0xffff, 0, 0, "Scroll character table down");
}
+#endif
static void editing_panel_font_type(Object *ob, Curve *cu)
{
@@ -2796,6 +3144,10 @@ void do_curvebuts(unsigned short event)
allqueue(REDRAWVIEW3D, 0);
}
break;
+ case B_TILTINTERP:
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
case B_SUBSURFTYPE:
/* fallthrough */
case B_MAKEDISP:
@@ -2860,6 +3212,40 @@ void do_curvebuts(unsigned short event)
allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
break;
+
+ /* Buttons for aligning handles */
+ case B_SETPT_AUTO:
+ if(ob->type==OB_CURVE) {
+ sethandlesNurb(1);
+ BIF_undo_push("Auto Curve Handles");
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
+ case B_SETPT_VECTOR:
+ if(ob->type==OB_CURVE) {
+ sethandlesNurb(2);
+ BIF_undo_push("Vector Curve Handles");
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
+ case B_SETPT_ALIGN:
+ if(ob->type==OB_CURVE) {
+ sethandlesNurb(5);
+ BIF_undo_push("Align Curve Handles");
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
+ case B_SETPT_FREE:
+ if(ob->type==OB_CURVE) {
+ sethandlesNurb(6);
+ BIF_undo_push("Free Align Curve Handles");
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
}
}
@@ -2906,6 +3292,14 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu)
nu= lastnu;
if(nu==NULL) nu= editNurb.first;
if(nu) {
+ if (ob->type==OB_CURVE) {
+ uiDefBut(block, LABEL, 0, "Tilt",
+ 467,87,72, 18, 0, 0, 0, 0, 0, "");
+ /* KEY_LINEAR, KEY_CARDINAL, KEY_BSPLINE */
+ uiDefButS(block, MENU, B_TILTINTERP, "Tilt Interpolation %t|Linear %x0|Cardinal %x1|BSpline %x2",
+ 467,67,72, 18, &(nu->tilt_interp), 0, 0, 0, 0, "Tilt interpolation");
+ }
+
uiBlockBeginAlign(block);
sp= &(nu->orderu);
uiDefButS(block, NUM, B_SETORDER, "Order U:", 565,90,102, 19, sp, 2.0, 6.0, 0, 0, "Nurbs only; the amount of control points involved");
@@ -2933,13 +3327,16 @@ static void editing_panel_curve_tools1(Object *ob, Curve *cu)
uiDefBut(block, BUT, B_SPINNURB, "Spin", 400,160,150,20, 0, 0, 0, 0, 0, "Spin selected 360 degrees");
}
uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_HIDE, "Hide", 400,120,150,18, 0, 0, 0, 0, 0, "Hides selected faces");
- uiDefBut(block, BUT,B_REVEAL, "Reveal", 400,100,150,18, 0, 0, 0, 0, 0, "Reveals selected faces");
- uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 400,80,150,18, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
+ uiDefBut(block, BUT,B_HIDE, "Hide", 400,140,150,18, 0, 0, 0, 0, 0, "Hides selected faces");
+ uiDefBut(block, BUT,B_REVEAL, "Reveal", 400,120,150,18, 0, 0, 0, 0, 0, "Reveals selected faces");
+ uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 400,100,150,18, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
uiBlockEndAlign(block);
- uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 400, 40, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
-
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, REDRAWVIEW3D, "NSize:", 400, 60, 150, 19, &G.scene->editbutsize, 0.001, 1.0, 10, 0, "Normal size for drawing");
+ uiDefButBitI(block, TOGN, G_HIDDENHANDLES, REDRAWVIEW3D, "Draw Handles", 400, 40, 150, 19, &G.f, 0, 0, 0, 0, "Draw curve handles in 3D view");
+ uiBlockEndAlign(block);
+
if(G.obedit) {
uiBut *but;
uiBlockBeginAlign(block);
@@ -3012,7 +3409,8 @@ static void editing_panel_curve_type(Object *ob, Curve *cu)
uiDefBut(block, LABEL, 0, str, 675,135,75,19, 0, 1.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 600,50,150,19, &cu->pathlen, 1.0, MAXFRAMEF, 0, 0, "If no speed Ipo was set, the amount of frames of the path");
+ /*note, PathLen's max was MAXFRAMEF but this is a short, perhaps the pathlen should be increased later on */
+ uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 600,50,150,19, &cu->pathlen, 1.0, 32767.0f, 0, 0, "If no speed Ipo was set, the amount of frames of the path");
uiDefButBitS(block, TOG, CU_PATH, B_RECALCPATH, "CurvePath", 600,30,75,19 , &cu->flag, 0, 0, 0, 0, "Enables curve to become translation path");
uiDefButBitS(block, TOG, CU_FOLLOW, REDRAWVIEW3D, "CurveFollow",675,30,75,19, &cu->flag, 0, 0, 0, 0, "Makes curve path children to rotate along path");
uiDefButBitS(block, TOG, CU_STRETCH, B_CURVECHECK, "CurveStretch", 600,10,150,19, &cu->flag, 0, 0, 0, 0, "Option for curve-deform: makes deformed child to stretch along entire path");
@@ -3027,7 +3425,7 @@ static void editing_panel_curve_type(Object *ob, Curve *cu)
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_MAKEDISP, "Width:", 760,90,150,19, &cu->width, 0.0, 2.0, 1, 0, "Make interpolated result thinner or fatter");
- uiDefButF(block, NUM, B_MAKEDISP, "Extrude:", 760,70,150,19, &cu->ext1, 0.0, 5.0, 10, 0, "Curve extrusion size when not using a bevel object");
+ uiDefButF(block, NUM, B_MAKEDISP, "Extrude:", 760,70,150,19, &cu->ext1, 0.0, 100.0, 10, 0, "Curve extrusion size when not using a bevel object");
uiDefButF(block, NUM, B_MAKEDISP, "Bevel Depth:", 760,50,150,19, &cu->ext2, 0.0, 2.0, 1, 0, "Bevel depth when not using a bevel object");
uiDefButS(block, NUM, B_MAKEDISP, "BevResol:", 760,30,150,19, &cu->bevresol, 0.0, 32.0, 0, 0, "Bevel resolution when depth is non-zero and not using a bevel object");
uiDefIDPoinBut(block, test_obcurpoin_but, ID_OB, B_CHANGEDEP, "BevOb:", 760,10,150,19, &cu->bevobj, "Curve object name that defines the bevel shape");
@@ -3088,6 +3486,7 @@ static void editing_panel_camera_type(Object *ob, Camera *cam)
uiDefBut(block, LABEL, 10, "Lens:", 10, 180, 150, 20, 0, 0.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
if(cam->type==CAM_ORTHO) {
uiDefButF(block, NUM,REDRAWVIEW3D, "Scale:",
10, 160, 150, 20, &cam->ortho_scale, 0.01, 1000.0, 50, 0, "Specify the ortho scaling of the used camera");
@@ -3106,59 +3505,57 @@ static void editing_panel_camera_type(Object *ob, Camera *cam)
uiDefButS(block, TOG|BIT|5, B_REDR, "D",
140, 160, 20, 20, &cam->flag, 0, 0, 0, 0, "Use degree as the unit of the camera lens");
}
+ uiDefButS(block, TOG, REDRAWVIEW3D, "Orthographic",
+ 10, 140, 150, 20, &cam->type, 0, 0, 0, 0, "Render with orthographic projection (no prespective)");
+ uiBlockEndAlign(block);
/* qdn: focal dist. param. from yafray now enabled for Blender as well, to use with defocus composit node */
- uiDefButF(block, NUM, REDRAWVIEW3D, "DoFDist:", 10, 140, 150, 20 /*0, 125, 150, 20*/, &cam->YF_dofdist, 0.0, 5000.0, 50, 0, "Sets distance to point of focus (enable 'Limits' to make visible in 3Dview)");
-
- uiDefButS(block, TOG, REDRAWVIEW3D, "Orthographic",
- 10, 115, 150, 20, &cam->type, 0, 0, 0, 0, "Render orthogonally");
- //10, 135, 150, 20, &cam->type, 0, 0, 0, 0, "Render orthogonally");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, REDRAWVIEW3D, "Dof Dist:", 10, 110, 150, 20 /*0, 125, 150, 20*/, &cam->YF_dofdist, 0.0, 5000.0, 50, 0, "Sets distance to point of focus (enable 'Limits' to make visible in 3Dview)");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "Dof Ob:", 10, 90, 150, 20, &cam->dof_ob, "Focus on this object (overrides the 'Dof Dist')");
+ uiBlockEndAlign(block);
- uiDefBut(block, LABEL, 0, "Clipping:", 10, 90, 150, 20, 0, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Clipping Start/End:", 10, 45, 150, 20, 0, 0.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUM,REDRAWVIEW3D, "Start:",
- 10, 70, 150, 20, &cam->clipsta, 0.001*grid, 100.0*grid, 10, 0, "Specify the startvalue of the the field of view");
+ 10, 25, 150, 20, &cam->clipsta, 0.001*grid, 100.0*grid, 10, 0, "Clip out geometry closer then this distance to the camera");
uiDefButF(block, NUM,REDRAWVIEW3D, "End:",
- 10, 50, 150, 20, &cam->clipend, 1.0, 5000.0*grid, 100, 0, "Specify the endvalue of the the field of view");
- uiBlockEndAlign(block);
-
- uiDefButF(block, NUM,REDRAWVIEW3D, "Size:",
- 170, 25, 150, 20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "The size that the camera is displayed in the 3D View (different from the object's scale)");
-
- uiDefBut(block, LABEL, 0, "Shift:", 10, 25, 150, 20, 0, 0.0, 0.0, 0, 0, "");
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM,REDRAWVIEW3D, "X:",
- 10, 5, 75, 20, &cam->shiftx, -2.0, 2.0, 1, 2, "Horizontally shifts the camera view, without changing the perspective");
- uiDefButF(block, NUM,REDRAWVIEW3D, "Y:",
- 85, 5, 75, 20, &cam->shifty, -2.0, 2.0, 1, 2, "Vertically shifts the camera view, without changing the perspective");
+ 10, 5, 150, 20, &cam->clipend, 1.0, 5000.0*grid, 100, 0, "Clip out geometry further then this distance to the camera");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Show:", 170, 180, 150, 20, 0, 0.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|0, REDRAWVIEW3D, "Limits",
- 170, 160, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw the field of view");
+ 170, 160, 75, 20, &cam->flag, 0, 0, 0, 0, "Draw the clipping range and the focal point");
uiDefButS(block, TOG|BIT|1, REDRAWVIEW3D, "Mist",
- 170, 140, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area");
- uiBlockEndAlign(block);
+ 245, 160, 75, 20, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area");
- uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "Name",
- 170, 115, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw the active camera's name in camera view");
+ 170, 140, 75, 20, &cam->flag, 0, 0, 0, 0, "Draw the active camera's name in camera view");
uiDefButS(block, TOG|BIT|3, REDRAWVIEW3D, "Title Safe",
- 170, 95, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw a the title safe zone in camera view");
+ 245, 140, 75, 20, &cam->flag, 0, 0, 0, 0, "Draw a the title safe zone in camera view");
uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
+ uiBlockBeginAlign(block);
uiDefButS(block, TOG|BIT|2, REDRAWVIEW3D, "Passepartout",
- 170, 70, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw a darkened passepartout over the off-screen area in camera view");
+ 170, 110, 150, 20, &cam->flag, 0, 0, 0, 0, "Draw a darkened passepartout over the off-screen area in camera view");
uiDefButF(block, NUMSLI, REDRAWVIEW3D, "Alpha: ",
- 170, 50, 150, 20, &cam->passepartalpha, 0.0, 1.0, 0, 0, "The opacity (darkness) of the passepartout");
+ 170, 90, 150, 20, &cam->passepartalpha, 0.0, 1.0, 0, 0, "The opacity (darkness) of the passepartout");
uiBlockEndAlign(block);
-
+ uiDefButF(block, NUM,REDRAWVIEW3D, "Size:",
+ 170, 50, 150, 20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "The size that the camera is displayed in the 3D View (different from the object's scale)");
+
+ uiDefBut(block, LABEL, 0, "Shift:", 170, 25, 150, 20, 0, 0.0, 0.0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM,REDRAWVIEW3D, "X:",
+ 170, 5, 75, 20, &cam->shiftx, -2.0, 2.0, 1, 2, "Horizontally shift the camera view, without changing the perspective");
+ uiDefButF(block, NUM,REDRAWVIEW3D, "Y:",
+ 245, 5, 75, 20, &cam->shifty, -2.0, 2.0, 1, 2, "Vertically shift the camera view, without changing the perspective");
+ uiBlockEndAlign(block);
}
/* yafray: extra camera panel to set Depth-of-Field parameters */
@@ -3299,6 +3696,10 @@ void do_latticebuts(unsigned short event)
if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
ob->softflag |= OB_SB_REDO;
+ if(modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
@@ -3307,6 +3708,10 @@ void do_latticebuts(unsigned short event)
lt = ob->data;
resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob);
ob->softflag |= OB_SB_REDO;
+ if(modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
@@ -3378,6 +3783,7 @@ static void editing_panel_lattice_type(Object *ob, Lattice *lt)
void do_armbuts(unsigned short event)
{
Object *ob= OBACT;
+ bAction *act;
switch(event) {
case B_ARM_RECALCDATA:
@@ -3415,6 +3821,149 @@ void do_armbuts(unsigned short event)
if (ob && ob->pose)
pose_clear_paths(ob);
break;
+
+ case B_POSELIB_ADDPOSE:
+ if (ob && ob->pose)
+ poselib_add_current_pose(ob, 1);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ break;
+ case B_POSELIB_REPLACEP:
+ if (ob && ob->pose)
+ poselib_add_current_pose(ob, 2);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ break;
+ case B_POSELIB_REMOVEP:
+ if (ob && ob->pose) {
+ bAction *act= ob->poselib;
+ TimeMarker *marker= poselib_get_active_pose(act);
+
+ poselib_remove_pose(ob, marker);
+ }
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ break;
+ case B_POSELIB_VALIDATE:
+ if (ob && ob->pose)
+ poselib_validate_act(ob->poselib);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ break;
+ case B_POSELIB_APPLYP:
+ if (ob && ob->pose)
+ poselib_preview_poses(ob, 1);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+
+ /* note: copied from headerbuttons.c */
+ case B_POSELIB_ALONE: //B_ACTALONE
+ if (ob && ob->id.lib==0) {
+ act= ob->poselib;
+
+ if (act->id.us > 1) {
+ if (okee("Single user")) {
+ ob->poselib= copy_action(act);
+ act->id.us--;
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ }
+ }
+ }
+ break;
+ case B_POSELIB_DELETE: //B_ACTIONDELETE
+ act= ob->poselib;
+
+ if (act)
+ act->id.us--;
+ ob->poselib=NULL;
+
+ BIF_undo_push("Unlink PoseLib");
+
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ break;
+ case B_POSELIB_BROWSE: //B_ACTIONBROWSE:
+ {
+ ID *id, *idtest;
+ int nr= 1;
+
+ if (ob == NULL)
+ break;
+ act= ob->poselib;
+ id= (ID *)act;
+
+ if (G.buts->menunr == -2) {
+ activate_databrowse((ID *)ob->poselib, ID_AC, 0, B_POSELIB_BROWSE, &G.buts->menunr, do_armbuts);
+ return;
+ }
+ if (G.buts->menunr < 0) break;
+
+ /* See if we have selected a valid action */
+ for (idtest= G.main->action.first; idtest; idtest= idtest->next) {
+ if (nr == G.buts->menunr) {
+ break;
+ }
+ nr++;
+ }
+
+ /* Store current action */
+ if (!idtest) {
+ /* 'Add New' option:
+ * - make a copy of an exisiting action
+ * - or make a new empty action if no existing action
+ */
+ if (act) {
+ idtest= (ID *)copy_action(act);
+ }
+ else {
+ /* a plain action */
+ idtest=(ID *)add_empty_action("PoseLib");
+ }
+ idtest->us--;
+ }
+
+ if ((idtest != id) && (ob)) {
+ act= (bAction *)idtest;
+
+ ob->poselib= act;
+ id_us_plus(idtest);
+
+ if (id) id->us--;
+
+ /* Update everything */
+ BIF_undo_push("Browse PoseLibs");
+
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWHEADERS, 0);
+ }
+ }
+ break;
+
+ case B_POSEGRP_RECALC:
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ case B_POSEGRP_ADD:
+ if (ob && ob->pose)
+ pose_add_posegroup();
+ break;
+ case B_POSEGRP_REMOVE:
+ if (ob && ob->pose)
+ pose_remove_posegroup();
+ break;
+ case B_POSEGRP_MCUSTOM:
+ if (ob && ob->pose) {
+ if (ob->pose->active_group) {
+ bActionGroup *grp= (bActionGroup *)BLI_findlink(&ob->pose->agroups, ob->pose->active_group-1);
+ grp->customCol= -1;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
}
}
@@ -3483,10 +4032,10 @@ static void build_bonestring (char *string, EditBone *bone)
int skip=0;
int index, numbones, i;
char (*qsort_ptr)[32] = NULL;
+ char *s = string;
- sprintf (string, "Parent%%t| %%x%d", -1); /* That space is there
- * for a reason
- */
+ /* That space is there for a reason - for no parent */
+ s += sprintf (string, "Parent%%t| %%x%d", -1);
numbones = BLI_countlist(&G.edbo);
@@ -3527,7 +4076,7 @@ static void build_bonestring (char *string, EditBone *bone)
( int (*)(const void *, const void *) ) strcmp);
for (i=0; i < numbones; ++i) {
- sprintf (string, "%s%s", string, qsort_ptr[i]);
+ strcat(s, qsort_ptr[i]);
}
if (qsort_ptr)
@@ -3601,13 +4150,13 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
uiBlockBeginAlign(block);
for(a=0; a<8; a++) {
short dx= 18;
- but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 10+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "");
+ but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 10+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "Armature layer (Hold Ctrl for locking in a proxy instance)");
uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<<a));
}
uiBlockBeginAlign(block);
for(a=8; a<16; a++) {
short dx= 18;
- but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 18+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "");
+ but= uiDefButBitS(block, BUT_TOGDUAL, 1<<a, REDRAWVIEW3D, "", 18+a*dx, 115, dx, 15, &arm->layer, 0, 0, 0, 0, "Armature layer (Hold Ctrl for locking in a proxy instance)");
uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<<a));
}
/* quite bad here, but I don't know a better place for copy... */
@@ -3620,18 +4169,21 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 87,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines");
uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 87,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume");
- uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 67,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
- uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,67,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
- uiDefButBitI(block, TOGN, ARM_NO_CUSTOM, REDRAWVIEW3D, "Draw Shapes", 210,67,100,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone shapes");
+ uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Axes", 10, 67,75,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
+ uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Names", 85,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
+ uiDefButBitI(block, TOGN, ARM_NO_CUSTOM, REDRAWVIEW3D, "Shapes", 160,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone shapes");
+ uiDefButBitI(block, TOG, ARM_COL_CUSTOM, REDRAWVIEW3D, "Colors", 235,67,75,20, &arm->flag, 0, 0, 0, 0, "Draw custom bone colors (colors are set per Bone Group)");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Deform Options", 10,40,150,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 20,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)");
- uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 160,20,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)");
- uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,0,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible");
- uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160,0,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
+ uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)");
+ uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 110,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)");
+ uiDefButBitS(block, TOG, ARM_DEF_QUATERNION, B_ARM_RECALCDATA, "Quaternion", 210,20,100,20, &arm->deformflag, 0, 0, 0, 0, "Enable deform rotation interpolation with Quaternions (not for Modifiers)");
+ uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,0,100,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible");
+ uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 110,0,100,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
+ uiDefButBitS(block, TOG, ARM_DEF_B_BONE_REST, B_ARM_RECALCDATA,"B-Bone Rest", 210,0,100,20, &arm->deformflag, 0, 0, 0, 0, "Make B-Bones deform already in rest position");
uiBlockEndAlign(block);
}
@@ -3652,15 +4204,23 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
arm->pathsf = SFRA;
arm->pathef = EFRA;
}
+ if ((arm->pathbc == 0) || (arm->pathac == 0)) {
+ arm->pathbc = 15;
+ arm->pathac = 15;
+ }
/* Ghost Drawing Options */
uiDefBut(block, LABEL, 0, "Ghost Options", 10,180,150,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1",
- 10, 160, 150, 20, &arm->ghosttype, 0, 0, 0, 0, "Choose range of Ghosts to draw for current Action");
-
- uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
+ uiDefButS(block, MENU, REDRAWVIEW3D, "Ghosts %t|Around Current Frame %x0|In Range %x1|On Keyframes %x2",
+ 10, 160, 150, 20, &arm->ghosttype, 0, 0, 0, 0, "Choose range of Ghosts to draw for current Action");
+
+ if (arm->ghosttype != ARM_GHOST_KEYS)
+ uiDefButS(block, NUM, REDRAWVIEW3D, "GStep: ", 10,140,120,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances");
+ else
+ uiDefBut(block, LABEL, REDRAWVIEW3D, "GStep: N/A", 10,140,120,20, NULL, 0.0f, 0.0f, 0, 0, "How many frames between Ghost instances");
+ uiDefButBitI(block, TOG, ARM_GHOST_ONLYSEL, REDRAWVIEW3D, "Sel", 130, 140, 30, 20, &arm->flag, 0, 0, 0, 0, "Only show Ghosts for selected bones");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -3668,7 +4228,7 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
/* range is around current frame */
uiDefButS(block, NUM, REDRAWVIEW3D, "Ghost: ", 10,110,150,20, &arm->ghostep, 0.0f, 30.0f, 0, 0, "Draw Ghosts around current frame, for current Action");
}
- else if (arm->ghosttype == ARM_GHOST_RANGE) {
+ else if (ELEM(arm->ghosttype, ARM_GHOST_RANGE, ARM_GHOST_KEYS)) {
/* range is defined by start+end frame below */
uiDefButI(block, NUM,REDRAWVIEW3D,"GSta:",10,110,150,20, &arm->ghostsf,1.0,MAXFRAMEF, 0, 0, "The start frame for Ghost display range");
uiDefButI(block, NUM,REDRAWVIEW3D,"GEnd:",10,90,150,20, &arm->ghostef,arm->ghostsf,MAXFRAMEF, 0, 0, "The end frame for Ghost display range");
@@ -3676,23 +4236,38 @@ static void editing_panel_armature_visuals(Object *ob, bArmature *arm)
uiBlockEndAlign(block);
/* Bone Path Drawing Options */
- uiDefBut(block, LABEL, 0, "Bone Paths", 165,180,150,20, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Bone Paths Drawing:", 165,180,170,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, ARM_PATH_FNUMS, REDRAWVIEW3D, "Frame Nums", 170, 160, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers on path");
- uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",250,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
- uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
+ uiDefButS(block, NUM, REDRAWVIEW3D, "PStep:",170,160,80,20, &arm->pathsize,1,100, 10, 50, "Frames between highlighted points on bone path");
+ uiDefButBitS(block, TOG, ARM_PATH_FNUMS, REDRAWVIEW3D, "Frame Nums", 250, 160, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers on path");
+
+ uiDefButBitS(block, TOG, ARM_PATH_KFRAS, REDRAWVIEW3D, "Show Keys", 170, 140, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show key frames on path");
+ uiDefButBitS(block, TOG, ARM_PATH_KFNOS, REDRAWVIEW3D, "Keyframe Nums", 250, 140, 80, 20, &arm->pathflag, 0, 0, 0, 0, "Show frame numbers of key frames on path");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButI(block, NUM,REDRAWVIEW3D,"PSta:",170,100,80,20, &arm->pathsf, 1.0, MAXFRAMEF, 0, 0, "The start frame for Bone Path display range");
- uiDefButI(block, NUM,REDRAWVIEW3D,"PEnd:",250,100,80,20, &arm->pathef, arm->pathsf, MAXFRAMEF, 0, 0, "The end frame for Bone Path display range");
- uiDefButBitS(block, TOG, ARM_PATH_HEADS, REDRAWVIEW3D, "Bone-Head Path", 170, 80, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate the Path travelled by the Bone's Head instead of Tail");
+ uiDefButBitS(block, TOG, ARM_PATH_ACFRA, REDRAWVIEW3D, "Around Current Frame", 170, 110, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Only show Bone Path around the current frame");
+
+ /* only show extra ranges when needed */
+ if (arm->pathflag & ARM_PATH_ACFRA) {
+ uiDefButI(block, NUM, REDRAWVIEW3D,"PPre:",170,90,80,20, &arm->pathbc, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames before current frame for Bone Path display range");
+ uiDefButI(block, NUM, REDRAWVIEW3D,"PPost:",250,90,80,20, &arm->pathac, 1.0, MAXFRAMEF/2, 0, 0, "The number of frames after current frame for Bone Path display range");
+ }
uiBlockEndAlign(block);
+ /* Bone Path Calculation Options */
+ uiDefBut(block, LABEL, 0, "Bone Paths Calc.", 10,50,170,20, 0, 0, 0, 0, 0, "");
+
uiBlockBeginAlign(block);
- uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 170,40,160,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones");
- uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear All Paths", 170,20,160,20, 0, 0, 0, 0, 0, "Clears all bone paths");
+ uiDefBut(block, BUT, B_ARM_CALCPATHS, "Calculate Paths", 10,30,155,20, 0, 0, 0, 0, 0, "(Re)calculates the paths of the selected bones");
+ uiDefBut(block, BUT, B_ARM_CLEARPATHS, "Clear Paths", 10,10,155,20, 0, 0, 0, 0, 0, "Clears bone paths of the selected bones");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, ARM_PATH_HEADS, REDRAWVIEW3D, "Bone-Head Path", 170, 30, 160, 20, &arm->pathflag, 0, 0, 0, 0, "Calculate the Path travelled by the Bone's Head instead of Tail");
+ uiDefButI(block, NUM,REDRAWVIEW3D,"PSta:",170,10,80,20, &arm->pathsf, 1.0, MAXFRAMEF, 0, 0, "The start frame for Bone Path display range");
+ uiDefButI(block, NUM,REDRAWVIEW3D,"PEnd:",250,10,80,20, &arm->pathef, arm->pathsf, MAXFRAMEF, 0, 0, "The end frame for Bone Path display range");
uiBlockEndAlign(block);
}
@@ -3768,22 +4343,23 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
/* bone types */
- uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
- uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 75, by-38, 85, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
- uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
- uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 245,by-38,85,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
+ uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
+ uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
+ uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
+ uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
+ uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
/* layers */
uiBlockBeginAlign(block);
for(a=0; a<8; a++) {
short dx= 21;
- but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -10+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Don't draw this layer for group-duplicators");
+ but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -10+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Armature layer that bone exists on");
uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<<a));
}
uiBlockBeginAlign(block);
for(a=8; a<16; a++) {
short dx= 21;
- but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -6+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Don't draw this layer for group-duplicators");
+ but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -6+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Armature layer that bone exists on");
uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<<a));
}
@@ -3827,6 +4403,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
Bone *curBone;
int by, a;
int index, zerodof, zerolimit;
+ char *menustr;
/* Draw the bone name block */
block= uiNewBlock(&curarea->uiblocks, "editing_panel_pose_bones", UI_EMBOSS, UI_HELV, curarea->win);
@@ -3842,19 +4419,25 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
for (pchan=ob->pose->chanbase.first, index=0; pchan; pchan=pchan->next, index++){
curBone= pchan->bone;
if ((curBone->flag & BONE_SELECTED) && (curBone->layer & arm->layer)) {
-
if(ob_arm_bone_pchan_lock(ob, arm, curBone, pchan))
uiDefBut(block, LABEL, 0, "Proxy Locked", 160, 180,150,18, NULL, 1, 0, 0, 0, "");
- /* Bone naming button */
+ /* Bone naming button */
uiBlockBeginAlign(block);
but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", -10,by,117,19, curBone->name, 0, 24, 0, 0, "Change the bone name");
uiButSetFunc(but, validate_posebonebutton_cb, curBone, NULL);
uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
- /* Dist and weight buttons */
- uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", 107, by, 105, 19, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance");
- uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 220, by, 110, 19, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
+ /* Bone custom drawing */
+ menustr= build_posegroups_menustr(ob->pose, 0);
+ uiDefButS(block, MENU,REDRAWVIEW3D, menustr, 107,by,105,19, &pchan->agrp_index, 0, 0.0, 0.0, 0.0, "Change the Pose Group this Bone belongs to");
+ MEM_freeN(menustr);
+
+ ob_arm_bone_pchan_lock(ob, arm, curBone, pchan);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "OB:", 220,by,90,19, &pchan->custom, "Object that defines custom draw type for this Bone");
+ ob_arm_bone_pchan_lock(ob, arm, curBone, NULL);
+
+ uiDefButBitI(block, TOG, BONE_DRAWWIRE, B_ARM_RECALCDATA, "W", 309,by,21,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Custom shape of this Bone should always be drawn as a wireframe");
/* Segment, ease in/out buttons */
uiBlockBeginAlign(block);
@@ -3863,24 +4446,23 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
uiDefButF(block, NUM,B_ARM_RECALCDATA, "Out:", 220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle");
/* bone types */
- uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
- uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 70, by-38, 80, 19, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
- uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 150,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
- ob_arm_bone_pchan_lock(ob, arm, curBone, pchan);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "OB:", 230,by-38,100,19, &pchan->custom, "Object that defines custom draw type for this Bone");
- ob_arm_bone_pchan_lock(ob, arm, curBone, NULL);
+ uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
+ uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone");
+ uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 90, by-38, 80, 19, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry");
+ uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup");
+ uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Hide", 250,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Toggles display of this bone in Edit Mode");
/* layers */
uiBlockBeginAlign(block);
for(a=0; a<8; a++) {
short dx= 21;
- but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -10+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "");
+ but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -10+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Armature layer that bone exists on");
uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<<a));
}
uiBlockBeginAlign(block);
for(a=8; a<16; a++) {
short dx= 21;
- but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -6+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "");
+ but= uiDefButBitS(block, TOG, 1<<a, REDRAWVIEW3D, "", -6+a*dx, by-57, dx, 15, &curBone->layer, 0, 0, 0, 0, "Armature layer that bone exists on");
uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<<a));
}
uiBlockEndAlign(block);
@@ -4091,6 +4673,8 @@ void do_meshbuts(unsigned short event)
if(!mcol)
shadeMeshMCol(ob, me);
}
+
+ if (me->mr) multires_load_cols(me);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
BIF_undo_push("New Vertex Color");
@@ -4120,19 +4704,19 @@ void do_meshbuts(unsigned short event)
break;
case B_NEWTFACE:
- if(me)
- layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
- else
- layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
-
if(me && me->mr) {
+ layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
multires_add_layer(me, &me->mr->fdata, CD_MTFACE, layernum);
+ multires_level_to_editmesh(ob, me, 0);
+ multires_finish_mesh_update(ob);
}
else if(G.obedit) {
+ layernum= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
EM_add_data_layer(&em->fdata, CD_MTFACE);
CustomData_set_layer_active(&em->fdata, CD_MTFACE, layernum);
}
else if(me) {
+ layernum= CustomData_number_of_layers(&me->fdata, CD_MTFACE);
if(me->mtface)
CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DUPLICATE,
me->mtface, me->totface);
@@ -4213,7 +4797,7 @@ void do_meshbuts(unsigned short event)
G.f -= G_DISABLE_OK;
break;
case B_REMDOUB:
- count= removedoublesflag(1, G.scene->toolsettings->doublimit);
+ count= removedoublesflag(1, 0, G.scene->toolsettings->doublimit);
notice("Removed: %d", count);
if (count) { /* only undo and redraw if an action is taken */
countall ();
@@ -4266,9 +4850,16 @@ void do_meshbuts(unsigned short event)
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
break;
+ //~ case B_DRAWBWEIGHTS:
+ //~ allqueue(REDRAWBUTSEDIT, 0);
+ //~ allqueue(REDRAWVIEW3D, 0);
+ //~ break;
case B_JOINTRIA:
join_triangles();
break;
+ case B_GEN_SKELETON:
+ generateSkeleton();
+ break;
}
/* WATCH IT: previous events only in editmode! */
@@ -4319,6 +4910,7 @@ static void editing_panel_mesh_tools(Object *ob, Mesh *me)
uiDefButS(block, NUM, B_DIFF, "Turns:", 210,55,115,19, &G.scene->toolsettings->turn,1.0,360.0, 0, 0, "Specifies the number of revolutions the screw turns");
uiDefButBitS(block, TOG, B_KEEPORIG, B_DIFF, "Keep Original",10,35,200,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Keeps a copy of the original vertices and faces after executing tools");
uiDefButBitS(block, TOG, B_CLOCKWISE, B_DIFF, "Clockwise", 210,35,115,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Specifies the direction for 'Screw' and 'Spin'");
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefBut(block, BUT,B_EXTREP, "Extrude Dup", 10,10,150,19, 0, 0, 0, 0, 0, "Creates copies of the selected vertices in a straight line away from the current viewport");
@@ -4328,10 +4920,10 @@ static void editing_panel_mesh_tools(Object *ob, Mesh *me)
uiBlockBeginAlign(block);
uiDefBut(block, BUT, B_JOINTRIA, "Join Triangles", 10, -20, 120, 19, 0, 0, 0, 0, 0, "Convert selected triangles to Quads");
uiDefButF(block, NUM, B_DIFF, "Threshold", 130, -20, 195, 19, &G.scene->toolsettings->jointrilimit, 0.0, 1.0, 5, 0, "Conversion threshold for complex islands");
- uiDefButBitS(block, TOG, B_JOINTRIA_UV, 0, "Delimit UVs", 10, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Don't join pairs where UVs don't match");
- uiDefButBitS(block, TOG, B_JOINTRIA_VCOL, 0, "Delimit Vcol", 90, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Don't join pairs where Vcols don't match");
- uiDefButBitS(block, TOG, B_JOINTRIA_SHARP, 0, "Delimit Sharp", 170, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Don't join pairs where edge is sharp");
- uiDefButBitS(block, TOG, B_JOINTRIA_MAT, 0, "Delimit Mat", 250, -40, 74, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Don't join pairs where material dosnt match");
+ uiDefButBitS(block, TOG, B_JOINTRIA_UV, 0, "Delimit UVs", 10, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Join pairs only where UVs match");
+ uiDefButBitS(block, TOG, B_JOINTRIA_VCOL, 0, "Delimit Vcol", 90, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Join pairs only where Vcols match");
+ uiDefButBitS(block, TOG, B_JOINTRIA_SHARP, 0, "Delimit Sharp", 170, -40, 78, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Join pairs only where edge is not sharp");
+ uiDefButBitS(block, TOG, B_JOINTRIA_MAT, 0, "Delimit Mat", 250, -40, 74, 19, &G.scene->toolsettings->editbutflag, 0,0,0,0, "Join pairs only where material matches");
uiBlockEndAlign(block);
@@ -4342,7 +4934,81 @@ static void verify_vertexgroup_name_func(void *datav, void *data2_unused)
unique_vertexgroup_name((bDeformGroup*)datav, OBACT);
}
+static void skgen_reorder(void *option, void *arg2)
+{
+ char tmp;
+ switch ((int)option)
+ {
+ case 0:
+ tmp = G.scene->toolsettings->skgen_subdivisions[0];
+ G.scene->toolsettings->skgen_subdivisions[0] = G.scene->toolsettings->skgen_subdivisions[1];
+ G.scene->toolsettings->skgen_subdivisions[1] = tmp;
+ break;
+ case 1:
+ tmp = G.scene->toolsettings->skgen_subdivisions[2];
+ G.scene->toolsettings->skgen_subdivisions[2] = G.scene->toolsettings->skgen_subdivisions[1];
+ G.scene->toolsettings->skgen_subdivisions[1] = tmp;
+ break;
+ case 2:
+ tmp = G.scene->toolsettings->skgen_subdivisions[0];
+ G.scene->toolsettings->skgen_subdivisions[0] = G.scene->toolsettings->skgen_subdivisions[2];
+ G.scene->toolsettings->skgen_subdivisions[2] = G.scene->toolsettings->skgen_subdivisions[1];
+ G.scene->toolsettings->skgen_subdivisions[1] = tmp;
+ break;
+ }
+}
+
+static void editing_panel_mesh_skgen(Object *ob, Mesh *me)
+{
+ uiBlock *block;
+ uiBut *but;
+ int i;
+
+ block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_skgen", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Skeleton Generator", "Editing", 960, 0, 318, 204)==0) return;
+
+ uiDefBut(block, BUT, B_GEN_SKELETON, "Generate Skeleton", 1025,170,250,19, 0, 0, 0, 0, 0, "Generate Skeleton from Mesh");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,150,250,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding");
+ uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1025,130, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs");
+ uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1025,110, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs");
+
+ for(i = 0; i < SKGEN_SUB_TOTAL; i++)
+ {
+ int y = 90 - 20 * i;
+
+ but = uiDefIconBut(block, BUT, B_MODIFIER_RECALC, VICON_MOVE_DOWN, 1025, y, 16, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Change the order the subdivisions algorithm are applied");
+ uiButSetFunc(but, skgen_reorder, (void *)i, NULL);
+
+ switch(G.scene->toolsettings->skgen_subdivisions[i])
+ {
+ case SKGEN_SUB_LENGTH:
+ uiDefButBitS(block, TOG, SKGEN_CUT_LENGTH, B_DIFF, "Length", 1041, y, 67,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs in bones of equal length");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1111, y, 82,19, &G.scene->toolsettings->skgen_length_ratio,1.0, 4.0, 10, 0, "Specify the ratio limit between straight arc and embeddings to trigger equal subdivisions");
+ uiDefButF(block, NUM, B_DIFF, "L:", 1193, y, 82,19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the bones when subdividing");
+ break;
+ case SKGEN_SUB_ANGLE:
+ uiDefButBitS(block, TOG, SKGEN_CUT_ANGLE, B_DIFF, "Angle", 1041, y, 67,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on angle");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1111, y,164,19, &G.scene->toolsettings->skgen_angle_limit,0.0, 90.0, 10, 0, "Specify the threshold angle in degrees for subdivision");
+ break;
+ case SKGEN_SUB_CORRELATION:
+ uiDefButBitS(block, TOG, SKGEN_CUT_CORRELATION, B_DIFF, "Correlation", 1041, y, 67,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on correlation");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1111, y,164,19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Specify the threshold correlation for subdivision");
+ break;
+ }
+ }
+
+ uiDefButBitS(block, TOG, SKGEN_SYMMETRY, B_DIFF, "Symmetry", 1025, 30,125,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Restore symmetries based on topology");
+ uiDefButF(block, NUM, B_DIFF, "T:", 1150, 30,125,19, &G.scene->toolsettings->skgen_symmetry_limit,0.0, 1.0, 10, 0, "Specify the threshold distance for considering potential symmetric arcs");
+ uiDefButC(block, NUM, B_DIFF, "P:", 1025, 10, 62,19, &G.scene->toolsettings->skgen_postpro_passes, 0, 10, 10, 0, "Specify the number of processing passes on the embeddings");
+ uiDefButC(block, ROW, B_DIFF, "Smooth", 1087, 10, 63,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_SMOOTH, 0, 0, "Smooth embeddings");
+ uiDefButC(block, ROW, B_DIFF, "Average", 1150, 10, 62,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_AVERAGE, 0, 0, "Average embeddings");
+ uiDefButC(block, ROW, B_DIFF, "Sharpen", 1212, 10, 63,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_SHARPEN, 0, 0, "Sharpen embeddings");
+ uiBlockEndAlign(block);
+}
static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
{
@@ -4353,9 +5019,9 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
if(uiNewPanel(curarea, block, "Mesh Tools 1", "Editing", 960, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 955, 200, 106, 19, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces");
- uiDefBut(block, BUT,B_HIDE, "Hide", 1061, 200, 106, 19, 0, 0, 0, 0, 0, "Hides selected faces");
- uiDefBut(block, BUT,B_REVEAL, "Reveal", 1167, 200, 107, 19, 0, 0, 0, 0, 0, "Reveals selected faces");
+ uiDefBut(block, BUT,B_SELSWAP, "Select Swap", 955, 200, 106, 19, 0, 0, 0, 0, 0, "Selects unselected faces, and deselects selected faces (Ctrl+I)");
+ uiDefBut(block, BUT,B_HIDE, "Hide", 1061, 200, 106, 19, 0, 0, 0, 0, 0, "Hides selected faces (H)");
+ uiDefBut(block, BUT,B_REVEAL, "Reveal", 1167, 200, 107, 19, 0, 0, 0, 0, 0, "Reveals selected faces (Alt H)");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -4365,11 +5031,12 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, G_DRAWFACES, REDRAWVIEW3D, "Draw Faces", 955,88,150,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades");
- uiDefButBitI(block, TOG, G_DRAWEDGES, REDRAWVIEW3D, "Draw Edges", 955,66,150,19, &G.f, 0, 0, 0, 0, "Displays selected edges using hilights");
- uiDefButBitI(block, TOG, G_DRAWCREASES, REDRAWVIEW3D, "Draw Creases", 955,44,150,19, &G.f, 0, 0, 0, 0, "Displays creases created for subsurf weighting");
- uiDefButBitI(block, TOG, G_DRAWSEAMS, REDRAWVIEW3D, "Draw Seams", 955,22,150,19, &G.f, 0, 0, 0, 0, "Displays UV unwrapping seams");
- uiDefButBitI(block, TOG, G_DRAWSHARP, REDRAWVIEW3D, "Draw Sharp", 955,0,150,19, &G.f, 0, 0, 0, 0, "Displays sharp edges, used with the EdgeSplit modifier");
+ uiDefButBitI(block, TOG, G_DRAWFACES, REDRAWVIEW3D_IMAGE, "Draw Faces", 955,88,150,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor");
+ uiDefButBitI(block, TOG, G_DRAWEDGES, REDRAWVIEW3D, "Draw Edges", 955, 66,150,19, &G.f, 0, 0, 0, 0, "Displays selected edges using hilights");
+ uiDefButBitI(block, TOG, G_DRAWCREASES, REDRAWVIEW3D, "Draw Creases", 955, 42,150,19, &G.f, 0, 0, 0, 0, "Displays creases created for subsurf weighting");
+ uiDefButBitI(block, TOG, G_DRAWBWEIGHTS, REDRAWVIEW3D, "Draw Bevel Weights", 955, 20,150,19, &G.f, 0, 0, 0, 0, "Displays weights created for the Bevel modifier");
+ uiDefButBitI(block, TOG, G_DRAWSEAMS, REDRAWVIEW3D, "Draw Seams", 955, -2,150,19, &G.f, 0, 0, 0, 0, "Displays UV unwrapping seams");
+ uiDefButBitI(block, TOG, G_DRAWSHARP, REDRAWVIEW3D, "Draw Sharp", 955, -24,150,19, &G.f, 0, 0, 0, 0, "Displays sharp edges, used with the EdgeSplit modifier");
uiBlockEndAlign(block);
/* Measurement drawing options */
@@ -4394,7 +5061,7 @@ char *get_vertexgroup_menustr(Object *ob)
{
bDeformGroup *dg;
int defCount, min, index;
- char (*qsort_ptr)[sizeof(dg->name)+5] = NULL; // +5 for "%x99|"
+ char (*qsort_ptr)[sizeof(dg->name)+6] = NULL; // +6 for "%x999|" max 999 groups selectable
char *s, *menustr;
int printed;
@@ -4412,7 +5079,7 @@ char *get_vertexgroup_menustr(Object *ob)
"qsort_ptr");
for (index = 1, dg = ob->defbase.first; dg; index++, dg=dg->next) {
printed = snprintf (qsort_ptr[index - 1], sizeof (dg->name), dg->name);
- snprintf (qsort_ptr[index - 1]+printed, 5+1, "%%x%d|", index); // +1 to move the \0
+ snprintf (qsort_ptr[index - 1]+printed, 6+1, "%%x%d|", index); // +1 to move the \0 see above 999 max here too
}
qsort (qsort_ptr, defCount, sizeof (qsort_ptr[0]),
@@ -4434,6 +5101,48 @@ char *get_vertexgroup_menustr(Object *ob)
return menustr;
}
+static void verify_poselib_posename(void *arg1, void *arg2)
+{
+ bAction *act= (bAction *)arg1;
+ TimeMarker *marker= (TimeMarker *)arg2;
+
+ BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
+}
+
+static void verify_posegroup_groupname(void *arg1, void *arg2)
+{
+ bPose *pose= (bPose *)arg1;
+ bActionGroup *grp= (bActionGroup *)arg2;
+
+ BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
+}
+
+static char *build_colorsets_menustr ()
+{
+ DynStr *pupds= BLI_dynstr_new();
+ char *str;
+ char buf[48];
+ int i;
+
+ /* add title first (and the "default" entry) */
+ BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
+
+ /* loop through set indices, adding them */
+ for (i=1; i<21; i++) {
+ sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
+ BLI_dynstr_append(pupds, buf);
+ }
+
+ /* add the 'custom' entry */
+ BLI_dynstr_append(pupds, "Custom Set %x-1");
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
static void editing_panel_links(Object *ob)
{
uiBlock *block;
@@ -4508,7 +5217,7 @@ static void editing_panel_links(Object *ob)
xco, 154, 130,20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButC(block, MENU, REDRAWVIEW3D, "Empty Drawtype%t|Arrows%x1|Single Arrow%x4|Plain Axes%x2",
+ uiDefButC(block, MENU, REDRAWVIEW3D, "Empty Drawtype%t|Arrows%x1|Single Arrow%x4|Plain Axes%x2|Circle%x3|Cube%x5|Sphere%x6|Cone%x7",
xco, 128, 140, 20, &ob->empty_drawtype, 0, 0, 0, 0, "The Empty 3D View display style");
uiDefButF(block, NUM, REDRAWVIEW3D, "Size:",
xco, 108, 140, 21, &ob->empty_drawsize, 0.01, 10.0, 1, 0, "The size to display the Empty");
@@ -4516,6 +5225,123 @@ static void editing_panel_links(Object *ob)
return;
}
+ /* poselib for armatures */
+ if (ob->type==OB_ARMATURE) {
+ if ((ob->pose) && (ob->flag & OB_POSEMODE) && (G.obedit != ob)) {
+ bAction *act= ob->poselib;
+ bPose *pose= ob->pose;
+ bActionGroup *grp= NULL;
+ int count;
+ char *menustr;
+
+ /* PoseLib settings for armature reside on the left */
+ xco= 143;
+
+ uiDefBut(block, LABEL,0, "Pose Library:", xco, 154, 200, 20, 0, 0, 0, 0, 0, "");
+
+ /* PoseLib Action */
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+ std_libbuttons(block, 143, 130, 0, NULL, B_POSELIB_BROWSE, ID_AC, 0, (ID *)act, (ID *)ob, &(G.buts->menunr), B_POSELIB_ALONE, 0, B_POSELIB_DELETE, 0, 0);
+ uiBlockSetCol(block, TH_AUTO);
+
+ uiDefBut(block, BUT, B_POSELIB_VALIDATE, "Auto-Sync PoseLib", xco,110,160,20, 0, 0, 0, 0, 0, "Syncs the current PoseLib with the poses available");
+
+ /* PoseLib - Pose editing controls */
+ if (act) {
+ uiBlockBeginAlign(block);
+ /* currently 'active' pose */
+ if (act->markers.first) {
+ count= BLI_countlist(&act->markers);
+ menustr= poselib_build_poses_menu(act, "PoseLib Poses");
+ uiDefButI(block, MENU, B_POSELIB_APPLYP, menustr, xco, 85,18,20, &act->active_marker, 1, count, 0, 0, "Browses Poses in Pose Library. Applies chosen pose.");
+ MEM_freeN(menustr);
+
+ if (act->active_marker) {
+ TimeMarker *marker= poselib_get_active_pose(act);
+
+ but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change.");
+ uiButSetFunc(but, verify_poselib_posename, act, marker);
+ uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Library Pose from Pose Library.");
+ }
+ }
+
+ /* add new poses */
+ uiDefBut(block, BUT, B_POSELIB_ADDPOSE, "Add Pose", xco,65,80,20, 0, 0, 0, 0, 0, "Add current pose to PoseLib");
+ uiDefBut(block, BUT, B_POSELIB_REPLACEP, "Replace Pose", xco+80,65,80,20, 0, 0, 0, 0, 0, "Replace existing PoseLib Pose with current pose");
+ uiBlockEndAlign(block);
+ }
+
+
+ /* Bone Groups settings for armature reside on the right */
+ xco= 315;
+
+ uiDefBut(block, LABEL,0, "Bone Groups:", xco, 154, 140, 20, 0, 0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+ if (pose->agroups.first) {
+ /* currently 'active' group - browse groups */
+ count= BLI_countlist(&pose->agroups);
+ menustr= build_posegroups_menustr(pose, 0);
+ uiDefButI(block, MENU, B_POSEGRP_RECALC, menustr, xco, 130,18,20, &pose->active_group, 1, count, 0, 0, "Browses Bone Groups available for Armature. Click to change.");
+ MEM_freeN(menustr);
+
+ /* currently 'active' group - change name */
+ if (pose->active_group) {
+ grp= (bActionGroup *)BLI_findlink(&pose->agroups, pose->active_group-1);
+
+ /* active group */
+ but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,130,140-18-20,20, grp->name, 0, 31, 0, 0, "Displays current Bone Group name. Click to change.");
+ uiButSetFunc(but, verify_posegroup_groupname, pose, grp);
+ uiDefIconBut(block, BUT, B_POSEGRP_REMOVE, VICON_X, xco+140-20, 130, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Bone Group");
+ }
+ }
+
+ uiDefBut(block, BUT, B_POSEGRP_ADD, "Add Group", xco,110,140,20, 0, 21, 0, 0, 0, "Add a new Bone Group for the Pose");
+ uiBlockEndAlign(block);
+
+ /* colour set for 'active' group */
+ if (pose->active_group && grp) {
+ uiBlockBeginAlign(block);
+ menustr= build_colorsets_menustr();
+ uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
+ MEM_freeN(menustr);
+
+ /* show color-selection/preview */
+ if (grp->customCol) {
+ if (grp->customCol > 0) {
+ /* copy theme colors on-to group's custom color in case user tries to edit color */
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+
+ memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
+ }
+ else {
+ /* init custom colours with a generic multi-colour rgb set, if not initialised already */
+ if (grp->cs.solid[0] == 0) {
+ /* define for setting colors in theme below */
+ #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+
+ SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
+ SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
+ SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
+
+ #undef SETCOL
+ }
+ }
+
+ /* color changing */
+ uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
+ uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco+30, 65, 30, 19, grp->cs.select, 0, 0, 0, 0, "Color to use for 'selected' bones");
+ uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco+60, 65, 30, 19, grp->cs.active, 0, 0, 0, 0, "Color to use for 'active' bones");
+
+ uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_POSEGRP_MCUSTOM, "ConstCols", xco+90,65,50,20, &grp->cs.flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status");
+ }
+ uiBlockEndAlign(block);
+ }
+ }
+ return;
+ }
+
/* vertex group... partially editmode... */
if(ob->type==OB_MESH || ob->type==OB_LATTICE) {
bDeformGroup *defGroup;
@@ -4590,23 +5416,30 @@ static void editing_panel_links(Object *ob)
if(ob->totcol) min= 1.0; else min= 0.0;
ma= give_current_material(ob, ob->actcol);
- if(ma) uiDefBut(block, LABEL, 0, ma->id.name+2, 318,153, 103, 20, 0, 0, 0, 0, 0, "");
+ if(G.obedit) {
+ char *str= NULL;
+ IDnames_to_pupstring(&str, NULL, "ADD NEW %x 32767", &G.main->mat, NULL, NULL);
+ uiDefButS(block, MENU, B_MATASS_BROWSE, str, 292,150,20,20, &G.buts->menunr, 0, 0, 0, 0, "Browses existing choices and assign");
+ MEM_freeN(str);
+ }
+
+ if(ma) uiDefBut(block, LABEL, 0, ma->id.name+2, 318,150, 103, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- if(ma) uiDefButF(block, COL, B_REDR, "", 292,123,31,30, &(ma->r), 0, 0, 0, 0, "");
- uiDefButC(block, NUM, B_ACTCOL, str, 324,123,100,30, &ob->actcol, min, (float)(ob->totcol), 0, 0, "Displays total number of material indices and the current index");
- uiDefBut(block, BUT,B_MATWICH, "?", 424,123,30,30, 0, 0, 0, 0, 0, "In EditMode, sets the active material index from selected faces");
+ if(ma) uiDefButF(block, COL, B_MATCOL2, "", 292,113,31,30, &(ma->r), 0, 0, 0, 0, "");
+ uiDefButC(block, NUM, B_ACTCOL, str, 324,113,100,30, &ob->actcol, min, (float)(ob->totcol), 0, 0, "Displays total number of material indices and the current index");
+ uiDefBut(block, BUT,B_MATWICH, "?", 424,113,30,30, 0, 0, 0, 0, 0, "In EditMode, sets the active material index from selected faces");
uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_MATNEW, "New", 292,98,80,20, 0, 0, 0, 0, 0, "Adds a new Material index");
- uiDefBut(block, BUT,B_MATDEL, "Delete", 374,98,80,20, 0, 0, 0, 0, 0, "Deletes this Material index");
- uiDefBut(block, BUT,B_MATSEL, "Select", 292,76,80,20, 0, 0, 0, 0, 0, "In EditMode, selects faces that have the active index");
- uiDefBut(block, BUT,B_MATDESEL, "Deselect", 374,76,80,20, 0, 0, 0, 0, 0, "Deselects everything with current indexnumber");
- uiDefBut(block, BUT,B_MATASS, "Assign", 292,47,162,26, 0, 0, 0, 0, 0, "In EditMode, assigns the active index to selected faces");
+ uiDefBut(block, BUT,B_MATNEW, "New", 292,90,80,20, 0, 0, 0, 0, 0, "Adds a new Material index");
+ uiDefBut(block, BUT,B_MATDEL, "Delete", 372,90,80,20, 0, 0, 0, 0, 0, "Deletes this Material index");
+ uiDefBut(block, BUT,B_MATSEL, "Select", 292,70,80,20, 0, 0, 0, 0, 0, "In EditMode, selects faces that have the active index");
+ uiDefBut(block, BUT,B_MATDESEL, "Deselect", 372,70,80,20, 0, 0, 0, 0, 0, "Deselects everything with current indexnumber");
+ uiDefBut(block, BUT,B_MATASS, "Assign", 292,50,160,20, 0, 0, 0, 0, 0, "In EditMode, assigns the active index to selected faces");
uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 291,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
- uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 373,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
+ uiDefBut(block, BUT,B_SETSMOOTH,"Set Smooth", 292,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'smooth' rendering of selected faces");
+ uiDefBut(block, BUT,B_SETSOLID, "Set Solid", 372,15,80,20, 0, 0, 0, 0, 0, "In EditMode, sets 'solid' rendering of selected faces");
uiBlockEndAlign(block);
@@ -4621,22 +5454,29 @@ void editing_panel_sculpting_tools()
sculptmode_draw_interface_tools(block,0,200);
}
-void editing_panel_sculpting_textures()
+void editing_panel_sculpting_brush()
{
- uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_textures", UI_EMBOSS, UI_HELV, curarea->win);
+ uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_brush", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Brush", "Editing", 300, 0, 318, 204)==0) return;
+ sculptmode_draw_interface_brush(block,0,200);
+}
+
+void editing_panel_sculpting_textures()
+{
+ uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_texture", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Texture", "Editing", 300, 0, 318, 204)==0) return;
+
sculptmode_draw_interface_textures(block,0,200);
}
void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned short cy)
{
SculptData *sd;
- uiBut *but;
if(!G.scene) return;
sd= &G.scene->sculptdata;
-
+
uiBlockBeginAlign(block);
uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,"");
@@ -4663,9 +5503,9 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
uiDefButC(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&sculptmode_brush()->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
}
if(sd->brush_type!=GRAB_BRUSH)
- uiDefButC(block,TOG,B_NOP,"Airbrush",cx+178,cy,89,19,&sculptmode_brush()->airbrush,0,0,0,0,"Brush makes changes without waiting for the mouse to move");
+ uiDefButBitC(block, TOG, SCULPT_BRUSH_AIRBRUSH, 0, "Airbrush", cx+178,cy,89,19, &sculptmode_brush()->flag,0,0,0,0, "Brush makes changes without waiting for the mouse to move");
cy-= 20;
- but= uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
+ uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
cy-= 20;
if(sd->brush_type!=GRAB_BRUSH)
uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,268,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
@@ -4684,34 +5524,59 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
cx+= 210;
}
-void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsigned short cy)
+static void sculptmode_curves_reset(void *sd_v, void *j)
+{
+ SculptData *sd = sd_v;
+ sculpt_reset_curve(sd);
+ curvemapping_changed(sd->cumap, 0);
+}
+
+void sculptmode_draw_interface_brush(uiBlock *block, unsigned short cx, unsigned short cy)
{
SculptData *sd= sculpt_data();
- MTex *mtex;
- int i;
- int orig_y= cy;
- char *strp;
+ int orig_y = cy;
+ rctf rect;
uiBut *but;
uiBlockBeginAlign(block);
- uiDefBut(block,LABEL,B_NOP,"Common",cx,cy,80,20,0,0,0,0,0,"");
cy-= 20;
-
- uiBlockBeginAlign(block);
- uiDefButC(block,TOG,B_NOP, "Fade", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Smooth the edges of the texture");
+ uiDefButC(block,TOG,REDRAWBUTSEDIT, "Curve", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Use curve control for radial brush intensity");
cy-= 20;
+ but= uiDefBut(block, BUT, REDRAWBUTSEDIT, "Reset",cx,cy,80,19, NULL, 0,0,0,0, "Default curve preset");
+ uiButSetFunc(but, sculptmode_curves_reset, sd, NULL);
+ cy-= 25;
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
uiDefButS(block,NUM,B_NOP, "Space", cx,cy,80,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots");
cy-= 20;
if(sd->brush_type == DRAW_BRUSH)
uiDefButC(block,NUM,B_NOP, "View", cx,cy,80,19, &sculptmode_brush()->view, 0,10,20,0,"Pulls brush direction towards view");
+ cy-= 20;
+ uiDefButBitC(block, TOG, SCULPT_BRUSH_ANCHORED, 0, "Anchored", cx,cy,80,19, &sculptmode_brush()->flag, 0,0,0,0, "Keep the brush center anchored to the initial location");
uiBlockEndAlign(block);
-
- cy= orig_y;
- cx+= 85;
+
+ /* Draw curve */
+ cx += 90;
+ cy = orig_y;
+ rect.xmin= cx; rect.xmax= cx + 178;
+ rect.ymin= cy - 160; rect.ymax= cy + 20;
uiBlockBeginAlign(block);
- uiDefBut(block,LABEL,B_NOP,"Texture",cx,cy,80,20,0,0,0,0,0,"");
- cy-= 20;
+ curvemap_buttons(block, sd->cumap, (char)0, B_NOP, 0, &rect);
+ uiBlockEndAlign(block);
+}
+void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsigned short cy)
+{
+ SculptData *sd= sculpt_data();
+ MTex *mtex;
+ int i;
+ int orig_y= cy;
+ char *strp;
+ uiBut *but;
+
+ uiBlockBeginAlign(block);
+ cy-= 20;
/* TEX CHANNELS */
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_NEUTRAL);
@@ -4765,9 +5630,16 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig
if(sd->texrept != SCULPTREPT_3D) {
uiBlockBeginAlign(block);
uiDefButF(block,NUM,0, "Angle", cx,cy,115,19, &mtex->warpfac, 0,360,100,0, "Rotate texture counterclockwise");
+ /*Moved inside, so that following buttons aren't made bigger for no reason*/
+ cy-= 20;
}
- cy-= 20;
-
+
+ /* Added Rake button. Needs to be turned off if 3D is on / disappear*/
+ if(sd->texrept != SCULPTREPT_3D){
+ uiDefButC(block,TOG,B_NOP, "Rake", cx,cy,115,19, &sd->rake, 0,0,0,0,"Rotate the brush in the direction of motion");
+ cy-=20;
+ }
+
if(sd->texrept != SCULPTREPT_DRAG) {
uiBlockBeginAlign(block);
but= uiDefIconButC(block, TOG, REDRAWBUTSEDIT, sd->texsep ? ICON_UNLOCKED : ICON_LOCKED, cx,cy,20,19, &sd->texsep,0,0,0,0, "Locks the texture sizes together");
@@ -4811,6 +5683,7 @@ void do_fpaintbuts(unsigned short event)
ToolSettings *settings= G.scene->toolsettings;
int nr= 1;
MTex *mtex;
+ ParticleSystem *psys;
ob= OBACT;
if(ob==NULL) return;
@@ -4825,7 +5698,7 @@ void do_fpaintbuts(unsigned short event)
case B_COPY_TF_COL:
case B_COPY_TF_TEX:
me= get_mesh(OBACT);
- activetf= get_active_tface(&activemcol);
+ activetf= get_active_mtface(NULL, &activemcol, 0);
if(me && activetf) {
for (a=0, tf=me->mtface, mf=me->mface; a < me->totface; a++, tf++, mf++) {
@@ -4862,7 +5735,7 @@ void do_fpaintbuts(unsigned short event)
}
break;
case B_SET_VCOL:
- if(G.f & G_FACESELECT)
+ if(FACESEL_PAINT_TEST)
clear_vpaint_selectedfaces();
else
clear_vpaint();
@@ -4879,7 +5752,7 @@ void do_fpaintbuts(unsigned short event)
break;
case B_TFACE_HALO:
- activetf = get_active_tface(NULL);
+ activetf = get_active_mtface(NULL, NULL, 0);
if(activetf) {
activetf->mode &= ~TF_BILLBOARD2;
allqueue(REDRAWBUTSEDIT, 0);
@@ -4887,7 +5760,7 @@ void do_fpaintbuts(unsigned short event)
break;
case B_TFACE_BILLB:
- activetf = get_active_tface(NULL);
+ activetf = get_active_mtface(NULL, NULL, 0);
if(activetf) {
activetf->mode &= ~TF_BILLBOARD;
allqueue(REDRAWBUTSEDIT, 0);
@@ -5054,7 +5927,11 @@ void do_fpaintbuts(unsigned short event)
if(G.buts->menunr==-2) {
MTex *mtex= brush->mtex[brush->texact];
ID *id= (ID*)((mtex)? mtex->tex: NULL);
- activate_databrowse(id, ID_TE, 0, B_BTEXBROWSE, &G.buts->menunr, do_global_buttons);
+ if(G.qual & LR_CTRLKEY) {
+ activate_databrowse_imasel(id, ID_TE, 0, B_BTEXBROWSE, &G.buts->menunr, do_fpaintbuts);
+ } else {
+ activate_databrowse(id, ID_TE, 0, B_BTEXBROWSE, &G.buts->menunr, do_fpaintbuts);
+ }
break;
}
else if(G.buts->menunr < 0) break;
@@ -5081,6 +5958,20 @@ void do_fpaintbuts(unsigned short event)
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWBUTSEDIT, 0);
break;
+ case B_BAKE_REDRAWEDIT:
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ case B_BAKE_RECACHE:
+ psys=PE_get_current(ob);
+ PE_hide_keys_time(psys,CFRA);
+ psys_cache_paths(ob,psys,CFRA,0);
+ if(PE_settings()->flag & PE_SHOW_CHILD)
+ psys_cache_child_paths(ob,psys,CFRA,0);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
}
}
@@ -5095,48 +5986,58 @@ void weight_paint_buttons(uiBlock *block)
if(ob==NULL) return;
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, REDRAWVIEW3D, "Weight:",10,160,225,19, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
+ uiDefButF(block, NUMSLI, REDRAWVIEW3D, "Weight:",10,170,225,19, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
- uiDefBut(block, BUT, B_WEIGHT0_0 , "0", 10,140,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4", 55,140,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2", 100,140,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4", 145,140,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_WEIGHT1_0 , "1", 190,140,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_WEIGHT0_0 , "0", 10,150,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4", 55,150,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2", 100,150,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4", 145,150,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_WEIGHT1_0 , "1", 190,150,45,19, 0, 0, 0, 0, 0, "");
- uiDefButF(block, NUMSLI, B_NOP, "Opacity ", 10,120,225,19, &Gwp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
+ uiDefButF(block, NUMSLI, B_NOP, "Opacity ", 10,130,225,19, &Gwp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
- uiDefBut(block, BUT, B_OPA1_8 , "1/8", 10,100,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_OPA1_4 , "1/4", 55,100,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_OPA1_2 , "1/2", 100,100,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_OPA3_4 , "3/4", 145,100,45,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_OPA1_0 , "1", 190,100,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_OPA1_8 , "1/8", 10,110,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_OPA1_4 , "1/4", 55,110,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_OPA1_2 , "1/2", 100,110,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_OPA3_4 , "3/4", 145,110,45,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_OPA1_0 , "1", 190,110,45,19, 0, 0, 0, 0, 0, "");
- uiDefButF(block, NUMSLI, B_NOP, "Size ", 10,80,225,19, &Gwp.size, 2.0, 64.0, 0, 0, "The size of the brush");
+ uiDefButF(block, NUMSLI, B_NOP, "Size ", 10,90,225,19, &Gwp.size, 2.0, 64.0, 0, 0, "The size of the brush");
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_DIFF, "Mix", 250,160,60,17, &Gwp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
- uiDefButS(block, ROW, B_DIFF, "Add", 250,142,60,17, &Gwp.mode, 1.0, 1.0, 0, 0, "Add the vertex colors");
- uiDefButS(block, ROW, B_DIFF, "Sub", 250,124,60,17, &Gwp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
- uiDefButS(block, ROW, B_DIFF, "Mul", 250,106,60,17, &Gwp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
- uiDefButS(block, ROW, B_DIFF, "Filter", 250, 88,60,17, &Gwp.mode, 1.0, 4.0, 0, 0, "Mix the colors with an alpha factor");
- uiDefButS(block, ROW, B_DIFF, "Lighter", 250, 70,60,17, &Gwp.mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
- uiDefButS(block, ROW, B_DIFF, "Darker", 250, 52,60,17, &Gwp.mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
+ uiDefButS(block, ROW, B_DIFF, "Mix", 250,170,60,17, &Gwp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
+ uiDefButS(block, ROW, B_DIFF, "Add", 250,152,60,17, &Gwp.mode, 1.0, 1.0, 0, 0, "Add the vertex colors");
+ uiDefButS(block, ROW, B_DIFF, "Sub", 250,134,60,17, &Gwp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
+ uiDefButS(block, ROW, B_DIFF, "Mul", 250,116,60,17, &Gwp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
+ uiDefButS(block, ROW, B_DIFF, "Blur", 250, 98,60,17, &Gwp.mode, 1.0, 4.0, 0, 0, "Blur the weight with surrounding values");
+ uiDefButS(block, ROW, B_DIFF, "Lighter", 250, 80,60,17, &Gwp.mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
+ uiDefButS(block, ROW, B_DIFF, "Darker", 250, 62,60,17, &Gwp.mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 160,55,75,19, &Gwp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
+ /* draw options same as below */
+ uiBlockBeginAlign(block);
+ if (FACESEL_PAINT_TEST) {
+ uiDefButBitI(block, TOG, G_DRAWFACES, B_UVAUTO_DRAWFACES, "Faces", 10,45,60,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades");
+ uiDefButBitI(block,TOG, G_DRAWEDGES, REDRAWVIEW3D,"Edges",70,45,60,19, &G.f, 2.0, 0, 0, 0, "Displays edges of visible faces");
+ uiDefButBitI(block,TOG, G_HIDDENEDGES, REDRAWVIEW3D,"Hidden Edges",130,45,100,19, &G.f, 2.0, 1.0, 0, 0, "Displays edges of hidden faces");
+ } else{
+ uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 10,45,75,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
+ }
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces", 10,30,75,19, &Gwp.flag, 0, 0, 0, 0, "Paint on all faces inside brush (otherwise only on face under mouse cursor)");
- uiDefButBitS(block, TOG, VP_SOFT, 0, "Vertex Dist", 85,30,75,19, &Gwp.flag, 0, 0, 0, 0, "Use distances to vertices (instead of all vertices of face)");
- uiDefButBitS(block, TOGN, VP_HARD, 0, "Soft", 160,30,75,19, &Gwp.flag, 0, 0, 0, 0, "Use a soft brush");
- uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 235,30,75,19, &Gwp.flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
+ uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces", 10,20,60,19, &Gwp.flag, 0, 0, 0, 0, "Paint on all faces inside brush (otherwise only on face under mouse cursor)");
+ uiDefButBitS(block, TOG, VP_SOFT, 0, "Vert Dist", 70,20,60,19, &Gwp.flag, 0, 0, 0, 0, "Use distances to vertices (instead of all vertices of face)");
+ uiDefButBitS(block, TOGN, VP_HARD, 0, "Soft", 130,20,60,19, &Gwp.flag, 0, 0, 0, 0, "Use a soft brush");
+ uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 190,20,60,19, &Gwp.flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
+ uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 250,20,55,19, &Gwp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
+ uiBlockEndAlign(block);
if(ob) {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, VP_ONLYVGROUP, REDRAWVIEW3D, "Vgroup", 10,0,75,19, &Gwp.flag, 0, 0, 0, 0, "Only paint on vertices in the selected vertex group.");
- uiDefButBitS(block, TOG, VP_MIRROR_X, REDRAWVIEW3D, "X-Mirror", 85,0,75,19, &Gwp.flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored Weight Group name");
- uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 160,0,75,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
- uiDefBut(block, BUT, B_CLR_WPAINT, "Clear", 235,0,75,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices");
+ uiDefButBitS(block, TOG, VP_ONLYVGROUP, REDRAWVIEW3D, "Vgroup", 10,0,100,19, &Gwp.flag, 0, 0, 0, 0, "Only paint on vertices in the selected vertex group.");
+ uiDefButBitS(block, TOG, VP_MIRROR_X, REDRAWVIEW3D, "X-Mirror", 110,0,100,19, &Gwp.flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored Weight Group name");
+ uiDefBut(block, BUT, B_CLR_WPAINT, "Clear", 210,0,100,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices");
uiBlockEndAlign(block);
}
}
@@ -5156,34 +6057,42 @@ static void editing_panel_mesh_paint(void)
extern VPaint Gvp; /* from vpaint */
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_NOP, "R ", 979,160,194,19, &Gvp.r, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of red used for painting");
- uiDefButF(block, NUMSLI, B_NOP, "G ", 979,140,194,19, &Gvp.g, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of green used for painting");
- uiDefButF(block, NUMSLI, B_NOP, "B ", 979,120,194,19, &Gvp.b, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of blue used for painting");
+ uiDefButF(block, NUMSLI, B_NOP, "R ", 979,170,150,19, &Gvp.r, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of red used for painting");
+ uiDefButF(block, NUMSLI, B_NOP, "G ", 979,150,150,19, &Gvp.g, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of green used for painting");
+ uiDefButF(block, NUMSLI, B_NOP, "B ", 979,130,150,19, &Gvp.b, 0.0, 1.0, B_VPCOLSLI, 0, "The amount of blue used for painting");
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_NOP, "Opacity ", 979,95,194,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
- uiDefButF(block, NUMSLI, B_NOP, "Size ", 979,75,194,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush");
+ uiDefButF(block, NUMSLI, B_NOP, "Opacity ", 979,105,222,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
+ uiDefButF(block, NUMSLI, B_NOP, "Size ", 979,85,222,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush");
uiBlockEndAlign(block);
- uiDefButF(block, COL, B_REDR, "", 1176,120,28,60, &(Gvp.r), 0, 0, 0, B_VPCOLSLI, "");
+ uiDefButF(block, COL, B_REDR, "", 1140,150,60,40, &(Gvp.r), 0, 0, 0, B_VPCOLSLI, "");
+ uiDefBut(block, BUT, B_SET_VCOL, "SetVCol", 1140,130,60,20, 0, 0, 0, 0, 0, "Set Vertex color of selection to current (Shift+K)");
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_DIFF, "Mix", 1212,160,63,17, &Gvp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
- uiDefButS(block, ROW, B_DIFF, "Add", 1212,142,63,17, &Gvp.mode, 1.0, 1.0, 0, 0, "Add the vertex color");
- uiDefButS(block, ROW, B_DIFF, "Sub", 1212, 124,63,17, &Gvp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
- uiDefButS(block, ROW, B_DIFF, "Mul", 1212, 106,63,17, &Gvp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
- uiDefButS(block, ROW, B_DIFF, "Filter", 1212, 88,63,17, &Gvp.mode, 1.0, 4.0, 0, 0, "Mix the colors with an alpha factor");
- uiDefButS(block, ROW, B_DIFF, "Lighter", 1212, 70,63,17, &Gvp.mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
- uiDefButS(block, ROW, B_DIFF, "Darker", 1212, 52,63,17, &Gvp.mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
+ uiDefButS(block, ROW, B_DIFF, "Mix", 1212,170,63,17, &Gvp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
+ uiDefButS(block, ROW, B_DIFF, "Add", 1212,152,63,17, &Gvp.mode, 1.0, 1.0, 0, 0, "Add the vertex color");
+ uiDefButS(block, ROW, B_DIFF, "Sub", 1212, 134,63,17, &Gvp.mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
+ uiDefButS(block, ROW, B_DIFF, "Mul", 1212, 116,63,17, &Gvp.mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
+ uiDefButS(block, ROW, B_DIFF, "Blur", 1212, 98,63,17, &Gvp.mode, 1.0, 4.0, 0, 0, "Blur the color with surrounding values");
+ uiDefButS(block, ROW, B_DIFF, "Lighter", 1212, 80,63,17, &Gvp.mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
+ uiDefButS(block, ROW, B_DIFF, "Darker", 1212, 62,63,17, &Gvp.mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
uiBlockEndAlign(block);
- uiDefBut(block, BUT, B_SET_VCOL, "Set VertCol", 979,50,81,20, 0, 0, 0, 0, 0, "Set Vertex color of selection to current (Shift+K)");
+ /* draw options */
+ uiBlockBeginAlign(block);
+ if (FACESEL_PAINT_TEST) {
+ uiDefButBitI(block, TOG, G_DRAWFACES, B_UVAUTO_DRAWFACES, "Faces", 979,50,60,19, &G.f, 0, 0, 0, 0, "Displays all faces as shades");
+ uiDefButBitI(block,TOG, G_DRAWEDGES, REDRAWVIEW3D,"Edges",1039,50,60,19, &G.f, 2.0, 0, 0, 0, "Displays edges of visible faces");
+ uiDefButBitI(block,TOG, G_HIDDENEDGES, REDRAWVIEW3D,"Hidden Edges",1099,50,100,19, &G.f, 2.0, 1.0, 0, 0, "Displays edges of hidden faces");
+ }
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces", 979,25,75,19, &Gvp.flag, 0, 0, 0, 0, "Paint on all faces inside brush");
uiDefButBitS(block, TOG, VP_SOFT, 0, "Vertex Dist", 1054,25,75,19, &Gvp.flag, 0, 0, 0, 0, "Use distances to vertices (instead of paint entire faces)");
uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals", 1129,25,75,19, &Gvp.flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
- uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 1204,25,75,19, &Gvp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
+ uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray", 1204,25,72,19, &Gvp.flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
uiBlockBeginAlign(block);
uiDefBut(block, BUT, B_VPGAMMA, "Set", 979,0,81,19, 0, 0, 0, 0, 0, "Apply Mul and Gamma to vertex colors");
@@ -5252,14 +6161,14 @@ static void editing_panel_mesh_paint(void)
static void editing_panel_mesh_texface(void)
{
- extern VPaint Gvp; /* from vpaint */
uiBlock *block;
MTFace *tf;
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_texface", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Texture face", "Editing", 960, 0, 318, 204)==0) return;
-
- tf = get_active_tface(NULL);
+ uiNewPanelTabbed("Multires", "Editing");
+ if(uiNewPanel(curarea, block, "Texture Face", "Editing", 960, 0, 318, 204)==0) return;
+
+ tf = get_active_mtface(NULL, NULL, 0);
if(tf) {
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex", 600,160,60,19, &tf->mode, 0, 0, 0, 0, "Render face with texture");
@@ -5282,20 +6191,9 @@ static void editing_panel_mesh_texface(void)
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,80,60,19, &tf->transp, 2.0, 0.0, 0, 0, "Render color of textured face as color");
- uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &tf->transp, 2.0, 1.0, 0, 0, "Render face transparent and add color of face");
- uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &tf->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture");
-
- uiBlockSetCol(block, TH_AUTO);
-
- uiBlockBeginAlign(block);
- uiDefButF(block, COL, B_VPCOLSLI, "", 769,40,40,28, &(Gvp.r), 0, 0, 0, 0, "");
- uiDefBut(block, BUT, B_SET_VCOL, "Set VertCol", 809,40,103,28, 0, 0, 0, 0, 0, "Set Vertex color of selection to current (Shift+K)");
-
- uiBlockBeginAlign(block);
- uiDefBut(block, BUT, B_COPY_TF_MODE, "Copy DrawMode", 600,7,117,28, 0, 0, 0, 0, 0, "Copy the drawmode from active face to selected faces");
- uiDefBut(block, BUT, B_COPY_TF_UV, "Copy UV+tex", 721,7,85,28, 0, 0, 0, 0, 0, "Copy UV information and textures from active face to selected faces");
- uiDefBut(block, BUT, B_COPY_TF_COL, "Copy VertCol", 809,7,103,28, 0, 0, 0, 0, 0, "Copy vertex colors from active face to selected faces");
+ uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque", 600,80,60,19, &tf->transp, 2.0, (float)TF_SOLID,0, 0, "Render color of textured face as color");
+ uiDefButC(block, ROW, REDRAWVIEW3D, "Add", 660,80,60,19, &tf->transp, 2.0, (float)TF_ADD, 0, 0, "Render face transparent and add color of face");
+ uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha", 720,80,60,19, &tf->transp, 2.0, (float)TF_ALPHA,0, 0, "Render polygon transparent, depending on alpha channel of the texture");
}
}
@@ -5316,16 +6214,9 @@ static void editing_panel_mesh_uvautocalculation(void)
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_uvautocalculation", UI_EMBOSS, UI_HELV, curarea->win);
/* make this a tab of "Texture face" to save screen space*/
- uiNewPanelTabbed("Texture face", "Editing");
+ uiNewPanelTabbed("Multires", "Editing");
if(uiNewPanel(curarea, block, "UV Calculation", "Editing", 960, 0, 318, 204)==0)
return;
-
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, G_DRAWFACES, B_UVAUTO_DRAWFACES, "Draw Faces", 100,row,200,butH, &G.f, 0, 0, 0, 0, "Displays all faces as shades");
- uiDefButBitI(block,TOG, G_DRAWEDGES, REDRAWVIEW3D,"Draw Edges",100,row-butHB,200,butH,&G.f, 2.0, 0, 0, 0, "Displays edges of visible faces");
- uiDefButBitI(block,TOG, G_HIDDENEDGES, REDRAWVIEW3D,"Draw Hidden Edges",100,row-2*butHB,200,butH,&G.f, 2.0, 1.0, 0, 0, "Displays edges of hidden faces");
- uiDefButBitI(block,TOG, G_DRAWSEAMS, REDRAWVIEW3D,"Draw Seams",100,row-3*butHB,200,butH,&G.f, 2.0, 2.0, 0, 0, "Displays UV unwrapping seams");
- uiBlockEndAlign(block);
row-= 4*butHB+butS;
uiBlockBeginAlign(block);
@@ -5373,7 +6264,7 @@ void editing_panel_mesh_multires()
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if(!me->mr) {
- but= uiDefBut(block,BUT,B_NOP,"Add Multires", cx,cy,268,19,0,0,0,0,0,"");
+ but= uiDefBut(block,BUT,B_NOP,"Add Multires", cx,cy,268,19,0,0,0,0,0,"Allow editing of the mesh at multiple subdivision levels (disables distructive mesh editing)");
uiButSetFunc(but,multires_make,ob,me);
} else {
char subsurfmenu[]= "Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
@@ -5384,7 +6275,7 @@ void editing_panel_mesh_multires()
uiBlockBeginAlign(block);
but= uiDefBut(block,BUT,B_NOP,"Add Level", cx,cy,134,19,0,0,0,0,0,"Add a new level of subdivision at the end of the chain");
- uiButSetFunc(but,multires_add_level,ob,me);
+ uiButSetFunc(but, multires_subdivide, ob, me);
uiDefButC(block, MENU, B_NOP, subsurfmenu, cx + 134, cy, 134, 19, &G.scene->toolsettings->multires_subdiv_type, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
cy-= 20;
@@ -5400,7 +6291,7 @@ void editing_panel_mesh_multires()
cy-= 20;
but= uiDefButC(block,NUM,B_NOP,"Edges: ",cx,cy,268,19,(char *)&me->mr->edgelvl,1.0,me->mr->level_count,0,0,"Set level of edges to display");
- uiButSetFunc(but,multires_edge_level_update,ob,me);
+ uiButSetFunc(but,multires_edge_level_update_cb,ob,me);
cy-= 20;
uiBlockEndAlign(block);
@@ -5426,6 +6317,126 @@ void editing_panel_mesh_multires()
uiBlockEndAlign(block);
}
+void particle_edit_buttons(uiBlock *block)
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEditSettings *pset = PE_settings();
+ ParticleEdit *edit;
+ uiBut *but;
+ short butx=10,buty=150,butw=150,buth=20, lastbuty;
+ static short partact;
+
+ char *menustr;
+
+ if(psys==NULL) return;
+
+ menustr = psys_menu_string(ob, 0);
+ partact = PE_get_current_num(ob)+1;
+
+ but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr, 160,180,butw,buth, &partact, 14.0, 0.0, 0, 0, "Browse systems");
+ uiButSetFunc(but, PE_change_act, ob, &partact);
+
+ MEM_freeN(menustr);
+
+ if(psys->edit) {
+ edit= psys->edit;
+
+ /* brushes (the update evend needs to be B_BAKE_RECACHE so that path colors are updated properly) */
+ uiBlockBeginAlign(block);
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"None",butx,buty,75,19,&pset->brushtype,14.0,PE_BRUSH_NONE,0,0,"Disable brush");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Comb",butx+75,buty,75,19,&pset->brushtype,14.0,PE_BRUSH_COMB,0,0,"Comb hairs");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Smooth",butx+150,buty,75,19,&pset->brushtype,14.0,PE_BRUSH_SMOOTH,0,0,"Smooth hairs");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Weight",butx+225,buty,75,19,&pset->brushtype,14,PE_BRUSH_WEIGHT,0,0,"Weight hairs");
+ buty-= buth;
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Add", butx,buty,75,19,&pset->brushtype,14,PE_BRUSH_ADD,0,0,"Add hairs");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Length", butx+75,buty,75,19,&pset->brushtype,14, PE_BRUSH_LENGTH,0,0,"Make hairs longer or shorter");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Puff", butx+150,buty,75,19,&pset->brushtype,14, PE_BRUSH_PUFF,0,0,"Make hairs stand up");
+ uiDefButS(block,ROW,B_BAKE_RECACHE,"Cut", butx+225,buty,75,19,&pset->brushtype,14, PE_BRUSH_CUT,0,0,"Cut hairs");
+ uiBlockEndAlign(block);
+
+ buty-= 10;
+ lastbuty= buty;
+
+ /* brush options */
+ if(pset->brushtype>=0) {
+ ParticleBrushData *brush= &pset->brush[pset->brushtype];
+
+ butw= 180;
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUMSLI, B_BAKE_REDRAWEDIT, "Size:", butx,(buty-=buth),butw,buth, &brush->size, 1.0, 100.0, 1, 1, "Brush size");
+ uiDefButS(block, NUMSLI, B_BAKE_REDRAWEDIT, "Strength:", butx,(buty-=buth),butw,buth, &brush->strength, 1.0, 100.0, 1, 1, "Brush strength");
+
+ if(ELEM(pset->brushtype, PE_BRUSH_LENGTH, PE_BRUSH_PUFF)) {
+ char *str1, *str2, *tip1, *tip2;
+
+ if(pset->brushtype == PE_BRUSH_LENGTH) {
+ str1= "Grow"; tip1= "Make hairs longer [Shift]";
+ str2= "Shrink"; tip2= "Make hairs shorter [Shift]";
+ }
+ else /*if(pset->brushtype == PE_BRUSH_PUFF)*/ {
+ str1= "Add"; tip1= "Make hair more puffy [Shift]";
+ str2= "Sub"; tip2= "Make hair less puffy [Shift]";
+ }
+
+ uiDefButS(block,ROW,B_NOP,str1, butx,(buty-=buth),butw/2,buth,&brush->invert,0.0,0.0,0, 0,tip1);
+ uiDefButS(block,ROW,B_NOP,str2, butx+butw/2,buty,butw/2,buth,&brush->invert,0.0,1.0,0, 0,tip2);
+ }
+ uiBlockEndAlign(block);
+
+ butx += butw+10;
+ buty= lastbuty;
+ butw= 110;
+
+ if(pset->brushtype==PE_BRUSH_ADD) {
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PE_INTERPOLATE_ADDED, B_BAKE_REDRAWEDIT, "Interpolate", butx,(buty-=buth),butw,buth, &pset->flag, 0, 0, 0, 0, "Interpolate new particles from the existing ones");
+ uiDefButS(block, NUMSLI, B_BAKE_REDRAWEDIT, "Step:", butx,(buty-=buth),butw,buth, &brush->step, 1.0, 50.0, 1, 1, "Brush step");
+ uiDefButS(block, NUMSLI, B_BAKE_REDRAWEDIT, "Keys:", butx,(buty-=buth),butw,buth, &pset->totaddkey, 2.0, 20.0, 1, 1, "How many keys to make new particles with");
+ uiBlockEndAlign(block);
+ }
+ }
+
+ /* keep options */
+ butw= 150;
+ butx= 10;
+ buty= lastbuty - (buth*3 + 10);
+ lastbuty= buty;
+
+ uiDefBut(block, LABEL, 0, "Keep", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PE_KEEP_LENGTHS, B_BAKE_REDRAWEDIT, "Lengths", butx,(buty-=buth),butw/2,buth, &pset->flag, 0, 0, 0, 0, "Keep path lengths constant");
+ uiDefButBitS(block, TOG, PE_LOCK_FIRST, B_BAKE_REDRAWEDIT, "Root", butx+butw/2,buty,butw/2,buth, &pset->flag, 0, 0, 0, 0, "Keep first keys unmodified");
+ uiBlockEndAlign(block);
+
+ buty -= 5;
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PE_DEFLECT_EMITTER, B_BAKE_REDRAWEDIT, "Deflect Emitter", butx,(buty-=buth),butw,buth, &pset->flag, 0, 0, 0, 0, "Keep paths from intersecting the emitter");
+ uiDefButF(block, NUM, B_BAKE_REDRAWEDIT, "Dist:", butx,(buty-=buth),butw,buth, &pset->emitterdist, 0.0, 10.0, 1, 1, "Distance from emitter");
+ uiBlockEndAlign(block);
+
+ buty= lastbuty;
+ butx += butw+10;
+ butw -= 10;
+
+ uiDefBut(block, LABEL, 0, "Draw", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUMSLI, B_BAKE_RECACHE, "Steps:", butx,(buty-=buth),butw,buth, &psys->part->draw_step, 0.0, 10.0, 1, 1, "Drawing accuracy of paths");
+ uiBlockEndAlign(block);
+
+ buty -= 5;
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PE_SHOW_TIME, B_BAKE_REDRAWEDIT, "Show Time", butx,(buty-=buth),butw,buth, &pset->flag, 0, 0, 0, 0, "Show time values of the baked keys");
+ uiDefButBitS(block, TOG, PE_SHOW_CHILD, B_BAKE_RECACHE, "Show Children", butx,(buty-=buth),butw,buth, &pset->flag, 0, 0, 0, 0, "Show child particles in particle mode");
+ uiBlockEndAlign(block);
+ }
+ else{
+ uiDefBut(block, LABEL, 0, "System isn't editable", butx,(buty-=buth),250,buth, NULL, 0.0, 0, 0, 0, "");
+ }
+}
/* this is a mode context sensitive system */
void editing_panels()
@@ -5452,17 +6463,20 @@ void editing_panels()
if(G.obedit) {
editing_panel_mesh_tools(ob, ob->data);
editing_panel_mesh_tools1(ob, ob->data);
+ uiNewPanelTabbed("Mesh Tools 1", "Editing");
+ editing_panel_mesh_skgen(ob, ob->data);
+ editing_panel_mesh_uvautocalculation();
+ if (EM_texFaceCheck())
+ editing_panel_mesh_texface();
}
else if(G.f & G_SCULPTMODE) {
uiNewPanelTabbed("Multires", "Editing");
editing_panel_sculpting_tools();
uiNewPanelTabbed("Multires", "Editing");
+ editing_panel_sculpting_brush();
+ uiNewPanelTabbed("Multires", "Editing");
editing_panel_sculpting_textures();
} else {
- if(G.f & G_FACESELECT) {
- editing_panel_mesh_texface();
- editing_panel_mesh_uvautocalculation();
- }
if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) ) {
editing_panel_mesh_paint();
}
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 77922f041d8..6b69a4a8da7 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -712,6 +712,8 @@ static char *actuator_name(int type)
return "Game";
case ACT_VISIBILITY:
return "Visibility";
+ case ACT_2DFILTER:
+ return "2D Filter";
}
return "unknown";
}
@@ -727,13 +729,13 @@ static char *actuator_pup(Object *owner)
return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18";
+ "|Visibility %x18|2D Filter %x19";
break;
default:
return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18";
+ "|Visibility %x18|2D Filter %x19";
}
}
@@ -1476,6 +1478,7 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
bActionActuator *aa = NULL;
bGameActuator *gma = NULL;
bVisibilityActuator *visAct = NULL;
+ bTwoDFilterActuator *tdfa = NULL;
float *fp;
short ysize = 0, wval;
@@ -2172,6 +2175,58 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
yco -= ysize;
break;
+ case ACT_2DFILTER:
+ tdfa = act->data;
+
+ ysize = 50;
+ if(tdfa->type == ACT_2DFILTER_CUSTOMFILTER)
+ {
+ ysize +=20;
+ }
+ glRects( xco, yco-ysize, xco+width, yco );
+ uiEmboss( (float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1 );
+
+ switch(tdfa->type)
+ {
+ case ACT_2DFILTER_MOTIONBLUR:
+ if(!tdfa->flag)
+ {
+ uiDefButS(block, TOG, B_REDR, "D", xco+30,yco-44,19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur");
+ uiDefButF(block, NUM, B_REDR, "Value:", xco+52,yco-44,width-82,19,&tdfa->float_arg,0.0,1.0,0.0,0.0,"Set motion blur value");
+ }
+ else
+ {
+ uiDefButS(block, TOG, B_REDR, "Disabled", xco+30,yco-44,width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur");
+ }
+ break;
+ case ACT_2DFILTER_BLUR:
+ case ACT_2DFILTER_SHARPEN:
+ case ACT_2DFILTER_DILATION:
+ case ACT_2DFILTER_EROSION:
+ case ACT_2DFILTER_LAPLACIAN:
+ case ACT_2DFILTER_SOBEL:
+ case ACT_2DFILTER_PREWITT:
+ case ACT_2DFILTER_GRAYSCALE:
+ case ACT_2DFILTER_SEPIA:
+ case ACT_2DFILTER_INVERT:
+ case ACT_2DFILTER_NOFILTER:
+ case ACT_2DFILTER_DISABLED:
+ case ACT_2DFILTER_ENABLED:
+ uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
+ break;
+ case ACT_2DFILTER_CUSTOMFILTER:
+ uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
+ uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
+ break;
+ }
+
+ str= "2D Filter %t|Motion Blur %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|"
+ "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|"
+ "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|";
+ uiDefButS(block, MENU, B_REDR, str, xco+30,yco-24,width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type");
+
+ yco -= ysize;
+ break;
default:
ysize= 4;
@@ -2536,7 +2591,7 @@ void logic_buts(void)
ob= OBACT;
if(ob==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
sprintf(name, "buttonswin %d", curarea->win);
block= uiNewBlock(&curarea->uiblocks, name, UI_EMBOSS, UI_HELV, curarea->win);
@@ -2616,7 +2671,7 @@ void logic_buts(void)
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
@@ -2687,7 +2742,7 @@ void logic_buts(void)
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
/* presume it is only objects for now */
@@ -2755,7 +2810,7 @@ void logic_buts(void)
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if( (ob->scavisflag & OB_VIS_ACT) == 0) continue;
/* presume it is only objects for now */
@@ -2812,3 +2867,4 @@ void logic_buts(void)
if(idar) MEM_freeN(idar);
}
+
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index bb5ac2ba682..8fb4fab4a92 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -47,11 +47,13 @@
#include "DNA_scene_types.h"
#include "BKE_action.h"
+#include "BKE_cloth.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
+#include "BKE_particle.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -61,6 +63,7 @@
#include "BIF_butspace.h"
#include "BIF_editaction.h"
+#include "BIF_editparticle.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_graphics.h"
@@ -73,6 +76,7 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BIF_outliner.h"
#include "BDR_drawobject.h"
#include "BDR_editcurve.h"
@@ -86,6 +90,7 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
@@ -101,6 +106,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
#include "DNA_radio_types.h"
#include "DNA_screen_types.h"
#include "DNA_sound_types.h"
@@ -109,6 +115,7 @@
#include "DNA_vfont_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
+#include "DNA_text_types.h"
#include "BKE_anim.h"
#include "BKE_armature.h"
@@ -128,6 +135,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_sound.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -138,11 +146,13 @@
#include "BIF_editconstraint.h"
#include "BIF_editdeform.h"
+#include "BIF_editparticle.h"
#include "BSE_editipo.h"
#include "BSE_edit.h"
#include "BDR_editobject.h"
+#include "BPY_extern.h"
#include "butspace.h" // own module
@@ -182,27 +192,29 @@ static void constraint_active_func(void *ob_v, void *con_v)
static void add_constraint_to_active(Object *ob, bConstraint *con)
{
- ListBase *list;
+ ListBase *list= get_active_constraints(ob);
+ bPoseChannel *pchan= get_active_posechannel(ob);
- list = get_active_constraints(ob);
if (list) {
unique_constraint_name(con, list);
BLI_addtail(list, con);
+ if (proxylocked_constraints_owner(ob, pchan))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
+
con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
+ for (con= con->prev; con; con= con->prev)
con->flag &= ~CONSTRAINT_ACTIVE;
}
}
/* returns base ID for Ipo, sets actname to channel if appropriate */
/* should not make action... */
-void get_constraint_ipo_context(void *ob_v, char *actname)
+static void get_constraint_ipo_context(void *ob_v, char *actname)
{
Object *ob= ob_v;
- /* todo; check object if it has ob-level action ipo */
-
+ /* todo: check object if it has ob-level action ipo */
if (ob->flag & OB_POSEMODE) {
bPoseChannel *pchan;
@@ -229,8 +241,11 @@ static void enable_constraint_ipo_func (void *ob_v, void *con_v)
get_constraint_ipo_context(ob, actname);
/* adds ipo & channels & curve if needed */
- verify_ipo((ID *)ob, ID_CO, actname, con->name);
-
+ if(con->flag & CONSTRAINT_OWN_IPO)
+ verify_ipo((ID *)ob, ID_CO, NULL, con->name, actname);
+ else
+ verify_ipo((ID *)ob, ID_CO, actname, con->name, NULL);
+
/* make sure ipowin shows it */
ob->ipowin= ID_CO;
allqueue(REDRAWIPO, ID_CO);
@@ -253,17 +268,20 @@ static void add_influence_key_to_constraint_func (void *ob_v, void *con_v)
get_constraint_ipo_context(ob, actname);
/* adds ipo & channels & curve if needed */
- icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, CO_ENFORCE);
-
+ if(con->flag & CONSTRAINT_OWN_IPO)
+ icu= verify_ipocurve((ID *)ob, ID_CO, NULL, con->name, actname, CO_ENFORCE);
+ else
+ icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, NULL, CO_ENFORCE);
+
if (!icu) {
error("Cannot get a curve from this IPO, may be dealing with linked data");
return;
}
if(ob->action)
- insert_vert_ipo(icu, get_action_frame(ob, (float)CFRA), con->enforce);
+ insert_vert_icu(icu, get_action_frame(ob, (float)CFRA), con->enforce, 0);
else
- insert_vert_ipo(icu, CFRA, con->enforce);
+ insert_vert_icu(icu, CFRA, con->enforce, 0);
/* make sure ipowin shows it */
ob->ipowin= ID_CO;
@@ -323,106 +341,6 @@ static void verify_constraint_name_func (void *con_v, void *name_v)
allqueue(REDRAWACTION, 0);
}
-void get_constraint_typestring (char *str, void *con_v)
-{
- bConstraint *con= con_v;
-
- switch (con->type){
- case CONSTRAINT_TYPE_CHILDOF:
- strcpy (str, "Child Of");
- return;
- case CONSTRAINT_TYPE_NULL:
- strcpy (str, "Null");
- return;
- case CONSTRAINT_TYPE_TRACKTO:
- strcpy (str, "Track To");
- return;
- case CONSTRAINT_TYPE_MINMAX:
- strcpy (str, "Floor");
- return;
- case CONSTRAINT_TYPE_KINEMATIC:
- strcpy (str, "IK Solver");
- return;
- case CONSTRAINT_TYPE_ROTLIKE:
- strcpy (str, "Copy Rotation");
- return;
- case CONSTRAINT_TYPE_LOCLIKE:
- strcpy (str, "Copy Location");
- return;
- case CONSTRAINT_TYPE_SIZELIKE:
- strcpy (str, "Copy Scale");
- return;
- case CONSTRAINT_TYPE_ACTION:
- strcpy (str, "Action");
- return;
- case CONSTRAINT_TYPE_LOCKTRACK:
- strcpy (str, "Locked Track");
- return;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- strcpy (str, "Follow Path");
- return;
- case CONSTRAINT_TYPE_STRETCHTO:
- strcpy (str, "Stretch To");
- return;
- case CONSTRAINT_TYPE_LOCLIMIT:
- strcpy (str, "Limit Location");
- return;
- case CONSTRAINT_TYPE_ROTLIMIT:
- strcpy (str, "Limit Rotation");
- return;
- case CONSTRAINT_TYPE_SIZELIMIT:
- strcpy (str, "Limit Scale");
- return;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- strcpy (str, "Rigid Body");
- return;
- case CONSTRAINT_TYPE_CLAMPTO:
- strcpy (str, "Clamp To");
- return;
- default:
- strcpy (str, "Unknown");
- return;
- }
-}
-
-static int get_constraint_col(bConstraint *con)
-{
- switch (con->type) {
- case CONSTRAINT_TYPE_NULL:
- return TH_BUT_NEUTRAL;
- case CONSTRAINT_TYPE_KINEMATIC:
- return TH_BUT_SETTING2;
- case CONSTRAINT_TYPE_TRACKTO:
- return TH_BUT_SETTING;
- case CONSTRAINT_TYPE_ROTLIKE:
- return TH_BUT_SETTING1;
- case CONSTRAINT_TYPE_LOCLIKE:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_MINMAX:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_SIZELIKE:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_ACTION:
- return TH_BUT_ACTION;
- case CONSTRAINT_TYPE_LOCKTRACK:
- return TH_BUT_SETTING;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- return TH_BUT_SETTING2;
- case CONSTRAINT_TYPE_STRETCHTO:
- return TH_BUT_SETTING;
- case CONSTRAINT_TYPE_LOCLIMIT:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_ROTLIMIT:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_SIZELIMIT:
- return TH_BUT_POPUP;
- case CONSTRAINT_TYPE_RIGIDBODYJOINT:
- return TH_BUT_SETTING;
- default:
- return TH_REDALERT;
- }
-}
-
void const_moveUp(void *ob_v, void *con_v)
{
bConstraint *con, *constr= con_v;
@@ -508,58 +426,133 @@ void autocomplete_vgroup(char *str, void *arg_v)
}
}
-static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
+/* pole angle callback */
+void con_kinematic_set_pole_angle(void *ob_v, void *con_v)
{
- Object *ob= OBACT, *target;
- uiBut *but;
- char typestr[64], *subtarget;
- short height, width = 265, is_armature_target;
- int curCol, rb_col;
+ bConstraint *con= con_v;
+ bKinematicConstraint *data = con->data;
+
+ if(data->poletar) {
+ if(data->flag & CONSTRAINT_IK_SETANGLE) {
+ data->flag |= CONSTRAINT_IK_GETANGLE;
+ data->flag &= ~CONSTRAINT_IK_SETANGLE;
+ }
+ else {
+ data->flag &= ~CONSTRAINT_IK_GETANGLE;
+ data->flag |= CONSTRAINT_IK_SETANGLE;
+ }
+ }
+}
+
+/* some commonly used macros in the constraints drawing code */
+#define is_armature_target(target) (target && target->type==OB_ARMATURE)
+#define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->flag & OB_POSEMODE))
+#define is_geom_target(target) (target && (ELEM(target->type, OB_MESH, OB_LATTICE)) )
- target= get_constraint_target(con, &subtarget);
- is_armature_target= (target && target->type==OB_ARMATURE);
+/* Helper function for draw constraint - draws constraint space stuff
+ * This function should not be called if no menus are required
+ * owner/target: -1 = don't draw menu; 0= not posemode, 1 = posemode
+ */
+static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short xco, short yco, short owner, short target)
+{
+ short tarx, ownx;
+ short bwidth;
+
+ /* calculate sizes and placement of menus */
+ if (owner == -1) {
+ bwidth = 125;
+ tarx = 120;
+ ownx = 0;
+ }
+ else if (target == -1) {
+ bwidth = 125;
+ tarx = 0;
+ ownx = 120;
+ }
+ else {
+ bwidth = 100;
+ tarx = 95;
+ ownx = tarx + bwidth;
+ }
- /* unless button has own callback, it adds this callback to button */
- uiBlockSetFunc(block, constraint_active_func, ob, con);
- get_constraint_typestring (typestr, con);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "CSpace:", xco, yco, 80,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiBlockBeginAlign(block);
+
+ /* Target-Space */
+ if (target == 1) {
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
+ tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in");
+ }
+ else if (target == 0) {
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1",
+ tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in");
+ }
+
+ /* Owner-Space */
+ if (owner == 1) {
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
+ ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");
+ }
+ else if (owner == 0) {
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Local (Without Parent) Space %x1",
+ ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");
+ }
+
+ uiBlockEndAlign(block);
+}
- curCol = get_constraint_col(con);
+/* draw panel showing settings for a constraint */
+static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
+{
+ Object *ob= OBACT;
+ bPoseChannel *pchan= get_active_posechannel(ob);
+ bConstraintTypeInfo *cti;
+ uiBut *but;
+ char typestr[32];
+ short height, width = 265;
+ short proxy_protected;
+ int rb_col;
+
+ /* get constraint typeinfo */
+ cti= constraint_get_typeinfo(con);
+ if (cti == NULL) {
+ /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
+ if (con->type == CONSTRAINT_TYPE_NULL)
+ strcpy(typestr, "Null");
+ else
+ strcpy(typestr, "Unknown");
+ }
+ else
+ strcpy(typestr, cti->name);
+
+ /* determine whether constraint is proxy protected or not */
+ if (proxylocked_constraints_owner(ob, pchan)) {
+ proxy_protected= (con->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+ }
+ else
+ proxy_protected= 0;
+
+ /* unless button has own callback, it adds this callback to button */
+ uiBlockSetFunc(block, constraint_active_func, ob, con);
/* Draw constraint header */
uiBlockSetEmboss(block, UI_EMBOSSN);
/* rounded header */
- rb_col= (con->flag & CONSTRAINT_ACTIVE)?40:20;
+ rb_col= (con->flag & CONSTRAINT_ACTIVE)?50:20;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-1, width+40, 22, NULL, 5.0, 0.0,
(con->flag & CONSTRAINT_EXPAND)?3:15 , rb_col-20, "");
/* open/close */
uiDefIconButBitS(block, ICONTOG, CONSTRAINT_EXPAND, B_CONSTRAINT_TEST, ICON_DISCLOSURE_TRI_RIGHT, *xco-10, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
- /* up down */
- uiBlockSetEmboss(block, UI_EMBOSS);
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier up in stack");
- uiButSetFunc(but, constraint_moveUp, ob, con);
-
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+20, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
- uiButSetFunc(but, constraint_moveDown, ob, con);
-
- if (con->flag & CONSTRAINT_EXPAND) {
-
- if (con->flag & CONSTRAINT_DISABLE) {
- BIF_ThemeColor(TH_REDALERT);
+ /* name */
+ if ((con->flag & CONSTRAINT_EXPAND) && (proxy_protected==0)) {
+ if (con->flag & CONSTRAINT_DISABLE)
uiBlockSetCol(block, TH_REDALERT);
- }
- else {
- BIF_ThemeColor(curCol);
- }
-
- /*if (type==TARGET_BONE)
- but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Bone Constraint%t|Track To%x2|IK Solver%x3|Copy Rotation%x8|Copy Location%x9|Action%x12|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type");
- else
- but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Object Constraint%t|Track To%x2|Copy Rotation%x8|Copy Location%x9|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type");
- */
+
uiBlockSetEmboss(block, UI_EMBOSS);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -569,14 +562,9 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
}
else {
uiBlockSetEmboss(block, UI_EMBOSSN);
-
- if (con->flag & CONSTRAINT_DISABLE) {
+
+ if (con->flag & CONSTRAINT_DISABLE)
uiBlockSetCol(block, TH_REDALERT);
- BIF_ThemeColor(TH_REDALERT);
- }
- else {
- BIF_ThemeColor(curCol);
- }
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -585,56 +573,269 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockSetCol(block, TH_AUTO);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
+ if (proxy_protected) {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, *xco+244, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+ uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, *xco+262, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ else {
+ short prev_proxylock, show_upbut, show_downbut;
+
+ /* Up/Down buttons:
+ * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
+ * as that poses problems when restoring them, so disable the "up" button where
+ * it may cause this situation.
+ *
+ * Up/Down buttons should only be shown (or not greyed - todo) if they serve some purpose.
+ */
+ if (proxylocked_constraints_owner(ob, pchan)) {
+ if (con->prev) {
+ prev_proxylock= (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+ }
+ else
+ prev_proxylock= 0;
+ }
+ else
+ prev_proxylock= 0;
+
+ show_upbut= ((prev_proxylock == 0) && (con->prev));
+ show_downbut= (con->next) ? 1 : 0;
+
+ if (show_upbut || show_downbut) {
+ uiBlockBeginAlign(block);
+ uiBlockSetEmboss(block, UI_EMBOSS);
+
+ if (show_upbut) {
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
+ uiButSetFunc(but, constraint_moveUp, ob, con);
+ }
+
+ if (show_downbut) {
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
+ uiButSetFunc(but, constraint_moveDown, ob, con);
+ }
+ uiBlockEndAlign(block);
+ }
+
+
+ /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
+ uiButSetFunc(but, del_constraint_func, ob, con);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
- but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
- uiButSetFunc(but, del_constraint_func, ob, con);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
-
- /* Draw constraint data*/
- if (!(con->flag & CONSTRAINT_EXPAND)) {
- (*yco)-=21;
+ /* Set but-locks for protected settings (magic numbers are used here!) */
+ if (proxy_protected)
+ uiSetButLock(1, "Cannot edit Proxy-Protected Constraint");
+
+ /* Draw constraint data */
+ if ((con->flag & CONSTRAINT_EXPAND) == 0) {
+ (*yco) -= 21;
}
else {
- switch (con->type){
+ switch (con->type) {
+ case CONSTRAINT_TYPE_PYTHON:
+ {
+ bPythonConstraint *data = con->data;
+ bConstraintTarget *ct;
+ uiBut *but2;
+ int tarnum, theight;
+ static int pyconindex=0;
+ char *menustr;
+
+ theight = (data->tarnum)? (data->tarnum * 38) : (38);
+ height = theight + 78;
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40, height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Script:", *xco+60, *yco-24, 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* do the scripts menu */
+ menustr = buildmenu_pyconstraints(data->text, &pyconindex);
+ but2 = uiDefButI(block, MENU, B_CONSTRAINT_TEST, menustr,
+ *xco+120, *yco-24, 150, 20, &pyconindex,
+ 0, 0, 0, 0, "Set the Script Constraint to use");
+ uiButSetFunc(but2, validate_pyconstraint_cb, data, &pyconindex);
+ MEM_freeN(menustr);
+
+ /* draw target(s) */
+ if (data->flag & PYCON_USETARGETS) {
+ /* Draw target parameters */
+ for (ct=data->targets.first, tarnum=1; ct; ct=ct->next, tarnum++) {
+ char tarstr[32];
+ short yoffset= ((tarnum-1) * 38);
+
+ /* target label */
+ sprintf(tarstr, "Target %d:", tarnum);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* target space-selector - per target */
+ if (is_armature_target(ct->tar)) {
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
+ *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
+ }
+ else {
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1",
+ *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
+ }
+
+ uiBlockBeginAlign(block);
+ /* target object */
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-(48+yoffset), 150, 18, &ct->tar, "Target Object");
+
+ /* 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);
+ }
+ 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);
+ }
+ else {
+ strcpy(ct->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+ }
+ }
+ else {
+ /* Draw indication that no target needed */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+60, *yco-48, 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Not Applicable", *xco+120, *yco-48, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ }
+
+ /* settings */
+ uiBlockBeginAlign(block);
+ but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Options", *xco, *yco-(52+theight), (width/2),18, NULL, 0, 24, 0, 0, "Change some of the constraint's settings.");
+ uiButSetFunc(but, BPY_pyconstraint_settings, data, NULL);
+
+ but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Refresh", *xco+((width/2)+10), *yco-(52+theight), (width/2),18, NULL, 0, 24, 0, 0, "Force constraint to refresh it's settings");
+ uiBlockEndAlign(block);
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-(73+theight), is_armature_owner(ob), -1);
+ }
+ break;
case CONSTRAINT_TYPE_ACTION:
{
bActionConstraint *data = con->data;
-
- height = 88;
+ float minval, maxval;
+
+ height = 108;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target){
- but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
-
- /* Draw action button */
+
+ /* Draw action/type buttons */
uiBlockBeginAlign(block);
- uiDefButS(block, TOG, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-117), *yco-46, 78, 18, &data->local, 0, 0, 0, 0, "Use true local rotation difference");
- uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, B_CONSTRAINT_TEST, "AC:", *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone");
- uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-117), *yco-84, 78, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
-
+ uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, B_CONSTRAINT_TEST, "AC:", *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone");
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Key on%t|Loc X%x20|Loc Y%x21|Loc Z%x22|Rot X%x0|Rot Y%x1|Rot Z%x2|Size X%x10|Size Y%x11|Size Z%x12", *xco+((width/2)-117), *yco-84, 78, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
+ uiBlockEndAlign(block);
+
+ /* Draw start/end frame buttons */
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM, B_CONSTRAINT_TEST, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion");
+ uiDefButI(block, NUM, B_CONSTRAINT_TEST, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion");
+ uiBlockEndAlign(block);
+
+ /* Draw minimum/maximum transform range buttons */
uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_CONSTRAINT_TEST, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion");
- uiDefButI(block, NUM, B_CONSTRAINT_TEST, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion");
+ if (data->type < 10) { /* rotation */
+ minval = -180.0f;
+ maxval = 180.0f;
+ }
+ else if (data->type < 20) { /* scaling */
+ minval = 0.0001f;
+ maxval = 1000.0f;
+ }
+ else { /* location */
+ minval = -1000.0f;
+ maxval = 1000.0f;
+ }
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, minval, maxval, 0, 0, "Minimum value for target channel range");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, minval, maxval, 0, 0, "Maximum value for target channel range");
+ uiBlockEndAlign(block);
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-104, -1, is_armature_target(data->tar));
+ }
+ break;
+ case CONSTRAINT_TYPE_CHILDOF:
+ {
+ bChildOfConstraint *data = con->data;
+ short normButWidth = (width/3);
+
+ height = 165;
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Parent:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* Draw target parameters */
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object to use as Parent");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone to use as Parent");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+
+ /* Draw triples of channel toggles */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Use Channel(s):", *xco+65, *yco-64, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, CHILDOF_LOCX, B_CONSTRAINT_TEST, "Loc X", *xco, *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-location");
+ uiDefButBitI(block, TOG, CHILDOF_LOCY, B_CONSTRAINT_TEST, "Loc Y", *xco+normButWidth, *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-location");
+ uiDefButBitI(block, TOG, CHILDOF_LOCZ, B_CONSTRAINT_TEST, "Loc Z", *xco+(normButWidth * 2), *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-location");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, CHILDOF_ROTX, B_CONSTRAINT_TEST, "Rot X", *xco, *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-rotation");
+ uiDefButBitI(block, TOG, CHILDOF_ROTY, B_CONSTRAINT_TEST, "Rot Y", *xco+normButWidth, *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-rotation");
+ uiDefButBitI(block, TOG, CHILDOF_ROTZ, B_CONSTRAINT_TEST, "Rot Z", *xco+(normButWidth * 2), *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-rotation");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, CHILDOF_SIZEX, B_CONSTRAINT_TEST, "Scale X", *xco, *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-scaling");
+ uiDefButBitI(block, TOG, CHILDOF_SIZEY, B_CONSTRAINT_TEST, "Scale Y", *xco+normButWidth, *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-scaling");
+ uiDefButBitI(block, TOG, CHILDOF_SIZEZ, B_CONSTRAINT_TEST, "Scale Z", *xco+(normButWidth * 2), *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-scaling");
+ uiBlockEndAlign(block);
+
+ /* Inverse options */
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
+ but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Set Offset", *xco, *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Calculate current Parent-Inverse Matrix (i.e. restore offset from parent)");
+ uiButSetFunc(but, childof_const_setinv, con, NULL);
+
+ but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Clear Offset", *xco+((width/2)+10), *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Clear Parent-Inverse Matrix (i.e. clear offset from parent)");
+ uiButSetFunc(but, childof_const_clearinv, con, NULL);
uiBlockEndAlign(block);
}
break;
@@ -642,237 +843,325 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
{
bLocateLikeConstraint *data = con->data;
- height = 91;
+ height = 111;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
-
+
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
/* Draw XYZ toggles */
uiBlockBeginAlign(block);
- but=uiDefButBitI(block, TOG, LOCLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
- but=uiDefButBitI(block, TOG, LOCLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
- but=uiDefButBitI(block, TOG, LOCLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
- but=uiDefButBitI(block, TOG, LOCLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
- but=uiDefButBitI(block, TOG, LOCLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
- but=uiDefButBitI(block, TOG, LOCLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
+ uiDefButBitI(block, TOG, LOCLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
+ uiDefButBitI(block, TOG, LOCLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
+ uiDefButBitI(block, TOG, LOCLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
+ uiDefButBitI(block, TOG, LOCLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
+ uiDefButBitI(block, TOG, LOCLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+ uiDefButBitI(block, TOG, LOCLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
uiBlockEndAlign(block);
/* Draw options */
- uiDefButBitI(block, TOG, LOCLIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco+(width/3), *yco-89, (width/3), 18, &data->flag, 0, 24, 0, 0, "Add original location onto copied location");
- if (is_armature_target) {
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco, *yco-89, (width/3), 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
- uiDefButBitI(block, TOG, LOCLIKE_TIP, B_CONSTRAINT_TEST, "Target Bone Tip", *xco+(width/3*2), *yco-89, (width/3), 18, &data->flag, 0, 24, 0, 0, "Copy Location of Target Bone's Tip");
+ uiDefButBitI(block, TOG, LOCLIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-89, (width/2), 18, &data->flag, 0, 24, 0, 0, "Add original location onto copied location");
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+(width/2), *yco-89, (width/2), 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
}
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-109, is_armature_owner(ob), is_armature_target(data->tar));
}
break;
case CONSTRAINT_TYPE_ROTLIKE:
{
bRotateLikeConstraint *data = con->data;
- height = 91;
+ height = 101;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
/* Draw XYZ toggles */
uiBlockBeginAlign(block);
- if (is_armature_target)
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-98), *yco-64, 50, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
- but=uiDefButBitI(block, TOG, ROTLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
- but=uiDefButBitI(block, TOG, ROTLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
- but=uiDefButBitI(block, TOG, ROTLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
- but=uiDefButBitI(block, TOG, ROTLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
- but=uiDefButBitI(block, TOG, ROTLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
- but=uiDefButBitI(block, TOG, ROTLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
+ uiDefButBitI(block, TOG, ROTLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
+ uiDefButBitI(block, TOG, ROTLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
+ uiDefButBitI(block, TOG, ROTLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
+ uiDefButBitI(block, TOG, ROTLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
+ uiDefButBitI(block, TOG, ROTLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+ uiDefButBitI(block, TOG, ROTLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
uiBlockEndAlign(block);
+
+ /* draw offset toggle */
+ uiDefButBitI(block, TOG, ROTLIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-64, 80, 18, &data->flag, 0, 24, 0, 0, "Add original rotation onto copied rotation");
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
}
break;
case CONSTRAINT_TYPE_SIZELIKE:
{
bSizeLikeConstraint *data = con->data;
- height = 91;
-
+
+ height = 101;
+
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
-
+
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
-
+
/* Draw XYZ toggles */
uiBlockBeginAlign(block);
- if (is_armature_target)
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-98), *yco-64, 50, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
- but=uiDefButBitI(block, TOG, SIZELIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
- but=uiDefButBitI(block, TOG, SIZELIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
- but=uiDefButBitI(block, TOG, SIZELIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+ uiDefButBitI(block, TOG, SIZELIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
+ uiDefButBitI(block, TOG, SIZELIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
+ uiDefButBitI(block, TOG, SIZELIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
uiBlockEndAlign(block);
+
+ /* draw offset toggle */
+ uiDefButBitI(block, TOG, SIZELIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-64, 80, 18, &data->flag, 0, 24, 0, 0, "Add original scaling onto copied scaling");
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
}
break;
case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data = con->data;
- height = 111;
+ height = 146;
+ if(data->poletar)
+ height += 30;
+
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- /* Draw target parameters */
- uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco, *yco-24,60,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
+ /* IK Target */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ /* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 19, &data->tar, "Target Object");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco, *yco-44, 137, 19, &data->tar, "Target Object");
- if (is_armature_target) {
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco, *yco-62,137,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
}
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco, *yco-62,137,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
else {
strcpy (data->subtarget, "");
}
-
+
+ uiBlockEndAlign(block);
+
+ /* Settings */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco, *yco-64, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
- uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-84,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
+ uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tail", *xco, *yco-92, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tail als last element in Chain");
+ uiDefButS(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-112,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-64, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
- uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+147, *yco-84, 137, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
-
+ uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-92, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
+ uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco+147, *yco-112, 40,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
+ uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "W ", *xco+187, *yco-112, 97, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
+
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco, *yco-109, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
+
+ uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco, *yco-137,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco+147, *yco-109,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
+ uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+147, *yco-137, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
+ uiBlockEndAlign(block);
+
+ /* Pole Vector */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Pole Target:", *xco+147, *yco-24, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+147, *yco-44, 137, 19, &data->poletar, "Pole Target Object");
+ if (is_armature_target(data->poletar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+147, *yco-62,137,19, &data->polesubtarget, 0, 24, 0, 0, "Pole Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->poletar);
+ }
+ else if (is_geom_target(data->poletar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+147, *yco-62,137,18, &data->polesubtarget, 0, 24, 0, 0, "Name of Vertex Group defining pole 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->poletar);
+ }
+ else {
+ strcpy (data->polesubtarget, "");
+ }
+
+ if(data->poletar) {
+ uiBlockBeginAlign(block);
+#if 0
+ but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, (data->flag & CONSTRAINT_IK_SETANGLE)? "Set Pole Offset": "Clear Pole Offset", *xco, *yco-167, 137, 19, 0, 0.0, 1.0, 0.0, 0.0, "Set the pole rotation offset from the current pose");
+ uiButSetFunc(but, con_kinematic_set_pole_angle, ob, con);
+ if(!(data->flag & CONSTRAINT_IK_SETANGLE))
+#endif
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pole Offset ", *xco, *yco-167, 137, 19, &data->poleangle, -180.0, 180.0, 0, 0, "Pole rotation offset");
+ }
}
break;
case CONSTRAINT_TYPE_TRACKTO:
{
bTrackToConstraint *data = con->data;
-
- height = 66;
+
+ if (is_armature_target(data->tar))
+ height = 118;
+ else
+ height = 96;
+
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Align:", *xco+5, *yco-42, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "TargetZ", *xco+60, *yco-42, 50, 18, &data->flags, 0, 1, 0, 0, "Target Z axis, not world Z axis, will constrain up direction");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Align:", *xco+5, *yco-42, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "TargetZ", *xco+60, *yco-42, 50, 18, &data->flags, 0, 1, 0, 0, "Target Z axis, not world Z axis, will constrain up direction");
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "X axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->reserved1, 12.0, 1.0, 0, 0, "Y axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->reserved1, 12.0, 2.0, 0, 0, "Z axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "-X axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "X axis points to the target object");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->reserved1, 12.0, 1.0, 0, 0, "Y axis points to the target object");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->reserved1, 12.0, 2.0, 0, 0, "Z axis points to the target object");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "-X axis points to the target object");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->reserved2, 13.0, 0.0, 0, 0, "X axis points upward");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->reserved2, 13.0, 1.0, 0, 0, "Y axis points upward");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->reserved2, 13.0, 2.0, 0, 0, "Z axis points upward");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->reserved2, 13.0, 0.0, 0, 0, "X axis points upward");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->reserved2, 13.0, 1.0, 0, 0, "Y axis points upward");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->reserved2, 13.0, 2.0, 0, 0, "Z axis points upward");
uiBlockEndAlign(block);
+
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco, *yco-94, 241, 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-116, is_armature_owner(ob), is_armature_target(data->tar));
+ }
+ else {
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
+ }
}
break;
case CONSTRAINT_TYPE_MINMAX:
{
bMinMaxConstraint *data = con->data;
-
- height = 66;
+
+ if (is_armature_target(data->tar))
+ height = 88;
+ else
+ height = 66;
+
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Offset:", *xco, *yco-44, 100, 18, &data->offset, -100, 100, 100.0, 0.0, "Offset from the position of the object center");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
-
- but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 44, 18, &data->flag, 0, 24, 0, 0, "Immobilize object while constrained");
- but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Use Rot", *xco+44, *yco-24, 64, 18, &data->flag, 0, 24, 0, 0, "Use target object rotation");
+
+ uiDefButBitI(block, TOG, MINMAX_STICKY, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 44, 18, &data->flag, 0, 24, 0, 0, "Immobilize object while constrained");
+ uiDefButBitI(block, TOG, MINMAX_USEROT, B_CONSTRAINT_TEST, "Use Rot", *xco+44, *yco-24, 64, 18, &data->flag, 0, 24, 0, 0, "Use target object rotation");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Max/Min:", *xco-8, *yco-64, 54, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
uiBlockBeginAlign(block);
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+51, *yco-64,17,18, &data->minmaxflag, 12.0, 0.0, 0, 0, "Will not pass below X of target");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+67, *yco-64,17,18, &data->minmaxflag, 12.0, 1.0, 0, 0, "Will not pass below Y of target");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+85, *yco-64,17,18, &data->minmaxflag, 12.0, 2.0, 0, 0, "Will not pass below Z of target");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+102, *yco-64,24,18, &data->minmaxflag, 12.0, 3.0, 0, 0, "Will not pass above X of target");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+126, *yco-64,24,18, &data->minmaxflag, 12.0, 4.0, 0, 0, "Will not pass above Y of target");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+150, *yco-64,24,18, &data->minmaxflag, 12.0, 5.0, 0, 0, "Will not pass above Z of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X", *xco+51, *yco-64,17,18, &data->minmaxflag, 12.0, 0.0, 0, 0, "Will not pass below X of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y", *xco+67, *yco-64,17,18, &data->minmaxflag, 12.0, 1.0, 0, 0, "Will not pass below Y of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z", *xco+85, *yco-64,17,18, &data->minmaxflag, 12.0, 2.0, 0, 0, "Will not pass below Z of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-X", *xco+102, *yco-64,24,18, &data->minmaxflag, 12.0, 3.0, 0, 0, "Will not pass above X of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Y", *xco+126, *yco-64,24,18, &data->minmaxflag, 12.0, 4.0, 0, 0, "Will not pass above Y of target");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Z", *xco+150, *yco-64,24,18, &data->minmaxflag, 12.0, 5.0, 0, 0, "Will not pass above Z of target");
uiBlockEndAlign(block);
+
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco, *yco-86, 241, 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+ }
+
}
break;
case CONSTRAINT_TYPE_LOCKTRACK:
@@ -880,78 +1169,81 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bLockTrackConstraint *data = con->data;
height = 66;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
-
+
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "X axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "Y axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "Z axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "-X axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "X axis points to the target object");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "Y axis points to the target object");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "Z axis points to the target object");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "-X axis points to the target object");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->lockflag, 13.0, 0.0, 0, 0, "X axis is locked");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->lockflag, 13.0, 1.0, 0, 0, "Y axis is locked");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->lockflag, 13.0, 2.0, 0, 0, "Z axis is locked");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->lockflag, 13.0, 0.0, 0, 0, "X axis is locked");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->lockflag, 13.0, 1.0, 0, 0, "Y axis is locked");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->lockflag, 13.0, 2.0, 0, 0, "Z axis is locked");
uiBlockEndAlign(block);
}
break;
case CONSTRAINT_TYPE_FOLLOWPATH:
{
bFollowPathConstraint *data = con->data;
-
+
height = 66;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
/* Draw Curve Follow toggle */
- but=uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "CurveFollow", *xco+39, *yco-44, 100, 18, &data->followflag, 0, 24, 0, 0, "Object will follow the heading and banking of the curve");
-
+ uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "CurveFollow", *xco+39, *yco-44, 100, 18, &data->followflag, 0, 24, 0, 0, "Object will follow the heading and banking of the curve");
+
/* Draw Offset number button */
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Offset:", *xco+155, *yco-44, 100, 18, &data->offset, -MAXFRAMEF, MAXFRAMEF, 100.0, 0.0, "Offset from the position corresponding to the time frame");
-
+
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points forward along the path");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points forward along the path");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points forward along the path");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points forward along the path");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points forward along the path");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points forward along the path");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X", *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points forward along the path");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y", *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points forward along the path");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z", *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points forward along the path");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-X", *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points forward along the path");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Y", *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points forward along the path");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Z", *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points forward along the path");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->upflag, 13.0, 0.0, 0, 0, "The axis that points upward");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->upflag, 13.0, 1.0, 0, 0, "The axis that points upward");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->upflag, 13.0, 2.0, 0, 0, "The axis that points upward");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X", *xco+204, *yco-64,17,18, &data->upflag, 13.0, 0.0, 0, 0, "The axis that points upward");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y", *xco+221, *yco-64,17,18, &data->upflag, 13.0, 1.0, 0, 0, "The axis that points upward");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z", *xco+238, *yco-64,17,18, &data->upflag, 13.0, 2.0, 0, 0, "The axis that points upward");
uiBlockEndAlign(block);
}
break;
@@ -963,42 +1255,50 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
-
- if (is_armature_target) {
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
- uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
- }
- else {
- strcpy (data->subtarget, "");
- }
-
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
uiBlockEndAlign(block);
-
uiBlockBeginAlign(block);
- uiDefButF(block,BUTM,B_CONSTRAINT_TEST,"R",*xco, *yco-60,20,18,&(data->orglength),0.0,0,0,0,"Recalculate RLength");
- uiDefButF(block,NUM,B_CONSTRAINT_TEST,"Rest Length:",*xco+18, *yco-60,237,18,&(data->orglength),0.0,100,0.5,0.5,"Length at Rest Position");
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->orglength, 0.0, 0, 0, 0, "Recalculate RLength");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Rest Length:", *xco+18, *yco-60,139,18, &data->orglength, 0.0, 100, 0.5, 0.5, "Length at Rest Position");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,98,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+ }
+ else {
+ uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->orglength, 0.0, 0, 0, 0, "Recalculate RLength");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Rest Length:", *xco+18, *yco-60, 237, 18, &data->orglength, 0.0, 100, 0.5, 0.5, "Length at Rest Position");
+ }
uiBlockEndAlign(block);
-
- uiDefButF(block,NUM,B_CONSTRAINT_TEST,"Volume Variation:",*xco+18, *yco-82,237,18,&(data->bulge),0.0,100,0.5,0.5,"Factor between volume variation and stretching");
-
+
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Volume Variation:", *xco+18, *yco-82, 237, 18, &data->bulge, 0.0, 100, 0.5, 0.5, "Factor between volume variation and stretching");
+
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+14, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"XZ", *xco+44, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+74, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+94, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"NONE", *xco+114, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+14, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"XZ", *xco+44, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+74, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+94, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"NONE", *xco+114, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
uiBlockEndAlign(block);
-
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+175, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+215, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
- uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+235, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+175, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X", *xco+215, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
+ uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z", *xco+235, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
uiBlockEndAlign(block);
}
break;
@@ -1009,51 +1309,45 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
int togButWidth = 50;
int textButWidth = ((width/2)-togButWidth);
- height = 106;
+ height = 136;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), -1000, 1000, 0.1,0.5,"Lowest x value to allow");
+ uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), -1000, 1000, 0.1,0.5,"Lowest x value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), -1000, 1000, 0.1,0.5,"Highest x value to allow");
+ uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), -1000, 1000, 0.1,0.5,"Highest x value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), -1000, 1000, 0.1,0.5,"Lowest y value to allow");
+ uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), -1000, 1000, 0.1,0.5,"Lowest y value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), -1000, 1000, 0.1,0.5,"Highest y value to allow");
+ uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), -1000, 1000, 0.1,0.5,"Highest y value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), -1000, 1000, 0.1,0.5,"Lowest z value to allow");
+ uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), -1000, 1000, 0.1,0.5,"Lowest z value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), -1000, 1000, 0.1,0.5,"Highest z value to allow");
+ uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), -1000, 1000, 0.1,0.5,"Highest z value to allow");
uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Co-ordinate Space:",*xco, *yco-100,150,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- if (ob->type == OB_ARMATURE && (ob->flag & OB_POSEMODE))
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &con->flag, 0, 24, 0, 0, "Limit locations relative to the bone's rest-position");
- else if (ob->parent != NULL)
- uiDefButBitS(block, TOG, LIMIT_NOPARENT, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &data->flag2, 0, 24, 0, 0, "Limit locations relative to parent, not origin/world");
- else
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"World",*xco+160, *yco-100,60,18, NULL, 0.0, 0.0, 0.0, 0.0, "Limit locations relative to origin/world");
+ /* special option(s) */
+ uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well");
- uiBlockEndAlign(block);
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
}
break;
case CONSTRAINT_TYPE_ROTLIMIT:
@@ -1061,38 +1355,34 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bRotLimitConstraint *data = con->data;
int normButWidth = (width/3);
- if (ob->type == OB_ARMATURE && (ob->flag & OB_POSEMODE))
- height = 106;
- else
- height = 78;
+ height = 136;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_XROT, B_CONSTRAINT_TEST, "LimitX", *xco, *yco-28, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on x-axis");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-28, normButWidth, 18, &(data->xmin), -360, 360, 0.1,0.5,"Lowest x value to allow");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-28, normButWidth, 18, &(data->xmax), -360, 360, 0.1,0.5,"Highest x value to allow");
+ uiDefButBitS(block, TOG, LIMIT_XROT, B_CONSTRAINT_TEST, "LimitX", *xco, *yco-28, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on x-axis");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-28, normButWidth, 18, &(data->xmin), -360, 360, 0.1,0.5,"Lowest x value to allow");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-28, normButWidth, 18, &(data->xmax), -360, 360, 0.1,0.5,"Highest x value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_YROT, B_CONSTRAINT_TEST, "LimitY", *xco, *yco-50, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on y-axis");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-50, normButWidth, 18, &(data->ymin), -360, 360, 0.1,0.5,"Lowest y value to allow");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-50, normButWidth, 18, &(data->ymax), -360, 360, 0.1,0.5,"Highest y value to allow");
+ uiDefButBitS(block, TOG, LIMIT_YROT, B_CONSTRAINT_TEST, "LimitY", *xco, *yco-50, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on y-axis");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-50, normButWidth, 18, &(data->ymin), -360, 360, 0.1,0.5,"Lowest y value to allow");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-50, normButWidth, 18, &(data->ymax), -360, 360, 0.1,0.5,"Highest y value to allow");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_ZROT, B_CONSTRAINT_TEST, "LimitZ", *xco, *yco-72, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on z-axis");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-72, normButWidth, 18, &(data->zmin), -360, 360, 0.1,0.5,"Lowest z value to allow");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-72, normButWidth, 18, &(data->zmax), -360, 360, 0.1,0.5,"Highest z value to allow");
+ uiDefButBitS(block, TOG, LIMIT_ZROT, B_CONSTRAINT_TEST, "LimitZ", *xco, *yco-72, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on z-axis");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-72, normButWidth, 18, &(data->zmin), -360, 360, 0.1,0.5,"Lowest z value to allow");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-72, normButWidth, 18, &(data->zmax), -360, 360, 0.1,0.5,"Highest z value to allow");
uiBlockEndAlign(block);
- if (ob->type == OB_ARMATURE && (ob->flag & OB_POSEMODE)) {
- uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Co-ordinate Space:",*xco, *yco-100,150,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
- uiBlockEndAlign(block);
- }
+ /* special option(s) */
+ uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well");
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
}
break;
case CONSTRAINT_TYPE_SIZELIMIT:
@@ -1102,52 +1392,96 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
int togButWidth = 50;
int textButWidth = ((width/2)-togButWidth);
- if (ob->type == OB_ARMATURE && (ob->flag & OB_POSEMODE))
- height = 106;
- else
- height = 78;
+ height = 136;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), 0.0001, 1000, 0.1,0.5,"Lowest x value to allow");
+ uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), 0.0001, 1000, 0.1,0.5,"Lowest x value to allow");
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), 0.0001, 1000, 0.1,0.5,"Highest x value to allow");
+ uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), 0.0001, 1000, 0.1,0.5,"Highest x value to allow");
uiBlockEndAlign(block);
-
-
+
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), 0.0001, 1000, 0.1,0.5,"Lowest y value to allow");
+ uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), 0.0001, 1000, 0.1,0.5,"Lowest y value to allow");
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), 0.0001, 1000, 0.1,0.5,"Highest y value to allow");
+ uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), 0.0001, 1000, 0.1,0.5,"Highest y value to allow");
uiBlockEndAlign(block);
-
-
+
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), 0.0001, 1000, 0.1,0.5,"Lowest z value to allow");
+ uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), 0.0001, 1000, 0.1,0.5,"Lowest z value to allow");
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), 0.0001, 1000, 0.1,0.5,"Highest z value to allow");
+ uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), 0.0001, 1000, 0.1,0.5,"Highest z value to allow");
uiBlockEndAlign(block);
- if (ob->type == OB_ARMATURE && (ob->flag & OB_POSEMODE)) {
- uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Co-ordinate Space:",*xco, *yco-100,150,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+160, *yco-100, 60, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
- uiBlockEndAlign(block);
- }
+ /* special option(s) */
+ uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well");
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
+ }
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = con->data;
+
+ height = 105;
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* Draw target parameters */
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60,139,18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,100,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+ }
+ else {
+ uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60, 237, 18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ }
+
+ /* disabled soft-distance controls... currently it doesn't work yet. It was intended to be used for soft-ik (see xsi-blog for details) */
+#if 0
+ uiDefButBitS(block, TOG, LIMITDIST_USESOFT, B_CONSTRAINT_TEST, "Soft", *xco, *yco-82, 50, 18, &data->flag, 0, 24, 0, 0, "Enables soft-distance");
+ if (data->flag & LIMITDIST_USESOFT)
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Soft-Distance:", *xco+50, *yco-82, 187, 18, &data->soft, 0.0, 100, 0.5, 0.5, "Distance surrounding radius when transforms should get 'delayed'");
+#endif
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Limit Mode%t|Inside %x0|Outside %x1|Surface %x2", *xco+((width/2)-50), *yco-104, 100, 18, &data->mode, 0, 24, 0, 0, "Distances in relation to sphere of influence to allow");
}
break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
@@ -1160,18 +1494,20 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
int togButWidth = 70;
int offsetY = 150;
int textButWidth = ((width/2)-togButWidth);
-
- uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Generic (experimental)%x12",//|Extra Force%x6",
+
+ uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Cone Twist%x4|Generic (experimental)%x12",//|Extra Force%x6",
*xco, *yco-25, 150, 18, &data->type, 0, 0, 0, 0, "Choose the joint type");
height = 140;
if (data->type==CONSTRAINT_RB_GENERIC6DOF)
height = 270;
+ if (data->type==CONSTRAINT_RB_CONETWIST)
+ height = 200;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
-
+
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "toObject:", *xco, *yco-50, 130, 18, &data->tar, "Child Object");
uiDefButBitS(block, TOG, CONSTRAINT_DRAW_PIVOT, B_CONSTRAINT_TEST, "ShowPivot", *xco+135, *yco-50, 130, 18, &data->flag, 0, 24, 0, 0, "Show pivot position and rotation");
-
+
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot X:", *xco, *yco-75, 130, 18, &data->pivX, -1000, 1000, 100, 0.0, "Offset pivot on X");
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Y:", *xco, *yco-100, 130, 18, &data->pivY, -1000, 1000, 100, 0.0, "Offset pivot on Y");
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Z:", *xco, *yco-125, 130, 18, &data->pivZ, -1000, 1000, 100, 0.0, "Offset pivot on z");
@@ -1180,60 +1516,72 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Y:", *xco+135, *yco-100, 130, 18, &data->axY, -360, 360, 1500, 0.0, "Rotate pivot on Y Axis (in degrees)");
uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Z:", *xco+135, *yco-125, 130, 18, &data->axZ, -360, 360, 1500, 0.0, "Rotate pivot on Z Axis (in degrees)");
- if (data->type==CONSTRAINT_RB_GENERIC6DOF){
+ if (data->type==CONSTRAINT_RB_GENERIC6DOF) {
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"min x limit");
-
+ uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"min x limit");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"max x limit");
-
+ uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"max x limit");
+ uiBlockEndAlign(block);
+
offsetY += 20;
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"min y limit");
-
+ uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"min y limit");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"max y limit");
-
+ uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"max y limit");
+ uiBlockEndAlign(block);
+
offsetY += 20;
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"min z limit");
-
+ uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"min z limit");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"max z limit");
+ uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"max z limit");
+ uiBlockEndAlign(block);
offsetY += 20;
-
+ }
+ if ((data->type==CONSTRAINT_RB_GENERIC6DOF) || (data->type==CONSTRAINT_RB_CONETWIST)) {
/* Draw Pairs of LimitToggle+LimitValue */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"min x limit");
+ uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"min x limit");
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"max x limit");
-
+ uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"max x limit");
+ uiBlockEndAlign(block);
+
offsetY += 20;
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"min y limit");
-
+ uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"min y limit");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"max y limit");
-
+ uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"max y limit");
+ uiBlockEndAlign(block);
+
offsetY += 20;
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"min z limit");
-
+ uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"min z limit");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit");
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"max z limit");
+ uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"max z limit");
uiBlockEndAlign(block);
}
}
@@ -1242,40 +1590,165 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
{
bClampToConstraint *data = con->data;
- height = 66;
+ height = 90;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
+
/* Draw target parameters */
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
/* Draw XYZ toggles */
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Main Axis:", *xco, *yco-64, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Auto", *xco+100, *yco-64, 50, 18, &data->flag, 12.0, CLAMPTO_AUTO, 0, 0, "Automatically determine main-axis of movement");
- uiDefButI(block, ROW, B_CONSTRAINT_TEST, "X", *xco+150, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_X, 0, 0, "Main axis of movement is x-axis");
- uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Y", *xco+182, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Y, 0, 0, "Main axis of movement is y-axis");
- uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Z", *xco+214, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Z, 0, 0, "Main axis of movement is z-axis");
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Main Axis:", *xco, *yco-64, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Auto", *xco+100, *yco-64, 50, 18, &data->flag, 12.0, CLAMPTO_AUTO, 0, 0, "Automatically determine main-axis of movement");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST, "X", *xco+150, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_X, 0, 0, "Main axis of movement is x-axis");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Y", *xco+182, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Y, 0, 0, "Main axis of movement is y-axis");
+ uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Z", *xco+214, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Z, 0, 0, "Main axis of movement is z-axis");
+ uiBlockEndAlign(block);
+
+ /* Extra Options Controlling Behaviour */
+ //uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Options:", *xco, *yco-88, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButBitI(block, TOG, CLAMPTO_CYCLIC, B_CONSTRAINT_TEST, "Cyclic", *xco+((width/2)), *yco-88,60,19, &data->flag2, 0, 0, 0, 0, "Treat curve as cyclic curve (no clamping to curve bounding box)");
+ //uiBlockEndAlign(block);
+ }
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ {
+ bTransformConstraint *data = con->data;
+ float fmin, fmax, tmin, tmax;
+
+ height = 178;
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+
+ /* Draw target parameters */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* Draw target parameters */
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object to use as Parent");
+
+ if (is_armature_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone to use as Parent");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+
+ /* Extrapolate Ranges? */
+ uiDefButBitC(block, TOG, 1, B_CONSTRAINT_TEST, "Extrapolate", *xco, *yco-42,80,19, &data->expo, 0, 0, 0, 0, "Extrapolate ranges");
+
+ /* Draw options for source motion */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Source:", *xco-10, *yco-62, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* draw Loc/Rot/Size toggles */
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco-5, *yco-82, 45, 18, &data->from, 12.0, 0, 0, 0, "Use Location transform channels from Target");
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+40, *yco-82, 45, 18, &data->from, 12.0, 1, 0, 0, "Use Rotation transform channels from Target");
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+85, *yco-82, 45, 18, &data->from, 12.0, 2, 0, 0, "Use Scale transform channels from Target");
+ uiBlockEndAlign(block);
+
+ /* Draw Pairs of Axis: Min/Max Value*/
+ if (data->from == 2) {
+ fmin= 0.0001;
+ fmax= 1000.0;
+ }
+ else if (data->from == 1) {
+ fmin= -360.0;
+ fmax= 360.0;
+ }
+ else {
+ fmin = -1000.0;
+ fmax= 1000.0;
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "X:", *xco-10, *yco-107, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-107, 55, 18, &data->from_min[0], fmin, fmax, 0, 0, "Bottom of range of x-axis source motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-107, 55, 18, &data->from_max[0], fmin, fmax, 0, 0, "Top of range of x-axis source motion for source->target mapping");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Y:", *xco-10, *yco-127, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-127, 55, 18, &data->from_min[1], fmin, fmax, 0, 0, "Bottom of range of y-axis source motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-127, 55, 18, &data->from_max[1], fmin, fmax, 0, 0, "Top of range of y-axis source motion for source->target mapping");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Z:", *xco-10, *yco-147, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-147, 55, 18, &data->from_min[2], fmin, fmax, 0, 0, "Bottom of range of z-axis source motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-147, 55, 18, &data->from_max[2], fmin, fmax, 0, 0, "Top of range of z-axis source motion for source->target mapping");
+ uiBlockEndAlign(block);
+
+
+ /* Draw options for target motion */
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Destination:", *xco+150, *yco-62, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* draw Loc/Rot/Size toggles */
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco+150, *yco-82, 45, 18, &data->to, 12.0, 0, 0, 0, "Use as Location transform");
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+195, *yco-82, 45, 18, &data->to, 12.0, 1, 0, 0, "Use as Rotation transform");
+ uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+245, *yco-82, 45, 18, &data->to, 12.0, 2, 0, 0, "Use as Scale transform");
+ uiBlockEndAlign(block);
+
+ /* Draw Pairs of Source-Axis: Min/Max Value*/
+ if (data->to == 2) {
+ tmin= 0.0001;
+ tmax= 1000.0;
+ }
+ else if (data->to == 1) {
+ tmin= -360.0;
+ tmax= 360.0;
+ }
+ else {
+ tmin = -1000.0;
+ tmax= 1000.0;
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->X%x0|Y->X%x1|Z->X%x2", *xco+150, *yco-107, 40, 18, &data->map[0], 0, 24, 0, 0, "Specify which source axis the x-axis destination uses");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-107, 50, 18, &data->to_min[0], tmin, tmax, 0, 0, "Bottom of range of x-axis destination motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-107, 50, 18, &data->to_max[0], tmin, tmax, 0, 0, "Top of range of x-axis destination motion for source->target mapping");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Y%x0|Y->Y%x1|Z->Y%x2", *xco+150, *yco-127, 40, 18, &data->map[1], 0, 24, 0, 0, "Specify which source axis the y-axis destination uses");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-127, 50, 18, &data->to_min[1], tmin, tmax, 0, 0, "Bottom of range of y-axis destination motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-127, 50, 18, &data->to_max[1], tmin, tmax, 0, 0, "Top of range of y-axis destination motion for source->target mapping");
uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Z%x0|Y->Z%x1|Z->Z%x2", *xco+150, *yco-147, 40, 18, &data->map[2], 0, 24, 0, 0, "Specify which source axis the z-axis destination uses");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-147, 50, 18, &data->to_min[2], tmin, tmax, 0, 0, "Bottom of range of z-axis destination motion for source->target mapping");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-147, 50, 18, &data->to_max[2], tmin, tmax, 0, 0, "Top of range of z-axis destination motion for source->target mapping");
+ uiBlockEndAlign(block);
+
+ /* constraint space settings */
+ draw_constraint_spaceselect(block, con, *xco, *yco-170, is_armature_owner(ob), is_armature_target(data->tar));
}
break;
case CONSTRAINT_TYPE_NULL:
{
height = 17;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
-
}
break;
default:
height = 0;
break;
}
-
+
(*yco)-=(24+height);
}
- if ((con->type != CONSTRAINT_TYPE_NULL) && (con->type!=CONSTRAINT_TYPE_RIGIDBODYJOINT)) {
+ if (ELEM(con->type, CONSTRAINT_TYPE_NULL, CONSTRAINT_TYPE_RIGIDBODYJOINT)==0) {
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_CONSTRAINT_INF, "Influence ", *xco, *yco, 197, 20, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Show", *xco+200, *yco, 45, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show constraint's ipo in the Ipo window, adds a channel if not there");
@@ -1290,6 +1763,9 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
else {
(*yco)-=3;
}
+
+ /* clear any locks set up for proxies/lib-linking */
+ uiClearButLock();
}
static uiBlock *add_constraintmenu(void *arg_unused)
@@ -1303,40 +1779,51 @@ static uiBlock *add_constraintmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE,"Copy Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CHILDOF, "Child Of", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRANSFORM, "Transformation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT,"Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT,"Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT,"Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE, "Copy Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE, "Copy Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE, "Copy Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX,"Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CLAMPTO,"Clamp To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT, "Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT, "Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT, "Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_DISTLIMIT, "Limit Distance", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO, "Track To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX, "Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK, "Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, "Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CLAMPTO, "Clamp To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO, "Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT,"Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT, "Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
if (ob->flag & OB_POSEMODE) {
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC,"IK Solver", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
-
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC, "IK Solver", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
}
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION, "Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_PYTHON, "Script", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL, "Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+
uiTextBoundsBlock(block, 50);
uiBlockSetDirection(block, UI_DOWN);
@@ -1347,173 +1834,205 @@ static uiBlock *add_constraintmenu(void *arg_unused)
void do_constraintbuts(unsigned short event)
{
Object *ob= OBACT;
+ bConstraint *con;
switch(event) {
case B_CONSTRAINT_TEST:
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
break; // no handling
case B_CONSTRAINT_INF:
/* influence; do not execute actions for 1 dag_flush */
- if(ob->pose)
+ if (ob->pose)
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
case B_CONSTRAINT_CHANGETARGET:
- if(ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
+ if (ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
DAG_scene_sort(G.scene);
break;
-
+
case B_CONSTRAINT_ADD_NULL:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_NULL);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
- case B_CONSTRAINT_ADD_KINEMATIC:
+ case B_CONSTRAINT_ADD_PYTHON:
{
- bConstraint *con;
+ con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
+ add_constraint_to_active(ob, con);
+ BIF_undo_push("Add constraint");
+ }
+ break;
+ case B_CONSTRAINT_ADD_KINEMATIC:
+ {
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
add_constraint_to_active(ob, con);
-
+
+ BIF_undo_push("Add constraint");
+ }
+ break;
+ case B_CONSTRAINT_ADD_CHILDOF:
+ {
+ con= add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
+ add_constraint_to_active(ob, con);
+
+ /* if this constraint is being added to a posechannel, make sure
+ * the constraint gets evaluated in pose-space
+ */
+ if (ob->flag & OB_POSEMODE) {
+ con->ownspace = CONSTRAINT_SPACE_POSE;
+ con->flag |= CONSTRAINT_SPACEONCE;
+ }
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_TRACKTO:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_MINMAX:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_ROTLIKE:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_LOCLIKE:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_SIZELIKE:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_ACTION:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_LOCKTRACK:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_FOLLOWPATH:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
add_constraint_to_active(ob, con);
-
+
+ BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_STRETCHTO:
{
- bConstraint *con;
con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_LOCLIMIT:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_ROTLIMIT:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_SIZELIMIT:
{
- bConstraint *con;
-
con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
add_constraint_to_active(ob, con);
-
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_RIGIDBODYJOINT:
{
- bConstraint *con;
+ bRigidBodyJointConstraint *data;
+ Base *base_iter;
+
con = add_new_constraint(CONSTRAINT_TYPE_RIGIDBODYJOINT);
add_constraint_to_active(ob, con);
-
+
+ /* set selected first object as target - moved from new_constraint_data */
+ data = (bRigidBodyJointConstraint*)con->data;
+ base_iter = G.scene->base.first;
+ while ( base_iter && !data->tar ) {
+ if( ( ( base_iter->flag & SELECT ) &&
+// ( base_iter->lay & G.vd->lay ) ) &&
+ ( base_iter != G.scene->basact ) ))
+ {
+ data->tar=base_iter->object;
+ break;
+ }
+ base_iter = base_iter->next;
+ }
+
BIF_undo_push("Add constraint");
}
break;
case B_CONSTRAINT_ADD_CLAMPTO:
{
- bConstraint *con;
con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
add_constraint_to_active(ob, con);
-
+
+ BIF_undo_push("Add constraint");
+ }
+ break;
+ case B_CONSTRAINT_ADD_TRANSFORM:
+ {
+ con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
+ add_constraint_to_active(ob, con);
+
+ BIF_undo_push("Add constraint");
+ }
+ break;
+ case B_CONSTRAINT_ADD_DISTLIMIT:
+ {
+ con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
+ add_constraint_to_active(ob, con);
+
BIF_undo_push("Add constraint");
}
break;
@@ -1705,7 +2224,7 @@ void do_object_panels(unsigned short event)
case B_DUPLI_VERTS:
ob->transflag &= ~(OB_DUPLIFRAMES|OB_DUPLIFACES|OB_DUPLIGROUP);
DAG_scene_sort(G.scene);
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
break;
@@ -1756,9 +2275,16 @@ void do_object_panels(unsigned short event)
break;
case B_SOFTBODY_CHANGE:
- ob->softflag |= OB_SB_REDO;
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWVIEW3D, 0);
+ ob= OBACT;
+ if(ob) {
+ ParticleSystem *psys = PE_get_current(ob);
+ if(psys)
+ psys->softflag |= OB_SB_REDO;
+ else
+ ob->softflag |= OB_SB_REDO;
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
break;
case B_SOFTBODY_DEL_VG:
if(ob->soft) {
@@ -1821,6 +2347,86 @@ void do_object_panels(unsigned short event)
group_relink_nla_objects(ob);
allqueue(REDRAWVIEW3D, 0);
break;
+ case B_BAKEABLE_CHANGE:
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case B_OBJECT_IPOFLAG:
+ if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0;
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case B_CLOTH_CLEARCACHEALL:
+ {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ {
+ // do nothing in editmode
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
+ break;
+
+ /* force freeing because user wants */
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+
+ /*user wants to free all, so free whole cloth, this helps to start sim at later frame */
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+
+ CFRA= 1;
+ update_for_newframe_muted();
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ cloth_clear_cache(ob, clmd, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ break;
+ case B_CLOTH_CLEARCACHEFRAME:
+ {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ {
+ // do nothing in editmode
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
+ break;
+
+ /* force freeing because user wants */
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+
+ cloth_clear_cache(ob, clmd, MAX2(0.0,G.scene->r.cfra));
+ // MAX2(1.0,G.scene->r.cfra + 1.0)
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+ }
+ break;
+ case B_CLOTH_CHANGEPREROLL:
+ {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ {
+ // do nothing in editmode
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
+ break;
+
+ CFRA= 1;
+ update_for_newframe_muted();
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ break;
+ case B_CLOTH_RENEW:
+ {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(clmd)
+ {
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ break;
default:
if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
@@ -1888,8 +2494,7 @@ static void group_ob_rem(void *gr_v, void *ob_v)
{
Object *ob= OBACT;
- rem_from_group(gr_v, ob);
- if(find_group(ob)==NULL) {
+ if(rem_from_group(gr_v, ob) && find_group(ob, NULL)==NULL) {
ob->flag &= ~OB_FROMGROUP;
BASACT->flag &= ~OB_FROMGROUP;
}
@@ -1916,23 +2521,26 @@ static void object_panel_object(Object *ob)
Group *group;
int a, xco, yco=0;
short dx= 33, dy= 30;
-
+ int is_libdata = object_is_libdata(ob);
block= uiNewBlock(&curarea->uiblocks, "object_panel_object", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Object and Links", "Object", 0, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
/* object name */
uiBlockSetCol(block, TH_BUT_SETTING2);
+ uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
xco= std_libbuttons(block, 10, 180, 0, NULL, 0, ID_OB, 0, &ob->id, NULL, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0, B_KEEPDATA);
uiBlockSetCol(block, TH_AUTO);
/* parent */
+ uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", xco+5, 180, 305-xco, 20, &ob->parent, "Parent Object");
- /* TODO, check for ob->id.lib */
+ uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
but = uiDefButS(block, NUM, B_NOP, "PassIndex:", xco+5, 150, 305-xco, 20, &ob->index, 0.0, 1000.0, 0, 0, "Index # for the IndexOB render pass.");
-
+
+ uiSetButLock(1, NULL);
uiDefBlockBut(block, add_groupmenu, NULL, "Add to Group", 10,150,150,20, "Add Object to a new Group");
/* all groups */
@@ -1979,15 +2587,22 @@ static void object_panel_object(Object *ob)
uiNewPanelHeight(block, 204 - (120-yco));
}
+static void object_panel_anim_timeoffset_callback( void *data, void *timeoffset_ui) {
+ Object *ob = (Object *)data;
+ ob->sf = (*(float *)timeoffset_ui) - (give_timeoffset(ob) - ob->sf);
+}
+
static void object_panel_anim(Object *ob)
{
uiBlock *block;
+ uiBut *but;
+ static float timeoffset_ui;
char str[32];
block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Anim settings", "Object", 320, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
uiDefButS(block, ROW,B_TRACKBUTS,"TrackX", 24,180,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
@@ -2002,7 +2617,7 @@ static void object_panel_anim(Object *ob)
uiDefButS(block, ROW,REDRAWVIEW3D,"Z", 298,180,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_DRAWKEY, REDRAWVIEW3D, "Draw Key", 24,155,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
+ uiDefButBitS(block, TOG, OB_DRAWKEY, B_OBJECT_IPOFLAG, "Draw Key", 24,155,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
uiDefButBitS(block, TOG, OB_DRAWKEYSEL, REDRAWVIEW3D, "Draw Key Sel", 97,155,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
uiDefButBitS(block, TOG, OB_POWERTRACK, REDRAWVIEW3D, "Powertrack", 180,155,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
uiDefButBitS(block, TOG, PARSLOW, 0, "SlowPar", 260,155,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
@@ -2012,15 +2627,17 @@ static void object_panel_anim(Object *ob)
uiDefButBitS(block, TOG, OB_DUPLIVERTS, B_DUPLI_VERTS, "DupliVerts", 119,130,95,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
uiDefButBitS(block, TOG, OB_DUPLIFACES, B_DUPLI_FACES, "DupliFaces", 214,130,102,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all faces");
uiDefButBitS(block, TOG, OB_DUPLIGROUP, B_DUPLI_GROUP, "DupliGroup", 24,110,150,20, &ob->transflag, 0, 0, 0, 0, "Enable group instancing");
- if(ob->transflag & OB_DUPLIFRAMES)
+ if(ob->transflag & OB_DUPLIFRAMES) {
uiDefButBitS(block, TOG, OB_DUPLINOSPEED, REDRAWVIEW3D, "No Speed", 174,110,142,20, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
- else if(ob->transflag & OB_DUPLIVERTS)
+ } else if(ob->transflag & OB_DUPLIVERTS) {
uiDefButBitS(block, TOG, OB_DUPLIROT, REDRAWVIEW3D, "Rot", 174,110,142,20, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to vertex normal");
- else if(ob->transflag & OB_DUPLIFACES)
- uiDefButBitS(block, TOG, OB_DUPLIFACES_SCALE, REDRAWVIEW3D, "Scale", 174,110,142,20, &ob->transflag, 0, 0, 0, 0, "Scale dupli based on face size");
- else
+ } else if(ob->transflag & OB_DUPLIFACES) {
+ uiDefButBitS(block, TOG, OB_DUPLIFACES_SCALE, REDRAWVIEW3D, "Scale", 174,110,80,20, &ob->transflag, 0, 0, 0, 0, "Scale dupli based on face size");
+ uiDefButF(block, NUM, REDRAWVIEW3D, "", 254,110,62,20, &ob->dupfacesca, 0.001, 10000.0, 0, 0, "Scale the DupliFace objects");
+ } else {
uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_GROUP_RELINK, "GR:", 174,110,142,20, &ob->dup_group, "Instance an existing group");
-
+ }
+
uiBlockBeginAlign(block);
/* DupSta and DupEnd are both shorts, so the maxframe is greater then their range
just limit the buttons to the max short */
@@ -2028,19 +2645,29 @@ static void object_panel_anim(Object *ob)
uiDefButI(block, NUM, REDRAWVIEW3D, "DupOn:", 170,85,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "Specify the number of frames to use between DupOff frames");
uiDefButI(block, NUM, REDRAWVIEW3D, "DupEnd", 24,65,140,19, &ob->dupend, 1.0, 32767, 0, 0, "Specify endframe for Dupliframes");
uiDefButI(block, NUM, REDRAWVIEW3D, "DupOff", 171,65,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "Specify recurring frames to exclude from the Dupliframes");
+ uiBlockEndAlign(block);
+
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "Offs Ob", 24,35,56,20, &ob->ipoflag, 0, 0, 0, 0, "Not functional at the moment!");
- uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "Offs Par", 82,35,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent");
- uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "Offs Particle", 140,35,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
+
+ timeoffset_ui = give_timeoffset(ob);
+ but = uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,35,115,20, &timeoffset_ui, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Animation offset in frames for ipo's and dupligroup instances");
+ uiButSetFunc(but, object_panel_anim_timeoffset_callback, ob, &timeoffset_ui);
+
+ uiDefBut(block, BUT, B_AUTOTIMEOFS, "Auto", 139,35,34,20, 0, 0, 0, 0, 0, "Assign selected objects a timeoffset within a range, starting from the active object");
+ uiDefBut(block, BUT, B_OFSTIMEOFS, "Ofs", 173,35,34,20, 0, 0, 0, 0, 0, "Offset selected objects timeoffset");
+ uiDefBut(block, BUT, B_RANDTIMEOFS, "Rand", 207,35,34,20, 0, 0, 0, 0, 0, "Randomize selected objects timeoffset");
+ uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 250,35,65,20, 0, 0, 0, 0, 0, "Print objectspeed");
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,10,115,20, &ob->sf, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify an offset in frames");
- uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 139,10,104,20, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
- uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 248,10,67,20, 0, 0, 0, 0, 0, "Print objectspeed");
+ uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "OfsEdit", 24,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Use timeoffset when inserting keys and display timeoffset for ipo and action views");
+ uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "OfsParent", 82,10,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Apply the timeoffset to this objects parent relationship");
+ uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "OfsParticle", 140,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
+ uiDefButBitS(block, TOG, OB_OFFS_PARENTADD, REDRAWALL, "AddParent", 196,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Add the parents timeoffset value");
uiBlockEndAlign(block);
sprintf(str, "%.4f", prspeed);
- uiDefBut(block, LABEL, 0, str, 247,35,63,31, NULL, 1.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, str, 260,10,63,31, NULL, 1.0, 0, 0, 0, "");
}
@@ -2052,7 +2679,7 @@ static void object_panel_draw(Object *ob)
block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Draw", "Object", 640, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
/* LAYERS */
xco= 120;
@@ -2100,7 +2727,6 @@ static void object_panel_draw(Object *ob)
uiDefButBitC(block, TOG, OB_DRAWTRANSP, REDRAWVIEW3D, "Transp", 120, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Enables transparent materials for the active object (Mesh only)");
uiDefButBitC(block, TOG, OB_DRAWXRAY, REDRAWVIEW3D, "X-ray", 210, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Makes the active object draw in front of others");
-
}
void object_panel_constraint(char *context)
@@ -2115,23 +2741,23 @@ void object_panel_constraint(char *context)
block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Constraints", context, 960, 0, 318, 204)==0) return;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
/* this is a variable height panel, newpanel doesnt force new size on existing panels */
/* so first we make it default height */
uiNewPanelHeight(block, 204);
+ /* do not allow this panel to draw in editmode - why?*/
if(G.obedit==OBACT) return; // ??
conlist = get_active_constraints(OBACT);
if (conlist) {
-
uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint");
/* print active object or bone */
str[0]= 0;
- if (ob->flag & OB_POSEMODE){
+ if (ob->flag & OB_POSEMODE) {
bPoseChannel *pchan= get_active_posechannel(ob);
if(pchan) sprintf(str, "To Bone: %s", pchan->name);
}
@@ -2166,14 +2792,28 @@ void do_effects_panels(unsigned short event)
Base *base;
Effect *eff, *effn;
PartEff *paf;
+ ModifierData *md;
+ ParticleSystemModifierData *psmd;
+ ParticleSystem *psys;
+ ParticleSettings *part;
+ ID *id,*idtest;
+ int nr;
ob= OBACT;
+ psys=psys_get_current(ob);
+
switch(event) {
case B_AUTOTIMEOFS:
auto_timeoffs();
break;
+ case B_OFSTIMEOFS:
+ ofs_timeoffs();
+ break;
+ case B_RANDTIMEOFS:
+ rand_timeoffs();
+ break;
case B_FRAMEMAP:
G.scene->r.framelen= G.scene->r.framapto;
G.scene->r.framelen/= G.scene->r.images;
@@ -2287,6 +2927,244 @@ void do_effects_panels(unsigned short event)
allqueue(REDRAWVIEW3D, 0);
}
break;
+ case B_PARTBROWSE:
+ if(G.buts->menunr== -2) {
+ activate_databrowse((ID *)G.buts->lockpoin, ID_PA, 0, B_PARTBROWSE, &G.buts->menunr, do_effects_panels);
+ return;
+ }
+
+ if(G.buts->menunr < 0) return;
+
+ if(G.buts->pin) {
+
+ }
+ else {
+ psys= psys_get_current(ob);
+ if(psys)
+ part=psys->part;
+ else
+ part=NULL;
+
+ nr= 1;
+
+ id= (ID *)part;
+
+ idtest= G.main->particle.first;
+ while(idtest) {
+ if(nr==G.buts->menunr) {
+ break;
+ }
+ nr++;
+ idtest= idtest->next;
+ }
+ if(idtest==0) { /* new particle system */
+ if(id){
+ idtest= (ID *)psys_copy_settings((ParticleSettings *)id);
+ }
+ else {
+ idtest= (ID *)psys_new_settings("PSys", G.main);
+ }
+ idtest->us--;
+ }
+ if(idtest!=id) {
+ short nr=0;
+ if(id==0){ /* no psys previously -> no modifier -> need to create that also */
+ psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+ BLI_addtail(&ob->particlesystem,psys);
+
+ md= modifier_new(eModifierType_ParticleSystem);
+ sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+ psmd= (ParticleSystemModifierData*) md;
+ psmd->psys=psys;
+ BLI_addtail(&ob->modifiers, md);
+ }
+
+ idtest->us++;
+ psys->part=(ParticleSettings*)idtest;
+ psys->totpart=0;
+ psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+ psys->cfra=bsystem_time(ob,G.scene->r.cfra+1,0.0);
+
+ /* check need for dupliobjects */
+ nr=0;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
+ nr++;
+ }
+ if(nr)
+ ob->transflag |= OB_DUPLIPARTS;
+ else
+ ob->transflag &= ~OB_DUPLIPARTS;
+
+ BIF_undo_push("Browse Particle System");
+
+ DAG_scene_sort(G.scene);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+
+ }
+ break;
+ case B_PARTDELETE:
+ if(ob && ob->particlesystem.first){
+ psys= psys_get_current(ob);
+ if(psys) {
+ /* clear modifier */
+ psmd= psys_get_modifier(ob,psys);
+ BLI_remlink(&ob->modifiers, psmd);
+ modifier_free((ModifierData *)psmd);
+
+ /* clear particle system */
+ BLI_remlink(&ob->particlesystem,psys);
+ psys_free(ob,psys);
+
+ BIF_undo_push("Delete particle system");
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ }
+ break;
+ case B_PARTALONE: /* TODO: not too sure of how this works so someone check please, jahka */
+ if(ob && (psys=psys_get_current(ob))){
+ if(psys->part) {
+ if(psys->part->id.us>1){
+ if(okee("Make local")){
+ part=psys_copy_settings(psys->part);
+ part->id.us=1;
+ psys->part->id.us--;
+ psys->part=part;
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+
+ BIF_undo_push("Make single user or local");
+ }
+ }
+ }
+ }
+ break;
+ case B_PART_ALLOC:
+ case B_PART_ALLOC_CHILD:
+ if(psys){
+ psys_flush_settings(psys->part,PSYS_ALLOC,event==B_PART_ALLOC);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ break;
+ case B_PART_DISTR:
+ case B_PART_DISTR_CHILD:
+ if(psys){
+ psys_flush_settings(psys->part,PSYS_DISTR,event==B_PART_DISTR);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ break;
+ case B_PART_INIT:
+ case B_PART_INIT_CHILD:
+ if(psys){
+ psys_flush_settings(psys->part,PSYS_INIT,event==B_PART_INIT);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ break;
+ case B_PART_ENABLE:
+ if(psys) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
+ case B_PART_RECALC:
+ case B_PART_RECALC_CHILD:
+ if(psys){
+ psys_flush_settings(psys->part,0,event==B_PART_RECALC);
+ allqueue(REDRAWOOPS, 0);
+ }
+ /* no break! */
+ case B_PART_REDRAW_DEPS:
+ if(event == B_PART_REDRAW_DEPS)
+ DAG_scene_sort(G.scene);
+ /* no break! */
+ case B_PART_REDRAW:
+ nr=0;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
+ nr++;
+ }
+ if(nr)
+ ob->transflag |= OB_DUPLIPARTS;
+ else
+ ob->transflag &= ~OB_DUPLIPARTS;
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ break;
+ case B_PARTTYPE:
+ if((psys=psys_get_current(ob))){
+ DAG_scene_sort(G.scene);
+
+ psys_flush_settings(psys->part,PSYS_TYPE,1);
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ break;
+ case B_PARTACT:
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWIPO, 0);
+ break;
+ case B_PARTTARGET:
+ if((psys=psys_get_current(ob))){
+ if(psys->keyed_ob==ob || psys->target_ob==ob){
+ if(psys->keyed_ob==ob)
+ psys->keyed_ob=NULL;
+ else
+ psys->target_ob=NULL;
+ }
+ else{
+ DAG_scene_sort(G.scene);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_PART_REKEY:
+ PE_rekey();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ case B_PART_EDITABLE:
+ if((psys = psys_get_current(ob))) {
+ if(psys->flag & PSYS_EDITED){
+ if(okee("Lose changes done in particle mode?")){
+ if(psys->edit)
+ PE_free_particle_edit(psys);
+
+ psys->flag &= ~PSYS_EDITED;
+ psys->recalc |= PSYS_RECALC_HAIR;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ else {
+ psys->flag |= PSYS_EDITED;
+ if(G.f & G_PARTICLEEDIT)
+ PE_create_particle_edit(ob, psys);
+ }
+ }
case B_FIELD_DEP:
/* do this before scene sort, that one checks for CU_PATH */
if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) {
@@ -2306,6 +3184,10 @@ void do_effects_panels(unsigned short event)
allqueue(REDRAWBUTSOBJECT, 0);
break;
case B_FIELD_CHANGE:
+ if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex){
+ ob->pd->tex->id.us--;
+ ob->pd->tex=0;
+ }
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
allqueue(REDRAWVIEW3D, 0);
break;
@@ -2350,13 +3232,106 @@ void do_effects_panels(unsigned short event)
}
-/* Panel for particle interaction settings */
+/* copy from buttons_editing.c */
+static void field_testTexture(char *name, ID **idpp)
+{
+ ID *id;
+
+ for(id = G.main->tex.first; id; id = id->next) {
+ if(strcmp(name, id->name + 2) == 0) {
+ *idpp = id;
+ /* texture gets user, objects not: delete object = clear modifier */
+ id_us_plus(id);
+ return;
+ }
+ }
+ *idpp = 0;
+}
+
+/* Panel for collision */
+static void object_collision__enabletoggle ( void *ob_v, void *arg2 )
+{
+ Object *ob = ob_v;
+ PartDeflect *pd= ob->pd;
+ ModifierData *md = modifiers_findByType ( ob, eModifierType_Collision );
+
+ if ( !md )
+ {
+ if(pd && (pd->deflect))
+ {
+ md = modifier_new ( eModifierType_Collision );
+ BLI_addhead ( &ob->modifiers, md );
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ else
+ {
+ BLI_remlink ( &ob->modifiers, md );
+ modifier_free ( md );
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+}
+
+/* Panels for particle interaction settings */
+static void object_panel_deflection(Object *ob)
+{
+ uiBlock *block;
+ uiBut *but;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Deflection", "Physics", 0, 0, 318, 204)==0) return;
+
+ uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ /* should become button, option? */
+ if(ob->pd==NULL) {
+ ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
+ /* and if needed, init here */
+ ob->pd->pdef_sbdamp = 0.1f;
+ ob->pd->pdef_sbift = 0.2f;
+ ob->pd->pdef_sboft = 0.02f;
+ }
+
+ /* only meshes collide now */
+ if(ob->pd && ob->type==OB_MESH) {
+ PartDeflect *pd= ob->pd;
+
+ but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
+ uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
+
+ if(pd->deflect) {
+ uiDefBut(block, LABEL, 0, "Particles", 160,140,75,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_DIFF, "Kill",235,140,75,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_DIFF, "Damping: ", 160,120,75,20, &pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision");
+ uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ", 235,120,75,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping");
+ uiDefButF(block, NUM, B_DIFF, "Friction: ", 160,100,75,20, &pd->pdef_frict, 0.0, 1.0, 10, 0, "Amount of friction during particle collision");
+ uiDefButF(block, NUM, B_DIFF, "Rnd Friction: ", 235,100,75,20, &pd->pdef_rfrict, 0.0, 1.0, 10, 0, "Random variation of friction");
+ uiDefButF(block, NUM, B_DIFF, "Permeability: ", 160,80,150,20, &pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Soft Body / Cloth", 160,60,150,20, NULL, 0.0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 160,40,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 160,20,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160, 0,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+ }
+ }
+}
static void object_panel_fields(Object *ob)
{
uiBlock *block;
+ uiBut *but;
+ int particles=0;
+ static short actpsys=-1;
block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Fields and Deflection", "Physics", 0, 0, 318, 204)==0) return;
+ uiNewPanelTabbed("Deflection", "Physics");
+ if(uiNewPanel(curarea, block, "Fields", "Physics", 0, 0, 318, 204)==0) return;
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
@@ -2374,67 +3349,156 @@ static void object_panel_fields(Object *ob)
char *menustr= MEM_mallocN(256, "temp string");
char *tipstr="Choose field type";
- uiDefBut(block, LABEL, 0, "Fields", 10,180,140,20, NULL, 0.0, 0, 0, 0, "");
-
+ if(ob->particlesystem.first) {
+ ParticleSystem *psys;
+ char *menustr2= psys_menu_string(ob,1);
+
+ psys= psys_get_current(ob);
+ if(psys && actpsys >= 0) {
+ actpsys= psys_get_current_num(ob)+1;
+
+ if(psys->part->pd==NULL)
+ psys->part->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
+
+ pd= psys->part->pd;
+ particles=1;
+ }
+ else
+ actpsys= -1; /* -1 = object */
+
+ but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr2, 10,180,70,20, &actpsys, 14.0, 0.0, 0, 0, "Browse systems");
+ uiButSetFunc(but, PE_change_act, ob, &actpsys);
+
+ MEM_freeN(menustr2);
+ }
+
/* setup menu button */
- sprintf(menustr, "Field Type%%t|None %%x0|Spherical %%x%d|Wind %%x%d|Vortex %%x%d|Curve Guide %%x%d",
- PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE);
-
- if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles";
- else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis";
- else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the Object";
- else if(pd->forcefield==PFIELD_GUIDE) tipstr= "Use a Curve Path to guide particles";
+ if(particles){
+ sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d",
+ PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC);
+
+ if(pd->forcefield==PFIELD_FORCE) tipstr= "Particle attracts or repels particles (On shared object layers)";
+ else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of particle Z axis (On shared object layers)";
+ else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the particle (On shared object layers)";
+ }
+ else{
+ if(ob->type==OB_CURVE)
+ sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d",
+ PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE);
+ else
+ sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d",
+ PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE);
+
+ if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles (On shared object layers)";
+ else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis (On shared object layers)";
+ else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the Object (On shared object layers)";
+ else if(pd->forcefield==PFIELD_GUIDE) tipstr= "Use a Curve Path to guide particles (On shared object layers)";
+ }
- uiDefButS(block, MENU, B_FIELD_DEP, menustr, 10,160,140,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
+ if(ob->particlesystem.first)
+ uiDefButS(block, MENU, B_FIELD_DEP, menustr, 80,180,70,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
+ else
+ uiDefButS(block, MENU, B_FIELD_DEP, menustr, 10,180,140,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
+
MEM_freeN(menustr);
if(pd->forcefield) {
uiBlockBeginAlign(block);
if(pd->forcefield == PFIELD_GUIDE) {
- uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 10,120,140,20, &pd->f_strength, 0.0, 1000.0, 10, 0, "The distance from which particles are affected fully.");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 10,100,140,20, &pd->f_power, 0.0, 10.0, 10, 0, "Falloff factor, between mindist and maxdist");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 10,140,140,20, &pd->f_strength, 0.0, 1000.0, 10, 0, "The distance from which particles are affected fully.");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 10,120,140,20, &pd->f_power, 0.0, 10.0, 10, 0, "Falloff factor, between mindist and maxdist");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Free: ", 10,100,140,20, &pd->free_end, 0.0, 0.99, 10, 0, "Guide-free time from particle life's end");
+ uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use", 10,80,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 50,80,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
}
- else {
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Strength: ", 10,110,140,20, &pd->f_strength, -1000, 1000, 10, 0, "Strength of force field");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 10,90,140,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational fallof = 2)");
+ else {
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Strength: ", 10,140,140,20, &pd->f_strength, -1000, 1000, 10, 3, "Strength of force field");
+
+ if(pd->forcefield == PFIELD_TEXTURE){
+ uiDefIDPoinBut(block, field_testTexture, ID_TE, B_FIELD_CHANGE, "Texture: ", 10, 120, 140, 20, &pd->tex, "Texture to use as force");
+ uiDefButBitS(block, TOG, PFIELD_TEX_OBJECT, B_FIELD_CHANGE, "Use Object Co", 10,100,140,20, &pd->flag, 0.0, 0, 0, 0, "Use object/global coordinates for texture");
+ uiDefButBitS(block, TOG, PFIELD_TEX_ROOTCO, B_FIELD_CHANGE, "Root TexCo", 10,80,120,20, &pd->flag, 0.0, 0, 0, 0, "Texture coords from root particle locations");
+ uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D", 130,80,20,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
+ }
+ else if(pd->forcefield == PFIELD_HARMONIC)
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");
}
+ uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use MaxDist", 10,60,140,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 10,40,140,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
+ if(pd->forcefield == PFIELD_GUIDE){
+ uiDefButBitS(block, TOG, PFIELD_GUIDE_PATH_ADD, B_FIELD_CHANGE, "Additive", 10,40,140,20, &pd->flag, 0.0, 0, 0, 0, "Based on distance/falloff it adds a portion of the entire path");
+ }
+ else if(pd->forcefield==PFIELD_TEXTURE){
+ uiDefButS(block, MENU, B_FIELD_CHANGE, "Texture mode%t|RGB%x0|Gradient%x1|Curl%x2", 10,40,140,20, &pd->tex_mode, 0.0, 0.0, 0, 0, "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)");
+
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Nabla:", 10,20,140,20, &pd->tex_nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient and curl calculation");
+ }
+ else if(particles==0 && ELEM(pd->forcefield,PFIELD_VORTEX,PFIELD_WIND)==0){
+ //uiDefButF(block, NUM, B_FIELD_CHANGE, "Distance: ", 10,20,140,20, &pd->f_dist, 0, 1000.0, 10, 0, "Falloff power (real gravitational fallof = 2)");
+ uiDefButBitS(block, TOG, PFIELD_PLANAR, B_FIELD_CHANGE, "Planar", 10,0,140,20, &pd->flag, 0.0, 0, 0, 0, "Create planar field");
+ }
uiBlockEndAlign(block);
- if(pd->forcefield == PFIELD_GUIDE)
- uiDefButBitS(block, TOG, PFIELD_GUIDE_PATH_ADD, B_FIELD_CHANGE, "Additive", 10,10,140,20, &pd->flag, 0.0, 0, 0, 0, "Based on distance/falloff it adds a portion of the entire path");
-
- }
-
- uiDefBut(block, LABEL, 0, "Deflection", 160,180,140,20, NULL, 0.0, 0, 0, 0, "");
-
- /* only meshes collide now */
- if(ob->type==OB_MESH) {
- uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
- if(pd->deflect) {
- uiDefBut(block, LABEL, 0, "Particles", 160,140,150,20, NULL, 0.0, 0, 0, 0, "");
-
+ if(pd->forcefield==PFIELD_GUIDE){
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_DIFF, "Damping: ", 160,120,150,20, &pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision");
- uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ", 160,100,150,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping");
- uiDefButF(block, NUM, B_DIFF, "Permeability: ", 160,80,150,20, &pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh");
+ uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Clump:", 160,180,140,20, &pd->clump_fac, -1.0, 1.0, 1, 3, "Amount of clumpimg");
+ uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Shape:", 160,160,140,20, &pd->clump_pow, -0.999, 0.999, 1, 3, "Shape of clumpimg");
uiBlockEndAlign(block);
-
- uiDefBut(block, LABEL, 0, "Soft Body", 160,60,150,20, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 160,40,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 160,20,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
- uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160, 0,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+ if(pd->kink){
+ uiDefButS(block, MENU, B_FIELD_CHANGE, "Kink:%t|Roll%x6|Rotation%x5|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", 160,120,70,20, &pd->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the curve");
+ uiDefButS(block, MENU, B_FIELD_CHANGE, "Axis %t|Z %x2|Y %x1|X %x0", 230,120,70,20, &pd->kink_axis, 14.0, 0.0, 0, 0, "Which axis to use for offset");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Freq:", 160,100,140,20, &pd->kink_freq, 0.0, 10.0, 1, 3, "The frequency of the offset (1/total length)");
+ uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Shape:", 160,80,140,20, &pd->kink_shape, -0.999, 0.999, 1, 3, "Adjust the offset to the beginning/end");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Amplitude:", 160,60,140,20, &pd->kink_amp, 0.0, 10.0, 1, 3, "The amplitude of the offset");
+ }
+ else{
+ uiDefButS(block, MENU, B_FIELD_CHANGE, "Kink:%t|Roll%x6|Rotation%x5|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", 160,120,140,20, &pd->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the curve");
+ }
+ uiBlockEndAlign(block);
}
- }
+ else{
+ uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0", 160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, tipstr);
+ if(pd->falloff==PFIELD_FALL_TUBE)
+ uiDefBut(block, LABEL, 0, "Lognitudinal", 160,160,70,20, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos", 160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)");
+ uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use", 160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
+ uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use", 160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off");
+ uiBlockEndAlign(block);
+
+ if(pd->falloff==PFIELD_FALL_TUBE){
+ uiDefBut(block, LABEL, 0, "Radial", 160,80,70,20, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
+ uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work");
+ uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off");
+ uiBlockEndAlign(block);
+ }
+ else if(pd->falloff==PFIELD_FALL_CONE){
+ uiDefBut(block, LABEL, 0, "Angular", 160,80,70,20, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
+ uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ", 200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)");
+ uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off");
+ uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ", 200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)");
+ uiBlockEndAlign(block);
+ }
+ }
+ }
}
}
-
/* Panel for softbodies */
static void object_softbodies__enable(void *ob_v, void *arg2)
{
@@ -2456,10 +3520,14 @@ static void object_softbodies__enable(void *ob_v, void *arg2)
if (!ob->soft) {
ob->soft= sbNew();
ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
+ softbody_clear_cache(ob, CFRA);
}
}
+ /* needed so that initial state is cached correctly */
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
static int _can_softbodies_at_all(Object *ob)
@@ -2473,30 +3541,99 @@ static int _can_softbodies_at_all(Object *ob)
// else deny
return 0;
}
-static void object_softbodies_II(Object *ob)
+static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
+{
+ ParticleSystem *psys = psys_v;
+ Object *ob = ob_v;
+
+ if(psys->softflag & OB_SB_ENABLE){
+ psys->softflag &= ~OB_SB_ENABLE;
+ }
+ else{
+ if (!psys->soft) {
+ psys->soft= sbNew();
+ psys->softflag |= OB_SB_GOAL|OB_SB_EDGES;
+ psys->soft->particles=psys;
+ clear_particles_from_cache(ob, psys, CFRA);
+ }
+ psys->softflag |= OB_SB_ENABLE;
+ }
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+
+
+#ifdef _work_on_sb_solver
+static char sbsolvers[] = "Solver %t|RKP almost SOFT not usable but for some german teachers %x1|STU ip semi implicit euler%x3|SI1 (half step)adaptive semi implict euler %x2|SI2 (use dv)adaptive semi implict euler %x4|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+/* SIF would have been candidate .. well lack of time .. brecht is busy .. better make a stable version for peach now :) */
+static char sbsolvers[] = "SIF semi implicit euler with fixed step size (worth a try with real stiff egdes)%x3|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+#else
+static char sbsolvers[] = "RKCP correct physics (harder to get stable but usefull for education :)%x1|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+#endif
+
+static void object_softbodies_collision(Object *ob)
{
+ SoftBody *sb=ob->soft;
uiBlock *block;
+ uiBut *but = NULL;
static int val;
+ short *softflag=&ob->softflag, psys_cur=0;
+ int ob_has_hair=psys_ob_has_hair(ob);
if(!_can_softbodies_at_all(ob)) return;
- block= uiNewBlock(&curarea->uiblocks, "object_softbodies_II", UI_EMBOSS, UI_HELV, curarea->win);
- uiNewPanelTabbed("Soft Body", "Physics");
+ /*bah that is ugly! creating missing data members in UI code*/
+ if(ob->pd == NULL){
+ ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
+ ob->pd->pdef_sbdamp = 0.1f;
+ ob->pd->pdef_sbift = 0.2f;
+ ob->pd->pdef_sboft = 0.02f;
+ }
+ block= uiNewBlock(&curarea->uiblocks, "object_softbodies_collision", UI_EMBOSS, UI_HELV, curarea->win);
+ // uiNewPanelTabbed("Soft Body", "Physics"); /*don't really want it tabbed first */
if(uiNewPanel(curarea, block, "Soft Body Collision", "Physics", 651, 0, 318, 204)==0) return;
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- val = modifiers_isSoftbodyEnabled(ob);
+ if(ob_has_hair) {
+ if(PE_get_current_num(ob) >= 0) {
+ ParticleSystem *psys = PE_get_current(ob);
+ if(psys) {
+ sb = psys->soft;
+ softflag = &psys->softflag;
+ psys_cur = 1;
+ }
+ }
+ }
+
+ if(psys_cur) {
+ if(*softflag & OB_SB_ENABLE)
+ val = 1;
+ else
+ val = 0;
+ }
+ else
+ val = modifiers_isSoftbodyEnabled(ob);
+
if(!val) {
uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "However it can deflect a softbody",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
+ if(psys_cur){
+ uiDefBut(block, LABEL, 0, "Hair is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "However the emitter can deflect a softbody",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+ else {
+ uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "However it can deflect a softbody",10,170,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
/* OTHER OBJECTS COLLISION STUFF */
if (ob->type==OB_MESH){
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to softbody objects");
+ but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to softbody objects");
+ uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
if(ob->pd->deflect) {
uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:", 160,50,150,20, &ob->pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
+ uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 160,30,150,20, &ob->pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160,10,150,20, &ob->pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
}
@@ -2504,19 +3641,18 @@ static void object_softbodies_II(Object *ob)
uiBlockEndAlign(block);
}
else{
- SoftBody *sb= ob->soft;
/* SELF COLLISION STUFF */
if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
uiBlockBeginAlign(block);
- if (ob->softflag & OB_SB_EDGES){
- uiDefButBitS(block, TOG, OB_SB_SELF, B_SOFTBODY_CHANGE, "Self Collision", 10,170,150,20, &ob->softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
- if(ob->softflag & OB_SB_SELF){
+ if (*softflag & OB_SB_EDGES){
+ uiDefButBitS(block, TOG, OB_SB_SELF, B_SOFTBODY_CHANGE, "Self Collision", 10,170,150,20, softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
+ if(*softflag & OB_SB_SELF){
uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Ball Size:", 160,170,150,20, &sb->colball, -10.0, 10.0, 10, 0, "Absolute ball size or factor if not manual adjusted");
- uiDefButS(block, ROW, B_DIFF, "Man",10,150,60,20, &sb->sbc_mode, 4.0,(float)0, 0, 0, "Manual adjust");
- uiDefButS(block, ROW, B_DIFF, "Av",70,150,60,20, &sb->sbc_mode, 4.0,(float)1, 0, 0, "Average Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,(float)2, 0, 0, "Minimal Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,(float)3, 0, 0, "Maximal Spring lenght * Ball Size");
- uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,(float)4, 0, 0, "(Min+Max)/2 * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "Man",10,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MANUAL, 0, 0, "Manual adjust");
+ uiDefButS(block, ROW, B_DIFF, "Av",70,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVG, 0, 0, "Average Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "Min",130,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MIN, 0, 0, "Minimal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "Max",190,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MAX, 0, 0, "Maximal Spring lenght * Ball Size");
+ uiDefButS(block, ROW, B_DIFF, "AvMiMa",250,150,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVGMINMAX, 0, 0, "(Min+Max)/2 * Ball Size");
uiDefButF(block, NUM, B_DIFF, "B Stiff:", 10,130,150,20, &sb->ballstiff, 0.001, 100.0, 10, 0, "Ball inflating presure");
uiDefButF(block, NUM, B_DIFF, "B Damp:", 160,130,150,20, &sb->balldamp, 0.001, 1.0, 10, 0, "Blending to inelastic collision");
}
@@ -2528,20 +3664,15 @@ static void object_softbodies_II(Object *ob)
uiBlockEndAlign(block);
/*SOLVER SETTINGS*/
- uiDefButF(block, NUM, B_DIFF, "Error Lim:", 10,100,130,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
- uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"O", 140,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Old Error Calculation");
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,100,130,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
- uiDefButS(block, NUM, B_DIFF, "MinS:", 10,80,100,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "MaxS:", 110,80,100,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
+ /* done in another panel now*/
}
/* OTHER OBJECTS COLLISION STUFF */
if (ob->type==OB_MESH){
- uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to other softbody objects");
+ but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",10,50,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Makes this object visible to other softbody objects");
+ uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
if(ob->pd->deflect) {
uiDefButF(block, NUM, B_DIFF, "Damping:", 160,50,150,20, &ob->pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
- uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
+ uiDefButBitS(block, TOG,OB_SB_COLLFINAL , B_DIFF, "Ev.M.Stack",10,30,150,20, softflag, 0, 0, 0, 0, "Pick collision object from modifier stack");
uiDefButF(block, NUM, B_DIFF, "Inner:", 160,30,150,20, &ob->pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
uiDefButF(block, NUM, B_DIFF, "Outer:", 160,10,150,20, &ob->pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
}
@@ -2550,62 +3681,212 @@ static void object_softbodies_II(Object *ob)
}
uiBlockEndAlign(block);
}
+static void object_softbodies_solver(Object *ob)
+{
+ SoftBody *sb=ob->soft;
+ uiBlock *block;
+ static int val;
+ short *softflag=&ob->softflag, psys_cur=0, adaptive_mode=0;
+ int ob_has_hair=psys_ob_has_hair(ob);
+ if(!_can_softbodies_at_all(ob)) return;
+ block= uiNewBlock(&curarea->uiblocks, "object_softbodies_solver", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
+
+ uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ /* doubt that is really needed here but for now */
+ if(ob_has_hair) {
+ if(PE_get_current_num(ob) >= 0) {
+ ParticleSystem *psys = PE_get_current(ob);
+ if(psys) {
+ sb = psys->soft;
+ softflag = &psys->softflag;
+ psys_cur = 1;
+ }
+ }
+ }
+
+ if(psys_cur) {
+ if(*softflag & OB_SB_ENABLE)
+ val = 1;
+ else
+ val = 0;
+ }
+ else
+ val = modifiers_isSoftbodyEnabled(ob);
+
+ if(!val) {
+ uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
+ if(psys_cur){
+ uiDefBut(block, LABEL, 0, "Hair is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+ else {
+ uiDefBut(block, LABEL, 0, "Object is not a softbody",10,190,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+ }
+ else{
+ if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
+ /*SOLVER SETTINGS*/
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
+ uiBlockEndAlign(block);
+
+ /*some have adapive step size - some not*/
+ switch (sb->solver_ID) {
+ case 0:
+ case 1:
+ {adaptive_mode = 1; break;}
+ case 3:
+ {adaptive_mode = 0; break;}
+ default: printf("SB_solver?\n"); // should never happen
+ }
+ if(adaptive_mode){
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "Error Lim:", 10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+ uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"V", 290,140,20,20, &sb->solverflags, 0, 0, 0, 0, "Use velocities for automagic step sizes");
+ uiDefButS(block, NUM, B_DIFF, "MinS:", 10,120,150,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
+ uiDefButS(block, NUM, B_DIFF, "MaxS:", 160,120,150,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButS(block, NUM, B_DIFF, "Choke:", 10,80,150,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
+ uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,80,150,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, LABEL, 0, "Diagnosis",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiBlockEndAlign(block);
+ }
+ else{
+ uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+ uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
+ uiBlockEndAlign(block);
+ uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops, 1.00, 30000.0, 10, 0, "Solver steps/frame ");
+ uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
+ }
+
+ uiBlockEndAlign(block);
+
+ }
+ }
+ uiBlockEndAlign(block);
+}
+
+static void sb_clear_cache(void *ob_v, void *actsoft_v)
+{
+ Object *ob = ob_v;
+ short *actsoft = actsoft_v;
+ if(actsoft >= 0)
+ clear_particles_from_cache(ob, BLI_findlink(&ob->particlesystem, *actsoft), CFRA);
+ else
+ softbody_clear_cache(ob, CFRA);
+}
static void object_softbodies(Object *ob)
{
+ SoftBody *sb=ob->soft;
+ ParticleSystem *psys=NULL;
uiBlock *block;
- static int val;
uiBut *but;
+ static int val;
+ short *softflag=&ob->softflag, psys_cur=0;
+ int ob_has_hair = psys_ob_has_hair(ob);
+ static short actsoft= -1;
+
if(!_can_softbodies_at_all(ob)) return;
block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Soft Body", "Physics", 640, 0, 318, 204)==0) return;
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- val = modifiers_isSoftbodyEnabled(ob);
- but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
- uiButSetFunc(but, object_softbodies__enable, ob, NULL);
+ if(ob_has_hair) {
+ char *menustr = psys_menu_string(ob,1);
+
+ psys= psys_get_current(ob);
+ if(psys && actsoft >= 0) {
+ actsoft= psys_get_current_num(ob)+1;
+
+ sb=psys->soft;
+ softflag=&psys->softflag;
+ psys_cur=1;
+ }
+ else
+ actsoft= -1; /* -1 = object */
+
+ but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr, 10,200,100,20, &actsoft, 14.0, 0.0, 0, 0, "Browse systems");
+ uiButSetFunc(but, PE_change_act, ob, &actsoft);
+
+ MEM_freeN(menustr);
+ }
+
+ if(psys_cur && psys){
+ if(*softflag & OB_SB_ENABLE)
+ val=1;
+ else
+ val=0;
+
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 110,200,70,20, &val, 0, 0, 0, 0, "Sets hair to become soft body");
+ uiButSetFunc(but, object_softbodies__enable_psys, ob, psys);
+ }
+ else{
+ val = modifiers_isSoftbodyEnabled(ob);
+ if(ob_has_hair)
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 110,200,70,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
+ else
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
+
+
+ uiButSetFunc(but, object_softbodies__enable, ob, NULL);
+ }
+
uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
- if(modifiers_isSoftbodyEnabled(ob)){
- SoftBody *sb= ob->soft;
+ if(val){
int defCount;
char *menustr;
+ static char str[128];
- if(sb==NULL) {
- sb= ob->soft= sbNew();
- ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
- }
+ //uiDefButBitS(block, TOG, OB_SB_BAKESET, REDRAWBUTSOBJECT, "Bake settings", 180,200,130,20, &ob->softflag, 0, 0, 0, 0, "To convert simulation into baked (cached) result");
- uiDefButBitS(block, TOG, OB_SB_BAKESET, REDRAWBUTSOBJECT, "Bake settings", 180,200,130,20, &ob->softflag, 0, 0, 0, 0, "To convert simulation into baked (cached) result");
+ //if(sb->keys) uiSetButLock(1, "Soft Body is baked, free it first");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, OB_SB_PROTECT_CACHE, REDRAWBUTSOBJECT, "Protect", 180,200,50,20, softflag, 0.0, 0.0, 10, 0, "Protect the cache");
+ but=uiDefBut(block, BUT, B_SOFTBODY_CHANGE, "Clear", 230,200,50,20, NULL, 0.0, 0.0, 10, 0, "Clear the cache");
+ if((*softflag & PSYS_PROTECT_CACHE)==0)
+ uiButSetFunc(but, sb_clear_cache, ob, &actsoft);
- if(sb->keys) uiSetButLock(1, "Soft Body is baked, free it first");
+ uiBlockEndAlign(block);
- if(ob->softflag & OB_SB_BAKESET) {
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_DIFF, "Start:", 10, 170,100,20, &sb->sfra, 1.0, 10000.0, 10, 0, "Start frame for baking");
- uiDefButI(block, NUM, B_DIFF, "End:", 110, 170,100,20, &sb->efra, 1.0, 10000.0, 10, 0, "End frame for baking");
- uiDefButI(block, NUM, B_DIFF, "Interval:", 210, 170,100,20, &sb->interval, 1.0, 10.0, 10, 0, "Interval in frames between baked keys");
- uiBlockEndAlign(block);
+ if(*softflag & OB_SB_PROTECT_CACHE) uiSetButLock(1, "Cache is protected");
- uiDefButS(block, TOG, B_DIFF, "Local", 10, 145,100,20, &sb->local, 0.0, 0.0, 0, 0, "Use local coordinates for baking");
+ //if(ob->softflag & OB_SB_BAKESET) {
+ // uiBlockBeginAlign(block);
+ // uiDefButI(block, NUM, B_DIFF, "Start:", 10, 170,100,20, &sb->sfra, 1.0, 10000.0, 10, 0, "Start frame for baking");
+ // uiDefButI(block, NUM, B_DIFF, "End:", 110, 170,100,20, &sb->efra, 1.0, 10000.0, 10, 0, "End frame for baking");
+ // uiDefButI(block, NUM, B_DIFF, "Interval:", 210, 170,100,20, &sb->interval, 1.0, 10.0, 10, 0, "Interval in frames between baked keys");
+ // uiBlockEndAlign(block);
+ // uiDefButS(block, TOG, B_DIFF, "Local", 10, 145,100,20, &sb->local, 0.0, 0.0, 0, 0, "Use local coordinates for baking");
- uiClearButLock();
- uiBlockBeginAlign(block);
- if(sb->keys) {
- char str[128];
- uiDefIconTextBut(block, BUT, B_SOFTBODY_BAKE_FREE, ICON_X, "FREE BAKE", 10, 120,300,20, NULL, 0.0, 0.0, 0, 0, "Free baked result");
- sprintf(str, "Stored %d vertices %d keys %.3f MB", sb->totpoint, sb->totkey, ((float)16*sb->totpoint*sb->totkey)/(1024.0*1024.0));
- uiDefBut(block, LABEL, 0, str, 10, 100,300,20, NULL, 0.0, 0.0, 00, 0, "");
- }
- else
- uiDefBut(block, BUT, B_SOFTBODY_BAKE, "BAKE", 10, 120,300,20, NULL, 0.0, 0.0, 10, 0, "Start baking. Press ESC to exit without baking");
+ // uiClearButLock();
+ // uiBlockBeginAlign(block);
- }
- else {
+ // if(sb->keys) {
+ // char str[128];
+ // uiDefIconTextBut(block, BUT, B_SOFTBODY_BAKE_FREE, ICON_X, "FREE BAKE", 10, 120,300,20, NULL, 0.0, 0.0, 0, 0, "Free baked result");
+ // sprintf(str, "Stored %d vertices %d keys %.3f MB", sb->totpoint, sb->totkey, ((float)16*sb->totpoint*sb->totkey)/(1024.0*1024.0));
+ // uiDefBut(block, LABEL, 0, str, 10, 100,300,20, NULL, 0.0, 0.0, 00, 0, "");
+ // }
+ // else
+ // uiDefBut(block, BUT, B_SOFTBODY_BAKE, "BAKE", 10, 120,300,20, NULL, 0.0, 0.0, 10, 0, "Start baking. Press ESC to exit without baking");
+ //}
+ //else {
/* GENERAL STUFF */
- static char str[128];
if (sb->totpoint){
sprintf(str, "Vertex Mass; Object mass %f [k]",sb->nodemass*sb->totpoint/1000.0f);
}
@@ -2615,14 +3896,14 @@ static void object_softbodies(Object *ob)
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
uiDefButF(block, NUM, B_DIFF, "Mass:", 160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
- uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_DIFF, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
uiBlockEndAlign(block);
/* GOAL STUFF */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_GOAL, B_SOFTBODY_CHANGE, "Use Goal", 10,120,130,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
- if (ob->softflag & OB_SB_GOAL){
+ uiDefButBitS(block, TOG, OB_SB_GOAL, B_SOFTBODY_CHANGE, "Use Goal", 10,120,130,20, softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+ if (*softflag & OB_SB_GOAL){
if(ob->type==OB_MESH) {
menustr= get_vertexgroup_menustr(ob);
defCount=BLI_countlist(&ob->defbase);
@@ -2656,179 +3937,832 @@ static void object_softbodies(Object *ob)
/* EDGE SPRING STUFF */
if(ob->type!=OB_SURF) {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,50,90,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
- if (ob->softflag & OB_SB_EDGES){
- uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,50,90,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
- uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "CEdge", 220,50,45,20, &ob->softflag, 0, 0, 0, 0, "Edge collide too");
- uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_DIFF, "CFace", 265,50,45,20, &ob->softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning ");
- uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,30,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness");
- uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,30,150,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
- uiDefButS(block, NUM, B_DIFF, "Aero:", 10,10,150,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
+ uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,50,90,20, softflag, 0, 0, 0, 0, "Use Edges as springs");
+ if (*softflag & OB_SB_EDGES){
+ uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
+ uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_DIFF, "CEdge", 220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too");
+ uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_DIFF, "CFace", 265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning ");
+ uiDefButF(block, NUM, B_DIFF, "E Pull:", 10,30,100,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness when longer than rest length");
+ uiDefButF(block, NUM, B_DIFF, "E Push:", 110,30,100,20, &sb->inpush, 0.0, 0.999, 10, 0, "Edge spring stiffness when shorter than rest length");
+ uiDefButF(block, NUM, B_DIFF, "E Damp:", 210,30,100,20, &sb->infrict, 0.0, 50.0, 10, 0, "Edge spring friction");
+
+ uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_SOFTBODY_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and length)");
+ uiDefButS(block, NUM, B_DIFF, "Aero:", 30,10,60,20, &sb->aeroedge, 0.00, 30000.0, 10, 0, "Make edges 'sail'");
+ uiDefButS(block, NUM, B_SOFTBODY_CHANGE, "Plas:", 90,10,60,20, &sb->plastic, 0.0, 100.0, 10, 0, "Permanent deform");
if(ob->type==OB_MESH) {
- uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Rigidity:", 160,10,150,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Strenght of Springs over 2 Edges");
+ uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0, 10.0, 10, 0, "Bendig Stiffness");
+ if (*softflag & OB_SB_QUADS){
+ uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Sh:", 230,10,80,20, &sb->shearstiff, 0.0, 1.0, 10, 0, "Shear Stiffness");
+ }
}
else sb->secondspring = 0;
uiDefBut(block, LABEL, 0, "",10,10,1,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
}
uiBlockEndAlign(block);
}
+ //}
+ }
+ uiBlockEndAlign(block);
+}
+
+ /* Panels for new particles*/
+static void object_panel_particle_children(Object *ob)
+{
+ uiBlock *block;
+ ParticleSystem *psys = psys_get_current(ob);
+ ParticleSettings *part;
+ short butx=0, buty=160, butw=150, buth=20;
+ static short kink_ui=0;
+
+ if (psys==NULL) return;
+ part=psys->part;
+ if(part==NULL) return;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_child", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return;
+ uiNewPanelTabbed("Extras", "Particle");
+
+ uiDefButS(block, MENU, B_PART_ALLOC_CHILD, "Children from:%t|Faces%x2|Particles%x1|None%x0", butx,buty,butw,buth, &part->childtype, 14.0, 0.0, 0, 0, "Create child particles");
+
+ if(part->childtype==0) return;
+
+ if(part->childtype==PART_CHILD_FACES && (psys->flag&(PSYS_HAIR_DONE|PSYS_KEYED))==0) {
+ uiDefBut(block, LABEL, 0, "Hair or keyed", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "particles needed!", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ return;
+ }
+
+ uiBlockBeginAlign(block);
+
+ buty -= buth/2;
+
+ uiDefButI(block, NUM, B_PART_ALLOC_CHILD, "Amount:", butx,(buty-=buth),butw,buth, &part->child_nbr, 0.0, MAX_PART_CHILDREN, 0, 0, "Amount of children/parent");
+ uiDefButI(block, NUM, B_DIFF, "Render Amount:", butx,(buty-=buth),butw,buth, &part->ren_child_nbr, 0.0, MAX_PART_CHILDREN, 0, 0, "Amount of children/parent for rendering");
+
+ if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) {
+ uiDefButF(block, NUMSLI, B_PART_DISTR_CHILD, "VParents:", butx,(buty-=buth),butw,buth, &part->parents, 0.0, 1.0, 1, 3, "Relative amount of virtual parents");
}
+ else {
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Rad:", butx,(buty-=buth),butw,buth, &part->childrad, 0.0, 10.0, 1, 3, "Radius of children around parent");
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Round:", butx,(buty-=buth),butw,buth, &part->childflat, 0.0, 1.0, 1, 3, "Roundness of children around parent");
}
uiBlockEndAlign(block);
+
+ buty -= buth/2;
+
+ /* clump */
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Clump:", butx,(buty-=buth),butw,buth, &part->clumpfac, -1.0, 1.0, 1, 3, "Amount of clumpimg");
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:", butx,(buty-=buth),butw,buth, &part->clumppow, -0.999, 0.999, 1, 3, "Shape of clumpimg");
+ uiBlockEndAlign(block);
+
+ buty -= buth/2;
+
+ uiBlockBeginAlign(block);
+ if(part->draw_as != PART_DRAW_PATH) {
+ uiDefButF(block, NUM, B_PART_REDRAW, "Size:", butx,(buty-=buth),butw/2,buth, &part->childsize, 0.01, 100, 10, 1, "A multiplier for the child particle size");
+ uiDefButF(block, NUM, B_PART_REDRAW, "Rand:", butx+butw/2,buty,butw/2,buth, &part->childrandsize, 0.0, 1.0, 10, 1, "Random variation to the size of the child particles");
+ }
+ if(part->childtype == PART_CHILD_FACES) {
+ uiDefButF(block, NUM, B_PART_REDRAW, "Spread:",butx,(buty-=buth),butw/2,buth, &part->childspread, -1.0, 1.0, 10, 1, "Spread children from the faces");
+ uiDefButBitI(block, TOG, PART_CHILD_SEAMS, B_PART_DISTR_CHILD, "Use Seams", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Use seams to determine parents");
+ }
+ uiBlockEndAlign(block);
+
+ butx=160;
+ buty=180;
+
+ if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED))
+ uiDefButBitS(block, TOG, 1, B_PART_REDRAW, "Kink/Branch", butx,(buty-=buth),butw,buth, &kink_ui, 0, 0, 0, 0, "Show kink and branch options");
+ else
+ buty-=buth;
+
+ if(kink_ui || (psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) == 0) {
+ buty -= buth/2;
+
+ /* kink */
+ uiBlockBeginAlign(block);
+ if(part->kink) {
+ uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Kink:%t|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", butx,(buty-=buth),butw/2,buth, &part->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the path");
+ uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Axis %t|Z %x2|Y %x1|X %x0", butx+butw/2,buty,butw/2,buth, &part->kink_axis, 14.0, 0.0, 0, 0, "Which axis to use for offset");
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Freq:", butx,(buty-=buth),butw,buth, &part->kink_freq, 0.0, 10.0, 1, 3, "The frequency of the offset (1/total length)");
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:", butx,(buty-=buth),butw,buth, &part->kink_shape, -0.999, 0.999, 1, 3, "Adjust the offset to the beginning/end");
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Amplitude:", butx,(buty-=buth),butw,buth, &part->kink_amp, 0.0, 10.0, 1, 3, "The amplitude of the offset");
+ }
+ else {
+ uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Kink:%t|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", butx,(buty-=buth),butw,buth, &part->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the path");
+ buty-=3*buth;
+ }
+ uiBlockEndAlign(block);
+
+ if(part->childtype==PART_CHILD_PARTICLES && psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) {
+ if(part->flag & PART_BRANCHING) {
+ uiDefButBitI(block, TOG, PART_BRANCHING, B_PART_RECALC_CHILD, "Branching", butx,(buty-=2*buth),butw,buth, &part->flag, 0, 0, 0, 0, "Branch child paths from eachother");
+ uiDefButBitI(block, TOG, PART_ANIM_BRANCHING, B_PART_RECALC_CHILD, "Animated", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Animate branching");
+ uiDefButBitI(block, TOG, PART_SYMM_BRANCHING, B_PART_RECALC_CHILD, "Symmetric", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Start and end points are the same");
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Threshold:", butx,(buty-=buth),butw,buth, &part->branch_thres, 0.0, 1.0, 1, 3, "Threshold of branching");
+ }
+ else
+ uiDefButBitI(block, TOG, PART_BRANCHING, B_PART_RECALC_CHILD, "Branching", butx,(buty-=2*buth),butw,buth, &part->flag, 0, 0, 0, 0, "Branch child paths from eachother");
+ }
+ }
+ else {
+ /* rough */
+ buty -= buth/2;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Rough1:", butx,(buty-=buth),butw,buth, &part->rough1, 0.0, 10.0, 1, 3, "Amount of location dependant rough");
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Size1:", butx,(buty-=buth),butw,buth, &part->rough1_size, 0.01, 10.0, 1, 3, "Size of location dependant rough");
+ uiBlockEndAlign(block);
+ buty -= buth/2;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Rough2:", butx,(buty-=buth),butw,buth, &part->rough2, 0.0, 10.0, 1, 3, "Amount of random rough");
+ uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Size2:", butx,(buty-=buth),butw,buth, &part->rough2_size, 0.01, 10.0, 1, 3, "Size of random rough");
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Thresh:", butx,(buty-=buth),butw,buth, &part->rough2_thres, 0.00, 1.0, 1, 3, "Amount of particles left untouched by random rough");
+ uiBlockEndAlign(block);
+ buty -= buth/2;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "RoughE:", butx,(buty-=buth),butw,buth, &part->rough_end, 0.0, 10.0, 1, 3, "Amount of end point rough");
+ uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:", butx,(buty-=buth),butw,buth, &part->rough_end_shape, 0.0, 10.0, 1, 3, "Shape of end point rough");
+ uiBlockEndAlign(block);
+ }
}
+static void particle_set_vg(void *ob_v, void *vgnum_v)
+{
+ Object *ob= ob_v;
+ ParticleSystem *psys=psys_get_current(ob);
+ short vgnum = *((short *)vgnum_v);
-static void object_panel_particles_motion(Object *ob)
+ if(vgnum==PSYS_VG_DENSITY)
+ psys->recalc|=PSYS_DISTR;
+ else if(vgnum!=PSYS_VG_SIZE)
+ psys->recalc|=PSYS_INIT;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+}
+static void particle_del_vg(void *ob_v, void *vgnum_v)
+{
+ Object *ob= ob_v;
+ ParticleSystem *psys=psys_get_current(ob);
+ short vgnum = *((short *)vgnum_v);
+
+ if(vgnum==PSYS_VG_DENSITY) {
+ psys->recalc|=PSYS_DISTR;
+ }
+
+ psys->vgroup[vgnum]=0;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+}
+static void object_panel_particle_extra(Object *ob)
{
uiBlock *block;
uiBut *but;
- PartEff *paf= give_parteff(ob);
-
- if (paf==NULL) return;
+ ParticleSystem *psys=psys_get_current(ob);
+ ParticleSettings *part;
+ short butx=0, buty=160, butw=150, buth=20;
+ static short vgnum=0;
+
+ if (psys==NULL) return;
+ part=psys->part;
+ if(part==NULL) return;
- block= uiNewBlock(&curarea->uiblocks, "object_panel_particles_motion", UI_EMBOSS, UI_HELV, curarea->win);
- uiNewPanelTabbed("Particles ", "Physics");
- if(uiNewPanel(curarea, block, "Particle Motion", "Physics", 320, 0, 318, 204)==0) return;
-
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- /* top row */
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_extra", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Extras", "Particle", 980, 0, 318, 204)==0) return;
+
+ uiDefBut(block, LABEL, 0, "Effectors:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_CALCEFFECT, "Keys:", 0,180,75,20, &paf->totkey, 1.0, 100.0, 0, 0, "Specify the number of key positions");
- uiDefButBitS(block, TOG, PAF_BSPLINE, B_CALCEFFECT, "Bspline", 75,180,75,20, &paf->flag, 0, 0, 0, 0, "Use B spline formula for particle interpolation");
- uiDefButI(block, NUM, B_CALCEFFECT, "Seed:", 150,180,75,20, &paf->seed, 0.0, 255.0, 0, 0, "Set an offset in the random table");
- uiDefButF(block, NUM, B_CALCEFFECT, "RLife:", 225,180,85,20, &paf->randlife, 0.0, 2.0, 10, 1, "Give the particlelife a random variation");
+ uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_PART_RECALC, "GR:", butx, (buty-=buth), butw/2, buth, &part->eff_group, "Limit effectors to this Group");
+ uiDefButBitI(block, TOG, PART_SIZE_DEFL, B_PART_RECALC, "Size Deflect", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Use particle's size in deflection");
+ uiDefButBitI(block, TOG, PART_DIE_ON_COL, B_PART_RECALC, "Die on hit",butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Particles die when they collide with a deflector object");
+ uiDefButBitI(block, TOG, PART_STICKY, B_PART_RECALC, "Sticky", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Particles stick to collided objects if they die in the collision");
uiBlockEndAlign(block);
-
- /* left collumn */
- uiDefBut(block, LABEL, 0, "Velocity:", 0,160,150,20, NULL, 0.0, 0, 0, 0, "");
+
+ uiDefBut(block, LABEL, 0, "Time:", butx,(buty-=buth),butw/3,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiBlockSetCol(block, TH_BUT_SETTING2);
- uiDefButF(block, NUM, B_CALCEFFECT, "Normal:", 0,140,150,18, &paf->normfac, -2.0, 2.0, 1, 3, "Let the mesh give the particle a starting speed");
- uiDefButF(block, NUM, B_CALCEFFECT, "Object:", 0,122,150,18, &paf->obfac, -1.0, 1.0, 1, 3, "Let the object give the particle a starting speed");
- uiDefButF(block, NUM, B_CALCEFFECT, "Random:", 0,104,150,18, &paf->randfac, 0.0, 2.0, 1, 3, "Give the startingspeed a random variation");
- uiDefButF(block, NUM, B_CALCEFFECT, "Texture:", 0,86,150,18, &paf->texfac, 0.0, 2.0, 1, 3, "Let the texture give the particle a starting speed");
- uiDefButF(block, NUM, B_CALCEFFECT, "Damping:", 0,68,150,18, &paf->damp, 0.0, 1.0, 1, 3, "Specify the damping factor");
- uiBlockSetCol(block, TH_AUTO);
- but=uiDefBut(block, TEX, B_PAF_SET_VG1, "VGroup:", 0,50,150,18, paf->vgroupname_v, 0, 31, 0, 0, "Name of vertex group to use for speed control");
- uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)OBACT);
+ uiDefButBitI(block, TOG, PART_GLOB_TIME, B_PART_RECALC, "Global", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Set all ipos that work on particles to be calculated in global/object time");
+ uiDefButBitI(block, TOG, PART_ABS_TIME, B_PART_RECALC, "Absolute", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Set all ipos that work on particles to be calculated in absolute/relative time");
+
+ //if(part->flag & PART_LOOP){
+ // uiDefButBitI(block, TOG, PART_LOOP, B_PART_RECALC, "Loop", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Loop particle lives");
+ // uiDefButBitI(block, TOG, PART_LOOP_INSTANT, B_PART_RECALC, "Instantly", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Loop particle life at time of death");
+ //}
+ //else
+ uiDefButBitI(block, TOG, PART_LOOP, B_PART_RECALC, "Loop", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Loop particle lives");
+
+ uiDefButF(block, NUM, B_PART_RECALC, "Tweak:", butx,(buty-=buth),butw,buth, &part->timetweak, 0.0, 10.0, 1, 0, "A multiplier for physics timestep (1.0 means one frame = 1/25 seconds)");
uiBlockEndAlign(block);
+
+ if(ob->type==OB_MESH) {
+ char *menustr= get_vertexgroup_menustr(ob);
+ int defCount=BLI_countlist(&ob->defbase);
+ if(defCount==0) psys->vgroup[vgnum]= 0;
+
+ uiDefBut(block, LABEL, 0, "Vertex group:", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+
+ uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|Effector%x11|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
+ but=uiDefButBitS(block, TOG, (1<<vgnum), B_PART_RECALC, "Neg", butx+butw-40,buty,40,buth, &psys->vg_neg, 0, 0, 0, 0, "Negate the effect of the vertex group");
+ uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
+
+ butx+=butw;
+
+ but= uiDefButS(block, MENU, B_PART_RECALC, menustr, butx,buty,buth,buth, psys->vgroup+vgnum, 0, defCount, 0, 0, "Browses available vertex groups");
+ uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
+ MEM_freeN (menustr);
+
+ if(psys->vgroup[vgnum]) {
+ bDeformGroup *defGroup = BLI_findlink(&ob->defbase, psys->vgroup[vgnum]-1);
+ if(defGroup)
+ uiDefBut(block, BUT, B_PART_REDRAW, defGroup->name, butx+buth,buty,butw-2*buth,buth, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
+ else{
+ uiDefBut(block, BUT, B_PART_REDRAW, "(no group)", butx+buth,buty,butw-2*buth,buth, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
+ }
+ but=uiDefIconBut(block, BUT, B_PART_RECALC, ICON_X, butx+butw-buth,buty,buth,buth, 0, 0, 0, 0, 0, "Disable use of vertex group");
+ uiButSetFunc(but, particle_del_vg, (void *)ob, (void *)(&vgnum));
+ }
+
+ uiBlockEndAlign(block);
+ }
- uiDefBut(block, LABEL, 0, "Texture Emission", 0,30,150,20, NULL, 0.0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG3, PAF_TEXTIME, B_CALCEFFECT, "TexEmit", 0,10,75,20, &(paf->flag2), 0, 0, 0, 0, "Use a texture to define emission of particles");
- uiDefButS(block, NUM, B_CALCEFFECT, "Tex:", 75,10,75,20, &paf->timetex, 1.0, 10.0, 0, 0, "Specify texture used for the texture emission");
+ buty=butx=160;
+
+ uiDefButI(block, NUM, B_PART_DISTR, "Seed:", butx,(buty-=buth),butw,buth, &psys->seed, 0.0, 255.0, 1, 0, "Set an offset in the random table");
+ if(part->type == PART_HAIR) {
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_PART_RECALC, "Stiff:", butx,(buty-=buth),(butw*3)/5,buth, &part->eff_hair, 0.0, 1.0, 0, 0, "Hair stiffness for effectors");
+ uiDefButBitI(block, TOG, PART_CHILD_EFFECT, B_PART_RECALC, "Children", butx+(butw*3)/5,buty,(butw*2)/5,buth, &part->flag, 0, 0, 0, 0, "Apply effectors to children");
+ uiBlockEndAlign(block);
+ }
+ else
+ buty-=buth;
+
+ /* size changes must create a recalc event always so that sizes are updated properly */
+ uiDefButF(block, NUM, B_PART_RECALC, "Size:", butx,(buty-=buth),butw,buth, &part->size, 0.01, 100, 10, 1, "The size of the particles");
+ uiDefButF(block, NUM, B_PART_RECALC, "Rand:", butx,(buty-=buth),butw,buth, &part->randsize, 0.0, 2.0, 10, 1, "Give the particle size a random variation");
+
+ uiDefButBitI(block, TOG, PART_SIZEMASS, B_PART_RECALC, "Mass from size", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Multiply mass with particle size");
+ uiDefButF(block, NUM, B_PART_RECALC, "Mass:", butx,(buty-=buth),butw,buth, &part->mass, 0.01, 100, 10, 1, "Specify the mass of the particles");
+}
+/* copy from buttons_shading.c */
+static void autocomplete_uv(char *str, void *arg_v)
+{
+ Mesh *me;
+ CustomDataLayer *layer;
+ AutoComplete *autocpl;
+ int a;
+
+ if(str[0]==0)
+ return;
+
+ autocpl= autocomplete_begin(str, 32);
+
+ /* search if str matches the beginning of name */
+ for(me= G.main->mesh.first; me; me=me->id.next)
+ for(a=0, layer= me->fdata.layers; a<me->fdata.totlayer; a++, layer++)
+ if(layer->type == CD_MTFACE)
+ autocomplete_do_name(autocpl, layer->name);
- /* right collumn */
- uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_CALCEFFECT, "GR:", 160, 155, 150, 20, &paf->group, "Limit Force Fields to this Group");
+ autocomplete_end(autocpl, str);
+}
+static void object_panel_particle_visual(Object *ob)
+{
+ uiBlock *block;
+ uiBut *but;
+ ParticleSystem *psys=psys_get_current(ob);
+ ParticleSettings *part;
+ short butx=0, buty=160, butw=150, buth=20;
+ static short bbuvnum=0;
+
+ if (psys==NULL) return;
+ part=psys->part;
+ if(part==NULL) return;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_visual", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Visualization", "Particle", 640, 0, 318, 204)==0) return;
+
+ uiDefButS(block, MENU, B_PART_RECALC, "Billboard %x9|Group %x8|Object %x7|Path %x6|Line %x5|Axis %x4|Cross %x3|Circle %x2|Point %x1|None %x0", butx,buty,butw,buth, &part->draw_as, 14.0, 0.0, 0, 0, "How particles are visualized");
+
+ if(part->draw_as==PART_DRAW_NOT) {
+ uiDefButBitS(block, TOG, PART_DRAW_EMITTER, B_PART_REDRAW, "Render emitter", butx,(buty-=2*buth),butw,buth, &part->draw, 0, 0, 0, 0, "Render emitter object");
+ return;
+ }
+ uiDefBut(block, LABEL, 0, "Draw:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, 0, "Force:", 160,130,75,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_CALCEFFECT, "X:", 235,130,75,20, paf->force, -1.0, 1.0, 1, 2, "Specify the X axis of a continues force");
- uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 160,110,75,20, paf->force+1,-1.0, 1.0, 1, 2, "Specify the Y axis of a continues force");
- uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 235,110,75,20, paf->force+2, -1.0, 1.0, 1, 2, "Specify the Z axis of a continues force");
-
+ uiDefButBitS(block, TOG, PART_DRAW_VEL, B_PART_REDRAW, "Vel", butx,(buty-=buth),butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle velocity");
+ uiDefButBitS(block, TOG, PART_DRAW_SIZE, B_PART_REDRAW, "Size", butx+butw/3,buty,butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle size");
+ uiDefButBitS(block, TOG, PART_DRAW_NUM, B_PART_REDRAW, "Num", butx+2*butw/3,buty,butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle number");
+ uiDefButS(block, NUM, B_PART_REDRAW, "Draw Size:", butx,(buty-=buth),butw,buth, &part->draw_size, 0.0, 10.0, 0, 0, "Size of particles on viewport in pixels (0=default)");
+ uiDefButS(block, NUM, B_PART_RECALC_CHILD, "Disp:", butx,(buty-=buth),butw,buth, &part->disp, 0.0, 100.0, 10, 0, "Percentage of particles to display in 3d view");
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL, 0, "Render:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_CALCEFFECT, "Tex:", 160,80,75,20, &paf->speedtex, 1.0, 10.0, 0, 2, "Specify the texture used for force");
- uiDefButF(block, NUM, B_CALCEFFECT, "X:", 235,80,75,20, paf->defvec, -1.0, 1.0, 1, 2, "Specify the X axis of a force, determined by the texture");
- uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 160,60,75,20, paf->defvec+1,-1.0, 1.0, 1, 2, "Specify the Y axis of a force, determined by the texture");
- uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 235,60,75,20, paf->defvec+2, -1.0, 1.0, 1, 2, "Specify the Z axis of a force, determined by the texture");
-
+ uiDefButS(block, NUM, B_PART_DISTR, "Material:", butx,(buty-=buth),butw-30,buth, &part->omat, 1.0, 16.0, 0, 0, "Specify material used for the particles");
+ uiDefButBitS(block, TOG, PART_DRAW_MAT_COL, B_PART_RECALC, "Col", butx+butw-30,buty,30,buth, &part->draw, 0, 0, 0, 0, "Draw particles using material's diffuse color");
+ uiDefButBitS(block, TOG, PART_DRAW_EMITTER, B_PART_REDRAW, "Emitter", butx,(buty-=buth),butw/2,buth, &part->draw, 0, 0, 0, 0, "Render emitter Object also");
+ uiDefButBitS(block, TOG, PART_DRAW_PARENT, B_PART_REDRAW, "Parents", butx+butw/2,buty,butw/2,buth, &part->draw, 0, 0, 0, 0, "Render parent particles");
+ uiDefButBitI(block, TOG, PART_UNBORN, B_PART_REDRAW, "Unborn", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Show particles before they are emitted");
+ uiDefButBitI(block, TOG, PART_DIED, B_PART_REDRAW, "Died", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Show particles after they have died");
+
+ uiBlockEndAlign(block);
+
+ butx=160;
+ buty=160-buth;
+
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_CALCEFFECT, "Int", 160,30,50,20, &paf->texmap, 14.0, 0.0, 0, 0, "Use texture intensity as a factor for texture force");
- uiDefButS(block, ROW, B_CALCEFFECT, "RGB", 210,30,50,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed vector");
- uiDefButS(block, ROW, B_CALCEFFECT, "Grad", 260,30,50,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed vector");
-
- uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 160,10,150,20, &paf->nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation");
+
+ switch(part->draw_as) {
+ case PART_DRAW_OB:
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PART_REDRAW_DEPS, "OB:", butx,(buty-=buth),butw,buth, &part->dup_ob, "Show this Object in place of particles");
+ break;
+ case PART_DRAW_GR:
+ uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_PART_REDRAW_DEPS, "GR:", butx,(buty-=buth),butw,buth, &part->dup_group, "Show Objects in this Group in place of particles");
+ uiDefButBitS(block, TOG, PART_DRAW_WHOLE_GR, B_PART_REDRAW, "Dupli Group", butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Use whole group at once");
+ if((part->draw & PART_DRAW_WHOLE_GR)==0)
+ uiDefButBitS(block, TOG, PART_DRAW_RAND_GR, B_PART_REDRAW, "Pick Random", butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Pick objects from group randomly");
+ break;
+ case PART_DRAW_BB:
+ uiDefButBitS(block, TOG, PART_DRAW_BB_LOCK, B_PART_REDRAW, "Lock", butx,(buty+=buth),butw/2,buth, &part->draw, 0, 0, 0, 0, "Lock the billboards align axis");
+ uiDefButS(block, MENU, B_PART_REDRAW, "Align to%t|Velocity%x4|View%x3|Z%x2|Y%x1|X%x0", butx+butw/2,buty,butw/2,buth, &part->bb_align, 14.0, 0.0, 0, 0, "In respect to what the billboards are aligned");
+ uiDefButF(block, NUM, B_PART_REDRAW, "Tilt:", butx,(buty-=buth),butw/2,buth, &part->bb_tilt, -1.0, 1.0, 0, 0, "Tilt of the billboards");
+ uiDefButF(block, NUM, B_PART_REDRAW, "Rand:", butx+butw/2,buty,butw/2,buth, &part->bb_rand_tilt, 0.0, 1.0, 0, 0, "Random tilt of the billboards");
+ uiDefButS(block, NUM, B_PART_REDRAW, "UV Split:", butx,(buty-=buth),butw,buth, &part->bb_uv_split, 1.0, 10.0, 0, 0, "Amount of rows/columns to split uv coordinates for billboards");
+ uiDefButS(block, MENU, B_PART_REDRAW, "Animate%t|Angle%x2|Time%x1|None%x0", butx,(buty-=buth),butw/2,buth, &part->bb_anim, 14.0, 0.0, 0, 0, "How to animate billboard textures");
+ uiDefButS(block, MENU, B_PART_REDRAW, "Offset%t|Random%x2|Linear%x1|None%x0", butx+butw/2,buty,butw/2,buth, &part->bb_split_offset, 14.0, 0.0, 0, 0, "How to offset billboard textures");
+ uiDefButF(block, NUM, B_PART_REDRAW, "OffsetX:", butx,(buty-=buth),butw,buth, part->bb_offset, -1.0, 1.0, 0, 0, "Offset billboards horizontally");
+ uiDefButF(block, NUM, B_PART_REDRAW, "OffsetY:", butx,(buty-=buth),butw,buth, part->bb_offset+1, -1.0, 1.0, 0, 0, "Offset billboards vertically");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PART_REDRAW, "OB:", butx,(buty-=buth),butw,buth, &part->bb_ob, "Billboards face this object (default is active camera)");
+ uiDefButS(block, MENU, B_PART_REDRAW, "UV channel%t|Split%x2|Time-Index (X-Y)%x1|Normal%x0", butx,(buty-=buth),butw,buth, &bbuvnum, 14.0, 0.0, 0, 0, "UV channel");
+ but=uiDefBut(block, TEX, B_PART_REDRAW, "UV:", butx,(buty-=buth),butw,buth, psys->bb_uvname+bbuvnum, 0, 31, 0, 0, "Set name of UV layer to use with billboards, default is active UV layer");
+ uiButSetCompleteFunc(but, autocomplete_uv, NULL);
+ break;
+ case PART_DRAW_LINE:
+ uiDefButBitS(block, TOG, PART_DRAW_VEL_LENGTH, B_PART_REDRAW, "Speed", butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Multiply line length by particle speed");
+ uiDefButF(block, NUM, B_PART_REDRAW, "Back:", butx,(buty-=buth),butw,buth, &part->draw_line[0], 0.0, 10.0, 0, 0, "Length of the line's tail");
+ uiDefButF(block, NUM, B_PART_REDRAW, "Front:", butx,(buty-=buth),butw,buth, &part->draw_line[1], 0.0, 10.0, 0, 0, "Length of the line's head");
+ break;
+ case PART_DRAW_PATH:
+ if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)) {
+ uiDefButS(block, NUM, B_PART_RECALC, "Steps:", butx,(buty+=buth),butw,buth, &part->draw_step, 0.0, 7.0, 0, 0, "How many steps paths are drawn with (power of 2)");
+ uiDefButS(block, NUM, B_PART_REDRAW, "Render:", butx,(buty-=buth),butw,buth, &part->ren_step, 0.0, 9.0, 0, 0, "How many steps paths are rendered with (power of 2)");
+
+ uiDefButBitI(block, TOG, PART_ABS_LENGTH, B_PART_RECALC, "Abs Length", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Use maximum length in absolute blender units");
+ uiDefButF(block, NUM, B_PART_RECALC, "Max Length:", butx,(buty-=buth),butw,buth, &part->abslength, 0.0, 10000.0, 1, 3, "Absolute path length");
+ uiDefButF(block, NUMSLI, B_PART_RECALC, "RLength:", butx,(buty-=buth),butw,buth, &part->randlength, 0.0, 1.0, 1, 3, "Give path length a random variation");
+ uiBlockEndAlign(block);
+
+ uiDefButBitI(block, TOG, PART_HAIR_BSPLINE, B_PART_RECALC, "B-Spline", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Interpolate hair using B-Splines");
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PART_DRAW_REN_STRAND, B_PART_REDRAW, "Strand render", butx,buty-=buth,butw,buth, &part->draw, 0, 0, 0, 0, "Use the strand primitive for rendering");
+ if(part->draw & PART_DRAW_REN_STRAND) {
+ uiDefButS(block, NUM, B_PART_REDRAW, "Angle:", butx,(buty-=buth),butw,buth, &part->adapt_angle, 0.0, 45.0, 0, 0, "How many degrees path has to curve to make another render segment");
+ }
+ else {
+ uiDefButBitS(block, TOG, PART_DRAW_REN_ADAPT, B_PART_REDRAW, "Adaptive render", butx,buty-=buth,butw,buth, &part->draw, 0, 0, 0, 0, "Draw steps of the particle path");
+ if(part->draw & PART_DRAW_REN_ADAPT) {
+ uiDefButS(block, NUM, B_PART_REDRAW, "Angle:", butx,(buty-=buth),butw/2,buth, &part->adapt_angle, 0.0, 45.0, 0, 0, "How many degrees path has to curve to make another render segment");
+ uiDefButS(block, NUM, B_PART_REDRAW, "Pixel:", butx+butw/2,buty,(butw+1)/2,buth, &part->adapt_pix, 0.0, 50.0, 0, 0, "How many pixels path has to cover to make another render segment");
+ }
+ }
+ }
+ else {
+ uiDefBut(block, LABEL, 0, "Hair or keyed", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "particles needed!", butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ }
+ break;
+ }
+ uiBlockEndAlign(block);
+}
+static void object_panel_particle_simplification(Object *ob)
+{
+ uiBlock *block;
+ ParticleSystem *psys=psys_get_current(ob);
+ ParticleSettings *part;
+ short butx=0, buty=160, butw=150, buth=20;
+
+ if (psys==NULL) return;
+ part=psys->part;
+ if(part==NULL) return;
+
+ if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
+ return;
+ if(part->childtype!=PART_CHILD_FACES)
+ return;
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_simplification", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Visualization", "Particle");
+ if(uiNewPanel(curarea, block, "Simplification", "Particle", 640, 0, 318, 204)==0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PART_SIMPLIFY_ENABLE, B_PART_REDRAW, "Child Simplification", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object becomes smaller on the screen");
+ uiBlockEndAlign(block);
+ if(part->simplify_flag & PART_SIMPLIFY_ENABLE) {
+ buty -= 10;
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_NOP, "Reference Size:", butx,(buty-=buth),butw,buth, &part->simplify_refsize, 1.0, 32768.0, 0, 0, "Reference size size in pixels, after which simplification begins");
+ uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_rate, 0.0, 1.0, 0, 0, "Speed of simplification");
+ uiDefButF(block, NUM, B_NOP, "Transition:", butx,(buty-=buth),butw,buth, &part->simplify_transition, 0.0, 1.0, 0, 0, "Transition period for fading out strands");
+ uiBlockEndAlign(block);
+
+ buty -= 10;
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, PART_SIMPLIFY_VIEWPORT, B_PART_REDRAW, "Viewport", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object goes outside the viewport");
+ uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_viewport, 0.0, 0.999, 0, 0, "Speed of simplification");
+ uiBlockEndAlign(block);
+ }
+ uiBlockEndAlign(block);
+}
+static void boidrule_moveDown(void *part_v, void *rule_v)
+{
+ ParticleSettings *part = part_v;
+ char r, *rule = rule_v;
+
+ int n= rule - part->boidrule;
+
+ if(n+1 < BOID_TOT_RULES) {
+ r=part->boidrule[n];
+ part->boidrule[n]=part->boidrule[n+1];
+ part->boidrule[n+1]=r;
+ }
}
+static void boidrule_moveUp(void *part_v, void *rule_v)
+{
+ ParticleSettings *part = part_v;
+ char r, *rule = rule_v;
+ int n= rule - part->boidrule;
-static void object_panel_particles(Object *ob)
+ if(n-1 >= 0) {
+ r=part->boidrule[n];
+ part->boidrule[n]=part->boidrule[n-1];
+ part->boidrule[n-1]=r;
+ }
+}
+static void object_panel_particle_physics(Object *ob)
{
uiBlock *block;
uiBut *but;
- PartEff *paf= give_parteff(ob);
+ ParticleSystem *psys=psys_get_current(ob);
+ ParticleSettings *part;
+ short butx=0, buty=160, butw=150, buth=20;
+
+ if (psys==NULL) return;
- /* the panelname "Particles " has a space to exclude previous saved panel "Particles" */
- block= uiNewBlock(&curarea->uiblocks, "object_panel_particles", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Particles ", "Physics", 320, 0, 318, 204)==0) return;
+ part=psys->part;
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ if(part==NULL) return;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_physics", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Physics", "Particle", 320, 0, 318, 204)==0) return;
+
+ if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
- if (ob->type == OB_MESH) {
+ if(psys->flag & PSYS_EDITED || psys->flag & PSYS_PROTECT_CACHE) {
+ uiSetButLock(1, "Hair is edited or cache is protected!");
+ }
+
+ if(part->phystype==PART_PHYS_KEYED){
uiBlockBeginAlign(block);
- if(paf==NULL)
- uiDefBut(block, BUT, B_NEWEFFECT, "NEW", 0,180,75,20, 0, 0, 0, 0, 0, "Create a new Particle effect");
- else
- uiDefBut(block, BUT, B_DELEFFECT, "Delete", 0,180,75,20, 0, 0, 0, 0, 0, "Delete the effect");
+ uiDefButBitI(block, TOG, PSYS_FIRST_KEYED, B_PART_RECALC, "First", butx,buty,45,buth, &psys->flag, 0, 0, 0, 0, "Sets the system to be the starting point of keyed particles");
+ uiDefButS(block, MENU, B_PART_RECALC, "Physics %t|Boids%x3|Keyed %x2|Newtonian %x1|None %x0", butx+45,buty,butw-45,buth, &part->phystype, 14.0, 0.0, 0, 0, "Select particle physics type");
+ uiBlockEndAlign(block);
}
- else uiDefBut(block, LABEL, 0, "Only Mesh Objects can generate particles", 10,180,300,20, NULL, 0.0, 0, 0, 0, "");
-
-
- if(paf==NULL) return;
-
- uiDefBut(block, BUT, B_RECALCAL, "RecalcAll", 75,180,75,20, 0, 0, 0, 0, 0, "Update all particle systems");
- uiBlockEndAlign(block);
-
- uiDefBut(block, LABEL, 0, "Emit:", 0,150,75,20, NULL, 0.0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, B_CALCEFFECT, "Amount:", 0,130,150,20, &paf->totpart, 1.0, 100000.0, 0, 0, "The total number of particles");
- if(paf->flag & PAF_STATIC) {
- uiDefButS(block, NUM, REDRAWVIEW3D, "Step:", 0,110,150,20, &paf->staticstep, 1.0, 100.0, 10, 0, "For static duplicators, the Step value skips particles");
+ else
+ uiDefButS(block, MENU, B_PART_RECALC, "Physics%t|Boids%x3|Keyed%x2|Newtonian%x1|None%x0", butx,buty,butw,buth, &part->phystype, 14.0, 0.0, 0, 0, "Select particle physics type");
+
+ if(part->phystype==PART_PHYS_BOIDS) {
+ int i;
+ char *rules[BOID_TOT_RULES] = {"Collision", "Avoid", "Crowd", "Center", "AvVel", "Velocity", "Goal", "Level"};
+ char *ruletext[BOID_TOT_RULES] = {
+ "Avoid deflector objects",
+ "Avoid predators",
+ "Avoid other boids",
+ "Get to flock center",
+ "Maintain average velocity",
+ "Match velocity of nearby boids",
+ "Seek goal",
+ "Keep the Z level"
+ };
+ /* left column */
+ uiDefBut(block, LABEL, 0, "Behaviour:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ for(i=0; i<BOID_TOT_RULES; i++) {
+ uiBlockSetCol(block, TH_BUT_ACTION);
+
+ but = uiDefIconBut(block, BUT, B_PART_RECALC, VICON_MOVE_UP, butx, (buty-=buth), 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move rule up");
+ uiButSetFunc(but, boidrule_moveUp, part, part->boidrule+i);
+
+ but = uiDefIconBut(block, BUT, B_PART_RECALC, VICON_MOVE_DOWN, butx+20, buty, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move rule down");
+ uiButSetFunc(but, boidrule_moveDown, part, part->boidrule+i);
+
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+
+ uiDefButF(block, NUM, B_PART_RECALC, rules[part->boidrule[i]], butx+40,buty,butw-40,buth, part->boidfac+part->boidrule[i], -1.0, 2.0, 1, 3, ruletext[part->boidrule[i]]);
+ }
+ uiBlockSetCol(block, TH_AUTO);
+ uiBlockEndAlign(block);
+
+ buty=140;
+ butx=160;
+
+ uiDefBut(block, LABEL, 0, "Physics:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, PART_BOIDS_2D, B_PART_RECALC, "2D", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Constrain boids to a surface");
+ uiDefButF(block, NUM, B_PART_RECALC, "MaxVelocity:", butx,(buty-=buth),butw,buth, &part->max_vel, 0.0, 200.0, 1, 3, "Maximum velocity");
+ uiDefButF(block, NUM, B_PART_RECALC, "AvVelocity:", butx,(buty-=buth),butw,buth, &part->average_vel, 0.0, 1.0, 1, 3, "The usual speed % of max velocity");
+ uiDefButF(block, NUM, B_PART_RECALC, "LatAcc:", butx,(buty-=buth),butw,buth, &part->max_lat_acc, 0.0, 1.0, 1, 3, "Lateral acceleration % of max velocity");
+ uiDefButF(block, NUM, B_PART_RECALC, "TanAcc:", butx,(buty-=buth),butw,buth, &part->max_tan_acc, 0.0, 1.0, 1, 3, "Tangential acceleration % of max velocity");
+ if(part->flag & PART_BOIDS_2D) {
+ uiDefButF(block, NUM, B_PART_RECALC, "GroundZ:", butx,(buty-=buth),butw,buth, &part->groundz, -100.0, 100.0, 1, 3, "Default Z value");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:", butx,(buty-=buth),butw,buth, &psys->keyed_ob, "Constrain boids to object's surface");
+ }
+ else {
+ uiDefButF(block, NUM, B_PART_RECALC, "Banking:", butx,(buty-=buth),butw,buth, &part->banking, -10.0, 10.0, 1, 3, "Banking of boids on turns (1.0==natural banking)");
+ uiDefButF(block, NUM, B_PART_RECALC, "MaxBank:", butx,(buty-=buth),butw,buth, &part->max_bank, 0.0, 1.0, 1, 3, "How much a boid can bank at a single step");
+ }
+ uiBlockEndAlign(block);
+ uiDefButS(block, NUM, B_PART_RECALC, "N:", butx,(buty-=buth),butw,buth, &part->boidneighbours, 1.0, 10.0, 1, 3, "How many neighbours to consider for each boid");
}
else {
- uiDefButF(block, NUM, B_CALCEFFECT, "Sta:", 0,110,75,20, &paf->sta, -250.0, MAXFRAMEF, 100, 1, "Frame # to start emitting particles");
- uiDefButF(block, NUM, B_CALCEFFECT, "End:", 75,110,75,20, &paf->end, 1.0, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
+ /* left column */
+ uiDefBut(block, LABEL, 0, "Initial velocity:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+ uiDefButF(block, NUM, B_PART_RECALC, "Object:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->obfac, -1.0, 1.0, 1, 3, "Let the object give the particle a starting speed");
+ uiDefButF(block, NUM, B_PART_RECALC, "Normal:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->normfac, -200.0, 200.0, 1, 3, "Let the surface normal give the particle a starting speed");
+ uiDefButF(block, NUM, B_PART_RECALC, "Random:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->randfac, 0.0, 200.0, 1, 3, "Give the starting speed a random variation");
+ if(part->type==PART_REACTOR) {
+ uiDefButF(block, NUM, B_PART_RECALC, "Particle:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->partfac, -10.0, 10.0, 1, 3, "Let the target particle give the particle a starting speed");
+ uiDefButF(block, NUM, B_PART_RECALC, "Reactor:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->reactfac, -10.0, 10.0, 1, 3, "Let the vector away from the target particles location give the particle a starting speed");
+ }
+ else {
+ uiDefButF(block, NUM, B_PART_RECALC, "Tan:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->tanfac, -200.0, 200.0, 1, 3, "Let the surface tangent give the particle a starting speed");
+ uiDefButF(block, NUM, B_PART_RECALC, "Rot:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->tanphase, -1.0, 1.0, 1, 3, "Rotate the surface tangent");
+ }
+ uiBlockSetCol(block, TH_AUTO);
+ uiBlockEndAlign(block);
+
+ buty=160;
+ butx=160;
+
+ if(part->phystype==PART_PHYS_NEWTON)
+ uiDefButS(block, MENU, B_PART_RECALC, "Integration%t|RK4%x2|Midpoint%x1|Euler%x0", butx,buty,butw,buth, &part->integrator, 14.0, 0.0, 0, 0, "Select physics integrator type");
+
+ uiDefBut(block, LABEL, 0, "Rotation:", butx, (buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, PART_ROT_DYN, B_PART_RECALC, "Dynamic", butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->flag, 0, 0, 0, 0, "Sets rotation to dynamic/constant");
+ uiDefButS(block, MENU, B_PART_RECALC, "Rotation%t|Object Z%x8|Object Y%x7|Object X%x6|Global Z%x5|Global Y%x4|Global X%x3|Velocity%x2|Normal%x1|None%x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Particles initial rotation");
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+ uiDefButF(block, NUM, B_PART_RECALC, "Random:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->randrotfac, 0.0, 1.0, 1, 3, "Randomize rotation");
+ uiDefButF(block, NUM, B_PART_RECALC, "Phase:", butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase");
+ uiDefButF(block, NUM, B_PART_RECALC, "Rand:", butx+butw/2,buty,butw/2,buth*4/5, &part->randphasefac, 0.0, 1.0, 1, 3, "Randomize rotation phase");
+ uiBlockSetCol(block, TH_AUTO);
+
+ uiDefButS(block, MENU, B_PART_RECALC, "Angular v %t|Random%x2|Spin%x1|None%x0", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avemode, 14.0, 0.0, 0, 0, "Select particle angular velocity mode");
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+ if(ELEM(part->avemode,PART_AVE_RAND,PART_AVE_SPIN))
+ uiDefButF(block, NUM, B_PART_RECALC, "Angular v:", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount");
+ uiBlockSetCol(block, TH_AUTO);
+ uiBlockEndAlign(block);
+
+ if(part->phystype==PART_PHYS_NEWTON) {
+ butx=0;
+ buty=40;
+ uiDefBut(block, LABEL, 0, "Global effects:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
+
+ butw=103;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_PART_RECALC, "AccX:", butx,(buty-=buth),butw,buth, part->acc, -200.0, 200.0, 10, 0, "Specify a constant acceleration along the X-axis");
+ uiDefButF(block, NUM, B_PART_RECALC, "AccY:", butx+butw,buty,butw,buth, part->acc+1,-200.0, 200.0, 10, 0, "Specify a constant acceleration along the Y-axis");
+ uiDefButF(block, NUM, B_PART_RECALC, "AccZ:", butx+2*butw,buty,butw+1,buth, part->acc+2, -200.0, 200.0, 10, 0, "Specify a constant acceleration along the Z-axis");
+
+ uiDefButF(block, NUM, B_PART_RECALC, "Drag:", butx,(buty-=buth),butw,buth, &part->dragfac, 0.0, 1.0, 1, 0, "Specify the amount of air-drag");
+ uiDefButF(block, NUM, B_PART_RECALC, "Brown:", butx+butw,buty,butw,buth, &part->brownfac, 0.0, 200.0, 1, 0, "Specify the amount of brownian motion");
+ uiDefButF(block, NUM, B_PART_RECALC, "Damp:", butx+2*butw,buty,butw+1,buth, &part->dampfac, 0.0, 1.0, 1, 0, "Specify the amount of damping");
+ uiBlockEndAlign(block);
+ }
+ else if(part->phystype==PART_PHYS_KEYED) {
+ short totkpsys=1;
+ butx=0;
+ buty=40;
+ uiDefBut(block, LABEL, 0, "Keyed Target:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
+ if(psys->keyed_ob){
+ if(psys->keyed_ob==ob || BLI_findlink(&psys->keyed_ob->particlesystem,psys->keyed_psys-1)==0)
+ uiBlockSetCol(block, TH_REDALERT);
+ else
+ totkpsys = BLI_countlist(&psys->keyed_ob->particlesystem);
+ }
+ else
+ uiBlockSetCol(block, TH_REDALERT);
+
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:", butx,(buty-=buth),butw*2/3,buth, &psys->keyed_ob, "The object that has the target particle system");
+ uiDefButS(block, NUM, B_PARTTARGET, "Psys:", butx+butw*2/3,buty,butw/3,buth, &psys->keyed_psys, 1.0, totkpsys, 0, 0, "The target particle system number in the object");
+ uiBlockEndAlign(block);
+
+ uiBlockSetCol(block, TH_AUTO);
+
+ butx=160;
+
+ if(psys->flag & PSYS_FIRST_KEYED)
+ uiDefButBitI(block, TOG, PSYS_KEYED_TIME, B_PART_RECALC, "Timed", butx,buty,butw,buth, &psys->flag, 0, 0, 0, 0, "Use intermediate key times");
+ else
+ uiDefButF(block, NUMSLI, B_PART_RECALC, "Time:", butx,buty,butw,buth, &part->keyed_time, 0.0, 1.0, 1, 3, "Keyed key time relative to remaining particle life");
+ }
}
- uiDefButF(block, NUM, B_CALCEFFECT, "Life:", 0,90,75,20, &paf->lifetime, 1.0, MAXFRAMEF, 100, 1, "Specify the life span of the particles");
- uiDefButS(block, NUM, B_CALCEFFECT, "Disp:", 75,90,75,20, &paf->disp, 0.0, 100.0, 10, 0, "Percentage of particles to calculate for 3d view");
- uiBlockEndAlign(block);
+}
+
+static void psys_clear_cache(void *ob_v, void *psys_v)
+{
+ clear_particles_from_cache((Object *)ob_v, (ParticleSystem *)psys_v, CFRA);
+}
+static void object_panel_particle_system(Object *ob)
+{
+ uiBlock *block;
+ uiBut *but;
+ ParticleSystem *psys=NULL;
+ ParticleSettings *part;
+ ID *id, *idfrom;
+ short butx=0, buty=160, butw=150, buth=20;
+ char str[30];
+ static short partact;
+ short totpart, lock;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_system", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Particle System", "Particle", 0, 0, 318, 204)==0) return;
- uiDefBut(block, LABEL, 0, "From:", 0,70,75,20, NULL, 0.0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOGN, PAF_OFACE, B_CALCEFFECT, "Verts", 0,50,75,20, &paf->flag, 0, 0, 0, 0, "Emit particles from vertices");
- uiDefButBitS(block, TOG, PAF_FACE, B_CALCEFFECT, "Faces", 75,50,75,20, &paf->flag, 0, 0, 0, 0, "Emit particles from faces");
- if(paf->flag & PAF_FACE) {
- uiDefButBitS(block, TOG, PAF_TRAND, B_CALCEFFECT, "Rand", 0,30,50,20, &paf->flag, 0, 0, 0, 0, "Use true random distribution from faces");
- uiDefButBitS(block, TOG, PAF_EDISTR, B_CALCEFFECT, "Even", 50,30,50,20, &paf->flag, 0, 0, 0, 0, "Use even distribution from faces based on face areas");
- uiDefButS(block, NUM, B_CALCEFFECT, "P/F:", 100,30,50,20, &paf->userjit, 0.0, 200.0, 1, 0, "Jitter table distribution: maximum particles per face (0=uses default)");
+ if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
+
+ if(ELEM4(ob->type,OB_MESH,OB_FONT,OB_CURVE,OB_SURF)==0) {
+ uiDefBut(block, LABEL, 0, "Only Mesh or Curve Objects can generate particles", 10,180,300,20, NULL, 0.0, 0, 0, 0, "");
+ return;
}
- else uiBlockEndAlign(block); /* vgroup button no align */
+ psys=psys_get_current(ob);
+
+ if(psys)
+ id=(ID*)(psys->part);
+ else
+ id=NULL;
+ idfrom=&ob->id;
+
+ /* browse buttons */
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+ butx= std_libbuttons(block, butx, buty, 0, NULL, B_PARTBROWSE, ID_PA, 0, id, idfrom, &(G.buts->menunr), B_PARTALONE, 0, B_PARTDELETE, 0, 0);
- but=uiDefBut(block, TEX, B_PAF_SET_VG, "VGroup:", 0,10,150,20, paf->vgroupname, 0, 31, 0, 0, "Name of vertex group to use");
- uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)OBACT);
- uiBlockEndAlign(block);
+ uiBlockSetCol(block, TH_AUTO);
- /* right collumn */
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, PAF_STATIC, B_EFFECT_DEP, "Static", 160,180,75,20, &paf->flag, 0, 0, 0, 0, "Make static particles (deform only works with SubSurf)");
- if(paf->flag & PAF_STATIC) {
- uiDefButBitS(block, TOG, PAF_ANIMATED, B_DIFF, "Animated", 235,180,75,20, &paf->flag, 0, 0, 0, 0, "Static particles are recalculated each rendered frame");
+ partact=psys_get_current_num(ob)+1;
+ totpart=BLI_countlist(&ob->particlesystem);
+ sprintf(str, "%d Part", totpart);
+ but=uiDefButS(block, NUM, B_PARTACT, str, 224,buty,88,buth, &partact, 1.0, totpart+1, 0, 0, "Shows the number of particle systems in the object and the active particle system");
+ uiButSetFunc(but, PE_change_act, ob, &partact);
+
+ if(psys==NULL)
+ return;
+
+ part=psys->part;
+
+ if(part==NULL) return;
+
+ butx=0;
+ buty-=5;
+
+ uiDefButBitI(block, TOG, PSYS_ENABLED, B_PART_ENABLE, "Enabled", 0,(buty-=buth),100,buth, &psys->flag, 0, 0, 0, 0, "Sets particle system to be calculated and shown");
+
+ if(part->type == PART_HAIR){
+ if(psys->flag & PSYS_EDITED)
+ uiDefBut(block, BUT, B_PART_EDITABLE, "Free Edit", 105,buty,100,buth, NULL, 0.0, 0.0, 10, 0, "Free editing");
+ else
+ uiDefBut(block, BUT, B_PART_EDITABLE, "Set Editable", 105,buty,100,buth, NULL, 0.0, 0.0, 10, 0, "Finalize hair to enable editing in particle mode");
+
}
- uiBlockEndAlign(block);
+ else {
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, PSYS_PROTECT_CACHE, B_PART_REDRAW, "Protect", 105,buty,50,buth, &psys->flag, 0.0, 0.0, 10, 0, "Protect the cache");
+ but=uiDefBut(block, BUT, B_PART_RECALC, "Clear", 155,buty,50,buth, NULL, 0.0, 0.0, 10, 0, "Clear the cache");
+ if((psys->flag & PSYS_PROTECT_CACHE)==0)
+ uiButSetFunc(but, psys_clear_cache, ob, &partact);
+
+ uiBlockEndAlign(block);
+ }
+
+ lock= (psys->flag & PSYS_EDITED || psys->flag & PSYS_PROTECT_CACHE);
+ if(lock)
+ uiSetButLock(1, "Hair is edited or cache is protected!");
- uiDefBut(block, LABEL, 0, "Display:", 160,150,75,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefButS(block, MENU, B_PARTTYPE, "Type%t|Hair%x2|Reactor%x1|Emitter%x0", 210,buty,100,buth, &part->type, 14.0, 0.0, 0, 0, "Type of particle system");
+
+ buty-=5;
+ uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_CALCEFFECT, "Material:", 160,130,150,20, &paf->omat, 1.0, 16.0, 0, 0, "Specify material used for the particles");
- uiDefButS(block, TOG|BIT|7, B_REDR, "Mesh", 160,110,50,20, &paf->flag, 0, 0, 0, 0, "Render emitter Mesh also");
- uiDefButBitS(block, TOG, PAF_UNBORN, B_DIFF, "Unborn",210,110,50,20, &paf->flag, 0, 0, 0, 0, "Make particles appear before they are emitted");
- uiDefButBitS(block, TOG, PAF_DIED, B_DIFF, "Died", 260,110,50,20, &paf->flag, 0, 0, 0, 0, "Make particles appear after they have died");
- uiDefButS(block, TOG, REDRAWVIEW3D, "Vect", 160,90,75,20, &paf->stype, 0, 0, 0, 0, "Give the particles a direction and rotation");
- if(paf->flag & PAF_STATIC)
- uiDefButF(block, NUM, B_CALCEFFECT, "Max:", 235,90,75,20, &paf->maxlen, 0.0, 100.0, 10, 1, "The maximum length of a particle strand (zero is no limit)");
+
+ if(part->distr==PART_DISTR_GRID)
+ uiDefButI(block, NUM, B_PART_ALLOC, "Resol:", butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid");
else
- uiDefButF(block, NUM, B_CALCEFFECT, "Size:", 235,90,75,20, &paf->vectsize, 0.0, 1.0, 10, 1, "The amount the Vect option influences halo size");
+ uiDefButI(block, NUM, B_PART_ALLOC, "Amount:", butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles");
+ if(part->type==PART_REACTOR) {
+ uiDefButBitI(block, TOG, PART_REACT_STA_END, B_PART_INIT, "Sta/End", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Give birth to unreacted particles eventually");
+ uiDefButS(block, MENU, B_PART_RECALC, "React on %t|Near %x2|Collision %x1|Death %x0", butx+butw/2,buty,butw/2,buth, &part->reactevent, 14.0, 0.0, 0, 0, "The event of target particles to react");
+ if(part->flag&PART_REACT_STA_END) {
+ uiDefButF(block, NUM, B_PART_INIT, "Sta:", butx,(buty-=buth),butw,buth, &part->sta, 1.0, part->end, 100, 1, "Frame # to start emitting particles");
+ uiDefButF(block, NUM, B_PART_INIT, "End:", butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
+ }
+ if(part->from!=PART_FROM_PARTICLE) {
+ uiDefButBitI(block, TOG, PART_REACT_MULTIPLE, B_PART_RECALC, "Multi React", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "React multiple times");
+ uiDefButF(block, NUM, B_PART_RECALC, "Shape:", butx,(buty-=buth),butw,buth, &part->reactshape, 0.0, 10.0, 100, 1, "Power of reaction strength dependence on distance to target");
+ }
+ }
+ else if(part->type==PART_HAIR) {
+ uiDefButS(block, NUM, B_PART_RECALC, "Segments:", butx,(buty-=buth),butw,buth, &part->hair_step, 2.0, 50.0, 0, 0, "Amount of hair segments");
+ }
+ else {
+ uiDefButF(block, NUM, B_PART_INIT, "Sta:", butx,(buty-=buth),butw,buth, &part->sta, 1.0, part->end, 100, 1, "Frame # to start emitting particles");
+ uiDefButF(block, NUM, B_PART_INIT, "End:", butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
+ }
+
+ if(part->type!=PART_HAIR) {
+ uiDefButF(block, NUM, B_PART_INIT, "Life:", butx,(buty-=buth),butw,buth, &part->lifetime, 1.0, MAXFRAMEF, 100, 1, "Specify the life span of the particles");
+ uiDefButF(block, NUM, B_PART_INIT, "Rand:", butx,(buty-=buth),butw,buth, &part->randlife, 0.0, 2.0, 10, 1, "Give the particle life a random variation");
+ }
+
uiBlockEndAlign(block);
- uiDefBut(block, LABEL, 0, "Children:", 160,70,75,20, NULL, 0.0, 0, 0, 0, "");
+ butx=160;
+ buty=120;
+
+ buty-=10;
+
+ uiDefBut(block, LABEL, 0, "Emit From:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_REDR, "Generation:", 160,50,150,20, &paf->curmult, 0.0, 3.0, 0, 0, "Current generation of particles");
- uiDefButS(block, NUM, B_CALCEFFECT, "Num:", 160,30,75,20, paf->child+paf->curmult, 1.0, 600.0, 100, 0, "Specify the number of generations of particles that can multiply itself");
- uiDefButF(block, NUM, B_CALCEFFECT, "Prob:", 235,30,75,20, paf->mult+paf->curmult, 0.0, 1.0, 10, 1, "Probability \"dying\" particle spawns a new one.");
- uiDefButF(block, NUM, B_CALCEFFECT, "Life:", 160,10,75,20, paf->life+paf->curmult, 1.0, 600.0, 100, 1, "Specify the lifespan of the next generation particles");
- uiDefButS(block, NUM, B_CALCEFFECT, "Mat:", 235,10,75,20, paf->mat+paf->curmult, 1.0, 8.0, 0, 0, "Specify the material used for the particles");
+
+ if(lock) uiClearButLock();
+ uiDefButBitI(block, TOG, PART_TRAND, B_PART_DISTR, "Random", butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Emit in random order of elements");
+ if(lock) uiSetButLock(1, "Hair is edited or cache is protected!");
+
+ if(part->type==PART_REACTOR)
+ uiDefButS(block, MENU, B_PART_DISTR, "Particle %x3|Volume %x2|Faces %x1|Verts %x0", butx+butw/2,buty,butw/2,buth, &part->from, 14.0, 0.0, 0, 0, "Where to emit particles from");
+ else
+ uiDefButS(block, MENU, B_PART_DISTR, "Volume %x2|Faces %x1|Verts%x0", butx+butw/2,buty,butw/2,buth, &part->from, 14.0, 0.0, 0, 0, "Where to emit particles from");
+
+ if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)) {
+ if(lock) uiClearButLock();
+ uiDefButBitI(block, TOG, PART_EDISTR, B_PART_DISTR, "Even",butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Use even distribution from faces based on face areas or edge lengths");
+ if(lock) uiSetButLock(1, "Hair is edited or cache is protected!");
+ uiDefButS(block, MENU, B_PART_DISTR, "Distribution %t|Grid%x2|Random%x1|Jittered%x0", butx+butw/2,buty,butw/2,buth, &part->distr, 14.0, 0.0, 0, 0, "How to distribute particles on selected element");
+ if(part->distr==PART_DISTR_JIT) {
+ uiDefButF(block, NUM, B_PART_DISTR, "Amount:", butx,(buty-=buth),butw,buth, &part->jitfac, 0, 2.0, 1, 1, "Amount of jitter applied to the sampling");
+ uiDefButI(block, NUM, B_PART_DISTR, "P/F:", butx,(buty-=buth),butw,buth, &part->userjit, 0, 1000.0, 1, 1, "Emission locations / face (0 = automatic)");
+ }
+ if(part->distr==PART_DISTR_GRID){
+ uiDefButBitI(block, TOG, PART_GRID_INVERT, B_PART_DISTR, "Invert",butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Invert what is considered object and what is not.");
+ }
+ }
uiBlockEndAlign(block);
+ buty=30;
+
+ if(part->type==PART_REACTOR) {
+ ParticleSystem *tpsys=0;
+ Object *tob=0;
+ int tottpsys;
+
+ uiDefBut(block, LABEL, 0, "Target:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
+
+ if(psys->target_ob)
+ tob=psys->target_ob;
+ else
+ tob=ob;
+
+ tottpsys=BLI_countlist(&tob->particlesystem);
+
+ uiBlockBeginAlign(block);
+
+ if(tob->particlesystem.first==0)
+ uiBlockSetCol(block, TH_REDALERT);
+
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:", butx,(buty-=buth),butw*2/3,buth, &psys->target_ob, "The object that has the target particle system (empty if same object)");
+
+ tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
+ if(tpsys) {
+ if(tob==ob && tpsys==psys)
+ uiBlockSetCol(block, TH_REDALERT);
+ }
+ else
+ uiBlockSetCol(block, TH_REDALERT);
+
+ uiDefButS(block, NUM, B_PARTTARGET, "Psys:", butx+butw*2/3,buty,butw/3,buth, &psys->target_psys, 1.0, tottpsys, 0, 0, "The target particle system number in the object");
+ uiBlockEndAlign(block);
+
+ uiBlockSetCol(block, TH_AUTO);
+ }
}
/* NT - Panel for fluidsim settings */
@@ -3152,6 +5086,469 @@ errMessage:
#endif // DISABLE_ELBEEM
}
+/* Panel for cloth */
+static void object_cloth__enabletoggle(void *ob_v, void *arg2)
+{
+ Object *ob = ob_v;
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
+
+ if (!md) {
+ md = modifier_new(eModifierType_Cloth);
+ BLI_addhead(&ob->modifiers, md);
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ else {
+ Object *ob = ob_v;
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
+
+ if (!md)
+ return;
+
+ BLI_remlink(&ob->modifiers, md);
+
+ modifier_free(md);
+
+ BIF_undo_push("Del modifier");
+
+ ob->softflag |= OB_SB_RESET;
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWOOPS, 0);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ object_handle_update(ob);
+ countall();
+ }
+}
+
+static void cloth_presets_material(void *ob_v, void *arg2)
+{
+ Object *ob = ob_v;
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(!clmd) return;
+ if(clmd->sim_parms->presets==0) return;
+
+ if(clmd->sim_parms->presets==1) /* SILK */
+ {
+ clmd->sim_parms->structural = clmd->sim_parms->shear = 5.0;
+ clmd->sim_parms->bending = 0.05;
+ clmd->sim_parms->Cdis = 0.0;
+ clmd->sim_parms->mass = 0.15;
+ }
+ else if(clmd->sim_parms->presets==2) /* COTTON */
+ {
+ clmd->sim_parms->structural = clmd->sim_parms->shear = 15.0;
+ clmd->sim_parms->bending = 0.5;
+ clmd->sim_parms->Cdis = 5.0;
+ clmd->sim_parms->mass = 0.3;
+ }
+ else if(clmd->sim_parms->presets==3) /* RUBBER */
+ {
+ clmd->sim_parms->structural = clmd->sim_parms->shear = 15.0;
+ clmd->sim_parms->bending = 25.0;
+ clmd->sim_parms->Cdis = 25.0;
+ clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 7.0);
+ clmd->sim_parms->mass = 3.0;
+ }
+ else if(clmd->sim_parms->presets==4) /* DENIM */
+ {
+ clmd->sim_parms->structural = clmd->sim_parms->shear = 40.0;
+ clmd->sim_parms->bending = 10.0;
+ clmd->sim_parms->Cdis = 25.0;
+ clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 12.0);
+ clmd->sim_parms->mass = 1.0;
+ }
+ else if(clmd->sim_parms->presets==5) /* LEATHER */
+ {
+ clmd->sim_parms->structural = clmd->sim_parms->shear = 80.0;
+ clmd->sim_parms->bending = 150.0;
+ clmd->sim_parms->Cdis = 25.0;
+ clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 15.0);
+ clmd->sim_parms->mass = 0.4;
+ }
+}
+
+static void cloth_presets_custom_material(void *ob_v, void *arg2)
+{
+ Object *ob = ob_v;
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(!clmd) return;
+
+ clmd->sim_parms->presets = 0;
+}
+
+static int _can_cloth_at_all(Object *ob)
+{
+ // list of Yes
+ if ((ob->type==OB_MESH)) return 1;
+ // else deny
+ return 0;
+}
+
+static void object_panel_cloth(Object *ob)
+{
+ uiBlock *block=NULL;
+ uiBut *but=NULL;
+ static int val, val2;
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win);
+ if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return;
+ uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ val = (clmd ? 1:0);
+
+ if(!_can_cloth_at_all(ob))
+ {
+ uiDefBut(block, LABEL, 0, "Cloth can be activated on mesh only.", 10,200,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+ else
+ {
+ but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth", 10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth");
+ uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL);
+ }
+
+ uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
+
+ if(clmd)
+ {
+ int defCount;
+ char *clvg1, *clvg2;
+ char clmvg [] = "Vertex Groups%t|";
+
+ val2=0;
+
+ /* GENERAL STUFF */
+ uiClearButLock();
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+ else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+
+ uiDefBut(block, LABEL, 0, "Material Preset:", 10,170,150,20, NULL, 0.0, 0, 0, 0, "");
+ but=uiDefButS(block, MENU, B_CLOTH_RENEW, "Silk %x1|Cotton %x2|Rubber %x3|Denim %x4|Leather %x5|Custom %x0",
+ 160,170,150,20, &clmd->sim_parms->presets, 0, 0, 0, 0, "");
+ uiButSetFunc(but, cloth_presets_material, ob, NULL);
+
+ uiBlockBeginAlign(block);
+ but = uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,150,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
+ uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
+
+ but = uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
+ uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
+
+ but = uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 10,130,150,20, &clmd->sim_parms->Cdis, 0.0, 50.0, 100, 0, "Damping of cloth velocity (higher = more smooth, less jiggling)");
+ uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
+
+ uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,110,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Mass:", 160,110,150,20, &clmd->sim_parms->mass, 0.0, 10.0, 1000, 0, "Mass of cloth material.");
+
+ uiDefBut(block, LABEL, 0, "Gravity:", 10,90,60,20, NULL, 0.0, 0, 0, 0, "");
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,90,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,90,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,90,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+ uiBlockEndAlign(block);
+
+ /* GOAL STUFF */
+ uiBlockBeginAlign(block);
+
+
+ uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth", 10,60,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0))
+ {
+ if(ob->type==OB_MESH)
+ {
+
+ defCount = sizeof (clmvg);
+ clvg1 = get_vertexgroup_menustr (ob);
+ clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS");
+ if (! clvg2) {
+ printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
+ return;
+ }
+ defCount = BLI_countlist (&ob->defbase);
+ if (defCount == 0)
+ {
+ clmd->sim_parms->vgroup_mass = 0;
+ }
+ else
+ {
+ if(!clmd->sim_parms->vgroup_mass)
+ clmd->sim_parms->vgroup_mass = 1;
+ else if(clmd->sim_parms->vgroup_mass > defCount)
+ clmd->sim_parms->vgroup_mass = defCount;
+ }
+
+ sprintf (clvg2, "%s%s", clmvg, clvg1);
+
+ uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,60,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
+ MEM_freeN (clvg1);
+ MEM_freeN (clvg2);
+ }
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,40,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
+ uiDefBut(block, LABEL, 0, "",160,40,150,20, NULL, 0.0, 0, 0, 0, "");
+ // uiDefButI(block, NUM, B_CLOTH_RENEW, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
+ /*
+ // nobody is changing these ones anyway
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:", 10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:", 160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
+ */
+ }
+ else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ {
+ uiDefBut(block, LABEL, 0, " ", 160,60,150,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,30,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+
+ uiBlockEndAlign(block);
+
+ /*
+ // no tearing supported anymore since modifier stack restrictions
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing", 10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
+
+ if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
+ {
+ uiDefButI(block, NUM, B_DIFF, "Max extent:", 160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut");
+ }
+
+ uiBlockEndAlign(block);
+ */
+ }
+
+ uiBlockEndAlign(block);
+
+ uiBlockEndAlign(block);
+}
+
+static void object_cloth__protecttoggle(void *ob_v, void *arg2)
+{
+ Object *ob = ob_v;
+ int cageIndex, stack_index;
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ // automatically enable modifier in editmode when we havee a protected cache
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
+ {
+ cageIndex = modifiers_getCageIndex(ob_v, NULL );
+ stack_index = modifiers_indexInObject(ob_v, (ModifierData *)clmd);
+ if( stack_index >= cageIndex )
+ ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
+ }
+ else
+ {
+ ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
+ }
+
+}
+
+
+static void object_panel_cloth_II(Object *ob)
+{
+ uiBlock *block;
+ uiBut *but = NULL;
+ ClothModifierData *clmd = NULL;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_cloth_II", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Cloth ", "Physics");
+ if(uiNewPanel(curarea, block, "Cloth Cache/Collisions", "Physics", 651, 0, 318, 204)==0) return;
+
+ uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(clmd)
+ {
+ uiClearButLock();
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+ else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+
+ uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
+ uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops");
+
+ uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
+
+ if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
+ {
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
+ uiClearButLock();
+ }
+
+ if (!G.relbase_valid)
+ {
+ uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.", 10,120,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, " ", 10,100,300,40, NULL, 0.0, 0, 0, 0, "");
+ }
+ else
+ {
+ but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache & Enable Cache Editing", 10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed. This also enabled the cache beeing edited in editmode.");
+ uiButSetFunc(but, object_cloth__protecttoggle, ob, NULL);
+ uiDefBut(block, LABEL, 0, "Clear cache:", 10,100,90,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll");
+ uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame");
+ uiDefBut(block, LABEL, 0, " ", 10,80,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+
+ if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
+ {
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
+ uiSetButLock(1, "Cache is protected");
+ }
+
+ /*
+ TODO: implement this again in cloth!
+ if(length>1) // B_CLOTH_CHANGEPREROLL
+ uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame");
+ else
+ uiDefBut(block, LABEL, 0, " ", 10,80,145,20, NULL, 0.0, 0, 0, 0, "");
+ */
+#if WITH_BULLET == 1
+ uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_CLOTH_RENEW, "Enable collisions", 10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
+ {
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
+ uiDefButS(block, NUM, B_CLOTH_RENEW, "Collision Quality:", 10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower)");
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Friction:", 160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+
+ uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_CLOTH_RENEW, "Enable selfcollisions", 10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)
+ {
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:", 160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
+ // self_loop_count
+ uiDefButS(block, NUM, B_CLOTH_RENEW, "Selfcoll Quality:", 10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
+ }
+ else
+ uiDefBut(block, LABEL, 0, "",160,20,150,20, NULL, 0.0, 0, 0, 0, "");
+ }
+ else
+ uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");
+#else
+ uiDefBut(block, LABEL, 0, "No collisions available (compile with bullet).",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
+#endif
+ }
+
+ uiBlockEndAlign(block);
+
+}
+
+static void object_panel_cloth_III(Object *ob)
+{
+ uiBlock *block;
+ ClothModifierData *clmd = NULL;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Cloth ", "Physics");
+ if(uiNewPanel(curarea, block, "Cloth Advanced", "Physics", 651, 0, 318, 204)==0) return;
+
+ uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(clmd)
+ {
+ int defCount;
+ char *clvg1, *clvg2;
+ char clmvg [] = "Vertex Groups%t|None%x0|";
+ char clmvg2 [] = "Vertex Groups%t|None%x0|";
+
+ uiClearButLock();
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+ else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+
+ uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT, REDRAWBUTSOBJECT, "Autoprotect cache",10,160,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enables automatic toggling of the 'Protect cache' button from the 2nd panel.");
+
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
+ {
+ uiDefButI(block, NUM, B_DIFF, "From frame:",160,160,150,20, &clmd->sim_parms->autoprotect, 0.0, MAXFRAME + 1, 1, 0, "Frame on which the 'Protect Cache' button (2nd panel) is toggled automatically (To prevent accidently cleaning it).");
+ }
+ else
+ {
+ uiDefBut(block, LABEL, 0, " ", 160,160,150,20, NULL, 0.0, 0, 0, 0, "");
+ }
+
+ uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_CLOTH_RENEW, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
+
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0))
+ {
+ uiDefBut(block, LABEL, 0, "StructStiff VGroup:",10,110,150,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "BendStiff VGroup:",160,110,150,20, NULL, 0.0, 0, 0, 0, "");
+
+ defCount = sizeof (clmvg);
+ clvg1 = get_vertexgroup_menustr (ob);
+ clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgST");
+ if (! clvg2) {
+ printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
+ return;
+ }
+ defCount = BLI_countlist (&ob->defbase);
+ if (defCount == 0)
+ {
+ clmd->sim_parms->vgroup_struct = 0;
+ }
+ else
+ {
+ if(clmd->sim_parms->vgroup_struct > defCount)
+ clmd->sim_parms->vgroup_struct = 0;
+ }
+
+ sprintf (clvg2, "%s%s", clmvg, clvg1);
+
+ uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups");
+ MEM_freeN (clvg1);
+ MEM_freeN (clvg2);
+
+ defCount = sizeof (clmvg);
+ clvg1 = get_vertexgroup_menustr (ob);
+ clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgBD");
+ if (! clvg2) {
+ printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
+ return;
+ }
+ defCount = BLI_countlist (&ob->defbase);
+ if (defCount == 0)
+ {
+ clmd->sim_parms->vgroup_bend = 0;
+ }
+ else
+ {
+ if(clmd->sim_parms->vgroup_bend > defCount)
+ clmd->sim_parms->vgroup_bend = 0;
+ }
+
+ sprintf (clvg2, "%s%s", clmvg2, clvg1);
+
+ uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups");
+ MEM_freeN (clvg1);
+ MEM_freeN (clvg2);
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value");
+
+ uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value");
+
+ }
+ else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)
+ {
+ uiDefBut(block, LABEL, 0, " ", 10,110,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "No vertex group for pinning available.", 10,90,300,20, NULL, 0.0, 0, 0, 0, "");
+ }
+
+
+
+ }
+
+ uiBlockEndAlign(block);
+
+}
+
void object_panels()
{
Object *ob;
@@ -3175,11 +5572,36 @@ void physics_panels()
/* check context here */
ob= OBACT;
if(ob) {
+ if(ob->type==OB_MESH)
+ object_panel_deflection(ob);
object_panel_fields(ob);
- object_panel_particles(ob);
- object_panel_particles_motion(ob);
object_softbodies(ob);
- object_softbodies_II(ob);
+ object_softbodies_collision(ob);
+ object_softbodies_solver(ob);
+ object_panel_cloth(ob);
+ object_panel_cloth_II(ob);
+ object_panel_cloth_III(ob);
object_panel_fluidsim(ob);
}
}
+void particle_panels()
+{
+ Object *ob;
+ ParticleSystem *psys;
+
+ ob=OBACT;
+
+ if(ob && ob->type==OB_MESH) {
+ object_panel_particle_system(ob);
+
+ psys=psys_get_current(ob);
+
+ if(psys){
+ object_panel_particle_physics(ob);
+ object_panel_particle_visual(ob);
+ object_panel_particle_simplification(ob);
+ object_panel_particle_extra(ob);
+ object_panel_particle_children(ob);
+ }
+ }
+}
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 4f59e965371..302c76f4edf 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -41,6 +41,7 @@
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_sound_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_userdef_types.h"
#include "DNA_packedFile_types.h"
@@ -61,6 +62,7 @@
#include "BIF_graphics.h"
#include "BIF_glutil.h"
#include "BIF_interface.h"
+#include "BIF_imasel.h"
#include "BIF_keyval.h"
#include "BIF_mainqueue.h"
#include "BIF_mywindow.h"
@@ -70,6 +72,7 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BIF_editseq.h"
#include "BIF_butspace.h"
@@ -83,6 +86,7 @@
#include "BKE_writeavi.h"
#include "BKE_writeffmpeg.h"
#include "BKE_image.h"
+#include "BKE_plugin_types.h"
#include "BLI_threads.h"
@@ -90,8 +94,11 @@
#include "BIF_writeimage.h"
#include "BIF_writeavicodec.h"
-#include "BSE_seqaudio.h"
#include "BSE_headerbuttons.h"
+#include "BSE_sequence.h"
+#include "BSE_seqeffects.h"
+#include "BSE_seqscopes.h"
+#include "BSE_seqaudio.h"
#include "RE_pipeline.h"
@@ -465,6 +472,838 @@ static void sound_panel_sound(bSound *sound)
}
}
+/* ************************* Sequencer *********************** */
+
+#define SEQ_PANEL_EDITING 1
+#define SEQ_PANEL_INPUT 2
+#define SEQ_PANEL_FILTER 4
+#define SEQ_PANEL_EFFECT 8
+#define SEQ_PANEL_PROXY 16
+
+static char* seq_panel_blend_modes()
+{
+ static char string[2048];
+
+ Sequence *last_seq = get_last_seq();
+
+ sprintf(string, "Blend mode: %%t|%s %%x%d",
+ "Replace", SEQ_BLEND_REPLACE);
+
+ /*
+ Blending can only work without effect strips.
+ Otherwise, one would have
+ to decide, what the effect strips IPO should do:
+ - drive the effect _or_
+ - drive the blend mode ?
+
+ Also: effectdata is used by these implicit effects,
+ so that would collide also.
+ */
+
+ if (!(last_seq->type & SEQ_EFFECT)) {
+ int i;
+
+ for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) {
+ if (get_sequence_effect_num_inputs(i) == 2) {
+ sprintf(string + strlen(string),
+ "|%s %%x%d",
+ give_seqname_by_type(i), i);
+ }
+ }
+ }
+ return string;
+}
+
+static char* seq_panel_scenes()
+{
+ static char rstr[8192];
+ char * str;
+
+ IDnames_to_pupstring(&str, NULL, NULL,
+ &G.main->scene, (ID *)G.scene, NULL);
+
+ strncpy(rstr, str, 8192);
+ MEM_freeN(str);
+
+ return rstr;
+}
+
+static void seq_update_scenenr(Sequence * seq)
+{
+ Scene * sce;
+ int nr;
+ if (seq->type != SEQ_SCENE) {
+ return;
+ }
+
+ seq->scenenr = 0;
+
+ sce = G.main->scene.first;
+ nr = 1;
+ while(sce) {
+ if (sce == seq->scene) {
+ seq->scenenr = nr;
+ break;
+ }
+ nr++;
+ sce = sce->id.next;
+ }
+}
+
+
+static void seq_panel_editing()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+ static char strdata[1024];
+ char * str = strdata;
+ char * p;
+ int yco;
+
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_editing",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Edit", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+ uiDefBut(block, LABEL,
+ 0, give_seqname(last_seq),
+ 10,140,60,19, 0,
+ 0, 0, 0, 0, "");
+
+ uiDefBut(block, TEX,
+ B_NOP, "Name: ",
+ 70,140,180,19, last_seq->name+2,
+ 0.0, 21.0, 100, 0, "");
+
+ uiDefButI(block, MENU, B_SEQ_BUT_RELOAD, seq_panel_blend_modes(),
+ 10, 120, 120, 19, &last_seq->blend_mode,
+ 0,0,0,0, "Strip Blend Mode");
+
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Blend:",
+ 130, 120, 120, 19, &last_seq->blend_opacity,
+ 0.0, 100.0, 100.0, 0,
+ "Blend opacity");
+
+ uiDefButBitI(block, TOG, SEQ_MUTE,
+ B_SEQ_BUT_RELOAD_ALL, "Mute",
+ 10,100,60,19, &last_seq->flag,
+ 0.0, 1.0, 0, 0,
+ "Mute the current strip.");
+
+ uiDefButBitI(block, TOG, SEQ_LOCK,
+ B_REDR, "Lock",
+ 70,100,60,19, &last_seq->flag,
+ 0.0, 1.0, 0, 0,
+ "Lock strip, so that it can't be transformed.");
+
+ uiDefButBitI(block, TOG, SEQ_IPO_FRAME_LOCKED,
+ B_SEQ_BUT_RELOAD_ALL, "IPO Frame locked",
+ 130,100,120,19, &last_seq->flag,
+ 0.0, 1.0, 0, 0,
+ "Lock the IPO coordinates to the "
+ "global frame counter.");
+
+ if (!(last_seq->flag & SEQ_LOCK)) {
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "Start",
+ 10, 80, 120, 20, &last_seq->start,
+ -MAXFRAMEF, MAXFRAMEF, 0.0, 0.0, "Start of strip");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "Chan",
+ 130, 80, 120, 20, &last_seq->machine,
+ 0.0, MAXSEQ, 0.0, 0.0, "Channel used (Y position)");
+
+ if (check_single_seq(last_seq)) {
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "End-Still",
+ 130, 60, 120, 19, &last_seq->endstill,
+ 0.0, MAXFRAMEF, 0.0, 0.0, "End still");
+ } else {
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "Start-Still",
+ 10, 60, 120, 20, &last_seq->startstill,
+ 0.0, MAXFRAMEF, 0.0, 0.0, "Start still");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "End-Still",
+ 130, 60, 120, 19, &last_seq->endstill,
+ 0.0, MAXFRAMEF, 0.0, 0.0, "End still");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "Start-Ofs",
+ 10, 40, 120, 20, &last_seq->startofs,
+ 0.0, last_seq->len - last_seq->endofs,
+ 0.0, 0.0, "Start offset");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_TRANSFORM, "End-Ofs",
+ 130, 40, 120, 19, &last_seq->endofs,
+ 0.0, last_seq->len - last_seq->startofs,
+ 0.0, 0.0, "End offset");
+ }
+ }
+
+
+ if(last_seq->type & SEQ_EFFECT)
+ sprintf(str, "Len: %d\nFrom %d - %d\n", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
+ else
+ sprintf(str, "Len: %d(%d)\n", last_seq->enddisp-last_seq->startdisp, last_seq->len);
+
+ str += strlen(str);
+
+ if(last_seq->type==SEQ_IMAGE) {
+ if (last_seq->len > 1) {
+ /* CURRENT */
+ StripElem * se= give_stripelem(last_seq, CFRA);
+ StripElem * last;
+
+ /* FIRST AND LAST */
+
+ if(last_seq->strip) {
+ se= last_seq->strip->stripdata;
+ last= se+last_seq->len-1;
+ if(last_seq->startofs) se+= last_seq->startofs;
+ if(last_seq->endofs) last-= last_seq->endofs;
+
+ sprintf(str, "First: %s at %d\nLast: %s at %d\n", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
+ }
+ } else { /* single image */
+ if (last_seq->strip) {
+ sprintf(str, "Len: %d\n", last_seq->enddisp-last_seq->startdisp);
+ }
+ }
+
+ str += strlen(str);
+
+ /* orig size */
+ if(last_seq->strip) {
+ sprintf(str, "OrigSize: %d x %d\n", last_seq->strip->orx, last_seq->strip->ory);
+ }
+ }
+ else if(last_seq->type==SEQ_MOVIE) {
+ int sta= last_seq->startofs;
+ int end= last_seq->len-1-last_seq->endofs;
+
+ sprintf(str, "First: %d at %d\nLast: %d at %d\nCur: %d\n",
+ sta, last_seq->startdisp, end, last_seq->enddisp-1,
+ (G.scene->r.cfra)-last_seq->startdisp);
+
+ str += strlen(str);
+ /* orig size */
+ if(last_seq->strip) {
+ sprintf(str, "OrigSize: %d x %d\n",
+ last_seq->strip->orx, last_seq->strip->ory);
+ }
+ }
+ else if(last_seq->type==SEQ_SCENE) {
+ TStripElem * se= give_tstripelem(last_seq, (G.scene->r.cfra));
+ if(se && last_seq->scene) {
+ sprintf(str, "First: %d\nLast: %d\nCur: %d\n", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1);
+ }
+ str += strlen(str);
+ /* orig size */
+ if(last_seq->strip) {
+ sprintf(str, "OrigSize: %d x %d\n",
+ last_seq->strip->orx, last_seq->strip->ory);
+ }
+ }
+ else if(last_seq->type==SEQ_RAM_SOUND
+ || last_seq->type == SEQ_HD_SOUND) {
+
+ int sta= last_seq->startofs;
+ int end= last_seq->len-1-last_seq->endofs;
+
+ sprintf(str, "First: %d at %d\nLast: %d at %d\nCur: %d\n",
+ sta, last_seq->startdisp, end, last_seq->enddisp-1,
+ (G.scene->r.cfra)-last_seq->startdisp);
+ }
+ else if(last_seq->type == SEQ_SPEED) {
+ SpeedControlVars * vars =
+ (SpeedControlVars*) last_seq->effectdata;
+
+ if (vars) {
+ sprintf(str, "Last mapped frame: %d at %d\n",
+ vars->lastValidFrame,
+ vars->lastValidFrame
+ + last_seq->startdisp);
+ }
+ }
+
+ str = strdata;
+ yco = 20;
+
+ while ((p = strchr(str, '\n'))) {
+ *p = 0;
+ uiDefBut(block, LABEL, 0, str, 10,yco,240,17, 0,
+ 0, 0, 0, 0, "");
+ str = p+1;
+ yco -= 18;
+ }
+}
+
+static void seq_panel_input()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_input",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Input", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+ if (last_seq->type == SEQ_MOVIE
+ || last_seq->type == SEQ_IMAGE) {
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD_FILE, "Dir: ",
+ 10,140,240,19, last_seq->strip->dir,
+ 0.0, 160.0, 100, 0, "");
+ }
+
+ if (last_seq->type == SEQ_IMAGE) {
+ StripElem * se = give_stripelem(last_seq, CFRA);
+
+ if (se) {
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD_FILE, "File: ",
+ 10, 120, 190,19, se->name,
+ 0.0, 80.0, 100, 0, "");
+ }
+
+ } else if (last_seq->type == SEQ_MOVIE ||
+ last_seq->type == SEQ_HD_SOUND ||
+ last_seq->type == SEQ_RAM_SOUND) {
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD_FILE, "File: ",
+ 10,120,190,19, last_seq->strip->stripdata->name,
+ 0.0, 80.0, 100, 0, "");
+ } else if (last_seq->type == SEQ_SCENE) {
+ seq_update_scenenr(last_seq);
+ uiDefButI(block, MENU, B_SEQ_BUT_RELOAD_FILE,
+ seq_panel_scenes(),
+ 10, 120, 190, 19, &last_seq->scenenr,
+ 0,0,0,0, "Linked Scene");
+ }
+
+ uiDefBut(block, BUT, B_SEQ_BUT_RELOAD_FILE,
+ "Reload",
+ 200,120,50,19, 0, 0, 0, 0, 0,
+ "Reload files/scenes from disk and update strip length.");
+
+ if (last_seq->type == SEQ_MOVIE
+ || last_seq->type == SEQ_IMAGE
+ || last_seq->type == SEQ_SCENE) {
+ uiDefButBitI(block, TOG, SEQ_USE_CROP,
+ B_SEQ_BUT_RELOAD, "Use Crop",
+ 10,100,240,19, &last_seq->flag,
+ 0.0, 1.0, 0, 0,
+ "Crop image before processing.");
+
+ if (last_seq->flag & SEQ_USE_CROP) {
+ if (!last_seq->strip->crop) {
+ last_seq->strip->crop =
+ MEM_callocN(sizeof(struct StripCrop),
+ "StripCrop");
+ }
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "Top",
+ 10, 80, 120, 20,
+ &last_seq->strip->crop->top,
+ 0.0, 4096, 0.0, 0.0, "Top of source image");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "Bottom",
+ 130, 80, 120, 20,
+ &last_seq->strip->crop->bottom,
+ 0.0, 4096, 0.0, 0.0,
+ "Bottom of source image");
+
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "Left",
+ 10, 60, 120, 20,
+ &last_seq->strip->crop->left,
+ 0.0, 4096, 0.0, 0.0, "Left");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "Right",
+ 130, 60, 120, 19,
+ &last_seq->strip->crop->right,
+ 0.0, 4096, 0.0, 0.0, "Right");
+ }
+
+ uiDefButBitI(block, TOG, SEQ_USE_TRANSFORM,
+ B_SEQ_BUT_RELOAD, "Use Translate",
+ 10,40,240,19, &last_seq->flag,
+ 0.0, 1.0, 0, 0,
+ "Translate image before processing.");
+
+ if (last_seq->flag & SEQ_USE_TRANSFORM) {
+ if (!last_seq->strip->transform) {
+ last_seq->strip->transform =
+ MEM_callocN(
+ sizeof(struct StripTransform),
+ "StripTransform");
+ }
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "X-Ofs",
+ 10, 20, 120, 20,
+ &last_seq->strip->transform->xofs,
+ -4096.0, 4096, 0.0, 0.0, "X Offset");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD, "Y-Ofs",
+ 130, 20, 120, 20,
+ &last_seq->strip->transform->yofs,
+ -4096.0, 4096, 0.0, 0.0, "Y Offset");
+ }
+ }
+
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD_FILE, "A-Start",
+ 10, 0, 120, 20, &last_seq->anim_startofs,
+ 0.0, last_seq->len + last_seq->anim_startofs, 0.0, 0.0,
+ "Animation start offset in file");
+ uiDefButI(block, NUM,
+ B_SEQ_BUT_RELOAD_FILE, "A-End",
+ 130, 0, 120, 20, &last_seq->anim_endofs,
+ 0.0, last_seq->len + last_seq->anim_endofs, 0.0, 0.0,
+ "Animation end offset in file");
+
+
+ if (last_seq->type == SEQ_MOVIE) {
+ uiDefButI(block, NUM, B_SEQ_BUT_RELOAD, "MPEG-Preseek:",
+ 10, -20, 240,19, &last_seq->anim_preseek,
+ 0.0, 50.0, 100,0,
+ "On MPEG-seeking preseek this many frames");
+ }
+
+}
+
+static void seq_panel_filter_video()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Filter", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+
+ uiBlockBeginAlign(block);
+
+
+ uiDefButBitI(block, TOG, SEQ_MAKE_PREMUL,
+ B_SEQ_BUT_RELOAD, "Premul",
+ 10,110,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Converts RGB values to become premultiplied with Alpha");
+
+ uiDefButBitI(block, TOG, SEQ_MAKE_FLOAT,
+ B_SEQ_BUT_RELOAD, "Float",
+ 90,110,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Convert input to float data");
+
+ uiDefButBitI(block, TOG, SEQ_FILTERY,
+ B_SEQ_BUT_RELOAD, "FilterY",
+ 170,110,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "For video movies to remove fields");
+
+ uiDefButBitI(block, TOG, SEQ_FLIPX,
+ B_SEQ_BUT_RELOAD, "FlipX",
+ 10,90,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Flip on the X axis");
+ uiDefButBitI(block, TOG, SEQ_FLIPY,
+ B_SEQ_BUT_RELOAD, "FlipY",
+ 90,90,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Flip on the Y axis");
+
+ uiDefButBitI(block, TOG, SEQ_REVERSE_FRAMES,
+ B_SEQ_BUT_RELOAD, "Flip Time",
+ 170,90,80,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Reverse frame order");
+
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Mul:",
+ 10,70,120,19, &last_seq->mul,
+ 0.001, 20.0, 0.1, 0,
+ "Multiply colors");
+
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Strobe:",
+ 130,70,120,19, &last_seq->strobe,
+ 1.0, 30.0, 100, 0,
+ "Only display every nth frame");
+
+ uiDefButBitI(block, TOG, SEQ_USE_COLOR_BALANCE,
+ B_SEQ_BUT_RELOAD, "Use Color Balance",
+ 10,50,240,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Activate Color Balance "
+ "(3-Way color correction) on input");
+
+
+ if (last_seq->flag & SEQ_USE_COLOR_BALANCE) {
+ if (!last_seq->strip->color_balance) {
+ int c;
+ StripColorBalance * cb
+ = last_seq->strip->color_balance
+ = MEM_callocN(
+ sizeof(struct StripColorBalance),
+ "StripColorBalance");
+ for (c = 0; c < 3; c++) {
+ cb->lift[c] = 1.0;
+ cb->gamma[c] = 1.0;
+ cb->gain[c] = 1.0;
+ }
+ }
+
+ uiDefBut(block, LABEL, 0, "Lift",
+ 10,30,80,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Gamma",
+ 90,30,80,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Gain",
+ 170,30,80,19, 0, 0, 0, 0, 0, "");
+
+ uiDefButF(block, COL, B_SEQ_BUT_RELOAD, "Lift",
+ 10,10,80,19, last_seq->strip->color_balance->lift,
+ 0, 0, 0, 0, "Lift (shadows)");
+
+ uiDefButF(block, COL, B_SEQ_BUT_RELOAD, "Gamma",
+ 90,10,80,19, last_seq->strip->color_balance->gamma,
+ 0, 0, 0, 0, "Gamma (midtones)");
+
+ uiDefButF(block, COL, B_SEQ_BUT_RELOAD, "Gain",
+ 170,10,80,19, last_seq->strip->color_balance->gain,
+ 0, 0, 0, 0, "Gain (highlights)");
+
+ uiDefButBitI(block, TOG, SEQ_COLOR_BALANCE_INVERSE_LIFT,
+ B_SEQ_BUT_RELOAD, "Inv Lift",
+ 10,-10,80,19,
+ &last_seq->strip->color_balance->flag,
+ 0.0, 21.0, 100, 0,
+ "Inverse Lift");
+ uiDefButBitI(block, TOG, SEQ_COLOR_BALANCE_INVERSE_GAMMA,
+ B_SEQ_BUT_RELOAD, "Inv Gamma",
+ 90,-10,80,19,
+ &last_seq->strip->color_balance->flag,
+ 0.0, 21.0, 100, 0,
+ "Inverse Gamma");
+ uiDefButBitI(block, TOG, SEQ_COLOR_BALANCE_INVERSE_GAIN,
+ B_SEQ_BUT_RELOAD, "Inv Gain",
+ 170,-10,80,19,
+ &last_seq->strip->color_balance->flag,
+ 0.0, 21.0, 100, 0,
+ "Inverse Gain");
+ }
+
+
+ uiBlockEndAlign(block);
+
+}
+
+
+static void seq_panel_filter_audio()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_filter",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Filter", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, "");
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, "");
+ uiBlockEndAlign(block);
+}
+
+static void seq_panel_effect()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_effect",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Effect", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+ if(last_seq->type == SEQ_PLUGIN) {
+ PluginSeq *pis;
+ VarStruct *varstr;
+ int a, xco, yco;
+
+ get_sequence_effect(last_seq);/* make sure, plugin is loaded */
+
+ pis= last_seq->plugin;
+ if(pis->vars==0) return;
+
+ varstr= pis->varstr;
+ if(varstr) {
+ for(a=0; a<pis->vars; a++, varstr++) {
+ xco= 150*(a/6)+10;
+ yco= 125 - 20*(a % 6)+1;
+ uiDefBut(block, varstr->type, B_SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
+
+ }
+ }
+ return;
+ }
+
+ uiBlockBeginAlign(block);
+
+ if(last_seq->type==SEQ_WIPE){
+ WipeVars *wipe = (WipeVars *)last_seq->effectdata;
+ char formatstring[256];
+
+ strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255);
+ uiDefButS(block, MENU,B_SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed");
+ uiDefButF(block, NUM,B_SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge");
+ switch(wipe->wipetype){ /*Skip Types that do not require angle*/
+ case DO_IRIS_WIPE:
+ case DO_CLOCK_WIPE:
+ break;
+
+ default:
+ uiDefButF(block, NUM,B_SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge");
+ }
+ uiDefButS(block, TOG,B_SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe");
+ } else if(last_seq->type==SEQ_GLOW){
+ GlowVars *glow = (GlowVars *)last_seq->effectdata;
+
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect");
+ uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect");
+ uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only");
+ }
+ else if(last_seq->type==SEQ_TRANSFORM){
+ TransformVars *transform = (TransformVars *)last_seq->effectdata;
+
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End");
+
+ uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Percent", 10, 30, 150, 19, &transform->percent, 0.0, 1.0, 0.0, 0.0, "Percent Translate");
+ uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Pixels", 160, 30, 150, 19, &transform->percent, 0.0, 0.0, 0.0, 0.0, "Pixels Translate");
+ if(transform->percent==1){
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -500.0, 500.0, 0, 0, "X Position Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -500.0, 500.0, 0, 0, "X Position End");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -500.0, 500.0, 0, 0, "Y Position Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -500.0, 500.0, 0, 0, "Y Position End");
+ } else {
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x Start:", 10,10,150,19, &transform->xIni, -10000.0, 10000.0, 0, 0, "X Position Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "x End:", 160,10,150,19, &transform->xFin, -10000.0, 10000.0, 0, 0, "X Position End");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y Start:", 10,-10,150,19, &transform->yIni, -10000.0, 10000.0, 0, 0, "Y Position Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "y End:", 160,-10,150,19, &transform->yFin, -10000.0, 10000.0, 0, 0, "Y Position End");
+
+ }
+
+
+
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "rot Start:",10,-30,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start");
+ uiDefButF(block, NUM, B_SEQ_BUT_EFFECT, "rot End:",160,-30,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End");
+
+ uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "No Interpolat", 10, -50, 100, 19, &transform->interpolation, 0.0, 0.0, 0.0, 0.0, "No interpolation");
+ uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Bilinear", 101, -50, 100, 19, &transform->interpolation, 0.0, 1.0, 0.0, 0.0, "Bilinear interpolation");
+ uiDefButI(block, ROW, B_SEQ_BUT_EFFECT, "Bicubic", 202, -50, 100, 19, &transform->interpolation, 0.0, 2.0, 0.0, 0.0, "Bicubic interpolation");
+ } else if(last_seq->type==SEQ_COLOR) {
+ SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata;
+ uiDefButF(block, COL, B_SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, "");
+ } else if(last_seq->type==SEQ_SPEED){
+ SpeedControlVars *sp =
+ (SpeedControlVars *)last_seq->effectdata;
+
+ uiDefButF(block, NUM, B_SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE,
+ B_SEQ_BUT_RELOAD,
+ "IPO is velocity",
+ 10,50,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Interpret the IPO value as a "
+ "velocity instead of a frame number");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_BLEND,
+ B_SEQ_BUT_RELOAD,
+ "Enable frame blending",
+ 10,30,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Blend two frames into the "
+ "target for a smoother result");
+
+ uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y,
+ B_SEQ_BUT_RELOAD,
+ "IPO value runs from [0..1]",
+ 10,10,150,19, &sp->flags,
+ 0.0, 1.0, 0, 0,
+ "Scale IPO value to get the "
+ "target frame number.");
+ }
+
+ uiBlockEndAlign(block);
+}
+
+static void seq_panel_proxy()
+{
+ Sequence *last_seq = get_last_seq();
+ uiBlock *block;
+ block = uiNewBlock(&curarea->uiblocks, "seq_panel_proxy",
+ UI_EMBOSS, UI_HELV, curarea->win);
+
+ if(uiNewPanel(curarea, block, "Proxy", "Sequencer",
+ 10, 230, 318, 204) == 0) return;
+
+ uiBlockBeginAlign(block);
+
+ uiDefButBitI(block, TOG, SEQ_USE_PROXY,
+ B_SEQ_BUT_RELOAD, "Use Proxy",
+ 10,140,120,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Use a preview proxy for this strip");
+
+ if (last_seq->flag & SEQ_USE_PROXY) {
+ if (!last_seq->strip->proxy) {
+ last_seq->strip->proxy =
+ MEM_callocN(sizeof(struct StripProxy),
+ "StripProxy");
+ }
+
+ uiDefButBitI(block, TOG, SEQ_USE_PROXY_CUSTOM_DIR,
+ B_SEQ_BUT_RELOAD, "Custom Dir",
+ 130,140,120,19, &last_seq->flag,
+ 0.0, 21.0, 100, 0,
+ "Use a custom directory to store data");
+ }
+
+ if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD, "Dir: ",
+ 10,120,240,19, last_seq->strip->proxy->dir,
+ 0.0, 160.0, 100, 0, "");
+ }
+
+ if (last_seq->flag & SEQ_USE_PROXY) {
+ if (G.scene->r.size == 100) {
+ uiDefBut(block, LABEL, 0,
+ "Full render size selected, ",
+ 10,100,240,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0,
+ "so no proxy enabled!",
+ 10,80,240,19, 0, 0, 0, 0, 0, "");
+ } else if (last_seq->type != SEQ_MOVIE
+ && last_seq->type != SEQ_IMAGE
+ && !(last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)) {
+ uiDefBut(block, LABEL, 0,
+ "Cannot proxy this strip without ",
+ 10,100,240,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0,
+ "custom directory selection!",
+ 10,80,240,19, 0, 0, 0, 0, 0, "");
+
+ } else {
+ uiDefBut(block, BUT, B_SEQ_BUT_REBUILD_PROXY,
+ "Rebuild proxy",
+ 10,100,240,19, 0, 0, 0, 0, 0,
+ "Rebuild proxy for the "
+ "currently selected strip.");
+ }
+ }
+
+ uiBlockEndAlign(block);
+}
+
+
+void sequencer_panels()
+{
+ Sequence *last_seq = get_last_seq();
+ int panels = 0;
+ int type;
+
+ if(last_seq == NULL) {
+ return;
+ }
+
+ type = last_seq->type;
+
+ panels = SEQ_PANEL_EDITING;
+
+ if (type == SEQ_MOVIE || type == SEQ_IMAGE || type == SEQ_SCENE) {
+ panels |= SEQ_PANEL_INPUT | SEQ_PANEL_FILTER | SEQ_PANEL_PROXY;
+ }
+
+ if (type == SEQ_RAM_SOUND) {
+ panels |= SEQ_PANEL_FILTER;
+ }
+
+ if (type == SEQ_PLUGIN || type >= SEQ_EFFECT) {
+ panels |= SEQ_PANEL_EFFECT | SEQ_PANEL_PROXY;
+ }
+
+ if (panels & SEQ_PANEL_EDITING) {
+ seq_panel_editing();
+ }
+
+ if (panels & SEQ_PANEL_INPUT) {
+ seq_panel_input();
+ }
+
+ if (panels & SEQ_PANEL_FILTER) {
+ if (type == SEQ_RAM_SOUND || type == SEQ_HD_SOUND) {
+ seq_panel_filter_audio();
+ } else {
+ seq_panel_filter_video();
+ }
+ }
+
+ if (panels & SEQ_PANEL_EFFECT) {
+ seq_panel_effect();
+ }
+
+ if (panels & SEQ_PANEL_PROXY) {
+ seq_panel_proxy();
+ }
+}
+
+
+void do_sequencer_panels(unsigned short event)
+{
+ Sequence *last_seq = get_last_seq();
+
+ switch(event) {
+ case B_SEQ_BUT_PLUGIN:
+ case B_SEQ_BUT_EFFECT:
+ update_changed_seq_and_deps(last_seq, 0, 1);
+ break;
+ case B_SEQ_BUT_RELOAD_FILE:
+ reload_sequence_new_file(last_seq);
+ break;
+ case B_SEQ_BUT_REBUILD_PROXY:
+ seq_proxy_rebuild(last_seq);
+ break;
+ case B_SEQ_BUT_RELOAD:
+ case B_SEQ_BUT_RELOAD_ALL:
+ update_seq_ipo_rect(last_seq);
+ update_seq_icu_rects(last_seq);
+
+ free_imbuf_seq(); // frees all
+
+ break;
+ case B_SEQ_BUT_TRANSFORM:
+ calc_sequence(last_seq);
+ if (test_overlap_seq(last_seq))
+ shuffle_seq(last_seq);
+ break;
+ }
+
+ if (event == B_SEQ_BUT_RELOAD_ALL) {
+ allqueue(REDRAWALL, 0);
+ } else {
+ allqueue(REDRAWSEQ, 0);
+ }
+}
+
/* ************************* SCENE *********************** */
@@ -490,12 +1329,6 @@ static void backbuf_pic(char *name)
BIF_undo_push("Change background picture");
}
-static void ftype_pic(char *name)
-{
- strcpy(G.scene->r.ftype, name);
- allqueue(REDRAWBUTSSCENE, 0);
-}
-
static void run_playanim(char *file)
{
extern char bprogname[]; /* usiblender.c */
@@ -506,9 +1339,9 @@ static void run_playanim(char *file)
calc_renderwin_rectangle((G.scene->r.xsch*G.scene->r.size)/100,
(G.scene->r.ysch*G.scene->r.size)/100, G.winpos, pos, size);
#ifdef WIN32
- sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file);
+ sprintf(str, "%s -a -s %d -e %d -p %d %d -f %d %g \"%s\"", bprogname, G.scene->r.sfra, G.scene->r.efra, pos[0], pos[1], G.scene->r.frs_sec, G.scene->r.frs_sec_base, file);
#else
- sprintf(str, "\"%s\" -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file);
+ sprintf(str, "\"%s\" -a -s %d -e %d -p %d %d -f %d %g \"%s\"", bprogname, G.scene->r.sfra, G.scene->r.efra, pos[0], pos[1], G.scene->r.frs_sec, G.scene->r.frs_sec_base, file);
#endif
system(str);
}
@@ -594,15 +1427,6 @@ void do_render_panels(unsigned short event)
else
activate_fileselect(FILE_SPECIAL, "SELECT BACKBUF PICTURE", G.scene->r.backbuf, backbuf_pic);
break;
-
- case B_FS_FTYPE:
- sa= closest_bigger_area();
- areawinset(sa->win);
- if(G.qual == LR_CTRLKEY)
- activate_imageselect(FILE_SPECIAL, "SELECT FTYPE", G.scene->r.ftype, ftype_pic);
- else
- activate_fileselect(FILE_SPECIAL, "SELECT FTYPE", G.scene->r.ftype, ftype_pic);
- break;
case B_PR_PAL:
G.scene->r.xsch= 720;
@@ -611,6 +1435,7 @@ void do_render_panels(unsigned short event)
G.scene->r.yasp= 51;
G.scene->r.size= 100;
G.scene->r.frs_sec= 25;
+ G.scene->r.frs_sec_base= 1;
G.scene->r.mode &= ~R_PANORAMA;
G.scene->r.xparts= G.scene->r.yparts= 4;
#ifdef WITH_FFMPEG
@@ -717,6 +1542,7 @@ void do_render_panels(unsigned short event)
G.scene->r.yasp= 45;
G.scene->r.size= 100;
G.scene->r.frs_sec= 25;
+ G.scene->r.frs_sec_base= 1;
G.scene->r.mode &= ~R_PANORAMA;
G.scene->r.xparts= G.scene->r.yparts= 4;
#ifdef WITH_FFMPEG
@@ -748,7 +1574,7 @@ void do_render_panels(unsigned short event)
G.scene->r.xasp= 54;
G.scene->r.yasp= 51;
G.scene->r.size= 100;
- G.scene->r.mode= R_OSA+R_SHADOW+R_FIELDS;
+ G.scene->r.mode= R_OSA+R_SHADOW+R_FIELDS+R_SSS;
G.scene->r.imtype= R_TARGA;
G.scene->r.xparts= G.scene->r.yparts= 4;
@@ -779,6 +1605,7 @@ void do_render_panels(unsigned short event)
G.scene->r.yasp= 11;
G.scene->r.size= 100;
G.scene->r.frs_sec= 30;
+ G.scene->r.frs_sec_base = 1.001;
G.scene->r.mode &= ~R_PANORAMA;
G.scene->r.xparts= G.scene->r.yparts= 2;
#ifdef WITH_FFMPEG
@@ -801,7 +1628,7 @@ void do_render_panels(unsigned short event)
Scene *newset= (Scene*) BLI_findlink(&G.main->scene, G.buts->menunr-1);
if (newset==G.scene)
- error("Not allowed");
+ error("Can't use the same scene as its own set");
else if (newset) {
G.scene->set= newset;
if (scene_check_setscene(G.scene)==0)
@@ -1041,6 +1868,11 @@ static char *imagetype_pup(void)
#endif
strcat(formatstring, "|%s %%x%d"); // add space for PNG
+/* Commented out until implemented
+#ifdef WITH_DDS
+ strcat(formatstring, "|%s %%x%d"); // add space for DDS
+#endif
+*/
strcat(formatstring, "|%s %%x%d"); // add space for BMP
strcat(formatstring, "|%s %%x%d"); // add space for Radiance HDR
strcat(formatstring, "|%s %%x%d"); // add space for Cineon
@@ -1077,6 +1909,11 @@ static char *imagetype_pup(void)
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
+/* commented out until implemented
+#ifdef WITH_DDS
+ "DDS", R_DDS,
+#endif
+*/
"BMP", R_BMP,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
@@ -1102,6 +1939,9 @@ static char *imagetype_pup(void)
"Targa", R_TARGA,
"Targa Raw", R_RAWTGA,
"PNG", R_PNG,
+/*#ifdef WITH_DDS
+ "DDS", R_DDS,
+#endif*/
"BMP", R_BMP,
"Jpeg", R_JPEG90,
"HamX", R_HAMX,
@@ -1150,7 +1990,6 @@ static void render_panel_output(void)
uiBlock *block;
char *strp;
-
block= uiNewBlock(&curarea->uiblocks, "render_panel_output", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Output", "Render", 0, 0, 318, 204)==0) return;
@@ -1159,63 +1998,77 @@ static void render_panel_output(void)
uiDefBut(block, TEX,0,"", 31, 190, 279, 20,G.scene->r.pic, 0.0,79.0, 0, 0, "Directory/name to save rendered Pics to");
uiDefIconBut(block, BUT,B_FS_BACKBUF, ICON_FILESEL, 10, 168, 20, 20, 0, 0, 0, 0, 0, "Open Fileselect to get Backbuf image");
uiDefBut(block, TEX,0,"", 31, 168, 279, 20,G.scene->r.backbuf, 0.0,79.0, 0, 0, "Image to use as background for rendering");
- uiDefIconBut(block, BUT,B_FS_FTYPE, ICON_FILESEL, 10, 146, 20, 20, 0, 0, 0, 0, 0, "Open Fileselect to get Ftype image");
- uiDefBut(block, TEX,0,"", 31, 146, 279, 20,G.scene->r.ftype,0.0,79.0, 0, 0, "Image to use with FTYPE Image type");
uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_TOUCH, B_NOP, "Touch", 10, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)");
+ uiDefButBitI(block, TOG, R_NO_OVERWRITE, B_NOP, "No Overwrite", 60, 142, 90, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Skip rendering frames when the file exists (image output only)");
+ uiBlockEndAlign(block);
+ uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 160, 142, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image");
/* SET BUTTON */
uiBlockBeginAlign(block);
id= (ID *)G.scene->set;
IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), id, &(G.buts->menunr));
if(strp[0])
- uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 120, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set");
+ uiDefButS(block, MENU, B_SETBROWSE, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set");
MEM_freeN(strp);
if(G.scene->set) {
uiSetButLock(1, NULL);
- uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 120, 100, 20, &(G.scene->set), "Name of the Set");
+ uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, B_NOP, "", 31, 114, 100, 20, &(G.scene->set), "Name of the Set");
uiClearButLock();
- uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 120, 20, 20, 0, 0, 0, 0, 0, "Remove Set link");
+ uiDefIconBut(block, BUT, B_CLEARSET, ICON_X, 132, 114, 20, 20, 0, 0, 0, 0, 0, "Remove Set link");
}
uiBlockEndAlign(block);
- uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButBitS(block, TOG, R_BACKBUF, B_NOP,"Backbuf", 10, 94, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image");
- uiDefButS(block, NUM, B_NOP, "Threads:", 10, 68, 100, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render");
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOGN, R_FIXED_THREADS, B_REDR, ICON_AUTO, 10, 63, 20, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Automatically set the threads to the number of processors on the system");
+ if ((G.scene->r.mode & R_FIXED_THREADS)==0) {
+ char thread_str[16];
+ sprintf(thread_str, " Threads: %d", BLI_system_thread_count());
+ uiDefBut(block, LABEL, 0, thread_str, 30, 63,80,20, 0, 0, 0, 0, 0, "");
+ } else {
+ uiDefButS(block, NUM, B_NOP, "Threads:", 30, 63, 80, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render (takes advantage of multi-core and multi-processor computers)");
+ }
+ uiBlockEndAlign(block);
+
uiBlockSetCol(block, TH_AUTO);
uiBlockBeginAlign(block);
for(b=2; b>=0; b--)
for(a=0; a<3; a++)
uiDefButBitS(block, TOG, 1<<(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen");
- uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_NOP, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save the tiles for all RenderLayers and used SceneNodes to files, to save memory");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, R_EXR_TILE_FILE, B_REDR, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save tiles for all RenderLayers and used SceneNodes to files in the temp directory (saves memory, allows Full Sampling)");
+ if(G.scene->r.scemode & R_EXR_TILE_FILE)
+ uiDefButBitS(block, TOG, R_FULL_SAMPLE, B_REDR, "FullSample", 192, 31, 118, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Saves for every OSA sample the entire RenderLayer results (Higher quality sampling but slower)");
+ uiBlockEndAlign(block);
uiDefButS(block, MENU, B_REDR, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2",
72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display");
- uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations");
-
+ uiDefButBitS(block, TOG, R_EXTENSION, B_NOP, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds filetype extensions to the filename when rendering animations");
+
/* Dither control */
- uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
+ uiDefButF(block, NUM,B_DIFF, "Dither:", 10,89,100,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
/* Toon shading buttons */
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 100, 94, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
- uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 94, 140, 20, "Display Edge settings");
+ uiDefButBitI(block, TOG, R_EDGE, B_NOP,"Edge", 115, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
+ uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 135, 20, "Display Edge settings");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, R_NO_TEX, B_NOP, "Disable Tex", 115, 68, 70, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Disables Textures for render");
- uiDefButBitS(block, TOG, R_FREE_IMAGE, B_NOP, "Free Tex Images", 205, 68, 100, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Frees all Images used by Textures after each render");
+ uiDefButBitS(block, TOG, R_NO_TEX, B_NOP, "Disable Tex", 115, 63, 70, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Disables Textures for render");
+ uiDefButBitS(block, TOG, R_FREE_IMAGE, B_NOP, "Free Tex Images", 205, 63, 100, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Frees all Images used by Textures after each render");
uiBlockEndAlign(block);
}
static void do_bake_func(void *unused_v, void *unused_p)
{
- objects_bake_render(0);
+ objects_bake_render_ui(0);
}
static void render_panel_bake(void)
@@ -1229,6 +2082,23 @@ static void render_panel_bake(void)
but= uiDefBut(block, BUT, B_NOP, "BAKE", 10, 150, 190,40, 0, 0, 0, 0, 0, "Start the bake render for selected Objects");
uiButSetFunc(but, do_bake_func, NULL, NULL);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, R_BAKE_TO_ACTIVE, B_DIFF, "Selected to Active", 10,120,190,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Bake shading on the surface of selected objects to the active object");
+ uiDefButF(block, NUM, B_DIFF, "Dist:", 10,100,95,20,&G.scene->r.bake_maxdist, 0.0, 1000.0, 1, 0, "Maximum distance from active object to other object (in blender units)");
+ uiDefButF(block, NUM, B_DIFF, "Bias:", 105,100,95,20,&G.scene->r.bake_biasdist, 0.0, 1000.0, 1, 0, "Bias towards faces further away from the object (in blender units)");
+ uiBlockEndAlign(block);
+
+ if(G.scene->r.bake_mode == RE_BAKE_NORMALS)
+ uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3",
+ 10,70,190,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
+ else if(G.scene->r.bake_mode == RE_BAKE_AO || G.scene->r.bake_mode == RE_BAKE_DISPLACEMENT) {
+ uiDefButBitS(block, TOG, R_BAKE_NORMALIZE, B_DIFF, "Normalized", 10,70,190,20, &G.scene->r.bake_flag, 0.0, 0, 0, 0,
+ G.scene->r.bake_mode == RE_BAKE_AO ?
+ "Bake ambient occlusion normalized, without taking into acount material settings":
+ "Normalized displacement value to fit the 'Dist' range"
+ );
+ }
#if 0
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, R_BAKE_OSA, B_DIFF, "OSA", 10,120,190,20, &G.scene->r.bake_flag, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
@@ -1238,15 +2108,37 @@ static void render_panel_bake(void)
uiDefButS(block, ROW,B_DIFF,"16", 150,100,50,20,&G.scene->r.bake_osa,2.0,16.0, 0, 0, "Sets oversample level to 16");
#endif
uiBlockBeginAlign(block);
- uiDefButS(block, ROW,B_DIFF,"Full Render", 210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, "");
- uiDefButS(block, ROW,B_DIFF,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, "");
- uiDefButS(block, ROW,B_DIFF,"Normals", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, "");
- uiDefButS(block, ROW,B_DIFF,"Textures", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, "");
+ uiDefButS(block, ROW,B_REDR,"Full Render", 210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, "");
+ uiDefButS(block, ROW,B_REDR,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, "");
+ uiDefButS(block, ROW,B_REDR,"Normals", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, "");
+ uiDefButS(block, ROW,B_REDR,"Textures", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, "");
+ uiDefButS(block, ROW,B_REDR,"Displacement", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, "");
uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,80,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking");
+ uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,60,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking");
+
+ uiDefButS(block, NUM, B_DIFF,"Margin:", 210,30,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter");
+}
+
+static void render_panel_simplify(void)
+{
+ uiBlock *block;
- uiDefButS(block, NUM, B_DIFF,"Margin:", 210,50,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter");
+ block= uiNewBlock(&curarea->uiblocks, "render_panel_simplify", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Render", "Render");
+ if(uiNewPanel(curarea, block, "Simplifcation", "Render", 320, 0, 318, 204)==0) return;
+
+ uiDefButBitI(block, TOG, R_SIMPLIFY, B_DIFF,"Render Simplification", 10,150,190,20, &G.scene->r.mode, 0, 0, 0, 0, "Enable simplification of scene");
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM,B_DIFF, "Subsurf:", 10,120,190,20, &G.scene->r.simplify_subsurf, 0.0, 6.0, 0, 0, "Global maximum subsurf level percentage");
+ uiDefButF(block, NUM,B_DIFF, "Child Particles:", 10,100,190,20, &G.scene->r.simplify_particles, 0.0, 1.0, 0, 0, "Global child particle percentage");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM,B_DIFF, "Shadow Samples:", 10,70,190,20, &G.scene->r.simplify_shadowsamples, 1.0, 16.0, 0, 0, "Global maximum shadow map samples");
+ uiDefButF(block, NUM,B_DIFF, "AO and SSS:", 10,50,190,20, &G.scene->r.simplify_aosss, 0.0, 1.0, 0, 0, "Global approximate AO and SSS quality factor");
+ uiBlockEndAlign(block);
}
static void render_panel_render(void)
@@ -1258,7 +2150,7 @@ static void render_panel_render(void)
if(uiNewPanel(curarea, block, "Render", "Render", 320, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
- uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Start the rendering");
+ uiDefBut(block, BUT,B_DORENDER,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)");
#ifndef DISABLE_YAFRAY
/* yafray: on request, render engine menu is back again, and moved to Render panel */
uiDefButS(block, MENU, B_SWITCHRENDER, "Rendering Engine %t|Blender Internal %x0|YafRay %x1",
@@ -1269,11 +2161,14 @@ static void render_panel_render(void)
#endif /* disable yafray */
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
- uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Sets oversample level to 5");
- uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Sets oversample level to 8 (Recommended)");
- uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Sets oversample level to 11");
- uiDefButS(block, ROW,B_DIFF,"16", 462,88,29,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Sets oversample level to 16");
+ if((G.scene->r.scemode & R_FULL_SAMPLE) && (G.scene->r.scemode & R_EXR_TILE_FILE))
+ uiDefButBitI(block, TOG, R_OSA, B_DIFF, "FSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Saves all samples, then composites, and then merges (for best Anti-aliasing)");
+ else
+ uiDefButBitI(block, TOG, R_OSA, B_DIFF, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
+ uiDefButS(block, ROW,B_DIFF,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Render 5 samples per pixel for smooth edges (Fast)");
+ uiDefButS(block, ROW,B_DIFF,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Render 8 samples per pixel for smooth edges (Recommended)");
+ uiDefButS(block, ROW,B_DIFF,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Render 11 samples per pixel for smooth edges (High Quality)");
+ uiDefButS(block, ROW,B_DIFF,"16", 462,88,29,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Render 16 samples per pixel for smooth edges (Highest Quality)");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -1296,11 +2191,12 @@ static void render_panel_render(void)
uiDefButS(block, MENU, B_DIFF,"Octree resolution %t|64 %x64|128 %x128|256 %x256|512 %x512", 496,13,64,20,&G.scene->r.ocres,0.0,0.0, 0, 0, "Octree resolution for ray tracing");
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, R_SHADOW, B_REDR,"Shadow", 565,172,60,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
- uiDefButBitI(block, TOG, R_ENVMAP, B_REDR,"EnvMap", 627,172,60,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable environment map rendering");
- uiDefButBitI(block, TOG, R_PANORAMA, B_REDR,"Pano", 565,142,40,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)");
- uiDefButBitI(block, TOG, R_RAYTRACE, B_REDR,"Ray",606,142,40,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable ray tracing");
- uiDefButBitI(block, TOG, R_RADIO, B_REDR,"Radio", 647,142,40,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
+ uiDefButBitI(block, TOG, R_SHADOW, B_REDR,"Shadow", 565,172,52,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
+ uiDefButBitI(block, TOG, R_SSS, B_REDR,"SSS", 617,172,32,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable subsurface scattering map rendering");
+ uiDefButBitI(block, TOG, R_PANORAMA, B_REDR,"Pano", 649,172,38,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)");
+ uiDefButBitI(block, TOG, R_ENVMAP, B_REDR,"EnvMap", 565,142,52,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable environment map rendering");
+ uiDefButBitI(block, TOG, R_RAYTRACE, B_REDR,"Ray",617,142,32,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable ray tracing");
+ uiDefButBitI(block, TOG, R_RADIO, B_REDR,"Radio", 649,142,38,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -1319,7 +2215,7 @@ static void render_panel_render(void)
uiDefButS(block, MENU, B_DIFF,str, 565,34,60,20, &G.scene->r.filtertype, 0, 0, 0, 0, "Set sampling filter for antialiasing");
uiDefButF(block, NUM,B_DIFF,"", 627,34,60,20,&G.scene->r.gauss,0.5, 1.5, 10, 2, "Sets the filter size");
- uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image");
+ uiDefButBitI(block, TOG, R_BORDER, REDRAWVIEWCAM, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image (Shift+B to set in the camera view)");
uiBlockEndAlign(block);
}
@@ -1333,7 +2229,7 @@ static void render_panel_anim(void)
if(uiNewPanel(curarea, block, "Anim", "Render", 640, 0, 318, 204)==0) return;
- uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Start rendering a sequence");
+ uiDefBut(block, BUT,B_DOANIM,"ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Render the animation to disk from start to end frame, (Ctrl+F12)");
uiBlockSetCol(block, TH_BUT_SETTING1);
uiBlockBeginAlign(block);
@@ -1342,12 +2238,12 @@ static void render_panel_anim(void)
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_AUTO);
- uiDefBut(block, BUT,B_PLAYANIM, "PLAY",692,40,94,33, 0, 0, 0, 0, 0, "Play animation of rendered images/avi (searches Pics: field)");
+ uiDefBut(block, BUT,B_PLAYANIM, "PLAY",692,40,94,33, 0, 0, 0, 0, 0, "Play rendered images/avi animation (Ctrl+F11), (Play Hotkeys: A-Noskip, P-PingPong)");
uiDefButS(block, NUM, B_RTCHANGED, "rt:",789,40,95,33, &G.rt, -1000.0, 1000.0, 0, 0, "General testing/debug button");
uiBlockBeginAlign(block);
- uiDefButI(block, NUM,REDRAWSEQ,"Sta:",692,10,94,24, &G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "The start frame of the animation");
- uiDefButI(block, NUM,REDRAWSEQ,"End:",789,10,95,24, &G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0, "The end frame of the animation");
+ uiDefButI(block, NUM,REDRAWSEQ,"Sta:",692,10,94,24, &G.scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "The start frame of the animation (inclusive)");
+ uiDefButI(block, NUM,REDRAWSEQ,"End:",789,10,95,24, &G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0, "The end frame of the animation (inclusive)");
uiBlockEndAlign(block);
}
@@ -1512,6 +2408,70 @@ static void render_panel_ffmpeg_audio(void)
}
#endif
+static void render_panel_stamp(void)
+{
+ uiBlock *block;
+ int yofs=0, xofs=550;
+
+ block= uiNewBlock (&curarea->uiblocks, "render_panel_stamp", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed ("Format", "Render");
+ if(uiNewPanel (curarea, block, "Stamp", "Render", 960, 0, 318, 204)==0) return;
+
+ if (G.scene->r.scemode & R_STAMP_INFO) {
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_STAMP_NOTE, B_REDR, "Note", xofs, yofs, 120, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp user data");
+ uiDefBut(block, TEX, B_NOP, "", xofs+120, yofs, 180, 19, &G.scene->r.stamp_udata, 0.0, 128.0, 100, 0, "User Note");
+ uiBlockEndAlign(block);
+ yofs += 30; /* gap */
+
+
+ yofs += 80;
+ /* Order is important for alligning ... grr */
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_STAMP_FILENAME, B_REDR, "Filename", xofs, yofs, 120, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp blend filename");
+ yofs -= 20;
+ uiDefButBitI(block, TOG, R_STAMP_SCENE, B_REDR, "Scene", xofs, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp scene name");
+ uiDefButBitI(block, TOG, R_STAMP_CAMERA, B_REDR, "Camera", xofs+60, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp camera name");
+ yofs -= 20;
+ uiDefButBitI(block, TOG, R_STAMP_TIME, B_REDR, "Time", xofs, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp time (HH:MM:SS)");
+ uiDefButBitI(block, TOG, R_STAMP_DATE, B_REDR, "Date", xofs+60, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp date");
+ yofs -= 20;
+ uiDefButBitI(block, TOG, R_STAMP_FRAME, B_REDR, "Frame", xofs, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp frame number");
+ uiDefButBitI(block, TOG, R_STAMP_MARKER, B_REDR, "Marker", xofs+60, yofs, 60, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp the last marker");
+ yofs -= 20;
+ uiDefButBitI(block, TOG, R_STAMP_SEQSTRIP, B_REDR, "Sequence Strip", xofs, yofs, 120, 19, &G.scene->r.stamp, 0, 0, 0, 0, "Stamp the forground sequence strip name");
+ uiBlockEndAlign(block);
+ yofs += 80;
+
+ /* draw font selector */
+ if (G.scene->r.stamp & R_STAMP_DRAW) {
+ uiDefButS(block, MENU, B_REDR, "Stamp Font Size%t|Tiny Text%x1|Small Text%x2|Medium Text%x3|Large Text%x0|Extra Large Text%x4|",
+ xofs+130, yofs, 170, 19, &G.scene->r.stamp_font_id, 0, 0, 0, 0, "Choose stamp text size");
+
+ /* draw fg/bg next to the scene */
+ yofs -= 25;
+ uiDefBut(block, LABEL, B_NOP, "Text Color", xofs+130, yofs, 70, 19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, B_NOP, "Background", xofs+215, yofs, 70, 19, 0, 0, 0, 0, 0, "");
+ yofs -= 20;
+ uiDefButF(block, COL, B_NOP, "", xofs+130, yofs, 80, 19, G.scene->r.fg_stamp, 0, 0, 0, 0, "Foreground text color");
+ uiDefButF(block, COL, B_NOP, "", xofs+220, yofs, 80, 19, G.scene->r.bg_stamp, 0, 0, 0, 0, "Background color");
+ yofs -= 30;
+ uiDefButF(block, NUMSLI, B_NOP, "A ", xofs+130, yofs, 170, 19, &G.scene->r.bg_stamp[3], 0, 1.0, 0, 0, "Alpha for text background");
+ yofs += 105;
+ } else {
+ yofs += 30;
+ }
+
+ uiDefButBitS(block, TOG, R_STAMP_INFO, B_REDR, "Enable Stamp", xofs, yofs, 120, 20, &G.scene->r.scemode, 0, 0, 0, 0, "Disable stamp info in images metadata");
+ uiDefButBitI(block, TOG, R_STAMP_DRAW, B_REDR, "Draw Stamp", xofs+130, yofs, 170, 20, &G.scene->r.stamp, 0, 0, 0, 0, "Draw the stamp info into each frame");
+ yofs += 20;
+ }
+ else {
+ uiDefButBitS(block, TOG, R_STAMP_INFO, B_REDR, "Enable Stamp", xofs, 142, 120, 20, &G.scene->r.scemode, 0, 0, 0, 0, "Enable stamp info to image metadata");
+ yofs += 20;
+ uiDefBut(block, LABEL, 0, "", xofs, yofs, 300, 19, 0, 0, 0, 0, 0, "");
+ }
+}
static void render_panel_format(void)
{
@@ -1552,11 +2512,7 @@ static void render_panel_format(void)
if(G.scene->r.quality==0) G.scene->r.quality= 90;
-#ifdef WITH_QUICKTIME
if (G.scene->r.imtype == R_AVICODEC || G.scene->r.imtype == R_QUICKTIME) {
-#else /* WITH_QUICKTIME */
- if (0) {
-#endif
if(G.scene->r.imtype == R_QUICKTIME) {
#ifdef WITH_QUICKTIME
#if defined (_WIN32) || defined (__APPLE__)
@@ -1566,7 +2522,7 @@ static void render_panel_format(void)
uiDefBut(block, LABEL, 0, "Codec: not set", 892,yofs+44,225,20, 0, 0, 0, 0, 0, "");
else
uiDefBut(block, LABEL, 0, G.scene->r.qtcodecdata->qtcodecname, 892,yofs+44,225,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for Quicktime");
+ uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,74,20, 0, 0, 0, 0, 0, "Set codec settings for Quicktime");
#endif
#endif /* WITH_QUICKTIME */
} else {
@@ -1578,7 +2534,7 @@ static void render_panel_format(void)
else
uiDefBut(block, LABEL, 0, avicodec_str(), 892,yofs+43,225,20, 0, 0, 0, 0, 0, "");
#endif
- uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for AVI");
+ uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,74,20, 0, 0, 0, 0, 0, "Set codec settings for AVI");
}
#ifdef WITH_OPENEXR
}
@@ -1587,21 +2543,34 @@ static void render_panel_format(void)
if(G.scene->r.imtype==R_OPENEXR) {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_NOP,"Half", 892,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Use 16 bits float 'Half' type");
- uiDefButBitS(block, TOG, R_OPENEXR_ZBUF, B_NOP,"Zbuf", 952,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save the zbuffer as 32 bits unsigned int");
+ uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_NOP,"Half", 892,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Use 16 bit floats instead of 32 bit floats per channel");
+ uiDefButBitS(block, TOG, R_OPENEXR_ZBUF, B_NOP,"Zbuf", 952,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save the z-depth per pixel (32 bit unsigned int zbuffer)");
uiBlockEndAlign(block);
uiDefButBitS(block, TOG, R_PREVIEW_JPG, B_NOP,"Preview",1027,yofs+44,90,20, &G.scene->r.subimtype, 0, 0, 0, 0, "When animation render, save JPG preview images in same directory");
}
uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4",
- 892,yofs,112,20, &G.scene->r.quality, 0, 0, 0, 0, "Set codec settings for OpenEXR");
+ 892,yofs,74,20, &G.scene->r.quality, 0, 0, 0, 0, "Set codec settings for OpenEXR");
#endif
+ } else if (G.scene->r.imtype == R_DPX || G.scene->r.imtype == R_CINEON) {
+ uiDefButBitS(block, TOG, R_CINEON_LOG, B_REDR, "Log", 892,yofs,74,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Convert to log color space");
+
+ if(G.scene->r.subimtype & R_CINEON_LOG) {
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_NOP, "B", 892,yofs+44,80,20, &G.scene->r.cineonblack, 0, 1024, 0, 0, "Log conversion reference black");
+ uiDefButS(block, NUM, B_NOP, "W", 972,yofs+44,80,20, &G.scene->r.cineonwhite, 0, 1024, 0, 0, "Log conversion reference white");
+ uiDefButF(block, NUM, B_NOP, "G", 1052,yofs+44,70,20, &G.scene->r.cineongamma, 0.0f, 10.0f, 1, 2, "Log conversion gamma");
+ uiBlockEndAlign(block);
+ }
+ } else if (G.scene->r.imtype == R_TIFF) {
+ uiDefButBitS(block, TOG, R_TIFF_16BIT, B_REDR, "16 Bit", 892,yofs,74,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save 16 bit per channel TIFF");
} else {
if(G.scene->r.quality < 5) G.scene->r.quality = 90; /* restore from openexr */
- uiDefButS(block, NUM,B_DIFF, "Quality:", 892,yofs,112,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies");
+ uiDefButS(block, NUM,B_DIFF, "Q:", 892,yofs,74,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies");
}
- uiDefButS(block, NUM,B_FRAMEMAP,"Frs/sec:", 1006,yofs,113,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
+ uiDefButS(block, NUM,B_FRAMEMAP,"FPS:", 968,yofs,75,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
+ uiDefButF(block, NUM,B_FRAMEMAP,"/", 1043,yofs,75,20, &G.scene->r.frs_sec_base, 1.0, 120.0, 0.1, 3, "Frames per second base");
uiBlockBeginAlign(block);
@@ -1622,7 +2591,7 @@ static void render_panel_format(void)
uiBlockEndAlign(block);
}
-
+#ifndef DISABLE_YAFRAY /* disable yafray stuff */
/* yafray: global illumination options panel */
static void render_panel_yafrayGI()
{
@@ -1712,8 +2681,6 @@ static void render_panel_yafrayGlobal()
uiDefButF(block, NUMSLI, B_DIFF, "Gam ", 5,10,150,20, &G.scene->r.YF_gamma, 0.001, 5.0, 0, 0, "Gamma correction, 1 is off");
uiDefButF(block, NUMSLI, B_DIFF, "Exp ", 160,10,150,20,&G.scene->r.YF_exposure, 0.0, 10.0, 0, 0, "Exposure adjustment, 0 is off");
- uiDefButI(block, NUM, B_DIFF, "Processors:", 160,60,150,20, &G.scene->r.YF_numprocs, 1.0, 8.0, 10, 10, "Number of processors to use");
-
/*AA Settings*/
uiDefButBitS(block, TOGN, 1, B_REDR, "Auto AA", 5,140,150,20, &G.scene->r.YF_AA,
0, 0, 0, 0, "Set AA using OSA and GI quality, disable for manual control");
@@ -1725,14 +2692,14 @@ static void render_panel_yafrayGlobal()
uiDefButF(block, NUMSLI, B_DIFF, "Thr ", 160,90,150,20, &G.scene->r.YF_AAthreshold, 0.000001, 1.0, 0, 0, "AA threshold");
}
}
-
+#endif /* disable yafray stuff */
static void layer_copy_func(void *lay_v, void *lay_p)
{
unsigned int *lay= lay_p;
int laybit= (int)lay_v;
- if(G.qual & LR_SHIFTKEY) {
+ if(G.qual & (LR_SHIFTKEY|LR_CTRLKEY)) {
if(*lay==0) *lay= 1<<laybit;
}
else
@@ -1803,29 +2770,29 @@ static char *scene_layer_menu(void)
return str;
}
-static void draw_3d_layer_buttons(uiBlock *block, unsigned int *poin, short xco, short yco, short dx, short dy)
+static void draw_3d_layer_buttons(uiBlock *block, int type, unsigned int *poin, short xco, short yco, short dx, short dy, char *tip)
{
uiBut *bt;
long a;
uiBlockBeginAlign(block);
for(a=0; a<5; a++) {
- bt= uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt= uiDefButBitI(block, type, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=0; a<5; a++) {
- bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
xco+= 7;
uiBlockBeginAlign(block);
for(a=5; a<10; a++) {
- bt=uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=5; a<10; a++) {
- bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
@@ -1850,7 +2817,7 @@ static void render_panel_layers(void)
/* first, as reminder, the scene layers */
uiDefBut(block, LABEL, 0, "Scene:", 10,170,100,20, NULL, 0, 0, 0, 0, "");
- draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30);
+ draw_3d_layer_buttons(block, TOG, &G.scene->lay, 130, 170, 35, 30, "Scene layers to render");
/* layer disable, menu, name, delete button */
uiBlockBeginAlign(block);
@@ -1870,19 +2837,24 @@ static void render_panel_layers(void)
/* RenderLayer visible-layers */
uiDefBut(block, LABEL, 0, "Layer:", 10,110,100,20, NULL, 0, 0, 0, 0, "");
- draw_3d_layer_buttons(block, &srl->lay, 130,110, 35, 30);
+ draw_3d_layer_buttons(block, BUT_TOGDUAL, &srl->lay, 130,110, 35, 30, "Scene-layers included in this render-layer (Hold CTRL for Z-mask)");
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for all not-rendered faces, for masking");
+ uiDefButBitI(block, TOG, SCE_LAY_ZMASK, B_REDR,"Zmask", 10, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Only render what's in front of the solid z values");
+ if(srl->layflag & SCE_LAY_ZMASK)
+ uiDefButBitI(block, TOG, SCE_LAY_NEG_ZMASK, B_NOP,"Neg", 10, 65, 40, 20, &srl->layflag, 0, 0, 0, 0, "For Zmask, only render what is behind solid z values instead of in front");
+ else
+ uiDefButBitI(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 65, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for solid faces in invisible layers, for masking");
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 50, 85, 60, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer");
- uiDefButBitI(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 110, 85, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)");
- uiDefButBitI(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 165, 85, 55, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer (On top of Solid and Halos)");
- uiDefButBitI(block, TOG, SCE_LAY_SKY, B_NOP,"Sky", 220, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Sky or backbuffer in this Layer");
- uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge", 260, 85, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)");
-
- uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:", 10, 65, 150, 20, &(srl->light_override), "Name of Group to use as Lamps instead");
- uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:", 160, 65, 150, 20, &(srl->mat_override), "Name of Material to use as Materials instead");
+ uiDefButBitI(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 50, 85, 45, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer");
+ uiDefButBitI(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 95, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)");
+ uiDefButBitI(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 135, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer (On top of Solid and Halos)");
+ uiDefButBitI(block, TOG, SCE_LAY_SKY, B_NOP,"Sky", 175, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Sky or backbuffer in this Layer");
+ uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge", 215, 85, 45, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)");
+ uiDefButBitI(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand",260, 85, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Strands in this Layer");
+
+ uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:", 50, 65, 130, 20, &(srl->light_override), "Name of Group to use as Lamps instead");
+ uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:", 180, 65, 130, 20, &(srl->mat_override), "Name of Material to use as Materials instead");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
@@ -1891,16 +2863,17 @@ static void render_panel_layers(void)
uiDefButBitI(block, TOG, SCE_PASS_VECTOR, B_SET_PASS,"Vec", 120, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Speed Vector pass");
uiDefButBitI(block, TOG, SCE_PASS_NORMAL, B_SET_PASS,"Nor", 160, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Normal pass");
uiDefButBitI(block, TOG, SCE_PASS_UV, B_SET_PASS,"UV", 200, 30, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Texture UV pass");
- uiDefButBitI(block, TOG, SCE_PASS_INDEXOB, B_SET_PASS,"IndexOb",240, 30, 70, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Object Index pass");
+ uiDefButBitI(block, TOG, SCE_PASS_MIST, B_SET_PASS,"Mist", 240, 30, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Mist factor pass (0-1)");
+ uiDefButBitI(block, TOG, SCE_PASS_INDEXOB, B_SET_PASS,"Index", 275, 30, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Object Index pass");
uiDefButBitI(block, TOG, SCE_PASS_RGBA, B_SET_PASS,"Col", 10, 10, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver shade-less Color pass");
uiDefButBitI(block, TOG, SCE_PASS_DIFFUSE, B_SET_PASS,"Diff", 45, 10, 35, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SPEC, B_SET_PASS,"Spec", 80, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 120, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_AO, B_SET_PASS,"AO", 160, 10, 30, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 190, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass");
- uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_RADIO, B_SET_PASS,"Rad", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Radiosity pass");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SPEC, B_SET_PASS,"Spec", 80, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Specular pass (Hold Ctrl to exclude from combined)");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_SHADOW, B_SET_PASS,"Shad", 120, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Shadow pass (Hold Ctrl to exclude from combined)");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_AO, B_SET_PASS,"AO", 160, 10, 30, 20, &srl->passflag, 0, 0, 0, 0, "Deliver AO pass (Hold Ctrl to exclude from combined)");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFLECT, B_SET_PASS,"Refl", 190, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Reflection pass (Hold Ctrl to exclude from combined)");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_REFRACT, B_SET_PASS,"Refr", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Raytraced Refraction pass (Hold Ctrl to exclude from combined)");
+ uiDefButBitI(block, BUT_TOGDUAL, SCE_PASS_RADIO, B_SET_PASS,"Rad", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Radiosity pass (Hold Ctrl to exclude from combined)");
}
void render_panels()
@@ -1909,10 +2882,12 @@ void render_panels()
render_panel_output();
render_panel_layers();
render_panel_render();
+ if(G.rt == 1) render_panel_simplify();
render_panel_anim();
render_panel_bake();
render_panel_format();
+ render_panel_stamp();
#ifdef WITH_FFMPEG
if (G.scene->r.imtype == R_FFMPEG) {
render_panel_ffmpeg_video();
@@ -1951,7 +2926,9 @@ void anim_panels()
uiDefButI(block, NUM,B_FRAMEMAP,"Map New:", 160,160,150,20,&G.scene->r.images,1.0,900.0, 0, 0, "Specify how many frames the Map Old will last");
uiBlockBeginAlign(block);
- uiDefButS(block, NUM,B_FRAMEMAP,"Frs/sec:", 10,130,150,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
+ uiDefButS(block, NUM,B_FRAMEMAP,"FPS:", 10,130,75,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second");
+ uiDefButF(block, NUM,B_FRAMEMAP,"/", 85,130,75,20, &G.scene->r.frs_sec_base, 1.0, 120.0, 0.1, 3, "Frames per second base");
+
uiDefButBitS(block, TOG, AUDIO_SYNC, B_SOUND_CHANGED, "Sync",160,130,150,20, &G.scene->audio.flag, 0, 0, 0, 0, "Use sample clock for syncing animation to audio");
uiBlockBeginAlign(block);
diff --git a/source/blender/src/buttons_script.c b/source/blender/src/buttons_script.c
index 7b2057bed30..dd21dc75af1 100644
--- a/source/blender/src/buttons_script.c
+++ b/source/blender/src/buttons_script.c
@@ -265,9 +265,10 @@ void do_scriptbuts(unsigned short event)
}
allqueue(REDRAWBUTSSCRIPT, 0);
+ allqueue(REDRAWOOPS, 0);
}
-void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int scene)
+void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int idcode)
{
char str[256];
@@ -275,10 +276,13 @@ void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int sce
strcpy(str, "FrameChanged%x 1|");
strcat(str, "Redraw%x 4|");
strcat(str, "Render%x 16|");
- if (scene) {
+ if (idcode==ID_SCE) {
strcat(str, "OnLoad%x 2|");
strcat(str, "OnSave%x 8");
- }
+ } else {
+ strcat(str, "ObjectUpdate%x 64|");
+ strcat(str, "ObDataUpdate%x 128");
+ }
uiBlockBeginAlign(block);
uiDefButS(block, MENU, 1, str, (short)sx, (short)sy, 140, 19, &script->flag[script->actscript-1], 0, 0, 0, 0, "Script links for this event");
@@ -290,7 +294,7 @@ void draw_scriptlink(uiBlock *block, ScriptLink *script, int sx, int sy, int sce
uiDefButS(block, NUM, REDRAWBUTSSCRIPT, str, (short)(sx+140), (short)sy-20,60,19, &script->actscript, 1, script->totscript, 0, 0, "Total / Active Script link (LeftMouse + Drag to change)");
- if (scene) {
+ if (idcode==ID_SCE) {
if (script->totscript<32767)
uiDefBut(block, BUT, B_SSCRIPT_ADD, "New", (short)(sx+240), (short)sy-20, 40, 19, 0, 0, 0, 0, 0, "Add a new Script link");
@@ -367,9 +371,9 @@ static void script_panel_scriptlink(void)
script= &(G.scene->world->scriptlink);
}
- if (script) draw_scriptlink(block, script, 10, 140, 0);
+ if (script) draw_scriptlink(block, script, 10, 140, 0);
- draw_scriptlink(block, &G.scene->scriptlink, 10, 80, 1);
+ draw_scriptlink(block, &G.scene->scriptlink, 10, 80, ID_SCE);
}
}
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index 32a8245785b..f107102c7fc 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -52,6 +52,7 @@
#include "DNA_object_types.h"
#include "DNA_node_types.h"
#include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
#include "DNA_radio_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -61,6 +62,8 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
+#include "BKE_colortools.h"
+#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_global.h"
@@ -68,6 +71,7 @@
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
#include "BKE_texture.h"
@@ -94,6 +98,7 @@
#include "BIF_mywindow.h"
#include "BIF_space.h"
#include "BIF_glutil.h"
+#include "BIF_imasel.h"
#include "BIF_interface.h"
#include "BIF_toolbox.h"
#include "BIF_space.h"
@@ -137,6 +142,11 @@ static char *mapto_blendtype_pup(void)
str += sprintf(str, formatstr, "Darken", MTEX_DARK);
str += sprintf(str, formatstr, "Lighten", MTEX_LIGHT);
+ str += sprintf(str, formatstr, "Hue", MTEX_BLEND_HUE);
+ str += sprintf(str, formatstr, "Saturation", MTEX_BLEND_SAT);
+ str += sprintf(str, formatstr, "Value", MTEX_BLEND_VAL);
+ str += sprintf(str, formatstr, "Color", MTEX_BLEND_COLOR);
+
return string;
}
@@ -471,15 +481,15 @@ static void texture_panel_blend(Tex *tex)
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Lin", 10, 180, 75, 19, &tex->stype, 2.0, 0.0, 0, 0, "Creates a linear progresion");
- uiDefButS(block, ROW, B_TEXPRV, "Quad", 85, 180, 75, 19, &tex->stype, 2.0, 1.0, 0, 0, "Creates a quadratic progression");
- uiDefButS(block, ROW, B_TEXPRV, "Ease", 160, 180, 75, 19, &tex->stype, 2.0, 2.0, 0, 0, "Creates a progression easing from one step to the next");
+ uiDefButS(block, ROW, B_TEXPRV, "Lin", 10, 180, 75, 19, &tex->stype, 2.0, (float)TEX_LIN, 0, 0, "Creates a linear progresion");
+ uiDefButS(block, ROW, B_TEXPRV, "Quad", 85, 180, 75, 19, &tex->stype, 2.0, (float)TEX_QUAD, 0, 0, "Creates a quadratic progression");
+ uiDefButS(block, ROW, B_TEXPRV, "Ease", 160, 180, 75, 19, &tex->stype, 2.0, (float)TEX_EASE, 0, 0, "Creates a progression easing from one step to the next");
uiDefButBitS(block, TOG, TEX_FLIPBLEND, B_TEXPRV, "Flip XY", 235, 180, 75, 19, &tex->flag, 0, 0, 0, 0, "Flips the direction of the progression 90 degrees");
- uiDefButS(block, ROW, B_TEXPRV, "Diag", 10, 160, 75, 19, &tex->stype, 2.0, 3.0, 0, 0, "Use a diagonal progression");
- uiDefButS(block, ROW, B_TEXPRV, "Sphere", 85, 160, 75, 19, &tex->stype, 2.0, 4.0, 0, 0, "Use progression with the shape of a sphere");
- uiDefButS(block, ROW, B_TEXPRV, "Halo", 160, 160, 75, 19, &tex->stype, 2.0, 5.0, 0, 0, "Use a quadratic progression with the shape of a sphere");
- uiDefButS(block, ROW, B_TEXPRV, "Radial", 235, 160, 75, 19, &tex->stype, 2.0, 6.0, 0, 0, "Use a polar progression");
+ uiDefButS(block, ROW, B_TEXPRV, "Diag", 10, 160, 75, 19, &tex->stype, 2.0, (float)TEX_DIAG, 0, 0, "Use a diagonal progression");
+ uiDefButS(block, ROW, B_TEXPRV, "Sphere", 85, 160, 75, 19, &tex->stype, 2.0, (float)TEX_SPHERE, 0, 0, "Use progression with the shape of a sphere");
+ uiDefButS(block, ROW, B_TEXPRV, "Halo", 160, 160, 75, 19, &tex->stype, 2.0, (float)TEX_HALO, 0, 0, "Use a quadratic progression with the shape of a sphere");
+ uiDefButS(block, ROW, B_TEXPRV, "Radial", 235, 160, 75, 19, &tex->stype, 2.0, (float)TEX_RAD, 0, 0, "Use a polar progression");
}
@@ -500,16 +510,16 @@ static void texture_panel_wood(Tex *tex)
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Bands", 10, 180, 75, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard wood texture in bands");
- uiDefButS(block, ROW, B_TEXPRV, "Rings", 85, 180, 75, 18, &tex->stype, 2.0, 1.0, 0, 0, "Uses wood texture in rings");
- uiDefButS(block, ROW, B_TEXPRV, "BandNoise", 160, 180, 75, 18, &tex->stype, 2.0, 2.0, 0, 0, "Adds noise to standard wood");
- uiDefButS(block, ROW, B_TEXPRV, "RingNoise", 235, 180, 75, 18, &tex->stype, 2.0, 3.0, 0, 0, "Adds noise to rings");
+ uiDefButS(block, ROW, B_TEXPRV, "Bands", 10, 180, 75, 18, &tex->stype, 2.0, (float)TEX_BAND, 0, 0, "Uses standard wood texture in bands");
+ uiDefButS(block, ROW, B_TEXPRV, "Rings", 85, 180, 75, 18, &tex->stype, 2.0, (float)TEX_RING, 0, 0, "Uses wood texture in rings");
+ uiDefButS(block, ROW, B_TEXPRV, "BandNoise", 160, 180, 75, 18, &tex->stype, 2.0, (float)TEX_BANDNOISE, 0, 0, "Adds noise to standard wood");
+ uiDefButS(block, ROW, B_TEXPRV, "RingNoise", 235, 180, 75, 18, &tex->stype, 2.0, (float)TEX_RINGNOISE, 0, 0, "Adds noise to rings");
- uiDefButS(block, ROW, B_TEXPRV, "Sin", 10, 160, 50, 19, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands");
- uiDefButS(block, ROW, B_TEXPRV, "Saw", 60, 160, 50, 19, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
- uiDefButS(block, ROW, B_TEXPRV, "Tri", 110, 160, 50, 19, &tex->noisebasis2, 8.0, 2.0, 0, 0, "Uses a triangle wave to produce bands");
- uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 160, 160, 75, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 235, 160, 75, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Sin", 10, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_SIN, 0, 0, "Uses a sine wave to produce bands");
+ uiDefButS(block, ROW, B_TEXPRV, "Saw", 60, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_SAW, 0, 0, "Uses a saw wave to produce bands");
+ uiDefButS(block, ROW, B_TEXPRV, "Tri", 110, 160, 50, 19, &tex->noisebasis2, 8.0, (float)TEX_TRI, 0, 0, "Uses a triangle wave to produce bands");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 160, 160, 75, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 235, 160, 75, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
@@ -532,12 +542,12 @@ static void texture_panel_stucci(Tex *tex)
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Plastic", 10, 180, 100, 19, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard stucci");
- uiDefButS(block, ROW, B_TEXPRV, "Wall In", 110, 180, 100, 19, &tex->stype, 2.0, 1.0, 0, 0, "Creates Dimples");
- uiDefButS(block, ROW, B_TEXPRV, "Wall Out", 210, 180, 100, 19, &tex->stype, 2.0, 2.0, 0, 0, "Creates Ridges");
+ uiDefButS(block, ROW, B_TEXPRV, "Plastic", 10, 180, 100, 19, &tex->stype, 2.0, (float)TEX_PLASTIC, 0, 0, "Uses standard stucci");
+ uiDefButS(block, ROW, B_TEXPRV, "Wall In", 110, 180, 100, 19, &tex->stype, 2.0, (float)TEX_WALLIN, 0, 0, "Creates Dimples");
+ uiDefButS(block, ROW, B_TEXPRV, "Wall Out", 210, 180, 100, 19, &tex->stype, 2.0, (float)TEX_WALLOUT, 0, 0, "Creates Ridges");
- uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 110, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
@@ -561,12 +571,12 @@ static void texture_panel_marble(Tex *tex)
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Soft", 10, 180, 100, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses soft marble");
- uiDefButS(block, ROW, B_TEXPRV, "Sharp", 110, 180, 100, 18, &tex->stype, 2.0, 1.0, 0, 0, "Uses more clearly defined marble");
- uiDefButS(block, ROW, B_TEXPRV, "Sharper", 210, 180, 100, 18, &tex->stype, 2.0, 2.0, 0, 0, "Uses very clearly defined marble");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft", 10, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SOFT, 0, 0, "Uses soft marble");
+ uiDefButS(block, ROW, B_TEXPRV, "Sharp", 110, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SHARP, 0, 0, "Uses more clearly defined marble");
+ uiDefButS(block, ROW, B_TEXPRV, "Sharper", 210, 180, 100, 18, &tex->stype, 2.0, (float)TEX_SHARPER, 0, 0, "Uses very clearly defined marble");
- uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 10, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 160, 160, 150, 19, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
uiDefButS(block, ROW, B_TEXPRV, "Sin", 10, 140, 100, 18, &tex->noisebasis2, 8.0, 0.0, 0, 0, "Uses a sine wave to produce bands.");
uiDefButS(block, ROW, B_TEXPRV, "Saw", 110, 140, 100, 18, &tex->noisebasis2, 8.0, 1.0, 0, 0, "Uses a saw wave to produce bands");
@@ -594,10 +604,10 @@ static void texture_panel_clouds(Tex *tex)
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_TEXPRV, "Default", 10, 180, 70, 18, &tex->stype, 2.0, 0.0, 0, 0, "Uses standard noise");
- uiDefButS(block, ROW, B_TEXPRV, "Color", 80, 180, 70, 18, &tex->stype, 2.0, 1.0, 0, 0, "Lets Noise return RGB value");
- uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 155, 180, 75, 18, &tex->noisetype, 12.0, 0.0, 0, 0, "Generates soft noise");
- uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 230, 180, 80, 18, &tex->noisetype, 12.0, 1.0, 0, 0, "Generates hard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Default", 10, 180, 70, 18, &tex->stype, 2.0, (float)TEX_DEFAULT, 0, 0, "Uses standard noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Color", 80, 180, 70, 18, &tex->stype, 2.0, (float)TEX_COLOR, 0, 0, "Lets Noise return RGB value");
+ uiDefButS(block, ROW, B_TEXPRV, "Soft noise", 155, 180, 75, 18, &tex->noisetype, 12.0, (float)TEX_NOISESOFT, 0, 0, "Generates soft noise");
+ uiDefButS(block, ROW, B_TEXPRV, "Hard noise", 230, 180, 80, 18, &tex->noisetype, 12.0, (float)TEX_NOISEPERL, 0, 0, "Generates hard noise");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_TEXPRV, "NoiseSize :", 10, 130, 150, 19, &tex->noisesize, 0.0001, 2.0, 10, 0, "Sets scaling for noise input");
uiDefButS(block, NUM, B_TEXPRV, "NoiseDepth:", 160, 130, 150, 19, &tex->noisedepth, 0.0, 6.0, 0, 0, "Sets the depth of the cloud calculation");
@@ -622,7 +632,8 @@ static void texture_panel_musgrave(Tex *tex)
block= uiNewBlock(&curarea->uiblocks, "texture_panel_musgrave", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Musgrave", "Texture", 640, 0, 318, 204)==0) return;
uiSetButLock(tex->id.lib!=0, ERROR_LIBDATA_MESSAGE);
-
+
+ /* TEX_MFRACTAL, TEX_RIDGEDMF, TEX_HYBRIDMF, TEX_FBM, TEX_HTERRAIN */
str= "Multifractal %x0|Ridged Multifractal %x1|Hybrid Multifractal %x2|Hetero Terrain %x4|fBm %x3";
uiDefButS(block, MENU, B_TEXREDR_PRV, str, 10, 160, 150, 19, &tex->stype, 0.0, 0.0, 0, 0, "Sets Musgrave type");
@@ -737,8 +748,7 @@ static char *layer_menu(RenderResult *rr, short *curlay)
a+= sprintf(str+a, "|%s %%x%d", rl->name, nr);
}
- if(*curlay >= nr)
- *curlay= 0;
+ /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */
return str;
}
@@ -875,7 +885,12 @@ static void image_load_fs_cb(void *ima_pp_v, void *iuser_v)
#else
else name = U.textudir;
#endif
- activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+ if (G.qual & LR_CTRLKEY) {
+ activate_imageselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+ }
+ else {
+ activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+ }
}
/* 5 layer button callbacks... */
@@ -1150,22 +1165,24 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
}
else {
image_info(ima, ibuf, str);
- uiDefBut(block, LABEL, 0, str, 10, 107, 300, 20, NULL, 1, 0, 0, 0, "");
+ 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( (G.f & G_FACESELECT) && G.sima && &G.sima->iuser==iuser)
+ if( (FACESEL_PAINT_TEST) && G.sima && &G.sima->iuser==iuser)
return;
/* left side default per-image options, right half the additional options */
/* fields */
uiBlockBeginAlign(block);
- but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 100, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
+ but= uiDefButBitS(block, TOG, IMA_FIELDS, imagechanged, "Fields", 10, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image");
uiButSetFunc(but, image_field_test, ima, iuser);
- uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 10, 50, 100, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
- uiBlockEndAlign(block);
+ uiDefButBitS(block, TOG, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle");
- uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 10, 100, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
+ uiBlockSetFunc(block, image_reload_cb, ima, iuser);
+ uiDefButBitS(block, TOG, IMA_ANTIALI, B_NOP, "Anti", 10, 50, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors");
+ uiDefButBitS(block, TOG, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha");
+ uiBlockEndAlign(block);
if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
sprintf(str, "(%d) Frames:", iuser->framenr);
@@ -1200,7 +1217,7 @@ void uiblock_image_panel(uiBlock *block, Image **ima_pp, ImageUser *iuser,
uiBlockSetFunc(block, NULL, NULL, NULL);
}
}
-
+ uiBlockEndAlign(block);
}
static void texture_panel_image(Image **ima, ImageUser *iuser)
@@ -1213,7 +1230,7 @@ static void texture_panel_image(Image **ima, ImageUser *iuser)
uiblock_image_panel(block, ima, iuser, B_REDR, B_IMAGECHANGED);
}
-static void texture_panel_image_map(Tex *tex)
+static void texture_panel_image_map(Tex *tex, MTex *mtex)
{
uiBlock *block;
@@ -1231,12 +1248,18 @@ static void texture_panel_image_map(Tex *tex)
uiDefButBitS(block, TOG, TEX_USEALPHA, B_TEXPRV, "UseAlpha", 10, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to use Image's alpha channel");
uiDefButBitS(block, TOG, TEX_CALCALPHA, B_TEXPRV, "CalcAlpha", 110, 160, 100, 20, &tex->imaflag, 0, 0, 0, 0, "Click to calculate an alpha channel based on Image RGB values");
uiDefButBitS(block, TOG, TEX_NEGALPHA, B_TEXPRV, "NegAlpha", 210, 160, 100, 20, &tex->flag, 0, 0, 0, 0, "Click to invert the alpha values");
- uiBlockEndAlign(block);
- uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,120,150,20, &tex->filtersize, 0.1, 25.0, 10, 3, "Sets the filter size used by mipmap and interpol");
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, TEX_FILTER_MIN, B_TEXPRV, "Min", 10, 120, 30, 20, &tex->imaflag, 0, 0, 0, 0, "Use Filtersize as a minimal filter value in pixels");
+ uiDefButF(block, NUM, B_TEXPRV, "Filter: ", 40,120,120,20, &tex->filtersize, 0.1, 50.0, 10, 3, "Multiplies the filter size used by mipmap and interpol");
- uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,150,20, &tex->imaflag,
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, TEX_NORMALMAP, B_NOP, "Normal Map", 160,120,(mtex)? 75: 150,20, &tex->imaflag,
0, 0, 0, 0, "Use image RGB values for normal mapping");
+ if(mtex)
+ uiDefButS(block, MENU, B_DIFF, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3",
+ 235,120,75,20, &mtex->normapspace, 0, 0, 0, 0, "Sets space of normal map image");
+ uiBlockEndAlign(block);
/* crop extend clip */
@@ -1294,9 +1317,9 @@ static void texture_panel_envmap(Tex *tex)
env= tex->env;
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_REDR, "Static", 10, 180, 100, 19, &env->stype, 2.0, 0.0, 0, 0, "Calculates environment map only once");
- uiDefButS(block, ROW, B_REDR, "Anim", 110, 180, 100, 19, &env->stype, 2.0, 1.0, 0, 0, "Calculates environment map at each rendering");
- uiDefButS(block, ROW, B_ENV_FREE, "Load", 210, 180, 100, 19, &env->stype, 2.0, 2.0, 0, 0, "Loads saved environment map from disk");
+ uiDefButS(block, ROW, B_REDR, "Static", 10, 180, 100, 19, &env->stype, 2.0, (float)ENV_STATIC, 0, 0, "Calculates environment map only once");
+ uiDefButS(block, ROW, B_REDR, "Anim", 110, 180, 100, 19, &env->stype, 2.0, (float)ENV_ANIM, 0, 0, "Calculates environment map at each rendering");
+ uiDefButS(block, ROW, B_ENV_FREE, "Load", 210, 180, 100, 19, &env->stype, 2.0, (float)ENV_LOAD, 0, 0, "Loads saved environment map from disk");
uiBlockEndAlign(block);
if(env->stype==ENV_LOAD) {
@@ -1339,8 +1362,8 @@ static void texture_panel_envmap(Tex *tex)
uiDefBut(block, BUT, B_ENV_FREE_ALL, "Free all EnvMaps", 210,145,100,20, 0, 0, 0, 0, 0, "Frees all rendered environment maps for all materials");
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_NOP, "Cube", 10,120,100,20, &env->type, 3.0f, 0.0f, 0, 0, "Use environment map with six cube sides");
- uiDefButS(block, ROW, B_NOP, "Plane", 110,120,100,20, &env->type, 3.0f, 1.0f, 0, 0, "Only one side is rendered, with Z axis pointing in direction of image");
+ uiDefButS(block, ROW, B_NOP, "Cube", 10,120,100,20, &env->type, 3.0f, (float)ENV_CUBE, 0, 0, "Use environment map with six cube sides");
+ uiDefButS(block, ROW, B_NOP, "Plane", 110,120,100,20, &env->type, 3.0f, (float)ENV_PLANE, 0, 0, "Only one side is rendered, with Z axis pointing in direction of image");
uiDefButF(block, NUM, B_NOP, "Zoom: ", 210,120,100,20, &env->viewscale, 0.5f, 5.0f, 100, 2, "Zoom factor for planar environment map");
uiBlockEndAlign(block);
}
@@ -1350,10 +1373,11 @@ static void texture_panel_envmap(Tex *tex)
uiDefButS(block, NUM, B_ENV_FREE, "CubeRes", 160,90,150,20, &env->cuberes, 50, 4096.0, 0, 0, "Sets the pixel resolution of the rendered environment map");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_TEXPRV, "Filter :", 10,65,150,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"),
+ uiDefButBitS(block, TOG, TEX_FILTER_MIN, B_TEXPRV, "Min", 10, 65, 30, 20, &tex->imaflag, 0, 0, 0, 0, "Use Filtersize as a minimal filter value in pixels");
+ uiDefButF(block, NUM, B_TEXPRV, "Filter :", 40,65,120,20, &tex->filtersize, 0.1, 25.0, 0, 3, "Adjusts sharpness or blurriness of the reflection"),
uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 160,65,150,20, &env->depth, 0, 5.0, 0, 0, "Sets the number of times a map will be rendered recursively mirror effects"),
uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 10,40,150,20, &env->clipsta, 0.01, 50.0, 100, 0, "Sets start value for clipping: objects nearer than this are not visible to map");
- uiDefButF(block, NUM, B_NOP, "ClipEnd", 160,40,150,20, &env->clipend, 0.1, 5000.0, 1000, 0, "Sets end value for clipping beyond which objects are not visible to map");
+ uiDefButF(block, NUM, B_NOP, "ClipEnd", 160,40,150,20, &env->clipend, 0.1, 20000.0, 1000, 0, "Sets end value for clipping beyond which objects are not visible to map");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Don't render layer:", 10,10,140,22, 0, 0.0, 0.0, 0, 0, "");
@@ -1871,6 +1895,7 @@ void do_worldbuts(unsigned short event)
static MTex mtexcopybuf;
World *wrld;
MTex *mtex;
+ MTex *mtexswap;
switch(event) {
case B_TEXCLEARWORLD:
@@ -1915,8 +1940,28 @@ void do_worldbuts(unsigned short event)
scrarea_queue_winredraw(curarea);
}
break;
- case B_AO_DISTANCES:
- /* distances option only supports plain */
+ case B_WMTEXMOVEUP:
+ wrld= G.buts->lockpoin;
+ if(wrld && (int)wrld->texact > 0) {
+ mtexswap = wrld->mtex[(int)wrld->texact];
+ wrld->mtex[(int)wrld->texact] = wrld->mtex[((int)wrld->texact)-1];
+ wrld->mtex[((int)wrld->texact)-1] = mtexswap;
+ wrld->texact--;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
+ case B_WMTEXMOVEDOWN:
+ wrld= G.buts->lockpoin;
+ if(wrld && (int)wrld->texact < MAX_MTEX-1) {
+ mtexswap = wrld->mtex[(int)wrld->texact];
+ wrld->mtex[(int)wrld->texact] = wrld->mtex[((int)wrld->texact)+1];
+ wrld->mtex[((int)wrld->texact)+1] = mtexswap;
+ wrld->texact++;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
+ case B_AO_FALLOFF:
+ /* falloff distances option only supports plain */
wrld= G.buts->lockpoin;
if(wrld)
wrld->aocolor= WO_AOPLAIN;
@@ -1945,7 +1990,7 @@ static void world_panel_mapto(World *wrld)
/* TEXTURE OUTPUT */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, MTEX_STENCIL, B_WORLDPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode");
+ uiDefButBitS(block, TOG, MTEX_STENCIL, B_WORLDPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Use this texture as a blending value on the next texture");
uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_WORLDPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect");
uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_WORLDPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
uiBlockEndAlign(block);
@@ -1956,7 +2001,7 @@ static void world_panel_mapto(World *wrld)
uiDefButF(block, NUMSLI, B_WORLDPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiDefButF(block, NUMSLI, B_WORLDPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiBlockEndAlign(block);
- uiDefButF(block, NUMSLI, B_WORLDPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value for textures to mix with values (not RGB)");
+ uiDefButF(block, NUMSLI, B_WORLDPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard");
/* MAP TO */
uiBlockBeginAlign(block);
@@ -2019,24 +2064,26 @@ static void world_panel_texture(World *wrld)
if(id) {
uiDefBut(block, TEX, B_IDNAME, "TE:", 100,160,200,19, id->name+2, 0.0, 21.0, 0, 0, "Displays name of the texture block: click to change");
sprintf(str, "%d", id->us);
- uiDefBut(block, BUT, 0, str, 196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
- uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 220,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
+ uiDefBut(block, BUT, 0, str, 177,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
+ uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 155,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
if(id->lib) {
if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
}
uiBlockSetCol(block, TH_AUTO);
- uiDefBut(block, BUT, B_TEXCLEARWORLD, "Clear", 122, 140, 72, 19, 0, 0, 0, 0, 0, "Erases link to texture");
+ uiDefBut(block, BUT, B_TEXCLEARWORLD, "Clear", 122, 140, 32, 19, 0, 0, 0, 0, 0, "Erases link to texture");
}
else
uiDefButS(block, TOG, B_WTEXBROWSE, "Add New" ,100, 160, 200, 19, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock");
uiBlockSetCol(block, TH_AUTO);
- /* copy/paste */
+ /* copy/paste/up/down */
uiBlockBeginAlign(block);
- uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP, 250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
- uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP,275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP, 200,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
+ uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP, 225,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_WMTEXMOVEUP, VICON_MOVE_UP, 250,140,25,19, 0, 0, 0, 0, 0, "Move texture channel up");
+ uiDefIconBut(block, BUT, B_WMTEXMOVEDOWN, VICON_MOVE_DOWN, 275,140,25,19, 0, 0, 0, 0, 0, "Move texture channel down");
/* TEXCO */
uiBlockBeginAlign(block);
@@ -2086,29 +2133,29 @@ static void world_panel_mistaph(World *wrld)
#endif
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButBitS(block, TOG, WO_MIST, REDRAWVIEW3D,"Mist", 10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation");
+ uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation");
uiBlockSetCol(block, TH_AUTO);
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_DIFF, "Qua", 10, 90, 40, 19, &wrld->mistype, 1.0, 0.0, 0, 0, "Mist uses quadratic progression");
- uiDefButS(block, ROW, B_DIFF, "Lin", 50, 90, 50, 19, &wrld->mistype, 1.0, 1.0, 0, 0, "Mist uses linear progression");
- uiDefButS(block, ROW, B_DIFF, "Sqr", 100, 90, 50, 19, &wrld->mistype, 1.0, 2.0, 0, 0, "Mist uses inverse quadratic progression");
+ uiDefButS(block, ROW, B_WORLDPRV2, "Quad", 10, 90, 40, 19, &wrld->mistype, 1.0, 0.0, 0, 0, "Mist uses quadratic progression");
+ uiDefButS(block, ROW, B_WORLDPRV2, "Lin", 50, 90, 50, 19, &wrld->mistype, 1.0, 1.0, 0, 0, "Mist uses linear progression");
+ uiDefButS(block, ROW, B_WORLDPRV2, "Sqr", 100, 90, 50, 19, &wrld->mistype, 1.0, 2.0, 0, 0, "Mist uses inverse quadratic progression");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM,REDRAWVIEW3D, "Sta:",10,70,140,19, &wrld->miststa, 0.0, 1000.0, 10, 0, "Specifies the starting distance of the mist");
- uiDefButF(block, NUM,REDRAWVIEW3D, "Di:",10,50,140,19, &wrld->mistdist, 0.0,1000.0, 10, 00, "Specifies the depth of the mist");
- uiDefButF(block, NUM,B_DIFF,"Hi:", 10,30,140,19, &wrld->misthi,0.0,100.0, 10, 0, "Specifies the factor for a less dense mist with increasing height");
- uiDefButF(block, NUMSLI, B_DIFF, "Misi ", 10,10,140,19, &(wrld->misi), 0., 1.0, 0, 0, "Sets the mist intensity");
+ uiDefButF(block, NUM,B_WORLDPRV2, "Start:",10,70,140,19, &wrld->miststa, 0.0, 10000.0, 10, 0, "Specifies the starting distance of the mist");
+ uiDefButF(block, NUM,B_WORLDPRV2, "Dist:",10,50,140,19, &wrld->mistdist, 0.0,10000.0, 10, 00, "Specifies the depth of the mist");
+ uiDefButF(block, NUM,B_WORLDPRV2,"Height:", 10,30,140,19, &wrld->misthi,0.0,100.0, 10, 0, "Specifies the factor for a less dense mist with increasing height");
+ uiDefButF(block, NUMSLI, B_WORLDPRV2, "Misi ", 10,10,140,19, &(wrld->misi), 0., 1.0, 0, 0, "Sets the mist intensity");
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButBitS(block, TOG, WO_STARS, REDRAWVIEW3D, "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation");
+ uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation");
uiBlockSetCol(block, TH_AUTO);
uiBlockBeginAlign(block);
- uiDefButF(block, NUM,B_DIFF,"StarDist:", 160,70,140,19, &(wrld->stardist), 2.0, 1000.0, 100, 0, "Specifies the average distance between any two stars");
- uiDefButF(block, NUM,B_DIFF,"MinDist:", 160,50,140,19, &(wrld->starmindist), 0.0, 1000.0, 100, 0, "Specifies the minimum distance to the camera for stars");
- uiDefButF(block, NUMSLI,B_DIFF,"Size:", 160,30,140,19, &(wrld->starsize), 0.0, 10.0, 10, 0, "Specifies the average screen dimension of stars");
- uiDefButF(block, NUMSLI,B_DIFF,"Colnoise:", 160,10,140,19, &(wrld->starcolnoise), 0.0, 1.0, 100, 0, "Randomizes star color");
+ uiDefButF(block, NUM,B_WORLDPRV2,"StarDist:", 160,70,140,19, &(wrld->stardist), 2.0, 1000.0, 100, 0, "Specifies the average distance between any two stars");
+ uiDefButF(block, NUM,B_WORLDPRV2,"MinDist:", 160,50,140,19, &(wrld->starmindist), 0.0, 1000.0, 100, 0, "Specifies the minimum distance to the camera for stars");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2,"Size:", 160,30,140,19, &(wrld->starsize), 0.0, 10.0, 10, 0, "Specifies the average screen dimension of stars");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2,"Colnoise:", 160,10,140,19, &(wrld->starcolnoise), 0.0, 1.0, 100, 0, "Randomizes star color");
uiBlockEndAlign(block);
}
@@ -2116,49 +2163,115 @@ static void world_panel_mistaph(World *wrld)
static void world_panel_amb_occ(World *wrld)
{
uiBlock *block;
+ short yco=PANEL_YMAX;
block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Mist / Stars / Physics", "World");
- if(uiNewPanel(curarea, block, "Amb Occ", "World", 320, 0, 318, 204)==0) return;
-
+ if(uiNewPanel(curarea, block, "Amb Occ", "World", PANELX, PANELY, PANELW, PANELH)==0) return;
+ uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
+
+
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR, "Ambient Occlusion",10,150,300,19, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
+ uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR, "Ambient Occlusion",
+ X2CLM1, yco-=BUTH, BUTW1, BUTH, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
uiBlockSetCol(block, TH_AUTO);
+
+ if(!(wrld->mode & WO_AMB_OCC)) return;
- if(wrld->mode & WO_AMB_OCC) {
+ yco -= YSPACE;
- /* aolight: samples */
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_REDR, "Samples:", 10, 120, 150, 19, &wrld->aosamp, 1.0, 16.0, 100, 0, "Sets the number of samples used for AO (actual number: squared)");
- /* enable/disable total random sampling */
- uiDefButBitS(block, TOG, WO_AORNDSMP, 0, "Random Sampling", 160, 120, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, total random sampling will be used for an even noisier effect");
- uiBlockEndAlign(block);
+ if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
+ uiDefButS(block, NUM, B_REDR, "Samples:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO (actual number: squared)");
- uiDefButF(block, NUM, B_REDR, "Dist:", 10, 95, 150, 19, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
+ yco -= YSPACE;
+
+ uiDefButF(block, NUM, B_REDR, "Max Dist:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
+ }
+ else {
+ uiDefButS(block, NUM, B_REDR, "Passes:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_passes, 0.0, 10.0, 0, 0, "Sets the number of preprocessing passes to reduce overocclusion");
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, WO_AODIST, B_AO_DISTANCES, "Use Distances", 10, 70, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
- /* distance attenuation factor */
- if (wrld->aomode & WO_AODIST)
- uiDefButF(block, NUM, B_REDR, "DistF:", 160, 70, 150, 19, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance factor, the higher, the 'shorter' the shadows");
+ yco -= YSPACE;
+
+ uiDefButF(block, NUM, B_REDR, "Correction:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_correction, 0.0, 1.0, 0, 0, "Ad-hoc correction for over-occlusion due to the approximation.");
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, WO_AODIST, B_AO_FALLOFF, "Use Falloff",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
+ if (wrld->aomode & WO_AODIST)
+ uiDefButF(block, NUM, B_REDR, "Strength:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance attenuation factor, the higher, the 'shorter' the shadows");
+ uiBlockEndAlign(block);
+
+ /* column 2 */
+ yco = PANEL_YMAX - BUTH - YSPACE;
+
+ uiDefButS(block, MENU, B_REDR, "Gather Method%t|Raytrace %x0|Approximate %x1",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_gather_method, 0, 0, 0, 0, "Method for occlusion gathering: Raytrace: slow when noise free results are required, but accurate, Approximate: faster and without noise, but inaccurate");
- /* result mix modes */
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_REDR, "Add", 10, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
- uiDefButS(block, ROW, B_REDR, "Sub", 110, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
- uiDefButS(block, ROW, B_REDR, "Both", 210, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
+ yco -= YSPACE;
- /* color treatment */
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_REDR, "Plain", 10, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
- uiDefButS(block, ROW, B_REDR, "Sky Color", 110, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
- uiDefButS(block, ROW, B_REDR, "Sky Texture", 210, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
+ if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE) {
+ uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
+ yco -= YSPACE;
+
+ if (wrld->ao_samp_method == WO_AOSAMP_HALTON) {
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_REDR, "Threshold:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_thresh, 0.0, 1.0, 100, 0, "Samples below this threshold will be considered fully shadowed/unshadowed and skipped");
+ uiDefButF(block, NUMSLI, B_REDR, "Adapt Vec:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_speed_fac, 0.0, 1.0, 100, 0, "Use the speed vector pass to reduce AO samples in fast moving pixels. The higher the value, the more aggressive the sample reduction. Requires Vec pass enabled.");
+ uiBlockEndAlign(block);
+ } else if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT) {
+ uiDefButF(block, NUMSLI, B_REDR, "Bias:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
+ }
+ }
+ else {
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_REDR, "Energy:", 10, 0, 150, 19, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
- uiDefButF(block, NUMSLI, B_REDR, "Bias:", 160, 0, 150, 19, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
+ uiDefButF(block, NUM, B_REDR, "Error:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_approx_error, 0.0001, 10.0, 0, 0, "Error tolerance (low values are slower and higher quality)");
+
+ uiDefButBitS(block, TOG, WO_AOCACHE, B_REDR, "Pixel Cache",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "Cache AO results in pixels and interpolate over neighbouring pixels for speedup.");
+ uiBlockEndAlign(block);
}
+ yco = PANEL_YMAX - (5*BUTH+4*YSPACE);
+
+ /* result mix modes */
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_REDR, "Add",
+ X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
+ uiDefButS(block, ROW, B_REDR, "Sub",
+ X3CLM2, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
+ uiDefButS(block, ROW, B_REDR, "Both",
+ X3CLM3, yco, BUTW3, BUTH, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
+ /* color treatment */
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW, B_REDR, "Plain",
+ X3CLM1, yco-=BUTH, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
+ uiDefButS(block, ROW, B_REDR, "Sky Color",
+ X3CLM2, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
+ if(wrld->ao_gather_method == WO_AOGATHER_RAYTRACE)
+ uiDefButS(block, ROW, B_REDR, "Sky Texture",
+ X3CLM3, yco, BUTW3, BUTH, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
+ uiDefButF(block, NUMSLI, B_REDR, "Energy:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
}
static void world_panel_world(World *wrld)
@@ -2176,28 +2289,28 @@ static void world_panel_world(World *wrld)
uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
uiBlockSetCol(block, TH_AUTO);
- uiDefButF(block, COL, B_WORLDPRV, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, "");
- uiDefButF(block, COL, B_WORLDPRV, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, "");
-
uiBlockBeginAlign(block);
+ uiDefButF(block, COL, B_WORLDPRV, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, "");
uiDefButF(block, NUMSLI,B_WORLDPRV,"HoR ", 10,130,145,19, &(wrld->horr), 0.0, 1.0, B_COLHOR,0, "Sets the amount of red color at the horizon");
uiDefButF(block, NUMSLI,B_WORLDPRV,"HoG ", 10,110,145,19, &(wrld->horg), 0.0, 1.0, B_COLHOR,0, "Sets the amount of green color at the horizon");
uiDefButF(block, NUMSLI,B_WORLDPRV,"HoB ", 10,90,145,19, &(wrld->horb), 0.0, 1.0, B_COLHOR,0, "Sets the amount of blue color at the horizon");
uiBlockBeginAlign(block);
+ uiDefButF(block, COL, B_WORLDPRV, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, "");
uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeR ", 160,130,145,19, &(wrld->zenr), 0.0, 1.0, B_COLZEN,0, "Sets the amount of red color at the zenith");
uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeG ", 160,110,145,19, &(wrld->zeng), 0.0, 1.0, B_COLZEN,0, "Sets the amount of green color at the zenith");
uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeB ", 160,90,145,19, &(wrld->zenb), 0.0, 1.0, B_COLZEN,0, "Sets the amount of blue color at the zenith");
uiBlockBeginAlign(block);
+ uiDefButF(block, COL, B_WORLDPRV, "", 10,70,145,19, &wrld->ambr, 0, 0, 0, 0, "");
uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbR ", 10,50,145,19, &(wrld->ambr), 0.0, 1.0 ,0,0, "Sets the amount of red ambient color");
uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbG ", 10,30,145,19, &(wrld->ambg), 0.0, 1.0 ,0,0, "Sets the amount of green ambient color");
uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbB ", 10,10,145,19, &(wrld->ambb), 0.0, 1.0 ,0,0, "Sets the amount of blue ambient color");
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButF(block, NUMSLI,B_WORLDPRV, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light");
- uiDefButF(block, NUMSLI,B_WORLDPRV, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0");
}
@@ -2235,6 +2348,7 @@ void do_lampbuts(unsigned short event)
static MTex mtexcopybuf;
Lamp *la;
MTex *mtex;
+ MTex *mtexswap;
switch(event) {
case B_LAMPREDRAW:
@@ -2305,6 +2419,33 @@ void do_lampbuts(unsigned short event)
scrarea_queue_winredraw(curarea);
}
break;
+ case B_LMTEXMOVEUP:
+ la= G.buts->lockpoin;
+ if(la && (int)la->texact > 0) {
+ mtexswap = la->mtex[(int)la->texact];
+ la->mtex[(int)la->texact] = la->mtex[((int)la->texact)-1];
+ la->mtex[((int)la->texact)-1] = mtexswap;
+ la->texact--;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
+ case B_LMTEXMOVEDOWN:
+ la= G.buts->lockpoin;
+ if(la && (int)la->texact < MAX_MTEX-1) {
+ mtexswap = la->mtex[(int)la->texact];
+ la->mtex[(int)la->texact] = la->mtex[((int)la->texact)+1];
+ la->mtex[((int)la->texact)+1] = mtexswap;
+ la->texact++;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
+ case B_LFALLOFFCHANGED:
+ la= G.buts->lockpoin;
+ curvemapping_changed(la->curfalloff, 1);
+ BIF_undo_push("Edit Lamp falloff curve");
+ BIF_preview_changed(ID_LA);
+ scrarea_queue_winredraw(curarea);
+ break;
}
}
@@ -2330,7 +2471,7 @@ static void lamp_panel_mapto(Object *ob, Lamp *la)
/* TEXTURE OUTPUT */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, MTEX_STENCIL, B_LAMPPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode");
+ uiDefButBitS(block, TOG, MTEX_STENCIL, B_LAMPPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Use this texture as a blending value on the next texture");
uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_LAMPPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect");
uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_LAMPPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
uiBlockEndAlign(block);
@@ -2341,7 +2482,7 @@ static void lamp_panel_mapto(Object *ob, Lamp *la)
uiDefButF(block, NUMSLI, B_LAMPPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiDefButF(block, NUMSLI, B_LAMPPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiBlockEndAlign(block);
- uiDefButF(block, NUMSLI, B_LAMPPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value the textures uses to mix with");
+ uiDefButF(block, NUMSLI, B_LAMPPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard");
/* MAP TO */
uiDefButBitS(block, TOG, MAP_COL, B_LAMPPRV, "Col", 10,180,135,19, &(mtex->mapto), 0, 0, 0, 0, "Lets the texture affect the basic color of the lamp");
@@ -2399,22 +2540,25 @@ static void lamp_panel_texture(Object *ob, Lamp *la)
if(id) {
uiDefBut(block, TEX, B_IDNAME, "TE:", 100,160,200,19, id->name+2, 0.0, 21.0, 0, 0, "Displays name of the texture block: click to change");
sprintf(str, "%d", id->us);
- uiDefBut(block, BUT, 0, str, 196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
- uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 221,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
+ uiDefBut(block, BUT, 0, str, 155,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user");
+ uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 177,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture");
if(id->lib) {
if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, "");
}
uiBlockSetCol(block, TH_AUTO);
- uiDefBut(block, BUT, B_TEXCLEARLAMP, "Clear", 122, 140, 72, 19, 0, 0, 0, 0, 0, "Erases link to texture");
+ uiDefBut(block, BUT, B_TEXCLEARLAMP, "Clear", 122, 140, 32, 19, 0, 0, 0, 0, 0, "Erases link to texture");
}
else
uiDefButS(block, TOG, B_LTEXBROWSE, "Add New" ,100, 160, 200, 19, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock");
- /* copy/paste */
+ /* copy/paste/up/down */
uiBlockBeginAlign(block);
- uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP, 250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
- uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP, 275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP, 200,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
+ uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP, 225,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_LMTEXMOVEUP, VICON_MOVE_UP, 250,140,25,19, 0, 0, 0, 0, 0, "Move texture channel up");
+ uiDefIconBut(block, BUT, B_LMTEXMOVEDOWN, VICON_MOVE_DOWN, 275,140,25,19, 0, 0, 0, 0, 0, "Move texture channel down");
+
/* TEXCO */
uiBlockSetCol(block, TH_AUTO);
@@ -2441,7 +2585,7 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
float grid=0.0;
block= uiNewBlock(&curarea->uiblocks, "lamp_panel_spot", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Shadow and Spot", "Lamp", 640, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Shadow and Spot", "Lamp", 640, 0, 318, 224)==0) return;
/* hemis and ray shadow dont work at all... */
/* yafray: ignore photonlight as well */
@@ -2469,14 +2613,13 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
}
uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, LA_ONLYSHADOW, B_NOP,"OnlyShadow", 10,110,80,19,&la->mode, 0, 0, 0, 0, "Causes light to cast shadows only without illuminating objects");
+ uiDefButBitS(block, TOG, LA_ONLYSHADOW, B_LAMPPRV,"OnlyShadow", 10,110,80,19,&la->mode, 0, 0, 0, 0, "Causes light to cast shadows only without illuminating objects");
if(la->type==LA_SPOT) {
uiBlockBeginAlign(block);
uiDefButBitS(block, TOG, LA_SQUARE, B_LAMPREDRAW,"Square", 10,60,80,19,&la->mode, 0, 0, 0, 0, "Sets square spotbundles");
uiDefButBitS(block, TOG, LA_HALO, B_LAMPREDRAW,"Halo", 10,40,80,19,&la->mode, 0, 0, 0, 0, "Renders spotlight with a volumetric halo");
- uiBlockSetCol(block, TH_AUTO);
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotSi ", 100,180,200,19,&la->spotsize, 1.0, 180.0, 0, 0, "Sets the angle of the spotlight beam in degrees");
uiDefButF(block, NUMSLI,B_LAMPREDRAW,"SpotBl ", 100,160,200,19,&la->spotblend, 0.0, 1.0, 0, 0, "Sets the softness of the spotlight edge");
@@ -2492,9 +2635,10 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
uiDefButS(block, ROW,B_NOP, "Tent", 165,90,65,19, &la->filtertype, 0.0, LA_SHADBUF_TENT, 0, 0, "Apply Tent filter for shadowbuffer samples");
uiDefButS(block, ROW,B_NOP, "Gauss", 230,90,70,19, &la->filtertype, 0.0, LA_SHADBUF_GAUSS, 0, 0, "Apply Gauss filter for shadowbuffer samples");
- // uiDefButS(block, ROW,B_NOP,"SubSamples: 1", 100,90,140,19, &la->buffers, 1.0, 1.0, 0, 0, "Amount of lampbuffer subsamples, a value of larger than 1 halves the shadowbuffer size");
- // uiDefButS(block, ROW,B_NOP,"4", 240,90,30,19, &la->buffers, 1.0, 4.0, 0, 0, "Amount of lampbuffer subsamples, this halves the actual shadowbuffer size");
- // uiDefButS(block, ROW,B_NOP,"9", 270,90,30,19, &la->buffers, 1.0, 9.0, 0, 0, "Amount of lampbuffer subsamples, this halves the shadowbuffer size");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW,B_NOP,"SampleBuffers: 1", 100,-15,140,19, &la->buffers, 1.0, 1.0, 0, 0, "Only one lampbuffer rendered");
+ uiDefButS(block, ROW,B_NOP,"4", 240,-15,30,19, &la->buffers, 1.0, 4.0, 0, 0, "Renders 4 lampbuffers for better AA, this quadruples memory usage");
+ uiDefButS(block, ROW,B_NOP,"9", 270,-15,30,19, &la->buffers, 1.0, 9.0, 0, 0, "Renders 9 lampbuffers for better AA, this uses nine times more memory");
uiBlockBeginAlign(block);
uiDefButS(block, NUM,B_LAMPREDRAW,"Samples:", 100,60,100,19, &la->samp,1.0,16.0, 0, 0, "Sets the number of shadow map samples");
@@ -2521,25 +2665,46 @@ static void lamp_panel_spot(Object *ob, Lamp *la)
}
}
- else if(la->type==LA_AREA && (la->mode & LA_SHAD_RAY)) {
- uiBlockBeginAlign(block);
- uiBlockSetCol(block, TH_AUTO);
- if(la->area_shape==LA_AREA_SQUARE)
- uiDefButS(block, NUM,0,"Samples:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
- if(la->area_shape==LA_AREA_CUBE)
- uiDefButS(block, NUM,0,"Samples:", 100,160,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
-
- if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)) {
- uiDefButS(block, NUM,0,"SamplesX:", 100,180,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
- uiDefButS(block, NUM,0,"SamplesY:", 100,160,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
- if(la->area_shape==LA_AREA_BOX)
- uiDefButS(block, NUM,0,"SamplesZ:", 100,140,200,19, &la->ray_sampz, 1.0, 8.0, 100, 0, "Sets the amount of Z samples taken extra");
+ if(ELEM4(la->type, LA_AREA, LA_SPOT, LA_SUN, LA_LOCAL) && (la->mode & LA_SHAD_RAY)) {
+
+ if (ELEM3(la->type, LA_SPOT, LA_SUN, LA_LOCAL)) {
+ if (la->ray_samp_method == LA_SAMP_CONSTANT) la->ray_samp_method = LA_SAMP_HALTON;
+
+ uiDefButS(block, MENU, B_REDR, "Adaptive QMC %x1|Constant QMC %x2",
+ 100,110,200,19, &la->ray_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Adaptive QMC is fastest, Constant QMC is less noisy but slower");
+
+ uiDefButF(block, NUM,B_LAMPREDRAW,"Soft Size", 100,80,200,19, &la->area_size, 0.01, 100.0, 10, 0, "Area light size, doesn't affect energy amount");
+
+ uiDefButS(block, NUM,0,"Samples:", 100,60,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
+ uiDefButF(block, NUM,0,"Threshold:", 100,40,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow");
}
+ else if (la->type == LA_AREA) {
+ uiDefButS(block, MENU, B_REDR, "Adaptive QMC %x1|Constant QMC %x2|Constant Jittered %x0",
+ 100,180,200,19, &la->ray_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Adaptive QMC is fastest");
+
+ if(la->area_shape==LA_AREA_SQUARE)
+ uiDefButS(block, NUM,0,"Samples:", 100,150,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp)");
+ else if(la->area_shape==LA_AREA_CUBE)
+ uiDefButS(block, NUM,0,"Samples:", 100,130,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of samples taken extra (samp x samp x samp)");
+
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_BOX)) {
+ uiDefButS(block, NUM,0,"SamplesX:", 100,150,200,19, &la->ray_samp, 1.0, 16.0, 100, 0, "Sets the amount of X samples taken extra");
+ uiDefButS(block, NUM,0,"SamplesY:", 100,130,200,19, &la->ray_sampy, 1.0, 16.0, 100, 0, "Sets the amount of Y samples taken extra");
+ if(la->area_shape==LA_AREA_BOX)
+ uiDefButS(block, NUM,0,"SamplesZ:", 100,110,200,19, &la->ray_sampz, 1.0, 8.0, 100, 0, "Sets the amount of Z samples taken extra");
+ }
+
+ if (la->ray_samp_method == LA_SAMP_CONSTANT) {
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, LA_SAMP_UMBRA, 0,"Umbra", 100,90,200,19,&la->ray_samp_type, 0, 0, 0, 0, "Emphasis parts that are fully shadowed");
+ uiDefButBitS(block, TOG, LA_SAMP_DITHER, 0,"Dither", 100,70,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use 2x2 dithering for sampling");
+ uiDefButBitS(block, TOG, LA_SAMP_JITTER, 0,"Noise", 200,70,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use noise for sampling");
+ } else if (la->ray_samp_method == LA_SAMP_HALTON) {
+ uiDefButF(block, NUM,0,"Threshold:", 100,90,200,19, &la->adapt_thresh, 0.0, 1.0, 100, 0, "Threshold for adaptive sampling, to control what level is considered already in shadow");
+ }
+ }
+
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, LA_SAMP_UMBRA, 0,"Umbra", 100,110,200,19,&la->ray_samp_type, 0, 0, 0, 0, "Emphasis parts that are fully shadowed");
- uiDefButBitS(block, TOG, LA_SAMP_DITHER, 0,"Dither", 100,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use 2x2 dithering for sampling");
- uiDefButBitS(block, TOG, LA_SAMP_JITTER, 0,"Noise", 200,90,100,19,&la->ray_samp_type, 0, 0, 0, 0, "Use noise for sampling");
}
else uiDefBut(block, LABEL,0," ", 100,180,200,19,NULL, 0, 0, 0, 0, "");
@@ -2632,6 +2797,28 @@ static void lamp_panel_yafray(Object *ob, Lamp *la)
}
+static void lamp_panel_falloff(Object *ob, Lamp *la)
+{
+ uiBlock *block;
+ rctf butr;
+ short yco=PANEL_YMAX;
+ float grid= 0.0;
+
+ /* name "Preview" is abused to detect previewrender offset panel */
+ block= uiNewBlock(&curarea->uiblocks, "lamp_panel_falloff", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Lamp", "Lamp");
+ if(uiNewPanel(curarea, block, "Falloff Curve", "Lamp", PANELX, PANELY, PANELW, PANELH)==0) return;
+
+ if(G.vd) grid= G.vd->grid;
+ if(grid<1.0) grid= 1.0;
+
+ uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
+
+ BLI_init_rctf(&butr, 10.0, 310.0, 10.0, (float)yco);
+ curvemap_buttons(block, la->curfalloff, 's', B_LFALLOFFCHANGED, B_LAMPREDRAW, &butr);
+
+}
+
static void lamp_panel_lamp(Object *ob, Lamp *la)
{
uiBlock *block;
@@ -2669,7 +2856,8 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
}
else if( ELEM(la->type, LA_LOCAL, LA_SPOT)) {
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButBitS(block, TOG, LA_QUAD, B_LAMPPRV,"Quad", 10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation");
+ uiDefButS(block, MENU, B_LAMPREDRAW, "Falloff %t|Constant %x0|Inverse Linear %x1|Inverse Square %x2|Custom Curve %x3|Lin/Quad Weighted %x4|",
+ 10,150,100,19, &la->falloff_type, 0,0,0,0, "Lamp falloff - intensity decay with distance");
uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
}
@@ -2693,9 +2881,9 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiDefButF(block, COL, B_LAMPPRV, "", 120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, "");
uiBlockBeginAlign(block);
- if (ELEM(la->type, LA_LOCAL, LA_SPOT)) {
- uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp");
- uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp");
+ if (ELEM(la->type, LA_LOCAL, LA_SPOT) && (la->falloff_type == LA_FALLOFF_SLIDERS)) {
+ uiDefButF(block, NUMSLI,B_LAMPPRV,"Linear ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp");
+ uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp");
}
else if(la->type==LA_AREA) {
if(la->k==0.0) la->k= 1.0;
@@ -2739,6 +2927,7 @@ void do_matbuts(unsigned short event)
static MTex mtexcopybuf;
Material *ma;
MTex *mtex;
+ MTex *mtexswap;
/* all operations default on active material layer here */
/* but this also gets called for lamp and world... */
@@ -2825,11 +3014,17 @@ void do_matbuts(unsigned short event)
case B_LAMPPRV:
BIF_preview_changed(ID_LA);
allqueue(REDRAWBUTSSHADING, 0);
+ shade_buttons_change_3d();
break;
case B_WORLDPRV:
BIF_preview_changed(ID_WO);
allqueue(REDRAWBUTSSHADING, 0);
break;
+ case B_WORLDPRV2:
+ BIF_preview_changed(ID_TE);
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
case B_MATHALO:
/* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE <blush> */
/* same for 'xtreme alpha' which is 'only shadow' */
@@ -2882,6 +3077,24 @@ void do_matbuts(unsigned short event)
scrarea_queue_winredraw(curarea);
}
break;
+ case B_MTEXMOVEUP:
+ if(ma && (int)ma->texact > 0) {
+ mtexswap = ma->mtex[(int)ma->texact];
+ ma->mtex[(int)ma->texact] = ma->mtex[((int)ma->texact)-1];
+ ma->mtex[((int)ma->texact)-1] = mtexswap;
+ ma->texact--;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
+ case B_MTEXMOVEDOWN:
+ if(ma && (int)ma->texact < MAX_MTEX-1) {
+ mtexswap = ma->mtex[(int)ma->texact];
+ ma->mtex[(int)ma->texact] = ma->mtex[((int)ma->texact)+1];
+ ma->mtex[((int)ma->texact)+1] = mtexswap;
+ ma->texact++;
+ allqueue(REDRAWBUTSSHADING, 0);
+ }
+ break;
case B_MATZTRANSP:
if(ma) {
ma->mode &= ~MA_RAYTRANSP;
@@ -2938,16 +3151,65 @@ void do_matbuts(unsigned short event)
allqueue(REDRAWBUTSSHADING, 0);
}
break;
-
+
+ case B_MAT_PARTICLE:
+ if(ma) {
+ Base *base;
+ Object *ob;
+ ParticleSystem *psys;
+
+ base= G.scene->base.first;
+ while(base){
+ if(base->object->type==OB_MESH) {
+ ob=base->object;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ if(psys && ma==give_current_material(ob,psys->part->omat)) {
+ psys->recalc |= PSYS_INIT;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ }
+ base = base->next;
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ }
}
}
+static void particle_recalc_material(void *ma_v, void *arg2)
+{
+ Material *ma = ma_v;
+ Base *base;
+ Object *ob;
+ ParticleSystem *psys;
+
+ base= G.scene->base.first;
+ while(base){
+ if(base->object->type==OB_MESH){
+ ob=base->object;
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ if(psys && ma==give_current_material(ob,psys->part->omat)){
+ psys->recalc |= PSYS_INIT;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ }
+ base = base->next;
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
/* if from nodes, hide options that are not available */
-static void material_panel_map_to(Material *ma, int from_nodes)
+static void material_panel_map_to(Object *ob, Material *ma, int from_nodes)
{
uiBlock *block;
+ uiBut *but;
MTex *mtex;
+ ParticleSystem *psys;
+ int psys_mapto=0;
+ static short pattr=0;
block= uiNewBlock(&curarea->uiblocks, "material_panel_map_to", UI_EMBOSS, UI_HELV, curarea->win);
uiNewPanelTabbed("Texture", "Material");
@@ -2963,7 +3225,7 @@ static void material_panel_map_to(Material *ma, int from_nodes)
/* TEXTURE OUTPUT */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, MTEX_STENCIL, B_MATPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode");
+ uiDefButBitS(block, TOG, MTEX_STENCIL, B_MATPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Use this texture as a blending value on the next texture");
uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_MATPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect");
uiDefButBitS(block, TOG,MTEX_RGBTOINT, B_MATPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
uiBlockEndAlign(block);
@@ -2985,36 +3247,86 @@ static void material_panel_map_to(Material *ma, int from_nodes)
}
uiBlockEndAlign(block);
- uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value the texture uses to mix with (not RGB)");
+ uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "Value to use for Ref, Spec, Amb, Emit, Alpha, RayMir, TransLu and Hard");
/* MAP TO */
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, MAP_COL, B_MATPRV, "Col", 10,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic color of the material");
- uiDefButBitS(block, TOG3, MAP_NORM, B_MATPRV, "Nor", 50,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the rendered normal");
- uiDefButBitS(block, TOG, MAP_COLSPEC, B_MATPRV, "Csp", 90,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the specularity color");
- uiDefButBitS(block, TOG, MAP_COLMIR, B_MATPRV, "Cmir", 130,180,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the mirror color");
- uiDefButBitS(block, TOG3, MAP_REF, B_MATPRV, "Ref", 180,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of the materials reflectivity");
- uiDefButBitS(block, TOG3, MAP_SPEC, B_MATPRV, "Spec", 220,180,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of specularity");
- uiDefButBitS(block, TOG3, MAP_AMB, B_MATPRV, "Amb", 270,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of ambient");
-
- uiDefButBitS(block, TOG3, MAP_HAR, B_MATPRV, "Hard", 10,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the hardness value");
- uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir", 60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
- uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha", 110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
- uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
- uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
- if(from_nodes==0)
- uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp", 265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
+
+ /*check if material is being used by particles*/
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ if(psys->part->omat==ob->actcol)
+ psys_mapto=1;
+
+ if(psys_mapto && pattr) {
+ but=uiDefButBitS(block, TOG3, MAP_PA_TIME, B_MAT_PARTICLE, "Time", 10,180,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the emission time of particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ but=uiDefButBitS(block, TOG3, MAP_PA_LIFE, B_MAT_PARTICLE, "Life", 70,180,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the life time of particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ but=uiDefButBitS(block, TOG3, MAP_PA_DENS, B_MAT_PARTICLE, "Dens", 130,180,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the density of particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ uiDefButBitS(block, TOG3, MAP_PA_IVEL, B_MAT_PARTICLE, "IVel", 190,180,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the initial velocity of particles");
+ uiDefButBitS(block, TOG3, MAP_PA_ROUGH, B_MAT_PARTICLE, "Rough", 250,180,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the roughness of child particles");
+
+ but=uiDefButBitS(block, TOG3, MAP_PA_SIZE, B_MAT_PARTICLE, "Size", 10,160,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the size of particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ but=uiDefButBitS(block, TOG3, MAP_PA_KINK, B_MAT_PARTICLE, "Kink", 70,160,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the kink of child particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ but=uiDefButBitS(block, TOG3, MAP_PA_LENGTH, B_MAT_PARTICLE, "Length",130,160,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the length of particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+ but=uiDefButBitS(block, TOG3, MAP_PA_CLUMP, B_MAT_PARTICLE, "Clump", 190,160,60,19, &(mtex->pmapto), 0, 0, 0, 0, "Causes the texture to affect the clump of child particles");
+ //uiButSetFunc(but, particle_recalc_material, ma, NULL);
+
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+ uiDefButBitS(block, TOG, 1, B_MATPRV, "PAttr", 250,160,60,19, &pattr, 0, 0, 0, 0, "Display settings for particle attributes");
+ uiBlockSetCol(block, TH_AUTO);
+ }
+ else {
+ uiDefButBitS(block, TOG, MAP_COL, B_MATPRV, "Col", 10,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect basic colour of the material");
+ uiDefButBitS(block, TOG3, MAP_NORM, B_MATPRV, "Nor", 50,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the rendered normal");
+ uiDefButBitS(block, TOG, MAP_COLSPEC, B_MATPRV, "Csp", 90,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the specularity colour");
+ uiDefButBitS(block, TOG, MAP_COLMIR, B_MATPRV, "Cmir", 130,180,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the mirror colour");
+ uiDefButBitS(block, TOG3, MAP_REF, B_MATPRV, "Ref", 180,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of the materials reflectivity");
+ uiDefButBitS(block, TOG3, MAP_SPEC, B_MATPRV, "Spec", 220,180,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of specularity");
+ uiDefButBitS(block, TOG3, MAP_AMB, B_MATPRV, "Amb", 270,180,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the value of ambient");
+
+ if(psys_mapto) {
+ uiDefButBitS(block, TOG3, MAP_HAR, B_MATPRV, "Hard", 10,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the hardness value");
+ uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir", 50,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
+ uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha", 90,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
+ uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 130,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
+ uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu", 180,160,40,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
+ if(from_nodes==0)
+ uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp", 220,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+ uiDefButBitS(block, TOG, 1, B_MATPRV, "PAttr", 270,160,40,19, &pattr, 0, 0, 0, 0, "Display settings for particle attributes");
+ uiBlockSetCol(block, TH_AUTO);
+ }
+ else {
+ uiDefButBitS(block, TOG3, MAP_HAR, B_MATPRV, "Hard", 10,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the hardness value");
+ uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir", 60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value");
+ uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha", 110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value");
+ uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value");
+ uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "TransLu", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value");
+ if(from_nodes==0)
+ uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp", 265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface");
+ }
+ }
+
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_MATPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
+ but=uiDefButS(block, MENU, B_MATPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode");
uiBlockEndAlign(block);
+ if(psys_mapto && mtex->pmapto & MAP_PA_INIT)
+ uiButSetFunc(but, particle_recalc_material, ma, NULL);
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects color values");
/* newnoise: increased range to 25, the constant offset for bumpmapping quite often needs a higher nor setting */
uiDefButF(block, NUMSLI, B_MATPRV, "Nor ", 155,80,155,19, &(mtex->norfac), 0.0, 25.0, 0, 0, "Sets the amount the texture affects normal values");
- uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 155,60,155,19, &(mtex->varfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects other values");
+ but=uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 155,60,155,19, &(mtex->varfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects other values");
+ if(psys_mapto && mtex->pmapto & MAP_PA_INIT)
+ uiButSetFunc(but, particle_recalc_material, ma, NULL);
uiDefButF(block, NUMSLI, B_MATPRV, "Disp ", 155,40,155,19, &(mtex->dispfac), 0.0, 1.0, 0, 0, "Sets the amount the texture displaces the surface");
uiBlockBeginAlign(block);
@@ -3023,7 +3335,7 @@ static void material_panel_map_to(Material *ma, int from_nodes)
}
/* autocomplete callback for buttons */
-static void autocomplete_uv(char *str, void *arg_v)
+void autocomplete_uv(char *str, void *arg_v)
{
Mesh *me;
CustomDataLayer *layer;
@@ -3044,7 +3356,7 @@ static void autocomplete_uv(char *str, void *arg_v)
autocomplete_end(autocpl, str);
}
-static int verify_valid_uv_name(char *str)
+int verify_valid_uv_name(char *str)
{
Mesh *me;
CustomDataLayer *layer;
@@ -3086,7 +3398,7 @@ static void material_panel_map_input(Object *ob, Material *ma)
uiBlockBeginAlign(block);
uiDefButS(block, ROW, B_MATPRV, "Glob", 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
- if(mtex->texco == TEXCO_UV) {
+ if(mtex->texco == TEXCO_UV && !(mtex->texflag & MTEX_DUPLI_MAPTO)) {
if(!verify_valid_uv_name(mtex->uvname))
uiBlockSetCol(block, TH_REDALERT);
but=uiDefBut(block, TEX, B_MATPRV, "UV:", 750,180,158,18, mtex->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
@@ -3098,7 +3410,7 @@ static void material_panel_map_input(Object *ob, Material *ma)
uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates");
uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object");
- if( give_parteff(ob) )
+ if( ob->particlesystem.first )
uiDefButS(block, ROW, B_MATPRV, "Strand", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)");
else
uiDefButS(block, ROW, B_MATPRV, "Stick", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates");
@@ -3108,6 +3420,10 @@ static void material_panel_map_input(Object *ob, Material *ma)
uiDefButS(block, ROW, B_MATPRV, "Stress", 630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
uiDefButS(block, ROW, B_MATPRV, "Tangent", 700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses the optional tangent vector as texture coordinates");
+ uiBlockEndAlign(block);
+
+ if(ELEM(mtex->texco, TEXCO_UV, TEXCO_ORCO))
+ uiDefButBitS(block, TOG, MTEX_DUPLI_MAPTO, B_MATPRV, "From Dupli", 820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "If object is duplicated by vertices, faces or particles, inherit texture coordinate from parent object");
/* COORDS */
uiBlockBeginAlign(block);
@@ -3142,12 +3458,14 @@ static void material_panel_map_input(Object *ob, Material *ma)
}
-static void material_panel_texture(Material *ma)
+static void material_panel_texture(Object *ob, Material *ma)
{
uiBlock *block;
+ uiBut *but;
MTex *mtex;
ID *id;
- int loos;
+ ParticleSystem *psys;
+ int loos, psys_mapto=0;
int a;
char str[64], *strp;
@@ -3155,6 +3473,11 @@ static void material_panel_texture(Material *ma)
if(uiNewPanel(curarea, block, "Texture", "Material", 960, 0, 318, 204)==0) return;
uiClearButLock();
+ /*check if material is being used by particles*/
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ if(psys->part->omat==ob->actcol)
+ psys_mapto=1;
+
/* TEX CHANNELS */
uiBlockSetCol(block, TH_BUT_NEUTRAL);
@@ -3176,12 +3499,18 @@ static void material_panel_texture(Material *ma)
for(a= 0; a<MAX_MTEX; a++) {
mtex= ma->mtex[a];
if(mtex && mtex->tex) {
- uiDefIconButBitS(block, ICONTOGN, 1<<a, B_MATPRV, ICON_CHECKBOX_HLT-1, -20, 180-18*a, 28, 20, &ma->septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel");
+ but=uiDefIconButBitS(block, ICONTOGN, 1<<a, B_MATPRV, ICON_CHECKBOX_HLT-1, -20, 180-18*a, 28, 20, &ma->septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel");
+
+ if(psys_mapto && ma->mtex[a]->mapto & MAP_PA_IVEL)
+ uiButSetFunc(but, particle_recalc_material, ma, NULL);
}
}
+ /* copy/paste/up/down */
uiBlockBeginAlign(block);
- uiDefIconBut(block, BUT, B_MTEXCOPY, ICON_COPYUP, 100,180,23,21, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
- uiDefIconBut(block, BUT, B_MTEXPASTE, ICON_PASTEUP, 125,180,23,21, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_MTEXCOPY, ICON_COPYUP, 100,180,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer");
+ uiDefIconBut(block, BUT, B_MTEXPASTE, ICON_PASTEUP, 125,180,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer");
+ uiDefIconBut(block, BUT, B_MTEXMOVEUP, VICON_MOVE_UP, 150,180,25,19, 0, 0, 0, 0, 0, "Move texture channel up");
+ uiDefIconBut(block, BUT, B_MTEXMOVEDOWN, VICON_MOVE_DOWN, 175,180,25,19, 0, 0, 0, 0, 0, "Move texture channel down");
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_AUTO);
@@ -3225,44 +3554,102 @@ static void material_panel_texture(Material *ma)
static void material_panel_tramir(Material *ma)
{
- uiBlock *block;
-
- block= uiNewBlock(&curarea->uiblocks, "material_panel_tramir", UI_EMBOSS, UI_HELV, curarea->win);
- uiNewPanelTabbed("Shaders", "Material");
- if(uiNewPanel(curarea, block, "Mirror Transp", "Material", 640, 0, 318, 204)==0) return;
-
- uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+ uiBlock *block;
+ short yco=PANEL_YMAX;
+
+ block= uiNewBlock(&curarea->uiblocks, "material_panel_tramir", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Shaders", "Material");
+ if(uiNewPanel(curarea, block, "Mirror Transp", "Material", PANELX, PANELY, PANELW, PANELH+80)==0) return;
+
+ uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+
+ uiDefButBitI(block, TOG, MA_RAYMIRROR, B_MATPRV, "Ray Mirror",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for mirror reflection rendering");
+
+ yco -= YSPACE;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_MATPRV, "RayMir: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->ray_mirror), 0.0, 1.0, 100, 2, "Sets the amount mirror reflection for raytrace");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_mir), 0.0, 5.0, 10, 2, "Power of Fresnel for mirror reflection");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fac: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_mir_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
- uiDefButBitI(block, TOG, MA_RAYMIRROR, B_MATPRV,"Ray Mirror",210,180,100,20, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for mirror reflection rendering");
-
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_MATPRV, "RayMir ", 10,160,200,20, &(ma->ray_mirror), 0.0, 1.0, 100, 2, "Sets the amount mirror reflection for raytrace");
- uiDefButS(block, NUM, B_MATPRV, "Depth:", 210,160,100,20, &(ma->ray_depth), 0.0, 10.0, 100, 0, "Amount of inter-reflections calculated maximal ");
-
- uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel ", 10,140,160,20, &(ma->fresnel_mir), 0.0, 5.0, 10, 2, "Power of Fresnel for mirror reflection");
- uiDefButF(block, NUMSLI, B_MATPRV, "Fac ", 170,140,140,20, &(ma->fresnel_mir_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Gloss: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->gloss_mir), 0.0, 1.0, 100, 0, "The shininess of the reflection. Values < 1.0 give diffuse, blurry reflections ");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Aniso: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->aniso_gloss_mir), 0.0, 1.0, 100, 0, "The shape of the reflection, from 0. (circular) to 1.0 (fully stretched along the tangent)");
+ uiDefButS(block, NUM, B_MATPRV, "Samples:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->samp_gloss_mir), 1.0, 1024.0, 100, 0, "Number of cone samples averaged for blurry reflections");
+ uiDefButF(block, NUM, B_MATPRV, "Thresh: ",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->adapt_thresh_mir), 0.0, 1.0, 100, 0, "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+ uiDefButS(block, NUM, B_MATPRV, "Depth:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->ray_depth), 0.0, 10.0, 100, 0, "Maximum allowed number of light inter-reflections");
+
+ yco -= YSPACE;
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MATPRV, "Max Dist:",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->dist_mir), 0.0, 10000.0, 100, 0, "Maximum distance of reflected rays. Reflections further than this range fade to sky color");
+ uiDefButS(block, MENU, B_MATPRV, "Ray end fade-out: %t|Fade to Sky Color %x0|Fade to Material Color %x1",
+ X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->fadeto_mir), 0, 0, 0, 0, "The color that rays with no intersection within the Max Distance take. Material color can be best for indoor scenes, sky color for outdoor.");
+ uiBlockEndAlign(block);
+
+ yco=PANEL_YMAX;
+ uiDefButBitI(block, TOG, MA_RAYTRANSP, B_MATRAYTRANSP,"Ray Transp",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for transparent refraction rendering");
+
+ yco -= YSPACE;
+
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_MATPRV, "Filt:", 10,110,150,20, &(ma->filter), 0.0, 1.0, 10, 0, "Amount of filtering for transparent raytrace");
- uiDefButBitI(block, TOG, MA_RAYTRANSP, B_MATRAYTRANSP,"Ray Transp",160,110,150,20, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for transparency rendering");
-
- /* uiBlockBeginAlign(block); */
- uiDefButF(block, NUMSLI, B_MATPRV, "IOR ", 10,90,200,20, &(ma->ang), 1.0, 3.0, 100, 2, "Sets the angular index of refraction for raytrace");
- uiDefButS(block, NUM, B_MATPRV, "Depth:", 210,90,100,20, &(ma->ray_depth_tra), 0.0, 10.0, 100, 0, "Amount of refractions calculated maximal ");
-
- uiDefButF(block, NUMSLI, B_MATPRV, "Limit ", 10,70,160,20, &(ma->tx_limit), 0.0, 100.0, 10, 2, "Depth limit for transmissivity (0.0 is disabled)");
- uiDefButF(block, NUMSLI, B_MATPRV, "Falloff ", 170,70,140,20, &(ma->tx_falloff), 0.1, 10.0, 10, 2, "Falloff power for transmissivity (1.0 is linear)");
-
- uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel ", 10,50,160,20, &(ma->fresnel_tra), 0.0, 5.0, 10, 2, "Power of Fresnel for transparency");
- uiDefButF(block, NUMSLI, B_MATPRV, "Fac ", 170,50,140,20, &(ma->fresnel_tra_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel");
-
+ uiDefButF(block, NUMSLI, B_MATPRV, "IOR: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->ang), 1.0, 3.0, 100, 2, "Sets angular index of refraction for raytraced refraction");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_tra), 0.0, 5.0, 10, 2, "Power of Fresnel for mirror reflection");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Fac: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->fresnel_tra_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
uiBlockBeginAlign(block);
- uiDefButF(block, NUMSLI, B_MATPRV, "SpecTra ", 10,20,150,20, &(ma->spectra), 0.0, 1.0, 0, 0, "Makes specular areas opaque on transparent materials");
-// uiDefButF(block, NUMSLI, B_MATPRV, "Add ", 160,20,150,20, &(ma->add), 0.0, 1.0, 0, 0, "Uses additive blending for Z-transparant materials");
-
+ uiDefButF(block, NUMSLI, B_MATPRV, "Gloss: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->gloss_tra), 0.0, 1.0, 100, 0, "The clarity of the refraction. Values < 1.0 give diffuse, blurry reflections ");
+ uiDefButS(block, NUM, B_MATPRV, "Samples:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->samp_gloss_tra), 0.0, 1024.0, 100, 0, "Number of cone samples averaged for blurry refractions");
+ uiDefButF(block, NUM, B_MATPRV, "Thresh: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->adapt_thresh_tra), 0.0, 1.0, 100, 0, "Threshold for adaptive sampling. If a sample contributes less than this amount (as a percentage), sampling is stopped");
+ uiBlockEndAlign(block);
+
+ yco -= YSPACE;
+
+ uiDefButS(block, NUM, B_MATPRV, "Depth:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->ray_depth_tra), 0.0, 10.0, 100, 0, "Maximum allowed number of light inter-refractions");
+
+ yco -= YSPACE;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_MATPRV, "Filter:",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->filter), 0.0, 1.0, 10, 0, "Amount to blend in the material's diffuse color in raytraced transparency (simulating absorption)");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Limit: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->tx_limit), 0.0, 100.0, 10, 2, "Maximum depth for light to travel through the transparent material before becoming fully filtered (0.0 is disabled)");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Falloff: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->tx_falloff), 0.1, 10.0, 10, 2, "Falloff power for transmissivity filter effect (1.0 is linear)");
uiBlockEndAlign(block);
-}
+ yco -= YSPACE;
+
+ uiDefButF(block, NUMSLI, B_MATPRV, "SpecTra: ",
+ X2CLM2, yco-=BUTH, BUTW2, BUTH, &(ma->spectra), 0.0, 1.0, 0, 0, "Makes specular areas opaque on transparent materials");
+}
/* yafray: adapted version of Blender's tramir panel.
* Only removed the buttons not needed, so only the ones that are important for yafray are left.
@@ -3425,7 +3812,7 @@ static void material_panel_shading(Material *ma)
uiBlock *block;
block= uiNewBlock(&curarea->uiblocks, "material_panel_shading", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Shaders", "Material", 640, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Shaders", "Material", 640, 0, 318, 224)==0) return;
uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
@@ -3502,24 +3889,25 @@ static void material_panel_shading(Material *ma)
uiDefButF(block, NUMSLI, B_MATPRV, "Tralu ", 9,30,150,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Translucency, amount of diffuse shading of the back side");
uiDefButF(block, NUMSLI, B_MATPRV, "SBias ", 159,30,151,19, &(ma->sbias), 0.0, 0.25, 10, 2, "Shadow bias, to prevent terminator problems on shadow boundary");
uiDefButF(block, NUMSLI, B_MATPRV, "Amb ", 9,10,150,19, &(ma->amb), 0.0, 1.0, 0, 0, "Sets the amount of global ambient color the material receives");
- uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 159,10,151,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits");
+ uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 159,10,151,19, &(ma->emit), 0.0, 2.0, 0, 0, "Sets the amount of light the material emits");
+ uiDefButF(block, NUMSLI, B_MATPRV, "LBias ", 9,-10,300,19, &(ma->lbias), 0.0, 10.0, 100, 2, "Factor to multiply shadowbuffer bias with (0 is ignore)");
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitI(block, TOG, MA_TANGENT_V, B_MATPRV, "Tangent V", 245,180,65,19, &(ma->mode), 0, 0, 0, 0, "Use the tangent vector in V direction for shading");
- /* qdn: normalmap tangents separated from shading */
- uiDefButBitI(block, TOG, MA_NORMAP_TANG, B_MATPRV, "NMap TS", 245,160,65,19, &(ma->mode), 0, 0, 0, 0, "Enable Tangent Space normal mapping");
-
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, MA_SHADOW, B_MATPRV, "Shadow", 245,140,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows");
uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_MATPRV, "TraShadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Receives transparent shadows based at material color and alpha");
uiDefButBitI(block, TOG, MA_ONLYSHADOW, B_MATPRV, "OnlyShad", 245,100,65,20, &(ma->mode), 0, 0, 0, 0, "Renders shadows on material as Alpha value");
- uiDefButBitI(block, TOG, MA_RAYBIAS, B_MATPRV, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)");
+ uiDefButBitS(block, TOG, MA_CUBIC, B_MATPRV, "Cubic", 245,80,65,19, &(ma->shade_flag), 0, 0, 0, 0, "Use Cubic interpolation of diffuse values, for smoother transitions");
+ uiDefButBitI(block, TOG, MA_RAYBIAS, B_MATPRV, "Bias", 245,60,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)");
uiBlockBeginAlign(block);
uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_MATPRV, "GR:", 9, 55, 150, 19, &ma->group, "Limit Lighting to Lamps in this Group");
- uiDefButBitI(block, TOG, MA_GROUP_NOLAY, B_MATPRV, "Exclusive", 159,55, 85,20, &(ma->mode), 0, 0, 0, 0, "The material exclusively uses Lamps in this Group");
+ uiDefButBitI(block, TOG, MA_GROUP_NOLAY, B_MATPRV, "Exclusive", 159,55, 85,20, &(ma->mode), 0, 0, 0, 0, "Material uses Lights in this group exclusively, they get excluded from the Scene lighting");
+
+
}
}
@@ -3534,14 +3922,14 @@ static void material_panel_ramps(Material *ma)
uiNewPanelTabbed("Material", "Material");
if(uiNewPanel(curarea, block, "Ramps", "Material", 640, 0, 318, 204)==0) return;
- uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
-
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, ROW, B_REDR, "Show Col Ramp",10,180,150,20, &ma->ramp_show, 0, 0, 0, 0, "Show ramp buttons for material diffuse color");
uiDefButS(block, ROW, B_REDR, "Show Spec Ramp",160,180,150,20, &ma->ramp_show, 0, 1, 0, 0, "Show ramp buttons for material specular color");
uiBlockSetCol(block, TH_AUTO);
+ uiSetButLock(ma->id.lib!=NULL, ERROR_LIBDATA_MESSAGE);
+
/* COLORBAND */
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, ma->ramp_show?MA_RAMP_SPEC:MA_RAMP_COL, B_MATCOLORBAND, "Colorband",10,145,80,20, &ma->mode, 0, 0, 0, 0, "Toggles colorband ramp operations");
@@ -3576,21 +3964,41 @@ static uiBlock *strand_menu(void *mat_v)
{
Material *ma= mat_v;
uiBlock *block;
-
+ int buth=20, butw=230, butx=10, buty=180;
+
block= uiNewBlock(&curarea->uiblocks, "strand menu", UI_EMBOSS, UI_HELV, curarea->win);
-
+
+ if(ma->mode & MA_STR_B_UNITS)
+ buty += buth;
+
/* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", 0, 0, 250, 100, NULL, 0, 0, 0, 0, "");
-
+ uiDefBut(block, LABEL, 0, "", 0, 0, butw+20, buty+10, NULL, 0, 0, 0, 0, "");
+ /* event return 0, to prevent menu to close */
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", butx,buty-=buth,butw,buth, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading");
+ uiDefButBitI(block, TOG, MA_STR_SURFDIFF, 0, "Surface Diffuse", butx,buty-=buth,butw/2,buth, &(ma->mode), 0, 0, 0, 0, "Make diffuse shading more similar to shading the surface");
+ uiDefButF(block, NUM, 0, "Dist", butx+butw/2,buty,butw/2,buth, &ma->strand_surfnor, 0.0f, 10.0f, 2, 0, "Distance in Blender units over which to blend in the surface normal");
+
+ buty -= 5;
+
uiBlockBeginAlign(block);
- /* event return 0, to prevent menu to close */
- uiDefButBitI(block, TOG, MA_TANGENT_STR, 0, "Use Tangent Shading", 10,70,230,20, &(ma->mode), 0, 0, 0, 0, "Uses direction of strands as normal for tangent-shading");
- uiDefButF(block, NUMSLI, 0, "Start ", 10, 50, 230,20, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels");
- uiDefButF(block, NUMSLI, 0, "End ", 10, 30, 230,20, &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels");
- uiDefButF(block, NUMSLI, 0, "Shape ", 10, 10, 230,20, &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky");
+ uiDefButBitI(block, TOG, MA_STR_B_UNITS, 0, "Use Blender Units", butx,buty-=buth,butw,buth, &(ma->mode), 0, 0, 0, 0, "Use actual Blender units for widths instead of pixels");
+ if(ma->mode & MA_STR_B_UNITS){
+ uiDefButF(block, NUMSLI, 0, "Start ", butx,buty-=buth, butw,buth, &ma->strand_sta, 0.0001, 2.0, 2, 0, "Start size of strands in Blender units");
+ uiDefButF(block, NUMSLI, 0, "End ", butx,buty-=buth, butw,buth, &ma->strand_end, 0.0001, 1.0, 2, 0, "End size of strands in Blender units");
+ uiDefButF(block, NUMSLI, 0, "Minimum ", butx,buty-=buth, butw,buth, &ma->strand_min, 0.001, 10.0, 0, 0, "Minimum size of strands in pixels");
+ }
+ else{
+ uiDefButF(block, NUMSLI, 0, "Start ", butx,buty-=buth, butw,buth, &ma->strand_sta, 0.25, 20.0, 2, 0, "Start size of strands in pixels");
+ uiDefButF(block, NUMSLI, 0, "End ", butx,buty-=buth, butw,buth, &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels");
+ }
+ uiDefButF(block, NUMSLI, 0, "Shape ", butx,buty-=buth, butw,buth, &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky");
+ uiDefButF(block, NUMSLI, 0, "Width Fade ", butx,buty-=buth, butw,buth, &ma->strand_widthfade, 0.0, 2.0, 2, 0, "Transparency along the width of the strand");
+ uiDefBut(block, TEX, B_MATPRV, "UV:", butx,buty-=buth,butw,buth, ma->strand_uvname, 0, 31, 0, 0, "Set name of UV layer to override");
uiBlockSetDirection(block, UI_TOP);
-
+ BIF_preview_changed(ID_MA);
return block;
}
@@ -3625,8 +4033,9 @@ static void material_panel_material(Material *ma)
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitI(block, TOG, MA_VERTEXCOL, B_MAT_VCOL_LIGHT, "VCol Light", 8,166,74,20, &(ma->mode), 0, 0, 0, 0, "Adds vertex colors as extra light");
uiDefButBitI(block, TOG, MA_VERTEXCOLP, B_MAT_VCOL_PAINT, "VCol Paint", 82,166,74,20, &(ma->mode), 0, 0, 0, 0, "Replaces material's colors with vertex colors");
- uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,166,74,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces");
- uiDefButBitI(block, TOG, MA_SHLESS, B_MATPRV, "Shadeless", 230,166,73,20, &(ma->mode), 0, 0, 0, 0, "Makes material insensitive to light or shadow");
+ uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,166,64,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces");
+ if (ma->mode & MA_FACETEXTURE) uiDefButBitI(block, TOG, MA_FACETEXTURE_ALPHA, B_REDR, "A", 220,166,20,20, &(ma->mode), 0, 0, 0, 0, "Use alpha channel in 'TexFace' assigned images");
+ uiDefButBitI(block, TOG, MA_SHLESS, B_MATPRV, "Shadeless", 240,166,63,20, &(ma->mode), 0, 0, 0, 0, "Makes material insensitive to light or shadow");
uiDefButBitI(block, TOG, MA_NOMIST, B_NOP, "No Mist", 8,146,74,20, &(ma->mode), 0, 0, 0, 0, "Sets the material to ignore mist values");
uiDefButBitI(block, TOG, MA_ENV, B_MATPRV, "Env", 82,146,74,20, &(ma->mode), 0, 0, 0, 0, "Causes faces to render with alpha zero: allows sky/backdrop to show through (only for solid faces)");
@@ -3670,7 +4079,8 @@ static void material_panel_material(Material *ma)
uiDefButF(block, NUMSLI, B_MATPRV, "B ", 128,57,175,19, colpoin+2, 0.0, 1.0, rgbsel, 0, "");
}
uiBlockEndAlign(block);
- uiDefButF(block, NUMSLI, B_MATPRV, "A ", 128,30,175,19, &ma->alpha, 0.0, 1.0, 0, 0, "Alpha");
+ if (ma->mode & (MA_FACETEXTURE) && ma->mode & (MA_FACETEXTURE_ALPHA)) ;
+ else uiDefButF(block, NUMSLI, B_MATPRV, "A ", 128,30,175,19, &ma->alpha, 0.0, 1.0, 0, 0, "Alpha");
}
uiBlockBeginAlign(block);
@@ -3757,6 +4167,7 @@ static void material_panel_links(Object *ob, Material *ma)
}
uiBlockSetCol(block, TH_BUT_ACTION);
+ uiClearButLock();
uiDefButBitS(block, TOG, 1<<(ob->actcol-1), B_MATFROM, "OB", 125,135,32,20, &ob->colbits, 0, 0, 0, 0, "Links material to object");
idn= ob->data;
strncpy(str, idn->name, 2);
@@ -3799,7 +4210,7 @@ static void material_panel_links(Object *ob, Material *ma)
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, MA_HALO, B_MATHALO, "Halo", 10,50,100,19, &(ma->mode), 0, 0, 0, 0, "Renders material as a halo");
uiDefButBitI(block, TOG, MA_ZTRA, B_MATZTRANSP,"ZTransp", 110,50,100,19, &(ma->mode), 0, 0, 0, 0, "Enables Z-Buffering of transparent faces");
- uiDefButF(block, NUM, B_DIFF, "Zoffs:", 210,50,100,19, &(ma->zoffs), 0.0, 10.0, 100, 0, "Gives faces an artificial offset in the Z buffer for Ztransp option");
+ uiDefButF(block, NUM, B_DIFF, "Zoffs:", 210,50,100,19, &(ma->zoffs), 0.0, 100.0, 100, 0, "Gives faces an artificial offset in the Z buffer for Ztransp option");
uiDefButBitI(block, TOG, MA_FULL_OSA, 0, "Full Osa", 10,30,75,19, &(ma->mode), 0.0, 10.0, 0, 0, "Forces to render all OSA samples, for shading and texture antialiasing");
uiDefButBitI(block, TOG, MA_WIRE, B_MATPRV, "Wire", 85,30,75,19, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe");
@@ -3883,12 +4294,12 @@ void material_panels()
}
material_panel_sss(ma);
- material_panel_texture(ma);
+ material_panel_texture(ob, ma);
mtex= ma->mtex[ ma->texact ];
if(mtex && mtex->tex) {
material_panel_map_input(ob, ma);
- material_panel_map_to(ma, from_nodes);
+ material_panel_map_to(ob, ma, from_nodes);
}
}
}
@@ -3897,24 +4308,29 @@ void material_panels()
void lamp_panels()
{
Object *ob= OBACT;
+ Lamp *la;
if(ob==NULL || ob->type!= OB_LAMP) return;
+ la= ob->data;
lamp_panel_preview(ob, ob->data);
lamp_panel_lamp(ob, ob->data);
+
+ if (ELEM(la->type, LA_SPOT, LA_LOCAL) && (la->falloff_type == LA_FALLOFF_CURVE))
+ lamp_panel_falloff(ob, ob->data);
+
/* switch to yafray lamp panel if yafray enabled */
if (G.scene->r.renderer==R_INTERN)
lamp_panel_spot(ob, ob->data);
else {
/* init vars */
- Lamp* lp = ob->data;
- if (lp->YF_numphotons==0) lp->YF_numphotons=1000;
- if (lp->YF_numsearch==0) lp->YF_numsearch=10;
- if (lp->YF_phdepth==0) lp->YF_phdepth=1;
- if (lp->YF_causticblur==0.0) lp->YF_causticblur=0.001;
- if (lp->YF_bufsize==0) lp->YF_bufsize=128;
+ if (la->YF_numphotons==0) la->YF_numphotons=1000;
+ if (la->YF_numsearch==0) la->YF_numsearch=10;
+ if (la->YF_phdepth==0) la->YF_phdepth=1;
+ if (la->YF_causticblur==0.0) la->YF_causticblur=0.001;
+ if (la->YF_bufsize==0) la->YF_bufsize=128;
/* spherelight radius default is zero, so nothing to do */
- lamp_panel_yafray(ob, lp);
+ lamp_panel_yafray(ob, la);
}
lamp_panel_texture(ob, ob->data);
lamp_panel_mapto(ob, ob->data);
@@ -4003,7 +4419,7 @@ void texture_panels()
switch(tex->type) {
case TEX_IMAGE:
texture_panel_image(&tex->ima, &tex->iuser);
- texture_panel_image_map(tex);
+ texture_panel_image_map(tex, mtex);
break;
case TEX_ENVMAP:
texture_panel_envmap(tex);
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index fd6f5f8f0b4..9dbcd656df6 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Joshua Leung
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
* Drawing routines for the Action window type
@@ -61,7 +61,10 @@
#include "DNA_key_types.h"
#include "BKE_action.h"
+#include "BKE_depsgraph.h"
#include "BKE_ipo.h"
+#include "BKE_key.h"
+#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -69,6 +72,7 @@
#include "BIF_editaction.h"
#include "BIF_editkey.h"
+#include "BIF_editnla.h"
#include "BIF_interface.h"
#include "BIF_interface_icons.h"
#include "BIF_gl.h"
@@ -83,6 +87,7 @@
#include "BSE_drawnla.h"
#include "BSE_drawipo.h"
+#include "BSE_editaction_types.h"
#include "BSE_editipo.h"
#include "BSE_time.h"
#include "BSE_view.h"
@@ -90,14 +95,17 @@
/* 'old' stuff": defines and types, and own include -------------------- */
#include "blendef.h"
+#include "interface.h"
#include "mydevice.h"
+/********************************** Slider Stuff **************************** */
+
/* sliders for shapekeys */
static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
{
int i;
char str[64];
- float x, y;
+ float x, y;
uiBlock *block;
uiBut *but;
@@ -110,19 +118,18 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
* correctly *grumble*
*/
mywinset(curarea->win);
- myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+ myortho2(-0.375, curarea->winx-0.375, G.v2d->cur.ymin, G.v2d->cur.ymax);
sprintf(str, "actionbuttonswin %d", curarea->win);
- block= uiNewBlock (&curarea->uiblocks, str,
- UI_EMBOSS, UI_HELV, curarea->win);
+ block= uiNewBlock (&curarea->uiblocks, str, UI_EMBOSS, UI_HELV, curarea->win);
x = NAMEWIDTH + 1;
- y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP) + CHANNELHEIGHT/2 - G.v2d->cur.ymin;
+ y = 0.0f;
/* make the little 'open the sliders' widget */
- BIF_ThemeColor(TH_FACE); // this slot was open...
- glRects(2, y + 2*CHANNELHEIGHT - 2,
- ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
+ // should eventually be removed
+ BIF_ThemeColor(TH_FACE); // this slot was open... (???... Aligorith)
+ glRects(2, y + 2*CHANNELHEIGHT - 2, ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
glColor3ub(0, 0, 0);
glRasterPos2f(4, y + CHANNELHEIGHT + 6);
BMF_DrawString(G.font, "Sliders");
@@ -158,14 +165,14 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
glRects(NAMEWIDTH, 0, NAMEWIDTH+SLIDERWIDTH, curarea->winy);
uiBlockSetEmboss(block, UI_EMBOSS);
- for (i=1 ; i < key->totkey ; ++ i) {
+ for (i=1; i < key->totkey; i++) {
make_rvk_slider(block, ob, i,
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1, "Slider to control Shape Keys");
y-=CHANNELHEIGHT+CHANNELSKIP;
/* see sliderval array in editkey.c */
- if(i>=255) break;
+ if(i >= 255) break;
}
}
uiDrawBlock(block);
@@ -195,23 +202,32 @@ static void icu_slider_func(void *voidicu, void *voidignore)
/* create the bezier triple if one doesn't exist,
* otherwise modify it's value
*/
- if (!bezt) {
- insert_vert_ipo(icu, cfra, icu->curval);
+ if (bezt == NULL) {
+ insert_vert_icu(icu, cfra, icu->curval, 0);
}
else {
bezt->vec[1][1] = icu->curval;
}
- /* make sure the Ipo's are properly process and
+ /* make sure the Ipo's are properly processed and
* redraw as necessary
*/
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ /* nla-update (in case this affects anything) */
+ synchronize_action_strips();
+
+ /* do redraw pushes, and also the depsgraph flushes */
+ if (OBACT->pose || ob_get_key(OBACT))
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC);
+ else
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWBUTSALL, 0);
}
@@ -226,8 +242,8 @@ static void make_icu_slider(uiBlock *block, IpoCurve *icu,
if (IS_EQ(icu->slide_max, icu->slide_min)) {
if (IS_EQ(icu->ymax, icu->ymin)) {
- if (icu->blocktype == ID_CO) {
- /* hack for constraints (and maybe a few others) */
+ if (ELEM(icu->blocktype, ID_CO, ID_KE)) {
+ /* hack for constraints and shapekeys (and maybe a few others) */
icu->slide_min= 0.0;
icu->slide_max= 1.0;
}
@@ -259,10 +275,12 @@ static void make_icu_slider(uiBlock *block, IpoCurve *icu,
/* sliders for ipo-curves of active action-channel */
static void action_icu_buts(SpaceAction *saction)
{
- bAction *act= saction->action;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
char str[64];
float x, y;
uiBlock *block;
@@ -280,72 +298,93 @@ static void action_icu_buts(SpaceAction *saction)
UI_EMBOSS, UI_HELV, curarea->win);
x = NAMEWIDTH + 1;
- y = 0.0;
+ y = 0.0f;
uiBlockSetEmboss(block, UI_EMBOSSN);
if (G.saction->flag & SACTION_SLIDERS) {
/* sliders are open so draw them */
+ /* get editor data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* build list of channels to draw */
+ filter= (ACTFILTER_FORDRAWING|ACTFILTER_VISIBLE|ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
/* draw backdrop first */
BIF_ThemeColor(TH_FACE); // change this color... it's ugly
glRects(NAMEWIDTH, G.v2d->cur.ymin, NAMEWIDTH+SLIDERWIDTH, G.v2d->cur.ymax);
uiBlockSetEmboss(block, UI_EMBOSS);
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (EXPANDED_ACHAN(achan)) {
- if (achan->ipo) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
+ for (ale= act_data.first; ale; ale= ale->next) {
+ const float yminc= y-CHANNELHEIGHT/2;
+ const float ymaxc= y+CHANNELHEIGHT/2;
+
+ /* check if visible */
+ if ( IN_RANGE(yminc, G.v2d->cur.ymin, G.v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, G.v2d->cur.ymin, G.v2d->cur.ymax) )
+ {
+ /* determine what needs to be drawn */
+ switch (ale->type) {
+ case ACTTYPE_CONCHAN: /* constraint channel */
+ {
+ bActionChannel *achan = (bActionChannel *)ale->owner;
+ IpoCurve *icu = (IpoCurve *)ale->key_data;
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (achan->flag & ACHAN_HILIGHTED) {
- make_icu_slider(block, icu,
- x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
- "Slider to control current value of IPO-Curve");
- }
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
+ /* only show if action channel is selected */
+ if (SEL_ACHAN(achan)) {
+ make_icu_slider(block, icu,
+ x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
+ "Slider to control current value of Constraint Influence");
}
}
-
- if (achan->constraintChannels.first) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
+ break;
+ case ACTTYPE_ICU: /* ipo-curve channel */
+ {
+ bActionChannel *achan = (bActionChannel *)ale->owner;
+ IpoCurve *icu = (IpoCurve *)ale->key_data;
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if ((achan->flag & ACHAN_HILIGHTED) && EDITABLE_CONCHAN(conchan)) {
- icu= (IpoCurve *)conchan->ipo->curve.first;
- make_icu_slider(block, icu,
- x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
- "Slider to control current value of Constraint Channel");
- }
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
+ /* only show if action channel is selected */
+ if (SEL_ACHAN(achan)) {
+ make_icu_slider(block, icu,
+ x, y, SLIDERWIDTH-2, CHANNELHEIGHT-2,
+ "Slider to control current value of IPO-Curve");
}
}
- }
+ break;
+ case ACTTYPE_SHAPEKEY: /* shapekey channel */
+ {
+ // TODO...
+ }
+ break;
+ }
}
+
+ /* adjust y-position for next one */
+ y-=CHANNELHEIGHT+CHANNELSKIP;
}
+
+ /* free tempolary channels */
+ BLI_freelistN(&act_data);
}
uiDrawBlock(block);
}
-void draw_cfra_action(void)
+/********************************** Current Frame **************************** */
+
+void draw_cfra_action (void)
{
Object *ob;
float vec[2];
+ /* Draw a light green line to indicate current frame */
vec[0]= (G.scene->r.cfra);
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
- glColor3ub(0x60, 0xc0, 0x40);
+ BIF_ThemeColor(TH_CFRAME);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
@@ -354,11 +393,12 @@ void draw_cfra_action(void)
glVertex2fv(vec);
glEnd();
+ /* Draw dark green line if slow-parenting/time-offset is enabled */
ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
- if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
- vec[0]-= ob->sf;
+ if ((ob) && (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0)) {
+ vec[0]-= give_timeoffset(ob); /* could avoid calling twice */
- glColor3ub(0x10, 0x60, 0);
+ BIF_ThemeColorShade(TH_CFRAME, -30);
glBegin(GL_LINE_STRIP);
glVertex2fv(vec);
@@ -370,211 +410,25 @@ void draw_cfra_action(void)
glLineWidth(1.0);
}
-/* left hand */
-static void draw_action_channel_names(bAction *act)
-{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- float x, y;
-
- x = 0.0;
- y = 0.0f;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
-
- /* draw backing strip behind action channel name */
- BIF_ThemeColorShade(TH_HEADER, 20);
- glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- /* draw expand/collapse triangle for action-channel */
- if (EXPANDED_ACHAN(achan))
- BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
- else
- BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
-
- /* draw name of action channel */
- if (SEL_ACHAN(achan))
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x+18, y-4);
- BMF_DrawString(G.font, achan->name);
-
- /* draw 'lock' indicating whether channel is protected */
- if (EDITABLE_ACHAN(achan)==0)
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
- else
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (EXPANDED_ACHAN(achan)) {
- /* Draw IPO-curves show/hide widget */
- if (achan->ipo) {
- /* draw backing strip behind */
- BIF_ThemeColorShade(TH_HEADER, -20);
- glRectf(x+7, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- /* draw expand/collapse triangle for showing sub-channels */
- if (FILTER_IPO_ACHAN(achan))
- BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
- else
- BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
-
- /* draw icon showing type of ipo-block */
- BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, geticon_ipo_blocktype(achan->ipo->blocktype));
-
- /* draw name of ipo-block */
- if (SEL_ACHAN(achan))
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x+40, y-4);
- BMF_DrawString(G.font, "IPO Curves"); // TODO: make proper naming scheme
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- /* Draw IPO-curve-channels? */
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- char *icu_name= getname_ipocurve(icu);
-
- /* draw backing strip behind ipo-curve channel*/
- BIF_ThemeColorShade(TH_HEADER, -40);
- glRectf(x+14, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- /* draw name of ipo-curve channel */
- if (SEL_ICU(icu))
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x+24, y-4);
- BMF_DrawString(G.font, icu_name);
-
-#if 0 /* tempolarily disabled until all ipo-code can support this option */
- /* draw 'lock' to indicate if ipo-curve channel is protected */
- if (EDITABLE_ICU(icu)==0)
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
- else
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
-#endif
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
- }
-
- /* Draw constraints show/hide widget */
- if (achan->constraintChannels.first) {
- /* draw backing strip behind */
- BIF_ThemeColorShade(TH_HEADER, -20);
- glRectf(x+7, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- /* draw expand/collapse triangle for showing sub-channels */
- if (FILTER_CON_ACHAN(achan))
- BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
- else
- BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
-
- /* draw constraint icon */
- BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, ICON_CONSTRAINT);
-
- /* draw name of widget */
- if (SEL_ACHAN(achan))
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x+40, y-4);
- BMF_DrawString(G.font, "Constraints");
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- /* Draw constraint channels? */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- /* draw backing strip behind constraint channel*/
- BIF_ThemeColorShade(TH_HEADER, -40);
- glRectf(x+14, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- /* draw name of constraint channel */
- if (SEL_CONCHAN(conchan))
- BIF_ThemeColor(TH_TEXT_HI);
- else
- BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x+25, y-4);
- BMF_DrawString(G.font, conchan->name);
-
- /* draw 'lock' to indicate if constraint channel is protected */
- if (EDITABLE_CONCHAN(conchan)==0)
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
- else
- BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
- }
- }
-
- glDisable(GL_BLEND);
- }
- }
-}
-
-
-static void draw_action_mesh_names(Key *key)
-{
- /* draws the names of the rvk keys in the
- * left side of the action window
- */
- int i;
- char keyname[32];
- float x, y;
- KeyBlock *kb;
-
- x = 0.0;
- y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
-
- kb= key->block.first;
-
- for (i=1 ; i < key->totkey ; ++ i) {
- glColor3ub(0xAA, 0xAA, 0xAA);
- glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2);
-
- glColor3ub(0, 0, 0);
-
- glRasterPos2f(x+8, y-4);
- kb = kb->next;
- /* Blender now has support for named
- * key blocks. If a name hasn't
- * been set for an key block then
- * just display the key number --
- * otherwise display the name stored
- * in the keyblock.
- */
- if (kb->name[0] == '\0') {
- sprintf(keyname, "Key %d", i);
- BMF_DrawString(G.font, keyname);
- }
- else {
- BMF_DrawString(G.font, kb->name);
- }
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- }
-}
+/********************************** Left-Hand Panel + Generics **************************** */
/* left hand part */
static void draw_channel_names(void)
{
- short ofsx, ofsy = 0;
- bAction *act;
- Key *key;
-
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ short ofsx = 0, ofsy = 0;
+ float x= 0.0f, y= 0.0f;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
/* Clip to the scrollable area */
- if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ if (curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
if(G.v2d->scroll) {
ofsx= curarea->winrct.xmin;
ofsy= curarea->winrct.ymin;
@@ -587,58 +441,247 @@ static void draw_channel_names(void)
}
}
- myortho2(0, NAMEWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax); // Scaling
+ /* prepare scaling for LHS panel */
+ myortho2(0, NAMEWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ /* set default color back to black */
glColor3ub(0x00, 0x00, 0x00);
-
- act=G.saction->action;
-
- if (act) {
- /* if there is a selected action then
- * draw the channel names
- */
- draw_action_channel_names(act);
- }
- else if ( (key = get_action_mesh_key()) ) {
- /* if there is a mesh selected with rvk's,
- * then draw the RVK names
- */
- draw_action_mesh_names(key);
- }
-
- myortho2(0, NAMEWIDTH, 0, (ofsy+G.v2d->mask.ymax) -
- (ofsy+G.v2d->mask.ymin)); // Scaling
-
-}
-
-int count_action_levels(bAction *act)
-{
- bActionChannel *achan;
- int y=0;
-
- if (!act)
- return 0;
-
- for (achan=act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- y++;
+
+ /* build list of channels to draw */
+ filter= (ACTFILTER_FORDRAWING|ACTFILTER_VISIBLE|ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through channels, and set up drawing depending on their type */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ const float yminc= y-CHANNELHEIGHT/2;
+ const float ymaxc= y+CHANNELHEIGHT/2;
+
+ /* check if visible */
+ if ( IN_RANGE(yminc, G.v2d->cur.ymin, G.v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, G.v2d->cur.ymin, G.v2d->cur.ymax) )
+ {
+ short indent= 0, offset= 0, sel= 0, group=0;
+ int expand= -1, protect = -1, special= -1, mute = -1;
+ char name[32];
- if (EXPANDED_ACHAN(achan)) {
- if (achan->constraintChannels.first) {
- y++;
- if (FILTER_CON_ACHAN(achan))
- y += BLI_countlist(&achan->constraintChannels);
+ /* determine what needs to be drawn */
+ switch (ale->type) {
+ case ACTTYPE_GROUP: /* action group */
+ {
+ bActionGroup *agrp= (bActionGroup *)ale->data;
+
+ group= 2;
+ indent= 0;
+ special= -1;
+
+ if (EXPANDED_AGRP(agrp))
+ expand = ICON_TRIA_DOWN;
+ else
+ expand = ICON_TRIA_RIGHT;
+
+ if (EDITABLE_AGRP(agrp))
+ protect = ICON_UNLOCKED;
+ else
+ protect = ICON_LOCKED;
+
+ sel = SEL_AGRP(agrp);
+ sprintf(name, agrp->name);
+ }
+ break;
+ case ACTTYPE_ACHAN: /* action channel */
+ {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+
+ group= (ale->grp) ? 1 : 0;
+ indent = 0;
+ special = -1;
+
+ if (EXPANDED_ACHAN(achan))
+ expand = ICON_TRIA_DOWN;
+ else
+ expand = ICON_TRIA_RIGHT;
+
+ if (EDITABLE_ACHAN(achan))
+ protect = ICON_UNLOCKED;
+ else
+ protect = ICON_LOCKED;
+
+ if (achan->ipo) {
+ if (achan->ipo->muteipo)
+ mute = ICON_MUTE_IPO_ON;
+ else
+ mute = ICON_MUTE_IPO_OFF;
+ }
+
+ sel = SEL_ACHAN(achan);
+ sprintf(name, achan->name);
+ }
+ break;
+ case ACTTYPE_CONCHAN: /* constraint channel */
+ {
+ bConstraintChannel *conchan = (bConstraintChannel *)ale->data;
+
+ indent = 2;
+ group= (ale->grp) ? 1 : 0;
+
+ if (EDITABLE_CONCHAN(conchan))
+ protect = ICON_UNLOCKED;
+ else
+ protect = ICON_LOCKED;
+
+ if (conchan->ipo) {
+ if (conchan->ipo->muteipo)
+ mute = ICON_MUTE_IPO_ON;
+ else
+ mute = ICON_MUTE_IPO_OFF;
+ }
+
+ sel = SEL_CONCHAN(conchan);
+ sprintf(name, conchan->name);
+ }
+ break;
+ case ACTTYPE_ICU: /* ipo-curve channel */
+ {
+ IpoCurve *icu = (IpoCurve *)ale->data;
+
+ indent = 2;
+ protect = -1; // for now, until this can be supported by others
+ group= (ale->grp) ? 1 : 0;
+
+ if (icu->flag & IPO_MUTE)
+ mute = ICON_MUTE_IPO_ON;
+ else
+ mute = ICON_MUTE_IPO_OFF;
+
+ sel = SEL_ICU(icu);
+ if (G.saction->pin)
+ sprintf(name, getname_ipocurve(icu, NULL));
+ else
+ sprintf(name, getname_ipocurve(icu, OBACT));
+ }
+ break;
+ case ACTTYPE_SHAPEKEY: /* shapekey channel */
+ {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+
+ indent = 0;
+ special = -1;
+
+ if (kb->name[0] == '\0')
+ sprintf(name, "Key %d", ale->index);
+ else
+ sprintf(name, kb->name);
+ }
+ break;
+ case ACTTYPE_FILLIPO: /* ipo expand widget */
+ {
+ bActionChannel *achan = (bActionChannel *)ale->data;
+
+ indent = 1;
+ special = geticon_ipo_blocktype(achan->ipo->blocktype);
+ group= (ale->grp) ? 1 : 0;
+
+ if (FILTER_IPO_ACHAN(achan))
+ expand = ICON_TRIA_DOWN;
+ else
+ expand = ICON_TRIA_RIGHT;
+
+ sel = SEL_ACHAN(achan);
+ sprintf(name, "IPO Curves");
}
- else if (achan->ipo) {
- y++;
- if (FILTER_IPO_ACHAN(achan))
- y += BLI_countlist(&achan->ipo->curve);
+ break;
+ case ACTTYPE_FILLCON: /* constraint expand widget */
+ {
+ bActionChannel *achan = (bActionChannel *)ale->data;
+
+ indent = 1;
+ special = ICON_CONSTRAINT;
+ group= (ale->grp) ? 1 : 0;
+
+ if (FILTER_CON_ACHAN(achan))
+ expand = ICON_TRIA_DOWN;
+ else
+ expand = ICON_TRIA_RIGHT;
+
+ sel = SEL_ACHAN(achan);
+ sprintf(name, "Constraint");
}
+ break;
+ }
+
+ /* now, start drawing based on this information */
+ /* draw backing strip behind channel name */
+ if (group == 2) {
+ /* only for group-channels */
+ if (ale->flag & AGRP_ACTIVE)
+ BIF_ThemeColorShade(TH_GROUP_ACTIVE, 10);
+ else
+ BIF_ThemeColorShade(TH_GROUP, 20);
+ uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8));
+ gl_round_box(GL_POLYGON, x, yminc, (float)NAMEWIDTH, ymaxc, 8);
+
+ offset = 0;
+ }
+ else {
+ /* for normal channels */
+ BIF_ThemeColorShade(TH_HEADER, ((indent==0)?20: (indent==1)?-20: -40));
+ indent += group;
+ offset = 7 * indent;
+ glRectf(x+offset, yminc, (float)NAMEWIDTH, ymaxc);
+ }
+
+ /* draw expand/collapse triangle */
+ if (expand > 0) {
+ BIF_icon_draw(x+offset, yminc, expand);
+ offset += 17;
+ }
+
+ /* draw special icon indicating type of ipo-blocktype?
+ * only for expand widgets for Ipo and Constraint Channels
+ */
+ if (special > 0) {
+ offset = (group) ? 29 : 24;
+ BIF_icon_draw(x+offset, yminc, special);
+ offset += 17;
+ }
+
+ /* draw name */
+ if (sel)
+ BIF_ThemeColor(TH_TEXT_HI);
+ else
+ BIF_ThemeColor(TH_TEXT);
+ offset += 3;
+ glRasterPos2f(x+offset, y-4);
+ BMF_DrawString(G.font, name);
+
+ /* reset offset - for RHS of panel */
+ offset = 0;
+
+ /* draw protect 'lock' */
+ if (protect > 0) {
+ offset = 16;
+ BIF_icon_draw(NAMEWIDTH-offset, yminc, protect);
+ }
+
+ /* draw mute 'eye' */
+ if (mute > 0) {
+ offset += 16;
+ BIF_icon_draw(NAMEWIDTH-offset, yminc, mute);
}
}
+
+ /* adjust y-position for next one */
+ y-=CHANNELHEIGHT+CHANNELSKIP;
}
-
- return y;
+
+ /* free tempolary channels */
+ BLI_freelistN(&act_data);
+
+ /* re-adjust view matrices for correct scaling */
+ myortho2(0, NAMEWIDTH, 0, (ofsy+G.v2d->mask.ymax) - (ofsy+G.v2d->mask.ymin)); // Scaling
}
/* sets or clears hidden flags */
@@ -646,12 +689,12 @@ void check_action_context(SpaceAction *saction)
{
bActionChannel *achan;
- if(saction->action==NULL) return;
+ if (saction->action==NULL) return;
for (achan=saction->action->chanbase.first; achan; achan=achan->next)
achan->flag &= ~ACHAN_HIDDEN;
- if (G.saction->pin==0 && OBACT) {
+ if ((saction->pin==0) && ((saction->flag & SACTION_NOHIDE)==0) && (OBACT)) {
Object *ob= OBACT;
bPoseChannel *pchan;
bArmature *arm= ob->data;
@@ -668,155 +711,176 @@ void check_action_context(SpaceAction *saction)
}
}
-static void draw_channel_strips(SpaceAction *saction)
+static void draw_channel_strips(void)
{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
rcti scr_rct;
gla2DDrawInfo *di;
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
float y, sta, end;
int act_start, act_end, dummy;
char col1[3], col2[3];
+ char col1a[3], col2a[3];
BIF_GetThemeColor3ubv(TH_SHADE2, col2);
BIF_GetThemeColor3ubv(TH_HILITE, col1);
+ BIF_GetThemeColor3ubv(TH_GROUP, col2a);
+ BIF_GetThemeColor3ubv(TH_GROUP_ACTIVE, col1a);
- act= saction->action;
- if (!act)
- return;
+ /* get editor data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
- scr_rct.xmin= saction->area->winrct.xmin + saction->v2d.mask.xmin;
- scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin;
- scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
- scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
+ scr_rct.xmin= G.saction->area->winrct.xmin + G.saction->v2d.mask.xmin;
+ scr_rct.ymin= G.saction->area->winrct.ymin + G.saction->v2d.mask.ymin;
+ scr_rct.xmax= G.saction->area->winrct.xmin + G.saction->v2d.hor.xmax;
+ scr_rct.ymax= G.saction->area->winrct.ymin + G.saction->v2d.mask.ymax;
di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
/* if in NLA there's a strip active, map the view */
- if (G.saction->pin==0 && OBACT)
- map_active_strip(di, OBACT, 0);
-
- /* start and end of action itself */
- calc_action_range(act, &sta, &end, 0);
- gla2DDrawTranslatePt(di, sta, 0.0f, &act_start, &dummy);
- gla2DDrawTranslatePt(di, end, 0.0f, &act_end, &dummy);
+ if (datatype == ACTCONT_ACTION) {
+ if (NLA_ACTION_SCALED)
+ map_active_strip(di, OBACT, 0);
+
+ /* start and end of action itself */
+ calc_action_range(data, &sta, &end, 0);
+ gla2DDrawTranslatePt(di, sta, 0.0f, &act_start, &dummy);
+ gla2DDrawTranslatePt(di, end, 0.0f, &act_end, &dummy);
+
+ if (NLA_ACTION_SCALED)
+ map_active_strip(di, OBACT, 1);
+ }
- if (G.saction->pin==0 && OBACT)
- map_active_strip(di, OBACT, 1);
+ /* build list of channels to draw */
+ filter= (ACTFILTER_FORDRAWING|ACTFILTER_VISIBLE|ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
/* first backdrop strips */
y = 0.0;
glEnable(GL_BLEND);
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- int frame1_x, channel_y;
-
- gla2DDrawTranslatePt(di, G.v2d->cur.xmin, y, &frame1_x, &channel_y);
-
- if (SEL_ACHAN(achan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
-
- if (SEL_ACHAN(achan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(act_start, channel_y-CHANNELHEIGHT/2, act_end, channel_y+CHANNELHEIGHT/2);
-
- /* Increment the step */
- y-=CHANNELHEIGHT+CHANNELSKIP;
+ for (ale= act_data.first; ale; ale= ale->next) {
+ int frame1_x, channel_y, sel=0;
+
+ /* determine if any need to draw channel */
+ if (ale->datatype != ALE_NONE) {
+ /* determine if channel is selected */
+ switch (ale->type) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ sel = SEL_AGRP(agrp);
+ }
+ break;
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan = (bActionChannel *)ale->data;
+ sel = SEL_ACHAN(achan);
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan = (bConstraintChannel *)ale->data;
+ sel = SEL_CONCHAN(conchan);
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu = (IpoCurve *)ale->data;
+ sel = SEL_ICU(icu);
+ }
+ break;
+ }
- /* Draw sub channels */
- if (EXPANDED_ACHAN(achan)) {
- /* Draw ipo channels */
- if (achan->ipo) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
-
- if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
-
- if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4);
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
+ if (datatype == ACTCONT_ACTION) {
+ gla2DDrawTranslatePt(di, G.v2d->cur.xmin, y, &frame1_x, &channel_y);
+
+ if (ale->datatype == ALE_GROUP) {
+ if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22);
+ else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22);
}
+ else {
+ if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+ else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+ }
+ glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
- /* Draw constraint channels */
- if (achan->constraintChannels.first) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
-
- if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4);
-
- if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
- else glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4);
-
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
+ if (ale->datatype == ALE_GROUP) {
+ if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22);
+ else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22);
}
+ else {
+ if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+ else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+ }
+ glRectf(act_start, channel_y-CHANNELHEIGHT/2, act_end, channel_y+CHANNELHEIGHT/2);
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+
+ /* all frames that have a frame number less than one
+ * get a desaturated orange background
+ */
+ glColor4ub(col2[0], col2[1], col2[2], 0x22);
+ glRectf(0, channel_y-CHANNELHEIGHT/2, frame1_x, channel_y+CHANNELHEIGHT/2);
+
+ /* frames one and higher get a saturated orange background */
+ glColor4ub(col2[0], col2[1], col2[2], 0x44);
+ glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
}
}
+
+ /* Increment the step */
+ y-=CHANNELHEIGHT+CHANNELSKIP;
}
glDisable(GL_BLEND);
- if (G.saction->pin==0 && OBACT)
+ if (NLA_ACTION_SCALED)
map_active_strip(di, OBACT, 0);
- /* keyframes */
+ /* Draw keyframes
+ * 1) Only channels that are visible in the Action Editor get drawn/evaluated.
+ * This is to try to optimise this for heavier data sets
+ * 2) Keyframes which are out of view horizontally are disregarded
+ */
y = 0.0;
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
-
- draw_ipo_channel(di, achan->ipo, y);
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- /* Draw sub channels */
- if (EXPANDED_ACHAN(achan)) {
- /* Draw ipo curves */
- if (achan->ipo) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- draw_icu_channel(di, icu, y);
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
- }
-
- /* Draw constraint channels */
- if (achan->constraintChannels.first) {
- y-=CHANNELHEIGHT+CHANNELSKIP;
-
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- draw_ipo_channel(di, conchan->ipo, y);
- y-=CHANNELHEIGHT+CHANNELSKIP;
- }
- }
- }
+ for (ale= act_data.first; ale; ale= ale->next) {
+ const float yminc= y-CHANNELHEIGHT/2;
+ const float ymaxc= y+CHANNELHEIGHT/2;
+
+ /* check if visible */
+ if ( IN_RANGE(yminc, G.v2d->cur.ymin, G.v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, G.v2d->cur.ymin, G.v2d->cur.ymax) )
+ {
+ switch (ale->datatype) {
+ case ALE_GROUP:
+ draw_agroup_channel(di, ale->data, y);
+ break;
+ case ALE_IPO:
+ draw_ipo_channel(di, ale->key_data, y);
+ break;
+ case ALE_ICU:
+ draw_icu_channel(di, ale->key_data, y);
+ break;
}
}
+
+ y-=CHANNELHEIGHT+CHANNELSKIP;
}
+
+ /* free tempolary channels used for drawing */
+ BLI_freelistN(&act_data);
- if(saction->flag & SACTION_MOVING) {
+ /* black line marking 'current frame' for Time-Slide transform mode */
+ if (G.saction->flag & SACTION_MOVING) {
int frame1_x, channel_y;
- gla2DDrawTranslatePt(di, saction->timeslide, 0, &frame1_x, &channel_y);
+
+ gla2DDrawTranslatePt(di, G.saction->timeslide, 0, &frame1_x, &channel_y);
cpack(0x0);
+
glBegin(GL_LINES);
glVertex2f(frame1_x, G.v2d->mask.ymin - 100);
glVertex2f(frame1_x, G.v2d->mask.ymax);
@@ -826,58 +890,6 @@ static void draw_channel_strips(SpaceAction *saction)
glaEnd2DDraw(di);
}
-static void draw_mesh_strips(SpaceAction *saction, Key *key)
-{
- /* draw the RVK keyframes */
- rcti scr_rct;
- gla2DDrawInfo *di;
- float y, ybase;
- IpoCurve *icu;
- char col1[3], col2[3];
-
- BIF_GetThemeColor3ubv(TH_SHADE2, col2);
- BIF_GetThemeColor3ubv(TH_HILITE, col1);
-
- if (!key->ipo) return;
-
- scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
- scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin;
- scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
- scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
- di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
-
- ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
-
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- int frame1_x, channel_y;
-
- /* lets not deal with the "speed" Ipo */
- if (icu->adrcode==0) continue;
-
- y = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
- gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
-
- /* all frames that have a frame number less than one
- * get a desaturated orange background
- */
- glEnable(GL_BLEND);
- glColor4ub(col2[0], col2[1], col2[2], 0x22);
- glRectf(0, channel_y-CHANNELHEIGHT/2,
- frame1_x, channel_y+CHANNELHEIGHT/2);
-
- /* frames one and higher get a saturated orange background */
- glColor4ub(col2[0], col2[1], col2[2], 0x44);
- glRectf(frame1_x, channel_y-CHANNELHEIGHT/2,
- G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2);
- glDisable(GL_BLEND);
-
- /* draw the keyframes */
- draw_icu_channel(di, icu, y);
- }
-
- glaEnd2DDraw(di);
-}
-
/* ********* action panel *********** */
@@ -926,62 +938,60 @@ static void action_blockhandlers(ScrArea *sa)
uiDrawBlocksPanels(sa, 0);
}
+/* ************************* Action Editor Space ***************************** */
+
void drawactionspace(ScrArea *sa, void *spacedata)
{
+ bAction *act = NULL;
+ Key *key = NULL;
+ void *data;
+ short datatype;
+
short ofsx = 0, ofsy = 0;
- bAction *act;
- Key *key;
float col[3];
- short maxymin;
- if (!G.saction)
+ /* this is unlikely to occur, but it may */
+ if (G.saction == NULL)
return;
- /* warning; blocks need to be freed each time, handlers dont remove */
+ /* warning: blocks need to be freed each time, handlers dont remove */
uiFreeBlocksWin(&sa->uiblocks, sa->win);
- if (!G.saction->pin) {
- /* allow more than one active action sometime? */
+ /* only try to refresh action that's displayed if not pinned */
+ if (G.saction->pin==0) {
+ /* TODO: allow more than one active action sometime? */
if (OBACT)
G.saction->action = OBACT->action;
else
- G.saction->action=NULL;
+ G.saction->action= NULL;
}
- key = get_action_mesh_key();
- act= G.saction->action;
-
- /* Damn I hate hunting to find my rvk's because
- * they have scrolled off of the screen ... this
- * oughta fix it
- */
- if (!act && key) {
- if (G.v2d->cur.ymin < -CHANNELHEIGHT)
- G.v2d->cur.ymin = -CHANNELHEIGHT;
-
- maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
- if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
- }
-
+ /* get data */
+ data = get_action_context(&datatype);
+ if (datatype == ACTCONT_ACTION)
+ act = data;
+ else if (datatype == ACTCONT_SHAPEKEY)
+ key = data;
+
/* Lets make sure the width of the left hand of the screen
* is set to an appropriate value based on whether sliders
* are showing of not
*/
- if (((key)||(act)) && (G.saction->flag & SACTION_SLIDERS))
+ if ((data) && (G.saction->flag & SACTION_SLIDERS))
ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
else
ACTWIDTH = NAMEWIDTH;
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
- /* background color for entire window (used in lefthand part tho) */
+ /* background color for entire window (used in lefthand part though) */
BIF_GetThemeColor3fv(TH_HEADER, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
- if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ if (curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
if(G.v2d->scroll) {
ofsx= curarea->winrct.xmin;
ofsy= curarea->winrct.ymin;
@@ -1009,15 +1019,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
check_action_context(G.saction);
/* Draw channel strips */
- if (act) {
- draw_channel_strips(G.saction);
- }
- else if (key) {
- /* if there is a mesh with rvk's selected,
- * then draw the key frames in the action window
- */
- draw_mesh_strips(G.saction, key);
- }
+ draw_channel_strips();
/* reset matrices for stuff to be drawn on top of keys*/
glViewport(ofsx+G.v2d->mask.xmin,
@@ -1033,23 +1035,26 @@ void drawactionspace(ScrArea *sa, void *spacedata)
/* Draw current frame */
draw_cfra_action();
- /* Draw markers */
- draw_markers_timespace();
+ /* Draw markers (local behind scene ones, as local obscure scene markers) */
+ if (act)
+ draw_markers_timespace(&act->markers, DRAW_MARKERS_LOCAL);
+ draw_markers_timespace(SCE_MARKERS, 0);
/* Draw 'curtains' for preview */
draw_anim_preview_timespace();
/* Draw scroll */
mywinset(curarea->win); // reset scissor too
- if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
- myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
- if(G.v2d->scroll) drawscroll(0);
+ if (curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
+ myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+ if (G.v2d->scroll) drawscroll(0);
}
- if(G.v2d->mask.xmin!=0) {
+ /* Draw Left-Hand Panel if enough space in window */
+ if (G.v2d->mask.xmin!=0) {
/* Draw channel names */
draw_channel_names();
-
+
if(sa->winx > 50 + NAMEWIDTH + SLIDERWIDTH) {
if (act) {
/* if there is an action, draw sliders for its
@@ -1077,9 +1082,177 @@ void drawactionspace(ScrArea *sa, void *spacedata)
curarea->win_swap= WIN_BACK_OK;
}
-static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos, int totcurve)
+/* *************************** Keyframe Drawing *************************** */
+
+static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
+{
+ /* The equivilant of add_to_cfra_elem except this version
+ * makes ActKeyColumns - one of the two datatypes required
+ * for action editor drawing.
+ */
+ ActKeyColumn *ak, *akn;
+
+ if (ELEM(NULL, keys, bezt)) return;
+
+ /* try to any existing key to replace, or where to insert after */
+ for (ak= keys->last; ak; ak= ak->prev) {
+ /* do because of double keys */
+ if (ak->cfra == bezt->vec[1][0]) {
+ /* set selection status and 'touched' status */
+ if (BEZSELECTED(bezt)) ak->sel = SELECT;
+ ak->modified += 1;
+
+ return;
+ }
+ else if (ak->cfra < bezt->vec[1][0]) break;
+ }
+
+ /* add new block */
+ akn= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+ if (ak) BLI_insertlinkafter(keys, ak, akn);
+ else BLI_addtail(keys, akn);
+
+ akn->cfra= bezt->vec[1][0];
+ akn->modified += 1;
+
+ // TODO: handle type = bezt->h1 or bezt->h2
+ akn->handle_type= 0;
+
+ if (BEZSELECTED(bezt))
+ akn->sel = SELECT;
+ else
+ akn->sel = 0;
+}
+
+static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index)
{
- CfraElem *ce;
+ /* The equivilant of add_to_cfra_elem except this version
+ * makes ActKeyBlocks - one of the two datatypes required
+ * for action editor drawing.
+ */
+ ActKeyBlock *ab, *abn;
+ BezTriple *beztn=NULL, *prev=NULL;
+ BezTriple *bezt;
+ int v;
+
+ /* get beztriples */
+ beztn= (icu->bezt + index);
+
+ /* we need to go through all beztriples, as they may not be in order (i.e. during transform) */
+ for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) {
+ /* skip if beztriple is current */
+ if (v != index) {
+ /* check if beztriple is immediately before */
+ if (beztn->vec[1][0] > bezt->vec[1][0]) {
+ /* check if closer than previous was */
+ if (prev) {
+ if (prev->vec[1][0] < bezt->vec[1][0])
+ prev= bezt;
+ }
+ else {
+ prev= bezt;
+ }
+ }
+ }
+ }
+
+ /* check if block needed - same value(s)?
+ * -> firstly, handles must have same central value as each other
+ * -> secondly, handles which control that section of the curve must be constant
+ */
+ if ((!prev) || (!beztn)) return;
+ if (IS_EQ(beztn->vec[1][1], prev->vec[1][1])==0) return;
+ if (IS_EQ(beztn->vec[1][1], beztn->vec[0][1])==0) return;
+ if (IS_EQ(prev->vec[1][1], prev->vec[2][1])==0) return;
+
+ /* try to find a keyblock that starts on the previous beztriple */
+ for (ab= blocks->last; ab; ab= ab->prev) {
+ /* check if alter existing block or add new block */
+ if (ab->start == prev->vec[1][0]) {
+ /* set selection status and 'touched' status */
+ if (BEZSELECTED(beztn)) ab->sel = SELECT;
+ ab->modified += 1;
+
+ return;
+ }
+ else if (ab->start < prev->vec[1][0]) break;
+ }
+
+ /* add new block */
+ abn= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
+ if (ab) BLI_insertlinkafter(blocks, ab, abn);
+ else BLI_addtail(blocks, abn);
+
+ abn->start= prev->vec[1][0];
+ abn->end= beztn->vec[1][0];
+ abn->val= beztn->vec[1][1];
+
+ if (BEZSELECTED(prev) || BEZSELECTED(beztn))
+ abn->sel = SELECT;
+ else
+ abn->sel = 0;
+ abn->modified = 1;
+}
+
+/* helper function - find actkeycolumn that occurs on cframe */
+static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
+{
+ ActKeyColumn *ak, *ak2;
+
+ if (keys==NULL)
+ return NULL;
+
+ /* search from both ends at the same time, and stop if we find match or if both ends meet */
+ for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
+ /* return whichever end encounters the frame */
+ if (ak->cfra == cframe)
+ return ak;
+ if (ak2->cfra == cframe)
+ return ak2;
+
+ /* no matches on either end, so return NULL */
+ if (ak == ak2)
+ return NULL;
+ }
+
+ return NULL;
+}
+
+#if 0 // disabled, as some intel cards have problems with this
+/* Draw a simple diamond shape with a filled in center (in screen space) */
+static void draw_key_but(int x, int y, short w, short h, int sel)
+{
+ int xmin= x, ymin= y;
+ int xmax= x+w-1, ymax= y+h-1;
+ int xc= (xmin+xmax)/2, yc= (ymin+ymax)/2;
+
+ /* interior - hardcoded colours (for selected and unselected only) */
+ if (sel) glColor3ub(0xF1, 0xCA, 0x13);
+ else glColor3ub(0xE9, 0xE9, 0xE9);
+
+ glBegin(GL_QUADS);
+ glVertex2i(xc, ymin);
+ glVertex2i(xmax, yc);
+ glVertex2i(xc, ymax);
+ glVertex2i(xmin, yc);
+ glEnd();
+
+
+ /* outline */
+ glColor3ub(0, 0, 0);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2i(xc, ymin);
+ glVertex2i(xmax, yc);
+ glVertex2i(xc, ymax);
+ glVertex2i(xmin, yc);
+ glEnd();
+}
+#endif
+
+static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
+{
+ ActKeyColumn *ak;
ActKeyBlock *ab;
glEnable(GL_BLEND);
@@ -1087,8 +1260,22 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
/* draw keyblocks */
if (blocks) {
for (ab= blocks->first; ab; ab= ab->next) {
- /* only draw keyblock if it appears in all curves sampled */
- if (ab->totcurve == totcurve) {
+ short startCurves, endCurves, totCurves;
+
+ /* find out how many curves occur at each keyframe */
+ ak= cfra_find_actkeycolumn(keys, ab->start);
+ startCurves = (ak)? ak->totcurve: 0;
+
+ ak= cfra_find_actkeycolumn(keys, ab->end);
+ endCurves = (ak)? ak->totcurve: 0;
+
+ /* only draw keyblock if it appears in at all of the keyframes at lowest end */
+ if (!startCurves && !endCurves)
+ continue;
+ else
+ totCurves = (startCurves>endCurves)? endCurves: startCurves;
+
+ if (ab->totcurve >= totCurves) {
int sc_xa, sc_ya;
int sc_xb, sc_yb;
@@ -1097,7 +1284,7 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
gla2DDrawTranslatePt(di, ab->end, ypos, &sc_xb, &sc_yb);
/* draw block */
- if (ab->sel & 1)
+ if (ab->sel)
BIF_ThemeColor4(TH_STRIP_SELECT);
else
BIF_ThemeColor4(TH_STRIP);
@@ -1108,28 +1295,56 @@ static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, fl
/* draw keys */
if (keys) {
- for (ce= keys->first; ce; ce= ce->next) {
+ for (ak= keys->first; ak; ak= ak->next) {
int sc_x, sc_y;
/* get co-ordinate to draw at */
- gla2DDrawTranslatePt(di, ce->cfra, ypos, &sc_x, &sc_y);
+ gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
- if(ce->sel & 1) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f);
+ /* draw using icons - old way which is slower but more proven */
+ if(ak->sel & SELECT) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f);
else BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE3, 1.0f);
+
+ /* draw using OpenGL - slightly uglier but faster */
+ // NOTE: disabled for now, as some intel cards seem to have problems with this
+ //draw_key_but(sc_x-5, sc_y-4, 11, 11, (ak->sel & SELECT));
}
}
glDisable(GL_BLEND);
}
+
+static ActKeysInc *init_aki_data()
+{
+ static ActKeysInc aki;
+
+ /* init data of static struct here */
+ if ((curarea->spacetype == SPACE_ACTION) && NLA_ACTION_SCALED)
+ aki.ob= OBACT;
+ else if (curarea->spacetype == SPACE_NLA)
+ aki.ob= NULL; // FIXME
+ else
+ aki.ob= NULL;
+
+ aki.start= G.v2d->cur.xmin - 10;
+ aki.end= G.v2d->cur.xmax + 10;
+
+ /* only pass pointer for Action Editor if enabled (for now) */
+ if ((curarea->spacetype == SPACE_ACTION) && (G.saction->flag & SACTION_HORIZOPTIMISEON))
+ return &aki;
+ else
+ return NULL;
+}
+
void draw_object_channel(gla2DDrawInfo *di, Object *ob, float ypos)
{
ListBase keys = {0, 0};
ListBase blocks = {0, 0};
- int totcurve;
+ ActKeysInc *aki = init_aki_data();
- totcurve= ob_to_keylist(ob, &keys, &blocks);
- draw_keylist(di, &keys, &blocks, ypos, totcurve);
+ ob_to_keylist(ob, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
BLI_freelistN(&keys);
BLI_freelistN(&blocks);
@@ -1139,10 +1354,10 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, float ypos)
{
ListBase keys = {0, 0};
ListBase blocks = {0, 0};
- int totcurve;
+ ActKeysInc *aki = init_aki_data();
- totcurve= ipo_to_keylist(ipo, &keys, &blocks);
- draw_keylist(di, &keys, &blocks, ypos, totcurve);
+ ipo_to_keylist(ipo, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
BLI_freelistN(&keys);
BLI_freelistN(&blocks);
@@ -1152,129 +1367,81 @@ void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, float ypos)
{
ListBase keys = {0, 0};
ListBase blocks = {0, 0};
+ ActKeysInc *aki = init_aki_data();
- icu_to_keylist(icu, &keys, &blocks);
- draw_keylist(di, &keys, &blocks, ypos, 1);
+ icu_to_keylist(icu, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
BLI_freelistN(&keys);
BLI_freelistN(&blocks);
}
-void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos)
+void draw_agroup_channel(gla2DDrawInfo *di, bActionGroup *agrp, float ypos)
{
ListBase keys = {0, 0};
+ ListBase blocks = {0, 0};
+ ActKeysInc *aki = init_aki_data();
- action_to_keylist(act, &keys, NULL);
- draw_keylist(di, &keys, NULL, ypos, 0);
+ agroup_to_keylist(agrp, &keys, &blocks, aki);
+ draw_keylist(di, &keys, &blocks, ypos);
BLI_freelistN(&keys);
+ BLI_freelistN(&blocks);
}
-static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index)
+void draw_action_channel(gla2DDrawInfo *di, bAction *act, float ypos)
{
- /* The equivilant of add_to_cfra_elem except this version
- * makes ActKeyBlocks - one of the two datatypes required
- * for action editor drawing.
- */
- ActKeyBlock *ab, *abn;
- BezTriple *beztn=NULL, *prev=NULL;
- BezTriple *bezt;
- int v;
-
- /* get beztriples */
- beztn= (icu->bezt + index);
- /* The following search for previous beztriple doesn't work
- * that great on actions with a large amount of keys. There
- * are a few commented out shortcuts for these cases, which will
- * remain so until the definitive point where slowdown starts to
- * bite is determined.
- */
- //if (icu->totvert > 3500) {
- // if (index >= 1)
- // prev= (icu->bezt + (index - 1));
- //}
- //else {
- for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) {
- /* skip if beztriple is current */
- if (v != index) {
- /* check if beztriple is immediately before */
- if (beztn->vec[1][0] > bezt->vec[1][0]) {
- /* check if closer than previous was */
- if (prev) {
- if (prev->vec[1][0] < bezt->vec[1][0])
- prev= bezt;
- }
- else {
- prev= bezt;
- }
- }
- }
- }
- //}
-
- /* check if block needed - same value? */
- if ((!prev) || (!beztn))
- return;
- if (beztn->vec[1][1] != prev->vec[1][1])
- return;
-
- /* try to find a keyblock that starts on the previous beztriple */
- for (ab= blocks->first; ab; ab= ab->next) {
- /* check if alter existing block or add new block */
- if (ab->start == prev->vec[1][0]) {
- /* set selection status and 'touched' status */
- if (BEZSELECTED(beztn)) ab->sel = SELECT;
- ab->modified += 1;
-
- return;
- }
- else if (ab->start > prev->vec[1][0]) break;
- }
-
- /* add new block */
- abn= MEM_callocN(sizeof(ActKeyBlock), "add_bezt_to_keyblockslist");
- if (ab) BLI_insertlinkbefore(blocks, ab, abn);
- else BLI_addtail(blocks, abn);
-
- abn->start= prev->vec[1][0];
- abn->end= beztn->vec[1][0];
- abn->val= beztn->vec[1][1];
-
- if (BEZSELECTED(prev) || BEZSELECTED(beztn))
- abn->sel = SELECT;
- else
- abn->sel = 0;
- abn->modified += 1;
+ ListBase keys = {0, 0};
+ ActKeysInc *aki = init_aki_data();
+
+ action_to_keylist(act, &keys, NULL, aki);
+ draw_keylist(di, &keys, NULL, ypos);
+ BLI_freelistN(&keys);
}
-int ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks)
+/* --------------- Conversion: data -> keyframe list ------------------ */
+
+void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
{
bConstraintChannel *conchan;
- int totcurve = 0;
if (ob) {
/* Add object keyframes */
- if (ob->ipo) {
- totcurve += ipo_to_keylist(ob->ipo, keys, blocks);
- }
+ if (ob->ipo)
+ ipo_to_keylist(ob->ipo, keys, blocks, aki);
/* Add constraint keyframes */
- for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next){
- if(conchan->ipo) {
- totcurve += ipo_to_keylist(conchan->ipo, keys, blocks);
- }
+ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
}
/* Add object data keyframes */
// TODO??
}
-
- return totcurve;
}
-void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks)
+static short bezt_in_aki_range (ActKeysInc *aki, BezTriple *bezt)
+{
+ /* when aki == NULL, we don't care about range */
+ if (aki == NULL)
+ return 1;
+
+ /* if nla-scaling is in effect, apply appropriate scaling adjustments */
+ if (aki->ob) {
+ float frame= get_action_frame_inv(aki->ob, bezt->vec[1][0]);
+ return IN_RANGE(frame, aki->start, aki->end);
+ }
+ else {
+ /* check if in range */
+ return IN_RANGE(bezt->vec[1][0], aki->start, aki->end);
+ }
+}
+
+void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
{
BezTriple *bezt;
- ActKeyBlock *ab, *abn;
+ ActKeyColumn *ak, *ak2;
+ ActKeyBlock *ab, *ab2;
int v;
if (icu && icu->totvert) {
@@ -1282,62 +1449,96 @@ void icu_to_keylist(IpoCurve *icu, ListBase *keys, ListBase *blocks)
bezt= icu->bezt;
for (v=0; v<icu->totvert; v++, bezt++) {
- add_to_cfra_elem(keys, bezt);
- if (blocks) add_bezt_to_keyblockslist(blocks, icu, v);
+ /* only if keyframe is in range (optimisation) */
+ if (bezt_in_aki_range(aki, bezt)) {
+ add_bezt_to_keycolumnslist(keys, bezt);
+ if (blocks) add_bezt_to_keyblockslist(blocks, icu, v);
+ }
}
- /* update the number of curves the blocks have appeared in */
- if (blocks) {
- for (ab= blocks->first; ab; ab= abn) {
- abn= ab->next;
+ /* update the number of curves that elements have appeared in */
+ if (keys) {
+ for (ak=keys->first, ak2=keys->last; ak && ak2; ak=ak->next, ak2=ak2->prev) {
+ if (ak->modified) {
+ ak->modified = 0;
+ ak->totcurve += 1;
+ }
+ if (ak2->modified) {
+ ak2->modified = 0;
+ ak2->totcurve += 1;
+ }
+ if (ak == ak2)
+ break;
+ }
+ }
+ if (blocks) {
+ for (ab=blocks->first, ab2=blocks->last; ab && ab2; ab=ab->next, ab2=ab2->prev) {
if (ab->modified) {
ab->modified = 0;
ab->totcurve += 1;
}
+ if (ab2->modified) {
+ ab2->modified = 0;
+ ab2->totcurve += 1;
+ }
+
+ if (ab == ab2)
+ break;
}
}
}
}
-int ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks)
+void ipo_to_keylist(Ipo *ipo, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
{
IpoCurve *icu;
- int totcurve = 0;
if (ipo) {
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- icu_to_keylist(icu, keys, blocks);
- totcurve++;
+ for (icu= ipo->curve.first; icu; icu= icu->next)
+ icu_to_keylist(icu, keys, blocks, aki);
+ }
+}
+
+void agroup_to_keylist(bActionGroup *agrp, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
+{
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ if (agrp) {
+ /* loop through action channels */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ /* firstly, add keys from action channel's ipo block */
+ if (achan->ipo)
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
+
+ /* then, add keys from constraint channels */
+ for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
+ }
}
}
-
- return totcurve;
}
-int action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks)
+void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks, ActKeysInc *aki)
{
bActionChannel *achan;
bConstraintChannel *conchan;
- int totcurve = 0;
if (act) {
/* loop through action channels */
for (achan= act->chanbase.first; achan; achan= achan->next) {
/* firstly, add keys from action channel's ipo block */
- if (achan->ipo) {
- totcurve+= ipo_to_keylist(achan->ipo, keys, blocks);
- }
+ if (achan->ipo)
+ ipo_to_keylist(achan->ipo, keys, blocks, aki);
/* then, add keys from constraint channels */
for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (conchan->ipo) {
- totcurve+= ipo_to_keylist(achan->ipo, keys, blocks);
- }
+ if (conchan->ipo)
+ ipo_to_keylist(conchan->ipo, keys, blocks, aki);
}
}
}
-
- return totcurve;
}
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c
index dfcaefd03ff..9b8905b782b 100644
--- a/source/blender/src/drawarmature.c
+++ b/source/blender/src/drawarmature.c
@@ -49,6 +49,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -86,6 +87,227 @@
#include "blendef.h"
#include "nla.h"
+
+/* *************** Armature Drawing - Coloring API ***************************** */
+
+/* global here is reset before drawing each bone */
+static ThemeWireColor *bcolor= NULL;
+
+/* values of colCode for set_pchan_glcolor */
+enum {
+ PCHAN_COLOR_NORMAL = 0, /* normal drawing */
+ PCHAN_COLOR_SOLID, /* specific case where "solid" colour is needed */
+ PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
+
+ PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */
+ PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */
+ PCHAN_COLOR_LINEBONE /* for the middle of line-bones */
+};
+
+/* This function sets the color-set for coloring a certain bone */
+static void set_pchan_colorset (Object *ob, bPoseChannel *pchan)
+{
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bArmature *arm= (ob) ? ob->data : NULL;
+ bActionGroup *grp= NULL;
+ short color_index= 0;
+
+ /* sanity check */
+ if (ELEM4(NULL, ob, arm, pose, pchan)) {
+ bcolor= NULL;
+ return;
+ }
+
+ /* only try to set custom color if enabled for armature */
+ if (arm->flag & ARM_COL_CUSTOM) {
+ /* currently, a bone can only use a custom color set if it's group (if it has one),
+ * has been set to use one
+ */
+ if (pchan->agrp_index) {
+ grp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+ if (grp)
+ color_index= grp->customCol;
+ }
+ }
+
+ /* bcolor is a pointer to the color set to use. If NULL, then the default
+ * color set (based on the theme colors for 3d-view) is used.
+ */
+ if (color_index > 0) {
+ bTheme *btheme= U.themes.first;
+ bcolor= &btheme->tarm[(color_index - 1)];
+ }
+ else if (color_index == -1) {
+ /* use the group's own custom color set */
+ bcolor= (grp)? &grp->cs : NULL;
+ }
+ else
+ bcolor= NULL;
+}
+
+/* This function is for brightening/darkening a given color (like BIF_ThemeColorShade()) */
+static void cp_shade_color3ub (char cp[], int offset)
+{
+ int r, g, b;
+
+ r= offset + (int) cp[0];
+ CLAMP(r, 0, 255);
+ g= offset + (int) cp[1];
+ CLAMP(g, 0, 255);
+ b= offset + (int) cp[2];
+ CLAMP(b, 0, 255);
+
+ cp[0]= r;
+ cp[1]= g;
+ cp[2]= b;
+}
+
+/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
+static short set_pchan_glColor (short colCode, int armflag, int boneflag, int constflag)
+{
+ switch (colCode) {
+ case PCHAN_COLOR_NORMAL:
+ {
+ if (bcolor) {
+ char cp[3];
+
+ if (boneflag & BONE_ACTIVE) {
+ VECCOPY(cp, bcolor->active);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ VECCOPY(cp, bcolor->select);
+ }
+ else {
+ /* a bit darker than solid */
+ VECCOPY(cp, bcolor->solid);
+ cp_shade_color3ub(cp, -50);
+ }
+
+ glColor3ub(cp[0], cp[1], cp[2]);
+ }
+ else {
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+ else BIF_ThemeColor(TH_WIRE);
+ }
+
+ return 1;
+ }
+ break;
+
+ case PCHAN_COLOR_SOLID:
+ {
+ if (bcolor) {
+ char *cp= bcolor->solid;
+ glColor3ub(cp[0], cp[1], cp[2]);
+ }
+ else
+ BIF_ThemeColor(TH_BONE_SOLID);
+
+ return 1;
+ }
+ break;
+
+ case PCHAN_COLOR_CONSTS:
+ {
+ if ( (bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS) ) {
+ if (constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
+ else if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
+ else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
+ else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
+ else if (constflag) BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION
+
+ return 1;
+ }
+ else
+ return 0;
+ }
+ break;
+
+ case PCHAN_COLOR_SPHEREBONE_BASE:
+ {
+ if (bcolor) {
+ char cp[3];
+
+ if (boneflag & BONE_ACTIVE) {
+ VECCOPY(cp, bcolor->active);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ VECCOPY(cp, bcolor->select);
+ }
+ else {
+ VECCOPY(cp, bcolor->solid);
+ }
+
+ glColor3ub(cp[0], cp[1], cp[2]);
+ }
+ else {
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+ else BIF_ThemeColor(TH_BONE_SOLID);
+ }
+
+ return 1;
+ }
+ break;
+ case PCHAN_COLOR_SPHEREBONE_END:
+ {
+ if (bcolor) {
+ char cp[3];
+
+ if (boneflag & BONE_ACTIVE) {
+ VECCOPY(cp, bcolor->active);
+ cp_shade_color3ub(cp, 10);
+ }
+ else if (boneflag & BONE_SELECTED) {
+ VECCOPY(cp, bcolor->select);
+ cp_shade_color3ub(cp, -30);
+ }
+ else {
+ VECCOPY(cp, bcolor->solid);
+ cp_shade_color3ub(cp, -30);
+ }
+
+ glColor3ub(cp[0], cp[1], cp[2]);
+ }
+ else {
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
+ else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+ }
+ }
+ break;
+
+ case PCHAN_COLOR_LINEBONE:
+ {
+ /* inner part in background color or constraint */
+ if ( (constflag) && ((bcolor==NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) ) {
+ if (constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
+ else if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
+ else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
+ else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
+ else if (constflag) BIF_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */
+ }
+ else {
+ if (bcolor) {
+ char *cp= bcolor->solid;
+ glColor4ub(cp[0], cp[1], cp[2], 0.8);
+ }
+ else
+ BIF_ThemeColorShade(TH_BACK, -30);
+ }
+
+ return 1;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+
+/* *************** Armature drawing, helper calls for parts ******************* */
+
/* half the cube, in Y */
static float cube[8][3] = {
{-1.0, 0.0, -1.0},
@@ -98,81 +320,76 @@ static float cube[8][3] = {
{ 1.0, 1.0, -1.0},
};
-
-/* *************** Armature drawing, helper calls for parts ******************* */
-
static void drawsolidcube_size(float xsize, float ysize, float zsize)
{
+ static GLuint displist=0;
float n[3];
glScalef(xsize, ysize, zsize);
n[0]=0; n[1]=0; n[2]=0;
- glBegin(GL_QUADS);
- n[0]= -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
- n[0]=0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[1]= -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
- n[1]=0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[0]= 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
- n[0]=0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[1]= 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
- n[1]=0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[2]= 1.0;
- glNormal3fv(n);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
- n[2]=0;
- glEnd();
-
- glBegin(GL_QUADS);
- n[2]= -1.0;
- glNormal3fv(n);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
- glEnd();
+
+ if(displist==0) {
+ displist= glGenLists(1);
+ glNewList(displist, GL_COMPILE_AND_EXECUTE);
+
+ glBegin(GL_QUADS);
+ n[0]= -1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
+ n[0]=0;
+ n[1]= -1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
+ n[1]=0;
+ n[0]= 1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
+ n[0]=0;
+ n[1]= 1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
+ n[1]=0;
+ n[2]= 1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
+ n[2]=0;
+ n[2]= -1.0;
+ glNormal3fv(n);
+ glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
+ glEnd();
+
+ glEndList();
+ }
+ else glCallList(displist);
}
static void drawcube_size(float xsize, float ysize, float zsize)
{
+ static GLuint displist=0;
glScalef(xsize, ysize, zsize);
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
- glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
- glVertex3fv(cube[7]); glVertex3fv(cube[4]);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[1]); glVertex3fv(cube[5]);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[2]); glVertex3fv(cube[6]);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex3fv(cube[3]); glVertex3fv(cube[7]);
- glEnd();
+ if(displist == 0) {
+ displist= glGenLists(1);
+ glNewList(displist, GL_COMPILE_AND_EXECUTE);
+
+ glBegin(GL_LINE_STRIP);
+ glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
+ glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
+ glVertex3fv(cube[7]); glVertex3fv(cube[4]);
+ glEnd();
+
+ glBegin(GL_LINES);
+ glVertex3fv(cube[1]); glVertex3fv(cube[5]);
+ glVertex3fv(cube[2]); glVertex3fv(cube[6]);
+ glVertex3fv(cube[3]); glVertex3fv(cube[7]);
+ glEnd();
+
+ glEndList();
+ }
+ else glCallList(displist);
}
@@ -181,37 +398,38 @@ static void draw_bonevert(void)
{
static GLuint displist=0;
- if(displist==0) {
+ if (displist == 0) {
GLUquadricObj *qobj;
displist= glGenLists(1);
glNewList(displist, GL_COMPILE_AND_EXECUTE);
-
+
glPushMatrix();
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
- gluDisk( qobj, 0.0, 0.05, 16, 1);
+ gluDisk(qobj, 0.0, 0.05, 16, 1);
- glRotatef (90, 0, 1, 0);
- gluDisk( qobj, 0.0, 0.05, 16, 1);
+ glRotatef(90, 0, 1, 0);
+ gluDisk(qobj, 0.0, 0.05, 16, 1);
- glRotatef (90, 1, 0, 0);
- gluDisk( qobj, 0.0, 0.05, 16, 1);
+ glRotatef(90, 1, 0, 0);
+ gluDisk(qobj, 0.0, 0.05, 16, 1);
gluDeleteQuadric(qobj);
glPopMatrix();
glEndList();
}
- else glCallList(displist);
+ else
+ glCallList(displist);
}
static void draw_bonevert_solid(void)
{
static GLuint displist=0;
- if(displist==0) {
+ if (displist == 0) {
GLUquadricObj *qobj;
displist= glGenLists(1);
@@ -226,19 +444,20 @@ static void draw_bonevert_solid(void)
glEndList();
}
- else glCallList(displist);
+ else
+ glCallList(displist);
}
static void draw_bone_octahedral()
{
static GLuint displist=0;
- if(displist==0) {
+ if (displist == 0) {
float vec[6][3];
displist= glGenLists(1);
glNewList(displist, GL_COMPILE_AND_EXECUTE);
-
+
vec[0][0]= vec[0][1]= vec[0][2]= 0.0;
vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0;
@@ -269,14 +488,15 @@ static void draw_bone_octahedral()
glEndList();
}
- else glCallList(displist);
+ else
+ glCallList(displist);
}
static void draw_bone_solid_octahedral(void)
{
static GLuint displist=0;
- if(displist==0) {
+ if (displist == 0) {
float vec[6][3], nor[3];
displist= glGenLists(1);
@@ -330,7 +550,8 @@ static void draw_bone_solid_octahedral(void)
glEndList();
}
- else glCallList(displist);
+ else
+ glCallList(displist);
}
/* *************** Armature drawing, bones ******************* */
@@ -339,40 +560,51 @@ static void draw_bone_solid_octahedral(void)
static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id)
{
/* Draw root point if we are not connected */
- if (!(boneflag & BONE_CONNECTED)){
+ if ((boneflag & BONE_CONNECTED)==0) {
if (id != -1)
- glLoadName (id | BONESEL_ROOT);
+ glLoadName(id | BONESEL_ROOT);
- if(dt<=OB_WIRE) {
- if(armflag & ARM_EDITMODE) {
+ if(dt <= OB_WIRE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
}
- else
- BIF_ThemeColor(TH_BONE_SOLID);
+ else {
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
+ else
+ BIF_ThemeColor(TH_BONE_SOLID);
+ }
- if(dt>OB_WIRE) draw_bonevert_solid();
- else draw_bonevert();
+ if (dt > OB_WIRE)
+ draw_bonevert_solid();
+ else
+ draw_bonevert();
}
/* Draw tip point */
if (id != -1)
- glLoadName (id | BONESEL_TIP);
+ glLoadName(id | BONESEL_TIP);
- if(dt<=OB_WIRE) {
- if(armflag & ARM_EDITMODE) {
+ if (dt <= OB_WIRE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
}
else {
- BIF_ThemeColor(TH_BONE_SOLID);
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, 0);
+ else
+ BIF_ThemeColor(TH_BONE_SOLID);
}
glTranslatef(0.0, 1.0, 0.0);
- if(dt>OB_WIRE) draw_bonevert_solid();
- else draw_bonevert();
+ if (dt > OB_WIRE)
+ draw_bonevert_solid();
+ else
+ draw_bonevert();
glTranslatef(0.0, -1.0, 0.0);
}
@@ -411,7 +643,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
float *headvec, *tailvec, dirvec[3];
/* figure out the sizes of spheres */
- if(ebone) {
+ if (ebone) {
/* this routine doesn't call set_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
@@ -447,7 +679,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
/* move vector back */
Mat4Mul3Vecfl(imat, dirvec);
- if(0.0f != Normalize(dirvec)) {
+ if (0.0f != Normalize(dirvec)) {
float norvec[3], vec1[3], vec2[3], vec[3];
int a;
@@ -455,8 +687,8 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
Crossf(norvec, dirvec, imat[2]);
glBegin(GL_QUAD_STRIP);
-
- for(a=0; a<16; a++) {
+
+ for (a=0; a<16; a++) {
vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0];
vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1];
vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2];
@@ -474,7 +706,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
glVertex3fv(vec2);
}
- for(a=15; a>=0; a--) {
+ for (a=15; a>=0; a--) {
vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0];
vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1];
vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2];
@@ -521,10 +753,10 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
float *headvec, *tailvec, dirvec[3];
/* figure out the sizes of spheres */
- if(ebone) {
+ if (ebone) {
/* this routine doesn't call set_matrix_editbone() that calculates it */
ebone->length = VecLenf(ebone->head, ebone->tail);
-
+
length= ebone->length;
tail= ebone->rad_tail;
if (ebone->parent && (boneflag & BONE_CONNECTED))
@@ -537,7 +769,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
else {
length= pchan->bone->length;
tail= pchan->bone->rad_tail;
- if (pchan->parent && (boneflag & BONE_CONNECTED))
+ if ((pchan->parent) && (boneflag & BONE_CONNECTED))
head= pchan->parent->bone->rad_tail;
else
head= pchan->bone->rad_head;
@@ -546,38 +778,34 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
}
/* sphere root color */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
- else if(armflag & ARM_POSEMODE) {
- /* in black or selection color */
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
- }
+ else if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
/* Draw root point if we are not connected */
- if (!(boneflag & BONE_CONNECTED)){
+ if ((boneflag & BONE_CONNECTED)==0) {
if (id != -1)
- glLoadName (id | BONESEL_ROOT);
+ glLoadName(id | BONESEL_ROOT);
drawcircball(GL_LINE_LOOP, headvec, head, imat);
}
/* Draw tip point */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
if (id != -1)
- glLoadName (id | BONESEL_TIP);
+ glLoadName(id | BONESEL_TIP);
drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
/* base */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
else BIF_ThemeColor(TH_WIRE);
}
@@ -591,7 +819,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
/* move vector back */
Mat4Mul3Vecfl(imat, dirvec);
- if(0.0f != Normalize(dirvec)) {
+ if (0.0f != Normalize(dirvec)) {
float norvech[3], norvect[3], vec[3];
VECCOPY(vec, dirvec);
@@ -603,8 +831,8 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
Crossf(norvect, vec, imat[2]);
if (id != -1)
- glLoadName (id | BONESEL_BONE);
-
+ glLoadName(id | BONESEL_BONE);
+
glBegin(GL_LINES);
vec[0]= headvec[0] + norvech[0];
vec[1]= headvec[1] + norvech[1];
@@ -638,7 +866,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
qobj = gluNewQuadric();
/* figure out the sizes of spheres */
- if(ebone) {
+ if (ebone) {
length= ebone->length;
tail= ebone->rad_tail;
if (ebone->parent && (boneflag & BONE_CONNECTED))
@@ -656,9 +884,9 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
}
/* move to z-axis space */
- glRotatef (-90.0f, 1.0f, 0.0f, 0.0f);
+ glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
- if(dt==OB_SOLID) {
+ if (dt==OB_SOLID) {
/* set up solid drawing */
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
@@ -671,57 +899,49 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
}
/* sphere root color */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
}
- else if(armflag & ARM_POSEMODE) {
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
- else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
-
- }
- else if(dt==OB_SOLID)
+ else if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, armflag, boneflag, constflag);
+ else if (dt==OB_SOLID)
BIF_ThemeColorShade(TH_BONE_SOLID, -30);
/* Draw root point if we are not connected */
- if (!(boneflag & BONE_CONNECTED)){
+ if ((boneflag & BONE_CONNECTED)==0) {
if (id != -1)
- glLoadName (id | BONESEL_ROOT);
- gluSphere( qobj, head, 16, 10);
+ glLoadName(id | BONESEL_ROOT);
+ gluSphere(qobj, head, 16, 10);
}
/* Draw tip point */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
}
if (id != -1)
- glLoadName (id | BONESEL_TIP);
+ glLoadName(id | BONESEL_TIP);
glTranslatef(0.0, 0.0, length);
- gluSphere( qobj, tail, 16, 10);
+ gluSphere(qobj, tail, 16, 10);
glTranslatef(0.0, 0.0, -length);
/* base */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
else BIF_ThemeColor(TH_BONE_SOLID);
}
- else if(armflag & ARM_POSEMODE) {
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_BONE_SOLID);
-
- }
- else if(dt==OB_SOLID)
+ else if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, armflag, boneflag, constflag);
+ else if (dt == OB_SOLID)
BIF_ThemeColor(TH_BONE_SOLID);
fac1= (length-head)/length;
fac2= (length-tail)/length;
- if(length > head+tail) {
+ if (length > (head+tail)) {
if (id != -1)
glLoadName (id | BONESEL_BONE);
@@ -731,25 +951,25 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
glTranslatef(0.0f, 0.0f, head);
gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1);
glTranslatef(0.0f, 0.0f, -head);
-
+
glDisable(GL_POLYGON_OFFSET_FILL);
/* draw sphere on extrema */
glTranslatef(0.0f, 0.0f, length-tail);
- gluSphere( qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
+ gluSphere(qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
glTranslatef(0.0f, 0.0f, -length+tail);
-
+
glTranslatef(0.0f, 0.0f, head);
- gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+ gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
}
else {
/* 1 sphere in center */
glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0);
- gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+ gluSphere(qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
}
/* restore */
- if(dt==OB_SOLID) {
+ if (dt==OB_SOLID) {
glShadeModel(GL_FLAT);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
@@ -772,7 +992,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if(pchan)
+ if (pchan)
length= pchan->bone->length;
else
length= ebone->length;
@@ -781,20 +1001,16 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
glScalef(length, length, length);
/* this chunk not in object mode */
- if(armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
+ if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
glLineWidth(4.0);
- if(armflag & ARM_POSEMODE) {
- /* outline in black or selection color */
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
- }
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
else if (armflag & ARM_EDITMODE) {
BIF_ThemeColor(TH_WIRE);
}
/* Draw root point if we are not connected */
- if (!(boneflag & BONE_CONNECTED)){
+ if ((boneflag & BONE_CONNECTED)==0) {
if (G.f & G_PICKSEL) { // no bitmap in selection mode, crashes 3d cards...
glLoadName (id | BONESEL_ROOT);
glBegin(GL_POINTS);
@@ -808,7 +1024,7 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
}
if (id != -1)
- glLoadName ((GLuint) id|BONESEL_BONE);
+ glLoadName((GLuint) id|BONESEL_BONE);
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f);
@@ -816,8 +1032,9 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
glEnd();
/* tip */
- if (G.f & G_PICKSEL) { // no bitmap in selection mode, crashes 3d cards...
- glLoadName (id | BONESEL_TIP);
+ if (G.f & G_PICKSEL) {
+ /* no bitmap in selection mode, crashes 3d cards... */
+ glLoadName(id | BONESEL_TIP);
glBegin(GL_POINTS);
glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();
@@ -829,27 +1046,19 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
/* further we send no names */
if (id != -1)
- glLoadName (id & 0xFFFF); // object tag, for bordersel optim
-
- if(armflag & ARM_POSEMODE) {
- /* inner part in background color or constraint */
- if(constflag) {
- if(constflag & PCHAN_HAS_STRIDE) glColor3ub(0, 0, 200);
- else if(constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
- else if(constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
- else if(constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
- else BIF_ThemeColor(TH_BONE_POSE); // PCHAN_HAS_ACTION
- }
- else BIF_ThemeColorShade(TH_BACK, -30);
- }
+ glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */
+
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_LINEBONE, armflag, boneflag, constflag);
}
glLineWidth(2.0);
- /* Draw root point if we are not connected */
- if (!(boneflag & BONE_CONNECTED)){
- if ((G.f & G_PICKSEL)==0) { // no bitmap in selection mode, crashes 3d cards...
- if(armflag & ARM_EDITMODE) {
+ /*Draw root point if we are not connected */
+ if ((boneflag & BONE_CONNECTED)==0) {
+ if ((G.f & G_PICKSEL)==0) {
+ /* no bitmap in selection mode, crashes 3d cards... */
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
@@ -858,18 +1067,19 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
}
}
- if(armflag & ARM_EDITMODE) {
- if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT);
- else BIF_ThemeColorShade(TH_BACK, -30);
- }
+ if (armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_EDGE_SELECT);
+ else BIF_ThemeColorShade(TH_BACK, -30);
+ }
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();
/* tip */
- if ((G.f & G_PICKSEL)==0) { // no bitmap in selection mode, crashes 3d cards...
- if(armflag & ARM_EDITMODE) {
+ if ((G.f & G_PICKSEL)==0) {
+ /* no bitmap in selection mode, crashes 3d cards... */
+ if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
else BIF_ThemeColor(TH_VERTEX);
}
@@ -886,24 +1096,25 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l
{
int segments= 0;
- if(pchan) segments= pchan->bone->segments;
+ if (pchan)
+ segments= pchan->bone->segments;
- if(segments>1 && pchan) {
+ if ((segments > 1) && (pchan)) {
float dlen= length/(float)segments;
- Mat4 *bbone= b_bone_spline_setup(pchan);
+ Mat4 *bbone= b_bone_spline_setup(pchan, 0);
int a;
- for(a=0; a<segments; a++, bbone++) {
+ for (a=0; a<segments; a++, bbone++) {
glPushMatrix();
glMultMatrixf(bbone->mat);
- if(dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
+ if (dt==OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
else drawcube_size(xwidth, dlen, zwidth);
glPopMatrix();
}
}
else {
glPushMatrix();
- if(dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
+ if (dt==OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
else drawcube_size(xwidth, length, zwidth);
glPopMatrix();
}
@@ -913,7 +1124,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
{
float xwidth, length, zwidth;
- if(pchan) {
+ if (pchan) {
xwidth= pchan->bone->xwidth;
length= pchan->bone->length;
zwidth= pchan->bone->zwidth;
@@ -925,7 +1136,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
}
/* draw points only if... */
- if(armflag & ARM_EDITMODE) {
+ if (armflag & ARM_EDITMODE) {
/* move to unitspace */
glPushMatrix();
glScalef(length, length, length);
@@ -936,16 +1147,13 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
/* colors for modes */
if (armflag & ARM_POSEMODE) {
- if(dt==OB_WIRE) {
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
- }
+ if (dt <= OB_WIRE)
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
else
- BIF_ThemeColor(TH_BONE_SOLID);
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
}
else if (armflag & ARM_EDITMODE) {
- if(dt==OB_WIRE) {
+ if (dt==OB_WIRE) {
if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
else BIF_ThemeColor(TH_WIRE);
@@ -959,10 +1167,14 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
}
/* set up solid drawing */
- if(dt > OB_WIRE) {
+ if (dt > OB_WIRE) {
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
- BIF_ThemeColor(TH_BONE_SOLID);
+
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
+ else
+ BIF_ThemeColor(TH_BONE_SOLID);
draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
@@ -970,25 +1182,21 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
}
- else { // wire
- if (armflag & ARM_POSEMODE){
- if(constflag) {
- glEnable(GL_BLEND);
-
- if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
- else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
- else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
- else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
- else BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION
-
- draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
-
- glDisable(GL_BLEND);
+ else {
+ /* wire */
+ if (armflag & ARM_POSEMODE) {
+ if (constflag) {
+ /* set constraint colours */
+ if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {
+ glEnable(GL_BLEND);
+
+ draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
+
+ glDisable(GL_BLEND);
+ }
/* restore colors */
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
}
}
@@ -1005,7 +1213,7 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
glScalef(length, length, length);
/* set up solid drawing */
- if(dt > OB_WIRE) {
+ if (dt > OB_WIRE) {
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
BIF_ThemeColor(TH_BONE_SOLID);
@@ -1013,61 +1221,56 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
- if(dt==OB_WIRE) {
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
- }
+ if (dt <= OB_WIRE)
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
else
- BIF_ThemeColor(TH_BONE_SOLID);
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
}
draw_bone_points(dt, armflag, boneflag, id);
/* now draw the bone itself */
-
if (id != -1) {
- glLoadName ((GLuint) id|BONESEL_BONE);
+ glLoadName((GLuint) id|BONESEL_BONE);
}
/* wire? */
- if(dt <= OB_WIRE) {
+ if (dt <= OB_WIRE) {
/* colors */
if (armflag & ARM_EDITMODE) {
if (boneflag & BONE_ACTIVE) BIF_ThemeColor(TH_EDGE_SELECT);
else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_EDGE_SELECT, -20);
else BIF_ThemeColor(TH_WIRE);
}
- else if (armflag & ARM_POSEMODE){
- if(constflag) {
- glEnable(GL_BLEND);
-
- if(constflag & PCHAN_HAS_STRIDE) glColor4ub(0, 0, 200, 80);
- else if(constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
- else if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
- else if(constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
- else BIF_ThemeColor4(TH_BONE_POSE); // PCHAN_HAS_ACTION
+ else if (armflag & ARM_POSEMODE) {
+ if (constflag) {
+ /* draw constraint colors */
+ if (set_pchan_glColor(PCHAN_COLOR_CONSTS, armflag, boneflag, constflag)) {
+ glEnable(GL_BLEND);
- draw_bone_solid_octahedral();
- glDisable(GL_BLEND);
-
+ draw_bone_solid_octahedral();
+
+ glDisable(GL_BLEND);
+ }
+
/* restore colors */
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, constflag);
}
}
draw_bone_octahedral();
}
- else { /* solid */
-
- BIF_ThemeColor(TH_BONE_SOLID);
+ else {
+ /* solid */
+ if (armflag & ARM_POSEMODE)
+ set_pchan_glColor(PCHAN_COLOR_SOLID, armflag, boneflag, constflag);
+ else
+ BIF_ThemeColor(TH_BONE_SOLID);
draw_bone_solid_octahedral();
}
/* disable solid drawing */
- if(dt>OB_WIRE) {
+ if (dt > OB_WIRE) {
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
}
@@ -1075,41 +1278,42 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
static void draw_custom_bone(Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length)
{
-
- if(ob==NULL || ob->type!=OB_MESH) return;
+ if(ob==NULL) return;
glScalef(length, length, length);
/* colors for posemode */
if (armflag & ARM_POSEMODE) {
- if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
- else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
- else BIF_ThemeColor(TH_WIRE);
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, armflag, boneflag, 0);
}
if (id != -1) {
- glLoadName ((GLuint) id|BONESEL_BONE);
+ glLoadName((GLuint) id|BONESEL_BONE);
}
draw_object_instance(ob, dt, armflag & ARM_POSEMODE);
}
-static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
+static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
{
bConstraint *con;
bPoseChannel *parchan;
- for(con= pchan->constraints.first; con; con= con->next) {
- if(con->type == CONSTRAINT_TYPE_KINEMATIC) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = (bKinematicConstraint*)con->data;
int segcount= 0;
+ /* if only_temp, only draw if it is a temporary ik-chain */
+ if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP))
+ continue;
+
setlinestyle(3);
glBegin(GL_LINES);
/* exclude tip from chain? */
- if(!(data->flag & CONSTRAINT_IK_TIP))
+ if ((data->flag & CONSTRAINT_IK_TIP)==0)
parchan= pchan->parent;
else
parchan= pchan;
@@ -1117,12 +1321,12 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
glVertex3fv(parchan->pose_tail);
/* Find the chain's root */
- while (parchan->parent){
+ while (parchan->parent) {
segcount++;
if(segcount==data->rootbone || segcount>255) break; // 255 is weak
parchan= parchan->parent;
}
- if(parchan)
+ if (parchan)
glVertex3fv(parchan->pose_head);
glEnd();
@@ -1200,7 +1404,7 @@ static void draw_dof_ellipse(float ax, float az)
glColor3ub(0, 0, 0);
glBegin(GL_LINE_STRIP);
- for(i=0; i<n; i++)
+ for (i=0; i<n; i++)
bgl_sphere_project(staticSine[n-i-1]*ax, staticSine[i]*az);
glEnd();
}
@@ -1211,40 +1415,41 @@ static void draw_pose_dofs(Object *ob)
bPoseChannel *pchan;
Bone *bone;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & BONE_HIDDEN_P)) {
- if(bone->flag & BONE_SELECTED) {
- if(bone->layer & arm->layer) {
- if(pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) {
- if(pose_channel_in_IK_chain(ob, pchan)) {
+
+ if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+ if (bone->flag & BONE_SELECTED) {
+ if (bone->layer & arm->layer) {
+ if (pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) {
+ if (pose_channel_in_IK_chain(ob, pchan)) {
float corner[4][3], posetrans[3], mat[4][4];
float phi=0.0f, theta=0.0f, scale;
int a, i;
-
+
/* in parent-bone pose, but own restspace */
glPushMatrix();
-
+
VECCOPY(posetrans, pchan->pose_mat[3]);
glTranslatef(posetrans[0], posetrans[1], posetrans[2]);
-
- if(pchan->parent) {
+
+ if (pchan->parent) {
Mat4CpyMat4(mat, pchan->parent->pose_mat);
mat[3][0]= mat[3][1]= mat[3][2]= 0.0f;
glMultMatrixf(mat);
}
-
+
Mat4CpyMat3(mat, pchan->bone->bone_mat);
glMultMatrixf(mat);
-
+
scale= bone->length*pchan->size[1];
glScalef(scale, scale, scale);
-
- if(pchan->ikflag & BONE_IK_XLIMIT) {
- if(pchan->ikflag & BONE_IK_ZLIMIT) {
+
+ if (pchan->ikflag & BONE_IK_XLIMIT) {
+ if (pchan->ikflag & BONE_IK_ZLIMIT) {
float amin[3], amax[3];
-
- for(i=0; i<3; i++) {
+
+ for (i=0; i<3; i++) {
amin[i]= sin(pchan->limitmin[i]*M_PI/360.0);
amax[i]= sin(pchan->limitmax[i]*M_PI/360.0);
}
@@ -1263,49 +1468,50 @@ static void draw_pose_dofs(Object *ob)
}
/* arcs */
- if(pchan->ikflag & BONE_IK_ZLIMIT) {
+ if (pchan->ikflag & BONE_IK_ZLIMIT) {
theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]);
glRotatef(theta, 0.0f, 0.0f, 1.0f);
-
+
glColor3ub(50, 50, 255); // blue, Z axis limit
glBegin(GL_LINE_STRIP);
- for(a=-16; a<=16; a++) {
+ for (a=-16; a<=16; a++) {
float fac= ((float)a)/16.0f;
phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]);
- if(a==-16) i= 0; else i= 1;
+ i= (a == -16) ? 0 : 1;
corner[i][0]= sin(phi);
corner[i][1]= cos(phi);
corner[i][2]= 0.0f;
glVertex3fv(corner[i]);
}
glEnd();
-
+
glRotatef(-theta, 0.0f, 0.0f, 1.0f);
}
-
- if(pchan->ikflag & BONE_IK_XLIMIT) {
- theta= 0.5*( pchan->limitmin[0]+pchan->limitmax[0]);
+
+ if (pchan->ikflag & BONE_IK_XLIMIT) {
+ theta= 0.5*(pchan->limitmin[0]+pchan->limitmax[0]);
glRotatef(theta, 1.0f, 0.0f, 0.0f);
-
+
glColor3ub(255, 50, 50); // Red, X axis limit
glBegin(GL_LINE_STRIP);
- for(a=-16; a<=16; a++) {
+ for (a=-16; a<=16; a++) {
float fac= ((float)a)/16.0f;
phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]);
-
- if(a==-16) i= 2; else i= 3;
+
+ i= (a == -16) ? 2 : 3;
corner[i][0]= 0.0f;
corner[i][1]= sin(phi);
corner[i][2]= cos(phi);
glVertex3fv(corner[i]);
}
glEnd();
-
+
glRotatef(-theta, 1.0f, 0.0f, 0.0f);
}
-
- glPopMatrix(); // out of cone, out of bone
+
+ /* out of cone, out of bone */
+ glPopMatrix();
}
}
}
@@ -1324,38 +1530,39 @@ static void draw_pose_channels(Base *base, int dt)
GLfloat tmp;
float smat[4][4], imat[4][4];
int index= -1;
- int do_dashed= 1;
+ short do_dashed= 3, draw_wire= 0;
short flag, constflag;
/* hacky... prevent outline select from drawing dashed helplines */
glGetFloatv(GL_LINE_WIDTH, &tmp);
- if(tmp > 1.1) do_dashed= 0;
- if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed= 0;
+ if (tmp > 1.1) do_dashed &= ~1;
+ if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed &= ~2;
/* precalc inverse matrix for drawing screen aligned */
- if(arm->drawtype==ARM_ENVELOPE) {
+ if (arm->drawtype==ARM_ENVELOPE) {
/* precalc inverse matrix for drawing screen aligned */
mygetmatrix(smat);
Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
Mat4Invert(imat, smat);
/* and draw blended distances */
- if(arm->flag & ARM_POSEMODE) {
+ if (arm->flag & ARM_POSEMODE) {
glEnable(GL_BLEND);
//glShadeModel(GL_SMOOTH);
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM))) {
- if(bone->flag & (BONE_SELECTED))
- if(bone->layer & arm->layer)
+ if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM|BONE_HIDDEN_PG))) {
+ if (bone->flag & (BONE_SELECTED)) {
+ if (bone->layer & arm->layer)
draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL);
+ }
}
}
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
//glShadeModel(GL_FLAT);
}
@@ -1366,67 +1573,145 @@ static void draw_pose_channels(Base *base, int dt)
glEnable(GL_CULL_FACE);
/* if solid we draw that first, with selection codes, but without names, axes etc */
- if(dt>OB_WIRE) {
- if(arm->flag & ARM_POSEMODE) index= base->selcol;
+ if (dt > OB_WIRE) {
+ if (arm->flag & ARM_POSEMODE)
+ index= base->selcol;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & BONE_HIDDEN_P)) {
- if(bone->layer & arm->layer) {
+
+ if ( (bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) ) {
+ if (bone->layer & arm->layer) {
glPushMatrix();
glMultMatrixf(pchan->pose_mat);
/* catch exception for bone with hidden parent */
flag= bone->flag;
- if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
+ if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) )
flag &= ~BONE_CONNECTED;
+
+ /* set color-set to use */
+ set_pchan_colorset(ob, pchan);
- if(pchan->custom && !(arm->flag & ARM_NO_CUSTOM))
- draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length);
- else if(arm->drawtype==ARM_LINE)
+ if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
+ /* if drawwire, don't try to draw in solid */
+ if (pchan->bone->flag & BONE_DRAWWIRE)
+ draw_wire= 1;
+ else
+ draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length);
+ }
+ else if (arm->drawtype==ARM_LINE)
; /* nothing in solid */
- else if(arm->drawtype==ARM_ENVELOPE)
+ else if (arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
- else if(arm->drawtype==ARM_B_BONE)
+ else if (arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
- else {
+ else
draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
- }
+
glPopMatrix();
}
}
- if (index!= -1) index+= 0x10000; // pose bones count in higher 2 bytes only
+
+ if (index!= -1)
+ index+= 0x10000; // pose bones count in higher 2 bytes only
}
- /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet, stick bones are dawn in next loop */
- if(arm->drawtype!=ARM_LINE) {
- glLoadName (index & 0xFFFF); // object tag, for bordersel optim
+
+ /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet,
+ * stick bones and/or wire custom-shpaes are drawn in next loop
+ */
+ if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) {
+ /* object tag, for bordersel optim */
+ glLoadName(index & 0xFFFF);
index= -1;
}
}
- /* wire draw over solid only in posemode */
- if( dt<=OB_WIRE || (arm->flag & ARM_POSEMODE) || arm->drawtype==ARM_LINE) {
+ /* draw custom bone shapes as wireframes */
+ if ( !(arm->flag & ARM_NO_CUSTOM) &&
+ ((draw_wire) || (dt <= OB_WIRE)) )
+ {
+ if (arm->flag & ARM_POSEMODE)
+ index= base->selcol;
+
+ /* only draw custom bone shapes that need to be drawn as wires */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+
+ if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+ if (bone->layer & arm->layer) {
+ if (pchan->custom) {
+ if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
+ glPushMatrix();
+ glMultMatrixf(pchan->pose_mat);
+
+ /* prepare colours */
+ if (arm->flag & ARM_POSEMODE)
+ set_pchan_colorset(ob, pchan);
+ else {
+ if ((G.scene->basact)==base) {
+ if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_ACTIVE);
+ else BIF_ThemeColor(TH_WIRE);
+ }
+ else {
+ if (base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_SELECT);
+ else BIF_ThemeColor(TH_WIRE);
+ }
+ }
+
+ /* catch exception for bone with hidden parent */
+ flag= bone->flag;
+ if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
+ flag &= ~BONE_CONNECTED;
+
+ draw_custom_bone(pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length);
+
+ glPopMatrix();
+ }
+ }
+ }
+ }
+
+ if (index != -1)
+ index+= 0x10000; // pose bones count in higher 2 bytes only
+ }
+
+ if (draw_wire) {
+ /* object tag, for bordersel optim */
+ glLoadName(index & 0xFFFF);
+ index= -1;
+ }
+ }
+ /* wire draw over solid only in posemode */
+ if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) {
/* draw line check first. we do selection indices */
if (arm->drawtype==ARM_LINE) {
- if (arm->flag & ARM_POSEMODE) index= base->selcol;
+ if (arm->flag & ARM_POSEMODE)
+ index= base->selcol;
}
/* if solid && posemode, we draw again with polygonoffset */
- else if (dt>OB_WIRE && (arm->flag & ARM_POSEMODE))
+ else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) {
bglPolygonOffset(1.0);
- else
+ }
+ else {
/* and we use selection indices if not done yet */
- if (arm->flag & ARM_POSEMODE) index= base->selcol;
+ if (arm->flag & ARM_POSEMODE)
+ index= base->selcol;
+ }
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & BONE_HIDDEN_P)) {
- if(bone->layer & arm->layer) {
- if (do_dashed && bone->parent) {
- /* Draw a line from our root to the parent's tip */
- if(!(bone->flag & BONE_CONNECTED) ){
+
+ if ((bone) && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+ if (bone->layer & arm->layer) {
+ if ((do_dashed & 1) && (bone->parent)) {
+ /* Draw a line from our root to the parent's tip
+ * - only if V3D_HIDE_HELPLINES is enabled...
+ */
+ if ( (do_dashed & 2) && ((bone->flag & BONE_CONNECTED)==0) ) {
if (arm->flag & ARM_POSEMODE) {
- glLoadName (index & 0xFFFF); // object tag, for bordersel optim
+ glLoadName(index & 0xFFFF); // object tag, for bordersel optim
BIF_ThemeColor(TH_WIRE);
}
setlinestyle(3);
@@ -1436,64 +1721,66 @@ static void draw_pose_channels(Base *base, int dt)
glEnd();
setlinestyle(0);
}
- // Draw a line to IK root bone
- if(arm->flag & ARM_POSEMODE) {
- if(pchan->constflag & PCHAN_HAS_IK) {
- if(bone->flag & BONE_SELECTED) {
-
- if(pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
+
+ /* Draw a line to IK root bone
+ * - only if temporary chain (i.e. "autoik")
+ */
+ if (arm->flag & ARM_POSEMODE) {
+ if (pchan->constflag & PCHAN_HAS_IK) {
+ if (bone->flag & BONE_SELECTED) {
+ if (pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
else glColor3ub(200, 200, 50); // add theme!
-
- glLoadName (index & 0xFFFF);
- pchan_draw_IK_root_lines(pchan);
+
+ glLoadName(index & 0xFFFF);
+ pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
}
}
}
}
- if(arm->drawtype!=ARM_ENVELOPE) {
- glPushMatrix();
+ glPushMatrix();
+ if (arm->drawtype != ARM_ENVELOPE)
glMultMatrixf(pchan->pose_mat);
- }
/* catch exception for bone with hidden parent */
flag= bone->flag;
- if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
+ if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)))
flag &= ~BONE_CONNECTED;
/* extra draw service for pose mode */
constflag= pchan->constflag;
- if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
+ if (pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
constflag |= PCHAN_HAS_ACTION;
- if(pchan->flag & POSE_STRIDE)
+ if (pchan->flag & POSE_STRIDE)
constflag |= PCHAN_HAS_STRIDE;
-
- if(pchan->custom && !(arm->flag & ARM_NO_CUSTOM)) {
- if(dt<OB_SOLID)
- draw_custom_bone(pchan->custom, OB_WIRE, arm->flag, flag, index, bone->length);
- }
- else if(arm->drawtype==ARM_ENVELOPE) {
- if(dt<OB_SOLID)
+
+ /* set color-set to use */
+ set_pchan_colorset(ob, pchan);
+
+ if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM))
+ ; // custom bone shapes should not be drawn here!
+ else if (arm->drawtype==ARM_ENVELOPE) {
+ if (dt < OB_SOLID)
draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL);
}
- else if(arm->drawtype==ARM_LINE)
+ else if (arm->drawtype==ARM_LINE)
draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
- else if(arm->drawtype==ARM_B_BONE)
+ else if (arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
- else {
+ else
draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
- }
- if(arm->drawtype!=ARM_ENVELOPE)
- glPopMatrix();
+ glPopMatrix();
}
}
- if (index!= -1) index+= 0x10000; // pose bones count in higher 2 bytes only
+
+ /* pose bones count in higher 2 bytes only */
+ if (index != -1)
+ index+= 0x10000;
}
/* restore things */
- if (arm->drawtype!=ARM_LINE && dt>OB_WIRE && (arm->flag & ARM_POSEMODE))
+ if ((arm->drawtype!=ARM_LINE)&& (dt>OB_WIRE) && (arm->flag & ARM_POSEMODE))
bglPolygonOffset(0.0);
-
}
/* restore */
@@ -1504,31 +1791,35 @@ static void draw_pose_channels(Base *base, int dt)
draw_pose_dofs(ob);
/* finally names and axes */
- if(arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
- // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
- if((G.f & G_PICKSEL) == 0) {
+ if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
+ /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
+ if ((G.f & G_PICKSEL) == 0) {
float vec[3];
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if((pchan->bone->flag & BONE_HIDDEN_P)==0) {
- if(pchan->bone->layer & arm->layer) {
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ if ((pchan->bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))==0) {
+ if (pchan->bone->layer & arm->layer) {
if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) {
bone= pchan->bone;
- if(bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
+
+ if (bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
else BIF_ThemeColor(TH_TEXT);
}
- else if(dt > OB_WIRE) BIF_ThemeColor(TH_TEXT);
+ else if (dt > OB_WIRE)
+ BIF_ThemeColor(TH_TEXT);
- if (arm->flag & ARM_DRAWNAMES){
+ /* Draw names of bone */
+ if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, pchan->pose_head, pchan->pose_tail);
glRasterPos3fv(vec);
BMF_DrawString(G.font, " ");
BMF_DrawString(G.font, pchan->name);
- }
- /* Draw additional axes */
- if( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ){
+ }
+
+ /* 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);
@@ -1539,10 +1830,9 @@ static void draw_pose_channels(Base *base, int dt)
}
}
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
}
}
-
}
/* in editmode, we don't store the bone matrix... */
@@ -1551,10 +1841,10 @@ static void set_matrix_editbone(EditBone *eBone)
float delta[3],offset[3];
float mat[3][3], bmat[4][4];
- /* Compose the parent transforms (i.e. their translations) */
- VECCOPY (offset, eBone->head);
+ /* Compose the parent transforms (i.e. their translations) */
+ VECCOPY(offset, eBone->head);
- glTranslatef (offset[0],offset[1],offset[2]);
+ glTranslatef(offset[0],offset[1],offset[2]);
VecSubf(delta, eBone->tail, eBone->head);
@@ -1562,8 +1852,8 @@ static void set_matrix_editbone(EditBone *eBone)
vec_roll_to_mat3(delta, eBone->roll, mat);
Mat4CpyMat3(bmat, mat);
-
- glMultMatrixf (bmat);
+
+ glMultMatrixf(bmat);
}
@@ -1586,35 +1876,37 @@ static void draw_ebones(Object *ob, int dt)
glEnable(GL_BLEND);
//glShadeModel(GL_SMOOTH);
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
- for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
- if(eBone->layer & arm->layer)
- if(!(eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM)))
- if(eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
+ for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
+ if (eBone->layer & arm->layer) {
+ if ((eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))==0) {
+ if (eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone);
+ }
+ }
}
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
//glShadeModel(GL_FLAT);
}
/* if solid we draw it first */
- if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) {
+ if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) {
index= 0;
- for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
- if(eBone->layer & arm->layer) {
- if(!(eBone->flag & BONE_HIDDEN_A)) {
+ for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
+ if (eBone->layer & arm->layer) {
+ if ((eBone->flag & BONE_HIDDEN_A)==0) {
glPushMatrix();
set_matrix_editbone(eBone);
/* catch exception for bone with hidden parent */
flag= eBone->flag;
- if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
+ if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
flag &= ~BONE_CONNECTED;
- if(arm->drawtype==ARM_ENVELOPE)
+ if (arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
else if(arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
@@ -1631,42 +1923,42 @@ static void draw_ebones(Object *ob, int dt)
/* if wire over solid, set offset */
index= -1;
glLoadName(-1);
- if(arm->drawtype==ARM_LINE) {
+ if (arm->drawtype==ARM_LINE) {
if(G.f & G_PICKSEL)
index= 0;
}
- else if (dt>OB_WIRE)
+ else if (dt > OB_WIRE)
bglPolygonOffset(1.0);
- else if(arm->flag & ARM_EDITMODE)
- index= 0; // do selection codes
+ else if (arm->flag & ARM_EDITMODE)
+ index= 0; /* do selection codes */
- for (eBone=G.edbo.first; eBone; eBone=eBone->next){
- if(eBone->layer & arm->layer) {
- if(!(eBone->flag & BONE_HIDDEN_A)) {
+ for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
+ if (eBone->layer & arm->layer) {
+ if ((eBone->flag & BONE_HIDDEN_A)==0) {
/* catch exception for bone with hidden parent */
flag= eBone->flag;
- if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
+ if ( (eBone->parent) && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) )
flag &= ~BONE_CONNECTED;
- if(arm->drawtype==ARM_ENVELOPE) {
- if(dt<OB_SOLID)
+ if (arm->drawtype == ARM_ENVELOPE) {
+ if (dt < OB_SOLID)
draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
}
else {
glPushMatrix();
set_matrix_editbone(eBone);
- if(arm->drawtype==ARM_LINE)
+ if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
- else if(arm->drawtype==ARM_B_BONE)
+ else if (arm->drawtype == ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
else
draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
-
+
glPopMatrix();
}
-
+
/* offset to parent */
if (eBone->parent) {
BIF_ThemeColor(TH_WIRE);
@@ -1686,33 +1978,33 @@ static void draw_ebones(Object *ob, int dt)
}
/* restore */
- if(arm->drawtype==ARM_LINE);
+ if (arm->drawtype==ARM_LINE);
else if (dt>OB_WIRE) bglPolygonOffset(0.0);
/* finally names and axes */
- if(arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
+ if (arm->flag & (ARM_DRAWNAMES|ARM_DRAWAXES)) {
// patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
- if((G.f & G_PICKSEL) == 0) {
+ if ((G.f & G_PICKSEL) == 0) {
float vec[3];
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
- for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
+ for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++) {
if(eBone->layer & arm->layer) {
- if(!(eBone->flag & BONE_HIDDEN_A)) {
+ if ((eBone->flag & BONE_HIDDEN_A)==0) {
- if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
+ if (eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
else BIF_ThemeColor(TH_TEXT);
/* Draw name */
- if(arm->flag & ARM_DRAWNAMES){
+ if (arm->flag & ARM_DRAWNAMES) {
VecMidf(vec, eBone->head, eBone->tail);
glRasterPos3fv(vec);
BMF_DrawString(G.font, " ");
BMF_DrawString(G.font, eBone->name);
}
/* Draw additional axes */
- if(arm->flag & ARM_DRAWAXES){
+ if (arm->flag & ARM_DRAWAXES) {
glPushMatrix();
set_matrix_editbone(eBone);
glTranslatef(0.0f, eBone->length, 0.0f);
@@ -1724,25 +2016,31 @@ static void draw_ebones(Object *ob, int dt)
}
}
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
}
}
}
-/* in view space */
+/* ****************************** Armature Visualisation ******************************** */
+
+/* ---------- Paths --------- */
+
+/* draw bone paths
+ * - in view space
+ */
static void draw_pose_paths(Object *ob)
{
bArmature *arm= ob->data;
bPoseChannel *pchan;
bAction *act;
bActionChannel *achan;
- CfraElem *ce;
- ListBase ak;
- float *fp;
- int a;
- int stepsize, sfra;
+ ActKeyColumn *ak;
+ ListBase keys;
+ float *fp, *fp_start;
+ int a, stepsize;
+ int sfra, efra, len;
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
glPushMatrix();
glLoadMatrixf(G.vd->viewmat);
@@ -1751,22 +2049,94 @@ static void draw_pose_paths(Object *ob)
if (arm->pathsize == 0) arm->pathsize= 1;
stepsize = arm->pathsize;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->bone->layer & arm->layer) {
- if(pchan->path) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone->layer & arm->layer) {
+ if (pchan->path) {
/* version patch here - cannot access frame info from file reading */
if ((pchan->pathsf == 0) || (pchan->pathef == 0)) {
pchan->pathsf= SFRA;
pchan->pathef= EFRA;
}
- sfra= pchan->pathsf;
+
+ /* get frame ranges */
+ if (arm->pathflag & ARM_PATH_ACFRA) {
+ int sind;
+
+ /* With "Around Current", we only choose frames from around
+ * the current frame to draw. However, this range is still
+ * restricted by the limits of the original path.
+ */
+ sfra= CFRA - arm->pathbc;
+ efra= CFRA + arm->pathac;
+ if (sfra < pchan->pathsf) sfra= pchan->pathsf;
+ if (efra > pchan->pathef) efra= pchan->pathef;
+
+ len= efra - sfra;
+
+ sind= sfra - pchan->pathsf;
+ fp_start= (pchan->path + (3*sind));
+ }
+ else {
+ sfra= pchan->pathsf;
+ efra = sfra + pchan->pathlen;
+ len = pchan->pathlen;
+ fp_start = pchan->path;
+ }
/* draw curve-line of path */
- BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
- glBegin(GL_LINE_STRIP);
- for(a=0, fp= pchan->path; a<pchan->pathlen; a++, fp+=3)
+ glShadeModel(GL_SMOOTH);
+
+ glBegin(GL_LINE_STRIP);
+ for (a=0, fp=fp_start; a<len; a++, fp+=3) {
+ float intensity; /* how faint */
+
+ /* set colour
+ * - more intense for active/selected bones, less intense for unselected bones
+ * - black for before current frame, green for current frame, blue for after current frame
+ * - intensity decreases as distance from current frame increases
+ */
+ #define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max-min)) + min)
+ if ((a+sfra) < CFRA) {
+ /* black - before cfra */
+ if (pchan->bone->flag & BONE_SELECTED) {
+ // intensity= 0.5;
+ intensity = SET_INTENSITY(sfra, a, CFRA, 0.25f, 0.75f);
+ }
+ else {
+ //intensity= 0.8;
+ intensity = SET_INTENSITY(sfra, a, CFRA, 0.68f, 0.92f);
+ }
+ BIF_ThemeColorBlend(TH_WIRE, TH_BACK, intensity);
+ }
+ else if ((a+sfra) > CFRA) {
+ /* blue - after cfra */
+ if (pchan->bone->flag & BONE_SELECTED) {
+ //intensity = 0.5;
+ intensity = SET_INTENSITY(CFRA, a, efra, 0.25f, 0.75f);
+ }
+ else {
+ //intensity = 0.8;
+ intensity = SET_INTENSITY(CFRA, a, efra, 0.68f, 0.92f);
+ }
+ BIF_ThemeColorBlend(TH_BONE_POSE, TH_BACK, intensity);
+ }
+ else {
+ /* green - on cfra */
+ if (pchan->bone->flag & BONE_SELECTED) {
+ intensity= 0.5;
+ }
+ else {
+ intensity= 0.99;
+ }
+ BIF_ThemeColorBlendShade(TH_CFRAME, TH_BACK, intensity, 10);
+ }
+
+ /* draw a vertex with this colour */
glVertex3fv(fp);
+ }
+
glEnd();
+ glShadeModel(GL_FLAT);
glPointSize(1.0);
@@ -1774,29 +2144,29 @@ static void draw_pose_paths(Object *ob)
* NOTE: this is not really visible/noticable
*/
glBegin(GL_POINTS);
- for(a=0, fp= pchan->path; a<pchan->pathlen; a++, fp+=3)
+ for (a=0, fp=fp_start; a<len; a++, fp+=3)
glVertex3fv(fp);
glEnd();
/* Draw little white dots at each framestep value */
BIF_ThemeColor(TH_TEXT_HI);
glBegin(GL_POINTS);
- for(a=0, fp= pchan->path; a<pchan->pathlen; a+=stepsize, fp+=(stepsize*3))
+ for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3))
glVertex3fv(fp);
glEnd();
/* Draw frame numbers at each framestep value */
if (arm->pathflag & ARM_PATH_FNUMS) {
- for(a=0, fp= pchan->path; a<pchan->pathlen; a+=stepsize, fp+=(stepsize*3)) {
+ for (a=0, fp=fp_start; a<len; a+=stepsize, fp+=(stepsize*3)) {
char str[32];
- /* only draw framenum if several consecutive highlighted points occur on same point */
+ /* only draw framenum if several consecutive highlighted points don't occur on same point */
if (a == 0) {
glRasterPos3fv(fp);
sprintf(str, " %d\n", (a+sfra));
BMF_DrawString(G.font, str);
}
- else if ((a > stepsize) && (a < pchan->pathlen-stepsize)) {
+ else if ((a > stepsize) && (a < len-stepsize)) {
if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) {
glRasterPos3fv(fp);
sprintf(str, " %d\n", (a+sfra));
@@ -1809,30 +2179,34 @@ static void draw_pose_paths(Object *ob)
/* Keyframes - dots and numbers */
if (arm->pathflag & ARM_PATH_KFRAS) {
/* build list of all keyframes in active action for pchan */
- ak.first = ak.last = NULL;
+ keys.first = keys.last = NULL;
act= ob_get_action(ob);
if (act) {
achan= get_action_channel(act, pchan->name);
if (achan)
- ipo_to_keylist(achan->ipo, &ak, NULL);
+ ipo_to_keylist(achan->ipo, &keys, NULL, NULL);
}
- /* Draw little yellow dots at each keyframe */
+ /* Draw slightly-larger yellow dots at each keyframe */
BIF_ThemeColor(TH_VERTEX_SELECT);
+ glPointSize(5.0);
+
glBegin(GL_POINTS);
- for(a=0, fp= pchan->path; a<pchan->pathlen; a++, fp+=3) {
- for (ce= ak.first; ce; ce= ce->next) {
- if (ce->cfra == (a+sfra))
+ for (a=0, fp=fp_start; a<len; a++, fp+=3) {
+ for (ak= keys.first; ak; ak= ak->next) {
+ if (ak->cfra == (a+sfra))
glVertex3fv(fp);
}
}
glEnd();
+ glPointSize(1.0);
+
/* Draw frame numbers of keyframes */
- if (arm->pathflag & ARM_PATH_FNUMS) {
- for(a=0, fp= pchan->path; a<pchan->pathlen; a++, fp+=3) {
- for (ce= ak.first; ce; ce= ce->next) {
- if (ce->cfra == (a+sfra)) {
+ if ((arm->pathflag & ARM_PATH_FNUMS) || (arm->pathflag & ARM_PATH_KFNOS)) {
+ for(a=0, fp=fp_start; a<len; a++, fp+=3) {
+ for (ak= keys.first; ak; ak= ak->next) {
+ if (ak->cfra == (a+sfra)) {
char str[32];
glRasterPos3fv(fp);
@@ -1843,18 +2217,51 @@ static void draw_pose_paths(Object *ob)
}
}
- BLI_freelistN(&ak);
+ BLI_freelistN(&keys);
}
}
}
}
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
glPopMatrix();
}
+
+/* ---------- Ghosts --------- */
+
+/* helper function for ghost drawing - sets/removes flags for temporarily
+ * hiding unselected bones while drawing ghosts
+ */
+static void ghost_poses_tag_unselected(Object *ob, short unset)
+{
+ bArmature *arm= ob->data;
+ bPose *pose= ob->pose;
+ bPoseChannel *pchan;
+
+ /* don't do anything if no hiding any bones */
+ if ((arm->flag & ARM_GHOST_ONLYSEL)==0)
+ return;
+
+ /* loop over all pchans, adding/removing tags as appropriate */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (unset) {
+ /* remove tags from all pchans if cleaning up */
+ pchan->bone->flag &= ~BONE_HIDDEN_PG;
+ }
+ else {
+ /* set tags on unselected pchans only */
+ if ((pchan->bone->flag & BONE_SELECTED)==0)
+ pchan->bone->flag |= BONE_HIDDEN_PG;
+ }
+ }
+ }
+}
+
/* draw ghosts that occur within a frame range
- * note: object should be in posemode */
+ * note: object should be in posemode
+ */
static void draw_ghost_poses_range(Base *base)
{
Object *ob= base->object;
@@ -1865,7 +2272,7 @@ static void draw_ghost_poses_range(Base *base)
start = arm->ghostsf;
end = arm->ghostef;
- if (end<=start)
+ if (end <= start)
return;
stepsize= (float)(arm->ghostsize);
@@ -1884,12 +2291,13 @@ static void draw_ghost_poses_range(Base *base)
copy_pose(&posen, ob->pose, 1);
ob->pose= posen;
armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
glEnable(GL_BLEND);
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
/* draw from first frame of range to last */
- for(CFRA= start; CFRA<end; CFRA+=stepsize) {
+ for (CFRA= start; CFRA<end; CFRA+=stepsize) {
colfac = (end-CFRA)/range;
BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
@@ -1898,10 +2306,10 @@ static void draw_ghost_poses_range(Base *base)
draw_pose_channels(base, OB_WIRE);
}
glDisable(GL_BLEND);
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
- free_pose_channels(posen);
- MEM_freeN(posen);
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
/* restore */
CFRA= cfrao;
@@ -1910,10 +2318,89 @@ static void draw_ghost_poses_range(Base *base)
armature_rebuild_pose(ob, ob->data);
ob->flag |= OB_POSEMODE;
ob->ipoflag= ipoflago;
+}
+/* draw ghosts on keyframes in action within range
+ * - object should be in posemode
+ */
+static void draw_ghost_poses_keys(Base *base)
+{
+ Object *ob= base->object;
+ bAction *act= ob_get_action(ob);
+ bArmature *arm= ob->data;
+ bPose *posen, *poseo;
+ ListBase keys= {NULL, NULL};
+ ActKeysInc aki = {0, 0, 0};
+ ActKeyColumn *ak, *akn;
+ float start, end, range, colfac, i;
+ int cfrao, flago, ipoflago;
+
+ aki.start= start = arm->ghostsf;
+ aki.end= end = arm->ghostef;
+ if (end <= start)
+ return;
+
+ /* get keyframes - then clip to only within range */
+ action_to_keylist(act, &keys, NULL, &aki);
+ range= 0;
+ for (ak= keys.first; ak; ak= akn) {
+ akn= ak->next;
+
+ if ((ak->cfra < start) || (ak->cfra > end))
+ BLI_freelinkN(&keys, ak);
+ else
+ range++;
+ }
+ if (range == 0) return;
+
+ /* store values */
+ ob->flag &= ~OB_POSEMODE;
+ cfrao= CFRA;
+ flago= arm->flag;
+ arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
+ ipoflago= ob->ipoflag;
+ ob->ipoflag |= OB_DISABLE_PATH;
+
+ /* copy the pose */
+ poseo= ob->pose;
+ copy_pose(&posen, ob->pose, 1);
+ ob->pose= posen;
+ armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
+
+ glEnable(GL_BLEND);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+
+ /* draw from first frame of range to last */
+ for (ak=keys.first, i=0; ak; ak=ak->next, i++) {
+ colfac = i/range;
+ BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
+
+ CFRA= (int)ak->cfra;
+
+ do_all_pose_actions(ob);
+ where_is_pose(ob);
+ draw_pose_channels(base, OB_WIRE);
+ }
+ glDisable(GL_BLEND);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ BLI_freelistN(&keys);
+ free_pose(posen);
+
+ /* restore */
+ CFRA= cfrao;
+ ob->pose= poseo;
+ arm->flag= flago;
+ armature_rebuild_pose(ob, ob->data);
+ ob->flag |= OB_POSEMODE;
+ ob->ipoflag= ipoflago;
}
-/* object is supposed to be armature in posemode */
+/* draw ghosts around current frame
+ * - object is supposed to be armature in posemode
+ */
static void draw_ghost_poses(Base *base)
{
Object *ob= base->object;
@@ -1924,11 +2411,11 @@ static void draw_ghost_poses(Base *base)
int cfrao, maptime, flago, ipoflago;
/* pre conditions, get an action with sufficient frames */
- if(ob->action==NULL)
+ if (ob->action==NULL)
return;
calc_action_range(ob->action, &start, &end, 0);
- if(start==end)
+ if (start == end)
return;
stepsize= (float)(arm->ghostsize);
@@ -1936,7 +2423,7 @@ static void draw_ghost_poses(Base *base)
/* we only map time for armature when an active strip exists */
for (strip=ob->nlastrips.first; strip; strip=strip->next)
- if(strip->flag & ACTSTRIP_ACTIVE)
+ if (strip->flag & ACTSTRIP_ACTIVE)
break;
maptime= (strip!=NULL);
@@ -1944,7 +2431,7 @@ static void draw_ghost_poses(Base *base)
/* store values */
ob->flag &= ~OB_POSEMODE;
cfrao= CFRA;
- if(maptime) actframe= get_action_frame(ob, (float)CFRA);
+ if (maptime) actframe= get_action_frame(ob, (float)CFRA);
else actframe= CFRA;
flago= arm->flag;
arm->flag &= ~(ARM_DRAWNAMES|ARM_DRAWAXES);
@@ -1956,24 +2443,23 @@ static void draw_ghost_poses(Base *base)
copy_pose(&posen, ob->pose, 1);
ob->pose= posen;
armature_rebuild_pose(ob, ob->data); /* child pointers for IK */
+ ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
glEnable(GL_BLEND);
- if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glDisable(GL_DEPTH_TEST);
/* draw from darkest blend to lowest */
for(cur= stepsize; cur<range; cur+=stepsize) {
-
ctime= cur - fmod((float)cfrao, stepsize); /* ensures consistant stepping */
colfac= ctime/range;
BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
/* only within action range */
- if(actframe+ctime >= start && actframe+ctime <= end) {
-
- if(maptime) CFRA= (int)get_action_frame_inv(ob, actframe+ctime);
+ if (actframe+ctime >= start && actframe+ctime <= end) {
+ if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe+ctime);
else CFRA= (int)floor(actframe+ctime);
- if(CFRA!=cfrao) {
+ if (CFRA!=cfrao) {
do_all_pose_actions(ob);
where_is_pose(ob);
draw_pose_channels(base, OB_WIRE);
@@ -1985,12 +2471,11 @@ static void draw_ghost_poses(Base *base)
BIF_ThemeColorShadeAlpha(TH_WIRE, 0, -128-(int)(120.0f*sqrt(colfac)));
/* only within action range */
- if(actframe-ctime >= start && actframe-ctime <= end) {
-
- if(maptime) CFRA= (int)get_action_frame_inv(ob, actframe-ctime);
+ if ((actframe-ctime >= start) && (actframe-ctime <= end)) {
+ if (maptime) CFRA= (int)get_action_frame_inv(ob, actframe-ctime);
else CFRA= (int)floor(actframe-ctime);
-
- if(CFRA!=cfrao) {
+
+ if (CFRA != cfrao) {
do_all_pose_actions(ob);
where_is_pose(ob);
draw_pose_channels(base, OB_WIRE);
@@ -1998,10 +2483,10 @@ static void draw_ghost_poses(Base *base)
}
}
glDisable(GL_BLEND);
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (G.vd->zbuf) glEnable(GL_DEPTH_TEST);
- free_pose_channels(posen);
- MEM_freeN(posen);
+ ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
+ free_pose(posen);
/* restore */
CFRA= cfrao;
@@ -2010,9 +2495,10 @@ static void draw_ghost_poses(Base *base)
armature_rebuild_pose(ob, ob->data);
ob->flag |= OB_POSEMODE;
ob->ipoflag= ipoflago;
-
}
+/* ********************************** Armature Drawing - Main ************************* */
+
/* called from drawobject.c, return 1 if nothing was drawn */
int draw_armature(Base *base, int dt)
{
@@ -2048,10 +2534,13 @@ int draw_armature(Base *base, int dt)
arm->flag |= ARM_POSEMODE;
}
else if(ob->flag & OB_POSEMODE) {
- if (arm->ghosttype == ARM_GHOST_RANGE){
+ if (arm->ghosttype == ARM_GHOST_RANGE) {
draw_ghost_poses_range(base);
}
- else {
+ else if (arm->ghosttype == ARM_GHOST_KEYS) {
+ draw_ghost_poses_keys(base);
+ }
+ else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
draw_ghost_poses(base);
}
diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c
index 188f48bcdca..8263b92b0ac 100644
--- a/source/blender/src/drawimage.c
+++ b/source/blender/src/drawimage.c
@@ -43,6 +43,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -95,6 +96,7 @@
#include "BIF_screen.h"
#include "BIF_toolbox.h"
#include "BIF_transform.h"
+#include "BIF_editmesh.h"
#include "BSE_drawipo.h"
#include "BSE_drawview.h"
@@ -107,6 +109,8 @@
#include "RE_pipeline.h"
#include "BMF_Api.h"
+#include "PIL_time.h"
+
/* Modules used */
#include "mydevice.h"
#include "blendef.h"
@@ -184,15 +188,16 @@ void calc_image_view(SpaceImage *sima, char mode)
{
float xim=256, yim=256;
float x1, y1;
- float zoom;
if(image_preview_active(curarea, &xim, &yim));
else if(sima->image) {
- ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(sima);
+ float xuser_asp, yuser_asp;
+ aspect_sima(sima, &xuser_asp, &yuser_asp);
if(ibuf) {
- xim= ibuf->x;
- yim= ibuf->y;
+ xim= ibuf->x * xuser_asp;
+ yim= ibuf->y * yuser_asp;
}
else if( sima->image->type==IMA_TYPE_R_RESULT ) {
/* not very important, just nice */
@@ -218,17 +223,14 @@ void calc_image_view(SpaceImage *sima, char mode)
x1-= sima->zoom*sima->xof;
y1-= sima->zoom*sima->yof;
-
- /* float! */
- zoom= sima->zoom;
/* relative display right */
- sima->v2d.cur.xmin= ((curarea->winrct.xmin - (float)x1)/zoom);
- sima->v2d.cur.xmax= sima->v2d.cur.xmin + ((float)curarea->winx/zoom);
+ sima->v2d.cur.xmin= ((curarea->winrct.xmin - (float)x1)/sima->zoom);
+ sima->v2d.cur.xmax= sima->v2d.cur.xmin + ((float)curarea->winx/sima->zoom);
/* relative display left */
- sima->v2d.cur.ymin= ((curarea->winrct.ymin-(float)y1)/zoom);
- sima->v2d.cur.ymax= sima->v2d.cur.ymin + ((float)curarea->winy/zoom);
+ sima->v2d.cur.ymin= ((curarea->winrct.ymin-(float)y1)/sima->zoom);
+ sima->v2d.cur.ymax= sima->v2d.cur.ymin + ((float)curarea->winy/sima->zoom);
if(mode=='f') {
sima->v2d.cur.xmin/= xim;
@@ -242,112 +244,163 @@ void calc_image_view(SpaceImage *sima, char mode)
void what_image(SpaceImage *sima)
{
MTFace *activetf;
- Mesh *me;
+
+ if( (sima->mode!=SI_TEXTURE) ||
+ (sima->image && sima->image->source==IMA_SRC_VIEWER) ||
+ (G.obedit != OBACT) ||
+ (sima->pin)
+ ) {
+ return;
+ }
+
+ /* viewer overrides uv editmode */
+ if (EM_texFaceCheck()) {
+ sima->image= NULL;
- if(sima->mode==SI_TEXTURE) {
+ activetf = get_active_mtface(NULL, NULL, 1); /* partially selected face is ok */
- /* viewer overrides faceselect */
- if(sima->image && sima->image->source==IMA_SRC_VIEWER);
- else if((G.f & G_FACESELECT)) {
+ if(activetf && activetf->mode & TF_TEX) {
+ if (!sima->pin)
+ sima->image= activetf->tpage;
- sima->image= NULL;
- me= get_mesh(OBACT);
- activetf = get_active_tface(NULL);
+ if(sima->flag & SI_EDITTILE);
+ else sima->curtile= activetf->tile;
- if(me && me->mtface && activetf && activetf->mode & TF_TEX) {
- sima->image= activetf->tpage;
-
- if(sima->flag & SI_EDITTILE);
- else sima->curtile= activetf->tile;
-
- if(sima->image) {
- if(activetf->mode & TF_TILES)
- sima->image->tpageflag |= IMA_TILES;
- else sima->image->tpageflag &= ~IMA_TILES;
- }
+ if(sima->image) {
+ if(activetf->mode & TF_TILES)
+ sima->image->tpageflag |= IMA_TILES;
+ else sima->image->tpageflag &= ~IMA_TILES;
}
}
-
}
}
/* after a what_image(), this call will give ibufs, includes the spare image */
ImBuf *imagewindow_get_ibuf(SpaceImage *sima)
{
-
if(G.sima->image) {
/* check for spare */
- if(sima->image->type==IMA_TYPE_R_RESULT && sima->showspare)
- return sima->spare;
+ if(sima->image->type==IMA_TYPE_R_RESULT && BIF_show_render_spare())
+ return BIF_render_spare_imbuf();
else
return BKE_image_get_ibuf(sima->image, &sima->iuser);
}
return NULL;
}
-
+extern int EM_texFaceCheck(void); /* from editmesh.c */
/* called to assign images to UV faces */
-void image_changed(SpaceImage *sima, int dotile)
+void image_changed(SpaceImage *sima, Image *image)
{
MTFace *tface;
- MFace *mface;
- Mesh *me;
- int a;
-
- if(sima->image==NULL)
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ ImBuf *ibuf = NULL;
+ short change = 0;
+
+ if(image==NULL) {
sima->flag &= ~SI_DRAWTOOL;
+ } else {
+ ibuf = BKE_image_get_ibuf(image, NULL);
+ }
+
+ if(sima->mode!=SI_TEXTURE)
+ return;
- if(sima->mode==SI_TEXTURE) {
+ /* skip assigning these procedural images... */
+ if(image && (image->type==IMA_TYPE_R_RESULT || image->type==IMA_TYPE_COMPOSITE)) {
+ return;
+ } else if ((G.obedit) &&
+ (G.obedit->type == OB_MESH) &&
+ (G.editMesh) &&
+ (G.editMesh->faces.first)
+ ) {
- if(G.f & G_FACESELECT) {
+ /* Add a UV layer if there is none, editmode only */
+ if ( !CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE) ) {
+ EM_add_data_layer(&em->fdata, CD_MTFACE);
+ CustomData_set_layer_active(&em->fdata, CD_MTFACE, 0); /* always zero because we have no other UV layers */
+ change = 1; /* so we update the object, incase no faces are selected */
- /* skip assigning these procedural images... */
- if(sima->image) {
- if(sima->image->type==IMA_TYPE_R_RESULT)
- return;
- if(sima->image->type==IMA_TYPE_COMPOSITE)
- return;
+ /* BIF_undo_push("New UV Texture"); - undo should be done by whatever changes the image */
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (efa->h==0 && efa->f & SELECT) {
+ if (image) {
+ tface->tpage= image;
+ tface->mode |= TF_TEX;
+
+ if(image->tpageflag & IMA_TILES) tface->mode |= TF_TILES;
+ else tface->mode &= ~TF_TILES;
+
+ if(image->id.us==0) id_us_plus(&image->id);
+ else id_lib_extern(&image->id);
+
+ if (tface->transp==TF_ADD) {} /* they obviously know what they are doing! - leave as is */
+ else if (ibuf && ibuf->depth == 32) tface->transp = TF_ALPHA;
+ else tface->transp = TF_SOLID;
+
+ } else {
+ tface->tpage= NULL;
+ tface->mode &= ~TF_TEX;
+ tface->transp = TF_SOLID;
+ }
+ change = 1;
}
-
- me= get_mesh(OBACT);
- if(me && me->mtface) {
-
- tface= me->mtface;
- mface = me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
-
- if(dotile==2) {
- tface->mode &= ~TF_TILES;
- }
- else {
- tface->tpage= sima->image;
- tface->mode |= TF_TEX;
-
- if(dotile) tface->tile= sima->curtile;
- }
-
- if(sima->image) {
- if(sima->image->tpageflag & IMA_TILES) tface->mode |= TF_TILES;
- else tface->mode &= ~TF_TILES;
-
- if(sima->image->id.us==0) id_us_plus(&sima->image->id);
- else id_lib_extern(&sima->image->id);
- }
- }
- tface++;
- mface++;
+ }
+ }
+ /* change the space image after because simaFaceDraw_Check uses the space image
+ * to check if the face is displayed in UV-localview */
+ sima->image = image;
+
+ if (change)
+ object_uvs_changed(OBACT);
+
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+/*
+ * dotile - 1, set the tile flag (from the space image)
+ * 2, set the tile index for the faces.
+ * */
+void image_set_tile(SpaceImage *sima, int dotile)
+{
+ MTFace *tface;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+
+ if(!sima->image || sima->mode!=SI_TEXTURE || !EM_texFaceCheck())
+ return;
+
+ /* skip assigning these procedural images... */
+ if(sima->image && (sima->image->type==IMA_TYPE_R_RESULT || sima->image->type==IMA_TYPE_COMPOSITE))
+ return;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (efa->h==0 && efa->f & SELECT) {
+ if (dotile==1) {
+ /* set tile flag */
+ if (sima->image->tpageflag & IMA_TILES) {
+ tface->mode |= TF_TILES;
+ } else {
+ tface->mode &= ~TF_TILES;
}
-
- object_uvs_changed(OBACT);
- allqueue(REDRAWBUTSEDIT, 0);
+ } else if (dotile==2) {
+ /* set tile index */
+ tface->tile= sima->curtile;
}
}
}
+ object_uvs_changed(OBACT);
+ allqueue(REDRAWBUTSEDIT, 0);
}
+
void uvco_to_areaco(float *vec, short *mval)
{
float x, y;
@@ -381,258 +434,648 @@ void uvco_to_areaco_noclip(float *vec, int *mval)
mval[1]= y;
}
-void draw_tfaces(void)
+static void drawcursor_sima(float xuser_asp, float yuser_asp)
+{
+ int wi, hi;
+ float w, h;
+
+ if (!G.obedit || !CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE)) return;
+
+ transform_width_height_tface_uv(&wi, &hi);
+ w = (((float)wi)/256.0f)*G.sima->zoom * xuser_asp;
+ h = (((float)hi)/256.0f)*G.sima->zoom * yuser_asp;
+
+ cpack(0xFFFFFF);
+ glTranslatef(G.v2d->cursor[0], G.v2d->cursor[1], 0.0f);
+ fdrawline(-0.05/w, 0, 0, 0.05/h);
+ fdrawline(0, 0.05/h, 0.05/w, 0);
+ fdrawline(0.05/w, 0, 0, -0.05/h);
+ fdrawline(0, -0.05/h, -0.05/w, 0);
+
+ setlinestyle(4);
+ cpack(0xFF);
+ fdrawline(-0.05/w, 0, 0, 0.05/h);
+ fdrawline(0, 0.05/h, 0.05/w, 0);
+ fdrawline(0.05/w, 0, 0, -0.05/h);
+ fdrawline(0, -0.05/h, -0.05/w, 0);
+
+
+ setlinestyle(0);
+ cpack(0x0);
+ fdrawline(-0.020/w, 0, -0.1/w, 0);
+ fdrawline(0.1/w, 0, .020/w, 0);
+ fdrawline(0, -0.020/h, 0, -0.1/h);
+ fdrawline(0, 0.1/h, 0, 0.020/h);
+
+ setlinestyle(1);
+ cpack(0xFFFFFF);
+ fdrawline(-0.020/w, 0, -0.1/w, 0);
+ fdrawline(0.1/w, 0, .020/w, 0);
+ fdrawline(0, -0.020/h, 0, -0.1/h);
+ fdrawline(0, 0.1/h, 0, 0.020/h);
+
+ glTranslatef(-G.v2d->cursor[0], -G.v2d->cursor[1], 0.0f);
+ setlinestyle(0);
+}
+
+// checks if we are selecting only faces
+int draw_uvs_face_check(void)
+{
+ if (G.sima==NULL)
+ return 0;
+ if (G.sima->flag & SI_SYNC_UVSEL && G.scene->selectmode == SCE_SELECT_FACE)
+ return 2;
+ if (G.sima->flag & SI_SELACTFACE)
+ return 1;
+ return 0;
+}
+
+void tface_center(MTFace *tf, float cent[2], void * isquad)
+{
+
+ if (isquad) {
+ cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0] + tf->uv[3][0]) / 4.0;
+ cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1] + tf->uv[3][1]) / 4.0;
+ } else {
+ cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0]) / 3.0;
+ cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1]) / 3.0;
+ }
+}
+
+float tface_area(MTFace *tf, int quad)
+{
+ if (quad) {
+ return AreaF2Dfl(tf->uv[0], tf->uv[1], tf->uv[2]) + AreaF2Dfl(tf->uv[0], tf->uv[2], tf->uv[3]);
+ } else {
+ return AreaF2Dfl(tf->uv[0], tf->uv[1], tf->uv[2]);
+ }
+}
+
+/* draws uv's in the image space */
+void draw_uvs_sima(void)
{
MTFace *tface,*activetface = NULL;
- MFace *mface,*activemface = NULL;
- Mesh *me;
- int a;
+ EditMesh *em = G.editMesh;
+ EditFace *efa, *efa_act;
+
char col1[4], col2[4];
- float pointsize= BIF_GetThemeValuef(TH_VERTEX_SIZE);
+ float pointsize;
+ int drawface;
- if(G.f & G_FACESELECT) {
- me= get_mesh(OBACT);
-
- if(me && me->mtface) {
- calc_image_view(G.sima, 'f'); /* float */
- myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
- glLoadIdentity();
+ if (!G.obedit || !CustomData_has_layer(&em->fdata, CD_MTFACE))
+ return;
+
+ drawface = draw_uvs_face_check();
+
+ calc_image_view(G.sima, 'f'); /* float */
+ myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ glLoadIdentity();
+
+
+ if(G.sima->flag & SI_DRAWTOOL) {
+ /* draws the grey mesh when painting */
+ glColor3ub(112, 112, 112);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ return; /* only draw shadow mesh */
+ } else if (G.sima->flag & SI_DRAWSHADOW) {
+ /* draw shadow mesh - this is the mesh with the modifier applied */
+ glColor3ub(112, 112, 112);
+ if ( em->derivedFinal &&
+ em->derivedFinal->drawUVEdges &&
+ CustomData_has_layer(&em->derivedFinal->faceData, CD_MTFACE)
+ ) {
+ /* we can use the existing final mesh */
+ glColor3ub(112, 112, 112);
+ em->derivedFinal->drawUVEdges(em->derivedFinal);
+ } else {
+ DerivedMesh *finalDM, *cageDM;
- /* draw shadow mesh */
- if ((G.sima->flag & SI_DRAWSHADOW) && !(G.obedit==OBACT)) {
- DerivedMesh *dm;
-
- /* draw final mesh with modifiers applied */
- dm = mesh_get_derived_final(OBACT,
- CD_MASK_BAREMESH | CD_MASK_MTFACE);
-
+ /* draw final mesh with modifiers applied */
+ cageDM = editmesh_get_derived_cage_and_final(&finalDM, CD_MASK_BAREMESH | CD_MASK_MTFACE);
+
+ if (finalDM->drawUVEdges &&
+ DM_get_face_data_layer(finalDM, CD_MTFACE) &&
+ /* When sync selection is enabled, all faces are drawn (except for hidden)
+ * so if cage is the same as the final, theres no point in drawing the shadowmesh. */
+ !((G.sima->flag & SI_SYNC_UVSEL && cageDM==finalDM))
+ ) {
glColor3ub(112, 112, 112);
- if (dm->drawUVEdges) dm->drawUVEdges(dm);
-
- dm->release(dm);
+ finalDM->drawUVEdges(finalDM);
}
- else if((G.sima->flag & SI_DRAWTOOL) || (G.obedit==OBACT)) {
- /* draw mesh without modifiers applied */
-
- if (G.obedit) {
- DerivedMesh *dm = editmesh_get_derived_base();
-
- glColor3ub(112, 112, 112);
- dm->drawUVEdges(dm);
-
- dm->release(dm);
+
+ if (cageDM != finalDM)
+ cageDM->release(cageDM);
+ finalDM->release(finalDM);
+ }
+ }
+
+ activetface = get_active_mtface(&efa_act, NULL, 0); /* will be set to NULL if hidden */
+
+
+ if (G.sima->flag & SI_DRAW_STRETCH) {
+ float col[3];
+
+ switch (G.sima->dt_uvstretch) {
+ case SI_UVDT_STRETCH_AREA:
+ {
+ float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ totarea += EM_face_area(efa);
+ totuvarea += tface_area(tface, efa->v4!=0);
+
+ if (simaFaceDraw_Check(efa, tface)) {
+ efa->tmp.p = tface;
+ } else {
+ if (tface == activetface)
+ activetface= NULL;
+ efa->tmp.p = NULL;
+ }
}
- else {
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
-
- glColor3ub(112, 112, 112);
- while(a--) {
- if(!(mface->flag & ME_HIDE) && (mface->flag & ME_FACE_SEL)) {
- glBegin(GL_LINE_LOOP);
+
+ if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
+ col[0] = 1.0;
+ col[1] = col[2] = 0.0;
+ glColor3fv(col);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if ((tface=(MTFace *)efa->tmp.p)) {
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ }
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if ((tface=(MTFace *)efa->tmp.p)) {
+ area = EM_face_area(efa) / totarea;
+ uvarea = tface_area(tface, efa->v4!=0) / totuvarea;
+ if (area < FLT_EPSILON || uvarea < FLT_EPSILON) {
+ areadiff = 1.0;
+ } else if (area>uvarea) {
+ areadiff = 1.0-(uvarea/area);
+ } else {
+ areadiff = 1.0-(area/uvarea);
+ }
+
+ weight_to_rgb(areadiff, col, col+1, col+2);
+ glColor3fv(col);
+
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
glVertex2fv(tface->uv[0]);
glVertex2fv(tface->uv[1]);
glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
- glEnd();
- }
- tface++;
- mface++;
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
}
}
+ break;
}
-
- if((G.sima->flag & SI_DRAWTOOL) || (G.obedit==OBACT))
- return; /* only draw shadow mesh */
-
- /* draw transparent faces */
- if(G.f & G_DRAWFACES) {
- BIF_GetThemeColor4ubv(TH_FACE, col1);
- BIF_GetThemeColor4ubv(TH_FACE_SELECT, col2);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
- if(!(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&
- (!mface->v4 || tface->flag & TF_SEL4))
- glColor4ubv((GLubyte *)col2);
- else
- glColor4ubv((GLubyte *)col1);
+ case SI_UVDT_STRETCH_ANGLE:
+ {
+ float uvang1,uvang2,uvang3,uvang4;
+ float ang1,ang2,ang3,ang4;
+ float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d angle vectors */
+ float a;
+
+ col[3] = 0.5; /* hard coded alpha, not that nice */
+
+ glShadeModel(GL_SMOOTH);
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ if (simaFaceDraw_Check(efa, tface)) {
+ efa->tmp.p = tface;
+ if (efa->v4) {
+
+#if 0 /* Simple but slow, better reuse normalized vectors */
+ uvang1 = VecAngle3_2D(tface->uv[3], tface->uv[0], tface->uv[1]);
+ ang1 = VecAngle3(efa->v4->co, efa->v1->co, efa->v2->co);
+
+ uvang2 = VecAngle3_2D(tface->uv[0], tface->uv[1], tface->uv[2]);
+ ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
- glBegin(mface->v4?GL_QUADS:GL_TRIANGLES);
+ uvang3 = VecAngle3_2D(tface->uv[1], tface->uv[2], tface->uv[3]);
+ ang3 = VecAngle3(efa->v2->co, efa->v3->co, efa->v4->co);
+
+ uvang4 = VecAngle3_2D(tface->uv[2], tface->uv[3], tface->uv[0]);
+ ang4 = VecAngle3(efa->v3->co, efa->v4->co, efa->v1->co);
+#endif
+
+ /* uv angles */
+ VECSUB2D(av1, tface->uv[3], tface->uv[0]); Normalize2(av1);
+ VECSUB2D(av2, tface->uv[0], tface->uv[1]); Normalize2(av2);
+ VECSUB2D(av3, tface->uv[1], tface->uv[2]); Normalize2(av3);
+ VECSUB2D(av4, tface->uv[2], tface->uv[3]); Normalize2(av4);
+
+ /* This is the correct angle however we are only comparing angles
+ * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90);*/
+ uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
+ uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
+ uvang3 = NormalizedVecAngle2_2D(av3, av4)*180.0/M_PI;
+ uvang4 = NormalizedVecAngle2_2D(av4, av1)*180.0/M_PI;
+
+ /* 3d angles */
+ VECSUB(av1, efa->v4->co, efa->v1->co); Normalize(av1);
+ VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
+ VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
+ VECSUB(av4, efa->v3->co, efa->v4->co); Normalize(av4);
+
+ /* This is the correct angle however we are only comparing angles
+ * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90);*/
+ ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
+ ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
+ ang3 = NormalizedVecAngle2(av3, av4)*180.0/M_PI;
+ ang4 = NormalizedVecAngle2(av4, av1)*180.0/M_PI;
+
+ glBegin(GL_QUADS);
+
+ /* This simple makes the angles display worse then they really are ;)
+ * 1.0-pow((1.0-a), 2) */
+
+ a = fabs(uvang1-ang1)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
glVertex2fv(tface->uv[0]);
+ a = fabs(uvang2-ang2)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
glVertex2fv(tface->uv[1]);
+ a = fabs(uvang3-ang3)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
+ a = fabs(uvang4-ang4)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
+ glVertex2fv(tface->uv[3]);
+
+ } else {
+#if 0 /* Simple but slow, better reuse normalized vectors */
+ uvang1 = VecAngle3_2D(tface->uv[2], tface->uv[0], tface->uv[1]);
+ ang1 = VecAngle3(efa->v3->co, efa->v1->co, efa->v2->co);
+
+ uvang2 = VecAngle3_2D(tface->uv[0], tface->uv[1], tface->uv[2]);
+ ang2 = VecAngle3(efa->v1->co, efa->v2->co, efa->v3->co);
+
+ uvang3 = 180-(uvang1+uvang2);
+ ang3 = 180-(ang1+ang2);
+#endif
+
+ /* uv angles */
+ VECSUB2D(av1, tface->uv[2], tface->uv[0]); Normalize2(av1);
+ VECSUB2D(av2, tface->uv[0], tface->uv[1]); Normalize2(av2);
+ VECSUB2D(av3, tface->uv[1], tface->uv[2]); Normalize2(av3);
+
+ /* This is the correct angle however we are only comparing angles
+ * uvang1 = 90-((NormalizedVecAngle2_2D(av1, av2) * 180.0/M_PI)-90); */
+ uvang1 = NormalizedVecAngle2_2D(av1, av2)*180.0/M_PI;
+ uvang2 = NormalizedVecAngle2_2D(av2, av3)*180.0/M_PI;
+ uvang3 = NormalizedVecAngle2_2D(av3, av1)*180.0/M_PI;
+
+ /* 3d angles */
+ VECSUB(av1, efa->v3->co, efa->v1->co); Normalize(av1);
+ VECSUB(av2, efa->v1->co, efa->v2->co); Normalize(av2);
+ VECSUB(av3, efa->v2->co, efa->v3->co); Normalize(av3);
+ /* This is the correct angle however we are only comparing angles
+ * ang1 = 90-((NormalizedVecAngle2(av1, av2) * 180.0/M_PI)-90); */
+ ang1 = NormalizedVecAngle2(av1, av2)*180.0/M_PI;
+ ang2 = NormalizedVecAngle2(av2, av3)*180.0/M_PI;
+ ang3 = NormalizedVecAngle2(av3, av1)*180.0/M_PI;
+
+ /* This simple makes the angles display worse then they really are ;)
+ * 1.0-pow((1.0-a), 2) */
+
+ glBegin(GL_TRIANGLES);
+ a = fabs(uvang1-ang1)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
+ glVertex2fv(tface->uv[0]);
+ a = fabs(uvang2-ang2)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
+ glVertex2fv(tface->uv[1]);
+ a = fabs(uvang3-ang3)/180.0;
+ weight_to_rgb(1.0-pow((1.0-a), 2), col, col+1, col+2);
+ glColor3fv(col);
+ glVertex2fv(tface->uv[2]);
+ }
glEnd();
+ } else {
+ if (tface == activetface)
+ activetface= NULL;
+ efa->tmp.p = NULL;
}
- tface++;
- mface++;
}
- glDisable(GL_BLEND);
+ glShadeModel(GL_FLAT);
+ break;
}
-
-
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & TF_ACTIVE){
- activetface= tface;
- activemface= mface;
- }
-
- cpack(0x0);
- glBegin(GL_LINE_LOOP);
- glVertex2fv(tface->uv[0]);
- glVertex2fv(tface->uv[1]);
- glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
- glEnd();
-
- setlinestyle(2);
- cpack(0xFFFFFF);
- glBegin(GL_LINE_STRIP);
- glVertex2fv(tface->uv[0]);
- glVertex2fv(tface->uv[1]);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(tface->uv[0]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
- else glVertex2fv(tface->uv[2]);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(tface->uv[1]);
- glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
- glEnd();
- setlinestyle(0);
+ }
+ } else if(G.f & G_DRAWFACES) {
+ /* draw transparent faces */
+ BIF_GetThemeColor4ubv(TH_FACE, col1);
+ BIF_GetThemeColor4ubv(TH_FACE_SELECT, col2);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ if (simaFaceDraw_Check(efa, tface)) {
+ efa->tmp.p = tface;
+ if (tface==activetface) continue; /* important the temp pointer is set above */
+ if( simaFaceSel_Check(efa, tface)) {
+ glColor4ubv((GLubyte *)col2);
+ } else {
+ glColor4ubv((GLubyte *)col1);
}
- tface++;
- mface++;
+ glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+
+ } else {
+ if (tface == activetface)
+ activetface= NULL;
+ efa->tmp.p = NULL;
}
-
- /* draw active face edges */
- if (activetface){
- /* colors: R=u G=v */
-
- setlinestyle(2);
- tface=activetface;
- mface=activemface;
-
- cpack(0x0);
+ }
+ glDisable(GL_BLEND);
+ } else {
+ /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ efa->tmp.p = tface;
+ } else {
+ if (tface == activetface)
+ activetface= NULL;
+ efa->tmp.p = NULL;
+ }
+ }
+
+ }
+
+ if (activetface) {
+ GLubyte act_face_stipple[32*32/8] = DM_FACE_STIPPLE;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ BIF_ThemeColor4(TH_EDITMESH_ACTIVE);
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(act_face_stipple);
+ glBegin(efa_act->v4?GL_QUADS:GL_TRIANGLES);
+ glVertex2fv(activetface->uv[0]);
+ glVertex2fv(activetface->uv[1]);
+ glVertex2fv(activetface->uv[2]);
+ if(efa_act->v4) glVertex2fv(activetface->uv[3]);
+ glEnd();
+ glDisable(GL_POLYGON_STIPPLE);
+ glDisable(GL_BLEND);
+ }
+
+ if (G.sima->flag & SI_SMOOTH_UV) {
+ glEnable( GL_LINE_SMOOTH );
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ switch (G.sima->dt_uv) {
+ case SI_UVDT_DASH:
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ cpack(0x111111);
glBegin(GL_LINE_LOOP);
- glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[0]);
glVertex2fv(tface->uv[1]);
glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
glEnd();
-
- cpack(0xFF00);
+
+ setlinestyle(2);
+ cpack(0x909090);
glBegin(GL_LINE_STRIP);
glVertex2fv(tface->uv[0]);
glVertex2fv(tface->uv[1]);
glEnd();
-
- cpack(0xFF);
+
glBegin(GL_LINE_STRIP);
glVertex2fv(tface->uv[0]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
else glVertex2fv(tface->uv[2]);
glEnd();
-
- cpack(0xFFFFFF);
+
glBegin(GL_LINE_STRIP);
glVertex2fv(tface->uv[1]);
glVertex2fv(tface->uv[2]);
- if(mface->v4) glVertex2fv(tface->uv[3]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
glEnd();
-
setlinestyle(0);
}
+ }
+ break;
+ case SI_UVDT_BLACK: /* black/white */
+ case SI_UVDT_WHITE:
+ cpack((G.sima->dt_uv==SI_UVDT_WHITE) ? 0xFFFFFF : 0x0);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ }
+ break;
+ case SI_UVDT_OUTLINE:
+ glLineWidth(3);
+ cpack(0x0);
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ }
+
+ glLineWidth(1);
+ cpack(0xFFFFFF);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(efa->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ }
+ break;
+ }
- /* unselected uv's */
- BIF_ThemeColor(TH_VERTEX);
- glPointSize(pointsize);
+ if (G.sima->flag & SI_SMOOTH_UV) {
+ glDisable( GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+ }
- bglBegin(GL_POINTS);
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
-
- if(tface->flag & TF_SEL1); else bglVertex2fv(tface->uv[0]);
- if(tface->flag & TF_SEL2); else bglVertex2fv(tface->uv[1]);
- if(tface->flag & TF_SEL3); else bglVertex2fv(tface->uv[2]);
- if(mface->v4) {
- if(tface->flag & TF_SEL4); else bglVertex2fv(tface->uv[3]);
- }
+ if (drawface) {
+ // draw UV face points
+ float cent[2];
+
+
+ /* unselected faces's */
+ pointsize = BIF_GetThemeValuef(TH_FACEDOT_SIZE);
+ // TODO - drawobject.c changes this value after - Investiagate!
+ glPointSize(pointsize);
+
+ BIF_ThemeColor(TH_WIRE);
+ bglBegin(GL_POINTS);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+ if( ! simaFaceSel_Check(efa, tface) ) {
+ tface_center(tface, cent, (void *)efa->v4);
+ bglVertex2fv(cent);
}
- tface++;
- mface++;
}
- bglEnd();
-
- /* pinned uv's */
- /* give odd pointsizes odd pin pointsizes */
- glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
- cpack(0xFF);
-
- bglBegin(GL_POINTS);
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
-
- if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]);
- if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]);
- if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]);
- if(mface->v4) {
- if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]);
- }
+ }
+ bglEnd();
+ /* selected faces's */
+ BIF_ThemeColor(TH_FACE_DOT);
+ bglBegin(GL_POINTS);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+ if( simaFaceSel_Check(efa, tface) ) {
+ tface_center(tface, cent, (void *)efa->v4);
+ bglVertex2fv(cent);
}
- tface++;
- mface++;
}
- bglEnd();
-
- /* selected uv's */
- BIF_ThemeColor(TH_VERTEX_SELECT);
- glPointSize(pointsize);
-
- bglBegin(GL_POINTS);
- tface= me->mtface;
- mface= me->mface;
- a= me->totface;
- while(a--) {
- if(mface->flag & ME_FACE_SEL) {
-
- if(tface->flag & TF_SEL1) bglVertex2fv(tface->uv[0]);
- if(tface->flag & TF_SEL2) bglVertex2fv(tface->uv[1]);
- if(tface->flag & TF_SEL3) bglVertex2fv(tface->uv[2]);
- if(mface->v4) {
- if(tface->flag & TF_SEL4) bglVertex2fv(tface->uv[3]);
- }
+ }
+ bglEnd();
+ }
+
+ if (drawface != 2) { /* 2 means Mesh Face Mode */
+ /* unselected uv's */
+ BIF_ThemeColor(TH_VERTEX);
+ pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE);
+ glPointSize(pointsize);
+
+ bglBegin(GL_POINTS);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ if(simaUVSel_Check(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
+ if(simaUVSel_Check(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
+ if(simaUVSel_Check(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
+ if(efa->v4) {
+ if(simaUVSel_Check(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
}
- tface++;
- mface++;
}
- bglEnd();
-
- glPointSize(1.0);
}
- }
+ bglEnd();
+
+ /* pinned uv's */
+ /* give odd pointsizes odd pin pointsizes */
+ glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
+ cpack(0xFF);
+
+ bglBegin(GL_POINTS);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]);
+ if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]);
+ if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]);
+ if(efa->v4) {
+ if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]);
+ }
+ }
+ }
+ bglEnd();
+ /* selected uv's */
+ BIF_ThemeColor(TH_VERTEX_SELECT);
+ glPointSize(pointsize);
+
+ bglBegin(GL_POINTS);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+
+ /*this is a shortcut to do the same as above but a faster for drawing */
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ if(!simaUVSel_Check(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
+ if(!simaUVSel_Check(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
+ if(!simaUVSel_Check(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
+ if(efa->v4) {
+ if(!simaUVSel_Check(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
+ }
+ }
+ }
+ bglEnd();
+ }
+ glPointSize(1.0);
}
static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, short endx, short endy)
@@ -657,7 +1100,7 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty,
return rectmain;
}
-static void draw_image_transform(ImBuf *ibuf)
+static void draw_image_transform(ImBuf *ibuf, float xuser_asp, float yuser_asp)
{
if(G.moving) {
float aspx, aspy, center[3];
@@ -668,10 +1111,9 @@ static void draw_image_transform(ImBuf *ibuf)
aspx= aspy= 1.0;
}
else {
- aspx= 256.0/ibuf->x;
- aspy= 256.0/ibuf->y;
+ aspx= (256.0/ibuf->x) * xuser_asp;
+ aspy= (256.0/ibuf->y) * yuser_asp;
}
-
BIF_getPropCenter(center);
/* scale and translate the circle into place and draw it */
@@ -693,17 +1135,18 @@ static void draw_image_view_icon(void)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if(G.sima->flag & SI_STICKYUVS) {
- BIF_icon_draw_aspect(xPos, 5.0, ICON_STICKY2_UVS, 1.0f);
- xPos = 25.0;
- }
- else if(!(G.sima->flag & SI_LOCALSTICKY)) {
- BIF_icon_draw_aspect(xPos, 5.0, ICON_STICKY_UVS, 1.0f);
- xPos = 25.0;
- }
-
- if(G.sima->flag & SI_SELACTFACE) {
- BIF_icon_draw_aspect(xPos, 5.0, ICON_DRAW_UVFACES, 1.0f);
+
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ /* take settings from the editmesh */
+ if (G.scene->selectmode == SCE_SELECT_FACE || G.sima->flag & SI_SELACTFACE) {
+ BIF_icon_draw_aspect(xPos, 5.0, ICON_FACESEL_HLT, 1.0f);
+ }
+
+ } else {
+ /* use the flags for UV mode - normal operation */
+ if(G.sima->flag & SI_SELACTFACE) {
+ BIF_icon_draw_aspect(xPos, 5.0, ICON_FACESEL_HLT, 1.0f);
+ }
}
glBlendFunc(GL_ONE, GL_ZERO);
@@ -742,52 +1185,65 @@ static void draw_image_view_tool(void)
/* ************ panel stuff ************* */
+/* this function gets the values for cursor and vertex number buttons */
+static void image_transform_but_attr(int *imx, int *imy, int *step, int *digits) /*, float *xcoord, float *ycoord)*/
+{
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
+ if(ibuf) {
+ *imx= ibuf->x;
+ *imy= ibuf->y;
+ }
+
+ if (G.sima->flag & SI_COORDFLOATS) {
+ *step= 1;
+ *digits= 3;
+ }
+ else {
+ *step= 100;
+ *digits= 2;
+ }
+}
+
+
/* is used for both read and write... */
void image_editvertex_buts(uiBlock *block)
{
static float ocent[2];
float cent[2]= {0.0, 0.0};
int imx= 256, imy= 256;
- int i, nactive= 0, step, digits;
- Mesh *me;
+ int nactive= 0, step, digits;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tf;
if( is_uv_tface_editing_allowed_silent()==0 ) return;
- me= get_mesh(OBACT);
- if (G.sima->image) {
- ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
- if(ibuf) {
- imx= ibuf->x;
- imy= ibuf->y;
- }
- }
+ image_transform_but_attr(&imx, &imy, &step, &digits);
- for (i=0; i<me->totface; i++) {
- MFace *mf= &((MFace*) me->mface)[i];
- MTFace *tf= &((MTFace*) me->mtface)[i];
-
- if (!(mf->flag & ME_FACE_SEL))
- continue;
-
- if (tf->flag & TF_SEL1) {
- cent[0]+= tf->uv[0][0];
- cent[1]+= tf->uv[0][1];
- nactive++;
- }
- if (tf->flag & TF_SEL2) {
- cent[0]+= tf->uv[1][0];
- cent[1]+= tf->uv[1][1];
- nactive++;
- }
- if (tf->flag & TF_SEL3) {
- cent[0]+= tf->uv[2][0];
- cent[1]+= tf->uv[2][1];
- nactive++;
- }
- if (mf->v4 && (tf->flag & TF_SEL4)) {
- cent[0]+= tf->uv[3][0];
- cent[1]+= tf->uv[3][1];
- nactive++;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+
+ if (simaUVSel_Check(efa, tf, 0)) {
+ cent[0]+= tf->uv[0][0];
+ cent[1]+= tf->uv[0][1];
+ nactive++;
+ }
+ if (simaUVSel_Check(efa, tf, 1)) {
+ cent[0]+= tf->uv[1][0];
+ cent[1]+= tf->uv[1][1];
+ nactive++;
+ }
+ if (simaUVSel_Check(efa, tf, 2)) {
+ cent[0]+= tf->uv[2][0];
+ cent[1]+= tf->uv[2][1];
+ nactive++;
+ }
+ if (efa->v4 && simaUVSel_Check(efa, tf, 3)) {
+ cent[0]+= tf->uv[3][0];
+ cent[1]+= tf->uv[3][1];
+ nactive++;
+ }
}
}
@@ -796,27 +1252,21 @@ void image_editvertex_buts(uiBlock *block)
ocent[0]= cent[0]/nactive;
ocent[1]= cent[1]/nactive;
if (G.sima->flag & SI_COORDFLOATS) {
- step= 1;
- digits= 3;
- }
- else {
+ } else {
ocent[0] *= imx;
ocent[1] *= imy;
- step= 100;
- digits= 2;
}
- uiDefBut(block, LABEL, 0, "UV Vertex:",10,55,300,19,0,0,0,0,0,"");
- uiBlockBeginAlign(block);
+ //uiBlockBeginAlign(block);
if(nactive==1) {
- uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 35, 290, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
- uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 10, 15, 290, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
+ uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
+ uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
}
else {
- uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 35, 290, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
- uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 10, 15, 290, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
+ uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
+ uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
}
- uiBlockEndAlign(block);
+ //uiBlockEndAlign(block);
}
}
else { // apply event
@@ -834,28 +1284,25 @@ void image_editvertex_buts(uiBlock *block)
delta[1]= ocent[1]/imy - cent[1];
}
- for (i=0; i<me->totface; i++) {
- MFace *mf= &((MFace*) me->mface)[i];
- MTFace *tf= &((MTFace*) me->mtface)[i];
-
- if (!(mf->flag & ME_FACE_SEL))
- continue;
-
- if (tf->flag & TF_SEL1) {
- tf->uv[0][0]+= delta[0];
- tf->uv[0][1]+= delta[1];
- }
- if (tf->flag & TF_SEL2) {
- tf->uv[1][0]+= delta[0];
- tf->uv[1][1]+= delta[1];
- }
- if (tf->flag & TF_SEL3) {
- tf->uv[2][0]+= delta[0];
- tf->uv[2][1]+= delta[1];
- }
- if (mf->v4 && (tf->flag & TF_SEL4)) {
- tf->uv[3][0]+= delta[0];
- tf->uv[3][1]+= delta[1];
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if (simaUVSel_Check(efa, tf, 0)) {
+ tf->uv[0][0]+= delta[0];
+ tf->uv[0][1]+= delta[1];
+ }
+ if (simaUVSel_Check(efa, tf, 1)) {
+ tf->uv[1][0]+= delta[0];
+ tf->uv[1][1]+= delta[1];
+ }
+ if (simaUVSel_Check(efa, tf, 2)) {
+ tf->uv[2][0]+= delta[0];
+ tf->uv[2][1]+= delta[1];
+ }
+ if (efa->v4 && simaUVSel_Check(efa, tf, 3)) {
+ tf->uv[3][0]+= delta[0];
+ tf->uv[3][1]+= delta[1];
+ }
}
}
@@ -864,6 +1311,46 @@ void image_editvertex_buts(uiBlock *block)
}
}
+
+/* is used for both read and write... */
+void image_editcursor_buts(uiBlock *block)
+{
+ static float ocent[2];
+ int imx= 256, imy= 256;
+ int step, digits;
+
+ if( is_uv_tface_editing_allowed_silent()==0 ) return;
+
+ image_transform_but_attr(&imx, &imy, &step, &digits);
+
+ if(block) { // do the buttons
+ ocent[0]= G.v2d->cursor[0];
+ ocent[1]= G.v2d->cursor[1];
+ if (G.sima->flag & SI_COORDFLOATS) {
+ } else {
+ ocent[0] *= imx;
+ ocent[1] *= imy;
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor X:", 165, 120, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
+ uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor Y:", 165, 100, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, "");
+ uiBlockEndAlign(block);
+ }
+ else { // apply event
+ if (G.sima->flag & SI_COORDFLOATS) {
+ G.v2d->cursor[0]= ocent[0];
+ G.v2d->cursor[1]= ocent[1];
+ }
+ else {
+ G.v2d->cursor[0]= ocent[0]/imx;
+ G.v2d->cursor[1]= ocent[1]/imy;
+ }
+ allqueue(REDRAWIMAGE, 0);
+ }
+}
+
+
void image_info(Image *ima, ImBuf *ibuf, char *str)
{
int ofs= 0;
@@ -913,12 +1400,11 @@ static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES
block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES); // for close and esc
- if(uiNewPanel(curarea, block, "Properties", "Image", 10, 10, 318, 204)==0)
+ if(uiNewPanel(curarea, block, "Image Properties", "Image", 10, 10, 318, 204)==0)
return;
/* note, it draws no bottom half in facemode, for vertex buttons */
uiblock_image_panel(block, &G.sima->image, &G.sima->iuser, B_REDR, B_REDR);
-
image_editvertex_buts(block);
}
@@ -947,18 +1433,76 @@ static void image_panel_game_properties(short cntrl) // IMAGE_HANDLER_GAME_PROPE
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, IMA_TILES, B_SIMAGEDRAW1, "Tiles", 160,150,140,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of tilemode for faces");
- uiDefButS(block, NUM, B_SIMAGEDRAW, "X:", 160,130,70,19, &G.sima->image->xrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the X direction");
- uiDefButS(block, NUM, B_SIMAGEDRAW, "Y:", 230,130,70,19, &G.sima->image->yrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the Y direction");
+ uiDefButBitS(block, TOG, IMA_TILES, B_SIMAGETILE, "Tiles", 160,150,140,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of tilemode for faces (Shift LMB to pick the tile for selected faces)");
+ uiDefButS(block, NUM, B_SIMA_REDR_IMA_3D, "X:", 160,130,70,19, &G.sima->image->xrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the X direction");
+ uiDefButS(block, NUM, B_SIMA_REDR_IMA_3D, "Y:", 230,130,70,19, &G.sima->image->yrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the Y direction");
uiBlockBeginAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, IMA_CLAMP_U, B_SIMAGEDRAW, "ClampX", 160,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating horizontaly");
- uiDefButBitS(block, TOG, IMA_CLAMP_V, B_SIMAGEDRAW, "ClampY", 230,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating vertically");
- uiBlockEndAlign(block);
+ uiDefButBitS(block, TOG, IMA_CLAMP_U, B_SIMA3DVIEWDRAW, "ClampX", 160,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating horizontaly");
+ uiDefButBitS(block, TOG, IMA_CLAMP_V, B_SIMA3DVIEWDRAW, "ClampY", 230,100,70,19, &G.sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating vertically");
+ uiBlockEndAlign(block);
}
}
+//static void image_panel_transform_properties(short cntrl) // IMAGE_HANDLER_TRANSFORM_PROPERTIES
+//{
+// uiBlock *block;
+//
+// block= uiNewBlock(&curarea->uiblocks, "image_transform_properties", UI_EMBOSS, UI_HELV, curarea->win);
+// uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+// uiSetPanelHandler(IMAGE_HANDLER_TRANSFORM_PROPERTIES); // for close and esc
+// if(uiNewPanel(curarea, block, "Transform Properties", "Image", 10, 10, 318, 204)==0)
+// return;
+//
+// image_editvertex_buts(block);
+//}
+
+static void image_panel_view_properties(short cntrl) // IMAGE_HANDLER_VIEW_PROPERTIES
+{
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "image_view_properties", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(IMAGE_HANDLER_VIEW_PROPERTIES); // for close and esc
+ if(uiNewPanel(curarea, block, "View Properties", "Image", 10, 10, 318, 204)==0)
+ return;
+
+
+ uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &G.sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display");
+ uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &G.sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels");
+
+
+ if (G.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, &G.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, &G.sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables.");
+ uiBlockEndAlign(block);
+ }
+
+
+ if (EM_texFaceCheck()) {
+ uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 60,120,19, 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButC(block, ROW, B_REDR, "Dash", 10, 40,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype");
+ uiDefButC(block, ROW, B_REDR, "Black", 68, 40,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype");
+ uiDefButC(block, ROW, B_REDR, "White", 126,40,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype");
+ uiDefButC(block, ROW, B_REDR, "Outline", 184,40,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype");
+ uiBlockEndAlign(block);
+ uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,40,60,19, &G.sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view");
+
+ uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &G.sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)");
+
+ uiBlockBeginAlign(block);
+ uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &G.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, &G.sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords");
+ uiBlockEndAlign(block);
+
+ }
+ image_editcursor_buts(block);
+}
+
static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PAINT
{
/* B_SIMABRUSHCHANGE only redraws and eats the mouse messages */
@@ -1088,7 +1632,7 @@ static void image_panel_curves(short cntrl) // IMAGE_HANDLER_CURVES
rect.xmin= 110; rect.xmax= 310;
rect.ymin= 10; rect.ymax= 200;
- curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_SIMAGEDRAW, &rect);
+ curvemap_buttons(block, G.sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect);
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, G.sima->cumap, ibuf);
@@ -1272,6 +1816,13 @@ static void image_blockhandlers(ScrArea *sa)
case IMAGE_HANDLER_GAME_PROPERTIES:
image_panel_game_properties(sima->blockhandler[a+1]);
break;
+// case IMAGE_HANDLER_TRANSFORM_PROPERTIES:
+// if (EM_texFaceCheck())
+// image_panel_transform_properties(sima->blockhandler[a+1]);
+// break;
+ case IMAGE_HANDLER_VIEW_PROPERTIES:
+ image_panel_view_properties(sima->blockhandler[a+1]);
+ break;
case IMAGE_HANDLER_PAINT:
image_panel_paint(sima->blockhandler[a+1]);
break;
@@ -1395,44 +1946,26 @@ static void imagespace_grid(SpaceImage *sima)
static void sima_draw_alpha_backdrop(SpaceImage *sima, float x1, float y1, float xsize, float ysize)
{
- float tile= sima->zoom*15.0f;
- float x, y, maxx, maxy;
+ GLubyte checker_stipple[32*32/8] =
+ {
+ 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
+ 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
+ 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
+ 255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0, \
+ 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
+ 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
+ 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
+ 0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255, \
+ };
glColor3ub(100, 100, 100);
glRectf(x1, y1, x1 + sima->zoom*xsize, y1 + sima->zoom*ysize);
glColor3ub(160, 160, 160);
-
- maxx= x1+sima->zoom*xsize;
- maxy= y1+sima->zoom*ysize;
-
- for(x=0; x<xsize; x+=30) {
- for(y=0; y<ysize; y+=30) {
- float fx= x1 + sima->zoom*x;
- float fy= y1 + sima->zoom*y;
- float tilex= tile, tiley= tile;
-
- if(fx+tile > maxx)
- tilex= maxx-fx;
- if(fy+tile > maxy)
- tiley= maxy-fy;
-
- glRectf(fx, fy, fx + tilex, fy + tiley);
- }
- }
- for(x=15; x<xsize; x+=30) {
- for(y=15; y<ysize; y+=30) {
- float fx= x1 + sima->zoom*x;
- float fy= y1 + sima->zoom*y;
- float tilex= tile, tiley= tile;
-
- if(fx+tile > maxx)
- tilex= maxx-fx;
- if(fy+tile > maxy)
- tiley= maxy-fy;
-
- glRectf(fx, fy, fx + tilex, fy + tiley);
- }
- }
+
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(checker_stipple);
+ glRectf(x1, y1, x1 + sima->zoom*xsize, y1 + sima->zoom*ysize);
+ glDisable(GL_POLYGON_STIPPLE);
}
static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti)
@@ -1525,10 +2058,10 @@ static void sima_draw_zbuffloat_pixels(float x1, float y1, int rectx, int recty,
static void imagewindow_draw_renderinfo(ScrArea *sa)
{
- SpaceImage *sima= sa->spacedata.first;
rcti rect;
float colf[3];
- char *str= sima->showspare?sima->info_spare:sima->info_str;
+ int showspare= BIF_show_render_spare();
+ char *str= BIF_render_text();
if(str==NULL)
return;
@@ -1545,7 +2078,7 @@ static void imagewindow_draw_renderinfo(ScrArea *sa)
BIF_ThemeColor(TH_TEXT_HI);
glRasterPos2i(12, 5);
- if(sima->showspare) {
+ if(showspare) {
BMF_DrawString(G.fonts, "(Previous)");
glRasterPos2i(72, 5);
}
@@ -1561,16 +2094,16 @@ void drawimagespace(ScrArea *sa, void *spacedata)
unsigned int *rect;
float x1, y1;
short sx, sy, dx, dy, show_render= 0, show_viewer= 0;
-
+ float xuser_asp, yuser_asp;
/* If derived data is used then make sure that object
* is up-to-date... might not be the case because updates
* are normally done in drawview and could get here before
* drawing a View3D.
*/
- if (!G.obedit && OBACT && (sima->flag & SI_DRAWSHADOW)) {
+ if (G.obedit && OBACT && (sima->flag & SI_DRAWSHADOW)) {
object_handle_update(OBACT);
}
-
+
BIF_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -1585,6 +2118,8 @@ void drawimagespace(ScrArea *sa, void *spacedata)
}
what_image(sima);
+ aspect_sima(sima, &xuser_asp, &yuser_asp);
+
if(sima->image) {
/* UGLY hack? until now iusers worked fine... but for flipbook viewer we need this */
@@ -1601,8 +2136,10 @@ void drawimagespace(ScrArea *sa, void *spacedata)
if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
imagespace_grid(sima);
- if(show_viewer==0)
- draw_tfaces();
+ if(show_viewer==0) {
+ draw_uvs_sima();
+ drawcursor_sima(xuser_asp, yuser_asp);
+ }
}
else {
float xim, yim, xoffs=0.0f, yoffs= 0.0f;
@@ -1617,7 +2154,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
glLoadIdentity();
}
else {
- xim= ibuf->x; yim= ibuf->y;
+ xim= ibuf->x * xuser_asp; yim= ibuf->y * yuser_asp;
}
/* calc location */
@@ -1638,9 +2175,13 @@ void drawimagespace(ScrArea *sa, void *spacedata)
}
else glaDefine2DArea(&sa->winrct);
- glPixelZoom((float)sima->zoom, (float)sima->zoom);
+ glPixelZoom(sima->zoom * xuser_asp, sima->zoom * yuser_asp);
if(sima->flag & SI_EDITTILE) {
+ /* create char buffer from float if needed */
+ if(ibuf->rect_float && ibuf->rect==NULL)
+ IMB_rect_from_float(ibuf);
+
glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glPixelZoom(1.0, 1.0);
@@ -1681,6 +2222,10 @@ void drawimagespace(ScrArea *sa, void *spacedata)
sx*= dx;
sy*= dy;
+ /* create char buffer from float if needed */
+ if(ibuf->rect_float && ibuf->rect==NULL)
+ IMB_rect_from_float(ibuf);
+
rect= get_part_from_ibuf(ibuf, sx, sy, sx+dx, sy+dy);
/* rect= ibuf->rect; */
@@ -1693,52 +2238,93 @@ void drawimagespace(ScrArea *sa, void *spacedata)
MEM_freeN(rect);
}
else {
- /* this part is generic image display */
- if(sima->flag & SI_SHOW_ALPHA) {
- if(ibuf->rect)
- sima_draw_alpha_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect);
- else if(ibuf->rect_float && ibuf->channels==4)
- sima_draw_alpha_pixelsf(x1, y1, ibuf->x, ibuf->y, ibuf->rect_float);
- }
- else if(sima->flag & SI_SHOW_ZBUF) {
- if(ibuf->zbuf)
- sima_draw_zbuf_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf);
- else if(ibuf->zbuf_float)
- sima_draw_zbuffloat_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf_float);
- else if(ibuf->channels==1)
- sima_draw_zbuffloat_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect_float);
+ float x1_rep, y1_rep;
+ int x_rep, y_rep;
+ double time_current;
+ short loop_draw_ok = 0;
+
+ if (sima->flag & SI_DRAW_TILE) {
+ loop_draw_ok= 1;
}
- else {
- if(sima->flag & SI_USE_ALPHA) {
- sima_draw_alpha_backdrop(sima, x1, y1, (float)ibuf->x, (float)ibuf->y);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- /* detect if we need to redo the curve map.
- ibuf->rect is zero for compositor and render results after change
- convert to 32 bits always... drawing float rects isnt supported well (atis)
-
- NOTE: if float buffer changes, we have to manually remove the rect
- */
-
- if(ibuf->rect_float) {
- if(ibuf->rect==NULL) {
- if(image_curves_active(sa))
- curvemapping_do_ibuf(G.sima->cumap, ibuf);
- else
- IMB_rect_from_float(ibuf);
+
+ time_current = PIL_check_seconds_timer();
+
+ for (x_rep= ((int)G.v2d->cur.xmin)-1; x_rep < G.v2d->cur.xmax; x_rep++) {
+ x1_rep=x1+ ((x_rep* ibuf->x * sima->zoom) *xuser_asp);
+ for (y_rep= ((int)G.v2d->cur.ymin)-1; y_rep < G.v2d->cur.ymax; y_rep++) {
+ y1_rep=y1+ ((y_rep * ibuf->y *sima->zoom) *yuser_asp);
+
+ /* end repeating image loop */
+
+ if(!loop_draw_ok) {
+ y1_rep = y1;
+ x1_rep = x1;
+ }
+
+ /*printf("Drawing %d %d zoom:%.6f (%.6f %.6f), (%.6f %.6f)\n", x_rep, y_rep, sima->zoom, G.v2d->cur.xmin, G.v2d->cur.ymin, G.v2d->cur.xmax, G.v2d->cur.ymax);*/
+
+ /* this part is generic image display */
+ if(sima->flag & SI_SHOW_ALPHA) {
+ if(ibuf->rect)
+ sima_draw_alpha_pixels(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->rect);
+ else if(ibuf->rect_float && ibuf->channels==4)
+ sima_draw_alpha_pixelsf(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->rect_float);
+ }
+ else if(sima->flag & SI_SHOW_ZBUF && ((ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels==1)) == 0)) {
+ if(ibuf->zbuf)
+ sima_draw_zbuf_pixels(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->zbuf);
+ else if(ibuf->zbuf_float)
+ sima_draw_zbuffloat_pixels(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->zbuf_float);
+ else if(ibuf->channels==1)
+ sima_draw_zbuffloat_pixels(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->rect_float);
+ }
+ else {
+ if(sima->flag & SI_USE_ALPHA) {
+ sima_draw_alpha_backdrop(sima, x1_rep, y1_rep, ibuf->x*xuser_asp, ibuf->y*yuser_asp);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ /* detect if we need to redo the curve map.
+ ibuf->rect is zero for compositor and render results after change
+ convert to 32 bits always... drawing float rects isnt supported well (atis)
+
+ NOTE: if float buffer changes, we have to manually remove the rect
+ */
+
+ if(ibuf->rect_float) {
+ if(ibuf->rect==NULL) {
+ if(image_curves_active(sa))
+ curvemapping_do_ibuf(G.sima->cumap, ibuf);
+ else
+ IMB_rect_from_float(ibuf);
+ }
+ }
+
+ if(ibuf->rect)
+ glaDrawPixelsSafe(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ // else
+ // glaDrawPixelsSafe(x1_rep, y1_rep, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
+
+ if(sima->flag & SI_USE_ALPHA)
+ glDisable(GL_BLEND);
+ }
+
+ /* only draw once */
+ if(!loop_draw_ok) {
+ break; /* only draw once */
+ } else if ((PIL_check_seconds_timer() - time_current) > 0.25) {
+ loop_draw_ok = 0;
+ break;
}
+
+ /* tile draw loop */
}
-
- if(ibuf->rect)
- glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
-// else
-// glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
-
- if(sima->flag & SI_USE_ALPHA)
- glDisable(GL_BLEND);
+ /* only draw once */
+ if(!loop_draw_ok) break;
}
+ /* tile draw loop */
+
}
brush= G.scene->toolsettings->imapaint.brush;
@@ -1766,8 +2352,10 @@ void drawimagespace(ScrArea *sa, void *spacedata)
glPixelZoom(1.0, 1.0);
- if(show_viewer==0)
- draw_tfaces();
+ if(show_viewer==0) {
+ draw_uvs_sima();
+ drawcursor_sima(xuser_asp, yuser_asp);
+ }
}
glPixelZoom(1.0, 1.0);
@@ -1775,7 +2363,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
calc_image_view(sima, 'f'); /* float */
}
- draw_image_transform(ibuf);
+ draw_image_transform(ibuf, xuser_asp, yuser_asp);
mywinset(sa->win); /* restore scissor after gla call... */
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
@@ -1820,7 +2408,7 @@ static void image_zoom_set_factor(float zoomfac)
/* check zoom limits */
- calc_image_view(G.sima, 'p');
+ calc_image_view(G.sima, 'f'); /* was 'p' are there any cases where this should be 'p'?*/
width= 256;
height= 256;
if (sima->image) {
@@ -1970,14 +2558,15 @@ void image_home(void)
G.sima->xof= G.sima->yof= 0.0f;
- calc_image_view(G.sima, 'p');
-
+ calc_image_view(G.sima, 'f'); /* was 'p' are there any cases where this should be 'p'?*/
+ /*calc_arearcts(curarea);*/
+ scrarea_queue_winredraw(curarea);
scrarea_queue_winredraw(curarea);
}
void image_viewcenter(void)
{
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
float size, min[2], max[2], d[2], xim=256.0f, yim=256.0f;
if( is_uv_tface_editing_allowed()==0 ) return;
@@ -2000,7 +2589,7 @@ void image_viewcenter(void)
G.sima->zoom= 0.7/size;
- calc_image_view(G.sima, 'p');
+ calc_image_view(G.sima, 'f'); /* was 'p' are there any cases where 'p' is still needed? */
scrarea_queue_winredraw(curarea);
}
@@ -2072,7 +2661,7 @@ static void imagewindow_progress(ScrArea *sa, RenderResult *rr, volatile rcti *r
/* needed for gla draw */
{ rcti rct= sa->winrct; rct.ymax-= RW_HEADERY; glaDefine2DArea(&rct);}
- glPixelZoom((float)sima->zoom, (float)sima->zoom);
+ glPixelZoom(sima->zoom, sima->zoom);
if(rect32)
glaDrawPixelsSafe(x1, y1, xmax, ymax, rr->rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect32);
@@ -2105,20 +2694,31 @@ static void imagewindow_clear_display_cb(RenderResult *rr)
}
}
+/* returns biggest area that is not uv/image editor. Note that it uses buttons */
+/* window as the last possible alternative. */
static ScrArea *biggest_non_image_area(void)
{
ScrArea *sa, *big= NULL;
- int size, maxsize= 0;
+ int size, maxsize= 0, bwmaxsize= 0;
+ short foundwin= 0;
for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype!=SPACE_IMAGE) {
+ if(sa->winx > 10 && sa->winy > 10) {
size= sa->winx*sa->winy;
- if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
+ if(sa->spacetype == SPACE_BUTS) {
+ if(foundwin == 0 && size > bwmaxsize) {
+ bwmaxsize= size;
+ big= sa;
+ }
+ }
+ else if(sa->spacetype != SPACE_IMAGE && size > maxsize) {
maxsize= size;
big= sa;
+ foundwin= 1;
}
}
}
+
return big;
}
@@ -2220,9 +2820,6 @@ static void imagewindow_init_display_cb(RenderResult *rr)
areawinset(image_area->win);
- if(sima->info_str==NULL)
- sima->info_str= MEM_callocN(RW_MAXTEXT, "info str imagewin");
-
/* calc location using original size (tiles don't tell) */
sima->centx= (image_area->winx - sima->zoom*(float)rr->rectx)/2.0f;
sima->centy= (image_area->winy - sima->zoom*(float)rr->recty)/2.0f;
@@ -2232,7 +2829,9 @@ static void imagewindow_init_display_cb(RenderResult *rr)
drawimagespace(image_area, sima);
if(image_area->headertype) scrarea_do_headdraw(image_area);
- screen_swapbuffers();
+
+ /* no screen_swapbuffers, prevent any other window to draw */
+ myswapbuffers();
allqueue(REDRAWIMAGE, 0); /* redraw in end */
}
@@ -2268,10 +2867,7 @@ static void imagewindow_renderinfo_cb(RenderStats *rs)
{
if(image_area) {
- SpaceImage *sima= image_area->spacedata.first;
-
- if(rs)
- make_renderinfo_string(rs, sima->info_str);
+ BIF_make_render_text(rs);
imagewindow_draw_renderinfo(image_area);
@@ -2288,54 +2884,3 @@ void imagewindow_render_callbacks(Render *re)
RE_stats_draw_cb(re, imagewindow_renderinfo_cb);
}
-void imagewin_store_spare(void)
-{
- ScrArea *sa= find_area_showing_r_result();
-
- if(sa) {
- ImBuf *ibuf;
- SpaceImage *sima= sa->spacedata.first;
-
- if(sima->spare==NULL)
- return;
-
- /* only store when it does not show spare */
- if(sima->showspare==0)
- return;
- sima->showspare= 0;
-
- /* free spare */
- IMB_freeImBuf(sima->spare);
-
- /* make a copy of render result */
- ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
- sima->spare= IMB_dupImBuf(ibuf);
-
- if(sima->info_str)
- BLI_strncpy(sima->info_spare, sima->info_str, RW_MAXTEXT);
-
- }
-}
-
-/* context: in current image window? */
-void imagewindow_swap_render_rects(void)
-{
- ScrArea *sa= find_area_showing_r_result();
-
- if(sa) {
- SpaceImage *sima= sa->spacedata.first;
- ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
- if(ibuf) {
-
- sima->showspare ^= 1;
-
- if(sima->spare==NULL)
- sima->spare= IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0, 0);
- if(sima->info_spare==NULL)
- sima->info_spare= MEM_callocN(RW_MAXTEXT, "info str imagewin");
-
- allqueue(REDRAWIMAGE, 0);
- }
- }
-}
-
diff --git a/source/blender/src/drawimasel.c b/source/blender/src/drawimasel.c
index 45757170f78..6fa625592be 100644
--- a/source/blender/src/drawimasel.c
+++ b/source/blender/src/drawimasel.c
@@ -30,12 +30,6 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-#ifdef __sgi
-#define OLD_IMASEL 1
-#else
-#define OLD_IMASEL 0
-#endif
-
#include <string.h>
#ifdef HAVE_CONFIG_H
@@ -47,811 +41,627 @@
#endif
#include "MEM_guardedalloc.h"
-#include "BMF_Api.h"
-#include "BLI_blenlib.h"
-#include "IMB_imbuf_types.h"
+
+#include "DNA_ID.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_storage_types.h"
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+
#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_icons.h"
+#include "BKE_utildefines.h"
+#include "BIF_filelist.h"
-#include "BIF_fsmenu.h"
#include "BIF_gl.h"
-#include "BIF_resources.h"
+#include "BIF_glutil.h"
+#include "BIF_mywindow.h"
#include "BIF_screen.h"
+#include "BIF_resources.h"
+#include "BIF_language.h"
+
#include "BIF_interface.h"
#include "BIF_interface_icons.h"
-#include "BIF_imasel.h"
-#include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
+#include "BIF_fsmenu.h"
#include "BIF_space.h"
-#include "BIF_resources.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "BSE_drawimasel.h"
-#include "BSE_filesel.h"
+#include "BSE_drawipo.h" /* for v2d functions */
+#include "BSE_view.h"
-#include "blendef.h"
-#include "mydevice.h"
+#include "BLO_readfile.h"
-#define IMALINESIZE 16
-/* well, who would have thought ... */
-#define lrectwrite(a, b, c, d, rect) {glRasterPos2i(a, b);glDrawPixels((c)-(a)+1, (d)-(b)+1, GL_RGBA, GL_UNSIGNED_BYTE, rect);}
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
-/* GLOBALS */
-extern char *fsmenu;
+#include "PIL_time.h"
-void rectwrite_imasel(int , int , int , int , int , int , int , int , float , float , unsigned int *);
+#include "blendef.h"
+#include "mydevice.h"
-void rectwrite_imasel(int winxmin, int winymin, int winxmax, int winymax, int x1, int y1, int xim, int yim, float zoomx, float zoomy, unsigned int *rect)
-{
- int cx, cy, oldxim, x2, y2;
-
- oldxim= xim;
-
- /* coordinates how it will be put at screen */
- x2= x1+ zoomx*xim;
- y2= y1+ zoomy*yim;
-
- /* partial clip */
- if(x1<=winxmin) {
- /* with OpenGL, rects are not allowed to start outside of the left/bottom window edge */
- cx= winxmin-x1+(int)zoomx;
- /* make sure the rect will be drawn pixel-exact */
- cx/= zoomx;
- cx++;
- x1+= zoomx*cx;
- xim-= cx;
- rect+= cx;
+#include "interface.h" /* urm... for rasterpos_safe, roundbox */
+
+#define BUTTONWIDTH 20
+#define BOOKMARKWIDTH_MAX 240
+
+void calc_imasel_rcts(SpaceImaSel *simasel, int winx, int winy)
+{
+ int width = (int)16.0f*simasel->aspect;
+ int numtiles;
+ int numfiles = 0;
+ int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+ int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+
+ // complete area of the space
+ simasel->v2d.mask.xmin= simasel->v2d.mask.ymin = 0;
+ simasel->v2d.mask.xmax= winx;
+ simasel->v2d.mask.ymax= winy;
+
+ // vertical scroll bar
+ simasel->v2d.vert= simasel->v2d.mask;
+ simasel->v2d.vert.xmax -= TILE_BORDER_X + 2;
+ simasel->v2d.vert.xmin= simasel->v2d.vert.xmax- width - TILE_BORDER_X - 2;
+ simasel->v2d.vert.ymax -= IMASEL_BUTTONS_HEIGHT + TILE_BORDER_Y + 2;
+ simasel->v2d.vert.ymin += TILE_BORDER_Y + 2;
+ // simasel->v2d.mask.xmax= simasel->v2d.vert.xmin;
+
+ if ((simasel->flag & FILE_BOOKMARKS) && (simasel->type != FILE_MAIN)) {
+ int bmwidth = (simasel->v2d.vert.xmin - simasel->v2d.mask.xmin)/4.0f;
+ if (bmwidth > BOOKMARKWIDTH_MAX) bmwidth = BOOKMARKWIDTH_MAX;
+
+ simasel->bookmarkrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
+ simasel->bookmarkrect.xmax = simasel->v2d.mask.xmin + bmwidth - TILE_BORDER_X;
+ simasel->bookmarkrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;
+ simasel->bookmarkrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;
+
+ simasel->viewrect.xmin = simasel->bookmarkrect.xmax + TILE_BORDER_X;
+ simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
+ simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;
+ simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;
+ } else {
+ simasel->viewrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
+ simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
+ simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;
+ simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;
}
- if(y1<=winymin) {
- cy= winymin-y1+(int)zoomy;
- cy/= zoomy;
- cy++;
- y1+= zoomy*cy;
- rect+= cy*oldxim;
- yim-= cy;
- }
- if(x2>=winxmax) {
- cx= x2-winxmax;
- cx/= zoomx;
- xim-= cx+3;
+
+ simasel->numtilesx = (simasel->viewrect.xmax - simasel->viewrect.xmin) / tilewidth;
+ simasel->numtilesy = (simasel->viewrect.ymax - simasel->viewrect.ymin) / tileheight;
+ numtiles = simasel->numtilesx*simasel->numtilesy;
+
+ if (simasel->files) {
+ numfiles = BIF_filelist_numfiles(simasel->files);
}
- if(y2>=winymax) {
- cy= y2-winymax;
- cy/= zoomy;
- yim-= cy+3;
+ if (numtiles > numfiles) numtiles = numfiles;
+
+ simasel->scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ if (numtiles < numfiles) {
+ simasel->scrollheight = ((float)numtiles / (float)numfiles)*simasel->scrollarea;
+ simasel->scrollarea -= simasel->scrollheight;
+ } else {
+ simasel->scrollheight = simasel->scrollarea;
}
-
- if(xim<=0) return;
- if(yim<=0) return;
+ if (simasel->scrollarea < 0) simasel->scrollarea = 0;
+}
-// mywinset(curarea->win);
- glScissor(winxmin, winymin, winxmax-winxmin+1, winymax-winymin+1);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, oldxim);
-
- glPixelZoom(zoomx, zoomy);
+void draw_imasel_scroll(SpaceImaSel *simasel)
+{
+ rcti scrollbar;
+ rcti scrollhandle;
- glRasterPos2i(x1, y1);
- glDrawPixels(xim, yim, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ scrollbar.xmin= simasel->v2d.cur.xmin + simasel->v2d.vert.xmin;
+ scrollbar.ymin = simasel->v2d.cur.ymin + simasel->v2d.vert.ymin;
+ scrollbar.xmax= simasel->v2d.cur.xmin + simasel->v2d.vert.xmax;
+ scrollbar.ymax = simasel->v2d.cur.ymin + simasel->v2d.vert.ymax;
- glPixelZoom(1.0, 1.0);
+ scrollhandle.xmin= scrollbar.xmin;
+ scrollhandle.ymin = scrollbar.ymax - simasel->scrollpos -1;
+ scrollhandle.xmax= scrollbar.xmax-1;
+ scrollhandle.ymax = scrollbar.ymax - simasel->scrollpos - simasel->scrollheight;
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-}
+ BIF_ThemeColor(TH_SHADE1);
+ glRecti(scrollbar.xmin, scrollbar.ymin, scrollbar.xmax, scrollbar.ymax);
+ uiEmboss(scrollbar.xmin-2, scrollbar.ymin-2, scrollbar.xmax+2, scrollbar.ymax+2, 1);
-void viewgate(short sx, short sy, short ex, short ey)
-{
- short wx, wy;
- wx = curarea->winrct.xmin; wy = curarea->winrct.ymin;
- glViewport(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1);
- glScissor(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1);
- myortho2((float)sx-0.375 , (float)ex-0.375, (float)sy-0.375, (float)ey-0.375);
-}
+ BIF_ThemeColor(TH_SHADE2);
+ glRecti(scrollhandle.xmin, scrollhandle.ymin, scrollhandle.xmax, scrollhandle.ymax);
-void areaview (void)
-{
- short wx, wy;
- wx = curarea->winrct.xmin; wy = curarea->winrct.ymin;
- glViewport(wx, wy, curarea->winx, curarea->winy);
- glScissor(wx, wy, curarea->winx, curarea->winy);
- myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375);
-
+ uiEmboss(scrollhandle.xmin, scrollhandle.ymin, scrollhandle.xmax, scrollhandle.ymax, 1);
}
-
-void calc_hilite(SpaceImaSel *simasel)
+
+static void draw_tile(SpaceImaSel *simasel, short sx, short sy, int colorid)
{
- OneSelectableIma *ima;
- ImaDir *direntry;
- short mx, my;
- int i, area_event;
-
- if (simasel->hilite > -1) {
- direntry = simasel->firstdir;
- while(direntry){
- direntry->hilite = 0;
- direntry = direntry->next;
- }
- simasel->hilite = -1;
- }
-
- if (simasel->totalima){
- simasel->hilite_ima = 0;
- ima = simasel->first_sel_ima;
- while (ima){
- ima->selectable = 0;
- ima = ima->next;
- }
- }
-
- area_event = 0;
- mx = simasel->mx;
- my = simasel->my;
-
- if (simasel->desx > 0){
- if ( (mx > simasel->desx) && (mx < simasel->deex) && (my > simasel->desy) && (my < simasel->deey) ) area_event = IMS_INDIR;
- }
- if (simasel->fesx > 0){
- if ( (mx > simasel->fesx) && (mx < simasel->feex) && (my > simasel->fesy) && (my < simasel->feey) ) area_event = IMS_INFILE;
- }
-
- switch(area_event){
- case IMS_INDIR:
- simasel->hilite = simasel->topdir + ((simasel->deey - my - 4) / IMALINESIZE);
-
- if (my >= simasel->deey) simasel->hilite = -1;
- if (simasel->hilite >= simasel->totaldirs) simasel->hilite = -1;
-
- if (simasel->hilite > -1){
- direntry = simasel->firstdir;
- for (i = simasel->hilite; i>0; i--){
- direntry = direntry->next;
- }
- direntry->hilite = 1;
-
- }
- simasel->mouse_move_redraw = 1;
- break;
-
- case IMS_INFILE:
- if (simasel->totalima){
- ima = simasel->first_sel_ima;
- while (ima){
- ima->selectable = 0;
-
- if (ima->draw_me) {
- if ((mx > ima->sx) && (mx < ima->sx+76) && (my > ima->sy-16) && (my < ima->sy+76)) {
- ima->selectable = 1;
- simasel->hilite_ima = ima;
- simasel->mouse_move_redraw = 1;
- }
- }
-
- ima = ima->next;
- }
- }
- break;
- }
+ /* TODO: BIF_ThemeColor seems to need this to show the color, not sure why? - elubie */
+ glEnable(GL_BLEND);
+ glColor4ub(0, 0, 0, 100);
+ glDisable(GL_BLEND);
+
+ BIF_ThemeColor4(colorid);
+ uiSetRoundBox(15);
+ uiRoundBox(sx+TILE_BORDER_X, sy - simasel->prv_h - TILE_BORDER_Y*3 - U.fontsize, sx + simasel->prv_w + TILE_BORDER_X*3, sy, 6);
}
-
-void make_sima_area(SpaceImaSel *simasel)
-{
- OneSelectableIma *ima;
- short rh, dm, sc;
- short boxperline, boxlines, boxlinesinview, boxlinesleft;
-
-/* ima slider box */
- simasel->fssx = 8;
- simasel->fssy = 8;
- simasel->fsex = 30;
- simasel->fsey = curarea->winy-64;
-/* ima entry's box */
- simasel->fesx = simasel->fsex + 8;
- simasel->fesy = simasel->fssy;
- simasel->feex = curarea->winx- 8;
- simasel->feey = curarea->winy-64;
-/* ima names */
- simasel->dnsx = 38;
- simasel->dnsy = curarea->winy - 29;
- simasel->dnw = curarea->winx - 8 - 38;
- simasel->dnh = 21;
- simasel->fnsx = simasel->fesx;
- simasel->fnsy = curarea->winy - 29 - 29;
- simasel->fnw = curarea->winx - 8 - simasel->fnsx;
- simasel->fnh = 21;
-
- if ((simasel->mode & 1)==1){
- /* dir slider box */
- simasel->dssx = 8;
-
- simasel->dsex = 30;
- simasel->dsey = curarea->winy-64;
- /* dir entry's box */
- simasel->desx = 38;
- simasel->desy = 8;
-
- simasel->deex = 208;
- simasel->deey = curarea->winy-64;
- simasel->dssy = simasel->desy;
- if (simasel->deex > (curarea->winx -8) ) simasel->deex = curarea->winx - 8;
- if (simasel->deex <= simasel->desx ) simasel->dssx = 0;
- /* file slider & entry & name box ++ */
- simasel->fssx += 216;
- simasel->fsex += 216;
- simasel->fesx += 216;
- simasel->fnsx += 216;
- simasel->fnw -= 216;
- }else{
- simasel->desx = 0;
- }
-
- if ((simasel->mode & 2) == 2){
- simasel->fesy += 32;
- simasel->infsx = simasel->fesx; simasel->infsy = 8;
- simasel->infex = simasel->feex; simasel->infey = 28;
- }else{
- simasel->infsx = 0;
- }
-
- simasel->dsdh = simasel->deey - simasel->desy - 4;
-
- if (simasel->dsdh <= 16) { simasel->desx = 0; }
- if ((simasel->feex-16) <= simasel->fesx) { simasel->fesx = 0; }
- if ((simasel->infex-16) <= simasel->infsx) { simasel->infsx = 0; }
-
- if ((simasel->deey ) <= simasel->desy) { simasel->desx = 0; }
- if ((simasel->feey ) <= simasel->fesy) { simasel->fesx = 0; }
- if ((simasel->infey ) > simasel->feey) { simasel->infsx = 0;}
-
- /* Dir Slider */
- if (simasel->desx != 0){
- simasel->dirsli = 0;
-
- simasel->dirsli_lines = (simasel->dsdh / IMALINESIZE);
- simasel->dirsli_h = 0;
-
- if (simasel->topdir < 0) simasel->topdir = 0;
- if (simasel->topdir > (simasel->totaldirs - simasel->dirsli_lines) ) simasel->topdir = (simasel->totaldirs - simasel->dirsli_lines);
-
- if ( (simasel->totaldirs * IMALINESIZE) >= simasel->dsdh ){
- simasel->dirsli = 1;
- simasel->dirsli_sx = simasel->dssx+2;
- simasel->dirsli_ex = simasel->dsex-2;
-
- simasel->dirsli_h = (simasel->dsdh) * (float)simasel->dirsli_lines / (float)simasel->totaldirs;
- simasel->dirsli_ey = simasel->dsey - 2;
- if (simasel->topdir) {
- rh = (simasel->dsdh - simasel->dirsli_h);
- simasel->dirsli_ey -= rh * (float)((float)simasel->topdir / (float)(simasel->totaldirs - simasel->dirsli_lines ));
- }
-
- if (simasel->dirsli_h < 4) simasel->dirsli_h = 4;
-
- }else{
- simasel->topdir = 0;
- }
+static float shorten_string(SpaceImaSel *simasel, char* string, float w)
+{
+ short shortened = 0;
+ float sw = 0;
+
+ sw = BIF_GetStringWidth(simasel->curfont, string, 0);
+ while (sw>w) {
+ int slen = strlen(string);
+ string[slen-1] = '\0';
+ sw = BIF_GetStringWidth(simasel->curfont, string, 0);
+ shortened = 1;
}
-
- if (simasel->totalima){
- /* there are images */
-
- ima = simasel->first_sel_ima;
-
-
- boxperline = (simasel->feex - simasel->fesx) / 80;
- if (boxperline) boxlines = 1 + (simasel->totalima / boxperline); else boxlines = 1;
- boxlinesinview = (simasel->feey - simasel->fesy) / 100;
- boxlinesleft = boxlines - boxlinesinview;
-
- if (boxlinesleft > 0){
- /* slider needed */
-
- simasel->slider_height = boxlinesinview / (float)(boxlines+1);
- simasel->slider_space = 1.0 - simasel->slider_height;
-
- simasel->imasli_sx = simasel->fssx+1;
- simasel->imasli_ex = simasel->fsex-1;
- simasel->fsdh = simasel->fsey - simasel->fssy - 4;
-
- simasel->imasli_h = simasel->fsdh * simasel->slider_height;
- if (simasel->imasli_h < 6) simasel->imasli_h = 6;
- simasel->imasli_ey = simasel->fsey - 2 - (simasel->fsdh * simasel->slider_space * simasel->image_slider);
-
- simasel->imasli = 1;
-
- }else{
- simasel->image_slider = 0;
- simasel->imasli = 0;
- }
-
- sc = simasel->image_slider * (boxlinesleft * 100);
-
- simasel->curimax = simasel->fesx + 8;
- simasel->curimay = simasel->feey - 90 + sc;
-
- dm = 1;
- if (simasel->curimay-2 < simasel->fesy) dm = 0;
- // let first row of icons remain selectable
- if(OLD_IMASEL) if (simasel->curimay+80 > simasel->feey) dm = 0;
- if (simasel->curimax+72 > simasel->feex) dm = 0;
-
- simasel->total_selected = 0;
- while (ima){
- ima->draw_me = dm;
-
- if (ima->selected) simasel->total_selected++;
-
- ima->sx = simasel->curimax;
- ima->sy = simasel->curimay+16;
-
- ima->ex = ima->sx + ima->dw;
- ima->ey = ima->sy + ima->dh;
-
- simasel->curimax += 80;
- if (simasel->curimax + 72 > simasel->feex){
-
- simasel->curimax = simasel->fesx + 8;
- simasel->curimay -= 100;
-
- dm = 1;
- // let icons that fall off (top/bottom) be selectable
- if(OLD_IMASEL) {
- if (simasel->curimay+80 > simasel->feey) dm = 0;
- if (simasel->curimay-8 < simasel->fesy) dm = 0;
- }
-
- }
- ima = ima->next;
+ if (shortened) {
+ int slen = strlen(string);
+ if (slen > 3) {
+ BLI_strncpy(string+slen-3, "...", 4);
}
}
+ return sw;
}
-static void str_image_type(int ftype, char *name)
+static void draw_file(SpaceImaSel *simasel, short sx, short sy, struct direntry *file)
{
- strcpy(name, "");
-
- if((ftype & JPG_MSK) == JPG_STD) strcat(name, "std ");
- if((ftype & JPG_MSK) == JPG_VID) strcat(name, "video ");
- if((ftype & JPG_MSK) == JPG_JST) strcat(name, "amiga ");
- if((ftype & JPG_MSK) == JPG_MAX) strcat(name, "max ");
-
- if( ftype == AN_hamx) { strcat(name, "hamx "); return; }
+ short soffs;
+ char fname[FILE_MAXFILE];
+ float sw;
+
+ BLI_strncpy(fname,file->relname, FILE_MAXFILE);
+ sw = shorten_string(simasel, fname, simasel->prv_w );
+ soffs = (simasel->prv_w + TILE_BORDER_X*4 - sw) / 2;
- if( ftype == IMAGIC ) { strcat(name, "sgi "); return; }
- if( ftype & JPG ) { strcat(name, "jpeg "); }
- if( ftype & TGA ) { strcat(name, "targa "); }
- if( ftype & PNG ) { strcat(name, "png "); }
- if( ftype & BMP ) { strcat(name, "bmp "); }
- if( ftype & AMI ) { strcat(name, "iff "); }
-#ifdef WITH_QUICKTIME
- if( ftype & QUICKTIME ) { strcat(name, "quicktime "); }
+ ui_rasterpos_safe(sx+soffs, sy - simasel->prv_h - TILE_BORDER_Y*2 - U.fontsize, simasel->aspect);
+#ifdef WIN32
+ BIF_DrawString(simasel->curfont, fname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
+#else
+ BIF_DrawString(simasel->curfont, fname, (U.transopts & USER_TR_MENUS));
#endif
}
-void draw_sima_area(SpaceImaSel *simasel)
-{
- uiBlock *block;
- OneSelectableIma *ima;
- ImaDir *direntry;
- float col[3];
- int i, info;
- short sx, sy, ex, ey, sc;
- char naam[256], infostr[256];
-
- BIF_GetThemeColor3fv(TH_BACK, col);
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- sprintf(naam, "win %d", curarea->win);
- block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->win);
- uiBlockSetCol(block, TH_BUT_SETTING1);
-
- if (simasel->desx > 0){
- /* DIR ENTRYS */
- BIF_ThemeColorShade(TH_SHADE1, -70);
- glRecti(simasel->dssx, simasel->dssy, simasel->dsex, simasel->dsey);
- glRecti(simasel->desx, simasel->desy, simasel->deex, simasel->deey);
-
- uiEmboss(simasel->dssx, simasel->dssy, simasel->dsex, simasel->dsey,1);
- uiEmboss(simasel->desx, simasel->desy, simasel->deex, simasel->deey,1);
+static void draw_imasel_bookmarks(ScrArea *sa, SpaceImaSel *simasel)
+{
+ char bookmark[FILE_MAX];
+ float sw;
+
+ if ((simasel->flag & FILE_BOOKMARKS) && (simasel->type != FILE_MAIN)) {
+ int nentries = fsmenu_get_nentries();
+ int i;
+ short sx, sy;
+ int bmwidth;
+ int linestep = U.fontsize*3/2;
- if (simasel->dirsli == 1) {
- sx = simasel->dirsli_sx+2;
- sy = simasel->dirsli_ey - simasel->dirsli_h+2;
- ex = simasel->dirsli_ex-2;
- ey = simasel->dirsli_ey-2;
-
- BIF_ThemeColor(TH_SHADE1);
-
- glRecti(sx, sy, ex, ey);
- uiEmboss(sx, sy, ex,ey,0);
- }
- if (simasel->totaldirs) {
- sx = simasel->desx+8;
- sy = simasel->deey-IMALINESIZE;
+ sx = simasel->bookmarkrect.xmin + TILE_BORDER_X;
+ sy = simasel->bookmarkrect.ymax - TILE_BORDER_Y - linestep;
+ bmwidth = simasel->bookmarkrect.xmax - simasel->bookmarkrect.xmin - 2*TILE_BORDER_X;
+
+ if (bmwidth < 0) return;
+
+ for (i=0; i< nentries && sy > linestep ;++i) {
+ char *fname = fsmenu_get_entry(i);
+ char *sname = NULL;
- direntry = simasel->firstdir;
- if (simasel->topdir){
- for(i = simasel->topdir; i>0; i--){
- direntry = direntry->next;
- }
- }
- viewgate(simasel->desx, simasel->desy, simasel->deex-4, simasel->deey);
+ if (fname) {
+ int sl;
+ BLI_strncpy(bookmark, fname, FILE_MAX);
- i = simasel->dirsli_lines;
- if (i > simasel->totaldirs) i = simasel->totaldirs;
- for(;i > 0; i--){
- strcpy(naam, direntry->name);
-
- cpack(0xFFFFFF);
- if (direntry->selected == 1){
- cpack(0x7777CC);
- glRecti(simasel->desx+2, sy-4, simasel->deex-4, sy+IMALINESIZE-4);
- cpack(0xFFFFFF);
+ sl = strlen(bookmark)-1;
+ if (bookmark[sl] == '\\' || bookmark[sl] == '/') {
+ bookmark[sl] = '\0';
+ sl--;
}
- if (direntry->hilite == 1){
- cpack(0x999999);
- glRecti(simasel->desx+2, sy-4, simasel->deex-4, sy+IMALINESIZE-4);
- cpack(0xFFFFFF);
+ while (sl) {
+ if (bookmark[sl] == '\\' || bookmark[sl] == '/'){
+ sl++;
+ break;
+ };
+ sl--;
}
+ sname = &bookmark[sl];
+ sw = shorten_string(simasel, sname, bmwidth);
+
- glRasterPos2i(sx, sy);
- BMF_DrawString(G.font, naam);
-
- direntry = direntry->next;
- sy-=IMALINESIZE;
+ if (simasel->active_bookmark == i ) {
+ glEnable(GL_BLEND);
+ glColor4ub(0, 0, 0, 100);
+ glDisable(GL_BLEND);
+ BIF_ThemeColor(TH_HILITE);
+ uiSetRoundBox(15);
+ uiRoundBox(simasel->bookmarkrect.xmin + TILE_BORDER_X - 1, sy - linestep*0.25, simasel->bookmarkrect.xmax - TILE_BORDER_X + 1, sy + linestep*0.75, 6);
+ BIF_ThemeColor(TH_TEXT_HI);
+ } else {
+ BIF_ThemeColor(TH_TEXT);
+ }
+ ui_rasterpos_safe(sx, sy, simasel->aspect);
+#ifdef WIN32
+ BIF_DrawString(simasel->curfont, sname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
+#else
+ BIF_DrawString(simasel->curfont, sname, (U.transopts & USER_TR_MENUS));
+#endif
+ sy -= linestep;
+ } else {
+ cpack(0xB0B0B0);
+ sdrawline(sx, sy + U.fontsize/2 , sx + bmwidth, sy + U.fontsize/2);
+ cpack(0x303030);
+ sdrawline(sx, sy + 1 + U.fontsize/2 , sx + bmwidth, sy + 1 + U.fontsize/2);
+ sy -= linestep;
}
- areaview();
-
- }
-
- /* status icons */
-
- sx = simasel->desx;
- sy = simasel->deey+6;
-
- if (bitset(simasel->fase, IMS_FOUND_BIP)) {
- BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_HLT);
- } else if (bitset(simasel->fase, IMS_WRITE_NO_BIP)) {
- BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT);
- } else {
- BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT);
}
- if (bitset(simasel->fase, IMS_KNOW_INF)) {
- BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_HLT);
+ uiEmboss(simasel->bookmarkrect.xmin, simasel->bookmarkrect.ymin, simasel->bookmarkrect.xmax-1, simasel->bookmarkrect.ymax-1, 1);
+ }
+}
+
+static void draw_imasel_previews(ScrArea *sa, SpaceImaSel *simasel)
+{
+ static double lasttime= 0;
+ struct FileList* files = simasel->files;
+ int numfiles;
+ struct direntry *file;
+ int numtiles;
+
+ int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+ int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+ short sx, sy;
+ int do_load = 1;
+
+ ImBuf* imb=0;
+ int i,j;
+ short type;
+ int colorid = 0;
+ int todo;
+ int fileoffset, rowoffset, columnoffset;
+ float scrollofs;
+
+
+ rcti viewrect = simasel->viewrect;
+
+ if (!files) return;
+ /* Reload directory */
+ BLI_strncpy(simasel->dir, BIF_filelist_dir(files), FILE_MAXDIR);
+
+ type = BIF_filelist_gettype(simasel->files);
+
+ if (BIF_filelist_empty(files))
+ {
+ unsigned int filter = 0;
+ BIF_filelist_hidedot(simasel->files, simasel->flag & FILE_HIDE_DOT);
+ if (simasel->flag & FILE_FILTER) {
+ filter = simasel->filter ;
} else {
- BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_DEHLT);
+ filter = 0;
}
+
+ BIF_filelist_setfilter(simasel->files, filter);
+ BIF_filelist_readdir(files);
- if (bitset(simasel->fase, IMS_KNOW_IMA)) {
- BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_HLT);
- } else {
- BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_DEHLT);
- }
+ if(simasel->sort!=FILE_SORTALPHA) BIF_filelist_sort(simasel->files, simasel->sort);
}
-
- if (simasel->fesx > 0) {
- int extrabutsize;
-
- BIF_ThemeColorShade(TH_SHADE1, -80);
- glRecti(simasel->fssx, simasel->fssy, simasel->fsex, simasel->fsey);
+ BIF_filelist_imgsize(simasel->files,simasel->prv_w,simasel->prv_h);
- glRecti(simasel->fesx, simasel->fesy, simasel->feex, simasel->feey);
+ numfiles = BIF_filelist_numfiles(files);
+ numtiles = simasel->numtilesx*simasel->numtilesy;
- uiEmboss(simasel->fssx-1, simasel->fssy-1, simasel->fsex+1, simasel->fsey+1,1);
- uiEmboss(simasel->fesx-1, simasel->fesy-1, simasel->feex+1, simasel->feey+1,1);
-
- if (simasel->imasli == 1){
- sx = simasel->imasli_sx;
- sy = simasel->imasli_ey - simasel->imasli_h;
- ex = simasel->imasli_ex;
- ey = simasel->imasli_ey;
-
- BIF_ThemeColor(TH_SHADE1);
+ if (numtiles > numfiles) numtiles = numfiles;
+
+ todo = 0;
+ if (lasttime < 0.001) lasttime = PIL_check_seconds_timer();
- glRecti(sx, sy, ex, ey);
- uiEmboss(sx, sy, ex, ey, 1);
- }
- info = 0;
- strcpy(infostr, "");
- if (simasel->totalima){
- viewgate(simasel->fesx, simasel->fesy, simasel->feex, simasel->feey);
-
- ima = simasel->first_sel_ima;
-
- while (ima){
- sc = 0;
-
- sx = ima->sx- 6; sy = ima->sy-20 + sc;
- ex = ima->sx+71; ey = ima->sy+70 + sc;
-
- if(ima->selected == 1){
- cpack(0xCC6666);
- glRecti(sx, sy, ex, ey);
- }
- if(ima->selectable == 1){
- if (ima->selected ) cpack(0xEE8888); else cpack(0x999999);
-
- if (((simasel->mode & 8) != 8) && (simasel->hilite_ima == ima)){
- glRecti(sx, sy, ex, ey); uiEmboss(sx,sy, ex,ey, 1);
- }
- if (ima->disksize/1000 > 1000){ sprintf(infostr, "%s %.2fMb x%i y%i %i bits ",ima->file_name,(ima->disksize/1024)/1024.0, ima->orgx, ima->orgy, ima->orgd);
- }else{ sprintf(infostr, "%s %dKb %ix%i %i bits ", ima->file_name,ima->disksize/1024, ima->orgx, ima->orgy, ima->orgd);
- }
- if (ima->anim == 1){ strcat (infostr, "movie"); }else{
- str_image_type(ima->ibuf_type, naam);
- strcat (infostr, naam);
- }
- info = 1;
+ if (simasel->numtilesx > 0) {
+ /* calculate the offset to start drawing */
+ if ((numtiles < numfiles) && (simasel->scrollarea > 0)) {
+ fileoffset = numfiles*( (simasel->scrollpos) / simasel->scrollarea) + 0.5;
+ } else {
+ fileoffset = 0;
+ }
+ rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx;
+ columnoffset = fileoffset % simasel->numtilesx;
+ scrollofs = (float)tileheight*(float)columnoffset/(float)simasel->numtilesx;
+ } else {
+ rowoffset = 0;
+ scrollofs = 0;
+ }
+ /* add partially visible row */
+ numtiles += simasel->numtilesx;
+ for (i=rowoffset, j=0 ; (i < numfiles) && (j < numtiles); ++i, ++j)
+ {
+ sx = simasel->v2d.cur.xmin + viewrect.xmin + (j % simasel->numtilesx)*tilewidth;
+ sy = simasel->v2d.cur.ymin + viewrect.ymax + (short)scrollofs - (viewrect.ymin + (j / simasel->numtilesx)*tileheight);
+
+ file = BIF_filelist_file(files, i);
+
+ if (simasel->active_file == i) {
+ colorid = TH_ACTIVE;
+ draw_tile(simasel, sx, sy, colorid);
+ } else if (file->flags & ACTIVE) {
+ colorid = TH_HILITE;
+ draw_tile(simasel, sx, sy, colorid);
+ } else {
+ /*
+ colorid = TH_PANEL;
+ draw_tile(simasel, sx, sy, colorid);
+ */
+ }
+
+ if ( type == FILE_MAIN) {
+ ID *id;
+ int icon_id = 0;
+ int idcode;
+ idcode= BIF_groupname_to_code(simasel->dir);
+ if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
+ id = (ID *)file->poin;
+ icon_id = BKE_icon_getid(id);
+ }
+ if (icon_id) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (do_load) {
+ BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 0);
+ } else {
+ BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 1);
+ todo++;
}
- sx = ima->sx; sy = ima->sy + sc;
- ex = ima->ex; ey = ima->ey + sc;
-
- if (ima->anim == 0) BIF_ThemeColorShade(TH_SHADE1, -80);
- else BIF_ThemeColorShade(TH_SHADE1, -70);
-
- glRecti(sx, sy, ex, ey);
- uiEmboss(sx-1,sy-1, ex+1,ey+1, 1);
-
- cpack(0);
- strcpy(naam, ima->file_name);
- naam[11] = 0;
-
- glRasterPos2i(sx+32-BMF_GetStringWidth(G.fonts, naam) / 2 , sy-16);
- BMF_DrawString(G.fonts, naam);
-
- if ((ima) && (ima->pict) && (ima->pict->rect)){
- if ( (ey > simasel->fesy) && (sy < simasel->feey)){
- if(OLD_IMASEL) {
- lrectwrite(sx, sy, ex-1, ey-1, ima->pict->rect);
- } else
- rectwrite_imasel(simasel->fesx, simasel->fesy,
- curarea->winrct.xmax, curarea->winrct.ymax - 64, //simasel->feey*1.5,
- sx, sy, ima->pict->x, ima->pict->y, 1.0, 1.0, ima->pict->rect);
- }
+ glDisable(GL_BLEND);
+ }
+ }
+ else {
+ if ( (file->flags & IMAGEFILE) || (file->flags & MOVIEFILE))
+ {
+ if (do_load) {
+ BIF_filelist_loadimage(simasel->files, i);
+ } else {
+ todo++;
}
-
- ima = ima->next;
+ imb = BIF_filelist_getimage(simasel->files, i);
+ } else {
+ imb = BIF_filelist_getimage(simasel->files, i);
}
-
- if ((simasel->mode & 8) == 8) { /* if magnify */
-
- if (bitset(simasel->fase, IMS_KNOW_IMA) && (simasel->hilite_ima)) {
-
- ima = simasel->hilite_ima;
- glPixelZoom(2.0, 2.0);
-
- sx = ima->sx + (ima->ex - ima->sx)/2 - (ima->ex - ima->sx);
- sy = ima->sy + (ima->ey - ima->sy)/2 - (ima->ey - ima->sy);
-
- ex = sx + 2*(ima->ex - ima->sx);
- ey = sy + 2*(ima->ey - ima->sy);
-
- uiEmboss(sx-1,sy-1, ex+1,ey+1, 0);
-
- if(OLD_IMASEL) {
- lrectwrite(sx, sy, sx+ (ima->ex - ima->sx)-1, sy+ (ima->ey - ima->sy)-1, ima->pict->rect);
- } else
- rectwrite_imasel(simasel->fesx, simasel->fesy,
- curarea->winrct.xmax, curarea->winrct.ymax - 64, //simasel->feey*1.5,
- sx, sy, ima->pict->x, ima->pict->y, 2.0, 2.0, ima->pict->rect);
+
+ if (imb) {
+ float fx = ((float)simasel->prv_w - (float)imb->x)/2.0f;
+ float fy = ((float)simasel->prv_h - (float)imb->y)/2.0f;
+ short dx = (short)(fx + 0.5f);
+ short dy = (short)(fy + 0.5f);
- glPixelZoom(1.0, 1.0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ // glaDrawPixelsSafe((float)sx+8 + dx, (float)sy - imgwidth + dy - 8, imb->x, imb->y, imb->x, GL_RGBA, GL_UNSIGNED_BYTE, imb->rect);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glaDrawPixelsTex((float)sx+2*TILE_BORDER_X + dx, (float)sy - simasel->prv_h + dy - 2*TILE_BORDER_Y, imb->x, imb->y,GL_UNSIGNED_BYTE, imb->rect);
+ // glDisable(GL_BLEND);
+ imb = 0;
+ }
+ }
+
+ if (type == FILE_MAIN) {
+ glColor3f(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ if (S_ISDIR(file->type)) {
+ glColor3f(1.0f, 1.0f, 0.9f);
+ }
+ else if (file->flags & IMAGEFILE) {
+ BIF_ThemeColor(TH_SEQ_IMAGE);
+ }
+ else if (file->flags & MOVIEFILE) {
+ BIF_ThemeColor(TH_SEQ_MOVIE);
+ }
+ else if (file->flags & BLENDERFILE) {
+ BIF_ThemeColor(TH_SEQ_SCENE);
+ }
+ else {
+ if (simasel->active_file == i) {
+ BIF_ThemeColor(TH_GRID); /* grid used for active text */
+ } else if (file->flags & ACTIVE) {
+ BIF_ThemeColor(TH_TEXT_HI);
+ } else {
+ BIF_ThemeColor(TH_TEXT);
}
}
- areaview(); /* reset viewgate */
}
-
-
- /* INFO */
- if (simasel->infsx > 0){
- BIF_ThemeColorShade(TH_SHADE1, -80);
-
- glRecti(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey);
- uiEmboss(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey,1);
-
- if ((info)&&(strlen(infostr) > 0)){
-
- sx = curarea->winrct.xmin;
- sy = curarea->winrct.ymin;
-
- viewgate(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey);
- cpack(0xAAAAAA);
- glRasterPos2i(simasel->infsx+4, simasel->infsy+6);
- BMF_DrawString(G.font, infostr);
-
- areaview(); /* reset viewgate */
-
- }
- }
-
- extrabutsize= (simasel->returnfunc)?60:0;
- if (simasel->dnw > extrabutsize+8) {
- simasel->dnw-= extrabutsize;
- uiDefBut(block, TEX, 1,"", simasel->dnsx, simasel->dnsy, simasel->dnw, simasel->dnh, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
- if (extrabutsize)
- uiDefBut(block, BUT, 5, "Load", simasel->dnsx+simasel->dnw, simasel->dnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Load the selected image");
- }
- if (simasel->fnw > extrabutsize+8) {
- simasel->fnw-= extrabutsize;
- uiDefBut(block, TEX, 2,"", simasel->fnsx, simasel->fnsy, simasel->fnw, simasel->fnh, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
- if (extrabutsize)
- uiDefBut(block, BUT, 6, "Cancel", simasel->fnsx+simasel->fnw, simasel->fnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Cancel image loading");
+ draw_file(simasel, sx, sy, file);
+
+ if(do_load && (PIL_check_seconds_timer() - lasttime > 0.3)) {
+ lasttime= PIL_check_seconds_timer();
+ do_load = 0;
}
}
-
- if (curarea->winx > 16) {
- char *menu= fsmenu_build_menu();
-
- uiDefBut(block, BUT, 13, "P", 8, (short)(curarea->winy-29), 20, 21, 0, 0, 0, 0, 0, "");
- uiDefButS(block, MENU, 3 , menu, 8, (short)(curarea->winy-58), 20, 21, &simasel->fileselmenuitem, 0, 0, 0, 0, "");
- MEM_freeN(menu);
- }
-
- uiDrawBlock(block);
+ if (!do_load && todo > 0) /* we broke off loading */
+ addafterqueue(sa->win, RENDERPREVIEW, 1);
}
-void select_ima_files(SpaceImaSel *simasel)
+
+/* in panel space! */
+static void imasel_imgdraw(ScrArea *sa, uiBlock *block)
{
- short set_reset;
- short mval[2], oval[2];
-
- set_reset = 1 - (simasel->hilite_ima->selected);
-
- getmouseco_areawin(mval);
- oval[0] = mval[0] + 1;
- oval[1] = 0; /* Just give it a value to stop warnings */
-
- while(get_mbut()&R_MOUSE) {
- getmouseco_areawin(mval);
- if ((oval[0] != mval[0]) || (oval[1] != mval[1])){
- simasel->mx = mval[0];
- simasel->my = mval[1];
-
- calc_hilite(simasel);
-
- if (simasel->hilite_ima){
- simasel->hilite_ima->selected = set_reset;
- scrarea_do_windraw(curarea);
- screen_swapbuffers();
+ SpaceImaSel *simasel= sa->spacedata.first;
+ rctf dispf;
+ rcti winrect;
+ struct direntry *file;
+ char path[FILE_MAX];
+ float tsize;
+ short ofsx=0;
+ short ofsy=0;
+ short ex, ey;
+ float scaledx, scaledy;
+ int index;
+
+ BLI_init_rctf(&dispf, 0.0f, (block->maxx - block->minx)-0.0f, 0.0f, (block->maxy - block->miny)-0.0f);
+ ui_graphics_to_window_rct(sa->win, &dispf, &winrect);
+
+ if (!simasel->img) {
+ BLI_join_dirfile(path, simasel->dir, simasel->file);
+ if (!BLI_exists(path))
+ return;
+
+ index = BIF_filelist_find(simasel->files, simasel->file);
+ if (index >= 0) {
+ file = BIF_filelist_file(simasel->files,index);
+ if (file->flags & IMAGEFILE || file->flags & MOVIEFILE) {
+ simasel->img = IMB_loadiffname(path, IB_rect);
+
+ if (simasel->img) {
+ tsize = MIN2(winrect.xmax - winrect.xmin,winrect.ymax - winrect.ymin);
+
+ if (simasel->img->x > simasel->img->y) {
+ scaledx = (float)tsize;
+ scaledy = ( (float)simasel->img->y/(float)simasel->img->x )*tsize;
+ ofsy = (scaledx - scaledy) / 2.0;
+ ofsx = 0;
+ }
+ else {
+ scaledy = (float)tsize;
+ scaledx = ( (float)simasel->img->x/(float)simasel->img->y )*tsize;
+ ofsx = (scaledy - scaledx) / 2.0;
+ ofsy = 0;
+ }
+ ex = (short)scaledx;
+ ey = (short)scaledy;
+
+ IMB_scaleImBuf(simasel->img, ex, ey);
+ }
}
- oval[0] = mval[0];
- oval[1] = mval[1];
}
}
+ if (simasel->img == NULL)
+ return;
+ if(simasel->img->rect==NULL)
+ return;
+
+ /* correction for gla draw */
+ BLI_translate_rcti(&winrect, -curarea->winrct.xmin, -curarea->winrct.ymin);
+
+ glaDefine2DArea(&sa->winrct);
+ glaDrawPixelsSafe(winrect.xmin+ofsx, winrect.ymin+ofsy, simasel->img->x, simasel->img->y, simasel->img->x, GL_RGBA, GL_UNSIGNED_BYTE, simasel->img->rect);
}
-void move_imadir_sli(SpaceImaSel *simasel)
+static void imasel_panel_image(ScrArea *sa, short cntrl)
{
-
- short mval[2], lval[2], fh;
- float rh;
-
- getmouseco_areawin(mval);
-
- if ((mval[0] > simasel->dirsli_sx) &&
- (mval[0] < simasel->dirsli_ex) &&
- (mval[1] > simasel->dirsli_ey - simasel->dirsli_h) &&
- (mval[1] < simasel->dirsli_ey) ){
-
- /* extactly in the slider */
- fh = simasel->dirsli_ey - mval[1];
- lval[1]=1;
- while(get_mbut()&L_MOUSE) {
- getmouseco_areawin(mval);
- if (mval[1] != lval[1]){
-
- rh = (float)(simasel->dsey - mval[1] - fh - simasel->dssy) / (simasel->dsdh - simasel->dirsli_h);
-
- simasel->topdir = 1 + rh * (simasel->totaldirs - simasel->dirsli_lines);
-
- scrarea_do_windraw(curarea);
- uiEmboss(simasel->dirsli_sx, simasel->dirsli_ey - simasel->dirsli_h,
- simasel->dirsli_ex, simasel->dirsli_ey,1);
- screen_swapbuffers();
- lval[1] = mval[1];
- }
- }
- }else{
- if (mval[1] < simasel->dirsli_ey - simasel->dirsli_h)
- simasel->topdir += (simasel->dirsli_lines - 1);
- else
- simasel->topdir -= (simasel->dirsli_lines - 1);
-
- while(get_mbut()&L_MOUSE) { }
+ uiBlock *block;
+ SpaceImaSel *simasel= sa->spacedata.first;
+ short w = 300;
+ short h = 300;
+ short offsx, offsy;
+
+ if (simasel->img) {
+ w = simasel->img->x;
+ h = simasel->img->y;
}
+
+ offsx = -150 + (simasel->v2d.mask.xmax - simasel->v2d.mask.xmin)/2;
+ offsy = -150 + (simasel->v2d.mask.ymax - simasel->v2d.mask.ymin)/2;
+
+ block= uiNewBlock(&curarea->uiblocks, "imasel_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(IMASEL_HANDLER_IMAGE); // for close and esc
+ if(uiNewPanel(curarea, block, "Image Preview", "Image Browser", offsx, offsy, w, h)==0)
+ return;
+ uiBlockSetDrawExtraFunc(block, imasel_imgdraw);
}
-void move_imafile_sli(SpaceImaSel *simasel)
+static void imasel_blockhandlers(ScrArea *sa)
{
- short mval[2], cmy, omy = 0;
- short ssl, sdh, ssv;
-
- getmouseco_areawin(mval);
- cmy = mval[1];
-
- if ((mval[0] > simasel->imasli_sx) &&
- (mval[0] < simasel->imasli_ex) &&
- (mval[1] > simasel->imasli_ey - simasel->imasli_h) &&
- (mval[1] < simasel->imasli_ey) ){
+ SpaceImaSel *simasel= sa->spacedata.first;
+ short a;
- ssv = simasel->fsey - simasel->imasli_ey - 2;
+ for(a=0; a<SPACE_MAXHANDLER; a+=2) {
+ switch(simasel->blockhandler[a]) {
+
+ case IMASEL_HANDLER_IMAGE:
+ imasel_panel_image(sa, simasel->blockhandler[a+1]);
+ break;
- while(get_mbut() & L_MOUSE) {
- getmouseco_areawin(mval);
- if (mval[1] != omy){
- sdh = simasel->fsdh - simasel->imasli_h;
- ssl = cmy - mval[1] + ssv;
-
- if (ssl < 0) { ssl = 0; }
- if (ssl > sdh) { ssl = sdh; }
-
- simasel->image_slider = ssl / (float)sdh;
-
- scrarea_do_windraw(curarea);
- uiEmboss(simasel->imasli_sx, simasel->imasli_ey - simasel->imasli_h,
- simasel->imasli_ex, simasel->imasli_ey, 1);
-
- screen_swapbuffers();
- omy = mval[1];
- }
}
- }else{
- while(get_mbut() & L_MOUSE) { }
+ /* clear action value for event */
+ simasel->blockhandler[a+1]= 0;
}
+ uiDrawBlocksPanels(sa, 0);
}
-void ima_select_all(SpaceImaSel *simasel)
+
+static void draw_imasel_buttons(ScrArea *sa, SpaceImaSel* simasel)
{
- OneSelectableIma *ima;
- int reselect = 0;
-
- ima = simasel->first_sel_ima;
- if (!ima) return;
-
- while(ima){
- if (ima->selected == 1) reselect = 1;
- ima = ima->next;
- }
- ima = simasel->first_sel_ima;
- if (reselect == 1){
- while(ima){
- ima->selected = 0;
- ima = ima->next;
- }
- }else{
- while(ima){
- ima->selected = 1;
- ima = ima->next;
+ uiBlock *block;
+ int loadbutton;
+ char name[20];
+ char *menu;
+ float slen;
+ float parentbut_width = 20;
+ float bookmarkbut_width = 0.0f;
+ float file_start_width = 0.0f;
+
+ int filebuty1, filebuty2;
+
+ float xmin = simasel->v2d.mask.xmin + 10;
+ float xmax = simasel->v2d.mask.xmax - 10;
+
+ filebuty1= simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT;
+ filebuty2= filebuty1+IMASEL_BUTTONS_HEIGHT/2 -6;
+
+ /* HEADER */
+ sprintf(name, "win %d", sa->win);
+ block = uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win);
+
+ uiSetButLock( BIF_filelist_gettype(simasel->files)==FILE_MAIN && simasel->returnfunc, NULL);
+
+ /* space available for load/save buttons? */
+ slen = BIF_GetStringWidth(G.font, simasel->title, simasel->aspect);
+ loadbutton= slen > 60 ? slen + 20 : 80; /* MAX2(80, 20+BIF_GetStringWidth(G.font, simasel->title)); */
+ if(simasel->v2d.mask.xmax-simasel->v2d.mask.xmin > loadbutton+20) {
+ if(simasel->title[0]==0) {
+ loadbutton= 0;
}
}
-}
+ else {
+ loadbutton= 0;
+ }
-void pibplay(SpaceImaSel *simasel)
-{
- OneSelectableIma *ima;
- int sx= 8, sy= 8;
-
- ima = simasel->first_sel_ima;
- if (!ima) return ;
-
- sx = curarea->winrct.xmin + 8;
- sy = curarea->winrct.ymin + 8;
-
- while(!(get_mbut()&L_MOUSE)){
- scrarea_do_windraw(curarea);
-
- lrectwrite(sx, sy, sx+ima->dw-1, sy+ima->dh-1, ima->pict->rect);
-
- ima = ima->next;
- if (!ima) ima = simasel->first_sel_ima;
- screen_swapbuffers();
+ menu= fsmenu_build_menu();
+
+ if (menu[0]&& (simasel->type != FILE_MAIN)) {
+ bookmarkbut_width = parentbut_width;
+ file_start_width = parentbut_width;
+ }
+
+ uiDefBut(block, TEX, B_FS_FILENAME,"", xmin+file_start_width+bookmarkbut_width+2, filebuty1, xmax-xmin-loadbutton-file_start_width-bookmarkbut_width, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+ uiDefBut(block, TEX, B_FS_DIRNAME,"", xmin+parentbut_width, filebuty2, xmax-xmin-loadbutton-parentbut_width, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+
+ if(loadbutton) {
+ uiSetCurFont(block, UI_HELV);
+ uiDefBut(block, BUT,B_FS_LOAD, simasel->title, xmax-loadbutton, filebuty2, loadbutton, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+ uiDefBut(block, BUT,B_FS_CANCEL, "Cancel", xmax-loadbutton, filebuty1, loadbutton, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+ }
+
+ /* menu[0] = NULL happens when no .Bfs is there, and first time browse
+ disallow external directory browsing for databrowse */
+ if(menu[0] && (simasel->type != FILE_MAIN)) {
+ uiDefButS(block, MENU,B_FS_DIR_MENU, menu, xmin, filebuty1, parentbut_width, 21, &simasel->menu, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_FS_BOOKMARK, "B", xmin+22, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
}
+ MEM_freeN(menu);
+
+ uiDefBut(block, BUT, B_FS_PARDIR, "P", xmin, filebuty2, parentbut_width, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)");
+
+ uiDrawBlock(block);
}
@@ -860,65 +670,71 @@ void pibplay(SpaceImaSel *simasel)
void drawimaselspace(ScrArea *sa, void *spacedata)
{
- SpaceImaSel *simasel;
- simasel= curarea->spacedata.first;
+ float col[3];
+ SpaceImaSel *simasel= curarea->spacedata.first;
- /* ortho: xmin xmax, ymin, ymax! */
- myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375);
+ BIF_GetThemeColor3fv(TH_BACK, col);
+ glClearColor(col[0], col[1], col[2], 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
- if (simasel->fase == 0){
- BLI_cleanup_dir(G.sce, simasel->dir);
- clear_ima_dir(simasel);
- }
+ /* HACK: somehow when going fullscreen, v2d isn't set correctly */
+ simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f;
+ simasel->v2d.cur.xmax= sa->winx;
+ simasel->v2d.cur.ymax= sa->winy;
+ simasel->v2d.tot= simasel->v2d.cur;
+ test_view2d(G.v2d, sa->winx, sa->winy);
+
+ calc_imasel_rcts(simasel, sa->winx, sa->winy);
- if (!bitset(simasel->fase, IMS_KNOW_DIR)){
- if(simasel->firstdir) free_ima_dir(simasel->firstdir);
- if(simasel->firstfile) free_ima_dir(simasel->firstfile);
- simasel->firstdir = 0;
- simasel->firstfile = 0;
+ myortho2(simasel->v2d.cur.xmin, simasel->v2d.cur.xmax, simasel->v2d.cur.ymin, simasel->v2d.cur.ymax);
+ bwin_clear_viewmat(sa->win); /* clear buttons view */
+ glLoadIdentity();
- if (get_ima_dir(simasel->dir, IMS_DIR, &simasel->totaldirs, &simasel->firstdir) < 0){
- /* error */
- strcpy(simasel->dir, simasel->dor);
- get_ima_dir(simasel->dir, IMS_DIR, &simasel->totaldirs, &simasel->firstdir);
- }
-
- if (get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile) < 0){
- /* error */
- strcpy(simasel->file, simasel->fole);
- get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile);
- }
-
- simasel->topdir = 0;
- simasel->topfile = 0;
- simasel->fase |= IMS_KNOW_DIR;
-
- check_for_pib(simasel);
-
- strcpy(simasel->fole, simasel->file);
- strcpy(simasel->dor, simasel->dir);
- }
-
- if (!bitset(simasel->fase, IMS_FOUND_BIP)){
- /* Make the first Bip file ever in this directory */
- if ( !bitset(simasel->fase, IMS_KNOW_INF)){
- if (!bitset(simasel->fase, IMS_DOTHE_INF)){
- if(simasel->first_sel_ima) free_sel_ima(simasel->first_sel_ima);
- simasel->first_sel_ima = 0;
- simasel->fase |= IMS_DOTHE_INF;
- addafterqueue(curarea->win, AFTERIMASELIMA, 1);
- }
- }
- }else{
- if (!bitset(simasel->fase, IMS_KNOW_BIP)){
- addafterqueue(curarea->win, AFTERPIBREAD, 1);
- }
+ /* warning; blocks need to be freed each time, handlers dont remove */
+ uiFreeBlocksWin(&sa->uiblocks, sa->win);
+
+ /* aspect+font, set each time */
+ simasel->aspect= (simasel->v2d.cur.xmax - simasel->v2d.cur.xmin)/((float)sa->winx);
+ simasel->curfont= uiSetCurFont_ext(simasel->aspect);
+
+ if (!simasel->files) {
+ simasel->files = BIF_filelist_new();
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ BIF_filelist_settype(simasel->files, simasel->type);
}
+
+ /* Buttons */
+ draw_imasel_buttons(sa, simasel);
+
+ /* scrollbar */
+ draw_imasel_scroll(simasel);
+
+ /* bookmarks */
+ draw_imasel_bookmarks(sa, simasel);
+
+ uiEmboss(simasel->viewrect.xmin, simasel->viewrect.ymin, simasel->v2d.mask.xmax-TILE_BORDER_X, simasel->viewrect.ymax, 1);
+
+
+ glScissor(sa->winrct.xmin + simasel->viewrect.xmin ,
+ sa->winrct.ymin + simasel->viewrect.ymin,
+ simasel->viewrect.xmax - simasel->viewrect.xmin ,
+ simasel->viewrect.ymax - simasel->viewrect.ymin);
+
+ /* previews */
+ draw_imasel_previews(sa, simasel);
- make_sima_area(simasel);
- calc_hilite(simasel);
- draw_sima_area(simasel);
+ /* BIF_ThemeColor(TH_HEADER);*/
+ /* glRecti(simasel->viewrect.xmin, simasel->viewrect.ymin, simasel->viewrect.xmax, simasel->viewrect.ymax);*/
+ /* restore viewport (not needed yet) */
+ mywinset(sa->win);
+
+ /* ortho at pixel level curarea */
+ myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+
+ draw_area_emboss(sa);
+
+ imasel_blockhandlers(sa);
+
curarea->win_swap= WIN_BACK_OK;
}
-
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index e2acee267c1..c94df84c7f7 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -42,9 +42,8 @@
#include <unistd.h>
#else
#include <io.h>
-#endif
+#endif
-#include "BMF_Api.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -66,6 +65,7 @@
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
+#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BIF_cursors.h"
@@ -80,6 +80,7 @@
#include "BIF_glutil.h"
#include "BIF_editseq.h"
#include "BIF_editaction.h"
+#include "BIF_language.h"
#include "BSE_drawipo.h"
#include "BSE_view.h"
@@ -93,6 +94,7 @@
#include "mydevice.h"
#include "blendef.h"
#include "butspace.h" // shouldnt be...
+#include "interface.h" /* for ui_rasterpos_safe */
#include "winlay.h"
/* local define... also used in editipo ... */
@@ -133,8 +135,8 @@ static void scroll_prstr(float x, float y, float val, char dir, int disptype)
str[len+1]= 0;
}
- glRasterPos2f(x, y);
- BMF_DrawString(G.fonts, str);
+ ui_rasterpos_safe(x, y, 1.0);
+ BIF_DrawString(G.fonts, str, 0);
}
static void step_to_grid(float *step, int *macht)
@@ -209,7 +211,7 @@ void calc_ipogrid()
SpaceTime *stime= curarea->spacedata.first;
if(!(stime->flag & TIME_DRAWFRAMES)) {
secondgrid= 1;
- secondiv= 0.01 * (float)G.scene->r.frs_sec;
+ secondiv= 0.01 * FPS;
}
break;
}
@@ -217,8 +219,25 @@ void calc_ipogrid()
SpaceSeq * sseq = curarea->spacedata.first;
if (!(sseq->flag & SEQ_DRAWFRAMES)) {
secondgrid = 1;
- secondiv = 0.01 * (float)G.scene->r.frs_sec;
+ secondiv = 0.01 * FPS;
}
+ break;
+ }
+ case SPACE_ACTION: {
+ SpaceAction *saction = curarea->spacedata.first;
+ if (saction->flag & SACTION_DRAWTIME) {
+ secondgrid = 1;
+ secondiv = 0.01 * FPS;
+ }
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = curarea->spacedata.first;
+ if (snla->flag & SNLA_DRAWTIME) {
+ secondgrid = 1;
+ secondiv = 0.01 * FPS;
+ }
+ break;
}
default:
break;
@@ -231,7 +250,7 @@ void calc_ipogrid()
step_to_grid(&ipogrid_dx, &ipomachtx);
ipogrid_dx*= secondiv;
- if ELEM3(curarea->spacetype, SPACE_SEQ, SPACE_SOUND, SPACE_TIME) {
+ if ELEM5(curarea->spacetype, SPACE_SEQ, SPACE_SOUND, SPACE_TIME, SPACE_ACTION, SPACE_NLA) {
if(ipogrid_dx < 0.1) ipogrid_dx= 0.1;
ipomachtx-= 2;
if(ipomachtx<-2) ipomachtx= -2;
@@ -242,7 +261,7 @@ void calc_ipogrid()
ipogrid_dy= IPOSTEP*space/pixels;
step_to_grid(&ipogrid_dy, &ipomachty);
- if ELEM3(curarea->spacetype, SPACE_SEQ, SPACE_SOUND, SPACE_TIME) {
+ if ELEM5(curarea->spacetype, SPACE_SEQ, SPACE_SOUND, SPACE_TIME, SPACE_ACTION, SPACE_NLA) {
if(ipogrid_dy < 1.0) ipogrid_dy= 1.0;
if(ipomachty<1) ipomachty= 1;
}
@@ -502,6 +521,10 @@ void view2d_zoom(View2D *v2d, float factor, int winx, int winy)
view2d_do_locks(curarea, V2D_LOCK_COPY);
}
+void view2d_getscale(View2D *v2d, float *x, float *y) {
+ if (x) *x = (G.v2d->mask.xmax-G.v2d->mask.xmin)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
+ if (y) *y = (G.v2d->mask.ymax-G.v2d->mask.ymin)/(G.v2d->cur.ymax-G.v2d->cur.ymin);
+}
void test_view2d(View2D *v2d, int winx, int winy)
{
@@ -512,6 +535,7 @@ void test_view2d(View2D *v2d, int winx, int winy)
/* correct winx for scroll */
if(v2d->scroll & L_SCROLL) winx-= SCROLLB;
if(v2d->scroll & B_SCROLL) winy-= SCROLLH;
+ if(v2d->scroll & B_SCROLLO) winy-= SCROLLH; /* B_SCROLL and B_SCROLLO are basically same thing */
/* header completely closed window */
if(winy<=0) return;
@@ -603,17 +627,23 @@ void test_view2d(View2D *v2d, int winx, int winy)
else if( dy > 1.0) do_x= 0; else do_x= 1;
}
- v2d->oldwinx= winx;
- v2d->oldwiny= winy;
-
if( do_x ) {
-
- /* portrait window: correct for x */
- dx= cur->ymax-cur->ymin;
- temp= (cur->xmax+cur->xmin);
-
- cur->xmin= temp/2.0 - 0.5*dx/dy;
- cur->xmax= temp/2.0 + 0.5*dx/dy;
+ if (v2d->keeptot == 2 && winx < v2d->oldwinx) {
+ /* This is a special hack for the outliner, to ensure that the
+ * outliner contents will not eventually get pushed out of view
+ * when shrinking the view.
+ */
+ cur->xmax -= cur->xmin;
+ cur->xmin= 0.0f;
+ }
+ else {
+ /* portrait window: correct for x */
+ dx= cur->ymax-cur->ymin;
+ temp= (cur->xmax+cur->xmin);
+
+ cur->xmin= temp/2.0 - 0.5*dx/dy;
+ cur->xmax= temp/2.0 + 0.5*dx/dy;
+ }
}
else {
dx= cur->xmax-cur->xmin;
@@ -622,6 +652,9 @@ void test_view2d(View2D *v2d, int winx, int winy)
cur->ymin= temp/2.0 - 0.5*dy*dx;
cur->ymax= temp/2.0 + 0.5*dy*dx;
}
+
+ v2d->oldwinx= winx;
+ v2d->oldwiny= winy;
}
if(v2d->keeptot) {
@@ -652,7 +685,8 @@ void test_view2d(View2D *v2d, int winx, int winy)
cur->xmin+= dx;
cur->xmax+= dx;
}
- else if(cur->xmax > tot->xmax) {
+ else if((v2d->keeptot!=2) && (cur->xmax > tot->xmax)) {
+ /* keeptot==2 is a special case for the outliner. see space.c, init_v2d_oops for details */
dx= cur->xmax-tot->xmax;
cur->xmin-= dx;
cur->xmax-= dx;
@@ -699,6 +733,7 @@ static int calc_ipobuttonswidth(ScrArea *sa)
EditIpo *ei;
int ipowidth = IPOBUTX;
int a;
+ float textwidth = 0;
/* default width when no space ipo or no channels */
if (sipo == NULL) return IPOBUTX;
@@ -707,8 +742,9 @@ static int calc_ipobuttonswidth(ScrArea *sa)
ei= sipo->editipo;
for(a=0; a<sipo->totipo; a++, ei++) {
- if (BMF_GetStringWidth(G.font, ei->name) + 18 > ipowidth)
- ipowidth = BMF_GetStringWidth(G.font, ei->name) + 18;
+ textwidth = BIF_GetStringWidth(G.font, ei->name, 0);
+ if (textwidth + 18 > ipowidth)
+ ipowidth = textwidth + 18;
}
return ipowidth;
@@ -753,7 +789,7 @@ void calc_scrollrcts(ScrArea *sa, View2D *v2d, int winx, int winy)
v2d->mask.xmax= v2d->vert.xmin;
}
- if(v2d->scroll & B_SCROLL) {
+ if((v2d->scroll & B_SCROLL) || (v2d->scroll & B_SCROLLO)) {
v2d->hor= v2d->mask;
v2d->hor.ymax= SCROLLH;
v2d->mask.ymin= SCROLLH;
@@ -832,7 +868,7 @@ void draw_view2d_numbers_horiz(int drawframes)
scroll_prstr(fac, 2.0+(float)(G.v2d->mask.ymin), val, 'h', 0);
}
else {
- fac2= val/(float)G.scene->r.frs_sec;
+ fac2= val/FPS;
scroll_prstr(fac, 2.0+(float)(G.v2d->mask.ymin), fac2, 'h', 0);
}
@@ -856,7 +892,7 @@ void drawscroll(int disptype)
light= 20;
lighter= 50;
- if(G.v2d->scroll & HOR_SCROLL) {
+ if((G.v2d->scroll & HOR_SCROLL) || (G.v2d->scroll & HOR_SCROLLO)) {
BIF_ThemeColorShade(TH_SHADE1, light);
glRecti(hor.xmin, hor.ymin, hor.xmax, hor.ymax);
@@ -890,17 +926,23 @@ void drawscroll(int disptype)
val= ipogrid_startx;
while(fac < hor.xmax) {
- if(curarea->spacetype==SPACE_OOPS);
+ if(curarea->spacetype==SPACE_OOPS) {
+ /* Under no circumstances may the outliner/oops display numbers on its scrollbar
+ * Unfortunately, versions of Blender without this patch will hang on loading files with
+ * horizontally scrollable Outliners.
+ */
+ break;
+ }
else if(curarea->spacetype==SPACE_SEQ) {
SpaceSeq * sseq = curarea->spacedata.first;
if (sseq->flag & SEQ_DRAWFRAMES) {
ipomachtx = 1;
scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
} else {
- fac2= val/(float)G.scene->r.frs_sec;
+ fac2= val/FPS;
tim= floor(fac2);
fac2= fac2-tim;
- scroll_prstr(fac, 3.0+(float)(hor.ymin), tim+G.scene->r.frs_sec*fac2/100.0, 'h', disptype);
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), tim+FPS*fac2/100.0, 'h', disptype);
}
}
else if (curarea->spacetype==SPACE_SOUND) {
@@ -911,7 +953,7 @@ void drawscroll(int disptype)
scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
}
else {
- fac2= val/(float)G.scene->r.frs_sec;
+ fac2= val/FPS;
scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
}
}
@@ -923,7 +965,7 @@ void drawscroll(int disptype)
scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
}
else {
- fac2= val/(float)G.scene->r.frs_sec;
+ fac2= val/FPS;
scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
}
}
@@ -942,6 +984,30 @@ void drawscroll(int disptype)
else
scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
}
+ else if (curarea->spacetype==SPACE_ACTION) {
+ SpaceAction *saction= curarea->spacedata.first;
+
+ if (saction->flag & SACTION_DRAWTIME) {
+ fac2= val/FPS;
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
+ }
+ else {
+ ipomachtx= 1;
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
+ }
+ }
+ else if (curarea->spacetype==SPACE_NLA) {
+ SpaceNla *snla= curarea->spacedata.first;
+
+ if (snla->flag & SNLA_DRAWTIME) {
+ fac2= val/FPS;
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
+ }
+ else {
+ ipomachtx= 1;
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
+ }
+ }
else {
scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
}
@@ -1129,7 +1195,7 @@ static void draw_ipovertices(int sel)
ok= 0;
if(ei->flag & IPO_EDIT) {
- if( (bezt->f2 & 1) == sel ) ok= 1;
+ if( (bezt->f2 & SELECT) == sel ) ok= 1;
}
else ok= 1;
@@ -1151,15 +1217,15 @@ static void draw_ipovertices(int sel)
if(ei->flag & IPO_EDIT) {
if(ei->icu->ipo==IPO_BEZ) {
/* Draw the editmode hendels for a bezier curve */
- if( (bezt->f1 & 1) == sel)/* && G.v2d->cur.xmin < bezt->vec[0][0] < G.v2d->cur.xmax)*/
+ if( (bezt->f1 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[0][0] < G.v2d->cur.xmax)*/
bglVertex3fv(bezt->vec[0]);
- if( (bezt->f3 & 1) == sel)/* && G.v2d->cur.xmin < bezt->vec[2][0] < G.v2d->cur.xmax)*/
+ if( (bezt->f3 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[2][0] < G.v2d->cur.xmax)*/
bglVertex3fv(bezt->vec[2]);
}
- if( (bezt->f2 & 1) == sel) /* && G.v2d->cur.xmin < bezt->vec[1][0] < G.v2d->cur.xmax)*/
+ if( (bezt->f2 & SELECT) == sel) /* && G.v2d->cur.xmin < bezt->vec[1][0] < G.v2d->cur.xmax)*/
bglVertex3fv(bezt->vec[1]);
}
@@ -1200,7 +1266,7 @@ static void draw_ipohandles(int sel)
b= ei->icu->totvert;
while(b--) {
- if( (bezt->f2 & 1)==sel) {
+ if( (bezt->f2 & SELECT)==sel) {
fp= bezt->vec[0];
cpack(col[bezt->h1]);
@@ -1221,7 +1287,7 @@ static void draw_ipohandles(int sel)
glVertex2fv(fp); glVertex2fv(fp+3);
glEnd();
}
- else if( (bezt->f3 & 1)==sel) {
+ else if( (bezt->f3 & SELECT)==sel) {
fp= bezt->vec[1];
cpack(col[bezt->h2]);
@@ -1499,7 +1565,7 @@ static void draw_cfra(SpaceIpo *sipo)
vec[0]*= G.scene->r.framelen;
vec[1]= v2d->cur.ymin;
- glColor3ub(0x60, 0xc0, 0x40); // no theme, should be global color once...
+ BIF_ThemeColor(TH_CFRAME);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
@@ -1510,8 +1576,8 @@ static void draw_cfra(SpaceIpo *sipo)
if(sipo->blocktype==ID_OB) {
ob= (G.scene->basact) ? (G.scene->basact->object) : 0;
- if(ob && ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
- vec[0]-= ob->sf;
+ if (ob && (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0)) {
+ vec[0]-= give_timeoffset(ob);
BIF_ThemeColorShade(TH_HILITE, -30);
@@ -1623,7 +1689,7 @@ static void boundbox_ipo_curves(SpaceIpo *si)
if(ei->icu) {
if(ei->flag & IPO_VISIBLE) {
- boundbox_ipocurve(ei->icu);
+ boundbox_ipocurve(ei->icu, 0);
if(first) {
si->v2d.tot= ei->icu->totrct;
first= 0;
@@ -1669,16 +1735,16 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m
b= ei->icu->totvert;
while(b--) {
// all three selected
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
VecAddf(median, median, bezt->vec[1]);
tot++;
}
else {
- if(bezt->f1 & 1) {
+ if(bezt->f1 & SELECT) {
VecAddf(median, median, bezt->vec[0]);
tot++;
}
- if(bezt->f3 & 1) {
+ if(bezt->f3 & SELECT) {
VecAddf(median, median, bezt->vec[2]);
tot++;
}
@@ -1763,16 +1829,16 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m
b= ei->icu->totvert;
while(b--) {
// all three selected
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
VecAddf(bezt->vec[0], bezt->vec[0], median);
VecAddf(bezt->vec[1], bezt->vec[1], median);
VecAddf(bezt->vec[2], bezt->vec[2], median);
}
else {
- if(bezt->f1 & 1) {
+ if(bezt->f1 & SELECT) {
VecAddf(bezt->vec[0], bezt->vec[0], median);
}
- if(bezt->f3 & 1) {
+ if(bezt->f3 & SELECT) {
VecAddf(bezt->vec[2], bezt->vec[2], median);
}
}
@@ -1838,7 +1904,7 @@ void do_ipobuts(unsigned short event)
ei= get_active_editipo();
if(ei) {
if(ei->icu==NULL) {
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
if (!ei->icu) {
error("Could not add a driver to this curve, may be linked data!");
break;
@@ -1905,7 +1971,7 @@ void do_ipobuts(unsigned short event)
}
else {
if(driver->ob) {
- if(ob==driver->ob) {
+ if(ob==driver->ob && G.sipo->bonename[0]==0) {
error("Cannot assign a Driver to own Object");
driver->ob= NULL;
}
@@ -1953,7 +2019,7 @@ static char *ipodriver_modeselect_pup(Object *ob)
return (string);
}
-static char *ipodriver_channelselect_pup(void)
+static char *ipodriver_channelselect_pup(int is_armature)
{
static char string[1024];
char *tmp;
@@ -1970,6 +2036,8 @@ static char *ipodriver_channelselect_pup(void)
tmp+= sprintf(tmp, "|Scale X %%x%d", OB_SIZE_X);
tmp+= sprintf(tmp, "|Scale Y %%x%d", OB_SIZE_Y);
tmp+= sprintf(tmp, "|Scale Z %%x%d", OB_SIZE_Z);
+ if(is_armature)
+ tmp+= sprintf(tmp, "|Rotation Difference %%x%d", OB_ROT_DIFF);
return (string);
}
@@ -2020,6 +2088,10 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) {
icon = ICON_POSE_DEHLT;
uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name");
+
+ if(driver->adrcode==OB_ROT_DIFF)
+ uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,200,150,20, driver->name+DRIVER_NAME_OFFS, 0, 31, 0, 0, "Bone name for angular reference");
+
}
else driver->blocktype= ID_OB; /* safety when switching object button */
@@ -2028,7 +2100,8 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
ipodriver_modeselect_pup(driver->ob), 165,240,145,20, &(driver->blocktype), 0, 0, 0, 0, "Driver type");
uiDefButS(block, MENU, B_IPO_REDR,
- ipodriver_channelselect_pup(), 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel");
+ ipodriver_channelselect_pup(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR),
+ 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel");
}
uiBlockEndAlign(block);
}
@@ -2045,7 +2118,7 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
/* note ranges for buttons below are idiot... we need 2 ranges, one for sliding scale, one for real clip */
if(G.sipo->ipo && G.sipo->ipo->curve.first && totipo_curve) {
extern int totipo_vertsel; // editipo.c
- uiDefBut(block, LABEL, 0, "Visible curves", 10, 200, 150, 19, NULL, 1.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Visible curves", 160, 200, 150, 19, NULL, 1.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_MUL_IPO, "Xmin:", 10, 180, 150, 19, &G.sipo->tot.xmin, G.sipo->tot.xmin-1000.0, MAXFRAMEF, 100, 0, "");
@@ -2158,9 +2231,8 @@ void drawipospace(ScrArea *sa, void *spacedata)
}
/* map ipo-points for drawing if scaled ipo */
- if (OBACT && OBACT->action && sipo->pin==0 && sipo->actname) {
+ if (NLA_IPO_SCALED)
actstrip_map_ipo_keys(OBACT, sipo->ipo, 0, 0);
- }
/* draw deselect */
draw_ipocurves(0);
@@ -2173,15 +2245,14 @@ void drawipospace(ScrArea *sa, void *spacedata)
draw_ipovertices(1);
/* undo mapping of ipo-points for drawing if scaled ipo */
- if (OBACT && OBACT->action && sipo->pin==0 && sipo->actname) {
+ if (NLA_IPO_SCALED)
actstrip_map_ipo_keys(OBACT, sipo->ipo, 1, 0);
- }
/* Draw 'curtains' for preview */
draw_anim_preview_timespace();
/* draw markers */
- draw_markers_timespace();
+ draw_markers_timespace(SCE_MARKERS, 0);
/* restore viewport */
mywinset(sa->win);
@@ -2493,13 +2564,7 @@ int view2dmove(unsigned short event)
}
cursor = BC_NSEW_SCROLLCURSOR;
-
- /* no x move in outliner */
- if(curarea->spacetype==SPACE_OOPS && G.v2d->scroll) {
- facx= 0.0;
- cursor = BC_NS_SCROLLCURSOR;
- }
-
+
/* no y move in audio & time */
if ELEM(curarea->spacetype, SPACE_SOUND, SPACE_TIME) {
facy= 0.0;
diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c
index 6307307345b..df5334dd27d 100644
--- a/source/blender/src/drawmesh.c
+++ b/source/blender/src/drawmesh.c
@@ -38,6 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_edgehash.h"
+#include "BLI_editVert.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -66,7 +67,7 @@
#include "BKE_property.h"
#include "BKE_utildefines.h"
-#include "BIF_resources.h"
+#include "BIF_editmesh.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
@@ -221,7 +222,7 @@ int set_tpage(MTFace *tface)
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
-
+ glDisable ( GL_ALPHA_TEST );
return 0;
}
lasttface= tface;
@@ -238,14 +239,26 @@ int set_tpage(MTFace *tface)
}
else if(alphamode==TF_ALPHA) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* added after 2.45 to clip alpha */
+
+ /*if U.glalphaclip == 1.0, some cards go bonkers... turn off alpha test in this case*/
+ if(U.glalphaclip == 1.0) glDisable(GL_ALPHA_TEST);
+ else{
+ glEnable ( GL_ALPHA_TEST );
+ glAlphaFunc ( GL_GREATER, U.glalphaclip );
+ }
+
/* glBlendEquationEXT(GL_FUNC_ADD_EXT); */
}
/* else { */
/* glBlendFunc(GL_ONE, GL_ONE); */
/* glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); */
/* } */
+ } else {
+ glDisable(GL_BLEND);
+ glDisable ( GL_ALPHA_TEST );
}
- else glDisable(GL_BLEND);
}
ima= tface->tpage;
@@ -596,10 +609,6 @@ void update_realtime_textures()
enum {
eEdge_Visible = (1<<0),
eEdge_Select = (1<<1),
- eEdge_Active = (1<<2),
- eEdge_SelectAndActive = (1<<3),
- eEdge_ActiveFirst = (1<<4),
- eEdge_ActiveLast = (1<<5)
};
/* Creates a hash of edges to flags indicating
@@ -621,19 +630,18 @@ EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
{
EdgeHash *eh = BLI_edgehash_new();
int i;
-
+ MFace *mf;
+ MTFace *tf = NULL;
+
for (i=0; i<me->totface; i++) {
- MFace *mf = &me->mface[i];
- MTFace *tf = &me->mtface[i];
+ mf = &me->mface[i];
+ if (me->mtface)
+ tf = &me->mtface[i];
if (mf->v3) {
if (!(mf->flag&ME_HIDE)) {
unsigned int flags = eEdge_Visible;
if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select;
- if (tf->flag&TF_ACTIVE) {
- flags |= eEdge_Active;
- if (mf->flag&ME_FACE_SEL) flags |= eEdge_SelectAndActive;
- }
get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
@@ -643,11 +651,6 @@ EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
} else {
get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
}
-
- if (tf->flag&TF_ACTIVE) {
- get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, eEdge_ActiveFirst);
- get_marked_edge_info__orFlags(eh, mf->v1, mf->v4?mf->v4:mf->v3, eEdge_ActiveLast);
- }
}
}
}
@@ -704,17 +707,7 @@ static int draw_tfaces3D__setActiveOpts(void *userData, int index)
MEdge *med = &data->me->medge[index];
unsigned long flags = (long) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
- if (flags & eEdge_Active) {
- if (flags & eEdge_ActiveLast) {
- glColor3ub(255, 0, 0);
- } else if (flags & eEdge_ActiveFirst) {
- glColor3ub(0, 255, 0);
- } else if (flags & eEdge_SelectAndActive) {
- glColor3ub(255, 255, 0);
- } else {
- glColor3ub(255, 0, 255);
- }
-
+ if (flags & eEdge_Select) {
return 1;
} else {
return 0;
@@ -724,13 +717,10 @@ static int draw_tfaces3D__drawFaceOpts(void *userData, int index)
{
Mesh *me = (Mesh*)userData;
- if (me->mtface) {
- MFace *mface = &me->mface[index];
- if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL))
- return 2; /* Don't set color */
- else
- return 0;
- } else
+ MFace *mface = &me->mface[index];
+ if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL))
+ return 2; /* Don't set color */
+ else
return 0;
}
static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
@@ -758,7 +748,7 @@ static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
glLineWidth(1);
}
- /* Draw Selected Faces */
+ /* Draw Selected Faces */
if(G.f & G_DRAWFACES) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -941,25 +931,80 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac
/* Icky globals, fix with userdata parameter */
-static Object *g_draw_tface_mesh_ob = NULL;
-static int g_draw_tface_mesh_islight = 0;
-static int g_draw_tface_mesh_istex = 0;
-static unsigned char g_draw_tface_mesh_obcol[4];
+struct TextureDrawState {
+ Object *ob;
+ int islit, istex;
+ unsigned char obcol[4];
+} Gtexdraw = {NULL, 0, 0, {0, 0, 0, 0}};
+
+static void draw_textured_begin(Object *ob)
+{
+ unsigned char obcol[4];
+ int istex, solidtex= 0;
+
+ if(G.vd->drawtype==OB_SOLID || (ob==G.obedit && G.vd->drawtype!=OB_TEXTURE)) {
+ /* draw with default lights in solid draw mode and edit mode */
+ solidtex= 1;
+ Gtexdraw.islit= -1;
+ }
+ else
+ /* draw with lights in the scene otherwise */
+ Gtexdraw.islit= set_gl_light(ob);
+
+ obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
+ obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
+ obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
+ obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
+
+ glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
+ if(solidtex || G.vd->drawtype==OB_TEXTURE) istex= 1;
+ else istex= 0;
+
+ Gtexdraw.ob = ob;
+ Gtexdraw.istex = istex;
+ memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
+ set_draw_settings_cached(1, 0, 0, Gtexdraw.islit, 0, 0, 0);
+ glShadeModel(GL_SMOOTH);
+}
+
+static void draw_textured_end()
+{
+ /* switch off textures */
+ set_tpage(0);
+
+ glShadeModel(GL_FLAT);
+ glDisable(GL_CULL_FACE);
+
+ /* XXX, bad patch - default_gl_light() calls
+ * glLightfv(GL_LIGHT_POSITION, ...) which
+ * is transformed by the current matrix... we
+ * need to make sure that matrix is identity.
+ *
+ * It would be better if drawmesh.c kept track
+ * of and restored the light settings it changed.
+ * - zr
+ */
+ glPushMatrix();
+ glLoadIdentity();
+ default_gl_light();
+ glPopMatrix();
+}
+
static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
{
if (tface && (tface->mode&TF_INVISIBLE)) return 0;
- if (tface && set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) {
+ if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
glColor3ub(0xFF, 0x00, 0xFF);
return 2; /* Don't set color */
} else if (tface && tface->mode&TF_OBCOL) {
- glColor3ubv(g_draw_tface_mesh_obcol);
+ glColor3ubv(Gtexdraw.obcol);
return 2; /* Don't set color */
} else if (!mcol) {
if (tface) glColor3f(1.0, 1.0, 1.0);
else {
- Material *ma= give_current_material(g_draw_tface_mesh_ob, matnr+1);
+ Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
if(ma) glColor3f(ma->r, ma->g, ma->b);
else glColor3f(1.0, 1.0, 1.0);
}
@@ -980,215 +1025,192 @@ static int draw_tface_mapped__set_draw(void *userData, int index)
return draw_tface__set_draw(tface, mcol, matnr);
}
+static int draw_em_tf_mapped__set_draw(void *userData, int index)
+{
+ EditMesh *em = userData;
+ EditFace *efa = EM_get_face_for_index(index);
+ MTFace *tface;
+ MCol *mcol;
+ int matnr;
+
+ if (efa==NULL || efa->h)
+ return 0;
+
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ matnr = efa->mat_nr;
+
+ return draw_tface__set_draw(tface, mcol, matnr);
+}
+
static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = (Mesh*)userData;
MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
MFace *mface = (me->mface)? &me->mface[index]: NULL;
- if (tface) {
- if ((mface->flag&ME_HIDE) || (tface->mode&TF_INVISIBLE))
+ if ((mface->flag&ME_HIDE) || (tface && (tface->mode&TF_INVISIBLE)))
return 0;
- }
+
*drawSmooth_r = 1;
return 1;
}
-void draw_tface_mesh(Object *ob, Mesh *me, int dt)
-/* maximum dt (drawtype): exactly according values that have been set */
+static void draw_game_text_mesh(Object *ob, Mesh *me)
{
- unsigned char obcol[4];
- int a;
- short istex, solidtex=0;
- DerivedMesh *dm;
-
- if(me==NULL) return;
+ DerivedMesh *ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
+ MFace *mface= me->mface;
+ MTFace *tface= me->mtface;
+ MCol *mcol= me->mcol; /* why does mcol exist? */
+ bProperty *prop = get_property(ob, "Text");
+ int a, start= 0, totface= me->totface;
+
+ tface+= start;
+ mcol+= start*4;
+ for (a=start; a<totface; a++, tface++, mcol+=4) {
+ MFace *mf= &mface[a];
+ int mode= tface->mode;
+ int matnr= mf->mat_nr;
+ int mf_smooth= mf->flag & ME_SMOOTH;
+
+ if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
+ int badtex= set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
+ float v1[3], v2[3], v3[3], v4[3];
+ char string[MAX_PROPSTRING];
+ int characters, index;
+ ImBuf *ibuf;
+ float curpos;
+
+ if (badtex)
+ continue;
+
+ ddm->getVertCo(ddm, mf->v1, v1);
+ ddm->getVertCo(ddm, mf->v2, v2);
+ ddm->getVertCo(ddm, mf->v3, v3);
+ if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
+
+ // The BM_FONT handling code is duplicated in the gameengine
+ // Search for 'Frank van Beek' ;-)
+ // string = "Frank van Beek";
+
+ set_property_valstr(prop, string);
+ characters = strlen(string);
+
+ ibuf= BKE_image_get_ibuf(tface->tpage, NULL);
+ if (ibuf == NULL) {
+ characters = 0;
+ }
- dm = mesh_get_derived_final(ob, get_viewedit_datamask());
+ if (!mf_smooth) {
+ float nor[3];
- glShadeModel(GL_SMOOTH);
+ CalcNormFloat(v1, v2, v3, nor);
- /* option to draw solid texture with default lights */
- if(dt>OB_WIRE && G.vd->drawtype==OB_SOLID) {
- solidtex= 1;
- g_draw_tface_mesh_islight= -1;
- }
- else
- g_draw_tface_mesh_islight= set_gl_light(ob);
+ glNormal3fv(nor);
+ }
+
+ curpos= 0.0;
+ glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
+ for (index = 0; index < characters; index++) {
+ float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
+ int character = string[index];
+ char *cp= NULL;
+
+ // lets calculate offset stuff
+ // space starts at offset 1
+ // character = character - ' ' + 1;
+
+ matrixGlyph(ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+ movex+= curpos;
+
+ if (tface->mode & TF_OBCOL)
+ glColor3ubv(Gtexdraw.obcol);
+ else if (me->mcol) cp= (char *)mcol;
+ else glColor3ub(255, 255, 255);
+
+ glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
+
+ glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
- obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
- obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
- obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
- obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
+ glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
- /* first all texture polys */
+ if(mf->v4) {
+ glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
+ }
+
+ curpos+= advance;
+ }
+ glEnd();
+ }
+ }
+
+ ddm->release(ddm);
+}
+
+void draw_mesh_textured(Object *ob, DerivedMesh *dm, int faceselect)
+{
+ Mesh *me= ob->data;
+ int editing= 0;
+ /* correct for negative scale */
if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
else glFrontFace(GL_CCW);
- glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
- if(solidtex || G.vd->drawtype==OB_TEXTURE) istex= 1;
- else istex= 0;
-
- g_draw_tface_mesh_ob = ob;
- g_draw_tface_mesh_istex = istex;
- memcpy(g_draw_tface_mesh_obcol, obcol, sizeof(obcol));
- set_draw_settings_cached(1, 0, 0, g_draw_tface_mesh_islight, 0, 0, 0);
-
- if(dt > OB_SOLID || g_draw_tface_mesh_islight==-1) {
- bProperty *prop = get_property(ob, "Text");
- int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
+ /* draw the textured mesh */
+ draw_textured_begin(ob);
#ifdef WITH_VERSE
- if(me->vnode) {
- /* verse-blender doesn't support uv mapping of textures yet */
- dm->drawFacesTex(dm, NULL);
- }
- else if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) {
-#else
- if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) {
-#endif
+ if(me->vnode) {
+ /* verse-blender doesn't support uv mapping of textures yet */
+ dm->drawFacesTex(dm, NULL);
+ }
+ else {
+#endif
+ if(ob==G.obedit) {
+ dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, G.editMesh);
+ } else if(faceselect) {
if(G.f & G_WEIGHTPAINT)
- dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, (void*)me, 1);
+ dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1);
else
- dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, (void*)me);
+ dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me);
}
else
dm->drawFacesTex(dm, draw_tface__set_draw);
+#ifdef WITH_VERSE
+ }
+#endif
- /* drawing game engine text hack */
- if (!editing && prop && me->mtface) {
- DerivedMesh *ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
- MFace *mface= me->mface;
- MTFace *tface= me->mtface;
- MCol *mcol= me->mcol; /* why does mcol exist? */
- int start= 0, totface= me->totface;
-
- tface+= start;
- mcol+= start*4;
- for (a=start; a<totface; a++, tface++, mcol+=4) {
- MFace *mf= &mface[a];
- int mode= tface->mode;
- int matnr= mf->mat_nr;
- int mf_smooth= mf->flag & ME_SMOOTH;
-
- if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
- int badtex= set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE);
- float v1[3], v2[3], v3[3], v4[3];
- char string[MAX_PROPSTRING];
- int characters, index;
- ImBuf *ibuf;
- float curpos;
-
- if (badtex)
- continue;
-
- ddm->getVertCo(ddm, mf->v1, v1);
- ddm->getVertCo(ddm, mf->v2, v2);
- ddm->getVertCo(ddm, mf->v3, v3);
- if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
-
- // The BM_FONT handling code is duplicated in the gameengine
- // Search for 'Frank van Beek' ;-)
- // string = "Frank van Beek";
-
- set_property_valstr(prop, string);
- characters = strlen(string);
-
- ibuf= BKE_image_get_ibuf(tface->tpage, NULL);
- if (ibuf == NULL) {
- characters = 0;
- }
-
- if (!mf_smooth) {
- float nor[3];
-
- CalcNormFloat(v1, v2, v3, nor);
-
- glNormal3fv(nor);
- }
-
- curpos= 0.0;
- glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
- for (index = 0; index < characters; index++) {
- float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
- int character = string[index];
- char *cp= NULL;
-
- // lets calculate offset stuff
- // space starts at offset 1
- // character = character - ' ' + 1;
-
- matrixGlyph(ibuf, character, & centerx, &centery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
- movex+= curpos;
-
- if (tface->mode & TF_OBCOL) glColor3ubv(obcol);
- else if (mcol) cp= (char *)mcol;
- else glColor3ub(255, 255, 255);
-
- glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy);
- if (cp) glColor3ub(cp[3], cp[2], cp[1]);
- glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
-
- glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy);
- if (cp) glColor3ub(cp[7], cp[6], cp[5]);
- glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
-
- glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy);
- if (cp) glColor3ub(cp[11], cp[10], cp[9]);
- glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
-
- if(mf->v4) {
- glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy);
- if (cp) glColor3ub(cp[15], cp[14], cp[13]);
- glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
- }
-
- curpos+= advance;
- }
- glEnd();
- }
- }
-
- ddm->release(ddm);
- }
+ /* draw game engine text hack - but not if we are editing the mesh */
+ if (me->mtface && get_property(ob, "Text")) {
+ if(ob==G.obedit)
+ editing= 1;
+ else if(ob==OBACT)
+ if(FACESEL_PAINT_TEST)
+ editing= 1;
- /* switch off textures */
- set_tpage(0);
+ if(!editing)
+ draw_game_text_mesh(ob, me);
}
- glShadeModel(GL_FLAT);
- glDisable(GL_CULL_FACE);
+
+ draw_textured_end();
- if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) {
+ /* draw edges and selected faces over textured mesh */
+ if(!G.obedit && faceselect)
draw_tfaces3D(ob, me, dm);
- }
-
- /* XXX, bad patch - default_gl_light() calls
- * glLightfv(GL_LIGHT_POSITION, ...) which
- * is transformed by the current matrix... we
- * need to make sure that matrix is identity.
- *
- * It would be better if drawmesh.c kept track
- * of and restored the light settings it changed.
- * - zr
- */
- glPushMatrix();
- glLoadIdentity();
- default_gl_light();
- glPopMatrix();
-
- glFrontFace(GL_CCW);
-
- if(dt > OB_SOLID && !(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface)) {
- if(ob->flag & SELECT) {
- BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
- } else {
- BIF_ThemeColor(TH_WIRE);
- }
- dm->drawLooseEdges(dm);
- }
- dm->release(dm);
+ /* reset from negative scale correction */
+ glFrontFace(GL_CCW);
+
+ /* in editmode, the blend mode needs to be set incase it was ADD */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void init_realtime_GL(void)
@@ -1196,6 +1218,5 @@ void init_realtime_GL(void)
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
-
}
diff --git a/source/blender/src/drawnla.c b/source/blender/src/drawnla.c
index de35a0f2906..a0b4c7f01b3 100644
--- a/source/blender/src/drawnla.c
+++ b/source/blender/src/drawnla.c
@@ -148,6 +148,15 @@ static void draw_nla_channels(void)
else
BIF_icon_draw(x+17, y-8, ICON_ACTION);
}
+
+ /* icon to indicate if ipo-channel muted */
+ if (ob->ipo) {
+ if (ob->ipo->muteipo)
+ BIF_icon_draw(NLAWIDTH-16, y-NLACHANNELHEIGHT/2, ICON_MUTE_IPO_ON);
+ else
+ BIF_icon_draw(NLAWIDTH-16, y-NLACHANNELHEIGHT/2, ICON_MUTE_IPO_OFF);
+ }
+
glDisable(GL_BLEND);
y-=NLACHANNELHEIGHT+NLACHANNELSKIP;
@@ -192,16 +201,20 @@ static void draw_nla_channels(void)
glRasterPos2f(x+48, y-4);
BMF_DrawString(G.font, strip->act->id.name+2);
- if(strip->flag & ACTSTRIP_ACTIVE) {
- glEnable(GL_BLEND);
+ glEnable(GL_BLEND);
+
+ if(strip->flag & ACTSTRIP_ACTIVE)
BIF_icon_draw(x+16, y-8, ICON_DOT);
- glDisable(GL_BLEND);
- }
- if(strip->modifiers.first) {
- glEnable(GL_BLEND);
+
+ if(strip->modifiers.first)
BIF_icon_draw(x+34, y-8, ICON_MODIFIER);
- glDisable(GL_BLEND);
- }
+
+ if(strip->flag & ACTSTRIP_MUTE)
+ BIF_icon_draw(NLAWIDTH-16, y-NLACHANNELHEIGHT/2, ICON_MUTE_IPO_ON);
+ else
+ BIF_icon_draw(NLAWIDTH-16, y-NLACHANNELHEIGHT/2, ICON_MUTE_IPO_OFF);
+
+ glDisable(GL_BLEND);
}
y-=(NLACHANNELHEIGHT+NLACHANNELSKIP);
@@ -433,11 +446,13 @@ static void draw_nla_strips_keys(SpaceNla *snla)
#define B_NLA_PANEL 121
#define B_NLA_LOCK 122
-#define B_NLA_MOD_ADD 123
-#define B_NLA_MOD_NEXT 124
-#define B_NLA_MOD_PREV 125
-#define B_NLA_MOD_DEL 126
-#define B_NLA_MOD_DEPS 127
+#define B_NLA_SCALE 123
+#define B_NLA_SCALE2 124
+#define B_NLA_MOD_ADD 125
+#define B_NLA_MOD_NEXT 126
+#define B_NLA_MOD_PREV 127
+#define B_NLA_MOD_DEL 128
+#define B_NLA_MOD_DEPS 129
/* For now just returns the first selected strip */
bActionStrip *get_active_nlastrip(Object **obpp)
@@ -478,9 +493,37 @@ void do_nlabuts(unsigned short event)
allqueue (REDRAWNLA, 0);
allqueue (REDRAWVIEW3D, 0);
break;
+ case B_NLA_SCALE:
+ {
+ float actlen= strip->actend - strip->actstart;
+ float mapping= strip->scale * strip->repeat;
+
+ strip->end = (actlen * mapping) + strip->start;
+
+ allqueue (REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWVIEW3D, 0);
+ }
+ break;
+ case B_NLA_SCALE2:
+ {
+ float actlen= strip->actend - strip->actstart;
+ float len= strip->end - strip->start;
+
+ strip->scale= len / (actlen * strip->repeat);
+
+ allqueue (REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWVIEW3D, 0);
+ }
+ break;
case B_NLA_LOCK:
synchronize_action_strips();
+
allqueue (REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
allqueue (REDRAWACTION, 0);
allqueue (REDRAWVIEW3D, 0);
break;
@@ -563,7 +606,7 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NLA_PANEL, "Strip Start:", 10,160,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline");
- uiDefButF(block, NUM, B_NLA_PANEL, "Strip End:", 160,160,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
+ uiDefButF(block, NUM, B_NLA_SCALE2, "Strip End:", 160,160,150,19, &strip->end, strip->start+1, MAXFRAMEF, 100, 0, "Last frame in the timeline");
uiDefIconButBitS(block, ICONTOG, ACTSTRIP_LOCK_ACTION, B_NLA_LOCK, ICON_UNLOCKED, 10,140,20,19, &(strip->flag), 0, 0, 0, 0, "Toggles Action end/start to be automatic mapped to strip duration");
if(strip->flag & ACTSTRIP_LOCK_ACTION) {
@@ -594,7 +637,15 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES
uiDefButBitS(block, TOG, ACTSTRIP_MUTE, B_NLA_PANEL, "Mute", 10,60,145,19, &strip->flag, 0, 0, 0, 0, "Toggles whether the strip contributes to the NLA solution");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 160,100,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat");
+ // FIXME: repeat and scale are too cramped!
+ uiDefButF(block, NUM, B_NLA_SCALE, "Repeat:", 160,100,75,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat");
+ if ((strip->actend - strip->actstart) < 1.0f) {
+ uiBlockSetCol(block, TH_REDALERT);
+ uiDefButF(block, NUM, B_NLA_SCALE, "Scale:", 235,100,75,19, &strip->scale, 0.001, 1000.0f, 100, 0, "Please run Alt-S to fix up this error");
+ uiBlockSetCol(block, TH_AUTO);
+ }
+ else
+ uiDefButF(block, NUM, B_NLA_SCALE, "Scale:", 235,100,75,19, &strip->scale, 0.001, 1000.0f, 100, 0, "Amount the action should be scaled by");
but= uiDefButC(block, TEX, B_NLA_PANEL, "OffsBone:", 160,80,150,19, strip->offs_bone, 0, 31.0f, 0, 0, "Name of Bone that defines offset for repeat");
uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,60,75,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip");
@@ -741,7 +792,7 @@ void drawnlaspace(ScrArea *sa, void *spacedata)
draw_cfra_action();
/* draw markers */
- draw_markers_timespace();
+ draw_markers_timespace(SCE_MARKERS, 0);
/* Draw preview 'curtains' */
draw_anim_preview_timespace();
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index 883fd05909f..2fe89727c43 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -1,5 +1,5 @@
/**
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -36,16 +36,19 @@
#include "DNA_action_types.h"
#include "DNA_color_types.h"
+#include "DNA_customdata_types.h"
#include "DNA_ipo_types.h"
#include "DNA_ID.h"
#include "DNA_image_types.h"
#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
+#include "DNA_text_types.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
@@ -56,6 +59,7 @@
#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_texture.h"
+#include "BKE_text.h"
#include "BKE_utildefines.h"
#include "CMP_node.h"
@@ -88,6 +92,49 @@
#include "interface.h" /* urm... for rasterpos_safe, roundbox */
#include "mydevice.h"
+extern void autocomplete_uv(char *str, void *arg_v);
+extern int verify_valid_uv_name(char *str);
+
+/* autocomplete callback for buttons */
+static void autocomplete_vcol(char *str, void *arg_v)
+{
+ Mesh *me;
+ CustomDataLayer *layer;
+ AutoComplete *autocpl;
+ int a;
+
+ if(str[0]==0)
+ return;
+
+ autocpl= autocomplete_begin(str, 32);
+
+ /* search if str matches the beginning of name */
+ for(me= G.main->mesh.first; me; me=me->id.next)
+ for(a=0, layer= me->fdata.layers; a<me->fdata.totlayer; a++, layer++)
+ if(layer->type == CD_MCOL)
+ autocomplete_do_name(autocpl, layer->name);
+
+ autocomplete_end(autocpl, str);
+}
+
+static int verify_valid_vcol_name(char *str)
+{
+ Mesh *me;
+ CustomDataLayer *layer;
+ int a;
+
+ if(str[0]==0)
+ return 1;
+
+ /* search if str matches the name */
+ for(me= G.main->mesh.first; me; me=me->id.next)
+ for(a=0, layer= me->fdata.layers; a<me->fdata.totlayer; a++, layer++)
+ if(layer->type == CD_MCOL)
+ if(strcmp(layer->name, str)==0)
+ return 1;
+
+ return 0;
+}
static void snode_drawstring(SpaceNode *snode, char *str, int okwidth)
{
@@ -200,6 +247,14 @@ static void node_but_title_cb(void *node_v, void *but_v)
allqueue(REDRAWNODE, 0);
}
+static void node_group_alone_cb(void *node_v, void *unused_v)
+{
+ bNode *node= node_v;
+
+ nodeCopyGroup(node);
+
+ allqueue(REDRAWNODE, 0);
+}
/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */
@@ -224,8 +279,8 @@ static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *
sprintf(str1, "%d", node->id->us);
bt= uiDefBut(block, BUT, B_NOP, str1,
butr->xmax-19, butr->ymin, 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);
+ NULL, 0, 0, 0, 0, "Displays number of users.");
+ uiButSetFunc(bt, node_group_alone_cb, node, NULL);
}
uiBlockEndAlign(block);
@@ -292,6 +347,31 @@ static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf
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;
+
+ curvemap_buttons(block, node->storage, 's', B_NODE_EXEC+node->nr, 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);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Sta:",
+ butr->xmin, butr->ymin-22, dx, 19,
+ &node->custom1, 1.0, 20000.0, 0, 0, "Start frame");
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "End:",
+ butr->xmin+dx, butr->ymin-22, dx, 19,
+ &node->custom2, 1.0, 20000.0, 0, 0, "End frame");
+ }
+
+ return node->width-NODE_DY;
+}
+
static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
@@ -310,9 +390,23 @@ static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rct
return (int)(node->width-NODE_DY);
}
+static float *_sample_col= NULL; // bad bad, 2.5 will do better?
+void node_curvemap_sample(float *col)
+{
+ _sample_col= col;
+}
+
static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
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;
+
curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC+node->nr, B_REDR, butr);
}
return (int)(node->width-NODE_DY);
@@ -358,6 +452,37 @@ static void node_browse_tex_cb(void *ntree_v, void *node_v)
node->menunr= 0;
}
+static void node_dynamic_update_cb(void *ntree_v, void *node_v)
+{
+ Material *ma;
+ bNode *node= (bNode *)node_v;
+ ID *id= node->id;
+ int error= 0;
+
+ if (BTST(node->custom1, NODE_DYNAMIC_ERROR)) error= 1;
+
+ /* Users only have to press the "update" button in one pynode
+ * and we also update all others sharing the same script */
+ for (ma= G.main->mat.first; ma; ma= ma->id.next) {
+ if (ma->nodetree) {
+ bNode *nd;
+ for (nd= ma->nodetree->nodes.first; nd; nd= nd->next) {
+ if ((nd->type == NODE_DYNAMIC) && (nd->id == id)) {
+ nd->custom1= 0;
+ nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_REPARSE);
+ nd->menunr= 0;
+ if (error)
+ nd->custom1= BSET(nd->custom1, NODE_DYNAMIC_ERROR);
+ }
+ }
+ }
+ }
+
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWNODE, 0);
+ BIF_preview_changed(ID_MA);
+}
+
static int node_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
@@ -399,6 +524,31 @@ static int node_buts_math(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *b
/* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */
+static void node_browse_text_cb(void *ntree_v, void *node_v)
+{
+ bNodeTree *ntree= ntree_v;
+ bNode *node= node_v;
+ ID *oldid;
+
+ if(node->menunr<1) return;
+
+ if(node->id) {
+ node->id->us--;
+ }
+ oldid= node->id;
+ node->id= BLI_findlink(&G.main->text, node->menunr-1);
+ id_us_plus(node->id);
+ BLI_strncpy(node->name, node->id->name+2, 21); /* huh? why 21? */
+
+ node->custom1= BSET(node->custom1, NODE_DYNAMIC_NEW);
+
+ nodeSetActive(ntree, node);
+
+ allqueue(REDRAWBUTSSHADING, 0);
+ allqueue(REDRAWNODE, 0);
+
+ node->menunr= 0;
+}
static void node_mat_alone_cb(void *node_v, void *unused)
{
@@ -606,15 +756,61 @@ static int node_shader_buts_vect_math(uiBlock *block, bNodeTree *ntree, bNode *n
static int node_shader_buts_geometry(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
+ uiBut *but;
NodeGeometry *ngeo= (NodeGeometry*)node->storage;
- uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "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");
- uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "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");
+ if(!verify_valid_uv_name(ngeo->uvname))
+ uiBlockSetCol(block, TH_REDALERT);
+ but= uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "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");
+ uiButSetCompleteFunc(but, autocomplete_uv, NULL);
+ uiBlockSetCol(block, TH_AUTO);
+
+ if(!verify_valid_vcol_name(ngeo->colname))
+ uiBlockSetCol(block, TH_REDALERT);
+ but= uiDefBut(block, TEX, B_NODE_EXEC+node->nr, "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);
+ uiBlockSetCol(block, TH_AUTO);
}
return 40;
}
+static int node_shader_buts_dynamic(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ if (block) {
+ uiBut *bt;
+ 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)) {
+ BIF_ThemeColor(TH_REDALERT);
+ ui_rasterpos_safe(butr->xmin + xoff, butr->ymin + 5, snode->aspect);
+ snode_drawstring(snode, "Error! Check console...", butr->xmax - butr->xmin);
+ }
+ }
+ }
+ return 20+19;
+}
+
/* only once called */
static void node_shader_set_butfunc(bNodeType *ntype)
{
@@ -661,6 +857,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_GEOMETRY:
ntype->butfunc= node_shader_buts_geometry;
break;
+ case NODE_DYNAMIC:
+ ntype->butfunc= node_shader_buts_dynamic;
+ break;
default:
ntype->butfunc= NULL;
}
@@ -805,14 +1004,14 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
dy-= 19;
uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Frs:",
xmin, dy, width, 19,
- &iuser->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation");
+ &iuser->frames, 1.0, MAXFRAMEF, 0, 0, "Amount of images used in animation");
uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "SFra:",
xmin+width, dy, width, 19,
- &iuser->sfra, 1.0, 10000.0, 0, 0, "Start frame of animation");
+ &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Start frame of animation");
dy-= 19;
uiDefButI(block, NUM, B_NODE_EXEC+node->nr, "Offs:",
xmin, dy, width, 19,
- &iuser->offset, -10000.0, 10000.0, 0, 0, "Offsets the number of the frame to use in the animation");
+ &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation");
uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Cycl",
xmin+width, dy, width-20, 19,
&iuser->cycl, 0.0, 0.0, 0, 0, "Make animation go cyclic");
@@ -829,7 +1028,7 @@ static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *nod
bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp,
xmin, dy, width, 19,
&iuser->layer, 0.0, 10000.0, 0, 0, "Layer");
- uiButSetFunc(bt, image_layer_cb, ima, node->storage);
+ uiButSetFunc(bt, image_layer_cb, ima->rr, node->storage);
MEM_freeN(strp);
}
}
@@ -967,35 +1166,168 @@ static int node_composit_buts_renderlayers(uiBlock *block, bNodeTree *ntree, bNo
return 19;
}
+static void node_blur_relative_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+ if(nbd->image_in_width != 0){
+ if(nbd->relative){ /* convert absolute values to relative */
+ nbd->percentx= (float)(nbd->sizex)/nbd->image_in_width;
+ nbd->percenty= (float)(nbd->sizey)/nbd->image_in_height;
+ }else{ /* convert relative values to absolute */
+ nbd->sizex= (int)(nbd->percentx*nbd->image_in_width);
+ nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
+ }
+ }
+ allqueue(REDRAWNODE, 0);
+}
+static void node_blur_update_sizex_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+
+ nbd->sizex= (int)(nbd->percentx*nbd->image_in_width);
+}
+static void node_blur_update_sizey_cb(void *node, void *poin2)
+{
+ bNode *nodev= node;
+ NodeBlurData *nbd= nodev->storage;
+
+ nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
+}
static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
NodeBlurData *nbd= node->storage;
uiBut *bt;
- short dy= butr->ymin+38;
+ 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|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH);
- uiDefButS(block, MENU, B_NODE_EXEC+node->nr,str,
+ 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+node->nr,str,
butr->xmin, dy, dx*2, 19,
&nbd->filtertype, 0, 0, 0, 0, "Set sampling filter for blur");
- dy-=19;
- uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "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+node->nr, "Gamma",
- butr->xmin+dx, dy, dx, 19,
- &nbd->gamma, 0, 0, 0, 0, "Applies filter on gamma corrected values");
+ dy-=19;
+ if (nbd->filtertype != R_FILTER_FAST_GAUSS) {
+ uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "X:",
+ butr->xmin, dy, dx, 19,
+ &nbd->sizex, 0, 256, 0, 0, "");
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:",
+ butr->xmin+dx, dy, dx, 19,
+ &nbd->sizey, 0, 256, 0, 0, "");
+ }
+ uiBlockEndAlign(block);
+ }
+ return 77;
+}
+
+static int node_composit_buts_dblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ 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+node->nr, "Iterations:",
+ butr->xmin, dy, dx, 19,
+ &ndbd->iter, 1, 32, 10, 0, "Amount of iterations");
+ uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "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+node->nr, "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+node->nr, "Y:",
+ butr->xmin+halfdx, dy, halfdx, 19,
+ &ndbd->center_y, 0.0f, 1.0f, 10, 0, "Y center in percents");
+ uiBlockEndAlign(block);
+
+ dy-= 9;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "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+node->nr, "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);
+
+ dy-= 9;
+
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Spin:",
+ butr->xmin, dy-= 19, dx, 19,
+ &ndbd->spin, -360.0f, 360.0f, 1000, 0, "Angle that is used to spin the image");
+
+ dy-= 9;
+
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Zoom:",
+ butr->xmin, dy-= 19, dx, 19,
+ &ndbd->zoom, 0.0f, 100.0f, 100, 0, "Amount of which the image is zoomed");
+
+ }
+ return 190;
+}
+
+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+node->nr, "Iterations:",
+ butr->xmin, dy, dx, 19,
+ &nbbd->iter, 1, 128, 0, 0, "Amount of iterations");
dy-=19;
- bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X:",
- butr->xmin, dy, dx, 19,
- &nbd->sizex, 0, 256, 0, 0, "");
- bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:",
- butr->xmin+dx, dy, dx, 19,
- &nbd->sizey, 0, 256, 0, 0, "");
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "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+node->nr, "Space Sigma:",
+ butr->xmin, dy, dx, 19,
+ &nbbd->sigma_space ,0.01, 30, 10, 0, "Sigma value used to modify space");
+
}
return 57;
}
@@ -1054,6 +1386,145 @@ static int node_composit_buts_defocus(uiBlock *block, bNodeTree *ntree, bNode *n
return 228;
}
+
+/* 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+node->nr, mn1,
+ butr->xmin, dy, dx, 19,
+ &ndg->type, 0, 0, 0, 0, "Glow/Flare/Bloom type");
+ uiDefButC(block, MENU, B_NODE_EXEC+node->nr, 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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "streaks:",
+ butr->xmin, dy-114, dx, 19,
+ &ndg->angle, 2, 16, 1000, 0,
+ "Total number of streaks");
+ uiDefButC(block, NUM, B_NODE_EXEC+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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)");
+ }
+ 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+node->nr, 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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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+node->nr, "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);
+ }
+ return 95;
+}
+
+/* qdn: lens distortion node */
+static int node_composit_buts_lensdist(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ if(block) {
+ NodeLensDist *nld = node->storage;
+ short dy = butr->ymin + 19, dx = butr->xmax - butr->xmin;
+ uiBlockBeginAlign(block);
+ uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "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+node->nr, "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+node->nr, "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;
+}
+
+
static int node_composit_buts_vecblur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
@@ -1063,19 +1534,23 @@ static int node_composit_buts_vecblur(uiBlock *block, bNodeTree *ntree, bNode *n
uiBlockBeginAlign(block);
uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Samples:",
- butr->xmin, dy+57, dx, 19,
+ butr->xmin, dy+76, dx, 19,
&nbd->samples, 1, 256, 0, 0, "Amount of samples");
uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "MinSpeed:",
- butr->xmin, dy+38, dx, 19,
+ butr->xmin, dy+57, dx, 19,
&nbd->minspeed, 0, 1024, 0, 0, "Minimum speed for a pixel to be blurred, used to separate background from foreground");
uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "MaxSpeed:",
- butr->xmin, dy+19, dx, 19,
+ butr->xmin, dy+38, dx, 19,
&nbd->maxspeed, 0, 1024, 0, 0, "If not zero, maximum speed in pixels");
uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "BlurFac:",
- butr->xmin, dy, dx, 19,
+ butr->xmin, dy+19, dx, 19,
&nbd->fac, 0.0f, 2.0f, 10, 2, "Scaling factor for motion vectors, actually 'shutter speed' in frames");
+ uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Curved",
+ butr->xmin, dy, dx, 19,
+ &nbd->curved, 0.0f, 2.0f, 10, 2, "Interpolate between frames in a bezier curve, rather than linearly");
+ uiBlockEndAlign(block);
}
- return 76;
+ return 95;
}
static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
@@ -1106,6 +1581,49 @@ static int node_composit_buts_flip(uiBlock *block, bNodeTree *ntree, bNode *node
return 20;
}
+static int node_composit_buts_crop(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ 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+node->nr, "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+node->nr, "X1:",
+ butr->xmin, dy, dx, elementheight,
+ &ntxy->x1, xymin, xymax, 0, 0, "");
+ /* y1 */
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y1:",
+ butr->xmin+dx, dy, dx, elementheight,
+ &ntxy->y1, xymin, xymax, 0, 0, "");
+
+ dy-=elementheight;
+
+ /* x2 */
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X2:",
+ butr->xmin, dy, dx, elementheight,
+ &ntxy->x2, xymin, xymax, 0, 0, "");
+ /* y2 */
+ uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y2:",
+ butr->xmin+dx, dy, dx, elementheight,
+ &ntxy->y2, xymin, xymax, 0, 0, "");
+
+ uiBlockEndAlign(block);
+ }
+ return 60;
+}
+
static int node_composit_buts_splitviewer(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
@@ -1147,45 +1665,21 @@ static int node_composit_buts_map_value(uiBlock *block, bNodeTree *ntree, bNode
return 80;
}
-static int node_composit_buts_time(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
-{
- if(block) {
- CurveMapping *cumap= node->storage;
- short dx= (butr->xmax-butr->xmin)/2;
- rctf *curvebutr;
-
- memcpy(&curvebutr, &butr, sizeof(rctf));
- curvebutr->ymin += 26;
-
- curvemap_buttons(block, node->storage, 's', B_NODE_EXEC+node->nr, B_REDR, curvebutr);
-
- cumap->flag |= CUMA_DRAW_CFRA;
- if(node->custom1<node->custom2)
- cumap->black[0]= (float)(CFRA - node->custom1)/(float)(node->custom2-node->custom1);
-
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Sta:",
- butr->xmin, butr->ymin-22, dx, 19,
- &node->custom1, 1.0, 20000.0, 0, 0, "Start frame");
- uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "End:",
- butr->xmin+dx, butr->ymin-22, dx, 19,
- &node->custom2, 1.0, 20000.0, 0, 0, "End frame");
-
- }
-
- return node->width-NODE_DY;
-}
-
static int node_composit_buts_alphaover(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
+ NodeTwoFloats *ntf= node->storage;
/* alpha type */
uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "ConvertPremul",
- butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
+ butr->xmin, butr->ymin+19, butr->xmax-butr->xmin, 19,
&node->custom1, 0, 0, 0, 0, "");
+ /* mix factor */
+ uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "Premul: ",
+ butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19,
+ &ntf->x, 0.0f, 1.0f, 100, 0, "");
}
- return 19;
+ return 38;
}
static int node_composit_buts_hue_sat(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
@@ -1283,7 +1777,7 @@ static int node_composit_buts_color_spill(uiBlock *block, bNodeTree *ntree, bNod
uiBlockEndAlign(block);
}
return 60;
- }
+}
static int node_composit_buts_chroma_matte(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
@@ -1415,7 +1909,6 @@ static int node_composit_buts_id_mask(uiBlock *block, bNodeTree *ntree, bNode *n
return 20;
}
-
/* allocate sufficient! */
static void node_imagetype_string(char *str)
{
@@ -1432,10 +1925,19 @@ static void node_imagetype_string(char *str)
str += sprintf(str, "OpenEXR %%x%d", R_OPENEXR);
}
+static void node_set_image_cb(void *ntree_v, void *node_v)
+{
+ bNodeTree *ntree= ntree_v;
+ bNode *node= node_v;
+
+ nodeSetActive(ntree, node);
+}
+
static int node_composit_buts_file_output(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
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;
@@ -1445,8 +1947,13 @@ static int node_composit_buts_file_output(uiBlock *block, bNodeTree *ntree, bNod
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, "",
- x, y+60, w, 20,
+ 20+x, y+60, w-20, 20,
nif->name, 0.0f, 240.0f, 0, 0, "");
uiDefButS(block, MENU, B_NOP, str,
@@ -1487,7 +1994,7 @@ static void node_scale_cb(void *node_v, void *unused_v)
/* check the 2 inputs, and set them to reasonable values */
for(nsock= node->inputs.first; nsock; nsock= nsock->next) {
- if(node->custom1==CMP_SCALE_RELATIVE)
+ if(ELEM(node->custom1, CMP_SCALE_RELATIVE, CMP_SCALE_SCENEPERCENT))
nsock->ns.vec[0]= 1.0;
else {
if(nsock->next==NULL)
@@ -1501,9 +2008,9 @@ static void node_scale_cb(void *node_v, void *unused_v)
static int node_composit_buts_scale(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
{
if(block) {
- uiBut *bt= uiDefButS(block, TOG, B_NODE_EXEC+node->nr, "Absolute",
+ uiBut *bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "Relative %x0|Absolute %x1|Scene Size % %x2|",
butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20,
- &node->custom1, 0, 0, 0, 0, "");
+ &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;
@@ -1524,6 +2031,19 @@ static int node_composit_buts_invert(uiBlock *block, bNodeTree *ntree, bNode *no
return 20;
}
+static int node_composit_buts_premulkey(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr)
+{
+ if(block) {
+ uiBut *bt;
+
+ /* blend type */
+ bt=uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "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;
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -1563,13 +2083,34 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_VALTORGB:
ntype->butfunc= node_buts_valtorgb;
break;
+ case CMP_NODE_CROP:
+ ntype->butfunc= node_composit_buts_crop;
+ break;
case CMP_NODE_BLUR:
ntype->butfunc= node_composit_buts_blur;
break;
- /* qdn: defocus node */
+ case CMP_NODE_DBLUR:
+ ntype->butfunc= node_composit_buts_dblur;
+ break;
+ case CMP_NODE_BILATERALBLUR:
+ ntype->butfunc= node_composit_buts_bilateralblur;
+ break;
+ /* qdn: defocus node */
case CMP_NODE_DEFOCUS:
ntype->butfunc = node_composit_buts_defocus;
break;
+ /* qdn: glare node */
+ case CMP_NODE_GLARE:
+ ntype->butfunc = node_composit_buts_glare;
+ break;
+ /* qdn: tonemap node */
+ case CMP_NODE_TONEMAP:
+ ntype->butfunc = node_composit_buts_tonemap;
+ break;
+ /* qdn: lens distortion node */
+ case CMP_NODE_LENSDIST:
+ ntype->butfunc = node_composit_buts_lensdist;
+ break;
case CMP_NODE_VECBLUR:
ntype->butfunc= node_composit_buts_vecblur;
break;
@@ -1580,7 +2121,7 @@ static void node_composit_set_butfunc(bNodeType *ntype)
ntype->butfunc= node_composit_buts_map_value;
break;
case CMP_NODE_TIME:
- ntype->butfunc= node_composit_buts_time;
+ ntype->butfunc= node_buts_time;
break;
case CMP_NODE_ALPHAOVER:
ntype->butfunc= node_composit_buts_alphaover;
@@ -1628,6 +2169,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_INVERT:
ntype->butfunc= node_composit_buts_invert;
break;
+ case CMP_NODE_PREMULKEY:
+ ntype->butfunc= node_composit_buts_premulkey;
+ break;
default:
ntype->butfunc= NULL;
}
@@ -1656,6 +2200,45 @@ void init_node_butfuncs(void)
/* ************** Generic drawing ************** */
+void node_rename_but(char *s)
+{
+ uiBlock *block;
+ ListBase listb={0, 0};
+ int dy, x1, y1, sizex=80, sizey=30;
+ short pivot[2], mval[2], ret=0;
+
+ getmouseco_sc(mval);
+
+ pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30);
+ pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10);
+
+ if (pivot[0]!=mval[0] || pivot[1]!=mval[1])
+ warp_pointer(pivot[0], pivot[1]);
+
+ mywinset(G.curscreen->mainwin);
+
+ x1= pivot[0]-sizex+10;
+ y1= pivot[1]-sizey/2;
+ dy= sizey/2;
+
+ block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK);
+
+ /* buttons have 0 as return event, to prevent menu to close on hotkeys */
+ uiBlockBeginAlign(block);
+
+ uiDefBut(block, TEX, B_NOP, "Name: ", (short)(x1),(short)(y1+dy), 150, 19, s, 0.0, 19.0, 0, 0, "Node user name");
+
+ uiBlockEndAlign(block);
+
+ uiDefBut(block, BUT, 32767, "OK", (short)(x1+150), (short)(y1+dy), 29, 19, NULL, 0, 0, 0, 0, "");
+
+ uiBoundsBlock(block, 2);
+
+ ret= uiDoBlocks(&listb, 0, 0);
+}
+
+
static void draw_nodespace_grid(SpaceNode *snode)
{
float start, step= 25.0f;
@@ -1686,12 +2269,12 @@ static void draw_nodespace_grid(SpaceNode *snode)
glEnd();
}
-static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode)
+static void draw_nodespace_back_pix(ScrArea *sa, SpaceNode *snode)
{
-
+
draw_nodespace_grid(snode);
- if(snode->flag & SNODE_BACKDRAW) {
+ if((snode->flag & SNODE_BACKDRAW) && snode->treetype==NTREE_COMPOSIT) {
Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
if(ibuf) {
@@ -1701,10 +2284,10 @@ static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode)
glaDefine2DArea(&sa->winrct);
/* ortho at pixel level curarea */
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
-
+
x = (sa->winx-ibuf->x)/2 + snode->xof;
- y = (sa->winx-ibuf->y)/2 + snode->yof;
-
+ y = (sa->winy-ibuf->y)/2 + snode->yof;
+
if(ibuf->rect)
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
else if(ibuf->channels==4)
@@ -1718,39 +2301,59 @@ static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode)
}
}
-static void nodeshadow(rctf *rct, float radius, float aspect, int select)
+#if 0
+/* note: needs to be userpref or opengl profile option */
+static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
{
- float rad;
- float a;
- char alpha= 2;
-
- glEnable(GL_BLEND);
-
- if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
- rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
- else
- rad= radius;
+
+ draw_nodespace_grid(snode);
- if(select) a= 10.0f*aspect; else a= 7.0f*aspect;
- for(; a>0.0f; a-=aspect) {
- /* alpha ranges from 2 to 20 or so */
- glColor4ub(0, 0, 0, alpha);
- alpha+= 2;
-
- gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
+ if(snode->flag & SNODE_BACKDRAW) {
+ Image *ima= BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ if(ibuf) {
+ int x, y;
+ float zoom = 1.0;
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ glaDefine2DArea(&sa->winrct);
+
+ if(ibuf->x > sa->winx || ibuf->y > sa->winy) {
+ float zoomx, zoomy;
+ zoomx= (float)sa->winx/ibuf->x;
+ zoomy= (float)sa->winy/ibuf->y;
+ zoom = MIN2(zoomx, zoomy);
+ }
+
+ x = (sa->winx-zoom*ibuf->x)/2 + snode->xof;
+ y = (sa->winy-zoom*ibuf->y)/2 + snode->yof;
+
+ glPixelZoom(zoom, zoom);
+
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ if(ibuf->rect)
+ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ else if(ibuf->channels==4)
+ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, ibuf->rect_float);
+
+ glPixelZoom(1.0, 1.0);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
}
-
- /* outline emphasis */
- glEnable( GL_LINE_SMOOTH );
- glColor4ub(0, 0, 0, 100);
- gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius);
- glDisable( GL_LINE_SMOOTH );
-
- glDisable(GL_BLEND);
}
+#endif
/* nice AA filled circle */
-static void socket_circle_draw(float x, float y, float size, int type, int select)
+/* this might have some more generic use */
+static void circle_draw(float x, float y, float size, int type, int col[3])
{
/* 16 values of sin function */
static float si[16] = {
@@ -1768,28 +2371,7 @@ static void socket_circle_draw(float x, float y, float size, int type, int selec
};
int a;
- if(select==0) {
- if(type==-1)
- glColor3ub(0, 0, 0);
- else if(type==SOCK_VALUE)
- glColor3ub(160, 160, 160);
- else if(type==SOCK_VECTOR)
- glColor3ub(100, 100, 200);
- else if(type==SOCK_RGBA)
- glColor3ub(200, 200, 40);
- else
- glColor3ub(100, 200, 100);
- }
- else {
- if(type==SOCK_VALUE)
- glColor3ub(200, 200, 200);
- else if(type==SOCK_VECTOR)
- glColor3ub(140, 140, 240);
- else if(type==SOCK_RGBA)
- glColor3ub(240, 240, 100);
- else
- glColor3ub(140, 240, 140);
- }
+ glColor3ub(col[0], col[1], col[2]);
glBegin(GL_POLYGON);
for(a=0; a<16; a++)
@@ -1807,6 +2389,41 @@ static void socket_circle_draw(float x, float y, float size, int type, int selec
glDisable(GL_BLEND);
}
+static void socket_circle_draw(bNodeSocket *sock, float size)
+{
+ int col[3];
+
+ /* choose color based on sock flags */
+ if(sock->flag & SELECT) {
+ if(sock->flag & SOCK_SEL) {
+ col[0]= 240; col[1]= 200; col[2]= 40;}
+ else if(sock->type==SOCK_VALUE) {
+ col[0]= 200; col[1]= 200; col[2]= 200;}
+ else if(sock->type==SOCK_VECTOR) {
+ col[0]= 140; col[1]= 140; col[2]= 240;}
+ else if(sock->type==SOCK_RGBA) {
+ col[0]= 240; col[1]= 240; col[2]= 100;}
+ else {
+ col[0]= 140; col[1]= 240; col[2]= 140;}
+ }
+ else if(sock->flag & SOCK_SEL) {
+ col[0]= 200; col[1]= 160; col[2]= 0;}
+ else {
+ if(sock->type==-1) {
+ col[0]= 0; col[1]= 0; col[2]= 0;}
+ else if(sock->type==SOCK_VALUE) {
+ col[0]= 160; col[1]= 160; col[2]= 160;}
+ else if(sock->type==SOCK_VECTOR) {
+ col[0]= 100; col[1]= 100; col[2]= 200;}
+ else if(sock->type==SOCK_RGBA) {
+ col[0]= 200; col[1]= 200; col[2]= 40;}
+ else {
+ col[0]= 100; col[1]= 200; col[2]= 100;}
+ }
+
+ circle_draw(sock->locx, sock->locy, size, sock->type, col);
+}
+
/* not a callback */
static void node_draw_preview(bNodePreview *preview, rctf *prv)
{
@@ -1849,6 +2466,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); /* premul graphics */
+ glColor4f(1.0, 1.0, 1.0, 1.0);
glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_FLOAT, preview->rect);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@@ -1955,8 +2573,12 @@ static void node_update(bNode *node)
node->prvr.xmin+= 0.5*dx;
node->prvr.xmax-= 0.5*dx;
}
-
+
dy= node->prvr.ymin - NODE_DYS/2;
+
+ /* make sure that maximums are bigger or equal to minimums */
+ if(node->prvr.xmax < node->prvr.xmin) SWAP(float, node->prvr.xmax, node->prvr.xmin);
+ if(node->prvr.ymax < node->prvr.ymin) SWAP(float, node->prvr.ymax, node->prvr.ymin);
}
else {
float oldh= node->prvr.ymax - node->prvr.ymin;
@@ -1968,6 +2590,10 @@ static void node_update(bNode *node)
dy= node->prvr.ymin - NODE_DYS/2;
}
}
+
+ /* XXX ugly hack, typeinfo for group is generated */
+ if(node->type == NODE_GROUP)
+ node->typeinfo->butfunc= node_buts_group;
/* buttons rect? */
if((node->flag & NODE_OPTIONS) && node->typeinfo->butfunc) {
@@ -2083,6 +2709,168 @@ static int node_get_colorid(bNode *node)
return TH_NODE;
}
+static void node_draw_link_bezier(float vec[][3], int th_col1, int th_col2, int do_shaded)
+{
+ float dist;
+
+ dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
+
+ /* check direction later, for top sockets */
+ vec[1][0]= vec[0][0]+dist;
+ vec[1][1]= vec[0][1];
+
+ vec[2][0]= vec[3][0]-dist;
+ vec[2][1]= vec[3][1];
+
+ if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > G.v2d->cur.xmax); /* clipped */
+ else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */
+ else {
+ float curve_res = 24, spline_step = 0.0f;
+
+ /* we can reuse the dist variable here to increment the GL curve eval amount*/
+ dist = 1.0f/curve_res;
+
+ glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
+ glBegin(GL_LINE_STRIP);
+ while (spline_step < 1.000001f) {
+ if(do_shaded)
+ BIF_ThemeColorBlend(th_col1, th_col2, spline_step);
+ glEvalCoord1f(spline_step);
+ spline_step += dist;
+ }
+ glEnd();
+ }
+
+}
+
+/* note; this is used for fake links in groups too */
+void node_draw_link(SpaceNode *snode, bNodeLink *link)
+{
+ float vec[4][3];
+ float mx=0.0f, my=0.0f;
+ int do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
+
+ if(link->fromnode==NULL && link->tonode==NULL)
+ return;
+
+ /* this is dragging link */
+ if(link->fromnode==NULL || link->tonode==NULL) {
+ short mval[2];
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
+ BIF_ThemeColor(TH_WIRE);
+ do_shaded= 0;
+ }
+ else {
+ /* going to give issues once... */
+ if(link->tosock->flag & SOCK_UNAVAIL)
+ return;
+ if(link->fromsock->flag & SOCK_UNAVAIL)
+ return;
+
+ /* a bit ugly... but thats how we detect the internal group links */
+ if(link->fromnode==link->tonode) {
+ BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
+ do_shaded= 0;
+ }
+ else {
+ /* check cyclic */
+ if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
+ if(link->fromnode->flag & SELECT)
+ th_col1= TH_EDGE_SELECT;
+ if(link->tonode->flag & SELECT)
+ th_col2= TH_EDGE_SELECT;
+ }
+ else {
+ BIF_ThemeColor(TH_REDALERT);
+ do_shaded= 0;
+ }
+ }
+ }
+
+ vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
+
+ /* in v0 and v3 we put begin/end points */
+ if(link->fromnode) {
+ vec[0][0]= link->fromsock->locx;
+ vec[0][1]= link->fromsock->locy;
+ }
+ else {
+ vec[0][0]= mx;
+ vec[0][1]= my;
+ }
+ if(link->tonode) {
+ vec[3][0]= link->tosock->locx;
+ vec[3][1]= link->tosock->locy;
+ }
+ else {
+ vec[3][0]= mx;
+ vec[3][1]= my;
+ }
+
+ node_draw_link_bezier(vec, th_col1, th_col2, do_shaded);
+}
+
+
+/* note: in cmp_util.c is similar code, for node_compo_pass_on() */
+static void node_draw_mute_line(SpaceNode *snode, bNode *node)
+{
+ bNodeSocket *valsock= NULL, *colsock= NULL, *vecsock= NULL;
+ bNodeSocket *sock;
+ float vec[4][3];
+ int a;
+
+ vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
+
+ /* connect the first value buffer in with first value out */
+ /* connect the first RGBA buffer in with first RGBA out */
+
+ /* test the inputs */
+ for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
+ if(nodeCountSocketLinks(snode->edittree, sock)) {
+ if(sock->type==SOCK_VALUE && valsock==NULL) valsock= sock;
+ if(sock->type==SOCK_VECTOR && vecsock==NULL) vecsock= sock;
+ if(sock->type==SOCK_RGBA && colsock==NULL) colsock= sock;
+ }
+ }
+
+ /* outputs, draw lines */
+ BIF_ThemeColor(TH_REDALERT);
+ glEnable(GL_BLEND);
+ glEnable( GL_LINE_SMOOTH );
+
+ if(valsock || colsock || vecsock) {
+ for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
+ if(nodeCountSocketLinks(snode->edittree, sock)) {
+ vec[3][0]= sock->locx;
+ vec[3][1]= sock->locy;
+
+ if(sock->type==SOCK_VALUE && valsock) {
+ vec[0][0]= valsock->locx;
+ vec[0][1]= valsock->locy;
+ node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+ valsock= NULL;
+ }
+ if(sock->type==SOCK_VECTOR && vecsock) {
+ vec[0][0]= vecsock->locx;
+ vec[0][1]= vecsock->locy;
+ node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+ vecsock= NULL;
+ }
+ if(sock->type==SOCK_RGBA && colsock) {
+ vec[0][0]= colsock->locx;
+ vec[0][1]= colsock->locy;
+ node_draw_link_bezier(vec, TH_WIRE, TH_WIRE, 0);
+ colsock= NULL;
+ }
+ }
+ }
+ }
+ glDisable(GL_BLEND);
+ glDisable( GL_LINE_SMOOTH );
+}
+
+
static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
{
bNodeSocket *sock;
@@ -2091,9 +2879,10 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
rctf *rct= &node->totr;
float slen, iconofs;
int ofs, color_id= node_get_colorid(node);
+ char showname[128]; /* 128 used below */
uiSetRoundBox(15-4);
- nodeshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
+ ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
/* header */
if(color_id==TH_NODE)
@@ -2120,8 +2909,6 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
glDisable(GL_BLEND);
}
if(node->type == NODE_GROUP) {
- /* XXX ugly hack */
- node->typeinfo->butfunc= node_buts_group;
iconofs-= 18.0f;
glEnable(GL_BLEND);
@@ -2171,15 +2958,23 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
BIF_ThemeColor(TH_TEXT);
ui_rasterpos_safe(rct->xmin+19.0f, rct->ymax-NODE_DY+5.0f, snode->aspect);
- snode_drawstring(snode, node->name, (int)(iconofs - rct->xmin-18.0f));
-
+
+ if(node->flag & NODE_MUTED)
+ sprintf(showname, "[%s]", node->name);
+ else if(node->username[0])
+ sprintf(showname, "(%s) %s", node->username, node->name);
+ else
+ BLI_strncpy(showname, node->name, 128);
+
+ snode_drawstring(snode, showname, (int)(iconofs - rct->xmin-18.0f));
+
/* body */
BIF_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
uiSetRoundBox(8);
uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, BASIS_RAD);
glDisable(GL_BLEND);
-
+
/* scaling indicator */
node_scaling_widget(TH_NODE, snode->aspect, rct->xmax-BASIS_RAD*snode->aspect, rct->ymin, rct->xmax, rct->ymin+BASIS_RAD*snode->aspect);
@@ -2192,6 +2987,10 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
glDisable(GL_BLEND);
}
+ /* disable lines */
+ if(node->flag & NODE_MUTED)
+ node_draw_mute_line(snode, node);
+
/* we make buttons for input sockets, if... */
if(node->flag & NODE_OPTIONS) {
if(node->inputs.first || node->typeinfo->butfunc) {
@@ -2214,7 +3013,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
/* socket inputs, buttons */
for(sock= node->inputs.first; sock; sock= sock->next) {
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
+ socket_circle_draw(sock, NODE_SOCKSIZE);
if(block && sock->link==NULL) {
float *butpoin= sock->ns.vec;
@@ -2256,7 +3055,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
/* socket outputs */
for(sock= node->outputs.first; sock; sock= sock->next) {
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
+ socket_circle_draw(sock, NODE_SOCKSIZE);
BIF_ThemeColor(TH_TEXT);
ofs= 0;
@@ -2284,20 +3083,21 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
uiDrawBlock(block);
}
}
-
+
}
-void node_draw_hidden(SpaceNode *snode, bNode *node)
+static void node_draw_hidden(SpaceNode *snode, bNode *node)
{
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 showname[128]; /* 128 is used below */
/* shadow */
uiSetRoundBox(15);
- nodeshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT);
+ ui_dropshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT);
/* body */
BIF_ThemeColor(color_id);
@@ -2320,6 +3120,10 @@ void node_draw_hidden(SpaceNode *snode, bNode *node)
/* open entirely icon */
ui_draw_tria_icon(rct->xmin+9.0f, centy-6.0f, snode->aspect, 'h');
+ /* disable lines */
+ if(node->flag & NODE_MUTED)
+ node_draw_mute_line(snode, node);
+
if(node->flag & SELECT)
BIF_ThemeColor(TH_TEXT_HI);
else
@@ -2327,7 +3131,15 @@ void node_draw_hidden(SpaceNode *snode, bNode *node)
if(node->miniwidth>0.0f) {
ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect);
- snode_drawstring(snode, node->name, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
+
+ if(node->flag & NODE_MUTED)
+ sprintf(showname, "[%s]", node->name);
+ else if(node->username[0])
+ sprintf(showname, "(%s)%s", node->username, node->name);
+ else
+ BLI_strncpy(showname, node->name, 128);
+
+ snode_drawstring(snode, showname, (int)(rct->xmax - rct->xmin-18.0f -12.0f));
}
/* scale widget thing */
@@ -2344,107 +3156,12 @@ void node_draw_hidden(SpaceNode *snode, bNode *node)
/* sockets */
for(sock= node->inputs.first; sock; sock= sock->next) {
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
+ socket_circle_draw(sock, NODE_SOCKSIZE);
}
for(sock= node->outputs.first; sock; sock= sock->next) {
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
- }
-}
-
-/* note; this is used for fake links in groups too */
-void node_draw_link(SpaceNode *snode, bNodeLink *link)
-{
- float vec[4][3];
- float dist, spline_step, mx=0.0f, my=0.0f;
- int curve_res, do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE;
-
- if(link->fromnode==NULL && link->tonode==NULL)
- return;
-
- /* this is dragging link */
- if(link->fromnode==NULL || link->tonode==NULL) {
- short mval[2];
- getmouseco_areawin(mval);
- areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
- BIF_ThemeColor(TH_WIRE);
- do_shaded= 0;
- }
- else {
- /* going to give issues once... */
- if(link->tosock->flag & SOCK_UNAVAIL)
- return;
- if(link->fromsock->flag & SOCK_UNAVAIL)
- return;
-
- /* a bit ugly... but thats how we detect the internal group links */
- if(link->fromnode==link->tonode) {
- BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f);
- do_shaded= 0;
- }
- else {
- /* check cyclic */
- if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
- if(link->fromnode->flag & SELECT)
- th_col1= TH_EDGE_SELECT;
- if(link->tonode->flag & SELECT)
- th_col2= TH_EDGE_SELECT;
- }
- else {
- BIF_ThemeColor(TH_REDALERT);
- do_shaded= 0;
- }
- }
- }
-
- vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/
-
- /* in v0 and v3 we put begin/end points */
- if(link->fromnode) {
- vec[0][0]= link->fromsock->locx;
- vec[0][1]= link->fromsock->locy;
- }
- else {
- vec[0][0]= mx;
- vec[0][1]= my;
- }
- if(link->tonode) {
- vec[3][0]= link->tosock->locx;
- vec[3][1]= link->tosock->locy;
- }
- else {
- vec[3][0]= mx;
- vec[3][1]= my;
- }
-
- dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
-
- /* check direction later, for top sockets */
- vec[1][0]= vec[0][0]+dist;
- vec[1][1]= vec[0][1];
-
- vec[2][0]= vec[3][0]-dist;
- vec[2][1]= vec[3][1];
-
- if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > G.v2d->cur.xmax); /* clipped */
- else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */
- else {
- curve_res = 24;
-
- /* we can reuse the dist variable here to increment the GL curve eval amount*/
- dist = 1.0f/curve_res;
- spline_step = 0.0f;
-
- glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]);
- glBegin(GL_LINE_STRIP);
- while (spline_step < 1.000001f) {
- if(do_shaded)
- BIF_ThemeColorBlend(th_col1, th_col2, spline_step);
- glEvalCoord1f(spline_step);
- spline_step += dist;
- }
- glEnd();
+ socket_circle_draw(sock, NODE_SOCKSIZE);
}
}
@@ -2495,7 +3212,7 @@ static void node_draw_group_links(SpaceNode *snode, bNode *gnode)
bNodeSocket *sock;
glEnable(GL_BLEND);
- glEnable( GL_LINE_SMOOTH );
+ glEnable(GL_LINE_SMOOTH);
fakelink.tonode= fakelink.fromnode= gnode;
@@ -2520,7 +3237,7 @@ static void node_draw_group_links(SpaceNode *snode, bNode *gnode)
}
glDisable(GL_BLEND);
- glDisable( GL_LINE_SMOOTH );
+ glDisable(GL_LINE_SMOOTH);
}
/* groups are, on creation, centered around 0,0 */
@@ -2529,6 +3246,7 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
bNodeTree *ngroup= (bNodeTree *)gnode->id;
bNodeSocket *sock;
rctf rect= gnode->totr;
+ char showname[128];
/* backdrop header */
glEnable(GL_BLEND);
@@ -2552,7 +3270,17 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
/* backdrop title */
BIF_ThemeColor(TH_TEXT_HI);
ui_rasterpos_safe(rect.xmin+8.0f, rect.ymax+5.0f, snode->aspect);
- BIF_DrawString(snode->curfont, ngroup->id.name+2, 0);
+
+ if(gnode->username[0]) {
+ strcpy(showname,"(");
+ strcat(showname, gnode->username);
+ strcat(showname,") ");
+ strcat(showname, ngroup->id.name+2);
+ }
+ else
+ strcpy(showname, ngroup->id.name+2);
+
+ BIF_DrawString(snode->curfont, showname, 0);
/* links from groupsockets to the internal nodes */
node_draw_group_links(snode, gnode);
@@ -2560,10 +3288,10 @@ static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode)
/* group sockets */
for(sock= gnode->inputs.first; sock; sock= sock->next)
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
+ socket_circle_draw(sock, NODE_SOCKSIZE);
for(sock= gnode->outputs.first; sock; sock= sock->next)
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
- socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT);
+ socket_circle_draw(sock, NODE_SOCKSIZE);
/* and finally the whole tree */
node_draw_nodetree(sa, snode, ngroup);
@@ -2597,7 +3325,7 @@ void drawnodespace(ScrArea *sa, void *spacedata)
snode->curfont= uiSetCurFont_ext(snode->aspect);
/* backdrop */
- draw_nodespace_back(sa, snode);
+ draw_nodespace_back_pix(sa, snode);
/* nodes */
snode_set_context(snode);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index a39df5b7140..260b0ab6656 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -61,6 +61,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -74,6 +75,7 @@
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_edgehash.h"
+#include "BLI_rand.h"
#include "BKE_utildefines.h"
#include "BKE_curve.h"
@@ -93,6 +95,8 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_anim.h" //for the where_on_path function
+#include "BKE_particle.h"
+#include "BKE_utildefines.h"
#ifdef WITH_VERSE
#include "BKE_verse.h"
#endif
@@ -100,6 +104,7 @@
#include "BIF_editarmature.h"
#include "BIF_editdeform.h"
#include "BIF_editmesh.h"
+#include "BIF_editparticle.h"
#include "BIF_glutil.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -108,6 +113,7 @@
#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
+#include "BIF_toolbox.h"
#include "BDR_drawmesh.h"
#include "BDR_drawobject.h"
@@ -135,6 +141,11 @@ extern ListBase editelems;
static void draw_bounding_volume(Object *ob);
+static void drawcube_size(float size);
+static void drawcircle_size(float size);
+static void draw_empty_sphere(float size);
+static void draw_empty_cone(float size);
+
/* ************* Setting OpenGL Material ************ */
// Materials start counting at # one....
@@ -264,6 +275,79 @@ static float cube[8][3] = {
{ 1.0, 1.0, -1.0},
};
+/* ----------------- OpenGL Circle Drawing - Tables for Optimised Drawing Speed ------------------ */
+/* 32 values of sin function (still same result!) */
+static float sinval[32] = {
+ 0.00000000,
+ 0.20129852,
+ 0.39435585,
+ 0.57126821,
+ 0.72479278,
+ 0.84864425,
+ 0.93775213,
+ 0.98846832,
+ 0.99871650,
+ 0.96807711,
+ 0.89780453,
+ 0.79077573,
+ 0.65137248,
+ 0.48530196,
+ 0.29936312,
+ 0.10116832,
+ -0.10116832,
+ -0.29936312,
+ -0.48530196,
+ -0.65137248,
+ -0.79077573,
+ -0.89780453,
+ -0.96807711,
+ -0.99871650,
+ -0.98846832,
+ -0.93775213,
+ -0.84864425,
+ -0.72479278,
+ -0.57126821,
+ -0.39435585,
+ -0.20129852,
+ 0.00000000
+};
+
+/* 32 values of cos function (still same result!) */
+static float cosval[32] ={
+ 1.00000000,
+ 0.97952994,
+ 0.91895781,
+ 0.82076344,
+ 0.68896691,
+ 0.52896401,
+ 0.34730525,
+ 0.15142777,
+ -0.05064916,
+ -0.25065253,
+ -0.44039415,
+ -0.61210598,
+ -0.75875812,
+ -0.87434661,
+ -0.95413925,
+ -0.99486932,
+ -0.99486932,
+ -0.95413925,
+ -0.87434661,
+ -0.75875812,
+ -0.61210598,
+ -0.44039415,
+ -0.25065253,
+ -0.05064916,
+ 0.15142777,
+ 0.34730525,
+ 0.52896401,
+ 0.68896691,
+ 0.82076344,
+ 0.91895781,
+ 0.97952994,
+ 1.00000000
+};
+
/* flag is same as for draw_object */
void drawaxes(float size, int flag, char drawtype)
{
@@ -322,6 +406,22 @@ void drawaxes(float size, int flag, char drawtype)
glEnd();
break;
+ case OB_CUBE:
+ drawcube_size(size);
+ break;
+
+ case OB_CIRCLE:
+ drawcircle_size(size);
+ break;
+
+ case OB_EMPTY_SPHERE:
+ draw_empty_sphere(size);
+ break;
+
+ case OB_EMPTY_CONE:
+ draw_empty_cone(size);
+ break;
+
case OB_ARROWS:
default:
for (axis=0; axis<3; axis++) {
@@ -475,6 +575,31 @@ static void drawcube(void)
glEnd();
}
+/* draws a cube on given the scaling of the cube, assuming that
+ * all required matrices have been set (used for drawing empties)
+ */
+static void drawcube_size(float size)
+{
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(-size,-size,-size); glVertex3f(-size,-size,size);glVertex3f(-size,size,size); glVertex3f(-size,size,-size);
+ glVertex3f(-size,-size,-size); glVertex3f(size,-size,-size);glVertex3f(size,-size,size); glVertex3f(size,size,size);
+ glVertex3f(size,size,-size); glVertex3f(size,-size,-size);
+ glEnd();
+
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(-size,-size,size); glVertex3f(size,-size,size);
+ glEnd();
+
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(-size,size,size); glVertex3f(size,size,size);
+ glEnd();
+
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(-size,size,-size); glVertex3f(size,size,-size);
+ glEnd();
+}
+
+/* this is an unused (old) cube-drawing function based on a given size */
#if 0
static void drawcube_size(float *size)
{
@@ -987,7 +1112,7 @@ static void drawcamera(Object *ob, int flag)
if(cam->flag & CAM_SHOWLIMITS) {
draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
/* qdn: was yafray only, now also enabled for Blender to be used with defocus composit node */
- draw_focus_cross(cam->YF_dofdist, cam->drawsize);
+ draw_focus_cross(dof_camera(ob), cam->drawsize);
}
wrld= G.scene->world;
@@ -1017,7 +1142,7 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel)
int uxt = (u==0 || u==lt->pntsu-1);
if(!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
if(bp->hide==0) {
- if((bp->f1 & 1)==sel) {
+ if((bp->f1 & SELECT)==sel) {
bglVertex3fv(dl?co:bp->vec);
}
}
@@ -1248,12 +1373,21 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
BezTriple *bezt = &nu->bezt[i];
if(bezt->hide==0) {
- view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
- func(userData, nu, NULL, bezt, 0, s[0], s[1]);
- view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
- func(userData, nu, NULL, bezt, 1, s[0], s[1]);
- view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
- func(userData, nu, NULL, bezt, 2, s[0], s[1]);
+ if (G.f & G_HIDDENHANDLES) {
+ view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
+ if (s[0] != IS_CLIPPED)
+ func(userData, nu, NULL, bezt, 1, s[0], s[1]);
+ } else {
+ view3d_project_short_clip(curarea, bezt->vec[0], s, pmat, vmat);
+ if (s[0] != IS_CLIPPED)
+ func(userData, nu, NULL, bezt, 0, s[0], s[1]);
+ view3d_project_short_clip(curarea, bezt->vec[1], s, pmat, vmat);
+ if (s[0] != IS_CLIPPED)
+ func(userData, nu, NULL, bezt, 1, s[0], s[1]);
+ view3d_project_short_clip(curarea, bezt->vec[2], s, pmat, vmat);
+ if (s[0] != IS_CLIPPED)
+ func(userData, nu, NULL, bezt, 2, s[0], s[1]);
+ }
}
}
}
@@ -1341,17 +1475,38 @@ static void draw_dm_vert_normals(DerivedMesh *dm) {
/* Draw verts with color set based on selection */
static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
+ struct { int sel; EditVert *eve_act; } * data = userData;
EditVert *eve = EM_get_vert_for_index(index);
- int sel = *((int*) userData);
- if (eve->h==0 && (eve->f&SELECT)==sel) {
- bglVertex3fv(co);
+ if (eve->h==0 && (eve->f&SELECT)==data->sel) {
+ /* draw active larger - need to stop/start point drawing for this :/ */
+ if (eve==data->eve_act) {
+ float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
+ BIF_ThemeColor4(TH_EDITMESH_ACTIVE);
+
+ bglEnd();
+
+ glPointSize(size);
+ bglBegin(GL_POINTS);
+ bglVertex3fv(co);
+ bglEnd();
+
+ BIF_ThemeColor4(data->sel?TH_VERTEX_SELECT:TH_VERTEX);
+ glPointSize(size);
+ bglBegin(GL_POINTS);
+ } else {
+ bglVertex3fv(co);
+ }
}
}
-static void draw_dm_verts(DerivedMesh *dm, int sel)
+static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
{
+ struct { int sel; EditVert *eve_act; } data;
+ data.sel = sel;
+ data.eve_act = eve_act;
+
bglBegin(GL_POINTS);
- dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &sel);
+ dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
bglEnd();
}
@@ -1359,21 +1514,38 @@ static void draw_dm_verts(DerivedMesh *dm, int sel)
static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
{
EditEdge *eed = EM_get_edge_for_index(index);
- unsigned char **cols = userData;
+ //unsigned char **cols = userData, *col;
+ struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
+ unsigned char *col;
if (eed->h==0) {
- glColor4ubv(cols[(eed->f&SELECT)?1:0]);
+ if (eed==data->eed_act) {
+ glColor4ubv(data->actCol);
+ } else {
+ if (eed->f&SELECT) {
+ col = data->selCol;
+ } else {
+ col = data->baseCol;
+ }
+ /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */
+ if (col[3]==0) return 0;
+
+ glColor4ubv(col);
+ }
return 1;
} else {
return 0;
}
}
-static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
+static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act)
{
- unsigned char *cols[2];
- cols[0] = baseCol;
- cols[1] = selCol;
- dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, cols);
+ struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
+
+ data.baseCol = baseCol;
+ data.selCol = selCol;
+ data.actCol = actCol;
+ data.eed_act = eed_act;
+ dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data);
}
/* Draw edges */
@@ -1436,25 +1608,38 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
}
- /* Draw faces with color set based on selection */
+ /* Draw faces with color set based on selection
+ * return 2 for the active face so it renders with stipple enabled */
static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r)
{
+ struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
EditFace *efa = EM_get_face_for_index(index);
- unsigned char **cols = userData;
-
+ unsigned char *col;
+
if (efa->h==0) {
- glColor4ubv(cols[(efa->f&SELECT)?1:0]);
- return 1;
- } else {
- return 0;
+ if (efa == data->efa_act) {
+ glColor4ubv(data->cols[2]);
+ return 2; /* stipple */
+ } else {
+ col = data->cols[(efa->f&SELECT)?1:0];
+ if (col[3]==0) return 0;
+ glColor4ubv(col);
+ return 1;
+ }
}
+ return 0;
}
-static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
+
+/* also draws the active face */
+static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act)
{
- unsigned char *cols[2];
- cols[0] = baseCol;
- cols[1] = selCol;
- dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, cols, 0);
+ struct { unsigned char *cols[3]; EditFace *efa_act; } data;
+ data.cols[0] = baseCol;
+ data.cols[1] = selCol;
+ data.cols[2] = actCol;
+ data.efa_act = efa_act;
+
+ dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
}
static int draw_dm_creases__setDrawOptions(void *userData, int index)
@@ -1475,6 +1660,41 @@ static void draw_dm_creases(DerivedMesh *dm)
glLineWidth(1.0);
}
+static int draw_dm_bweights__setDrawOptions(void *userData, int index)
+{
+ EditEdge *eed = EM_get_edge_for_index(index);
+
+ if (eed->h==0 && eed->bweight!=0.0) {
+ BIF_ThemeColorBlend(TH_WIRE, TH_EDGE_SELECT, eed->bweight);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+static void draw_dm_bweights__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
+{
+ EditVert *eve = EM_get_vert_for_index(index);
+
+ if (eve->h==0 && eve->bweight!=0.0) {
+ BIF_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, eve->bweight);
+ bglVertex3fv(co);
+ }
+}
+static void draw_dm_bweights(DerivedMesh *dm)
+{
+ if (G.scene->selectmode & SCE_SELECT_VERTEX) {
+ glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE) + 2);
+ bglBegin(GL_POINTS);
+ dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, NULL);
+ bglEnd();
+ }
+ else {
+ glLineWidth(3.0);
+ dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, NULL);
+ glLineWidth(1.0);
+ }
+}
+
/* Second section of routines: Combine first sets to form fancy
* drawing routines (for example rendering twice to get overlays).
*
@@ -1484,7 +1704,7 @@ static void draw_dm_creases(DerivedMesh *dm)
/* EditMesh drawing routines*/
-static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM)
+static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM, EditVert *eve_act)
{
int sel;
@@ -1520,10 +1740,10 @@ static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM)
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
glPointSize(size);
glColor4ubv((GLubyte *)col);
- draw_dm_verts(cageDM, sel);
+ draw_dm_verts(cageDM, sel, eve_act);
}
- if(G.scene->selectmode & SCE_SELECT_FACE) {
+ if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
glPointSize(fsize);
glColor4ubv((GLubyte *)fcol);
draw_dm_face_centers(cageDM, sel);
@@ -1540,14 +1760,20 @@ static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM)
glPointSize(1.0);
}
-static void draw_em_fancy_edges(DerivedMesh *cageDM)
+static void draw_em_fancy_edges(DerivedMesh *cageDM, short sel_only, EditEdge *eed_act)
{
int pass;
- unsigned char wire[4], sel[4];
+ unsigned char wireCol[4], selCol[4], actCol[4];
/* since this function does transparant... */
- BIF_GetThemeColor3ubv(TH_EDGE_SELECT, (char *)sel);
- BIF_GetThemeColor3ubv(TH_WIRE, (char *)wire);
+ BIF_GetThemeColor4ubv(TH_EDGE_SELECT, (char *)selCol);
+ BIF_GetThemeColor4ubv(TH_WIRE, (char *)wireCol);
+ BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)actCol);
+
+ /* when sel only is used, dont render wire, only selected, this is used for
+ * textured draw mode when the 'edges' option is disabled */
+ if (sel_only)
+ wireCol[3] = 0;
for (pass=0; pass<2; pass++) {
/* show wires in transparant when no zbuf clipping for select */
@@ -1555,30 +1781,33 @@ static void draw_em_fancy_edges(DerivedMesh *cageDM)
if (G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0) {
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
-
- wire[3] = sel[3] = 85;
+ selCol[3] = 85;
+ if (!sel_only) wireCol[3] = 85;
} else {
continue;
}
} else {
- wire[3] = sel[3] = 255;
+ selCol[3] = 255;
+ if (!sel_only) wireCol[3] = 255;
}
if(G.scene->selectmode == SCE_SELECT_FACE) {
- draw_dm_edges_sel(cageDM, wire, sel);
+ draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
}
else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) {
if(cageDM->drawMappedEdgesInterp && (G.scene->selectmode & SCE_SELECT_VERTEX)) {
glShadeModel(GL_SMOOTH);
- draw_dm_edges_sel_interp(cageDM, wire, sel);
+ draw_dm_edges_sel_interp(cageDM, wireCol, selCol);
glShadeModel(GL_FLAT);
} else {
- draw_dm_edges_sel(cageDM, wire, sel);
+ draw_dm_edges_sel(cageDM, wireCol, selCol, actCol, eed_act);
}
}
else {
- glColor4ubv(wire);
- draw_dm_edges(cageDM);
+ if (!sel_only) {
+ glColor4ubv(wireCol);
+ draw_dm_edges(cageDM);
+ }
}
if (pass==0) {
@@ -1832,20 +2061,38 @@ static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth
static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
{
Mesh *me = ob->data;
-
+ EditFace *efa_act = NULL;
+ EditEdge *eed_act = NULL;
+ EditVert *eve_act = NULL;
+
+ if (G.editMesh->selected.last) {
+ EditSelection *ese = G.editMesh->selected.last;
+ if ( ese->type == EDITFACE ) {
+ efa_act = (EditFace *)ese->data;
+ } else if ( ese->type == EDITEDGE ) {
+ eed_act = (EditEdge *)ese->data;
+ } else if ( ese->type == EDITVERT ) {
+ eve_act = (EditVert *)ese->data;
+ }
+ }
+
EM_init_index_arrays(1, 1, 1);
if(dt>OB_WIRE) {
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
+ if( CHECK_OB_DRAWTEXTURE(G.vd, dt) ) {
+ draw_mesh_textured(ob, finalDM, 0);
+ } else {
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
- glEnable(GL_LIGHTING);
- glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
+ glEnable(GL_LIGHTING);
+ glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0);
+ finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
- glFrontFace(GL_CCW);
- glDisable(GL_LIGHTING);
-
+ glFrontFace(GL_CCW);
+ glDisable(GL_LIGHTING);
+ }
+
// Setup for drawing wire over, disable zbuffer
// write to show selected edge wires better
BIF_ThemeColor(TH_WIRE);
@@ -1860,53 +2107,83 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
}
}
- if((G.f & (G_FACESELECT+G_DRAWFACES))) { /* transp faces */
- unsigned char col1[4], col2[4];
+ if((G.f & (G_DRAWFACES)) || FACESEL_PAINT_TEST) { /* transp faces */
+ unsigned char col1[4], col2[4], col3[4];
BIF_GetThemeColor4ubv(TH_FACE, (char *)col1);
BIF_GetThemeColor4ubv(TH_FACE_SELECT, (char *)col2);
+ BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3);
+
+ glEnable(GL_BLEND);
+ glDepthMask(0); // disable write in zbuffer, needed for nice transp
+
+ /* dont draw unselected faces, only selected, this is MUCH nicer when texturing */
+ if CHECK_OB_DRAWTEXTURE(G.vd, dt)
+ col1[3] = 0;
+
+ draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
+
+ glDisable(GL_BLEND);
+ glDepthMask(1); // restore write in zbuffer
+ } else if (efa_act) {
+ /* even if draw faces is off it would be nice to draw the stipple face
+ * Make all other faces zero alpha except for the active
+ * */
+ unsigned char col1[4], col2[4], col3[4];
+ col1[3] = col2[3] = 0; /* dont draw */
+ BIF_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, (char *)col3);
glEnable(GL_BLEND);
glDepthMask(0); // disable write in zbuffer, needed for nice transp
- draw_dm_faces_sel(cageDM, col1, col2);
+ draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
glDisable(GL_BLEND);
glDepthMask(1); // restore write in zbuffer
+
}
/* here starts all fancy draw-extra over */
-
- if(G.f & G_DRAWSEAMS) {
- BIF_ThemeColor(TH_EDGE_SEAM);
- glLineWidth(2);
-
- draw_dm_edges_seams(cageDM);
-
- glColor3ub(0,0,0);
- glLineWidth(1);
- }
+ if((G.f & G_DRAWEDGES)==0 && CHECK_OB_DRAWTEXTURE(G.vd, dt)) {
+ /* we are drawing textures and 'G_DRAWEDGES' is disabled, dont draw any edges */
+
+ /* only draw selected edges otherwise there is no way of telling if a face is selected */
+ draw_em_fancy_edges(cageDM, 1, eed_act);
+
+ } else {
+ if(G.f & G_DRAWSEAMS) {
+ BIF_ThemeColor(TH_EDGE_SEAM);
+ glLineWidth(2);
- if(G.f & G_DRAWSHARP) {
- BIF_ThemeColor(TH_EDGE_SHARP);
- glLineWidth(2);
-
- draw_dm_edges_sharp(cageDM);
-
- glColor3ub(0,0,0);
- glLineWidth(1);
- }
-
- if(G.f & G_DRAWCREASES) {
- draw_dm_creases(cageDM);
+ draw_dm_edges_seams(cageDM);
+
+ glColor3ub(0,0,0);
+ glLineWidth(1);
+ }
+
+ if(G.f & G_DRAWSHARP) {
+ BIF_ThemeColor(TH_EDGE_SHARP);
+ glLineWidth(2);
+
+ draw_dm_edges_sharp(cageDM);
+
+ glColor3ub(0,0,0);
+ glLineWidth(1);
+ }
+
+ if(G.f & G_DRAWCREASES) {
+ draw_dm_creases(cageDM);
+ }
+ if(G.f & G_DRAWBWEIGHTS) {
+ draw_dm_bweights(cageDM);
+ }
+
+ draw_em_fancy_edges(cageDM, 0, eed_act);
}
-
- draw_em_fancy_edges(cageDM);
-
if(ob==G.obedit) {
retopo_matrix_update(G.vd);
- draw_em_fancy_verts(em, cageDM);
+ draw_em_fancy_verts(em, cageDM, eve_act);
if(G.f & G_DRAWNORMALS) {
BIF_ThemeColor(TH_NORMAL);
@@ -1991,14 +2268,14 @@ static void draw_mesh_fancy(Base *base, int dt, int flag)
else totface = 0;
}
else {
- totvert = me->totvert;
- totedge = me->totedge;
- totface = me->totface;
+ totvert = dm->getNumVerts(dm);
+ totedge = dm->getNumEdges(dm);
+ totface = dm->getNumFaces(dm);
}
#else
- totvert = me->totvert;
- totedge = me->totedge;
- totface = me->totface;
+ totvert = dm->getNumVerts(dm);
+ totedge = dm->getNumEdges(dm);
+ totface = dm->getNumFaces(dm);
#endif
/* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
@@ -2006,7 +2283,7 @@ static void draw_mesh_fancy(Base *base, int dt, int flag)
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
// Unwanted combination.
- if (ob==OBACT && (G.f&G_FACESELECT)) draw_wire = 0;
+ if (ob==OBACT && FACESEL_PAINT_TEST) draw_wire = 0;
if(dt==OB_BOUNDBOX) {
draw_bounding_volume(ob);
@@ -2019,13 +2296,25 @@ static void draw_mesh_fancy(Base *base, int dt, int flag)
else if(dt==OB_WIRE || totface==0) {
draw_wire = 1;
}
- else if( (ob==OBACT && (G.f & (G_FACESELECT|G_TEXTUREPAINT))) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) {
-
- if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) {
+ else if( (ob==OBACT && (G.f & G_TEXTUREPAINT || FACESEL_PAINT_TEST)) ||
+ CHECK_OB_DRAWTEXTURE(G.vd, dt))
+ {
+ int faceselect= (ob==OBACT && FACESEL_PAINT_TEST);
+
+ if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&G_PICKSEL || FACESEL_PAINT_TEST) && !draw_wire) {
draw_mesh_object_outline(ob, dm);
}
- draw_tface_mesh(ob, ob->data, dt);
+ draw_mesh_textured(ob, dm, faceselect);
+
+ if(!faceselect) {
+ if(base->flag & SELECT)
+ BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
+ else
+ BIF_ThemeColor(TH_WIRE);
+
+ dm->drawLooseEdges(dm);
+ }
}
else if(dt==OB_SOLID ) {
@@ -2075,7 +2364,7 @@ static void draw_mesh_fancy(Base *base, int dt, int flag)
else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mcol) {
dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 1);
}
- else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mtface) {
+ else if(G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
glColor3f(1.0f, 1.0f, 1.0f);
dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, NULL, 0);
}
@@ -2180,18 +2469,16 @@ static int draw_mesh_object(Base *base, int dt, int flag)
if(dt>OB_WIRE) init_gl_materials(ob, 0); // no transp in editmode, the fancy draw over goes bad then
draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
- if (cageDM != finalDM)
- cageDM->release(cageDM);
- finalDM->release(finalDM);
+ if (G.obedit!=ob && finalDM)
+ finalDM->release(finalDM);
}
- else if(!G.obedit && (G.f & G_SCULPTMODE) &&(G.scene->sculptdata.draw_flag & SCULPTDRAW_FAST) &&
+ else if(!G.obedit && (G.f & G_SCULPTMODE) &&(G.scene->sculptdata.flags & SCULPT_DRAW_FAST) &&
OBACT==ob && !sculpt_modifiers_active(ob)) {
sculptmode_draw_mesh(0);
}
else {
/* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */
-
- if(me->totface<=4 || boundbox_clip(ob->obmat, me->bb)) {
+ if(me->totface<=4 || boundbox_clip(ob->obmat, (ob->bb)? ob->bb: me->bb)) {
if(dt==OB_SOLID) has_alpha= init_gl_materials(ob, (base->flag & OB_FROMDUPLI)==0);
draw_mesh_fancy(base, dt, flag);
@@ -2608,9 +2895,9 @@ static void draw_particle_system(Base *base, PartEff *paf)
mymultmatrix(mat);
}
- if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
+ if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= give_timeoffset(ob);
else ptime= 0.0;
- ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime);
+ ctime= bsystem_time(ob, (float)(G.scene->r.cfra), ptime);
glPointSize(1.0);
@@ -2718,6 +3005,757 @@ static void draw_static_particle_system(Object *ob, PartEff *paf, int dt)
}
+/* unified drawing of all new particle systems draw types except dupli ob & group */
+/* mostly tries to use vertex arrays for speed */
+
+/* 1. check that everything is ok & updated */
+/* 2. start initialising things */
+/* 3. initialize according to draw type */
+/* 4. allocate drawing data arrays */
+/* 5. start filling the arrays */
+/* 6. draw the arrays */
+/* 7. clean up */
+static void draw_new_particle_system(Base *base, ParticleSystem *psys)
+{
+ View3D *v3d= G.vd;
+ Object *ob=base->object;
+ ParticleSystemModifierData *psmd;
+ ParticleSettings *part;
+ ParticleData *pars, *pa;
+ ParticleKey state, *states=0;
+ ParticleCacheKey *cache=0;
+ Material *ma;
+ Object *bb_ob=0;
+ float vel[3], vec[3], vec2[3], imat[4][4], onevec[3]={0.0f,0.0f,0.0f}, bb_center[3];
+ float timestep, pixsize=1.0, pa_size, pa_time, r_tilt;
+ float cfra=bsystem_time(ob,(float)CFRA,0.0);
+ float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3];
+ int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0;
+ int path_possible=0, keys_possible=0, draw_keys=0, totchild=0;
+ int select=ob->flag&SELECT;
+ GLint polygonmode[2];
+ char val[32];
+
+/* 1. */
+ if(psys==0)
+ return;
+
+ part=psys->part;
+ pars=psys->particles;
+
+ if(part==0 || !psys_check_enabled(ob, psys))
+ return;
+
+ if(pars==0) return;
+
+ if(!G.obedit && psys_in_edit_mode(psys)
+ && psys->flag & PSYS_HAIR_DONE && part->draw_as==PART_DRAW_PATH)
+ return;
+
+ if(part->draw_as==PART_DRAW_NOT) return;
+
+/* 2. */
+ if(part->phystype==PART_PHYS_KEYED){
+ if(psys->flag & PSYS_FIRST_KEYED){
+ if(psys->flag&PSYS_KEYED){
+ select=psys_count_keyed_targets(ob,psys);
+ if(psys->totkeyed==0)
+ return;
+ }
+ }
+ else
+ return;
+ }
+
+ if(select){
+ select=0;
+ if(psys_get_current(ob)==psys)
+ select=1;
+ }
+
+ psys->flag|=PSYS_DRAWING;
+
+ if(part->type==PART_HAIR && !psys->childcache)
+ totchild=0;
+ else
+ totchild=psys->totchild*part->disp/100;
+
+ ma= give_current_material(ob,part->omat);
+
+ if(select)
+ cpack(0xFFFFFF);
+ else if((ma) && (part->draw&PART_DRAW_MAT_COL))
+ glColor3f(ma->r,ma->g,ma->b);
+ else
+ cpack(0);
+
+ psmd= psys_get_modifier(ob,psys);
+
+ timestep= psys_get_timestep(part);
+
+ myloadmatrix(G.vd->viewmat);
+
+ if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
+ float mat[4][4];
+ Mat4MulMat4(mat, psys->imat, ob->obmat);
+ mymultmatrix(mat);
+ }
+
+ totpart=psys->totpart;
+ draw_as=part->draw_as;
+
+ if(part->flag&PART_ABS_TIME && part->ipo){
+ calc_ipo(part->ipo, cfra);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ if(part->flag&PART_GLOB_TIME)
+ cfra=bsystem_time(0,(float)CFRA,0.0);
+
+ if(psys->pathcache){
+ path_possible=1;
+ keys_possible=1;
+ }
+ if(draw_as==PART_DRAW_PATH && path_possible==0)
+ draw_as=PART_DRAW_DOT;
+
+ if(draw_as!=PART_DRAW_PATH && keys_possible && part->draw&PART_DRAW_KEYS){
+ path_nbr=part->keys_step;
+ draw_keys=1;
+ }
+
+/* 3. */
+ switch(draw_as){
+ case PART_DRAW_DOT:
+ if(part->draw_size)
+ glPointSize(part->draw_size);
+ else
+ glPointSize(2.0); /* default dot size */
+ break;
+ case PART_DRAW_CIRC:
+ /* calculate view aligned matrix: */
+ Mat4CpyMat4(imat, G.vd->viewinv);
+ Normalize(imat[0]);
+ Normalize(imat[1]);
+ /* no break! */
+ case PART_DRAW_CROSS:
+ case PART_DRAW_AXIS:
+ /* lets calculate the scale: */
+ pixsize= v3d->persmat[0][3]*ob->obmat[3][0]+ v3d->persmat[1][3]*ob->obmat[3][1]+ v3d->persmat[2][3]*ob->obmat[3][2]+ v3d->persmat[3][3];
+ pixsize*= v3d->pixsize;
+ if(part->draw_size==0.0)
+ pixsize*=2.0;
+ else
+ pixsize*=part->draw_size;
+ break;
+ case PART_DRAW_OB:
+ if(part->dup_ob==0)
+ draw_as=PART_DRAW_DOT;
+ else
+ draw_as=0;
+ break;
+ case PART_DRAW_GR:
+ if(part->dup_group==0)
+ draw_as=PART_DRAW_DOT;
+ else
+ draw_as=0;
+ break;
+ case PART_DRAW_BB:
+ if(G.vd->camera==0 && part->bb_ob==0){
+ error("Billboards need an active camera or a target object!");
+
+ draw_as=part->draw_as=PART_DRAW_DOT;
+
+ if(part->draw_size)
+ glPointSize(part->draw_size);
+ else
+ glPointSize(2.0); /* default dot size */
+ }
+ else if(part->bb_ob)
+ bb_ob=part->bb_ob;
+ else
+ bb_ob=G.vd->camera;
+
+ if(part->bb_align<PART_BB_VIEW)
+ onevec[part->bb_align]=1.0f;
+ break;
+ case PART_DRAW_PATH:
+ break;
+ }
+ if(part->draw & PART_DRAW_SIZE && part->draw_as!=PART_DRAW_CIRC){
+ Mat4CpyMat4(imat, G.vd->viewinv);
+ Normalize(imat[0]);
+ Normalize(imat[1]);
+ }
+
+/* 4. */
+ if(draw_as && draw_as!=PART_DRAW_PATH){
+ if(draw_as!=PART_DRAW_CIRC){
+ switch(draw_as){
+ case PART_DRAW_AXIS:
+ cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata");
+ /* no break! */
+ case PART_DRAW_CROSS:
+ vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata");
+ break;
+ case PART_DRAW_LINE:
+ vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata");
+ break;
+ case PART_DRAW_BB:
+ vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
+ ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata");
+ break;
+ default:
+ vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata");
+ }
+ }
+
+ if(part->draw&PART_DRAW_VEL && draw_as!=PART_DRAW_LINE)
+ vedata=MEM_callocN((totpart+totchild)*2*3*(path_nbr+1)*sizeof(float), "particle_vedata");
+
+ vd=vdata;
+ ved=vedata;
+ cd=cdata;
+ nd=ndata;
+
+ psys->lattice=psys_get_lattice(ob,psys);
+ }
+
+ if(draw_as){
+/* 5. */
+ for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
+ if(a<totpart){
+ if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
+ if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
+
+ pa_time=(cfra-pa->time)/pa->lifetime;
+
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ calc_ipo(part->ipo, 100*pa_time);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ pa_size=pa->size;
+
+ r_tilt=1.0f+pa->r_ave[0];
+
+ if(path_nbr){
+ cache=psys->pathcache[a];
+ k_max=(int)(cache->steps);
+ }
+ }
+ else{
+ ChildParticle *cpa= &psys->child[a-totpart];
+
+ pa_time=psys_get_child_time(psys,cpa,cfra);
+
+ if((part->flag&PART_ABS_TIME)==0 && part->ipo){
+ calc_ipo(part->ipo, 100*pa_time);
+ execute_ipo((ID *)part, part->ipo);
+ }
+
+ pa_size=psys_get_child_size(psys,cpa,cfra,0);
+
+ r_tilt=2.0f*cpa->rand[2];
+ if(path_nbr){
+ cache=psys->childcache[a-totpart];
+ k_max=(int)(cache->steps);
+ }
+ }
+
+ if(draw_as!=PART_DRAW_PATH){
+ int next_pa=0;
+ for(k=0; k<=path_nbr; k++){
+ if(draw_keys){
+ state.time=(float)k/(float)path_nbr;
+ psys_get_particle_on_path(ob,psys,a,&state,1);
+ }
+ else if(path_nbr){
+ if(k<=k_max){
+ VECCOPY(state.co,(cache+k)->co);
+ VECCOPY(state.vel,(cache+k)->vel);
+ QUATCOPY(state.rot,(cache+k)->rot);
+ }
+ else
+ continue;
+ }
+ else{
+ state.time=cfra;
+ if(psys_get_particle_state(ob,psys,a,&state,0)==0){
+ next_pa=1;
+ break;
+ }
+ }
+
+ switch(draw_as){
+ case PART_DRAW_DOT:
+ if(vd){
+ VECCOPY(vd,state.co) vd+=3;
+ }
+ break;
+ case PART_DRAW_CROSS:
+ case PART_DRAW_AXIS:
+ vec[0]=2.0f*pixsize;
+ vec[1]=vec[2]=0.0;
+ QuatMulVecf(state.rot,vec);
+ if(draw_as==PART_DRAW_AXIS){
+ cd[1]=cd[2]=cd[4]=cd[5]=0.0;
+ cd[0]=cd[3]=1.0;
+ cd[6]=cd[8]=cd[9]=cd[11]=0.0;
+ cd[7]=cd[10]=1.0;
+ cd[13]=cd[12]=cd[15]=cd[16]=0.0;
+ cd[14]=cd[17]=1.0;
+ cd+=18;
+
+ VECCOPY(vec2,state.co);
+ }
+ else VECSUB(vec2,state.co,vec);
+
+ VECADD(vec,state.co,vec);
+ VECCOPY(vd,vec); vd+=3;
+ VECCOPY(vd,vec2); vd+=3;
+
+ vec[1]=2.0f*pixsize;
+ vec[0]=vec[2]=0.0;
+ QuatMulVecf(state.rot,vec);
+ if(draw_as==PART_DRAW_AXIS){
+ VECCOPY(vec2,state.co);
+ }
+ else VECSUB(vec2,state.co,vec);
+
+ VECADD(vec,state.co,vec);
+ VECCOPY(vd,vec); vd+=3;
+ VECCOPY(vd,vec2); vd+=3;
+
+ vec[2]=2.0f*pixsize;
+ vec[0]=vec[1]=0.0;
+ QuatMulVecf(state.rot,vec);
+ if(draw_as==PART_DRAW_AXIS){
+ VECCOPY(vec2,state.co);
+ }
+ else VECSUB(vec2,state.co,vec);
+
+ VECADD(vec,state.co,vec);
+
+ VECCOPY(vd,vec); vd+=3;
+ VECCOPY(vd,vec2); vd+=3;
+ break;
+ case PART_DRAW_LINE:
+ VECCOPY(vec,state.vel);
+ Normalize(vec);
+ if(part->draw & PART_DRAW_VEL_LENGTH)
+ VecMulf(vec,VecLength(state.vel));
+ VECADDFAC(vd,state.co,vec,-part->draw_line[0]); vd+=3;
+ VECADDFAC(vd,state.co,vec,part->draw_line[1]); vd+=3;
+ break;
+ case PART_DRAW_CIRC:
+ drawcircball(GL_LINE_LOOP, state.co, pixsize, imat);
+ break;
+ case PART_DRAW_BB:
+ if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){
+ VECCOPY(xvec,bb_ob->obmat[0]);
+ Normalize(xvec);
+ VECCOPY(yvec,bb_ob->obmat[1]);
+ Normalize(yvec);
+ VECCOPY(zvec,bb_ob->obmat[2]);
+ Normalize(zvec);
+ }
+ else if(part->bb_align==PART_BB_VEL){
+ float temp[3];
+ VECCOPY(temp,state.vel);
+ Normalize(temp);
+ VECSUB(zvec,bb_ob->obmat[3],state.co);
+ if(part->draw&PART_DRAW_BB_LOCK){
+ float fac=-Inpf(zvec,temp);
+ VECADDFAC(zvec,zvec,temp,fac);
+ }
+ Normalize(zvec);
+ Crossf(xvec,temp,zvec);
+ Normalize(xvec);
+ Crossf(yvec,zvec,xvec);
+ }
+ else{
+ VECSUB(zvec,bb_ob->obmat[3],state.co);
+ if(part->draw&PART_DRAW_BB_LOCK)
+ zvec[part->bb_align]=0.0f;
+ Normalize(zvec);
+
+ if(part->bb_align<PART_BB_VIEW)
+ Crossf(xvec,onevec,zvec);
+ else
+ Crossf(xvec,bb_ob->obmat[1],zvec);
+ Normalize(xvec);
+ Crossf(yvec,zvec,xvec);
+ }
+
+ VECCOPY(vec,xvec);
+ VECCOPY(vec2,yvec);
+
+ VecMulf(xvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
+ VecMulf(vec2,sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
+ VECADD(xvec,xvec,vec2);
+
+ VecMulf(yvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
+ VecMulf(vec,-sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI));
+ VECADD(yvec,yvec,vec);
+
+ VecMulf(xvec,pa_size);
+ VecMulf(yvec,pa_size);
+
+ VECADDFAC(bb_center,state.co,xvec,part->bb_offset[0]);
+ VECADDFAC(bb_center,bb_center,yvec,part->bb_offset[1]);
+
+ VECADD(vd,bb_center,xvec);
+ VECADD(vd,vd,yvec); vd+=3;
+
+ VECSUB(vd,bb_center,xvec);
+ VECADD(vd,vd,yvec); vd+=3;
+
+ VECSUB(vd,bb_center,xvec);
+ VECSUB(vd,vd,yvec); vd+=3;
+
+ VECADD(vd,bb_center,xvec);
+ VECSUB(vd,vd,yvec); vd+=3;
+
+ VECCOPY(nd, zvec); nd+=3;
+ VECCOPY(nd, zvec); nd+=3;
+ VECCOPY(nd, zvec); nd+=3;
+ VECCOPY(nd, zvec); nd+=3;
+ break;
+ }
+
+ if(vedata){
+ VECCOPY(ved,state.co);
+ ved+=3;
+ VECCOPY(vel,state.vel);
+ VecMulf(vel,timestep);
+ VECADD(ved,state.co,vel);
+ ved+=3;
+ }
+
+ if(part->draw & PART_DRAW_SIZE){
+ setlinestyle(3);
+ drawcircball(GL_LINE_LOOP, state.co, pa_size, imat);
+ setlinestyle(0);
+ }
+
+ totpoint++;
+ }
+ if(next_pa)
+ continue;
+ if(part->draw&PART_DRAW_NUM){
+ /* in path drawing state.co is the end point */
+ glRasterPos3f(state.co[0], state.co[1], state.co[2]);
+ sprintf(val," %i",a);
+ BMF_DrawString(G.font, val);
+ }
+ }
+ }
+/* 6. */
+
+ glGetIntegerv(GL_POLYGON_MODE, polygonmode);
+ glDisableClientState(GL_NORMAL_ARRAY);
+
+ if(draw_as != PART_DRAW_CIRC){
+ if(draw_as==PART_DRAW_PATH){
+ ParticleCacheKey **cache, *path;
+ float *cd2=0,*cdata2=0;
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnable(GL_LIGHTING);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+
+ if(part->draw&PART_DRAW_MAT_COL)
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ if(totchild && (part->draw&PART_DRAW_PARENT)==0)
+ totpart=0;
+
+ cache=psys->pathcache;
+ for(a=0, pa=psys->particles; a<totpart; a++, pa++){
+ path=cache[a];
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
+ if(part->draw&PART_DRAW_MAT_COL)
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+ glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ }
+
+ cache=psys->childcache;
+ for(a=0; a<totchild; a++){
+ path=cache[a];
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
+ if(part->draw&PART_DRAW_MAT_COL)
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
+ glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ }
+
+ if(part->draw&PART_DRAW_MAT_COL)
+ glDisable(GL_COLOR_ARRAY);
+ glDisable(GL_COLOR_MATERIAL);
+
+ if(cdata2)
+ MEM_freeN(cdata2);
+ cd2=cdata2=0;
+
+ glLineWidth(1.0f);
+
+ /* draw particle edit mode key points*/
+ }
+
+ if(draw_as!=PART_DRAW_PATH){
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ if(vdata){
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vdata);
+ }
+ else
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ if(ndata && MIN2(G.vd->drawtype, ob->dt)>OB_WIRE){
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(GL_FLOAT, 0, ndata);
+ glEnable(GL_LIGHTING);
+ }
+ else{
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisable(GL_LIGHTING);
+ }
+
+ switch(draw_as){
+ case PART_DRAW_AXIS:
+ case PART_DRAW_CROSS:
+ if(cdata){
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(3, GL_FLOAT, 0, cdata);
+ }
+ glDrawArrays(GL_LINES, 0, 6*totpoint);
+ break;
+ case PART_DRAW_LINE:
+ glDrawArrays(GL_LINES, 0, 2*totpoint);
+ break;
+ case PART_DRAW_BB:
+ if(MIN2(G.vd->drawtype, ob->dt)<=OB_WIRE)
+ glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
+
+ glDrawArrays(GL_QUADS, 0, 4*totpoint);
+ break;
+ default:
+ glDrawArrays(GL_POINTS, 0, totpoint);
+ break;
+ }
+ }
+
+ }
+ if(vedata){
+ glDisableClientState(GL_COLOR_ARRAY);
+ cpack(0xC0C0C0);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vedata);
+
+ glDrawArrays(GL_LINES, 0, 2*totpoint);
+ }
+
+ glPolygonMode(GL_FRONT, polygonmode[0]);
+ glPolygonMode(GL_BACK, polygonmode[1]);
+ }
+
+/* 7. */
+
+ glDisable(GL_LIGHTING);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+#if 0 /* If this is needed, it cant be enabled in wire mode, since it messes up the view - Campbell */
+ glEnable(GL_DEPTH_TEST);
+#endif
+
+ if(states)
+ MEM_freeN(states);
+ if(vdata)
+ MEM_freeN(vdata);
+ if(vedata)
+ MEM_freeN(vedata);
+ if(cdata)
+ MEM_freeN(cdata);
+ if(ndata)
+ MEM_freeN(ndata);
+
+ psys->flag &= ~PSYS_DRAWING;
+
+ if(psys->lattice){
+ end_latt_deform();
+ psys->lattice=0;
+ }
+
+ myloadmatrix(G.vd->viewmat);
+ mymultmatrix(ob->obmat); // bring back local matrix for dtx
+}
+
+static void draw_particle_edit(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit = psys->edit;
+ ParticleData *pa;
+ ParticleCacheKey **path;
+ ParticleEditKey *key;
+ ParticleEditSettings *pset = PE_settings();
+ int i, k, totpart = psys->totpart, totchild=0, timed = pset->draw_timed;
+ char nosel[4], sel[4];
+ float sel_col[3];
+ float nosel_col[3];
+ char val[32];
+
+ if(psys->pathcache==0){
+ PE_hide_keys_time(psys,CFRA);
+ psys_cache_paths(ob,psys,CFRA,0);
+ }
+
+ if(pset->flag & PE_SHOW_CHILD && psys->part->draw_as == PART_DRAW_PATH) {
+ if(psys->childcache==0)
+ psys_cache_child_paths(ob, psys, CFRA, 0);
+ }
+ else if(!(pset->flag & PE_SHOW_CHILD) && psys->childcache)
+ free_child_path_cache(psys);
+
+ if((G.vd->flag & V3D_ZBUF_SELECT)==0)
+ glDisable(GL_DEPTH_TEST);
+
+ myloadmatrix(G.vd->viewmat);
+
+ BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, sel);
+ BIF_GetThemeColor3ubv(TH_VERTEX, nosel);
+ sel_col[0]=(float)sel[0]/255.0f;
+ sel_col[1]=(float)sel[1]/255.0f;
+ sel_col[2]=(float)sel[2]/255.0f;
+ nosel_col[0]=(float)nosel[0]/255.0f;
+ nosel_col[1]=(float)nosel[1]/255.0f;
+ nosel_col[2]=(float)nosel[2]/255.0f;
+
+ if(psys->childcache)
+ totchild = psys->totchildcache;
+
+ /* draw paths */
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ if(timed)
+ glEnable(GL_BLEND);
+
+ if(pset->brushtype == PE_BRUSH_WEIGHT){
+ glLineWidth(2.0f);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glDisable(GL_LIGHTING);
+ }
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+
+ for(i=0, pa=psys->particles, path = psys->pathcache; i<totpart; i++, pa++, path++){
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+
+ glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+ }
+
+ glEnable(GL_LIGHTING);
+ if(psys->part->draw_as == PART_DRAW_PATH) {
+ for(i=0, path=psys->childcache; i<totchild; i++,path++){
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->co);
+ glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), (*path)->vel);
+ glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), (*path)->col);
+
+ glDrawArrays(GL_LINE_STRIP, 0, (int)(*path)->steps + 1);
+ }
+ }
+
+ glDisable(GL_COLOR_MATERIAL);
+
+ /* draw edit vertices */
+ if(G.scene->selectmode!=SCE_SELECT_PATH){
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glDisable(GL_LIGHTING);
+ glPointSize(4.0f);
+
+ if(G.scene->selectmode==SCE_SELECT_POINT){
+ float *cd=0,*cdata=0;
+ cd=cdata=MEM_callocN(edit->totkeys*(timed?4:3)*sizeof(float), "particle edit color data");
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++){
+ for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++){
+ if(key->flag&PEK_SELECT){
+ VECCOPY(cd,sel_col);
+ }
+ else{
+ VECCOPY(cd,nosel_col);
+ }
+ if(timed)
+ *(cd+3) = (key->flag&PEK_HIDE)?0.0f:1.0f;
+ cd += (timed?4:3);
+ }
+ }
+ cd=cdata;
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++){
+ if((pa->flag & PARS_HIDE)==0){
+ glVertexPointer(3, GL_FLOAT, sizeof(ParticleEditKey), edit->keys[i]->world_co);
+ glColorPointer((timed?4:3), GL_FLOAT, (timed?4:3)*sizeof(float), cd);
+ glDrawArrays(GL_POINTS, 0, pa->totkey);
+ }
+ cd += (timed?4:3) * pa->totkey;
+
+ if(pset->flag&PE_SHOW_TIME && (pa->flag&PARS_HIDE)==0){
+ for(k=0, key=edit->keys[i]+k; k<pa->totkey; k++, key++){
+ if(key->flag & PEK_HIDE) continue;
+
+ glRasterPos3fv(key->world_co);
+ sprintf(val," %.1f",*key->time);
+ BMF_DrawString(G.font, val);
+ }
+ }
+ }
+ if(cdata)
+ MEM_freeN(cdata);
+ cd=cdata=0;
+ }
+ else if(G.scene->selectmode == SCE_SELECT_END){
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++){
+ if((pa->flag & PARS_HIDE)==0){
+ key = edit->keys[i] + pa->totkey - 1;
+ if(key->flag & PEK_SELECT)
+ glColor3fv(sel_col);
+ else
+ glColor3fv(nosel_col);
+ /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/
+ glBegin(GL_POINTS);
+ glVertex3fv(key->world_co);
+ glEnd();
+
+ if(pset->flag & PE_SHOW_TIME){
+ glRasterPos3fv(key->world_co);
+ sprintf(val," %.1f",*key->time);
+ BMF_DrawString(G.font, val);
+ }
+ }
+ }
+ }
+ }
+
+ glDisable(GL_BLEND);
+ glDisable(GL_LIGHTING);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnable(GL_DEPTH_TEST);
+ glLineWidth(1.0f);
+
+ mymultmatrix(ob->obmat); // bring back local matrix for dtx
+}
+
unsigned int nurbcol[8]= {
0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
@@ -2727,8 +3765,8 @@ static void tekenhandlesN(Nurb *nu, short sel)
float *fp;
unsigned int *col;
int a;
-
- if(nu->hide) return;
+
+ if(nu->hide || (G.f & G_HIDDENHANDLES)) return;
glBegin(GL_LINES);
@@ -2740,7 +3778,7 @@ static void tekenhandlesN(Nurb *nu, short sel)
a= nu->pntsu;
while(a--) {
if(bezt->hide==0) {
- if( (bezt->f2 & 1)==sel) {
+ if( (bezt->f2 & SELECT)==sel) {
fp= bezt->vec[0];
cpack(col[bezt->h1]);
@@ -2751,14 +3789,14 @@ static void tekenhandlesN(Nurb *nu, short sel)
glVertex3fv(fp+3);
glVertex3fv(fp+6);
}
- else if( (bezt->f1 & 1)==sel) {
+ else if( (bezt->f1 & SELECT)==sel) {
fp= bezt->vec[0];
cpack(col[bezt->h1]);
glVertex3fv(fp);
glVertex3fv(fp+3);
}
- else if( (bezt->f3 & 1)==sel) {
+ else if( (bezt->f3 & SELECT)==sel) {
fp= bezt->vec[1];
cpack(col[bezt->h2]);
@@ -2795,9 +3833,13 @@ static void tekenvertsN(Nurb *nu, short sel)
a= nu->pntsu;
while(a--) {
if(bezt->hide==0) {
- if((bezt->f1 & 1)==sel) bglVertex3fv(bezt->vec[0]);
- if((bezt->f2 & 1)==sel) bglVertex3fv(bezt->vec[1]);
- if((bezt->f3 & 1)==sel) bglVertex3fv(bezt->vec[2]);
+ if (G.f & G_HIDDENHANDLES) {
+ if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]);
+ } else {
+ if((bezt->f1 & SELECT)==sel) bglVertex3fv(bezt->vec[0]);
+ if((bezt->f2 & SELECT)==sel) bglVertex3fv(bezt->vec[1]);
+ if((bezt->f3 & SELECT)==sel) bglVertex3fv(bezt->vec[2]);
+ }
}
bezt++;
}
@@ -2807,7 +3849,7 @@ static void tekenvertsN(Nurb *nu, short sel)
a= nu->pntsu*nu->pntsv;
while(a--) {
if(bp->hide==0) {
- if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
+ if((bp->f1 & SELECT)==sel) bglVertex3fv(bp->vec);
}
bp++;
}
@@ -2850,7 +3892,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
for(a=nu->pntsu-1; a>0; a--, bp++) {
if(bp->hide==0 && bp1->hide==0) {
if(sel) {
- if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
+ if( (bp->f1 & SELECT) && ( bp1->f1 & SELECT ) ) {
cpack(nurbcol[5]);
glBegin(GL_LINE_STRIP);
@@ -2860,7 +3902,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
}
}
else {
- if( (bp->f1 & 1) && ( bp1->f1 & 1) );
+ if( (bp->f1 & SELECT) && ( bp1->f1 & SELECT) );
else {
cpack(nurbcol[1]);
@@ -2883,7 +3925,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
for(a=nu->pntsv-1; a>0; a--, bp+=ofs) {
if(bp->hide==0 && bp1->hide==0) {
if(sel) {
- if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
+ if( (bp->f1 & SELECT) && ( bp1->f1 & SELECT) ) {
cpack(nurbcol[7]);
glBegin(GL_LINE_STRIP);
@@ -2893,7 +3935,7 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
}
}
else {
- if( (bp->f1 & 1) && ( bp1->f1 & 1) );
+ if( (bp->f1 & SELECT) && ( bp1->f1 & SELECT) );
else {
cpack(nurbcol[3]);
@@ -2947,8 +3989,9 @@ static void drawnurb(Base *base, Nurb *nurb, int dt)
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
- /* direction vectors for 3d curve paths */
- if(cu->flag & CU_3D) {
+ /* direction vectors for 3d curve paths
+ when at its lowest, dont render normals */
+ if(cu->flag & CU_3D && G.scene->editbutsize > 0.0015) {
BIF_ThemeColor(TH_WIRE);
for (bl=cu->bev.first,nu=nurb; nu && bl; bl=bl->next,nu=nu->next) {
BevPoint *bevp= (BevPoint *)(bl+1);
@@ -2956,7 +3999,7 @@ static void drawnurb(Base *base, Nurb *nurb, int dt)
int skip= nu->resolu/16;
float fac;
- while (nr-->0) {
+ while (nr-->0) { /* accounts for empty bevel lists */
float ox,oy,oz; // Offset perpendicular to the curve
float dx,dy,dz; // Delta along the curve
@@ -2991,6 +4034,45 @@ static void drawnurb(Base *base, Nurb *nurb, int dt)
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
}
+/* draw a sphere for use as an empty drawtype */
+static void draw_empty_sphere (float size)
+{
+ float cent=0;
+ GLUquadricObj *qobj = gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+
+ glPushMatrix();
+ glTranslatef(cent, cent, cent);
+ glScalef(size, size, size);
+ gluSphere(qobj, 1.0, 8, 5);
+
+ glPopMatrix();
+
+ gluDeleteQuadric(qobj);
+}
+
+/* draw a cone for use as an empty drawtype */
+static void draw_empty_cone (float size)
+{
+ float cent=0;
+ float radius;
+ GLUquadricObj *qobj = gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+
+
+ glPushMatrix();
+
+ radius = size;
+ glTranslatef(cent,cent, cent);
+ glScalef(radius, 2.0*size, radius);
+ glRotatef(-90., 1.0, 0.0, 0.0);
+ gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
+
+ glPopMatrix();
+
+ gluDeleteQuadric(qobj);
+}
+
/* draw points on curve speed handles */
static void curve_draw_speed(Object *ob)
{
@@ -3041,72 +4123,6 @@ static void drawspiral(float *cent, float rad, float tmat[][4], int start)
float vec[3], vx[3], vy[3];
int a, tot=32;
char inverse=0;
- /* 32 values of sin function (still same result!) */
- static float si[32] = {0.00000000,
- 0.20129852,
- 0.39435585,
- 0.57126821,
- 0.72479278,
- 0.84864425,
- 0.93775213,
- 0.98846832,
- 0.99871650,
- 0.96807711,
- 0.89780453,
- 0.79077573,
- 0.65137248,
- 0.48530196,
- 0.29936312,
- 0.10116832,
- -0.10116832,
- -0.29936312,
- -0.48530196,
- -0.65137248,
- -0.79077573,
- -0.89780453,
- -0.96807711,
- -0.99871650,
- -0.98846832,
- -0.93775213,
- -0.84864425,
- -0.72479278,
- -0.57126821,
- -0.39435585,
- -0.20129852,
- 0.00000000};
- /* 32 values of cos function (still same result!) */
- static float co[32] ={1.00000000,
- 0.97952994,
- 0.91895781,
- 0.82076344,
- 0.68896691,
- 0.52896401,
- 0.34730525,
- 0.15142777,
- -0.05064916,
- -0.25065253,
- -0.44039415,
- -0.61210598,
- -0.75875812,
- -0.87434661,
- -0.95413925,
- -0.99486932,
- -0.99486932,
- -0.95413925,
- -0.87434661,
- -0.75875812,
- -0.61210598,
- -0.44039415,
- -0.25065253,
- -0.05064916,
- 0.15142777,
- 0.34730525,
- 0.52896401,
- 0.68896691,
- 0.82076344,
- 0.91895781,
- 0.97952994,
- 1.00000000};
if (start < 0) {
inverse = 1;
@@ -3126,103 +4142,58 @@ static void drawspiral(float *cent, float rad, float tmat[][4], int start)
start=-a + 1;
glBegin(GL_LINES);
glVertex3fv(vec);
- vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)a/(float)tot) + *(co+a+start) * (vy[0] * (float)a/(float)tot);
- vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)a/(float)tot) + *(co+a+start) * (vy[1] * (float)a/(float)tot);
- vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)a/(float)tot) + *(co+a+start) * (vy[2] * (float)a/(float)tot);
+ vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)a/(float)tot) + *(cosval+a+start) * (vy[0] * (float)a/(float)tot);
+ vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)a/(float)tot) + *(cosval+a+start) * (vy[1] * (float)a/(float)tot);
+ vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)a/(float)tot) + *(cosval+a+start) * (vy[2] * (float)a/(float)tot);
glVertex3fv(vec);
glEnd();
}
}
else {
a=0;
- vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
- vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
- vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
+ vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
+ vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
+ vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
for(a=0; a<tot; a++) {
if (a+start>31)
start=-a + 1;
glBegin(GL_LINES);
glVertex3fv(vec);
- vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
- vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
- vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
+ vec[0]= cent[0] + *(sinval+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
+ vec[1]= cent[1] + *(sinval+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
+ vec[2]= cent[2] + *(sinval+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(cosval+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
glVertex3fv(vec);
glEnd();
}
}
}
+/* draws a circle on x-z plane given the scaling of the circle, assuming that
+ * all required matrices have been set (used for drawing empties)
+ */
+static void drawcircle_size(float size)
+{
+ float x, y;
+ short degrees;
+
+ glBegin(GL_LINE_LOOP);
+
+ /* coordinates are: cos(degrees*11.25)=x, sin(degrees*11.25)=y, 0.0f=z */
+ for (degrees=0; degrees<32; degrees++) {
+ x= *(cosval + degrees);
+ y= *(sinval + degrees);
+
+ glVertex3f(x*size, 0.0f, y*size);
+ }
+
+ glEnd();
+
+}
+
void drawcircball(int mode, float *cent, float rad, float tmat[][4])
{
float vec[3], vx[3], vy[3];
int a, tot=32;
-
- /* 32 values of sin function (still same result!) */
- static float si[32] = {0.00000000,
- 0.20129852,
- 0.39435585,
- 0.57126821,
- 0.72479278,
- 0.84864425,
- 0.93775213,
- 0.98846832,
- 0.99871650,
- 0.96807711,
- 0.89780453,
- 0.79077573,
- 0.65137248,
- 0.48530196,
- 0.29936312,
- 0.10116832,
- -0.10116832,
- -0.29936312,
- -0.48530196,
- -0.65137248,
- -0.79077573,
- -0.89780453,
- -0.96807711,
- -0.99871650,
- -0.98846832,
- -0.93775213,
- -0.84864425,
- -0.72479278,
- -0.57126821,
- -0.39435585,
- -0.20129852,
- 0.00000000};
- /* 32 values of cos function (still same result!) */
- static float co[32] ={1.00000000,
- 0.97952994,
- 0.91895781,
- 0.82076344,
- 0.68896691,
- 0.52896401,
- 0.34730525,
- 0.15142777,
- -0.05064916,
- -0.25065253,
- -0.44039415,
- -0.61210598,
- -0.75875812,
- -0.87434661,
- -0.95413925,
- -0.99486932,
- -0.99486932,
- -0.95413925,
- -0.87434661,
- -0.75875812,
- -0.61210598,
- -0.44039415,
- -0.25065253,
- -0.05064916,
- 0.15142777,
- 0.34730525,
- 0.52896401,
- 0.68896691,
- 0.82076344,
- 0.91895781,
- 0.97952994,
- 1.00000000};
VECCOPY(vx, tmat[0]);
VECCOPY(vy, tmat[1]);
@@ -3231,14 +4202,56 @@ void drawcircball(int mode, float *cent, float rad, float tmat[][4])
glBegin(mode);
for(a=0; a<tot; a++) {
- vec[0]= cent[0] + *(si+a) * vx[0] + *(co+a) * vy[0];
- vec[1]= cent[1] + *(si+a) * vx[1] + *(co+a) * vy[1];
- vec[2]= cent[2] + *(si+a) * vx[2] + *(co+a) * vy[2];
+ vec[0]= cent[0] + *(sinval+a) * vx[0] + *(cosval+a) * vy[0];
+ vec[1]= cent[1] + *(sinval+a) * vx[1] + *(cosval+a) * vy[1];
+ vec[2]= cent[2] + *(sinval+a) * vx[2] + *(cosval+a) * vy[2];
glVertex3fv(vec);
}
glEnd();
}
+/* needs fixing if non-identity matrice used */
+static void drawtube(float *vec, float radius, float height, float tmat[][4])
+{
+ float cur[3];
+ drawcircball(GL_LINE_LOOP, vec, radius, tmat);
+
+ VecCopyf(cur,vec);
+ cur[2]+=height;
+ drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+
+ glBegin(GL_LINES);
+ glVertex3f(vec[0]+radius,vec[1],vec[2]);
+ glVertex3f(cur[0]+radius,cur[1],cur[2]);
+ glVertex3f(vec[0]-radius,vec[1],vec[2]);
+ glVertex3f(cur[0]-radius,cur[1],cur[2]);
+ glVertex3f(vec[0],vec[1]+radius,vec[2]);
+ glVertex3f(cur[0],cur[1]+radius,cur[2]);
+ glVertex3f(vec[0],vec[1]-radius,vec[2]);
+ glVertex3f(cur[0],cur[1]-radius,cur[2]);
+ glEnd();
+}
+/* needs fixing if non-identity matrice used */
+static void drawcone(float *vec, float radius, float height, float tmat[][4])
+{
+ float cur[3];
+
+ VecCopyf(cur,vec);
+ cur[2]+=height;
+
+ drawcircball(GL_LINE_LOOP, cur, radius, tmat);
+
+ glBegin(GL_LINES);
+ glVertex3f(vec[0],vec[1],vec[2]);
+ glVertex3f(cur[0]+radius,cur[1],cur[2]);
+ glVertex3f(vec[0],vec[1],vec[2]);
+ glVertex3f(cur[0]-radius,cur[1],cur[2]);
+ glVertex3f(vec[0],vec[1],vec[2]);
+ glVertex3f(cur[0],cur[1]+radius,cur[2]);
+ glVertex3f(vec[0],vec[1],vec[2]);
+ glVertex3f(cur[0],cur[1]-radius,cur[2]);
+ glEnd();
+}
/* return 1 if nothing was drawn */
static int drawmball(Base *base, int dt)
{
@@ -3368,7 +4381,7 @@ static void draw_forcefield(Object *ob)
else if (pd->forcefield == PFIELD_VORTEX) {
float ffall_val, force_val;
- Mat4One(imat);
+ Mat4One(tmat);
if (has_ipo_code(ob->ipo, OB_PD_FFALL))
ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, G.scene->r.cfra);
else
@@ -3381,12 +4394,12 @@ static void draw_forcefield(Object *ob)
BIF_ThemeColorBlend(curcol, TH_BACK, 0.7);
if (force_val < 0) {
- drawspiral(vec, size*1.0, imat, 1);
- drawspiral(vec, size*1.0, imat, 16);
+ drawspiral(vec, size*1.0, tmat, 1);
+ drawspiral(vec, size*1.0, tmat, 16);
}
else {
- drawspiral(vec, size*1.0, imat, -1);
- drawspiral(vec, size*1.0, imat, -16);
+ drawspiral(vec, size*1.0, tmat, -1);
+ drawspiral(vec, size*1.0, tmat, -16);
}
}
else if (pd->forcefield == PFIELD_GUIDE && ob->type==OB_CURVE) {
@@ -3414,14 +4427,66 @@ static void draw_forcefield(Object *ob)
VECCOPY(vec, guidevec1); /* max center */
}
}
-
- /* as last, guide curve alters it */
- if(pd->flag & PFIELD_USEMAX) {
- setlinestyle(3);
- BIF_ThemeColorBlend(curcol, TH_BACK, 0.5);
- drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat);
- setlinestyle(0);
+
+ setlinestyle(3);
+ BIF_ThemeColorBlend(curcol, TH_BACK, 0.5);
+
+ if(pd->falloff==PFIELD_FALL_SPHERE){
+ /* as last, guide curve alters it */
+ if(pd->flag & PFIELD_USEMAX)
+ drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat);
+
+ if(pd->flag & PFIELD_USEMIN)
+ drawcircball(GL_LINE_LOOP, vec, pd->mindist, imat);
+ }
+ else if(pd->falloff==PFIELD_FALL_TUBE){
+ float radius,distance;
+
+ Mat4One(tmat);
+
+ vec[0]=vec[1]=0.0f;
+ radius=(pd->flag&PFIELD_USEMAXR)?pd->maxrad:1.0f;
+ distance=(pd->flag&PFIELD_USEMAX)?pd->maxdist:0.0f;
+ vec[2]=distance;
+ distance=(pd->flag&PFIELD_POSZ)?-distance:-2.0f*distance;
+
+ if(pd->flag & (PFIELD_USEMAX|PFIELD_USEMAXR))
+ drawtube(vec,radius,distance,tmat);
+
+ radius=(pd->flag&PFIELD_USEMINR)?pd->minrad:1.0f;
+ distance=(pd->flag&PFIELD_USEMIN)?pd->mindist:0.0f;
+ vec[2]=distance;
+ distance=(pd->flag&PFIELD_POSZ)?-distance:-2.0f*distance;
+
+ if(pd->flag & (PFIELD_USEMIN|PFIELD_USEMINR))
+ drawtube(vec,radius,distance,tmat);
}
+ else if(pd->falloff==PFIELD_FALL_CONE){
+ float radius,distance;
+
+ Mat4One(tmat);
+
+ radius=(pd->flag&PFIELD_USEMAXR)?pd->maxrad:1.0f;
+ radius*=(float)M_PI/180.0f;
+ distance=(pd->flag&PFIELD_USEMAX)?pd->maxdist:0.0f;
+
+ if(pd->flag & (PFIELD_USEMAX|PFIELD_USEMAXR)){
+ drawcone(vec,distance*sin(radius),distance*cos(radius),tmat);
+ if((pd->flag & PFIELD_POSZ)==0)
+ drawcone(vec,distance*sin(radius),-distance*cos(radius),tmat);
+ }
+
+ radius=(pd->flag&PFIELD_USEMINR)?pd->minrad:1.0f;
+ radius*=(float)M_PI/180.0f;
+ distance=(pd->flag&PFIELD_USEMIN)?pd->mindist:0.0f;
+
+ if(pd->flag & (PFIELD_USEMIN|PFIELD_USEMINR)){
+ drawcone(vec,distance*sin(radius),distance*cos(radius),tmat);
+ if((pd->flag & PFIELD_POSZ)==0)
+ drawcone(vec,distance*sin(radius),-distance*cos(radius),tmat);
+ }
+ }
+ setlinestyle(0);
}
static void draw_box(float vec[8][3])
@@ -3505,7 +4570,7 @@ static void draw_bounding_volume(Object *ob)
BoundBox *bb=0;
if(ob->type==OB_MESH) {
- bb= mesh_get_bb(ob->data);
+ bb= mesh_get_bb(ob);
}
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
bb= ( (Curve *)ob->data )->bb;
@@ -3731,10 +4796,13 @@ void draw_object(Base *base, int flag)
/* xray delay? */
if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) {
- /* xray and transp are set when it is drawing the 2nd/3rd pass */
- if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) {
- add_view3d_after(G.vd, base, V3D_XRAY);
- return;
+ /* don't do xray in particle mode, need the z-buffer */
+ if(!(G.f & G_PARTICLEEDIT)) {
+ /* xray and transp are set when it is drawing the 2nd/3rd pass */
+ if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) {
+ add_view3d_after(G.vd, base, V3D_XRAY);
+ return;
+ }
}
}
@@ -3868,22 +4936,21 @@ void draw_object(Base *base, int flag)
dtx= 0;
/* faceselect exception: also draw solid when dt==wire, except in editmode */
- if(ob==OBACT && (G.f & (G_FACESELECT+G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) {
+ if(ob==OBACT && (G.f & (G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) {
if(ob->type==OB_MESH) {
if(ob==G.obedit);
else {
- dt= OB_SHADED;
+ if(dt<OB_SOLID)
+ zbufoff= 1;
- glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
+ dt= OB_SHADED;
glEnable(GL_DEPTH_TEST);
- if(dt<OB_SOLID) zbufoff= 1;
}
}
else {
if(dt<OB_SOLID) {
dt= OB_SOLID;
- glClearDepth(1.); glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
zbufoff= 1;
}
@@ -4071,6 +5138,28 @@ void draw_object(Base *base, int flag)
}
if(ob->pd && ob->pd->forcefield) draw_forcefield(ob);
+ /* code for new particle system */
+ if( (warning_recursive==0) &&
+ (ob->particlesystem.first) &&
+ (flag & DRAW_PICKING)==0 &&
+ (ob!=G.obedit)
+ ) {
+ ParticleSystem *psys;
+ if(col || (ob->flag & SELECT)) cpack(0xFFFFFF); /* for visibility, also while wpaint */
+ glDepthMask(GL_FALSE);
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next)
+ draw_new_particle_system(base, psys);
+
+ if(G.f & G_PARTICLEEDIT && ob==OBACT) {
+ psys= PE_get_current(ob);
+ if(psys && !G.obedit && psys_in_edit_mode(psys))
+ draw_particle_edit(ob, psys);
+ }
+ glDepthMask(GL_TRUE);
+ if(col) cpack(col);
+ }
+
{
bConstraint *con;
for(con=ob->constraints.first; con; con= con->next)
@@ -4102,7 +5191,7 @@ void draw_object(Base *base, int flag)
BMF_DrawString(G.font, ob->id.name+2);
}
}
- if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);
+ /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
if((dtx & OB_DRAWWIRE) && dt>=OB_SOLID) drawWireExtra(ob);
}
@@ -4129,7 +5218,7 @@ void draw_object(Base *base, int flag)
if(G.f & G_SIMULATION) return;
/* object centers, need to be drawn in viewmat space for speed, but OK for picking select */
- if(ob!=OBACT || (G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
+ if(ob!=OBACT || (G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
int do_draw_center= -1; /* defines below are zero or positive... */
if((G.scene->basact)==base)
@@ -4161,10 +5250,10 @@ void draw_object(Base *base, int flag)
/* not for sets, duplicators or picking */
if(flag==0 && (!(G.vd->flag & V3D_HIDE_HELPLINES))) {
ListBase *list;
-
+
/* draw hook center and offset line */
if(ob!=G.obedit) draw_hooks(ob);
-
+
/* help lines and so */
if(ob!=G.obedit && ob->parent && (ob->parent->lay & G.vd->lay)) {
setlinestyle(3);
@@ -4177,29 +5266,46 @@ void draw_object(Base *base, int flag)
/* Drawing the constraint lines */
list = &ob->constraints;
- if (list){
- /*
- extern void make_axis_color(char *col, char *col2, char axis); // drawview.c
- */
+ if (list) {
bConstraint *curcon;
- float size[3], tmat[4][4];
+ bConstraintOb *cob;
char col[4], col2[4];
-
+
BIF_GetThemeColor3ubv(TH_GRID, col);
make_axis_color(col, col2, 'z');
glColor3ubv((GLubyte *)col2);
-
- for (curcon = list->first; curcon; curcon=curcon->next){
- if ((curcon->flag & CONSTRAINT_EXPAND)&&(curcon->type!=CONSTRAINT_TYPE_NULL)&&(constraint_has_target(curcon))){
- get_constraint_target_matrix(curcon, TARGET_OBJECT, NULL, tmat, size, bsystem_time(ob, 0, (float)(G.scene->r.cfra), ob->sf));
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(tmat[3]);
- glVertex3fv(ob->obmat[3]);
- glEnd();
- setlinestyle(0);
+
+ cob= constraints_make_evalob(ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+
+ for (curcon = list->first; curcon; curcon=curcon->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if ((curcon->flag & CONSTRAINT_EXPAND) && (cti) && (cti->get_constraint_targets)) {
+ cti->get_constraint_targets(curcon, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ /* calculate target's matrix */
+ if (cti->get_target_matrix)
+ cti->get_target_matrix(curcon, cob, ct, bsystem_time(ob, (float)(G.scene->r.cfra), give_timeoffset(ob)));
+ else
+ Mat4One(ct->matrix);
+
+ setlinestyle(3);
+ glBegin(GL_LINES);
+ glVertex3fv(ct->matrix[3]);
+ glVertex3fv(ob->obmat[3]);
+ glEnd();
+ setlinestyle(0);
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(curcon, &targets, 1);
}
}
+
+ constraints_clear_evalob(cob);
}
}
@@ -4314,7 +5420,7 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
if (facecol) {
dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(long) 1, 0);
- if(G.scene->selectmode & SCE_SELECT_FACE) {
+ if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
bglBegin(GL_POINTS);
@@ -4333,7 +5439,7 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
{
Mesh *me = userData;
- if (!me->mtface || !(me->mface[index].flag&ME_HIDE)) {
+ if (!(me->mface[index].flag&ME_HIDE)) {
set_framebuffer_index_color(index+1);
return 1;
} else {
@@ -4354,6 +5460,7 @@ static int bbs_mesh_wire__setDrawOpts(void *userData, int index)
return 0;
}
+/* TODO remove this - since face select mode now only works with painting */
static void bbs_mesh_solid(Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(ob, get_viewedit_datamask());
@@ -4364,7 +5471,7 @@ static void bbs_mesh_solid(Object *ob)
/* draw edges for seam marking in faceselect mode, but not when painting,
so that painting doesn't get interrupted on an edge */
- if ((G.f & G_FACESELECT) && !(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) && me->mtface) {
+ if ((G.f & G_FACESELECT) && !(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))) {
struct { Mesh *me; EdgeHash *eh; int offset; } userData;
userData.me = me;
@@ -4429,12 +5536,11 @@ void draw_object_backbufsel(Object *ob)
/* ************* draw object instances for bones, for example ****************** */
/* assumes all matrices/etc set OK */
-void draw_object_instance(Object *ob, int dt, int outline)
+/* helper function for drawing object instances - meshes */
+static void draw_object_mesh_instance(Object *ob, int dt, int outline)
{
DerivedMesh *dm=NULL, *edm=NULL;
- if(ob==NULL || ob->type!=OB_MESH) return;
-
if(G.obedit && ob->data==G.obedit->data)
edm= editmesh_get_derived_base();
else
@@ -4474,3 +5580,17 @@ void draw_object_instance(Object *ob, int dt, int outline)
if(dm) dm->release(dm);
}
+void draw_object_instance(Object *ob, int dt, int outline)
+{
+ if (ob == NULL)
+ return;
+
+ switch (ob->type) {
+ case OB_MESH:
+ draw_object_mesh_instance(ob, dt, outline);
+ break;
+ case OB_EMPTY:
+ drawaxes(ob->empty_drawsize, 0, ob->empty_drawtype);
+ break;
+ }
+}
diff --git a/source/blender/src/drawoops.c b/source/blender/src/drawoops.c
index 70634a4964b..ef32d2c7039 100644
--- a/source/blender/src/drawoops.c
+++ b/source/blender/src/drawoops.c
@@ -56,6 +56,7 @@
#include "BIF_interface.h"
#include "BIF_interface_icons.h"
+#include "BIF_language.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
@@ -69,8 +70,13 @@
#include "BSE_drawipo.h"
#include "BSE_drawoops.h"
-float oopscalex;
-struct BMF_Font *font; /* for using different sized fonts */
+float aspect;
+void *font;
+
+
+static float icon_width();
+float center_oops_text(char *str);
+
void boundbox_oops(short sel)
{
@@ -130,7 +136,7 @@ void draw_oopslink(Oops *oops)
float vec[4][3], dist, spline_step;
short curve_res;
- if(oops->type==ID_SCE) {
+ if(oops->type==ID_SCE || oops->type==ID_GR) {
if(oops->flag & SELECT) {
/* when using python Mesh to make meshes a file was saved
that had an oops with no ID, stops a segfault when looking for lib */
@@ -180,7 +186,7 @@ void draw_oopslink(Oops *oops)
else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */
else {
/* calculate a curve resolution to use based on the length of the curve.*/
- curve_res = MIN2(40, MAX2(2, (short)((dist*2) * (oopscalex))));
+ curve_res = MIN2(40, MAX2(2, 2*dist/aspect));
/* we can reuse the dist variable here to increment the GL curve eval amount*/
dist = (float)1/curve_res;
@@ -200,9 +206,16 @@ void draw_oopslink(Oops *oops)
}
}
+static float icon_width()
+{
+ /* change it in *one place* when you mess around */
+ return 0.8*OOPSY;
+}
+
void draw_icon_oops(float *co, short type)
{
BIFIconID icon;
+ float ofs;
switch(type) {
default: return;
@@ -218,12 +231,15 @@ void draw_icon_oops(float *co, short type)
case ID_IP: icon= ICON_IPO_HLT; break;
case ID_LI: icon= ICON_LIBRARY_HLT; break;
case ID_IM: icon= ICON_IMAGE_HLT; break;
+ case ID_GR: icon= ICON_CIRCLE_DEHLT; break;
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- BIF_icon_draw(co[0], co[1]-0.2, icon);
+ /* height of box is OOPSY...icon is centered vertically */
+ ofs = (OOPSY - icon_width())/2.0;
+ BIF_icon_draw_aspect(co[0], co[1]+ofs, icon, icon_width()*aspect*ICON_DEFAULT_HEIGHT/OOPSY);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
@@ -267,6 +283,8 @@ unsigned int give_oops_color(short type, short sel, unsigned int *border)
body= 0x2198DC; break;
case ID_IM:
body= 0x35659F; break;
+ case ID_GR:
+ body= 0x507050; break;
default:
body= 0x606070; break;
}
@@ -281,46 +299,25 @@ unsigned int give_oops_color(short type, short sel, unsigned int *border)
return body;
}
-void calc_oopstext(char *str, float *v1)
+
+float center_oops_text(char *str)
+/* gives x offset at which to draw oops text -- takes icon into account */
{
- float f1, f2, size; /* f1 is the lhs of the oops block, f2 is the rhs */
- short mval[2], len, flen;
-
- ipoco_to_areaco_noclip(G.v2d, v1, mval);
- f1= mval[0];
- v1[0]+= OOPSX;
- ipoco_to_areaco_noclip(G.v2d, v1, mval);
- f2= mval[0];
-
- if (oopscalex>1.1) { /* Make text area wider if we have no icon.*/
- size= f2-f1;
- } else {
- size= (f2-f1)*1.7;
- }
+ int len;
+ float width;
len= strlen(str);
-
- while( (flen= BMF_GetStringWidth(G.fonts, str)) > size) {
- if(flen < 10 || len<2) break;
- len--;
- str[len]= 0;
- }
-
- flen= BMF_GetStringWidth(font, str);
-
- /* calc centerd location for icon and text,
- else if were zoomed too far out, just push text to the left of the oops block. */
- if (oopscalex>1.1) {
- mval[0]= (f1+f2-flen+1)/2;
- } else {
- mval[0]= f1;
- }
-
- mval[1]= 1;
- areamouseco_to_ipoco(G.v2d, mval, &f1, &f2);
-
- v1[0]= f1;
-
+ if(len < 1) return 0;
+
+ /* center at box width of OOPSX */
+ width= aspect*BIF_GetStringWidth(font, str, 0) + icon_width();
+
+ while(width > OOPSX && len >= 0) {
+ str[len] = 0;
+ width= aspect*BIF_GetStringWidth(font, str, 0) + icon_width();
+ len--;
+ }
+ return (OOPSX - width)/2;
}
void draw_oops(Oops *oops)
@@ -336,6 +333,7 @@ void draw_oops(Oops *oops)
y1= oops->y;
y2= oops->y+OOPSY;
+ /* do clip */
if(x2 < G.v2d->cur.xmin || x1 > G.v2d->cur.xmax) return;
if(y2 < G.v2d->cur.ymin || y1 > G.v2d->cur.ymax) return;
@@ -343,15 +341,15 @@ void draw_oops(Oops *oops)
if(oops->id== (ID *)((G.scene->basact) ? (G.scene->basact->object) : 0)) line= 1;
else if(oops->id== (ID *)G.scene) line= 1;
+ if (!oops->id) return;
+
if(oops->id->us) {
cpack(body);
- glRectf(x1, y1, x2, y2);
+ glRectf(x1, y1, x2, y2);
}
-
- /* it has never happened that an oops was missing an ID at
- this point but has occured elseware so lets be safe */
- if(oops->id && oops->id->lib) {
+
+ if(oops->id->lib) {
if(oops->id->flag & LIB_INDIRECT) cpack(0x1144FF);
else cpack(0x11AAFF);
@@ -359,27 +357,31 @@ void draw_oops(Oops *oops)
}
v1[0]= x1;
- v1[1]= (y1+y2)/2 -0.3;
+ v1[1] = y1;
+
if(oops->type==ID_LI) {
- sprintf(str, " %s", ((Library *)oops->id)->name);
+ sprintf(str, " %s", ((Library *)oops->id)->name);
}
else {
- sprintf(str, " %s", oops->id->name+2);
+ sprintf(str, " %s", oops->id->name+2);
}
- calc_oopstext(str, v1);
-
- /* ICON */
- if(str[1] && oopscalex>1.1) { /* HAS ICON */
- draw_icon_oops(v1, oops->type);
- } else { /* NO ICON, UNINDENT*/
- v1[0] -= 1.3 / oopscalex;
- }
+
+ BIF_SetScale(aspect);
+ v1[0] += center_oops_text(str);
+
+ draw_icon_oops(v1, oops->type);
+ v1[0] += icon_width();
+
+ v1[1] = y1+(y2-y1)/3.0;
if(oops->flag & SELECT) BIF_ThemeColor(TH_TEXT_HI);
else BIF_ThemeColor(TH_TEXT);
- glRasterPos3f(v1[0], v1[1], 0.0);
- BMF_DrawString(font, str);
-
- if(line) setlinestyle(2);
+ glRasterPos2f(v1[0], v1[1]);
+ BIF_RasterPos(v1[0], v1[1]);
+ BIF_SetScale(aspect);
+ BIF_DrawString(font, str, 0);
+
+
+ if(line) setlinestyle(2);
cpack(border);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -410,7 +412,7 @@ void draw_oops(Oops *oops)
}
if(oops->flag & OOPS_REFER) {
- /* Draw the little rounded connection point */
+ /* Draw the little rounded connection point */
glColor3ub(0, 0, 0);
glPushMatrix();
@@ -428,6 +430,8 @@ void drawoopsspace(ScrArea *sa, void *spacedata)
float col[3];
BIF_GetThemeColor3fv(TH_BACK, col);
+
+ if(soops==0) return;
/* darker background for oops */
if(soops->type!=SO_OUTLINER) {
@@ -436,7 +440,6 @@ void drawoopsspace(ScrArea *sa, void *spacedata)
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
- if(soops==0) return;
if(soops->type==SO_OUTLINER) draw_outliner(sa, soops);
else {
@@ -445,62 +448,56 @@ void drawoopsspace(ScrArea *sa, void *spacedata)
boundbox_oops(0);
calc_scrollrcts(sa, G.v2d, curarea->winx, curarea->winy);
- myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ bwin_clear_viewmat(sa->win); /* clear buttons view */
+ glLoadIdentity();
+
+ aspect= (G.v2d->cur.xmax - G.v2d->cur.xmin)/((float)sa->winx);
+ font= uiSetCurFont_ext(30*aspect);
- oopscalex= .14*((float)curarea->winx)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
calc_ipogrid(); /* for scrollvariables */
-
- /* Draw a page about the oops */
+ /* drop shadow */
+ BIF_ThemeColorShade(TH_BACK, -96); /* drop shadow color */
+ glRectf(G.v2d->tot.xmin-1, G.v2d->tot.ymin-3, G.v2d->tot.xmax+3,
+ G.v2d->tot.ymax+1);
+
+ /* light square in the center */
BIF_GetThemeColor3fv(TH_BACK, col);
glColor3fv(col);
- glRectf(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2, G.v2d->tot.ymax+2); /* light square in the center */
- BIF_ThemeColorShade(TH_BACK, -96); /* drop shadow color */
- glRectf(G.v2d->tot.xmin-1, G.v2d->tot.ymin-2, G.v2d->tot.xmax+3, G.v2d->tot.ymin-3); /* bottom dropshadow */
- glRectf(G.v2d->tot.xmax+2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+3, G.v2d->tot.ymax+1); /* right hand dropshadow */
+ glRectf(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2,
+ G.v2d->tot.ymax+2);
+
/* box around the oops. */
cpack(0x0);
- mysbox(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2, G.v2d->tot.ymax+2);
-
-
- /* Set the font size for the oops based on the zoom level */
- if (oopscalex > 6.0) font = BMF_GetFont(BMF_kScreen15);
- else if (oopscalex > 3.5) font = G.font;
- else if (oopscalex > 2.5) font = G.fonts;
- else font = G.fontss;
-
+ mysbox(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2,
+ G.v2d->tot.ymax+2);
+
+
/* Draw unselected oops links */
- oops= soops->oops.first;
- while(oops) {
+ for(oops= soops->oops.first; oops; oops = oops->next) {
if(oops->hide==0 && (oops->flag & SELECT)); else {
draw_oopslink(oops);
}
- oops= oops->next;
}
/* Draw selected oops links */
- oops= soops->oops.first;
- while(oops) {
+ for(oops= soops->oops.first; oops; oops = oops->next) {
if(oops->hide==0 && (oops->flag & SELECT)) {
draw_oopslink(oops);
}
- oops= oops->next;
}
- oops= soops->oops.first;
- while(oops) {
+ for(oops= soops->oops.first; oops; oops = oops->next) {
if(oops->hide==0) {
if(oops->flag & SELECT); else draw_oops(oops);
}
- oops= oops->next;
}
- oops= soops->oops.first;
- while(oops) {
+ for(oops= soops->oops.first; oops; oops = oops->next) {
if(oops->hide==0) {
if(oops->flag & SELECT) draw_oops(oops);
}
- oops= oops->next;
}
}
diff --git a/source/blender/src/drawscene.c b/source/blender/src/drawscene.c
index b2d8920c1a2..557083d2b97 100644
--- a/source/blender/src/drawscene.c
+++ b/source/blender/src/drawscene.c
@@ -74,16 +74,7 @@ void set_scene(Scene *sce) /* also see scene.c: set_scene_bg() */
if( G.obedit)
exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
- if(G.f & G_FACESELECT)
- set_faceselect();
- if(G.f & G_VERTEXPAINT)
- set_vpaint();
- if(G.f & G_TEXTUREPAINT)
- set_texturepaint();
- if(G.f & G_WEIGHTPAINT)
- set_wpaint();
- if(G.f & G_SCULPTMODE)
- set_sculptmode();
+ exit_paint_modes();
G.scene= sce;
diff --git a/source/blender/src/drawscript.c b/source/blender/src/drawscript.c
index 024d83950ad..b6ea63ca695 100644
--- a/source/blender/src/drawscript.c
+++ b/source/blender/src/drawscript.c
@@ -58,7 +58,6 @@
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BPI_script.h"
#include "BPY_extern.h"
#include "BIF_gl.h"
@@ -95,6 +94,20 @@ void drawscriptspace(ScrArea *sa, void *spacedata)
script = sc->script;
+ /* Is this script loaded from a file and it needs running??? */
+ if ( (G.f & G_DOSCRIPTLINKS) &&
+ script->scriptname[0] != '\0' &&
+ (script->flags == 0 &&
+ script->py_event == NULL &&
+ script->py_button == NULL &&
+ script->py_draw == NULL )
+ ) {
+ if (!BPY_run_script(script)) {
+ /* if this fails, script will be free'd */
+ script = NULL;
+ }
+ }
+
if (script->py_draw) {
BPY_spacescript_do_pywin_draw(sc);
}
@@ -114,6 +127,22 @@ void winqreadscriptspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *
Script *script = sc->script;
if (script) {
+ /* Is this script loaded from a file and it needs running??? */
+ if ( (G.f & G_DOSCRIPTLINKS) &&
+ script->scriptname[0] != '\0' &&
+ (script->flags == 0 &&
+ script->py_event == NULL &&
+ script->py_button == NULL &&
+ script->py_draw == NULL )
+ ) {
+ if (!BPY_run_script(script)) {
+ /* if this fails, script will be free'd */
+ script = NULL;
+ }
+ }
+ }
+
+ if (script) {
if (script->py_event || script->py_button)
BPY_spacescript_do_pywin_event(sc, event, val, ascii);
@@ -142,6 +171,12 @@ void winqreadscriptspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *
void free_scriptspace (SpaceScript *sc)
{
if (!sc) return;
-
+
+ /*free buttons references*/
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList();
+ sc->but_refs = NULL;
+ }
sc->script = NULL;
}
diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c
index fac1468fdd2..ab77294abea 100644
--- a/source/blender/src/drawseq.c
+++ b/source/blender/src/drawseq.c
@@ -51,6 +51,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view2d_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "BKE_plugin_types.h"
@@ -75,6 +76,7 @@
#include "BSE_seqeffects.h"
#include "BSE_seqscopes.h"
#include "BSE_seqaudio.h"
+#include "BSE_time.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -90,43 +92,33 @@
#define SEQ_STRIP_OFSBOTTOM 0.2
#define SEQ_STRIP_OFSTOP 0.8
+static GLubyte halftone[] = {
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
+
+/* Note, Dont use WHILE_SEQ while drawing! - it messes up transform, - Campbell */
+
int no_rightbox=0, no_leftbox= 0;
-static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction);
+static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, float pixelx, short direction);
static void draw_seq_extensions(Sequence *seq, SpaceSeq *sseq);
static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2);
static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float x2, float y2);
-static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq);
+static void draw_seq_strip(struct Sequence *seq, struct ScrArea *sa, struct SpaceSeq *sseq, int outline_tint, float pixelx);
-static char *give_seqname(Sequence *seq)
-{
- if(seq->type==SEQ_META) return "Meta";
- else if(seq->type==SEQ_IMAGE) return "Image";
- else if(seq->type==SEQ_SCENE) return "Scene";
- else if(seq->type==SEQ_MOVIE) return "Movie";
- else if(seq->type==SEQ_RAM_SOUND) return "Audio (RAM)";
- else if(seq->type==SEQ_HD_SOUND) return "Audio (HD)";
- else if(seq->type<SEQ_EFFECT) return seq->strip->dir;
- else if(seq->type==SEQ_CROSS) return "Cross";
- else if(seq->type==SEQ_GAMCROSS) return "Gamma Cross";
- else if(seq->type==SEQ_ADD) return "Add";
- else if(seq->type==SEQ_SUB) return "Sub";
- else if(seq->type==SEQ_MUL) return "Mul";
- else if(seq->type==SEQ_ALPHAOVER) return "Alpha Over";
- else if(seq->type==SEQ_ALPHAUNDER) return "Alpha Under";
- else if(seq->type==SEQ_OVERDROP) return "Over Drop";
- else if(seq->type==SEQ_WIPE) return "Wipe";
- else if(seq->type==SEQ_GLOW) return "Glow";
- else if(seq->type==SEQ_TRANSFORM) return "Transform";
- else if(seq->type==SEQ_COLOR) return "Color";
- else if(seq->type==SEQ_SPEED) return "Speed";
- else if(seq->type==SEQ_PLUGIN) {
- if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
- seq->plugin && seq->plugin->doit) return seq->plugin->pname;
- return "Plugin";
- }
- else return "Effect";
-
-}
static void draw_cfra_seq(void)
{
glColor3ub(0x30, 0x90, 0x50);
@@ -235,20 +227,26 @@ static void get_seq_color3ubv(Sequence *seq, char *col)
static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, float y2)
{
+ /* Note, this used to use WHILE_SEQ, but it messes up the seq->depth value, (needed by transform when doing overlap checks)
+ * so for now, just use the meta's immediate children, could be fixed but its only drawing - Campbell */
Sequence *seq;
float dx;
int nr;
char col[3];
- nr= 0;
- WHILE_SEQ(&seqm->seqbase) {
- nr++;
- }
- END_SEQ
+ nr= BLI_countlist(&seqm->seqbase);
dx= (x2-x1)/nr;
- WHILE_SEQ(&seqm->seqbase) {
+ if (seqm->flag & SEQ_MUTE) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(halftone);
+
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(1, 0x8888);
+ }
+
+ for (seq= seqm->seqbase.first; seq; seq= seq->next) {
get_seq_color3ubv(seq, col);
glColor3ubv((GLubyte *)col);
@@ -262,7 +260,11 @@ static void drawmeta_contents(Sequence *seqm, float x1, float y1, float x2, floa
x1+= dx;
}
- END_SEQ
+
+ if (seqm->flag & SEQ_MUTE) {
+ glDisable(GL_POLYGON_STIPPLE);
+ glDisable(GL_LINE_STIPPLE);
+ }
}
static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, int winx)
@@ -306,8 +308,8 @@ static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, i
if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
- sofs = ((int)( (((float)(seq->startdisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
- eofs = ((int)( (((float)(seq->enddisp-seq->start))/(float)G.scene->r.frs_sec)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
+ sofs = ((int)( FRA2TIME(seq->startdisp-seq->start)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
+ eofs = ((int)( FRA2TIME(seq->enddisp-seq->start)*(float)G.scene->audio.mixrate*4.0 )) & (~3);
/* clip the drawing area to the screen bounds to save time */
sample_step= (G.v2d->cur.xmax - G.v2d->cur.xmin)/winx;
@@ -368,11 +370,10 @@ static void drawseqwave(Sequence *seq, float x1, float y1, float x2, float y2, i
}
/* draw a handle, for each end of a sequence strip */
-static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction)
+static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, float pixelx, short direction)
{
float v1[2], v2[2], v3[2], rx1=0, rx2=0; //for triangles and rect
float x1, x2, y1, y2;
- float pixelx;
float handsize;
float minhandle, maxhandle;
char str[120];
@@ -386,12 +387,11 @@ static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction)
y2= seq->machine+SEQ_STRIP_OFSTOP;
v2d = &sseq->v2d;
- pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
/* clamp handles to defined size in pixel space */
handsize = seq->handsize;
minhandle = 7;
- maxhandle = 28;
+ maxhandle = 40;
CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
/* set up co-ordinates/dimensions for either left or right handle */
@@ -634,6 +634,11 @@ static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float
{
float ymid1, ymid2;
+ if (seq->flag & SEQ_MUTE) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(halftone);
+ }
+
ymid1 = (y2-y1)*0.25 + y1;
ymid2 = (y2-y1)*0.65 + y1;
@@ -675,6 +680,9 @@ static void draw_shadedstrip(Sequence *seq, char *col, float x1, float y1, float
glEnd();
+ if (seq->flag & SEQ_MUTE) {
+ glDisable(GL_POLYGON_STIPPLE);
+ }
}
/*
@@ -682,12 +690,14 @@ Draw a sequence strip, bounds check alredy made
ScrArea is currently only used to get the windows width in pixels
so wave file sample drawing precission is zoom adjusted
*/
-static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
+static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq, int outline_tint, float pixelx)
{
float x1, x2, y1, y2;
- char col[3];
- Sequence *last_seq = get_last_seq();
+ char col[3], is_single_image;
+ /* we need to know if this is a single image/color or not for drawing */
+ is_single_image = (char)check_single_seq(seq);
+
/* body */
if(seq->startstill) x1= seq->start;
else x1= seq->startdisp;
@@ -701,13 +711,20 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
get_seq_color3ubv(seq, col);
/* draw the main strip body */
- draw_shadedstrip(seq, col, x1, y1, x2, y2);
+ if (is_single_image) /* single image */
+ draw_shadedstrip(seq, col, seq_tx_get_final_left(seq), y1, seq_tx_get_final_right(seq), y2);
+ else /* normal operation */
+ draw_shadedstrip(seq, col, x1, y1, x2, y2);
/* draw additional info and controls */
- if (seq->type == SEQ_RAM_SOUND) drawseqwave(seq, x1, y1, x2, y2, sa->winx);
- draw_seq_extensions(seq, sseq);
- draw_seq_handle(seq, sseq, SEQ_LEFTHANDLE);
- draw_seq_handle(seq, sseq, SEQ_RIGHTHANDLE);
+ if (seq->type == SEQ_RAM_SOUND)
+ drawseqwave(seq, x1, y1, x2, y2, sa->winx);
+
+ if (!is_single_image)
+ draw_seq_extensions(seq, sseq);
+
+ draw_seq_handle(seq, sseq, pixelx, SEQ_LEFTHANDLE);
+ draw_seq_handle(seq, sseq, pixelx, SEQ_RIGHTHANDLE);
/* draw the strip outline */
x1= seq->startdisp;
@@ -719,13 +736,21 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
col[0]= 255; col[1]= col[2]= 40;
} else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
}
- else if (seq == last_seq) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
- else if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -150);
- else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -60);
+ BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, outline_tint);
+
glColor3ubv((GLubyte *)col);
+
+ if (seq->flag & SEQ_MUTE) {
+ glEnable(GL_LINE_STIPPLE);
+ glLineStipple(1, 0x8888);
+ }
+
gl_round_box_shade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
-
+
+ if (seq->flag & SEQ_MUTE) {
+ glDisable(GL_LINE_STIPPLE);
+ }
/* calculate if seq is long enough to print a name */
x1= seq->startdisp+seq->handsize;
@@ -740,10 +765,10 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
if(x2<G.v2d->cur.xmin) x2= G.v2d->cur.xmin;
else if(x2>G.v2d->cur.xmax) x2= G.v2d->cur.xmax;
- if(x1 != x2) {
+ /* nice text here would require changing the view matrix for texture text */
+ if( (x2-x1) / pixelx > 32) {
draw_seq_text(seq, x1, x2, y1, y2);
}
-
}
static Sequence *special_seq_update= 0;
@@ -763,12 +788,12 @@ void set_special_seq_update(int val)
static void draw_image_seq(ScrArea *sa)
{
SpaceSeq *sseq;
- StripElem *se;
struct ImBuf *ibuf;
int x1, y1, rectx, recty;
int free_ibuf = 0;
static int recursive= 0;
float zoom;
+ float zoomx, zoomy;
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -788,7 +813,19 @@ static void draw_image_seq(ScrArea *sa)
return;
else {
recursive= 1;
- ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ if (special_seq_update) {
+ ibuf= give_ibuf_seq_direct(
+ rectx, recty, (G.scene->r.cfra),
+ special_seq_update);
+ } else if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) {
+ ibuf= (ImBuf *)give_ibuf_seq(
+ rectx, recty, (G.scene->r.cfra),
+ sseq->chanshown);
+ } else {
+ ibuf= (ImBuf *)give_ibuf_seq_threaded(
+ rectx, recty, (G.scene->r.cfra),
+ sseq->chanshown);
+ }
recursive= 0;
/* HURMF! the give_ibuf_seq can call image display in this window */
@@ -799,31 +836,40 @@ static void draw_image_seq(ScrArea *sa)
}
}
- if(special_seq_update) {
- se = special_seq_update->curelem;
- if(se) {
- if(se->ok==2) {
- if(se->se1)
- ibuf= se->se1->ibuf;
- }
- else ibuf= se->ibuf;
- }
- }
if(ibuf==NULL)
return;
- if(ibuf->rect_float && ibuf->rect==NULL)
- IMB_rect_from_float(ibuf);
- if(ibuf->rect==NULL)
+
+ if(ibuf->rect==NULL && ibuf->rect_float == NULL)
return;
- if (sseq->mainb == SEQ_DRAW_IMG_WAVEFORM) {
- ibuf = make_waveform_view_from_ibuf(ibuf);
+ switch(sseq->mainb) {
+ case SEQ_DRAW_IMG_IMBUF:
+ if (sseq->zebra != 0) {
+ ibuf = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
+ free_ibuf = 1;
+ }
+ break;
+ case SEQ_DRAW_IMG_WAVEFORM:
+ if ((sseq->flag & SEQ_DRAW_COLOR_SEPERATED) != 0) {
+ ibuf = make_sep_waveform_view_from_ibuf(ibuf);
+ } else {
+ ibuf = make_waveform_view_from_ibuf(ibuf);
+ }
free_ibuf = 1;
- } else if (sseq->mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
+ break;
+ case SEQ_DRAW_IMG_VECTORSCOPE:
ibuf = make_vectorscope_view_from_ibuf(ibuf);
free_ibuf = 1;
+ break;
+ case SEQ_DRAW_IMG_HISTOGRAM:
+ ibuf = make_histogram_view_from_ibuf(ibuf);
+ free_ibuf = 1;
+ break;
}
+ if(ibuf->rect_float && ibuf->rect==NULL)
+ IMB_rect_from_float(ibuf);
+
if (sseq->zoom > 0) {
zoom = sseq->zoom;
} else if (sseq->zoom == 0) {
@@ -838,123 +884,49 @@ static void draw_image_seq(ScrArea *sa)
/* needed for gla draw */
glaDefine2DArea(&curarea->winrct);
- glPixelZoom(zoom, zoom);
+ zoomx = zoom * ((float)G.scene->r.xasp / (float)G.scene->r.yasp);
+ zoomy = zoom;
+
+ glPixelZoom(zoomx, zoomy);
+
glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glPixelZoom(1.0, 1.0);
- if (free_ibuf) {
- IMB_freeImBuf(ibuf);
- }
-
- sa->win_swap= WIN_BACK_OK;
-}
-
-static void draw_extra_seqinfo(void)
-{
- Sequence *last_seq = get_last_seq();
- StripElem *se, *last;
- float xco, xfac;
- int sta, end;
- char str[256];
-
- if(last_seq==0) return;
-
- /* xfac: size of 1 pixel */
- xfac= G.v2d->cur.xmax - G.v2d->cur.xmin;
- xfac/= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
- xco= G.v2d->cur.xmin+40*xfac;
-
- BIF_ThemeColor(TH_TEXT);
-
- /* NAME */
- glRasterPos3f(xco, 0.3, 0.0);
- strncpy(str, give_seqname(last_seq), 255);
- BMF_DrawString(G.font, str);
- xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
-
- if(last_seq->type==SEQ_SCENE && last_seq->scene) {
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, last_seq->scene->id.name+2);
- xco += xfac*BMF_GetStringWidth(G.font, last_seq->scene->id.name+2) +30.0*xfac;
- }
-
- /* LEN */
- if(last_seq->type & SEQ_EFFECT)
- sprintf(str, "len: %d From %d - %d", last_seq->len, last_seq->startdisp, last_seq->enddisp-1);
- else
- sprintf(str, "len: %d (%d)", last_seq->enddisp-last_seq->startdisp, last_seq->len);
-
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
-
- if(last_seq->type==SEQ_IMAGE) {
-
- /* CURRENT */
- se= (StripElem *)give_stripelem(last_seq, (G.scene->r.cfra));
- if(se) {
- sprintf(str, "Cur: %s", se->name);
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
- }
-
- /* FIRST AND LAST */
-
- if(last_seq->strip) {
- se= last_seq->strip->stripdata;
- last= se+last_seq->len-1;
- if(last_seq->startofs) se+= last_seq->startofs;
- if(last_seq->endofs) last-= last_seq->endofs;
-
- sprintf(str, "First: %s at %d Last: %s at %d", se->name, last_seq->startdisp, last->name, last_seq->enddisp-1);
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
-
- /* orig size */
- sprintf(str, "OrigSize: %d x %d", last_seq->strip->orx, last_seq->strip->ory);
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- xco += xfac*BMF_GetStringWidth(G.font, str) +30.0*xfac;
- }
- }
- else if(last_seq->type==SEQ_MOVIE) {
-
- sta= last_seq->startofs;
- end= last_seq->len-1-last_seq->endofs;
+ /* safety border */
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF &&
+ (sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
+ float fac= 0.1;
+ float x2 = x1 + ibuf->x * zoomx;
+ float y2 = y1 + ibuf->y * zoomy;
+
+ float a= fac*(x2-x1);
+ x1+= a;
+ x2-= a;
+
+ a= fac*(y2-y1);
+ y1+= a;
+ y2-= a;
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ setlinestyle(3);
- sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d",
- last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
- sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp);
+ BIF_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0);
+
+ uiSetRoundBox(15);
+ gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- }
- else if(last_seq->type==SEQ_SCENE) {
- se= (StripElem *)give_stripelem(last_seq, (G.scene->r.cfra));
- if(se && last_seq->scene) {
- sprintf(str, "Cur: %d First: %d Last: %d", last_seq->sfra+se->nr, last_seq->sfra, last_seq->sfra+last_seq->len-1);
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- }
+ setlinestyle(0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
- else if(last_seq->type==SEQ_RAM_SOUND
- || last_seq->type == SEQ_HD_SOUND) {
- sta= last_seq->startofs;
- end= last_seq->len-1-last_seq->endofs;
- sprintf(str, "%s %s%s First: %d at %d Last: %d at %d Cur: %d Gain: %.2f dB Pan: %.2f",
- last_seq->name+2, last_seq->strip->dir, last_seq->strip->stripdata->name,
- sta, last_seq->startdisp, end, last_seq->enddisp-1, (G.scene->r.cfra)-last_seq->startdisp,
- last_seq->level, last_seq->pan);
+ if (free_ibuf) {
+ IMB_freeImBuf(ibuf);
+ }
- glRasterPos3f(xco, 0.3, 0.0);
- BMF_DrawString(G.font, str);
- }
+ sa->win_swap= WIN_BACK_OK;
}
void seq_reset_imageofs(SpaceSeq *sseq)
@@ -1011,232 +983,7 @@ void seq_viewmove(SpaceSeq *sseq)
window_set_cursor(win, oldcursor);
}
-#define SEQ_BUT_PLUGIN 1
-#define SEQ_BUT_RELOAD 2
-#define SEQ_BUT_EFFECT 3
-#define SEQ_BUT_RELOAD_ALL 4
-
-void do_seqbuttons(short val)
-{
- Sequence *last_seq = get_last_seq();
-
- switch(val) {
- case SEQ_BUT_PLUGIN:
- case SEQ_BUT_EFFECT:
- update_changed_seq_and_deps(last_seq, 0, 1);
- break;
-
- case SEQ_BUT_RELOAD:
- case SEQ_BUT_RELOAD_ALL:
- update_seq_ipo_rect(last_seq);
- update_seq_icu_rects(last_seq);
-
- free_imbuf_seq(); // frees all
-
- break;
- }
-
- if (val == SEQ_BUT_RELOAD_ALL) {
- allqueue(REDRAWALL, 0);
- } else {
- allqueue(REDRAWSEQ, 0);
- }
-}
-
-static void seq_panel_properties(short cntrl) // SEQ_HANDLER_PROPERTIES
-{
- Sequence *last_seq = get_last_seq();
- uiBlock *block;
-
- block= uiNewBlock(&curarea->uiblocks, "seq_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
- uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
- uiSetPanelHandler(SEQ_HANDLER_PROPERTIES); // for close and esc
- if(uiNewPanel(curarea, block, "Strip Properties", "Seq", 10, 230, 318, 204)==0) return;
-
- if(last_seq==NULL) return;
-
- if(last_seq->type==SEQ_PLUGIN) {
- PluginSeq *pis;
- VarStruct *varstr;
- int a, xco, yco;
-
- get_sequence_effect(last_seq);/* make sure, plugin is loaded */
-
- uiDefBut(block, LABEL, 0, "Type: Plugin", 10,50,70,20, 0, 0, 0, 0, 0, "");
-
- pis= last_seq->plugin;
- if(pis->vars==0) return;
-
- varstr= pis->varstr;
- if(varstr) {
- for(a=0; a<pis->vars; a++, varstr++) {
- xco= 150*(a/6)+10;
- yco= 125 - 20*(a % 6)+1;
- uiDefBut(block, varstr->type, SEQ_BUT_PLUGIN, varstr->name, xco,yco,150,19, &(pis->data[a]), varstr->min, varstr->max, 100, 0, varstr->tip);
-
- }
- }
- uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
- SEQ_BUT_RELOAD_ALL, "IPO Frame locked",
- 10,-40,150,19, &last_seq->flag,
- 0.0, 1.0, 0, 0,
- "Lock the IPO coordinates to the "
- "global frame counter.");
-
- }
- else if(last_seq->type==SEQ_IMAGE) {
-
- uiDefBut(block, LABEL, 0, "Type: Image", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
-
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Convert to Premul", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
- uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY", 10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", 10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
- uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", 10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame");
- uiBlockEndAlign(block);
- }
- else if(last_seq->type==SEQ_META) {
-
- uiDefBut(block, LABEL, 0, "Type: Meta", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
-
- }
- else if(last_seq->type==SEQ_SCENE) {
-
- uiDefBut(block, LABEL, 0, "Type: Scene", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
- uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
- }
- else if(last_seq->type==SEQ_MOVIE) {
-
- if(last_seq->mul==0.0) last_seq->mul= 1.0;
-
- uiDefBut(block, LABEL, 0, "Type: Movie", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
-
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, SEQ_MAKE_PREMUL, SEQ_BUT_RELOAD, "Make Premul Alpha ", 10,90,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Converts RGB values to become premultiplied with Alpha");
- uiDefButBitS(block, TOG, SEQ_FILTERY, SEQ_BUT_RELOAD, "FilterY ", 10,70,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "For video movies to remove fields");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Mul:", 10,50,150,19, &last_seq->mul, 0.001, 5.0, 100, 0, "Multiply colors");
-
- uiDefButS(block, TOG|BIT|7, SEQ_BUT_RELOAD, "Reverse Frames", 10,30,150,19, &last_seq->flag, 0.0, 21.0, 100, 0, "Reverse frame order");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Strobe:", 10,10,150,19, &last_seq->strobe, 1.0, 30.0, 100, 0, "Only display every nth frame");
- uiDefButI(block, NUM, SEQ_BUT_RELOAD, "Preseek:", 10,-10,150,19, &last_seq->anim_preseek, 0.0, 50.0, 100, 0, "On MPEG-seeking preseek this many frames");
- uiBlockEndAlign(block);
- }
- else if(last_seq->type==SEQ_RAM_SOUND ||
- last_seq->type==SEQ_HD_SOUND) {
- uiDefBut(block, LABEL, 0, "Type: Audio", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, 0, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
-
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
- SEQ_BUT_RELOAD_ALL, "IPO Frame locked",
- 10,90,150,19, &last_seq->flag,
- 0.0, 1.0, 0, 0,
- "Lock the IPO coordinates to the "
- "global frame counter.");
-
- uiDefButBitS(block, TOG, SEQ_MUTE, B_NOP, "Mute", 10,70,120,19, &last_seq->flag, 0.0, 21.0, 100, 0, "");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Gain (dB):", 10,50,150,19, &last_seq->level, -96.0, 6.0, 100, 0, "");
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Pan:", 10,30,150,19, &last_seq->pan, -1.0, 1.0, 100, 0, "");
- uiBlockEndAlign(block);
- }
- else if(last_seq->type>=SEQ_EFFECT) {
- uiDefBut(block, LABEL, 0, "Type: Effect", 10,140,150,20, 0, 0, 0, 0, 0, "");
- uiDefBut(block, TEX, B_NOP, "Name: ", 10,120,150,19, last_seq->name+2, 0.0, 21.0, 100, 0, "");
-
- uiDefButBitS(block, TOG, SEQ_IPO_FRAME_LOCKED,
- SEQ_BUT_RELOAD_ALL, "IPO Frame locked",
- 10,90,150,19, &last_seq->flag,
- 0.0, 1.0, 0, 0,
- "Lock the IPO coordinates to the "
- "global frame counter.");
-
- uiBlockBeginAlign(block);
- if(last_seq->type==SEQ_WIPE){
- WipeVars *wipe = (WipeVars *)last_seq->effectdata;
- char formatstring[256];
-
- strncpy(formatstring, "Transition Type %t|Single Wipe%x0|Double Wipe %x1|Iris Wipe %x4|Clock Wipe %x5", 255);
- uiDefButS(block, MENU,SEQ_BUT_EFFECT, formatstring, 10,65,220,22, &wipe->wipetype, 0, 0, 0, 0, "What type of wipe should be performed");
- uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Blur:", 10,40,220,22, &wipe->edgeWidth,0.0,1.0, 1, 2, "The percent width of the blur edge");
- switch(wipe->wipetype){ /*Skip Types that do not require angle*/
- case DO_IRIS_WIPE:
- case DO_CLOCK_WIPE:
- break;
-
- default:
- uiDefButF(block, NUM,SEQ_BUT_EFFECT,"Angle:", 10,15,220,22, &wipe->angle,-90.0,90.0, 1, 2, "The Angle of the Edge");
- }
- uiDefButS(block, TOG,SEQ_BUT_EFFECT,"Wipe In", 10,-10,220,22, &wipe->forward,0,0, 0, 0, "Controls Primary Direction of Wipe");
- }
- else if(last_seq->type==SEQ_GLOW){
- GlowVars *glow = (GlowVars *)last_seq->effectdata;
-
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Threshold:", 10,70,150,19, &glow->fMini, 0.0, 1.0, 0, 0, "Trigger Intensity");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Clamp:", 10,50,150,19, &glow->fClamp, 0.0, 1.0, 0, 0, "Brightness limit of intensity");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Boost factor:", 10,30,150,19, &glow->fBoost, 0.0, 10.0, 0, 0, "Brightness multiplier");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "Blur distance:", 10,10,150,19, &glow->dDist, 0.5, 20.0, 0, 0, "Radius of glow effect");
- uiDefButI(block, NUM, B_NOP, "Quality:", 10,-5,150,19, &glow->dQuality, 1.0, 5.0, 0, 0, "Accuracy of the blur effect");
- uiDefButI(block, TOG, B_NOP, "Only boost", 10,-25,150,19, &glow->bNoComp, 0.0, 0.0, 0, 0, "Show the glow buffer only");
- }
- else if(last_seq->type==SEQ_TRANSFORM){
- TransformVars *transform = (TransformVars *)last_seq->effectdata;
-
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale Start:", 10,70,150,19, &transform->ScalexIni, 0.0, 10.0, 0, 0, "X Scale Start");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "xScale End:", 160,70,150,19, &transform->ScalexFin, 0.0, 10.0, 0, 0, "X Scale End");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale Start:", 10,50,150,19, &transform->ScaleyIni, 0.0, 10.0, 0, 0, "Y Scale Start");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "yScale End:", 160,50,150,19, &transform->ScaleyFin, 0.0, 10.0, 0, 0, "Y Scale End");
-
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x Start:", 10,30,150,19, &transform->xIni, -1000.0, 1000.0, 0, 0, "X Position Start");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "x End:", 160,30,150,19, &transform->xFin, -1000.0, 1000.0, 0, 0, "X Position End");
-
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y Start:", 10,10,150,19, &transform->yIni, -1000.0, 1000.0, 0, 0, "Y Position Start");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "y End:", 160,10,150,19, &transform->yFin, -1000.0, 1000.0, 0, 0, "Y Position End");
-
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot Start:",10,-10,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start");
- uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot End:",160,-10,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End");
- } else if(last_seq->type==SEQ_COLOR) {
- SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata;
- uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, "");
- } else if(last_seq->type==SEQ_SPEED){
- SpeedControlVars *sp =
- (SpeedControlVars *)last_seq->effectdata;
-
- uiDefButF(block, NUM, SEQ_BUT_RELOAD, "Global Speed:", 10,70,150,19, &sp->globalSpeed, 0.0, 100.0, 0, 0, "Global Speed");
-
- uiDefButBitI(block, TOG, SEQ_SPEED_INTEGRATE,
- SEQ_BUT_RELOAD,
- "IPO is velocity",
- 10,50,150,19, &sp->flags,
- 0.0, 1.0, 0, 0,
- "Interpret the IPO value as a "
- "velocity instead of a frame number");
-
- uiDefButBitI(block, TOG, SEQ_SPEED_BLEND,
- SEQ_BUT_RELOAD,
- "Enable frame blending",
- 10,30,150,19, &sp->flags,
- 0.0, 1.0, 0, 0,
- "Blend two frames into the "
- "target for a smoother result");
-
- uiDefButBitI(block, TOG, SEQ_SPEED_COMPRESS_IPO_Y,
- SEQ_BUT_RELOAD,
- "IPO value runs from [0..1]",
- 10,10,150,19, &sp->flags,
- 0.0, 1.0, 0, 0,
- "Scale IPO value to get the "
- "target frame number.");
- }
-
- uiBlockEndAlign(block);
- }
-}
static void seq_blockhandlers(ScrArea *sa)
{
@@ -1247,13 +994,6 @@ static void seq_blockhandlers(ScrArea *sa)
uiFreeBlocksWin(&sa->uiblocks, sa->win);
for(a=0; a<SPACE_MAXHANDLER; a+=2) {
- switch(sseq->blockhandler[a]) {
-
- case SEQ_HANDLER_PROPERTIES:
- seq_panel_properties(sseq->blockhandler[a+1]);
- break;
-
- }
/* clear action value for event */
sseq->blockhandler[a+1]= 0;
}
@@ -1261,6 +1001,20 @@ static void seq_blockhandlers(ScrArea *sa)
}
+void drawprefetchseqspace(ScrArea *sa, void *spacedata)
+{
+ SpaceSeq *sseq= sa->spacedata.first;
+ int rectx, recty;
+
+ rectx= (G.scene->r.size*G.scene->r.xsch)/100;
+ recty= (G.scene->r.size*G.scene->r.ysch)/100;
+
+ if(sseq->mainb) {
+ give_ibuf_prefetch_request(
+ rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+ }
+}
+
void drawseqspace(ScrArea *sa, void *spacedata)
{
SpaceSeq *sseq= sa->spacedata.first;
@@ -1308,6 +1062,7 @@ void drawseqspace(ScrArea *sa, void *spacedata)
boundbox_seq();
calc_ipogrid();
+ /* Alternating horizontal stripes */
i= MAX2(1, ((int)G.v2d->cur.ymin)-1);
glBegin(GL_QUADS);
@@ -1344,41 +1099,41 @@ void drawseqspace(ScrArea *sa, void *spacedata)
/* sequences: first deselect */
if(ed) {
- seq= ed->seqbasep->first;
- while(seq) { /* bound box test, dont draw outside the view */
- if (seq->flag & SELECT ||
- MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
- MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
- seq->machine+1.0 < v2d->cur.ymin ||
- seq->machine > v2d->cur.ymax)
- {
- /* dont draw */
- } else {
- draw_seq_strip(seq, sa, sseq);
+ Sequence *last_seq = get_last_seq();
+ int sel = 0, j;
+ int outline_tint;
+ float pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
+ /* loop through twice, first unselected, then selected */
+ for (j=0; j<2; j++) {
+ seq= ed->seqbasep->first;
+ if (j==0) outline_tint = -150;
+ else outline_tint = -60;
+
+ while(seq) { /* bound box test, dont draw outside the view */
+ if ( ((seq->flag & SELECT) == sel) ||
+ seq == last_seq ||
+ MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
+ MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
+ seq->machine+1.0 < v2d->cur.ymin ||
+ seq->machine > v2d->cur.ymax)
+ {
+ /* dont draw */
+ } else {
+ draw_seq_strip(seq, sa, sseq, outline_tint, pixelx);
+ }
+ seq= seq->next;
}
- seq= seq->next;
+ sel= SELECT; /* draw selected next time round */
}
- }
- ed= G.scene->ed;
- if(ed) {
- seq= ed->seqbasep->first;
- while(seq) { /* bound box test, dont draw outside the view */
- if (!(seq->flag & SELECT) ||
- MIN2(seq->startdisp, seq->start) > v2d->cur.xmax ||
- MAX2(seq->enddisp, seq->start+seq->len) < v2d->cur.xmin ||
- seq->machine+1.0 < v2d->cur.ymin ||
- seq->machine > v2d->cur.ymax)
- {
- /* dont draw */
- } else {
- draw_seq_strip(seq, sa, sseq);
- }
- seq= seq->next;
+ /* draw the last selected last, removes some overlapping error */
+ if (last_seq) {
+ draw_seq_strip(last_seq, sa, sseq, 120, pixelx);
}
}
- draw_extra_seqinfo();
-
+ /* Draw markers */
+ draw_markers_timespace(SCE_MARKERS, DRAW_MARKERS_LINES);
+
/* restore viewport */
mywinset(sa->win);
diff --git a/source/blender/src/drawsound.c b/source/blender/src/drawsound.c
index 1fe10bf2c17..4fff327c5bb 100644
--- a/source/blender/src/drawsound.c
+++ b/source/blender/src/drawsound.c
@@ -58,6 +58,8 @@
#include "BSE_time.h"
#include "BMF_Api.h"
+#include "blendef.h"
+
/* local */
void drawsoundspace(ScrArea *sa, void *spacedata);
@@ -99,7 +101,7 @@ static void draw_sample(bSample *sample)
short *sp, sampdx;
/* one sample is where in v2d space? (v2d space in frames!) */
- sampfac= ((float)G.scene->r.frs_sec)/(sample->rate);
+ sampfac= FPS/(sample->rate);
/* how many samples? */
samples= sample->len/(sample->channels*(sample->bits/8));
@@ -161,8 +163,8 @@ static void draw_cfra_sound(SpaceSound *ssound)
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
if(ssound->flag & SND_DRAWFRAMES)
- sprintf(str, " %d\n", (G.scene->r.cfra));
- else sprintf(str, " %.2f\n", (G.scene->r.cfra/(float)G.scene->r.frs_sec));
+ sprintf(str, " %d\n", CFRA);
+ else sprintf(str, " %.2f\n", FRA2TIME(CFRA));
glRasterPos2f(x, y);
glColor3ub(0, 0, 0);
@@ -174,8 +176,8 @@ static void draw_cfra_sound(SpaceSound *ssound)
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
- glColor3ub(0x20, 0x90, 0x20);
- glLineWidth(4.0);
+ BIF_ThemeColor(TH_CFRAME);
+ glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
glVertex2fv(vec);
@@ -184,7 +186,6 @@ static void draw_cfra_sound(SpaceSound *ssound)
glEnd();
glLineWidth(1.0);
-
}
void drawsoundspace(ScrArea *sa, void *spacedata)
@@ -219,7 +220,7 @@ void drawsoundspace(ScrArea *sa, void *spacedata)
}
draw_cfra_sound(spacedata);
- draw_markers_timespace();
+ draw_markers_timespace(SCE_MARKERS, 0);
/* restore viewport */
mywinset(curarea->win);
diff --git a/source/blender/src/drawtext.c b/source/blender/src/drawtext.c
index 1ea29886850..8ef18ee954e 100644
--- a/source/blender/src/drawtext.c
+++ b/source/blender/src/drawtext.c
@@ -62,6 +62,7 @@
#include "BKE_text.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_node.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -83,6 +84,7 @@
#include "mydevice.h"
#include "blendef.h"
+#include "winlay.h"
#define TEXTXLOC 38
@@ -91,10 +93,9 @@
void drawtextspace(ScrArea *sa, void *spacedata);
void winqreadtextspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
void txt_copy_selectbuffer (Text *text);
-void txt_paste_clipboard(Text *text); /* blank on non Win32 */
-void txt_copy_clipboard(Text *text); /* blank on non Win32 */
void do_brackets();
+void get_selection_buffer(Text *text);
int check_bracket(char *string);
static int check_delim(char *string);
static int check_numbers(char *string);
@@ -167,15 +168,13 @@ void free_txt_data(void) {
if (temp_char_accum) MEM_freeN(temp_char_accum);
}
-static int render_string (char *in) {
- SpaceText *st= curarea->spacedata.first;
+static int render_string (SpaceText *st, char *in) {
int r = 0, i = 0;
while(*in) {
if (*in=='\t') {
if (temp_char_pos && *(in-1)=='\t') i= st->tabnumber;
else if (st->tabnumber > 0) i= st->tabnumber - (temp_char_pos%st->tabnumber);
-
while(i--) temp_char_write(' ', r);
} else temp_char_write(*in, r);
@@ -188,9 +187,8 @@ static int render_string (char *in) {
return r;
}
-void get_format_string(void)
+void get_format_string(SpaceText *st)
{
- SpaceText *st = curarea->spacedata.first;
Text *text = st->text;
TextLine *tmp;
char *in_line;
@@ -538,7 +536,7 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra
char *in;
int *acc;
- w= render_string(str);
+ w= render_string(st, str);
if(w<cshift ) return 0; /* String is shorter than shift */
in= temp_char_buf+cshift;
@@ -630,7 +628,7 @@ static void set_cursor_to_pos (SpaceText *st, int x, int y, int sel)
if (x<0) x= 0;
x = (x/spacetext_get_fontwidth(st)) + st->left;
- w= render_string((*linep)->line);
+ w= render_string(st, (*linep)->line);
if(x<w) *charp= temp_char_accum[x];
else *charp= (*linep)->len;
@@ -725,45 +723,106 @@ static void draw_cursor(SpaceText *st) {
static void calc_text_rcts(SpaceText *st)
{
- short barheight, barstart;
- int lbarstart, lbarh, ltexth;
-
- lbarstart= st->top;
- lbarh= st->viewlines;
- ltexth= txt_get_span(st->text->lines.first, st->text->lines.last)+1;
-
- barheight= (lbarh*(curarea->winy-4))/ltexth;
- if (barheight<20) barheight=20;
+ int lhlstart, lhlend, ltexth;
+ short barheight, barstart, hlstart, hlend, blank_lines;
+ short pix_available, pix_top_margin, pix_bottom_margin, pix_bardiff;
+
+ pix_top_margin = 8;
+ pix_bottom_margin = 4;
+ pix_available = curarea->winy - pix_top_margin - pix_bottom_margin;
+ ltexth= txt_get_span(st->text->lines.first, st->text->lines.last);
+ blank_lines = st->viewlines / 2;
+
+ /* when resizing a vieport with the bar at the bottom to a greater height more blank lines will be added */
+ if (ltexth + blank_lines < st->top + st->viewlines) {
+ blank_lines = st->top + st->viewlines - ltexth;
+ }
- barstart= (lbarstart*(curarea->winy-4))/ltexth + 8;
+ ltexth += blank_lines;
+
+ barheight = (ltexth > 0)? (st->viewlines*pix_available)/ltexth: 0;
+ pix_bardiff = 0;
+ if (barheight < 20) {
+ pix_bardiff = 20 - barheight; /* take into account the now non-linear sizing of the bar */
+ barheight = 20;
+ }
+ barstart = (ltexth > 0)? ((pix_available - pix_bardiff) * st->top)/ltexth: 0;
- st->txtbar.xmin= 5;
- st->txtbar.xmax= 17;
- st->txtbar.ymax= curarea->winy - barstart;
- st->txtbar.ymin= st->txtbar.ymax - barheight;
+ st->txtbar.xmin = 5;
+ st->txtbar.xmax = 17;
+ st->txtbar.ymax = curarea->winy - pix_top_margin - barstart;
+ st->txtbar.ymin = st->txtbar.ymax - barheight;
- CLAMP(st->txtbar.ymin, 2, curarea->winy-2);
- CLAMP(st->txtbar.ymax, 2, curarea->winy-2);
+ CLAMP(st->txtbar.ymin, pix_bottom_margin, curarea->winy - pix_top_margin);
+ CLAMP(st->txtbar.ymax, pix_bottom_margin, curarea->winy - pix_top_margin);
- st->pix_per_line= (float) ltexth/curarea->winy;
+ st->pix_per_line= (pix_available > 0)? (float) ltexth/pix_available: 0;
if (st->pix_per_line<.1) st->pix_per_line=.1f;
- lbarstart= MIN2(txt_get_span(st->text->lines.first, st->text->curl),
+ lhlstart = MIN2(txt_get_span(st->text->lines.first, st->text->curl),
txt_get_span(st->text->lines.first, st->text->sell));
- lbarh= abs(txt_get_span(st->text->lines.first, st->text->curl)-txt_get_span(st->text->lines.first, st->text->sell));
-
- barheight= (lbarh*(curarea->winy-4))/ltexth;
- if (barheight<2) barheight=2;
-
- barstart= (lbarstart*(curarea->winy-4))/ltexth + 8;
+ lhlend = MAX2(txt_get_span(st->text->lines.first, st->text->curl),
+ txt_get_span(st->text->lines.first, st->text->sell));
+
+ if(ltexth > 0) {
+ hlstart = (lhlstart * pix_available)/ltexth;
+ hlend = (lhlend * pix_available)/ltexth;
+
+ /* the scrollbar is non-linear sized */
+ if (pix_bardiff > 0) {
+ /* the start of the highlight is in the current viewport */
+ if (lhlstart >= st->top && lhlstart <= st->top + st->viewlines) {
+ /* speed the progresion of the start of the highlight through the scrollbar */
+ hlstart = ( ( (pix_available - pix_bardiff) * lhlstart) / ltexth) + (pix_bardiff * (lhlstart - st->top) / st->viewlines);
+ }
+ else if (lhlstart > st->top + st->viewlines && hlstart < barstart + barheight && hlstart > barstart) {
+ /* push hl start down */
+ hlstart = barstart + barheight;
+ }
+ else if (lhlend > st->top && lhlstart < st->top && hlstart > barstart) {
+ /*fill out start */
+ hlstart = barstart;
+ }
+
+ if (hlend <= hlstart) {
+ hlend = hlstart + 2;
+ }
+
+ /* the end of the highlight is in the current viewport */
+ if (lhlend >= st->top && lhlend <= st->top + st->viewlines) {
+ /* speed the progresion of the end of the highlight through the scrollbar */
+ hlend = (((pix_available - pix_bardiff )*lhlend)/ltexth) + (pix_bardiff * (lhlend - st->top)/st->viewlines);
+ }
+ else if (lhlend < st->top && hlend >= barstart - 2 && hlend < barstart + barheight) {
+ /* push hl end up */
+ hlend = barstart;
+ }
+ else if (lhlend > st->top + st->viewlines && lhlstart < st->top + st->viewlines && hlend < barstart + barheight) {
+ /* fill out end */
+ hlend = barstart + barheight;
+ }
+
+ if (hlend <= hlstart) {
+ hlstart = hlend - 2;
+ }
+ }
+ }
+ else {
+ hlstart = 0;
+ hlend = 0;
+ }
+
+ if (hlend - hlstart < 2) {
+ hlend = hlstart + 2;
+ }
st->txtscroll.xmin= 5;
st->txtscroll.xmax= 17;
- st->txtscroll.ymax= curarea->winy-barstart;
- st->txtscroll.ymin= st->txtscroll.ymax - barheight;
+ st->txtscroll.ymax= curarea->winy - pix_top_margin - hlstart;
+ st->txtscroll.ymin= curarea->winy - pix_top_margin - hlend;
- CLAMP(st->txtscroll.ymin, 2, curarea->winy-2);
- CLAMP(st->txtscroll.ymax, 2, curarea->winy-2);
+ CLAMP(st->txtscroll.ymin, pix_bottom_margin, curarea->winy - pix_top_margin);
+ CLAMP(st->txtscroll.ymax, pix_bottom_margin, curarea->winy - pix_top_margin);
}
static void draw_textscroll(SpaceText *st)
@@ -941,6 +1000,8 @@ void drawtextspace(ScrArea *sa, void *spacedata)
float col[3];
int linecount = 0;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
BIF_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -975,13 +1036,18 @@ void drawtextspace(ScrArea *sa, void *spacedata)
if(st->showsyntax) {
if (tmp && !tmp->format) {
- get_format_string();
+ get_format_string(st);
}
}
for (i=0; i<st->viewlines && tmp; i++, tmp= tmp->next) {
if(st->showlinenrs) {
- BIF_ThemeColor(TH_TEXT);
+ /*Change the color of the current line the cursor is on*/
+ if(tmp == text->curl) {
+ BIF_ThemeColor(TH_HILITE);
+ } else {
+ BIF_ThemeColor(TH_TEXT);
+ }
if(((float)(i + linecount + 1)/10000.0) < 1.0) {
sprintf(linenr, "%4d", i + linecount + 1);
glRasterPos2i(TXT_OFFSET - 7, curarea->winy-st->lheight*(i+1));
@@ -989,6 +1055,7 @@ void drawtextspace(ScrArea *sa, void *spacedata)
sprintf(linenr, "%5d", i + linecount + 1);
glRasterPos2i(TXT_OFFSET - 11, curarea->winy-st->lheight*(i+1));
}
+ BIF_ThemeColor(TH_TEXT);
BMF_DrawString(spacetext_get_font(st), linenr);
text_draw(st, tmp->line, st->left, 0, 1, TXT_OFFSET + TEXTXLOC, curarea->winy-st->lheight*(i+1), tmp->format);
} else
@@ -1025,13 +1092,12 @@ void pop_space_text (SpaceText *st)
if (st->left <0) st->left= 0;
}
-void add_text_fs(char *file)
+void add_text_fs(char *file) /* bad but cant pass an as arg here */
{
SpaceText *st= curarea->spacedata.first;
Text *text;
- if (!st) return;
- if (st->spacetype != SPACE_TEXT) return;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
text= add_text(file);
@@ -1039,7 +1105,7 @@ void add_text_fs(char *file)
st->top= 0;
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
allqueue(REDRAWTEXT, 0);
allqueue(REDRAWHEADERS, 0);
}
@@ -1127,6 +1193,10 @@ void unlink_text(Text *text)
if (BPY_check_all_scriptlinks (text)) {
allqueue(REDRAWBUTSSCRIPT, 0);
}
+ /* equivalently for pynodes: */
+ if (nodeDynamicUnlinkText ((ID*)text)) {
+ allqueue(REDRAWNODE, 0);
+ }
for (scr= G.main->screen.first; scr; scr= scr->id.next) {
for (area= scr->areabase.first; area; area= area->next) {
@@ -1248,8 +1318,6 @@ void txt_copy_selectbuffer (Text *text)
bufferlength = length;
}
-
-#ifdef _WIN32
static char *unixNewLine(char *buffer)
{
char *p, *p2, *output;
@@ -1282,55 +1350,42 @@ static char *winNewLine(char *buffer)
return(output);
}
-#endif
-
void txt_paste_clipboard(Text *text) {
-#ifdef _WIN32
- char * buffer = NULL;
-
- if ( OpenClipboard(NULL) ) {
- HANDLE hData = GetClipboardData( CF_TEXT );
- buffer = (char*)GlobalLock( hData );
- if (buffer) {
- buffer = unixNewLine(buffer);
- if (buffer) txt_insert_buf(text, buffer);
- }
- GlobalUnlock( hData );
- CloseClipboard();
- MEM_freeN(buffer);
+
+ char * buff;
+ char *temp_buff;
+
+ buff = (char*)getClipboard(0);
+ if(buff) {
+ temp_buff = unixNewLine(buff);
+
+ txt_insert_buf(text, temp_buff);
+ if(buff){free((void*)buff);}
+ if(temp_buff){MEM_freeN(temp_buff);}
}
-#endif
}
-void txt_copy_clipboard(Text *text) {
-#ifdef _WIN32
- txt_copy_selectbuffer(text);
-
- if (OpenClipboard(NULL)) {
- HLOCAL clipbuffer;
- char* buffer;
-
- if (copybuffer) {
- copybuffer = winNewLine(copybuffer);
+void get_selection_buffer(Text *text)
+{
+ char *buff = getClipboard(1);
+ txt_insert_buf(text, buff);
+}
- EmptyClipboard();
- clipbuffer = LocalAlloc(LMEM_FIXED,((bufferlength+1)));
- buffer = (char *) LocalLock(clipbuffer);
+void txt_copy_clipboard(Text *text) {
+ char *temp;
- strncpy(buffer, copybuffer, bufferlength);
- buffer[bufferlength] = '\0';
- LocalUnlock(clipbuffer);
- SetClipboardData(CF_TEXT,clipbuffer);
- }
- CloseClipboard();
- }
+ txt_copy_selectbuffer(text);
if (copybuffer) {
+ copybuffer[bufferlength] = '\0';
+ temp = winNewLine(copybuffer);
+
+ putClipboard(temp, 0);
+ MEM_freeN(temp);
MEM_freeN(copybuffer);
copybuffer= NULL;
}
-#endif
}
/*
@@ -1411,9 +1466,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
short val= evt->val;
char ascii= evt->ascii;
SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ Text *text;
int do_draw=0, p;
-
+
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
/* smartass code to prevent the CTRL/ALT events below from not working! */
if(G.qual & (LR_ALTKEY|LR_CTRLKEY))
if(!ispunct(ascii))
@@ -1477,19 +1534,34 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (event==LEFTMOUSE) {
if (val) {
short mval[2];
+ char *buffer;
set_tabs(text);
getmouseco_areawin(mval);
-
+
if (mval[0]>2 && mval[0]<20 && mval[1]>2 && mval[1]<curarea->winy-2) {
do_textscroll(st, 2);
- } else {
+ } else {
do_selection(st, G.qual&LR_SHIFTKEY);
+ if (txt_has_sel(text)) {
+ buffer = txt_sel_to_buf(text);
+ putClipboard(buffer, 1);
+ MEM_freeN(buffer);
+ }
do_draw= 1;
}
}
} else if (event==MIDDLEMOUSE) {
if (val) {
- do_textscroll(st, 1);
+ if (U.uiflag & USER_MMB_PASTE)
+ {
+ do_selection(st, G.qual&LR_SHIFTKEY);
+ get_selection_buffer(text);
+ do_draw= 1;
+ }
+ else
+ {
+ do_textscroll(st, 1);
+ }
}
} else if (event==RIGHTMOUSE) {
if (val) {
@@ -1525,7 +1597,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
} else if (ascii) {
if (txt_add_char(text, ascii)) {
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
pop_space_text(st);
do_draw= 1;
}
@@ -1546,7 +1618,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(G.qual & LR_SHIFTKEY)
txt_copy_clipboard(text);
else
- txt_copy_sel(text);
+ txt_copy_clipboard(text);
do_draw= 1;
}
@@ -1557,11 +1629,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
txt_order_cursors(text);
uncomment(text);
do_draw = 1;
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
break;
} else if (G.qual == LR_CTRLKEY) {
txt_delete_char(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
}
@@ -1570,16 +1642,19 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (G.qual == (LR_ALTKEY|LR_SHIFTKEY)) {
switch(pupmenu("Edit %t|Cut %x0|Copy %x1|Paste %x2|Print Cut Buffer %x3")) {
case 0:
+ txt_copy_clipboard(text); //First copy to clipboard
txt_cut_sel(text);
do_draw= 1;
break;
case 1:
- txt_copy_sel(text);
+ txt_copy_clipboard(text);
+ //txt_copy_sel(text);
do_draw= 1;
break;
case 2:
- txt_paste(text);
- if (st->showsyntax) get_format_string();
+ //txt_paste(text);
+ txt_paste_clipboard(text);
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
break;
case 3:
@@ -1667,7 +1742,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (okee("Reopen text")) {
if (!reopen_text(text))
error("Could not reopen file");
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
}
do_draw= 1;
}
@@ -1711,7 +1786,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
if (G.qual == LR_ALTKEY) {
txt_do_undo(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
}
break; /* BREAK U */
@@ -1744,8 +1819,8 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (G.qual & LR_SHIFTKEY)
txt_paste_clipboard(text);
else
- txt_paste(text);
- if (st->showsyntax) get_format_string();
+ txt_paste_clipboard(text);
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
}
@@ -1753,7 +1828,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case XKEY:
if (G.qual == LR_ALTKEY || G.qual == LR_CTRLKEY) {
txt_cut_sel(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
}
@@ -1765,7 +1840,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
} else {
txt_do_undo(text);
}
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
}
break;
@@ -1784,7 +1859,7 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
txt_add_char(text, '\t');
}
}
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
pop_space_text(st);
do_draw= 1;
st->currtab_set = setcurr_tab(text);
@@ -1803,20 +1878,20 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
}
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
break;
case BACKSPACEKEY:
txt_backspace_char(text);
set_tabs(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
break;
case DELKEY:
txt_delete_char(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
do_draw= 1;
pop_space_text(st);
st->currtab_set = setcurr_tab(text);
@@ -2083,18 +2158,18 @@ void convert_tabs (struct SpaceText *st, int tab)
//first convert to all space, this make it alot easier to convert to tabs because there is no mixtures of ' ' && '\t'
while(tmp) {
check_line = tmp->line;
- new_line = MEM_mallocN(render_string(check_line)+1, "Converted_Line");
- format = MEM_mallocN(render_string(check_line)+1, "Converted_Syntax_format");
+ new_line = MEM_mallocN(render_string(st, check_line)+1, "Converted_Line");
+ format = MEM_mallocN(render_string(st, check_line)+1, "Converted_Syntax_format");
j = 0;
for (a=0; a < strlen(check_line); a++) { //foreach char in line
if(check_line[a] == '\t') { //checking for tabs
//get the number of spaces this tabs is showing
//i dont like doing it this way but will look into it later
new_line[j] = '\0';
- number = render_string(new_line);
+ number = render_string(st, new_line);
new_line[j] = '\t';
new_line[j+1] = '\0';
- number = render_string(new_line)-number;
+ number = render_string(st, new_line)-number;
for(extra = 0; extra < number; extra++) {
new_line[j] = ' ';
j++;
diff --git a/source/blender/src/drawtime.c b/source/blender/src/drawtime.c
index 9b9cba4dc98..039184a0e43 100644
--- a/source/blender/src/drawtime.c
+++ b/source/blender/src/drawtime.c
@@ -39,6 +39,7 @@
#include "BLI_arithb.h"
#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_object_types.h"
#include "DNA_material_types.h"
@@ -54,22 +55,38 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
+#include "BIF_editaction.h"
#include "BIF_gl.h"
+#include "BIF_interface.h"
#include "BIF_interface_icons.h"
#include "BIF_mywindow.h"
#include "BIF_screen.h"
#include "BIF_resources.h"
+#include "BIF_language.h"
#include "BSE_drawipo.h"
+#include "BSE_time.h"
#include "BSE_view.h"
-#include "BMF_Api.h"
#include "blendef.h"
+#include "interface.h" /* for ui_rasterpos_safe */
+
+#define TIMELINE_STIPPLE \
+{ \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0, \
+ 136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0 \
+}
/* ---- prototypes ------ */
void drawtimespace(ScrArea *, void *);
-
+/* draws a current frame indicator for the TimeLine */
static void draw_cfra_time(SpaceTime *stime)
{
float vec[2];
@@ -78,7 +95,7 @@ static void draw_cfra_time(SpaceTime *stime)
vec[0]*= G.scene->r.framelen;
vec[1]= G.v2d->cur.ymin;
- glColor3ub(0x60, 0xc0, 0x40); // no theme, should be global color once...
+ BIF_ThemeColor(TH_CFRAME); // no theme, should be global color once...
glLineWidth(3.0);
glBegin(GL_LINES);
@@ -92,8 +109,10 @@ static void draw_cfra_time(SpaceTime *stime)
if(stime->flag & TIME_CFRA_NUM) {
short mval[2];
float x, y;
+ float xscale, yscale;
char str[32];
- /* little box with frame */
+
+ /* little box with frame drawn beside */
glFlush(); // huhh... without this glColor won't work for the text...
getmouseco_areawin(mval);
@@ -107,81 +126,112 @@ static void draw_cfra_time(SpaceTime *stime)
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
if(stime->flag & TIME_DRAWFRAMES)
- sprintf(str, " %d\n", (G.scene->r.cfra));
- else sprintf(str, " %.2f\n", (G.scene->r.cfra/(float)G.scene->r.frs_sec));
+ sprintf(str, " %d", CFRA);
+ else sprintf(str, " %.2f", FRA2TIME(CFRA));
/* HACK! somehow the green color won't go away... */
glColor4ub(0, 0, 0, 0);
BIF_ThemeColor(TH_TEXT);
- glRasterPos2f(x, y);
- BMF_DrawString(G.fonts, str);
+ view2d_getscale(G.v2d, &xscale, &yscale);
+
+ /* because the frame number text is subject to the same scaling as the contents of the view */
+ glScalef( 1.0/xscale, 1.0/yscale, 1.0);
+ ui_rasterpos_safe(x * xscale, y * yscale, 1.0);
+ BIF_DrawString(G.fonts, str, 0);
+ glScalef(xscale, yscale, 1.0);
}
-
}
-static void draw_marker(TimeMarker *marker)
+/* ---------- */
+
+/* function to draw markers */
+static void draw_marker(TimeMarker *marker, int flag)
{
- float xpos, xspace, yspace, xpixels, ypixels;
+ float xpos, ypixels, xscale, yscale;
+ int icon_id= 0;
xpos = marker->frame;
/* no time correction for framelen! space is drawn with old values */
- xspace= G.v2d->cur.xmax - G.v2d->cur.xmin;
- yspace= G.v2d->cur.ymax - G.v2d->cur.ymin;
- xpixels= G.v2d->mask.xmax-G.v2d->mask.xmin;
ypixels= G.v2d->mask.ymax-G.v2d->mask.ymin;
-
+ view2d_getscale(G.v2d, &xscale, &yscale);
+
+ glScalef( 1.0/xscale, 1.0/yscale, 1.0);
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* verticle line */
+ if (flag & DRAW_MARKERS_LINES) {
+ setlinestyle(3);
+ if(marker->flag & SELECT)
+ glColor4ub(255,255,255, 96);
+ else
+ glColor4ub(0,0,0, 96);
+
+ glBegin(GL_LINES);
+ glVertex2f((xpos*xscale)+0.5, 12);
+ glVertex2f((xpos*xscale)+0.5, 34*yscale); /* a bit lazy but we know it cant be greater then 34 strips high*/
+ glEnd();
+ setlinestyle(0);
+ }
+
/* 5 px to offset icon to align properly, space / pixels corrects for zoom */
- if(marker->flag & SELECT)
- BIF_icon_draw(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER_HLT);
- else
- BIF_icon_draw(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER);
+ if (flag & DRAW_MARKERS_LOCAL) {
+ icon_id= (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
+ (marker->flag & SELECT) ? ICON_PMARKER_SEL :
+ ICON_PMARKER;
+ }
+ else {
+ icon_id= (marker->flag & SELECT) ? ICON_MARKER_HLT :
+ ICON_MARKER;
+ }
+ BIF_icon_draw(xpos*xscale-5.0, 12.0, icon_id);
glBlendFunc(GL_ONE, GL_ZERO);
- glDisable(GL_BLEND);
-
+ glDisable(GL_BLEND);
+
/* and the marker name too, shifted slightly to the top-right */
if(marker->name && marker->name[0]) {
if(marker->flag & SELECT) {
BIF_ThemeColor(TH_TEXT_HI);
- glRasterPos2f(xpos+(4.0*(xspace/xpixels)),
- ((ypixels<=39.0)?(ypixels-10.0):29.0)*yspace/ypixels);
+ ui_rasterpos_safe(xpos*xscale+4.0, (ypixels<=39.0)?(ypixels-10.0):29.0, 1.0);
}
else {
BIF_ThemeColor(TH_TEXT);
if((marker->frame <= G.scene->r.cfra) && (marker->frame+5 > G.scene->r.cfra))
- glRasterPos2f(xpos+(4.0*(xspace/xpixels)),
- ((ypixels<=39.0)?(ypixels-10.0):29.0)*yspace/ypixels);
+ ui_rasterpos_safe(xpos*xscale+4.0, (ypixels<=39.0)?(ypixels-10.0):29.0, 1.0);
else
- glRasterPos2f(xpos+(4.0*(xspace/xpixels)), 17.0*yspace/ypixels);
+ ui_rasterpos_safe(xpos*xscale+4.0, 17.0, 1.0);
}
- BMF_DrawString(G.font, marker->name);
+ BIF_DrawString(G.font, marker->name, 0);
}
+ glScalef(xscale, yscale, 1.0);
}
-static void draw_markers_time(void)
+/* Draw Scene-Markers for the TimeLine */
+static void draw_markers_time(int flag)
{
TimeMarker *marker;
/* unselected markers are drawn at the first time */
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
- if(!(marker->flag & SELECT)) draw_marker(marker);
+ for (marker= G.scene->markers.first; marker; marker= marker->next) {
+ if (!(marker->flag & SELECT)) draw_marker(marker, flag);
}
/* selected markers are drawn later ... selected markers have to cover unselected
* markers laying at the same position as selected markers
- * (jiri: it is hack, it could be solved better) */
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) draw_marker(marker);
+ * (jiri: it is hack, it could be solved better)
+ */
+ for (marker= G.scene->markers.first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) draw_marker(marker, flag);
}
}
-void draw_markers_timespace()
+/* Draw specified set of markers for Animation Editors */
+void draw_markers_timespace(ListBase *markers, int flag)
{
TimeMarker *marker;
float yspace, ypixels;
@@ -195,21 +245,21 @@ void draw_markers_timespace()
glTranslatef(0.0f, -11.0*yspace/ypixels, 0.0f);
/* unselected markers are drawn at the first time */
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
- if(!(marker->flag & SELECT)) draw_marker(marker);
+ for (marker= markers->first; marker; marker= marker->next) {
+ if (!(marker->flag & SELECT)) draw_marker(marker, flag);
}
/* selected markers are drawn later ... selected markers have to cover unselected
* markers laying at the same position as selected markers */
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) draw_marker(marker);
+ for (marker= markers->first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) draw_marker(marker, flag);
}
glTranslatef(0.0f, -G.v2d->cur.ymin, 0.0f);
glTranslatef(0.0f, 11.0*yspace/ypixels, 0.0f);
-
}
+
void draw_anim_preview_timespace()
{
/* only draw this if preview range is set */
@@ -250,83 +300,156 @@ static void draw_sfra_efra()
glDisable(GL_BLEND);
}
-/*draw all the keys in a list (elems) as lines */
-static void draw_key_list(ListBase elems, char col[3])
+static void draw_mapoldnew()
{
- CfraElem *ce;
- float drawframe;
+ float anim_end; /* the end of the blender frames that are actually animated (map old)*/
+ float frames_end; /* the end of the frames that get rendered and saved to disk (map new) */
+ GLubyte timeline_stipple[32*32/8] = TIMELINE_STIPPLE;
+
+ if (G.scene->r.framelen == 1.0) return;
+
+ anim_end = PEFRA * G.scene->r.framelen;
+ frames_end = PEFRA;
+
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(timeline_stipple);
+ BIF_ThemeColorShade(TH_BACK, -65);
+
+ if (anim_end < frames_end)
+ glRectf(anim_end, G.v2d->cur.ymin, frames_end, G.v2d->cur.ymax);
- ce= elems.first;
- while(ce) {
- drawframe = ce->cfra; //not correct for G.scene->r.framelen;
- glColor3ub(col[0], col[1], col[2]);
+ glDisable(GL_POLYGON_STIPPLE);
+}
- fdrawline(drawframe, G.v2d->cur.ymin, drawframe, G.v2d->cur.ymax);
-
- ce= ce->next;
+
+static void draw_ipo_keys(Ipo *ipo, char col[3])
+{
+ IpoCurve *icu;
+ int nvert;
+ int i;
+ int lbound, ubound;
+ int idx;
+ int diff;
+ float t;
+ float drawnext; /* next time to begin drawing new keyframes */
+
+ float space = G.v2d->cur.xmax - G.v2d->cur.xmin;
+ float pixels = G.v2d->mask.xmax-G.v2d->mask.xmin;
+ float spaceperpix = 1; /* amount of time occupied per pixel */
+
+ if (pixels > 0)
+ spaceperpix = space / pixels;
+
+ glColor3ub(col[0], col[1], col[2]);
+ glBegin(GL_LINES);
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ if (icu->flag & IPO_VISIBLE) {
+ if (icu->bezt) {
+ nvert= icu->totvert;
+
+ if (nvert > 0)
+ drawnext = icu->bezt[0].vec[1][0];
+ else
+ continue;
+
+ /* binary search for beginning of the visible keys */
+ lbound = 0;
+ ubound = nvert;
+ while (ubound - lbound > 1) {
+ diff = (ubound - lbound) / 2;
+ idx = lbound + diff;
+ t= icu->bezt[idx].vec[1][0];
+ if (t < G.v2d->cur.xmin)
+ lbound += diff;
+ else
+ ubound = lbound + diff;
+ }
+
+ for (i = lbound; i < nvert; i++) {
+ t= icu->bezt[i].vec[1][0];
+
+ /* dont do anymore draw tests after we draw the last visible key */
+ if (t > G.v2d->cur.xmax)
+ break;
+ /* avoid repeatedly drawing lines on the same pixel */
+ if (t < drawnext)
+ continue;
+
+ glVertex2f(t, G.v2d->cur.ymin);
+ glVertex2f(t, G.v2d->cur.ymax);
+
+ drawnext = t + spaceperpix;
+ }
+ }
+ }
}
+
+ glEnd();
}
+
+/* This function draws keyframes that the active object has (as long as
+ * it is not in EditMode). Some filters are available to optimise the
+ * drawing efficiency.
+ */
static void draw_ob_keys()
{
- /*mostly copied from drawobject.c, draw_object() */
- Object *ob;
- bActionChannel *achan;
- bAction *act;
- ListBase elems;
- int a;
+ /* mostly copied from drawobject.c, draw_object() */
+ SpaceTime *stime= curarea->spacedata.first;
+
+ Object *ob= OBACT;
+ short filter, ok;
char col[3];
+ int a;
- if (OBACT) {
- ob = OBACT;
+ if (ob && ob!=G.obedit) {
+ /* Object's IPO block - show all keys */
+ if (ob->ipo) {
+ /* draw the list of current frame elements */
+ col[0] = 0xDD; col[1] = 0xD7; col[2] = 0x00;
+ draw_ipo_keys(ob->ipo, col);
+ }
- if(ob) {
- if(ob!=G.obedit) {
- if(ob->ipo) {
- /* convert the ipo to a list of 'current frame elements' */
-
- elems.first= elems.last= NULL;
- make_cfra_list(ob->ipo, &elems);
-
- /* draw the list of current frame elements */
- col[0] = 0xDD; col[1] = 0xD7; col[2] = 0x00;
- draw_key_list(elems, col);
-
- BLI_freelistN(&elems);
+ /* Object's Action block - may be filtered in some cases */
+ if (ob->action) {
+ bAction *act = ob->action;
+ bActionChannel *achan;
+
+ /* only apply filter if action is likely to be for pose channels + filter is on */
+ filter= ((stime->flag & TIME_ONLYACTSEL) &&
+ (ob->pose) && (ob->flag & OB_POSEMODE));
+
+ /* go through each channel in the action */
+ for (achan=act->chanbase.first; achan; achan=achan->next) {
+ /* if filtering, check if this channel passes */
+ if (filter) {
+ ok= (SEL_ACHAN(achan))? 1 : 0;
}
+ else ok= 1;
- if(ob->action) {
- act = ob->action;
-
- /* go through each channel in the action */
- for (achan=act->chanbase.first; achan; achan=achan->next){
- /* convert the ipo to a list of 'current frame elements' */
- if(achan->ipo) {
- elems.first= elems.last= NULL;
- make_cfra_list(achan->ipo, &elems);
-
- col[0] = 0x00; col[1] = 0x82; col[2] = 0x8B;
- draw_key_list(elems, col);
-
- BLI_freelistN(&elems);
- }
- }
+ /* convert the ipo to a list of 'current frame elements' */
+ if (achan->ipo && ok) {
+ col[0] = 0x00; col[1] = 0x82; col[2] = 0x8B;
+ draw_ipo_keys(achan->ipo, col);
}
-
- for(a=0; a<ob->totcol; a++) {
- Material *ma= give_current_material(ob, a+1);
-
- if(ma && ma->ipo) {
- elems.first= elems.last= NULL;
- make_cfra_list(ma->ipo, &elems);
-
- col[0] = 0xDD; col[1] = 0xA7; col[2] = 0x00;
- draw_key_list(elems, col);
-
- BLI_freelistN(&elems);
- }
- }
-
+ }
+ }
+
+ /* Materials (only relevant for geometry objects) - some filtering might occur */
+ filter= (stime->flag & TIME_ONLYACTSEL);
+ for (a=0; a<ob->totcol; a++) {
+ Material *ma= give_current_material(ob, a+1);
+
+ /* the only filter we apply right now is only showing the active material */
+ if (filter) {
+ ok= (ob->actcol==a)? 1 : 0;
+ }
+ else ok= 1;
+
+ if (ma && ma->ipo && ok) {
+ col[0] = 0xDD; col[1] = 0xA7; col[2] = 0x00;
+ draw_ipo_keys(ma->ipo, col);
}
}
}
@@ -349,6 +472,7 @@ void drawtimespace(ScrArea *sa, void *spacedata)
* frame range used is preview range or scene range
*/
draw_sfra_efra();
+ draw_mapoldnew();
/* boundbox_seq(); */
calc_ipogrid();
@@ -356,7 +480,7 @@ void drawtimespace(ScrArea *sa, void *spacedata)
draw_cfra_time(spacedata);
draw_ob_keys();
- draw_markers_time();
+ draw_markers_time(0);
/* restore viewport */
mywinset(curarea->win);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 93de097a908..c4c221bcdf6 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -70,7 +70,10 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_force.h"
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -100,8 +103,12 @@
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
#include "BKE_scene.h"
+#include "BKE_sculpt.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -110,6 +117,7 @@
#include "BIF_editgroup.h"
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
+#include "BIF_editparticle.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_interface.h"
@@ -117,6 +125,7 @@
#include "BIF_mywindow.h"
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
@@ -136,6 +145,7 @@
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"
#include "BSE_seqaudio.h"
+#include "BSE_sequence.h"
#include "BSE_trans_types.h"
#include "BSE_time.h"
#include "BSE_view.h"
@@ -436,10 +446,13 @@ static void draw_bgpic(void)
glPushMatrix();
glaDefine2DArea(&curarea->winrct);
+
glEnable(GL_BLEND);
- glPixelTransferf(GL_ALPHA_SCALE, (1.0f-bgpic->blend));
+
glPixelZoom(zoomx, zoomy);
- glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ glColor4f(1.0, 1.0, 1.0, 1.0-bgpic->blend);
+ glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
@@ -1017,11 +1030,13 @@ static void drawviewborder(void)
BIF_ThemeColor(TH_WIRE);
glRectf(x1, y1, x2, y2);
- /* camera name */
+ /* camera name - draw in highlighted text color */
if (ca && (ca->flag & CAM_SHOWNAME)) {
+ BIF_ThemeColor(TH_TEXT_HI);
glRasterPos2f(x1, y1-15);
BMF_DrawString(G.font, G.vd->camera->id.name+2);
+ BIF_ThemeColor(TH_WIRE);
}
@@ -1075,7 +1090,7 @@ void backdrawview3d(int test)
int m;
#endif
- if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT));
+ if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT);
else if(G.obedit && G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT));
else {
G.vd->flag &= ~V3D_NEEDBACKBUFDRAW;
@@ -1394,6 +1409,11 @@ static void draw_view_axis(void)
float dx, dy;
float h, s, v;
+ /* thickness of lines is proportional to k */
+ /* (log(k)-1) gives a more suitable thickness, but fps decreased by about 3 fps */
+ glLineWidth(k / 10);
+ //glLineWidth(log(k)-1); // a bit slow
+
BIF_GetThemeColor3ubv(TH_GRID, (char *)gridcol);
/* X */
@@ -1458,6 +1478,9 @@ static void draw_view_axis(void)
glRasterPos2i(start + dx + 2, start + dy + ydisp + 2);
BMF_DrawString(G.fonts, "z");
}
+
+ /* restore line-width */
+ glLineWidth(1.0);
}
@@ -1481,25 +1504,57 @@ static void draw_view_icon(void)
static void draw_viewport_name(ScrArea *sa)
{
char *name = NULL;
+ char *printable = NULL;
switch(G.vd->view) {
case 1:
- name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back" : "Front";
+ if (G.vd->persp & V3D_PERSP_DO_3D_PERSP)
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp";
+ else
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho";
break;
case 3:
- name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left" : "Right";
+ if (G.vd->persp & V3D_PERSP_DO_3D_PERSP)
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp";
+ else
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho";
break;
case 7:
- name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom" : "Top";
+ if (G.vd->persp & V3D_PERSP_DO_3D_PERSP)
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp";
+ else
+ name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho";
break;
default:
- name = G.vd->persp==V3D_PERSP_USE_THE_CAMERA ? "Camera" : "User";
+ if (G.vd->persp==V3D_PERSP_USE_THE_CAMERA) {
+ if ((G.vd->camera) && (G.vd->camera->type == OB_CAMERA)) {
+ Camera *cam;
+ cam = G.vd->camera->data;
+ name = (cam->type != CAM_ORTHO) ? "Camera Persp" : "Camera Ortho";
+ } else {
+ name = "Object as Camera";
+ }
+ } else {
+ name = (G.vd->persp & V3D_PERSP_DO_3D_PERSP) ? "User Persp" : "User Ortho";
+ }
+ }
+
+ if (G.vd->localview) {
+ printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */
+ strcpy(printable, name);
+ strcat(printable, " (Local)");
+ } else {
+ printable = name;
}
- if (name) {
+ if (printable) {
BIF_ThemeColor(TH_TEXT_HI);
glRasterPos2i(10, sa->winy-20);
- BMF_DrawString(G.fonts, name);
+ BMF_DrawString(G.fonts, printable);
+ }
+
+ if (G.vd->localview) {
+ free(printable);
}
}
@@ -1536,7 +1591,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
if(ob->type==OB_MESH) {
eve= em->verts.first;
while(eve) {
- if(eve->f & 1) {
+ if(eve->f & SELECT) {
evedef= eve;
tot++;
VecAddf(median, median, eve->co);
@@ -1592,18 +1647,18 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
VecAddf(median, median, bezt->vec[1]);
tot++;
median[4]+= bezt->weight;
totweight++;
}
else {
- if(bezt->f1 & 1) {
+ if(bezt->f1 & SELECT) {
VecAddf(median, median, bezt->vec[0]);
tot++;
}
- if(bezt->f3 & 1) {
+ if(bezt->f3 & SELECT) {
VecAddf(median, median, bezt->vec[2]);
tot++;
}
@@ -1615,7 +1670,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
VecAddf(median, median, bp->vec);
median[3]+= bp->vec[3];
totw++;
@@ -1659,17 +1714,15 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
Mat4MulVecfl(ob->obmat, median);
if(block) { // buttons
-
+ int but_y;
+ if((ob->parent) && (ob->partype == PARBONE)) but_y = 135;
+ else but_y = 150;
+
uiBlockBeginAlign(block);
- if((ob->parent) && (ob->partype == PARBONE)) {
- uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 135, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values");
- uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 135, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values");
- }
- else {
- uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values");
- uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values");
- }
-
+ uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, but_y, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values");
+ uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, but_y, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values");
+ uiBlockEndAlign(block);
+
memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
uiBlockBeginAlign(block);
@@ -1704,6 +1757,15 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 10, 20, 290, 19, &(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);
+ }
+
if(totedge==1)
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
else if(totedge>1)
@@ -1725,7 +1787,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
eve= em->verts.first;
while(eve) {
- if(eve->f & 1) {
+ if(eve->f & SELECT) {
VecAddf(eve->co, eve->co, median);
}
eve= eve->next;
@@ -1758,17 +1820,17 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
VecAddf(bezt->vec[0], bezt->vec[0], median);
VecAddf(bezt->vec[1], bezt->vec[1], median);
VecAddf(bezt->vec[2], bezt->vec[2], median);
bezt->weight+= median[4];
}
else {
- if(bezt->f1 & 1) {
+ if(bezt->f1 & SELECT) {
VecAddf(bezt->vec[0], bezt->vec[0], median);
}
- if(bezt->f3 & 1) {
+ if(bezt->f3 & SELECT) {
VecAddf(bezt->vec[2], bezt->vec[2], median);
}
}
@@ -1779,7 +1841,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
VecAddf(bp->vec, bp->vec, median);
bp->vec[3]+= median[3];
bp->weight+= median[4];
@@ -1832,7 +1894,6 @@ static void validate_bonebutton_cb(void *bonev, void *namev)
}
}
-
static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim)
{
uiBut *but;
@@ -1912,20 +1973,20 @@ static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim)
uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootX:", 10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootY:", 10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootZ:", 10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
+ 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, "");
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipX:", 160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipY:", 160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipZ:", 160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
+ 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, "");
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, "");
-
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
+ 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
@@ -2176,7 +2237,81 @@ void do_viewbuts(unsigned short event)
allqueue(REDRAWVIEW3D, 1);
}
break;
+ case B_TRANSFORMSPACEADD:
+ BIF_manageTransformOrientation(1, 0);
+ allqueue(REDRAWVIEW3D, 1);
+ break;
+ case B_TRANSFORMSPACECLEAR:
+ BIF_clearTransformOrientation();
+ allqueue(REDRAWVIEW3D, 1);
+ }
+}
+
+void removeTransformOrientation_func(void *target, void *unused)
+{
+ BIF_removeTransformOrientation((TransformOrientation *) target);
+}
+
+void selectTransformOrientation_func(void *target, void *unused)
+{
+ BIF_selectTransformOrientation((TransformOrientation *) target);
+}
+
+static void view3d_panel_transform_spaces(short cntrl)
+{
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts = transform_spaces->first;
+ uiBlock *block;
+ uiBut *but;
+ int xco = 20, yco = 70, height = 140;
+ int index;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_panel_transform", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(VIEW3D_HANDLER_TRANSFORM); // for close and esc
+
+ if(uiNewPanel(curarea, block, "Transform Orientations", "View3d", 10, 230, 318, height)==0) return;
+
+ uiNewPanelHeight(block, height);
+
+ uiBlockBeginAlign(block);
+
+ if (G.obedit)
+ uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
+ else
+ uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
+
+ uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
+
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+
+ uiDefButS(block, ROW, REDRAWHEADERS, "Global", xco, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "Local", xco + 40, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "Normal", xco + 80, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
+ uiDefButS(block, ROW, REDRAWHEADERS, "View", xco + 120, 90, 40,20, &G.vd->twmode, 5.0, (float)V3D_MANIP_VIEW, 0, 0, "View Transform Orientation");
+
+ for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
+
+ BIF_ThemeColor(TH_BUT_ACTION);
+ if (G.vd->twmode == index) {
+ but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_CHECKBOX_HLT, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
+ }
+ else {
+ but = uiDefIconButS(block,ROW, REDRAWHEADERS, ICON_CHECKBOX_DEHLT, xco,yco,XIC,YIC, &G.vd->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
+ }
+ uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
+ uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
+ but = uiDefIconBut(block, BUT, REDRAWVIEW3D, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
+ uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
+
+ xco = 20;
+ yco -= 25;
}
+ uiBlockEndAlign(block);
+
+ if(yco < 0) uiNewPanelHeight(block, height-yco);
}
@@ -2200,12 +2335,20 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(VIEW3D_HANDLER_OBJECT); // for close and esc
- if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 204))
- return;
+ if((G.f & G_SCULPTMODE) && !G.obedit) {
+ if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234))
+ return;
+ } else if(G.f & G_PARTICLEEDIT && !G.obedit){
+ if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234))
+ return;
+ } else {
+ if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 204))
+ return;
+ }
- uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
+ if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw
}
else {
@@ -2217,13 +2360,17 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
#endif
-
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object");
- if((ob->parent) && (ob->partype == PARBONE)) {
- if (G.f & G_SCULPTMODE)
- uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 310, 180, 140, 20, ob->parsubstr, 0.0, 32.0, 0, 0, "");
- else
- uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0.0, 32.0, 0, 0, "");
+ if((G.f & G_PARTICLEEDIT)==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, "");
+ }
+ uiBlockEndAlign(block);
}
}
@@ -2258,6 +2405,9 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
else if(G.f & G_SCULPTMODE) {
uiNewPanelTitle(block, "Sculpt Properties");
sculptmode_draw_interface_tools(block,10,150);
+ } else if(G.f & G_PARTICLEEDIT){
+ uiNewPanelTitle(block, "Particle Edit Properties");
+ particle_edit_buttons(block);
} else {
BoundBox *bb = NULL;
@@ -2348,7 +2498,7 @@ static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
uiSetPanelHandler(VIEW3D_HANDLER_BACKGROUND); // for close and esc
if(uiNewPanel(curarea, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
- if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
+ if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT) {
uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw
}
@@ -2363,12 +2513,12 @@ static void view3d_panel_background(short cntrl) // VIEW3D_HANDLER_BACKGROUND
}
if(!(vd->flag & V3D_DISPBGPIC)) {
- uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use Background Image", 10, 180, 150, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
+ uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use Background Image", 10, 180, 150, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
}
else {
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use", 10, 225, 50, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of the 3D View");
+ uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use", 10, 225, 50, 20, &vd->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
uiDefButF(block, NUMSLI, B_REDR, "Blend:", 60, 225, 150, 20, &vd->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
uiDefButF(block, NUM, B_REDR, "Size:", 210, 225, 100, 20, &vd->bgpic->size, 0.1, 250.0*vd->grid, 100, 0, "Set the size (width) of the background image");
@@ -2403,8 +2553,8 @@ static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS
uiDefBut(block, LABEL, 1, "Grid:", 10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, REDRAWVIEW3D, "Spacing:", 10, 200, 140, 19, &vd->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
- uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:", 10, 180, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines");
- uiDefButS(block, NUM, REDRAWVIEW3D, "Divisions:", 10, 160, 140, 19, &vd->gridsubdiv, 0.0, 100.0, 100, 0, "Set the number of grid lines");
+ uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:", 10, 180, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines in perspective view");
+ uiDefButS(block, NUM, REDRAWVIEW3D, "Divisions:", 10, 160, 140, 19, &vd->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 1, "3D Display:", 160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
@@ -2436,11 +2586,12 @@ static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS
uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, REDRAWVIEW3D, "Outline Selected", 10, 30, 140, 19, &vd->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, REDRAWVIEW3D, "All Object Centers", 10, 10, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw the center points on all objects");
uiDefButBitS(block, TOGN, V3D_HIDE_HELPLINES, REDRAWVIEW3D, "Relationship Lines", 10, -10, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships");
+ uiDefButBitS(block, TOG, V3D_SOLID_TEX, REDRAWVIEW3D, "Solid Tex", 10, -30, 140, 19, &vd->flag2, 0, 0, 0, 0, "Display textures in Solid draw type (Shift T)");
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 1, "View Locking:", 160, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "Object:", 160, 30, 140, 19, &vd->ob_centre, "Lock view to center always on this Object");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "Object:", 160, 30, 140, 19, &vd->ob_centre, "Lock view to center to this Object");
uiDefBut(block, TEX, REDRAWVIEW3D, "Bone:", 160, 10, 140, 19, vd->ob_centre_bone, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
}
@@ -2498,6 +2649,9 @@ static void view3d_blockhandlers(ScrArea *sa)
case VIEW3D_HANDLER_PREVIEW:
view3d_panel_preview(sa, v3d->blockhandler[a+1]);
break;
+ case VIEW3D_HANDLER_TRANSFORM:
+ view3d_panel_transform_spaces(v3d->blockhandler[a+1]);
+ break;
}
/* clear action value for event */
v3d->blockhandler[a+1]= 0;
@@ -2590,10 +2744,6 @@ static void draw_dupli_objects_color(View3D *v3d, Base *base, int color)
if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
- /* test if we can do a displist */
- if(base->object->transflag & OB_DUPLIGROUP)
- use_displist= 0;
-
tbase.flag= OB_FROMDUPLI|base->flag;
lb= object_duplilist(G.scene, base->object);
@@ -2622,7 +2772,7 @@ static void draw_dupli_objects_color(View3D *v3d, Base *base, int color)
if(use_displist == -1) {
/* lamp drawing messes with matrices, could be handled smarter... but this works */
- if(dob->ob->type==OB_LAMP)
+ if(dob->ob->type==OB_LAMP || dob->type==OB_DUPLIGROUP)
use_displist= 0;
else {
/* disable boundbox check for list creation */
@@ -2707,13 +2857,47 @@ void view3d_update_depths(View3D *v3d)
}
}
+/* Enable sculpting in wireframe mode by drawing sculpt object only to the depth buffer */
+static void draw_sculpt_depths(View3D *v3d)
+{
+ Object *ob = OBACT;
+
+ int dt= MIN2(v3d->drawtype, ob->dt);
+ if(v3d->zbuf==0 && dt>OB_WIRE)
+ dt= OB_WIRE;
+ if(dt == OB_WIRE) {
+ GLboolean depth_on;
+ int orig_vdt = v3d->drawtype;
+ int orig_zbuf = v3d->zbuf;
+ int orig_odt = ob->dt;
+
+ glGetBooleanv(GL_DEPTH_TEST, &depth_on);
+ v3d->drawtype = ob->dt = OB_SOLID;
+ v3d->zbuf = 1;
+
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glEnable(GL_DEPTH_TEST);
+ draw_object(BASACT, 0);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ if(!depth_on)
+ glDisable(GL_DEPTH_TEST);
+
+ v3d->drawtype = orig_vdt;
+ v3d->zbuf = orig_zbuf;
+ ob->dt = orig_odt;
+ }
+}
+
+static void draw_viewport_fps(ScrArea *sa);
+
+
void drawview3dspace(ScrArea *sa, void *spacedata)
{
View3D *v3d= spacedata;
Base *base;
Object *ob;
Scene *sce;
- char retopo, sculpt;
+ char retopo, sculptparticle;
Object *obact = OBACT;
/* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual,
@@ -2723,6 +2907,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
for(SETLOOPER(G.scene->set, base))
object_handle_update(base->object); // bke_object.h
}
+
for(base= G.scene->base.first; base; base= base->next)
object_handle_update(base->object); // bke_object.h
@@ -2757,7 +2942,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
BIF_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
}
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
@@ -2765,7 +2950,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
float col[3];
BIF_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
myloadmatrix(v3d->viewmat);
@@ -2841,7 +3026,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
retopo= retopo_mesh_check() || retopo_curve_check();
- sculpt= (G.f & G_SCULPTMODE) && !G.obedit;
+ sculptparticle= (G.f & (G_SCULPTMODE|G_PARTICLEEDIT)) && !G.obedit;
if(retopo)
view3d_update_depths(v3d);
@@ -2853,12 +3038,16 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
}
- if(!retopo && sculpt && !(obact && (obact->dtx & OB_DRAWXRAY)))
+ if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) {
+ if(G.f & G_SCULPTMODE)
+ draw_sculpt_depths(v3d);
view3d_update_depths(v3d);
+ }
if(G.moving) {
BIF_drawConstraint();
- if(G.obedit) BIF_drawPropCircle(); // only editmode has proportional edit
+ if(G.obedit || (G.f & G_PARTICLEEDIT))
+ BIF_drawPropCircle(); // only editmode and particles have proportional edit
BIF_drawSnap();
}
@@ -2867,9 +3056,12 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
/* Transp and X-ray afterdraw stuff */
view3d_draw_xray(v3d, 0); // clears zbuffer if it is used!
view3d_draw_transp(v3d, 0);
-
- if(!retopo && sculpt && (obact && (OBACT->dtx & OB_DRAWXRAY)))
+
+ if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) {
+ if(G.f & G_SCULPTMODE)
+ draw_sculpt_depths(v3d);
view3d_update_depths(v3d);
+ }
if(v3d->flag & V3D_CLIPPING)
view3d_clr_clipping();
@@ -2885,66 +3077,14 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
/* Draw Sculpt Mode brush */
if(!G.obedit && (G.f & G_SCULPTMODE) && area_is_active_area(v3d->area) && sculpt_session()) {
- PropsetData *pd= sculpt_session()->propset;
- short r1=100, r2=100, r3=100;
- short mouse[2];
- if(pd) {
- if(pd->mode == PropsetSize) {
- r1= sculptmode_brush()->size;
- r2= pd->origsize;
- r3= r1;
- } else if(pd->mode == PropsetStrength) {
- r1= 200 - sculptmode_brush()->strength * 2;
- r2= 200;
- r3= 200;
- } else if(pd->mode == PropsetTexRot) {
- r1= r2= 200;
- r3= 200;
- }
-
- /* Draw brush with texture */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ RadialControl *rc= sculpt_session()->radialcontrol;
- glBindTexture(GL_TEXTURE_2D, pd->tex);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- glPushMatrix();
- glTranslatef(pd->origloc[0], pd->origloc[1], 0);
- glRotatef(tex_angle(), 0, 0, 1);
-
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
- glColor4f(0,0,0,1);
- glTexCoord2f(0,0);
- glVertex2f(-r3, -r3);
- glTexCoord2f(1,0);
- glVertex2f(r3, -r3);
- glTexCoord2f(1,1);
- glVertex2f(r3, r3);
- glTexCoord2f(0,1);
- glVertex2f(-r3, r3);
- glEnd();
- glDisable(GL_TEXTURE_2D);
-
- glPopMatrix();
+ if(sculpt_data()->flags & SCULPT_INPUT_SMOOTH)
+ sculpt_stroke_draw();
- if(r1 != r2)
- fdrawXORcirc(pd->origloc[0], pd->origloc[1], r1);
- fdrawXORcirc(pd->origloc[0], pd->origloc[1], r2);
-
- if(pd->mode == PropsetTexRot) {
- const float ang= pd->origtexrot * (M_PI/180.0f);
- getmouseco_areawin(mouse);
- sdrawXORline(pd->origloc[0], pd->origloc[1],
- pd->origloc[0]+200*cos(ang), pd->origloc[1]+200*sin(ang));
- sdrawXORline(pd->origloc[0], pd->origloc[1], mouse[0], mouse[1]);
- }
- }
- else if(sculpt_data()->draw_flag & SCULPTDRAW_BRUSH) {
+ if(rc)
+ radialcontrol_draw(rc);
+ else if(sculpt_data()->flags & SCULPT_DRAW_BRUSH) {
short csc[2], car[2];
getmouseco_sc(csc);
getmouseco_areawin(car);
@@ -2955,8 +3095,23 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
fdrawXORcirc((float)car[0], (float)car[1], sculptmode_brush()->size);
}
}
+
+ retopo_paint_view_update(v3d);
retopo_draw_paint_lines();
+ if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT && area_is_active_area(v3d->area)){
+ ParticleSystem *psys = PE_get_current(OBACT);
+ ParticleEditSettings *pset = PE_settings();
+
+ short c[2];
+ if(*PE_radialcontrol())
+ radialcontrol_draw(*PE_radialcontrol());
+ else if(psys && psys->edit && pset->brushtype>=0) {
+ getmouseco_areawin(c);
+ fdrawXORcirc((float)c[0], (float)c[1], (float)pset->brush[pset->brushtype].size);
+ }
+ }
+
if(v3d->persp>1) drawviewborder();
if(v3d->flag2 & V3D_FLYMODE) drawviewborder_flymode();
if(!(G.f & G_PLAYANIM)) drawcursor(v3d);
@@ -2964,8 +3119,12 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
draw_view_axis();
else
draw_view_icon();
- if(U.uiflag & USER_SHOW_VIEWPORTNAME)
+
+ if(U.uiflag & USER_SHOW_FPS && G.f & G_PLAYANIM) {
+ draw_viewport_fps(sa);
+ } else if(U.uiflag & USER_SHOW_VIEWPORTNAME) {
draw_viewport_name(sa);
+ }
ob= OBACT;
if(ob && (U.uiflag & USER_DRAWVIEWINFO))
@@ -2980,7 +3139,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
sa->win_swap= WIN_BACK_OK;
- if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
+ if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT || G.f & G_TEXTUREPAINT) {
v3d->flag |= V3D_NEEDBACKBUFDRAW;
addafterqueue(sa->win, BACKBUFDRAW, 1);
}
@@ -3007,22 +3166,26 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
}
-void drawview3d_render(struct View3D *v3d, int winx, int winy)
+void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4])
{
Base *base;
Scene *sce;
- float winmat[4][4];
+ float v3dwinmat[4][4];
- update_for_newframe_muted(); /* first, since camera can be animated */
+ if(!winmat)
+ setwinmatrixview3d(winx, winy, NULL);
- setwinmatrixview3d(winx, winy, NULL);
-
setviewmatrixview3d();
myloadmatrix(v3d->viewmat);
+
+ /* when winmat is not NULL, it overrides the regular window matrix */
glMatrixMode(GL_PROJECTION);
- mygetmatrix(winmat);
+ if(winmat)
+ myloadmatrix(winmat);
+ mygetmatrix(v3dwinmat);
glMatrixMode(GL_MODELVIEW);
- Mat4MulMat4(v3d->persmat, v3d->viewmat, winmat);
+
+ Mat4MulMat4(v3d->persmat, v3d->viewmat, v3dwinmat);
Mat4Invert(v3d->persinv, v3d->persmat);
Mat4Invert(v3d->viewinv, v3d->viewmat);
@@ -3130,13 +3293,23 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy)
double tottime = 0.0;
+static ScrArea *oldsa;
+static double swaptime;
+static int curmode;
+
+/* used for fps display */
+static double redrawtime;
+static double lredrawtime;
int update_time(void)
{
static double ltime;
double time;
- if ((U.mixbufsize)&&(audiostream_pos() != CFRA)&&(G.scene->audio.flag & AUDIO_SYNC)) return 0;
+ if ((audiostream_pos() != CFRA)
+ && (G.scene->audio.flag & AUDIO_SYNC)) {
+ return 0;
+ }
time = PIL_check_seconds_timer();
@@ -3145,60 +3318,238 @@ int update_time(void)
return (tottime < 0.0);
}
-void inner_play_anim_loop(int init, int mode)
+static void draw_viewport_fps(ScrArea *sa)
{
- ScrArea *sa;
- static ScrArea *oldsa;
- static double swaptime;
- static int curmode;
+ float fps;
+ char printable[16];
- /* init */
- if(init) {
- oldsa= curarea;
- swaptime= 1.0/(float)G.scene->r.frs_sec;
- tottime= 0.0;
- curmode= mode;
+
+ if (lredrawtime == redrawtime)
+ return;
+
+ printable[0] = '\0';
+ fps = (float)(1.0/(lredrawtime-redrawtime));
+
+ /* is this more then half a frame behind? */
+ if (fps+0.5 < FPS) {
+ BIF_ThemeColor(TH_REDALERT);
+ sprintf(printable, "fps: %.2f", (float)fps);
+ } else {
+ BIF_ThemeColor(TH_TEXT_HI);
+ sprintf(printable, "fps: %i", (int)(fps+0.5));
+ }
+
+ glRasterPos2i(10, sa->winy-20);
+ BMF_DrawString(G.fonts, printable);
+}
+
+static void inner_play_prefetch_frame(int mode, int cfra)
+{
+ ScrArea *sa;
+ int oldcfra = CFRA;
+ ScrArea *oldcurarea = curarea;
+ if (!U.prefetchframes) {
return;
}
- set_timecursor(CFRA);
-
- update_for_newframe_nodraw(1); /* adds no events in UI */
+ CFRA = cfra;
sa= G.curscreen->areabase.first;
while(sa) {
if(sa==oldsa) {
- scrarea_do_windraw(sa);
+ scrarea_do_winprefetchdraw(sa);
}
- else if(curmode & 1) { /* all view3d and seq spaces */
+ else if(mode & 1) { /* all view3d and seq spaces */
if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
- scrarea_do_windraw(sa);
+ scrarea_do_winprefetchdraw(sa);
}
}
- else if(curmode & 4) { /* all seq spaces */
+ else if(mode & 4) { /* all seq spaces */
if (sa->spacetype == SPACE_SEQ) {
- scrarea_do_windraw(sa);
+ scrarea_do_winprefetchdraw(sa);
}
}
sa= sa->next;
}
+
+ CFRA = oldcfra;
+ curarea = oldcurarea;
+}
+
+static void inner_play_prefetch_startup(int mode)
+{
+ int i;
+
+ if (!U.prefetchframes) {
+ return;
+ }
+
+ seq_start_threads();
+
+ for (i = 0; i <= U.prefetchframes; i++) {
+ int cfra = CFRA + i;
+ inner_play_prefetch_frame(mode, cfra);
+ }
+
+ seq_wait_for_prefetch_ready();
+}
+
+static void inner_play_prefetch_shutdown(int mode)
+{
+ if (!U.prefetchframes) {
+ return;
+ }
+ seq_stop_threads();
+}
+
+static int cached_dynamics(int sfra, int efra)
+{
+ Base *base = G.scene->base.first;
+ Object *ob;
+ ModifierData *md;
+ ParticleSystem *psys;
+ int i, stack_index=-1, cached=1;
+
+ while(base && cached) {
+ ob = base->object;
+ if(ob->softflag & OB_SB_ENABLE && ob->soft) {
+ for(i=0, md=ob->modifiers.first; md; i++, md=md->next) {
+ if(md->type == eModifierType_Softbody) {
+ stack_index = i;
+ break;
+ }
+ }
+ for(i=sfra; i<=efra && cached; i++)
+ cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+ }
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+ stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,psys));
+ if(psys->part->type==PART_HAIR) {
+ if(psys->softflag & OB_SB_ENABLE && psys->soft);
+ else
+ stack_index = -1;
+ }
+
+ if(stack_index >= 0)
+ for(i=sfra; i<=efra && cached; i++)
+ cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+ }
+
+ base = base->next;
+ }
+
+ return cached;
+}
+void inner_play_anim_loop(int init, int mode)
+{
+ ScrArea *sa;
+ static int last_cfra = -1;
+ static int cached = 0;
+
+ /* init */
+ if(init) {
+ oldsa= curarea;
+ swaptime= 1.0/FPS;
+ tottime= 0.0;
+ curmode= mode;
+ last_cfra = -1;
+ cached = cached_dynamics(PSFRA,PEFRA);
+
+ redrawtime = 1.0/FPS;
+ lredrawtime = 0.0;
+ return;
+ }
+
+ if (CFRA != last_cfra) {
+ int pf;
+ set_timecursor(CFRA);
+ update_for_newframe_nodraw(1); /* adds no events in UI */
+
+ sa= G.curscreen->areabase.first;
+ while(sa) {
+ if(sa==oldsa) {
+ scrarea_do_windraw(sa);
+ }
+ else if(curmode & 1) { /* all view3d and seq spaces */
+ if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
+ scrarea_do_windraw(sa);
+ }
+ }
+ else if(curmode & 4) { /* all seq spaces */
+ if (sa->spacetype == SPACE_SEQ) {
+ scrarea_do_windraw(sa);
+ }
+ }
+
+ sa= sa->next;
+ }
+
+ if (last_cfra == -1) {
+ last_cfra = CFRA - 1;
+ }
+
+ if (U.prefetchframes) {
+ pf = last_cfra;
+
+ if (CFRA - last_cfra >= U.prefetchframes ||
+ CFRA - last_cfra < 0) {
+ pf = CFRA - U.prefetchframes;
+ fprintf(stderr,
+ "SEQ-THREAD: Lost sync, "
+ "stopping threads, "
+ "back to skip mode...\n");
+ seq_stop_threads();
+ } else {
+ while (pf < CFRA) {
+ int c;
+ pf++;
+ c = pf + U.prefetchframes;
+ if (c >= PEFRA) {
+ c -= PEFRA;
+ c += PSFRA;
+ }
+
+ inner_play_prefetch_frame(curmode, c);
+ }
+ }
+
+ }
+ }
+
+ last_cfra = CFRA;
+
/* make sure that swaptime passed by */
tottime -= swaptime;
- while (update_time()) PIL_sleep_ms(1);
-
- if(CFRA>=PEFRA) {
- if (tottime > 0.0) tottime = 0.0;
- CFRA= PSFRA;
+ while (update_time()) {
+ PIL_sleep_ms(1);
+ }
+
+ if (CFRA >= PEFRA) {
+ if (tottime > 0.0) {
+ tottime = 0.0;
+ }
+ CFRA = PSFRA;
audiostream_stop();
audiostream_start( CFRA );
+ cached = cached_dynamics(PSFRA,PEFRA);
+ } else {
+ if (cached
+ && (G.scene->audio.flag & AUDIO_SYNC)) {
+ CFRA = audiostream_pos();
+ } else {
+ CFRA++;
+ }
+ if (CFRA < last_cfra) {
+ fprintf(stderr,
+ "SEQ-THREAD: CFRA running backwards: %d\n",
+ CFRA);
+ }
}
- else {
- if (U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) CFRA = audiostream_pos();
- else CFRA++;
- }
+
}
/* play_anim: 'mode' defines where to play and if repeat is on (now bitfield):
@@ -3211,7 +3562,7 @@ int play_anim(int mode)
ScrArea *sa, *oldsa;
int cfraont;
unsigned short event=0;
- short val;
+ short val = 0; /* its possible qtest() wont run and val must be initialized */
/* patch for very very old scenes */
if(SFRA==0) SFRA= 1;
@@ -3219,31 +3570,35 @@ int play_anim(int mode)
if(PSFRA>PEFRA) return 0;
- update_time();
-
/* waitcursor(1); */
G.f |= G_PLAYANIM; /* in sequence.c and view.c this is handled */
cfraont= CFRA;
oldsa= curarea;
- audiostream_start( CFRA );
-
if (curarea && curarea->spacetype == SPACE_SEQ) {
SpaceSeq *sseq = curarea->spacedata.first;
if (sseq->mainb == 0) mode |= 4;
}
+
+ inner_play_prefetch_startup(mode);
+
+ update_time();
inner_play_anim_loop(1, mode); /* 1==init */
+
+ audiostream_start( CFRA );
/* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */
curarea->win_swap= WIN_BACK_OK;
screen_swapbuffers();
-
- while(TRUE) {
+ while(TRUE) {
+
+ if (U.uiflag & USER_SHOW_FPS)
+ lredrawtime = PIL_check_seconds_timer();
+
while(qtest()) {
-
/* we test events first because of MKEY event */
event= extern_qread(&val);
@@ -3264,17 +3619,23 @@ int play_anim(int mode)
if(val) add_marker(CFRA-1);
}
}
- if(ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break;
+ if(val && ELEM3(event, ESCKEY, SPACEKEY, RIGHTMOUSE)) break;
inner_play_anim_loop(0, 0);
+
+
screen_swapbuffers();
-
+
+ if (U.uiflag & USER_SHOW_FPS)
+ redrawtime = lredrawtime;
+
if((mode & 2) && CFRA==PEFRA) break; /* no replay */
}
if(event==SPACEKEY);
else CFRA= cfraont;
+ inner_play_prefetch_shutdown(mode);
audiostream_stop();
if(oldsa!=curarea) areawinset(oldsa->win);
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index 5a088ec6bef..ecd546a6780 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -52,12 +52,14 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
#include "DNA_ipo_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -81,6 +83,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
#ifdef WITH_VERSE
@@ -90,6 +93,7 @@
#include "BIF_editmesh.h"
#include "BIF_editview.h"
#include "BIF_editarmature.h"
+#include "BIF_editparticle.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_interface.h"
@@ -120,6 +124,7 @@
/*#include "armature.h"*/
/* #include "edit.h" */
#include "nla.h"
+#include "transform.h"
#ifdef __NLA
#include "BIF_editarmature.h"
@@ -421,9 +426,12 @@ int get_border(rcti *rect, short flag)
circle_selectCB(&obedit_selectionCB);
}
}
- else if (G.f&G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
circle_selectCB(&obedit_selectionCB);
}
+ else if (G.f&G_PARTICLEEDIT) {
+ circle_selectCB(&PE_selectionCB);
+ }
return 0;
case SPACE_IMAGE: // brush select in UV editor
@@ -476,7 +484,7 @@ void draw_sel_circle(short *mval, short *mvalo, float rad, float rado, int selec
void circle_selectCB(select_CBfunc callback)
{
static float rad= 40.0;
- float rado;
+ float rado= rad;
int firsttime=1;
int escape= 0;
unsigned short event;
@@ -494,8 +502,6 @@ void circle_selectCB(select_CBfunc callback)
draw_sel_circle(mval, NULL, rad, 0.0, selecting); // draws frontbuffer, but sets backbuf again
- rado= rad;
-
while(TRUE) {
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || rado!=rad || firsttime) {
@@ -722,7 +728,7 @@ void countall()
a= nu->pntsu*nu->pntsv;
while(a--) {
G.totvert++;
- if(bp->f1 & 1) G.totvertsel++;
+ if(bp->f1 & SELECT) G.totvertsel++;
bp++;
}
}
@@ -746,7 +752,7 @@ void countall()
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
G.totvert++;
- if(bp->f1 & 1) G.totvertsel++;
+ if(bp->f1 & SELECT) G.totvertsel++;
bp++;
}
}
@@ -768,7 +774,7 @@ void countall()
allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
return;
}
- else if(G.f & (G_FACESELECT + G_VERTEXPAINT + G_TEXTUREPAINT +G_WEIGHTPAINT)) {
+ else if(FACESEL_PAINT_TEST) {
me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0);
if(me) {
G.totface= me->totface;
@@ -786,8 +792,47 @@ void countall()
ob= base->object; /* warning, ob not is obact anymore */
if(base->flag & SELECT) G.totobjsel++;
-
- if(ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS|OB_DUPLIFACES))) {
+
+ if(ob->transflag & OB_DUPLIPARTS) {
+ ParticleSystem *psys;
+ ParticleSettings *part;
+ int step_nbr;
+
+ for(psys=ob->particlesystem.first; psys; psys=psys->next){
+ part=psys->part;
+
+ //if(psys->flag&PSYS_BAKED && part->draw&PART_DRAW_KEYS)
+ // step_nbr=part->keys_step;
+ //else
+ step_nbr=1;
+
+ if(part->draw_as==PART_DRAW_OB && part->dup_ob){
+ int tot=count_particles(psys);
+ count_object(part->dup_ob, 0, tot*step_nbr);
+ }
+ else if(part->draw_as==PART_DRAW_GR && part->dup_group){
+ GroupObject *go;
+ int tot, totgroup=0, cur=0;
+
+ go= part->dup_group->gobject.first;
+ while(go){
+ go=go->next;
+ totgroup++;
+ }
+ go= part->dup_group->gobject.first;
+ while(go){
+ tot=count_particles_mod(psys,totgroup,cur);
+ count_object(go->ob, 0, tot*step_nbr);
+ cur++;
+ go=go->next;
+ }
+ }
+ }
+
+ count_object(ob, base->flag & SELECT, 1);
+ G.totobj++;
+ }
+ else if(ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS|OB_DUPLIFACES))) {
int tot= count_duplilist(ob->parent);
G.totobj+=tot;
count_object(ob, base->flag & SELECT, tot);
@@ -883,7 +928,7 @@ static void special_transvert_update(void)
}
/* copied from editobject.c, needs to be replaced with new transform code still */
-/* mode: 1 = proportional */
+/* mode: 1 = proportional, 2 = all joints (for bones only) */
static void make_trans_verts(float *min, float *max, int mode)
{
extern ListBase editNurb;
@@ -907,7 +952,7 @@ static void make_trans_verts(float *min, float *max, int mode)
/* I skip it for editmesh now (ton) */
if(G.obedit->type!=OB_MESH) {
countall();
- if(mode) tottrans= G.totvert;
+ if(mode) tottrans= G.totvert;
else tottrans= G.totvertsel;
if(G.totvertsel==0) {
@@ -955,7 +1000,7 @@ static void make_trans_verts(float *min, float *max, int mode)
}
/* proportional edit exception... */
- if(mode==1 && tottrans) {
+ if((mode & 1) && tottrans) {
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->h==0) {
eve->f1 |= 2;
@@ -991,8 +1036,9 @@ static void make_trans_verts(float *min, float *max, int mode)
short rootok= (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL));
if ((tipsel && rootsel) || (rootsel)) {
- /* Only add the root if there is no connection.
- * Don't add the tip, otherwise we get zero-length bones.
+ /* Don't add the tip (unless mode & 2, for getting all joints),
+ * otherwise we get zero-length bones as tips will snap to the same
+ * location as heads.
*/
if (rootok) {
VECCOPY (tv->oldloc, ebo->head);
@@ -1002,6 +1048,15 @@ static void make_trans_verts(float *min, float *max, int mode)
tv++;
tottrans++;
}
+
+ if ((mode & 2) && (tipsel)) {
+ VECCOPY (tv->oldloc, ebo->tail);
+ tv->loc= ebo->tail;
+ tv->nor= NULL;
+ tv->flag= 1;
+ tv++;
+ tottrans++;
+ }
}
else if (tipsel) {
VECCOPY (tv->oldloc, ebo->tail);
@@ -1022,26 +1077,26 @@ static void make_trans_verts(float *min, float *max, int mode)
bezt= nu->bezt;
while(a--) {
if(bezt->hide==0) {
- if(mode==1 || (bezt->f1 & 1)) {
+ if((mode & 1) || (bezt->f1 & SELECT)) {
VECCOPY(tv->oldloc, bezt->vec[0]);
tv->loc= bezt->vec[0];
- tv->flag= bezt->f1 & 1;
+ tv->flag= bezt->f1 & SELECT;
tv++;
tottrans++;
}
- if(mode==1 || (bezt->f2 & 1)) {
+ if((mode & 1) || (bezt->f2 & SELECT)) {
VECCOPY(tv->oldloc, bezt->vec[1]);
tv->loc= bezt->vec[1];
tv->val= &(bezt->alfa);
tv->oldval= bezt->alfa;
- tv->flag= bezt->f2 & 1;
+ tv->flag= bezt->f2 & SELECT;
tv++;
tottrans++;
}
- if(mode==1 || (bezt->f3 & 1)) {
+ if((mode & 1) || (bezt->f3 & SELECT)) {
VECCOPY(tv->oldloc, bezt->vec[2]);
tv->loc= bezt->vec[2];
- tv->flag= bezt->f3 & 1;
+ tv->flag= bezt->f3 & SELECT;
tv++;
tottrans++;
}
@@ -1054,12 +1109,12 @@ static void make_trans_verts(float *min, float *max, int mode)
bp= nu->bp;
while(a--) {
if(bp->hide==0) {
- if(mode==1 || (bp->f1 & 1)) {
+ if((mode & 1) || (bp->f1 & SELECT)) {
VECCOPY(tv->oldloc, bp->vec);
tv->loc= bp->vec;
tv->val= &(bp->alfa);
tv->oldval= bp->alfa;
- tv->flag= bp->f1 & 1;
+ tv->flag= bp->f1 & SELECT;
tv++;
tottrans++;
}
@@ -1092,11 +1147,11 @@ static void make_trans_verts(float *min, float *max, int mode)
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
- if(mode==1 || (bp->f1 & 1)) {
+ if((mode & 1) || (bp->f1 & SELECT)) {
if(bp->hide==0) {
VECCOPY(tv->oldloc, bp->vec);
tv->loc= bp->vec;
- tv->flag= bp->f1 & 1;
+ tv->flag= bp->f1 & SELECT;
tv++;
tottrans++;
}
@@ -1147,13 +1202,13 @@ void snap_sel_to_grid()
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
make_trans_verts(bmat[0], bmat[1], 0);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
Mat3Inv(imat, bmat);
-
+
tv= transvmain;
for(a=0; a<tottrans; a++, tv++) {
-
+
VECCOPY(vec, tv->loc);
Mat3MulVecfl(bmat, vec);
VecAddf(vec, vec, G.obedit->obmat[3]);
@@ -1161,17 +1216,17 @@ void snap_sel_to_grid()
vec[1]= G.vd->gridview*floor(.5+ vec[1]/gridf);
vec[2]= G.vd->gridview*floor(.5+ vec[2]/gridf);
VecSubf(vec, vec, G.obedit->obmat[3]);
-
+
Mat3MulVecfl(imat, vec);
VECCOPY(tv->loc, vec);
-
+
}
-
+
special_transvert_update();
MEM_freeN(transvmain);
transvmain= 0;
-
+
allqueue(REDRAWVIEW3D, 0);
return;
}
@@ -1209,7 +1264,10 @@ void snap_sel_to_grid()
}
}
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
- ob->recalc |= OB_RECALC_DATA;
+
+ /* auto-keyframing */
+ autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
else {
ob->recalc |= OB_RECALC_OB;
@@ -1217,10 +1275,10 @@ void snap_sel_to_grid()
vec[0]= -ob->obmat[3][0]+G.vd->gridview*floor(.5+ ob->obmat[3][0]/gridf);
vec[1]= -ob->obmat[3][1]+G.vd->gridview*floor(.5+ ob->obmat[3][1]/gridf);
vec[2]= -ob->obmat[3][2]+G.vd->gridview*floor(.5+ ob->obmat[3][2]/gridf);
-
+
if(ob->parent) {
where_is_object(ob);
-
+
Mat3Inv(imat, originmat);
Mat3MulVecfl(imat, vec);
ob->loc[0]+= vec[0];
@@ -1235,6 +1293,9 @@ void snap_sel_to_grid()
#ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob);
#endif
+
+ /* auto-keyframing */
+ autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
}
}
@@ -1257,31 +1318,29 @@ void snap_sel_to_curs()
if(G.obedit) {
tottrans= 0;
-
+
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
make_trans_verts(bmat[0], bmat[1], 0);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
Mat3Inv(imat, bmat);
-
+
tv= transvmain;
for(a=0; a<tottrans; a++, tv++) {
-
vec[0]= curs[0]-G.obedit->obmat[3][0];
vec[1]= curs[1]-G.obedit->obmat[3][1];
vec[2]= curs[2]-G.obedit->obmat[3][2];
-
+
Mat3MulVecfl(imat, vec);
VECCOPY(tv->loc, vec);
-
}
special_transvert_update();
MEM_freeN(transvmain);
transvmain= 0;
-
+
allqueue(REDRAWVIEW3D, 0);
return;
}
@@ -1318,7 +1377,10 @@ void snap_sel_to_curs()
}
}
ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
- ob->recalc |= OB_RECALC_DATA;
+
+ /* auto-keyframing */
+ autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
else {
ob->recalc |= OB_RECALC_OB;
@@ -1326,10 +1388,10 @@ void snap_sel_to_curs()
vec[0]= -ob->obmat[3][0] + curs[0];
vec[1]= -ob->obmat[3][1] + curs[1];
vec[2]= -ob->obmat[3][2] + curs[2];
-
+
if(ob->parent) {
where_is_object(ob);
-
+
Mat3Inv(imat, originmat);
Mat3MulVecfl(imat, vec);
ob->loc[0]+= vec[0];
@@ -1344,6 +1406,9 @@ void snap_sel_to_curs()
#ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob);
#endif
+
+ /* auto-keyframing */
+ autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
}
}
@@ -1365,7 +1430,6 @@ void snap_curs_to_grid()
curs[2]= G.vd->gridview*floor(.5+curs[2]/gridf);
allqueue(REDRAWVIEW3D, 0);
-
}
void snap_curs_to_sel()
@@ -1383,13 +1447,13 @@ void snap_curs_to_sel()
if(G.obedit) {
tottrans=0;
-
+
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
- make_trans_verts(bmat[0], bmat[1], 0);
+ make_trans_verts(bmat[0], bmat[1], 2);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
-
+
tv= transvmain;
for(a=0; a<tottrans; a++, tv++) {
VECCOPY(vec, tv->loc);
@@ -1398,7 +1462,7 @@ void snap_curs_to_sel()
VecAddf(centroid, centroid, vec);
DO_MINMAX(vec, min, max);
}
-
+
if(G.vd->around==V3D_CENTROID) {
VecMulf(centroid, 1.0/(float)tottrans);
VECCOPY(curs, centroid);
@@ -1454,6 +1518,58 @@ void snap_curs_to_sel()
allqueue(REDRAWVIEW3D, 0);
}
+void snap_curs_to_active()
+{
+ float *curs;
+ curs = give_cursor();
+
+ if (G.obedit)
+ {
+ if (G.obedit->type == OB_MESH)
+ {
+ /* check active */
+ if (G.editMesh->selected.last) {
+ EditSelection *ese = G.editMesh->selected.last;
+ if ( ese->type == EDITVERT ) {
+ EditVert *eve = (EditVert *)ese->data;
+ VECCOPY(curs, eve->co);
+ }
+ else if ( ese->type == EDITEDGE ) {
+ EditEdge *eed = (EditEdge *)ese->data;
+ VecAddf(curs, eed->v1->co, eed->v2->co);
+ VecMulf(curs, 0.5f);
+ }
+ else if ( ese->type == EDITFACE ) {
+ EditFace *efa = (EditFace *)ese->data;
+
+ if (efa->v4)
+ {
+ VecAddf(curs, efa->v1->co, efa->v2->co);
+ VecAddf(curs, curs, efa->v3->co);
+ VecAddf(curs, curs, efa->v4->co);
+ VecMulf(curs, 0.25f);
+ }
+ else
+ {
+ VecAddf(curs, efa->v1->co, efa->v2->co);
+ VecAddf(curs, curs, efa->v3->co);
+ VecMulf(curs, 1/3.0f);
+ }
+ }
+ }
+ Mat4MulVecfl(G.obedit->obmat, curs);
+ }
+ }
+ else
+ {
+ if (BASACT)
+ {
+ VECCOPY(curs, BASACT->object->obmat[3]);
+ }
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
+
void snap_curs_to_firstsel()
{
TransVert *tv;
@@ -1469,20 +1585,20 @@ void snap_curs_to_firstsel()
if(G.obedit) {
tottrans=0;
-
+
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
make_trans_verts(bmat[0], bmat[1], 0);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
-
+
tv= transvmain;
VECCOPY(vec, tv->loc);
/*Mat3MulVecfl(bmat, vec);
VecAddf(vec, vec, G.obedit->obmat[3]);
VecAddf(centroid, centroid, vec);
DO_MINMAX(vec, min, max);*/
-
+
if(G.vd->around==V3D_CENTROID) {
VecMulf(vec, 1.0/(float)tottrans);
VECCOPY(curs, vec);
@@ -1538,14 +1654,14 @@ void snap_to_center()
if(G.obedit) {
tottrans= 0;
-
+
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
make_trans_verts(bmat[0], bmat[1], 0);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
Mat3Inv(imat, bmat);
-
+
tv= transvmain;
for(a=0; a<tottrans; a++, tv++) {
VECCOPY(vec, tv->loc);
@@ -1554,7 +1670,7 @@ void snap_to_center()
VecAddf(centroid, centroid, vec);
DO_MINMAX(vec, min, max);
}
-
+
if(G.vd->around==V3D_CENTROID) {
VecMulf(centroid, 1.0/(float)tottrans);
VECCOPY(snaploc, centroid);
@@ -1567,7 +1683,6 @@ void snap_to_center()
MEM_freeN(transvmain);
transvmain= 0;
-
}
else {
base= (G.scene->base.first);
@@ -1615,21 +1730,20 @@ void snap_to_center()
/* Snap the selection to the snaplocation (duh!) */
if(G.obedit) {
tottrans= 0;
-
+
if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)
make_trans_verts(bmat[0], bmat[1], 0);
if(tottrans==0) return;
-
+
Mat3CpyMat4(bmat, G.obedit->obmat);
Mat3Inv(imat, bmat);
-
+
tv= transvmain;
for(a=0; a<tottrans; a++, tv++) {
-
vec[0]= snaploc[0]-G.obedit->obmat[3][0];
vec[1]= snaploc[1]-G.obedit->obmat[3][1];
vec[2]= snaploc[2]-G.obedit->obmat[3][2];
-
+
Mat3MulVecfl(imat, vec);
VECCOPY(tv->loc, vec);
}
@@ -1638,7 +1752,7 @@ void snap_to_center()
MEM_freeN(transvmain);
transvmain= 0;
-
+
allqueue(REDRAWVIEW3D, 0);
return;
}
@@ -1667,8 +1781,11 @@ void snap_to_center()
}
}
}
- ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
- ob->recalc |= OB_RECALC_DATA;
+
+ /* auto-keyframing */
+ ob->pose->flag |= POSE_DO_UNLOCK;
+ autokeyframe_pose_cb_func(ob, TFM_TRANSLATION, 0);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
else {
ob->recalc |= OB_RECALC_OB;
@@ -1676,10 +1793,10 @@ void snap_to_center()
vec[0]= -ob->obmat[3][0] + snaploc[0];
vec[1]= -ob->obmat[3][1] + snaploc[1];
vec[2]= -ob->obmat[3][2] + snaploc[2];
-
+
if(ob->parent) {
where_is_object(ob);
-
+
Mat3Inv(imat, originmat);
Mat3MulVecfl(imat, vec);
ob->loc[0]+= vec[0];
@@ -1694,9 +1811,12 @@ void snap_to_center()
#ifdef WITH_VERSE
if(ob->vnode) b_verse_send_transformation(ob);
#endif
+
+ /* auto-keyframing */
+ autokeyframe_ob_cb_func(ob, TFM_TRANSLATION);
}
}
-
+
base= base->next;
}
DAG_scene_flush_update(G.scene, screen_view3d_layers());
@@ -1708,7 +1828,7 @@ void snapmenu()
{
short event;
- event = pupmenu("Snap %t|Selection -> Grid%x1|Selection -> Cursor%x2|Cursor-> Grid%x3|Cursor-> Selection%x4|Selection-> Center%x5");
+ event = pupmenu("Snap %t|Selection -> Grid%x1|Selection -> Cursor%x2|Selection -> Center%x3|%l|Cursor -> Selection%x4|Cursor -> Grid%x5|Cursor -> Active%x6");
switch (event) {
case 1: /*Selection to grid*/
@@ -1718,15 +1838,19 @@ void snapmenu()
case 2: /*Selection to cursor*/
snap_sel_to_curs();
BIF_undo_push("Snap selection to cursor");
- break;
- case 3: /*Cursor to grid*/
- snap_curs_to_grid();
+ break;
+ case 3: /*Selection to center of selection*/
+ snap_to_center();
+ BIF_undo_push("Snap selection to center");
break;
case 4: /*Cursor to selection*/
snap_curs_to_sel();
break;
- case 5: /*Selection to center of selection*/
- snap_to_center();
+ case 5: /*Cursor to grid*/
+ snap_curs_to_grid();
+ break;
+ case 6: /*Cursor to Active*/
+ snap_curs_to_active();
BIF_undo_push("Snap selection to center");
break;
}
@@ -1794,6 +1918,9 @@ void delete_context_selected(void)
else if(G.obedit->type==OB_MBALL) delete_mball();
else if (G.obedit->type==OB_ARMATURE) delete_armature();
}
+ else if(G.f & G_PARTICLEEDIT){
+ PE_delete_particle();
+ }
else delete_obj(0);
}
@@ -1805,9 +1932,9 @@ void duplicate_context_selected(void)
else if(G.obedit->type==OB_MBALL) adduplicate_mball();
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) adduplicate_nurb();
}
- else {
+ else if(G.f & G_PARTICLEEDIT);
+ else
adduplicate(0, U.dupflag);
- }
}
void toggle_shading(void)
@@ -1844,7 +1971,7 @@ int minmax_verts(float *min, float *max)
tottrans=0;
if ELEM5(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE)
- make_trans_verts(bmat[0], bmat[1], 0);
+ make_trans_verts(bmat[0], bmat[1], 2);
if(tottrans==0) return 0;
Mat3CpyMat4(bmat, G.obedit->obmat);
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 1b0429abda2..d6d748f2213 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -25,12 +25,13 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung (major rewrite of Action Editor)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <string.h>
+#include <stddef.h>
#include <math.h>
#include "MEM_guardedalloc.h"
@@ -80,10 +81,12 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BIF_transform.h"
#include "BSE_edit.h"
#include "BSE_drawipo.h"
#include "BSE_headerbuttons.h"
+#include "BSE_editaction_types.h"
#include "BSE_editipo.h"
#include "BSE_time.h"
#include "BSE_trans_types.h"
@@ -95,65 +98,61 @@
#include "blendef.h"
#include "nla.h"
-/* Local Function prototypes, are forward needed */
-static void hilight_channel (bAction *act, bActionChannel *achan, short select);
+/* **************************************************** */
+/* ACTION API */
-/* messy call... */
-static void select_poseelement_by_name (char *name, int select)
+/* this function adds a new Action block */
+bAction *add_empty_action (char *name)
{
- /* Syncs selection of channels with selection of object elements in posemode */
- Object *ob= OBACT;
- bPoseChannel *pchan;
+ bAction *act;
- if (!ob || ob->type!=OB_ARMATURE)
- return;
+ act= alloc_libblock(&G.main->action, ID_AC, name);
+ act->id.flag |= LIB_FAKEUSER;
+ act->id.us++;
- if(select==2) {
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
- pchan->bone->flag &= ~(BONE_ACTIVE);
- }
+ return act;
+}
+
+/* generic get current action call, for action window context */
+bAction *ob_get_action (Object *ob)
+{
+ bActionStrip *strip;
- pchan= get_pose_channel(ob->pose, name);
- if(pchan) {
- if(select)
- pchan->bone->flag |= (BONE_SELECTED);
- else
- pchan->bone->flag &= ~(BONE_SELECTED);
- if(select==2)
- pchan->bone->flag |= (BONE_ACTIVE);
+ if(ob->action)
+ return ob->action;
+
+ for (strip=ob->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT)
+ return strip->act;
}
+ return NULL;
}
-/* apparently within active object context */
-/* called extern, like on bone selection */
-void select_actionchannel_by_name (bAction *act, char *name, int select)
+/* used by ipo, outliner, buttons to find the active channel */
+bActionChannel *get_hilighted_action_channel (bAction *action)
{
bActionChannel *achan;
- if (!act)
- return;
+ if (!action)
+ return NULL;
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (!strcmp(achan->name, name)) {
- if (select) {
- achan->flag |= ACHAN_SELECTED;
- hilight_channel(act, achan, 1);
- }
- else {
- achan->flag &= ~ACHAN_SELECTED;
- hilight_channel(act, achan, 0);
- }
- return;
+ for (achan= action->chanbase.first; achan; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (SEL_ACHAN(achan) && (achan->flag & ACHAN_HILIGHTED))
+ return achan;
}
}
+
+ return NULL;
}
-/* called on changing action ipos or keys */
-void remake_action_ipos(bAction *act)
+/* ----------------------------------------- */
+
+void remake_action_ipos (bAction *act)
{
bActionChannel *achan;
bConstraintChannel *conchan;
- IpoCurve *icu;
+ IpoCurve *icu;
for (achan= act->chanbase.first; achan; achan= achan->next) {
if (achan->ipo) {
@@ -162,9 +161,9 @@ void remake_action_ipos(bAction *act)
testhandles_ipocurve(icu);
}
}
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (conchan->ipo) {
- for (icu = conchan->ipo->curve.first; icu; icu=icu->next){
+ for (icu = conchan->ipo->curve.first; icu; icu=icu->next) {
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
}
@@ -175,144 +174,504 @@ void remake_action_ipos(bAction *act)
synchronize_action_strips();
}
-static void remake_meshaction_ipos(Ipo *ipo)
-{
- /* this puts the bezier triples in proper
- * order and makes sure the bezier handles
- * aren't too strange.
- */
- IpoCurve *icu;
+/* **************************************************** */
+/* FILTER->EDIT STRUCTURES */
+/*
+ * This method involves generating a list of edit structures which enable
+ * tools to naively perform the actions they require without all the boiler-plate
+ * associated with loops within loops and checking for cases to ignore.
+ */
- for (icu = ipo->curve.first; icu; icu=icu->next) {
- sort_time_ipocurve(icu);
- testhandles_ipocurve(icu);
+/* this function allocates memory for a new bActListElem struct for the
+ * provided action channel-data.
+ */
+bActListElem *make_new_actlistelem (void *data, short datatype, void *owner, short ownertype)
+{
+ bActListElem *ale= NULL;
+
+ /* only allocate memory if there is data to convert */
+ if (data) {
+ /* allocate and set generic data */
+ ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
+
+ ale->data= data;
+ ale->type= datatype;
+ ale->owner= owner;
+ ale->ownertype= ownertype;
+
+ if ((owner) && (ownertype == ACTTYPE_ACHAN)) {
+ bActionChannel *ochan= (bActionChannel *)owner;
+ ale->grp= ochan->grp;
+ }
+ else
+ ale->grp= NULL;
+
+ /* do specifics */
+ switch (datatype) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)data;
+
+ ale->flag= agrp->flag;
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_GROUP;
+ }
+ break;
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ ale->flag= achan->flag;
+
+ if (achan->ipo) {
+ ale->key_data= achan->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ case ACTTYPE_CONCHAN2:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)data;
+
+ ale->flag= conchan->flag;
+
+ if (datatype == ACTTYPE_CONCHAN2) {
+ /* CONCHAN2 is a hack so that constraint-channels keyframes can be edited */
+ if (conchan->ipo) {
+ ale->key_data= conchan->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ else {
+ if (conchan->ipo && conchan->ipo->curve.first) {
+ /* we assume that constraint ipo blocks only have 1 curve:
+ * INFLUENCE, so we pretend that a constraint channel is
+ * really just a Ipo-Curve channel instead.
+ */
+ ale->key_data= conchan->ipo->curve.first;
+ ale->datatype= ALE_ICU;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)data;
+
+ ale->flag= icu->flag;
+ ale->key_data= icu;
+ ale->datatype= ALE_ICU;
+ }
+ break;
+
+ case ACTTYPE_FILLIPO:
+ case ACTTYPE_FILLCON:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ if (datatype == ACTTYPE_FILLIPO)
+ ale->flag= FILTER_IPO_ACHAN(achan);
+ else
+ ale->flag= FILTER_CON_ACHAN(achan);
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ break;
+ case ACTTYPE_IPO:
+ {
+ ale->flag= 0;
+ ale->key_data= data;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ }
}
+
+ /* return created datatype */
+ return ale;
}
+
+/* ----------------------------------------- */
-static void meshkey_do_redraw(Key *key)
+static void actdata_filter_actionchannel (ListBase *act_data, bActionChannel *achan, int filter_mode)
{
- if(key->ipo)
- remake_meshaction_ipos(key->ipo);
-
- DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ bActListElem *ale;
+ bConstraintChannel *conchan;
+ IpoCurve *icu;
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-
+ /* only work with this channel and its subchannels if it is visible */
+ if (!(filter_mode & ACTFILTER_VISIBLE) || VISIBLE_ACHAN(achan)) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_ACHAN(achan)) {
+ /* check if this achan should only be included if it is selected */
+ if (!(filter_mode & ACTFILTER_SEL) || SEL_ACHAN(achan)) {
+ /* are we only interested in the ipo-curves? */
+ if ((filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(achan, ACTTYPE_ACHAN, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ else {
+ /* for insert key... this check could be improved */
+ return;
+ }
+
+ /* check if expanded - if not, continue on to next action channel */
+ if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ACTFILTER_ONLYICU)==0) {
+ /* only exit if we don't need to include constraint channels for group-channel keyframes */
+ if ( !(filter_mode & ACTFILTER_IPOKEYS) || (achan->grp == NULL) || (EXPANDED_AGRP(achan->grp)==0) )
+ return;
+ }
+
+ /* ipo channels */
+ if ((achan->ipo) && (filter_mode & ACTFILTER_IPOKEYS)==0) {
+ /* include ipo-expand widget? */
+ if ((filter_mode & ACTFILTER_CHANNELS) && (filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(achan, ACTTYPE_FILLIPO, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+
+ /* add ipo-curve channels? */
+ if (FILTER_IPO_ACHAN(achan) || (filter_mode & ACTFILTER_ONLYICU)) {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_actlistelem(icu, ACTTYPE_ICU, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+
+ /* constraint channels */
+ if (achan->constraintChannels.first) {
+ /* include constraint-expand widget? */
+ if ( (filter_mode & ACTFILTER_CHANNELS) && !(filter_mode & ACTFILTER_ONLYICU)
+ && !(filter_mode & ACTFILTER_IPOKEYS) )
+ {
+ ale= make_new_actlistelem(achan, ACTTYPE_FILLCON, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+
+ /* add constraint channels? */
+ if (FILTER_CON_ACHAN(achan) || (filter_mode & ACTFILTER_ONLYICU)) {
+ /* loop through constraint channels, checking and adding them */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_CONCHAN(conchan)) {
+ /* check if this conchan should only be included if it is selected */
+ if (!(filter_mode & ACTFILTER_SEL) || SEL_CONCHAN(conchan)) {
+ if (filter_mode & ACTFILTER_IPOKEYS) {
+ ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN2, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ else {
+ ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
-void duplicate_meshchannel_keys(Key *key)
+static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
{
- duplicate_ipo_keys(key->ipo);
- transform_meshchannel_keys('g', key);
+ bActListElem *ale;
+ bActionGroup *agrp;
+ bActionChannel *achan, *lastchan=NULL;
+
+ /* loop over groups */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ /* add this group as a channel first */
+ if (!(filter_mode & ACTFILTER_ONLYICU) && !(filter_mode & ACTFILTER_IPOKEYS)) {
+ /* check if filtering by selection */
+ if ( !(filter_mode & ACTFILTER_SEL) || SEL_AGRP(agrp) ) {
+ ale= make_new_actlistelem(agrp, ACTTYPE_GROUP, NULL, ACTTYPE_NONE);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+
+ /* store reference to last channel of group */
+ if (agrp->channels.last)
+ lastchan= agrp->channels.last;
+
+
+ /* there are some situations, where only the channels of the active group should get considered */
+ if (!(filter_mode & ACTFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
+ /* filters here are a bit convoulted...
+ * - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes
+ * - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed)
+ */
+ if ( (!(filter_mode & ACTFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) ||
+ (filter_mode & (ACTFILTER_IPOKEYS|ACTFILTER_ONLYICU)) )
+ {
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ actdata_filter_actionchannel(act_data, achan, filter_mode);
+ }
+ }
+ }
+ }
+ }
+
+ /* loop over un-grouped action channels (only if we're not only considering those channels in the active group) */
+ if (!(filter_mode & ACTFILTER_ACTGROUPED)) {
+ for (achan=(lastchan)?lastchan->next:act->chanbase.first; achan; achan=achan->next) {
+ actdata_filter_actionchannel(act_data, achan, filter_mode);
+ }
+ }
}
-void duplicate_actionchannel_keys(void)
+static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mode)
{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- act=G.saction->action;
- if (!act)
- return;
-
- /* Find selected items */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- duplicate_ipo_keys(achan->ipo);
+ bActListElem *ale;
+ KeyBlock *kb;
+ IpoCurve *icu;
+ int i;
+
+ /* are we filtering for display or editing */
+ if (filter_mode & ACTFILTER_FORDRAWING) {
+ /* for display - loop over shapekeys, adding ipo-curve references where needed */
+ kb= key->block.first;
+
+ /* loop through possible shapekeys, manually creating entries */
+ for (i= 1; i < key->totkey; i++) {
+ ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
+ kb = kb->next;
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- duplicate_ipo_keys(conchan->ipo);
+ ale->data= kb;
+ ale->type= ACTTYPE_SHAPEKEY; /* 'abused' usage of this type */
+ ale->owner= key;
+ ale->ownertype= ACTTYPE_SHAPEKEY;
+ ale->datatype= ALE_NONE;
+ ale->index = i;
+
+ if (key->ipo) {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ if (icu->adrcode == i) {
+ ale->key_data= icu;
+ ale->datatype= ALE_ICU;
+ break;
+ }
+ }
+ }
+
+ BLI_addtail(act_data, ale);
+ }
+ }
+ else {
+ /* loop over ipo curves if present - for editing */
+ if (key->ipo) {
+ if (filter_mode & ACTFILTER_IPOKEYS) {
+ ale= make_new_actlistelem(key->ipo, ACTTYPE_IPO, key, ACTTYPE_SHAPEKEY);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ else {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_actlistelem(icu, ACTTYPE_ICU, key, ACTTYPE_SHAPEKEY);
+ if (ale) BLI_addtail(act_data, ale);
}
}
}
}
+}
+
+/* This function filters the active data source to leave only the desired
+ * data types. 'Public' api call.
+ * *act_data: is a pointer to a ListBase, to which the filtered action data
+ * will be placed for use.
+ * filter_mode: how should the data be filtered - bitmapping accessed flags
+ */
+void actdata_filter (ListBase *act_data, int filter_mode, void *data, short datatype)
+{
+ /* only filter data if there's somewhere to put it */
+ if (data && act_data) {
+ bActListElem *ale, *next;
+
+ /* firstly filter the data */
+ switch (datatype) {
+ case ACTCONT_ACTION:
+ actdata_filter_action(act_data, data, filter_mode);
+ break;
+ case ACTCONT_SHAPEKEY:
+ actdata_filter_shapekey(act_data, data, filter_mode);
+ break;
+ }
+
+ /* remove any weedy entries */
+ for (ale= act_data->first; ale; ale= next) {
+ next= ale->next;
+
+ if (ale->type == ACTTYPE_NONE)
+ BLI_freelinkN(act_data, ale);
+
+ if (filter_mode & ACTFILTER_IPOKEYS) {
+ if (ale->datatype != ALE_IPO)
+ BLI_freelinkN(act_data, ale);
+ else if (ale->key_data == NULL)
+ BLI_freelinkN(act_data, ale);
+ }
+ }
+ }
+}
+
+/* **************************************************** */
+/* GENERAL ACTION TOOLS */
+
+/* gets the key data from the currently selected
+ * mesh/lattice. If a mesh is not selected, or does not have
+ * key data, then we return NULL (currently only
+ * returns key data for RVK type meshes). If there
+ * is an action that is pinned, return null
+ */
+/* Note: there's a similar function in key.c (ob_get_key) */
+Key *get_action_mesh_key(void)
+{
+ Object *ob;
+ Key *key;
+
+ ob = OBACT;
+ if (ob == NULL)
+ return NULL;
+
+ if (G.saction->pin) return NULL;
+
+ if (ob->type==OB_MESH)
+ key = ((Mesh *)ob->data)->key;
+ else if (ob->type==OB_LATTICE)
+ key = ((Lattice *)ob->data)->key;
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF))
+ key= ((Curve *)ob->data)->key;
+ else
+ return NULL;
+
+ if (key) {
+ if (key->type == KEY_RELATIVE)
+ return key;
+ }
+
+ return NULL;
+}
+
+/* TODO: kill this! */
+int get_nearest_key_num (Key *key, short *mval, float *x)
+{
+ /* returns the key num that cooresponds to the
+ * y value of the mouse click. Does not check
+ * if this is a valid keynum. Also gives the Ipo
+ * x coordinate.
+ */
+ int num;
+ float y;
- transform_actionchannel_keys ('g', 0);
+ areamouseco_to_ipoco(G.v2d, mval, x, &y);
+ num = (int) ((CHANNELHEIGHT/2 - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ return (num + 1);
}
-/* helper for get_nearest_[action,mesh]channel_key */
-static IpoCurve *get_nearest_icu_key (IpoCurve *curve, float *selx, short *sel, float xrange[])
+/* this function is used to get a pointer to an action or shapekey
+ * datablock, thus simplying that process.
+ */
+/* this function is intended for use */
+void *get_nearest_act_channel (short mval[], short *ret_type)
{
- /* try to find first beztriple in bounds that is selected */
- IpoCurve *icu, *firsticu=NULL;
- int foundsel=0;
- float firstvert=-1, foundx=-1;
- int i;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ int clickmin, clickmax;
+ float x,y;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) {
+ *ret_type= ACTTYPE_NONE;
+ return NULL;
+ }
+
+ areamouseco_to_ipoco(G.v2d, mval, &x, &y);
+ clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+ clickmax = clickmin;
- if (curve == NULL)
+ if (clickmax < 0) {
+ *ret_type= ACTTYPE_NONE;
return NULL;
+ }
- /* lets loop through the IpoCurves trying to find the closest bezier */
- for (icu= curve; icu ; icu= icu->next) {
- /* loop through the beziers in the curve */
- for (i=0; i<icu->totvert; i++) {
- /* Is this bezier in the right area? */
- if (icu->bezt[i].vec[1][0] > xrange[0] &&
- icu->bezt[i].vec[1][0] <= xrange[1] ) {
-
- /* if no other curves have been picked ... */
- if (firsticu==NULL) {
- /* mark this curve/bezier as the first selected */
- firsticu= icu;
- firstvert= icu->bezt[i].vec[1][0];
-
- /* sel = (is the bezier is already selected) ? 1 : 0; */
- *sel = (icu->bezt[i].f2 & 1);
- }
-
- /* if the bezier is selected ... */
- if (icu->bezt[i].f2 & 1) {
- /* if we haven't found a selected one yet ... */
- if (!foundsel) {
- /* record the found x value */
- foundsel=1;
- foundx = icu->bezt[i].vec[1][0];
-
- }
- }
-
- /* if the bezier is unselected and not at the x
- * position of a previous found selected bezier ...
- */
- else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
- /* lets return this found curve/bezier */
- *sel = 0;
- *selx= icu->bezt[i].vec[1][0];
- return icu;
- }
- }
+ /* filter data */
+ filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (clickmax < 0)
+ break;
+ if (clickmin <= 0) {
+ /* found match */
+ *ret_type= ale->type;
+ data= ale->data;
+
+ BLI_freelistN(&act_data);
+
+ return data;
}
+ --clickmin;
+ --clickmax;
}
- /* return what we've found */
- *selx=firstvert;
- return firsticu;
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ *ret_type= ACTTYPE_NONE;
+ return NULL;
}
-static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
+/* used only by mouse_action. It is used to find the location of the nearest
+ * keyframe to where the mouse clicked,
+ */
+static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
{
- bAction *act= G.saction->action;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
+ ListBase act_data = {NULL, NULL};
+ ListBase act_keys = {NULL, NULL};
+ bActListElem *ale;
+ ActKeyColumn *ak;
+ void *data;
+ short datatype;
+ int filter;
+
rctf rectf;
float xmin, xmax, x, y;
- float xrange[2];
int clickmin, clickmax;
short mval[2];
+ short found = 0;
getmouseco_areawin (mval);
/* action-channel */
*par= NULL;
- if (act == NULL) {
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
@@ -327,7 +686,7 @@ static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
/* if action is mapped in NLA, it returns a correction */
- if (G.saction->pin==0 && OBACT) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
xmin= get_action_frame(OBACT, rectf.xmin);
xmax= get_action_frame(OBACT, rectf.xmax);
}
@@ -340,1419 +699,1734 @@ static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_
*ret_type= ACTTYPE_NONE;
return NULL;
}
-
- xrange[0]= xmin;
- xrange[1]= xmax;
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0)
- break;
- if ((clickmin <= 0) && (achan->ipo)) {
- /* found level - action channel */
- icu= get_nearest_icu_key(achan->ipo->curve.first, selx, sel, xrange);
-
- *ret_type= ACTTYPE_ACHAN;
- return achan;
- }
- --clickmin;
- --clickmax;
- }
- else
- continue;
- if (EXPANDED_ACHAN(achan) == 0)
- continue;
-
- /* try in ipo curves */
- if (achan->ipo) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found level - ipo-curves show/hide */
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
- --clickmin;
- --clickmax;
+ /* filter data */
+ filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (clickmax < 0)
+ break;
+ if (clickmin <= 0) {
+ /* found match */
- /* now the ipo-curve channels if they are exposed */
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0)
+ /* make list of keyframes */
+ if (ale->key_data) {
+ switch (ale->datatype) {
+ case ALE_IPO:
+ {
+ Ipo *ipo= (Ipo *)ale->key_data;
+ ipo_to_keylist(ipo, &act_keys, NULL, NULL);
+ }
break;
- if (clickmin <= 0) {
- /* found level - ipo-curve channel */
- icu= get_nearest_icu_key (icu, selx, sel, xrange);
-
- *ret_type= ACTTYPE_ICU;
- *par= achan;
- return icu;
+ case ALE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+ icu_to_keylist(icu, &act_keys, NULL, NULL);
}
- --clickmin;
- --clickmax;
+ break;
}
}
- }
-
- /* try in constaint channels */
- if (achan->constraintChannels.first) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraints show/hide */
- *ret_type= ACTTYPE_NONE;
- return NULL;
+ else if (ale->type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= (bActionGroup *)ale->data;
+ agroup_to_keylist(agrp, &act_keys, NULL, NULL);
}
- --clickmin;
- --clickmax;
- /* now the constraint channels if they are exposed */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0)
- break;
- if ((clickmin <= 0) && (conchan->ipo)) {
- /* found match - constraint channel */
- icu= get_nearest_icu_key(conchan->ipo->curve.first, selx, sel, xrange);
-
- *ret_type= ACTTYPE_CONCHAN;
- *par= achan;
- return conchan;
- }
- --clickmin;
- --clickmax;
+ /* loop through keyframes, finding one that was clicked on */
+ for (ak= act_keys.first; ak; ak= ak->next) {
+ if (IN_RANGE(ak->cfra, xmin, xmax)) {
+ *selx= ak->cfra;
+ found= 1;
+ break;
}
}
+ /* no matching keyframe found - set to mean frame value so it doesn't actually select anything */
+ if (found == 0)
+ *selx= ((xmax+xmin) / 2);
+
+ /* figure out what to return */
+ if (datatype == ACTCONT_ACTION) {
+ *par= ale->owner; /* assume that this is an action channel */
+ *ret_type= ale->type;
+ data = ale->data;
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ data = ale->key_data;
+ *ret_type= ACTTYPE_ICU;
+ }
+
+ /* cleanup tempolary lists */
+ BLI_freelistN(&act_keys);
+ act_keys.first = act_keys.last = NULL;
+
+ BLI_freelistN(&act_data);
+
+ return data;
}
+ --clickmin;
+ --clickmax;
}
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
*ret_type= ACTTYPE_NONE;
return NULL;
}
-static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
+void *get_action_context (short *datatype)
{
- /* This function tries to find the RVK key that is
- * closest to the user's mouse click
- */
- Key *key;
- IpoCurve *icu;
- IpoCurve *firsticu=NULL;
- int foundsel=0;
- float firstvert=-1, foundx=-1;
- int i;
- short mval[2];
- float ymin, ymax, ybase;
- rctf rectf;
-
- *index=0;
-
- key = get_action_mesh_key();
-
- /* lets get the mouse position and process it so
- * we can start testing selections
- */
- getmouseco_areawin (mval);
- mval[0]-=7;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]+=14;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
- ybase += CHANNELHEIGHT/2;
- *sel=0;
-
- /* lets loop through the IpoCurves trying to find the closest bezier */
- if (!key->ipo) return NULL;
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- /* lets not deal with the "speed" Ipo */
- if (!icu->adrcode) continue;
-
- ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
- ymin = ymax - (CHANNELHEIGHT+CHANNELSKIP);
-
- /* Does this curve coorespond to the right
- * strip?
- */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
-
- /* loop through the beziers in the curve */
- for (i=0; i<icu->totvert; i++) {
-
- /* Is this bezier in the right area? */
- if (icu->bezt[i].vec[1][0] > rectf.xmin &&
- icu->bezt[i].vec[1][0] <= rectf.xmax ) {
-
- /* if no other curves have been picked ... */
- if (!firsticu){
- /* mark this curve/bezier as the first selected */
- firsticu=icu;
- firstvert=icu->bezt[i].vec[1][0];
-
- /* sel = (is the bezier is already selected) ? 1 : 0; */
- *sel = icu->bezt[i].f2 & 1;
- }
-
- /* if the bezier is selected ... */
- if (icu->bezt[i].f2 & 1){
- /* if we haven't found a selected one yet ... */
- if (!foundsel){
- /* record the found x value */
- foundsel=1;
- foundx = icu->bezt[i].vec[1][0];
- }
- }
-
- /* if the bezier is unselected and not at the x
- * position of a previous found selected bezier ...
- */
- else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
- /* lets return this found curve/bezier */
- *index=icu->bezt[i].vec[1][0];
- *sel = 0;
- return icu;
- }
- }
- }
- }
- }
+ bAction *act;
+ Key *key;
- /* return what we've found
- */
- *index=firstvert;
- return firsticu;
+ /* get pointers to active action/shapekey blocks */
+ act = (G.saction)? G.saction->action: NULL;
+ key = get_action_mesh_key();
+
+ if (act) {
+ *datatype= ACTCONT_ACTION;
+ return act;
+ }
+ else if (key) {
+ *datatype= ACTCONT_SHAPEKEY;
+ return key;
+ }
+ else {
+ *datatype= ACTCONT_NONE;
+ return NULL;
+ }
}
-/* This function makes a list of the selected keyframes
- * in the ipo curves it has been passed
- */
-static void make_sel_cfra_list(Ipo *ipo, ListBase *elems)
+/* **************************************************** */
+/* ACTION CHANNEL GROUPS */
+
+/* Get the active action-group for an Action */
+bActionGroup *get_active_actiongroup (bAction *act)
{
- IpoCurve *icu;
- BezTriple *bezt;
- int a;
+ bActionGroup *agrp= NULL;
- for(icu= ipo->curve.first; icu; icu= icu->next) {
-
- bezt= icu->bezt;
- if(bezt) {
- a= icu->totvert;
- while(a--) {
- if(bezt->f2 & 1) {
- add_to_cfra_elem(elems, bezt);
- }
- bezt++;
- }
+ if (act && act->groups.first) {
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ if (agrp->flag & AGRP_ACTIVE)
+ break;
}
}
+
+ return agrp;
}
-/* This function selects all key frames in the same column(s) as a already selected key(s)
- * this version only works for Shape Keys, Key should be not NULL
+/* Make the given Action-Group the active one */
+void set_active_actiongroup (bAction *act, bActionGroup *agrp, short select)
+{
+ bActionGroup *grp;
+
+ /* sanity checks */
+ if (act == NULL)
+ return;
+
+ /* Deactive all others */
+ for (grp= act->groups.first; grp; grp= grp->next) {
+ if ((grp==agrp) && (select))
+ grp->flag |= AGRP_ACTIVE;
+ else
+ grp->flag &= ~AGRP_ACTIVE;
+ }
+}
+
+/* Add given channel into (active) group
+ * - assumes that channel is not linked to anything anymore
+ * - always adds at the end of the group
*/
-void column_select_shapekeys(Key *key, int mode)
+static void action_groups_addachan (bAction *act, bActionGroup *agrp, bActionChannel *achan)
{
- if(key && key->ipo) {
- IpoCurve *icu;
- ListBase elems= {NULL, NULL};
- CfraElem *ce;
+ bActionChannel *chan;
+ short done=0;
+
+ /* sanity checks */
+ if (ELEM3(NULL, act, agrp, achan))
+ return;
+
+ /* if no channels, just add to two lists at the same time */
+ if (act->chanbase.first == NULL) {
+ achan->next = achan->prev = NULL;
- /* build list of columns */
- switch (mode) {
- case 1:
- /* create a list of all selected keys */
- make_sel_cfra_list(key->ipo, &elems);
+ agrp->channels.first = agrp->channels.last = achan;
+ act->chanbase.first = act->chanbase.last = achan;
+
+ achan->grp= agrp;
+ return;
+ }
+
+ /* try to find a channel to slot this in before/after */
+ for (chan= act->chanbase.first; chan; chan= chan->next) {
+ /* if channel has no group, then we have ungrouped channels, which should always occur after groups */
+ if (chan->grp == NULL) {
+ BLI_insertlinkbefore(&act->chanbase, chan, achan);
+
+ if (agrp->channels.first == NULL)
+ agrp->channels.first= achan;
+ agrp->channels.last= achan;
+
+ done= 1;
+ break;
+ }
+
+ /* if channel has group after current, we can now insert (otherwise we have gone too far) */
+ else if (chan->grp == agrp->next) {
+ BLI_insertlinkbefore(&act->chanbase, chan, achan);
+
+ if (agrp->channels.first == NULL)
+ agrp->channels.first= achan;
+ agrp->channels.last= achan;
+
+ done= 1;
+ break;
+ }
+
+ /* if channel has group we're targeting, check whether it is the last one of these */
+ else if (chan->grp == agrp) {
+ if ((chan->next) && (chan->next->grp != agrp)) {
+ BLI_insertlinkafter(&act->chanbase, chan, achan);
+ agrp->channels.last= achan;
+ done= 1;
break;
- case 2:
- /* create a list of all selected markers */
- make_marker_cfra_list(&elems, 1);
+ }
+ else if (chan->next == NULL) {
+ BLI_addtail(&act->chanbase, achan);
+ agrp->channels.last= achan;
+ done= 1;
break;
+ }
}
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- BezTriple *bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
- if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
+ /* if channel has group before target, check whether the next one is something after target */
+ else if (chan->grp == agrp->prev) {
+ if (chan->next) {
+ if ((chan->next->grp != chan->grp) && (chan->next->grp != agrp)) {
+ BLI_insertlinkafter(&act->chanbase, chan, achan);
+
+ agrp->channels.first= achan;
+ agrp->channels.last= achan;
+
+ done= 1;
+ break;
}
}
+ else {
+ BLI_insertlinkafter(&act->chanbase, chan, achan);
+
+ agrp->channels.first= achan;
+ agrp->channels.last= achan;
+
+ done= 1;
+ break;
+ }
}
-
- BLI_freelistN(&elems);
}
-}
+
+ /* only if added, set channel as belonging to this group */
+ if (done) {
+ achan->grp= agrp;
+ }
+ else
+ printf("Error: ActionChannel: '%s' couldn't be added to Group: '%s' \n", achan->name, agrp->name);
+}
-/* This function selects all key frames in the same column(s) as a already selected key(s)
- * this version only works for on Action. *act should be not NULL
- */
-void column_select_actionkeys(bAction *act, int mode)
+/* Remove the given channel from all groups */
+static void action_groups_removeachan (bAction *act, bActionChannel *achan)
{
- IpoCurve *icu;
- BezTriple *bezt;
- ListBase elems= {NULL, NULL};
- CfraElem *ce;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- if (!act)
+ /* sanity checks */
+ if (ELEM(NULL, act, achan))
return;
- /* build list of columns */
- switch (mode) {
- case 1:
- /* create a list of all selected keys */
- for (achan=act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (achan->ipo)
- make_sel_cfra_list(achan->ipo, &elems);
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo)
- make_sel_cfra_list(conchan->ipo, &elems);
- }
- }
- }
- }
- break;
- case 2:
- /* create a list of all selected markers */
- make_marker_cfra_list(&elems, 1);
-
- /* apply scaled action correction if needed */
- if (G.saction->pin==0 && OBACT) {
- for (ce= elems.first; ce; ce= ce->next)
- ce->cfra= get_action_frame(OBACT, ce->cfra);
- }
- break;
- }
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if(VISIBLE_ACHAN(achan)) {
- if (achan->ipo) {
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = achan->ipo->curve.first; icu; icu = icu->next){
- bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
-
- if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
- }
- }
- }
+ /* check if any group used this directly */
+ if (achan->grp) {
+ bActionGroup *agrp= achan->grp;
+
+ if (agrp->channels.first == agrp->channels.last) {
+ if (agrp->channels.first == achan) {
+ agrp->channels.first= NULL;
+ agrp->channels.last= NULL;
}
-
- if (EXPANDED_ACHAN(achan) == 0 || (FILTER_CON_ACHAN(achan)))
- continue;
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo) {
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = conchan->ipo->curve.first; icu; icu = icu->next){
- bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
-
- if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
- }
- }
- }
- }
- }
}
+ else if (agrp->channels.first == achan) {
+ if ((achan->next) && (achan->next->grp==agrp))
+ agrp->channels.first= achan->next;
+ else
+ agrp->channels.first= NULL;
+ }
+ else if (agrp->channels.last == achan) {
+ if ((achan->prev) && (achan->prev->grp==agrp))
+ agrp->channels.last= achan->prev;
+ else
+ agrp->channels.last= NULL;
+ }
+
+ achan->grp= NULL;
}
- BLI_freelistN(&elems);
+
+ /* now just remove from list */
+ BLI_remlink(&act->chanbase, achan);
}
-/* apparently within active object context */
-static void mouse_action(int selectmode)
+/* Add a new Action-Group or add channels to active one */
+void action_groups_group (short add_group)
{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
- TimeMarker *marker;
- void *act_channel;
- short sel, act_type;
- float selx;
+ bAction *act;
+ bActionChannel *achan, *anext;
+ bActionGroup *agrp;
+ void *data;
+ short datatype;
- act=G.saction->action;
- if (!act)
- return;
-
- act_channel= get_nearest_actionchannel_key(&selx, &sel, &act_type, &achan);
- marker=find_nearest_marker(1);
-
- if (act_channel) {
- switch (act_type) {
- case ACTTYPE_ICU:
- icu= (IpoCurve *)act_channel;
- break;
- case ACTTYPE_CONCHAN:
- conchan= (bConstraintChannel *)act_channel;
- break;
- default:
- achan= (bActionChannel *)act_channel;
- }
+ /* validate type of data we are working on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* get active group */
+ if ((act->groups.first==NULL) || (add_group)) {
+ /* Add a new group, and make it active */
+ agrp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
- if (selectmode == SELECT_REPLACE) {
- selectmode = SELECT_ADD;
-
- deselect_actionchannel_keys(act, 0, 0);
- deselect_actionchannels(act, 0);
-
- achan->flag |= ACHAN_SELECTED;
- hilight_channel (act, achan, 1);
- select_poseelement_by_name(achan->name, 2); /* 2 is activate */
- }
+ agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED|AGRP_EXPANDED);
+ sprintf(agrp->name, "Group");
- if (icu)
- select_icu_key(icu, selx, selectmode);
- else if (conchan)
- select_ipo_key(conchan->ipo, selx, selectmode);
- else
- select_ipo_key(achan->ipo, selx, selectmode);
+ BLI_addtail(&act->groups, agrp);
+ BLI_uniquename(&act->groups, agrp, "Group", offsetof(bActionGroup, name), 32);
- std_rmouse_transform(transform_actionchannel_keys);
+ set_active_actiongroup(act, agrp, 1);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWBUTSALL, 0);
+ add_group= 1;
}
- else if (marker) {
- /* not channel, so maybe marker */
- if (selectmode == SELECT_REPLACE) {
- deselect_markers(0, 0);
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_INVERT) {
- if (marker->flag & SELECT)
- marker->flag &= ~SELECT;
- else
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_ADD)
- marker->flag |= SELECT;
- else if (selectmode == SELECT_SUBTRACT)
- marker->flag &= ~SELECT;
+ else {
+ agrp= get_active_actiongroup(act);
- std_rmouse_transform(transform_markers);
+ if (agrp == NULL) {
+ error("No Active Action Group");
+ return;
+ }
+ }
+
+ /* loop through action-channels, finding those that are selected + visible to move */
+ // FIXME: this should be done with action api instead
+ for (achan= act->chanbase.first; achan; achan= anext) {
+ anext= achan->next;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ /* make sure not already in new-group */
+ if (achan->grp != agrp) {
+ if ((achan->grp==NULL) || (EXPANDED_AGRP(achan->grp))) {
+ if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
+ /* unlink from everything else */
+ action_groups_removeachan(act, achan);
+
+ /* add to end of group's channels */
+ action_groups_addachan(act, agrp, achan);
+ }
+ }
+ }
}
+
+ /* updates and undo */
+ if (add_group)
+ BIF_undo_push("Add Action Group");
+ else
+ BIF_undo_push("Add to Action Group");
+
+ allqueue(REDRAWACTION, 0);
}
-static void mouse_mesh_action(int selectmode, Key *key)
+/* Remove selected channels from their groups */
+void action_groups_ungroup (void)
{
- /* Handle a right mouse click selection in an
- * action window displaying RVK data
- */
-
- IpoCurve *icu;
- TimeMarker *marker;
- short sel;
- float selx;
- short mval[2];
-
- /* going to assume that the only reason
- * we got here is because it has been
- * determined that we are a mesh with
- * the right properties (i.e., have key
- * data, etc)
- */
-
- marker= find_nearest_marker(1);
-
- /* get the click location, and the cooresponding
- * ipo curve and selection time value
- */
- getmouseco_areawin (mval);
- icu = get_nearest_meshchannel_key(&selx, &sel);
-
- if (icu) {
- if (selectmode == SELECT_REPLACE) {
- /* if we had planned to replace the
- * selection, then we will first deselect
- * all of the keys, and if the clicked on
- * key had been unselected, we will select
- * it, otherwise, we are done.
- */
- deselect_meshchannel_keys(key, 0, 0);
-
- if (sel == 0)
- selectmode = SELECT_ADD;
- else
- /* the key is selected so we should
- * deselect -- but everything is now deselected
- * so we are done.
- */
- return;
- }
-
- /* select the key using the given mode
- * and redraw as mush stuff as needed.
- */
- select_icu_key(icu, selx, selectmode);
-
- BIF_undo_push("Select Action key");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-
- }
- else if (marker) {
- /* not channel, so maybe marker */
- if (selectmode == SELECT_REPLACE) {
- deselect_markers(0, 0);
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_INVERT) {
- if (marker->flag & SELECT)
- marker->flag &= ~SELECT;
- else
- marker->flag |= SELECT;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ bAction *act;
+ void *data;
+ short datatype;
+ short filter;
+
+ /* validate type of data we are working on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE|ACTFILTER_SEL);
+ actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
+
+ /* Only ungroup selected action-channels */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (ale->type == ACTTYPE_ACHAN) {
+ action_groups_removeachan(act, ale->data);
+ BLI_addtail(&act->chanbase, ale->data);
}
- else if (selectmode == SELECT_ADD)
- marker->flag |= SELECT;
- else if (selectmode == SELECT_SUBTRACT)
- marker->flag &= ~SELECT;
-
- std_rmouse_transform(transform_markers);
-
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
}
+
+ BLI_freelistN(&act_data);
+
+ /* updates and undo */
+ BIF_undo_push("Remove From Action Groups");
+
+ allqueue(REDRAWACTION, 0);
}
-void borderselect_action(void)
-{
- rcti rect;
- rctf rectf;
- bAction *act;
+/* This function is used when inserting keyframes for pose-channels. It assigns the
+ * action-channel with the nominated name to a group with the same name as that of
+ * the pose-channel with the nominated name.
+ *
+ * Note: this function calls validate_action_channel if action channel doesn't exist
+ */
+void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
+{
bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- int val, selectmode;
- int (*select_function)(BezTriple *);
- short mval[2];
- float ymin, ymax;
+ bPoseChannel *pchan;
- act=G.saction->action;
-
- if (!act)
+ /* sanity checks */
+ if (ELEM3(NULL, act, pose, name))
return;
-
- if ( (val = get_border(&rect, 3)) ) {
- if (val == LEFTMOUSE) {
- selectmode = SELECT_ADD;
- select_function = select_bezier_add;
+ if (name[0] == 0)
+ return;
+
+ /* try to get the channels */
+ pchan= get_pose_channel(pose, name);
+ if (pchan == NULL) return;
+ achan= verify_action_channel(act, name);
+
+ /* check if pchan has a group */
+ if ((pchan->agrp_index) && (achan->grp == NULL)) {
+ bActionGroup *agrp, *grp=NULL;
+
+ /* get group to try to be like */
+ agrp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+ if (agrp == NULL) {
+ error("PoseChannel has invalid group!");
+ return;
}
- else {
- selectmode = SELECT_SUBTRACT;
- select_function = select_bezier_subtract;
+
+ /* try to find a group which is similar to the one we want (or add one) */
+ for (grp= act->groups.first; grp; grp= grp->next) {
+ if (!strcmp(grp->name, agrp->name))
+ break;
}
+ if (grp == NULL) {
+ grp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- /* if action is mapped in NLA, it returns a correction */
- if (G.saction->pin==0 && OBACT) {
- rectf.xmin= get_action_frame(OBACT, rectf.xmin);
- rectf.xmax= get_action_frame(OBACT, rectf.xmax);
+ grp->flag |= (AGRP_ACTIVE|AGRP_SELECTED|AGRP_EXPANDED);
+ sprintf(grp->name, agrp->name);
+
+ BLI_addtail(&act->groups, grp);
}
- ymax = CHANNELHEIGHT/2;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- /* Check action channel */
- ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
- ymax=ymin;
-
- if (EXPANDED_ACHAN(achan)) {
- /* check ipo - although the action channel has already been checked,
- * selection may have started below that channel
- */
- if (achan->ipo) {
- /* skip the widget*/
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- ymax= ymin;
-
- if (FILTER_IPO_ACHAN(achan)) {
- /* check ipo-curve channels */
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_icu_key(icu, rectf.xmin, rectf.xmax, select_function);
-
- ymax=ymin;
- }
- }
- }
-
- /* Check constraints */
- if (achan->constraintChannels.first) {
- /* skip the widget*/
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- ymax= ymin;
-
- /* check constraint channels */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
-
- ymax=ymin;
- }
- }
- }
- }
- }
- }
-
- BIF_undo_push("Border Select Action");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
+ /* make sure this channel is definitely not connected to anything before adding to group */
+ action_groups_removeachan(act, achan);
+ action_groups_addachan(act, grp, achan);
}
}
-void borderselect_mesh(Key *key)
-{
- rcti rect;
- int val, adrcodemax, adrcodemin;
- short mval[2];
- float xmin, xmax;
- int selectmode;
- int (*select_function)(BezTriple *);
- IpoCurve *icu;
+/* **************************************************** */
+/* TRANSFORM TOOLS */
+
+/* main call to start transforming keyframes */
+void transform_action_keys (int mode, int dummy)
+{
+ void *data;
+ short datatype;
+ short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
- if ( (val = get_border(&rect, 3)) ){
- /* set the selection function based on what
- * mouse button had been used in the border
- * select
- */
- if (val == LEFTMOUSE) {
- selectmode = SELECT_ADD;
- select_function = select_bezier_add;
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ switch (mode) {
+ case 'g':
+ {
+ initTransform(TFM_TIME_TRANSLATE, context);
+ Transform();
}
- else {
- selectmode = SELECT_SUBTRACT;
- select_function = select_bezier_subtract;
- }
-
- /* get the minimum and maximum adrcode numbers
- * for the IpoCurves (this is the number that
- * relates an IpoCurve to the keyblock it
- * controls).
- */
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- adrcodemax = get_nearest_key_num(key, mval, &xmin);
- adrcodemax = (adrcodemax >= key->totkey) ? key->totkey : adrcodemax;
-
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- adrcodemin = get_nearest_key_num(key, mval, &xmax);
- adrcodemin = (adrcodemin < 1) ? 1 : adrcodemin;
-
- /* Lets loop throug the IpoCurves and do borderselect
- * on the curves with adrcodes in our selected range.
- */
- if(key->ipo) {
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- /* lets not deal with the "speed" Ipo
- */
- if (!icu->adrcode) continue;
- if ( (icu->adrcode >= adrcodemin) &&
- (icu->adrcode <= adrcodemax) ) {
- borderselect_icu_key(icu, xmin, xmax, select_function);
- }
- }
+ break;
+ case 's':
+ {
+ initTransform(TFM_TIME_SCALE, context);
+ Transform();
}
-
- /* redraw stuff */
- BIF_undo_push("Border select Action Key");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
+ break;
+ case 't':
+ {
+ initTransform(TFM_TIME_SLIDE, context);
+ Transform();
+ }
+ break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, context);
+ Transform();
+ }
+ break;
}
-}
+}
-/* ******************** action API ***************** */
+/* ----------------------------------------- */
-/* generic get current action call, for action window context */
-bAction *ob_get_action(Object *ob)
+/* duplicate keyframes */
+void duplicate_action_keys (void)
{
- bActionStrip *strip;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
- if(ob->action)
- return ob->action;
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
- for (strip=ob->nlastrips.first; strip; strip=strip->next){
- if (strip->flag & ACTSTRIP_SELECT)
- return strip->act;
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and duplicate selected keys */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ duplicate_ipo_keys((Ipo *)ale->key_data);
}
- return NULL;
+
+ /* free filtered list */
+ BLI_freelistN(&act_data);
+
+ /* now, go into transform-grab mode, to move keys */
+ BIF_TransformSetUndo("Add Duplicate");
+ transform_action_keys('g', 0);
}
-/* used by ipo, outliner, buttons to find the active channel */
-bActionChannel *get_hilighted_action_channel(bAction *action)
+/* this function is responsible for snapping the current frame to selected data */
+void snap_cfra_action()
{
- bActionChannel *achan;
-
- if (!action)
- return NULL;
-
- for (achan= action->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && achan->flag & ACHAN_HILIGHTED)
- return achan;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* snap current frame to selected data */
+ snap_cfra_ipo_keys(NULL, -1);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ snap_cfra_ipo_keys(ale->key_data, 0);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
+ else
+ snap_cfra_ipo_keys(ale->key_data, 0);
}
+ BLI_freelistN(&act_data);
+
+ snap_cfra_ipo_keys(NULL, 1);
+
+ BIF_undo_push("Snap Current Frame to Keys");
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- return NULL;
-
+/* this function is responsible for snapping keyframes to frame-times */
+void snap_action_keys(short mode)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ char str[32];
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* determine mode */
+ switch (mode) {
+ case 1:
+ strcpy(str, "Snap Keys To Nearest Frame");
+ break;
+ case 2:
+ if (G.saction->flag & SACTION_DRAWTIME)
+ strcpy(str, "Snap Keys To Current Time");
+ else
+ strcpy(str, "Snap Keys To Current Frame");
+ break;
+ case 3:
+ strcpy(str, "Snap Keys To Nearest Marker");
+ break;
+ case 4:
+ strcpy(str, "Snap Keys To Nearest Second");
+ break;
+ default:
+ return;
+ }
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* snap to frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ snap_ipo_keys(ale->key_data, mode);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
+ }
+ else
+ snap_ipo_keys(ale->key_data, mode);
+ }
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-bAction *add_empty_action(char *name)
+/* this function is responsible for snapping keyframes to frame-times */
+void mirror_action_keys(short mode)
{
- bAction *act;
- /*
- if(blocktype==ID_OB)
- str= "ObAction";
- else if(blocktype==ID_KE)
- str= "ShapeAction";
- */
- act= alloc_libblock(&G.main->action, ID_AC, name);
- act->id.flag |= LIB_FAKEUSER;
- act->id.us++;
- return act;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ char str[32];
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* determine mode */
+ switch (mode) {
+ case 1:
+ strcpy(str, "Mirror Keys Over Current Frame");
+ break;
+ case 2:
+ strcpy(str, "Mirror Keys Over Y-Axis");
+ break;
+ case 3:
+ strcpy(str, "Mirror Keys Over X-Axis");
+ break;
+ case 4:
+ strcpy(str, "Mirror Keys Over Marker");
+ break;
+ default:
+ return;
+ }
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* mirror */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ mirror_ipo_keys(ale->key_data, mode);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
+ }
+ else
+ mirror_ipo_keys(ale->key_data, mode);
+ }
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-void transform_actionchannel_keys(int mode, int dummy)
+/* **************************************************** */
+/* ADD/REMOVE KEYFRAMES */
+
+/* This function allows the user to insert keyframes on the current
+ * frame from the Action Editor, using the current values of the channels
+ * to be keyframed.
+ */
+void insertkey_action(void)
{
- bAction *act;
- TransVert *tv;
+ void *data;
+ short datatype;
+
Object *ob= OBACT;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- float deltax, startx;
- float minx, maxx, cenf[2];
- float sval[2], cval[2], lastcval[2]={0,0};
- float fac=0.0f;
- int loop=1;
- int tvtot=0;
- int invert=0, firsttime=1;
- int i;
- short cancel=0;
- short mvals[2], mvalc[2], cent[2];
- char str[256];
-
- act=G.saction->action;
- if(act==NULL) return;
-
- /* Ensure that partial selections result in beztriple selections */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- tvtot+=fullselect_ipo_keys(achan->ipo);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot+=fullselect_ipo_keys(conchan->ipo);
- }
+ short mode;
+ float cfra;
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+ cfra = frame_to_float(CFRA);
+
+ if (datatype == ACTCONT_ACTION) {
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+
+ /* ask user what to keyframe */
+ mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2|In Active Group%x3");
+ if (mode <= 0) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU );
+ if (mode == 2) filter |= ACTFILTER_SEL;
+ else if (mode == 3) filter |= ACTFILTER_ACTGROUPED;
+
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through ipo curves retrieved */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ /* verify that this is indeed an ipo curve */
+ if (ale->key_data && ale->owner) {
+ bActionChannel *achan= (bActionChannel *)ale->owner;
+ bConstraintChannel *conchan= (ale->type==ACTTYPE_CONCHAN) ? ale->data : NULL;
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+
+ if (ob)
+ insertkey((ID *)ob, icu->blocktype, achan->name, ((conchan)?(conchan->name):(NULL)), icu->adrcode, 0);
+ else
+ insert_vert_icu(icu, cfra, icu->curval, 0);
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ Key *key= (Key *)data;
+ IpoCurve *icu;
+
+ /* ask user if they want to insert a keyframe */
+ mode = okee("Insert Keyframe?");
+ if (mode <= 0) return;
+
+ if (key->ipo) {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ insert_vert_icu(icu, cfra, icu->curval, 0);
}
}
}
- /* If nothing is selected, bail out */
- if (!tvtot)
- return;
+ BIF_undo_push("Insert Key");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
+/* delete selected keyframes */
+void delete_action_keys (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+ /* loop through filtered data and delete selected keys */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ delete_ipo_keys((Ipo *)ale->key_data);
+ }
+
+ /* free filtered list */
+ BLI_freelistN(&act_data);
- /* Build the transvert structure */
- tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
- tvtot=0;
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if(EDITABLE_ACHAN(achan)) {
- tvtot = add_trans_ipo_keys(achan->ipo, tv, tvtot);
+ BIF_undo_push("Delete Action Keys");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
+/* delete selected action-channels (only achans and conchans are considered) */
+void delete_action_channels (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale, *next;
+ bAction *act;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* deal with groups first */
+ if (act->groups.first) {
+ bActionGroup *agrp, *grp;
+ bActionChannel *chan, *nchan;
+
+ /* unlink achan's that belonged to this group (and make sure they're not selected if they weren't visible) */
+ for (agrp= act->groups.first; agrp; agrp= grp) {
+ grp= agrp->next;
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot);
+ /* remove if group is selected */
+ if (SEL_AGRP(agrp)) {
+ for (chan= agrp->channels.first; chan && chan->grp==agrp; chan= nchan) {
+ nchan= chan->next;
+
+ action_groups_removeachan(act, chan);
+ BLI_addtail(&act->chanbase, chan);
+
+ if (EXPANDED_AGRP(agrp) == 0)
+ chan->flag &= ~(ACHAN_SELECTED|ACHAN_HILIGHTED);
}
+
+ BLI_freelinkN(&act->groups, agrp);
}
}
}
- /* min max, only every other three */
- minx= maxx= tv[1].loc[0];
- for (i=1; i<tvtot; i+=3){
- if(minx>tv[i].loc[0]) minx= tv[i].loc[0];
- if(maxx<tv[i].loc[0]) maxx= tv[i].loc[0];
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_CHANNELS | ACTFILTER_SEL);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* remove irrelevant entries */
+ for (ale= act_data.first; ale; ale= next) {
+ next= ale->next;
+
+ if (ale->type != ACTTYPE_ACHAN)
+ BLI_freelinkN(&act_data, ale);
}
- /* Do the event loop */
- cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
- cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
- areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
-
- getmouseco_areawin (mvals);
- areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
+ /* clean up action channels */
+ for (ale= act_data.first; ale; ale= next) {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+ bConstraintChannel *conchan, *cnext;
+ next= ale->next;
+
+ /* release reference to ipo users */
+ if (achan->ipo)
+ achan->ipo->id.us--;
+
+ for (conchan= achan->constraintChannels.first; conchan; conchan=cnext) {
+ cnext= conchan->next;
+
+ if (conchan->ipo)
+ conchan->ipo->id.us--;
+ }
+
+ /* free memory */
+ BLI_freelistN(&achan->constraintChannels);
+ BLI_freelinkN(&act->chanbase, achan);
+ BLI_freelinkN(&act_data, ale);
+ }
+
+ remake_action_ipos(data);
+
+ BIF_undo_push("Delete Action Channels");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- if(G.saction->pin==0 && OBACT)
- sval[0]= get_action_frame(OBACT, sval[0]);
+/* 'Clean' IPO curves - remove any unnecessary keyframes */
+void clean_action (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype, ok;
- /* used for drawing */
- if(mode=='t') {
- G.saction->flag |= SACTION_MOVING;
- G.saction->timeslide= sval[0];
+ /* don't proceed any further if nothing to work on or user refuses */
+ data= get_action_context(&datatype);
+ ok= fbutton(&G.scene->toolsettings->clean_thresh,
+ 0.0000001f, 1.0, 0.001, 0.1,
+ "Clean Threshold");
+ if (!ok) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_SEL | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and clean curves */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ clean_ipo_curve((IpoCurve *)ale->key_data);
}
- startx=sval[0];
- while (loop) {
-
- if(mode=='t' && minx==maxx)
- break;
-
- /* Get the input */
- /* If we're cancelling, reset transformations */
- /* Else calc new transformation */
- /* Perform the transformations */
- while (qtest()) {
- short val;
- unsigned short event= extern_qread(&val);
-
- if (val) {
- switch (event) {
- case LEFTMOUSE:
- case SPACEKEY:
- case RETKEY:
- loop=0;
- break;
- case XKEY:
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- cancel=1;
- loop=0;
- break;
- default:
- arrows_move_cursor(event);
- break;
- };
- }
- }
+ /* admin and redraws */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Clean Action");
+ allqueue(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+}
- if (cancel) {
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
- tv[i].loc[1]=tv[i].oldloc[1];
- }
- }
- else {
- getmouseco_areawin (mvalc);
- areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
-
- if(G.saction->pin==0 && OBACT)
- cval[0]= get_action_frame(OBACT, cval[0]);
- if(mode=='t')
- G.saction->timeslide= cval[0];
-
- if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
- PIL_sleep_ms(1);
- }
- else {
- short autosnap= 0;
-
- /* determine mode of keyframe snapping/autosnap */
- if (mode != 't') {
- switch (G.saction->autosnap) {
- case SACTSNAP_OFF:
- if (G.qual == LR_CTRLKEY)
- autosnap= SACTSNAP_STEP;
- else if (G.qual == LR_SHIFTKEY)
- autosnap= SACTSNAP_FRAME;
- else
- autosnap= SACTSNAP_OFF;
- break;
- case SACTSNAP_STEP:
- autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
- break;
- case SACTSNAP_FRAME:
- autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
- break;
- }
- }
-
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
+/* little cache for values... */
+typedef struct tempFrameValCache {
+ float frame, val;
+} tempFrameValCache;
- switch (mode) {
- case 't':
- if( sval[0] > minx && sval[0] < maxx) {
- float timefac, cvalc= CLAMPIS(cval[0], minx, maxx);
-
- /* left half */
- if(tv[i].oldloc[0] < sval[0]) {
- timefac= ( sval[0] - tv[i].oldloc[0])/(sval[0] - minx);
- tv[i].loc[0]= cvalc - timefac*( cvalc - minx);
- }
- else {
- timefac= (tv[i].oldloc[0] - sval[0])/(maxx - sval[0]);
- tv[i].loc[0]= cvalc + timefac*(maxx- cvalc);
- }
- }
- break;
- case 'g':
- if (G.saction->pin==0 && OBACT) {
- deltax = get_action_frame_inv(OBACT, cval[0]);
- deltax -= get_action_frame_inv(OBACT, sval[0]);
-
- if (autosnap == SACTSNAP_STEP)
- deltax= 1.0f*floor(deltax/1.0f + 0.5f);
-
- fac = get_action_frame_inv(OBACT, tv[i].loc[0]);
- fac += deltax;
- tv[i].loc[0] = get_action_frame(OBACT, fac);
- }
- else {
- deltax = cval[0] - sval[0];
- fac= deltax;
-
- if (autosnap == SACTSNAP_STEP)
- fac= 1.0f*floor(fac/1.0f + 0.5f);
-
- tv[i].loc[0]+=fac;
- }
- break;
- case 's':
- startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
- deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
- fac= fabs(deltax/startx);
-
- if (autosnap == SACTSNAP_STEP) {
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
-
- if (invert){
- if (i % 03 == 0){
- memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i+2].oldloc));
- }
- if (i % 03 == 2){
- memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i-2].oldloc));
- }
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+void sample_action_keys (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
- fac*=-1;
- }
- startx= (G.scene->r.cfra);
- if(G.saction->pin==0 && OBACT)
- startx= get_action_frame(OBACT, startx);
-
- tv[i].loc[0]-= startx;
- tv[i].loc[0]*=fac;
- tv[i].loc[0]+= startx;
+ /* sanity checks */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+ BezTriple *bezt, *start=NULL, *end=NULL;
+ tempFrameValCache *value_cache, *fp;
+ int sfra, range;
+ int i, n;
- break;
- }
+ /* find selected keyframes... once pair has been found, add keyframes */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* check if selected, and which end this is */
+ if (BEZSELECTED(bezt)) {
+ if (start) {
+ /* set end */
+ end= bezt;
+
+ /* cache values then add keyframes using these values, as adding
+ * keyframes while sampling will affect the outcome...
+ */
+ range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+ sfra= (int)( floor(start->vec[1][0]) );
- /* snap key to nearest frame? */
- if (autosnap == SACTSNAP_FRAME) {
- float snapval;
+ if (range) {
+ value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
- /* convert frame to nla-action time (if needed) */
- if (G.saction->pin==0 && OBACT)
- snapval= get_action_frame_inv(OBACT, tv[i].loc[0]);
- else
- snapval= tv[i].loc[0];
+ /* sample values */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ fp->frame= (float)(sfra + n);
+ fp->val= eval_icu(icu, fp->frame);
+ }
- /* snap to nearest frame */
- snapval= (float)(floor(snapval+0.5));
-
- /* convert frame out of nla-action time */
- if (G.saction->pin==0 && OBACT)
- tv[i].loc[0]= get_action_frame(OBACT, snapval);
- else
- tv[i].loc[0]= snapval;
- }
- }
-
- if (mode=='s') {
- sprintf(str, "scaleX: %.3f", fac);
- headerprint(str);
- }
- else if (mode=='g') {
- if(G.saction->pin==0 && OBACT) {
- /* recalculate the delta based on 'visual' times */
- fac = get_action_frame_inv(OBACT, cval[0]);
- fac -= get_action_frame_inv(OBACT, sval[0]);
+ /* add keyframes with these */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ insert_vert_icu(icu, fp->frame, fp->val, 1);
+ }
- if (autosnap == SACTSNAP_STEP)
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
- sprintf(str, "deltaX: %.3f", fac);
- headerprint(str);
- }
- else if (mode=='t') {
- float fac= 2.0*(cval[0]-sval[0])/(maxx-minx);
- CLAMP(fac, -1.0f, 1.0f);
- sprintf(str, "TimeSlide: %.3f", fac);
- headerprint(str);
- }
-
- if (G.saction->lock) {
- if(ob) {
- ob->ctime= -1234567.0f;
- if(ob->pose || ob_get_key(ob))
- DAG_object_flush_update(G.scene, ob, OB_RECALC);
- else
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ /* free temp cache */
+ MEM_freeN(value_cache);
+
+ /* as we added keyframes, we need to compensate so that bezt is at the right place */
+ bezt = icu->bezt + i + range - 1;
+ i += (range - 1);
}
- force_draw_plus(SPACE_VIEW3D, 0);
+
+ /* bezt was selected, so it now marks the start of a whole new chain to search */
+ start= bezt;
+ end= NULL;
}
else {
- force_draw(0);
+ /* just set start keyframe */
+ start= bezt;
+ end= NULL;
}
}
}
- lastcval[0]= cval[0];
- lastcval[1]= cval[1];
- firsttime= 0;
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
}
- /* Update the curve */
- /* Depending on the lock status, draw necessary views */
+ /* admin and redraws */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Sample Action Keys");
+ allqueue(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
+/* **************************************************** */
+/* COPY/PASTE FOR ACTIONS */
+/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
+ * IPO-blocks, and also temporary IpoCurves which only contain the selected keyframes.
+ * - Only pastes between compatable data is possible (i.e. same achan->name, ipo-curve type, etc.)
+ * Unless there is only one element in the buffer, names are also tested to check for compatability.
+ * - All pasted frames are offset by the same amount. This is calculated as the difference in the times of
+ * the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
+ * - The earliest frame is calculated per copy operation.
+ */
- if(ob) {
- ob->ctime= -1234567.0f;
+/* globals for copy/paste data (like for other copy/paste buffers) */
+ListBase actcopybuf = {NULL, NULL};
+static float actcopy_firstframe= 999999999.0f;
- if(ob->pose || ob_get_key(ob))
- DAG_object_flush_update(G.scene, ob, OB_RECALC);
- else
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
- }
+/* This function frees any MEM_calloc'ed copy/paste buffer data */
+void free_actcopybuf ()
+{
+ bActionChannel *achan, *anext;
+ bConstraintChannel *conchan, *cnext;
- remake_action_ipos(act);
-
- G.saction->flag &= ~SACTION_MOVING;
+ for (achan= actcopybuf.first; achan; achan= anext) {
+ anext= achan->next;
+
+ if (achan->ipo) {
+ free_ipo(achan->ipo);
+ MEM_freeN(achan->ipo);
+ }
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) {
+ cnext= conchan->next;
+
+ if (conchan->ipo) {
+ free_ipo(conchan->ipo);
+ MEM_freeN(conchan->ipo);
+ }
+
+ BLI_freelinkN(&achan->constraintChannels, conchan);
+ }
+
+ BLI_freelinkN(&actcopybuf, achan);
+ }
- if(cancel==0) BIF_undo_push("Transform Action");
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- allqueue(REDRAWTIME, 0);
- MEM_freeN (tv);
+ actcopybuf.first= actcopybuf.last= NULL;
+ actcopy_firstframe= 999999999.0f;
}
-void transform_meshchannel_keys(char mode, Key *key)
+/* This function adds data to the copy/paste buffer, freeing existing data first
+ * Only the selected action channels gets their selected keyframes copied.
+ */
+void copy_actdata ()
{
- /* this is the function that determines what happens
- * to those little blocky rvk key things you have selected
- * after you press a 'g' or an 's'. I'd love to say that
- * I have an intimate knowledge of all of what this function
- * is doing, but instead I'm just going to pretend.
- */
- TransVert *tv;
- int /*sel=0,*/ i;
- short mvals[2], mvalc[2], cent[2];
- float sval[2], cval[2], lastcval[2]={0,0};
- short cancel=0;
- float fac=0.0F;
- int loop=1;
- int tvtot=0;
- float deltax, startx;
- float cenf[2];
- int invert=0, firsttime=1;
- char str[256];
-
- /* count all of the selected beziers, and
- * set all 3 control handles to selected
- */
- tvtot=fullselect_ipo_keys(key->ipo);
-
- /* If nothing is selected, bail out */
- if (!tvtot)
- return;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ /* clear buffer first */
+ free_actcopybuf();
- /* Build the transvert structure */
- tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
- tvtot=0;
-
- tvtot = add_trans_ipo_keys(key->ipo, tv, tvtot);
-
- /* Do the event loop */
- cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
- cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
- areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
-
- getmouseco_areawin (mvals);
- areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
-
- startx=sval[0];
- while (loop) {
- /* Get the input
- * If we're cancelling, reset transformations
- * Else calc new transformation
- * Perform the transformations
- */
- while (qtest()) {
- short val;
- unsigned short event= extern_qread(&val);
-
- if (val) {
- switch (event) {
- case LEFTMOUSE:
- case SPACEKEY:
- case RETKEY:
- loop=0;
- break;
- case XKEY:
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- cancel=1;
- loop=0;
- break;
- default:
- arrows_move_cursor(event);
- break;
- };
- }
- }
-
- if (cancel) {
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
- tv[i].loc[1]=tv[i].oldloc[1];
- }
- }
- else {
- getmouseco_areawin (mvalc);
- areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* assume that each of these is an ipo-block */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ bActionChannel *achan;
+ Ipo *ipo= ale->key_data;
+ Ipo *ipn;
+ IpoCurve *icu, *icn;
+ BezTriple *bezt;
+ int i;
+
+ /* coerce an action-channel out of owner */
+ if (ale->ownertype == ACTTYPE_ACHAN) {
+ bActionChannel *achanO= ale->owner;
+ achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
+ strcpy(achan->name, achanO->name);
+ }
+ else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
+ achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
+ strcpy(achan->name, "#ACP_ShapeKey");
+ }
+ else
+ continue;
+ BLI_addtail(&actcopybuf, achan);
+
+ /* add constraint channel if needed, then add new ipo-block */
+ if (ale->type == ACTTYPE_CONCHAN) {
+ bConstraintChannel *conchanO= ale->data;
+ bConstraintChannel *conchan;
- if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
- PIL_sleep_ms(1);
- }
- else {
- short autosnap= 0;
-
- /* determine mode of keyframe snapping/autosnap */
- if (mode != 't') {
- switch (G.saction->autosnap) {
- case SACTSNAP_OFF:
- if (G.qual == LR_CTRLKEY)
- autosnap= SACTSNAP_STEP;
- else if (G.qual == LR_SHIFTKEY)
- autosnap= SACTSNAP_FRAME;
- else
- autosnap= SACTSNAP_OFF;
- break;
- case SACTSNAP_STEP:
- autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
- break;
- case SACTSNAP_FRAME:
- autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
- break;
- }
- }
+ conchan= MEM_callocN(sizeof(bConstraintChannel), "ActCopyPasteConchan");
+ strcpy(conchan->name, conchanO->name);
+ BLI_addtail(&achan->constraintChannels, conchan);
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
-
- switch (mode){
- case 'g':
- deltax = cval[0]-sval[0];
- fac= deltax;
-
- if (autosnap == SACTSNAP_STEP) {
- /* NOTE: this doesn't take into account NLA scaling */
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
-
- tv[i].loc[0]+=fac;
- break;
- case 's':
- startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax
- -curarea->winrct.xmin)/2);
- deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax
- -curarea->winrct.xmin)/2);
- fac= fabs(deltax/startx);
-
- if (autosnap == SACTSNAP_FRAME) {
- /* NOTE: this doesn't take into account NLA scaling */
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
-
- if (invert){
- if (i % 03 == 0){
- memcpy (tv[i].loc, tv[i].oldloc,
- sizeof(tv[i+2].oldloc));
- }
- if (i % 03 == 2){
- memcpy (tv[i].loc, tv[i].oldloc,
- sizeof(tv[i-2].oldloc));
- }
-
- fac*=-1;
- }
- startx= (G.scene->r.cfra);
-
- tv[i].loc[0]-= startx;
- tv[i].loc[0]*=fac;
- tv[i].loc[0]+= startx;
+ conchan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
+ }
+ else {
+ achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
+ }
+ ipn->blocktype = ipo->blocktype;
- break;
- }
+ /* now loop through curves, and only copy selected keyframes */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ /* allocate a new curve */
+ icn= MEM_callocN(sizeof(IpoCurve), "ActCopyPasteIcu");
+ icn->blocktype = icu->blocktype;
+ icn->adrcode = icu->adrcode;
+ BLI_addtail(&ipn->curve, icn);
+
+ /* find selected BezTriples to add to the buffer (and set first frame) */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (BEZSELECTED(bezt)) {
+ /* add to buffer ipo-curve */
+ insert_bezt_icu(icn, bezt);
- /* auto-snap key to nearest frame? */
- if (autosnap == SACTSNAP_FRAME) {
- tv[i].loc[0]= (float)(floor(tv[i].loc[0]+0.5));
- }
- }
- }
- /* Display a message showing the magnitude of
- * the grab/scale we are performing
- */
- if (mode=='s') {
- sprintf(str, "scaleX: %.3f", fac);
- headerprint(str);
- }
- else if (mode=='g') {
- sprintf(str, "deltaX: %.3f", fac);
- headerprint(str);
- }
-
- if (G.saction->lock) {
- /* doubt any of this code ever gets
- * executed, but it might in the
- * future
- */
-
- DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWTIME, 0);
- force_draw_all(0);
- }
- else {
- addqueue (curarea->win, REDRAWALL, 0);
- force_draw(0);
- }
- }
-
- lastcval[0]= cval[0];
- lastcval[1]= cval[1];
- firsttime= 0;
- }
+ /* check if this is the earliest frame encountered so far */
+ if (bezt->vec[1][0] < actcopy_firstframe)
+ actcopy_firstframe= bezt->vec[1][0];
+ }
+ }
+ }
+ }
- /* fix up the Ipocurves and redraw stuff */
- meshkey_do_redraw(key);
- BIF_undo_push("Transform Action Keys");
-
- MEM_freeN (tv);
-
- /* did you understand all of that? I pretty much understand
- * what it does, but the specifics seem a little weird and crufty.
- */
+ /* check if anything ended up in the buffer */
+ if (ELEM(NULL, actcopybuf.first, actcopybuf.last))
+ error("Nothing copied to buffer");
+
+ /* free temp memory */
+ BLI_freelistN(&act_data);
}
-void deselect_actionchannel_keys (bAction *act, int test, int sel)
+void paste_actdata ()
{
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- if (!act)
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ short no_name= 0;
+ float offset = CFRA - actcopy_firstframe;
+ char *actname = NULL, *conname = NULL;
+
+ /* check if buffer is empty */
+ if (ELEM(NULL, actcopybuf.first, actcopybuf.last)) {
+ error("No data in buffer to paste");
return;
-
- /* Determine if this is selection or deselection */
- if (test) {
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- /* Test the channel ipos */
- if (is_ipo_key_selected(achan->ipo)) {
- sel = 0;
- break;
- }
-
- if ((EXPANDED_ACHAN(achan) == 0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
+ }
+ /* check if single channel in buffer (disregard names if so) */
+ if (actcopybuf.first == actcopybuf.last)
+ no_name= 1;
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* from selected channels */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ Ipo *ipo_src=NULL, *ipo_dst=ale->key_data;
+ bActionChannel *achan;
+ IpoCurve *ico, *icu;
+ BezTriple *bezt;
+ int i;
+
+ /* find matching ipo-block */
+ for (achan= actcopybuf.first; achan; achan= achan->next) {
+ /* try to match data */
+ if (ale->ownertype == ACTTYPE_ACHAN) {
+ bActionChannel *achant= ale->owner;
- /* Test the constraint ipos */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
- if (is_ipo_key_selected(conchan->ipo)) {
- sel = 0;
+ /* check if we have a corresponding action channel */
+ if ((no_name) || (strcmp(achan->name, achant->name)==0)) {
+ actname= achan->name;
+
+ /* check if this is a constraint channel */
+ if (ale->type == ACTTYPE_CONCHAN) {
+ bConstraintChannel *conchant= ale->data;
+ bConstraintChannel *conchan;
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (strcmp(conchan->name, conchant->name)==0) {
+ conname= conchan->name;
+ ipo_src= conchan->ipo;
+ break;
+ }
+ }
+ if (ipo_src) break;
+ }
+ else {
+ ipo_src= achan->ipo;
break;
}
}
-
- if (sel == 0)
+ }
+ else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
+ /* check if this action channel is "#ACP_ShapeKey" */
+ if ((no_name) || (strcmp(achan->name, "#ACP_ShapeKey")==0)) {
+ actname= achan->name;
+ ipo_src= achan->ipo;
break;
+ }
+ }
+ }
+
+ /* this shouldn't happen, but it might */
+ if (ELEM(NULL, ipo_src, ipo_dst))
+ continue;
+
+ /* loop over curves, pasting keyframes */
+ for (ico= ipo_src->curve.first; ico; ico= ico->next) {
+ icu= verify_ipocurve((ID*)OBACT, ico->blocktype, actname, conname, "", ico->adrcode);
+
+ if(icu) {
+ /* just start pasting, with the the first keyframe on the current frame, and so on */
+ for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
+ /* temporarily apply offset to src beztriple while copying */
+ bezt->vec[0][0] += offset;
+ bezt->vec[1][0] += offset;
+ bezt->vec[2][0] += offset;
+
+ /* insert the keyframe */
+ insert_bezt_icu(icu, bezt);
+
+ /* un-apply offset from src beztriple after copying */
+ bezt->vec[0][0] -= offset;
+ bezt->vec[1][0] -= offset;
+ bezt->vec[2][0] -= offset;
+ }
+
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
}
}
}
- /* Set the flags */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- set_ipo_key_selection(achan->ipo, sel);
+ /* free temp memory */
+ BLI_freelistN(&act_data);
+
+ /* undo and redraw stuff */
+ allqueue(REDRAWVIEW3D, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ BIF_undo_push("Paste Action Keyframes");
+}
+
+/* **************************************************** */
+/* VARIOUS SETTINGS */
+
+/* This function combines several features related to setting
+ * various ipo extrapolation/interpolation
+ */
+void action_set_ipo_flags (short mode, short event)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* determine which set of processing we are doing */
+ switch (mode) {
+ case SET_EXTEND_POPUP:
+ {
+ /* present popup menu for ipo extrapolation type */
+ event
+ = pupmenu("Channel Extending Type %t|"
+ "Constant %x11|"
+ "Extrapolation %x12|"
+ "Cyclic %x13|"
+ "Cyclic extrapolation %x14");
+ if (event < 1) return;
+ }
+ break;
+ case SET_IPO_POPUP:
+ {
+ /* present popup menu for ipo interpolation type */
+ event
+ = pupmenu("Channel Ipo Type %t|"
+ "Constant %x1|"
+ "Linear %x2|"
+ "Bezier %x3");
+ if (event < 1) return;
+ }
+ break;
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- set_ipo_key_selection(conchan->ipo, sel);
+ case SET_IPO_MENU: /* called from menus */
+ case SET_EXTEND_MENU:
+ break;
+
+ default: /* weird, unhandled case */
+ return;
+ }
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through setting flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ Ipo *ipo= (Ipo *)ale->key_data;
+
+ /* depending on the mode */
+ switch (mode) {
+ case SET_EXTEND_POPUP: /* extrapolation */
+ case SET_EXTEND_MENU:
+ {
+ switch (event) {
+ case SET_EXTEND_CONSTANT:
+ setexprap_ipoloop(ipo, IPO_HORIZ);
+ break;
+ case SET_EXTEND_EXTRAPOLATION:
+ setexprap_ipoloop(ipo, IPO_DIR);
+ break;
+ case SET_EXTEND_CYCLIC:
+ setexprap_ipoloop(ipo, IPO_CYCL);
+ break;
+ case SET_EXTEND_CYCLICEXTRAPOLATION:
+ setexprap_ipoloop(ipo, IPO_CYCLX);
+ break;
+ }
}
+ break;
+ case SET_IPO_POPUP: /* interpolation */
+ case SET_IPO_MENU:
+ {
+ setipotype_ipo(ipo, event);
+ }
+ break;
}
}
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push("Set Ipo Type");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-void deselect_meshchannel_keys (Key *key, int test, int sel)
+/* this function sets the handles on keyframes */
+void sethandles_action_keys (int code)
{
- /* should deselect the rvk keys */
-
- /* Determine if this is selection or deselection */
- if (test) {
- if (is_ipo_key_selected(key->ipo)) {
- sel = 0;
- }
- }
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
- /* Set the flags */
- set_ipo_key_selection(key->ipo, sel);
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through setting flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ sethandles_ipo_keys((Ipo *)ale->key_data, code);
+ }
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push("Set Handle Type");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-/* apparently within active object context */
-void deselect_actionchannels (bAction *act, int test)
-{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- int sel= 1;
+/* ----------------------------------------- */
- if (!act)
+/* this gets called when nkey is pressed (no Transform Properties panel yet) */
+static void numbuts_action ()
+{
+ void *data;
+ short datatype;
+
+ void *act_channel;
+ short chantype;
+
+ bActionGroup *agrp= NULL;
+ bActionChannel *achan= NULL;
+ bConstraintChannel *conchan= NULL;
+ IpoCurve *icu= NULL;
+ KeyBlock *kb= NULL;
+
+ short mval[2];
+
+ int but=0;
+ char str[64];
+ short expand, protect, mute;
+ float slidermin, slidermax;
+
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* figure out what is under cursor */
+ getmouseco_areawin(mval);
+ if (mval[0] > NAMEWIDTH)
return;
+ act_channel= get_nearest_act_channel(mval, &chantype);
+
+ /* create items for clever-numbut */
+ if (chantype == ACTTYPE_ACHAN) {
+ /* Action Channel */
+ achan= (bActionChannel *)act_channel;
+
+ strcpy(str, achan->name);
+ protect= (achan->flag & ACHAN_PROTECTED);
+ expand = (achan->flag & ACHAN_EXPANDED);
+ mute = (achan->ipo)? (achan->ipo->muteipo): 0;
+
+ add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
+ add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
+ add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else if (chantype == ACTTYPE_CONCHAN) {
+ /* Constraint Channel */
+ conchan= (bConstraintChannel *)act_channel;
+
+ strcpy(str, conchan->name);
+ protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
+ mute = (conchan->ipo)? (conchan->ipo->muteipo): 0;
+
+ add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
+ add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else if (chantype == ACTTYPE_ICU) {
+ /* IPO Curve */
+ icu= (IpoCurve *)act_channel;
+
+ if (G.saction->pin)
+ sprintf(str, getname_ipocurve(icu, NULL));
+ else
+ sprintf(str, getname_ipocurve(icu, OBACT));
+
+ if (IS_EQ(icu->slide_max, icu->slide_min)) {
+ if (IS_EQ(icu->ymax, icu->ymin)) {
+ icu->slide_min= -100.0;
+ icu->slide_max= 100.0;
+ }
+ else {
+ icu->slide_min= icu->ymin;
+ icu->slide_max= icu->ymax;
+ }
+ }
+ slidermin= icu->slide_min;
+ slidermax= icu->slide_max;
+
+ //protect= (icu->flag & IPO_PROTECT);
+ mute = (icu->flag & IPO_MUTE);
+
+ add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
+ add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
+ //add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else if (chantype == ACTTYPE_SHAPEKEY) {
+ /* Shape Key */
+ kb= (KeyBlock *)act_channel;
+
+ if (kb->name[0] == '\0') {
+ Key *key= (Key *)data;
+ int keynum= BLI_findindex(&key->block, kb);
+
+ sprintf(str, "Key %d", keynum);
+ }
+ else
+ strcpy(str, kb->name);
+
+ if (kb->slidermin >= kb->slidermax) {
+ kb->slidermin = 0.0;
+ kb->slidermax = 1.0;
+ }
+
+ add_numbut(but++, TEX, "KB: ", 0, 24, str,
+ "Does this really need a tool tip?");
+ add_numbut(but++, NUM|FLO, "Slider Min:",
+ -10000, kb->slidermax, &kb->slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider Max:",
+ kb->slidermin, 10000, &kb->slidermax, 0);
+ }
+ else if (chantype == ACTTYPE_GROUP) {
+ /* Action Group */
+ agrp= (bActionGroup *)act_channel;
+
+ strcpy(str, agrp->name);
+ protect= (agrp->flag & AGRP_PROTECTED);
+ expand = (agrp->flag & AGRP_EXPANDED);
+
+ add_numbut(but++, TEX, "ActGroup: ", 0, 31, str, "Name of Action Group");
+ add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Group is Expanded");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Group is Protected");
+ }
+ else {
+ /* nothing under-cursor */
+ return;
+ }
+
+ /* draw clever-numbut */
+ if (do_clever_numbuts(str, but, REDRAW)) {
+ /* restore settings based on type */
+ if (icu) {
+ icu->slide_min= slidermin;
+ icu->slide_max= slidermax;
+
+ //if (protect) icu->flag |= IPO_PROTECT;
+ //else icu->flag &= ~IPO_PROTECT;
+ if (mute) icu->flag |= IPO_MUTE;
+ else icu->flag &= ~IPO_MUTE;
+ }
+ else if (conchan) {
+ strcpy(conchan->name, str);
+
+ if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
+ else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
+
+ if (conchan->ipo)
+ conchan->ipo->muteipo = mute;
+ }
+ else if (achan) {
+ strcpy(achan->name, str);
+
+ if (expand) achan->flag |= ACHAN_EXPANDED;
+ else achan->flag &= ~ACHAN_EXPANDED;
+
+ if (protect) achan->flag |= ACHAN_PROTECTED;
+ else achan->flag &= ~ACHAN_PROTECTED;
+
+ if (achan->ipo)
+ achan->ipo->muteipo = mute;
+ }
+ else if (agrp) {
+ strcpy(agrp->name, str);
+ BLI_uniquename(&( ((bAction *)data)->groups ), agrp, "Group", offsetof(bActionGroup, name), 32);
+
+ if (expand) agrp->flag |= AGRP_EXPANDED;
+ else agrp->flag &= ~AGRP_EXPANDED;
+
+ if (protect) agrp->flag |= AGRP_PROTECTED;
+ else agrp->flag &= ~AGRP_PROTECTED;
+ }
+
+ allqueue(REDRAWACTION, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+}
- /* See if we should be selecting or deselecting */
- if (test) {
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (!sel)
- break;
+/* Set/clear a particular flag (setting) for all selected + visible channels
+ * mode: 0 = toggle, 1 = turn on, 2 = turn off
+ */
+void setflag_action_channels (short mode)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ char str[32];
+ short val;
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* get setting to affect */
+ if (mode == 2) {
+ val= pupmenu("Disable Setting%t|Protect %x1|Mute%x2");
+ sprintf(str, "Disable Action Setting");
+ }
+ else if (mode == 1) {
+ val= pupmenu("Enable Setting%t|Protect %x1|Mute%x2");
+ sprintf(str, "Enable Action Setting");
+ }
+ else {
+ val= pupmenu("Toggle Setting%t|Protect %x1|Mute%x2");
+ sprintf(str, "Toggle Action Setting");
+ }
+ if (val <= 0) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS | ACTFILTER_SEL);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* affect selected channels */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ switch (ale->type) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)ale->data;
- if (achan->flag & ACHAN_SELECTED) {
- sel= 0;
- break;
+ /* only 'protect' is available */
+ if (val == 1) {
+ if (mode == 2)
+ agrp->flag &= ~AGRP_PROTECTED;
+ else if (mode == 1)
+ agrp->flag |= AGRP_PROTECTED;
+ else
+ agrp->flag ^= AGRP_PROTECTED;
}
- if (sel) {
- if (EXPANDED_ACHAN(achan)) {
- if (FILTER_IPO_ACHAN(achan) && (achan->ipo)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- if (SEL_ICU(icu)) {
- sel= 0;
- break;
- }
- }
-
- }
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (SEL_CONCHAN(conchan)) {
- sel= 0;
- break;
- }
- }
- }
- }
+ }
+ break;
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+
+ /* 'protect' and 'mute' */
+ if ((val == 2) && (achan->ipo)) {
+ Ipo *ipo= achan->ipo;
+
+ /* mute */
+ if (mode == 2)
+ ipo->muteipo= 0;
+ else if (mode == 1)
+ ipo->muteipo= 1;
+ else
+ ipo->muteipo= (ipo->muteipo) ? 0 : 1;
+ }
+ else if (val == 1) {
+ /* protected */
+ if (mode == 2)
+ achan->flag &= ~ACHAN_PROTECTED;
+ else if (mode == 1)
+ achan->flag |= ACHAN_PROTECTED;
+ else
+ achan->flag ^= ACHAN_PROTECTED;
+ }
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
+
+ /* 'protect' and 'mute' */
+ if ((val == 2) && (conchan->ipo)) {
+ Ipo *ipo= conchan->ipo;
+
+ /* mute */
+ if (mode == 2)
+ ipo->muteipo= 0;
+ else if (mode == 1)
+ ipo->muteipo= 1;
+ else
+ ipo->muteipo= (ipo->muteipo) ? 0 : 1;
+ }
+ else if (val == 1) {
+ /* protect */
+ if (mode == 2)
+ conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
+ else if (mode == 1)
+ conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
+ else
+ conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
}
}
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)ale->data;
+
+ /* mute */
+ if (val == 2) {
+ if (mode == 2)
+ icu->flag &= ~IPO_MUTE;
+ else if (mode == 1)
+ icu->flag |= IPO_MUTE;
+ else
+ icu->flag ^= IPO_MUTE;
+ }
+ }
+ break;
}
}
- else
- sel= 0;
+ BLI_freelistN(&act_data);
- /* Now set the flags */
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- select_poseelement_by_name(achan->name, sel);
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- if (sel)
- achan->flag |= ACHAN_SELECTED;
- else
- achan->flag &= ~ACHAN_SELECTED;
+/* **************************************************** */
+/* CHANNEL SELECTION */
- if (EXPANDED_ACHAN(achan)) {
- if (FILTER_IPO_ACHAN(achan) && (achan->ipo)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- if (sel)
- icu->flag |= IPO_SELECT;
- else
- icu->flag &= ~IPO_SELECT;
- }
- }
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (sel)
- conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
- else
- conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
- }
- }
- }
- }
+/* select_mode = SELECT_REPLACE
+ * = SELECT_ADD
+ * = SELECT_SUBTRACT
+ * = SELECT_INVERT
+ */
+static void select_action_group (bAction *act, bActionGroup *agrp, int selectmode)
+{
+ /* Select the channel based on the selection mode */
+ short select;
+
+ switch (selectmode) {
+ case SELECT_ADD:
+ agrp->flag |= AGRP_SELECTED;
+ break;
+ case SELECT_SUBTRACT:
+ agrp->flag &= ~AGRP_SELECTED;
+ break;
+ case SELECT_INVERT:
+ agrp->flag ^= AGRP_SELECTED;
+ break;
}
+ select = (agrp->flag & AGRP_SELECTED) ? 1 : 0;
+ set_active_actiongroup(act, agrp, select);
}
-static void hilight_channel (bAction *act, bActionChannel *achan, short select)
+static void hilight_channel(bAction *act, bActionChannel *achan, short select)
{
bActionChannel *curchan;
@@ -1767,6 +2441,56 @@ static void hilight_channel (bAction *act, bActionChannel *achan, short select)
}
}
+/* Syncs selection of channels with selection of object elements in posemode */
+/* messy call... */
+static void select_poseelement_by_name (char *name, int select)
+{
+ Object *ob= OBACT;
+ bPoseChannel *pchan;
+
+ if ((ob==NULL) || (ob->type!=OB_ARMATURE))
+ return;
+
+ if (select == 2) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ pchan->bone->flag &= ~(BONE_ACTIVE);
+ }
+
+ pchan= get_pose_channel(ob->pose, name);
+ if (pchan) {
+ if (select)
+ pchan->bone->flag |= (BONE_SELECTED);
+ else
+ pchan->bone->flag &= ~(BONE_SELECTED);
+ if (select == 2)
+ pchan->bone->flag |= (BONE_ACTIVE);
+ }
+}
+
+/* apparently within active object context */
+/* called extern, like on bone selection */
+void select_actionchannel_by_name (bAction *act, char *name, int select)
+{
+ bActionChannel *achan;
+
+ if (act == NULL)
+ return;
+
+ for (achan = act->chanbase.first; achan; achan= achan->next) {
+ if (!strcmp(achan->name, name)) {
+ if (select) {
+ achan->flag |= ACHAN_SELECTED;
+ hilight_channel(act, achan, 1);
+ }
+ else {
+ achan->flag &= ~ACHAN_SELECTED;
+ hilight_channel(act, achan, 0);
+ }
+ return;
+ }
+ }
+}
+
/* select_mode = SELECT_REPLACE
* = SELECT_ADD
* = SELECT_SUBTRACT
@@ -1801,7 +2525,8 @@ int select_channel(bAction *act, bActionChannel *achan, int selectmode)
static int select_constraint_channel(bAction *act,
bConstraintChannel *conchan,
- int selectmode) {
+ int selectmode)
+{
/* Select the constraint channel based on the selection mode */
int flag;
@@ -1841,150 +2566,888 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
return flag;
}
-static void borderselect_actionchannels(bAction *act, short *mval,
- short *mvalo, int selectmode)
+/* ----------------------------------------- */
+
+/* De-selects or inverts the selection of Channels in a given Action
+ * mode: 0 = default behaviour (select all), 1 = test if (de)select all, 2 = invert all
+ */
+void deselect_actionchannels (bAction *act, short mode)
{
- /* Select action channels, based on mouse values.
- * If mvalo is NULL we assume it is a one click
- * action, other wise we treat it like it is a
- * border select with mval[0],mval[1] and
- * mvalo[0], mvalo[1] forming the corners of
- * a rectangle.
- */
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- float click, x,y;
- int clickmin, clickmax;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter, sel=1;
+
+ /* filter data */
+ filter= ACTFILTER_VISIBLE;
+ actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
+
+ /* See if we should be selecting or deselecting */
+ if (mode == 1) {
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (sel == 0)
+ break;
+
+ switch (ale->type) {
+ case ACTTYPE_GROUP:
+ if (ale->flag & AGRP_SELECTED)
+ sel= 0;
+ break;
+ case ACTTYPE_ACHAN:
+ if (ale->flag & ACHAN_SELECTED)
+ sel= 0;
+ break;
+ case ACTTYPE_CONCHAN:
+ if (ale->flag & CONSTRAINT_CHANNEL_SELECT)
+ sel=0;
+ break;
+ case ACTTYPE_ICU:
+ if (ale->flag & IPO_SELECT)
+ sel=0;
+ break;
+ }
+ }
+ }
+ else
+ sel= 0;
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ switch (ale->type) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)ale->data;
+
+ if (mode == 2)
+ agrp->flag ^= AGRP_SELECTED;
+ else if (sel)
+ agrp->flag |= AGRP_SELECTED;
+ else
+ agrp->flag &= ~AGRP_SELECTED;
+
+ agrp->flag &= ~AGRP_ACTIVE;
+ }
+ break;
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+
+ if (mode == 2)
+ achan->flag ^= AGRP_SELECTED;
+ else if (sel)
+ achan->flag |= ACHAN_SELECTED;
+ else
+ achan->flag &= ~ACHAN_SELECTED;
+
+ select_poseelement_by_name(achan->name, sel);
+ achan->flag &= ~ACHAN_HILIGHTED;
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
+
+ if (mode == 2)
+ conchan->flag ^= CONSTRAINT_CHANNEL_SELECT;
+ else if (sel)
+ conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
+ else
+ conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)ale->data;
+
+ if (mode == 2)
+ icu->flag ^= IPO_SELECT;
+ else if (sel)
+ icu->flag |= IPO_SELECT;
+ else
+ icu->flag &= ~IPO_SELECT;
+
+ icu->flag &= ~IPO_ACTIVE;
+ }
+ break;
+ }
+ }
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- if (!act)
- return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannels (act, 0);
- selectmode = SELECT_ADD;
+/* deselects channels in the action editor */
+void deselect_action_channels (short mode)
+{
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* based on type */
+ if (datatype == ACTCONT_ACTION)
+ deselect_actionchannels(data, mode);
+ // should shapekey channels be allowed to do this?
+}
+
+/* deselects keyframes in the action editor */
+void deselect_action_keys (short test, short sel)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (is_ipo_key_selected(ale->key_data)) {
+ sel= 0;
+ break;
+ }
+ }
}
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ set_ipo_key_selection(ale->key_data, sel);
+ }
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+/* selects all keyframes in the action editor - per channel or time
+ * mode = 0: all in channel; mode = 1: all in frame
+ */
+void selectall_action_keys (short mval[], short mode, short select_mode)
+{
+ void *data;
+ short datatype;
- /* Only one click */
- if (mvalo == NULL) {
- clickmax = clickmin;
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ if (select_mode == SELECT_REPLACE) {
+ deselect_action_keys(0, 0);
+ select_mode = SELECT_ADD;
}
- /* Two click values (i.e., border select */
- else {
- areamouseco_to_ipoco(G.v2d, mvalo, &x, &y);
- click = (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ /* depending on mode */
+ switch (mode) {
+ case 0: /* all in channel*/
+ {
+ void *act_channel;
+ short chantype;
+
+ /* get channel, and act according to type */
+ act_channel= get_nearest_act_channel(mval, &chantype);
+ switch (chantype) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)act_channel;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_ipo_bezier_keys(achan->ipo, select_mode);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ select_ipo_bezier_keys(conchan->ipo, select_mode);
+ }
+ }
+ break;
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)act_channel;
+ select_ipo_bezier_keys(achan->ipo, select_mode);
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
+ select_ipo_bezier_keys(conchan->ipo, select_mode);
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)act_channel;
+ select_icu_bezier_keys(icu, select_mode);
+ }
+ break;
+ }
+ }
+ break;
+ case 1: /* all in frame */
+ {
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ rcti rect;
+ rctf rectf;
+
+ /* use bounding box to find kframe */
+ rect.xmin = rect.xmax = mval[0];
+ rect.ymin = rect.ymax = mval[1];
+
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ rectf.xmax= rectf.xmin;
+ rectf.ymax= rectf.ymin;
+
+ rectf.xmin = rectf.xmin - 0.5;
+ rectf.xmax = rectf.xmax + 0.5;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next)
+ borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, select_mode);
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+ }
+ break;
+ }
+
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+}
- if ( ((int) click) < clickmin) {
- clickmax = clickmin;
- clickmin = (int) click;
+/* Selects all visible keyframes between the specified markers */
+void markers_selectkeys_between (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ float min, max;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* get extreme markers */
+ get_minmax_markers(1, &min, &max);
+ if (min==max) return;
+ min -= 0.5f;
+ max += 0.5f;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* select keys in-between */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if(NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else {
- clickmax = (int) click;
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
}
}
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- if (clickmax < 0) {
+/* Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */
+void selectkeys_leftright (short leftright, short select_mode)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ float min, max;
+
+ if (select_mode==SELECT_REPLACE) {
+ select_mode=SELECT_ADD;
+ deselect_action_keys(0, 0);
+ }
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ if (leftright == 1) {
+ min = -MAXFRAMEF;
+ max = (float)(CFRA + 0.1f);
+ }
+ else {
+ min = (float)(CFRA - 0.1f);
+ max = MAXFRAMEF;
+ }
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* select keys on the side where most data occurs */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if(NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
+ }
+ else {
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
+ }
+ }
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+}
+
+/* ----------------------------------------- */
+
+/* Jumps to the frame where the next/previous keyframe (that is visible) occurs
+ * dir: indicates direction
+ */
+void nextprev_action_keyframe (short dir)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ ListBase elems= {NULL, NULL};
+ CfraElem *ce, *nearest=NULL;
+ float dist, min_dist= 1000000;
+
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* abort if no direction */
+ if (dir == 0)
return;
+
+ /* get list of keyframes that can be used (in global-time) */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ make_cfra_list(ale->key_data, &elems);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
+ }
+ else
+ make_cfra_list(ale->key_data, &elems);
+ }
+
+ BLI_freelistN(&act_data);
+
+ /* find nearest keyframe to current frame */
+ for (ce= elems.first; ce; ce= ce->next) {
+ dist= ABS(ce->cfra - CFRA);
+
+ if (dist < min_dist) {
+ min_dist= dist;
+ nearest= ce;
+ }
}
+
+ /* if a nearest keyframe was found, use the one either side */
+ if (nearest) {
+ short changed= 0;
+
+ if ((dir > 0) && (nearest->next)) {
+ CFRA= nearest->next->cfra;
+ changed= 1;
+ }
+ else if ((dir < 0) && (nearest->prev)) {
+ CFRA= nearest->prev->cfra;
+ changed= 1;
+ }
+
+ if (changed) {
+ update_for_newframe();
+ allqueue(REDRAWALL, 0);
+ }
+ }
+
+ /* free temp data */
+ BLI_freelistN(&elems);
+}
- /* clickmin and clickmax now coorespond to indices into
- * the collection of channels and constraint channels.
- * What we need to do is apply the selection mode on all
- * channels and constraint channels between these indices.
- * This is done by traversing the channels and constraint
- * channels, for each item decrementing clickmin and clickmax.
- * When clickmin is less than zero we start selecting stuff,
- * until clickmax is less than zero or we run out of channels
- * and constraint channels.
- */
+/* ----------------------------------------- */
+
+/* This function makes a list of the selected keyframes
+ * in the ipo curves it has been passed
+ */
+static void make_sel_cfra_list (Ipo *ipo, ListBase *elems)
+{
+ IpoCurve *icu;
+
+ if (ipo == NULL) return;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int a= 0;
+
+ for (bezt=icu->bezt; a<icu->totvert; a++, bezt++) {
+ if (bezt && BEZSELECTED(bezt))
+ add_to_cfra_elem(elems, bezt);
+ }
+ }
+}
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0) break;
+/* This function selects all key frames in the same column(s) as a already selected key(s)
+ * or marker(s), or all the keyframes on a particular frame (triggered by a RMB on x-scrollbar)
+ */
+void column_select_action_keys (int mode)
+{
+ ListBase elems= {NULL, NULL};
+ CfraElem *ce;
+ IpoCurve *icu;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* build list of columns */
+ switch (mode) {
+ case 1: /* list of selected keys */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
- if (clickmin <= 0) {
- /* Select the channel with the given mode. If the
- * channel is freshly selected then set it to the
- * active channel for the action
- */
- select_channel(act, achan, selectmode);
- /* messy... */
- select_poseelement_by_name(achan->name, 2);
+ for (ale= act_data.first; ale; ale= ale->next)
+ make_sel_cfra_list(ale->key_data, &elems);
+
+ BLI_freelistN(&act_data);
+ break;
+ case 2: /* list of selected markers */
+ make_marker_cfra_list(&elems, 1);
+
+ /* apply scaled action correction if needed */
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ for (ce= elems.first; ce; ce= ce->next)
+ ce->cfra= get_action_frame(OBACT, ce->cfra);
}
+ break;
+ case 3: /* current frame */
+ /* make a single CfraElem */
+ ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&elems, ce);
- --clickmin;
- --clickmax;
+ /* apply scaled action correction if needed */
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION)
+ ce->cfra= get_action_frame(OBACT, CFRA);
+ else
+ ce->cfra= CFRA;
+ }
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ for (ce= elems.first; ce; ce= ce->next) {
+ for (icu= ale->key_data; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int verts = 0;
+
+ for (bezt=icu->bezt; verts<icu->totvert; bezt++, verts++) {
+ if (bezt) {
+ if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) )
+ bezt->f2 |= 1;
+ }
+ }
+ }
+ }
+ }
+
+ BLI_freelistN(&act_data);
+ BLI_freelistN(&elems);
+}
+
+
+/* some quick defines for borderselect modes */
+enum {
+ ACTEDIT_BORDERSEL_ALL = 0,
+ ACTEDIT_BORDERSEL_FRA,
+ ACTEDIT_BORDERSEL_CHA
+};
+
+/* borderselect: for keyframes only */
+void borderselect_action (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ rcti rect;
+ rctf rectf;
+ int val, selectmode, mode;
+ int (*select_function)(BezTriple *);
+ short mval[2];
+ float ymin, ymax;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* what should be selected (based on the starting location of cursor) */
+ getmouseco_areawin(mval);
+ if (IN_2D_VERT_SCROLL(mval))
+ mode = ACTEDIT_BORDERSEL_CHA;
+ else if (IN_2D_HORIZ_SCROLL(mval))
+ mode = ACTEDIT_BORDERSEL_FRA;
+ else
+ mode = ACTEDIT_BORDERSEL_ALL;
+
+ /* draw and handle the borderselect stuff (ui) and get the select rect */
+ if ( (val = get_border(&rect, 3)) ) {
+ if (val == LEFTMOUSE) {
+ selectmode = SELECT_ADD;
+ select_function = select_bezier_add;
+ }
+ else {
+ selectmode = SELECT_SUBTRACT;
+ select_function = select_bezier_subtract;
}
- if (EXPANDED_ACHAN(achan) == 0) {
- /* cannot search IPO/constaint channels */
- continue;
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ mval[0]= rect.xmax;
+ mval[1]= rect.ymax-2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
+ rectf.xmin= get_action_frame(OBACT, rectf.xmin);
+ rectf.xmax= get_action_frame(OBACT, rectf.xmax);
}
- if (achan->ipo) {
- /* widget */
- if (clickmax < 0) break;
- --clickmin;
- --clickmax;
+ ymax = CHANNELHEIGHT/2;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop over data, doing border select */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0) break;
-
- if (clickmin <= 0) {
- /* constraint channel */
- select_icu_channel(act, icu, selectmode);
+ /* what gets selected depends on the mode (based on initial position of cursor) */
+ switch (mode) {
+ case ACTEDIT_BORDERSEL_FRA: /* all in frame(s) */
+ if (ale->key_data) {
+ if (ale->datatype == ALE_IPO)
+ borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
+ else if (ale->datatype == ALE_ICU)
+ borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_function);
}
-
- --clickmin;
- --clickmax;
+ else if (ale->type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= ale->data;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
+ }
+ }
+ break;
+ case ACTEDIT_BORDERSEL_CHA: /* all in channel(s) */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ if (ale->key_data) {
+ if (ale->datatype == ALE_IPO)
+ select_ipo_bezier_keys(ale->key_data, selectmode);
+ else if (ale->datatype == ALE_ICU)
+ select_icu_bezier_keys(ale->key_data, selectmode);
+ }
+ else if (ale->type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= ale->data;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_ipo_bezier_keys(achan->ipo, selectmode);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ select_ipo_bezier_keys(conchan->ipo, selectmode);
+ }
+ }
+ }
+ break;
+ default: /* any keyframe inside region defined by region */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ if (ale->key_data) {
+ if (ale->datatype == ALE_IPO)
+ borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
+ else if (ale->datatype == ALE_ICU)
+ borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_function);
+ }
+ else if (ale->type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= ale->data;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
+ }
+ }
+ }
+ }
+
+ ymax=ymin;
+ }
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Border Select Action");
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ }
+}
+
+/* **************************************************** */
+/* MOUSE-HANDLING */
+
+/* right-hand side - mouse click */
+static void mouse_action (int selectmode)
+{
+ void *data;
+ short datatype;
+
+ bAction *act= NULL;
+ bActionGroup *agrp= NULL;
+ bActionChannel *achan= NULL;
+ bConstraintChannel *conchan= NULL;
+ IpoCurve *icu= NULL;
+ TimeMarker *marker, *pmarker;
+
+ void *act_channel;
+ short sel, act_type = 0;
+ float selx = 0.0;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype == ACTCONT_ACTION) act= (bAction *)data;
+
+ act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
+ marker= find_nearest_marker(SCE_MARKERS, 1);
+ pmarker= (act) ? find_nearest_marker(&act->markers, 1) : NULL;
+
+ if (marker) {
+ /* what about scene's markers? */
+ if (selectmode == SELECT_REPLACE) {
+ deselect_markers(0, 0);
+ marker->flag |= SELECT;
+ }
+ else if (selectmode == SELECT_INVERT) {
+ if (marker->flag & SELECT)
+ marker->flag &= ~SELECT;
+ else
+ marker->flag |= SELECT;
+ }
+ else if (selectmode == SELECT_ADD)
+ marker->flag |= SELECT;
+ else if (selectmode == SELECT_SUBTRACT)
+ marker->flag &= ~SELECT;
+
+ std_rmouse_transform(transform_markers);
+
+ allqueue(REDRAWMARKER, 0);
+ }
+ else if (pmarker) {
+ /* action's markers are drawn behind scene markers */
+ if (selectmode == SELECT_REPLACE) {
+ action_set_activemarker(act, pmarker, 1);
+ pmarker->flag |= SELECT;
+ }
+ else if (selectmode == SELECT_INVERT) {
+ if (pmarker->flag & SELECT) {
+ pmarker->flag &= ~SELECT;
+ action_set_activemarker(act, NULL, 0);
}
+ else {
+ pmarker->flag |= SELECT;
+ action_set_activemarker(act, pmarker, 0);
+ }
+ }
+ else if (selectmode == SELECT_ADD) {
+ pmarker->flag |= SELECT;
+ action_set_activemarker(act, pmarker, 0);
+ }
+ else if (selectmode == SELECT_SUBTRACT) {
+ pmarker->flag &= ~SELECT;
+ action_set_activemarker(act, NULL, 0);
+ }
+
+ // TODO: local-markers cannot be moved atm...
+ //std_rmouse_transform(transform_markers);
+
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ else if (act_channel) {
+ /* must have been a channel */
+ switch (act_type) {
+ case ACTTYPE_ICU:
+ icu= (IpoCurve *)act_channel;
+ break;
+ case ACTTYPE_CONCHAN:
+ conchan= (bConstraintChannel *)act_channel;
+ break;
+ case ACTTYPE_ACHAN:
+ achan= (bActionChannel *)act_channel;
+ break;
+ case ACTTYPE_GROUP:
+ agrp= (bActionGroup *)act_channel;
+ break;
+ default:
+ return;
}
- if (achan->constraintChannels.first) {
- /* widget */
- if (clickmax < 0) break;
- --clickmin;
- --clickmax;
+ if (selectmode == SELECT_REPLACE) {
+ selectmode = SELECT_ADD;
- /* try in constaint channels */
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0) break;
+ deselect_action_keys(0, 0);
+
+ if (datatype == ACTCONT_ACTION) {
+ deselect_action_channels(0);
- if (clickmin <= 0) {
- /* constraint channel */
- select_constraint_channel(act, conchan, selectmode);
+ /* Highlight either an Action-Channel or Action-Group */
+ if (achan) {
+ achan->flag |= ACHAN_SELECTED;
+ hilight_channel(act, achan, 1);
+ select_poseelement_by_name(achan->name, 2); /* 2 is activate */
+ }
+ else if (agrp) {
+ agrp->flag |= AGRP_SELECTED;
+ set_active_actiongroup(act, agrp, 1);
}
+ }
+ }
+
+ if (icu)
+ select_icu_key(icu, selx, selectmode);
+ else if (conchan)
+ select_ipo_key(conchan->ipo, selx, selectmode);
+ else if (achan)
+ select_ipo_key(achan->ipo, selx, selectmode);
+ else if (agrp) {
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_ipo_key(achan->ipo, selx, selectmode);
- --clickmin;
- --clickmax;
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
+ select_ipo_key(conchan->ipo, selx, selectmode);
}
}
+
+ std_rmouse_transform(transform_action_keys);
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWBUTSALL, 0);
}
-
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
- allqueue (REDRAWOOPS, 0);
- allqueue (REDRAWBUTSALL, 0);
}
-/* lefthand side */
+/* lefthand side - mouse-click */
static void mouse_actionchannels (short mval[])
{
bAction *act= G.saction->action;
- void *act_channel;
- short chan_type;
+ void *data, *act_channel;
+ short datatype, chantype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
/* get channel to work on */
- act_channel= get_nearest_act_channel(mval, &chan_type);
+ act_channel= get_nearest_act_channel(mval, &chantype);
/* action to take depends on what channel we've got */
- switch (chan_type) {
+ switch (chantype) {
+ case ACTTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)act_channel;
+
+ if (mval[0] < 16) {
+ /* toggle expand */
+ agrp->flag ^= AGRP_EXPANDED;
+ }
+ else if (mval[0] >= (NAMEWIDTH-16)) {
+ /* toggle protection/locking */
+ agrp->flag ^= AGRP_PROTECTED;
+ }
+ else {
+ /* select/deselect group */
+ if (G.qual == LR_SHIFTKEY) {
+ /* inverse selection status of group */
+ select_action_group(act, agrp, SELECT_INVERT);
+ }
+ else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
+ bActionChannel *achan;
+
+ /* select all in group (and deselect everthing else) */
+ deselect_actionchannels(act, 0);
+
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_channel(act, achan, SELECT_ADD);
+
+ /* messy... set active bone */
+ select_poseelement_by_name(achan->name, 1);
+ }
+ select_action_group(act, agrp, SELECT_ADD);
+ }
+ else {
+ /* select group by itself */
+ deselect_actionchannels(act, 0);
+ select_action_group(act, agrp, SELECT_ADD);
+ }
+ }
+ }
+ break;
case ACTTYPE_ACHAN:
{
bActionChannel *achan= (bActionChannel *)act_channel;
@@ -1993,6 +3456,10 @@ static void mouse_actionchannels (short mval[])
/* toggle protect */
achan->flag ^= ACHAN_PROTECTED;
}
+ else if ((mval[0] >= (NAMEWIDTH-32)) && (achan->ipo)) {
+ /* toggle mute */
+ achan->ipo->muteipo = (achan->ipo->muteipo)? 0: 1;
+ }
else if (mval[0] <= 17) {
/* toggle expand */
achan->flag ^= ACHAN_EXPANDED;
@@ -2048,10 +3515,16 @@ static void mouse_actionchannels (short mval[])
{
IpoCurve *icu= (IpoCurve *)act_channel;
+#if 0 /* disabled until all ipo tools support this -------> */
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle protection */
icu->flag ^= IPO_PROTECT;
}
+#endif /* <------- end of disabled code */
+ if (mval[0] >= (NAMEWIDTH-16)) {
+ /* toggle mute */
+ icu->flag ^= IPO_MUTE;
+ }
else {
/* select/deselect */
select_icu_channel(act, icu, SELECT_INVERT);
@@ -2066,6 +3539,10 @@ static void mouse_actionchannels (short mval[])
/* toggle protection */
conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
}
+ else if ((mval[0] >= (NAMEWIDTH-32)) && (conchan->ipo)) {
+ /* toggle mute */
+ conchan->ipo->muteipo = (conchan->ipo->muteipo)? 0: 1;
+ }
else {
/* select/deselect */
select_constraint_channel(act, conchan, SELECT_INVERT);
@@ -2076,1073 +3553,600 @@ static void mouse_actionchannels (short mval[])
return;
}
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
- allqueue (REDRAWOOPS, 0);
- allqueue (REDRAWBUTSALL, 0);
-}
-
-void delete_meshchannel_keys(Key *key)
-{
- delete_ipo_keys(key->ipo);
-
- BIF_undo_push("Delete Action Keys");
- meshkey_do_redraw(key);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void delete_actionchannel_keys(void)
-{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- act = G.saction->action;
- if (!act)
- return;
-
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- /* Check action channel keys*/
- delete_ipo_keys(achan->ipo);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* Delete constraint channel keys */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- delete_ipo_keys(conchan->ipo);
- }
- }
- }
- }
-
- remake_action_ipos(act);
- BIF_undo_push("Delete Action Keys");
- allspace(REMAKEIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
-
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWBUTSALL, 0);
}
-static void delete_actionchannels (void)
-{
- bAction *act;
- bActionChannel *achan, *next;
- bConstraintChannel *conchan=NULL, *nextconchan;
- int freechan;
+/* **************************************************** */
+/* ACTION CHANNEL RE-ORDERING */
- act=G.saction->action;
-
- if (!act)
- return;
-
- for (achan=act->chanbase.first; achan; achan=achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan))
- break;
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
- if (SEL_CONCHAN(conchan)) {
- achan= act->chanbase.last;
- break;
- }
- }
- }
- }
-
- if (!achan && !conchan)
- return;
+/* make sure all action-channels belong to a group (and clear action's list) */
+static void split_groups_action_temp (bAction *act, bActionGroup *tgrp)
+{
+ bActionChannel *achan;
+ bActionGroup *agrp;
- for (achan= act->chanbase.first; achan; achan= next) {
- freechan = 0;
- next= achan->next;
-
- if (VISIBLE_ACHAN(achan)) {
- /* Remove action channels */
- if (SEL_ACHAN(achan)) {
- if (achan->ipo)
- achan->ipo->id.us--; /* Release the ipo */
- freechan = 1;
+ /* Separate action-channels into lists per group */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ if (agrp->channels.first) {
+ achan= agrp->channels.last;
+ act->chanbase.first= achan->next;
- /* Remove constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan=nextconchan) {
- nextconchan= conchan->next;
- if (freechan || SEL_CONCHAN(conchan)) {
- if (conchan->ipo)
- conchan->ipo->id.us--;
- BLI_freelinkN(&achan->constraintChannels, conchan);
- }
- }
- }
+ achan= agrp->channels.first;
+ achan->prev= NULL;
- if (freechan)
- BLI_freelinkN (&act->chanbase, achan);
+ achan= agrp->channels.last;
+ achan->next= NULL;
}
}
-
- BIF_undo_push("Delete Action channels");
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-
-}
-
-void clean_shapekeys(Key *key)
-{
- int ok;
-
- /* don't proceed if user refuses */
- if (!key) return;
- ok= fbutton(&G.scene->toolsettings->clean_thresh,
- 0.0000001f, 1.0, 0.001, 0.1,
- "Clean Threshold");
- if (!ok) return;
- /* viable option? */
- if (key->ipo) {
- IpoCurve *icu;
+ /* Initialise memory for temp-group */
+ memset(tgrp, 0, sizeof(bActionGroup));
+ tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP);
+ strcpy(tgrp->name, "#TempGroup");
- for (icu= key->ipo->curve.first; icu; icu=icu->next)
- clean_ipo_curve(icu);
-
- /* admin and redraw stuff */
- BIF_undo_push("Clean Action");
- allqueue(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
+ /* Move any action-channels not already moved, to the temp group */
+ if (act->chanbase.first) {
+ /* start of list */
+ achan= act->chanbase.first;
+ achan->prev= NULL;
+ tgrp->channels.first= achan;
+ act->chanbase.first= NULL;
+
+ /* end of list */
+ achan= act->chanbase.last;
+ achan->next= NULL;
+ tgrp->channels.last= achan;
+ act->chanbase.last= NULL;
}
+
+ /* Add temp-group to list */
+ BLI_addtail(&act->groups, tgrp);
}
-void clean_actionchannels(bAction *act)
+/* link lists of channels that groups have */
+static void join_groups_action_temp (bAction *act)
{
+ bActionGroup *agrp;
bActionChannel *achan;
- bConstraintChannel *conchan;
-
- Ipo *ipo;
- IpoCurve *icu;
-
- int ok;
-
- /* don't proceed any further if no action or user refuses */
- if (!act) return;
- ok= fbutton(&G.scene->toolsettings->clean_thresh,
- 0.0000001f, 1.0, 0.001, 0.1,
- "Clean Threshold");
- if (!ok) return;
- /* clean selected channels only */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- /* clean if action channel if selected */
- if (SEL_ACHAN(achan)) {
- ipo= achan->ipo;
- if (ipo) {
- if (EXPANDED_ACHAN(achan) && FILTER_IPO_ACHAN(achan)) {
- /* only clean selected ipo-curves */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (SEL_ICU(icu) && EDITABLE_ICU(icu))
- clean_ipo_curve(icu);
- }
- }
- else {
- /* clean all ipo-curves for action channel */
- for (icu= ipo->curve.first; icu; icu= icu->next)
- clean_ipo_curve(icu);
- }
- }
- }
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* clean action channel's constraint channels */
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- ipo= conchan->ipo;
- if (ipo) {
- for (icu= ipo->curve.first; icu; icu= icu->next)
- clean_ipo_curve(icu);
- }
- }
- }
- }
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ ListBase tempGroup;
+
+ /* add list of channels to action's channels */
+ tempGroup= agrp->channels;
+ addlisttolist(&act->chanbase, &agrp->channels);
+ agrp->channels= tempGroup;
+
+ /* clear moved flag */
+ agrp->flag &= ~AGRP_MOVED;
+
+ /* if temp-group... remove from list (but don't free as it's on the stack!) */
+ if (agrp->flag & AGRP_TEMP) {
+ BLI_remlink(&act->groups, agrp);
+ break;
}
}
- /* admin and redraws */
- BIF_undo_push("Clean Action");
- allqueue(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
+ /* clear "moved" flag from all achans */
+ for (achan= act->chanbase.first; achan; achan= achan->next)
+ achan->flag &= ~ACHAN_MOVED;
}
-void sethandles_meshchannel_keys(int code, Key *key)
+
+static short rearrange_actchannel_is_ok (Link *channel, short type)
{
+ if (type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= (bActionGroup *)channel;
+
+ if (SEL_AGRP(agrp) && !(agrp->flag & AGRP_MOVED))
+ return 1;
+ }
+ else if (type == ACTTYPE_ACHAN) {
+ bActionChannel *achan= (bActionChannel *)channel;
+
+ if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED))
+ return 1;
+ }
- sethandles_ipo_keys(key->ipo, code);
-
- BIF_undo_push("Set handles Action keys");
- meshkey_do_redraw(key);
+ return 0;
}
-void sethandles_actionchannel_keys(int code)
+static short rearrange_actchannel_after_ok (Link *channel, short type)
{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act)
- return;
-
- /* Loop through the channels and set the beziers
- * of the selected keys based on the integer code
- */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- sethandles_ipo_keys(achan->ipo, code);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- sethandles_ipo_keys(conchan->ipo, code);
- }
- }
- }
+ if (type == ACTTYPE_GROUP) {
+ bActionGroup *agrp= (bActionGroup *)channel;
+
+ if (agrp->flag & AGRP_TEMP)
+ return 0;
}
-
- /* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set handles Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
+
+ return 1;
}
-void set_ipotype_actionchannels(int ipotype)
-{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- short event;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act)
- return;
-
- if (ipotype == SET_IPO_POPUP) {
- /* Present a popup menu asking the user what type
- * of IPO curve he/she/GreenBTH wants. ;)
- */
- event
- = pupmenu("Channel Ipo Type %t|"
- "Constant %x1|"
- "Linear %x2|"
- "Bezier %x3");
- if(event < 1) return;
- ipotype = event;
- }
-
- /* Loop through the channels and for the selected ones set
- * the type for each Ipo curve in the channel Ipo (based on
- * the value from the popup).
- */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan)) {
- if (achan->ipo)
- setipotype_ipo(achan->ipo, ipotype);
- }
+static short rearrange_actchannel_top (ListBase *list, Link *channel, short type)
+{
+ if (rearrange_actchannel_is_ok(channel, type)) {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (SEL_CONCHAN(conchan)) {
- if (conchan->ipo)
- setipotype_ipo(conchan->ipo, ipotype);
- }
- }
- }
- }
- }
+ /* make it first element */
+ BLI_insertlinkbefore(list, list->first, channel);
+
+ return 1;
}
-
- /* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set Ipo type Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
+
+ return 0;
}
-void set_extendtype_actionchannels(int extendtype)
+static short rearrange_actchannel_up (ListBase *list, Link *channel, short type)
{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- short event;
-
- /* Get the selected action, exit if none are selected
- */
- act = G.saction->action;
- if (!act)
- return;
-
- if (extendtype == SET_EXTEND_POPUP) {
- /* Present a popup menu asking the user what type
- * of IPO curve he/she/GreenBTH wants. ;)
- */
- event
- = pupmenu("Channel Extending Type %t|"
- "Constant %x1|"
- "Extrapolation %x2|"
- "Cyclic %x3|"
- "Cyclic extrapolation %x4");
- if(event < 1) return;
- extendtype = event;
- }
-
- /* Loop through the channels and for the selected ones set
- * the type for each Ipo curve in the channel Ipo (based on
- * the value from the popup).
- */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan)) {
- if (achan->ipo) {
- switch (extendtype) {
- case SET_EXTEND_CONSTANT:
- setexprap_ipoloop(achan->ipo, IPO_HORIZ);
- break;
- case SET_EXTEND_EXTRAPOLATION:
- setexprap_ipoloop(achan->ipo, IPO_DIR);
- break;
- case SET_EXTEND_CYCLIC:
- setexprap_ipoloop(achan->ipo, IPO_CYCL);
- break;
- case SET_EXTEND_CYCLICEXTRAPOLATION:
- setexprap_ipoloop(achan->ipo, IPO_CYCLX);
- break;
- }
- }
- }
+ if (rearrange_actchannel_is_ok(channel, type)) {
+ Link *prev= channel->prev;
+
+ if (prev) {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
+ /* push it up */
+ BLI_insertlinkbefore(list, prev, channel);
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (SEL_CONCHAN(conchan)) {
- if (conchan->ipo) {
- switch (extendtype) {
- case SET_EXTEND_CONSTANT:
- setexprap_ipoloop(conchan->ipo, IPO_HORIZ);
- break;
- case SET_EXTEND_EXTRAPOLATION:
- setexprap_ipoloop(conchan->ipo, IPO_DIR);
- break;
- case SET_EXTEND_CYCLIC:
- setexprap_ipoloop(conchan->ipo, IPO_CYCL);
- break;
- case SET_EXTEND_CYCLICEXTRAPOLATION:
- setexprap_ipoloop(conchan->ipo, IPO_CYCLX);
- break;
- }
- }
- }
- }
- }
+ return 1;
}
}
-
- /* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set Ipo type Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
+
+ return 0;
}
-static void set_snap_actionchannels(bAction *act, short snaptype)
+static short rearrange_actchannel_down (ListBase *list, Link *channel, short type)
{
- /* snapping function for action channels*/
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* Loop through the channels */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- if (achan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- snap_ipo_keys(achan->ipo, snaptype);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
- }
- else {
- snap_ipo_keys(achan->ipo, snaptype);
- }
- }
+ if (rearrange_actchannel_is_ok(channel, type)) {
+ Link *next = (channel->next) ? channel->next->next : NULL;
+
+ if (next) {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
+ /* move it down */
+ BLI_insertlinkbefore(list, next, channel);
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- snap_ipo_keys(conchan->ipo, snaptype);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- snap_ipo_keys(conchan->ipo, snaptype);
- }
- }
- }
- }
+ return 1;
+ }
+ else if (rearrange_actchannel_after_ok(list->last, type)) {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
+
+ /* add at end */
+ BLI_addtail(list, channel);
+
+ return 1;
+ }
+ else {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
+
+ /* add just before end */
+ BLI_insertlinkbefore(list, list->last, channel);
+
+ return 1;
}
}
+
+ return 0;
}
-static void set_snap_meshchannels(Key *key, short snaptype)
+static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short type)
{
- /* snapping function for mesh channels */
- if(key->ipo) {
- snap_ipo_keys(key->ipo, snaptype);
+ if (rearrange_actchannel_is_ok(channel, type)) {
+ if (rearrange_actchannel_after_ok(list->last, type)) {
+ /* take it out off the chain keep data */
+ BLI_remlink(list, channel);
+
+ /* add at end */
+ BLI_addtail(list, channel);
+
+ return 1;
+ }
}
+
+ return 0;
}
-void snap_keys_to_frame(int snap_mode)
+/* Change the order of action-channels
+ * mode: REARRANGE_ACTCHAN_*
+ */
+void rearrange_action_channels (short mode)
{
- /* This function is the generic entry-point for snapping keyframes
- * to a frame(s). It passes the work off to sub-functions for the
- * different types in the action editor.
- */
-
- SpaceAction *saction;
bAction *act;
- Key *key;
- char str[32];
-
- /* get data */
- saction= curarea->spacedata.first;
- if (!saction) return;
- act = saction->action;
- key = get_action_mesh_key();
+ bActionChannel *achan, *chan;
+ bActionGroup *agrp, *grp;
+ bActionGroup tgrp;
- /* determine mode */
- switch (snap_mode) {
- case 1:
- strcpy(str, "Snap Keys To Nearest Frame");
+ void *data;
+ short datatype;
+
+ short (*rearrange_func)(ListBase *, Link *, short);
+ short do_channels = 1;
+ char undostr[60];
+
+ /* Get the active action, exit if none are selected */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* exit if invalid mode */
+ switch (mode) {
+ case REARRANGE_ACTCHAN_TOP:
+ strcpy(undostr, "Channel(s) to Top");
+ rearrange_func= rearrange_actchannel_top;
break;
- case 2:
- strcpy(str, "Snap Keys To Current Frame");
+ case REARRANGE_ACTCHAN_UP:
+ strcpy(undostr, "Channel(s) Move Up");
+ rearrange_func= rearrange_actchannel_up;
break;
- case 3:
- strcpy(str, "Snap Keys To Nearest Marker");
+ case REARRANGE_ACTCHAN_DOWN:
+ strcpy(undostr, "Channel(s) Move Down");
+ rearrange_func= rearrange_actchannel_down;
+ break;
+ case REARRANGE_ACTCHAN_BOTTOM:
+ strcpy(undostr, "Channel(s) to Bottom");
+ rearrange_func= rearrange_actchannel_bottom;
break;
default:
return;
}
- /* snap to frame */
- if (act) {
- set_snap_actionchannels(act, snap_mode);
- remake_action_ipos (act);
- }
- else if (key) {
- set_snap_meshchannels(key, snap_mode);
+ /* make sure we're only operating with groups */
+ split_groups_action_temp(act, &tgrp);
+
+ /* rearrange groups first (and then, only consider channels if the groups weren't moved) */
+ #define GET_FIRST(list) ((mode > 0) ? (list.first) : (list.last))
+ #define GET_NEXT(item) ((mode > 0) ? (item->next) : (item->prev))
+
+ for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
+ /* Get next group to consider */
+ grp= GET_NEXT(agrp);
+
+ /* try to do group first */
+ if (rearrange_func(&act->groups, (Link *)agrp, ACTTYPE_GROUP)) {
+ do_channels= 0;
+ agrp->flag |= AGRP_MOVED;
+ }
}
- else {
- return;
+
+ if (do_channels) {
+ for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
+ /* Get next group to consider */
+ grp= GET_NEXT(agrp);
+
+ /* only consider action-channels if they're visible (group expanded) */
+ if (EXPANDED_AGRP(agrp)) {
+ for (achan= GET_FIRST(agrp->channels); achan; achan= chan) {
+ /* Get next channel to consider */
+ chan= GET_NEXT(achan);
+
+ /* Try to do channel */
+ if (rearrange_func(&agrp->channels, (Link *)achan, ACTTYPE_ACHAN))
+ achan->flag |= ACHAN_MOVED;
+ }
+ }
+ }
}
+ #undef GET_FIRST
+ #undef GET_NEXT
- BIF_undo_push(str);
- allspace(REMAKEIPO, 0);
+ /* assemble lists into one list (and clear moved tags) */
+ join_groups_action_temp(act);
+
+ /* Undo + redraw */
+ BIF_undo_push(undostr);
allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
}
-static void mirror_actionchannels(bAction *act, short mirror_mode)
+/* ******************************************************************* */
+/* CHANNEL VISIBILITY/FOLDING */
+
+/* Expand all channels to show full hierachy */
+void expand_all_action (void)
{
- /* mirror function for action channels */
+ void *data;
+ short datatype;
+
+ bAction *act;
bActionChannel *achan;
- bConstraintChannel *conchan;
+ bActionGroup *agrp;
+ short mode= 1;
- /* Loop through the channels */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (achan->ipo) {
- if (G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- mirror_ipo_keys(achan->ipo, mirror_mode);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
- }
- else {
- mirror_ipo_keys(achan->ipo, mirror_mode);
+ /* Get the selected action, exit if none are selected */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* check if expand all, or close all */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ if (EXPANDED_AGRP(agrp)) {
+ mode= 0;
+ break;
+ }
+ }
+
+ if (mode == 0) {
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (EXPANDED_ACHAN(achan)) {
+ mode= 0;
+ break;
}
}
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- mirror_ipo_keys(conchan->ipo, mirror_mode);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- mirror_ipo_keys(conchan->ipo, mirror_mode);
- }
- }
- }
- }
}
}
-}
-
-static void mirror_meshchannels(Key *key, short mirror_mode)
-{
- /* mirror function for mesh channels */
- if(key->ipo) {
- mirror_ipo_keys(key->ipo, mirror_mode);
+
+ /* expand/collapse depending on mode */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ if (mode == 1)
+ agrp->flag |= AGRP_EXPANDED;
+ else
+ agrp->flag &= ~AGRP_EXPANDED;
}
+
+ for (achan=act->chanbase.first; achan; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (mode == 1)
+ achan->flag |= (ACHAN_EXPANDED|ACHAN_SHOWIPO|ACHAN_SHOWCONS);
+ else
+ achan->flag &= ~(ACHAN_EXPANDED|ACHAN_SHOWIPO|ACHAN_SHOWCONS);
+ }
+ }
+
+ /* Cleanup and do redraws */
+ BIF_undo_push("Expand Action Hierachy");
+ allqueue(REDRAWACTION, 0);
}
-void mirror_action_keys(short mirror_mode)
+/* Expands those groups which are hiding a selected actionchannel */
+void expand_obscuregroups_action (void)
{
- /* This function is the generic entry-point for mirroring keyframes
- * to over a frame. It passes the work off to sub-functions for the
- * different types in the action editor.
- */
-
- SpaceAction *saction;
+ void *data;
+ short datatype;
+
bAction *act;
- Key *key;
- char str[32];
-
- /* get data */
- saction= curarea->spacedata.first;
- if (!saction) return;
- act = saction->action;
- key = get_action_mesh_key();
+ bActionChannel *achan;
- /* determine mode */
- switch (mirror_mode) {
- case 1:
- strcpy(str, "Mirror Keys Over Current Frame");
- break;
- case 2:
- strcpy(str, "Mirror Keys Over Y-Axis");
- break;
- case 3:
- strcpy(str, "Mirror Keys Over X-Axis");
- break;
- case 4:
- strcpy(str, "Mirror Keys Over Marker");
- break;
- default:
- return;
- }
+ /* Get the selected action, exit if none are selected */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
- /* mirror */
- if (act) {
- mirror_actionchannels(act, mirror_mode);
- remake_action_ipos (act);
- }
- else if (key) {
- mirror_meshchannels(key, mirror_mode);
- }
- else {
- return;
+ /* check if expand all, or close all */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
+ if (achan->grp)
+ achan->grp->flag |= AGRP_EXPANDED;
+ }
}
- BIF_undo_push(str);
- allspace(REMAKEIPO, 0);
+ /* Cleanup and do redraws */
+ BIF_undo_push("Show Group-Hidden Channels");
allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
}
-/* This function allows the user to insert keyframes on the current
- * frame from the Action Editor, using the current values of the channels
- * to be keyframed.
- */
-void insertkey_action(void)
+/* For visible channels, expand/collapse one level */
+void openclose_level_action (short mode)
{
+ void *data;
+ short datatype;
+
bAction *act;
- Key *key;
- Object *ob= OBACT;
- IpoCurve *icu;
- short mode;
- float cfra;
+ bActionChannel *achan;
+ bActionGroup *agrp;
- /* get data */
- act = G.saction->action;
- key = get_action_mesh_key();
- cfra = frame_to_float(CFRA);
+ /* Get the selected action, exit if none are selected */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
- if (act) {
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* ask user what to keyframe */
- mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
- if (mode == 0) return;
-
- for (achan= act->chanbase.first; achan; achan=achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (achan->ipo && (SEL_ACHAN(achan) || (mode == 1))) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (ob)
- insertkey((ID *)ob, icu->blocktype, achan->name, NULL, icu->adrcode);
- else
- insert_vert_ipo(icu, cfra, icu->curval);
- }
- }
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo && (SEL_ACHAN(conchan) || (mode == 1))) {
- for (icu= conchan->ipo->curve.first; icu; icu=icu->next) {
- /* // commented out as this doesn't seem to work right for some reason
- if (ob)
- insertkey((ID *)ob, ID_CO, achan->name, conchan->name, CO_ENFORCE);
- else
- insert_vert_ipo(icu, cfra, icu->curval);
- */
- insert_vert_ipo(icu, cfra, icu->curval);
- }
- }
- }
+ /* Abort if no operation required */
+ if (mode == 0) return;
+
+ /* Only affect selected channels */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ /* make sure if there is a group, it isn't about to be collapsed and is open */
+ if ( (achan->grp==NULL) || (EXPANDED_AGRP(achan->grp) && SEL_AGRP(achan->grp)==0) ) {
+ if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
+ if (EXPANDED_ACHAN(achan)) {
+ if (FILTER_IPO_ACHAN(achan) || FILTER_CON_ACHAN(achan)) {
+ if (mode < 0)
+ achan->flag &= ~(ACHAN_SHOWIPO|ACHAN_SHOWCONS);
}
+ else {
+ if (mode > 0)
+ achan->flag |= (ACHAN_SHOWIPO|ACHAN_SHOWCONS);
+ else
+ achan->flag &= ~ACHAN_EXPANDED;
+ }
+ }
+ else {
+ if (mode > 0)
+ achan->flag |= ACHAN_EXPANDED;
}
}
}
}
- else if (key) {
- /* ask user if they want to insert a keyframe */
- mode = okee("Insert Keyframe?");
- if (mode == 0) return;
-
- if (key->ipo) {
- for (icu= key->ipo->curve.first; icu; icu=icu->next) {
- insert_vert_ipo(icu, cfra, icu->curval);
- }
+
+ /* Expand/collapse selected groups */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ if (SEL_AGRP(agrp)) {
+ if (mode < 0)
+ agrp->flag &= ~AGRP_EXPANDED;
+ else
+ agrp->flag |= AGRP_EXPANDED;
}
}
- BIF_undo_push("Insert Key");
- allspace(REMAKEIPO, 0);
+ /* Cleanup and do redraws */
+ BIF_undo_push("Expand/Collapse Action Level");
allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
}
-static void select_all_keys_frames(bAction *act, short *mval,
- short *mvalo, int selectmode)
+/* **************************************************** */
+/* ACTION MARKERS (PoseLib features) */
+/* NOTE: yes, these duplicate code from edittime.c a bit, but these do a bit more...
+ * These could get merged with those someday if need be... (Aligorith, 20071230)
+ */
+
+/* Makes the given marker the active one
+ * - deselect indicates whether unactive ones should be deselected too
+ */
+void action_set_activemarker (bAction *act, TimeMarker *active, short deselect)
{
+ TimeMarker *marker;
+ int index= 0;
- /* This function tries to select all action keys in
- * every channel for a given range of keyframes that
- * are within the mouse values mval and mvalo (usually
- * the result of a border select). If mvalo is passed as
- * NULL then the selection is treated as a one-click and
- * the function tries to select all keys within half a
- * frame of the click point.
- */
-
- rcti rect;
- rctf rectf;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- if (!act)
+ /* sanity checks */
+ if (act == NULL)
return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannel_keys(act, 0, 0);
- selectmode = SELECT_ADD;
- }
-
- if (mvalo == NULL) {
- rect.xmin = rect.xmax = mval[0];
- rect.ymin = rect.ymax = mval[1];
- }
- else {
- if (mval[0] < mvalo[0] ) {
- rect.xmin = mval[0];
- rect.xmax = mvalo[0];
- }
- else {
- rect.xmin = mvalo[0];
- rect.xmax = mval[0];
- }
- if (mval[1] < mvalo[1] ) {
- rect.ymin = mval[1];
- rect.ymax = mvalo[1];
+ act->active_marker= 0;
+
+ /* set appropriate flags for all markers */
+ for (marker=act->markers.first; marker; marker=marker->next, index++) {
+ /* only active may be active */
+ if (marker == active) {
+ act->active_marker= index + 1;
+ marker->flag |= (SELECT|ACTIVE);
}
else {
- rect.ymin = mvalo[1];
- rect.ymax = mval[1];
- }
- }
-
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- if (mvalo == NULL) {
- rectf.xmin = rectf.xmin - 0.5;
- rectf.xmax = rectf.xmax + 0.5;
- }
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
- }
- }
+ if (deselect)
+ marker->flag &= ~(SELECT|ACTIVE);
+ else
+ marker->flag &= ~ACTIVE;
}
}
-
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
}
-
-static void select_all_keys_channels(bAction *act, short *mval,
- short *mvalo, int selectmode)
+/* Adds a local marker to the active action */
+void action_add_localmarker (bAction *act, int frame)
{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- float click, x,y;
- int clickmin, clickmax;
-
- /* This function selects all the action keys that
- * are in the mouse selection range defined by
- * the ordered pairs mval and mvalo (usually
- * these 2 are obtained from a border select).
- * If mvalo is NULL, then the selection is
- * treated like a one-click action, and at most
- * one channel is selected.
- */
-
- /* If the action is null then abort */
- if (!act)
- return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannel_keys(act, 0, 0);
- selectmode = SELECT_ADD;
- }
+ TimeMarker *marker;
+ char name[64];
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+ /* sanity checks */
+ if (act == NULL)
+ return;
- /* Only one click */
- if (mvalo == NULL) {
- clickmax = clickmin;
- }
- /* Two click values (i.e., border select) */
- else {
- areamouseco_to_ipoco(G.v2d, mvalo, &x, &y);
- click = (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
-
- if ( ((int) click) < clickmin) {
- clickmax = clickmin;
- clickmin = (int) click;
- }
- else {
- clickmax = (int) click;
- }
- }
-
- if (clickmax < 0) {
+ /* get name of marker */
+ sprintf(name, "Pose");
+ if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
return;
- }
-
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (clickmax < 0) break;
-
- if (clickmin <= 0) {
- /* Select the channel with the given mode. If the
- * channel is freshly selected then set it to the
- * active channel for the action
- */
- select_ipo_bezier_keys(achan->ipo, selectmode);
- }
- --clickmin;
- --clickmax;
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* Check for click in a constraint */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0) break;
- if (clickmin <= 0) {
- select_ipo_bezier_keys(achan->ipo, selectmode);
- }
- --clickmin;
- --clickmax;
- }
+
+ /* add marker to action - replaces any existing marker there */
+ for (marker= act->markers.first; marker; marker= marker->next) {
+ if (marker->frame == frame) {
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ break;
}
}
-
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
-}
-
-static void borderselect_function(void (*select_func)(bAction *act,
- short *mval,
- short *mvalo,
- int selectmode))
-{
- /* This function executes an arbitrary selection
- * function as part of a border select. This
- * way the same function that is used for
- * right click selection points can generally
- * be used as the argument to this function
- */
- bAction *act;
- rcti rect;
- short mval[2], mvalo[2];
- int val;
-
- /* Get the selected action, exit if none are selected */
- act=G.saction->action;
- if (!act)
- return;
-
- /* Let the user draw a border (or abort) */
- if ( (val=get_border (&rect, 3)) ) {
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- mvalo[0]= rect.xmax;
- mvalo[1]= rect.ymax-2;
-
- /* if the left mouse was used, do an additive
- * selection with the user defined selection
- * function.
- */
- if (val == LEFTMOUSE)
- select_func(act, mval, mvalo, SELECT_ADD);
+ if (marker == NULL) {
+ marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
- /* if the right mouse was used, do a subtractive
- * selection with the user defined selection
- * function.
- */
- else if (val == RIGHTMOUSE)
- select_func(act, mval, mvalo, SELECT_SUBTRACT);
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ marker->frame= frame;
+
+ BLI_addtail(&act->markers, marker);
}
- BIF_undo_push("Border Select Action");
-}
-
-static void clever_keyblock_names(Key *key, short* mval){
- int but=0, i, keynum;
- char str[64];
- float x;
- KeyBlock *kb;
- /* get the keynum cooresponding to the y value
- * of the mouse pointer, return if this is
- * an invalid key number (and we don't deal
- * with the speed ipo).
- */
-
- keynum = get_nearest_key_num(key, mval, &x);
- if ( (keynum < 1) || (keynum >= key->totkey) )
- return;
-
- kb= key->block.first;
- for (i=0; i<keynum; ++i) kb = kb->next;
-
- if (kb->name[0] == '\0') {
- sprintf(str, "Key %d", keynum);
- }
- else {
- strcpy(str, kb->name);
- }
-
- if ( (kb->slidermin >= kb->slidermax) ) {
- kb->slidermin = 0.0;
- kb->slidermax = 1.0;
- }
-
- add_numbut(but++, TEX, "KB: ", 0, 24, str,
- "Does this really need a tool tip?");
- add_numbut(but++, NUM|FLO, "Slider Min:",
- -10000, kb->slidermax, &kb->slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:",
- kb->slidermin, 10000, &kb->slidermax, 0);
-
- if (do_clever_numbuts(str, but, REDRAW)) {
- strcpy(kb->name, str);
- allqueue (REDRAWACTION, 0);
- allspace(REMAKEIPO, 0);
- allqueue (REDRAWIPO, 0);
- }
-
+ /* validate the name */
+ BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
+
+ /* sets the newly added marker as the active one */
+ action_set_activemarker(act, marker, 1);
+ BIF_undo_push("Action Add Marker");
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
-static void clever_achannel_names(short *mval)
+/* Renames the active local marker to the active action */
+void action_rename_localmarker (bAction *act)
{
- void *act_channel;
- bActionChannel *achan= NULL;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
+ TimeMarker *marker;
+ char name[64];
+ int val;
- int but=0;
- char str[64];
- short expand, protect, chantype;
- float slidermin, slidermax;
+ /* sanity checks */
+ if (act == NULL)
+ return;
- /* figure out what is under cursor */
- act_channel= get_nearest_act_channel(mval, &chantype);
+ /* get active marker to rename */
+ if (act->active_marker == 0)
+ return;
+ else
+ val= act->active_marker;
- /* create items for clever-numbut */
- if (chantype == ACTTYPE_ACHAN) {
- achan= (bActionChannel *)act_channel;
-
- strcpy(str, achan->name);
- protect= (achan->flag & ACHAN_PROTECTED);
- expand = (achan->flag & ACHAN_EXPANDED);
-
- add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
- add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_CONCHAN) {
- conchan= (bConstraintChannel *)act_channel;
-
- strcpy(str, conchan->name);
- protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
-
- add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_ICU) {
- icu= (IpoCurve *)act_channel;
-
- strcpy(str, getname_ipocurve(icu));
-
- if (IS_EQ(icu->slide_max, icu->slide_min)) {
- if (IS_EQ(icu->ymax, icu->ymin)) {
- icu->slide_min= -100.0;
- icu->slide_max= 100.0;
- }
- else {
- icu->slide_min= icu->ymin;
- icu->slide_max= icu->ymax;
- }
- }
- slidermin= icu->slide_min;
- slidermax= icu->slide_max;
-
- //protect= (icu->flag & IPO_PROTECT);
-
- add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
- //add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else {
- /* nothing under-cursor */
+ if (val <= 0) return;
+ marker= BLI_findlink(&act->markers, val-1);
+ if (marker == NULL) return;
+
+ /* get name of marker */
+ sprintf(name, marker->name);
+ if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
return;
- }
+ /* copy then validate name */
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
- /* draw clever-numbut */
- if (do_clever_numbuts(str, but, REDRAW)) {
- /* restore settings based on type */
- if (icu) {
- icu->slide_min= slidermin;
- icu->slide_max= slidermax;
-
- //if (protect) icu->flag |= IPO_PROTECT;
- //else icu->flag &= ~IPO_PROTECT;
- }
- else if (conchan) {
- strcpy(conchan->name, str);
-
- if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
- else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
- }
- else if (achan) {
- strcpy(achan->name, str);
-
- if (expand) achan->flag |= ACHAN_EXPANDED;
- else achan->flag &= ~ACHAN_EXPANDED;
-
- if (protect) achan->flag |= ACHAN_PROTECTED;
- else achan->flag &= ~ACHAN_PROTECTED;
- }
-
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWVIEW3D, 0);
- }
+ /* undo and update */
+ BIF_undo_push("Action Rename Marker");
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
}
-/* this gets called when nkey is pressed (no Transform Properties panel yet) */
-static void numbuts_action(void)
+/* Deletes all selected markers, and adjusts things as appropriate */
+void action_remove_localmarkers (bAction *act)
{
- /* now called from action window event loop, plus reacts on mouseclick */
- /* removed Hos grunts for that reason! :) (ton) */
- bAction *act;
- Key *key;
- short mval[2];
+ TimeMarker *marker, *next;
- key = get_action_mesh_key();
- act = G.saction->action;
+ /* sanity checks */
+ if (act == NULL)
+ return;
+
+ /* remove selected markers */
+ for (marker= act->markers.first; marker; marker= next) {
+ next= marker->next;
+
+ if (marker->flag & SELECT)
+ BLI_freelinkN(&act->markers, marker);
+ }
- getmouseco_areawin (mval);
+ /* clear active just in case */
+ act->active_marker= 0;
- if (mval[0] < NAMEWIDTH) {
- if (act)
- clever_achannel_names(mval);
- else if (key)
- clever_keyblock_names(key, mval);
- }
+ /* undo and update */
+ BIF_undo_push("Action Remove Marker(s)");
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
}
+/* **************************************************** */
+/* EVENT HANDLING */
+
void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
extern void do_actionbuts(unsigned short event); // drawaction.c
SpaceAction *saction;
- bAction *act;
- Key *key;
+ void *data;
+ short datatype;
float dx, dy;
int doredraw= 0;
int cfra;
@@ -3151,24 +4155,24 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
short val= evt->val;
short mousebut = L_MOUSE;
- if(curarea->win==0) return;
+ if (curarea->win==0) return;
saction= curarea->spacedata.first;
if (!saction)
return;
- act=saction->action;
- key = get_action_mesh_key();
+ data= get_action_context(&datatype);
if (val) {
- if ( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if ( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
if (event == LEFTMOUSE) {
event = RIGHTMOUSE;
mousebut = L_MOUSE;
- } else if (event == RIGHTMOUSE) {
+ }
+ else if (event == RIGHTMOUSE) {
event = LEFTMOUSE;
mousebut = R_MOUSE;
}
@@ -3178,190 +4182,240 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
switch(event) {
case UI_BUT_EVENT:
- do_actionbuts(val); // window itself
+ do_actionbuts(val); /* window itself */
break;
+
+ /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
+ * based on user preference USER_LMOUSESELECT
+ */
+ case LEFTMOUSE:
+ if (view2dmove(LEFTMOUSE)) /* only checks for sliders */
+ break;
+ else if ((G.v2d->mask.xmin==0) || (mval[0] > ACTWIDTH)) {
+ /* moving time-marker / current frame */
+ do {
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
+
+ cfra= (int)(dx+0.5f);
+ if (cfra < 1) cfra= 1;
+
+ if (cfra != CFRA) {
+ CFRA= cfra;
+ update_for_newframe();
+ force_draw_all(0);
+ }
+ else
+ PIL_sleep_ms(30);
+ }
+ while(get_mbut() & mousebut);
+ break;
+ }
+ /* passed on as selection */
+ case RIGHTMOUSE:
+ /* Clicking in the channel area */
+ if ((G.v2d->mask.xmin) && (mval[0] < NAMEWIDTH)) {
+ if (datatype == ACTCONT_ACTION) {
+ /* mouse is over action channels */
+ if (G.qual == LR_CTRLKEY)
+ numbuts_action();
+ else
+ mouse_actionchannels(mval);
+ }
+ else
+ numbuts_action();
+ }
+ else {
+ short select_mode= (G.qual & LR_SHIFTKEY)? SELECT_INVERT: SELECT_REPLACE;
+
+ /* Clicking in the vertical scrollbar selects
+ * all of the keys for that channel at that height
+ */
+ if (IN_2D_VERT_SCROLL(mval))
+ selectall_action_keys(mval, 0, select_mode);
- case HOMEKEY:
- do_action_buttons(B_ACTHOME); // header
+ /* Clicking in the horizontal scrollbar selects
+ * all of the keys within 0.5 of the nearest integer
+ * frame
+ */
+ else if (IN_2D_HORIZ_SCROLL(mval))
+ selectall_action_keys(mval, 1, select_mode);
+
+ /* Clicking in the main area of the action window
+ * selects keys and markers
+ */
+ else if (G.qual & LR_ALTKEY) {
+ areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
+
+ /* sends a 1 for left and 0 for right */
+ selectkeys_leftright((dx < (float)CFRA), select_mode);
+ }
+ else
+ mouse_action(select_mode);
+ }
break;
-
+
+ case MIDDLEMOUSE:
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ view2dmove(event); /* in drawipo.c */
+ break;
+
case AKEY:
- if (act) {
- if (mval[0]<NAMEWIDTH) {
- deselect_actionchannels (act, 1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (mval[0]>ACTWIDTH) {
- if (G.qual == LR_CTRLKEY) {
- deselect_markers (1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- else {
- deselect_actionchannel_keys (act, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- }
+ if (mval[0] < NAMEWIDTH) {
+ deselect_action_channels(1);
+ BIF_undo_push("(De)Select Action Channels");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
}
- else if (key) {
- if (mval[0]<ACTWIDTH) {
- /* to do ??? */
+ else if (mval[0] > ACTWIDTH) {
+ if (G.qual == LR_CTRLKEY) {
+ deselect_markers(1, 0);
+ BIF_undo_push("(De)Select Markers");
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWSOUND, 0);
}
else {
- if (G.qual == LR_CTRLKEY) {
- deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- else {
- deselect_meshchannel_keys(key, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ deselect_action_keys(1, 1);
+ BIF_undo_push("(De)Select Keys");
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
}
}
break;
-
+
case BKEY:
- if (G.qual & LR_CTRLKEY)
+ if (G.qual & LR_CTRLKEY) {
borderselect_markers();
- else if (act) {
- /* If the border select is initiated in the
- * part of the action window where the channel
- * names reside, then select the channels
- */
- if (mval[0]<NAMEWIDTH) {
- borderselect_function(borderselect_actionchannels);
- BIF_undo_push("Select Action");
- }
- else if (mval[0]>ACTWIDTH) {
- /* If the border select is initiated in the
- * vertical scrollbar, then (de)select all keys
- * for the channels in the selection region
- */
- if (IN_2D_VERT_SCROLL(mval)) {
- borderselect_function(select_all_keys_channels);
- }
-
- /* If the border select is initiated in the
- * horizontal scrollbar, then (de)select all keys
- * for the keyframes in the selection region
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- borderselect_function(select_all_keys_frames);
- }
-
- /* Other wise, select the action keys */
- else {
- borderselect_action();
- }
- }
}
- else if (key) {
- if (mval[0]<ACTWIDTH) {
- /* to do?? */
- }
- else {
- borderselect_mesh(key);
- }
+ else {
+ if (mval[0] >= ACTWIDTH)
+ borderselect_action();
}
break;
-
+
case CKEY:
/* scroll the window so the current
* frame is in the center.
*/
center_currframe();
break;
-
+
case DKEY:
- if (mval[0]>ACTWIDTH) {
- if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
+ if (mval[0] > ACTWIDTH) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
duplicate_marker();
- }
- else if (G.qual == LR_SHIFTKEY) {
- if (act) {
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
- }
- else if (key) {
- duplicate_meshchannel_keys(key);
- }
- }
+ else if (G.qual == LR_SHIFTKEY)
+ duplicate_action_keys();
}
break;
-
+
+ case EKEY:
+ if (mval[0] >= ACTWIDTH)
+ transform_action_keys('e', 0);
+ break;
+
case GKEY:
- if (G.qual & LR_CTRLKEY) {
- transform_markers('g', 0);
- }
+ /* Action Channel Groups */
+ if (G.qual == LR_SHIFTKEY)
+ action_groups_group(0);
+ else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ action_groups_group(1);
+ else if (G.qual == LR_ALTKEY)
+ action_groups_ungroup();
+
+ /* Transforms */
else {
- if (mval[0]>=ACTWIDTH) {
- if (act) {
- transform_actionchannel_keys ('g', 0);
- }
- else if (key) {
- transform_meshchannel_keys('g', key);
- }
+ if (mval[0] >= ACTWIDTH) {
+ if (G.qual == LR_CTRLKEY)
+ transform_markers('g', 0);
+ else
+ transform_action_keys('g', 0);
}
}
break;
case HKEY:
- if(G.qual & LR_SHIFTKEY) {
- if(okee("Set Keys to Auto Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_AUTO);
- else if (key)
- sethandles_meshchannel_keys(HD_AUTO, key);
- }
+ if (G.qual & LR_SHIFTKEY) {
+ if (okee("Set Keys to Auto Handle"))
+ sethandles_action_keys(HD_AUTO);
}
else {
- if(okee("Toggle Keys Aligned Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_ALIGN);
- else if (key)
- sethandles_meshchannel_keys(HD_ALIGN, key);
+ if (okee("Toggle Keys Aligned Handle"))
+ sethandles_action_keys(HD_ALIGN);
+ }
+ break;
+
+ case IKEY:
+ if (G.qual & LR_CTRLKEY) {
+ if (mval[0] < ACTWIDTH) {
+ deselect_action_channels(2);
+ BIF_undo_push("Inverse Action Channels");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ }
+ else if (G.qual & LR_SHIFTKEY) {
+ deselect_markers(0, 2);
+ BIF_undo_push("Inverse Markers");
+ allqueue(REDRAWMARKER, 0);
+ }
+ else {
+ deselect_action_keys(0, 2);
+ BIF_undo_push("Inverse Keys");
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
}
}
break;
case KKEY:
- if (G.qual & LR_CTRLKEY) {
+ if (G.qual == LR_ALTKEY)
markers_selectkeys_between();
- }
- else {
- val= (G.qual & LR_SHIFTKEY) ? 2 : 1;
-
- if (act)
- column_select_actionkeys(act, val);
- else if (key)
- column_select_shapekeys(key, val);
- }
+ else if (G.qual == LR_SHIFTKEY)
+ column_select_action_keys(2);
+ else if (G.qual == LR_CTRLKEY)
+ column_select_action_keys(3);
+ else
+ column_select_action_keys(1);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWMARKER, 0);
+ break;
+
+ case LKEY:
+ /* poselib manipulation - only for actions */
+ if (datatype == ACTCONT_ACTION) {
+ if (G.qual == LR_SHIFTKEY)
+ action_add_localmarker(data, CFRA);
+ else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ action_rename_localmarker(data);
+ else if (G.qual == LR_ALTKEY)
+ action_remove_localmarkers(data);
+ else if (G.qual == LR_CTRLKEY) {
+ G.saction->flag |= SACTION_POSEMARKERS_MOVE;
+ transform_markers('g', 0);
+ G.saction->flag &= ~SACTION_POSEMARKERS_MOVE;
+ }
+ }
break;
case MKEY:
if (G.qual & LR_SHIFTKEY) {
/* mirror keyframes */
- if (act || key) {
- val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
+ if (data) {
+ if (G.saction->flag & SACTION_DRAWTIME)
+ val = pupmenu("Mirror Keys Over%t|Current Time%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
+ else
+ val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
+
mirror_action_keys(val);
}
}
@@ -3373,16 +4427,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
rename_marker();
else
break;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
case NKEY:
- if(G.qual==0) {
+ if (G.qual==0) {
numbuts_action();
/* no panel (yet). current numbuts are not easy to put in panel... */
@@ -3392,10 +4442,10 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case OKEY:
- if(act)
- clean_actionchannels(act);
- else if(key)
- clean_shapekeys(key);
+ if (G.qual & LR_ALTKEY)
+ sample_action_keys();
+ else
+ clean_action();
break;
case PKEY:
@@ -3403,836 +4453,167 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
- allqueue(REDRAWTIME, 0);
+
+ allqueue(REDRAWMARKER, 0);
allqueue(REDRAWBUTSALL, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWIPO, 0);
break;
case SKEY:
if (mval[0]>=ACTWIDTH) {
- if(G.qual & LR_SHIFTKEY) {
- if (act || key) {
- val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
- snap_keys_to_frame(val);
+ if (G.qual == (LR_SHIFTKEY|LR_CTRLKEY)) {
+ if (data) {
+ snap_cfra_action();
+ }
+ }
+ else if (G.qual & LR_SHIFTKEY) {
+ if (data) {
+ if (G.saction->flag & SACTION_DRAWTIME)
+ val = pupmenu("Snap Keys To%t|Nearest Second%x4|Current Time%x2|Nearest Marker %x3");
+ else
+ val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
+
+ snap_action_keys(val);
}
}
else {
- if (act)
- transform_actionchannel_keys ('s', 0);
- else if (key)
- transform_meshchannel_keys('s', key);
+ transform_action_keys('s', 0);
}
}
break;
case TKEY:
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- set_ipotype_actionchannels(SET_IPO_POPUP);
- else
- transform_actionchannel_keys ('t', 0);
- }
- /* else if (key) {} ... todo */
+ if (G.qual & LR_SHIFTKEY)
+ action_set_ipo_flags(SET_IPO_POPUP, 0);
+ else if (G.qual & LR_CTRLKEY) {
+ val= pupmenu("Time value%t|Frames %x1|Seconds%x2");
+
+ if (val > 0) {
+ if (val == 2) saction->flag |= SACTION_DRAWTIME;
+ else saction->flag &= ~SACTION_DRAWTIME;
+
+ doredraw= 1;
+ }
+ }
+ else
+ transform_action_keys ('t', 0);
break;
-
+
case VKEY:
- if(okee("Set Keys to Vector Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_VECT);
- else if (key)
- sethandles_meshchannel_keys(HD_VECT, key);
+ if (okee("Set Keys to Vector Handle"))
+ sethandles_action_keys(HD_VECT);
+ break;
+
+ case WKEY:
+ /* toggle/turn-on\off-based-on-setting */
+ if (G.qual) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ val= 1;
+ else if (G.qual == LR_ALTKEY)
+ val= 2;
+ else
+ val= 0;
+
+ setflag_action_channels(val);
}
break;
-
+
case PAGEUPKEY:
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- top_sel_action();
- else if (G.qual & LR_CTRLKEY)
- up_sel_action();
+ if (datatype == ACTCONT_ACTION) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ rearrange_action_channels(REARRANGE_ACTCHAN_TOP);
+ else if (G.qual == LR_SHIFTKEY)
+ rearrange_action_channels(REARRANGE_ACTCHAN_UP);
+ else if (G.qual == LR_CTRLKEY)
+ nextprev_action_keyframe(1);
else
nextprev_marker(1);
}
- else if (key) {
+ else if (datatype == ACTCONT_SHAPEKEY) {
/* only jump to markers possible (key channels can't be moved yet) */
- nextprev_marker(1);
+ if (G.qual == LR_CTRLKEY)
+ nextprev_action_keyframe(1);
+ else
+ nextprev_marker(1);
}
break;
case PAGEDOWNKEY:
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- bottom_sel_action();
- else if (G.qual & LR_CTRLKEY)
- down_sel_action();
+ if (datatype == ACTCONT_ACTION) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ rearrange_action_channels(REARRANGE_ACTCHAN_BOTTOM);
+ else if (G.qual == LR_SHIFTKEY)
+ rearrange_action_channels(REARRANGE_ACTCHAN_DOWN);
+ else if (G.qual == LR_CTRLKEY)
+ nextprev_action_keyframe(-1);
else
nextprev_marker(-1);
}
- else if (key) {
+ else if (datatype == ACTCONT_SHAPEKEY) {
/* only jump to markers possible (key channels can't be moved yet) */
- nextprev_marker(-1);
+ if (G.qual == LR_CTRLKEY)
+ nextprev_action_keyframe(-1);
+ else
+ nextprev_marker(-1);
}
break;
case DELKEY:
case XKEY:
if (okee("Erase selected")) {
- if (act) {
- if (mval[0]<NAMEWIDTH)
- delete_actionchannels();
- else
- delete_actionchannel_keys();
- }
- else if (key) {
- delete_meshchannel_keys(key);
- }
+ if (mval[0] < NAMEWIDTH)
+ delete_action_channels();
+ else
+ delete_action_keys();
if (mval[0] >= NAMEWIDTH)
remove_marker();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
- /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
- * based on user preference USER_LMOUSESELECT
- */
- case LEFTMOUSE:
- if(view2dmove(LEFTMOUSE)) // only checks for sliders
- break;
- else if (mval[0]>ACTWIDTH) {
- do {
- getmouseco_areawin(mval);
-
- areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
-
- cfra= (int)dx;
- if(cfra< 1) cfra= 1;
-
- if( cfra!=CFRA ) {
- CFRA= cfra;
- update_for_newframe();
- force_draw_all(0);
- }
- else PIL_sleep_ms(30);
-
- } while(get_mbut() & mousebut);
- break;
- }
- /* passed on as selection */
- case RIGHTMOUSE:
- /* Clicking in the channel area */
- if (mval[0]<NAMEWIDTH) {
- if (act) {
- /* mouse is over action channels */
- if (G.qual & LR_CTRLKEY)
- clever_achannel_names(mval);
- else
- mouse_actionchannels(mval);
- }
- else numbuts_action();
+ case ACCENTGRAVEKEY:
+ if (datatype == ACTCONT_ACTION) {
+ if (G.qual == LR_SHIFTKEY)
+ expand_obscuregroups_action();
+ else
+ expand_all_action();
}
- else if (mval[0]>ACTWIDTH) {
- /* Clicking in the vertical scrollbar selects
- * all of the keys for that channel at that height
- */
- if (IN_2D_VERT_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_channels(act, mval, NULL, SELECT_INVERT);
- else
- select_all_keys_channels(act, mval, NULL, SELECT_REPLACE);
- }
+ break;
- /* Clicking in the horizontal scrollbar selects
- * all of the keys within 0.5 of the nearest integer
- * frame
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_frames(act, mval, NULL, SELECT_INVERT);
- else
- select_all_keys_frames(act, mval, NULL, SELECT_REPLACE);
- BIF_undo_push("Select all Action");
- }
+ case PADPLUSKEY:
+ if (G.qual == LR_CTRLKEY) {
+ if (datatype == ACTCONT_ACTION)
+ openclose_level_action(1);
+ }
+ else {
+ view2d_zoom(G.v2d, 0.1154, sa->winx, sa->winy);
+ test_view2d(G.v2d, sa->winx, sa->winy);
+ view2d_do_locks(curarea, V2D_LOCK_COPY);
- /* Clicking in the main area of the action window
- * selects keys and markers
- */
- else {
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- mouse_action(SELECT_INVERT);
- else
- mouse_action(SELECT_REPLACE);
- }
- else if (key) {
- if(G.qual & LR_SHIFTKEY)
- mouse_mesh_action(SELECT_INVERT, key);
- else
- mouse_mesh_action(SELECT_REPLACE, key);
- }
- }
+ doredraw= 1;
}
break;
- case PADPLUSKEY:
- view2d_zoom(G.v2d, 0.1154, sa->winx, sa->winy);
- test_view2d(G.v2d, sa->winx, sa->winy);
- view2d_do_locks(curarea, V2D_LOCK_COPY);
-
- doredraw= 1;
- break;
case PADMINUS:
- view2d_zoom(G.v2d, -0.15, sa->winx, sa->winy);
- test_view2d(G.v2d, sa->winx, sa->winy);
- view2d_do_locks(curarea, V2D_LOCK_COPY);
-
- doredraw= 1;
- break;
- case MIDDLEMOUSE:
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- view2dmove(event); /* in drawipo.c */
- break;
- }
- }
-
- if(doredraw) addqueue(curarea->win, REDRAW, 1);
-
-}
-
-Key *get_action_mesh_key(void)
-{
- /* gets the key data from the currently selected
- * mesh/lattice. If a mesh is not selected, or does not have
- * key data, then we return NULL (currently only
- * returns key data for RVK type meshes). If there
- * is an action that is pinned, return null
- */
- Object *ob;
- Key *key;
-
- ob = OBACT;
- if (!ob) return NULL;
-
- if (G.saction->pin) return NULL;
-
- if (ob->type==OB_MESH ) {
- key = ((Mesh *)ob->data)->key;
- }
- else if (ob->type==OB_LATTICE ) {
- key = ((Lattice *)ob->data)->key;
- }
- else return NULL;
-
- if (key) {
- if (key->type == KEY_RELATIVE)
- return key;
- }
-
- return NULL;
-}
-
-int get_nearest_key_num(Key *key, short *mval, float *x)
-{
- /* returns the key num that cooresponds to the
- * y value of the mouse click. Does not check
- * if this is a valid keynum. Also gives the Ipo
- * x coordinate.
- */
- int num;
- float ybase, y;
-
- areamouseco_to_ipoco(G.v2d, mval, x, &y);
-
- ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
- num = (int) ((ybase - y + CHANNELHEIGHT/2) / (CHANNELHEIGHT+CHANNELSKIP));
-
- return (num + 1);
-}
-
-void *get_nearest_act_channel(short mval[], short *ret_type)
-{
- /* Returns the 'channel' that is under the mouse cursor.
- * This 'channel' can either be an action channel, or a constraint channel.
- *
- * #ret_type# is used to denote what type of channel was found.
- * It should only be one of the ACTTYPE_* constant values.
- */
-
- bAction *act= G.saction->action;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
-
- float x,y;
- int clickmin, clickmax;
-
- if (act == NULL) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
- clickmax = clickmin;
-
- if (clickmax < 0) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - action channel */
- *ret_type= ACTTYPE_ACHAN;
- return achan;
- }
- --clickmin;
- --clickmax;
- }
- else
- continue;
-
- if (EXPANDED_ACHAN(achan) == 0)
- continue;
-
- /* try in ipo curves */
- if (achan->ipo) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - ipo-curves show/hide */
- *ret_type= ACTTYPE_FILLIPO;
- return achan; /* pointer to action-channel is returned in this case */
- }
- --clickmin;
- --clickmax;
-
- /* now the ipo-curve channels if they are exposed */
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - ipo-curve channel */
- *ret_type= ACTTYPE_ICU;
- return icu;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
-
- /* try in constaint channels */
- if (achan->constraintChannels.first) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraints show/hide */
- *ret_type= ACTTYPE_FILLCON;
- return achan; /* pointer to action-channel is returned in this case */
- }
- --clickmin;
- --clickmax;
-
- /* now the constraint channels if they are exposed */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraint channel */
- *ret_type= ACTTYPE_CONCHAN;
- return conchan;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
- }
-
- *ret_type= ACTTYPE_NONE;
- return NULL;
-}
-
-/* ************************************* Action Editor Markers ************************************* */
-
-void markers_selectkeys_between(void)
-{
- bAction *act;
- Key *key;
- float min, max;
-
- /* get extreme markers */
- get_minmax_markers(1, &min, &max);
- if (min==max) return;
- min -= 0.5f;
- max += 0.5f;
-
- /* get keyframe data */
- act = G.saction->action;
- key = get_action_mesh_key();
-
- /* select keys in-between */
- if (act) {
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if (achan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- borderselect_ipo_key(achan->ipo, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
- }
- else {
- borderselect_ipo_key(achan->ipo, min, max, SELECT_ADD);
- }
- }
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- borderselect_ipo_key(conchan->ipo, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- borderselect_ipo_key(conchan->ipo, min, max, SELECT_ADD);
- }
- }
- }
- }
- }
- else if (key) {
- if (key->ipo)
- borderselect_ipo_key(key->ipo, min, max, SELECT_ADD);
- }
-}
-
-/* ************************************* Action Channel Ordering *********************************** */
-
-void top_sel_action()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.first; achan; achan= achan->next){
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* make it first element */
- BLI_insertlinkbefore(&act->chanbase, act->chanbase.first, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Top Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void up_sel_action()
-{
- bAction *act;
- bActionChannel *achan, *prev;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- prev = achan->prev;
- if (prev) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* push it up */
- BLI_insertlinkbefore(&act->chanbase, prev, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Up Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void down_sel_action()
-{
- bAction *act;
- bActionChannel *achan, *next;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- next = achan->next;
- if (next) next = next->next;
- if (next) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* move it down */
- BLI_insertlinkbefore(&act->chanbase, next, achan);
- achan->flag |= ACHAN_MOVED;
- }
- else {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
- }
+ if (G.qual == LR_CTRLKEY) {
+ if (datatype == ACTCONT_ACTION)
+ openclose_level_action(-1);
}
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Down Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void bottom_sel_action()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
+ else {
+ view2d_zoom(G.v2d, -0.15, sa->winx, sa->winy);
+ test_view2d(G.v2d, sa->winx, sa->winy);
+ view2d_do_locks(curarea, V2D_LOCK_COPY);
+
+ doredraw= 1;
}
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Bottom Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* ********************************* BAKING STUFF ********************************** */
-/* NOTE: these functions should probably be moved to their own file sometime - Aligorith */
-
-void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4])
-{
- float imatarm[4][4], imatbone[4][4], tmat[4][4], t2mat[4][4];
-
- Mat4Invert(imatarm, armPos);
- Mat4Invert(imatbone, restPos);
- Mat4MulMat4(tmat, imatarm, worldSpace);
- Mat4MulMat4(t2mat, tmat, imatbone);
- Mat4MulMat4(boneSpaceMat, restPos, t2mat);
-}
-
-bAction *bake_action_with_client (bAction *act, Object *armob, float tolerance)
-{
- bArmature *arm;
- bAction *result=NULL;
- bActionChannel *achan;
- bAction *temp;
- bPoseChannel *pchan;
- ID *id;
- float actstart, actend;
- int oldframe;
- int curframe;
- char newname[64];
-
- if (!act)
- return NULL;
-
- arm = get_armature(armob);
-
- if (G.obedit){
- error ("Actions can't be baked in Edit Mode");
- return NULL;
- }
-
- if (!arm || armob->pose==NULL){
- error ("Select an armature before baking");
- return NULL;
- }
-
- /* Get a new action */
- result = add_empty_action("Action");
- id= (ID *)armob;
-
- /* Assign the new action a unique name */
- sprintf (newname, "%s.BAKED", act->id.name+2);
- rename_id(&result->id, newname);
-
- calc_action_range(act, &actstart, &actend, 1);
-
- oldframe = G.scene->r.cfra;
-
- temp = armob->action;
- armob->action = result;
-
- for (curframe=1; curframe<ceil(actend+1.0f); curframe++){
-
- /* Apply the old action */
+ break;
- G.scene->r.cfra = curframe;
-
- /* Apply the object ipo */
- extract_pose_from_action(armob->pose, act, curframe);
-
- where_is_pose(armob);
-
- /* For each channel: set quats and locs if channel is a bone */
- for (pchan=armob->pose->chanbase.first; pchan; pchan=pchan->next){
-
- /* Apply to keys */
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
- }
- }
-
-
- /* Make another pass to ensure all keyframes are set to linear interpolation mode */
- for (achan = result->chanbase.first; achan; achan=achan->next){
- IpoCurve* icu;
- if(achan->ipo) {
- for (icu = achan->ipo->curve.first; icu; icu=icu->next){
- icu->ipo= IPO_LIN;
- }
+ case HOMEKEY:
+ do_action_buttons(B_ACTHOME); /* header */
+ break;
}
}
- notice ("Made a new action named \"%s\"", newname);
- G.scene->r.cfra = oldframe;
- armob->action = temp;
-
- /* restore */
- extract_pose_from_action(armob->pose, act, G.scene->r.cfra);
- where_is_pose(armob);
-
- allqueue(REDRAWACTION, 1);
-
- return result;
+ if (doredraw) addqueue(curarea->win, REDRAW, 1);
}
-
-bAction* bake_obIPO_to_action (Object *ob)
-{
- bArmature *arm;
- bAction *result=NULL;
- bAction *temp;
- Bone *bone;
- ID *id;
- ListBase elems;
- int oldframe,testframe;
- char newname[64];
- float quat[4],tmat[4][4],startpos[4][4];
- CfraElem *firstcfra, *lastcfra;
-
- arm = get_armature(ob);
-
- if (arm) {
-
- oldframe = CFRA;
- result = add_empty_action("Action");
- id = (ID *)ob;
-
- sprintf (newname, "TESTOBBAKE");
- rename_id(&result->id, newname);
-
- if(ob!=G.obedit) { // make sure object is not in edit mode
- if(ob->ipo) {
- /* convert the ipo to a list of 'current frame elements' */
-
- temp = ob->action;
- ob->action = result;
-
- elems.first= elems.last= NULL;
- make_cfra_list(ob->ipo, &elems);
- /* set the beginning armature location */
- firstcfra=elems.first;
- lastcfra=elems.last;
- CFRA=firstcfra->cfra;
-
- where_is_object(ob);
- Mat4CpyMat4(startpos,ob->obmat);
-
- /* loop from first key to last, sampling every 10 */
- for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) {
- CFRA=testframe;
- where_is_object(ob);
-
- for (bone = arm->bonebase.first; bone; bone=bone->next) {
- if (!bone->parent) { /* this is a root bone, so give it a key! */
- world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
- Mat4ToQuat(tmat,quat);
- printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
- }
- }
- }
- BLI_freelistN(&elems);
- }
- }
- CFRA = oldframe;
- }
- return result;
-}
-
-bAction *bake_everything_to_action (Object *ob)
-{
- bArmature *arm;
- bAction *result=NULL;
- bAction *temp;
- Bone *bone;
- ID *id;
- ListBase elems;
- int oldframe,testframe;
- char newname[64];
- float quat[4],tmat[4][4],startpos[4][4];
- CfraElem *firstcfra, *lastcfra;
-
- arm = get_armature(ob);
-
- if (arm) {
- oldframe = CFRA;
- result = add_empty_action("Action");
- id = (ID *)ob;
-
- sprintf (newname, "TESTOBBAKE");
- rename_id(&result->id, newname);
-
- if(ob!=G.obedit) { // make sure object is not in edit mode
- if(ob->ipo) {
- /* convert the ipo to a list of 'current frame elements' */
-
- temp = ob->action;
- ob->action = result;
-
- elems.first= elems.last= NULL;
- make_cfra_list(ob->ipo, &elems);
- /* set the beginning armature location */
- firstcfra=elems.first;
- lastcfra=elems.last;
- CFRA=firstcfra->cfra;
-
- where_is_object(ob);
- Mat4CpyMat4(startpos,ob->obmat);
-
- /* loop from first key to last, sampling every 10 */
- for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) {
- CFRA=testframe;
-
- do_all_pose_actions(ob);
- where_is_object(ob);
- for (bone = arm->bonebase.first; bone; bone=bone->next) {
- if (!bone->parent) { /* this is a root bone, so give it a key! */
- world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
-
- Mat4ToQuat(tmat,quat);
- printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
- }
- }
- }
- BLI_freelistN(&elems);
- }
- }
- CFRA = oldframe;
- }
- return result;
-}
+/* **************************************************** */
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index c7b818482bd..55ed6252dae 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -55,18 +55,21 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_modifier_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
+#include "BLI_ghash.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -82,6 +85,8 @@
#include "BIF_gl.h"
#include "BIF_graphics.h"
#include "BIF_interface.h"
+#include "BIF_meshlaplacian.h"
+#include "BIF_meshtools.h"
#include "BIF_poseobject.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
@@ -99,6 +104,8 @@
#include "PIL_time.h"
+#include "reeb.h" // FIX ME
+
#include "mydevice.h"
#include "blendef.h"
#include "nla.h"
@@ -114,7 +121,7 @@ static EditBone *editbone_name_exists (ListBase *ebones, char *name); // proto f
/* **************** tools on Editmode Armature **************** */
/* converts Bones to EditBone list, used for tools as well */
-void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
+void make_boneList(ListBase *list, ListBase *bones, EditBone *parent)
{
EditBone *eBone;
Bone *curBone;
@@ -124,7 +131,7 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
float imat[3][3];
float difmat[3][3];
- for (curBone=bones->first; curBone; curBone=curBone->next){
+ for (curBone=bones->first; curBone; curBone=curBone->next) {
eBone= MEM_callocN(sizeof(EditBone), "make_editbone");
/* Copy relevant data from bone to eBone */
@@ -133,7 +140,7 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
eBone->flag = curBone->flag;
/* fix selection flags */
- if(eBone->flag & BONE_SELECTED) {
+ if (eBone->flag & BONE_SELECTED) {
eBone->flag |= BONE_TIPSEL;
if(eBone->parent && (eBone->flag & BONE_CONNECTED))
eBone->parent->flag |= BONE_TIPSEL;
@@ -153,7 +160,7 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
vec_roll_to_mat3(delta, 0.0, postmat);
Mat3CpyMat4(premat, curBone->arm_mat);
-
+
Mat3Inv(imat, postmat);
Mat3MulMat3(difmat, imat, premat);
@@ -172,7 +179,7 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
eBone->segments = curBone->segments;
eBone->layer = curBone->layer;
- BLI_addtail (list, eBone);
+ BLI_addtail(list, eBone);
/* Add children if necessary */
if (curBone->childbase.first)
@@ -203,7 +210,7 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
if (ebone) {
/* Get the ebone premat */
- VecSubf (delta, ebone->tail, ebone->head);
+ VecSubf(delta, ebone->tail, ebone->head);
vec_roll_to_mat3(delta, ebone->roll, premat);
/* Get the bone postmat */
@@ -213,9 +220,9 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
Mat3MulMat3(difmat, imat, postmat);
#if 0
printf ("Bone %s\n", curBone->name);
- printmatrix4 ("premat", premat);
- printmatrix4 ("postmat", postmat);
- printmatrix4 ("difmat", difmat);
+ printmatrix4("premat", premat);
+ printmatrix4("postmat", postmat);
+ printmatrix4("difmat", difmat);
printf ("Roll = %f\n", (-atan2(difmat[2][0], difmat[2][2]) * (180.0/M_PI)));
#endif
curBone->roll = -atan2(difmat[2][0], difmat[2][2]);
@@ -223,7 +230,7 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
/* and set restposition again */
where_is_armature_bone(curBone, curBone->parent);
}
- fix_bonelist_roll (&curBone->childbase, editbonelist);
+ fix_bonelist_roll(&curBone->childbase, editbonelist);
}
}
@@ -246,29 +253,30 @@ void editbones_to_armature (ListBase *list, Object *ob)
for (eBone=list->first; eBone; eBone= neBone) {
float len= VecLenf(eBone->head, eBone->tail);
neBone= eBone->next;
- if(len <= FLT_EPSILON) {
+ if (len <= FLT_EPSILON) {
EditBone *fBone;
/* Find any bones that refer to this bone */
- for (fBone=list->first; fBone; fBone= fBone->next){
+ for (fBone=list->first; fBone; fBone= fBone->next) {
if (fBone->parent==eBone)
fBone->parent= eBone->parent;
}
- printf("Warning; removed zero sized bone: %s\n", eBone->name);
+ printf("Warning: removed zero sized bone: %s\n", eBone->name);
BLI_freelinkN (list, eBone);
}
}
/* Copy the bones from the editData into the armature */
- for (eBone=list->first; eBone; eBone=eBone->next){
+ for (eBone=list->first; eBone; eBone=eBone->next) {
newBone= MEM_callocN (sizeof(Bone), "bone");
eBone->temp= newBone; /* Associate the real Bones with the EditBones */
BLI_strncpy (newBone->name, eBone->name, 32);
- memcpy (newBone->head, eBone->head, sizeof(float)*3);
- memcpy (newBone->tail, eBone->tail, sizeof(float)*3);
+ memcpy(newBone->head, eBone->head, sizeof(float)*3);
+ memcpy(newBone->tail, eBone->tail, sizeof(float)*3);
newBone->flag= eBone->flag;
- if(eBone->flag & BONE_ACTIVE) newBone->flag |= BONE_SELECTED; /* important, editbones can be active with only 1 point selected */
+ if (eBone->flag & BONE_ACTIVE)
+ newBone->flag |= BONE_SELECTED; /* important, editbones can be active with only 1 point selected */
newBone->roll = 0.0f;
newBone->weight = eBone->weight;
@@ -282,16 +290,15 @@ void editbones_to_armature (ListBase *list, Object *ob)
newBone->rad_tail= eBone->rad_tail;
newBone->segments= eBone->segments;
newBone->layer = eBone->layer;
-
}
/* Fix parenting in a separate pass to ensure ebone->bone connections
are valid at this point */
for (eBone=list->first;eBone;eBone=eBone->next) {
- newBone= (Bone*) eBone->temp;
- if (eBone->parent){
- newBone->parent=(Bone*) eBone->parent->temp;
- BLI_addtail (&newBone->parent->childbase,newBone);
+ newBone= (Bone *)eBone->temp;
+ if (eBone->parent) {
+ newBone->parent=(Bone *)eBone->parent->temp;
+ BLI_addtail(&newBone->parent->childbase,newBone);
{
float M_boneRest[3][3];
@@ -311,24 +318,24 @@ void editbones_to_armature (ListBase *list, Object *ob)
Mat3Inv(iM_parentRest, M_parentRest);
/* Get the new head and tail */
- VecSubf (newBone->head, eBone->head, eBone->parent->tail);
- VecSubf (newBone->tail, eBone->tail, eBone->parent->tail);
-
+ VecSubf(newBone->head, eBone->head, eBone->parent->tail);
+ VecSubf(newBone->tail, eBone->tail, eBone->parent->tail);
+
Mat3MulVecfl(iM_parentRest, newBone->head);
Mat3MulVecfl(iM_parentRest, newBone->tail);
}
}
/* ...otherwise add this bone to the armature's bonebase */
else
- BLI_addtail (&arm->bonebase,newBone);
+ BLI_addtail(&arm->bonebase,newBone);
}
/* Make a pass through the new armature to fix rolling */
/* also builds restposition again (like where_is_armature) */
- fix_bonelist_roll (&arm->bonebase, list);
+ fix_bonelist_roll(&arm->bonebase, list);
/* so all users of this armature should get rebuilt */
- for(obt= G.main->object.first; obt; obt= obt->id.next) {
+ for (obt= G.main->object.first; obt; obt= obt->id.next) {
if(obt->data==arm)
armature_rebuild_pose(obt, arm);
}
@@ -343,12 +350,12 @@ void apply_rot_armature (Object *ob, float mat[3][3])
ListBase list;
EditBone *ebone;
bArmature *arm;
-
+ float scale = Mat3ToScalef(mat); /* store the scale of the matrix here to use on envelopes */
arm = get_armature(ob);
if (!arm)
- return;
-
+ return;
+
/* Put the armature into editmode */
list.first= list.last = NULL;
make_boneList(&list, &arm->bonebase, NULL);
@@ -357,6 +364,10 @@ void apply_rot_armature (Object *ob, float mat[3][3])
for (ebone = list.first; ebone; ebone=ebone->next){
Mat3MulVecfl(mat, ebone->head);
Mat3MulVecfl(mat, ebone->tail);
+
+ ebone->rad_head *= scale;
+ ebone->rad_tail *= scale;
+ ebone->dist *= scale;
}
/* Turn the list into an armature */
@@ -444,16 +455,28 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
pose= ob->pose;
for (pchant= pose->chanbase.first; pchant; pchant= pchant->next) {
for (con= pchant->constraints.first; con; con= con->next) {
- Object *conOb;
- char *subtarget;
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
/* constraint targets */
- conOb= get_constraint_target(con, &subtarget);
- if (conOb == srcArm) {
- if (strcmp(subtarget, "")==0)
- set_constraint_target(con, tarArm, "");
- else if (strcmp(pchan->name, subtarget)==0)
- set_constraint_target(con, tarArm, curbone->name);
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == srcArm) {
+ if (strcmp(ct->subtarget, "")==0) {
+ ct->tar = tarArm;
+ }
+ else if (strcmp(ct->subtarget, pchan->name)==0) {
+ ct->tar = tarArm;
+ strcpy(ct->subtarget, curbone->name);
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
/* action constraint? */
@@ -479,15 +502,28 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann
/* fix object-level constraints */
if (ob != srcArm) {
for (con= ob->constraints.first; con; con= con->next) {
- Object *conOb;
- char *subtarget;
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
- conOb= get_constraint_target(con, &subtarget);
- if (conOb == srcArm) {
- if (strcmp(subtarget, "")==0)
- set_constraint_target(con, tarArm, "");
- else if (strcmp(pchan->name, subtarget)==0)
- set_constraint_target(con, tarArm, curbone->name);
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == srcArm) {
+ if (strcmp(ct->subtarget, "")==0) {
+ ct->tar = tarArm;
+ }
+ else if (strcmp(ct->subtarget, pchan->name)==0) {
+ ct->tar = tarArm;
+ strcpy(ct->subtarget, curbone->name);
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
}
}
@@ -800,6 +836,98 @@ void select_bone_parent (void)
BIF_undo_push("Select Parent");
}
+/* helper for setflag_sel_bone() */
+static void bone_setflag (int *bone, int flag, short mode)
+{
+ if (bone && flag) {
+ /* exception for inverse flags */
+ if (flag == BONE_NO_DEFORM) {
+ if (mode == 2)
+ *bone |= flag;
+ else if (mode == 1)
+ *bone &= ~flag;
+ else
+ *bone ^= flag;
+
+ }
+ else {
+ if (mode == 2)
+ *bone &= ~flag;
+ else if (mode == 1)
+ *bone |= flag;
+ else
+ *bone ^= flag;
+ }
+ }
+}
+
+/* used by posemode and editmode */
+void setflag_armature (short mode)
+{
+ Object *ob;
+ bArmature *arm;
+ int flag;
+
+ /* get data */
+ if (G.obedit)
+ ob= G.obedit;
+ else if (OBACT)
+ ob= OBACT;
+ else
+ return;
+ arm= (bArmature *)ob->data;
+
+ /* get flag to set (sync these with the ones used in eBone_Flag */
+ if (mode == 2)
+ flag= pupmenu("Disable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+ else if (mode == 1)
+ flag= pupmenu("Enable Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+ else
+ flag= pupmenu("Toggle Setting%t|Draw Wire%x1|Deform%x2|Mult VG%x3|Hinge%x4|No Scale%x5");
+ switch (flag) {
+ case 1: flag = BONE_DRAWWIRE; break;
+ case 2: flag = BONE_NO_DEFORM; break;
+ case 3: flag = BONE_MULT_VG_ENV; break;
+ case 4: flag = BONE_HINGE; break;
+ case 5: flag = BONE_NO_SCALE; break;
+ default: return;
+ }
+
+ /* determine which mode armature is in */
+ if ((!G.obedit) && (ob->flag & OB_POSEMODE)) {
+ /* deal with pose channels */
+ bPoseChannel *pchan;
+
+ /* set setting */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (pchan->bone->flag & BONE_SELECTED) {
+ bone_setflag(&pchan->bone->flag, flag, mode);
+ }
+ }
+ }
+ }
+ else if (G.obedit) {
+ /* deal with editbones */
+ EditBone *curbone;
+
+ /* set setting */
+ for (curbone= G.edbo.first; curbone; curbone= curbone->next) {
+ if (arm->layer & curbone->layer) {
+ if (curbone->flag & BONE_SELECTED) {
+ bone_setflag(&curbone->flag, flag, mode);
+ }
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
+
+ BIF_undo_push("Change Bone Setting");
+}
/* **************** END PoseMode & EditMode *************************** */
/* **************** Posemode stuff ********************** */
@@ -1042,28 +1170,55 @@ void delete_armature(void)
bConstraint *con;
TEST_EDITARMATURE;
- if(okee("Erase selected bone(s)")==0) return;
+ if (okee("Erase selected bone(s)")==0) return;
+
+ /* Select mirrored bones */
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ for (curBone=G.edbo.first; curBone; curBone=curBone->next) {
+ if (arm->layer & curBone->layer) {
+ if (curBone->flag & BONE_SELECTED) {
+ next = armature_bone_get_mirrored(curBone);
+ if (next)
+ next->flag |= BONE_SELECTED;
+ }
+ }
+ }
+ }
/* First erase any associated pose channel */
- if (G.obedit->pose){
+ if (G.obedit->pose) {
bPoseChannel *chan, *next;
for (chan=G.obedit->pose->chanbase.first; chan; chan=next) {
next= chan->next;
- curBone = editbone_name_exists (&G.edbo, chan->name);
+ curBone = editbone_name_exists(&G.edbo, chan->name);
if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
free_constraints(&chan->constraints);
BLI_freelinkN (&G.obedit->pose->chanbase, chan);
}
else {
- for(con= chan->constraints.first; con; con= con->next) {
- char *subtarget = get_con_subtarget_name(con, G.obedit);
- if (subtarget) {
- curBone = editbone_name_exists (&G.edbo, subtarget);
- if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
- con->flag |= CONSTRAINT_DISABLE;
- subtarget[0]= 0;
+ for (con= chan->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == G.obedit) {
+ if (ct->subtarget[0]) {
+ curBone = editbone_name_exists(&G.edbo, ct->subtarget);
+ if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
+ con->flag |= CONSTRAINT_DISABLE;
+ ct->subtarget[0]= 0;
+ }
+ }
+ }
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
}
}
@@ -1071,9 +1226,9 @@ void delete_armature(void)
}
- for (curBone=G.edbo.first;curBone;curBone=next){
+ for (curBone=G.edbo.first;curBone;curBone=next) {
next=curBone->next;
- if(arm->layer & curBone->layer)
+ if (arm->layer & curBone->layer)
if (curBone->flag & BONE_SELECTED)
delete_bone(curBone);
}
@@ -1166,11 +1321,9 @@ void mouse_armature(void)
void free_editArmature(void)
{
-
/* Clear the editbones list */
- if (G.edbo.first){
- BLI_freelistN (&G.edbo);
- }
+ if (G.edbo.first)
+ BLI_freelistN(&G.edbo);
}
void remake_editArmature(void)
@@ -1185,29 +1338,27 @@ void remake_editArmature(void)
allqueue(REDRAWBUTSOBJECT, 0);
// BIF_undo_push("Delete bone");
-
}
/* Put object in EditMode */
void make_editArmature(void)
{
- bArmature *arm;
+ bArmature *arm;
if (G.obedit==0) return;
free_editArmature();
arm= get_armature(G.obedit);
- if (!arm)
- return;
+ if (!arm) return;
- make_boneList (&G.edbo, &arm->bonebase,NULL);
+ make_boneList(&G.edbo, &arm->bonebase,NULL);
}
/* put EditMode back in Object */
void load_editArmature(void)
{
- bArmature *arm;
+ bArmature *arm;
arm= get_armature(G.obedit);
if (!arm) return;
@@ -1266,37 +1417,86 @@ void deselectall_armature(int toggle, int doundo)
}
}
-void auto_align_armature(void)
-/* Sets the roll value of selected bones so that their zaxes point upwards */
+/* Sets the roll value of selected bones, depending on the mode
+ * mode == 0: their z-axes point upwards
+ * mode == 1: their z-axes point towards 3d-cursor
+ */
+void auto_align_armature(short mode)
{
bArmature *arm= G.obedit->data;
EditBone *ebone;
- float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
- float targetmat[3][3], imat[3][3];
- float curmat[3][3], diffmat[3][3];
+ EditBone *flipbone = NULL;
float delta[3];
-
- for (ebone = G.edbo.first; ebone; ebone=ebone->next){
- if(arm->layer & ebone->layer) {
- if (ebone->flag & BONE_SELECTED){
- /* Find the current bone matrix */
- VecSubf(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, 0.0, curmat);
-
- /* Make new matrix based on y axis & z-up */
- VECCOPY (yaxis, curmat[1]);
-
- Mat3One(targetmat);
- VECCOPY (targetmat[0], xaxis);
- VECCOPY (targetmat[1], yaxis);
- VECCOPY (targetmat[2], zaxis);
- Mat3Ortho(targetmat);
-
- /* Find the difference between the two matrices */
- Mat3Inv(imat, targetmat);
- Mat3MulMat3(diffmat, imat, curmat);
-
- ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
+ float curmat[3][3];
+ float *cursor= give_cursor();
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
+ if (arm->layer & ebone->layer) {
+ if (arm->flag & ARM_MIRROR_EDIT)
+ flipbone = armature_bone_get_mirrored(ebone);
+
+ if ((ebone->flag & BONE_SELECTED) ||
+ (flipbone && flipbone->flag & BONE_SELECTED))
+ {
+ /* specific method used to calculate roll depends on mode */
+ if (mode == 1) {
+ /* Z-Axis point towards cursor */
+ float mat[4][4], tmat[4][4], imat[4][4];
+ float rmat[4][4], rot[3];
+ float vec[3];
+
+ /* find the current bone matrix as a 4x4 matrix (in Armature Space) */
+ VecSubf(delta, ebone->tail, ebone->head);
+ vec_roll_to_mat3(delta, ebone->roll, curmat);
+ Mat4CpyMat3(mat, curmat);
+ VECCOPY(mat[3], ebone->head);
+
+ /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
+ Mat4MulMat4(tmat, mat, G.obedit->obmat);
+ Mat4Invert(imat, tmat);
+
+ /* find position of cursor relative to bone */
+ VecMat4MulVecfl(vec, imat, cursor);
+
+ /* check that cursor is in usable position */
+ if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
+ /* Compute a rotation matrix around y */
+ rot[1] = atan2(vec[0], vec[2]);
+ rot[0] = rot[2] = 0.0f;
+ EulToMat4(rot, rmat);
+
+ /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
+ Mat4MulMat4(tmat, rmat, mat);
+ Mat3CpyMat4(curmat, tmat);
+
+ /* Now convert from new bone-matrix, back to a roll value (in radians) */
+ mat3_to_vec_roll(curmat, delta, &ebone->roll);
+ }
+ }
+ else {
+ /* Z-Axis Point Up */
+ float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
+ float targetmat[3][3], imat[3][3], diffmat[3][3];
+
+ /* Find the current bone matrix */
+ VecSubf(delta, ebone->tail, ebone->head);
+ vec_roll_to_mat3(delta, 0.0, curmat);
+
+ /* Make new matrix based on y axis & z-up */
+ VECCOPY (yaxis, curmat[1]);
+
+ Mat3One(targetmat);
+ VECCOPY (targetmat[0], xaxis);
+ VECCOPY (targetmat[1], yaxis);
+ VECCOPY (targetmat[2], zaxis);
+ Mat3Ortho(targetmat);
+
+ /* Find the difference between the two matrices */
+ Mat3Inv(imat, targetmat);
+ Mat3MulMat3(diffmat, imat, curmat);
+
+ ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
+ }
}
}
}
@@ -1335,7 +1535,7 @@ static void *editBones_to_undoBones(void)
lb= MEM_callocN(sizeof(ListBase), "listbase undo");
- /* copy */
+ /* copy */
for(ebo= G.edbo.first; ebo; ebo= ebo->next) {
newebo= MEM_dupallocN(ebo);
ebo->temp= newebo;
@@ -1361,7 +1561,7 @@ static void free_undoBones(void *lbv)
/* and this is all the undo system needs to know */
void undo_push_armature(char *name)
{
- undo_editmode_push(name, free_undoBones, undoBones_to_editBones, editBones_to_undoBones);
+ undo_editmode_push(name, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
}
@@ -1376,7 +1576,7 @@ static EditBone *add_editbone(char *name)
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
- BLI_strncpy (bone->name, name, 32);
+ BLI_strncpy(bone->name, name, 32);
unique_editbone_name(&G.edbo, bone->name);
BLI_addtail(&G.edbo, bone);
@@ -1396,7 +1596,7 @@ static EditBone *add_editbone(char *name)
return bone;
}
-static void add_primitive_bone(Object *ob)
+static void add_primitive_bone(Object *ob, short newob)
{
float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
EditBone *bone;
@@ -1407,7 +1607,9 @@ static void add_primitive_bone(Object *ob)
Mat4Invert(G.obedit->imat, G.obedit->obmat);
Mat4MulVecfl(G.obedit->imat, curs);
- Mat3CpyMat4(obmat, G.vd->viewmat);
+ if ( !(newob) || U.flag & USER_ADD_VIEWALIGNED) Mat3CpyMat4(obmat, G.vd->viewmat);
+ else Mat3One(obmat);
+
Mat3CpyMat4(viewmat, G.obedit->obmat);
Mat3MulMat3(totmat, obmat, viewmat);
Mat3Inv(imat, totmat);
@@ -1418,19 +1620,25 @@ static void add_primitive_bone(Object *ob)
bone= add_editbone("Bone");
VECCOPY(bone->head, curs);
- VecAddf(bone->tail, bone->head, imat[1]); // bone with unit length 1
+
+ if ( !(newob) || U.flag & USER_ADD_VIEWALIGNED)
+ VecAddf(bone->tail, bone->head, imat[1]); // bone with unit length 1
+ else
+ VecAddf(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z
}
void add_primitiveArmature(int type)
{
+ short newob=0;
+
if(G.scene->id.lib) return;
/* this function also comes from an info window */
if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
if(G.vd==NULL) return;
- G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT);
+ G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT);
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
check_editmode(OB_ARMATURE);
@@ -1445,13 +1653,18 @@ void add_primitiveArmature(int type)
make_editArmature();
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
+ newob=1;
}
/* no primitive support yet */
- add_primitive_bone(G.obedit);
+ add_primitive_bone(G.obedit, newob);
countall(); // flushes selection!
+ if ( (newob) && !(U.flag & USER_ADD_EDITMODE)) {
+ exit_editmode(2);
+ }
+
allqueue(REDRAWALL, 0);
BIF_undo_push("Add primitive");
}
@@ -1538,6 +1751,19 @@ void addvert_armature(void)
while(get_mbut()&R_MOUSE);
}
+/* adds an EditBone between the nominated locations (should be in the right space) */
+static EditBone *add_points_bone (float head[], float tail[])
+{
+ EditBone *ebo;
+
+ ebo= add_editbone("Bone");
+
+ VECCOPY(ebo->head, head);
+ VECCOPY(ebo->tail, tail);
+
+ return ebo;
+}
+
static EditBone *get_named_editbone(char *name)
{
@@ -1562,28 +1788,43 @@ static void update_dup_subtarget(EditBone *dupBone)
bPoseChannel *chan;
bConstraint *curcon;
ListBase *conlist;
- char *subname;
- if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) )
- if ( (conlist = &chan->constraints) )
+ if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) ) {
+ if ( (conlist = &chan->constraints) ) {
for (curcon = conlist->first; curcon; curcon=curcon->next) {
/* does this constraint have a subtarget in
* this armature?
*/
- subname = get_con_subtarget_name(curcon, G.obedit);
- oldtarget = get_named_editbone(subname);
- if (oldtarget)
- /* was the subtarget bone duplicated too? If
- * so, update the constraint to point at the
- * duplicate of the old subtarget.
- */
- if (oldtarget->flag & BONE_SELECTED){
- newtarget = (EditBone*) oldtarget->temp;
- strcpy(subname, newtarget->name);
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(curcon, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if ((ct->tar == G.obedit) && (ct->subtarget[0])) {
+ oldtarget = get_named_editbone(ct->subtarget);
+ if (oldtarget) {
+ /* was the subtarget bone duplicated too? If
+ * so, update the constraint to point at the
+ * duplicate of the old subtarget.
+ */
+ if (oldtarget->flag & BONE_SELECTED){
+ newtarget = (EditBone *) oldtarget->temp;
+ strcpy(ct->subtarget, newtarget->name);
+ }
+ }
+ }
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(curcon, &targets, 0);
+ }
}
-
+ }
+ }
}
@@ -1595,11 +1836,24 @@ void adduplicate_armature(void)
EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */
countall(); // flushes selection!
+
+ /* Select mirrored bones */
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ for (curBone=G.edbo.first; curBone; curBone=curBone->next) {
+ if (arm->layer & curBone->layer) {
+ if (curBone->flag & BONE_SELECTED) {
+ eBone = armature_bone_get_mirrored(curBone);
+ if (eBone)
+ eBone->flag |= BONE_SELECTED;
+ }
+ }
+ }
+ }
/* Find the selected bones and duplicate them as needed */
for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){
- if(arm->layer & curBone->layer) {
- if (curBone->flag & BONE_SELECTED){
+ if (arm->layer & curBone->layer) {
+ if (curBone->flag & BONE_SELECTED) {
eBone=MEM_callocN(sizeof(EditBone), "addup_editbone");
eBone->flag |= BONE_SELECTED;
@@ -1615,9 +1869,9 @@ void adduplicate_armature(void)
if (!firstDup)
firstDup=eBone;
- /* Lets duplicate the list of constraits that the
- * current bone has.
- */
+ /* Lets duplicate the list of constraints that the
+ * current bone has.
+ */
if (OBACT->pose) {
bPoseChannel *chanold, *channew;
ListBase *listold, *listnew;
@@ -1625,17 +1879,30 @@ void adduplicate_armature(void)
chanold = verify_pose_channel (OBACT->pose, curBone->name);
if (chanold) {
listold = &chanold->constraints;
- if (listold){
+ if (listold) {
+ /* WARNING: this creates a new posechannel, but there will not be an attached bone
+ * yet as the new bones created here are still 'EditBones' not 'Bones'.
+ */
channew =
verify_pose_channel(OBACT->pose, eBone->name);
if (channew) {
+ /* copy transform locks */
+ channew->protectflag = chanold->protectflag;
+
+ /* ik (dof) settings */
+ channew->ikflag = chanold->ikflag;
+ VECCOPY(channew->limitmin, chanold->limitmin);
+ VECCOPY(channew->limitmax, chanold->limitmax);
+ VECCOPY(channew->stiffness, chanold->stiffness);
+ channew->ikstretch= chanold->ikstretch;
+
+ /* constraints */
listnew = &channew->constraints;
copy_constraints (listnew, listold);
}
}
}
}
-
}
}
}
@@ -1692,6 +1959,383 @@ void adduplicate_armature(void)
/* *************** END Adding stuff in editmode *************** */
+/* ************** Add/Remove stuff in editmode **************** */
+
+/* temporary data-structure for merge/fill bones */
+typedef struct EditBonePoint {
+ struct EditBonePoint *next, *prev;
+
+ EditBone *head_owner; /* EditBone which uses this point as a 'head' point */
+ EditBone *tail_owner; /* EditBone which uses this point as a 'tail' point */
+
+ float vec[3]; /* the actual location of the point in local/EditMode space */
+} EditBonePoint;
+
+/* find chain-tips (i.e. bones without children) */
+static void chains_find_tips (ListBase *list)
+{
+ EditBone *curBone, *ebo;
+ LinkData *ld;
+
+ /* note: this is potentially very slow ... there's got to be a better way */
+ for (curBone= G.edbo.first; curBone; curBone= curBone->next) {
+ short stop= 0;
+
+ /* is this bone contained within any existing chain? (skip if so) */
+ for (ld= list->first; ld; ld= ld->next) {
+ for (ebo= ld->data; ebo; ebo= ebo->parent) {
+ if (ebo == curBone) {
+ stop= 1;
+ break;
+ }
+ }
+
+ if (stop) break;
+ }
+ /* skip current bone if it is part of an existing chain */
+ if (stop) continue;
+
+ /* is any existing chain part of the chain formed by this bone? */
+ stop= 0;
+ for (ebo= curBone->parent; ebo; ebo= ebo->parent) {
+ for (ld= list->first; ld; ld= ld->next) {
+ if (ld->data == ebo) {
+ ld->data= curBone;
+ stop= 1;
+ break;
+ }
+ }
+
+ if (stop) break;
+ }
+ /* current bone has already been added to a chain? */
+ if (stop) continue;
+
+ /* add current bone to a new chain */
+ ld= MEM_callocN(sizeof(LinkData), "BoneChain");
+ ld->data= curBone;
+ BLI_addtail(list, ld);
+ }
+}
+
+
+static void fill_add_joint (EditBone *ebo, short eb_tail, ListBase *points)
+{
+ EditBonePoint *ebp;
+ float vec[3];
+ short found= 0;
+
+ if (eb_tail) {
+ VECCOPY(vec, ebo->tail);
+ }
+ else {
+ VECCOPY(vec, ebo->head);
+ }
+
+ // FIXME: this algorithm sucks... it misses things it shouldn't
+ for (ebp= points->first; ebp; ebp= ebp->next) {
+ if (VecEqual(ebp->vec, vec)) {
+ if (eb_tail) {
+ if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
+ /* so this bone's tail owner is this bone*/
+ ebp->tail_owner= ebo;
+ found= 1;
+ break;
+ }
+ }
+ else {
+ if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
+ /* so this bone's head owner is this bone */
+ ebp->head_owner= ebo;
+ found = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ /* allocate a new point if no existing point was related */
+ if (found == 0) {
+ ebp= MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
+
+ if (eb_tail) {
+ VECCOPY(ebp->vec, ebo->tail);
+ ebp->tail_owner= ebo;
+ }
+ else {
+ VECCOPY(ebp->vec, ebo->head);
+ ebp->head_owner= ebo;
+ }
+
+ BLI_addtail(points, ebp);
+ }
+}
+
+/* bone adding between selected joints */
+void fill_bones_armature(void)
+{
+ bArmature *arm= G.obedit->data;
+ EditBone *ebo, *newbone=NULL;
+ ListBase points = {NULL, NULL};
+ int count;
+
+ /* loop over all bones, and only consider if visible */
+ for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
+ if ((arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A)) {
+ if (!(ebo->flag & BONE_CONNECTED) && (ebo->flag & BONE_ROOTSEL))
+ fill_add_joint(ebo, 0, &points);
+ if (ebo->flag & BONE_TIPSEL)
+ fill_add_joint(ebo, 1, &points);
+ }
+ }
+
+ /* the number of joints determines how we fill:
+ * 1) between joint and cursor (joint=head, cursor=tail)
+ * 2) between the two joints (order is dependent on active-bone/hierachy)
+ * 3+) error (a smarter method involving finding chains needs to be worked out
+ */
+ count= BLI_countlist(&points);
+
+ if (count == 0) {
+ error("No joints selected");
+ return;
+ }
+ else if (count == 1) {
+ EditBonePoint *ebp;
+ float curs[3];
+
+ /* Get Points - selected joint */
+ ebp= (EditBonePoint *)points.first;
+
+ /* Get points - cursor (tail) */
+ VECCOPY (curs, give_cursor());
+
+ Mat4Invert(G.obedit->imat, G.obedit->obmat);
+ Mat4MulVecfl(G.obedit->imat, curs);
+
+ /* Create a bone */
+ newbone= add_points_bone(ebp->vec, curs);
+ }
+ else if (count == 2) {
+ EditBonePoint *ebp, *ebp2;
+ float head[3], tail[3];
+
+ /* check that the points don't belong to the same bone */
+ ebp= (EditBonePoint *)points.first;
+ ebp2= ebp->next;
+
+ if ((ebp->head_owner==ebp2->tail_owner) && (ebp->head_owner!=NULL)) {
+ error("Same bone selected...");
+ BLI_freelistN(&points);
+ return;
+ }
+ if ((ebp->tail_owner==ebp2->head_owner) && (ebp->tail_owner!=NULL)) {
+ error("Same bone selected...");
+ BLI_freelistN(&points);
+ return;
+ }
+
+ /* find which one should be the 'head' */
+ if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) {
+ /* rule: whichever one is closer to 3d-cursor */
+ float curs[3];
+ float vecA[3], vecB[3];
+ float distA, distB;
+
+ /* get cursor location */
+ VECCOPY (curs, give_cursor());
+
+ Mat4Invert(G.obedit->imat, G.obedit->obmat);
+ Mat4MulVecfl(G.obedit->imat, curs);
+
+ /* get distances */
+ VecSubf(vecA, ebp->vec, curs);
+ VecSubf(vecB, ebp2->vec, curs);
+ distA= VecLength(vecA);
+ distB= VecLength(vecB);
+
+ /* compare distances - closer one therefore acts as direction for bone to go */
+ if (distA < distB) {
+ VECCOPY(head, ebp2->vec);
+ VECCOPY(tail, ebp->vec);
+ }
+ else {
+ VECCOPY(head, ebp->vec);
+ VECCOPY(tail, ebp2->vec);
+ }
+ }
+ else if (ebp->head_owner) {
+ VECCOPY(head, ebp->vec);
+ VECCOPY(tail, ebp2->vec);
+ }
+ else if (ebp2->head_owner) {
+ VECCOPY(head, ebp2->vec);
+ VECCOPY(tail, ebp->vec);
+ }
+
+ /* add new bone */
+ newbone= add_points_bone(head, tail);
+ }
+ else {
+ // FIXME.. figure out a method for multiple bones
+ error("Too many points selected");
+ printf("Points selected: %d \n", count);
+ BLI_freelistN(&points);
+ return;
+ }
+
+ /* free points */
+ BLI_freelistN(&points);
+
+ /* undo + updates */
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ BIF_undo_push("Fill Bones");
+}
+
+/* this function merges between two bones, removes them and those in-between,
+ * and adjusts the parent relationships for those in-between
+ */
+static void bones_merge(EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
+{
+ EditBone *ebo, *ebone, *newbone;
+ LinkData *chain;
+ float head[3], tail[3];
+
+ /* check if same bone */
+ if (start == end) {
+ printf("Error: same bone! \n");
+ printf("\tstart = %s, end = %s \n", start->name, end->name);
+ }
+
+ /* step 1: add a new bone
+ * - head = head/tail of start (default head)
+ * - tail = head/tail of end (default tail)
+ * - parent = parent of start
+ */
+ if ((start->flag & BONE_TIPSEL) && !(start->flag & (BONE_SELECTED|BONE_ACTIVE))) {
+ VECCOPY(head, start->tail);
+ }
+ else {
+ VECCOPY(head, start->head);
+ }
+ if ((end->flag & BONE_ROOTSEL) && !(end->flag & (BONE_SELECTED|BONE_ACTIVE))) {
+ VECCOPY(tail, end->head);
+ }
+ else {
+ VECCOPY(tail, end->tail);
+ }
+ newbone= add_points_bone(head, tail);
+ newbone->parent = start->parent;
+
+ /* step 2a: parent children of in-between bones to newbone */
+ for (chain= chains->first; chain; chain= chain->next) {
+ /* ick: we need to check if parent of each bone in chain is one of the bones in the */
+ for (ebo= chain->data; ebo; ebo= ebo->parent) {
+ short found= 0;
+
+ /* try to find which bone from the list to be removed, is the parent */
+ for (ebone= end; ebone; ebone= ebone->parent) {
+ if (ebo->parent == ebone) {
+ found= 1;
+ break;
+ }
+ }
+
+ /* adjust this bone's parent to newbone then */
+ if (found) {
+ ebo->parent= newbone;
+ break;
+ }
+ }
+ }
+
+ /* step 2b: parent child of end to newbone (child from this chain) */
+ if (endchild)
+ endchild->parent= newbone;
+
+ /* step 3: delete all bones between and including start and end */
+ for (ebo= end; ebo; ebo= ebone) {
+ ebone= (ebo == start) ? (NULL) : (ebo->parent);
+ BLI_freelinkN(&G.edbo, ebo);
+ }
+}
+
+/* bone merging - has a menu! */
+void merge_armature(void)
+{
+ bArmature *arm= G.obedit->data;
+ short val= 0;
+
+ /* process a menu to determine how to merge */
+ // TODO: there's room for more modes of merging stuff...
+ val= pupmenu("Merge Selected Bones%t|Within Chains%x1");
+ if (val <= 0) return;
+
+ if (val == 1) {
+ /* go down chains, merging bones */
+ ListBase chains = {NULL, NULL};
+ LinkData *chain, *nchain;
+ EditBone *ebo;
+
+ /* get chains (ends on chains) */
+ chains_find_tips(&chains);
+ if (chains.first == NULL) return;
+
+ /* each 'chain' is the last bone in the chain (with no children) */
+ for (chain= chains.first; chain; chain= nchain) {
+ EditBone *bstart= NULL, *bend= NULL;
+ EditBone *bchild= NULL, *child=NULL;
+
+ /* temporarily remove chain from list of chains */
+ nchain= chain->next;
+ BLI_remlink(&chains, chain);
+
+ /* only consider bones that are visible and selected */
+ for (ebo=chain->data; ebo; child=ebo, ebo=ebo->parent) {
+ /* check if visible + selected */
+ if ( (arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A) &&
+ ((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
+ (ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) )
+ {
+ /* set either end or start (end gets priority, unless it is already set) */
+ if (bend == NULL) {
+ bend= ebo;
+ bchild= child;
+ }
+ else
+ bstart= ebo;
+ }
+ else {
+ /* chain is broken... merge any continous segments then clear */
+ if (bstart && bend)
+ bones_merge(bstart, bend, bchild, &chains);
+
+ bstart = NULL;
+ bend = NULL;
+ bchild = NULL;
+ }
+ }
+
+ /* merge from bstart to bend if something not merged */
+ if (bstart && bend)
+ bones_merge(bstart, bend, bchild, &chains);
+
+ /* put back link */
+ BLI_insertlinkbefore(&chains, nchain, chain);
+ }
+
+ BLI_freelistN(&chains);
+ }
+
+ /* undo + updates */
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ BIF_undo_push("Merge Bones");
+}
+
+/* ************** END Add/Remove stuff in editmode ************ */
/* *************** Tools in editmode *********** */
@@ -1753,104 +2397,172 @@ void show_all_armature_bones(void)
BIF_undo_push("Reveal Bones");
}
-void make_bone_parent(void)
+/* check for null, before calling! */
+static void bone_connect_to_existing_parent(EditBone *bone)
+{
+ bone->flag |= BONE_CONNECTED;
+ VECCOPY(bone->head, bone->parent->tail);
+ bone->rad_head = bone->parent->rad_tail;
+}
+
+static void bone_connect_to_new_parent(EditBone *selbone, EditBone *actbone, short mode)
{
- bArmature *arm= G.obedit->data;
EditBone *ebone;
float offset[3];
- short val;
- val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2");
+ if ((selbone->parent) && (selbone->flag & BONE_CONNECTED))
+ selbone->parent->flag &= ~(BONE_TIPSEL);
- if(val<1) return;
+ /* make actbone the parent of selbone */
+ selbone->parent= actbone;
- /* find active */
- for (ebone = G.edbo.first; ebone; ebone=ebone->next)
- if(arm->layer & ebone->layer)
- if(ebone->flag & BONE_ACTIVE) break;
+ /* in actbone tree we cannot have a loop */
+ for (ebone= actbone->parent; ebone; ebone= ebone->parent) {
+ if (ebone->parent==selbone) {
+ ebone->parent= NULL;
+ ebone->flag &= ~BONE_CONNECTED;
+ }
+ }
- if(ebone) {
- EditBone *actbone= ebone, *selbone= NULL;
+ if (mode == 1) {
+ /* Connected: Child bones will be moved to the parent tip */
+ selbone->flag |= BONE_CONNECTED;
+ VecSubf(offset, actbone->tail, selbone->head);
- /* find selected */
+ VECCOPY(selbone->head, actbone->tail);
+ selbone->rad_head= actbone->rad_tail;
+
+ VecAddf(selbone->tail, selbone->tail, offset);
+
+ /* offset for all its children */
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
- if(arm->layer & ebone->layer) {
- if(ebone->flag & BONE_SELECTED) {
- if(ebone!=actbone) {
- if(selbone==NULL) selbone= ebone;
- else {
- error("Need one active and one selected bone");
- return;
- }
- }
+ EditBone *par;
+
+ for (par= ebone->parent; par; par= par->parent) {
+ if (par==selbone) {
+ VecAddf(ebone->head, ebone->head, offset);
+ VecAddf(ebone->tail, ebone->tail, offset);
+ break;
}
}
}
- if(selbone==NULL) {
- /* we make sure bone is connected */
- if(val==1 && actbone->parent) {
- actbone->flag |= BONE_CONNECTED;
- VECCOPY(actbone->head, actbone->parent->tail);
- actbone->rad_head= actbone->parent->rad_tail;
- countall(); // checks selection
- allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Connect to Parent");
- }
- else error("Need one active and one selected bone");
+ }
+ else {
+ /* Offset: Child bones will retain their distance from the parent tip */
+ selbone->flag &= ~BONE_CONNECTED;
+ }
+}
+
+void make_bone_parent(void)
+{
+ bArmature *arm= G.obedit->data;
+ EditBone *actbone, *ebone, *selbone;
+ EditBone *flipbone, *flippar;
+ short allchildbones= 0, foundselbone= 0;
+ short val;
+
+ /* find active bone to parent to */
+ for (actbone = G.edbo.first; actbone; actbone=actbone->next) {
+ if (arm->layer & actbone->layer) {
+ if (actbone->flag & BONE_ACTIVE)
+ break;
}
- else {
- /* if selbone had a parent we clear parent tip */
- if(selbone->parent && (selbone->flag & BONE_CONNECTED))
- selbone->parent->flag &= ~(BONE_TIPSEL);
-
- selbone->parent= actbone;
-
- /* in actbone tree we cannot have a loop */
- for(ebone= actbone->parent; ebone; ebone= ebone->parent) {
- if(ebone->parent==selbone) {
- ebone->parent= NULL;
- ebone->flag &= ~BONE_CONNECTED;
- }
- }
-
- if(val==1) { // connected
- selbone->flag |= BONE_CONNECTED;
- VecSubf(offset, actbone->tail, selbone->head);
-
- VECCOPY(selbone->head, actbone->tail);
- selbone->rad_head= actbone->rad_tail;
+ }
+ if (actbone == NULL) {
+ error("Needs an active bone");
+ return;
+ }
- VecAddf(selbone->tail, selbone->tail, offset);
-
- // offset for all its children
- for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
- EditBone *par;
- for(par= ebone->parent; par; par= par->parent) {
- if(par==selbone) {
- VecAddf(ebone->head, ebone->head, offset);
- VecAddf(ebone->tail, ebone->tail, offset);
- break;
+ /* find selected bones */
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
+ if (arm->layer & ebone->layer) {
+ if ((ebone->flag & BONE_SELECTED) && (ebone != actbone)) {
+ foundselbone++;
+ if (ebone->parent != actbone) allchildbones= 1;
+ }
+ }
+ }
+ /* abort if no selected bones, and active bone doesn't have a parent to work with instead */
+ if (foundselbone==0 && actbone->parent==NULL) {
+ error("Need selected bone(s)");
+ return;
+ }
+
+ /* 'Keep Offset' option is only displayed if it's likely to be useful */
+ if (allchildbones)
+ val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2");
+ else
+ val= pupmenu("Make Parent%t|Connected%x1");
+
+ if (val < 1) return;
+
+ if (foundselbone==0 && actbone->parent) {
+ /* When only the active bone is selected, and it has a parent,
+ * connect it to the parent, as that is the only possible outcome.
+ */
+ bone_connect_to_existing_parent(actbone);
+
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ flipbone = armature_bone_get_mirrored(actbone);
+ if (flipbone)
+ bone_connect_to_existing_parent(flipbone);
+ }
+ }
+ else {
+ /* loop through all editbones, parenting all selected bones to the active bone */
+ for (selbone = G.edbo.first; selbone; selbone=selbone->next) {
+ if (arm->layer & selbone->layer) {
+ if ((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) {
+ /* parent selbone to actbone */
+ bone_connect_to_new_parent(selbone, actbone, val);
+
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ /* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
+ * (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
+ * This is useful for arm-chains, for example parenting lower arm to upper arm
+ * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
+ * then just use actbone. Useful when doing upper arm to spine.
+ */
+ flipbone = armature_bone_get_mirrored(selbone);
+ flippar = armature_bone_get_mirrored(actbone);
+
+ if (flipbone) {
+ if (flippar)
+ bone_connect_to_new_parent(flipbone, flippar, val);
+ else
+ bone_connect_to_new_parent(flipbone, actbone, val);
}
}
}
}
- else {
- selbone->flag &= ~BONE_CONNECTED;
- }
-
- countall(); // checks selection
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWOOPS, 0);
- BIF_undo_push("Make Parent");
}
}
+
+ countall(); /* checks selection */
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWOOPS, 0);
+ BIF_undo_push("Make Parent");
+
+ return;
+}
+
+static void editbone_clear_parent(EditBone *ebone, int mode)
+{
+ if (ebone->parent) {
+ /* for nice selection */
+ ebone->parent->flag &= ~(BONE_TIPSEL);
+ }
+
+ if(mode==1) ebone->parent= NULL;
+ ebone->flag &= ~BONE_CONNECTED;
}
void clear_bone_parent(void)
{
bArmature *arm= G.obedit->data;
EditBone *ebone;
+ EditBone *flipbone = NULL;
short val;
val= pupmenu("Clear Parent%t|Clear Parent%x1|Disconnect Bone%x2");
@@ -1859,13 +2571,13 @@ void clear_bone_parent(void)
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
if(arm->layer & ebone->layer) {
if(ebone->flag & BONE_SELECTED) {
- if(ebone->parent) {
- /* for nice selection */
- ebone->parent->flag &= ~(BONE_TIPSEL);
+
+ if(arm->flag & ARM_MIRROR_EDIT)
+ flipbone = armature_bone_get_mirrored(ebone);
- if(val==1) ebone->parent= NULL;
- ebone->flag &= ~BONE_CONNECTED;
- }
+ if (flipbone)
+ editbone_clear_parent(flipbone, val);
+ editbone_clear_parent(ebone, val);
}
}
}
@@ -2051,53 +2763,77 @@ void extrude_armature(int forked)
}
/* context; editmode armature */
-void subdivide_armature(void)
+void subdivide_armature(int numcuts)
{
bArmature *arm= G.obedit->data;
EditBone *ebone, *newbone, *tbone, *mbone;
- int a;
+ int a, i;
+ if(numcuts < 1) return;
+
for (mbone = G.edbo.last; mbone; mbone= mbone->prev) {
if(arm->layer & mbone->layer) {
if(mbone->flag & BONE_SELECTED) {
-
- /* take care of mirrored stuff */
- for(a=0; a<2; a++) {
- if(a==0) ebone= mbone;
- else {
- if(arm->flag & ARM_MIRROR_EDIT)
- ebone= armature_bone_get_mirrored(mbone);
- else ebone= NULL;
- }
- if(ebone) {
-
- newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv");
- *newbone = *ebone;
- BLI_addtail(&G.edbo, newbone);
-
- VecMidf(newbone->head, ebone->head, ebone->tail);
- VECCOPY(newbone->tail, ebone->tail);
- VECCOPY(ebone->tail, newbone->head);
-
- newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail);
- ebone->rad_tail= newbone->rad_head;
-
- newbone->flag |= BONE_CONNECTED;
-
- unique_editbone_name (&G.edbo, newbone->name);
+ for(i=numcuts+1; i>1; i--) {
+ /* compute cut ratio first */
+ float cutratio= 1/(float)i;
+ float cutratioI= 1-cutratio;
+
+ /* take care of mirrored stuff */
+ for(a=0; a<2; a++) {
+ float val1[3];
+ float val2[3];
+ float val3[3];
- /* correct parent bones */
- for (tbone = G.edbo.first; tbone; tbone=tbone->next){
- if(tbone->parent==ebone)
- tbone->parent= newbone;
+ /* try to find mirrored bone on a != 0 */
+ if(a) {
+ if(arm->flag & ARM_MIRROR_EDIT)
+ ebone= armature_bone_get_mirrored(mbone);
+ else ebone= NULL;
+ }
+ else
+ ebone= mbone;
+
+ if(ebone) {
+ newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv");
+ *newbone = *ebone;
+ BLI_addtail(&G.edbo, newbone);
+
+ /* calculate location of newbone->head */
+ VECCOPY(val1, ebone->head);
+ VECCOPY(val2, ebone->tail);
+ VECCOPY(val3, newbone->head);
+
+ val3[0]= val1[0]*cutratio+val2[0]*cutratioI;
+ val3[1]= val1[1]*cutratio+val2[1]*cutratioI;
+ val3[2]= val1[2]*cutratio+val2[2]*cutratioI;
+
+ VECCOPY(newbone->head, val3);
+ VECCOPY(newbone->tail, ebone->tail);
+ VECCOPY(ebone->tail, newbone->head);
+
+ newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail);
+ ebone->rad_tail= newbone->rad_head;
+
+ newbone->flag |= BONE_CONNECTED;
+
+ unique_editbone_name (&G.edbo, newbone->name);
+
+ /* correct parent bones */
+ for (tbone = G.edbo.first; tbone; tbone=tbone->next){
+ if(tbone->parent==ebone)
+ tbone->parent= newbone;
+ }
+ newbone->parent= ebone;
}
- newbone->parent= ebone;
}
}
}
}
}
- BIF_undo_push("Subdivide");
+
+ if(numcuts==1) BIF_undo_push("Subdivide");
+ else BIF_undo_push("Subdivide multi");
}
/* ***************** Pose tools ********************* */
@@ -2115,7 +2851,7 @@ void clear_armature(Object *ob, char mode)
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
if(arm->layer & pchan->bone->layer) {
- switch (mode){
+ switch (mode) {
case 'r':
pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; pchan->quat[0]=1.0F;
break;
@@ -2127,6 +2863,9 @@ void clear_armature(Object *ob, char mode)
break;
}
+
+ /* the current values from IPO's may not be zero, so tag as unkeyed */
+ pchan->bone->flag |= BONE_UNKEYED;
}
}
}
@@ -2157,6 +2896,8 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits)
nearBone= get_bone_from_selectbuffer(base, buffer, hits, 1);
if (nearBone) {
+ bArmature *arm= ob->data;
+
/* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
if (!(G.qual & LR_SHIFTKEY) || base!=BASACT){
deselectall_posearmature(ob, 0, 0);
@@ -2167,9 +2908,7 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits)
if (nearBone->flag & BONE_SELECTED) {
/* if not active, we make it active */
if((nearBone->flag & BONE_ACTIVE)==0) {
- bArmature *arm= ob->data;
bone_looper(ob, arm->bonebase.first, NULL, clear_active_flag);
-
nearBone->flag |= BONE_ACTIVE;
}
else {
@@ -2178,7 +2917,6 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits)
}
}
else{
- bArmature *arm= ob->data;
bone_looper(ob, arm->bonebase.first, NULL, clear_active_flag);
nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
@@ -2295,7 +3033,7 @@ int bone_looper(Object *ob, Bone *bone, void *data,
}
-static int bone_skinnable(Object *ob, Bone *bone, void *data)
+static int bone_skinnable(Object *ob, Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -2319,16 +3057,28 @@ static int bone_skinnable(Object *ob, Bone *bone, void *data)
* pointers to bones that point to all
* skinnable bones.
*/
- Bone ***hbone;
-
- if (!(bone->flag & BONE_NO_DEFORM)) {
- if (data != NULL) {
- hbone = (Bone ***) data;
- **hbone = bone;
- ++*hbone;
- }
- return 1;
- }
+ Bone ***hbone;
+ int a, segments;
+ struct { Object *armob; void *list; int heat; } *data = datap;
+
+ if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+ if (!(bone->flag & BONE_NO_DEFORM)) {
+ if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ segments = bone->segments;
+ else
+ segments = 1;
+
+ if (data->list != NULL) {
+ hbone = (Bone ***) &data->list;
+
+ for(a=0; a<segments; a++) {
+ **hbone = bone;
+ ++*hbone;
+ }
+ }
+ return segments;
+ }
+ }
return 0;
}
@@ -2347,7 +3097,7 @@ static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data)
return 0;
}
-static int dgroup_skinnable(Object *ob, Bone *bone, void *data)
+static int dgroup_skinnable(Object *ob, Bone *bone, void *datap)
{
/* Bones that are deforming
* are regarded to be "skinnable" and are eligible for
@@ -2373,156 +3123,257 @@ static int dgroup_skinnable(Object *ob, Bone *bone, void *data)
* of skinnable bones.
*/
bDeformGroup ***hgroup, *defgroup;
+ int a, segments;
+ struct { Object *armob; void *list; int heat; } *data= datap;
- if (!(bone->flag & BONE_NO_DEFORM)) {
- if ( !(defgroup = get_named_vertexgroup(ob, bone->name)) ) {
- defgroup = add_defgroup_name(ob, bone->name);
- }
-
- if (data != NULL) {
- hgroup = (bDeformGroup ***) data;
- **hgroup = defgroup;
- ++*hgroup;
- }
- return 1;
- }
+ if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+ if (!(bone->flag & BONE_NO_DEFORM)) {
+ if(data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
+ segments = bone->segments;
+ else
+ segments = 1;
+
+ if(!(defgroup = get_named_vertexgroup(ob, bone->name)))
+ defgroup = add_defgroup_name(ob, bone->name);
+
+ if (data->list != NULL) {
+ hgroup = (bDeformGroup ***) &data->list;
+
+ for(a=0; a<segments; a++) {
+ **hgroup = defgroup;
+ ++*hgroup;
+ }
+ }
+ return segments;
+ }
+ }
return 0;
}
-static void add_verts_to_closest_dgroup(Object *ob, Object *par)
-{
- /* This function implements a crude form of
- * auto-skinning: vertices are assigned to the
- * deformation groups associated with bones based
- * on thier proximity to a bone. Every vert is
- * given a weight of 1.0 to the weight group
- * cooresponding to the bone that it is
- * closest to. The vertex may also be assigned to
- * a deformation group associated to a bone
- * that is within 10% of the mninimum distance
- * between the bone and the nearest vert -- the
- * cooresponding weight will fall-off to zero
- * as the distance approaches the 10% tolerance mark.
- * If the mesh has subsurf enabled then the verts
- * on the subsurf limit surface is used to generate
- * the weights rather than the verts on the cage
- * mesh.
- *
- * ("Limit surface" = same amount of vertices as mesh, but vertices
- * moved to the subsurfed position, like for 'optimal').
- */
+static void add_vgroups__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
+{
+ /* DerivedMesh mapFunc for getting final coords in weight paint mode */
- bArmature *arm;
- Bone **bonelist, **bonehandle, *bone;
- bDeformGroup **dgrouplist, **dgrouphandle, *defgroup;
- float *distance;
- float root[3];
- float tip[3];
- float real_co[3];
- float *subverts = NULL;
- float *subvert;
- Mesh *mesh;
- MVert *vert;
-
- int numbones, i, j;
-
- /* If the parent object is not an armature exit */
- arm = get_armature(par);
- if (!arm)
- return;
-
- /* count the number of skinnable bones */
- numbones = bone_looper(ob, arm->bonebase.first, NULL,
- bone_skinnable);
-
- /* create an array of pointer to bones that are skinnable
- * and fill it with all of the skinnable bones
- */
- bonelist = MEM_mallocN(numbones*sizeof(Bone *), "bonelist");
- bonehandle = bonelist;
- bone_looper(ob, arm->bonebase.first, &bonehandle,
- bone_skinnable);
-
- /* create an array of pointers to the deform groups that
- * coorespond to the skinnable bones (creating them
- * as necessary.
- */
- dgrouplist = MEM_mallocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
- dgrouphandle = dgrouplist;
- bone_looper(ob, arm->bonebase.first, &dgrouphandle,
- dgroup_skinnable);
+ float (*verts)[3] = userData;
+ VECCOPY(verts[index], co);
+}
- /* create an array of floats that will be used for each vert
- * to hold the distance-factor to each bone.
- */
- distance = MEM_mallocN(numbones*sizeof(float), "distance");
+static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale)
+{
+ /* Create vertex group weights from envelopes */
- mesh = (Mesh*)ob->data;
+ Bone *bone;
+ bDeformGroup *dgroup;
+ float distance;
+ int i, iflip, j;
+
+ /* for each vertex in the mesh */
+ for (i=0; i < mesh->totvert; i++) {
+ iflip = (dgroupflip)? mesh_get_x_mirror_vert(ob, i): 0;
+
+ /* for each skinnable bone */
+ for (j=0; j < numbones; ++j) {
+ if(!selected[j])
+ continue;
- /* Is subsurf on? Lets use the verts on the limit surface then */
- if (modifiers_findByType(ob, eModifierType_Subsurf)) {
- subverts = MEM_mallocN(3*mesh->totvert*sizeof(float), "subverts");
- subsurf_calculate_limit_positions(mesh, (void *)subverts); /* (ton) made void*, dunno how to cast */
+ bone = bonelist[j];
+ dgroup = dgrouplist[j];
+
+ /* store the distance-factor from the vertex to the bone */
+ distance = distfactor_to_bone (verts[i], root[j], tip[j],
+ bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
+
+ /* add the vert to the deform group if weight!=0.0 */
+ if (distance!=0.0)
+ add_vert_to_defgroup (ob, dgroup, i, distance, WEIGHT_REPLACE);
+ else
+ remove_vert_defgroup (ob, dgroup, i);
+
+ /* do same for mirror */
+ if (dgroupflip && dgroupflip[j] && iflip >= 0) {
+ if (distance!=0.0)
+ add_vert_to_defgroup (ob, dgroupflip[j], iflip, distance,
+ WEIGHT_REPLACE);
+ else
+ remove_vert_defgroup (ob, dgroupflip[j], iflip);
+ }
+ }
}
+}
- /* for each vertex in the mesh ...
- */
- for ( i=0 ; i < mesh->totvert ; ++i ) {
- /* get the vert in global coords
- */
-
- if (subverts) {
- subvert = subverts + i*3;
- VECCOPY (real_co, subvert);
+void add_verts_to_dgroups(Object *ob, Object *par, int heat, int mirror)
+{
+ /* This functions implements the automatic computation of vertex group
+ * weights, either through envelopes or using a heat equilibrium.
+ *
+ * This function can be called both when parenting a mesh to an armature,
+ * or in weightpaint + posemode. In the latter case selection is taken
+ * into account and vertex weights can be mirrored.
+ *
+ * The mesh vertex positions used are either the final deformed coords
+ * from the derivedmesh in weightpaint mode, the final subsurf coords
+ * when parenting, or simply the original mesh coords.
+ */
+
+ bArmature *arm;
+ Bone **bonelist, *bone;
+ bDeformGroup **dgrouplist, **dgroupflip;
+ bDeformGroup *dgroup, *curdg;
+ bPoseChannel *pchan;
+ Mesh *mesh;
+ Mat4 *bbone = NULL;
+ float (*root)[3], (*tip)[3], (*verts)[3];
+ int *selected;
+ int numbones, vertsfilled = 0, i, j, segments = 0;
+ int wpmode = (G.f & G_WEIGHTPAINT);
+ struct { Object *armob; void *list; int heat; } looper_data;
+
+ /* If the parent object is not an armature exit */
+ arm = get_armature(par);
+ if (!arm)
+ return;
+
+ looper_data.armob = par;
+ looper_data.heat= heat;
+ looper_data.list= NULL;
+
+ /* count the number of skinnable bones */
+ numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
+
+ if (numbones == 0)
+ return;
+
+ /* create an array of pointer to bones that are skinnable
+ * and fill it with all of the skinnable bones */
+ bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
+ looper_data.list= bonelist;
+ bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable);
+
+ /* create an array of pointers to the deform groups that
+ * coorespond to the skinnable bones (creating them
+ * as necessary. */
+ dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
+ dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
+
+ looper_data.list= dgrouplist;
+ bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable);
+
+ /* create an array of root and tip positions transformed into
+ * global coords */
+ root = MEM_callocN(numbones*sizeof(float)*3, "root");
+ tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
+ selected = MEM_callocN(numbones*sizeof(int), "selected");
+
+ for (j=0; j < numbones; ++j) {
+ bone = bonelist[j];
+ dgroup = dgrouplist[j];
+
+ /* handle bbone */
+ if(heat) {
+ if(segments == 0) {
+ segments = 1;
+ bbone = NULL;
+
+ if(par->pose && (pchan=get_pose_channel(par->pose, bone->name))) {
+ if(bone->segments > 1) {
+ segments = bone->segments;
+ bbone = b_bone_spline_setup(pchan, 1);
+ }
+ }
+ }
+
+ segments--;
+ }
+
+ /* compute root and tip */
+ if(bbone) {
+ VECCOPY(root[j], bbone[segments].mat[3]);
+ Mat4MulVecfl(bone->arm_mat, root[j]);
+ if(segments+1 < bone->segments) {
+ VECCOPY(tip[j], bbone[segments+1].mat[3])
+ Mat4MulVecfl(bone->arm_mat, tip[j]);
+ }
+ else
+ VECCOPY(tip[j], bone->arm_tail)
}
else {
- vert = mesh->mvert + i;
- VECCOPY (real_co, vert->co);
+ VECCOPY(root[j], bone->arm_head);
+ VECCOPY(tip[j], bone->arm_tail);
}
- Mat4MulVecfl(ob->obmat, real_co);
+ Mat4MulVecfl(par->obmat, root[j]);
+ Mat4MulVecfl(par->obmat, tip[j]);
- /* for each skinnable bone ...
- */
- for (j=0; j < numbones; ++j) {
- bone = bonelist[j];
-
- /* get the root of the bone in global coords
- */
- VECCOPY(root, bone->arm_head);
- Mat4MulVecfl(par->obmat, root);
-
- /* get the tip of the bone in global coords
- */
- VECCOPY(tip, bone->arm_tail);
- Mat4MulVecfl(par->obmat, tip);
-
- /* store the distance-factor from the vertex to
- * the bone
- */
- distance[j]= distfactor_to_bone (real_co, root, tip, bone->rad_head, bone->rad_tail, bone->dist);
- }
-
- /* for each deform group ...
- */
- for (j=0; j < numbones; ++j) {
- defgroup = dgrouplist[j];
-
- /* add the vert to the deform group if weight!=0.0
- */
- if (distance[j]!=0.0)
- add_vert_to_defgroup (ob, defgroup, i, distance[j], WEIGHT_REPLACE);
- else
- remove_vert_defgroup (ob, defgroup, i);
- }
- }
+ /* set selected */
+ if(wpmode) {
+ if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))
+ selected[j] = 1;
+ }
+ else
+ selected[j] = 1;
- /* free the memory allocated
- */
+ /* find flipped group */
+ if(mirror) {
+ char name[32];
+
+ BLI_strncpy(name, dgroup->name, 32);
+ // 0 = don't strip off number extensions
+ bone_flip_name(name, 0);
+
+ for (curdg = ob->defbase.first; curdg; curdg=curdg->next)
+ if (!strcmp(curdg->name, name))
+ break;
+
+ dgroupflip[j] = curdg;
+ }
+ }
+
+ /* create verts */
+ mesh = (Mesh*)ob->data;
+ verts = MEM_callocN(mesh->totvert*sizeof(*verts), "closestboneverts");
+
+ if (wpmode) {
+ /* if in weight paint mode, use final verts from derivedmesh */
+ DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
+
+ if(dm->foreachMappedVert) {
+ dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void*)verts);
+ vertsfilled = 1;
+ }
+
+ dm->release(dm);
+ }
+ else if (modifiers_findByType(ob, eModifierType_Subsurf)) {
+ /* is subsurf on? Lets use the verts on the limit surface then.
+ * = same amount of vertices as mesh, but vertices moved to the
+ * subsurfed position, like for 'optimal'. */
+ subsurf_calculate_limit_positions(mesh, verts);
+ vertsfilled = 1;
+ }
+
+ /* transform verts to global space */
+ for (i=0; i < mesh->totvert; i++) {
+ if (!vertsfilled)
+ VECCOPY(verts[i], mesh->mvert[i].co)
+ Mat4MulVecfl(ob->obmat, verts[i]);
+ }
+
+ /* compute the weights based on gathered vertices and bones */
+ if (heat)
+ heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip,
+ root, tip, selected);
+ else
+ envelope_bone_weighting(ob, mesh, verts, numbones, bonelist, dgrouplist,
+ dgroupflip, root, tip, selected, Mat4ToScalef(par->obmat));
+
+ /* free the memory allocated */
MEM_freeN(bonelist);
MEM_freeN(dgrouplist);
- MEM_freeN(distance);
- if (subverts) MEM_freeN(subverts);
+ MEM_freeN(dgroupflip);
+ MEM_freeN(root);
+ MEM_freeN(tip);
+ MEM_freeN(selected);
+ MEM_freeN(verts);
}
void create_vgroups_from_armature(Object *ob, Object *par)
@@ -2544,7 +3395,8 @@ void create_vgroups_from_armature(Object *ob, Object *par)
mode= pupmenu("Create Vertex Groups? %t|"
"Don't Create Groups %x1|"
"Name Groups %x2|"
- "Create From Closest Bones %x3");
+ "Create From Envelopes %x3|"
+ "Create From Bone Heat %x4|");
switch (mode){
case 2:
/* Traverse the bone list, trying to create empty vertex
@@ -2558,11 +3410,12 @@ void create_vgroups_from_armature(Object *ob, Object *par)
break;
case 3:
+ case 4:
/* Traverse the bone list, trying to create vertex groups
* that are populated with the vertices for which the
* bone is closest.
*/
- add_verts_to_closest_dgroup(ob, par);
+ add_verts_to_dgroups(ob, par, (mode == 4), 0);
break;
}
@@ -2575,7 +3428,7 @@ static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr)
if(arm->layer & bone->layer) {
if (bone->flag & BONE_SELECTED) {
bone->flag |= BONE_HIDDEN_P;
- bone->flag &= ~BONE_SELECTED;
+ bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
}
}
return 0;
@@ -2605,6 +3458,7 @@ static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr)
if(arm->layer & bone->layer) {
if (~bone->flag & BONE_SELECTED) {
bone->flag |= BONE_HIDDEN_P;
+ bone->flag &= ~BONE_ACTIVE;
}
}
return 0;
@@ -2625,6 +3479,7 @@ void hide_unselected_pose_bones(void)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
BIF_undo_push("Hide Unselected Bone");
}
@@ -2657,6 +3512,7 @@ void show_all_pose_bones(void)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
BIF_undo_push("Reveal Bones");
}
@@ -2695,13 +3551,25 @@ void unique_bone_name (bArmature *arm, char *name)
static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldname, char *newname)
{
bConstraint *curcon;
- char *subtarget;
+ bConstraintTarget *ct;
- for (curcon = conlist->first; curcon; curcon=curcon->next){
- subtarget = get_con_subtarget_name(curcon, ob);
- if (subtarget)
- if (!strcmp(subtarget, oldname) )
- BLI_strncpy(subtarget, newname, MAXBONENAME);
+ for (curcon = conlist->first; curcon; curcon=curcon->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
+ ListBase targets = {NULL, NULL};
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(curcon, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if (ct->tar == ob) {
+ if (!strcmp(ct->subtarget, oldname) )
+ BLI_strncpy(ct->subtarget, newname, MAXBONENAME);
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(curcon, &targets, 0);
+ }
}
}
@@ -2833,13 +3701,37 @@ void armature_flip_names(void)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names");
+}
+
+/* context: edtimode armature */
+void armature_autoside_names(short axis)
+{
+ bArmature *arm= G.obedit->data;
+ EditBone *ebone;
+ char newname[32];
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
+ if (arm->layer & ebone->layer) {
+ if (ebone->flag & BONE_SELECTED) {
+ BLI_strncpy(newname, ebone->name, sizeof(newname));
+ bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]);
+ armature_bone_rename(G.obedit->data, ebone->name, newname);
+ }
+ }
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWOOPS, 0);
+ BIF_undo_push("Auto-side name");
}
-/* context; editmode armature */
+/* context: editmode armature */
EditBone *armature_bone_get_mirrored(EditBone *ebo)
{
EditBone *eboflip= NULL;
@@ -2883,6 +3775,7 @@ void transform_armature_mirror_update(void)
}
if(ebo->flag & BONE_SELECTED) {
eboflip->dist= ebo->dist;
+ eboflip->roll= -ebo->roll;
eboflip->xwidth= ebo->xwidth;
eboflip->zwidth= ebo->zwidth;
}
@@ -2891,3 +3784,1109 @@ void transform_armature_mirror_update(void)
}
}
+
+/*****************************************************************************************************/
+/*************************************** SKELETON GENERATOR ******************************************/
+/*****************************************************************************************************/
+
+/**************************************** SYMMETRY HANDLING ******************************************/
+
+void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level);
+
+void mirrorAlongAxis(float v[3], float center[3], float axis[3])
+{
+ float dv[3], pv[3];
+
+ VecSubf(dv, v, center);
+ Projf(pv, dv, axis);
+ VecMulf(pv, -2);
+ VecAddf(v, v, pv);
+}
+
+/* Helper structure for radial symmetry */
+typedef struct RadialArc
+{
+ ReebArc *arc;
+ float n[3]; /* normalized vector joining the nodes of the arc */
+} RadialArc;
+
+void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
+{
+ RadialArc *ring = NULL;
+ RadialArc *unit;
+ float limit = G.scene->toolsettings->skgen_symmetry_limit;
+ int symmetric = 1;
+ int count = 0;
+ int i;
+
+ /* count the number of arcs in the symmetry ring */
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* depth is store as a negative in flag. symmetry level is positive */
+ if (connectedArc->flags == -depth)
+ {
+ count++;
+ }
+ }
+
+ ring = MEM_callocN(sizeof(RadialArc) * count, "radial symmetry ring");
+ unit = ring;
+
+ /* fill in the ring */
+ for (unit = ring, i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* depth is store as a negative in flag. symmetry level is positive */
+ if (connectedArc->flags == -depth)
+ {
+ ReebNode *otherNode = OTHER_NODE(connectedArc, node);
+ float vec[3];
+
+ unit->arc = connectedArc;
+
+ /* project the node to node vector on the symmetry plane */
+ VecSubf(unit->n, otherNode->p, node->p);
+ Projf(vec, unit->n, axis);
+ VecSubf(unit->n, unit->n, vec);
+
+ Normalize(unit->n);
+
+ unit++;
+ }
+ }
+
+ /* sort ring */
+ for (i = 0; i < count - 1; i++)
+ {
+ float minAngle = 3; /* arbitrary high value, higher than 2, at least */
+ int minIndex = -1;
+ int j;
+
+ for (j = i + 1; j < count; j++)
+ {
+ float angle = Inpf(ring[i].n, ring[j].n);
+
+ /* map negative values to 1..2 */
+ if (angle < 0)
+ {
+ angle = 1 - angle;
+ }
+
+ if (angle < minAngle)
+ {
+ minIndex = j;
+ minAngle = angle;
+ }
+ }
+
+ /* swap if needed */
+ if (minIndex != i + 1)
+ {
+ RadialArc tmp;
+ tmp = ring[i + 1];
+ ring[i + 1] = ring[minIndex];
+ ring[minIndex] = tmp;
+ }
+ }
+
+ for (i = 0; i < count && symmetric; i++)
+ {
+ ReebNode *node1, *node2;
+ float tangent[3];
+ float normal[3];
+ float p[3];
+ int j = (i + 1) % count; /* next arc in the circular list */
+
+ VecAddf(tangent, ring[i].n, ring[j].n);
+ Crossf(normal, tangent, axis);
+
+ node1 = OTHER_NODE(ring[i].arc, node);
+ node2 = OTHER_NODE(ring[j].arc, node);
+
+ VECCOPY(p, node2->p);
+ mirrorAlongAxis(p, node->p, normal);
+
+ /* check if it's within limit before continuing */
+ if (VecLenf(node1->p, p) > limit)
+ {
+ symmetric = 0;
+ }
+
+ }
+
+ if (symmetric)
+ {
+ /* first pass, merge incrementally */
+ for (i = 0; i < count - 1; i++)
+ {
+ ReebNode *node1, *node2;
+ float tangent[3];
+ float normal[3];
+ int j = i + 1;
+
+ VecAddf(tangent, ring[i].n, ring[j].n);
+ Crossf(normal, tangent, axis);
+
+ node1 = OTHER_NODE(ring[i].arc, node);
+ node2 = OTHER_NODE(ring[j].arc, node);
+
+ /* mirror first node and mix with the second */
+ mirrorAlongAxis(node1->p, node->p, normal);
+ VecLerpf(node2->p, node2->p, node1->p, 1.0f / (j + 1));
+
+ /* Merge buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (ring[i].arc->bcount > 0 && ring[j].arc->bcount > 0)
+ {
+ ReebArcIterator iter1, iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(&iter1, ring[i].arc, node);
+ initArcIterator(&iter2, ring[j].arc, node);
+
+ bucket1 = nextBucket(&iter1);
+ bucket2 = nextBucket(&iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket1->val < bucket2->val)
+ {
+ bucket1 = nextBucket(&iter1);
+ }
+
+ while(bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = nextBucket(&iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+ {
+ bucket2->nv += bucket1->nv; /* add counts */
+
+ /* mirror on axis */
+ mirrorAlongAxis(bucket1->p, node->p, normal);
+ /* add bucket2 in bucket1 */
+ VecLerpf(bucket2->p, bucket2->p, bucket1->p, (float)bucket1->nv / (float)(bucket2->nv));
+ }
+ }
+ }
+
+ /* second pass, mirror back on previous arcs */
+ for (i = count - 1; i > 0; i--)
+ {
+ ReebNode *node1, *node2;
+ float tangent[3];
+ float normal[3];
+ int j = i - 1;
+
+ VecAddf(tangent, ring[i].n, ring[j].n);
+ Crossf(normal, tangent, axis);
+
+ node1 = OTHER_NODE(ring[i].arc, node);
+ node2 = OTHER_NODE(ring[j].arc, node);
+
+ /* copy first node than mirror */
+ VECCOPY(node2->p, node1->p);
+ mirrorAlongAxis(node2->p, node->p, normal);
+
+ /* Copy buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (ring[i].arc->bcount > 0 && ring[j].arc->bcount > 0)
+ {
+ ReebArcIterator iter1, iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(&iter1, ring[i].arc, node);
+ initArcIterator(&iter2, ring[j].arc, node);
+
+ bucket1 = nextBucket(&iter1);
+ bucket2 = nextBucket(&iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket1->val < bucket2->val)
+ {
+ bucket1 = nextBucket(&iter1);
+ }
+
+ while(bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = nextBucket(&iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+ {
+ /* copy and mirror back to bucket2 */
+ bucket2->nv = bucket1->nv;
+ VECCOPY(bucket2->p, bucket1->p);
+ mirrorAlongAxis(bucket2->p, node->p, normal);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(ring);
+}
+
+void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3])
+{
+ ReebArc *arc1 = NULL;
+ ReebArc *arc2 = NULL;
+ ReebNode *node1 = NULL, *node2 = NULL;
+ float limit = G.scene->toolsettings->skgen_symmetry_limit;
+ float nor[3], vec[3], p[3];
+ int i;
+
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* depth is store as a negative in flag. symmetry level is positive */
+ if (connectedArc->flags == -depth)
+ {
+ if (arc1 == NULL)
+ {
+ arc1 = connectedArc;
+ node1 = OTHER_NODE(arc1, node);
+ }
+ else
+ {
+ arc2 = connectedArc;
+ node2 = OTHER_NODE(arc2, node);
+ break; /* Can stop now, the two arcs have been found */
+ }
+ }
+ }
+
+ /* shouldn't happen, but just to be sure */
+ if (node1 == NULL || node2 == NULL)
+ {
+ return;
+ }
+
+ VecSubf(p, node1->p, node->p);
+ Crossf(vec, p, axis);
+ Crossf(nor, vec, axis);
+
+ /* mirror node2 along axis */
+ VECCOPY(p, node2->p);
+ mirrorAlongAxis(p, node->p, nor);
+
+ /* check if it's within limit before continuing */
+ if (VecLenf(node1->p, p) <= limit)
+ {
+
+ /* average with node1 */
+ VecAddf(node1->p, node1->p, p);
+ VecMulf(node1->p, 0.5f);
+
+ /* mirror back on node2 */
+ VECCOPY(node2->p, node1->p);
+ mirrorAlongAxis(node2->p, node->p, nor);
+
+ /* Merge buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (arc1->bcount > 0 && arc2->bcount > 0)
+ {
+ ReebArcIterator iter1, iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(&iter1, arc1, node);
+ initArcIterator(&iter2, arc2, node);
+
+ bucket1 = nextBucket(&iter1);
+ bucket2 = nextBucket(&iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket1->val < bucket2->val)
+ {
+ bucket1 = nextBucket(&iter1);
+ }
+
+ while(bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = nextBucket(&iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
+ {
+ bucket1->nv += bucket2->nv; /* add counts */
+
+ /* mirror on axis */
+ mirrorAlongAxis(bucket2->p, node->p, nor);
+ /* add bucket2 in bucket1 */
+ VecLerpf(bucket1->p, bucket1->p, bucket2->p, (float)bucket2->nv / (float)(bucket1->nv));
+
+ /* copy and mirror back to bucket2 */
+ bucket2->nv = bucket1->nv;
+ VECCOPY(bucket2->p, bucket1->p);
+ mirrorAlongAxis(bucket2->p, node->p, nor);
+ }
+ }
+ }
+}
+
+void markdownSecondarySymmetry(ReebNode *node, int depth, int level)
+{
+ float axis[3] = {0, 0, 0};
+ int count = 0;
+ int i;
+
+ /* Only reestablish spatial symmetry if needed */
+ if (G.scene->toolsettings->skgen_options & SKGEN_SYMMETRY)
+ {
+ /* count the number of branches in this symmetry group
+ * and determinte the axis of symmetry
+ * */
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* depth is store as a negative in flag. symmetry level is positive */
+ if (connectedArc->flags == -depth)
+ {
+ count++;
+ }
+ /* If arc is on the axis */
+ else if (connectedArc->flags == level)
+ {
+ VecAddf(axis, axis, connectedArc->v1->p);
+ VecSubf(axis, axis, connectedArc->v2->p);
+ }
+ }
+
+ Normalize(axis);
+
+ /* Split between axial and radial symmetry */
+ if (count == 2)
+ {
+ reestablishAxialSymmetry(node, depth, axis);
+ }
+ else
+ {
+ reestablishRadialSymmetry(node, depth, axis);
+ }
+ }
+
+ /* markdown secondary symetries */
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ if (connectedArc->flags == -depth)
+ {
+ /* markdown symmetry for branches corresponding to the depth */
+ markdownSymmetryArc(connectedArc, node, level + 1);
+ }
+ }
+}
+
+void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level)
+{
+ int i;
+ arc->flags = level;
+
+ node = OTHER_NODE(arc, node);
+
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ if (connectedArc != arc)
+ {
+ ReebNode *connectedNode = OTHER_NODE(connectedArc, node);
+
+ /* symmetry level is positive value, negative values is subtree depth */
+ connectedArc->flags = -subtreeDepth(connectedNode, connectedArc);
+ }
+ }
+
+ arc = NULL;
+
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ int issymmetryAxis = 0;
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* only arcs not already marked as symetric */
+ if (connectedArc->flags < 0)
+ {
+ int j;
+
+ /* true by default */
+ issymmetryAxis = 1;
+
+ for (j = 0; node->arcs[j] != NULL && issymmetryAxis == 1; j++)
+ {
+ ReebArc *otherArc = node->arcs[j];
+
+ /* different arc, same depth */
+ if (otherArc != connectedArc && otherArc->flags == connectedArc->flags)
+ {
+ /* not on the symmetry axis */
+ issymmetryAxis = 0;
+ }
+ }
+ }
+
+ /* arc could be on the symmetry axis */
+ if (issymmetryAxis == 1)
+ {
+ /* no arc as been marked previously, keep this one */
+ if (arc == NULL)
+ {
+ arc = connectedArc;
+ }
+ else
+ {
+ /* there can't be more than one symmetry arc */
+ arc = NULL;
+ break;
+ }
+ }
+ }
+
+ /* go down the arc continuing the symmetry axis */
+ if (arc)
+ {
+ markdownSymmetryArc(arc, node, level);
+ }
+
+
+ /* secondary symmetry */
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ ReebArc *connectedArc = node->arcs[i];
+
+ /* only arcs not already marked as symetric and is not the next arc on the symmetry axis */
+ if (connectedArc->flags < 0)
+ {
+ /* subtree depth is store as a negative value in the flag */
+ markdownSecondarySymmetry(node, -connectedArc->flags, level);
+ }
+ }
+}
+
+void markdownSymmetry(ReebGraph *rg)
+{
+ ReebNode *node;
+ ReebArc *arc;
+ /* only for Acyclic graphs */
+ int cyclic = isGraphCyclic(rg);
+
+ /* mark down all arcs as non-symetric */
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ arc->flags = 0;
+ }
+
+ /* mark down all nodes as not on the symmetry axis */
+ for (node = rg->nodes.first; node; node = node->next)
+ {
+ node->flags = 0;
+ }
+
+ /* node list is sorted, so lowest node is always the head (by design) */
+ node = rg->nodes.first;
+
+ /* only work on acyclic graphs and if only one arc is incident on the first node */
+ if (cyclic == 0 && countConnectedArcs(rg, node) == 1)
+ {
+ arc = node->arcs[0];
+
+ markdownSymmetryArc(arc, node, 1);
+
+ /* mark down non-symetric arcs */
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->flags < 0)
+ {
+ arc->flags = 0;
+ }
+ else
+ {
+ /* mark down nodes with the lowest level symmetry axis */
+ if (arc->v1->flags == 0 || arc->v1->flags > arc->flags)
+ {
+ arc->v1->flags = arc->flags;
+ }
+ if (arc->v2->flags == 0 || arc->v2->flags > arc->flags)
+ {
+ arc->v2->flags = arc->flags;
+ }
+ }
+ }
+ }
+}
+
+/**************************************** SUBDIVISION ALGOS ******************************************/
+
+EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
+{
+ EditBone *lastBone = NULL;
+ if (G.scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
+ {
+ ReebArcIterator iter;
+ EmbedBucket *current = NULL;
+ EmbedBucket *previous = NULL;
+ EditBone *child = NULL;
+ EditBone *parent = NULL;
+ EditBone *root = NULL;
+ float angleLimit = (float)cos(G.scene->toolsettings->skgen_angle_limit * M_PI / 180.0f);
+
+ parent = add_editbone("Bone");
+ parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ VECCOPY(parent->head, head->p);
+
+ root = parent;
+
+ for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
+ current;
+ previous = current, current = nextBucket(&iter))
+ {
+ float vec1[3], vec2[3];
+ float len1, len2;
+
+ VecSubf(vec1, previous->p, parent->head);
+ VecSubf(vec2, current->p, previous->p);
+
+ len1 = Normalize(vec1);
+ len2 = Normalize(vec2);
+
+ if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
+ {
+ VECCOPY(parent->tail, previous->p);
+
+ child = add_editbone("Bone");
+ VECCOPY(child->head, parent->tail);
+ child->parent = parent;
+ child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+
+ parent = child; /* new child is next parent */
+ }
+ }
+ VECCOPY(parent->tail, tail->p);
+
+ /* If the bone wasn't subdivided, delete it and return NULL
+ * to let subsequent subdivision methods do their thing.
+ * */
+ if (parent == root)
+ {
+ delete_bone(parent);
+ parent = NULL;
+ }
+
+ lastBone = parent; /* set last bone in the chain */
+ }
+
+ return lastBone;
+}
+
+float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
+{
+ int len = 2 + abs(end - start);
+
+ if (len > 2)
+ {
+ ReebArcIterator iter;
+ EmbedBucket *bucket = NULL;
+ float avg_t = 0.0f;
+ float s_t = 0.0f;
+ float s_xyz = 0.0f;
+
+ /* First pass, calculate average */
+ for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
+ bucket;
+ bucket = nextBucket(&iter))
+ {
+ float v[3];
+
+ VecSubf(v, bucket->p, v0);
+ avg_t += Inpf(v, n);
+ }
+
+ avg_t /= Inpf(n, n);
+ avg_t += 1.0f; /* adding start (0) and end (1) values */
+ avg_t /= len;
+
+ /* Second pass, calculate s_xyz and s_t */
+ for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
+ bucket;
+ bucket = nextBucket(&iter))
+ {
+ float v[3], d[3];
+ float dt;
+
+ VecSubf(v, bucket->p, v0);
+ Projf(d, v, n);
+ VecSubf(v, v, d);
+
+ dt = VecLength(d) - avg_t;
+
+ s_t += dt * dt;
+ s_xyz += Inpf(v, v);
+ }
+
+ /* adding start(0) and end(1) values to s_t */
+ s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
+
+ return 1.0f - s_xyz / s_t;
+ }
+ else
+ {
+ return 1.0f;
+ }
+}
+
+EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
+{
+ ReebArcIterator iter;
+ float n[3];
+ float CORRELATION_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
+ EditBone *lastBone = NULL;
+
+ /* init iterator to get start and end from head */
+ initArcIterator(&iter, arc, head);
+
+ /* Calculate overall */
+ VecSubf(n, arc->buckets[iter.end].p, head->p);
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION &&
+ calcCorrelation(arc, iter.start, iter.end, head->p, n) < CORRELATION_THRESHOLD)
+ {
+ EmbedBucket *bucket = NULL;
+ EmbedBucket *previous = NULL;
+ EditBone *child = NULL;
+ EditBone *parent = NULL;
+ int boneStart = iter.start;
+
+ parent = add_editbone("Bone");
+ parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ VECCOPY(parent->head, head->p);
+
+ for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
+ bucket;
+ previous = bucket, bucket = nextBucket(&iter))
+ {
+ /* Calculate normal */
+ VecSubf(n, bucket->p, parent->head);
+
+ if (calcCorrelation(arc, boneStart, iter.index, parent->head, n) < CORRELATION_THRESHOLD)
+ {
+ VECCOPY(parent->tail, previous->p);
+
+ child = add_editbone("Bone");
+ VECCOPY(child->head, parent->tail);
+ child->parent = parent;
+ child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+
+ parent = child; // new child is next parent
+ boneStart = iter.index; // start from end
+ }
+ }
+
+ VECCOPY(parent->tail, tail->p);
+
+ lastBone = parent; /* set last bone in the chain */
+ }
+
+ return lastBone;
+}
+
+float arcLengthRatio(ReebArc *arc)
+{
+ float arcLength = 0.0f;
+ float embedLength = 0.0f;
+ int i;
+
+ arcLength = VecLenf(arc->v1->p, arc->v2->p);
+
+ if (arc->bcount > 0)
+ {
+ /* Add the embedding */
+ for ( i = 1; i < arc->bcount; i++)
+ {
+ embedLength += VecLenf(arc->buckets[i - 1].p, arc->buckets[i].p);
+ }
+ /* Add head and tail -> embedding vectors */
+ embedLength += VecLenf(arc->v1->p, arc->buckets[0].p);
+ embedLength += VecLenf(arc->v2->p, arc->buckets[arc->bcount - 1].p);
+ }
+ else
+ {
+ embedLength = arcLength;
+ }
+
+ return embedLength / arcLength;
+}
+
+EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
+{
+ EditBone *lastBone = NULL;
+ if ((G.scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
+ arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
+ {
+ ReebArcIterator iter;
+ EmbedBucket *bucket = NULL;
+ EmbedBucket *previous = NULL;
+ EditBone *child = NULL;
+ EditBone *parent = NULL;
+ float lengthLimit = G.scene->toolsettings->skgen_length_limit;
+ int same = 0;
+
+ parent = add_editbone("Bone");
+ parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ VECCOPY(parent->head, head->p);
+
+ initArcIterator(&iter, arc, head);
+
+ bucket = nextBucket(&iter);
+
+ while (bucket != NULL)
+ {
+ float *vec0 = NULL;
+ float *vec1 = bucket->p;
+
+ /* first bucket. Previous is head */
+ if (previous == NULL)
+ {
+ vec0 = head->p;
+ }
+ /* Previous is a valid bucket */
+ else
+ {
+ vec0 = previous->p;
+ }
+
+ /* If lengthLimit hits the current segment */
+ if (VecLenf(vec1, parent->head) > lengthLimit)
+ {
+ if (same == 0)
+ {
+ float dv[3], off[3];
+ float a, b, c, f;
+
+ /* Solve quadratic distance equation */
+ VecSubf(dv, vec1, vec0);
+ a = Inpf(dv, dv);
+
+ VecSubf(off, vec0, parent->head);
+ b = 2 * Inpf(dv, off);
+
+ c = Inpf(off, off) - (lengthLimit * lengthLimit);
+
+ f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
+
+ //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
+
+ if (isnan(f) == 0 && f < 1.0f)
+ {
+ VECCOPY(parent->tail, dv);
+ VecMulf(parent->tail, f);
+ VecAddf(parent->tail, parent->tail, vec0);
+ }
+ else
+ {
+ VECCOPY(parent->tail, vec1);
+ }
+ }
+ else
+ {
+ float dv[3];
+
+ VecSubf(dv, vec1, vec0);
+ Normalize(dv);
+
+ VECCOPY(parent->tail, dv);
+ VecMulf(parent->tail, lengthLimit);
+ VecAddf(parent->tail, parent->tail, parent->head);
+ }
+
+ child = add_editbone("Bone");
+ VECCOPY(child->head, parent->tail);
+ child->parent = parent;
+ child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+
+ parent = child; // new child is next parent
+
+ same = 1; // mark as same
+ }
+ else
+ {
+ previous = bucket;
+ bucket = nextBucket(&iter);
+ same = 0; // Reset same
+ }
+ }
+ VECCOPY(parent->tail, tail->p);
+
+ lastBone = parent; /* set last bone in the chain */
+ }
+
+ return lastBone;
+}
+
+/***************************************** MAIN ALGORITHM ********************************************/
+
+void generateSkeletonFromReebGraph(ReebGraph *rg)
+{
+ GHash *arcBoneMap = NULL;
+ ReebArc *arc = NULL;
+ ReebNode *node = NULL;
+ Object *src = NULL;
+ Object *dst = NULL;
+
+ src = BASACT->object;
+
+ if (G.obedit != NULL)
+ {
+ exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
+ }
+
+ setcursor_space(SPACE_VIEW3D, CURSOR_WAIT);
+
+ dst = add_object(OB_ARMATURE);
+ base_init_from_view3d(BASACT, G.vd);
+ G.obedit= BASACT->object;
+
+ /* Copy orientation from source */
+ VECCOPY(dst->loc, src->obmat[3]);
+ Mat4ToEul(src->obmat, dst->rot);
+ Mat4ToSize(src->obmat, dst->size);
+
+ where_is_object(G.obedit);
+
+ make_editArmature();
+
+ arcBoneMap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ markdownSymmetry(rg);
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ EditBone *lastBone = NULL;
+ ReebNode *head, *tail;
+ int i;
+
+ /* Find out the direction of the arc through simple heuristics (in order of priority) :
+ *
+ * 1- Arcs on primary symmetry axis (flags == 1) point up (head: high weight -> tail: low weight)
+ * 2- Arcs starting on a primary axis point away from it (head: node on primary axis)
+ * 3- Arcs point down (head: low weight -> tail: high weight)
+ *
+ * Finally, the arc direction is stored in its flags: 1 (low -> high), -1 (high -> low)
+ */
+
+ /* if arc is a symmetry axis, internal bones go up the tree */
+ if (arc->flags == 1 && arc->v2->degree != 1)
+ {
+ head = arc->v2;
+ tail = arc->v1;
+
+ arc->flags = -1; /* mark arc direction */
+ }
+ /* Bones point AWAY from the symmetry axis */
+ else if (arc->v1->flags == 1)
+ {
+ head = arc->v1;
+ tail = arc->v2;
+
+ arc->flags = 1; /* mark arc direction */
+ }
+ else if (arc->v2->flags == 1)
+ {
+ head = arc->v2;
+ tail = arc->v1;
+
+ arc->flags = -1; /* mark arc direction */
+ }
+ /* otherwise, always go from low weight to high weight */
+ else
+ {
+ head = arc->v1;
+ tail = arc->v2;
+
+ arc->flags = 1; /* mark arc direction */
+ }
+
+ /* Loop over subdivision methods */
+ for (i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++)
+ {
+ switch(G.scene->toolsettings->skgen_subdivisions[i])
+ {
+ case SKGEN_SUB_LENGTH:
+ lastBone = subdivideByLength(arc, head, tail);
+ break;
+ case SKGEN_SUB_ANGLE:
+ lastBone = subdivideByAngle(arc, head, tail);
+ break;
+ case SKGEN_SUB_CORRELATION:
+ lastBone = subdivideByCorrelation(arc, head, tail);
+ break;
+ }
+ }
+
+ if (lastBone == NULL)
+ {
+ EditBone *bone;
+ bone = add_editbone("Bone");
+ bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+
+ VECCOPY(bone->head, head->p);
+ VECCOPY(bone->tail, tail->p);
+
+ /* set first and last bone, since there's only one */
+ lastBone = bone;
+ }
+
+ BLI_ghash_insert(arcBoneMap, arc, lastBone);
+ }
+
+ /* Second pass, setup parent relationship between arcs */
+ for (node = rg->nodes.first; node; node = node->next)
+ {
+ ReebArc *incomingArc = NULL;
+ int i;
+
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ arc = node->arcs[i];
+
+ /* if arc is incoming into the node */
+ if ((arc->v1 == node && arc->flags == -1) || (arc->v2 == node && arc->flags == 1))
+ {
+ if (incomingArc == NULL)
+ {
+ incomingArc = arc;
+ /* loop further to make sure there's only one incoming arc */
+ }
+ else
+ {
+ /* skip this node if more than one incomingArc */
+ incomingArc = NULL;
+ break; /* No need to look further, we are skipping already */
+ }
+ }
+ }
+
+ if (incomingArc != NULL)
+ {
+ EditBone *parentBone = BLI_ghash_lookup(arcBoneMap, incomingArc);
+
+ /* Look for outgoing arcs and parent their bones */
+ for (i = 0; node->arcs[i] != NULL; i++)
+ {
+ arc = node->arcs[i];
+
+ /* if arc is outgoing from the node */
+ if ((arc->v1 == node && arc->flags == 1) || (arc->v2 == node && arc->flags == -1))
+ {
+ EditBone *childBone = BLI_ghash_lookup(arcBoneMap, arc);
+
+ /* find the root bone */
+ while(childBone->parent != NULL)
+ {
+ childBone = childBone->parent;
+ }
+
+ childBone->parent = parentBone;
+ childBone->flag |= BONE_CONNECTED;
+ }
+ }
+ }
+ }
+
+ BLI_ghash_free(arcBoneMap, NULL, NULL);
+
+ setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
+
+ BIF_undo_push("Generate Skeleton");
+}
+
+void generateSkeleton(void)
+{
+ EditMesh *em = G.editMesh;
+ ReebGraph *rg = NULL;
+ int i;
+
+ if (em == NULL)
+ return;
+
+ setcursor_space(SPACE_VIEW3D, CURSOR_WAIT);
+
+ if (weightFromDistance(em) == 0)
+ {
+ error("No selected vertex\n");
+ return;
+ }
+
+ renormalizeWeight(em, 1.0f);
+
+ weightToHarmonic(em);
+
+#ifdef DEBUG_REEB
+ weightToVCol(em);
+#endif
+
+ rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution);
+
+ verifyBuckets(rg);
+
+ /* Remove arcs without embedding */
+ filterNullReebGraph(rg);
+
+ verifyBuckets(rg);
+
+
+ i = 1;
+ /* filter until there's nothing more to do */
+ while (i == 1)
+ {
+ i = 0; /* no work done yet */
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_EXTERNAL)
+ {
+ i |= filterExternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution);
+ }
+
+ verifyBuckets(rg);
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_INTERNAL)
+ {
+ i |= filterInternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution);
+ }
+ }
+
+ verifyBuckets(rg);
+
+ repositionNodes(rg);
+
+ verifyBuckets(rg);
+
+ /* Filtering might have created degree 2 nodes, so remove them */
+ removeNormalNodes(rg);
+
+ verifyBuckets(rg);
+
+ for(i = 0; i < G.scene->toolsettings->skgen_postpro_passes; i++)
+ {
+ postprocessGraph(rg, G.scene->toolsettings->skgen_postpro);
+ }
+
+ buildAdjacencyList(rg);
+
+ sortNodes(rg);
+
+ sortArcs(rg);
+
+ generateSkeletonFromReebGraph(rg);
+
+ freeGraph(rg);
+}
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index 2eef0f55978..542b31b1157 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Joshua Leung
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_dynstr.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
@@ -45,6 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
#include "BKE_action.h"
@@ -52,6 +54,7 @@
#include "BKE_constraint.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_ipo.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
@@ -65,59 +68,62 @@
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BPY_extern.h"
+
#include "blendef.h"
#include "nla.h"
#include "mydevice.h"
+/* -------------- Get Active Constraint Data ---------------------- */
ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
{
char ipstr[64];
- if (!ob)
+ if (ob == NULL)
return NULL;
/* See if we are a bone constraint */
if (ob->flag & OB_POSEMODE) {
bActionChannel *achan;
bPoseChannel *pchan;
-
+
pchan = get_active_posechannel(ob);
if (pchan) {
-
/* Make sure we have an action */
- if (!ob->action){
- if (!forcevalid)
+ if (ob->action == NULL) {
+ if (forcevalid == 0)
return NULL;
- ob->action=add_empty_action("Action");
+ ob->action= add_empty_action("Action");
}
/* Make sure we have an actionchannel */
achan = get_action_channel(ob->action, pchan->name);
- if (!achan){
- if (!forcevalid)
+ if (achan == NULL) {
+ if (forcevalid == 0)
return NULL;
- achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
-
- strcpy (achan->name, pchan->name);
- sprintf (ipstr, "%s.%s", ob->action->id.name+2, achan->name);
+ achan = MEM_callocN (sizeof(bActionChannel), "ActionChannel");
+
+ strcpy(achan->name, pchan->name);
+ sprintf(ipstr, "%s.%s", ob->action->id.name+2, achan->name);
ipstr[23]=0;
achan->ipo= add_ipo(ipstr, ID_AC);
- BLI_addtail (&ob->action->chanbase, achan);
+ BLI_addtail(&ob->action->chanbase, achan);
}
return &achan->constraintChannels;
}
- else return NULL;
+ else
+ return NULL;
}
/* else we return object constraints */
else {
- if(ob->ipoflag & OB_ACTION_OB) {
+ if (ob->ipoflag & OB_ACTION_OB) {
bActionChannel *achan = get_action_channel(ob->action, "Object");
- if(achan)
+ if (achan)
return &achan->constraintChannels;
else
return NULL;
@@ -129,14 +135,14 @@ ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
/* if object in posemode, active bone constraints, else object constraints */
-ListBase *get_active_constraints(Object *ob)
+ListBase *get_active_constraints (Object *ob)
{
- if (!ob)
+ if (ob == NULL)
return NULL;
if (ob->flag & OB_POSEMODE) {
bPoseChannel *pchan;
-
+
pchan = get_active_posechannel(ob);
if (pchan)
return &pchan->constraints;
@@ -148,40 +154,46 @@ ListBase *get_active_constraints(Object *ob)
}
/* single constraint */
-bConstraint *get_active_constraint(Object *ob)
+bConstraint *get_active_constraint (Object *ob)
{
ListBase *lb= get_active_constraints(ob);
- if(lb) {
+ if (lb) {
bConstraint *con;
- for(con= lb->first; con; con=con->next)
- if(con->flag & CONSTRAINT_ACTIVE)
+
+ for (con= lb->first; con; con=con->next) {
+ if (con->flag & CONSTRAINT_ACTIVE)
return con;
+ }
}
+
return NULL;
}
/* single channel, for ipo */
-bConstraintChannel *get_active_constraint_channel(Object *ob)
+bConstraintChannel *get_active_constraint_channel (Object *ob)
{
bConstraint *con;
bConstraintChannel *chan;
if (ob->flag & OB_POSEMODE) {
- if(ob->action) {
+ if (ob->action) {
bPoseChannel *pchan;
pchan = get_active_posechannel(ob);
- if(pchan) {
- for(con= pchan->constraints.first; con; con= con->next)
- if(con->flag & CONSTRAINT_ACTIVE)
+ if (pchan) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (con->flag & CONSTRAINT_ACTIVE)
break;
- if(con) {
+ }
+
+ if (con) {
bActionChannel *achan = get_action_channel(ob->action, pchan->name);
- if(achan) {
- for(chan= achan->constraintChannels.first; chan; chan= chan->next)
- if(!strcmp(chan->name, con->name))
+ if (achan) {
+ for (chan= achan->constraintChannels.first; chan; chan= chan->next) {
+ if (!strcmp(chan->name, con->name))
break;
+ }
return chan;
}
}
@@ -189,16 +201,20 @@ bConstraintChannel *get_active_constraint_channel(Object *ob)
}
}
else {
- for(con= ob->constraints.first; con; con= con->next)
- if(con->flag & CONSTRAINT_ACTIVE)
+ for (con= ob->constraints.first; con; con= con->next) {
+ if (con->flag & CONSTRAINT_ACTIVE)
break;
- if(con) {
+ }
+
+ if (con) {
ListBase *lb= get_active_constraint_channels(ob, 0);
-
- if(lb) {
- for(chan= lb->first; chan; chan= chan->next)
- if(!strcmp(chan->name, con->name))
+
+ if (lb) {
+ for (chan= lb->first; chan; chan= chan->next) {
+ if (!strcmp(chan->name, con->name))
break;
+ }
+
return chan;
}
}
@@ -207,24 +223,37 @@ bConstraintChannel *get_active_constraint_channel(Object *ob)
return NULL;
}
+/* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
-bConstraint *add_new_constraint(short type)
+/* Creates a new constraint, initialises its data, and returns it */
+bConstraint *add_new_constraint (short type)
{
bConstraint *con;
+ bConstraintTypeInfo *cti;
- con = MEM_callocN(sizeof(bConstraint), "constraint");
-
+ con = MEM_callocN(sizeof(bConstraint), "Constraint");
+
/* Set up a generic constraint datablock */
con->type = type;
con->flag |= CONSTRAINT_EXPAND;
- con->enforce=1.0F;
+ con->enforce = 1.0F;
+ strcpy(con->name, "Const");
+
/* Load the data for it */
- con->data = new_constraint_data(con->type);
- strcpy (con->name, "Const");
+ cti = constraint_get_typeinfo(con);
+ if (cti) {
+ con->data = MEM_callocN(cti->size, cti->structName);
+
+ /* only constraints that change any settings need this */
+ if (cti->new_data)
+ cti->new_data(con->data);
+ }
+
return con;
}
-void add_constraint_to_object(bConstraint *con, Object *ob)
+/* Adds the given constraint to the Object-level set of constraints for the given Object */
+void add_constraint_to_object (bConstraint *con, Object *ob)
{
ListBase *list;
list = &ob->constraints;
@@ -233,404 +262,52 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
unique_constraint_name(con, list);
BLI_addtail(list, con);
+ if (proxylocked_constraints_owner(ob, NULL))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
+
con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
+ for (con= con->prev; con; con= con->prev)
con->flag &= ~CONSTRAINT_ACTIVE;
}
}
-
-char *get_con_subtarget_name(bConstraint *con, Object *target)
+/* helper function for add_constriant - sets the last target for the active constraint */
+static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
{
- /*
- * If the target for this constraint is target, return a pointer
- * to the name for this constraints subtarget ... NULL otherwise
- */
- switch (con->type) {
-
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = con->data;
- if (data->tar==target) return data->subtarget;
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- /* wonder if this is relevent, since this constraint
- * cannot have a subtarget - theeth
- */
- {
- /*
- * bFollowPathConstraint *data = con->data;
- */
- return NULL;
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+ int num_targets, i;
+
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+ num_targets= BLI_countlist(&targets);
+
+ if (index < 0) {
+ if (abs(index) < num_targets)
+ index= num_targets - abs(index);
+ else
+ index= num_targets - 1;
}
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- /* cannot have subtarget. if followpath is removed from here, remove this too... */
- return NULL;
+ else if (index >= num_targets) {
+ index= num_targets - 1;
}
- break;
- }
-
- return NULL;
-}
-
-/* checks validity of object pointers, and NULLs,
- if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */
-static void test_constraints (Object *owner, const char* substring)
-{
-
- bConstraint *curcon;
- ListBase *conlist= NULL;
- int type;
-
- if (owner==NULL) return;
-
- /* Check parents */
- /* Get the constraint list for this object */
-
- if (strlen (substring)){
- switch (owner->type){
- case OB_ARMATURE:
- type = TARGET_BONE;
- break;
- default:
- type = TARGET_OBJECT;
+
+ for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
+ if (i == index) {
+ ct->tar= target;
+ strcpy(ct->subtarget, subtarget);
break;
- }
- }
- else
- type = TARGET_OBJECT;
-
-
- switch (type){
- case TARGET_OBJECT:
- conlist = &owner->constraints;
- break;
- case TARGET_BONE:
- {
- Bone *bone;
- bPoseChannel *chan;
-
- bone = get_named_bone(((bArmature*)owner->data), substring);
- chan = get_pose_channel (owner->pose, substring);
- if (bone && chan){
- conlist = &chan->constraints;
- }
- }
- break;
- }
-
- /* Cycle constraints */
- if (conlist){
- for (curcon = conlist->first; curcon; curcon=curcon->next){
- curcon->flag &= ~CONSTRAINT_DISABLE;
-
- switch (curcon->type){
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_MINMAX:
- {
- bMinMaxConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- {
- bSizeLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = curcon->data;
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = curcon->data;
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->reserved2==data->reserved1){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->reserved2+3==data->reserved1){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if (data->lockflag==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->lockflag+3==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->tar->type != OB_CURVE){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->upflag==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- if (data->upflag+3==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- }
- break;
- case CONSTRAINT_TYPE_CLAMPTO:
- {
- bClampToConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
-
- if (data->tar->type != OB_CURVE){
- data->tar = NULL;
- curcon->flag |= CONSTRAINT_DISABLE;
- break;
- }
- else {
- Curve *cu= data->tar->data;
-
- /* auto-set 'Path' setting on curve so this works */
- cu->flag |= CU_PATH;
- }
- }
- break;
}
}
- }
-}
-
-static void test_bonelist_constraints (Object *owner, ListBase *list)
-{
- Bone *bone;
-
- for (bone = list->first; bone; bone=bone->next) {
- test_constraints(owner, bone->name);
- test_bonelist_constraints (owner, &bone->childbase);
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
}
}
-void object_test_constraints (Object *owner)
-{
- test_constraints(owner, "");
-
- if(owner->type==OB_ARMATURE) {
- bArmature *arm;
- arm = get_armature(owner);
- if (arm)
- test_bonelist_constraints (owner, &arm->bonebase);
- }
-
-}
-
/* context: active object in posemode, active channel, optional selected channel */
-void add_constraint(int only_IK)
+void add_constraint (short only_IK)
{
Object *ob= OBACT, *obsel=NULL;
bPoseChannel *pchanact=NULL, *pchansel=NULL;
@@ -639,95 +316,94 @@ void add_constraint(int only_IK)
short nr;
/* paranoia checks */
- if(ob==NULL || ob==G.obedit) return;
+ if ((ob==NULL) || (ob==G.obedit))
+ return;
- if(ob->pose && (ob->flag & OB_POSEMODE)) {
+ if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
bArmature *arm= ob->data;
/* find active channel */
pchanact= get_active_posechannel(ob);
- if(pchanact==NULL) return;
-
- /* check protection */
- if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
- error("Bone is Proxy protected");
+ if (pchanact==NULL)
return;
- }
/* find selected bone */
- for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
- if(pchansel!=pchanact)
- if(pchansel->bone->flag & BONE_SELECTED)
- if(pchansel->bone->layer & arm->layer)
+ for (pchansel=ob->pose->chanbase.first; pchansel; pchansel=pchansel->next) {
+ if (pchansel != pchanact) {
+ if (pchansel->bone->flag & BONE_SELECTED) {
+ if (pchansel->bone->layer & arm->layer)
break;
+ }
+ }
}
}
/* find selected object */
- for(base= FIRSTBASE; base; base= base->next)
- if( TESTBASE(base) && base->object!=ob )
+ for (base= FIRSTBASE; base; base= base->next) {
+ if ((TESTBASE(base)) && (base->object!=ob))
obsel= base->object;
+ }
/* the only_IK caller has checked for posemode! */
- if(only_IK) {
- for(con= pchanact->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
+ if (only_IK) {
+ for (con= pchanact->constraints.first; con; con= con->next) {
+ if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
}
- if(con) {
+ if (con) {
error("Pose Channel already has IK");
return;
}
- if(pchansel)
+ if (pchansel)
nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
- else if(obsel)
+ else if (obsel)
nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
else
nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
}
else {
- if(pchanact) {
- if(pchansel)
- nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16");
- else if(obsel && obsel->type==OB_CURVE)
- nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|Action%x16");
- else if(obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16");
+ if (pchanact) {
+ if (pchansel)
+ nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ else if ((obsel) && (obsel->type==OB_CURVE))
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
+ else if (obsel)
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
}
else {
- if(obsel && obsel->type==OB_CURVE)
- nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17");
- else if(obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
+ if ((obsel) && (obsel->type==OB_CURVE))
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
+ else if (obsel)
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
}
}
- if(nr<1) return;
+ if (nr < 1) return;
/* handle IK separate */
- if(nr==10 || nr==11) {
-
- /* prevent weird chains... */
- if(pchansel) {
+ if (nr==10 || nr==11) {
+ /* ik - prevent weird chains... */
+ if (pchansel) {
bPoseChannel *pchan= pchanact;
- while(pchan) {
- if(pchan==pchansel) break;
+ while (pchan) {
+ if (pchan==pchansel) break;
pchan= pchan->parent;
}
- if(pchan) {
+ if (pchan) {
error("IK root cannot be linked to IK tip");
return;
}
+
pchan= pchansel;
- while(pchan) {
- if(pchan==pchanact) break;
+ while (pchan) {
+ if (pchan==pchanact) break;
pchan= pchan->parent;
}
- if(pchan) {
+ if (pchan) {
error("IK tip cannot be linked to IK root");
return;
}
@@ -736,54 +412,96 @@ void add_constraint(int only_IK)
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
BLI_addtail(&pchanact->constraints, con);
unique_constraint_name(con, &pchanact->constraints);
- pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
- if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
+ pchanact->constflag |= PCHAN_HAS_IK; /* for draw, but also for detecting while pose solving */
+ if (nr==11)
+ pchanact->constflag |= PCHAN_HAS_TARGET;
+ if (proxylocked_constraints_owner(ob, pchanact))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
else {
-
- if(nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
- else if(nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
- else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
- else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
- else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
- else if(nr==6) {
+ /* normal constraints - add data */
+ if (nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
+ else if (nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
+ else if (nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
+ else if (nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
+ else if (nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
+ else if (nr==6) {
Curve *cu= obsel->data;
cu->flag |= CU_PATH;
con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
}
- else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
- else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
- else if(nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
- else if(nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
- else if(nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
- else if(nr==16) con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
- else if(nr==17) {
+ else if (nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
+ else if (nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
+ else if (nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
+ else if (nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
+ else if (nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
+ else if (nr==16) {
+ /* TODO: add a popup-menu to display list of available actions to use (like for pyconstraints) */
+ con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
+ }
+ else if (nr==17) {
Curve *cu= obsel->data;
cu->flag |= CU_PATH;
con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
}
+ else if (nr==18) {
+ char *menustr;
+ int scriptint= 0;
+
+ /* popup a list of usable scripts */
+ menustr = buildmenu_pyconstraints(NULL, &scriptint);
+ scriptint = pupmenu(menustr);
+ MEM_freeN(menustr);
+
+ /* only add constraint if a script was chosen */
+ if (scriptint) {
+ /* add constraint */
+ con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
+ validate_pyconstraint_cb(con->data, &scriptint);
+
+ /* make sure target allowance is set correctly */
+ BPY_pyconstraint_update(ob, con);
+ }
+ }
+ else if (nr==19) {
+ con = add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
+
+ /* if this constraint is being added to a posechannel, make sure
+ * the constraint gets evaluated in pose-space
+ */
+ if (pchanact) {
+ con->ownspace = CONSTRAINT_SPACE_POSE;
+ con->flag |= CONSTRAINT_SPACEONCE;
+ }
+ }
+ else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
+ else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
- if(con==NULL) return; /* paranoia */
+ if (con==NULL) return; /* paranoia */
- if(pchanact) {
+ if (pchanact) {
BLI_addtail(&pchanact->constraints, con);
unique_constraint_name(con, &pchanact->constraints);
pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
+ if (proxylocked_constraints_owner(ob, pchanact))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
else {
BLI_addtail(&ob->constraints, con);
unique_constraint_name(con, &ob->constraints);
+ if (proxylocked_constraints_owner(ob, NULL))
+ con->flag |= CONSTRAINT_PROXY_LOCAL;
}
}
/* set the target */
- if(pchansel) {
- set_constraint_target(con, ob, pchansel->name);
+ if (pchansel) {
+ set_constraint_nth_target(con, ob, pchansel->name, 0);
}
- else if(obsel) {
- set_constraint_target(con, obsel, NULL);
+ else if (obsel) {
+ set_constraint_nth_target(con, obsel, "", 0);
}
- else if(ELEM4(nr, 11, 13, 14, 15)==0) { /* add new empty as target */
+ else if (ELEM4(nr, 11, 13, 14, 15)==0) { /* add new empty as target */
Base *base= BASACT, *newbase;
Object *obt;
@@ -794,8 +512,8 @@ void add_constraint(int only_IK)
obt->lay= newbase->lay;
/* transform cent to global coords for loc */
- if(pchanact) {
- if(only_IK)
+ if (pchanact) {
+ if (only_IK)
VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
else
VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
@@ -803,63 +521,68 @@ void add_constraint(int only_IK)
else
VECCOPY(obt->loc, ob->obmat[3]);
- set_constraint_target(con, obt, NULL);
+ set_constraint_nth_target(con, obt, "", 0);
/* restore, add_object sets active */
BASACT= base;
base->flag |= SELECT;
}
-
-
+
/* active flag */
con->flag |= CONSTRAINT_ACTIVE;
- for(con= con->prev; con; con= con->prev)
+ for (con= con->prev; con; con= con->prev)
con->flag &= ~CONSTRAINT_ACTIVE;
DAG_scene_sort(G.scene); // sort order of objects
- if(pchanact) {
+ if (pchanact) {
ob->pose->flag |= POSE_RECALC; // sort pose channels
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
}
else
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); // and all its relations
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
- if(only_IK)
+ if (only_IK)
BIF_undo_push("Add IK Constraint");
else
BIF_undo_push("Add Constraint");
}
-void ob_clear_constraints(void)
+/* Remove all constraints from the active object */
+void ob_clear_constraints (void)
{
Object *ob= OBACT;
/* paranoia checks */
- if(!ob) return;
- if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
+ if ((ob==NULL) || (ob==G.obedit) || (ob->flag & OB_POSEMODE))
+ return;
- if(okee("Clear Constraints")==0) return;
+ /* get user permission */
+ if (okee("Clear Constraints")==0)
+ return;
+ /* do freeing */
free_constraints(&ob->constraints);
+ /* do updates */
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWBUTSOBJECT, 0);
- allqueue (REDRAWOOPS, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWOOPS, 0);
BIF_undo_push("Clear Constraint(s)");
-
}
-/* con already has the new name */
-void rename_constraint(Object *ob, bConstraint *con, char *oldname)
+/* Rename the given constraint
+ * - con already has the new name
+ */
+void rename_constraint (Object *ob, bConstraint *con, char *oldname)
{
bConstraint *tcon;
bConstraintChannel *conchan;
@@ -868,33 +591,35 @@ void rename_constraint(Object *ob, bConstraint *con, char *oldname)
char *channame="";
/* get context by searching for con (primitive...) */
- for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
- if(tcon==con)
+ for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
+ if (tcon==con)
break;
+ }
- if(tcon) {
+ if (tcon) {
conlist= &ob->constraints;
channame= "Object";
from_object= 1;
}
- else if(ob->pose) {
+ else if (ob->pose) {
bPoseChannel *pchan;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
- if(tcon==con)
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
+ if (tcon==con)
break;
}
- if(tcon)
+ if (tcon)
break;
}
- if(tcon) {
+
+ if (tcon) {
conlist= &pchan->constraints;
channame= pchan->name;
}
}
- if(conlist==NULL) {
+ if (conlist==NULL) {
printf("rename constraint failed\n"); /* should not happen in UI */
return;
}
@@ -903,21 +628,358 @@ void rename_constraint(Object *ob, bConstraint *con, char *oldname)
unique_constraint_name (con, conlist);
/* own channels */
- if(from_object) {
- for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
- if( strcmp(oldname, conchan->name)==0 )
+ if (from_object) {
+ for (conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
+ if ( strcmp(oldname, conchan->name)==0 )
BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
}
}
+
/* own action */
- if(ob->action) {
+ if (ob->action) {
bActionChannel *achan= get_action_channel(ob->action, channame);
- if(achan) {
+ if (achan) {
conchan= get_constraint_channel(&achan->constraintChannels, oldname);
- if(conchan)
+ if (conchan)
BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
}
}
+}
+
+
+/* ------------- Constraint Sanity Testing ------------------- */
+
+/* checks validity of object pointers, and NULLs,
+ * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag
+ */
+static void test_constraints (Object *owner, const char substring[])
+{
+ bConstraint *curcon;
+ ListBase *conlist= NULL;
+ int type;
+
+ if (owner==NULL) return;
+
+ /* Check parents */
+ if (strlen (substring)) {
+ switch (owner->type) {
+ case OB_ARMATURE:
+ type = CONSTRAINT_OBTYPE_BONE;
+ break;
+ default:
+ type = CONSTRAINT_OBTYPE_OBJECT;
+ break;
+ }
+ }
+ else
+ type = CONSTRAINT_OBTYPE_OBJECT;
+
+ /* Get the constraint list for this object */
+ switch (type) {
+ case CONSTRAINT_OBTYPE_OBJECT:
+ conlist = &owner->constraints;
+ break;
+ case CONSTRAINT_OBTYPE_BONE:
+ {
+ Bone *bone;
+ bPoseChannel *chan;
+
+ bone = get_named_bone( ((bArmature *)owner->data ), substring );
+ chan = get_pose_channel(owner->pose, substring);
+ if (bone && chan) {
+ conlist = &chan->constraints;
+ }
+ }
+ break;
+ }
+
+ /* Check all constraints - is constraint valid? */
+ if (conlist) {
+ for (curcon = conlist->first; curcon; curcon=curcon->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* clear disabled-flag first */
+ curcon->flag &= ~CONSTRAINT_DISABLE;
+
+ /* Check specialised data (settings) for constraints that need this */
+ if (curcon->type == CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = curcon->data;
+
+ /* is there are valid script? */
+ if (data->text == NULL) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (BPY_is_pyconstraint(data->text)==0) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else {
+ /* does the constraint require target input... also validates targets */
+ BPY_pyconstraint_update(owner, curcon);
+ }
+
+ /* targets have already been checked for this */
+ continue;
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data = curcon->data;
+
+ /* bad: we need a separate set of checks here as poletarget is
+ * optional... otherwise poletarget must exist too or else
+ * the constraint is deemed invalid
+ */
+ if (exist_object(data->tar) == 0) {
+ data->tar = NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (data->tar == owner) {
+ if (!get_named_bone(get_armature(owner), data->subtarget)) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ }
+
+ if (data->poletar) {
+ if (exist_object(data->poletar) == 0) {
+ data->poletar = NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (data->poletar == owner) {
+ if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ }
+ }
+
+ /* targets have already been checked for this */
+ continue;
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
+ bActionConstraint *data = curcon->data;
+
+ /* validate action */
+ if (data->act == NULL)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
+ bFollowPathConstraint *data = curcon->data;
+
+ /* don't allow track/up axes to be the same */
+ if (data->upflag==data->trackflag)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ if (data->upflag+3==data->trackflag)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
+ bTrackToConstraint *data = curcon->data;
+
+ /* don't allow track/up axes to be the same */
+ if (data->reserved2==data->reserved1)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ if (data->reserved2+3==data->reserved1)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
+ bLockTrackConstraint *data = curcon->data;
+
+ if (data->lockflag==data->trackflag)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ if (data->lockflag+3==data->trackflag)
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+
+ /* Check targets for constraints */
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(curcon, &targets);
+
+ /* disable and clear constraints targets that are incorrect */
+ for (ct= targets.first; ct; ct= ct->next) {
+ /* general validity checks (for those constraints that need this) */
+ if (exist_object(ct->tar) == 0) {
+ ct->tar = NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (ct->tar == owner) {
+ if (!get_named_bone(get_armature(owner), ct->subtarget)) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ }
+
+ /* target checks for specific constraints */
+ if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
+ if (ct->tar) {
+ if (ct->tar->type != OB_CURVE) {
+ ct->tar= NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else {
+ Curve *cu= ct->tar->data;
+
+ /* auto-set 'Path' setting on curve so this works */
+ cu->flag |= CU_PATH;
+ }
+ }
+ }
+ }
+
+ /* free any temporary targets */
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(curcon, &targets, 0);
+ }
+ }
+ }
+}
+
+static void test_bonelist_constraints (Object *owner, ListBase *list)
+{
+ Bone *bone;
+
+ for (bone = list->first; bone; bone=bone->next) {
+ test_constraints(owner, bone->name);
+ test_bonelist_constraints (owner, &bone->childbase);
+ }
+}
+
+void object_test_constraints (Object *owner)
+{
+ test_constraints(owner, "");
+
+ if (owner->type==OB_ARMATURE) {
+ bArmature *arm= get_armature(owner);
+
+ if (arm)
+ test_bonelist_constraints (owner, &arm->bonebase);
+ }
+}
+
+/* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
+/* ------------- PyConstraints ------------------ */
+
+/* this callback sets the text-file to be used for selected menu item */
+void validate_pyconstraint_cb (void *arg1, void *arg2)
+{
+ bPythonConstraint *data = arg1;
+ Text *text= NULL;
+ int index = *((int *)arg2);
+ int i;
+
+ /* exception for no script */
+ if (index) {
+ /* innovative use of a for...loop to search */
+ for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
+ }
+ data->text = text;
+}
+
+/* this returns a string for the list of usable pyconstraint script names */
+char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
+{
+ DynStr *pupds= BLI_dynstr_new();
+ Text *text;
+ char *str;
+ char buf[64];
+ int i;
+
+ /* add title first */
+ sprintf(buf, "Scripts: %%t|[None]%%x0|");
+ BLI_dynstr_append(pupds, buf);
+
+ /* init active-index first */
+ if (con_text == NULL)
+ *pyconindex= 0;
+
+ /* loop through markers, adding them */
+ for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
+ /* this is important to ensure that right script is shown as active */
+ if (text == con_text) *pyconindex = i;
+
+ /* only include valid pyconstraint scripts */
+ if (BPY_is_pyconstraint(text)) {
+ BLI_dynstr_append(pupds, text->id.name+2);
+
+ sprintf(buf, "%%x%d", i);
+ BLI_dynstr_append(pupds, buf);
+
+ if (text->id.next)
+ BLI_dynstr_append(pupds, "|");
+ }
+ }
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
+/* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
+void update_pyconstraint_cb (void *arg1, void *arg2)
+{
+ Object *owner= (Object *)arg1;
+ bConstraint *con= (bConstraint *)arg2;
+
+ if (owner && con)
+ BPY_pyconstraint_update(owner, con);
+}
+
+/* ------------- Child-Of Constraint ------------------ */
+
+/* ChildOf Constraint - set inverse callback */
+void childof_const_setinv (void *conv, void *unused)
+{
+ bConstraint *con= (bConstraint *)conv;
+ bChildOfConstraint *data= (bChildOfConstraint *)con->data;
+ Object *ob= OBACT;
+ bPoseChannel *pchan= NULL;
+
+ /* try to find a pose channel */
+ if (ob && ob->pose)
+ pchan= get_active_posechannel(ob);
+ /* calculate/set inverse matrix */
+ if (pchan) {
+ float pmat[4][4], cinf;
+ float imat[4][4], tmat[4][4];
+
+ /* make copy of pchan's original pose-mat (for use later) */
+ Mat4CpyMat4(pmat, pchan->pose_mat);
+
+ /* disable constraint for pose to be solved without it */
+ cinf= con->enforce;
+ con->enforce= 0.0f;
+
+ /* solve pose without constraint */
+ where_is_pose(ob);
+
+ /* determine effect of constraint by removing the newly calculated
+ * pchan->pose_mat from the original pchan->pose_mat, thus determining
+ * the effect of the constraint
+ */
+ Mat4Invert(imat, pchan->pose_mat);
+ Mat4MulMat4(tmat, imat, pmat);
+ Mat4Invert(data->invmat, tmat);
+
+ /* recalculate pose with new inv-mat */
+ con->enforce= cinf;
+ where_is_pose(ob);
+ }
+ else if (ob) {
+ /* use what_does_parent to find inverse - just like for normal parenting.
+ * NOTE: what_does_parent uses a static workob defined in object.c
+ */
+ what_does_parent(ob);
+ Mat4Invert(data->invmat, workob.obmat);
+ }
+ else
+ Mat4One(data->invmat);
}
+/* ChildOf Constraint - clear inverse callback */
+void childof_const_clearinv (void *conv, void *unused)
+{
+ bConstraint *con= (bConstraint *)conv;
+ bChildOfConstraint *data= (bChildOfConstraint *)con->data;
+
+ /* simply clear the matrix */
+ Mat4One(data->invmat);
+}
diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c
index e4cd813f9cd..aef4d16e5e1 100644
--- a/source/blender/src/editcurve.c
+++ b/source/blender/src/editcurve.c
@@ -50,6 +50,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_dynstr.h"
+#include "BLI_rand.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
@@ -111,6 +112,66 @@ float nurbcircle[8][2]= {
{0.0, 1.0}, { 1.0, 1.0}, { 1.0, 0.0}, { 1.0, -1.0}
};
+/* ******************* SELECTION FUNCTIONS ********************* */
+
+/* returns 1 in case (de)selection was successful */
+static short select_beztriple(BezTriple *bezt, short selstatus, short flag, short hidden)
+{
+ if(bezt) {
+ if((bezt->hide==0) || (hidden==1)) {
+ if(selstatus==1) { /* selects */
+ bezt->f1 |= flag;
+ bezt->f2 |= flag;
+ bezt->f3 |= flag;
+ return 1;
+ }
+ else { /* deselects */
+ bezt->f1 &= ~flag;
+ bezt->f2 &= ~flag;
+ bezt->f3 &= ~flag;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* returns 1 in case (de)selection was successful */
+static short select_bpoint(BPoint *bp, short selstatus, short flag, short hidden)
+{
+ if(bp) {
+ if((bp->hide==0) || (hidden==1)) {
+ if(selstatus==1) {
+ bp->f1 |= flag;
+ return 1;
+ }
+ else {
+ bp->f1 &= ~flag;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static short swap_selection_beztriple(BezTriple *bezt)
+{
+ if(bezt->f2 & SELECT)
+ return select_beztriple(bezt, DESELECT, 1, VISIBLE);
+ else
+ return select_beztriple(bezt, SELECT, 1, VISIBLE);
+}
+
+static short swap_selection_bpoint(BPoint *bp)
+{
+ if(bp->f1 & SELECT)
+ return select_bpoint(bp, DESELECT, 1, VISIBLE);
+ else
+ return select_bpoint(bp, SELECT, 1, VISIBLE);
+}
+
short isNurbsel(Nurb *nu)
{
BezTriple *bezt;
@@ -121,7 +182,7 @@ short isNurbsel(Nurb *nu)
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if( (bezt->f1 & 1) || (bezt->f2 & 1) || (bezt->f3 & 1) ) return 1;
+ if( (bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT) ) return 1;
bezt++;
}
}
@@ -129,7 +190,7 @@ short isNurbsel(Nurb *nu)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if( (bp->f1 & 1) ) return 1;
+ if( (bp->f1 & SELECT) ) return 1;
bp++;
}
}
@@ -146,7 +207,7 @@ int isNurbsel_count(Nurb *nu)
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if( (bezt->f1 & 1) || (bezt->f2 & 1) || (bezt->f3 & 1) ) sel++;
+ if (BEZSELECTED_HIDDENHANDLES(bezt)) sel++;
bezt++;
}
}
@@ -154,13 +215,14 @@ int isNurbsel_count(Nurb *nu)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if( (bp->f1 & 1) ) sel++;
+ if( (bp->f1 & SELECT) ) sel++;
bp++;
}
}
return sel;
}
+/* ******************* PRINTS ********************* */
void printknots()
{
@@ -703,8 +765,8 @@ short extrudeflagNurb(int flag)
nu->bp= newbp;
a= nu->pntsu;
while(a--) {
- bp->f1 |= flag;
- newbp->f1 &= ~flag;
+ select_bpoint(bp, SELECT, flag, HIDDEN);
+ select_bpoint(newbp, DESELECT, flag, HIDDEN);
bp++;
newbp++;
}
@@ -723,7 +785,7 @@ short extrudeflagNurb(int flag)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- bp->f1 &= ~flag;
+ select_bpoint(bp, DESELECT, flag, HIDDEN);
bp++;
}
@@ -747,7 +809,7 @@ short extrudeflagNurb(int flag)
a= nu->pntsu;
while(a--) {
- bp->f1 |= flag;
+ select_bpoint(bp, SELECT, flag, HIDDEN);
bp++;
}
@@ -793,7 +855,6 @@ short extrudeflagNurb(int flag)
return ok;
}
-
void adduplicateflagNurb(short flag)
{
Nurb *nu, *newnu;
@@ -810,9 +871,7 @@ void adduplicateflagNurb(short flag)
enda= -1;
starta= a;
while( (bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag) ) {
- bezt->f1 &= ~flag;
- bezt->f2 &= ~flag;
- bezt->f3 &= ~flag;
+ select_beztriple(bezt, DESELECT, flag, HIDDEN);
enda=a;
if(a>=nu->pntsu-1) break;
a++;
@@ -831,9 +890,7 @@ void adduplicateflagNurb(short flag)
b= newnu->pntsu;
bezt1= newnu->bezt;
while(b--) {
- bezt1->f1 |= flag;
- bezt1->f2 |= flag;
- bezt1->f3 |= flag;
+ select_beztriple(bezt1, SELECT, flag, HIDDEN);
bezt1++;
}
@@ -850,7 +907,7 @@ void adduplicateflagNurb(short flag)
enda= -1;
starta= a;
while(bp->f1 & flag) {
- bp->f1 &= ~flag;
+ select_bpoint(bp, DESELECT, flag, HIDDEN);
enda= a;
if(a>=nu->pntsu-1) break;
a++;
@@ -868,7 +925,7 @@ void adduplicateflagNurb(short flag)
b= newnu->pntsu;
bp1= newnu->bp;
while(b--) {
- bp1->f1 |= flag;
+ select_bpoint(bp1, SELECT, flag, HIDDEN);
bp1++;
}
@@ -931,7 +988,7 @@ void adduplicateflagNurb(short flag)
for(b=0; b<nu->pntsu; b++, bp1++) {
if(bp1->f1 & flag) {
memcpy(bp, bp1, sizeof(BPoint));
- bp1->f1 &= ~flag;
+ select_bpoint(bp1, DESELECT, flag, HIDDEN);
bp++;
}
}
@@ -1024,89 +1081,331 @@ void switchdirection_knots(float *base, int tot)
MEM_freeN(tempf);
}
-/* **************** EDIT ************************ */
+void setweightNurb(void)
+{
+ static float weight= 1.0f;
+ extern ListBase editNurb;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if(nu->bezt) {
+ for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT)
+ bezt->weight= weight;
+ }
+ }
+ else if(nu->bp) {
+ for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+ if(bp->f1 & SELECT)
+ bp->weight= weight;
+ }
+ }
+ }
+ }
+ BIF_undo_push("Set Curve Weight");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+}
-void deselectall_nurb()
+void setradiusNurb( void )
{
+ static float radius= 1.0f;
+ extern ListBase editNurb;
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- int a, b;
+ int a;
+
+ if(fbutton(&radius, 0.0001f, 10.0f, 10, 10, "Set Radius")) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if(nu->bezt) {
+ for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT)
+ bezt->radius= radius;
+ }
+ }
+ else if(nu->bp) {
+ for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+ if(bp->f1 & SELECT)
+ bp->radius= radius;
+ }
+ }
+ }
+ }
+ BIF_undo_push("Set Curve Radius");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSALL, 0);
+ allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
+}
- if(!G.vd || !(G.obedit->lay & G.vd->lay))
- return;
- a= 0;
+/* TODO, make smoothing distance based */
+void smoothradiusNurb( void )
+{
+ extern ListBase editNurb;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ /* use for smoothing */
+ int last_sel;
+ int start_sel, end_sel; /* selection indicies, inclusive */
+ float start_rad, end_rad, fac, range;
+
for(nu= editNurb.first; nu; nu= nu->next) {
- if((nu->type & 7)==CU_BEZIER) {
- b= nu->pntsu;
- bezt= nu->bezt;
- while(b--) {
- if(bezt->hide==0) {
- if(bezt->f1 & 1) {
- a=1;
+ if(nu->bezt) {
+
+ for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = end_sel = -1;
+ for(bezt=nu->bezt+last_sel, a=last_sel; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT) {
+ start_sel = a;
break;
}
- if(bezt->f2 & 1) {
- a=1;
+ }
+ /* incase there are no other selected verts */
+ end_sel = start_sel;
+ for(bezt=nu->bezt+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bezt++) {
+ if((bezt->f2 & SELECT)==0) {
break;
}
- if(bezt->f3 & 1) {
- a=1;
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ } else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = -1.0;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel>0) start_rad = (nu->bezt+start_sel-1)->radius;
+ if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bezt+start_sel+1)->radius;
+
+ if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bezt+start_sel)->radius = (start_rad + end_rad)/2;
+ else if (start_rad >= 0.0) (nu->bezt+start_sel)->radius = start_rad;
+ else if (end_rad >= 0.0) (nu->bezt+start_sel)->radius = end_rad;
+ } else {
+ /* if endpoints selected, then use them */
+ if (start_sel==0) {
+ start_rad = (nu->bezt+start_sel)->radius;
+ start_sel++; /* we dont want to edit the selected endpoint */
+ } else {
+ start_rad = (nu->bezt+start_sel-1)->radius;
+ }
+ if (end_sel==nu->pntsu-1) {
+ end_rad = (nu->bezt+end_sel)->radius;
+ end_sel--; /* we dont want to edit the selected endpoint */
+ } else {
+ end_rad = (nu->bezt+end_sel+1)->radius;
+ }
+
+ /* Now Blend between the points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for(bezt=nu->bezt+start_sel, a=start_sel; a<=end_sel; a++, bezt++) {
+ fac = (float)(1+a-start_sel) / range;
+ bezt->radius = start_rad*(1.0-fac) + end_rad*fac;
+ }
+ }
+ }
+ }
+ } else if (nu->bp) {
+ /* Same as above, keep these the same! */
+ for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = end_sel = -1;
+ for(bp=nu->bp+last_sel, a=last_sel; a<nu->pntsu; a++, bp++) {
+ if(bp->f1 & SELECT) {
+ start_sel = a;
break;
}
}
- bezt++;
+ /* incase there are no other selected verts */
+ end_sel = start_sel;
+ for(bp=nu->bp+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bp++) {
+ if((bp->f1 & SELECT)==0) {
+ break;
+ }
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ } else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = -1.0;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel>0) start_rad = (nu->bp+start_sel-1)->radius;
+ if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bp+start_sel+1)->radius;
+
+ if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bp+start_sel)->radius = (start_rad + end_rad)/2;
+ else if (start_rad >= 0.0) (nu->bp+start_sel)->radius = start_rad;
+ else if (end_rad >= 0.0) (nu->bp+start_sel)->radius = end_rad;
+ } else {
+ /* if endpoints selected, then use them */
+ if (start_sel==0) {
+ start_rad = (nu->bp+start_sel)->radius;
+ start_sel++; /* we dont want to edit the selected endpoint */
+ } else {
+ start_rad = (nu->bp+start_sel-1)->radius;
+ }
+ if (end_sel==nu->pntsu-1) {
+ end_rad = (nu->bp+end_sel)->radius;
+ end_sel--; /* we dont want to edit the selected endpoint */
+ } else {
+ end_rad = (nu->bp+end_sel+1)->radius;
+ }
+
+ /* Now Blend between the points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for(bp=nu->bp+start_sel, a=start_sel; a<=end_sel; a++, bp++) {
+ fac = (float)(1+a-start_sel) / range;
+ bp->radius = start_rad*(1.0-fac) + end_rad*fac;
+ }
+ }
+ }
+ }
+ }
+ }
+ BIF_undo_push("Smooth Curve Radius");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSALL, 0);
+ allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
+}
+
+
+
+/* **************** EDIT ************************ */
+
+/* next == 1 -> select next */
+/* next == -1 -> select previous */
+/* cont == 1 -> select continuously */
+/* selstatus, inverts behaviour */
+static void select_adjacent_cp(short next, short cont, short selstatus)
+{
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+ short lastsel= 0, sel=0;
+
+ if(next==0) return;
+
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ lastsel=0;
+ if((nu->type & 7)==CU_BEZIER) {
+ a= nu->pntsu;
+ bezt= nu->bezt;
+ if(next < 0) bezt= (nu->bezt + (a-1));
+ while(a--) {
+ if(a-abs(next) < 0) break;
+ sel= 0;
+ if((lastsel==0) && (bezt->hide==0) && ((bezt->f2 & SELECT) || (selstatus==0))) {
+ bezt+=next;
+ if(!(bezt->f2 & SELECT) || (selstatus==0)) {
+ sel= select_beztriple(bezt, selstatus, 1, VISIBLE);
+ if((sel==1) && (cont==0)) lastsel= 1;
+ }
+ }
+ else {
+ bezt+=next;
+ lastsel= 0;
+ }
+ /* move around in zigzag way so that we go through each */
+ bezt-=(next-next/abs(next));
}
}
else {
- b= nu->pntsu*nu->pntsv;
+ a= nu->pntsu*nu->pntsv;
bp= nu->bp;
- while(b--) {
- if(bp->hide==0) {
- if(bp->f1 & 1) {
- a=1;
- break;
- }
+ if(next < 0) bp= (nu->bp + (a-1));
+ while(a--) {
+ if(a-abs(next) < 0) break;
+ sel=0;
+ if((lastsel==0) && (bp->hide==0) && ((bp->f1 & SELECT) || (selstatus==0))) {
+ bp+=next;
+ if(!(bp->f1 & SELECT) || (selstatus==0)) {
+ sel= select_bpoint(bp, selstatus, 1, VISIBLE);
+ if((sel==1) && (cont==0)) lastsel= 1;
+ }
}
- bp++;
+ else {
+ bp+=next;
+ lastsel= 0;
+ }
+ /* move around in zigzag way so that we go through each */
+ bp-=(next-next/abs(next));
}
}
- if(a) break;
}
+}
+
+static short nurb_has_selected_cps()
+{
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
for(nu= editNurb.first; nu; nu= nu->next) {
- if((nu->type & 7)==1) {
- b= nu->pntsu;
+ if((nu->type & 7)==CU_BEZIER) {
+ a= nu->pntsu;
bezt= nu->bezt;
- while(b--) {
+ while(a--) {
if(bezt->hide==0) {
- if(a) {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
- }
- else {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
- }
+ if((bezt->f1 & SELECT)
+ || (bezt->f2 & SELECT)
+ || (bezt->f3 & SELECT)) return 1;
}
bezt++;
}
}
else {
- b= nu->pntsu*nu->pntsv;
+ a= nu->pntsu*nu->pntsv;
bp= nu->bp;
- while(b--) {
- if(bp->hide==0) {
- if(a) bp->f1 &= ~ 1;
- else bp->f1 |= 1;
- }
+ while(a--) {
+ if((bp->hide==0) && (bp->f1 & SELECT)) return 1;
bp++;
}
}
}
+
+ return 0;
+}
+
+void deselectall_nurb()
+{
+ if(!G.vd || !(G.obedit->lay & G.vd->lay))
+ return;
+
+ if(nurb_has_selected_cps()) { /* deselect all */
+ selectend_nurb(FIRST, 0, DESELECT); /* set first control points as unselected */
+ select_adjacent_cp(1, 1, DESELECT); /* cascade selection */
+ }
+ else { /* select all */
+ selectend_nurb(FIRST, 0, SELECT); /* set first control points as selected */
+ select_adjacent_cp(1, 1, SELECT); /* cascade selection */
+ }
+
countall();
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Deselect all");
@@ -1129,10 +1428,8 @@ void hideNurb(int swap)
a= nu->pntsu;
sel= 0;
while(a--) {
- if(BEZSELECTED(bezt)) {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
+ if(BEZSELECTED_HIDDENHANDLES(bezt)) {
+ select_beztriple(bezt, DESELECT, 1, HIDDEN);
bezt->hide= 1;
}
if(bezt->hide) sel++;
@@ -1145,12 +1442,12 @@ void hideNurb(int swap)
a= nu->pntsu*nu->pntsv;
sel= 0;
while(a--) {
- if(swap==0 && (bp->f1 & 1)) {
- bp->f1 &= ~1;
+ if(swap==0 && (bp->f1 & SELECT)) {
+ select_bpoint(bp, DESELECT, 1, HIDDEN);
bp->hide= 1;
}
- else if(swap && (bp->f1 & 1)==0) {
- bp->f1 &= ~1;
+ else if(swap && (bp->f1 & SELECT)==0) {
+ select_bpoint(bp, DESELECT, 1, HIDDEN);
bp->hide= 1;
}
if(bp->hide) sel++;
@@ -1182,9 +1479,7 @@ void revealNurb()
a= nu->pntsu;
while(a--) {
if(bezt->hide) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ select_beztriple(bezt, SELECT, 1, HIDDEN);
bezt->hide= 0;
}
bezt++;
@@ -1195,7 +1490,7 @@ void revealNurb()
a= nu->pntsu*nu->pntsv;
while(a--) {
if(bp->hide) {
- bp->f1 |= 1;
+ select_bpoint(bp, SELECT, 1, HIDDEN);
bp->hide= 0;
}
bp++;
@@ -1225,12 +1520,11 @@ void selectswapNurb()
a= nu->pntsu;
while(a--) {
if(bezt->hide==0) {
- if(bezt->f1 & 1) bezt->f1 &= ~1;
- else bezt->f1 |= 1;
- if(bezt->f2 & 1) bezt->f2 &= ~1;
- else bezt->f2 |= 1;
- if(bezt->f3 & 1) bezt->f3 &= ~1;
- else bezt->f3 |= 1;
+ bezt->f2 ^= SELECT; /* always do the center point */
+ if ((G.f & G_HIDDENHANDLES)==0) {
+ bezt->f1 ^= SELECT;
+ bezt->f3 ^= SELECT;
+ }
}
bezt++;
}
@@ -1239,10 +1533,7 @@ void selectswapNurb()
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if(bp->hide==0) {
- if(bp->f1 & 1) bp->f1 &= ~1;
- else bp->f1 |= 1;
- }
+ swap_selection_bpoint(bp);
bp++;
}
}
@@ -1292,7 +1583,7 @@ void subdivideNurb()
bezt= prevbezt+1;
}
while(a--) {
- if( BEZSELECTED(prevbezt) && BEZSELECTED(bezt) ) amount++;
+ if( BEZSELECTED_HIDDENHANDLES(prevbezt) && BEZSELECTED_HIDDENHANDLES(bezt) ) amount++;
prevbezt= bezt;
bezt++;
}
@@ -1316,7 +1607,7 @@ void subdivideNurb()
memcpy(beztn, prevbezt, sizeof(BezTriple));
beztn++;
- if( BEZSELECTED(prevbezt) && BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(prevbezt) && BEZSELECTED_HIDDENHANDLES(bezt) ) {
memcpy(beztn, bezt, sizeof(BezTriple));
/* midpoint subdividing */
@@ -1375,7 +1666,7 @@ void subdivideNurb()
bp= prevbp+1;
}
while(a--) {
- if( (bp->f1 & 1) && (prevbp->f1 & 1) ) amount++;
+ if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) amount++;
prevbp= bp;
bp++;
}
@@ -1400,7 +1691,7 @@ void subdivideNurb()
memcpy(bpn, prevbp, sizeof(BPoint));
bpn++;
- if( (bp->f1 & 1) && (prevbp->f1 & 1) ) {
+ if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) {
// printf("*** subdivideNurb: insert 'linear' point\n");
memcpy(bpn, bp, sizeof(BPoint));
bpn->vec[0]= (prevbp->vec[0]+bp->vec[0])/2.0;
@@ -1476,7 +1767,7 @@ void subdivideNurb()
bp= nu->bp;
for(a=0; a<nu->pntsv; a++) {
for(b=0; b<nu->pntsu; b++) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
usel[b]++;
vsel[a]++;
sel++;
@@ -1708,7 +1999,7 @@ static void findselectedNurbvert(Nurb **nu, BezTriple **bezt, BPoint **bp)
bezt1= nu1->bezt;
a= nu1->pntsu;
while(a--) {
- if( (bezt1->f1 & 1) || (bezt1->f2 & 1) || (bezt1->f3 & 1) ) {
+ if( (bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT) ) {
if(*nu!=0 && *nu!= nu1) {
*nu= 0;
*bp= 0;
@@ -1946,7 +2237,7 @@ int is_u_selected(Nurb *nu, int u)
/* what about resolu == 2? */
bp= nu->bp+u;
for(v=0; v<nu->pntsv-1; v++, bp+=nu->pntsu) {
- if(v) if(bp->f1 & 1) return 1;
+ if(v) if(bp->f1 & SELECT) return 1;
}
return 0;
@@ -2127,7 +2418,7 @@ void merge_2_nurb(Nurb *nu1, Nurb *nu2)
for(u=0; u<nu1->pntsu; u++, bp++) {
if(u<origu) {
*bp= *bp1; bp1++;
- bp->f1 &= ~SELECT;
+ select_bpoint(bp, SELECT, 1, HIDDEN);
}
else {
*bp= *bp2; bp2++;
@@ -2225,7 +2516,7 @@ void addsegment_nurb()
if(isNurbsel_count(nu)==1) {
/* only 1 selected, not first or last, a little complex, but intuitive */
if(nu->pntsv==1) {
- if( (nu->bp->f1 & 1) || ((nu->bp+nu->pntsu-1)->f1 & 1));
+ if( (nu->bp->f1 & SELECT) || ((nu->bp+nu->pntsu-1)->f1 & SELECT));
else break;
}
}
@@ -2243,23 +2534,23 @@ void addsegment_nurb()
if( (nu->type & 7)==CU_BEZIER ) {
bezt= nu->bezt;
if(nu1==0) {
- if( BEZSELECTED(bezt) ) nu1= nu;
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) nu1= nu;
else {
bezt= bezt+(nu->pntsu-1);
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
nu1= nu;
switchdirectionNurb(nu);
}
}
}
else if(nu2==0) {
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
nu2= nu;
switchdirectionNurb(nu);
}
else {
bezt= bezt+(nu->pntsu-1);
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
nu2= nu;
}
}
@@ -2269,23 +2560,23 @@ void addsegment_nurb()
else if(nu->pntsv==1) {
bp= nu->bp;
if(nu1==0) {
- if( bp->f1 & 1) nu1= nu;
+ if( bp->f1 & SELECT) nu1= nu;
else {
bp= bp+(nu->pntsu-1);
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
nu1= nu;
switchdirectionNurb(nu);
}
}
}
else if(nu2==0) {
- if( bp->f1 & 1) {
+ if( bp->f1 & SELECT ) {
nu2= nu;
switchdirectionNurb(nu);
}
else {
bp= bp+(nu->pntsu-1);
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
nu2= nu;
}
}
@@ -2377,17 +2668,13 @@ void mouse_nurb()
if(bezt) {
- if(hand==1) {
- bezt->f1|= 1;
- bezt->f2|= 1;
- bezt->f3|= 1;
- }
- else if(hand==0) bezt->f1|= 1;
- else bezt->f3|= 1;
+ if(hand==1) select_beztriple(bezt, SELECT, 1, HIDDEN);
+ else if(hand==0) bezt->f1|= SELECT;
+ else bezt->f3|= SELECT;
}
else {
lastselbp= bp;
- bp->f1 |= 1;
+ select_bpoint(bp, SELECT, 1, HIDDEN);
}
allqueue(REDRAWVIEW3D, 0);
@@ -2395,38 +2682,18 @@ void mouse_nurb()
else {
if(bezt) {
if(hand==1) {
- if(bezt->f2 & 1) {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
- }
- else {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
- }
- }
- else if(hand==0) {
- if(bezt->f1 & 1) {
- bezt->f1 &= ~1;
- }
- else {
- bezt->f1 |= 1;
- }
- }
- else {
- if(bezt->f3 & 1) {
- bezt->f3 &= ~1;
- }
- else {
- bezt->f3 |= 1;
- }
+ if(bezt->f2 & SELECT) select_beztriple(bezt, DESELECT, 1, HIDDEN);
+ else select_beztriple(bezt, SELECT, 1, HIDDEN);
+ } else if(hand==0) {
+ bezt->f1 ^= SELECT;
+ } else {
+ bezt->f3 ^= SELECT;
}
}
else {
- if(bp->f1 & 1) bp->f1 &= ~1;
+ if(bp->f1 & SELECT) select_bpoint(bp, DESELECT, 1, HIDDEN);
else {
- bp->f1 |= 1;
+ select_bpoint(bp, SELECT, 1, HIDDEN);
lastselbp= bp;
}
}
@@ -2447,6 +2714,10 @@ void mouse_nurb()
}
+/* from what I can gather, the mode==0 magic number spins and bridges the nurbs based on the
+ * orientation of the global 3d view (yuck yuck!) mode==1 does the same, but doesn't bridge up
+ * up the new geometry, mode==2 now does the same as 0, but aligned to world axes, not the view.
+*/
static void spin_nurb(float *dvec, short mode)
{
Nurb *nu;
@@ -2458,7 +2729,8 @@ static void spin_nurb(float *dvec, short mode)
if(G.vd==0 || G.obedit==0 || G.obedit->type!=OB_SURF) return;
if( (G.vd->lay & G.obedit->lay)==0 ) return;
- Mat3CpyMat4(persmat, G.vd->viewmat);
+ if (mode != 2) Mat3CpyMat4(persmat, G.vd->viewmat);
+ else Mat3One(persmat);
Mat3Inv(persinv, persmat);
/* imat and center and size */
@@ -2470,7 +2742,7 @@ static void spin_nurb(float *dvec, short mode)
VecSubf(cent, cent, G.obedit->obmat[3]);
Mat3MulVecfl(imat,cent);
- if(dvec) {
+ if(dvec || mode==2) {
n[0]=n[1]= 0.0;
n[2]= 1.0;
} else {
@@ -2511,7 +2783,7 @@ static void spin_nurb(float *dvec, short mode)
ok= 1;
for(a=0;a<7;a++) {
- if(mode==0) ok= extrudeflagNurb(1);
+ if(mode==0 || mode==2) ok= extrudeflagNurb(1);
else adduplicateflagNurb(1);
if(ok==0) {
error("Can't spin");
@@ -2519,7 +2791,7 @@ static void spin_nurb(float *dvec, short mode)
}
rotateflagNurb(1,cent,rotmat);
- if(mode==0) {
+ if(mode==0 || mode==2) {
if( (a & 1)==0 ) {
rotateflagNurb(1,cent,scalemat1);
weightflagNurb(1, 0.25*sqrt(2.0), 1);
@@ -2578,7 +2850,7 @@ void addvert_Nurb(int mode)
(BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb");
memcpy(newbezt+1, bezt, nu->pntsu*sizeof(BezTriple));
*newbezt= *bezt;
- newbezt->f1= newbezt->f2= newbezt->f3= 1;
+ newbezt->f1= newbezt->f2= newbezt->f3= SELECT;
if(newbezt->h1 >= 0) newbezt->h2= newbezt->h1;
else newbezt->h2= newbezt->h1= HD_ALIGN; /* does this ever happen? */
VECCOPY(temp, bezt->vec[1]);
@@ -2596,7 +2868,7 @@ void addvert_Nurb(int mode)
MEM_freeN(nu->bezt);
nu->bezt= newbezt;
newbezt+= nu->pntsu;
- newbezt->f1= newbezt->f2= newbezt->f3= 1;
+ newbezt->f1= newbezt->f2= newbezt->f3= SELECT;
if(newbezt->h1 >= 0) newbezt->h2= newbezt->h1;
else newbezt->h2= newbezt->h1= HD_ALIGN; /* does this ever happen? */
bezt= nu->bezt+nu->pntsu-1;
@@ -2635,6 +2907,7 @@ void addvert_Nurb(int mode)
newbp->f1= 1;
MEM_freeN(nu->bp);
nu->bp= newbp;
+ bp= newbp + 1;
}
else if(bp== (nu->bp+nu->pntsu-1)) { /* last */
bp->f1= 0;
@@ -2646,15 +2919,16 @@ void addvert_Nurb(int mode)
nu->bp= newbp;
newbp+= nu->pntsu;
newbp->f1= 1;
+ bp= newbp - 1;
}
else bp= 0;
if(bp) {
nu->pntsu++;
-
+
if(nu->resolu<3) nu->resolu++;
makeknots(nu, 1, nu->flagu>>1);
-
+
if(mode=='e') {
VECCOPY(newbp->vec, bp->vec);
}
@@ -2704,10 +2978,7 @@ void extrude_nurb()
}
if(nu) {
addvert_Nurb('e');
- }
- else {
-
-
+ } else {
ok= extrudeflagNurb(1); /* '1'= flag */
if(ok) {
@@ -2737,7 +3008,7 @@ void makecyclicNurb()
a= nu->pntsu;
bp= nu->bp;
while(a--) {
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
if(nu->flagu & CU_CYCLIC) nu->flagu--;
else nu->flagu++;
break;
@@ -2749,7 +3020,7 @@ void makecyclicNurb()
a= nu->pntsu;
bezt= nu->bezt;
while(a--) {
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
if(nu->flagu & CU_CYCLIC) nu->flagu--;
else nu->flagu++;
break;
@@ -2762,7 +3033,7 @@ void makecyclicNurb()
a= nu->pntsu;
bp= nu->bp;
while(a--) {
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
if(nu->flagu & CU_CYCLIC) nu->flagu--;
else {
nu->flagu++;
@@ -2790,7 +3061,7 @@ void makecyclicNurb()
bp= nu->bp;
while(a--) {
- if( bp->f1 & 1) {
+ if( bp->f1 & SELECT) {
if(cyclmode==1 && nu->pntsu>1) {
if(nu->flagu & CU_CYCLIC) nu->flagu--;
else {
@@ -2841,18 +3112,8 @@ void selectconnected_nurb()
a= nu->pntsu;
bezt= nu->bezt;
while(a--) {
- if(bezt->hide==0) {
- if(G.qual & LR_SHIFTKEY) {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
- }
- else {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
- }
- }
+ if(G.qual & LR_SHIFTKEY) select_beztriple(bezt, DESELECT, 1, VISIBLE);
+ else select_beztriple(bezt, SELECT, 1, VISIBLE);
bezt++;
}
}
@@ -2860,14 +3121,8 @@ void selectconnected_nurb()
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
while(a--) {
- if(bp->hide==0) {
- if(G.qual & LR_SHIFTKEY) {
- bp->f1 &= ~1;
- }
- else {
- bp->f1 |= 1;
- }
- }
+ if(G.qual & LR_SHIFTKEY) select_bpoint(bp, DESELECT, 1, VISIBLE);
+ else select_bpoint(bp, SELECT, 1, VISIBLE);
bp++;
}
}
@@ -2896,7 +3151,7 @@ void selectrow_nurb()
for(v=0; v<nu->pntsv; v++) {
for(u=0; u<nu->pntsu; u++, bp++) {
if(bp==lastselbp) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
ok= 1;
break;
}
@@ -2915,10 +3170,10 @@ void selectrow_nurb()
for(a=0; a<nu->pntsv; a++) {
for(b=0; b<nu->pntsu; b++, bp++) {
if(direction) {
- if(a==v) if(bp->hide==0) bp->f1 |= 1;
+ if(a==v) select_bpoint(bp, SELECT, 1, VISIBLE);
}
else {
- if(b==u) if(bp->hide==0) bp->f1 |= 1;
+ if(b==u) select_bpoint(bp, SELECT, 1, VISIBLE);
}
}
}
@@ -2931,56 +3186,58 @@ void selectrow_nurb()
}
-void selectends_nurb(int selFirst)
+/* (de)selects first or last of visible part of each Nurb depending on selFirst */
+/* selFirst: defines the end of which to select */
+/* doswap: defines if selection state of each first/last control point is swapped */
+/* selstatus: selection status in case doswap is false */
+void selectend_nurb(short selfirst, short doswap, short selstatus)
{
Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
+ short sel;
if(G.obedit==0) return;
for(nu= editNurb.first; nu; nu= nu->next) {
+ sel= 0;
if((nu->type & 7)==CU_BEZIER) {
a= nu->pntsu;
/* which point? */
- if (selFirst==0) /* select last */
+ if(selfirst==0) { /* select last */
bezt= (nu->bezt + (a-1));
- else /* select first */
+ }
+ else { /* select first */
bezt= nu->bezt;
+ }
- if (bezt->hide == 0) {
- /* check if anything is selected */
- if (bezt->f1 & 1 || bezt->f2 & 1 || bezt->f3 & 1) {
- /* deselct all handles */
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
- }
- else {
- /* just select all handles */
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
- }
+ while(a--) {
+ if(doswap) sel= swap_selection_beztriple(bezt);
+ else sel= select_beztriple(bezt, selstatus, 1, VISIBLE);
+
+ if(sel==1) break;
}
}
else {
- /* ummm... doesn't really make sense, but... */
a= nu->pntsu*nu->pntsv;
/* which point? */
- if (selFirst==0) /* select last */
+ if(selfirst==0) { /* select last */
bp= (nu->bp + (a-1));
- else /* select first */
+ }
+ else{ /* select first */
bp= nu->bp;
-
- if (bp->hide == 0) {
- if (bp->f1 & 1) /* deselect */
- bp->f1 &= ~1;
- else /* select */
- bp->f1 |= 1;
+ }
+
+ while(a--) {
+ if (bp->hide == 0) {
+ if(doswap) sel= swap_selection_bpoint(bp);
+ else sel= select_bpoint(bp, selstatus, 1, VISIBLE);
+
+ if(sel==1) break;
+ }
}
}
}
@@ -2992,60 +3249,9 @@ void selectends_nurb(int selFirst)
void select_next_nurb()
{
- Nurb *nu;
- BezTriple *bezt;
- int *selectFlags; /* array of ints defining selection status */
- int totCount=0, totSel=0, totChange=0;
- int i=0;
-
if(G.obedit==0) return;
- for(nu= editNurb.first; nu; nu= nu->next) {
- /* check what type of curve/nurb it is */
- if((nu->type & 7)==CU_BEZIER) {
- totCount= nu->pntsu;
- selectFlags= MEM_callocN(sizeof(int)*totCount, "selectlist");
-
- /* find out which beztriples are selected */
- for (i=0; i<totCount; i++) {
- bezt= (nu->bezt + i);
- selectFlags[i]= BEZSELECTED(bezt);
- if (selectFlags[i]) totSel++;
- }
-
- /* check if anything is selected at all */
- if (totSel==0) {
- MEM_freeN(selectFlags);
- continue;
- }
-
- /* find out which ones deserve an extra flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 1) {
- if (((i+1) < totCount) && (selectFlags[i+1] == 0)) {
- selectFlags[i+1]= 2;
- totChange++;
- }
- }
- }
-
- /* set select flags based on select flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 2) {
- bezt = (nu->bezt + i);
-
- if (bezt->hide == 0) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
- }
- }
- }
-
- /* free tempolary array */
- MEM_freeN(selectFlags);
- }
- }
+ select_adjacent_cp(1, 0, SELECT);
countall();
allqueue(REDRAWVIEW3D, 0);
@@ -3054,281 +3260,326 @@ void select_next_nurb()
void select_prev_nurb()
{
- Nurb *nu;
- BezTriple *bezt;
- int *selectFlags; /* array of ints defining selection status */
- int totCount=0, totSel=0, totChange=0;
- int i=0;
+ if(G.obedit==0) return;
+
+ select_adjacent_cp(-1, 0, SELECT);
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Select Previous");
+}
+void select_more_nurb()
+{
+ Nurb *nu;
+ BPoint *bp, *tempbp;
+ int a;
+ short sel= 0;
+ short *selbpoints;
+
if(G.obedit==0) return;
- for(nu= editNurb.first; nu; nu= nu->next) {
- /* check what type of curve/nurb it is */
- if((nu->type & 7)==CU_BEZIER) {
- totCount= nu->pntsu;
- selectFlags= MEM_callocN(sizeof(int)*totCount, "selectlist");
-
- /* find out which beztriples are selected */
- for (i=0; i<totCount; i++) {
- bezt= (nu->bezt + i);
- selectFlags[i]= BEZSELECTED(bezt);
- if (selectFlags[i]) totSel++;
- }
-
- /* check if anything is selected at all */
- if (totSel==0) {
- MEM_freeN(selectFlags);
- continue;
- }
-
- /* find out which ones deserve an extra flag */
- for (i= totCount-1; i>=0; i--) {
- if (selectFlags[i] == 1) {
- if (((i-1) >= 0) && (selectFlags[i-1] == 0)) {
- selectFlags[i-1]= 2;
- totChange++;
+ /* note that NURBS surface is a special case because we mimic */
+ /* the behaviour of "select more" of mesh tools. */
+ /* The algorithm is designed to work in planar cases so it */
+ /* may not be optimal always (example: end of NURBS sphere) */
+ if(G.obedit->type==OB_SURF) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ selbpoints= MEM_callocN(sizeof(short)*a-nu->pntsu, "selectlist");
+ while(a > 0) {
+ if((selbpoints[a]!=1) && (bp->hide==0) && (bp->f1 & SELECT)) {
+ /* upper control point */
+ if(a%nu->pntsu != 0) {
+ tempbp= bp-1;
+ if(!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, 1, VISIBLE);
+ }
+
+ /* left control point. select only if it is not selected already */
+ if(a-nu->pntsu > 0) {
+ sel= 0;
+ tempbp= bp+nu->pntsu;
+ if(!(tempbp->f1 & SELECT)) sel= select_bpoint(tempbp, SELECT, 1, VISIBLE);
+ /* make sure selected bpoint is discarded */
+ if(sel == 1) selbpoints[a-nu->pntsu]= 1;
}
- }
- }
-
- /* set select flags based on select flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 2) {
- bezt = (nu->bezt + i);
- if (bezt->hide == 0) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ /* right control point */
+ if(a+nu->pntsu < nu->pntsu*nu->pntsv) {
+ tempbp= bp-nu->pntsu;
+ if(!(tempbp->f1 & SELECT)) select_bpoint(tempbp, SELECT, 1, VISIBLE);
}
+
+ /* lower control point. skip next bp in case selection was made */
+ if(a%nu->pntsu != 1) {
+ sel= 0;
+ tempbp= bp+1;
+ if(!(tempbp->f1 & 1)) sel= select_bpoint(tempbp, SELECT, 1, VISIBLE);
+ if(sel) {
+ bp++;
+ a--;
+ }
+ }
}
+
+ bp++;
+ a--;
}
- /* free tempolary array */
- MEM_freeN(selectFlags);
+ MEM_freeN(selbpoints);
}
}
-
+ else {
+ select_adjacent_cp(1, 0, SELECT);
+ select_adjacent_cp(-1, 0, SELECT);
+ }
+
countall();
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select Previous");
+ BIF_undo_push("Select More");
}
-void select_more_nurb()
+/* basic method: deselect if control point doesn't have all neighbours selected */
+void select_less_nurb()
{
Nurb *nu;
- BezTriple *bezt;
BPoint *bp;
- int *selectFlags; /* array of ints defining selection status */
- int totCount=0, totSel=0, totChange=0, totU=0, totV=0;
- int i=0, n=0, x=0;
+ BezTriple *bezt;
+ int a;
+ short sel= 0, lastsel= 0;
+ short *selbpoints;
if(G.obedit==0) return;
- for(nu= editNurb.first; nu; nu= nu->next) {
- /* check what type of curve/nurb it is */
- if((nu->type & 7)==CU_BEZIER) {
- totCount= nu->pntsu;
- selectFlags= MEM_callocN(sizeof(int)*totCount, "selectlist");
-
- /* find out which beztriples are selected */
- for (i=0; i<totCount; i++) {
- bezt= (nu->bezt + i);
- selectFlags[i]= BEZSELECTED(bezt);
- if (selectFlags[i]) totSel++;
- }
-
- /* check if anything is selected at all */
- if (totSel==0) {
- MEM_freeN(selectFlags);
- continue;
- }
-
- /* find out which ones deserve an extra flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 1) {
- if ((totCount > (i+1)) && (selectFlags[i+1] == 0)) {
- selectFlags[i+1] = 2;
- totChange++;
+ if(G.obedit->type==OB_SURF) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ selbpoints= MEM_callocN(sizeof(short)*a, "selectlist");
+ while(a--) {
+ if((bp->hide==0) && (bp->f1 & SELECT)) {
+ sel= 0;
+
+ /* check if neighbours have been selected */
+ /* edges of surface are an exception */
+ if((a+1)%nu->pntsu==0) sel++;
+ else {
+ bp--;
+ if((selbpoints[a+1]==1) || ((bp->hide==0) && (bp->f1 & SELECT))) sel++;
+ bp++;
}
- }
- else {
- if ((totCount > (i+1)) && (selectFlags[i+1] == 1)) {
- selectFlags[i] = 2;
- totChange++;
+
+ if((a+1)%nu->pntsu==1) sel++;
+ else {
+ bp++;
+ if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
+ bp--;
}
- }
- }
-
- /* set select flags based on select flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 2) {
- bezt = (nu->bezt + i);
- if (bezt->hide == 0) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ if(a+1 > nu->pntsu*nu->pntsv-nu->pntsu) sel++;
+ else {
+ bp-=nu->pntsu;
+ if((selbpoints[a+nu->pntsu]==1) || ((bp->hide==0) && (bp->f1 & SELECT))) sel++;
+ bp+=nu->pntsu;
}
+
+ if(a < nu->pntsu) sel++;
+ else {
+ bp+=nu->pntsu;
+ if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
+ bp-=nu->pntsu;
+ }
+
+ if(sel!=4) {
+ select_bpoint(bp, DESELECT, 1, VISIBLE);
+ selbpoints[a]= 1;
+ }
}
+ else lastsel= 0;
+
+ bp++;
}
- /* free tempolary array */
- MEM_freeN(selectFlags);
+ MEM_freeN(selbpoints);
}
- else {
- totCount= nu->pntsu*nu->pntsv;
- totU= nu->pntsu;
- totV= nu->pntsv;
- selectFlags= MEM_callocN(sizeof(int)*totCount, "selectlist");
-
- /* find out which bpoints are selected */
- for (i=0; i<totCount; i++) {
- bp = (nu->bp + i);
- selectFlags[i]= (bp->f1 & 1);
- if (selectFlags[i]) totSel++;
- }
-
- /* check if anything selected */
- if (totSel==0) continue;
-
- /* find out which ones deserve an extra flag */
- /* FIXME: why the heck does this go wrong? */
- for (i=0; i<totV; i++) {
- /* search column */
- for (n=0; n<totU; n++) {
- x = ((i * totU) + n);
-
- if (selectFlags[i] == 1) {
- if ((totU > (n+1)) && (selectFlags[x+1] == 0))
- selectFlags[x+1] = 2;
- }
- else {
- if ((totU > (n+1)) && (selectFlags[x+1] == 1))
- selectFlags[i] = 2;
+ }
+ else {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ lastsel=0;
+ /* check what type of curve/nurb it is */
+ if((nu->type & 7)==CU_BEZIER) {
+ a= nu->pntsu;
+ bezt= nu->bezt;
+ while(a--) {
+ if((bezt->hide==0) && (bezt->f2 & SELECT)) {
+ if(lastsel==1) sel= 1;
+ else sel= 0;
+
+ /* check if neighbours have been selected */
+ /* first and last are exceptions */
+ if(a==nu->pntsu-1) sel++;
+ else {
+ bezt--;
+ if((bezt->hide==0) && (bezt->f2 & SELECT)) sel++;
+ bezt++;
+ }
+
+ if(a==0) sel++;
+ else {
+ bezt++;
+ if((bezt->hide==0) && (bezt->f2 & SELECT)) sel++;
+ bezt--;
+ }
+
+ if(sel!=2) {
+ select_beztriple(bezt, DESELECT, 1, VISIBLE);
+ lastsel= 1;
+ }
+ else lastsel= 0;
}
+ else lastsel= 0;
+
+ bezt++;
}
-
- /* search row */
- /*
- if (selectFlags[(i*totU)] == 1) {
- if ((totV > (i+1)) && (selectFlags[((i+1)*totU)] == 0))
- selectFlags[((i+1)*totU)] = 2;
- }
- else {
- if ((totV > (i+1)) && (selectFlags[((i+1)*totU)] == 1))
- selectFlags[(i*totU)] = 2;
- } */
}
-
- /* set select flags based on select flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 2) {
- bp = (nu->bp + i);
- if (bp->hide == 0) bp->f1 |= 1;
+ else {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ while(a--) {
+ if((lastsel==0) && (bp->hide==0) && (bp->f1 & SELECT)) {
+ if(lastsel!=0) sel= 1;
+ else sel= 0;
+
+ /* first and last are exceptions */
+ if(a==nu->pntsu*nu->pntsv-1) sel++;
+ else {
+ bp--;
+ if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
+ bp++;
+ }
+
+ if(a==0) sel++;
+ else {
+ bp++;
+ if((bp->hide==0) && (bp->f1 & SELECT)) sel++;
+ bp--;
+ }
+
+ if(sel!=2) {
+ select_bpoint(bp, DESELECT, 1, VISIBLE);
+ lastsel= 1;
+ }
+ else lastsel= 0;
+ }
+ else lastsel= 0;
+
+ bp++;
}
}
-
- /* free tempolary array */
- MEM_freeN(selectFlags);
}
}
countall();
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select More");
+ BIF_undo_push("Select Less");
}
-void select_less_nurb()
+/* this function could be moved elsewhere as it can be reused in other parts of the source needing randomized list */
+/* returns list containing -1 in indices that have been left out of the list. otherwise index contains reference */
+/* to next index. basically *list contains a linked list */
+static void generate_pickable_list(int *list, int size, int pickamount)
+{
+ int i, j, removable;
+
+ BLI_srand( BLI_rand() ); /* random seed */
+
+ /* generate list in form 0->1, 1->2, 2->3, ... i-2->i-1, i->0 */
+ for(i=0; i<size; i++) {
+ if(i == size-1) list[i]= 0;
+ else list[i]= i+1;
+ }
+
+ for(i=0; i<size-pickamount; i++) {
+ removable= floor(BLI_frand()*(size-1)+0.5); /* with rounding. frand returns [0,1] */
+
+ /* seek proper item as the one randomly selected might not be appropriate */
+ for(j=0; j<size; j++, removable++) {
+ if(list[removable] != -1) break;
+ if(removable == size-1) removable= -1;
+ }
+
+ /* pick unwanted item out of the list */
+ list[list[removable]]= -1; /* mark former last as invalid */
+
+ if(list[removable] == size-1) list[removable]= 0;
+ else list[removable]= list[removable]+1;
+ }
+}
+
+void select_random_nurb()
{
Nurb *nu;
- /* BPoint *bp; */
BezTriple *bezt;
- int *selectFlags; /* array of ints*/
- int totCount=0, totSel=0, totChange=0, i;
+ BPoint *bp;
+ static short randfac= 50;
+ int amounttoselect, amountofcps, a, i, k= 0;
+ int *itemstobeselected;
+
+ if(!G.obedit) return;
- if(G.obedit==0) return;
+ if(!button(&randfac,0, 100,"Percentage:")) return;
- for(nu= editNurb.first; nu; nu= nu->next) {
- /* check what type of curve/nurb it is */
- if((nu->type & 7)==CU_BEZIER) {
- totCount= nu->pntsu;
- totSel= 0;
- selectFlags= MEM_callocN(sizeof(int)*totCount, "selectlist");
-
- /* find out which beztriples are selected */
- for (i=0; i<totCount; i++) {
- bezt= (nu->bezt + i);
- selectFlags[i]= BEZSELECTED(bezt);
- if (selectFlags[i]) totSel++;
- }
-
- /* determine best course of action */
- if (totSel<=1) {
- /* not enough to select-less of */
- MEM_freeN(selectFlags);
- continue;
- }
- else if (totSel==totCount) {
- /* deselect first and last points */
- selectFlags[0]= 2;
- selectFlags[totCount-1]= 2;
- totChange= 2;
- }
- else {
- /* find out which ones deserve an extra flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 1) {
- if ((i < (totCount-1)) && (selectFlags[i+1] == 0)) {
- selectFlags[i] = 2;
- totChange++;
- }
- else if ((i != 0) && (selectFlags[i-1] == 0)) {
- selectFlags[i] = 2;
- totChange++;
- }
- }
- }
-
- /* second pass - for the ends. done after as it may affect results */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 1) {
- if ((i==0) && (i != (totCount-1)) && (selectFlags[i+1] == 1)) {
- selectFlags[i] = 2;
- totChange++;
- }
- else if ((i==(totCount-1)) && (i!=0) && (selectFlags[i-1] == 1)) {
- selectFlags[i] = 2;
- totChange++;
- }
- }
- }
- }
-
- /* set select flags based on select flag */
- for (i=0; i<totCount; i++) {
- if (selectFlags[i] == 2) {
- bezt = (nu->bezt + i);
-
- if (bezt->hide == 0) {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
- }
- }
+ if(randfac == 0) return;
+
+ amountofcps= count_curveverts_without_handles(&editNurb);
+ itemstobeselected= MEM_callocN(sizeof(int) * amountofcps, "selectitems");
+ amounttoselect= floor(randfac * amountofcps / 100 + 0.5);
+ generate_pickable_list(itemstobeselected, amountofcps, amounttoselect);
+
+ /* select elements */
+ for(i=1, nu= editNurb.first; nu; nu= nu->next) {
+ if((nu->type & 7)==CU_BEZIER) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ if(itemstobeselected[k] != -1) select_beztriple(bezt, SELECT, 1, VISIBLE);
+ k++;
+ bezt++;
}
-
- /* free tempolary array */
- MEM_freeN(selectFlags);
}
else {
- /* TODO: figure out method of nurbs surfaces */
- }
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+ while(a--) {
+ if(itemstobeselected[k] != -1) select_bpoint(bp, SELECT, 1, VISIBLE);
+ k++;
+ bp++;
+ }
+ }
}
+
+ MEM_freeN(itemstobeselected);
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Select Random");
+}
+
+void select_every_nth_nurb()
+{
+ static short nfac= 2;
+
+ if(!G.obedit) return;
+
+ if(!button(&nfac, 2, 25,"N:")) return;
+
+ select_adjacent_cp(nfac, 1, SELECT);
+ select_adjacent_cp(-nfac, 1, SELECT);
countall();
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select Less");
+ BIF_undo_push("Select Every Nth");
}
void adduplicate_nurb()
@@ -3383,7 +3634,7 @@ void delNurb()
a= nu->pntsu;
if(a) {
while(a) {
- if( BEZSELECTED(bezt) );
+ if( BEZSELECTED_HIDDENHANDLES(bezt) );
else break;
a--;
bezt++;
@@ -3399,7 +3650,7 @@ void delNurb()
a= nu->pntsu*nu->pntsv;
if(a) {
while(a) {
- if(bp->f1 & 1 );
+ if(bp->f1 & SELECT);
else break;
a--;
bp++;
@@ -3420,7 +3671,7 @@ void delNurb()
if( (nu->type & 7)==CU_BEZIER ) {
bezt= nu->bezt;
for(a=0;a<nu->pntsu;a++) {
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
memcpy(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple));
nu->pntsu--;
a--;
@@ -3441,7 +3692,7 @@ void delNurb()
bp= nu->bp;
for(a=0;a<nu->pntsu;a++) {
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
memcpy(bp, bp+1, (nu->pntsu-a-1)*sizeof(BPoint));
nu->pntsu--;
a--;
@@ -3473,14 +3724,14 @@ void delNurb()
if( (nu->type & 7)==CU_BEZIER ) {
bezt= nu->bezt;
for(a=0; a<nu->pntsu-1; a++) {
- if( BEZSELECTED(bezt) ) {
+ if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
bezt1= bezt;
bezt2= bezt+1;
- if( (bezt2->f1 & 1) || (bezt2->f2 & 1) || (bezt2->f3 & 1) ) ;
+ if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) ;
else { /* maybe do not make cyclic */
if(a==0 && (nu->flagu & 1) ) {
bezt2= bezt+(nu->pntsu-1);
- if( (bezt2->f1 & 1) || (bezt2->f2 & 1) || (bezt2->f3 & 1) ) {
+ if( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) {
nu->flagu--;
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
@@ -3500,7 +3751,7 @@ void delNurb()
else if(nu->pntsv==1) {
bp= nu->bp;
for(a=0; a<nu->pntsu-1; a++) {
- if( bp->f1 & 1 ) {
+ if( bp->f1 & SELECT ) {
bp1= bp;
bp2= bp+1;
if( bp2->f1 & 1 ) ;
@@ -3757,7 +4008,8 @@ Nurb *addNurbprim(int type, int stype, int newname)
cent[2]-= G.obedit->obmat[3][2];
if (G.vd) {
- Mat3CpyMat4(imat, G.vd->viewmat);
+ if ( !(newname) || U.flag & USER_ADD_VIEWALIGNED) Mat3CpyMat4(imat, G.vd->viewmat);
+ else Mat3One(imat);
Mat3MulVecfl(imat, cent);
Mat3MulMat3(cmat, imat, mat);
Mat3Inv(imat, cmat);
@@ -3788,7 +4040,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
(BezTriple*)MEM_callocN(2 * sizeof(BezTriple), "addNurbprim1");
bezt= nu->bezt;
bezt->h1= bezt->h2= HD_ALIGN;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->radius = 1.0;
for(a=0;a<3;a++) {
@@ -3803,7 +4055,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
bezt++;
bezt->h1= bezt->h2= HD_ALIGN;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->radius = bezt->weight = 1.0;
for(a=0;a<3;a++) {
@@ -3825,7 +4077,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
for(a=0;a<4;a++, bp++) {
VECCOPY(bp->vec, cent);
bp->vec[3]= 1.0;
- bp->f1= 1;
+ bp->f1= SELECT;
bp->radius = bp->weight = 1.0;
}
@@ -3862,7 +4114,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
for(a=0;a<5;a++, bp++) {
VECCOPY(bp->vec, cent);
bp->vec[3]= 1.0;
- bp->f1= 1;
+ bp->f1= SELECT;
bp->radius = bp->weight = 1.0;
}
@@ -3899,7 +4151,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
VECCOPY(bezt->vec[a], cent);
}
bezt->h1= bezt->h2= HD_AUTO;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->vec[1][0]+= -grid;
for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]);
bezt->radius = bezt->weight = 1.0;
@@ -3909,7 +4161,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
VECCOPY(bezt->vec[a], cent);
}
bezt->h1= bezt->h2= HD_AUTO;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->vec[1][1]+= grid;
for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]);
bezt->radius = bezt->weight = 1.0;
@@ -3919,7 +4171,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
VECCOPY(bezt->vec[a], cent);
}
bezt->h1= bezt->h2= HD_AUTO;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->vec[1][0]+= grid;
for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]);
bezt->radius = bezt->weight = 1.0;
@@ -3929,7 +4181,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
VECCOPY(bezt->vec[a], cent);
}
bezt->h1= bezt->h2= HD_AUTO;
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
bezt->vec[1][1]+= -grid;
for(a=0;a<3;a++) Mat3MulVecfl(imat,bezt->vec[a]);
bezt->radius = bezt->weight = 1.0;
@@ -3945,7 +4197,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
bp= nu->bp;
for(a=0; a<8; a++) {
- bp->f1= 1;
+ bp->f1= SELECT;
VECCOPY(bp->vec, cent);
if(xzproj==0) {
@@ -3987,7 +4239,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
for(a=0; a<4; a++) {
for(b=0; b<4; b++) {
VECCOPY(bp->vec, cent);
- bp->f1= 1;
+ bp->f1= SELECT;
fac= (float)a -1.5;
bp->vec[0]+= fac*grid;
fac= (float)b -1.5;
@@ -4012,7 +4264,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
rename_id((ID *)G.obedit->data, "SurfTube");
}
- nu= addNurbprim(4, 1, 0); /* circle */
+ nu= addNurbprim(4, 1, newname); /* circle */
nu->resolu= 32;
nu->flag= CU_SMOOTH;
BLI_addtail(&editNurb, nu); /* temporal for extrude and translate */
@@ -4031,7 +4283,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
while(a-- >0) {
- bp->f1 |= 1;
+ bp->f1 |= SELECT;
bp++;
}
}
@@ -4054,7 +4306,7 @@ Nurb *addNurbprim(int type, int stype, int newname)
bp= nu->bp;
for(a=0; a<5; a++) {
- bp->f1= 1;
+ bp->f1= SELECT;
VECCOPY(bp->vec, cent);
bp->vec[0]+= nurbcircle[a][0]*grid;
bp->vec[2]+= nurbcircle[a][1]*grid;
@@ -4067,14 +4319,15 @@ Nurb *addNurbprim(int type, int stype, int newname)
makeknots(nu, 1, nu->flagu>>1);
BLI_addtail(&editNurb, nu); /* temporal for spin */
- spin_nurb(0, 0);
+ if(newname) spin_nurb(0, 2);
+ else spin_nurb(0, 0);
makeknots(nu, 2, nu->flagv>>1);
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
while(a-- >0) {
- bp->f1 |= 1;
+ bp->f1 |= SELECT;
bp++;
}
BLI_remlink(&editNurb, nu);
@@ -4088,20 +4341,21 @@ Nurb *addNurbprim(int type, int stype, int newname)
}
xzproj= 1;
- nu= addNurbprim(4, 1, 0); /* circle */
+ nu= addNurbprim(4, 1, newname); /* circle */
xzproj= 0;
nu->resolu= 24;
nu->resolv= 32;
nu->flag= CU_SMOOTH;
BLI_addtail(&editNurb, nu); /* temporal for extrude and translate */
- spin_nurb(0, 0);
+ if(newname) spin_nurb(0, 2);
+ else spin_nurb(0, 0);
BLI_remlink(&editNurb, nu);
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
while(a-- >0) {
- bp->f1 |= 1;
+ bp->f1 |= SELECT;
bp++;
}
@@ -4207,11 +4461,17 @@ void add_primitiveCurve(int stype)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
countall();
- allqueue(REDRAWALL, 0);
/* if a new object was created, it stores it in Curve, for reload original data and undo */
- if(newname) load_editNurb();
- BIF_undo_push("Add primitive");
+ if ( !(newname) || U.flag & USER_ADD_EDITMODE) {
+ if(newname) load_editNurb();
+ } else {
+ exit_editmode(2);
+ }
+
+ allqueue(REDRAWALL, 0);
+
+ BIF_undo_push("Add Curve");
}
void add_primitiveNurb(int type)
@@ -4242,11 +4502,16 @@ void add_primitiveNurb(int type)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
countall();
- allqueue(REDRAWALL, 0);
-
+
/* if a new object was created, it stores it in Curve, for reload original data and undo */
- if(newname) load_editNurb();
- else BIF_undo_push("Add primitive");
+ if ( !(newname) || U.flag & USER_ADD_EDITMODE) {
+ if(newname) load_editNurb();
+ } else {
+ exit_editmode(2);
+ }
+ allqueue(REDRAWALL, 0);
+
+ BIF_undo_push("Add Surface");
}
@@ -4265,7 +4530,7 @@ void clear_tilt()
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if(BEZSELECTED(bezt)) bezt->alfa= 0.0;
+ if(BEZSELECTED_HIDDENHANDLES(bezt)) bezt->alfa= 0.0;
bezt++;
}
}
@@ -4273,7 +4538,7 @@ void clear_tilt()
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if(bp->f1 & 1) bp->alfa= 0.0;
+ if(bp->f1 & SELECT) bp->alfa= 0.0;
bp++;
}
}
@@ -4301,9 +4566,9 @@ int bezt_compare (const void *e1, const void *e2)
/* Check selected flags : Ensures that selected keys will be listed first */
- if ((b1->f2 & 1) && !(b2->f2 & 1))
+ if ((b1->f2 & SELECT) && !(b2->f2 & SELECT))
return -1;
- if (!(b1->f2 & 1) && (b2->f2 & 1))
+ if (!(b1->f2 & SELECT) && (b2->f2 & SELECT))
return 1;
return 0;
@@ -4359,7 +4624,7 @@ static void free_undoCurve(void *lbv)
/* and this is all the undo system needs to know */
void undo_push_curve(char *name)
{
- undo_editmode_push(name, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve);
+ undo_editmode_push(name, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
}
diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c
index 7a086ed5be3..6ab3d5c17c6 100644
--- a/source/blender/src/editdeform.c
+++ b/source/blender/src/editdeform.c
@@ -334,11 +334,13 @@ void del_defgroup (Object *ob)
MDeformVert *dvert= editLatt->dvert;
int a, tot;
- tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
- for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
- for (i=0; i<dvert->totweight; i++){
- if (dvert->dw[i].def_nr > (ob->actdef-1))
- dvert->dw[i].def_nr--;
+ if (dvert) {
+ tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+ for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
+ for (i=0; i<dvert->totweight; i++){
+ if (dvert->dw[i].def_nr > (ob->actdef-1))
+ dvert->dw[i].def_nr--;
+ }
}
}
}
@@ -702,6 +704,53 @@ void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
remove_vert_def_nr (ob, def_nr, vertnum);
}
+/* for mesh in object mode lattice can be in editmode */
+static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
+{
+ MDeformVert *dvert= NULL;
+ int i;
+
+ /* get the deform vertices corresponding to the
+ * vertnum
+ */
+ if(ob->type==OB_MESH) {
+ if( ((Mesh*)ob->data)->dvert )
+ dvert = ((Mesh*)ob->data)->dvert + vertnum;
+ }
+ else if(ob->type==OB_LATTICE) {
+ Lattice *lt= ob->data;
+
+ if(ob==G.obedit)
+ lt= editLatt;
+
+ if(lt->dvert)
+ dvert = lt->dvert + vertnum;
+ }
+
+ if(dvert==NULL)
+ return 0.0f;
+
+ for(i=dvert->totweight-1 ; i>=0 ; i--)
+ if(dvert->dw[i].def_nr == def_nr)
+ return dvert->dw[i].weight;
+
+ return 0.0f;
+}
+
+/* mesh object mode, lattice can be in editmode */
+float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+{
+ int def_nr;
+
+ if(!ob)
+ return 0.0f;
+
+ def_nr = get_defgroup_num(ob, dg);
+ if(def_nr < 0) return 0.0f;
+
+ return get_vert_def_nr (ob, def_nr, vertnum);
+}
+
/* Only available in editmode */
/* removes from active defgroup, if allverts==0 only selected vertices */
void remove_verts_defgroup (int allverts)
@@ -730,7 +779,7 @@ void remove_verts_defgroup (int allverts)
case OB_MESH:
for (eve=G.editMesh->verts.first; eve; eve=eve->next){
dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
-
+
if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
for (i=0; i<dvert->totweight; i++){
/* Find group */
@@ -776,6 +825,36 @@ void remove_verts_defgroup (int allverts)
}
}
+/* Only available in editmode */
+/* removes from all defgroup, if allverts==0 only selected vertices */
+void remove_verts_defgroups(int allverts)
+{
+ Object *ob;
+ int actdef, defCount;
+
+ if (multires_level1_test()) return;
+
+ ob= G.obedit;
+ if (ob == NULL) return;
+
+ actdef= ob->actdef;
+ defCount= BLI_countlist(&ob->defbase);
+
+ if (defCount == 0) {
+ error("Object has no vertex groups");
+ return;
+ }
+
+ /* To prevent code redundancy, we just use remove_verts_defgroup, but that
+ * only operates on the active vgroup. So we iterate through all groups, by changing
+ * active group index
+ */
+ for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
+ remove_verts_defgroup(allverts);
+
+ ob->actdef= actdef;
+}
+
void vertexgroup_select_by_name(Object *ob, char *name)
{
bDeformGroup *curdef;
@@ -810,7 +889,7 @@ void vgroup_assign_with_menu(void)
/* give user choices of adding to current/new or removing from current */
if (defCount && ob->actdef)
- mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3");
+ mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4");
else
mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
@@ -832,6 +911,11 @@ void vgroup_assign_with_menu(void)
allqueue(REDRAWVIEW3D, 1);
BIF_undo_push("Remove from vertex group");
break;
+ case 4: /* remove from all groups */
+ remove_verts_defgroups(0);
+ allqueue(REDRAWVIEW3D, 1);
+ BIF_undo_push("Remove from all vertex groups");
+ break;
}
}
diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c
index 21ccac16da9..33b9a60104f 100644
--- a/source/blender/src/editface.c
+++ b/source/blender/src/editface.c
@@ -40,6 +40,7 @@
#include "BLI_arithb.h"
#include "BLI_heap.h"
#include "BLI_edgehash.h"
+#include "BLI_editVert.h"
#include "MTC_matrixops.h"
@@ -62,15 +63,18 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
#include "BSE_view.h"
#include "BSE_edit.h"
#include "BSE_drawview.h" /* for backdrawview3d */
#include "BIF_editsima.h"
+#include "BIF_editmesh.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
#include "BIF_toolbox.h"
@@ -90,7 +94,6 @@
#include "mydevice.h"
#include "blendef.h"
#include "butspace.h"
-#include "multires.h"
#include "BSE_trans_types.h"
@@ -124,7 +127,7 @@
/* returns 0 if not found, otherwise 1 */
int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
{
- if (!me || !me->mtface || me->totface==0)
+ if (!me || me->totface==0)
return 0;
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
@@ -175,27 +178,24 @@ static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
return 1;
}
-static void uv_calc_center_vector(float *result, Object *ob, Mesh *me)
+/* only operates on the edit object - this is all thats needed at the moment */
+static void uv_calc_center_vector(float *result, Object *ob, EditMesh *em)
{
float min[3], max[3], *cursx;
- int a;
- MTFace *tface;
- MFace *mface;
-
+
+ EditFace *efa;
switch (G.vd->around)
{
case V3D_CENTER: /* bounding box center */
min[0]= min[1]= min[2]= 1e20f;
max[0]= max[1]= max[2]= -1e20f;
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- DO_MINMAX((me->mvert+mface->v1)->co, min, max);
- DO_MINMAX((me->mvert+mface->v2)->co, min, max);
- DO_MINMAX((me->mvert+mface->v3)->co, min, max);
- if(mface->v4) DO_MINMAX((me->mvert+mface->v4)->co, min, max);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ DO_MINMAX(efa->v1->co, min, max);
+ DO_MINMAX(efa->v2->co, min, max);
+ DO_MINMAX(efa->v3->co, min, max);
+ if(efa->v4) DO_MINMAX(efa->v4->co, min, max);
}
}
VecMidf(result, min, max);
@@ -340,27 +340,42 @@ static void uv_calc_shift_project(float *target, float *shift, float rotmat[][4]
void calculate_uv_map(unsigned short mapmode)
{
- Mesh *me;
MTFace *tface;
- MFace *mface;
Object *ob;
float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3];
float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0;
- int i, b, mi, a, n;
+ int i, b, mi, n;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+
if(G.scene->toolsettings->uvcalc_mapdir==1) {
upangledeg= 90.0;
sideangledeg= 0.0;
- }
- else {
+ } else {
upangledeg= 0.0;
if(G.scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0;
else sideangledeg= 90.0;
}
-
- me= get_mesh(ob=OBACT);
- if(me==0 || me->mtface==0) return;
- if(me->totface==0) return;
+
+ /* add uvs if there not here */
+ if (!EM_texFaceCheck()) {
+ if (em && em->faces.first)
+ EM_add_data_layer(&em->fdata, CD_MTFACE);
+
+ if (!EM_texFaceCheck())
+ return;
+
+ /* select new UV's */
+ if ((G.sima && G.sima->flag & SI_SYNC_UVSEL)==0) {
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ simaFaceSel_Set(efa, tf);
+ }
+ }
+ }
+
+ ob=OBACT;
switch(mapmode) {
case B_UVAUTO_BOUNDS:
@@ -369,28 +384,26 @@ void calculate_uv_map(unsigned short mapmode)
cent[0] = cent[1] = cent[2] = 0.0;
uv_calc_map_matrix(rotatematrix, ob, upangledeg, sideangledeg, 1.0f);
-
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3,(me->mvert+mface->v1)->co,min,max);
- uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3,(me->mvert+mface->v2)->co,min,max);
- uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3,(me->mvert+mface->v3)->co,min,max);
- if(mface->v4)
- uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3,(me->mvert+mface->v4)->co,min,max);
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3, efa->v1->co, min,max);
+ uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3, efa->v2->co, min,max);
+ uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3, efa->v3->co,min,max);
+ if(efa->v4)
+ uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3, efa->v4->co,min,max);
}
}
- /* rescale UV to be in 0..1,1/2,1/4,1/8 */
+ /* rescale UV to be in 1/1 */
dx= (max[0]-min[0]);
dy= (max[1]-min[1]);
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(mface->v4) b= 3; else b= 2;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(efa->v4) b= 3; else b= 2;
for(; b>=0; b--) {
tface->uv[b][0]= ((tface->uv[b][0]-min[0])*fac)/dx;
tface->uv[b][1]= 1.0-fac+((tface->uv[b][1]-min[1])/* *fac */)/dy;
@@ -402,31 +415,30 @@ void calculate_uv_map(unsigned short mapmode)
case B_UVAUTO_WINDOW:
cent[0] = cent[1] = cent[2] = 0.0;
Mat4CpyMat4(rotatematrix,ob->obmat);
-
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4,(me->mvert+mface->v1)->co,NULL,NULL);
- uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4,(me->mvert+mface->v2)->co,NULL,NULL);
- uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4,(me->mvert+mface->v3)->co,NULL,NULL);
- if(mface->v4)
- uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4,(me->mvert+mface->v4)->co,NULL,NULL);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4, efa->v1->co, NULL,NULL);
+ uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4, efa->v2->co, NULL,NULL);
+ uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4, efa->v3->co, NULL,NULL);
+ if(efa->v4)
+ uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4, efa->v4->co, NULL,NULL);
}
}
break;
case B_UVAUTO_RESET:
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, tface++, mface++)
- if(mface->flag & ME_FACE_SEL)
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
default_uv(tface->uv, 1.0);
+ }
+ }
break;
case B_UVAUTO_CYLINDER:
case B_UVAUTO_SPHERE:
- uv_calc_center_vector(cent, ob, me);
+ uv_calc_center_vector(cent, ob, em);
if(mapmode==B_UVAUTO_CYLINDER) radius = G.scene->toolsettings->uvcalc_radius;
@@ -435,17 +447,15 @@ void calculate_uv_map(unsigned short mapmode)
Mat4One(rotatematrix);
else
uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius);
-
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode,(me->mvert+mface->v1)->co,NULL,NULL);
- uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode,(me->mvert+mface->v2)->co,NULL,NULL);
- uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode,(me->mvert+mface->v3)->co,NULL,NULL);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode, efa->v1->co, NULL,NULL);
+ uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode, efa->v2->co, NULL,NULL);
+ uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode, efa->v3->co, NULL,NULL);
n = 3;
- if(mface->v4) {
- uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode,(me->mvert+mface->v4)->co,NULL,NULL);
+ if(efa->v4) {
+ uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode, efa->v4->co, NULL,NULL);
n=4;
}
@@ -471,15 +481,14 @@ void calculate_uv_map(unsigned short mapmode)
float no[3];
short cox, coy;
float *loc= ob->obmat[3];
- MVert *mv= me->mvert;
+ /*MVert *mv= me->mvert;*/
float cubesize = G.scene->toolsettings->uvcalc_cubesize;
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(mface->flag & ME_FACE_SEL) {
- CalcNormFloat((mv+mface->v1)->co, (mv+mface->v2)->co, (mv+mface->v3)->co, no);
-
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, no);
+
no[0]= fabs(no[0]);
no[1]= fabs(no[1]);
no[2]= fabs(no[2]);
@@ -489,43 +498,42 @@ void calculate_uv_map(unsigned short mapmode)
else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2;
else { cox= 1; coy= 2; }
- tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v1)->co[cox]);
- tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v1)->co[coy]);
+ tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v1->co[cox]);
+ tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v1->co[coy]);
dx = floor(tface->uv[0][0]);
dy = floor(tface->uv[0][1]);
tface->uv[0][0] -= dx;
tface->uv[0][1] -= dy;
- tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v2)->co[cox]);
- tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v2)->co[coy]);
+ tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v2->co[cox]);
+ tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v2->co[coy]);
tface->uv[1][0] -= dx;
tface->uv[1][1] -= dy;
- tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v3)->co[cox]);
- tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v3)->co[coy]);
+ tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v3->co[cox]);
+ tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v3->co[coy]);
tface->uv[2][0] -= dx;
tface->uv[2][1] -= dy;
- if(mface->v4) {
- tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v4)->co[cox]);
- tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v4)->co[coy]);
+ if(efa->v4) {
+ tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v4->co[cox]);
+ tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v4->co[coy]);
tface->uv[3][0] -= dx;
tface->uv[3][1] -= dy;
}
}
}
+ break;
}
- break;
default:
return;
} /* end switch mapmode */
/* clipping and wrapping */
if(G.sima && G.sima->flag & SI_CLIP_UV) {
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++, tface++) {
- if(!(mface->flag & ME_FACE_SEL)) continue;
-
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (!(efa->f & SELECT)) continue;
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
dx= dy= 0;
- if(mface->v4) b= 3; else b= 2;
+ if(efa->v4) b= 3; else b= 2;
for(; b>=0; b--) {
while(tface->uv[b][0] + dx < 0.0) dx+= 0.5;
while(tface->uv[b][0] + dx > 1.0) dx-= 0.5;
@@ -533,7 +541,7 @@ void calculate_uv_map(unsigned short mapmode)
while(tface->uv[b][1] + dy > 1.0) dy-= 0.5;
}
- if(mface->v4) b= 3; else b= 2;
+ if(efa->v4) b= 3; else b= 2;
for(; b>=0; b--) {
tface->uv[b][0]+= dx;
CLAMP(tface->uv[b][0], 0.0, 1.0);
@@ -552,42 +560,50 @@ void calculate_uv_map(unsigned short mapmode)
allqueue(REDRAWIMAGE, 0);
}
-MTFace *get_active_tface(MCol **mcol)
+/* last_sel, use em->act_face otherwise get the last selected face in the editselections
+ * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
+MTFace *get_active_mtface(EditFace **act_efa, MCol **mcol, short sloppy)
{
- Mesh *me;
- MTFace *tf;
- MFace *mf;
- int a;
-
- if(OBACT==NULL || OBACT->type!=OB_MESH)
- return NULL;
+ EditMesh *em = G.editMesh;
+ EditFace *efa = NULL;
+ EditSelection *ese;
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0)
+ if(!EM_texFaceCheck())
return NULL;
- for(a=0, tf=me->mtface; a < me->totface; a++, tf++) {
- if(tf->flag & TF_ACTIVE) {
- if(mcol) *mcol = (me->mcol)? &me->mcol[a*4]: NULL;
- return tf;
+ /* first check the active face */
+ if (sloppy && em->act_face) {
+ efa = em->act_face;
+ } else {
+ ese = em->selected.last;
+ for (; ese; ese=ese->prev){
+ if(ese->type == EDITFACE) {
+ efa = (EditFace *)ese->data;
+
+ if (efa->h) efa= NULL;
+ else break;
+ }
}
}
-
- for(a=0, tf=me->mtface, mf=me->mface; a < me->totface; a++, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
- if(mcol) *mcol = (me->mcol)? &me->mcol[a*4]: NULL;
- return tf;
+ if (sloppy && !efa) {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT)
+ break;
}
}
-
- for(a=0, tf=me->mtface, mf=me->mface; a < me->totface; a++, tf++, mf++) {
- if((mf->flag & ME_HIDE)==0) {
- if(mcol) *mcol = (me->mcol)? &me->mcol[a*4]: NULL;
- return tf;
+
+ if (efa) {
+ if (mcol) {
+ if (CustomData_has_layer(&em->fdata, CD_MCOL))
+ *mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ else
+ *mcol = NULL;
}
+ if (act_efa) *act_efa = efa;
+ return CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
}
-
+ if (act_efa) *act_efa= NULL;
if(mcol) *mcol = NULL;
return NULL;
}
@@ -634,7 +650,7 @@ void reveal_tface()
int a;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0 || me->totface==0) return;
+ if(me==0 || me->totface==0) return;
mface= me->mface;
a= me->totface;
@@ -646,7 +662,7 @@ void reveal_tface()
mface++;
}
- BIF_undo_push("Reveal UV face");
+ BIF_undo_push("Reveal face");
object_tface_flags_changed(OBACT, 0);
}
@@ -658,7 +674,7 @@ void hide_tface()
int a;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0 || me->totface==0) return;
+ if(me==0 || me->totface==0) return;
if(G.qual & LR_ALTKEY) {
reveal_tface();
@@ -682,7 +698,7 @@ void hide_tface()
mface++;
}
- BIF_undo_push("Hide UV face");
+ BIF_undo_push("Hide face");
object_tface_flags_changed(OBACT, 0);
}
@@ -696,7 +712,7 @@ void select_linked_tfaces(int mode)
ob = OBACT;
me = get_mesh(ob);
- if(me==0 || me->mtface==0 || me->totface==0) return;
+ if(me==0 || me->totface==0) return;
if (mode==0 || mode==1) {
if (!(ob->lay & G.vd->lay))
@@ -716,7 +732,7 @@ void deselectall_tface()
int a, sel;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(me==0) return;
mface= me->mface;
a= me->totface;
@@ -738,7 +754,7 @@ void deselectall_tface()
mface++;
}
- BIF_undo_push("(De)select all UV face");
+ BIF_undo_push("(De)select all faces");
object_tface_flags_changed(OBACT, 0);
}
@@ -750,7 +766,7 @@ void selectswap_tface(void)
int a;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(me==0) return;
mface= me->mface;
a= me->totface;
@@ -763,158 +779,11 @@ void selectswap_tface(void)
mface++;
}
- BIF_undo_push("Select inverse UV face");
+ BIF_undo_push("Select inverse face");
object_tface_flags_changed(OBACT, 0);
}
-void rotate_uv_tface()
-{
- Mesh *me;
- MFace *mf;
- MCol *mcol;
- MTFace *tf;
- short mode;
- int a;
-
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
-
- mode= pupmenu("Rotate %t|UV Co-ordinates %x1|Vertex Colors %x2");
-
- if (mode == 1 && me->mtface) {
- tf= me->mtface;
- mf= me->mface;
- for(a=0; a<me->totface; a++, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
- float u1= tf->uv[0][0];
- float v1= tf->uv[0][1];
-
- tf->uv[0][0]= tf->uv[1][0];
- tf->uv[0][1]= tf->uv[1][1];
-
- tf->uv[1][0]= tf->uv[2][0];
- tf->uv[1][1]= tf->uv[2][1];
-
- if(mf->v4) {
- tf->uv[2][0]= tf->uv[3][0];
- tf->uv[2][1]= tf->uv[3][1];
-
- tf->uv[3][0]= u1;
- tf->uv[3][1]= v1;
- }
- else {
- tf->uv[2][0]= u1;
- tf->uv[2][1]= v1;
- }
- }
- }
-
- BIF_undo_push("Rotate UV face");
- object_uvs_changed(OBACT);
- }
- else if (mode == 2 && me->mcol) {
- tf= me->mtface;
- mcol= me->mcol;
- mf= me->mface;
- for(a=0; a<me->totface; a++, tf++, mf++, mcol+=4) {
- if(mf->flag & ME_FACE_SEL) {
- MCol tmpcol= mcol[0];
-
- mcol[0]= mcol[1];
- mcol[1]= mcol[2];
-
- if(mf->v4) {
- mcol[2]= mcol[3];
- mcol[3]= tmpcol;
- }
- else
- mcol[2]= tmpcol;
- }
- }
-
- BIF_undo_push("Rotate color face");
- object_uvs_changed(OBACT);
- }
-}
-
-void mirror_uv_tface()
-{
- Mesh *me;
- MFace *mf;
- MTFace *tf;
- MCol *mcol;
- short mode;
- int a;
-
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
-
- mode= pupmenu("Mirror %t|UV Co-ordinates %x1|Vertex Colors %x2");
-
- if (mode==1 && me->mtface) {
- mf= me->mface;
- tf= me->mtface;
-
- for (a=0; a<me->totface; a++, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
- float u1= tf->uv[0][0];
- float v1= tf->uv[0][1];
- if(mf->v4) {
- tf->uv[0][0]= tf->uv[3][0];
- tf->uv[0][1]= tf->uv[3][1];
-
- tf->uv[3][0]= u1;
- tf->uv[3][1]= v1;
-
- u1= tf->uv[1][0];
- v1= tf->uv[1][1];
-
- tf->uv[1][0]= tf->uv[2][0];
- tf->uv[1][1]= tf->uv[2][1];
-
- tf->uv[2][0]= u1;
- tf->uv[2][1]= v1;
- }
- else {
- tf->uv[0][0]= tf->uv[2][0];
- tf->uv[0][1]= tf->uv[2][1];
- tf->uv[2][0]= u1;
- tf->uv[2][1]= v1;
- }
- }
- }
- }
- else if(mode==2 && me->mcol) {
- mf= me->mface;
- tf= me->mtface;
- mcol= me->mcol;
-
- for (a=0; a<me->totface; a++, tf++, mf++, mcol+=4) {
- if(mf->flag & ME_FACE_SEL) {
- MCol tmpcol= mcol[0];
-
- if(mf->v4) {
- mcol[0]= mcol[3];
- mcol[3]= tmpcol;
-
- tmpcol = mcol[1];
- mcol[1]= mcol[2];
- mcol[2]= tmpcol;
- }
- else {
- mcol[0]= mcol[2];
- mcol[2]= tmpcol;
- }
- }
- }
- }
-
- BIF_undo_push("Mirror UV face");
-
- object_uvs_changed(OBACT);
-}
-
int minmax_tface(float *min, float *max)
{
Object *ob;
@@ -1182,7 +1051,7 @@ void seam_mark_clear_tface(short mode)
int a;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0 || me->totface==0) return;
+ if(me==0 || me->totface==0) return;
if (mode == 0)
mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
@@ -1237,7 +1106,6 @@ void face_select()
{
Object *ob;
Mesh *me;
- MTFace *tface, *tsel;
MFace *mface, *msel;
short mval[2];
unsigned int a, index;
@@ -1257,27 +1125,20 @@ void face_select()
if (!facesel_face_pick(me, mval, &index, 1)) return;
- tsel= (((MTFace*)me->mtface)+index);
msel= (((MFace*)me->mface)+index);
-
if (msel->flag & ME_HIDE) return;
/* clear flags */
- tface = me->mtface;
mface = me->mface;
a = me->totface;
- while (a--) {
- if (G.qual & LR_SHIFTKEY)
- tface->flag &= ~TF_ACTIVE;
- else {
- tface->flag &= ~TF_ACTIVE;
+ if ((G.qual & LR_SHIFTKEY)==0) {
+ while (a--) {
mface->flag &= ~ME_FACE_SEL;
+ mface++;
}
- tface++;
- mface++;
}
- tsel->flag |= TF_ACTIVE;
+ me->act_face = (int)index;
if (G.qual & LR_SHIFTKEY) {
if (msel->flag & ME_FACE_SEL)
@@ -1297,7 +1158,6 @@ void face_select()
void face_borderselect()
{
Mesh *me;
- MTFace *tface;
MFace *mface;
rcti rect;
struct ImBuf *ibuf;
@@ -1306,7 +1166,7 @@ void face_borderselect()
char *selar;
me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(me==0) return;
if(me->totface==0) return;
val= get_border(&rect, 3);
@@ -1339,7 +1199,7 @@ void face_borderselect()
}
mface= me->mface;
- for(a=1; a<=me->totface; a++, tface++, mface++) {
+ for(a=1; a<=me->totface; a++, mface++) {
if(selar[a]) {
if(mface->flag & ME_HIDE);
else {
@@ -1420,50 +1280,6 @@ void uv_autocalc_tface()
}
}
-void set_faceselect() /* toggle */
-{
- Object *ob = OBACT;
- Mesh *me = 0;
-
- if(ob==NULL) return;
- if(object_data_is_libdata(ob)) {
- error_libdata();
- return;
- }
-
- me= get_mesh(ob);
-
- scrarea_queue_headredraw(curarea);
-
- if(me) /* make sure modifiers are updated for mapping requirements */
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
-
- if(G.f & G_FACESELECT) {
- G.f &= ~G_FACESELECT;
-
- if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
- if(me)
- reveal_tface();
- setcursor_space(SPACE_VIEW3D, CURSOR_STD);
- BIF_undo_push("End UV Faceselect");
- }
- }
- else if (me && (ob->lay & G.vd->lay)) {
- G.f |= G_FACESELECT;
- if(me->mtface==NULL)
- make_tfaces(me);
-
- setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL);
- BIF_undo_push("Set UV Faceselect");
- }
-
- countall();
-
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- allqueue(REDRAWIMAGE, 0);
-}
-
/* Texture Paint */
void set_texturepaint() /* toggle */
@@ -1502,81 +1318,74 @@ void set_texturepaint() /* toggle */
allqueue(REDRAWBUTSEDIT, 0);
}
-/* Get the barycentric coordinates of 2d point p in 2d triangle (v1, v2, v3) */
-static void texpaint_barycentric_2d(float *v1, float *v2, float *v3, float *p, float *w)
+static void texpaint_project(Object *ob, float *model, float *proj, float *co, float *pco)
{
- float b[2], c[2], h[2], div;
-
- Vec2Subf(b, v1, v3);
- Vec2Subf(c, v2, v3);
- Vec2Subf(h, p, v3);
+ VECCOPY(pco, co);
+ pco[3]= 1.0f;
- div= b[0]*c[1] - b[1]*c[0];
-
- if (div == 0.0) {
- w[0]= w[1]= w[2]= 1.0f/3.0f;
- }
- else {
- div = 1.0/div;
- w[0] = (h[0]*c[1] - h[1]*c[0])*div;
- w[1] = (b[0]*h[1] - b[1]*h[0])*div;
- w[2] = 1.0 - w[0] - w[1];
- }
+ Mat4MulVecfl(ob->obmat, pco);
+ Mat4MulVecfl((float(*)[4])model, pco);
+ Mat4MulVec4fl((float(*)[4])proj, pco);
}
-/* Get 2d vertex coordinates of tface projected onto screen */
-static void texpaint_project(Object *ob, double *model, double *proj, GLint *view, float *co, float *pco)
+static void texpaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, float *co, float *w)
{
- float obco[3];
- double winx, winy, winz;
-
- VecCopyf(obco, co);
- Mat4MulVecfl(ob->obmat, obco);
- gluProject(obco[0], obco[1], obco[2], model, proj, view, &winx, &winy, &winz);
-
- pco[0]= (float)winx;
- pco[1]= (float)winy;
-}
-
-static int texpaint_projected_verts(Object *ob, MFace *mf, MTFace *tf, MVert *mv, float *v1, float *v2, float *v3, float *v4)
-{
- double model[16], proj[16];
+ float pv1[4], pv2[4], pv3[4], h[3], divw;
+ float model[16], proj[16], wmat[3][3], invwmat[3][3];
GLint view[4];
- persp(PERSP_VIEW);
+ /* compute barycentric coordinates */
/* get the needed opengl matrices */
glGetIntegerv(GL_VIEWPORT, view);
- glGetDoublev(GL_MODELVIEW_MATRIX, model);
- glGetDoublev(GL_PROJECTION_MATRIX, proj);
+ glGetFloatv(GL_MODELVIEW_MATRIX, model);
+ glGetFloatv(GL_PROJECTION_MATRIX, proj);
view[0] = view[1] = 0;
/* project the verts */
- texpaint_project(ob, model, proj, view, mv[0].co, v1);
- texpaint_project(ob, model, proj, view, mv[1].co, v2);
- texpaint_project(ob, model, proj, view, mv[2].co, v3);
- if(mf->v4)
- texpaint_project(ob, model, proj, view, mv[3].co, v4);
+ texpaint_project(ob, model, proj, v1, pv1);
+ texpaint_project(ob, model, proj, v2, pv2);
+ texpaint_project(ob, model, proj, v3, pv3);
- return (mf->v4? 4: 3);
+ /* do inverse view mapping, see gluProject man page */
+ h[0]= (co[0] - view[0])*2.0f/view[2] - 1;
+ h[1]= (co[1] - view[1])*2.0f/view[3] - 1;
+ h[2]= 1.0f;
+
+ /* solve for (w1,w2,w3)/perspdiv in:
+ h*perspdiv = Project*Model*(w1*v1 + w2*v2 + w3*v3) */
+
+ wmat[0][0]= pv1[0]; wmat[1][0]= pv2[0]; wmat[2][0]= pv3[0];
+ wmat[0][1]= pv1[1]; wmat[1][1]= pv2[1]; wmat[2][1]= pv3[1];
+ wmat[0][2]= pv1[3]; wmat[1][2]= pv2[3]; wmat[2][2]= pv3[3];
+
+ Mat3Inv(invwmat, wmat);
+ Mat3MulVecfl(invwmat, h);
+
+ VECCOPY(w, h);
+
+ /* w is still divided by perspdiv, make it sum to one */
+ divw= w[0] + w[1] + w[2];
+ if(divw != 0.0f)
+ VecMulf(w, 1.0f/divw);
}
/* compute uv coordinates of mouse in face */
void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy, float *uv)
{
- float v1[2], v2[2], v3[2], v4[2], p[2], w[3];
- float absw, minabsw;
- int nvert;
DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
int *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
MTFace *tface = dm->getFaceDataArray(dm, CD_MTFACE), *tf;
int numfaces = dm->getNumFaces(dm), a;
+ float p[2], w[3], absw, minabsw;
MFace mf;
MVert mv[4];
minabsw = 1e10;
uv[0] = uv[1] = 0.0;
+ persp(PERSP_VIEW);
+
/* test all faces in the derivedmesh with the original index of the picked face */
for (a = 0; a < numfaces; a++) {
if (index[a] == faceindex) {
@@ -1590,18 +1399,13 @@ void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy,
tf= &tface[a];
- /* compute barycentric coordinates of point in face and interpolate uv's.
- it's ok to compute the barycentric coords on the projected positions,
- because they are invariant under affine transform */
- nvert= texpaint_projected_verts(ob, &mf, tf, mv, v1, v2, v3, v4);
-
p[0]= xy[0];
p[1]= xy[1];
- if (nvert == 4) {
- /* the triangle with the largest absolute values is the one with the
- most negative weights */
- texpaint_barycentric_2d(v1, v2, v4, p, w);
+ if (mf.v4) {
+ /* the triangle with the largest absolute values is the one
+ with the most negative weights */
+ texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[3].co, p, w);
absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
if(absw < minabsw) {
uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[3][0]*w[2];
@@ -1609,7 +1413,7 @@ void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy,
minabsw = absw;
}
- texpaint_barycentric_2d(v2, v3, v4, p, w);
+ texpaint_tri_weights(ob, mv[1].co, mv[2].co, mv[3].co, p, w);
absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
if (absw < minabsw) {
uv[0]= tf->uv[1][0]*w[0] + tf->uv[2][0]*w[1] + tf->uv[3][0]*w[2];
@@ -1618,7 +1422,7 @@ void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy,
}
}
else {
- texpaint_barycentric_2d(v1, v2, v3, p, w);
+ texpaint_tri_weights(ob, mv[0].co, mv[1].co, mv[2].co, p, w);
absw= fabs(w[0]) + fabs(w[1]) + fabs(w[2]);
if (absw < minabsw) {
uv[0]= tf->uv[0][0]*w[0] + tf->uv[1][0]*w[1] + tf->uv[2][0]*w[2];
@@ -1631,71 +1435,3 @@ void texpaint_pick_uv(Object *ob, Mesh *mesh, unsigned int faceindex, short *xy,
dm->release(dm);
}
-
- /* Selects all faces which have the same uv-texture as the active face
- * @author Roel Spruit
- * @return Void
- * Errors: - Active object not in this layer
- * - No active face or active face has no UV-texture
- */
-void get_same_uv(void)
-{
- Object *ob;
- Mesh *me;
- MTFace *tface;
- MFace *mface;
- short a, foundtex=0;
- Image *ima;
- char uvname[160];
-
- ob = OBACT;
- if (!(ob->lay & G.vd->lay)) {
- error("The active object is not in this layer");
- return;
- }
- me = get_mesh(ob);
-
-
- /* Search for the active face with a UV-Texture */
- tface = me->mtface;
- a = me->totface;
- while (a--) {
- if(tface->flag & TF_ACTIVE){
- ima=tface->tpage;
- if(ima && ima->name){
- strcpy(uvname,ima->name);
- a=0;
- foundtex=1;
- }
- }
- tface++;
- }
-
- if(!foundtex) {
- error("No active face, or active face has no UV texture");
- return;
- }
-
- /* select everything with the same texture */
- tface = me->mtface;
- mface = me->mface;
- a = me->totface;
- while (a--) {
- ima=tface->tpage;
- if(!(mface->flag & ME_HIDE) && ima && ima->name){
- if(!strcmp(ima->name, uvname)){
- mface->flag |= ME_FACE_SEL;
- }
- else mface->flag &= ~ME_FACE_SEL;
- }
- else mface->flag &= ~ME_FACE_SEL;
- tface++;
- mface++;
- }
-
- /* image window redraw */
- BIF_undo_push("Get same UV");
-
- object_tface_flags_changed(OBACT, 0);
-}
-
diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c
index a3de5d03283..ac56aec8e51 100644
--- a/source/blender/src/editfont.c
+++ b/source/blender/src/editfont.c
@@ -58,6 +58,7 @@
#include "DNA_scene_types.h"
#include "DNA_text_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_depsgraph.h"
#include "BKE_font.h"
@@ -1186,7 +1187,8 @@ void add_primitiveFont(int dummy_argument)
cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
cu->tb[0].w = cu->tb[0].h = 0.0;
- enter_editmode(EM_WAITCURSOR);
+ if (U.flag & USER_ADD_EDITMODE)
+ enter_editmode(EM_WAITCURSOR);
allqueue(REDRAWALL, 0);
}
@@ -1281,7 +1283,7 @@ static void free_undoFont(void *strv)
/* and this is all the undo system needs to know */
void undo_push_font(char *name)
{
- undo_editmode_push(name, free_undoFont, undoFont_to_editFont, editFont_to_undoFont);
+ undo_editmode_push(name, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL);
}
diff --git a/source/blender/src/editgroup.c b/source/blender/src/editgroup.c
index b17e6efee1b..fb99b57a39e 100644
--- a/source/blender/src/editgroup.c
+++ b/source/blender/src/editgroup.c
@@ -112,15 +112,15 @@ void add_selected_to_act_ob_groups(void)
}
-void rem_selected_from_group(void)
+void rem_selected_from_all_groups(void)
{
Base *base;
Group *group;
for(base=FIRSTBASE; base; base= base->next) {
if TESTBASE(base) {
-
- while( (group = find_group(base->object)) ) {
+ group = NULL;
+ while( (group = find_group(base->object, group)) ) {
rem_from_group(group, base->object);
}
base->object->flag &= ~OB_FROMGROUP;
@@ -134,6 +134,77 @@ void rem_selected_from_group(void)
BIF_undo_push("Remove from Group");
}
+
+void rem_selected_from_group(void)
+{
+ char menutext[30+(22*22)], *menupt;
+ int i=0;
+ short ret;
+ Group *group= NULL;
+ Object *ob;
+ Base *base;
+ Group *group_array[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ /* UnSet Tags for Objects and Groups */
+ for(group= G.main->group.first; group; group= group->id.next) {
+ if(group->id.lib==NULL) {
+ group->id.flag &= ~LIB_DOIT;
+ }
+ }
+ for(ob=G.main->object.first; ob; ob= ob->id.next) {
+ ob->id.flag &= ~LIB_DOIT;
+ }
+
+ /* Not tag selected objects */
+ for(base=FIRSTBASE; base; base= base->next) {
+ if TESTBASELIB(base) {
+ base->object->id.flag |= LIB_DOIT;
+ }
+ }
+
+ menupt = menutext;
+ /* Build a list of groups that contain selected objects */
+ for(group= G.main->group.first; group && i<24; group= group->id.next) {
+ if(group->id.lib==NULL) {
+ GroupObject *go;
+ for(go= group->gobject.first; go; go= go->next) {
+ if(go->ob->id.flag & LIB_DOIT) {
+ group_array[i] = group;
+ menupt += sprintf(menupt, "|%s", group->id.name+2);
+ i++;
+ break; /* Only want to know if this group should go in the list*/
+ }
+ }
+ }
+ }
+
+ /* do we have any groups? */
+ if (group_array[0] == NULL) {
+ error("Object selection contains no groups");
+ } else {
+ ret = pupmenu(menutext);
+ if (ret==-1) {
+ return;
+ } else {
+ group = group_array[ret-1];
+ for(base=FIRSTBASE; base; base= base->next) {
+ if TESTBASELIB(base) {
+ /* if we are removed and are not in any group, set our flag */
+ if(rem_from_group(group, base->object) && find_group(base->object, NULL)==NULL) {
+ base->object->flag &= ~OB_FROMGROUP;
+ base->flag &= ~OB_FROMGROUP;
+ }
+ }
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ DAG_scene_sort(G.scene);
+ BIF_undo_push("Remove from Group");
+}
+
void group_operation_with_menu(void)
{
Group *group= NULL;
@@ -145,7 +216,7 @@ void group_operation_with_menu(void)
break;
if(group)
- mode= pupmenu("Groups %t|Add to Existing Group %x3|Add to Active Objects Groups %x4|Add to New Group %x1|Remove from All Groups %x2");
+ mode= pupmenu("Groups %t|Add to Existing Group %x3|Add to Active Objects Groups %x4|Add to New Group %x1|Remove from Group %x5|Remove from All Groups %x2");
else
mode= pupmenu("Groups %t|Add to New Group %x1|Remove from All Groups %x2");
@@ -173,7 +244,7 @@ void group_operation(int mode)
strp1 += sprintf(strp1, "%s %%x%d|", group->id.name+2, tot);
}
}
- tot= pupmenu(strp);
+ tot= pupmenu_col(strp, 20);
MEM_freeN(strp);
if(tot>0) group= BLI_findlink(&G.main->group, tot-1);
else return;
@@ -181,6 +252,7 @@ void group_operation(int mode)
if(mode==4) add_selected_to_act_ob_groups();
else if(mode==1 || mode==3) add_selected_to_group(group);
- else if(mode==2) rem_selected_from_group();
+ else if(mode==2) rem_selected_from_all_groups();
+ else if(mode==5) rem_selected_from_group();
}
}
diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c
index f3f9aa31d07..e93687fef93 100644
--- a/source/blender/src/editimasel.c
+++ b/source/blender/src/editimasel.c
@@ -43,411 +43,1123 @@
#include <sys/times.h>
#endif
-#include "PIL_time.h"
+#include "MEM_guardedalloc.h"
+
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_depsgraph.h"
+#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_storage_types.h"
-#include "DNA_screen_types.h"
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_image_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_texture_types.h"
#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_vfont_types.h"
+#include "DNA_view3d_types.h"
-#include "BKE_global.h"
-#include "BIF_fsmenu.h"
+#include "BIF_filelist.h"
+#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_interface.h"
-#include "BIF_imasel.h"
#include "BIF_mywindow.h"
+#include "BIF_imasel.h"
+#include "BIF_gl.h"
+#include "BIF_fsmenu.h"
+#include "BIF_editview.h"
#include "BIF_toolbox.h"
-#include "BSE_filesel.h"
+#include "BLO_readfile.h"
+
+#include "BSE_drawipo.h"
#include "BSE_drawimasel.h"
+#include "BSE_edit.h"
-#include "BDR_editcurve.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
#include "blendef.h"
#include "mydevice.h"
-#define XIC 20
-#define YIC 21
+/* for events */
+#define NOTACTIVE 0
+#define ACTIVATE 1
+#define INACTIVATE 2
+/* for state of file */
+#define ACTIVE 2
-/* GLOBALS */
-extern char *fsmenu;
+static void imasel_select_objects(SpaceImaSel *simasel);
-void winqreadimaselspace(ScrArea *, void *, BWinEvent *);
+static int imasel_has_func(SpaceImaSel *simasel)
+{
+ if(simasel->returnfunc || simasel->returnfunc_event || simasel->returnfunc_args)
+ return 1;
+ return 0;
+}
-void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
+#if defined __BeOS
+static int fnmatch(const char *pattern, const char *string, int flags)
+{
+ return 0;
+}
+#elif defined WIN32 && !defined _LIBC
+ /* use fnmatch included in blenlib */
+ #include "BLI_fnmatch.h"
+#else
+ #include <fnmatch.h>
+#endif
+
+static void imasel_split_file(SpaceImaSel *simasel, char *s1)
+{
+ char string[FILE_MAX], dir[FILE_MAX], file[FILE_MAX];
+
+ BLI_strncpy(string, s1, sizeof(string));
+
+ BLI_split_dirfile(string, dir, file);
+
+ if(simasel->files) {
+ BIF_filelist_free(simasel->files);
+ }
+ BLI_strncpy(simasel->file, file, sizeof(simasel->file));
+ BLI_strncpy(simasel->dir, dir, sizeof(simasel->dir));
+
+ BIF_filelist_setdir(simasel->files, dir);
+
+ BLI_make_file_string(G.sce, simasel->dir, dir, "");
+}
+
+/**************** IMAGESELECT ******************************/
+
+/* the complete call; pulldown menu, and three callback types */
+static void activate_imageselect_(int type, char *title, char *file, short *menup, char *pupmenu,
+ void (*func)(char *),
+ void (*func_event)(unsigned short),
+ void (*func_args)(char *, void *arg1, void *arg2),
+ void *arg1, void *arg2)
{
- unsigned short event= evt->event;
- short val= evt->val;
SpaceImaSel *simasel;
+ char group[24], name[FILE_MAX], temp[FILE_MAX];
- short mval[2];
- short area_event;
- short queredraw = 0;
- int ret = 0;
- char name[256];
- char *selname;
- static double prevtime=0;
+ if(curarea==0) return;
+ if(curarea->win==0) return;
+
+ newspace(curarea, SPACE_IMASEL);
+ scrarea_queue_winredraw(curarea);
+
+ /* sometime double, when area already is SPACE_IMASEL with a different file name */
+ if(curarea->headwin) addqueue(curarea->headwin, CHANGED, 1);
+
+ name[2]= 0;
+ BLI_strncpy(name, file, sizeof(name));
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
- if(val==0) return;
simasel= curarea->spacedata.first;
+
+ simasel->returnfunc= func;
+ simasel->returnfunc_event= func_event;
+ simasel->returnfunc_args= func_args;
+ simasel->arg1= arg1;
+ simasel->arg2= arg2;
- area_event = 0;
- getmouseco_areawin(mval);
- simasel->mx= mval[0];
- simasel->my= mval[1];
+ simasel->type= type;
+ simasel->scrollpos = 0.0f;
+
+ if(simasel->pupmenu)
+ MEM_freeN(simasel->pupmenu);
+ simasel->pupmenu= pupmenu;
+ simasel->menup= menup;
- if (simasel->desx > 0){
- if ( (mval[0] > simasel->dssx) && (mval[0] < simasel->dsex) && (mval[1] > simasel->dssy) && (mval[1] < simasel->dsey) ) area_event = IMS_INDIRSLI;
- if ( (mval[0] > simasel->desx) && (mval[0] < simasel->deex) && (mval[1] > simasel->desy) && (mval[1] < simasel->deey) ) area_event = IMS_INDIR;
+ /* sfile->act is used for databrowse: double names of library objects */
+ simasel->active_file= -1;
+
+ if(!simasel->files) {
+ simasel->files = BIF_filelist_new();
+ }
+
+ if(G.relbase_valid && U.flag & USER_RELPATHS && type != FILE_BLENDER)
+ simasel->flag |= FILE_STRINGCODE;
+ else
+ simasel->flag &= ~FILE_STRINGCODE;
+
+ if (U.uiflag & USER_HIDE_DOT)
+ simasel->flag |= FILE_HIDE_DOT;
+
+ if(type==FILE_MAIN) {
+ char *groupname;
+
+ BLI_strncpy(simasel->file, name+2, sizeof(simasel->file));
+
+ groupname = BLO_idcode_to_name( GS(name) );
+ if (groupname) {
+ BLI_strncpy(simasel->dir, groupname, sizeof(simasel->dir) - 1);
+ strcat(simasel->dir, "/");
+ }
+
+ /* free all */
+ if (simasel->files) {
+ BIF_filelist_freelib(simasel->files);
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ BIF_filelist_settype(simasel->files, type);
+ }
+ }
+ else if(type==FILE_LOADLIB) {
+
+ if( BIF_filelist_islibrary(simasel->files, temp, group) ) {
+ /* force a reload of the library-filelist */
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_freelib(simasel->files);
+ BLI_strncpy(simasel->dir, name, sizeof(simasel->dir));
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ BIF_filelist_settype(simasel->files, type);
+ }
+ else {
+ imasel_split_file(simasel, name);
+ BIF_filelist_freelib(simasel->files);
+ BIF_filelist_settype(simasel->files, type);
+ }
}
- if (simasel->fesx > 0){
- if ( (mval[0] > simasel->fssx) && (mval[0] < simasel->fsex) && (mval[1] > simasel->fssy) && (mval[1] < simasel->fsey) ) area_event = IMS_INFILESLI;
- if ( (mval[0] > simasel->fesx) && (mval[0] < simasel->feex) && (mval[1] > simasel->fesy) && (mval[1] < simasel->feey) ) area_event = IMS_INFILE;
- }
+ else { /* FILE_BLENDER */
+ imasel_split_file(simasel, name);
+ BIF_filelist_settype(simasel->files, type);
+
+ BLI_cleanup_dir(G.sce, simasel->dir);
+
+ /* free: filelist and libfiledata became incorrect */
+ BIF_filelist_freelib(simasel->files);
+ }
+ BLI_strncpy(simasel->title, title, sizeof(simasel->title));
+ /* filetoname= 1; */ /* TODO: elubie - check what this means */
+}
+
+void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
+{
+ activate_imageselect_(type, title, file, NULL, NULL, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_imageselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *))
+{
+ activate_imageselect_(type, title, file, menup, pupmenu, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_imageselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2)
+{
+ activate_imageselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2);
+}
+
+void activate_databrowse_imasel(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short))
+{
+ ListBase *lb;
+ SpaceImaSel *simasel;
+ char str[32];
- if( event!=RETKEY && event!=PADENTER)
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
-
- switch(event) {
- case AFTERPIBREAD:
- get_pib_file(simasel);
- queredraw = 1;
- break;
-
- case AFTERIMASELIMA:
- if (bitset(simasel->fase, IMS_DOTHE_INF)){
- get_file_info(simasel);
-
- if (!bitset(simasel->fase, IMS_KNOW_INF)){
- addafterqueue(curarea->win, AFTERIMASELIMA, 1);
-
- }else{
- simasel->subfase = 0;
- simasel->imafase = 0;
- simasel->fase |= IMS_DOTHE_IMA;
- addafterqueue(curarea->win, AFTERIMASELGET, 1);
+ if(id==NULL) {
+ lb= wich_libbase(G.main, idcode);
+ id= lb->first;
+ }
+
+ if(id) BLI_strncpy(str, id->name, sizeof(str));
+ else return;
+
+ activate_imageselect_(FILE_MAIN, "SELECT DATABLOCK", str, menup, NULL, NULL, func, NULL, NULL, NULL);
+
+ simasel= curarea->spacedata.first;
+ simasel->retval= retval;
+ simasel->menup= menup;
+
+ BIF_filelist_setipotype(simasel->files, fromcode);
+ BIF_filelist_hasfunc(simasel->files, imasel_has_func(simasel));
+}
+
+
+static void set_active_file(SpaceImaSel *simasel, short x, short y)
+{
+ short tilex, tiley;
+ int active_tile;
+ int active_file;
+ int stridex;
+ struct direntry* file;
+ rcti viewrect = simasel->viewrect;
+ int fileoffset;
+ int rowoffset;
+ int rowleftover;
+ float scrollofs;
+ int numfiles;
+ int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+ int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+
+ numfiles = BIF_filelist_numfiles(simasel->files);
+
+ if (simasel->numtilesx > 0) {
+ fileoffset = numfiles*(simasel->scrollpos / simasel->scrollarea) + 0.5;
+ rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx;
+ rowleftover = fileoffset % simasel->numtilesx;
+ scrollofs = (float)tileheight*(float)rowleftover/(float)simasel->numtilesx;
+
+ stridex = (viewrect.xmax - viewrect.xmin) / (tilewidth);
+ tilex = ( (x-viewrect.xmin)) / (tilewidth);
+ tiley = (viewrect.ymax - viewrect.ymin + scrollofs - y) / (tileheight);
+ if (tilex >= simasel->numtilesx) tilex = simasel->numtilesx-1;
+ if (tiley >= simasel->numtilesy+1) tiley = simasel->numtilesy;
+ if (tilex < 0) tilex=0;
+ if (tiley < 0) tiley = 0;
+ active_tile = tilex + stridex*tiley;
+ active_file = rowoffset + active_tile;
+
+ if (active_file >= 0 && active_file < BIF_filelist_numfiles(simasel->files) )
+ {
+ simasel->active_file = active_file;
+ if (simasel->selstate & ACTIVATE) {
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ file->flags |= ACTIVE;
}
+ } else {
+ simasel->active_file = -1;
+ }
+ } else {
+ simasel->active_file = -1;
+ }
+}
+
+static void set_active_bookmark(SpaceImaSel *simasel, short y)
+{
+ int nentries = fsmenu_get_nentries();
+ short posy = simasel->bookmarkrect.ymax - TILE_BORDER_Y - y;
+ simasel->active_bookmark = ((float)posy / (U.fontsize*3.0f/2.0f));
+ if (simasel->active_bookmark < 0 || simasel->active_bookmark > nentries) {
+ simasel->active_bookmark = -1;
+ }
+}
+
+static void imasel_prevspace()
+{
+ SpaceImaSel *simasel;
+
+ simasel= curarea->spacedata.first;
+
+ /* cleanup */
+ if(simasel->spacetype==SPACE_IMASEL) {
+ if(simasel->pupmenu) {
+ MEM_freeN(simasel->pupmenu);
+ simasel->pupmenu= NULL;
+ }
+ }
+
+ if(simasel->next) {
+
+ BLI_remlink(&curarea->spacedata, simasel);
+ BLI_addtail(&curarea->spacedata, simasel);
+
+ simasel= curarea->spacedata.first;
+
+ if (simasel->spacetype == SPACE_SCRIPT) {
+ SpaceScript *sc = (SpaceScript *)simasel;
+ if (sc->script) sc->script->flags &=~SCRIPT_FILESEL;
}
- break;
- case AFTERIMASELGET:
- if (bitset(simasel->fase, IMS_DOTHE_IMA)){
- get_next_image(simasel);
- if (simasel->ima_redraw > 0){
- double newtime = PIL_check_seconds_timer();
- if ((newtime - prevtime) > 0.03) {
- simasel->ima_redraw = 0;
- queredraw = 1;
- prevtime = newtime;
+
+ newspace(curarea, simasel->spacetype);
+ }
+ else newspace(curarea, SPACE_INFO);
+}
+
+static void free_imasel_spec(char *dir)
+{
+ /* all filesels with 'dir' are freed */
+ bScreen *sc;
+
+ sc= G.main->screen.first;
+ while(sc) {
+ ScrArea *sa= sc->areabase.first;
+ while(sa) {
+ SpaceLink *sl= sa->spacedata.first;
+ while(sl) {
+ if(sl->spacetype==SPACE_FILE) {
+ SpaceImaSel *simasel= (SpaceImaSel*) sl;
+ if (BLI_streq(simasel->dir, dir)) {
+ BIF_filelist_free(simasel->files);
+ }
}
-
+ sl= sl->next;
}
- if (!bitset(simasel->fase, IMS_KNOW_IMA)){
- addafterqueue(curarea->win, AFTERIMASELGET, 1);
- }else{
- simasel->ima_redraw = 0;
- simasel->subfase = 0;
- simasel->imafase = 0;
- addqueue(curarea->win, AFTERIMAWRITE, 1);
- queredraw = 1;
+ sa= sa->next;
+ }
+ sc= sc->id.next;
+ }
+}
+
+static void do_library_append(SpaceImaSel *simasel)
+{
+ Library *lib;
+ char dir[FILE_MAXDIR], group[32];
+
+ if ( BIF_filelist_islibrary(simasel->files, dir, group)==0 ) {
+ error("Not a library");
+ } else if (!BIF_filelist_lib(simasel->files) ) {
+ error("Library not loaded");
+ } else if (group[0]==0) {
+ error("Nothing indicated");
+ } else if (BLI_streq(G.main->name, dir)) {
+ error("Cannot use current file as library");
+ } else {
+ Object *ob;
+ int idcode = BIF_groupname_to_code(group);
+
+ if((simasel->flag & FILE_LINK)==0) {
+ /* tag everything, all untagged data can be made local */
+ ID *id;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a;
+
+ a= set_listbasepointers(G.main, lbarray);
+ while(a--) {
+ for(id= lbarray[a]->first; id; id= id->next) id->flag |= LIB_APPEND_TAG;
}
}
- break;
- case AFTERIMAWRITE:
- if (bitset(simasel->fase, IMS_KNOW_IMA)){
- write_new_pib(simasel);
- queredraw = 1;
+
+ BIF_filelist_append_library(simasel->files, dir, simasel->file, simasel->flag, idcode);
+
+ /* DISPLISTS? */
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->id.lib) {
+ ob->recalc |= OB_RECALC;
+ }
+ ob= ob->id.next;
}
- break;
- case RIGHTMOUSE:
- if ((area_event == IMS_INFILE) && (simasel->hilite_ima)){
- select_ima_files(simasel);
- queredraw = 1;
+ /* and now find the latest append lib file */
+ lib= G.main->library.first;
+ while(lib) {
+ if (BLI_streq(dir, lib->filename)) break;
+ lib= lib->id.next;
}
- break;
- case UI_BUT_EVENT:
- /* bug: blender's interface kit also returns a '4'... what is it! */
+ /* make local */
+ if(lib) {
+ if((simasel->flag & FILE_LINK)==0)
+ all_local(lib,1);
+ }
- switch(val) {
- case 13: /* 'P' */
- imadir_parent(simasel);
- queredraw = 1;
-
- case 1: /* dir entry */
- BLI_cleanup_dir(G.sce, simasel->dir);
- clear_ima_dir(simasel);
- queredraw = 1;
- break;
+ DAG_scene_sort(G.scene);
+
+ /* in sfile->dir is the whole lib name */
+ BLI_strncpy(G.lib, simasel->dir, sizeof(G.lib) );
- case 3: /* fsmenu */
- selname= fsmenu_get_entry(simasel->fileselmenuitem-1);
- if (selname) {
- strcpy(simasel->dir, selname);
- BLI_cleanup_dir(G.sce, simasel->dir);
- clear_ima_dir(simasel);
- queredraw = 1;
- }
- break;
+ }
+}
- case 5:
- if (simasel->returnfunc) {
- char name[256];
- strcpy(name, simasel->dir);
- strcat(name, simasel->file);
- filesel_prevspace();
- simasel->returnfunc(name);
+/* NOTE: this is called for file read, after the execfunc no UI memory is valid! */
+static void imasel_execute(SpaceImaSel *simasel)
+{
+ struct direntry *file;
+ char name[FILE_MAX];
+ int a;
+ int n;
+
+ imasel_prevspace();
+
+ if(simasel->type==FILE_LOADLIB) {
+ if(simasel->flag & FILE_STRINGCODE) {
+ if (!G.relbase_valid) {
+ okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
+ simasel->flag &= ~FILE_STRINGCODE;
}
- break;
- case 6:
- filesel_prevspace();
- break;
-
}
- break;
-
- case LEFTMOUSE:
- case MIDDLEMOUSE:
+
+ do_library_append(simasel);
+ BIF_undo_push("Append from file");
+ allqueue(REDRAWALL, 1);
+ }
+ else if(imasel_has_func(simasel)) {
+ fsmenu_insert_entry(simasel->dir, 1, 0);
- /* No button pressed */
- switch (area_event){
- case IMS_INDIRSLI:
- move_imadir_sli(simasel);
- queredraw = 1;
- break;
- case IMS_INFILESLI:
- move_imafile_sli(simasel);
- queredraw = 1;
- break;
- case IMS_INDIR:
- if (simasel->hilite > -1){
- change_imadir(simasel);
- queredraw = 1;
- }
- break;
- case IMS_INFILE:
- if (simasel->hilite_ima){
- strcpy(simasel->fole, simasel->hilite_ima->file_name);
- strcpy(simasel->file, simasel->hilite_ima->file_name);
-
- if (event == LEFTMOUSE) addqueue(curarea->win, IMALEFTMOUSE, 1);
-
- if ((event == MIDDLEMOUSE)&&(simasel->returnfunc)){
- strcpy(name, simasel->dir);
- strcat(name, simasel->file);
-
- if(simasel->mode & IMS_STRINGCODE) BLI_makestringcode(G.sce, name);
+ if(simasel->type==FILE_MAIN) { /* DATABROWSE */
+ if (simasel->menup) { /* with value pointing to ID block index */
+ int notfound = 1;
+
+ /* Need special handling since hiding .* datablocks means that
+ simasel->active_file is no longer the same as files->nr.
+
+ Also, toggle HIDE_DOT on and off can make simasel->active_file not longer
+ correct (meaning it doesn't point to the correct item in the filelist.
- filesel_prevspace();
- simasel->returnfunc(name);
+ simasel->file is always correct, so first with check if, for the item
+ corresponding to simasel->active_file, the name is the same.
+
+ If it isn't (or if simasel->active_file is not good), go over filelist and take
+ the correct one.
+
+ This means that selecting a datablock than hiding it makes it
+ unselectable. Not really a problem.
+
+ - theeth
+ */
+
+ *simasel->menup= -1;
+ n = BIF_filelist_numfiles(simasel->files);
+ if(simasel->files) {
+ if( (simasel->active_file>=0) && (simasel->active_file < n) ) {
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ if ( strcmp(file->relname, simasel->file)==0) {
+ notfound = 0;
+ *simasel->menup= file->nr;
+ }
+ }
+ if (notfound) {
+ for(a=0; a<n; a++) {
+ file = BIF_filelist_file(simasel->files, a);
+ if( strcmp(file->relname, simasel->file)==0) {
+ *simasel->menup= file->nr;
+ break;
+ }
+ }
+ }
}
- queredraw = 1;
}
- break;
+ if(simasel->returnfunc_event)
+ simasel->returnfunc_event(simasel->retval);
+ else if(simasel->returnfunc_args)
+ simasel->returnfunc_args(NULL, simasel->arg1, simasel->arg2);
}
- break;
+ else {
+ if(strncmp(simasel->title, "Save", 4)==0) free_imasel_spec(simasel->dir);
+ if(strncmp(simasel->title, "Export", 6)==0) free_imasel_spec(simasel->dir);
+
+ BLI_strncpy(name, simasel->dir, sizeof(name));
+ strcat(name, simasel->file);
+
+ if(simasel->flag & FILE_STRINGCODE) {
+ /* still weak, but we don't want saving files to make relative paths */
+ if(G.relbase_valid && strncmp(simasel->title, "Save", 4)) {
+ BLI_makestringcode(G.sce, name);
+ } else {
+ /* if we don't have a valid relative base (.blend file hasn't been saved yet)
+ then we don't save the path as relative (for texture images, background image).
+ Warning message not shown when saving files (doesn't make sense there)
+ */
+ if (strncmp(simasel->title, "Save", 4)) {
+ printf("Relative path setting has been ignored because .blend file hasn't been saved yet.\n");
+ }
+ simasel->flag &= ~FILE_STRINGCODE;
+ }
+ }
+ if(simasel->returnfunc)
+ simasel->returnfunc(name);
+ else if(simasel->returnfunc_args)
+ simasel->returnfunc_args(name, simasel->arg1, simasel->arg2);
+ }
+ }
+}
+
+static void do_imasel_buttons(short event, SpaceImaSel *simasel)
+{
+ char butname[FILE_MAX];
- case MOUSEX:
- case MOUSEY:
- getmouseco_areawin(mval); /* local screen coordinates */
- calc_hilite(simasel);
- if (simasel->mouse_move_redraw ){
- simasel->mouse_move_redraw = 0;
- queredraw = 1;
+ if (event == B_FS_FILENAME) {
+ if (strchr(simasel->file, '*') || strchr(simasel->file, '?') || strchr(simasel->file, '[')) {
+ int i, match = FALSE;
+ struct direntry *file;
+ int n = BIF_filelist_numfiles(simasel->files);
+ for (i = 2; i < n; i++) {
+ file = BIF_filelist_file(simasel->files, i);
+ if (fnmatch(simasel->file, file->relname, 0) == 0) {
+ file->flags |= ACTIVE;
+ match = TRUE;
+ }
+ }
+ if (match) simasel->file[0] = '\0';
+ if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+ scrarea_queue_winredraw(curarea);
}
- break;
+ }
+ else if(event== B_FS_DIRNAME) {
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- switch(area_event){
- case IMS_INDIRSLI:
- case IMS_INDIR:
- if (simasel->dirsli){
- if (event == WHEELUPMOUSE) simasel->topdir -= U.wheellinescroll;
- if (event == WHEELDOWNMOUSE) simasel->topdir += U.wheellinescroll;
- queredraw = 1;
+ /* convienence shortcut '~' -> $HOME
+ * If the first char is ~ then this is invalid on all OS's so its safe to replace with home */
+ if ( simasel->dir[0] == '~' ) {
+ if (simasel->dir[1] == '\0') {
+ BLI_strncpy(simasel->dir, BLI_gethome(), sizeof(simasel->dir) );
+ } else {
+ /* replace ~ with home */
+ char tmpstr[FILE_MAX];
+ BLI_join_dirfile(tmpstr, BLI_gethome(), simasel->dir+1);
+ BLI_strncpy(simasel->dir, tmpstr, sizeof(simasel->dir));
}
- break;
- case IMS_INFILESLI:
- case IMS_INFILE:
- if(simasel->imasli){
- if (event == WHEELUPMOUSE) simasel->image_slider -= 0.2 * simasel->slider_height;
- if (event == WHEELDOWNMOUSE) simasel->image_slider += 0.2 * simasel->slider_height;
-
- if(simasel->image_slider < 0.0) simasel->image_slider = 0.0;
- if(simasel->image_slider > 1.0) simasel->image_slider = 1.0;
- queredraw = 1;
- }
- break;
}
- break;
-
- case PAGEUPKEY:
- case PAGEDOWNKEY:
- switch(area_event){
- case IMS_INDIRSLI:
- case IMS_INDIR:
- if (simasel->dirsli){
- if (event == PAGEUPKEY) simasel->topdir -= (simasel->dirsli_lines - 1);
- if (event == PAGEDOWNKEY) simasel->topdir += (simasel->dirsli_lines - 1);
- queredraw = 1;
+
+ /* reuse the butname vsariable */
+ BLI_cleanup_dir(G.sce, simasel->dir);
+
+ BLI_make_file_string(G.sce, butname, simasel->dir, "");
+ BLI_strncpy(simasel->dir, butname, sizeof(simasel->dir));
+
+ /* strip the trailing slash if its a real dir */
+ if (strlen(butname)!=1)
+ butname[strlen(butname)-1]=0;
+
+ /* updating the directory in the filelist */
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+
+ if(simasel->type & FILE_UNIX) {
+ if (!BLI_exists(butname)) {
+ if (okee("Makedir")) {
+ BLI_recurdir_fileops(butname);
+ if (!BLI_exists(butname)) {
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_parent(simasel->files);
+ BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+ }
+ } else {
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_parent(simasel->files);
+ BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+ }
}
- break;
- case IMS_INFILESLI:
- case IMS_INFILE:
- if(simasel->imasli){
- if (event == PAGEUPKEY) simasel->image_slider -= simasel->slider_height;
- if (event == PAGEDOWNKEY) simasel->image_slider += simasel->slider_height;
-
- if(simasel->image_slider < 0.0) simasel->image_slider = 0.0;
- if(simasel->image_slider > 1.0) simasel->image_slider = 1.0;
- queredraw = 1;
- }
- break;
}
- break;
-
- case HOMEKEY:
- simasel->image_slider = 0.0;
- queredraw = 1;
- break;
-
- case ENDKEY:
- simasel->image_slider = 1.0;
- queredraw = 1;
- break;
-
- case AKEY:
- if (G.qual == 0){
- ima_select_all(simasel);
- queredraw = 1;
+ BIF_filelist_free(simasel->files);
+ simasel->file[0] = '\0';
+ simasel->scrollpos = 0;
+ simasel->active_file = -1;
+ scrarea_queue_winredraw(curarea);
+ }
+ else if(event== B_FS_DIR_MENU) {
+ char *selected= fsmenu_get_entry(simasel->menu-1);
+
+ /* which string */
+ if (selected) {
+ BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir));
+ BLI_cleanup_dir(G.sce, simasel->dir);
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ simasel->file[0] = '\0';
+ simasel->scrollpos = 0;
+ simasel->active_file = -1;
+ scrarea_queue_redraw(curarea);
}
- break;
- case IKEY:
- if ((G.qual == 0)&&(simasel->file)){
- sprintf(name, "$IMAGEEDITOR %s%s", simasel->dir, simasel->file);
- system(name);
- queredraw = 1;
+ simasel->active_file = -1;
+
+ }
+ else if(event== B_FS_PARDIR) {
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_parent(simasel->files);
+ BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+ simasel->file[0] = '\0';
+ simasel->active_file = -1;
+ simasel->scrollpos = 0;
+ scrarea_queue_redraw(curarea);
+ }
+ else if(event== B_FS_LOAD) {
+ if(simasel->type)
+ imasel_execute(simasel);
+ }
+ else if(event== B_FS_CANCEL)
+ imasel_prevspace();
+ else if(event== B_FS_LIBNAME) {
+ Library *lib= BLI_findlink(&G.main->library, simasel->menu);
+ if(lib) {
+ BLI_strncpy(simasel->dir, lib->filename, sizeof(simasel->dir));
+ BLI_make_exist(simasel->dir);
+ BLI_cleanup_dir(G.sce, simasel->dir);
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ simasel->file[0] = '\0';
+ simasel->scrollpos = 0;
+ simasel->active_file = -1;
+ scrarea_queue_winredraw(curarea);
}
+ } else if(event== B_FS_BOOKMARK) {
+ char name[FILE_MAX];
+ BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
+ fsmenu_insert_entry(simasel->dir, 1, 1);
+ scrarea_queue_winredraw(curarea);
+ fsmenu_write_file(name);
+ }
+
+}
- break;
+static void imasel_home(ScrArea *sa, SpaceImaSel *simasel)
+{
+ simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f;
+ simasel->v2d.cur.xmax= sa->winx;
+ simasel->v2d.cur.ymax= sa->winy;
- case PKEY:
- if(G.qual & LR_SHIFTKEY) {
- extern char bprogname[]; /* usiblender.c */
-#ifdef WIN32
- sprintf(name, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
-#else
- sprintf(name, "\"%s\" -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
-#endif
- system(name);
+ simasel->v2d.tot= simasel->v2d.cur;
+ test_view2d(G.v2d, sa->winx, sa->winy);
+
+}
+
+static struct direntry* get_hilited_entry(SpaceImaSel *simasel)
+{
+ struct direntry *file;
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ return file;
+}
+
+static void do_filescroll(SpaceImaSel *simasel)
+{
+ short mval[2], oldy, yo;
+ float scrollarea, scrollstep;
+
+ /* for beauty */
+ scrarea_do_windraw(curarea);
+ screen_swapbuffers();
+
+ getmouseco_areawin(mval);
+ oldy= yo= mval[1];
+
+ while(get_mbut()&L_MOUSE) {
+ getmouseco_areawin(mval);
+
+ if(yo!=mval[1]) {
+ scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ scrollstep = yo - mval[1];
+ simasel->scrollpos += scrollstep;
+
+ if (simasel->scrollpos<0)
+ simasel->scrollpos=0;
+ if (simasel->scrollpos > scrollarea - simasel->scrollheight)
+ simasel->scrollpos = scrollarea - simasel->scrollheight;
+ scrarea_do_windraw(curarea);
+ screen_swapbuffers();
+
+ yo= mval[1];
}
- if(G.qual & LR_CTRLKEY) {
- if(bitset(simasel->fase, IMS_KNOW_IMA)) pibplay(simasel);
+ else BIF_wait_for_statechange();
+ }
+
+ /* for beauty */
+ scrarea_do_windraw(curarea);
+ screen_swapbuffers();
+
+}
+
+/* ******************* DATA SELECT ********************* */
+
+static void imasel_select_objects(SpaceImaSel *simasel)
+{
+ Object *ob;
+ Base *base;
+ Scene *sce;
+ struct direntry* file;
+ int a;
+ int totfile;
+
+ /* only when F4 DATABROWSE */
+ if(imasel_has_func(simasel)) return;
+
+ totfile = BIF_filelist_numfiles(simasel->files);
+
+ if( strcmp(simasel->dir, "Object/")==0 ) {
+ for(a=0; a<totfile; a++) {
+ file = BIF_filelist_file(simasel->files, a);
+ ob= (Object *)file->poin;
+
+ if(ob) {
+ if(file->flags & ACTIVE) ob->flag |= SELECT;
+ else ob->flag &= ~SELECT;
+ }
+
}
- if (G.qual == 0){
- imadir_parent(simasel);
- BLI_cleanup_dir(G.sce, simasel->dir);
- clear_ima_dir(simasel);
- queredraw = 1;
+ base= FIRSTBASE;
+ while(base) {
+ base->flag= base->object->flag;
+ base= base->next;
}
- break;
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ else if( strcmp(simasel->dir, "Scene/")==0 ) {
- case RKEY:
- case XKEY:
- if (simasel->hilite_ima){
- strcpy(name, simasel->dir);
- strcat(name, simasel->hilite_ima->file_name);
-
- if( okee("Delete %s", name) ) {
- ret = BLI_delete(name, 0, 0);
- if (ret) {
- error("Command failed, see console");
- } else {
- clear_ima_dir(simasel);
- queredraw = 1;
- }
+ for(a=0; a<totfile; a++) {
+ file = BIF_filelist_file(simasel->files, a);
+ sce= (Scene *)file->poin;
+ if(sce) {
+ if(file->flags & ACTIVE) sce->r.scemode |= R_BG_RENDER;
+ else sce->r.scemode &= ~R_BG_RENDER;
}
+
}
- break;
+ allqueue(REDRAWBUTSSCENE, 0);
+ }
+}
- case PADPLUSKEY:
- case EQUALKEY:
- BLI_newname(simasel->file, +1);
- queredraw = 1;
- break;
-
- case PADMINUS:
- case MINUSKEY:
- BLI_newname(simasel->file, -1);
- queredraw = 1;
- break;
-
- case BACKSLASHKEY:
- case SLASHKEY:
-#ifdef WIN32
- strcpy(simasel->dir, "\\");
-#else
- strcpy(simasel->dir, "/");
-#endif
- clear_ima_dir(simasel);
- simasel->image_slider = 0.0;
- queredraw = 1;
- break;
-
- case PERIODKEY:
- clear_ima_dir(simasel);
- queredraw = 1;
- break;
+static void active_imasel_object(SpaceImaSel *simasel)
+{
+ Object *ob;
+ struct direntry* file;
+
+ /* only when F4 DATABROWSE */
+ if(imasel_has_func(simasel)) return;
- case ESCKEY:
- filesel_prevspace();
- break;
-
- case PADENTER:
- case RETKEY:
- if (simasel->returnfunc){
- strcpy(name, simasel->dir);
- strcat(name, simasel->file);
- filesel_prevspace();
- simasel->returnfunc(name);
+ if( strcmp(simasel->dir, "Object/")==0 ) {
+ int n = BIF_filelist_numfiles(simasel->files);
+ if(simasel->active_file >= 0 && simasel->active_file < n) {
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ ob= (Object *)file->poin;
+
+ if(ob) {
+ set_active_object(ob);
+ if(BASACT && BASACT->object==ob) {
+ BASACT->flag |= SELECT;
+ file->flags |= ACTIVE;
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWOOPS, 0);
+ scrarea_queue_winredraw(curarea);
+ }
+ }
}
- break;
}
+}
+
+
+
+void winqreadimaselspace(ScrArea *, void *, BWinEvent *);
+
+
+void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
+{
+ unsigned short event= evt->event;
+ short val= evt->val;
+ SpaceImaSel *simasel;
+ char str[FILE_MAXDIR+FILE_MAXFILE+12];
+ short mval[2];
+ short do_draw = 0;
+ short do_headdraw = 0;
+ int numfiles;
+ struct direntry *file;
+ float scrollstep = 0;
+ float scrollarea;
+
+ // if(val==0) return;
+ simasel= curarea->spacedata.first;
+
+ if (!simasel->files)
+ return;
+
+ if (BIF_filelist_empty(simasel->files))
+ return;
+
+ numfiles = BIF_filelist_numfiles(simasel->files);
+
+ /* calc_scrollrcts(sa, &(simasel->v2d), sa->winx, sa->winy); */
+ calc_imasel_rcts(simasel, sa->winx, sa->winy);
+
+ /* prevent looping */
+ if(simasel->selstate && !(get_mbut() & R_MOUSE)) simasel->selstate= 0;
+
+ if(val) {
+
+ if( event!=RETKEY && event!=PADENTER)
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
+
+ switch(event) {
- if (queredraw) scrarea_queue_winredraw(curarea);
+ case UI_BUT_EVENT:
+ do_imasel_buttons(val, simasel);
+ break;
+ case RENDERPREVIEW:
+ do_draw= 1;
+ /* draw_imasel_previews(sa, simasel); */
+ break;
+ case REDRAWIMASEL:
+ do_draw= 1;
+ break;
+ case WHEELDOWNMOUSE:
+ numfiles = BIF_filelist_numfiles(simasel->files);
+ scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx;
+ simasel->scrollpos += scrollstep;
+ if (simasel->scrollpos > scrollarea - simasel->scrollheight)
+ simasel->scrollpos = scrollarea - simasel->scrollheight;
+ do_draw= 1;
+ break;
+ case WHEELUPMOUSE:
+ numfiles = BIF_filelist_numfiles(simasel->files);
+ scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx;
+ simasel->scrollpos -= scrollstep;
+ if (simasel->scrollpos<0)
+ simasel->scrollpos=0;
+ do_draw= 1;
+ break;
+ case PAGEUPKEY:
+ numfiles = BIF_filelist_numfiles(simasel->files);
+ scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)
+ *simasel->numtilesx*simasel->numtilesy;
+ simasel->scrollpos -= scrollstep;
+ if (simasel->scrollpos<0)
+ simasel->scrollpos=0;
+ do_draw= 1;
+ break;
+ case PAGEDOWNKEY:
+ numfiles = BIF_filelist_numfiles(simasel->files);
+ scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+ scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)
+ * simasel->numtilesx*simasel->numtilesy;
+ simasel->scrollpos += scrollstep;
+ if (simasel->scrollpos > scrollarea - simasel->scrollheight)
+ simasel->scrollpos = scrollarea - simasel->scrollheight;
+ do_draw= 1;
+ break;
+ case HOMEKEY:
+ simasel->scrollpos=0;
+ imasel_home(sa, simasel);
+ do_draw= 1;
+ break;
+ case ENDKEY:
+ simasel->scrollpos = simasel->scrollarea;
+ do_draw= 1;
+ break;
+
+ case ESCKEY:
+ BIF_filelist_free(simasel->files);
+ imasel_prevspace();
+ break;
+ case PERIODKEY:
+ BIF_filelist_free(simasel->files);
+ simasel->active_file = -1;
+ do_draw = 1;
+ break;
+ case LEFTMOUSE:
+ case MIDDLEMOUSE:
+ getmouseco_areawin(mval);
+ if(mval[0]>simasel->v2d.vert.xmin && mval[0]<simasel->v2d.vert.xmax && mval[1]>simasel->v2d.vert.ymin && mval[1]<simasel->v2d.vert.ymax) {
+ do_filescroll(simasel);
+ }
+ else if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax
+ && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {
+ set_active_file(simasel, mval[0], mval[1]);
+ if (simasel->active_file >= 0 && simasel->active_file < numfiles) {
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+
+ if(file && S_ISDIR(file->type)) {
+ strcat(simasel->dir, file->relname);
+ strcat(simasel->dir,"/");
+ simasel->file[0] = '\0';
+ BLI_cleanup_dir(G.sce, simasel->dir);
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ BIF_filelist_free(simasel->files);
+ simasel->active_file = -1;
+ simasel->scrollpos = 0;
+ do_draw = 1;
+ do_headdraw = 1;
+ }
+ else if (file)
+ {
+ if (file->relname) {
+ if (simasel->img) {
+ IMB_freeImBuf(simasel->img);
+ simasel->img = NULL;
+ }
+ BLI_strncpy(simasel->file, file->relname, FILE_MAXFILE);
+ if(event==MIDDLEMOUSE && BIF_filelist_gettype(simasel->files))
+ imasel_execute(simasel);
+ }
+
+ }
+ if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) {
+ active_imasel_object(simasel);
+ }
+
+ do_draw = 1;
+ }
+ }
+ else {
+ simasel->active_file = -1;
+ if (simasel->flag & FILE_BOOKMARKS) {
+ if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {
+ int nentries = fsmenu_get_nentries();
+
+ set_active_bookmark(simasel, mval[1]);
+ if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) {
+ char *selected= fsmenu_get_entry(simasel->active_bookmark);
+ /* which string */
+ if (selected) {
+ BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir));
+ BLI_cleanup_dir(G.sce, simasel->dir);
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ simasel->file[0] = '\0';
+ simasel->scrollpos = 0;
+ simasel->active_file = -1;
+ do_headdraw = 1;
+ }
+ }
+ } else {
+ simasel->active_bookmark = -1;
+ }
+ do_draw= 1;
+ }
+ }
+ break;
+ case RIGHTMOUSE:
+ getmouseco_areawin(mval);
+ if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax
+ && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {
+ set_active_file(simasel, mval[0], mval[1]);
+ if(simasel->active_file >=0 && simasel->active_file<numfiles) {
+ simasel->selstate = NOTACTIVE;
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ if (file->flags & ACTIVE) {
+ file->flags &= ~ACTIVE;
+ simasel->selstate = INACTIVATE;
+ }
+ else {
+ file->flags |= ACTIVE;
+ simasel->selstate = ACTIVATE;
+ }
+ do_draw= 1;
+ }
+ }
+ break;
+ case MOUSEY:
+ case MOUSEX:
+ getmouseco_areawin(mval);
+ if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {
+ set_active_file(simasel, mval[0], mval[1]);
+ simasel->active_bookmark = -1;
+ if(simasel->active_file >=0 && simasel->active_file<numfiles) {
+ file = BIF_filelist_file(simasel->files, simasel->active_file);
+ if (simasel->selstate == INACTIVATE) {
+ file->flags &= ~ACTIVE;
+ }
+ else if (simasel->selstate == ACTIVATE) {
+ file->flags |= ACTIVE;
+ }
+ do_draw= 1;
+ }
+ } else {
+ simasel->active_file = -1;
+ if (simasel->flag & FILE_BOOKMARKS) {
+ if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {
+ set_active_bookmark(simasel, mval[1]);
+ } else {
+ simasel->active_bookmark = -1;
+ }
+ do_draw= 1;
+ }
+ }
+ break;
+ case AKEY:
+ BIF_filelist_swapselect(simasel->files);
+ if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+ do_draw= 1;
+ break;
+ case BKEY:
+ toggle_blockhandler(sa, IMASEL_HANDLER_IMAGE, UI_PNL_UNSTOW);
+ scrarea_queue_winredraw(sa);
+ break;
+ case PKEY:
+ if(G.qual & LR_SHIFTKEY) {
+ extern char bprogname[]; /* usiblender.c */
+
+ sprintf(str, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
+ system(str);
+ }
+ else
+ {
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_parent(simasel->files);
+ BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+ simasel->file[0] = '\0';
+ simasel->active_file = -1;
+ simasel->scrollpos = 0;
+ do_headdraw = 1;
+ }
+ do_draw = 1;
+ break;
+ case XKEY:
+ getmouseco_areawin(mval);
+ if (simasel->flag & FILE_BOOKMARKS) {
+ if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {
+ int nentries = fsmenu_get_nentries();
+ set_active_bookmark(simasel, mval[1]);
+ if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) {
+ char name[FILE_MAX];
+ BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
+ fsmenu_remove_entry(simasel->active_bookmark);
+ fsmenu_write_file(name);
+ simasel->active_bookmark = -1;
+ do_draw = 1;
+ }
+ }
+ }
+ break;
+ }
+ }
+ else if(event==RIGHTMOUSE) {
+ simasel->selstate = NOTACTIVE;
+ if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+ }
+ else if(event==LEFTMOUSE) {
+ if(simasel->type==FILE_MAIN) {
+ getmouseco_areawin(mval);
+ set_active_file(simasel, mval[0], mval[1]);
+ }
+ }
+ /* XXX, stupid patch, curarea can become undone
+ * because of file loading... fixme zr
+ */
+ if(curarea) {
+ if(do_draw) scrarea_queue_winredraw(curarea);
+ if(do_headdraw) scrarea_queue_headredraw(curarea);
+ }
}
+/* copied from filesel.c */
void clever_numbuts_imasel()
{
SpaceImaSel *simasel;
- static char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
- static char filename[FILE_MAXDIR+FILE_MAXFILE+12];
- static char newname[FILE_MAXDIR+FILE_MAXFILE+12];
+ char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
+ char filename[FILE_MAXDIR+FILE_MAXFILE+12];
+ char newname[FILE_MAXDIR+FILE_MAXFILE+12];
+ struct direntry *file;
int len;
simasel= curarea->spacedata.first;
+
+ if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) return;
+
len = 110;
+ file = get_hilited_entry(simasel);
+
+ if (file != NULL && !(S_ISDIR(file->type))){
+
+ BLI_make_file_string(G.sce, orgname, simasel->dir, file->relname);
+ BLI_strncpy(filename, file->relname, sizeof(filename));
- if (simasel->hilite_ima){
- BLI_make_file_string(G.sce, orgname, simasel->dir, simasel->hilite_ima->file_name);
- strcpy(filename, simasel->hilite_ima->file_name);
+ add_numbut(0, TEX, "", 0, len, filename, "Rename File");
- add_numbut(0, TEX, "", 0, len, filename, "Rename Image");
- if( do_clever_numbuts("Rename Image", 1, REDRAW) ) {
+ if( do_clever_numbuts("Rename File", 1, REDRAW) ) {
BLI_make_file_string(G.sce, newname, simasel->dir, filename);
if( strcmp(orgname, newname) != 0 ) {
BLI_rename(orgname, newname);
-
- clear_ima_dir(simasel);
+ BIF_filelist_free(simasel->files);
}
}
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index ad5ffacf103..ef656281d75 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -20,7 +20,8 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
- * Contributor(s): Blender Foundation, 2005. Full recode
+ * Contributor(s): Blender Foundation, 2005. Full recode.
+ * Roland Hess, 2007. Visual Key refactor.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -61,6 +62,7 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -81,8 +83,10 @@
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BKE_object.h"
#include "BIF_butspace.h"
#include "BIF_editaction.h"
@@ -116,6 +120,7 @@
#include "blendef.h"
#include "mydevice.h"
+#include "transform.h"
extern int ob_ar[];
extern int ma_ar[];
@@ -129,6 +134,7 @@ extern int ac_ar[];
extern int co_ar[];
extern int te_ar[];
extern int fluidsim_ar[]; // NT
+extern int part_ar[];
/* forwards */
#define IPOTHRESH 0.9
@@ -247,7 +253,7 @@ void editipo_changed(SpaceIpo *si, int doredraw)
if(ei->flag & IPO_VISIBLE) {
- boundbox_ipocurve(ei->icu);
+ boundbox_ipocurve(ei->icu, 0);
sort_time_ipocurve(ei->icu);
if(first) {
si->v2d.tot= ei->icu->totrct;
@@ -342,6 +348,22 @@ void editipo_changed(SpaceIpo *si, int doredraw)
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
}
+ else if(si->blocktype==ID_PA){
+ Object *ob=OBACT;
+ ParticleSystem *psys = ob->particlesystem.first;
+
+ /* find out if we need to initialize particles */
+ for(; psys; psys=psys->next) {
+ if(psys->part->ipo==si->ipo) {
+ ei= si->editipo;
+ for(a=0; a<si->totipo; a++, ei++)
+ if(ei->icu && ELEM3(ei->icu->adrcode,PART_EMIT_FREQ,PART_EMIT_LIFE,PART_EMIT_SIZE))
+ psys_flush_settings(psys->part,PSYS_INIT,1);
+ }
+ }
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
}
if(si->showkey) make_ipokey();
@@ -434,6 +456,49 @@ static void make_ob_editipo(Object *ob, SpaceIpo *si)
//fprintf(stderr,"FSIMAKE_OPBJ call %d \n", si->totipo);
}
+static void make_part_editipo(SpaceIpo *si)
+{
+ EditIpo *ei;
+ int a;
+ char *name;
+
+ if(si->from==0) return;
+
+ ei= si->editipo= MEM_callocN(PART_TOTIPO*sizeof(EditIpo), "editipo");
+
+ si->totipo= PART_TOTIPO;
+
+ for(a=0; a<PART_TOTIPO; a++) {
+ name = getname_part_ei(part_ar[a]);
+ strcpy(ei->name, name);
+ ei->adrcode= part_ar[a];
+
+ //if(ei->adrcode & MA_MAP1) {
+ // ei->adrcode-= MA_MAP1;
+ // ei->adrcode |= texchannel_to_adrcode(si->channel);
+ //}
+ //else {
+ // if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS;
+ //}
+
+ ei->col= ipo_rainbow(a, PART_TOTIPO);
+
+ //len= strlen(ei->name);
+ //if(len) {
+ // if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF;
+ // else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50;
+ // else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050;
+ //}
+
+ ei->icu= find_ipocurve(si->ipo, ei->adrcode);
+ if(ei->icu) {
+ ei->flag= ei->icu->flag;
+ }
+
+ ei++;
+ }
+}
+
// copied from make_seq_editipo
static void make_fluidsim_editipo(SpaceIpo *si) // NT
{
@@ -911,6 +976,12 @@ static void make_editipo(void)
make_fluidsim_editipo(G.sipo);
}
}
+ else if(G.sipo->blocktype==ID_PA) {
+ if (ob) {
+ ob->ipowin= ID_PA;
+ make_part_editipo(G.sipo);
+ }
+ }
if(G.sipo->editipo==0) return;
@@ -943,7 +1014,8 @@ static void make_editipo(void)
/* evaluates context in the current UI */
/* blocktype is type of ipo */
/* from is the base pointer to find data to change (ob in case of action or pose) */
-static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname, char *constname)
+/* bonename is for local bone ipos (constraint only now) */
+static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname, char *constname, char *bonename)
{
Object *ob= OBACT;
@@ -956,25 +1028,48 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
bConstraint *con= get_active_constraint(ob);
if(con) {
- BLI_strncpy(constname, con->name, 32);
-
- chan= get_active_constraint_channel(ob);
- if(chan) {
- *ipo= chan->ipo;
- BLI_strncpy(constname, con->name, 32);
- }
-
*from= &ob->id;
- /* set actname if in posemode */
- if(ob->action) {
+ BLI_strncpy(constname, con->name, 32);
+
+ /* a bit hackish, but we want con->ipo to work */
+ if(con->flag & CONSTRAINT_OWN_IPO) {
if(ob->flag & OB_POSEMODE) {
bPoseChannel *pchan= get_active_posechannel(ob);
- if(pchan)
- BLI_strncpy(actname, pchan->name, 32);
+ if(pchan) {
+ BLI_strncpy(bonename, pchan->name, 32);
+ *ipo= con->ipo;
+ }
+ }
+ }
+ else {
+ chan= get_active_constraint_channel(ob);
+ if(chan) {
+ *ipo= chan->ipo;
+ BLI_strncpy(constname, con->name, 32);
+ }
+
+ /* set actname if in posemode */
+ if (ob->action) {
+ if (ob->flag & OB_POSEMODE) {
+ bPoseChannel *pchan= get_active_posechannel(ob);
+ if (pchan) {
+ BLI_strncpy(actname, pchan->name, 32);
+ BLI_strncpy(bonename, pchan->name, 32);
+ }
+ }
+ else if (ob->ipoflag & OB_ACTION_OB)
+ strcpy(actname, "Object");
+ }
+ else {
+ if (ob->flag & OB_POSEMODE) {
+ bPoseChannel *pchan= get_active_posechannel(ob);
+ if (pchan) {
+ BLI_strncpy(actname, pchan->name, 32);
+ BLI_strncpy(bonename, pchan->name, 32);
+ }
+ }
}
- else if(ob->ipoflag & OB_ACTION_OB)
- strcpy(actname, "Object");
}
}
}
@@ -1016,7 +1111,7 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
else if(blocktype==ID_SEQ) {
Sequence *last_seq = get_last_seq();
- if(last_seq && ((last_seq->type & SEQ_EFFECT)||(last_seq->type == SEQ_HD_SOUND)||(last_seq->type == SEQ_RAM_SOUND))) {
+ if(last_seq) {
*from= (ID *)last_seq;
*ipo= last_seq->ipo;
}
@@ -1095,6 +1190,13 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
if(fss) *ipo= fss->ipo;
}
}
+ else if(blocktype==ID_PA) {
+ ParticleSystem *psys = psys_get_current(ob);
+ if(psys){
+ *from= (ID *)ob;
+ *ipo= psys->part->ipo;
+ }
+ }
}
/* called on each redraw, check if editipo data has to be remade */
@@ -1105,13 +1207,15 @@ void test_editipo(int doit)
if(G.sipo->pin==0) {
Ipo *ipo;
ID *from;
- char actname[32]="", constname[32]="";
+ char actname[32]="", constname[32]="", bonename[32]="";
- get_ipo_context(G.sipo->blocktype, &from, &ipo, actname, constname);
+ get_ipo_context(G.sipo->blocktype, &from, &ipo, actname, constname, bonename);
if(G.sipo->ipo != ipo) {
G.sipo->ipo= ipo;
- if(ipo) G.v2d->cur= ipo->cur;
+ /* if lock we don't copy from ipo, this makes the UI jump around confusingly */
+ if(G.v2d->flag & V2D_VIEWLOCK);
+ else if(ipo) G.v2d->cur= ipo->cur;
doit= 1;
}
if(G.sipo->from != from) {
@@ -1126,6 +1230,12 @@ void test_editipo(int doit)
BLI_strncpy(G.sipo->constname, constname, 32);
doit= 1;
}
+ if( strcmp(G.sipo->bonename, bonename)) {
+ BLI_strncpy(G.sipo->bonename, bonename, 32);
+ /* urmf; if bonename, then no action */
+ if(bonename[0]) G.sipo->actname[0]= 0;
+ doit= 1;
+ }
if(G.sipo->ipo)
G.sipo->ipo->cur = G.v2d->cur;
@@ -1177,11 +1287,11 @@ void get_status_editipo(void)
b= ei->icu->totvert;
while(b--) {
if(ei->icu->ipo==IPO_BEZ) {
- if(bezt->f1 & 1) totipo_vertsel++;
- if(bezt->f3 & 1) totipo_vertsel++;
+ if(bezt->f1 & SELECT) totipo_vertsel++;
+ if(bezt->f3 & SELECT) totipo_vertsel++;
totipo_vert+= 2;
}
- if(bezt->f2 & 1) totipo_vertsel++;
+ if(bezt->f2 & SELECT) totipo_vertsel++;
totipo_vert++;
bezt++;
@@ -1222,14 +1332,14 @@ void update_editipo_flags(void)
for(a=0; a<G.sipo->totipo; a++) {
if(ik->data[a]) {
if(ik->flag & 1) {
- ik->data[a]->f1 |= 1;
- ik->data[a]->f2 |= 1;
- ik->data[a]->f3 |= 1;
+ ik->data[a]->f1 |= SELECT;
+ ik->data[a]->f2 |= SELECT;
+ ik->data[a]->f3 |= SELECT;
}
else {
- ik->data[a]->f1 &= ~1;
- ik->data[a]->f2 &= ~1;
- ik->data[a]->f3 &= ~1;
+ ik->data[a]->f1 &= ~SELECT;
+ ik->data[a]->f2 &= ~SELECT;
+ ik->data[a]->f3 &= ~SELECT;
}
}
}
@@ -1316,7 +1426,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt)
}
else temp= abs(mval[0]- sco[1][0])+ abs(mval[1]- sco[1][1]);
- if( bezt1->f2 & 1) temp+=5;
+ if( bezt1->f2 & SELECT) temp+=5;
if(temp<dist) {
hpoint= 1;
*bezt= bezt1;
@@ -1369,23 +1479,26 @@ void mouse_select_ipo(void)
if(G.sipo->editipo==0) return;
get_status_editipo();
- marker=find_nearest_marker(1);
+ marker=find_nearest_marker(SCE_MARKERS, 1);
/* map ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 0, 0);
}
if(G.sipo->showkey) {
- getmouseco_areawin(mval);
+ float pixelwidth;
+ view2d_getscale(G.v2d, &pixelwidth, NULL);
+
+ getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
actik= 0;
mindist= 1000.0;
ik= G.sipo->ipokey.first;
while(ik) {
dist= (float)(fabs(ik->val-x));
- if(ik->flag & 1) dist+= 1.0;
+ if(ik->flag & SELECT) dist+= pixelwidth;
if(dist < mindist) {
actik= ik;
mindist= dist;
@@ -1418,16 +1531,16 @@ void mouse_select_ipo(void)
bezt->f1= bezt->f2= bezt->f3= 0;
}
else {
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
}
}
else if(hand==0) {
- if(bezt->f1 & 1) bezt->f1= 0;
- else bezt->f1= 1;
+ if(bezt->f1 & SELECT) bezt->f1= 0;
+ else bezt->f1= SELECT;
}
else {
- if(bezt->f3 & 1) bezt->f3= 0;
- else bezt->f3= 1;
+ if(bezt->f3 & SELECT) bezt->f3= 0;
+ else bezt->f3= SELECT;
}
}
}
@@ -1436,10 +1549,10 @@ void mouse_select_ipo(void)
if(bezt) {
if(hand==1) {
- bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1;
+ bezt->f1|= SELECT; bezt->f2|= SELECT; bezt->f3|= SELECT;
}
- else if(hand==0) bezt->f1|= 1;
- else bezt->f3|= 1;
+ else if(hand==0) bezt->f1 |= SELECT;
+ else bezt->f3 |= SELECT;
}
}
}
@@ -1535,7 +1648,7 @@ void mouse_select_ipo(void)
}
/* undo mapping of ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 1, 0);
}
@@ -1556,7 +1669,7 @@ void mouse_select_ipo(void)
xo= mval[0];
yo= mval[1];
- while(get_mbut()&R_MOUSE) {
+ while (get_mbut() & ((U.flag & USER_LMOUSESELECT)?L_MOUSE:R_MOUSE)) {
getmouseco_areawin(mval);
if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) {
@@ -1674,11 +1787,12 @@ void do_ipo_selectbuttons(void)
/* arguments define full context;
- *from has to be set always, to Object in case of Actions
- blocktype defines available channels of Ipo struct (blocktype ID_OB can be in action too)
- - if actname, use this to locate action, and optional constname to find the channel
+ - if actname, use this to locate actionchannel, and optional constname
+ - if bonename, the constname is the ipo to the constraint
*/
/* note; check header_ipo.c, spaceipo_assign_ipo() too */
-Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
+Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char *bonename)
{
if(from==NULL || from->lib) return NULL;
@@ -1699,6 +1813,10 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
achan= verify_action_channel(ob->action, actname);
if(achan) {
+ /* automatically assign achan to act-group based on pchan's grouping */
+ if (blocktype == ID_PO)
+ verify_pchan2achan_grouping(ob->action, ob->pose, actname);
+
/* constraint exception */
if(blocktype==ID_CO) {
bConstraintChannel *conchan= verify_constraint_channel(&achan->constraintChannels, constname);
@@ -1722,13 +1840,30 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
case ID_OB:
{
Object *ob= (Object *)from;
+
/* constraint exception */
if(blocktype==ID_CO) {
- bConstraintChannel *conchan= verify_constraint_channel(&ob->constraintChannels, constname);
- if(conchan->ipo==NULL) {
- conchan->ipo= add_ipo("CoIpo", ID_CO);
+ /* check the local constraint ipo */
+ if(bonename && bonename[0] && ob->pose) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, bonename);
+ bConstraint *con;
+ for(con= pchan->constraints.first; con; con= con->next)
+ if(strcmp(con->name, constname)==0)
+ break;
+ if(con) {
+ if(con->ipo==NULL) {
+ con->ipo= add_ipo("CoIpo", ID_CO);
+ }
+ return con->ipo;
+ }
+ }
+ else { /* the actionchannel */
+ bConstraintChannel *conchan= verify_constraint_channel(&ob->constraintChannels, constname);
+ if(conchan->ipo==NULL) {
+ conchan->ipo= add_ipo("CoIpo", ID_CO);
+ }
+ return conchan->ipo;
}
- return conchan->ipo;
}
else if(blocktype==ID_OB) {
if(ob->ipo==NULL) {
@@ -1758,6 +1893,16 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
return fss->ipo;
}
}
+ else if(blocktype== ID_PA){
+ Object *ob= (Object *)from;
+ ParticleSystem *psys= psys_get_current(ob);
+ if(psys){
+ if(psys->part->ipo==0)
+ psys->part->ipo= add_ipo("ParticleIpo", ID_PA);
+ return psys->part->ipo;
+ }
+ return NULL;
+ }
}
break;
case ID_MA:
@@ -1784,15 +1929,11 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
{
Sequence *seq= (Sequence *)from; /* note, sequence is mimicing Id */
- if((seq->type & SEQ_EFFECT)||
- (seq->type == SEQ_RAM_SOUND)||
- (seq->type == SEQ_HD_SOUND)) {
- if(seq->ipo==NULL) {
- seq->ipo= add_ipo("SeqIpo", ID_SEQ);
- }
- update_seq_ipo_rect(seq);
- return seq->ipo;
+ if(seq->ipo==NULL) {
+ seq->ipo= add_ipo("SeqIpo", ID_SEQ);
}
+ update_seq_ipo_rect(seq);
+ return seq->ipo;
}
break;
case ID_CU:
@@ -1853,14 +1994,14 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
/* returns and creates
* Make sure functions check for NULL or they will crash!
* */
-IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, int adrcode)
+IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, char *bonename, int adrcode)
{
Ipo *ipo;
IpoCurve *icu= NULL;
/* return 0 if lib */
/* creates ipo too */
- ipo= verify_ipo(from, blocktype, actname, constname);
+ ipo= verify_ipo(from, blocktype, actname, constname, bonename);
if(ipo && ipo->id.lib==NULL && from->lib==NULL) {
@@ -1869,22 +2010,24 @@ IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constn
}
if(icu==NULL) {
icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
-
+
icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
+ if(ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE; /* first one added active */
+
icu->blocktype= blocktype;
icu->adrcode= adrcode;
set_icu_vars(icu);
-
+
BLI_addtail( &(ipo->curve), icu);
-
+
switch (GS(from->name)) {
- case ID_SEQ: {
- Sequence *seq= (Sequence *)from;
-
- update_seq_icu_rects(seq);
- break;
- }
+ case ID_SEQ: {
+ Sequence *seq= (Sequence *)from;
+
+ update_seq_icu_rects(seq);
+ break;
+ }
}
}
}
@@ -1892,74 +2035,177 @@ IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constn
return icu;
}
-void insert_vert_ipo(IpoCurve *icu, float x, float y)
+
+/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
+#define BEZT_INSERT_THRESH 0.00001
+
+/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
+ * Returns the index to insert before, OR the -(index + 1) to replace.
+ * Caller will need to decrement index if > 0 to add to right place (and avoid segfaults)
+ */
+static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arraylen)
{
- BezTriple *bezt, beztr, *newbezt;
- int a = 0, h1, h2;
+ int start=0, end=arraylen;
+ int loopbreaker= 0, maxloop= arraylen * 2;
+ const float frame= (item)? item->vec[1][0] : 0.0f;
- memset(&beztr, 0, sizeof(BezTriple));
- beztr.vec[0][0]= x; // set all three points, for nicer start position
- beztr.vec[0][1]= y;
- beztr.vec[1][0]= x;
- beztr.vec[1][1]= y;
- beztr.vec[2][0]= x;
- beztr.vec[2][1]= y;
- beztr.hide= IPO_BEZ;
- beztr.f1= beztr.f2= beztr.f3= SELECT;
- beztr.h1= beztr.h2= HD_AUTO;
+ /* 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) || ELEM(NULL, array, item)) {
+ printf("Warning: binarysearch_bezt_index encountered invalid array \n");
+ return 0;
+ }
+ else {
+ /* check whether to add before/after/on */
+ float framenum;
- bezt= icu->bezt;
+ /* 'First' Keyframe */
+ framenum= array[0].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH))
+ return -1;
+ else if (frame < framenum)
+ return 0;
+
+ /* 'Last' Keyframe */
+ framenum= array[(arraylen-1)].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH))
+ return -(arraylen);
+ 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) / 2;
+ float midfra= array[mid].vec[1][0];
- if(bezt==NULL) {
- icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple");
- *(icu->bezt)= beztr;
+ /* check if exactly equal to midpoint */
+ if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH))
+ return -(mid + 1);
+
+ /* 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 IPO-Curve. It will allocate
+ * memory for the array if needed, and will insert the BezTriple into a
+ * suitable place in chronological order.
+ *
+ * NOTE: any recalculate of the IPO-Curve that needs to be done will need to
+ * be done by the caller.
+ */
+int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
+{
+ BezTriple *newb;
+ int i= 0;
+
+ if (icu->bezt == NULL) {
+ icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
+ *(icu->bezt)= *bezt;
icu->totvert= 1;
}
else {
- /* all vertices deselect */
- for(a=0; a<icu->totvert; a++, bezt++) {
- bezt->f1= bezt->f2= bezt->f3= 0;
+ i = binarysearch_bezt_index(icu->bezt, bezt, icu->totvert);
+
+ if (i < 0) {
+ /* replace existing item (need to 'invert' i first and decremement by 1) */
+ i = -i - 1;
+
+ /* sanity check: 'i' may in rare cases exceed arraylen */
+ if (i < icu->totvert)
+ *(icu->bezt + i) = *bezt;
}
-
- bezt= icu->bezt;
- for(a=0; a<=icu->totvert; a++, bezt++) {
+ else {
+ /* add new */
+ newb= MEM_callocN( (icu->totvert+1)*sizeof(BezTriple), "beztriple");
- /* no double points */
- if(a<icu->totvert && IS_EQ(bezt->vec[1][0], x)) {
- *(bezt)= beztr;
- break;
- }
- if(a==icu->totvert || bezt->vec[1][0] > x) {
- newbezt= MEM_callocN( (icu->totvert+1)*sizeof(BezTriple), "beztriple");
-
- if(a>0) memcpy(newbezt, icu->bezt, a*sizeof(BezTriple));
-
- bezt= newbezt+a;
- *(bezt)= beztr;
-
- if(a<icu->totvert) memcpy(newbezt+a+1, icu->bezt+a, (icu->totvert-a)*sizeof(BezTriple));
-
- MEM_freeN(icu->bezt);
- icu->bezt= newbezt;
-
- icu->totvert++;
- break;
- }
+ /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
+ if (i > 0)
+ memcpy(newb, icu->bezt, i*sizeof(BezTriple));
+
+ /* add beztriple to paste at index i */
+ *(newb + i)= *bezt;
+
+ /* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
+ if (i < icu->totvert)
+ memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
+
+ /* replace (+ free) old with new */
+ MEM_freeN(icu->bezt);
+ icu->bezt= newb;
+
+ icu->totvert++;
}
}
+ /* we need to return the index, so that some tools which do post-processing can
+ * detect where we added the BezTriple in the array
+ */
+ return i;
+}
+
+/* This function is a wrapper for insert_bezt_icu, and should be used when
+ * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
+ * else yet.
+ *
+ * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
+ */
+void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
+{
+ BezTriple beztr;
+ int a, h1, h2;
+
+ /* set all three points, for nicer start position */
+ memset(&beztr, 0, sizeof(BezTriple));
+ beztr.vec[0][0]= x;
+ beztr.vec[0][1]= y;
+ beztr.vec[1][0]= x;
+ beztr.vec[1][1]= y;
+ beztr.vec[2][0]= x;
+ beztr.vec[2][1]= y;
+ beztr.hide= IPO_BEZ;
+ beztr.f1= beztr.f2= beztr.f3= SELECT;
+ beztr.h1= beztr.h2= HD_AUTO;
- calchandles_ipocurve(icu);
+ /* add temp beztriple to keyframes */
+ a= insert_bezt_icu(icu, &beztr);
+ if (!fast) calchandles_ipocurve(icu);
/* set handletype */
- if(icu->totvert>2) {
+ if (icu->totvert > 2) {
+ BezTriple *bezt;
+
h1= h2= HD_AUTO;
- if(a>0) h1= (bezt-1)->h2;
- if(a<icu->totvert-1) h2= (bezt+1)->h1;
+ bezt= (icu->bezt + a);
+
+ if (a > 0) h1= (bezt-1)->h2;
+ if (a < icu->totvert-1) h2= (bezt+1)->h1;
+
bezt->h1= h1;
bezt->h2= h2;
-
- calchandles_ipocurve(icu);
+
+ if (!fast) calchandles_ipocurve(icu);
}
}
@@ -1990,13 +2236,13 @@ void add_vert_ipo(void)
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
/* convert click-time to ipo-time */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
x= get_action_frame(OBACT, x);
}
if(ei->icu==NULL) {
if(G.sipo->from) {
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
if (ei->icu)
ei->flag |= ei->icu->flag & IPO_AUTO_HORIZ; /* new curve could have been added, weak... */
else
@@ -2012,7 +2258,7 @@ void add_vert_ipo(void)
y= (float)(1 << val);
}
- insert_vert_ipo(ei->icu, x, y);
+ insert_vert_icu(ei->icu, x, y, 0);
/* to be sure: if icu was 0, or only 1 curve visible */
ei->flag |= IPO_SELECT;
@@ -2029,8 +2275,12 @@ static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, IpoCurve
Object *ob= (Object *)id;
bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
- *vartype= IPO_FLOAT;
- return get_pchan_ipo_poin(pchan, icu->adrcode);
+ if(pchan) {
+ *vartype= IPO_FLOAT;
+ return get_pchan_ipo_poin(pchan, icu->adrcode);
+ }
+ else
+ return NULL;
}
return NULL;
}
@@ -2154,42 +2404,270 @@ static int new_key_needed(IpoCurve *icu, float cFrame, float nValue)
return KEYNEEDED_JUSTADD;
}
-void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode)
+/* a duplicate of insertkey that does not check for routing to insertmatrixkey
+ to avoid recursion problems */
+static void insertkey_nonrecurs(ID *id, int blocktype, char *actname, char *constname, int adrcode)
{
IpoCurve *icu;
Object *ob;
void *poin= NULL;
float curval, cfra;
int vartype;
+ int matset=0;
- icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
-
- if(icu) {
-
- poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
+ if (matset==0) {
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
- if(poin) {
- curval= read_ipo_poin(poin, vartype);
+ if(icu) {
- cfra= frame_to_float(CFRA);
+ poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
- /* if action is mapped in NLA, it returns a correction */
- if(actname && actname[0] && GS(id->name)==ID_OB)
- cfra= get_action_frame((Object *)id, cfra);
+ if(poin) {
+ curval= read_ipo_poin(poin, vartype);
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ insert_vert_icu(icu, cfra, curval, 0);
+ }
+ }
+ }
+}
+
+int insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode)
+{
+ int matindex=0;
+ /* branch on adrcode and blocktype, generating the proper matrix-based
+ values to send to insertfloatkey */
+ if (GS(id->name)==ID_OB) {
+ Object *ob= (Object *)id;
+
+ if ( blocktype==ID_OB ){ //working with an object
+ if ((ob)&&!(ob->parent)) {
+ if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)) { //get a rotation
+ float eul[3];
+ switch (adrcode) {
+ case OB_ROT_X:
+ matindex=0;
+ break;
+ case OB_ROT_Y:
+ matindex=1;
+ break;
+ case OB_ROT_Z:
+ matindex=2;
+ break;
+ }
+ Mat4ToEul(ob->obmat, eul);
+ insertfloatkey(id, ID_OB, actname, NULL, adrcode, eul[matindex]*(5.72958));
+ return 1;
+ } else if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)) {//get a translation
+ switch (adrcode) {
+ case OB_LOC_X:
+ matindex=0;
+ break;
+ case OB_LOC_Y:
+ matindex=1;
+ break;
+ case OB_LOC_Z:
+ matindex=2;
+ break;
+ }
+ insertfloatkey(id, ID_OB, actname, NULL, adrcode, ob->obmat[3][matindex]);
+ return 1;
+ }
+ }
+ } else if ( blocktype==ID_PO) { //working with a pose channel
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+ if (pchan) {
+ if ((adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
+ switch (adrcode) {
+ case AC_LOC_X:
+ matindex=0;
+ break;
+ case AC_LOC_Y:
+ matindex=1;
+ break;
+ case AC_LOC_Z:
+ matindex=2;
+ break;
+ }
+ if (!(pchan->bone->parent)||((pchan->bone->parent)&&!(pchan->bone->flag&BONE_CONNECTED))) { /* don't use for non-connected child bones */
+ float delta_mat[4][4];
+ armature_mat_pose_to_delta(delta_mat, pchan->pose_mat, pchan->bone->arm_mat);
+ insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, delta_mat[3][matindex]);
+ return 1;
+ }
+ } else if ((adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
+ float tmat[4][4], trimat[3][3], localQuat[4];
+
+ switch (adrcode) {
+ case AC_QUAT_W:
+ matindex=0;
+ break;
+ case AC_QUAT_X:
+ matindex=1;
+ break;
+ case AC_QUAT_Y:
+ matindex=2;
+ break;
+ case AC_QUAT_Z:
+ matindex=3;
+ break;
+ }
+
+ /* it should be reasonable to assume that we are keyframing on the active object, although it is not
+ * strictly required for this particular space conversion, arg1 must not be null for this to work
+ */
+ Mat4CpyMat4(tmat, pchan->pose_mat);
+ constraint_mat_convertspace(OBACT, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+
+ Mat3CpyMat4(trimat, tmat);
+ Mat3ToQuat_is_ok(trimat, localQuat);
+ insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, localQuat[matindex]);
+
+ return 1;
+ }
+ }
+ }
+ }
+ /* failed to set a matrix key -- use traditional, but the non-recursing version */
+ insertkey_nonrecurs(id,blocktype,actname,constname,adrcode);
+ return 0;
+}
+
+static int match_adr_constraint(ID * id, int blocktype, char *actname, int adrcode)
+{ /* This function matches constraint blocks with adrcodes to see if the
+ visual keying method should be used. For example, an object looking to key
+ location and having a CopyLoc constraint would return true. */
+
+ Object *ob=NULL;
+ int foundmatch=0;
+ int searchtype=0;
+ bConstraint *conref=NULL, *con=NULL;
+
+ /*Retrieve constraint list*/
+ if( GS(id->name)==ID_OB )
+ ob= (Object *)id;
+ if (ob) {
+ if (blocktype==ID_PO) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+ conref=pchan->constraints.first;
+ } else if (blocktype==ID_OB) {
+ conref=ob->constraints.first;
+ }
+
+ if (conref) {
+ /*Set search type: 1 is for translation contraints, 2 is for rotation*/
+ if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)||(adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
+ searchtype=1;
+ } else if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)||(adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
+ searchtype=2;
+ }
- if( GS(id->name)==ID_OB ) {
- ob= (Object *)id;
- if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
- /* actually frametofloat calc again! */
- cfra-= ob->sf*G.scene->r.framelen;
+ if (searchtype>0) {
+ for (con=conref; (con)&&(foundmatch==0); con=con->next) {
+ switch (con->type) {
+ /* match constraint types to which kinds of keying they would affect */
+ case CONSTRAINT_TYPE_CHILDOF:
+ foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_MINMAX:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ foundmatch=1;
+ break;
+ default:
+ break;
+ }
}
}
+ }
+ }
+
+ return foundmatch;
+
+}
+
+void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, short fast)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float curval, cfra;
+ int vartype;
+ int matset=0;
+
+ if ((IS_AUTOKEY_FLAG(AUTOMATKEY))&&(match_adr_constraint(id, blocktype, actname, adrcode))) {
+ matset=insertmatrixkey(id, blocktype, actname, constname, adrcode);
+ }
+ if (matset==0) {
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype);
- insert_vert_ipo(icu, cfra, curval);
+ if(poin) {
+ curval= read_ipo_poin(poin, vartype);
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ insert_vert_icu(icu, cfra, curval, fast);
+ }
}
}
}
+
+
/* This function is a 'smarter' version of the insert key code.
* It uses an auxilliary function to check whether a keyframe is really needed */
void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, int adrcode)
@@ -2201,7 +2679,7 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in
int vartype;
int insert_mode;
- icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
if(icu) {
@@ -2218,9 +2696,9 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in
if( GS(id->name)==ID_OB ) {
ob= (Object *)id;
- if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
/* actually frametofloat calc again! */
- cfra-= ob->sf*G.scene->r.framelen;
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
}
}
@@ -2229,24 +2707,23 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in
/* insert new keyframe at current frame */
if (insert_mode)
- insert_vert_ipo(icu, cfra, curval);
+ insert_vert_icu(icu, cfra, curval, 0);
/* delete keyframe immediately before/after newly added */
switch (insert_mode) {
case KEYNEEDED_DELPREV:
- delete_icu_key(icu, icu->totvert-2);
+ delete_icu_key(icu, icu->totvert-2, 1);
break;
case KEYNEEDED_DELNEXT:
- delete_icu_key(icu, 1);
+ delete_icu_key(icu, 1, 1);
break;
}
}
}
}
-/* For inserting keys based on the object matrix - not on the current IPO value
- Generically - it inserts the passed float value into the appropriate IPO */
-void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue)
+/* For inserting keys based on an arbitrary float value */
+void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float floatkey)
{
IpoCurve *icu;
Object *ob;
@@ -2254,7 +2731,7 @@ void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int
float cfra;
int vartype;
- icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
if(icu) {
@@ -2270,12 +2747,14 @@ void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int
if( GS(id->name)==ID_OB ) {
ob= (Object *)id;
- if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
/* actually frametofloat calc again! */
- cfra-= ob->sf*G.scene->r.framelen;
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
}
}
- insert_vert_ipo(icu, cfra, matrixvalue);
+
+ /* insert new keyframe at current frame */
+ insert_vert_icu(icu, cfra, floatkey, 0);
}
}
}
@@ -2306,16 +2785,16 @@ void insertkey_editipo(void)
ei->icu->totvert= 0;
ei->icu->bezt= NULL;
- insert_vert_ipo(ei->icu, 0.0f, 0.0f);
+ insert_vert_icu(ei->icu, 0.0f, 0.0f, 0);
if(ELEM3(driver->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) {
if(ei->disptype==IPO_DISPDEGR)
- insert_vert_ipo(ei->icu, 18.0f, 18.0f);
+ insert_vert_icu(ei->icu, 18.0f, 18.0f, 0);
else
- insert_vert_ipo(ei->icu, 18.0f, 1.0f);
+ insert_vert_icu(ei->icu, 18.0f, 1.0f, 0);
}
else
- insert_vert_ipo(ei->icu, 1.0f, 1.0f);
+ insert_vert_icu(ei->icu, 1.0f, 1.0f, 0);
ei->flag |= IPO_SELECT|IPO_VISIBLE;
ei->icu->flag= ei->flag;
@@ -2350,8 +2829,8 @@ void insertkey_editipo(void)
id= G.sipo->from;
if(id && GS(id->name)==ID_OB ) {
Object *ob= (Object *)id;
- if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
- cfra-= ob->sf*G.scene->r.framelen;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
}
}
else if(id && GS(id->name)==ID_SEQ) {
@@ -2363,7 +2842,7 @@ void insertkey_editipo(void)
}
/* convert cfra to ipo-time */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
cfra= get_action_frame(OBACT, cfra);
}
@@ -2392,7 +2871,7 @@ void insertkey_editipo(void)
}
fp= insertvals;
for(a=0; a<tot; a++, fp+=2) {
- insert_vert_ipo(ei->icu, fp[0], fp[1]);
+ insert_vert_icu(ei->icu, fp[0], fp[1], 0);
}
MEM_freeN(insertvals);
@@ -2445,58 +2924,58 @@ void common_insertkey(void)
map= texchannel_to_adrcode(ma->texact);
if(event==0 || event==10) {
- insertkey(id, ID_MA, NULL, NULL, MA_COL_R);
- insertkey(id, ID_MA, NULL, NULL, MA_COL_G);
- insertkey(id, ID_MA, NULL, NULL, MA_COL_B);
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_B, 0);
}
if(event==1 || event==10) {
- insertkey(id, ID_MA, NULL, NULL, MA_ALPHA);
+ insertkey(id, ID_MA, NULL, NULL, MA_ALPHA, 0);
}
if(event==2 || event==10) {
- insertkey(id, ID_MA, NULL, NULL, MA_HASIZE);
+ insertkey(id, ID_MA, NULL, NULL, MA_HASIZE, 0);
}
if(event==3 || event==10) {
- insertkey(id, ID_MA, NULL, NULL, MA_MODE);
+ insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
}
if(event==10) {
- insertkey(id, ID_MA, NULL, NULL, MA_SPEC_R);
- insertkey(id, ID_MA, NULL, NULL, MA_SPEC_G);
- insertkey(id, ID_MA, NULL, NULL, MA_SPEC_B);
- insertkey(id, ID_MA, NULL, NULL, MA_REF);
- insertkey(id, ID_MA, NULL, NULL, MA_EMIT);
- insertkey(id, ID_MA, NULL, NULL, MA_AMB);
- insertkey(id, ID_MA, NULL, NULL, MA_SPEC);
- insertkey(id, ID_MA, NULL, NULL, MA_HARD);
- insertkey(id, ID_MA, NULL, NULL, MA_MODE);
- insertkey(id, ID_MA, NULL, NULL, MA_TRANSLU);
- insertkey(id, ID_MA, NULL, NULL, MA_ADD);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_B, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_REF, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_EMIT, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_AMB, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_HARD, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_TRANSLU, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_ADD, 0);
}
if(event==14) {
- insertkey(id, ID_MA, NULL, NULL, MA_RAYM);
- insertkey(id, ID_MA, NULL, NULL, MA_FRESMIR);
- insertkey(id, ID_MA, NULL, NULL, MA_FRESMIRI);
- insertkey(id, ID_MA, NULL, NULL, MA_FRESTRA);
- insertkey(id, ID_MA, NULL, NULL, MA_FRESTRAI);
+ insertkey(id, ID_MA, NULL, NULL, MA_RAYM, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESMIR, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESMIRI, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESTRA, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESTRAI, 0);
}
if(event==12 || event==11) {
- insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_X);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Y);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Z);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Z, 0);
}
if(event==13 || event==11) {
- insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_X);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Y);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Z, 0);
}
if(event==11) {
- insertkey(id, ID_MA, NULL, NULL, map+MAP_R);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_G);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_B);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_DVAR);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_COLF);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_NORF);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_VARF);
- insertkey(id, ID_MA, NULL, NULL, map+MAP_DISP);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_B, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_DVAR, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_COLF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_NORF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_VARF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_DISP, 0);
}
}
}
@@ -2510,37 +2989,37 @@ void common_insertkey(void)
map= texchannel_to_adrcode(wo->texact);
if(event==0) {
- insertkey(id, ID_WO, NULL, NULL, WO_ZEN_R);
- insertkey(id, ID_WO, NULL, NULL, WO_ZEN_G);
- insertkey(id, ID_WO, NULL, NULL, WO_ZEN_B);
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_B, 0);
}
if(event==1) {
- insertkey(id, ID_WO, NULL, NULL, WO_HOR_R);
- insertkey(id, ID_WO, NULL, NULL, WO_HOR_G);
- insertkey(id, ID_WO, NULL, NULL, WO_HOR_B);
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_B, 0);
}
if(event==2) {
- insertkey(id, ID_WO, NULL, NULL, WO_MISI);
- insertkey(id, ID_WO, NULL, NULL, WO_MISTDI);
- insertkey(id, ID_WO, NULL, NULL, WO_MISTSTA);
- insertkey(id, ID_WO, NULL, NULL, WO_MISTHI);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISI, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTDI, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTSTA, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTHI, 0);
}
if(event==3) {
- insertkey(id, ID_WO, NULL, NULL, WO_STAR_R);
- insertkey(id, ID_WO, NULL, NULL, WO_STAR_G);
- insertkey(id, ID_WO, NULL, NULL, WO_STAR_B);
- insertkey(id, ID_WO, NULL, NULL, WO_STARDIST);
- insertkey(id, ID_WO, NULL, NULL, WO_STARSIZE);
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_B, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STARDIST, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STARSIZE, 0);
}
if(event==12) {
- insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_X);
- insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Y);
- insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Z);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Z, 0);
}
if(event==13) {
- insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_X);
- insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Y);
- insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Z, 0);
}
}
}
@@ -2554,25 +3033,25 @@ void common_insertkey(void)
map= texchannel_to_adrcode(la->texact);
if(event==0) {
- insertkey(id, ID_LA, NULL, NULL, LA_COL_R);
- insertkey(id, ID_LA, NULL, NULL, LA_COL_G);
- insertkey(id, ID_LA, NULL, NULL, LA_COL_B);
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_R, 0);
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_G, 0);
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_B, 0);
}
if(event==1) {
- insertkey(id, ID_LA, NULL, NULL, LA_ENERGY);
+ insertkey(id, ID_LA, NULL, NULL, LA_ENERGY, 0);
}
if(event==2) {
- insertkey(id, ID_LA, NULL, NULL, LA_SPOTSI);
+ insertkey(id, ID_LA, NULL, NULL, LA_SPOTSI, 0);
}
if(event==12) {
- insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_X);
- insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Y);
- insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Z);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Z, 0);
}
if(event==13) {
- insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_X);
- insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Y);
- insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Z);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Z, 0);
}
}
@@ -2585,102 +3064,107 @@ void common_insertkey(void)
if(event== -1) return;
if(event==0) {
- insertkey(id, ID_TE, NULL, NULL, TE_NSIZE);
- insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH);
- insertkey(id, ID_TE, NULL, NULL, TE_NTYPE);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
}
if(event==1) {
- insertkey(id, ID_TE, NULL, NULL, TE_NSIZE);
- insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH);
- insertkey(id, ID_TE, NULL, NULL, TE_NTYPE);
- insertkey(id, ID_TE, NULL, NULL, TE_TURB);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
}
if(event==2) {
- insertkey(id, ID_TE, NULL, NULL, TE_NSIZE);
- insertkey(id, ID_TE, NULL, NULL, TE_NTYPE);
- insertkey(id, ID_TE, NULL, NULL, TE_TURB);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
}
if(event==3) {
- insertkey(id, ID_TE, NULL, NULL, TE_NSIZE);
- insertkey(id, ID_TE, NULL, NULL, TE_NTYPE);
- insertkey(id, ID_TE, NULL, NULL, TE_TURB);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1);
- insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
}
if(event==4) {
- insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH);
- insertkey(id, ID_TE, NULL, NULL, TE_TURB);
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
}
if(event==5) {
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
}
if(event==6) {
- insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP);
- insertkey(id, ID_TE, NULL, NULL, TE_MGH);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_LAC);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MGH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_LAC, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
}
if(event==7) {
- insertkey(id, ID_TE, NULL, NULL, TE_VNW1);
- insertkey(id, ID_TE, NULL, NULL, TE_VNW2);
- insertkey(id, ID_TE, NULL, NULL, TE_VNW3);
- insertkey(id, ID_TE, NULL, NULL, TE_VNW4);
- insertkey(id, ID_TE, NULL, NULL, TE_VNMEXP);
- insertkey(id, ID_TE, NULL, NULL, TE_VN_DISTM);
- insertkey(id, ID_TE, NULL, NULL, TE_VN_COLT);
- insertkey(id, ID_TE, NULL, NULL, TE_ISCA);
- insertkey(id, ID_TE, NULL, NULL, TE_NSIZE);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW2, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW3, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW4, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNMEXP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VN_DISTM, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VN_COLT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_ISCA, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
}
if(event==8) {
- insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF);
- insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN);
- insertkey(id, ID_TE, NULL, NULL, TE_DISTA);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_DISTA, 0);
}
if(event==9) {
- insertkey(id, ID_TE, NULL, NULL, TE_COL_R);
- insertkey(id, ID_TE, NULL, NULL, TE_COL_G);
- insertkey(id, ID_TE, NULL, NULL, TE_COL_B);
- insertkey(id, ID_TE, NULL, NULL, TE_BRIGHT);
- insertkey(id, ID_TE, NULL, NULL, TE_CONTRA);
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_R, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_G, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_B, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_BRIGHT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_CONTRA, 0);
}
}
}
}
else if(G.buts->mainb==CONTEXT_OBJECT) {
ob= OBACT;
- if(ob && ob->type==OB_MESH) {
+ if(ob) {
id= (ID *) (ob);
if(id) {
- event= pupmenu("Insert Key %t|Surface Damping%x0|Random Damping%x1|Permeability%x2|Force Strength%x3|Force Falloff%x4");
- if(event== -1) return;
+ if(ob->type==OB_MESH)
+ event= pupmenu("Insert Key %t|Surface Damping%x0|Random Damping%x1|Permeability%x2|Force Strength%x3|Force Falloff%x4");
+ else
+ event= pupmenu("Insert Key %t|Force Strength%x3|Force Falloff%x4");
+ if(event == -1) return;
if(event==0) {
- insertkey(id, ID_OB, NULL, NULL, OB_PD_SDAMP);
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_SDAMP, 0);
}
if(event==1) {
- insertkey(id, ID_OB, NULL, NULL, OB_PD_RDAMP);
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_RDAMP, 0);
}
if(event==2) {
- insertkey(id, ID_OB, NULL, NULL, OB_PD_PERM);
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_PERM, 0);
}
if(event==3) {
- insertkey(id, ID_OB, NULL, NULL, OB_PD_FSTR);
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FSTR, 0);
}
if(event==4) {
- insertkey(id, ID_OB, NULL, NULL, OB_PD_FFALL);
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FFALL, 0);
+ }
+ if(event==5) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FMAXD, 0);
}
-
}
}
}
@@ -2698,21 +3182,21 @@ void common_insertkey(void)
if(event== -1) return;
if(event==0) {
- insertkey(id, ID_CA, NULL, NULL, CAM_LENS);
+ insertkey(id, ID_CA, NULL, NULL, CAM_LENS, 0);
}
else if(event==1) {
- insertkey(id, ID_CA, NULL, NULL, CAM_STA);
- insertkey(id, ID_CA, NULL, NULL, CAM_END);
+ insertkey(id, ID_CA, NULL, NULL, CAM_STA, 0);
+ insertkey(id, ID_CA, NULL, NULL, CAM_END, 0);
}
else if(event==2) {
- insertkey(id, ID_CA, NULL, NULL, CAM_YF_APERT);
+ insertkey(id, ID_CA, NULL, NULL, CAM_YF_APERT, 0);
}
else if(event==3) {
- insertkey(id, ID_CA, NULL, NULL, CAM_YF_FDIST);
+ insertkey(id, ID_CA, NULL, NULL, CAM_YF_FDIST, 0);
}
else if(event==4) {
- insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_X);
- insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_Y);
+ insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_X, 0);
+ insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_Y, 0);
}
}
}
@@ -2725,16 +3209,16 @@ void common_insertkey(void)
if(event== -1) return;
if(event==0) {
- insertkey(id, ID_SO, NULL, NULL, SND_VOLUME);
+ insertkey(id, ID_SO, NULL, NULL, SND_VOLUME, 0);
}
if(event==1) {
- insertkey(id, ID_SO, NULL, NULL, SND_PITCH);
+ insertkey(id, ID_SO, NULL, NULL, SND_PITCH, 0);
}
if(event==2) {
- insertkey(id, ID_SO, NULL, NULL, SND_PANNING);
+ insertkey(id, ID_SO, NULL, NULL, SND_PANNING, 0);
}
if(event==3) {
- insertkey(id, ID_SO, NULL, NULL, SND_ATTEN);
+ insertkey(id, ID_SO, NULL, NULL, SND_ATTEN, 0);
}
}
}
@@ -2754,7 +3238,7 @@ void common_insertkey(void)
if (ob && (ob->flag & OB_POSEMODE)) {
bPoseChannel *pchan;
- set_pose_keys(ob); // sets pchan->flag to POSE_KEY if bone selected
+ set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next)
if (pchan->flag & POSE_KEY)
break;
@@ -2788,84 +3272,78 @@ void common_insertkey(void)
if (ob && (ob->flag & OB_POSEMODE)){
bPoseChannel *pchan;
-
+ short recalc_bonepaths= 0;
+
if (ob->action && ob->action->id.lib) {
error ("Can't key libactions");
return;
}
-
+
id= &ob->id;
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
- if (pchan->flag & POSE_KEY){
+ if (pchan->flag & POSE_KEY) {
+ /* insert relevant keyframes */
if(event==0 || event==3 ||event==4) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+ 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);
}
- if(event==1 || event==3 ||event==4) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ if(event==1 || event==3 || event==4) {
+ 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(event==2 || event==4) {
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
+ 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 (event==9 && ob->action) {
bActionChannel *achan;
-
+
for (achan = ob->action->chanbase.first; achan; achan=achan->next){
if (achan->ipo && !strcmp (achan->name, pchan->name)){
for (icu = achan->ipo->curve.first; icu; icu=icu->next){
- insertkey(id, ID_PO, achan->name, NULL, icu->adrcode);
+ insertkey(id, ID_PO, achan->name, NULL, icu->adrcode, 0);
}
break;
}
}
}
if(event==11 || event==13) {
- float delta_mat[4][4];
-
- armature_mat_pose_to_delta(delta_mat, pchan->pose_mat, pchan->bone->arm_mat);
- insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, delta_mat[3][0]);
- insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, delta_mat[3][1]);
- insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, delta_mat[3][2]);
+ int matok=0;
+ /* check one to make sure we're not trying to set visual loc keys on
+ bones inside of a chain, which only leads to tears. */
+ matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+
+ if (matok == 0) {
+ 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);
+ }
}
if(event==12 || event==13) {
- float delta_mat[4][4];
- float localQuat[4], oldQuat[4];
-
- /* obtain rotation caused by constraints/IK*/
- armature_mat_pose_to_delta(delta_mat, pchan->pose_mat, pchan->bone->arm_mat);
- Mat4ToQuat(delta_mat, localQuat);
-
- /* bad hack warning:
- * Write the 'visual' rotation onto the
- * bone's quat/rotation values and use standard
- * keyframing method to insert a keyframe with this
- * value.
- *
- * Needed, as rotation wouldn't get keyed correctly
- * otherwise for some strange reason. As a side-effect,
- * sometimes there may be slightly un-updated bones, but
- * still, it is better that this worked.
- */
-
- QUATCOPY(oldQuat, pchan->quat);
- QUATCOPY(pchan->quat, localQuat);
-
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
+ int matok=0;
+ /* check one to make sure we're not trying to set visual rot keys on
+ bones inside of a chain, which only leads to tears. */
+ matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- QUATCOPY(pchan->quat, oldQuat);
+ if (matok == 0) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
+ 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);
+ }
}
if (event==15 && ob->action) {
bActionChannel *achan;
-
+
for (achan = ob->action->chanbase.first; achan; achan=achan->next){
if (achan->ipo && !strcmp (achan->name, pchan->name)){
for (icu = achan->ipo->curve.first; icu; icu=icu->next){
@@ -2874,12 +3352,28 @@ void common_insertkey(void)
break;
}
}
- }
+ }
+
+ /* clear unkeyed flag (it doesn't matter if it's set or not) */
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* check if bone has a path */
+ if (pchan->path)
+ recalc_bonepaths = 1;
}
}
+
+ /* recalculate ipo handles, etc. */
if(ob->action)
remake_action_ipos(ob->action);
-
+
+ /* recalculate bone-paths on adding new keyframe? */
+ // TODO: currently, there is no setting to turn this on/off globally
+ if (recalc_bonepaths)
+ pose_recalculate_paths(ob);
+
+
allqueue(REDRAWIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
@@ -2915,7 +3409,7 @@ void common_insertkey(void)
switch (event) {
case 9:
- insertkey(id, ID_OB, actname, NULL, icu->adrcode);
+ insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
break;
case 15:
insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
@@ -2926,39 +3420,36 @@ void common_insertkey(void)
}
if(event==0 || event==3 ||event==4) {
- insertkey(id, ID_OB, actname, NULL, OB_LOC_X);
- insertkey(id, ID_OB, actname, NULL, OB_LOC_Y);
- insertkey(id, ID_OB, actname, NULL, OB_LOC_Z);
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, 0);
}
if(event==1 || event==3 ||event==4) {
- insertkey(id, ID_OB, actname, NULL, OB_ROT_X);
- insertkey(id, ID_OB, actname, NULL, OB_ROT_Y);
- insertkey(id, ID_OB, actname, NULL, OB_ROT_Z);
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, 0);
}
if(event==2 || event==4) {
- insertkey(id, ID_OB, actname, NULL, OB_SIZE_X);
- insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y);
- insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z);
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
}
if(event==5) {
/* remove localview */
tlay= base->object->lay;
base->object->lay &= 0xFFFFFF;
- insertkey(id, ID_OB, actname, NULL, OB_LAY);
+ insertkey(id, ID_OB, actname, NULL, OB_LAY, 0);
base->object->lay= tlay;
}
if(event==11 || event==13) {
- insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X, ob->obmat[3][0]);
- insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y, ob->obmat[3][1]);
- insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z, ob->obmat[3][2]);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z);
}
if(event==12 || event==13) {
- float eul[3];
-
- Mat4ToEul(ob->obmat, eul);
- insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X, eul[0]*(5.72958));
- insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y, eul[1]*(5.72958));
- insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z, eul[2]*(5.72958));
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z);
}
base->object->recalc |= OB_RECALC_OB;
}
@@ -3014,7 +3505,7 @@ void add_duplicate_editipo(void)
b= icu->totvert;
bezt= icu->bezt;
while(b--) {
- if(bezt->f2 & 1) tot++;
+ if(bezt->f2 & SELECT) tot++;
bezt++;
}
@@ -3025,7 +3516,7 @@ void add_duplicate_editipo(void)
b= icu->totvert-tot;
while(b--) {
*beztn= *bezt;
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
beztn->f1= beztn->f2= beztn->f3= 0;
beztn++;
*beztn= *bezt;
@@ -3079,7 +3570,7 @@ void remove_doubles_ipo(void)
while(b--) {
/* can we remove? */
- if(mode==2 || (bezt->f2 & 1)) {
+ if(mode==2 || (bezt->f2 & SELECT)) {
/* are the points different? */
if( fabs( bezt->vec[1][0]-newb->vec[1][0] ) > 0.9 ) {
@@ -3178,51 +3669,73 @@ void clean_ipo(void)
void clean_ipo_curve(IpoCurve *icu)
{
- BezTriple *bezt=NULL, *beztn=NULL;
- BezTriple *newb, *newbs;
- int totCount, newCount, i;
+ BezTriple *old_bezts, *bezt, *beztn;
+ BezTriple *lastb;
+ int totCount, i;
float thresh;
/* check if any points */
- if (!icu) return;
- totCount= icu->totvert;
- newCount= 1;
- if (totCount<=1) return;
+ if (icu == NULL || icu->totvert <= 1)
+ return;
/* get threshold for match-testing */
thresh= G.scene->toolsettings->clean_thresh;
- /* add first keyframe and setup tempolary array of beztriples */
- newb = newbs = MEM_callocN(sizeof(BezTriple)*totCount, "NewBeztriples");
- bezt= icu->bezt;
- *newb= *bezt;
- bezt++;
+ /* make a copy of the old BezTriples, and clear IPO curve */
+ old_bezts = icu->bezt;
+ totCount = icu->totvert;
+ icu->bezt = NULL;
+ icu->totvert = 0;
+
+ /* now insert first keyframe, as it should be ok */
+ bezt = old_bezts;
+ insert_vert_icu(icu, bezt->vec[1][0], bezt->vec[1][1], 0);
- /* loop through beztriples, comparing them */
- for (i=0; i<totCount && newCount<totCount; i++, bezt++) {
+ /* Loop through BezTriples, comparing them. Skip any that do
+ * not fit the criteria for "ok" points.
+ */
+ for (i=1; i<totCount; i++) {
float prev[2], cur[2], next[2];
- /* get references for quicker access */
- memcpy(prev, newb->vec[1], 8);
- memcpy(cur, bezt->vec[1], 8);
-
+ /* get BezTriples and their values */
if (i < (totCount - 1)) {
- beztn = (bezt + 1);
- memcpy(next, beztn->vec[1], 8);
+ beztn = (old_bezts + (i+1));
+ next[0]= beztn->vec[1][0]; next[1]= beztn->vec[1][1];
}
else {
beztn = NULL;
next[0] = next[1] = 0.0f;
}
+ lastb= (icu->bezt + (icu->totvert - 1));
+ bezt= (old_bezts + i);
+
+ /* get references for quicker access */
+ prev[0] = lastb->vec[1][0]; prev[1] = lastb->vec[1][1];
+ cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1];
/* check if current bezt occurs at same time as last ok */
- if ((cur[0] - prev[0]) <= thresh) {
- /* only add if values are a considerable distance apart */
- if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ if (IS_EQT(cur[0], prev[0], thresh)) {
+ /* If there is a next beztriple, and if occurs at the same time, only insert
+ * if there is a considerable distance between the points, and also if the
+ * current is further away than the next one is to the previous.
+ */
+ if (beztn && (IS_EQT(cur[0], next[0], thresh)) &&
+ (IS_EQT(next[1], prev[1], thresh)==0))
+ {
+ /* only add if current is further away from previous */
+ if (cur[1] > next[1]) {
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ }
+ }
+ else {
+ /* only add if values are a considerable distance apart */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe */
- newCount++;
- newb++;
- *newb = *bezt;
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
}
}
else {
@@ -3231,51 +3744,26 @@ void clean_ipo_curve(IpoCurve *icu)
/* does current have same value as previous and next? */
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe*/
- newb++;
- *newb = *bezt;
- newCount++;
+ insert_vert_icu(icu, cur[0], cur[1], 0);
}
else if (IS_EQT(cur[1], next[1], thresh) == 0) {
/* add new keyframe */
- newb++;
- *newb = *bezt;
- newCount++;
+ insert_vert_icu(icu, cur[0], cur[1], 0);
}
}
else {
/* add if value doesn't equal that of previous */
if (IS_EQT(cur[1], prev[1], thresh) == 0) {
/* add new keyframe */
- newb++;
- *newb = *bezt;
- newCount++;
+ insert_vert_icu(icu, cur[0], cur[1], 0);
}
}
}
}
-
- /* we only need to free stuff if the number of verts changed */
- if (totCount != newCount) {
- BezTriple *newbz;
-
- /* make better sized list */
- newbz= MEM_callocN(sizeof(BezTriple)*newCount, "BezTriples");
- memcpy(newbz, newbs, sizeof(BezTriple)*newCount);
-
- /* free and assign new */
- MEM_freeN(icu->bezt);
- MEM_freeN(newbs);
- icu->bezt= newbz;
- icu->totvert= newCount;
- }
- else {
- /* free memory we used */
- MEM_freeN(newbs);
- }
- /* fix up handles and make sure points are in order */
- sort_time_ipocurve(icu);
- calchandles_ipocurve(icu);
+ /* now free the memory used by the old BezTriples */
+ if (old_bezts)
+ MEM_freeN(old_bezts);
}
void smooth_ipo(void)
@@ -3396,7 +3884,7 @@ void join_ipo(int mode)
b= icu->totvert;
bezt= icu->bezt;
while(b--) {
- if(bezt->f2 & 1) tot++;
+ if(bezt->f2 & SELECT) tot++;
bezt++;
}
@@ -3413,7 +3901,7 @@ void join_ipo(int mode)
b= icu->totvert+tot+1;
while(b--) {
- if(bezt->f2 & 1) {
+ if(bezt->f2 & SELECT) {
if(tot==0) *newb= *bezt;
else {
VecAddf(newb->vec[0], newb->vec[0], bezt->vec[0]);
@@ -3512,7 +4000,7 @@ void ipo_snap(short event)
get_status_editipo();
/* map ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 0, 0);
}
@@ -3531,7 +4019,7 @@ void ipo_snap(short event)
while(a--) {
ok= 0;
if(totipo_vert) {
- if(bezt->f2 & 1) ok= 1;
+ if(bezt->f2 & SELECT) ok= 1;
}
else ok= 1;
@@ -3585,7 +4073,7 @@ void ipo_snap(short event)
}
/* undo mapping of ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 1, 0);
}
@@ -3609,7 +4097,7 @@ void ipo_mirror(short mode)
BezTriple *bezt;
int a, b;
- int ok, ok2;
+ short ok, ok2, i;
float diff;
/* what's this for? */
@@ -3620,7 +4108,7 @@ void ipo_mirror(short mode)
if (!ei) return;
/* map ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 0, 0);
}
@@ -3641,7 +4129,7 @@ void ipo_mirror(short mode)
while(a--) {
ok= 0;
if(totipo_vert) {
- if(bezt->f2 & 1) ok= 1;
+ if(bezt->f2 & SELECT) ok= 1;
}
else ok= 1;
@@ -3649,20 +4137,26 @@ void ipo_mirror(short mode)
switch (mode) {
case 1: /* mirror over current frame */
{
- diff= ((float)CFRA - bezt->vec[1][0]);
- bezt->vec[1][0]= ((float)CFRA + diff);
+ for (i=0; i<3; i++) {
+ diff= ((float)CFRA - bezt->vec[i][0]);
+ bezt->vec[i][0]= ((float)CFRA + diff);
+ }
}
break;
case 2: /* mirror over vertical axis (frame 0) */
{
- diff= (0.0f - bezt->vec[1][0]);
- bezt->vec[1][0]= (0.0f + diff);
+ for (i=0; i<3; i++) {
+ diff= (0.0f - bezt->vec[i][0]);
+ bezt->vec[i][0]= (0.0f + diff);
+ }
}
break;
case 3: /* mirror over horizontal axis */
{
- diff= (0.0f - bezt->vec[1][1]);
- bezt->vec[1][1]= (0.0f + diff);
+ for (i=0; i<3; i++) {
+ diff= (0.0f - bezt->vec[i][1]);
+ bezt->vec[i][1]= (0.0f + diff);
+ }
}
break;
}
@@ -3679,7 +4173,7 @@ void ipo_mirror(short mode)
}
/* undo mapping of ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 1, 0);
}
@@ -3793,7 +4287,7 @@ void del_ipo(int need_check)
bezt= ei->icu->bezt;
for(a=0; a<ei->icu->totvert; a++) {
if( BEZSELECTED(bezt) ) {
- memcpy(bezt, bezt+1, (ei->icu->totvert-a-1)*sizeof(BezTriple));
+ memmove(bezt, bezt+1, (ei->icu->totvert-a-1)*sizeof(BezTriple));
ei->icu->totvert--;
a--;
event= 1;
@@ -3877,64 +4371,109 @@ void paste_editipo(void)
{
EditIpo *ei;
IpoCurve *icu;
- int a, ok;
+ int a;
- if(G.sipo->showkey) return;
+ if (G.sipo->showkey) return;
- if(totipocopybuf==0) return;
- if(G.sipo->ipo==0) return;
- if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
+ if (totipocopybuf==0) return;
+ if (G.sipo->ipo==0) return;
+ if (G.sipo->ipo && G.sipo->ipo->id.lib) return;
get_status_editipo();
- if(totipo_vis==0) {
+ if (totipo_vis==0) {
error("No visible channels");
+ return;
}
- else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) {
+ else if (totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) {
error("Incompatible paste");
+ return;
}
- else {
- /* prevent problems: splines visible that are not selected */
- if(totipo_vis==totipo_sel) totipo_vis= 0;
-
- icu= ipocopybuf.first;
- if(icu==0) return;
-
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
- if(ei->flag & IPO_VISIBLE) {
- ok= 0;
- if(totipo_vis==totipocopybuf) ok= 1;
- if(totipo_sel==totipocopybuf && (ei->flag & IPO_SELECT)) ok= 1;
- if(ok) {
+ icu= ipocopybuf.first;
+
+ for (a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
+ if (ei->flag & IPO_VISIBLE) {
+ /* don't attempt pasting if no valid buffer-curve to paste from anymore */
+ if (icu == 0) return;
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
- if(ei->icu==NULL) return;
-
- if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
- ei->icu->bezt= NULL;
- if(ei->icu->driver) MEM_freeN(ei->icu->driver);
- ei->icu->driver= NULL;
-
- ei->icu->totvert= icu->totvert;
- ei->icu->flag= ei->flag= icu->flag;
- ei->icu->extrap= icu->extrap;
- ei->icu->ipo= icu->ipo;
-
- if(icu->bezt)
- ei->icu->bezt= MEM_dupallocN(icu->bezt);
- if(icu->driver)
- ei->icu->driver= MEM_dupallocN(icu->driver);
+ /* if in editmode, paste keyframes */
+ if (ei->flag & IPO_EDIT) {
+ BezTriple *bezt;
+ float offset= 0.0f;
+ short offsetInit= 0;
+ int i;
+
+ /* make sure an ipo-curve exists (it may not, as this is an editipo) */
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
+ if (ei->icu == NULL) return;
+
+ /* Copy selected beztriples from source icu onto this edit-icu,
+ * with all added keyframes being offsetted by the difference between
+ * the first source keyframe and the current frame.
+ */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* skip if not selected */
+ if (BEZSELECTED(bezt) == 0) continue;
- icu= icu->next;
+ /* initialise offset (if not already done) */
+ if (offsetInit==0) {
+ offset= CFRA - bezt->vec[1][0];
+ offsetInit= 1;
+ }
+ /* temporarily apply offset to src beztriple while copying */
+ bezt->vec[0][0] += offset;
+ bezt->vec[1][0] += offset;
+ bezt->vec[2][0] += offset;
+
+ /* insert the keyframe */
+ insert_bezt_icu(ei->icu, bezt);
+ /* un-apply offset from src beztriple after copying */
+ bezt->vec[0][0] -= offset;
+ bezt->vec[1][0] -= offset;
+ bezt->vec[2][0] -= offset;
}
+
+ /* recalculate handles of curve that data was pasted into */
+ calchandles_ipocurve(ei->icu);
+
+ /* advance to next copy/paste buffer ipo-curve */
+ icu= icu->next;
+ }
+
+ /* otherwise paste entire curve data */
+ else {
+
+ /* make sure an ipo-curve exists (it may not, as this is an editipo) */
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
+ if (ei->icu==NULL) return;
+
+ /* clear exisiting dynamic memory (keyframes, driver) */
+ if (ei->icu->bezt) MEM_freeN(ei->icu->bezt);
+ ei->icu->bezt= NULL;
+ if (ei->icu->driver) MEM_freeN(ei->icu->driver);
+ ei->icu->driver= NULL;
+
+ ei->icu->totvert= icu->totvert;
+ ei->icu->flag= ei->flag= icu->flag;
+ ei->icu->extrap= icu->extrap;
+ ei->icu->ipo= icu->ipo;
+
+ /* make a copy of the source icu's data */
+ if (icu->bezt)
+ ei->icu->bezt= MEM_dupallocN(icu->bezt);
+ if (icu->driver)
+ ei->icu->driver= MEM_dupallocN(icu->driver);
+
+ /* advance to next copy/paste buffer ipo-curve */
+ icu= icu->next;
}
}
- editipo_changed(G.sipo, 1);
- BIF_undo_push("Paste Ipo curves");
}
+
+ editipo_changed(G.sipo, 1);
+ BIF_undo_push("Paste Ipo curves");
}
/* *********************** */
@@ -3972,7 +4511,7 @@ void set_speed_editipo(float speed)
EditIpo *ei;
BezTriple *bezt, *beztar[3];
float vec1[3], vec2[3];
- int a, b, totvert, didit=0;
+ int a, b, totvert, didit=0, done_error = 0;
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
@@ -4021,7 +4560,10 @@ void set_speed_editipo(float speed)
didit= 1;
}
else {
- error("Only works for 3 visible curves with handles");
+ if (done_error==0) {
+ error("Only works for 3 visible curves with handles");
+ }
+ done_error = 1;
}
}
}
@@ -4075,7 +4617,7 @@ void add_to_ipokey(ListBase *lb, BezTriple *bezt, int nr, int len)
if( ik->val==bezt->vec[1][0] ) {
if(ik->data[nr]==0) { /* double points! */
ik->data[nr]= bezt;
- if(bezt->f2 & 1) ik->flag= 1;
+ if(bezt->f2 & SELECT) ik->flag= 1;
return;
}
}
@@ -4092,7 +4634,7 @@ void add_to_ipokey(ListBase *lb, BezTriple *bezt, int nr, int len)
ikn->data[nr]= bezt;
ikn->val= bezt->vec[1][0];
- if(bezt->f2 & 1) ikn->flag= 1;
+ if(bezt->f2 & SELECT) ikn->flag= 1;
}
void make_ipokey(void)
@@ -4130,7 +4672,7 @@ void make_ipokey(void)
for(a=0; a<G.sipo->totipo; a++) {
if(ik->data[a]) {
bezt= ik->data[a];
- if(bezt->f2 & 1) sel++;
+ if(bezt->f2 & SELECT) sel++;
else desel++;
}
}
@@ -4139,14 +4681,14 @@ void make_ipokey(void)
if(ik->data[a]) {
bezt= ik->data[a];
if(sel) {
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
}
else {
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
}
}
}
@@ -4154,7 +4696,7 @@ void make_ipokey(void)
else ik->flag= 0;
/* map ipo-keys for drawing/editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
ik->val= get_action_frame_inv(OBACT, ik->val);
}
@@ -4244,7 +4786,7 @@ void make_ipokey_transform(Object *ob, ListBase *lb, int sel)
bezt= icu->bezt;
a= icu->totvert;
while(a--) {
- if(sel==0 || (bezt->f2 & 1)) {
+ if(sel==0 || (bezt->f2 & SELECT)) {
add_to_ipokey(lb, bezt, adrcode, OB_TOTIPO);
}
bezt++;
@@ -4258,7 +4800,7 @@ void make_ipokey_transform(Object *ob, ListBase *lb, int sel)
ik= lb->first;
while(ik) {
/* map ipo-keys for drawing/editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
ik->val= get_action_frame_inv(OBACT, ik->val);
}
@@ -4278,7 +4820,7 @@ void update_ipokey_val(void) /* after moving vertices */
ik->val= ik->data[a]->vec[1][0];
/* map ipo-keys for drawing/editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
ik->val= get_action_frame_inv(OBACT, ik->val);
}
break;
@@ -4470,485 +5012,436 @@ void movekey_obipo(int dir) /* only call external from view3d queue */
}
/* **************************************************** */
+/* IPO TRANSFORM TOOLS
+ *
+ * Only the helper functions are stored here these days. They are here as
+ * there are heaps of ugly globals which the IPO editor relies on.
+ * However, the actual transforms go through the transform system these days.
+ */
-
-void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot)
+/* Helper function for make_ipo_transdata, which is reponsible for associating
+ * source data with transform data
+ */
+static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, float *cent, short selected, short onlytime)
{
- EditIpo *ei;
- TransVert *tv;
- BezTriple *bezt;
- int a, b;
+ /* New location from td gets dumped onto the old-location of td2d, which then
+ * gets copied to the actual data at td2d->loc2d (bezt->vec[n])
+ *
+ * Due to NLA scaling, we apply NLA scaling to some of the verts here,
+ * and then that scaling will be undone after transform is done.
+ */
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
+ if (NLA_IPO_SCALED) {
+ td2d->loc[0] = get_action_frame_inv(OBACT, loc[0]);
+ td2d->loc[1] = loc[1];
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = loc;
- if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-
- if(ei->icu->bezt) {
- sort_time_ipocurve(ei->icu);
- }
- }
+ td->flag = 0;
+ td->loc = td2d->loc;
+ VECCOPY(td->center, cent);
+ VECCOPY(td->iloc, td->loc);
}
-
- ei= G.sipo->editipo;
- tv= transmain;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
+ else {
+ td2d->loc[0] = loc[0];
+ td2d->loc[1] = loc[1];
+ td2d->loc[2] = 0.0f;
+ td2d->loc2d = loc;
- if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
- if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
- if(ei->icu->bezt) {
- bezt= ei->icu->bezt;
- b= ei->icu->totvert;
- while(b--) {
- if(ei->icu->ipo==IPO_BEZ) {
- if(bezt->f1 & 1) {
- tv->loc= bezt->vec[0];
- tv++;
- }
- if(bezt->f3 & 1) {
- tv->loc= bezt->vec[2];
- tv++;
- }
- }
- if(bezt->f2 & 1) {
- tv->loc= bezt->vec[1];
- tv++;
- }
-
- bezt++;
- }
- testhandles_ipocurve(ei->icu);
- }
- }
- }
+ td->flag = 0;
+ td->loc = td2d->loc;
+ VECCOPY(td->center, cent);
+ VECCOPY(td->iloc, td->loc);
}
+
+ memset(td->axismtx, 0, sizeof(td->axismtx));
+ td->axismtx[2][2] = 1.0f;
+
+ td->ext= NULL; td->tdi= NULL; td->val= NULL;
+
+ if (selected) {
+ td->flag |= TD_SELECTED;
+ td->dist= 0.0;
+ }
+ else
+ td->dist= MAXFLOAT;
+
+ if (onlytime)
+ td->flag |= TD_TIMEONLY;
+
+ Mat3One(td->mtx);
+ Mat3One(td->smtx);
+}
+
+/* This function is called by createTransIpoData and remake_ipo_transdata to
+ * create the TransData and TransData2D arrays for transform. The costly counting
+ * stage is only performed for createTransIpoData case, and is indicated by t->total==-1;
+ */
+void make_ipo_transdata (TransInfo *t)
+{
+ TransData *td = NULL;
+ TransData2D *td2d = NULL;
- if(G.sipo->showkey) make_ipokey();
+ EditIpo *ei;
+ BezTriple *bezt;
+ int a, b;
- if(dvec==0) return;
+ /* countsel and propmode are used for proportional edit, which is not yet available */
+ int count=0/*, countsel=0*/;
+ /*int propmode = t->flag & T_PROP_EDIT;*/
- tv= transmain;
- for(a=0; a<tot; a++, tv++) {
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
- tv->oldloc[0] = get_action_frame_inv(OBACT, tv->loc[0]);
- tv->oldloc[0]-= dvec[0];
- tv->oldloc[0] = get_action_frame(OBACT, tv->loc[0]);
+ /* count data and allocate memory (if needed) */
+ if (t->total == 0) {
+ /* count data first */
+ if (totipo_vertsel) {
+ /* we're probably in editmode, so only selected verts */
+ count= totipo_vertsel;
+ }
+ else if (totipo_edit==0 && totipo_sel!=0) {
+ /* we're not in editmode, so entire curves get moved */
+ ei= G.sipo->editipo;
+ for (a=0; a<G.sipo->totipo; a++, ei++) {
+ if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
+ if (ei->icu->bezt && ei->icu->ipo==IPO_BEZ)
+ count+= 3*ei->icu->totvert;
+ else
+ count+= ei->icu->totvert;
+ }
+ }
+ if (count==0) return;
}
else {
- tv->oldloc[0]= tv->loc[0]-dvec[0];
+ /* this case should not happen */
+ return;
}
- tv->oldloc[1]= tv->loc[1]-dvec[1];
+
+ /* memory allocation */
+ /*t->total= (propmode)? count: countsel;*/
+ t->total= count;
+ t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (IPO Editor)");
+ /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */
+ t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransData2D (IPO Editor)");
}
-}
-
-#define CLAMP_OFF 0
-#define CLAMP_X 1
-#define CLAMP_Y 2
-
-void transform_ipo(int mode)
-{
- EditIpo *ei;
- BezTriple *bezt;
- TransVert *transmain = NULL, *tv;
- float dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac;
- int tot=0, a, b, firsttime=1, afbreek=0, dosort, clampAxis=CLAMP_OFF;
- unsigned short event = 0;
- short mval[2], val, xo, yo, xn, yn, xc, yc;
- char str[64];
- if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
- if(G.sipo->editipo==0) return;
- if(mode=='r') return; /* from gesture */
-
- INIT_MINMAX(min, max);
+ td= t->data;
+ td2d= t->data2d;
- /* which vertices are involved */
- get_status_editipo();
- if(totipo_vertsel) {
- tot= totipo_vertsel;
- tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
-
+ /* add verts */
+ if (totipo_vertsel) {
+ /* we're probably in editmode, so only selected verts */
ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
-
+ for (a=0; a<G.sipo->totipo; a++, ei++) {
+ /* only consider those curves that are visible and are being edited/used for showkeys */
if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
- if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
-
-
- if(ei->icu->bezt) {
+ if ( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
+ if (ei->icu->bezt) {
+ short onlytime= (ei->disptype==IPO_DISPBITS) ? 1 : (G.sipo->showkey) ? 1 : 0;
bezt= ei->icu->bezt;
- b= ei->icu->totvert;
- while(b--) {
- if(ei->icu->ipo==IPO_BEZ) {
- if(bezt->f1 & 1) {
- tv->loc= bezt->vec[0];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-
- /* we take the middle vertex */
- DO_MINMAX2(bezt->vec[1], min, max);
-
- tv++;
- }
- if(bezt->f3 & 1) {
- tv->loc= bezt->vec[2];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-
- /* we take the middle vertex */
- DO_MINMAX2(bezt->vec[1], min, max);
-
- tv++;
- }
+
+ for (b=0; b < ei->icu->totvert; b++, bezt++) {
+ /* only include handles if selected, and interpolaton mode uses beztriples */
+ if (ei->icu->ipo==IPO_BEZ) {
+ if (bezt->f1 & SELECT)
+ bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, onlytime);
+ if (bezt->f3 & SELECT)
+ bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, onlytime);
}
- if(bezt->f2 & 1) {
- tv->loc= bezt->vec[1];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
- DO_MINMAX2(bezt->vec[1], min, max);
- tv++;
+
+ /* only include main vert if selected */
+ if (bezt->f2 & SELECT) {
+ bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, onlytime);
}
- bezt++;
}
}
}
}
}
-
}
- else if(totipo_edit==0 && totipo_sel!=0) {
-
+ else if (totipo_edit==0 && totipo_sel!=0) {
+ /* we're not in editmode, so entire curves get moved */
ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
+ for (a=0; a<G.sipo->totipo; a++, ei++) {
+ /* only include curves that are visible and selected */
if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
- if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert;
- else tot+= ei->icu->totvert;
- }
- }
- if(tot==0) return;
-
- tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
-
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
- if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
- if(ei->icu->bezt) {
-
+ if (ei->icu->bezt) {
+ short onlytime= (ei->disptype==IPO_DISPBITS) ? 1 : (G.sipo->showkey) ? 1 : 0;
bezt= ei->icu->bezt;
b= ei->icu->totvert;
- while(b--) {
- if(ei->icu->ipo==IPO_BEZ) {
- tv->loc= bezt->vec[0];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
- tv++;
-
- tv->loc= bezt->vec[2];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
- tv++;
+
+ for (b=0; b < ei->icu->totvert; b++, bezt++) {
+ /* only include handles if interpolation mode is bezier not bpoint */
+ if (ei->icu->ipo==IPO_BEZ) {
+ bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, onlytime);
+ bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, onlytime);
}
- tv->loc= bezt->vec[1];
- VECCOPY(tv->oldloc, tv->loc);
- if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-
- DO_MINMAX2(bezt->vec[1], min, max);
- tv++;
-
- bezt++;
+ /* always include the main handle */
+ bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, onlytime);
}
}
}
}
-
}
+}
- if(tot==0) {
- if(totipo_edit==0) move_keys(OBACT);
- return;
- }
+/* ------------------------ */
- cent[0]= (float)((min[0]+max[0])/2.0);
- cent[1]= (float)((min[1]+max[1])/2.0);
+/* struct for use in re-sorting BezTriples during IPO transform */
+typedef struct BeztMap {
+ BezTriple *bezt;
+ int oldIndex; /* index of bezt in icu->bezt array before sorting */
+ int newIndex; /* index of bezt in icu->bezt array after sorting */
+ short swapHs; /* swap order of handles (-1=clear; 0=not checked, 1=swap) */
+} BeztMap;
- if(G.sipo->showkey) {
- clampAxis = CLAMP_Y;
- }
+
+/* This function converts an IpoCurve's BezTriple array to a BeztMap array
+ * NOTE: this allocates memory that will need to get freed later
+ */
+static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert)
+{
+ BezTriple *bezt= bezts;
+ BeztMap *bezm, *bezms;
+ int i;
- ipoco_to_areaco(G.v2d, cent, mval);
- xc= mval[0];
- yc= mval[1];
+ /* allocate memory for this array */
+ if (totvert==0 || bezts==NULL)
+ return NULL;
+ bezm= bezms= MEM_callocN(sizeof(BeztMap)*totvert, "BeztMaps");
- getmouseco_areawin(mval);
- xo= xn= mval[0];
- yo= yn= mval[1];
- dvec[0]= dvec[1]= 0.0;
+ /* assign beztriples to beztmaps */
+ for (i=0; i < totvert; i++, bezm++, bezt++) {
+ bezm->bezt= bezt;
+ bezm->oldIndex= i;
+ bezm->newIndex= i;
+ }
- sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ));
- if(sizefac<2.0) sizefac= 2.0;
+ return bezms;
+}
- while(afbreek==0) {
- getmouseco_areawin(mval);
- if(mval[0]!=xo || mval[1]!=yo || firsttime) {
-
- if(mode=='g') {
-
- dx= (float)(mval[0]- xo);
- dy= (float)(mval[1]- yo);
-
- div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
- dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
+/* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */
+static void sort_time_beztmaps (BeztMap *bezms, int totvert)
+{
+ BeztMap *bezm;
+ int i, ok= 1;
- div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin);
- dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
-
- if(clampAxis) dvec[clampAxis-1]= 0.0;
-
- /* vec is reused below: remake_ipo_transverts */
- vec[0]= dvec[0];
- vec[1]= dvec[1];
-
- apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & USER_AUTOGRABGRID);
- apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0);
-
- tv= transmain;
- for(a=0; a<tot; a++, tv++) {
- /* adjust times for scaled ipos */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
- tv->loc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]);
- tv->loc[0]+= vec[0];
- tv->loc[0] = get_action_frame(OBACT, tv->loc[0]);
- }
- else {
- tv->loc[0]= tv->oldloc[0]+vec[0];
- }
-
- if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1];
- }
-
- if (clampAxis == CLAMP_Y)
- sprintf(str, "X: %.3f ", vec[0]);
- else if (clampAxis == CLAMP_X)
- sprintf(str, "Y: %.3f ", vec[1]);
- else
- sprintf(str, "X: %.3f Y: %.3f ", vec[0], vec[1]);
-
- headerprint(str);
- }
- else if(mode=='s') {
-
- size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac);
-
- if(clampAxis) size[clampAxis-1]= 1.0;
-
- apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID);
- apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID);
-
- tv= transmain;
-
- for(a=0; a<tot; a++, tv++) {
- /* adjust times for scaled ipo's */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
- tv->loc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]) - get_action_frame_inv(OBACT, cent[0]);
- tv->loc[0]*= size[0];
- tv->loc[0]+= get_action_frame_inv(OBACT, cent[0]);
- tv->loc[0] = get_action_frame(OBACT, tv->loc[0]);
- }
- else {
- tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0];
- }
+ /* keep repeating the process until nothing is out of place anymore */
+ while (ok) {
+ ok= 0;
+
+ bezm= bezms;
+ i= totvert;
+ while (i--) {
+ /* is current bezm out of order (i.e. occurs later than next)? */
+ if (i > 0) {
+ if (bezm->bezt->vec[1][0] > (bezm+1)->bezt->vec[1][0]) {
+ bezm->newIndex++;
+ (bezm+1)->newIndex--;
- if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1];
- }
-
- if (clampAxis == CLAMP_Y)
- sprintf(str, "scaleX: %.3f ", size[0]);
- else if (clampAxis == CLAMP_X)
- sprintf(str, "scaleY: %.3f ", size[1]);
- else
- sprintf(str, "scaleX: %.3f scaleY: %.3f ", size[0], size[1]);
-
- headerprint(str);
-
- }
-
- xo= mval[0];
- yo= mval[1];
-
- dosort= 0;
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
- if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+ SWAP(BeztMap, *bezm, *(bezm+1));
- /* watch it: if the time is wrong: do not correct handles */
- if (test_time_ipocurve(ei->icu) ) dosort++;
- else testhandles_ipocurve(ei->icu);
+ ok= 1;
}
}
- if(dosort) {
- if(mode=='g') remake_ipo_transverts(transmain, vec, tot);
- else remake_ipo_transverts(transmain, 0, tot);
+ /* do we need to check if the handles need to be swapped?
+ * optimisation: this only needs to be performed in the first loop
+ */
+ if (bezm->swapHs == 0) {
+ if ( (bezm->bezt->vec[0][0] > bezm->bezt->vec[1][0]) &&
+ (bezm->bezt->vec[2][0] < bezm->bezt->vec[1][0]) )
+ {
+ /* handles need to be swapped */
+ bezm->swapHs = 1;
+ }
+ else {
+ /* handles need to be cleared */
+ bezm->swapHs = -1;
+ }
}
- if(G.sipo->showkey) update_ipokey_val();
- calc_ipo(G.sipo->ipo, (float)CFRA);
+ bezm++;
+ }
+ }
+}
- /* update realtime */
- if(G.sipo->lock) {
- if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) {
- do_ipo(G.sipo->ipo);
- force_draw_plus(SPACE_BUTS, 0);
- }
- else if(G.sipo->blocktype==ID_CA) {
- do_ipo(G.sipo->ipo);
- force_draw_plus(SPACE_VIEW3D, 0);
- }
- else if(G.sipo->blocktype==ID_KE) {
- Object *ob= OBACT;
- if(ob) {
- ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+/* This function firstly adjusts the pointers that the transdata has to each BezTriple*/
+static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totvert)
+{
+ BezTriple *bezts = ei->icu->bezt;
+ BeztMap *bezm;
+ TransData2D *td;
+ int i, j;
+ char *adjusted;
+
+ /* dynamically allocate an array of chars to mark whether an TransData's
+ * pointers have been fixed already, so that we don't override ones that are
+ * already done
+ */
+ adjusted= MEM_callocN(t->total, "beztmap_adjusted_map");
+
+ /* for each beztmap item, find if it is used anywhere */
+ bezm= bezms;
+ for (i= 0; i < totvert; i++, bezm++) {
+ /* loop through transdata, testing if we have a hit
+ * for the handles (vec[0]/vec[2]), we must also check if they need to be swapped...
+ */
+ td= t->data2d;
+ for (j= 0; j < t->total; j++, td++) {
+ /* skip item if already marked */
+ if (adjusted[j] != 0) continue;
+
+ if (totipo_vertsel) {
+ /* only selected verts */
+ if (ei->icu->ipo==IPO_BEZ) {
+ if (bezm->bezt->f1 & SELECT) {
+ if (td->loc2d == bezm->bezt->vec[0]) {
+ if (bezm->swapHs == 1)
+ td->loc2d= (bezts + bezm->newIndex)->vec[2];
+ else
+ td->loc2d= (bezts + bezm->newIndex)->vec[0];
+ adjusted[j] = 1;
+ }
}
- force_draw_plus(SPACE_VIEW3D, 0);
- }
- else if(G.sipo->blocktype==ID_PO) {
- Object *ob= OBACT;
- if(ob && ob->pose) {
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ if (bezm->bezt->f3 & SELECT) {
+ if (td->loc2d == bezm->bezt->vec[2]) {
+ if (bezm->swapHs == 1)
+ td->loc2d= (bezts + bezm->newIndex)->vec[0];
+ else
+ td->loc2d= (bezts + bezm->newIndex)->vec[2];
+ adjusted[j] = 1;
+ }
}
- force_draw_plus(SPACE_VIEW3D, 0);
}
- else if(G.sipo->blocktype==ID_OB) {
- Base *base= FIRSTBASE;
-
- while(base) {
- if(base->object->ipo==G.sipo->ipo) {
- do_ob_ipo(base->object);
- base->object->recalc |= OB_RECALC_OB;
- }
- base= base->next;
+ if (bezm->bezt->f2 & SELECT) {
+ if (td->loc2d == bezm->bezt->vec[1]) {
+ td->loc2d= (bezts + bezm->newIndex)->vec[1];
+ adjusted[j] = 1;
}
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
- force_draw_plus(SPACE_VIEW3D, 0);
}
- else force_draw(0);
}
else {
- force_draw(0);
- }
- firsttime= 0;
- }
- else BIF_wait_for_statechange();
-
- while(qtest()) {
- event= extern_qread(&val);
- if(val) {
- switch(event) {
- case ESCKEY:
- case LEFTMOUSE:
- case RIGHTMOUSE:
- case SPACEKEY:
- case RETKEY:
- afbreek= 1;
- break;
- case MIDDLEMOUSE:
- if(G.sipo->showkey==0) {
- if (clampAxis == CLAMP_OFF)
- {
- if( abs(mval[0]-xn) > abs(mval[1]-yn))
- clampAxis = CLAMP_Y;
- else
- clampAxis = CLAMP_X;
- }
+ /* whole curve */
+ if (ei->icu->ipo==IPO_BEZ) {
+ if (td->loc2d == bezm->bezt->vec[0]) {
+ if (bezm->swapHs == 1)
+ td->loc2d= (bezts + bezm->newIndex)->vec[2];
else
- {
- clampAxis = CLAMP_OFF;
- }
- firsttime= 1;
+ td->loc2d= (bezts + bezm->newIndex)->vec[0];
+ adjusted[j] = 1;
}
- break;
- case XKEY:
- /* clampAxis is the axis that will be Zeroed out, which is why we clamp
- * on Y when pressing X
- */
- if (clampAxis == CLAMP_Y)
- clampAxis = CLAMP_OFF; // Clamp Off if already on Y
- else
- clampAxis = CLAMP_Y; // On otherwise
- firsttime= 1;
- break;
- case YKEY:
- /* clampAxis is the axis that will be Zeroed out, which is why we clamp
- * on X when pressing Y
- */
- if (clampAxis == CLAMP_X)
- clampAxis = CLAMP_OFF; // Clamp Off if already on X
- else
- clampAxis = CLAMP_X; // On otherwise
- firsttime= 1;
- break;
- case LEFTCTRLKEY:
- case RIGHTCTRLKEY:
- firsttime= 1;
- break;
- default:
- if(mode=='g') {
- if(G.qual & LR_CTRLKEY) {
- if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;}
- else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;}
- else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;}
- else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;}
- }
- else arrows_move_cursor(event);
+
+ if (td->loc2d == bezm->bezt->vec[2]) {
+ if (bezm->swapHs == 1)
+ td->loc2d= (bezts + bezm->newIndex)->vec[0];
+ else
+ td->loc2d= (bezts + bezm->newIndex)->vec[2];
+ adjusted[j] = 1;
}
- else arrows_move_cursor(event);
}
- }
- if(afbreek) break;
- }
- }
-
- if(event==ESCKEY || event==RIGHTMOUSE) {
- tv= transmain;
- for(a=0; a<tot; a++, tv++) {
- tv->loc[0]= tv->oldloc[0];
- tv->loc[1]= tv->oldloc[1];
- }
-
- dosort= 0;
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
- if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
- if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
- if( test_time_ipocurve(ei->icu)) {
- dosort= 1;
- break;
- }
+ if (td->loc2d == bezm->bezt->vec[1]) {
+ td->loc2d= (bezts + bezm->newIndex)->vec[1];
+ adjusted[j] = 1;
}
}
}
- if(dosort) remake_ipo_transverts(transmain, 0, tot);
-
- ei= G.sipo->editipo;
- for(a=0; a<G.sipo->totipo; a++, ei++) {
- if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
- if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
- testhandles_ipocurve(ei->icu);
- }
+ }
+
+ /* free temp memory used for 'adjusted' array */
+ MEM_freeN(adjusted);
+}
+
+/* This function is called by recalcData during the Transform loop to recalculate
+ * the handles of curves and sort the keyframes so that the curves draw correctly.
+ * It is only called if some keyframes have moved out of order.
+ */
+void remake_ipo_transdata (TransInfo *t)
+{
+ EditIpo *ei;
+ int a;
+
+ /* sort and reassign verts */
+ ei= G.sipo->editipo;
+ for (a=0; a<G.sipo->totipo; a++, ei++) {
+ if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+ if (ei->icu->bezt) {
+ BeztMap *bezm;
+
+ /* adjust transform-data pointers */
+ bezm= bezt_to_beztmaps(ei->icu->bezt, ei->icu->totvert);
+ sort_time_beztmaps(bezm, ei->icu->totvert);
+ beztmap_to_data(t, ei, bezm, ei->icu->totvert);
+
+ /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */
+ sort_time_ipocurve(ei->icu);
+
+ /* free mapping stuff */
+ MEM_freeN(bezm);
+
+ /* make sure handles are all set correctly */
+ testhandles_ipocurve(ei->icu);
}
}
- calc_ipo(G.sipo->ipo, (float)CFRA);
}
- else BIF_undo_push("Transform Ipo");
+
+ /* remake ipokeys */
+ if (G.sipo->showkey) make_ipokey();
+}
+/* This function acts as the entrypoint for transforms in the IPO editor (as for
+ * the Action and NLA editors). The actual transform loop is not here anymore.
+ */
+void transform_ipo (int mode)
+{
+ short tmode;
+ short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
+
+ /* data-validation */
+ if (G.sipo->ipo && G.sipo->ipo->id.lib) return;
+ if (G.sipo->editipo==0) return;
+
+ /* convert ascii-based mode to transform system constants (mode) */
+ switch (mode) {
+ case 'g':
+ tmode= TFM_TRANSLATION;
+ break;
+ case 'r':
+ tmode= TFM_ROTATION;
+ break;
+ case 's':
+ tmode= TFM_RESIZE;
+ break;
+ default:
+ tmode= 0;
+ return;
+ }
+
+ /* the transform system method involved depends on the selection */
+ get_status_editipo();
+ if (totipo_vertsel) {
+ /* we're probably in editmode, so only selected verts - transform system */
+ initTransform(tmode, context);
+ Transform();
+ }
+ else if (totipo_edit==0 && totipo_sel!=0) {
+ /* we're not in editmode, so entire curves get moved - transform system*/
+ initTransform(tmode, context);
+ Transform();
+ }
+ else {
+ /* shapekey mode? special transform code */
+ if (totipo_edit==0)
+ move_keys(OBACT);
+ return;
+ }
+
+ /* cleanup */
editipo_changed(G.sipo, 1);
-
- MEM_freeN(transmain);
}
+/**************************************************/
+
void filter_sampledata(float *data, int sfra, int efra)
{
float *da;
@@ -5049,7 +5542,7 @@ void ipo_record(void)
/* make curves ready, start values */
if(ei1->icu==NULL)
- ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei1->adrcode);
+ ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei1->adrcode);
if(ei1->icu==NULL) return;
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
@@ -5059,7 +5552,7 @@ void ipo_record(void)
if(ei2) {
if(ei2->icu==NULL)
- ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei2->adrcode);
+ ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei2->adrcode);
if(ei2->icu==NULL) return;
poin= get_ipo_poin(G.sipo->from, ei2->icu, &type);
@@ -5096,7 +5589,7 @@ void ipo_record(void)
waitcursor(1);
tottime= 0.0;
- swaptime= 1.0/(float)G.scene->r.frs_sec;
+ swaptime= 1.0/FPS;
cfrao= CFRA;
cfra=efra= SFRA;
@@ -5238,22 +5731,25 @@ void remake_object_ipos(Object *ob)
/* Only delete the nominated keyframe from provided ipo-curve.
* Not recommended to be used many times successively. For that
- * there is delete_ipo_keys(). */
-void delete_icu_key(IpoCurve *icu, int index)
+ * there is delete_ipo_keys().
+ */
+void delete_icu_key(IpoCurve *icu, int index, short do_recalc)
{
/* firstly check that index is valid */
if (index < 0)
index *= -1;
+ if (icu == NULL)
+ return;
if (index >= icu->totvert)
return;
- if (!icu) return;
/* Delete this key */
- memcpy (&icu->bezt[index], &icu->bezt[index+1], sizeof (BezTriple)*(icu->totvert-index-1));
+ memmove(&icu->bezt[index], &icu->bezt[index+1], sizeof(BezTriple)*(icu->totvert-index-1));
icu->totvert--;
- /* recalc handles */
- calchandles_ipocurve(icu);
+ /* recalc handles - only if it won't cause problems */
+ if (do_recalc)
+ calchandles_ipocurve(icu);
}
void delete_ipo_keys(Ipo *ipo)
@@ -5261,22 +5757,24 @@ void delete_ipo_keys(Ipo *ipo)
IpoCurve *icu, *next;
int i;
- if (!ipo)
+ if (ipo == NULL)
return;
- for (icu=ipo->curve.first; icu; icu=next){
+ for (icu= ipo->curve.first; icu; icu= next) {
next = icu->next;
- for (i=0; i<icu->totvert; i++){
- if (icu->bezt[i].f2 & 1){
- // Delete the item
- memcpy (&icu->bezt[i], &icu->bezt[i+1], sizeof (BezTriple)*(icu->totvert-i-1));
+
+ /* Delete selected BezTriples */
+ for (i=0; i<icu->totvert; i++) {
+ if (icu->bezt[i].f2 & SELECT) {
+ memmove(&icu->bezt[i], &icu->bezt[i+1], sizeof(BezTriple)*(icu->totvert-i-1));
icu->totvert--;
i--;
}
}
- if (!icu->totvert){
- /* Delete the curve */
- BLI_remlink( &(ipo->curve), icu);
+
+ /* Only delete if there isn't an ipo-driver still hanging around on an empty curve */
+ if (icu->totvert==0 && icu->driver==NULL) {
+ BLI_remlink(&ipo->curve, icu);
free_ipo_curve(icu);
}
}
@@ -5373,8 +5871,8 @@ void move_to_frame(void)
id= G.sipo->from;
if(id && GS(id->name)==ID_OB ) {
Object *ob= (Object *)id;
- if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
- cfra+= ob->sf/G.scene->r.framelen;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ cfra+= give_timeoffset(ob)/G.scene->r.framelen;
}
}
CFRA= (int)floor(cfra+0.5);
diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c
index 96be44e1234..41044ad13d7 100644
--- a/source/blender/src/editipo_lib.c
+++ b/source/blender/src/editipo_lib.c
@@ -34,12 +34,15 @@
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
+#include "BKE_key.h"
#include "BKE_utildefines.h"
#include "BIF_resources.h"
@@ -56,9 +59,9 @@ char *ob_ic_names[OB_TOTNAM] = { "LocX", "LocY", "LocZ", "dLocX", "dLocY", "dLoc
"RotX", "RotY", "RotZ", "dRotX", "dRotY", "dRotZ",
"ScaleX", "ScaleY", "ScaleZ", "dScaleX", "dScaleY", "dScaleZ",
"Layer", "Time", "ColR", "ColG", "ColB", "ColA",
- "FStreng", "FFall", "RDamp", "Damping", "Perm" };
+ "FStreng", "FFall", "RDamp", "Damping", "Perm", "FMaxD" };
-char *co_ic_names[CO_TOTNAM] = { "Inf" };
+char *co_ic_names[CO_TOTNAM] = { "Inf", "HeadTail" };
char *mtex_ic_names[TEX_TOTNAM] = { "OfsX", "OfsY", "OfsZ", "SizeX", "SizeY", "SizeZ",
"texR", "texG", "texB", "DefVar", "Col", "Nor", "Var",
"Disp" };
@@ -98,6 +101,9 @@ char *ac_ic_names[AC_TOTNAM] = {"LocX", "LocY", "LocZ", "ScaleX", "ScaleY",
"ScaleZ", "QuatW", "QuatX", "QuatY", "QuatZ"};
char *ic_name_empty[1] ={ "" };
char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time", "GravX","GravY","GravZ", "VelX","VelY","VelZ", "Active" };
+char *part_ic_names[PART_TOTNAM] = { "E_Freq", "E_Life", "E_Speed", "E_Angular", "E_Size",
+"Angular", "Size", "Drag", "Brown", "Damp", "Length", "Clump",
+"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt"};
/* gets the appropriate icon for the given blocktype */
int geticon_ipo_blocktype(short blocktype)
@@ -130,8 +136,11 @@ int geticon_ipo_blocktype(short blocktype)
}
}
-/* get name of ipo-curve (icu should be valid pointer) */
-char *getname_ipocurve(IpoCurve *icu)
+/* get name of ipo-curve
+ * - icu should be valid pointer
+ * - ob is only needed for a shapekey-related hack
+ */
+char *getname_ipocurve(IpoCurve *icu, Object *ob)
{
switch (icu->blocktype) {
case ID_OB:
@@ -140,11 +149,17 @@ char *getname_ipocurve(IpoCurve *icu)
return getname_ac_ei(icu->adrcode);
case ID_KE:
{
- /* quick 'hack' - must find a better solution to this
- * although shapekey ipo-curves can have names,
- * we don't have access to that info yet.
- */
static char name[32];
+ Key *key= ob_get_key(ob);
+ KeyBlock *kb= key_get_keyblock(key, icu->adrcode);
+
+ /* only return name if it has been set, otherwise use
+ * default method using static string (Key #)
+ */
+ if ((kb) && (kb->name[0] != '\0'))
+ return kb->name; /* return keyblock's name */
+
+ /* in case keyblock is not named or no key/keyblock was found */
sprintf(name, "Key %d", icu->adrcode);
return name;
}
@@ -179,6 +194,7 @@ char *getname_co_ei(int nr)
{
switch(nr){
case CO_ENFORCE:
+ case CO_HEADTAIL:
return co_ic_names[nr-1];
}
return ic_name_empty[0];
@@ -186,7 +202,7 @@ char *getname_co_ei(int nr)
char *getname_ob_ei(int nr, int colipo)
{
- if(nr>=OB_LOC_X && nr <= OB_PD_PERM) return ob_ic_names[nr-1];
+ if(nr>=OB_LOC_X && nr <= OB_PD_FMAXD) return ob_ic_names[nr-1];
return ic_name_empty[0];
}
@@ -261,9 +277,14 @@ char *getname_fluidsim_ei(int nr)
if(nr <= FLUIDSIM_TOTIPO) return fluidsim_ic_names[nr-1];
return ic_name_empty[0];
}
+char *getname_part_ei(int nr)
+{
+ if(nr <= PART_TOTIPO) return part_ic_names[nr-1];
+ return ic_name_empty[0];
+}
-void boundbox_ipocurve(IpoCurve *icu)
+void boundbox_ipocurve(IpoCurve *icu, int selectedonly)
{
BezTriple *bezt;
float vec[3]={0.0,0.0,0.0};
@@ -278,20 +299,25 @@ void boundbox_ipocurve(IpoCurve *icu)
bezt= icu->bezt;
while(a--) {
if(icu->vartype & IPO_BITS) {
- vec[0]= bezt->vec[1][0];
- vec[1]= 0.0;
- DO_MINMAX(vec, min, max);
-
- vec[1]= 16.0;
- DO_MINMAX(vec, min, max);
+ if((bezt->f2 & SELECT) || !selectedonly) {
+ vec[0]= bezt->vec[1][0];
+ vec[1]= 0.0;
+ DO_MINMAX(vec, min, max);
+
+ vec[1]= 16.0;
+ DO_MINMAX(vec, min, max);
+ }
}
else {
- if(icu->ipo==IPO_BEZ && a!=icu->totvert-1) {
- DO_MINMAX(bezt->vec[0], min, max);
+ if((bezt->f1 & SELECT) || !selectedonly) {
+ if(icu->ipo==IPO_BEZ && a!=icu->totvert-1)
+ DO_MINMAX(bezt->vec[0], min, max);
}
- DO_MINMAX(bezt->vec[1], min, max);
- if(icu->ipo==IPO_BEZ && a!=0) {
- DO_MINMAX(bezt->vec[2], min, max);
+ if((bezt->f2 & SELECT) || !selectedonly)
+ DO_MINMAX(bezt->vec[1], min, max);
+ if((bezt->f3 & SELECT) || !selectedonly) {
+ if(icu->ipo==IPO_BEZ && a!=0)
+ DO_MINMAX(bezt->vec[2], min, max);
}
}
@@ -313,7 +339,7 @@ void boundbox_ipocurve(IpoCurve *icu)
}
}
-void boundbox_ipo(Ipo *ipo, rctf *bb)
+void boundbox_ipo(Ipo *ipo, rctf *bb, int selectedonly)
{
IpoCurve *icu;
int first= 1;
@@ -321,7 +347,7 @@ void boundbox_ipo(Ipo *ipo, rctf *bb)
icu= ipo->curve.first;
while(icu) {
- boundbox_ipocurve(icu);
+ boundbox_ipocurve(icu, selectedonly);
if(first) {
*bb= icu->totrct;
@@ -371,3 +397,5 @@ int texchannel_to_adrcode(int channel)
}
+
+
diff --git a/source/blender/src/editipo_mods.c b/source/blender/src/editipo_mods.c
index fe88d2da3c0..ae283ce8c0b 100644
--- a/source/blender/src/editipo_mods.c
+++ b/source/blender/src/editipo_mods.c
@@ -58,6 +58,7 @@
#include "BKE_key.h"
#include "BKE_utildefines.h"
+#include "BIF_editaction.h"
#include "BIF_interface.h"
#include "BIF_screen.h"
#include "BIF_space.h"
@@ -79,15 +80,13 @@ extern int totipo_edit, totipo_sel, totipo_vertsel, totipo_vis;
void ipo_toggle_showkey(void)
{
- if(G.sipo->showkey) {
- G.sipo->showkey= 0;
- swap_selectall_editipo(); /* sel all */
- }
+ if(G.sipo->showkey) G.sipo->showkey= 0;
else G.sipo->showkey= 1;
+
free_ipokey(&G.sipo->ipokey);
if(G.sipo->ipo) G.sipo->ipo->showkey= G.sipo->showkey;
- BIF_undo_push("Toggle show key Ipo");
+ BIF_undo_push("Toggle Show Key Ipo");
}
void swap_selectall_editipo(void)
@@ -140,7 +139,7 @@ void swap_selectall_editipo(void)
bezt->f1= bezt->f2= bezt->f3= 0;
}
else {
- bezt->f1= bezt->f2= bezt->f3= 1;
+ bezt->f1= bezt->f2= bezt->f3= SELECT;
}
bezt++;
}
@@ -376,32 +375,32 @@ static int selected_bezier_loop(int (*looptest)(EditIpo *),
int select_bezier_add(BezTriple *bezt)
{
/* Select the bezier triple */
- bezt->f1 |= 1;
- bezt->f2 |= 1;
- bezt->f3 |= 1;
+ bezt->f1 |= SELECT;
+ bezt->f2 |= SELECT;
+ bezt->f3 |= SELECT;
return 0;
}
int select_bezier_subtract(BezTriple *bezt)
{
/* Deselect the bezier triple */
- bezt->f1 &= ~1;
- bezt->f2 &= ~1;
- bezt->f3 &= ~1;
+ bezt->f1 &= ~SELECT;
+ bezt->f2 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
return 0;
}
int select_bezier_invert(BezTriple *bezt)
{
/* Invert the selection for the bezier triple */
- bezt->f2 ^= 1;
- if ( bezt->f2 & 1 ) {
- bezt->f1 |= 1;
- bezt->f3 |= 1;
+ bezt->f2 ^= SELECT;
+ if ( bezt->f2 & SELECT ) {
+ bezt->f1 |= SELECT;
+ bezt->f3 |= SELECT;
}
else {
- bezt->f1 &= ~1;
- bezt->f3 &= ~1;
+ bezt->f1 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
}
return 0;
}
@@ -496,21 +495,40 @@ static int vis_edit_icu_bez(EditIpo *ei)
void select_ipo_bezier_keys(Ipo *ipo, int selectmode)
{
- /* Select all of the beziers in all
- * of the Ipo curves belonging to the
- * Ipo, using the selection mode.
- */
- switch (selectmode) {
- case SELECT_ADD:
- ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
- break;
- case SELECT_SUBTRACT:
- ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
- break;
- case SELECT_INVERT:
- ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
- break;
- }
+ /* Select all of the beziers in all
+ * of the Ipo curves belonging to the
+ * Ipo, using the selection mode.
+ */
+ switch (selectmode) {
+ case SELECT_ADD:
+ ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
+ break;
+ case SELECT_SUBTRACT:
+ ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
+ break;
+ case SELECT_INVERT:
+ ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
+ break;
+ }
+}
+
+void select_icu_bezier_keys(IpoCurve *icu, int selectmode)
+{
+ /* Select all of the beziers in all
+ * of the Ipo curves belonging to the
+ * Ipo, using the selection mode.
+ */
+ switch (selectmode) {
+ case SELECT_ADD:
+ icu_keys_bezier_loop(icu, select_bezier_add, NULL);
+ break;
+ case SELECT_SUBTRACT:
+ icu_keys_bezier_loop(icu, select_bezier_subtract, NULL);
+ break;
+ case SELECT_INVERT:
+ icu_keys_bezier_loop(icu, select_bezier_invert, NULL);
+ break;
+ }
}
void sethandles_ipo_keys(Ipo *ipo, int code)
@@ -557,6 +575,14 @@ static int snap_bezier_nearest(BezTriple *bezt)
return 0;
}
+static int snap_bezier_nearestsec(BezTriple *bezt)
+{
+ float secf = FPS;
+ if(bezt->f2 & SELECT)
+ bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]/secf + 0.5f) * secf);
+ return 0;
+}
+
static int snap_bezier_cframe(BezTriple *bezt)
{
if(bezt->f2 & SELECT)
@@ -575,7 +601,7 @@ static int snap_bezier_nearmarker(BezTriple *bezt)
void snap_ipo_keys(Ipo *ipo, short snaptype)
{
switch (snaptype) {
- case 1: /* snap to nearest */
+ case 1: /* snap to nearest frame */
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
break;
case 2: /* snap to current frame */
@@ -584,6 +610,9 @@ void snap_ipo_keys(Ipo *ipo, short snaptype)
case 3: /* snap to nearest marker */
ipo_keys_bezier_loop(ipo, snap_bezier_nearmarker, calchandles_ipocurve);
break;
+ case 4: /* snap to nearest second */
+ ipo_keys_bezier_loop(ipo, snap_bezier_nearestsec, calchandles_ipocurve);
+ break;
default: /* just in case */
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
break;
@@ -694,6 +723,53 @@ void mirror_ipo_keys(Ipo *ipo, short mirror_type)
}
}
+/* This function is called to calculate the average location of the
+ * selected keyframes, and place the current frame at that location.
+ *
+ * It must be called like so:
+ * snap_cfra_ipo_keys(NULL, -1); // initialise the static vars first
+ * for (ipo...) snap_cfra_ipo_keys(ipo, 0); // sum up keyframe times
+ * snap_cfra_ipo_keys(NULL, 1); // set current frame after taking average
+ */
+void snap_cfra_ipo_keys(Ipo *ipo, short mode)
+{
+ static int cfra;
+ static int tot;
+
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int a;
+
+
+ if (mode == -1) {
+ /* initialise a new snap-operation */
+ cfra= 0;
+ tot= 0;
+ }
+ else if (mode == 1) {
+ /* set current frame - using average frame */
+ if (tot != 0)
+ CFRA = cfra / tot;
+ }
+ else {
+ /* loop through keys in ipo, summing the frame
+ * numbers of those that are selected
+ */
+ if (ipo == NULL)
+ return;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
+ if (BEZSELECTED(bezt)) {
+ cfra += bezt->vec[1][0];
+ tot++;
+ }
+ }
+ }
+ }
+}
+
+
/* currently only used by some action editor tools, but may soon get used by ipo editor */
/* restore = whether to map points back to ipo-time
* only_keys = whether to only adjust the location of the center point of beztriples
@@ -843,9 +919,8 @@ void setipotype_ipo(Ipo *ipo, int code)
void setexprap_ipoloop(Ipo *ipo, int code)
{
IpoCurve *icu;
-
- /* Loop through each curve in the Ipo
- */
+
+ /* Loop through each curve in the Ipo */
for (icu=ipo->curve.first; icu; icu=icu->next)
icu->extrap= code;
}
@@ -910,7 +985,7 @@ void borderselect_ipo(void)
if(val) {
/* map ipo-points for editing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 0, 0);
}
@@ -948,11 +1023,11 @@ void borderselect_ipo(void)
int bit= (val==LEFTMOUSE);
if(BLI_in_rctf(&rectf, bezt->vec[0][0], bezt->vec[0][1]))
- bezt->f1 = (bezt->f1&~1) | bit;
+ bezt->f1 = (bezt->f1&~SELECT) | bit;
if(BLI_in_rctf(&rectf, bezt->vec[1][0], bezt->vec[1][1]))
- bezt->f2 = (bezt->f2&~1) | bit;
+ bezt->f2 = (bezt->f2&~SELECT) | bit;
if(BLI_in_rctf(&rectf, bezt->vec[2][0], bezt->vec[2][1]))
- bezt->f3 = (bezt->f3&~1) | bit;
+ bezt->f3 = (bezt->f3&~SELECT) | bit;
bezt++;
}
@@ -962,7 +1037,7 @@ void borderselect_ipo(void)
}
/* undo mapping of ipo-points for drawing if scaled ipo */
- if (OBACT && OBACT->action && G.sipo->pin==0 && G.sipo->actname) {
+ if (NLA_IPO_SCALED) {
actstrip_map_ipo_keys(OBACT, G.sipo->ipo, 1, 0);
}
diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c
index 85dac9ee3c5..5cc193f8844 100644
--- a/source/blender/src/editkey.c
+++ b/source/blender/src/editkey.c
@@ -67,6 +67,7 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
@@ -170,9 +171,9 @@ static void rvk_slider_func(void *voidob, void *voidkeynum)
/* ipo on action or ob? */
if(ob->ipoflag & OB_ACTION_KEY)
- icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, keynum);
+ icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, NULL, keynum);
else
- icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, keynum);
+ icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, NULL, keynum);
if (icu) {
/* if the ipocurve exists, try to get a bezier
@@ -183,8 +184,8 @@ static void rvk_slider_func(void *voidob, void *voidkeynum)
/* create the bezier triple if one doesn't exist,
* otherwise modify it's value
*/
- if (!bezt) {
- insert_vert_ipo(icu, cfra, meshslidervals[keynum]);
+ if (bezt == NULL) {
+ insert_vert_icu(icu, cfra, meshslidervals[keynum], 0);
}
else {
bezt->vec[1][1] = meshslidervals[keynum];
@@ -380,7 +381,7 @@ static KeyBlock *add_keyblock(Key *key)
if(key->type == KEY_RELATIVE)
kb->pos= curpos+0.1;
else {
- curpos= bsystem_time(0, 0, (float)CFRA, 0.0);
+ curpos= bsystem_time(0, (float)CFRA, 0.0);
if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) {
curpos /= 100.0;
}
@@ -599,26 +600,32 @@ void insert_curvekey(Curve *cu, short rel)
void insert_shapekey(Object *ob)
{
- Key *key;
-
- if(ob->type==OB_MESH) insert_meshkey(ob->data, 1);
- else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data, 1);
- else if(ob->type==OB_LATTICE) insert_lattkey(ob->data, 1);
-
- key= ob_get_key(ob);
- ob->shapenr= BLI_countlist(&key->block);
-
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWBUTSOBJECT, 0);
- allqueue(REDRAWBUTSEDIT, 0);
+ if(get_mesh(ob) && get_mesh(ob)->mr) {
+ error("Cannot create shape keys on a multires mesh.");
+ }
+ else {
+ Key *key;
+
+ if(ob->type==OB_MESH) insert_meshkey(ob->data, 1);
+ else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data, 1);
+ else if(ob->type==OB_LATTICE) insert_lattkey(ob->data, 1);
+
+ key= ob_get_key(ob);
+ ob->shapenr= BLI_countlist(&key->block);
+
+ BIF_undo_push("Add Shapekey");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
}
void delete_key(Object *ob)
{
- KeyBlock *kb;
+ KeyBlock *kb, *rkb;
Key *key;
IpoCurve *icu;
@@ -628,6 +635,10 @@ void delete_key(Object *ob)
kb= BLI_findlink(&key->block, ob->shapenr-1);
if(kb) {
+ for(rkb= key->block.first; rkb; rkb= rkb->next)
+ if(rkb->relative == ob->shapenr-1)
+ rkb->relative= 0;
+
BLI_remlink(&key->block, kb);
key->totkey--;
if(key->refkey== kb) key->refkey= key->block.first;
@@ -668,6 +679,7 @@ void delete_key(Object *ob)
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ BIF_undo_push("Delete Shapekey");
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allspace(REMAKEIPO, 0);
@@ -756,6 +768,7 @@ void move_keys(Object *ob)
/* for boundbox */
editipo_changed(G.sipo, 0);
+ BIF_undo_push("Move Shapekey(s)");
allspace(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWVIEW3D, 0);
diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c
index 9aa363a654f..e80e87b6976 100644
--- a/source/blender/src/editlattice.c
+++ b/source/blender/src/editlattice.c
@@ -240,7 +240,7 @@ static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, in
struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
- if ((bp->f1&1)==data->select) temp += 5;
+ if ((bp->f1 & SELECT)==data->select) temp += 5;
if (temp<data->dist) {
data->dist = temp;
@@ -274,17 +274,13 @@ void mouse_lattice(void)
if((G.qual & LR_SHIFTKEY)==0) {
setflagsLatt(0);
- bp->f1 |= 1;
+ bp->f1 |= SELECT;
allqueue(REDRAWVIEW3D, 0);
}
else {
-
- if(bp->f1 & 1) bp->f1 &= ~1;
- else bp->f1 |= 1;
-
+ bp->f1 ^= SELECT; /* swap */
allqueue(REDRAWVIEW3D, 0);
-
}
countall();
@@ -298,28 +294,51 @@ void mouse_lattice(void)
/* **************** undo for lattice object ************** */
-static void undoLatt_to_editLatt(void *defv)
+typedef struct UndoLattice {
+ BPoint *def;
+ int pntsu, pntsv, pntsw;
+} UndoLattice;
+
+static void undoLatt_to_editLatt(void *data)
{
+ UndoLattice *ult= (UndoLattice*)data;
int a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
- memcpy(editLatt->def, defv, a*sizeof(BPoint));
+ memcpy(editLatt->def, ult->def, a*sizeof(BPoint));
}
static void *editLatt_to_undoLatt(void)
{
+ UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice");
+ ult->def= MEM_dupallocN(editLatt->def);
+ ult->pntsu= editLatt->pntsu;
+ ult->pntsv= editLatt->pntsv;
+ ult->pntsw= editLatt->pntsw;
- return MEM_dupallocN(editLatt->def);
+ return ult;
+}
+
+static void free_undoLatt(void *data)
+{
+ UndoLattice *ult= (UndoLattice*)data;
+
+ if(ult->def) MEM_freeN(ult->def);
+ MEM_freeN(ult);
}
-static void free_undoLatt(void *defv)
+static int validate_undoLatt(void *data)
{
- MEM_freeN(defv);
+ UndoLattice *ult= (UndoLattice*)data;
+
+ return (ult->pntsu == editLatt->pntsu &&
+ ult->pntsv == editLatt->pntsv &&
+ ult->pntsw == editLatt->pntsw);
}
/* and this is all the undo system needs to know */
void undo_push_lattice(char *name)
{
- undo_editmode_push(name, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt);
+ undo_editmode_push(name, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt);
}
diff --git a/source/blender/src/editmball.c b/source/blender/src/editmball.c
index 91f0f25ec60..10ef8756ebf 100644
--- a/source/blender/src/editmball.c
+++ b/source/blender/src/editmball.c
@@ -30,6 +30,7 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+#include <math.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
@@ -40,6 +41,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_rand.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -47,6 +49,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_utildefines.h"
#include "BKE_depsgraph.h"
@@ -130,6 +133,7 @@ void add_primitiveMball(int dummy_argument)
{
MetaElem *ml;
float *curs, mat[3][3], cent[3], imat[3][3], cmat[3][3];
+ short newob= 0;
if(G.scene->id.lib) return;
@@ -148,6 +152,7 @@ void add_primitiveMball(int dummy_argument)
make_editMball();
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
+ newob= 1;
}
/* deselect */
@@ -220,7 +225,15 @@ void add_primitiveMball(int dummy_argument)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); // added ball can influence others
- countall();
+ countall();
+
+ /* if a new object was created, it stores it in Mball, for reload original data and undo */
+ if ( !(newob) || (U.flag & USER_ADD_EDITMODE)) {
+ if(newob) load_editMball();
+ } else {
+ exit_editmode(2);
+ }
+
allqueue(REDRAWALL, 0);
BIF_undo_push("Add MetaElem");
}
@@ -251,6 +264,43 @@ void deselectall_mball()
BIF_undo_push("Deselect MetaElem");
}
+/* inverts metaball selection */
+void selectinverse_mball()
+{
+ MetaElem *ml;
+
+ ml= editelems.first;
+ while(ml) {
+ if(ml->flag & SELECT) ml->flag &= ~SELECT;
+ else ml->flag |= SELECT;
+ ml= ml->next;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ countall();
+ BIF_undo_push("Invert MetaElem");
+}
+
+/* select random metaball selection */
+void selectrandom_mball()
+{
+ MetaElem *ml;
+ static short randfac= 50;
+
+ if(!button(&randfac,0, 100,"Percentage:")) return;
+
+ ml= editelems.first;
+ BLI_srand( BLI_rand() ); /* random seed */
+ while(ml) {
+ if((BLI_frand() * 100) < randfac) ml->flag |= SELECT;
+ ml= ml->next;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ countall();
+ BIF_undo_push("Random MetaElem");
+}
+
/* select MetaElement with mouse click (user can select radius circle or
* stiffness circle) */
void mouse_mball()
@@ -444,7 +494,7 @@ static void free_undoMball(void *lbv)
/* this is undo system for MetaBalls */
void undo_push_mball(char *name)
{
- undo_editmode_push(name, free_undoMball, undoMball_to_editMball, editMball_to_undoMball);
+ undo_editmode_push(name, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL);
}
/* Hide selected/unselected MetaElems */
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 9b0811bf788..34d3bc89bdb 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -65,6 +65,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_depsgraph.h"
+#include "BKE_cloth.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -72,7 +73,10 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_multires.h"
#include "BKE_object.h"
+#include "BKE_pointcache.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -159,10 +163,13 @@ EditVert *addvertlist(float *vec, EditVert *example)
createVerseVert(eve);
#endif
- if(example)
+ if(example) {
CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data);
- else
+ eve->bweight = example->bweight;
+ }
+ else {
CustomData_em_set_default(&em->vdata, &eve->data);
+ }
return eve;
}
@@ -295,6 +302,7 @@ EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
rule is to do this with addedgelist call, before addfacelist */
if(example) {
eed->crease= example->crease;
+ eed->bweight= example->bweight;
eed->sharp = example->sharp;
eed->seam = example->seam;
eed->h |= (example->h & EM_FGON);
@@ -333,6 +341,10 @@ void free_editface(EditFace *efa)
}
#endif
EM_remove_selection(efa, EDITFACE);
+
+ if (G.editMesh->act_face==efa)
+ EM_set_actFace(NULL);
+
CustomData_em_free_block(&G.editMesh->fdata, &efa->data);
if(efa->fast==0)
free(efa);
@@ -797,7 +809,10 @@ void make_editMesh()
EditFace *efa;
EditEdge *eed;
EditSelection *ese;
- int tot, a, eekadoodle= 0;
+ int tot, a, eekadoodle= 0, cloth_enabled = 0;
+ ClothModifierData *clmd = NULL;
+ Cloth *cloth = NULL;
+ float temp[3];
#ifdef WITH_VERSE
if(me->vnode){
@@ -809,10 +824,11 @@ void make_editMesh()
/* because of reload */
free_editMesh(em);
+ em->act_face = NULL;
G.totvert= tot= me->totvert;
G.totedge= me->totedge;
G.totface= me->totface;
-
+
if(tot==0) {
countall();
return;
@@ -831,14 +847,53 @@ void make_editMesh()
/* make editverts */
CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
mvert= me->mvert;
+
+ /* lots of checks to be sure if we have nice cloth object */
+ if(modifiers_isClothEnabled(G.obedit))
+ {
+ clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth);
+ cloth = clmd->clothObject;
+
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+
+ /* just to be sure also check vertcount */
+ /* also check if we have a protected cache */
+ if(cloth && (tot == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+ {
+ /* check if we have cache for this frame */
+ int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd);
+
+ if(BKE_ptcache_id_exist((ID *)G.obedit, G.scene->r.cfra, stack_index))
+ {
+ cloth_enabled = 1;
+
+ clmd->sim_parms->editedframe = G.scene->r.cfra;
+
+ /* inverse matrix is not uptodate... */
+ Mat4Invert ( G.obedit->imat, G.obedit->obmat );
+ if(G.rt > 0)
+ printf("make_editmesh --> cloth_enabled\n");
+ }
+ }
+ }
evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
for(a=0; a<tot; a++, mvert++) {
- eve= addvertlist(mvert->co, NULL);
+
+ if(cloth_enabled)
+ {
+ VECCOPY(temp, cloth->verts[a].x);
+ Mat4MulVecfl ( G.obedit->imat, temp );
+ eve= addvertlist(temp, NULL);
+
+ /* TODO: what about normals? */
+ }
+ else
+ eve= addvertlist(mvert->co, NULL);
evlist[a]= eve;
// face select sets selection in next loop
- if( (G.f & G_FACESELECT)==0 )
+ if( (FACESEL_PAINT_TEST)==0 )
eve->f |= (mvert->flag & 1);
if (mvert->flag & ME_HIDE) eve->h= 1;
@@ -846,6 +901,8 @@ void make_editMesh()
eve->no[1]= mvert->no[1]/32767.0;
eve->no[2]= mvert->no[2]/32767.0;
+ eve->bweight= ((float)mvert->bweight)/255.0f;
+
/* lets overwrite the keyindex of the editvert
* with the order it used to be in before
* editmode
@@ -859,12 +916,14 @@ void make_editMesh()
else {
MEdge *medge= me->medge;
+ CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
/* make edges */
for(a=0; a<me->totedge; a++, medge++) {
eed= addedgelist(evlist[medge->v1], evlist[medge->v2], NULL);
/* eed can be zero when v1 and v2 are identical, dxf import does this... */
if(eed) {
- eed->crease= ((float)medge->crease)/255.0;
+ eed->crease= ((float)medge->crease)/255.0f;
+ eed->bweight= ((float)medge->bweight)/255.0f;
if(medge->flag & ME_SEAM) eed->seam= 1;
if(medge->flag & ME_SHARP) eed->sharp = 1;
@@ -873,6 +932,7 @@ void make_editMesh()
if(medge->flag & ME_HIDE) eed->h |= 1;
if(G.scene->selectmode==SCE_SELECT_EDGE)
EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ...
+ CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
}
}
@@ -902,8 +962,11 @@ void make_editMesh()
}
if(mface->flag & ME_HIDE) efa->h= 1;
- if((G.f & G_FACESELECT) && (efa->f & SELECT))
+ if((FACESEL_PAINT_TEST) && (efa->f & SELECT))
EM_select_face(efa, 1); /* flush down */
+
+ if (a==me->act_face)
+ em->act_face = efa;
}
}
}
@@ -922,7 +985,7 @@ void make_editMesh()
for(a=0; a<me->totselect; a++, mselect++){
/*check if recorded selection is still valid, if so copy into editmesh*/
- if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & SELECT) ){
+ if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ){
ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
ese->type = mselect->type;
if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
@@ -958,8 +1021,11 @@ void load_editMesh(void)
EditEdge *eed;
EditSelection *ese;
float *fp, *newkey, *oldkey, nor[3];
- int i, a, ototvert, totedge=0;
-
+ int i, a, ototvert, totedge=0, cloth_enabled = 0;
+ ClothModifierData *clmd = NULL;
+ Cloth *cloth = NULL;
+ float temp[3], dt = 0.0;
+
#ifdef WITH_VERSE
if(em->vnode) {
struct VNode *vnode = (VNode*)em->vnode;
@@ -1014,6 +1080,7 @@ void load_editMesh(void)
me->totface= G.totface;
CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
+ CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface);
CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
@@ -1024,9 +1091,60 @@ void load_editMesh(void)
/* the vertices, use ->tmp.l as counter */
eve= em->verts.first;
a= 0;
-
+
+ /* lots of checks to be sure if we have nice cloth object */
+ if(modifiers_isClothEnabled(G.obedit))
+ {
+ clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth);
+ cloth = clmd->clothObject;
+
+ /* just to be sure also check vertcount */
+ /* also check if we have a protected cache */
+ if(cloth && (G.totvert == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+ {
+ /* check if we have cache for this frame */
+ int stack_index = modifiers_indexInObject(G.obedit, (ModifierData *)clmd);
+
+ if(BKE_ptcache_id_exist((ID *)G.obedit, clmd->sim_parms->editedframe, stack_index))
+ {
+ cloth_enabled = 1;
+
+ /* inverse matrix is not uptodate... */
+ Mat4Invert ( G.obedit->imat, G.obedit->obmat );
+ dt = 1.0f / clmd->sim_parms->stepsPerFrame;
+ }
+ if(G.rt > 0)
+ printf("loadmesh --> tot: %d, num: %d\n", G.totvert, cloth->numverts);
+ }
+ }
+
+ i=0;
while(eve) {
- VECCOPY(mvert->co, eve->co);
+
+ if(cloth_enabled)
+ {
+ if(G.rt > 0)
+ printf("loadmesh --> cloth_enabled\n");
+
+ VECCOPY(temp, cloth->verts[i].x);
+ VECCOPY(cloth->verts[i].x, eve->co);
+ Mat4MulVecfl ( G.obedit->obmat, cloth->verts[i].x );
+
+
+ // not physical correct but gives nicer results when commented
+ VECSUB(temp, cloth->verts[i].x, temp);
+ VecMulf(temp, 1.0f / (dt*10.0));
+ VECADD(cloth->verts[i].v, cloth->verts[i].v, temp);
+
+ if(oldverts) {
+ VECCOPY(mvert->co, oldverts[i].co);
+ if(G.rt > 0)
+ printf("loadmesh --> cloth_enabled oldverts\n");
+ }
+ i++;
+ }
+ else
+ VECCOPY(mvert->co, eve->co);
mvert->mat_nr= 255; /* what was this for, halos? */
/* vertex normal */
@@ -1043,7 +1161,8 @@ void load_editMesh(void)
mvert->flag= 0;
if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
mvert->flag |= (eve->f & SELECT);
- if (eve->h) mvert->flag |= ME_HIDE;
+ if (eve->h) mvert->flag |= ME_HIDE;
+ mvert->bweight= (char)(255.0*eve->bweight);
#ifdef WITH_VERSE
if(eve->vvert) {
@@ -1054,6 +1173,36 @@ void load_editMesh(void)
eve= eve->next;
mvert++;
}
+
+ /* burn changes to cache */
+ if(cloth_enabled)
+ {
+ if(G.rt > 0)
+ printf("loadmesh --> cloth_enabled cloth_write_cache\n");
+ cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe);
+
+ if(G.scene->r.cfra != clmd->sim_parms->editedframe)
+ {
+ if(cloth_read_cache(G.obedit, clmd, G.scene->r.cfra))
+ implicit_set_positions(clmd);
+ }
+ else
+ implicit_set_positions(clmd);
+
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+ }
+ else
+ {
+ if(modifiers_isClothEnabled(G.obedit)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(G.obedit, eModifierType_Cloth);
+ if(G.rt > 0)
+ printf("loadmesh --> CLOTH_SIMSETTINGS_FLAG_RESET\n");
+ /* only reset cloth when no cache was used */
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+ clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+ }
+ }
/* the edges */
a= 0;
@@ -1071,7 +1220,9 @@ void load_editMesh(void)
if(eed->h & 1) medge->flag |= ME_HIDE;
medge->crease= (char)(255.0*eed->crease);
-
+ medge->bweight= (char)(255.0*eed->bweight);
+ CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);
+
eed->tmp.l = a++;
medge++;
@@ -1082,6 +1233,7 @@ void load_editMesh(void)
a = 0;
efa= em->faces.first;
i = 0;
+ me->act_face = -1;
while(efa) {
mface= &((MFace *) me->mface)[i];
@@ -1136,6 +1288,9 @@ void load_editMesh(void)
/* no index '0' at location 3 or 4 */
test_index_face(mface, &me->fdata, i, efa->v4?4:3);
+
+ if (EM_get_actFace() == efa)
+ me->act_face = a;
#ifdef WITH_VERSE
if(efa->vface) {
@@ -1322,6 +1477,7 @@ void remake_editMesh(void)
{
make_editMesh();
allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0); /* needed to have nice cloth panels */
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
BIF_undo_push("Undo all changes");
}
@@ -1787,6 +1943,7 @@ typedef struct EditVertC
float no[3];
float co[3];
unsigned char f, h;
+ short bweight;
int keyindex;
} EditVertC;
@@ -1794,7 +1951,7 @@ typedef struct EditEdgeC
{
int v1, v2;
unsigned char f, h, seam, sharp, pad;
- short crease, fgoni;
+ short crease, bweight, fgoni;
} EditEdgeC;
typedef struct EditFaceC
@@ -1823,7 +1980,7 @@ typedef struct UndoMesh {
short selectmode;
RetopoPaintData *retopo_paint_data;
char retopo_mode;
- CustomData vdata, fdata;
+ CustomData vdata, edata, fdata;
EM_MultiresUndo *mru;
} UndoMesh;
@@ -1839,6 +1996,7 @@ static void free_undoMesh(void *umv)
if(um->selected) MEM_freeN(um->selected);
if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
CustomData_free(&um->vdata, um->totvert);
+ CustomData_free(&um->edata, um->totedge);
CustomData_free(&um->fdata, um->totface);
if(um->mru) {
--um->mru->users;
@@ -1881,6 +2039,7 @@ static void *editMesh_to_undoMesh(void)
if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
+ if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
/* now copy vertices */
@@ -1893,6 +2052,7 @@ static void *editMesh_to_undoMesh(void)
evec->h= eve->h;
evec->keyindex= eve->keyindex;
eve->tmp.l = a; /*store index*/
+ evec->bweight= (short)(eve->bweight*255.0);
CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
}
@@ -1907,8 +2067,11 @@ static void *editMesh_to_undoMesh(void)
eedc->seam= eed->seam;
eedc->sharp= eed->sharp;
eedc->crease= (short)(eed->crease*255.0);
+ eedc->bweight= (short)(eed->bweight*255.0);
eedc->fgoni= eed->fgoni;
eed->tmp.l = a; /*store index*/
+ CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
+
}
/* copy faces */
@@ -2000,9 +2163,11 @@ static void undoMesh_to_editMesh(void *umv)
#endif
CustomData_free(&em->vdata, 0);
+ CustomData_free(&em->edata, 0);
CustomData_free(&em->fdata, 0);
CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
+ CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
/* now copy vertices */
@@ -2016,6 +2181,7 @@ static void undoMesh_to_editMesh(void *umv)
eve->f= evec->f;
eve->h= evec->h;
eve->keyindex= evec->keyindex;
+ eve->bweight= ((float)evec->bweight)/255.0f;
CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
}
@@ -2029,7 +2195,9 @@ static void undoMesh_to_editMesh(void *umv)
eed->seam= eedc->seam;
eed->sharp= eedc->sharp;
eed->fgoni= eedc->fgoni;
- eed->crease= ((float)eedc->crease)/255.0;
+ eed->crease= ((float)eedc->crease)/255.0f;
+ eed->bweight= ((float)eedc->bweight)/255.0f;
+ CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
}
/* copy faces */
@@ -2089,7 +2257,7 @@ static void undoMesh_to_editMesh(void *umv)
/* and this is all the undo system needs to know */
void undo_push_mesh(char *name)
{
- undo_editmode_push(name, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh);
+ undo_editmode_push(name, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
}
@@ -2153,3 +2321,30 @@ EditFace *EM_get_face_for_index(int index)
{
return g_em_face_array?g_em_face_array[index]:NULL;
}
+
+/* can we edit UV's for this mesh?*/
+int EM_texFaceCheck(void)
+{
+ /* some of these checks could be a touch overkill */
+ if ( (G.obedit) &&
+ (G.obedit->type == OB_MESH) &&
+ (G.editMesh) &&
+ (G.editMesh->faces.first) &&
+ (CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE)))
+ return 1;
+ return 0;
+}
+
+/* can we edit colors for this mesh?*/
+int EM_vertColorCheck(void)
+{
+ /* some of these checks could be a touch overkill */
+ if ( (G.obedit) &&
+ (G.obedit->type == OB_MESH) &&
+ (G.editMesh) &&
+ (G.editMesh->faces.first) &&
+ (CustomData_has_layer(&G.editMesh->fdata, CD_MCOL)))
+ return 1;
+ return 0;
+}
+
diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c
index bb1d5d00957..8fb21549172 100644
--- a/source/blender/src/editmesh_add.c
+++ b/source/blender/src/editmesh_add.c
@@ -48,6 +48,7 @@
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "BLI_blenlib.h"
@@ -960,7 +961,7 @@ void make_prim(int type, float imat[3][3], int tot, int seg,
rotateflag(2, v1->co, cmat);
}
- removedoublesflag(4, 0.0001);
+ removedoublesflag(4, 0, 0.0001);
/* and now do imat */
eve= em->verts.first;
@@ -1178,7 +1179,7 @@ void add_primitiveMesh(int type)
char *name=NULL;
if(G.scene->id.lib) return;
-
+
/* this function also comes from an info window */
if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
if(G.vd==0) return;
@@ -1188,8 +1189,8 @@ void add_primitiveMesh(int type)
/* if editmode exists for other type, it exits */
check_editmode(OB_MESH);
- if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT)) {
- G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT);
+ if(G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
+ G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT);
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
}
@@ -1278,7 +1279,7 @@ void add_primitiveMesh(int type)
undostr="Add UV Sphere";
break;
case 12: /* Icosphere */
- add_numbut(0, NUM|INT, "Subdivision:", 1, 500, &subdiv, NULL);
+ add_numbut(0, NUM|INT, "Subdivision:", 1, 8, &subdiv, NULL);
add_numbut(1, NUM|FLO, "Radius:", 0.001*G.vd->grid, 100*G.vd->grid, &dia, NULL);
if (!(do_clever_numbuts("Add Ico Sphere", 2, REDRAW))) return;
@@ -1308,7 +1309,8 @@ void add_primitiveMesh(int type)
cent[1]-= G.obedit->obmat[3][1];
cent[2]-= G.obedit->obmat[3][2];
- Mat3CpyMat4(imat, G.vd->viewmat);
+ if ( !(newob) || U.flag & USER_ADD_VIEWALIGNED) Mat3CpyMat4(imat, G.vd->viewmat);
+ else Mat3One(imat);
Mat3MulVecfl(imat, cent);
Mat3MulMat3(cmat, imat, mat);
Mat3Inv(imat,cmat);
@@ -1320,8 +1322,7 @@ void add_primitiveMesh(int type)
phid= 2*M_PI/tot;
phi= .25*M_PI;
- make_prim(type, imat, tot, seg, subdiv, dia, d,
- ext, fill, cent);
+ make_prim(type, imat, tot, seg, subdiv, dia, d, ext, fill, cent);
if(type<2) tot = totoud;
@@ -1331,12 +1332,18 @@ void add_primitiveMesh(int type)
if(type!=0 && type!=13) righthandfaces(1); /* otherwise monkey has eyes in wrong direction... */
countall();
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+
+ /* if a new object was created, it stores it in Mesh, for reload original data and undo */
+ if ( !(newob) || U.flag & USER_ADD_EDITMODE) {
+ if(newob) load_editMesh();
+ } else {
+ exit_editmode(2);
+ }
+
allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
allqueue(REDRAWALL, 0);
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
-
- /* if a new object was created, it stores it in Mesh, for reload original data and undo */
- if(newob) load_editMesh();
+
BIF_undo_push(undostr);
}
diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c
index 78cf2d17c04..298bc222133 100644
--- a/source/blender/src/editmesh_lib.c
+++ b/source/blender/src/editmesh_lib.c
@@ -72,6 +72,17 @@ editmesh_lib: generic (no UI, no menus) operations/evaluators for editmesh data
#include "editmesh.h"
+/* this replaces the active flag used in uv/face mode */
+void EM_set_actFace(EditFace *efa)
+{
+ G.editMesh->act_face = efa;
+}
+
+EditFace * EM_get_actFace(void)
+{
+ return G.editMesh->act_face;
+}
+
/* ********* Selection History ************ */
static int EM_check_selection(void *data)
{
@@ -1131,26 +1142,39 @@ static short extrudeflag_edge(short flag, float *nor)
MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
+ float mtx[4][4];
+ if (mmd->mirror_ob) {
+ float imtx[4][4];
+ Mat4Invert(imtx, mmd->mirror_ob->obmat);
+ Mat4MulMat4(mtx, G.obedit->obmat, imtx);
+ }
+
for (eed= em->edges.first; eed; eed= eed->next) {
if(eed->f2 == 1) {
+ float co1[3], co2[3];
+
+ VecCopyf(co1, eed->v1->co);
+ VecCopyf(co2, eed->v2->co);
- switch(mmd->axis){
- case 0:
- if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
- (fabs(eed->v2->co[0]) < mmd->tolerance) )
- ++eed->f2;
- break;
- case 1:
- if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
- (fabs(eed->v2->co[1]) < mmd->tolerance) )
- ++eed->f2;
- break;
- case 2:
- if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
- (fabs(eed->v2->co[2]) < mmd->tolerance) )
- ++eed->f2;
- break;
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(co1, mtx, co1);
+ VecMat4MulVecfl(co2, mtx, co2);
}
+
+ if (mmd->flag & MOD_MIR_AXIS_X)
+ if ( (fabs(co1[0]) < mmd->tolerance) &&
+ (fabs(co2[0]) < mmd->tolerance) )
+ ++eed->f2;
+
+ if (mmd->flag & MOD_MIR_AXIS_Y)
+ if ( (fabs(co1[1]) < mmd->tolerance) &&
+ (fabs(co2[1]) < mmd->tolerance) )
+ ++eed->f2;
+
+ if (mmd->flag & MOD_MIR_AXIS_Z)
+ if ( (fabs(co1[2]) < mmd->tolerance) &&
+ (fabs(co2[2]) < mmd->tolerance) )
+ ++eed->f2;
}
}
}
@@ -1400,26 +1424,38 @@ short extrudeflag_vert(short flag, float *nor)
MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
+ float mtx[4][4];
+ if (mmd->mirror_ob) {
+ float imtx[4][4];
+ Mat4Invert(imtx, mmd->mirror_ob->obmat);
+ Mat4MulMat4(mtx, G.obedit->obmat, imtx);
+ }
+
for (eed= em->edges.first; eed; eed= eed->next) {
if(eed->f2 == 2) {
+ float co1[3], co2[3];
+
+ VecCopyf(co1, eed->v1->co);
+ VecCopyf(co2, eed->v2->co);
- switch(mmd->axis){
- case 0:
- if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
- (fabs(eed->v2->co[0]) < mmd->tolerance) )
- ++eed->f2;
- break;
- case 1:
- if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
- (fabs(eed->v2->co[1]) < mmd->tolerance) )
- ++eed->f2;
- break;
- case 2:
- if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
- (fabs(eed->v2->co[2]) < mmd->tolerance) )
- ++eed->f2;
- break;
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(co1, mtx, co1);
+ VecMat4MulVecfl(co2, mtx, co2);
}
+
+ if (mmd->flag & MOD_MIR_AXIS_X)
+ if ( (fabs(co1[0]) < mmd->tolerance) &&
+ (fabs(co2[0]) < mmd->tolerance) )
+ ++eed->f2;
+
+ if (mmd->flag & MOD_MIR_AXIS_Y)
+ if ( (fabs(co1[1]) < mmd->tolerance) &&
+ (fabs(co2[1]) < mmd->tolerance) )
+ ++eed->f2;
+ if (mmd->flag & MOD_MIR_AXIS_Z)
+ if ( (fabs(co1[2]) < mmd->tolerance) &&
+ (fabs(co2[2]) < mmd->tolerance) )
+ ++eed->f2;
}
}
}
@@ -2070,3 +2106,134 @@ void EM_fgon_flags(void)
}
}
+
+/* editmesh vertmap, copied from intern.mesh.c
+ * if do_face_idx_array is 0 it means we need to run it as well as freeing
+ * */
+
+UvVertMap *make_uv_vert_map_EM(int selected, int do_face_idx_array, float *limit)
+{
+ EditMesh *em = G.editMesh;
+ EditVert *ev;
+ EditFace *efa;
+ int totverts;
+
+ /* vars from original func */
+ UvVertMap *vmap;
+ UvMapVert *buf;
+ MTFace *tf;
+ unsigned int a;
+ int i, totuv, nverts;
+
+ if (do_face_idx_array)
+ EM_init_index_arrays(0, 0, 1);
+
+ /* we need the vert */
+ for (ev= em->verts.first, totverts=0; ev; ev= ev->next, totverts++) {
+ ev->tmp.l = totverts;
+ }
+
+ totuv = 0;
+
+ /* generate UvMapVert array */
+ for (efa= em->faces.first; efa; efa= efa->next)
+ if(!selected || ((!efa->h) && (efa->f & SELECT)))
+ totuv += (efa->v4)? 4: 3;
+
+ if(totuv==0)
+ return NULL;
+
+ vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap");
+ if (!vmap)
+ return NULL;
+
+ vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*");
+ buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
+
+ if (!vmap->vert || !vmap->buf) {
+ free_uv_vert_map(vmap);
+ return NULL;
+ }
+
+ for (a=0, efa= em->faces.first; efa; a++, efa= efa->next) {
+ if(!selected || ((!efa->h) && (efa->f & SELECT))) {
+ nverts= (efa->v4)? 4: 3;
+
+ for(i=0; i<nverts; i++) {
+ buf->tfindex= i;
+ buf->f= a;
+ buf->separate = 0;
+
+ buf->next= vmap->vert[(*(&efa->v1 + i))->tmp.l];
+ vmap->vert[(*(&efa->v1 + i))->tmp.l]= buf;
+
+ buf++;
+ }
+ }
+ }
+
+ /* sort individual uvs for each vert */
+ for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) {
+ UvMapVert *newvlist= NULL, *vlist=vmap->vert[a];
+ UvMapVert *iterv, *v, *lastv, *next;
+ float *uv, *uv2, uvdiff[2];
+
+ while(vlist) {
+ v= vlist;
+ vlist= vlist->next;
+ v->next= newvlist;
+ newvlist= v;
+
+ efa = EM_get_face_for_index(v->f);
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ uv = tf->uv[v->tfindex];
+
+ lastv= NULL;
+ iterv= vlist;
+
+ while(iterv) {
+ next= iterv->next;
+ efa = EM_get_face_for_index(iterv->f);
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ uv2 = tf->uv[iterv->tfindex];
+
+ Vec2Subf(uvdiff, uv2, uv);
+
+ if(fabs(uv[0]-uv2[0]) < limit[0] && fabs(uv[1]-uv2[1]) < limit[1]) {
+ if(lastv) lastv->next= next;
+ else vlist= next;
+ iterv->next= newvlist;
+ newvlist= iterv;
+ }
+ else
+ lastv=iterv;
+
+ iterv= next;
+ }
+
+ newvlist->separate = 1;
+ }
+
+ vmap->vert[a]= newvlist;
+ }
+
+ if (do_face_idx_array)
+ EM_free_index_arrays();
+
+ return vmap;
+}
+
+UvMapVert *get_uv_map_vert_EM(UvVertMap *vmap, unsigned int v)
+{
+ return vmap->vert[v];
+}
+
+void free_uv_vert_map_EM(UvVertMap *vmap)
+{
+ if (vmap) {
+ if (vmap->vert) MEM_freeN(vmap->vert);
+ if (vmap->buf) MEM_freeN(vmap->buf);
+ MEM_freeN(vmap);
+ }
+}
+
diff --git a/source/blender/src/editmesh_loop.c b/source/blender/src/editmesh_loop.c
index 013a6b2947b..b99710f782f 100644
--- a/source/blender/src/editmesh_loop.c
+++ b/source/blender/src/editmesh_loop.c
@@ -488,7 +488,7 @@ static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash
{
CutCurve *curve,*temp;
EditVert *snapvert;
- float *scr, mval[2], lastx=0, lasty=0;
+ float *scr, mval[2]={0.0,0.0}, lastx=0, lasty=0;
int i=0, j, blocks=1, lasti=0;
int dist, tolerance;
short event, val, qual, vsnap=0, ldown=0, restart=0, rubberband=0;
@@ -515,13 +515,12 @@ static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash
G.scene->selectmode = oldmode;
}
glDrawBuffer(GL_FRONT);
- headerprint("LMB to draw, CTRL while drawing for vertex snap. Enter to finish (with CTRL to leave only the "
- "cut line selected), ESC to abort.");
+ headerprint("(LMB) draw, (Ctrl held while drawing) snap to vertex, (MMB) constrain to x/y screen axis, (Enter) cut "
+ "(with Ctrl to select cut line), (Esc) cancel");
}
else{
glDrawBuffer(GL_FRONT);
- headerprint("LMB to draw, Enter to finish (with CTRL to leave only the "
- "cut line selected), ESC to abort.");
+ headerprint("(LMB) draw, (MMB) constrain to x/y screen axis, (Enter) cut (with Ctrl to select cut line), (Esc) cancel");
}
persp(PERSP_WIN);
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index e3bc718858a..bc1dd4afa8b 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -52,6 +52,7 @@ editmesh_mods.c, UI level access, no geometry changes
#include "DNA_texture_types.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"
@@ -81,10 +82,12 @@ editmesh_mods.c, UI level access, no geometry changes
#include "BIF_interface.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+#include "BIF_editsima.h"
#ifdef WITH_VERSE
#include "BIF_verse.h"
@@ -129,6 +132,22 @@ void EM_select_mirrored(void)
}
}
+void EM_automerge(int update) {
+ int len;
+ if ((G.scene->automerge) &&
+ (G.obedit && G.obedit->type==OB_MESH) &&
+ (((Mesh*)G.obedit->data)->mr==NULL)
+ ) {
+ len = removedoublesflag(1, 1, G.scene->toolsettings->doublimit);
+ if (len) {
+ G.totvert -= len; /* saves doing a countall */
+ if (update) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ }
+ }
+ }
+}
+
/* ****************************** SELECTION ROUTINES **************** */
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0; /* set in drawobject.c ... for colorindices */
@@ -239,7 +258,7 @@ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short
/* method in use for face selecting too */
if(G.obedit==NULL) {
- if(G.f & G_FACESELECT);
+ if(FACESEL_PAINT_TEST);
else return 0;
}
else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -301,7 +320,7 @@ int EM_init_backbuf_circle(short xs, short ys, short rads)
/* method in use for face selecting too */
if(G.obedit==NULL) {
- if(G.f & G_FACESELECT);
+ if(FACESEL_PAINT_TEST);
else return 0;
}
else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -696,7 +715,7 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
}
}
- if(G.scene->selectmode & SCE_SELECT_FACE) {
+ if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
if(efa->fgonf==0) {
glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
BIF_ThemeColor((efa->f & SELECT)?TH_FACE_DOT:TH_WIRE);
@@ -933,6 +952,8 @@ EDGE GROUP
mode 3: same number of face users
mode 4: similar face angles.
mode 5: similar crease
+ mode 6: similar seam
+ mode 7: similar sharp
*/
/* this function is only used by edgegroup_select's edge angle */
@@ -1104,6 +1125,34 @@ int edgegroup_select(short mode)
return selcount;
}
}
+ } else if (mode==6) { /* edge seam */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ (eed->seam == base_eed->seam)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==7) { /* edge sharp */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ (eed->sharp == base_eed->sharp)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
}
}
}
@@ -1239,24 +1288,35 @@ facegroup_select/edgegroup_select/vertgroup_select do all the work
void select_mesh_group_menu()
{
short ret;
- int selcount, first_item=1;
- char str[512] = "Select Grouped%t"; /* total max length is 404 at the moment */
-
+ int selcount, first_item=1, multi=0;
+ char str[512] = "Select Similar "; /* total max length is 404 at the moment */
+
+ if (!ELEM3(G.scene->selectmode, SCE_SELECT_VERTEX, SCE_SELECT_EDGE, SCE_SELECT_FACE)) {
+ multi=1;
+ }
+
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ if (multi) strcat(str, "%t|Vertices%x-1|");
+ else strcat(str, "Vertices %t|");
+ strcat(str, " Normal %x1| Face Users %x2| Shared Vertex Groups%x3");
first_item=0;
- strcat(str, "|Verts...%x-1| Similar Normal %x1| Same Face Users %x2| Shared Vertex Groups%x3");
}
if(G.scene->selectmode & SCE_SELECT_EDGE) {
- if (!first_item) strcat(str, "|%l");
- else first_item=1;
+ if (multi) {
+ if (first_item) strcat(str, "%t|Edges%x-1|");
+ else strcat(str, "|%l|Edges%x-1|");
+ } else strcat(str, "Edges %t|");
- strcat(str, "|Edges...%x-1| Similar Length %x10| Similar Direction %x20| Same Face Users%x30| Similar Face Angle%x40| Similar Crease%x50");
+ strcat(str, " Length %x10| Direction %x20| Face Users%x30| Face Angle%x40| Crease%x50| Seam%x60| Sharp%x70");
+ first_item=0;
}
if(G.scene->selectmode & SCE_SELECT_FACE) {
- if (!first_item) strcat(str, "|%l");
- strcat(str, "|Faces...%x-1| Same Material %x100| Same Image %x200| Similar Area %x300| Similar Perimeter %x400| Similar Normal %x500| Similar Co-Planer %x600");
+ if (multi) {
+ strcat(str, "|%l|Faces%x-1|");
+ } else strcat(str, "Faces %t|");
+ strcat(str, " Material %x100| Image %x200| Area %x300| Perimeter %x400| Normal %x500| Co-Planar %x600");
}
@@ -1269,7 +1329,9 @@ void select_mesh_group_menu()
EM_select_flush(); /* so that selected verts, go onto select faces */
G.totvertsel += selcount;
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select Grouped Verts");
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+ BIF_undo_push("Select Similar Vertices");
}
return;
}
@@ -1281,7 +1343,9 @@ void select_mesh_group_menu()
/*EM_select_flush();*/ /* dont use because it can end up selecting more edges and is not usefull*/
G.totedgesel+=selcount;
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select Grouped Edges");
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+ BIF_undo_push("Select Similar Edges");
}
return;
}
@@ -1291,12 +1355,398 @@ void select_mesh_group_menu()
if (selcount) { /* update if data was selected */
G.totfacesel+=selcount;
allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Select Grouped Faces");
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+ BIF_undo_push("Select Similar Faces");
}
return;
}
}
+int mesh_layers_menu_charlen(CustomData *data, int type)
+{
+ int i, len = 0;
+ /* see if there is a duplicate */
+ for(i=0; i<data->totlayer; i++) {
+ if((&data->layers[i])->type == type) {
+ /* we could count the chars here but we'll just assumeme each
+ * is 32 chars with some room for the menu text - 40 should be fine */
+ len+=40;
+ }
+ }
+ return len;
+}
+
+/* this function adds menu text into an existing string.
+ * this string's size should be allocated with mesh_layers_menu_charlen */
+void mesh_layers_menu_concat(CustomData *data, int type, char *str) {
+ int i, count = 0;
+ char *str_pt = str;
+ CustomDataLayer *layer;
+
+ /* see if there is a duplicate */
+ for(i=0; i<data->totlayer; i++) {
+ layer = &data->layers[i];
+ if(layer->type == type) {
+ str_pt += sprintf(str_pt, "%s%%x%d|", layer->name, count);
+ count++;
+ }
+ }
+}
+
+int mesh_layers_menu(CustomData *data, int type) {
+ int ret;
+ char *str_pt, *str;
+
+ str_pt = str = MEM_mallocN(mesh_layers_menu_charlen(data, type) + 18, "layer menu");
+ str[0] = '\0';
+
+ str_pt += sprintf(str_pt, "Layers%%t|");
+
+ mesh_layers_menu_concat(data, type, str_pt);
+
+ ret = pupmenu(str);
+ MEM_freeN(str);
+ return ret;
+}
+
+/* ctrl+c in mesh editmode */
+void mesh_copy_menu(void)
+{
+ EditMesh *em = G.editMesh;
+ EditSelection *ese;
+ short ret, change=0;
+
+ if (!em) return;
+
+ ese = em->selected.last;
+
+ if (!ese) return;
+
+ if(ese->type == EDITVERT) {
+ /*EditVert *ev, *ev_act = (EditVert*)ese->data;
+ ret= pupmenu("");*/
+ } else if(ese->type == EDITEDGE) {
+ EditEdge *eed, *eed_act = (EditEdge*)ese->data;
+ float vec[3], vec_mid[3], eed_len, eed_len_act;
+
+ ret= pupmenu("Copy Active Edge to Selected%t|Crease%x1|Length%x2");
+ if (ret<1) return;
+
+ eed_len_act = VecLenf(eed_act->v1->co, eed_act->v2->co);
+
+ switch (ret) {
+ case 1: /* copy crease */
+ for(eed=em->edges.first; eed; eed=eed->next) {
+ if (eed->f & SELECT && eed != eed_act && eed->crease != eed_act->crease) {
+ eed->crease = eed_act->crease;
+ change = 1;
+ }
+ }
+ break;
+
+ case 2: /* copy length */
+
+ for(eed=em->edges.first; eed; eed=eed->next) {
+ if (eed->f & SELECT && eed != eed_act) {
+
+ eed_len = VecLenf(eed->v1->co, eed->v2->co);
+
+ if (eed_len == eed_len_act) continue;
+ /* if this edge is zero length we cont do anything with it*/
+ if (eed_len == 0.0f) continue;
+ if (eed_len_act == 0.0f) {
+ VecAddf(vec_mid, eed->v1->co, eed->v2->co);
+ VecMulf(vec_mid, 0.5);
+ VECCOPY(eed->v1->co, vec_mid);
+ VECCOPY(eed->v2->co, vec_mid);
+ } else {
+ /* copy the edge length */
+ VecAddf(vec_mid, eed->v1->co, eed->v2->co);
+ VecMulf(vec_mid, 0.5);
+
+ /* SCALE 1 */
+ VecSubf(vec, eed->v1->co, vec_mid);
+ VecMulf(vec, eed_len_act/eed_len);
+ VecAddf(eed->v1->co, vec, vec_mid);
+
+ /* SCALE 2 */
+ VecSubf(vec, eed->v2->co, vec_mid);
+ VecMulf(vec, eed_len_act/eed_len);
+ VecAddf(eed->v2->co, vec, vec_mid);
+ }
+ change = 1;
+ }
+ }
+
+ if (change)
+ recalc_editnormals();
+
+
+ break;
+ }
+
+ } else if(ese->type == EDITFACE) {
+ EditFace *efa, *efa_act = (EditFace*)ese->data;
+ MTFace *tf, *tf_act;
+ MCol *mcol, *mcol_act;
+
+ ret= pupmenu(
+ "Copy Face Selected%t|"
+ "Active Material%x1|Active Image%x2|Active UV Coords%x3|"
+ "Active Mode%x4|Active Transp%x5|Active Vertex Colors%x6|%l|"
+
+ "TexFace UVs from layer%x7|"
+ "TexFace Images from layer%x8|"
+ "TexFace All from layer%x9|"
+ "Vertex Colors from layer%x10");
+
+ if (ret<1) return;
+
+ tf_act = CustomData_em_get(&em->fdata, efa_act->data, CD_MTFACE);
+ mcol_act = CustomData_em_get(&em->fdata, efa_act->data, CD_MCOL);
+
+ switch (ret) {
+ case 1: /* copy material */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa->mat_nr != efa_act->mat_nr) {
+ efa->mat_nr = efa_act->mat_nr;
+ change = 1;
+ }
+ }
+ break;
+ case 2: /* copy image */
+ if (!tf_act) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa != efa_act) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (tf_act->tpage) {
+ tf->tpage = tf_act->tpage;
+ tf->mode |= TF_TEX;
+ } else {
+ tf->tpage = NULL;
+ tf->mode &= ~TF_TEX;
+ }
+ tf->tile= tf_act->tile;
+ change = 1;
+ }
+ }
+ break;
+
+ case 3: /* copy UV's */
+ if (!tf_act) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa != efa_act) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ memcpy(tf->uv, tf_act->uv, sizeof(tf->uv));
+ change = 1;
+ }
+ }
+ break;
+ case 4: /* mode's */
+ if (!tf_act) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa != efa_act) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ tf->mode= tf_act->mode;
+ change = 1;
+ }
+ }
+ break;
+ case 5: /* copy transp's */
+ if (!tf_act) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa != efa_act) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ tf->transp= tf_act->transp;
+ change = 1;
+ }
+ }
+ break;
+
+ case 6: /* copy vcols's */
+ if (!mcol_act) {
+ error("mesh has no color layers");
+ return;
+ } else {
+ /* guess the 4th color if needs be */
+ float val =- 1;
+
+ if (!efa_act->v4) {
+ /* guess the othe vale, we may need to use it
+ *
+ * Modifying the 4th value of the mcol is ok here since its not seen
+ * on a triangle
+ * */
+ val = ((float)(mcol_act->r + (mcol_act+1)->r + (mcol_act+2)->r)) / 3; CLAMP(val, 0, 255);
+ (mcol_act+3)->r = (char)val;
+
+ val = ((float)(mcol_act->g + (mcol_act+1)->g + (mcol_act+2)->g)) / 3; CLAMP(val, 0, 255);
+ (mcol_act+3)->g = (char)val;
+
+ val = ((float)(mcol_act->b + (mcol_act+1)->b + (mcol_act+2)->b)) / 3; CLAMP(val, 0, 255);
+ (mcol_act+3)->b = (char)val;
+ }
+
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT && efa != efa_act) {
+ /* TODO - make copy from tri to quad guess the 4th vert */
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ memcpy(mcol, mcol_act, sizeof(MCol)*4);
+ change = 1;
+ }
+ }
+ }
+
+ break;
+
+
+ /* copy from layer */
+ case 7:
+ case 8:
+ case 9:
+ if (!tf_act) {
+ error("mesh has no uv/image layers");
+ return;
+ } else if (CustomData_number_of_layers(&em->fdata, CD_MTFACE)<2) {
+ error("mesh does not have multiple uv/image layers");
+ return;
+ } else {
+ int layer_orig_idx, layer_idx;
+
+ layer_idx = mesh_layers_menu(&em->fdata, CD_MTFACE);
+ if (layer_idx<0) return;
+
+ /* warning, have not updated mesh pointers however this is not needed since we swicth back */
+ layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MTFACE);
+ if (layer_idx==layer_orig_idx)
+ return;
+
+ /* get the tfaces */
+ CustomData_set_layer_active(&em->fdata, CD_MTFACE, (int)layer_idx);
+ /* store the tfaces in our temp */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ }
+ }
+ CustomData_set_layer_active(&em->fdata, CD_MTFACE, layer_orig_idx);
+ }
+ break;
+
+ case 10: /* select vcol layers - make sure this stays in sync with above code */
+ if (!mcol_act) {
+ error("mesh has no color layers");
+ return;
+ } else if (CustomData_number_of_layers(&em->fdata, CD_MCOL)<2) {
+ error("mesh does not have multiple color layers");
+ return;
+ } else {
+ int layer_orig_idx, layer_idx;
+
+ layer_idx = mesh_layers_menu(&em->fdata, CD_MCOL);
+ if (layer_idx<0) return;
+
+ /* warning, have not updated mesh pointers however this is not needed since we swicth back */
+ layer_orig_idx = CustomData_get_active_layer(&em->fdata, CD_MCOL);
+ if (layer_idx==layer_orig_idx)
+ return;
+
+ /* get the tfaces */
+ CustomData_set_layer_active(&em->fdata, CD_MCOL, (int)layer_idx);
+ /* store the tfaces in our temp */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ efa->tmp.p = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ }
+ }
+ CustomData_set_layer_active(&em->fdata, CD_MCOL, layer_orig_idx);
+
+ }
+ break;
+ }
+
+ /* layer copy only - sanity checks done above */
+ switch (ret) {
+ case 7: /* copy UV's only */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ memcpy(tf->uv, tf_act->uv, sizeof(tf->uv));
+ change = 1;
+ }
+ }
+ break;
+ case 8: /* copy image settings only */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (tf_act->tpage) {
+ tf->tpage = tf_act->tpage;
+ tf->mode |= TF_TEX;
+ } else {
+ tf->tpage = NULL;
+ tf->mode &= ~TF_TEX;
+ }
+ tf->tile= tf_act->tile;
+ change = 1;
+ }
+ }
+ break;
+ case 9: /* copy all tface info */
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ tf_act = (MTFace *)efa->tmp.p; /* not active but easier to use this way */
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ memcpy(tf->uv, ((MTFace *)efa->tmp.p)->uv, sizeof(tf->uv));
+ tf->tpage = tf_act->tpage;
+ tf->mode = tf_act->mode;
+ tf->transp = tf_act->transp;
+ change = 1;
+ }
+ }
+ break;
+ case 10:
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ mcol_act = (MCol *)efa->tmp.p;
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ memcpy(mcol, mcol_act, sizeof(MCol)*4);
+ change = 1;
+ }
+ }
+ break;
+ }
+
+ }
+
+ if (change) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+
+ if(ese->type == EDITVERT) BIF_undo_push("Copy Vert Attribute");
+ else if (ese->type == EDITEDGE) BIF_undo_push("Copy Edge Attribute");
+ else if (ese->type == EDITFACE) BIF_undo_push("Copy Face Attribute");
+ }
+
+}
+
/* **************** LOOP SELECTS *************** */
@@ -1572,6 +2022,8 @@ void loop_multiselect(int looptype)
}
MEM_freeN(edarray);
allqueue(REDRAWVIEW3D,0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
/* ***************** MAIN MOUSE SELECTION ************** */
@@ -1612,8 +2064,9 @@ static void mouse_mesh_loop(void)
EM_selectmode_flush();
countall();
-
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
}
@@ -1631,6 +2084,8 @@ void mouse_mesh(void)
if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
if(efa) {
+ /* set the last selected face */
+ EM_set_actFace(efa);
if( (efa->f & SELECT)==0 ) {
EM_store_selection(efa, EDITFACE);
@@ -1667,15 +2122,25 @@ void mouse_mesh(void)
EM_selectmode_flush();
countall();
-
+
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck()) {
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWBUTSEDIT, 0); /* for the texture face panel */
+ }
+ if (efa && efa->mat_nr != G.obedit->actcol-1) {
+ G.obedit->actcol= efa->mat_nr+1;
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWBUTSSHADING, 0);
+ BIF_preview_changed(ID_MA);
+ }
}
rightmouse_transform();
}
-static void selectconnectedAll(void)
+void selectconnected_mesh_all(void)
{
EditMesh *em = G.editMesh;
EditVert *v1,*v2;
@@ -1719,10 +2184,12 @@ static void selectconnectedAll(void)
countall();
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Select Connected (All)");
}
-void selectconnected_mesh(int qual)
+void selectconnected_mesh(void)
{
EditMesh *em = G.editMesh;
EditVert *eve, *v1, *v2;
@@ -1731,12 +2198,6 @@ void selectconnected_mesh(int qual)
short done=1, sel, toggle=0;
if(em->edges.first==0) return;
-
- if(qual & LR_CTRLKEY) {
- selectconnectedAll();
- return;
- }
-
if( unified_findnearest(&eve, &eed, &efa)==0 ) {
error("Nothing indicated ");
@@ -1744,7 +2205,7 @@ void selectconnected_mesh(int qual)
}
sel= 1;
- if(qual & LR_SHIFTKEY) sel=0;
+ if(G.qual & LR_SHIFTKEY) sel=0;
/* clear test flags */
for(v1= em->verts.first; v1; v1= v1->next) v1->f1= 0;
@@ -1796,10 +2257,122 @@ void selectconnected_mesh(int qual)
countall();
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
BIF_undo_push("Select Linked");
}
+/* for use with selectconnected_delimit_mesh only! */
+#define is_edge_delimit_ok(eed) ((eed->tmp.l == 1) && (eed->seam==0))
+#define is_face_tag(efa) is_edge_delimit_ok(efa->e1) || is_edge_delimit_ok(efa->e2) || is_edge_delimit_ok(efa->e3) || (efa->v4 && is_edge_delimit_ok(efa->e4))
+
+#define face_tag(efa)\
+ if(efa->v4) efa->tmp.l= efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= efa->e4->tmp.l= 1;\
+ else efa->tmp.l= efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= 1;
+
+/* all - 1) use all faces for extending the selection 2) only use the mouse face
+ * sel - 1) select 0) deselect
+ * */
+static void selectconnected_delimit_mesh__internal(short all, short sel)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ short done=1, change=0;
+ int dist = 75;
+ EditEdge *eed;
+ if(em->faces.first==0) return;
+
+ /* flag all edges as off*/
+ for(eed= em->edges.first; eed; eed= eed->next)
+ eed->tmp.l=0;
+
+ if (all) {
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->f & SELECT) {
+ face_tag(efa);
+ } else {
+ efa->tmp.l = 0;
+ }
+ }
+ } else {
+ EditFace *efa_mouse = findnearestface(&dist);
+
+ if( !efa_mouse ) {
+ error("Nothing indicated ");
+ return;
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->tmp.l = 0;
+ }
+ efa_mouse->tmp.l = 1;
+ face_tag(efa_mouse);
+ }
+
+ while(done==1) {
+ done= 0;
+ /* simple algo - select all faces that have a selected edge
+ * this intern selects the edge, repeat until nothing is left to do */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if ((efa->tmp.l == 0) && (!efa->h)) {
+ if (is_face_tag(efa)) {
+ face_tag(efa);
+ done= 1;
+ }
+ }
+ }
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->tmp.l) {
+ if (sel) {
+ if (!(efa->f & SELECT)) {
+ EM_select_face(efa, 1);
+ change = 1;
+ }
+ } else {
+ if (efa->f & SELECT) {
+ EM_select_face(efa, 0);
+ change = 1;
+ }
+ }
+ }
+ }
+
+ if (!change)
+ return;
+
+ if (!sel) /* make sure de-selecting faces didnt de-select the verts/edges connected to selected faces, this is common with boundries */
+ for(efa= em->faces.first; efa; efa= efa->next)
+ if (efa->f & SELECT)
+ EM_select_face(efa, 1);
+
+ countall();
+
+ allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
+ BIF_undo_push("Select Linked Delimeted");
+
+}
+
+#undef is_edge_delimit_ok
+#undef is_face_tag
+#undef face_tag
+
+void selectconnected_delimit_mesh(void)
+{
+ selectconnected_delimit_mesh__internal(0, ((G.qual & LR_SHIFTKEY)==0));
+}
+void selectconnected_delimit_mesh_all(void)
+{
+ selectconnected_delimit_mesh__internal(1, 1);
+}
+
+
/* swap is 0 or 1, if 1 it hides not selected */
void hide_mesh(int swap)
{
@@ -1896,6 +2469,8 @@ void hide_mesh(int swap)
G.totedgesel= G.totfacesel= G.totvertsel= 0;
allqueue(REDRAWVIEW3D, 0);
+ if(EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
BIF_undo_push("Hide");
}
@@ -1936,10 +2511,91 @@ void reveal_mesh(void)
countall();
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
BIF_undo_push("Reveal");
}
+/* TODO - improve this with sync sel and selection flushing */
+void hide_tface_uv(int swap)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+
+ /* call the mesh function if we are in mesh sync sel */
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ hide_mesh(swap);
+ return;
+ }
+
+ if(swap) {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->f & SELECT) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if((tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))==0) {
+ if(!efa->v4)
+ EM_select_face(efa, 0);
+ else if(!(tface->flag & TF_SEL4))
+ EM_select_face(efa, 0);
+ }
+ }
+ }
+ } else {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->f & SELECT) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
+ EM_select_face(efa, 0);
+ else if(efa->v4 && tface->flag & TF_SEL4)
+ EM_select_face(efa, 0);
+ }
+ }
+ }
+
+ /*deselects too many but ok for now*/
+ EM_deselect_flush();
+ EM_validate_selections();
+
+ BIF_undo_push("Hide UV");
+
+ object_tface_flags_changed(OBACT, 0);
+}
+
+void reveal_tface_uv(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+
+ /* call the mesh function if we are in mesh sync sel */
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ reveal_mesh();
+ return;
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (!(efa->h)) {
+ if (!(efa->f & SELECT)) {
+ EM_select_face(efa, 1);
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ tface->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+ }
+ }
+
+ EM_selectmode_flush();
+
+ BIF_undo_push("Reveal UV");
+
+ object_tface_flags_changed(OBACT, 0);
+}
+
void select_faces_by_numverts(int numverts)
{
EditMesh *em = G.editMesh;
@@ -1968,7 +2624,9 @@ void select_faces_by_numverts(int numverts)
countall();
addqueue(curarea->win, REDRAW, 0);
-
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
if (numverts==3)
BIF_undo_push("Select Triangles");
else if (numverts==4)
@@ -2075,6 +2733,9 @@ void select_sharp_edges(void)
countall();
addqueue(curarea->win, REDRAW, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
BIF_undo_push("Select Sharp Edges");
}
@@ -2218,6 +2879,8 @@ void select_linked_flat_faces(void)
countall();
addqueue(curarea->win, REDRAW, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Select Linked Flat Faces");
}
@@ -2288,6 +2951,8 @@ void select_non_manifold(void)
countall();
addqueue(curarea->win, REDRAW, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Select Non Manifold");
}
@@ -2326,6 +2991,8 @@ void selectswap_mesh(void) /* UI level */
countall();
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Select Swap");
@@ -2346,6 +3013,10 @@ void deselectall_mesh(void) /* this toggles!!!, UI level */
}
countall();
+
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
allqueue(REDRAWVIEW3D, 0);
}
}
@@ -2391,6 +3062,8 @@ void select_more(void)
countall();
addqueue(curarea->win, REDRAW, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Select More");
}
@@ -2458,6 +3131,8 @@ void select_less(void)
countall();
BIF_undo_push("Select Less");
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
@@ -2511,6 +3186,8 @@ void selectrandom_mesh(void) /* randomly selects a user-set % of vertices/edges/
BIF_undo_push("Select Random:Faces");
}
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
void editmesh_select_by_material(int index)
@@ -2576,6 +3253,8 @@ void EM_selectmode_menu(void)
}
allqueue(REDRAWVIEW3D, 1);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
}
@@ -2666,6 +3345,40 @@ void BME_Menu() {
}
}
+
+
+void Vertex_Menu() {
+ short ret;
+ ret= pupmenu("Vertex Specials%t|Remove Doubles%x1|Merge%x2|Smooth %x3|Select Vertex Path%x4|Blend From Shape%x5|Propagate To All Shapes%x6");
+
+ switch(ret)
+ {
+ case 1:
+ notice("Removed %d Vertices", removedoublesflag(1, 0, G.scene->toolsettings->doublimit));
+ BIF_undo_push("Remove Doubles");
+ break;
+ case 2:
+ mergemenu();
+ break;
+ case 3:
+ vertexsmooth();
+ break;
+ case 4:
+ pathselect();
+ BIF_undo_push("Select Vertex Path");
+ break;
+ case 5:
+ shape_copy_select_from();
+ break;
+ case 6:
+ shape_propagate();
+ break;
+ }
+ /* some items crashed because this is in the original W menu but not here. should really manage this better */
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+}
+
+
void Edge_Menu() {
short ret;
@@ -2716,6 +3429,72 @@ void Edge_Menu() {
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
break;
}
+ /* some items crashed because this is in the original W menu but not here. should really manage this better */
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+}
+
+void Face_Menu() {
+ short ret;
+ ret= pupmenu(
+ "Face Specials%t|Flip Normals%x1|Bevel%x2|Shade Smooth%x3|Shade Flat%x4|"
+ "Triangulate (Ctrl T)%x5|Quads from Triangles (Alt J)%x6|Flip Triangle Edges (Ctrl Shift F)%x7|%l|"
+ "Face Mode Set%x8|Face Mode Clear%x9|%l|"
+ "UV Rotate (Shift - CCW)%x10|UV Mirror (Shift - Switch Axis)%x11|"
+ "Color Rotate (Shift - CCW)%x12|Color Mirror (Shift - Switch Axis)%x13");
+
+ switch(ret)
+ {
+ case 1:
+ flip_editnormals();
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ BIF_undo_push("Flip Normals");
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case 2:
+ bevel_menu();
+ break;
+ case 3:
+ mesh_set_smooth_faces(1);
+ break;
+ case 4:
+ mesh_set_smooth_faces(0);
+ break;
+
+ case 5: /* Quads to Tris */
+ convert_to_triface(0);
+ allqueue(REDRAWVIEW3D, 0);
+ countall();
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ break;
+ case 6: /* Tris to Quads */
+ join_triangles();
+ break;
+ case 7: /* Flip triangle edges */
+ edge_flip();
+ break;
+ case 8:
+ mesh_set_face_flags(1);
+ break;
+ case 9:
+ mesh_set_face_flags(0);
+ break;
+
+ /* uv texface options */
+ case 10:
+ mesh_rotate_uvs();
+ break;
+ case 11:
+ mesh_mirror_uvs();
+ break;
+ case 12:
+ mesh_rotate_colors();
+ break;
+ case 13:
+ mesh_mirror_colors();
+ break;
+ }
+ /* some items crashed because this is in the original W menu but not here. should really manage this better */
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
@@ -3140,7 +3919,7 @@ void vertexsmooth(void)
eve= em->verts.first;
while(eve) {
if(eve->f & SELECT) {
- eve->tmp.fp = adr;
+ eve->tmp.p = (void*)adr;
eve->f1= 0;
eve->f2= 0;
adr+= 3;
@@ -3188,11 +3967,11 @@ void vertexsmooth(void)
if((eed->v1->f & SELECT) && eed->v1->f1<255) {
eed->v1->f1++;
- VecAddf(eed->v1->tmp.fp, eed->v1->tmp.fp, fvec);
+ VecAddf(eed->v1->tmp.p, eed->v1->tmp.p, fvec);
}
if((eed->v2->f & SELECT) && eed->v2->f1<255) {
eed->v2->f1++;
- VecAddf(eed->v2->tmp.fp, eed->v2->tmp.fp, fvec);
+ VecAddf(eed->v2->tmp.p, eed->v2->tmp.p, fvec);
}
}
eed= eed->next;
@@ -3202,7 +3981,7 @@ void vertexsmooth(void)
while(eve) {
if(eve->f & SELECT) {
if(eve->f1) {
- adr = eve->tmp.fp;
+ adr = eve->tmp.p;
fac= 0.5/(float)eve->f1;
eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
@@ -3222,7 +4001,7 @@ void vertexsmooth(void)
}
}
}
- eve->tmp.fp= 0;
+ eve->tmp.p= NULL;
}
eve= eve->next;
}
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index b69ce4bdead..19b6ed287f9 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -51,6 +51,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -72,6 +73,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
#ifdef WITH_VERSE
#include "BKE_verse.h"
@@ -89,6 +91,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "BIF_resources.h"
#include "BIF_toolbox.h"
#include "BIF_transform.h"
+#include "transform.h"
#ifdef WITH_VERSE
#include "BIF_verse.h"
@@ -195,8 +198,15 @@ void convert_to_triface(int direction)
}
-int removedoublesflag(short flag, float limit) /* return amount */
+int removedoublesflag(short flag, short automerge, float limit) /* return amount */
{
+ /*
+ flag - Test with vert->flags
+ automerge - Alternative operation, merge unselected into selected.
+ Used for "Auto Weld" mode. warning.
+ limit - Quick manhattan distance between verts.
+ */
+
EditMesh *em = G.editMesh;
/* all verts with (flag & 'flag') are being evaluated */
EditVert *eve, *v1, *nextve;
@@ -204,17 +214,19 @@ int removedoublesflag(short flag, float limit) /* return amount */
EditFace *efa, *nextvl;
xvertsort *sortblock, *sb, *sb1;
struct facesort *vlsortblock, *vsb, *vsb1;
- float dist;
int a, b, test, amount;
if(multires_test()) return 0;
+
/* flag 128 is cleared, count */
+
+ /* Normal non weld operation */
eve= em->verts.first;
amount= 0;
while(eve) {
eve->f &= ~128;
- if(eve->h==0 && (eve->f & flag)) amount++;
+ if(eve->h==0 && (automerge || (eve->f & flag))) amount++;
eve= eve->next;
}
if(amount==0) return 0;
@@ -223,7 +235,7 @@ int removedoublesflag(short flag, float limit) /* return amount */
sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub");
eve= em->verts.first;
while(eve) {
- if(eve->h==0 && (eve->f & flag)) {
+ if(eve->h==0 && (automerge || (eve->f & flag))) {
sb->x= eve->co[0]+eve->co[1]+eve->co[2];
sb->v1= eve;
sb++;
@@ -232,44 +244,72 @@ int removedoublesflag(short flag, float limit) /* return amount */
}
qsort(sortblock, amount, sizeof(xvertsort), vergxco);
+
/* test for doubles */
- sb= sortblock;
- for(a=0; a<amount; a++) {
- eve= sb->v1;
- if( (eve->f & 128)==0 ) {
- sb1= sb+1;
- for(b=a+1; b<amount; b++) {
- /* first test: simpel dist */
- dist= sb1->x - sb->x;
- if(dist > limit) break;
-
- /* second test: is vertex allowed */
- v1= sb1->v1;
- if( (v1->f & 128)==0 ) {
+ sb= sortblock;
+ if (automerge) {
+ for(a=0; a<amount; a++, sb++) {
+ eve= sb->v1;
+ if( (eve->f & 128)==0 ) {
+ sb1= sb+1;
+ for(b=a+1; b<amount && (eve->f & 128)==0; b++, sb1++) {
+ if(sb1->x - sb->x > limit) break;
- dist= (float)fabs(v1->co[0]-eve->co[0]);
- if(dist<=limit) {
- dist= (float)fabs(v1->co[1]-eve->co[1]);
- if(dist<=limit) {
- dist= (float)fabs(v1->co[2]-eve->co[2]);
- if(dist<=limit) {
+ /* when automarge, only allow unselected->selected */
+ v1= sb1->v1;
+ if( (v1->f & 128)==0 ) {
+ if ((eve->f & flag)==0 && (v1->f & flag)==1) {
+ if( (float)fabs(v1->co[0]-eve->co[0])<=limit &&
+ (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+ (float)fabs(v1->co[2]-eve->co[2])<=limit)
+ { /* unique bit */
+ eve->f|= 128;
+ eve->tmp.v = v1;
+ }
+ } else if( (eve->f & flag)==1 && (v1->f & flag)==0 ) {
+ if( (float)fabs(v1->co[0]-eve->co[0])<=limit &&
+ (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+ (float)fabs(v1->co[2]-eve->co[2])<=limit)
+ { /* unique bit */
v1->f|= 128;
v1->tmp.v = eve;
}
}
}
}
- sb1++;
}
}
- sb++;
+ } else {
+ for(a=0; a<amount; a++, sb++) {
+ eve= sb->v1;
+ if( (eve->f & 128)==0 ) {
+ sb1= sb+1;
+ for(b=a+1; b<amount; b++, sb1++) {
+ /* first test: simpel dist */
+ if(sb1->x - sb->x > limit) break;
+ v1= sb1->v1;
+
+ /* second test: is vertex allowed */
+ if( (v1->f & 128)==0 ) {
+ if( (float)fabs(v1->co[0]-eve->co[0])<=limit &&
+ (float)fabs(v1->co[1]-eve->co[1])<=limit &&
+ (float)fabs(v1->co[2]-eve->co[2])<=limit)
+ {
+ v1->f|= 128;
+ v1->tmp.v = eve;
+ }
+ }
+ }
+ }
+ }
}
MEM_freeN(sortblock);
-
- for(eve = em->verts.first; eve; eve=eve->next)
- if((eve->f & flag) && (eve->f & 128))
- EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f);
-
+
+ if (!automerge)
+ for(eve = em->verts.first; eve; eve=eve->next)
+ if((eve->f & flag) && (eve->f & 128))
+ EM_data_interp_from_verts(eve, eve->tmp.v, eve->tmp.v, 0.5f);
+
/* test edges and insert again */
eed= em->edges.first;
while(eed) {
@@ -445,7 +485,7 @@ int removedoublesflag(short flag, float limit) /* return amount */
eve= (struct EditVert *)em->verts.first;
while(eve) {
nextve= eve->next;
- if(eve->f & flag) {
+ if(automerge || eve->f & flag) {
if(eve->f & 128) {
a++;
BLI_remlink(&em->verts, eve);
@@ -642,15 +682,15 @@ void extrude_mesh(void)
/* individual faces? */
BIF_TransformSetUndo("Extrude");
if(nr==2) {
- initTransform(TFM_SHRINKFATTEN, CTX_NO_PET);
+ initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR);
Transform();
}
else {
- initTransform(TFM_TRANSLATION, CTX_NO_PET);
+ initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
if(transmode=='n') {
Mat4MulVecfl(G.obedit->obmat, nor);
VecSubf(nor, nor, G.obedit->obmat[3]);
- BIF_setSingleAxisConstraint(nor, NULL);
+ BIF_setSingleAxisConstraint(nor, "along normal");
}
Transform();
}
@@ -756,14 +796,15 @@ void spin_mesh(int steps, float degr, float *dvec, int mode)
if(G.scene->toolsettings->editbutflag & B_CLOCKWISE) phi= -phi;
if(dvec) {
- n[0]=n[1]= 0.0;
- n[2]= 1.0;
+ n[0]= G.vd->viewinv[1][0];
+ n[1]= G.vd->viewinv[1][1];
+ n[2]= G.vd->viewinv[1][2];
} else {
n[0]= G.vd->viewinv[2][0];
n[1]= G.vd->viewinv[2][1];
n[2]= G.vd->viewinv[2][2];
- Normalize(n);
}
+ Normalize(n);
q[0]= (float)cos(phi);
si= (float)sin(phi);
@@ -824,12 +865,6 @@ void screw_mesh(int steps, int turns)
TEST_EDITMESH
if(multires_test()) return;
-
- /* first condition: we need frontview! */
- if(G.vd->view!=1) {
- error("Must be in Front View");
- return;
- }
/* clear flags */
eve= em->verts.first;
@@ -1251,6 +1286,19 @@ static EditVert *subdivide_edge_addvert(EditEdge *edge, float rad, int beauty, f
/* offset for smooth or sphere or fractal */
alter_co(co, edge, rad, beauty, percent);
+ /* clip if needed by mirror modifier */
+ if (edge->v1->f2) {
+ if ( edge->v1->f2 & edge->v2->f2 & 1) {
+ co[0]= 0.0f;
+ }
+ if ( edge->v1->f2 & edge->v2->f2 & 2) {
+ co[1]= 0.0f;
+ }
+ if ( edge->v1->f2 & edge->v2->f2 & 4) {
+ co[2]= 0.0f;
+ }
+ }
+
ev = addvertlist(co, NULL);
/* vert data (vgroups, ..) */
@@ -2371,12 +2419,39 @@ void esubdivideflag(int flag, float rad, int beauty, int numcuts, int seltype)
EditMesh *em = G.editMesh;
EditFace *ef;
EditEdge *eed, *cedge, *sort[4];
- EditVert **templist;
+ EditVert *eve, **templist;
struct GHash *gh;
float length[4], v1mat[3], v2mat[3], v3mat[3], v4mat[3];
int i, j, edgecount, touchcount, facetype,hold;
+ ModifierData *md= G.obedit->modifiers.first;
if(multires_test()) return;
+
+ for (; md; md=md->next) {
+ if (md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ if(mmd->flag & MOD_MIR_CLIPPING) {
+ for (eve= em->verts.first; eve; eve= eve->next) {
+ eve->f2= 0;
+ switch(mmd->axis){
+ case 0:
+ if (fabs(eve->co[0]) < mmd->tolerance)
+ eve->f2 |= 1;
+ break;
+ case 1:
+ if (fabs(eve->co[1]) < mmd->tolerance)
+ eve->f2 |= 2;
+ break;
+ case 2:
+ if (fabs(eve->co[2]) < mmd->tolerance)
+ eve->f2 |= 4;
+ break;
+ }
+ }
+ }
+ }
+ }
//Set faces f1 to 0 cause we need it later
for(ef=em->faces.first;ef;ef = ef->next) {
@@ -2919,8 +2994,6 @@ void beauty_fill(void)
totedge = count_selected_edges(em->edges.first);
if(totedge==0) return;
- if(okee("Beautify fill")==0) return;
-
/* temp block with face pointers */
efaar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "beautyfill");
@@ -3636,6 +3709,7 @@ static void edge_rotate(EditEdge *eed,int dir)
srchedge->dir = eed->dir;
srchedge->seam = eed->seam;
srchedge->crease = eed->crease;
+ srchedge->bweight = eed->bweight;
}
}
@@ -4030,7 +4104,7 @@ static void bevel_mesh(float bsize, int allfaces)
waitcursor(1);
- removedoublesflag(1, limit);
+ removedoublesflag(1, 0, limit);
/* tag all original faces */
efa= em->faces.first;
@@ -4385,7 +4459,7 @@ static void bevel_mesh(float bsize, int allfaces)
allqueue(REDRAWVIEW3D, 0);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
- removedoublesflag(1, limit);
+ removedoublesflag(1, 0, limit);
/* flush selected vertices to edges/faces */
EM_select_flush();
@@ -4405,7 +4479,53 @@ static void bevel_mesh_recurs(float bsize, short recurs, int allfaces)
}
}
-void bevel_menu()
+void bevel_menu() {
+ BME_Mesh *bm;
+ BME_TransData_Head *td;
+ TransInfo *t;
+ int options, res, gbm_free = 0;
+
+ t = BIF_GetTransInfo();
+ if (!G.editBMesh) {
+ G.editBMesh = MEM_callocN(sizeof(*(G.editBMesh)),"bevel_menu() G.editBMesh");
+ gbm_free = 1;
+ }
+
+ G.editBMesh->options = BME_BEVEL_RUNNING | BME_BEVEL_SELECT;
+ G.editBMesh->res = 1;
+
+ while(G.editBMesh->options & BME_BEVEL_RUNNING) {
+ options = G.editBMesh->options;
+ res = G.editBMesh->res;
+ bm = BME_make_mesh();
+ bm = BME_editmesh_to_bmesh(G.editMesh, bm);
+ BIF_undo_push("Pre-Bevel");
+ free_editMesh(G.editMesh);
+ BME_bevel(bm,0.1f,res,options,0,0,&td);
+ BME_bmesh_to_editmesh(bm, td);
+ EM_selectmode_flush();
+ G.editBMesh->bm = bm;
+ G.editBMesh->td = td;
+ initTransform(TFM_BEVEL,CTX_BMESH);
+ Transform();
+ BME_free_transdata(td);
+ BME_free_mesh(bm);
+ if (t->state != TRANS_CONFIRM) {
+ BIF_undo();
+ }
+ if (options == G.editBMesh->options) {
+ G.editBMesh->options &= ~BME_BEVEL_RUNNING;
+ }
+ }
+
+ if (gbm_free) {
+ MEM_freeN(G.editBMesh);
+ G.editBMesh = NULL;
+ }
+}
+
+
+void bevel_menu_old()
{
char Finished = 0, Canceled = 0, str[100], Recalc = 0;
short mval[2], oval[2], curval[2], event = 0, recurs = 1, nr;
@@ -4538,7 +4658,7 @@ int EdgeLoopDelete(void) {
return 0;
}
select_more();
- removedoublesflag(1,0.001);
+ removedoublesflag(1,0, 0.001);
EM_select_flush();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
return 1;
@@ -4803,34 +4923,35 @@ int EdgeSlide(short immediate, float imperc)
nearest = NULL;
vertdist = -1;
while(look) {
- if(look->next != NULL) {
- SlideVert *sv;
+ tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+ if(!tempsv->up || !tempsv->down) {
+ error("Missing rails");
+ BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
+ BLI_linklist_free(vertlist,NULL);
+ BLI_linklist_free(edgelist,NULL);
+ return 0;
+ }
- tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
- sv = BLI_ghash_lookup(vertgh,(EditVert*)look->next->link);
-
- if(!tempsv->up || !tempsv->down) {
- error("Missing rails");
- BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
- BLI_linklist_free(vertlist,NULL);
- BLI_linklist_free(edgelist,NULL);
- return 0;
+ if(G.f & G_DRAW_EDGELEN) {
+ if(!(tempsv->up->f & SELECT)) {
+ tempsv->up->f |= SELECT;
+ tempsv->up->f2 |= 16;
+ } else {
+ tempsv->up->f2 |= ~16;
}
-
- if(G.f & G_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(!(tempsv->down->f & SELECT)) {
+ tempsv->down->f |= SELECT;
+ tempsv->down->f2 |= 16;
+ } else {
+ tempsv->down->f2 |= ~16;
}
+ }
+
+ if(look->next != NULL) {
+ SlideVert *sv;
+
+ sv = BLI_ghash_lookup(vertgh,(EditVert*)look->next->link);
if(sv) {
float tempdist, co[2];
@@ -5086,6 +5207,9 @@ int EdgeSlide(short immediate, float imperc)
}
force_draw(0);
+
+ if(!immediate)
+ EM_automerge(0);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
scrarea_queue_winredraw(curarea);
@@ -5110,6 +5234,58 @@ int EdgeSlide(short immediate, float imperc)
/* -------------------- More tools ------------------ */
+void mesh_set_face_flags(short mode)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+ short m_tex=0, m_tiles=0, m_shared=0, m_light=0, m_invis=0, m_collision=0, m_twoside=0, m_obcolor=0;
+ short flag = 0, change = 0;
+
+ if (!EM_texFaceCheck()) {
+ error("not a mesh with uv/image layers");
+ return;
+ }
+
+ add_numbut(0, TOG|SHO, "Texture", 0, 0, &m_tex, NULL);
+ add_numbut(1, TOG|SHO, "Tiles", 0, 0, &m_tiles, NULL);
+ add_numbut(2, TOG|SHO, "Shared", 0, 0, &m_shared, NULL);
+ add_numbut(3, TOG|SHO, "Light", 0, 0, &m_light, NULL);
+ add_numbut(4, TOG|SHO, "Invisible", 0, 0, &m_invis, NULL);
+ add_numbut(5, TOG|SHO, "Collision", 0, 0, &m_collision, NULL);
+ add_numbut(6, TOG|SHO, "Twoside", 0, 0, &m_twoside, NULL);
+ add_numbut(7, TOG|SHO, "ObColor", 0, 0, &m_obcolor, NULL);
+
+ if (!do_clever_numbuts((mode ? "Set Flags" : "Clear Flags"), 8, REDRAW))
+ return;
+
+ if (m_tex) flag |= TF_TEX;
+ if (m_tiles) flag |= TF_TILES;
+ if (m_shared) flag |= TF_SHAREDCOL;
+ if (m_light) flag |= TF_LIGHT;
+ if (m_invis) flag |= TF_INVISIBLE;
+ if (m_collision) flag |= TF_DYNAMIC;
+ if (m_twoside) flag |= TF_TWOSIDE;
+ if (m_obcolor) flag |= TF_OBCOL;
+
+ efa= em->faces.first;
+ while(efa) {
+ if(efa->f & SELECT) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (mode) tface->mode |= flag;
+ else tface->mode &= ~flag;
+ }
+ efa= efa->next;
+ }
+
+ if (change) {
+ BIF_undo_push((mode ? "Set Flags" : "Clear Flags"));
+
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+}
+
void mesh_set_smooth_faces(short event)
{
EditMesh *em = G.editMesh;
@@ -5844,7 +6020,7 @@ static void collapse_edgeuvs(void)
int curtag, balanced, collectionfound= 0, vcount;
float avg[2];
- if (!CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE))
+ if (!EM_texFaceCheck())
return;
uvverts.first = uvverts.last = uvedges.first = uvedges.last = allcollections.first = allcollections.last = NULL;
@@ -5946,7 +6122,7 @@ static void collapseuvs(void)
int uvcount;
float uvav[2];
- if (!CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE))
+ if (!EM_texFaceCheck())
return;
uvcount = 0;
@@ -6054,7 +6230,7 @@ int collapseEdges(void)
VECCOPY(((EditEdge*)curredge->eed)->v2->co,avgcount);
}
- if (CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE)) {
+ if (EM_texFaceCheck()) {
/*uv collapse*/
for(eve=G.editMesh->verts.first; eve; eve=eve->next) eve->f1 = 0;
for(eed=G.editMesh->edges.first; eed; eed=eed->next) eed->f1 = 0;
@@ -6068,11 +6244,13 @@ int collapseEdges(void)
}
freecollections(&allcollections);
- removedoublesflag(1, MERGELIMIT);
+ removedoublesflag(1, 0, MERGELIMIT);
/*get rid of this!*/
countall();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
return mergecount;
}
@@ -6110,7 +6288,7 @@ int merge_firstlast(int first, int uvmerge)
}
countall();
- return removedoublesflag(1,MERGELIMIT);
+ return removedoublesflag(1, 0, MERGELIMIT);
}
int merge_target(int target, int uvmerge)
@@ -6133,7 +6311,7 @@ int merge_target(int target, int uvmerge)
countall();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
- return removedoublesflag(1,MERGELIMIT);
+ return removedoublesflag(1, 0, MERGELIMIT);
}
#undef MERGELIMIT
@@ -6301,6 +6479,8 @@ void pathselect(void)
countall();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
}
}
else{
@@ -6338,6 +6518,8 @@ void region_to_loop(void)
countall();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Face Region to Edge Loop");
}
@@ -6496,6 +6678,215 @@ void loop_to_region(void)
freecollections(&allcollections);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
BIF_undo_push("Edge Loop to Face Region");
}
+
+/* texface and vertex color editmode tools for the face menu */
+
+void mesh_rotate_uvs(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ short change = 0, ccw;
+ MTFace *tf;
+ float u1, v1;
+
+ if (!EM_texFaceCheck()) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+
+ ccw = (G.qual == LR_SHIFTKEY);
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ u1= tf->uv[0][0];
+ v1= tf->uv[0][1];
+
+ if (ccw) {
+ if(efa->v4) {
+ tf->uv[0][0]= tf->uv[3][0];
+ tf->uv[0][1]= tf->uv[3][1];
+
+ tf->uv[3][0]= tf->uv[2][0];
+ tf->uv[3][1]= tf->uv[2][1];
+ } else {
+ tf->uv[0][0]= tf->uv[2][0];
+ tf->uv[0][1]= tf->uv[2][1];
+ }
+
+ tf->uv[2][0]= tf->uv[1][0];
+ tf->uv[2][1]= tf->uv[1][1];
+
+ tf->uv[1][0]= u1;
+ tf->uv[1][1]= v1;
+ } else {
+ tf->uv[0][0]= tf->uv[1][0];
+ tf->uv[0][1]= tf->uv[1][1];
+
+ tf->uv[1][0]= tf->uv[2][0];
+ tf->uv[1][1]= tf->uv[2][1];
+
+ if(efa->v4) {
+ tf->uv[2][0]= tf->uv[3][0];
+ tf->uv[2][1]= tf->uv[3][1];
+
+ tf->uv[3][0]= u1;
+ tf->uv[3][1]= v1;
+ }
+ else {
+ tf->uv[2][0]= u1;
+ tf->uv[2][1]= v1;
+ }
+ }
+ change = 1;
+ }
+ }
+
+ if (change) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Rotate UV face");
+ }
+}
+
+void mesh_mirror_uvs(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ short change = 0;
+ MTFace *tf;
+ float u1, v1;
+
+ if (!EM_texFaceCheck()) {
+ error("mesh has no uv/image layers");
+ return;
+ }
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ u1= tf->uv[0][0];
+ v1= tf->uv[0][1];
+ if(efa->v4) {
+ tf->uv[0][0]= tf->uv[3][0];
+ tf->uv[0][1]= tf->uv[3][1];
+
+ tf->uv[3][0]= u1;
+ tf->uv[3][1]= v1;
+
+ u1= tf->uv[1][0];
+ v1= tf->uv[1][1];
+
+ tf->uv[1][0]= tf->uv[2][0];
+ tf->uv[1][1]= tf->uv[2][1];
+
+ tf->uv[2][0]= u1;
+ tf->uv[2][1]= v1;
+ }
+ else {
+ tf->uv[0][0]= tf->uv[2][0];
+ tf->uv[0][1]= tf->uv[2][1];
+ tf->uv[2][0]= u1;
+ tf->uv[2][1]= v1;
+ }
+ change = 1;
+ }
+ }
+
+ if (change) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Mirror UV face");
+ }
+}
+
+void mesh_rotate_colors(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ short change = 0, ccw;
+ MCol tmpcol, *mcol;
+ if (!EM_vertColorCheck()) {
+ error("mesh has no color layers");
+ return;
+ }
+
+ ccw = (G.qual == LR_SHIFTKEY);
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ tmpcol= mcol[0];
+
+ if (ccw) {
+ if(efa->v4) {
+ mcol[0]= mcol[3];
+ mcol[3]= mcol[2];
+ } else {
+ mcol[0]= mcol[2];
+ }
+ mcol[2]= mcol[1];
+ mcol[1]= tmpcol;
+ } else {
+ mcol[0]= mcol[1];
+ mcol[1]= mcol[2];
+
+ if(efa->v4) {
+ mcol[2]= mcol[3];
+ mcol[3]= tmpcol;
+ }
+ else
+ mcol[2]= tmpcol;
+ }
+ change = 1;
+ }
+ }
+
+ if (change) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Rotate Color face");
+ }
+}
+
+void mesh_mirror_colors(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ short change = 0;
+ MCol tmpcol, *mcol;
+ if (!EM_vertColorCheck()) {
+ error("mesh has no color layers");
+ return;
+ }
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ if (efa->f & SELECT) {
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+ tmpcol= mcol[0];
+
+ mcol[0]= mcol[1];
+ mcol[1]= mcol[2];
+
+ if(efa->v4) {
+ mcol[2]= mcol[3];
+ mcol[3]= tmpcol;
+ }
+ else {
+ mcol[2]= tmpcol;
+ }
+ change = 1;
+ }
+ }
+
+ if (change) {
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Mirror Color face");
+ }
+}
diff --git a/source/blender/src/editmode_undo.c b/source/blender/src/editmode_undo.c
index 22a399ae1e2..cd7a6c23069 100644
--- a/source/blender/src/editmode_undo.c
+++ b/source/blender/src/editmode_undo.c
@@ -79,6 +79,7 @@ void undo_editmode_push(char *name,
void (*freedata)(void *), // pointer to function freeing data
void (*to_editmode)(void *), // data to editmode conversion
void * (*from_editmode)(void)) // editmode to data conversion
+ int (*validate_undo)(void *)) // check if undo data is still valid
Further exported for UI is:
@@ -96,7 +97,8 @@ void undo_editmode_menu(void) // history menu
void undo_editmode_clear(void); // free & clear all data
void undo_editmode_menu(void); // history menu
void undo_editmode_push(char *name, void (*freedata)(void *),
- void (*to_editmode)(void *), void *(*from_editmode)(void));
+ void (*to_editmode)(void *), void *(*from_editmode)(void),
+ int (*validate_undo)(void *));
struct uiBlock *editmode_undohistorymenu(void *arg_unused);
@@ -112,6 +114,7 @@ typedef struct UndoElem {
void (*freedata)(void *);
void (*to_editmode)(void *);
void * (*from_editmode)(void);
+ int (*validate_undo)(void *);
} UndoElem;
static ListBase undobase={NULL, NULL};
@@ -133,7 +136,8 @@ static void undo_restore(UndoElem *undo)
/* name can be a dynamic string */
void undo_editmode_push(char *name, void (*freedata)(void *),
- void (*to_editmode)(void *), void *(*from_editmode)(void))
+ void (*to_editmode)(void *), void *(*from_editmode)(void),
+ int (*validate_undo)(void *))
{
UndoElem *uel;
int nr;
@@ -157,6 +161,7 @@ void undo_editmode_push(char *name, void (*freedata)(void *),
uel->freedata= freedata;
uel->to_editmode= to_editmode;
uel->from_editmode= from_editmode;
+ uel->validate_undo= validate_undo;
/* and limit amount to the maximum */
nr= 0;
@@ -197,7 +202,8 @@ static void undo_clean_stack(void)
next= uel->next;
/* for when objects are converted, renamed, or global undo changes pointers... */
- if(uel->type==G.obedit->type && strcmp(uel->id.name, G.obedit->id.name)==0) {
+ if(uel->type==G.obedit->type && strcmp(uel->id.name, G.obedit->id.name)==0 &&
+ (!uel->validate_undo || uel->validate_undo(uel->undodata))) {
uel->ob= G.obedit;
}
else {
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 73eea2b5aa4..0fc8baae154 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -73,11 +73,13 @@
#include "BIF_toolbox.h"
#include "BIF_editnla.h"
#include "BIF_editaction.h"
+#include "BIF_transform.h"
#include "BSE_editipo.h"
#include "BSE_editnla_types.h"
#include "BSE_headerbuttons.h"
#include "BSE_drawipo.h"
+#include "BSE_editaction_types.h"
#include "BSE_trans_types.h"
#include "BSE_edit.h"
#include "BSE_filesel.h"
@@ -196,11 +198,12 @@ void synchronize_action_strips(void)
calc_action_range(strip->act, &actstart, &actend, 1);
- if(strip->actstart!=actstart || strip->actend!=actend) {
- float mapping= (strip->end - strip->start)/(strip->actend - strip->actstart);
+ if ((strip->actstart!=actstart) || (strip->actend!=actend)) {
+ float offset = strip->scale * (actstart - strip->actstart);
+ float actlen = actend - actstart;
- strip->start+= mapping*(actstart - strip->actstart);
- strip->end+= mapping*(actend - strip->actend);
+ strip->start += offset;
+ strip->end = (strip->scale * strip->repeat * actlen) + strip->start;
strip->actstart= actstart;
strip->actend= actend;
@@ -369,15 +372,41 @@ void reset_action_strips(int val)
for (strip = base->object->nlastrips.last; strip; strip=strip->prev) {
if (strip->flag & ACTSTRIP_SELECT) {
- if(val==2) {
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
- }
- else if(val==1) {
- float mapping= (strip->actend - strip->actstart)/(strip->end - strip->start);
-
- strip->end= strip->start + mapping*(strip->end - strip->start);
+ switch (val) {
+ case 1:
+ {
+ /* clear scaling - reset to 1.0 without touching keys */
+ float actlen= (strip->actend - strip->actstart);
+
+ strip->scale= 1.0f;
+ strip->end= (strip->repeat * actlen) + strip->start;
+ }
+ break;
+ case 2:
+ {
+ /* reset action-range */
+ calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
+ }
+ break;
+ case 3:
+ {
+ /* apply scale to keys - scale is reset to 1.0f, but keys stay at the same times */
+ bActionChannel *achan;
+
+ if (strip->act) {
+ for (achan= strip->act->chanbase.first; achan; achan= achan->next) {
+ actstrip_map_ipo_keys(base->object, achan->ipo, 0, 0);
+ }
+
+ /* now we can reset scale */
+ calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
+ strip->scale= 1.0f;
+ strip->end = (strip->repeat * (strip->actend - strip->actstart)) + strip->start;
+ }
+ }
+ break;
}
- base->object->ctime= -1234567.0f; // eveil!
+ base->object->ctime= -1234567.0f; // evil!
DAG_object_flush_update(G.scene, base->object, OB_RECALC_OB|OB_RECALC_DATA);
}
}
@@ -394,9 +423,16 @@ void snap_action_strips(int snap_mode)
bActionStrip *strip;
for (base=G.scene->base.first; base; base=base->next) {
+ /* object has ipo - these keyframes should be able to be snapped, even if strips are collapsed */
+ if (base->object->ipo) {
+ snap_ipo_keys(base->object->ipo, snap_mode);
+ }
+
+ /* object is collapsed - action and nla strips not shown/editable */
if (base->object->nlaflag & OB_NLA_COLLAPSED)
continue;
+ /* snap action strips */
for (strip = base->object->nlastrips.last; strip; strip=strip->prev) {
if (strip->flag & ACTSTRIP_SELECT) {
if (snap_mode==1) {
@@ -418,11 +454,40 @@ void snap_action_strips(int snap_mode)
strip->end += diff;
}
}
+ else if (snap_mode==3) {
+ /* nearest second */
+ float secf = FPS;
+ strip->start= (float)(floor(strip->start/secf + 0.5f) * secf);
+ strip->end= (float)(floor(strip->end/secf + 0.5f) * secf);
+ }
+ }
+ }
+
+ /* object has action */
+ if (base->object->action) {
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+
+ /* filter action data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, base->object->action, ACTCONT_ACTION);
+
+ /* snap to frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ actstrip_map_ipo_keys(base->object, ale->key_data, 0, 1);
+ snap_ipo_keys(ale->key_data, snap_mode);
+ actstrip_map_ipo_keys(base->object, ale->key_data, 1, 1);
}
+ BLI_freelistN(&act_data);
+
+ remake_action_ipos(base->object->action);
}
}
BIF_undo_push("Snap NLA strips");
allqueue (REDRAWVIEW3D, 0);
+ allqueue (REMAKEIPO, 0);
+ allqueue (REDRAWIPO, 0);
allqueue (REDRAWACTION, 0);
allqueue (REDRAWNLA, 0);
}
@@ -516,7 +581,7 @@ static void add_nla_block(short event)
/* simple prevention of zero strips */
if(strip->start>strip->end-2)
strip->end= strip->start+100;
- strip->repeat = 1.0;
+ strip->repeat = strip->scale= 1.0f;
strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
@@ -555,6 +620,7 @@ static void add_nla_block_by_name(char name[32], Object *ob, short hold, short a
/* Initialize the new action block */
strip = MEM_callocN(sizeof(bActionStrip), "bActionStrip");
+ strip->scale= 1.0f;
deselect_nlachannel_keys(0);
@@ -794,8 +860,12 @@ static void mouse_nlachannels(short mval[2])
if(actclick) /* de-activate all strips */
set_active_strip(ob, NULL);
- else if(strip) /* set action */
- set_active_strip(ob, strip);
+ else if(strip) {
+ if(mval[0] >= (NLAWIDTH-16)) /* toggle strip muting */
+ strip->flag ^= ACTSTRIP_MUTE;
+ else /* set action */
+ set_active_strip(ob, strip);
+ }
/* icon toggles beside strip */
if (obclick && mval[0]<20) {
@@ -806,6 +876,10 @@ static void mouse_nlachannels(short mval[2])
/* override option for NLA */
ob->nlaflag ^= OB_NLA_OVERRIDE;
}
+ else if((obclick) && (ob->ipo) && (mval[0] >= (NLAWIDTH-16))) {
+ /* mute Object IPO-block */
+ ob->ipo->muteipo = (ob->ipo->muteipo)? 0: 1;
+ }
ob->ctime= -1234567.0f; // eveil!
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
@@ -936,291 +1010,28 @@ static void recalc_all_ipos(void)
void transform_nlachannel_keys(int mode, int dummy)
{
- Base *base;
- TransVert *tv;
- bActionChannel *chan;
- bActionStrip *strip;
- bConstraintChannel *conchan;
- float sval[2], cval[2], lastcval[2];
- float fac=0.0F;
- float deltax, startx;
- int i;
- int loop=1;
- int tvtot=0;
- int invert=0, firsttime=1;
- short mvals[2], mvalc[2];
- short cancel=0;
- char str[256];
-
- /* Ensure that partial selections result in beztriple selections */
- for (base=G.scene->base.first; base; base=base->next){
- /* Check object ipos */
- i= fullselect_ipo_keys(base->object->ipo);
- if(i) base->flag |= BA_HAS_RECALC_OB;
- tvtot+=i;
-
- /* Check object constraint ipos */
- for(conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- tvtot+=fullselect_ipo_keys(conchan->ipo);
-
- /* skip actions and nlastrips if object is collapsed */
- if (base->object->nlaflag & OB_NLA_COLLAPSED)
- continue;
-
- /* Check action ipos */
- if (base->object->action){
- /* exclude if strip is selected too */
- for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
- if (strip->flag & ACTSTRIP_SELECT)
- if(strip->act==base->object->action)
- break;
- }
- if(strip==NULL) {
-
- for (chan=base->object->action->chanbase.first; chan; chan=chan->next) {
- if (EDITABLE_ACHAN(chan)) {
- i= fullselect_ipo_keys(chan->ipo);
- if(i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
- tvtot+=i;
-
- /* Check action constraint ipos */
- if (EXPANDED_ACHAN(chan) && FILTER_CON_ACHAN(chan)) {
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot+=fullselect_ipo_keys(conchan->ipo);
- }
- }
- }
- }
- }
- }
-
- /* Check nlastrips */
- for (strip=base->object->nlastrips.first; strip; strip=strip->next){
- if (strip->flag & ACTSTRIP_SELECT) {
- base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
- tvtot+=2;
- }
- }
- }
-
- /* If nothing is selected, bail out */
- if (!tvtot)
- return;
-
-
- /* Build the transvert structure */
- tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
- tvtot=0;
- for (base=G.scene->base.first; base; base=base->next){
- /* Manipulate object ipos */
- tvtot=add_trans_ipo_keys(base->object->ipo, tv, tvtot);
-
- /* Manipulate object constraint ipos */
- for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- tvtot=add_trans_ipo_keys(conchan->ipo, tv, tvtot);
+ short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
- /* skip actions and nlastrips if object collapsed */
- if (base->object->nlaflag & OB_NLA_COLLAPSED)
- continue;
-
- /* Manipulate action ipos */
- if (base->object->action){
- /* exclude if strip is selected too */
- for (strip=base->object->nlastrips.first; strip; strip=strip->next){
- if (strip->flag & ACTSTRIP_SELECT)
- if(strip->act==base->object->action)
- break;
- }
-
- /* can include - no selected strip is action */
- if(strip==NULL) {
- for (chan=base->object->action->chanbase.first; chan; chan=chan->next){
- if (EDITABLE_ACHAN(chan)) {
- tvtot=add_trans_ipo_keys(chan->ipo, tv, tvtot);
-
- /* Manipulate action constraint ipos */
- if (EXPANDED_ACHAN(chan) && FILTER_CON_ACHAN(chan)) {
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot=add_trans_ipo_keys(conchan->ipo, tv, tvtot);
- }
- }
- }
- }
- }
- }
-
- /* Manipulate nlastrips */
- for (strip=base->object->nlastrips.first; strip; strip=strip->next){
- if (strip->flag & ACTSTRIP_SELECT){
- tv[tvtot+0].val=&strip->start;
- tv[tvtot+1].val=&strip->end;
-
- tv[tvtot+0].oldval = strip->start;
- tv[tvtot+1].oldval = strip->end;
-
- tvtot+=2;
- }
+ switch (mode) {
+ case 'g':
+ {
+ initTransform(TFM_TIME_TRANSLATE, context);
+ Transform();
}
- }
-
- /* Do the event loop */
- // cent[0] = curarea->winx + (G.snla->v2d.hor.xmax)/2;
- // cent[1] = curarea->winy + (G.snla->v2d.hor.ymax)/2;
-
- // areamouseco_to_ipoco(cent, &cenf[0], &cenf[1]);
-
- getmouseco_areawin (mvals);
- areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
-
- startx=sval[0];
- while (loop) {
- /* Get the input */
- /* If we're cancelling, reset transformations */
- /* Else calc new transformation */
- /* Perform the transformations */
- while (qtest()) {
- short val;
- unsigned short event= extern_qread(&val);
-
- if (val) {
- switch (event) {
- case LEFTMOUSE:
- case SPACEKEY:
- case RETKEY:
- loop=0;
- break;
- case XKEY:
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- cancel=1;
- loop=0;
- break;
- default:
- arrows_move_cursor(event);
- break;
- };
- }
- }
-
- if (cancel) {
- for (i=0; i<tvtot; i++) {
- if (tv[i].loc){
- tv[i].loc[0]=tv[i].oldloc[0];
- tv[i].loc[1]=tv[i].oldloc[1];
- }
- if (tv[i].val)
- tv[i].val[0]=tv[i].oldval;
- }
+ break;
+ case 's':
+ {
+ initTransform(TFM_TIME_SCALE, context);
+ Transform();
}
- else {
- getmouseco_areawin (mvalc);
- areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
-
- if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
- PIL_sleep_ms(10);
- }
- else {
- for (i=0; i<tvtot; i++){
- if (tv[i].loc)
- tv[i].loc[0]=tv[i].oldloc[0];
- if (tv[i].val)
- tv[i].val[0]=tv[i].oldval;
-
- switch (mode){
- case 'g':
- deltax = cval[0]-sval[0];
- fac= deltax;
-
- apply_keyb_grid(&fac, 0.0F, 1.0F, 0.1F, U.flag & USER_AUTOGRABGRID);
-
- if (tv[i].loc)
- tv[i].loc[0]+=fac;
- if (tv[i].val)
- tv[i].val[0]+=fac;
- break;
- case 's':
- startx=mvals[0]-(NLAWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
- deltax=mvalc[0]-(NLAWIDTH/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
- fac= (float)fabs(deltax/startx);
-
- apply_keyb_grid(&fac, 0.0F, 0.2F, 0.1F, U.flag & USER_AUTOSIZEGRID);
-
- if (invert){
- if (i % 03 == 0){
- memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i+2].oldloc));
- }
- if (i % 03 == 2){
- memcpy (tv[i].loc, tv[i].oldloc, sizeof(tv[i-2].oldloc));
- }
-
- fac*=-1;
- }
- startx= (G.scene->r.cfra);
-
- if (tv[i].loc){
- tv[i].loc[0]-= startx;
- tv[i].loc[0]*=fac;
- tv[i].loc[0]+= startx;
- }
- if (tv[i].val){
- tv[i].val[0]-= startx;
- tv[i].val[0]*=fac;
- tv[i].val[0]+= startx;
- }
-
- break;
- }
- }
-
- if (mode=='s'){
- sprintf(str, "scaleX: %.3f", fac);
- headerprint(str);
- }
- else if (mode=='g'){
- sprintf(str, "deltaX: %.3f", fac);
- headerprint(str);
- }
-
- if (G.snla->lock) {
- for (base=G.scene->base.first; base; base=base->next){
- if(base->flag & BA_HAS_RECALC_OB)
- base->object->recalc |= OB_RECALC_OB;
- if(base->flag & BA_HAS_RECALC_DATA)
- base->object->recalc |= OB_RECALC_DATA;
-
- if(base->object->recalc) base->object->ctime= -1234567.0f; // eveil!
- }
-
- DAG_scene_flush_update(G.scene, screen_view3d_layers());
-
- force_draw_all(0);
- }
- else {
- force_draw(0);
- }
- }
+ break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, context);
+ Transform();
}
-
- lastcval[0]= cval[0];
- lastcval[1]= cval[1];
- firsttime= 0;
+ break;
}
-
- synchronize_action_strips();
-
- /* cleanup */
- for (base=G.scene->base.first; base; base=base->next)
- base->flag &= ~(BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA);
-
- if(cancel==0) BIF_undo_push("Select all NLA");
- recalc_all_ipos(); // bad
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- MEM_freeN (tv);
}
void delete_nlachannel_keys(void)
@@ -1267,10 +1078,10 @@ void delete_nlachannel_keys(void)
}
}
+ recalc_all_ipos(); // bad
synchronize_action_strips();
BIF_undo_push("Delete NLA keys");
- recalc_all_ipos(); // bad
allspace(REMAKEIPO,0);
allqueue (REDRAWVIEW3D, 0);
allqueue(REDRAWNLA, 0);
@@ -1428,11 +1239,7 @@ void borderselect_nla(void)
}
}
BIF_undo_push("Border select NLA");
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
}
@@ -1453,7 +1260,7 @@ static void mouse_nla(int selectmode)
/* Try object ipo or ob-constraint ipo selection */
base= get_nearest_nlachannel_ob_key(&selx, &sel);
- marker=find_nearest_marker(1);
+ marker=find_nearest_marker(SCE_MARKERS, 1);
if (base) {
isdone= 1;
@@ -1487,11 +1294,7 @@ static void mouse_nla(int selectmode)
std_rmouse_transform(transform_markers);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
else {
/* Try action ipo selection */
@@ -1917,7 +1720,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (!snla) return;
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -1950,11 +1753,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
shift_nlastrips_up();
else {
nextprev_marker(1);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
@@ -1967,11 +1766,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
shift_nlastrips_down();
else {
nextprev_marker(-1);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
@@ -1983,11 +1778,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if (G.qual & LR_CTRLKEY) {
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
else{
if (mval[0]>=NLAWIDTH)
@@ -2036,6 +1827,13 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
+ case EKEY:
+ if (mval[0] >= NLAWIDTH) {
+ transform_nlachannel_keys ('e', 0);
+ update_for_newframe_muted();
+ }
+ break;
+
case GKEY:
if (mval[0]>=NLAWIDTH) {
if (G.qual & LR_CTRLKEY) {
@@ -2056,11 +1854,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
rename_marker();
else
break;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case NKEY:
@@ -2081,24 +1875,21 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWBUTSALL, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case SKEY:
- if(G.qual==LR_ALTKEY) {
- val= pupmenu("Action Strip Scale%t|Clear Strip Scale%x1|Remap Start/End%x2");
- if(val==1)
- reset_action_strips(1);
- else if(val==2)
- reset_action_strips(2);
+ if (G.qual==LR_ALTKEY) {
+ val= pupmenu("Action Strip Scale%t|Reset Strip Scale%x1|Remap Action Start/End%x2|Apply Scale%x3");
+ if (val > 0)
+ reset_action_strips(val);
}
- else if(G.qual & LR_SHIFTKEY) {
- val= pupmenu("Snap To%t|Nearest Frame%x1|Current Frame%x2");
- if (val==1 || val==2)
+ else if (G.qual & LR_SHIFTKEY) {
+ if (snla->flag & SNLA_DRAWTIME)
+ val= pupmenu("Snap To%t|Nearest Second%x3|Current Time%x2");
+ else
+ val= pupmenu("Snap To%t|Nearest Frame%x1|Current Frame%x2");
+ if (ELEM3(val, 1, 2, 3))
snap_action_strips(val);
}
else {
@@ -2108,20 +1899,29 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
+ case TKEY:
+ if (G.qual & LR_CTRLKEY) {
+ val= pupmenu("Time value%t|Frames %x1|Seconds%x2");
+
+ if (val > 0) {
+ if (val == 2) snla->flag |= SNLA_DRAWTIME;
+ else snla->flag &= ~SNLA_DRAWTIME;
+
+ doredraw= 1;
+ }
+ }
+ break;
+
case DELKEY:
case XKEY:
if (mval[0]>=NLAWIDTH) {
if (okee("Erase selected?")) {
- remove_marker();
-
delete_nlachannel_keys();
update_for_newframe_muted();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ remove_marker();
+
+ allqueue(REDRAWMARKER, 0);
}
}
break;
@@ -2138,7 +1938,7 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
- cfra= (int)dx;
+ cfra= (int)(dx+0.5f);
if(cfra< 1) cfra= 1;
if( cfra!=CFRA ) {
@@ -2199,7 +1999,8 @@ void bake_all_to_action(void)
ob = get_object_from_active_strip();
if (ob) {
if (ob->flag&OB_ARMATURE) {
- newAction = bake_obIPO_to_action(ob);
+ //newAction = bake_obIPO_to_action(ob);
+ newAction = NULL;
if (newAction) {
/* unlink the object's IPO */
ipo=ob->ipo;
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 28c1d898a62..a308b428894 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -22,7 +22,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -60,6 +60,7 @@
#include "BIF_editview.h"
#include "BIF_gl.h"
#include "BIF_graphics.h"
+#include "BIF_imasel.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
#include "BIF_previewrender.h"
@@ -211,6 +212,13 @@ static void load_node_image(char *str) /* called from fileselect */
}
}
+static void set_node_imagepath(char *str) /* called from fileselect */
+{
+ SpaceNode *snode= curarea->spacedata.first;
+ bNode *node= nodeGetActive(snode->edittree);
+ BLI_strncpy(((NodeImageFile *)node->storage)->name, str, sizeof( ((NodeImageFile *)node->storage)->name ));
+}
+
static bNode *snode_get_editgroup(SpaceNode *snode)
{
bNode *gnode;
@@ -243,6 +251,7 @@ static void composite_node_render(SpaceNode *snode, bNode *node)
G.scene->r.mode &= ~(R_BORDER|R_DOCOMP);
G.scene->r.mode |= scene->r.mode & R_BORDER;
G.scene->r.border= scene->r.border;
+ G.scene->r.cfra= scene->r.cfra;
}
scemode= G.scene->r.scemode;
@@ -279,8 +288,24 @@ static void composit_node_event(SpaceNode *snode, short event)
if(node->id)
strcpy(name, ((Image *)node->id)->name);
else strcpy(name, U.textudir);
+ if (G.qual & LR_CTRLKEY) {
+ activate_imageselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
+ } else {
+ activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
+ }
+ break;
+ }
+ case B_NODE_SETIMAGE:
+ {
+ bNode *node= nodeGetActive(snode->edittree);
+ char name[FILE_MAXDIR+FILE_MAXFILE];
- activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image);
+ strcpy(name, ((NodeImageFile *)node->storage)->name);
+ if (G.qual & LR_CTRLKEY) {
+ activate_imageselect(FILE_SPECIAL, "SELECT OUTPUT DIR", name, set_node_imagepath);
+ } else {
+ activate_fileselect(FILE_SPECIAL, "SELECT OUTPUT DIR", name, set_node_imagepath);
+ }
break;
}
case B_NODE_TREE_EXEC:
@@ -292,12 +317,17 @@ static void composit_node_event(SpaceNode *snode, short event)
bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC);
if(node) {
NodeTagChanged(snode->edittree, node);
- NodeTagIDChanged(snode->nodetree, node->id); /* Scene-layer nodes, texture nodes, image nodes, all can be used many times */
+ /* 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);
- /* new event, a render can go fullscreen and open new window */
+ 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 {
@@ -328,10 +358,10 @@ void node_shader_default(Material *ma)
ma->nodetree= ntreeAddTree(NTREE_SHADER);
- out= nodeAddNodeType(ma->nodetree, SH_NODE_OUTPUT, NULL);
+ out= nodeAddNodeType(ma->nodetree, SH_NODE_OUTPUT, NULL, NULL);
out->locx= 300.0f; out->locy= 300.0f;
- in= nodeAddNodeType(ma->nodetree, SH_NODE_MATERIAL, NULL);
+ in= nodeAddNodeType(ma->nodetree, SH_NODE_MATERIAL, NULL, NULL);
in->locx= 10.0f; in->locy= 300.0f;
nodeSetActive(ma->nodetree, in);
@@ -358,10 +388,10 @@ void node_composit_default(Scene *sce)
sce->nodetree= ntreeAddTree(NTREE_COMPOSIT);
- out= nodeAddNodeType(sce->nodetree, CMP_NODE_COMPOSITE, NULL);
+ out= nodeAddNodeType(sce->nodetree, CMP_NODE_COMPOSITE, NULL, NULL);
out->locx= 300.0f; out->locy= 400.0f;
- in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_LAYERS, NULL);
+ in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_LAYERS, NULL, NULL);
in->locx= 10.0f; in->locy= 400.0f;
nodeSetActive(sce->nodetree, in);
@@ -616,7 +646,7 @@ static void node_addgroup(SpaceNode *snode)
if(val>=0) {
ngroup= BLI_findlink(&G.main->nodetree, val);
if(ngroup) {
- bNode *node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup);
+ bNode *node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup, NULL);
/* generics */
if(node) {
@@ -826,6 +856,23 @@ static void snode_bg_viewmove(SpaceNode *snode)
window_set_cursor(win, oldcursor);
}
+static void reset_sel_socket(SpaceNode *snode, int in_out)
+{
+ bNode *node;
+ bNodeSocket *sock;
+
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(in_out & SOCK_IN) {
+ for(sock= node->inputs.first; sock; sock= sock->next)
+ if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
+ }
+ if(in_out & SOCK_OUT) {
+ for(sock= node->outputs.first; sock; sock= sock->next)
+ if(sock->flag & SOCK_SEL) sock->flag&= ~SOCK_SEL;
+ }
+ }
+}
+
/* checks mouse position, and returns found node/socket */
/* type is SOCK_IN and/or SOCK_OUT */
static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out)
@@ -836,15 +883,28 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
short mval[2];
getmouseco_areawin(mval);
- areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin);
-
- rect.xmin -= NODE_SOCKSIZE+3;
- rect.ymin -= NODE_SOCKSIZE+3;
- rect.xmax = rect.xmin + 2*NODE_SOCKSIZE+6;
- rect.ymax = rect.ymin + 2*NODE_SOCKSIZE+6;
/* check if we click in a socket */
for(node= snode->edittree->nodes.first; node; node= node->next) {
+
+ areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin);
+
+ rect.xmin -= NODE_SOCKSIZE+3;
+ rect.ymin -= NODE_SOCKSIZE+3;
+ rect.xmax = rect.xmin + 2*NODE_SOCKSIZE+6;
+ rect.ymax = rect.ymin + 2*NODE_SOCKSIZE+6;
+
+ if (!(node->flag & NODE_HIDDEN)) {
+ /* extra padding inside and out - allow dragging on the text areas too */
+ if (in_out == SOCK_IN) {
+ rect.xmax += NODE_SOCKSIZE;
+ rect.xmin -= NODE_SOCKSIZE*4;
+ } else if (in_out == SOCK_OUT) {
+ rect.xmax += NODE_SOCKSIZE*4;
+ rect.xmin -= NODE_SOCKSIZE;
+ }
+ }
+
if(in_out & SOCK_IN) {
for(sock= node->inputs.first; sock; sock= sock->next) {
if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
@@ -1049,7 +1109,29 @@ static void scale_node(SpaceNode *snode, bNode *node)
allqueue(REDRAWNODE, 1);
}
+/* ******************** rename ******************* */
+
+void node_rename(SpaceNode *snode)
+{
+ bNode *node, *rename_node;
+ short found_node= 0;
+
+ /* check if a node is selected */
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & SELECT) {
+ found_node= 1;
+ break;
+ }
+ }
+ if(found_node) {
+ rename_node= nodeGetActive(snode->edittree);
+ node_rename_but((char *)rename_node->username);
+ BIF_undo_push("Rename Node");
+
+ allqueue(REDRAWNODE, 1);
+ }
+}
/* ********************** select ******************** */
@@ -1254,6 +1336,47 @@ static int do_header_hidden_node(SpaceNode *snode, bNode *node, float mx, float
return 0;
}
+static void node_link_viewer(SpaceNode *snode, bNode *tonode)
+{
+ bNode *node;
+
+ /* context check */
+ if(tonode==NULL || tonode->outputs.first==NULL)
+ return;
+ if( ELEM(tonode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ return;
+
+ /* get viewer */
+ for(node= snode->edittree->nodes.first; node; node= node->next)
+ if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ if(node->flag & NODE_DO_OUTPUT)
+ break;
+
+ if(node) {
+ bNodeLink *link;
+
+ /* get link to viewer */
+ for(link= snode->edittree->links.first; link; link= link->next)
+ if(link->tonode==node)
+ break;
+
+ if(link) {
+ link->fromnode= tonode;
+ link->fromsock= tonode->outputs.first;
+ NodeTagChanged(snode->edittree, node);
+
+ snode_handle_recalc(snode);
+ }
+ }
+}
+
+
+void node_active_link_viewer(SpaceNode *snode)
+{
+ bNode *node= editnode_get_active(snode->edittree);
+ if(node)
+ node_link_viewer(snode, node);
+}
/* return 0: nothing done */
static int node_mouse_select(SpaceNode *snode, unsigned short event)
@@ -1296,6 +1419,10 @@ static int node_mouse_select(SpaceNode *snode, unsigned short event)
node_set_active(snode, node);
+ /* viewer linking */
+ if(G.qual & LR_CTRLKEY)
+ node_link_viewer(snode, node);
+
/* not so nice (no event), but function below delays redraw otherwise */
force_draw(0);
@@ -1410,7 +1537,7 @@ void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag)
bNode *node, *nodefrom[8];
int totsock= 0, socktype=0;
- if(node_to->inputs.first==NULL)
+ if(node_to==NULL || node_to->inputs.first==NULL)
return;
/* no inputs for node allowed (code it) */
@@ -1463,7 +1590,10 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
node_deselectall(snode, 0);
- if(type>=NODE_GROUP_MENU) {
+ if(type>=NODE_DYNAMIC_MENU) {
+ node= nodeAddNodeType(snode->edittree, type, NULL, NULL);
+ }
+ else if(type>=NODE_GROUP_MENU) {
if(snode->edittree!=snode->nodetree) {
error("Can not add a Group in a Group");
return NULL;
@@ -1471,11 +1601,11 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
else {
bNodeTree *ngroup= BLI_findlink(&G.main->nodetree, type-NODE_GROUP_MENU);
if(ngroup)
- node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup);
+ node= nodeAddNodeType(snode->edittree, NODE_GROUP, ngroup, NULL);
}
}
else
- node= nodeAddNodeType(snode->edittree, type, NULL);
+ node= nodeAddNodeType(snode->edittree, type, NULL, NULL);
/* generics */
if(node) {
@@ -1503,6 +1633,30 @@ bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy)
return node;
}
+void node_mute(SpaceNode *snode)
+{
+ bNode *node;
+
+ /* no disabling inside of groups */
+ if(snode_get_editgroup(snode))
+ return;
+
+ for(node= snode->edittree->nodes.first; node; node= node->next) {
+ if(node->flag & SELECT) {
+ if(node->inputs.first && node->outputs.first) {
+ if(node->flag & NODE_MUTED)
+ node->flag &= ~NODE_MUTED;
+ else
+ node->flag |= NODE_MUTED;
+ }
+ }
+ }
+
+ allqueue(REDRAWNODE, 0);
+ BIF_undo_push("Enable/Disable nodes");
+
+}
+
void node_adduplicate(SpaceNode *snode)
{
@@ -1551,6 +1705,33 @@ static void node_insert_convertor(SpaceNode *snode, bNodeLink *link)
#endif
+static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeLink *link)
+{
+ bNodeLink *tlink;
+ bNodeSocket *sock;
+
+ if(tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
+
+ for(tlink= snode->edittree->links.first; tlink; tlink= tlink->next) {
+ if(link!=tlink && tlink->tosock==link->tosock)
+ break;
+ }
+ if(tlink) {
+ /* is there a free input socket with same type? */
+ for(sock= tlink->tonode->inputs.first; sock; sock= sock->next) {
+ if(sock->type==tlink->fromsock->type)
+ if(nodeCountSocketLinks(snode->edittree, sock) < sock->limit)
+ break;
+ }
+ if(sock)
+ tlink->tosock= sock;
+ else {
+ nodeRemLink(snode->edittree, tlink);
+ }
+ }
+ }
+}
+
/* loop that adds a nodelink, called by function below */
/* in_out = starting socket */
static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int in_out)
@@ -1621,35 +1802,12 @@ static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock,
nodeRemLink(snode->edittree, link);
}
else {
- bNodeLink *tlink;
-
/* send changed events for original tonode and new */
if(link->tonode)
NodeTagChanged(snode->edittree, link->tonode);
/* we might need to remove a link */
- if(in_out==SOCK_OUT) {
- if(tsock && nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) {
-
- for(tlink= snode->edittree->links.first; tlink; tlink= tlink->next) {
- if(link!=tlink && tlink->tosock==link->tosock)
- break;
- }
- if(tlink) {
- /* is there a free input socket with same type? */
- for(tsock= tlink->tonode->inputs.first; tsock; tsock= tsock->next) {
- if(tsock->type==tlink->fromsock->type)
- if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit)
- break;
- }
- if(tsock)
- tlink->tosock= tsock;
- else {
- nodeRemLink(snode->edittree, tlink);
- }
- }
- }
- }
+ if(in_out==SOCK_OUT) node_remove_extra_links(snode, tsock, link);
}
ntreeSolveOrder(snode->edittree);
@@ -1716,10 +1874,18 @@ static int node_add_link(SpaceNode *snode)
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--;
@@ -1809,6 +1975,33 @@ void node_select_linked(SpaceNode *snode, int out)
allqueue(REDRAWNODE, 1);
}
+/* makes a link between selected output and input sockets */
+void node_make_link(SpaceNode *snode)
+{
+ bNode *fromnode, *tonode;
+ bNodeLink *link;
+ bNodeSocket *outsock= snode->edittree->selout;
+ bNodeSocket *insock= snode->edittree->selin;
+
+ if(!insock || !outsock) return;
+ if(nodeFindLink(snode->edittree, outsock, insock)) return;
+
+ if(nodeFindNode(snode->edittree, outsock, &fromnode, NULL) &&
+ nodeFindNode(snode->edittree, insock, &tonode, NULL)) {
+ link= nodeAddLink(snode->edittree, fromnode, outsock, tonode, insock);
+ NodeTagChanged(snode->edittree, tonode);
+ node_remove_extra_links(snode, insock, link);
+ }
+ else return;
+
+ ntreeSolveOrder(snode->edittree);
+ snode_verify_groups(snode);
+ snode_handle_recalc(snode);
+
+ allqueue(REDRAWNODE, 0);
+ BIF_undo_push("Make Link Between Sockets");
+}
+
static void node_border_link_delete(SpaceNode *snode)
{
rcti rect;
@@ -1906,9 +2099,56 @@ void node_read_renderlayers(SpaceNode *snode)
}
}
+ /* own render result should be read/allocated */
+ if(G.scene->id.flag & LIB_DOIT)
+ RE_ReadRenderResult(G.scene, G.scene);
+
snode_handle_recalc(snode);
}
+void node_read_fullsamplelayers(SpaceNode *snode)
+{
+ Render *re= RE_NewRender(G.scene->id.name);
+
+ waitcursor(1);
+
+ BIF_init_render_callbacks(re, 1);
+ RE_MergeFullSample(re, G.scene, snode->nodetree);
+ BIF_end_render_callbacks();
+
+ allqueue(REDRAWNODE, 1);
+ allqueue(REDRAWIMAGE, 1);
+
+ waitcursor(0);
+}
+
+/* called from header_info, when deleting a scene
+ * goes over all scenes other than the input, checks if they have
+ * render layer nodes referencing the to-be-deleted scene, and
+ * resets them to NULL. */
+void clear_scene_in_nodes(Scene *sce)
+{
+ Scene *sce1;
+ bNode *node;
+
+ sce1= G.main->scene.first;
+ while(sce1) {
+ if(sce1!=sce) {
+ if (sce1->nodetree) {
+ for(node= sce1->nodetree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS) {
+ Scene *nodesce= (Scene *)node->id;
+
+ if (nodesce==sce) node->id = NULL;
+ }
+ }
+ }
+ }
+ sce1= sce1->id.next;
+ }
+}
+
+
/* gets active viewer user */
struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
{
@@ -2029,7 +2269,7 @@ static int node_uiDoBlocks(ScrArea *sa, short event)
((struct Link *)block)->next= NULL;
lb->first= lb->last= block;
- retval= uiDoBlocks(lb, event);
+ retval= uiDoBlocks(lb, event, 1);
((struct Link *)block)->prev= prev;
((struct Link *)block)->next= next;
@@ -2047,6 +2287,8 @@ static int node_uiDoBlocks(ScrArea *sa, short event)
void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
SpaceNode *snode= spacedata;
+ bNode *actnode;
+ bNodeSocket *actsock;
unsigned short event= evt->event;
short val= evt->val, doredraw=0, fromlib= 0;
@@ -2074,12 +2316,35 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case RIGHTMOUSE:
- if(!node_mouse_select(snode, event))
+ if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) {
+ if(actsock->flag & SOCK_SEL) {
+ snode->edittree->selin= NULL;
+ actsock->flag&= ~SOCK_SEL;
+ }
+ else {
+ snode->edittree->selin= actsock;
+ reset_sel_socket(snode, SOCK_IN);
+ actsock->flag|= SOCK_SEL;
+ }
+ }
+ else if(find_indicated_socket(snode, &actnode, &actsock, SOCK_OUT)) {
+ if(actsock->flag & SOCK_SEL) {
+ snode->edittree->selout= NULL;
+ actsock->flag&= ~SOCK_SEL;
+ }
+ else {
+ snode->edittree->selout= actsock;
+ reset_sel_socket(snode, SOCK_OUT);
+ actsock->flag|= SOCK_SEL;
+ }
+ }
+ else if(!node_mouse_select(snode, event))
toolbox_n();
break;
case MIDDLEMOUSE:
- if (G.qual==LR_SHIFTKEY) {
+ if((snode->flag & SNODE_BACKDRAW) && (snode->treetype==NTREE_COMPOSIT)
+ && (G.qual==LR_SHIFTKEY)) {
snode_bg_viewmove(snode);
} else {
view2dmove(event);
@@ -2150,6 +2415,9 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case EKEY:
snode_handle_recalc(snode);
break;
+ case FKEY:
+ node_make_link(snode);
+ break;
case GKEY:
if(fromlib) fromlib= -1;
else {
@@ -2177,9 +2445,21 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case LKEY:
node_select_linked(snode, G.qual==LR_SHIFTKEY);
break;
+ case MKEY:
+ node_mute(snode);
+ break;
case RKEY:
- if(okee("Read saved Render Layers"))
- node_read_renderlayers(snode);
+ if(G.qual==LR_CTRLKEY) {
+ node_rename(snode);
+ }
+ else if(G.qual==LR_SHIFTKEY) {
+ if(okee("Read saved Full Sample Layers"))
+ node_read_fullsamplelayers(snode);
+ }
+ else {
+ if(okee("Read saved Render Layers"))
+ node_read_renderlayers(snode);
+ }
break;
case DELKEY:
case XKEY:
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index d362605d63c..1a3775ac301 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -74,11 +74,13 @@
#include "DNA_meta_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
+#include "DNA_object_fluidsim.h"
#include "DNA_object_force.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
+#include "DNA_particle_types.h"
#include "DNA_property_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
@@ -90,6 +92,7 @@
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_ghash.h"
+#include "BLI_rand.h"
#include "BKE_action.h"
#include "BKE_anim.h"
@@ -98,6 +101,7 @@
#include "BKE_customdata.h"
#include "BKE_blender.h"
#include "BKE_booleanops.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_depsgraph.h"
@@ -115,8 +119,10 @@
#include "BKE_material.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_nla.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
@@ -133,6 +139,7 @@
#include "BIF_editlattice.h"
#include "BIF_editmesh.h"
#include "BIF_editoops.h"
+#include "BIF_editparticle.h"
#include "BIF_editview.h"
#include "BIF_editarmature.h"
#include "BIF_gl.h"
@@ -140,6 +147,7 @@
#include "BIF_interface.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
@@ -174,7 +182,6 @@
#include "blendef.h"
#include "butspace.h"
-#include "multires.h"
#include "BIF_transform.h"
#include "BIF_poseobject.h"
@@ -182,11 +189,22 @@
/* --------------------------------- */
+void exit_paint_modes(void)
+{
+ if(G.f & G_VERTEXPAINT) set_vpaint();
+ if(G.f & G_TEXTUREPAINT) set_texturepaint();
+ if(G.f & G_WEIGHTPAINT) set_wpaint();
+ if(G.f & G_SCULPTMODE) set_sculptmode();
+ if(G.f & G_PARTICLEEDIT) PE_set_particle_edit();
+
+ G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE+G_PARTICLEEDIT);
+}
+
void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff */
{
Object *ob;
- G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE);
+ exit_paint_modes();
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) {
@@ -261,8 +279,6 @@ void delete_obj(int ok)
if(G.obedit) return;
if(G.scene->id.lib) return;
- if(G.f & G_SCULPTMODE) set_sculptmode();
-
base= FIRSTBASE;
while(base) {
Base *nbase= base->next;
@@ -279,6 +295,8 @@ void delete_obj(int ok)
}
}
+ exit_paint_modes();
+
if(base->object->type==OB_LAMP) islamp= 1;
#ifdef WITH_VERSE
if(base->object->vnode) b_verse_delete_object(base->object);
@@ -306,7 +324,6 @@ void delete_obj(int ok)
}
countall();
- G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT);
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
if(islamp) reshadeall_displist(); /* only frees displist */
@@ -616,13 +633,10 @@ int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r)
}
}
-void add_hook(void)
+void add_hook_menu(void)
{
- ModifierData *md = NULL;
- HookModifierData *hmd = NULL;
- Object *ob=NULL;
int mode;
-
+
if(G.obedit==NULL) return;
if(modifiers_findByType(G.obedit, eModifierType_Hook))
@@ -631,9 +645,25 @@ void add_hook(void)
mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
if(mode<1) return;
+
+ /* do operations */
+ add_hook(mode);
- /* preconditions */
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+
+ BIF_undo_push("Add hook");
+}
+void add_hook(int mode)
+{
+ ModifierData *md = NULL;
+ HookModifierData *hmd = NULL;
+ Object *ob=NULL;
+
+ if(G.obedit==NULL) return;
+
+ /* preconditions */
if(mode==2) { /* selected object */
Base *base= FIRSTBASE;
while(base) {
@@ -690,11 +720,11 @@ void add_hook(void)
a++;
}
}
-
+
hmd = (HookModifierData*) md;
ob= hmd->object;
}
-
+
/* do it, new hooks or reassign */
if(mode==1 || mode==2 || mode==4) {
float cent[3];
@@ -702,7 +732,7 @@ void add_hook(void)
char name[32];
ok = hook_getIndexArray(&tot, &indexar, name, cent);
-
+
if(ok==0) {
error("Requires selected vertices or active Vertex Group");
}
@@ -710,7 +740,7 @@ void add_hook(void)
if(mode==1) {
Base *base= BASACT, *newbase;
-
+
ob= add_object(OB_EMPTY);
/* set layers OK */
newbase= BASACT;
@@ -724,15 +754,15 @@ void add_hook(void)
BASACT= base;
}
/* if mode is 2 or 4, ob has been set */
-
+
/* new hook */
if(mode==1 || mode==2) {
ModifierData *md = G.obedit->modifiers.first;
-
+
while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
md = md->next;
}
-
+
hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
BLI_insertlinkbefore(&G.obedit->modifiers, md, hmd);
sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
@@ -751,7 +781,7 @@ void add_hook(void)
/* (parentinv ) */
where_is_object(ob);
-
+
Mat4Invert(ob->imat, ob->obmat);
/* apparently this call goes from right to left... */
Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL,
@@ -768,18 +798,14 @@ void add_hook(void)
}
else if(mode==6) { /* clear offset */
where_is_object(ob); /* ob is hook->parent */
-
+
Mat4Invert(ob->imat, ob->obmat);
/* this call goes from right to left... */
Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL,
NULL, NULL, NULL, NULL, NULL);
}
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSOBJECT, 0);
DAG_scene_sort(G.scene);
-
- BIF_undo_push("Add hook");
}
void make_track(void)
@@ -999,9 +1025,15 @@ void clear_object(char mode)
if TESTBASELIB(base) {
ob= base->object;
- if( (ob->flag & OB_POSEMODE) && ob==OBACT) {
- clear_armature(ob, mode);
- armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
+ if ((ob->flag & OB_POSEMODE)) {
+ /* only clear pose transforms if:
+ * - with a mesh in weightpaint mode, it's related armature needs to be cleared
+ * - with clearing transform of object being edited at the time
+ */
+ if ((G.f & G_WEIGHTPAINT) || ob==OBACT) {
+ clear_armature(ob, mode);
+ armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
+ }
}
else if((G.f & G_WEIGHTPAINT)==0) {
@@ -1075,7 +1107,7 @@ void reset_slowparents(void)
{
/* back to original locations */
Base *base;
-
+
base= FIRSTBASE;
while(base) {
if(base->object->parent) {
@@ -1140,7 +1172,7 @@ void make_vertex_parent(void)
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
- if(BEZSELECTED(bezt)) {
+ if(BEZSELECTED_HIDDENHANDLES(bezt)) {
if(v1==0) v1= nr;
else if(v2==0) v2= nr;
else if(v3==0) v3= nr;
@@ -1371,9 +1403,6 @@ void make_parent(void)
}
}
else if(par->type == OB_CURVE){
- bConstraint *con;
- bFollowPathConstraint *data;
-
mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3|Path Constraint %x4");
if(mode<=0){
return;
@@ -1395,24 +1424,26 @@ void make_parent(void)
mode= PARSKEL;
}
else if(mode==4) {
-
+ bConstraint *con;
+ bFollowPathConstraint *data;
+
base= FIRSTBASE;
while(base) {
if TESTBASELIB(base) {
if(base!=BASACT) {
- float cmat[4][4], vec[3], size[3];
-
+ float cmat[4][4], vec[3];
+
con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
strcpy (con->name, "AutoPath");
-
+
data = con->data;
data->tar = BASACT->object;
-
+
add_constraint_to_object(con, base->object);
-
- get_constraint_target_matrix(con, TARGET_OBJECT, NULL, cmat, size, G.scene->r.cfra - base->object->sf);
+
+ get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, G.scene->r.cfra - give_timeoffset(base->object));
VecSubf(vec, base->object->obmat[3], cmat[3]);
-
+
base->object->loc[0] = vec[0];
base->object->loc[1] = vec[1];
base->object->loc[2] = vec[2];
@@ -1423,7 +1454,7 @@ void make_parent(void)
allqueue(REDRAWVIEW3D, 0);
DAG_scene_sort(G.scene);
- BIF_undo_push("make Parent");
+ BIF_undo_push("Make Parent");
return;
}
}
@@ -1602,16 +1633,31 @@ void enter_editmode(int wc)
if(ob->type==OB_MESH) {
me= get_mesh(ob);
if( me==0 ) return;
- if(me->pv) sculptmode_pmv_off(me);
+ if(me->pv) mesh_pmv_off(ob, me);
ok= 1;
G.obedit= ob;
make_editMesh();
allqueue(REDRAWBUTSLOGIC, 0);
- if(G.f & G_FACESELECT) allqueue(REDRAWIMAGE, 0);
+ /*if(G.f & G_FACESELECT) allqueue(REDRAWIMAGE, 0);*/
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
}
if (ob->type==OB_ARMATURE){
arm= base->object->data;
if (!arm) return;
+ /*
+ * The function object_data_is_libdata make a problem here, the
+ * check for ob->proxy return 0 and let blender enter to edit mode
+ * this causa a crash when you try leave the edit mode.
+ * The problem is that i can't remove the ob->proxy check from
+ * object_data_is_libdata that prevent the bugfix #6614, so
+ * i add this little hack here.
+ */
+ if(arm->id.lib) {
+ error_libdata();
+ return;
+ }
ok=1;
G.obedit=ob;
make_editArmature();
@@ -1670,7 +1716,10 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
/* temporal */
countall();
-
+
+ if(EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
if(retopo_mesh_paint_check())
retopo_end_okee();
@@ -1681,9 +1730,7 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
load_editMesh();
if(freedata) free_editMesh(G.editMesh);
-
- if(G.f & G_FACESELECT)
- allqueue(REDRAWIMAGE, 0);
+
if(G.f & G_WEIGHTPAINT)
mesh_octree_table(G.obedit, NULL, 'e');
}
@@ -1717,12 +1764,17 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b
/* total remake of softbody data */
if(modifiers_isSoftbodyEnabled(ob)) {
if (ob->soft && ob->soft->keys) {
- notice("Erased Baked SoftBody");
+ notice("Erase Baked SoftBody");
}
sbObjectToSoftbody(ob);
}
+ if(modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
+
if(ob->type==OB_MESH && get_mesh(ob)->mr)
multires_edge_level_update(ob, get_mesh(ob));
@@ -2036,7 +2088,7 @@ void docenter(int centermode)
/* Warn if any errors occured */
if (tot_lib_error+tot_key_error+tot_multiuser_arm_error) {
char err[512];
- sprintf(err, "Warning %i Object(s) Not Centered, %i Changed%%t", tot_lib_error+tot_key_error+tot_multiuser_arm_error, tot_change);
+ sprintf(err, "Warning %i Object(s) Not Centered, %i Changed:", tot_lib_error+tot_key_error+tot_multiuser_arm_error, tot_change);
if (tot_lib_error)
sprintf(err+strlen(err), "|%i linked library objects", tot_lib_error);
@@ -2045,7 +2097,7 @@ void docenter(int centermode)
if (tot_multiuser_arm_error)
sprintf(err+strlen(err), "|%i multiuser armature object(s)", tot_multiuser_arm_error);
- pupmenu(err);
+ error(err);
}
}
@@ -2164,6 +2216,153 @@ void split_font()
}
}
+static void helpline(short *mval, int *center2d)
+{
+
+ /* helpline, copied from transform.c actually */
+ persp(PERSP_WIN);
+ glDrawBuffer(GL_FRONT);
+
+ BIF_ThemeColor(TH_WIRE);
+
+ setlinestyle(3);
+ glBegin(GL_LINE_STRIP);
+ glVertex2sv(mval);
+ glVertex2iv((GLint *)center2d);
+ glEnd();
+ setlinestyle(0);
+
+ persp(PERSP_VIEW);
+ bglFlush(); // flush display for frontbuffer
+ glDrawBuffer(GL_BACK);
+
+
+}
+
+/* context: ob = lamp */
+/* code should be replaced with proper (custom) transform handles for lamp properties */
+static void spot_interactive(Object *ob, int mode)
+{
+ Lamp *la= ob->data;
+ float transfac, dx, dy, ratio, origval;
+ int keep_running= 1, center2d[2];
+ short mval[2], mvalo[2];
+
+ getmouseco_areawin(mval);
+ getmouseco_areawin(mvalo);
+
+ project_int(ob->obmat[3], center2d);
+ if( center2d[0] > 100000 ) { /* behind camera */
+ center2d[0]= curarea->winx/2;
+ center2d[1]= curarea->winy/2;
+ }
+
+ helpline(mval, center2d);
+
+ /* ratio is like scaling */
+ dx = (float)(center2d[0] - mval[0]);
+ dy = (float)(center2d[1] - mval[1]);
+ transfac = (float)sqrt( dx*dx + dy*dy);
+ if(transfac==0.0f) transfac= 1.0f;
+
+ if(mode==1)
+ origval= la->spotsize;
+ else if(mode==2)
+ origval= la->dist;
+ else if(mode==3)
+ origval= la->clipsta;
+ else
+ origval= la->clipend;
+
+ while (keep_running>0) {
+
+ getmouseco_areawin(mval);
+
+ /* essential for idling subloop */
+ if(mval[0]==mvalo[0] && mval[1]==mvalo[1]) {
+ PIL_sleep_ms(2);
+ }
+ else {
+ char str[32];
+
+ dx = (float)(center2d[0] - mval[0]);
+ dy = (float)(center2d[1] - mval[1]);
+ ratio = (float)(sqrt( dx*dx + dy*dy))/transfac;
+
+ /* do the trick */
+
+ if(mode==1) { /* spot */
+ la->spotsize = ratio*origval;
+ CLAMP(la->spotsize, 1.0f, 180.0f);
+ sprintf(str, "Spot size %.2f\n", la->spotsize);
+ }
+ else if(mode==2) { /* dist */
+ la->dist = ratio*origval;
+ CLAMP(la->dist, 0.01f, 5000.0f);
+ sprintf(str, "Distance %.2f\n", la->dist);
+ }
+ else if(mode==3) { /* sta */
+ la->clipsta = ratio*origval;
+ CLAMP(la->clipsta, 0.001f, 5000.0f);
+ sprintf(str, "Distance %.2f\n", la->clipsta);
+ }
+ else if(mode==4) { /* end */
+ la->clipend = ratio*origval;
+ CLAMP(la->clipend, 0.1f, 5000.0f);
+ sprintf(str, "Clip End %.2f\n", la->clipend);
+ }
+
+ /* cleanup */
+ mvalo[0]= mval[0];
+ mvalo[1]= mval[1];
+
+ /* handle shaded mode */
+ shade_buttons_change_3d();
+
+ /* DRAW */
+ headerprint(str);
+ force_draw_plus(SPACE_BUTS, 0);
+
+ helpline(mval, center2d);
+ }
+
+ while( qtest() ) {
+ short val;
+ unsigned short event= extern_qread(&val);
+
+ switch (event){
+ case ESCKEY:
+ case RIGHTMOUSE:
+ keep_running= 0;
+ break;
+ case LEFTMOUSE:
+ case SPACEKEY:
+ case PADENTER:
+ case RETKEY:
+ if(val)
+ keep_running= -1;
+ break;
+ }
+ }
+ }
+
+ if(keep_running==0) {
+ if(mode==1)
+ la->spotsize= origval;
+ else if(mode==2)
+ la->dist= origval;
+ else if(mode==3)
+ la->clipsta= origval;
+ else
+ la->clipend= origval;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSSHADING, 0);
+ BIF_preview_changed(ID_LA);
+}
+
+
void special_editmenu(void)
{
static short numcuts= 2;
@@ -2179,7 +2378,7 @@ void special_editmenu(void)
if(ob->flag & OB_POSEMODE) {
pose_special_editmenu();
}
- else if(G.f & G_FACESELECT) {
+ else if(FACESEL_PAINT_TEST) {
Mesh *me= get_mesh(ob);
MTFace *tface;
MFace *mface;
@@ -2245,13 +2444,49 @@ void special_editmenu(void)
}
else if(G.f & G_WEIGHTPAINT) {
Object *par= modifiers_isDeformedByArmature(ob);
+
if(par && (par->flag & OB_POSEMODE)) {
- nr= pupmenu("Specials%t|Apply Bone Envelopes to VertexGroups %x1");
- if(nr==1) {
- pose_adds_vgroups(ob);
- BIF_undo_push("Apply Bone Envelopes to VertexGroups");
- }
+ nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2");
+
+ if(nr==1 || nr==2)
+ pose_adds_vgroups(ob, (nr == 2));
+ }
+ }
+ else if(G.f & G_PARTICLEEDIT) {
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEditSettings *pset = PE_settings();
+
+ if(!psys)
+ return;
+
+ if(G.scene->selectmode & SCE_SELECT_POINT)
+ nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
+ else
+ nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
+
+ switch(nr) {
+ case 1:
+ if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return;
+ waitcursor(1);
+ PE_rekey();
+ break;
+ case 2:
+ PE_subdivide();
+ break;
+ case 3:
+ PE_select_root();
+ break;
+ case 4:
+ PE_select_tip();
+ break;
+ case 5:
+ PE_remove_doubles();
+ break;
}
+
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+
+ if(nr>0) waitcursor(0);
}
else {
Base *base, *base_select= NULL;
@@ -2315,6 +2550,14 @@ void special_editmenu(void)
allqueue(REDRAWVIEW3D, 0);
}
+ else if (ob->type == OB_LAMP) {
+ Lamp *la= ob->data;
+ if(la->type==LA_SPOT) {
+ short nr= pupmenu("Lamp Tools%t|Spot Size%x1|Distance%x2|Clip Start%x3|Clip End%x4");
+ if(nr>0)
+ spot_interactive(ob, nr);
+ }
+ }
else if (ob->type == OB_FONT) {
/* removed until this gets a decent implementation (ton) */
/* nr= pupmenu("Split %t|Characters%x1");
@@ -2328,7 +2571,44 @@ void special_editmenu(void)
}
}
else if(G.obedit->type==OB_MESH) {
-
+ /* This is all that is needed, since all other functionality is in Ctrl+ V/E/F but some users didnt like, so for now have the old/big menu */
+ /*
+ nr= pupmenu("Subdivide Mesh%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x4");
+ switch(nr) {
+ case 1:
+ waitcursor(1);
+ esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, 1, 0);
+
+ BIF_undo_push("ESubdivide Single");
+ break;
+ case 2:
+ if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+ waitcursor(1);
+ esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, numcuts, 0);
+ BIF_undo_push("ESubdivide");
+ break;
+ case 3:
+ if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+ randfac= 10;
+ if(button(&randfac, 1, 100, "Rand fac:")==0) return;
+ waitcursor(1);
+ fac= -( (float)randfac )/100;
+ esubdivideflag(1, fac, G.scene->toolsettings->editbutflag, numcuts, 0);
+ BIF_undo_push("Subdivide Fractal");
+ break;
+
+ case 4:
+ fac= 1.0f;
+ if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return;
+ fac= 0.292f*fac;
+
+ waitcursor(1);
+ esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
+ BIF_undo_push("Subdivide Smooth");
+ break;
+ }
+ */
+
nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15|Blend From Shape%x16|Propagate To All Shapes%x17|Select Vertex Path%x18");
switch(nr) {
@@ -2364,12 +2644,12 @@ void special_editmenu(void)
esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
BIF_undo_push("Subdivide Smooth");
break;
-
+
case 4:
mergemenu();
break;
case 5:
- notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit));
+ notice("Removed %d Vertices", removedoublesflag(1, 0, G.scene->toolsettings->doublimit));
BIF_undo_push("Remove Doubles");
break;
case 6:
@@ -2409,6 +2689,7 @@ void special_editmenu(void)
break;
}
+
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
if(nr>0) waitcursor(0);
@@ -2416,7 +2697,7 @@ void special_editmenu(void)
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
- nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4");
+ nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5");
switch(nr) {
case 1:
@@ -2426,75 +2707,31 @@ void special_editmenu(void)
switchdirectionNurb2();
break;
case 3:
- {
- static float weight= 1.0f;
- extern ListBase editNurb;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
- for(nu= editNurb.first; nu; nu= nu->next) {
- if(nu->bezt) {
- for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
- if(bezt->f2 & SELECT)
- bezt->weight= weight;
- }
- }
- else if(nu->bp) {
- for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
- if(bp->f1 & SELECT)
- bp->weight= weight;
- }
- }
- }
- }
- }
+ setweightNurb();
break;
case 4:
- {
- static float radius= 1.0f;
- extern ListBase editNurb;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- if(fbutton(&radius, 0.0001f, 10.0f, 10, 10, "Set Radius")) {
- for(nu= editNurb.first; nu; nu= nu->next) {
- if(nu->bezt) {
- for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
- if(bezt->f2 & SELECT)
- bezt->radius= radius;
- }
- }
- else if(nu->bp) {
- for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
- if(bp->f1 & SELECT)
- bp->radius= radius;
- }
- }
- }
- }
-
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSALL, 0);
- allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
-
- }
+ setradiusNurb();
+ break;
+ case 5:
+ smoothradiusNurb();
break;
}
-
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
else if(G.obedit->type==OB_ARMATURE) {
- nr= pupmenu("Specials%t|Subdivide %x1|Flip Left-Right Names%x2");
+ nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
if(nr==1)
- subdivide_armature();
- else if(nr==2)
+ subdivide_armature(1);
+ if(nr==2) {
+ if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+ waitcursor(1);
+ subdivide_armature(numcuts);
+ }
+ else if(nr==3)
armature_flip_names();
+ else if(ELEM3(nr, 4, 5, 6)) {
+ armature_autoside_names(nr-4);
+ }
}
else if(G.obedit->type==OB_LATTICE) {
static float weight= 1.0f;
@@ -2759,48 +2996,88 @@ void convertmenu(void)
DAG_scene_sort(G.scene);
}
- /* Change subdivision properties of mesh object ob, if
- * level==-1 then toggle subsurf, else set to level.
- * *set allows to toggle multiple selections
- */
-static void object_flip_subdivison(Object *ob, int *set, int level, int mode)
+/* Change subdivision or particle properties of mesh object ob, if level==-1
+ * then toggle subsurf, else set to level set allows to toggle multiple
+ * selections */
+
+static void object_has_subdivision_particles(Object *ob, int *havesubdiv, int *havepart, int depth)
+{
+ if(ob->type==OB_MESH) {
+ if(modifiers_findByType(ob, eModifierType_Subsurf))
+ *havesubdiv= 1;
+ if(modifiers_findByType(ob, eModifierType_ParticleSystem))
+ *havepart= 1;
+ }
+
+ if(ob->dup_group && depth <= 4) {
+ GroupObject *go;
+
+ for(go= ob->dup_group->gobject.first; go; go= go->next)
+ object_has_subdivision_particles(go->ob, havesubdiv, havepart, depth+1);
+ }
+}
+
+static void object_flip_subdivison_particles(Object *ob, int *set, int level, int mode, int particles, int depth)
{
ModifierData *md;
- if(ob->type!=OB_MESH)
- return;
-
- md = modifiers_findByType(ob, eModifierType_Subsurf);
-
- if (md) {
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
+ if(ob->type==OB_MESH) {
+ if(particles) {
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData*)md;
+
+ if(*set == -1)
+ *set= psmd->modifier.mode&(mode);
- if (level == -1) {
- if(*set == -1)
- *set= smd->modifier.mode&(mode);
-
- if (*set) {
- smd->modifier.mode &= ~(mode);
- } else {
- smd->modifier.mode |= (mode);
+ if (*set)
+ psmd->modifier.mode &= ~(mode);
+ else
+ psmd->modifier.mode |= (mode);
+ }
}
- } else {
- smd->levels = level;
}
- }
- else if(*set != 0) {
- SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
+ else {
+ md = modifiers_findByType(ob, eModifierType_Subsurf);
+
+ if (md) {
+ SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+ if (level == -1) {
+ if(*set == -1)
+ *set= smd->modifier.mode&(mode);
+
+ if (*set)
+ smd->modifier.mode &= ~(mode);
+ else
+ smd->modifier.mode |= (mode);
+ } else {
+ smd->levels = level;
+ }
+ }
+ else if(depth == 0 && *set != 0) {
+ SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
- BLI_addtail(&ob->modifiers, smd);
+ BLI_addtail(&ob->modifiers, smd);
- if (level!=-1) {
- smd->levels = level;
+ if (level!=-1) {
+ smd->levels = level;
+ }
+
+ if(*set == -1)
+ *set= 1;
+ }
}
-
- if(*set == -1)
- *set= 1;
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+
+ if(ob->dup_group && depth<=4) {
+ GroupObject *go;
+
+ for(go= ob->dup_group->gobject.first; go; go= go->next)
+ object_flip_subdivison_particles(go->ob, set, level, mode, particles, depth+1);
}
- ob->recalc |= OB_RECALC_DATA;
}
/* Change subdivision properties of mesh object ob, if
@@ -2811,23 +3088,34 @@ void flip_subdivison(int level)
{
Base *base;
int set= -1;
- int mode;
+ int mode, pupmode, particles= 0, havesubdiv= 0, havepart= 0;
if(G.qual & LR_ALTKEY)
mode= eModifierMode_Realtime;
else
mode= eModifierMode_Render|eModifierMode_Realtime;
- for(base= G.scene->base.first; base; base= base->next) {
- if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base))) {
- object_flip_subdivison(base->object, &set, level, mode);
- if(base->object->dup_group) {
- GroupObject *go;
- for(go= base->object->dup_group->gobject.first; go; go= go->next)
- object_flip_subdivison(go->ob, &set, level, mode);
- }
- }
+ if(level == -1) {
+ for(base= G.scene->base.first; base; base= base->next)
+ if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base)))
+ object_has_subdivision_particles(base->object, &havesubdiv, &havepart, 0);
+ }
+ else
+ havesubdiv= 1;
+
+ if(havesubdiv && havepart) {
+ pupmode= pupmenu("Switch%t|Subsurf %x1|Particle Systems %x2");
+ if(pupmode <= 0)
+ return;
+ else if(pupmode == 2)
+ particles= 1;
}
+ else if(havepart)
+ particles= 1;
+
+ for(base= G.scene->base.first; base; base= base->next)
+ if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base)))
+ object_flip_subdivison_particles(base->object, &set, level, mode, particles, 0);
countall();
allqueue(REDRAWVIEW3D, 0);
@@ -2836,7 +3124,10 @@ void flip_subdivison(int level)
allqueue(REDRAWBUTSOBJECT, 0);
DAG_scene_flush_update(G.scene, screen_view3d_layers());
- BIF_undo_push("Switch subsurf on/off");
+ if(particles)
+ BIF_undo_push("Switch particles on/off");
+ else
+ BIF_undo_push("Switch subsurf on/off");
}
static void copymenu_properties(Object *ob)
@@ -2953,7 +3244,7 @@ static void copymenu_modifiers(Object *ob)
for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
ModifierTypeInfo *mti = modifierType_getInfo(i);
- if (ELEM(i, eModifierType_Hook, eModifierType_Softbody)) continue;
+ if(ELEM3(i, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue;
if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
(ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@ -2983,6 +3274,9 @@ static void copymenu_modifiers(Object *ob)
BLI_addtail(&base->object->modifiers, nmd);
}
}
+
+ copy_object_particlesystems(base->object, ob);
+ copy_object_softbody(base->object, ob);
} else {
/* copy specific types */
ModifierData *md, *mdn;
@@ -3006,6 +3300,15 @@ static void copymenu_modifiers(Object *ob)
modifier_copyData(md, mdn);
}
}
+
+ if(event == eModifierType_ParticleSystem) {
+ object_free_particlesystems(base->object);
+ copy_object_particlesystems(base->object, ob);
+ }
+ else if(event == eModifierType_Softbody) {
+ object_free_softbody(base->object);
+ copy_object_softbody(base->object, ob);
+ }
}
}
else
@@ -3316,6 +3619,9 @@ void copy_attr(short event)
else if(event==29) { /* protected bits */
base->object->protectflag= ob->protectflag;
}
+ else if(event==30) { /* index object */
+ base->object->index= ob->index;
+ }
}
}
base= base->next;
@@ -3334,101 +3640,60 @@ void copy_attr(short event)
BIF_undo_push("Copy Attributes");
}
-void copy_attr_tface(short event)
-{
- /* Face Select Mode */
- Object *ob= OBACT;
- Mesh *me= get_mesh(ob);
- MTFace *tface;
- MFace *mface;
- MCol *activemcol;
- MTFace *activetf= get_active_tface(&activemcol);
- int a;
-
- if(activetf==NULL) return;
-
- tface= me->mtface;
- mface= me->mface;
- for(a=0; a<me->totface; a++, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- switch(event) {
- case 1:
- tface->tpage = activetf->tpage;
- tface->tile= activetf->tile;
- tface->mode |= TF_TEX;
- break;
- case 2:
- memcpy(tface->uv, activetf->uv, sizeof(tface->uv)); break;
- case 3:
- if(activemcol)
- memcpy(&me->mcol[a*4], activemcol, sizeof(MCol)*4); break;
- case 4:
- tface->mode = activetf->mode; break;
- case 5:
- tface->transp= activetf->transp; break;
- }
- }
- }
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
- BIF_undo_push("Copy texture face");
-}
-
void copy_attr_menu()
{
Object *ob;
short event;
+ char str[512];
if(!(ob=OBACT)) return;
- if ((G.obedit)) return; /* no editmode copy yet */
+ if (G.obedit) {
+ if (ob->type == OB_MESH)
+ mesh_copy_menu();
+ return;
+ }
- if(G.f & G_FACESELECT) {
- event= pupmenu("Copy Active Texface%t|Image%x1|UV Coords%x2|Color%x3|Mode%x4|Transp%x5");
- copy_attr_tface(event);
+ /* Object Mode */
- } else { /* Object Mode */
-
- /* If you change this menu, don't forget to update the menu in header_view3d.c
- * view3d_edit_object_copyattrmenu() and in toolbox.c
- */
-
- char str[512];
-
- strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Drawtype%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
-
- strcat (str, "|Object Constraints%x22");
- strcat (str, "|NLA Strips%x26");
-
- if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) {
- strcat(str, "|Texture Space%x17");
- }
-
- if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19");
- if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28");
-
- if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
- strcat(str, "|Curve Resolution%x25");
- }
-
- if(ob->type==OB_MESH){
- strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27");
- }
+ /* If you change this menu, don't forget to update the menu in header_view3d.c
+ * view3d_edit_object_copyattrmenu() and in toolbox.c
+ */
+
+ strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
+
+ strcat (str, "|Object Constraints%x22");
+ strcat (str, "|NLA Strips%x26");
+
+ if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) {
+ strcat(str, "|Texture Space%x17");
+ }
+
+ if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19");
+ if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28");
+
+ if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
+ strcat(str, "|Curve Resolution%x25");
+ }
- if( give_parteff(ob) ) strcat(str, "|Particle Settings%x20");
+ if(ob->type==OB_MESH){
+ strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27");
+ }
- if(ob->soft) strcat(str, "|Soft Body Settings%x23");
-
- if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){
- strcat(str, "|Modifiers ...%x24");
- }
+ if( give_parteff(ob) ) strcat(str, "|Particle Settings%x20");
- event= pupmenu(str);
- if(event<= 0) return;
-
- copy_attr(event);
+ if(ob->soft) strcat(str, "|Soft Body Settings%x23");
+
+ strcat(str, "|Pass Index%x30");
+
+ if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){
+ strcat(str, "|Modifiers ...%x24");
}
+
+ event= pupmenu(str);
+ if(event<= 0) return;
+
+ copy_attr(event);
}
@@ -3512,7 +3777,7 @@ void make_links(short event)
return;
}
else {
- event= pupmenu(strp);
+ event= pupmenu_col(strp, 20);
MEM_freeN(strp);
if(event<= 0) return;
@@ -3618,10 +3883,11 @@ void make_links(short event)
BIF_undo_push("Create links");
}
-void apply_object()
+void apply_objects_locrot( void )
{
Base *base, *basact;
Object *ob;
+ bArmature *arm;
Mesh *me;
Curve *cu;
Nurb *nu;
@@ -3629,49 +3895,59 @@ void apply_object()
BezTriple *bezt;
MVert *mvert;
float mat[3][3];
- int a;
-
- if(G.scene->id.lib) return;
- if(G.obedit) return;
- basact= BASACT;
+ int a, change = 0;
- if(G.qual & LR_SHIFTKEY) {
- ob= OBACT;
- if(ob==0) return;
-
- if(ob->transflag & OB_DUPLI) {
- make_duplilist_real();
- }
- else {
- if(okee("Apply deformation")) {
- object_apply_deform(ob);
- BIF_undo_push("Apply deformation");
- }
- }
- allqueue(REDRAWVIEW3D, 0);
-
- return;
- }
-
- if(okee("Apply scale and rotation")==0) return;
-
- base= FIRSTBASE;
- while(base) {
+ /* first check if we can execute */
+ for (base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
ob= base->object;
-
if(ob->type==OB_MESH) {
- object_to_mat3(ob, mat);
me= ob->data;
if(me->id.us>1) {
- error("Can't apply to a multi user mesh");
+ error("Can't apply to a multi user mesh, doing nothing.");
return;
}
if(me->key) {
- error("Can't apply to a mesh with vertex keys");
+ error("Can't apply to a mesh with vertex keys, doing nothing.");
+ return;
+ }
+ }
+ else if (ob->type==OB_ARMATURE) {
+ arm= ob->data;
+
+ if(arm->id.us>1) {
+ error("Can't apply to a multi user armature, doing nothing.");
+ return;
+ }
+ }
+ else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+ cu= ob->data;
+
+ if(cu->id.us>1) {
+ error("Can't apply to a multi user curve, doing nothing.");
+ return;
+ }
+ if(cu->key) {
+ error("Can't apply to a curve with vertex keys, doing nothing.");
return;
}
+ }
+ }
+ }
+
+ /* now execute */
+ basact= BASACT;
+ base= FIRSTBASE;
+ for (base= FIRSTBASE; base; base= base->next) {
+ if TESTBASELIB(base) {
+ ob= base->object;
+
+ if(ob->type==OB_MESH) {
+ object_to_mat3(ob, mat);
+ me= ob->data;
+
+ /* see checks above */
mvert= me->mvert;
for(a=0; a<me->totvert; a++, mvert++) {
@@ -3688,39 +3964,33 @@ void apply_object()
enter_editmode(EM_WAITCURSOR);
BIF_undo_push("Applied object"); /* editmode undo itself */
exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
- BASACT= basact;
+ BASACT= basact;
+ change = 1;
}
- else if (ob->type==OB_ARMATURE){
- bArmature *arm;
-
+ else if (ob->type==OB_ARMATURE) {
object_to_mat3(ob, mat);
arm= ob->data;
- if(arm->id.us>1) {
- error("Can't apply to a multi user armature");
- return;
- }
-
- apply_rot_armature (ob, mat);
+
+ /* see checks above */
+ apply_rot_armature(ob, mat);
+
/* Reset the object's transforms */
ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
QuatOne(ob->quat);
where_is_object(ob);
+
+ change = 1;
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+ float scale;
object_to_mat3(ob, mat);
+ scale = Mat3ToScalef(mat);
cu= ob->data;
- if(cu->id.us>1) {
- error("Can't apply to a multi user curve");
- return;
- }
- if(cu->key) {
- error("Can't apply to a curve with vertex keys");
- return;
- }
+ /* see checks above */
nu= cu->nurb.first;
while(nu) {
@@ -3731,6 +4001,7 @@ void apply_object()
Mat3MulVecfl(mat, bezt->vec[0]);
Mat3MulVecfl(mat, bezt->vec[1]);
Mat3MulVecfl(mat, bezt->vec[2]);
+ bezt->radius *= scale;
bezt++;
}
}
@@ -3757,13 +4028,75 @@ void apply_object()
BIF_undo_push("Applied object"); /* editmode undo itself */
exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
BASACT= basact;
+
+ change = 1;
}
}
- base= base->next;
}
+ if (change) {
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Apply Objects Scale & Rotation");
+ }
+}
+
+void apply_objects_visual_tx( void )
+{
+ Base *base;
+ Object *ob;
+ int change = 0;
- allqueue(REDRAWVIEW3D, 0);
- BIF_undo_push("Apply object");
+ for (base= FIRSTBASE; base; base= base->next) {
+ if TESTBASELIB(base) {
+ ob= base->object;
+ where_is_object(ob);
+ VECCOPY(ob->loc, ob->obmat[3]);
+ Mat4ToSize(ob->obmat, ob->size);
+ Mat4ToEul(ob->obmat, ob->rot);
+
+ where_is_object(ob);
+
+ change = 1;
+ }
+ }
+ if (change) {
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Apply Objects Visual Transform");
+ }
+}
+
+void apply_object( void )
+{
+ Object *ob;
+ int evt;
+ if(G.scene->id.lib) return;
+ if(G.obedit) return;
+
+ if(G.qual & LR_SHIFTKEY) {
+ ob= OBACT;
+ if(ob==0) return;
+
+ if(ob->transflag & OB_DUPLI) {
+ make_duplilist_real();
+ }
+ else {
+ if(okee("Apply deformation")) {
+ object_apply_deform(ob);
+ BIF_undo_push("Apply deformation");
+ }
+ }
+ allqueue(REDRAWVIEW3D, 0);
+
+ } else {
+
+ evt = pupmenu("Apply Object%t|Scale and Rotation to ObData|Visual Transform to Objects Loc/Scale/Rot");
+ if (evt==-1) return;
+
+ if (evt==1) {
+ apply_objects_locrot();
+ } else if (evt==2) {
+ apply_objects_visual_tx();
+ }
+ }
}
@@ -3907,6 +4240,7 @@ void std_rmouse_transform(void (*xf_func)(int, int))
short xo, yo;
short timer=0;
short mousebut;
+ short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
/* check for left mouse select/right mouse select */
@@ -3920,20 +4254,16 @@ void std_rmouse_transform(void (*xf_func)(int, int))
getmouseco_areawin(mval);
xo= mval[0];
yo= mval[1];
-
+
while(get_mbut() & mousebut) {
getmouseco_areawin(mval);
if(abs(mval[0]-xo)+abs(mval[1]-yo) > 10) {
if(curarea->spacetype==SPACE_VIEW3D) {
-#ifdef TWEAK_MODE
- initTransform(TFM_TRANSLATION, CTX_TWEAK);
-#else
- initTransform(TFM_TRANSLATION, CTX_NONE);
-#endif
+ initTransform(TFM_TRANSLATION, context);
Transform();
}
else if(curarea->spacetype==SPACE_IMAGE) {
- initTransform(TFM_TRANSLATION, CTX_NONE);
+ initTransform(TFM_TRANSLATION, context);
Transform();
}
else if(xf_func)
@@ -4181,6 +4511,28 @@ void single_obdata_users(int flag)
}
}
+void single_ipo_users(int flag)
+{
+ Object *ob;
+ Base *base;
+ ID *id;
+
+ base= FIRSTBASE;
+ while(base) {
+ ob= base->object;
+ if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) {
+ ob->recalc= OB_RECALC_DATA;
+
+ id= (ID *)ob->ipo;
+ if(id && id->us>1 && id->lib==NULL) {
+ ob->ipo= copy_ipo(ob->ipo);
+ id->us--;
+ ipo_idnew(ob->ipo); /* drivers */
+ }
+ }
+ base= base->next;
+ }
+}
void single_mat_users(int flag)
{
@@ -4361,7 +4713,7 @@ void single_user(void)
clear_id_newpoins();
- nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex");
+ nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex|Ipos");
if(nr>0) {
if(nr==1) single_object_users(1);
@@ -4379,6 +4731,10 @@ void single_user(void)
else if(nr==4) {
single_mat_users(1);
}
+ else if(nr==5) {
+ single_ipo_users(1);
+ }
+
clear_id_newpoins();
@@ -4452,8 +4808,8 @@ void make_local(int mode)
base= FIRSTBASE;
while(base) {
- ob= base->object;
- if( (base->flag & SELECT)) {
+ if( TESTBASE(base) ) {
+ ob= base->object;
if(ob->id.lib) {
make_local_object(ob);
}
@@ -4464,8 +4820,8 @@ void make_local(int mode)
/* maybe object pointers */
base= FIRSTBASE;
while(base) {
- ob= base->object;
- if( (base->flag & SELECT)) {
+ if( TESTBASE(base) ) {
+ ob= base->object;
if(ob->id.lib==NULL) {
ID_NEW(ob->parent);
ID_NEW(ob->track);
@@ -4476,9 +4832,8 @@ void make_local(int mode)
base= FIRSTBASE;
while(base) {
- ob= base->object;
- if( (base->flag & SELECT) ) {
-
+ if( TESTBASE(base) ) {
+ ob= base->object;
id= ob->data;
if(id && mode>1) {
@@ -4538,9 +4893,8 @@ void make_local(int mode)
if(mode>1) {
base= FIRSTBASE;
while(base) {
- ob= base->object;
- if(base->flag & SELECT ) {
-
+ if( TESTBASE(base) ) {
+ ob= base->object;
if(ob->type==OB_LAMP) {
la= ob->data;
for(b=0; b<MAX_MTEX; b++) {
@@ -4792,6 +5146,11 @@ void adduplicate(int mode, int dupflag)
ID_NEW_US2( obn->data )
else {
obn->data= copy_mesh(obn->data);
+
+ if(obn->fluidsimSettings) {
+ obn->fluidsimSettings->orgMesh = (Mesh *)obn->data;
+ }
+
didit= 1;
}
id->us--;
@@ -4990,7 +5349,7 @@ void selectlinks_menu(void)
/* If you modify this menu, please remember to update view3d_select_linksmenu
* in header_view3d.c and the menu in toolbox.c
*/
- nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5");
+ nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5|ParticleSystem%x6");
if (nr <= 0) return;
@@ -5013,6 +5372,7 @@ void selectlinks(int nr)
* Current Material: 3
* Current Texture: 4
* DupliGroup: 5
+ * PSys: 6
*/
@@ -5038,6 +5398,9 @@ void selectlinks(int nr)
else if(nr==5) {
if(ob->dup_group==NULL) return;
}
+ else if(nr==6) {
+ if(ob->particlesystem.first==NULL) return;
+ }
else return;
base= FIRSTBASE;
@@ -5066,6 +5429,7 @@ void selectlinks(int nr)
if(tex==mat1->mtex[b]->tex) {
base->flag |= SELECT;
changed = 1;
+ break;
}
}
}
@@ -5078,6 +5442,25 @@ void selectlinks(int nr)
changed = 1;
}
}
+ else if(nr==6) {
+ /* loop through other, then actives particles*/
+ ParticleSystem *psys;
+ ParticleSystem *psys_act;
+
+ for(psys=base->object->particlesystem.first; psys; psys=psys->next) {
+ for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) {
+ if (psys->part == psys_act->part) {
+ base->flag |= SELECT;
+ changed = 1;
+ break;
+ }
+ }
+
+ if (base->flag & SELECT) {
+ break;
+ }
+ }
+ }
base->object->flag= base->flag;
}
base= base->next;
@@ -5184,18 +5567,17 @@ void set_ob_ipoflags(void)
}
else {
base->object->ipoflag &= ~OB_DRAWKEY;
+ if(base->object->ipo) base->object->ipo->showkey= 0;
}
}
base= base->next;
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
- if(set) {
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWACTION, 0);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- }
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWACTION, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
}
void select_select_keys(void)
@@ -5312,6 +5694,57 @@ void auto_timeoffs(void)
allqueue(REDRAWBUTSOBJECT, 0);
}
+void ofs_timeoffs(void)
+{
+ Base *base;
+ float offset=0.0f;
+
+ if(BASACT==0 || G.vd==NULL) return;
+
+ if(fbutton(&offset, -10000.0f, 10000.0f, 10, 10, "Offset")==0) return;
+
+ /* make array of all bases, xco yco (screen) */
+ base= FIRSTBASE;
+ while(base) {
+ if(TESTBASELIB(base)) {
+ base->object->sf += offset;
+ if (base->object->sf < -MAXFRAMEF) base->object->sf = -MAXFRAMEF;
+ else if (base->object->sf > MAXFRAMEF) base->object->sf = MAXFRAMEF;
+ }
+ base= base->next;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+}
+
+
+void rand_timeoffs(void)
+{
+ Base *base;
+ float rand=0.0f;
+
+ if(BASACT==0 || G.vd==NULL) return;
+
+ if(fbutton(&rand, 0.0f, 10000.0f, 10, 10, "Randomize")==0) return;
+
+ rand *= 2;
+
+ base= FIRSTBASE;
+ while(base) {
+ if(TESTBASELIB(base)) {
+ base->object->sf += (BLI_drand()-0.5) * rand;
+ if (base->object->sf < -MAXFRAMEF) base->object->sf = -MAXFRAMEF;
+ else if (base->object->sf > MAXFRAMEF) base->object->sf = MAXFRAMEF;
+ }
+ base= base->next;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+}
+
+
void texspace_edit(void)
{
Base *base;
@@ -5366,20 +5799,12 @@ void texspace_edit(void)
void mirrormenu(void)
{
- short mode = 0;
-
-
- if (G.obedit==0) {
- mode=pupmenu("Mirror Axis %t|X Local%x4|Y Local%x5|Z Local%x6|");
-
- if (mode==-1) return; /* return */
- Mirror(mode); /* separating functionality from interface | call*/
+ if(G.f & G_PARTICLEEDIT) {
+ PE_mirror_x(0);
}
else {
- mode=pupmenu("Mirror Axis %t|X Global%x1|Y Global%x2|Z Global%x3|%l|X Local%x4|Y Local%x5|Z Local%x6|%l|X View%x7|Y View%x8|Z View%x9|");
-
- if (mode==-1) return; /* return */
- Mirror(mode); /* separating functionality from interface | call*/
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
}
}
@@ -5454,6 +5879,18 @@ void hookmenu(void)
}
/*
+ * Returns true if the Object is a from an external blend file (libdata)
+ */
+int object_is_libdata(Object *ob)
+{
+ if (!ob) return 0;
+ if (ob->proxy) return 0;
+ if (ob->id.lib) return 1;
+ return 0;
+}
+
+
+/*
* Returns true if the Object data is a from an external blend file (libdata)
*/
int object_data_is_libdata(Object *ob)
@@ -5469,14 +5906,17 @@ int object_data_is_libdata(Object *ob)
void hide_objects(int select)
{
Base *base;
- int changed = 0;
+ short changed = 0, changed_act = 0;
for(base = FIRSTBASE; base; base=base->next){
if(TESTBASELIB(base)==select){
base->flag &= ~SELECT;
base->object->flag = base->flag;
base->object->restrictflag |= OB_RESTRICT_VIEW;
changed = 1;
- if (base==BASACT) BASACT= NULL;
+ if (base==BASACT) {
+ BASACT= NULL;
+ changed_act = 1;
+ }
}
}
if (changed) {
@@ -5485,6 +5925,12 @@ void hide_objects(int select)
DAG_scene_sort(G.scene);
allqueue(REDRAWVIEW3D,0);
allqueue(REDRAWOOPS,0);
+ allqueue(REDRAWDATASELECT,0);
+ if (changed_act) { /* these spaces depend on the active object */
+ allqueue(REDRAWBUTSALL,0);
+ allqueue(REDRAWIPO,0);
+ allqueue(REDRAWACTION,0);
+ }
countall();
}
}
diff --git a/source/blender/src/editparticle.c b/source/blender/src/editparticle.c
new file mode 100644
index 00000000000..d70b8620ae8
--- /dev/null
+++ b/source/blender/src/editparticle.c
@@ -0,0 +1,3193 @@
+/* editparticle.c
+ *
+ *
+ * $Id: editparticle.c $
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_types.h"
+#include "DNA_vec_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_bad_level_calls.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_depsgraph.h"
+
+#include "BKE_global.h"
+#include "BKE_object.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_particle.h"
+#include "BKE_scene.h"
+#include "BKE_utildefines.h"
+
+#include "BSE_edit.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
+#include "BLI_kdtree.h"
+#include "BLI_rand.h"
+
+#include "PIL_time.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_graphics.h"
+#include "BIF_editparticle.h"
+#include "BIF_editview.h"
+#include "BIF_interface.h"
+#include "BIF_meshtools.h"
+#include "BIF_mywindow.h"
+#include "BIF_radialcontrol.h"
+#include "BIF_resources.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_toolbox.h"
+
+#include "BSE_view.h"
+
+#include "BDR_editobject.h" //rightmouse_transform()
+#include "BDR_drawobject.h"
+
+#include "blendef.h"
+#include "mydevice.h"
+
+static void ParticleUndo_clear(ParticleSystem *psys);
+
+#define LOOP_PARTICLES(i,pa) for(i=0, pa=psys->particles; i<totpart; i++, pa++)
+#define LOOP_KEYS(k,key) if(psys->edit)for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++)
+
+void PE_free_particle_edit(ParticleSystem *psys)
+{
+ ParticleEdit *edit=psys->edit;
+ int i, totpart=psys->totpart;
+
+ if(edit==0) return;
+
+ ParticleUndo_clear(psys);
+
+ if(edit->keys){
+ for(i=0; i<totpart; i++){
+ if(edit->keys[i])
+ MEM_freeN(edit->keys[i]);
+ }
+ MEM_freeN(edit->keys);
+ }
+
+ if(edit->mirror_cache)
+ MEM_freeN(edit->mirror_cache);
+
+ if(edit->emitter_cosnos){
+ MEM_freeN(edit->emitter_cosnos);
+ edit->emitter_cosnos=0;
+ }
+
+ if(edit->emitter_field){
+ BLI_kdtree_free(edit->emitter_field);
+ edit->emitter_field=0;
+ }
+
+ MEM_freeN(edit);
+
+ psys->edit=NULL;
+}
+/************************************************/
+/* Edit Mode Helpers */
+/************************************************/
+int PE_can_edit(ParticleSystem *psys)
+{
+ return (psys && psys->edit && (G.f & G_PARTICLEEDIT));
+}
+
+ParticleEditSettings *PE_settings()
+{
+ return &G.scene->toolsettings->particle;
+}
+
+void PE_change_act(void *ob_v, void *act_v)
+{
+ Object *ob = ob_v;
+ ParticleSystem *psys;
+ short act = *((short*)act_v) - 1;
+
+ if((psys=psys_get_current(ob)))
+ psys->flag &= ~PSYS_CURRENT;
+
+ if(act>=0){
+ if((psys=BLI_findlink(&ob->particlesystem,act))) {
+ psys->flag |= PSYS_CURRENT;
+
+ if(psys_check_enabled(ob, psys)) {
+ if(G.f & G_PARTICLEEDIT && !psys->edit)
+ PE_create_particle_edit(ob, psys);
+ PE_recalc_world_cos(ob, psys);
+ }
+ }
+ }
+}
+
+/* always gets atleast the first particlesystem even if PSYS_CURRENT flag is not set */
+ParticleSystem *PE_get_current(Object *ob)
+{
+ ParticleSystem *psys;
+
+ if(ob==NULL)
+ return NULL;
+
+ psys= ob->particlesystem.first;
+ while(psys){
+ if(psys->flag & PSYS_CURRENT)
+ break;
+ psys=psys->next;
+ }
+
+ if(psys==NULL && ob->particlesystem.first){
+ psys=ob->particlesystem.first;
+ psys->flag |= PSYS_CURRENT;
+ }
+
+ if(psys && psys_check_enabled(ob, psys) && ob == OBACT && (G.f & G_PARTICLEEDIT))
+ if(psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED)
+ if(psys->edit == NULL)
+ PE_create_particle_edit(ob, psys);
+
+ return psys;
+}
+/* returns -1 if no system has PSYS_CURRENT flag */
+short PE_get_current_num(Object *ob)
+{
+ short num=0;
+ ParticleSystem *psys = ob->particlesystem.first;
+
+ while(psys){
+ if(psys->flag & PSYS_CURRENT)
+ return num;
+ num++;
+ psys=psys->next;
+ }
+
+ return -1;
+}
+
+void PE_hide_keys_time(ParticleSystem *psys, float cfra)
+{
+ ParticleData *pa;
+ ParticleEditKey *key;
+ ParticleEditSettings *pset=PE_settings();
+ int i,k,totpart=psys->totpart;
+
+ if(pset->draw_timed && G.scene->selectmode==SCE_SELECT_POINT){
+ LOOP_PARTICLES(i,pa){
+ LOOP_KEYS(k,key){
+ if(fabs(cfra-*key->time) < pset->draw_timed)
+ key->flag &= ~PEK_HIDE;
+ else{
+ key->flag |= PEK_HIDE;
+ key->flag &= ~PEK_SELECT;
+ }
+ }
+ }
+ }
+ else{
+ LOOP_PARTICLES(i,pa){
+ LOOP_KEYS(k,key){
+ key->flag &= ~PEK_HIDE;
+ }
+ }
+ }
+}
+
+static int key_inside_circle(short mco[2], float rad, float co[3], float *distance)
+{
+ float dx,dy,dist;
+ short vertco[2];
+
+ project_short(co,vertco);
+
+ if (vertco[0]==IS_CLIPPED)
+ return 0;
+
+ dx=(float)(mco[0]-vertco[0]);
+ dy=(float)(mco[1]-vertco[1]);
+ dist=(float)sqrt((double)(dx*dx + dy*dy));
+
+ if(dist<=rad){
+ if(distance) *distance=dist;
+ return 1;
+ }
+ else
+ return 0;
+}
+static int key_inside_rect(rcti *rect, float co[3])
+{
+ short vertco[2];
+
+ project_short(co,vertco);
+
+ if (vertco[0]==IS_CLIPPED)
+ return 0;
+
+ if(vertco[0] > rect->xmin && vertco[0] < rect->xmax &&
+ vertco[1] > rect->ymin && vertco[1] < rect->ymax)
+ return 1;
+ else
+ return 0;
+}
+static int test_key_depth(float *co, bglMats *mats){
+ double ux, uy, uz;
+ float depth;
+ short wco[3], x,y;
+
+ if((G.vd->flag & V3D_ZBUF_SELECT)==0) return 1;
+
+ gluProject(co[0],co[1],co[2], mats->modelview, mats->projection,
+ (GLint *)mats->viewport, &ux, &uy, &uz );
+
+ project_short(co,wco);
+
+ if (wco[0]==IS_CLIPPED)
+ return 0;
+
+ x=wco[0];
+ y=wco[1];
+
+ if(G.vd->depths && x<G.vd->depths->w && y<G.vd->depths->h){
+ if((float)uz>G.vd->depths->depths[y*G.vd->depths->w+x])
+ return 0;
+ else
+ return 1;
+ }
+ else{
+ x+= (short)curarea->winrct.xmin;
+ y+= (short)curarea->winrct.ymin;
+
+ glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
+
+ if((float)uz>depth)
+ return 0;
+ else
+ return 1;
+ }
+}
+
+static int particle_is_selected(ParticleSystem *psys, ParticleData *pa)
+{
+ ParticleEditKey *key;
+ int sel, i, k;
+
+ if(pa->flag&PARS_HIDE) return 0;
+
+ sel=0;
+ i= pa - psys->particles;
+ LOOP_KEYS(k,key)
+ if(key->flag&PEK_SELECT)
+ return 1;
+
+ return 0;
+}
+
+/*-----iterators over editable particles-----*/
+static void for_mouse_hit_keys(int nearest, ParticleSystem *psys, void (*func)(ParticleSystem *psys, int pa_index, int key_index, void *userData), void *userData){
+ /* these are allways the first in this userData */
+ struct { short *mval; float rad; rcti *rect;} *data = userData;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ bglMats mats;
+ int i,k, totpart, nearest_pa=-1, nearest_key=-1;
+ float dist=data->rad;
+
+ if(psys==0 || G.scene->selectmode==SCE_SELECT_PATH) return;
+
+ totpart=psys->totpart;
+
+ bgl_get_mats(&mats);
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+
+ if(G.scene->selectmode==SCE_SELECT_END){
+ key=psys->edit->keys[i]+pa->totkey-1;
+
+ if(nearest){
+ if(key_inside_circle(data->mval,dist,key->world_co,&dist) && test_key_depth(key->world_co,&mats)){
+ nearest_pa=i;
+ nearest_key=pa->totkey-1;
+ }
+ }
+ else if(((data->mval)?
+ key_inside_circle(data->mval,data->rad,key->world_co,0):
+ key_inside_rect(data->rect,key->world_co)) && test_key_depth(key->world_co,&mats))
+ func(psys,i,pa->totkey-1,userData);
+ }
+ else{
+ key=psys->edit->keys[i];
+
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_HIDE) continue;
+
+ if(nearest){
+ if(key_inside_circle(data->mval,dist,key->world_co,&dist) && test_key_depth(key->world_co,&mats)){
+ nearest_pa=i;
+ nearest_key=k;
+ }
+ }
+ else if(((data->mval)?
+ key_inside_circle(data->mval,data->rad,key->world_co,0):
+ key_inside_rect(data->rect,key->world_co)) && test_key_depth(key->world_co,&mats))
+ func(psys,i,k,userData);
+ }
+ }
+ }
+ if(nearest && nearest_pa>-1){
+ func(psys,nearest_pa,nearest_key,userData);
+ }
+}
+static void foreach_mouse_hit_element(int selected, ParticleSystem *psys,void (*func)(ParticleSystem *psys, int index, void *userData), void *userData){
+ /* these are allways the first in this userData */
+ struct { short *mval; float rad; rcti* rect; float dist;} *data = userData;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ bglMats mats;
+ int i,k, totpart;
+
+ if(psys==0) return;
+
+ totpart=psys->totpart;
+
+ bgl_get_mats(&mats);
+
+ if(G.scene->selectmode==SCE_SELECT_PATH)
+ selected=0;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+
+ if(G.scene->selectmode==SCE_SELECT_END){
+ key=psys->edit->keys[i]+pa->totkey-1;
+ if(key_inside_circle(data->mval,data->rad,key->world_co,&data->dist) && (selected==0 || key->flag&PEK_SELECT) && test_key_depth(key->world_co,&mats))
+ func(psys,i,userData);
+ }
+ else{
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_HIDE) continue;
+
+ if(key_inside_circle(data->mval,data->rad,key->world_co,&data->dist) && (selected==0 || key->flag&PEK_SELECT) && test_key_depth(key->world_co,&mats)){
+ func(psys,i,userData);
+ break;
+ }
+ }
+ }
+ }
+}
+static void foreach_mouse_hit_key(int selected, ParticleSystem *psys,void (*func)(ParticleSystem *psys, float mat[][4], float imat[][4], int bel_index, int key_index, void *userData), void *userData){
+ /* these are allways the first in this userData */
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist;} *data = userData;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ ParticleSystemModifierData *psmd=0;
+ bglMats mats;
+ int i,k, totpart;
+ float mat[4][4], imat[4][4];
+
+ if(psys==0) return;
+
+ psmd=psys_get_modifier(data->ob,psys);
+
+ totpart=psys->totpart;
+
+ bgl_get_mats(&mats);
+
+ if(G.scene->selectmode==SCE_SELECT_PATH)
+ selected=0;
+
+ Mat4One(imat);
+ Mat4One(mat);
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+
+ psys_mat_hair_to_global(data->ob, psmd->dm, psys->part->from, pa, mat);
+ //psys_geometry_mat(psmd->dm,pa,tmat);
+ //Mat4MulMat4(mat,tmat,data->ob->obmat);
+ Mat4Invert(imat,mat);
+
+ if(G.scene->selectmode==SCE_SELECT_END){
+ key=psys->edit->keys[i]+pa->totkey-1;
+ if(key_inside_circle(data->mval,data->rad,key->world_co,&data->dist) && (selected==0 || key->flag&PEK_SELECT) && test_key_depth(key->world_co,&mats))
+ func(psys,mat,imat,i,pa->totkey-1,userData);
+ }
+ else{
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_HIDE) continue;
+
+ if(key_inside_circle(data->mval,data->rad,key->world_co,&data->dist) && (selected==0 || key->flag&PEK_SELECT) && test_key_depth(key->world_co,&mats)){
+ func(psys,mat,imat,i,k,userData);
+ }
+ }
+ }
+ }
+}
+static void foreach_selected_element(ParticleSystem *psys, void (*func)(ParticleSystem *psys, int index, void *userData), void *userData){
+ ParticleData *pa;
+ int i,totpart;
+
+ if(psys==0) return;
+
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa)
+ if(particle_is_selected(psys, pa))
+ func(psys,i,userData);
+}
+static void foreach_selected_key(ParticleSystem *psys, void (*func)(ParticleSystem *psys, int pa_index, int key_index, void *userData), void *userData){
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i,k,totpart;
+
+ if(psys==0) return;
+
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag&PARS_HIDE) continue;
+
+ key=psys->edit->keys[i];
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_SELECT)
+ func(psys,i,k,userData);
+ }
+ }
+}
+void PE_foreach_element(ParticleSystem *psys, void (*func)(ParticleSystem *psys, int index, void *userData), void *userData)
+{
+ int i,totpart;
+
+ if(psys==0) return;
+
+ totpart=psys->totpart;
+
+ for(i=0; i<totpart; i++)
+ func(psys,i,userData);
+}
+static int count_selected_keys(ParticleSystem *psys)
+{
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i,k,totpart,sel=0;
+
+ if(psys==0) return 0;
+
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag&PARS_HIDE) continue;
+
+ key=psys->edit->keys[i];
+ if(G.scene->selectmode==SCE_SELECT_POINT){
+ for(k=0; k<pa->totkey; k++,key++){
+ if(key->flag&PEK_SELECT)
+ sel++;
+ }
+ }
+ else if(G.scene->selectmode==SCE_SELECT_END){
+ key+=pa->totkey-1;
+ if(key->flag&PEK_SELECT)
+ sel++;
+ }
+ }
+ return sel;
+}
+
+/************************************************/
+/* Particle Edit Mirroring */
+/************************************************/
+
+static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleSystemModifierData *psmd;
+ KDTree *tree;
+ KDTreeNearest nearest;
+ float mat[4][4], co[3];
+ int i, index, totpart;
+
+ edit= psys->edit;
+ psmd= psys_get_modifier(ob, psys);
+ totpart= psys->totpart;
+
+ tree= BLI_kdtree_new(totpart);
+
+ /* insert particles into kd tree */
+ LOOP_PARTICLES(i,pa) {
+ psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
+ VECCOPY(co, pa->hair[0].co);
+ Mat4MulVecfl(mat, co);
+ BLI_kdtree_insert(tree, i, co, NULL);
+ }
+
+ BLI_kdtree_balance(tree);
+
+ /* lookup particles and set in mirror cache */
+ if(!edit->mirror_cache)
+ edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache");
+
+ LOOP_PARTICLES(i,pa) {
+ psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat);
+ VECCOPY(co, pa->hair[0].co);
+ Mat4MulVecfl(mat, co);
+ co[0]= -co[0];
+
+ index= BLI_kdtree_find_nearest(tree, co, NULL, &nearest);
+
+ /* this needs a custom threshold still, duplicated for editmode mirror */
+ if(index != -1 && index != i && (nearest.dist <= 0.0002f))
+ edit->mirror_cache[i]= index;
+ else
+ edit->mirror_cache[i]= -1;
+ }
+
+ /* make sure mirrors are in two directions */
+ LOOP_PARTICLES(i,pa) {
+ if(edit->mirror_cache[i]) {
+ index= edit->mirror_cache[i];
+ if(edit->mirror_cache[index] != i)
+ edit->mirror_cache[i]= -1;
+ }
+ }
+
+ BLI_kdtree_free(tree);
+}
+
+static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
+{
+ HairKey *hkey, *mhkey;
+ ParticleEditKey *key, *mkey;
+ ParticleEdit *edit;
+ float mat[4][4], mmat[4][4], immat[4][4];
+ int i, mi, k;
+
+ edit= psys->edit;
+ i= pa - psys->particles;
+
+ /* find mirrored particle if needed */
+ if(!mpa) {
+ if(!edit->mirror_cache)
+ PE_update_mirror_cache(ob, psys);
+
+ mi= edit->mirror_cache[i];
+ if(mi == -1)
+ return;
+ mpa= psys->particles + mi;
+ }
+ else
+ mi= mpa - psys->particles;
+
+ /* make sure they have the same amount of keys */
+ if(pa->totkey != mpa->totkey) {
+ if(mpa->hair) MEM_freeN(mpa->hair);
+ if(edit->keys[mi]) MEM_freeN(edit->keys[mi]);
+
+ mpa->hair= MEM_dupallocN(pa->hair);
+ edit->keys[mi]= MEM_dupallocN(edit->keys[i]);
+ mpa->totkey= pa->totkey;
+
+ mhkey= mpa->hair;
+ mkey= edit->keys[mi];
+ for(k=0; k<mpa->totkey; k++, mkey++, mhkey++) {
+ mkey->co= mhkey->co;
+ mkey->time= &mhkey->time;
+ mkey->flag &= PEK_SELECT;
+ }
+ }
+
+ /* mirror positions and tags */
+ psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat);
+ psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat);
+ Mat4Invert(immat, mmat);
+
+ hkey=pa->hair;
+ mhkey=mpa->hair;
+ key= edit->keys[i];
+ mkey= edit->keys[mi];
+ for(k=0; k<pa->totkey; k++, hkey++, mhkey++, key++, mkey++) {
+ VECCOPY(mhkey->co, hkey->co);
+ Mat4MulVecfl(mat, mhkey->co);
+ mhkey->co[0]= -mhkey->co[0];
+ Mat4MulVecfl(immat, mhkey->co);
+
+ if(key->flag & PEK_TAG)
+ mkey->flag |= PEK_TAG;
+ }
+
+ if(pa->flag & PARS_TAG)
+ mpa->flag |= PARS_TAG;
+ if(pa->flag & PARS_EDIT_RECALC)
+ mpa->flag |= PARS_EDIT_RECALC;
+}
+
+static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleSystemModifierData *psmd;
+ int i, totpart;
+
+ edit= psys->edit;
+ psmd= psys_get_modifier(ob, psys);
+ totpart= psys->totpart;
+
+ /* we delay settings the PARS_EDIT_RECALC for mirrored particles
+ * to avoid doing mirror twice */
+ LOOP_PARTICLES(i,pa) {
+ if(pa->flag & PARS_EDIT_RECALC) {
+ PE_mirror_particle(ob, psmd->dm, psys, pa, NULL);
+
+ if(edit->mirror_cache[i] != -1)
+ psys->particles[edit->mirror_cache[i]].flag &= ~PARS_EDIT_RECALC;
+ }
+ }
+
+ LOOP_PARTICLES(i,pa)
+ if(pa->flag & PARS_EDIT_RECALC)
+ if(edit->mirror_cache[i] != -1)
+ psys->particles[edit->mirror_cache[i]].flag |= PARS_EDIT_RECALC;
+
+ edit->totkeys= psys_count_keys(psys);
+}
+
+/************************************************/
+/* Edit Calculation */
+/************************************************/
+/* tries to stop edited particles from going through the emitter's surface */
+static void PE_deflect_emitter(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ int i,k,totpart,index;
+ float *vec, *nor, dvec[3], dot, dist_1st;
+ float hairimat[4][4], hairmat[4][4];
+
+ if(psys==0)
+ return;
+
+ if((pset->flag & PE_DEFLECT_EMITTER)==0)
+ return;
+
+ edit=psys->edit;
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(!(pa->flag & PARS_EDIT_RECALC))
+ continue;
+
+ psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ LOOP_KEYS(k,key){
+ Mat4MulVecfl(hairmat, key->co);
+ }
+ //}
+
+ //LOOP_PARTICLES(i,pa){
+ key=psys->edit->keys[i]+1;
+
+ dist_1st=VecLenf((key-1)->co,key->co);
+ dist_1st*=0.75f*pset->emitterdist;
+
+ for(k=1; k<pa->totkey; k++, key++){
+ index= BLI_kdtree_find_nearest(edit->emitter_field,key->co,NULL,NULL);
+
+ vec=edit->emitter_cosnos +index*6;
+ nor=vec+3;
+
+ VecSubf(dvec, key->co, vec);
+
+ dot=Inpf(dvec,nor);
+ VECCOPY(dvec,nor);
+
+ if(dot>0.0f){
+ if(dot<dist_1st){
+ Normalize(dvec);
+ VecMulf(dvec,dist_1st-dot);
+ VecAddf(key->co,key->co,dvec);
+ }
+ }
+ else{
+ Normalize(dvec);
+ VecMulf(dvec,dist_1st-dot);
+ VecAddf(key->co,key->co,dvec);
+ }
+ if(k==1)
+ dist_1st*=1.3333f;
+ }
+ //}
+
+ //LOOP_PARTICLES(i,pa){
+
+ Mat4Invert(hairimat,hairmat);
+
+ LOOP_KEYS(k,key){
+ Mat4MulVecfl(hairimat, key->co);
+ }
+ }
+}
+/* force set distances between neighbouring keys */
+void PE_apply_lengths(ParticleSystem *psys)
+{
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ ParticleEditSettings *pset=PE_settings();
+ int i,k,totpart;
+ float dv1[3];
+
+ if(psys==0)
+ return;
+
+ if((pset->flag & PE_KEEP_LENGTHS)==0)
+ return;
+
+ edit=psys->edit;
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(!(pa->flag & PARS_EDIT_RECALC))
+ continue;
+
+ for(k=1, key=edit->keys[i] + 1; k<pa->totkey; k++, key++){
+ VecSubf(dv1, key->co, (key - 1)->co);
+ Normalize(dv1);
+ VecMulf(dv1, (key - 1)->length);
+ VecAddf(key->co, (key - 1)->co, dv1);
+ }
+ }
+}
+/* try to find a nice solution to keep distances between neighbouring keys */
+static void PE_iterate_lengths(ParticleSystem *psys)
+{
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ ParticleEditSettings *pset=PE_settings();
+ int i, j, k,totpart;
+ float tlen;
+ float dv0[3] = {0.0f, 0.0f, 0.0f};
+ float dv1[3] = {0.0f, 0.0f, 0.0f};
+ float dv2[3] = {0.0f, 0.0f, 0.0f};
+
+ if(psys==0)
+ return;
+
+ if((pset->flag & PE_KEEP_LENGTHS)==0)
+ return;
+
+ edit=psys->edit;
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(!(pa->flag & PARS_EDIT_RECALC))
+ continue;
+
+ for(j=1; j<pa->totkey; j++){
+ float mul = 1.0f / (float)pa->totkey;
+
+ if(pset->flag & PE_LOCK_FIRST){
+ key = edit->keys[i] + 1;
+ k = 1;
+ dv1[0] = dv1[1] = dv1[2] = 0.0;
+ }
+ else{
+ key = edit->keys[i];
+ k = 0;
+ dv0[0] = dv0[1] = dv0[2] = 0.0;
+ }
+
+ for(; k<pa->totkey; k++, key++){
+ if(k){
+ VecSubf(dv0, (key - 1)->co, key->co);
+ tlen = Normalize(dv0);
+ VecMulf(dv0, (mul * (tlen - (key - 1)->length)));
+ }
+
+ if(k < pa->totkey - 1){
+ VecSubf(dv2, (key + 1)->co, key->co);
+ tlen = Normalize(dv2);
+ VecMulf(dv2, mul * (tlen - key->length));
+ }
+
+ if(k){
+ VecAddf((key-1)->co,(key-1)->co,dv1);
+ }
+
+ VECADD(dv1,dv0,dv2);
+ }
+ }
+ }
+}
+/* set current distances to be kept between neighbouting keys */
+static void recalc_lengths(ParticleSystem *psys)
+{
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i, k, totpart;
+
+ if(psys==0)
+ return;
+
+ totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ key = psys->edit->keys[i];
+ for(k=0; k<pa->totkey-1; k++, key++){
+ key->length = VecLenf(key->co, (key + 1)->co);
+ }
+ }
+}
+/* calculate and store key locations in world coordinates */
+void PE_recalc_world_cos(Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i, k, totpart;
+ float hairmat[4][4];
+
+ if(psys==0)
+ return;
+
+ totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ LOOP_KEYS(k,key){
+ VECCOPY(key->world_co,key->co);
+ Mat4MulVecfl(hairmat, key->world_co);
+ }
+ }
+}
+/* calculate a tree for finding nearest emitter's vertice */
+static void recalc_emitter_field(Object *ob, ParticleSystem *psys)
+{
+ DerivedMesh *dm=psys_get_modifier(ob,psys)->dm;
+ ParticleEdit *edit = psys->edit;
+ MFace *mface;
+ MVert *mvert;
+ float *vec, *nor;
+ int i, totface, totvert;
+
+ if(edit->emitter_cosnos)
+ MEM_freeN(edit->emitter_cosnos);
+
+ BLI_kdtree_free(edit->emitter_field);
+
+ totface=dm->getNumFaces(dm);
+ totvert=dm->getNumVerts(dm);
+
+ edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float),"emitter cosnos");
+
+ edit->emitter_field= BLI_kdtree_new(totface);
+
+ vec=edit->emitter_cosnos;
+ nor=vec+3;
+
+ mvert=dm->getVertDataArray(dm,CD_MVERT);
+ for(i=0; i<totface; i++, vec+=6, nor+=6){
+ mface=dm->getFaceData(dm,i,CD_MFACE);
+
+ mvert=dm->getVertData(dm,mface->v1,CD_MVERT);
+ VECCOPY(vec,mvert->co);
+ VECCOPY(nor,mvert->no);
+
+ mvert=dm->getVertData(dm,mface->v2,CD_MVERT);
+ VECADD(vec,vec,mvert->co);
+ VECADD(nor,nor,mvert->no);
+
+ mvert=dm->getVertData(dm,mface->v3,CD_MVERT);
+ VECADD(vec,vec,mvert->co);
+ VECADD(nor,nor,mvert->no);
+
+ if (mface->v4){
+ mvert=dm->getVertData(dm,mface->v4,CD_MVERT);
+ VECADD(vec,vec,mvert->co);
+ VECADD(nor,nor,mvert->no);
+
+ VecMulf(vec,0.25);
+ }
+ else
+ VecMulf(vec,0.3333f);
+
+ Normalize(nor);
+
+ BLI_kdtree_insert(edit->emitter_field, i, vec, NULL);
+ }
+
+ BLI_kdtree_balance(edit->emitter_field);
+}
+
+void PE_update_selection(Object *ob, int useflag)
+{
+ ParticleSystem *psys= PE_get_current(ob);
+ ParticleEdit *edit= psys->edit;
+ ParticleEditSettings *pset= PE_settings();
+ ParticleSettings *part= psys->part;
+ ParticleData *pa;
+ HairKey *hkey;
+ ParticleEditKey *key;
+ float cfra= CFRA;
+ int i, k, totpart;
+
+ totpart= psys->totpart;
+
+ /* flag all particles to be updated if not using flag */
+ if(!useflag)
+ LOOP_PARTICLES(i,pa)
+ pa->flag |= PARS_EDIT_RECALC;
+
+ /* flush edit key flag to hair key flag to preserve selection
+ * on save */
+ LOOP_PARTICLES(i,pa) {
+ key = edit->keys[i];
+
+ for(k=0, hkey=pa->hair; k<pa->totkey; k++, hkey++, key++)
+ hkey->editflag= key->flag;
+ }
+
+ psys_cache_paths(ob, psys, CFRA, 1);
+
+ if(part->childtype && (pset->flag & PE_SHOW_CHILD))
+ psys_cache_child_paths(ob, psys, cfra, 1);
+
+ /* disable update flag */
+ LOOP_PARTICLES(i,pa)
+ pa->flag &= ~PARS_EDIT_RECALC;
+}
+
+void PE_update_object(Object *ob, int useflag)
+{
+ ParticleSystem *psys= PE_get_current(ob);
+ ParticleEditSettings *pset= PE_settings();
+ ParticleSettings *part= psys->part;
+ ParticleData *pa;
+ float cfra= CFRA;
+ int i, totpart= psys->totpart;
+
+ /* flag all particles to be updated if not using flag */
+ if(!useflag)
+ LOOP_PARTICLES(i,pa)
+ pa->flag |= PARS_EDIT_RECALC;
+
+ /* do post process on particle edit keys */
+ PE_iterate_lengths(psys);
+ PE_deflect_emitter(ob,psys);
+ PE_apply_lengths(psys);
+ if(pset->flag & PE_X_MIRROR)
+ PE_apply_mirror(ob,psys);
+ PE_recalc_world_cos(ob,psys);
+ PE_hide_keys_time(psys,cfra);
+
+ /* regenerate path caches */
+ psys_cache_paths(ob, psys, cfra, 1);
+
+ if(part->childtype && (pset->flag & PE_SHOW_CHILD))
+ psys_cache_child_paths(ob, psys, cfra, 1);
+
+ /* disable update flag */
+ LOOP_PARTICLES(i,pa)
+ pa->flag &= ~PARS_EDIT_RECALC;
+}
+
+/* initialize needed data for bake edit */
+void PE_create_particle_edit(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit=psys->edit;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ HairKey *hkey;
+ int i,k, totpart=psys->totpart, alloc=1;
+
+ if((psys->flag & PSYS_EDITED)==0)
+ return;
+
+ if(edit){
+ int newtotkeys = psys_count_keys(psys);
+ if(newtotkeys == edit->totkeys)
+ alloc=0;
+ }
+
+ if(alloc){
+ if(edit){
+ error("ParticleEdit exists allready! Poke jahka!");
+ PE_free_particle_edit(psys);
+ }
+
+ edit=psys->edit=MEM_callocN(sizeof(ParticleEdit), "PE_create_particle_edit");
+
+ edit->keys=MEM_callocN(totpart*sizeof(ParticleEditKey*),"ParticleEditKey array");
+
+ LOOP_PARTICLES(i,pa){
+ key = edit->keys[i] = MEM_callocN(pa->totkey*sizeof(ParticleEditKey),"ParticleEditKeys");
+ for(k=0, hkey=pa->hair; k<pa->totkey; k++, hkey++, key++){
+ key->co = hkey->co;
+ key->time = &hkey->time;
+ key->flag= hkey->editflag;
+ }
+ }
+
+ edit->totkeys = psys_count_keys(psys);
+ }
+
+ recalc_lengths(psys);
+ recalc_emitter_field(ob, psys);
+ PE_recalc_world_cos(ob, psys);
+
+ if(alloc) {
+ ParticleUndo_clear(psys);
+ PE_undo_push("Original");
+ }
+}
+
+/* toggle particle mode on & off */
+void PE_set_particle_edit(void)
+{
+ Object *ob= OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+
+ scrarea_queue_headredraw(curarea);
+
+ //if(!ob || ob->id.lib) return; /* is the id.lib test needed? -jahka*/
+ if(ob==0 || psys==0) return;
+
+ if(psys==0){
+ if(ob->particlesystem.first){
+ psys=ob->particlesystem.first;
+ psys->flag |= PSYS_CURRENT;
+ }
+ else
+ return;
+ }
+
+ if((G.f & G_PARTICLEEDIT)==0){
+ if(psys && psys->part->type == PART_HAIR && psys->flag & PSYS_EDITED) {
+ if(psys_check_enabled(ob, psys)) {
+ if(psys->edit==0)
+ PE_create_particle_edit(ob, psys);
+ PE_recalc_world_cos(ob, psys);
+ }
+ }
+
+ G.f |= G_PARTICLEEDIT;
+ }
+ else{
+ G.f &= ~G_PARTICLEEDIT;
+
+ if(psys->soft)
+ psys->softflag |= OB_SB_REDO;
+ }
+
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+
+ allqueue(REDRAWVIEW3D, 1); /* including header */
+ allqueue(REDRAWBUTSOBJECT, 0);
+}
+/************************************************/
+/* Edit Selections */
+/************************************************/
+/*-----selection callbacks-----*/
+static void select_key(ParticleSystem *psys, int pa_index, int key_index, void *userData)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } *data = userData;
+ ParticleData *pa = psys->particles + pa_index;
+ ParticleEditKey *key = psys->edit->keys[pa_index] + key_index;
+
+ if(data->select)
+ key->flag|=PEK_SELECT;
+ else
+ key->flag&=~PEK_SELECT;
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void select_keys(ParticleSystem *psys, int pa_index, int key_index, void *userData)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } *data = userData;
+ ParticleData *pa = psys->particles + pa_index;
+ ParticleEditKey *key = psys->edit->keys[pa_index];
+ int k;
+
+ for(k=0; k<pa->totkey; k++,key++){
+ if(data->select)
+ key->flag|=PEK_SELECT;
+ else
+ key->flag&=~PEK_SELECT;
+ }
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void toggle_key_select(ParticleSystem *psys, int pa_index, int key_index, void *userData)
+{
+ ParticleData *pa = psys->particles + pa_index;
+
+ if(psys->edit->keys[pa_index][key_index].flag&PEK_SELECT)
+ psys->edit->keys[pa_index][key_index].flag&=~PEK_SELECT;
+ else
+ psys->edit->keys[pa_index][key_index].flag|=PEK_SELECT;
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void select_root(ParticleSystem *psys, int index, void *userData)
+{
+ psys->edit->keys[index]->flag |= PEK_SELECT;
+}
+
+static void select_tip(ParticleSystem *psys, int index, void *userData)
+{
+ ParticleData *pa = psys->particles + index;
+ ParticleEditKey *key = psys->edit->keys[index] + pa->totkey-1;
+
+ key->flag |= PEK_SELECT;
+}
+static void select_more_keys(ParticleSystem *psys, int index, void *userData)
+{
+ ParticleEdit *edit = psys->edit;
+ ParticleData *pa = psys->particles+index;
+ ParticleEditKey *key;
+ int k;
+
+ for(k=0,key=edit->keys[index]; k<pa->totkey; k++,key++){
+ if(key->flag&PEK_SELECT) continue;
+
+ if(k==0){
+ if((key+1)->flag&PEK_SELECT)
+ key->flag |= PEK_TO_SELECT;
+ }
+ else if(k==pa->totkey-1){
+ if((key-1)->flag&PEK_SELECT)
+ key->flag |= PEK_TO_SELECT;
+ }
+ else{
+ if(((key-1)->flag | (key+1)->flag) & PEK_SELECT)
+ key->flag |= PEK_TO_SELECT;
+ }
+ }
+
+ for(k=0,key=edit->keys[index]; k<pa->totkey; k++,key++){
+ if(key->flag&PEK_TO_SELECT){
+ key->flag &= ~PEK_TO_SELECT;
+ key->flag |= PEK_SELECT;
+ }
+ }
+}
+
+static void select_less_keys(ParticleSystem *psys, int index, void *userData)
+{
+ ParticleEdit *edit = psys->edit;
+ ParticleData *pa = psys->particles+index;
+ ParticleEditKey *key;
+ int k;
+
+ for(k=0,key=edit->keys[index]; k<pa->totkey; k++,key++){
+ if((key->flag&PEK_SELECT)==0) continue;
+
+ if(k==0){
+ if(((key+1)->flag&PEK_SELECT)==0)
+ key->flag |= PEK_TO_SELECT;
+ }
+ else if(k==pa->totkey-1){
+ if(((key-1)->flag&PEK_SELECT)==0)
+ key->flag |= PEK_TO_SELECT;
+ }
+ else{
+ if((((key-1)->flag & (key+1)->flag) & PEK_SELECT)==0)
+ key->flag |= PEK_TO_SELECT;
+ }
+ }
+
+ for(k=0,key=edit->keys[index]; k<pa->totkey; k++,key++){
+ if(key->flag&PEK_TO_SELECT)
+ key->flag &= ~(PEK_TO_SELECT|PEK_SELECT);
+ }
+}
+
+/*-----using above callbacks-----*/
+void PE_deselectall(void)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEdit *edit = 0;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i,k,totpart, sel = 0;
+
+ if(!PE_can_edit(psys)) return;
+
+ edit = psys->edit;
+
+ totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_SELECT){
+ sel = 1;
+ key->flag &= ~PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+
+ if(sel==0){
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+ LOOP_KEYS(k,key){
+ if(!(key->flag & PEK_SELECT)) {
+ key->flag |= PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+ }
+
+ PE_update_selection(ob, 1);
+
+ BIF_undo_push("(De)select all keys");
+ allqueue(REDRAWVIEW3D, 1);
+}
+void PE_mouse_particles(void)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } data;
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEdit *edit = 0;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ short mval[2];
+ int i,k,totpart;
+
+ if(!PE_can_edit(psys)) return;
+
+ edit = psys->edit;
+
+ totpart = psys->totpart;
+
+ bglFlush();
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_BACK);
+ persp(PERSP_VIEW);
+
+ if(G.qual != LR_SHIFTKEY)
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+ LOOP_KEYS(k,key){
+ if(key->flag & PEK_SELECT) {
+ key->flag &= ~PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+
+ getmouseco_areawin(mval);
+
+ data.mval=mval;
+ data.rad=75.0f;
+ data.rect=0;
+ data.select=0;
+
+ for_mouse_hit_keys(1,psys,toggle_key_select,&data);
+
+ PE_update_selection(ob, 1);
+
+ rightmouse_transform();
+
+ allqueue(REDRAWVIEW3D, 1);
+}
+void PE_select_root()
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+
+ if(!PE_can_edit(psys)) return;
+
+ PE_foreach_element(psys,select_root,NULL);
+ BIF_undo_push("Select first");
+}
+void PE_select_tip()
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+
+ if(!PE_can_edit(psys)) return;
+
+ PE_foreach_element(psys,select_tip,NULL);
+ BIF_undo_push("Select last");
+}
+void PE_select_linked(void)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } data;
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ short mval[2];
+
+ if(!PE_can_edit(psys)) return;
+
+ getmouseco_areawin(mval);
+
+ data.mval=mval;
+ data.rad=75.0f;
+ data.rect=0;
+ data.select=(G.qual != LR_SHIFTKEY);
+
+ for_mouse_hit_keys(1,psys,select_keys,&data);
+
+ PE_update_selection(ob, 1);
+
+ BIF_undo_push("Select linked keys");
+
+ allqueue(REDRAWVIEW3D, 1);
+ return;
+}
+void PE_borderselect(void)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } data;
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ rcti rect;
+ int val;
+
+ if(!PE_can_edit(psys)) return;
+
+ setlinestyle(2);
+ val= get_border(&rect, 3);
+ setlinestyle(0);
+
+ if(val==0) return;
+
+ data.mval=0;
+ data.rect=&rect;
+ data.select=(val==LEFTMOUSE);
+
+ for_mouse_hit_keys(0,psys,select_key,&data);
+
+ PE_update_selection(ob, 1);
+
+ BIF_undo_push("Select keys");
+
+ allqueue(REDRAWVIEW3D, 1);
+ return;
+}
+void PE_selectionCB(short selecting, Object *editobj, short *mval, float rad)
+{
+ struct { short *mval; float rad; rcti* rect; int select; } data;
+ ParticleSystem *psys = PE_get_current(OBACT);
+
+ if(!PE_can_edit(psys)) return;
+
+ data.mval=mval;
+ data.rad=rad;
+ data.rect=0;
+ data.select=(selecting==LEFTMOUSE);
+
+ for_mouse_hit_keys(0,psys,select_key,&data);
+
+ draw_sel_circle(0, 0, 0, 0, 0); /* signal */
+ force_draw(0);
+}
+void PE_do_lasso_select(short mcords[][2], short moves, short select)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleSystemModifierData *psmd;
+ ParticleEdit *edit;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ float co[3], mat[4][4];
+ short vertco[2];
+ int i, k, totpart;
+
+ if(!PE_can_edit(psys)) return;
+
+ psmd= psys_get_modifier(ob, psys);
+ edit=psys->edit;
+ totpart=psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag & PARS_HIDE) continue;
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
+
+ if(G.scene->selectmode==SCE_SELECT_POINT){
+ LOOP_KEYS(k,key){
+ VECCOPY(co, key->co);
+ Mat4MulVecfl(mat, co);
+ project_short(co,vertco);
+ if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])){
+ if(select && !(key->flag & PEK_SELECT)) {
+ key->flag|=PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ else if(key->flag & PEK_SELECT) {
+ key->flag&=~PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+ }
+ else if(G.scene->selectmode==SCE_SELECT_END){
+ key = edit->keys[i] + pa->totkey - 1;
+
+ VECCOPY(co, key->co);
+ Mat4MulVecfl(mat, co);
+ project_short(co,vertco);
+ if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1])){
+ if(select && !(key->flag & PEK_SELECT)) {
+ key->flag|=PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ else if(key->flag & PEK_SELECT) {
+ key->flag&=~PEK_SELECT;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+ }
+
+ PE_update_selection(ob, 1);
+
+ BIF_undo_push("Lasso select particles");
+
+ allqueue(REDRAWVIEW3D, 1);
+}
+void PE_hide(int mode)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+ ParticleEdit *edit;
+ ParticleData *pa;
+ int i,totpart;
+
+ if(!PE_can_edit(psys)) return;
+
+ edit = psys->edit;
+ totpart = psys->totpart;
+
+ if(mode == 0){ /* reveal all particles */
+ LOOP_PARTICLES(i,pa){
+ pa->flag &= ~PARS_HIDE;
+ }
+ }
+ else if(mode == 1){ /* hide unselected particles */
+ LOOP_PARTICLES(i,pa)
+ if(particle_is_selected(psys, pa))
+ pa->flag |= PARS_HIDE;
+ }
+ else{ /* hide selected particles */
+ LOOP_PARTICLES(i,pa)
+ if(particle_is_selected(psys, pa))
+ pa->flag |= PARS_HIDE;
+ }
+
+ BIF_undo_push("(Un)hide elements");
+
+ allqueue(REDRAWVIEW3D, 1);
+}
+void PE_select_less(void)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+
+ if(!PE_can_edit(psys)) return;
+
+ PE_foreach_element(psys,select_less_keys,NULL);
+
+ BIF_undo_push("Select less");
+ allqueue(REDRAWVIEW3D, 1);
+}
+void PE_select_more(void)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+
+ if(!PE_can_edit(psys)) return;
+
+ PE_foreach_element(psys,select_more_keys,NULL);
+
+ BIF_undo_push("Select more");
+ allqueue(REDRAWVIEW3D, 1);
+}
+/************************************************/
+/* Edit Rekey */
+/************************************************/
+static void rekey_element(ParticleSystem *psys, int index, void *userData)
+{
+ struct { Object *ob; float dval; } *data = userData;
+ ParticleData *pa = psys->particles + index;
+ ParticleEdit *edit = psys->edit;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleKey state;
+ HairKey *key, *new_keys;
+ ParticleEditKey *ekey;
+ float dval, sta, end;
+ int k;
+
+ pa->flag |= PARS_REKEY;
+
+ key = new_keys = MEM_callocN(pset->totrekey * sizeof(HairKey),"Hair re-key keys");
+
+ /* root and tip stay the same */
+ VECCOPY(key->co, pa->hair->co);
+ VECCOPY((key + pset->totrekey - 1)->co, (pa->hair + pa->totkey - 1)->co);
+
+ sta = key->time = pa->hair->time;
+ end = (key + pset->totrekey - 1)->time = (pa->hair + pa->totkey - 1)->time;
+ dval = (end - sta) / (float)(pset->totrekey - 1);
+
+ /* interpolate new keys from old ones */
+ for(k=1,key++; k<pset->totrekey-1; k++,key++) {
+ state.time = (float)k / (float)(pset->totrekey-1);
+ psys_get_particle_on_path(data->ob, psys, index, &state, 0);
+ VECCOPY(key->co, state.co);
+ key->time = sta + k * dval;
+ }
+
+ /* replace keys */
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ pa->hair = new_keys;
+
+ pa->totkey=pset->totrekey;
+
+ if(edit->keys[index])
+ MEM_freeN(edit->keys[index]);
+ ekey = edit->keys[index] = MEM_callocN(pa->totkey * sizeof(ParticleEditKey),"Hair re-key edit keys");
+
+ for(k=0, key=pa->hair; k<pa->totkey; k++, key++, ekey++) {
+ ekey->co = key->co;
+ ekey->time = &key->time;
+ }
+
+ pa->flag &= ~PARS_REKEY;
+ pa->flag |= PARS_EDIT_RECALC;
+}
+void PE_rekey(void)
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEditSettings *pset = PE_settings();
+ struct { Object *ob; float dval; } data;
+
+ if(!PE_can_edit(psys)) return;
+
+ data.ob = ob;
+ data.dval = 1.0f / (float)(pset->totrekey-1);
+
+ foreach_selected_element(psys,rekey_element,&data);
+
+ psys->edit->totkeys = psys_count_keys(psys);
+
+ recalc_lengths(psys);
+
+ PE_update_object(ob, 1);
+
+ BIF_undo_push("Re-key particles");
+}
+static void rekey_element_to_time(int index, float path_time)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEdit *edit=0;
+ ParticleData *pa;
+ ParticleKey state;
+ HairKey *new_keys, *key;
+ ParticleEditKey *ekey;
+ int k;
+
+ if(psys==0) return;
+
+ edit = psys->edit;
+
+ pa = psys->particles + index;
+
+ pa->flag |= PARS_REKEY;
+
+ key = new_keys = MEM_dupallocN(pa->hair);
+
+ /* 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(ob, psys, index, &state, 0);
+ VECCOPY(key->co, state.co);
+ }
+
+ /* replace hair keys */
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ pa->hair = new_keys;
+
+ /* update edit pointers */
+ for(k=0, key=pa->hair, ekey=edit->keys[index]; k<pa->totkey; k++, key++, ekey++) {
+ ekey->co = key->co;
+ ekey->time = &key->time;
+ }
+
+ pa->flag &= ~PARS_REKEY;
+}
+static int remove_tagged_elements(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit = psys->edit;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleData *pa, *npa=0, *new_pars=0;
+ ParticleEditKey **key, **nkey=0, **new_keys=0;
+ ParticleSystemModifierData *psmd;
+ int i, totpart, new_totpart = psys->totpart, removed = 0;
+
+ if(pset->flag & PE_X_MIRROR) {
+ /* mirror tags */
+ psmd = psys_get_modifier(ob, psys);
+ totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa)
+ if(pa->flag & PARS_TAG)
+ PE_mirror_particle(ob, psmd->dm, psys, pa, NULL);
+ }
+
+ for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++) {
+ if(pa->flag & PARS_TAG) {
+ new_totpart--;
+ removed++;
+ }
+ }
+
+ if(new_totpart != psys->totpart) {
+ if(new_totpart) {
+ npa = new_pars = MEM_callocN(new_totpart * sizeof(ParticleData), "ParticleData array");
+ nkey = new_keys = MEM_callocN(new_totpart * sizeof(ParticleEditKey *), "ParticleEditKey array");
+ }
+
+ pa = psys->particles;
+ key = edit->keys;
+ for(i=0; i<psys->totpart; i++, pa++, key++) {
+ if(pa->flag & PARS_TAG) {
+ if(*key)
+ MEM_freeN(*key);
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ }
+ else {
+ memcpy(npa, pa, sizeof(ParticleData));
+ memcpy(nkey, key, sizeof(ParticleEditKey*));
+ npa++;
+ nkey++;
+ }
+ }
+
+ if(psys->particles) MEM_freeN(psys->particles);
+ psys->particles = new_pars;
+
+ if(edit->keys) MEM_freeN(edit->keys);
+ edit->keys = new_keys;
+
+ if(edit->mirror_cache) {
+ MEM_freeN(edit->mirror_cache);
+ edit->mirror_cache = NULL;
+ }
+
+ psys->totpart = new_totpart;
+
+ edit->totkeys = psys_count_keys(psys);
+ }
+
+ return removed;
+}
+static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
+{
+ ParticleEdit *edit = psys->edit;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleData *pa;
+ HairKey *key, *nkey, *new_keys=0;
+ ParticleEditKey *ekey;
+ ParticleSystemModifierData *psmd;
+ int i, k, totpart = psys->totpart;
+ short new_totkey;
+
+ if(pset->flag & PE_X_MIRROR) {
+ /* mirror key tags */
+ psmd = psys_get_modifier(ob, psys);
+
+ LOOP_PARTICLES(i,pa) {
+ LOOP_KEYS(k,ekey) {
+ if(ekey->flag & PEK_TAG) {
+ PE_mirror_particle(ob, psmd->dm, psys, pa, NULL);
+ break;
+ }
+ }
+ }
+ }
+
+ LOOP_PARTICLES(i,pa) {
+ new_totkey = pa->totkey;
+ LOOP_KEYS(k,ekey) {
+ if(ekey->flag & PEK_TAG)
+ new_totkey--;
+ }
+ /* we can't have elements with less than two keys*/
+ if(new_totkey < 2)
+ pa->flag |= PARS_TAG;
+ }
+ remove_tagged_elements(ob, psys);
+
+ totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa) {
+ new_totkey = pa->totkey;
+ LOOP_KEYS(k,ekey) {
+ if(ekey->flag & PEK_TAG)
+ new_totkey--;
+ }
+ if(new_totkey != pa->totkey) {
+ key = pa->hair;
+ nkey = new_keys = MEM_callocN(new_totkey*sizeof(HairKey), "HairKeys");
+
+ for(k=0, ekey=edit->keys[i]; k<new_totkey; k++, key++, nkey++, ekey++) {
+ while(ekey->flag & PEK_TAG && key < pa->hair + pa->totkey) {
+ key++;
+ ekey++;
+ }
+
+ if(key < pa->hair + pa->totkey) {
+ VECCOPY(nkey->co, key->co);
+ nkey->time = key->time;
+ nkey->weight = key->weight;
+ }
+ }
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+
+ pa->hair = new_keys;
+
+ pa->totkey=new_totkey;
+
+ if(edit->keys[i])
+ MEM_freeN(edit->keys[i]);
+ ekey = edit->keys[i] = MEM_callocN(new_totkey*sizeof(ParticleEditKey), "particle edit keys");
+
+ for(k=0, key=pa->hair; k<pa->totkey; k++, key++, ekey++) {
+ ekey->co = key->co;
+ ekey->time = &key->time;
+ }
+ }
+ }
+
+ edit->totkeys = psys_count_keys(psys);
+}
+/* works like normal edit mode subdivide, inserts keys between neighbouring selected keys */
+static void subdivide_element(ParticleSystem *psys, int index, void *userData)
+{
+ struct { Object *ob; } *data = userData;
+ ParticleEdit *edit = psys->edit;
+ ParticleData *pa = psys->particles + index;
+
+ ParticleKey state;
+ HairKey *key, *nkey, *new_keys;
+ ParticleEditKey *ekey, *nekey, *new_ekeys;
+
+ int k;
+ short totnewkey=0;
+ float endtime;
+
+ for(k=0, ekey=edit->keys[index]; k<pa->totkey-1; k++,ekey++){
+ if(ekey->flag&PEK_SELECT && (ekey+1)->flag&PEK_SELECT)
+ totnewkey++;
+ }
+
+ if(totnewkey==0) return;
+
+ pa->flag |= PARS_REKEY;
+
+ nkey = new_keys = MEM_callocN((pa->totkey+totnewkey)*(sizeof(HairKey)),"Hair subdivide keys");
+ nekey = new_ekeys = MEM_callocN((pa->totkey+totnewkey)*(sizeof(ParticleEditKey)),"Hair subdivide edit keys");
+ endtime = pa->hair[pa->totkey-1].time;
+
+ for(k=0, key=pa->hair, ekey=edit->keys[index]; k<pa->totkey-1; k++, key++, ekey++){
+
+ memcpy(nkey,key,sizeof(HairKey));
+ memcpy(nekey,ekey,sizeof(ParticleEditKey));
+
+ nekey->co = nkey->co;
+ nekey->time = &nkey->time;
+
+ nkey++;
+ nekey++;
+
+ 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->ob, psys, index, &state, 0);
+ VECCOPY(nkey->co, state.co);
+
+ nekey->co= nkey->co;
+ nekey->time= &nkey->time;
+ nekey->flag |= PEK_SELECT;
+
+ nekey++;
+ nkey++;
+ }
+ }
+ /*tip still not copied*/
+ memcpy(nkey,key,sizeof(HairKey));
+ memcpy(nekey,ekey,sizeof(ParticleEditKey));
+
+ nekey->co = nkey->co;
+ nekey->time = &nkey->time;
+
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ pa->hair = new_keys;
+
+ if(edit->keys[index])
+ MEM_freeN(edit->keys[index]);
+
+ edit->keys[index] = new_ekeys;
+
+ pa->totkey += totnewkey;
+ pa->flag |= PARS_EDIT_RECALC;
+ pa->flag &= ~PARS_REKEY;
+}
+void PE_subdivide(void)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ struct { Object *ob; } data;
+
+ if(!PE_can_edit(psys)) return;
+
+ data.ob= ob;
+ PE_foreach_element(psys,subdivide_element,&data);
+
+ psys->edit->totkeys = psys_count_keys(psys);
+
+ recalc_lengths(psys);
+ PE_recalc_world_cos(ob, psys);
+
+ PE_update_object(ob, 1);
+
+ BIF_undo_push("Subdivide hair(s)");
+}
+void PE_remove_doubles(void)
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys=PE_get_current(ob);
+ ParticleEditSettings *pset=PE_settings();
+ ParticleData *pa;
+ ParticleEdit *edit;
+ ParticleSystemModifierData *psmd;
+ KDTree *tree;
+ KDTreeNearest nearest[10];
+ float mat[4][4], co[3];
+ int i, n, totn, removed, totpart, flag, totremoved;
+
+ if(!PE_can_edit(psys)) return;
+
+ edit= psys->edit;
+ psmd= psys_get_modifier(ob, psys);
+ totremoved= 0;
+
+ do {
+ removed= 0;
+
+ totpart= psys->totpart;
+ tree=BLI_kdtree_new(totpart);
+
+ /* insert particles into kd tree */
+ LOOP_PARTICLES(i,pa) {
+ if(particle_is_selected(psys, pa)) {
+ psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat);
+ VECCOPY(co, pa->hair[0].co);
+ Mat4MulVecfl(mat, co);
+ BLI_kdtree_insert(tree, i, co, NULL);
+ }
+ }
+
+ BLI_kdtree_balance(tree);
+
+ /* tag particles to be removed */
+ LOOP_PARTICLES(i,pa) {
+ if(particle_is_selected(psys, pa)) {
+ psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, mat);
+ VECCOPY(co, pa->hair[0].co);
+ Mat4MulVecfl(mat, co);
+
+ totn= BLI_kdtree_find_n_nearest(tree,10,co,NULL,nearest);
+
+ for(n=0; n<totn; n++) {
+ /* this needs a custom threshold still */
+ if(nearest[n].index > i && nearest[n].dist < 0.0002f) {
+ if(!(pa->flag & PARS_TAG)) {
+ pa->flag |= PARS_TAG;
+ removed++;
+ }
+ }
+ }
+ }
+ }
+
+ BLI_kdtree_free(tree);
+
+ /* remove tagged particles - don't do mirror here! */
+ flag= pset->flag;
+ pset->flag &= ~PE_X_MIRROR;
+ remove_tagged_elements(ob, psys);
+ pset->flag= flag;
+ totremoved += removed;
+ } while(removed);
+
+ if(totremoved)
+ notice("Removed: %d", totremoved);
+
+ PE_recalc_world_cos(ob, psys);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 1);
+ BIF_undo_push("Remove double particles");
+}
+
+static void PE_radialcontrol_callback(const int mode, const int val)
+{
+ ParticleEditSettings *pset = PE_settings();
+
+ if(pset->brushtype>=0) {
+ ParticleBrushData *brush= &pset->brush[pset->brushtype];
+
+ if(mode == RADIALCONTROL_SIZE)
+ brush->size = val;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ brush->strength = val;
+ }
+
+ (*PE_radialcontrol()) = NULL;
+}
+
+RadialControl **PE_radialcontrol()
+{
+ static RadialControl *rc = NULL;
+ return &rc;
+}
+
+void PE_radialcontrol_start(const int mode)
+{
+ ParticleEditSettings *pset = PE_settings();
+ int orig= 1;
+
+ if(pset->brushtype>=0) {
+ ParticleBrushData *brush= &pset->brush[pset->brushtype];
+
+ if(mode == RADIALCONTROL_SIZE)
+ orig = brush->size;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ orig = brush->strength;
+
+ if(mode != RADIALCONTROL_NONE)
+ (*PE_radialcontrol())= radialcontrol_start(mode, PE_radialcontrol_callback, orig, 100, 0);
+ }
+}
+
+/************************************************/
+/* Edit Brushes */
+/************************************************/
+static void brush_comb(ParticleSystem *psys, float mat[][4], float imat[][4], int pa_index, int key_index, void *userData)
+{
+ struct {Object *ob; short *mval; float rad; rcti* rect; float dist; float *dvec; float combfac;} *data = userData;
+ ParticleData *pa= &psys->particles[pa_index];
+ ParticleEditSettings *pset= PE_settings();
+ HairKey *key = pa->hair + key_index;
+ float cvec[3], fac;
+
+ if(pset->flag & PE_LOCK_FIRST && key_index == 0) return;
+
+ fac = (float)pow((double)(1.0f - data->dist / data->rad), (double)data->combfac);
+
+ VECCOPY(cvec,data->dvec);
+ Mat4Mul3Vecfl(imat,cvec);
+ VecMulf(cvec, fac);
+ VECADD(key->co, key->co, cvec);
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void brush_cut(ParticleSystem *psys, int index, void *userData)
+{
+ struct { short *mval; float rad; rcti* rect; int selected; float cutfac;} *data = userData;
+ ParticleData *pa= &psys->particles[index];
+ ParticleCacheKey *key = psys->pathcache[index];
+ float rad2, cut_time = 1.0;
+ float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv;
+ int k, cut, keys = (int)pow(2.0, (double)psys->part->draw_step);
+ short vertco[2];
+
+ /* blunt scissors */
+ if(BLI_frand() > data->cutfac) return;
+
+ rad2 = data->rad * data->rad;
+
+ cut=0;
+
+ project_short_noclip(key->co, vertco);
+ x0 = (float)vertco[0];
+ x1 = (float)vertco[1];
+
+ o0 = (float)data->mval[0];
+ o1 = (float)data->mval[1];
+
+ xo0 = x0 - o0;
+ xo1 = x1 - o1;
+
+ /* check if root is inside circle */
+ if(xo0*xo0 + xo1*xo1 < rad2) {
+ cut_time = -1.0f;
+ cut = 1;
+ }
+ else {
+ /* calculate path time closest to root that was inside the circle */
+ for(k=1, key++; k<=keys; k++, key++){
+ project_short_noclip(key->co, vertco);
+
+ v0 = (float)vertco[0] - x0;
+ v1 = (float)vertco[1] - x1;
+
+ dv = v0*v0 + v1*v1;
+
+ d = (v0*xo1 - v1*xo0);
+
+ d = dv * rad2 - d*d;
+
+ if(d > 0.0f) {
+ d = sqrt(d);
+
+ cut_time = -(v0*xo0 + v1*xo1 + d);
+
+ if(cut_time > 0.0f) {
+ cut_time /= dv;
+
+ if(cut_time < 1.0f) {
+ cut_time += (float)(k-1);
+ cut_time /= (float)keys;
+ cut = 1;
+ break;
+ }
+ }
+ }
+
+ x0 = (float)vertco[0];
+ x1 = (float)vertco[1];
+
+ xo0 = x0 - o0;
+ xo1 = x1 - o1;
+ }
+ }
+
+ if(cut) {
+ if(cut_time < 0.0f) {
+ pa->flag |= PARS_TAG;
+ }
+ else {
+ rekey_element_to_time(index, cut_time);
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+}
+static void brush_length(ParticleSystem *psys, int index, void *userData)
+{
+ struct { short *mval; float rad; rcti* rect; float dist; float growfac; } *data = userData;
+ ParticleData *pa = &psys->particles[index];
+ HairKey *key;
+ float dvec[3],pvec[3];
+ int k;
+
+ key = pa->hair;
+ VECCOPY(pvec,key->co);
+
+ for(k=1, key++; k<pa->totkey; k++,key++){
+ VECSUB(dvec,key->co,pvec);
+ VECCOPY(pvec,key->co);
+ VecMulf(dvec,data->growfac);
+ VECADD(key->co,(key-1)->co,dvec);
+ }
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void brush_puff(ParticleSystem *psys, int index, void *userData)
+{
+ struct { short *mval; float rad; rcti* rect; float dist;
+ Object *ob; DerivedMesh *dm; float pufffac; int invert; } *data = userData;
+ ParticleData *pa = &psys->particles[index];
+ ParticleEdit *edit = psys->edit;
+ HairKey *key;
+ float mat[4][4], imat[4][4];
+ float lastco[3], rootco[3], co[3], nor[3], kco[3], dco[3], fac, length;
+ int k;
+
+ psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, pa, mat);
+ Mat4Invert(imat,mat);
+
+ /* find root coordinate and normal on emitter */
+ key = pa->hair;
+ VECCOPY(co, key->co);
+ Mat4MulVecfl(mat, co);
+
+ index= BLI_kdtree_find_nearest(edit->emitter_field, co, NULL, NULL);
+ if(index == -1) return;
+
+ VECCOPY(rootco, co);
+ VecCopyf(nor, &psys->edit->emitter_cosnos[index*6+3]);
+ Normalize(nor);
+ length= 0.0f;
+
+ fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac);
+ fac *= 0.025f;
+ if(data->invert)
+ fac= -fac;
+
+ for(k=1, key++; k<pa->totkey; k++, key++){
+ /* compute position as if hair was standing up straight */
+ VECCOPY(lastco, co);
+ VECCOPY(co, key->co);
+ Mat4MulVecfl(mat, co);
+ length += VecLenf(lastco, co);
+
+ VECADDFAC(kco, rootco, nor, length);
+
+ /* blend between the current and straight position */
+ VECSUB(dco, kco, co);
+ VECADDFAC(co, co, dco, fac);
+
+ VECCOPY(key->co, co);
+ Mat4MulVecfl(imat, key->co);
+ }
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+static void brush_smooth_get(ParticleSystem *psys, float mat[][4], float imat[][4], int pa_index, int key_index, void *userData)
+{
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float vec[3]; int tot; float smoothfac;} *data = userData;
+ ParticleData *pa= &psys->particles[pa_index];
+ HairKey *key = pa->hair + key_index;
+
+ if(key_index){
+ float dvec[3];
+
+ VecSubf(dvec,key->co,(key-1)->co);
+ Mat4Mul3Vecfl(mat,dvec);
+ VECADD(data->vec,data->vec,dvec);
+ data->tot++;
+ }
+}
+static void brush_smooth_do(ParticleSystem *psys, float mat[][4], float imat[][4], int pa_index, int key_index, void *userData)
+{
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float vec[3]; int tot; float smoothfac;} *data = userData;
+ ParticleData *pa= &psys->particles[pa_index];
+ HairKey *key = pa->hair + key_index;
+ float vec[3], dvec[3];
+
+ if(key_index){
+ VECCOPY(vec,data->vec);
+ Mat4Mul3Vecfl(imat,vec);
+
+ VecSubf(dvec,key->co,(key-1)->co);
+
+ VECSUB(dvec,vec,dvec);
+ VecMulf(dvec,data->smoothfac);
+
+ VECADD(key->co,key->co,dvec);
+ }
+
+ pa->flag |= PARS_EDIT_RECALC;
+}
+#define EXPERIMENTAL_DEFORM_ONLY_PAINTING 1
+static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short number)
+{
+ ParticleData *add_pars = MEM_callocN(number*sizeof(ParticleData),"ParticleData add");
+ ParticleSystemModifierData *psmd = psys_get_modifier(ob,psys);
+ ParticleEditSettings *pset= PE_settings();
+ ParticleEdit *edit = psys->edit;
+ int i, k, n = 0, totpart = psys->totpart;
+ short dmx = 0, dmy = 0;
+ short mx = mval[0] - curarea->winx / 2, my = mval[1] - curarea->winy / 2;
+ float co1[3], co2[3], vec[4], min_d, imat[4][4];
+ float framestep, timestep = psys_get_timestep(psys->part);
+ short size = pset->brush[PE_BRUSH_ADD].size;
+ short size2 = size*size;
+#if EXPERIMENTAL_DEFORM_ONLY_PAINTING
+ DerivedMesh *dm=0;
+#endif
+ Mat4Invert(imat,ob->obmat);
+
+ BLI_srandom(psys->seed+mval[0]+mval[1]);
+
+ /* painting onto the deformed mesh, could be an option? */
+#if EXPERIMENTAL_DEFORM_ONLY_PAINTING
+ if (psmd->dm->deformedOnly)
+ dm = psmd->dm;
+ else
+ dm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH);
+#endif
+ for(i=0; i<number; i++){
+ if(number>1){
+ dmx=dmy=size;
+ while(dmx*dmx+dmy*dmy>size2){
+ dmx=(short)((2.0f*BLI_frand()-1.0f)*size);
+ dmy=(short)((2.0f*BLI_frand()-1.0f)*size);
+ }
+ }
+
+ /* create intersection coordinates in view Z direction at mouse coordinates */
+ /* Thanks to who ever wrote the "Mouse Location 3D Space" tutorial in "Blender 3D: Blending Into Python/Cookbook". */
+ if(G.vd->persp){
+ vec[0]= (2.0f*(mx+dmx)/curarea->winx);
+ vec[1]= (2.0f*(my+dmy)/curarea->winy);
+ vec[2]= -1.0f;
+ vec[3]= 1.0f;
+
+ Mat4MulVec4fl(G.vd->persinv, vec);
+ VecMulf(vec, 1.0f/vec[3]);
+
+ VECCOPY(co1, G.vd->viewinv[3]);
+ VECSUB(vec, vec, co1);
+ Normalize(vec);
+
+ VECADDFAC(co1, G.vd->viewinv[3], vec, G.vd->near);
+ VECADDFAC(co2, G.vd->viewinv[3], vec, G.vd->far);
+ }
+ else {
+ vec[0] = 2.0f*(mx+dmx)/curarea->winx;
+ vec[1] = 2.0f*(my+dmy)/curarea->winy;
+ vec[2] = 0.0f;
+ vec[3] = 1.0f;
+
+ Mat4MulVec4fl(G.vd->persinv,vec);
+
+ VECADDFAC(co1,vec,G.vd->viewinv[2],1000.0f);
+ VECADDFAC(co2,vec,G.vd->viewinv[2],-1000.0f);
+ }
+
+ Mat4MulVecfl(imat,co1);
+ Mat4MulVecfl(imat,co2);
+ min_d=2.0;
+
+ /* warning, returns the derived mesh face */
+#if EXPERIMENTAL_DEFORM_ONLY_PAINTING
+ if(psys_intersect_dm(ob,dm,0,co1,co2,&min_d,&add_pars[n].num,add_pars[n].fuv,0,0,0,0)) {
+ add_pars[n].num_dmcache= psys_particle_dm_face_lookup(ob,psmd->dm,add_pars[n].num,add_pars[n].fuv,NULL);
+ n++;
+ }
+#else
+#if 0
+ if (psmd->dm->deformedOnly) {
+ if(psys_intersect_dm(ob,psmd->dm,0,co1,co2,&min_d,&add_pars[n].num,add_pars[n].fuv,0,0,0,0)){
+ n++;
+ }
+ } else {
+ /* we need to test against the cage mesh, because 1) its faster and 2) then we can avoid converting the fuv back which is not simple */
+ if(psys_intersect_dm(ob,psmd->dm,0,co1,co2,&min_d,&add_pars[n].num,add_pars[n].fuv,0,0,0,0)){
+ MFace *mface;
+ float fuv_mod[3] = {0.0, 0.0, 0.0};
+ OrigSpaceFace *osface;
+
+ mface= psmd->dm->getFaceData(psmd->dm,add_pars[n].num,CD_MFACE);
+ osface= psmd->dm->getFaceData(psmd->dm, add_pars[n].num, CD_ORIGSPACE);
+
+ add_pars[n].fuv[2]=0.0;
+
+ /* use the original index for num and the derived index for num_dmcache */
+ add_pars[n].num_dmcache = add_pars[n].num;
+ add_pars[n].num = *(int *)psmd->dm->getFaceData(psmd->dm, add_pars[n].num, CD_ORIGINDEX);
+
+ /* This is totally unaceptable code (fakeing mesh dara) but changing the target function isnt really nice either, do this temporarily */
+ if (1) { /* Evilness*/
+ MFace mface_fake;
+ MVert mvert_fake[4];
+ //int test1,test2;
+ //test1 = add_pars[n].num_dmcache;
+ //test2 = add_pars[n].num;
+
+ mvert_fake[0].co[2] = mvert_fake[1].co[2] = mvert_fake[2].co[2] = mvert_fake[3].co[2] = 0.0;
+
+ mface_fake.v1 = 0;
+ mface_fake.v2 = 1;
+ mface_fake.v3 = 2;
+
+ if (mface->v4) {
+ mface_fake.v4 = 3;
+ } else {
+ mface_fake.v4 = 0;
+ }
+
+ Vec2Copyf(mvert_fake[0].co, osface->uv[0]);
+ Vec2Copyf(mvert_fake[1].co, osface->uv[1]);
+ Vec2Copyf(mvert_fake[2].co, osface->uv[2]);
+ Vec2Copyf(mvert_fake[3].co, osface->uv[3]);
+ //printf("before %f %f %i %i\n", add_pars[n].fuv[0], add_pars[n].fuv[1], test1, test2);
+ psys_interpolate_face(&mvert_fake, &mface_fake, NULL, &add_pars[n].fuv, &fuv_mod, NULL, NULL, NULL);
+
+ /* Apply as the UV */
+ Vec2Copyf(add_pars[n].fuv, fuv_mod);
+ //printf("after %f %f\n", add_pars[n].fuv[0], add_pars[n].fuv[1]);
+ }
+ /* Make a fake face, for calculating the derived face's fuv on the original face */
+ //PointInFace2DUV(mface->v4, osface->uv[0], osface->uv[1], osface->uv[2], osface->uv[3], add_pars[n].fuv, fuv_mod);
+ //Vec2Copyf(add_pars[n].fuv, fuv_mod);
+
+ n++;
+ }
+ }
+#endif
+#endif
+ }
+ if(n){
+ int newtotpart=totpart+n;
+ float hairmat[4][4], cur_co[3];
+ KDTree *tree=0;
+ ParticleData *pa, *new_pars = MEM_callocN(newtotpart*sizeof(ParticleData),"ParticleData new");
+ ParticleEditKey *ekey, **key, **new_keys = MEM_callocN(newtotpart*sizeof(ParticleEditKey *),"ParticleEditKey array new");
+ HairKey *hkey;
+
+ /* save existing elements */
+ memcpy(new_pars, psys->particles, totpart * sizeof(ParticleData));
+ memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*));
+
+ /* change old arrays to new ones */
+ if(psys->particles) MEM_freeN(psys->particles);
+ psys->particles = new_pars;
+
+ if(edit->keys) MEM_freeN(edit->keys);
+ edit->keys = new_keys;
+
+ if(edit->mirror_cache) {
+ MEM_freeN(edit->mirror_cache);
+ edit->mirror_cache = NULL;
+ }
+
+ /* create tree for interpolation */
+ if(pset->flag & PE_INTERPOLATE_ADDED && psys->totpart){
+ tree=BLI_kdtree_new(psys->totpart);
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,cur_co,0,0,0,0,0);
+ BLI_kdtree_insert(tree, i, cur_co, NULL);
+ }
+
+ BLI_kdtree_balance(tree);
+ }
+
+ psys->totpart = newtotpart;
+
+ /* create new elements */
+ pa = psys->particles + totpart;
+ key = edit->keys + totpart;
+
+ for(i=totpart; i<newtotpart; i++, pa++, key++){
+ memcpy(pa, add_pars + i - totpart, sizeof(ParticleData));
+ pa->hair = MEM_callocN(pset->totaddkey * sizeof(HairKey), "BakeKey key add");
+ ekey = *key = MEM_callocN(pset->totaddkey * sizeof(ParticleEditKey), "ParticleEditKey add");
+ pa->totkey = pset->totaddkey;
+
+ for(k=0, hkey=pa->hair; k<pa->totkey; k++, hkey++, ekey++) {
+ ekey->co = hkey->co;
+ ekey->time = &hkey->time;
+ }
+
+ pa->size= 1.0f;
+ initialize_particle(pa,i,ob,psys,psmd);
+ reset_particle(pa,psys,psmd,ob,0.0,1.0,0,0,0);
+ pa->flag |= PARS_EDIT_RECALC;
+ if(pset->flag & PE_X_MIRROR)
+ pa->flag |= PARS_TAG; /* signal for duplicate */
+
+ framestep = pa->lifetime/(float)(pset->totaddkey-1);
+
+ if(tree){
+ HairKey *hkey;
+ ParticleKey key[3];
+ KDTreeNearest ptn[3];
+ int w, maxw;
+ float maxd, mind, dd, totw=0.0, weight[3];
+
+ psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,0,0);
+ maxw = BLI_kdtree_find_n_nearest(tree,3,co1,NULL,ptn);
+
+ maxd = ptn[maxw-1].dist;
+ mind = ptn[0].dist;
+ dd = maxd - mind;
+
+ for(w=0; w<maxw; w++){
+ weight[w] = (float)pow(2.0, (double)(-6.0f * ptn[w].dist / maxd));
+ totw += weight[w];
+ }
+ for(;w<3; w++){
+ weight[w] = 0.0f;
+ }
+
+ for(w=0; w<maxw; w++)
+ weight[w] /= totw;
+
+ for(k=0; k<pset->totaddkey; k++) {
+ hkey = pa->hair + k;
+ hkey->time = pa->time + k * framestep;
+
+ key[0].time = hkey->time/ 100.0f;
+ psys_get_particle_on_path(ob, psys, 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(ob, psys, 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(ob, psys, ptn[2].index, key + 2, 0);
+ VecMulf(key[2].co, weight[2]);
+ VECADD(key[0].co, key[0].co, key[2].co);
+ }
+ }
+
+ if(k==0)
+ VECSUB(co1, pa->state.co, key[0].co);
+
+ VECADD(pa->hair[k].co, key[0].co, co1);
+
+ pa->hair[k].time = key[0].time;
+ }
+ }
+ else{
+ for(k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) {
+ VECADDFAC(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep);
+ pa->hair[k].time += k * framestep;
+ }
+ }
+ for(k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) {
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+ Mat4Invert(imat,hairmat);
+ Mat4MulVecfl(imat, hkey->co);
+ }
+ }
+ edit->totkeys = psys_count_keys(psys);
+
+ if(tree)
+ BLI_kdtree_free(tree);
+ }
+ if(add_pars)
+ MEM_freeN(add_pars);
+
+/* painting onto the deformed mesh, could be an option? */
+#if EXPERIMENTAL_DEFORM_ONLY_PAINTING
+ if (!psmd->dm->deformedOnly)
+ dm->release(dm);
+#endif
+}
+static void brush_weight(ParticleSystem *psys, float mat[][4], float imat[][4], int pa_index, int key_index, void *userData)
+{
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float weightfac;} *data = userData;
+ ParticleData *pa;
+
+ /* roots have full weight allways */
+ if(key_index) {
+ pa= &psys->particles[pa_index];
+ pa->hair[key_index].weight = data->weightfac;
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+}
+
+/* returns 0 if no brush was used */
+int PE_brush_particles(void)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEdit *edit;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleSystemModifierData *psmd;
+ ParticleBrushData *brush;
+ float vec1[3], vec2[3];
+ short mval[2], mvalo[2], firsttime = 1, dx, dy;
+ int selected = 0, flip, removed = 0;
+
+ if(!PE_can_edit(psys)) return 0;
+
+ edit = psys->edit;
+ psmd= psys_get_modifier(ob, psys);
+
+ flip= (get_qual() == LR_SHIFTKEY);
+
+ if(pset->brushtype<0) return 0;
+ brush= &pset->brush[pset->brushtype];
+
+ initgrabz(ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]);
+
+ getmouseco_areawin(mvalo);
+
+ mval[0] = mvalo[0]; mval[1] = mvalo[1];
+
+ while(get_mbut() & L_MOUSE){
+ bglFlush();
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_BACK);
+ persp(PERSP_VIEW);
+
+ dx=mval[0]-mvalo[0];
+ dy=mval[1]-mvalo[1];
+ if(((pset->brushtype == PE_BRUSH_ADD) ?
+ (sqrt(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0))
+ || firsttime){
+ firsttime = 0;
+
+ selected = (short)count_selected_keys(psys);
+
+ switch(pset->brushtype){
+ case PE_BRUSH_COMB:
+ {
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float *dvec; float combfac;} data;
+
+ data.ob = ob;
+ data.mval = mval;
+ data.rad = (float)brush->size;
+
+ data.combfac = (float)(brush->strength - 50) / 50.0f;
+ if(data.combfac < 0.0f)
+ data.combfac = 1.0f - 9.0f * data.combfac;
+ else
+ data.combfac = 1.0f - data.combfac;
+
+ Mat4Invert(ob->imat, ob->obmat);
+
+ window_to_3d(vec1, mvalo[0], mvalo[1]);
+ window_to_3d(vec2, mval[0], mval[1]);
+ VECSUB(vec1, vec2, vec1);
+ data.dvec = vec1;
+
+ foreach_mouse_hit_key(selected, psys,brush_comb, &data);
+ break;
+ }
+ case PE_BRUSH_CUT:
+ {
+ struct { short *mval; float rad; rcti* rect; int selected; float cutfac;} data;
+
+ data.mval = mval;
+ data.rad = (float)brush->size;
+
+ data.selected = selected;
+
+ data.cutfac = (float)(brush->strength / 100.0f);
+
+ if(selected)
+ foreach_selected_element(psys, brush_cut, &data);
+ else
+ PE_foreach_element(psys, brush_cut, &data);
+
+ removed= remove_tagged_elements(ob, psys);
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(psys);
+ break;
+ }
+ case PE_BRUSH_LENGTH:
+ {
+ struct { short *mval; float rad; rcti* rect; float dist; float growfac; } data;
+
+ data.mval = mval;
+
+ data.rad = (float)brush->size;
+ data.growfac = (float)brush->strength / 5000.0f;
+
+ if(brush->invert ^ flip)
+ data.growfac = 1.0f - data.growfac;
+ else
+ data.growfac = 1.0f + data.growfac;
+
+ foreach_mouse_hit_element(selected, psys, brush_length, &data);
+
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(psys);
+ break;
+ }
+ case PE_BRUSH_PUFF:
+ {
+ struct { short *mval; float rad; rcti* rect; float dist;
+ Object *ob; DerivedMesh *dm; float pufffac; int invert; } data;
+
+ data.ob = ob;
+ data.dm = psmd->dm;
+ data.mval = mval;
+ data.rad = (float)brush->size;
+
+ data.pufffac = (float)(brush->strength - 50) / 50.0f;
+ if(data.pufffac < 0.0f)
+ data.pufffac = 1.0f - 9.0f * data.pufffac;
+ else
+ data.pufffac = 1.0f - data.pufffac;
+
+ data.invert= (brush->invert ^ flip);
+ Mat4Invert(ob->imat, ob->obmat);
+
+ foreach_mouse_hit_element(selected, psys, brush_puff, &data);
+ break;
+ }
+ case PE_BRUSH_ADD:
+ if(psys->part->from==PART_FROM_FACE){
+ brush_add(ob, psys, mval, brush->strength);
+ if(pset->flag & PE_KEEP_LENGTHS)
+ recalc_lengths(psys);
+ }
+ break;
+ case PE_BRUSH_WEIGHT:
+ {
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float weightfac;} data;
+
+ data.ob = ob;
+ data.mval = mval;
+ data.rad = (float)brush->size;
+
+ data.weightfac = (float)(brush->strength / 100.0f);
+
+ foreach_mouse_hit_key(selected, psys, brush_weight, &data);
+ break;
+ }
+ case PE_BRUSH_SMOOTH:
+ {
+ struct { Object *ob; short *mval; float rad; rcti* rect; float dist; float vec[3]; int tot; float smoothfac;} data;
+
+ data.ob = ob;
+ data.mval = mval;
+ data.rad = (float)brush->size;
+
+ data.vec[0] = data.vec[1] = data.vec[2] = 0.0f;
+ data.tot = 0;
+
+ data.smoothfac = (float)(brush->strength / 100.0f);
+
+ Mat4Invert(ob->imat, ob->obmat);
+
+ foreach_mouse_hit_key(selected, psys, brush_smooth_get, &data);
+
+ if(data.tot){
+ VecMulf(data.vec, 1.0f / (float)data.tot);
+ foreach_mouse_hit_key(selected, psys, brush_smooth_do, &data);
+ }
+
+ break;
+ }
+ }
+ if((pset->flag & PE_KEEP_LENGTHS)==0)
+ recalc_lengths(psys);
+
+ if(pset->brushtype == PE_BRUSH_ADD || removed) {
+ if(pset->brushtype == PE_BRUSH_ADD && (pset->flag & PE_X_MIRROR))
+ PE_mirror_x(1);
+ PE_recalc_world_cos(ob,psys);
+ psys_free_path_cache(psys);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ else
+ PE_update_object(ob, 1);
+
+ mvalo[0] = mval[0];
+ mvalo[1] = mval[1];
+ }
+
+ force_draw(0);
+
+ PIL_sleep_ms(10);
+
+ getmouseco_areawin(mval);
+ }
+ allqueue(REDRAWVIEW3D, 1);
+
+ BIF_undo_push("Brush edit particles");
+
+ return 1;
+}
+static void set_delete_particle(ParticleSystem *psys, int index, void *userData)
+{
+ psys->particles[index].flag |= PARS_TAG;
+}
+static void set_delete_particle_key(ParticleSystem *psys, int pa_index, int key_index, void *userData)
+{
+ psys->edit->keys[pa_index][key_index].flag |= PEK_TAG;
+}
+void PE_delete_particle(void)
+{
+ Object *ob=OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ short event=0;
+
+ if(!PE_can_edit(psys)) return;
+
+ event= pupmenu("Erase %t|Particle%x2|Key%x1");
+
+ if(event<1) return;
+
+ if(event==1){
+ foreach_selected_key(psys, set_delete_particle_key, 0);
+ remove_tagged_keys(ob, psys);
+ recalc_lengths(psys);
+ }
+ else if(event==2){
+ foreach_selected_element(psys, set_delete_particle, 0);
+ remove_tagged_elements(ob, psys);
+ recalc_lengths(psys);
+ }
+
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 1);
+ BIF_undo_push("Delete particles/keys");
+}
+
+void PE_mirror_x(int tagged)
+{
+ Object *ob=OBACT;
+ Mesh *me= (Mesh*)(ob->data);
+ ParticleSystemModifierData *psmd;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleEdit *edit;
+ ParticleData *pa, *newpa, *new_pars;
+ ParticleEditKey *ekey, **newkey, **key, **new_keys;
+ HairKey *hkey;
+ int *mirrorfaces;
+ int i, k, rotation, totpart, newtotpart;
+
+ if(!PE_can_edit(psys)) return;
+
+ edit= psys->edit;
+ psmd= psys_get_modifier(ob, psys);
+
+ mirrorfaces= mesh_get_x_mirror_faces(ob);
+
+ if(!edit->mirror_cache)
+ PE_update_mirror_cache(ob, psys);
+
+ totpart= psys->totpart;
+ newtotpart= psys->totpart;
+ LOOP_PARTICLES(i,pa) {
+ if(pa->flag&PARS_HIDE) continue;
+
+ if(!tagged) {
+ if(particle_is_selected(psys, pa)) {
+ if(edit->mirror_cache[i] != -1) {
+ /* already has a mirror, don't need to duplicate */
+ PE_mirror_particle(ob, psmd->dm, psys, pa, NULL);
+ continue;
+ }
+ else
+ pa->flag |= PARS_TAG;
+ }
+ }
+
+ if((pa->flag & PARS_TAG) && mirrorfaces[pa->num*2] != -1)
+ newtotpart++;
+ }
+
+ if(newtotpart != psys->totpart) {
+ /* allocate new arrays and copy existing */
+ new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
+ new_keys= MEM_callocN(newtotpart*sizeof(ParticleEditKey*), "ParticleEditKey new");
+
+ memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData));
+ memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*));
+
+ if(psys->particles) MEM_freeN(psys->particles);
+ psys->particles= new_pars;
+
+ if(edit->keys) MEM_freeN(edit->keys);
+ edit->keys= new_keys;
+
+ if(edit->mirror_cache) {
+ MEM_freeN(edit->mirror_cache);
+ edit->mirror_cache= NULL;
+ }
+
+ psys->totpart= newtotpart;
+
+ /* create new elements */
+ pa= psys->particles;
+ newpa= psys->particles + totpart;
+ key= edit->keys;
+ newkey= edit->keys + totpart;
+
+ for(i=0; i<totpart; i++, pa++, key++) {
+ if(pa->flag&PARS_HIDE) continue;
+
+ if(!(pa->flag & PARS_TAG) || mirrorfaces[pa->num*2] == -1)
+ continue;
+
+ /* duplicate */
+ *newpa= *pa;
+ if(pa->hair) newpa->hair= MEM_dupallocN(pa->hair);
+ if(pa->keys) newpa->keys= MEM_dupallocN(pa->keys);
+ if(*key) *newkey= MEM_dupallocN(*key);
+
+ /* rotate weights according to vertex index rotation */
+ rotation= mirrorfaces[pa->num*2+1];
+ newpa->fuv[0]= pa->fuv[2];
+ newpa->fuv[1]= pa->fuv[1];
+ newpa->fuv[2]= pa->fuv[0];
+ newpa->fuv[3]= pa->fuv[3];
+ while(rotation-- > 0)
+ if(me->mface[pa->num].v4)
+ SHIFT4(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2], newpa->fuv[3])
+ else
+ SHIFT3(float, newpa->fuv[0], newpa->fuv[1], newpa->fuv[2])
+
+ /* assign face inddex */
+ newpa->num= mirrorfaces[pa->num*2];
+ newpa->num_dmcache= psys_particle_dm_face_lookup(ob,psmd->dm,newpa->num,newpa->fuv, NULL);
+
+ /* update edit key pointers */
+ ekey= *newkey;
+ for(k=0, hkey=newpa->hair; k<newpa->totkey; k++, hkey++, ekey++) {
+ ekey->co= hkey->co;
+ ekey->time= &hkey->time;
+ }
+
+ /* map key positions as mirror over x axis */
+ PE_mirror_particle(ob, psmd->dm, psys, pa, newpa);
+
+ newpa++;
+ newkey++;
+ }
+
+ edit->totkeys = psys_count_keys(psys);
+ }
+
+ for(pa=psys->particles, i=0; i<psys->totpart; i++, pa++)
+ pa->flag &= ~PARS_TAG;
+
+ MEM_freeN(mirrorfaces);
+
+ if(!tagged) {
+ PE_recalc_world_cos(ob,psys);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 1);
+ BIF_undo_push("Mirror particles");
+ }
+}
+
+void PE_selectbrush_menu(void)
+{
+ ParticleEditSettings *pset= PE_settings();
+ int val;
+
+ pupmenu_set_active(pset->brushtype);
+
+ val= pupmenu("Select Brush%t|None %x0|Comb %x1|Smooth %x7|Weight %x6|Add %x5|Length %x3|Puff %x4|Cut %x2");
+
+ if(val>=0) {
+ pset->brushtype= val-1;
+ allqueue(REDRAWVIEW3D, 1);
+ }
+}
+
+/************************************************/
+/* Particle Edit Undo */
+/************************************************/
+static void free_ParticleUndo(ParticleUndo *undo)
+{
+ ParticleData *pa;
+ int i;
+
+ for(i=0, pa=undo->particles; i<undo->totpart; i++, pa++) {
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+ if(undo->keys[i])
+ MEM_freeN(undo->keys[i]);
+ }
+ if(undo->keys)
+ MEM_freeN(undo->keys);
+
+ if(undo->particles)
+ MEM_freeN(undo->particles);
+
+ //if(undo->emitter_cosnos)
+ // MEM_freeN(undo->emitter_cosnos);
+}
+static void make_ParticleUndo(ParticleSystem *psys, ParticleUndo *undo)
+{
+ ParticleData *pa,*upa;
+ int i;
+
+ undo->totpart = psys->totpart;
+ undo->totkeys = psys->edit->totkeys;
+
+ upa = undo->particles = MEM_dupallocN(psys->particles);
+ undo->keys = MEM_dupallocN(psys->edit->keys);
+
+ for(i=0, pa=psys->particles; i<undo->totpart; i++, pa++, upa++) {
+ upa->hair = MEM_dupallocN(pa->hair);
+ undo->keys[i] = MEM_dupallocN(psys->edit->keys[i]);
+ /* no need to update edit key->co & key->time pointers here */
+ }
+}
+static void get_ParticleUndo(ParticleSystem *psys, ParticleUndo *undo)
+{
+ ParticleData *pa, *upa;
+ ParticleEditKey *key;
+ HairKey *hkey;
+ int i, k, totpart = psys->totpart;
+
+ LOOP_PARTICLES(i,pa) {
+ if(pa->hair)
+ MEM_freeN(pa->hair);
+
+ if(psys->edit->keys[i])
+ MEM_freeN(psys->edit->keys[i]);
+ }
+ if(psys->particles)
+ MEM_freeN(psys->particles);
+ if(psys->edit->keys)
+ MEM_freeN(psys->edit->keys);
+ if(psys->edit->mirror_cache) {
+ MEM_freeN(psys->edit->mirror_cache);
+ psys->edit->mirror_cache= NULL;
+ }
+
+ pa = psys->particles = MEM_dupallocN(undo->particles);
+ psys->edit->keys = MEM_dupallocN(undo->keys);
+
+ for(i=0,upa=undo->particles; i<undo->totpart; i++, upa++, pa++){
+ hkey = pa->hair = MEM_dupallocN(upa->hair);
+ key = psys->edit->keys[i] = MEM_dupallocN(undo->keys[i]);
+ for(k=0; k<pa->totkey; k++, hkey++, key++) {
+ key->co = hkey->co;
+ key->time = &hkey->time;
+ }
+ }
+
+ psys->totpart = undo->totpart;
+ psys->edit->totkeys = undo->totkeys;
+}
+void PE_undo_push(char *str)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+ ParticleEdit *edit = 0;
+ ParticleUndo *undo;
+ int nr;
+
+ if(!PE_can_edit(psys)) return;
+ edit = psys->edit;
+
+ /* remove all undos after (also when curundo==NULL) */
+ while(edit->undo.last != edit->curundo) {
+ undo= edit->undo.last;
+ BLI_remlink(&edit->undo, undo);
+ free_ParticleUndo(undo);
+ MEM_freeN(undo);
+ }
+
+ /* make new */
+ edit->curundo= undo= MEM_callocN(sizeof(ParticleUndo), "particle undo file");
+ strncpy(undo->name, str, 64-1);
+ BLI_addtail(&edit->undo, undo);
+
+ /* and limit amount to the maximum */
+ nr= 0;
+ undo= edit->undo.last;
+ while(undo) {
+ nr++;
+ if(nr==U.undosteps) break;
+ undo= undo->prev;
+ }
+ if(undo) {
+ while(edit->undo.first!=undo) {
+ ParticleUndo *first= edit->undo.first;
+ BLI_remlink(&edit->undo, first);
+ free_ParticleUndo(first);
+ MEM_freeN(first);
+ }
+ }
+
+ /* copy */
+ make_ParticleUndo(psys,edit->curundo);
+}
+void PE_undo_step(int step)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+ ParticleEdit *edit = 0;
+
+ if(!PE_can_edit(psys)) return;
+ edit=psys->edit;
+
+ if(step==0) {
+ get_ParticleUndo(psys,edit->curundo);
+ }
+ else if(step==1) {
+
+ if(edit->curundo==NULL || edit->curundo->prev==NULL) error("No more steps to undo");
+ else {
+ if(G.f & G_DEBUG) printf("undo %s\n", edit->curundo->name);
+ edit->curundo= edit->curundo->prev;
+ get_ParticleUndo(psys, edit->curundo);
+ }
+ }
+ else {
+ /* curundo has to remain current situation! */
+
+ if(edit->curundo==NULL || edit->curundo->next==NULL) error("No more steps to redo");
+ else {
+ get_ParticleUndo(psys, edit->curundo->next);
+ edit->curundo= edit->curundo->next;
+ if(G.f & G_DEBUG) printf("redo %s\n", edit->curundo->name);
+ }
+ }
+
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+}
+static void ParticleUndo_number(ParticleEdit *edit, int nr)
+{
+ ParticleUndo *undo;
+ int a=1;
+
+ for(undo= edit->undo.first; undo; undo= undo->next, a++) {
+ if(a==nr) break;
+ }
+ edit->curundo= undo;
+ PE_undo_step(0);
+}
+static void ParticleUndo_clear(ParticleSystem *psys)
+{
+ ParticleUndo *undo;
+ ParticleEdit *edit;
+
+ if(psys==0) return;
+
+ edit = psys->edit;
+
+ if(edit==0) return;
+
+ undo= edit->undo.first;
+ while(undo) {
+ free_ParticleUndo(undo);
+ undo= undo->next;
+ }
+ BLI_freelistN(&edit->undo);
+ edit->curundo= NULL;
+}
+void PE_undo(void)
+{
+ PE_undo_step(1);
+}
+void PE_redo(void)
+{
+ PE_undo_step(-1);
+}
+void PE_undo_menu(void)
+{
+ ParticleSystem *psys = PE_get_current(OBACT);
+ ParticleEdit *edit = 0;
+ ParticleUndo *undo;
+ DynStr *ds;
+ short event;
+ char *menu;
+
+ if(!PE_can_edit(psys)) return;
+ edit = psys->edit;
+
+ ds= BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, "Particlemode Undo History %t");
+
+ for(undo= edit->undo.first; undo; undo= undo->next) {
+ BLI_dynstr_append(ds, "|");
+ BLI_dynstr_append(ds, undo->name);
+ }
+
+ menu= BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ event= pupmenu_col(menu, 20);
+ MEM_freeN(menu);
+
+ if(event>0) ParticleUndo_number(edit,event);
+}
+
+void PE_get_colors(char sel[4], char nosel[4])
+{
+ BIF_GetThemeColor3ubv(TH_EDGE_SELECT, sel);
+ BIF_GetThemeColor3ubv(TH_WIRE, nosel);
+}
+
+int PE_minmax(float *min, float *max)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleSystemModifierData *psmd;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ float co[3], mat[4][4];
+ int i, k, totpart, ok = 0;
+
+ if(!PE_can_edit(psys)) return ok;
+
+ psmd= psys_get_modifier(ob, psys);
+ totpart= psys->totpart;
+
+ LOOP_PARTICLES(i,pa){
+ if(pa->flag&PARS_HIDE) continue;
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
+
+ LOOP_KEYS(k,key){
+ if(key->flag&PEK_SELECT) {
+ VECCOPY(co, key->co);
+ Mat4MulVecfl(mat, co);
+ DO_MINMAX(co, min, max);
+ ok= 1;
+ }
+ }
+ }
+
+ if(!ok) {
+ minmax_object(ob, min, max);
+ ok= 1;
+ }
+
+ return ok;
+}
+
diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c
index 541790ec98e..6391cf54f27 100644
--- a/source/blender/src/editscreen.c
+++ b/source/blender/src/editscreen.c
@@ -176,8 +176,9 @@ static int choose_cursor(ScrArea *sa)
if(G.obedit) return CURSOR_EDIT;
else if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))
return CURSOR_VPAINT;
- else if(G.f & G_FACESELECT) return CURSOR_FACESEL;
+ else if(FACESEL_PAINT_TEST) return CURSOR_FACESEL;
else if(G.f & G_SCULPTMODE) return CURSOR_EDIT;
+ else if(G.f & G_PARTICLEEDIT) return CURSOR_EDIT;
else return CURSOR_STD;
}
else if (sa->spacetype==SPACE_TEXT) {
@@ -358,6 +359,11 @@ void areawinset(short win)
G.v2d= &snode->v2d;
}
break;
+ case SPACE_IMASEL:
+ {
+ SpaceImaSel *simasel= curarea->spacedata.first;
+ G.v2d= &simasel->v2d;
+ }
default:
break;
}
@@ -485,6 +491,8 @@ static void addqueue_ext(short win, unsigned short event, short val, char ascii)
}
else {
BWinEvent evt;
+
+ memset(&evt, 0, sizeof(evt));
evt.event= event;
evt.val= val;
evt.ascii= ascii;
@@ -523,7 +531,7 @@ static void scrarea_dispatch_header_events(ScrArea *sa)
while(bwin_qread(sa->headwin, &evt)) {
if(evt.val) {
- if( uiDoBlocks(&curarea->uiblocks, evt.event)!=UI_NOTHING ) evt.event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, evt.event, 1)!=UI_NOTHING ) evt.event= 0;
switch(evt.event) {
case UI_BUT_EVENT:
@@ -1078,7 +1086,7 @@ int has_screenhandler(bScreen *sc, short eventcode)
static void animated_screen(bScreen *sc, short val)
{
- if (U.mixbufsize && (val & TIME_WITH_SEQ_AUDIO)) {
+ if ((val & TIME_WITH_SEQ_AUDIO)) {
if(CFRA>=PEFRA) {
CFRA= PSFRA;
audiostream_stop();
@@ -1114,7 +1122,9 @@ static void animated_screen(bScreen *sc, short val)
}
if(val & TIME_ALL_ANIM_WIN) allqueue(REDRAWANIM, 0);
if(val & TIME_ALL_BUTS_WIN) allqueue(REDRAWBUTSALL, 0);
- if(val & TIME_SEQ) allqueue(REDRAWSEQ, 0);
+ if(val & TIME_SEQ) {
+ allqueue(REDRAWSEQ, 0);
+ }
allqueue(REDRAWTIME, 0);
}
@@ -1131,7 +1141,7 @@ int do_screenhandlers(bScreen *sc)
short a, done= 0;
time = PIL_check_seconds_timer();
- swaptime= 1.0/(float)G.scene->r.frs_sec;
+ swaptime= 1.0/FPS;
/* only now do the handlers */
if(swaptime < time-ltime || ltime==0.0) {
@@ -1387,9 +1397,14 @@ void screenmain(void)
towin= 0;
}
else if (event==QKEY) {
- if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
+ /* Temp place to print mem debugging info ctrl+alt+shift + qkey */
+ if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
+ MEM_printmemlist_pydict();
+ }
+
+ else if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
else {
- if(val && (G.qual & LR_CTRLKEY)) {
+ if(val && (G.qual == LR_CTRLKEY)) {
if(okee("Quit Blender")) exit_usiblender();
}
towin= 0;
@@ -1400,10 +1415,10 @@ void screenmain(void)
bScreen *sc= G.curscreen->id.next;
/* if screen is last, set it to first */
- if(sc == NULL)
+ if(sc == NULL)
sc= G.main->screen.first;
- setscreen(sc);
+ if(is_allowed_to_change_screen(sc)) setscreen(sc);
g_activearea= NULL;
towin= 0;
}
@@ -1413,10 +1428,10 @@ void screenmain(void)
bScreen *sc= G.curscreen->id.prev;
/* if screen is first, set it to last */
- if(sc == NULL)
+ if(sc == NULL)
sc= G.main->screen.last;
- setscreen(sc);
+ if(is_allowed_to_change_screen(sc)) setscreen(sc);
g_activearea= NULL;
towin= 0;
}
@@ -2453,9 +2468,6 @@ void area_fullscreen(void) /* with curarea */
wich_cursor(newa);
}
- if(curarea->full)
- retopo_force_update();
-
/* there's also events in queue for this, but we call fullscreen for render output
now, and that doesn't go back to queue. Bad code, but doesn't hurt... (ton) */
for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
@@ -2465,8 +2477,7 @@ void area_fullscreen(void) /* with curarea */
/* bad code #2: setscreen() ends with first area active. fullscreen render assumes this too */
curarea= sc->areabase.first;
- if(!curarea->full)
- retopo_force_update();
+ retopo_force_update();
}
static void area_autoplayscreen(void)
@@ -3089,7 +3100,7 @@ static void splitarea_interactive(ScrArea *area, ScrEdge *onedge)
ScrArea *scr, *sa= area;
float fac= 0.0;
unsigned short event;
- short ok= 0, val, split = 0, mval[2], mvalo[2], first= 1;
+ short ok= 0, val, split = 0, mval[2], mvalo[2]= {-1, -1}, first= 1;
char dir;
if(sa->win==0) return;
@@ -3133,7 +3144,7 @@ static void splitarea_interactive(ScrArea *area, ScrEdge *onedge)
}
}
- if (first || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
+ if (first || (dir=='v' && mval[0]!=mvalo[0]) || (dir=='h' && mval[1]!=mvalo[1])) {
if (!first) {
scrarea_draw_splitpoint(sa, dir, fac);
}
@@ -3409,7 +3420,7 @@ static void moveareas(ScrEdge *edge)
{
ScrVert *v1;
ScrArea *sa;
- short mvalo[2];
+ short mvalo[2], mval_prev=-1;
short edge_start, edge_end, edge_position;
short bigger, smaller, headery, areaminy;
int delta, doit;
@@ -3498,13 +3509,18 @@ static void moveareas(ScrEdge *edge)
short mval[2];
getmouseco_sc(mval);
-
- draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end);
+ if ((dir=='h' && mval_prev != mval[1]) || (dir=='v' && mval_prev != mval[0])) {
+ /* update the previous val with this one for comparison next loop */
+ if (dir=='h') mval_prev = mval[1];
+ else mval_prev = mval[0];
+
+ draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end);
- delta= (dir=='h')?(mval[1]-mvalo[1]):(mval[0]-mvalo[0]);
- delta= CLAMPIS(delta, -smaller, bigger);
- draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end);
- bglFlush();
+ delta= (dir=='h')?(mval[1]-mvalo[1]):(mval[0]-mvalo[0]);
+ delta= CLAMPIS(delta, -smaller, bigger);
+ draw_front_xor_dirdist_line(dir, edge_position+delta, edge_start, edge_end);
+ bglFlush();
+ }
}
else if (event==LEFTMOUSE) {
doit= 1;
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index 1677fe49c59..10d6187fc76 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -83,6 +83,7 @@
#include "BIF_editview.h"
#include "BIF_scrarea.h"
#include "BIF_editsound.h"
+#include "BIF_imasel.h"
#include "BSE_edit.h"
#include "BSE_sequence.h"
@@ -90,6 +91,7 @@
#include "BSE_filesel.h"
#include "BSE_drawipo.h"
#include "BSE_seqaudio.h"
+#include "BSE_time.h"
#include "BDR_editobject.h"
@@ -109,8 +111,14 @@ char last_sounddir[FILE_MAXDIR+FILE_MAXFILE]= "";
#define SEQ_DESEL ~(SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL)
-static int test_overlap_seq(Sequence *);
-static void shuffle_seq(Sequence *);
+typedef struct TransSeq {
+ int start, machine;
+ int startstill, endstill;
+ int startdisp, enddisp;
+ int startofs, endofs;
+ int final_left, final_right;
+ int len;
+} TransSeq;
Sequence *get_last_seq()
{
@@ -137,12 +145,134 @@ void set_last_seq(Sequence *seq)
_last_seq_init = 1;
}
-void clear_last_seq()
+void clear_last_seq(Sequence *seq)
{
_last_seq = NULL;
_last_seq_init = 0;
}
+Sequence *get_forground_frame_seq(int frame)
+{
+ Editing *ed;
+ Sequence *seq, *best_seq=NULL;
+ int best_machine = -1;
+ ed= G.scene->ed;
+ if(!ed) return NULL;
+
+ for (seq=ed->seqbasep->first; seq; seq= seq->next) {
+ if(seq->startdisp > frame || seq->enddisp <= frame)
+ continue;
+ /* only use elements you can see - not */
+ if (ELEM6(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_MOVIE_AND_HD_SOUND, SEQ_COLOR)) {
+ if (seq->machine > best_machine) {
+ best_seq = seq;
+ best_machine = seq->machine;
+ }
+ }
+ }
+ return best_seq;
+}
+
+/* seq funcs's for transforming internally
+ notice the difference between start/end and left/right.
+
+ left and right are the bounds at which the setuence is rendered,
+start and end are from the start and fixed length of the sequence.
+*/
+int seq_tx_get_start(Sequence *seq) {
+ return seq->start;
+}
+int seq_tx_get_end(Sequence *seq)
+{
+ return seq->start+seq->len;
+}
+
+int seq_tx_get_final_left(Sequence *seq)
+{
+ return (seq->start - seq->startstill) + seq->startofs;
+}
+int seq_tx_get_final_right(Sequence *seq)
+{
+ return ((seq->start+seq->len) + seq->endstill) - seq->endofs;
+}
+
+void seq_tx_set_final_left(Sequence *seq, int val)
+{
+ if (val < (seq)->start) {
+ seq->startstill = abs(val - (seq)->start);
+ (seq)->startofs = 0;
+ } else {
+ seq->startofs = abs(val - (seq)->start);
+ seq->startstill = 0;
+ }
+}
+
+void seq_tx_set_final_right(Sequence *seq, int val)
+{
+ if (val > (seq)->start + (seq)->len) {
+ seq->endstill = abs(val - (seq->start + (seq)->len));
+ (seq)->endofs = 0;
+ } else {
+ seq->endofs = abs(val - ((seq)->start + (seq)->len));
+ seq->endstill = 0;
+ }
+}
+
+/* check if one side can be transformed */
+int seq_tx_check_left(Sequence *seq)
+{
+ if (seq->flag & SELECT) {
+ if (seq->flag & SEQ_LEFTSEL)
+ return 1;
+ else if (seq->flag & SEQ_RIGHTSEL)
+ return 0;
+
+ return 1; /* selected and neither left or right handles are, so let us move both */
+ }
+ return 0;
+}
+
+int seq_tx_check_right(Sequence *seq)
+{
+ if (seq->flag & SELECT) {
+ if (seq->flag & SEQ_RIGHTSEL)
+ return 1;
+ else if (seq->flag & SEQ_LEFTSEL)
+ return 0;
+
+ return 1; /* selected and neither left or right handles are, so let us move both */
+ }
+ return 0;
+}
+
+/* used so we can do a quick check for single image seq
+ since they work a bit differently to normal image seq's (during transform) */
+int check_single_seq(Sequence *seq)
+{
+ if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR))
+ return 1;
+ else
+ return 0;
+}
+
+static void fix_single_image_seq(Sequence *seq)
+{
+ int left, start, offset;
+ if (!check_single_seq(seq))
+ return;
+
+ /* make sure the image is always at the start since there is only one,
+ adjusting its start should be ok */
+ left = seq_tx_get_final_left(seq);
+ start = seq->start;
+ if (start != left) {
+ offset = left - start;
+ seq_tx_set_final_left( seq, seq_tx_get_final_left(seq) - offset );
+ seq_tx_set_final_right( seq, seq_tx_get_final_right(seq) - offset );
+ seq->start += offset;
+ }
+}
+
static void change_plugin_seq(char *str) /* called from fileselect */
{
struct SeqEffectHandle sh;
@@ -160,7 +290,7 @@ static void change_plugin_seq(char *str) /* called from fileselect */
if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
- BIF_undo_push("Load/change Sequencer plugin");
+ BIF_undo_push("Load/Change Plugin, Sequencer");
}
@@ -201,6 +331,102 @@ int sequence_is_free_transformable(Sequence * seq)
|| (get_sequence_effect_num_inputs(seq->type) == 0);
}
+char mouse_cfra_side( int frame ) {
+ short mval[2];
+ float xmouse, ymouse;
+ getmouseco_areawin(mval);
+
+ /* choose the side based on which side of the playhead the mouse is on */
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ return (xmouse > frame) ? 'R' : 'L';
+}
+
+Sequence *find_neighboring_sequence(Sequence *test, int lr, int sel) {
+/* looks to the left on lr==1, to the right on lr==2
+ sel - 0==unselected, 1==selected, -1==done care*/
+ Sequence *seq;
+ Editing *ed;
+
+ ed= G.scene->ed;
+ if(ed==0) return 0;
+
+ if (sel>0) sel = SELECT;
+
+ seq= ed->seqbasep->first;
+ while(seq) {
+ if( (seq!=test) &&
+ (test->machine==seq->machine) &&
+ (test->depth==seq->depth) &&
+ ((sel == -1) || (sel && (seq->flag & SELECT)) || (sel==0 && (seq->flag & SELECT)==0) ))
+ {
+ switch (lr) {
+ case 1:
+ if (test->startdisp == (seq->enddisp)) {
+ return seq;
+ }
+ break;
+ case 2:
+ if (test->enddisp == (seq->startdisp)) {
+ return seq;
+ }
+ break;
+ }
+ }
+ seq= seq->next;
+ }
+ return NULL;
+}
+
+Sequence *find_next_prev_sequence(Sequence *test, int lr, int sel) {
+/* looks to the left on lr==1, to the right on lr==2
+ sel - 0==unselected, 1==selected, -1==done care*/
+ Sequence *seq,*best_seq = NULL;
+ Editing *ed;
+
+ int dist, best_dist;
+ best_dist = MAXFRAME*2;
+
+ ed= G.scene->ed;
+ if(ed==0) return 0;
+
+ if (sel) sel = SELECT;
+
+ seq= ed->seqbasep->first;
+ while(seq) {
+ if( (seq!=test) &&
+ (test->machine==seq->machine) &&
+ (test->depth==seq->depth) &&
+ ((sel == -1) || (sel==(seq->flag & SELECT))))
+ {
+ dist = MAXFRAME*2;
+
+ switch (lr) {
+ case 1:
+ if (seq->enddisp <= test->startdisp) {
+ dist = test->enddisp - seq->startdisp;
+ }
+ break;
+ case 2:
+ if (seq->startdisp >= test->enddisp) {
+ dist = seq->startdisp - test->enddisp;
+ }
+ break;
+ }
+
+ if (dist==0) {
+ best_seq = seq;
+ break;
+ } else if (dist < best_dist) {
+ best_dist = dist;
+ best_seq = seq;
+ }
+ }
+ seq= seq->next;
+ }
+ return best_seq; /* can be null */
+}
+
+
Sequence *find_nearest_seq(int *hand)
{
Sequence *seq;
@@ -209,7 +435,7 @@ Sequence *find_nearest_seq(int *hand)
short mval[2];
float pixelx;
float handsize;
- float minhandle, maxhandle;
+ float displen;
View2D *v2d = G.v2d;
*hand= 0;
@@ -224,22 +450,33 @@ Sequence *find_nearest_seq(int *hand)
seq= ed->seqbasep->first;
while(seq) {
- /* clamp handles to defined size in pixel space */
- handsize = seq->handsize;
- minhandle = 7;
- maxhandle = 28;
- CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
-
if(seq->machine == (int)y) {
/* check for both normal strips, and strips that have been flipped horizontally */
if( ((seq->startdisp < seq->enddisp) && (seq->startdisp<=x && seq->enddisp>=x)) ||
((seq->startdisp > seq->enddisp) && (seq->startdisp>=x && seq->enddisp<=x)) )
{
if(sequence_is_free_transformable(seq)) {
- if( handsize+seq->startdisp >=x )
- *hand= 1;
- else if( -handsize+seq->enddisp <=x )
- *hand= 2;
+
+ /* clamp handles to defined size in pixel space */
+
+ handsize = seq->handsize;
+ displen = (float)abs(seq->startdisp - seq->enddisp);
+
+ if (displen / pixelx > 16) { /* dont even try to grab the handles of small strips */
+ /* Set the max value to handle to 1/3 of the total len when its less then 28.
+ * This is important because otherwise selecting handles happens even when you click in the middle */
+
+ if ((displen/3) < 30*pixelx) {
+ handsize = displen/3;
+ } else {
+ CLAMP(handsize, 7*pixelx, 30*pixelx);
+ }
+
+ if( handsize+seq->startdisp >=x )
+ *hand= 1;
+ else if( -handsize+seq->enddisp <=x )
+ *hand= 2;
+ }
}
return seq;
}
@@ -297,7 +534,7 @@ void update_seq_icu_rects(Sequence * seq)
}
}
-static int test_overlap_seq(Sequence *test)
+int test_overlap_seq(Sequence *test)
{
Sequence *seq;
Editing *ed;
@@ -320,7 +557,7 @@ static int test_overlap_seq(Sequence *test)
return 0;
}
-static void shuffle_seq(Sequence *test)
+void shuffle_seq(Sequence *test)
{
Editing *ed;
Sequence *seq;
@@ -395,7 +632,7 @@ static void deselect_all_seq(void)
}
END_SEQ
- BIF_undo_push("(De)select all Sequencer");
+ BIF_undo_push("(De)select all Strips, Sequencer");
}
static void recurs_sel_seq(Sequence *seqm)
@@ -437,60 +674,253 @@ void swap_select_seq(void)
END_SEQ
allqueue(REDRAWSEQ, 0);
- BIF_undo_push("Swap select all Sequencer");
+ BIF_undo_push("Swap Selected Strips, Sequencer");
}
-void mouse_select_seq(void)
-{
+void select_channel_direction(Sequence *test,int lr) {
+/* selects all strips in a channel to one direction of the passed strip */
Sequence *seq;
- int hand;
+ Editing *ed;
- seq= find_nearest_seq(&hand);
+ ed= G.scene->ed;
+ if(ed==0) return;
- if(!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+ seq= ed->seqbasep->first;
+ while(seq) {
+ if(seq!=test) {
+ if (test->machine==seq->machine) {
+ if(test->depth==seq->depth) {
+ if (((lr==1)&&(test->startdisp > (seq->startdisp)))||((lr==2)&&(test->startdisp < (seq->startdisp)))) {
+ seq->flag |= SELECT;
+ recurs_sel_seq(seq);
+ }
+ }
+ }
+ }
+ seq= seq->next;
+ }
+ test->flag |= SELECT;
+ recurs_sel_seq(test);
+}
- if(seq) {
- set_last_seq(seq);
+void select_dir_from_last(int lr)
+{
+ Sequence *seq=get_last_seq();
+ if (seq==NULL)
+ return;
+
+ select_channel_direction(seq,lr);
+ allqueue(REDRAWSEQ, 0);
+
+ if (lr==1) BIF_undo_push("Select Strips to the Left, Sequencer");
+ else BIF_undo_push("Select Strips to the Right, Sequencer");
+}
- if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
- if(seq->strip) {
- strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
- }
- } else
- if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
- if(seq->strip) {
- strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
+void select_surrounding_handles(Sequence *test)
+{
+ Sequence *neighbor;
+
+ neighbor=find_neighboring_sequence(test, 1, -1);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_RIGHTSEL;
+ }
+ neighbor=find_neighboring_sequence(test, 2, -1);
+ if (neighbor) {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_LEFTSEL;
+ }
+ test->flag |= SELECT;
+}
+
+void select_surround_from_last()
+{
+ Sequence *seq=get_last_seq();
+
+ if (seq==NULL)
+ return;
+
+ select_surrounding_handles(seq);
+ allqueue(REDRAWSEQ, 0);
+ BIF_undo_push("Select Surrounding Handles, Sequencer");
+}
+
+void select_neighbor_from_last(int lr)
+{
+ Sequence *seq=get_last_seq();
+ Sequence *neighbor;
+ int change = 0;
+ if (seq) {
+ neighbor=find_neighboring_sequence(seq, lr, -1);
+ if (neighbor) {
+ switch (lr) {
+ case 1:
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_RIGHTSEL;
+ seq->flag |= SEQ_LEFTSEL;
+ break;
+ case 2:
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_LEFTSEL;
+ seq->flag |= SEQ_RIGHTSEL;
+ break;
}
+ seq->flag |= SELECT;
+ change = 1;
}
+ }
+ if (change) {
+ allqueue(REDRAWSEQ, 0);
+
+ if (lr==1) BIF_undo_push("Select Left Handles, Sequencer");
+ else BIF_undo_push("Select Right Handles, Sequencer");
+ }
+}
- if((G.qual & LR_SHIFTKEY) && (seq->flag & SELECT)) {
- if(hand==0) seq->flag &= SEQ_DESEL;
- else if(hand==1) {
- if(seq->flag & SEQ_LEFTSEL)
- seq->flag &= ~SEQ_LEFTSEL;
- else seq->flag |= SEQ_LEFTSEL;
- }
- else if(hand==2) {
- if(seq->flag & SEQ_RIGHTSEL)
- seq->flag &= ~SEQ_RIGHTSEL;
- else seq->flag |= SEQ_RIGHTSEL;
- }
+void mouse_select_seq(void)
+{
+ Sequence *seq,*neighbor;
+ int hand,seldir;
+ TimeMarker *marker;
+
+ marker=find_nearest_marker(SCE_MARKERS, 1);
+
+ if (marker) {
+ int oldflag;
+ /* select timeline marker */
+ if (G.qual & LR_SHIFTKEY) {
+ oldflag= marker->flag;
+ deselect_markers(0, 0);
+
+ if (oldflag & SELECT)
+ marker->flag &= ~SELECT;
+ else
+ marker->flag |= SELECT;
}
else {
- seq->flag |= SELECT;
- if(hand==1) seq->flag |= SEQ_LEFTSEL;
- if(hand==2) seq->flag |= SEQ_RIGHTSEL;
+ marker->flag |= SELECT;
}
- recurs_sel_seq(seq);
- }
+ allqueue(REDRAWMARKER, 0);
+ force_draw(0);
+
+ BIF_undo_push("Select Strips, Sequencer");
+
+ } else {
+
+ seq= find_nearest_seq(&hand);
+ if(!(G.qual & LR_SHIFTKEY)&&!(G.qual & LR_ALTKEY)&&!(G.qual & LR_CTRLKEY)) deselect_all_seq();
+
+ if(seq) {
+ set_last_seq(seq);
+
+ if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
+ if(seq->strip) {
+ strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
+ }
+ } else
+ if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
+ if(seq->strip) {
+ strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
+ }
+ }
+
+ if((G.qual & LR_SHIFTKEY) && (seq->flag & SELECT)) {
+ if(hand==0) seq->flag &= SEQ_DESEL;
+ else if(hand==1) {
+ if(seq->flag & SEQ_LEFTSEL)
+ seq->flag &= ~SEQ_LEFTSEL;
+ else seq->flag |= SEQ_LEFTSEL;
+ }
+ else if(hand==2) {
+ if(seq->flag & SEQ_RIGHTSEL)
+ seq->flag &= ~SEQ_RIGHTSEL;
+ else seq->flag |= SEQ_RIGHTSEL;
+ }
+ }
+ else {
+ seq->flag |= SELECT;
+ if(hand==1) seq->flag |= SEQ_LEFTSEL;
+ if(hand==2) seq->flag |= SEQ_RIGHTSEL;
+ }
+
+ /* On Ctrl-Alt selection, select the strip and bordering handles */
+ if ((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) {
+ if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+ seq->flag |= SELECT;
+ select_surrounding_handles(seq);
+
+ /* Ctrl signals Left, Alt signals Right
+ First click selects adjacent handles on that side.
+ Second click selects all strips in that direction.
+ If there are no adjacent strips, it just selects all in that direction. */
+ } else if (((G.qual & LR_CTRLKEY) || (G.qual & LR_ALTKEY)) && (seq->flag & SELECT)) {
+
+ if (G.qual & LR_CTRLKEY) seldir=1;
+ else seldir=2;
+ neighbor=find_neighboring_sequence(seq, seldir, -1);
+ if (neighbor) {
+ switch (seldir) {
+ case 1:
+ if ((seq->flag & SEQ_LEFTSEL)&&(neighbor->flag & SEQ_RIGHTSEL)) {
+ if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+ select_channel_direction(seq,1);
+ } else {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_RIGHTSEL;
+ seq->flag |= SEQ_LEFTSEL;
+ }
+ break;
+ case 2:
+ if ((seq->flag & SEQ_RIGHTSEL)&&(neighbor->flag & SEQ_LEFTSEL)) {
+ if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+ select_channel_direction(seq,2);
+ } else {
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_LEFTSEL;
+ seq->flag |= SEQ_RIGHTSEL;
+ }
+ break;
+ }
+ } else {
+ if (!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
+ select_channel_direction(seq,seldir);
+ }
+ }
- force_draw(0);
+ recurs_sel_seq(seq);
+ }
+ force_draw_plus(SPACE_BUTS, 0);
- if(get_last_seq()) allqueue(REDRAWIPO, 0);
- BIF_undo_push("Select Sequencer");
+ if(get_last_seq()) allqueue(REDRAWIPO, 0);
+ BIF_undo_push("Select Strips, Sequencer");
- std_rmouse_transform(transform_seq);
+ std_rmouse_transform(transform_seq_nomarker);
+ }
+
+ /* marker transform */
+ if (marker) {
+ short mval[2], xo, yo;
+ getmouseco_areawin(mval);
+ xo= mval[0];
+ yo= mval[1];
+
+ while(get_mbut()&R_MOUSE) {
+ getmouseco_areawin(mval);
+ if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) {
+ transform_markers('g', 0);
+ allqueue(REDRAWMARKER, 0);
+ return;
+ }
+ BIF_wait_for_statechange();
+ }
+ }
}
@@ -512,6 +942,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
seq->start= cfra;
seq->machine= machine;
seq->mul= 1.0;
+ seq->blend_opacity = 100.0;
return seq;
}
@@ -522,7 +953,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
Strip *strip;
StripElem *se;
int totsel, a;
- char name[160], rel[160];
+ char name[160];
/* are there selected files? */
totsel= 0;
@@ -554,8 +985,7 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
if(sfile->flag & FILE_STRINGCODE) {
strcpy(name, sfile->dir);
- strcpy(rel, G.sce);
- BLI_makestringcode(rel, name);
+ BLI_makestringcode(G.sce, name);
} else {
strcpy(name, sfile->dir);
}
@@ -571,7 +1001,6 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
if(sfile->filelist[a].flags & ACTIVE) {
if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
strncpy(se->name, sfile->filelist[a].relname, FILE_MAXFILE-1);
- se->ok= 1;
se++;
}
}
@@ -579,7 +1008,6 @@ static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int
/* no selected file: */
if(totsel==1 && se==strip->stripdata) {
strncpy(se->name, sfile->file, FILE_MAXFILE-1);
- se->ok= 1;
}
/* last active name */
@@ -596,8 +1024,8 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
struct anim *anim;
Strip *strip;
StripElem *se;
- int totframe, a;
- char name[160], rel[160];
+ int totframe;
+ char name[160];
char str[FILE_MAXDIR+FILE_MAXFILE];
totframe= 0;
@@ -629,8 +1057,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
if(sfile->flag & FILE_STRINGCODE) {
strcpy(name, sfile->dir);
- strcpy(rel, G.sce);
- BLI_makestringcode(rel, name);
+ BLI_makestringcode(G.sce, name);
} else {
strcpy(name, sfile->dir);
}
@@ -640,7 +1067,7 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
strip->len= totframe;
strip->us= 1;
strncpy(strip->dir, name, FILE_MAXDIR-1);
- strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+ strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
/* name movie in first strip */
if(index<0)
@@ -648,11 +1075,6 @@ static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra,
else
strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
- for(a=1; a<=totframe; a++, se++) {
- se->ok= 1;
- se->nr= a;
- }
-
/* last active name */
strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
return(cfra+totframe);
@@ -697,8 +1119,7 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
Strip *strip;
StripElem *se;
double totframe;
- int a;
- char name[160], rel[160];
+ char name[160];
char str[256];
totframe= 0.0;
@@ -719,7 +1140,8 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
sound->flags |= SOUND_FLAGS_SEQUENCE;
audio_makestream(sound);
- totframe= (int) ( ((float)(sound->streamlen-1)/( (float)G.scene->audio.mixrate*4.0 ))* (float)G.scene->r.frs_sec);
+ totframe= (int) ( ((float)(sound->streamlen-1)/
+ ( (float)G.scene->audio.mixrate*4.0 ))* FPS);
/* make seq */
seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
@@ -731,8 +1153,7 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
if(sfile->flag & FILE_STRINGCODE) {
strcpy(name, sfile->dir);
- strcpy(rel, G.sce);
- BLI_makestringcode(rel, name);
+ BLI_makestringcode(G.sce, name);
} else {
strcpy(name, sfile->dir);
}
@@ -742,17 +1163,11 @@ static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile,
strip->len= totframe;
strip->us= 1;
strncpy(strip->dir, name, FILE_MAXDIR-1);
- strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+ strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
/* name sound in first strip */
strncpy(se->name, sfile->file, FILE_MAXFILE-1);
- for(a=1; a<=totframe; a++, se++) {
- se->ok= 2; /* why? */
- se->ibuf= 0;
- se->nr= a;
- }
-
/* last active name */
strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
@@ -766,8 +1181,8 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
struct hdaudio *hdaudio;
Strip *strip;
StripElem *se;
- int totframe, a;
- char name[160], rel[160];
+ int totframe;
+ char name[160];
char str[FILE_MAXDIR+FILE_MAXFILE];
totframe= 0;
@@ -786,7 +1201,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
return(cfra);
}
- totframe= sound_hdaudio_get_duration(hdaudio, G.scene->r.frs_sec);
+ totframe= sound_hdaudio_get_duration(hdaudio, FPS);
/* make seq */
seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
@@ -798,8 +1213,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
if(sfile->flag & FILE_STRINGCODE) {
strcpy(name, sfile->dir);
- strcpy(rel, G.sce);
- BLI_makestringcode(rel, name);
+ BLI_makestringcode(G.sce, name);
} else {
strcpy(name, sfile->dir);
}
@@ -809,7 +1223,7 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
strip->len= totframe;
strip->us= 1;
strncpy(strip->dir, name, FILE_MAXDIR-1);
- strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
+ strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
/* name movie in first strip */
if(index<0)
@@ -817,12 +1231,6 @@ static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra,
else
strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
- for(a=1; a<=totframe; a++, se++) {
- se->ok= 2;
- se->ibuf = 0;
- se->nr= a;
- }
-
/* last active name */
strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
return(cfra+totframe);
@@ -917,8 +1325,8 @@ static void add_image_strips(char *name)
waitcursor(0);
- BIF_undo_push("Add image strip Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Image Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
}
@@ -952,8 +1360,8 @@ static void add_movie_strip(char *name)
waitcursor(0);
- BIF_undo_push("Add movie strip Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Movie Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
}
@@ -988,8 +1396,8 @@ static void add_movie_and_hdaudio_strip(char *name)
waitcursor(0);
- BIF_undo_push("Add movie and HD-audio strip Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Movie and HD-Audio Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
}
@@ -1017,8 +1425,8 @@ static void add_sound_strip_ram(char *name)
waitcursor(0);
- BIF_undo_push("Add ram sound strip Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Sound (RAM) Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
}
static void add_sound_strip_hd(char *name)
@@ -1045,8 +1453,52 @@ static void add_sound_strip_hd(char *name)
waitcursor(0);
- BIF_undo_push("Add hd sound strip Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Sound (HD) Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
+}
+
+static void add_scene_strip(short event)
+{
+ Sequence *seq;
+ Strip *strip;
+ float x, y;
+ int cfra, machine;
+ short mval[2];
+
+ if(event> -1) {
+ int nr= 1;
+ Scene * sce= G.main->scene.first;
+ while(sce) {
+ if( event==nr) break;
+ nr++;
+ sce= sce->id.next;
+ }
+ if(sce) {
+
+ deselect_all_seq();
+
+ /* where ? */
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &x, &y);
+ cfra= (int)(x+0.5);
+ machine= (int)(y+0.5);
+
+ seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
+ seq->type= SEQ_SCENE;
+ seq->scene= sce;
+ seq->sfra= sce->r.sfra;
+ seq->len= sce->r.efra - sce->r.sfra + 1;
+
+ seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
+ strncpy(seq->name + 2, sce->id.name + 2,
+ sizeof(seq->name) - 2);
+ strip->len= seq->len;
+ strip->us= 1;
+
+ BIF_undo_push("Add Scene Strip, Sequencer");
+ transform_seq_nomarker('g', 0);
+ }
+ }
}
#if 0
@@ -1188,8 +1640,8 @@ static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type,
switch(get_sequence_effect_num_inputs(type)) {
case 0:
- seq1 = seq2 = seq3 = 0;
- break;
+ *selseq1 = *selseq2 = *selseq3 = 0;
+ return 1;
case 1:
if(seq2==0) {
error("Need at least one selected sequence strip");
@@ -1204,7 +1656,9 @@ static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type,
}
if(seq3==0) seq3= seq2;
}
-
+
+ if (seq1==NULL && seq2==NULL && seq3==NULL) return 0;
+
*selseq1= seq1;
*selseq2= seq2;
*selseq3= seq3;
@@ -1286,12 +1740,12 @@ static int add_seq_effect(int type, char *str)
/* push undo and go into grab mode */
if(newseq->type == SEQ_PLUGIN) {
- BIF_undo_push("Add plugin strip Sequencer");
+ BIF_undo_push("Add Plugin Strip, Sequencer");
} else {
- BIF_undo_push("Add effect strip Sequencer");
+ BIF_undo_push("Add Effect Strip, Sequencer");
}
- transform_seq('g', 0);
+ transform_seq_nomarker('g', 0);
return 1;
}
@@ -1304,12 +1758,7 @@ static void load_plugin_seq(char *str) /* called from fileselect */
void add_sequence(int type)
{
Editing *ed;
- Sequence *seq;
- Strip *strip;
- Scene *sce;
- float x, y;
- int cfra, machine;
- short nr, event, mval[2];
+ short event;
char *str;
if (type >= 0){
@@ -1382,7 +1831,7 @@ void add_sequence(int type)
}
else {
event= pupmenu("Add Sequence Strip%t"
- "|Images%x1"
+ "|Image Sequence%x1"
"|Movie%x102"
#ifdef WITH_FFMPEG
"|Movie + Audio (HD)%x105"
@@ -1418,8 +1867,11 @@ void add_sequence(int type)
switch(event) {
case 1:
-
- activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
+ /* Image Dosnt work at the moment - TODO */
+ //if(G.qual & LR_CTRLKEY)
+ // activate_imageselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
+ //else
+ activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
break;
case 105:
activate_fileselect(FILE_SPECIAL, "Select Movie+Audio", last_imagename, add_movie_and_hdaudio_strip);
@@ -1432,43 +1884,8 @@ void add_sequence(int type)
/* new menu: */
IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL);
- event= pupmenu_col(str, 20);
+ add_scene_strip(pupmenu_col(str, 20));
- if(event> -1) {
- nr= 1;
- sce= G.main->scene.first;
- while(sce) {
- if( event==nr) break;
- nr++;
- sce= sce->id.next;
- }
- if(sce) {
-
- deselect_all_seq();
-
- /* where ? */
- getmouseco_areawin(mval);
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- cfra= (int)(x+0.5);
- machine= (int)(y+0.5);
-
- seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
- seq->type= SEQ_SCENE;
- seq->scene= sce;
- seq->sfra= sce->r.sfra;
- seq->len= sce->r.efra - sce->r.sfra + 1;
-
- seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
- strncpy(seq->name + 2, sce->id.name + 2,
- sizeof(seq->name) - 2);
- strip->len= seq->len;
- strip->us= 1;
- if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-
- BIF_undo_push("Add scene strip Sequencer");
- transform_seq('g', 0);
- }
- }
MEM_freeN(str);
break;
@@ -1571,7 +1988,7 @@ void change_sequence(void)
update_changed_seq_and_deps(last_seq, 0, 1);
allqueue(REDRAWSEQ, 0);
- BIF_undo_push("Change effect Sequencer");
+ BIF_undo_push("Change Strip Effect, Sequencer");
}
}
else if(last_seq->type == SEQ_IMAGE) {
@@ -1593,6 +2010,10 @@ void change_sequence(void)
last_seq->len= sce->r.efra - sce->r.sfra + 1;
last_seq->sfra= sce->r.sfra;
+
+ /* bad code to change seq->len? update_changed_seq_and_deps() expects the strip->len to be OK */
+ new_tstripdata(last_seq);
+
update_changed_seq_and_deps(last_seq, 1, 1);
allqueue(REDRAWSEQ, 0);
@@ -1601,6 +2022,19 @@ void change_sequence(void)
}
+void reload_sequence(void)
+{
+ Editing *ed= G.scene->ed;
+ Sequence *seq;
+ WHILE_SEQ(ed->seqbasep) {
+ if(seq->flag & SELECT) {
+ update_changed_seq_and_deps(seq, 0, 1);
+ }
+ }
+ END_SEQ
+ allqueue(REDRAWSEQ, 0);
+}
+
void reassign_inputs_seq_effect()
{
Editing *ed= G.scene->ed;
@@ -1728,165 +2162,262 @@ void del_seq(void)
ms= ms->prev;
}
- BIF_undo_push("Delete from Sequencer");
+ BIF_undo_push("Delete Strip(s), Sequencer");
allqueue(REDRAWSEQ, 0);
}
-static void recurs_dupli_seq(ListBase *old, ListBase *new)
+static Sequence *dupli_seq(Sequence *seq)
{
- Sequence *seq, *seqn;
- Sequence *last_seq = get_last_seq();
- StripElem *se;
- int a;
+ Sequence *seqn = MEM_dupallocN(seq);
- seq= old->first;
-
- while(seq) {
- seq->newseq= 0;
- if(seq->flag & SELECT) {
+ seq->tmp = seqn;
+
+ seqn->strip= MEM_dupallocN(seq->strip);
- if(seq->type==SEQ_META) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
+ if(seqn->ipo) seqn->ipo->id.us++;
- seqn->strip= MEM_dupallocN(seq->strip);
+ seqn->strip->tstripdata = 0;
+ seqn->strip->tstripdata_startstill = 0;
+ seqn->strip->tstripdata_endstill = 0;
+ seqn->strip->ibuf_startstill = 0;
+ seqn->strip->ibuf_endstill = 0;
- if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+ if (seq->strip->crop) {
+ seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
+ }
- seq->flag &= SEQ_DESEL;
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
+ if (seq->strip->transform) {
+ seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
+ }
- seqn->seqbase.first= seqn->seqbase.last= 0;
- recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);
+ if (seq->strip->proxy) {
+ seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
+ }
- }
- else if(seq->type == SEQ_SCENE) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
+ if (seq->strip->color_balance) {
+ seqn->strip->color_balance
+ = MEM_dupallocN(seq->strip->color_balance);
+ }
+
+ if(seq->type==SEQ_META) {
+ seqn->strip->stripdata = 0;
+
+ seqn->seqbase.first= seqn->seqbase.last= 0;
+ /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
+ /* - recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);*/
+ } else if(seq->type == SEQ_SCENE) {
+ seqn->strip->stripdata = 0;
+ } else if(seq->type == SEQ_MOVIE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ seqn->anim= 0;
+ } else if(seq->type == SEQ_RAM_SOUND) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ seqn->sound->id.us++;
+ } else if(seq->type == SEQ_HD_SOUND) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ seqn->hdaudio = 0;
+ } else if(seq->type == SEQ_IMAGE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ } else if(seq->type >= SEQ_EFFECT) {
+ if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
+ if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
+ if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
+
+ if (seq->type & SEQ_EFFECT) {
+ struct SeqEffectHandle sh;
+ sh = get_sequence_effect(seq);
+ if(sh.copy)
+ sh.copy(seq, seqn);
+ }
- seqn->strip= MEM_dupallocN(seq->strip);
+ seqn->strip->stripdata = 0;
+
+ } else {
+ fprintf(stderr, "Aiiiiekkk! sequence type not "
+ "handled in duplicate!\nExpect a crash"
+ " now...\n");
+ }
+
+ return seqn;
+}
- if(seq->len>0) seqn->strip->stripdata = MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+static void recurs_dupli_seq(ListBase *old, ListBase *new)
+{
+ Sequence *seq;
+ Sequence *seqn = 0;
+ Sequence *last_seq = get_last_seq();
+ for(seq= old->first; seq; seq= seq->next) {
+ seq->tmp= NULL;
+ if(seq->flag & SELECT) {
+ seqn = dupli_seq(seq);
+ if (seqn) { /*should never fail */
seq->flag &= SEQ_DESEL;
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
- }
- else if(seq->type == SEQ_MOVIE) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
+ seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
- seqn->strip= MEM_dupallocN(seq->strip);
- seqn->anim= 0;
-
- if(seqn->len>0) {
- seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- /* copy first elem */
- *seqn->strip->stripdata= *seq->strip->stripdata;
- se= seqn->strip->stripdata;
- a= seq->len;
- while(a--) {
- se->ok= 1;
- se++;
- }
+ BLI_addtail(new, seqn);
+ if(seq->type==SEQ_META)
+ recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);
+
+ if (seq == last_seq) {
+ set_last_seq(seqn);
}
-
- seq->flag &= SEQ_DESEL;
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
}
- else if(seq->type == SEQ_RAM_SOUND) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
+ }
+ }
+}
+
+/* like duplicate, but only duplicate and cut overlapping strips,
+ * strips to the left of the cutframe are ignored and strips to the right are moved into the new list */
+static void recurs_cut_seq(ListBase *old, ListBase *new, int cutframe)
+{
+ Sequence *seq, *seq_next;
+ Sequence *seqn = 0;
+
+ TransSeq ts;
- seqn->strip= MEM_dupallocN(seq->strip);
- seqn->anim= 0;
- seqn->sound->id.us++;
- if(seqn->ipo) seqn->ipo->id.us++;
-
- if(seqn->len>0) {
- seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- /* copy first elem */
- *seqn->strip->stripdata= *seq->strip->stripdata;
- se= seqn->strip->stripdata;
- a= seq->len;
- while(a--) {
- se->ok= 1;
- se++;
+ seq= old->first;
+
+ while(seq) {
+ seq_next = seq->next; /* we need this because we may remove seq */
+
+ seq->tmp= NULL;
+ if(seq->flag & SELECT) {
+ if(cutframe > seq->startdisp && cutframe < seq->enddisp) {
+
+ /* backup values */
+ ts.start= seq->start;
+ ts.machine= seq->machine;
+ ts.startstill= seq->startstill;
+ ts.endstill= seq->endstill;
+ ts.startdisp= seq->startdisp;
+ ts.enddisp= seq->enddisp;
+ ts.startofs= seq->startofs;
+ ts.endofs= seq->endofs;
+ ts.len= seq->len;
+
+ /* First Strip! */
+ /* strips with extended stillfames before */
+ if(seq->type!=SEQ_META) {
+
+ if ((seq->startstill) && (cutframe <seq->start)) {
+ seq->start= cutframe -1;
+ seq->startstill= cutframe -seq->startdisp -1;
+ seq->len= 1;
+ seq->endstill= 0;
+ }
+
+ /* normal strip */
+ else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
+ seq->endofs = (seq->start+seq->len) - cutframe;
}
+
+ /* strips with extended stillframes after */
+ else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
+ seq->endstill -= seq->enddisp - cutframe;
+ }
+
+ calc_sequence(seq);
}
-
- seq->flag &= SEQ_DESEL;
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
- }
- else if(seq->type == SEQ_HD_SOUND) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
-
- seqn->strip= MEM_dupallocN(seq->strip);
- seqn->anim= 0;
- seqn->hdaudio = 0;
- if(seqn->ipo) seqn->ipo->id.us++;
-
- if(seqn->len>0) {
- seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- /* copy first elem */
- *seqn->strip->stripdata= *seq->strip->stripdata;
- se= seqn->strip->stripdata;
- a= seq->len;
- while(a--) {
- se->ok= 1;
- se++;
+
+ /* Duplicate AFTER the first change */
+ seqn = dupli_seq(seq);
+
+ if (seqn) { /* should never fail */
+ seqn->flag |= SELECT;
+
+
+ BLI_addtail(new, seqn);
+
+ /* dont transform meta's - just do their children then recalc */
+ if(seq->type==SEQ_META) {
+ recurs_cut_seq(&seq->seqbase,&seqn->seqbase, cutframe);
+ } else {
+ /* Second Strip! */
+ /* strips with extended stillframes before */
+ if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
+ seqn->start = ts.start;
+ seqn->startstill= ts.start- cutframe;
+ seqn->len = ts.len;
+ seqn->endstill = ts.endstill;
+ }
+
+ /* normal strip */
+ else if ((cutframe>=seqn->start)&&(cutframe<=(seqn->start+seqn->len))) {
+ seqn->startstill = 0;
+ seqn->startofs = cutframe - ts.start;
+ seqn->endofs = ts.endofs;
+ seqn->endstill = ts.endstill;
+ }
+
+ /* strips with extended stillframes after */
+ else if (((seqn->start+seqn->len) < cutframe) && (seqn->endstill)) {
+ seqn->start = cutframe - ts.len +1;
+ seqn->startofs = ts.len-1;
+ seqn->endstill = ts.enddisp - cutframe -1;
+ seqn->startstill = 0;
+ }
}
+
+ if(seq->type==SEQ_META) /* account for strips within changing */
+ calc_sequence(seq);
+
+ calc_sequence(seqn);
}
-
- seq->flag &= SEQ_DESEL;
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
+ } else if (seq->enddisp <= cutframe) {
+ /* do nothing */
+ } else if (seq->startdisp >= cutframe) {
+ /* move into new list */
+ BLI_remlink(old, seq);
+ BLI_addtail(new, seq);
}
- else if(seq->type < SEQ_EFFECT) {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
-
- seqn->strip->us++;
- seq->flag &= SEQ_DESEL;
-
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
- }
- else {
- seqn= MEM_dupallocN(seq);
- seq->newseq= seqn;
- BLI_addtail(new, seqn);
-
- if(seq->seq1 && seq->seq1->newseq) seqn->seq1= seq->seq1->newseq;
- if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
- if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
-
- if(seqn->ipo) seqn->ipo->id.us++;
+ }
+ seq = seq_next;
+ }
+}
- if (seq->type & SEQ_EFFECT) {
- struct SeqEffectHandle sh;
- sh = get_sequence_effect(seq);
- if(sh.copy)
- sh.copy(seq, seqn);
+void seq_cut(int cutframe)
+{
+ Editing *ed;
+ ListBase newlist;
+ char side;
+ ed= G.scene->ed;
+ if(ed==0) return;
+
+ newlist.first= newlist.last= NULL;
+
+ recurs_cut_seq(ed->seqbasep, &newlist, cutframe);
+
+ if (newlist.first) { /* simple check to see if anything was done */
+ Sequence *seq;
+ addlisttolist(ed->seqbasep, &newlist);
+
+
+ /* change the selection, not strictly needed but nice */
+ side = mouse_cfra_side(cutframe);
+
+ WHILE_SEQ(ed->seqbasep) {
+ if (side=='L') {
+ if ( seq->startdisp >= cutframe ) {
+ seq->flag &= ~SELECT;
+ }
+ } else {
+ if ( seq->enddisp <= cutframe ) {
+ seq->flag &= ~SELECT;
}
-
- seqn->strip= MEM_dupallocN(seq->strip);
-
- if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
-
- seq->flag &= SEQ_DESEL;
-
- seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
- }
- if (seq == last_seq) {
- set_last_seq(seqn);
}
}
- seq= seq->next;
+ END_SEQ;
+
+ /* as last: */
+ sort_seq();
+
+ allqueue(REDRAWSEQ, 0);
+ BIF_undo_push("Cut Strips, Sequencer");
}
}
@@ -1903,8 +2434,8 @@ void add_duplicate_seq(void)
recurs_dupli_seq(ed->seqbasep, &new);
addlisttolist(ed->seqbasep, &new);
- BIF_undo_push("Add duplicate Sequencer");
- transform_seq('g', 0);
+ BIF_undo_push("Add Duplicate, Sequencer");
+ transform_seq_nomarker('g', 0);
}
int insert_gap(int gap, int cfra)
@@ -1981,6 +2512,48 @@ void set_filter_seq(void)
}
+void seq_remap_paths(void)
+{
+ Sequence *seq, *last_seq = get_last_seq();
+ Editing *ed;
+ char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
+
+ ed= G.scene->ed;
+ if(ed==NULL || last_seq==NULL)
+ return;
+
+ BLI_strncpy(from, last_seq->strip->dir, FILE_MAX);
+ if (0==sbutton(from, 0, sizeof(from)-1, "From: "))
+ return;
+
+ strcpy(to, from);
+ if (0==sbutton(to, 0, sizeof(to)-1, "To: "))
+ return;
+
+ if (strcmp(to, from)==0)
+ return;
+
+ WHILE_SEQ(ed->seqbasep) {
+ if(seq->flag & SELECT) {
+ if(strncmp(seq->strip->dir, from, strlen(from))==0) {
+ printf("found %s\n", seq->strip->dir);
+
+ /* strip off the beginning */
+ stripped[0]= 0;
+ BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
+
+ /* new path */
+ BLI_strncpy(seq->strip->dir, to, FILE_MAX);
+ strcat(seq->strip->dir, stripped);
+ printf("new %s\n", seq->strip->dir);
+ }
+ }
+ }
+ END_SEQ
+
+ BIF_undo_push("Remap Paths, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+}
void no_gaps(void)
@@ -2005,7 +2578,7 @@ void no_gaps(void)
}
}
- BIF_undo_push("No gaps Sequencer");
+ BIF_undo_push("No Gaps, Sequencer");
allqueue(REDRAWSEQ, 0);
}
@@ -2034,7 +2607,7 @@ void make_meta(void)
}
seq= seq->next;
}
- if(tot < 2) return;
+ if(tot < 1) return;
if(okee("Make Meta Strip")==0) return;
@@ -2087,10 +2660,12 @@ void make_meta(void)
seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
seqm->strip->len= seqm->len;
seqm->strip->us= 1;
- if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
- set_meta_stripdata(seqm);
- BIF_undo_push("Make Meta Sequencer");
+ set_meta_stripdata(seqm);
+
+ if( test_overlap_seq(seqm) ) shuffle_seq(seqm);
+
+ BIF_undo_push("Make Meta Strip, Sequencer");
allqueue(REDRAWSEQ, 0);
}
@@ -2113,7 +2688,7 @@ void un_meta(void)
if(last_seq==0 || last_seq->type!=SEQ_META) return;
- if(okee("Un Meta")==0) return;
+ if(okee("Un Meta Strip")==0) return;
addlisttolist(ed->seqbasep, &last_seq->seqbase);
@@ -2143,7 +2718,7 @@ void un_meta(void)
sort_seq();
- BIF_undo_push("Un-make Meta Sequencer");
+ BIF_undo_push("Un-Make Meta Strip, Sequencer");
allqueue(REDRAWSEQ, 0);
}
@@ -2176,13 +2751,13 @@ void exit_meta(void)
set_last_seq(ms->parseq);
- ms->parseq->flag= SELECT;
+ ms->parseq->flag |= SELECT;
recurs_sel_seq(ms->parseq);
MEM_freeN(ms);
allqueue(REDRAWSEQ, 0);
- BIF_undo_push("Exit meta strip Sequence");
+ BIF_undo_push("Exit Meta Strip, Sequence");
}
@@ -2209,175 +2784,507 @@ void enter_meta(void)
set_last_seq(NULL);
allqueue(REDRAWSEQ, 0);
- BIF_undo_push("Enter meta strip Sequence");
+ BIF_undo_push("Enter Meta Strip, Sequence");
}
/* ****************** END META ************************* */
+static int seq_get_snaplimit(void)
+{
+ /* fake mouse coords to get the snap value
+ a bit lazy but its only done once pre transform */
+ float xmouse, ymouse, x;
+ short mval[2] = {24, 0}; /* 24 screen px snap */
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ x = xmouse;
+ mval[0] = 0;
+ areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
+ return (int)(x - xmouse);
+}
-typedef struct TransSeq {
- int start, machine;
- int startstill, endstill;
- int startdisp, enddisp;
- int startofs, endofs;
- int len;
-} TransSeq;
+/* use to impose limits when dragging/extending - so impossible situations dont happen */
+static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
+{
+ if(leftflag) {
+ if (seq_tx_get_final_left(seq) >= seq_tx_get_final_right(seq)) {
+ seq_tx_set_final_left(seq, seq_tx_get_final_right(seq)-1);
+ }
+
+ if (check_single_seq(seq)==0) {
+ if (seq_tx_get_final_left(seq) >= seq_tx_get_end(seq)) {
+ seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
+ }
+
+ /* dosnt work now - TODO */
+ /*
+ if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq)) {
+ int ofs;
+ ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq);
+ seq->start -= ofs;
+ seq_tx_set_final_left(seq, seq_tx_get_final_left(seq) + ofs );
+ }*/
+
+ }
+ }
+
+ if(rightflag) {
+ if (seq_tx_get_final_right(seq) <= seq_tx_get_final_left(seq)) {
+ seq_tx_set_final_right(seq, seq_tx_get_final_left(seq)+1);
+ }
+
+ if (check_single_seq(seq)==0) {
+ if (seq_tx_get_final_right(seq) <= seq_tx_get_start(seq)) {
+ seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
+ }
+ }
+ }
+
+ /* sounds cannot be extended past their endpoints */
+ if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
+ seq->startstill= 0;
+ seq->endstill= 0;
+ }
+}
+
+static int can_transform_seq_test_func(Sequence * seq)
+{
+ if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
+ return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN;
+ }
+ if ((seq->depth==0 && seq->flag & SEQ_LOCK) && !(seq->type & SEQ_EFFECT)) {
+ if (seq->type != SEQ_META) {
+ return BUILD_SEQAR_COUNT_NOTHING;
+ } else {
+ return BUILD_SEQAR_COUNT_CURRENT;
+ }
+ }
+ return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN;
+}
void transform_seq(int mode, int context)
{
- Sequence *seq;
+ SpaceSeq *sseq= curarea->spacedata.first;
+ Sequence *seq, *last_seq;
Editing *ed;
float dx, dy, dvec[2], div;
TransSeq *transmain, *ts;
- int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+ int totstrip=0, firsttime=1, afbreek=0, midtog= 0, proj= 0;
+ int ix, iy; /* these values are used for storing the mouses offset from its original location */
+ int ix_old = 0;
unsigned short event = 0;
short mval[2], val, xo, yo, xn, yn;
char str[32];
-
- if(mode!='g') return; /* from gesture */
+ char side= 'L'; /* for extend mode only - use to know which side to extend on */
+ char marker_moved=0; /* if we mvoed a marker, redraw all marker views */
+ /* used for extend in a number of places */
+ int cfra = CFRA;
+
+ /* for snapping */
+ char snapskip = 0, snap, snap_old= 0;
+ int snapdist_max = seq_get_snaplimit();
+ /* at the moment there are only 4 possible snap points,
+ - last_seq (start,end)
+ - selected bounds (start/end)
+ - last_seq (next/prev)
+ - current frame */
+ int snap_points[4], snap_point_num = 0;
+ int j; /* loop on snap_points */
+
+ /* for markers */
+ int *oldframe = NULL, totmark=0, a;
+ TimeMarker *marker;
+
+ /* looping on sequences, WHILE_SEQ macro allocates memory each time */
+ int totseq_index, seq_index;
+ Sequence **seqar = 0;
+
+ if(mode!='g' && mode!='e') return; /* from gesture */
/* which seqs are involved */
ed= G.scene->ed;
if(ed==0) return;
- WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) tot++;
+ /* Build the sequence array once, be sure to free it */
+ build_seqar_cb( ed->seqbasep, &seqar, &totseq_index,
+ can_transform_seq_test_func );
+
+ if (seqar) {
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK))
+ totstrip++;
+ }
+ }
+
+ if (sseq->flag & SEQ_MARKER_TRANS) {
+ for(marker= G.scene->markers.first; marker; marker= marker->next) {
+ if(marker->flag & SELECT) totmark++;
+ }
+ }
+
+ if(totstrip==0 && totmark==0) {
+ if(seqar) MEM_freeN(seqar);
+ return;
}
- END_SEQ
-
- if(tot==0) return;
G.moving= 1;
+
+ last_seq = get_last_seq();
+
+ ts=transmain= MEM_callocN(totstrip*sizeof(TransSeq), "transseq");
- ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
-
- WHILE_SEQ(ed->seqbasep) {
-
- if(seq->flag & SELECT) {
-
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
ts->start= seq->start;
ts->machine= seq->machine;
ts->startstill= seq->startstill;
ts->endstill= seq->endstill;
ts->startofs= seq->startofs;
ts->endofs= seq->endofs;
-
+
+ /* for extend only */
+ if (mode=='e') {
+ ts->final_left = seq_tx_get_final_left(seq);
+ ts->final_right = seq_tx_get_final_right(seq);
+ }
ts++;
}
}
- END_SEQ
-
+
getmouseco_areawin(mval);
+
+ /* choose the side based on which side of the playhead the mouse is on */
+ if (mode=='e')
+ side = mouse_cfra_side(cfra);
+
+ /* Markers */
+ if (sseq->flag & SEQ_MARKER_TRANS && totmark) {
+ oldframe= MEM_mallocN(totmark*sizeof(int), "marker array");
+ for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+ if(marker->flag & SELECT) {
+ if (mode=='e') {
+
+ /* when extending, invalidate markers on the other side by using an invalid frame value */
+ if ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)) {
+ oldframe[a] = MAXFRAME+1;
+ } else {
+ oldframe[a]= marker->frame;
+ }
+ } else {
+ oldframe[a]= marker->frame;
+ }
+ a++;
+ }
+ }
+ }
+
xo=xn= mval[0];
yo=yn= mval[1];
dvec[0]= dvec[1]= 0.0;
while(afbreek==0) {
getmouseco_areawin(mval);
- if(mval[0]!=xo || mval[1]!=yo || firsttime) {
- firsttime= 0;
+ G.qual = get_qual();
+ snap = (G.qual & LR_CTRLKEY) ? 1 : 0;
+
+ if(mval[0]!=xo || mval[1]!=yo || firsttime || snap != snap_old) {
+ if (firsttime) {
+ snap_old = snap;
+ firsttime= 0;
+ }
+
+ /* run for either grab or extend */
+ dx= mval[0]- xo;
+ dy= mval[1]- yo;
- if(mode=='g') {
+ div= G.v2d->mask.xmax-G.v2d->mask.xmin;
+ dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
- dx= mval[0]- xo;
- dy= mval[1]- yo;
+ div= G.v2d->mask.ymax-G.v2d->mask.ymin;
+ dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
- div= G.v2d->mask.xmax-G.v2d->mask.xmin;
- dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
+ if(G.qual & LR_SHIFTKEY) {
+ if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
+ }
- div= G.v2d->mask.ymax-G.v2d->mask.ymin;
- dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
+ dvec[0]+= dx;
+ dvec[1]+= dy;
- if(G.qual & LR_SHIFTKEY) {
- if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
+ if(midtog) dvec[proj]= 0.0;
+ ix= floor(dvec[0]+0.5);
+ iy= floor(dvec[1]+0.5);
+
+ ts= transmain;
+
+ /* SNAP! use the active Seq */
+ snap = G.qual & LR_CTRLKEY ? 1 : 0;
+
+ if (!snap) {
+ snapskip = 0;
+ } else {
+ int dist;
+ int snap_ofs= 0;
+ int snap_dist= snapdist_max;
+
+ /* Get sequence points to snap to the markers */
+
+ snap_point_num=0;
+ if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */
+ if(seq_tx_check_left(last_seq))
+ snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq);
+ if(seq_tx_check_right(last_seq))
+ snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq);
+
+ }
+ if (totstrip > 1) { /* selection bounds */
+ int bounds_left = MAXFRAME*2;
+ int bounds_right = -(MAXFRAME*2);
+
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if(seq->flag & SELECT) {
+ if(seq_tx_check_left(seq))
+ bounds_left = MIN2(bounds_left, seq_tx_get_final_left(seq));
+ if(seq_tx_check_right(seq))
+ bounds_right = MAX2(bounds_right,seq_tx_get_final_right(seq));
+ }
+ }
+
+ /* its possible there were no points to set on either side */
+ if (bounds_left != MAXFRAME*2)
+ snap_points[snap_point_num++] = bounds_left;
+ if (bounds_right != -(MAXFRAME*2))
+ snap_points[snap_point_num++] = bounds_right;
+ }
+
+
+ /* Define so we can snap to other points without hassle */
+
+#define TESTSNAP(test_frame)\
+ for(j=0; j<snap_point_num; j++) {\
+ /* see if this beats the current best snap point */\
+ dist = abs(snap_points[j] - test_frame);\
+ if (dist < snap_dist) {\
+ snap_ofs = test_frame - snap_points[j];\
+ snap_dist = dist;\
+ }\
+ }
+
+
+ /* Detect the best marker to snap to! */
+ for(a=0, marker= G.scene->markers.first; marker; a++, marker= marker->next) {
+
+ /* dont snap to a marker on the wrong extend side */
+ if (mode=='e' && ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)))
+ continue;
+
+ /* when we are moving markers, dont snap to selected markers, durr */
+ if ((sseq->flag & SEQ_MARKER_TRANS)==0 || (marker->flag & SELECT)==0) {
+
+ /* loop over the sticky points - max 4 */
+ TESTSNAP(marker->frame);
+ if (snap_dist == 0) break; /* alredy snapped? - stop looking */
+ }
+ }
+
+ if (snap_dist) {
+ TESTSNAP(cfra);
+ }
+
+ /* check seq's next to the active also - nice for quick snapping */
+ if (snap_dist && last_seq && seq_tx_check_left(last_seq)) {
+ seq = find_next_prev_sequence(last_seq, 1, 0); /* left */
+ if(seq && !seq_tx_check_right(seq))
+ TESTSNAP(seq_tx_get_final_right(seq));
+ }
+
+ if (snap_dist && last_seq && seq_tx_check_right(last_seq)) {
+ seq = find_next_prev_sequence(last_seq, 2, 0); /* right */
+ if(seq && !seq_tx_check_left(seq))
+ TESTSNAP(seq_tx_get_final_left(seq));
}
- dvec[0]+= dx;
- dvec[1]+= dy;
-
- if(midtog) dvec[proj]= 0.0;
- ix= floor(dvec[0]+0.5);
- iy= floor(dvec[1]+0.5);
-
-
- ts= transmain;
-
- WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
+#undef TESTSNAP
+
+ if (abs(ix_old-ix) >= snapdist_max) {
+ /* mouse has moved out of snap range */
+ snapskip = 0;
+ } else if (snap_dist==0) {
+ /* nowhere to move, dont do anything */
+ snapskip = 1;
+ } else if (snap_dist < snapdist_max) {
+ /* do the snapping by adjusting the mouse offset value */
+ ix = ix_old + snap_ofs;
+ }
+ }
+
+ if (mode=='g' && !snapskip) {
+ /* Grab */
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
+ int myofs;
+ // SEQ_DEBUG_INFO(seq);
+
+ /* X Transformation */
if(seq->flag & SEQ_LEFTSEL) {
- if(ts->startstill) {
- seq->startstill= ts->startstill-ix;
- if(seq->startstill<0) seq->startstill= 0;
- }
- else if(ts->startofs) {
- seq->startofs= ts->startofs+ix;
- if(seq->startofs<0) seq->startofs= 0;
- }
- else {
- if(ix>0) {
- seq->startofs= ix;
- seq->startstill= 0;
- }
- else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
- seq->startstill= -ix;
- seq->startofs= 0;
- }
- }
- if(seq->len <= seq->startofs+seq->endofs) {
- seq->startofs= seq->len-seq->endofs-1;
- }
+ myofs = (ts->startofs - ts->startstill);
+ seq_tx_set_final_left(seq, ts->start + (myofs + ix));
}
if(seq->flag & SEQ_RIGHTSEL) {
- if(ts->endstill) {
- seq->endstill= ts->endstill+ix;
- if(seq->endstill<0) seq->endstill= 0;
- }
- else if(ts->endofs) {
- seq->endofs= ts->endofs-ix;
- if(seq->endofs<0) seq->endofs= 0;
- }
- else {
- if(ix<0) {
- seq->endofs= -ix;
- seq->endstill= 0;
- }
- else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
- seq->endstill= ix;
- seq->endofs= 0;
- }
- }
- if(seq->len <= seq->startofs+seq->endofs) {
- seq->endofs= seq->len-seq->startofs-1;
- }
+ myofs = (ts->endstill - ts->endofs);
+ seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
}
+ transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
+
if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
+ /* Y Transformation */
if(seq->depth==0) seq->machine= ts->machine+ iy;
if(seq->machine<1) seq->machine= 1;
else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
}
-
calc_sequence(seq);
-
ts++;
}
}
- END_SEQ
-
- sprintf(str, "X: %d Y: %d ", ix, iy);
- headerprint(str);
+
+ /* Markers */
+ if (sseq->flag & SEQ_MARKER_TRANS) {
+ for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+ if(marker->flag & SELECT) {
+ marker->frame= oldframe[a] + ix;
+ marker_moved=1;
+ a++;
+ }
+ }
+ }
+
+ /* Extend, grabs one side of the current frame */
+ } else if (mode=='e' && !snapskip) {
+ int myofs; /* offset from start of the seq clip */
+ int xnew, final_left, final_right; /* just to store results from seq_tx_get_final_left/right */
+
+ /* we dont use seq side selection flags for this,
+ instead we need to calculate which sides to move
+ based on its initial position from the cursor */
+ int move_left, move_right;
+
+ /* Extend, Similar to grab but operate on one side of the cursor */
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
+ /* only move the contents of the metastrip otherwise the transformation is applied twice */
+ if (sequence_is_free_transformable(seq) && seq->type != SEQ_META) {
+
+ move_left = move_right = 0;
+
+ //SEQ_DEBUG_INFO(seq);
+
+ final_left = seq_tx_get_final_left(seq);
+ final_right = seq_tx_get_final_right(seq);
+
+ /* Only X Axis moving */
+
+ /* work out which sides to move first */
+ if (side=='L') {
+ if (final_left <= cfra || ts->final_left <= cfra) move_left = 1;
+ if (final_right <= cfra || ts->final_right <= cfra) move_right = 1;
+ } else {
+ if (final_left >= cfra || ts->final_left >= cfra) move_left = 1;
+ if (final_right >= cfra || ts->final_right >= cfra) move_right = 1;
+ }
+
+ if (move_left && move_right) {
+ /* simple move - dont need to do anything complicated */
+ seq->start= ts->start+ ix;
+ } else {
+ if (side=='L') {
+ if (move_left) {
+
+ /* Similar to other funcs */
+ myofs = (ts->startofs - ts->startstill);
+ xnew = ts->start + (ix + myofs);
+
+ /* make sure the we dont resize down to 0 or less in size
+ also include the startstill so the contense dosnt go outside the bounds,
+ if the seq->startofs is 0 then its ignored */
+
+ /* TODO remove, add check to transform_grab_xlimits, works ok for now */
+ if (xnew + seq->startstill > final_right-1) {
+ xnew = (final_right-1) - seq->startstill;
+ }
+ /* Note, this is the only case where the start needs to be adjusted
+ since its not needed when modifying the end or when moving the entire sequence */
+ //seq->start = ts->start+ix; // This works when xnew is not clamped, line below takes clamping into account
+ seq->start= xnew - myofs; /* TODO see above */
+ /* done with unique stuff */
+
+ seq_tx_set_final_left(seq, xnew);
+ transform_grab_xlimits(seq, 1, 0);
+
+ /* Special case again - setting the end back to what it was */
+ seq_tx_set_final_right(seq, final_right);
+ }
+ if (move_right) {
+ myofs = (ts->endstill - ts->endofs);
+ xnew = ts->start + seq->len + (myofs + ix);
+ seq_tx_set_final_right(seq, xnew);
+ transform_grab_xlimits(seq, 0, 1);
+ }
+ } else { /* R */
+ if (move_left) {
+ myofs = (ts->startofs - ts->startstill);
+ xnew = ts->start + (myofs + ix);
+ seq_tx_set_final_left(seq, xnew);
+ transform_grab_xlimits(seq, 1, 0);
+ }
+ if (move_right) {
+ myofs = (ts->endstill - ts->endofs);
+ xnew = ts->start + seq->len + (myofs + ix);
+ seq_tx_set_final_right(seq, xnew);
+ transform_grab_xlimits(seq, 0, 1);
+ }
+ }
+ }
+ }
+ calc_sequence(seq);
+ ts++;
+ }
+ }
+
+ /* markers */
+ if (sseq->flag & SEQ_MARKER_TRANS) {
+ for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {\
+ if (marker->flag & SELECT) {
+ if(oldframe[a] != MAXFRAME+1) {
+ marker->frame= oldframe[a] + ix;
+ marker_moved=1;
+ }
+ a++;
+ }
+ }
+ }
}
-
+
+ sprintf(str, "X: %d Y: %d ", ix, iy);
+ headerprint(str);
+
+ /* remember the last value for snapping,
+ only set if we are not currently snapped,
+ prevents locking on a keyframe */
+ if (!snapskip)
+ ix_old = ix;
+
+ /* just to tell if ctrl was pressed, this means we get a recalc when pressing ctrl */
+ snap_old = snap;
+
+ /* rememver last mouse values so we can skip transform when nothing happens */
xo= mval[0];
yo= mval[1];
/* test for effect and overlap */
-
- WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if((seq->depth==0) && (seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
seq->flag &= ~SEQ_OVERLAP;
if( test_overlap_seq(seq) ) {
seq->flag |= SEQ_OVERLAP;
@@ -2389,9 +3296,11 @@ void transform_seq(int mode, int context)
else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
}
}
- END_SEQ;
-
- force_draw(0);
+ /* warning, drawing should NEVER use WHILE_SEQ,
+ if it does the seq->depth value will be messed up and
+ overlap checks with metastrips will give incorrect results */
+ force_draw_plus(SPACE_BUTS, 0);
+
}
else BIF_wait_for_statechange();
@@ -2406,6 +3315,24 @@ void transform_seq(int mode, int context)
case RETKEY:
afbreek= 1;
break;
+ case XKEY:
+ if(!(midtog && (proj == 0))) {
+ midtog= ~midtog;
+ }
+ if(midtog) {
+ proj= 1;
+ firsttime= 1;
+ }
+ break;
+ case YKEY:
+ if(!(midtog && (proj == 1))) {
+ midtog= ~midtog;
+ }
+ if(midtog) {
+ proj= 0;
+ firsttime= 1;
+ }
+ break;
case MIDDLEMOUSE:
midtog= ~midtog;
if(midtog) {
@@ -2425,8 +3352,8 @@ void transform_seq(int mode, int context)
if((event==ESCKEY) || (event==RIGHTMOUSE)) {
ts= transmain;
- WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+ if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
seq->start= ts->start;
seq->machine= ts->machine;
seq->startstill= ts->startstill;
@@ -2443,14 +3370,30 @@ void transform_seq(int mode, int context)
else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
}
-
}
- END_SEQ
- }
- else {
+
+ /* Markers */
+ if (sseq->flag & SEQ_MARKER_TRANS) {
+ for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) {
+ if(oldframe[a] != MAXFRAME+1) {
+ marker->frame= oldframe[a];
+ }
+ a++;
+ }
+ }
+ marker_moved = 0;
+ }
+ } else {
/* images, effects and overlap */
- WHILE_SEQ(ed->seqbasep) {
+ for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
+
+ /* fixes single image strips - makes sure their start is not out of bounds
+ ideally this would be done during transform since data is rendered at that time
+ however it ends up being a lot messier! - Campbell */
+ fix_single_image_seq(seq);
+
if(seq->type == SEQ_META) {
calc_sequence(seq);
seq->flag &= ~SEQ_OVERLAP;
@@ -2463,147 +3406,213 @@ void transform_seq(int mode, int context)
}
else if(seq->type & SEQ_EFFECT) calc_sequence(seq);
}
- END_SEQ
/* as last: */
sort_seq();
}
-
+
+ /* free sequence array */
+ if(seqar) MEM_freeN(seqar);
+
G.moving= 0;
MEM_freeN(transmain);
+
+ if (sseq->flag & SEQ_MARKER_TRANS && totmark)
+ MEM_freeN(oldframe);
+
+ if (mode=='g')
+ BIF_undo_push("Transform Grab, Sequencer");
+ else if (mode=='e')
+ BIF_undo_push("Transform Extend, Sequencer");
+
+ if (marker_moved)
+ allqueue(REDRAWMARKER, 0);
+ else
+ allqueue(REDRAWSEQ, 0);
+}
- BIF_undo_push("Transform Sequencer");
- allqueue(REDRAWSEQ, 0);
+/* since grab can move markers, we must turn this off before adding a new sequence
+ I am not so happy with this, but the baddness in contained here - Campbell */
+void transform_seq_nomarker(int mode, int context) {
+ SpaceSeq *sseq= curarea->spacedata.first;
+ int flag_back;
+ if (!sseq) return; /* should never happen */
+ flag_back = sseq->flag;
+ sseq->flag &= ~SEQ_MARKER_TRANS;
+
+ transform_seq(mode, context);
+
+ sseq->flag = flag_back;
}
-void seq_cut(int cutframe)
+void seq_separate_images(void)
{
Editing *ed;
- Sequence *seq;
- TransSeq *ts, *transmain;
- int tot=0;
- ListBase newlist;
+ Sequence *seq, *seq_new, *seq_next;
+ Strip *strip_new;
+ StripElem *se, *se_new;
+ int start_ofs, cfra, frame_end;
+ static int step= 1;
+
+ add_numbut(0, NUM|INT, "Image Duration:", 1, 256, &step, NULL);
+ if (!do_clever_numbuts("Separate Images", 1, REDRAW))
+ return;
ed= G.scene->ed;
if(ed==0) return;
- /* test for validity */
- for(seq= ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->flag & SELECT) {
- if(cutframe > seq->startdisp && cutframe < seq->enddisp)
- if(seq->type==SEQ_META) break;
- }
- }
- if(seq) {
- error("Cannot cut Meta strips");
- return;
- }
+ seq= ed->seqbasep->first;
- /* we build an array of TransSeq, to denote which strips take part in cutting */
- for(seq= ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->flag & SELECT) {
- if(cutframe > seq->startdisp && cutframe < seq->enddisp)
- tot++;
- else
- seq->flag &= ~SELECT; // bad code, but we need it for recurs_dupli_seq... note that this ~SELECT assumption is used in loops below too (ton)
+ while (seq) {
+ if((seq->flag & SELECT) && (seq->type == SEQ_IMAGE) && (seq->len > 1)) {
+ /* remove seq so overlap tests dont conflict,
+ see free_sequence below for the real free'ing */
+ seq_next = seq->next;
+ BLI_remlink(ed->seqbasep, seq);
+ if(seq->ipo) seq->ipo->id.us--;
+
+ start_ofs = cfra = seq_tx_get_final_left(seq);
+ frame_end = seq_tx_get_final_right(seq);
+
+ while (cfra < frame_end) {
+ /* new seq */
+ se = give_stripelem(seq, cfra);
+
+ seq_new= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, start_ofs, seq->machine);
+ seq_new->type= SEQ_IMAGE;
+ seq_new->len = 1;
+ seq_new->endstill = step-1;
+
+ /* new strip */
+ seq_new->strip= strip_new= MEM_callocN(sizeof(Strip)*1, "strip");
+ strip_new->len= 1;
+ strip_new->us= 1;
+ strncpy(strip_new->dir, seq->strip->dir, FILE_MAXDIR-1);
+
+ /* new stripdata */
+ strip_new->stripdata= se_new= MEM_callocN(sizeof(StripElem)*1, "stripelem");
+ strncpy(se_new->name, se->name, FILE_MAXFILE-1);
+ calc_sequence(seq_new);
+ seq_new->flag &= ~SEQ_OVERLAP;
+ if (test_overlap_seq(seq_new)) {
+ shuffle_seq(seq_new);
+ }
+
+ cfra++;
+ start_ofs += step;
+ }
+
+ free_sequence(seq);
+ seq = seq->next;
+ } else {
+ seq = seq->next;
}
}
- if(tot==0) {
- error("No strips to cut");
- return;
- }
+ /* as last: */
+ sort_seq();
+ BIF_undo_push("Separate Image Strips, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+}
+
+/* run recursivly to select linked */
+static int select_more_less_seq__internal(int sel, int linked) {
+ Editing *ed;
+ Sequence *seq, *neighbor;
+ int change=0;
+ int isel;
- ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
+ ed= G.scene->ed;
+ if(ed==0) return 0;
- for(seq= ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->flag & SELECT) {
-
- ts->start= seq->start;
- ts->machine= seq->machine;
- ts->startstill= seq->startstill;
- ts->endstill= seq->endstill;
- ts->startdisp= seq->startdisp;
- ts->enddisp= seq->enddisp;
- ts->startofs= seq->startofs;
- ts->endofs= seq->endofs;
- ts->len= seq->len;
-
- ts++;
+ if (sel) {
+ sel = SELECT;
+ isel = 0;
+ } else {
+ sel = 0;
+ isel = SELECT;
+ }
+
+ if (!linked) {
+ /* if not linked we only want to touch each seq once, newseq */
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ seq->tmp = NULL;
}
}
-
+
for(seq= ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->flag & SELECT) {
-
- /* strips with extended stillframes before */
- if ((seq->startstill) && (cutframe <seq->start)) {
- seq->start= cutframe -1;
- seq->startstill= cutframe -seq->startdisp -1;
- seq->len= 1;
- seq->endstill= 0;
- }
-
- /* normal strip */
- else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
- seq->endofs = (seq->start+seq->len) - cutframe;
- }
-
- /* strips with extended stillframes after */
- else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
- seq->endstill -= seq->enddisp - cutframe;
+ if((int)(seq->flag & SELECT) == sel) {
+ if ((linked==0 && seq->tmp)==0) {
+ /* only get unselected nabours */
+ neighbor = find_neighboring_sequence(seq, 1, isel);
+ if (neighbor) {
+ if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);}
+ else neighbor->flag &= ~SELECT;
+ if (linked==0) neighbor->tmp = (Sequence *)1;
+ change = 1;
+ }
+ neighbor = find_neighboring_sequence(seq, 2, isel);
+ if (neighbor) {
+ if (sel) {neighbor->flag |= SELECT; recurs_sel_seq(neighbor);}
+ else neighbor->flag &= ~SELECT;
+ if (linked==0) neighbor->tmp = (void *)1;
+ change = 1;
+ }
}
-
- calc_sequence(seq);
}
}
-
- newlist.first= newlist.last= NULL;
- /* now we duplicate the cut strip and move it into place afterwards */
- recurs_dupli_seq(ed->seqbasep, &newlist);
- addlisttolist(ed->seqbasep, &newlist);
+ return change;
+}
+
+void select_less_seq(void)
+{
+ if (select_more_less_seq__internal(0, 0)) {
+ BIF_undo_push("Select Less, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+ }
+}
+
+void select_more_seq(void)
+{
+ if (select_more_less_seq__internal(1, 0)) {
+ BIF_undo_push("Select More, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+ }
+}
+
+/* TODO not all modes supported - if you feel like being picky, add them! ;) */
+void select_linked_seq(int mode) {
+ Editing *ed;
+ Sequence *seq, *mouse_seq;
+ int selected, hand;
- ts= transmain;
+ ed= G.scene->ed;
+ if(ed==0) return;
- /* go through all the strips and correct them based on their stored values */
- for(seq= ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->flag & SELECT) {
-
- /* strips with extended stillframes before */
- if ((seq->startstill) && (cutframe == seq->start + 1)) {
- seq->start = ts->start;
- seq->startstill= ts->start- cutframe;
- seq->len = ts->len;
- seq->endstill = ts->endstill;
- }
-
- /* normal strip */
- else if ((cutframe>=seq->start)&&(cutframe<=(seq->start+seq->len))) {
- seq->startstill = 0;
- seq->startofs = cutframe - ts->start;
- seq->endofs = ts->endofs;
- seq->endstill = ts->endstill;
- }
+ /* replace current selection */
+ if (mode==0 || mode==2) {
+ /* this works like UV, not mesh */
+ if (mode==0) {
+ mouse_seq= find_nearest_seq(&hand);
+ if (!mouse_seq)
+ return; /* user error as with mesh?? */
- /* strips with extended stillframes after */
- else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
- seq->start = cutframe - ts->len +1;
- seq->startofs = ts->len-1;
- seq->endstill = ts->enddisp - cutframe -1;
- seq->startstill = 0;
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ seq->flag &= ~SELECT;
}
- calc_sequence(seq);
-
- ts++;
+ mouse_seq->flag |= SELECT;
+ recurs_sel_seq(mouse_seq);
}
- }
- /* as last: */
- sort_seq();
- MEM_freeN(transmain);
-
- allqueue(REDRAWSEQ, 0);
+ selected = 1;
+ while (selected) {
+ selected = select_more_less_seq__internal(1, 1);
+ }
+ BIF_undo_push("Select Linked, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+ }
+ /* TODO - more modes... */
}
void seq_snap_menu(void)
@@ -2628,26 +3637,38 @@ void seq_snap(short event)
/* also check metas */
WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
- if(sequence_is_free_transformable(seq)) seq->start= CFRA-seq->startofs+seq->startstill;
+ if (seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK) &&
+ sequence_is_free_transformable(seq)) {
+ if((seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0) {
+ seq->start= CFRA-seq->startofs+seq->startstill;
+ } else {
+ if(seq->flag & SEQ_LEFTSEL) {
+ seq_tx_set_final_left(seq, CFRA);
+ } else { /* SEQ_RIGHTSEL */
+ seq_tx_set_final_right(seq, CFRA);
+ }
+ transform_grab_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
+ }
calc_sequence(seq);
}
}
END_SEQ
-
/* test for effects and overlap */
WHILE_SEQ(ed->seqbasep) {
- if(seq->flag & SELECT) {
+ if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
seq->flag &= ~SEQ_OVERLAP;
if( test_overlap_seq(seq) ) {
shuffle_seq(seq);
}
}
else if(seq->type & SEQ_EFFECT) {
- if(seq->seq1->flag & SELECT) calc_sequence(seq);
- else if(seq->seq2->flag & SELECT) calc_sequence(seq);
- else if(seq->seq3->flag & SELECT) calc_sequence(seq);
+ if(seq->seq1 && (seq->seq1->flag & SELECT))
+ calc_sequence(seq);
+ else if(seq->seq2 && (seq->seq2->flag & SELECT))
+ calc_sequence(seq);
+ else if(seq->seq3 && (seq->seq3->flag & SELECT))
+ calc_sequence(seq);
}
}
END_SEQ;
@@ -2655,7 +3676,41 @@ void seq_snap(short event)
/* as last: */
sort_seq();
- BIF_undo_push("Snap menu Sequencer");
+ BIF_undo_push("Snap Strips, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+}
+
+void seq_mute_sel(int mute) {
+ Editing *ed;
+ Sequence *seq;
+
+ ed= G.scene->ed;
+ if(!ed) return;
+
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ if ((seq->flag & SELECT) && (seq->flag & SEQ_LOCK)==0) {
+ if (mute) seq->flag |= SEQ_MUTE;
+ else seq->flag &= ~SEQ_MUTE;
+ }
+ }
+ BIF_undo_push(mute?"Mute Strips, Sequencer":"UnMute Strips, Sequencer");
+ allqueue(REDRAWSEQ, 0);
+}
+
+void seq_lock_sel(int lock) {
+ Editing *ed;
+ Sequence *seq;
+
+ ed= G.scene->ed;
+ if(!ed) return;
+
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ if ((seq->flag & SELECT)) {
+ if (lock) seq->flag |= SEQ_LOCK;
+ else seq->flag &= ~SEQ_LOCK;
+ }
+ }
+ BIF_undo_push(lock?"Lock Strips, Sequencer":"Unlock Strips, Sequencer");
allqueue(REDRAWSEQ, 0);
}
@@ -2704,7 +3759,7 @@ void borderselect_seq(void)
seq= seq->next;
}
- BIF_undo_push("Border select Sequencer");
+ BIF_undo_push("Border Select, Sequencer");
addqueue(curarea->win, REDRAW, 1);
}
}
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index 40cbe36ac8c..e94339d7a08 100644
--- a/source/blender/src/editsima.c
+++ b/source/blender/src/editsima.c
@@ -47,6 +47,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_editVert.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -79,6 +80,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BIF_imasel.h"
#include "BIF_interface.h"
#include "BIF_drawimage.h"
#include "BIF_editview.h"
@@ -90,10 +92,12 @@
#include "BIF_toolbox.h"
#include "BIF_transform.h"
#include "BIF_writeimage.h"
+#include "BIF_editmesh.h"
#include "BSE_drawipo.h"
#include "BSE_edit.h"
#include "BSE_filesel.h"
+#include "BSE_node.h"
#include "BSE_trans_types.h"
#include "BDR_editobject.h"
@@ -106,10 +110,10 @@
#include "blendef.h"
#include "multires.h"
#include "mydevice.h"
+#include "editmesh.h"
/* local prototypes */
-void clever_numbuts_sima(void);
-void sel_uvco_inside_radius(short , MTFace *, int , float *, float *, short);
+void sel_uvco_inside_radius(short , EditFace *efa, MTFace *, int , float *, float *, short);
void uvedit_selectionCB(short , Object *, short *, float ); /* used in edit.c*/
void object_uvs_changed(Object *ob)
@@ -129,28 +133,22 @@ void object_tface_flags_changed(Object *ob, int updateButtons)
int is_uv_tface_editing_allowed_silent(void)
{
- Mesh *me;
-
- if(G.obedit) return 0;
+ if(!EM_texFaceCheck()) return 0;
if(G.sima->mode!=SI_TEXTURE) return 0;
- if(!(G.f & G_FACESELECT)) return 0;
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return 0;
- if(multires_level1_test()) return 0;
-
+ if(multires_level1_test()) return 0;
return 1;
}
int is_uv_tface_editing_allowed(void)
{
- if(G.obedit) error("Unable to perform action in Edit Mode");
+ if(!G.obedit) error("Enter Edit Mode to perform this action");
return is_uv_tface_editing_allowed_silent();
}
void get_connected_limit_tface_uv(float *limit)
{
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
limit[0]= 0.05/(float)ibuf->x;
limit[1]= 0.05/(float)ibuf->y;
@@ -159,111 +157,16 @@ void get_connected_limit_tface_uv(float *limit)
limit[0]= limit[1]= 0.05/256.0;
}
-void clever_numbuts_sima(void)
-{
- float ocent[2], cent[2]= {0.0, 0.0};
- int imx= 256, imy= 256;
- int i, nactive= 0;
- Mesh *me;
-
- if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
-
- if (G.sima->image) {
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
- if(ibuf) {
- imx= ibuf->x;
- imy= ibuf->y;
- }
- }
-
- for (i=0; i<me->totface; i++) {
- MFace *mf= &((MFace*) me->mface)[i];
- MTFace *tf= &((MTFace*) me->mtface)[i];
-
- if (!(mf->flag & ME_FACE_SEL))
- continue;
-
- if (tf->flag & TF_SEL1) {
- cent[0]+= tf->uv[0][0];
- cent[1]+= tf->uv[0][1];
- nactive++;
- }
- if (tf->flag & TF_SEL2) {
- cent[0]+= tf->uv[1][0];
- cent[1]+= tf->uv[1][1];
- nactive++;
- }
- if (tf->flag & TF_SEL3) {
- cent[0]+= tf->uv[2][0];
- cent[1]+= tf->uv[2][1];
- nactive++;
- }
- if (mf->v4 && (tf->flag & TF_SEL4)) {
- cent[0]+= tf->uv[3][0];
- cent[1]+= tf->uv[3][1];
- nactive++;
- }
- }
-
- if (nactive) {
- cent[0]= (cent[0]*imx)/nactive;
- cent[1]= (cent[1]*imy)/nactive;
-
- add_numbut(0, NUM|FLO, "LocX:", -imx*20, imx*20, &cent[0], NULL);
- add_numbut(1, NUM|FLO, "LocY:", -imy*20, imy*20, &cent[1], NULL);
-
- ocent[0]= cent[0];
- ocent[1]= cent[1];
- if (do_clever_numbuts((nactive==1)?"Active Vertex":"Selected Center", 2, REDRAW)) {
- float delta[2];
-
- delta[0]= (cent[0]-ocent[0])/imx;
- delta[1]= (cent[1]-ocent[1])/imy;
-
- for (i=0; i<me->totface; i++) {
- MFace *mf= &((MFace*) me->mface)[i];
- MTFace *tf= &((MTFace*) me->mtface)[i];
-
- if (!(mf->flag & ME_FACE_SEL))
- continue;
-
- if (tf->flag & TF_SEL1) {
- tf->uv[0][0]+= delta[0];
- tf->uv[0][1]+= delta[1];
- }
- if (tf->flag & TF_SEL2) {
- tf->uv[1][0]+= delta[0];
- tf->uv[1][1]+= delta[1];
- }
- if (tf->flag & TF_SEL3) {
- tf->uv[2][0]+= delta[0];
- tf->uv[2][1]+= delta[1];
- }
- if (mf->v4 && (tf->flag & TF_SEL4)) {
- tf->uv[3][0]+= delta[0];
- tf->uv[3][1]+= delta[1];
- }
- }
-
- object_uvs_changed(OBACT);
- }
- }
-}
-
-void be_square_tface_uv(Mesh *me)
+void be_square_tface_uv(EditMesh *em)
{
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
- int a;
-
/* if 1 vertex selected: doit (with the selected vertex) */
- mface= (MFace*)me->mface;
- tface= (MTFace*)me->mtface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->v4) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & TF_SEL1) {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->v4) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0)) {
if( tface->uv[1][0] == tface->uv[2][0] ) {
tface->uv[1][1]= tface->uv[0][1];
tface->uv[3][0]= tface->uv[0][0];
@@ -274,7 +177,7 @@ void be_square_tface_uv(Mesh *me)
}
}
- if(tface->flag & TF_SEL2) {
+ if (simaUVSel_Check(efa, tface, 1)) {
if( tface->uv[2][1] == tface->uv[3][1] ) {
tface->uv[2][0]= tface->uv[1][0];
tface->uv[0][1]= tface->uv[1][1];
@@ -285,7 +188,7 @@ void be_square_tface_uv(Mesh *me)
}
}
- if(tface->flag & TF_SEL3) {
+ if (simaUVSel_Check(efa, tface, 2)) {
if( tface->uv[3][0] == tface->uv[0][0] ) {
tface->uv[3][1]= tface->uv[2][1];
tface->uv[1][0]= tface->uv[2][0];
@@ -295,7 +198,7 @@ void be_square_tface_uv(Mesh *me)
tface->uv[1][1]= tface->uv[2][1];
}
}
- if(tface->flag & TF_SEL4) {
+ if (simaUVSel_Check(efa, tface, 3)) {
if( tface->uv[0][1] == tface->uv[1][1] ) {
tface->uv[0][0]= tface->uv[3][0];
tface->uv[2][1]= tface->uv[3][1];
@@ -314,15 +217,18 @@ void be_square_tface_uv(Mesh *me)
void transform_aspect_ratio_tface_uv(float *aspx, float *aspy)
{
int w, h;
-
+ float xuser_asp, yuser_asp;
+
+ aspect_sima(G.sima, &xuser_asp, &yuser_asp);
+
transform_width_height_tface_uv(&w, &h);
- *aspx= (float)w/256.0f;
- *aspy= (float)h/256.0f;
+ *aspx= (float)w/256.0f * xuser_asp;
+ *aspy= (float)h/256.0f * yuser_asp;
}
void transform_width_height_tface_uv(int *width, int *height)
{
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
if(ibuf) {
*width= ibuf->x;
@@ -334,17 +240,12 @@ void transform_width_height_tface_uv(int *width, int *height)
}
}
-void mirror_tface_uv(char mirroraxis)
-{
- if (mirroraxis == 'x')
- Mirror(1); /* global x */
- else if (mirroraxis == 'y')
- Mirror(2); /* global y */
-}
-
void mirrormenu_tface_uv(void)
{
+ float mat[3][3];
short mode= 0;
+
+ Mat3One(mat);
if( is_uv_tface_editing_allowed()==0 ) return;
@@ -352,58 +253,78 @@ void mirrormenu_tface_uv(void)
if(mode==-1) return;
- if(mode==1) mirror_tface_uv('x');
- else if(mode==2) mirror_tface_uv('y');
+ if (mode == 1) {
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[0], " on X axis");
+ Transform();
+ }
+ else {
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[1], " on Y axis");
+ Transform();
+ }
BIF_undo_push("Mirror UV");
}
void weld_align_tface_uv(char tool)
{
- MFace *mface;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
MTFace *tface;
- Mesh *me;
- float min[2], max[2], cent[2];
- int a;
+ float cent[2], min[2], max[2];
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
- if (!minmax_tface_uv(min, max))
- return;
+ INIT_MINMAX2(min, max);
- cent[0]= (min[0]+max[0])/2.0;
- cent[1]= (min[1]+max[1])/2.0;
+ if(tool == 'a') {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0))
+ DO_MINMAX2(tface->uv[0], min, max)
+ if (simaUVSel_Check(efa, tface, 1))
+ DO_MINMAX2(tface->uv[1], min, max)
+ if (simaUVSel_Check(efa, tface, 2))
+ DO_MINMAX2(tface->uv[2], min, max)
+ if (efa->v4 && simaUVSel_Check(efa, tface, 3))
+ DO_MINMAX2(tface->uv[3], min, max)
+ }
+ }
+
+ tool= (max[0]-min[0] >= max[1]-min[1])? 'y': 'x';
+ }
+
+ cent_tface_uv(cent, 0);
if(tool == 'x' || tool == 'w') {
- tface= me->mtface;
- mface= me->mface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & TF_SEL1)
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0))
tface->uv[0][0]= cent[0];
- if(tface->flag & TF_SEL2)
+ if (simaUVSel_Check(efa, tface, 1))
tface->uv[1][0]= cent[0];
- if(tface->flag & TF_SEL3)
+ if (simaUVSel_Check(efa, tface, 2))
tface->uv[2][0]= cent[0];
- if(mface->v4 && (tface->flag & TF_SEL4))
+ if (efa->v4 && simaUVSel_Check(efa, tface, 3))
tface->uv[3][0]= cent[0];
}
}
}
if(tool == 'y' || tool == 'w') {
- tface= me->mtface;
- mface= me->mface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & TF_SEL1)
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0))
tface->uv[0][1]= cent[1];
- if(tface->flag & TF_SEL2)
+ if (simaUVSel_Check(efa, tface, 1))
tface->uv[1][1]= cent[1];
- if(tface->flag & TF_SEL3)
+ if (simaUVSel_Check(efa, tface, 2))
tface->uv[2][1]= cent[1];
- if(mface->v4 && (tface->flag & TF_SEL4))
+ if (efa->v4 && simaUVSel_Check(efa, tface, 3))
tface->uv[3][1]= cent[1];
}
}
@@ -412,59 +333,177 @@ void weld_align_tface_uv(char tool)
object_uvs_changed(OBACT);
}
+// just for averaging UV's
+typedef struct UVVertAverage {
+ float uv[2];
+ int count;
+} UVVertAverage;
+
+void stitch_vert_uv_tface(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ EditVert *eve;
+ MTFace *tface;
+ int count;
+ UVVertAverage *uv_average, *uvav;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+
+ // index and count verts
+ for (count=0, eve=em->verts.first; eve; count++, eve= eve->next) {
+ eve->tmp.l = count;
+ }
+
+ uv_average = MEM_callocN(sizeof(UVVertAverage) * count, "Stitch");
+
+ // gather uv averages per vert
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0)) {
+ uvav = uv_average + efa->v1->tmp.l;
+ uvav->count++;
+ uvav->uv[0] += tface->uv[0][0];
+ uvav->uv[1] += tface->uv[0][1];
+ }
+ if (simaUVSel_Check(efa, tface, 1)) {
+ uvav = uv_average + efa->v2->tmp.l;
+ uvav->count++;
+ uvav->uv[0] += tface->uv[1][0];
+ uvav->uv[1] += tface->uv[1][1];
+ }
+ if (simaUVSel_Check(efa, tface, 2)) {
+ uvav = uv_average + efa->v3->tmp.l;
+ uvav->count++;
+ uvav->uv[0] += tface->uv[2][0];
+ uvav->uv[1] += tface->uv[2][1];
+ }
+ if (efa->v4 && simaUVSel_Check(efa, tface, 3)) {
+ uvav = uv_average + efa->v4->tmp.l;
+ uvav->count++;
+ uvav->uv[0] += tface->uv[3][0];
+ uvav->uv[1] += tface->uv[3][1];
+ }
+ }
+ }
+
+ // apply uv welding
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0)) {
+ uvav = uv_average + efa->v1->tmp.l;
+ tface->uv[0][0] = uvav->uv[0]/uvav->count;
+ tface->uv[0][1] = uvav->uv[1]/uvav->count;
+ }
+ if (simaUVSel_Check(efa, tface, 1)) {
+ uvav = uv_average + efa->v2->tmp.l;
+ tface->uv[1][0] = uvav->uv[0]/uvav->count;
+ tface->uv[1][1] = uvav->uv[1]/uvav->count;
+ }
+ if (simaUVSel_Check(efa, tface, 2)) {
+ uvav = uv_average + efa->v3->tmp.l;
+ tface->uv[2][0] = uvav->uv[0]/uvav->count;
+ tface->uv[2][1] = uvav->uv[1]/uvav->count;
+ }
+ if (efa->v4 && simaUVSel_Check(efa, tface, 3)) {
+ uvav = uv_average + efa->v4->tmp.l;
+ tface->uv[3][0] = uvav->uv[0]/uvav->count;
+ tface->uv[3][1] = uvav->uv[1]/uvav->count;
+ }
+ }
+ }
+ MEM_freeN(uv_average);
+ object_uvs_changed(OBACT);
+}
+
void weld_align_menu_tface_uv(void)
{
short mode= 0;
if( is_uv_tface_editing_allowed()==0 ) return;
- mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3|");
+ mode= pupmenu("Weld/Align%t|Weld%x1|Align Auto%x2|Align X%x3|Align Y%x4");
if(mode==-1) return;
-
if(mode==1) weld_align_tface_uv('w');
- else if(mode==2) weld_align_tface_uv('x');
- else if(mode==3) weld_align_tface_uv('y');
+ else if(mode==2) weld_align_tface_uv('a');
+ else if(mode==3) weld_align_tface_uv('x');
+ else if(mode==4) weld_align_tface_uv('y');
if(mode==1) BIF_undo_push("Weld UV");
- else if(mode==2 || mode==3) BIF_undo_push("Align UV");
+ else if(ELEM3(mode, 2, 3, 4)) BIF_undo_push("Align UV");
}
-void select_swap_tface_uv(void)
+void select_invert_tface_uv(void)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
- int a, sel=0;
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) {
- sel= 1;
- break;
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ /* Warning, this is not that good (calling editmode stuff from UV),
+ TODO look into changing it */
+ selectswap_mesh();
+ return;
+ } else {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ tface->flag ^= TF_SEL1;
+ tface->flag ^= TF_SEL2;
+ tface->flag ^= TF_SEL3;
+ if(efa->v4) tface->flag ^= TF_SEL4;
}
}
}
+ BIF_undo_push("Select Inverse UV");
+
+ allqueue(REDRAWIMAGE, 0);
+}
+
+void select_swap_tface_uv(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+ int sel=0;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(mface->v4) {
- if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
- else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ deselectall_mesh();
+ return;
+ } else {
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if(tface->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) {
+ sel= 1;
+ break;
+ }
}
- else {
- if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
- else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3);
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if(efa->v4) {
+ if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
+ else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
+ }
+ else {
+ if(sel) tface->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
+ else tface->flag |= (TF_SEL1+TF_SEL2+TF_SEL3);
+ }
}
}
}
-
- BIF_undo_push("Select swap UV");
+ BIF_undo_push("Select swap");
allqueue(REDRAWIMAGE, 0);
}
@@ -485,29 +524,68 @@ static int msel_hit(float *limit, unsigned int *hitarray, unsigned int vertexid,
return 0;
}
-static void find_nearest_tface(MTFace **nearesttf, MFace **nearestmf)
+static void find_nearest_uv_edge(MTFace **nearesttf, EditFace **nearestefa, int *nearestedge)
{
- Mesh *me;
+ EditMesh *em= G.editMesh;
MTFace *tf;
- MFace *mf;
- int a, i, nverts, mindist, dist, fcenter[2], uval[2];
+ EditFace *efa;
+ float mvalf[2], v1[2], v2[2];
+ int i, nverts, mindist, dist, uval1[2], uval2[2];
short mval[2];
- getmouseco_areawin(mval);
+ getmouseco_areawin(mval);
+ mvalf[0]= mval[0];
+ mvalf[1]= mval[1];
mindist= 0x7FFFFFF;
*nearesttf= NULL;
- *nearestmf= NULL;
+ *nearestefa= NULL;
+ *nearestedge= 0;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if(simaFaceDraw_Check(efa, tf)) {
+ nverts= efa->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ uvco_to_areaco_noclip(tf->uv[i], uval1);
+ uvco_to_areaco_noclip(tf->uv[(i+1)%nverts], uval2);
- me= get_mesh(OBACT);
- mf= (MFace*)me ->mface;
- tf= (MTFace*)me->mtface;
+ v1[0]= uval1[0];
+ v1[1]= uval1[1];
+ v2[0]= uval2[0];
+ v2[1]= uval2[1];
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
+ dist= PdistVL2Dfl(mvalf, v1, v2);
+ if (dist < mindist) {
+ *nearesttf= tf;
+ *nearestefa= efa;
+ *nearestedge= i;
+ mindist= dist;
+ }
+ }
+ }
+ }
+}
+static void find_nearest_tface(MTFace **nearesttf, EditFace **nearestefa)
+{
+ EditMesh *em= G.editMesh;
+ MTFace *tf;
+ EditFace *efa;
+ int i, nverts, mindist, dist, fcenter[2], uval[2];
+ short mval[2];
+
+ getmouseco_areawin(mval);
+
+ mindist= 0x7FFFFFF;
+ *nearesttf= NULL;
+ *nearestefa= NULL;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
fcenter[0]= fcenter[1]= 0;
- nverts= mf->v4? 4: 3;
+ nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
uvco_to_areaco_noclip(tf->uv[i], uval);
fcenter[0] += uval[0];
@@ -520,7 +598,7 @@ static void find_nearest_tface(MTFace **nearesttf, MFace **nearestmf)
dist= abs(mval[0]- fcenter[0])+ abs(mval[1]- fcenter[1]);
if (dist < mindist) {
*nearesttf= tf;
- *nearestmf= mf;
+ *nearestefa= efa;
mindist= dist;
}
}
@@ -554,32 +632,35 @@ static int nearest_uv_between(MTFace *tf, int nverts, int id, short *mval, int *
return (c1*c2 >= 0.0f);
}
-static void find_nearest_uv(MTFace **nearesttf, unsigned int *nearestv, int *nearestuv)
+void find_nearest_uv(MTFace **nearesttf, EditFace **nearestefa, unsigned int *nearestv, int *nearestuv)
{
- Mesh *me;
+ EditMesh *em= G.editMesh;
+ EditFace *efa;
MTFace *tf;
- MFace *mf;
- int a, i, nverts, mindist, dist, uval[2];
+ int i, nverts, mindist, dist, uval[2];
short mval[2];
getmouseco_areawin(mval);
mindist= 0x7FFFFFF;
- *nearesttf= NULL;
-
- me= get_mesh(OBACT);
- mf= (MFace*)me->mface;
- tf= (MTFace*)me->mtface;
-
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
-
- nverts= mf->v4? 4: 3;
+ if (nearesttf) *nearesttf= NULL;
+ if (nearestefa) *nearestefa= NULL;
+
+ if (nearestv) {
+ EditVert *ev;
+ for (i=0, ev=em->verts.first; ev; ev = ev->next, i++)
+ ev->tmp.l = i;
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
uvco_to_areaco_noclip(tf->uv[i], uval);
dist= abs(mval[0]-uval[0]) + abs(mval[1]-uval[1]);
- if(tf->flag & TF_SEL_MASK(i))
+ if (simaUVSel_Check(efa, tf, i))
dist += 5;
if(dist<=mindist) {
@@ -587,15 +668,17 @@ static void find_nearest_uv(MTFace **nearesttf, unsigned int *nearestv, int *nea
if (!nearest_uv_between(tf, nverts, i, mval, uval))
continue;
- mindist= dist;
-
- *nearesttf= tf;
+ mindist= dist;
*nearestuv= i;
-
- if (i==0) *nearestv= mf->v1;
- else if (i==1) *nearestv= mf->v2;
- else if (i==2) *nearestv= mf->v3;
- else *nearestv= mf->v4;
+
+ if (nearesttf) *nearesttf= tf;
+ if (nearestefa) *nearestefa= efa;
+ if (nearestv) {
+ if (i==0) *nearestv= efa->v1->tmp.l;
+ else if (i==1) *nearestv= efa->v2->tmp.l;
+ else if (i==2) *nearestv= efa->v3->tmp.l;
+ else *nearestv= efa->v4->tmp.l;
+ }
}
}
}
@@ -604,46 +687,79 @@ static void find_nearest_uv(MTFace **nearesttf, unsigned int *nearestv, int *nea
void mouse_select_sima(void)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
MTFace *tf, *nearesttf;
- MFace *mf, *nearestmf=NULL;
- int a, selectsticky, sticky, actface, nearestuv, i;
+ EditFace *nearestefa=NULL;
+ int a, selectsticky, edgeloop, actface, nearestuv, nearestedge, i, shift;
+ char sticky= 0;
+ int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
unsigned int hitv[4], nearestv;
float *hituv[4], limit[2];
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
get_connected_limit_tface_uv(limit);
- actface= (G.qual & LR_ALTKEY || G.sima->flag & SI_SELACTFACE);
-
- if(G.qual & LR_CTRLKEY) {
- if(G.sima->flag & SI_STICKYUVS) sticky= 0;
- else sticky= 1;
- }
- else {
- if(G.sima->flag & SI_STICKYUVS) sticky= 1;
- else if(G.sima->flag & SI_LOCALSTICKY) sticky= 2;
- else sticky= 0;
+
+ edgeloop= G.qual & LR_ALTKEY;
+ shift= G.qual & LR_SHIFTKEY;
+
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ /* copy from mesh */
+ if (G.scene->selectmode == SCE_SELECT_FACE) {
+ actface= 1;
+ sticky= 0;
+ } else {
+ actface= G.sima->flag & SI_SELACTFACE;
+ sticky= 2;
+ }
+ } else {
+ /* normal operation */
+ actface= G.sima->flag & SI_SELACTFACE;
+
+ switch(G.sima->sticky) {
+ case SI_STICKY_LOC:
+ sticky=2;
+ break;
+ case SI_STICKY_DISABLE:
+ sticky=0;
+ break;
+ case SI_STICKY_VERTEX:
+ if(G.qual & LR_CTRLKEY) {
+ sticky=0;
+ } else {
+ sticky=1;
+ }
+ break;
+ }
}
- if(actface) {
- find_nearest_tface(&nearesttf, &nearestmf);
+ if(edgeloop) {
+ find_nearest_uv_edge(&nearesttf, &nearestefa, &nearestedge);
if(nearesttf==NULL)
return;
- nearesttf->flag |= TF_ACTIVE;
+ select_edgeloop_tface_uv(nearestefa, nearestedge, shift, &flush);
+ }
+ else if(actface) {
+ find_nearest_tface(&nearesttf, &nearestefa);
+ if(nearesttf==NULL)
+ return;
+
+ EM_set_actFace(nearestefa);
for (i=0; i<4; i++)
hituv[i]= nearesttf->uv[i];
- hitv[0]= nearestmf->v1;
- hitv[1]= nearestmf->v2;
- hitv[2]= nearestmf->v3;
- hitv[3]= nearestmf->v4? nearestmf->v4: 0xFFFFFFFF;
+ hitv[0]= nearestefa->v1->tmp.l;
+ hitv[1]= nearestefa->v2->tmp.l;
+ hitv[2]= nearestefa->v3->tmp.l;
+
+ if (nearestefa->v4) hitv[3]= nearestefa->v4->tmp.l;
+ else hitv[3]= 0xFFFFFFFF;
}
else {
- find_nearest_uv(&nearesttf, &nearestv, &nearestuv);
+ find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
if(nearesttf==NULL)
return;
@@ -655,133 +771,152 @@ void mouse_select_sima(void)
}
}
- if(G.qual & LR_SHIFTKEY) {
+ if(!edgeloop && shift) {
/* (de)select face */
if(actface) {
- if(!(~nearesttf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
- && (!nearestmf->v4 || nearesttf->flag & TF_SEL4)) {
- nearesttf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ if(simaFaceSel_Check(nearestefa, nearesttf)) {
+ simaFaceSel_UnSet(nearestefa, nearesttf);
selectsticky= 0;
}
else {
- nearesttf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4;
+ simaFaceSel_Set(nearestefa, nearesttf);
selectsticky= 1;
}
+ flush = -1;
}
/* (de)select uv node */
else {
- if(nearesttf->flag & TF_SEL_MASK(nearestuv)) {
- nearesttf->flag &= ~TF_SEL_MASK(nearestuv);
+ if (simaUVSel_Check(nearestefa, nearesttf, nearestuv)) {
+ simaUVSel_UnSet(nearestefa, nearesttf, nearestuv);
selectsticky= 0;
}
else {
- nearesttf->flag |= TF_SEL_MASK(nearestuv);
+ simaUVSel_Set(nearestefa, nearesttf, nearestuv);
selectsticky= 1;
}
+ flush = 1;
}
/* (de)select sticky uv nodes */
if(sticky || actface) {
- mf= (MFace*)me->mface;
- tf= (MTFace*)me->mtface;
+ EditVert *ev;
+
+ for (a=0, ev=em->verts.first; ev; ev = ev->next, a++)
+ ev->tmp.l = a;
+
/* deselect */
if(selectsticky==0) {
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(!(mf->flag & ME_FACE_SEL)) continue;
- if(nearesttf && tf!=nearesttf) tf->flag &=~ TF_ACTIVE;
- if (!sticky) continue;
-
- if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0], sticky))
- tf->flag &= ~TF_SEL1;
- if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1], sticky))
- tf->flag &= ~TF_SEL2;
- if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2], sticky))
- tf->flag &= ~TF_SEL3;
- if (mf->v4)
- if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3], sticky))
- tf->flag &= ~TF_SEL4;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ /*if(nearesttf && tf!=nearesttf) tf->flag &=~ TF_ACTIVE;*/ /* TODO - deal with editmesh active face */
+ if (!sticky) continue;
+
+ if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
+ simaUVSel_UnSet(efa, tf, 0);
+ if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
+ simaUVSel_UnSet(efa, tf, 1);
+ if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
+ simaUVSel_UnSet(efa, tf, 2);
+ if (efa->v4)
+ if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
+ simaUVSel_UnSet(efa, tf, 3);
+ }
}
+ flush = -1;
}
/* select */
else {
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(!(mf->flag & ME_FACE_SEL)) continue;
- if(nearesttf && tf!=nearesttf)
- tf->flag &=~ TF_ACTIVE;
- if (!sticky) continue;
-
- if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0], sticky))
- tf->flag |= TF_SEL1;
- if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1], sticky))
- tf->flag |= TF_SEL2;
- if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2], sticky))
- tf->flag |= TF_SEL3;
- if (mf->v4)
- if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3], sticky))
- tf->flag |= TF_SEL4;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if (!sticky) continue;
+ if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
+ simaUVSel_Set(efa, tf, 0);
+ if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
+ simaUVSel_Set(efa, tf, 1);
+ if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
+ simaUVSel_Set(efa, tf, 2);
+ if (efa->v4)
+ if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
+ simaUVSel_Set(efa, tf, 3);
+ }
}
- }
+ EM_set_actFace(nearestefa);
+ flush = 1;
+ }
}
}
- else {
+ else if(!edgeloop) {
/* select face and deselect other faces */
if(actface) {
- mf= (MFace*)me->mface;
- tf= (MTFace*)me->mtface;
- for(a=me->totface; a>0; a--, tf++, mf++) {
- tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
- if(nearesttf && tf!=nearesttf)
- tf->flag &= ~TF_ACTIVE;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ simaFaceSel_UnSet(efa, tf);
+ }
+ if(nearesttf) {
+ simaFaceSel_Set(nearestefa, nearesttf);
+ EM_set_actFace(nearestefa);
}
- if(nearesttf)
- nearesttf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+
}
/* deselect uvs, and select sticky uvs */
- mf= (MFace*)me->mface;
- tf= (MTFace*)me->mtface;
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->flag & ME_FACE_SEL) {
- if(!actface) tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if(!actface) simaFaceSel_UnSet(efa, tf);
if(!sticky) continue;
- if(msel_hit(limit, hitv, mf->v1, hituv, tf->uv[0], sticky))
- tf->flag |= TF_SEL1;
- if(msel_hit(limit, hitv, mf->v2, hituv, tf->uv[1], sticky))
- tf->flag |= TF_SEL2;
- if(msel_hit(limit, hitv, mf->v3, hituv, tf->uv[2], sticky))
- tf->flag |= TF_SEL3;
- if(mf->v4)
- if(msel_hit(limit, hitv, mf->v4, hituv, tf->uv[3], sticky))
- tf->flag |= TF_SEL4;
+ if(msel_hit(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
+ simaUVSel_Set(efa, tf, 0);
+ if(msel_hit(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
+ simaUVSel_Set(efa, tf, 1);
+ if(msel_hit(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
+ simaUVSel_Set(efa, tf, 2);
+ if(efa->v4)
+ if(msel_hit(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
+ simaUVSel_Set(efa, tf, 3);
+ flush= 1;
}
}
- if(!actface)
- nearesttf->flag |= TF_SEL_MASK(nearestuv);
+ if(!actface) {
+ simaUVSel_Set(nearestefa, nearesttf, nearestuv);
+ flush= 1;
+ }
}
force_draw(1);
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ /* flush for mesh selection */
+ if (G.scene->selectmode != SCE_SELECT_FACE) {
+ if (flush==1) EM_select_flush();
+ else if (flush==-1) EM_deselect_flush();
+ }
+ allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
+ }
+
BIF_undo_push("Select UV");
rightmouse_transform();
}
void borderselect_sima(short whichuvs)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
rcti rect;
rctf rectf;
- int a, val;
- short mval[2];
+ int val, ok = 1;
+ short mval[2], select;
- if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
+ if( is_uv_tface_editing_allowed()==0) return;
val= get_border(&rect, 3);
-
+ select = (val==LEFTMOUSE) ? 1 : 0;
+
if(val) {
mval[0]= rect.xmin;
mval[1]= rect.ymin;
@@ -789,62 +924,325 @@ void borderselect_sima(short whichuvs)
mval[0]= rect.xmax;
mval[1]= rect.ymax;
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
-
- if (whichuvs == UV_SELECT_ALL) {
-
- if(BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
- if(val==LEFTMOUSE) tface->flag |= TF_SEL1;
- else tface->flag &= ~TF_SEL1;
- }
- if(BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
- if(val==LEFTMOUSE) tface->flag |= TF_SEL2;
- else tface->flag &= ~TF_SEL2;
- }
- if(BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
- if(val==LEFTMOUSE) tface->flag |= TF_SEL3;
- else tface->flag &= ~TF_SEL3;
- }
- if(mface->v4 && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
- if(val==LEFTMOUSE) tface->flag |= TF_SEL4;
- else tface->flag &= ~TF_SEL4;
- }
- } else if (whichuvs == UV_SELECT_PINNED) {
- if ((tface->unwrap & TF_PIN1) &&
- BLI_in_rctf(&rectf, (float)tface->uv[0][0], (float)tface->uv[0][1])) {
-
- if(val==LEFTMOUSE) tface->flag |= TF_SEL1;
- else tface->flag &= ~TF_SEL1;
- }
- if ((tface->unwrap & TF_PIN2) &&
- BLI_in_rctf(&rectf, (float)tface->uv[1][0], (float)tface->uv[1][1])) {
-
- if(val==LEFTMOUSE) tface->flag |= TF_SEL2;
- else tface->flag &= ~TF_SEL2;
- }
- if ((tface->unwrap & TF_PIN3) &&
- BLI_in_rctf(&rectf, (float)tface->uv[2][0], (float)tface->uv[2][1])) {
-
- if(val==LEFTMOUSE) tface->flag |= TF_SEL3;
- else tface->flag &= ~TF_SEL3;
- }
- if ((mface->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, (float)tface->uv[3][0], (float)tface->uv[3][1])) {
- if(val==LEFTMOUSE) tface->flag |= TF_SEL4;
- else tface->flag &= ~TF_SEL4;
+ if (draw_uvs_face_check() && whichuvs != UV_SELECT_PINNED) {
+ float cent[2];
+ ok = 0;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ /* assume not touched */
+ efa->tmp.l = 0;
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ tface_center(tface, cent, (void *)efa->v4);
+ if(BLI_in_rctf(&rectf, cent[0], cent[1])) {
+ efa->tmp.l = ok = 1;
}
}
}
+ /* (de)selects all tagged faces and deals with sticky modes */
+ if (ok)
+ uvface_setsel__internal(select);
+ } else {
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (whichuvs == UV_SELECT_ALL || (G.sima->flag & SI_SYNC_UVSEL) ) {
+ /* SI_SYNC_UVSEL - cant do pinned selection */
+ if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+ if(select) simaUVSel_Set(efa, tface, 0);
+ else simaUVSel_UnSet(efa, tface, 0);
+ }
+ if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+ if(select) simaUVSel_Set(efa, tface, 1);
+ else simaUVSel_UnSet(efa, tface, 1);
+ }
+ if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+ if(select) simaUVSel_Set(efa, tface, 2);
+ else simaUVSel_UnSet(efa, tface, 2);
+ }
+ if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+ if(select) simaUVSel_Set(efa, tface, 3);
+ else simaUVSel_UnSet(efa, tface, 3);
+ }
+ } else if (whichuvs == UV_SELECT_PINNED) {
+ if ((tface->unwrap & TF_PIN1) &&
+ BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
+
+ if(select) simaUVSel_Set(efa, tface, 0);
+ else simaUVSel_UnSet(efa, tface, 0);
+ }
+ if ((tface->unwrap & TF_PIN2) &&
+ BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
+ if(select) simaUVSel_Set(efa, tface, 1);
+ else simaUVSel_UnSet(efa, tface, 1);
+ }
+ if ((tface->unwrap & TF_PIN3) &&
+ BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
+
+ if(select) simaUVSel_Set(efa, tface, 2);
+ else simaUVSel_UnSet(efa, tface, 2);
+ }
+ if ((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
+ if(select) simaUVSel_Set(efa, tface, 3);
+ else simaUVSel_UnSet(efa, tface, 3);
+ }
+ }
+ }
+ }
+ }
+ if (ok) {
+ /* make sure newly selected vert selection is updated*/
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ if (G.scene->selectmode != SCE_SELECT_FACE) {
+ if (select) EM_select_flush();
+ else EM_deselect_flush();
+ }
+ }
+ allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
+
+ BIF_undo_push("Border select UV");
+ scrarea_queue_winredraw(curarea);
}
- BIF_undo_push("Border select UV");
- scrarea_queue_winredraw(curarea);
}
}
+int snap_uv_sel_to_curs(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+ short change = 0;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0)) VECCOPY2D(tface->uv[0], G.v2d->cursor);
+ if (simaUVSel_Check(efa, tface, 1)) VECCOPY2D(tface->uv[1], G.v2d->cursor);
+ if (simaUVSel_Check(efa, tface, 2)) VECCOPY2D(tface->uv[2], G.v2d->cursor);
+ if (efa->v4)
+ if (simaUVSel_Check(efa, tface, 3)) VECCOPY2D(tface->uv[3], G.v2d->cursor);
+ change = 1;
+ }
+ }
+ return change;
+}
+
+int snap_uv_sel_to_adj_unsel(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ EditVert *eve;
+ MTFace *tface;
+ short change = 0;
+ int count = 0;
+ float *coords;
+ short *usercount, users;
+
+ /* set all verts to -1 : an unused index*/
+ for (eve= em->verts.first; eve; eve= eve->next)
+ eve->tmp.l=-1;
+
+ /* index every vert that has a selected UV using it, but only once so as to
+ * get unique indicies and to count how much to malloc */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0) && efa->v1->tmp.l==-1) efa->v1->tmp.l= count++;
+ if (simaUVSel_Check(efa, tface, 1) && efa->v2->tmp.l==-1) efa->v2->tmp.l= count++;
+ if (simaUVSel_Check(efa, tface, 2) && efa->v3->tmp.l==-1) efa->v3->tmp.l= count++;
+ if (efa->v4)
+ if (simaUVSel_Check(efa, tface, 3) && efa->v4->tmp.l==-1) efa->v4->tmp.l= count++;
+ change = 1;
+
+ /* optional speedup */
+ efa->tmp.p = tface;
+ } else {
+ efa->tmp.p = NULL;
+ }
+ }
+
+ coords = MEM_callocN(sizeof(float)*count*2, "snap to adjacent coords");
+ usercount = MEM_callocN(sizeof(short)*count, "snap to adjacent counts");
+
+ /* add all UV coords from visible, unselected UV coords as well as counting them to average later */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ /* is this an unselected UV we can snap to? */
+ if (efa->v1->tmp.l >= 0 && (!simaUVSel_Check(efa, tface, 0))) {
+ coords[efa->v1->tmp.l*2] += tface->uv[0][0];
+ coords[(efa->v1->tmp.l*2)+1] += tface->uv[0][1];
+ usercount[efa->v1->tmp.l]++;
+ change = 1;
+ }
+ if (efa->v2->tmp.l >= 0 && (!simaUVSel_Check(efa, tface, 1))) {
+ coords[efa->v2->tmp.l*2] += tface->uv[1][0];
+ coords[(efa->v2->tmp.l*2)+1] += tface->uv[1][1];
+ usercount[efa->v2->tmp.l]++;
+ change = 1;
+ }
+ if (efa->v3->tmp.l >= 0 && (!simaUVSel_Check(efa, tface, 2))) {
+ coords[efa->v3->tmp.l*2] += tface->uv[2][0];
+ coords[(efa->v3->tmp.l*2)+1] += tface->uv[2][1];
+ usercount[efa->v3->tmp.l]++;
+ change = 1;
+ }
+
+ if (efa->v4) {
+ if (efa->v4->tmp.l >= 0 && (!simaUVSel_Check(efa, tface, 3))) {
+ coords[efa->v4->tmp.l*2] += tface->uv[3][0];
+ coords[(efa->v4->tmp.l*2)+1] += tface->uv[3][1];
+ usercount[efa->v4->tmp.l]++;
+ change = 1;
+ }
+ }
+ }
+ }
+
+ /* no other verts selected, bail out */
+ if (!change) {
+ MEM_freeN(coords);
+ MEM_freeN(usercount);
+ return change;
+ }
+
+ /* copy the averaged unselected UVs back to the selected UVs */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+// tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+// if (simaFaceDraw_Check(efa, tface)) {
+ if ((tface=(MTFace *)efa->tmp.p)) {
+
+ if ( simaUVSel_Check(efa, tface, 0) &&
+ efa->v1->tmp.l >= 0 &&
+ (users = usercount[efa->v1->tmp.l])
+ ) {
+ tface->uv[0][0] = coords[efa->v1->tmp.l*2] / users;
+ tface->uv[0][1] = coords[(efa->v1->tmp.l*2)+1] / users;
+ }
+
+ if ( simaUVSel_Check(efa, tface, 1) &&
+ efa->v2->tmp.l >= 0 &&
+ (users = usercount[efa->v2->tmp.l])
+ ) {
+ tface->uv[1][0] = coords[efa->v2->tmp.l*2] / users;
+ tface->uv[1][1] = coords[(efa->v2->tmp.l*2)+1] / users;
+ }
+
+ if ( simaUVSel_Check(efa, tface, 2) &&
+ efa->v3->tmp.l >= 0 &&
+ (users = usercount[efa->v3->tmp.l])
+ ) {
+ tface->uv[2][0] = coords[efa->v3->tmp.l*2] / users;
+ tface->uv[2][1] = coords[(efa->v3->tmp.l*2)+1] / users;
+ }
+
+ if (efa->v4) {
+ if ( simaUVSel_Check(efa, tface, 3) &&
+ efa->v4->tmp.l >= 0 &&
+ (users = usercount[efa->v4->tmp.l])
+ ) {
+ tface->uv[3][0] = coords[efa->v4->tmp.l*2] / users;
+ tface->uv[3][1] = coords[(efa->v4->tmp.l*2)+1] / users;
+ }
+ }
+ }
+ }
+
+ MEM_freeN(coords);
+ MEM_freeN(usercount);
+ return change;
+}
+
+void snap_coord_to_pixel(float *uvco, float w, float h)
+{
+ uvco[0] = ((float) ((int)((uvco[0]*w) + 0.5))) / w;
+ uvco[1] = ((float) ((int)((uvco[1]*h) + 0.5))) / h;
+}
+
+int snap_uv_sel_to_pixels(void) /* warning, sanity checks must alredy be done */
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tface;
+ int wi, hi;
+ float w, h;
+ short change = 0;
+
+ transform_width_height_tface_uv(&wi, &hi);
+ w = (float)wi;
+ h = (float)hi;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (simaUVSel_Check(efa, tface, 0)) snap_coord_to_pixel(tface->uv[0], w, h);
+ if (simaUVSel_Check(efa, tface, 1)) snap_coord_to_pixel(tface->uv[1], w, h);
+ if (simaUVSel_Check(efa, tface, 2)) snap_coord_to_pixel(tface->uv[2], w, h);
+ if (efa->v4)
+ if (simaUVSel_Check(efa, tface, 3)) snap_coord_to_pixel(tface->uv[3], w, h);
+ change = 1;
+ }
+ }
+ return change;
+}
+
+void snap_uv_curs_to_pixels(void)
+{
+ int wi, hi;
+ float w, h;
+
+ transform_width_height_tface_uv(&wi, &hi);
+ w = (float)wi;
+ h = (float)hi;
+ snap_coord_to_pixel(G.v2d->cursor, w, h);
+}
+
+int snap_uv_curs_to_sel(void)
+{
+ if( is_uv_tface_editing_allowed()==0 ) return 0;
+ return cent_tface_uv(G.v2d->cursor, 0);
+}
+
+void snap_menu_sima(void)
+{
+ short event;
+ if( is_uv_tface_editing_allowed()==0 || !G.v2d) return; /* !G.v2d should never happen */
+
+ event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor -> Pixel%x4|Cursor -> Selection%x5");
+ switch (event) {
+ case 1:
+ if (snap_uv_sel_to_pixels()) {
+ BIF_undo_push("Snap UV Selection to Pixels");
+ object_uvs_changed(OBACT);
+ }
+ break;
+ case 2:
+ if (snap_uv_sel_to_curs()) {
+ BIF_undo_push("Snap UV Selection to Cursor");
+ object_uvs_changed(OBACT);
+ }
+ break;
+ case 3:
+ if (snap_uv_sel_to_adj_unsel()) {
+ BIF_undo_push("Snap UV Selection to Cursor");
+ object_uvs_changed(OBACT);
+ }
+ break;
+ case 4:
+ snap_uv_curs_to_pixels();
+ scrarea_queue_winredraw(curarea);
+ break;
+ case 5:
+ if (snap_uv_curs_to_sel())
+ allqueue(REDRAWIMAGE, 0);
+ break;
+ }
+}
+
+
/** This is an ugly function to set the Tface selection flags depending
* on whether its UV coordinates are inside the normalized
* area with radius rad and offset offset. These coordinates must be
@@ -852,7 +1250,7 @@ void borderselect_sima(short whichuvs)
* Just for readability...
*/
-void sel_uvco_inside_radius(short sel, MTFace *tface, int index, float *offset, float *ell, short select_mask)
+void sel_uvco_inside_radius(short sel, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, short select_index)
{
// normalized ellipse: ell[0] = scaleX,
// [1] = scaleY
@@ -865,8 +1263,8 @@ void sel_uvco_inside_radius(short sel, MTFace *tface, int index, float *offset,
r2 = x * x + y * y;
if (r2 < 1.0) {
- if (sel == LEFTMOUSE) tface->flag |= select_mask;
- else tface->flag &= ~select_mask;
+ if (sel == LEFTMOUSE) simaUVSel_Set(efa, tface, select_index);
+ else simaUVSel_UnSet(efa, tface, select_index);
}
}
@@ -874,17 +1272,14 @@ void sel_uvco_inside_radius(short sel, MTFace *tface, int index, float *offset,
/** gets image dimensions of the 2D view 'v' */
static void getSpaceImageDimension(SpaceImage *sima, float *xy)
{
- ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
- float z;
-
- z = sima->zoom;
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
if (ibuf) {
- xy[0] = ibuf->x * z;
- xy[1] = ibuf->y * z;
+ xy[0] = ibuf->x * sima->zoom;
+ xy[1] = ibuf->y * sima->zoom;
} else {
- xy[0] = 256 * z;
- xy[1] = 256 * z;
+ xy[0] = 256 * sima->zoom;
+ xy[1] = 256 * sima->zoom;
}
}
@@ -894,37 +1289,28 @@ static void getSpaceImageDimension(SpaceImage *sima, float *xy)
void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad)
{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
float offset[2];
- Mesh *me;
- MFace *mface;
MTFace *tface;
- int i;
-
float ellipse[2]; // we need to deal with ellipses, as
// non square textures require for circle
// selection. this ellipse is normalized; r = 1.0
-
- me = get_mesh(editobj);
getSpaceImageDimension(curarea->spacedata.first, ellipse);
ellipse[0] /= rad;
ellipse[1] /= rad;
areamouseco_to_ipoco(G.v2d, mval, &offset[0], &offset[1]);
-
- mface= me->mface;
- tface= me->mtface;
-
+
if (selecting) {
- for(i = 0; i < me->totface; i++) {
- sel_uvco_inside_radius(selecting, tface, 0, offset, ellipse, TF_SEL1);
- sel_uvco_inside_radius(selecting, tface, 1, offset, ellipse, TF_SEL2);
- sel_uvco_inside_radius(selecting, tface, 2, offset, ellipse, TF_SEL3);
- if (mface->v4)
- sel_uvco_inside_radius(selecting, tface, 3, offset, ellipse, TF_SEL4);
-
- tface++; mface++;
-
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ sel_uvco_inside_radius(selecting, efa, tface, 0, offset, ellipse, 0);
+ sel_uvco_inside_radius(selecting, efa, tface, 1, offset, ellipse, 1);
+ sel_uvco_inside_radius(selecting, efa, tface, 2, offset, ellipse, 2);
+ if (efa->v4)
+ sel_uvco_inside_radius(selecting, efa, tface, 3, offset, ellipse, 3);
}
if(G.f & G_DRAWFACES) { /* full redraw only if necessary */
@@ -933,11 +1319,18 @@ void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad
}
else { /* force_draw() is no good here... */
glDrawBuffer(GL_FRONT);
- draw_tfaces();
+ draw_uvs_sima();
bglFlush();
glDrawBuffer(GL_BACK);
}
- }
+
+
+ if (selecting == LEFTMOUSE) EM_select_flush();
+ else EM_deselect_flush();
+
+ if (G.sima->lock && (G.sima->flag & SI_SYNC_UVSEL))
+ force_draw_plus(SPACE_VIEW3D, 0);
+ }
}
@@ -976,123 +1369,82 @@ void mouseco_to_curtile(void)
G.sima->flag &= ~SI_EDITTILE;
- image_changed(G.sima, 1);
+ image_set_tile(G.sima, 2);
allqueue(REDRAWVIEW3D, 0);
scrarea_queue_winredraw(curarea);
}
}
-void hide_tface_uv(int swap)
+/* Could be used for other 2D views also */
+void mouseco_to_cursor_sima(void)
{
- Mesh *me;
- MTFace *tface;
- MFace *mface;
- int a;
-
- if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
-
- if(swap) {
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if((tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))==0) {
- if(!mface->v4)
- mface->flag &= ~ME_FACE_SEL;
- else if(!(tface->flag & TF_SEL4))
- mface->flag &= ~ME_FACE_SEL;
- }
- }
- }
- } else {
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
- mface->flag &= ~ME_FACE_SEL;
- else if(mface->v4 && tface->flag & TF_SEL4)
- mface->flag &= ~ME_FACE_SEL;
- }
- }
- }
-
- BIF_undo_push("Hide UV");
-
- object_tface_flags_changed(OBACT, 0);
-}
-
-void reveal_tface_uv(void)
-{
- Mesh *me;
- MTFace *tface;
- MFace *mface;
- int a;
-
- if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
-
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++)
- if(!(mface->flag & ME_HIDE))
- if(!(mface->flag & ME_FACE_SEL))
- tface->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
-
- BIF_undo_push("Reveal UV");
-
- object_tface_flags_changed(OBACT, 0);
+ short mval[2];
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &G.v2d->cursor[0], &G.v2d->cursor[1]);
+ scrarea_queue_winredraw(curarea);
}
-void stitch_uv_tface(int mode)
+void stitch_limit_uv_tface(void)
{
- Mesh *me;
MTFace *tf;
int a, vtot;
- float newuv[2], limit[2];
- UvMapVert *vlist, *iterv, *v;
- UvVertMap *vmap;
+ float newuv[2], limit[2], pixellimit;
+ UvMapVert *vlist, *iterv;
+ EditMesh *em = G.editMesh;
+ EditVert *ev;
+ EditFace *efa;
+
+ struct UvVertMap *vmap;
+
if(is_uv_tface_editing_allowed()==0)
return;
-
- limit[0]= limit[1]= 20.0;
- if(mode==1) {
- add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL);
- if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
- return;
+ if(G.sima->flag & SI_SYNC_UVSEL) {
+ error("Can't stitch when Sync Mesh Selection is enabled");
+ return;
}
+
+ pixellimit= 20.0f;
+ add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &pixellimit, NULL);
+ if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
+ return;
- limit[0]= limit[1]= limit[0]/256.0;
if(G.sima->image) {
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
if(ibuf && ibuf->x > 0 && ibuf->y > 0) {
- limit[1]= limit[0]/(float)ibuf->y;
- limit[0]= limit[0]/(float)ibuf->x;
+ limit[0]= pixellimit/(float)ibuf->x;
+ limit[1]= pixellimit/(float)ibuf->y;
}
+ else
+ limit[0]= limit[1]= pixellimit/256.0;
}
+ else
+ limit[0]= limit[1]= pixellimit/256.0;
- me= get_mesh(OBACT);
- tf= me->mtface;
-
- vmap= make_uv_vert_map(me->mface, tf, me->totface, me->totvert, 1, limit);
+ /*vmap= make_uv_vert_map(me->mface, tf, me->totface, me->totvert, 1, limit);*/
+ EM_init_index_arrays(0, 0, 1);
+ vmap= make_uv_vert_map_EM(1, 0, limit);
if(vmap == NULL)
return;
- if(mode==0) {
- for(a=0; a<me->totvert; a++) {
- v = get_uv_map_vert(vmap, a);
-
- if(v == NULL)
- continue;
+ for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
+ vlist= get_uv_map_vert_EM(vmap, a);
+ while(vlist) {
newuv[0]= 0; newuv[1]= 0;
vtot= 0;
- for(iterv=v; iterv; iterv=iterv->next) {
- if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
- newuv[0] += tf[iterv->f].uv[iterv->tfindex][0];
- newuv[1] += tf[iterv->f].uv[iterv->tfindex][1];
+ for(iterv=vlist; iterv; iterv=iterv->next) {
+ if((iterv != vlist) && iterv->separate)
+ break;
+ efa = EM_get_face_for_index(iterv->f);
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
+ newuv[0] += tf->uv[iterv->tfindex][0];
+ newuv[1] += tf->uv[iterv->tfindex][1];
vtot++;
}
}
@@ -1100,126 +1452,108 @@ void stitch_uv_tface(int mode)
if (vtot > 1) {
newuv[0] /= vtot; newuv[1] /= vtot;
- for(iterv=v; iterv; iterv=iterv->next) {
- if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
- tf[iterv->f].uv[iterv->tfindex][0]= newuv[0];
- tf[iterv->f].uv[iterv->tfindex][1]= newuv[1];
- }
- }
- }
- }
- } else if(mode==1) {
- for(a=0; a<me->totvert; a++) {
- vlist= get_uv_map_vert(vmap, a);
-
- while(vlist) {
- newuv[0]= 0; newuv[1]= 0;
- vtot= 0;
-
for(iterv=vlist; iterv; iterv=iterv->next) {
if((iterv != vlist) && iterv->separate)
break;
- if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
- newuv[0] += tf[iterv->f].uv[iterv->tfindex][0];
- newuv[1] += tf[iterv->f].uv[iterv->tfindex][1];
- vtot++;
- }
- }
-
- if (vtot > 1) {
- newuv[0] /= vtot; newuv[1] /= vtot;
-
- for(iterv=vlist; iterv; iterv=iterv->next) {
- if((iterv != vlist) && iterv->separate)
- break;
- if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
- tf[iterv->f].uv[iterv->tfindex][0]= newuv[0];
- tf[iterv->f].uv[iterv->tfindex][1]= newuv[1];
- }
+ efa = EM_get_face_for_index(iterv->f);
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
+ tf->uv[iterv->tfindex][0]= newuv[0];
+ tf->uv[iterv->tfindex][1]= newuv[1];
}
}
-
- vlist= iterv;
}
+ vlist= iterv;
}
}
- free_uv_vert_map(vmap);
-
- if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me);
+ free_uv_vert_map_EM(vmap);
+ EM_free_index_arrays();
+
+ if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(em);
BIF_undo_push("Stitch UV");
object_uvs_changed(OBACT);
}
-void select_linked_tface_uv(int mode)
+void select_linked_tface_uv(int mode) /* TODO */
{
- Mesh *me;
- MFace *mf;
+ EditMesh *em= G.editMesh;
+ EditFace *efa, *nearestefa=NULL;
MTFace *tf, *nearesttf=NULL;
UvVertMap *vmap;
UvMapVert *vlist, *iterv, *startv;
unsigned int *stack, stacksize= 0, nearestv;
char *flag;
- int a, nearestuv, i, nverts;
+ int a, nearestuv, i, nverts, j;
float limit[2];
-
if(is_uv_tface_editing_allowed()==0)
return;
- me= get_mesh(OBACT);
-
+ if(G.sima->flag & SI_SYNC_UVSEL) {
+ error("Can't select linked when Sync Mesh Selection is enabled");
+ return;
+ }
+
if (mode == 2) {
nearesttf= NULL;
nearestuv= 0;
}
if (mode!=2) {
- find_nearest_uv(&nearesttf, &nearestv, &nearestuv);
+ find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
if(nearesttf==NULL)
return;
}
get_connected_limit_tface_uv(limit);
- vmap= make_uv_vert_map(me->mface, me->mtface, me->totface, me->totvert, 1, limit);
+ vmap= make_uv_vert_map_EM(1, 1, limit);
if(vmap == NULL)
return;
- stack= MEM_mallocN(sizeof(*stack)*me->totface, "UvLinkStack");
- flag= MEM_callocN(sizeof(*flag)*me->totface, "UvLinkFlag");
+ stack= MEM_mallocN(sizeof(*stack)* BLI_countlist(&em->faces), "UvLinkStack");
+ flag= MEM_callocN(sizeof(*flag)*BLI_countlist(&em->faces), "UvLinkFlag");
if (mode == 2) {
- tf= me->mtface;
- mf= me->mface;
- for(a=0; a<me->totface; a++, tf++, mf++)
- if(!(mf->flag & ME_HIDE) && (mf->flag & ME_FACE_SEL))
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) {
stack[stacksize]= a;
stacksize++;
flag[a]= 1;
}
- }
- else {
- tf= me->mtface;
- for(a=0; a<me->totface; a++, tf++)
+ }
+ }
+ } else {
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if(tf == nearesttf) {
stack[stacksize]= a;
stacksize++;
flag[a]= 1;
break;
}
+ }
}
while(stacksize > 0) {
stacksize--;
a= stack[stacksize];
- mf= me->mface+a;
- tf= me->mtface+a;
+
+ for (j=0, efa= em->faces.first; efa; efa= efa->next, j++) {
+ if (j==a) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ break;
+ }
+ }
- nverts= mf->v4? 4: 3;
+ nverts= efa->v4? 4: 3;
for(i=0; i<nverts; i++) {
- vlist= get_uv_map_vert(vmap, *(&mf->v1 + i));
+ /* make_uv_vert_map_EM sets verts tmp.l to the indicies */
+ vlist= get_uv_map_vert_EM(vmap, (*(&efa->v1 + i))->tmp.l);
+
startv= vlist;
for(iterv=vlist; iterv; iterv=iterv->next) {
@@ -1242,17 +1576,19 @@ void select_linked_tface_uv(int mode)
}
if(mode==0 || mode==2) {
- for(a=0, tf=me->mtface; a<me->totface; a++, tf++)
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if(flag[a])
tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
else
tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
}
else if(mode==1) {
- mf= me->mface;
- for(a=0, tf=me->mtface; a<me->totface; a++, tf++, mf++) {
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
if(flag[a]) {
- if (mf->v4) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (efa->v4) {
if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
break;
}
@@ -1261,21 +1597,27 @@ void select_linked_tface_uv(int mode)
}
}
- if (a<me->totface) {
- for(a=0, tf=me->mtface; a<me->totface; a++, tf++)
- if(flag[a])
+ if (efa) {
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+ if(flag[a]) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+ }
}
else {
- for(a=0, tf=me->mtface; a<me->totface; a++, tf++)
- if(flag[a])
+ for (a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+ if(flag[a]) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+ }
}
}
MEM_freeN(stack);
MEM_freeN(flag);
- free_uv_vert_map(vmap);
+ free_uv_vert_map_EM(vmap);
BIF_undo_push("Select linked UV");
scrarea_queue_winredraw(curarea);
@@ -1283,18 +1625,21 @@ void select_linked_tface_uv(int mode)
void unlink_selection(void)
{
- Mesh *me;
+ EditMesh *em= G.editMesh;
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
- int a;
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
- mface= me->mface;
- for(a=me->totface, tface= me->mtface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(mface->v4) {
+ if(G.sima->flag & SI_SYNC_UVSEL) {
+ error("Can't select unlinked when Sync Mesh Selection is enabled");
+ return;
+ }
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if(efa->v4) {
if(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))
tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
} else {
@@ -1308,56 +1653,173 @@ void unlink_selection(void)
scrarea_queue_winredraw(curarea);
}
-void toggle_uv_select(int mode)
-{
- switch(mode){
- case 'f':
- G.sima->flag ^= SI_SELACTFACE;
- break;
- case 's':
- G.sima->flag ^= SI_STICKYUVS;
- if (G.sima->flag & SI_STICKYUVS) G.sima->flag &= ~SI_LOCALSTICKY;
- else G.sima->flag |= SI_LOCALSTICKY;
- break;
- case 'l':
- G.sima->flag ^= SI_LOCALSTICKY;
- if (G.sima->flag & SI_LOCALSTICKY) G.sima->flag &= ~SI_STICKYUVS;
- break;
- case 'o':
- G.sima->flag &= ~SI_STICKYUVS;
- G.sima->flag &= ~SI_LOCALSTICKY;
- break;
+/* this function sets the selection on tagged faces
+ * This is needed because setting the selection on a face is done in
+ * a number of places but it also needs to respect the sticky modes
+ * for the UV verts - dealing with the sticky modes is best done in a seperate function
+ *
+ * de-selects faces that have been tagged on efa->tmp.l
+ */
+void uvface_setsel__internal(short select)
+{
+
+ /* All functions calling this should call
+ * draw_uvs_face_check()
+ */
+
+
+ /* selecting UV Faces with some modes requires us to change
+ * the selection in other faces (depending on the stickt mode)
+ *
+ * This only needs to be done when the Mesh is not used for selection
+ * (So for sticky modes - vertex or location based)
+ * */
+
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tf;
+ int nverts, i;
+
+ if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_VERTEX) {
+ /* tag all verts as untouched,
+ * then touch the ones that have a face center in the loop
+ * and select all MTFace UV's that use a touched vert */
+
+ EditVert *eve;
+
+ for (eve= em->verts.first; eve; eve= eve->next)
+ eve->tmp.l = 0;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->tmp.l) {
+ if (efa->v4) {
+ efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
+ } else {
+ efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
+ }
+ }
+ }
+ /* now select tagged verts */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ nverts= efa->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ if ((*(&efa->v1 + i))->tmp.l) {
+ if (select) {
+ simaUVSel_Set(efa, tf, i);
+ } else {
+ simaUVSel_UnSet(efa, tf, i);
+ }
+ }
+ }
+ }
+ } else if ((G.sima->flag & SI_SYNC_UVSEL)==0 && G.sima->sticky == SI_STICKY_LOC) {
+ EditFace *efa_vlist;
+ MTFace *tf_vlist;
+ UvMapVert *vlist, *start_vlist=NULL, *vlist_iter;
+ struct UvVertMap *vmap;
+ float limit[2];
+ int efa_index;
+ //EditVert *eve; /* removed vert counting for now */
+ //int a;
+
+ get_connected_limit_tface_uv(limit);
+
+ EM_init_index_arrays(0, 0, 1);
+ vmap= make_uv_vert_map_EM(0, 0, limit);
+
+ /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
+ /*for (a=0, eve= em->verts.first; eve; a++, eve= eve->next)
+ eve->tmp.l = a; */
+
+ if(vmap == NULL)
+ return;
+
+ for (efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
+ if (efa->tmp.l) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ nverts= efa->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ if (select) {
+ simaUVSel_Set(efa, tf, i);
+ } else {
+ simaUVSel_UnSet(efa, tf, i);
+ }
+
+ vlist= vlist_iter= get_uv_map_vert_EM(vmap, (*(&efa->v1 + i))->tmp.l);
+
+ while (vlist_iter) {
+ if (vlist_iter->separate)
+ start_vlist = vlist_iter;
+
+ if (efa_index == vlist_iter->f) {
+ break;
+ }
+ vlist_iter = vlist_iter->next;
+ }
+
+ vlist_iter = start_vlist;
+ while (vlist_iter) {
+
+ if (vlist_iter != start_vlist && vlist_iter->separate)
+ break;
+
+ if (efa_index != vlist_iter->f) {
+ efa_vlist = EM_get_face_for_index(vlist_iter->f);
+ tf_vlist = CustomData_em_get(&em->fdata, efa_vlist->data, CD_MTFACE);
+
+ if (select) {
+ simaUVSel_Set(efa_vlist, tf_vlist, vlist_iter->tfindex);
+ } else {
+ simaUVSel_UnSet(efa_vlist, tf_vlist, vlist_iter->tfindex);
+ }
+ }
+ vlist_iter = vlist_iter->next;
+ }
+ }
+ }
+ }
+ EM_free_index_arrays();
+ free_uv_vert_map_EM(vmap);
+
+ } else { /* SI_STICKY_DISABLE or G.sima->flag & SI_SYNC_UVSEL */
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ if (efa->tmp.l) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (select) {
+ simaFaceSel_Set(efa, tf);
+ } else {
+ simaFaceSel_UnSet(efa, tf);
+ }
+ }
+ }
}
- allqueue(REDRAWIMAGE, 0);
}
void pin_tface_uv(int mode)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
- int a;
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
- mface= me->mface;
- tface= me->mtface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- if(mode ==1){
- if(tface->flag & TF_SEL1) tface->unwrap |= TF_PIN1;
- if(tface->flag & TF_SEL2) tface->unwrap |= TF_PIN2;
- if(tface->flag & TF_SEL3) tface->unwrap |= TF_PIN3;
- if(mface->v4)
- if(tface->flag & TF_SEL4) tface->unwrap |= TF_PIN4;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if(mode ==1) {
+ if(simaUVSel_Check(efa, tface, 0)) tface->unwrap |= TF_PIN1;
+ if(simaUVSel_Check(efa, tface, 1)) tface->unwrap |= TF_PIN2;
+ if(simaUVSel_Check(efa, tface, 2)) tface->unwrap |= TF_PIN3;
+ if(efa->v4)
+ if(simaUVSel_Check(efa, tface, 3)) tface->unwrap |= TF_PIN4;
}
- else if (mode ==0){
- if(tface->flag & TF_SEL1) tface->unwrap &= ~TF_PIN1;
- if(tface->flag & TF_SEL2) tface->unwrap &= ~TF_PIN2;
- if(tface->flag & TF_SEL3) tface->unwrap &= ~TF_PIN3;
- if(mface->v4)
- if(tface->flag & TF_SEL4) tface->unwrap &= ~TF_PIN4;
+ else if (mode ==0) {
+ if(simaUVSel_Check(efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
+ if(simaUVSel_Check(efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
+ if(simaUVSel_Check(efa, tface, 2)) tface->unwrap &= ~TF_PIN3;
+ if(efa->v4)
+ if(simaUVSel_Check(efa, tface, 3)) tface->unwrap &= ~TF_PIN4;
}
}
}
@@ -1368,72 +1830,293 @@ void pin_tface_uv(int mode)
void select_pinned_tface_uv(void)
{
- Mesh *me;
+ EditMesh *em= G.editMesh;
+ EditFace *efa;
MTFace *tface;
- MFace *mface;
- int a;
if( is_uv_tface_editing_allowed()==0 ) return;
- me= get_mesh(OBACT);
- mface= me->mface;
- tface= me->mtface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
-
- if (tface->unwrap & TF_PIN1) tface->flag |= TF_SEL1;
- if (tface->unwrap & TF_PIN2) tface->flag |= TF_SEL2;
- if (tface->unwrap & TF_PIN3) tface->flag |= TF_SEL3;
- if(mface->v4) {
- if (tface->unwrap & TF_PIN4) tface->flag |= TF_SEL4;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tface)) {
+ if (tface->unwrap & TF_PIN1) simaUVSel_Set(efa, tface, 0);
+ if (tface->unwrap & TF_PIN2) simaUVSel_Set(efa, tface, 1);
+ if (tface->unwrap & TF_PIN3) simaUVSel_Set(efa, tface, 2);
+ if(efa->v4) {
+ if (tface->unwrap & TF_PIN4) simaUVSel_Set(efa, tface, 3);
}
}
}
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ allqueue(REDRAWVIEW3D, 0); /* mesh selection has changed */
+ }
+
BIF_undo_push("Select Pinned UVs");
scrarea_queue_winredraw(curarea);
}
-int minmax_tface_uv(float *min, float *max)
+/* UV edge loop select, follows same rules as editmesh */
+
+static void uv_vertex_loop_flag(UvMapVert *first)
{
- Mesh *me;
- MTFace *tf;
- MFace *mf;
- int a, sel;
+ UvMapVert *iterv;
+ int count= 0;
- if( is_uv_tface_editing_allowed()==0 ) return 0;
- me= get_mesh(OBACT);
+ for(iterv=first; iterv; iterv=iterv->next) {
+ if(iterv->separate && iterv!=first)
+ break;
- INIT_MINMAX2(min, max);
+ count++;
+ }
+
+ if(count < 5)
+ first->flag= 1;
+}
- sel= 0;
- mf= (MFace*)me->mface;
- tf= (MTFace*)me->mtface;
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->flag & ME_HIDE);
- else if(mf->flag & ME_FACE_SEL) {
+static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, EditFace *efa, int a)
+{
+ UvMapVert *iterv, *first;
+
+ first= get_uv_map_vert_EM(vmap, (*(&efa->v1 + a))->tmp.l);
+
+ for(iterv=first; iterv; iterv=iterv->next) {
+ if(iterv->separate)
+ first= iterv;
+ if(iterv->f == efa->tmp.l)
+ return first;
+ }
+
+ return NULL;
+}
+
+static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface)
+{
+ UvMapVert *iterv1, *iterv2;
+ EditFace *efa;
+ int tot = 0;
- if (tf->flag & TF_SEL1) {
- DO_MINMAX2(tf->uv[0], min, max);
+ /* count number of faces this edge has */
+ for(iterv1=first1; iterv1; iterv1=iterv1->next) {
+ if(iterv1->separate && iterv1 != first1)
+ break;
+
+ for(iterv2=first2; iterv2; iterv2=iterv2->next) {
+ if(iterv2->separate && iterv2 != first2)
+ break;
+
+ if(iterv1->f == iterv2->f) {
+ /* if face already tagged, don't do this edge */
+ efa= EM_get_face_for_index(iterv1->f);
+ if(efa->f1)
+ return 0;
+
+ tot++;
+ break;
}
- if (tf->flag & TF_SEL2) {
- DO_MINMAX2(tf->uv[1], min, max);
+ }
+ }
+
+ if(*totface == 0) /* start edge */
+ *totface= tot;
+ else if(tot != *totface) /* check for same number of faces as start edge */
+ return 0;
+
+ /* tag the faces */
+ for(iterv1=first1; iterv1; iterv1=iterv1->next) {
+ if(iterv1->separate && iterv1 != first1)
+ break;
+
+ for(iterv2=first2; iterv2; iterv2=iterv2->next) {
+ if(iterv2->separate && iterv2 != first2)
+ break;
+
+ if(iterv1->f == iterv2->f) {
+ efa= EM_get_face_for_index(iterv1->f);
+ efa->f1= 1;
+ break;
}
- if (tf->flag & TF_SEL3) {
- DO_MINMAX2(tf->uv[2], min, max);
+ }
+ }
+
+ return 1;
+}
+
+void select_edgeloop_tface_uv(EditFace *startefa, int starta, int shift, int *flush)
+{
+ EditMesh *em= G.editMesh;
+ EditVert *eve;
+ EditFace *efa;
+ MTFace *tface;
+ UvVertMap *vmap;
+ UvMapVert *iterv1, *iterv2;
+ float limit[2];
+ int a, count, looking, nverts, starttotface, select;
+
+ if( is_uv_tface_editing_allowed()==0 ) return;
+
+ /* setup */
+ EM_init_index_arrays(0, 0, 1);
+
+ get_connected_limit_tface_uv(limit);
+ vmap= make_uv_vert_map_EM(0, 0, limit);
+
+ for(count=0, eve=em->verts.first; eve; count++, eve= eve->next)
+ eve->tmp.l = count;
+
+ for(count=0, efa= em->faces.first; efa; count++, efa= efa->next) {
+ if(!shift) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ simaFaceSel_UnSet(efa, tface);
+ }
+
+ efa->tmp.l= count;
+ efa->f1= 0;
+ }
+
+ /* set flags for first face and verts */
+ nverts= (startefa->v4)? 4: 3;
+ iterv1= uv_vertex_map_get(vmap, startefa, starta);
+ iterv2= uv_vertex_map_get(vmap, startefa, (starta+1)%nverts);
+ uv_vertex_loop_flag(iterv1);
+ uv_vertex_loop_flag(iterv2);
+
+ starttotface= 0;
+ uv_edge_tag_faces(iterv1, iterv2, &starttotface);
+
+ /* sorry, first edge isnt even ok */
+ if(iterv1->flag==0 && iterv2->flag==0) looking= 0;
+ else looking= 1;
+
+ /* iterate */
+ while(looking) {
+ looking= 0;
+
+ /* find correct valence edges which are not tagged yet, but connect to tagged one */
+ for(efa= em->faces.first; efa; efa=efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ if(!efa->f1 && simaFaceDraw_Check(efa, tface)) {
+ nverts= (efa->v4)? 4: 3;
+ for(a=0; a<nverts; a++) {
+ /* check face not hidden and not tagged */
+ iterv1= uv_vertex_map_get(vmap, efa, a);
+ iterv2= uv_vertex_map_get(vmap, efa, (a+1)%nverts);
+
+ /* check if vertex is tagged and has right valence */
+ if(iterv1->flag || iterv2->flag) {
+ if(uv_edge_tag_faces(iterv1, iterv2, &starttotface)) {
+ looking= 1;
+ efa->f1= 1;
+
+ uv_vertex_loop_flag(iterv1);
+ uv_vertex_loop_flag(iterv2);
+ break;
+ }
+ }
+ }
}
- if (mf->v4 && tf->flag & TF_SEL4) {
- DO_MINMAX2(tf->uv[3], min, max);
+ }
+ }
+
+ /* do the actual select/deselect */
+ nverts= (startefa->v4)? 4: 3;
+ iterv1= uv_vertex_map_get(vmap, startefa, starta);
+ iterv2= uv_vertex_map_get(vmap, startefa, (starta+1)%nverts);
+ iterv1->flag= 1;
+ iterv2->flag= 1;
+
+ if(shift) {
+ tface= CustomData_em_get(&em->fdata, startefa->data, CD_MTFACE);
+ if(simaUVSel_Check(startefa, tface, starta) && simaUVSel_Check(startefa, tface, starta))
+ select= 0;
+ else
+ select= 1;
+ }
+ else
+ select= 1;
+
+ if(select) *flush= 1;
+ else *flush= -1;
+
+ for(efa= em->faces.first; efa; efa=efa->next) {
+ tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ nverts= (efa->v4)? 4: 3;
+ for(a=0; a<nverts; a++) {
+ iterv1= uv_vertex_map_get(vmap, efa, a);
+
+ if(iterv1->flag) {
+ if(select) simaUVSel_Set(efa, tface, a);
+ else simaUVSel_UnSet(efa, tface, a);
}
+ }
+ }
+
+ /* cleanup */
+ free_uv_vert_map_EM(vmap);
+ EM_free_index_arrays();
+}
+int minmax_tface_uv(float *min, float *max)
+{
+ EditMesh *em= G.editMesh;
+ EditFace *efa;
+ MTFace *tf;
+ int sel;
+
+ if( is_uv_tface_editing_allowed()==0 ) return 0;
+
+ INIT_MINMAX2(min, max);
+
+ sel= 0;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if (simaUVSel_Check(efa, tf, 0)) DO_MINMAX2(tf->uv[0], min, max);
+ if (simaUVSel_Check(efa, tf, 1)) DO_MINMAX2(tf->uv[1], min, max);
+ if (simaUVSel_Check(efa, tf, 2)) DO_MINMAX2(tf->uv[2], min, max);
+ if (efa->v4 && (simaUVSel_Check(efa, tf, 3))) DO_MINMAX2(tf->uv[3], min, max);
sel = 1;
}
}
-
return sel;
}
+int cent_tface_uv(float *cent, int mode)
+{
+ float min[2], max[2];
+ short change= 0;
+
+ if (mode==0) {
+ if (minmax_tface_uv(min, max))
+ change = 1;
+
+ } else if (mode==1) {
+ EditFace *efa;
+ MTFace *tf;
+ INIT_MINMAX2(min, max);
+
+ for (efa= G.editMesh->faces.first; efa; efa= efa->next) {
+ tf = CustomData_em_get(&G.editMesh->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if (simaUVSel_Check(efa, tf, 0)) { DO_MINMAX2(tf->uv[0], min, max); change= 1;}
+ if (simaUVSel_Check(efa, tf, 1)) { DO_MINMAX2(tf->uv[1], min, max); change= 1;}
+ if (simaUVSel_Check(efa, tf, 2)) { DO_MINMAX2(tf->uv[2], min, max); change= 1;}
+ if (efa->v4 && (simaUVSel_Check(efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); change= 1;}
+ }
+ }
+ }
+
+ if (change) {
+ cent[0]= (min[0]+max[0])/2.0;
+ cent[1]= (min[1]+max[1])/2.0;
+ return 1;
+ }
+ return 0;
+}
+
static void sima_show_info(int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf)
{
short ofs;
@@ -1471,7 +2154,7 @@ static void sima_show_info(int channels, int x, int y, char *cp, float *fp, int
void sima_sample_color(void)
{
- ImBuf *ibuf= BKE_image_get_ibuf(G.sima->image, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
float fx, fy;
short mval[2], mvalo[2], firsttime=1;
@@ -1490,6 +2173,7 @@ void sima_sample_color(void)
if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) {
float *fp= NULL, *zpf= NULL;
+ float vec[3];
int *zp= NULL;
char *cp= NULL;
@@ -1508,14 +2192,14 @@ void sima_sample_color(void)
if(ibuf->rect_float)
fp= (ibuf->rect_float + (ibuf->channels)*(y*ibuf->x + x));
+ if(fp==NULL) {
+ fp= vec;
+ vec[0]= (float)cp[0]/255.0f;
+ vec[1]= (float)cp[1]/255.0f;
+ vec[2]= (float)cp[2]/255.0f;
+ }
+
if(G.sima->cumap) {
- float vec[3];
- if(fp==NULL) {
- fp= vec;
- vec[0]= (float)cp[0]/255.0f;
- vec[1]= (float)cp[1]/255.0f;
- vec[2]= (float)cp[2]/255.0f;
- }
if(ibuf->channels==4) {
if(G.qual & LR_CTRLKEY) {
@@ -1529,18 +2213,36 @@ void sima_sample_color(void)
}
}
+ {
+ ScrArea *sa, *cur= curarea;
+
+ node_curvemap_sample(fp); /* sends global to node editor */
+ for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ if(sa->spacetype==SPACE_NODE) {
+ areawinset(sa->win);
+ scrarea_do_windraw(sa);
+ }
+ }
+ node_curvemap_sample(NULL); /* clears global in node editor */
+ curarea= cur;
+ }
+
+ areawinset(curarea->win);
scrarea_do_windraw(curarea);
myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
glLoadIdentity();
- sima_show_info(ibuf->channels, x, y, cp, fp, zp, zpf);
+
+ sima_show_info(ibuf->channels, x, y, cp, (ibuf->rect_float)?fp:NULL, zp, zpf);
+
screen_swapbuffers();
+
}
-
}
BIF_wait_for_statechange();
}
scrarea_queue_winredraw(curarea);
+
}
/* Image functions */
@@ -1548,95 +2250,33 @@ void sima_sample_color(void)
static void load_image_filesel(char *str) /* called from fileselect */
{
Image *ima= NULL;
-
- if(G.obedit) {
- error("Can't perfom this in editmode");
- return;
- }
ima= BKE_add_image_file(str);
if(ima) {
-
- G.sima->image= ima;
-
BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
- image_changed(G.sima, 0);
-
+ image_changed(G.sima, ima);
}
BIF_undo_push("Load image UV");
allqueue(REDRAWIMAGE, 0);
}
-static void image_replace(Image *old, Image *new)
-{
- MTFace *tface;
- Mesh *me;
- int a, rep=0;
-
- new->tpageflag= old->tpageflag;
- new->twsta= old->twsta;
- new->twend= old->twend;
- new->xrep= old->xrep;
- new->yrep= old->yrep;
-
- me= G.main->mesh.first;
- while(me) {
-
- if(me->id.lib==NULL && me->mtface) {
- tface= me->mtface;
- a= me->totface;
- while(a--) {
- if(tface->tpage==old) {
- tface->tpage= new;
- rep++;
- }
- tface++;
- }
- }
- me= me->id.next;
-
- }
- if(rep) {
- if(new->id.us==0) id_us_plus(&new->id);
- else id_lib_extern(&new->id);
-
- }
- else error("Nothing replaced");
-}
-
static void replace_image_filesel(char *str) /* called from fileselect */
{
- Image *ima=0;
-
- if(G.obedit) {
- error("Can't perfom this in editmode");
+ if (!G.sima->image)
return;
- }
-
- ima= BKE_add_image_file(str);
- if(ima) {
-
- if(G.sima->image && G.sima->image != ima) {
- image_replace(G.sima->image, ima);
- }
-
- G.sima->image= ima;
-
- BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
-
- /* replace also assigns: */
- image_changed(G.sima, 0);
-
- }
+
+ strncpy(G.sima->image->name, str, sizeof(G.sima->image->name)-1); /* we cant do much if the str is longer then 240 :/ */
+ BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
BIF_undo_push("Replace image UV");
allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
static void save_image_doit(char *name)
{
Image *ima= G.sima->image;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
int len;
char str[FILE_MAXDIR+FILE_MAXFILE];
@@ -1645,8 +2285,10 @@ static void save_image_doit(char *name)
BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
- if(G.scene->r.scemode & R_EXTENSION)
+ if(G.scene->r.scemode & R_EXTENSION) {
BKE_add_image_extension(str, G.sima->imtypenr);
+ BKE_add_image_extension(name, G.sima->imtypenr);
+ }
if (saveover(str)) {
@@ -1764,7 +2406,7 @@ static char *filesel_imagetype_string(Image *ima)
void save_as_image_sima(void)
{
Image *ima = G.sima->image;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
char name[FILE_MAXDIR+FILE_MAXFILE];
if (ima) {
@@ -1779,7 +2421,7 @@ void save_as_image_sima(void)
if(ima->rr && !(ima->source==IMA_SRC_SEQUENCE && ima->type==IMA_TYPE_MULTILAYER))
G.sima->imtypenr= R_MULTILAYER;
else if(ima->type==IMA_TYPE_R_RESULT)
- G.sima->imtypenr= R_MULTILAYER;
+ G.sima->imtypenr= G.scene->r.imtype;
else G.sima->imtypenr= BKE_ftype_to_imtype(ibuf->ftype);
activate_fileselect_menu(FILE_SPECIAL, "Save Image", name, strp, &G.sima->imtypenr, save_image_doit);
@@ -1791,7 +2433,7 @@ void save_as_image_sima(void)
void save_image_sima(void)
{
Image *ima = G.sima->image;
- ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
char name[FILE_MAXDIR+FILE_MAXFILE];
if (ima) {
@@ -1867,10 +2509,9 @@ void save_image_sequence_sima(void)
void reload_image_sima(void)
{
-
if (G.sima ) {
BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_RELOAD);
- image_changed(G.sima, 0);
+ /* image_changed(G.sima, 0); - do we really need this? */
}
allqueue(REDRAWIMAGE, 0);
@@ -1880,26 +2521,28 @@ void reload_image_sima(void)
void new_image_sima(void)
{
- static int width= 256, height= 256;
+ static int width= 1024, height= 1024;
static short uvtestgrid= 0;
+ static int floatbuf=0;
static float color[] = {0, 0, 0, 1};
char name[22];
-
+ Image *ima;
+
strcpy(name, "Untitled");
add_numbut(0, TEX, "Name:", 0, 21, name, NULL);
- add_numbut(1, NUM|INT, "Width:", 1, 5000, &width, NULL);
- add_numbut(2, NUM|INT, "Height:", 1, 5000, &height, NULL);
+ add_numbut(1, NUM|INT, "Width:", 1, 16384, &width, NULL);
+ add_numbut(2, NUM|INT, "Height:", 1, 16384, &height, NULL);
add_numbut(3, COL, "", 0, 0, &color, NULL);
add_numbut(4, NUM|FLO, "Alpha:", 0.0, 1.0, &color[3], NULL);
add_numbut(5, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL);
- if (!do_clever_numbuts("New Image", 6, REDRAW))
+ add_numbut(6, TOG|INT, "32 bit Float", 0, 0, &floatbuf, NULL);
+ if (!do_clever_numbuts("New Image", 7, REDRAW))
return;
- G.sima->image= BKE_add_image_size(width, height, name, uvtestgrid, color);
+ ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color);
+ image_changed(G.sima, ima);
BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
- image_changed(G.sima, 0);
-
BIF_undo_push("Add image");
allqueue(REDRAWIMAGE, 0);
@@ -1923,7 +2566,7 @@ void pack_image_sima()
}
}
else {
- ImBuf *ibuf= BKE_image_get_ibuf(ima, &G.sima->iuser);
+ ImBuf *ibuf= imagewindow_get_ibuf(G.sima);
if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
if(okee("Can't pack painted image. Use Repack as PNG?"))
BKE_image_memorypack(ima);
@@ -1989,3 +2632,113 @@ void BIF_image_update_frame(void)
}
}
+void aspect_sima(SpaceImage *sima, float *x, float *y)
+{
+ *x = *y = 1.0;
+
+ if( (sima->image == 0) ||
+ (sima->image->type == IMA_TYPE_R_RESULT) ||
+ (sima->image->type == IMA_TYPE_COMPOSITE) ||
+ (sima->image->tpageflag & IMA_TILES) ||
+ (sima->image->aspx==0.0 || sima->image->aspy==0.0)
+ ) {
+ return;
+ }
+
+ /* x is always 1 */
+ *y = sima->image->aspy / sima->image->aspx;
+}
+
+
+/* Face selection tests - Keep these together */
+
+/* this checks weather a face is drarn without the local image check */
+int simaFaceDraw_Check_nolocal( EditFace *efa )
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ return (efa->h==0);
+ } else {
+ return (efa->h==0 && efa->f & SELECT);
+ }
+ return 0;
+}
+
+int simaFaceDraw_Check( EditFace *efa, MTFace *tf )
+{
+ if (G.sima && G.sima->flag & SI_LOCAL_UV) {
+ if (tf->tpage==G.sima->image) {
+ return simaFaceDraw_Check_nolocal(efa);
+ } else {
+ return 0;
+ }
+ } else {
+ return simaFaceDraw_Check_nolocal(efa);
+ }
+}
+
+int simaFaceSel_Check( struct EditFace *efa, struct MTFace *tf )
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ return (efa->f & SELECT);
+ } else {
+ return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4));
+ }
+}
+
+void simaFaceSel_Set( struct EditFace *efa, struct MTFace *tf )
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ EM_select_face(efa, 1);
+ } else {
+ tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+}
+
+void simaFaceSel_UnSet( struct EditFace *efa, struct MTFace *tf )
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ EM_select_face(efa, 0);
+ } else {
+ tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+ }
+}
+
+int simaUVSel_Check( struct EditFace *efa, struct MTFace *tf, int i)
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ if (G.scene->selectmode == SCE_SELECT_FACE) {
+ return efa->f & SELECT;
+ } else {
+ return (*(&efa->v1 + i))->f & SELECT;
+ }
+ } else {
+ return tf->flag & TF_SEL_MASK(i);
+ }
+}
+
+void simaUVSel_Set( struct EditFace *efa, struct MTFace *tf, int i)
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ if (G.scene->selectmode == SCE_SELECT_FACE) {
+ EM_select_face(efa, 1);
+ } else {
+ (*(&efa->v1 + i))->f |= SELECT;
+ }
+ } else {
+ tf->flag |= TF_SEL_MASK(i);
+ }
+}
+
+void simaUVSel_UnSet( struct EditFace *efa, struct MTFace *tf, int i)
+{
+ if (G.sima && G.sima->flag & SI_SYNC_UVSEL) {
+ if (G.scene->selectmode == SCE_SELECT_FACE) {
+ EM_select_face(efa, 0);
+ } else {
+ (*(&efa->v1 + i))->f &= ~SELECT;
+ }
+ } else {
+ tf->flag &= ~TF_SEL_MASK(i);
+ }
+}
+
diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c
index e167ebbafb4..38098bdb35d 100644
--- a/source/blender/src/editsound.c
+++ b/source/blender/src/editsound.c
@@ -123,7 +123,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -143,7 +143,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
- cfra = (int)dx;
+ cfra = (int)(dx+0.5f);
if(cfra< 1) cfra= 1;
if( cfra!=CFRA || first )
@@ -173,7 +173,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
- marker = find_nearest_marker(0);
+ marker = find_nearest_marker(SCE_MARKERS, 0);
if (marker) {
if ((G.qual & LR_SHIFTKEY)==0)
deselect_markers(0, 0);
@@ -219,11 +219,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case AKEY: /* select/deselect all */
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case BKEY: /* borderselect markers */
@@ -234,11 +230,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if (G.qual & LR_SHIFTKEY) {
duplicate_marker();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
@@ -252,11 +244,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else
add_marker(CFRA);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case TKEY: /* toggle time display */
@@ -273,12 +261,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case XKEY:
if (okee("Erase selected")) {
remove_marker();
-
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
break;
}
diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c
index 83e8e5473e1..34c5bb0ff96 100644
--- a/source/blender/src/edittime.c
+++ b/source/blender/src/edittime.c
@@ -103,6 +103,8 @@ void add_marker(int frame)
BIF_undo_push("Add Marker");
}
+
+
/* remove selected TimeMarkers */
void remove_marker(void)
{
@@ -167,6 +169,8 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
{
SpaceLink *slink= curarea->spacedata.first;
SpaceTime *stime= curarea->spacedata.first;
+ SpaceAction *saction = curarea->spacedata.first;
+ ListBase *markers;
TimeMarker *marker, *selmarker=NULL;
float dx, fac;
int a, ret_val= 0, totmark=0, *oldframe, offs, firsttime=1;
@@ -174,16 +178,26 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
short val, pmval[2], mval[2], mvalo[2];
char str[32];
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) totmark++;
+ /* hack for pose-markers in action editor */
+ if ((slink->spacetype == SPACE_ACTION) && (saction->flag & SACTION_POSEMARKERS_MOVE)) {
+ if (saction->action)
+ markers= &saction->action->markers;
+ else
+ markers= NULL;
}
- if(totmark==0) return;
+ else
+ markers= &G.scene->markers;
+
+ for (marker= markers->first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) totmark++;
+ }
+ if (totmark==0) return;
oldframe= MEM_mallocN(totmark*sizeof(int), "marker array");
- for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) {
+ for (a=0, marker= markers->first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) {
oldframe[a]= marker->frame;
- selmarker= marker; // used for hederprint
+ selmarker= marker; // used for headerprint
a++;
}
}
@@ -194,8 +208,7 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
getmouseco_areawin(pmval);
mvalo[0]= pmval[0];
- while(ret_val == 0) {
-
+ while (ret_val == 0) {
getmouseco_areawin(mval);
if (mval[0] != mvalo[0] || firsttime) {
@@ -205,35 +218,49 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
fac= (((float)(mval[0] - pmval[0]))*dx);
if (ELEM(slink->spacetype, SPACE_TIME, SPACE_SOUND))
- apply_keyb_grid(&fac, 0.0, (float)G.scene->r.frs_sec, 0.1*(float)G.scene->r.frs_sec, 0);
+ apply_keyb_grid(&fac, 0.0, FPS, 0.1*FPS, 0);
else
apply_keyb_grid(&fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID);
offs= (int)fac;
- for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) {
+ for (a=0, marker= markers->first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) {
marker->frame= oldframe[a] + offs;
a++;
}
}
- if(totmark==1) { // we print current marker value
+ if (totmark==1) {
+ /* we print current marker value */
if (ELEM(slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
- if(stime->flag & TIME_DRAWFRAMES)
+ if (stime->flag & TIME_DRAWFRAMES)
sprintf(str, "Marker %d offset %d", selmarker->frame, offs);
else
- sprintf(str, "Marker %.2f offset %.2f", (selmarker->frame/(float)G.scene->r.frs_sec), (offs/(float)G.scene->r.frs_sec));
+ sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
+ }
+ else if (slink->spacetype == SPACE_ACTION) {
+ if (saction->flag & SACTION_DRAWTIME)
+ sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
+ else
+ sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
}
else {
sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
}
}
else {
+ /* we only print the offset */
if (ELEM(slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
- if(stime->flag & TIME_DRAWFRAMES)
+ if (stime->flag & TIME_DRAWFRAMES)
sprintf(str, "Marker offset %d ", offs);
else
- sprintf(str, "Marker offset %.2f ", (offs/(float)G.scene->r.frs_sec));
+ sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
+ }
+ else if (slink->spacetype == SPACE_ACTION) {
+ if (saction->flag & SACTION_DRAWTIME)
+ sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
+ else
+ sprintf(str, "Marker offset %.2f ", (double)(offs));
}
else {
sprintf(str, "Marker offset %.2f ", (double)(offs));
@@ -246,20 +273,20 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
else PIL_sleep_ms(10); // idle
/* emptying queue and reading events */
- while( qtest() ) {
+ while ( qtest() ) {
event= extern_qread(&val);
- if(val) {
- if(event==ESCKEY || event==RIGHTMOUSE) ret_val= 2;
- else if(event==LEFTMOUSE || event==RETKEY || event==SPACEKEY) ret_val= 1;
+ if (val) {
+ if (ELEM(event, ESCKEY, RIGHTMOUSE)) ret_val= 2;
+ else if (ELEM3(event, LEFTMOUSE, RETKEY, SPACEKEY)) ret_val= 1;
}
}
}
/* restore? */
- if(ret_val==2) {
- for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
- if(marker->flag & SELECT) {
+ if (ret_val==2) {
+ for (a=0, marker= markers->first; marker; marker= marker->next) {
+ if (marker->flag & SELECT) {
marker->frame= oldframe[a];
a++;
}
@@ -269,11 +296,7 @@ void transform_markers(int mode, int smode) // mode and smode unused here, for c
BIF_undo_push("Move Markers");
}
MEM_freeN(oldframe);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
/* select/deselect all TimeMarkers
@@ -374,11 +397,7 @@ void borderselect_markers(void)
borderselect_markers_func(rectf.xmin, rectf.xmax, selectmode);
BIF_undo_push("Border Select Markers");
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
}
@@ -466,7 +485,7 @@ void get_minmax_markers(short sel, float *first, float *last)
*last= max;
}
-TimeMarker *find_nearest_marker(int clip_y)
+TimeMarker *find_nearest_marker(ListBase *markers, int clip_y)
{
TimeMarker *marker;
float xmin, xmax;
@@ -476,7 +495,7 @@ TimeMarker *find_nearest_marker(int clip_y)
getmouseco_areawin (mval);
/* first clip selection in Y */
- if((clip_y) && (mval[1] > 30))
+ if ((clip_y) && (mval[1] > 30))
return NULL;
mval[0]-=7;
@@ -487,7 +506,7 @@ TimeMarker *find_nearest_marker(int clip_y)
xmin= rectf.xmin;
xmax= rectf.xmax;
- for(marker= G.scene->markers.first; marker; marker= marker->next) {
+ for (marker= markers->first; marker; marker= marker->next) {
if ((marker->frame > xmin) && (marker->frame <= xmax)) {
return marker;
}
@@ -599,6 +618,8 @@ void anim_previewrange_set()
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
/* set preview-range */
+ if (rectf.xmin < 1) rectf.xmin = 1.0f;
+ if (rectf.xmax < 1) rectf.xmax = 1.0f;
G.scene->r.psfra= rectf.xmin;
G.scene->r.pefra= rectf.xmax;
@@ -726,6 +747,27 @@ void nextprev_timeline_key(short dir)
}
}
+/* return the current marker for this frame,
+we can have more then 1 marker per frame, this just returns the first :/ */
+TimeMarker *get_frame_marker(int frame)
+{
+ TimeMarker *marker, *best_marker = NULL;
+ int best_frame = -MAXFRAME*2;
+ for (marker= G.scene->markers.first; marker; marker= marker->next) {
+ if (marker->frame==frame) {
+ return marker;
+ }
+
+ if ( marker->frame > best_frame && marker->frame < frame) {
+ best_marker = marker;
+ best_frame = marker->frame;
+ }
+ }
+
+ return best_marker;
+}
+
+
void timeline_frame_to_center(void)
{
float dtime;
@@ -806,7 +848,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
- if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&sa->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -826,7 +868,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
- cfra = (int)dx;
+ cfra = (int)(dx+0.5f);
if(cfra< MINFRAME) cfra= MINFRAME;
if( cfra!=CFRA || first )
@@ -847,9 +889,9 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case RIGHTMOUSE: /* select/deselect marker */
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
-
+
cfra= find_nearest_marker_time(dx);
-
+
if (G.qual && LR_SHIFTKEY)
select_timeline_marker_frame(cfra, 1);
else
@@ -904,11 +946,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case AKEY:
/* deselect all TimeMarkers */
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case BKEY:
/* borderselect markers */
@@ -939,11 +977,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
rename_marker();
else
add_marker(CFRA);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case PKEY: /* preview-range stuff */
if (G.qual & LR_CTRLKEY) /* set preview range */
@@ -974,11 +1008,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if( okee("Erase selected")==0 ) break;
remove_marker();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
}
}
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index 9bed12cb3da..edaec5fb268 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -64,6 +64,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
+#include "BLI_rand.h" /* random object selection */
#include "BKE_armature.h"
#include "BKE_depsgraph.h"
@@ -73,11 +74,15 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_object.h" /* fly mode where_is_object to get camera location */
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
+#include "BIF_drawimage.h"
#include "BIF_butspace.h"
#include "BIF_editaction.h"
#include "BIF_editarmature.h"
+#include "BIF_editparticle.h"
#include "BIF_editgroup.h"
#include "BIF_editmesh.h"
#include "BIF_editoops.h"
@@ -246,7 +251,7 @@ static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2)
#define MOVES_GESTURE 50
#define MOVES_LASSO 500
-static int lasso_inside(short mcords[][2], short moves, short sx, short sy)
+int lasso_inside(short mcords[][2], short moves, short sx, short sy)
{
/* we do the angle rule, define that all added angles should be about zero or 2*PI */
float angletot=0.0, len, dot, ang, cross, fp1[2], fp2[2];
@@ -467,20 +472,81 @@ static void do_lasso_select_mesh(short mcords[][2], short moves, short select)
EM_selectmode_flush();
}
+/* this is an exception in that its the only lasso that dosnt use the 3d view (uses space image view) */
+static void do_lasso_select_mesh_uv(short mcords[][2], short moves, short select)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ MTFace *tf;
+ int screenUV[2], nverts, i, ok = 1;
+ rcti rect;
+
+ lasso_select_boundbox(&rect, mcords, moves);
+
+ if (draw_uvs_face_check()) { /* Face Center Sel */
+ float cent[2];
+ ok = 0;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ /* assume not touched */
+ efa->tmp.l = 0;
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if ((select) != (simaFaceSel_Check(efa, tf))) {
+ tface_center(tf, cent, (void *)efa->v4);
+ uvco_to_areaco_noclip(cent, screenUV);
+ if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
+ efa->tmp.l = ok = 1;
+ }
+ }
+ }
+ /* (de)selects all tagged faces and deals with sticky modes */
+ if (ok)
+ uvface_setsel__internal(select);
+
+ } else { /* Vert Sel*/
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ nverts= efa->v4? 4: 3;
+ for(i=0; i<nverts; i++) {
+ if ((select) != (simaUVSel_Check(efa, tf, i))) {
+ uvco_to_areaco_noclip(tf->uv[i], screenUV);
+ if (BLI_in_rcti(&rect, screenUV[0], screenUV[1]) && lasso_inside(mcords, moves, screenUV[0], screenUV[1])) {
+ if (select) {
+ simaUVSel_Set(efa, tf, i);
+ } else {
+ simaUVSel_UnSet(efa, tf, i);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (ok && G.sima->flag & SI_SYNC_UVSEL) {
+ if (select) EM_select_flush();
+ else EM_deselect_flush();
+ }
+}
+
static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
{
struct { short (*mcords)[2]; short moves; short select; } *data = userData;
if (lasso_inside(data->mcords, data->moves, x, y)) {
if (bp) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
} else {
- if (beztindex==0) {
- bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
- } else if (beztindex==1) {
- bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+ if (G.f & G_HIDDENHANDLES) {
+ /* can only be beztindex==0 here since handles are hidden */
+ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
} else {
- bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
+ if (beztindex==0) {
+ bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
+ } else if (beztindex==1) {
+ bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
+ } else {
+ bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
+ }
}
}
}
@@ -501,7 +567,7 @@ static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x,
struct { short (*mcords)[2]; short moves; short select; } *data = userData;
if (lasso_inside(data->mcords, data->moves, x, y)) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
}
}
static void do_lasso_select_lattice(short mcords[][2], short moves, short select)
@@ -574,16 +640,22 @@ static void do_lasso_select_facemode(short mcords[][2], short moves, short selec
static void do_lasso_select(short mcords[][2], short moves, short select)
{
if(G.obedit==NULL) {
- if(G.f & G_FACESELECT)
+ if(FACESEL_PAINT_TEST)
do_lasso_select_facemode(mcords, moves, select);
else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))
;
+ else if(G.f & G_PARTICLEEDIT)
+ PE_do_lasso_select(mcords, moves, select);
else
do_lasso_select_objects(mcords, moves, select);
}
- else if(G.obedit->type==OB_MESH)
- do_lasso_select_mesh(mcords, moves, select);
- else if(G.obedit->type==OB_CURVE || G.obedit->type==OB_SURF)
+ else if(G.obedit->type==OB_MESH) {
+ if(curarea->spacetype==SPACE_VIEW3D) {
+ do_lasso_select_mesh(mcords, moves, select);
+ } else if (EM_texFaceCheck()){
+ do_lasso_select_mesh_uv(mcords, moves, select);
+ }
+ } else if(G.obedit->type==OB_CURVE || G.obedit->type==OB_SURF)
do_lasso_select_curve(mcords, moves, select);
else if(G.obedit->type==OB_LATTICE)
do_lasso_select_lattice(mcords, moves, select);
@@ -591,7 +663,10 @@ static void do_lasso_select(short mcords[][2], short moves, short select)
do_lasso_select_armature(mcords, moves, select);
BIF_undo_push("Lasso select");
-
+
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
allqueue(REDRAWVIEW3D, 0);
countall();
}
@@ -748,6 +823,10 @@ int gesture(void)
if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) return 0;
}
lasso= 1;
+ } else if (curarea->spacetype==SPACE_IMAGE) {
+ if(G.obedit) {
+ lasso= 1;
+ }
}
}
@@ -968,6 +1047,31 @@ void selectswap(void)
BIF_undo_push("Select Inverse");
}
+/* inverts object selection */
+void selectrandom(void)
+{
+ Base *base;
+ static short randfac = 50;
+ if(button(&randfac,0, 100,"Percentage:")==0) return;
+
+ for(base= FIRSTBASE; base; base= base->next) {
+ if(base->lay & G.vd->lay &&
+ (base->object->restrictflag & OB_RESTRICT_VIEW)==0
+ ) {
+ if (!TESTBASE(base) && ( (BLI_frand() * 100) < randfac)) {
+ select_base_v3d(base, BA_SELECT);
+ base->object->flag= base->flag;
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWDATASELECT, 0);
+ allqueue(REDRAWNLA, 0);
+
+ countall();
+ BIF_undo_push("Select Random");
+}
/* selects all objects of a particular type, on currently visible layers */
void selectall_type(short obtype)
@@ -1087,22 +1191,8 @@ void set_active_base(Base *base)
Base *tbase;
/* activating a non-mesh, should end a couple of modes... */
- if(base) {
- if(base->object->type!=OB_MESH) {
- if(G.f & G_SCULPTMODE)
- set_sculptmode(); /* toggle */
- if(G.f & G_WEIGHTPAINT)
- set_wpaint(); /* toggle */
- if(G.f & G_VERTEXPAINT)
- set_vpaint(); /* toggle */
- if(G.f & G_TEXTUREPAINT)
- set_texturepaint(); /* Switch off tex paint */
- }
- /* always end this */
- if(G.f & G_FACESELECT) {
- set_faceselect(); /* toggle */
- }
- }
+ if(base && base->object->type!=OB_MESH)
+ exit_paint_modes();
/* sets scene->basact */
BASACT= base;
@@ -1282,7 +1372,7 @@ static short mixed_bones_object_selectbuffer(unsigned int *buffer, short *mval)
void mouse_select(void)
{
Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
- unsigned int buffer[MAXPICKBUF];
+ unsigned int buffer[4*MAXPICKBUF];
int temp, a, dist=100;
short hits, mval[2];
@@ -1535,14 +1625,19 @@ static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp,
if (BLI_in_rcti(data->rect, x, y)) {
if (bp) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
} else {
- if (beztindex==0) {
- bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
- } else if (beztindex==1) {
- bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+ if (G.f & G_HIDDENHANDLES) {
+ /* can only be beztindex==0 here since handles are hidden */
+ bezt->f1 = bezt->f2 = bezt->f3 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
} else {
- bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
+ if (beztindex==0) {
+ bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
+ } else if (beztindex==1) {
+ bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
+ } else {
+ bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
+ }
}
}
}
@@ -1562,7 +1657,7 @@ static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, i
struct { rcti *rect; int select; } *data = userData;
if (BLI_in_rcti(data->rect, x, y)) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
}
}
static void do_lattice_box_select(rcti *rect, int select)
@@ -1662,14 +1757,18 @@ void borderselect(void)
rcti rect;
Base *base;
MetaElem *ml;
- unsigned int buffer[MAXPICKBUF];
+ unsigned int buffer[4*MAXPICKBUF];
int a, index;
short hits, val;
- if(G.obedit==NULL && (G.f & G_FACESELECT)) {
+ if(G.obedit==NULL && (FACESEL_PAINT_TEST)) {
face_borderselect();
return;
}
+ else if(G.obedit==NULL && (G.f & G_PARTICLEEDIT)) {
+ PE_borderselect();
+ return;
+ }
a = 0;
#ifdef __APPLE__
@@ -1679,13 +1778,19 @@ void borderselect(void)
val= get_border(&rect, 3);
if (!a) setlinestyle(0);
- if(val==0)
+ if(val==0) {
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
return;
+ }
if(G.obedit) {
if(G.obedit->type==OB_MESH) {
do_mesh_box_select(&rect, (val==LEFTMOUSE));
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
do_nurbs_box_select(&rect, val==LEFTMOUSE);
@@ -1912,7 +2017,7 @@ static void mesh_selectionCB(int selecting, Object *editobj, short *mval, float
EditMesh *em = G.editMesh;
int bbsel;
- if(!G.obedit && (G.f&G_FACESELECT)) {
+ if(!G.obedit && (FACESEL_PAINT_TEST)) {
Mesh *me = get_mesh(OBACT);
if (me) {
@@ -1972,14 +2077,14 @@ static void nurbscurve_selectionCB__doSelect(void *userData, Nurb *nu, BPoint *b
if (r<=data->radius) {
if (bp) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
} else {
if (beztindex==0) {
- bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
+ bezt->f1 = data->select?(bezt->f1|SELECT):(bezt->f1&~SELECT);
} else if (beztindex==1) {
- bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+ bezt->f2 = data->select?(bezt->f2|SELECT):(bezt->f2&~SELECT);
} else {
- bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
+ bezt->f3 = data->select?(bezt->f3|SELECT):(bezt->f3&~SELECT);
}
}
}
@@ -2004,7 +2109,7 @@ static void latticecurve_selectionCB__doSelect(void *userData, BPoint *bp, int x
float r = sqrt(mx*mx + my*my);
if (r<=data->radius) {
- bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+ bp->f1 = data->select?(bp->f1|SELECT):(bp->f1&~SELECT);
}
}
static void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad)
@@ -2057,15 +2162,26 @@ void set_render_border(void)
G.scene->r.border.ymin= ((float)rect.ymin-vb.ymin)/(vb.ymax-vb.ymin);
G.scene->r.border.xmax= ((float)rect.xmax-vb.xmin)/(vb.xmax-vb.xmin);
G.scene->r.border.ymax= ((float)rect.ymax-vb.ymin)/(vb.ymax-vb.ymin);
-
+
CLAMP(G.scene->r.border.xmin, 0.0, 1.0);
CLAMP(G.scene->r.border.ymin, 0.0, 1.0);
CLAMP(G.scene->r.border.xmax, 0.0, 1.0);
CLAMP(G.scene->r.border.ymax, 0.0, 1.0);
-
+
allqueue(REDRAWVIEWCAM, 1);
- /* if it was not set, we do this */
- G.scene->r.mode |= R_BORDER;
+
+ /* drawing a border surrounding the entire camera view switches off border rendering
+ * or the border covers no pixels */
+ if ((G.scene->r.border.xmin <= 0.0 && G.scene->r.border.xmax >= 1.0 &&
+ G.scene->r.border.ymin <= 0.0 && G.scene->r.border.ymax >= 1.0) ||
+ (G.scene->r.border.xmin == G.scene->r.border.xmax ||
+ G.scene->r.border.ymin == G.scene->r.border.ymax ))
+ {
+ G.scene->r.mode &= ~R_BORDER;
+ } else {
+ G.scene->r.mode |= R_BORDER;
+ }
+
allqueue(REDRAWBUTSSCENE, 1);
}
}
@@ -2546,18 +2662,18 @@ void fly(void)
G.vd->persp= 2;
/* record the motion */
- if (G.flags & G_RECORDKEYS && (!playing_anim || cfra != G.scene->r.cfra)) {
+ if (IS_AUTOKEY_MODE(NORMAL) && (!playing_anim || cfra != G.scene->r.cfra)) {
cfra = G.scene->r.cfra;
if (xlock || zlock || moffset[0] || moffset[1]) {
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_X);
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_Y);
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_Z);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
}
if (speed) {
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_X);
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_Y);
- insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_Z);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(&G.vd->camera->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
}
}
}
@@ -2593,7 +2709,7 @@ void fly(void)
DAG_object_flush_update(G.scene, G.vd->camera, OB_RECALC_OB);
- if (G.flags & G_RECORDKEYS) {
+ if (IS_AUTOKEY_MODE(NORMAL)) {
allqueue(REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWNLA, 0);
@@ -2640,7 +2756,7 @@ void view3d_edit_clipping(View3D *v3d)
if(val==0) return;
v3d->flag |= V3D_CLIPPING;
- v3d->clipbb= MEM_mallocN(sizeof(BoundBox), "clipbb");
+ v3d->clipbb= MEM_callocN(sizeof(BoundBox), "clipbb");
/* convert border to 3d coordinates */
diff --git a/source/blender/src/filelist.c b/source/blender/src/filelist.c
new file mode 100644
index 00000000000..42940e5be04
--- /dev/null
+++ b/source/blender/src/filelist.c
@@ -0,0 +1,1137 @@
+/**
+ * $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.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+/* global includes */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <direct.h>
+#endif
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_storage_types.h"
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BIF_filelist.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BLO_readfile.h"
+
+#include "DNA_space_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_world_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
+
+#include "PIL_time.h"
+
+#include "datatoc.h"
+
+/* Elubie: VERY, really very ugly and evil! Remove asap!!! */
+/* for state of file */
+#define ACTIVE 2
+
+/* max length of library group name within filesel */
+#define GROUP_MAX 32
+
+typedef struct FileList
+{
+ struct direntry *filelist;
+ int *fidx;
+
+ int numfiles;
+ int numfiltered;
+ char dir[FILE_MAXDIR];
+ short type;
+ short ipotype;
+ struct BlendHandle *libfiledata;
+ int has_func;
+ short prv_w;
+ short prv_h;
+ short hide_dot;
+ unsigned int filter;
+} FileList;
+
+int BIF_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);
+}
+
+
+#define SPECIAL_IMG_SIZE 48
+#define SPECIAL_IMG_ROWS 4
+#define SPECIAL_IMG_COLS 4
+
+#define SPECIAL_IMG_FOLDER 0
+#define SPECIAL_IMG_PARENT 1
+#define SPECIAL_IMG_REFRESH 2
+#define SPECIAL_IMG_BLENDFILE 3
+#define SPECIAL_IMG_SOUNDFILE 4
+#define SPECIAL_IMG_MOVIEFILE 5
+#define SPECIAL_IMG_PYTHONFILE 6
+#define SPECIAL_IMG_TEXTFILE 7
+#define SPECIAL_IMG_FONTFILE 8
+#define SPECIAL_IMG_UNKNOWNFILE 9
+#define SPECIAL_IMG_MAX SPECIAL_IMG_UNKNOWNFILE + 1
+
+static ImBuf* gSpecialFileImages[SPECIAL_IMG_MAX];
+
+
+/* ******************* SORT ******************* */
+
+static int compare_name(const void *a1, const void *a2)
+{
+ const struct direntry *entry1=a1, *entry2=a2;
+
+ /* type is is equal to stat.st_mode */
+
+ if (S_ISDIR(entry1->type)){
+ if (S_ISDIR(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISDIR(entry2->type)) return (1);
+ }
+ if (S_ISREG(entry1->type)){
+ if (S_ISREG(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISREG(entry2->type)) return (1);
+ }
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
+
+ /* make sure "." and ".." are always first */
+ if( strcmp(entry1->relname, ".")==0 ) return (-1);
+ if( strcmp(entry2->relname, ".")==0 ) return (1);
+ if( strcmp(entry1->relname, "..")==0 ) return (-1);
+
+ return (BLI_strcasecmp(entry1->relname,entry2->relname));
+}
+
+static int compare_date(const void *a1, const void *a2)
+{
+ const struct direntry *entry1=a1, *entry2=a2;
+
+ /* type is equal to stat.st_mode */
+
+ if (S_ISDIR(entry1->type)){
+ if (S_ISDIR(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISDIR(entry2->type)) return (1);
+ }
+ if (S_ISREG(entry1->type)){
+ if (S_ISREG(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISREG(entry2->type)) return (1);
+ }
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
+
+ /* make sure "." and ".." are always first */
+ if( strcmp(entry1->relname, ".")==0 ) return (-1);
+ if( strcmp(entry2->relname, ".")==0 ) return (1);
+ if( strcmp(entry1->relname, "..")==0 ) return (-1);
+
+ if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1;
+ if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1;
+
+ else return BLI_strcasecmp(entry1->relname,entry2->relname);
+}
+
+static int compare_size(const void *a1, const void *a2)
+{
+ const struct direntry *entry1=a1, *entry2=a2;
+
+ /* type is equal to stat.st_mode */
+
+ if (S_ISDIR(entry1->type)){
+ if (S_ISDIR(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISDIR(entry2->type)) return (1);
+ }
+ if (S_ISREG(entry1->type)){
+ if (S_ISREG(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISREG(entry2->type)) return (1);
+ }
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
+
+ /* make sure "." and ".." are always first */
+ if( strcmp(entry1->relname, ".")==0 ) return (-1);
+ if( strcmp(entry2->relname, ".")==0 ) return (1);
+ if( strcmp(entry1->relname, "..")==0 ) return (-1);
+
+ if ( entry1->s.st_size < entry2->s.st_size) return 1;
+ if ( entry1->s.st_size > entry2->s.st_size) return -1;
+ else return BLI_strcasecmp(entry1->relname,entry2->relname);
+}
+
+static int compare_extension(const void *a1, const void *a2) {
+ const struct direntry *entry1=a1, *entry2=a2;
+ char *sufix1, *sufix2;
+ char *nil="";
+
+ if (!(sufix1= strstr (entry1->relname, ".blend.gz")))
+ sufix1= strrchr (entry1->relname, '.');
+ if (!(sufix2= strstr (entry2->relname, ".blend.gz")))
+ sufix2= strrchr (entry2->relname, '.');
+ if (!sufix1) sufix1= nil;
+ if (!sufix2) sufix2= nil;
+
+ /* type is is equal to stat.st_mode */
+
+ if (S_ISDIR(entry1->type)){
+ if (S_ISDIR(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISDIR(entry2->type)) return (1);
+ }
+ if (S_ISREG(entry1->type)){
+ if (S_ISREG(entry2->type)==0) return (-1);
+ } else{
+ if (S_ISREG(entry2->type)) return (1);
+ }
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
+
+ /* make sure "." and ".." are always first */
+ if( strcmp(entry1->relname, ".")==0 ) return (-1);
+ if( strcmp(entry2->relname, ".")==0 ) return (1);
+ if( strcmp(entry1->relname, "..")==0 ) return (-1);
+ if( strcmp(entry2->relname, "..")==0 ) return (-1);
+
+ return (BLI_strcasecmp(sufix1, sufix2));
+}
+
+void BIF_filelist_filter(FileList* filelist)
+{
+ char dir[FILE_MAX], group[GROUP_MAX];
+ int num_filtered = 0;
+ int i, j;
+
+ if (!filelist->filelist)
+ return;
+
+ 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);
+ filelist->fidx = NULL;
+ }
+ filelist->fidx = (int *)MEM_callocN(filelist->numfiles*sizeof(int), "filteridx");
+ for (i = 0; i < filelist->numfiles; ++i) {
+ filelist->fidx[i] = i;
+ }
+ filelist->numfiltered = filelist->numfiles;
+ return;
+ }
+
+ // How many files are left after filter ?
+ for (i = 0; i < filelist->numfiles; ++i) {
+ if (filelist->filelist[i].flags & filelist->filter) {
+ num_filtered++;
+ }
+ else if (filelist->filelist[i].type & S_IFDIR) {
+ if (filelist->filter & FOLDERFILE) {
+ num_filtered++;
+ }
+ }
+ }
+
+ if (filelist->fidx) {
+ MEM_freeN(filelist->fidx);
+ filelist->fidx = NULL;
+ }
+ filelist->fidx = (int *)MEM_callocN(num_filtered*sizeof(int), "filteridx");
+ filelist->numfiltered = num_filtered;
+
+ for (i = 0, j=0; i < filelist->numfiles; ++i) {
+ if (filelist->filelist[i].flags & filelist->filter) {
+ filelist->fidx[j++] = i;
+ }
+ else if (filelist->filelist[i].type & S_IFDIR) {
+ if (filelist->filter & FOLDERFILE) {
+ filelist->fidx[j++] = i;
+ }
+ }
+ }
+}
+
+void BIF_filelist_init_icons()
+{
+ short x, y, k;
+ ImBuf *bbuf;
+ ImBuf *ibuf;
+ bbuf = IMB_ibImageFromMemory((int *)datatoc_prvicons, datatoc_prvicons_size, IB_rect);
+ if (bbuf) {
+ for (y=0; y<SPECIAL_IMG_ROWS; y++) {
+ for (x=0; x<SPECIAL_IMG_COLS; x++) {
+ int tile = SPECIAL_IMG_COLS*y + x;
+ if (tile < SPECIAL_IMG_MAX) {
+ ibuf = IMB_allocImBuf(SPECIAL_IMG_SIZE, SPECIAL_IMG_SIZE, 32, IB_rect, 0);
+ for (k=0; k<SPECIAL_IMG_SIZE; k++) {
+ memcpy(&ibuf->rect[k*SPECIAL_IMG_SIZE], &bbuf->rect[(k+y*SPECIAL_IMG_SIZE)*SPECIAL_IMG_SIZE*SPECIAL_IMG_COLS+x*SPECIAL_IMG_SIZE], SPECIAL_IMG_SIZE*sizeof(int));
+ }
+ gSpecialFileImages[tile] = ibuf;
+ }
+ }
+ }
+ IMB_freeImBuf(bbuf);
+ }
+
+}
+
+void BIF_filelist_free_icons()
+{
+ int i;
+ for (i=0; i < SPECIAL_IMG_MAX; ++i) {
+ IMB_freeImBuf(gSpecialFileImages[i]);
+ gSpecialFileImages[i] = NULL;
+ }
+}
+
+struct FileList* BIF_filelist_new()
+{
+ FileList* p = MEM_callocN( sizeof(FileList), "filelist" );
+ p->filelist = 0;
+ p->numfiles = 0;
+ p->dir[0] = '\0';
+ p->libfiledata = 0;
+ p->type = 0;
+ p->has_func = 0;
+ p->filter = 0;
+ return p;
+}
+
+struct FileList* BIF_filelist_copy(struct FileList* filelist)
+{
+ FileList* p = BIF_filelist_new();
+ BLI_strncpy(p->dir, filelist->dir, FILE_MAXDIR);
+ p->filelist = NULL;
+ p->fidx = NULL;
+ p->type = filelist->type;
+ p->ipotype = filelist->ipotype;
+ p->has_func = filelist->has_func;
+
+ return p;
+}
+
+void BIF_filelist_free(struct FileList* filelist)
+{
+ int i;
+
+ if (!filelist) {
+ printf("Attemtping to delete empty filelist.\n");
+ return;
+ }
+
+ if (filelist->fidx) {
+ MEM_freeN(filelist->fidx);
+ filelist->fidx = NULL;
+ }
+
+ for (i = 0; i < filelist->numfiles; ++i) {
+ if (filelist->filelist[i].image) {
+ IMB_freeImBuf(filelist->filelist[i].image);
+ }
+ filelist->filelist[i].image = 0;
+ if (filelist->filelist[i].relname)
+ MEM_freeN(filelist->filelist[i].relname);
+ filelist->filelist[i].relname = 0;
+ if (filelist->filelist[i].string)
+ MEM_freeN(filelist->filelist[i].string);
+ filelist->filelist[i].string = 0;
+ }
+
+ filelist->numfiles = 0;
+ free(filelist->filelist);
+ filelist->filelist = 0;
+ filelist->filter = 0;
+ filelist->numfiltered =0;
+}
+
+void BIF_filelist_freelib(struct FileList* filelist)
+{
+ if(filelist->libfiledata)
+ BLO_blendhandle_close(filelist->libfiledata);
+ filelist->libfiledata= 0;
+}
+
+struct BlendHandle *BIF_filelist_lib(struct FileList* filelist)
+{
+ return filelist->libfiledata;
+}
+
+int BIF_filelist_numfiles(struct FileList* filelist)
+{
+ return filelist->numfiltered;
+}
+
+const char * BIF_filelist_dir(struct FileList* filelist)
+{
+ return filelist->dir;
+}
+
+void BIF_filelist_setdir(struct FileList* filelist, const char *dir)
+{
+ BLI_strncpy(filelist->dir, dir, FILE_MAXDIR);
+}
+
+void BIF_filelist_imgsize(struct FileList* filelist, short w, short h)
+{
+ filelist->prv_w = w;
+ filelist->prv_h = h;
+}
+
+void BIF_filelist_loadimage(struct FileList* filelist, int index)
+{
+ ImBuf *imb = NULL;
+ int imgwidth = filelist->prv_w;
+ int imgheight = filelist->prv_h;
+ short ex, ey, dx, dy;
+ float scaledx, scaledy;
+ int fidx = 0;
+
+ if ( (index < 0) || (index >= filelist->numfiltered) ) {
+ return;
+ }
+ fidx = filelist->fidx[index];
+
+ if (!filelist->filelist[fidx].image)
+ {
+ if (filelist->type != FILE_MAIN)
+ {
+ if ( filelist->filelist[fidx].flags & IMAGEFILE ) {
+ imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_IMAGE);
+ } else if ( filelist->filelist[fidx].flags & MOVIEFILE ) {
+ imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_MOVIE);
+ if (!imb) {
+ /* remember that file can't be loaded via IMB_open_anim */
+ filelist->filelist[fidx].flags &= ~MOVIEFILE;
+ filelist->filelist[fidx].flags |= MOVIEFILE_ICON;
+ }
+ }
+ if (imb) {
+ if (imb->x > imb->y) {
+ scaledx = (float)imgwidth;
+ scaledy = ( (float)imb->y/(float)imb->x )*imgwidth;
+ }
+ else {
+ scaledy = (float)imgheight;
+ scaledx = ( (float)imb->x/(float)imb->y )*imgheight;
+ }
+ ex = (short)scaledx;
+ ey = (short)scaledy;
+
+ dx = imgwidth - ex;
+ dy = imgheight - ey;
+
+ IMB_scaleImBuf(imb, ex, ey);
+
+ }
+ filelist->filelist[fidx].image = imb;
+
+ }
+ }
+}
+
+struct ImBuf * BIF_filelist_getimage(struct FileList* filelist, int index)
+{
+ ImBuf* ibuf = NULL;
+ int fidx = 0;
+ if ( (index < 0) || (index >= filelist->numfiltered) ) {
+ return NULL;
+ }
+ fidx = filelist->fidx[index];
+ ibuf = filelist->filelist[fidx].image;
+
+ if (ibuf == NULL) {
+ struct direntry *file = &filelist->filelist[fidx];
+ if (file->type & S_IFDIR) {
+ if ( strcmp(filelist->filelist[fidx].relname, "..") == 0) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
+ } else if ( strcmp(filelist->filelist[fidx].relname, ".") == 0) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
+ } else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
+ }
+ } else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
+ }
+
+ if (file->flags & BLENDERFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
+ } else if ( (file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON) ) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
+ } else if (file->flags & SOUNDFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
+ } else if (file->flags & PYSCRIPTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
+ } else if (file->flags & FTFONTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
+ } else if (file->flags & TEXTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
+ }
+ }
+ return ibuf;
+}
+
+struct direntry * BIF_filelist_file(struct FileList* filelist, int index)
+{
+ int fidx = 0;
+
+ if ( (index < 0) || (index >= filelist->numfiltered) ) {
+ return NULL;
+ }
+ fidx = filelist->fidx[index];
+
+ return &filelist->filelist[fidx];
+}
+
+int BIF_filelist_find(struct FileList* filelist, char *file)
+{
+ int index = -1;
+ int i;
+ int fidx = -1;
+
+ if (!filelist->fidx)
+ return fidx;
+
+
+ for (i = 0; i < filelist->numfiles; ++i) {
+ if ( strcmp(filelist->filelist[i].relname, file) == 0) {
+ index = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < filelist->numfiltered; ++i) {
+ if (filelist->fidx[i] == index) {
+ fidx = i;
+ break;
+ }
+ }
+ return fidx;
+}
+
+void BIF_filelist_hidedot(struct FileList* filelist, short hide)
+{
+ filelist->hide_dot = hide;
+}
+
+void BIF_filelist_setfilter(struct FileList* filelist, unsigned int filter)
+{
+ filelist->filter = filter;
+}
+
+void BIF_filelist_readdir(struct FileList* filelist)
+{
+ char wdir[FILE_MAXDIR];
+ int finished = 0;
+
+ if (!filelist) return;
+ filelist->fidx = 0;
+ filelist->filelist = 0;
+
+ if(filelist->type==FILE_MAIN) {
+ BIF_filelist_from_main(filelist);
+ finished = 1;
+ } else if(filelist->type==FILE_LOADLIB) {
+ BLI_cleanup_dir(G.sce, filelist->dir);
+ BIF_filelist_from_library(filelist);
+ if(filelist->libfiledata) {
+ finished = 1;
+ }
+ }
+
+ if (!finished) {
+ 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));
+
+ chdir(wdir);
+ BIF_filelist_setfiletypes(filelist, G.have_quicktime);
+ BIF_filelist_filter(filelist);
+
+ }
+}
+
+int BIF_filelist_empty(struct FileList* filelist)
+{
+ return filelist->filelist == 0;
+}
+
+void BIF_filelist_parent(struct FileList* filelist)
+{
+#ifdef WIN32
+ char c = '\\';
+#else
+ char c = '/';
+#endif
+ char *dir = filelist->dir;
+ size_t len = strlen(dir);
+
+ while( (len > 0) && (dir[len-1] == c) )
+ {
+ --len;
+ dir[len] = '\0';
+ }
+ while ( (len > 0) && (dir[len-1] != c) )
+ {
+ --len;
+ dir[len] = '\0';
+ }
+ if (len == 0)
+ {
+ dir[0] = c; dir[1] = '\0';
+ }
+#ifdef WIN32
+ strcat(filelist->dir, "\\");
+#else
+ strcat(filelist->dir, "/");
+#endif
+
+ BLI_cleanup_dir(G.sce, filelist->dir);
+ BLI_make_exist(filelist->dir);
+ BIF_filelist_readdir(filelist);
+}
+
+void BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
+{
+ struct direntry *file;
+ int num;
+
+ file= filelist->filelist;
+
+ for(num=0; num<filelist->numfiles; num++, file++) {
+ file->flags= 0;
+ file->type= file->s.st_mode; /* restore the mess below */
+
+ /* Don't check extensions for directories */
+ if (file->type & S_IFDIR)
+ continue;
+
+
+
+ if(BLO_has_bfile_extension(file->relname)) {
+ file->flags |= BLENDERFILE;
+ if(filelist->type==FILE_LOADLIB) {
+ 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;
+ }
+ }
+ } else if(BLI_testextensie(file->relname, ".py")) {
+ file->flags |= PYSCRIPTFILE;
+ } else if(BLI_testextensie(file->relname, ".txt")) {
+ file->flags |= TEXTFILE;
+ } else if( BLI_testextensie(file->relname, ".ttf")
+ || BLI_testextensie(file->relname, ".ttc")
+ || BLI_testextensie(file->relname, ".pfb")
+ || BLI_testextensie(file->relname, ".otf")
+ || BLI_testextensie(file->relname, ".otc")) {
+ file->flags |= FTFONTFILE;
+ } else if (has_quicktime){
+ if( BLI_testextensie(file->relname, ".int")
+ || BLI_testextensie(file->relname, ".inta")
+ || BLI_testextensie(file->relname, ".jpg")
+ || BLI_testextensie(file->relname, ".jpeg")
+ || BLI_testextensie(file->relname, ".tga")
+ || BLI_testextensie(file->relname, ".rgb")
+ || BLI_testextensie(file->relname, ".rgba")
+ || BLI_testextensie(file->relname, ".bmp")
+ || BLI_testextensie(file->relname, ".png")
+ || BLI_testextensie(file->relname, ".iff")
+ || BLI_testextensie(file->relname, ".lbm")
+ || BLI_testextensie(file->relname, ".gif")
+ || BLI_testextensie(file->relname, ".psd")
+ || BLI_testextensie(file->relname, ".tif")
+ || BLI_testextensie(file->relname, ".tiff")
+ || BLI_testextensie(file->relname, ".pct")
+ || BLI_testextensie(file->relname, ".pict")
+ || BLI_testextensie(file->relname, ".pntg") //macpaint
+ || BLI_testextensie(file->relname, ".qtif")
+ || BLI_testextensie(file->relname, ".sgi")
+ || BLI_testextensie(file->relname, ".hdr")
+#ifdef WITH_DDS
+ || BLI_testextensie(file->relname, ".dds")
+#endif
+#ifdef WITH_OPENEXR
+ || BLI_testextensie(file->relname, ".exr")
+#endif
+ ) {
+ file->flags |= IMAGEFILE;
+ }
+ else if(BLI_testextensie(file->relname, ".avi")
+ || BLI_testextensie(file->relname, ".flc")
+ || BLI_testextensie(file->relname, ".mov")
+ || BLI_testextensie(file->relname, ".movie")
+ || BLI_testextensie(file->relname, ".mp4")
+ || BLI_testextensie(file->relname, ".m4v")
+ || BLI_testextensie(file->relname, ".mv")) {
+ file->flags |= MOVIEFILE;
+ }
+ else if(BLI_testextensie(file->relname, ".wav")) {
+ file->flags |= SOUNDFILE;
+ }
+ } else { // no quicktime
+ if(BLI_testextensie(file->relname, ".int")
+ || BLI_testextensie(file->relname, ".inta")
+ || BLI_testextensie(file->relname, ".jpg")
+ || BLI_testextensie(file->relname, ".tga")
+ || BLI_testextensie(file->relname, ".rgb")
+ || BLI_testextensie(file->relname, ".rgba")
+ || BLI_testextensie(file->relname, ".bmp")
+ || BLI_testextensie(file->relname, ".png")
+ || BLI_testextensie(file->relname, ".iff")
+ || BLI_testextensie(file->relname, ".tif")
+ || BLI_testextensie(file->relname, ".tiff")
+ || BLI_testextensie(file->relname, ".hdr")
+#ifdef WITH_DDS
+ || BLI_testextensie(file->relname, ".dds")
+#endif
+#ifdef WITH_OPENEXR
+ || BLI_testextensie(file->relname, ".exr")
+#endif
+ || BLI_testextensie(file->relname, ".lbm")
+ || BLI_testextensie(file->relname, ".sgi")) {
+ file->flags |= IMAGEFILE;
+ }
+ else if(BLI_testextensie(file->relname, ".avi")
+ || BLI_testextensie(file->relname, ".mp4")
+ || BLI_testextensie(file->relname, ".mv")) {
+ file->flags |= MOVIEFILE;
+ }
+ else if(BLI_testextensie(file->relname, ".wav")) {
+ file->flags |= SOUNDFILE;
+ }
+ }
+ }
+}
+
+void BIF_filelist_swapselect(struct FileList* filelist)
+{
+ struct direntry *file;
+ int num, act= 0;
+
+ file= filelist->filelist;
+ for(num=0; num<filelist->numfiles; num++, file++) {
+ if(file->flags & ACTIVE) {
+ act= 1;
+ break;
+ }
+ }
+ file= filelist->filelist+2;
+ for(num=2; num<filelist->numfiles; num++, file++) {
+ if(act) file->flags &= ~ACTIVE;
+ else file->flags |= ACTIVE;
+ }
+}
+
+int BIF_filelist_islibrary(struct FileList* filelist, 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, filelist->dir);
+ 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)) {
+ *fd= '/';
+ }
+ 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 */
+ BLI_strncpy(group, gp, GROUP_MAX);
+ }
+ return 1;
+}
+
+void BIF_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_MAXDIR], group[GROUP_MAX];
+
+ filelist->type = FILE_LOADLIB;
+
+ /* name test */
+ ok= BIF_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= BIF_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 + 2;
+ 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;
+ filelist->filelist[1].relname= BLI_strdup("..");
+ filelist->filelist[1].type |= S_IFDIR;
+
+ for (i=0, l= names; i<nnames; i++, l= l->next) {
+ char *blockname= l->link;
+
+ filelist->filelist[i + 2].relname= BLI_strdup(blockname);
+ if (!idcode)
+ filelist->filelist[i + 2].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 + 2].image = ima;
+ filelist->filelist[i + 2].flags = IMAGEFILE;
+ }
+ }
+ }
+ }
+
+ BLI_linklist_free(names, free);
+ if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN);
+
+ BIF_filelist_sort(filelist, FILE_SORTALPHA);
+
+ BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change
+
+ filelist->filter = 0;
+ BIF_filelist_filter(filelist);
+}
+
+void BIF_filelist_append_library(struct FileList *filelist, char *dir, char *file, short flag, int idcode)
+{
+ BLO_library_append_(&filelist->libfiledata, filelist->filelist, filelist->numfiles, dir, file, flag, idcode);
+}
+
+void BIF_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;
+
+ if(filelist->dir[0]=='/') filelist->dir[0]= 0;
+
+ if(filelist->dir[0]) {
+ idcode= BIF_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[1].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");
+ BIF_filelist_sort(filelist, FILE_SORTALPHA);
+ }
+ else {
+
+ /* make files */
+ idcode= BIF_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->has_func && idcode==ID_IP) {
+ if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++;
+ }
+ else if (!filelist->hide_dot || id->name[2] != '.') {
+ filelist->numfiles++;
+ }
+
+ id= id->next;
+ }
+
+ if(!filelist->has_func) filelist->numfiles+= 2;
+ filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
+
+ files = filelist->filelist;
+
+ if(!filelist->has_func) {
+ memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry));
+ filelist->filelist[0].relname= BLI_strdup(".");
+ filelist->filelist[0].type |= S_IFDIR;
+ memset( &(filelist->filelist[1]), 0 , sizeof(struct direntry));
+ filelist->filelist[1].relname= BLI_strdup("..");
+ filelist->filelist[1].type |= S_IFDIR;
+
+ files+= 2;
+ }
+
+ id= lb->first;
+ totlib= totbl= 0;
+
+ while(id) {
+
+ ok= 0;
+ if(filelist->has_func && idcode==ID_IP) {
+ if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1;
+ }
+ else ok= 1;
+
+ if(ok) {
+ /* TODO: hide dot files - elubie */
+ 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(!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;
+ }
+ }
+ 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;
+ BIF_filelist_filter(filelist);
+}
+
+
+void BIF_filelist_settype(struct FileList* filelist, int type)
+{
+ filelist->type = type;
+}
+
+short BIF_filelist_gettype(struct FileList* filelist)
+{
+ return filelist->type;
+}
+
+void BIF_filelist_sort(struct FileList* filelist, short sort)
+{
+ struct direntry *file;
+ int num;/* , act= 0; */
+
+ switch(sort) {
+ case FILE_SORTALPHA:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
+ break;
+ case FILE_SORTDATE:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);
+ break;
+ case FILE_SORTSIZE:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);
+ break;
+ case FILE_SORTEXTENS:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
+ }
+
+ file= filelist->filelist;
+ for(num=0; num<filelist->numfiles; num++, file++) {
+ file->flags &= ~HILITE;
+ }
+ BIF_filelist_filter(filelist);
+}
+
+
+void BIF_filelist_setipotype(struct FileList* filelist, short ipotype)
+{
+ filelist->ipotype = ipotype;
+}
+
+void BIF_filelist_hasfunc(struct FileList* filelist, int has_func)
+{
+ filelist->has_func = has_func;
+}
+
diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c
index 025ee86e563..597611344c6 100644
--- a/source/blender/src/filesel.c
+++ b/source/blender/src/filesel.c
@@ -34,6 +34,12 @@
#include <string.h>
#include <math.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "MEM_guardedalloc.h"
+
+#include "BMF_Api.h"
+
#ifdef WIN32
#include <io.h>
#include <direct.h>
@@ -43,12 +49,6 @@
#include <sys/times.h>
#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include "MEM_guardedalloc.h"
-
-#include "BMF_Api.h"
-
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_linklist.h"
@@ -86,6 +86,7 @@
#include "BKE_utildefines.h"
#include "BIF_editview.h"
+#include "BIF_filelist.h"
#include "BIF_gl.h"
#include "BIF_interface.h"
#include "BIF_language.h"
@@ -101,7 +102,6 @@
#include "BDR_editcurve.h"
#include "BDR_editobject.h"
-#include "BPI_script.h"
#include "BSE_filesel.h"
#include "BSE_view.h"
@@ -111,15 +111,18 @@
#include "BIF_fsmenu.h" /* include ourselves */
-#if defined WITH_ICONV
- #include "iconv.h"
+#ifdef INTERNATIONAL
+#include "FTF_Api.h"
#endif
-#if defined WIN32 || defined __BeOS
-int fnmatch(const char *pattern, const char *string, int flags)
+#if defined __BeOS
+static int fnmatch(const char *pattern, const char *string, int flags)
{
return 0;
}
+#elif defined WIN32 && !defined _LIBC
+ /* use fnmatch included in blenlib */
+ #include "BLI_fnmatch.h"
#else
#include <fnmatch.h>
#endif
@@ -170,155 +173,6 @@ static float pixels_to_ofs;
static char otherdir[FILE_MAX];
static ScrArea *otherarea;
-/* FSMENU HANDLING */
-
- /* FSMenuEntry's without paths indicate seperators */
-typedef struct _FSMenuEntry FSMenuEntry;
-struct _FSMenuEntry {
- FSMenuEntry *next;
-
- char *path;
-};
-
-static FSMenuEntry *fsmenu= 0;
-
-int fsmenu_get_nentries(void)
-{
- FSMenuEntry *fsme;
- int count= 0;
-
- for (fsme= fsmenu; fsme; fsme= fsme->next)
- count++;
-
- return count;
-}
-int fsmenu_is_entry_a_seperator(int idx)
-{
- FSMenuEntry *fsme;
-
- for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
- idx--;
-
- return (fsme && !fsme->path)?1:0;
-}
-char *fsmenu_get_entry(int idx)
-{
- FSMenuEntry *fsme;
-
- for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
- idx--;
-
- return fsme?fsme->path:NULL;
-}
-char *fsmenu_build_menu(void)
-{
- DynStr *ds= BLI_dynstr_new();
- FSMenuEntry *fsme;
- char *menustr;
-
- for (fsme= fsmenu; fsme; fsme= fsme->next) {
- if (!fsme->path) {
- /* clean consecutive seperators and ignore trailing ones */
- if (fsme->next) {
- if (fsme->next->path) {
- BLI_dynstr_append(ds, "%l|");
- } else {
- FSMenuEntry *next= fsme->next;
- fsme->next= next->next;
- MEM_freeN(next);
- }
- }
- } else {
- BLI_dynstr_append(ds, fsme->path);
- if (fsme->next) BLI_dynstr_append(ds, "|");
- }
- }
-
- menustr= BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return menustr;
-}
-static FSMenuEntry *fsmenu_get_last_separator(void)
-{
- FSMenuEntry *fsme, *lsep=NULL;
-
- for (fsme= fsmenu; fsme; fsme= fsme->next)
- if (!fsme->path)
- lsep= fsme;
-
- return lsep;
-}
-void fsmenu_insert_entry(char *path, int sorted)
-{
- FSMenuEntry *prev= fsmenu_get_last_separator();
- FSMenuEntry *fsme= prev?prev->next:fsmenu;
-
- for (; fsme; prev= fsme, fsme= fsme->next) {
- if (fsme->path) {
- if (BLI_streq(path, fsme->path)) {
- return;
- } else if (sorted && strcmp(path, fsme->path)<0) {
- break;
- }
- }
- }
-
- fsme= MEM_mallocN(sizeof(*fsme), "fsme");
- fsme->path= BLI_strdup(path);
-
- if (prev) {
- fsme->next= prev->next;
- prev->next= fsme;
- } else {
- fsme->next= fsmenu;
- fsmenu= fsme;
- }
-}
-void fsmenu_append_seperator(void)
-{
- if (fsmenu) {
- FSMenuEntry *fsme= fsmenu;
-
- while (fsme->next) fsme= fsme->next;
-
- fsme->next= MEM_mallocN(sizeof(*fsme), "fsme");
- fsme->next->next= NULL;
- fsme->next->path= NULL;
- }
-}
-void fsmenu_remove_entry(int idx)
-{
- FSMenuEntry *prev= NULL, *fsme= fsmenu;
-
- for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next)
- if (fsme->path)
- idx--;
-
- if (fsme) {
- if (prev) {
- prev->next= fsme->next;
- } else {
- fsmenu= fsme->next;
- }
-
- MEM_freeN(fsme->path);
- MEM_freeN(fsme);
- }
-}
-void fsmenu_free(void)
-{
- FSMenuEntry *fsme= fsmenu;
-
- while (fsme) {
- FSMenuEntry *n= fsme->next;
-
- if (fsme->path) MEM_freeN(fsme->path);
- MEM_freeN(fsme);
-
- fsme= n;
- }
-}
-
/* ******************* SORT ******************* */
static int compare_name(const void *a1, const void *a2)
@@ -511,7 +365,7 @@ void test_flags_file(SpaceFile *sfile)
}
}
}
- } else if (sfile->type==FILE_SPECIAL){
+ } else if (sfile->type==FILE_SPECIAL || sfile->type==FILE_LOADFONT){
if(BLI_testextensie(file->relname, ".py")) {
file->flags |= PYSCRIPTFILE;
} else if( BLI_testextensie(file->relname, ".ttf")
@@ -535,6 +389,9 @@ void test_flags_file(SpaceFile *sfile)
|| BLI_testextensie(file->relname, ".rgb")
|| BLI_testextensie(file->relname, ".bmp")
|| BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+ || BLI_testextensie(file->relname, ".dds")
+#endif
|| BLI_testextensie(file->relname, ".iff")
|| BLI_testextensie(file->relname, ".lbm")
|| BLI_testextensie(file->relname, ".gif")
@@ -566,6 +423,9 @@ void test_flags_file(SpaceFile *sfile)
|| BLI_testextensie(file->relname, ".rgb")
|| BLI_testextensie(file->relname, ".bmp")
|| BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+ || BLI_testextensie(file->relname, ".dds")
+#endif
|| BLI_testextensie(file->relname, ".iff")
|| BLI_testextensie(file->relname, ".lbm")
|| BLI_testextensie(file->relname, ".cin")
@@ -777,7 +637,7 @@ void swapselect_file(SpaceFile *sfile)
static int find_active_file(SpaceFile *sfile, short x, short y)
{
- int ofs;
+ int ofs, act;
if(y > textrct.ymax) y= textrct.ymax;
if(y <= textrct.ymin) y= textrct.ymin+1;
@@ -786,8 +646,12 @@ static int find_active_file(SpaceFile *sfile, short x, short y)
if(ofs<0) ofs= 0;
ofs*= (textrct.ymax-textrct.ymin);
- return sfile->ofs+ (ofs+textrct.ymax-y)/FILESEL_DY;
+ act= sfile->ofs+ (ofs+textrct.ymax-y)/FILESEL_DY;
+ if(act<0 || act>=sfile->totfile)
+ act= -1;
+
+ return act;
}
@@ -896,32 +760,6 @@ static void linerect(int id, int x, int y)
}
-#ifdef WITH_ICONV
-static void string_to_utf8(char *original, char *utf_8, char *code)
-{
- size_t inbytesleft=strlen(original);
- size_t outbytesleft=512;
- size_t rv=0;
- iconv_t cd;
-
- cd=iconv_open("UTF-8", code);
-
- if (cd == (iconv_t)(-1)) {
- printf("iconv_open Error");
- *utf_8='\0';
- return ;
- }
- rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
- if (rv == (size_t) -1) {
- printf("iconv Error\n");
- return ;
- }
- *utf_8 = '\0';
- iconv_close(cd);
-}
-#endif
-
-
static void print_line(SpaceFile *sfile, struct direntry *files, int x, int y)
{
int boxcol=0;
@@ -972,25 +810,24 @@ static void print_line(SpaceFile *sfile, struct direntry *files, int x, int y)
#ifdef WITH_ICONV
{
struct LANGMenuEntry *lme;
- char utf_8[512];
-
- lme = find_language(U.language);
-
- if (!strcmp(lme->code, "ja_JP")) { /* japanese */
- string_to_utf8(files->relname, utf_8, "Shift_JIS");
- BIF_RasterPos((float)x, (float)y); /* texture fonts */
- BIF_DrawString(G.font, utf_8, (U.transopts & USER_TR_MENUS));
- } else if (!strcmp(lme->code, "zh_CN")) { /* chinese */
- string_to_utf8(files->relname, utf_8, "gb2312");
- BIF_RasterPos((float)x, (float)y); /* texture fonts */
- BIF_DrawString(G.font, utf_8, (U.transopts & USER_TR_MENUS));
+ lme = find_language(U.language);
+
+ if ((lme !=NULL) && (!strcmp(lme->code, "ja_JP") ||
+ !strcmp(lme->code, "zh_CN")))
+ {
+ BIF_RasterPos((float)x, (float)y);
+#ifdef WIN32
+ BIF_DrawString(G.font, files->relname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
+#else
+ BIF_DrawString(G.font, files->relname, (U.transopts & USER_TR_MENUS));
+#endif
} else {
BMF_DrawString(G.font, files->relname);
}
}
#else
BMF_DrawString(G.font, files->relname);
-#endif
+#endif /* WITH_ICONV */
x += sfile->maxnamelen + 100;
@@ -1208,7 +1045,7 @@ void drawfilespace(ScrArea *sa, void *spacedata)
else loadbutton= 0;
uiBlockBeginAlign(block);
- uiDefBut(block, TEX, B_FS_DIRNAME,"", textrct.xmin + (strp?20:0), filebuty2, textrct.xmax-textrct.xmin-loadbutton - (strp?20:0), 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "Directory, enter a directory and press enter to create it"); /* Directory input */
+ uiDefBut(block, TEX, B_FS_DIRNAME,"", textrct.xmin + (strp?20:0), filebuty2, textrct.xmax-textrct.xmin-loadbutton - (strp?20:0), 21, sfile->dir, 0.0, (float)FILE_MAXDIR-1, 0, 0, "Directory, enter a directory and press enter to create it, Substitute ~ for home"); /* Directory input */
if(loadbutton) {
uiSetCurFont(block, UI_HELV);
uiDefBut(block, BUT, B_FS_LOAD, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
@@ -1338,6 +1175,7 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
name[2]= 0;
BLI_strncpy(name, file, sizeof(name));
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
sfile= curarea->spacedata.first;
@@ -1358,8 +1196,10 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
/* sfile->act is used for databrowse: double names of library objects */
sfile->act= -1;
- if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) sfile->flag |= FILE_STRINGCODE;
- else sfile->flag &= ~FILE_STRINGCODE;
+ if(G.relbase_valid && U.flag & USER_RELPATHS && type != FILE_BLENDER)
+ sfile->flag |= FILE_STRINGCODE;
+ else
+ sfile->flag &= ~FILE_STRINGCODE;
if (U.uiflag & USER_HIDE_DOT)
sfile->flag |= FILE_HIDE_DOT;
@@ -1393,7 +1233,7 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
sfile->libfiledata= NULL;
}
}
- else { /* FILE_BLENDER */
+ else { /* FILE_BLENDER or FILE_LOADFONT */
split_sfile(sfile, name); /* test filelist too */
BLI_cleanup_dir(G.sce, sfile->dir);
@@ -1420,41 +1260,6 @@ void activate_fileselect_args(int type, char *title, char *file, void (*func)(ch
activate_fileselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2);
}
-
-void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
-{
- SpaceImaSel *simasel;
- char dir[FILE_MAX], name[FILE_MAX];
-
- if(curarea==NULL) return;
- if(curarea->win==0) return;
-
- newspace(curarea, SPACE_IMASEL);
-
- /* sometimes double, when area is already SPACE_FILE with a different file name */
- addqueue(curarea->headwin, CHANGED, 1);
- addqueue(curarea->win, CHANGED, 1);
-
- name[2]= 0;
- BLI_strncpy(name, file, sizeof(name));
-
- simasel= curarea->spacedata.first;
- simasel->returnfunc= func;
-
- if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE;
- else simasel->mode &= ~IMS_STRINGCODE;
-
- BLI_split_dirfile(name, dir, simasel->file);
- BLI_cleanup_dir(G.sce, simasel->dir);
- if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0;
-
- BLI_strncpy(simasel->dir, dir, sizeof(simasel->dir));
- BLI_strncpy(simasel->title, title, sizeof(simasel->title));
-
- /* filetoname= 1; */
-}
-
-
void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short))
{
ListBase *lb;
@@ -1620,11 +1425,13 @@ static void filesel_execute(SpaceFile *sfile)
}
do_library_append(sfile);
- BIF_undo_push("Append from file");
+
+ BIF_undo_push( ((sfile->flag & FILE_LINK)==0) ? "Append from file" : "Link from file");
+
allqueue(REDRAWALL, 1);
}
else if(filesel_has_func(sfile)) {
- fsmenu_insert_entry(sfile->dir, 1);
+ fsmenu_insert_entry(sfile->dir, 1, 0);
if(sfile->type==FILE_MAIN) { /* DATABROWSE */
if (sfile->menup) { /* with value pointing to ID block index */
@@ -1650,7 +1457,7 @@ static void filesel_execute(SpaceFile *sfile)
*sfile->menup= -1;
- if(sfile->act>=0) {
+ if(sfile->act>=0 && sfile->act<sfile->totfile) {
if(sfile->filelist) {
files= sfile->filelist+sfile->act;
if ( strcmp(files->relname, sfile->file)==0) {
@@ -1682,8 +1489,18 @@ static void filesel_execute(SpaceFile *sfile)
if(sfile->flag & FILE_STRINGCODE) {
/* still weak, but we don't want saving files to make relative paths */
- if(strncmp(sfile->title, "Save", 4))
+ if(G.relbase_valid && strncmp(sfile->title, "Save", 4)) {
BLI_makestringcode(G.sce, name);
+ } else {
+ /* if we don't have a valid relative base (.blend file hasn't been saved yet)
+ then we don't save the path as relative (for texture images, background image).
+ Warning message not shown when saving files (doesn't make sense there)
+ */
+ if (strncmp(sfile->title, "Save", 4)) {
+ printf("Relative path setting has been ignored because .blend file hasn't been saved yet.\n");
+ }
+ sfile->flag &= ~FILE_STRINGCODE;
+ }
}
if(sfile->returnfunc)
sfile->returnfunc(name);
@@ -1714,6 +1531,20 @@ static void do_filesel_buttons(short event, SpaceFile *sfile)
}
else if(event== B_FS_DIRNAME) {
/* reuse the butname variable */
+
+ /* convienence shortcut '~' -> $HOME
+ * If the first char is ~ then this is invalid on all OS's so its safe to replace with home */
+ if ( sfile->dir[0] == '~' ) {
+ if (sfile->dir[1] == '\0') {
+ BLI_strncpy(sfile->dir, BLI_gethome(), sizeof(sfile->dir) );
+ } else {
+ /* replace ~ with home */
+ char tmpstr[FILE_MAX];
+ BLI_join_dirfile(tmpstr, BLI_gethome(), sfile->dir+1);
+ BLI_strncpy(sfile->dir, tmpstr, sizeof(sfile->dir));
+ }
+ }
+
BLI_cleanup_dir(G.sce, sfile->dir);
BLI_make_file_string(G.sce, butname, sfile->dir, "");
@@ -2001,7 +1832,7 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
if( event!=RETKEY && event!=PADENTER)
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
switch(event) {
@@ -2035,17 +1866,34 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(act>=0 && act<sfile->totfile) {
if(S_ISDIR(sfile->filelist[act].type)) {
- strcat(sfile->dir, sfile->filelist[act].relname);
- strcat(sfile->dir,"/");
- BLI_cleanup_dir(G.sce, sfile->dir);
- freefilelist(sfile);
- sfile->ofs= 0;
- do_draw= 1;
+ /* the path is too long and we are not going up! */
+ if (strcmp(sfile->filelist[act].relname, ".") &&
+ strcmp(sfile->filelist[act].relname, "..") &&
+ strlen(sfile->dir) + strlen(sfile->filelist[act].relname) >= FILE_MAXDIR )
+ {
+ error("Path too long, cannot enter this directory");
+ } else {
+ strcat(sfile->dir, sfile->filelist[act].relname);
+ strcat(sfile->dir,"/");
+ BLI_cleanup_dir(G.sce, sfile->dir);
+ freefilelist(sfile);
+ sfile->ofs= 0;
+ do_draw= 1;
+ }
}
else {
if( strcmp(sfile->file, sfile->filelist[act].relname)) {
+ char tmpstr[240];
do_draw= 1;
BLI_strncpy(sfile->file, sfile->filelist[act].relname, sizeof(sfile->file));
+ if (sfile->f_fp) {
+ sprintf (tmpstr, "%s%s", sfile->dir, sfile->file);
+ /* printf ("%s\n", tmpstr); */
+ #ifdef INTERNATIONAL
+ if (!FTF_GetNewFont ((const unsigned char *)tmpstr, 0, U.fontsize))
+ error ("No font file");
+ #endif
+ }
}
if(event==MIDDLEMOUSE && sfile->type) filesel_execute(sfile);
}
@@ -2373,7 +2221,8 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group)
/* now we know that we are in a blend file and it is safe to
assume that gp actually points to a group */
- BLI_strncpy(group, gp, GROUP_MAX);
+ if (BLI_streq("Screen", gp)==0)
+ BLI_strncpy(group, gp, GROUP_MAX);
}
return 1;
}
@@ -2557,7 +2406,7 @@ static void active_file_object(SpaceFile *sfile)
if(filesel_has_func(sfile)) return;
if( strcmp(sfile->dir, "Object/")==0 ) {
- if(sfile->act >= 0) {
+ if(sfile->act >= 0 && sfile->act < sfile->totfile) {
ob= (Object *)sfile->filelist[sfile->act].poin;
diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c
index 3eae54b3482..ac90d3ed119 100644
--- a/source/blender/src/fluidsim.c
+++ b/source/blender/src/fluidsim.c
@@ -70,7 +70,6 @@
#include "BKE_scene.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
-#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ipo.h"
#include "LBM_fluidsim.h"
@@ -151,6 +150,7 @@ typedef struct {
/* ********************** fluid sim settings struct functions ********************** */
/* allocates and initializes general main data */
+
FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
{
//char blendDir[FILE_MAXDIR], blendFile[FILE_MAXFILE];
@@ -189,7 +189,7 @@ FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
/* elubie: changed this to default to the same dir as the render output
to prevent saving to C:\ on Windows */
- BLI_strncpy(fss->surfdataPath, U.tempdir, FILE_MAX);
+ BLI_strncpy(fss->surfdataPath, btempdir, FILE_MAX);
fss->orgMesh = (Mesh *)srcob->data;
fss->meshSurface = NULL;
fss->meshBB = NULL;
@@ -226,8 +226,8 @@ static Mesh *fluidsimCopyMesh(Mesh *me)
Mesh *dup = MEM_dupallocN(me);
CustomData_copy(&me->vdata, &dup->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert);
- CustomData_copy(&me->vdata, &dup->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert);
- CustomData_copy(&me->vdata, &dup->vdata, CD_MASK_MESH, CD_DUPLICATE, me->totvert);
+ CustomData_copy(&me->edata, &dup->edata, CD_MASK_MESH, CD_DUPLICATE, me->totedge);
+ CustomData_copy(&me->fdata, &dup->fdata, CD_MASK_MESH, CD_DUPLICATE, me->totface);
return dup;
}
@@ -350,6 +350,7 @@ static void fluidsimInitChannel(float **setchannel, int size, float *time,
char *cstr = NULL;
float *channel = NULL;
float aniFrlen = G.scene->r.framelen;
+ int current_frame = G.scene->r.cfra;
if((entries<1) || (entries>3)) {
printf("fluidsimInitChannel::Error - invalid no. of entries: %d\n",entries);
entries = 1;
@@ -368,6 +369,11 @@ static void fluidsimInitChannel(float **setchannel, int size, float *time,
for(j=0; j<entries; j++) {
if(icus[j]) {
for(i=1; i<=size; i++) {
+ /* Bugfix to make python drivers working
+ // which uses Blender.get("curframe")
+ */
+ G.scene->r.cfra = floor(aniFrlen*((float)i));
+
calc_icu(icus[j], aniFrlen*((float)i) );
channel[(i-1)*(entries+1) + j] = icus[j]->curval;
}
@@ -380,7 +386,7 @@ static void fluidsimInitChannel(float **setchannel, int size, float *time,
for(i=1; i<=size; i++) {
channel[(i-1)*(entries+1) + entries] = time[i];
}
-
+ G.scene->r.cfra = current_frame;
*setchannel = channel;
}
diff --git a/source/blender/src/fsmenu.c b/source/blender/src/fsmenu.c
new file mode 100644
index 00000000000..319fb8de48f
--- /dev/null
+++ b/source/blender/src/fsmenu.c
@@ -0,0 +1,257 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BMF_Api.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_dynstr.h"
+#include "BIF_usiblender.h"
+
+
+#include "BIF_fsmenu.h" /* include ourselves */
+
+
+/* FSMENU HANDLING */
+
+ /* FSMenuEntry's without paths indicate seperators */
+typedef struct _FSMenuEntry FSMenuEntry;
+struct _FSMenuEntry {
+ FSMenuEntry *next;
+
+ char *path;
+ short save;
+};
+
+static FSMenuEntry *fsmenu= 0;
+
+int fsmenu_get_nentries(void)
+{
+ FSMenuEntry *fsme;
+ int count= 0;
+
+ for (fsme= fsmenu; fsme; fsme= fsme->next)
+ count++;
+
+ return count;
+}
+int fsmenu_is_entry_a_seperator(int idx)
+{
+ FSMenuEntry *fsme;
+
+ for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
+ idx--;
+
+ return (fsme && !fsme->path)?1:0;
+}
+char *fsmenu_get_entry(int idx)
+{
+ FSMenuEntry *fsme;
+
+ for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
+ idx--;
+
+ return fsme?fsme->path:NULL;
+}
+char *fsmenu_build_menu(void)
+{
+ DynStr *ds= BLI_dynstr_new();
+ FSMenuEntry *fsme;
+ char *menustr;
+
+ for (fsme= fsmenu; fsme; fsme= fsme->next) {
+ if (!fsme->path) {
+ /* clean consecutive seperators and ignore trailing ones */
+ if (fsme->next) {
+ if (fsme->next->path) {
+ BLI_dynstr_append(ds, "%l|");
+ } else {
+ FSMenuEntry *next= fsme->next;
+ fsme->next= next->next;
+ MEM_freeN(next);
+ }
+ }
+ } else {
+ if (fsme->save) {
+ BLI_dynstr_append(ds, "o ");
+ } else {
+ BLI_dynstr_append(ds, " ");
+ }
+ BLI_dynstr_append(ds, fsme->path);
+ if (fsme->next) BLI_dynstr_append(ds, "|");
+ }
+ }
+
+ menustr= BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return menustr;
+}
+static FSMenuEntry *fsmenu_get_last_separator(void)
+{
+ FSMenuEntry *fsme, *lsep=NULL;
+
+ for (fsme= fsmenu; fsme; fsme= fsme->next)
+ if (!fsme->path)
+ lsep= fsme;
+
+ return lsep;
+}
+
+static FSMenuEntry *fsmenu_get_first_separator(void)
+{
+ FSMenuEntry *fsme, *lsep=NULL;
+
+ for (fsme= fsmenu; fsme; fsme= fsme->next)
+ if (!fsme->path) {
+ lsep= fsme;
+ break;
+ }
+
+ return lsep;
+}
+
+void fsmenu_insert_entry(char *path, int sorted, short save)
+{
+ FSMenuEntry *prev;
+ FSMenuEntry *fsme;
+
+ if (save) {
+ prev = fsmenu_get_first_separator();
+ } else {
+ prev = fsmenu_get_last_separator();
+ }
+ fsme= prev?prev->next:fsmenu;
+
+ for (; fsme; prev= fsme, fsme= fsme->next) {
+ if (fsme->path) {
+ if (BLI_streq(path, fsme->path)) {
+ return;
+ } else if (sorted && strcmp(path, fsme->path)<0) {
+ break;
+ }
+ } else {
+ // if we're bookmarking this, file should come
+ // before the last separator, only automatically added
+ // current dir go after the last sep.
+ if (save) {
+ break;
+ }
+ }
+ }
+
+ fsme= MEM_mallocN(sizeof(*fsme), "fsme");
+ fsme->path= BLI_strdup(path);
+ fsme->save = save;
+
+ if (prev) {
+ fsme->next= prev->next;
+ prev->next= fsme;
+ } else {
+ fsme->next= fsmenu;
+ fsmenu= fsme;
+ }
+}
+void fsmenu_append_separator(void)
+{
+ if (fsmenu) {
+ FSMenuEntry *fsme= fsmenu;
+
+ while (fsme->next) fsme= fsme->next;
+
+ fsme->next= MEM_mallocN(sizeof(*fsme), "fsme");
+ fsme->next->next= NULL;
+ fsme->next->path= NULL;
+ }
+}
+void fsmenu_remove_entry(int idx)
+{
+ FSMenuEntry *prev= NULL, *fsme= fsmenu;
+
+ for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next)
+ idx--;
+
+ if (fsme) {
+ /* you should only be able to remove entries that were
+ not added by default, like windows drives.
+ also separators (where path == NULL) shouldn't be removed */
+ if (fsme->save && fsme->path) {
+
+ /* remove fsme from list */
+ if (prev) {
+ prev->next= fsme->next;
+ } else {
+ fsmenu= fsme->next;
+ }
+ /* free entry */
+ MEM_freeN(fsme->path);
+ MEM_freeN(fsme);
+ }
+ }
+}
+
+void fsmenu_write_file(const char *filename)
+{
+ FSMenuEntry *fsme= fsmenu;
+
+ FILE *fp = fopen(filename, "w");
+ if (!fp) return;
+
+ for (fsme= fsmenu; fsme; fsme= fsme->next) {
+ if (fsme->path && fsme->save) {
+ fprintf(fp, "%s\n", fsme->path);
+ }
+ }
+ fclose(fp);
+}
+
+void fsmenu_free(void)
+{
+ FSMenuEntry *fsme= fsmenu;
+
+ while (fsme) {
+ FSMenuEntry *n= fsme->next;
+
+ if (fsme->path) MEM_freeN(fsme->path);
+ MEM_freeN(fsme);
+
+ fsme= n;
+ }
+}
+
+
+
diff --git a/source/blender/src/ghostwinlay.c b/source/blender/src/ghostwinlay.c
index 855699fa512..b1e7084a7a2 100644
--- a/source/blender/src/ghostwinlay.c
+++ b/source/blender/src/ghostwinlay.c
@@ -68,6 +68,8 @@
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#define __CARBONSOUND__
+ /* XXX BIG WARNING: carbon.h should not be included in blender/src code, it conflicts with struct ID */
+#define ID ID_
#include <Carbon/Carbon.h>
/*declarations*/
@@ -509,7 +511,7 @@ static int change_bit(int val, int bit, int to_on) {
return to_on?(val|bit):(val&~bit);
}
-static void update_tablet_data(Window *win, Window *ghostwin) {
+static void update_tablet_data(Window *win, GHOST_WindowHandle ghostwin) {
const GHOST_TabletData *td= GHOST_GetTabletData(ghostwin);
/* if there's tablet data from an active tablet device then use it,
@@ -521,7 +523,7 @@ static void update_tablet_data(Window *win, Window *ghostwin) {
win->ytilt = td->Ytilt;
} else {
win->activedevice = DEV_MOUSE;
- win->pressure = 0.0;
+ win->pressure = 1.0;
win->xtilt = win->ytilt = 0.0;
}
}
@@ -946,3 +948,11 @@ void window_open_ndof(Window* win)
G.ndofdevice = -1;
}
}
+
+char *getClipboard(int flag) {
+ return (char*)GHOST_getClipboard(flag);
+}
+
+void putClipboard(char *buffer, int flag) {
+ GHOST_putClipboard((GHOST_TInt8*)buffer, flag);
+}
diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c
index 248d36dcb1e..13922bb7eef 100644
--- a/source/blender/src/glutil.c
+++ b/source/blender/src/glutil.c
@@ -50,6 +50,11 @@
#include "BIF_glutil.h"
#include "BIF_mywindow.h"
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+
+
/* Invert line handling */
#define glToggle(mode, onoff) (((onoff)?glEnable:glDisable)(mode))
@@ -263,10 +268,17 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *
int nsubparts_x= (img_w+(tex_w-1))/tex_w;
int nsubparts_y= (img_h+(tex_h-1))/tex_h;
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ /* Specify the color outside this function, and tex will modulate it.
+ * This is useful for changing alpha without using glPixelTransferf()
+ */
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
glBindTexture(GL_TEXTURE_2D, texid);
+ /* don't want nasty border artifacts */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
for (subpart_y=0; subpart_y<nsubparts_y; subpart_y++) {
for (subpart_x=0; subpart_x<nsubparts_x; subpart_x++) {
int subpart_w= (subpart_x==nsubparts_x-1)?(img_w-subpart_x*tex_w):tex_w;
@@ -278,17 +290,16 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_FLOAT, &f_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]);
else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]);
-
- glColor3ub(255, 255, 255);
+
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(rast_x, rast_y);
- glTexCoord2f((float) subpart_w/tex_w, 0);
+ glTexCoord2f((float) (subpart_w-1)/tex_w, 0);
glVertex2f(rast_x+subpart_w*xzoom, rast_y);
- glTexCoord2f((float) subpart_w/tex_w, (float) subpart_h/tex_h);
+ glTexCoord2f((float) (subpart_w-1)/tex_w, (float) subpart_h/tex_h);
glVertex2f(rast_x+subpart_w*xzoom, rast_y+subpart_h*yzoom);
glTexCoord2f(0, (float) subpart_h/tex_h);
diff --git a/source/blender/src/hddaudio.c b/source/blender/src/hddaudio.c
index 0b1989dc6d0..8a6128fba26 100644
--- a/source/blender/src/hddaudio.c
+++ b/source/blender/src/hddaudio.c
@@ -200,7 +200,7 @@ struct hdaudio * sound_copy_hdaudio(struct hdaudio * c)
#endif
}
-long sound_hdaudio_get_duration(struct hdaudio * hdaudio, int frame_rate)
+long sound_hdaudio_get_duration(struct hdaudio * hdaudio, double frame_rate)
{
#ifdef WITH_FFMPEG
return hdaudio->pFormatCtx->duration * frame_rate / AV_TIME_BASE;
@@ -283,58 +283,61 @@ static void sound_hdaudio_extract_small_block(
decode_pos -= bl_size;
- memset(hdaudio->decode_cache + decode_pos, 0,
- (hdaudio->decode_cache_size - decode_pos)
- * sizeof(short));
-
-
- while(av_read_frame(hdaudio->pFormatCtx, &packet) >= 0) {
- int data_size;
- int len;
- uint8_t *audio_pkt_data;
- int audio_pkt_size;
-
- if(packet.stream_index != hdaudio->audioStream) {
- av_free_packet(&packet);
- continue;
- }
-
- audio_pkt_data = packet.data;
- audio_pkt_size = packet.size;
-
- while (audio_pkt_size > 0) {
- len = avcodec_decode_audio(
- hdaudio->pCodecCtx,
- hdaudio->decode_cache
- + decode_pos,
- &data_size,
- audio_pkt_data,
- audio_pkt_size);
- if (len <= 0) {
- audio_pkt_size = 0;
- break;
- }
+ if (decode_pos < hdaudio->decode_cache_size) {
+ memset(hdaudio->decode_cache + decode_pos, 0,
+ (hdaudio->decode_cache_size - decode_pos)
+ * sizeof(short));
+
+ while(av_read_frame(
+ hdaudio->pFormatCtx, &packet) >= 0) {
+ int data_size;
+ int len;
+ uint8_t *audio_pkt_data;
+ int audio_pkt_size;
- audio_pkt_size -= len;
- audio_pkt_data += len;
-
- if (data_size <= 0) {
+ if(packet.stream_index
+ != hdaudio->audioStream) {
+ av_free_packet(&packet);
continue;
}
+
+ audio_pkt_data = packet.data;
+ audio_pkt_size = packet.size;
+
+ while (audio_pkt_size > 0) {
+ len = avcodec_decode_audio(
+ hdaudio->pCodecCtx,
+ hdaudio->decode_cache
+ + decode_pos,
+ &data_size,
+ audio_pkt_data,
+ audio_pkt_size);
+ if (len <= 0) {
+ audio_pkt_size = 0;
+ break;
+ }
+
+ audio_pkt_size -= len;
+ audio_pkt_data += len;
+
+ if (data_size <= 0) {
+ continue;
+ }
+
+ decode_pos += data_size / sizeof(short);
+ if (decode_pos + data_size
+ / sizeof(short)
+ > hdaudio->decode_cache_size) {
+ break;
+ }
+ }
+ av_free_packet(&packet);
- decode_pos += data_size / sizeof(short);
- if (decode_pos + data_size
- / sizeof(short)
+ if (decode_pos + data_size / sizeof(short)
> hdaudio->decode_cache_size) {
break;
}
}
- av_free_packet(&packet);
-
- if (decode_pos + data_size / sizeof(short)
- > hdaudio->decode_cache_size) {
- break;
- }
}
if (rate_conversion) {
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index 14a62d67231..a31f92c4b68 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -30,7 +30,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung (Action Editor recode)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -79,85 +79,146 @@
#include "blendef.h"
#include "mydevice.h"
-#define ACTMENU_VIEW_CENTERVIEW 0
-#define ACTMENU_VIEW_AUTOUPDATE 1
-#define ACTMENU_VIEW_PLAY3D 2
-#define ACTMENU_VIEW_PLAYALL 3
-#define ACTMENU_VIEW_ALL 4
-#define ACTMENU_VIEW_MAXIMIZE 5
-#define ACTMENU_VIEW_LOCK 6
-#define ACTMENU_VIEW_SLIDERS 7
-#define ACTMENU_VIEW_NEXTMARKER 8
-#define ACTMENU_VIEW_PREVMARKER 9
-
-#define ACTMENU_SEL_BORDER 0
-#define ACTMENU_SEL_BORDERM 1
-#define ACTMENU_SEL_ALL_KEYS 2
-#define ACTMENU_SEL_ALL_CHAN 3
-#define ACTMENU_SEL_ALL_MARKERS 4
-#define ACTMENU_SEL_INVERSE_KEYS 5
-#define ACTMENU_SEL_INVERSE_MARKERS 6
-
-#define ACTMENU_SEL_COLUMN_KEYS 1
-#define ACTMENU_SEL_COLUMN_MARKERSCOLUMN 2
-#define ACTMENU_SEL_COLUMN_MARKERSBETWEEN 3
-
-#define ACTMENU_KEY_DUPLICATE 0
-#define ACTMENU_KEY_DELETE 1
-#define ACTMENU_KEY_BAKE 2
-#define ACTMENU_KEY_CLEAN 3
-
-#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP 0
-#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN 1
-#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP 2
-#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM 3
-
-#define ACTMENU_KEY_TRANSFORM_MOVE 0
-#define ACTMENU_KEY_TRANSFORM_SCALE 1
-#define ACTMENU_KEY_TRANSFORM_SLIDE 2
-
-#define ACTMENU_KEY_HANDLE_AUTO 0
-#define ACTMENU_KEY_HANDLE_ALIGN 1
-#define ACTMENU_KEY_HANDLE_FREE 2
-#define ACTMENU_KEY_HANDLE_VECTOR 3
-
-#define ACTMENU_KEY_INTERP_CONST 0
-#define ACTMENU_KEY_INTERP_LINEAR 1
-#define ACTMENU_KEY_INTERP_BEZIER 2
-
-#define ACTMENU_KEY_EXTEND_CONST 0
-#define ACTMENU_KEY_EXTEND_EXTRAPOLATION 1
-#define ACTMENU_KEY_EXTEND_CYCLIC 2
-#define ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION 3
-
-#define ACTMENU_KEY_SNAP_NEARFRAME 1
-#define ACTMENU_KEY_SNAP_CURFRAME 2
-#define ACTMENU_KEY_SNAP_NEARMARK 3
-
-#define ACTMENU_KEY_MIRROR_CURFRAME 1
-#define ACTMENU_KEY_MIRROR_YAXIS 2
-#define ACTMENU_KEY_MIRROR_XAXIS 3
-#define ACTMENU_KEY_MIRROR_MARKER 4
-
-#define ACTMENU_MARKERS_ADD 0
-#define ACTMENU_MARKERS_DUPLICATE 1
-#define ACTMENU_MARKERS_DELETE 2
-#define ACTMENU_MARKERS_NAME 3
-#define ACTMENU_MARKERS_MOVE 4
+/* enums declaring constants that are used as menu event codes */
+
+enum {
+ ACTMENU_VIEW_CENTERVIEW= 0,
+ ACTMENU_VIEW_AUTOUPDATE,
+ ACTMENU_VIEW_PLAY3D,
+ ACTMENU_VIEW_PLAYALL,
+ ACTMENU_VIEW_ALL,
+ ACTMENU_VIEW_MAXIMIZE,
+ ACTMENU_VIEW_LOCK,
+ ACTMENU_VIEW_SLIDERS,
+ ACTMENU_VIEW_NEXTMARKER,
+ ACTMENU_VIEW_PREVMARKER,
+ ACTMENU_VIEW_NEXTKEYFRAME,
+ ACTMENU_VIEW_PREVKEYFRAME,
+ ACTMENU_VIEW_TIME,
+ ACTMENU_VIEW_NOHIDE,
+ ACTMENU_VIEW_TRANSDELDUPS,
+ ACTMENU_VIEW_HORIZOPTIMISE
+};
+
+enum {
+ ACTMENU_SEL_BORDER = 0,
+ ACTMENU_SEL_BORDERM,
+ ACTMENU_SEL_ALL_KEYS,
+ ACTMENU_SEL_ALL_CHAN,
+ ACTMENU_SEL_ALL_MARKERS,
+ ACTMENU_SEL_INVERSE_KEYS,
+ ACTMENU_SEL_INVERSE_MARKERS,
+ ACTMENU_SEL_INVERSE_CHANNELS,
+ ACTMENU_SEL_LEFTKEYS,
+ ACTMENU_SEL_RIGHTKEYS
+};
+
+enum {
+ ACTMENU_SEL_COLUMN_KEYS = 1,
+ ACTMENU_SEL_COLUMN_CFRA,
+ ACTMENU_SEL_COLUMN_MARKERSCOLUMN,
+ ACTMENU_SEL_COLUMN_MARKERSBETWEEN
+};
+
+enum {
+ ACTMENU_CHANNELS_OPENLEVELS = 0,
+ ACTMENU_CHANNELS_CLOSELEVELS,
+ ACTMENU_CHANNELS_EXPANDALL,
+ ACTMENU_CHANNELS_SHOWACHANS,
+ ACTMENU_CHANNELS_DELETE
+};
+
+enum {
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP = 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM
+};
+
+enum {
+ ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE = 0,
+ ACTMENU_CHANNELS_GROUP_ADD_TONEW,
+ ACTMENU_CHANNELS_GROUP_REMOVE
+};
+
+enum {
+ ACTMENU_CHANNELS_SETTINGS_TOGGLE = 0,
+ ACTMENU_CHANNELS_SETTINGS_ENABLE,
+ ACTMENU_CHANNELS_SETTINGS_DISABLE,
+};
+
+enum {
+ ACTMENU_KEY_DUPLICATE = 0,
+ ACTMENU_KEY_DELETE,
+ ACTMENU_KEY_CLEAN,
+ ACTMENU_KEY_SAMPLEKEYS,
+ ACTMENU_KEY_INSERTKEY
+};
+
+enum {
+ ACTMENU_KEY_TRANSFORM_MOVE = 0,
+ ACTMENU_KEY_TRANSFORM_SCALE,
+ ACTMENU_KEY_TRANSFORM_SLIDE,
+ ACTMENU_KEY_TRANSFORM_EXTEND
+};
+
+enum {
+ ACTMENU_KEY_HANDLE_AUTO = 0,
+ ACTMENU_KEY_HANDLE_ALIGN,
+ ACTMENU_KEY_HANDLE_FREE,
+ ACTMENU_KEY_HANDLE_VECTOR
+};
+
+enum {
+ ACTMENU_KEY_INTERP_CONST = 0,
+ ACTMENU_KEY_INTERP_LINEAR,
+ ACTMENU_KEY_INTERP_BEZIER
+};
+
+enum {
+ ACTMENU_KEY_EXTEND_CONST = 0,
+ ACTMENU_KEY_EXTEND_EXTRAPOLATION,
+ ACTMENU_KEY_EXTEND_CYCLIC,
+ ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION
+};
+
+enum {
+ ACTMENU_KEY_SNAP_NEARFRAME = 1,
+ ACTMENU_KEY_SNAP_CURFRAME,
+ ACTMENU_KEY_SNAP_NEARMARK,
+ ACTMENU_KEY_SNAP_NEARTIME,
+ ACTMENU_KEY_SNAP_CFRA2KEY,
+};
+
+enum {
+ ACTMENU_KEY_MIRROR_CURFRAME = 1,
+ ACTMENU_KEY_MIRROR_YAXIS,
+ ACTMENU_KEY_MIRROR_XAXIS,
+ ACTMENU_KEY_MIRROR_MARKER
+};
+
+enum {
+ ACTMENU_MARKERS_ADD = 0,
+ ACTMENU_MARKERS_DUPLICATE,
+ ACTMENU_MARKERS_DELETE,
+ ACTMENU_MARKERS_NAME,
+ ACTMENU_MARKERS_MOVE,
+ ACTMENU_MARKERS_LOCALADD,
+ ACTMENU_MARKERS_LOCALRENAME,
+ ACTMENU_MARKERS_LOCALDELETE,
+ ACTMENU_MARKERS_LOCALMOVE
+};
void do_action_buttons(unsigned short event)
{
Object *ob= OBACT;
- switch(event){
- case B_ACTBAKE:
- bake_action_with_client(G.saction->action, ob, 0.01);
- break;
- case B_ACTHOME:
+ switch(event) {
+ case B_ACTHOME: /* HOMEKEY in Action Editor */
/* Find X extents */
G.v2d->cur.xmin = 0;
G.v2d->cur.ymin=-SCROLLB;
-
+
if (G.saction->action) {
float extra;
@@ -174,24 +235,24 @@ void do_action_buttons(unsigned short event)
G.v2d->cur.xmax= -5;
G.v2d->cur.xmax= 100;
}
-
- G.v2d->cur.ymin= -(count_action_levels(G.saction->action)*(CHANNELHEIGHT+CHANNELSKIP));
- G.v2d->cur.ymax= 0;
}
else { /* shapekeys and/or no action */
- G.v2d->cur.xmax= -5;
- G.v2d->cur.xmax= 100;
- G.v2d->cur.ymax= 1000;
- G.v2d->cur.ymin= 0;
+ G.v2d->cur.xmin= -5.0;
+ G.v2d->cur.xmax= 65.0;
}
+ G.v2d->cur.ymin= -75.0;
+ G.v2d->cur.ymax= 5.0;
+
G.v2d->tot= G.v2d->cur;
test_view2d(G.v2d, curarea->winx, curarea->winy);
view2d_do_locks(curarea, V2D_LOCK_COPY);
-
+
addqueue (curarea->win, REDRAW, 1);
-
+
break;
+
+ /* copy/paste/paste-flip buttons in 3d-view header in PoseMode */
case B_ACTCOPY:
copy_posebuf();
allqueue(REDRAWVIEW3D, 1);
@@ -204,6 +265,14 @@ void do_action_buttons(unsigned short event)
paste_posebuf(1);
allqueue(REDRAWVIEW3D, 1);
break;
+
+ /* copy/paste buttons in Action Editor header */
+ case B_ACTCOPYKEYS:
+ copy_actdata();
+ break;
+ case B_ACTPASTEKEYS:
+ paste_actdata();
+ break;
case B_ACTPIN: /* __PINFAKE */
/* if (G.saction->flag & SACTION_PIN) {
@@ -245,7 +314,7 @@ static void do_action_viewmenu(void *arg, int event)
break;
case ACTMENU_VIEW_LOCK:
G.v2d->flag ^= V2D_VIEWLOCK;
- if(G.v2d->flag & V2D_VIEWLOCK)
+ if (G.v2d->flag & V2D_VIEWLOCK)
view2d_do_locks(curarea, 0);
break;
case ACTMENU_VIEW_SLIDERS: /* Show sliders (when applicable) */
@@ -254,12 +323,30 @@ static void do_action_viewmenu(void *arg, int event)
case ACTMENU_VIEW_MAXIMIZE: /* Maximize Window */
/* using event B_FULL */
break;
- case ACTMENU_VIEW_NEXTMARKER: /* jump to next marker */
+ case ACTMENU_VIEW_NEXTMARKER: /* Jump to next marker */
nextprev_marker(1);
break;
- case ACTMENU_VIEW_PREVMARKER: /* jump to previous marker */
+ case ACTMENU_VIEW_PREVMARKER: /* Jump to previous marker */
nextprev_marker(-1);
break;
+ case ACTMENU_VIEW_TIME: /* switch between frames and seconds display */
+ G.saction->flag ^= SACTION_DRAWTIME;
+ break;
+ case ACTMENU_VIEW_NOHIDE: /* Show hidden channels */
+ G.saction->flag ^= SACTION_NOHIDE;
+ break;
+ case ACTMENU_VIEW_NEXTKEYFRAME: /* Jump to next keyframe */
+ nextprev_action_keyframe(1);
+ break;
+ case ACTMENU_VIEW_PREVKEYFRAME: /* Jump to previous keyframe */
+ nextprev_action_keyframe(-1);
+ break;
+ case ACTMENU_VIEW_TRANSDELDUPS: /* Don't delete duplicate/overlapping keyframes after transform */
+ G.saction->flag ^= SACTION_NOTRANSKEYCULL;
+ break;
+ case ACTMENU_VIEW_HORIZOPTIMISE: /* Include keyframes not in view (horizontally) when preparing to draw */
+ G.saction->flag ^= SACTION_HORIZOPTIMISEON;
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -280,12 +367,45 @@ static uiBlock *action_viewmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ if (G.saction->flag & SACTION_DRAWTIME) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Show Frames|Ctrl T", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1,
+ ACTMENU_VIEW_TIME, "");
+ }
+ else {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Show Seconds|Ctrl T", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1,
+ ACTMENU_VIEW_TIME, "");
+ }
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_SLIDERS)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
"Show Sliders|", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1,
ACTMENU_VIEW_SLIDERS, "");
+ uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOHIDE)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
+ "Show Hidden Channels|", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1,
+ ACTMENU_VIEW_NOHIDE, "");
+
+ // this option may get removed in future
+ uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_HORIZOPTIMISEON)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
+ "Cull Out-of-View Keys (Time)|", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1,
+ ACTMENU_VIEW_HORIZOPTIMISE, "");
+
+ // this option may get removed in future...
+ uiDefIconTextBut(block, BUTM, 1, (G.saction->flag & SACTION_NOTRANSKEYCULL)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT,
+ "AfterTrans Delete Dupli-Frames|", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1,
+ ACTMENU_VIEW_TRANSDELDUPS, "");
+
+
uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
"Lock Time to Other Windows|", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1,
@@ -298,13 +418,20 @@ static uiBlock *action_viewmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Jump To Next Marker|PageUp", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_NEXTMARKER, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Jump To Prev Marker|PageDown", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_PREVMARKER, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Jump To Next Keyframe|Ctrl PageUp", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_NEXTKEYFRAME, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Jump To Prev Keyframe|Ctrl PageDown", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_VIEW_PREVKEYFRAME, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -352,33 +479,22 @@ static uiBlock *action_viewmenu(void *arg_unused)
static void do_action_selectmenu_columnmenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- key = get_action_mesh_key();
-
- if (event == ACTMENU_SEL_COLUMN_MARKERSBETWEEN) {
- markers_selectkeys_between();
- }
- else if (ELEM(event, ACTMENU_SEL_COLUMN_KEYS, ACTMENU_SEL_COLUMN_MARKERSCOLUMN)) {
- if (act)
- column_select_actionkeys(act, event);
- else if (key)
- column_select_shapekeys(key, event);
+ switch (event) {
+ case ACTMENU_SEL_COLUMN_MARKERSBETWEEN:
+ markers_selectkeys_between();
+ break;
+ case ACTMENU_SEL_COLUMN_KEYS:
+ column_select_action_keys(1);
+ break;
+ case ACTMENU_SEL_COLUMN_MARKERSCOLUMN:
+ column_select_action_keys(2);
+ break;
+ case ACTMENU_SEL_COLUMN_CFRA:
+ column_select_action_keys(3);
+ break;
}
- else
- return;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
static uiBlock *action_selectmenu_columnmenu(void *arg_unused)
@@ -394,10 +510,13 @@ static uiBlock *action_selectmenu_columnmenu(void *arg_unused)
"On Selected Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_COLUMN_KEYS, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "On Current Frame|Ctrl K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_SEL_COLUMN_CFRA, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"On Selected Markers|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_COLUMN_MARKERSCOLUMN, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Between Selected Markers|Ctrl K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
+ "Between Selected Markers|Alt K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_COLUMN_MARKERSBETWEEN, "");
@@ -414,7 +533,7 @@ static void do_action_selectmenu(void *arg, int event)
Key *key;
saction = curarea->spacedata.first;
- if (!saction) return;
+ if (saction == NULL) return;
act = saction->action;
key = get_action_mesh_key();
@@ -422,12 +541,7 @@ static void do_action_selectmenu(void *arg, int event)
switch(event)
{
case ACTMENU_SEL_BORDER: /* Border Select */
- if (act) {
- borderselect_action();
- }
- else if (key) {
- borderselect_mesh(key);
- }
+ borderselect_action();
break;
case ACTMENU_SEL_BORDERM: /* Border Select */
@@ -435,59 +549,57 @@ static void do_action_selectmenu(void *arg, int event)
break;
case ACTMENU_SEL_ALL_KEYS: /* Select/Deselect All Keys */
- if (act) {
- deselect_actionchannel_keys (act, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (key) {
- deselect_meshchannel_keys(key, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ deselect_action_keys(1, 1);
+ BIF_undo_push("(De)Select Keys");
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
break;
case ACTMENU_SEL_ALL_CHAN: /* Select/Deselect All Channels */
- deselect_actionchannels(act, 1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
+ deselect_action_channels(1);
+ BIF_undo_push("(De)Select Action Channels");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
+ allqueue(REDRAWIPO, 0);
break;
case ACTMENU_SEL_ALL_MARKERS: /* select/deselect all markers */
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
+ BIF_undo_push("(De)Select Markers");
+ allqueue(REDRAWMARKER, 0);
+ break;
+
+ case ACTMENU_SEL_INVERSE_KEYS: /* invert selection status of keys */
+ deselect_action_keys(0, 2);
+ BIF_undo_push("Inverse Keys");
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWIPO, 0);
break;
- case ACTMENU_SEL_INVERSE_KEYS: /* invert selection status of keys */
- if (act) {
- deselect_actionchannel_keys(act, 0, 2);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (key) {
- deselect_meshchannel_keys(key, 0, 2);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ case ACTMENU_SEL_INVERSE_CHANNELS: /* invert selection status of channels */
+ deselect_action_channels(2);
+ BIF_undo_push("Inverse Action Channels");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
break;
case ACTMENU_SEL_INVERSE_MARKERS: /* invert selection of markers */
deselect_markers(0, 2);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ BIF_undo_push("Inverse Action Channels");
+ allqueue(REDRAWMARKER, 0);
+ break;
+
+ case ACTMENU_SEL_LEFTKEYS:
+ selectkeys_leftright(1, SELECT_REPLACE);
+ break;
+
+ case ACTMENU_SEL_RIGHTKEYS:
+ selectkeys_leftright(0, SELECT_REPLACE);
break;
}
}
@@ -522,7 +634,7 @@ static uiBlock *action_selectmenu(void *arg_unused)
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_ALL_MARKERS, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Select/Deselect All Channels", 0, yco-=20,
+ "Select/Deselect All Channels|A", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_ALL_CHAN, "");
@@ -530,21 +642,38 @@ static uiBlock *action_selectmenu(void *arg_unused)
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Inverse Keys", 0, yco-=20,
+ "Inverse Keys|Ctrl I", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_INVERSE_KEYS, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Inverse Markers", 0, yco-=20,
+ "Inverse Markers|Ctrl Shift I", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_SEL_INVERSE_MARKERS, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Inverse All Channels|Ctrl I", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_SEL_INVERSE_CHANNELS, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Back In Time|Alt RMB", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_SEL_LEFTKEYS, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Ahead In Time|Alt RMB", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_SEL_RIGHTKEYS, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBlockBut(block, action_selectmenu_columnmenu,
NULL, ICON_RIGHTARROW_THIN, "Column Select Keys", 0, yco-=20, 120, 20, "");
- if(curarea->headertype==HEADERTOP) {
+ if (curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
else {
@@ -557,43 +686,249 @@ static uiBlock *action_selectmenu(void *arg_unused)
return block;
}
-static void do_action_keymenu_transformmenu(void *arg, int event)
+
+static void do_action_channelmenu_posmenu(void *arg, int event)
+{
+ switch(event)
+ {
+ case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN:
+ rearrange_action_channels(REARRANGE_ACTCHAN_DOWN);
+ break;
+ case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP:
+ rearrange_action_channels(REARRANGE_ACTCHAN_UP);
+ break;
+ case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP:
+ rearrange_action_channels(REARRANGE_ACTCHAN_TOP);
+ break;
+ case ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM:
+ rearrange_action_channels(REARRANGE_ACTCHAN_BOTTOM);
+ break;
+ }
+
+ scrarea_queue_winredraw(curarea);
+}
+
+static uiBlock *action_channelmenu_posmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_posmenu",
+ UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_action_channelmenu_posmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Move Up|Shift Page Up", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Move Down|Shift Page Down", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Move to Top|Ctrl Shift Page Up", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Move to Bottom|Ctrl Shift Page Down", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
+
+static void do_action_channelmenu_groupmenu(void *arg, int event)
+{
+ switch(event)
+ {
+ case ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE:
+ action_groups_group(0);
+ break;
+ case ACTMENU_CHANNELS_GROUP_ADD_TONEW:
+ action_groups_group(1);
+ break;
+ case ACTMENU_CHANNELS_GROUP_REMOVE:
+ action_groups_ungroup();
+ break;
+ }
+}
+
+static uiBlock *action_channelmenu_groupmenu(void *arg_unused)
{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_groupmenu",
+ UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_action_channelmenu_groupmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Add to Active Group|Shift G", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Add to New Group|Ctrl Shift G", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_GROUP_ADD_TONEW, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Remove From Group|Alt G", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_GROUP_REMOVE, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
+
+static void do_action_channelmenu_settingsmenu(void *arg, int event)
+{
+ setflag_action_channels(event);
+}
+
+static uiBlock *action_channelmenu_settingsmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "action_channelmenu_settingsmenu",
+ UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_action_channelmenu_settingsmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Toggle a Setting|Shift W", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_SETTINGS_TOGGLE, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Enable a Setting|Ctrl Shift W", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_SETTINGS_ENABLE, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Disable a Setting|Alt W", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_CHANNELS_SETTINGS_DISABLE, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
+
+static void do_action_channelmenu(void *arg, int event)
+{
SpaceAction *saction;
- bAction *act;
- Key *key;
saction = curarea->spacedata.first;
- if (!saction) return;
+ if (saction == NULL) return;
+
+ switch(event)
+ {
+ case ACTMENU_CHANNELS_OPENLEVELS: /* Unfold selected channels one step */
+ openclose_level_action(1);
+ break;
+ case ACTMENU_CHANNELS_CLOSELEVELS: /* Fold selected channels one step */
+ openclose_level_action(-1);
+ break;
+ case ACTMENU_CHANNELS_EXPANDALL: /* Expands all channels */
+ expand_all_action();
+ break;
+ case ACTMENU_CHANNELS_SHOWACHANS: /* Unfold groups that are hiding selected achans */
+ expand_obscuregroups_action();
+ break;
+ case ACTMENU_CHANNELS_DELETE: /* Deletes selected channels */
+ delete_action_channels();
+ break;
+ }
+}
- act = saction->action;
- key = get_action_mesh_key();
+static uiBlock *action_channelmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "action_channelmenu",
+ UI_EMBOSSP, UI_HELV, curarea->headwin);
+ uiBlockSetButmFunc(block, do_action_channelmenu, NULL);
+
+ uiDefIconTextBlockBut(block, action_channelmenu_groupmenu,
+ NULL, ICON_RIGHTARROW_THIN,
+ "Grouping", 0, yco-=20, 120, 20, "");
+
+ uiDefIconTextBlockBut(block, action_channelmenu_posmenu,
+ NULL, ICON_RIGHTARROW_THIN,
+ "Ordering", 0, yco-=20, 120, 20, "");
+
+ uiDefIconTextBlockBut(block, action_channelmenu_settingsmenu,
+ NULL, ICON_RIGHTARROW_THIN,
+ "Settings", 0, yco-=20, 120, 20, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Delete|X", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_DELETE, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Toggle Show Hierachy|~", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_EXPANDALL, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Show Group-Hidden Channels|Shift ~", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_SHOWACHANS, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Expand One Level|Ctrl NumPad+", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_OPENLEVELS, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Collapse One Level|Ctrl NumPad-", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_CHANNELS_CLOSELEVELS, "");
+
+ if (curarea->headertype==HEADERTOP) {
+ uiBlockSetDirection(block, UI_DOWN);
+ }
+ else {
+ uiBlockSetDirection(block, UI_TOP);
+ uiBlockFlipOrder(block);
+ }
+
+ uiTextBoundsBlock(block, 50);
+
+ return block;
+}
+
+static void do_action_keymenu_transformmenu(void *arg, int event)
+{
switch (event)
{
case ACTMENU_KEY_TRANSFORM_MOVE:
- if (act) {
- transform_actionchannel_keys ('g', 0);
- }
- else if (key) {
- transform_meshchannel_keys('g', key);
- }
+ transform_action_keys('g', 0);
break;
case ACTMENU_KEY_TRANSFORM_SCALE:
- if (act) {
- transform_actionchannel_keys ('s', 0);
- }
- else if (key) {
- transform_meshchannel_keys('s', key);
- }
+ transform_action_keys('s', 0);
break;
case ACTMENU_KEY_TRANSFORM_SLIDE:
- if (act) {
- transform_actionchannel_keys ('t', 0);
- }
- else if (key) {
- //transform_meshchannel_keys('t', key);
- }
+ transform_action_keys('t', 0);
+ break;
+ case ACTMENU_KEY_TRANSFORM_EXTEND:
+ transform_action_keys('e', 0);
break;
}
@@ -613,6 +948,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused)
"Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_MOVE, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_TRANSFORM_EXTEND, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_SCALE, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
@@ -628,24 +966,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused)
static void do_action_keymenu_handlemenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- key = get_action_mesh_key();
-
switch (event) {
case ACTMENU_KEY_HANDLE_AUTO:
- if (act) {
- sethandles_actionchannel_keys(HD_AUTO);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_AUTO, key);
- }
+ sethandles_action_keys(HD_AUTO);
break;
case ACTMENU_KEY_HANDLE_ALIGN:
@@ -653,21 +976,11 @@ static void do_action_keymenu_handlemenu(void *arg, int event)
/* OK, this is kinda dumb, need to fix the
* toggle crap in sethandles_ipo_keys()
*/
- if (act) {
- sethandles_actionchannel_keys(HD_ALIGN);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_ALIGN, key);
- }
+ sethandles_action_keys(HD_ALIGN);
break;
case ACTMENU_KEY_HANDLE_VECTOR:
- if (act) {
- sethandles_actionchannel_keys(HD_VECT);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_VECT, key);
- }
+ sethandles_action_keys(HD_VECT);
break;
}
}
@@ -705,32 +1018,16 @@ static uiBlock *action_keymenu_handlemenu(void *arg_unused)
static void do_action_keymenu_intpolmenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- //Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- //key = get_action_mesh_key();
-
switch(event)
{
case ACTMENU_KEY_INTERP_CONST:
- if (act)
- set_ipotype_actionchannels(SET_IPO_CONSTANT);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_MENU, SET_IPO_CONSTANT);
break;
case ACTMENU_KEY_INTERP_LINEAR:
- if (act)
- set_ipotype_actionchannels(SET_IPO_LINEAR);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_MENU, SET_IPO_LINEAR);
break;
case ACTMENU_KEY_INTERP_BEZIER:
- if (act)
- set_ipotype_actionchannels(SET_IPO_BEZIER);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_MENU, SET_IPO_BEZIER);
break;
}
@@ -747,15 +1044,15 @@ static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_action_keymenu_intpolmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Constant", 0, yco-=20,
+ "Constant|Shift T, 1", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_INTERP_CONST, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Linear", 0, yco-=20,
+ "Linear|Shift T, 2", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_INTERP_LINEAR, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Bezier", 0, yco-=20,
+ "Bezier|Shift T, 3", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_INTERP_BEZIER, "");
@@ -767,37 +1064,19 @@ static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
static void do_action_keymenu_extendmenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- //Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- //key = get_action_mesh_key();
-
switch(event)
{
case ACTMENU_KEY_EXTEND_CONST:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CONSTANT);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CONSTANT);
break;
case ACTMENU_KEY_EXTEND_EXTRAPOLATION:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_EXTRAPOLATION);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_EXTRAPOLATION);
break;
case ACTMENU_KEY_EXTEND_CYCLIC:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CYCLIC);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CYCLIC);
break;
case ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CYCLICEXTRAPOLATION);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_MENU, SET_EXTEND_CYCLICEXTRAPOLATION);
break;
}
@@ -836,63 +1115,6 @@ static uiBlock *action_keymenu_extendmenu(void *arg_unused)
return block;
}
-static void do_action_keymenu_chanposmenu(void *arg, int event)
-{
- switch(event)
- {
- case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN:
- down_sel_action();
- break;
- case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP:
- up_sel_action();
- break;
- case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP:
- top_sel_action();
- break;
- case ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM:
- bottom_sel_action();
- break;
- }
-
- scrarea_queue_winredraw(curarea);
-}
-
-static uiBlock *action_keymenu_chanposmenu(void *arg_unused)
-{
- uiBlock *block;
- short yco= 0, menuwidth=120;
-
- block= uiNewBlock(&curarea->uiblocks, "action_keymenu_chanposmenu",
- UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
- uiBlockSetButmFunc(block, do_action_keymenu_chanposmenu, NULL);
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Move Up|Ctrl Page Up", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Move Down|Ctrl Page Down", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6,
- menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Move to Top|Shift Page Up", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_TOP, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Move to Bottom|Shift Page Down", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_BOTTOM, "");
-
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 60);
-
- return block;
-}
-
static void do_action_keymenu_snapmenu(void *arg, int event)
{
switch(event)
@@ -900,7 +1122,12 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
case ACTMENU_KEY_SNAP_NEARFRAME:
case ACTMENU_KEY_SNAP_CURFRAME:
case ACTMENU_KEY_SNAP_NEARMARK:
- snap_keys_to_frame(event);
+ case ACTMENU_KEY_SNAP_NEARTIME:
+ snap_action_keys(event);
+ break;
+
+ case ACTMENU_KEY_SNAP_CFRA2KEY:
+ snap_cfra_action();
break;
}
@@ -916,16 +1143,37 @@ static uiBlock *action_keymenu_snapmenu(void *arg_unused)
UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_action_keymenu_snapmenu, NULL);
+ if (G.saction->flag & SACTION_DRAWTIME) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Key -> Nearest Second|Shift S, 1", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SNAP_NEARTIME, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Key -> Current Time|Shift S, 2", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SNAP_CURFRAME, "");
+
+ }
+ else {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Key -> Nearest Frame|Shift S, 1", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SNAP_NEARFRAME, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Key -> Current Frame|Shift S, 2", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SNAP_CURFRAME, "");
+ }
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Nearest Frame|Shift S, 1", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_SNAP_NEARFRAME, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Current Frame|Shift S, 2", 0, yco-=20,
+ "Key -> Nearest Marker|Shift S, 3", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_SNAP_CURFRAME, "");
+ ACTMENU_KEY_SNAP_NEARMARK, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Nearest Marker|Shift S, 3", 0, yco-=20,
+ "Current Frame -> Key|Ctrl Shift S", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_SNAP_NEARMARK, "");
@@ -995,31 +1243,19 @@ static void do_action_keymenu(void *arg, int event)
switch(event)
{
case ACTMENU_KEY_DUPLICATE:
- if (act) {
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
- }
- else if (key) {
- duplicate_meshchannel_keys(key);
- }
+ duplicate_action_keys();
break;
-
case ACTMENU_KEY_DELETE:
- if (act) {
- delete_actionchannel_keys ();
- }
- else if (key) {
- delete_meshchannel_keys(key);
- }
- break;
- case ACTMENU_KEY_BAKE:
- bake_action_with_client(G.saction->action, OBACT, 0.01);
+ delete_action_keys();
break;
case ACTMENU_KEY_CLEAN:
- if (act)
- clean_actionchannels(act);
- else if (key)
- clean_shapekeys(key);
+ clean_action();
+ break;
+ case ACTMENU_KEY_SAMPLEKEYS:
+ sample_action_keys();
+ break;
+ case ACTMENU_KEY_INSERTKEY:
+ insertkey_action();
break;
}
}
@@ -1044,7 +1280,15 @@ static uiBlock *action_keymenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Insert Key|I", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_INSERTKEY, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6,
+ menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Duplicate|Shift D", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
@@ -1062,11 +1306,11 @@ static uiBlock *action_keymenu(void *arg_unused)
"Clean Action|O", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_CLEAN, "");
-
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Bake Action to Ipo Keys", 0, yco-=20,
+ "Sample Keys|Alt O", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_BAKE, "");
+ ACTMENU_KEY_SAMPLEKEYS, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1084,9 +1328,6 @@ static uiBlock *action_keymenu(void *arg_unused)
uiDefIconTextBlockBut(block, action_keymenu_intpolmenu,
NULL, ICON_RIGHTARROW_THIN,
"Interpolation Mode", 0, yco-=20, 120, 20, "");
- uiDefIconTextBlockBut(block, action_keymenu_chanposmenu,
- NULL, ICON_RIGHTARROW_THIN,
- "Channel Ordering", 0, yco-=20, 120, 20, "");
if(curarea->headertype==HEADERTOP) {
@@ -1121,13 +1362,24 @@ static void do_action_markermenu(void *arg, int event)
case ACTMENU_MARKERS_MOVE:
transform_markers('g', 0);
break;
+
+ case ACTMENU_MARKERS_LOCALADD:
+ action_add_localmarker(G.saction->action, CFRA);
+ break;
+ case ACTMENU_MARKERS_LOCALDELETE:
+ action_remove_localmarkers(G.saction->action);
+ break;
+ case ACTMENU_MARKERS_LOCALRENAME:
+ action_rename_localmarker(G.saction->action);
+ break;
+ case ACTMENU_MARKERS_LOCALMOVE:
+ G.saction->flag |= SACTION_POSEMARKERS_MOVE;
+ transform_markers('g', 0);
+ G.saction->flag &= ~SACTION_POSEMARKERS_MOVE;
+ break;
}
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
static uiBlock *action_markermenu(void *arg_unused)
@@ -1145,14 +1397,24 @@ static uiBlock *action_markermenu(void *arg_unused)
menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DUPLICATE, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Marker|X", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_DELETE, "");
-
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "(Re)Name Marker|Ctrl M", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_NAME, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Marker|Ctrl G", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_MOVE, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Pose Marker|Shift L", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALADD, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename Pose Marker|Ctrl Shift L", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALRENAME, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Pose Marker|Alt L", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALDELETE, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Pose Marker|Ctrl L", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, ACTMENU_MARKERS_LOCALMOVE, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
@@ -1171,23 +1433,23 @@ void action_buttons(void)
{
uiBlock *block;
short xco, xmax;
- char naam[256];
+ char name[256];
Object *ob;
ID *from;
- if (!G.saction)
+ if (G.saction == NULL)
return;
- // copy from drawactionspace....
+ /* copied from drawactionspace.... */
if (!G.saction->pin) {
if (OBACT)
G.saction->action = OBACT->action;
else
- G.saction->action=NULL;
+ G.saction->action= NULL;
}
- sprintf(naam, "header %d", curarea->headwin);
- block= uiNewBlock(&curarea->uiblocks, naam,
+ sprintf(name, "header %d", curarea->headwin);
+ block= uiNewBlock(&curarea->uiblocks, name,
UI_EMBOSS, UI_HELV, curarea->headwin);
if (area_is_active_area(curarea))
@@ -1225,10 +1487,10 @@ void action_buttons(void)
uiBlockSetEmboss(block, UI_EMBOSS);
xco+=XIC;
- if((curarea->flag & HEADER_NO_PULLDOWN)==0) {
+ if ((curarea->flag & HEADER_NO_PULLDOWN)==0) {
/* pull down menus */
uiBlockSetEmboss(block, UI_EMBOSSP);
-
+
xmax= GetButStringLength("View");
uiDefPulldownBut(block, action_viewmenu, NULL,
"View", xco, -2, xmax-3, 24, "");
@@ -1239,6 +1501,13 @@ void action_buttons(void)
"Select", xco, -2, xmax-3, 24, "");
xco+= xmax;
+ if (G.saction->action) {
+ xmax= GetButStringLength("Channel");
+ uiDefPulldownBut(block, action_channelmenu, NULL,
+ "Channel", xco, -2, xmax-3, 24, "");
+ xco+= xmax;
+ }
+
xmax= GetButStringLength("Marker");
uiDefPulldownBut(block, action_markermenu, NULL,
"Marker", xco, -2, xmax-3, 24, "");
@@ -1253,43 +1522,53 @@ void action_buttons(void)
uiBlockSetEmboss(block, UI_EMBOSS);
/* NAME ETC */
- ob=OBACT;
- from = (ID*) ob;
+ ob= OBACT;
+ from = (ID *)ob;
xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin,
B_ACTIONBROWSE, ID_AC, 0, (ID*)G.saction->action,
from, &(G.saction->actnr), B_ACTALONE,
B_ACTLOCAL, B_ACTIONDELETE, 0, 0);
-
- /* Draw action baker */
- xco+= 8;
-
- uiDefBut(block, BUT, B_ACTBAKE,
- "Bake", xco, 0, 64, YIC, 0, 0, 0, 0, 0,
- "Create an action with the constraint effects "
- "converted into Ipo keys");
- xco+=64;
-
uiClearButLock();
- /* draw AUTOSNAP */
- xco+= 8;
+ xco += 8;
- uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF,
- "Auto-Snap Keys %t|Off %x0|Frame Step %x1|Nearest Frame %x2",
- xco,0,XIC+10,YIC, &(G.saction->autosnap), 0, 1, 0, 0,
- "Auto-snapping mode for keys when transforming");
+ /* COPY PASTE */
+ uiBlockBeginAlign(block);
+ if (curarea->headertype==HEADERTOP) {
+ uiDefIconBut(block, BUT, B_ACTCOPYKEYS, ICON_COPYUP, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected keyframes from the selected channel(s) to the buffer");
+ uiDefIconBut(block, BUT, B_ACTPASTEKEYS, ICON_PASTEUP, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the keyframes from the buffer");
+ }
+ else {
+ uiDefIconBut(block, BUT, B_ACTCOPYKEYS, ICON_COPYDOWN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Copies the selected keyframes from the selected channel(s) to the buffer");
+ uiDefIconBut(block, BUT, B_ACTPASTEKEYS, ICON_PASTEDOWN, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Pastes the keyframes from the buffer");
+ }
+ uiBlockEndAlign(block);
+ xco += (XIC + 8);
- xco+= (XIC + 18);
+ /* draw AUTOSNAP */
+ if (G.saction->flag & SACTION_DRAWTIME) {
+ uiDefButS(block, MENU, B_REDR,
+ "Auto-Snap Keyframes %t|No Snap %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3",
+ xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0,
+ "Auto-snapping mode for keyframes when transforming");
+ }
+ else {
+ uiDefButS(block, MENU, B_REDR,
+ "Auto-Snap Keyframes %t|No Snap %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3",
+ xco,0,70,YIC, &(G.saction->autosnap), 0, 1, 0, 0,
+ "Auto-snapping mode for keyframes when transforming");
+ }
- /* draw LOCK*/
-
+ xco += (70 + 8);
+
+ /* draw LOCK */
uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco, 0, XIC, YIC,
&(G.saction->lock), 0, 0, 0, 0,
"Updates other affected window spaces automatically "
"to reflect changes in real time");
-
+
/* always as last */
curarea->headbutlen = xco + 2*XIC;
diff --git a/source/blender/src/header_buttonswin.c b/source/blender/src/header_buttonswin.c
index 15ef5962e99..3519c1f582c 100644
--- a/source/blender/src/header_buttonswin.c
+++ b/source/blender/src/header_buttonswin.c
@@ -170,6 +170,7 @@ void do_buts_buttons(short event)
}
}
matcopybuf.nodetree= ntreeCopyTree(ma->nodetree, 0);
+ matcopybuf.preview= NULL;
matcopied= 1;
}
break;
@@ -436,6 +437,14 @@ static uiBlock *buts_view_scenemenu(void *arg_unused)
uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_DEHLT, "Render|F10",
0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_RENDER, 0.0, 0, 10, "");
}
+
+ if((G.buts->mainb == CONTEXT_SCENE) && (G.buts->tab[CONTEXT_SCENE]==TAB_SCENE_SEQUENCER)) {
+ uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_HLT, "Sequencer",
+ 0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_SEQUENCER, 0.0, 0, 10, "");
+ } else {
+ uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_DEHLT, "Sequencer",
+ 0, yco-=20, menuwidth, 19, &(G.buts->tab[CONTEXT_SCENE]), (float)TAB_SCENE_SEQUENCER, 0.0, 0, 10, "");
+ }
if((G.buts->mainb == CONTEXT_SCENE) && (G.buts->tab[CONTEXT_SCENE]==TAB_SCENE_ANIM)) {
uiDefIconTextButC(block, BUTM, B_REDR, ICON_CHECKBOX_HLT, "Animation",
@@ -683,6 +692,7 @@ void buts_buttons(void)
case CONTEXT_SCENE:
uiBlockBeginAlign(block);
uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SCENE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_RENDER, 0, 0, "Render buttons ");
+ uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SEQUENCE, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_SEQUENCER, 0, 0, "Sequencer buttons ");
uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_ANIM, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_ANIM, 0, 0, "Anim/playback buttons");
uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_SOUND, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_SCENE]), 1.0, (float)TAB_SCENE_SOUND, 0, 0, "Sound block buttons");
@@ -690,7 +700,8 @@ void buts_buttons(void)
case CONTEXT_OBJECT:
uiBlockBeginAlign(block);
uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_OBJECT, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_OBJECT, 0, 0, "Object buttons ");
- uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_EFFECTS, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_PHYSICS, 0, 0, "Physics buttons");
+ uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_PHYSICS, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_PHYSICS, 0, 0, "Physics buttons");
+ uiDefIconButC(block, ROW, B_CONTEXT_SWITCH, ICON_PARTICLES, xco+=XIC, t_base, XIC, YIC, &(G.buts->tab[CONTEXT_OBJECT]), 1.0, (float)TAB_OBJECT_PARTICLE, 0, 0, "Particle buttons");
break;
case CONTEXT_SHADING:
diff --git a/source/blender/src/header_filesel.c b/source/blender/src/header_filesel.c
index 3424c4b7c3d..7591a6e7e21 100644
--- a/source/blender/src/header_filesel.c
+++ b/source/blender/src/header_filesel.c
@@ -136,10 +136,13 @@ void file_buttons(void)
uiDefIconButBitS(block, TOG, FILE_HIDE_DOT, B_RELOADDIR, ICON_GHOST,xco+=XIC,0,XIC,YIC, &sfile->flag, 0, 0, 0, 0, "Hides dot files");
uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, FILE_STRINGCODE, 0, "Relative Paths", xco+=XIC+20,0,100,YIC, &sfile->flag, 0, 0, 0, 0, "Makes sure returned paths are relative to the current .blend file");
-
- xco+=90;
-
+ if(sfile->type==FILE_BLENDER) {
+ xco+=20;
+ } else {
+ uiDefButBitS(block, TOG, FILE_STRINGCODE, 0, "Relative Paths", xco+=XIC+20,0,100,YIC, &sfile->flag, 0, 0, 0, 0, "Makes sure returned paths are relative to the current .blend file");
+ xco+=90;
+ }
+
if(sfile->type==FILE_LOADLIB) {
uiBlockBeginAlign(block);
uiDefButBitS(block, TOGN, FILE_LINK, B_REDR, "Append", xco+=XIC,0,100,YIC, &sfile->flag, 0, 0, 0, 0, "Copies selected data into current project");
@@ -158,6 +161,15 @@ void file_buttons(void)
xco+= 100; // scroll
}
+ #ifdef INTERNATIONAL
+ else if(sfile->type==FILE_LOADFONT) {
+ uiDefIconButBitS(block, TOG, FILE_SHOWSHORT, B_SORTFILELIST, ICON_FONTPREVIEW, xco+= XIC, 0, XIC, YIC, &sfile->f_fp, 0, 0, 0, 0, "Activate font preview");
+ if (sfile->f_fp)
+ uiDefButC(block, FTPREVIEW, 0, "Font preview", xco+= XIC, 0, 100, YIC, sfile->fp_str, (float)0, (float)16, 0, 0, "Font preview");
+
+ xco+= 100; // scroll
+ }
+ #endif
uiDrawBlock(block);
@@ -179,7 +191,7 @@ void file_buttons(void)
BIF_DrawString(G.font, naam, 0);
}
-
+
/* always do as last */
curarea->headbutlen= xco+2*XIC;
}
diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c
index ea0850d77d0..b5abf0947e4 100644
--- a/source/blender/src/header_image.c
+++ b/source/blender/src/header_image.c
@@ -50,7 +50,9 @@
#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_customdata_types.h" /* for UV layer menu */
+#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BDR_drawmesh.h"
@@ -62,21 +64,26 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
+#include "BLI_editVert.h" /* for UV layer menu */
+#include "BKE_customdata.h" /* ditto */
#include "BIF_butspace.h"
#include "BIF_drawimage.h"
#include "BIF_editsima.h"
+#include "BIF_imasel.h"
#include "BIF_interface.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_transform.h"
#include "BIF_toolbox.h"
+#include "BIF_editmesh.h"
#include "BSE_drawview.h"
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"
#include "BSE_trans_types.h"
+#include "BSE_edit.h"
#include "BPY_extern.h"
#include "BPY_menus.h"
@@ -104,14 +111,22 @@ void do_image_buttons(unsigned short event)
}
switch(event) {
+ case B_SIMAPIN:
+ allqueue (REDRAWIMAGE, 0);
+ break;
case B_SIMAGEHOME:
image_home();
break;
case B_SIMABROWSE:
if(G.sima->imanr== -2) {
- activate_databrowse((ID *)G.sima->image, ID_IM, 0, B_SIMABROWSE,
+ if(G.qual & LR_CTRLKEY) {
+ activate_databrowse_imasel((ID *)G.sima->image, ID_IM, 0, B_SIMABROWSE,
+ &G.sima->imanr, do_image_buttons);
+ } else {
+ activate_databrowse((ID *)G.sima->image, ID_IM, 0, B_SIMABROWSE,
&G.sima->imanr, do_image_buttons);
+ }
return;
}
if(G.sima->imanr < 0) break;
@@ -131,31 +146,22 @@ void do_image_buttons(unsigned short event)
allqueue(REDRAWIMAGE, 0);
}
/* also when image is the same: assign! 0==no tileflag: */
- image_changed(G.sima, 0);
+ image_changed(G.sima, (Image *)idtest);
BIF_undo_push("Assign image UV");
break;
-
- case B_SIMAGEDRAW:
- if(G.f & G_FACESELECT) {
- make_repbind(G.sima->image);
- image_changed(G.sima, 1);
- }
- /* XXX might be another event needed for this? */
- if(G.sima->image)
- if(ELEM(G.sima->image->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
- if(G.sima->iuser.flag & IMA_ANIM_ALWAYS)
- BKE_image_user_calc_imanr(&G.sima->iuser, G.scene->r.cfra, 0);
+ case B_SIMAGETILE:
+ image_set_tile(G.sima, 1); /* 1: only tileflag */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
break;
-
- case B_SIMAGEDRAW1:
- image_changed(G.sima, 2); /* 2: only tileflag */
+ case B_SIMA3DVIEWDRAW:
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case B_SIMA_REDR_IMA_3D:
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
break;
-
case B_SIMAGEPAINTTOOL:
if(G.sima->flag & SI_DRAWTOOL)
/* add new brush if none exists */
@@ -204,12 +210,8 @@ void do_image_buttons(unsigned short event)
BLI_strncpy(str, G.sima->image->name, sizeof(str));
ima= BKE_add_image_file(str);
if(ima) {
-
- G.sima->image= ima;
-
BKE_image_signal(ima, &G.sima->iuser, IMA_SIGNAL_RELOAD);
- image_changed(G.sima, 0);
-
+ image_changed(G.sima, ima);
}
BIF_undo_push("Load image");
allqueue(REDRAWIMAGE, 0);
@@ -224,6 +226,9 @@ void do_image_buttons(unsigned short event)
case B_TRANS_IMAGE:
image_editvertex_buts(NULL);
break;
+ case B_CURSOR_IMAGE:
+ image_editcursor_buts(NULL);
+ break;
case B_TWINANIM:
{
@@ -311,7 +316,11 @@ void do_image_buttons(unsigned short event)
if(G.sima->menunr==-2) {
MTex *mtex= brush->mtex[brush->texact];
ID *id= (ID*)((mtex)? mtex->tex: NULL);
- activate_databrowse(id, ID_TE, 0, B_SIMABTEXBROWSE, &G.sima->menunr, do_global_buttons);
+ if(G.qual & LR_CTRLKEY) {
+ activate_databrowse_imasel(id, ID_TE, 0, B_SIMABTEXBROWSE, &G.sima->menunr, do_image_buttons);
+ } else {
+ activate_databrowse(id, ID_TE, 0, B_SIMABTEXBROWSE, &G.sima->menunr, do_image_buttons);
+ }
break;
}
else if(G.sima->menunr < 0) break;
@@ -343,6 +352,36 @@ void do_image_buttons(unsigned short event)
}
}
+static void do_image_buttons_set_uvlayer_callback(void *act, void *data)
+{
+ CustomData_set_layer_active(&G.editMesh->fdata, CD_MTFACE, *((int *)act));
+
+ BIF_undo_push("Set Active UV Texture");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+}
+
+static void do_image_buttons_set_selection_mode_callback(void *mode, void *dummy2)
+{
+ int selectmode = *((int *)mode);
+ if (selectmode==0) {
+ if (G.scene->selectmode == SCE_SELECT_VERTEX) return;
+ G.scene->selectmode = SCE_SELECT_VERTEX;
+ } else {
+ if (G.scene->selectmode == SCE_SELECT_FACE) return;
+ G.scene->selectmode = SCE_SELECT_FACE;
+ }
+
+ EM_selectmode_set();
+ countall();
+
+ BIF_undo_push("Set Selection Mode");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWIMAGE, 0);
+}
+
static void do_image_view_viewnavmenu(void *arg, int event)
{
switch(event) {
@@ -418,18 +457,15 @@ static void do_image_viewmenu(void *arg, int event)
case 2: /* Maximize Window */
/* using event B_FULL */
break;
+ case 4: /* Realtime Panel... */
+ add_blockhandler(curarea, IMAGE_HANDLER_VIEW_PROPERTIES, UI_PNL_UNSTOW);
+ break;
case 5: /* Draw Shadow Mesh */
- if(G.sima->flag & SI_DRAWSHADOW)
- G.sima->flag &= ~SI_DRAWSHADOW;
- else
- G.sima->flag |= SI_DRAWSHADOW;
+ G.sima->flag ^= SI_DRAWSHADOW;
allqueue(REDRAWIMAGE, 0);
break;
case 6: /* Draw Faces */
- if(G.f & G_DRAWFACES)
- G.f &= ~G_DRAWFACES;
- else
- G.f |= G_DRAWFACES;
+ G.f ^= G_DRAWFACES;
allqueue(REDRAWIMAGE, 0);
break;
case 7: /* Properties Panel */
@@ -454,7 +490,10 @@ static void do_image_viewmenu(void *arg, int event)
case 13: /* Realtime Panel... */
add_blockhandler(curarea, IMAGE_HANDLER_GAME_PROPERTIES, UI_PNL_UNSTOW);
break;
-
+ case 14: /* Draw active image UV's only*/
+ G.sima->flag ^= SI_LOCAL_UV;
+ allqueue(REDRAWIMAGE, 0);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -468,7 +507,8 @@ static uiBlock *image_viewmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_image_viewmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Image Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Real-time Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Paint Tool...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Curves Tool...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
@@ -482,6 +522,14 @@ static uiBlock *image_viewmenu(void *arg_unused)
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Draw Shadow Mesh|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ if(G.sima->flag & SI_LOCAL_UV) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "UV Local View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+ if(!(G.sima->flag & SI_LOCAL_UV)) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "UV Global View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "UV Global View|NumPad /", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBlockBut(block, image_view_viewnavmenu, NULL, ICON_RIGHTARROW_THIN, "View Navigation", 0, yco-=20, 120, 19, "");
if(G.sima->lock) {
@@ -524,32 +572,15 @@ static void do_image_selectmenu(void *arg, int event)
case 1: /* Select/Deselect All */
select_swap_tface_uv();
break;
+ case 9: /* Select Inverse */
+ select_invert_tface_uv();
+ break;
case 2: /* Unlink Selection */
unlink_selection();
break;
case 3: /* Linked UVs */
select_linked_tface_uv(2);
break;
- case 4: /* Toggle Local UVs Stick to Vertex in Mesh */
- if(G.sima->flag & SI_LOCALSTICKY)
- G.sima->flag &= ~SI_LOCALSTICKY;
- else {
- G.sima->flag |= SI_LOCALSTICKY;
- G.sima->flag &= ~SI_STICKYUVS;
- }
- allqueue(REDRAWIMAGE, 0);
- break;
- case 5: /* Toggle UVs Stick to Vertex in Mesh */
- if(G.sima->flag & SI_STICKYUVS) {
- G.sima->flag &= ~SI_STICKYUVS;
- G.sima->flag |= SI_LOCALSTICKY;
- }
- else {
- G.sima->flag |= SI_STICKYUVS;
- G.sima->flag &= ~SI_LOCALSTICKY;
- }
- allqueue(REDRAWIMAGE, 0);
- break;
case 6: /* Toggle Active Face Select */
if(G.sima->flag & SI_SELACTFACE)
G.sima->flag &= ~SI_SELACTFACE;
@@ -570,20 +601,15 @@ static uiBlock *image_selectmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "image_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_image_selectmenu, NULL);
-
- if(G.sima->flag & SI_SELACTFACE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- if(G.sima->flag & SI_LOCALSTICKY) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Stick Local UVs to Mesh Vertex|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Stick Local UVs to Mesh Vertex|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
-
- if(G.sima->flag & SI_STICKYUVS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Stick UVs to Mesh Vertex|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Stick UVs to Mesh Vertex|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
+
+
+ if ((G.sima->flag & SI_SYNC_UVSEL)==0 || (G.sima->flag & SI_SYNC_UVSEL && (G.scene->selectmode != SCE_SELECT_FACE))) {
+ if(G.sima->flag & SI_SELACTFACE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Active Face Select|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ }
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select Pinned|Shift B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
@@ -591,6 +617,8 @@ static uiBlock *image_selectmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unlink Selection|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -864,12 +892,20 @@ static uiBlock *image_uvs_transformmenu(void *arg_unused)
static void do_image_uvs_mirrormenu(void *arg, int event)
{
+ float mat[3][3];
+
+ Mat3One(mat);
+
switch(event) {
case 0: /* X axis */
- mirror_tface_uv('x');
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[0], " on global X axis");
+ Transform();
break;
case 1: /* Y axis */
- mirror_tface_uv('y');
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[1], " on global Y axis");
+ Transform();
break;
}
@@ -898,16 +934,19 @@ static void do_image_uvs_weldalignmenu(void *arg, int event)
case 0: /* Weld */
weld_align_tface_uv('w');
break;
- case 1: /* Align X */
+ case 1: /* Align Auto */
+ weld_align_tface_uv('a');
+ break;
+ case 2: /* Align X */
weld_align_tface_uv('x');
break;
- case 2: /* Align Y */
+ case 3: /* Align Y */
weld_align_tface_uv('y');
break;
}
if(event==0) BIF_undo_push("Weld UV");
- else if(event==1 || event==2) BIF_undo_push("Align UV");
+ else if(ELEM3(event, 1, 2, 3)) BIF_undo_push("Align UV");
}
static uiBlock *image_uvs_weldalignmenu(void *arg_unused)
@@ -919,8 +958,9 @@ static uiBlock *image_uvs_weldalignmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_image_uvs_weldalignmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Weld|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align X|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Y|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Auto|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align X|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Y|W, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -962,6 +1002,9 @@ static void do_image_uvsmenu(void *arg, int event)
{
switch(event) {
+// case 0: /* UV Transform Properties Panel... */
+// add_blockhandler(curarea, IMAGE_HANDLER_TRANSFORM_PROPERTIES, UI_PNL_UNSTOW);
+// break;
case 1: /* UVs Constrained Rectangular */
if(G.sima->flag & SI_BE_SQUARE) G.sima->flag &= ~SI_BE_SQUARE;
else G.sima->flag |= SI_BE_SQUARE;
@@ -971,10 +1014,10 @@ static void do_image_uvsmenu(void *arg, int event)
else G.sima->flag |= SI_CLIP_UV;
break;
case 3: /* Limit Stitch UVs */
- stitch_uv_tface(1);
+ stitch_limit_uv_tface();
break;
case 4: /* Stitch UVs */
- stitch_uv_tface(0);
+ stitch_vert_uv_tface();
break;
case 5: /* Proportional Edit (toggle) */
if(G.scene->proportional)
@@ -1004,6 +1047,9 @@ static void do_image_uvsmenu(void *arg, int event)
case 13:
pack_charts_tface_uv();
break;
+ case 14:
+ average_charts_tface_uv();
+ break;
}
}
@@ -1014,9 +1060,9 @@ static uiBlock *image_uvsmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "image_uvsmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_image_uvsmenu, NULL);
-
- // uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
- // uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ //uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
if(G.sima->flag & SI_PIXELSNAP) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap to Pixels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap to Pixels|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
@@ -1036,7 +1082,8 @@ static uiBlock *image_uvsmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Charts|Ctrl P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Islands|Ctrl P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Average Islands Scale|Ctrl A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
@@ -1084,8 +1131,15 @@ void image_buttons(void)
uiBlock *block;
short xco, xmax;
char naam[256], *menuname;
+ char is_render; /* true if the image is a render or composite */
+
+ int allow_pin= B_SIMAPIN;
+
/* This should not be a static var */
static int headerbuttons_packdummy;
+
+
+ is_render = ((G.sima->image!=NULL) && ((G.sima->image->type == IMA_TYPE_R_RESULT) || (G.sima->image->type == IMA_TYPE_COMPOSITE)));
headerbuttons_packdummy = 0;
@@ -1127,7 +1181,7 @@ void image_buttons(void)
uiDefPulldownBut(block, image_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
xco+= xmax;
- if((G.f & G_FACESELECT) && !(ima && (G.sima->flag & SI_DRAWTOOL))) {
+ if((EM_texFaceCheck()) && !(ima && (G.sima->flag & SI_DRAWTOOL))) {
xmax= GetButStringLength("Select");
uiDefPulldownBut(block, image_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
xco+= xmax;
@@ -1140,8 +1194,7 @@ void image_buttons(void)
xmax= GetButStringLength(menuname);
uiDefPulldownBut(block, image_imagemenu, NULL, menuname, xco, -2, xmax-3, 24, "");
xco+= xmax;
-
- if((G.f & G_FACESELECT) && !(ima && (G.sima->flag & SI_DRAWTOOL))) {
+ if((EM_texFaceCheck()) && !(ima && (G.sima->flag & SI_DRAWTOOL))) {
xmax= GetButStringLength("UVs");
uiDefPulldownBut(block, image_uvsmenu, NULL, "UVs", xco, -2, xmax-3, 24, "");
xco+= xmax;
@@ -1151,8 +1204,98 @@ void image_buttons(void)
/* other buttons: */
uiBlockSetEmboss(block, UI_EMBOSS);
- xco= std_libbuttons(block, xco, 0, 0, NULL, B_SIMABROWSE, ID_IM, 0, (ID *)ima, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0);
+ if (is_render)
+ allow_pin = 0;
+
+ xco= 8 + std_libbuttons(block, xco, 0, allow_pin, &G.sima->pin, B_SIMABROWSE, ID_IM, 0, (ID *)ima, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0);
+
+ if( ima && !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
+ if (ima->packedfile) {
+ headerbuttons_packdummy = 1;
+ }
+ if (ima->packedfile && ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+ uiDefIconButBitI(block, TOG, 1, B_SIMA_REPACK, ICON_UGLYPACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
+ else
+ uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
+
+ xco+= XIC+8;
+ }
+
+ /* UV EditMode buttons, not painting or rencering or compositing */
+ if ( EM_texFaceCheck() && (G.sima->flag & SI_DRAWTOOL)==0 && !is_render) {
+ uiBut *ubut;
+ int layercount;
+
+ uiDefIconTextButS(block, ICONTEXTROW, B_NOP, ICON_ROTATE,
+ "Pivot: %t|Bounding Box Center %x0|Median Point %x3|2D Cursor %x1",
+ xco,0,XIC+10,YIC, &(G.v2d->around), 0, 3.0, 0, 0,
+ "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period)");
+ xco+= XIC + 18;
+
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOG, SI_SYNC_UVSEL, B_REDR, ICON_EDIT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Sync UV and Mesh Selection");
+ xco+= XIC;
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ static int selectmode;
+ /* would use these if const's could go in strings
+ * SCE_SELECT_VERTEX, SCE_SELECT_FACE */
+ ubut = uiDefIconTextButI(block, ICONTEXTROW, B_REDR, ICON_VERTEXSEL,
+ "Selection Mode: %t|Vertex%x0|Face%x2",
+ xco,0,XIC+10,YIC, &selectmode, 0, 3.0, 0, 0,
+ "Change mesh selection mode");
+ uiButSetFunc(ubut, do_image_buttons_set_selection_mode_callback, &selectmode, NULL);
+
+ } else {
+ /* would use these if const's could go in strings
+ * SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
+ ubut = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
+ "Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
+ xco,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0,
+ "Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
+
+ }
+ xco+= XIC + 16;
+ uiBlockEndAlign(block);
+
+ /* Snap copied right out of view3d header */
+ uiBlockBeginAlign(block);
+
+ if (G.scene->snap_flag & SCE_SNAP) {
+ uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)");
+ xco+= XIC;
+ uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+ xco+= 70;
+ } else {
+ uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
+ xco+= XIC;
+ }
+
+ uiBlockEndAlign(block);
+ xco+= 10;
+ /* end snap */
+
+ /* Layer Menu */
+ layercount = CustomData_number_of_layers(&G.editMesh->fdata, CD_MTFACE);
+ if (layercount>1 && layercount < 12) { /* could allow any number but limit of 11 means no malloc needed */
+ static int act;
+ char str_menu[384], *str_pt; /*384 allows for 11 layers */
+
+
+ act = CustomData_get_active_layer(&G.editMesh->fdata, CD_MTFACE);
+
+ /*str_pt = (char *)MEM_mallocN(layercount*40 , "uvmenu"); str[0]='\0';*/
+ str_pt = str_menu;
+ str_pt[0]='\0';
+ mesh_layers_menu_concat(&G.editMesh->fdata, CD_MTFACE, str_pt);
+ ubut = uiDefButI(block, MENU, B_NOP, str_menu ,xco,0,85,YIC, &act, 0, 0, 0, 0, "Active UV Layer for editing");
+ uiButSetFunc(ubut, do_image_buttons_set_uvlayer_callback, &act, NULL);
+
+ /*MEM_freeN(str);*/
+ xco+= 90;
+ }
+ }
+
if (ima) {
RenderResult *rr= BKE_image_get_renderresult(ima);
@@ -1164,20 +1307,8 @@ void image_buttons(void)
uiBlockEndAlign(block);
xco+= 166;
}
- if( !ELEM3(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE, IMA_SRC_VIEWER) && ima->ok) {
-
- if (ima->packedfile) {
- headerbuttons_packdummy = 1;
- }
- if (ima->packedfile && ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
- uiDefIconButBitI(block, TOG, 1, B_SIMA_REPACK, ICON_UGLYPACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Re-Pack this image as PNG");
- else
- uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image");
-
- xco+= XIC+8;
- }
-
uiDefIconButBitI(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button");
+
xco+= XIC+8;
uiBlockBeginAlign(block);
@@ -1192,7 +1323,6 @@ void image_buttons(void)
uiDefIconButBitI(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values");
xco+= XIC;
}
- else G.sima->flag &= ~SI_SHOW_ZBUF; /* no confusing display for non-zbuf images */
}
xco+= 8;
@@ -1208,7 +1338,7 @@ void image_buttons(void)
uiBlockEndAlign(block);
xco+= 8;
}
-
+
/* draw LOCK */
uiDefIconButS(block, ICONTOG, 0, ICON_UNLOCKED, xco,0,XIC,YIC, &(G.sima->lock), 0, 0, 0, 0, "Updates other affected window spaces automatically to reflect changes in real time");
diff --git a/source/blender/src/header_imasel.c b/source/blender/src/header_imasel.c
index c99112248b7..8650d620cc0 100644
--- a/source/blender/src/header_imasel.c
+++ b/source/blender/src/header_imasel.c
@@ -44,19 +44,23 @@
#endif
#include "BMF_Api.h"
-#include "BIF_language.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
#include "DNA_ID.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "BIF_filelist.h"
#include "BIF_gl.h"
#include "BIF_imasel.h"
#include "BIF_interface.h"
+#include "BIF_language.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
#include "BSE_headerbuttons.h"
#include "blendef.h"
@@ -65,26 +69,30 @@
void do_imasel_buttons(short event)
{
SpaceImaSel *simasel;
- char name[256];
-
+
simasel= curarea->spacedata.first;
if(curarea->win==0) return;
switch(event) {
- case B_IMASELHOME:
+ case B_SORTIMASELLIST:
+ BIF_filelist_sort(simasel->files, simasel->sort);
+ scrarea_queue_winredraw(curarea);
break;
- case B_IMASELREMOVEBIP:
-
- if(bitset(simasel->fase, IMS_FOUND_BIP)){
-
- strcpy(name, simasel->dir);
- strcat(name, ".Bpib");
-
- remove(name);
-
- simasel->fase &= ~ IMS_FOUND_BIP;
+ case B_RELOADIMASELDIR:
+ BIF_filelist_free(simasel->files);
+ scrarea_queue_winredraw(curarea);
+ break;
+ case B_FILTERIMASELDIR:
+ if (simasel->flag & FILE_FILTER) {
+ BIF_filelist_setfilter(simasel->files,simasel->filter);
+ BIF_filelist_filter(simasel->files);
+ scrarea_queue_winredraw(curarea);
+ } else {
+ BIF_filelist_setfilter(simasel->files,0);
+ BIF_filelist_filter(simasel->files);
+ scrarea_queue_winredraw(curarea);
}
break;
}
@@ -94,9 +102,12 @@ void imasel_buttons(void)
{
SpaceImaSel *simasel;
uiBlock *block;
- short xco;
+ short xco, xcotitle;
char naam[256];
-
+ char dir[FILE_MAXDIR], group[32];
+ short type;
+ int do_filter = 0;
+
simasel= curarea->spacedata.first;
sprintf(naam, "header %d", curarea->headwin);
@@ -117,24 +128,93 @@ void imasel_buttons(void)
if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "");
else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "");
+ /* SORT TYPE */
xco+=XIC;
- if (simasel->title){
- xco+=25;
- glRasterPos2i(xco, 4);
- BMF_DrawString(G.font, simasel->title);
- xco+=BMF_GetStringWidth(G.fonts, simasel->title);
- xco+=25;
- }
-
uiBlockBeginAlign(block);
- uiDefIconBut(block, BUT, B_IMASELREMOVEBIP, ICON_BPIBFOLDER_X, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "");/* remove */
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTALPHA, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 0.0, 0, 0, "Sorts files alphabetically");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTBYEXT, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 3.0, 0, 0, "Sorts files by extension");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTTIME, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 1.0, 0, 0, "Sorts files by time");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTSIZE, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 2.0, 0, 0, "Sorts files by size");
+ uiBlockEndAlign(block);
+
+ cpack(0x0);
+ xco+=XIC+10;
+
+ type = simasel->type;
+
+ if (type != FILE_MAIN) {
+ uiDefIconButBitS(block, TOG, FILE_BOOKMARKS, B_RELOADIMASELDIR, ICON_BOOKMARKS,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Toggles Bookmarks on/off");
+ xco+=XIC+10;
+ }
+ xcotitle= xco;
+ xco+= BIF_GetStringWidth(G.font, simasel->title, (U.transopts & USER_TR_BUTTONS));
- uiDefIconButS(block, TOG|BIT|0, B_REDR, ICON_BPIBFOLDERGREY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles display of directory information");/* dir */
- uiDefIconButS(block, TOG|BIT|1, B_REDR, ICON_INFO, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles display of selected image information");/* info */
- uiDefIconButS(block, TOG|BIT|2, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* image */
- uiDefIconButS(block, TOG|BIT|3, B_REDR, ICON_MAGNIFY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles magnified view of thumbnail of images under mouse pointer");/* magnify */
+ if(simasel->pupmenu && simasel->menup) {
+ uiDefButS(block, MENU, B_NOP, simasel->pupmenu, xco+10,0,90,20, simasel->menup, 0, 0, 0, 0, "");
+ xco+= 100;
+ }
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, TOG, FILE_HIDE_DOT, B_RELOADIMASELDIR, ICON_GHOST,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Hides dot files");
uiBlockEndAlign(block);
+ xco+=20;
+ if(!simasel->files) {
+ simasel->files = BIF_filelist_new();
+ }
+
+ if (type == FILE_LOADLIB) {
+ do_filter = !BIF_filelist_islibrary(simasel->files, dir, group);
+ } else {
+ do_filter = (type != FILE_MAIN);
+ }
+ if ( do_filter ) {
+ uiDefIconButBitS(block, TOG, FILE_FILTER, B_FILTERIMASELDIR, ICON_SORTBYEXT,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Filter files");
+ if (simasel->flag & FILE_FILTER) {
+ xco+=4;
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, TOG, IMAGEFILE, B_FILTERIMASELDIR, ICON_IMAGE_COL,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show images");
+ uiDefIconButBitS(block, TOG, BLENDERFILE, B_FILTERIMASELDIR, ICON_BLENDER,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show .blend files");
+ uiDefIconButBitS(block, TOG, MOVIEFILE, B_FILTERIMASELDIR, ICON_SEQUENCE,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show movies");
+ uiDefIconButBitS(block, TOG, PYSCRIPTFILE, B_FILTERIMASELDIR, ICON_PYTHON,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show python scripts");
+ uiDefIconButBitS(block, TOG, FTFONTFILE, B_FILTERIMASELDIR, ICON_SYNTAX,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show fonts");
+ uiDefIconButBitS(block, TOG, SOUNDFILE, B_FILTERIMASELDIR, ICON_SOUND,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show sound files");
+ uiDefIconButBitS(block, TOG, TEXTFILE, B_FILTERIMASELDIR, ICON_TEXT,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show text files");
+ uiDefIconButBitS(block, TOG, FOLDERFILE, B_FILTERIMASELDIR, ICON_FILESEL,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show folders");
+ uiBlockEndAlign(block);
+ }
+ }
+
+ if(simasel->type==FILE_BLENDER) {
+ xco+=20;
+ } else {
+ uiDefButBitS(block, TOG, FILE_STRINGCODE, 0, "Relative Paths", xco+=XIC+20,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Makes sure returned paths are relative to the current .blend file");
+ xco+=90;
+ }
+
+ if(simasel->type==FILE_LOADLIB) {
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOGN, FILE_LINK, B_REDR, "Append", xco+=XIC,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Copies selected data into current project");
+ uiDefButBitS(block, TOG, FILE_LINK, B_REDR, "Link", xco+=100,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Creates a link to selected data from current project");
+ uiBlockEndAlign(block);
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, FILE_AUTOSELECT, B_REDR, "Autosel", xco+=125,0,65,YIC, &simasel->flag, 0, 0, 0, 0, "Autoselect imported objects");
+ uiDefButBitS(block, TOG, FILE_ACTIVELAY, B_REDR, "Active Layer", xco+=65,0,80,YIC, &simasel->flag, 0, 0, 0, 0, "Append object(s) in active layer");
+ uiDefButBitS(block, TOG, FILE_ATCURSOR, B_REDR, "At Cursor", xco+=80,0,65,YIC, &simasel->flag, 0, 0, 0, 0, "Append object(s) at cursor, use centroid if more than one object is selected");
+ uiBlockEndAlign(block);
+
+ xco+= 100; // scroll
+
+ } else if(simasel->type==FILE_BLENDER) {
+ uiDefButBitI(block, TOGN, G_FILE_NO_UI, B_REDR, "Load UI", xco+=XIC,0,80,YIC, &G.fileflags, 0, 0, 0, 0, "Load the UI setup as well as the scene data");
+
+ xco+= 100; // scroll
+ }
+
+ glRasterPos2f((float)xcotitle, 5.0);
+ BIF_RasterPos((float)xcotitle, 5.0); // stupid texture fonts
+ BIF_ThemeColor(TH_TEXT);
+ BIF_DrawString(uiBlockGetCurFont(block), simasel->title, (U.transopts & USER_TR_BUTTONS));
+
/* always do as last */
curarea->headbutlen= xco+2*XIC;
diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c
index 6e8aa70a88f..fb7b57ddb8d 100644
--- a/source/blender/src/header_info.c
+++ b/source/blender/src/header_info.c
@@ -84,6 +84,7 @@
#endif
#include "BKE_blender.h"
+#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_exotic.h"
#include "BKE_global.h"
@@ -101,13 +102,17 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_bpath.h"
#include "BLO_writefile.h"
#include "BSE_editipo.h"
#include "BSE_filesel.h"
+#include "BIF_imasel.h"
#include "BSE_headerbuttons.h"
+#include "BSE_node.h"
#include "BSE_sequence.h"
#include "BSE_edit.h"
+#include "BSE_time.h"
#include "IMB_imbuf_types.h"
@@ -279,45 +284,90 @@ int buttons_do_unpack()
Scene *copy_scene(Scene *sce, int level)
{
- /* level 0: al objects shared
- * level 1: al object-data shared
- * level 2: full copy
+ /*
+ * level 0: empty, only copy minimal stuff
+ * level 1: all objects shared
+ * level 2: all object-data shared
+ * level 3: full copy
*/
+
Scene *scen;
Base *base, *obase;
-
- /* level 0 */
- scen= copy_libblock(sce);
- duplicatelist(&(scen->base), &(sce->base));
- clear_id_newpoins();
+ if (level==0) { /* Add Empty, minimal copy */
+ ListBase lb;
+ scen= add_scene(sce->id.name+2);
+
+ lb= scen->r.layers;
+ scen->r= sce->r;
+ scen->r.layers= lb;
+
+ } else {
+ /* level 1+, but not level 0 */
+ scen= copy_libblock(sce);
+ duplicatelist(&(scen->base), &(sce->base));
+
+ clear_id_newpoins();
+
+ id_us_plus((ID *)scen->world);
+ id_us_plus((ID *)scen->set);
- id_us_plus((ID *)scen->world);
- id_us_plus((ID *)scen->set);
-
- scen->ed= NULL;
- scen->radio= NULL;
- scen->theDag= NULL;
- scen->toolsettings= MEM_dupallocN(sce->toolsettings);
-
- duplicatelist(&(scen->markers), &(sce->markers));
- duplicatelist(&(scen->r.layers), &(sce->r.layers));
+ scen->ed= NULL;
+ scen->radio= NULL;
+ scen->theDag= NULL;
+ scen->toolsettings= MEM_dupallocN(sce->toolsettings);
+
+ duplicatelist(&(scen->markers), &(sce->markers));
+ duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
+ duplicatelist(&(scen->r.layers), &(sce->r.layers));
+
+ scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
+
+ obase= sce->base.first;
+ base= scen->base.first;
+ while(base) {
+ id_us_plus(&base->object->id);
+ if(obase==sce->basact) scen->basact= base;
+
+ obase= obase->next;
+ base= base->next;
+ }
+ BPY_copy_scriptlink(&sce->scriptlink);
+
+ /* sculpt data */
+ sce->sculptdata.session = NULL;
+ if (sce->sculptdata.cumap) {
+ int a;
+ scen->sculptdata.cumap = curvemapping_copy(sce->sculptdata.cumap);
+ scen->sculptdata.session = NULL; /* this is only for temp data storage anyway */
+ for(a=0; a<MAX_MTEX; ++a) {
+ if (sce->sculptdata.mtex[a]) {
+ scen->sculptdata.mtex[a]= MEM_dupallocN(sce->sculptdata.mtex[a]);
+ }
+ }
+ }
+ }
- scen->nodetree= ntreeCopyTree(sce->nodetree, 0);
+ // make a private copy of the avicodecdata
- obase= sce->base.first;
- base= scen->base.first;
- while(base) {
- id_us_plus(&base->object->id);
- if(obase==sce->basact) scen->basact= base;
-
- obase= obase->next;
- base= base->next;
+ if (sce->r.avicodecdata) {
+
+ scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+ scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
+ scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
}
+
+ // make a private copy of the qtcodecdata
+
+ if (sce->r.qtcodecdata) {
+ scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
+ scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
+ }
+
+
+ if(level==0 || level==1) return scen;
- if(level==0) return scen;
-
- /* level 1 */
+ /* level 2 */
G.scene= scen;
single_object_users(0);
@@ -325,8 +375,8 @@ Scene *copy_scene(Scene *sce, int level)
/* camera */
ID_NEW(G.scene->camera);
- /* level 2 */
- if(level>=2) {
+ /* level 3 */
+ if(level>=3) {
if(scen->world) {
id_us_plus(&scen->world->id);
scen->world= copy_world(scen->world);
@@ -340,24 +390,6 @@ Scene *copy_scene(Scene *sce, int level)
}
clear_id_newpoins();
-
- BPY_copy_scriptlink(&sce->scriptlink);
- // make a private copy of the avicodecdata
-
- if (sce->r.avicodecdata) {
-
- scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
- scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
- scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
- }
-
- // make a private copy of the qtcodecdata
-
- if (sce->r.qtcodecdata) {
- scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
- scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
- }
-
return scen;
}
@@ -395,7 +427,10 @@ void do_info_buttons(unsigned short event)
}
/* last item: NEW SCREEN */
if(sc==0) {
- duplicate_screen();
+ nr= pupmenu("New Screen%t|Empty%x1|Duplicate%x2");
+
+ if(nr==1) default_twosplit();
+ if(nr==2) duplicate_screen();
}
break;
case B_INFODELSCR:
@@ -440,32 +475,9 @@ void do_info_buttons(unsigned short event)
}
/* last item: NEW SCENE */
if(sce==0) {
- nr= pupmenu("Add scene%t|Empty|Link Objects|Link ObData|Full Copy");
- if(nr<= 0) return;
- if(nr==1) {
- ListBase lb;
-
- sce= add_scene(G.scene->id.name+2);
- /* pretty bad ass copying here. we should use copy_scene to do all (ton) */
- lb= sce->r.layers;
- sce->r= G.scene->r;
- sce->r.layers= lb;
-#ifdef _WIN32
- if (sce->r.avicodecdata) {
- sce->r.avicodecdata = MEM_dupallocN(G.scene->r.avicodecdata);
- sce->r.avicodecdata->lpFormat = MEM_dupallocN(G.scene->r.avicodecdata->lpFormat);
- sce->r.avicodecdata->lpParms = MEM_dupallocN(G.scene->r.avicodecdata->lpParms);
- }
-#endif
-#ifdef WITH_QUICKTIME
- if (sce->r.qtcodecdata) {
- sce->r.qtcodecdata = MEM_dupallocN(G.scene->r.qtcodecdata);
- sce->r.qtcodecdata->cdParms = MEM_dupallocN(G.scene->r.qtcodecdata->cdParms);
- }
-#endif
- }
- else sce= copy_scene(G.scene, nr-2);
-
+ nr= pupmenu("Add scene%t|Empty%x0|Link Objects%x1|Link ObData%x2|Full Copy%x3");
+ if(nr<0) return;
+ sce= copy_scene(G.scene, nr);
set_scene(sce);
}
countall();
@@ -478,29 +490,29 @@ void do_info_buttons(unsigned short event)
else if(G.scene->id.next) sce= G.scene->id.next;
else return;
if(okee("Delete current scene")) {
+ /* Note, anything besides free_libblock needs to be added in
+ * Python Scene.c for Blender.Scene.Unlink() */
+
/* exit modes... could become single call once */
exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
- if(G.f & G_FACESELECT) set_faceselect(); /* Switch off face select */
+ exit_paint_modes();
/* check all sets */
- sce1= G.main->scene.first;
- while(sce1) {
+ for (sce1= G.main->scene.first; sce1; sce1= sce1->id.next) {
if(sce1->set == G.scene) sce1->set= 0;
- sce1= sce1->id.next;
}
-
+
/* check all sequences */
clear_scene_in_allseqs(G.scene);
+ /* check render layer nodes in other scenes */
+ clear_scene_in_nodes(G.scene);
+
/* al screens */
- sc= G.main->screen.first;
- while(sc) {
+
+ for (sc= G.main->screen.first; sc; sc= sc->id.next ) {
if(sc->scene == G.scene) sc->scene= sce;
- sc= sc->id.next;
}
free_libblock(&G.main->scene, G.scene);
set_scene(sce);
@@ -832,6 +844,9 @@ static void do_info_filemenu(void *arg, int event)
case 6: /* save image */
BIF_save_rendered_image_fs();
break;
+ case 7:
+ activate_imageselect(FILE_LOADLIB, "Load Library", G.lib, 0);
+ break;
case 22: /* save runtime */
activate_fileselect(FILE_SPECIAL, "Save Runtime", "", write_runtime_check);
break;
@@ -844,33 +859,25 @@ static void do_info_filemenu(void *arg, int event)
case 25:
BIF_screendump(1);
break;
- case 10: /* pack data */
- check_packAll();
- break;
- case 11: /* unpack to current dir */
- unpackAll(PF_WRITE_LOCAL);
- G.fileflags &= ~G_AUTOPACK;
- break;
- case 12: /* unpack data */
- if (buttons_do_unpack() != RET_CANCEL) {
- /* Clear autopack bit only if user selected one of the unpack options */
- G.fileflags &= ~G_AUTOPACK;
- }
- break;
case 13:
exit_usiblender();
break;
case 15: /* recover previous session */
{
extern short winqueue_break; /* editscreen.c */
- int save_over;
+ int save_over, retval = 0;
char str[FILE_MAXDIR+FILE_MAXFILE];
char scestr[FILE_MAXDIR+FILE_MAXFILE];
strcpy(scestr, G.sce); /* temporal store */
save_over = G.save_over;
- BLI_make_file_string("/", str, U.tempdir, "quit.blend");
- BKE_read_file(str, NULL);
+ BLI_make_file_string("/", str, btempdir, "quit.blend");
+ retval = BKE_read_file(str, NULL);
+
+ /*we successfully loaded a blend file, get sure that
+ pointcache works */
+ if (retval!=0) G.relbase_valid = 1;
+
G.save_over = save_over;
strcpy(G.sce, scestr);
@@ -894,6 +901,7 @@ static void do_info_filemenu(void *arg, int event)
U.flag ^= (USER_FILECOMPRESS);
break;
}
+
allqueue(REDRAWINFO, 0);
}
@@ -936,6 +944,109 @@ static uiBlock *info_openrecentmenu(void *arg_unused)
return block;
}
+static void do_info_externalfiles(void *arg, int event)
+{
+ switch (event) {
+
+ case 1: /* pack data */
+ check_packAll();
+ break;
+#if 0
+ case 2: /* unpack to current dir */
+ unpackAll(PF_WRITE_LOCAL);
+ G.fileflags &= ~G_AUTOPACK;
+ break;
+#endif
+ case 3: /* unpack data */
+ if (buttons_do_unpack() != RET_CANCEL) {
+ /* Clear autopack bit only if user selected one of the unpack options */
+ G.fileflags &= ~G_AUTOPACK;
+ }
+ break;
+ case 10: /* make all paths relative */
+ if (G.relbase_valid) {
+ int tot,changed,failed,linked;
+ char str[512];
+ char txtname[24]; /* text block name */
+ txtname[0] = '\0';
+ makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
+ if (failed) sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
+ else sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+ pupmenu(str);
+ } else {
+ pupmenu("Can't set relative paths with an unsaved blend file");
+ }
+ break;
+ case 11: /* make all paths relative */
+ {
+ int tot,changed,failed,linked;
+ char str[512];
+ char txtname[24]; /* text block name */
+ txtname[0] = '\0';
+ makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
+ sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+ if (failed) sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
+ else sprintf(str, "Make Absolute%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
+
+ pupmenu(str);
+ }
+ break;
+ case 12: /* check images exist */
+ {
+ char txtname[24]; /* text block name */
+ txtname[0] = '\0';
+
+ /* run the missing file check */
+ checkMissingFiles( txtname );
+
+ if (txtname[0] == '\0') {
+ okee("No external files missing");
+ } else {
+ char str[128];
+ sprintf(str, "Missing files listed in Text \"%s\"", txtname );
+ error(str);
+ }
+ }
+ break;
+ case 13: /* search for referenced files that are not available */
+ if(curarea->spacetype==SPACE_INFO) {
+ ScrArea *sa;
+ sa= closest_bigger_area();
+ areawinset(sa->win);
+ }
+ activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles);
+ break;
+ }
+
+ allqueue(REDRAWINFO, 0);
+}
+
+static uiBlock *info_externalfiles(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "info_externalfiles", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_info_externalfiles, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into Blend", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+#if 0
+ uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Removes all packed files from the project and saves them to the current directory");
+#endif
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack into Files...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Absolute", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 13, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
static uiBlock *info_filemenu(void *arg_unused)
{
uiBlock *block;
@@ -966,9 +1077,9 @@ static uiBlock *info_filemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Image...|F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Dump Screen|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Rendered Image...|F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot Subwindow|Ctrl F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Screenshot All|Ctrl Shift F3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, "");
#if GAMEBLENDER == 1
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save Runtime...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, "");
#ifdef _WIN32
@@ -984,17 +1095,16 @@ static uiBlock *info_filemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, "");
uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Data", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
-// uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "Removes all packed files from the project and saves them to the current directory");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Data...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
-
+
+ uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
uiBlockSetDirection(block, UI_DOWN);
@@ -1343,44 +1453,48 @@ static uiBlock *info_add_groupmenu(void *arg_unused)
void do_info_addmenu(void *arg, int event)
{
- switch(event) {
- case 0:
- /* Mesh */
- break;
- case 1:
- /* Curve */
- break;
- case 2:
- /* Surface */
- break;
- case 3:
- /* Metaball */
- break;
- case 4:
- /* Text (argument is discarded) */
- add_primitiveFont(event);
- break;
- case 5:
- /* Empty */
- add_object_draw(OB_EMPTY);
- break;
- case 6:
- /* Camera */
- add_object_draw(OB_CAMERA);
- break;
- case 8:
- /* Armature */
- add_primitiveArmature(OB_ARMATURE);
- break;
- case 9:
- /* Lattice */
- add_object_draw(OB_LATTICE);
- break;
- case 10:
- /* group instance not yet */
- break;
- default:
- break;
+ if (event>=20) {
+ BPY_menu_do_python(PYMENU_ADD, event - 20);
+ } else {
+ switch(event) {
+ case 0:
+ /* Mesh */
+ break;
+ case 1:
+ /* Curve */
+ break;
+ case 2:
+ /* Surface */
+ break;
+ case 3:
+ /* Metaball */
+ break;
+ case 4:
+ /* Text (argument is discarded) */
+ add_primitiveFont(event);
+ break;
+ case 5:
+ /* Empty */
+ add_object_draw(OB_EMPTY);
+ break;
+ case 6:
+ /* Camera */
+ add_object_draw(OB_CAMERA);
+ break;
+ case 8:
+ /* Armature */
+ add_primitiveArmature(OB_ARMATURE);
+ break;
+ case 9:
+ /* Lattice */
+ add_object_draw(OB_LATTICE);
+ break;
+ case 10:
+ /* group instance not yet */
+ break;
+ default:
+ break;
+ }
}
allqueue(REDRAWINFO, 0);
}
@@ -1390,6 +1504,8 @@ static uiBlock *info_addmenu(void *arg_unused)
{
/* static short tog=0; */
uiBlock *block;
+ BPyMenu *pym;
+ int i=0;
short yco= 0;
block= uiNewBlock(&curarea->uiblocks, "addmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
@@ -1416,6 +1532,15 @@ static uiBlock *info_addmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Armature", 0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Lattice", 0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 9, "");
+ pym = BPyMenuTable[PYMENU_ADD];
+ if (pym) {
+ uiDefIconTextBut(block, SEPR, 0, ICON_BLANK1, "", 0, yco-=6, 1620, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ for (; pym; pym = pym->next, i++) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, i+20, pym->tooltip?pym->tooltip:pym->filename);
+ }
+ }
+
uiBlockSetDirection(block, UI_DOWN);
uiTextBoundsBlock(block, 80);
@@ -1539,23 +1664,23 @@ static void do_info_timelinemenu(void *arg, int event)
if (!ob) error("Select an object before showing and selecting its keyframes");
else select_select_keys();
break;
- case 3:
+ case 3:
/* select next keyframe */
if (!ob) error("Select an object before selecting its next keyframe");
else nextkey_obipo(1);
break;
- case 4:
+ case 4:
/* select previous keyframe */
if (!ob) error("Select an object before selecting its previous keyframe");
else nextkey_obipo(-1);
break;
case 5:
- /* next keyframe */
+ /* next keyframe */
if (!ob) error("Select an object before going to its next keyframe");
else movekey_obipo(1);
break;
case 6:
- /* previous keyframe */
+ /* previous keyframe */
if (!ob) error("Select an object before going to its previous keyframe");
else movekey_obipo(-1);
break;
@@ -1591,6 +1716,14 @@ static void do_info_timelinemenu(void *arg, int event)
CFRA= SFRA;
update_for_newframe();
break;
+ case 13:
+ /* previous keyframe */
+ nextprev_timeline_key(-1);
+ break;
+ case 14:
+ /* next keyframe */
+ nextprev_timeline_key(1);
+ break;
}
allqueue(REDRAWINFO, 0);
}
@@ -1613,9 +1746,12 @@ static uiBlock *info_timelinemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Keyframe|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Previous Keyframe|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Ob-Keyframe|Shift PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Previous Ob-Keyframe|Shift PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Keyframe|Ctrl PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Previous Keyframe|Ctrl PageDown", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Next Frame|RightArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
@@ -1641,8 +1777,13 @@ static uiBlock *info_timelinemenu(void *arg_unused)
void do_info_render_bakemenu(void *arg, int event)
{
-
- objects_bake_render(event);
+ switch (event) {
+ case 6:
+ G.scene->r.bake_flag ^= event;
+ break;
+ default:
+ objects_bake_render_ui(event);
+ }
allqueue(REDRAWINFO, 0);
}
@@ -1650,15 +1791,24 @@ void do_info_render_bakemenu(void *arg, int event)
static uiBlock *info_render_bakemenu(void *arg_unused)
{
uiBlock *block;
- short yco= 0;
+ short yco= 0, menuwidth=160;
block= uiNewBlock(&curarea->uiblocks, "render_bakemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_info_render_bakemenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Full Render|Ctrl Alt B, 1", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ambient Occlusion|Ctrl Alt B, 2", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Normals|Ctrl Alt B, 3", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Only|Ctrl Alt B, 4", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 4, "");
+ if(G.scene->r.bake_flag & R_BAKE_TO_ACTIVE) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ } else {
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Selected to Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ }
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Full Render|Ctrl Alt B, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ambient Occlusion|Ctrl Alt B, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Normals|Ctrl Alt B, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Only|Ctrl Alt B, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Displacement|Ctrl Alt B, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 50);
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index 1c117e0331e..4f98e966f8c 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -54,6 +54,7 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
@@ -64,11 +65,13 @@
#include "BKE_action.h"
#include "BKE_constraint.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -82,6 +85,7 @@
#include "BSE_time.h"
#include "BIF_editaction.h"
+#include "BIF_editconstraint.h"
#include "BIF_interface.h"
#include "BIF_mainqueue.h"
#include "BIF_resources.h"
@@ -94,7 +98,6 @@
#include "blendef.h"
#include "mydevice.h"
-static int viewmovetemp = 0;
extern int totipo_edit, totipo_sel;
/* headerbutton call, assuming full context is set */
@@ -138,11 +141,27 @@ void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
Object *ob= (Object *)si->from;
/* constraint exception */
if(si->blocktype==ID_CO) {
- bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
- if(conchan) {
- if(conchan->ipo)
- conchan->ipo->id.us--;
- conchan->ipo= ipo;
+ /* check the local constraint ipo */
+ if(si->bonename && si->bonename[0] && ob->pose) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, si->bonename);
+ bConstraint *con;
+
+ for(con= pchan->constraints.first; con; con= con->next)
+ if(strcmp(con->name, si->constname)==0)
+ break;
+ if(con) {
+ if(con->ipo)
+ con->ipo->id.us--;
+ con->ipo= ipo;
+ }
+ }
+ else {
+ bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
+ if(conchan) {
+ if(conchan->ipo)
+ conchan->ipo->id.us--;
+ conchan->ipo= ipo;
+ }
}
}
else if(si->blocktype==ID_FLUIDSIM) { // NT
@@ -153,6 +172,15 @@ void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
}
ob->fluidsimSettings->ipo = ipo;
}
+ else if(si->blocktype==ID_PA) {
+ ParticleSystem *psys=psys_get_current(ob);
+ if(psys){
+ if(psys->part->ipo){
+ psys->part->ipo->id.us--;
+ }
+ psys->part->ipo = ipo;
+ }
+ }
else if(si->blocktype==ID_OB) {
if(ob->ipo)
ob->ipo->id.us--;
@@ -263,7 +291,10 @@ static void do_ipo_editmenu_transformmenu(void *arg, int event)
case 0: /* grab/move */
transform_ipo('g');
break;
- case 1: /* scale */
+ case 1: /* rotate */
+ transform_ipo('r');
+ break;
+ case 2: /* scale */
transform_ipo('s');
break;
}
@@ -278,7 +309,8 @@ static uiBlock *ipo_editmenu_transformmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_ipo_editmenu_transformmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -640,7 +672,7 @@ static uiBlock *ipo_editmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clean IPO Curves|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Smooth IPO Curves|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
@@ -714,6 +746,9 @@ static void do_ipo_viewmenu(void *arg, int event)
center_currframe();
scrarea_queue_winredraw(curarea);
break;
+ case 11:
+ do_ipo_buttons(B_IPOVIEWCENTER);
+ break;
}
}
@@ -749,7 +784,7 @@ static uiBlock *ipo_viewmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center on Current Frame|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
"Lock Time to Other Windows|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
@@ -758,6 +793,10 @@ static uiBlock *ipo_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Current Frame to Selected|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
}
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View Selected|NumPad .", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
if(!curarea->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,20, "");
else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
@@ -786,14 +825,11 @@ static void do_ipo_selectmenu(void *arg, int event)
break;
case 2:
borderselect_markers();
+ allqueue(REDRAWMARKER, 0);
break;
case 3:
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
}
}
@@ -848,11 +884,7 @@ static void do_ipo_markermenu(void *arg, int event)
break;
}
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
static uiBlock *ipo_markermenu(void *arg_unused)
@@ -932,6 +964,10 @@ static char *ipo_modeselect_pup(void)
if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
str += sprintf(str,formatstring,"Fluidsim",ID_FLUIDSIM, ICON_WORLD);
}
+
+ if(ob->particlesystem.first) {
+ str += sprintf(str,formatstring,"Particles",ID_PA, ICON_PARTICLES);
+ }
}
str += sprintf(str,formatstring, "Sequence",ID_SEQ, ICON_SEQUENCE);
@@ -952,6 +988,7 @@ void do_ipo_buttons(short event)
if(curarea->win==0) return;
switch(event) {
+ case B_IPOVIEWCENTER:
case B_IPOHOME:
/* boundbox */
@@ -970,7 +1007,7 @@ void do_ipo_buttons(short event)
for(a=0; a<G.sipo->totipo; a++, ei++) {
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
- boundbox_ipocurve(ei->icu);
+ boundbox_ipocurve(ei->icu, (event==B_IPOVIEWCENTER));
if(first) {
v2d->tot= ei->icu->totrct;
@@ -1065,7 +1102,6 @@ void do_ipo_buttons(short event)
allqueue(REDRAWVIEW3D, 0);
break;
case B_VIEW2DZOOM:
- viewmovetemp= 0;
view2dzoom(event);
scrarea_queue_headredraw(curarea);
break;
@@ -1149,7 +1185,19 @@ void do_ipo_buttons(short event)
}
}
break;
- }
+ case B_IPOVIEWALL:
+ /* set visible active */
+ for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
+ if (ei->icu) ei->flag |= IPO_VISIBLE;
+ else ei->flag &= ~IPO_VISIBLE;
+ }
+ break;
+ case B_IPOREDRAW:
+ DAG_object_flush_update(G.scene, ob, OB_RECALC);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIPO, 0);
+ break;
+ }
}
void ipo_buttons(void)
@@ -1245,11 +1293,14 @@ void ipo_buttons(void)
}
else if(G.sipo->blocktype==ID_CO) {
- if(G.sipo->from && G.sipo->actname[0]==0)
+ if(ob->pose==NULL)
uiDefIconButBitS(block, TOG, OB_ACTION_OB, B_IPO_ACTION_OB, ICON_ACTION, xco,0,XIC,YIC, &(ob->ipoflag), 0, 0, 0, 0, "Sets Ipo to be included in an Action or not");
else {
- uiSetButLock(1, "Pose Constraint Ipo cannot be switched");
- uiDefIconButS(block, TOG, 1, ICON_ACTION, xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
+ bConstraint *con= get_active_constraint(ob);
+ if(con)
+ uiDefIconButBitS(block, TOGN, CONSTRAINT_OWN_IPO, B_IPOREDRAW, ICON_ACTION, xco,0,XIC,YIC, &con->flag, 0, 0, 0, 0,
+ (con->flag & CONSTRAINT_OWN_IPO)?"Ipo is connected to Constraint itself":"Ipo is connected to Pose Action"
+ );
}
xco+= XIC;
}
@@ -1261,6 +1312,12 @@ void ipo_buttons(void)
uiClearButLock();
}
+ /* ipo muting */
+ if (G.sipo->ipo) {
+ uiDefIconButS(block, ICONTOG, 1, ICON_MUTE_IPO_OFF, xco,0,XIC,YIC, &(G.sipo->ipo->muteipo), 0, 0, 0, 0, "Mute IPO-block");
+ xco += XIC;
+ }
+
/* mainmenu, only when data is there and no pin */
uiSetButLock(G.sipo->pin, "Can't change because of pinned data");
@@ -1288,6 +1345,8 @@ void ipo_buttons(void)
icon = ICON_TEXTURE;
else if(G.sipo->blocktype == ID_FLUIDSIM)
icon = ICON_WORLD;
+ else if(G.sipo->blocktype == ID_PA)
+ icon = ICON_PARTICLES;
uiDefIconTextButS(block, MENU, B_IPOMAIN, icon, ipo_modeselect_pup(), xco,0,100,20, &(G.sipo->blocktype), 0, 0, 0, 0, "Show IPO type");
diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c
index 918383478e5..05f809a46ae 100644
--- a/source/blender/src/header_nla.c
+++ b/source/blender/src/header_nla.c
@@ -122,6 +122,9 @@ static void do_nla_viewmenu(void *arg, int event)
case 6: /* Show all objects that have keyframes? */
G.snla->flag ^= SNLA_ALLKEYED;
break;
+ case 7: /* Show timing in Frames or Seconds */
+ G.snla->flag ^= SNLA_DRAWTIME;
+ break;
}
}
@@ -137,6 +140,12 @@ static uiBlock *nla_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, (G.snla->flag & SNLA_ALLKEYED)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT,
"Only Objects On Visible Layers|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ if (G.snla->flag & SNLA_DRAWTIME) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Frames|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ } else {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Seconds|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ }
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
if(BTST(G.snla->lock, 0)) {
@@ -193,11 +202,7 @@ static void do_nla_selectmenu(void *arg, int event)
break;
case 3: /* Select/Deselect All Markers */
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case 4: /* Borderselect markers */
borderselect_markers();
@@ -264,12 +269,16 @@ static void do_nla_strip_transformmenu(void *arg, int event)
{
switch(event) {
case 0: /* grab/move */
- transform_nlachannel_keys ('g', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('g', 0);
+ update_for_newframe_muted();
break;
case 1: /* scale */
- transform_nlachannel_keys ('s', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('s', 0);
+ update_for_newframe_muted();
+ break;
+ case 2: /* extend */
+ transform_nlachannel_keys('e', 0);
+ update_for_newframe_muted();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -284,8 +293,10 @@ static uiBlock *nla_strip_transformmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_nla_strip_transformmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-
+
+
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
@@ -320,7 +331,7 @@ static void do_nla_stripmenu(void *arg, int event)
case 7: /* Move Down */
shift_nlastrips_down();
break;
- case 8: /* size */
+ case 8: /* reset scale */
reset_action_strips(1);
break;
case 9: /* reset start/end of action */
@@ -329,6 +340,9 @@ static void do_nla_stripmenu(void *arg, int event)
case 10: /* add new action as new action strip */
add_empty_nlablock();
break;
+ case 11: /* apply scale */
+ reset_action_strips(3);
+ break;
}
}
@@ -342,10 +356,11 @@ static uiBlock *nla_stripmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Strip Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBlockBut(block, nla_strip_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 20, "");
- uiDefIconTextBlockBut(block, nla_strip_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap To Frame", 0, yco-=20, 120, 20, "");
+ uiDefIconTextBlockBut(block, nla_strip_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 20, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Strip Size|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Strip Scale|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reset Action Start/End|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Strip Scaling|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -396,11 +411,7 @@ static void do_nla_markermenu(void *arg, int event)
break;
}
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
static uiBlock *nla_markermenu(void *arg_unused)
@@ -501,34 +512,24 @@ void nla_buttons(void)
uiBlockSetEmboss(block, UI_EMBOSS);
- /* FULL WINDOW */
-
-
-// xco = 8;
-
-// uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
-
-// xco+= XIC+22;
+ /* draw AUTOSNAP */
+ xco += 8;
- /* FULL WINDOW */
-// if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Returns to multiple views window (CTRL+Up arrow)");
-// else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, "Makes current window full screen (CTRL+Down arrow)");
+ if (G.snla->flag & SNLA_DRAWTIME) {
+ uiDefButS(block, MENU, B_REDR,
+ "Auto-Snap Strips/Keyframes %t|No Snap %x0|Second Step %x1|Nearest Second %x2|Nearest Marker %x3",
+ xco,0,70,YIC, &(G.snla->autosnap), 0, 1, 0, 0,
+ "Auto-snapping mode for strips and keyframes when transforming");
+ }
+ else {
+ uiDefButS(block, MENU, B_REDR,
+ "Auto-Snap Strips/Keyframes %t|No Snap %x0|Frame Step %x1|Nearest Frame %x2|Nearest Marker %x3",
+ xco,0,70,YIC, &(G.snla->autosnap), 0, 1, 0, 0,
+ "Auto-snapping mode for strips and keyframes when transforming");
+ }
- /* HOME */
-// uiDefIconBut(block, BUT, B_NLAHOME, ICON_HOME, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");
-// xco+= XIC;
+ xco += (70 + 8);
- /* IMAGE */
-// uiDefIconButS(block, TOG, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &sseq->mainb, 0, 0, 0, 0, "Toggles image display");
-
- /* ZOOM en BORDER */
-// xco+= XIC;
-// uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, xco+=XIC,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zoom view (CTRL+MiddleMouse)");
-// uiDefIconBut(block, BUT, B_NLABORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zoom view to area");
-
- /* draw LOCK */
-// xco+= XIC/2;
-
xco += 8;
uiDefIconButS(block, ICONTOG, 1, ICON_UNLOCKED, xco,0,XIC,YIC, &(snla->lock), 0, 0, 0, 0, "Toggles forced redraw of other windows to reflect changes in real time");
diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c
index 83aff8bcbe1..dd6ae890b01 100644
--- a/source/blender/src/header_node.c
+++ b/source/blender/src/header_node.c
@@ -23,7 +23,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): David Millan Escriva, Juho Vepsäläinen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -216,7 +216,7 @@ void do_node_addmenu(void *arg, int event)
else node->flag &= ~NODE_TEST;
}
- getmouseco_areawin(mval);
+ toolbox_mousepos(mval, 0 ); /* get initial mouse position */
areamouseco_to_ipoco(G.v2d, mval, &locx, &locy);
node= node_add_node(snode, event, locx, locy);
@@ -273,11 +273,17 @@ static void node_make_addmenu(SpaceNode *snode, int nodeclass, uiBlock *block)
}
else {
bNodeType *type;
+ int script=0;
for(a=0, type= ntree->alltypes.first; type; type=type->next) {
if( type->nclass == nodeclass ) {
- printf("node %s\n", type->name);
+ if(type->type == NODE_DYNAMIC) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, type->name, 0,
+ yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, NODE_DYNAMIC_MENU+script, "");
+ script++;
+ } else {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, type->name, 0,
yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, type->type, "");
+ }
a++;
}
}
@@ -424,6 +430,22 @@ static uiBlock *node_add_groupmenu(void *arg_unused)
return block;
}
+static uiBlock *node_add_dynamicmenu(void *arg_unused)
+{
+ SpaceNode *snode= curarea->spacedata.first;
+ uiBlock *block;
+
+ block= uiNewBlock(&curarea->uiblocks, "node_add_dynamicmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_node_addmenu, NULL);
+
+ node_make_addmenu(snode, NODE_CLASS_OP_DYNAMIC, block);
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
+
static uiBlock *node_addmenu(void *arg_unused)
{
SpaceNode *snode= curarea->spacedata.first;
@@ -441,6 +463,7 @@ static uiBlock *node_addmenu(void *arg_unused)
uiDefIconTextBlockBut(block, node_add_vectormenu, NULL, ICON_RIGHTARROW_THIN, "Vector", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, node_add_convertermenu, NULL, ICON_RIGHTARROW_THIN, "Convertor", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, node_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBlockBut(block, node_add_dynamicmenu, NULL, ICON_RIGHTARROW_THIN, "Dynamic", 0, yco-=20, 120, 19, "");
}
else if(snode->treetype==NTREE_COMPOSIT) {
uiDefIconTextBlockBut(block, node_add_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input", 0, yco-=20, 120, 19, "");
@@ -513,6 +536,19 @@ static void do_node_nodemenu(void *arg, int event)
case 10: /* execute */
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
break;
+ case 11: /* make link */
+ node_make_link(snode);
+ break;
+ case 12: /* rename */
+ node_rename(snode);
+ break;
+ case 13: /* read saved full sample layers */
+ node_read_fullsamplelayers(snode);
+ break;
+ case 14: /* connect viewer */
+ node_active_link_viewer(snode);
+ break;
+
}
if(fromlib==-1) error_libdata();
@@ -537,6 +573,10 @@ static uiBlock *node_nodemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Link|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ungroup|Alt G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ -545,12 +585,20 @@ static uiBlock *node_nodemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide/Unhide|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
if(snode->treetype==NTREE_COMPOSIT) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Execute Composite|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Render Results|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Read Saved Full Sample Results|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connect Node to Viewer|Ctrl LMB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
}
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Cyclic Dependencies|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
@@ -662,7 +710,7 @@ void node_buttons(ScrArea *sa)
xco+= 80;
uiDefButBitS(block, TOG, R_COMP_FREE, B_NOP, "Free Unused", xco+5,0,80,19, &G.scene->r.scemode, 0.0f, 0.0f, 0, 0, "Free Nodes that are not used while composite");
xco+= 80;
- uiDefButBitS(block, TOG, SNODE_BACKDRAW, B_NOP, "Backdrop", xco+5,0,80,19, &snode->flag, 0.0f, 0.0f, 0, 0, "Use active Viewer Node output as backdrop");
+ uiDefButBitS(block, TOG, SNODE_BACKDRAW, REDRAWNODE, "Backdrop", xco+5,0,80,19, &snode->flag, 0.0f, 0.0f, 0, 0, "Use active Viewer Node output as backdrop");
xco+= 80;
}
diff --git a/source/blender/src/header_oops.c b/source/blender/src/header_oops.c
index 1a825bbe6dd..7bfbf0ee667 100644
--- a/source/blender/src/header_oops.c
+++ b/source/blender/src/header_oops.c
@@ -507,7 +507,9 @@ void oops_buttons(void)
uiDefIconButBitS(block, TOG, OOPS_TE, B_NEWOOPS, ICON_TEXTURE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Texture datablocks");
uiDefIconButBitS(block, TOG, OOPS_IP, B_NEWOOPS, ICON_IPO_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Ipo datablocks");
uiDefIconButBitS(block, TOG, OOPS_IM, B_NEWOOPS, ICON_IMAGE_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Image datablocks");
+ uiDefIconButBitS(block, TOG, OOPS_GR, B_NEWOOPS, ICON_CIRCLE_DEHLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Group datablocks");
uiDefIconButBitS(block, TOG, OOPS_LI, B_NEWOOPS, ICON_LIBRARY_HLT, (short)(xco+=XIC),0,XIC,YIC, &soops->visiflag, 0, 0, 0, 0, "Displays Library datablocks");
+
uiBlockEndAlign(block);
@@ -518,8 +520,11 @@ void oops_buttons(void)
else strcpy(naam, oops->id->name);
cpack(0x0);
+ BIF_ThemeColor(TH_MENU_TEXT); /* makes text readable on dark theme */
+ BIF_SetScale(1.0);
glRasterPos2i(xco+=XIC+10, 5);
- BMF_DrawString(uiBlockGetCurFont(block), naam);
+ BIF_RasterPos(xco+=XIC+10, 5);
+ BIF_DrawString(G.font, naam, 0);
}
}
diff --git a/source/blender/src/header_script.c b/source/blender/src/header_script.c
index 98f18c4e2ac..ba43ae2e7e5 100644
--- a/source/blender/src/header_script.c
+++ b/source/blender/src/header_script.c
@@ -60,7 +60,6 @@
#include "BKE_sca.h"
#include "BSE_filesel.h"
-#include "BPI_script.h"
#include "BPY_extern.h"
#include "BPY_menus.h"
@@ -117,6 +116,7 @@ static void do_script_scriptsmenu(void *arg, int event)
switch(event) {
case 0: /* update menus */
BPyMenu_RemoveAllEntries();
+ BPY_rebuild_syspath();
if (BPyMenu_Init(1) == -1) error("Invalid scripts dir: check console");
break;
}
diff --git a/source/blender/src/header_seq.c b/source/blender/src/header_seq.c
index e3bffc550b5..207b2c3873d 100644
--- a/source/blender/src/header_seq.c
+++ b/source/blender/src/header_seq.c
@@ -63,7 +63,7 @@
#include "BSE_drawipo.h"
#include "BSE_headerbuttons.h"
#include "BSE_sequence.h"
-
+#include "BSE_time.h"
#include "blendef.h"
#include "mydevice.h"
@@ -115,10 +115,22 @@ static uiBlock *seq_viewmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "seq_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_seq_viewmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation|Alt A", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ if (sseq->mainb == 0) {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Play Back Animation "
+ "in all Sequence Areas|Alt A", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ } else {
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Play Back Animation "
+ "in this window|Alt A", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ }
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Play Back Animation in all "
+ "3D Views and Sequence Areas|Alt Shift A",
+ 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -126,12 +138,12 @@ static uiBlock *seq_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View Selected|NumPad .", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
+
/* Lock Time */
uiDefIconTextBut(block, BUTM, 1, (G.v2d->flag & V2D_VIEWLOCK)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
"Lock Time to Other Windows|", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
-
+
/* Draw time or frames.*/
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -167,6 +179,24 @@ static void do_seq_selectmenu(void *arg, int event)
case 1:
swap_select_seq();
break;
+ case 2:
+ select_dir_from_last(1);
+ break;
+ case 3:
+ select_dir_from_last(2);
+ break;
+ case 4:
+ select_surround_from_last();
+ break;
+ case 5:
+ select_neighbor_from_last(1);
+ break;
+ case 6:
+ select_neighbor_from_last(2);
+ break;
+ case 7:
+ select_linked_seq(2);
+ break;
}
}
@@ -177,9 +207,17 @@ static uiBlock *seq_selectmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "seq_selectmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_seq_selectmenu, NULL);
-
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Strips to the Left", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Strips to the Right", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Surrounding Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Left Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Right Handles", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
if(curarea->headertype==HEADERTOP) {
@@ -355,8 +393,7 @@ static void do_seq_editmenu(void *arg, int event)
case 3: /* Separate Meta Strip */
un_meta();
break;
- case 4: /* Properties... */
- add_blockhandler(curarea, SEQ_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
+ case 4: /* former Properties... */
break;
case 5: /* Duplicate */
add_duplicate_seq();
@@ -364,6 +401,9 @@ static void do_seq_editmenu(void *arg, int event)
case 6: /* Delete */
del_seq();
break;
+ case 7: /* Grab/Extend */
+ transform_seq('e', 0);
+ break;
case 8:
set_filter_seq();
break;
@@ -385,6 +425,27 @@ static void do_seq_editmenu(void *arg, int event)
case 14:
reassign_inputs_seq_effect();
break;
+ case 15:
+ seq_remap_paths();
+ break;
+ case 16:
+ seq_separate_images();
+ break;
+ case 17:
+ reload_sequence();
+ break;
+ case 18:
+ seq_lock_sel(1);
+ break;
+ case 19:
+ seq_lock_sel(0);
+ break;
+ case 20:
+ seq_mute_sel(1);
+ break;
+ case 21:
+ seq_mute_sel(0);
+ break;
}
}
@@ -400,14 +461,14 @@ static uiBlock *seq_editmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "seq_editmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_seq_editmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Strip Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
-
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Snap to Current Frame|Shift S, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cut at Current Frame|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Separate Images to Strips|Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -423,12 +484,18 @@ static uiBlock *seq_editmenu(void *arg_unused)
}
else if(last_seq->type == SEQ_IMAGE) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Image...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
else uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Scene...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+
+ if(last_seq->type==SEQ_IMAGE)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remap Paths...|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
+
}
-/* if (last_seq != NULL && last_seq->type == SEQ_MOVIE) {
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Filter Y|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
+ if (last_seq != NULL && last_seq->type == SEQ_MOVIE) {
+/* uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Filter Y|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); */
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remap Paths...|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
}
-*/
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Meta Strip...|M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
@@ -444,6 +511,14 @@ static uiBlock *seq_editmenu(void *arg_unused)
}
}
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reload Strip Data...|Alt R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 17, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Lock Strips...|Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 18, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unlock Strips...|Alt-Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mute Strips...|H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unmute Strips...|Alt H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 21, "");
+
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
@@ -458,6 +533,78 @@ static uiBlock *seq_editmenu(void *arg_unused)
return block;
}
+static void do_seq_markermenu(void *arg, int event)
+{
+ SpaceSeq *sseq= curarea->spacedata.first;
+
+ switch(event)
+ {
+ case 1:
+ add_marker(CFRA);
+ break;
+ case 2:
+ duplicate_marker();
+ break;
+ case 3:
+ remove_marker();
+ break;
+ case 4:
+ rename_marker();
+ break;
+ case 5:
+ transform_markers('g', 0);
+ break;
+ case 6:
+ sseq->flag ^= SEQ_MARKER_TRANS;
+ break;
+
+ }
+
+ allqueue(REDRAWMARKER, 0);
+}
+
+static uiBlock *seq_markermenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ SpaceSeq *sseq= curarea->spacedata.first;
+
+ block= uiNewBlock(&curarea->uiblocks, "ipo_markermenu",
+ UI_EMBOSSP, UI_HELV, curarea->headwin);
+ uiBlockSetButmFunc(block, do_seq_markermenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Marker|Ctrl Alt M", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate Marker|Ctrl Shift D", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete Marker", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "(Re)Name Marker|Ctrl M", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move Marker|Ctrl G", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, (sseq->flag & SEQ_MARKER_TRANS)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
+ "Transform Markers", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+
+ if(curarea->headertype==HEADERTOP) {
+ uiBlockSetDirection(block, UI_DOWN);
+ } else {
+ uiBlockSetDirection(block, UI_TOP);
+ uiBlockFlipOrder(block);
+ }
+
+ uiTextBoundsBlock(block, 50);
+
+ return block;
+}
void do_seq_buttons(short event)
{
@@ -528,18 +675,23 @@ void seq_buttons()
xmax= GetButStringLength("View");
uiDefPulldownBut(block,seq_viewmenu, NULL, "View", xco, -2, xmax-3, 24, "");
xco+=xmax;
+ if (sseq->mainb == 0) {
+ xmax= GetButStringLength("Select");
+ uiDefPulldownBut(block,seq_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
+ xco+=xmax;
+
+ xmax= GetButStringLength("Marker");
+ uiDefPulldownBut(block,seq_markermenu, NULL, "Marker", xco, -2, xmax-3, 24, "");
+ xco+=xmax;
+
+ xmax= GetButStringLength("Add");
+ uiDefPulldownBut(block, seq_addmenu, NULL, "Add", xco, -2, xmax-3, 24, "");
+ xco+= xmax;
- xmax= GetButStringLength("Select");
- uiDefPulldownBut(block,seq_selectmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
- xco+=xmax;
-
- xmax= GetButStringLength("Add");
- uiDefPulldownBut(block, seq_addmenu, NULL, "Add", xco, -2, xmax-3, 24, "");
- xco+= xmax;
-
- xmax= GetButStringLength("Strip");
- uiDefPulldownBut(block, seq_editmenu, NULL, "Strip", xco, -2, xmax-3, 24, "");
- xco+= xmax;
+ xmax= GetButStringLength("Strip");
+ uiDefPulldownBut(block, seq_editmenu, NULL, "Strip", xco, -2, xmax-3, 24, "");
+ xco+= xmax;
+ }
/* end of pull down menus */
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -551,40 +703,78 @@ void seq_buttons()
"|Sequence %x0"
"|Image Preview %x1"
"|Luma Waveform %x2"
- "|Chroma Vectorscope %x3",
+ "|Chroma Vectorscope %x3"
+ "|Histogram %x4",
xco,0,XIC+10,YIC, &sseq->mainb, 0.0, 3.0,
0, 0,
"Shows the sequence output image preview");
xco+= 8 + XIC+10;
- /* CHANNEL shown in 3D preview */
if(sseq->mainb) {
int minchan = 0;
+ /* CHANNEL shown in image preview */
+
if (G.scene->ed && ((Editing*)G.scene->ed)->metastack.first)
minchan = -BLI_countlist(&((Editing*)G.scene->ed)->metastack);
uiDefButS(block, NUM, B_REDR, "Chan:",
- xco, 0, 3.5 * XIC,YIC,
- &sseq->chanshown, minchan, MAXSEQ, 0, 0,
- "The channel number shown in the image preview. 0 is the result of all strips combined.");
+ xco, 0, 3.5 * XIC,YIC,
+ &sseq->chanshown, minchan, MAXSEQ, 0, 0,
+ "The channel number shown in the image preview. 0 is the result of all strips combined.");
xco+= 8 + XIC*3.5;
- }
-
-
- /* ZOOM and BORDER */
- xco+= 8;
- uiBlockBeginAlign(block);
- uiDefIconButI(block, TOG, B_VIEW2DZOOM, ICON_VIEWZOOM, xco,0,XIC,YIC, &viewmovetemp, 0, 0, 0, 0, "Zooms view in and out (Ctrl MiddleMouse)");
- uiDefIconBut(block, BUT, B_IPOBORDER, ICON_BORDERMOVE, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms view to fit area");
- uiBlockEndAlign(block);
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
+ uiDefButS(block, MENU, B_REDR,
+ "Show zebra: %t"
+ "|Z 110 %x110"
+ "|Z 100 %x100"
+ "|Z 95 %x95"
+ "|Z 90 %x90"
+ "|Z 70 %x70"
+ "|Z Off %x0",
+ xco,0,3.0 * XIC, YIC, &sseq->zebra,
+ 0,0,0,0,
+ "Show overexposed "
+ "areas with zebra stripes");
+
+ xco+= 8 + XIC*3.0;
+
+ uiDefButBitI(block, TOG, SEQ_DRAW_SAFE_MARGINS,
+ B_REDR, "T",
+ xco,0,XIC,YIC, &sseq->flag,
+ 0, 0, 0, 0,
+ "Draw title safe margins in preview");
+ xco+= 8 + XIC;
+ }
+
+ if (sseq->mainb == SEQ_DRAW_IMG_WAVEFORM) {
+ uiDefButBitI(block, TOG, SEQ_DRAW_COLOR_SEPERATED,
+ B_REDR, "CS",
+ xco,0,XIC,YIC, &sseq->flag,
+ 0, 0, 0, 0,
+ "Seperate color channels in preview");
+ xco+= 8 + XIC;
+ }
+ } else {
+ /* ZOOM and BORDER */
+ uiDefIconButI(block, TOG, B_VIEW2DZOOM,
+ ICON_VIEWZOOM,
+ xco,0,XIC,YIC, &viewmovetemp,
+ 0, 0, 0, 0,
+ "Zooms view in and out (Ctrl MiddleMouse)");
+ xco += XIC;
+ uiDefIconBut(block, BUT, B_IPOBORDER,
+ ICON_BORDERMOVE,
+ xco,0,XIC,YIC, 0,
+ 0, 0, 0, 0,
+ "Zooms view to fit area");
+ xco += 8 + XIC;
+ }
- /* CLEAR MEM */
- xco+= 8;
- uiDefBut(block, BUT, B_SEQCLEAR, "Refresh", xco+=XIC,0,3*XIC,YIC, 0, 0, 0, 0, 0, "Clears all buffered images in memory");
+ uiDefBut(block, BUT, B_SEQCLEAR, "Refresh", xco,0,3*XIC,YIC, 0, 0, 0, 0, 0, "Clears all buffered images in memory");
uiDrawBlock(block);
}
diff --git a/source/blender/src/header_sound.c b/source/blender/src/header_sound.c
index 55c14f1a0aa..c2fb72d7d17 100644
--- a/source/blender/src/header_sound.c
+++ b/source/blender/src/header_sound.c
@@ -269,11 +269,7 @@ static void do_sound_markermenu(void *arg, int event)
break;
}
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
static uiBlock *sound_markermenu(void *arg_unused)
diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c
index 92a5a49a681..9ee7896d65e 100644
--- a/source/blender/src/header_text.c
+++ b/source/blender/src/header_text.c
@@ -52,6 +52,8 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_text_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_action_types.h"
#include "BIF_drawtext.h"
#include "BIF_interface.h"
@@ -59,11 +61,14 @@
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
+
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_sca.h"
#include "BKE_text.h"
+#include "BKE_depsgraph.h"
+
#include "BSE_filesel.h"
#include "BPY_extern.h"
@@ -74,13 +79,12 @@
void do_text_buttons(unsigned short event)
{
- SpaceText *st= curarea->spacedata.first;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
ID *id, *idtest;
int nr= 1;
Text *text;
-
- if (!st) return;
- if (st->spacetype != SPACE_TEXT) return;
+
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
switch (event) {
case B_TEXTBROWSE:
@@ -127,7 +131,7 @@ void do_text_buttons(unsigned short event)
st->top= 0;
pop_space_text(st);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
allqueue(REDRAWTEXT, 0);
allqueue(REDRAWHEADERS, 0);
}
@@ -135,27 +139,36 @@ void do_text_buttons(unsigned short event)
break;
case B_TEXTDELETE:
-
- text= st->text;
- if (!text) return;
-
- /* make the previous text active, if its not there make the next text active */
- if (st->text->id.prev) {
- st->text = st->text->id.prev;
- pop_space_text(st);
- } else if (st->text->id.next) {
- st->text = st->text->id.next;
- pop_space_text(st);
- }
+ {
+ text= st->text;
+ if (!text) return;
- BPY_clear_bad_scriptlinks(text);
- free_text_controllers(text);
-
- unlink_text(text);
- free_libblock(&G.main->text, text);
-
- allqueue(REDRAWTEXT, 0);
- allqueue(REDRAWHEADERS, 0);
+ /* make the previous text active, if its not there make the next text active */
+ if (st->text->id.prev) {
+ st->text = st->text->id.prev;
+ pop_space_text(st);
+ } else if (st->text->id.next) {
+ st->text = st->text->id.next;
+ pop_space_text(st);
+ }
+
+ BPY_clear_bad_scriptlinks(text);
+ BPY_free_pyconstraint_links(text);
+ free_text_controllers(text);
+
+ unlink_text(text);
+ free_libblock(&G.main->text, text);
+
+ allqueue(REDRAWTEXT, 0);
+ allqueue(REDRAWHEADERS, 0);
+
+ /*for if any object constraints were changed.*/
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+
+ BIF_undo_push("Delete Text");
+ }
break;
/*
@@ -184,13 +197,13 @@ void do_text_buttons(unsigned short event)
break;
case B_TAB_NUMBERS:
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
allqueue(REDRAWTEXT, 0);
allqueue(REDRAWHEADERS, 0);
break;
case B_SYNTAX:
if (st->showsyntax) {
- get_format_string();
+ get_format_string(st);
}
allqueue(REDRAWTEXT, 0);
allqueue(REDRAWHEADERS, 0);
@@ -232,15 +245,19 @@ static uiBlock *text_template_scriptsmenu (void *args_unused)
/* action executed after clicking in File menu */
static void do_text_filemenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
ScrArea *sa;
-
+
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text= st->text;
+
switch(event) {
case 1:
st->text= add_empty_text( "Text" );
st->top=0;
-
+
allqueue(REDRAWTEXT, 0);
allqueue(REDRAWHEADERS, 0);
break;
@@ -254,7 +271,7 @@ static void do_text_filemenu(void *arg, int event)
if (!reopen_text(text)) {
error("Could not reopen file");
}
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
}
break;
case 5:
@@ -265,6 +282,42 @@ static void do_text_filemenu(void *arg, int event)
case 6:
run_python_script(st);
break;
+ case 7:
+ {
+ Object *ob;
+ bConstraint *con;
+ short update;
+
+ /* check all pyconstraints */
+ for (ob= G.main->object.first; ob; ob= ob->id.next) {
+ update = 0;
+ if (ob->type==OB_ARMATURE && ob->pose) {
+ bPoseChannel *pchan;
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (con = pchan->constraints.first; con; con= con->next) {
+ if (con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) BPY_pyconstraint_update(ob, con);
+ update = 1;
+
+ }
+ }
+ }
+ }
+ for (con = ob->constraints.first; con; con= con->next) {
+ if (con->type==CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = con->data;
+ if (data->text==text) BPY_pyconstraint_update(ob, con);
+ update = 1;
+ }
+ }
+
+ if (update) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ }
+ break;
default:
break;
}
@@ -279,10 +332,14 @@ static void do_text_filemenu(void *arg, int event)
/* action executed after clicking in Edit menu */
static void do_text_editmenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
ScrArea *sa;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text= st->text;
+
switch(event) {
case 1:
txt_do_undo(text);
@@ -291,15 +348,17 @@ static void do_text_editmenu(void *arg, int event)
txt_do_redo(text);
break;
case 3:
+ txt_copy_clipboard(text);
txt_cut_sel(text);
pop_space_text(st);
break;
case 4:
- txt_copy_sel(text);
+ //txt_copy_sel(text);
+ txt_copy_clipboard(text);
break;
case 5:
- txt_paste(text);
- if (st->showsyntax) get_format_string();
+ txt_paste_clipboard(text);
+ if (st->showsyntax) get_format_string(st);
break;
case 6:
txt_print_cutbuffer();
@@ -328,10 +387,14 @@ static void do_text_editmenu(void *arg, int event)
/* action executed after clicking in View menu */
static void do_text_editmenu_viewmenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
ScrArea *sa;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text = st->text;
+
switch(event) {
case 1:
txt_move_bof(text, 0);
@@ -356,10 +419,14 @@ static void do_text_editmenu_viewmenu(void *arg, int event)
/* action executed after clicking in Select menu */
static void do_text_editmenu_selectmenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
ScrArea *sa;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text = st->text;
+
switch(event) {
case 1:
txt_sel_all(text);
@@ -382,10 +449,14 @@ static void do_text_editmenu_selectmenu(void *arg, int event)
/* action executed after clicking in Format menu */
static void do_text_formatmenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
ScrArea *sa;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text = st->text;
+
switch(event) {
case 3:
if (txt_has_sel(text)) {
@@ -408,7 +479,7 @@ static void do_text_formatmenu(void *arg, int event)
if ( txt_has_sel(text)) {
txt_order_cursors(text);
comment(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
break;
}
break;
@@ -416,7 +487,7 @@ static void do_text_formatmenu(void *arg, int event)
if ( txt_has_sel(text)) {
txt_order_cursors(text);
uncomment(text);
- if (st->showsyntax) get_format_string();
+ if (st->showsyntax) get_format_string(st);
break;
}
break;
@@ -470,7 +541,9 @@ static uiBlock *text_editmenu_selectmenu(void *arg_unused)
void do_text_formatmenu_convert(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
switch(event) {
case 1: convert_tabs(st, 0); break;
@@ -529,8 +602,11 @@ static uiBlock *text_formatmenu(void *arg_unused)
/* action executed after clicking in Object to 3d Sub Menu */
void do_text_editmenu_to3dmenu(void *arg, int event)
{
- SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
+ Text *text;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text = st->text;
switch(event) {
case 1: txt_export_to_object(text); break;
@@ -598,7 +674,7 @@ static uiBlock *text_editmenu(void *arg_unused)
/* File menu */
static uiBlock *text_filemenu(void *arg_unused)
{
- SpaceText *st= curarea->spacedata.first;
+ SpaceText *st= curarea->spacedata.first; /* bad but cant pass as an arg here */
Text *text= st->text;
uiBlock *block;
short yco= 0, menuwidth=120;
@@ -608,13 +684,23 @@ static uiBlock *text_filemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "New|Alt N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Open...|Alt O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+
if(text) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reopen|Alt R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Save As...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Run Python Script|Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+
+ if (BPY_is_pyconstraint(text))
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Refresh All PyConstraints", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
}
uiDefIconTextBlockBut(block, text_template_scriptsmenu, NULL, ICON_RIGHTARROW_THIN, "Script Templates", 0, yco-=20, 120, 19, "");
@@ -636,11 +722,13 @@ void text_buttons(void)
{
uiBlock *block;
SpaceText *st= curarea->spacedata.first;
- Text *text= st->text;
+ Text *text;
short xco, xmax;
char naam[256];
- if (!st || st->spacetype != SPACE_TEXT) return;
+ if (st==NULL || st->spacetype != SPACE_TEXT) return;
+
+ text = st->text;
sprintf(naam, "header %d", curarea->headwin);
block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->headwin);
diff --git a/source/blender/src/header_time.c b/source/blender/src/header_time.c
index 00ce8987d27..7b98d2f5f4c 100644
--- a/source/blender/src/header_time.c
+++ b/source/blender/src/header_time.c
@@ -136,7 +136,7 @@ static void do_time_redrawmenu(void *arg, int event)
}
else {
if(event==1001) {
- button(&G.scene->r.frs_sec,1,120,"Frames/Second:");
+ button(&G.scene->r.frs_sec,1,120,"FPS:");
}
}
}
@@ -180,7 +180,7 @@ static uiBlock *time_redrawmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- sprintf(str, "Set Frames/Sec (%d)", G.scene->r.frs_sec);
+ sprintf(str, "Set Frames/Sec (%d/%f)", G.scene->r.frs_sec, G.scene->r.frs_sec_base);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, str, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1001, "");
@@ -241,6 +241,9 @@ static void do_time_viewmenu(void *arg, int event)
if(G.v2d->flag & V2D_VIEWLOCK)
view2d_do_locks(curarea, 0);
break;
+ case 12: /* only show keyframes from selected data */
+ stime->flag ^= TIME_ONLYACTSEL;
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -265,6 +268,9 @@ static uiBlock *time_viewmenu(void *arg_unused)
else
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Frames|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, (stime->flag & TIME_ONLYACTSEL)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
+ "Only Selected Data Keys|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Jump To Next Marker|PageUp", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
@@ -463,27 +469,27 @@ void time_buttons(ScrArea *sa)
uiDefButI(block, NUM, REDRAWALL,"Start:",
xco,0, 4.5*XIC, YIC,
&G.scene->r.psfra,MINFRAMEF, MAXFRAMEF, 0, 0,
- "The start frame of the animation preview");
+ "The start frame of the animation preview (inclusive)");
xco += 4.5*XIC;
uiDefButI(block, NUM, REDRAWALL,"End:",
xco,0,4.5*XIC,YIC,
&G.scene->r.pefra,PSFRA,MAXFRAMEF, 0, 0,
- "The end frame of the animation preview");
+ "The end frame of the animation preview (inclusive)");
}
else {
uiDefButI(block, NUM, REDRAWALL,"Start:",
xco,0, 4.5*XIC, YIC,
&G.scene->r.sfra,MINFRAMEF, MAXFRAMEF, 0, 0,
- "The start frame of the animation");
+ "The start frame of the animation (inclusive)");
xco += 4.5*XIC;
uiDefButI(block, NUM, REDRAWALL,"End:",
xco,0,4.5*XIC,YIC,
&G.scene->r.efra,SFRA,MAXFRAMEF, 0, 0,
- "The end frame of the animation");
+ "The end frame of the animation (inclusive)");
}
uiBlockEndAlign(block);
@@ -492,7 +498,7 @@ void time_buttons(ScrArea *sa)
uiDefButI(block, NUM, B_NEWFRAME, "",
xco,0,3.5*XIC,YIC,
&(G.scene->r.cfra), MINFRAMEF, MAXFRAMEF, 0, 0,
- "Displays Current Frame of animation. Click to change.");
+ "Displays Current Frame of animation");
xco += 3.5*XIC+16;
@@ -518,10 +524,18 @@ void time_buttons(ScrArea *sa)
xco, 0, XIC, YIC, 0, 0, 0, 0, 0, "Skip to End frame (Shift UpArrow)");
xco+= XIC+8;
- uiDefIconButBitI(block, TOG, G_RECORDKEYS, REDRAWINFO, ICON_REC,
- xco, 0, XIC, YIC, &(G.flags), 0, 0, 0, 0, "Automatically insert keyframes in Object and Action Ipo curves");
+ uiDefIconButBitS(block, TOG, AUTOKEY_ON, REDRAWINFO, ICON_REC,
+ xco, 0, XIC, YIC, &(U.autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
+ xco+= XIC;
+ if (IS_AUTOKEY_ON) {
+ uiDefButS(block, MENU, REDRAWINFO,
+ "Auto-Keying Mode %t|Add/Replace Keys%x3|Replace Keys %x5",
+ xco, 0, 3*XIC, YIC, &(U.autokey_mode), 0, 1, 0, 0,
+ "Mode of automatic keyframe insertion for Objects and Bones");
+ xco+= (4*XIC);
+ }
- xco+= XIC+16;
+ xco+= 16;
uiDefIconButBitI(block, TOG, TIME_WITH_SEQ_AUDIO, B_DIFF, ICON_SPEAKER,
xco, 0, XIC, YIC, &(stime->redraws), 0, 0, 0, 0, "Play back and sync with audio from Sequence Editor");
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index b5c784aa18a..d738cd5eb72 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -71,6 +71,8 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h" /* for VECCOPY */
#ifdef WITH_VERSE
@@ -97,6 +99,7 @@
#include "BIF_editlattice.h"
#include "BIF_editarmature.h"
+#include "BIF_editparticle.h"
#include "BIF_editconstraint.h"
#include "BIF_editdeform.h"
#include "BIF_editfont.h"
@@ -108,7 +111,9 @@
#include "BIF_interface.h"
#include "BIF_mainqueue.h"
#include "BIF_meshtools.h"
+#include "BIF_poselib.h"
#include "BIF_poseobject.h"
+#include "BIF_radialcontrol.h"
#include "BIF_renderwin.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
@@ -144,17 +149,16 @@
#define V3D_OBJECTMODE_SEL ICON_OBJECT
#define V3D_EDITMODE_SEL ICON_EDITMODE_HLT
#define V3D_SCULPTMODE_SEL ICON_SCULPTMODE_HLT
-#define V3D_FACESELECTMODE_SEL ICON_FACESEL_HLT
+#define V3D_FACESELECT_SEL ICON_FACESEL_HLT /* this is not a mode anymore - just a switch */
#define V3D_VERTEXPAINTMODE_SEL ICON_VPAINT_HLT
#define V3D_TEXTUREPAINTMODE_SEL ICON_TPAINT_HLT
#define V3D_WEIGHTPAINTMODE_SEL ICON_WPAINT_HLT
#define V3D_POSEMODE_SEL ICON_POSE_HLT
+#define V3D_PARTICLEEDITMODE_SEL ICON_ANIM
#define TEST_EDITMESH if(G.obedit==0) return; \
if( (G.vd->lay & G.obedit->lay)==0 ) return;
-static int viewmovetemp = 0;
-
void do_layer_buttons(short event)
{
static int oldlay= 1;
@@ -386,7 +390,7 @@ static void do_view3d_view_alignviewmenu(void *arg, int event)
case 2:
if ((G.obedit) && (G.obedit->type == OB_MESH)) {
editmesh_align_view_to_selected(v3d, event);
- } else if (G.f & G_FACESELECT) {
+ } else if (FACESEL_PAINT_TEST) {
Object *obact= OBACT;
if (obact && obact->type==OB_MESH) {
Mesh *me= obact->data;
@@ -438,7 +442,7 @@ static uiBlock *view3d_view_alignviewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center Cursor and View All|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align Active Camera to View|Ctrl Alt NumPad 0", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
- if (((G.obedit) && (G.obedit->type == OB_MESH)) || (G.f & G_FACESELECT)) {
+ if (((G.obedit) && (G.obedit->type == OB_MESH)) || (FACESEL_PAINT_TEST)) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align View to Selected (Top)|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align View to Selected (Front)|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align View to Selected (Side)|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
@@ -595,6 +599,12 @@ static void do_view3d_viewmenu(void *arg, int event)
case 18: /* render preview */
toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
break;
+ case 19: /* zoom within border */
+ view3d_border_zoom();
+ break;
+ case 20: /* Transform Space Panel */
+ add_blockhandler(curarea, VIEW3D_HANDLER_TRANSFORM, UI_PNL_UNSTOW);
+ break;
}
allqueue(REDRAWVIEW3D, 1);
}
@@ -608,6 +618,7 @@ static uiBlock *view3d_viewmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_viewmenu, NULL);
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Orientations...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 20, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Render Preview...|Shift P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 16, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Background Image...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
@@ -652,6 +663,7 @@ static uiBlock *view3d_viewmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Clipping Border|Alt B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 17, "");
else
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Clipping Border|Alt B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 17, "");
+ if (v3d->persp==0) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Zoom Within Border...|Shift B", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 19, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View Selected|NumPad .", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "View All|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
if(!curarea->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 99, "");
@@ -859,6 +871,7 @@ void do_view3d_select_object_groupedmenu(void *arg, int event)
case 6: /* Objects on Shared Layers */
case 7: /* Objects in Same Group */
case 8: /* Object Hooks*/
+ case 9: /* Object PassIndex*/
select_object_grouped((short)event);
break;
}
@@ -881,7 +894,8 @@ static uiBlock *view3d_select_object_groupedmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Objects on Shared Layers|Shift G, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Objects in Same Group|Shift G, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Hooks|Shift G, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
-
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object PassIndex|Shift G, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
@@ -900,6 +914,9 @@ void do_view3d_select_objectmenu(void *arg, int event)
case 2: /* inverse */
selectswap();
break;
+ case 3: /* random */
+ selectrandom();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -918,6 +935,8 @@ static uiBlock *view3d_select_objectmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+
uiDefIconTextBlockBut(block, view3d_select_object_layermenu, NULL, ICON_RIGHTARROW_THIN, "Select All by Layer", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_select_object_typemenu, NULL, ICON_RIGHTARROW_THIN, "Select All by Type", 0, yco-=20, 120, 19, "");
@@ -954,7 +973,7 @@ void do_view3d_select_meshmenu(void *arg, int event)
selectswap_mesh();
break;
case 4: /* select linked vertices */
- selectconnected_mesh(LR_CTRLKEY);
+ selectconnected_mesh_all();
break;
case 5: /* select random */
selectrandom_mesh();
@@ -1021,7 +1040,7 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1034,7 +1053,7 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused)
"Sharp Edges|Ctrl Alt Shift S",
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Linked flat faces|Ctrl Alt Shift F",
+ "Linked Flat Faces|Ctrl Alt Shift F",
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
@@ -1050,7 +1069,7 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused)
"Non-Triangles/Quads|Ctrl Alt Shift 5",
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Group From Selection|Shift G",
+ "Similar to Selection...|Shift G",
0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
@@ -1104,17 +1123,17 @@ void do_view3d_select_curvemenu(void *arg, int event)
/* select connected control points */
/*case 4:
G.qual |= LR_CTRLKEY;
- selectconnected_nurb();
+ select_connected_nurb();
G.qual &= ~LR_CTRLKEY;
break;*/
case 5: /* select row (nurb) */
selectrow_nurb();
break;
case 7: /* select/deselect first */
- selectends_nurb(1);
+ selectend_nurb(FIRST, 1, DESELECT);
break;
case 8: /* select/deselect last */
- selectends_nurb(0);
+ selectend_nurb(LAST, 1, DESELECT);
break;
case 9: /* select more */
select_more_nurb();
@@ -1128,6 +1147,12 @@ void do_view3d_select_curvemenu(void *arg, int event)
case 12: /* select previous */
select_prev_nurb();
break;
+ case 13: /* select random */
+ select_random_nurb();
+ break;
+ case 14: /* select every nth */
+ select_every_nth_nurb();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1147,6 +1172,8 @@ static uiBlock *view3d_select_curvemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Every Nth", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
if (OBACT->type == OB_SURF) {
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1181,7 +1208,7 @@ static uiBlock *view3d_select_curvemenu(void *arg_unused)
return block;
}
-static void do_view3d_select_metaballmenu(void *arg, int event)
+void do_view3d_select_metaballmenu(void *arg, int event)
{
switch(event) {
@@ -1191,6 +1218,12 @@ static void do_view3d_select_metaballmenu(void *arg, int event)
case 2: /* Select/Deselect all */
deselectall_mball();
break;
+ case 3: /* Inverse */
+ selectinverse_mball();
+ break;
+ case 4: /* Select Random */
+ selectrandom_mball();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1209,7 +1242,13 @@ static uiBlock *view3d_select_metaballmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
@@ -1373,10 +1412,7 @@ void do_view3d_select_faceselmenu(void *arg, int event)
case 3: /* Select Inverse */
selectswap_tface();
break;
- case 4: /* Select Same UV */
- get_same_uv();
- break;
- case 5: /* Select Linked */
+ case 4: /* Select Linked */
select_linked_tfaces(2);
break;
}
@@ -1399,10 +1435,9 @@ static uiBlock *view3d_select_faceselmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same UV", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked Faces|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Linked Faces|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1427,21 +1462,28 @@ static uiBlock *view3d_select_faceselmenu(void *arg_unused)
void do_view3d_edit_snapmenu(void *arg, int event)
{
- switch(event) {
- case 1: /* Selection to grid */
+ switch (event) {
+ case 1: /*Selection to grid*/
snap_sel_to_grid();
+ BIF_undo_push("Snap selection to grid");
break;
- case 2: /* Selection to cursor */
+ case 2: /*Selection to cursor*/
snap_sel_to_curs();
- break;
- case 3: /* Cursor to grid */
- snap_curs_to_grid();
+ BIF_undo_push("Snap selection to cursor");
+ break;
+ case 3: /*Selection to center of selection*/
+ snap_to_center();
+ BIF_undo_push("Snap selection to center");
break;
- case 4: /* Cursor to selection */
+ case 4: /*Cursor to selection*/
snap_curs_to_sel();
break;
- case 5: /* Selection to center of selection*/
- snap_to_center();
+ case 5: /*Cursor to grid*/
+ snap_curs_to_grid();
+ break;
+ case 6: /*Cursor to Active*/
+ snap_curs_to_active();
+ BIF_undo_push("Snap selection to center");
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1457,9 +1499,12 @@ static uiBlock *view3d_edit_snapmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selection -> Grid|Shift S, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selection -> Cursor|Shift S, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cursor -> Grid|Shift S, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selection -> Center|Shift S, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cursor -> Selection|Shift S, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Selection -> Center|Shift S, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cursor -> Grid|Shift S, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Cursor -> Active|Shift S, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+
uiBlockSetDirection(block, UI_RIGHT);
@@ -1724,19 +1769,26 @@ static void do_view3d_transformmenu(void *arg, int event)
Transform();
break;
case 15:
- G.vd->flag2 &= ~V3D_TRANSFORM_SNAP;
+ G.scene->snap_flag &= ~SCE_SNAP;
break;
case 16:
- G.vd->flag2 |= V3D_TRANSFORM_SNAP;
+ G.scene->snap_flag |= SCE_SNAP;
break;
case 17:
- G.vd->snap_target = V3D_SNAP_TARGET_CLOSEST;
+ G.scene->snap_target = SCE_SNAP_TARGET_CLOSEST;
break;
case 18:
- G.vd->snap_target = V3D_SNAP_TARGET_CENTER;
+ G.scene->snap_target = SCE_SNAP_TARGET_CENTER;
break;
case 19:
- G.vd->snap_target = V3D_SNAP_TARGET_MEDIAN;
+ G.scene->snap_target = SCE_SNAP_TARGET_MEDIAN;
+ break;
+ case 20:
+ G.scene->snap_target = SCE_SNAP_TARGET_ACTIVE;
+ break;
+ case 21:
+ initTransform(TFM_ALIGN, CTX_NO_PET|CTX_AUTOCONFIRM);
+ Transform();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1787,13 +1839,14 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
if (!G.obedit) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center New", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center Cursor", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Align to Transform Orientation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, "");
}
- if (G.obedit != NULL && G.obedit->type==OB_MESH)
+ if (BIF_snappingSupported())
{
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
+ if (G.scene->snap_flag & SCE_SNAP)
{
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Grid", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
@@ -1806,22 +1859,31 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- switch(G.vd->snap_target)
+ switch(G.scene->snap_target)
{
- case V3D_SNAP_TARGET_CLOSEST:
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ case SCE_SNAP_TARGET_CLOSEST:
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
- case V3D_SNAP_TARGET_CENTER:
+ case SCE_SNAP_TARGET_CENTER:
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
- case V3D_SNAP_TARGET_MEDIAN:
+ case SCE_SNAP_TARGET_MEDIAN:
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
+ break;
+ case SCE_SNAP_TARGET_ACTIVE:
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
}
}
@@ -1834,10 +1896,24 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
void do_view3d_object_mirrormenu(void *arg, int event)
{
switch(event) {
+ case 0:
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
+ break;
case 1:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('X', " on X axis");
+ Transform();
+ break;
case 2:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Y', " on Y axis");
+ Transform();
+ break;
case 3:
- Mirror(event + 3); /* + 3 because the first three modes are global*/
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Z', " on Z axis");
+ Transform();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1851,9 +1927,11 @@ static uiBlock *view3d_object_mirrormenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_object_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_object_mirrormenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -1882,7 +1960,10 @@ static void do_view3d_edit_object_transformmenu(void *arg, int event)
make_duplilist_real();
break;
case 6: /* apply scale/rotation or deformation */
- apply_object();
+ apply_objects_locrot();
+ break;
+ case 7: /* apply visual matrix to objects loc/size/rot */
+ apply_objects_visual_tx();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1896,7 +1977,8 @@ static uiBlock *view3d_edit_object_transformmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_object_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_edit_object_transformmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotation|Ctrl A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotationr to ObData|Ctrl A, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Visual Transform|Ctrl A, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Deformation|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Duplicates Real|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ -2019,6 +2101,9 @@ static void do_view3d_edit_object_singleusermenu(void *arg, int event)
case 4: /* Materials+Tex */
single_mat_users(1);
break;
+ case 5: /* Ipo */
+ single_ipo_users(1);
+ break;
}
clear_id_newpoins();
@@ -2039,7 +2124,8 @@ static uiBlock *view3d_edit_object_singleusermenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object|U, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object & ObData|U, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object & ObData & Materials+Tex|U, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Materials+Tex|U, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Materials+Tex|U, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Ipos|U, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -2071,6 +2157,7 @@ static void do_view3d_edit_object_copyattrmenu(void *arg, int event)
case 25:
case 26:
case 29:
+ case 30:
copy_attr((short)event);
break;
}
@@ -2134,6 +2221,8 @@ static uiBlock *view3d_edit_object_copyattrmenu(void *arg_unused)
if( give_parteff(ob) ) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Particle Settings|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
}
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Pass Index|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 30, "");
}
uiBlockSetDirection(block, UI_RIGHT);
@@ -2326,15 +2415,17 @@ extern ListBase session_list;
static void do_view3d_edit_objectmenu(void *arg, int event)
{
+#ifdef WITH_VERSE
+ struct VerseSession *session=NULL;
+
/* needed to check for valid selected objects */
Base *base=NULL;
Object *ob=NULL;
-#ifdef WITH_VERSE
- struct VerseSession *session=NULL;
-#endif
-
+
base= BASACT;
if (base) ob= base->object;
+#endif
+
switch(event) {
@@ -2512,7 +2603,7 @@ void do_view3d_edit_mesh_verticesmenu(void *arg, int event)
make_parent();
break;
case 1: /* remove doubles */
- count= removedoublesflag(1, G.scene->toolsettings->doublimit);
+ count= removedoublesflag(1, 0, G.scene->toolsettings->doublimit);
notice("Removed: %d", count);
if (count) { /* only undo and redraw if an action is taken */
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
@@ -2533,7 +2624,7 @@ void do_view3d_edit_mesh_verticesmenu(void *arg, int event)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
break;
case 6: /* add hook */
- add_hook();
+ add_hook_menu();
break;
case 7: /* rip */
mesh_rip();
@@ -2570,6 +2661,8 @@ static uiBlock *view3d_edit_mesh_verticesmenu(void *arg_unused)
return block;
}
+extern void editmesh_mark_sharp(int set); /* declared in editmesh_mods.c */
+
void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
{
float fac;
@@ -2610,7 +2703,7 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
case 8: /* Clear Seam */
editmesh_mark_seam(1);
break;
- case 9: /* Cease SubSurf */
+ case 9: /* Crease SubSurf */
if(!multires_level1_test()) {
initTransform(TFM_CREASE, CTX_EDGE);
Transform();
@@ -2632,6 +2725,22 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
collapseEdges();
BIF_undo_push("Collapse");
break;
+ case 15:
+ editmesh_mark_sharp(1);
+ BIF_undo_push("Mark Sharp");
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ break;
+ case 16:
+ editmesh_mark_sharp(0);
+ BIF_undo_push("Clear Sharp");
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+ break;
+ case 17: /* Adjust Bevel Weight */
+ if(!multires_level1_test()) {
+ initTransform(TFM_BWEIGHT, CTX_EDGE);
+ Transform();
+ }
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -2662,6 +2771,14 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Sharp|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Sharp|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Adjust Bevel Weight|Ctrl Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Crease SubSurf|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
@@ -2731,7 +2848,7 @@ static uiBlock *view3d_edit_mesh_facesmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Quads to Triangles|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Triangles to Quads|Alt J", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl Shift F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -2781,17 +2898,44 @@ static uiBlock *view3d_edit_mesh_normalsmenu(void *arg_unused)
void do_view3d_edit_mirrormenu(void *arg, int event)
{
+ float mat[3][3];
+
+ Mat3One(mat);
+
switch(event) {
+ case 0:
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
+ break;
case 1:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[0], " on global X axis");
+ Transform();
+ break;
case 2:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[1], " on global Y axis");
+ Transform();
+ break;
case 3:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[2], "on global Z axis");
+ Transform();
+ break;
case 4:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('X', " on local X axis");
+ Transform();
+ break;
case 5:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Y', " on local Y axis");
+ Transform();
+ break;
case 6:
- case 7:
- case 8:
- case 9:
- Mirror(event);
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Z', " on local Z axis");
+ Transform();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -2805,21 +2949,19 @@ static uiBlock *view3d_edit_mirrormenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_edit_mirrormenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X View|Ctrl M, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y View|Ctrl M, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z View|Ctrl M, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -2936,13 +3078,20 @@ static void do_view3d_edit_meshmenu(void *arg, int event)
if(G.scene->proportional) G.scene->proportional= 0;
else G.scene->proportional= 1;
break;
+ case 13: /* automerge edit (toggle) */
+ if(G.scene->automerge) G.scene->automerge= 0;
+ else G.scene->automerge= 1;
+ break;
#ifdef WITH_VERSE
- case 13:
+ case 14:
if(session_list.first != session_list.last) session = session_menu();
else session = session_list.first;
if(session) b_verse_push_object(session, G.obedit);
break;
#endif
+ case 15:
+ uv_autocalc_tface();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -2959,13 +3108,13 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
#ifdef WITH_VERSE
if((session_list.first != NULL) && (!G.obedit->vnode)) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Share at Verse Server",
- 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
}
#endif
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Editing|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo Editing|Shift U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Editing|Ctrl Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Redo Editing|Ctrl Shift Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBlockBut(block, editmode_undohistorymenu, NULL, ICON_RIGHTARROW_THIN, "Undo History", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -2981,6 +3130,10 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Edge/Face|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
@@ -2995,6 +3148,8 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+
if(G.scene->proportional) {
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
} else {
@@ -3004,6 +3159,14 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ /* PITA but we should let users know that automerge cant work with multires :/ */
+ uiDefIconTextBut(block, BUTM, 1,
+ G.scene->automerge ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT,
+ ((Mesh*)G.obedit->data)->mr ? "AutoMerge Editing (disabled by multires)" : "AutoMerge Editing",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBlockBut(block, view3d_edit_mesh_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Vertices", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -3047,7 +3210,7 @@ static void do_view3d_edit_curve_controlpointsmenu(void *arg, int event)
make_parent();
break;
case 6: /* add hook */
- add_hook();
+ add_hook_menu();
break;
case 7:
separate_nurb();
@@ -3192,6 +3355,9 @@ static void do_view3d_edit_curvemenu(void *arg, int event)
initTransform(TFM_WARP, CTX_NONE);
Transform();
break;
+ case 15:
+ uv_autocalc_tface();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -3219,6 +3385,10 @@ static uiBlock *view3d_edit_curvemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Segment|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
@@ -3312,6 +3482,9 @@ static void do_view3d_edit_metaballmenu(void *arg, int event)
break;
case 7: /* Transform Properties */
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, 0);
+ break;
+ case 8:
+ uv_autocalc_tface();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -3337,6 +3510,10 @@ static uiBlock *view3d_edit_metaballmenu(void *arg_unused)
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete...|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
@@ -3522,6 +3699,9 @@ static void do_view3d_edit_latticemenu(void *arg, int event)
if(G.scene->proportional) G.scene->proportional= 0;
else G.scene->proportional= 1;
break;
+ case 6:
+ uv_autocalc_tface();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -3548,6 +3728,10 @@ static uiBlock *view3d_edit_latticemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "UV Unwrap|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
if(G.scene->proportional) {
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Proportional Editing|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
} else {
@@ -3596,10 +3780,44 @@ static uiBlock *view3d_edit_armature_parentmenu(void *arg_unused)
return block;
}
+void do_view3d_edit_armature_rollmenu(void *arg, int event)
+{
+ if (event == 1 || event == 2)
+ /* set roll based on aligning z-axis */
+ auto_align_armature(event);
+ else if (event == 3) {
+ /* interactively set bone roll */
+ initTransform(TFM_BONE_ROLL, CTX_NONE);
+ Transform();
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_edit_armature_rollmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_edit_armature_rollmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_edit_armature_rollmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Roll (Z-Axis Up)|Ctrl N, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Roll to Cursor|Ctrl N, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Roll|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
static void do_view3d_edit_armaturemenu(void *arg, int event)
{
+ static short numcuts= 2;
+
switch(event) {
-
case 0: /* Undo Editing */
remake_editArmature();
break;
@@ -3625,19 +3843,34 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
case 10: /* forked! */
extrude_armature(1);
break;
- case 11: /* clear roll */
- auto_align_armature();
- break;
case 12: /* subdivide */
- subdivide_armature();
+ subdivide_armature(1);
break;
case 13: /* flip left and right names */
armature_flip_names();
break;
- case 14: /* interactively set bone roll */
- initTransform(TFM_BONE_ROLL, CTX_NONE);
+ case 15: /* subdivide multi */
+ if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+ waitcursor(1);
+ subdivide_armature(numcuts);
+ break;
+ case 16: /* Alt-S transform (BoneSize) */
+ initTransform(TFM_BONESIZE, CTX_NONE);
Transform();
+ break;
+ case 17: /* move to layer */
+ pose_movetolayer();
+ break;
+ case 18: /* merge bones */
+ merge_armature();
+ break;
+ case 19: /* auto-extensions */
+ case 20:
+ case 21:
+ armature_autoside_names(event-19);
+ break;
}
+
allqueue(REDRAWVIEW3D, 0);
}
@@ -3674,6 +3907,29 @@ static uiBlock *view3d_scripts_armaturemenu(void *args_unused)
return block;
}
+static void do_view3d_armature_settingsmenu(void *arg, int event)
+{
+ setflag_armature(event);
+}
+
+static uiBlock *view3d_armature_settingsmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_armature_settingsmenu",
+ UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_armature_settingsmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Toggle a Setting|Shift W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Enable a Setting|Ctrl Shift W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Disable a Setting|Alt W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
{
@@ -3692,8 +3948,12 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Bone Roll Angle|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Bone Roll Angle|Ctrl N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+ uiDefIconTextBlockBut(block, view3d_edit_armature_rollmenu, NULL, ICON_RIGHTARROW_THIN, "Bone Roll", 0, yco-=20, 120, 19, "");
+
+ if (arm->drawtype==ARM_ENVELOPE)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale Envelope Distance|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
+ else if (arm->drawtype==ARM_B_BONE)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale B-Bone Width|Alt S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -3702,16 +3962,28 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude Forked|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Merge|Alt M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Fill Between Joints|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Left & Right Names|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Multi|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Left & Right Names|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Left-Right|W, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Front-Back|W, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Top-Bottom|W, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Switch Armature Layers|Shift M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Bone To Layer|M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBlockBut(block, view3d_edit_armature_parentmenu, NULL, ICON_RIGHTARROW_THIN, "Parent", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBlockBut(block, view3d_armature_settingsmenu, NULL, ICON_RIGHTARROW_THIN, "Bone Settings", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -3873,6 +4145,46 @@ static uiBlock *view3d_pose_armature_constraintsmenu(void *arg_unused)
return block;
}
+static void do_view3d_pose_armature_groupmenu(void *arg, int event)
+{
+ switch (event) {
+ case 1:
+ pose_assign_to_posegroup(1);
+ break;
+ case 2:
+ pose_assign_to_posegroup(0);
+ break;
+ case 3:
+ pose_add_posegroup();
+ break;
+ case 4:
+ pose_remove_from_posegroups();
+ break;
+ case 5:
+ pose_remove_posegroup();
+ break;
+ }
+}
+
+static uiBlock *view3d_pose_armature_groupmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_groupmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_pose_armature_groupmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Selected to Active Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add Selected to Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add New Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove from All Groups|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Active Group|Ctrl G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
static void do_view3d_pose_armature_motionpathsmenu(void *arg, int event)
{
@@ -3904,13 +4216,55 @@ static uiBlock *view3d_pose_armature_motionpathsmenu(void *arg_unused)
return block;
}
+static void do_view3d_pose_armature_poselibmenu(void *arg, int event)
+{
+ Object *ob= OBACT;
+
+ switch(event) {
+ case 1:
+ poselib_preview_poses(ob, 0);
+ break;
+ case 2:
+ poselib_add_current_pose(ob, 0);
+ break;
+ case 3:
+ poselib_rename_pose(ob);
+ break;
+ case 4:
+ poselib_remove_pose(ob, NULL);
+ break;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_pose_armature_poselibmenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_poselibmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_pose_armature_poselibmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Browse Poses|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add/Replace Pose|Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rename Pose|Ctrl Shift L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Pose|Alt L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
static void do_view3d_pose_armaturemenu(void *arg, int event)
{
Object *ob;
ob=OBACT;
switch(event) {
-
case 0: /* transform properties */
mainqenter(NKEY, 1);
break;
@@ -3942,7 +4296,19 @@ static void do_view3d_pose_armaturemenu(void *arg, int event)
}
}
break;
+ case 14: /* move bone to layer / change armature layer */
+ pose_movetolayer();
+ break;
+ case 15:
+ pose_relax();
+ break;
+ case 16: /* auto-extensions for bones */
+ case 17:
+ case 18:
+ pose_autoside_names(event-16);
+ break;
}
+
allqueue(REDRAWVIEW3D, 0);
}
@@ -3965,26 +4331,43 @@ static uiBlock *view3d_pose_armaturemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Relax Pose|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy Current Pose", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Paste Pose", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Paste Flipped Pose", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBlockBut(block, view3d_pose_armature_poselibmenu, NULL, ICON_RIGHTARROW_THIN, "Pose Library", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_pose_armature_motionpathsmenu, NULL, ICON_RIGHTARROW_THIN, "Motion Paths", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBlockBut(block, view3d_pose_armature_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Bone Groups", 0, yco-=20, 120, 19, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBlockBut(block, view3d_pose_armature_ikmenu, NULL, ICON_RIGHTARROW_THIN, "Inverse Kinematics", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_pose_armature_constraintsmenu, NULL, ICON_RIGHTARROW_THIN, "Constraints", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Left-Right|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Front-Back|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "AutoName Top-Bottom|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip L/R Names|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy Attributes...|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Switch Armature Layers|Shift M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Move Bone To Layer|M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBlockBut(block, view3d_pose_armature_showhidemenu,
NULL, ICON_RIGHTARROW_THIN, "Show/Hide Bones", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBlockBut(block, view3d_armature_settingsmenu,
+ NULL, ICON_RIGHTARROW_THIN, "Bone Settings", 0, yco-=20, 120, 19, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
@@ -4002,19 +4385,22 @@ static uiBlock *view3d_pose_armaturemenu(void *arg_unused)
/* vertex paint menu */
static void do_view3d_vpaintmenu(void *arg, int event)
{
- /* events >= 2 are registered bpython scripts */
- if (event >= 2) BPY_menu_do_python(PYMENU_VERTEXPAINT, event - 2);
+ /* events >= 3 are registered bpython scripts */
+ if (event >= 3) BPY_menu_do_python(PYMENU_VERTEXPAINT, event - 3);
switch(event) {
case 0: /* undo vertex painting */
BIF_undo();
break;
case 1: /* set vertex colors/weight */
- if(G.f & G_FACESELECT)
+ if(FACESEL_PAINT_TEST)
clear_vpaint_selectedfaces();
else /* we know were in vertex paint mode */
clear_vpaint();
break;
+ case 2:
+ make_vertexcol(1);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -4031,12 +4417,13 @@ static uiBlock *view3d_vpaintmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Vertex Painting|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Vertex Colors|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Shaded Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- /* note that we account for the 2 previous entries with i+2:
+ /* note that we account for the 3 previous entries with i+3:
even if the last item isnt displayed, it dosent matter */
for (pym = BPyMenuTable[PYMENU_VERTEXPAINT]; pym; pym = pym->next, i++) {
uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, i+2,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, i+3,
pym->tooltip?pym->tooltip:pym->filename);
}
@@ -4091,9 +4478,10 @@ static uiBlock *view3d_tpaintmenu(void *arg_unused)
static void do_view3d_wpaintmenu(void *arg, int event)
{
+ Object *ob= OBACT;
- /* events >= 2 are registered bpython scripts */
- if (event >= 2) BPY_menu_do_python(PYMENU_WEIGHTPAINT, event - 2);
+ /* events >= 3 are registered bpython scripts */
+ if (event >= 4) BPY_menu_do_python(PYMENU_WEIGHTPAINT, event - 4);
switch(event) {
case 0: /* undo weight painting */
@@ -4102,6 +4490,12 @@ static void do_view3d_wpaintmenu(void *arg, int event)
case 1: /* set vertex colors/weight */
clear_wpaint_selectedfaces();
break;
+ case 2: /* vgroups from envelopes */
+ pose_adds_vgroups(ob, 0);
+ break;
+ case 3: /* vgroups from bone heat */
+ pose_adds_vgroups(ob, 1);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -4112,22 +4506,30 @@ static uiBlock *view3d_wpaintmenu(void *arg_unused)
short yco= 0, menuwidth=120, menunr=1;
BPyMenu *pym;
int i=0;
-
+
block= uiNewBlock(&curarea->uiblocks, "view3d_paintmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_wpaintmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Undo Weight Painting|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
- if (G.f & G_FACESELECT) {
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Bone Heat Weights to Vertex Groups|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Bone Envelopes to Vertex Groups|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ if (FACESEL_PAINT_TEST) {
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Weight|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
menunr++;
}
- /* note that we account for the 2 previous entries with i+2:
+ /* note that we account for the 4 previous entries with i+4:
even if the last item isnt displayed, it dosent matter */
for (pym = BPyMenuTable[PYMENU_WEIGHTPAINT]; pym; pym = pym->next, i++) {
uiDefIconTextBut(block, BUTM, 1, ICON_PYTHON, pym->name, 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, i+2,
+ menuwidth, 19, NULL, 0.0, 0.0, 1, i+4,
pym->tooltip?pym->tooltip:pym->filename);
}
@@ -4150,19 +4552,20 @@ void do_view3d_sculpt_inputmenu(void *arg, int event)
switch(event) {
case 0:
- val= sd->averaging;
- if(button(&val,1,10,"Averaging:")==0) return;
- sd->averaging= val;
+ sd->flags ^= SCULPT_INPUT_SMOOTH;
+ BIF_undo_push("Smooth stroke");
break;
case 1:
val= sd->tablet_size;
if(button(&val,0,10,"Tablet Size:")==0) return;
sd->tablet_size= val;
+ BIF_undo_push("Tablet size");
break;
case 2:
val= sd->tablet_strength;
if(button(&val,0,10,"Tablet Strength:")==0) return;
sd->tablet_strength= val;
+ BIF_undo_push("Tablet strength");
break;
}
@@ -4174,6 +4577,7 @@ void do_view3d_sculptmenu(void *arg, int event)
{
SculptData *sd= &G.scene->sculptdata;
BrushData *br= sculptmode_brush();
+
switch(event) {
case 0:
case 1:
@@ -4183,39 +4587,52 @@ void do_view3d_sculptmenu(void *arg, int event)
case 5:
case 6:
sd->brush_type= event+1;
+ BIF_undo_push("Brush type");
break;
case 7:
- br->airbrush= !br->airbrush; break;
+ br->flag ^= SCULPT_BRUSH_AIRBRUSH;
+ BIF_undo_push("Airbrush");
+ break;
case 8:
- sd->symm ^= SYMM_X; break;
+ sd->symm ^= SYMM_X;
+ BIF_undo_push("X Symmetry");
+ break;
case 9:
- sd->symm ^= SYMM_Y; break;
+ sd->symm ^= SYMM_Y;
+ BIF_undo_push("Y Symmetry");
+ break;
case 10:
- sd->symm ^= SYMM_Z; break;
+ sd->symm ^= SYMM_Z;
+ BIF_undo_push("Z Symmetry");
+ break;
case 11:
- if(G.vd)
+ if(G.vd)
G.vd->pivot_last= !G.vd->pivot_last;
break;
case 12:
- sd->draw_flag ^= SCULPTDRAW_FAST;
+ sd->flags ^= SCULPT_DRAW_FAST;
+ BIF_undo_push("Partial Redraw");
break;
case 13:
- sd->draw_flag ^= SCULPTDRAW_BRUSH;
+ sd->flags ^= SCULPT_DRAW_BRUSH;
+ BIF_undo_push("Draw Brush");
break;
case 14:
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
break;
case 15:
- sculptmode_propset_init(PropsetTexRot);
+ sculpt_radialcontrol_start(RADIALCONTROL_ROTATION);
break;
case 16:
- sculptmode_propset_init(PropsetStrength);
+ sculpt_radialcontrol_start(RADIALCONTROL_STRENGTH);
break;
case 17:
- sculptmode_propset_init(PropsetSize);
+ sculpt_radialcontrol_start(RADIALCONTROL_SIZE);
break;
case 18:
- br->dir= br->dir==1 ? 2 : 1; break;
+ br->dir= br->dir==1 ? 2 : 1;
+ BIF_undo_push("Add/Sub");
+ break;
}
allqueue(REDRAWBUTSEDIT, 0);
@@ -4226,11 +4643,12 @@ uiBlock *view3d_sculpt_inputmenu(void *arg_unused)
{
uiBlock *block;
short yco= 0, menuwidth= 120;
+ SculptData *sd= &G.scene->sculptdata;
block= uiNewBlock(&curarea->uiblocks, "view3d_sculpt_inputmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_sculpt_inputmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Averaging", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ((sd->flags & SCULPT_INPUT_SMOOTH) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Smooth Stroke", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Tablet Size Adjust", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Tablet Strength Adjust", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
@@ -4251,10 +4669,10 @@ uiBlock *view3d_sculptmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Sculpt Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBlockBut(block, view3d_sculpt_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input Devices", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBlockBut(block, view3d_sculpt_inputmenu, NULL, ICON_RIGHTARROW_THIN, "Input Settings", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ((sd->draw_flag & SCULPTDRAW_BRUSH) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Display Brush", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
- uiDefIconTextBut(block, BUTM, 1, ((sd->draw_flag & SCULPTDRAW_FAST) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Partial Redraw", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
+ uiDefIconTextBut(block, BUTM, 1, ((sd->flags & SCULPT_DRAW_BRUSH) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Display Brush", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+ uiDefIconTextBut(block, BUTM, 1, ((sd->flags & SCULPT_DRAW_FAST) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Partial Redraw", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
if(G.vd)
uiDefIconTextBut(block, BUTM, 1, (G.vd->pivot_last ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Pivot Last", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
@@ -4271,14 +4689,14 @@ uiBlock *view3d_sculptmenu(void *arg_unused)
if(sd->brush_type!=GRAB_BRUSH) {
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, (br->airbrush ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Airbrush|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, (br->flag & SCULPT_BRUSH_AIRBRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Airbrush|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
if(sd->brush_type!=SMOOTH_BRUSH && sd->brush_type!=FLATTEN_BRUSH) {
uiDefIconTextBut(block, BUTM, 1, (br->dir==1 ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Add|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
}
}
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==FLATTEN_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Flatten", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==FLATTEN_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Flatten|T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==LAYER_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Layer|L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==GRAB_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Grab|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==INFLATE_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Inflate|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
@@ -4300,126 +4718,6 @@ uiBlock *view3d_sculptmenu(void *arg_unused)
return block;
}
-static void do_view3d_facesel_propertiesmenu(void *arg, int event)
-{
- MTFace *tf = get_active_tface(NULL);
-
- if (tf) {
- switch(event) {
- case 0: /* textured */
- tf->mode ^= TF_TEX;
- break;
- case 1: /* tiled*/
- tf->mode ^= TF_TILES;
- break;
- case 2: /* light */
- tf->mode ^= TF_LIGHT;
- break;
- case 3: /* invisible */
- tf->mode ^= TF_INVISIBLE;
- break;
- case 4: /* collision */
- tf->mode ^= TF_DYNAMIC;
- break;
- case 5: /* shared vertex colors */
- tf->mode ^= TF_SHAREDCOL;
- break;
- case 6: /* two sided */
- tf->mode ^= TF_TWOSIDE;
- break;
- case 7: /* use object color */
- tf->mode ^= TF_OBCOL;
- break;
- case 8: /* halo */
- tf->mode ^= TF_BILLBOARD;
- break;
- case 9: /* billboard */
- tf->mode ^= TF_BILLBOARD2;
- break;
- case 10: /* shadow */
- tf->mode ^= TF_SHADOW;
- break;
- case 11: /* text */
- tf->mode ^= TF_BMFONT;
- break;
- case 12: /* opaque blend mode */
- tf->transp = TF_SOLID;
- break;
- case 13: /* additive blend mode */
- tf->transp |= TF_ADD;
- break;
- case 14: /* alpha blend mode */
- tf->transp = TF_ALPHA;
- break;
- }
- }
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
-}
-
-static uiBlock *view3d_facesel_propertiesmenu(void *arg_unused)
-{
- MTFace *tf = get_active_tface(NULL);
- uiBlock *block;
- short yco = 20, menuwidth = 120;
-
- /* display ticks/crosses depending on active tface properties */
-
- block= uiNewBlock(&curarea->uiblocks, "view3d_facesel_propertiesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
- uiBlockSetButmFunc(block, do_view3d_facesel_propertiesmenu, NULL);
-
- if (tf->mode & TF_TEX) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Textured", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Textured", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
-
- if (tf->mode & TF_TILES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Tiled", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Tiled", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
-
- if (tf->mode & TF_LIGHT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Light", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Light", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
-
- if (tf->mode & TF_INVISIBLE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Invisible", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Invisible", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
-
- if (tf->mode & TF_DYNAMIC) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Collision", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Collision", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
-
- if (tf->mode & TF_SHAREDCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shared Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shared Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
-
- if (tf->mode & TF_TWOSIDE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Two Sided", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Two Sided", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
-
- if (tf->mode & TF_OBCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Object Color", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Object Color", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
-
- if (tf->mode & TF_BILLBOARD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Halo", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Halo", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
-
- if (tf->mode & TF_BILLBOARD2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Billboard", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Billboard", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
-
- if (tf->mode & TF_SHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shadow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shadow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
-
- if (tf->mode & TF_BMFONT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Text", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Text", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- if (tf->transp == TF_SOLID) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Opaque Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Opaque Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
-
- if (tf->transp == TF_ADD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Additive Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Additive Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
-
- if (tf->transp == TF_ALPHA) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Alpha Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
- else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Alpha Blend Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
-
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 60);
- return block;
-}
-
static void do_view3d_facesel_showhidemenu(void *arg, int event)
{
switch(event) {
@@ -4457,61 +4755,14 @@ static uiBlock *view3d_facesel_showhidemenu(void *arg_unused)
static void do_view3d_faceselmenu(void *arg, int event)
{
- /* code copied from buttons.c :(
- would be nice if it was split up into functions */
- Mesh *me;
- MTFace *tf, *activetf;
- MFace *mf;
- MCol *activemcol;
- int a;
-
switch(event) {
- case 0: /* copy draw mode */
- case 1: /* copy UVs */
- case 2: /* copy vertex colors */
- me= get_mesh(OBACT);
- activetf = get_active_tface(&activemcol);
-
- if (me && activetf) {
- mf = me->mface;
- for (a=0, tf=me->mtface; a < me->totface; a++, tf++, mf++) {
- if(tf!=activetf && (mf->flag & ME_FACE_SEL)) {
- if(event==0) {
- tf->mode= activetf->mode;
- tf->transp= activetf->transp;
- } else if(event==1) {
- memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
- tf->tpage= activetf->tpage;
- tf->tile= activetf->tile;
-
- if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
- else tf->mode &= ~TF_TILES;
-
- }
- else if(event==2 && activemcol)
- memcpy(&me->mcol[a*4], activemcol, sizeof(MCol)*4);
- }
- }
-
- do_shared_vertexcol(me);
- }
- break;
- case 3: /* set vertex colors */
+ case 0: /* set vertex colors */
clear_vpaint_selectedfaces();
break;
- case 8: /* uv calculation */
- uv_autocalc_tface();
- break;
- case 7: /* rotate UVs */
- rotate_uv_tface();
- break;
- case 9: /* mirror UVs */
- mirror_uv_tface();
- break;
- case 10: /* mark border seam */
+ case 1: /* mark border seam */
seam_mark_clear_tface(1);
break;
- case 11: /* clear seam */
+ case 2: /* clear seam */
seam_mark_clear_tface(2);
break;
}
@@ -4526,30 +4777,198 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_faceselmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_view3d_faceselmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Vertex Colors|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBlockBut(block, view3d_facesel_propertiesmenu, NULL, ICON_RIGHTARROW_THIN, "Active Draw Mode", 0, yco-=20, 120, 19, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy Draw Mode", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Border Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unwrap UVs|U", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate UVs|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mirror UVs|M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+ uiDefIconTextBlockBut(block, view3d_facesel_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, 120, 19, "");
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ if(curarea->headertype==HEADERTOP) {
+ uiBlockSetDirection(block, UI_DOWN);
+ }
+ else {
+ uiBlockSetDirection(block, UI_TOP);
+ uiBlockFlipOrder(block);
+ }
+
+ uiTextBoundsBlock(block, 50);
+ return block;
+}
+
+void do_view3d_select_particlemenu(void *arg, int event)
+{
+ /* events >= 6 are registered bpython scripts */
+ if (event >= 6) BPY_menu_do_python(PYMENU_FACESELECT, event - 6);
+
+ switch(event) {
+ case 0:
+ PE_borderselect();
+ break;
+ case 1:
+ PE_deselectall();
+ break;
+ case 2:
+ PE_select_root();
+ break;
+ case 3:
+ PE_select_tip();
+ break;
+ case 4:
+ PE_select_more();
+ break;
+ case 5:
+ PE_select_less();
+ break;
+ case 7:
+ PE_select_linked();
+ break;
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_select_particlemenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_select_particlemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
+ uiBlockSetButmFunc(block, do_view3d_select_particlemenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy UVs & Textures", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Copy Vertex Colors", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Vertex Colors|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Border Select|B",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, SEPR, 0, "",
+ 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Border Seam|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Linked|L",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Last|W, 4",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select First|W, 3",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, SEPR, 0, "",
+ 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBlockBut(block, view3d_facesel_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, 120, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "More|Ctrl NumPad +",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Less|Ctrl NumPad -",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+
+
+ if(curarea->headertype==HEADERTOP) {
+ uiBlockSetDirection(block, UI_DOWN);
+ }
+ else {
+ uiBlockSetDirection(block, UI_TOP);
+ uiBlockFlipOrder(block);
+ }
+
+ uiTextBoundsBlock(block, 50);
+ return block;
+}
+
+void do_view3d_particle_showhidemenu(void *arg, int event)
+{
+ switch(event) {
+ case 1: /* show hidden */
+ PE_hide(0);
+ break;
+ case 2: /* hide selected */
+ PE_hide(2);
+ break;
+ case 3: /* hide deselected */
+ PE_hide(1);
+ break;
+ }
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_particle_showhidemenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco = 20, menuwidth = 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_particle_showhidemenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_view3d_particle_showhidemenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Hidden|Alt H",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Selected|H",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Hide Deselected|Shift H",
+ 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+ return block;
+}
+
+void do_view3d_particlemenu(void *arg, int event)
+{
+ ParticleEditSettings *pset= PE_settings();
+
+ switch(event) {
+ case 1:
+ add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
+ break;
+ case 2:
+ if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return;
+ PE_rekey();
+ break;
+ case 3:
+ PE_subdivide();
+ break;
+ case 4:
+ PE_delete_particle();
+ break;
+ case 5:
+ PE_mirror_x(0);
+ break;
+ case 6:
+ pset->flag ^= PE_X_MIRROR;
+ break;
+ case 7:
+ PE_remove_doubles();
+ break;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+uiBlock *view3d_particlemenu(void *arg_unused)
+{
+ uiBlock *block;
+ ParticleEditSettings *pset= PE_settings();
+ short yco= 0, menuwidth= 120;
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_particlemenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
+ uiBlockSetButmFunc(block, do_view3d_particlemenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Particle Edit Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, (pset->flag & PE_X_MIRROR)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT, "X-Axis Mirror Editing", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Doubles|W, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete...|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ if(G.scene->selectmode & SCE_SELECT_POINT)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rekey|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBlockBut(block, view3d_particle_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Particles", 0, yco-=20, menuwidth, 19, "");
if(curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
@@ -4560,6 +4979,7 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
}
uiTextBoundsBlock(block, 50);
+
return block;
}
@@ -4588,7 +5008,7 @@ static char *view3d_modeselect_pup(void)
if (ob->type == OB_MESH) {
str += sprintf(str, formatstr, "Sculpt Mode", V3D_SCULPTMODE_SEL, ICON_SCULPTMODE_HLT);
- str += sprintf(str, formatstr, "UV Face Select", V3D_FACESELECTMODE_SEL, ICON_FACESEL_HLT);
+ /*str += sprintf(str, formatstr, "Face Select", V3D_FACESELECTMODE_SEL, ICON_FACESEL_HLT);*/
str += sprintf(str, formatstr, "Vertex Paint", V3D_VERTEXPAINTMODE_SEL, ICON_VPAINT_HLT);
str += sprintf(str, formatstr, "Texture Paint", V3D_TEXTUREPAINTMODE_SEL, ICON_TPAINT_HLT);
str += sprintf(str, formatstr, "Weight Paint", V3D_WEIGHTPAINTMODE_SEL, ICON_WPAINT_HLT);
@@ -4599,7 +5019,11 @@ static char *view3d_modeselect_pup(void)
if (ob->type==OB_ARMATURE) {
str += sprintf(str, formatstr, "Pose Mode", V3D_POSEMODE_SEL, ICON_POSE_HLT);
}
-
+
+ if (ob->particlesystem.first) {
+ str += sprintf(str, formatstr, "Particle Mode", V3D_PARTICLEEDITMODE_SEL, ICON_PHYSICS);
+ }
+
return (string);
}
@@ -4627,7 +5051,10 @@ static char *around_pup(void)
str += sprintf(str, "%s", "|Median Point %x3");
str += sprintf(str, "%s", "|3D Cursor %x1");
str += sprintf(str, "%s", "|Individual Centers %x2");
- str += sprintf(str, "%s", "|Active Object %x4");
+ if ((G.obedit) && (G.obedit->type == OB_MESH))
+ str += sprintf(str, "%s", "|Active Vert/Edge/Face %x4");
+ else
+ str += sprintf(str, "%s", "|Active Object %x4");
return string;
}
@@ -4729,37 +5156,18 @@ void do_view3d_buttons(short event)
start_game();
}
break;
- case B_VIEWZOOM:
- viewmovetemp= 0;
- viewmove(2);
- scrarea_queue_headredraw(curarea);
- break;
- case B_VIEWTRANS:
- viewmovetemp= 0;
- viewmove(1);
- scrarea_queue_headredraw(curarea);
- break;
-
case B_MODESELECT:
if (G.vd->modeselect == V3D_OBJECTMODE_SEL) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
- if(G.f & G_FACESELECT) set_faceselect(); /* Switch off face select */
+ exit_paint_modes();
if(ob) exit_posemode(); /* exit posemode for active object */
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
}
else if (G.vd->modeselect == V3D_EDITMODE_SEL) {
if(!G.obedit) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
-
+ exit_paint_modes();
enter_editmode(EM_WAITCURSOR);
BIF_undo_push("Original"); /* here, because all over code enter_editmode is abused */
}
@@ -4767,39 +5175,16 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_SCULPTMODE_SEL) {
if (!(G.f & G_SCULPTMODE)) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_FACESELECT) set_faceselect(); /* Switch off face select */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
+ exit_paint_modes();
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
set_sculptmode();
}
- }
- else if (G.vd->modeselect == V3D_FACESELECTMODE_SEL) {
- if ((G.obedit) && (G.f & G_FACESELECT)) {
- exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
- } else if ((G.f & G_FACESELECT) && (G.f & G_VERTEXPAINT)) {
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- } else if ((G.f & G_FACESELECT) && (G.f & G_TEXTUREPAINT)) {
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- } else {
- G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
- if (G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
-
- set_faceselect();
- }
- }
+ }
else if (G.vd->modeselect == V3D_VERTEXPAINTMODE_SEL) {
if (!(G.f & G_VERTEXPAINT)) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
+ exit_paint_modes();
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
set_vpaint();
@@ -4808,9 +5193,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_TEXTUREPAINTMODE_SEL) {
if (!(G.f & G_TEXTUREPAINT)) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
+ exit_paint_modes();
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
set_texturepaint();
@@ -4819,9 +5202,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_WEIGHTPAINTMODE_SEL) {
if (!(G.f & G_WEIGHTPAINT) && (ob && ob->type == OB_MESH) ) {
G.vd->flag &= ~V3D_MODE;
- if(G.f & G_SCULPTMODE) set_sculptmode(); /* Switch off sculptmode */
- if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
- if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
+ exit_paint_modes();
if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
set_wpaint();
@@ -4836,6 +5217,15 @@ void do_view3d_buttons(short event)
enter_posemode();
}
}
+ else if(G.vd->modeselect == V3D_PARTICLEEDITMODE_SEL){
+ if (!(G.f & G_PARTICLEEDIT)) {
+ G.vd->flag &= ~V3D_MODE;
+ exit_paint_modes();
+ if(G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* exit editmode and undo */
+
+ PE_set_particle_edit();
+ }
+ }
allqueue(REDRAWVIEW3D, 1);
break;
@@ -4851,6 +5241,7 @@ void do_view3d_buttons(short event)
countall();
BIF_undo_push("Selectmode Set: Vertex");
allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
break;
case B_SEL_EDGE:
if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){
@@ -4863,6 +5254,7 @@ void do_view3d_buttons(short event)
countall();
BIF_undo_push("Selectmode Set: Edge");
allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
break;
case B_SEL_FACE:
if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){
@@ -4875,6 +5267,23 @@ void do_view3d_buttons(short event)
countall();
BIF_undo_push("Selectmode Set: Face");
allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
+ break;
+
+ case B_SEL_PATH:
+ G.scene->selectmode= SCE_SELECT_PATH;
+ BIF_undo_push("Selectmode Set: Path");
+ allqueue(REDRAWVIEW3D, 1);
+ break;
+ case B_SEL_POINT:
+ G.scene->selectmode = SCE_SELECT_POINT;
+ BIF_undo_push("Selectmode Set: Point");
+ allqueue(REDRAWVIEW3D, 1);
+ break;
+ case B_SEL_END:
+ G.scene->selectmode = SCE_SELECT_END;
+ BIF_undo_push("Selectmode Set: End point");
+ allqueue(REDRAWVIEW3D, 1);
break;
case B_MAN_TRANS:
@@ -4895,7 +5304,10 @@ void do_view3d_buttons(short event)
case B_NDOF:
allqueue(REDRAWVIEW3D, 1);
break;
-
+ case B_MAN_MODE:
+ allqueue(REDRAWVIEW3D, 1);
+ break;
+
default:
if(event>=B_LAY && event<B_LAY+31) {
@@ -4978,12 +5390,14 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
} else if (ob && ob->type == OB_ARMATURE) {
uiDefPulldownBut(block, view3d_select_armaturemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
}
- } else if (G.f & G_FACESELECT) {
+ } else if (FACESEL_PAINT_TEST) {
if (ob && ob->type == OB_MESH) {
uiDefPulldownBut(block, view3d_select_faceselmenu, NULL, "Select", xco,-2, xmax-3, 24, "");
}
} else if ((G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_WEIGHTPAINT)) {
uiDefBut(block, LABEL,0,"", xco, 0, xmax, 20, 0, 0, 0, 0, 0, "");
+ } else if (G.f & G_PARTICLEEDIT) {
+ uiDefPulldownBut(block, view3d_select_particlemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
} else {
if (ob && (ob->flag & OB_POSEMODE))
@@ -5023,6 +5437,7 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
uiDefPulldownBut(block, view3d_edit_armaturemenu, NULL, "Armature", xco,-2, xmax-3, 24, "");
xco+= xmax;
}
+
}
else if (G.f & G_WEIGHTPAINT) {
xmax= GetButStringLength("Paint");
@@ -5044,13 +5459,19 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
uiDefPulldownBut(block, view3d_sculptmenu, NULL, "Sculpt", xco, -2, xmax-3, 24, "");
xco+= xmax;
}
- else if (G.f & G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
if (ob && ob->type == OB_MESH) {
xmax= GetButStringLength("Face");
uiDefPulldownBut(block, view3d_faceselmenu, NULL, "Face", xco,-2, xmax-3, 24, "");
xco+= xmax;
}
- } else {
+ }
+ else if(G.f & G_PARTICLEEDIT) {
+ xmax= GetButStringLength("Particle");
+ uiDefPulldownBut(block, view3d_particlemenu, NULL, "Particle", xco,-2, xmax-3, 24, "");
+ xco+= xmax;
+ }
+ else {
if (ob && (ob->flag & OB_POSEMODE)) {
xmax= GetButStringLength("Pose");
uiDefPulldownBut(block, view3d_pose_armaturemenu, NULL, "Pose", xco,-2, xmax-3, 24, "");
@@ -5112,7 +5533,8 @@ void view3d_buttons(void)
else if (G.f & G_WEIGHTPAINT) G.vd->modeselect = V3D_WEIGHTPAINTMODE_SEL;
else if (G.f & G_VERTEXPAINT) G.vd->modeselect = V3D_VERTEXPAINTMODE_SEL;
else if (G.f & G_TEXTUREPAINT) G.vd->modeselect = V3D_TEXTUREPAINTMODE_SEL;
- else if(G.f & G_FACESELECT) G.vd->modeselect = V3D_FACESELECTMODE_SEL;
+ /*else if(G.f & G_FACESELECT) G.vd->modeselect = V3D_FACESELECTMODE_SEL;*/
+ else if(G.f & G_PARTICLEEDIT) G.vd->modeselect = V3D_PARTICLEEDITMODE_SEL;
G.vd->flag &= ~V3D_MODE;
@@ -5122,10 +5544,10 @@ void view3d_buttons(void)
if(G.f & G_VERTEXPAINT) G.vd->flag |= V3D_VERTEXPAINT;
if(G.f & G_WEIGHTPAINT) G.vd->flag |= V3D_WEIGHTPAINT;
if (G.f & G_TEXTUREPAINT) G.vd->flag |= V3D_TEXTUREPAINT;
- if(G.f & G_FACESELECT) G.vd->flag |= V3D_FACESELECT;
+ if(FACESEL_PAINT_TEST) G.vd->flag |= V3D_FACESELECT;
uiDefIconTextButS(block, MENU, B_MODESELECT, (G.vd->modeselect),view3d_modeselect_pup() ,
- xco,0,126,20, &(G.vd->modeselect), 0, 0, 0, 0, "Mode (Hotkeys: Tab, F, V, Ctrl Tab)");
+ xco,0,126,20, &(G.vd->modeselect), 0, 0, 0, 0, "Mode (Hotkeys: Tab, V, Ctrl Tab)");
xco+= 126+8;
@@ -5167,74 +5589,71 @@ void view3d_buttons(void)
uiBlockEndAlign(block);
}
} else {
- uiDefIconTextButS(block, ICONTEXTROW,B_AROUND, ICON_ROTATE, around_pup(), xco,0,XIC+10,YIC, &(G.vd->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period) ");
+ if (G.obedit==NULL && (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_SCULPTMODE))) {
+ uiDefIconButBitI(block, TOG, G_FACESELECT, B_REDR, ICON_FACESEL_HLT,xco,0,XIC,YIC, &G.f, 0, 0, 0, 0, "Painting Mask (FKey)");
+ xco+= XIC+10;
+ } else {
+ /* Manipulators arnt used in weight paint mode */
+ char *str_menu;
+ uiDefIconTextButS(block, ICONTEXTROW,B_AROUND, ICON_ROTATE, around_pup(), xco,0,XIC+10,YIC, &(G.vd->around), 0, 3.0, 0, 0, "Rotation/Scaling Pivot (Hotkeys: Comma, Shift Comma, Period, Ctrl Period, Alt Period)");
- xco+= XIC+10;
+ xco+= XIC+10;
+
+ uiDefIconButBitS(block, TOG, V3D_ALIGN, B_AROUND, ICON_ALIGN,
+ xco,0,XIC,YIC,
+ &G.vd->flag, 0, 0, 0, 0, "Move object centers only");
+ uiBlockEndAlign(block);
+
+ xco+= XIC+8;
- uiDefIconButBitS(block, TOG, V3D_ALIGN, B_AROUND, ICON_ALIGN,
+ uiDefIconButBitS(block, TOG, V3D_ALIGN, B_AROUND, ICON_ALIGN,
xco,0,XIC,YIC,
&G.vd->flag, 0, 0, 0, 0, "Move object centers only");
- xco+= XIC+8;
- uiBlockEndAlign(block);
+ xco+= XIC+8;
+ uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
+ uiBlockBeginAlign(block);
- /* NDOF */
- if (G.ndofdevice ==0 ) {
- uiDefIconTextButC(block, ICONTEXTROW,B_NDOF, ICON_NDOF_TURN, ndof_pup(), xco,0,XIC+10,YIC, &(G.vd->ndofmode), 0, 3.0, 0, 0, "Ndof mode");
+ /* NDOF */
+ if (G.ndofdevice ==0 ) {
+ uiDefIconTextButC(block, ICONTEXTROW,B_NDOF, ICON_NDOF_TURN, ndof_pup(), xco,0,XIC+10,YIC, &(G.vd->ndofmode), 0, 3.0, 0, 0, "Ndof mode");
- xco+= XIC+10;
+ xco+= XIC+10;
- uiDefIconButC(block, TOG, B_NDOF, ICON_NDOF_DOM,
+ uiDefIconButC(block, TOG, B_NDOF, ICON_NDOF_DOM,
xco,0,XIC,YIC,
&G.vd->ndoffilter, 0, 1, 0, 0, "dominant axis");
- uiBlockEndAlign(block);
+ uiBlockEndAlign(block);
- xco+= XIC+8;
- }
- uiBlockEndAlign(block);
+ xco+= XIC+8;
+ }
+ uiBlockEndAlign(block);
- /*{
- char tempstring[256];
- switch (G.vd->ndofmode) {
- case 0:
- sprintf(tempstring,"6dof : %s %s", "turntable",((G.vd->ndoffilter==1) ? "dominant" : ""));
- break;
- case 1:
- sprintf(tempstring,"6dof : %s %s", "fly",((G.vd->ndoffilter==1) ? "dominant" : ""));
- break;
- case 2:
- sprintf(tempstring,"6dof : %s %s", "transform",((G.vd->ndoffilter==1) ? "dominant" : ""));
- break;
- default:
- tempstring[0]=0;
- break;
+ /* Transform widget / manipulators */
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, TOG, V3D_USE_MANIPULATOR, B_REDR, ICON_MANIPUL,xco,0,XIC,YIC, &G.vd->twflag, 0, 0, 0, 0, "Use 3d transform manipulator (Ctrl Space)");
+ xco+= XIC;
+
+
+ if(G.vd->twflag & V3D_USE_MANIPULATOR) {
+ uiDefIconButBitS(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode (Ctrl Alt G)");
+ xco+= XIC;
+ uiDefIconButBitS(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode (Ctrl Alt R)");
+ xco+= XIC;
+ uiDefIconButBitS(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode (Ctrl Alt S)");
+ xco+= XIC;
}
- uiDefBut(block, LABEL,0,tempstring,
- xco+=XIC*2,0,150,YIC, 0, 1.0, 0, 0, 0,
- "");
- }
-*/
- /* Transform widget / manipulators */
- uiBlockBeginAlign(block);
- uiDefIconButBitS(block, TOG, V3D_USE_MANIPULATOR, B_REDR, ICON_MANIPUL,xco,0,XIC,YIC, &G.vd->twflag, 0, 0, 0, 0, "Use 3d transform manipulator (Ctrl Space)");
- xco+= XIC;
-
- if(G.vd->twflag & V3D_USE_MANIPULATOR) {
- uiDefIconButBitS(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode (Ctrl Alt G)");
- xco+= XIC;
- uiDefIconButBitS(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode (Ctrl Alt R)");
- xco+= XIC;
- uiDefIconButBitS(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, xco,0,XIC,YIC, &G.vd->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode (Ctrl Alt S)");
- xco+= XIC;
- }
- uiDefButS(block, MENU, B_NOP, "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3",xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (Alt Space)");
- xco+= 70;
- uiBlockEndAlign(block);
- xco+= 8;
-
+ str_menu = BIF_menustringTransformOrientation();
+ uiDefButS(block, MENU, B_MAN_MODE, str_menu,xco,0,70,YIC, &G.vd->twmode, 0, 0, 0, 0, "Transform Orientation (ALT+Space)");
+ MEM_freeN(str_menu);
+
+ xco+= 70;
+ uiBlockEndAlign(block);
+ xco+= 8;
+ }
+
/* LAYERS */
if(G.obedit==NULL && G.vd->localview==0) {
uiBlockBeginAlign(block);
@@ -5255,13 +5674,13 @@ void view3d_buttons(void)
xco+= (a-2)*(XIC/2)+3;
/* LOCK */
- uiDefIconButS(block, ICONTOG, B_SCENELOCK, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.vd->scenelock), 0, 0, 0, 0, "Locks layers and used Camera to Scene (Ctrl `)");
+ uiDefIconButS(block, ICONTOG, B_SCENELOCK, ICON_UNLOCKED, xco+=XIC,0,XIC,YIC, &(G.vd->scenelock), 0, 0, 0, 0, "Locks Active Camera and layers to Scene (Ctrl `)");
xco+= XIC+10;
}
/* proportional falloff */
- if(G.obedit && (G.obedit->type == OB_MESH || G.obedit->type == OB_CURVE || G.obedit->type == OB_SURF || G.obedit->type == OB_LATTICE)) {
+ if((G.obedit && (G.obedit->type == OB_MESH || G.obedit->type == OB_CURVE || G.obedit->type == OB_SURF || G.obedit->type == OB_LATTICE)) || G.f & G_PARTICLEEDIT) {
uiBlockBeginAlign(block);
uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_PROP_OFF, "Proportional %t|Off %x0|On %x1|Connected %x2", xco,0,XIC+10,YIC, &(G.scene->proportional), 0, 1.0, 0, 0, "Proportional Edit Falloff (Hotkeys: O, Alt O) ");
@@ -5275,21 +5694,18 @@ void view3d_buttons(void)
}
/* Snap */
- if(G.obedit && (G.obedit->type == OB_MESH)) { // Only Mesh for now
+ if (BIF_snappingSupported()) {
uiBlockBeginAlign(block);
- if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
- {
- uiDefIconButBitS(block, TOG, V3D_TRANSFORM_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.vd->flag2, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)");
+ if (G.scene->snap_flag & SCE_SNAP) {
+ uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)");
xco+= XIC;
- uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,0,70,YIC, &G.vd->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+ uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
xco+= 70;
- }
- else
- {
- uiDefIconButBitS(block, TOG, V3D_TRANSFORM_SNAP, B_REDR, ICON_SNAP_GEAR,xco,0,XIC,YIC, &G.vd->flag2, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)");
+ } else {
+ uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
xco+= XIC;
- }
+ }
uiBlockEndAlign(block);
xco+= 10;
@@ -5306,6 +5722,21 @@ void view3d_buttons(void)
xco+= XIC;
uiBlockEndAlign(block);
if(G.vd->drawtype > OB_WIRE) {
+ uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,0,XIC,YIC, &G.vd->flag, 1.0, 0.0, 0, 0, "Occlude background geometry");
+ xco+= XIC;
+ }
+ xco+= 20;
+ }
+ else if(G.f & G_PARTICLEEDIT) {
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, TOG, SCE_SELECT_PATH, B_SEL_PATH, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Path edit mode (Ctrl Tab 1)");
+ xco+= XIC;
+ uiDefIconButBitS(block, TOG, SCE_SELECT_POINT, B_SEL_POINT, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Point select mode (Ctrl Tab 2)");
+ xco+= XIC;
+ uiDefIconButBitS(block, TOG, SCE_SELECT_END, B_SEL_END, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Tip select mode (Ctrl Tab 3)");
+ xco+= XIC;
+ uiBlockEndAlign(block);
+ if(G.vd->drawtype > OB_WIRE) {
uiDefIconButBitS(block, TOG, V3D_ZBUF_SELECT, B_REDR, ICON_ORTHO, xco,0,XIC,YIC, &G.vd->flag, 1.0, 0.0, 0, 0, "Limit selection to visible (clipped with depth buffer)");
xco+= XIC;
}
diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c
index 7685ec99b2e..dde5a512de9 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -148,8 +148,6 @@
#include "BIF_writeimage.h"
#include "BIF_butspace.h"
-#include "BPI_script.h"
-
#include "BSE_edit.h"
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"
@@ -255,7 +253,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
if(browse) {
char *extrastr= NULL;
- if(ELEM3(id_code, ID_MA, ID_TE, ID_BR)) add_addbutton= 1;
+ if(ELEM4(id_code, ID_MA, ID_TE, ID_BR, ID_PA)) add_addbutton= 1;
lb= wich_libbase(G.main, id_code);
@@ -265,7 +263,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
uiBlockSetCol(block, TH_BUT_SETTING2);
}
- if ELEM8( id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC, ID_BR) extrastr= "ADD NEW %x 32767";
+ if (ELEM8( id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC, ID_BR) || id_code == ID_PA) extrastr= "ADD NEW %x 32767";
else if (id_code==ID_TXT) extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
else if (id_code==ID_SO) extrastr= "OPEN NEW %x 32766";
@@ -325,6 +323,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
}
if( GS(id->name)==ID_IP) len= 110;
+ else if((yco) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib)
else if(yco) len= 140; // comes from button panel
else len= 120;
@@ -392,6 +391,7 @@ int std_libbuttons(uiBlock *block, short xco, short yco,
}
else if(add_addbutton) { /* "add new" button */
uiBlockSetCol(block, oldcol);
+ if(parid) uiSetButLock(parid->lib!=0, ERROR_LIBDATA_MESSAGE);
uiDefButS(block, TOG, browse, "Add New" ,xco, yco, 110, YIC, menupoin, (float)*menupoin, 32767.0, 0, 0, "Add new data block");
xco+= 110;
}
@@ -457,11 +457,12 @@ static void show_splash(void)
char buffer[1024];
extern char * build_date;
extern char * build_time;
+ extern char * build_rev;
extern char * build_platform;
extern char * build_type;
string = &buffer[0];
- sprintf(string,"Built on %s %s Version %s %s", build_date, build_time, build_platform, build_type);
+ sprintf(string,"Built on %s %s, Rev-%s Version %s %s", build_date, build_time, build_rev, build_platform, build_type);
#endif
splash((void *)datatoc_splash_jpg, datatoc_splash_jpg_size, string);
@@ -567,6 +568,8 @@ static void filesel_u_tempdir(char *name)
BLI_split_dirfile(name, dir, file);
strcpy(U.tempdir, dir);
+ BLI_where_is_temp( btempdir, 1 );
+
allqueue(REDRAWALL, 0);
}
@@ -587,7 +590,10 @@ void do_global_buttons(unsigned short event)
ScrArea *sa;
Brush *br;
int nr= 1;
+
+#ifdef INTERNATIONAL
char buf[FILE_MAX];
+#endif
ob= OBACT;
@@ -709,7 +715,12 @@ void do_global_buttons(unsigned short event)
else return;
if(*menunr== -2) {
- activate_databrowse((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons);
+ if(G.qual & LR_CTRLKEY) {
+ activate_databrowse_imasel((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons);
+ }
+ else {
+ activate_databrowse((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons);
+ }
return;
}
@@ -854,8 +865,12 @@ void do_global_buttons(unsigned short event)
if(mtex) id= (ID *)mtex->tex;
}
}
-
- activate_databrowse(id, ID_TE, 0, B_TEXBROWSE, &G.buts->texnr, do_global_buttons);
+ if(G.qual & LR_CTRLKEY) {
+ activate_databrowse_imasel(id, ID_TE, 0, B_TEXBROWSE, &G.buts->texnr, do_global_buttons);
+ }
+ else {
+ activate_databrowse(id, ID_TE, 0, B_TEXBROWSE, &G.buts->texnr, do_global_buttons);
+ }
return;
}
if(G.buts->texnr < 0) break;
@@ -919,20 +934,21 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
break;
case B_ACTIONBROWSE:
if (!ob)
break;
act=ob->action;
id= (ID *)act;
-
+
if (G.saction->actnr== -2){
activate_databrowse((ID *)G.saction->action, ID_AC, 0, B_ACTIONBROWSE, &G.saction->actnr, do_global_buttons);
return;
}
-
+
if(G.saction->actnr < 0) break;
-
+
/* See if we have selected a valid action */
for (idtest= G.main->action.first; idtest; idtest= idtest->next) {
if(nr==G.saction->actnr) {
@@ -943,19 +959,58 @@ void do_global_buttons(unsigned short event)
}
if(G.saction->pin) {
- G.saction->action= (bAction *)idtest;
+ if (idtest == NULL) {
+ /* assign new/copy of pinned action only - messy as it doesn't assign to any obj's */
+ if (G.saction->action)
+ G.saction->action= (bAction *)copy_action(G.saction->action);
+ else
+ G.saction->action= (bAction *)add_empty_action("PinnedAction");
+ }
+ else {
+ G.saction->action= (bAction *)idtest;
+ }
allqueue(REDRAWACTION, 0);
}
else {
/* Store current action */
- if (!idtest){
+ if (!idtest) {
+ /* 'Add New' option:
+ * - make a copy of an exisiting action
+ * - or make a new empty action if no existing action
+ */
if (act) {
idtest= (ID *)copy_action(act);
- } else {
+ }
+ else {
if (ID_OB==ob->type) {
+ /* for empties */
idtest=(ID *)add_empty_action("ObAction");
- } else {
+ }
+ else if (ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
+ /* shapekey - like if B_IPO_ACTION_KEY is triggered */
+ bActionChannel *achan;
+ Key *key= ob_get_key(ob);
+
+ ob->ipoflag |= OB_ACTION_KEY;
+
+ act = add_empty_action("ShapeAction");
+ idtest=(ID *)act;
+
+ achan= verify_action_channel(act, "Shape");
+ achan->flag = (ACHAN_HILIGHTED|ACHAN_SELECTED|ACHAN_EXPANDED|ACHAN_SHOWIPO);
+
+ if(achan->ipo==NULL && key->ipo) {
+ achan->ipo= key->ipo;
+ key->ipo= NULL;
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWOOPS, 0);
+ }
+ }
+ else {
+ /* a plain action */
idtest=(ID *)add_empty_action("Action");
}
}
@@ -978,6 +1033,7 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWNLA, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWHEADERS, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
}
@@ -1032,6 +1088,8 @@ void do_global_buttons(unsigned short event)
else if(nr==ID_LA) idtest= (ID *)add_ipo("LaIpo", nr);
else if(nr==ID_CA) idtest= (ID *)add_ipo("CaIpo", nr);
else if(nr==ID_SO) idtest= (ID *)add_ipo("SndIpo", nr);
+ else if(nr==ID_FLUIDSIM) idtest= (ID *)add_ipo("FluidsimIpo", nr);
+ else if(nr==ID_PA) idtest= (ID *)add_ipo("PaIpo", nr);
else error("Warn bugtracker!");
}
idtest->us--;
@@ -1262,18 +1320,16 @@ void do_global_buttons(unsigned short event)
break;
case B_IMAGEDELETE:
-
- if(G.sima->image && BLI_streq(G.sima->image->id.name+2, "Render Result")==0) {
- /* Run on non render images, unlink normally */
- G.sima->image= NULL;
- image_changed(G.sima, 0);
- BIF_undo_push("Unlink Image");
- allqueue(REDRAWIMAGE, 0);
- } else {
+ if(G.sima->image && (G.sima->image->type == IMA_TYPE_R_RESULT || G.sima->image->type == IMA_TYPE_COMPOSITE)) {
/* Run if G.sima is render, remove the render and display the meshes image if it exists */
G.sima->image= NULL;
what_image(G.sima);
allqueue(REDRAWIMAGE, 0);
+ } else {
+ /* Run on non render images, unlink normally */
+ image_changed(G.sima, NULL);
+ BIF_undo_push("Unlink Image");
+ allqueue(REDRAWIMAGE, 0);
}
break;
@@ -1439,6 +1495,7 @@ void do_global_buttons(unsigned short event)
case B_PYMENUEVAL: /* is button from space.c *info* */
waitcursor( 1 ); /* can take some time */
BPyMenu_RemoveAllEntries(); /* free old data */
+ BPY_rebuild_syspath();
if (BPyMenu_Init(1) == -1) { /* re-eval scripts registration in menus */
waitcursor( 0 );
error("Invalid scripts dir: check console");
@@ -1651,7 +1708,8 @@ void do_global_buttons2(short event)
if(act->id.lib) {
if(okee("Make local")) {
make_local_action(act);
- allqueue(REDRAWACTION,0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
}
}
@@ -1659,12 +1717,13 @@ void do_global_buttons2(short event)
case B_ACTALONE:
if(ob && ob->id.lib==0) {
act= ob->action;
-
+
if(act->id.us>1) {
if(okee("Single user")) {
ob->action=copy_action(act);
act->id.us--;
allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
}
}
diff --git a/source/blender/src/imagepaint.c b/source/blender/src/imagepaint.c
index 3809d731473..7b8efd0ed75 100644
--- a/source/blender/src/imagepaint.c
+++ b/source/blender/src/imagepaint.c
@@ -559,6 +559,9 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
ImBuf *ibuf= BKE_image_get_ibuf(image, G.sima?&G.sima->iuser:NULL);
float pos[2];
+ if(!ibuf)
+ return 0;
+
pos[0] = uv[0]*ibuf->x;
pos[1] = uv[1]*ibuf->y;
diff --git a/source/blender/src/imasel.c b/source/blender/src/imasel.c
index 6c232ea6464..78fc3f1be2a 100644
--- a/source/blender/src/imasel.c
+++ b/source/blender/src/imasel.c
@@ -57,864 +57,29 @@
#include "BKE_global.h"
#include "BIF_imasel.h"
+#include "BIF_filelist.h"
#include "BIF_space.h"
#include "BIF_screen.h"
#include "blendef.h"
#include "mydevice.h"
-#ifndef WIN32
-#include <dirent.h>
-#endif
-
-#include <sys/stat.h>
-#include "datatoc.h"
-
-/* locals */
-void longtochar(char *des, unsigned int *src, int size);
-void chartolong(unsigned int *des, char *src, int size);
-int dir_compare(const void *a1, const void *a2);
-void issort( int te, ImaDir **firstentry);
-int ima_compare(const void *a1, const void *a2);
-void imsort(OneSelectableIma **firstentry);
-void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima);
-void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry);
-
-/* implementation */
-int bitset(int l, int bit)
-{ return (( l & bit) == bit); }
-
-void longtochar(char *des, unsigned int *src, int size)
-{ int i;for (i = 0; i<size; i++){ des[i] = src[i] & 0xFF; }}
-
-void chartolong(unsigned int *des, char *src, int size)
-{ int i;for (i = 0; i<size; i++){ des[i] = src[i]; }}
-
-int dir_compare(const void *a1, const void *a2)
-{
- ImaDir **in1, **in2;
- ImaDir *use1, *use2;
-
- in1= (ImaDir **)a1;
- in2= (ImaDir **)a2;
-
- use1 = *in1;
- use2 = *in2;
-
- return BLI_strcasecmp(use1->name, use2->name);
-}
-
-void issort( int te, ImaDir **firstentry)
-{
- ImaDir **sort;
- ImaDir *use;
- int i = 0;
-
- sort = MEM_mallocN(te * sizeof(void *), "dir Sorteer temp");
- use = *firstentry;
-
- while (use){
- sort[i++] = use;
- use = use->next;
- }
-
- qsort (sort, te, sizeof(void *), dir_compare);
-
- *firstentry = sort[0];
- use = *firstentry;
-
-
- for (i=0; i<te; i++){
- if (i != 0) use->prev = sort[i-1]; else use->prev = 0;
- if (i != te-1) use->next = sort[i+1]; else use->next = 0;
-
- use = use->next;
- }
-
- MEM_freeN(sort);
-}
-
-
-int ima_compare(const void *a1, const void *a2)
-{
- OneSelectableIma **in1, **in2;
- OneSelectableIma *use1, *use2;
-
- in1= (OneSelectableIma **)a1;
- in2= (OneSelectableIma **)a2;
-
- use1 = *in1; use2 = *in2;
- return BLI_strcasecmp(use1->file_name, use2->file_name);
-}
-
-void imsort(OneSelectableIma **firstentry)
-{
- OneSelectableIma **sort;
- OneSelectableIma *use;
- int tot = 0, i = 0;
-
- use = *firstentry;
- while (use){
- tot++;
- use = use->next;
- }
-
- if (tot){
- sort = MEM_mallocN(tot * sizeof(void *), "Sorteer imsort temp");
- use = *firstentry;
- while (use){
- sort[i++] = use;
- use = use->next;
- }
-
- qsort (sort, tot, sizeof(void *), ima_compare);
-
- *firstentry = sort[0];
- use = *firstentry;
- for (i=0; i<tot; i++){
- if (i != 0) use->prev = sort[i-1]; else use->prev = 0;
- if (i != tot-1) use->next = sort[i+1]; else use->next = 0;
-
- use = use->next;
- }
- MEM_freeN(sort);
- }
-}
-
-static int write_msb_int(int fd, int i) {
- unsigned int ui= (unsigned int) i;
- unsigned char buf[4];
- buf[0]= (ui>>24)&0xFF;
- buf[1]= (ui>>16)&0xFF;
- buf[2]= (ui>>8)&0xFF;
- buf[3]= (ui>>0)&0xFF;
- return write(fd, buf, 4);
-}
-static int write_msb_short(int fd, short s) {
- unsigned short us= (unsigned short) s;
- unsigned char buf[2];
- buf[0]= (us>>8)&0xFF;
- buf[1]= (us>>0)&0xFF;
- return write(fd, buf, 2);
-}
-
-static int read_msb_int(int fd, int *i_r) {
- unsigned char buf[4];
- int rcount= read(fd, buf, 4);
-
- if (i_r)
- *i_r= (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0);
-
- return rcount;
-}
-static int read_msb_short(int fd, short *s_r) {
- unsigned char buf[2];
- int rcount= read(fd, buf, 2);
-
- if (s_r)
- *s_r= (buf[0]<<8)|(buf[1]<<0);
-
- return rcount;
-}
-
-void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima)
-{
- int file;
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- if ( bitset (simasel->fase, IMS_WRITE_NO_BIP)) return;
-
- strcpy(name, simasel->dir);
- strcat(name, ".Bpib");
-
- file = open(name, O_BINARY|O_APPEND | O_RDWR | O_CREAT, 0666);
- if (file == -1) {
- /* printf("Could not write .Bpib file in dir %s\n", simasel->dir); */
- simasel->fase |= IMS_WRITE_NO_BIP;
- return;
- }
-
- lseek(file, 0, SEEK_END);
-
- write(file, "BIP2", 4);
- write_msb_int(file, ima->ibuf_type);
- write_msb_int(file, 0);
- write_msb_int(file, 0);
- write_msb_int(file, 0);
- write_msb_short(file, ima->cmap);
- write_msb_short(file, ima->image);
- write_msb_short(file, ima->draw_me);
- write_msb_short(file, ima->rt);
- write_msb_short(file, ima->sx);
- write_msb_short(file, ima->sy);
- write_msb_short(file, ima->ex);
- write_msb_short(file, ima->ey);
- write_msb_short(file, ima->dw);
- write_msb_short(file, ima->dh);
- write_msb_short(file, ima->selectable);
- write_msb_short(file, ima->selected);
- write_msb_int(file, ima->mtime);
- write_msb_int(file, ima->disksize);
- write(file, ima->file_name, 64);
- write_msb_short(file, ima->orgx);
- write_msb_short(file, ima->orgy);
- write_msb_short(file, ima->orgd);
- write_msb_short(file, ima->anim);
- write_msb_int(file, 0); /* pad to 128 boundary */
- write(file, ima->pict_rect, 3968);
-
- close(file);
-}
-
-void write_new_pib(SpaceImaSel *simasel)
-{
- OneSelectableIma *ima;
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- strcpy(name, simasel->dir);
- strcat(name, ".Bpib");
- remove(name);
-
- ima = simasel->first_sel_ima;
- while (ima) {
- append_pib(simasel, ima);
- ima = ima->next;
- }
-}
-
-void free_ima_dir(ImaDir *firstdir)
-{
- ImaDir *n;
-
- while(firstdir){
- n = firstdir->next;
- MEM_freeN(firstdir);
- firstdir = n;
- }
-}
-void free_sel_ima(OneSelectableIma *firstima)
-{
- OneSelectableIma *n;
-
- while(firstima){
-
- if (firstima->pict) {
- IMB_freeImBuf(firstima->pict);
- }
- n = firstima->next;
- MEM_freeN(firstima);
- firstima = n;
- }
-}
-
-void check_for_pib(SpaceImaSel *simasel)
-{
- ImaDir *direntry;
-
- direntry = simasel->firstfile;
- while(direntry){
- if ((strlen(direntry->name) > 4) && (0==strcmp(direntry->name, ".Bpib")) ){
- simasel->fase |= IMS_FOUND_BIP;
- direntry = 0;
- }else{
- direntry = direntry->next;
- }
- }
-}
-
-void clear_ima_dir(SpaceImaSel *simasel)
-{
- if(simasel->first_sel_ima) free_sel_ima(simasel->first_sel_ima);
- if(simasel->firstdir) free_ima_dir(simasel->firstdir);
- if(simasel->firstfile) free_ima_dir(simasel->firstfile);
-
- simasel->first_sel_ima = 0;
- simasel->firstdir = 0;
- simasel->firstfile = 0;
-
- simasel->totaldirs = 0;
- simasel->totalfiles = 0;
- simasel->totalima = 0;
- simasel->topdir = -1;
- simasel->topfile = -1;
- simasel->topima = 0;
- simasel->image_slider = 0.0;
- simasel->slider_height = 0.0;
- simasel->slider_space = 0.0;
- simasel->hilite = -1;
- simasel->curimax = 0;
- simasel->curimay = 0;
-
- simasel->total_selected = 0;
- simasel->fase = 0;
- simasel->subfase = 0;
- simasel->imafase = 0;
- simasel->ima_redraw = 0;
-}
-
-int get_ima_dir(char *dirname, int dtype, int *td, ImaDir **first)
-{
- DIR *dirp;
- struct dirent *dep;
- struct ImaDir *temp;
- struct ImaDir *dnext = NULL, *fnext;
- struct stat status;
- char olddir[FILE_MAXDIR+FILE_MAXFILE];
- char getdirname[FILE_MAXDIR+FILE_MAXFILE];
- int /* i=0, */ tot=0;
- int isdir;
-
- if(!BLI_getwdN(olddir)) return -1;
-
- if (chdir(dirname) == -1) return(-1);
-
- strcpy(getdirname, ".");
-
- dirp = (DIR *) opendir(getdirname);
- if (dirp == NULL) return (-1);
-
- waitcursor(1);
-
- while((dep = (struct dirent*) readdir(dirp)) != NULL){
-
- strcpy(getdirname, dirname);
- strcat(getdirname,dep->d_name);
-
- stat(getdirname, &status);
- isdir = S_ISDIR(status.st_mode);
-
- if ( ((dtype == IMS_DIR) && isdir) || ((dtype == IMS_FILE) && !isdir)){
- /* yes, searching for this type */
- tot++;
- if (tot == 1){
- dnext = MEM_callocN(sizeof(struct ImaDir), "get first");
- *first = dnext;
-
- dnext->prev = 0;
- dnext->next = 0;
- }else{
- fnext = MEM_callocN(sizeof(struct ImaDir), "get nextdir");
- dnext->next = fnext;
-
- temp = dnext;
- dnext = fnext;
-
- dnext ->prev = temp;
- dnext ->next = 0;
- }
-
- dnext->type = dtype;
- dnext->selected = 0;
- dnext->hilite = 0;
-
- dnext->mtime = status.st_ctime;
- dnext->size = (int)status.st_size;
- strcpy(dnext->name, dep->d_name);
- }
- }
- closedir(dirp);
-
- if (tot) issort(tot, first);
-
- waitcursor(0);
-
- *td = tot;
-
- chdir (olddir);
-
- return (tot);
-}
-
-void imadir_parent(SpaceImaSel *simasel)
-{
-
-#ifdef WIN32
- if (strlen(simasel->dir) > 1){
- simasel->dir[strlen(simasel->dir)-1] = 0;
- while(simasel->dir[strlen(simasel->dir)-1] != '\\'){
- if(strlen(simasel->dir)==0) break;
- simasel->dir[strlen(simasel->dir)-1] = 0;
- }
- }
-#else
- if (strlen(simasel->dir) > 1){
- simasel->dir[strlen(simasel->dir)-1] = 0;
- while(simasel->dir[strlen(simasel->dir)-1] != '/') {
- if(strlen(simasel->dir)==0) break;
- simasel->dir[strlen(simasel->dir)-1] = 0;
- }
- }
-#endif
-}
-
-
-void get_next_image(SpaceImaSel *simasel)
-{
- OneSelectableIma * ima;
- ImBuf * ibuf;
- struct anim * anim;
- int i = 0, size;
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- ima = simasel->first_sel_ima;
- if (ima == 0){
- simasel->imafase = 0;
- simasel->fase |= IMS_KNOW_IMA;
- simasel->fase &= ~IMS_DOTHE_IMA;
- return;
- }
- if (simasel->imafase > simasel->totalima){
- simasel->imafase = 0;
- simasel->fase &= ~IMS_DOTHE_IMA;
- simasel->fase |= IMS_KNOW_IMA;
- }
-
- ima = simasel->first_sel_ima;
- i = 0;
- while(i < simasel->imafase){
- if ((ima) && (ima->next)) ima = ima->next;
- i++;
- }
-
- if (ima->image == 0) {
- if (ima->anim == 1) {
- /* open movie, get len, get middle picture */
-
- strcpy(name, simasel->dir);
- strcat(name, ima->file_name);
-
- anim = IMB_open_anim(name, IB_rect);
-
- if (anim == 0) {
- // ibuf= IMB_loadiffmem((int*)datatoc_cmovie_tga, IB_rect);
- ibuf= IMB_ibImageFromMemory((int *)datatoc_cmovie_tga, datatoc_cmovie_tga_size, IB_rect);
- }
- else{
- int animlen;
-
- ibuf = IMB_anim_nextpic(anim);
- IMB_freeImBuf(ibuf);
-
- animlen= IMB_anim_get_duration(anim);
- ibuf = IMB_anim_absolute(anim, animlen / 2);
-
- if(ibuf) {
- //get icon dimensions for movie
- ima->orgx = ibuf->x;
- ima->orgy = ibuf->y;
-// ima->orgd = ibuf->depth;
-
- if (ima->orgx > ima->orgy){
- ima->dw = 64;
- ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx));
- }else{
- ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy));
- ima->dh = 62;
- }
- }
-
- IMB_free_anim(anim);
- }
- }
- else {
-
- strcpy(name, simasel->dir);
- strcat(name, ima->file_name);
-
- ibuf = IMB_loadiffname(name, IB_rect);
- if(ibuf && ibuf->zbuf) IMB_freezbufImBuf(ibuf);
- }
-
- if (ibuf){
- if (ima->dw < 4) ima->dw = 4;
- if (ima->dh < 4) ima->dh = 4;
-
- IMB_scaleImBuf(ibuf, ima->dw, ima->dh);
- /* the whole cmap system is wacko */
-
- if (G.order==B_ENDIAN)
- IMB_convert_rgba_to_abgr(ibuf);
-
- ibuf->mincol = 0;
- ibuf->maxcol = 256;
- ibuf->cbits = 5;
- ibuf->depth = 8;
-
- IMB_freecmapImBuf(ibuf);
- ibuf->cmap = simasel->cmap->cmap;
-
- IMB_converttocmap(ibuf);
-
- /* copy ibuf->rect to ima->pict_rect */
- size = ima->dw * ima->dh; if (size > 3968) size = 3968;
- longtochar(ima->pict_rect, ibuf->rect, size);
-
- IMB_applycmap(ibuf);
- IMB_convert_rgba_to_abgr(ibuf);
-
- if (ima->pict) IMB_freeImBuf(ima->pict);
- ima->pict = ibuf;
- ibuf = 0;
- ima->cmap = 1;
- ima->image = 1;
-
- append_pib(simasel, ima);
- }
- }
- simasel->ima_redraw++;
- simasel->imafase ++;
- if (simasel->imafase == simasel->totalima){
- simasel->imafase = 0;
- simasel->fase &= ~IMS_DOTHE_IMA;
- simasel->fase |= IMS_KNOW_IMA;
- }
-}
-
-void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry)
-{
- OneSelectableIma *ima, *prev_ima;
- ImBuf *ibuf;
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- strcpy(name , simasel->dir);
- strcat(name , direntry->name);
-
- prev_ima = simasel->first_sel_ima;
- while((prev_ima)&&(prev_ima->next)){
- prev_ima = prev_ima->next;
- }
-
- ima = MEM_callocN(sizeof(OneSelectableIma), "OSIbip");
- if (direntry->type == IMS_IMA){
- /* Picture is an Image */
- ibuf = IMB_loadiffname(name, IB_test);
- if (ibuf){
- ima->anim = 0;
- ima->pict = ibuf;
- ima->ibuf_type= ibuf->ftype;
- ima->orgx = ibuf->x;
- ima->orgy = ibuf->y;
- ima->orgd = ibuf->depth;
-
- ima->dw = 64;
- ima->dh = 51;
- ima->cmap = 0;
- ima->image = 0;
- if (ima->orgx > ima->orgy){
- ima->dw = 64;
- ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx));
- }else{
- ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy));
- ima->dh = 62;
- }
- }else{
- printf("%s image with no imbuf ???\n", name);
- }
- ibuf = 0;
- }else{
- /* Picture is an Animation */
-
- ima->pict = 0;
- ima->anim = 1;
- ima->ibuf_type= 0;
- ima->orgx = 64;
- ima->orgy = 51;
- ima->orgd = 24;
-
- ima->dw = 64;
- ima->dh = 51;
- ima->cmap = 0;
- ima->image = 0;
- }
-
- strcpy(name, direntry->name); name[63] = 0;
- strcpy(ima->file_name, name);
- ima->disksize = (int)direntry->size;
- ima->mtime = (int)direntry->mtime;
-
- ima->next = 0;
- ima->prev = prev_ima;
-
- if (prev_ima) {
- prev_ima->next = ima;
- }else{
- simasel->first_sel_ima = ima;
- }
-
- simasel->ima_redraw++;
- simasel->totalima++;
-}
-
-
-void get_file_info(SpaceImaSel *simasel)
-{
- OneSelectableIma *prev_ima;
- ImaDir *direntry;
- char name[FILE_MAXDIR+FILE_MAXFILE];
- int i = 0;
-
- if (!simasel->firstfile){
- simasel->subfase = 0;
- simasel->fase |= IMS_KNOW_INF;
- simasel->fase &= ~IMS_DOTHE_INF;
- return;
- }
- if (simasel->subfase > simasel->totalfiles){
- simasel->subfase = 0;
- simasel->fase |= IMS_KNOW_INF;
- simasel->fase &= ~IMS_DOTHE_INF;
- }
-
- direntry = simasel->firstfile;
- while(i < simasel->subfase){
- direntry = direntry->next;
- i++;
- }
-
- prev_ima = simasel->first_sel_ima;
- while((prev_ima)&&(prev_ima->next)){
- prev_ima = prev_ima->next;
- }
-
- strcpy(name , simasel->dir);
- strcat(name , direntry->name);
-
- if(direntry->name[0] == '.') {
- direntry->type = IMS_NOIMA;
- } else {
- if (IMB_ispic(name)) {
- direntry->type = IMS_IMA;
- }else{
- if (IMB_isanim(name)) {
- direntry->type = IMS_ANIM;
- }else{
- direntry->type = IMS_NOIMA;
- }
- }
- }
-
- if (direntry->type != IMS_NOIMA){
- add_ima(1, simasel, direntry);
- }
-
- simasel->subfase++;
-
- if (simasel->subfase == simasel->totalfiles){
- simasel->subfase = 0;
- simasel->fase |= IMS_KNOW_INF;
- simasel->fase &= ~IMS_DOTHE_INF;
- }
-}
-
-/* Note: the thumbnails are saved in ABGR format in the .Bpib
-cache file */
-
-void get_pib_file(SpaceImaSel *simasel)
-{
- ImaDir *direntry, *prev_dir, *next_dir;
- OneSelectableIma *ima, *prev_ima;
- int flen;
- int dl, file, first, trd=0, rd, size, found, ima_added = 0;
- char name[FILE_MAXDIR+FILE_MAXFILE];
-
- if (bitset(simasel->fase , IMS_KNOW_BIP)) return;
-
- waitcursor(1);
-
- strcpy(name, simasel->dir);
- strcat(name, ".Bpib");
-
- file = open(name, O_BINARY|O_RDONLY);
-
- flen = BLI_filesize(file);
-
- simasel->totalima = 0;
- prev_ima = 0;
- first = 1;
- trd = 0;
-
- while(trd < flen){
- char header[5];
-
- ima = MEM_callocN(sizeof(OneSelectableIma), "Ima");
-
- rd= 0;
- rd+= read(file, header, 4);
- rd+= read_msb_int(file, &ima->ibuf_type);
- rd+= read_msb_int(file, NULL);
- rd+= read_msb_int(file, NULL);
- rd+= read_msb_int(file, NULL);
- rd+= read_msb_short(file, &ima->cmap);
- rd+= read_msb_short(file, &ima->image);
- rd+= read_msb_short(file, &ima->draw_me);
- rd+= read_msb_short(file, &ima->rt);
- rd+= read_msb_short(file, &ima->sx);
- rd+= read_msb_short(file, &ima->sy);
- rd+= read_msb_short(file, &ima->ex);
- rd+= read_msb_short(file, &ima->ey);
- rd+= read_msb_short(file, &ima->dw);
- rd+= read_msb_short(file, &ima->dh);
- rd+= read_msb_short(file, &ima->selectable);
- rd+= read_msb_short(file, &ima->selected);
- rd+= read_msb_int(file, &ima->mtime);
- rd+= read_msb_int(file, &ima->disksize);
- rd+= read(file, ima->file_name, 64);
- rd+= read_msb_short(file, &ima->orgx);
- rd+= read_msb_short(file, &ima->orgy);
- rd+= read_msb_short(file, &ima->orgd);
- rd+= read_msb_short(file, &ima->anim);
- rd+= read_msb_int(file, NULL);
- rd+= read(file, ima->pict_rect, 3968);
-
- found = 0;
-
- if (rd != sizeof(OneSelectableIma) || memcmp(header, "BIP2", 4)!=0) {
- printf("Error in Bpib file\n");
- strcpy(name, simasel->dir);
- strcat(name, ".Bpib");
- dl = remove(name);
- if (dl == 0) printf("corrupt Bpib file removed\n");
- trd = flen;
- } else {
- /* find matching direntry (if possible) */
- for (direntry= simasel->firstfile; direntry; direntry= direntry->next)
- if (BLI_streq(direntry->name, ima->file_name))
- break;
-
- if (direntry) {
- if (direntry->mtime == ima->mtime) {
- /* ima found and same, load pic */
- size = ima->dw * ima->dh;
- if (size > 3968) size = 3968;
- if (size) {
- ima->pict = IMB_allocImBuf(ima->dw, ima->dh, 24, IB_rect | IB_cmap, 0);
- chartolong(ima->pict->rect, ima->pict_rect, size);
- ima->pict->cmap = simasel->cmap->cmap;
- ima->pict->maxcol = 256;
- IMB_applycmap(ima->pict);
- IMB_convert_rgba_to_abgr(ima->pict);
- }
- ima->selected = 0;
- ima->selectable = 0;
-
- if(prev_ima) prev_ima->next = ima;
- ima->next = 0;
- ima->prev = prev_ima;
-
- prev_ima = ima;
-
- if (first){ first = 0;simasel->first_sel_ima = ima; }
- simasel->totalima++;
- found = 1;
- }
-
- /* remove direntry */
- prev_dir = direntry->prev;
- next_dir = direntry->next;
-
- if(prev_dir) prev_dir->next = next_dir;
- if(next_dir) next_dir->prev = prev_dir;
-
- MEM_freeN(direntry);
- }
- }
- if (!found) MEM_freeN(ima);
-
- trd+=rd;
- }
- close(file);
-
- direntry = simasel->firstfile;
-
- while(direntry){
-
- strcpy(name , simasel->dir);
- strcat(name , direntry->name);
-
- if (IMB_ispic(name)) {
- direntry->type = IMS_IMA;
- }else{
- if (IMB_isanim(name)) {
- direntry->type = IMS_ANIM;
- }else{
- direntry->type = IMS_NOIMA;
- }
- }
-
- if (direntry->type != IMS_NOIMA){
- prev_ima = simasel->first_sel_ima;
- while((prev_ima)&&(prev_ima->next)){
- prev_ima = prev_ima->next;
- }
- add_ima(2, simasel, direntry);
- ima_added = 1;
- }
- direntry = direntry->next;
- }
-
- imsort(&simasel->first_sel_ima);
-
- simasel->fase |= IMS_KNOW_BIP;
- simasel->fase |= IMS_KNOW_INF;
- simasel->fase |= IMS_KNOW_IMA;
-
- if (ima_added){
- simasel->fase |= IMS_DOTHE_IMA;
- simasel->fase &= ~IMS_KNOW_IMA;
- addafterqueue(curarea->win, AFTERIMASELGET, 1);
- }else{
- write_new_pib(simasel);
- }
-
- waitcursor(0);
-}
-
-void change_imadir(SpaceImaSel *simasel)
+void free_imasel(SpaceImaSel *simasel)
{
- ImaDir *direntry;
- int i;
-
- direntry = simasel->firstdir;
- for (i=0; i<simasel->hilite; i++){
- direntry = direntry->next;
+ /* do not free imasel itself */
+ if(simasel->files) {
+ BIF_filelist_freelib(simasel->files);
+ BIF_filelist_free(simasel->files);
+ MEM_freeN(simasel->files);
+ simasel->files = NULL;
}
-
- if(direntry==NULL);
- else if (direntry->name[0] != '.'){
- strcat(simasel->dir, direntry->name);
- strcat(simasel->dir, "/");
+ if (simasel->img) {
+ IMB_freeImBuf(simasel->img);
}
- else {
- if (direntry->name[1] == '.'){
- imadir_parent(simasel);
- }
+ if(simasel->pupmenu) {
+ MEM_freeN(simasel->pupmenu);
+ simasel->pupmenu = NULL;
}
-
- clear_ima_dir(simasel);
-}
-
-void check_imasel_copy(SpaceImaSel *simasel)
-{
-
- /* WATCH IT: also used when reading blender file */
- /* initialize stuff, malloc, etc */
- simasel->first_sel_ima = 0;
- simasel->hilite_ima = 0;
- simasel->firstdir = 0;
- simasel->firstfile = 0;
- simasel->cmap = 0;
- clear_ima_dir(simasel);
-
- // simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap);
- simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap);
-}
-
-void free_imasel(SpaceImaSel *simasel)
-{
- /* do not free imasel itself */
-
- clear_ima_dir(simasel);
- IMB_freeImBuf(simasel->cmap);
}
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index 56e2c6326b7..6513a3a2a4e 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -135,6 +135,7 @@ uiBut *UIbuttip;
static char but_copypaste_str[256]="";
static double but_copypaste_val=0.0;
static float but_copypaste_rgb[3];
+static ColorBand but_copypaste_coba;
/* ************* PROTOTYPES ***************** */
@@ -482,6 +483,7 @@ static int ui_but_copy_paste(uiBut *but, char mode)
}
else {
ui_set_but_val(but, but_copypaste_val);
+ uibut_do_func(but);
ui_check_but(but);
return 1;
}
@@ -524,7 +526,6 @@ static int ui_but_copy_paste(uiBut *but, char mode)
}
}
else if(but->type==TEX) {
-
if(poin==NULL);
else if(mode=='c') {
strncpy(but_copypaste_str, but->poin, but->max);
@@ -544,7 +545,6 @@ static int ui_but_copy_paste(uiBut *but, char mode)
}
}
else if(but->type==IDPOIN) {
-
if(mode=='c') {
ID *id= *but->idpoin_idpp;
if(id) strncpy(but_copypaste_str, id->name+2, 22);
@@ -555,8 +555,24 @@ static int ui_but_copy_paste(uiBut *but, char mode)
return 1;
}
}
-
-
+ else if(but->type==BUT_COLORBAND) {
+ if(mode=='c') {
+ if (!but->poin) {
+ return 0;
+ }
+ memcpy( &but_copypaste_coba, but->poin, sizeof(ColorBand) );
+ } else {
+ if (but_copypaste_coba.tot==0) {
+ return 0;
+ }
+ if (!but->poin) {
+ but->poin= MEM_callocN( sizeof(ColorBand), "colorband");
+ }
+ memcpy( but->poin, &but_copypaste_coba, sizeof(ColorBand) );
+ return 1;
+ }
+ }
+
return 0;
}
@@ -621,7 +637,7 @@ void uiBoundsBlock(uiBlock *block, int addval)
if(bt->x1 < block->minx) block->minx= bt->x1;
if(bt->y1 < block->miny) block->miny= bt->y1;
- if(bt->x2 > block->maxx) block->maxx= bt->x2;
+ if(bt->x2 > block->maxx) block->maxx= bt->x2;
if(bt->y2 > block->maxy) block->maxy= bt->y2;
bt= bt->next;
@@ -1288,7 +1304,7 @@ static int ui_do_but_MENU(uiBut *but)
for(bt= block->buttons.first; bt; bt= bt->next) bt->win= block->win;
bwin_getsinglematrix(block->win, block->winmat);
- event= uiDoBlocks(&listb, 0);
+ event= uiDoBlocks(&listb, 0, 1);
menudata_free(md);
@@ -2335,7 +2351,7 @@ static int ui_do_but_ICONROW(uiBut *but)
this is needs better implementation */
block->win= G.curscreen->mainwin;
- uiDoBlocks(&listb, 0);
+ uiDoBlocks(&listb, 0, 1);
but->flag &= ~UI_SELECT;
ui_check_but(but);
@@ -2408,7 +2424,7 @@ static int ui_do_but_ICONTEXTROW(uiBut *but)
uiBoundsBlock(block, 3);
- uiDoBlocks(&listb, 0);
+ uiDoBlocks(&listb, 0, 1);
menudata_free(md);
@@ -2671,12 +2687,36 @@ static uiBlock *ui_do_but_BLOCK(uiBut *but, int event)
static int ui_do_but_BUTM(uiBut *but)
{
-
+ /* draw 'pushing-in' when clicked on for use as a normal button in a panel */
+ do {
+ int oflag= but->flag;
+ short mval[2];
+
+ uiGetMouse(mywinget(), mval);
+
+ if (uibut_contains_pt(but, mval))
+ but->flag |= UI_SELECT;
+ else
+ but->flag &= ~UI_SELECT;
+
+ if (but->flag != oflag) {
+ ui_draw_but(but);
+ ui_block_flush_back(but->block);
+ }
+
+ PIL_sleep_ms(10);
+ } while (get_mbut() & L_MOUSE);
+
ui_set_but_val(but, but->min);
UIafterfunc_butm= but->butm_func;
UIafterfunc_arg1= but->butm_func_arg;
UIafterval= but->a2;
+ uibut_do_func(but);
+
+ but->flag &= ~UI_SELECT;
+ ui_draw_but(but);
+
return but->retval;
}
@@ -3286,7 +3326,7 @@ static int ui_do_but_COL(uiBut *but)
for(bt= block->buttons.first; bt; bt= bt->next) bt->win= block->win;
bwin_getsinglematrix(block->win, block->winmat);
- event= uiDoBlocks(&listb, 0);
+ event= uiDoBlocks(&listb, 0, 1);
if(but->pointype==CHA) ui_set_but_vectorf(but, colstore);
@@ -4290,7 +4330,7 @@ int uiIsMenu(int *x, int *y, int *sizex, int *sizey)
* UI_CONT don't pass event to other ui's
* UI_RETURN something happened, return, swallow event
*/
-static int ui_do_block(uiBlock *block, uiEvent *uevent)
+static int ui_do_block(uiBlock *block, uiEvent *uevent, int movemouse_quit)
{
uiBut *but, *bt;
int butevent, event, retval=UI_NOTHING, count, act=0;
@@ -4432,21 +4472,13 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
}
break;
- case PAD8: case PAD2:
case UPARROWKEY:
case DOWNARROWKEY:
if(inside || (block->flag & UI_BLOCK_LOOP)) {
/* arrowkeys: only handle for block_loop blocks */
event= 0;
- if(block->flag & UI_BLOCK_LOOP) {
+ if(block->flag & UI_BLOCK_LOOP)
event= uevent->event;
- if(event==PAD8) event= UPARROWKEY;
- if(event==PAD2) event= DOWNARROWKEY;
- }
- else {
- if(uevent->event==PAD8) event= UPARROWKEY;
- if(uevent->event==PAD2) event= DOWNARROWKEY;
- }
if(event && uevent->val) {
for(but= block->buttons.first; but; but= but->next) {
@@ -4475,7 +4507,6 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
/* nothing done */
if(but==NULL) {
-
if(event==UPARROWKEY) {
if(block->direction & UI_TOP) but= ui_but_first(block);
else but= ui_but_last(block);
@@ -4494,16 +4525,26 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
}
break;
- case ONEKEY: act= 1;
- case TWOKEY: if(act==0) act= 2;
- case THREEKEY: if(act==0) act= 3;
- case FOURKEY: if(act==0) act= 4;
- case FIVEKEY: if(act==0) act= 5;
- case SIXKEY: if(act==0) act= 6;
- case SEVENKEY: if(act==0) act= 7;
- case EIGHTKEY: if(act==0) act= 8;
- case NINEKEY: if(act==0) act= 9;
- case ZEROKEY: if(act==0) act= 10;
+ case ONEKEY: case PAD1:
+ act= 1;
+ case TWOKEY: case PAD2:
+ if(act==0) act= 2;
+ case THREEKEY: case PAD3:
+ if(act==0) act= 3;
+ case FOURKEY: case PAD4:
+ if(act==0) act= 4;
+ case FIVEKEY: case PAD5:
+ if(act==0) act= 5;
+ case SIXKEY: case PAD6:
+ if(act==0) act= 6;
+ case SEVENKEY: case PAD7:
+ if(act==0) act= 7;
+ case EIGHTKEY: case PAD8:
+ if(act==0) act= 8;
+ case NINEKEY: case PAD9:
+ if(act==0) act= 9;
+ case ZEROKEY: case PAD0:
+ if(act==0) act= 10;
if( block->flag & UI_BLOCK_NUMSELECT ) {
@@ -4713,19 +4754,18 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
if(uevent->val || (block->flag & UI_BLOCK_RET_1)==0) {
if ELEM6(uevent->event, LEFTMOUSE, PADENTER, RETKEY, BUT_ACTIVATE, BUT_NEXT, BUT_PREV) {
/* when mouse outside, don't do button */
- if(inside || uevent->event!=LEFTMOUSE) {
-
+ if(inside || uevent->event!=LEFTMOUSE) {
if ELEM(uevent->event, BUT_NEXT, BUT_PREV) {
butevent= ui_act_as_text_but(but);
uibut_do_func(but);
}
else
butevent= ui_do_button(block, but, uevent);
-
+
/* add undo pushes if... */
if( !(block->flag & UI_BLOCK_LOOP)) {
if(!G.obedit) {
- if ELEM4(but->type, BLOCK, BUT, LABEL, PULLDOWN);
+ if ELEM5(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX);
else {
/* define which string to use for undo */
if ELEM(but->type, LINK, INLINK) screen_delayed_undo_push("Add button link");
@@ -4735,12 +4775,12 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
}
}
}
-
+
if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
-
+
/* i doubt about the next line! */
/* if(but->func) mywinset(block->win); */
-
+
if( (block->flag & UI_BLOCK_LOOP) && but->type==BLOCK);
else
if (butevent) retval= UI_RETURN_OK;
@@ -4777,7 +4817,7 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
if((uevent->event==RETKEY || uevent->event==PADENTER) && uevent->val==1) return UI_RETURN_OK;
/* check outside */
- if(inside==0) {
+ if(inside==0 && movemouse_quit) {
uiBlock *tblock= NULL;
/* check for all parent rects, enables arrowkeys to be used */
@@ -4805,30 +4845,15 @@ static uiOverDraw *ui_draw_but_tip(uiBut *but)
{
uiOverDraw *od;
float x1, x2, y1, y2;
+ rctf tip_bbox;
-#ifdef INTERNATIONAL
- if(G.ui_international == TRUE) {
- float llx,lly,llz,urx,ury,urz; //for FTF_GetBoundingBox()
-
- if(U.transopts & USER_TR_TOOLTIPS) {
- FTF_GetBoundingBox(but->tip, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
+ BIF_GetBoundingBox(but->font, but->tip, (U.transopts & USER_TR_TOOLTIPS), &tip_bbox);
+
+ x1= (but->x1+but->x2)/2;
+ x2= x1+but->aspect*((tip_bbox.xmax-tip_bbox.xmin) + 8);
+ y2= but->y1-10;
+ y1= y2-but->aspect*((tip_bbox.ymax+(tip_bbox.ymax-tip_bbox.ymin)));
- x1= (but->x1+but->x2)/2; x2= 10+x1+ but->aspect*FTF_GetStringWidth(but->tip, FTF_USE_GETTEXT | FTF_INPUT_UTF8); //BMF_GetStringWidth(but->font, but->tip);
- y1= but->y1-(ury+FTF_GetSize())-12; y2= but->y1-12;
- } else {
- FTF_GetBoundingBox(but->tip, &llx,&lly,&llz,&urx,&ury,&urz, FTF_NO_TRANSCONV | FTF_INPUT_UTF8);
-
- x1= (but->x1+but->x2)/2; x2= 10+x1+ but->aspect*FTF_GetStringWidth(but->tip, FTF_NO_TRANSCONV | FTF_INPUT_UTF8); //BMF_GetStringWidth(but->font, but->tip);
- y1= but->y1-(ury+FTF_GetSize())-12; y2= but->y1-12;
- }
- } else {
- x1= (but->x1+but->x2)/2; x2= 10+x1+ but->aspect*BMF_GetStringWidth(but->font, but->tip);
- y1= but->y1-30; y2= but->y1-12;
- }
-#else
- x1= (but->x1+but->x2)/2; x2= 10+x1+ but->aspect*BMF_GetStringWidth(but->font, but->tip);
- y1= but->y1-30; y2= but->y1-12;
-#endif
/* for pulldown menus it doesnt work */
if(mywinget()==G.curscreen->mainwin);
@@ -4846,13 +4871,6 @@ static uiOverDraw *ui_draw_but_tip(uiBut *but)
y2 += 36;
}
- // adjust tooltip heights
- if(mywinget()==G.curscreen->mainwin)
- y2 -= G.ui_international ? 4:1; //tip is from pulldownmenu
- else if(curarea->win != mywinget())
- y2 -= G.ui_international ? 5:1; //tip is from a windowheader
-// else y2 += 1; //tip is from button area
-
od= ui_begin_overdraw((int)(x1-1), (int)(y1-2), (int)(x2+4), (int)(y2+4));
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -4874,7 +4892,10 @@ static uiOverDraw *ui_draw_but_tip(uiBut *but)
glRectf(x1, y1, x2, y2);
glColor3ub(0,0,0);
- ui_rasterpos_safe( x1+3, y1+5.0/but->aspect, but->aspect);
+ /* set the position for drawing text +4 in from the left edge, and leaving an equal gap between the top of the background box
+ * and the top of the string's tip_bbox, and the bottom of the background box, and the bottom of the string's tip_bbox
+ */
+ ui_rasterpos_safe(x1+4, ((y2-tip_bbox.ymax)+(y1+tip_bbox.ymin))/2 - tip_bbox.ymin, but->aspect);
BIF_SetScale(1.0);
BIF_DrawString(but->font, but->tip, (U.transopts & USER_TR_TOOLTIPS));
@@ -4938,7 +4959,7 @@ static void ui_do_but_tip(uiBut *buttip)
}
/* returns UI_NOTHING, if nothing happened */
-int uiDoBlocks(ListBase *lb, int event)
+int uiDoBlocks(ListBase *lb, int event, int movemouse_quit)
{
/* return when: firstblock != BLOCK_LOOP
*
@@ -4993,7 +5014,7 @@ int uiDoBlocks(ListBase *lb, int event)
}
block->in_use= 1; // bit awkward, but now we can detect if frontbuf flush should be set
- retval |= ui_do_block(block, &uevent); /* we 'or' because 2nd loop can return to here, and we we want 'out' to return */
+ retval |= ui_do_block(block, &uevent, movemouse_quit); /* we 'or' because 2nd loop can return to here, and we we want 'out' to return */
block->in_use= 0;
if(retval & UI_EXIT_LOOP) break;
@@ -5037,7 +5058,7 @@ int uiDoBlocks(ListBase *lb, int event)
if(uevent.event) {
block->in_use= 1; // bit awkward, but now we can detect if frontbuf flush should be set
- retval= ui_do_block(block, &uevent);
+ retval= ui_do_block(block, &uevent, movemouse_quit);
block->in_use= 0;
if(block->needflush) { // flush (old menu) now, maybe new menu was opened
@@ -6280,7 +6301,7 @@ int uiButGetRetVal(uiBut *but)
return but->retval;
}
-
+/* Call this function BEFORE adding buttons to the block */
void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event), void *arg)
{
block->butm_func= menufunc;
@@ -6533,7 +6554,7 @@ short pupmenu(char *instr)
uiBoundsBlock(block, 1);
- event= uiDoBlocks(&listb, 0);
+ event= uiDoBlocks(&listb, 0, 1);
/* calculate last selected */
if(event & UI_RETURN_OK) {
@@ -6691,7 +6712,7 @@ short pupmenu_col(char *instr, int maxrow)
uiBoundsBlock(block, 1);
- event= uiDoBlocks(&listb, 0);
+ event= uiDoBlocks(&listb, 0, 1);
menudata_free(md);
diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c
index c7bcc510ef1..0cbcff3875a 100644
--- a/source/blender/src/interface_draw.c
+++ b/source/blender/src/interface_draw.c
@@ -1604,7 +1604,15 @@ static void ui_draw_text_icon(uiBut *but)
ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
if(but->type==IDPOIN) transopts= 0; // no translation, of course!
else transopts= (U.transopts & USER_TR_BUTTONS);
+
+ #ifdef INTERNATIONAL
+ if (but->type == FTPREVIEW)
+ FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
+ else
+ BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
+ #else
BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
+ #endif
/* part text right aligned */
if(cpoin) {
@@ -1785,7 +1793,7 @@ static void ui_draw_but_CHARTAB(uiBut *but)
PackedFile *pf;
int result = 0;
int charmax = G.charmax;
-
+
/* <builtin> font in use. There are TTF <builtin> and non-TTF <builtin> fonts */
if(!strcmp(G.selfont->name, "<builtin>"))
{
@@ -1947,6 +1955,12 @@ static void ui_draw_but_CHARTAB(uiBut *but)
{
result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
}
+
+ /* resets the font size */
+ if(G.ui_international == TRUE)
+ {
+ uiSetCurFont(but->block, UI_HELV);
+ }
}
#endif // INTERNATIONAL
@@ -1956,7 +1970,7 @@ static void ui_draw_but_COLORBAND(uiBut *but)
ColorBand *coba= (ColorBand *)but->poin;
CBData *cbd;
float x1, y1, sizex, sizey;
- float dx, v3[2], v1[2], v2[2];
+ float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
int a;
if(coba==NULL) return;
@@ -2024,39 +2038,55 @@ static void ui_draw_but_COLORBAND(uiBut *but)
/* help lines */
v1[0]= v2[0]=v3[0]= x1;
v1[1]= y1;
+ v1a[1]= y1+0.25*sizey;
v2[1]= y1+0.5*sizey;
+ v2a[1]= y1+0.75*sizey;
v3[1]= y1+sizey;
+
cbd= coba->data;
glBegin(GL_LINES);
for(a=0; a<coba->tot; a++, cbd++) {
- v1[0]=v2[0]=v3[0]= x1+ cbd->pos*sizex;
-
- glColor3ub(0, 0, 0);
- glVertex2fv(v1);
- glVertex2fv(v2);
-
- if(a==coba->cur) {
- glVertex2f(v1[0]-1, v1[1]);
- glVertex2f(v2[0]-1, v2[1]);
- glVertex2f(v1[0]+1, v1[1]);
- glVertex2f(v2[0]+1, v2[1]);
- }
-
- glColor3ub(255, 255, 255);
- glVertex2fv(v2);
- glVertex2fv(v3);
+ v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
if(a==coba->cur) {
- if(cbd->pos>0.01) {
- glVertex2f(v2[0]-1, v2[1]);
- glVertex2f(v3[0]-1, v3[1]);
- }
- if(cbd->pos<0.99) {
- glVertex2f(v2[0]+1, v2[1]);
- glVertex2f(v3[0]+1, v3[1]);
- }
+ glColor3ub(0, 0, 0);
+ glVertex2fv(v1);
+ glVertex2fv(v3);
+ glEnd();
+
+ setlinestyle(2);
+ glBegin(GL_LINES);
+ glColor3ub(255, 255, 255);
+ glVertex2fv(v1);
+ glVertex2fv(v3);
+ glEnd();
+ setlinestyle(0);
+ glBegin(GL_LINES);
+
+ /* glColor3ub(0, 0, 0);
+ glVertex2fv(v1);
+ glVertex2fv(v1a);
+ glColor3ub(255, 255, 255);
+ glVertex2fv(v1a);
+ glVertex2fv(v2);
+ glColor3ub(0, 0, 0);
+ glVertex2fv(v2);
+ glVertex2fv(v2a);
+ glColor3ub(255, 255, 255);
+ glVertex2fv(v2a);
+ glVertex2fv(v3);
+ */
}
+ else {
+ glColor3ub(0, 0, 0);
+ glVertex2fv(v1);
+ glVertex2fv(v2);
+
+ glColor3ub(255, 255, 255);
+ glVertex2fv(v2);
+ glVertex2fv(v3);
+ }
}
glEnd();
}
@@ -2220,13 +2250,40 @@ static void ui_draw_but_CURVE(uiBut *but)
if(cumap->flag & CUMA_DRAW_CFRA) {
glColor3ub(0x60, 0xc0, 0x40);
glBegin(GL_LINES);
- glVertex2f(but->x1 + zoomx*(cumap->black[0]-offsx), but->y1);
- glVertex2f(but->x1 + zoomx*(cumap->black[0]-offsx), but->y2);
+ glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y1);
+ glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y2);
glEnd();
}
+ /* sample option */
+ if(cumap->flag & CUMA_DRAW_SAMPLE) {
+ if(cumap->cur==3) {
+ float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
+ glColor3ub(240, 240, 240);
+
+ glBegin(GL_LINES);
+ glVertex2f(but->x1 + zoomx*(lum-offsx), but->y1);
+ glVertex2f(but->x1 + zoomx*(lum-offsx), but->y2);
+ glEnd();
+ }
+ else {
+ if(cumap->cur==0)
+ glColor3ub(240, 100, 100);
+ else if(cumap->cur==1)
+ glColor3ub(100, 240, 100);
+ else
+ glColor3ub(100, 100, 240);
+
+ glBegin(GL_LINES);
+ glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y1);
+ glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y2);
+ glEnd();
+ }
+ }
/* the curve */
- BIF_ThemeColor(TH_TEXT);
+ BIF_ThemeColorBlend(TH_TEXT, TH_BUT_NEUTRAL, 0.35);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
glBegin(GL_LINE_STRIP);
if(cuma->table==NULL)
@@ -2255,6 +2312,8 @@ static void ui_draw_but_CURVE(uiBut *but)
glVertex2f(fx, fy);
}
glEnd();
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
/* the points, use aspect to make them visible on edges */
cmp= cuma->curve;
@@ -2417,3 +2476,33 @@ void ui_draw_but(uiBut *but)
}
}
+void ui_dropshadow(rctf *rct, float radius, float aspect, int select)
+{
+ float rad;
+ float a;
+ char alpha= 2;
+
+ glEnable(GL_BLEND);
+
+ if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
+ rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
+ else
+ rad= radius;
+
+ if(select) a= 12.0f*aspect; else a= 12.0f*aspect;
+ for(; a>0.0f; a-=aspect) {
+ /* alpha ranges from 2 to 20 or so */
+ glColor4ub(0, 0, 0, alpha);
+ alpha+= 2;
+
+ gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
+ }
+
+ /* outline emphasis */
+ glEnable( GL_LINE_SMOOTH );
+ glColor4ub(0, 0, 0, 100);
+ gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius);
+ glDisable( GL_LINE_SMOOTH );
+
+ glDisable(GL_BLEND);
+}
diff --git a/source/blender/src/interface_icons.c b/source/blender/src/interface_icons.c
index d257f2f37f8..d93834d8d8a 100644
--- a/source/blender/src/interface_icons.c
+++ b/source/blender/src/interface_icons.c
@@ -90,11 +90,6 @@
#include "datatoc.h"
#include "mydevice.h"
-/* OpenGL textures have to be size 2n+2 x 2m+2 for some n,m */
-/* choose ICON_RENDERSIZE accordingly */
-#define ICON_RENDERSIZE 32
-#define ICON_MIPMAPS 8
-
#define ICON_IMAGE_W 512
#define ICON_IMAGE_H 256
@@ -105,52 +100,60 @@
#define ICON_GRID_W 15
#define ICON_GRID_H 16
+typedef struct IconImage {
+ int w;
+ int h;
+ unsigned int *rect;
+} IconImage;
+
typedef struct DrawInfo {
int w;
int h;
- int rw;
- int rh;
- VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */
float aspect;
- unsigned int *rect;
+ VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */
+ IconImage* icon;
} DrawInfo;
-
/* ******************* 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 int preview_render_size(int miplevel);
+
/* **************************************************** */
static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs)
{
Icon *new_icon = NULL;
+ IconImage *iimg = NULL;
DrawInfo *di;
int y = 0;
new_icon = MEM_callocN(sizeof(Icon), "texicon");
new_icon->obj = 0; /* icon is not for library object */
- new_icon->type = 0;
- new_icon->changed = 0;
-
+ new_icon->type = 0;
di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
di->drawFunc = 0;
di->w = ICON_DEFAULT_HEIGHT;
di->h = ICON_DEFAULT_HEIGHT;
- di->rw = ICON_DEFAULT_HEIGHT;
- di->rh = ICON_DEFAULT_HEIGHT;
di->aspect = 1.0f;
- di->rect = MEM_mallocN(ICON_DEFAULT_HEIGHT*ICON_DEFAULT_HEIGHT*sizeof(unsigned int), "icon_rect");
+ iimg = MEM_mallocN(sizeof(IconImage), "icon_img");
+ iimg->rect = MEM_mallocN(ICON_DEFAULT_HEIGHT*ICON_DEFAULT_HEIGHT*sizeof(unsigned int), "icon_rect");
+ iimg->w = ICON_DEFAULT_HEIGHT;
+ iimg->h = ICON_DEFAULT_HEIGHT;
+
/* Here we store the rect in the icon - same as before */
for (y=0; y<ICON_DEFAULT_HEIGHT; y++) {
- memcpy(&di->rect[y*ICON_DEFAULT_HEIGHT], &bbuf->rect[(y+yofs)*512+xofs], ICON_DEFAULT_HEIGHT*sizeof(int));
+ memcpy(&iimg->rect[y*ICON_DEFAULT_HEIGHT], &bbuf->rect[(y+yofs)*512+xofs], ICON_DEFAULT_HEIGHT*sizeof(int));
}
+ di->icon = iimg;
+
new_icon->drawinfo_free = BIF_icons_free_drawinfo;
new_icon->drawinfo = di;
@@ -166,17 +169,14 @@ static void def_internal_vicon( int icon_id, VectorDrawFunc drawFunc)
new_icon->obj = 0; /* icon is not for library object */
new_icon->type = 0;
- new_icon->changed = 0;
-
+
di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
di->drawFunc =drawFunc;
di->w = ICON_DEFAULT_HEIGHT;
di->h = ICON_DEFAULT_HEIGHT;
- di->rw = ICON_DEFAULT_HEIGHT;
- di->rh = ICON_DEFAULT_HEIGHT;
di->aspect = 1.0f;
- di->rect = NULL;
-
+ di->icon = NULL;
+
new_icon->drawinfo_free = 0;
new_icon->drawinfo = di;
@@ -693,7 +693,10 @@ void BIF_icons_free_drawinfo(void *drawinfo)
if (di)
{
- MEM_freeN(di->rect);
+ if (di->icon) {
+ MEM_freeN(di->icon->rect);
+ MEM_freeN(di->icon);
+ }
MEM_freeN(di);
}
}
@@ -705,11 +708,9 @@ static DrawInfo *icon_create_drawinfo()
di = MEM_callocN(sizeof(DrawInfo), "di_icon");
di->drawFunc = 0;
- di->w = 16;
- di->h = 16;
- di->rw = ICON_RENDERSIZE;
- di->rh = ICON_RENDERSIZE;
- di->rect = 0;
+ di->w = ICON_DEFAULT_HEIGHT;
+ di->h = ICON_DEFAULT_HEIGHT;
+ di->icon = NULL;
di->aspect = 1.0f;
return di;
@@ -771,7 +772,7 @@ void BIF_icons_init(int first_dyn_id)
init_internal_icons();
}
-static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri)
+static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect)
{
struct ImBuf *ima;
unsigned int *drect, *srect;
@@ -789,19 +790,19 @@ static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri)
return;
if (ima->x > ima->y) {
- scaledx = (float)ri->pr_rectx;
- scaledy = ( (float)ima->y/(float)ima->x )*(float)ri->pr_rectx;
+ scaledx = (float)w;
+ scaledy = ( (float)ima->y/(float)ima->x )*(float)w;
}
else {
- scaledx = ( (float)ima->x/(float)ima->y )*(float)ri->pr_recty;
- scaledy = (float)ri->pr_recty;
+ scaledx = ( (float)ima->x/(float)ima->y )*(float)h;
+ scaledy = (float)h;
}
ex = (short)scaledx;
ey = (short)scaledy;
- dx = (ri->pr_rectx - ex) / 2;
- dy = (ri->pr_recty - ey) / 2;
+ dx = (w - ex) / 2;
+ dy = (h - ey) / 2;
IMB_scalefastImBuf(ima, ex, ey);
@@ -810,61 +811,66 @@ static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri)
IMB_rect_from_float(ima);
srect = ima->rect;
- drect = ri->rect;
+ drect = rect;
- drect+= dy*ri->pr_rectx+dx;
+ drect+= dy*w+dx;
for (;ey > 0; ey--){
memcpy(drect,srect, ex * sizeof(int));
- drect += ri->pr_rectx;
+ drect += w;
srect += ima->x;
}
IMB_freeImBuf(ima);
}
+static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel)
+{
+ unsigned int size = preview_render_size(miplevel);
+
+ if (!prv_img) {
+ printf("Error: requested preview image does not exist");
+ }
+ if (!prv_img->rect[miplevel]) {
+ prv_img->w[miplevel] = size;
+ prv_img->h[miplevel] = size;
+ prv_img->changed[miplevel] = 1;
+ prv_img->rect[miplevel] = MEM_callocN(size*size*sizeof(unsigned int), "prv_rect");
+ }
+}
+
/* create single icon from jpg, png etc. */
-static void icon_from_image(Image *img, RenderInfo *ri)
+static void icon_from_image(Image *img, int miplevel)
{
- unsigned int pr_size = ri->pr_rectx*ri->pr_recty*sizeof(unsigned int);
+ unsigned int pr_size;
+ short image_loaded = 0;
+ struct ImBuf* ibuf=NULL;
+ PreviewImage* pi;
/* img->ok is zero when Image cannot load */
if (img==NULL || img->ok==0)
return;
-
- if (!ri->rect) {
- ri->rect= MEM_callocN(pr_size, "butsrect");
- memset(ri->rect, 0x00, pr_size);
+
+ /* 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, NULL);
+ if(ibuf==NULL || ibuf->rect==NULL) {
+ return;
}
- /* we only load image if there's no preview saved already ...
- always loading and reducing images is too expensive */
- /* new rule: never read images, so icons get created while user works,
- not always on first use of a menu */
- if(!img->preview) {
- ImBuf *ibuf;
- if(img->ok!=IMA_OK_LOADED) {
- return;
- }
- ibuf= BKE_image_get_ibuf(img, NULL);
- icon_copy_rect(ibuf, ri);
-
- /* now copy the created preview to the DNA struct to be saved in file */
- img->preview = MEM_callocN(sizeof(PreviewImage), "img_prv");
- if (img->preview) {
- printf("created image prv\n");
- img->preview->w = ri->pr_rectx;
- img->preview->h = ri->pr_recty;
- img->preview->rect = MEM_callocN(pr_size, "prv_rect");
- memcpy(img->preview->rect, ri->rect, pr_size);
- }
- }
- else {
- unsigned int img_prv_size = img->preview->w*img->preview->h*sizeof(unsigned int);
- if (!img->preview->rect || img_prv_size != pr_size) {
- printf("Missing preview or wrong preview size!\n");
- return;
- }
- memcpy(ri->rect, img->preview->rect, pr_size);
+ 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)
@@ -879,27 +885,36 @@ static void set_alpha(char* cp, int sizex, int sizey, char alpha)
/* only called when icon has changed */
/* only call with valid pointer from BIF_icon_draw */
-static void icon_set_image(ID *id, DrawInfo *di)
+static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int miplevel)
{
RenderInfo ri;
-
- if (!di) return;
-
- if (!di->rect)
- di->rect = MEM_callocN(di->rw*di->rh*sizeof(unsigned int), "laprevrect");
+ unsigned int pr_size = 0;
+
+ if (!di) return;
- ri.curtile= 0;
- ri.tottile= 0;
- ri.rect = NULL;
- ri.pr_rectx = di->rw;
- ri.pr_recty = di->rh;
+ 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((struct Image*)id, &ri);
- else {
+ icon_from_image((struct Image*)id, miplevel);
+ else {
+ /* create the preview rect */
+ icon_create_mipmap(prv_img, miplevel);
+
+ ri.curtile= 0;
+ ri.tottile= 0;
+ ri.rect = NULL;
+ 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);
+
BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER);
+
/* 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) {
@@ -909,25 +924,74 @@ static void icon_set_image(ID *id, DrawInfo *di)
Material* mat = (Material*)id;
if (mat->mode & MA_HALO) {
set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255);
- }
+ }
+ }
+
+ if (ri.rect) {
+ memcpy(prv_img->rect[miplevel], ri.rect, pr_size);
+
+ /* and clean up */
+ MEM_freeN(ri.rect);
+ ri.rect = 0;
}
}
+}
- /* and copy the image into the icon */
- if (ri.rect) {
- memcpy(di->rect, ri.rect,di->rw*di->rh*sizeof(unsigned int));
+static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect)
+{
+ ui_rasterpos_safe(x, y, aspect);
+
+ if(w<1 || h<1) {
+ printf("what the heck!\n");
+ }
+ /* 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
+ glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+}
- /* and clean up */
- MEM_freeN(ri.rect);
- ri.rect = 0;
+/* Render size for preview images at level miplevel */
+static int preview_render_size(int miplevel)
+{
+ switch (miplevel) {
+ case 0: return 32;
+ case 1: return PREVIEW_DEFAULT_HEIGHT;
}
+ return 0;
}
-void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect)
+/* Drawing size for preview images at level miplevel */
+static int preview_size(int miplevel)
+{
+ switch (miplevel) {
+ case 0: return ICON_DEFAULT_HEIGHT;
+ case 1: return PREVIEW_DEFAULT_HEIGHT;
+ }
+ return 0;
+}
+
+
+static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate)
{
Icon *icon = NULL;
DrawInfo *di = NULL;
-
+ int draw_size = preview_size(miplevel);
+
icon = BKE_icon_get(icon_id);
if (!icon) {
@@ -939,65 +1003,61 @@ void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect)
if (!di) {
di = icon_create_drawinfo();
-
- icon->changed = 1;
+
icon->drawinfo = di;
icon->drawinfo_free = BIF_icons_free_drawinfo;
}
di->aspect = aspect;
/* scale width and height according to aspect */
- di->w = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f);
- di->h = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f);
+ di->w = (int)(draw_size/di->aspect + 0.5f);
+ di->h = (int)(draw_size/di->aspect + 0.5f);
if (di->drawFunc) {
/* 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);
+ }
+ else if (di->icon) {
+ /* it is a builtin icon */
+ if (!di->icon->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);
}
else {
- if (icon->changed) /* changed only ever set by dynamic icons */
- {
- waitcursor(1);
- icon_set_image((ID*)icon->obj, icon->drawinfo);
- icon->changed = 0;
- waitcursor(0);
- }
-
- if (!di->rect) return; /* something has gone wrong! */
-
- ui_rasterpos_safe(x, y, di->aspect);
-
- if(di->w<1 || di->h<1) {
- printf("what the heck!\n");
- }
- /* di->rect contains image in 'rendersize', we only scale if needed */
- else if(di->rw!=di->w && di->rh!=di->h) {
- ImBuf *ima;
- if(di->w>2000 || di->h>2000) { /* something has gone wrong! */
- printf("insane icon size di->w %d di->h %d\n",di->w,di->h);
- return;
+ PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj);
+
+ if (pi) {
+ if (!nocreate && (pi->changed[miplevel] ||!pi->rect[miplevel])) /* changed only ever set by dynamic icons */
+ {
+ waitcursor(1);
+ /* create the preview rect if necessary */
+ icon_set_image((ID*)icon->obj, icon->drawinfo, pi, miplevel);
+ pi->changed[miplevel] = 0;
+ waitcursor(0);
}
- /* first allocate imbuf for scaling and copy preview into it */
- ima = IMB_allocImBuf(di->rw, di->rh, 32, IB_rect, 0);
- memcpy(ima->rect, di->rect, di->rw*di->rh*sizeof(unsigned int));
- /* scale it */
- IMB_scaleImBuf(ima, di->w, di->h);
- glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect);
+ if (!pi->rect[miplevel]) return; /* something has gone wrong! */
- IMB_freeImBuf(ima);
+ icon_draw_rect(x,y,di->w, di->h, di->aspect, pi->w[miplevel], pi->h[miplevel], pi->rect[miplevel]);
}
- else
- glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, di->rect);
}
}
+void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect)
+{
+ icon_draw_mipmap(x,y,icon_id, aspect, PREVIEW_MIPMAP_ZERO, 0);
+}
+
void BIF_icon_draw(float x, float y, int icon_id)
{
BIF_icon_draw_aspect(x, y, icon_id, 1.0f);
}
+void BIF_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);
+}
void BIF_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade)
{
diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c
index bafc544daa7..0752a5dd198 100644
--- a/source/blender/src/interface_panel.c
+++ b/source/blender/src/interface_panel.c
@@ -1766,7 +1766,7 @@ static void panel_clicked_tabs(uiBlock *block, int mousex)
pa= curarea->panels.first;
while(pa) {
if(pa!=panel) {
- if(pa->paneltab==panel) nr++;
+ if(pa->active && pa->paneltab==panel) nr++;
}
pa= pa->next;
}
@@ -1778,7 +1778,7 @@ static void panel_clicked_tabs(uiBlock *block, int mousex)
width= (int)((float)(panel->sizex - ofsx-10)/nr);
pa= curarea->panels.first;
while(pa) {
- if(pa==panel || pa->paneltab==panel) {
+ if(pa==panel || (pa->active && pa->paneltab==panel)) {
if( (mousex > ofsx+a*width) && (mousex < ofsx+(a+1)*width) ) {
tabsel= pa;
break;
@@ -1805,6 +1805,13 @@ static void panel_clicked_tabs(uiBlock *block, int mousex)
}
addqueue(curarea->win, REDRAW, 1);
+
+ /* panels now differ size.. */
+ if(curarea->spacetype==SPACE_BUTS) {
+ SpaceButs *sbuts= curarea->spacedata.first;
+ if(sbuts->align)
+ uiAlignPanelStep(curarea, 1.0);
+ }
}
}
diff --git a/source/blender/src/language.c b/source/blender/src/language.c
index 4c485bad8d3..5eb4bf3dc61 100644
--- a/source/blender/src/language.c
+++ b/source/blender/src/language.c
@@ -33,6 +33,7 @@
#include "DNA_listBase.h"
#include "DNA_userdef_types.h"
+#include "DNA_vec_types.h"
#include "BKE_global.h" /* G */
#include "BKE_utildefines.h"
@@ -52,6 +53,33 @@
#include "BMF_Api.h"
+#ifdef WITH_ICONV
+#include "iconv.h"
+
+void string_to_utf8(char *original, char *utf_8, char *code)
+{
+ size_t inbytesleft=strlen(original);
+ size_t outbytesleft=512;
+ size_t rv=0;
+ iconv_t cd;
+
+ cd=iconv_open("UTF-8", code);
+
+ if (cd == (iconv_t)(-1)) {
+ printf("iconv_open Error");
+ *utf_8='\0';
+ return ;
+ }
+ rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
+ if (rv == (size_t) -1) {
+ printf("iconv Error\n");
+ return ;
+ }
+ *utf_8 = '\0';
+ iconv_close(cd);
+}
+#endif // WITH_ICONV
+
#ifdef INTERNATIONAL
#include "FTF_Api.h"
@@ -92,23 +120,33 @@ int BIF_DrawString(BMF_Font* font, char *str, int translate)
#ifdef INTERNATIONAL
if(G.ui_international == TRUE) {
if(translate)
- return FTF_DrawString(str, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
+ {
+#ifdef WITH_ICONV
+ if(translate & CONVERT_TO_UTF8) {
+ char utf_8[512];
+
+ struct LANGMenuEntry *lme;
+ lme = find_language(U.language);
+
+ if (lme !=NULL) {
+ if (!strcmp(lme->code, "ja_JP"))
+ string_to_utf8(str, utf_8, "Shift_JIS"); /* Japanese */
+ else if (!strcmp(lme->code, "zh_CN"))
+ string_to_utf8(str, utf_8, "GB2312"); /* Chinese */
+ }
+
+ return FTF_DrawString(utf_8, FTF_INPUT_UTF8);
+ }
+ else
+#endif // WITH_ICONV
+ return FTF_DrawString(str, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
+ }
else
return FTF_DrawString(str, FTF_NO_TRANSCONV | FTF_INPUT_UTF8);
} else {
return BMF_DrawString(font, str);
-/*
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- BMF_GetFontTexture(font);??
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- BMF_DrawStringTexture(font, str, pen_x, pen_y, 0.0);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- return 0;
-*/
}
-#else
+#else // INTERNATIONAL
return BMF_DrawString(font, str);
#endif
@@ -134,6 +172,21 @@ float BIF_GetStringWidth(BMF_Font* font, char *str, int translate)
return rt;
}
+void BIF_GetBoundingBox(struct BMF_Font* font, char* str, int translate, rctf *bbox){
+#ifdef INTERNATIONAL
+ float dummy;
+ if(G.ui_international == TRUE)
+ if(translate && (U.transopts & USER_TR_BUTTONS))
+ FTF_GetBoundingBox(str, &bbox->xmin, &bbox->ymin, &dummy, &bbox->xmax, &bbox->ymax, &dummy, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
+ else
+ FTF_GetBoundingBox(str, &bbox->xmin, &bbox->ymin, &dummy, &bbox->xmax, &bbox->ymax, &dummy, FTF_NO_TRANSCONV | FTF_INPUT_UTF8);
+ else
+ BMF_GetStringBoundingBox(font, str, &bbox->xmin, &bbox->ymin, &bbox->xmax, &bbox->ymax);
+#else
+ BMF_GetStringBoundingBox(font, str, &bbox->xmin, &bbox->ymin, &bbox->xmax, &bbox->ymax);
+#endif
+}
+
#ifdef INTERNATIONAL
diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c
new file mode 100644
index 00000000000..5e8fdac80da
--- /dev/null
+++ b/source/blender/src/meshlaplacian.c
@@ -0,0 +1,1911 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ * meshlaplacian.c: Algorithms using the mesh laplacian.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_edgehash.h"
+#include "BLI_memarena.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_utildefines.h"
+
+#include "BIF_editdeform.h"
+#include "BIF_meshlaplacian.h"
+#include "BIF_meshtools.h"
+#include "BIF_screen.h"
+#include "BIF_toolbox.h"
+
+#include "BSE_headerbuttons.h"
+
+#ifdef RIGID_DEFORM
+#include "BLI_editVert.h"
+#include "BLI_polardecomp.h"
+#endif
+
+#include "RE_raytrace.h"
+
+#include "ONL_opennl.h"
+
+/************************** Laplacian System *****************************/
+
+struct LaplacianSystem {
+ NLContext context; /* opennl context */
+
+ int totvert, totface;
+
+ float **verts; /* vertex coordinates */
+ float *varea; /* vertex weights for laplacian computation */
+ char *vpinned; /* vertex pinning */
+ int (*faces)[3]; /* face vertex indices */
+ float (*fweights)[3]; /* cotangent weights per face */
+
+ int areaweights; /* use area in cotangent weights? */
+ int storeweights; /* store cotangent weights in fweights */
+ int nlbegun; /* nlBegin(NL_SYSTEM/NL_MATRIX) done */
+
+ EdgeHash *edgehash; /* edge hash for construction */
+
+ struct HeatWeighting {
+ Mesh *mesh;
+ float (*verts)[3]; /* vertex coordinates */
+ float (*vnors)[3]; /* vertex normals */
+
+ float (*root)[3]; /* bone root */
+ float (*tip)[3]; /* bone tip */
+ int numbones;
+
+ float *H; /* diagonal H matrix */
+ float *p; /* values from all p vectors */
+ float *mindist; /* minimum distance to a bone for all vertices */
+
+ RayTree *raytree; /* ray tracing acceleration structure */
+ MFace **vface; /* a face that the vertex belongs to */
+ } heat;
+
+#ifdef RIGID_DEFORM
+ struct RigidDeformation {
+ EditMesh *mesh;
+
+ float (*R)[3][3];
+ float (*rhs)[3];
+ float (*origco)[3];
+ int thrownerror;
+ } rigid;
+#endif
+};
+
+/* Laplacian matrix construction */
+
+/* Computation of these weights for the laplacian is based on:
+ "Discrete Differential-Geometry Operators for Triangulated 2-Manifolds",
+ Meyer et al, 2002. Section 3.5, formula (8).
+
+ We do it a bit different by going over faces instead of going over each
+ vertex and adjacent faces, since we don't store this adjacency. Also, the
+ formulas are tweaked a bit to work for non-manifold meshes. */
+
+static void laplacian_increase_edge_count(EdgeHash *edgehash, int v1, int v2)
+{
+ void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
+
+ if(p)
+ *p = (void*)((long)*p + (long)1);
+ else
+ BLI_edgehash_insert(edgehash, v1, v2, (void*)(long)1);
+}
+
+static int laplacian_edge_count(EdgeHash *edgehash, int v1, int v2)
+{
+ return (int)(long)BLI_edgehash_lookup(edgehash, v1, v2);
+}
+
+static float cotan_weight(float *v1, float *v2, float *v3)
+{
+ float a[3], b[3], c[3], clen;
+
+ VecSubf(a, v2, v1);
+ VecSubf(b, v3, v1);
+ Crossf(c, a, b);
+
+ clen = VecLength(c);
+
+ if (clen == 0.0f)
+ return 0.0f;
+
+ return Inpf(a, b)/clen;
+}
+
+static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3)
+{
+ float t1, t2, t3, len1, len2, len3, area;
+ float *varea= sys->varea, *v1, *v2, *v3;
+ int obtuse = 0;
+
+ v1= sys->verts[i1];
+ v2= sys->verts[i2];
+ v3= sys->verts[i3];
+
+ t1= cotan_weight(v1, v2, v3);
+ 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 (obtuse > 0) {
+ area= AreaT3Dfl(v1, v2, v3);
+
+ varea[i1] += (obtuse == 1)? area: area*0.5;
+ varea[i2] += (obtuse == 2)? area: area*0.5;
+ varea[i3] += (obtuse == 3)? area: area*0.5;
+ }
+ else {
+ len1= VecLenf(v2, v3);
+ len2= VecLenf(v1, v3);
+ len3= VecLenf(v1, v2);
+
+ t1 *= len1*len1;
+ t2 *= len2*len2;
+ t3 *= len3*len3;
+
+ varea[i1] += (t2 + t3)*0.25f;
+ varea[i2] += (t1 + t3)*0.25f;
+ varea[i3] += (t1 + t2)*0.25f;
+ }
+}
+
+static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int i2, int i3)
+{
+ float t1, t2, t3;
+ float *varea= sys->varea, *v1, *v2, *v3;
+
+ v1= sys->verts[i1];
+ v2= sys->verts[i2];
+ v3= sys->verts[i3];
+
+ /* instead of *0.5 we divided by the number of faces of the edge, it still
+ needs to be varified that this is indeed the correct thing to do! */
+ t1= cotan_weight(v1, v2, v3)/laplacian_edge_count(sys->edgehash, i2, i3);
+ t2= cotan_weight(v2, v3, v1)/laplacian_edge_count(sys->edgehash, i3, i1);
+ t3= cotan_weight(v3, v1, v2)/laplacian_edge_count(sys->edgehash, i1, i2);
+
+ nlMatrixAdd(i1, i1, (t2+t3)*varea[i1]);
+ nlMatrixAdd(i2, i2, (t1+t3)*varea[i2]);
+ nlMatrixAdd(i3, i3, (t1+t2)*varea[i3]);
+
+ nlMatrixAdd(i1, i2, -t3*varea[i1]);
+ nlMatrixAdd(i2, i1, -t3*varea[i2]);
+
+ nlMatrixAdd(i2, i3, -t1*varea[i2]);
+ nlMatrixAdd(i3, i2, -t1*varea[i3]);
+
+ nlMatrixAdd(i3, i1, -t2*varea[i3]);
+ nlMatrixAdd(i1, i3, -t2*varea[i1]);
+
+ if(sys->storeweights) {
+ sys->fweights[f][0]= t1*varea[i1];
+ sys->fweights[f][1]= t2*varea[i2];
+ sys->fweights[f][2]= t3*varea[i3];
+ }
+}
+
+LaplacianSystem *laplacian_system_construct_begin(int totvert, int totface)
+{
+ LaplacianSystem *sys;
+
+ sys= MEM_callocN(sizeof(LaplacianSystem), "LaplacianSystem");
+
+ sys->verts= MEM_callocN(sizeof(float*)*totvert, "LaplacianSystemVerts");
+ sys->vpinned= MEM_callocN(sizeof(char)*totvert, "LaplacianSystemVpinned");
+ sys->faces= MEM_callocN(sizeof(int)*3*totface, "LaplacianSystemFaces");
+
+ sys->totvert= 0;
+ sys->totface= 0;
+
+ sys->areaweights= 1;
+ sys->storeweights= 0;
+
+ /* create opennl context */
+ nlNewContext();
+ nlSolverParameteri(NL_NB_VARIABLES, totvert);
+
+ sys->context= nlGetCurrent();
+
+ return sys;
+}
+
+void laplacian_add_vertex(LaplacianSystem *sys, float *co, int pinned)
+{
+ sys->verts[sys->totvert]= co;
+ sys->vpinned[sys->totvert]= pinned;
+ sys->totvert++;
+}
+
+void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3)
+{
+ sys->faces[sys->totface][0]= v1;
+ sys->faces[sys->totface][1]= v2;
+ sys->faces[sys->totface][2]= v3;
+ sys->totface++;
+}
+
+void laplacian_system_construct_end(LaplacianSystem *sys)
+{
+ int (*face)[3];
+ int a, totvert=sys->totvert, totface=sys->totface;
+
+ laplacian_begin_solve(sys, 0);
+
+ sys->varea= MEM_callocN(sizeof(float)*totvert, "LaplacianSystemVarea");
+
+ sys->edgehash= BLI_edgehash_new();
+ for(a=0, face=sys->faces; a<sys->totface; a++, face++) {
+ laplacian_increase_edge_count(sys->edgehash, (*face)[0], (*face)[1]);
+ laplacian_increase_edge_count(sys->edgehash, (*face)[1], (*face)[2]);
+ laplacian_increase_edge_count(sys->edgehash, (*face)[2], (*face)[0]);
+ }
+
+ if(sys->areaweights)
+ for(a=0, face=sys->faces; a<sys->totface; a++, face++)
+ laplacian_triangle_area(sys, (*face)[0], (*face)[1], (*face)[2]);
+
+ for(a=0; a<totvert; a++) {
+ if(sys->areaweights) {
+ if(sys->varea[a] != 0.0f)
+ sys->varea[a]= 0.5f/sys->varea[a];
+ }
+ else
+ sys->varea[a]= 1.0f;
+
+ /* for heat weighting */
+ if(sys->heat.H)
+ nlMatrixAdd(a, a, sys->heat.H[a]);
+ }
+
+ if(sys->storeweights)
+ sys->fweights= MEM_callocN(sizeof(float)*3*totface, "LaplacianFWeight");
+
+ for(a=0, face=sys->faces; a<totface; a++, face++)
+ laplacian_triangle_weights(sys, a, (*face)[0], (*face)[1], (*face)[2]);
+
+ MEM_freeN(sys->faces);
+ sys->faces= NULL;
+
+ if(sys->varea) {
+ MEM_freeN(sys->varea);
+ sys->varea= NULL;
+ }
+
+ BLI_edgehash_free(sys->edgehash, NULL);
+ sys->edgehash= NULL;
+}
+
+void laplacian_system_delete(LaplacianSystem *sys)
+{
+ if(sys->verts) MEM_freeN(sys->verts);
+ if(sys->varea) MEM_freeN(sys->varea);
+ if(sys->vpinned) MEM_freeN(sys->vpinned);
+ if(sys->faces) MEM_freeN(sys->faces);
+ if(sys->fweights) MEM_freeN(sys->fweights);
+
+ nlDeleteContext(sys->context);
+ MEM_freeN(sys);
+}
+
+void laplacian_begin_solve(LaplacianSystem *sys, int index)
+{
+ int a;
+
+ if (!sys->nlbegun) {
+ nlBegin(NL_SYSTEM);
+
+ if(index >= 0) {
+ for(a=0; a<sys->totvert; a++) {
+ if(sys->vpinned[a]) {
+ nlSetVariable(0, a, sys->verts[a][index]);
+ nlLockVariable(a);
+ }
+ }
+ }
+
+ nlBegin(NL_MATRIX);
+ sys->nlbegun = 1;
+ }
+}
+
+void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value)
+{
+ nlRightHandSideAdd(0, v, value);
+}
+
+int laplacian_system_solve(LaplacianSystem *sys)
+{
+ nlEnd(NL_MATRIX);
+ nlEnd(NL_SYSTEM);
+ sys->nlbegun = 0;
+
+ //nlPrintMatrix();
+
+ return nlSolveAdvanced(NULL, NL_TRUE);
+}
+
+float laplacian_system_get_solution(int v)
+{
+ return nlGetVariable(0, v);
+}
+
+/************************* Heat Bone Weighting ******************************/
+/* From "Automatic Rigging and Animation of 3D Characters"
+ Ilya Baran and Jovan Popovic, SIGGRAPH 2007 */
+
+#define C_WEIGHT 1.0f
+#define WEIGHT_LIMIT_START 0.05f
+#define WEIGHT_LIMIT_END 0.025f
+#define DISTANCE_EPSILON 1e-4f
+
+/* Raytracing for vertex to bone visibility */
+
+static LaplacianSystem *HeatSys = NULL;
+
+static void heat_ray_coords_func(RayFace *face, float **v1, float **v2, float **v3, float **v4)
+{
+ MFace *mface= (MFace*)face;
+ float (*verts)[3]= HeatSys->heat.verts;
+
+ *v1= verts[mface->v1];
+ *v2= verts[mface->v2];
+ *v3= verts[mface->v3];
+ *v4= (mface->v4)? verts[mface->v4]: NULL;
+}
+
+static int heat_ray_check_func(Isect *is, int ob, RayFace *face)
+{
+ float *v1, *v2, *v3, *v4, nor[3];
+
+ /* don't intersect if the ray faces along the face normal */
+ heat_ray_coords_func(face, &v1, &v2, &v3, &v4);
+
+ if(v4) CalcNormFloat4(v1, v2, v3, v4, nor);
+ else CalcNormFloat(v1, v2, v3, nor);
+
+ return (INPR(nor, is->vec) < 0);
+}
+
+static void heat_ray_tree_create(LaplacianSystem *sys)
+{
+ Mesh *me = sys->heat.mesh;
+ RayTree *tree;
+ MFace *mface;
+ float min[3], max[3];
+ int a;
+
+ /* create a raytrace tree from the mesh */
+ INIT_MINMAX(min, max);
+
+ for(a=0; a<me->totvert; a++)
+ DO_MINMAX(sys->heat.verts[a], min, max);
+
+ tree= RE_ray_tree_create(64, me->totface, min, max,
+ heat_ray_coords_func, heat_ray_check_func, NULL, NULL);
+
+ sys->heat.vface= MEM_callocN(sizeof(MFace*)*me->totvert, "HeatVFaces");
+
+ HeatSys= sys;
+
+ for(a=0, mface=me->mface; a<me->totface; a++, mface++) {
+ RE_ray_tree_add_face(tree, 0, mface);
+
+ sys->heat.vface[mface->v1]= mface;
+ sys->heat.vface[mface->v2]= mface;
+ sys->heat.vface[mface->v3]= mface;
+ if(mface->v4) sys->heat.vface[mface->v4]= mface;
+ }
+
+ HeatSys= NULL;
+
+ RE_ray_tree_done(tree);
+
+ sys->heat.raytree= tree;
+}
+
+static int heat_ray_bone_visible(LaplacianSystem *sys, int vertex, int bone)
+{
+ Isect isec;
+ MFace *mface;
+ float dir[3];
+ int visible;
+
+ mface= sys->heat.vface[vertex];
+ if(!mface)
+ return 1;
+
+ /* setup isec */
+ memset(&isec, 0, sizeof(isec));
+ isec.mode= RE_RAY_SHADOW;
+ isec.lay= -1;
+ isec.face_last= NULL;
+ isec.faceorig= mface;
+
+ VECCOPY(isec.start, sys->heat.verts[vertex]);
+ PclosestVL3Dfl(isec.end, isec.start,
+ sys->heat.root[bone], sys->heat.tip[bone]);
+
+ /* add an extra offset to the start position to avoid self intersection */
+ VECSUB(dir, isec.end, isec.start);
+ Normalize(dir);
+ VecMulf(dir, 1e-5);
+ VecAddf(isec.start, isec.start, dir);
+
+ HeatSys= sys;
+ visible= !RE_ray_tree_intersect(sys->heat.raytree, &isec);
+ HeatSys= NULL;
+
+ return visible;
+}
+
+static float heat_bone_distance(LaplacianSystem *sys, int vertex, int bone)
+{
+ float closest[3], d[3], dist, cosine;
+
+ /* compute euclidian distance */
+ PclosestVL3Dfl(closest, sys->heat.verts[vertex],
+ sys->heat.root[bone], sys->heat.tip[bone]);
+
+ VecSubf(d, sys->heat.verts[vertex], closest);
+ dist= Normalize(d);
+
+ /* if the vertex normal does not point along the bone, increase distance */
+ cosine= INPR(d, sys->heat.vnors[vertex]);
+
+ return dist/(0.5f*(cosine + 1.001f));
+}
+
+static int heat_bone_closest(LaplacianSystem *sys, int vertex, int bone)
+{
+ float dist;
+
+ dist= heat_bone_distance(sys, vertex, bone);
+
+ if(dist <= sys->heat.mindist[vertex]*(1.0f + DISTANCE_EPSILON))
+ if(heat_ray_bone_visible(sys, vertex, bone))
+ return 1;
+
+ return 0;
+}
+
+static void heat_set_H(LaplacianSystem *sys, int vertex)
+{
+ float dist, mindist, h;
+ int j, numclosest = 0;
+
+ mindist= 1e10;
+
+ /* compute minimum distance */
+ for(j=0; j<sys->heat.numbones; j++) {
+ dist= heat_bone_distance(sys, vertex, j);
+
+ if(dist < mindist)
+ mindist= dist;
+ }
+
+ sys->heat.mindist[vertex]= mindist;
+
+ /* count number of bones with approximately this minimum distance */
+ for(j=0; j<sys->heat.numbones; j++)
+ if(heat_bone_closest(sys, vertex, j))
+ numclosest++;
+
+ sys->heat.p[vertex]= (numclosest > 0)? 1.0f/numclosest: 0.0f;
+
+ /* compute H entry */
+ if(numclosest > 0) {
+ if(mindist > 1e-5)
+ h= numclosest*C_WEIGHT/(mindist*mindist);
+ else
+ h= 1e10f;
+ }
+ else
+ h= 0.0f;
+
+ sys->heat.H[vertex]= h;
+}
+
+void heat_calc_vnormals(LaplacianSystem *sys)
+{
+ float fnor[3];
+ int a, v1, v2, v3, (*face)[3];
+
+ sys->heat.vnors= MEM_callocN(sizeof(float)*3*sys->totvert, "HeatVNors");
+
+ for(a=0, face=sys->faces; a<sys->totface; a++, face++) {
+ v1= (*face)[0];
+ v2= (*face)[1];
+ v3= (*face)[2];
+
+ CalcNormFloat(sys->verts[v1], sys->verts[v2], sys->verts[v3], fnor);
+
+ VecAddf(sys->heat.vnors[v1], sys->heat.vnors[v1], fnor);
+ VecAddf(sys->heat.vnors[v2], sys->heat.vnors[v2], fnor);
+ VecAddf(sys->heat.vnors[v3], sys->heat.vnors[v3], fnor);
+ }
+
+ for(a=0; a<sys->totvert; a++)
+ Normalize(sys->heat.vnors[a]);
+}
+
+static void heat_laplacian_create(LaplacianSystem *sys)
+{
+ Mesh *me = sys->heat.mesh;
+ MFace *mface;
+ int a;
+
+ /* heat specific definitions */
+ sys->heat.mindist= MEM_callocN(sizeof(float)*me->totvert, "HeatMinDist");
+ sys->heat.H= MEM_callocN(sizeof(float)*me->totvert, "HeatH");
+ sys->heat.p= MEM_callocN(sizeof(float)*me->totvert, "HeatP");
+
+ /* add verts and faces to laplacian */
+ for(a=0; a<me->totvert; a++)
+ laplacian_add_vertex(sys, sys->heat.verts[a], 0);
+
+ for(a=0, mface=me->mface; a<me->totface; a++, mface++) {
+ laplacian_add_triangle(sys, mface->v1, mface->v2, mface->v3);
+ if(mface->v4)
+ laplacian_add_triangle(sys, mface->v1, mface->v3, mface->v4);
+ }
+
+ /* for distance computation in set_H */
+ heat_calc_vnormals(sys);
+
+ for(a=0; a<me->totvert; a++)
+ heat_set_H(sys, a);
+}
+
+static float heat_limit_weight(float weight)
+{
+ float t;
+
+ if(weight < WEIGHT_LIMIT_END) {
+ return 0.0f;
+ }
+ else if(weight < WEIGHT_LIMIT_START) {
+ t= (weight - WEIGHT_LIMIT_END)/(WEIGHT_LIMIT_START - WEIGHT_LIMIT_END);
+ return t*WEIGHT_LIMIT_START;
+ }
+ else
+ return weight;
+}
+
+void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numbones, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected)
+{
+ LaplacianSystem *sys;
+ MFace *mface;
+ float solution, weight;
+ int *vertsflipped = NULL;
+ int a, totface, j, bbone, firstsegment, lastsegment, thrownerror = 0;
+
+ /* count triangles */
+ for(totface=0, a=0, mface=me->mface; a<me->totface; a++, mface++) {
+ totface++;
+ if(mface->v4) totface++;
+ }
+
+ /* create laplacian */
+ sys = laplacian_system_construct_begin(me->totvert, totface);
+
+ sys->heat.mesh= me;
+ sys->heat.verts= verts;
+ sys->heat.root= root;
+ sys->heat.tip= tip;
+ sys->heat.numbones= numbones;
+
+ heat_ray_tree_create(sys);
+ heat_laplacian_create(sys);
+
+ laplacian_system_construct_end(sys);
+
+ if(dgroupflip) {
+ vertsflipped = MEM_callocN(sizeof(int)*me->totvert, "vertsflipped");
+ for(a=0; a<me->totvert; a++)
+ vertsflipped[a] = mesh_get_x_mirror_vert(ob, a);
+ }
+
+ /* compute weights per bone */
+ for(j=0; j<numbones; j++) {
+ if(!selected[j])
+ continue;
+
+ firstsegment= (j == 0 || dgrouplist[j-1] != dgrouplist[j]);
+ lastsegment= (j == numbones-1 || dgrouplist[j] != dgrouplist[j+1]);
+ bbone= !(firstsegment && lastsegment);
+
+ /* clear weights */
+ if(bbone && firstsegment) {
+ for(a=0; a<me->totvert; a++) {
+ remove_vert_defgroup(ob, dgrouplist[j], a);
+ if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0)
+ remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
+ }
+ }
+
+ /* fill right hand side */
+ laplacian_begin_solve(sys, -1);
+
+ for(a=0; a<me->totvert; a++)
+ if(heat_bone_closest(sys, a, j))
+ laplacian_add_right_hand_side(sys, a,
+ sys->heat.H[a]*sys->heat.p[a]);
+
+ /* solve */
+ if(laplacian_system_solve(sys)) {
+ /* load solution into vertex groups */
+ for(a=0; a<me->totvert; a++) {
+ solution= laplacian_system_get_solution(a);
+
+ if(bbone) {
+ if(solution > 0.0f)
+ add_vert_to_defgroup(ob, dgrouplist[j], a, solution,
+ WEIGHT_ADD);
+ }
+ else {
+ weight= heat_limit_weight(solution);
+ if(weight > 0.0f)
+ add_vert_to_defgroup(ob, dgrouplist[j], a, weight,
+ WEIGHT_REPLACE);
+ else
+ remove_vert_defgroup(ob, dgrouplist[j], a);
+ }
+
+ /* do same for mirror */
+ if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
+ if(bbone) {
+ if(solution > 0.0f)
+ add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a],
+ solution, WEIGHT_ADD);
+ }
+ else {
+ weight= heat_limit_weight(solution);
+ if(weight > 0.0f)
+ add_vert_to_defgroup(ob, dgroupflip[j], vertsflipped[a],
+ weight, WEIGHT_REPLACE);
+ else
+ remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
+ }
+ }
+ }
+ }
+ else if(!thrownerror) {
+ error("Bone Heat Weighting:"
+ " failed to find solution for one or more bones");
+ thrownerror= 1;
+ break;
+ }
+
+ /* remove too small vertex weights */
+ if(bbone && lastsegment) {
+ for(a=0; a<me->totvert; a++) {
+ weight= get_vert_defgroup(ob, dgrouplist[j], a);
+ weight= heat_limit_weight(weight);
+ if(weight <= 0.0f)
+ remove_vert_defgroup(ob, dgrouplist[j], a);
+
+ if(vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
+ weight= get_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
+ weight= heat_limit_weight(weight);
+ if(weight <= 0.0f)
+ remove_vert_defgroup(ob, dgroupflip[j], vertsflipped[a]);
+ }
+ }
+ }
+ }
+
+ /* free */
+ if(vertsflipped) MEM_freeN(vertsflipped);
+
+ RE_ray_tree_free(sys->heat.raytree);
+ MEM_freeN(sys->heat.vface);
+
+ MEM_freeN(sys->heat.mindist);
+ MEM_freeN(sys->heat.H);
+ MEM_freeN(sys->heat.p);
+ MEM_freeN(sys->heat.vnors);
+
+ laplacian_system_delete(sys);
+}
+
+#ifdef RIGID_DEFORM
+/********************** As-Rigid-As-Possible Deformation ******************/
+/* From "As-Rigid-As-Possible Surface Modeling",
+ Olga Sorkine and Marc Alexa, ESGP 2007. */
+
+/* investigate:
+ - transpose R in orthogonal
+ - flipped normals and per face adding
+ - move cancelling to transform, make origco pointer
+*/
+
+static LaplacianSystem *RigidDeformSystem = NULL;
+
+static void rigid_add_half_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w)
+{
+ float e[3], e_[3];
+ int i;
+
+ VecSubf(e, sys->rigid.origco[v1->tmp.l], sys->rigid.origco[v2->tmp.l]);
+ VecSubf(e_, v1->co, v2->co);
+
+ /* formula (5) */
+ for (i=0; i<3; i++) {
+ sys->rigid.R[v1->tmp.l][i][0] += w*e[0]*e_[i];
+ sys->rigid.R[v1->tmp.l][i][1] += w*e[1]*e_[i];
+ sys->rigid.R[v1->tmp.l][i][2] += w*e[2]*e_[i];
+ }
+}
+
+static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w)
+{
+ rigid_add_half_edge_to_R(sys, v1, v2, w);
+ rigid_add_half_edge_to_R(sys, v2, v1, w);
+}
+
+static void rigid_orthogonalize_R(float R[][3])
+{
+ HMatrix M, Q, S;
+
+ Mat4CpyMat3(M, R);
+ polar_decomp(M, Q, S);
+ Mat3CpyMat4(R, Q);
+}
+
+static void rigid_add_half_edge_to_rhs(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w)
+{
+ /* formula (8) */
+ float Rsum[3][3], rhs[3];
+
+ if (sys->vpinned[v1->tmp.l])
+ return;
+
+ Mat3AddMat3(Rsum, sys->rigid.R[v1->tmp.l], sys->rigid.R[v2->tmp.l]);
+ Mat3Transp(Rsum);
+
+ VecSubf(rhs, sys->rigid.origco[v1->tmp.l], sys->rigid.origco[v2->tmp.l]);
+ Mat3MulVecfl(Rsum, rhs);
+ VecMulf(rhs, 0.5f);
+ VecMulf(rhs, w);
+
+ VecAddf(sys->rigid.rhs[v1->tmp.l], sys->rigid.rhs[v1->tmp.l], rhs);
+}
+
+static void rigid_add_edge_to_rhs(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w)
+{
+ rigid_add_half_edge_to_rhs(sys, v1, v2, w);
+ rigid_add_half_edge_to_rhs(sys, v2, v1, w);
+}
+
+void rigid_deform_iteration()
+{
+ LaplacianSystem *sys= RigidDeformSystem;
+ EditMesh *em;
+ EditVert *eve;
+ EditFace *efa;
+ int a, i;
+
+ if(!sys)
+ return;
+
+ nlMakeCurrent(sys->context);
+ em= sys->rigid.mesh;
+
+ /* compute R */
+ memset(sys->rigid.R, 0, sizeof(float)*3*3*sys->totvert);
+ memset(sys->rigid.rhs, 0, sizeof(float)*3*sys->totvert);
+
+ for(a=0, efa=em->faces.first; efa; efa=efa->next, a++) {
+ rigid_add_edge_to_R(sys, efa->v1, efa->v2, sys->fweights[a][2]);
+ rigid_add_edge_to_R(sys, efa->v2, efa->v3, sys->fweights[a][0]);
+ rigid_add_edge_to_R(sys, efa->v3, efa->v1, sys->fweights[a][1]);
+
+ if(efa->v4) {
+ a++;
+ rigid_add_edge_to_R(sys, efa->v1, efa->v3, sys->fweights[a][2]);
+ rigid_add_edge_to_R(sys, efa->v3, efa->v4, sys->fweights[a][0]);
+ rigid_add_edge_to_R(sys, efa->v4, efa->v1, sys->fweights[a][1]);
+ }
+ }
+
+ for(a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
+ rigid_orthogonalize_R(sys->rigid.R[a]);
+ eve->tmp.l= a;
+ }
+
+ /* compute right hand sides for solving */
+ for(a=0, efa=em->faces.first; efa; efa=efa->next, a++) {
+ rigid_add_edge_to_rhs(sys, efa->v1, efa->v2, sys->fweights[a][2]);
+ rigid_add_edge_to_rhs(sys, efa->v2, efa->v3, sys->fweights[a][0]);
+ rigid_add_edge_to_rhs(sys, efa->v3, efa->v1, sys->fweights[a][1]);
+
+ if(efa->v4) {
+ a++;
+ rigid_add_edge_to_rhs(sys, efa->v1, efa->v3, sys->fweights[a][2]);
+ rigid_add_edge_to_rhs(sys, efa->v3, efa->v4, sys->fweights[a][0]);
+ rigid_add_edge_to_rhs(sys, efa->v4, efa->v1, sys->fweights[a][1]);
+ }
+ }
+
+ /* solve for positions, for X,Y and Z separately */
+ for(i=0; i<3; i++) {
+ laplacian_begin_solve(sys, i);
+
+ for(a=0; a<sys->totvert; a++)
+ if(!sys->vpinned[a])
+ laplacian_add_right_hand_side(sys, a, sys->rigid.rhs[a][i]);
+
+ if(laplacian_system_solve(sys)) {
+ for(a=0, eve=em->verts.first; eve; eve=eve->next, a++)
+ eve->co[i]= laplacian_system_get_solution(a);
+ }
+ else {
+ if(!sys->rigid.thrownerror) {
+ error("RigidDeform: failed to find solution.");
+ sys->rigid.thrownerror= 1;
+ }
+ break;
+ }
+ }
+}
+
+static void rigid_laplacian_create(LaplacianSystem *sys)
+{
+ EditMesh *em = sys->rigid.mesh;
+ EditVert *eve;
+ EditFace *efa;
+ int a;
+
+ /* add verts and faces to laplacian */
+ for(a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
+ laplacian_add_vertex(sys, eve->co, eve->pinned);
+ eve->tmp.l= a;
+ }
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ laplacian_add_triangle(sys,
+ efa->v1->tmp.l, efa->v2->tmp.l, efa->v3->tmp.l);
+ if(efa->v4)
+ laplacian_add_triangle(sys,
+ efa->v1->tmp.l, efa->v3->tmp.l, efa->v4->tmp.l);
+ }
+}
+
+void rigid_deform_begin(EditMesh *em)
+{
+ LaplacianSystem *sys;
+ EditVert *eve;
+ EditFace *efa;
+ int a, totvert, totface;
+
+ /* count vertices, triangles */
+ for(totvert=0, eve=em->verts.first; eve; eve=eve->next)
+ totvert++;
+
+ for(totface=0, efa=em->faces.first; efa; efa=efa->next) {
+ totface++;
+ if(efa->v4) totface++;
+ }
+
+ /* create laplacian */
+ sys = laplacian_system_construct_begin(totvert, totface);
+
+ sys->rigid.mesh= em;
+ sys->rigid.R = MEM_callocN(sizeof(float)*3*3*totvert, "RigidDeformR");
+ sys->rigid.rhs = MEM_callocN(sizeof(float)*3*totvert, "RigidDeformRHS");
+ sys->rigid.origco = MEM_callocN(sizeof(float)*3*totvert, "RigidDeformCo");
+
+ for(a=0, eve=em->verts.first; eve; eve=eve->next, a++)
+ VecCopyf(sys->rigid.origco[a], eve->co);
+
+ sys->areaweights= 0;
+ sys->storeweights= 1;
+
+ rigid_laplacian_create(sys);
+
+ laplacian_system_construct_end(sys);
+
+ RigidDeformSystem = sys;
+}
+
+void rigid_deform_end(int cancel)
+{
+ LaplacianSystem *sys = RigidDeformSystem;
+
+ if(sys) {
+ EditMesh *em = sys->rigid.mesh;
+ EditVert *eve;
+ int a;
+
+ if(cancel)
+ for(a=0, eve=em->verts.first; eve; eve=eve->next, a++)
+ if(!eve->pinned)
+ VecCopyf(eve->co, sys->rigid.origco[a]);
+
+ if(sys->rigid.R) MEM_freeN(sys->rigid.R);
+ if(sys->rigid.rhs) MEM_freeN(sys->rigid.rhs);
+ if(sys->rigid.origco) MEM_freeN(sys->rigid.origco);
+
+ /* free */
+ laplacian_system_delete(sys);
+ }
+
+ RigidDeformSystem = NULL;
+}
+#endif
+
+/************************** Harmonic Coordinates ****************************/
+/* From "Harmonic Coordinates for Character Articulation",
+ Pushkar Joshi, Mark Meyer, Tony DeRose, Brian Green and Tom Sanocki,
+ SIGGRAPH 2007. */
+
+#define EPSILON 0.0001f
+
+#define MESHDEFORM_TAG_UNTYPED 0
+#define MESHDEFORM_TAG_BOUNDARY 1
+#define MESHDEFORM_TAG_INTERIOR 2
+#define MESHDEFORM_TAG_EXTERIOR 3
+
+#define MESHDEFORM_LEN_THRESHOLD 1e-6
+
+#define MESHDEFORM_MIN_INFLUENCE 0.0005
+
+static int MESHDEFORM_OFFSET[7][3] =
+ {{0,0,0}, {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}};
+
+typedef struct MDefBoundIsect {
+ float co[3], uvw[4];
+ int nvert, v[4], facing;
+ float len;
+} MDefBoundIsect;
+
+typedef struct MDefBindInfluence {
+ struct MDefBindInfluence *next;
+ float weight;
+ int vertex;
+} MDefBindInfluence;
+
+typedef struct MeshDeformBind {
+ /* grid dimensions */
+ float min[3], max[3];
+ float width[3], halfwidth[3];
+ int size, size3;
+
+ /* meshes */
+ DerivedMesh *cagedm;
+ float (*cagecos)[3];
+ float (*vertexcos)[3];
+ int totvert, totcagevert;
+
+ /* grids */
+ MemArena *memarena;
+ MDefBoundIsect *(*boundisect)[6];
+ int *semibound;
+ int *tag;
+ float *phi, *totalphi;
+
+ /* mesh stuff */
+ int *inside;
+ float *weights;
+ MDefBindInfluence **dyngrid;
+ float cagemat[4][4];
+
+ /* direct solver */
+ int *varidx;
+
+ /* raytrace */
+ RayTree *raytree;
+} MeshDeformBind;
+
+/* ray intersection */
+
+/* our own triangle intersection, so we can fully control the epsilons and
+ * prevent corner case from going wrong*/
+static int meshdeform_tri_intersect(float orig[3], float end[3], float vert0[3],
+ float vert1[3], float vert2[3], float *isectco, float *uvw)
+{
+ float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
+ float det,inv_det, u, v, dir[3], isectdir[3];
+
+ VECSUB(dir, end, orig);
+
+ /* find vectors for two edges sharing vert0 */
+ VECSUB(edge1, vert1, vert0);
+ VECSUB(edge2, vert2, vert0);
+
+ /* begin calculating determinant - also used to calculate U parameter */
+ Crossf(pvec, dir, edge2);
+
+ /* if determinant is near zero, ray lies in plane of triangle */
+ det = INPR(edge1, pvec);
+
+ if (det == 0.0f)
+ return 0;
+ inv_det = 1.0f / det;
+
+ /* calculate distance from vert0 to ray origin */
+ VECSUB(tvec, orig, vert0);
+
+ /* calculate U parameter and test bounds */
+ u = INPR(tvec, pvec) * inv_det;
+ if (u < -EPSILON || u > 1.0f+EPSILON)
+ return 0;
+
+ /* prepare to test V parameter */
+ Crossf(qvec, tvec, edge1);
+
+ /* calculate V parameter and test bounds */
+ v = INPR(dir, qvec) * inv_det;
+ if (v < -EPSILON || u + v > 1.0f+EPSILON)
+ return 0;
+
+ isectco[0]= (1.0f - u - v)*vert0[0] + u*vert1[0] + v*vert2[0];
+ isectco[1]= (1.0f - u - v)*vert0[1] + u*vert1[1] + v*vert2[1];
+ isectco[2]= (1.0f - u - v)*vert0[2] + u*vert1[2] + v*vert2[2];
+
+ uvw[0]= 1.0 - u - v;
+ uvw[1]= u;
+ uvw[2]= v;
+
+ /* check if it is within the length of the line segment */
+ VECSUB(isectdir, isectco, orig);
+
+ if(INPR(dir, isectdir) < -EPSILON)
+ return 0;
+
+ if(INPR(dir, dir) + EPSILON < INPR(isectdir, isectdir))
+ return 0;
+
+ return 1;
+}
+
+/* blender's raytracer is not use now, even though it is much faster. it can
+ * give problems with rays falling through, so we use our own intersection
+ * function above with tweaked epsilons */
+
+#if 0
+static MeshDeformBind *MESHDEFORM_BIND = NULL;
+
+static void meshdeform_ray_coords_func(RayFace *face, float **v1, float **v2, float **v3, float **v4)
+{
+ MFace *mface= (MFace*)face;
+ float (*cagecos)[3]= MESHDEFORM_BIND->cagecos;
+
+ *v1= cagecos[mface->v1];
+ *v2= cagecos[mface->v2];
+ *v3= cagecos[mface->v3];
+ *v4= (mface->v4)? cagecos[mface->v4]: NULL;
+}
+
+static int meshdeform_ray_check_func(Isect *is, RayFace *face)
+{
+ return 1;
+}
+
+static void meshdeform_ray_tree_create(MeshDeformBind *mdb)
+{
+ MFace *mface;
+ float min[3], max[3];
+ int a, totface;
+
+ /* create a raytrace tree from the mesh */
+ INIT_MINMAX(min, max);
+
+ for(a=0; a<mdb->totcagevert; a++)
+ DO_MINMAX(mdb->cagecos[a], min, max)
+
+ MESHDEFORM_BIND= mdb;
+
+ mface= mdb->cagedm->getFaceArray(mdb->cagedm);
+ totface= mdb->cagedm->getNumFaces(mdb->cagedm);
+
+ mdb->raytree= RE_ray_tree_create(64, totface, min, max,
+ meshdeform_ray_coords_func, meshdeform_ray_check_func);
+
+ for(a=0; a<totface; a++, mface++)
+ RE_ray_tree_add_face(mdb->raytree, mface);
+
+ RE_ray_tree_done(mdb->raytree);
+}
+
+static void meshdeform_ray_tree_free(MeshDeformBind *mdb)
+{
+ MESHDEFORM_BIND= NULL;
+ RE_ray_tree_free(mdb->raytree);
+}
+#endif
+
+static int meshdeform_intersect(MeshDeformBind *mdb, Isect *isec)
+{
+ MFace *mface;
+ float face[4][3], co[3], uvw[3], len, nor[3];
+ int f, hit, is= 0, totface;
+
+ isec->labda= 1e10;
+
+ mface= mdb->cagedm->getFaceArray(mdb->cagedm);
+ totface= mdb->cagedm->getNumFaces(mdb->cagedm);
+
+ for(f=0; f<totface; f++, mface++) {
+ VECCOPY(face[0], mdb->cagecos[mface->v1]);
+ VECCOPY(face[1], mdb->cagecos[mface->v2]);
+ VECCOPY(face[2], mdb->cagecos[mface->v3]);
+
+ if(mface->v4) {
+ VECCOPY(face[3], mdb->cagecos[mface->v4]);
+ hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[1], face[2], co, uvw);
+
+ if(hit) {
+ CalcNormFloat(face[0], face[1], face[2], nor);
+ }
+ else {
+ hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[2], face[3], co, uvw);
+ CalcNormFloat(face[0], face[2], face[3], nor);
+ }
+ }
+ else {
+ hit= meshdeform_tri_intersect(isec->start, isec->end, face[0], face[1], face[2], co, uvw);
+ CalcNormFloat(face[0], face[1], face[2], nor);
+ }
+
+ if(hit) {
+ len= VecLenf(isec->start, co)/VecLenf(isec->start, isec->end);
+ if(len < isec->labda) {
+ isec->labda= len;
+ isec->face= mface;
+ isec->isect= (INPR(isec->vec, nor) <= 0.0f);
+ is= 1;
+ }
+ }
+ }
+
+ return is;
+}
+
+static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float *co1, float *co2)
+{
+ MDefBoundIsect *isect;
+ Isect isec;
+ float (*cagecos)[3];
+ MFace *mface;
+ float vert[4][3], len;
+ static float epsilon[3]= {0, 0, 0}; //1e-4, 1e-4, 1e-4};
+
+ /* setup isec */
+ memset(&isec, 0, sizeof(isec));
+ isec.mode= RE_RAY_MIRROR; /* we want the closest intersection */
+ isec.lay= -1;
+ isec.face_last= NULL;
+ isec.faceorig= NULL;
+ isec.labda= 1e10f;
+
+ VECADD(isec.start, co1, epsilon);
+ VECADD(isec.end, co2, epsilon);
+ VECSUB(isec.vec, isec.end, isec.start);
+
+#if 0
+ /*if(RE_ray_tree_intersect(mdb->raytree, &isec)) {*/
+#endif
+
+ if(meshdeform_intersect(mdb, &isec)) {
+ len= isec.labda;
+ mface= isec.face;
+
+ /* create MDefBoundIsect */
+ isect= BLI_memarena_alloc(mdb->memarena, sizeof(*isect));
+
+ /* compute intersection coordinate */
+ isect->co[0]= co1[0] + isec.vec[0]*len;
+ isect->co[1]= co1[1] + isec.vec[1]*len;
+ isect->co[2]= co1[2] + isec.vec[2]*len;
+
+ isect->len= VecLenf(co1, isect->co);
+ if(isect->len < MESHDEFORM_LEN_THRESHOLD)
+ isect->len= MESHDEFORM_LEN_THRESHOLD;
+
+ isect->v[0]= mface->v1;
+ isect->v[1]= mface->v2;
+ isect->v[2]= mface->v3;
+ isect->v[3]= mface->v4;
+ isect->nvert= (mface->v4)? 4: 3;
+
+ isect->facing= isec.isect;
+
+ /* compute mean value coordinates for interpolation */
+ cagecos= mdb->cagecos;
+ VECCOPY(vert[0], cagecos[mface->v1]);
+ VECCOPY(vert[1], cagecos[mface->v2]);
+ VECCOPY(vert[2], cagecos[mface->v3]);
+ if(mface->v4) VECCOPY(vert[3], cagecos[mface->v4]);
+ MeanValueWeights(vert, isect->nvert, isect->co, isect->uvw);
+
+ return isect;
+ }
+
+ return NULL;
+}
+
+static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co)
+{
+ MDefBoundIsect *isect;
+ float outside[3], start[3], dir[3];
+ int i, counter;
+
+ for(i=1; i<=6; i++) {
+ counter = 0;
+
+ outside[0] = co[0] + (mdb->max[0] - mdb->min[0] + 1.0f)*MESHDEFORM_OFFSET[i][0];
+ outside[1] = co[1] + (mdb->max[1] - mdb->min[1] + 1.0f)*MESHDEFORM_OFFSET[i][1];
+ outside[2] = co[2] + (mdb->max[2] - mdb->min[2] + 1.0f)*MESHDEFORM_OFFSET[i][2];
+
+ VECSUB(dir, outside, start);
+ Normalize(dir);
+ VECCOPY(start, co);
+
+ isect = meshdeform_ray_tree_intersect(mdb, start, outside);
+ if(isect && !isect->facing)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* solving */
+
+static int meshdeform_index(MeshDeformBind *mdb, int x, int y, int z, int n)
+{
+ int size= mdb->size;
+
+ x += MESHDEFORM_OFFSET[n][0];
+ y += MESHDEFORM_OFFSET[n][1];
+ z += MESHDEFORM_OFFSET[n][2];
+
+ if(x < 0 || x >= mdb->size)
+ return -1;
+ if(y < 0 || y >= mdb->size)
+ return -1;
+ if(z < 0 || z >= mdb->size)
+ return -1;
+
+ return x + y*size + z*size*size;
+}
+
+static void meshdeform_cell_center(MeshDeformBind *mdb, int x, int y, int z, int n, float *center)
+{
+ x += MESHDEFORM_OFFSET[n][0];
+ y += MESHDEFORM_OFFSET[n][1];
+ z += MESHDEFORM_OFFSET[n][2];
+
+ center[0]= mdb->min[0] + x*mdb->width[0] + mdb->halfwidth[0];
+ center[1]= mdb->min[1] + y*mdb->width[1] + mdb->halfwidth[1];
+ center[2]= mdb->min[2] + z*mdb->width[2] + mdb->halfwidth[2];
+}
+
+static void meshdeform_add_intersections(MeshDeformBind *mdb, int x, int y, int z)
+{
+ MDefBoundIsect *isect;
+ float center[3], ncenter[3];
+ int i, a;
+
+ a= meshdeform_index(mdb, x, y, z, 0);
+ meshdeform_cell_center(mdb, x, y, z, 0, center);
+
+ /* check each outgoing edge for intersection */
+ for(i=1; i<=6; i++) {
+ if(meshdeform_index(mdb, x, y, z, i) == -1)
+ continue;
+
+ meshdeform_cell_center(mdb, x, y, z, i, ncenter);
+
+ isect= meshdeform_ray_tree_intersect(mdb, center, ncenter);
+ if(isect) {
+ mdb->boundisect[a][i-1]= isect;
+ mdb->tag[a]= MESHDEFORM_TAG_BOUNDARY;
+ }
+ }
+}
+
+static void meshdeform_bind_floodfill(MeshDeformBind *mdb)
+{
+ int *stack, *tag= mdb->tag;
+ int a, b, i, xyz[3], stacksize, size= mdb->size;
+
+ stack= MEM_callocN(sizeof(int)*mdb->size3, "MeshDeformBindStack");
+
+ /* we know lower left corner is EXTERIOR because of padding */
+ tag[0]= MESHDEFORM_TAG_EXTERIOR;
+ stack[0]= 0;
+ stacksize= 1;
+
+ /* floodfill exterior tag */
+ while(stacksize > 0) {
+ a= stack[--stacksize];
+
+ xyz[2]= a/(size*size);
+ xyz[1]= (a - xyz[2]*size*size)/size;
+ xyz[0]= a - xyz[1]*size - xyz[2]*size*size;
+
+ for(i=1; i<=6; i++) {
+ b= meshdeform_index(mdb, xyz[0], xyz[1], xyz[2], i);
+
+ if(b != -1) {
+ if(tag[b] == MESHDEFORM_TAG_UNTYPED ||
+ (tag[b] == MESHDEFORM_TAG_BOUNDARY && !mdb->boundisect[a][i-1])) {
+ tag[b]= MESHDEFORM_TAG_EXTERIOR;
+ stack[stacksize++]= b;
+ }
+ }
+ }
+ }
+
+ /* other cells are interior */
+ for(a=0; a<size*size*size; a++)
+ if(tag[a]==MESHDEFORM_TAG_UNTYPED)
+ tag[a]= MESHDEFORM_TAG_INTERIOR;
+
+#if 0
+ {
+ int tb, ti, te, ts;
+ tb= ti= te= ts= 0;
+ for(a=0; a<size*size*size; a++)
+ if(tag[a]==MESHDEFORM_TAG_BOUNDARY)
+ tb++;
+ else if(tag[a]==MESHDEFORM_TAG_INTERIOR)
+ ti++;
+ else if(tag[a]==MESHDEFORM_TAG_EXTERIOR) {
+ te++;
+
+ if(mdb->semibound[a])
+ ts++;
+ }
+
+ printf("interior %d exterior %d boundary %d semi-boundary %d\n", ti, te, tb, ts);
+ }
+#endif
+
+ MEM_freeN(stack);
+}
+
+static float meshdeform_boundary_phi(MeshDeformBind *mdb, MDefBoundIsect *isect, int cagevert)
+{
+ int a;
+
+ for(a=0; a<isect->nvert; a++)
+ if(isect->v[a] == cagevert)
+ return isect->uvw[a];
+
+ return 0.0f;
+}
+
+static float meshdeform_interp_w(MeshDeformBind *mdb, float *gridvec, float *vec, int cagevert)
+{
+ float dvec[3], ivec[3], wx, wy, wz, result=0.0f;
+ float weight, totweight= 0.0f;
+ int i, a, x, y, z;
+
+ for(i=0; i<3; i++) {
+ ivec[i]= (int)gridvec[i];
+ dvec[i]= gridvec[i] - ivec[i];
+ }
+
+ for(i=0; i<8; i++) {
+ if(i & 1) { x= ivec[0]+1; wx= dvec[0]; }
+ else { x= ivec[0]; wx= 1.0f-dvec[0]; }
+
+ if(i & 2) { y= ivec[1]+1; wy= dvec[1]; }
+ else { y= ivec[1]; wy= 1.0f-dvec[1]; }
+
+ if(i & 4) { z= ivec[2]+1; wz= dvec[2]; }
+ else { z= ivec[2]; wz= 1.0f-dvec[2]; }
+
+ CLAMP(x, 0, mdb->size-1);
+ CLAMP(y, 0, mdb->size-1);
+ CLAMP(z, 0, mdb->size-1);
+
+ a= meshdeform_index(mdb, x, y, z, 0);
+ weight= wx*wy*wz;
+ result += weight*mdb->phi[a];
+ totweight += weight;
+ }
+
+ if(totweight > 0.0f)
+ result /= totweight;
+
+ return result;
+}
+
+static void meshdeform_check_semibound(MeshDeformBind *mdb, int x, int y, int z)
+{
+ int i, a;
+
+ a= meshdeform_index(mdb, x, y, z, 0);
+ if(mdb->tag[a] != MESHDEFORM_TAG_EXTERIOR)
+ return;
+
+ for(i=1; i<=6; i++)
+ if(mdb->boundisect[a][i-1])
+ mdb->semibound[a]= 1;
+}
+
+static float meshdeform_boundary_total_weight(MeshDeformBind *mdb, int x, int y, int z)
+{
+ float weight, totweight= 0.0f;
+ int i, a;
+
+ a= meshdeform_index(mdb, x, y, z, 0);
+
+ /* count weight for neighbour cells */
+ for(i=1; i<=6; i++) {
+ if(meshdeform_index(mdb, x, y, z, i) == -1)
+ continue;
+
+ if(mdb->boundisect[a][i-1])
+ weight= 1.0f/mdb->boundisect[a][i-1]->len;
+ else if(!mdb->semibound[a])
+ weight= 1.0f/mdb->width[0];
+ else
+ weight= 0.0f;
+
+ totweight += weight;
+ }
+
+ return totweight;
+}
+
+static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z)
+{
+ MDefBoundIsect *isect;
+ float weight, totweight;
+ int i, a, acenter;
+
+ acenter= meshdeform_index(mdb, x, y, z, 0);
+ if(mdb->tag[acenter] == MESHDEFORM_TAG_EXTERIOR)
+ return;
+
+ nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[acenter], 1.0f);
+
+ totweight= meshdeform_boundary_total_weight(mdb, x, y, z);
+ for(i=1; i<=6; i++) {
+ a= meshdeform_index(mdb, x, y, z, i);
+ if(a == -1 || mdb->tag[a] == MESHDEFORM_TAG_EXTERIOR)
+ continue;
+
+ isect= mdb->boundisect[acenter][i-1];
+ if (!isect) {
+ weight= (1.0f/mdb->width[0])/totweight;
+ nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[a], -weight);
+ }
+ }
+}
+
+static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, int x, int y, int z, int cagevert)
+{
+ MDefBoundIsect *isect;
+ float rhs, weight, totweight;
+ int i, a, acenter;
+
+ acenter= meshdeform_index(mdb, x, y, z, 0);
+ if(mdb->tag[acenter] == MESHDEFORM_TAG_EXTERIOR)
+ return;
+
+ totweight= meshdeform_boundary_total_weight(mdb, x, y, z);
+ for(i=1; i<=6; i++) {
+ a= meshdeform_index(mdb, x, y, z, i);
+ if(a == -1)
+ continue;
+
+ isect= mdb->boundisect[acenter][i-1];
+
+ if (isect) {
+ weight= (1.0f/isect->len)/totweight;
+ rhs= weight*meshdeform_boundary_phi(mdb, isect, cagevert);
+ nlRightHandSideAdd(0, mdb->varidx[acenter], rhs);
+ }
+ }
+}
+
+static void meshdeform_matrix_add_semibound_phi(MeshDeformBind *mdb, int x, int y, int z, int cagevert)
+{
+ MDefBoundIsect *isect;
+ float rhs, weight, totweight;
+ int i, a;
+
+ a= meshdeform_index(mdb, x, y, z, 0);
+ if(!mdb->semibound[a])
+ return;
+
+ mdb->phi[a]= 0.0f;
+
+ totweight= meshdeform_boundary_total_weight(mdb, x, y, z);
+ for(i=1; i<=6; i++) {
+ isect= mdb->boundisect[a][i-1];
+
+ if (isect) {
+ weight= (1.0f/isect->len)/totweight;
+ rhs= weight*meshdeform_boundary_phi(mdb, isect, cagevert);
+ mdb->phi[a] += rhs;
+ }
+ }
+}
+
+static void meshdeform_matrix_add_exterior_phi(MeshDeformBind *mdb, int x, int y, int z, int cagevert)
+{
+ float phi, totweight;
+ int i, a, acenter;
+
+ acenter= meshdeform_index(mdb, x, y, z, 0);
+ if(mdb->tag[acenter] != MESHDEFORM_TAG_EXTERIOR || mdb->semibound[acenter])
+ return;
+
+ phi= 0.0f;
+ totweight= 0.0f;
+ for(i=1; i<=6; i++) {
+ a= meshdeform_index(mdb, x, y, z, i);
+
+ if(a != -1 && mdb->semibound[a]) {
+ phi += mdb->phi[a];
+ totweight += 1.0f;
+ }
+ }
+
+ if(totweight != 0.0f)
+ mdb->phi[acenter]= phi/totweight;
+}
+
+static void meshdeform_matrix_solve(MeshDeformBind *mdb)
+{
+ NLContext *context;
+ float vec[3], gridvec[3];
+ int a, b, x, y, z, totvar;
+ char message[1024];
+
+ /* setup variable indices */
+ mdb->varidx= MEM_callocN(sizeof(int)*mdb->size3, "MeshDeformDSvaridx");
+ for(a=0, totvar=0; a<mdb->size3; a++)
+ mdb->varidx[a]= (mdb->tag[a] == MESHDEFORM_TAG_EXTERIOR)? -1: totvar++;
+
+ if(totvar == 0) {
+ MEM_freeN(mdb->varidx);
+ return;
+ }
+
+ progress_bar(0, "Starting mesh deform solve");
+
+ /* setup opennl solver */
+ nlNewContext();
+ context= nlGetCurrent();
+
+ nlSolverParameteri(NL_NB_VARIABLES, totvar);
+ nlSolverParameteri(NL_NB_ROWS, totvar);
+ nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 1);
+
+ nlBegin(NL_SYSTEM);
+ nlBegin(NL_MATRIX);
+
+ /* build matrix */
+ for(z=0; z<mdb->size; z++)
+ for(y=0; y<mdb->size; y++)
+ for(x=0; x<mdb->size; x++)
+ meshdeform_matrix_add_cell(mdb, x, y, z);
+
+ /* solve for each cage vert */
+ for(a=0; a<mdb->totcagevert; a++) {
+ if(a != 0) {
+ nlBegin(NL_SYSTEM);
+ nlBegin(NL_MATRIX);
+ }
+
+ /* fill in right hand side and solve */
+ for(z=0; z<mdb->size; z++)
+ for(y=0; y<mdb->size; y++)
+ for(x=0; x<mdb->size; x++)
+ meshdeform_matrix_add_rhs(mdb, x, y, z, a);
+
+ nlEnd(NL_MATRIX);
+ nlEnd(NL_SYSTEM);
+
+#if 0
+ nlPrintMatrix();
+#endif
+
+ if(nlSolveAdvanced(NULL, NL_TRUE)) {
+ for(z=0; z<mdb->size; z++)
+ for(y=0; y<mdb->size; y++)
+ for(x=0; x<mdb->size; x++)
+ meshdeform_matrix_add_semibound_phi(mdb, x, y, z, a);
+
+ for(z=0; z<mdb->size; z++)
+ for(y=0; y<mdb->size; y++)
+ for(x=0; x<mdb->size; x++)
+ meshdeform_matrix_add_exterior_phi(mdb, x, y, z, a);
+
+ for(b=0; b<mdb->size3; b++) {
+ if(mdb->tag[b] != MESHDEFORM_TAG_EXTERIOR)
+ mdb->phi[b]= nlGetVariable(0, mdb->varidx[b]);
+ mdb->totalphi[b] += mdb->phi[b];
+ }
+
+ if(mdb->weights) {
+ /* static bind : compute weights for each vertex */
+ for(b=0; b<mdb->totvert; b++) {
+ if(mdb->inside[b]) {
+ VECCOPY(vec, mdb->vertexcos[b]);
+ Mat4MulVecfl(mdb->cagemat, vec);
+ gridvec[0]= (vec[0] - mdb->min[0] - mdb->halfwidth[0])/mdb->width[0];
+ gridvec[1]= (vec[1] - mdb->min[1] - mdb->halfwidth[1])/mdb->width[1];
+ gridvec[2]= (vec[2] - mdb->min[2] - mdb->halfwidth[2])/mdb->width[2];
+
+ mdb->weights[b*mdb->totcagevert + a]= meshdeform_interp_w(mdb, gridvec, vec, a);
+ }
+ }
+ }
+ else {
+ MDefBindInfluence *inf;
+
+ /* dynamic bind */
+ for(b=0; b<mdb->size3; b++) {
+ if(mdb->phi[b] >= MESHDEFORM_MIN_INFLUENCE) {
+ inf= BLI_memarena_alloc(mdb->memarena, sizeof(*inf));
+ inf->vertex= a;
+ inf->weight= mdb->phi[b];
+ inf->next= mdb->dyngrid[b];
+ mdb->dyngrid[b]= inf;
+ }
+ }
+ }
+ }
+ else {
+ error("Mesh Deform: failed to find solution.");
+ break;
+ }
+
+ sprintf(message, "Mesh deform solve %d / %d |||", a+1, mdb->totcagevert);
+ progress_bar((float)(a+1)/(float)(mdb->totcagevert), message);
+ }
+
+#if 0
+ /* sanity check */
+ for(b=0; b<mdb->size3; b++)
+ if(mdb->tag[b] != MESHDEFORM_TAG_EXTERIOR)
+ if(fabs(mdb->totalphi[b] - 1.0f) > 1e-4)
+ printf("totalphi deficiency [%s|%d] %d: %.10f\n",
+ (mdb->tag[b] == MESHDEFORM_TAG_INTERIOR)? "interior": "boundary", mdb->semibound[b], mdb->varidx[b], mdb->totalphi[b]);
+#endif
+
+ /* free */
+ MEM_freeN(mdb->varidx);
+
+ nlDeleteContext(context);
+}
+
+void harmonic_coordinates_bind(MeshDeformModifierData *mmd, float (*vertexcos)[3], int totvert, float cagemat[][4])
+{
+ MeshDeformBind mdb;
+ MDefBindInfluence *inf;
+ MDefInfluence *mdinf;
+ MDefCell *cell;
+ MVert *mvert;
+ float center[3], vec[3], maxwidth, totweight;
+ int a, b, x, y, z, totinside, offset;
+
+ waitcursor(1);
+ start_progress_bar();
+
+ memset(&mdb, 0, sizeof(MeshDeformBind));
+
+ /* get mesh and cage mesh */
+ mdb.vertexcos= vertexcos;
+ mdb.totvert= totvert;
+
+ mdb.cagedm= mesh_create_derived_no_deform(mmd->object, NULL, CD_MASK_BAREMESH);
+ mdb.totcagevert= mdb.cagedm->getNumVerts(mdb.cagedm);
+ mdb.cagecos= MEM_callocN(sizeof(*mdb.cagecos)*mdb.totcagevert, "MeshDeformBindCos");
+ Mat4CpyMat4(mdb.cagemat, cagemat);
+
+ mvert= mdb.cagedm->getVertArray(mdb.cagedm);
+ for(a=0; a<mdb.totcagevert; a++)
+ VECCOPY(mdb.cagecos[a], mvert[a].co)
+
+ /* compute bounding box of the cage mesh */
+ INIT_MINMAX(mdb.min, mdb.max);
+
+ for(a=0; a<mdb.totcagevert; a++)
+ DO_MINMAX(mdb.cagecos[a], mdb.min, mdb.max);
+
+ /* allocate memory */
+ mdb.size= (2<<(mmd->gridsize-1)) + 2;
+ mdb.size3= mdb.size*mdb.size*mdb.size;
+ mdb.tag= MEM_callocN(sizeof(int)*mdb.size3, "MeshDeformBindTag");
+ mdb.phi= MEM_callocN(sizeof(float)*mdb.size3, "MeshDeformBindPhi");
+ mdb.totalphi= MEM_callocN(sizeof(float)*mdb.size3, "MeshDeformBindTotalPhi");
+ mdb.boundisect= MEM_callocN(sizeof(*mdb.boundisect)*mdb.size3, "MDefBoundIsect");
+ mdb.semibound= MEM_callocN(sizeof(int)*mdb.size3, "MDefSemiBound");
+
+ mdb.inside= MEM_callocN(sizeof(int)*mdb.totvert, "MDefInside");
+
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
+ mdb.dyngrid= MEM_callocN(sizeof(MDefBindInfluence*)*mdb.size3, "MDefDynGrid");
+ else
+ mdb.weights= MEM_callocN(sizeof(float)*mdb.totvert*mdb.totcagevert, "MDefWeights");
+
+ mdb.memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ BLI_memarena_use_calloc(mdb.memarena);
+
+ /* make bounding box equal size in all directions, add padding, and compute
+ * width of the cells */
+ maxwidth = -1.0f;
+ for(a=0; a<3; a++)
+ if(mdb.max[a]-mdb.min[a] > maxwidth)
+ maxwidth= mdb.max[a]-mdb.min[a];
+
+ for(a=0; a<3; a++) {
+ center[a]= (mdb.min[a]+mdb.max[a])*0.5f;
+ mdb.min[a]= center[a] - maxwidth*0.5f;
+ mdb.max[a]= center[a] + maxwidth*0.5f;
+
+ mdb.width[a]= (mdb.max[a]-mdb.min[a])/(mdb.size-4);
+ mdb.min[a] -= 2.1f*mdb.width[a];
+ mdb.max[a] += 2.1f*mdb.width[a];
+
+ mdb.width[a]= (mdb.max[a]-mdb.min[a])/mdb.size;
+ mdb.halfwidth[a]= mdb.width[a]*0.5f;
+ }
+
+ progress_bar(0, "Setting up mesh deform system");
+
+#if 0
+ /* create ray tree */
+ meshdeform_ray_tree_create(&mdb);
+#endif
+
+ totinside= 0;
+ for(a=0; a<mdb.totvert; a++) {
+ VECCOPY(vec, mdb.vertexcos[a]);
+ Mat4MulVecfl(mdb.cagemat, vec);
+ mdb.inside[a]= meshdeform_inside_cage(&mdb, vec);
+ if(mdb.inside[a])
+ totinside++;
+ }
+
+ /* free temporary MDefBoundIsects */
+ BLI_memarena_free(mdb.memarena);
+ mdb.memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+
+ /* start with all cells untyped */
+ for(a=0; a<mdb.size3; a++)
+ mdb.tag[a]= MESHDEFORM_TAG_UNTYPED;
+
+ /* detect intersections and tag boundary cells */
+ for(z=0; z<mdb.size; z++)
+ for(y=0; y<mdb.size; y++)
+ for(x=0; x<mdb.size; x++)
+ meshdeform_add_intersections(&mdb, x, y, z);
+
+#if 0
+ /* free ray tree */
+ meshdeform_ray_tree_free(&mdb);
+#endif
+
+ /* compute exterior and interior tags */
+ meshdeform_bind_floodfill(&mdb);
+
+ for(z=0; z<mdb.size; z++)
+ for(y=0; y<mdb.size; y++)
+ for(x=0; x<mdb.size; x++)
+ meshdeform_check_semibound(&mdb, x, y, z);
+
+ /* solve */
+ meshdeform_matrix_solve(&mdb);
+
+ /* assign results */
+ mmd->bindcos= (float*)mdb.cagecos;
+ mmd->totvert= mdb.totvert;
+ mmd->totcagevert= mdb.totcagevert;
+ Mat4CpyMat4(mmd->bindmat, mmd->object->obmat);
+
+ if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
+ mmd->totinfluence= 0;
+ for(a=0; a<mdb.size3; a++)
+ for(inf=mdb.dyngrid[a]; inf; inf=inf->next)
+ mmd->totinfluence++;
+
+ /* convert MDefBindInfluences to smaller MDefInfluences */
+ mmd->dyngrid= MEM_callocN(sizeof(MDefCell)*mdb.size3, "MDefDynGrid");
+ mmd->dyninfluences= MEM_callocN(sizeof(MDefInfluence)*mmd->totinfluence, "MDefInfluence");
+ offset= 0;
+ for(a=0; a<mdb.size3; a++) {
+ cell= &mmd->dyngrid[a];
+ cell->offset= offset;
+
+ totweight= 0.0f;
+ mdinf= mmd->dyninfluences + cell->offset;
+ for(inf=mdb.dyngrid[a]; inf; inf=inf->next, mdinf++) {
+ mdinf->weight= inf->weight;
+ mdinf->vertex= inf->vertex;
+ totweight += mdinf->weight;
+ cell->totinfluence++;
+ }
+
+ if(totweight > 0.0f) {
+ mdinf= mmd->dyninfluences + cell->offset;
+ for(b=0; b<cell->totinfluence; b++, mdinf++)
+ mdinf->weight /= totweight;
+ }
+
+ offset += cell->totinfluence;
+ }
+
+ mmd->dynverts= mdb.inside;
+ mmd->dyngridsize= mdb.size;
+ VECCOPY(mmd->dyncellmin, mdb.min);
+ mmd->dyncellwidth= mdb.width[0];
+ MEM_freeN(mdb.dyngrid);
+ }
+ else {
+ mmd->bindweights= mdb.weights;
+ MEM_freeN(mdb.inside);
+ }
+
+ /* transform bindcos to world space */
+ for(a=0; a<mdb.totcagevert; a++)
+ Mat4MulVecfl(mmd->object->obmat, mmd->bindcos+a*3);
+
+ /* free */
+ mdb.cagedm->release(mdb.cagedm);
+ MEM_freeN(mdb.tag);
+ MEM_freeN(mdb.phi);
+ MEM_freeN(mdb.totalphi);
+ MEM_freeN(mdb.boundisect);
+ MEM_freeN(mdb.semibound);
+ BLI_memarena_free(mdb.memarena);
+
+ end_progress_bar();
+ waitcursor(0);
+}
+
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 41a9bece61a..8ac0a1f2558 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -93,6 +93,7 @@ void sort_faces(void);
#include "BDR_sculptmode.h"
#include "BLI_editVert.h"
+#include "BLI_ghash.h"
#include "BLI_threads.h"
#include "BLI_rand.h" /* for randome face sorting */
@@ -107,6 +108,7 @@ void sort_faces(void);
#include "PIL_time.h"
#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
/* from rendercode.c */
#define VECMUL(dest, f) dest[0]*= f; dest[1]*= f; dest[2]*= f
@@ -648,6 +650,13 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
float fx, fy, fz;
int vx, vy, vz;
+ if (isnan(co[0]) || !finite(co[0]) ||
+ isnan(co[1]) || !finite(co[1]) ||
+ isnan(co[2]) || !finite(co[2])
+ ) {
+ return;
+ }
+
fx= (co[0]-offs[0])/div[0];
fy= (co[1]-offs[1])/div[1];
fz= (co[2]-offs[2])/div[2];
@@ -684,7 +693,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
}
-static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
+static long mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
{
float *vec;
int a;
@@ -695,7 +704,12 @@ static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
for(a=0; a<MOC_NODE_RES; a++) {
if((*bt)->index[a]) {
/* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
- if(mvert) {
+ if(orco) {
+ vec= orco[(*bt)->index[a]-1];
+ if(FloatCompare(vec, co, MOC_THRESH))
+ return (*bt)->index[a]-1;
+ }
+ else if(mvert) {
vec= (mvert+(*bt)->index[a]-1)->co;
if(FloatCompare(vec, co, MOC_THRESH))
return (*bt)->index[a]-1;
@@ -709,84 +723,118 @@ static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
else return -1;
}
if( (*bt)->next)
- return mesh_octree_find_index(&(*bt)->next, mvert, co);
+ return mesh_octree_find_index(&(*bt)->next, orco, mvert, co);
return -1;
}
+static struct {
+ MocNode **table;
+ float offs[3], div[3];
+ float (*orco)[3];
+ float orcoloc[3];
+} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}, NULL};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
long mesh_octree_table(Object *ob, float *co, char mode)
{
MocNode **bt;
- static MocNode **basetable= NULL;
- static float offs[3], div[3];
if(mode=='u') { /* use table */
- if(basetable==NULL)
+ if(MeshOctree.table==NULL)
mesh_octree_table(ob, NULL, 's');
- if(basetable) {
+ if(MeshOctree.table) {
Mesh *me= ob->data;
- bt= basetable + mesh_octree_get_base_offs(co, offs, div);
+ bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
if(ob==G.obedit)
- return mesh_octree_find_index(bt, NULL, co);
+ return mesh_octree_find_index(bt, NULL, NULL, co);
else
- return mesh_octree_find_index(bt, me->mvert, co);
+ return mesh_octree_find_index(bt, MeshOctree.orco, me->mvert, co);
}
return -1;
}
else if(mode=='s') { /* start table */
Mesh *me= ob->data;
- BoundBox *bb = mesh_get_bb(me);
+ float min[3], max[3];
+
+ /* we compute own bounding box and don't reuse ob->bb because
+ * we are using the undeformed coordinates*/
+ INIT_MINMAX(min, max);
+
+ if(ob==G.obedit) {
+ EditVert *eve;
+
+ for(eve= G.editMesh->verts.first; eve; eve= eve->next)
+ DO_MINMAX(eve->co, min, max)
+ }
+ else {
+ MVert *mvert;
+ float *co;
+ int a, totvert;
+
+ MeshOctree.orco= mesh_getRefKeyCos(me, &totvert);
+ mesh_get_texspace(me, MeshOctree.orcoloc, NULL, NULL);
+
+ for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
+ co= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
+ DO_MINMAX(co, min, max);
+ }
+ }
/* for quick unit coordinate calculus */
- VECCOPY(offs, bb->vec[0]);
- offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */
- offs[1]-= MOC_THRESH;
- offs[2]-= MOC_THRESH;
-
- VecSubf(div, bb->vec[6], bb->vec[0]);
- div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
- div[1]+= 2*MOC_THRESH;
- div[2]+= 2*MOC_THRESH;
+ VECCOPY(MeshOctree.offs, min);
+ MeshOctree.offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */
+ MeshOctree.offs[1]-= MOC_THRESH;
+ MeshOctree.offs[2]-= MOC_THRESH;
+
+ VecSubf(MeshOctree.div, max, min);
+ MeshOctree.div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */
+ MeshOctree.div[1]+= 2*MOC_THRESH;
+ MeshOctree.div[2]+= 2*MOC_THRESH;
- VecMulf(div, 1.0f/MOC_RES);
- if(div[0]==0.0f) div[0]= 1.0f;
- if(div[1]==0.0f) div[1]= 1.0f;
- if(div[2]==0.0f) div[2]= 1.0f;
+ VecMulf(MeshOctree.div, 1.0f/MOC_RES);
+ if(MeshOctree.div[0]==0.0f) MeshOctree.div[0]= 1.0f;
+ if(MeshOctree.div[1]==0.0f) MeshOctree.div[1]= 1.0f;
+ if(MeshOctree.div[2]==0.0f) MeshOctree.div[2]= 1.0f;
- if(basetable) /* happens when entering this call without ending it */
+ if(MeshOctree.table) /* happens when entering this call without ending it */
mesh_octree_table(ob, co, 'e');
- basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
+ MeshOctree.table= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table");
if(ob==G.obedit) {
EditVert *eve;
-
+
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
- mesh_octree_add_nodes(basetable, eve->co, offs, div, (long)(eve));
+ mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (long)(eve));
}
}
else {
MVert *mvert;
- long a;
+ float *co;
+ int a;
- for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) {
- mesh_octree_add_nodes(basetable, mvert->co, offs, div, a);
+ for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
+ co= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
+ mesh_octree_add_nodes(MeshOctree.table, co, MeshOctree.offs, MeshOctree.div, a+1);
}
}
}
else if(mode=='e') { /* end table */
- if(basetable) {
+ if(MeshOctree.table) {
int a;
- for(a=0, bt=basetable; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) {
+ for(a=0, bt=MeshOctree.table; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) {
if(*bt) mesh_octree_free_node(bt);
}
- MEM_freeN(basetable);
- basetable= NULL;
+ MEM_freeN(MeshOctree.table);
+ MeshOctree.table= NULL;
+ }
+ if(MeshOctree.orco) {
+ MEM_freeN(MeshOctree.orco);
+ MeshOctree.orco= NULL;
}
}
return 0;
@@ -795,12 +843,22 @@ long mesh_octree_table(Object *ob, float *co, char mode)
int mesh_get_x_mirror_vert(Object *ob, int index)
{
Mesh *me= ob->data;
- MVert *mvert= me->mvert+index;
+ MVert *mvert;
float vec[3];
- vec[0]= -mvert->co[0];
- vec[1]= mvert->co[1];
- vec[2]= mvert->co[2];
+ if(MeshOctree.orco) {
+ float *loc= MeshOctree.orcoloc;
+
+ vec[0]= -(MeshOctree.orco[index][0] + loc[0]) - loc[0];
+ vec[1]= MeshOctree.orco[index][1];
+ vec[2]= MeshOctree.orco[index][2];
+ }
+ else {
+ mvert= me->mvert+index;
+ vec[0]= -mvert->co[0];
+ vec[1]= mvert->co[1];
+ vec[2]= mvert->co[2];
+ }
return mesh_octree_table(ob, vec, 'u');
}
@@ -810,6 +868,13 @@ EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co)
float vec[3];
long poinval;
+ /* ignore nan verts */
+ if (isnan(co[0]) || !finite(co[0]) ||
+ isnan(co[1]) || !finite(co[1]) ||
+ isnan(co[2]) || !finite(co[2])
+ )
+ return NULL;
+
vec[0]= -co[0];
vec[1]= co[1];
vec[2]= co[2];
@@ -820,6 +885,95 @@ EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co)
return NULL;
}
+static unsigned int mirror_facehash(void *ptr)
+{
+ MFace *mf= ptr;
+ int v0, v1;
+
+ if(mf->v4) {
+ v0= MIN4(mf->v1, mf->v2, mf->v3, mf->v4);
+ v1= MAX4(mf->v1, mf->v2, mf->v3, mf->v4);
+ }
+ else {
+ v0= MIN3(mf->v1, mf->v2, mf->v3);
+ v1= MAX3(mf->v1, mf->v2, mf->v3);
+ }
+
+ return ((v0*39)^(v1*31));
+}
+
+static int mirror_facerotation(MFace *a, MFace *b)
+{
+ if(b->v4) {
+ if(a->v1==b->v1 && a->v2==b->v2 && a->v3==b->v3 && a->v4==b->v4)
+ return 0;
+ else if(a->v4==b->v1 && a->v1==b->v2 && a->v2==b->v3 && a->v3==b->v4)
+ return 1;
+ else if(a->v3==b->v1 && a->v4==b->v2 && a->v1==b->v3 && a->v2==b->v4)
+ return 2;
+ else if(a->v2==b->v1 && a->v3==b->v2 && a->v4==b->v3 && a->v1==b->v4)
+ return 3;
+ }
+ else {
+ if(a->v1==b->v1 && a->v2==b->v2 && a->v3==b->v3)
+ return 0;
+ else if(a->v3==b->v1 && a->v1==b->v2 && a->v2==b->v3)
+ return 1;
+ else if(a->v2==b->v1 && a->v3==b->v2 && a->v1==b->v3)
+ return 2;
+ }
+
+ return -1;
+}
+
+static int mirror_facecmp(void *a, void *b)
+{
+ return (mirror_facerotation((MFace*)a, (MFace*)b) == -1);
+}
+
+int *mesh_get_x_mirror_faces(Object *ob)
+{
+ Mesh *me= ob->data;
+ MVert *mv, *mvert= me->mvert;
+ MFace mirrormf, *mf, *hashmf, *mface= me->mface;
+ GHash *fhash;
+ int *mirrorverts, *mirrorfaces;
+ int a;
+
+ mirrorverts= MEM_callocN(sizeof(int)*me->totvert, "MirrorVerts");
+ mirrorfaces= MEM_callocN(sizeof(int)*2*me->totface, "MirrorFaces");
+
+ mesh_octree_table(ob, NULL, 's');
+
+ for(a=0, mv=mvert; a<me->totvert; a++, mv++)
+ mirrorverts[a]= mesh_get_x_mirror_vert(ob, a);
+
+ mesh_octree_table(ob, NULL, 'e');
+
+ fhash= BLI_ghash_new(mirror_facehash, mirror_facecmp);
+ for(a=0, mf=mface; a<me->totface; a++, mf++)
+ BLI_ghash_insert(fhash, mf, mf);
+
+ for(a=0, mf=mface; a<me->totface; a++, mf++) {
+ mirrormf.v1= mirrorverts[mf->v3];
+ mirrormf.v2= mirrorverts[mf->v2];
+ mirrormf.v3= mirrorverts[mf->v1];
+ mirrormf.v4= (mf->v4)? mirrorverts[mf->v4]: 0;
+
+ hashmf= BLI_ghash_lookup(fhash, &mirrormf);
+ if(hashmf) {
+ mirrorfaces[a*2]= hashmf - mface;
+ mirrorfaces[a*2+1]= mirror_facerotation(&mirrormf, hashmf);
+ }
+ else
+ mirrorfaces[a*2]= -1;
+ }
+
+ BLI_ghash_free(fhash, NULL, NULL);
+ MEM_freeN(mirrorverts);
+
+ return mirrorfaces;
+}
/* ****************** render BAKING ********************** */
@@ -850,6 +1004,7 @@ static ScrArea *biggest_image_area(void)
typedef struct BakeRender {
Render *re;
+ struct Object *actob;
int event, tot, ready;
} BakeRender;
@@ -857,7 +1012,7 @@ static void *do_bake_render(void *bake_v)
{
BakeRender *bkr= bake_v;
- bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event);
+ bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event, bkr->actob);
bkr->ready= 1;
return NULL;
@@ -868,57 +1023,65 @@ void objects_bake_render_menu(void)
{
short event;
- event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4");
-
- objects_bake_render(event);
+ event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5");
+ if (event < 1) return;
+ objects_bake_render_ui(event);
}
-/* all selected meshes with UV maps are rendered for current scene visibility */
-void objects_bake_render(short event)
+void objects_bake_render(short event, char **error_msg)
{
+ Object *actob= OBACT;
+ int active= G.scene->r.bake_flag & R_BAKE_TO_ACTIVE;
short prev_r_raytrace= 0, prev_wo_amb_occ= 0;
if(event==0) event= G.scene->r.bake_mode;
if(G.scene->r.renderer!=R_INTERN) {
- error("Bake only supported for Internal Renderer");
- return;
+ *error_msg = "Bake only supported for Internal Renderer";
+ return;
}
+ if(active && !actob) {
+ *error_msg = "No active object";
+ return;
+ }
+
if(event>0) {
Render *re= RE_NewRender("_Bake View_");
ScrArea *area= biggest_image_area();
ListBase threads;
BakeRender bkr;
int timer=0, tot, sculptmode= G.f & G_SCULPTMODE;
-
+
if(sculptmode) set_sculptmode();
if(event==1) event= RE_BAKE_ALL;
else if(event==2) event= RE_BAKE_AO;
else if(event==3) event= RE_BAKE_NORMALS;
- else event= RE_BAKE_TEXTURE;
+ else if(event==4) event= RE_BAKE_TEXTURE;
+ else event= RE_BAKE_DISPLACEMENT;
if(event==RE_BAKE_AO) {
if(G.scene->world==NULL) {
- error("No world set up");
+ *error_msg = "No world set up";
return;
}
/* If raytracing or AO is disabled, switch it on temporarily for baking. */
- prev_r_raytrace = (G.scene->r.mode & R_RAYTRACE) != 0;
prev_wo_amb_occ = (G.scene->world->mode & WO_AMB_OCC) != 0;
-
- G.scene->r.mode |= R_RAYTRACE;
G.scene->world->mode |= WO_AMB_OCC;
}
+ if(event==RE_BAKE_AO || active) {
+ prev_r_raytrace = (G.scene->r.mode & R_RAYTRACE) != 0;
+ G.scene->r.mode |= R_RAYTRACE;
+ }
waitcursor(1);
RE_test_break_cb(re, thread_break);
g_break= 0;
G.afbreek= 0; /* blender_test_break uses this global */
- RE_Database_Baking(re, G.scene, event);
+ RE_Database_Baking(re, G.scene, event, (active)? actob: NULL);
/* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
@@ -926,6 +1089,7 @@ void objects_bake_render(short event)
bkr.re= re;
bkr.event= event;
bkr.ready= 0;
+ bkr.actob= (active)? actob: NULL;
BLI_insert_thread(&threads, &bkr);
while(bkr.ready==0) {
@@ -950,24 +1114,29 @@ void objects_bake_render(short event)
RE_Database_Free(re);
waitcursor(0);
- if(tot==0) error("No Images found to bake to");
+ if(tot==0) *error_msg = "No Images found to bake to";
else {
Image *ima;
- /* force OpenGL reload */
+ /* force OpenGL reload and mipmap recalc */
for(ima= G.main->image.first; ima; ima= ima->id.next) {
if(ima->ok==IMA_OK_LOADED) {
ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
- if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY))
+ if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
free_realtime_image(ima);
+ imb_freemipmapImBuf(ibuf);
+ }
}
}
}
- /* restore raytrace and AO */
- if(event==RE_BAKE_AO) {
- if( prev_wo_amb_occ == 0) G.scene->world->mode &= ~WO_AMB_OCC;
- if( prev_r_raytrace == 0) G.scene->r.mode &= ~R_RAYTRACE;
- }
+ /* restore raytrace and AO */
+ if(event==RE_BAKE_AO)
+ if(prev_wo_amb_occ == 0)
+ G.scene->world->mode &= ~WO_AMB_OCC;
+
+ if(event==RE_BAKE_AO || active)
+ if(prev_r_raytrace == 0)
+ G.scene->r.mode &= ~R_RAYTRACE;
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
@@ -977,4 +1146,20 @@ void objects_bake_render(short event)
}
}
+/* all selected meshes with UV maps are rendered for current scene visibility */
+void objects_bake_render_ui(short event)
+{
+ char *error_msg = NULL;
+ int is_editmode = (G.obedit!=NULL);
+
+ /* Deal with editmode, this is a bit clunky but since UV's are in editmode, users are likely to bake from their */
+ if (is_editmode) exit_editmode(0);
+
+ objects_bake_render(event, &error_msg);
+
+ if (is_editmode) enter_editmode(0);
+
+ if (error_msg)
+ error(error_msg);
+}
diff --git a/source/blender/src/multires.c b/source/blender/src/multires.c
index 33b85bd27b6..64edfb5f6cc 100644
--- a/source/blender/src/multires.c
+++ b/source/blender/src/multires.c
@@ -52,6 +52,7 @@
#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_multires.h"
#include "BKE_object.h"
#include "BIF_editmesh.h"
@@ -78,7 +79,7 @@
#include <math.h>
-const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT;
+void multires_calc_temp_data(struct MultiresLevel *lvl);
int multires_test()
{
@@ -107,442 +108,115 @@ void multires_check_state()
sculptmode_correct_state();
}
-typedef struct MultiresMapNode {
- struct MultiresMapNode *next, *prev;
- unsigned Index;
-} MultiresMapNode;
-
-MultiresLevel *current_level(Multires *mr)
-{
- return BLI_findlink(&mr->levels, mr->current - 1);
-}
-
-MultiresLevel *multires_level_n(Multires *mr, int n)
-{
- if(mr)
- return BLI_findlink(&mr->levels, n - 1);
- else
- return NULL;
-}
-
-void Vec3fAvg3(float *out, float *v1, float *v2, float *v3)
-{
- out[0]= (v1[0]+v2[0]+v3[0])/3;
- out[1]= (v1[1]+v2[1]+v3[1])/3;
- out[2]= (v1[2]+v2[2]+v3[2])/3;
-}
-void Vec3fAvg4(float *out, float *v1, float *v2, float *v3, float *v4)
+static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed)
{
- out[0]= (v1[0]+v2[0]+v3[0]+v4[0])/4;
- out[1]= (v1[1]+v2[1]+v3[1]+v4[1])/4;
- out[2]= (v1[2]+v2[2]+v3[2]+v4[2])/4;
+ if(!eed) return;
+
+ if(flag & ME_SEAM) eed->seam= 1;
+ if(flag & ME_SHARP) eed->sharp = 1;
+ if(flag & SELECT) eed->f |= SELECT;
+ if(flag & ME_FGON) eed->h= EM_FGON;
+ if(flag & ME_HIDE) eed->h |= 1;
+
+ eed->crease= ((float)crease)/255.0;
}
-short multires_edge_is_boundary(MultiresLevel *lvl, unsigned e)
+void multires_level_to_editmesh(Object *ob, Mesh *me, const int render)
{
- MultiresMapNode *n1= lvl->vert_face_map[lvl->edges[e].v[0]].first;
- unsigned total= 0;
-
- while(n1) {
- MultiresMapNode *n2= lvl->vert_face_map[lvl->edges[e].v[1]].first;
- while(n2) {
- if(n1->Index == n2->Index) {
- ++total;
+ MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
+ int i;
+ EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
+ EditVert **eves= NULL;
+ EditEdge *eed= NULL;
- if(total > 1)
- return 0;
- }
+ if(em) {
+ /* Remove editmesh elements */
+ free_editMesh(em);
+
+ eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers");
- n2= n2->next;
+ /* Vertices/Edges/Faces */
+ for(i=0; i<lvl->totvert; ++i) {
+ eves[i]= addvertlist(me->mr->verts[i].co, NULL);
+ if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
+ if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
+ eves[i]->data= NULL;
+ }
+ for(i=0; i<lvl->totedge; ++i) {
+ addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL);
+ }
+ for(i=0; i<lvl->totface; ++i) {
+ EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
+ EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
+ eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
+ efa->flag= lvl->faces[i].flag & ~ME_HIDE;
+ efa->mat_nr= lvl->faces[i].mat_nr;
+ if(lvl->faces[i].flag & ME_FACE_SEL)
+ efa->f |= SELECT;
+ if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
+ efa->data= NULL;
}
- n1= n1->next;
- }
-
- return 1;
-}
-
-short multires_vert_is_boundary(MultiresLevel *lvl, unsigned v)
-{
- MultiresMapNode *node= lvl->vert_edge_map[v].first;
- while(node) {
- if(multires_edge_is_boundary(lvl,node->Index))
- return 1;
- node= node->next;
- }
- return 0;
-}
-
-typedef struct FloatNode {
- struct FloatNode *next, *prev;
- float value;
-} FloatNode;
-typedef struct FloatArrayNode {
- struct FloatArrayNode *next, *prev;
- float *value;
-} FloatArrayNode;
-
-typedef struct MultiApplyData {
- /* Smooth faces */
- float *corner1, *corner2, *corner3, *corner4;
- char quad;
-
- /* Smooth edges */
- char boundary;
- float edge_face_neighbor_midpoints_accum[3];
- unsigned edge_face_neighbor_midpoints_total;
- float *endpoint1, *endpoint2;
-
- /* Smooth verts */
- /* uses 'char boundary' */
- float *original;
- int edge_count;
- float vert_face_neighbor_midpoints_average[3];
- float vert_edge_neighbor_midpoints_average[3];
- float boundary_edges_average[3];
-} MultiApplyData;
-
-/* CATMULL-CLARK
- ============= */
-
-/* Simply averages the four corners of a polygon. */
-float catmullclark_smooth_face(MultiApplyData *data, const unsigned i)
-{
- const float total= data->corner1[i]+data->corner2[i]+data->corner3[i];
- return data->quad ? (total+data->corner4[i])/4 : total/3;
-}
-
-float catmullclark_smooth_edge(MultiApplyData *data, const unsigned i)
-{
- float accum= 0;
- unsigned count= 2;
-
- accum+= data->endpoint1[i] + data->endpoint2[i];
-
- if(!data->boundary) {
- accum+= data->edge_face_neighbor_midpoints_accum[i];
- count+= data->edge_face_neighbor_midpoints_total;
- }
-
- return accum / count;
-}
-float catmullclark_smooth_vert(MultiApplyData *data, const unsigned i)
-{
- if(data->boundary) {
- return data->original[i]*0.75 + data->boundary_edges_average[i]*0.25;
- } else {
- return (data->vert_face_neighbor_midpoints_average[i] +
- 2*data->vert_edge_neighbor_midpoints_average[i] +
- data->original[i]*(data->edge_count-3))/data->edge_count;
- }
-}
-
-
-
-/* Call func count times, passing in[i] as the input and storing the output in out[i] */
-void multi_apply(float *out, MultiApplyData *data,
- const unsigned count, float (*func)(MultiApplyData *, const unsigned))
-{
- unsigned i;
- for(i=0; i<count; ++i)
- out[i]= func(data,i);
-}
-
-float get_float(void *array, const unsigned i, const unsigned j, const char stride)
-{
- return ((float*)((char*)array+(i*stride)))[j];
-}
-
-void edge_face_neighbor_midpoints_accum(MultiApplyData *data, MultiresLevel *lvl,
- void *array, const char stride, const MultiresEdge *e)
-{
- ListBase *neighbors1= &lvl->vert_face_map[e->v[0]];
- ListBase *neighbors2= &lvl->vert_face_map[e->v[1]];
- MultiresMapNode *n1, *n2;
- unsigned j,count= 0;
- float *out= data->edge_face_neighbor_midpoints_accum;
- out[0]=out[1]=out[2]= 0;
-
- for(n1= neighbors1->first; n1; n1= n1->next) {
- for(n2= neighbors2->first; n2; n2= n2->next) {
- if(n1->Index == n2->Index) {
- for(j=0; j<3; ++j)
- out[j]+= get_float(array,lvl->faces[n1->Index].mid,j,stride);
- ++count;
+ /* Edge flags */
+ eed= em->edges.first;
+ if(lvl==me->mr->levels.first) {
+ for(i=0; i<lvl->totedge; ++i) {
+ medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
+ eed= eed->next;
+ }
+ } else {
+ MultiresLevel *lvl1= me->mr->levels.first;
+ const int last= lvl1->totedge * pow(2, me->mr->current-1);
+ for(i=0; i<last; ++i) {
+ const int ndx= i / pow(2, me->mr->current-1);
+
+ medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed);
+ eed= eed->next;
}
}
- }
-
- data->edge_face_neighbor_midpoints_total= count;
-}
-void vert_face_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl,
- void *array, const char stride, const unsigned i)
-{
- ListBase *neighbors= &lvl->vert_face_map[i];
- MultiresMapNode *n1;
- unsigned j,count= 0;
- float *out= data->vert_face_neighbor_midpoints_average;
-
- out[0]=out[1]=out[2]= 0;
- for(n1= neighbors->first; n1; n1= n1->next) {
- for(j=0; j<3; ++j)
- out[j]+= get_float(array,lvl->faces[n1->Index].mid,j,stride);
- ++count;
- }
- for(j=0; j<3; ++j) out[j]/= count;
-}
-void vert_edge_neighbor_midpoints_average(MultiApplyData *data, MultiresLevel *lvl,
- void *array, const char stride, const unsigned i)
-{
- ListBase *neighbors= &lvl->vert_edge_map[i];
- MultiresMapNode *n1;
- unsigned j,count= 0;
- float *out= data->vert_edge_neighbor_midpoints_average;
-
- out[0]=out[1]=out[2]= 0;
-
- for(n1= neighbors->first; n1; n1= n1->next) {
- for(j=0; j<3; ++j)
- out[j]+= (get_float(array,lvl->edges[n1->Index].v[0],j,stride) +
- get_float(array,lvl->edges[n1->Index].v[1],j,stride)) / 2;
- ++count;
- }
- for(j=0; j<3; ++j) out[j]/= count;
-}
-void boundary_edges_average(MultiApplyData *data, MultiresLevel *lvl,
- void *array, const char stride, const unsigned i)
-{
- ListBase *neighbors= &lvl->vert_edge_map[i];
- MultiresMapNode *n1;
- unsigned j,count= 0;
- float *out= data->boundary_edges_average;
-
- out[0]=out[1]=out[2]= 0;
-
- for(n1= neighbors->first; n1; n1= n1->next) {
- const MultiresEdge *e= &lvl->edges[n1->Index];
- const unsigned end= e->v[0]==i ? e->v[1] : e->v[0];
-
- if(multires_edge_is_boundary(lvl,n1->Index)) {
- for(j=0; j<3; ++j)
- out[j]+= get_float(array,end,j,stride);
- ++count;
+ eed= em->edges.first;
+ for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
+ eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
+ me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
}
- }
- for(j=0; j<3; ++j) out[j]/= count;
-}
-
-/* For manipulating vertex colors / uvs */
-void mcol_to_multires(MultiresColFace *mrf, MCol *mcol)
-{
- char i;
- for(i=0; i<4; ++i) {
- mrf->col[i].a= mcol[i].a;
- mrf->col[i].r= mcol[i].r;
- mrf->col[i].g= mcol[i].g;
- mrf->col[i].b= mcol[i].b;
- }
-}
-
-float clamp_component(const float c)
-{
- if(c<0) return 0;
- else if(c>255) return 255;
- else return c;
-}
-
-void multires_to_mcol(MultiresColFace *f, MCol mcol[4])
-{
- unsigned char j;
- for(j=0; j<4; ++j) {
- mcol->a= clamp_component(f->col[j].a);
- mcol->r= clamp_component(f->col[j].r);
- mcol->g= clamp_component(f->col[j].g);
- mcol->b= clamp_component(f->col[j].b);
- ++mcol;
- }
-}
-
-/* 1 <= count <= 4 */
-void multires_col_avg(MultiresCol *avg, MultiresCol cols[4], char count)
-{
- unsigned i;
- avg->a= avg->r= avg->g= avg->b= 0;
- for(i=0; i<count; ++i) {
- avg->a+= cols[i].a;
- avg->r+= cols[i].r;
- avg->g+= cols[i].g;
- avg->b+= cols[i].b;
- }
- avg->a/= count;
- avg->r/= count;
- avg->g/= count;
- avg->b/= count;
-}
-
-void multires_col_avg2(MultiresCol *avg, MultiresCol *c1, MultiresCol *c2)
-{
- MultiresCol in[2];
- in[0]= *c1;
- in[1]= *c2;
- multires_col_avg(avg,in,2);
-}
-
-void multires_load_cols(Mesh *me)
-{
- MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *cur;
- EditMesh *em= G.obedit ? G.editMesh : NULL;
- CustomData *src= em ? &em->fdata : &me->fdata;
- EditFace *efa= NULL;
- unsigned i,j;
-
- if(!CustomData_has_layer(src, CD_MCOL) && !CustomData_has_layer(src, CD_MTFACE)) return;
-
- /* Add texcol data */
- for(cur= me->mr->levels.first; cur; cur= cur->next)
- if(!cur->colfaces)
- cur->colfaces= MEM_callocN(sizeof(MultiresColFace)*cur->totface,"ColFaces");
+
+ EM_select_flush();
- me->mr->use_col= CustomData_has_layer(src, CD_MCOL);
+ multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
+ multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
- if(em) efa= em->faces.first;
- for(i=0; i<lvl->totface; ++i) {
- MultiresColFace *f= &lvl->colfaces[i];
+ /* Colors */
+ if(me->mr->use_col) {
+ MCol c[4];
+ EditFace *efa= NULL;
+ CustomData *src= &em->fdata;
- if(me->mr->use_col)
- mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]);
+ if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL);
+ efa= em->faces.first;
- if(em) efa= efa->next;
- }
-
- /* Update higher levels */
- lvl= lvl->next;
- while(lvl) {
- MultiresColFace *cf= lvl->colfaces;
- for(i=0; i<lvl->prev->totface; ++i) {
- const char sides= lvl->prev->faces[i].v[3]?4:3;
- MultiresCol cntr;
-
- /* Find average color of 4 (or 3 for triangle) verts */
- multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides);
-
- for(j=0; j<sides; ++j) {
- MultiresColFace *pf= &lvl->prev->colfaces[i];
-
- multires_col_avg2(&cf->col[0],
- &pf->col[j],
- &pf->col[j==0?sides-1:j-1]);
- cf->col[1]= pf->col[j];
- multires_col_avg2(&cf->col[2],
- &pf->col[j],
- &pf->col[j==sides-1?0:j+1]);
- cf->col[3]= cntr;
-
- ++cf;
- }
- }
- lvl= lvl->next;
- }
-
- /* Update lower levels */
- lvl= me->mr->levels.last;
- lvl= lvl->prev;
- while(lvl) {
- unsigned curf= 0;
- for(i=0; i<lvl->totface; ++i) {
- MultiresFace *f= &lvl->faces[i];
- for(j=0; j<(f->v[3]?4:3); ++j) {
- lvl->colfaces[i].col[j]= lvl->next->colfaces[curf].col[1];
- ++curf;
+ for(i=0; i<lvl->totface; ++i) {
+ if(me->mr->use_col) {
+ multires_to_mcol(&lvl->colfaces[i], c);
+ CustomData_em_set(src, efa->data, CD_MCOL, c);
+ }
+ efa= efa->next;
}
+
}
- lvl= lvl->prev;
- }
-}
-
-void multires_get_vert(MVert *out, EditVert *eve, MVert *m, int i)
-{
- if(eve) {
- VecCopyf(out->co, eve->co);
- out->flag= 0;
- if(eve->f & SELECT) out->flag |= 1;
- if(eve->h) out->flag |= ME_HIDE;
- eve->tmp.l= i;
- }
- else
- *out= *m;
-}
-
-void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
-{
- if(efa) {
- MFace tmp;
- int j;
- tmp.v1= efa->v1->tmp.l;
- tmp.v2= efa->v2->tmp.l;
- tmp.v3= efa->v3->tmp.l;
- tmp.v4= 0;
- if(efa->v4) tmp.v4= efa->v4->tmp.l;
- test_index_face(&tmp, NULL, 0, efa->v4?4:3);
- for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
-
- /* Flags */
- f->flag= efa->flag;
- if(efa->f & 1) f->flag |= ME_FACE_SEL;
- else f->flag &= ~ME_FACE_SEL;
- if(efa->h) f->flag |= ME_HIDE;
- f->mat_nr= efa->mat_nr;
- } else {
- f->v[0]= m->v1;
- f->v[1]= m->v2;
- f->v[2]= m->v3;
- f->v[3]= m->v4;
- f->flag= m->flag;
- f->mat_nr= m->mat_nr;
- }
-}
-
-void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease)
-{
- if(!eed || !flag) return;
-
- /* Would be nice if EditMesh edge flags could be unified with Mesh flags! */
- *flag= (eed->f & SELECT) | ME_EDGERENDER;
- if(eed->f2<2) *flag |= ME_EDGEDRAW;
- if(eed->f2==0) *flag |= ME_LOOSEEDGE;
- if(eed->sharp) *flag |= ME_SHARP;
- if(eed->seam) *flag |= ME_SEAM;
- if(eed->h & EM_FGON) *flag |= ME_FGON;
- if(eed->h & 1) *flag |= ME_HIDE;
- *crease= (char)(255.0*eed->crease);
-}
-
-void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease)
-{
- if(eed) {
- e->v[0]= eed->v1->tmp.l;
- e->v[1]= eed->v2->tmp.l;
- eed_to_medge_flag(eed, flag, crease);
- } else {
- e->v[0]= m->v1;
- e->v[1]= m->v2;
- *flag= m->flag;
- *crease= m->crease;
+ mesh_update_customdata_pointers(me);
+
+ MEM_freeN(eves);
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ recalc_editnormals();
}
}
void multires_make(void *ob, void *me_v)
{
Mesh *me= me_v;
- MultiresLevel *lvl;
- EditMesh *em= G.obedit ? G.editMesh : NULL;
- EditVert *eve= NULL;
- EditFace *efa= NULL;
- EditEdge *eed= NULL;
Key *key;
- int i;
/* Check for shape keys */
key= me->key;
@@ -555,66 +229,14 @@ void multires_make(void *ob, void *me_v)
return;
}
- lvl= MEM_callocN(sizeof(MultiresLevel), "multires level");
-
waitcursor(1);
multires_check_state();
- if(me->pv) sculptmode_pmv_off(me);
-
- me->mr= MEM_callocN(sizeof(Multires), "multires data");
-
- BLI_addtail(&me->mr->levels,lvl);
- me->mr->current= 1;
- me->mr->level_count= 1;
- me->mr->edgelvl= 1;
- me->mr->pinlvl= 1;
- me->mr->renderlvl= 1;
-
- /* Load mesh (or editmesh) into multires data */
-
- /* Load vertices and vdata (MDeformVerts) */
- lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert;
- me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
- multires_update_customdata(me->mr->levels.first, em ? &em->vdata : &me->vdata,
- &me->mr->vdata, CD_MDEFORMVERT);
- if(em) eve= em->verts.first;
- for(i=0; i<lvl->totvert; ++i) {
- multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
- if(em) eve= eve->next;
- }
-
- /* Load faces and fdata (MTFaces) */
- lvl->totface= em ? BLI_countlist(&em->faces) : me->totface;
- lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
- multires_update_customdata(me->mr->levels.first, em ? &em->fdata : &me->fdata,
- &me->mr->fdata, CD_MTFACE);
- if(em) efa= em->faces.first;
- for(i=0; i<lvl->totface; ++i) {
- multires_get_face(&lvl->faces[i], efa, &me->mface[i]);
- if(em) efa= efa->next;
- }
-
- /* Load edges and edge_flags */
- lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge;
- lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
- me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags");
- me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases");
- if(em) eed= em->edges.first;
- for(i=0; i<lvl->totedge; ++i) {
- multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]);
- if(em) eed= eed->next;
- }
-
- multires_load_cols(me);
+ multires_create(ob, me);
- multires_calc_level_maps(lvl);
-
allqueue(REDRAWBUTSEDIT, 0);
-
BIF_undo_push("Make multires");
-
waitcursor(0);
}
@@ -631,90 +253,6 @@ void multires_delete(void *ob, void *me_v)
BIF_undo_push("Apply multires");
}
-MultiresLevel *multires_level_copy(MultiresLevel *orig)
-{
- if(orig) {
- MultiresLevel *lvl= MEM_dupallocN(orig);
-
- lvl->next= lvl->prev= NULL;
- lvl->faces= MEM_dupallocN(orig->faces);
- lvl->colfaces= MEM_dupallocN(orig->colfaces);
- lvl->edges= MEM_dupallocN(orig->edges);
- lvl->vert_edge_map= lvl->vert_face_map= NULL;
- multires_calc_level_maps(lvl);
-
- return lvl;
- }
- return NULL;
-}
-
-Multires *multires_copy(Multires *orig)
-{
- if(orig) {
- Multires *mr= MEM_dupallocN(orig);
- MultiresLevel *lvl;
-
- mr->levels.first= mr->levels.last= NULL;
-
- for(lvl= orig->levels.first; lvl; lvl= lvl->next)
- BLI_addtail(&mr->levels, multires_level_copy(lvl));
-
- mr->verts= MEM_dupallocN(orig->verts);
-
- lvl= mr->levels.first;
- if(lvl) {
- CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert);
- CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface);
- mr->edge_flags= MEM_dupallocN(orig->edge_flags);
- mr->edge_creases= MEM_dupallocN(orig->edge_creases);
- }
-
- return mr;
- }
- return NULL;
-}
-
-void multires_free(Multires *mr)
-{
- if(mr) {
- MultiresLevel* lvl= mr->levels.first;
-
- /* Free the first-level data */
- if(lvl) {
- CustomData_free(&mr->vdata, lvl->totvert);
- CustomData_free(&mr->fdata, lvl->totface);
- MEM_freeN(mr->edge_flags);
- MEM_freeN(mr->edge_creases);
- }
-
- while(lvl) {
- multires_free_level(lvl);
- lvl= lvl->next;
- }
-
- MEM_freeN(mr->verts);
-
- BLI_freelistN(&mr->levels);
-
- MEM_freeN(mr);
- }
-}
-
-/* Does not actually free lvl itself! */
-void multires_free_level(MultiresLevel *lvl)
-{
- if(lvl) {
- if(lvl->faces) MEM_freeN(lvl->faces);
- if(lvl->edges) MEM_freeN(lvl->edges);
- if(lvl->colfaces) MEM_freeN(lvl->colfaces);
-
- /* Free all vertex maps */
- MEM_freeN(lvl->vert_edge_map);
- MEM_freeN(lvl->vert_face_map);
- MEM_freeN(lvl->map_mem);
- }
-}
-
/* Make sure that all level indices are clipped to [1, mr->level_count] */
void multires_clip_levels(Multires *mr)
{
@@ -811,241 +349,52 @@ void multires_del_higher(void *ob, void *me)
BIF_undo_push("Multires delete higher");
}
-unsigned int find_mid_edge(ListBase *vert_edge_map,
- MultiresLevel *lvl,
- const unsigned int v1,
- const unsigned int v2 )
+void multires_finish_mesh_update(Object *ob)
{
- MultiresMapNode *n= vert_edge_map[v1].first;
- while(n) {
- if(lvl->edges[n->Index].v[0]==v2 ||
- lvl->edges[n->Index].v[1]==v2)
- return lvl->edges[n->Index].mid;
-
- n= n->next;
+ /* friendly check for background render */
+ if(G.background==0) {
+ object_handle_update(ob);
+ countall();
+
+ if(G.vd && G.vd->depths) G.vd->depths->damaged= 1;
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIMAGE, 0);
}
- return -1;
}
-void check_colors(Mesh *me)
+void multires_subdivide(void *ob_v, void *me_v)
{
- CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata;
- const char col= CustomData_has_layer(src, CD_MCOL);
-
- /* Check if vertex colors have been deleted or added */
- if(me->mr->use_col && !col)
- me->mr->use_col= 0;
- else if(!me->mr->use_col && col) {
- me->mr->use_col= 1;
- multires_load_cols(me);
- }
-}
+ Mesh *me = me_v;
-void multires_add_level(void *ob, void *me_v)
-{
- int i,j, curf, cure;
- Mesh *me= me_v;
- MultiresLevel *lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel");
- MultiApplyData data;
- MVert *oldverts= NULL;
-
multires_check_state();
- waitcursor(1);
-
- if(me->pv) sculptmode_pmv_off(me);
-
- check_colors(me);
-
- ++me->mr->level_count;
- BLI_addtail(&me->mr->levels,lvl);
-
- /* Create vertices
- =============== */
- lvl->totvert= lvl->prev->totvert + lvl->prev->totedge + lvl->prev->totface;
- oldverts= me->mr->verts;
- me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert, "multitres verts");
- /* Copy old verts */
- for(i=0; i<lvl->prev->totvert; ++i)
- me->mr->verts[i]= oldverts[i];
- /* Create new edge verts */
- for(i=0; i<lvl->prev->totedge; ++i) {
- VecMidf(me->mr->verts[lvl->prev->totvert + i].co,
- oldverts[lvl->prev->edges[i].v[0]].co,
- oldverts[lvl->prev->edges[i].v[1]].co);
- lvl->prev->edges[i].mid= lvl->prev->totvert + i;
- }
- /* Create new face verts */
- for(i=0; i<lvl->prev->totface; ++i) {
- lvl->prev->faces[i].mid= lvl->prev->totvert + lvl->prev->totedge + i;
- }
-
- /* Create faces
- ============ */
- /* Allocate all the new faces (each triangle creates three, and
- each quad creates four */
- lvl->totface= 0;
- for(i=0; i<lvl->prev->totface; ++i)
- lvl->totface+= lvl->prev->faces[i].v[3] ? 4 : 3;
- lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
-
- curf= 0;
- for(i=0; i<lvl->prev->totface; ++i) {
- const int max= lvl->prev->faces[i].v[3] ? 3 : 2;
-
- lvl->prev->faces[i].childrenstart= curf;
- for(j=0; j<max+1; ++j) {
- lvl->faces[curf].v[0]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev,
- lvl->prev->faces[i].v[j],
- lvl->prev->faces[i].v[j==0?max:j-1]);
- lvl->faces[curf].v[1]= lvl->prev->faces[i].v[j];
- lvl->faces[curf].v[2]= find_mid_edge(lvl->prev->vert_edge_map,lvl->prev,
- lvl->prev->faces[i].v[j],
- lvl->prev->faces[i].v[j==max?0:j+1]);
- lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i;
- lvl->faces[curf].flag= lvl->prev->faces[i].flag;
- lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr;
-
- ++curf;
- }
- }
-
- /* Create edges
- ============ */
- /* Figure out how many edges to allocate */
- lvl->totedge= lvl->prev->totedge*2;
- for(i=0; i<lvl->prev->totface; ++i)
- lvl->totedge+= lvl->prev->faces[i].v[3]?4:3;
- lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
-
- for(i=0; i<lvl->prev->totedge; ++i) {
- lvl->edges[i*2].v[0]= lvl->prev->edges[i].v[0];
- lvl->edges[i*2].v[1]= lvl->prev->edges[i].mid;
- lvl->edges[i*2+1].v[0]= lvl->prev->edges[i].mid;
- lvl->edges[i*2+1].v[1]= lvl->prev->edges[i].v[1];
- }
- /* Add edges inside of old polygons */
- curf= 0;
- cure= lvl->prev->totedge*2;
- for(i=0; i<lvl->prev->totface; ++i) {
- for(j=0; j<(lvl->prev->faces[i].v[3]?4:3); ++j) {
- lvl->edges[cure].v[0]= lvl->faces[curf].v[2];
- lvl->edges[cure].v[1]= lvl->faces[curf].v[3];
- ++cure;
- ++curf;
- }
- }
-
- multires_calc_level_maps(lvl);
-
- /* Smooth vertices
- =============== */
- for(i=0; i<lvl->prev->totface; ++i) {
- const MultiresFace *f= &lvl->prev->faces[i];
- data.corner1= oldverts[f->v[0]].co;
- data.corner2= oldverts[f->v[1]].co;
- data.corner3= oldverts[f->v[2]].co;
- data.corner4= oldverts[f->v[3]].co;
- data.quad= f->v[3] ? 1 : 0;
- multi_apply(me->mr->verts[f->mid].co, &data, 3, catmullclark_smooth_face);
- }
-
- if(G.scene->toolsettings->multires_subdiv_type == 0) {
- for(i=0; i<lvl->prev->totedge; ++i) {
- const MultiresEdge *e= &lvl->prev->edges[i];
- data.boundary= multires_edge_is_boundary(lvl->prev,i);
- edge_face_neighbor_midpoints_accum(&data,lvl->prev, me->mr->verts, sizeof(MVert),e);
- data.endpoint1= oldverts[e->v[0]].co;
- data.endpoint2= oldverts[e->v[1]].co;
- multi_apply(me->mr->verts[e->mid].co, &data, 3, catmullclark_smooth_edge);
- }
-
- for(i=0; i<lvl->prev->totvert; ++i) {
- data.boundary= multires_vert_is_boundary(lvl->prev,i);
- data.original= oldverts[i].co;
- data.edge_count= BLI_countlist(&lvl->prev->vert_edge_map[i]);
- if(data.boundary)
- boundary_edges_average(&data,lvl->prev, oldverts, sizeof(MVert),i);
- else {
- vert_face_neighbor_midpoints_average(&data,lvl->prev, me->mr->verts,
- sizeof(MVert),i);
- vert_edge_neighbor_midpoints_average(&data,lvl->prev, oldverts,
- sizeof(MVert),i);
- }
- multi_apply(me->mr->verts[i].co, &data, 3, catmullclark_smooth_vert);
- }
+ if(CustomData_number_of_layers(G.obedit ? &G.editMesh->fdata : &me->fdata, CD_MCOL) > 1) {
+ int ret= okee("Adding a level will delete all but the active vertex color layer, proceed?");
+ if(!ret)
+ return;
}
- MEM_freeN(oldverts);
-
- /* Vertex Colors
- ============= */
- curf= 0;
- if(me->mr->use_col) {
- MultiresColFace *cf= MEM_callocN(sizeof(MultiresColFace)*lvl->totface,"Multirescolfaces");
- lvl->colfaces= cf;
- for(i=0; i<lvl->prev->totface; ++i) {
- const char sides= lvl->prev->faces[i].v[3]?4:3;
- MultiresCol cntr;
-
- /* Find average color of 4 (or 3 for triangle) verts */
- multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides);
-
- for(j=0; j<sides; ++j) {
- multires_col_avg2(&cf->col[0],
- &lvl->prev->colfaces[i].col[j],
- &lvl->prev->colfaces[i].col[j==0?sides-1:j-1]);
- cf->col[1]= lvl->prev->colfaces[i].col[j];
- multires_col_avg2(&cf->col[2],
- &lvl->prev->colfaces[i].col[j],
- &lvl->prev->colfaces[i].col[j==sides-1?0:j+1]);
- cf->col[3]= cntr;
-
- ++cf;
- }
- }
- }
+ waitcursor(1);
+ multires_add_level(ob_v, me, G.scene->toolsettings->multires_subdiv_type);
+ multires_level_to_editmesh(ob_v, me, 0);
+ multires_finish_mesh_update(ob_v);
- multires_update_levels(me, 0);
- me->mr->newlvl= me->mr->level_count;
- me->mr->current= me->mr->newlvl;
- /* Unless the render level has been set to something other than the
- highest level (by the user), increment the render level to match
- the highest available level */
- if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count;
-
- multires_level_to_mesh(ob, me, 0);
-
allqueue(REDRAWBUTSEDIT, 0);
-
BIF_undo_push("Add multires level");
-
waitcursor(0);
}
void multires_set_level_cb(void *ob, void *me)
{
- multires_set_level(ob, me, 0);
-}
-
-void multires_set_level(struct Object *ob, struct Mesh *me, const int render)
-{
waitcursor(1);
multires_check_state();
- if(me->pv) sculptmode_pmv_off(me);
-
- check_colors(me);
- multires_update_levels(me, render);
-
- me->mr->current= me->mr->newlvl;
- if(me->mr->current<1) me->mr->current= 1;
- else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count;
-
- multires_level_to_mesh(ob, me, render);
+ multires_set_level(ob, me, 0);
+ multires_level_to_editmesh(ob, me, 0);
+ multires_finish_mesh_update(ob);
- if(!render && (G.obedit || G.f & G_SCULPTMODE))
+ if(G.obedit || G.f & G_SCULPTMODE)
BIF_undo_push("Multires set level");
allqueue(REDRAWBUTSEDIT, 0);
@@ -1053,561 +402,10 @@ void multires_set_level(struct Object *ob, struct Mesh *me, const int render)
waitcursor(0);
}
-
-void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed)
-{
- if(!eed) return;
-
- if(flag & ME_SEAM) eed->seam= 1;
- if(flag & ME_SHARP) eed->sharp = 1;
- if(flag & SELECT) eed->f |= SELECT;
- if(flag & ME_FGON) eed->h= EM_FGON;
- if(flag & ME_HIDE) eed->h |= 1;
-
- eed->crease= ((float)crease)/255.0;
-}
-
-/* note, function is called in background render too, without UI */
-void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
-{
- MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
- int i;
- EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
- EditVert **eves= NULL;
- EditEdge *eed= NULL;
-
- if(em) {
- /* Remove editmesh elements */
- free_editMesh(em);
-
- eves= MEM_callocN(sizeof(EditVert)*lvl->totvert, "editvert pointers");
- } else {
- CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
- CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
- CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
- CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface);
- CustomData_free_layers(&me->fdata, CD_MCOL, me->totface);
-
- me->totvert= lvl->totvert;
- me->totface= lvl->totface;
- me->totedge= lvl->totedge;
-
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
- CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
- mesh_update_customdata_pointers(me);
- }
-
- /* Vertices/Edges/Faces */
-
- for(i=0; i<lvl->totvert; ++i) {
- if(em) {
- eves[i]= addvertlist(me->mr->verts[i].co, NULL);
- if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
- if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
- eves[i]->data= NULL;
- }
- else
- me->mvert[i]= me->mr->verts[i];
- }
- for(i=0; i<lvl->totedge; ++i) {
- if(em) {
- addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL);
- } else {
- me->medge[i].v1= lvl->edges[i].v[0];
- me->medge[i].v2= lvl->edges[i].v[1];
- me->medge[i].flag &= ~ME_HIDE;
- }
- }
- for(i=0; i<lvl->totface; ++i) {
- if(em) {
- EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
- EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
- eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
- efa->flag= lvl->faces[i].flag & ~ME_HIDE;
- efa->mat_nr= lvl->faces[i].mat_nr;
- if(lvl->faces[i].flag & ME_FACE_SEL)
- efa->f |= SELECT;
- if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
- efa->data= NULL;
- }
- else {
- me->mface[i].v1= lvl->faces[i].v[0];
- me->mface[i].v2= lvl->faces[i].v[1];
- me->mface[i].v3= lvl->faces[i].v[2];
- me->mface[i].v4= lvl->faces[i].v[3];
- me->mface[i].flag= lvl->faces[i].flag;
- me->mface[i].flag &= ~ME_HIDE;
- me->mface[i].mat_nr= lvl->faces[i].mat_nr;
- }
- }
-
- /* Edge flags */
- if(em) eed= em->edges.first;
- if(lvl==me->mr->levels.first) {
- for(i=0; i<lvl->totedge; ++i) {
- if(em) {
- medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
- eed= eed->next;
- }
- else {
- me->medge[i].flag= me->mr->edge_flags[i];
- me->medge[i].crease= me->mr->edge_creases[i];
- }
- }
- } else {
- MultiresLevel *lvl1= me->mr->levels.first;
- const int last= lvl1->totedge * pow(2, me->mr->current-1);
- for(i=0; i<last; ++i) {
- const int ndx= i / pow(2, me->mr->current-1);
-
- if(em) {
- medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed);
- eed= eed->next;
- }
- else {
- me->medge[i].flag= me->mr->edge_flags[ndx];
- me->medge[i].crease= me->mr->edge_creases[ndx];
- }
- }
- }
-
- if(em) {
- eed= em->edges.first;
- for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
- eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
- me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
- }
- }
-
- EM_select_flush();
-
- multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
- multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
-
- /* Colors */
- if(me->mr->use_col) {
- MCol c[4];
- EditFace *efa= NULL;
- CustomData *src= em ? &em->fdata : &me->fdata;
- if(em) {
- if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL);
- efa= em->faces.first;
- }
- else {
- if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface);
- }
-
- for(i=0; i<lvl->totface; ++i) {
- if(em) {
- if(me->mr->use_col) {
- multires_to_mcol(&lvl->colfaces[i], c);
- CustomData_em_set(src, efa->data, CD_MCOL, c);
- }
- efa= efa->next;
- }
- else if(me->mr->use_col) multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]);
- }
-
- }
-
- mesh_update_customdata_pointers(me);
-
- if(em) {
- MEM_freeN(eves);
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- recalc_editnormals();
- } else {
- multires_edge_level_update(ob,me);
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
- }
-
- /* friendly check for background render */
- if(G.background==0) {
- object_handle_update(ob);
- countall();
-
- if(G.vd && G.vd->depths) G.vd->depths->damaged= 1;
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWIMAGE, 0);
- }
-}
-
-void multires_update_colors(Mesh *me)
-{
- MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
- MultiresCol *pr_deltas= NULL, *cr_deltas= NULL;
- EditMesh *em= G.obedit ? G.editMesh : NULL;
- CustomData *src= em ? &em->fdata : &me->fdata;
- EditFace *efa= NULL;
- unsigned i,j,curf= 0;
-
- if(me->mr->use_col) {
- /* Calc initial deltas */
- cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"initial color/uv deltas");
-
- if(em) efa= em->faces.first;
- for(i=0; i<lvl->totface; ++i) {
- MCol *col= em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4];
- for(j=0; j<4; ++j) {
- if(me->mr->use_col) {
- cr_deltas[i*4+j].a= col[j].a - lvl->colfaces[i].col[j].a;
- cr_deltas[i*4+j].r= col[j].r - lvl->colfaces[i].col[j].r;
- cr_deltas[i*4+j].g= col[j].g - lvl->colfaces[i].col[j].g;
- cr_deltas[i*4+j].b= col[j].b - lvl->colfaces[i].col[j].b;
- }
- }
- if(em) efa= efa->next;
- }
-
- /* Update current level */
- if(em) efa= em->faces.first;
- for(i=0; i<lvl->totface; ++i) {
- MultiresColFace *f= &lvl->colfaces[i];
-
- if(me->mr->use_col)
- mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]);
-
- if(em) efa= efa->next;
- }
-
- /* Update higher levels */
- lvl= lvl->next;
- while(lvl) {
- /* Set up new deltas, but keep the ones from the previous level */
- if(pr_deltas) MEM_freeN(pr_deltas);
- pr_deltas= cr_deltas;
- cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"color deltas");
-
- curf= 0;
- for(i=0; i<lvl->prev->totface; ++i) {
- const char sides= lvl->prev->faces[i].v[3]?4:3;
- MultiresCol cntr;
-
- /* Find average color of 4 (or 3 for triangle) verts */
- multires_col_avg(&cntr,&pr_deltas[i*4],sides);
-
- for(j=0; j<sides; ++j) {
- multires_col_avg2(&cr_deltas[curf*4],
- &pr_deltas[i*4+j],
- &pr_deltas[i*4+(j==0?sides-1:j-1)]);
- cr_deltas[curf*4+1]= pr_deltas[i*4+j];
- multires_col_avg2(&cr_deltas[curf*4+2],
- &pr_deltas[i*4+j],
- &pr_deltas[i*4+(j==sides-1?0:j+1)]);
- cr_deltas[curf*4+3]= cntr;
- ++curf;
- }
- }
-
- for(i=0; i<lvl->totface; ++i) {
- for(j=0; j<4; ++j) {
- lvl->colfaces[i].col[j].a+= cr_deltas[i*4+j].a;
- lvl->colfaces[i].col[j].r+= cr_deltas[i*4+j].r;
- lvl->colfaces[i].col[j].g+= cr_deltas[i*4+j].g;
- lvl->colfaces[i].col[j].b+= cr_deltas[i*4+j].b;
- }
- }
-
- lvl= lvl->next;
- }
- if(pr_deltas) MEM_freeN(pr_deltas);
- if(cr_deltas) MEM_freeN(cr_deltas);
-
- /* Update lower levels */
- lvl= me->mr->levels.last;
- lvl= lvl->prev;
- while(lvl) {
- MultiresColFace *nf= lvl->next->colfaces;
- for(i=0; i<lvl->totface; ++i) {
- MultiresFace *f= &lvl->faces[i];
- for(j=0; j<(f->v[3]?4:3); ++j) {
- lvl->colfaces[i].col[j]= nf->col[1];
- ++nf;
- }
- }
- lvl= lvl->prev;
- }
- }
-}
-
-/* Update vertex locations and vertex flags */
-void multires_update_vertices(Mesh *me, EditMesh *em)
-{
- MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
- *last_lvl= me->mr->levels.last;
- vec3f *pr_deltas= NULL, *cr_deltas= NULL, *swap_deltas= NULL;
- EditVert *eve= NULL;
- MultiApplyData data;
- int i, j;
-
- /* Prepare deltas */
- pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1");
- cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2");
-
- /* Calculate initial deltas -- current mesh subtracted from current level*/
- if(em) eve= em->verts.first;
- for(i=0; i<cr_lvl->totvert; ++i) {
- if(em) {
- VecSubf(&cr_deltas[i].x, eve->co, me->mr->verts[i].co);
- eve= eve->next;
- } else
- VecSubf(&cr_deltas[i].x, me->mvert[i].co, me->mr->verts[i].co);
- }
-
-
- /* Copy current level's vertex flags and clear the rest */
- if(em) eve= em->verts.first;
- for(i=0; i < last_lvl->totvert; ++i) {
- if(i < cr_lvl->totvert) {
- MVert mvflag;
- multires_get_vert(&mvflag, eve, &me->mvert[i], i);
- if(em) eve= eve->next;
- me->mr->verts[i].flag= mvflag.flag;
- }
- else
- me->mr->verts[i].flag= 0;
- }
-
- /* If already on the highest level, copy current verts (including flags) into current level */
- if(cr_lvl == last_lvl) {
- if(em)
- eve= em->verts.first;
- for(i=0; i<cr_lvl->totvert; ++i) {
- multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i);
- if(em) eve= eve->next;
- }
- }
-
- /* Update higher levels */
- pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
- cr_lvl= pr_lvl->next;
- while(cr_lvl) {
- /* Swap the old/new deltas */
- swap_deltas= pr_deltas;
- pr_deltas= cr_deltas;
- cr_deltas= swap_deltas;
-
- /* Calculate and add new deltas
- ============================ */
- for(i=0; i<pr_lvl->totface; ++i) {
- const MultiresFace *f= &pr_lvl->faces[i];
- data.corner1= &pr_deltas[f->v[0]].x;
- data.corner2= &pr_deltas[f->v[1]].x;
- data.corner3= &pr_deltas[f->v[2]].x;
- data.corner4= &pr_deltas[f->v[3]].x;
- data.quad= f->v[3] ? 1 : 0;
- multi_apply(&cr_deltas[f->mid].x, &data, 3, catmullclark_smooth_face);
-
- for(j=0; j<(data.quad?4:3); ++j)
- me->mr->verts[f->mid].flag |= me->mr->verts[f->v[j]].flag;
- }
-
- for(i=0; i<pr_lvl->totedge; ++i) {
- const MultiresEdge *e= &pr_lvl->edges[i];
- data.boundary= multires_edge_is_boundary(pr_lvl,i);
- edge_face_neighbor_midpoints_accum(&data,pr_lvl,cr_deltas,sizeof(vec3f),e);
- data.endpoint1= &pr_deltas[e->v[0]].x;
- data.endpoint2= &pr_deltas[e->v[1]].x;
- multi_apply(&cr_deltas[e->mid].x, &data, 3, catmullclark_smooth_edge);
-
- for(j=0; j<2; ++j)
- me->mr->verts[e->mid].flag |= me->mr->verts[e->v[j]].flag;
- }
-
- for(i=0; i<pr_lvl->totvert; ++i) {
- data.boundary= multires_vert_is_boundary(pr_lvl,i);
- data.original= &pr_deltas[i].x;
- data.edge_count= BLI_countlist(&pr_lvl->vert_edge_map[i]);
- if(data.boundary)
- boundary_edges_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i);
- else {
- vert_face_neighbor_midpoints_average(&data,pr_lvl,cr_deltas,sizeof(vec3f),i);
- vert_edge_neighbor_midpoints_average(&data,pr_lvl,pr_deltas,sizeof(vec3f),i);
- }
- multi_apply(&cr_deltas[i].x, &data, 3, catmullclark_smooth_vert);
- }
-
- /* Apply deltas to vertex locations */
- for(i=0; (cr_lvl == last_lvl) && (i < cr_lvl->totvert); ++i) {
- VecAddf(me->mr->verts[i].co,
- me->mr->verts[i].co,
- &cr_deltas[i].x);
- }
-
- pr_lvl= pr_lvl->next;
- cr_lvl= cr_lvl->next;
- }
- if(pr_deltas) MEM_freeN(pr_deltas);
- if(cr_deltas) MEM_freeN(cr_deltas);
-
-}
-
-void multires_update_faces(Mesh *me, EditMesh *em)
-{
- MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL,
- *last_lvl= me->mr->levels.last;
- char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL,
- *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL;
- EditFace *efa= NULL;
- unsigned i,j,curf;
-
- /* Find for each face whether flag/mat has changed */
- pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
- cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1");
- pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
- cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1");
- if(em) efa= em->faces.first;
- for(i=0; i<cr_lvl->totface; ++i) {
- MultiresFace mftmp;
- multires_get_face(&mftmp, efa, &me->mface[i]);
- if(cr_lvl->faces[i].flag != mftmp.flag)
- cr_flag_damaged[i]= 1;
- if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr)
- cr_mat_damaged[i]= 1;
-
- /* Update current level */
- cr_lvl->faces[i].flag= mftmp.flag;
- cr_lvl->faces[i].mat_nr= mftmp.mat_nr;
-
- if(em) efa= efa->next;
- }
- or_flag_damaged= MEM_dupallocN(cr_flag_damaged);
- or_mat_damaged= MEM_dupallocN(cr_mat_damaged);
-
- /* Update lower levels */
- cr_lvl= cr_lvl->prev;
- while(cr_lvl) {
- swap= pr_flag_damaged;
- pr_flag_damaged= cr_flag_damaged;
- cr_flag_damaged= swap;
-
- swap= pr_mat_damaged;
- pr_mat_damaged= cr_mat_damaged;
- cr_mat_damaged= swap;
-
- curf= 0;
- for(i=0; i<cr_lvl->totface; ++i) {
- const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
-
- /* Check damages */
- for(j=0; j<sides; ++j, ++curf) {
- if(pr_flag_damaged[curf]) {
- cr_lvl->faces[i].flag= cr_lvl->next->faces[curf].flag;
- cr_flag_damaged[i]= 1;
- }
- if(pr_mat_damaged[curf]) {
- cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr;
- cr_mat_damaged[i]= 1;
- }
- }
- }
-
- cr_lvl= cr_lvl->prev;
- }
-
- /* Clear to original damages */
- if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
- if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
- cr_flag_damaged= or_flag_damaged;
- cr_mat_damaged= or_mat_damaged;
-
- /* Update higher levels */
- pr_lvl= current_level(me->mr);
- cr_lvl= pr_lvl->next;
- while(cr_lvl) {
- swap= pr_flag_damaged;
- pr_flag_damaged= cr_flag_damaged;
- cr_flag_damaged= swap;
-
- swap= pr_mat_damaged;
- pr_mat_damaged= cr_mat_damaged;
- cr_mat_damaged= swap;
-
- /* Update faces */
- for(i=0, curf= 0; i<pr_lvl->totface; ++i) {
- const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
- for(j=0; j<sides; ++j, ++curf) {
- if(pr_flag_damaged[i]) {
- cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
- cr_flag_damaged[curf]= 1;
- }
- if(pr_mat_damaged[i]) {
- cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
- cr_mat_damaged[curf]= 1;
- }
- }
- }
-
- pr_lvl= pr_lvl->next;
- cr_lvl= cr_lvl->next;
- }
-
- if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
- if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
- if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
- if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
-}
-
-void multires_update_levels(Mesh *me, const int render)
-{
- EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
-
- multires_update_first_level(me, em);
- multires_update_vertices(me, em);
- multires_update_faces(me, em);
- multires_update_colors(me);
-}
-
-void multires_calc_level_maps(MultiresLevel *lvl)
-{
- unsigned i,j;
- MultiresMapNode *indexnode= NULL;
-
- lvl->map_mem= MEM_mallocN(sizeof(MultiresMapNode)*(lvl->totedge*2 + lvl->totface*4), "map_mem");
- indexnode= lvl->map_mem;
-
- lvl->vert_edge_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_edge_map");
- for(i=0; i<lvl->totedge; ++i) {
- for(j=0; j<2; ++j, ++indexnode) {
- indexnode->Index= i;
- BLI_addtail(&lvl->vert_edge_map[lvl->edges[i].v[j]], indexnode);
- }
- }
-
- lvl->vert_face_map= MEM_callocN(sizeof(ListBase)*lvl->totvert,"vert_face_map");
- for(i=0; i<lvl->totface; ++i){
- for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j, ++indexnode) {
- indexnode->Index= i;
- BLI_addtail(&lvl->vert_face_map[lvl->faces[i].v[j]], indexnode);
- }
- }
-}
-
-void multires_edge_level_update(void *ob, void *me_v)
+void multires_edge_level_update_cb(void *ob_v, void *me_v)
{
- if(!G.obedit) {
- Mesh *me= me_v;
- MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
- MultiresLevel *edge_lvl= BLI_findlink(&me->mr->levels,me->mr->edgelvl-1);
- const int threshold= edge_lvl->totedge * powf(2, me->mr->current - me->mr->edgelvl);
- unsigned i;
-
- for(i=0; i<cr_lvl->totedge; ++i) {
- const int ndx= me->pv ? me->pv->edge_map[i] : i;
- if(ndx != -1) { /* -1= hidden edge */
- if(me->mr->edgelvl >= me->mr->current || i<threshold)
- me->medge[ndx].flag |= ME_EDGEDRAW | ME_EDGERENDER;
- else
- me->medge[ndx].flag &= ~ME_EDGEDRAW | ~ME_EDGERENDER;
- }
- }
-
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWVIEW3D, 0);
- }
+ multires_edge_level_update(ob_v, me_v);
+ allqueue(REDRAWVIEW3D, 0);
}
int multires_modifier_warning()
diff --git a/source/blender/src/oops.c b/source/blender/src/oops.c
index 6c0efd27a22..7def4ca615e 100644
--- a/source/blender/src/oops.c
+++ b/source/blender/src/oops.c
@@ -50,6 +50,7 @@
#include "DNA_texture_types.h"
#include "DNA_texture_types.h"
#include "DNA_key_types.h"
+#include "DNA_group_types.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
@@ -656,8 +657,21 @@ void add_material_oopslinks(Material *ma, Oops *oops, short flag)
if(ma->mtex[a]) add_oopslink("ob", oops, ID_OB, &(ma->mtex[a]->object), 0.0, (float)(0.2*OOPSY));
}
}
- if(flag & OOPS_IP) {
+ if(flag & OOPS_IP)
if(ma->ipo) add_oopslink("ipo", oops, ID_IP, &(ma->ipo), OOPSX, (float)(0.5*OOPSY));
+
+ if (ma->group)
+ add_oopslink("group", oops, ID_GR, &(ma->group), OOPSX, (float)(0.5*OOPSY));
+}
+
+
+void add_group_oopslinks(Group *gp, Oops *oops, short flag)
+{
+ GroupObject *gob;
+ if(flag & OOPS_GR) {
+ for(gob=gp->gobject.first; gob; gob= gob->next) {
+ add_oopslink("group", oops, ID_GR, &(gob->ob), (float)(0.5*OOPSX), (float)OOPSY);
+ }
}
}
@@ -701,6 +715,9 @@ void add_object_oopslinks(Object *ob, Oops *oops, short flag)
}
if(flag & OOPS_IP) add_oopslink("ipo", oops, ID_IP, &ob->ipo, OOPSX, (float)(0.5*OOPSY));
+
+ if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
+ add_oopslink("group", oops, ID_GR, &ob->dup_group, OOPSX, (float)(0.5*OOPSY));
}
void add_mesh_oopslinks(Mesh *me, Oops *oops, short flag)
@@ -817,6 +834,9 @@ Oops *add_test_oops(void *id) /* incl links */
case ID_MA:
add_material_oopslinks((Material *)id, oops, G.soops->visiflag);
break;
+ case ID_GR:
+ add_group_oopslinks((Group *)id, oops, G.soops->visiflag);
+ break;
case ID_TE:
tex= (Tex *)id;
if(tex->ima) if(G.soops->visiflag & OOPS_IM) add_oopslink("image", oops, ID_IM, &tex->ima, OOPSX, (float)(0.3*OOPSY));
@@ -962,7 +982,13 @@ void build_oops()
ima= ima->id.next;
}
}
-
+ if(G.soops->visiflag & OOPS_GR) {
+ Group *gp= G.main->group.first;
+ while(gp) {
+ oops= add_test_oops(gp);
+ gp= gp->id.next;
+ }
+ }
}
else {
diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c
index 271d002e464..b9c1725233f 100644
--- a/source/blender/src/outliner.c
+++ b/source/blender/src/outliner.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <stdlib.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -138,6 +139,8 @@ extern ListBase server_list;
/* ******************** PROTOTYPES ***************** */
static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty);
+static void outliner_do_object_operation(SpaceOops *soops, ListBase *lb,
+ void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *));
/* ******************** PERSISTANT DATA ***************** */
@@ -229,6 +232,7 @@ static void check_persistant(SpaceOops *soops, TreeElement *te, ID *id, short ty
if(type) tselem->nr= nr; // we're picky! :)
else tselem->nr= 0;
tselem->id= id;
+ tselem->used = 0;
tselem->flag= TSE_CLOSED;
te->store_index= ts->usedelem;
@@ -261,6 +265,20 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
}
}
+static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
+{
+ TreeElement *te= lb->first;
+ while(te) {
+ TreeStoreElem *tselem= TREESTORE(te);
+ if(tselem->flag & TSE_CLOSED) {
+ if (te->xend > *w)
+ *w = te->xend;
+ }
+ outliner_width(soops, &te->subtree, w);
+ te= te->next;
+ }
+}
+
static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index)
{
TreeElement *te= lb->first, *tes;
@@ -429,6 +447,10 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
te->name= "UV";
te->directdata= &srl->passflag;
+ te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_MIST);
+ te->name= "Mist";
+ te->directdata= &srl->passflag;
+
te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, SCE_PASS_INDEXOB);
te->name= "Index Object";
te->directdata= &srl->passflag;
@@ -577,19 +599,22 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
pchan->prev= (bPoseChannel *)ten;
if(pchan->constraints.first) {
- Object *target;
+ //Object *target;
bConstraint *con;
TreeElement *ten1;
TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
- char *str;
+ //char *str;
tenla1->name= "Constraints";
for(con= pchan->constraints.first; con; con= con->next, const_index++) {
ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
+#if 0 /* disabled as it needs to be reworked for recoded constraints system */
target= get_constraint_target(con, &str);
if(str && str[0]) ten1->name= str;
else if(target) ten1->name= target->id.name+2;
else ten1->name= con->name;
+#endif
+ ten1->name= con->name;
ten1->directdata= con;
/* possible add all other types links? */
}
@@ -618,6 +643,21 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if(pchan->next) pchan->next->prev= pchan;
}
}
+
+ /* Pose Groups */
+ if(ob->pose->agroups.first) {
+ bActionGroup *agrp;
+ TreeElement *ten;
+ TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
+ int a= 0;
+
+ tenla->name= "Bone Groups";
+ for (agrp=ob->pose->agroups.first; agrp; agrp=agrp->next, a++) {
+ ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSEGRP, a);
+ ten->name= agrp->name;
+ ten->directdata= agrp;
+ }
+ }
}
outliner_add_element(soops, &te->subtree, ob->ipo, te, 0, 0);
@@ -627,20 +667,23 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a);
if(ob->constraints.first) {
- Object *target;
+ //Object *target;
bConstraint *con;
TreeElement *ten;
TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
int a= 0;
- char *str;
+ //char *str;
tenla->name= "Constraints";
for(con= ob->constraints.first; con; con= con->next, a++) {
ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
+#if 0 /* disabled due to constraints system targets recode... code here needs review */
target= get_constraint_target(con, &str);
if(str && str[0]) ten->name= str;
else if(target) ten->name= target->id.name+2;
else ten->name= con->name;
+#endif
+ ten->name= con->name;
ten->directdata= con;
/* possible add all other types links? */
}
@@ -934,7 +977,7 @@ static void outliner_build_tree(SpaceOops *soops)
outliner_free_tree(&soops->tree);
outliner_storage_cleanup(soops);
-
+
/* clear ob id.new flags */
for(ob= G.main->object.first; ob; ob= ob->id.next) ob->id.newid= NULL;
@@ -1127,6 +1170,75 @@ static void outliner_set_flag(SpaceOops *soops, ListBase *lb, short flag, short
}
}
+void object_toggle_visibility_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+ Base *base= (Base *)te->directdata;
+
+ if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene);
+ if(base) {
+ base->object->restrictflag^=OB_RESTRICT_VIEW;
+ }
+}
+
+void outliner_toggle_visibility(struct ScrArea *sa)
+{
+ SpaceOops *soops= sa->spacedata.first;
+
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_visibility_cb);
+
+ BIF_undo_push("Outliner toggle selectability");
+
+ allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWINFO, 1);
+}
+
+static void object_toggle_selectability_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+ Base *base= (Base *)te->directdata;
+
+ if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene);
+ if(base) {
+ base->object->restrictflag^=OB_RESTRICT_SELECT;
+ }
+}
+
+void outliner_toggle_selectability(struct ScrArea *sa)
+{
+ SpaceOops *soops= sa->spacedata.first;
+
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_selectability_cb);
+
+ BIF_undo_push("Outliner toggle selectability");
+
+ allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWINFO, 1);
+}
+
+void object_toggle_renderability_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+ Base *base= (Base *)te->directdata;
+
+ if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene);
+ if(base) {
+ base->object->restrictflag^=OB_RESTRICT_RENDER;
+ }
+}
+
+void outliner_toggle_renderability(struct ScrArea *sa)
+{
+ SpaceOops *soops= sa->spacedata.first;
+
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_renderability_cb);
+
+ BIF_undo_push("Outliner toggle renderability");
+
+ allqueue(REDRAWVIEW3D, 1);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWINFO, 1);
+}
+
void outliner_toggle_visible(struct ScrArea *sa)
{
SpaceOops *soops= sa->spacedata.first;
@@ -1595,6 +1707,24 @@ static int tree_element_active_nla_action(TreeElement *te, TreeStoreElem *tselem
return 0;
}
+static int tree_element_active_posegroup(TreeElement *te, TreeStoreElem *tselem, int set)
+{
+ Object *ob= (Object *)tselem->id;
+
+ if(set) {
+ if (ob->pose) {
+ ob->pose->active_group= te->index+1;
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+ else {
+ if(ob==OBACT && ob->pose) {
+ if (ob->pose->active_group== te->index+1) return 1;
+ }
+ }
+ return 0;
+}
+
static int tree_element_active_posechannel(TreeElement *te, TreeStoreElem *tselem, int set)
{
Object *ob= (Object *)tselem->id;
@@ -1776,6 +1906,8 @@ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStore
return tree_element_active_constraint(te, tselem, set);
case TSE_R_LAYER:
return tree_element_active_renderlayer(te, tselem, set);
+ case TSE_POSEGRP:
+ return tree_element_active_posegroup(te, tselem, set);
}
return 0;
}
@@ -1894,21 +2026,17 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even
/* activate a name button? */
if(event==LEFTMOUSE) {
- if (G.qual & LR_CTRLKEY) {
- if(ELEM8(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_R_LAYER_BASE, TSE_R_PASS))
+ if (G.qual == LR_CTRLKEY) {
+ if(ELEM9(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS))
error("Cannot edit builtin name");
- else if(tselem->id->lib)
+ else if(tselem->id->lib) {
error_libdata();
- else {
+ } else if(te->idcode == ID_LI && te->parent) {
+ error("Cannot edit the path of an indirectly linked library");
+ } else {
tselem->flag |= TSE_TEXTBUT;
}
} else {
-
- if (G.qual & LR_SHIFTKEY) {
- if(tselem->id->lib && tselem->type==0) {
- notice(tselem->id->lib->name);
- }
- }
/* always makes active object */
tree_element_active_object(soops, te);
@@ -2042,7 +2170,7 @@ void outliner_show_active(struct ScrArea *sa)
{
SpaceOops *so= sa->spacedata.first;
TreeElement *te;
- int ytop;
+ int xdelta, ytop;
if(OBACT == NULL) return;
@@ -2053,6 +2181,12 @@ void outliner_show_active(struct ScrArea *sa)
if(ytop>0) ytop= 0;
so->v2d.cur.ymax= ytop;
so->v2d.cur.ymin= ytop-(so->v2d.mask.ymax-so->v2d.mask.ymin);
+
+ /* make te->xs ==> te->xend center of view */
+ xdelta = te->xs - so->v2d.cur.xmin;
+ so->v2d.cur.xmin += xdelta;
+ so->v2d.cur.xmax += xdelta;
+
so->storeflag |= SO_TREESTORE_REDRAW;
scrarea_queue_redraw(sa);
}
@@ -2062,7 +2196,7 @@ void outliner_show_selected(struct ScrArea *sa)
{
SpaceOops *so= sa->spacedata.first;
TreeElement *te;
- int ytop;
+ int xdelta, ytop;
te= outliner_find_id(so, &so->tree, (ID *)OBACT);
if(te) {
@@ -2071,6 +2205,12 @@ void outliner_show_selected(struct ScrArea *sa)
if(ytop>0) ytop= 0;
so->v2d.cur.ymax= ytop;
so->v2d.cur.ymin= ytop-(so->v2d.mask.ymax-so->v2d.mask.ymin);
+
+ /* make te->xs ==> te->xend center of view */
+ xdelta = te->xs - so->v2d.cur.xmin;
+ so->v2d.cur.xmin += xdelta;
+ so->v2d.cur.xmax += xdelta;
+
so->storeflag |= SO_TREESTORE_REDRAW;
scrarea_queue_redraw(sa);
}
@@ -2149,7 +2289,7 @@ void outliner_find_panel(struct ScrArea *sa, int again, int flags)
TreeElement *te= NULL;
TreeElement *last_find;
TreeStoreElem *tselem;
- int ytop, prevFound=0;
+ int ytop, xdelta, prevFound=0;
char name[33];
/* get last found tree-element based on stored search_tse */
@@ -2196,6 +2336,11 @@ void outliner_find_panel(struct ScrArea *sa, int again, int flags)
soops->v2d.cur.ymax= ytop;
soops->v2d.cur.ymin= ytop-(soops->v2d.mask.ymax-soops->v2d.mask.ymin);
+ /* make te->xs ==> te->xend center of view */
+ xdelta = te->xs - soops->v2d.cur.xmin;
+ soops->v2d.cur.xmin += xdelta;
+ soops->v2d.cur.xmax += xdelta;
+
/* store selection */
soops->search_tse= *tselem;
@@ -2208,7 +2353,8 @@ void outliner_find_panel(struct ScrArea *sa, int again, int flags)
}
}
else {
- if (name) error("Not found: %s", name);
+ /* no tree-element found */
+ error("Not found: %s", name);
}
}
@@ -2323,9 +2469,11 @@ void outliner_select(struct ScrArea *sa )
/* ************ SELECTION OPERATIONS ********* */
-static int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; // globals, euh... you can do better
-
-static void set_operation_types(SpaceOops *soops, ListBase *lb)
+static void set_operation_types(SpaceOops *soops, ListBase *lb,
+ int *scenelevel,
+ int *objectlevel,
+ int *idlevel,
+ int *datalevel)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -2335,22 +2483,22 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb)
if(tselem->flag & TSE_SELECTED) {
if(tselem->type) {
#ifdef WITH_VERSE
- if(te->idcode==ID_VS) datalevel= TSE_VERSE_SESSION;
- else if(te->idcode==ID_VN) datalevel= TSE_VERSE_OBJ_NODE;
- else if(datalevel==0) datalevel= tselem->type;
+ if(te->idcode==ID_VS) *datalevel= TSE_VERSE_SESSION;
+ else if(te->idcode==ID_VN) *datalevel= TSE_VERSE_OBJ_NODE;
+ else if(*datalevel==0) *datalevel= tselem->type;
#else
- if(datalevel==0) datalevel= tselem->type;
+ if(*datalevel==0) *datalevel= tselem->type;
#endif
- else if(datalevel!=tselem->type) datalevel= -1;
+ else if(*datalevel!=tselem->type) *datalevel= -1;
}
else {
int idcode= GS(tselem->id->name);
switch(idcode) {
case ID_SCE:
- scenelevel= 1;
+ *scenelevel= 1;
break;
case ID_OB:
- objectlevel= 1;
+ *objectlevel= 1;
break;
case ID_ME: case ID_CU: case ID_MB: case ID_LT:
@@ -2358,13 +2506,16 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb)
case ID_MA: case ID_TE: case ID_IP: case ID_IM:
case ID_SO: case ID_KE: case ID_WO: case ID_AC:
case ID_NLA: case ID_TXT: case ID_GR:
- if(idlevel==0) idlevel= idcode;
- else if(idlevel!=idcode) idlevel= -1;
+ if(*idlevel==0) *idlevel= idcode;
+ else if(*idlevel!=idcode) *idlevel= -1;
break;
}
}
}
- if((tselem->flag & TSE_CLOSED)==0) set_operation_types(soops, &te->subtree);
+ if((tselem->flag & TSE_CLOSED)==0) {
+ set_operation_types(soops, &te->subtree,
+ scenelevel, objectlevel, idlevel, datalevel);
+ }
}
}
@@ -2501,7 +2652,7 @@ static void object_delete_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem
if(G.obedit==base->object) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
if(base==BASACT) {
- G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT);
+ G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT);
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
}
@@ -2520,6 +2671,30 @@ static void id_local_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tse
}
}
+static void group_linkobs2scene_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+ Group *group= (Group *)tselem->id;
+ GroupObject *gob;
+ Base *base;
+
+ for(gob=group->gobject.first; gob; gob=gob->next) {
+ base= object_in_scene(gob->ob, G.scene);
+ if (base) {
+ base->object->flag |= SELECT;
+ base->flag |= SELECT;
+ } else {
+ /* link to scene */
+ base= MEM_callocN( sizeof(Base), "add_base");
+ BLI_addhead(&G.scene->base, base);
+ base->lay= (1<<20)-1; /*G.vd->lay;*/ /* would be nice to use the 3d layer but the include's not here */
+ gob->ob->flag |= SELECT;
+ base->flag = gob->ob->flag;
+ base->object= gob->ob;
+ id_lib_extern((ID *)gob->ob); /* incase these are from a linked group */
+ }
+ }
+}
+
static void outliner_do_object_operation(SpaceOops *soops, ListBase *lb,
void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *))
{
@@ -2635,18 +2810,16 @@ void outliner_del(ScrArea *sa)
void outliner_operation_menu(ScrArea *sa)
{
SpaceOops *soops= sa->spacedata.first;
+ int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
- // bad globals
- scenelevel= objectlevel= idlevel= datalevel=0;
-
- set_operation_types(soops, &soops->tree);
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
if(scenelevel) {
if(objectlevel || datalevel || idlevel) error("Mixed selection");
//else pupmenu("Scene Operations%t|Delete");
}
else if(objectlevel) {
- short event= pupmenu("Select%x1|Deselect%x2|Delete%x4|Make Local%x5");
+ short event= pupmenu("Select%x1|Deselect%x2|Delete%x4|Toggle Visible%x6|Toggle Selectable%x7|Toggle Renderable%x8"); /* make local: does not work... it doesn't set lib_extern flags... so data gets lost */
if(event>0) {
char *str="";
@@ -2666,11 +2839,22 @@ void outliner_operation_menu(ScrArea *sa)
DAG_scene_sort(G.scene);
str= "Delete Objects";
}
- else if(event==5) {
+ else if(event==5) { /* disabled, see above (ton) */
outliner_do_object_operation(soops, &soops->tree, id_local_cb);
str= "Localized Objects";
}
-
+ else if(event==6) {
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_visibility_cb);
+ str= "Toggle Visibility";
+ }
+ else if(event==7) {
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_selectability_cb);
+ str= "Toggle Selectability";
+ }
+ else if(event==8) {
+ outliner_do_object_operation(soops, &soops->tree, object_toggle_renderability_cb);
+ str= "Toggle Renderability";
+ }
countall();
BIF_undo_push(str);
@@ -2680,7 +2864,12 @@ void outliner_operation_menu(ScrArea *sa)
else if(idlevel) {
if(idlevel==-1 || datalevel) error("Mixed selection");
else {
- short event= pupmenu("Unlink %x1|Make Local %x2");
+ short event;
+ if (idlevel==ID_GR)
+ event = pupmenu("Unlink %x1|Make Local %x2|Link Group Objects to Scene%x3");
+ else
+ event = pupmenu("Unlink %x1|Make Local %x2");
+
if(event==1) {
switch(idlevel) {
@@ -2708,6 +2897,10 @@ void outliner_operation_menu(ScrArea *sa)
BIF_undo_push("Localized Data");
allqueue(REDRAWALL, 0);
}
+ else if(event==3 && idlevel==ID_GR) {
+ outliner_do_libdata_operation(soops, &soops->tree, group_linkobs2scene_cb);
+ BIF_undo_push("Link Group Objects to Scene");
+ }
}
}
else if(datalevel) {
@@ -2820,6 +3013,8 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen
BIF_icon_draw(x, y, ICON_LAMP_DEHLT); break;
case TSE_LINKED_MAT:
BIF_icon_draw(x, y, ICON_MATERIAL_DEHLT); break;
+ case TSE_POSEGRP_BASE:
+ BIF_icon_draw(x, y, ICON_VERTEXSEL); break;
#ifdef WITH_VERSE
case ID_VS:
@@ -3174,7 +3369,7 @@ static void outliner_draw_selection(SpaceOops *soops, ListBase *lb, int *starty)
/* selection status */
if(tselem->flag & TSE_SELECTED) {
- glRecti(0, *starty+1, (int)soops->v2d.mask.xmax, *starty+OL_H-1);
+ glRecti(0, *starty+1, (int)soops->v2d.cur.xmax, *starty+OL_H-1);
}
*starty-= OL_H;
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(soops, &te->subtree, starty);
@@ -3225,7 +3420,7 @@ static void outliner_back(SpaceOops *soops)
ystart= OL_H*(ystart/(OL_H));
while(ystart > soops->v2d.cur.ymin) {
- glRecti(0, ystart, (int)soops->v2d.mask.xmax, ystart+OL_H);
+ glRecti(0, ystart, (int)soops->v2d.cur.xmax, ystart+OL_H);
ystart-= 2*OL_H;
}
}
@@ -3236,35 +3431,35 @@ static void outliner_draw_restrictcols(SpaceOops *soops)
/* background underneath */
BIF_ThemeColor(TH_BACK);
- glRecti((int)soops->v2d.mask.xmax-(OL_TOGW+SCROLLB), soops->v2d.cur.ymin, (int)soops->v2d.mask.xmax, soops->v2d.tot.ymax);
+ glRecti((int)soops->v2d.cur.xmax-OL_TOGW, soops->v2d.cur.ymin, (int)soops->v2d.cur.xmax, soops->v2d.cur.ymax);
BIF_ThemeColorShade(TH_BACK, 6);
ystart= soops->v2d.tot.ymax;
ystart= OL_H*(ystart/(OL_H));
while(ystart > soops->v2d.cur.ymin) {
- glRecti((int)soops->v2d.mask.xmax-(OL_TOGW+SCROLLB), ystart, (int)soops->v2d.mask.xmax, ystart+OL_H);
+ glRecti((int)soops->v2d.cur.xmax-OL_TOGW, ystart, (int)soops->v2d.cur.xmax, ystart+OL_H);
ystart-= 2*OL_H;
}
BIF_ThemeColorShadeAlpha(TH_BACK, -15, -200);
/* view */
- fdrawline(soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB),
- soops->v2d.tot.ymax,
- soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB),
+ fdrawline(soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX,
+ soops->v2d.cur.ymax,
+ soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX,
soops->v2d.cur.ymin);
/* render */
- fdrawline(soops->v2d.mask.xmax-(OL_TOG_RESTRICT_SELECTX+SCROLLB),
- soops->v2d.tot.ymax,
- soops->v2d.mask.xmax-(OL_TOG_RESTRICT_SELECTX+SCROLLB),
+ fdrawline(soops->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX,
+ soops->v2d.cur.ymax,
+ soops->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX,
soops->v2d.cur.ymin);
/* render */
- fdrawline(soops->v2d.mask.xmax-(OL_TOG_RESTRICT_RENDERX+SCROLLB),
- soops->v2d.tot.ymax,
- soops->v2d.mask.xmax-(OL_TOG_RESTRICT_RENDERX+SCROLLB),
+ fdrawline(soops->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX,
+ soops->v2d.cur.ymax,
+ soops->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX,
soops->v2d.cur.ymin);
}
@@ -3341,7 +3536,7 @@ static void namebutton_cb(void *tep, void *oldnamep)
if (te->idcode == ID_LI) {
char expanded[FILE_MAXDIR + FILE_MAXFILE];
BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE);
-
+ BLI_convertstringcode(expanded, G.sce, G.scene->r.cfra);
if (!BLI_exists(expanded)) {
error("This path does not exist, correct this before saving");
}
@@ -3409,6 +3604,15 @@ static void namebutton_cb(void *tep, void *oldnamep)
allqueue(REDRAWVIEW3D, 1);
allqueue(REDRAWBUTSEDIT, 0);
break;
+ case TSE_POSEGRP:
+ {
+ Object *ob= (Object *)tselem->id; // id = object
+ bActionGroup *grp= te->directdata;
+
+ BLI_uniquename(&ob->pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ break;
case TSE_R_LAYER:
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWBUTSSCENE, 0);
@@ -3419,12 +3623,76 @@ static void namebutton_cb(void *tep, void *oldnamep)
scrarea_queue_redraw(curarea);
}
+static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBase *lb)
+{
+ uiBut *bt;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+ Object *ob;
+
+ for(te= lb->first; te; te= te->next) {
+ tselem= TREESTORE(te);
+ if(te->ys >= soops->v2d.cur.ymin && te->ys <= soops->v2d.cur.ymax) {
+ /* objects have toggle-able restriction flags */
+ if(tselem->type==0 && te->idcode==ID_OB) {
+ ob = (Object *)tselem->id;
+
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+ bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, REDRAWALL, ICON_RESTRICT_VIEW_OFF,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ uiButSetFunc(bt, restrictbutton_view_cb, ob, NULL);
+ uiButSetFlag(bt, UI_NO_HILITE);
+
+ bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_SELECT, REDRAWALL, ICON_RESTRICT_SELECT_OFF,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ uiButSetFunc(bt, restrictbutton_sel_cb, ob, NULL);
+ uiButSetFlag(bt, UI_NO_HILITE);
+
+ bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_RENDER, REDRAWALL, ICON_RESTRICT_RENDER_OFF,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow renderability");
+ uiButSetFunc(bt, restrictbutton_rend_cb, NULL, NULL);
+ uiButSetFlag(bt, UI_NO_HILITE);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ /* scene render layers and passes have toggle-able flags too! */
+ else if(tselem->type==TSE_R_LAYER) {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ else if(tselem->type==TSE_R_PASS) {
+ int *layflag= te->directdata;
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ /* NOTE: tselem->nr is short! */
+ bt= uiDefIconButBitI(block, ICONTOG, tselem->nr, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass");
+ uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
+
+ layflag++; /* is lay_xor */
+ if(ELEM6(tselem->nr, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_RADIO))
+ bt= uiDefIconButBitI(block, TOG, tselem->nr, REDRAWBUTSSCENE, (*layflag & tselem->nr)?ICON_DOT:ICON_BLANK1,
+ (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ }
+
+ if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, soops, &te->subtree);
+ }
+}
+
static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
{
uiBut *bt;
TreeElement *te;
TreeStoreElem *tselem;
- Object *ob;
int dx, len;
for(te= lb->first; te; te= te->next) {
@@ -3451,59 +3719,6 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
/* otherwise keeps open on ESC */
tselem->flag &= ~TSE_TEXTBUT;
}
-
- if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
-
- /* objects have toggle-able restriction flags */
- if(tselem->type==0 && te->idcode==ID_OB) {
- ob = (Object *)tselem->id;
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, REDRAWALL, ICON_RESTRICT_VIEW_OFF,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB), te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
- uiButSetFunc(bt, restrictbutton_view_cb, ob, NULL);
- uiButSetFlag(bt, UI_NO_HILITE);
-
- bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_SELECT, REDRAWALL, ICON_RESTRICT_SELECT_OFF,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_SELECTX+SCROLLB), te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
- uiButSetFunc(bt, restrictbutton_sel_cb, ob, NULL);
- uiButSetFlag(bt, UI_NO_HILITE);
-
- bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_RENDER, REDRAWALL, ICON_RESTRICT_RENDER_OFF,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_RENDERX+SCROLLB), te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow renderability");
- uiButSetFunc(bt, restrictbutton_rend_cb, NULL, NULL);
- uiButSetFlag(bt, UI_NO_HILITE);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- /* scene render layers and passes have toggle-able flags too! */
- else if(tselem->type==TSE_R_LAYER) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB), te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
- uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else if(tselem->type==TSE_R_PASS) {
- int *layflag= te->directdata;
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- /* NOTE: tselem->nr is short! */
- bt= uiDefIconButBitI(block, ICONTOG, tselem->nr, REDRAWBUTSSCENE, ICON_CHECKBOX_HLT-1,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_VIEWX+SCROLLB), te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass");
- uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
-
- layflag++; /* is lay_xor */
- if(ELEM6(tselem->nr, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_RADIO))
- bt= uiDefIconButBitI(block, TOG, tselem->nr, REDRAWBUTSSCENE, (*layflag & tselem->nr)?ICON_DOT:ICON_BLANK1,
- (int)soops->v2d.mask.xmax-(OL_TOG_RESTRICT_SELECTX+SCROLLB), te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
- uiButSetFunc(bt, restrictbutton_r_lay_cb, NULL, NULL);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- }
}
if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(block, soops, &te->subtree);
@@ -3513,11 +3728,18 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb)
void draw_outliner(ScrArea *sa, SpaceOops *soops)
{
uiBlock *block;
- int sizey;
+ int sizey, sizex;
short ofsx, ofsy;
- calc_scrollrcts(sa, G.v2d, sa->winx, sa->winy);
-
+ /* version patch for old outliners here - do_versions patch doesn't work */
+ if (G.v2d->scroll != L_SCROLL+B_SCROLLO) {
+ init_v2d_oops(curarea, soops);
+ test_view2d(G.v2d, curarea->winx, curarea->winy);
+ calc_scrollrcts(sa, G.v2d, sa->winx, sa->winy);
+ }
+ else
+ calc_scrollrcts(sa, G.v2d, sa->winx, sa->winy);
+
if(sa->winx>SCROLLB+10 && sa->winy>SCROLLH+10) {
if(G.v2d->scroll) {
ofsx= sa->winrct.xmin; /* because mywin */
@@ -3528,12 +3750,21 @@ void draw_outliner(ScrArea *sa, SpaceOops *soops)
}
outliner_build_tree(soops); // always
- sizey= 0;
+ sizey = sizex = 0;
outliner_height(soops, &soops->tree, &sizey);
+ outliner_width(soops, &soops->tree, &sizex);
- /* we init all tot rect vars, only really needed on window size change tho */
+ /* we init all tot rect vars, only really needed on window size change though */
G.v2d->tot.xmin= 0.0;
G.v2d->tot.xmax= (G.v2d->mask.xmax-G.v2d->mask.xmin);
+ if(soops->flag & SO_HIDE_RESTRICTCOLS) {
+ if(G.v2d->tot.xmax <= sizex)
+ G.v2d->tot.xmax= 2*sizex;
+ }
+ else {
+ if(G.v2d->tot.xmax-OL_TOGW <= sizex)
+ G.v2d->tot.xmax= 2*sizex;
+ }
G.v2d->tot.ymax= 0.0;
G.v2d->tot.ymin= -sizey*OL_H;
test_view2d(G.v2d, sa->winx, sa->winy);
@@ -3546,20 +3777,26 @@ void draw_outliner(ScrArea *sa, SpaceOops *soops)
myortho2(G.v2d->cur.xmin-0.375, G.v2d->cur.xmax-0.375, G.v2d->cur.ymin-0.375, G.v2d->cur.ymax-0.375);
- /* draw outliner stuff */
+ /* draw outliner stuff (background and hierachy lines) */
outliner_back(soops);
outliner_draw_tree(soops);
- if (!(soops->flag & SO_HIDE_RESTRICTCOLS))
- outliner_draw_restrictcols(soops);
/* restore viewport */
mywinset(sa->win);
- /* ortho corrected */
- myortho2(G.v2d->cur.xmin-SCROLLB-0.375, G.v2d->cur.xmax-0.375, G.v2d->cur.ymin-0.375, G.v2d->cur.ymax-0.375);
+ /* ortho corrected - 'pixel space' */
+ myortho2(G.v2d->cur.xmin-SCROLLB-0.375, G.v2d->cur.xmax-0.375, G.v2d->cur.ymin-SCROLLH-0.375, G.v2d->cur.ymax-0.375);
+ /* draw icons and names */
block= uiNewBlock(&sa->uiblocks, "outliner buttons", UI_EMBOSS, UI_HELV, sa->win);
outliner_buttons(block, soops, &soops->tree);
+
+ /* draw restriction columns */
+ if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
+ outliner_draw_restrictcols(soops);
+ outliner_draw_restrictbuts(block, soops, &soops->tree);
+ }
+
uiDrawBlock(block);
/* clear flag that allows quick redraws */
diff --git a/source/blender/src/parametrizer.c b/source/blender/src/parametrizer.c
index d70d25ecd31..c97056956d8 100644
--- a/source/blender/src/parametrizer.c
+++ b/source/blender/src/parametrizer.c
@@ -2213,7 +2213,7 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
nlBegin(NL_MATRIX);
for (i = 0; i < nvar; i++)
- nlRightHandSideAdd(i, sys->bInterior[i]);
+ nlRightHandSideAdd(0, i, sys->bInterior[i]);
for (f=chart->faces; f; f=f->nextlink) {
float wi1, wi2, wi3, b, si, beta[3], j2[3][3], W[3][3];
@@ -2259,8 +2259,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
sys->J2dt[e2->u.id][0] = j2[1][0] = p_abf_compute_sin_product(sys, v1, e2->u.id)*wi2;
sys->J2dt[e3->u.id][0] = j2[2][0] = p_abf_compute_sin_product(sys, v1, e3->u.id)*wi3;
- nlRightHandSideAdd(v1->u.id, j2[0][0]*beta[0]);
- nlRightHandSideAdd(ninterior + v1->u.id, j2[1][0]*beta[1] + j2[2][0]*beta[2]);
+ nlRightHandSideAdd(0, v1->u.id, j2[0][0]*beta[0]);
+ nlRightHandSideAdd(0, ninterior + v1->u.id, j2[1][0]*beta[1] + j2[2][0]*beta[2]);
row1[0] = j2[0][0]*W[0][0];
row2[0] = j2[0][0]*W[1][0];
@@ -2279,8 +2279,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
sys->J2dt[e2->u.id][1] = j2[1][1] = 1.0*wi2;
sys->J2dt[e3->u.id][1] = j2[2][1] = p_abf_compute_sin_product(sys, v2, e3->u.id)*wi3;
- nlRightHandSideAdd(v2->u.id, j2[1][1]*beta[1]);
- nlRightHandSideAdd(ninterior + v2->u.id, j2[0][1]*beta[0] + j2[2][1]*beta[2]);
+ nlRightHandSideAdd(0, v2->u.id, j2[1][1]*beta[1]);
+ nlRightHandSideAdd(0, ninterior + v2->u.id, j2[0][1]*beta[0] + j2[2][1]*beta[2]);
row1[1] = j2[1][1]*W[0][1];
row2[1] = j2[1][1]*W[1][1];
@@ -2299,8 +2299,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
sys->J2dt[e2->u.id][2] = j2[1][2] = p_abf_compute_sin_product(sys, v3, e2->u.id)*wi2;
sys->J2dt[e3->u.id][2] = j2[2][2] = 1.0*wi3;
- nlRightHandSideAdd(v3->u.id, j2[2][2]*beta[2]);
- nlRightHandSideAdd(ninterior + v3->u.id, j2[0][2]*beta[0] + j2[1][2]*beta[1]);
+ nlRightHandSideAdd(0, v3->u.id, j2[2][2]*beta[2]);
+ nlRightHandSideAdd(0, ninterior + v3->u.id, j2[0][2]*beta[0] + j2[1][2]*beta[1]);
row1[2] = j2[2][2]*W[0][2];
row2[2] = j2[2][2]*W[1][2];
@@ -2357,24 +2357,24 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
pre[0] = pre[1] = pre[2] = 0.0;
if (v1->flag & PVERT_INTERIOR) {
- float x = nlGetVariable(v1->u.id);
- float x2 = nlGetVariable(ninterior + v1->u.id);
+ float x = nlGetVariable(0, v1->u.id);
+ float x2 = nlGetVariable(0, ninterior + v1->u.id);
pre[0] += sys->J2dt[e1->u.id][0]*x;
pre[1] += sys->J2dt[e2->u.id][0]*x2;
pre[2] += sys->J2dt[e3->u.id][0]*x2;
}
if (v2->flag & PVERT_INTERIOR) {
- float x = nlGetVariable(v2->u.id);
- float x2 = nlGetVariable(ninterior + v2->u.id);
+ float x = nlGetVariable(0, v2->u.id);
+ float x2 = nlGetVariable(0, ninterior + v2->u.id);
pre[0] += sys->J2dt[e1->u.id][1]*x2;
pre[1] += sys->J2dt[e2->u.id][1]*x;
pre[2] += sys->J2dt[e3->u.id][1]*x2;
}
if (v3->flag & PVERT_INTERIOR) {
- float x = nlGetVariable(v3->u.id);
- float x2 = nlGetVariable(ninterior + v3->u.id);
+ float x = nlGetVariable(0, v3->u.id);
+ float x2 = nlGetVariable(0, ninterior + v3->u.id);
pre[0] += sys->J2dt[e1->u.id][2]*x2;
pre[1] += sys->J2dt[e2->u.id][2]*x2;
pre[2] += sys->J2dt[e3->u.id][2]*x;
@@ -2405,8 +2405,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
}
for (i = 0; i < ninterior; i++) {
- sys->lambdaPlanar[i] += nlGetVariable(i);
- sys->lambdaLength[i] += nlGetVariable(ninterior + i);
+ sys->lambdaPlanar[i] += nlGetVariable(0, i);
+ sys->lambdaLength[i] += nlGetVariable(0, ninterior + i);
}
}
@@ -2738,8 +2738,8 @@ static void p_chart_lscm_load_solution(PChart *chart)
PVert *v;
for (v=chart->verts; v; v=v->nextlink) {
- v->uv[0] = nlGetVariable(2*v->u.id);
- v->uv[1] = nlGetVariable(2*v->u.id + 1);
+ v->uv[0] = nlGetVariable(0, 2*v->u.id);
+ v->uv[1] = nlGetVariable(0, 2*v->u.id + 1);
}
}
@@ -2771,8 +2771,6 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
#endif
if (abf) {
- PBool p_chart_abf_solve(PChart *chart);
-
if (!p_chart_abf_solve(chart))
param_warning("ABF solving failed: falling back to LSCM.\n");
}
@@ -2798,6 +2796,7 @@ static void p_chart_lscm_begin(PChart *chart, PBool live, PBool abf)
nlNewContext();
nlSolverParameteri(NL_NB_VARIABLES, 2*chart->nverts);
+ nlSolverParameteri(NL_NB_ROWS, 2*chart->nfaces);
nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
chart->u.lscm.context = nlGetCurrent();
@@ -2809,6 +2808,7 @@ static PBool p_chart_lscm_solve(PChart *chart)
PVert *v, *pin1 = chart->u.lscm.pin1, *pin2 = chart->u.lscm.pin2;
PFace *f;
float *alpha = chart->u.lscm.abf_alpha;
+ int row;
nlMakeCurrent(chart->u.lscm.context);
@@ -2828,10 +2828,10 @@ static PBool p_chart_lscm_solve(PChart *chart)
nlLockVariable(2*pin2->u.id);
nlLockVariable(2*pin2->u.id + 1);
- nlSetVariable(2*pin1->u.id, pin1->uv[0]);
- nlSetVariable(2*pin1->u.id + 1, pin1->uv[1]);
- nlSetVariable(2*pin2->u.id, pin2->uv[0]);
- nlSetVariable(2*pin2->u.id + 1, pin2->uv[1]);
+ nlSetVariable(0, 2*pin1->u.id, pin1->uv[0]);
+ nlSetVariable(0, 2*pin1->u.id + 1, pin1->uv[1]);
+ nlSetVariable(0, 2*pin2->u.id, pin2->uv[0]);
+ nlSetVariable(0, 2*pin2->u.id + 1, pin2->uv[1]);
}
else {
/* set and lock the pins */
@@ -2840,8 +2840,8 @@ static PBool p_chart_lscm_solve(PChart *chart)
nlLockVariable(2*v->u.id);
nlLockVariable(2*v->u.id + 1);
- nlSetVariable(2*v->u.id, v->uv[0]);
- nlSetVariable(2*v->u.id + 1, v->uv[1]);
+ nlSetVariable(0, 2*v->u.id, v->uv[0]);
+ nlSetVariable(0, 2*v->u.id + 1, v->uv[1]);
}
}
}
@@ -2850,6 +2850,7 @@ static PBool p_chart_lscm_solve(PChart *chart)
nlBegin(NL_MATRIX);
+ row = 0;
for (f=chart->faces; f; f=f->nextlink) {
PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
@@ -2872,9 +2873,6 @@ static PBool p_chart_lscm_solve(PChart *chart)
sinmax = MAX3(sina1, sina2, sina3);
/* shift vertices to find most stable order */
- #define SHIFT3(type, a, b, c) \
- { type tmp; tmp = a; a = c; c = b; b = tmp; }
-
if (sina3 != sinmax) {
SHIFT3(PVert*, v1, v2, v3);
SHIFT3(float, a1, a2, a3);
@@ -2892,6 +2890,7 @@ static PBool p_chart_lscm_solve(PChart *chart)
cosine = cos(a1)*ratio;
sine = sina1*ratio;
+#if 0
nlBegin(NL_ROW);
nlCoefficient(2*v1->u.id, cosine - 1.0);
nlCoefficient(2*v1->u.id+1, -sine);
@@ -2907,6 +2906,21 @@ static PBool p_chart_lscm_solve(PChart *chart)
nlCoefficient(2*v2->u.id+1, -cosine);
nlCoefficient(2*v3->u.id+1, 1.0);
nlEnd(NL_ROW);
+#else
+ nlMatrixAdd(row, 2*v1->u.id, cosine - 1.0);
+ nlMatrixAdd(row, 2*v1->u.id+1, -sine);
+ nlMatrixAdd(row, 2*v2->u.id, -cosine);
+ nlMatrixAdd(row, 2*v2->u.id+1, sine);
+ nlMatrixAdd(row, 2*v3->u.id, 1.0);
+ row++;
+
+ nlMatrixAdd(row, 2*v1->u.id, sine);
+ nlMatrixAdd(row, 2*v1->u.id+1, cosine - 1.0);
+ nlMatrixAdd(row, 2*v2->u.id, -sine);
+ nlMatrixAdd(row, 2*v2->u.id+1, -cosine);
+ nlMatrixAdd(row, 2*v3->u.id+1, 1.0);
+ row++;
+#endif
}
nlEnd(NL_MATRIX);
@@ -3932,7 +3946,7 @@ void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl)
p_chart_boundaries(chart, &nboundaries, &outer);
- if (nboundaries == 0) {
+ if (!impl && nboundaries == 0) {
p_chart_delete(chart);
continue;
}
@@ -4101,7 +4115,6 @@ void param_pack(ParamHandle *handle)
PHandle *phandle = (PHandle*)handle;
-
if (phandle->ncharts == 0)
return;
@@ -4111,7 +4124,6 @@ void param_pack(ParamHandle *handle)
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
-
if (chart->flag & PCHART_NOPACK) {
unpacked++;
continue;
@@ -4150,6 +4162,64 @@ void param_pack(ParamHandle *handle)
MEM_freeN(boxarray);
}
+
+void param_average(ParamHandle *handle)
+{
+ PChart *chart;
+ int i;
+ float tot_uvarea = 0.0f, tot_facearea = 0.0f;
+ float tot_fac, fac;
+ float minv[2], maxv[2], trans[2];
+ PHandle *phandle = (PHandle*)handle;
+
+ if (phandle->ncharts == 0)
+ return;
+
+ for (i = 0; i < phandle->ncharts; i++) {
+ PFace *f;
+ chart = phandle->charts[i];
+
+ chart->u.pack.area = 0.0f; /* 3d area */
+ chart->u.pack.rescale = 0.0f; /* UV area, abusing rescale for tmp storage, oh well :/ */
+
+ for (f=chart->faces; f; f=f->nextlink) {
+ chart->u.pack.area += p_face_area(f);
+ chart->u.pack.rescale += fabs(p_face_uv_area_signed(f));
+ }
+
+ tot_facearea += chart->u.pack.area;
+ tot_uvarea += chart->u.pack.rescale;
+ }
+
+ if (tot_facearea == tot_uvarea || tot_facearea==0.0f || tot_uvarea==0.0f) {
+ /* nothing to do */
+ return;
+ }
+
+ tot_fac = tot_facearea/tot_uvarea;
+
+ for (i = 0; i < phandle->ncharts; i++) {
+ chart = phandle->charts[i];
+ if (chart->u.pack.area != 0.0f && chart->u.pack.rescale != 0.0f) {
+ fac = chart->u.pack.area / chart->u.pack.rescale;
+
+ /* Get the island center */
+ p_chart_uv_bbox(chart, minv, maxv);
+ trans[0] = (minv[0] + maxv[0]) /-2.0f;
+ trans[1] = (minv[1] + maxv[1]) /-2.0f;
+
+ /* Move center to 0,0 */
+ p_chart_uv_translate(chart, trans);
+ p_chart_uv_scale(chart, sqrt(fac / tot_fac));
+
+ /* Move to original center */
+ trans[0] = -trans[0];
+ trans[1] = -trans[1];
+ p_chart_uv_translate(chart, trans);
+ }
+ }
+}
+
void param_flush(ParamHandle *handle)
{
PHandle *phandle = (PHandle*)handle;
diff --git a/source/blender/src/parametrizer.h b/source/blender/src/parametrizer.h
index fcda5fc6164..a192be05b0e 100644
--- a/source/blender/src/parametrizer.h
+++ b/source/blender/src/parametrizer.h
@@ -71,6 +71,10 @@ void param_smooth_area(ParamHandle *handle);
void param_pack(ParamHandle *handle);
+/* Average area for all charts */
+
+void param_average(ParamHandle *handle);
+
/* Flushing */
void param_flush(ParamHandle *handle);
diff --git a/source/blender/src/playanim.c b/source/blender/src/playanim.c
index 3092cf8d4f2..1c3e1d66148 100644
--- a/source/blender/src/playanim.c
+++ b/source/blender/src/playanim.c
@@ -201,18 +201,18 @@ static void toscreen(Pict *picture, struct ImBuf *ibuf)
pupdate_time();
- if(picture && (qualN & LMOUSE)) {
+ if(picture && (qualN & (SHIFT|LMOUSE))) {
char str[256];
cpack(-1);
glRasterPos2f(0.02f, 0.03f);
- sprintf(str, "%s", picture->name);
+ sprintf(str, "%s | %.2f frames/s\n", picture->name, 1.0 / swaptime);
BMF_DrawString(G.fonts, str);
}
window_swap_buffers(g_window);
}
-static void build_pict_list(char * first)
+static void build_pict_list(char * first, int totframes)
{
int size,pic,file;
char *mem, name[256];
@@ -261,7 +261,8 @@ static void build_pict_list(char * first)
O_DIRECT is a Silicon Graphics extension and is only supported on
local EFS and XFS file systems.
*/
- while(IMB_ispic(name)){
+
+ while(IMB_ispic(name) && totframes){
file = open(name, O_BINARY|O_RDONLY, 0);
if (file < 0) return;
picture = (struct pict*)MEM_callocN(sizeof(struct pict), "picture");
@@ -271,6 +272,13 @@ static void build_pict_list(char * first)
return;
}
size = BLI_filesize(file);
+
+ if (size < 1) {
+ close(file);
+ MEM_freeN(picture);
+ return;
+ }
+
picture->size = size;
picture->IB_flags = IB_rect;
@@ -320,6 +328,7 @@ static void build_pict_list(char * first)
break;
}
}
+ totframes--;
}
}
return;
@@ -337,8 +346,10 @@ void playanim(int argc, char **argv)
int sizex, sizey, ofsx, ofsy, i;
/* This was done to disambiguate the name for use under c++. */
struct anim * anim = 0;
- int start_x= 0, start_y= 0;
-
+ int start_x= 0, start_y= 0;
+ int sfra= -1;
+ int efra= -1;
+
while (argc > 1) {
if (argv[1][0] == '-'){
switch(argv[1][1]) {
@@ -355,6 +366,32 @@ void playanim(int argc, char **argv)
printf("too few arguments for -p (need 2): skipping\n");
}
break;
+ case 'f':
+ if (argc>3) {
+ double fps = atof(argv[2]);
+ double fps_base= atof(argv[3]);
+ if (fps == 0) {
+ fps = 1;
+ printf("invalid fps,"
+ "forcing 1\n");
+ }
+ swaptime = fps_base / fps;
+ argc-= 2;
+ argv+= 2;
+ } else {
+ printf("too few arguments for -f (need 2): skipping\n");
+ }
+ break;
+ case 's':
+ sfra= MIN2(MAXFRAME, MAX2(1, atoi(argv[2]) ));
+ argc--;
+ argv++;
+ break;
+ case 'e':
+ efra= MIN2(MAXFRAME, MAX2(1, atoi(argv[2]) ));
+ argc--;
+ argv++;
+ break;
default:
printf("unknown option '%c': skipping\n", argv[1][1]);
break;
@@ -439,11 +476,17 @@ void playanim(int argc, char **argv)
window_swap_buffers(g_window);
- build_pict_list(name);
+ if (sfra == -1 || efra == -1) {
+ /* one of the frames was invalid, just use all images */
+ sfra = 1;
+ efra = MAXFRAME;
+ }
+
+ build_pict_list(name, (efra - sfra) + 1);
for (i = 2; i < argc; i++){
strcpy(name, argv[i]);
- build_pict_list(name);
+ build_pict_list(name, (efra - sfra) + 1);
}
IMB_freeImBuf(ibuf);
@@ -650,7 +693,10 @@ void playanim(int argc, char **argv)
swaptime = 1.0 / 30.0;
break;
case PAD4:
- swaptime = 1.0 / 25.0;
+ if (qualN & SHIFT)
+ swaptime = 1.0 / 24.0;
+ else
+ swaptime = 1.0 / 25.0;
break;
case PAD5:
swaptime = 1.0 / 20.0;
diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c
new file mode 100644
index 00000000000..14b3286c03b
--- /dev/null
+++ b/source/blender/src/poselib.c
@@ -0,0 +1,1333 @@
+/**
+ * $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
+ * 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>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
+
+#include "DNA_listBase.h"
+#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"
+#include "DNA_userdef_types.h"
+
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "BKE_depsgraph.h"
+#include "BKE_ipo.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+//#include "BIF_keyframing.h"
+#include "BSE_editipo.h"
+
+#include "BDR_drawaction.h"
+#include "BSE_time.h"
+
+#include "BIF_poselib.h"
+#include "BIF_interface.h"
+#include "BIF_editaction.h"
+#include "BIF_space.h"
+#include "BIF_screen.h"
+#include "BIF_toets.h"
+#include "BIF_toolbox.h"
+
+
+#include "blendef.h"
+
+#include "PIL_time.h" /* sleep */
+#include "mydevice.h"
+
+/* ************************************************************* */
+/* == POSE-LIBRARY TOOL FOR BLENDER ==
+ *
+ * Overview:
+ * This tool allows animators to store a set of frequently used poses to dump into
+ * the active action to help in "budget" productions to quickly block out new actions.
+ * It acts as a kind of "glorified clipboard for poses", allowing for naming of poses.
+ *
+ * Features:
+ * - PoseLibs are simply normal Actions
+ * - Each "pose" is simply a set of keyframes that occur on a particular frame
+ * -> a set of TimeMarkers that belong to each Action, help 'label' where a 'pose' can be
+ * found in the Action
+ * - The Scrollwheel or PageUp/Down buttons when used in a special mode or after pressing/holding
+ * [a modifier] key, cycles through the poses available for the active pose's poselib, allowing the
+ * animator to preview what action best suits that pose
+ */
+/* ************************************************************* */
+
+/* gets list of poses in poselib as a string usable for pupmenu() */
+char *poselib_build_poses_menu (bAction *act, char title[])
+{
+ DynStr *pupds= BLI_dynstr_new();
+ TimeMarker *marker;
+ char *str;
+ char buf[64];
+ int i;
+
+ /* add title first */
+ sprintf(buf, "%s%%t|", title);
+ BLI_dynstr_append(pupds, buf);
+
+ /* loop through markers, adding them */
+ for (marker=act->markers.first, i=1; marker; marker=marker->next, i++) {
+ BLI_dynstr_append(pupds, marker->name);
+
+ sprintf(buf, "%%x%d", i);
+ BLI_dynstr_append(pupds, buf);
+
+ if (marker->next)
+ BLI_dynstr_append(pupds, "|");
+ }
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
+/* gets the first available frame in poselib to store a pose on
+ * - frames start from 1, and a pose should occur on every frame... 0 is error!
+ */
+int poselib_get_free_index (bAction *act)
+{
+ TimeMarker *marker;
+ int low=0, high=0;
+
+ /* sanity checks */
+ if (ELEM(NULL, act, act->markers.first)) return 1;
+
+ /* loop over poses finding various values (poses are not stored in chronological order) */
+ for (marker= act->markers.first; marker; marker= marker->next) {
+ /* only increase low if value is 1 greater than low, to find "gaps" where
+ * poses were removed from the poselib
+ */
+ if (marker->frame == (low + 1))
+ low++;
+
+ /* value replaces high if it is the highest value encountered yet */
+ if (marker->frame > high)
+ high= marker->frame;
+ }
+
+ /* - if low is not equal to high, then low+1 is a gap
+ * - if low is equal to high, then high+1 is the next index (add at end)
+ */
+ if (low < high)
+ return (low + 1);
+ else
+ return (high + 1);
+}
+
+/* returns the active pose for a poselib */
+TimeMarker *poselib_get_active_pose (bAction *act)
+{
+ if ((act) && (act->active_marker))
+ return BLI_findlink(&act->markers, act->active_marker-1);
+ else
+ return NULL;
+}
+
+/* ************************************************************* */
+
+/* Initialise a new poselib (whether it is needed or not) */
+bAction *poselib_init_new (Object *ob)
+{
+ /* sanity checks - only for armatures */
+ if (ELEM(NULL, ob, ob->pose))
+ return NULL;
+
+ /* init object's poselib action (unlink old one if there) */
+ if (ob->poselib)
+ ob->poselib->id.us--;
+ ob->poselib= add_empty_action("PoseLib");
+
+ return ob->poselib;
+}
+
+/* Initialise a new poselib (checks if that needs to happen) */
+bAction *poselib_validate (Object *ob)
+{
+ if (ELEM(NULL, ob, ob->pose))
+ return NULL;
+ else if (ob->poselib == NULL)
+ return poselib_init_new(ob);
+ else
+ return ob->poselib;
+}
+
+
+/* This tool automagically generates/validates poselib data so that it corresponds to the data
+ * in the action. This is for use in making existing actions usable as poselibs.
+ */
+void poselib_validate_act (bAction *act)
+{
+ ListBase keys = {NULL, NULL};
+ ActKeyColumn *ak;
+ TimeMarker *marker, *markern;
+
+ /* validate action and poselib */
+ if (act == NULL) {
+ error("No Action to validate");
+ return;
+ }
+
+ /* determine which frames have keys */
+ action_to_keylist(act, &keys, NULL, NULL);
+
+ /* for each key, make sure there is a correspnding pose */
+ for (ak= keys.first; ak; ak= ak->next) {
+ /* check if any pose matches this */
+ for (marker= act->markers.first; marker; marker= marker->next) {
+ if (IS_EQ(marker->frame, ak->cfra)) {
+ marker->flag = -1;
+ break;
+ }
+ }
+
+ /* add new if none found */
+ if (marker == NULL) {
+ char name[64];
+
+ /* add pose to poselib */
+ marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
+
+ strcpy(name, "Pose");
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+
+ marker->frame= (int)ak->cfra;
+ marker->flag= -1;
+
+ BLI_addtail(&act->markers, marker);
+ }
+ }
+
+ /* remove all untagged poses (unused), and remove all tags */
+ for (marker= act->markers.first; marker; marker= markern) {
+ markern= marker->next;
+
+ if (marker->flag != -1)
+ BLI_freelinkN(&act->markers, marker);
+ else
+ marker->flag = 0;
+ }
+
+ /* free temp memory */
+ BLI_freelistN(&keys);
+
+ BIF_undo_push("PoseLib Validate Action");
+}
+
+/* ************************************************************* */
+
+/* This function adds an ipo-curve of the right type where it's needed */
+static IpoCurve *poselib_verify_icu (Ipo *ipo, int adrcode)
+{
+ IpoCurve *icu;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ if (icu->adrcode==adrcode) break;
+ }
+ if (icu==NULL) {
+ icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
+
+ icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
+ if (ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE; /* first one added active */
+
+ icu->blocktype= ID_PO;
+ icu->adrcode= adrcode;
+
+ set_icu_vars(icu);
+
+ BLI_addtail(&ipo->curve, icu);
+ }
+
+ return icu;
+}
+
+/* This tool adds the current pose to the poselib
+ * Note: Standard insertkey cannot be used for this due to its limitations
+ */
+void poselib_add_current_pose (Object *ob, int val)
+{
+ bArmature *arm= (ob) ? ob->data : NULL;
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bPoseChannel *pchan;
+ TimeMarker *marker;
+ bAction *act;
+ bActionChannel *achan;
+ IpoCurve *icu;
+ int frame;
+ char name[64];
+
+ /* sanity check */
+ if (ELEM3(NULL, ob, arm, pose))
+ return;
+
+ /* mode - add new or replace existing */
+ if (val == 0) {
+ if ((ob->poselib) && (ob->poselib->markers.first)) {
+ val= pupmenu("PoseLib Add Current Pose%t|Add New%x1|Replace Existing%x2");
+ if (val <= 0) return;
+ }
+ else
+ val= 1;
+ }
+
+ if ((ob->poselib) && (val == 2)) {
+ char *menustr;
+
+ /* get poselib */
+ act= ob->poselib;
+
+ /* get the pose to replace */
+ menustr= poselib_build_poses_menu(act, "Replace PoseLib Pose");
+ val= pupmenu_col(menustr, 20);
+ if (menustr) MEM_freeN(menustr);
+
+ if (val <= 0) return;
+ marker= BLI_findlink(&act->markers, val-1);
+ if (marker == NULL) return;
+
+ /* get the frame from the poselib */
+ frame= marker->frame;
+ }
+ else {
+ /* get name of pose */
+ sprintf(name, "Pose");
+ if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
+ return;
+
+ /* get/initialise poselib */
+ act= poselib_validate(ob);
+
+ /* get frame */
+ frame= poselib_get_free_index(act);
+
+ /* add pose to poselib - replaces any existing pose there */
+ for (marker= act->markers.first; marker; marker= marker->next) {
+ if (marker->frame == frame) {
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ break;
+ }
+ }
+ if (marker == NULL) {
+ marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
+
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ marker->frame= frame;
+
+ BLI_addtail(&act->markers, marker);
+ }
+
+ /* validate name */
+ BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
+ }
+
+ /* loop through selected posechannels, keying their pose to the action */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ /* check if available */
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
+ /* make action-channel if needed */
+ achan= verify_action_channel(act, pchan->name);
+
+ /* make ipo if needed... */
+ if (achan->ipo == NULL)
+ achan->ipo= add_ipo(achan->name, ID_PO);
+
+ /* add missing ipo-curves and insert keys */
+ #define INSERT_KEY_ICU(adrcode, data) {\
+ icu= poselib_verify_icu(achan->ipo, adrcode); \
+ insert_vert_icu(icu, frame, data, 1); \
+ }
+
+ INSERT_KEY_ICU(AC_LOC_X, pchan->loc[0])
+ INSERT_KEY_ICU(AC_LOC_Y, pchan->loc[1])
+ INSERT_KEY_ICU(AC_LOC_Z, pchan->loc[2])
+ INSERT_KEY_ICU(AC_SIZE_X, pchan->size[0])
+ INSERT_KEY_ICU(AC_SIZE_Y, pchan->size[1])
+ INSERT_KEY_ICU(AC_SIZE_Z, pchan->size[2])
+ INSERT_KEY_ICU(AC_QUAT_W, pchan->quat[0])
+ INSERT_KEY_ICU(AC_QUAT_X, pchan->quat[1])
+ INSERT_KEY_ICU(AC_QUAT_Y, pchan->quat[2])
+ INSERT_KEY_ICU(AC_QUAT_Z, pchan->quat[3])
+ }
+ }
+ }
+
+ /* store new 'active' pose number */
+ act->active_marker= BLI_countlist(&act->markers);
+
+ BIF_undo_push("PoseLib Add Pose");
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+
+
+/* This tool removes the pose that the user selected from the poselib (or the provided pose) */
+void poselib_remove_pose (Object *ob, TimeMarker *marker)
+{
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bAction *act= (ob) ? ob->poselib : NULL;
+ bActionChannel *achan;
+ char *menustr;
+ int val;
+
+ /* check if valid poselib */
+ if (ELEM(NULL, ob, pose)) {
+ error("PoseLib is only for Armatures in PoseMode");
+ return;
+ }
+ if (act == NULL) {
+ error("Object doesn't have PoseLib data");
+ return;
+ }
+
+ /* get index (and pointer) of pose to remove */
+ if (marker == NULL) {
+ menustr= poselib_build_poses_menu(act, "Remove PoseLib Pose");
+ val= pupmenu_col(menustr, 20);
+ if (menustr) MEM_freeN(menustr);
+
+ if (val <= 0) return;
+ marker= BLI_findlink(&act->markers, val-1);
+ if (marker == NULL) return;
+ }
+ else {
+ /* only continue if pose belongs to poselib */
+ if (BLI_findindex(&act->markers, marker) == -1)
+ return;
+ }
+
+ /* remove relevant keyframes */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ Ipo *ipo= achan->ipo;
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int i;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* check if remove... */
+ if (IS_EQ(bezt->vec[1][0], marker->frame)) {
+ delete_icu_key(icu, i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ /* remove poselib from list */
+ BLI_freelinkN(&act->markers, marker);
+
+ /* fix active pose number */
+ act->active_marker= 0;
+
+ /* undo + redraw */
+ BIF_undo_push("PoseLib Remove Pose");
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+}
+
+
+/* This tool renames the pose that the user selected from the poselib */
+void poselib_rename_pose (Object *ob)
+{
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bAction *act= (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+ char *menustr, name[64];
+ int val;
+
+ /* check if valid poselib */
+ if (ELEM(NULL, ob, pose)) {
+ error("PoseLib is only for Armatures in PoseMode");
+ return;
+ }
+ if (act == NULL) {
+ error("Object doesn't have a valid PoseLib");
+ return;
+ }
+
+ /* get index of pose to remove */
+ menustr= poselib_build_poses_menu(act, "Rename PoseLib Pose");
+ val= pupmenu_col(menustr, 20);
+ if (menustr) MEM_freeN(menustr);
+
+ if (val <= 0) return;
+ marker= BLI_findlink(&act->markers, val-1);
+ if (marker == NULL) return;
+
+ /* get name of pose */
+ sprintf(name, marker->name);
+ if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
+ return;
+
+ /* copy name and validate it */
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
+
+ /* undo and update */
+ BIF_undo_push("PoseLib Rename Pose");
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+}
+
+
+/* ************************************************************* */
+
+/* Simple struct for storing settings/data for use during PoseLib preview */
+typedef struct tPoseLib_PreviewData {
+ ListBase backups; /* tPoseLib_Backup structs for restoring poses */
+ ListBase searchp; /* LinkData structs storing list of poses which match the current search-string */
+
+ Object *ob; /* object to work on */
+ bArmature *arm; /* object's armature data */
+ bPose *pose; /* object's pose */
+ bAction *act; /* poselib to use */
+ TimeMarker *marker; /* 'active' pose */
+
+ short state; /* state of main loop */
+ short redraw; /* redraw/update settings during main loop */
+ short flag; /* flags for various settings */
+
+ int selcount; /* number of selected elements to work on */
+ int totcount; /* total number of elements to work on */
+
+ char headerstr[200]; /* Info-text to print in header */
+
+ char searchstr[64]; /* (Part of) Name to search for to filter poses that get shown */
+ char searchold[64]; /* Previously set searchstr (from last loop run), so that we can detected when to rebuild searchp */
+ short search_cursor; /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
+} tPoseLib_PreviewData;
+
+/* defines for tPoseLib_PreviewData->state values */
+enum {
+ PL_PREVIEW_ERROR = -1,
+ PL_PREVIEW_RUNNING,
+ PL_PREVIEW_CONFIRM,
+ PL_PREVIEW_CANCEL,
+ PL_PREVIEW_RUNONCE
+};
+
+/* defines for tPoseLib_PreviewData->redraw values */
+enum {
+ PL_PREVIEW_NOREDRAW = 0,
+ PL_PREVIEW_REDRAWALL,
+ PL_PREVIEW_REDRAWHEADER,
+};
+
+/* defines for tPoseLib_PreviewData->flag values */
+enum {
+ PL_PREVIEW_FIRSTTIME = (1<<0),
+ PL_PREVIEW_SHOWORIGINAL = (1<<1)
+};
+
+/* ---------------------------- */
+
+/* simple struct for storing backup info */
+typedef struct tPoseLib_Backup {
+ struct tPoseLib_Backup *next, *prev;
+
+ bPoseChannel *pchan;
+ bPoseChannel olddata;
+} tPoseLib_Backup;
+
+/* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
+static void poselib_backup_posecopy (tPoseLib_PreviewData *pld)
+{
+ bActionChannel *achan;
+ bPoseChannel *pchan;
+
+ /* for each posechannel that has an actionchannel in */
+ for (achan= pld->act->chanbase.first; achan; achan= achan->next) {
+ /* try to find posechannel */
+ pchan= get_pose_channel(pld->pose, achan->name);
+
+ /* backup data if available */
+ if (pchan) {
+ tPoseLib_Backup *plb;
+
+ /* store backup */
+ plb= MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
+
+ plb->pchan= pchan;
+ memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
+
+ BLI_addtail(&pld->backups, plb);
+
+ /* mark as being affected */
+ if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
+ pld->selcount++;
+ pld->totcount++;
+ }
+ }
+}
+
+/* Restores original pose - doesn't do constraints currently */
+static void poselib_backup_restore (tPoseLib_PreviewData *pld)
+{
+ tPoseLib_Backup *plb;
+
+ for (plb= pld->backups.first; plb; plb= plb->next) {
+ memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
+ }
+}
+
+/* ---------------------------- */
+
+/* Applies the appropriate stored pose from the pose-library to the current pose
+ * - assumes that a valid object, with a poselib has been supplied
+ * - gets the string to print in the header
+ * - this code is based on the code for extract_pose_from_action in blenkernel/action.c
+ */
+static void poselib_apply_pose (tPoseLib_PreviewData *pld)
+{
+ bPose *pose= pld->pose;
+ bPoseChannel *pchan;
+ bAction *act= pld->act;
+ bActionChannel *achan;
+ IpoCurve *icu;
+ int frame;
+
+ if (pld->marker)
+ frame= pld->marker->frame;
+ else
+ return;
+
+ /* start applying - only those channels which have a key at this point in time! */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ short found= 0;
+
+ /* apply this achan? */
+ if (achan->ipo) {
+ /* find a keyframe at this frame - users may not have defined the pose on every channel, so this is necessary */
+ // TODO: this may be bad for user-defined poses...
+ for (icu= achan->ipo->curve.first; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int i;
+
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (IN_RANGE(bezt->vec[1][0], (frame-0.5f), (frame+0.5f))) {
+ found= 1;
+ break;
+ }
+ }
+
+ if (found) break;
+ }
+
+ /* apply pose - only if posechannel selected? */
+ if (found) {
+ pchan= get_pose_channel(pose, achan->name);
+
+ if (pchan) {
+ short ok= 0;
+
+ if (pchan->bone) {
+ if ( (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) &&
+ (pchan->bone->flag & BONE_HIDDEN_P)==0 )
+ ok = 1;
+ else if (pld->selcount == 0)
+ ok= 1;
+ }
+ else if (pld->selcount == 0)
+ ok= 1;
+
+ if (ok) {
+ /* Evaluates and sets the internal ipo values */
+ calc_ipo(achan->ipo, frame);
+ /* This call also sets the pchan flags */
+ execute_action_ipo(achan, pchan);
+ }
+ }
+ }
+ }
+
+ /* tag achan as having been used or not... */
+ if (found)
+ achan->flag |= ACHAN_SELECTED;
+ else
+ achan->flag &= ~ACHAN_SELECTED;
+ }
+}
+
+/* Auto-keys/tags bones affected by the pose used from the poselib */
+static void poselib_keytag_pose (tPoseLib_PreviewData *pld)
+{
+ bPose *pose= pld->pose;
+ bPoseChannel *pchan;
+ bAction *act= pld->act;
+ bActionChannel *achan;
+
+ /* start tagging/keying */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ /* only for selected action channels */
+ if (achan->flag & ACHAN_SELECTED) {
+ pchan= get_pose_channel(pose, achan->name);
+
+ if (pchan) {
+ // TODO: use a standard autokeying function in future (to allow autokeying-editkeys to work)
+ if (IS_AUTOKEY_MODE(NORMAL)) {
+ ID *id= &pld->ob->id;
+
+ /* 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);
+ }
+
+ /* clear any unkeyed tags */
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ /* add unkeyed tags */
+ if (pchan->bone)
+ pchan->bone->flag |= BONE_UNKEYED;
+ }
+ }
+ }
+ }
+}
+
+/* ---------------------------- */
+
+/* This helper function is called during poselib_preview_poses to find the
+ * pose to preview next (after a change event)
+ */
+static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step)
+{
+ if ((pld->marker) && (step)) {
+ /* search-string dictates a special approach */
+ if (pld->searchstr[0]) {
+ TimeMarker *marker;
+ LinkData *ld, *ldn, *ldc;
+
+ /* free and rebuild if needed (i.e. if search-str changed) */
+ if (strcmp(pld->searchstr, pld->searchold)) {
+ /* free list of temporary search matches */
+ BLI_freelistN(&pld->searchp);
+
+ /* generate a new list of search matches */
+ for (marker= pld->act->markers.first; marker; marker= marker->next) {
+ /* does the name partially match?
+ * - don't worry about case, to make it easier for users to quickly input a name (or
+ * part of one), which is the whole point of this feature
+ */
+ if (BLI_strcasestr(marker->name, pld->searchstr)) {
+ /* make link-data to store reference to it */
+ ld= MEM_callocN(sizeof(LinkData), "PoseMatch");
+ ld->data= marker;
+ BLI_addtail(&pld->searchp, ld);
+ }
+ }
+
+ /* set current marker to NULL (so that we start from first) */
+ pld->marker= NULL;
+ }
+
+ /* check if any matches */
+ if (pld->searchp.first == NULL) {
+ pld->marker= NULL;
+ return;
+ }
+
+ /* find first match */
+ for (ldc= pld->searchp.first; ldc; ldc= ldc->next) {
+ if (ldc->data == pld->marker)
+ break;
+ }
+ if (ldc == NULL)
+ ldc= pld->searchp.first;
+
+ /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate
+ * until step == 0. At this point, marker should be the correct marker.
+ */
+ if (step > 0) {
+ for (ld=ldc; ld && step; ld=ldn, step--)
+ ldn= (ld->next) ? ld->next : pld->searchp.first;
+ }
+ else {
+ for (ld=ldc; ld && step; ld=ldn, step++)
+ ldn= (ld->prev) ? ld->prev : pld->searchp.last;
+ }
+
+ /* set marker */
+ if (ld)
+ pld->marker= ld->data;
+ }
+ else {
+ TimeMarker *marker, *next;
+
+ /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate
+ * until step == 0. At this point, marker should be the correct marker.
+ */
+ if (step > 0) {
+ for (marker=pld->marker; marker && step; marker=next, step--)
+ next= (marker->next) ? marker->next : pld->act->markers.first;
+ }
+ else {
+ for (marker=pld->marker; marker && step; marker=next, step++)
+ next= (marker->prev) ? marker->prev : pld->act->markers.last;
+ }
+
+ /* it should be fairly impossible for marker to be NULL */
+ if (marker)
+ pld->marker= marker;
+ }
+ }
+}
+
+/* specially handle events for searching */
+static void poselib_preview_handle_search (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
+{
+ if (ascii) {
+ /* character to add to the string */
+ short index= pld->search_cursor;
+ short len= (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
+ short i;
+
+ if (len) {
+ for (i = len; i > index; i--)
+ pld->searchstr[i]= pld->searchstr[i-1];
+ }
+ else
+ pld->searchstr[1]= 0;
+
+ pld->searchstr[index]= ascii;
+ pld->search_cursor++;
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ else {
+ /* some form of string manipulation */
+ switch (event) {
+ case BACKSPACEKEY:
+ if (pld->searchstr[0] && pld->search_cursor) {
+ short len= strlen(pld->searchstr);
+ short index= pld->search_cursor;
+ short i;
+
+ for (i = index; i <= len; i++)
+ pld->searchstr[i-1] = pld->searchstr[i];
+
+ pld->search_cursor--;
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ case DELKEY:
+ if (pld->searchstr[0] && pld->searchstr[1]) {
+ short len= strlen(pld->searchstr);
+ short index= pld->search_cursor;
+ int i;
+
+ if (index < len) {
+ for (i = index; i < len; i++)
+ pld->searchstr[i] = pld->searchstr[i+1];
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ }
+ break;
+ }
+ }
+}
+
+/* handle events for poselib_preview_poses */
+static void poselib_preview_handle_event (tPoseLib_PreviewData *pld, unsigned short event, char ascii)
+{
+ /* backup stuff that needs to occur before every operation
+ * - make a copy of searchstr, so that we know if cache needs to be rebuilt
+ */
+ strcpy(pld->searchold, pld->searchstr);
+
+ /* if we're currently showing the original pose, only certain events are handled */
+ if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
+ switch (event) {
+ /* exit - cancel */
+ case ESCKEY:
+ case RIGHTMOUSE:
+ pld->state= PL_PREVIEW_CANCEL;
+ break;
+
+ /* exit - confirm */
+ case LEFTMOUSE:
+ case RETKEY:
+ case PADENTER:
+ case SPACEKEY:
+ pld->state= PL_PREVIEW_CONFIRM;
+ break;
+
+ /* view manipulation */
+ case MIDDLEMOUSE:
+ // there's a little bug here that causes the normal header to get drawn while view is manipulated
+ handle_view_middlemouse();
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ break;
+
+ /* view manipulation, or searching */
+ case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
+ case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
+ case PADPLUSKEY: case PADMINUS:
+ persptoetsen(event);
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ break;
+
+ case TABKEY:
+ pld->flag &= ~PL_PREVIEW_SHOWORIGINAL;
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+ }
+
+ /* EXITS HERE... */
+ return;
+ }
+
+ /* NORMAL EVENT HANDLING... */
+ /* searching takes priority over normal activity */
+ switch (event) {
+ /* exit - cancel */
+ case ESCKEY:
+ case RIGHTMOUSE:
+ pld->state= PL_PREVIEW_CANCEL;
+ break;
+
+ /* exit - confirm */
+ case LEFTMOUSE:
+ case RETKEY:
+ case PADENTER:
+ case SPACEKEY:
+ pld->state= PL_PREVIEW_CONFIRM;
+ break;
+
+ /* toggle between original pose and poselib pose*/
+ case TABKEY:
+ pld->flag |= PL_PREVIEW_SHOWORIGINAL;
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to previous pose (cyclic) */
+ case PAGEUPKEY:
+ case WHEELUPMOUSE:
+ poselib_preview_get_next(pld, -1);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to next pose (cyclic) */
+ case PAGEDOWNKEY:
+ case WHEELDOWNMOUSE:
+ poselib_preview_get_next(pld, 1);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* jump 5 poses (cyclic, back) */
+ case DOWNARROWKEY:
+ poselib_preview_get_next(pld, -5);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* jump 5 poses (cyclic, forward) */
+ case UPARROWKEY:
+ poselib_preview_get_next(pld, 5);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to next pose or searching cursor control */
+ case RIGHTARROWKEY:
+ if (pld->searchstr[0]) {
+ /* move text-cursor to the right */
+ if (pld->search_cursor < strlen(pld->searchstr))
+ pld->search_cursor++;
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to next pose (cyclic) */
+ poselib_preview_get_next(pld, 1);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to next pose or searching cursor control */
+ case LEFTARROWKEY:
+ if (pld->searchstr[0]) {
+ /* move text-cursor to the left */
+ if (pld->search_cursor)
+ pld->search_cursor--;
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to previous pose (cyclic) */
+ poselib_preview_get_next(pld, -1);
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to first pose or start of searching string */
+ case HOMEKEY:
+ if (pld->searchstr[0]) {
+ pld->search_cursor= 0;
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to first pose */
+ pld->marker= pld->act->markers.first;
+ pld->act->active_marker= 1;
+
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to last pose or start of searching string */
+ case ENDKEY:
+ if (pld->searchstr[0]) {
+ pld->search_cursor= strlen(pld->searchstr);
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to last pose */
+ pld->marker= pld->act->markers.last;
+ pld->act->active_marker= BLI_countlist(&pld->act->markers);
+
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* view manipulation */
+ case MIDDLEMOUSE:
+ // there's a little bug here that causes the normal header to get drawn while view is manipulated
+ handle_view_middlemouse();
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ break;
+
+ /* view manipulation, or searching */
+ case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
+ case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
+ case PADPLUSKEY: case PADMINUS:
+ if (pld->searchstr[0]) {
+ poselib_preview_handle_search(pld, event, ascii);
+ }
+ else {
+ persptoetsen(event);
+ pld->redraw= PL_PREVIEW_REDRAWHEADER;
+ }
+ break;
+
+ /* otherwise, assume that searching might be able to handle it */
+ default:
+ poselib_preview_handle_search(pld, event, ascii);
+ break;
+ }
+}
+
+/* ---------------------------- */
+
+/* Init PoseLib Previewing data */
+static void poselib_preview_init_data (tPoseLib_PreviewData *pld, Object *ob, short apply_active)
+{
+ /* clear pld first as it resides on the stack */
+ memset(pld, 0, sizeof(tPoseLib_PreviewData));
+
+ /* get basic data */
+ pld->ob= ob;
+ pld->arm= (ob) ? (ob->data) : NULL;
+ pld->pose= (ob) ? (ob->pose) : NULL;
+ pld->act= (ob) ? (ob->poselib) : NULL;
+ pld->marker= poselib_get_active_pose(pld->act);
+
+ /* check if valid poselib */
+ if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) {
+ error("PoseLib is only for Armatures in PoseMode");
+ pld->state= PL_PREVIEW_ERROR;
+ return;
+ }
+ if (pld->act == NULL) {
+ error("Object doesn't have a valid PoseLib");
+ pld->state= PL_PREVIEW_ERROR;
+ return;
+ }
+ if (pld->marker == NULL) {
+ if ((apply_active==0) || (pld->act->markers.first)) {
+ /* just use first one then... */
+ pld->marker= pld->act->markers.first;
+ printf("PoseLib had no active pose\n");
+ }
+ else {
+ error("PoseLib has no poses to preview/apply");
+ pld->state= PL_PREVIEW_ERROR;
+ return;
+ }
+ }
+
+ /* make backups for restoring pose */
+ poselib_backup_posecopy(pld);
+
+ /* set flags for running */
+ pld->state= (apply_active) ? PL_PREVIEW_RUNONCE : PL_PREVIEW_RUNNING;
+ pld->redraw= PL_PREVIEW_REDRAWALL;
+ pld->flag= PL_PREVIEW_FIRSTTIME;
+
+ /* set depsgraph flags */
+ /* make sure the lock is set OK, unlock can be accidentally saved? */
+ pld->pose->flag |= POSE_LOCKED;
+ pld->pose->flag &= ~POSE_DO_UNLOCK;
+
+ /* clear strings + search */
+ strcpy(pld->headerstr, "");
+ strcpy(pld->searchstr, "");
+ strcpy(pld->searchold, "");
+ pld->search_cursor= 0;
+}
+
+/* After previewing poses */
+static void poselib_preview_cleanup (tPoseLib_PreviewData *pld)
+{
+ Base *base;
+ Object *ob= pld->ob;
+ bPose *pose= pld->pose;
+ bArmature *arm= pld->arm;
+ bAction *act= pld->act;
+ TimeMarker *marker= pld->marker;
+
+ /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
+ pose->flag |= POSE_DO_UNLOCK;
+
+ /* clear pose if cancelled */
+ if (pld->state == PL_PREVIEW_CANCEL) {
+ poselib_backup_restore(pld);
+
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ if ((arm->flag & ARM_DELAYDEFORM)==0) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */
+
+ /* bah, softbody exception... recalcdata doesnt reset */
+ for (base= FIRSTBASE; base; base= base->next) {
+ if (base->object->recalc & OB_RECALC_DATA)
+ if (modifiers_isSoftbodyEnabled(base->object)) {
+ base->object->softflag |= OB_SB_REDO;
+ }
+ }
+ }
+ else
+ where_is_pose(ob);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ else if (pld->state == PL_PREVIEW_CONFIRM) {
+ /* tag poses as appropriate */
+ poselib_keytag_pose(pld);
+
+ /* change active pose setting */
+ act->active_marker= BLI_findindex(&act->markers, marker) + 1;
+ action_set_activemarker(act, marker, 0);
+
+ /* Update event for pose and deformation children */
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+ /* updates */
+ if (IS_AUTOKEY_MODE(NORMAL)) {
+ remake_action_ipos(ob->action);
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ }
+ else {
+ /* need to trick depgraph, action is not allowed to execute on pose */
+ where_is_pose(ob);
+ ob->recalc= 0;
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+
+ /* free memory used for backups */
+ BLI_freelistN(&pld->backups);
+ BLI_freelistN(&pld->searchp);
+}
+
+
+
+/* This tool allows users to preview the pose from the pose-lib using the mouse-scrollwheel/pageupdown
+ * It is also used to apply the active poselib pose only
+ */
+void poselib_preview_poses (Object *ob, short apply_active)
+{
+ tPoseLib_PreviewData pld;
+ Base *base;
+
+ unsigned short event;
+ short val=0;
+ char ascii;
+
+ /* check if valid poselib */
+ poselib_preview_init_data(&pld, ob, apply_active);
+ if (pld.state == PL_PREVIEW_ERROR)
+ return;
+
+ /* start preview loop */
+ while (ELEM(pld.state, PL_PREVIEW_RUNNING, PL_PREVIEW_RUNONCE)) {
+ /* preview a pose */
+ if (pld.redraw) {
+ /* only recalc pose (and its dependencies) if pose has changed */
+ if (pld.redraw == PL_PREVIEW_REDRAWALL) {
+ /* don't clear pose if firsttime */
+ if ((pld.flag & PL_PREVIEW_FIRSTTIME)==0)
+ poselib_backup_restore(&pld);
+ else
+ pld.flag &= ~PL_PREVIEW_FIRSTTIME;
+
+ /* pose should be the right one to draw (unless we're temporarily not showing it) */
+ if ((pld.flag & PL_PREVIEW_SHOWORIGINAL)==0)
+ poselib_apply_pose(&pld);
+
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ if ((pld.arm->flag & ARM_DELAYDEFORM)==0) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* sets recalc flags */
+
+ /* bah, softbody exception... recalcdata doesnt reset */
+ for (base= FIRSTBASE; base; base= base->next) {
+ if (base->object->recalc & OB_RECALC_DATA)
+ if (modifiers_isSoftbodyEnabled(base->object)) {
+ base->object->softflag |= OB_SB_REDO;
+ }
+ }
+ }
+ else
+ where_is_pose(ob);
+ }
+
+ /* do header print - if interactively previewing */
+ if (pld.state == PL_PREVIEW_RUNNING) {
+ if (pld.flag & PL_PREVIEW_SHOWORIGINAL) {
+ sprintf(pld.headerstr, "PoseLib Previewing Pose: [Showing Original Pose] | Use Tab to start previewing poses again");
+ headerprint(pld.headerstr);
+ }
+ else if (pld.searchstr[0]) {
+ char tempstr[65];
+ char markern[64];
+ short index;
+
+ /* get search-string */
+ index= pld.search_cursor;
+
+ memcpy(&tempstr[0], &pld.searchstr[0], index);
+ tempstr[index]= '|';
+ memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+
+ /* get marker name */
+ if (pld.marker)
+ strcpy(markern, pld.marker->name);
+ else
+ strcpy(markern, "No Matches");
+
+ sprintf(pld.headerstr, "PoseLib Previewing Pose: Filter - [%s] | Current Pose - \"%s\" | Use ScrollWheel or PageUp/Down to change", tempstr, markern);
+ headerprint(pld.headerstr);
+ }
+ else {
+ sprintf(pld.headerstr, "PoseLib Previewing Pose: \"%s\" | Use ScrollWheel or PageUp/Down to change", pld.marker->name);
+ headerprint(pld.headerstr);
+ }
+ }
+
+ /* force drawing of view + clear redraw flag */
+ force_draw(0);
+ pld.redraw= PL_PREVIEW_NOREDRAW;
+ }
+
+ /* stop now if only running once */
+ if (pld.state == PL_PREVIEW_RUNONCE) {
+ pld.state = PL_PREVIEW_CONFIRM;
+ break;
+ }
+
+ /* essential for idling subloop */
+ if (qtest() == 0)
+ PIL_sleep_ms(2);
+
+ /* emptying queue and reading events */
+ while ( qtest() ) {
+ event= extern_qread_ext(&val, &ascii);
+
+ /* event processing */
+ if (val) {
+ poselib_preview_handle_event(&pld, event, ascii);
+ }
+ }
+ }
+
+ /* finish up */
+ poselib_preview_cleanup(&pld);
+
+ BIF_undo_push("PoseLib Apply Pose");
+}
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index 0b78601ab9b..0eb4d0bb9a1 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -27,16 +27,19 @@
*/
#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_curve_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -44,6 +47,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -51,12 +55,12 @@
#include "BKE_constraint.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BKE_ipo.h"
#include "BIF_editarmature.h"
#include "BIF_editaction.h"
@@ -66,7 +70,6 @@
#include "BIF_graphics.h"
#include "BIF_interface.h"
#include "BIF_poseobject.h"
-#include "BIF_meshtools.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BIF_screen.h"
@@ -79,6 +82,9 @@
#include "mydevice.h"
#include "blendef.h"
+#include "transform.h"
+
+#include "BIF_transform.h" /* for autokey TFM_TRANSLATION, etc */
void enter_posemode(void)
{
@@ -115,7 +121,7 @@ void enter_posemode(void)
}
if (G.obedit) exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
- G.f &= ~(G_VERTEXPAINT | G_FACESELECT | G_TEXTUREPAINT | G_WEIGHTPAINT);
+ G.f &= ~(G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT);
}
void set_pose_keys (Object *ob)
@@ -162,6 +168,9 @@ bPoseChannel *get_active_posechannel (Object *ob)
bArmature *arm= ob->data;
bPoseChannel *pchan;
+ if ELEM(NULL, ob, ob->pose)
+ return NULL;
+
/* find active */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
@@ -221,7 +230,9 @@ int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
/* ********************************************** */
-/* for the object with pose/action: create path curves for selected bones */
+/* For the object with pose/action: create path curves for selected bones
+ * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
+ */
void pose_calculate_path(Object *ob)
{
bArmature *arm;
@@ -231,7 +242,7 @@ void pose_calculate_path(Object *ob)
int cfra;
int sfra, efra;
- if(ob==NULL || ob->pose==NULL)
+ if (ob==NULL || ob->pose==NULL)
return;
arm= ob->data;
@@ -248,38 +259,50 @@ void pose_calculate_path(Object *ob)
cfra= CFRA;
sfra = arm->pathsf;
efra = arm->pathef;
- if (efra<=sfra) return;
+ if (efra <= sfra) {
+ error("Can't calculate paths when pathlen <= 0");
+ return;
+ }
+
+ waitcursor(1);
+
+ /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
+ if ((ob->recalc & OB_RECALC)==0) {
+ ob->recalc |= OB_RECALC;
+ DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
+ }
+ else
+ DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
- DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
/* malloc the path blocks */
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- if(arm->layer & pchan->bone->layer) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
+ if (arm->layer & pchan->bone->layer) {
pchan->pathlen= efra-sfra+1;
pchan->pathsf= sfra;
pchan->pathef= efra+1;
- if(pchan->path)
+ if (pchan->path)
MEM_freeN(pchan->path);
pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
}
}
}
- for(CFRA=sfra; CFRA<=efra; CFRA++) {
+ for (CFRA=sfra; CFRA<=efra; CFRA++) {
/* do all updates */
- for(base= FIRSTBASE; base; base= base->next) {
- if(base->object->recalc) {
+ for (base= FIRSTBASE; base; base= base->next) {
+ if (base->object->recalc) {
int temp= base->object->recalc;
object_handle_update(base->object);
base->object->recalc= temp;
}
}
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->path) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->path) {
fp= pchan->path+3*(CFRA-sfra);
if (arm->pathflag & ARM_PATH_HEADS) {
@@ -296,25 +319,113 @@ void pose_calculate_path(Object *ob)
}
}
+ waitcursor(0);
+
CFRA= cfra;
allqueue(REDRAWVIEW3D, 0); /* recalc tags are still there */
allqueue(REDRAWBUTSEDIT, 0);
}
+/* For the object with pose/action: update paths for those that have got them
+ * This should selectively update paths that exist...
+ */
+void pose_recalculate_paths(Object *ob)
+{
+ bArmature *arm;
+ bPoseChannel *pchan;
+ Base *base;
+ float *fp;
+ int cfra;
+ int sfra, efra;
+
+ if (ob==NULL || ob->pose==NULL)
+ return;
+ arm= ob->data;
+
+ /* set frame values */
+ cfra = CFRA;
+ sfra = efra = cfra;
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (pchan->path) {
+ /* if the pathsf and pathef aren't initialised, abort! */
+ if (ELEM(0, pchan->pathsf, pchan->pathef))
+ return;
+
+ /* try to increase area to do (only as much as needed) */
+ sfra= MIN2(sfra, pchan->pathsf);
+ efra= MAX2(efra, pchan->pathef);
+ }
+ }
+ }
+ if (efra <= sfra) return;
+
+ waitcursor(1);
+
+ /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
+ if ((ob->recalc & OB_RECALC)==0) {
+ ob->recalc |= OB_RECALC;
+ DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
+ }
+ else
+ DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
+
+ for (CFRA=sfra; CFRA<=efra; CFRA++) {
+ /* do all updates */
+ for (base= FIRSTBASE; base; base= base->next) {
+ if (base->object->recalc) {
+ int temp= base->object->recalc;
+ object_handle_update(base->object);
+ base->object->recalc= temp;
+ }
+ }
+
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
+ if (pchan->path) {
+ /* only update if:
+ * - in range of this pchan's existing path
+ * - ... insert evil filtering/optimising conditions here...
+ */
+ if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
+ fp= pchan->path+3*(CFRA-sfra);
+
+ if (arm->pathflag & ARM_PATH_HEADS) {
+ VECCOPY(fp, pchan->pose_head);
+ }
+ else {
+ VECCOPY(fp, pchan->pose_tail);
+ }
+
+ Mat4MulVecfl(ob->obmat, fp);
+ }
+ }
+ }
+ }
+ }
+
+ waitcursor(0);
+
+ CFRA= cfra;
+ allqueue(REDRAWVIEW3D, 0); /* recalc tags are still there */
+ allqueue(REDRAWBUTSEDIT, 0);
+}
-/* for the object with pose/action: clear all path curves */
+/* for the object with pose/action: clear path curves for selected bones only */
void pose_clear_paths(Object *ob)
{
bPoseChannel *pchan;
- if(ob==NULL || ob->pose==NULL)
+ if (ob==NULL || ob->pose==NULL)
return;
/* free the path blocks */
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->path) {
- MEM_freeN(pchan->path);
- pchan->path= NULL;
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
+ if (pchan->path) {
+ MEM_freeN(pchan->path);
+ pchan->path= NULL;
+ }
}
}
@@ -331,23 +442,30 @@ void pose_select_constraint_target(void)
bConstraint *con;
/* paranoia checks */
- if(!ob && !ob->pose) return;
- if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
+ if (!ob && !ob->pose) return;
+ if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
-
- for(con= pchan->constraints.first; con; con= con->next) {
- char *subtarget;
- Object *target= get_constraint_target(con, &subtarget);
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
- if(ob==target) {
- if(subtarget) {
- bPoseChannel *pchanc= get_pose_channel(ob->pose, subtarget);
- if(pchanc)
- pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ if ((ct->tar == ob) && (ct->subtarget[0])) {
+ bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
+ if(pchanc)
+ pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ }
}
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 1);
}
}
}
@@ -372,7 +490,7 @@ void pose_special_editmenu(void)
if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
- nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear All Paths%x4|Clear User Transform %x5");
+ nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6|%l|AutoName Left-Right%x7|AutoName Front-Back%x8|AutoName Top-Bottom%x9");
if(nr==1) {
pose_select_constraint_target();
}
@@ -390,6 +508,12 @@ void pose_special_editmenu(void)
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
BIF_undo_push("Clear User Transform Pose");
}
+ else if(nr==6) {
+ pose_relax();
+ }
+ else if(ELEM3(nr, 7, 8, 9)) {
+ pose_autoside_names(nr-7);
+ }
}
void pose_add_IK(void)
@@ -682,7 +806,7 @@ void paste_posebuf (int flip)
/* Safely merge all of the channels in this pose into
any existing pose */
- for (chan=g_posebuf->chanbase.first; chan; chan=chan->next){
+ for (chan=g_posebuf->chanbase.first; chan; chan=chan->next) {
if (chan->flag & POSE_KEY) {
BLI_strncpy(name, chan->name, sizeof(name));
if (flip)
@@ -691,7 +815,7 @@ void paste_posebuf (int flip)
/* only copy when channel exists, poses are not meant to add random channels to anymore */
pchan= get_pose_channel(ob->pose, name);
- if(pchan) {
+ if (pchan) {
/* only loc rot size */
/* only copies transform info for the pose */
VECCOPY(pchan->loc, chan->loc);
@@ -699,35 +823,44 @@ void paste_posebuf (int flip)
QUATCOPY(pchan->quat, chan->quat);
pchan->flag= chan->flag;
- if (flip){
+ if (flip) {
pchan->loc[0]*= -1;
-
+
QuatToEul(pchan->quat, eul);
eul[1]*= -1;
eul[2]*= -1;
EulToQuat(eul, pchan->quat);
}
-
- if (G.flags & G_RECORDKEYS){
+
+ if (autokeyframe_cfra_can_key(ob)) {
ID *id= &ob->id;
-
+
/* Set keys on pose */
- if (chan->flag & POSE_ROT){
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ 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);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
+ 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);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+ 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);
}
+
+ /* clear any unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ /* add unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag |= BONE_UNKEYED;
}
}
}
@@ -736,11 +869,11 @@ void paste_posebuf (int flip)
/* Update event for pose and deformation children */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- if (G.flags & G_RECORDKEYS) {
+ if (IS_AUTOKEY_ON) {
remake_action_ipos(ob->action);
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
}
else {
@@ -754,114 +887,344 @@ void paste_posebuf (int flip)
/* ********************************************** */
-struct vgroup_map {
- float head[3], tail[3];
- Bone *bone;
- bDeformGroup *dg, *dgflip;
- Object *meshobj;
-};
+/* context weightpaint and deformer in posemode */
+void pose_adds_vgroups(Object *meshobj, int heatweights)
+{
+ extern VPaint Gwp; /* from vpaint */
+ Object *poseobj= modifiers_isDeformedByArmature(meshobj);
+
+ if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) {
+ error("The active object must have a deforming armature in pose mode");
+ return;
+ }
+
+ add_verts_to_dgroups(meshobj, poseobj, heatweights, (Gwp.flag & VP_MIRROR_X));
-static void pose_adds_vgroups__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
+ if(heatweights)
+ BIF_undo_push("Apply Bone Heat Weights to Vertex Groups");
+ else
+ BIF_undo_push("Apply Bone Envelopes to Vertex Groups");
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+
+ // and all its relations
+ DAG_object_flush_update(G.scene, meshobj, OB_RECALC_DATA);
+}
+
+/* ********************************************** */
+
+/* adds a new pose-group */
+void pose_add_posegroup ()
{
- struct vgroup_map *map= userData;
- float vec[3], fac;
+ Object *ob= OBACT;
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bActionGroup *grp;
- VECCOPY(vec, co);
- Mat4MulVecfl(map->meshobj->obmat, vec);
+ if (ELEM(NULL, ob, ob->pose))
+ return;
+
+ grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
+ strcpy(grp->name, "Group");
+ BLI_addtail(&pose->agroups, grp);
+ BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
+
+ pose->active_group= BLI_countlist(&pose->agroups);
+
+ BIF_undo_push("Add Bone Group");
+
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+/* Remove the active bone-group */
+void pose_remove_posegroup ()
+{
+ Object *ob= OBACT;
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bActionGroup *grp = NULL;
+ bPoseChannel *pchan;
+
+ /* sanity checks */
+ if (ELEM(NULL, ob, pose))
+ return;
+ if (pose->active_group <= 0)
+ return;
+
+ /* get group to remove */
+ grp= BLI_findlink(&pose->agroups, pose->active_group-1);
+ if (grp) {
+ /* firstly, make sure nothing references it */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->agrp_index == pose->active_group)
+ pchan->agrp_index= 0;
+ }
+
+ /* now, remove it from the pose */
+ BLI_freelinkN(&pose->agroups, grp);
+ pose->active_group= 0;
- /* get the distance-factor from the vertex to bone */
- fac= distfactor_to_bone (vec, map->head, map->tail, map->bone->rad_head, map->bone->rad_tail, map->bone->dist);
+ BIF_undo_push("Remove Bone Group");
+ }
- /* add to vgroup. this call also makes me->dverts */
- if(fac!=0.0f)
- add_vert_to_defgroup (map->meshobj, map->dg, index, fac, WEIGHT_REPLACE);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+char *build_posegroups_menustr (bPose *pose, short for_pupmenu)
+{
+ DynStr *pupds= BLI_dynstr_new();
+ bActionGroup *grp;
+ char *str;
+ char buf[16];
+ int i;
+
+ /* add title first (and the "none" entry) */
+ BLI_dynstr_append(pupds, "Bone Group%t|");
+ if (for_pupmenu)
+ BLI_dynstr_append(pupds, "Add New%x0|");
else
- remove_vert_defgroup (map->meshobj, map->dg, index);
+ BLI_dynstr_append(pupds, "BG: [None]%x0|");
- if(map->dgflip) {
- int j= mesh_get_x_mirror_vert(map->meshobj, index);
- if(j>=0) {
- if(fac!=0.0f)
- add_vert_to_defgroup (map->meshobj, map->dgflip, j, fac, WEIGHT_REPLACE);
- else
- remove_vert_defgroup (map->meshobj, map->dgflip, j);
+ /* loop through groups, adding them */
+ for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++) {
+ if (for_pupmenu == 0)
+ BLI_dynstr_append(pupds, "BG: ");
+ BLI_dynstr_append(pupds, grp->name);
+
+ sprintf(buf, "%%x%d", i);
+ BLI_dynstr_append(pupds, buf);
+
+ if (grp->next)
+ BLI_dynstr_append(pupds, "|");
+ }
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
+/* Assign selected pchans to the bone group that the user selects */
+void pose_assign_to_posegroup (short active)
+{
+ Object *ob= OBACT;
+ bArmature *arm= (ob) ? ob->data : NULL;
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bPoseChannel *pchan;
+ char *menustr;
+ int nr;
+ short done= 0;
+
+ /* sanity checks */
+ if (ELEM3(NULL, ob, pose, arm))
+ return;
+
+ /* get group to affect */
+ if ((active==0) || (pose->active_group <= 0)) {
+ menustr= build_posegroups_menustr(pose, 1);
+ nr= pupmenu_col(menustr, 20);
+ MEM_freeN(menustr);
+
+ if (nr < 0)
+ return;
+ else if (nr == 0) {
+ /* add new - note: this does an undo push and sets active group */
+ pose_add_posegroup();
}
+ else
+ pose->active_group= nr;
}
+
+ /* add selected bones to group then */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
+ pchan->agrp_index= pose->active_group;
+ done= 1;
+ }
+ }
+
+ if (done)
+ BIF_undo_push("Add Bones To Group");
+
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
-/* context weightpaint and deformer in posemode */
-void pose_adds_vgroups(Object *meshobj)
+/* Remove selected pchans from their bone groups */
+void pose_remove_from_posegroups ()
{
- extern VPaint Gwp; /* from vpaint */
- struct vgroup_map map;
- DerivedMesh *dm;
- Object *poseobj= modifiers_isDeformedByArmature(meshobj);
- bArmature *arm= poseobj->data;
+ Object *ob= OBACT;
+ bArmature *arm= (ob) ? ob->data : NULL;
+ bPose *pose= (ob) ? ob->pose : NULL;
bPoseChannel *pchan;
- Bone *bone;
- bDeformGroup *dg, *curdef;
+ short done= 0;
- if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) return;
+ /* sanity checks */
+ if (ELEM3(NULL, ob, pose, arm))
+ return;
+
+ /* remove selected bones from their groups */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
+ if (pchan->agrp_index) {
+ pchan->agrp_index= 0;
+ done= 1;
+ }
+ }
+ }
+
+ if (done)
+ BIF_undo_push("Remove Bones From Groups");
+
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+/* Ctrl-G in 3D-View while in PoseMode */
+void pgroup_operation_with_menu (void)
+{
+ Object *ob= OBACT;
+ bArmature *arm= (ob) ? ob->data : NULL;
+ bPose *pose= (ob) ? ob->pose : NULL;
+ bPoseChannel *pchan= NULL;
+ int mode;
- dm = mesh_get_derived_final(meshobj, CD_MASK_BAREMESH);
+ /* sanity checks */
+ if (ELEM3(NULL, ob, pose, arm))
+ return;
- map.meshobj= meshobj;
+ /* check that something is selected */
+ for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
+ if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer))
+ break;
+ }
+ if (pchan == NULL)
+ return;
- for(pchan= poseobj->pose->chanbase.first; pchan; pchan= pchan->next) {
- bone= pchan->bone;
- if(arm->layer & pchan->bone->layer) {
- if(bone->flag & (BONE_SELECTED)) {
-
- /* check if mesh has vgroups */
- dg= get_named_vertexgroup(meshobj, bone->name);
- if(dg==NULL)
- dg= add_defgroup_name(meshobj, bone->name);
-
- /* flipped bone */
- if(Gwp.flag & VP_MIRROR_X) {
- char name[32];
-
- BLI_strncpy(name, dg->name, 32);
- bone_flip_name(name, 0); // 0 = don't strip off number extensions
-
- for (curdef = meshobj->defbase.first; curdef; curdef=curdef->next)
- if (!strcmp(curdef->name, name))
- break;
- map.dgflip= curdef;
- }
- else map.dgflip= NULL;
-
- /* get the root of the bone in global coords */
- VECCOPY(map.head, bone->arm_head);
- Mat4MulVecfl(poseobj->obmat, map.head);
-
- /* get the tip of the bone in global coords */
- VECCOPY(map.tail, bone->arm_tail);
- Mat4MulVecfl(poseobj->obmat, map.tail);
+ /* get mode of action */
+ if (pchan)
+ mode= pupmenu("Bone Groups%t|Add Selected to Active Group%x1|Add Selected to Group%x2|%|Remove Selected From Groups%x3|Remove Active Group%x4");
+ else
+ mode= pupmenu("Bone Groups%t|Add New Group%x5|Remove Active Group%x4");
+
+ /* handle mode */
+ switch (mode) {
+ case 1:
+ pose_assign_to_posegroup(1);
+ break;
+ case 2:
+ pose_assign_to_posegroup(0);
+ break;
+ case 5:
+ pose_add_posegroup();
+ break;
+ case 3:
+ pose_remove_from_posegroups();
+ break;
+ case 4:
+ pose_remove_posegroup();
+ break;
+ }
+}
+
+/* ********************************************** */
+
+static short pose_select_same_group (Object *ob)
+{
+ bPose *pose= (ob)? ob->pose : NULL;
+ bArmature *arm= (ob)? ob->data : NULL;
+ bPoseChannel *pchan, *chan;
+ short changed= 0;
+
+ if (ELEM3(NULL, ob, pose, arm))
+ return 0;
+
+ /* loop in loop... bad and slow! */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
- /* use the optimal vertices instead of mverts */
- map.dg= dg;
- map.bone= bone;
- if(dm->foreachMappedVert)
- dm->foreachMappedVert(dm, pose_adds_vgroups__mapFunc, (void*) &map);
- else {
- Mesh *me= meshobj->data;
- int i;
- for(i=0; i<me->totvert; i++)
- pose_adds_vgroups__mapFunc(&map, i, (me->mvert+i)->co, NULL, NULL);
+ /* only if group matches (and is not selected or current bone) */
+ for (chan= ob->pose->chanbase.first; chan; chan= chan->next) {
+ if (arm->layer & chan->bone->layer) {
+ if (pchan->agrp_index == chan->agrp_index) {
+ chan->bone->flag |= BONE_SELECTED;
+ changed= 1;
+ }
+ }
}
}
}
}
- dm->release(dm);
+ return changed;
+}
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
+static short pose_select_same_layer (Object *ob)
+{
+ bPose *pose= (ob)? ob->pose : NULL;
+ bArmature *arm= (ob)? ob->data : NULL;
+ bPoseChannel *pchan;
+ short layers= 0, changed= 0;
+
+ if (ELEM3(NULL, ob, pose, arm))
+ return 0;
+
+ /* figure out what bones are selected */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+ layers |= pchan->bone->layer;
+ }
+ }
+ }
+ if (layers == 0)
+ return 0;
+
+ /* select bones that are on same layers as layers flag */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (layers & pchan->bone->layer) {
+ pchan->bone->flag |= BONE_SELECTED;
+ changed= 1;
+ }
+ }
+ }
+
+ return changed;
+}
+
+
+void pose_select_grouped (short nr)
+{
+ short changed = 0;
- DAG_object_flush_update(G.scene, meshobj, OB_RECALC_DATA); // and all its relations
+ if (nr == 1) changed= pose_select_same_group(OBACT);
+ else if (nr == 2) changed= pose_select_same_layer(OBACT);
+
+ if (changed) {
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ BIF_undo_push("Select Grouped");
+ }
+}
+/* Shift-G in 3D-View while in PoseMode */
+void pose_select_grouped_menu (void)
+{
+ short nr;
+
+ /* here we go */
+ nr= pupmenu("Select Grouped%t|In Same Group%x1|In Same Layer%x2");
+ pose_select_grouped(nr);
}
/* ********************************************** */
@@ -897,7 +1260,39 @@ void pose_flip_names(void)
allqueue (REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names");
+}
+
+/* context active object */
+void pose_autoside_names(short axis)
+{
+ Object *ob= OBACT;
+ bArmature *arm= ob->data;
+ bPoseChannel *pchan;
+ char newname[32];
+ /* paranoia checks */
+ if (ELEM(NULL, ob, ob->pose)) return;
+ if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
+
+ if (pose_has_protected_selected(ob, 0))
+ return;
+
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if(arm->layer & pchan->bone->layer) {
+ if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+ BLI_strncpy(newname, pchan->name, sizeof(newname));
+ bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
+ armature_bone_rename(ob->data, pchan->name, newname);
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWOOPS, 0);
+ BIF_undo_push("Flip names");
}
/* context active object, or weightpainted object with armature in posemode */
@@ -950,20 +1345,23 @@ void pose_activate_flipped_bone(void)
}
}
-
+/* This function pops up the move-to-layer popup widgets when the user
+ * presses either SHIFT-MKEY or MKEY in PoseMode OR EditMode (for Armatures)
+ */
void pose_movetolayer(void)
{
Object *ob= OBACT;
bArmature *arm;
short lay= 0;
- if(ob==NULL) return;
+ if (ob==NULL) return;
arm= ob->data;
- if(G.qual & LR_SHIFTKEY) {
+ if (G.qual & LR_SHIFTKEY) {
+ /* armature layers */
lay= arm->layer;
- if( movetolayer_short_buts(&lay, "Armature Layers")==0 ) return;
- if(lay==0) return;
+ if ( movetolayer_short_buts(&lay, "Armature Layers")==0 ) return;
+ if (lay==0) return;
arm->layer= lay;
if(ob->pose)
ob->pose->proxy_layer= lay;
@@ -971,35 +1369,256 @@ void pose_movetolayer(void)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWBUTSEDIT, 0);
+ }
+ else if (G.obedit) {
+ /* the check for editbone layer moving needs to occur before posemode one to work */
+ EditBone *ebo;
+ EditBone *flipBone;
+
+ for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
+ if (arm->layer & ebo->layer) {
+ if (ebo->flag & BONE_SELECTED)
+ lay |= ebo->layer;
+ }
+ }
+ if (lay==0) return;
+
+ if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
+ if (lay==0) return;
+ for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
+ if (arm->layer & ebo->layer) {
+ if (ebo->flag & BONE_SELECTED) {
+ ebo->layer= lay;
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ flipBone = armature_bone_get_mirrored(ebo);
+ if (flipBone)
+ flipBone->layer = lay;
+ }
+ }
+ }
+ }
+
+ BIF_undo_push("Move Bone Layer");
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
- else if(ob->flag & OB_POSEMODE) {
+ else if (ob->flag & OB_POSEMODE) {
+ /* pose-channel layers */
bPoseChannel *pchan;
- if(pose_has_protected_selected(ob, 0))
+ if (pose_has_protected_selected(ob, 0))
return;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->bone->flag & BONE_SELECTED)
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & BONE_SELECTED)
lay |= pchan->bone->layer;
}
}
- if(lay==0) return;
+ if (lay==0) return;
- if( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
- if(lay==0) return;
-
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(arm->layer & pchan->bone->layer) {
- if(pchan->bone->flag & BONE_SELECTED)
+ if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
+ if (lay==0) return;
+
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (arm->layer & pchan->bone->layer) {
+ if (pchan->bone->flag & BONE_SELECTED)
pchan->bone->layer= lay;
}
}
- BIF_undo_push("Move Bone layer");
+ BIF_undo_push("Move Bone Layer");
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
}
+
+
+/* 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;
+ }
+}
+
+void pose_relax()
+{
+ 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? */
+ 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;
+ }
+ }
+ }
+ }
+
+ 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_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ BIF_undo_push("Relax Pose");
+}
+
+/* for use in insertkey, ensure rotation goes other way around */
+void pose_flipquats(void)
+{
+ Object *ob = OBACT;
+ bArmature *arm= ob->data;
+ bPoseChannel *pchan;
+
+ if(ob->pose==NULL)
+ return;
+
+ /* find sel bones */
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if(pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
+ /* quaternions have 720 degree range */
+ pchan->quat[0]= -pchan->quat[0];
+ pchan->quat[1]= -pchan->quat[1];
+ pchan->quat[2]= -pchan->quat[2];
+ pchan->quat[3]= -pchan->quat[3];
+ }
+ }
+
+}
+
diff --git a/source/blender/src/preview.blend.c b/source/blender/src/preview.blend.c
index b88d16c5699..1ea7d7531ec 100644
--- a/source/blender/src/preview.blend.c
+++ b/source/blender/src/preview.blend.c
@@ -1,1027 +1,1355 @@
/* DataToC output of file <preview_blend> */
-int datatoc_preview_blend_size= 459544;
+int datatoc_preview_blend_size= 433792;
char datatoc_preview_blend[]= {
- 66, 76, 69, 78, 68, 69, 82, 95, 86, 50, 52, 50, 82, 69, 78, 68, 0, 0, 0, 32,191,255,236,148,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 20,112,114,101,118,105,101,119, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 71, 76, 79, 66, 0, 0, 0, 32,191,255,235,240, 0, 0, 0,139, 0, 0, 0, 1, 32, 32, 32, 52,
- 0, 4, 0, 0, 0,240, 0, 0, 0, 1, 1, 0, 2,236, 30,176, 5, 30,236, 32, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 83, 82,
- 0, 0, 0,120, 2,236, 30,176, 0, 0, 0,134, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 83, 82,115, 99,114,101,101,110, 0, 45, 83, 99,114,105,112,116,105,110,103, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,235, 18,144, 2,236, 32, 16, 2,236, 32, 80, 2,236, 34,208, 2,236, 35, 16, 2,236,136,160, 5, 30,236, 32,
- 0, 0, 4,198, 0, 49, 3, 84, 4,199, 3, 36, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, 2,235, 18,144, 0, 0, 0,135, 0, 0, 0, 1, 2,235,137,224,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, 2,235,137,224, 0, 0, 0,135,
- 0, 0, 0, 1, 2,235, 63,144, 2,235, 18,144, 0, 0, 0, 0, 0, 0, 3, 36, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20,
- 2,235, 63,144, 0, 0, 0,135, 0, 0, 0, 1, 2,228,196,160, 2,235,137,224, 0, 0, 0, 0, 4,199, 3, 36, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 20, 2,228,196,160, 0, 0, 0,135, 0, 0, 0, 1, 2,236, 31, 80, 2,235, 63,144, 0, 0, 0, 0,
- 4,199, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, 2,236, 31, 80, 0, 0, 0,135, 0, 0, 0, 1, 2,236, 31,144,
- 2,228,196,160, 0, 0, 0, 0, 0, 0, 3, 10, 0, 0, 0, 1, 68, 65, 84, 65, 0, 0, 0, 20, 2,236, 31,144, 0, 0, 0,135,
- 0, 0, 0, 1, 2,236, 31,208, 2,236, 31, 80, 0, 0, 0, 0, 4,199, 3, 10, 0, 0, 0, 1, 68, 65, 84, 65, 0, 0, 0, 20,
- 2,236, 31,208, 0, 0, 0,135, 0, 0, 0, 1, 2,236, 32, 16, 2,236, 31,144, 0, 0, 0, 0, 3,208, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 20, 2,236, 32, 16, 0, 0, 0,135, 0, 0, 0, 1, 0, 0, 0, 0, 2,236, 31,208, 0, 0, 0, 0,
- 3,208, 3, 10, 0, 0, 0, 1, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 32, 80, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 32,144,
- 0, 0, 0, 0, 2,235, 63,144, 2,235,137,224, 0, 1, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 32,144,
- 0, 0, 0,136, 0, 0, 0, 1, 2,236, 32,208, 2,236, 32, 80, 2,235,137,224, 2,236, 31, 80, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 32,208, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 33, 16, 2,236, 32,144, 2,235, 63,144,
- 2,236, 31,144, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 33, 16, 0, 0, 0,136, 0, 0, 0, 1,
- 2,236, 33, 80, 2,236, 32,208, 2,236, 31, 80, 2,236, 31,144, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24,
- 2,236, 33, 80, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 33,144, 2,236, 33, 16, 2,228,196,160, 2,236, 31,208, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 33,144, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 33,208, 2,236, 33, 80,
- 2,236, 31,144, 2,236, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 33,208, 0, 0, 0,136,
- 0, 0, 0, 1, 2,236, 34, 16, 2,236, 33,144, 2,236, 31,208, 2,236, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0, 24, 2,236, 34, 16, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 34, 80, 2,236, 33,208, 2,228,196,160, 2,236, 31,144,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 34, 80, 0, 0, 0,136, 0, 0, 0, 1, 2,236, 34,144,
- 2,236, 34, 16, 2,235, 18,144, 2,236, 31, 80, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 34,144,
- 0, 0, 0,136, 0, 0, 0, 1, 2,236, 34,208, 2,236, 34, 80, 2,236, 31, 80, 2,236, 32, 16, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 24, 2,236, 34,208, 0, 0, 0,136, 0, 0, 0, 1, 0, 0, 0, 0, 2,236, 34,144, 2,235, 18,144,
- 2,236, 31,208, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,204, 2,236, 35, 16, 0, 0, 0,138, 0, 0, 0, 1,
- 2,236, 79,160, 0, 0, 0, 0, 2,236, 31, 80, 2,235,137,224, 2,235, 63,144, 2,236, 31,144, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 66, 76, 69, 78, 68, 69, 82, 95,118, 50, 52, 53, 82, 69, 78, 68, 32, 0, 0, 0,160,242, 34, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 20, 0, 0, 0,112,114,101,118,105,101,119, 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,192,241, 34, 0,155, 0, 0, 0, 1, 0, 0, 0, 32, 32, 49, 52, 14, 0, 34, 0,240, 0, 0, 0,
+ 1, 0, 0, 1, 56,106,163, 2,240, 36,130, 2, 0, 0, 0, 0, 64, 0, 0, 0, 83, 82, 0, 0,120, 0, 0, 0, 56,106,163, 2,
+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, 82,115, 99,114,101,101,110,
+ 0, 45, 83, 99,114,105,112,116,105,110,103, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,106,163, 2,
+104, 48,127, 2, 32,109,163, 2,216, 47,127, 2,248, 3,130, 2,160, 78,130, 2,240, 36,130, 2, 0, 0,127, 7, 18, 0,174, 4,
+128, 7,157, 4, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 5, 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,224,106,163, 2,151, 0, 0, 0, 1, 0, 0, 0, 40,107,163, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 40,107,163, 2,151, 0, 0, 0, 1, 0, 0, 0,112,107,163, 2,
+224,106,163, 2, 0, 0, 0, 0, 0, 0,157, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,112,107,163, 2,151, 0, 0, 0,
+ 1, 0, 0, 0,184,107,163, 2, 40,107,163, 2, 0, 0, 0, 0,128, 7,157, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,
+184,107,163, 2,151, 0, 0, 0, 1, 0, 0, 0, 0,108,163, 2,112,107,163, 2, 0, 0, 0, 0,128, 7, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 20, 0, 0, 0, 0,108,163, 2,151, 0, 0, 0, 1, 0, 0, 0, 72,108,163, 2,184,107,163, 2, 0, 0, 0, 0,
+ 0, 0,124, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 72,108,163, 2,151, 0, 0, 0, 1, 0, 0, 0,144,108,163, 2,
+ 0,108,163, 2, 0, 0, 0, 0,128, 7,124, 4, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,144,108,163, 2,151, 0, 0, 0,
+ 1, 0, 0, 0,216,108,163, 2, 72,108,163, 2, 0, 0, 0, 0,252, 5, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,
+216,108,163, 2,151, 0, 0, 0, 1, 0, 0, 0, 32, 48,127, 2,144,108,163, 2, 0, 0, 0, 0,252, 5,124, 4, 0, 0, 0, 0,
+ 68, 65, 84, 65, 20, 0, 0, 0, 32, 48,127, 2,151, 0, 0, 0, 1, 0, 0, 0,104, 48,127, 2,216,108,163, 2, 0, 0, 0, 0,
+104, 3, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0,104, 48,127, 2,151, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 32, 48,127, 2, 0, 0, 0, 0,104, 3,124, 4, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 32,109,163, 2,152, 0, 0, 0,
+ 1, 0, 0, 0,104,109,163, 2, 0, 0, 0, 0, 40,107,163, 2,112,107,163, 2, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0,104,109,163, 2,152, 0, 0, 0, 1, 0, 0, 0,176,109,163, 2, 32,109,163, 2, 40,107,163, 2, 0,108,163, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,176,109,163, 2,152, 0, 0, 0, 1, 0, 0, 0,248,109,163, 2,
+104,109,163, 2,112,107,163, 2, 72,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,248,109,163, 2,
+152, 0, 0, 0, 1, 0, 0, 0, 64,110,163, 2,176,109,163, 2, 0,108,163, 2, 72,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0, 64,110,163, 2,152, 0, 0, 0, 1, 0, 0, 0,136,110,163, 2,248,109,163, 2,184,107,163, 2,
+144,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,136,110,163, 2,152, 0, 0, 0, 1, 0, 0, 0,
+208,110,163, 2, 64,110,163, 2, 72,108,163, 2,216,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,
+208,110,163, 2,152, 0, 0, 0, 1, 0, 0, 0, 24,111,163, 2,136,110,163, 2,144,108,163, 2,216,108,163, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 24,111,163, 2,152, 0, 0, 0, 1, 0, 0, 0, 96,111,163, 2,208,110,163, 2,
+184,107,163, 2, 72,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 96,111,163, 2,152, 0, 0, 0,
+ 1, 0, 0, 0,184, 46,127, 2, 24,111,163, 2,224,106,163, 2, 0,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0,184, 46,127, 2,152, 0, 0, 0, 1, 0, 0, 0, 0, 47,127, 2, 96,111,163, 2, 32, 48,127, 2,224,106,163, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 0, 47,127, 2,152, 0, 0, 0, 1, 0, 0, 0, 72, 47,127, 2,
+184, 46,127, 2, 32, 48,127, 2,144,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 72, 47,127, 2,
+152, 0, 0, 0, 1, 0, 0, 0,144, 47,127, 2, 0, 47,127, 2,104, 48,127, 2, 0,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0,144, 47,127, 2,152, 0, 0, 0, 1, 0, 0, 0,216, 47,127, 2, 72, 47,127, 2,104, 48,127, 2,
+216,108,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,216, 47,127, 2,152, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0,144, 47,127, 2, 32, 48,127, 2,104, 48,127, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,204, 0, 0, 0,
+248, 3,130, 2,154, 0, 0, 0, 1, 0, 0, 0,104,250,126, 2, 0, 0, 0, 0, 0,108,163, 2, 40,107,163, 2,112,107,163, 2,
+ 72,108,163, 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,128, 7, 0, 0,125, 4, 0, 0,157, 4, 0, 0, 0, 0, 0, 0,128, 7, 0, 0,
+125, 4, 0, 0,151, 4, 0, 0, 0, 0, 0, 0,128, 7, 0, 0,152, 4, 0, 0,157, 4, 0, 0, 5, 0, 4, 0, 1, 0, 7, 7,
+129, 7, 6, 0, 1, 0, 1, 0,171, 2, 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,120, 94,127, 2, 32,204,128, 2, 40, 17,146, 2,152,151,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+ 40, 17,146, 2,153, 0, 0, 0, 1, 0, 0, 0,192,206,149, 2, 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, 4,199, 0, 0, 3, 11, 0, 0, 3, 36, 0, 0, 0, 0, 0, 0, 4,199, 0, 0, 3, 11, 0, 0, 3, 37, 0, 0, 0, 0,
- 0, 0, 4,199, 0, 0, 3, 36, 0, 0, 3, 36, 0, 5, 0, 4, 0, 1, 7, 7, 4,200, 0, 1, 1, 0, 1, 0, 2,189, 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, 2,237, 23,112,
- 2,237, 23,112, 2,236, 36, 16, 2,236, 78,144, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 36, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 37, 32, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,192,206,149, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,120,203,149, 2, 40, 17,146, 2, 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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 37, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 38, 48, 2,236, 36, 16,
- 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, 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,
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,120,203,149, 2,153, 0, 0, 0, 1, 0, 0, 0,144,204,149, 2,
+192,206,149, 2, 65,110,105,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,
- 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 38, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 39, 64, 2,236, 37, 32, 65,110,105,109, 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, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,144,204,149, 2,153, 0, 0, 0, 1, 0, 0, 0, 56,112,163, 2,120,203,149, 2, 70,111,114,109,
+ 97,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, 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, 0, 0,
- 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,140, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 39, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 40, 80, 2,236, 38, 48, 70,111,114,109, 97,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, 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,210, 3, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 56,112,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 80,113,163, 2,144,204,149, 2, 80,114,101,118,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, 76, 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, 0, 0, 0, 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,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 40, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 41, 96, 2,236, 39, 64, 80,114,101,118,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, 76, 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, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 80,113,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,104,114,163, 2, 56,112,163, 2, 76, 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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 41, 96, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 42,112, 2,236, 40, 80,
- 76, 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,
- 76, 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, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,104,114,163, 2,153, 0, 0, 0, 1, 0, 0, 0,128,115,163, 2,
+ 80,113,163, 2, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,112,111,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, 76, 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, 0, 0, 0, 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, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 42,112, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 43,128, 2,236, 41, 96, 83,104, 97,100,111,119, 32, 97,
-110,100, 32, 83,112,111,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, 76, 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,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,128,115,163, 2,153, 0, 0, 0, 1, 0, 0, 0,152,116,163, 2,104,114,163, 2, 84,101,120,116,
+117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 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, 0, 0, 0,
- 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,140, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 43,128,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 44,144, 2,236, 42,112, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210, 3, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+152,116,163, 2,153, 0, 0, 0, 1, 0, 0, 0,176,117,163, 2,128,115,163, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 44,144, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 45,160, 2,236, 43,128, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,115,163, 2, 68, 65, 84, 65,228, 0, 0, 0,176,117,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,200,118,163, 2,152,116,163, 2, 80,114,101,118,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, 77, 97,116,101,114,105, 97,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, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 43,128, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 45,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 46,176, 2,236, 44,144,
- 80,114,101,118,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,
- 77, 97,116,101,114,105, 97,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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,200,118,163, 2,153, 0, 0, 0, 1, 0, 0, 0,224,119,163, 2,
+176,117,163, 2, 76,105,110,107,115, 32, 97,110,100, 32, 80,105,112,101,108,105,110,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 46,176, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 47,192, 2,236, 45,160, 76,105,110,107,115, 32, 97,110,
-100, 32, 80,105,112,101,108,105,110,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,224,119,163, 2,153, 0, 0, 0, 1, 0, 0, 0,248,120,163, 2,200,118,163, 2, 77, 97,116,101,
+114,105, 97,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, 0, 0, 0, 77, 97,116,101,
+114,105, 97,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, 0, 0, 0, 0, 0, 0, 0,
- 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, 70, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 47,192,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 48,208, 2,236, 46,176, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 77, 97,116,101,114,105, 97,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,140, 2, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+248,120,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 16,122,163, 2,224,119,163, 2, 82, 97,109,112,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 48,208, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 49,224, 2,236, 47,192, 82, 97,109,112,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, 77, 97,116,101,114,105, 97,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,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,119,163, 2, 68, 65, 84, 65,228, 0, 0, 0, 16,122,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 40,123,163, 2,248,120,163, 2, 83,104, 97,100,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 47,192, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 49,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 50,240, 2,236, 48,208,
- 83,104, 97,100,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,
- 77, 97,116,101,114,105, 97,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,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 40,123,163, 2, 68, 65, 84, 65,228, 0, 0, 0, 40,123,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 64,124,163, 2,
+ 16,122,163, 2, 77,105,114,114,111,114, 32, 84,114, 97,110,115,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 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,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 50,240, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 50,240, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 52, 0, 2,236, 49,224, 77,105,114,114,111,114, 32, 84,
-114, 97,110,115,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, 77, 97,116,101,114,105, 97,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,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 64,124,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 88,125,163, 2, 40,123,163, 2, 84,101,120,116,
+117,114,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, 77, 97,116,101,
+114,105, 97,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, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,210, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 52, 0,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 53, 16, 2,236, 50,240, 84,101,120,116,117,114,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, 24, 5, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 88,125,163, 2,153, 0, 0, 0, 1, 0, 0, 0,112,126,163, 2, 64,124,163, 2, 77, 97,112, 32, 73,110,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, 77, 97,116,101,114,105, 97,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 53, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 54, 32, 2,236, 52, 0, 77, 97,112, 32, 73,110,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, 24, 5, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,124,163, 2, 68, 65, 84, 65,228, 0, 0, 0,112,126,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,136,127,163, 2, 88,125,163, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 97,116,101,114,105, 97,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 52, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 54, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 55, 48, 2,236, 53, 16,
- 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 5, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 64,124,163, 2, 68, 65, 84, 65,228, 0, 0, 0,136,127,163, 2,153, 0, 0, 0, 1, 0, 0, 0,160,128,163, 2,
+112,126,163, 2, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,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,
- 77, 97,116,101,114,105, 97,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 52, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 55, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 56, 64, 2,236, 54, 32, 76,105,110,107, 32, 97,110,100,
- 32, 77, 97,116,101,114,105, 97,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, 69,100,105,116,105,110,103, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,160,128,163, 2,153, 0, 0, 0, 1, 0, 0, 0,184,129,163, 2,136,127,163, 2, 77,101,115,104,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 56, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 57, 80, 2,236, 55, 48, 77,101,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+184,129,163, 2,153, 0, 0, 0, 1, 0, 0, 0,208,130,163, 2,160,128,163, 2, 77,111,100,105,102,105,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, 69,100,105,116,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 57, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 58, 96, 2,236, 56, 64, 77,111,100,105,102,105,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,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,208,130,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,232,131,163, 2,184,129,163, 2, 83,104, 97,112,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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 58, 96, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 59,112, 2,236, 57, 80,
- 83,104, 97,112,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, 0,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,184,129,163, 2, 68, 65, 84, 65,228, 0, 0, 0,232,131,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 0,133,163, 2,
+208,130,163, 2, 77,101,115,104, 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,
- 69,100,105,116,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 57, 80, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 59,112, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 60,128, 2,236, 58, 96, 77,101,115,104, 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, 69,100,105,116,105,110,103, 0,
+ 0, 0, 0, 0,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 0,133,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 24,134,163, 2,232,131,163, 2, 77,101,115,104,
+ 32, 84,111,111,108,115, 32, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 5, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 24,134,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 48,135,163, 2, 0,133,163, 2, 80,114,101,118,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, 3,210, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 60,128,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 61,144, 2,236, 59,112, 77,101,115,104, 32, 84,111,111,108,115, 32, 49, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 48,135,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 72,136,163, 2, 24,134,163, 2, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 61,144, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 62,160, 2,236, 60,128, 80,114,101,118,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 72,136,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 96,137,163, 2,
+ 48,135,163, 2, 77,105,115,116, 32, 47, 32, 83,116, 97,114,115, 32, 47, 32, 80,104,121,115,105, 99,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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 62,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 63,176, 2,236, 61,144,
- 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 96,137,163, 2,153, 0, 0, 0, 1, 0, 0, 0,120,138,163, 2, 72,136,163, 2, 65,109, 98, 32,
+ 79, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,111,114,108,
+100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 63,176, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 64,192, 2,236, 62,160, 77,105,115,116, 32, 47, 32, 83,
-116, 97,114,115, 32, 47, 32, 80,104,121,115,105, 99,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, 87,111,114,108,100, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 2, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,136,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+120,138,163, 2,153, 0, 0, 0, 1, 0, 0, 0,144,139,163, 2, 96,137,163, 2, 84,101,120,116,117,114,101, 32, 97,110,100, 32,
+ 73,110,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,140, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 64,192,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 65,208, 2,236, 63,176, 65,109, 98, 32, 79, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,144,139,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,168,140,163, 2,120,138,163, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 63,176, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 65,208, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 66,224, 2,236, 64,192, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,120,138,163, 2, 68, 65, 84, 65,228, 0, 0, 0,168,140,163, 2,153, 0, 0, 0, 1, 0, 0, 0,192,141,163, 2,
+144,139,163, 2, 80,114,101,118,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, 84,101,120,116,117,114,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, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 66,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 67,240, 2,236, 65,208,
- 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,192,141,163, 2,153, 0, 0, 0, 1, 0, 0, 0,216,142,163, 2,168,140,163, 2, 84,101,120,116,
+117,114,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, 84,101,120,116,
+117,114,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+216,142,163, 2,153, 0, 0, 0, 1, 0, 0, 0,240,143,163, 2,192,141,163, 2, 67,111,108,111,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,
- 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 65,208, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 67,240, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 69, 0, 2,236, 66,224, 80,114,101,118,105,101,119, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,101,120,116,117,114,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, 84,101,120,116,117,114,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, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,141,163, 2, 68, 65, 84, 65,228, 0, 0, 0,240,143,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 8,145,163, 2,216,142,163, 2, 79, 98,106,101, 99,116, 32, 97,110,100, 32, 76,105,110,107,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, 0, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 69, 0,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 70, 16, 2,236, 67,240, 84,101,120,116,117,114,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,101,120,116,117,114,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, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 8,145,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 32,146,163, 2,
+240,143,163, 2, 65,110,105,109, 32,115,101,116,116,105,110,103,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, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 70, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 71, 32, 2,236, 69, 0, 67,111,108,111,114,115, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,101,120,116,117,114,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, 70, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 32,146,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 56,147,163, 2, 8,145,163, 2, 68,114, 97,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, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 69, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 71, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 72, 48, 2,236, 70, 16,
- 79, 98,106,101, 99,116, 32, 97,110,100, 32, 76,105,110,107,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 2, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 56,147,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 80,148,163, 2, 32,146,163, 2, 67,111,110,115,116,114, 97,105,110,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, 79, 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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 72, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 73, 64, 2,236, 71, 32, 65,110,105,109, 32,115,101,116,
-116,105,110,103,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 80,148,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,104,149,163, 2, 56,147,163, 2, 67,108,111,117,100,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 73, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 74, 80, 2,236, 72, 48, 68,114, 97,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, 84,101,120,116,117,114,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,104,149,163, 2,153, 0, 0, 0, 1, 0, 0, 0,128,150,163, 2,
+ 80,148,163, 2, 83,116,117, 99, 99,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 74, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 75, 96, 2,236, 73, 64, 67,111,110,115,116,114, 97,105,110,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 84,101,120,116,117,114,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, 79, 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, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,140, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,128,150,163, 2,153, 0, 0, 0, 1, 0, 0, 0,152,151,163, 2,104,149,163, 2, 87,111,111,100,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 75, 96, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 76,112, 2,236, 74, 80,
- 67,108,111,117,100,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, 84,101,120,116,
+117,114,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,
- 84,101,120,116,117,114,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,140, 2, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+152,151,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,128,150,163, 2, 82,101,110,100,101,114, 32, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 76,112, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 77,128, 2,236, 75, 96, 83,116,117, 99, 99,105, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,101,120,116,117,114,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, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 17,146, 2, 68, 65, 84, 65,204, 0, 0, 0,104,250,126, 2,154, 0, 0, 0,
+ 1, 0, 0, 0, 24,120,126, 2,248, 3,130, 2,144,108,163, 2,216,108,163, 2, 72,108,163, 2,184,107,163, 2, 0, 0, 0, 0,
+ 0, 0,140, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 68, 45, 65, 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,
+253, 5, 0, 0,128, 7, 0, 0, 0, 0, 0, 0,123, 4, 0, 0,253, 5, 0, 0,128, 7, 0, 0, 97, 4, 0, 0,123, 4, 0, 0,
+253, 5, 0, 0,128, 7, 0, 0, 0, 0, 0, 0, 96, 4, 0, 0, 7, 0, 6, 0, 2, 0, 4, 4,132, 1, 97, 4, 1, 0, 1, 0,
+173, 1, 4, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,208,163, 2,192,158,126, 2,
+ 24,124,127, 2, 64,245,126, 2,176,152,163, 2,112, 59, 8, 3, 68, 65, 84, 65,228, 0, 0, 0,176,152,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,200,153,163, 2, 0, 0, 0, 0, 84,114, 97,110,115,102,111,114,109, 32, 80,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, 0, 0, 0, 0, 0, 0, 0, 73,112,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,140, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 77,128,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 78,144, 2,236, 76,112, 87,111,111,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,167, 0, 62, 1,204, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,200,153,163, 2,153, 0, 0, 0, 1, 0, 0, 0,224,154,163, 2,
+176,152,163, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 78,144, 0, 0, 0,137, 0, 0, 0, 1,
- 0, 0, 0, 0, 2,236, 77,128, 82,101,110,100,101,114, 32, 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, 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, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,176,187,163, 2,
+ 68, 65, 84, 65,228, 0, 0, 0,224,154,163, 2,153, 0, 0, 0, 1, 0, 0, 0,248,155,163, 2,200,153,163, 2, 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, 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, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+248,155,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 16,157,163, 2,224,154,163, 2, 65,110,105,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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 36, 16, 68, 65, 84, 65, 0, 0, 0,204, 2,236, 79,160, 0, 0, 0,138, 0, 0, 0, 1, 2,236,136,160, 2,236, 35, 16,
- 2,236, 31,208, 2,236, 32, 16, 2,236, 31,144, 2,228,196,160, 0, 0, 0, 0, 63,140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 45, 68,171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,128, 1, 80,
-191,128, 0, 0,128, 0, 0, 0,128, 0, 0, 0,188,163,215,226,128, 0, 0, 0, 0, 0, 3,209, 0, 0, 4,199, 0, 0, 0, 0,
- 0, 0, 3, 9, 0, 0, 3,209, 0, 0, 4,199, 0, 0, 2,239, 0, 0, 3, 9, 0, 0, 3,209, 0, 0, 4,199, 0, 0, 0, 0,
- 0, 0, 2,238, 0, 7, 0, 6, 0, 2, 4, 4, 0,247, 2,239, 1, 0, 1, 0, 1,136, 0, 68, 0, 7, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,127, 96, 2,236,135, 16, 2,232,159,176, 2,232,206,176, 2,236, 80,160,
- 2,232,193, 80, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 80,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 81,176, 0, 0, 0, 0,
- 84,114, 97,110,115,102,111,114,109, 32, 80,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, 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,
- 73,112,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,254, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 16,157,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 40,158,163, 2,248,155,163, 2, 70,111,114,109, 97,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, 33, 0,167, 1, 62, 0,204, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 81,176, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 82,192, 2,236, 80,160, 79,117,116,112,117,116, 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, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 40,158,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 64,159,163, 2,
+ 16,157,163, 2, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2,236,114,160, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 82,192,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 83,208, 2,236, 81,176, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 69,100,105,116,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 64,159,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 88,160,163, 2, 40,158,163, 2, 67, 97,109,101,
+114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 24, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 83,208, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 84,224, 2,236, 82,192, 65,110,105,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, 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,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 88,160,163, 2,153, 0, 0, 0, 1, 0, 0, 0,112,161,163, 2, 64,159,163, 2, 80,114,101,118,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, 76, 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,254, 48, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 84,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 85,240, 2,236, 83,208,
- 70,111,114,109, 97,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,
- 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,112,161,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,136,162,163, 2, 88,160,163, 2, 76, 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, 76, 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,253, 72, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 85,240, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 87, 0, 2,236, 84,224, 76,105,110,107, 32, 97,110,100,
- 32, 77, 97,116,101,114,105, 97,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,136,162,163, 2,153, 0, 0, 0, 1, 0, 0, 0,160,163,163, 2,
+112,161,163, 2, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,112,111,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, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 87, 0,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 88, 16, 2,236, 85,240, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 48,254, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,160,163,163, 2,153, 0, 0, 0, 1, 0, 0, 0,184,164,163, 2,136,162,163, 2, 84,101,120,116,
+117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 88, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 89, 32, 2,236, 87, 0, 80,114,101,118,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,253,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+184,164,163, 2,153, 0, 0, 0, 1, 0, 0, 0,208,165,163, 2,160,163,163, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 89, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 90, 48, 2,236, 88, 16,
- 76, 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,
- 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,253, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,163,163, 2, 68, 65, 84, 65,228, 0, 0, 0,208,165,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,232,166,163, 2,184,164,163, 2, 77,101,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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,255, 24, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 90, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 91, 64, 2,236, 89, 32, 83,104, 97,100,111,119, 32, 97,
-110,100, 32, 83,112,111,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, 76, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,232,166,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 0,168,163, 2,
+208,165,163, 2, 77,111,100,105,102,105,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 48, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 91, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 92, 80, 2,236, 90, 48, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 92, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 93, 96, 2,236, 91, 64, 77, 97,112, 32, 84,111, 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,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 0,168,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 24,169,163, 2,232,166,163, 2, 83,104, 97,112,
+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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,253,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,166,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+ 24,169,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 48,170,163, 2, 0,168,163, 2, 77,101,115,104, 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, 69,100,105,116,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,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236, 91, 64, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 93, 96, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 94,112, 2,236, 92, 80,
- 77,101,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,253, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 48,170,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 72,171,163, 2, 24,169,163, 2, 77,101,115,104, 32, 84,111,111,108,115, 32, 49, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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,255, 24, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 94,112, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 95,128, 2,236, 93, 96, 77,111,100,105,102,105,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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,252, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 72,171,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 96,172,163, 2,
+ 48,170,163, 2, 84,101,120,116,117,114,101, 32,102, 97, 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,253, 72, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 95,128,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236, 96,144, 2,236, 94,112, 83,104, 97,112,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,172,163, 2,
+ 68, 65, 84, 65,228, 0, 0, 0, 96,172,163, 2,153, 0, 0, 0, 1, 0, 0, 0,120,173,163, 2, 72,171,163, 2, 85, 86, 32, 67,
+ 97,108, 99,117,108, 97,116,105,111,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 12, 2,236, 94,112, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 96,144, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236, 97,160, 2,236, 95,128, 77,101,115,104, 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, 69,100,105,116,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,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+120,173,163, 2,153, 0, 0, 0, 1, 0, 0, 0,144,174,163, 2, 96,172,163, 2, 80, 97,105,110,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, 69,100,105,116,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,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 97,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 98,176, 2,236, 96,144,
- 77,101,115,104, 32, 84,111,111,108,115, 32, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,254, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,144,174,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,168,175,163, 2,120,173,163, 2, 67,117,114,118,101, 32, 97,110,100, 32, 83,117,114,102, 97, 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, 69,100,105,116,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,252, 96, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236, 98,176, 0, 0, 0,137, 0, 0, 0, 1, 2,236, 99,192, 2,236, 97,160, 84,101,120,116,117,114,101, 32,
-102, 97, 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, 69,100,105,116,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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,168,175,163, 2,153, 0, 0, 0, 1, 0, 0, 0,192,176,163, 2,
+144,174,163, 2, 67,117,114,118,101, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236, 99,192, 68, 65, 84, 65, 0, 0, 0,228, 2,236, 99,192,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,100,208, 2,236, 98,176, 85, 86, 32, 67, 97,108, 99,117,108, 97,116,105,111,110, 0, 0,
+ 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,192,176,163, 2,153, 0, 0, 0, 1, 0, 0, 0,216,177,163, 2,168,175,163, 2, 67,117,114,118,
+101, 32, 84,111,111,108,115, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,
+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, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,100,208, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,101,224, 2,236, 99,192, 80, 97,105,110,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, 69,100,105,116,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, 72,253,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+216,177,163, 2,153, 0, 0, 0, 1, 0, 0, 0,240,178,163, 2,192,176,163, 2, 80,114,101,118,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, 77, 97,116,101,114,105, 97,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, 0, 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, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,101,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236,102,240, 2,236,100,208,
- 67,117,114,118,101, 32, 97,110,100, 32, 83,117,114,102, 97, 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,
- 69,100,105,116,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, 62, 1,204, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,240,178,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 8,180,163, 2,216,177,163, 2, 76,105,110,107,115, 32, 97,110,100, 32, 80,105,112,101,108,105,110,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,102,240, 0, 0, 0,137, 0, 0, 0, 1, 2,236,104, 0, 2,236,101,224, 67,117,114,118,101, 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, 69,100,105,116,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, 24,255, 62, 1,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 21, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 8,180,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 32,181,163, 2,
+240,178,163, 2, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 77, 97,116,101,114,105, 97,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, 0, 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, 24, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,104, 0,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,105, 16, 2,236,102,240, 67,117,114,118,101, 32, 84,111,111,108,115, 49, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 48,254, 62, 1,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 32,181,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 56,182,163, 2, 8,180,163, 2, 82, 97,109,112,
+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, 77, 97,116,101,
+114,105, 97,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, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,105, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,106, 32, 2,236,104, 0, 80,114,101,118,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, 48,254,
+ 62, 1,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 8,180,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+ 56,182,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 80,183,163, 2, 32,181,163, 2, 83,104, 97,100,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, 77, 97,116,101,114,105, 97,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,106, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236,107, 48, 2,236,105, 16,
- 76,105,110,107,115, 32, 97,110,100, 32, 80,105,112,101,108,105,110,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, 52,253, 62, 1,224, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 80,183,163, 2, 68, 65, 84, 65,228, 0, 0, 0, 80,183,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,104,184,163, 2, 56,182,163, 2, 77,105,114,114,111,114, 32, 84,114, 97,110,115,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,
- 77, 97,116,101,114,105, 97,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,107, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236,108, 64, 2,236,106, 32, 77, 97,116,101,114,105, 97,108,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,248,252, 62, 1, 28, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 21, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,104,184,163, 2,153, 0, 0, 0, 1, 0, 0, 0,128,185,163, 2,
+ 80,183,163, 2, 84,101,120,116,117,114,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, 77, 97,116,101,114,105, 97,108,
+ 0, 0, 0, 0, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 48, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,108, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,109, 80, 2,236,107, 48, 82, 97,109,112,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16,252, 62, 1,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,128,185,163, 2,
+ 68, 65, 84, 65,228, 0, 0, 0,128,185,163, 2,153, 0, 0, 0, 1, 0, 0, 0,152,186,163, 2,104,184,163, 2, 77, 97,112, 32,
+ 73,110,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, 77, 97,116,101,
+114,105, 97,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, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,252,
+ 62, 1,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+152,186,163, 2,153, 0, 0, 0, 1, 0, 0, 0,176,187,163, 2,128,185,163, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 97,116,101,114,105, 97,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, 0,254, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,236,107, 48, 68, 65, 84, 65, 0, 0, 0,228, 2,236,109, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,110, 96, 2,236,108, 64, 83,104, 97,100,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, 77, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,252, 62, 1,204, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,128,185,163, 2, 68, 65, 84, 65,228, 0, 0, 0,176,187,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,200,188,163, 2,152,186,163, 2, 82,101,110,100,101,114, 32, 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, 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,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236,110, 96, 68, 65, 84, 65, 0, 0, 0,228, 2,236,110, 96, 0, 0, 0,137, 0, 0, 0, 1, 2,236,111,112, 2,236,109, 80,
- 77,105,114,114,111,114, 32, 84,114, 97,110,115,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,
- 77, 97,116,101,114,105, 97,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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,200,188,163, 2,153, 0, 0, 0, 1, 0, 0, 0,224,189,163, 2,
+176,187,163, 2, 80,114,101,118,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,111,112, 0, 0, 0,137, 0, 0, 0, 1, 2,236,112,128, 2,236,110, 96, 84,101,120,116,117,114,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, 77, 97,116,101,114,105, 97,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, 48,254, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,224,189,163, 2,153, 0, 0, 0, 1, 0, 0, 0,248,190,163, 2,200,188,163, 2, 87,111,114,108,
+100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,111,114,108,
+100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 96, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,112,128,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,113,144, 2,236,111,112, 77, 97,112, 32, 73,110,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, 72,253,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+248,190,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 16,192,163, 2,224,189,163, 2, 77,105,115,116, 32, 47, 32, 83,116, 97,114,115,
+ 32, 47, 32, 80,104,121,115,105, 99,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 16,192,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 40,193,163, 2,248,190,163, 2, 65,109, 98, 32, 79, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,252, 96, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,236,111,112, 68, 65, 84, 65, 0, 0, 0,228, 2,236,113,144, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,114,160, 2,236,112,128, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,248,190,163, 2, 68, 65, 84, 65,228, 0, 0, 0, 40,193,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 64,194,163, 2,
+ 16,192,163, 2, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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,252, 96, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236,111,112, 68, 65, 84, 65, 0, 0, 0,228, 2,236,114,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236,115,176, 2,236,113,144,
- 82,101,110,100,101,114, 32, 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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 64,194,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 88,195,163, 2, 40,193,163, 2, 77, 97,112, 32,
+ 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,111,114,108,
+100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,115,176, 0, 0, 0,137, 0, 0, 0, 1, 2,236,116,192, 2,236,114,160, 80,114,101,118,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, 87,111,114,108,100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,193,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+ 88,195,163, 2,153, 0, 0, 0, 1, 0, 0, 0,112,196,163, 2, 64,194,163, 2, 77,117,108,116,105,114,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 48, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,116,192,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,117,208, 2,236,115,176, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,254, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,112,196,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,136,197,163, 2, 88,195,163, 2, 79, 98,106,101, 99,116, 32, 97,110,100, 32, 76,105,110,107,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,117,208, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,118,224, 2,236,116,192, 77,105,115,116, 32, 47, 32, 83,116, 97,114,115, 32, 47, 32, 80,104,121,115,105, 99,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,136,197,163, 2,153, 0, 0, 0, 1, 0, 0, 0,160,198,163, 2,
+112,196,163, 2, 65,110,105,109, 32,115,101,116,116,105,110,103,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, 79, 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, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,118,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236,119,240, 2,236,117,208,
- 65,109, 98, 32, 79, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,160,198,163, 2,153, 0, 0, 0, 1, 0, 0, 0,184,199,163, 2,136,197,163, 2, 68,114, 97,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,117,208, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,119,240, 0, 0, 0,137, 0, 0, 0, 1, 2,236,121, 0, 2,236,118,224, 84,101,120,116,117,114,101, 32,
- 97,110,100, 32, 73,110,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, 87,111,114,108,100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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,254,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+184,199,163, 2,153, 0, 0, 0, 1, 0, 0, 0,208,200,163, 2,160,198,163, 2, 67,111,110,115,116,114, 97,105,110,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 24, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,121, 0,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,122, 16, 2,236,119,240, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,208,200,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,232,201,163, 2,184,199,163, 2, 66, 97,107,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 24, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,236,119,240, 68, 65, 84, 65, 0, 0, 0,228, 2,236,122, 16, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,123, 32, 2,236,121, 0, 77,117,108,116,105,114,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 48,254, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0,248,155,163, 2, 68, 65, 84, 65,228, 0, 0, 0,232,201,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 0,203,163, 2,
+208,200,163, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,123, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236,124, 48, 2,236,122, 16,
- 79, 98,106,101, 99,116, 32, 97,110,100, 32, 76,105,110,107,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,
- 79, 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, 72,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 16,157,163, 2,
+ 68, 65, 84, 65,228, 0, 0, 0, 0,203,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 24,204,163, 2,232,201,163, 2, 80, 97,114,116,
+105, 99,108,101, 32, 83,121,115,116,101,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, 80, 97,114,116,
+105, 99,108,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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,124, 48, 0, 0, 0,137, 0, 0, 0, 1, 2,236,125, 64, 2,236,123, 32, 65,110,105,109, 32,115,101,116,
-116,105,110,103,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, 79, 98,106,101, 99,116, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 24,204,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 48,205,163, 2, 0,203,163, 2, 80,104,121,115,105, 99,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, 80, 97,114,116,105, 99,108,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,255, 24, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,125, 64,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,126, 80, 2,236,124, 48, 68,114, 97,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, 79, 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, 24,255, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 48,205,163, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 72,206,163, 2, 24,204,163, 2, 86,105,115,117, 97,108,105,122, 97,116,105,111,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, 0, 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, 97,114,116,105, 99,108,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,254, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,126, 80, 0, 0, 0,137, 0, 0, 0, 1,
- 2,232,193, 80, 2,236,125, 64, 67,111,110,115,116,114, 97,105,110,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, 79, 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, 48,254, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 72,206,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 96,207,163, 2,
+ 48,205,163, 2, 69,120,116,114, 97,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, 80, 97,114,116,105, 99,108,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,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,232,193, 80, 0, 0, 0,137, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,126, 80,
- 66, 97,107,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,
- 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, 72,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 96,207,163, 2,153, 0, 0, 0, 1, 0, 0, 0,208,244,161, 2, 72,206,163, 2, 67,104,105,108,
+100,114,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, 0, 0,
+ 0, 0, 0, 0, 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, 97,114,116,
+105, 99,108,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, 0, 0, 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,253,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,206,163, 2, 68, 65, 84, 65,228, 0, 0, 0,
+208,244,161, 2,153, 0, 0, 0, 1, 0, 0, 0,136,110,155, 2, 96,207,163, 2, 80,114,101,118,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,254, 48, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 2,236, 83,208, 68, 65, 84, 65,
- 0, 0, 0,204, 2,236,127, 96, 0, 0, 0,118, 0, 0, 0, 1, 5, 30,228, 32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
- 2,236, 79,160, 0, 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,
-193, 0, 0, 0, 67,163, 0, 0,196,106, 0, 0, 67,104, 0, 0,194,173, 94,108, 67,202, 87,155,196,148,152,252, 67,152,156, 15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,101,120,116,117,114,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, 67,128, 0, 0, 66, 40, 0, 0, 69, 0, 0, 0, 67,225, 0, 0,
- 63, 0, 0, 0, 63,154,225, 72, 0, 0, 0, 1, 0, 1, 0, 1, 0,247, 2,239, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,
- 5, 30,236, 32,255,255, 0, 0, 0, 0, 0, 0, 1,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 3, 0, 5, 30,228, 32, 0, 0, 0,113, 0, 0, 0, 1, 2,236,128, 96, 2,236,127, 96, 0, 0, 0, 1, 63, 51, 51, 51,
- 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,127,198, 52,188,166, 29,146, 61, 22,153, 97,
- 0, 0, 0, 0, 61, 43,252, 13, 62,247, 11, 89,191, 95,248, 90, 0, 0, 0, 0, 52, 67,176,196, 63, 96, 42,246, 62,247, 67, 44,
- 0, 0, 0, 0, 64, 78, 45, 74, 62,172, 87,201,194, 41,171, 79, 63,128, 0, 0, 63,127,198, 53, 61, 43,251,248, 52, 80, 0, 0,
- 0, 0, 0, 0,188,166, 29,186, 62,247, 11,119, 63, 96, 43, 16, 0, 0, 0, 0, 61, 22,153, 99,191, 95,248,117, 62,247, 67, 75,
- 0, 0, 0, 0,191,211,125,192,194, 21,161,185, 65,161,133, 59, 63,128, 0, 0, 63,139,224,100,190, 96,221, 21,189, 22,154,236,
-189, 22,153, 97, 61, 60, 27,174, 64,167, 52,239, 63, 95,250,166, 63, 95,248, 90, 52, 86, 9, 86, 65, 23,185, 41,190,247, 69,181,
-190,247, 67, 44, 64, 97,129,137, 64,105, 75, 27, 66, 41,152,145, 66, 41,171, 79, 63,105,225, 95, 61, 39,247, 84,186,185, 46,176,
-184,146,196,144,186,245,126,178, 61, 54,117, 48, 61,165,157, 23, 52,153,160, 0, 66,165, 56,225, 68,233,202,192,196,124, 94, 18,
-194, 71,254, 87,194,165, 77,102,196,233,177, 39, 68,124, 65,193, 66, 72, 0,101, 63,140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 65, 45, 68,171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,128, 1, 80,
-191,128, 0, 0,128, 0, 0, 0,128, 0, 0, 0,188,163,215,226,128, 0, 0, 0, 63,127,198, 52,188,166, 29,146, 61, 22,153, 97,
- 0, 0, 0, 0, 61, 43,252, 13, 62,247, 11, 89,191, 95,248, 90, 0, 0, 0, 0, 52, 67,176,196, 63, 96, 42,246, 62,247, 67, 44,
- 0, 0, 0, 0, 64, 78, 45, 74, 62,172, 87,201,194, 41,171, 79, 63,128, 0, 0, 63, 92, 99,141,191, 2, 35, 43,188, 46,238,188,
-188,148, 32, 94, 66, 25,240, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 30,248, 32, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 1, 0, 1, 0, 0,
-255,226, 0, 0, 66, 12, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 58,124, 56, 68, 60, 35,215, 10, 67,250, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 64, 68, 77,201, 64,111, 66,228,191,205, 97,230, 60,149,191,128,191, 77,109,116, 63,230,165,248, 0, 20, 0, 0,
- 0, 7, 0, 99, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,255,255, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,254, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,136,110,155, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,112,109,155, 2,208,244,161, 2, 84,101,120,116,117,114,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, 24, 24, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 40, 2,236,128, 96, 0, 0, 0,117,
- 0, 0, 0, 1, 2,236,129,176, 5, 30,228, 32, 0, 0, 0, 2, 63, 51, 51, 51, 2,236, 79,160, 0, 0, 0, 0, 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,122, 0, 0,189,204,204,205, 63,140,204,205,
- 63,128, 0, 0, 67,122, 0, 0,192,160, 0, 0, 64,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 2,235,
- 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 16, 0, 0, 2,235,
- 60, 35,215, 10, 60, 35,215, 10, 70,106, 96, 0, 68,122, 0, 0, 0, 0, 0, 0, 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, 5, 31, 16, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,101,120,116,117,114,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, 29, 0, 0,
- 0, 0, 0, 0, 0, 0, 79, 66, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 67,122, 0, 0,189,204,204,205, 63,140,204,205, 68, 65, 84, 65, 0, 0, 0,120, 2,236,129,176, 0, 0, 0,124, 0, 0, 0, 1,
- 2,236,130, 80, 2,236,128, 96, 0, 0, 0, 9, 63, 51, 51, 51, 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,236,183,112, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 5, 0, 0, 0, 17,
- 0, 0, 2,225, 0, 0, 2,227, 0, 0, 0, 5, 0, 0, 0, 17, 0, 0, 2,207, 0, 0, 2,227, 68, 65, 84, 65, 0, 0, 0,248,
- 2,236,130, 80, 0, 0, 0,122, 0, 0, 0, 1, 2,236,131,112, 2,236,129,176, 0, 0, 0, 6, 63, 51, 51, 51, 2,236, 79,160,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0, 0, 0, 0, 0, 67,128, 0, 0,
-190,120, 0, 0, 63,159, 0, 0,190,242, 0, 0, 63,188,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,124, 0, 0, 0, 0, 0, 0, 1,242,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 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, 1, 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, 63,128, 0, 0, 0, 0, 0, 0, 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, 0, 0,248, 2,236,131,112, 0, 0, 0,121, 0, 0, 0, 1, 2,236,132,144, 2,236,130, 80,
- 0, 0, 0, 3, 63, 51, 51, 51, 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 67,182, 0, 0,195,209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,182, 0, 0,195,190, 0, 0,181, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
- 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 1,124,195,190, 0, 0,195,190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1,108, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,142,
- 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, 68, 65, 84, 65, 0, 0, 0,160, 2,236,132,144, 0, 0, 0,194,
- 0, 0, 0, 1, 2,236,133, 96, 2,236,131,112, 0, 0, 0, 11, 63, 51, 51, 51, 2,236, 79,160,192,128, 0, 0, 67,122, 0, 0,
-192,128, 0, 0, 67,127, 0, 0,192,128, 0, 0, 66, 72, 0, 0,192,128, 0, 0, 67,127, 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,124, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1,124,
- 0, 0, 0, 16, 0, 0, 1,124, 63,128, 0, 0, 67,129,128, 0, 70,250, 0, 0, 67,129,128, 0, 61,204,204,205, 65, 32, 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, 68, 65, 84, 65, 0, 0, 0,164, 2,236,133, 96, 0, 0, 0,123, 0, 0, 0, 1, 2,236,134, 48, 2,236,132,144,
- 0, 0, 0, 13, 63, 51, 51, 51, 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 68,122, 0, 0, 0, 0, 0, 0, 68,122, 0, 0,192,160, 0, 0, 66,130, 0, 0, 0, 0, 0, 0,
- 67,182, 0, 0, 0, 0, 1,108, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0,196, 0, 0, 1,108, 0, 0, 0, 0,
- 0, 0, 0, 16, 0, 0, 0,196, 0, 0, 1,108, 0, 0, 0, 16, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 68,122, 0, 0,
- 68,122, 0, 0, 61,204,204,205, 66, 72, 0, 0, 0, 10, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,176, 2,236,134, 48, 0, 0, 0,203, 0, 0, 0, 1, 2,236,135, 16, 2,236,133, 96, 0, 0, 0, 12, 63, 51, 51, 51,
- 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 0, 66, 2, 0, 0,193,128, 0, 0,
- 67,247, 0, 0,191, 0, 0, 0, 66, 2, 0, 0,193,128, 0, 0, 67,247, 0, 0, 0, 0, 1,108, 0, 0, 1,124, 0, 0, 0, 0,
- 0, 0, 2, 14, 0, 0, 0,128, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 1,108, 0, 0, 0, 16,
- 0, 0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 70,250, 0, 0, 68,122, 0, 0, 60, 35,215, 10, 66, 72, 0, 0, 0, 10, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 1,104, 2,236,135, 16, 0, 0, 0,120, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,134, 48, 0, 0, 0, 5,
- 63, 51, 51, 51, 2,236, 79,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150,
- 83, 97,118,101, 32, 70,105,108,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101,114,115, 47,116,
-111,110, 47, 68,101,115,107,116,111,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,112,114,101,118,105,101,119, 46,
- 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 82, 0, 0, 0, 0, 1, 76, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,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, 68, 65, 84, 65,
- 0, 0, 0,204, 2,236,136,160, 0, 0, 0,138, 0, 0, 0, 1, 0, 0, 0, 0, 2,236, 79,160, 2,235, 18,144, 2,236, 31, 80,
- 2,236, 32, 16, 2,236, 31,208, 0, 0, 0, 0, 63, 79, 65,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,134,173, 25, 0, 0, 0, 0, 0, 0, 0, 0,189, 60, 82,171,188,131, 1,211,191,153,211,206,191,128, 0, 0,128, 0, 0, 0,
-128, 0, 0, 0,193, 65,236,225,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,207, 0, 0, 0, 0, 0, 0, 3, 9, 0, 0, 0, 0,
- 0, 0, 3,207, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 3,207, 0, 0, 0, 27, 0, 0, 3, 9, 0, 9, 0, 8,
- 0, 1, 1, 1, 3,208, 2,239, 1, 0, 1, 0, 2,195, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 5, 30,232, 32, 2,236,159, 32, 2,232,189,144, 2,232,189,144, 2,236,137,160, 2,236,150, 96, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,137,160, 0, 0, 0,137, 0, 0, 0, 1, 2,236,138,176, 0, 0, 0, 0, 84,114, 97,110,115,102,111,114,
-109, 32, 80,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, 0, 0, 0, 0, 0, 0, 0, 73,112,111, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,112,109,155, 2,153, 0, 0, 0, 1, 0, 0, 0,232,245,161, 2,
+136,110,155, 2, 67,111,108,111,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, 84,101,120,116,117,114,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, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,136,110,155, 2,
+ 68, 65, 84, 65,228, 0, 0, 0,232,245,161, 2,153, 0, 0, 0, 1, 0, 0, 0,112, 59, 8, 3,112,109,155, 2, 87,111,111,100,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,101,120,116,
+117,114,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+112, 59, 8, 3,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,232,245,161, 2, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 97,116,101,114,105, 97,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 80,183,163, 2, 68, 65, 84, 65,220, 0, 0, 0,120,208,163, 2,133, 0, 0, 0,
+ 1, 0, 0, 0,240,182, 63, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,104,250,126, 2, 40,252,163, 2, 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,193, 0, 0,163, 67, 0, 0,124,196,
+ 0, 0,104, 67,108, 94,173,194,155, 87,202, 67,101,243,143,196,181, 5,134, 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, 0, 0, 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, 67, 0, 0, 40, 66, 0, 0, 0, 69, 0, 0,225, 67, 0, 0, 0, 63, 72,225,154, 63, 0, 0, 1, 0,
+ 1, 0, 1, 0,132, 1, 97, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0,
+ 0, 0, 3, 0,152,140,165, 2, 1, 0, 0, 0, 0, 0, 0, 0,150, 1, 0, 0, 48, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 0, 3, 0, 0,240,182, 63, 0,128, 0, 0, 0, 1, 0, 0, 0,208,189,147, 2,120,208,163, 2, 1, 0, 0, 0,
+ 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52,198,127, 63,146, 29,166,188,
+ 97,153, 22, 61, 0, 0, 0, 0, 13,252, 43, 61, 89, 11,247, 62, 90,248, 95,191, 0, 0, 0, 0,196,176, 67, 52,246, 42, 96, 63,
+ 44, 67,247, 62, 0, 0, 0, 0, 74, 45, 78, 64,201, 87,172, 62, 79,171, 41,194, 0, 0,128, 63, 53,198,127, 63,248,251, 43, 61,
+ 0, 0, 80, 52, 0, 0, 0, 0,186, 29,166,188,119, 11,247, 62, 16, 43, 96, 63, 0, 0, 0, 0, 99,153, 22, 61,117,248, 95,191,
+ 75, 67,247, 62, 0, 0, 0, 0,192,125,211,191,185,161, 21,194, 59,133,161, 65, 0, 0,128, 63,100,224,139, 63, 21,221, 96,190,
+236,154, 22,189, 97,153, 22,189,174, 27, 60, 61,239, 52,167, 64,166,250, 95, 63, 90,248, 95, 63, 86, 9, 86, 52, 41,185, 23, 65,
+181, 69,247,190, 44, 67,247,190,137,129, 97, 64, 27, 75,105, 64,145,152, 41, 66, 79,171, 41, 66, 95,225,105, 63, 84,247, 39, 61,
+176, 46,185,186,144,196,146,184,178,126,245,186, 48,117, 54, 61, 23,157,165, 61, 0,160,153, 52,225, 56,165, 66,192,202,233, 68,
+ 18, 94,124,196, 87,254, 71,194,102, 77,165,194, 39,177,233,196,193, 65,124, 68,101, 0, 72, 66, 0, 0,140, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,171, 68, 45, 65, 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, 52,198,127, 63,146, 29,166,188,
+ 97,153, 22, 61, 0, 0, 0, 0, 13,252, 43, 61, 89, 11,247, 62, 90,248, 95,191, 0, 0, 0, 0,196,176, 67, 52,246, 42, 96, 63,
+ 44, 67,247, 62, 0, 0, 0, 0, 74, 45, 78, 64,201, 87,172, 62, 79,171, 41,194, 0, 0,128, 63,141, 99, 92, 63, 43, 35, 2,191,
+188,238, 46,188, 94, 32,148,188, 23,240, 25, 66, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,160, 26,156, 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, 2, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
+ 1, 0, 0, 0,226,255, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63, 68, 56,124, 58, 10,215, 35, 60, 0, 0,250, 67,
+ 0, 0, 0, 0, 0, 0, 0, 0,201, 77, 68, 64,228, 66,111, 64,230, 97,205,191,128,191,149, 60,116,109, 77,191,248,165,230, 63,
+ 20, 0, 0, 0, 7, 0, 99, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,255,255, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,167, 1, 62, 0,204,
- 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,138,176,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,139,192, 2,236,137,160, 79,117,116,112,117,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0,208,189,147, 2,
+132, 0, 0, 0, 1, 0, 0, 0,136,209,163, 2,240,182, 63, 0, 2, 0, 0, 0, 51, 51, 51, 63,104,250,126, 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,122, 67,205,204,204,189,
+205,204,140, 63, 0, 0,128, 63, 0, 0,122, 67, 0, 0,160,192, 0, 0,160, 64, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
+235, 2, 0, 0, 16, 0, 0, 0,168, 3, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0,168, 3, 0, 0, 16, 0, 0, 0,
+235, 2, 0, 0, 10,215, 35, 60, 10,215, 35, 60, 0, 96,106, 70, 0, 0,122, 68, 0, 0, 0, 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, 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, 88, 43,153, 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, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 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,122, 67,205,204,204,189,205,204,140, 63,
+ 68, 65, 84, 65,120, 0, 0, 0,136,209,163, 2,139, 0, 0, 0, 1, 0, 0, 0, 48,210,163, 2,208,189,147, 2, 9, 0, 0, 0,
+ 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,199,156, 2, 0, 0, 0, 0,
+ 62, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 12, 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,205,204,204, 61, 5, 0, 0, 0, 17, 0, 0, 0,225, 2, 0, 0,227, 2, 0, 0, 5, 0, 0, 0,
+ 17, 0, 0, 0,207, 2, 0, 0,227, 2, 0, 0, 68, 65, 84, 65, 16, 1, 0, 0, 48,210,163, 2,137, 0, 0, 0, 1, 0, 0, 0,
+112,211,163, 2,136,209,163, 2, 6, 0, 0, 0, 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 67, 0, 0,120,190, 0, 0,159, 63, 0, 0,242,190,
+ 0,128,188, 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,124, 1, 0, 0, 0, 0, 0, 0,242, 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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,139,192, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,140,208, 2,236,138,176, 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, 82,101,110,100,101,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,208, 1, 0, 0,112,211,163, 2,136, 0, 0, 0,
+ 1, 0, 0, 0,112,213,163, 2, 48,210,163, 2, 3, 0, 0, 0, 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 67, 0, 0,209,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 67,
+ 0, 0,190,195, 0, 0, 0,181, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0,190,195, 0, 0,190,195,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 1, 0, 1, 0, 1, 0, 1, 0,108, 1,124, 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,142, 3, 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, 1, 64, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,140,208, 0, 0, 0,137, 0, 0, 0, 1, 2,236,141,224, 2,236,139,192,
- 65,110,105,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 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,128, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,141,224, 0, 0, 0,137, 0, 0, 0, 1, 2,236,142,240, 2,236,140,208, 70,111,114,109, 97,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, 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, 68, 65, 84, 65,176, 0, 0, 0,112,213,163, 2,
+216, 0, 0, 0, 1, 0, 0, 0, 80,214,163, 2,112,211,163, 2, 11, 0, 0, 0, 51, 51, 51, 63,104,250,126, 2, 0, 0,128,192,
+ 0, 0,122, 67, 0, 0,128,192, 0, 0,127, 67, 0, 0,128,192, 0, 0, 72, 66, 0, 0,128,192, 0, 0,127, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,
+124, 1, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0,128, 63, 0,128,129, 67, 0, 0,250, 70, 0,128,129, 67,205,204,204, 61,
+ 0, 0, 32, 65, 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, 68, 65, 84, 65,180, 0, 0, 0,
+ 80,214,163, 2,138, 0, 0, 0, 1, 0, 0, 0,176,186,132, 2,112,213,163, 2, 13, 0, 0, 0, 51, 51, 51, 63,104,250,126, 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,128, 63, 0, 0,122, 68,
+ 0, 0, 0, 0, 0, 0,122, 68, 0, 0,160,192, 0, 0,130, 66, 0, 0, 0, 0, 0, 0,182, 67,108, 1, 0, 0,124, 1, 0, 0,
+ 0, 0, 0, 0,124, 1, 0, 0,196, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,196, 0, 0, 0,108, 1, 0, 0,
+ 16, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 68, 0, 0,122, 68,205,204,204, 61, 0, 0, 72, 66,
+ 10, 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,
+ 68, 65, 84, 65,192, 0, 0, 0,176,186,132, 2,226, 0, 0, 0, 1, 0, 0, 0,192,158,126, 2, 80,214,163, 2, 12, 0, 0, 0,
+ 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 2, 66,
+ 0, 0,122,196, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 2, 66, 0, 0,150,194, 0, 0,160, 64,108, 1, 0, 0,124, 1, 0, 0,
+ 0, 0, 0, 0, 14, 2, 0, 0,128, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 0,108, 1, 0, 0,
+ 16, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 70, 0, 0,122, 68, 10,215, 35, 60, 0, 0, 72, 66,
+ 10, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,120, 1, 0, 0,192,158,126, 2,
+135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176,186,132, 2, 5, 0, 0, 0, 51, 51, 51, 63,104,250,126, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 0, 0, 0, 83, 97,118,101, 32, 70,105,108,101, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101,114,115, 47,116,111,110, 47, 68,101,115,107,116,111,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, 3,192, 0, 0, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,142,240,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,144, 0, 2,236,141,224, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,
-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, 69,100,105,116,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,112,114,101,118,105,101,119, 46, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 82, 0,
+ 0, 0, 0, 0, 76, 1, 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,
+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,
+ 68, 65, 84, 65,204, 0, 0, 0, 24,120,126, 2,154, 0, 0, 0, 1, 0, 0, 0,160, 78,130, 2,104,250,126, 2, 32, 48,127, 2,
+104, 48,127, 2,216,108,163, 2,144,108,163, 2, 0, 0, 0, 0, 17, 38,238, 63, 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,225,215,163,188, 0, 0, 0, 0,105, 3, 0, 0,251, 5, 0, 0, 0, 0, 0, 0,123, 4, 0, 0,
+105, 3, 0, 0,251, 5, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0,105, 3, 0, 0,251, 5, 0, 0, 27, 0, 0, 0,123, 4, 0, 0,
+ 10, 0, 11, 0, 1, 0, 6, 6,147, 2, 97, 4, 1, 0, 1, 0,214, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 80,171,154, 2,120,126,126, 2, 72, 36,155, 2, 72, 36,155, 2, 56,104,163, 2, 88,133,152, 2,
+ 68, 65, 84, 65,228, 0, 0, 0, 56,104,163, 2,153, 0, 0, 0, 1, 0, 0, 0,192,168,154, 2, 0, 0, 0, 0, 84,114, 97,110,
+115,102,111,114,109, 32, 80,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, 0, 0, 0, 0, 0, 0, 0, 73,112,111, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,144, 0, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,145, 16, 2,236,142,240, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,167, 0,
+ 62, 1,204, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+192,168,154, 2,153, 0, 0, 0, 1, 0, 0, 0, 0,165,127, 2, 56,104,163, 2, 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, 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, 1, 64, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,145, 16, 0, 0, 0,137, 0, 0, 0, 1, 2,236,146, 32, 2,236,144, 0,
- 80,114,101,118,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,
- 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 0,165,127, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 56, 24,156, 2,192,168,154, 2, 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, 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, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,146, 32, 0, 0, 0,137, 0, 0, 0, 1, 2,236,147, 48, 2,236,145, 16, 76, 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, 76, 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, 64, 1, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 56, 24,156, 2,153, 0, 0, 0, 1, 0, 0, 0,224, 93,163, 2,
+ 0,165,127, 2, 65,110,105,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 24, 1, 62, 0,204,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,147, 48,
- 0, 0, 0,137, 0, 0, 0, 1, 2,236,148, 64, 2,236,146, 32, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,112,111,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, 76, 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,128, 2, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,224, 93,163, 2,153, 0, 0, 0, 1, 0, 0, 0,248, 94,163, 2, 56, 24,156, 2, 70,111,114,109,
+ 97,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, 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, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,148, 64, 0, 0, 0,137, 0, 0, 0, 1,
- 2,236,149, 80, 2,236,147, 48, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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,192, 3, 0, 0,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+248, 94,163, 2,153, 0, 0, 0, 1, 0, 0, 0,120,125,165, 2,224, 93,163, 2, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,
+101,114,105, 97,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, 69,100,105,116,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,120,125,165, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,144,126,165, 2,248, 94,163, 2, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,228, 2,236,149, 80, 0, 0, 0,137, 0, 0, 0, 1, 2,236,150, 96, 2,236,148, 64,
- 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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,
- 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,144,126,165, 2,153, 0, 0, 0, 1, 0, 0, 0,168,127,165, 2,
+120,125,165, 2, 80,114,101,118,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,253, 72, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,148, 64, 68, 65, 84, 65,
- 0, 0, 0,228, 2,236,150, 96, 0, 0, 0,137, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,149, 80, 84,114, 97,110,115,102,111,114,
-109, 32, 80,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, 0, 0, 0, 0, 0, 0, 0, 86,105,101,119, 51,100, 0, 0,
+ 0, 0, 0, 0, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228, 1, 62, 0,204,
- 0, 0, 0, 0, 0,162, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 3, 0, 5, 30,232, 32,
- 0, 0, 0,113, 0, 0, 0, 1, 2,236,151,112, 0, 0, 0, 0, 0, 0, 0, 1, 63, 51, 51, 51, 2,236,136,160, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 37,127,255,255, 37,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 51,160, 0, 0,191,128, 0, 0, 0, 0, 0, 0,165,128, 0, 0, 63,128, 0, 0, 51,162, 33,104, 0, 0, 0, 0, 60, 41,199, 78,
-191,230,129,210,193, 30,230,225, 63,128, 0, 0, 63,128, 0, 0, 37,127,255,254,165,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0,191,128, 0, 1, 51,160, 0, 0, 0, 0, 0, 0,188, 41,199, 79,
-193, 30,230,226, 63,230,129,216, 63,128, 0, 0, 63, 79, 65,254, 37,132,161, 17,165,153,211,206,165,128, 0, 0, 61, 60, 82,171,
- 60,131, 1,253, 63,153,211,206, 63,128, 0, 0,177,110,137,200, 63,134,173, 25,179,194,216, 54,179,162, 33,104, 62,238, 21, 90,
-191,222, 51, 78,190, 61,126, 0, 65, 30,230,225, 63,158, 26, 70, 37,158, 26, 69,165,158, 26, 71,153,128, 0, 0, 0, 0, 0, 0,
- 51,144, 0, 0, 63,115, 79, 65, 0, 0, 0, 0, 58, 96, 32, 0, 63, 81,196, 5,190, 24, 37, 84,189,168,248,231,189,108,210, 23,
- 60,122, 37,233, 62, 39, 71,242, 61,203, 17, 30, 63, 79, 65,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,134,173, 25, 0, 0, 0, 0, 0, 0, 0, 0,189, 60, 82,171,188,131, 1,211,191,153,211,206,191,128, 0, 0,128, 0, 0, 0,
-128, 0, 0, 0,193, 65,236,225,128, 0, 0, 0, 63,128, 0, 0, 37,127,255,255, 37,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 51,160, 0, 0,191,128, 0, 0, 0, 0, 0, 0,165,128, 0, 0, 63,128, 0, 0, 51,162, 33,104, 0, 0, 0, 0, 60, 41,199, 78,
-191,230,129,210,193, 30,230,225, 63,128, 0, 0, 63, 53, 4,244,191, 53, 4,243,165, 53, 4,243, 36,181, 4,242, 65, 98,160,147,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 5, 30,248, 32, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,168,127,165, 2,153, 0, 0, 0, 1, 0, 0, 0,192,128,165, 2,144,126,165, 2, 76, 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, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0,255,251, 0, 0, 66, 12, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 59, 37,224,208, 60, 35,215, 10, 67,250, 0, 0,188,218, 18,228,188, 23,180, 37, 62, 24, 35, 81,
-190, 55, 52, 64,191,230,153,244, 54,224, 0, 0, 63, 88,146, 56, 64, 71, 37,198, 0, 20, 0, 0, 0, 7, 0,207, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0,255,255, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,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, 24, 8, 0, 0, 0, 10,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,204, 2,236,151,112, 0, 0, 0,118, 0, 0, 0, 1, 2,236,152,112,
- 5, 30,232, 32, 0, 0, 0, 4, 0, 0, 0, 0, 2,236,136,160, 0, 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, 4, 0, 0, 0, 0, 68,160, 0, 0,196, 46, 0, 0, 67,100, 0, 0, 55,136,197,197,
- 68, 78,209,118,195,231,222, 40, 67, 25,158,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0,
- 66, 40, 0, 0, 69, 0, 0, 0, 67,225, 0, 0, 63, 0, 0, 0, 63,154,225, 72, 0, 0, 0, 1, 0, 1, 0, 1, 3,233, 2,235,
- 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 1,150, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 4, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 40, 2,236,152,112, 0, 0, 0,117, 0, 0, 0, 1, 2,236,153,192,
- 2,236,151,112, 0, 0, 0, 2, 63, 51, 51, 51, 2,236,136,160, 0, 0, 0, 0, 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,122, 0, 0,189,204,204,205, 63,140,204,205, 63,128, 0, 0, 67,122, 0, 0,
-192,160, 0, 0, 64,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 2,235, 0, 0, 0, 16, 0, 0, 3,168,
- 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 16, 0, 0, 2,235, 60, 35,215, 10, 60, 35,215, 10,
- 70,106, 96, 0, 68,122, 0, 0, 0, 0, 0, 0, 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, 5, 31, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,122, 0, 0,189,204,204,205,
- 63,140,204,205, 68, 65, 84, 65, 0, 0, 0,120, 2,236,153,192, 0, 0, 0,124, 0, 0, 0, 1, 2,236,154, 96, 2,236,152,112,
- 0, 0, 0, 9, 63, 51, 51, 51, 2,236,136,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,183,112,
- 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 5, 0, 0, 0, 17, 0, 0, 2,225, 0, 0, 2,227,
- 0, 0, 0, 5, 0, 0, 0, 17, 0, 0, 2,207, 0, 0, 2,227, 68, 65, 84, 65, 0, 0, 0,248, 2,236,154, 96, 0, 0, 0,122,
- 0, 0, 0, 1, 2,236,155,128, 2,236,153,192, 0, 0, 0, 6, 63, 51, 51, 51, 2,236,136,160, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0, 0, 0, 0, 0, 67,128, 0, 0,190,120, 0, 0, 63,159, 0, 0,
-190,242, 0, 0, 63,188,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,124, 0, 0, 0, 0, 0, 0, 1,242, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 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, 63,128, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24,255,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+192,128,165, 2,153, 0, 0, 0, 1, 0, 0, 0, 40,131,152, 2,168,127,165, 2, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,
+112,111,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,254, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 40,131,152, 2,153, 0, 0, 0,
+ 1, 0, 0, 0, 64,132,152, 2,192,128,165, 2, 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 64,132,152, 2,153, 0, 0, 0, 1, 0, 0, 0, 88,133,152, 2,
+ 40,131,152, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,131,152, 2,
+ 68, 65, 84, 65,228, 0, 0, 0, 88,133,152, 2,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64,132,152, 2, 84,114, 97,110,
+115,102,111,114,109, 32, 80,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, 0, 0, 0, 0, 0, 0, 0, 86,105,101,119,
+ 51,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,228, 0,
+ 62, 1,204, 0, 0, 0, 0, 0,162, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 16, 1, 0, 0,
+ 80,171,154, 2,137, 0, 0, 0, 1, 0, 0, 0,184,208,127, 2, 0, 0, 0, 0, 6, 0, 0, 0, 51, 51, 51, 63, 24,120,126, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 67,
+ 0,128, 73,191, 0,192,228, 63, 0, 64,216,191, 0, 32, 44, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,147, 2, 0, 0, 0, 0, 0, 0, 97, 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, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,255, 0, 0, 0, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0,248, 2,236,155,128, 0, 0, 0,121, 0, 0, 0, 1, 2,236,156,160, 2,236,154, 96, 0, 0, 0, 3, 63, 51, 51, 51,
- 2,236,136,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,182, 0, 0,195,209, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 67,182, 0, 0,195,190, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0,
- 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 1,124, 0, 0, 0, 0,
- 0, 0, 1,124,195,190, 0, 0,195,190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1,
- 0, 1, 0, 1, 1,108, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,142, 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, 68, 65, 84, 65, 0, 0, 0,160, 2,236,156,160, 0, 0, 0,194, 0, 0, 0, 1, 2,236,157,112,
- 2,236,155,128, 0, 0, 0, 11, 63, 51, 51, 51, 2,236,136,160,192,128, 0, 0, 67,122, 0, 0,192,128, 0, 0, 67,127, 0, 0,
-192,128, 0, 0, 66, 72, 0, 0,192,128, 0, 0, 67,127, 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,124, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0, 16, 0, 0, 1,124,
- 63,128, 0, 0, 67,129,128, 0, 70,250, 0, 0, 67,129,128, 0, 61,204,204,205, 65, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0,184,208,127, 2,128, 0, 0, 0, 1, 0, 0, 0,144,197,126, 2, 80,171,154, 2, 1, 0, 0, 0, 51, 51, 51, 63,
+ 24,120,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 75, 64, 63,119,102,191, 62, 11, 73, 11,191,
+ 0, 0, 0, 0,108,254, 40,191, 94,202,217, 62,246,124, 30,191, 0, 0, 0, 0,218, 33,186,180,184,254, 82, 63,193,248, 16, 63,
+ 0, 0, 0, 0, 73,228, 8, 62, 72,158, 33,192,125,148,210,193, 0, 0,128, 63, 68, 75, 64, 63,161,254, 40,191,101,221, 58, 54,
+ 0, 0, 0, 0, 10,103,191, 62,178,202,217, 62, 4,255, 82, 63, 0, 0, 0, 0, 20, 73, 11,191, 78,125, 30,191,219,248, 16, 63,
+ 0, 0, 0, 0, 3,166, 87,193, 19, 36,114,193,213,230,135, 65, 0, 0,128, 63,132,226,178, 63, 18, 88,209, 62,121, 74, 11, 63,
+ 11, 73, 11, 63,169, 53,157,191, 87, 53,238, 62,150,126, 30, 63,246,124, 30, 63, 38, 39, 45,181,153,198,102, 63, 62,250, 16,191,
+193,248, 16,191, 46,177,126, 62, 31,197, 48,192,176,109,210, 65,125,148,210, 65,119,202,206, 62,194,145,181,190, 62, 1, 84,185,
+188, 79, 73,183, 32,236,174, 62,100, 10,199, 62, 33,245, 64, 63, 0,160, 52, 55, 84, 79, 40, 68,158,252, 60, 68, 68, 35, 84,196,
+165,205, 71,194, 68, 46, 40,196,248,214, 60,196, 62, 1, 84, 68,188,207, 71, 66, 17, 38,238, 63, 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,225,215,163,188, 0, 0, 0, 0, 54, 75, 64, 63,119,102,191, 62, 11, 73, 11,191,
+ 0, 0, 0, 0,108,254, 40,191, 94,202,217, 62,246,124, 30,191, 0, 0, 0, 0,218, 33,186,180,184,254, 82, 63,193,248, 16, 63,
+ 0, 0, 0, 0, 73,228, 8, 62, 72,158, 33,192,125,148,210,193, 0, 0,128, 63, 84,252, 83, 63,104, 25,223,190,115, 52, 40, 62,
+119,211,159, 62, 96,183,198, 65, 96,183,198, 65, 0, 0, 0, 0, 1, 0, 0, 0,160, 26,156, 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, 2, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 1, 0, 0, 0,
+251,255, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63,174,207,213, 58, 10,215, 35, 60, 0, 0,250, 67,228, 18,218,188,
+ 37,180, 23,188,163,146, 22,189,174, 51,122,190, 29,244, 58,192, 0, 0,224, 54, 56,146, 88, 63,198, 37, 71, 64, 20, 0, 0, 0,
+ 7, 0,115, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,255,255, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 24, 24, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0,144,197,126, 2,133, 0, 0, 0,
+ 1, 0, 0, 0, 96,221,128, 2,184,208,127, 2, 4, 0, 0, 0, 0, 0, 0, 0, 24,120,126, 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, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0,160, 68, 0, 0, 46,196,
+ 0, 0,100, 67,197,197,136, 55,118,209, 78, 68, 40,222,231,195,172,158, 25, 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, 0, 0, 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, 67, 0, 0, 40, 66, 0, 0, 0, 69, 0, 0,225, 67, 0, 0, 0, 63, 72,225,154, 63, 0, 0, 1, 0,
+ 1, 0, 1, 0,233, 3,235, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0,150, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 68, 65, 84, 65, 88, 1, 0, 0, 96,221,128, 2,132, 0, 0, 0, 1, 0, 0, 0, 24, 1,132, 2,144,197,126, 2, 2, 0, 0, 0,
+ 51, 51, 51, 63, 24,120,126, 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,122, 67,205,204,204,189,205,204,140, 63, 0, 0,128, 63, 0, 0,122, 67, 0, 0,160,192, 0, 0,160, 64,
+ 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,235, 2, 0, 0, 16, 0, 0, 0,168, 3, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 16, 0, 0, 0,168, 3, 0, 0, 16, 0, 0, 0,235, 2, 0, 0, 10,215, 35, 60, 10,215, 35, 60, 0, 96,106, 70, 0, 0,122, 68,
+ 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 88, 43,153, 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, 29, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 79, 66, 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,122, 67,205,204,204,189,205,204,140, 63, 68, 65, 84, 65,120, 0, 0, 0, 24, 1,132, 2,139, 0, 0, 0, 1, 0, 0, 0,
+240,220,126, 2, 96,221,128, 2, 9, 0, 0, 0, 51, 51, 51, 63, 24,120,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,192,199,156, 2, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 12, 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,205,204,204, 61, 5, 0, 0, 0, 17, 0, 0, 0,
+225, 2, 0, 0,227, 2, 0, 0, 5, 0, 0, 0, 17, 0, 0, 0,207, 2, 0, 0,227, 2, 0, 0, 68, 65, 84, 65,208, 1, 0, 0,
+240,220,126, 2,136, 0, 0, 0, 1, 0, 0, 0, 24,208,129, 2, 24, 1,132, 2, 3, 0, 0, 0, 51, 51, 51, 63, 24,120,126, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 67, 0, 0,209,195, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,182, 67, 0, 0,190,195, 0, 0, 0,181, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,124, 1, 0, 0,
+ 0, 0,190,195, 0, 0,190,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 1, 0, 1, 0, 1, 0, 1, 0,
+108, 1,124, 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,142, 3, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 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, 0, 0,164, 2,236,157,112, 0, 0, 0,123, 0, 0, 0, 1, 2,236,158, 64, 2,236,156,160, 0, 0, 0, 13, 63, 51, 51, 51,
- 2,236,136,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 68,122, 0, 0, 0, 0, 0, 0, 68,122, 0, 0,192,160, 0, 0, 66,130, 0, 0, 0, 0, 0, 0, 67,182, 0, 0, 0, 0, 1,108,
- 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0,196, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,196,
- 0, 0, 1,108, 0, 0, 0, 16, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 68,122, 0, 0, 68,122, 0, 0, 61,204,204,205,
- 66, 72, 0, 0, 0, 10, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,176, 2,236,158, 64,
- 0, 0, 0,203, 0, 0, 0, 1, 2,236,159, 32, 2,236,157,112, 0, 0, 0, 12, 63, 51, 51, 51, 2,236,136,160, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 0, 66, 2, 0, 0,193,128, 0, 0, 67,247, 0, 0,191, 0, 0, 0,
- 66, 2, 0, 0,193,128, 0, 0, 67,247, 0, 0, 0, 0, 1,108, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 2, 14, 0, 0, 0,128,
- 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 1,108, 0, 0, 0, 16, 0, 0, 2, 14, 0, 0, 0, 0,
- 0, 0, 0, 0, 70,250, 0, 0, 68,122, 0, 0, 60, 35,215, 10, 66, 72, 0, 0, 0, 10, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1,104,
- 2,236,159, 32, 0, 0, 0,120, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,158, 64, 0, 0, 0, 5, 63, 51, 51, 51, 2,236,136,160,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 97,118,101, 32, 70,105,108,
-101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101,114,115, 47,116,111,110, 47, 68,101,115,107,116,
-111,112, 47, 0,114, 47,114,101,108,101, 97,115,101, 47,100, 97,116, 97,102,105,108,101,115, 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,112,114,101,118,105,101,119, 46, 98,108,101,110,100, 0, 0, 0,
- 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8, 0, 46, 0, 0, 0, 0, 1, 85, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4,156, 5, 30,236, 32,
- 0, 0, 0,111, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67,112,114,101,118,105,101,
-119, 0, 0, 99,101,110,101, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 30,248, 32,
- 2,236,182, 32, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,160,176, 2,236,167,144, 2,236,165,176, 63,149,213, 84,193, 7,238,126,
- 63,142,109, 36, 55,142, 84, 52,192,188, 12,194, 64, 71, 38, 28, 55,142, 84, 52,192,188, 12,194, 64, 71, 38, 28, 55,142, 84, 52,
-192,188, 12,194, 64, 71, 38, 28, 0, 0, 0, 1, 62,214,245, 65, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236,167,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,168, 48, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 20,
- 0, 0, 0,100, 0, 0, 0,100, 0, 0, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2,128, 1,224, 0, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 25, 0,141, 2, 88,
- 2, 88, 0,100, 0,100, 0, 2, 0, 2, 0, 0, 0, 24, 0, 4, 0, 0, 0, 0, 0, 90, 0, 16, 0, 0, 0, 0, 0, 0, 0, 64,
- 0, 0, 0, 0, 0, 0, 0, 5, 0, 25, 0, 10, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,236,168,176,
- 2,236,168,176, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 5, 0, 2, 0, 1, 0, 1, 0, 0, 0, 0,
+176, 0, 0, 0, 24,208,129, 2,216, 0, 0, 0, 1, 0, 0, 0,104,219,126, 2,240,220,126, 2, 11, 0, 0, 0, 51, 51, 51, 63,
+ 24,120,126, 2, 0, 0,128,192, 0, 0,122, 67, 0, 0,128,192, 0, 0,127, 67, 0, 0,128,192, 0, 0, 72, 66, 0, 0,128,192,
+ 0, 0,127, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0,128, 63, 0,128,129, 67, 0, 0,250, 70,
+ 0,128,129, 67,205,204,204, 61, 0, 0, 32, 65, 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,
+ 68, 65, 84, 65,180, 0, 0, 0,104,219,126, 2,138, 0, 0, 0, 1, 0, 0, 0,176, 72,130, 2, 24,208,129, 2, 13, 0, 0, 0,
+ 51, 51, 51, 63, 24,120,126, 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,128, 63, 0, 0,122, 68, 0, 0, 0, 0, 0, 0,122, 68, 0, 0,160,192, 0, 0,130, 66, 0, 0, 0, 0, 0, 0,182, 67,
+108, 1, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,124, 1, 0, 0,196, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+196, 0, 0, 0,108, 1, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 68, 0, 0,122, 68,
+205,204,204, 61, 0, 0, 72, 66, 10, 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, 68, 65, 84, 65,192, 0, 0, 0,176, 72,130, 2,226, 0, 0, 0, 1, 0, 0, 0,120,126,126, 2,
+104,219,126, 2, 12, 0, 0, 0, 51, 51, 51, 63, 24,120,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,191, 0, 0, 2, 66, 0, 0,122,196, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 2, 66, 0, 0,150,194, 0, 0,160, 64,
+108, 1, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0,128, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+128, 0, 0, 0,108, 1, 0, 0, 16, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,250, 70, 0, 0,122, 68,
+ 10,215, 35, 60, 0, 0, 72, 66, 10, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+120, 1, 0, 0,120,126,126, 2,135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,176, 72,130, 2, 5, 0, 0, 0, 51, 51, 51, 63,
+ 24,120,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 83, 97,118,101,
+ 32, 70,105,108,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101,114,115, 47,116,111,110, 47, 68,
+101,115,107,116,111,112, 47, 0,114, 47,114,101,108,101, 97,115,101, 47,100, 97,116, 97,102,105,108,101,115, 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,112,114,101,118,105,101,119, 46, 98,108,101,110,
+100, 0, 0, 0, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 46, 0, 0, 0, 0, 0, 85, 1, 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, 72, 0, 0, 0, 0, 0, 0, 0, 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,204, 0, 0, 0,160, 78,130, 2,154, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 24,120,126, 2,224,106,163, 2, 0,108,163, 2,104, 48,127, 2, 32, 48,127, 2, 0, 0, 0, 0, 33,250,179, 63, 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,225,215,163,188, 0, 0, 0, 0, 0, 0, 0, 0,103, 3, 0, 0,
+ 0, 0, 0, 0,123, 4, 0, 0, 0, 0, 0, 0,103, 3, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0,103, 3, 0, 0,
+ 27, 0, 0, 0,123, 4, 0, 0, 8, 0, 9, 0, 1, 0, 1, 1,104, 3, 97, 4, 1, 0, 1, 0,216, 2, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,112,229,163, 2, 0,191,126, 2,152,251,149, 2,152,251,149, 2,
+120,248,164, 2,192, 25, 16, 3, 68, 65, 84, 65,228, 0, 0, 0,120,248,164, 2,153, 0, 0, 0, 1, 0, 0, 0, 40,144, 16, 3,
+ 0, 0, 0, 0, 84,114, 97,110,115,102,111,114,109, 32, 80,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, 0, 0, 0,
+ 0, 0, 0, 0, 73,112,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0,167, 0, 62, 1,204, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 40,144, 16, 3,153, 0, 0, 0, 1, 0, 0, 0,152,189,177, 2,120,248,164, 2, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+152,189,177, 2,153, 0, 0, 0, 1, 0, 0, 0,152, 15,132, 2, 40,144, 16, 3, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,152, 15,132, 2,153, 0, 0, 0,
+ 1, 0, 0, 0,120,113,126, 2,152,189,177, 2, 65,110,105,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,120,113,126, 2,153, 0, 0, 0, 1, 0, 0, 0, 40,142, 8, 3,
+152, 15,132, 2, 70,111,114,109, 97,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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 0, 0, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0, 40,142, 8, 3,153, 0, 0, 0, 1, 0, 0, 0, 88,234,163, 2,120,113,126, 2, 76,105,110,107,
+ 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,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, 69,100,105,116,
+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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+ 88,234,163, 2,153, 0, 0, 0, 1, 0, 0, 0, 24, 6, 16, 3, 40,142, 8, 3, 67, 97,109,101,114, 97, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0, 24, 6, 16, 3,153, 0, 0, 0,
+ 1, 0, 0, 0,120,128,150, 2, 88,234,163, 2, 80,114,101,118,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,120,128,150, 2,153, 0, 0, 0, 1, 0, 0, 0,216, 86,155, 2,
+ 24, 6, 16, 3, 76, 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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24,255, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,228, 0, 0, 0,216, 86,155, 2,153, 0, 0, 0, 1, 0, 0, 0,240, 87,155, 2,120,128,150, 2, 83,104, 97,100,
+111,119, 32, 97,110,100, 32, 83,112,111,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, 76, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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,254,
+ 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,
+240, 87,155, 2,153, 0, 0, 0, 1, 0, 0, 0,168, 24, 16, 3,216, 86,155, 2, 84,101,120,116,117,114,101, 32, 97,110,100, 32,
+ 73,110,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, 76, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,228, 0, 0, 0,168, 24, 16, 3,153, 0, 0, 0,
+ 1, 0, 0, 0,192, 25, 16, 3,240, 87,155, 2, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,253, 62, 1,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,240, 87,155, 2, 68, 65, 84, 65,228, 0, 0, 0,192, 25, 16, 3,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+168, 24, 16, 3, 84,114, 97,110,115,102,111,114,109, 32, 80,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, 0, 0, 0,
+ 0, 0, 0, 0, 86,105,101,119, 51,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,228, 0, 62, 1,204, 0, 0, 0, 0, 0,162, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 0, 3, 0, 0,112,229,163, 2,128, 0, 0, 0, 1, 0, 0, 0, 24, 79,161, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+ 51, 51, 51, 63,160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 75, 64, 63,119,102,191, 62,
+ 11, 73, 11,191, 0, 0, 0, 0,108,254, 40,191, 94,202,217, 62,246,124, 30,191, 0, 0, 0, 0,218, 33,186,180,184,254, 82, 63,
+193,248, 16, 63, 0, 0, 0, 0, 73,228, 8, 62, 72,158, 33,192,125,148,210,193, 0, 0,128, 63, 68, 75, 64, 63,161,254, 40,191,
+101,221, 58, 54, 0, 0, 0, 0, 10,103,191, 62,178,202,217, 62, 4,255, 82, 63, 0, 0, 0, 0, 20, 73, 11,191, 78,125, 30,191,
+219,248, 16, 63, 0, 0, 0, 0, 3,166, 87,193, 19, 36,114,193,213,230,135, 65, 0, 0,128, 63,121, 48,135, 63, 18, 88,209, 62,
+121, 74, 11, 63, 11, 73, 11, 63, 8,158,109,191, 87, 53,238, 62,150,126, 30, 63,246,124, 30, 63,136,219, 2,181,153,198,102, 63,
+ 62,250, 16,191,193,248, 16,191,191,122, 64, 62, 31,197, 48,192,176,109,210, 65,125,148,210, 65,160,194, 8, 63,174, 96,240,190,
+ 0, 0, 0, 0, 0, 0, 16,180,218, 0,175, 62,170, 33,199, 62, 18,232, 64, 63, 0, 0,130,181, 53,114, 40, 68,198, 35, 61, 68,
+ 59, 79, 84,196, 14,247, 71,194, 30, 81, 40,196, 25,254, 60,196, 44, 45, 84, 68, 28,249, 71, 66, 33,250,179, 63, 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,225,215,163,188, 0, 0, 0, 0, 54, 75, 64, 63,119,102,191, 62,
+ 11, 73, 11,191, 0, 0, 0, 0,108,254, 40,191, 94,202,217, 62,246,124, 30,191, 0, 0, 0, 0,218, 33,186,180,184,254, 82, 63,
+193,248, 16, 63, 0, 0, 0, 0, 73,228, 8, 62, 72,158, 33,192,125,148,210,193, 0, 0,128, 63, 84,252, 83, 63,104, 25,223,190,
+115, 52, 40, 62,119,211,159, 62, 96,183,198, 65, 96,183,198, 65, 0, 0, 0, 0, 1, 0, 0, 0,160, 26,156, 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, 2, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
+ 1, 0, 0, 0,251,255, 0, 0, 0, 0, 12, 66, 0, 0,128, 63, 0, 0,128, 63,232,205,213, 58, 10,215, 35, 60, 0, 0,250, 67,
+228, 18,218,188, 37,180, 23,188,163,146, 22,189,174, 51,122,190, 29,244, 58,192, 0, 0,224, 54, 56,146, 88, 63,198, 37, 71, 64,
+ 20, 0, 0, 0, 7, 0,207, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,255,255, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 24, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,220, 0, 0, 0, 24, 79,161, 2,
+133, 0, 0, 0, 1, 0, 0, 0, 72,188,147, 2,112,229,163, 2, 4, 0, 0, 0, 0, 0, 0, 0,160, 78,130, 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, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0,160, 68,
+ 0, 0, 46,196, 0, 0,100, 67,197,197,136, 55,118,209, 78, 68, 40,222,231,195,172,158, 25, 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, 0, 0, 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, 67, 0, 0, 40, 66, 0, 0, 0, 69, 0, 0,225, 67, 0, 0, 0, 63, 72,225,154, 63,
+ 0, 0, 1, 0, 1, 0, 1, 0,233, 3,235, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0,150, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 68, 65, 84, 65, 88, 1, 0, 0, 72,188,147, 2,132, 0, 0, 0, 1, 0, 0, 0,176,233,163, 2, 24, 79,161, 2,
+ 2, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 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,122, 67,205,204,204,189,205,204,140, 63, 0, 0,128, 63, 0, 0,122, 67, 0, 0,160,192,
+ 0, 0,160, 64, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,235, 2, 0, 0, 16, 0, 0, 0,168, 3, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 16, 0, 0, 0,168, 3, 0, 0, 16, 0, 0, 0,235, 2, 0, 0, 10,215, 35, 60, 10,215, 35, 60, 0, 96,106, 70,
+ 0, 0,122, 68, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 88, 43,153, 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,
+ 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 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,122, 67,205,204,204,189,205,204,140, 63, 68, 65, 84, 65,120, 0, 0, 0,176,233,163, 2,139, 0, 0, 0,
+ 1, 0, 0, 0,144,212,166, 2, 72,188,147, 2, 9, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,192,199,156, 2, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 12, 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,205,204,204, 61, 5, 0, 0, 0,
+ 17, 0, 0, 0,225, 2, 0, 0,227, 2, 0, 0, 5, 0, 0, 0, 17, 0, 0, 0,207, 2, 0, 0,227, 2, 0, 0, 68, 65, 84, 65,
+ 16, 1, 0, 0,144,212,166, 2,137, 0, 0, 0, 1, 0, 0, 0,152,235,163, 2,176,233,163, 2, 6, 0, 0, 0, 51, 51, 51, 63,
+160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0,
+ 0, 0,128, 67, 0, 0,120,190, 0, 0,159, 63, 0, 0,242,190, 0,128,188, 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,124, 1, 0, 0, 0, 0, 0, 0,
+242, 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, 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, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,208, 1, 0, 0,152,235,163, 2,136, 0, 0, 0, 1, 0, 0, 0,152,237,163, 2,144,212,166, 2, 3, 0, 0, 0,
+ 51, 51, 51, 63,160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 67,
+ 0, 0,209,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,182, 67, 0, 0,190,195, 0, 0, 0,181, 0, 0, 0, 0, 16, 0, 0, 0,
+ 0, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,124, 1, 0, 0,
+ 0, 0, 0, 0,124, 1, 0, 0, 0, 0,190,195, 0, 0,190,195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 1, 0, 1, 0, 1, 0, 1, 0,108, 1,124, 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,142, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,176, 0, 0, 0,152,237,163, 2,216, 0, 0, 0, 1, 0, 0, 0,120,238,163, 2,152,235,163, 2,
+ 11, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 2, 0, 0,128,192, 0, 0,122, 67, 0, 0,128,192, 0, 0,127, 67, 0, 0,128,192,
+ 0, 0, 72, 66, 0, 0,128,192, 0, 0,127, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+124, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0,124, 1, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0,128, 63,
+ 0,128,129, 67, 0, 0,250, 70, 0,128,129, 67,205,204,204, 61, 0, 0, 32, 65, 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, 68, 65, 84, 65,180, 0, 0, 0,120,238,163, 2,138, 0, 0, 0, 1, 0, 0, 0, 96,239,163, 2,
+152,237,163, 2, 13, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 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,128, 63, 0, 0,122, 68, 0, 0, 0, 0, 0, 0,122, 68, 0, 0,160,192, 0, 0,130, 66,
+ 0, 0, 0, 0, 0, 0,182, 67,108, 1, 0, 0,124, 1, 0, 0, 0, 0, 0, 0,124, 1, 0, 0,196, 0, 0, 0,108, 1, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0,196, 0, 0, 0,108, 1, 0, 0, 16, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,122, 68, 0, 0,122, 68,205,204,204, 61, 0, 0, 72, 66, 10, 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, 68, 65, 84, 65,192, 0, 0, 0, 96,239,163, 2,226, 0, 0, 0,
+ 1, 0, 0, 0, 0,191,126, 2,120,238,163, 2, 12, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 2, 66, 0, 0,122,196, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 2, 66,
+ 0, 0,150,194, 0, 0,160, 64,108, 1, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0,128, 0, 0, 0,108, 1, 0, 0,
+ 0, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 0,108, 1, 0, 0, 16, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,250, 70, 0, 0,122, 68, 10,215, 35, 60, 0, 0, 72, 66, 10, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,120, 1, 0, 0, 0,191,126, 2,135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 96,239,163, 2,
+ 5, 0, 0, 0, 51, 51, 51, 63,160, 78,130, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 86, 0, 0, 0, 83, 97,118,101, 32, 70,105,108,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101,
+114,115, 47,116,111,110, 47, 68,101,115,107,116,111,112, 47, 0,114, 47,114,101,108,101, 97,115,101, 47,100, 97,116, 97,102,105,
+108,101,115, 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,112,114,101,118,
+105,101,119, 46, 98,108,101,110,100, 0, 0, 0, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 46, 0, 0, 0, 0, 0, 85, 1, 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, 72, 0, 0, 0, 0, 0, 0, 0, 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, 20, 5, 0, 0,240, 36,130, 2,126, 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,112,114,101,118,105,101,119, 0, 0, 99,
+101,110,101, 46, 48, 48, 49, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,160, 26,156, 2,104, 7, 16, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 64,116, 8, 3,104,109, 8, 3,224,116, 8, 3, 84,213,149, 63,126,238, 7,193, 36,109,142, 63,
+ 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 64, 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 64, 52, 84,142, 55,194, 12,188,192,
+ 28, 38, 71, 64, 0, 4, 0, 0, 65,245,214, 62, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 96,251,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 22,162, 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, 2, 0, 0, 0, 1, 0, 0, 0, 20, 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,
+ 0, 0, 25, 0,141, 0, 88, 2, 88, 2,100, 0,100, 0, 2, 0, 2, 0, 0, 0, 24, 0, 4, 0, 0, 0, 0, 0, 90, 0, 16, 0,
+ 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 5, 0, 25, 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, 40,172,132, 2, 40,172,132, 2, 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, 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, 47, 47, 98, 97,
@@ -1030,861 +1358,9 @@ char datatoc_preview_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, 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, 47, 47,102,116,
-121,112,101, 0, 64, 38, 35, 0, 0, 0, 0, 0, 64, 94, 0, 0, 64, 38, 94, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,172, 68,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 2,233, 81,160, 0, 1, 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, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,160,176, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,161, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 0, 1,255, 1,124, 5, 31, 4, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,161, 0,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,161, 80, 2,236,160,176, 0, 0, 4, 14, 0, 0, 0, 1, 0, 0, 0, 0, 1,255, 1,252,
- 5, 31, 0, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,161, 80, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,161,160, 2,236,161, 0,
- 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1,203, 1, 72, 5, 31, 76, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,161,160,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,161,240, 2,236,161, 80, 0, 0, 0, 32, 0, 0, 0, 4, 0, 0, 16, 0, 46,224, 1, 49,
- 5, 31, 40, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,161,240, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,162, 64, 2,236,161,160,
- 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 0, 1,255, 1,124, 5, 31, 44, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,162, 64,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,162,144, 2,236,161,240, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 20, 0, 46,224, 0, 52,
- 5, 31, 36, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,162,144, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,162,224, 2,236,162, 64,
- 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 20, 0, 46,224, 0, 47, 5, 31, 32, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,162,224,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,163, 48, 2,236,162,144, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 20, 0, 46,224, 1, 85,
- 5, 31, 28, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,163, 48, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,163,128, 2,236,162,224,
- 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 20, 0, 46,224, 0,158, 5, 31, 24, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,163,128,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,163,208, 2,236,163, 48, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 20, 0, 46,224, 0,100,
- 5, 31, 20, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,163,208, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,164, 32, 2,236,163,128,
- 0, 0, 0, 4, 0, 0, 0, 11, 0, 0, 0, 0, 1,254, 1,152, 5, 31, 72, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,164, 32,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,164,112, 2,236,163,208, 0, 0, 4, 14, 0, 0, 0, 5, 0, 0, 0, 0, 1,255, 1,252,
- 5, 30,252, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,164,112, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,164,192, 2,236,164, 32,
- 0, 0, 0, 64, 0, 0, 0, 13, 0, 0, 16, 0, 1,252, 2,162, 5, 31, 64, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,164,192,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,165, 16, 2,236,164,112, 0, 0, 0, 64, 0, 0, 0, 14, 0, 0, 0, 0, 1,249, 1,199,
- 5, 31, 68, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,165, 16, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,165, 96, 2,236,164,192,
- 0, 0, 0, 32, 0, 0, 0, 15, 0, 0, 0, 0, 1,253, 1,124, 5, 31, 80, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,165, 96,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,165,176, 2,236,165, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1,254, 1,125,
- 5, 31, 60, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,165,176, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,166, 0, 2,236,165, 96,
- 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1, 1,253, 1,125, 5, 31, 48, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,166, 0,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,166, 80, 2,236,165,176, 0, 0, 4, 28, 0, 0, 0, 2, 0, 0, 20, 0, 46,224, 1,152,
- 5, 31, 8, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,166, 80, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,166,160, 2,236,166, 0,
- 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 1,254, 1,125, 5, 31, 56, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,166,160,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,166,240, 2,236,166, 80, 0, 0, 4, 28, 0, 0, 0, 3, 0, 0, 20, 0, 46,224, 0, 44,
- 5, 31, 16, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,166,240, 0, 0, 0, 98, 0, 0, 0, 1, 2,236,167, 64, 2,236,166,160,
- 0, 0, 0, 8, 0, 0, 0, 21, 0, 0, 0, 0, 1,194, 1,152, 5, 31, 52, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,167, 64,
- 0, 0, 0, 98, 0, 0, 0, 1, 2,236,167,144, 2,236,166,240, 0, 0, 4, 28, 0, 0, 0, 4, 0, 0, 20, 0, 46,224, 0, 20,
- 5, 31, 12, 32, 68, 65, 84, 65, 0, 0, 0, 28, 2,236,167,144, 0, 0, 0, 98, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,167, 64,
- 0, 0, 5,223, 0, 0, 0, 6, 0, 0, 4, 0, 46,224, 0, 62, 5, 30,248, 32, 68, 65, 84, 65, 0, 0, 0, 40, 2,236,167,224,
- 0, 0, 0, 97, 0, 0, 0, 1, 1, 44, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 1, 1,244, 0,200, 0,100, 0, 20,
- 0, 0, 39, 16, 61,204,204,205, 65,240, 0, 0, 64, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 76, 2,236,168, 48, 0, 0, 0,108,
- 0, 0, 0, 1, 0, 1, 0, 1, 63, 76,204,205, 66,180, 0, 0, 0, 9, 0, 1, 63,128, 0, 0, 58,131, 18,111, 0, 32, 0, 32,
- 0, 32, 0, 1, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 56,209,183, 23, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 64, 2,236,168,176, 0, 0, 0,103,
- 0, 0, 0, 1, 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, 2,236,184, 64, 0, 15,255,255, 0, 0,127,255, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 73, 77, 0, 0, 1,116, 2,236,169, 32, 0, 0, 0, 28, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 73, 77, 73,109, 97,103,101, 46, 48, 48, 49, 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, 85,110,116,105,116,108,101,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,134,110,108,
- 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 67, 65, 0, 0, 0,128, 2,236,170,192, 0, 0, 0, 25, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 65, 67, 97,109,101,114, 97, 46, 48, 48, 49, 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, 12, 62, 76,204,205, 0, 0, 0, 0,
- 64,176, 39, 76, 66,112, 69,210, 65,240, 0, 0, 64,234, 14,161, 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, 76, 65, 0, 0, 1, 0, 2,236,171,112, 0, 0, 0, 36, 0, 0, 0, 1, 2,236,172,160, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 76, 65, 76, 97,109,112, 46, 48, 48, 50, 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, 2, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 65,160, 0, 0, 66,143,152,182, 62, 25,153,154, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0,
- 66, 32, 0, 0, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,172,160,
- 0, 0, 0, 36, 0, 0, 0, 1, 2,236,173,208, 2,236,171,112, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 64, 12,204,205, 65,239,255,247, 66,150, 0, 0,
- 62, 25,153,154, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0,
- 64, 64, 0, 0, 11, 64, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,173,208, 0, 0, 0, 36, 0, 0, 0, 1, 2,236,175, 0,
- 2,236,172,160, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 49, 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, 16, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,102,102,102, 65,239,255,247, 66,150, 0, 0, 62, 25,153,154, 63,128, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 11, 64, 0, 3, 0, 1, 0, 0,
- 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,175, 0, 0, 0, 0, 36, 0, 0, 0, 1, 2,236,176, 48, 2,236,173,208, 0, 0, 0, 0, 0, 0, 0, 0,
- 76, 65, 83,112,111,116, 46, 48, 48, 51, 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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 65,239,255,247, 66,150, 0, 0, 62, 25,153,154, 63,128, 0, 0, 63, 27,182,200, 63,128, 0, 0, 63,128, 26, 46, 65,240, 4, 25,
- 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 11, 64, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,176, 48, 0, 0, 0, 36,
- 0, 0, 0, 1, 2,236,177, 96, 2,236,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 52, 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, 16, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 62,204,204,205, 65,239,255,247, 66,150, 0, 0, 62, 25,153,154,
- 63,128, 0, 0, 63, 27,182,200, 63,128, 0, 0, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0,
- 11, 64, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,177, 96, 0, 0, 0, 36, 0, 0, 0, 1, 2,236,178,144, 2,236,176, 48,
- 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 53, 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, 16, 8, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63, 83, 78, 80, 65,239,255,247, 66,150, 0, 0, 62, 25,153,154, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 11, 64, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1,
- 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 1, 0,
- 2,236,178,144, 0, 0, 0, 36, 0, 0, 0, 1, 2,236,179,192, 2,236,177, 96, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,
-111,116, 46, 48, 48, 54, 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, 2, 0, 8, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,179, 51, 51, 65,239,255,247,
- 66, 72, 0, 0, 63, 8,156,171, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 65, 68,207, 78, 65,240, 4, 25, 66, 52, 0, 0,
- 63,128, 0, 0, 64, 64, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,179,192, 0, 0, 0, 36, 0, 0, 0, 1,
- 2,236,180,240, 2,236,178,144, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 55, 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, 16, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 65,239,255,247, 66,150, 0, 0, 62, 25,153,154, 63,128, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 11, 64, 0, 3,
- 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 2,236,180,240, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,179,192, 0, 0, 0, 0,
- 0, 0, 0, 0, 76, 65, 76, 97,109,112, 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, 1, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,192, 0, 0, 65,160, 0, 0, 66, 52, 0, 0, 62, 25,153,154, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0,
- 66, 32, 0, 0, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 1, 40, 2,236,182, 32,
- 0, 0, 0, 96, 0, 0, 0, 1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 79, 47,141, 62,209, 19, 64, 63, 14, 23, 73, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 28,204,205, 0, 0, 0, 0, 0, 1, 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, 64, 0, 0, 0,
- 0, 0, 0, 0, 65,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 32, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 61, 76,204,205, 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, 84, 88, 0, 0, 0,104, 2,236,183,112, 0, 0, 0, 23,
- 0, 0, 0, 1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
- 0, 0, 0, 1, 2,236,184, 0, 2,236,184, 0, 2,236,184, 0, 2,236,184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 30,242, 32,
-255,255,255,255, 0, 0, 4, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,184, 0, 0, 0, 0, 22, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,233, 30,112, 0, 0, 0, 0, 0, 0, 0, 0, 70, 82, 69, 69, 68, 65, 84, 65, 0, 0, 0, 4,
- 2,233, 30,112, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 71, 82, 0, 0, 0, 68, 2,236,184, 64, 0, 0, 0,196,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 82, 79,118,101,114,114,105,100,101, 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, 2,236,184,176, 2,236,186,240,
- 0, 15,255,255, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,184,176, 0, 0, 0,195, 0, 0, 0, 1, 2,236,184,240,
- 0, 0, 0, 0, 5, 31, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,184,240,
- 0, 0, 0,195, 0, 0, 0, 1, 2,236,185, 48, 2,236,184,176, 5, 31, 36, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 24, 2,236,185, 48, 0, 0, 0,195, 0, 0, 0, 1, 2,236,185,112, 2,236,184,240, 5, 31, 32, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,185,112, 0, 0, 0,195, 0, 0, 0, 1,
- 2,236,185,176, 2,236,185, 48, 5, 31, 28, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24,
- 2,236,185,176, 0, 0, 0,195, 0, 0, 0, 1, 2,236,185,240, 2,236,185,112, 5, 31, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,185,240, 0, 0, 0,195, 0, 0, 0, 1, 2,236,186, 48, 2,236,185,176,
- 5, 31, 20, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,186, 48, 0, 0, 0,195,
- 0, 0, 0, 1, 2,236,186,112, 2,236,185,240, 5, 31, 64, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0, 24, 2,236,186,112, 0, 0, 0,195, 0, 0, 0, 1, 2,236,186,176, 2,236,186, 48, 5, 31, 8, 32, 5,157,146, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,186,176, 0, 0, 0,195, 0, 0, 0, 1, 2,236,186,240,
- 2,236,186,112, 5, 31, 16, 32, 5,157,150, 32, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 2,236,186,240,
- 0, 0, 0,195, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,186,176, 5, 31, 12, 32, 5,157,154, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 79, 66, 0, 0, 3, 16, 5, 30,248, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 30,252, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,170,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,188, 41,199, 78,
-193, 30,230,225, 63,230,129,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, 37,128, 0, 0,
- 37,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 37,127,255,255,165,128, 0, 0, 0, 0, 0, 0,
- 37,127,255,255, 51,162, 33,105, 63,128, 0, 0, 0, 0, 0, 0, 37,128, 0, 0,191,128, 0, 0, 51,162, 33,105, 0, 0, 0, 0,
-188, 41,199, 78,193, 30,230,225, 63,230,129,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,137,145,110, 60, 24,136,133,160, 0, 0, 0, 0,
- 25,127,255,254, 63,128, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0,165,127,255,255,176,136, 90, 64, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 5,223, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 1,
- 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,
- 64, 0, 0, 0, 63,128, 0, 0, 63,100, 41, 6, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 63,100, 41, 6, 0, 0, 0, 0,
- 2, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 30,252, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 0, 32, 5, 30,248, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 99,104,101, 99,107,101,114,115, 46, 48, 48, 49, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0,
- 0, 1, 4, 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, 2,236,213, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,235, 92,144,
- 55,142, 84, 52,192,188, 12,194, 64, 71, 38, 28, 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,190, 36, 69, 64,190, 36, 69, 64,190, 36, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-128, 0, 0, 0, 63, 73, 15,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,134,115, 83, 64,134,115, 82, 0, 0, 0, 0,
- 0, 0, 0, 0,192,134,115, 82, 64,134,115, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,190, 36, 68,
- 0, 0, 0, 0, 55,142, 84, 52,192,188, 12,194, 64, 71, 38, 28, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 61,243,183,207,189,243,183,205, 37,162, 83,160,
- 0, 0, 0, 0, 50, 26, 90, 29, 50, 26, 90, 31, 62, 44, 85,173, 0, 0, 0, 0,189,243,183,205,189,243,183,207, 50, 87,107, 24,
- 0, 0, 0, 0,190,247,176,158,190,246,108,212,190, 97,232, 64, 63,128, 0, 0, 0, 0, 4, 14, 0, 0, 0, 1, 0, 0, 0, 68,
- 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100,
- 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205,
- 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,190, 48, 2,235,196, 48, 0, 0, 0, 89,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,235, 92,144, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,191,224,
- 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 0, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 4, 32, 5, 30,252, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66, 99,104,101, 99,107,101,114,115, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,208,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, 2,235,151,176, 55,142, 84, 52,
-192,188, 12,194, 64, 71, 38, 28, 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,190, 36, 69, 64,190, 36, 69, 64,190, 36, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,
- 63, 73, 15,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,134,115, 83, 64,134,115, 82, 0, 0, 0, 0, 0, 0, 0, 0,
-192,134,115, 82, 64,134,115, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,190, 36, 68, 0, 0, 0, 0,
- 55,142, 84, 52,192,188, 12,194, 64, 71, 38, 28, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 61,243,183,207,189,243,183,205, 37,162, 83,160, 0, 0, 0, 0,
- 50, 26, 90, 29, 50, 26, 90, 31, 62, 44, 85,173, 0, 0, 0, 0,189,243,183,205,189,243,183,207, 50, 87,107, 24, 0, 0, 0, 0,
-190,247,176,158,190,246,108,212,190, 97,232, 64, 63,128, 0, 0, 0, 0, 4, 14, 0, 0, 0, 1, 0, 0, 0, 68, 0, 1, 0, 2,
- 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,
-201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0,
- 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,177,128, 2,235,183,144, 0, 0, 0, 89, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,235,151,176, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,189, 96, 0, 0, 79, 66,
- 0, 0, 3, 16, 5, 31, 4, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 8, 32, 5, 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 79, 66, 99,104,101, 99,107,101,114,115, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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,
- 2,236,218, 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, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,230, 6, 0, 60,102,131, 0, 64,164,112, 14,
- 63,229,211, 24, 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, 34,159,178,
- 65, 34,159,178, 65, 34,159,177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,178, 89,250,166,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 34,159,178,180, 10,120,151, 0, 0, 0, 0, 0, 0, 0, 0, 52, 10,120,151,
- 65, 34,159,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 34,159,177, 0, 0, 0, 0, 60,102,131, 0,
- 64,164,112, 14, 63,229,211, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 61,201,126,231, 48,171,145,219,163,201, 66, 34, 0, 0, 0, 0,164,167,209, 65,
- 49,255, 57, 51, 61,201,126,232, 0, 0, 0, 0, 48,172, 66,235,189,201,126,231, 49,251,201, 70, 0, 0, 0, 0,187, 29,136, 18,
-191,189,200,203, 58, 9,139,180, 63,128, 0, 0, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0,
- 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56,
- 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1,
- 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,229,237, 0, 2,229,242,240, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 4, 2,230, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,191,224, 0, 0, 79, 66, 0, 0, 3, 16,
- 5, 31, 8, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 12, 32, 5, 31, 4, 32, 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, 0, 1, 4, 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, 2,236,172,160,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 57, 42, 64, 11,114,237, 64,121, 99,120,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85,190,186, 45,254, 63,128,209,115, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28,
- 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47, 0, 0, 0, 0, 65,110, 57, 42, 64, 11,114,237,
- 64,121, 99,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,138,191, 44, 21,164, 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,141, 63, 59,248,176,
- 63, 20, 7, 45, 0, 0, 0, 0,191, 74, 39, 37,189,194, 67, 9, 63, 27, 45,217, 0, 0, 0, 0,193,142, 14,147, 64,234,125, 35,
-192, 0,119, 85, 63,128, 0, 0, 0, 0, 4, 28, 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0,
- 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 12, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 16, 32, 5, 31, 8, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 79, 66, 76, 97,109,112, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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,
- 2,236,173,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,210, 76, 84,193, 71,162,178,
- 64,178,186,210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85,190,186, 45,254, 63,128,209,115,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164,
- 61,194, 67, 28, 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47, 0, 0, 0, 0,191,210, 76, 84,
-193, 71,162,178, 64,178,186,210, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,136,191, 44, 21,164, 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,139,
- 63, 59,248,173, 63, 20, 7, 44, 0, 0, 0, 0,191, 74, 39, 36,189,194, 67, 17, 63, 27, 45,217, 0, 0, 0, 0, 63,189,129,191,
-192,104,159,176,192, 53,194,132, 63,128, 0, 0, 0, 0, 4, 28, 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0,
- 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56,
- 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0,
- 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 16, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 20, 32, 5, 31, 12, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,178,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 16,188,238,
-193, 57,119,229, 65,141,218, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 15, 79,202,191, 12,100,179,
- 63,234, 92,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190, 96,197,171, 63, 83, 27,149, 63, 5,118, 10, 0, 0, 0, 0,
-191, 99,218,142, 61, 75, 4,109,190,232, 3,179, 0, 0, 0, 0,190,204,142,233,191, 16, 64,104, 63, 57, 28,174, 0, 0, 0, 0,
-193, 16,188,238,193, 57,119,229, 65,141,218, 17, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,190, 96,197,175,191, 99,218,143,190,204,142,235, 0, 0, 0, 0,
- 63, 5,118, 11,190,232, 3,179, 63, 57, 28,172, 0, 0, 0, 0,191, 83, 27,150,189, 75, 4,119, 63, 16, 64,105, 0, 0, 0, 0,
-193, 14,181,128,191, 61,177,214,193,128,133, 29, 63,128, 0, 0, 0, 0, 4, 28, 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1,
- 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,
-201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0,
- 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 20, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 24, 32, 5, 31, 16, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 4, 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, 2,236,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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,104,147,176,193, 23, 84, 42, 64,171, 77,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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85,
-190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138,
- 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47,
- 0, 0, 0, 0, 64,104,147,176,193, 23, 84, 42, 64,171, 77,116, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,137,191, 44, 21,165, 63, 11,203,251,
- 0, 0, 0, 0, 62,182, 26,141, 63, 59,248,176, 63, 20, 7, 46, 0, 0, 0, 0,191, 74, 39, 37,189,194, 67, 20, 63, 27, 45,217,
- 0, 0, 0, 0,192, 93, 99, 91,190, 80, 98,136,192,112,119,223, 63,128, 0, 0, 0, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 68,
- 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100,
- 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205,
- 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 24, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 28, 32,
- 5, 31, 20, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 4, 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, 2,236,176, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,251,147,249,193, 24, 0,206,192,104,131, 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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,103, 90, 85,190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37,
- 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217,
- 63, 20, 7, 47, 0, 0, 0, 0,192,251,147,249,193, 24, 0,206,192,104,131, 67, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,137,191, 44, 21,165,
- 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,139, 63, 59,248,176, 63, 20, 7, 45, 0, 0, 0, 0,191, 74, 39, 36,189,194, 67, 19,
- 63, 27, 45,217, 0, 0, 0, 0, 64,176,142,147,191,170, 22, 97, 64,246, 28, 27, 63,128, 0, 0, 0, 0, 0, 1, 20, 0, 0, 0,
- 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0,
- 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 28, 32, 0, 0, 0, 90, 0, 0, 0, 1,
- 5, 31, 32, 32, 5, 31, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 53, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,177, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 54, 41,142,191,115,124, 24,192, 58,215,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,103, 90, 85,190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136,
- 63, 74, 39, 37, 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,
-191, 27, 45,217, 63, 20, 7, 47, 0, 0, 0, 0, 65, 54, 41,142,191,115,124, 24,192, 58,215,162, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,136,
-191, 44, 21,164, 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,139, 63, 59,248,175, 63, 20, 7, 46, 0, 0, 0, 0,191, 74, 39, 36,
-189,194, 67, 25, 63, 27, 45,217, 0, 0, 0, 0,193, 49,192,139, 65, 36, 99, 40, 63,249,156, 89, 63,128, 0, 0, 0, 0, 0, 2,
- 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205,
- 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 32, 32, 0, 0, 0, 90,
- 0, 0, 0, 1, 5, 31, 36, 32, 5, 31, 28, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 54, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,178,144, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 19,239,220,193, 54,239,215, 65, 60, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,191,103,251, 67,191, 24, 27,164, 64, 3,136, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-190,197,143, 31, 63, 59,184,209, 63, 15, 80,138, 0, 0, 0, 0,191, 64, 66, 57, 61,210,119,132,191, 38,249,118, 0, 0, 0, 0,
-191, 9, 43, 37,191, 44, 15, 35, 63, 2,212,114, 0, 0, 0, 0,193, 19,239,220,193, 54,239,215, 65, 60, 9, 42, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
-190,197,143, 31,191, 64, 66, 56,191, 9, 43, 35, 0, 0, 0, 0, 63, 15, 80,139,191, 38,249,117, 63, 2,212,112, 0, 0, 0, 0,
-191, 59,184,208,189,210,119,142, 63, 44, 15, 35, 0, 0, 0, 0,193, 0,135,195,190,148,252,127,193, 48,180, 8, 63,128, 0, 0,
- 0, 0, 0, 2, 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0,
- 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 36, 32,
- 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 40, 32, 5, 31, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48,
- 48, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,179,192, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,164, 99,104,193, 51,244,239, 64, 19,110,188, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85,190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176,
- 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47, 0, 0, 0, 0,192,164, 99,104,193, 51,244,239, 64, 19,110,188,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 62,255,247,137,191, 44, 21,165, 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,139, 63, 59,248,178, 63, 20, 7, 45,
- 0, 0, 0, 0,191, 74, 39, 36,189,194, 67, 18, 63, 27, 45,217, 0, 0, 0, 0, 64, 91, 24, 96,192,108, 50,226, 63,219, 9,101,
- 63,128, 0, 0, 0, 0, 0, 2, 20, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10,
- 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 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, 3, 16,
- 5, 31, 40, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 44, 32, 5, 31, 36, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,
-109,112, 46, 48, 48, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,180,240,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,188, 75,145,193,107,197, 44, 64, 81,147, 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, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, 37,128, 0, 0, 37,127,255,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 37,127,255,255,165,128, 0, 0, 0, 0, 0, 0, 37,127,255,255, 51,162, 33,105,
- 63,128, 0, 0, 0, 0, 0, 0, 37,128, 0, 0,191,128, 0, 0, 51,162, 33,105, 0, 0, 0, 0, 63,188, 75,145,193,107,197, 44,
- 64, 81,147, 5, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,178, 23, 25, 45,179, 75,199,107, 0, 0, 0, 0,153,236,127, 0, 63,128, 0, 0,
- 40, 0, 0, 0, 0, 0, 0, 0,177,108,127, 0, 50, 29, 9,206, 63,128, 0, 0, 0, 0, 0, 0,191,189,159, 32,191,188,164, 47,
-192,153,188,150, 63,128, 0, 0, 0, 0, 0, 32, 16, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0,
- 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 44, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 48, 32, 5, 31, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 79, 66, 99,104,101, 99,107,101,114,115, 0, 0,108, 97,110,101, 46, 48, 48, 51, 0, 0, 0, 0, 0, 1, 4, 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,
- 2,236,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,233, 65, 80, 60,102,131, 0, 64,164,112, 14,
- 63,229,211, 24, 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, 34,159,178,
- 65, 34,159,178, 65, 34,159,177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,178, 89,250,166,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 34,159,178,180, 10,120,151, 0, 0, 0, 0, 0, 0, 0, 0, 52, 10,120,151,
- 65, 34,159,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 34,159,177, 0, 0, 0, 0, 60,102,131, 0,
- 64,164,112, 14, 63,229,211, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 61,201,126,231, 48,171,145,219,163,201, 66, 34, 0, 0, 0, 0,164,167,209, 65,
- 49,255, 57, 51, 61,201,126,232, 0, 0, 0, 0, 48,172, 66,235,189,201,126,231, 49,251,201, 70, 0, 0, 0, 0,187, 29,136, 18,
-191,189,200,203, 58, 9,139,180, 63,128, 0, 0, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0,
- 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56,
- 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1,
- 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,232,181,208, 2,233, 28, 32, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 4, 2,233, 65, 80, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,189, 96, 0, 0, 79, 66, 0, 0, 3, 16,
- 5, 31, 48, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 52, 32, 5, 31, 44, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,
-101,118,105,101,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,248,224,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,230, 32,176,189, 7, 82,100,191,103,204, 21, 63,230,165,241,
- 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,155, 39,153, 64,155, 39,153,
- 64,155, 39,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, 37,192, 0, 0, 36,255,255,255, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64,155, 39,153, 38, 27, 39,152,166,232,187,102, 0, 0, 0, 0, 38,232,187,102, 52,196,134,157,
- 64,155, 39,153, 0, 0, 0, 0, 38, 27, 39,154,192,155, 39,153, 52,196,134,157, 0, 0, 0, 0,189, 7, 82,100,191,103,204, 21,
- 63,230,165,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 62, 83, 50, 25, 35,211, 50, 28,163,211, 50, 23, 0, 0, 0, 0,163,211, 50, 27, 62, 83, 50, 25,
- 38,174, 59,158, 0, 0, 0, 0,173,204, 94, 0,175, 96, 79,158, 62, 83, 50, 25, 0, 0, 0, 0, 59,153, 62,135,185,110, 94,217,
- 63,238, 71,118, 63,128, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0,
- 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,168, 32, 2,235,172,208, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0, 4, 2,230, 32,176, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 52, 32,
- 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 56, 32, 5, 31, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,
-119, 46, 48, 48, 50, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,203,160, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,236,187, 48, 2,236,187, 48, 2,233, 41,192,191,213,187,242, 63,134,145,194, 64, 35,100,254, 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, 28, 0,243, 65, 28, 0,246, 65, 28, 0,243,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,135,110, 48, 62, 59,169,180,191, 1,115,138, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 65, 6, 49,198,192,148,154,115,191,227,113, 3, 0, 0, 0, 0, 64,106,250,159, 64, 91,207,189, 65, 5,170, 80,
- 0, 0, 0, 0,192, 86,151, 46,192,251, 94,125, 64,150,127,188, 0, 0, 0, 0,191,213,187,242, 63,134,145,194, 64, 35,100,254,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 61,180,174,143, 61, 30, 48,160,189, 16,118,223, 0, 0, 0, 0,188,153, 29,162, 61,179,248, 38, 61, 74,162,115,
- 0, 0, 0, 0, 61, 72, 21, 15,189, 19,250,160, 61,169, 57, 88, 0, 0, 0, 0, 63, 50,107, 4,190,204, 46, 88, 63, 79,206,177,
- 63,128, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10,
- 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,230, 90, 96, 2,235, 93,240, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4,
- 2,233, 41,192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 68, 2,236,187, 48, 0, 0, 0, 69,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 31, 83,117, 98,115,117,114,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, 1, 0, 1, 0, 8,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 56, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 60, 32,
- 5, 31, 52, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 4, 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, 2,236,243,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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,230, 42, 80,187,203,194, 16, 63, 45, 89,155, 63,230,153,244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 72,135, 56, 63, 72,135, 56, 63, 72,135, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 72,135, 56, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 72,135, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 72,135, 56, 0, 0, 0, 0,187,203,194, 16, 63, 45, 89,155, 63,230,153,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,163,104,144, 37,163,104,143,
-165,163,104,143, 0, 0, 0, 0, 37,165,104, 66, 51,206,250,252, 63,163,104,144, 0, 0, 0, 0,173,202,240, 60,191,163,104,144,
- 51,204, 63,183, 0, 0, 0, 0,187,173, 93,105,193, 88,176,172,186,118, 52, 95, 63,128, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
- 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0,
- 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 32, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,236, 8,208, 2,236, 13,128,
- 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,230, 42, 80, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 60, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 64, 32, 5, 31, 56, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 4, 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, 2,236,243,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,233,103, 32,
- 58, 10, 31, 0, 63,236, 94, 59, 63,231, 84,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,110,188, 91, 63,110,188, 91, 63,110,188, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218,
-128, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,110,188, 91, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 51,151, 50, 90, 63,110,188, 91, 0, 0, 0, 0, 0, 0, 0, 0,191,110,188, 91, 51,151, 50, 90,
- 0, 0, 0, 0, 58, 10, 31, 0, 63,236, 94, 59, 63,231, 84,236, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,137, 65,160,165,137, 65,159,165,137, 65,161,
- 0, 0, 0, 0, 37,137, 65,160, 63,137, 65,160, 40, 19, 46,157, 0, 0, 0, 0, 45, 14,127,248,176,150,195,159, 63,137, 65,161,
- 0, 0, 0, 0,188, 63, 80, 29,187,226, 95, 62, 65, 74, 19, 87, 63,128, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 68,
- 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100,
- 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205,
- 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 32, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,222, 64, 2,235,117, 16, 0, 0, 0, 25,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,233,103, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 64, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 68, 32, 5, 31, 60, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 53, 0, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,236,171,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,189,195,155,128,
- 64,188,145, 20, 65, 88,220, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,134,180,221, 37,141,190, 48,
- 35, 57, 55,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 35, 57, 55,253,165,141,190, 48, 0, 0, 0, 0,
- 37,112,128,219, 62,253,177, 52, 63, 94, 93, 94, 0, 0, 0, 0, 37, 22,133, 52,191, 94, 93, 94, 62,253,177, 52, 0, 0, 0, 0,
-189,195,155,128, 64,188,145, 20, 65, 88,220, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 37, 16,252, 23,165, 70,176,196, 0, 0, 0, 0,
-174,231, 90, 80, 63, 94, 93, 94, 62,253,177, 52, 0, 0, 0, 0,172,239, 68, 0,190,253,177, 50, 63, 94, 93, 95, 0, 0, 0, 0,
- 61,174, 98,150,193,144,101, 85, 64,253,124,196, 63,128, 0, 0, 0, 0, 0, 64, 16, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1,
- 0, 0, 0, 0, 79, 66, 0, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,
-201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0,
- 4, 0, 0, 0, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 16, 5, 31, 68, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 72, 32, 5, 31, 64, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 4, 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, 2,237, 7, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,228, 97, 96,
-190,252, 52, 94, 65,228,101,174, 65, 17,116,141, 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, 30,239,235, 66, 30,239,236, 66, 30,239,235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 95,174,138,
- 37,123,132, 98,165, 87, 56, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 30,239,235,168, 5,158,105,168, 28, 39,108,
- 0, 0, 0, 0, 40, 77,129,212, 65,204, 15, 66, 65,243,186,158, 0, 0, 0, 0,165, 13, 89, 55,193,243,186,156, 65,204, 15, 65,
- 0, 0, 0, 0,190,252, 52, 94, 65,228,101,174, 65, 17,116,141, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 60,206, 43,101, 34,240,217,143,163, 18,165,201,
- 0, 0, 0, 0, 31,231, 14,226, 60,158, 20,101, 60,132, 89,193, 0, 0, 0, 0, 34,173, 83,190,188,132, 89,192, 60,158, 20,103,
- 0, 0, 0, 0, 60, 70,215, 11,191, 67, 43, 61, 63, 31,241,185, 63,128, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 68,
- 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100,
- 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205,
- 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,205,112, 2,235,242,224, 0, 0, 0, 25,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,228, 97, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 72, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 76, 32, 5, 31, 68, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 99,117, 98,101, 0,117, 98,101, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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, 2,237, 14,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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,233,120, 16, 59, 88,253,128,
- 63,160,118,220, 64, 37, 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,
- 64, 68, 88, 84, 64, 68, 88, 84, 64, 68, 88, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,237,190, 1,190,217,230,108,
- 63, 52,151, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 8, 38, 67, 63,231,228,191, 63,162, 31,186, 0, 0, 0, 0,
-192, 13,118, 35, 63,220, 61, 2, 63,160, 44, 31, 0, 0, 0, 0, 60,234, 52,166,191,227,223,102, 64, 31,229, 55, 0, 0, 0, 0,
- 59, 88,253,128, 63,160,118,220, 64, 37, 15, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,103,115, 10,190,112,122,201, 59, 71, 17,255, 0, 0, 0, 0,
- 62, 9,205,116, 62, 8, 36,205, 62,135,232,136, 0, 0, 0, 0,190, 69, 27, 1,190, 59, 50,224, 62, 65,176, 25, 0, 0, 0, 0,
-192, 16,176,110,192, 9, 71,158, 63,244, 90,115, 63,128, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2,
- 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,
-201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0,
- 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235,226, 64, 2,235,211, 0, 0, 0, 0, 25, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,233,120, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 79, 66,
- 0, 0, 3, 16, 5, 31, 76, 32, 0, 0, 0, 90, 0, 0, 0, 1, 5, 31, 80, 32, 5, 31, 72, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 79, 66,112,114,101,118,105,101,119,104, 97,105,114, 0,108, 97,110,101, 0, 0, 0, 0, 0, 0, 0, 1, 4, 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,
- 2,236,237,192, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,187,160, 2,236,187,160, 0, 0, 0, 0, 0, 0, 0, 0, 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,228, 54, 96, 63,200, 92, 86, 63,227,205, 7,
-189, 9,199,149, 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, 47,126,234,
- 64, 47,126,234, 64, 47,126,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 2, 80,225,191, 15,211, 5, 62, 18,219, 92,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 18,254,224, 62,169,209, 23, 63,186,251, 27, 0, 0, 0, 0,191,133,254, 71,
- 64, 17, 40,207, 63,144,194,229, 0, 0, 0, 0,191,137, 38, 78,191,192,162, 48, 64, 1,176,125, 0, 0, 0, 0, 63,200, 92, 86,
- 63,227,205, 7,189, 9,199,149, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,156,100,244,190, 14,143,135,190, 17,235, 52, 0, 0, 0, 0, 62, 70,239,175,
- 62, 26, 4,102, 62,137,251, 72, 0, 0, 0, 0,189, 52,172,174,190,154,112,211, 62, 76,243, 67, 0, 0, 0, 0,191, 36, 56,149,
-192, 66, 98,139, 64, 68, 5,168, 63,128, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0,
- 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 0,201,150,180, 56,
- 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 0, 1, 1,
- 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 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,236,189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 4, 2,228, 54, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 56,
- 2,236,187,160, 0, 0, 0,153, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 13, 0, 1, 0, 1, 0, 0, 0, 0,
- 63,128, 0, 0, 66,200, 0, 0, 66, 72, 0, 0, 0, 0, 0,150, 0, 0, 0, 8, 0, 0, 0, 0, 61,125,243, 64, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,189, 35,214,240, 0, 0, 0, 0,189,196,155,184, 0, 0, 0, 0, 61, 76,204,205,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 66, 72, 0, 0, 66, 72, 0, 0, 66, 72, 0, 0, 66, 72, 0, 0, 0, 4, 0, 4, 0, 4, 0, 4,
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 5, 0, 1, 0, 1, 0, 8, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,156,100,244,
-190, 14,143,134,190, 17,235, 52, 0, 0, 0, 0, 61, 52,172,172, 62,154,112,211,190, 76,243, 69, 0, 0, 0, 0, 62, 70,239,176,
- 62, 26, 4,102, 62,137,251, 73, 0, 0, 0, 0,191, 12,211,188,190,160,176,198, 63, 22,156, 56, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 44, 2,236,189, 0, 0, 0, 0, 92, 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, 61,204,204,205, 62, 76,204,205,
- 60,163,215, 10, 0, 0, 79, 66, 0, 0, 3, 16, 5, 31, 80, 32, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 0, 5, 31, 76, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,116,101,120,116,117,114,101, 0,114,101,118,105,101,119, 46, 48, 48, 53, 0, 0, 0, 0,
- 0, 1, 4, 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, 2,237, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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,228,195, 96,
-188,183, 16, 61,191,103,204, 21, 63,228,234, 48, 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,155, 39,153, 64,155, 39,153, 64,155, 39,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218,
- 37,192, 0, 0, 36,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,155, 39,153, 38, 27, 39,152,166,232,187,102,
- 0, 0, 0, 0, 38,232,187,102, 52,196,134,157, 64,155, 39,153, 0, 0, 0, 0, 38, 27, 39,154,192,155, 39,153, 52,196,134,157,
- 0, 0, 0, 0,188,183, 16, 61,191,103,204, 21, 63,228,234, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62, 83, 50, 25, 35,211, 50, 28,163,211, 50, 23,
- 0, 0, 0, 0,163,211, 50, 27, 62, 83, 50, 25, 38,174, 59,158, 0, 0, 0, 0,173, 44, 24, 0,175, 94,165,224, 62, 83, 50, 25,
- 0, 0, 0, 0, 59, 33,251,236, 59, 40, 37,135, 63,238, 71,118, 63,128, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 68,
- 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,100,
- 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205,
- 0, 0, 0, 0, 4, 0, 1, 1, 1, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,235, 92,192, 2,235,104,176, 0, 0, 0, 25,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,228,195, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 77, 65, 0, 0, 1,184, 2,236,189, 96, 0, 0, 0, 38, 0, 0, 0, 1, 2,236,191,224, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 77, 65, 99,104,101, 99,107,101,114,100, 97,114,107, 0, 0, 0, 97,116,101,114,105, 97, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 61,221, 1,116, 61,220,251,200, 61,220,251,200, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0,
- 63, 89,153,154, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 76,204,205, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 2, 0, 2, 0, 1, 0, 6, 1, 64, 0, 3, 1, 64, 0, 3, 0, 1, 0, 4, 0, 12, 0, 4, 63, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0, 63, 0, 0, 0,
- 61,204,204,205, 63, 0, 0, 0, 61,204,204,205, 61,204,204,205, 63,128, 0, 0, 8, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 2,236,191, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0,120, 2,236,191, 64, 0, 0, 0, 29, 0, 0, 0, 1,
- 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,202,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, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,192, 0, 1, 63,192, 0, 1, 63,192, 0, 1, 0, 0, 0, 0, 56,209,183, 23, 56,209,177,184, 56,209,177,184, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 62, 76,204,205, 0, 0, 0, 0, 0, 0, 77, 65, 0, 0, 1,184,
- 2,236,191,224, 0, 0, 0, 38, 0, 0, 0, 1, 2,236,194, 96, 2,236,189, 96, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 99,104,
-101, 99,107,101,114,108,105,103,104,116, 0, 0, 0, 97,116,101,114,105, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 3, 0, 1, 62,157, 65,188, 62,157, 61,178, 62,157, 61,178, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 89,153,154, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 76,204,205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,205, 0, 2, 0, 2,
- 0, 1, 0, 6, 1, 64, 0, 3, 1, 64, 0, 3, 0, 1, 0, 4, 0, 12, 0, 4, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0, 63, 0, 0, 0, 61,204,204,205, 63, 0, 0, 0,
- 61,204,204,205, 61,204,204,205, 63,128, 0, 0, 8, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 2,236,193,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0,120, 2,236,193,192, 0, 0, 0, 29, 0, 0, 0, 1, 0, 16, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,236,202,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, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 56,209,183, 23, 56,209,177,184, 56,209,177,184, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 62, 76,204,205, 0, 0, 0, 0, 0, 0, 77, 65, 0, 0, 1,184, 2,236,194, 96, 0, 0, 0, 38,
- 0, 0, 0, 1, 2,236,196,224, 2,236,191,224, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,112,114,101,118,105,101,119, 0, 0, 97,
-116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 63,128, 0, 0,
- 63, 54,232, 61, 63, 23,161,184, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 62, 68,248,188,
- 63,128, 0, 0, 63, 76,204,205, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,130,121,198, 63,160, 0, 0,
- 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,205, 0, 2, 0, 2, 0, 50, 0, 6, 3, 17, 0, 3,
- 3, 17, 0, 3, 0, 1, 0, 4, 0, 12, 0, 4, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2,
- 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0, 63, 0, 0, 0, 61,204,204,205, 63, 0, 0, 0, 61,204,204,205, 61,204,204,205,
- 63,128, 0, 0, 8, 1, 0, 1, 5, 31, 84, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 2,236,196, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 68, 65, 84, 65,
- 0, 0, 0,120, 2,236,196, 64, 0, 0, 0, 29, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,201, 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, 0, 0, 0, 0, 0, 0,
- 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 16, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 62, 76,204,205, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 3, 8, 5, 31, 84, 32, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,220, 40,245, 0, 0, 0, 0, 63,125,112,164,
- 63,128, 0, 0, 63, 24,214,106, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 1, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0,
- 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0,
- 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0,
- 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1892,45 +1368,3075 @@ char datatoc_preview_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,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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,200, 25,130, 2, 1, 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, 96,152, 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, 68, 65, 84, 65, 28, 0, 0, 0,
+ 64,116, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,144,116, 8, 3, 0, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 88, 1, 72, 2,224, 49,164, 2, 68, 65, 84, 65, 28, 0, 0, 0,144,116, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,224,116, 8, 3,
+ 64,116, 8, 3, 14, 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 41, 2,231, 1, 96, 46,164, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+224,116, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 48,117, 8, 3,144,116, 8, 3, 0, 4, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0,
+182, 1, 21, 2, 32,170,161, 2, 68, 65, 84, 65, 28, 0, 0, 0, 48,117, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,128,117, 8, 3,
+224,116, 8, 3, 32, 0, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0,224, 46, 49, 1,168,186, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,
+128,117, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,208,117, 8, 3, 48,117, 8, 3, 33, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
+ 88, 1, 72, 2, 40,190, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,208,117, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 32,118, 8, 3,
+128,117, 8, 3, 2, 0, 0, 0, 2, 0, 0, 0, 0, 20, 0, 0,224, 46, 52, 0, 40,183, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,
+ 32,118, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,112,118, 8, 3,208,117, 8, 3, 2, 0, 0, 0, 3, 0, 0, 0, 0, 20, 0, 0,
+224, 46, 47, 0,168,179, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,112,118, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,192,118, 8, 3,
+ 32,118, 8, 3, 2, 0, 0, 0, 4, 0, 0, 0, 0, 20, 0, 0,224, 46, 85, 1, 40,176, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,
+192,118, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 16,119, 8, 3,112,118, 8, 3, 1, 0, 0, 0, 3, 0, 0, 0, 0, 20, 0, 0,
+174, 1,139, 0, 88, 50,153, 2, 68, 65, 84, 65, 28, 0, 0, 0, 16,119, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 96,119, 8, 3,
+192,118, 8, 3, 1, 0, 0, 0, 4, 0, 0, 0, 0, 20, 0, 0,189, 2, 23, 2,216, 46,153, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+ 96,119, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,176,119, 8, 3, 16,119, 8, 3, 4, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+254, 1,152, 1,160,166,161, 2, 68, 65, 84, 65, 28, 0, 0, 0,176,119, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 0,120, 8, 3,
+ 96,119, 8, 3, 14, 4, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 41, 2,231, 1,224, 42,164, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+ 0,120, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 80,120, 8, 3,176,119, 8, 3, 64, 0, 0, 0, 13, 0, 0, 0, 0, 16, 0, 0,
+252, 1,162, 2,160,159,161, 2, 68, 65, 84, 65, 28, 0, 0, 0, 80,120, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,160,120, 8, 3,
+ 0,120, 8, 3, 64, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,249, 1,199, 1, 32,163,161, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+160,120, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,240,120, 8, 3, 80,120, 8, 3, 32, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+253, 1,124, 1,120, 3,131, 2, 68, 65, 84, 65, 28, 0, 0, 0,240,120, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 64,121, 8, 3,
+160,120, 8, 3, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,254, 1,125, 1, 32,156,161, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+ 64,121, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,144,121, 8, 3,240,120, 8, 3, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+175, 1, 12, 2,168,193, 32, 3, 68, 65, 84, 65, 28, 0, 0, 0,144,121, 8, 3,110, 0, 0, 0, 1, 0, 0, 0,224,121, 8, 3,
+ 64,121, 8, 3, 28, 4, 0, 0, 4, 0, 0, 0, 0, 20, 0, 0,104, 2,179, 2,224, 8, 16, 3, 68, 65, 84, 65, 28, 0, 0, 0,
+224,121, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 56,246,163, 2,144,121, 8, 3, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+254, 1,125, 1,160,152,161, 2, 68, 65, 84, 65, 28, 0, 0, 0, 56,246,163, 2,110, 0, 0, 0, 1, 0, 0, 0,160,126,152, 2,
+224,121, 8, 3, 28, 4, 0, 0, 5, 0, 0, 0, 0, 20, 0, 0, 69, 2, 88, 4, 88, 43,153, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+160,126,152, 2,110, 0, 0, 0, 1, 0, 0, 0,192,125,152, 2, 56,246,163, 2, 8, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+194, 1,152, 1, 32,149,161, 2, 68, 65, 84, 65, 28, 0, 0, 0,192,125,152, 2,110, 0, 0, 0, 1, 0, 0, 0,104,109, 8, 3,
+160,126,152, 2, 28, 4, 0, 0, 6, 0, 0, 0, 0, 20, 0, 0,224, 2,142, 1,216, 39,153, 2, 68, 65, 84, 65, 28, 0, 0, 0,
+104,109, 8, 3,110, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,192,125,152, 2,223, 5, 0, 0, 7, 0, 0, 0, 0, 4, 0, 0,
+137, 2,135, 1,160, 26,156, 2, 68, 65, 84, 65, 40, 0, 0, 0, 96,251,152, 2,109, 0, 0, 0, 1, 0, 0, 0, 44, 1, 0, 0,
+ 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 1, 0,244, 1,200, 0,100, 0, 20, 0, 16, 39, 0, 0,205,204,204, 61, 0, 0,240, 65,
+ 0, 0, 0, 64, 68, 65, 84, 65,244, 0, 0, 0,136, 22,162, 2,123, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0,205,204, 76, 63,
+ 0, 0,180, 66, 9, 0, 1, 0, 0, 0,128, 63,111, 18,131, 58, 32, 0, 32, 0, 32, 0, 1, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 5, 0, 5, 0,255,255, 50, 0, 50, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0,100, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 50, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 0, 23,183,209, 56,205,204,204, 61, 0, 0, 0, 0,
+ 0, 0, 50, 0, 10,215, 35, 60, 10,215, 35, 60,102,102,166, 63, 0, 0,192, 63, 0, 0, 52, 66, 72,225,122, 63,205,204,204, 61,
+ 3, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65, 8, 1, 0, 0, 0, 96,152, 2, 18, 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, 6, 0, 0, 0, 0, 0,128, 67, 0, 0, 0, 0, 0, 0,128, 63, 78, 10,127,191, 36, 44,177, 61,
+ 78, 10,127,191,213, 43,177, 61,144,156,148, 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,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, 72, 0, 0, 0,144,156,148, 2, 16, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0,205,204,204, 61, 86,188,121, 63, 0, 0, 0, 0,154,153,153, 62, 96, 60, 75, 63, 0, 0, 0, 0,
+ 51, 51, 51, 63,128, 14, 83, 62, 0, 0, 0, 0,102,102,102, 63, 79,117,200, 60, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 72, 0, 0, 0, 40,172,132, 2,115, 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,240,108,155, 2,255,255, 15, 0, 0, 0, 0, 0,255,127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 73, 77, 0, 0,124, 1, 0, 0,184, 62, 18, 3, 29, 0, 0, 0, 1, 0, 0, 0,120, 70, 18, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 73, 77, 73,109, 97,103,101, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 62, 1, 0, 0, 0, 0, 0, 0, 85,110,116,105,116,108,101,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108,110,134, 68, 0, 0, 0, 1,
+ 0, 1, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 73, 77, 0, 0,124, 1, 0, 0,120, 70, 18, 3, 29, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,184, 62, 18, 3, 0, 0, 0, 0, 0, 0, 0, 0, 73, 77, 82,101,110,100,101,114, 32, 82,101,115,
+117,108,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 63, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 5, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 67, 65, 0, 0,132, 0, 0, 0, 16, 2,164, 2, 27, 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, 46, 48, 48, 49, 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, 12, 0,205,204, 76, 62,117,148, 96, 66, 76, 39,176, 64,210, 69,112, 66, 0, 0,240, 65,
+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, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0, 24, 1, 0, 0,
+208, 63,148, 2, 37, 0, 0, 0, 1, 0, 0, 0,136, 62,148, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 76, 97,
+109,112, 46, 48, 48, 50, 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,
+ 2, 0, 1, 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,160, 65,
+182,152,143, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,128,238,126, 2, 1, 0, 0, 0,
+ 0, 0, 0, 63, 0, 0, 32, 66, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0,128,238,126, 2, 18, 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,
+ 80,175,131, 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,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, 80,175,131, 2, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0,136, 62,148, 2, 37, 0, 0, 0, 1, 0, 0, 0,
+ 24, 65,148, 2,208, 63,148, 2, 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, 8, 16, 0, 0, 0, 0, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,205,204, 12, 64,247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,176,101,152, 2, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 1, 0, 0,
+176,101,152, 2, 18, 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, 80,110,126, 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,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, 80,110,126, 2,
+ 16, 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,
+ 76, 65, 0, 0, 24, 1, 0, 0, 24, 65,148, 2, 37, 0, 0, 0, 1, 0, 0, 0,208, 17,164, 2,136, 62,148, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 49, 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, 16, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+102,102,102, 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, 0, 0, 0, 0,
+ 16, 3,164, 2, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,184, 2,236,196,224, 0, 0, 0, 38, 0, 0, 0, 1, 2,236,199, 96, 2,236,194, 96,
- 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,116,101,120,116,117,114,101, 0,114,101,118,105,101,119, 46, 48, 48, 49, 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, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,204,205, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,204,204,205, 0, 2, 0, 2, 0, 50, 0, 6, 3, 1, 0, 71, 3, 1, 0, 67, 0, 1, 0, 4, 0, 12, 0, 4,
- 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0,
- 63, 0, 0, 0, 61,204,204,205, 63, 0, 0, 0, 61,204,204,205, 61,204,204,205, 63,128, 0, 0, 8, 1, 0,129, 5, 31, 88, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 2,236,198,192, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 16, 3,164, 2, 18, 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,192,109,126, 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, 0, 0, 0,120, 2,236,198,192, 0, 0, 0, 29,
- 0, 0, 0, 1, 0, 1, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,201, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,192,109,126, 2, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0,208, 17,164, 2,
+ 37, 0, 0, 0, 1, 0, 0, 0, 80, 20,164, 2, 24, 65,148, 2, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48,
+ 48, 51, 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,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,247,255,239, 65, 0, 0,150, 66,
+154,153, 25, 62, 0, 0,128, 63,200,182, 27, 63, 0, 0,128, 63, 0, 0, 0, 0,136,156,154, 2, 1, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0,136,156,154, 2, 18, 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,224,175,131, 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,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,224,175,131, 2, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0, 80, 20,164, 2, 37, 0, 0, 0, 1, 0, 0, 0,208, 22,164, 2,
+208, 17,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 52, 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, 16, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63,205,204,204, 62,247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63,200,182, 27, 63,
+ 0, 0,128, 63, 0, 0, 0, 0,192,157,154, 2, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0,192,157,154, 2,
+ 18, 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, 2,129, 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,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, 2,129, 2, 16, 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, 76, 65, 0, 0,
+ 24, 1, 0, 0,208, 22,164, 2, 37, 0, 0, 0, 1, 0, 0, 0, 80, 25,164, 2, 80, 20,164, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 76, 65, 83,112,111,116, 46, 48, 48, 53, 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, 8, 16, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 80, 78, 83, 63,
+247,255,239, 65, 0, 0,150, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 56, 42,130, 2,
+ 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 56, 42,130, 2, 18, 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, 8,110,126, 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,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, 8,110,126, 2, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0, 80, 25,164, 2, 37, 0, 0, 0,
+ 1, 0, 0, 0, 24, 28,164, 2,208, 22,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 54, 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, 2, 0, 8, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 51, 51,179, 63,247,255,239, 65, 0, 0, 72, 66,171,156, 8, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,112, 43,130, 2, 4, 0, 0, 0, 78,207, 68, 65, 25, 4,240, 65,
+ 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 0, 2, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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, 1, 0, 0,112, 43,130, 2, 18, 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, 80,207, 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, 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,
+ 80,207, 63, 0, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0, 24, 28,164, 2, 37, 0, 0, 0, 1, 0, 0, 0,224, 30,164, 2, 80, 25,164, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 55, 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, 16, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 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,
+ 0, 0, 0, 0,168, 44,130, 2, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0,168, 44,130, 2, 18, 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,224,239,128, 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,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,224,239,128, 2, 16, 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, 76, 65, 0, 0, 24, 1, 0, 0,
+224, 30,164, 2, 37, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 24, 28,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0,192, 63, 0, 0,160, 65,
+ 0, 0, 52, 66,154,153, 25, 62, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,224, 45,130, 2, 1, 0, 0, 0,
+ 0, 0, 0, 63, 0, 0, 32, 66, 0, 0, 52, 66, 0, 0,128, 63, 0, 0, 64, 64, 0, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0,224, 45,130, 2, 18, 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,
+ 56,196,126, 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,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, 56,196,126, 2, 16, 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, 87, 79, 0, 0, 68, 1, 0, 0,104, 7, 16, 3,108, 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,141, 47, 79, 62,
+ 64, 19,209, 62, 73, 23, 14, 63, 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,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, 1, 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, 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, 84, 88, 0, 0,104, 0, 0, 0,192,199,156, 2, 25, 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,216,228,126, 2,216,228,126, 2,
+216,228,126, 2,216,228,126, 2, 0, 0, 0, 0, 0, 0, 0, 0,168, 35,153, 2,255,255,255,255, 0, 4, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0,216,228,126, 2, 24, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 38,167, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 69, 69, 82, 70, 68, 65, 84, 65, 4, 0, 0, 0, 56, 38,167, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 71, 82, 0, 0, 68, 0, 0, 0,240,108,155, 2,218, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 71, 82, 79,118,101,114,114,105,100,101, 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,120,232,126, 2,184, 28,153, 2,255,255, 15, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0,120,232,126, 2,217, 0, 0, 0, 1, 0, 0, 0, 24,236,126, 2, 0, 0, 0, 0,168,186, 32, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0, 24,236,126, 2,217, 0, 0, 0, 1, 0, 0, 0,184,239,126, 2,
+120,232,126, 2, 40,183, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,184,239,126, 2,
+217, 0, 0, 0, 1, 0, 0, 0, 72,191,132, 2, 24,236,126, 2,168,179, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 24, 0, 0, 0, 72,191,132, 2,217, 0, 0, 0, 1, 0, 0, 0,184,143,125, 2,184,239,126, 2, 40,176, 32, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,184,143,125, 2,217, 0, 0, 0, 1, 0, 0, 0,
+ 48, 88,126, 2, 72,191,132, 2, 88, 50,153, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,
+ 48, 88,126, 2,217, 0, 0, 0, 1, 0, 0, 0,120, 88,126, 2,184,143,125, 2,216, 46,153, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,120, 88,126, 2,217, 0, 0, 0, 1, 0, 0, 0,120,100,169, 2, 48, 88,126, 2,
+160,159,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,120,100,169, 2,217, 0, 0, 0,
+ 1, 0, 0, 0, 88, 93,169, 2,120, 88,126, 2,224, 8, 16, 3,144, 93,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 24, 0, 0, 0, 88, 93,169, 2,217, 0, 0, 0, 1, 0, 0, 0,184, 28,153, 2,120,100,169, 2, 88, 43,153, 2,168,232,150, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 24, 0, 0, 0,184, 28,153, 2,217, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 88, 93,169, 2,216, 39,153, 2, 24,235,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0,160, 26,156, 2,
+102, 0, 0, 0, 1, 0, 0, 0,224, 42,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97,
+ 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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, 16, 2,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 78,199, 41,188,225,230, 30,193,216,129,230, 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,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,218, 15,201, 63, 0, 0,128, 37,255,255,127, 37, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+255,255,127, 37, 0, 0,128,165, 0, 0, 0, 0,255,255,127, 37,105, 33,162, 51, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 37,
+ 0, 0,128,191,105, 33,162, 51, 0, 0, 0, 0, 78,199, 41,188,225,230, 30,193,216,129,230, 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, 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,
+162,133,136,152,164,133,136,152, 0, 0, 0, 0,255,255,127, 37, 0, 0,128, 63, 64, 90,136, 48, 0, 0, 0, 0,164,133,136,152,
+ 0, 0, 0,168, 0, 0,128, 63, 0, 0, 0, 0, 0,192, 59, 39, 60,252, 17, 52,234, 90, 20, 51, 0, 0,128, 63, 0, 0,128, 63,
+251,255,127,152,160,133,136, 24, 0, 0, 0, 0,254,255,127, 25, 0, 0,128, 63, 0, 0, 0, 40, 0, 0, 0, 0,255,255,127,165,
+ 64, 90,136,176, 0, 0,128, 63, 0, 0, 0, 0, 1, 0,231, 37, 40, 19,212, 50, 63,252, 17,180, 0, 0,128, 63,223, 5, 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, 6, 41,100, 63, 0, 0,128, 63,205,204,204, 62,
+ 6, 41,100, 63, 0, 0, 0, 0, 2, 0, 0, 0, 1, 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, 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, 79, 66, 0, 0, 80, 3, 0, 0,
+224, 42,164, 2,102, 0, 0, 0, 1, 0, 0, 0, 96, 46,164, 2,160, 26,156, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 99,104,
+101, 99,107,101,114,115, 46, 48, 48, 49, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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, 56, 14,132, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 18, 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,112, 41,150, 2, 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 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, 69, 36,190, 64, 69, 36,190, 64, 68, 36,190, 64, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,218, 15, 73, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 83,115,134, 64, 82,115,134, 64, 0, 0, 0, 0, 0, 0, 0, 0, 82,115,134,192, 83,115,134, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 36,190, 64, 0, 0, 0, 0, 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 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,184,118,201,177, 0, 0, 0, 0, 0, 0, 0, 0,184,118,201, 49, 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,220,232,118, 52,208,124, 46,180, 16,213,141, 51, 0, 0,128, 63,
+207,183,243, 61,205,183,243,189,156, 83,162, 37, 0, 0, 0, 0, 29, 90, 26, 50, 31, 90, 26, 50,173, 85, 44, 62, 0, 0, 0, 0,
+205,183,243,189,207,183,243,189, 25,107, 87, 50, 0, 0, 0, 0,158,176,247,190,212,108,246,190, 64,232, 97,190, 0, 0,128, 63,
+ 14, 4, 0, 0, 0, 4, 1, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,
+205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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,184,225,152, 2, 48,100,163, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 4, 0, 0, 0,112, 41,150, 2, 0, 0, 0, 0, 1, 0, 0, 0,104,137,165, 2, 79, 66, 0, 0, 80, 3, 0, 0, 96, 46,164, 2,
+102, 0, 0, 0, 1, 0, 0, 0,224, 49,164, 2,224, 42,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 99,104,101, 99,107,101,
+114,115, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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, 48,250,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,153,166, 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,186,126, 2, 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 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, 69, 36,190, 64, 69, 36,190, 64, 68, 36,190, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,218, 15, 73, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 83,115,134, 64,
+ 82,115,134, 64, 0, 0, 0, 0, 0, 0, 0, 0, 82,115,134,192, 83,115,134, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 36,190, 64, 0, 0, 0, 0, 52, 84,142, 55,194, 12,188,192, 28, 38, 71, 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,
+184,118,201,177, 0, 0, 0, 0, 0, 0, 0, 0,184,118,201, 49, 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,220,232,118, 52,208,124, 46,180, 16,213,141, 51, 0, 0,128, 63,207,183,243, 61,
+205,183,243,189,156, 83,162, 37, 0, 0, 0, 0, 29, 90, 26, 50, 31, 90, 26, 50,173, 85, 44, 62, 0, 0, 0, 0,205,183,243,189,
+207,183,243,189, 25,107, 87, 50, 0, 0, 0, 0,158,176,247,190,212,108,246,190, 64,232, 97,190, 0, 0,128, 63, 14, 4, 0, 0,
+ 0, 4, 1, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,
+205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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,122,152, 2, 40, 15,161, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,
+ 0,186,126, 2, 0, 0, 0, 0, 1, 0, 0, 0, 56,134,165, 2, 79, 66, 0, 0, 80, 3, 0, 0,224, 49,164, 2,102, 0, 0, 0,
+ 1, 0, 0, 0,224, 8, 16, 3, 96, 46,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 99,104,101, 99,107,101,114,115, 46, 48,
+ 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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, 16, 2,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208, 84,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+208,249,134, 2, 0,131,102, 60, 14,112,164, 64, 24,211,229, 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,178,159, 34, 65,178,159, 34, 65,177,159, 34, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,128,166,250, 89,178, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,178,159, 34, 65,151,120, 10,180,
+ 0, 0, 0, 0, 0, 0, 0, 0,151,120, 10, 52,178,159, 34, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+177,159, 34, 65, 0, 0, 0, 0, 0,131,102, 60, 14,112,164, 64, 24,211,229, 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, 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,160, 85, 74, 36,
+ 0, 0, 0, 0, 0, 0, 0, 0,160, 85, 74,164, 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,126, 46,151,175, 19,238,187, 52, 64, 17,113,178, 0, 0,128, 63,231,126,201, 61,219,145,171, 48,
+207,121,201,163, 0, 0, 0, 0, 65,209,167,164, 51, 57,255, 49,232,126,201, 61, 0, 0, 0, 0,235, 66,172, 48,231,126,201,189,
+ 79,216,251, 49, 0, 0, 0, 0, 18,136, 29,187,203,200,189,191,139,139, 9, 58, 0, 0,128, 63, 33, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61,
+ 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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,
+ 40, 87,163, 2,248,158,154, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,208,249,134, 2,
+ 0, 0, 0, 0, 1, 0, 0, 0,104,137,165, 2, 79, 66, 0, 0, 80, 3, 0, 0,224, 8, 16, 3,102, 0, 0, 0, 1, 0, 0, 0,
+216, 39,153, 2,224, 49,164, 2, 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, 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,136, 62,148, 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,
+ 42, 57,110, 65,237,114, 11, 64,120, 99,121, 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, 85, 90,103, 63,
+254, 45,186,190,115,209,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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,136,247,255, 62, 37, 39, 74, 63,138, 26,182, 62,
+ 0, 0, 0, 0,164, 21, 44,191, 28, 67,194, 61,176,248, 59, 63, 0, 0, 0, 0,251,203, 11, 63,217, 45, 27,191, 47, 7, 20, 63,
+ 0, 0, 0, 0, 42, 57,110, 65,237,114, 11, 64,120, 99,121, 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,254,255,127, 63, 96,139,222,178,240,132, 96, 51,
+ 0, 0, 0, 0,161, 43,128, 51, 0, 0,128, 63, 62, 70,101, 49, 0, 0, 0, 0,179,106, 15, 51, 67, 91, 19,178, 0, 0,128, 63,
+ 0, 0, 0, 0,219, 81, 21, 53,237,171,186,179,163,166,113,181, 0, 0,128, 63,138,247,255, 62,164, 21, 44,191,251,203, 11, 63,
+ 0, 0, 0, 0,141, 26,182, 62,176,248, 59, 63, 45, 7, 20, 63, 0, 0, 0, 0, 37, 39, 74,191, 9, 67,194,189,217, 45, 27, 63,
+ 0, 0, 0, 0,147, 14,142,193, 35,125,234, 64, 85,119, 0,192, 0, 0,128, 63, 28, 4, 0, 0, 0, 20, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0,
+ 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0,216, 39,153, 2,102, 0, 0, 0,
+ 1, 0, 0, 0, 88, 43,153, 2,224, 8, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 49, 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, 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, 24, 65,148, 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, 84, 76,210,191,178,162, 71,193,210,186,178, 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,
+ 85, 90,103, 63,254, 45,186,190,115,209,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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,136,247,255, 62, 37, 39, 74, 63,
+138, 26,182, 62, 0, 0, 0, 0,164, 21, 44,191, 28, 67,194, 61,176,248, 59, 63, 0, 0, 0, 0,251,203, 11, 63,217, 45, 27,191,
+ 47, 7, 20, 63, 0, 0, 0, 0, 84, 76,210,191,178,162, 71,193,210,186,178, 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,131,235,180, 52,
+190, 31,238,179, 0, 0, 0, 0,196,103,141,178,248,255,127, 63,214, 14,245, 51, 0, 0, 0, 0,167,140, 60, 50,232,103,134,179,
+ 1, 0,128, 63, 0, 0, 0, 0, 55, 83,232,180,137,218,173,182, 76, 55,130, 53, 0, 0,128, 63,134,247,255, 62,164, 21, 44,191,
+251,203, 11, 63, 0, 0, 0, 0,138, 26,182, 62,173,248, 59, 63, 45, 7, 20, 63, 0, 0, 0, 0, 36, 39, 74,191, 19, 67,194,189,
+218, 45, 27, 63, 0, 0, 0, 0,197,129,189, 63,176,159,104,192,135,194, 53,192, 0, 0,128, 63, 28, 4, 0, 0, 0, 20, 0, 0,
+ 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61,
+ 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0, 88, 43,153, 2,
+102, 0, 0, 0, 1, 0, 0, 0,216, 46,153, 2,216, 39,153, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48,
+ 48, 50, 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, 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, 80, 25,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,238,188, 16,193,229,119, 57,193, 17,218,141, 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,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,202, 79, 15,191,179,100, 12,191,112, 92,234, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,171,197, 96,190,
+149, 27, 83, 63, 10,118, 5, 63, 0, 0, 0, 0,142,218, 99,191,109, 4, 75, 61,179, 3,232,190, 0, 0, 0, 0,233,142,204,190,
+104, 64, 16,191,174, 28, 57, 63, 0, 0, 0, 0,238,188, 16,193,229,119, 57,193, 17,218,141, 65, 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,254,255,127, 63,
+154,215,220,178,103, 99, 11, 52, 0, 0, 0, 0,233,200,198,178, 0, 0,128, 63,163, 97,236, 51, 0, 0, 0, 0,174,189,205,178,
+205,147,215, 49, 1, 0,128, 63, 0, 0, 0, 0,142,106,113,181,207, 60,210,181,255,141,244, 53, 0, 0,128, 63,174,197, 96,190,
+143,218, 99,191,233,142,204,190, 0, 0, 0, 0, 12,118, 5, 63,180, 3,232,190,172, 28, 57, 63, 0, 0, 0, 0,150, 27, 83,191,
+119, 4, 75,189,104, 64, 16, 63, 0, 0, 0, 0,128,181, 14,193,224,177, 61,191, 28,133,128,193, 0, 0,128, 63, 28, 4, 0, 0,
+ 0, 20, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,
+205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0,
+216, 46,153, 2,102, 0, 0, 0, 1, 0, 0, 0, 88, 50,153, 2, 88, 43,153, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,
+109,112, 46, 48, 48, 51, 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,
+ 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, 17,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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,147,104, 64, 42, 84, 23,193,116, 77,171, 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, 85, 90,103, 63,254, 45,186,190,115,209,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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+136,247,255, 62, 37, 39, 74, 63,138, 26,182, 62, 0, 0, 0, 0,164, 21, 44,191, 28, 67,194, 61,176,248, 59, 63, 0, 0, 0, 0,
+251,203, 11, 63,217, 45, 27,191, 47, 7, 20, 63, 0, 0, 0, 0,176,147,104, 64, 42, 84, 23,193,116, 77,171, 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,168,125, 20,180, 35,254, 63, 50, 0, 0, 0, 0,142,131, 88, 50,254,255,127, 63,191,122,148, 50, 0, 0, 0, 0,
+164,124,113,178,179, 27,138, 49, 0, 0,128, 63, 0, 0, 0, 0,198,133, 72, 52,154, 21,207,180, 39,159, 41, 53, 0, 0,128, 63,
+136,247,255, 62,164, 21, 44,191,251,203, 11, 63, 0, 0, 0, 0,138, 26,182, 62,175,248, 59, 63, 45, 7, 20, 63, 0, 0, 0, 0,
+ 37, 39, 74,191, 18, 67,194,189,217, 45, 27, 63, 0, 0, 0, 0, 88, 99, 93,192,122, 98, 80,190,223,119,112,192, 0, 0,128, 63,
+ 1, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,
+205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0,
+ 80, 3, 0, 0, 88, 50,153, 2,102, 0, 0, 0, 1, 0, 0, 0, 40,176, 32, 3,216, 46,153, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 79, 66, 76, 97,109,112, 46, 48, 48, 52, 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, 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,
+ 80, 20,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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249,147,251,192,206, 0, 24,193, 67,131,104,192, 0, 0, 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, 85, 90,103, 63,254, 45,186,190,115,209,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,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0,136,247,255, 62, 37, 39, 74, 63,138, 26,182, 62, 0, 0, 0, 0,164, 21, 44,191, 28, 67,194, 61,176,248, 59, 63,
+ 0, 0, 0, 0,251,203, 11, 63,217, 45, 27,191, 47, 7, 20, 63, 0, 0, 0, 0,249,147,251,192,206, 0, 24,193, 67,131,104,192,
+ 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,254,255,127, 63,184,251, 16, 51,201, 8,244, 50, 0, 0, 0, 0, 44, 86,171,178,254,255,127, 63,157,147,147,178,
+ 0, 0, 0, 0, 52,174,103, 48, 15,174,236, 50, 0, 0,128, 63, 0, 0, 0, 0, 93,121,121,181,103,135,116,181, 92,181, 25,180,
+ 0, 0,128, 63,139,247,255, 62,165, 21, 44,191,252,203, 11, 63, 0, 0, 0, 0,140, 26,182, 62,175,248, 59, 63, 45, 7, 20, 63,
+ 0, 0, 0, 0, 36, 39, 74,191, 20, 67,194,189,217, 45, 27, 63, 0, 0, 0, 0,147,142,176, 64,101, 22,170,191, 27, 28,246, 64,
+ 0, 0,128, 63, 1, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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, 10,215, 35, 61,
+ 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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,
+ 79, 66, 0, 0, 80, 3, 0, 0, 40,176, 32, 3,102, 0, 0, 0, 1, 0, 0, 0,168,179, 32, 3, 88, 50,153, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 53, 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, 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, 22,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 41, 54, 65, 24,124,115,191,162,215, 58,192,
+ 0, 0, 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, 85, 90,103, 63,254, 45,186,190,115,209,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,128, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0,136,247,255, 62, 37, 39, 74, 63,138, 26,182, 62, 0, 0, 0, 0,164, 21, 44,191, 28, 67,194, 61,
+176,248, 59, 63, 0, 0, 0, 0,251,203, 11, 63,217, 45, 27,191, 47, 7, 20, 63, 0, 0, 0, 0,142, 41, 54, 65, 24,124,115,191,
+162,215, 58,192, 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,136,247,255, 62,164, 21, 44,191,251,203, 11, 63, 0, 0, 0, 0,139, 26,182, 62,175,248, 59, 63,
+ 46, 7, 20, 63, 0, 0, 0, 0, 36, 39, 74,191, 25, 67,194,189,217, 45, 27, 63, 0, 0, 0, 0,139,192, 49,193, 40, 99, 36, 65,
+ 89,156,249, 63, 0, 0,128, 63, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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,
+ 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0,168,179, 32, 3,102, 0, 0, 0, 1, 0, 0, 0, 40,183, 32, 3, 40,176, 32, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 54, 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, 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, 80, 25,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,239, 19,193,215,239, 54,193,
+ 42, 9, 60, 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,128, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,251,103,191,164, 27, 24,191, 37,136, 3, 64,
+ 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 31,143,197,190,209,184, 59, 63,138, 80, 15, 63, 0, 0, 0, 0, 57, 66, 64,191,
+132,119,210, 61,118,249, 38,191, 0, 0, 0, 0, 37, 43, 9,191, 35, 15, 44,191,114,212, 2, 63, 0, 0, 0, 0,220,239, 19,193,
+215,239, 54,193, 42, 9, 60, 65, 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, 31,143,197,190, 56, 66, 64,191, 35, 43, 9,191, 0, 0, 0, 0,139, 80, 15, 63,
+117,249, 38,191,112,212, 2, 63, 0, 0, 0, 0,208,184, 59,191,142,119,210,189, 35, 15, 44, 63, 0, 0, 0, 0,195,135, 0,193,
+127,252,148,190, 8,180, 48,193, 0, 0,128, 63, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0, 40,183, 32, 3,102, 0, 0, 0, 1, 0, 0, 0,168,186, 32, 3,
+168,179, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 55, 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, 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, 24, 28,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 99,164,192,
+239,244, 51,193,188,110, 19, 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, 85, 90,103, 63,254, 45,186,190,
+115,209,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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,136,247,255, 62, 37, 39, 74, 63,138, 26,182, 62, 0, 0, 0, 0,
+164, 21, 44,191, 28, 67,194, 61,176,248, 59, 63, 0, 0, 0, 0,251,203, 11, 63,217, 45, 27,191, 47, 7, 20, 63, 0, 0, 0, 0,
+104, 99,164,192,239,244, 51,193,188,110, 19, 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, 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,137,247,255, 62,164, 21, 44,191,251,203, 11, 63, 0, 0, 0, 0,
+138, 26,182, 62,177,248, 59, 63, 46, 7, 20, 63, 0, 0, 0, 0, 36, 39, 74,191, 18, 67,194,189,218, 45, 27, 63, 0, 0, 0, 0,
+ 96, 24, 91, 64,226, 50,108,192,100, 9,219, 63, 0, 0,128, 63, 2, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0,
+ 1, 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, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0,168,186, 32, 3,102, 0, 0, 0, 1, 0, 0, 0,
+ 40,190, 32, 3, 40,183, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 56, 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, 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,224, 30,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+145, 75,188, 63, 44,197,107,193, 5,147, 81, 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,218, 15,201, 63,
+ 0, 0,128, 37,255,255,127, 37, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,255,255,127, 37, 0, 0,128,165,
+ 0, 0, 0, 0,255,255,127, 37,105, 33,162, 51, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 37, 0, 0,128,191,105, 33,162, 51,
+ 0, 0, 0, 0,145, 75,188, 63, 44,197,107,193, 5,147, 81, 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, 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, 25, 58,194,178, 67,191,128,179,
+ 0, 0, 0, 0,156, 90,113, 26, 0, 0,128, 63,255,255,255, 39, 0, 0, 0, 0,156, 90,241, 49,220, 13,171,177,255,255,127, 63,
+ 0, 0, 0, 0, 33,159,189,191, 47,164,188,191,151,188,153,192, 0, 0,128, 63, 32, 0, 0, 0, 0, 16, 0, 0, 0, 0, 68, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0,
+ 4, 0, 0, 0, 1, 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,128, 63, 0, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0, 40,190, 32, 3,102, 0, 0, 0,
+ 1, 0, 0, 0,168,193, 32, 3,168,186, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 99,104,101, 99,107,101,114,115, 0, 0,
+108, 97,110,101, 46, 48, 48, 51, 0, 0, 0, 0, 1, 0, 0, 4, 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,128, 26,153, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 26,131, 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,
+ 24, 29,153, 2, 0,131,102, 60, 14,112,164, 64, 24,211,229, 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,178,159, 34, 65,178,159, 34, 65,177,159, 34, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,128,166,250, 89,178, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,178,159, 34, 65,151,120, 10,180,
+ 0, 0, 0, 0, 0, 0, 0, 0,151,120, 10, 52,178,159, 34, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+177,159, 34, 65, 0, 0, 0, 0, 0,131,102, 60, 14,112,164, 64, 24,211,229, 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, 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,160, 85, 74, 36,
+ 0, 0, 0, 0, 0, 0, 0, 0,160, 85, 74,164, 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,126, 46,151,175, 19,238,187, 52, 64, 17,113,178, 0, 0,128, 63,231,126,201, 61,219,145,171, 48,
+207,121,201,163, 0, 0, 0, 0, 65,209,167,164, 51, 57,255, 49,232,126,201, 61, 0, 0, 0, 0,235, 66,172, 48,231,126,201,189,
+ 79,216,251, 49, 0, 0, 0, 0, 18,136, 29,187,203,200,189,191,139,139, 9, 58, 0, 0,128, 63, 33, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61,
+ 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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,
+224, 80,150, 2,152, 3,153, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 24, 29,153, 2,
+ 0, 0, 0, 0, 1, 0, 0, 0, 56,134,165, 2, 79, 66, 0, 0, 80, 3, 0, 0,168,193, 32, 3,102, 0, 0, 0, 1, 0, 0, 0,
+ 32,149,161, 2, 40,190, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 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, 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,
+200,250,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,197,152, 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,168, 41,150, 2,
+100, 82, 7,189, 21,204,103,191,241,165,230, 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,153, 39,155, 64,153, 39,155, 64,153, 39,155, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218, 15,201, 63,
+ 0, 0,192, 37,255,255,255, 36, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,153, 39,155, 64,152, 39, 27, 38,102,187,232,166,
+ 0, 0, 0, 0,102,187,232, 38,157,134,196, 52,153, 39,155, 64, 0, 0, 0, 0,154, 39, 27, 38,153, 39,155,192,157,134,196, 52,
+ 0, 0, 0, 0,100, 82, 7,189, 21,204,103,191,241,165,230, 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, 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, 19, 21,240,152,211, 45,212,152,
+ 0, 0, 0, 0, 21, 21,240,152, 0, 0,128, 63,204,175,227,166, 0, 0, 0, 0,234, 43, 90,153,204,175,227, 38, 0, 0,128, 63,
+ 0, 0, 0, 0, 40,196,146, 48,240,160,185,178, 35, 61,138,178, 0, 0,128, 63, 25, 50, 83, 62, 27, 50,211, 35, 23, 50,211,163,
+ 0, 0, 0, 0, 27, 50,211,163, 25, 50, 83, 62, 59,119,189, 38, 0, 0, 0, 0, 0, 94,204,173, 16, 58, 97,175, 25, 50, 83, 62,
+ 0, 0, 0, 0,135, 62,153, 59,184, 97,110,185,118, 71,238, 63, 0, 0,128, 63, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0,
+ 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0,
+ 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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,240,212,127, 2,
+136,218,131, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,168, 41,150, 2, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0, 32,149,161, 2,102, 0, 0, 0, 1, 0, 0, 0,160,152,161, 2,
+168,193, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 50, 0, 46, 48, 48, 49, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 4, 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,136,161,165, 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, 40,141, 20, 3, 40,141, 20, 3,216, 31,156, 2,242,187,213,191,
+194,145,134, 63,254,100, 35, 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,
+243, 0, 28, 65,246, 0, 28, 65,243, 0, 28, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,110,135, 63,180,169, 59, 62,
+138,115, 1,191, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,198, 49, 6, 65,115,154,148,192, 3,113,227,191, 0, 0, 0, 0,
+159,250,106, 64,189,207, 91, 64, 80,170, 5, 65, 0, 0, 0, 0, 46,151, 86,192,125, 94,251,192,188,127,150, 64, 0, 0, 0, 0,
+242,187,213,191,194,145,134, 63,254,100, 35, 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, 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,143,174,180, 61,160, 48, 30, 61,223,118, 16,189, 0, 0, 0, 0,
+162, 29,153,188, 38,248,179, 61,115,162, 74, 61, 0, 0, 0, 0, 15, 21, 72, 61,160,250, 19,189, 88, 57,169, 61, 0, 0, 0, 0,
+ 4,107, 50, 63, 88, 46,204,190,177,206, 79, 63, 0, 0,128, 63, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1,
+ 1, 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,128, 63,
+ 0, 64, 0, 0, 0, 0, 0, 0, 0, 1, 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,
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,216, 31,156, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 68, 0, 0, 0, 40,141, 20, 3, 74, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 31, 0, 0, 0, 83,117, 98,115,117,114,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, 1, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0,
+ 80, 3, 0, 0,160,152,161, 2,102, 0, 0, 0, 1, 0, 0, 0, 32,156,161, 2, 32,149,161, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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,
+152, 43,161, 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,152,194,149, 2, 16,194,203,187,155, 89, 45, 63,244,153,230, 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, 56,135, 72, 63, 56,135, 72, 63, 56,135, 72, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 56,135, 72, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,135, 72, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,135, 72, 63, 0, 0, 0, 0, 16,194,203,187,155, 89, 45, 63,244,153,230, 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, 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,144,104,163, 63,143,104,163, 37,144,104,163,165, 0, 0, 0, 0, 66,104,165, 37,252,250,206, 51,144,104,163, 63,
+ 0, 0, 0, 0, 60,240,202,173,144,104,163,191,130, 64,204, 51, 0, 0, 0, 0,105, 93,173,187,172,176, 88,193,178, 56,118,186,
+ 0, 0,128, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61,
+ 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 0, 0, 0, 0, 0, 0, 32, 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, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 4, 0, 0, 0,152,194,149, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0,
+ 32,156,161, 2,102, 0, 0, 0, 1, 0, 0, 0,160,159,161, 2,160,152,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,
+101,118,105,101,119, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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,152, 43,161, 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, 64,100,152, 2, 0, 31, 10, 58, 59, 94,236, 63,236, 84,231, 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, 91,188,110, 63, 91,188,110, 63, 91,188,110, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,218, 15,201, 63, 0, 0, 0,128, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 91,188,110, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 50,151, 51, 91,188,110, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 91,188,110,191, 90, 50,151, 51, 0, 0, 0, 0, 0, 31, 10, 58, 59, 94,236, 63,236, 84,231, 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, 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,
+160, 65,137, 63,159, 65,137,165,161, 65,137,165, 0, 0, 0, 0,160, 65,137, 37,160, 65,137, 63,194,226, 40, 40, 0, 0, 0, 0,
+248,127, 14, 45,115,141,149,176,161, 65,137, 63, 0, 0, 0, 0, 29, 80, 63,188,103, 95,226,187, 87, 19, 74, 65, 0, 0,128, 63,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,
+205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 0, 0, 0, 0, 0, 0, 32, 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, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 4, 0, 0, 0, 64,100,152, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0,160,159,161, 2,
+102, 0, 0, 0, 1, 0, 0, 0, 32,163,161, 2, 32,156,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,
+119, 46, 48, 48, 53, 0, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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, 63,148, 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,128,155,195,189, 20,145,188, 64, 94,220, 88, 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,128, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,221,180,134, 63, 48,190,141, 37,253, 55, 57, 35, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63,
+253, 55, 57, 35, 48,190,141,165, 0, 0, 0, 0,219,128,112, 37, 52,177,253, 62, 94, 93, 94, 63, 0, 0, 0, 0, 52,133, 22, 37,
+ 94, 93, 94,191, 52,177,253, 62, 0, 0, 0, 0,128,155,195,189, 20,145,188, 64, 94,220, 88, 65, 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, 0, 0,128, 63,
+ 23,252, 16, 37,196,176, 70,165, 0, 0, 0, 0, 80, 90,231,174, 94, 93, 94, 63, 52,177,253, 62, 0, 0, 0, 0, 0, 68,239,172,
+ 50,177,253,190, 95, 93, 94, 63, 0, 0, 0, 0,150, 98,174, 61, 85,101,144,193,196,124,253, 64, 0, 0,128, 63, 64, 0, 0, 0,
+ 0, 16, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 0, 79, 66, 0, 0, 7, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,
+205,204,204, 61, 0, 0, 0, 0, 4, 0, 0, 0, 1, 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,128, 63, 0, 64, 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, 79, 66, 0, 0, 80, 3, 0, 0,
+ 32,163,161, 2,102, 0, 0, 0, 1, 0, 0, 0,160,166,161, 2,160,159,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,
+101,118,105,101,119, 46, 48, 48, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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,152, 47,161, 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,120,100,152, 2, 94, 52,252,190,174,101,228, 65,141,116, 17, 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,235,239, 30, 66,236,239, 30, 66,235,239, 30, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,138,174, 95, 63, 98,132,123, 37, 61, 56, 87,165, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+235,239, 30, 66,105,158, 5,168,108, 39, 28,168, 0, 0, 0, 0,212,129, 77, 40, 66, 15,204, 65,158,186,243, 65, 0, 0, 0, 0,
+ 55, 89, 13,165,156,186,243,193, 65, 15,204, 65, 0, 0, 0, 0, 94, 52,252,190,174,101,228, 65,141,116, 17, 65, 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,
+101, 43,206, 60,142,217,240, 34,201,165, 18,163, 0, 0, 0, 0,226, 14,231, 31,101, 20,158, 60,193, 89,132, 60, 0, 0, 0, 0,
+190, 83,173, 34,192, 89,132,188,103, 20,158, 60, 0, 0, 0, 0, 11,215, 70, 60, 61, 43, 67,191,185,241, 31, 63, 0, 0,128, 63,
+ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,
+205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 4, 0, 0, 0,120,100,152, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0,160,166,161, 2,
+102, 0, 0, 0, 1, 0, 0, 0, 32,170,161, 2, 32,163,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,
+119, 99,117, 98,101, 0,117, 98,101, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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,248, 52,161, 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,248,252,149, 2,128,253, 88, 59,220,118,160, 63, 0, 15, 37, 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, 84, 88, 68, 64, 84, 88, 68, 64, 83, 88, 68, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1,190,237, 62,108,230,217,190, 20,151, 52, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 67, 38, 8, 64,
+191,228,231, 63,186, 31,162, 63, 0, 0, 0, 0, 35,118, 13,192, 2, 61,220, 63, 31, 44,160, 63, 0, 0, 0, 0,166, 52,234, 60,
+102,223,227,191, 55,229, 31, 64, 0, 0, 0, 0,128,253, 88, 59,220,118,160, 63, 0, 15, 37, 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,
+ 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, 10,115,103, 62,
+201,122,112,190,191, 17, 71, 59, 0, 0, 0, 0,116,205, 9, 62,205, 36, 8, 62,136,232,135, 62, 0, 0, 0, 0, 1, 27, 69,190,
+224, 50, 59,190, 25,176, 65, 62, 0, 0, 0, 0,110,176, 16,192,158, 71, 9,192,115, 90,244, 63, 0, 0,128, 63, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,
+205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,
+248,252,149, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0, 32,170,161, 2,102, 0, 0, 0,
+ 1, 0, 0, 0,120, 3,131, 2,160,166,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119,104, 97,105,
+114, 0,108, 97,110,101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 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,104, 1,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 25,155, 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, 80,116,164, 2, 80,116,164, 2,
+ 80,110,149, 2, 86, 92,200, 63, 7,205,227, 63,149,199, 9,189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,234,126, 47, 64,234,126, 47, 64,236,126, 47, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+225, 80, 2, 63, 5,211, 15,191, 92,219, 18, 62, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,224,254, 18, 64, 23,209,169, 62,
+ 27,251,186, 63, 0, 0, 0, 0, 71,254,133,191,207, 40, 17, 64,229,194,144, 63, 0, 0, 0, 0, 78, 38,137,191, 48,162,192,191,
+125,176, 1, 64, 0, 0, 0, 0, 86, 92,200, 63, 7,205,227, 63,149,199, 9,189, 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, 4, 42,199,178,
+231, 81, 69,179, 0, 0, 0, 0,195, 12,143, 50, 1, 0,128, 63, 87, 5,139, 51, 0, 0, 0, 0,155,189, 80,179,143,215, 79,178,
+254,255,127, 63, 0, 0, 0, 0,157,196,173, 51,119,194, 5,180,210,243,132,180, 0, 0,128, 63,244,100,156, 62,135,143, 14,190,
+ 52,235, 17,190, 0, 0, 0, 0,175,239, 70, 62,102, 4, 26, 62, 72,251,137, 62, 0, 0, 0, 0,174,172, 52,189,211,112,154,190,
+ 67,243, 76, 62, 0, 0, 0, 0,149, 56, 36,191,139, 98, 66,192,168, 5, 68, 64, 0, 0,128, 63, 0, 4, 0, 0, 1, 4, 0, 0,
+ 0, 0, 68, 0, 1, 0, 2, 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, 0, 0, 0, 64, 0, 0,128, 63, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61,
+ 0, 0, 0, 0, 4, 0, 1, 1, 1, 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,128, 63, 0, 64, 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, 8,127,152, 2, 8,127,152, 2,
+216,116,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, 0, 0,
+ 24,220, 16, 3,104,243,163, 2, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 80,110,149, 2,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,116, 0, 0, 0,216,116,164, 2,104, 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,
+205,204,204, 61,205,204, 76, 62, 10,215,163, 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, 0, 0, 0, 0, 68, 65, 84, 65, 44, 1, 0, 0, 8,127,152, 2,
+ 28, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232,102,152, 2,136,174, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 40,213,148, 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,244,100,156, 62,134,143, 14,190, 52,235, 17,190, 0, 0, 0, 0,172,172, 52, 61,211,112,154, 62,
+ 69,243, 76,190, 0, 0, 0, 0,176,239, 70, 62,102, 4, 26, 62, 73,251,137, 62, 0, 0, 0, 0,188,211, 12,191,198,176,160,190,
+ 56,156, 22, 63, 0, 0,128, 63, 0, 0, 0, 64, 0, 0, 0, 0, 17, 2, 0, 0,150, 0, 0, 0, 0, 0, 0, 0,150, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,216,114, 0, 0,136,174, 7, 3,
+ 26, 1, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 20,135, 17,192, 36,121, 97,192,112, 32,141, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,144,233,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 96, 32, 63,
+185,201,160, 62,160, 3, 6, 63, 11, 34,248,190,206, 53,185, 60,192,197,178, 61,174,184, 53, 63,223,172,162,190,109,136,224, 62,
+142,173, 61,191,180, 96, 10, 60,200,196,163, 61, 78,182, 99, 63,165,242,180, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,248,112,150, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 46, 7,192,143, 26, 60,192, 28,147,207, 63,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,232,211,127, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6,121,229,190,108, 50, 41,191,136,152, 7,191,156,100,146,190,146,141, 25,191, 39, 92,142, 62,212,104, 18, 63,227,105,105,190,
+113,156, 96, 62,137,226, 69,191,147,247, 17, 61, 51,172, 44, 62, 17,125, 54, 63, 69,195,169, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,144, 63,245, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,103,174,189, 60, 88, 17,192,230, 35, 76, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,232,146, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,101,160,155, 62, 59, 87,152, 62,118,199, 84,191, 86, 89,183, 62,118,103,231, 62,110, 47,177,189,155, 8, 4,191,
+100, 60,199, 62,197, 40,177,189, 2, 14, 46, 62,102, 96, 39, 62,101,119,242, 61,189,168,146, 62, 55, 9,221, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,135, 36, 87, 61, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75,102,131,192,196,241, 26, 63,
+140,198, 76, 64,190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,240,147, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 49, 80, 39, 63,171, 26,218,190, 89,118, 16, 63,130, 72,138,190,169,255,122,190,185,111, 14,191,
+ 21,207, 38, 63, 73,252,211, 61,198,177, 80,191, 43,154,203,189,227,146, 53, 61, 63,180,115, 63,216,113, 42, 59,125, 63,144, 58,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,175, 95,142, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 43,226,189,
+253, 85,220,191,225,104,101, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,248,148, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 97, 45, 63,119, 47,205,190, 35,117, 19, 63,166,125, 98, 62,242,195, 73, 62,
+124,228,243, 62,119, 86, 11, 63, 70,156, 89, 62,230,232, 88, 63,130, 53,204,190,250,120,128, 62, 19,194, 20, 62, 61, 15, 90, 62,
+ 92, 30,200, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 53,129,253, 62,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+108,159,129,191, 8,210, 6, 63, 35,221,152, 64,190, 81, 55,191,107,243, 71,191,102,237, 42, 63,235,163,214, 62,200,206,183,190,
+205,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0,150, 16, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41,167,210,190,194,172,139, 62,250,220, 35, 63, 30,182, 22,191,
+122, 3,136, 61,109,164,176,190, 30,153,147,190,255,248, 10,188,234, 90,160,190, 89,241,205,190,148,235, 25, 63,206,172,146, 62,
+137,195, 52, 61, 99,142,139, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 37,227, 77, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,114,167,189,191,217, 59,104,192,184,179,184, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 8,151, 16, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 45,121, 62,120,126, 98, 63, 60,171,135,189,
+139,174,200,190,220,142, 21, 63, 77, 70, 40,191,118, 70,150, 62, 4,245, 92, 61,159,118,174,190,176,217, 49, 63,120,167,104, 60,
+166,104,235, 60,218,251, 73, 63, 13, 25, 44, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,217, 2,247, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 86,112, 30, 63,111, 69, 82,192, 59,191, 51, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 16,152, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,227,137,190,206,195, 71,191,
+ 70, 31, 96,190,127, 46, 5, 63, 99, 51,214,189,228, 61, 67,191,134, 90, 2, 62,120,214,146,190, 34,111, 33, 62,136,229,187,190,
+ 27,112,241, 60, 0,187,177, 60, 4,134,171, 62,164, 35, 29, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,130,192, 56, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,148,176,191, 88,200, 1, 63, 89, 48,146, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 24,153, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42,169, 82,190,
+102,214, 57, 63, 55,112, 36,191, 59,205, 9, 62,184,139, 5, 63,105, 32, 43,190,120, 62, 37,191,220,215, 15, 63,180, 2, 8, 63,
+198,170,163, 62,160,178, 8, 63,185,164,184, 62, 68, 72, 63, 61, 16,104,112, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 97,249,192, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 80,168,191, 8,154,165,191,229,248, 80, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 32,154, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 56,145, 5,191, 83, 77,126, 62, 14,133, 63,191,190, 5,167, 62,123,212, 96,190,233,136,176, 62, 25,193, 80,189,147, 49, 18, 62,
+222, 40, 25, 62, 59,204, 10,191,177, 46,104, 62, 36,106,150, 62, 2, 61,138, 62, 4,131, 86, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 39, 27, 19, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,190,246,189,233,129, 90,192,224,155, 20, 64,
+190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 40,155, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 30, 77, 14,191,231, 81,154, 62, 41,220, 22,191,104,189, 0,191,214,167,160,190,140, 60, 22,190, 37, 85, 74, 63,
+ 32,253, 8,191, 96,146, 23, 61,196, 30,177,190, 79, 25,187, 60,207,244,194, 60, 53,234,253, 62,233, 52,234, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,218, 21, 79, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,176,231, 67,190,144,105, 11,189,
+210,111,153, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 48,156, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 74,110,205, 62,146,226, 27,191, 73, 95,219, 61, 75, 3, 45, 63,222,109,147,190,152,196, 40, 63,
+ 36,136,116,190,181, 21,190,190,211, 38,213,190,114,230,183, 62,206,217, 24, 63, 59,222, 25, 62, 0, 50,134, 61,139,161, 63, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,180, 67,127, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58,217,158, 63,
+122,225, 17,192,213,158,120, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 56,157, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 95, 22, 63,172, 95,210,190,114, 70, 46,191, 67, 71, 26, 62,188,164,234, 61,
+121,120, 78,191,186,229,108,188,144,225, 72,190,197,218, 42,190, 83,104,114,191, 34,213, 73, 62,217,230, 49, 61,217,117,187, 61,
+143,253, 42, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,226,144, 95, 62,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29,205,127,191,231,116,142,191,116, 64,100, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 64,158, 16, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,196, 25,132,189, 67,167, 41,191,249,145,174,190,171,227, 41, 63,
+ 84,208, 94, 62, 98, 21, 50, 63,138,162, 46,191,136, 53, 56,191, 9, 44,160, 62, 15, 42,188,190,109,124,145, 62, 47, 84,135, 62,
+ 95, 56, 95, 62,104, 38,111, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+183,116, 87, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,143,106, 67,192,239, 1,236, 62,230,139,105, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 80, 12, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 72, 62,147,226,176, 62, 67,185, 48,191,
+255,215, 26,191,242,158,254,187, 89,238,201,190, 99,166, 39, 63,102,238, 3,191,206,229, 10, 62,165, 53,230, 62, 37,227,100, 62,
+230, 38, 54, 63, 87, 4, 43, 61,166, 1,190, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,213, 26,126, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,114, 63, 58,191,242, 44,102,191,239,155,119, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 88, 13, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,198,238,131, 61, 49, 99, 58,191,
+ 63,180, 26, 63,201, 92,162,190,113,254,209, 62,151, 67, 12, 63, 80,138,197, 62,197,116, 72,191,117,129,182,190,180,137, 76, 62,
+232,134,178, 62, 23,134,113, 62,235,242, 46, 62, 45,121,122, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,248, 12,169, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,244,173,175, 62,136,194,141, 61, 0,239,164, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 96, 14, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,213, 38, 28, 63,
+ 66,248,166, 60,227,199, 67,191,127,123, 83,190,122,119,224,190, 73, 46,149, 62,135, 43, 62, 62, 30,175,199, 62, 97,224, 2, 63,
+180,198,250, 62,211, 97, 48, 63, 38,134,130, 61,167, 53, 8, 61, 56, 40, 91, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 93,115,157, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,127,188, 36,192, 83,192, 42,192, 20, 24,202, 63,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,104, 15, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 10,121, 82,190,233,142,216,190, 94,156, 83,191,222, 73,158, 62,170,207, 3, 63, 63, 41, 39,191, 2,164,147, 62, 36,187, 38,191,
+ 0, 1,218, 62,145,119, 32,191,191,242,154, 60, 14,165,130, 62,127,236, 49, 63,163, 44,253, 60, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 13,194,130, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,191,117, 51, 63, 40,247, 44,192, 84, 59, 82, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,112, 16, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 89,176, 71, 59,214, 55, 18,191, 67, 82,223,190,142, 2, 50, 63,235, 17,202, 61, 51,118,199, 62,129,125, 72, 63,
+ 86,250, 36,191, 70, 99, 90, 61,125, 38, 25, 63,218, 50,227, 61, 48,152,110, 61,166, 58,104, 62,121,161, 26, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 21, 69, 35, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23,218, 44,192,131,112,159,190,
+ 68,196, 80, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,120, 17, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 65, 39,191,175,203,203,190, 24, 58, 8,191,132,178,185,190, 48,133, 27, 63,166,150, 35, 63,
+195,164,174,189,146, 20,209,189,124, 43, 3,191,219,188, 54, 63, 23,126, 53, 62, 93,113, 22, 63, 29,104, 42, 62,166,168,140, 61,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 90,122,222, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,222,253, 61,191,
+212,216, 43,190,219,239,140, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,128, 18, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 62,251,190,154,207,132, 62,191,198, 19,191,122, 82, 25,191,179,114,169,190,
+242, 80, 46,191,161, 92,100,189,125,103,188, 62, 0,234, 23,191, 12,140, 22, 63, 24, 36,252, 62,191,130,121, 62, 96,245,198, 61,
+ 98,186, 42, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 62,205, 89, 62,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+192,168,212,191, 47,175, 30,192, 94,228, 12, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,136, 19, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,136, 6, 62,240,135, 58,191, 89,198,233, 61, 57,148, 41, 63,
+151,188,189,190,156, 72,189,190,184, 14, 86, 63,185, 54,165,190,131,220, 49, 62, 60, 87,189,189,118,198,167, 61, 92,200, 80, 62,
+157,210, 10, 63,240, 9, 48, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+186,132,181, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,114,184,238,190,237,206,230,191,208,122, 85, 64,190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,
+198,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144, 20, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,165, 30, 63,161, 50,249,190,180,213, 86,189,
+178, 10, 29,191,227,247, 49,191,215,139, 7,189,222,249,154,189,153, 77, 23,191,160, 58, 14, 63, 72, 47, 15, 61,138,132, 94, 62,
+167,190, 48, 62,203, 41,136, 62,157, 52,176, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 38,177,233, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 67, 19,104, 63,179,122,254,191,115, 37,123, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+152, 21, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,231,181, 62, 36, 19, 51, 63,
+126, 5, 6,191,231, 27,170,190,128,253, 35,189,182, 11,151,189, 74,171,178, 62,127,231, 49, 63,204,146,128, 62, 88,100, 17, 62,
+197,245,124, 62, 30,108,130, 61,201,152,229, 61,242,193, 19, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 56,156, 79, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,172,106,191, 63,110,225, 42,192, 2,170,110, 64,190, 81, 55,191,109,243, 71,191,
+ 98,237, 42, 63,236,163,214, 62,197,206,183,190,201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,160, 22, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,227, 27,191,
+ 17, 83, 26, 63, 27,229, 2,191, 83, 48,135, 61,199,244,134, 62, 55, 37,151,190,210,195,237,189,249, 39, 17, 63,154, 1, 76, 61,
+ 75,194, 79,191,240, 99,249, 61,190, 88,249, 60,174, 20,183, 61, 39, 38, 66, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,150, 40,178, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,121, 3, 12,192, 63, 11,252,190,146,136, 89, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,168, 23, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+104, 59, 20,191, 30, 36, 17, 63,112, 57,252,190, 32,101,162, 62,139, 6,160, 62, 57,160, 80, 61,109,243,245, 61, 41, 18,224,190,
+182,154,227,188,238,196,139,190,173, 28,108, 62,191,152,246, 62,199, 50, 61, 62, 31,254,210, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 20,166, 56, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,250,104,187,191, 56, 86,139,189,145, 23,131, 64,
+190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,176, 24, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,228, 80, 19,191,118,138, 16,191,122,210, 6,191,139, 14,138, 62, 73, 65,189, 62, 19, 89,244,189,205, 5, 83, 62,
+ 94,159,107,190, 19,199,255, 62, 14,124, 48,190, 15, 67,208, 62,184, 57,190, 62,119,154,219, 61,111,114,234, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,203, 51,223, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 56,161, 62,255,221,207,191,
+202,110,120, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,184, 25, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,138,124, 47, 63, 12,193, 0, 63,124, 39,176, 62, 68, 3,204,190,132,180, 43, 61, 66,184,104,189,
+ 69,173, 54,191, 24,239,116,189,191,183, 53,190,120, 91,198,190,123, 33,150, 62, 68, 30,226, 61,224,121, 27, 62, 4,154,227, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,117, 22, 35, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89, 41,192,
+117,107, 25,192,174,245,222, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,192, 26, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66,202,207, 62,211, 32, 47, 63,139,219, 0,191,197,212,172,190,195, 68, 65, 63,
+105,152,217,190,159,218,214,190, 85,113, 84,190,194,108,158,190,229,217,235, 61, 82,179,202, 60,197,106,157, 62,211,197, 33, 63,
+ 9,243, 18, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 1,162,102, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 94,238,220,191, 91, 70,150,191,203,192, 72, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,200, 27, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,176, 95, 22, 63,172, 95,210,190,114, 70, 46,191, 67, 71, 26, 62,
+188,164,234, 61,121,120, 78,191,186,229,108,188,144,225, 72,190,197,218, 42,190, 83,104,114,191, 13,183, 77, 62,158,153,182, 62,
+ 65, 59,143, 62, 52,159, 38, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+226,144, 95, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 61,234,116,192,224,101,238,188,165, 20, 56, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,
+198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,208, 28, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,242,136, 6, 62,240,135, 58,191, 89,198,233, 61,
+ 57,148, 41, 63,151,188,189,190,156, 72,189,190,184, 14, 86, 63,185, 54,165,190,131,220, 49, 62, 60, 87,189,189, 31,255,242, 60,
+231,194, 83, 63,189, 56, 5, 62, 68,188, 85, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,186,132,181, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,128,209,240,189,178,183, 95, 63, 5, 67,176, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,201,206,183,190,200,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+216, 29, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107,114, 86,191,137,141, 2,191,
+227,140,105, 61, 70,121, 63,190,130,242,218, 62,237,163,132,190,219,235, 16, 60, 85,203,248, 62, 79,244, 80,191,103, 0,148, 62,
+153,189, 85, 63,151,104,200, 61,246, 55,142, 60, 74, 57, 76, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 31,252, 33, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,206, 54, 25,192,171,197,162, 62, 6, 16,121, 64,190, 81, 55,191,109,243, 71,191,
+ 98,237, 42, 63,236,163,214, 62,197,206,183,190,201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,224, 30, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,219,100,244,190,
+182, 69, 91,191, 60,137,144,189,161,126, 59, 62, 28,228,200,190, 60, 49,170, 62,225,139,250,189,244,143,111, 62,252,103,100,191,
+148, 32, 79, 62,104,246,163, 62, 91,201, 16, 63, 24,104,136, 61,227,230, 66, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,182, 88, 41, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 57, 61,192,236, 53, 39,191,173,221, 55, 64,190, 81, 55,191,
+107,243, 71,191,100,237, 42, 63,235,163,214, 62,198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,232, 31, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+167, 43, 35,190,242,210,225, 61,197, 58, 30, 63,229, 8, 67, 63,215,176,222, 61, 70, 15, 12, 63, 80,195,165, 62,218, 72,227, 61,
+188, 66, 87,191,145,213,195, 62, 39,218,212, 61,242, 20, 25, 63,122, 70,118, 62,159,226,107, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,173, 74, 64, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,249, 62, 40,191, 16,113, 26, 63, 50,179,160, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,240, 32, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,190, 29,224,190,239, 44, 4, 63,125,217, 49, 63,107, 25,121,190,117,172,217, 62,242, 98,116,190,148,162, 42, 63,
+142,178,199,190, 54,105, 13,191, 83,107,163,190, 64,186, 45, 63,109,122, 91, 62, 32,134, 21, 61, 21,118,144, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,113,107, 73, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 51,138,191,199, 14,110,192,
+ 18, 66,203, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,248, 33, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 36, 78, 39, 63,128, 50,251,190,139,185,189,190,175, 4,226, 62,118, 23,153,190, 67,228,120,190,
+ 50,226, 42,191,239,243, 86,191, 37, 42,189,190, 66, 1,190,190,235,223,153, 59, 21,174,243, 59,231,160, 60, 63,251,135,128, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,167,245,105, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 75,186,191,
+170,205,204,191,132,169, 61, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 35, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,223,155, 62,249,196, 3,191,115, 12,163,190,212, 73, 60,191, 59,208, 85, 62,
+ 65, 11,155, 62, 28, 17,173,189, 20, 16,254,190,213,229, 32, 63,216,221, 28,189, 79, 19, 52, 62,229, 52,146, 62,191,228,171, 62,
+106,185, 79, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 45,184, 37, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4,119,219, 63,231, 73, 28,192, 83,117,128, 64,188, 81, 55,191,109,243, 71,191,100,237, 42, 63,233,163,214, 62,202,206,183,190,
+201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 8, 36, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,109,254, 62,210,146, 4, 63,232,131, 23, 63, 66,212,187, 62,
+ 9,109,158,190, 71, 12,216, 62, 64, 20,153, 59, 11, 2, 7, 62, 92,134, 91, 62, 43,128, 33,191,186, 75, 51, 62,206,251,144, 60,
+198, 49, 19, 61, 22,114, 69, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+221,100,115, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,172, 59,194,191, 35, 29, 13,192, 13,208, 30, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 16, 37, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,223,155, 62,249,196, 3,191,115, 12,163,190,
+212, 73, 60,191, 59,208, 85, 62, 65, 11,155, 62, 28, 17,173,189, 20, 16,254,190,213,229, 32, 63,216,221, 28,189, 97, 31,227, 61,
+168,207,104, 62, 38, 89,237, 62, 93,238, 74, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 45,184, 37, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,197,190, 82,192,251,148,174, 62, 29,189, 91, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 24, 38, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,170,132, 10,191, 82, 61,237, 62,
+127,191,223,190, 11,148, 12, 63,236,142, 92, 62, 17,199, 32, 63,157,206,242,189,199,114, 15, 63, 91, 82, 33,191, 3,247,167,190,
+210, 10, 37, 62,124,152, 65, 63, 28,110,106, 61,179,189,207, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 40, 23,140, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,120,157,163,190, 44,219, 33, 63,250, 25,167, 64,190, 81, 55,191,107,243, 71,191,
+102,237, 42, 63,237,163,214, 62,199,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 32, 39, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,175, 4,191,
+160,200, 50,190,248,214, 77, 63,226,194,110,190,138, 10,198, 61,210,213, 62, 62,141,163,253, 61,106,130,160, 61,201,229,101,191,
+103,145, 50, 62, 52,192, 61, 63, 16, 50, 23, 62, 40, 56, 1, 61, 43,254,162, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 89, 81,220, 60, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 63, 79, 63, 22,225,203,191,183, 83,133, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 40, 40, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 70,155,194,190, 82, 93, 3,191, 23,133, 19,191,179,146, 2,191,131,198,104, 62, 15,189, 93, 63, 77,226,209,190,159,122, 21,191,
+169,192,234,190, 16,128, 35, 63, 9,188,167, 62,141,167,138, 61,186,163,185, 61,147,152, 3, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 25,249,236, 59, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20,218, 89, 62,169, 21, 81,192, 50,226, 38, 64,
+190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 48, 41, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,139,169, 52, 63, 97,163,156, 62, 26,132,184,190, 82, 25, 7, 63,127,117,151, 62,254,206,247, 62, 27,144, 76, 63,
+150, 57,204, 62,184,181,246,188,196,222, 19, 63,175,237, 18, 61, 50, 0, 0, 61,180, 45,208, 62, 72,186, 6, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 61,195,186, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 91,166,190,203,138,151, 62,
+232, 4,159, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,201,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 56, 42, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,212,240, 7, 63,213, 2, 18,191,228, 90, 5,191,221, 92,178, 62, 8,236, 16, 63, 90,216,151, 62,
+155,193,128, 62, 56, 60,245,188,118,129,160,190, 47,157,113,191,114,117, 40, 63,164, 92, 37, 62, 72,198, 78, 61, 6, 28, 5, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,137, 96,226, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,137,191,191,
+143,156,208,190,234,245,116, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,202,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 64, 43, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173,218, 49,191,113,109, 23,191, 32, 16, 55, 62, 54,117,188,190, 25, 20,208, 62,
+118,245, 46,191, 72,158,236,186, 55, 10, 97,191,140,128,183, 62,177,230,146,190,121,217,174, 62, 45, 55,188, 62, 41, 76, 25, 62,
+138,146, 16, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 96, 85, 48, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+218, 6, 78,191,240,247, 2,191, 2,181,131, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 72, 44, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 25,236,189,127,158, 27, 63,123,235,239, 62, 59,108, 33, 63,
+244,198,103,190,251,192,187, 62,179, 39,101,190,110,210,138, 62,145,168, 54,191,208, 20, 63,190,237,209,211, 62, 1,168,129, 62,
+108,237, 7, 62,188, 30, 77, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 2,210,109, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,100,181,251,191,160, 67, 79, 63, 83,115,143, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,
+197,206,183,190,201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 80, 45, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122,243,237, 61, 11,234,169,190,211,226, 55,191,
+184,175, 25,191, 24,201, 39, 63,204, 23, 71,190, 87, 61,218, 62, 31,211, 39, 63,108,101,215,190, 35,125,244,189, 31, 56,250, 62,
+174,208,248, 62, 50, 43, 79, 60,252,186, 79, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 83,130,186, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,166,143, 16,192,219, 40, 31,192,188,165,240, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 88, 46, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,157, 15,191, 47, 51,205,190,
+152, 40,136,190,128,122, 44, 63,194,144, 92, 63,235, 36, 99,190,244, 22,206,190,143, 32,220, 62,169,244, 19, 63,160,205,238,189,
+ 93,255, 69, 61,131,237,129, 62,199,113, 29, 63, 16,188,169, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,249,139,151, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 16, 46,192,234,135, 17, 62,196,174,101, 64,190, 81, 55,191,107,243, 71,191,
+100,237, 42, 63,235,163,214, 62,198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 96, 47, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,186,110,162,190,
+145,104,105,190,247,168,239, 62, 3,235, 74, 63,140, 77,178,190, 80, 49, 72, 63,164, 45,112, 62, 43,101, 44, 63, 95,162,173, 62,
+180,215,104,190,132,185,112, 62, 76,198, 31, 63, 82,148,186, 61,149,140, 75, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,161,174,120, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,221, 76, 34,192,195, 63,220,191,101, 92, 19, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,104, 48, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+101, 89, 32, 62,234, 91, 82, 63,243, 78, 86, 60, 22, 61, 12, 63,249,120,178,190,203, 19, 37,191,128, 65, 24, 63,196,226, 52, 63,
+219,214, 0,191,203,228,210,190,191, 5,144, 61, 27,251,203, 62, 8,217,232, 62,185,169,156, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 7,165,113, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,209,208,191,175, 98, 57,192,214, 39,244, 63,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,112, 49, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,242,136, 6, 62,240,135, 58,191, 89,198,233, 61, 57,148, 41, 63,151,188,189,190,156, 72,189,190,184, 14, 86, 63,
+185, 54,165,190,131,220, 49, 62, 60, 87,189,189, 40,142,100, 61,206, 81, 18, 62, 52,238, 34, 63,214,209, 40, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,186,132,181, 61, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,156,146, 19,192,132,169, 38, 63,
+119,240,133, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,120, 50, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,123,191,104,191, 91, 12,172,190,100, 97,112, 62,240, 67,150, 61,237,234,241, 61,121, 15, 65,190,
+224, 2, 61, 62,159, 38,233,190,118, 62,191,187,107,119, 29, 63,177, 98,202, 62,157,134, 14, 63,246,140,213, 60, 97,116,179, 60,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,159,173, 69, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,209,211, 63,
+ 80, 57, 64,192,239, 52,100, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,128, 51, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 46,157,190,239,142, 47,191, 7,129,219, 60,124,203, 40, 63, 5,175,122,189,
+180, 33,139, 62,162, 8, 63, 61, 75,191, 26,191, 52,191,189, 61,125,188,100,190,131,222,112, 61,150,149,161, 60,127,188,202, 61,
+219,141, 82, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 34, 78, 58, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+204, 40,195, 62,169, 66, 22,192, 56, 69, 88, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,136, 52, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 69, 25, 63, 76,123,124, 62,100,238, 32,191,234,140,220, 62,
+ 84,159,120, 61,187,254,244, 61,103,215, 59, 63,244,235, 71,190, 9,172, 73,191, 94,228,165,190,237,198, 39, 62,232,166,180, 61,
+ 33, 45,106, 62, 32,238, 4, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+128,255,104, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,179, 41,124, 63,215, 52, 92,192, 1,194, 56, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144, 53, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,249,191,175, 62, 72,210, 67, 63, 91, 44,255,190,
+ 36,232, 97, 62,183, 89, 70,191, 58, 37,246,190,112,174,211, 61,231,174,119,189,237, 2,119,191,180,205, 35, 62,225,119,158, 59,
+ 62,185, 89, 59, 58, 41,150, 62,186,212, 50, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 78,102, 32, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 78,215, 66,192, 16,102, 17,189,251, 64, 82, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+152, 54, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 15,158,190, 97, 48, 27,191,
+ 48,181, 41,191, 31, 19,160,190, 91, 23,153,189,100,243,110,190,182,169,164,190, 97,129,120,191,145,101, 90, 60,193, 53,186, 61,
+ 94, 65, 31, 62,152, 57, 45, 63,117,240,248, 61, 59,128, 61, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,196, 79,137, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,243,234,243, 63, 12,199, 50,192,246,173,118, 64,192, 81, 55,191,107,243, 71,191,
+ 98,237, 42, 63,235,163,214, 62,197,206,183,190,205,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,160, 55, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,137,136, 62,
+101, 7,106,191,249,249,155,190,146,218,155, 60,179,212,184,188, 68,215,201,189, 40,244, 61,191,114,234, 70, 61,154,226, 1,191,
+119,139, 91, 63,202, 64,207, 61, 46,106, 89, 60, 30, 53, 13, 61,236,222, 89, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 6, 40, 87, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,174,176, 54,191, 99,173,187,191,209, 31, 93, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,168, 56, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 89,176, 71, 59,214, 55, 18,191, 67, 82,223,190,142, 2, 50, 63,235, 17,202, 61, 51,118,199, 62,129,125, 72, 63, 86,250, 36,191,
+ 70, 99, 90, 61,125, 38, 25, 63,101,144,129, 62,185, 1, 91, 62, 60, 67,121, 62, 32, 77,148, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 21, 69, 35, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,238,131,100,192,222,185, 81,191, 40, 50, 27, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,176, 57, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,167, 43, 35,190,242,210,225, 61,197, 58, 30, 63,229, 8, 67, 63,215,176,222, 61, 70, 15, 12, 63, 80,195,165, 62,
+218, 72,227, 61,188, 66, 87,191,145,213,195, 62,197,146, 70, 60, 83,125, 44, 63, 64,124,156, 62,125,144, 10, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,173, 74, 64, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,226, 77,248,190, 12,109,103,190,
+230,231,143, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,199,206,183,190,204,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,184, 58, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 59, 62,251,190,154,207,132, 62,191,198, 19,191,122, 82, 25,191,179,114,169,190,242, 80, 46,191,
+161, 92,100,189,125,103,188, 62, 0,234, 23,191, 12,140, 22, 63, 53,173, 3, 63,187,233, 78, 62, 77,225,187, 61,203,112, 68, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 62,205, 89, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 80, 10, 64,
+253,130, 74,192,124,179,109, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,192, 59, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89,176, 71, 59,214, 55, 18,191, 67, 82,223,190,142, 2, 50, 63,235, 17,202, 61,
+ 51,118,199, 62,129,125, 72, 63, 86,250, 36,191, 70, 99, 90, 61,125, 38, 25, 63,215, 2,202, 60, 38,116,181, 59,240,167,204, 60,
+193,223,113, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 21, 69, 35, 62,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 73, 37, 55,192, 92, 44,210,191,134, 20, 12, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,200, 60, 33, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 7, 15, 63,135,194, 46,190, 36, 82,148, 62,185, 22, 66,191,
+211,135, 53, 63,111, 29,172,190,200, 68,229, 62,253,167,140, 62,181,223, 99,190, 35,226,176,190,144,158, 50, 61, 53,247,230, 62,
+253, 25,236, 62,226,215, 52, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+202,199,214, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4,163,152,191,233,189, 16,192,148, 29, 39, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,208, 61, 33, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 25,236,189,127,158, 27, 63,123,235,239, 62,
+ 59,108, 33, 63,244,198,103,190,251,192,187, 62,179, 39,101,190,110,210,138, 62,145,168, 54,191,208, 20, 63,190,113,136,250, 61,
+109, 45, 71, 62,248,240,222, 62,108,172,125, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 2,210,109, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 83,219,213, 63,119,221, 77,192, 98,157, 90, 64,192, 81, 55,191,107,243, 71,191, 98,237, 42, 63,
+235,163,214, 62,197,206,183,190,205,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+216, 62, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,225, 4,191,239,172, 35, 63,
+ 92, 44, 4,191, 88,166,112,190,229,149,176,190,233,184, 6, 63, 91,120, 44,191,208, 36, 20, 63,165, 84, 79, 63,190,145, 89, 61,
+154,154,192, 60,206,233, 43, 60, 68, 13, 0, 62, 51, 72, 87, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 34,131, 32, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 39,106,191,130, 29,114, 63,156,123,164, 64,190, 81, 55,191,107,243, 71,191,
+102,237, 42, 63,235,163,214, 62,200,206,183,190,205,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 40,160,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 97, 45, 63,
+119, 47,205,190, 35,117, 19, 63,166,125, 98, 62,242,195, 73, 62,124,228,243, 62,119, 86, 11, 63, 70,156, 89, 62,230,232, 88, 63,
+130, 53,204,190,149, 27, 54, 63,243, 38,133, 62,232, 55, 53, 60, 91,130,143, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 53,129,253, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 71,102,192,241,109,194,190,108, 39, 47, 64,192, 81, 55,191,
+107,243, 71,191,100,237, 42, 63,233,163,214, 62,198,206,183,190,204,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 48,161,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+127,157,105,188,148, 8,184, 62,181,109, 7,191,177,194, 68,191,163, 77,220,190, 58,120,101, 63,241,105, 25, 61, 69,197, 86, 62,
+214, 78,236,190,126,136, 46, 63,152,203, 22, 61,132,161, 61, 63, 67,196, 79, 62, 79, 22,160, 60, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,112,148, 93, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,224,214, 63,225,182, 5,192,246, 59,136, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 56,162,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,192, 46, 24,191, 41, 20, 43,191,186,184,183, 62, 42,173,136, 62, 75, 75, 50, 63, 40, 83,126, 62,188,195, 8, 63,
+234,211,238, 62, 69, 36,152, 61,235,106,145, 62,211, 28,131, 62, 24,255, 46, 60, 11,165,139, 60,113, 88, 55, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 93,122, 57, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95,158, 92, 63,117,243, 67,192,
+ 16,154, 70, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 64,163,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,102,175, 4,191,160,200, 50,190,248,214, 77, 63,226,194,110,190,138, 10,198, 61,210,213, 62, 62,
+141,163,253, 61,106,130,160, 61,201,229,101,191,103,145, 50, 62,112, 55,104, 61, 14, 23, 9, 61,208, 82,129, 62,176, 65, 40, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 89, 81,220, 60, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,234, 31,192,
+204,234, 65,192,110,200,172, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 72,164,160, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,180, 99, 63,127,169,145, 62,114, 95,174, 62,169,121,223,189,173,190, 73, 63,
+118, 72, 51,190,116, 48,162,190, 59, 98,139,189, 77,245,191, 62, 75,124,253, 61,197,252, 48, 60,163,176, 62, 62,216, 93, 72, 63,
+ 94, 65,166, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 81, 69, 12, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 76,122,189,191,238,243,102,191,158,253, 93, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 80,165,160, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,139,218,189,160, 81,222,190, 75, 71,151,190, 47, 33, 88,191,
+152,174,128,190, 43,218,107,190, 40, 96, 66,190,219, 29,113,190, 89,240,184,190,153, 92,204, 62,101,159,135, 62,253,216,174, 62,
+217, 99, 96, 62,104,171, 50, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 5, 27,207, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,227, 75, 67, 63, 48,124, 78, 61,200,150,171, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,
+198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 88,166,160, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 19,190,190,188,203,147, 62, 19,242, 2, 62,
+223,138, 95, 63,144, 50, 24, 60,148,174, 64, 63,196,158, 11,191,220, 22, 64, 63, 98, 35, 19,190,217, 93, 44, 62,191,115, 58, 63,
+121,198, 2, 60,254,102,167, 59,178,100,132, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,189,176, 27, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 24, 37,139, 62, 4,231, 62, 63,174,205,179, 64,188, 81, 55,191,107,243, 71,191,102,237, 42, 63,
+235,163,214, 62,200,206,183,190,206,137, 61,190,156, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 96,167,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,220,239, 60,168,204, 46,191,
+ 78, 95, 84, 61, 8,105, 58,191,231,245, 43, 63, 91,254,151, 62, 77,143,206, 61,177,139, 42, 63, 26,107,196,190,150,211,139,190,
+ 50, 23, 92, 63,169, 27, 15, 61, 8, 43, 83, 60, 59, 83,189, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,121,221, 49, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32,247,225,191, 37,175, 81,192,248,254,198, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,104,168,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59,132,130, 62,
+131,166,120,190, 15,191,109,191,170,164,238, 61, 20, 93, 78,190,245,164,231,189,254,254, 16, 62, 61,189,234,190,116,167,116,189,
+ 67,175, 16, 63, 66,132, 2, 61,191, 37,189, 61,173, 5, 64, 63, 91,181, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,129, 93, 2, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,200,110,165, 61,183, 43,239, 62,129,243,169, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,112,169,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+173,218, 49,191,113,109, 23,191, 32, 16, 55, 62, 54,117,188,190, 25, 20,208, 62,118,245, 46,191, 72,158,236,186, 55, 10, 97,191,
+140,128,183, 62,177,230,146,190, 62,109, 66, 63,244,159,170, 61, 79,150,243, 60, 69,136, 2, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 96, 85, 48, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12,158,243,191,244,237,104,192,138, 34,155, 63,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,120,170,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,155, 22, 49,191,223,232,165, 62,133,208, 6,191, 93,253,190,190,190,234,194,190,239, 89, 29,191,134,110, 23,191,
+ 8,217, 30,191,107,159,205,190, 18, 94,185,190,228,106, 92, 60, 23, 25, 35, 61,136,111, 93, 63,211,105,167, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,252,153,132, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,118, 74, 8, 63, 0,240, 1,192,
+ 28,123,108, 64,190, 81, 55,191,107,243, 71,191,102,237, 42, 63,235,163,214, 62,200,206,183,190,205,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,128,171,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,217,155,104, 63,215,164, 29,190,175, 60,179,190,201,201, 43, 62,100, 60, 67, 61,171, 42, 90,189,
+ 68, 85, 4,191, 67,249,130, 62,230,199,133,190,149, 14,107, 63,233,242,101, 62,181,120,181, 61,231,136, 43, 62,245,241, 4, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,252,179,108, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 24,231,191,
+ 44,105, 21,191,186, 32, 98, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,198,206,183,190,203,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,136,172,160, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 52, 49,191,201, 9, 43, 63,166,234, 96,190,182,210, 37,190,206, 58, 54, 61,
+231, 1, 63, 63,133,173, 34,191, 5,154,170,190, 93,112, 51, 63, 18, 61, 23,191, 66,189,138, 62,114,103,210, 62,117,128, 62, 62,
+ 35, 54, 7, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 33,132,126, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+141, 52, 5,191, 10,103, 49,192,230,154, 37, 64,190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,
+206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144,173,160, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 96, 32, 63,185,201,160, 62,160, 3, 6, 63, 11, 34,248,190,
+206, 53,185, 60,192,197,178, 61,174,184, 53, 63,223,172,162,190,109,136,224, 62,142,173, 61,191,132, 47,184, 61,244,157,207, 61,
+168, 0,225, 62,249, 11,189, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+248,112,150, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,136, 45,177,191, 22,253, 99, 63, 8, 58,155, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,
+197,206,183,190,202,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,152,174,160, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,202, 55, 63,249,235, 89,190,127, 18, 92,190,
+146,129, 32,191, 7,212, 8,190,167, 50,171,190, 97,120,123, 62,232,152,249,189,140, 18,149, 62, 37,111, 13, 61,147,253, 28, 63,
+231,184,184, 62, 48, 48, 58, 60, 59, 78,111, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,115, 61, 18, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 42,255, 57,191,235, 4, 65,192, 77, 7, 19, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+160,175,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,218,133,189,116, 10,176,189,
+186,237, 10, 63, 14, 61, 85, 63,182,219, 38,190,174,175,206, 62, 47,240, 10, 63, 31,232,114,190, 91,162,207,190,173, 85,193,190,
+228,255,128, 61, 76, 32,172, 61,147,152, 5, 63,205,134,169, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 62, 38,212, 60, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 68,137,191,204,177,226, 61,196,247,141, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,168,176,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133,138,146, 61,
+133, 75, 8,187, 28,235, 68, 62,122,141,122, 63,116,117, 92, 63, 7,147,125,190, 87, 49,147,190, 9, 88, 41, 63, 63,255, 2, 63,
+ 71, 44,126, 61,107,166, 0, 63, 23, 29,154, 62, 34,214,165, 61, 42,130,236, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,241,170,103, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22,103, 82,192, 73, 75,201,191, 1,247, 0, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,176,177,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+231,120,168, 62,179,154, 7,191, 41,180, 48, 63,239,232,187,190, 9, 35,104,191,222, 8,114, 62, 76,143,177,190,107, 29, 28,191,
+210,112,234, 62, 9,249, 92,190, 73,109,118, 59,168,155, 4, 63, 73, 2,243, 62,186,198,108, 59, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 74, 4,184, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,194,241,246,191, 87,130,236, 62, 50,209,135, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,184,178,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,124,197,223, 62, 32,243,189,190,199,213,140,190, 13,149, 69,191,221,235,199,190,159, 79,240, 62,113,202, 14,190,
+186,168, 60,190, 5,145,220,190, 42, 8,148, 62, 49, 99,219, 62, 85, 73,242, 62,127, 14, 79, 61, 68,141, 67, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,157,236,192, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,224,228,149,189,233, 13,221,190,
+210,251,145, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,199,206,183,190,204,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,192,179,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 92, 19,190,190,188,203,147, 62, 19,242, 2, 62,223,138, 95, 63,144, 50, 24, 60,148,174, 64, 63,
+196,158, 11,191,220, 22, 64, 63, 98, 35, 19,190,217, 93, 44, 62,198,141, 4, 63, 3, 71, 19, 62, 60,186,174, 61, 99,146,129, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,189,176, 27, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120, 89, 62,
+164,169,120,190, 26, 78,155, 64,192, 81, 55,191,109,243, 71,191, 98,237, 42, 63,234,163,214, 62,197,206,183,190,202,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,200,180,160, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,201, 94, 63,192,189,213, 62,142, 27, 67, 62,214, 93, 55,190, 6,154,131,190,
+133, 48,178,190,139, 11,192,190, 39,123,147,189, 29,130, 57,191, 46,253, 33,190,224, 89, 24, 63,189,174,198, 61, 2,152,101, 61,
+143,237,128, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 59,122,117, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 92, 80, 26,192,232, 3,239,189,182,210, 99, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,208,181,160, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,148, 16,153,190,224, 1, 33,191, 43,253,168, 62,254, 36, 35, 63,
+124,255, 19,191, 70, 97,138,190,188,109, 6, 62, 64, 58,223,190,154,121,189,189, 9,126,170, 62,115,248,126, 62, 84, 41, 12, 63,
+153, 55, 4, 62, 62, 85,152, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 74,244,106, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 80,245, 70,190,136,148, 37,192, 41,107, 57, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,216,182,160, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,246,249, 62,200,102,140, 62,154,199, 10, 63,
+ 40,102, 32, 63, 78, 10, 19,191,224,238,250,190, 0, 13,111,190,243,232,187, 61,106, 10, 99, 62,163, 96,221, 62,208,237,239, 61,
+ 10, 34,210, 61, 62,101,181, 62,205, 22,218, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 35,143, 25, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,253,172, 25,191, 68,234,249,191, 59,217, 73, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 32, 31,127, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,109,230, 62, 67, 47,189,190,
+205,119,155,189,238, 53, 79,191,223,144, 88,191, 88,163,146, 62, 63, 99,208,190,236,235,130, 62, 72, 10, 17,190,124,223, 15, 63,
+ 12,172, 64, 62,160, 24, 51, 62,145, 49,156, 62, 26,236,169, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,254,237, 72, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 63, 60,192,192, 70,245,191,246,177,248, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,240, 34,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50,162, 16, 63,
+ 33,180,219,190, 24,166,177,190,234, 8, 29,191, 24, 26, 48,190,240, 70,115,190, 0,197, 54, 63, 69,201, 75, 62, 28,174, 10,189,
+ 81,128, 78, 63,172,109,175, 60, 7,135,214, 62, 59, 12, 9, 63,150,154,198, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 34, 50,138, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,125,162, 63, 63,233, 64,192,147,167, 86, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,192, 46,159, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+234,120, 11, 63,200, 35,253,190, 2,152,233,190, 0, 38, 0,191,214, 3, 36,191, 3,239, 45,190,135,175, 9,191, 18,130, 42,190,
+156,197, 38, 63,181, 37,238,190, 4, 49,119, 61,119,251,224, 60, 94, 5, 47, 62,188,195, 61, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 89,162,191, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,184, 96, 27,192,251, 23,179,191,193, 77, 38, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,128, 56,155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,177,231, 32,191,150, 89,239, 62,128,156,188,190,225, 45, 0,191,247,133,210, 62, 51,169, 40, 63,146,184, 26, 63,
+209, 39,223,190,182,238, 15,191, 75, 63,146,190,166,161,213, 61,217,242,218, 62, 39, 18,191, 62, 89, 74,194, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 81,236,129, 61, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,185, 0, 21,191,137,241, 14,192,
+206, 27, 61, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 72, 93,155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,214, 79,213,190, 95, 19, 10, 63, 60, 25, 56,191,193,193, 10, 62,127,232, 10,190,162,126, 93,190,
+ 25,169, 7, 63, 38,209,221,190, 52,214,186, 62, 21, 63, 41,191, 58, 36, 27, 62,245,151, 28, 62, 82, 23,179, 62,148, 10,177, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 98,241, 41, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 57,189,
+193, 80,166,191,242,172,123, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,200,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,160, 13,165, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,160,174,232, 62, 64, 99,164, 61, 41,108, 12, 63,106,126, 50,191, 66,117,124, 62,
+134, 54, 82, 63, 38, 55,191, 62,121,232,197,190,188,203, 70,189, 26, 88, 51,191,199,225,170, 62,114, 67, 23, 62,202, 56, 33, 62,
+ 26,224,184, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,216,213,138, 61,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+202,106,219,190, 17,216,127, 63,140,251,173, 64,190, 81, 55,191,110,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,168,139, 8, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,214, 79,213,190, 95, 19, 10, 63, 60, 25, 56,191,193,193, 10, 62,
+127,232, 10,190,162,126, 93,190, 25,169, 7, 63, 38,209,221,190, 52,214,186, 62, 21, 63, 41,191, 10,203, 79, 63,104, 14, 32, 62,
+252,238, 44, 60, 55,180,175, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 98,241, 41, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,111, 39, 91,192, 64, 81,150,191, 89, 68, 15, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 40,137, 8, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,212, 0,191, 15,161, 38,191,131,203,123,190,
+207, 48, 3,191,112, 6, 64, 63,137, 53, 34,190,175,202, 6,191, 66,241, 19, 62,119,105, 85,190,149,246,146, 61, 25, 88, 25, 60,
+ 85, 74, 25, 63,199,185,196, 62,210,179,249, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,198,223, 90, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,231, 17, 40, 63,141, 44,153,190, 68,123,161, 64,190, 81, 55,191,107,243, 71,191,102,237, 42, 63,
+235,163,214, 62,200,206,183,190,205,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+168,134, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,219, 68, 63,190, 75, 74, 62,
+250,129,229, 62,198, 78,210,190, 65, 63, 59,188,173,173,214, 62, 18,159, 85, 62, 25,160,185,189,169,193, 46,191,177, 21, 77,190,
+202,133, 32, 63, 25,163, 36, 61, 45,136,225, 60,133, 71,156, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 22,208,141, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 95,160, 63, 34,101,249,191,176, 96,132, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 40,132, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,179, 25,236,189,
+127,158, 27, 63,123,235,239, 62, 59,108, 33, 63,244,198,103,190,251,192,187, 62,179, 39,101,190,110,210,138, 62,145,168, 54,191,
+208, 20, 63,190, 62, 45,138, 62, 35,142, 30, 61,173, 78,128, 61,170,246, 32, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 2,210,109, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,133, 6,192,167,152,225,191, 84, 16, 32, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 24,254, 17, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+184, 57,241, 62,209,244,173, 62,202,195,188, 61,229, 10, 79, 63, 15,223, 34,191,171, 65, 40,190,158,228, 38, 61,187,225, 12, 63,
+198,196, 13,189,185,253, 14,191,245,107,217, 61,253,147,174, 62,227,232,218, 62, 70, 80, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 8,168,183, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 99,228,190, 44, 59, 51,191,221, 75,133, 64,
+192, 81, 55,191,109,243, 71,191, 98,237, 42, 63,234,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,232,132,165, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 52,191, 23, 63,247,209, 82, 62, 34, 21,204, 62, 21, 58, 43, 63, 1, 3,139, 61, 52,159,135, 61, 30,117, 36,189,
+230,123,244, 62, 79,104,185, 62, 17, 73, 33, 63,117,208,213, 62,118,118, 76, 62, 32,254, 5, 62, 65,245,128, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,179,246, 4, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85,101, 74,192,166,185,105,191,
+ 18,141, 36, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 40, 69, 18, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,221,157, 3, 63, 67, 81,215, 62,135, 46, 5, 63,121,108, 9,191, 37, 83, 16,190, 37,244,130,190,
+191, 18,216, 62,221, 44, 53, 63,153,136,162,189, 80,138,252,190,221,214,102, 61, 50, 22, 25, 63,139, 42,157, 62,164,113, 30, 61,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,145,208, 26, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,122,234,218,191,
+ 50,177,232,191,108,174, 42, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,216, 29, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 41, 59,191,236, 70,252, 61, 77, 96, 25,191, 33,195,154,190, 31,119,242,190,
+125, 79,204,190, 23, 53, 18,190,102, 31,214,190,165,174,199,190, 48,105,169,188,229, 50, 8, 62,227,251,148, 62,133, 65,206, 62,
+ 75, 82, 49, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 44,230, 5, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+254,106,206,191,205, 36,150, 62, 96, 42,137, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,198,206,183,190,
+203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 56,146,150, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52,191, 23, 63,247,209, 82, 62, 34, 21,204, 62, 21, 58, 43, 63,
+ 1, 3,139, 61, 52,159,135, 61, 30,117, 36,189,230,123,244, 62, 79,104,185, 62, 17, 73, 33, 63, 87, 15,231, 62, 49,237,207, 62,
+254, 43,141, 61,226,225,150, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+179,246, 4, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,200, 61,167, 63,119, 5,171,191, 86,214,147, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,
+197,206,183,190,201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,224,233, 63, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, 39, 70, 63, 91,103,218,188, 44, 24, 30, 63,
+ 28, 81, 12, 62, 26,129, 16, 63,215,153,162, 61, 11,203, 31,191,222,132, 2, 63, 26, 4,154,190,202,112,100, 62,216, 36,214, 62,
+172, 85,122, 60, 44,247,142, 60,132,140, 12, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 48, 61,115, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,194, 14,251,191, 44,213,105,190,165,188,109, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,
+235,163,214, 62,198,206,183,190,203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+160,168,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,173, 49, 3,191,178,133, 9, 63,
+104, 18, 16, 63,159, 16,186, 62,183,147,245, 62,220, 88,111, 62,220, 25, 2, 63, 80, 44, 77,191, 76,136,152, 62,126,242,176, 61,
+239, 13,155, 62, 40, 17,234, 62, 92,128, 13, 62,226,130,208, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 65,147,208, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 47, 46,192, 64,212, 45, 63, 61, 35,127, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,240, 12,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,164, 48, 63,
+ 32,100, 38,191,163,157,157,190, 10, 78,167, 61, 4, 8, 54, 59,139,155,147,190, 11, 41, 50, 63, 27,101,140, 62,241,237,110, 63,
+ 18,188,179, 59, 74, 31,165, 62,207,208, 37, 63, 74,227,141, 60, 8, 28, 76, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,129, 24, 80, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,203, 83,191,133, 15, 29,192,237, 82, 42, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 24, 38,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 41,194,232,190,156,110, 35, 63,233,200, 75,190,170,158, 22,191, 83,122,193,189,217, 58,149,189, 80, 15, 18,191, 66, 37,145,189,
+ 98,184,219,189, 70,185, 86,191, 21,150,239, 61,130,193, 24, 62, 46, 71,217, 62,141,114,158, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,122,231, 75, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 71,102, 63, 16, 13, 44,191, 24,187,156, 64,
+190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,201,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144,156,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,120, 40, 61,190,150,196, 15,191,159,219, 54,191,234,195,191, 62,104, 96,122,190,193, 71, 74,191, 15,230, 56,190,
+ 61,156,203, 61,227, 39,177, 61, 25,222,193,190,178,206, 13, 63,144,101,237, 60, 16,227,198, 60, 16, 30,201, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 74,137,189, 61, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,210,252, 62,216, 58, 44,191,
+ 98,217,149, 64,192, 81, 55,191,109,243, 71,191, 98,237, 42, 63,234,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 64, 16, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 86,152, 38, 63,169,225, 17,191, 57,217,140,189, 67,124,254,190, 13, 65, 17, 62,229,204, 15, 63,
+180,148,241, 62,175,210, 73,191,182,161, 21, 63,186,222,169,188,235,174, 4, 63,125,216,156, 61,114,228,115, 61,124,239,176, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 86,104,165, 61, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,181,210, 46,192,
+ 59, 4,135,191,164, 99, 44, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,202,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,168, 33,164, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,119, 97, 45, 63,119, 47,205,190, 35,117, 19, 63,166,125, 98, 62,242,195, 73, 62,
+124,228,243, 62,119, 86, 11, 63, 70,156, 89, 62,230,232, 88, 63,130, 53,204,190,154, 69,201, 61, 74,143, 3, 63,155, 10,162, 62,
+186, 21,146, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 53,129,253, 62,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 64,235, 64, 60,203,210,147, 63,205, 32,185, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,201,206,183,190,
+200,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,104,249,161, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,137,136, 62,101, 7,106,191,249,249,155,190,146,218,155, 60,
+179,212,184,188, 68,215,201,189, 40,244, 61,191,114,234, 70, 61,154,226, 1,191,119,139, 91, 63,135,168,109, 63, 87, 44,112, 61,
+106, 72,115, 59,214, 90, 24, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 6, 40, 87, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,160,185, 0,192,197,235, 38,192,182,221,245, 63,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,184, 34,155, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,241, 54,241, 62, 25, 75, 60,190,137, 31,166,190,
+ 26,162, 76, 63,214, 23,180, 62,134, 28, 22,191,189,125,184, 62,170,143, 49, 63, 42,100,208, 62,201,182, 12, 63, 85,123,103, 61,
+230, 65, 90, 62, 33,215, 29, 63,124, 5,233, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,233, 6, 78, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,132,118,247,191, 87, 66, 8,192, 93, 88, 20, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+168,154,160, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,183,149,157, 62,169,241,150, 62,
+210, 72, 5, 63,196, 98, 61,191, 94, 43,103,191,141,249, 13, 62,108, 40, 28,190,180,143, 89,189,159,169,180, 62, 50,210,102, 63,
+ 15,245,186, 61,252,211,140, 62,237,184,252, 62,164,107, 15, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,234, 53,126, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96,252, 2,190,189, 32, 63,192,249,176, 40, 64,190, 81, 55,191,107,243, 71,191,
+ 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 48, 13,132, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,227,185,185, 62,
+ 69, 55,133,190, 76,101,246, 62,146, 32, 65,191, 11,142, 47,190,207,240, 16,191,178, 47,250, 60,147, 12,135, 62,250,130,192,190,
+182,224, 63, 63,109,251,141, 61,209, 15,135, 61,152,122,212, 62,150, 66,230, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,194, 22,201, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,186, 37, 60,192,209, 36, 19,192,200,102,212, 63,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 88, 27, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+133,116,253,190,160,178, 23, 63,114, 78, 32,191, 57, 97,221, 61,191,244,236,189,206, 56,214, 62, 77,142, 40,191, 31, 48,161, 61,
+ 82, 95, 7, 63,244, 70, 62,190,144,146,141, 59, 24,189,182, 62, 12, 24, 34, 63,242, 33,183, 59, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 51, 4, 90, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,165,155, 63, 35,188,200,191,156,201,140, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,104,124, 20, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68,198,205, 62, 50, 21, 99, 63, 18,246, 86,190,237, 24,178,189,229,177, 74, 62,233, 94,174,190, 14,113, 17,189,
+144,148,211, 62,157,182, 80,190, 18,214, 66,191, 54,112,182, 62,156,202, 2, 61, 65,146, 40, 61, 24, 18, 18, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,229, 84,124, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,150, 48, 1, 63,133, 14,211, 62,
+120,209,175, 64,190, 81, 55,191,107,243, 71,191,102,237, 42, 63,235,163,214, 62,200,206,183,190,205,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 32, 41,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,181, 60,183, 21, 39, 63,174, 28, 42,191,206,254,185, 62, 60,101,180, 61,224,164,162, 62,
+169, 22, 78,191, 15,164,146,190, 66, 47,188, 62,233,255, 63,191, 26, 61, 76, 63,214,234,171, 60,230,187, 47, 60,126,146, 46, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,113,195, 41, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,196,144, 98, 62,
+ 62,190,112,191,153,224,138, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,200, 89,169, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 80,148,190, 17,138, 5, 63,171, 16, 38, 62,107, 50, 73,191,214,126, 32, 63,
+143, 14,148, 62,183, 31, 4,191, 70,152,145, 62, 21, 32, 89,189, 63,239,100, 62, 51,212,220, 62, 49, 96,238, 61, 1,246,205, 61,
+ 64, 22,180, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,247, 33, 76, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80,243, 2,192, 18, 84, 91,191,110, 0, 77, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,232, 96,169, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,146, 69,191,236,123, 69,190,179,188, 26,191,207,182, 47,189,
+ 96, 14,105,191, 55,120, 31,190,138, 41, 18, 62,210, 73,183,189,105, 99, 57,189, 32,155,137,190,112,143, 79, 62, 13, 36,220, 62,
+207,171,119, 62,168,124, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+184,151,199, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,228, 81, 34, 62,178, 55, 39,192, 87, 36, 68, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144, 82,169, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,148, 3, 63,224, 68,239, 62, 72, 64,241, 62,
+ 71, 35, 11,191,248,202, 31,191, 68, 98,182, 62, 18,127, 48,191,158,108, 26,189,145, 93,173,190,161,155, 16,191,144, 72,244, 61,
+152, 98,173, 61, 16,243,154, 62, 38,162,252, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63, 69,111,245, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,226,206,132,191,153,157,254,191, 61, 78, 57, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+224, 31,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 64,217, 62,151, 24,213,190,
+ 94,174,187, 61,102,136, 76, 63, 27, 1, 32, 63,236, 95,162,189,124, 18, 29,191, 75, 78,155,190,124,134, 43,191,174,202,184,190,
+ 49,138, 35, 62,237,209, 85, 62,126, 75,186, 62,113, 6,137, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,111,100, 76, 61, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,228,163,237, 62, 55, 20, 58,192, 9,122, 64, 64,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 88, 20,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 95, 55,189,
+ 43, 21,181,190,230, 3,101,191, 87,248,137, 62, 4,208, 75, 62, 0,115,115, 59,100,196, 95,190,191, 15, 83, 62, 84,222, 81,191,
+ 36, 58,169, 62,187,215,163, 61, 90,207, 92, 61,188,248,152, 62,182, 59, 17, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,230,119,112, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,202, 59,148,191,188,242, 56,191,189,111,113, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,176, 23,162, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+202, 21,192, 61,216, 22, 8, 63,188, 84, 66, 63,158, 70,186, 62,240,211, 98, 62,124, 7,155, 62, 10,134,246, 62,110, 16, 79,190,
+248,197,252,189, 81,188, 39, 63, 42,204,169, 62,204,195,154, 62,146,225, 51, 62,125,254, 66, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,123, 26, 81, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34,179,252,191, 86,102,184,191,169,174, 51, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 32,160,148, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,232, 50,144,190,207, 31, 50,191,179,203, 40,191,214, 99, 45,189,109,153, 34,190,239, 94, 10,191,115,186,212,190,
+ 42,234, 19,190, 72, 26, 97,191,122,105, 99, 61, 46,210, 21, 62,250, 32,186, 62,195,126,178, 62, 85,238, 16, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,131,240,124, 60, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,244, 77,192, 51, 52,163,190,
+ 30,234, 62, 64,190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,168, 37,155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,126, 41,112, 63, 56,166,164, 61, 91, 4,240, 61, 15,172,161, 62,106,126,191,190,117, 33, 64, 63,
+130,227,184, 62, 92, 20,244,190,210,168,180,189, 60, 25, 43,191, 89,246,198, 61, 30,130, 46, 63,223,241, 54, 62,221, 41, 46, 61,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,190,196,107, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 27,122, 63,
+179,229,133,191, 66, 39,149, 64,190, 81, 55,191,107,243, 71,191,102,237, 42, 63,235,163,214, 62,200,206,183,190,205,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,176, 38,155, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192, 46, 24,191, 41, 20, 43,191,186,184,183, 62, 42,173,136, 62, 75, 75, 50, 63,
+ 40, 83,126, 62,188,195, 8, 63,234,211,238, 62, 69, 36,152, 61,235,106,145, 62,216, 4,239, 62,235,100, 21, 61,174, 73, 20, 61,
+ 83,197,235, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 93,122, 57, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 20, 66,151,191,208,139, 62,192, 98,118, 5, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,224,124, 8, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,159,160, 32,190,190, 39, 52,191,142,138, 9,191,138, 13,224, 62,
+166,218,242, 62, 93, 71, 26, 63, 36, 22, 52, 62,231, 52,124, 62,165, 91,192,190,148,111, 86,191,212,101,120, 61, 72, 26,221, 61,
+158, 82, 22, 63,241, 14,122, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+195, 96, 22, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,224, 63, 46,190,222,105,107,191,198,191,132, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+201,206,183,190,200,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,232,125, 8, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47,202, 55, 63,249,235, 89,190,127, 18, 92,190,
+146,129, 32,191, 7,212, 8,190,167, 50,171,190, 97,120,123, 62,232,152,249,189,140, 18,149, 62, 37,111, 13, 61, 89,238,204, 62,
+ 10, 90, 39, 62,123,156, 6, 62, 98, 22,156, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,115, 61, 18, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,250,148,234,190, 11,179, 97,192, 16,215, 3, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+200,205, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,177,227,248,190,160,134,192,190,
+155,159,184, 62,105,157, 51, 63, 2, 56, 54, 63, 88,126,182, 62,108,207, 4,187, 38,216,198, 62,140, 66, 73,191,139,126,248, 61,
+251, 26,119, 60, 34,207,150, 60,170,176, 20, 63,225,120,197, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,208,234,216, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,202,177,135,191,150,220, 86,192,144, 9,239, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,208,206, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,201,122, 18,191,
+155, 68,163,190,236, 36, 39,191,221,182,194,190,217, 47, 98,190, 97, 46,230,190,197,236,134, 62,216, 40,187, 60,111, 92,179,189,
+ 71, 17, 54, 63, 87,169, 5, 61,120,116, 92, 61,179,253, 38, 63,225,192,133, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,100, 58,154, 60, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,213,105,108,192,125,145,223, 62,192,182, 82, 64,190, 81, 55,191,
+107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,160,173,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+195,244, 32,190,174,189,218,190,163, 11, 55, 62,157, 75, 95,191, 33,155,243,190,180, 86, 90,191, 57,237, 86, 62,226,198,126,190,
+ 30, 34,101, 61, 93,239,180,190,206, 82,204, 61, 44,113, 89, 63, 63, 63, 23, 61,220, 33,100, 60, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 6, 63, 50, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 23,243, 62, 46,133,166,191, 78,153,134, 64,
+192, 81, 55,191,109,243, 71,191, 98,237, 42, 63,234,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,168,174,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,173,218, 49,191,113,109, 23,191, 32, 16, 55, 62, 54,117,188,190, 25, 20,208, 62,118,245, 46,191, 72,158,236,186,
+ 55, 10, 97,191,140,128,183, 62,177,230,146,190,159, 2,190, 62, 29,141,193, 61,214, 93,214, 61,164, 2,220, 62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 96, 85, 48, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,130,192,214,190,182, 57, 73,192,
+175, 83, 23, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,216, 53,153, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,206,172, 34,191, 64, 79,187, 62,140,197, 11, 62,199,135, 42, 63,100, 91,148, 61,123, 75, 25, 60,
+ 54,126,232,189,210,190,220,189, 9,158,186, 62,182, 62,225,190,211,103, 84, 61, 92,194,115, 61,148,216,253, 62, 41, 34,201, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 38,103,162, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 4,133,192,
+109,136,128, 62,136, 58, 58, 64,190, 81, 55,191,107,243, 71,191, 98,237, 42, 63,235,163,214, 62,198,206,183,190,206,137, 61,190,
+157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,224, 54,153, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,147,206,137, 62,234,207, 11, 63,195,144,225, 62,162,225, 40, 63, 24, 69,148,190,
+ 50,238,190, 61, 13, 31, 86,191,217,106, 71, 63,247, 60, 1, 62,162,250,136, 62, 70, 80,156, 58,142,100,108, 63, 15, 72,153, 61,
+116, 35, 17, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,174,199, 41, 60,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+132, 40, 12, 62,102, 32, 1,192,222,178, 95, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,232, 55,153, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,157, 57, 95, 63,238,148,214, 62, 87,249,109, 62,227,220,204,189,
+238,118,221,189,121,162, 19,191,203, 50, 48,191, 58,232, 80,190,141,100, 8,191,229,142, 19, 63,223,196, 88, 62,134, 94,237, 61,
+141, 5, 97, 62, 43,195,231, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 75, 11, 15, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,211,109, 80, 63, 96,210, 20,192,246,253,103, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 72,253,149, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 32,133, 62, 13,201,189,190, 55, 43, 66, 63,
+ 76,254,239, 62,254,163,179, 62, 15,181,171,188,130, 8,196, 60,214, 27, 14,191, 86, 32,128,190,190, 27,208,190, 69,196, 53, 62,
+136,184,135, 61,240,250, 35, 62, 34,153, 24, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,224, 93,234, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,240,142,147,191, 43, 7,166,190, 61, 69,130, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 80,254,149, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,246,249, 62,200,102,140, 62,
+154,199, 10, 63, 40,102, 32, 63, 78, 10, 19,191,224,238,250,190, 0, 13,111,190,243,232,187, 61,106, 10, 99, 62,163, 96,221, 62,
+ 56,243,206, 62,109,170,159, 62,224,145, 2, 62,211, 50, 32, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63, 35,143, 25, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,254, 89,191,195,197, 85,192,176,197,254, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 88,255,149, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122,125,204, 62,
+ 37, 10, 46, 63, 69, 71, 26,190,130,168, 24, 63,117,105, 36,190,144,220, 32, 63, 11,167,231, 62,151,145,179, 62, 33, 72, 36,190,
+ 42, 67, 50,191,111, 3, 11, 61,241, 2, 76, 61,231,181, 28, 63,103,179,155, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,244,186,188, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 46,253,191,200,126,214, 61,248, 1,125, 64,190, 81, 55,191,
+109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 96, 0,150, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+171,218,181,190,162,100, 80, 63, 86, 18,175,190,142, 51,157,190, 18, 35, 4,191,207,113,210, 62, 0,170, 11, 63,134,126,165,190,
+141, 47, 59, 62,104,163, 62,191, 18,251,181, 62,225,163,242, 62, 90, 98,191, 61,220, 33,158, 61, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 83, 76,104, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 18, 94,192,112, 61, 49, 61, 90,153, 71, 64,
+190, 81, 55,191,109,243, 71,191, 98,237, 42, 63,236,163,214, 62,197,206,183,190,202,137, 61,190,157, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,144, 17,162, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,126, 41,112, 63, 56,166,164, 61, 91, 4,240, 61, 15,172,161, 62,106,126,191,190,117, 33, 64, 63,130,227,184, 62,
+ 92, 20,244,190,210,168,180,189, 60, 25, 43,191,141,188,190, 61,118,157, 68, 63,105,119,224, 61,112,129,239, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,190,196,107, 62, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 34,141,191,222,140, 39,192,
+182, 55, 25, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,152, 18,162, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,193, 40, 85, 63,120, 79,146,190, 68,249,203,190,207,217,131, 62,229, 65, 22, 63,120,104, 63, 63,
+173,135,124,189,131,179,190,190,208, 81,171, 62,211,132, 69, 63,122, 6,189, 61, 58,195, 23, 62, 6,114,254, 62,189,106,134, 62,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,179,102, 20, 63, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,149, 14, 63,192,
+ 64,204,165,191, 12, 96, 24, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,160, 19,162, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 81, 30,191,157, 39,223, 62,214, 30, 11, 63, 76, 51,186, 62,206,228, 83, 62,
+209,146, 0, 61, 22,106,121, 63, 44,124, 6,187,128,233, 71,187,218,190,173, 62, 14, 67, 83, 61,192,186, 4, 63, 39,206,197, 62,
+178,159, 50, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,208, 19, 52, 60,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+183,180, 22,192,126,173, 4,192,240,189, 8, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,
+199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,168, 20,162, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 59, 20,191, 30, 36, 17, 63,112, 57,252,190, 32,101,162, 62,
+139, 6,160, 62, 57,160, 80, 61,109,243,245, 61, 41, 18,224,190,182,154,227,188,238,196,139,190,133, 49,131, 61,130, 33,167, 62,
+160,225, 5, 63,124, 59,177, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 20,166, 56, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 35,160, 97, 63,129,220,163,191,194,248,141, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,
+200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,184,109, 8, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,183,149,157, 62,169,241,150, 62,210, 72, 5, 63,
+196, 98, 61,191, 94, 43,103,191,141,249, 13, 62,108, 40, 28,190,180,143, 89,189,159,169,180, 62, 50,210,102, 63, 78,174,206, 62,
+ 68,159, 93, 61,160, 84,118, 61, 54,211,246, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0,128, 63,234, 53,126, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4,223, 18,192,155,169,140,191,151, 18, 57, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,
+234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+192,110, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,186, 63, 44, 63,134,104,136, 62,
+ 44,117, 32, 63,178,227,147,190,254, 77, 90, 63, 0,117,175,190,119, 69,167, 62,238, 73,138, 61, 58,211,189, 62,210, 28, 37,191,
+245, 96, 21, 62, 35,104,227, 62, 83, 62,154, 62, 64,164,222, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0,128, 63,130, 27,151, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,193,179,191,251,111, 78,192,166, 64,228, 63,190, 81, 55,191,109,243, 71,191,
+100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66,200,111, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,101, 4,191,
+237, 90, 0, 63,104,125,239,190,131, 31, 3, 63,200,160,212,190,115,217, 27, 63, 55,189, 6,190,131,223, 22,190, 4,241,223,190,
+ 4, 70, 0,190, 37,242, 35, 61,204,214,171, 61,175, 25, 46, 63, 82,177, 72, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,184,249,202, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 90,124,191,113, 48,212,191, 56,208, 74, 64,190, 81, 55,191,
+109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66,208,112, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+179, 25,236,189,127,158, 27, 63,123,235,239, 62, 59,108, 33, 63,244,198,103,190,251,192,187, 62,179, 39,101,190,110,210,138, 62,
+145,168, 54,191,208, 20, 63,190,187,178, 81, 62,176, 57,108, 62, 93,177,153, 62,108, 88,135, 62, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 2,210,109, 63, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,251,231, 33,192,132, 2, 59,191, 78,162, 66, 64,
+190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66,216,113, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,192, 46, 24,191, 41, 20, 43,191,186,184,183, 62, 42,173,136, 62, 75, 75, 50, 63, 40, 83,126, 62,188,195, 8, 63,
+234,211,238, 62, 69, 36,152, 61,235,106,145, 62,217, 15, 30, 62,227,209, 4, 63,178,148,117, 62,218, 39,178, 61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 93,122, 57, 63, 0, 0, 0, 0,255,255,255,255,
+ 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,185,138, 63,191,128, 41,192,
+139,193, 97, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,158, 38, 80,191,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 80,240,163, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,231,120,168, 62,179,154, 7,191, 41,180, 48, 63,239,232,187,190, 9, 35,104,191,222, 8,114, 62,
+ 76,143,177,190,107, 29, 28,191,210,112,234, 62, 9,249, 92,190, 0,196,250, 61, 79,120, 62, 61,195, 12, 31, 62,202,252, 44, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63, 74, 4,184, 62, 0, 0, 0, 0,
+255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,242, 63,243,190,
+ 86,176,159,191,245,150,111, 64,190, 81, 55,191,109,243, 71,191,100,237, 42, 63,234,163,214, 62,200,206,183,190,199,137, 61,190,
+158, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 88,241,163, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 26, 58,191, 1, 70,159, 62,113,111, 2, 63,235,187,173,190,116, 51,237, 62,
+130, 53,247, 62,243,199, 26,190,235, 88,172,189,118,115,244, 62, 34,147, 5,191,217, 77,158, 62, 43,131, 72, 62,119,208, 68, 62,
+ 86, 8,155, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,253,152,110, 63,
+ 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+198,178, 48,191,138, 39, 52, 62, 39,252,149, 64,190, 81, 55,191,107,243, 71,191,100,237, 42, 63,235,163,214, 62,198,206,183,190,
+203,137, 61,190,157, 38, 80,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 96,242,163, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41,167,210,190,194,172,139, 62,250,220, 35, 63, 30,182, 22,191,
+122, 3,136, 61,109,164,176,190, 30,153,147,190,255,248, 10,188,234, 90,160,190, 89,241,205,190, 62, 71, 19, 63,111,215,107, 62,
+ 63, 71,138, 61,243,231, 1, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,200, 66, 0, 0,200, 66, 0, 0, 0, 0, 0, 0,128, 63,
+ 37,227, 77, 62, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,144,233,164, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,
+ 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 31,224,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,168,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,
+151,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 31,224,124, 62,143, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,232,211,127, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 15, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+232,146, 16, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186, 63,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,239, 61, 14, 61,219,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,251,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189,
+ 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,142,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,240,147, 16, 3, 23, 1, 0, 0, 9, 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, 7, 82,145,186,255,223,124, 59, 56,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 84,145,187,255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,127, 35,188,255, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188, 15,224,124, 61,
+123,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,171, 20,227,188, 15,143,197, 61, 80, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,136,127, 35,189, 15, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 43,138, 94,189,151,155, 65, 62,182,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189, 31,224,124, 62,
+139, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,248,148, 16, 3, 23, 1, 0, 0,
+ 9, 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, 7, 85,145,186,
+127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,243, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 15, 85,145,188,251,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,
+ 5,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,180,127, 35,189, 8, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,142,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 11, 85,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 0,150, 16, 3, 23, 1, 0, 0, 9, 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, 7, 82,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 84,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,126, 35,188,247, 61, 14, 61,
+219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,135, 84,145,188, 7,224,124, 61,125,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,107, 20,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+104,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,251,137, 94,189,145,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,231, 84,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 8,151, 16, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 58,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188,
+ 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 15,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 75,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189,
+ 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 16,152, 16, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,223,223,124, 60,
+186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,247, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,251,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 5,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 8, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,142,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 24,153, 16, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187, 15,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,
+ 7, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 23,224,124, 61,127,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 18,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,
+152,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 34,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 32,154, 16, 3, 23, 1, 0, 0, 9, 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,135, 84,145,186,255,223,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,223, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,132,127, 35,188, 3, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+252, 84,145,188, 19,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,207, 20,227,188, 15,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,169,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 50,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 7, 85,145,189, 31,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+ 40,155, 16, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,143,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+223,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,250, 61, 14, 61,218,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 4,224,124, 61,124,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189,
+ 11, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 43,138, 94,189,146,155, 65, 62,183,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189, 26,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 48,156, 16, 3, 23, 1, 0, 0, 9, 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, 7, 87,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,199, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,128, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,255,223,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,192,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 75,138, 94,189,145,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 25,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 56,157, 16, 3, 23, 1, 0, 0,
+ 9, 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, 7, 86,145,186,
+255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,188, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,239, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 39, 85,145,188,239,223,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,
+255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 3, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,135,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 23, 85,145,189, 17,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 64,158, 16, 3, 23, 1, 0, 0, 9, 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, 71, 84,145,186,239,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+199, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,120,127, 35,188, 2, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,247, 84,145,188, 17,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+165,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 48,138, 94,189,147,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189, 28,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 80, 12, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 8,128, 35,188,255, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,
+ 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 7,143,197, 61, 82, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 7, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 91,138, 94,189,143,155, 65, 62,186,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189,
+ 23,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 88, 13, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+135, 84,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,255,223,124, 60,
+186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188, 3, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188, 17,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+211, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 53,138, 94,189,148,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 10, 85,145,189, 29,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 96, 14, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,
+255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,255,223,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 83,138, 94,189,
+143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 27, 85,145,189, 23,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,104, 15, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 23,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 19, 85,145,189, 27,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+112, 16, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,239, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,247,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189,
+ 5, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,138,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 19,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,120, 17, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,128, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 15,224,124, 61,
+126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 83,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 27, 85,145,189, 23,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,128, 18, 33, 3, 23, 1, 0, 0,
+ 9, 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, 7, 85,145,186,
+255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 85,145,187,223,223,124, 60,189, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,247, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 23, 85,145,188, 7,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,
+ 11,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 11, 62, 14, 62,165,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,145,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 15, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,136, 19, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,247, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 7,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 11,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+168,127, 35,189, 13, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 43,138, 94,189,145,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 25,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,144, 20, 33, 3, 23, 1, 0, 0, 9, 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,135, 84,145,186, 63,224,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187, 55,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,152,127, 35,188, 17, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188,
+ 30,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 24,143,197, 61, 80, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,164,127, 35,189, 18, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 55,138, 94,189,155,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 9, 85,145,189,
+ 36,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,152, 21, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 85,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,239, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,139,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 19,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,160, 22, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+255, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 15,224,124, 61,124,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 15,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 15, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,
+151,155, 65, 62,182,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 31,224,124, 62,139, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168, 23, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 23, 85,145,188, 23,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 19,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 15, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+176, 24, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,191,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,
+247,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188, 0, 62, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 14,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,171, 20,227,188, 13,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189,
+ 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 27,138, 94,189,147,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,251, 84,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,184, 25, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,223,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+184,127, 35,188,247, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 31, 85,145,188,255,223,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,243, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,188,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 67,138, 94,189,141,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 17, 85,145,189, 22,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,192, 26, 33, 3, 23, 1, 0, 0,
+ 9, 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, 7, 85,145,186,
+255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188,
+ 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 11, 62, 14, 62,165,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 23, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,200, 27, 33, 3, 23, 1, 0, 0, 9, 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, 71, 84,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+199, 84,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188, 7, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188, 23,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,211, 20,227,188, 19,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+170,127, 35,189, 15, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 56,138, 94,189,147,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 13, 85,145,189, 25,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,208, 28, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 84,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 72,127, 35,188, 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188,
+ 15,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,171, 20,227,188, 7,143,197, 61, 80, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 11, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 27,138, 94,189,147,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189,
+ 19,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,216, 29, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,103, 85,145,188,255,223,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+ 75, 21,227,188, 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,216,127, 35,189, 7, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,143,155, 65, 62,186,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 23,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,224, 30, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187, 31,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,
+ 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 23,224,124, 61,127,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 27,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 19, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,
+155,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 35,224,124, 62,141, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,232, 31, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,104,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+231, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,187, 20,227,188, 7,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 35,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+255, 84,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+240, 32, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,221,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 15,224,124, 61,128,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0, 11, 21,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189,
+ 13, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,147,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 29,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,248, 33, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187, 31,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188, 7, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 23,224,124, 61,
+126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 19,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 75,138, 94,189,149,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 33,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 0, 35, 33, 3, 23, 1, 0, 0,
+ 9, 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,135, 84,145,186,
+255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,215, 84,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,144,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,251, 84,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,207, 20,227,188,
+ 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,166,127, 35,189, 13, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 45,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 8, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 8, 36, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+135, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,239, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+200,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,139,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 15,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 16, 37, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 58,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,168,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,
+ 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 51,138, 94,189,145,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189,
+ 29,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 24, 38, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+ 11, 21,227,188, 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 11, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 32, 39, 33, 3, 23, 1, 0, 0, 9, 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, 7, 82,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 83,145,187,191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,126, 35,188,
+239, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,135, 84,145,188,255,223,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 75, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0, 88,127, 35,189,255, 61, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,219,137, 94,189,
+135,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,223, 84,145,189, 15,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 40, 40, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,222,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,239, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 23, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,255,142,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 3, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,137,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 11, 85,145,189, 15,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+ 48, 41, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,127,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+223,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,251, 61, 14, 61,218,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 3,224,124, 61,124,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188, 8,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189,
+ 10, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 27,138, 94,189,143,155, 65, 62,183,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,247, 84,145,189, 24,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 56, 42, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,224,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,128, 35,188, 15, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 31,224,124, 61,
+127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 27,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,216,127, 35,189, 23, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 91,138, 94,189,157,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 37,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 64, 43, 33, 3, 23, 1, 0, 0,
+ 9, 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, 7, 87,145,186,
+ 15,224,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187, 19,224,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,232,127, 35,188, 12, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 39, 85,145,188, 28,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188,
+ 25,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 19, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,155,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 31, 85,145,189, 35,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 72, 44, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186, 63,224,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 3, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 19,224,124, 61,127,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+168,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,148,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 29,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 80, 45, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186, 33,224,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187, 29,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 8,128, 35,188, 11, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,
+ 24,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 24,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 18, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 91,138, 94,189,157,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189,
+ 37,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 88, 46, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 85,145,187,255,223,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 11, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 27, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 96, 47, 33, 3, 23, 1, 0, 0, 9, 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, 7, 82,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,127, 35,188,
+ 7, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,167, 84,145,188, 15,224,124, 61,125,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,139, 20,227,188, 15,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,136,127, 35,189, 11, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 11,138, 94,189,
+143,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,247, 84,145,189, 23,224,124, 62,140, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,104, 48, 33, 3, 23, 1, 0, 0, 9, 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,135, 84,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,215, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+255, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,223, 20,227,188, 15,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,174,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 57,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 12, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+112, 49, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189,
+ 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,147,155, 65, 62,186,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 31,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,120, 50, 33, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,191,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187, 15,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,128, 35,188, 7, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 23,224,124, 61,
+127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 17,143,197, 61, 83, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 14, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 91,138, 94,189,146,155, 65, 62,186,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 26,224,124, 62,
+143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,128, 51, 33, 3, 23, 1, 0, 0,
+ 9, 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, 7, 86,145,186,
+255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 39, 85,145,188,255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188,
+ 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,139,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 31, 85,145,189, 19,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,136, 52, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 71, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,239, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,251, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+192,127, 35,189, 6, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,140,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 21,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,144, 53, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,127,223,124, 59, 56,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,136,127, 35,188,247, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188,
+255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 7,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 91,138, 94,189,141,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189,
+ 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,152, 54, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 11, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,160, 55, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,224,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 84,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,
+ 47, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 63,224,124, 61,125,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 47,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,168,127, 35,189, 27, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 43,138, 94,189,
+167,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189, 51,224,124, 62,139, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168, 56, 33, 3, 23, 1, 0, 0, 9, 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,135, 84,145,186, 31,224,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187, 31,224,124, 60,188, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188, 16, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 31,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,215, 20,227,188, 22,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,172,127, 35,189, 17, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 53,138, 94,189,151,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 9, 85,145,189, 32,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+176, 57, 33, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,
+255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,247, 84,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189,
+ 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,143,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,184, 58, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,191,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+104,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188,247,223,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,171, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 35,138, 94,189,145,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189, 26,224,124, 62,
+140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,192, 59, 33, 3, 23, 1, 0, 0,
+ 9, 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, 7, 84,145,186,
+255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,
+ 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 23, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,200, 60, 33, 3, 23, 1, 0, 0, 9, 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,191, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+229, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,154,127, 35,188,255, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,232, 20,227,188, 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+182,127, 35,189, 7, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 65,138, 94,189,139,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 16, 85,145,189, 19,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,208, 61, 33, 3, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 58,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187, 31,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,168,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,247, 84,145,188,
+ 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 51,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189,
+ 31,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,216, 62, 33, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,224,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187, 63,224,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188, 47, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 47,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+171, 20,227,188, 47,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 27, 62, 14, 62,
+163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 27,138, 94,189,167,155, 65, 62,183,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0,247, 84,145,189, 49,224,124, 62,139, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 40,160,160, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 84,145,187,191,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,127, 35,188,
+239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,167, 84,145,188,255,223,124, 61,125,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,107, 20,227,188, 11,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,104,127, 35,189, 9, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,251,137, 94,189,
+143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,239, 84,145,189, 23,224,124, 62,141, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 48,161,160, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59,
+ 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+231, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,171, 20,227,188, 31,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 11,138, 94,189,159,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+247, 84,145,189, 39,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+ 56,162,160, 2, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,219,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188,255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188, 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,192,127, 35,189,
+ 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,139,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 19,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 64,163,160, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,247,223,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 5, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 59,138, 94,189,138,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 19,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 72,164,160, 2, 23, 1, 0, 0,
+ 9, 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, 7, 84,145,186,
+255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,231, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188,
+ 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 11, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 23, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 80,165,160, 2, 23, 1, 0, 0, 9, 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,135, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+231, 84,145,187, 15,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188, 7, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,247, 84,145,188, 19,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 17,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+164,127, 35,189, 14, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,148,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189, 30,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 88,166,160, 2, 23, 1, 0, 0, 9, 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, 7, 83,145,186,255,222,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 84,145,187,191,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 40,127, 35,188,223, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188,
+239,223,124, 61,124,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,155, 20,227,188,255,142,197, 61, 80, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,128,127, 35,189,255, 61, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 11,138, 94,189,131,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,243, 84,145,189,
+ 15,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 96,167,160, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,191,223,124, 60,
+186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,239, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188,255,223,124, 61,124,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+139, 20,227,188,247,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,120,127, 35,189,255, 61, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,251,137, 94,189,131,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0,239, 84,145,189, 11,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,104,168,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+ 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 31,224,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 23,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,
+147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 39, 85,145,189, 27,224,124, 62,143, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,112,169,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,222,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,239, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+103, 85,145,188,255,223,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188,255,142,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 3, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,135,155, 65, 62,186,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 23, 85,145,189, 19,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+120,170,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 15, 62, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0, 11, 21,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189,
+ 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,151,155, 65, 62,186,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 27,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,128,171,160, 2, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188,231, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,215, 84,145,188,231,223,124, 61,
+126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,171, 20,227,188,247,142,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 1, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 27,138, 94,189,135,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,251, 84,145,189, 15,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,136,172,160, 2, 23, 1, 0, 0,
+ 9, 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, 7, 83,145,186,
+191,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,239,223,124, 60,186, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,104,127, 35,188, 3, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,231, 84,145,188, 15,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,187, 20,227,188,
+ 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 11, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 35,138, 94,189,145,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0,255, 84,145,189, 25,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,144,173,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186, 63,224,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 85,145,187, 47,224,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188, 15, 62, 14, 61,
+218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 29,224,124, 61,125,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 24,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+168,127, 35,189, 17, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,155,155, 65, 62,
+183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189, 35,224,124, 62,140, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,152,174,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 8,128, 35,188, 7, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,
+ 23,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 43, 21,227,188, 23,143,197, 61, 82, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,216,127, 35,189, 15, 62, 14, 62,166,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 91,138, 94,189,150,155, 65, 62,186,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189,
+ 30,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,160,175,160, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187, 15,224,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 11, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 23,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 19,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 17, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,151,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 33,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,168,176,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,191,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187, 15,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,
+ 7, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 19,224,124, 61,127,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 17,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,184,127, 35,189, 14, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,
+151,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 34,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,176,177,160, 2, 23, 1, 0, 0, 9, 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,103, 84,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,191, 84,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,144,127, 35,188, 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 3, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,223, 20,227,188, 7,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,174,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 63,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 15, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+184,178,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,191,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,
+ 3,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188, 4, 62, 14, 61,221,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 18,224,124, 61,128,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0, 43, 21,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189,
+ 14, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,149,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 26,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,192,179,160, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,247, 84,145,188,247,223,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,160,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 51,138, 94,189,145,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189, 25,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,200,180,160, 2, 23, 1, 0, 0,
+ 9, 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, 7, 87,145,186,
+255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 85,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 40,128, 35,188, 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 71, 85,145,188, 31,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 27, 21,227,188,
+ 31,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,208,127, 35,189, 27, 62, 14, 62,163,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,163,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 27, 85,145,189, 43,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,208,181,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+135, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188, 7, 62, 14, 61,
+221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 19,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+184,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,147,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,216,182,160, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,127,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,207,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0, 8,128, 35,188,244, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188,
+254,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 5,143,197, 61, 82, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 9, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189,
+ 25,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 32, 31,127, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,241,223,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,253, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 11,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+219, 20,227,188, 13,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 12, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,146,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,240, 34,167, 2, 23, 1, 0, 0, 9, 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,199, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,247, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,160,127, 35,188,
+255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 11, 85,145,188,255,223,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,231, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,178,127, 35,189, 7, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 61,138, 94,189,
+143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 14, 85,145,189, 23,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,192, 46,159, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,239, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188,239,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188,255,142,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 3, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,137,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 23, 85,145,189, 17,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+128, 56,155, 2, 23, 1, 0, 0, 9, 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,135, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,215, 84,145,187,
+255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,140,127, 35,188, 15, 62, 14, 61,219,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,251, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,178,127, 35,189,
+ 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 61,138, 94,189,147,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 72, 93,155, 2, 23, 1, 0, 0, 9, 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, 7, 85,145,186, 13,224,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187, 31,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+168,127, 35,188, 9, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 22,224,124, 61,
+127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 16,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 14, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 59,138, 94,189,148,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 30,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,160, 13,165, 2, 23, 1, 0, 0,
+ 9, 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,199, 84,145,186,
+255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,159,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,144,127, 35,188,231, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 7, 85,145,188,239,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,217, 20,227,188,
+255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,175,127, 35,189, 5, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 56,138, 94,189,140,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 11, 85,145,189, 21,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,168,139, 8, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,224,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+135, 85,145,187, 63,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,128, 35,188, 31, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,103, 85,145,188, 47,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0, 75, 21,227,188, 39,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+248,127, 35,189, 27, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,139,138, 94,189,163,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 55, 85,145,189, 43,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 40,137, 8, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,222,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,152,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,
+ 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 7,143,197, 61, 82, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 59,138, 94,189,139,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189,
+ 19,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168,134, 8, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,255,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 84,145,187,191,223,124, 60,
+186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188,255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+187, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 3, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 35,138, 94,189,139,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0,255, 84,145,189, 19,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 40,132, 8, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 71, 85,145,187,255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,255,223,124, 61,125,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,251, 20,227,188, 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,
+139,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 19,224,124, 62,141, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 24,254, 17, 3, 23, 1, 0, 0, 9, 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,199, 84,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 3, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 15,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,180,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 63,138, 94,189,147,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 15, 85,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+232,132,165, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,
+ 31,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188, 39,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,227, 20,227,188, 33,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189,
+ 24, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,162,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 17, 85,145,189, 45,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 40, 69, 18, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 59,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 19,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,216, 29, 16, 3, 23, 1, 0, 0,
+ 9, 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,135, 84,145,186,
+255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,255, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188,
+ 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 15, 62, 14, 62,165,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 9, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 56,146,150, 2, 23, 1, 0, 0, 9, 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, 7, 82,145,186,223,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 84,145,187,235,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,126, 35,188,251, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,167, 84,145,188, 9,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,107, 20,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+120,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,251,137, 94,189,145,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,239, 84,145,189, 28,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,224,233, 63, 0, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,222,124, 59, 56,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,191,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,168,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,
+255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 3, 21,227,188, 7,143,197, 61, 80, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,196,127, 35,189, 7, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 87,138, 94,189,143,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 29, 85,145,189,
+ 23,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,160,168,126, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 84,145,186,191,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 84,145,187,223,223,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,251, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188, 11,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+155, 20,227,188, 13,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,136,127, 35,189, 12, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 19,138, 94,189,144,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0,247, 84,145,189, 24,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,240, 12,167, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0,135, 85,145,187, 31,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,
+ 7, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 15,224,124, 61,127,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,200,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,
+143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 23,224,124, 62,141, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 24, 38,164, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,239,223,124, 60,188, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 3, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 17,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,149,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 23, 85,145,189, 29,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+144,156,160, 2, 23, 1, 0, 0, 9, 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,135, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,103, 85,145,187,
+255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,248,127, 35,188,255, 61, 14, 61,219,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 55, 85,145,188, 15,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0, 35, 21,227,188, 15,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,220,127, 35,189,
+ 15, 62, 14, 62,162,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,107,138, 94,189,151,155, 65, 62,182,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 37, 85,145,189, 31,224,124, 62,139, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 64, 16, 16, 3, 23, 1, 0, 0, 9, 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,135, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,103, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+184,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 31,224,124, 61,
+126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 31,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,180,127, 35,189, 23, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 71,138, 94,189,159,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 18, 85,145,189, 43,224,124, 62,
+141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168, 33,164, 2, 23, 1, 0, 0,
+ 9, 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, 7, 85,145,186,
+255,222,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 15, 85,145,188, 15,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,243, 20,227,188,
+ 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 11, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 83,138, 94,189,151,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 25, 85,145,189, 27,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,104,249,161, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,222,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+135, 85,145,187,191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,239, 61, 14, 61,
+221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188,255,223,124, 61,127,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0, 75, 21,227,188, 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+216,127, 35,189, 7, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,107,138, 94,189,143,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 31, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,184, 34,155, 2, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,
+ 31,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 23,143,197, 61, 82, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 67,138, 94,189,151,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189,
+ 31,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168,154,160, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 85,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 85,145,187,255,223,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 15, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 31,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 48, 13,132, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,143,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187,223,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+251, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 2,224,124, 61,125,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 11,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,168,127, 35,189, 11, 62, 14, 62,163,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 43,138, 94,189,
+145,155, 65, 62,183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 7, 85,145,189, 27,224,124, 62,139, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 88, 27, 16, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59,
+ 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 23, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 7,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 19, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+104,124, 20, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,
+191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188,239, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 15, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,235, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189,
+ 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,143,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 32, 41,167, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,191,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,127, 35,188,239, 61, 14, 61,218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188,239,223,124, 61,
+124,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,139, 20,227,188,247,142,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,120,127, 35,189,251, 61, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 11,138, 94,189,131,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,239, 84,145,189, 11,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,200, 89,169, 2, 23, 1, 0, 0,
+ 9, 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, 7, 85,145,186,
+255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,191,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,176,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 19, 85,145,188,239,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,231, 20,227,188,
+255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,179,127, 35,189, 5, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 65,138, 94,189,139,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 16, 85,145,189, 21,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,232, 96,169, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+199, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,104,127, 35,188,255, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,239, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 11,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+164,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,145,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 25,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,144, 82,169, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,127,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,207,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,200,127, 35,188,243, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188,
+251,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 3,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 75,138, 94,189,141,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189,
+ 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,224, 31,167, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 85,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+219, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 88, 20,167, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+247, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,255,223,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,184,127, 35,189, 6, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,
+141,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 22,224,124, 62,141, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,176, 23,162, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59,
+ 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 71, 85,145,187, 13,224,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 5, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 19,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,227, 20,227,188, 17,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189, 14, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,149,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 13, 85,145,189, 31,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+ 32,160,148, 2, 23, 1, 0, 0, 9, 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,151, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,219, 84,145,187,
+255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,140,127, 35,188, 7, 62, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,249, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,205, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189,
+ 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,147,155, 65, 62,185,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 10, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,168, 37,155, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+ 8,128, 35,188,255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 15,224,124, 61,
+125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 91,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 27, 85,145,189, 23,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,176, 38,155, 2, 23, 1, 0, 0,
+ 9, 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,175, 84,145,186,
+255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,224, 84,145,187,191,223,124, 60,188, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,142,127, 35,188,239, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0, 1, 85,145,188,239,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,207, 20,227,188,
+255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,164,127, 35,189, 3, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 42,138, 94,189,135,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 4, 85,145,189, 15,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,224,124, 8, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 85,145,187, 31,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 7, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188, 23,224,124, 61,127,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 19,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+168,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,
+186,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 31,224,124, 62,143, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,232,125, 8, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 56,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,176,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 19, 85,145,188,
+255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,231, 20,227,188, 3,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,178,127, 35,189, 9, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 63,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189,
+ 24,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,200,205, 16, 3,
+ 23, 1, 0, 0, 9, 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,
+ 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187, 31,224,124, 60,
+187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 19,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 15, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,151,155, 65, 62,186,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 31,224,124, 62,143, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,208,206, 16, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,
+ 7, 62, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,184,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,
+151,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 31,224,124, 62,143, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,160,173,161, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59,
+ 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,255, 61, 14, 61,217,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+231, 84,145,188, 15,224,124, 61,123,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61,
+ 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 11, 62, 14, 62,163,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,147,155, 65, 62,182,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 7, 85,145,189, 27,224,124, 62,139, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+168,174,161, 2, 23, 1, 0, 0, 9, 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, 71, 85,145,186,255,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 39, 85,145,187,
+255,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,144,127, 35,188, 15, 62, 14, 61,219,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188, 31,224,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,223, 20,227,188, 31,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189,
+ 23, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 63,138, 94,189,161,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 14, 85,145,189, 43,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,216, 53,153, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187, 15,224,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,231, 84,145,188, 15,224,124, 61,
+127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 17,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 15, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 59,138, 94,189,150,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 30,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,224, 54,153, 2, 23, 1, 0, 0,
+ 9, 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, 7, 84,145,186,
+255,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 84,145,187,255,223,124, 60,185, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 72,127, 35,188,255, 61, 14, 61,217,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,231, 84,145,188,255,223,124, 61,123,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188,
+ 15,143,197, 61, 80, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,152,127, 35,189, 7, 62, 14, 62,163,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 43,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0,255, 84,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,232, 55,153, 2, 23, 1, 0, 0, 9, 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, 7, 85,145,186,127,223,124, 59, 56,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+ 7, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,247, 61, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188,255,223,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 3,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+176,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,141,155, 65, 62,
+184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 72,253,149, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,200,127, 35,188,239, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 39, 85,145,188,
+255,223,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 3,143,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 5, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 75,138, 94,189,139,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189,
+ 21,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 80,254,149, 2,
+ 23, 1, 0, 0, 9, 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,
+ 7, 86,145,186,255,223,124, 59, 59,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,
+189, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188, 1, 62, 14, 61,221,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 16,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+235, 20,227,188, 15,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,184,127, 35,189, 13, 62, 14, 62,
+165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 30,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0, 88,255,149, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187,223,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,
+255, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 7,224,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 11,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,168,127, 35,189, 11, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 59,138, 94,189,
+145,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 29,224,124, 62,143, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 96, 0,150, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,191,223,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,135, 85,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188, 11, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 39, 85,145,188, 19,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0, 11, 21,227,188, 21,143,197, 61,
+ 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,200,127, 35,189, 17, 62, 14, 62,165,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 91,138, 94,189,153,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 31, 85,145,189, 33,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+144, 17,162, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 86,145,187,
+255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,128, 35,188,255, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 71, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0, 43, 21,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,216,127, 35,189,
+ 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,107,138, 94,189,147,155, 65, 62,183,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 39, 85,145,189, 27,224,124, 62,140, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,152, 18,162, 2, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,255,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+200,127, 35,188, 7, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 15,224,124, 61,
+127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 13, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 43,138, 94,189,147,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 15, 85,145,189, 31,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,160, 19,162, 2, 23, 1, 0, 0,
+ 9, 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,135, 84,145,186,
+255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,255,223,124, 60,187, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,255, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,215, 20,227,188,
+ 7,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,174,127, 35,189, 11, 62, 14, 62,165,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 57,138, 94,189,143,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 13, 85,145,189, 23,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0,168, 20,162, 2, 23, 1, 0, 0, 9, 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,135, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+231, 84,145,187,255,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188, 15, 62, 14, 61,
+220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 15, 85,145,188, 31,224,124, 61,126,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,211, 20,227,188, 23,143,197, 61, 82, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+168,127, 35,189, 15, 62, 14, 62,165,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,147,155, 65, 62,
+185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 11, 85,145,189, 27,224,124, 62,142, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,184,109, 8, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 57,146,131, 62,
+ 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,247, 84,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63,
+ 0, 0, 0, 0,152,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 11, 85,145,188,
+255,223,124, 61,125,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,227, 20,227,188,255,142,197, 61, 81, 2,158, 63,
+ 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,180,127, 35,189, 7, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62,
+ 0, 0, 0, 0, 73,138, 94,189,143,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 20, 85,145,189,
+ 23,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,192,110, 8, 3,
+ 23, 1, 0, 0, 9, 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,
+135, 84,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,231, 84,145,187,255,223,124, 60,
+188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,136,127, 35,188,255, 61, 14, 61,220,123, 65, 63, 0, 0, 22, 66,
+ 0, 0, 32, 63, 0, 0, 0, 0,255, 84,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,
+211, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 15, 62, 14, 62,
+164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 55,138, 94,189,147,155, 65, 62,184,177,216, 63, 0, 0,175, 66,
+ 0, 0, 0, 62, 0, 0, 0, 0, 12, 85,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65,216, 0, 0, 0,200,111, 8, 3, 23, 1, 0, 0, 9, 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, 7, 86,145,186,255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63,
+ 0, 0, 0, 0, 7, 85,145,187, 63,224,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,200,127, 35,188,
+ 15, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188, 31,224,124, 61,126,101,127, 63,
+ 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,235, 20,227,188, 23,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62,
+ 0, 0, 0, 0,184,127, 35,189, 15, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 75,138, 94,189,
+151,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 35,224,124, 62,142, 17,245, 63,
+ 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,208,112, 8, 3, 23, 1, 0, 0, 9, 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,135, 84,145,186, 15,224,124, 59,
+ 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,199, 84,145,187,251,223,124, 60,188, 71, 2, 63, 0, 0,200, 65,
+ 0, 0, 64, 63, 0, 0, 0, 0,152,127, 35,188, 8, 62, 14, 61,220,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,
+ 7, 85,145,188, 22,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,219, 20,227,188, 17,143,197, 61,
+ 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,172,127, 35,189, 15, 62, 14, 62,164,172,187, 63, 0, 0,150, 66,
+ 0, 0,128, 62, 0, 0, 0, 0, 51,138, 94,189,148,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,
+ 9, 85,145,189, 30,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0,
+216,113, 8, 3, 23, 1, 0, 0, 9, 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, 7, 85,145,186,255,223,124, 59, 58,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,
+191,223,124, 60,188, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,168,127, 35,188,255, 61, 14, 61,220,123, 65, 63,
+ 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 23, 85,145,188, 15,224,124, 61,126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63,
+ 0, 0, 0, 0,219, 20,227,188, 15,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,176,127, 35,189,
+ 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 67,138, 94,189,147,155, 65, 62,184,177,216, 63,
+ 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 19, 85,145,189, 27,224,124, 62,141, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 80,240,163, 2, 23, 1, 0, 0, 9, 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, 7, 84,145,186,255,222,124, 59, 57,146,131, 62, 0, 0, 72, 65,
+ 0, 0, 96, 63, 0, 0, 0, 0, 7, 85,145,187,191,223,124, 60,187, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,
+136,127, 35,188,239, 61, 14, 61,219,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0, 7, 85,145,188,239,223,124, 61,
+126,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,203, 20,227,188,255,142,197, 61, 81, 2,158, 63, 0, 0,122, 66,
+ 0, 0,192, 62, 0, 0, 0, 0,168,127, 35,189, 3, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0,
+ 59,138, 94,189,137,155, 65, 62,184,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0, 23, 85,145,189, 17,224,124, 62,
+142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,216, 0, 0, 0, 88,241,163, 2, 23, 1, 0, 0,
+ 9, 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,111, 84,145,186,
+255,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,173, 84,145,187,255,223,124, 60,188, 71, 2, 63,
+ 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0,116,127, 35,188,255, 61, 14, 61,221,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63,
+ 0, 0, 0, 0,245, 84,145,188, 15,224,124, 61,127,101,127, 63, 0, 0, 72, 66, 0, 0, 0, 63, 0, 0, 0, 0,199, 20,227,188,
+ 13,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,163,127, 35,189, 13, 62, 14, 62,164,172,187, 63,
+ 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 47,138, 94,189,147,155, 65, 62,185,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62,
+ 0, 0, 0, 0, 6, 85,145,189, 28,224,124, 62,142, 17,245, 63, 0, 0,200, 66, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+216, 0, 0, 0, 96,242,163, 2, 23, 1, 0, 0, 9, 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, 7, 82,145,186,127,223,124, 59, 57,146,131, 62, 0, 0, 72, 65, 0, 0, 96, 63, 0, 0, 0, 0,
+135, 84,145,187,223,223,124, 60,186, 71, 2, 63, 0, 0,200, 65, 0, 0, 64, 63, 0, 0, 0, 0, 8,127, 35,188,247, 61, 14, 61,
+218,123, 65, 63, 0, 0, 22, 66, 0, 0, 32, 63, 0, 0, 0, 0,199, 84,145,188, 7,224,124, 61,125,101,127, 63, 0, 0, 72, 66,
+ 0, 0, 0, 63, 0, 0, 0, 0,139, 20,227,188, 7,143,197, 61, 81, 2,158, 63, 0, 0,122, 66, 0, 0,192, 62, 0, 0, 0, 0,
+136,127, 35,189, 11, 62, 14, 62,164,172,187, 63, 0, 0,150, 66, 0, 0,128, 62, 0, 0, 0, 0, 27,138, 94,189,147,155, 65, 62,
+183,177,216, 63, 0, 0,175, 66, 0, 0, 0, 62, 0, 0, 0, 0,247, 84,145,189, 28,224,124, 62,140, 17,245, 63, 0, 0,200, 66,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 76, 0, 0, 0, 80,116,164, 2, 96, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 19, 0, 0, 0, 23, 0, 0, 0, 80, 97,114,116,105, 99,108,101, 83,121,115,116,101,109, 32, 49, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,127,152, 2,120, 88,169, 2, 4, 0, 0, 0, 4, 0, 0, 0,
+ 1, 0, 0, 0, 2, 0, 0, 0, 79, 66, 0, 0, 80, 3, 0, 0,120, 3,131, 2,102, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 32,170,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,116,101,120,116,117,114,101, 0,114,101,118,105,101,119, 46, 48, 48, 53,
+ 0, 0, 0, 0, 1, 0, 0, 4, 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,104,202,152, 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,144,174, 63, 0, 61, 16,183,188,
+ 21,204,103,191, 48,234,228, 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,
+153, 39,155, 64,153, 39,155, 64,153, 39,155, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,218, 15,201, 63, 0, 0,192, 37,
+255,255,255, 36, 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,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,153, 39,155, 64,152, 39, 27, 38,102,187,232,166, 0, 0, 0, 0,
+102,187,232, 38,157,134,196, 52,153, 39,155, 64, 0, 0, 0, 0,154, 39, 27, 38,153, 39,155,192,157,134,196, 52, 0, 0, 0, 0,
+ 61, 16,183,188, 21,204,103,191, 48,234,228, 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, 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, 25, 50, 83, 62, 27, 50,211, 35, 23, 50,211,163, 0, 0, 0, 0,
+ 27, 50,211,163, 25, 50, 83, 62, 59,119,189, 38, 0, 0, 0, 0, 0, 24, 44,173, 0,179,115,175, 25, 50, 83, 62, 0, 0, 0, 0,
+236,251, 33, 59, 88, 37, 40, 59,118, 71,238, 63, 0, 0,128, 63, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 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, 10,215, 35, 61, 0, 0,128, 63,205,204,204, 62,205,204,204, 61, 0, 0, 0, 0, 4, 0, 1, 1,
+ 1, 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,128, 63,
+ 0, 64, 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,
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,144,174, 63, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 77, 65, 0, 0, 68, 2, 0, 0, 56,134,165, 2, 39, 0, 0, 0, 1, 0, 0, 0,104,137,165, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 99,104,101, 99,107,101,114,100, 97,114,107, 0, 0, 0, 97,116,101,114,105, 97, 0, 0,
+ 2, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0,116, 1,221, 61,200,251,220, 61,200,251,220, 61, 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,154,153, 89, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 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, 1, 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, 64, 1, 3, 0, 64, 1, 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, 0, 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, 16, 8, 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,176,136,165, 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, 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,
+136, 0, 0, 0,176,136,165, 2, 30, 0, 0, 0, 1, 0, 0, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 10,131, 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,
+ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,192, 63, 1, 0,192, 63, 1, 0,192, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23,183,209, 56,184,177,209, 56,184,177,209, 56, 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, 77, 65, 0, 0, 68, 2, 0, 0,
+104,137,165, 2, 39, 0, 0, 0, 1, 0, 0, 0,152,140,165, 2, 56,134,165, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 99,104,
+101, 99,107,101,114,108,105,103,104,116, 0, 0, 0, 97,116,101,114,105, 0, 0, 2, 0, 0, 0, 67, 1, 0, 0, 0, 0, 0, 0,
+ 3, 0, 1, 0,188, 65,157, 62,178, 61,157, 62,178, 61,157, 62, 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,154,153, 89, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,205,204, 76, 63, 0, 0, 0, 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,205,204,204, 61, 2, 0, 2, 0,
+ 1, 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, 64, 1, 3, 0, 64, 1, 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, 2, 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, 16, 8, 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, 64,192, 16, 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, 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,136, 0, 0, 0, 64,192, 16, 3, 30, 0, 0, 0,
+ 1, 0, 0, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 10,131, 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, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 16, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 62, 76,204,205, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 3, 8, 5, 31, 88, 32, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,220, 40,245, 0, 0, 0, 0, 63,125,112,164, 63,128, 0, 0, 63, 24,214,106, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 1, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 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,
+ 23,183,209, 56,184,177,209, 56,184,177,209, 56, 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, 77, 65, 0, 0, 68, 2, 0, 0,152,140,165, 2, 39, 0, 0, 0, 1, 0, 0, 0,
+ 0,147,165, 2,104,137,165, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,112,114,101,118,105,101,119, 0, 0, 97,116,101,114,105,
+ 97,108, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,128, 63, 61,232, 54, 63,
+184,161, 23, 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,188,248, 68, 62, 0, 0,128, 63,
+205,204, 76, 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,198,121,130, 63, 0, 0,160, 63, 0, 0, 0, 0,
+ 0, 0,160, 63, 0, 0, 0, 0, 0, 0, 0, 0,205,204,204, 61, 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, 17, 3, 3, 0, 17, 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, 1, 0, 0, 0, 2, 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, 16, 8, 1, 0,200,143,165, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,104,247,161, 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,
+216, 59,153, 2, 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,136, 0, 0, 0,104,247,161, 2, 30, 0, 0, 0, 1, 0, 0, 0, 16, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,112, 9,131, 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, 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, 16, 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, 8, 3, 0, 0,200,143,165, 2, 33, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,245, 40,220, 62, 0, 0, 0, 0,164,112,125, 63, 0, 0,128, 63,106,214, 24, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1940,1796 +4446,1858 @@ char datatoc_preview_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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65, 0, 0, 1,184,
- 2,236,199, 96, 0, 0, 0, 38, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,196,224, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,116,101,
-120,116,117,114,101, 46, 48, 48, 49, 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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 76,204,205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 2, 0, 2,
- 0, 50, 0, 6, 3, 1, 0, 3, 3, 1, 0, 3, 0, 1, 0, 4, 0, 12, 0, 4, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0,
- 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0, 63, 0, 0, 0, 61,204,204,205, 63, 0, 0, 0,
- 61,204,204,205, 61,204,204,205, 63,128, 0, 0, 0, 0, 0, 0, 5, 31, 92, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 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,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 3, 8, 5, 31, 92, 32, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,220, 40,245, 0, 0, 0, 0, 63,125,112,164, 63,128, 0, 0,
- 63, 24,214,106, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 1, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 1, 0, 2,236,201, 64, 0, 0, 0, 34, 0, 0, 0, 1, 2,236,202,112, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 84, 69,112,114,101,118,105,101,119, 0,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 64,160, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 5, 0, 8, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1,
- 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 60,204,204,205, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 84, 69, 0, 0, 1, 0, 2,236,202,112,
- 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 0, 2,236,201, 64, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69,102, 97,107,101,115,104,
- 97,100,111,119, 0, 0, 76,101,110,100, 0,101,120, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0,
- 64,160, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 64, 0, 0, 0, 64, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 40, 0, 5, 0, 4,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 60,204,204,205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 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, 77, 69, 0, 0, 1, 20, 2,236,203,160, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,208,112,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117, 98,101, 46, 48, 48, 49, 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, 2,235,160,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,233, 45, 16, 5, 31,184, 32, 8,102,176, 32, 8,170,144, 32, 5, 31, 96, 32, 5, 31,136, 32, 0, 0, 0, 0,
- 5, 31,232, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,204,224, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,236,206, 16, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0,
- 2,236,207, 64, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 1,249, 0, 0, 3,237, 0, 0, 1,244,
- 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 61, 88,133,192,189, 85, 45,184,190, 24,181,196, 63, 35, 71,185, 62,235, 31,153,
- 62,203,102,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 68, 65, 84, 65, 0, 0, 0, 4, 2,233, 45, 16, 0, 0, 0, 0,
- 0, 0, 0, 1, 2,236,194, 96, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,204,224, 0, 0, 0,242, 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, 5, 31, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 39,116, 5, 31, 96, 32, 0, 0, 0, 56, 0, 0, 1,249, 62,131,144,140, 60,200,163,119, 62, 85, 9,156,
- 92,125,170, 70, 21,228, 0,255,190, 26,222, 50, 60,200,163,119, 62, 85, 9,156,163,131,170, 70, 21,228, 0,255, 62,146,126, 61,
-188, 8, 37,223, 62, 47,183, 99, 76,247,194,191, 81,228, 2,255,190, 56,185,147,188, 8, 37,223, 62, 47,183, 99,179, 9,194,191,
- 81,228, 2,255, 62,157,176,129,188,217, 91,211, 61,246,238,244, 84, 31,181,226, 61,191, 2,255,190, 79, 30, 28,188,217, 91,211,
- 61,246,238,244,171,225,181,226, 61,191, 2,255, 62, 94, 19,115,189,128,251,103, 62, 14, 32,150, 9,241,144,155, 62, 64, 2,255,
-189,227,161, 26,189,128,251,103, 62, 14, 32,150,246, 15,144,155, 62, 64, 2,255, 62, 94, 19,115,189, 25,118,251, 62, 62,165, 20,
- 14,184,163,144, 87, 76, 2,255,189,227,161, 26,189, 25,118,251, 62, 62,165, 20,241, 72,163,144, 87, 76, 2,255, 62, 94, 19,115,
- 60, 34,107,232, 62, 92,128,116, 3, 3,131,121, 29,110, 0,255,189,227,161, 26, 60, 34,107,232, 62, 92,128,116,252,253,131,121,
- 29,110, 0,255, 62, 56,193, 58, 60,200,163,119, 62, 99,247, 77,171, 56,167,117, 36,206, 0,255,189,152,252,168, 60,200,163,119,
- 62, 99,247, 77, 84,200,167,117, 36,206, 0,255, 62, 23, 42,109,188, 8, 37,223, 62, 73,215, 88,217,152,203,122,110, 56, 0,255,
- 62, 0,197,229,188,217, 91,211, 62, 29, 14, 71,184,179,175, 93, 69, 66, 2,255,188,164, 23,249,188,217, 91,211, 62, 29, 14, 71,
- 71, 77,175, 93, 69, 66, 2,255, 61,182,231, 88, 61,121,154,159, 62, 32,201,179,151,181,255,104, 74, 51, 2,255, 60,134,121,207,
- 61,121,154,159, 62, 32,201,179,104, 75,255,104, 74, 51, 2,255, 61,242,158, 25, 61,121,154,159, 62, 73,215, 88,171, 78,255,150,
- 95,246, 2,255,188, 80,194,110, 61,121,154,159, 62, 73,215, 88, 84,178,255,150, 95,246, 2,255, 62, 41,211,138, 61,121,154,159,
- 62, 99,247, 77,133,152,254,153, 37, 98, 0,255,189,118, 66,143, 61,121,154,159, 62, 99,247, 77,122,104,254,153, 37, 98, 0,255,
- 62, 56,193, 58, 61,206,232,154, 62, 99,247, 77,170, 24, 88, 13, 35, 89, 0,255,189,152,252,168, 61,206,232,154, 62, 99,247, 77,
- 85,232, 88, 13, 35, 89, 0,255, 62, 23, 42,109, 62, 5, 79,173, 62, 73,215, 88,200,249, 65,221, 94,244, 2,255,189, 43,158, 31,
- 62, 5, 79,173, 62, 73,215, 88, 55, 7, 65,221, 94,244, 2,255, 62, 0,197,229, 62, 27,180, 54, 62, 29, 14, 71,186, 51, 78, 86,
- 73, 78, 2,255,188,164, 23,249, 62, 27,180, 54, 62, 29, 14, 71, 69,205, 78, 86, 73, 78, 2,255, 62, 94, 19,115, 62, 65, 6,111,
- 62, 14, 32,150, 11, 2,107,152, 68,114, 2,255,189,227,161, 26, 62, 65, 6,111, 62, 14, 32,150,244,254,107,152, 68,114, 2,255,
- 62, 94, 19,115, 62, 35, 43, 14, 62, 62,165, 20, 14,201, 91,180, 88, 14, 2,255,189,227,161, 26, 62, 35, 43, 14, 62, 62,165, 20,
-241, 55, 91,180, 88, 14, 2,255, 62, 94, 19,115, 61,236,195,250, 62, 92,128,116, 2,134,125, 29, 26,228, 0,255,189,227,161, 26,
- 61,236,195,250, 62, 92,128,116,253,122,125, 29, 26,228, 0,255, 62,131,144,140, 61,206,232,154, 62, 85, 9,156, 93, 54, 85, 67,
- 20,154, 0,255,190, 26,222, 50, 61,206,232,154, 62, 85, 9,156,162,202, 85, 67, 20,154, 0,255, 62,146,126, 61, 62, 5, 79,173,
- 62, 47,183, 99, 76,241, 60,161, 82, 97, 2,255,190, 56,185,147, 62, 5, 79,173, 62, 47,183, 99,179, 15, 60,161, 82, 97, 2,255,
- 62,157,176,129, 62, 27,180, 54, 61,246,238,244, 83,179, 71,157, 65, 45, 2,255,190, 79, 30, 28, 62, 27,180, 54, 61,246,238,244,
-172, 77, 71,157, 65, 45, 2,255, 62,176, 89,157, 61,121,154,159, 61,232, 1, 67,111, 40,255,113, 63,117, 2,255,190,116,112, 84,
- 61,121,154,159, 61,232, 1, 67,144,216,255,113, 63,117, 2,255, 62,161,107,237, 61,121,154,159, 62, 40, 64,139,100, 48,255,154,
- 79,167, 2,255,190, 86,148,244, 61,121,154,159, 62, 40, 64,139,155,208,255,154, 79,167, 2,255, 62,139, 7,100, 61,121,154,159,
- 62, 81, 78, 48,126,117,254,181, 19,185, 0,255,190, 41,203,227, 61,121,154,159, 62, 81, 78, 48,129,139,254,181, 19,185, 0,255,
- 62,140,229, 26, 61,121,154,159, 62, 88,197, 8,120,160,254,106, 42,198, 2,255,190, 45,135, 79, 61,121,154,159, 62, 88,197, 8,
-135, 96,254,106, 42,198, 2,255, 62,133,110, 66, 61,214, 95,114, 62, 92,128,116, 93,173, 74,126, 45, 93, 2,255,190, 30,153,158,
- 61,214, 95,114, 62, 92,128,116,162, 83, 74,126, 45, 93, 2,255, 62, 94, 19,115, 61,251,177,170, 62,103,178,185, 11, 9,115, 31,
- 54,216, 2,255,189,227,161, 26, 61,251,177,170, 62,103,178,185,244,247,115, 31, 54,216, 2,255, 62, 53, 5,206, 61,214, 95,114,
- 62,111, 41,145,181, 9, 80,184, 65, 43, 2,255,189,145,133,208, 61,214, 95,114, 62,111, 41,145, 74,247, 80,184, 65, 43, 2,255,
- 62, 34, 92,178, 61,121,154,159, 62,111, 41,145,146,116,254, 57, 66, 43, 2,255,189, 88,103, 48, 61,121,154,159, 62,111, 41,145,
-109,140,254, 57, 66, 43, 2,255, 62, 53, 5,206, 60,170,200, 22, 62,111, 41,145,182, 34,173,181, 64,115, 2,255,189,145,133,208,
- 60,170,200, 22, 62,111, 41,145, 73,222,173,181, 64,115, 2,255, 62, 94, 19,115, 61,121,154,159, 62,114,228,253, 24, 74,255,139,
-125,171, 2,255,189,227,161, 26, 61,121,154,159, 62,114,228,253,231,182,255,139,125,171, 2,255, 62, 94, 19,115, 59, 43,249,149,
- 62,103,178,185, 10,218,140,140, 54, 45, 2,255,189,227,161, 26, 59, 43,249,149, 62,103,178,185,245, 38,140,140, 54, 45, 2,255,
- 62,133,110, 66, 60,170,200, 22, 62, 92,128,116, 92,141,179,203, 44,210, 2,255,190, 30,153,158, 60,170,200, 22, 62, 92,128,116,
-163,115,179,203, 44,210, 2,255, 61, 88,133,203, 62, 23,248,202, 62, 73,215, 88, 0, 0,124, 43, 31, 17, 0,255, 61, 88,133,203,
- 61,229, 77, 34, 62,111, 41,145, 0, 0,249, 63,127,209, 0,255, 61, 88,133,203,190,188,254,150, 62, 70, 27,236, 0, 0,251,204,
-127,237, 0,255, 61, 88,133,203,190, 78, 79,191, 62, 92,128,116, 0, 0,150, 33, 71,238, 2,255, 61, 88,133,203,190, 14,221,146,
- 62, 99,247, 77, 0, 0,100, 28, 79,192, 0,255, 61, 88,133,203,190,211, 99, 30, 62, 62,165, 20, 0, 0,142,184, 59,147, 2,255,
- 61, 88,133,203, 62, 12,198,133, 62, 6,169,190, 0, 0,103,143, 75, 57, 0,255, 61, 88,133,203, 62, 91, 38, 99, 61,239,120, 28,
- 0, 0, 78,115,101, 34, 0,255, 61, 88,133,203, 62,187,243, 16,190,206,250,170, 0, 0,110,190,191,212, 2,255, 61, 88,133,203,
- 62, 87,106,247,191, 11,224,178, 0, 0, 35,144,133, 12, 3,255, 61, 88,133,203,188,157,165, 18,191, 9, 20, 33, 0, 0,214,194,
-134,213, 2,255, 61, 88,133,203,190,108, 43, 32,190,160, 83,227, 0, 0,134,154,215,113, 2,255, 62, 23, 42,109,190, 14,221,146,
- 61,232, 1, 67,113,144,198,122, 13, 79, 0,255,189, 43,158, 31,190, 14,221,146, 61,232, 1, 67,142,112,198,122, 13, 79, 0,255,
- 62, 75,106, 87,190,131, 37,138, 61,239,120, 28,122,196, 31, 19, 18,152, 2,255,189,190, 78,225,190,131, 37,138, 61,239,120, 28,
-133, 60, 31, 19, 18,152, 2,255, 62, 94, 19,115,190,192,186, 2, 61,239,120, 28,125,167, 12,146, 20,226, 0,255,189,227,161, 26,
-190,192,186, 2, 61,239,120, 28,130, 89, 12,146, 20,226, 0,255, 62,101,138, 75,190,239, 96,200, 61,202, 37,227,124,113,242,142,
- 26,196, 2,255,189,242,142,203,190,239, 96,200, 61,202, 37,227,131,143,242,142, 26,196, 2,255, 62, 82,225, 47,190,252,112,195,
- 61,194,175, 10, 79,159,159, 44, 25,210, 2,255,189,205, 60,146,190,252,112,195, 61,194,175, 10,176, 97,159, 44, 25,210, 2,255,
- 62, 11,248, 41,191, 1, 4,242, 61,224,138,107, 19,143,131, 13, 19,178, 2,255,188,253,170, 27,191, 1, 4,242, 61,224,138,107,
-236,113,131, 13, 19,178, 2,255, 61, 88,133,203,191, 2,226,168, 61,246,238,244, 0, 0,130, 75, 24, 21, 2,255, 62,131,144,140,
-189,240,242, 18, 61,202, 37,227, 47,114,137,117, 8,232, 2,255,190, 26,222, 50,189,240,242, 18, 61,202, 37,227,208,142,137,117,
- 8,232, 2,255, 62,178, 55, 83,189,143,233, 23, 61,209,156,187, 77, 25,154,198, 13,214, 2,255,190,120, 43,193,189,143,233, 23,
- 61,209,156,187,178,231,154,198, 13,214, 2,255, 62,224,222, 26, 60,140,236,182, 61,112, 21, 49,113,216,198,247, 12,255, 2,255,
-190,170,188,167, 60,140,236,182, 61,112, 21, 49,142, 40,198,247, 12,255, 2,255, 62,232, 84,243, 62, 23,248,202, 62, 2,238, 82,
-113,104, 51, 31, 30, 32, 2,255,190,178, 51,128, 62, 23,248,202, 62, 2,238, 82,142,152, 51, 31, 30, 32, 2,255, 62,196,224,112,
- 62, 50, 24,190, 62, 17,220, 2, 64,216,106,225, 27,121, 0,255,190,142,190,253, 62, 50, 24,190, 62, 17,220, 2,191, 40,106,225,
- 27,121, 0,255, 62,144,160,134, 62,106, 20, 20, 62, 47,183, 99, 75,137,101, 82, 20, 70, 0,255,190, 52,254, 39, 62,106, 20, 20,
- 62, 47,183, 99,180,119,101, 82, 20, 70, 0,255, 62, 79, 37,195, 62,154, 92, 67, 62, 70, 27,236, 38,241,119, 19, 26, 54, 2,255,
-189,197,197,186, 62,154, 92, 67, 62, 70, 27,236,217, 15,119, 19, 26, 54, 2,255, 62, 0,197,229, 62,145, 7,181, 62, 81, 78, 48,
-175, 21, 96, 54, 24, 12, 2,255,188,164, 23,249, 62,145, 7,181, 62, 81, 78, 48, 80,235, 96, 54, 24, 12, 2,255, 61,167,249,168,
- 62, 53,212, 42, 62, 77,146,196,155,174, 76,128, 21,151, 0,255, 60,194, 48,144, 62, 53,212, 42, 62, 77,146,196,100, 82, 76,128,
- 21,151, 0,255, 62, 4,129, 81, 62, 16,129,241, 62, 88,197, 8, 25, 0,237, 4,124, 22, 0,255,188,193,243, 89, 62, 16,129,241,
- 62, 88,197, 8,231, 0,237, 4,124, 22, 0,255, 61,227,176,105, 61,184,132, 17, 62, 85, 9,156,255,160,232,126,125,209, 0,255,
-187,178,169,214, 61,184,132, 17, 62, 85, 9,156, 0, 96,232,126,125,209, 0,255,189, 43,158, 31,188, 8, 37,223, 62, 73,215, 88,
- 38,104,203,122,110, 56, 0,255, 62,105, 69,184,189, 55, 82, 92, 62, 55, 46, 59, 34,106,200,119,110, 16, 0,255,189,250, 5,163,
-189, 55, 82, 92, 62, 55, 46, 59,221,150,200,119,110, 16, 0,255, 62,144,160,134,188,187,128,115, 62, 40, 64,139, 55,161,207, 60,
-104,115, 0,255,190, 52,254, 39,188,187,128,115, 62, 40, 64,139,200, 95,207, 60,104,115, 0,255, 62,176, 89,157, 61, 17, 26,205,
- 62, 29, 14, 71, 58,181,226,123,109,214, 0,255,190,116,112, 84, 61, 17, 26,205, 62, 29, 14, 71,197, 75,226,123,109,214, 0,255,
- 62,180, 21, 9, 61,177, 13, 57, 62, 29, 14, 71, 49,157,230, 61,115, 36, 0,255,190,123,231, 45, 61,177, 13, 57, 62, 29, 14, 71,
-206, 99,230, 61,115, 36, 0,255, 62,170,192,123, 61,251,177,170, 62, 36,133, 31, 39,206,234,175,119,196, 0,255,190,105, 62, 16,
- 61,251,177,170, 62, 36,133, 31,216, 50,234,175,119,196, 0,255, 62,129,178,214, 62, 27,180, 54, 62, 62,165, 20, 24, 62,255, 85,
-125,173, 0,255,190, 23, 34,198, 62, 27,180, 54, 62, 62,165, 20,231,194,255, 85,125,173, 0,255, 62, 45,142,246, 62, 42,161,230,
- 62, 81, 78, 48, 31,251,247, 40,123,158, 0,255,189,130,152, 32, 62, 42,161,230, 62, 81, 78, 48,224, 5,247, 40,123,158, 0,255,
- 61, 88,133,203,190,209,133,104, 62, 70, 27,236, 0, 0,210,148,119,170, 0,255, 61,212,194,185,190,198, 83, 36, 62, 70, 27,236,
- 19, 39,222, 65,121,248, 0,255, 58,240,196,191,190,198, 83, 36, 62, 70, 27,236,236,217,222, 65,121,248, 0,255, 61,220, 57,145,
-190,226, 80,207, 62, 58,233,167, 2,134,217,132,122, 12, 0,255,186,236,241, 77,190,226, 80,207, 62, 58,233,167,253,122,217,132,
-122, 12, 0,255, 61,167,249,168,190,237,131, 19, 62, 51,114,207,252, 13,214,169,121, 18, 0,255, 60,194, 48,144,190,237,131, 19,
- 62, 51,114,207, 3,243,214,169,121, 18, 0,255, 61, 88,133,203,190,239, 96,200, 62, 47,183, 99, 0, 0,219,150,122,180, 0,255,
- 61, 88,133,203,190, 18,152,254, 62, 77,146,196, 0, 0, 97, 46, 83, 76, 0,255, 61, 88,133,203,189,240,242, 18, 62, 73,215, 88,
- 0, 0,104,197, 73,134, 0,255, 61,205, 75,225,189,248,104,235, 62, 73,215, 88, 36, 52, 53, 2,110,187, 0,255, 59,179,158,179,
-189,248,104,235, 62, 73,215, 88,219,204, 53, 2,110,187, 0,255, 61,227,176,105,190, 33,134,174, 62, 77,146,196, 95,187,212, 14,
- 72,182, 0,255,187,178,169,214,190, 33,134,174, 62, 77,146,196,160, 69,212, 14, 72,182, 0,255, 61,190, 94, 48,190, 63, 98, 15,
- 62, 73,215, 88, 64,117,207,117, 99, 90, 0,255, 60, 81, 60,220,190, 63, 98, 15, 62, 73,215, 88,191,139,207,117, 99, 90, 0,255,
- 62,116,119,252,189,151, 95,239, 62, 40, 64,139, 49,103,196,157,102, 13, 0,255,190, 8, 53, 22,189,151, 95,239, 62, 40, 64,139,
-206,153,196,157,102, 13, 0,255, 62,174,123,231,188,217, 91,211, 62, 17,220, 2, 59,142,204,107,100,223, 2,255,190,112,180,232,
-188,217, 91,211, 62, 17,220, 2,196,114,204,107,100,223, 2,255, 62,200,155,220, 61, 46,246, 45, 62, 6,169,190, 66,102,217, 11,
-102, 65, 0,255,190,146,122,105, 61, 46,246, 45, 62, 6,169,190,189,154,217, 11,102, 65, 0,255, 62,204, 87, 72, 61,251,177,170,
- 62, 32,201,179, 54, 87,228,142,112,151, 0,255,190,150, 53,213, 61,251,177,170, 62, 32,201,179,201,169,228,142,112,151, 0,255,
- 62,191, 71, 78, 62, 16,129,241, 62, 66, 96,128, 42, 82,247, 97,120,125, 2,255,190,137, 37,219, 62, 16,129,241, 62, 66, 96,128,
-213,174,247, 97,120,125, 2,255, 62,131,144,140, 62, 79,244, 31, 62, 99,247, 77, 41,192,254,216,120,253, 0,255,190, 26,222, 50,
- 62, 79,244, 31, 62, 99,247, 77,214, 64,254,216,120,253, 0,255, 62, 75,106, 87, 62,124,189, 48, 62,118,160,105, 28,217, 7, 53,
-124,126, 0,255,189,190, 78,225, 62,124,189, 48, 62,118,160,105,227, 39, 7, 53,124,126, 0,255, 62, 23, 42,109, 62,113,138,236,
- 62,126, 23, 65,255,125, 5, 44,127,227, 0,255,189, 43,158, 31, 62,113,138,236, 62,126, 23, 65, 0,131, 5, 44,127,227, 0,255,
- 61,205, 75,225, 62, 23,248,202, 62,122, 91,213,238,130, 2, 89,126,197, 0,255, 59,179,158,179, 62, 23,248,202, 62,122, 91,213,
- 17,126, 2, 89,126,197, 0,255, 61,227,176,105,189,203,159,217, 62,107,110, 37, 23,115,230, 27,123, 34, 0,255,187,178,169,214,
-189,203,159,217, 62,107,110, 37,232,141,230, 27,123, 34, 0,255, 62, 26,229,218,190,133, 3, 64, 62, 58,233,167, 74,212, 14, 28,
-102,225, 2,255,189, 58,139,207,190,133, 3, 64, 62, 58,233,167,181, 44, 14, 28,102,225, 2,255, 62, 45,142,246,190,194,151,184,
- 62, 47,183, 99, 72,235,252, 17,105, 31, 2,255,189,130,152, 32,190,194,151,184, 62, 47,183, 99,183, 21,252, 17,105, 31, 2,255,
- 62, 53, 5,206,190,222,149, 99, 62, 36,133, 31, 66,179,225,197,104,249, 2,255,189,145,133,208,190,222,149, 99, 62, 36,133, 31,
-189, 77,225,197,104,249, 2,255, 62, 38, 24, 30,190,244,249,234, 62, 21,151,111, 44, 62,183, 4, 95, 98, 2,255,189,103, 84,224,
-190,244,249,234, 62, 21,151,111,211,194,183, 4, 95, 98, 2,255, 62, 4,129, 81,190,248,181, 86, 62, 21,151,111, 19,155,158, 52,
- 80, 54, 2,255,188,193,243, 89,190,248,181, 86, 62, 21,151,111,236,101,158, 52, 80, 54, 2,255, 61, 88,133,203,190,252,112,195,
- 62, 25, 82,219, 0, 0,154,201, 78, 88, 2,255, 61, 88,133,203,188,247, 55, 52, 62, 66, 96,128, 0, 0,252, 2,127,239, 0,255,
- 61, 88,133,203, 61, 61,227,222, 62, 85, 9,156, 0, 0,227,112,124,196, 0,255, 62, 82,225, 47, 62, 46, 93, 82, 62, 73,215, 88,
- 21, 58,254,234,126, 56, 0,255,189,205, 60,146, 62, 46, 93, 82, 62, 73,215, 88,234,198,254,234,126, 56, 0,255, 62, 4,129, 81,
- 60, 94, 34,170, 62, 77,146,196,214, 37,232,110,118,163, 0,255,188,193,243, 89, 60, 94, 34,170, 62, 77,146,196, 41,219,232,110,
-118,163, 0,255, 61,235, 39, 65, 61, 61,227,222, 62, 81, 78, 48,232,150,230,127,123, 57, 0,255,188, 21, 11,173, 61, 61,227,222,
- 62, 81, 78, 48, 23,106,230,127,123, 57, 0,255, 61,220, 57,145,190,190,220, 76, 62, 70, 27,236, 20,117,248,197,126, 36, 0,255,
-186,236,241, 77,190,190,220, 76, 62, 70, 27,236,235,139,248,197,126, 36, 0,255, 61,182,231, 88,190,133, 3, 64, 62, 77,146,196,
- 19, 43, 0,128,126,141, 2,255, 60,134,121,207,190,133, 3, 64, 62, 77,146,196,236,213, 0,128,126,141, 2,255, 61, 88,133,203,
-190,133, 3, 64, 62, 77,146,196, 0, 0,255,122,127,254, 0,255, 61, 88,133,203,190, 82, 11, 43, 62, 73,215, 88, 0, 0,184,121,
-106, 36, 0,255, 61,197,213, 8,190, 55,235, 55, 62, 92,128,116, 66,167,160,139, 53, 45, 2,255, 60, 21,134, 27,190, 55,235, 55,
- 62, 92,128,116,189, 89,160,139, 53, 45, 2,255, 61,235, 39, 65,190, 33,134,174, 62, 99,247, 77,118,133,224,215, 36,239, 2,255,
-188, 21, 11,173,190, 33,134,174, 62, 99,247, 77,137,123,224,215, 36,239, 2,255, 61,212,194,185,189,233,123, 57, 62, 92,128,116,
- 81,167, 95,141, 24, 49, 2,255, 58,240,196,191,189,233,123, 57, 62, 92,128,116,174, 89, 95,141, 24, 49, 2,255, 61,145,149, 31,
-189,226, 4, 97, 62, 92,128,116,200,189,108,160, 39, 26, 2,255, 61, 13,225, 89,189,226, 4, 97, 62, 92,128,116, 55, 67,108,160,
- 39, 26, 2,255, 61, 88,133,203,190, 22, 84,106, 62,114,228,253, 0, 0, 23, 42,125,225, 0,255, 61,153, 11,247,189,248,104,235,
- 62,107,110, 37,231,186, 78, 89, 98, 66, 2,255, 60,253,231, 82,189,248,104,235, 62,107,110, 37, 24, 70, 78, 89, 98, 66, 2,255,
- 61,197,213, 8,189,255,223,195, 62,107,110, 37, 43, 88, 62,134,102,237, 2,255, 60, 21,134, 27,189,255,223,195, 62,107,110, 37,
-212,168, 62,134,102,237, 2,255, 61,212,194,185,190, 33,134,174, 62,114,228,253, 46,247,233, 89,116,228, 2,255, 58,240,196,191,
-190, 33,134,174, 62,114,228,253,209, 9,233, 89,116,228, 2,255, 61,182,231, 88,190, 44,184,243, 62,103,178,185, 31, 46,181,198,
- 99,128, 2,255, 60,134,121,207,190, 44,184,243, 62,103,178,185,224,210,181,198, 99,128, 2,255, 61, 88,133,203,190, 63, 98, 15,
- 62,103,178,185, 0, 0,191,185,110,175, 2,255, 62, 49, 74, 98,190, 74,148, 83, 61,224,138,107,120, 23, 41, 34, 16, 99, 0,255,
-189,138, 14,248,190, 74,148, 83, 61,224,138,107,135,233, 41, 34, 16, 99, 0,255, 62, 4,129, 81,190, 40,253,134, 62, 58,233,167,
- 80,251,250, 26, 98,241, 0,255,188,193,243, 89,190, 40,253,134, 62, 58,233,167,175, 5,250, 26, 98,241, 0,255, 62, 11,248, 41,
-190, 74,148, 83, 62, 58,233,167, 83,215, 16,153, 95, 71, 0,255,188,253,170, 27,190, 74,148, 83, 62, 58,233,167,172, 41, 16,153,
- 95, 71, 0,255, 62, 38, 24, 30,190, 44,184,243, 61,224,138,107,122, 24, 35, 67, 15, 64, 0,255,189,103, 84,224,190, 44,184,243,
- 61,224,138,107,133,232, 35, 67, 15, 64, 0,255, 61, 88,133,203,190,235,165, 93, 62, 47,183, 99, 0, 0, 86,139, 94, 77, 0,255,
- 61,153, 11,247,190,233,199,167, 62, 47,183, 99,206,144, 70,200, 94,125, 0,255, 60,253,231, 82,190,233,199,167, 62, 47,183, 99,
- 49,112, 70,200, 94,125, 0,255, 61,197,213, 8,190,222,149, 99, 62, 58,233,167,164,253, 17,109, 88, 75, 0,255, 60, 21,134, 27,
-190,222,149, 99, 62, 58,233,167, 91, 3, 17,109, 88, 75, 0,255, 61,197,213, 8,190,203,236, 70, 62, 66, 96,128,225,141,168, 87,
- 88, 39, 0,255, 60, 21,134, 27,190,203,236, 70, 62, 66, 96,128, 30,115,168, 87, 88, 39, 0,255, 61, 88,133,203,190,213, 64,212,
- 62, 32,201,179, 0, 0,159, 20, 83,153, 0,255, 61,197,213, 8,190,205,201,252, 62, 36,133, 31,230, 5,177,250, 98, 20, 0,255,
- 60, 21,134, 27,190,205,201,252, 62, 36,133, 31, 25,251,177,250, 98, 20, 0,255, 61,197,213, 8,190,220,183,173, 62, 25, 82,219,
-152, 18, 24, 8, 70,188, 0,255, 60, 21,134, 27,190,220,183,173, 62, 25, 82,219,103,238, 24, 8, 70,188, 0,255, 61,153, 11,247,
-190,230, 12, 59, 62, 21,151,111,222, 26, 49,242,112,221, 0,255, 60,253,231, 82,190,230, 12, 59, 62, 21,151,111, 33,230, 49,242,
-112,221, 0,255, 61, 88,133,203,190,231,233,241, 62, 21,151,111, 0, 0, 60, 18,113, 5, 0,255, 62, 8, 60,189, 61, 76,209,142,
- 62, 92,128,116, 30, 4,244, 93,123,225, 0,255,188,223,206,186, 61, 76,209,142, 62, 92,128,116,225,252,244, 93,123,225, 0,255,
- 62, 15,179,149, 60,170,200, 22, 62, 88,197, 8, 9, 71,251, 34,127,144, 0,255,189, 13,194,190, 60,170,200, 22, 62, 88,197, 8,
-246,185,251, 34,127,144, 0,255, 62, 86,156,155, 62, 23,248,202, 62, 81, 78, 48, 17, 81, 2, 74,126,204, 0,255,189,212,179,106,
- 62, 23,248,202, 62, 81, 78, 48,238,175, 2, 74,126,204, 0,255, 62, 56,193, 58, 62, 20, 61, 94, 62, 88,197, 8, 25,218,253,177,
-125, 86, 2,255,189,152,252,168, 62, 20, 61, 94, 62, 88,197, 8,230, 38,253,177,125, 86, 2,255, 62,127,170, 64, 62, 9, 11, 25,
- 62, 88,197, 8, 21,182,240,210,125, 57, 2,255,190, 19,103, 90, 62, 9, 11, 25, 62, 88,197, 8,234, 74,240,210,125, 57, 2,255,
- 62,161,107,237, 61,229, 77, 34, 62, 51,114,207, 28,143,237,249,123,117, 0,255,190, 86,148,244, 61,229, 77, 34, 62, 51,114,207,
-227,113,237,249,123,117, 0,255, 62,167, 5, 15, 61,169,150, 97, 62, 47,183, 99, 15,209,246,217,126,175, 0,255,190, 97,199, 56,
- 61,169,150, 97, 62, 47,183, 99,240, 47,246,217,126,175, 0,255, 62,165, 39, 89, 61, 32, 8,125, 62, 43,251,247, 24,177,253,190,
-125,146, 0,255,190, 94, 11,204, 61, 32, 8,125, 62, 43,251,247,231, 79,253,190,125,146, 0,255, 62,140,229, 26,187,152,222, 60,
- 62, 62,165, 20, 33, 20, 2, 75,123,160, 0,255,190, 45,135, 79,187,152,222, 60, 62, 62,165, 20,222,236, 2, 75,123,160, 0,255,
- 62,105, 69,184,188,187,128,115, 62, 73,215, 88, 26, 85,248,238,125, 14, 0,255,189,250, 5,163,188,187,128,115, 62, 73,215, 88,
-229,171,248,238,125, 14, 0,255, 62, 34, 92,178,186,133,194,226, 62, 92,128,116, 7, 8,250,142,127,175, 0,255,189, 88,103, 48,
-186,133,194,226, 62, 92,128,116,248,248,250,142,127,175, 0,255, 62, 11,248, 41, 61,177, 13, 57, 62, 92,128,116, 34,169,240, 2,
-122, 43, 0,255,188,253,170, 27, 61,177, 13, 57, 62, 92,128,116,221, 87,240, 2,122, 43, 0,255, 62, 26,229,218, 61,251,177,170,
- 62, 92,128,116, 27,126,239,108,123,231, 0,255,189, 58,139,207, 61,251,177,170, 62, 92,128,116,228,130,239,108,123,231, 0,255,
- 62, 38, 24, 30, 61,236,195,250, 62, 81, 78, 48, 64,226,207, 13, 98,224, 0,255,189,103, 84,224, 61,236,195,250, 62, 81, 78, 48,
-191, 30,207, 13, 98,224, 0,255, 62, 19,111, 1, 61,177, 13, 57, 62, 81, 78, 48, 96, 29,229,169, 80, 81, 0,255,189, 28,176,110,
- 61,177, 13, 57, 62, 81, 78, 48,159,227,229,169, 80, 81, 0,255, 62, 41,211,138, 59,205,106, 77, 62, 81, 78, 48, 55, 36, 71,122,
- 90,188, 0,255,189,118, 66,143, 59,205,106, 77, 62, 81, 78, 48,200,220, 71,122, 90,188, 0,255, 62,105, 69,184,188, 67,220,161,
- 62, 66, 96,128, 21, 76, 78, 90, 98,241, 0,255,189,250, 5,163,188, 67,220,161, 62, 66, 96,128,234,180, 78, 90, 98,241, 0,255,
- 62,137, 41,174, 59, 43,249,149, 62, 55, 46, 59,245, 85, 69, 69,107, 25, 0,255,190, 38, 16,118, 59, 43,249,149, 62, 55, 46, 59,
- 10,171, 69, 69,107, 25, 0,255, 62,157,176,129, 61, 61,227,222, 62, 40, 64,139,223,232, 29,211,120, 67, 0,255,190, 79, 30, 28,
- 61, 61,227,222, 62, 40, 64,139, 32, 24, 29,211,120, 67, 0,255, 62,159,142, 55, 61,162, 31,137, 62, 40, 64,139,210,148,238,123,
-118, 95, 0,255,190, 82,217,136, 61,162, 31,137, 62, 40, 64,139, 45,108,238,123,118, 95, 0,255, 62,153,245, 21, 61,214, 95,114,
- 62, 43,251,247,229,216,179,108, 99, 43, 0,255,190, 71,167, 67, 61,214, 95,114, 62, 43,251,247, 26, 40,179,108, 99, 43, 0,255,
- 62,123,238,212, 62, 5, 79,173, 62, 77,146,196,237,202,158,179, 81, 35, 2,255,190, 15,171,238, 62, 5, 79,173, 62, 77,146,196,
- 18, 54,158,179, 81, 35, 2,255, 62, 60,124,166, 62, 9, 11, 25, 62, 85, 9,156, 39, 24,212,118,113,214, 2,255,189,160,115,129,
- 62, 9, 11, 25, 62, 85, 9,156,216,232,212,118,113,214, 2,255, 62, 86,156,155, 62, 12,198,133, 62, 77,146,196, 1,213,193,189,
-111,208, 0,255,189,212,179,106, 62, 12,198,133, 62, 77,146,196,254, 43,193,189,111,208, 0,255, 62, 23, 42,109, 60,230,126,216,
- 62, 77,146,196, 84,226, 42,192, 85,187, 0,255,189, 43,158, 31, 60,230,126,216, 62, 77,146,196,171, 30, 42,192, 85,187, 0,255,
- 62, 19,111, 1, 61, 91,191, 63, 62, 77,146,196,102,235, 2,196, 76, 11, 0,255,189, 28,176,110, 61, 91,191, 63, 62, 77,146,196,
-153, 21, 2,196, 76, 11, 0,255, 61,212,194,185, 62, 38,230,122, 62, 10,101, 42,182,183,104,118,246, 5, 0,255, 58,240,196,191,
- 62, 38,230,122, 62, 10,101, 42, 73, 73,104,118,246, 5, 0,255, 62, 19,111, 1, 62,131,247,186, 62, 14, 32,150,192,208, 66,221,
-167, 3, 2,255,189, 28,176,110, 62,131,247,186, 62, 14, 32,150, 63, 48, 66,221,167, 3, 2,255, 62, 86,156,155, 62,137,144,220,
- 62, 2,238, 82, 9, 59, 90, 89,165,208, 2,255,189,212,179,106, 62,137,144,220, 62, 2,238, 82,246,197, 90, 89,165,208, 2,255,
- 62,142,194,208, 62, 83,175,139, 61,224,138,107, 37,165,114,104,212,176, 0,255,190, 49, 66,187, 62, 83,175,139, 61,224,138,107,
-218, 91,114,104,212,176, 0,255, 62,189,105,152, 62, 35, 43, 14, 61,164,211,170, 45, 67,116, 40,227, 1, 0,255,190,135, 72, 37,
- 62, 35, 43, 14, 61,164,211,170,210,189,116, 40,227, 1, 0,255, 62,217,103, 66, 62, 12,198,133, 61,134,248, 73, 94,100, 79,237,
-223, 18, 0,255,190,163, 69,207, 62, 12,198,133, 61,134,248, 73,161,156, 79,237,223, 18, 0,255, 62,211,206, 32, 60,200,163,119,
- 60,211,115,252,120,247,221,255,231,165, 0,255,190,157,172,173, 60,200,163,119, 60,211,115,252,135, 9,221,255,231,165, 0,255,
- 62,170,192,123,189, 85, 45,188, 61, 52, 94,112, 76,155,154,106,242, 19, 0,255,190,105, 62, 16,189, 85, 45,188, 61, 52, 94,112,
-179,101,154,106,242, 19, 0,255, 62,131,144,140,189,196, 41, 0, 61,142,111, 33, 56,204,142, 26, 13,138, 0,255,190, 26,222, 50,
-189,196, 41, 0, 61,142,111, 33,199, 52,142, 26, 13,138, 0,255, 61, 88,133,203, 62,187,243, 16,188,105,242, 89, 0, 0,106,155,
- 70,214, 2,255, 61, 88,133,203, 62,208,121,226,190, 62, 7,254, 0, 0,127,243, 3, 82, 2,255, 61, 88,133,203,190, 18,152,254,
-190,236,214, 11, 0, 0,164, 54,166,204, 3,255, 61, 88,133,203,190,136,190,173,189,124,142,139, 0, 0,129,179,235, 65, 0,255,
- 61, 88,133,203,191, 1,243,205, 61,134,248, 73, 0, 0,151,182,181,204, 2,255, 61, 88,133,203,190,218,217,247, 60, 56, 12,241,
- 0, 0,221,231,132,162, 2,255, 61, 88,133,203,190,162,222,161, 57,157, 21,147, 0, 0,212, 16,135,201, 0,255, 61, 88,133,203,
-190,142, 87,207,188,146,212,141, 0, 0,147,245,187, 97, 0,255, 62,230,119, 61, 61,106,172,239,189,253, 43,161,125,164,235,181,
- 13,156, 0,255,190,176, 85,202, 61,106,172,239,189,253, 43,161,130, 92,235,181, 13,156, 0,255, 62,232, 84,243, 61,199,113,194,
-190, 47, 26, 78,126,174,238, 23,252, 66, 0,255,190,178, 51,128, 61,199,113,194,190, 47, 26, 78,129, 82,238, 23,252, 66, 0,255,
- 62,211,206, 32, 61,147, 49,216,190,180,218,181, 81, 70, 13,148,158, 15, 1,255,190,157,172,173, 61,147, 49,216,190,180,218,181,
-174,186, 13,148,158, 15, 1,255, 62,137, 41,174, 62, 27,180, 54,190,244, 76,226, 58,123, 21,228,144, 70, 3,255,190, 38, 16,118,
- 62, 27,180, 54,190,244, 76,226,197,133, 21,228,144, 70, 3,255, 62,202,121,146,189,151, 95,239,189,238, 61,240, 89, 76,164,139,
- 6,161, 2,255,190,148, 88, 31,189,151, 95,239,189,238, 61,240,166,180,164,139, 6,161, 2,255, 62,168,226,197,189,226, 4, 97,
-190,103, 21,163, 38, 93,134, 34, 7,182, 0,255,190,101,130,164,189,226, 4, 97,190,103, 21,163,217,163,134, 34, 7,182, 0,255,
- 62,180, 21, 9,189,100, 27,109,190,178,252,255, 43,106,170,219,170,222, 1,255,190,123,231, 45,189,100, 27,109,190,178,252,255,
-212,150,170,219,170,222, 1,255, 62, 86,156,155,188,217, 91,211,190,234,248, 85, 55,168,213,109,148,229, 2,255,189,212,179,106,
-188,217, 91,211,190,234,248, 85,200, 88,213,109,148,229, 2,255, 62, 38, 24, 30,190, 93, 61,112, 61, 37,112,191,120,197,255, 36,
-213,158, 0,255,189,103, 84,224,190, 93, 61,112, 61, 37,112,191,135, 59,255, 36,213,158, 0,255, 62, 11,248, 41,190,123, 24,209,
-188,236,102,176, 84,188,181, 20,196, 24, 0,255,188,253,170, 27,190,123, 24,209,188,236,102,176,171, 68,181, 20,196, 24, 0,255,
- 62, 64, 56, 19,190,196,117,110, 60,241, 79, 92, 79,131,254, 86,155,183, 2,255,189,167,234, 89,190,196,117,110, 60,241, 79, 92,
-176,125,254, 86,155,183, 2,255, 62, 45,142,246,190,146, 19, 59, 61, 7,149, 95, 99, 5, 1, 8,174,231, 0,255,189,130,152, 32,
-190,146, 19, 59, 61, 7,149, 95,156,251, 1, 8,174,231, 0,255, 62, 82,225, 47,190,244,249,234, 61, 22,131, 15, 62, 65,185,227,
-168,224, 2,255,189,205, 60,146,190,244,249,234, 61, 22,131, 15,193,191,185,227,168,224, 2,255, 61,242,158, 25,190,207,167,178,
- 60,181,152,155, 16,133,232,208,131, 55, 0,255,188, 80,194,110,190,207,167,178, 60,181,152,155,239,123,232,208,131, 55, 0,255,
- 61,227,176,105,190,155,103,201, 60,151,189, 58, 48, 7,224,163,141,149, 0,255,187,178,169,214,190,155,103,201, 60,151,189, 58,
-207,249,224,163,141,149, 0,255, 62, 4,129, 81,190,252,112,195, 61, 97, 39,129, 12, 68,158,218,173,147, 0,255,188,193,243, 89,
-190,252,112,195, 61, 97, 39,129,243,188,158,218,173,147, 0,255, 62, 30,161, 70,190, 59,166,163, 61, 82, 57,208,124,195,227,106,
-255,203, 0,255,189, 73,121,127,190, 59,166,163, 61, 82, 57,208,131, 61,227,106,255,203, 0,255, 62, 26,229,218,190, 33,134,174,
- 61,142,111, 33,120, 29,231,105, 36,193, 0,255,189, 58,139,207,190, 33,134,174, 61,142,111, 33,135,227,231,105, 36,193, 0,255,
- 62, 23, 42,109,190, 7,102,186, 61,172, 74,130,101,160,182,164, 25,240, 0,255,189, 43,158, 31,190, 7,102,186, 61,172, 74,130,
-154, 96,182,164, 25,240, 0,255, 62, 26,229,218,190,111,230,140,189,148,171,206, 84,120,159,221,253,198, 0,255,189, 58,139,207,
-190,111,230,140,189,148,171,206,171,136,159,221,253,198, 0,255, 62, 67,243,127,190, 74,148, 83,190,139,205, 16, 67,255,151, 42,
-228, 73, 2,255,189,175, 97, 49,190, 74,148, 83,190,139,205, 16,188, 1,151, 42,228, 73, 2,255, 62, 90, 88, 7,189,248,104,235,
-190,205, 28,244, 63,201,176, 25,179, 0, 3,255,189,220, 42, 66,189,248,104,235,190,205, 28,244,192, 55,176, 25,179, 0, 3,255,
- 62,135, 75,248, 62,180,124, 55,190,167,202,187, 56, 34, 95,160,192, 17, 2,255,190, 34, 85, 10, 62,180,124, 55,190,167,202,187,
-199,222, 95,160,192, 17, 2,255, 62,135, 75,248, 62,195,105,232,190, 58, 76,146, 55, 54,115,120, 0,239, 2,255,190, 34, 85, 10,
- 62,195,105,232,190, 58, 76,146,200,202,115,120, 0,239, 2,255, 62,135, 75,248, 62,176,192,203,189, 34,252,105, 63,239, 92,164,
- 60,238, 2,255,190, 34, 85, 10, 62,176,192,203,189, 34,252,105,192, 17, 92,164, 60,238, 2,255, 62,137, 41,174, 62, 68,193,219,
- 61, 82, 57,208, 49,123,102,255, 57,170, 0,255,190, 38, 16,118, 62, 68,193,219, 61, 82, 57,208,206,133,102,255, 57,170, 0,255,
- 62,200,155,220, 62, 12,198,133, 59,248,172, 95, 98,142, 73,198, 35, 6, 0,255,190,146,122,105, 62, 12,198,133, 59,248,172, 95,
-157,114, 73,198, 35, 6, 0,255, 62,178, 55, 83, 62, 35, 43, 14,188,146,212,141, 61,129,106,254, 33,241, 0,255,190,120, 43,193,
- 62, 35, 43, 14,188,146,212,141,194,127,106,254, 33,241, 0,255, 62,180, 21, 9, 62,141, 76, 72,189,253, 43,161, 76,234, 87,151,
- 52,221, 0,255,190,123,231, 45, 62,141, 76, 72,189,253, 43,161,179, 22, 87,151, 52,221, 0,255, 62,217,103, 66, 62, 87,106,247,
-189,185,254, 7,101,187, 66, 28, 40,199, 2,255,190,163, 69,207, 62, 87,106,247,189,185,254, 7,154, 69, 66, 28, 40,199, 2,255,
- 62,217,103, 66, 62,113,138,236,190, 80,177, 26,113,183, 58, 68,248,119, 2,255,190,163, 69,207, 62,113,138,236,190, 80,177, 26,
-142, 73, 58, 68,248,119, 2,255, 62,180, 21, 9, 62,152,126,141,190,118, 3, 83, 86,235, 93,238,253,205, 0,255,190,123,231, 45,
- 62,152,126,141,190,118, 3, 83,169, 21, 93,238,253,205, 0,255, 62,180, 21, 9, 62,135,179, 38,190,182,184,107, 85,232, 70,154,
-192,157, 2,255,190,123,231, 45, 62,135,179, 38,190,182,184,107,170, 24, 70,154,192,157, 2,255, 62,217,103, 66, 62, 76, 56,179,
-190,162, 49,153,110,166, 42,177,207,222, 2,255,190,163, 69,207, 62, 76, 56,179,190,162, 49,153,145, 90, 42,177,207,222, 2,255,
- 62,174,123,231, 61,206,232,154,190,216, 79, 56, 75, 58, 1, 57,152,116, 3,255,190,112,180,232, 61,206,232,154,190,216, 79, 56,
-180,198, 1, 57,152,116, 3,255, 62,142,194,208,189, 40,100,171,190,206,250,170, 70, 73,187,147,173,200, 1,255,190, 49, 66,187,
-189, 40,100,171,190,206,250,170,185,183,187,147,173,200, 0,255, 62,223, 0,100, 61,206,232,154,190,121,190,191,114,194, 41, 80,
- 38,207, 0,255,190,168,222,241, 61,206,232,154,190,121,190,191,141, 62, 41, 80, 38,207, 0,255, 62,120, 51,104,190, 7,102,186,
-189,163,153,127, 74,232,154,153, 22, 28, 0,255,190, 11,240,130,190, 7,102,186,189,163,153,127,181, 24,154,153, 22, 28, 0,255,
- 62,129,178,214,190, 18,152,254,190,125,122, 44, 71, 89,151,115,237, 1, 0,255,190, 23, 34,198,190, 18,152,254,190,125,122, 44,
-184,167,151,115,237, 1, 0,255, 62,239,203,202, 62, 12,198,133,190,132, 86, 56,220, 72, 93,207, 79,106, 2,255,190,185,170, 88,
- 62, 12,198,133,190,132, 86, 56, 35,184, 93,207, 79,106, 2,255, 62,211,206, 32,189,240,242, 18,190, 84,108,135, 15, 30,150, 34,
- 70, 84, 2,255,190,157,172,173,189,240,242, 18,190, 84,108,135,240,226,150, 34, 70, 84, 2,255, 63, 9,160, 38,189,203,159,217,
-190,154,186,192, 67,164,166,138, 61,172, 0,255,190,221, 30,219,189,203,159,217,190,154,186,192,188, 92,166,138, 61,172, 0,255,
- 63, 38,140,172,188,217, 91,211,190,178,252,255, 83,179,206,223, 83,114, 0,255,191, 11,123,244,188,217, 91,211,190,178,252,255,
-172, 77,206,223, 83,114, 0,255, 63, 46,242, 95, 61,199,113,194,190,177, 31, 73, 92, 54, 12,232, 87,210, 2,255,191, 19,225,167,
- 61,199,113,194,190,177, 31, 73,163,202, 12,232, 87,210, 2,255, 63, 32,243,138, 62, 61, 75, 3,190,177, 31, 73, 62,247, 83,221,
- 73, 97, 0,255,191, 5,226,209, 62, 61, 75, 3,190,177, 31, 73,193, 9, 83,221, 73, 97, 0,255, 63, 7,194,112, 62, 46, 93, 82,
-190,150,255, 84, 5,181,111, 80, 62,236, 0,255,190,217, 99,111, 62, 46, 93, 82,190,150,255, 84,250, 75,111, 80, 62,236, 0,255,
- 63, 6,211,149, 62, 16,129,241,190,145,102, 50, 69,236,239,117,105,236, 0,255,190,215,133,185, 62, 16,129,241,190,145,102, 50,
-186, 20,239,117,105,236, 0,255, 63, 27, 90,104, 62, 27,180, 54,190,169,168,113, 24, 34,231,205,123, 89, 0,255,191, 0, 73,175,
- 62, 27,180, 54,190,169,168,113,231,222,231,205,123, 89, 0,255, 63, 36,174,246, 61,169,150, 97,190,173, 99,221,223, 69,252, 16,
-123,173, 0,255,191, 9,158, 62, 61,169,150, 97,190,173, 99,221, 32,187,252, 16,123,173, 0,255, 63, 30, 38,249,188,127,147, 98,
-190,173, 99,221,239,171, 39, 0,120,207, 0,255,191, 3, 22, 64,188,127,147, 98,190,173, 99,221, 16, 85, 39, 0,120,207, 0,255,
- 63, 8,177, 75,189,143,233, 23,190,149, 33,158, 51, 9, 45, 56,108, 82, 0,255,190,219, 65, 37,189,143,233, 23,190,149, 33,158,
-204,247, 45, 56,108, 82, 0,255, 62,224,222, 26,189,173,196,120,190, 88, 39,243, 38,147, 62,224,104,153, 2,255,190,170,188,167,
-189,173,196,120,190, 88, 39,243,217,109, 62,224,104,153, 2,255, 62,247, 66,162, 61,236,195,250,190,128,154,204, 62,218,243,152,
-110,206, 2,255,190,193, 33, 48, 61,236,195,250,190,128,154,204,193, 38,243,152,110,206, 2,255, 62,252,219,196, 61,184,132, 17,
-190,145,102, 50, 87, 10,182, 73, 58, 19, 0,255,190,198,186, 82, 61,184,132, 17,190,145,102, 50,168,246,182, 73, 58, 19, 0,255,
- 62,237,238, 21,189,128,251,103,190,125,122, 44, 15,232,121,106, 37, 64, 0,255,190,183,204,162,189,128,251,103,190,125,122, 44,
-240, 24,121,106, 37, 64, 0,255, 63, 9,160, 38,189, 85, 45,188,190,164, 15, 79,239,157,122, 89, 33,212, 0,255,190,221, 30,219,
-189, 85, 45,188,190,164, 15, 79, 16, 99,122, 89, 33,212, 0,255, 63, 27, 90,104,188, 8, 37,223,190,182,184,107,158, 8, 81,202,
- 9,185, 0,255,191, 0, 73,175,188, 8, 37,223,190,182,184,107, 97,248, 81,202, 9,185, 0,255, 63, 32,243,138, 61,132, 68, 40,
-190,182,184,107,131, 60,239,145, 23, 95, 0,255,191, 5,226,209, 61,132, 68, 40,190,182,184,107,124,196,239,145, 23, 95, 0,255,
- 63, 25,124,178, 61,236,195,250,190,180,218,181,228, 27,153, 22, 70,206, 0,255,190,252,215,242, 61,236,195,250,190,180,218,181,
- 27,229,153, 22, 70,206, 0,255, 63, 7,194,112, 61,221,214, 74,190,162, 49,153, 68, 65,168,253, 64,113, 0,255,190,217, 99,111,
- 61,221,214, 74,190,162, 49,153,187,191,168,253, 64,113, 0,255, 62,228,153,135, 61,169,150, 97,190,125,122, 44, 86,113,222,190,
- 88, 87, 0,255,190,174,120, 20, 61,169,150, 97,190,125,122, 44,169,143,222,190, 88, 87, 0,255, 62,226,187,209, 60,230,126,216,
-190,141,170,198, 95,196,182,107, 42,100, 0,255,190,172,154, 93, 60,230,126,216,190,141,170,198,160, 60,182,107, 42,100, 0,255,
- 62,208, 18,180,188, 8, 37,223,190,141,170,198,111, 42, 14, 21, 61,220, 0,255,190,153,241, 65,188, 8, 37,223,190,141,170,198,
-144,214, 14, 21, 61,220, 0,255, 62,223, 0,100,188, 67,220,161,190,141,170,198, 79, 3, 91, 4, 43, 19, 2,255,190,168,222,241,
-188, 67,220,161,190,141,170,198,176,253, 91, 4, 43, 19, 2,255, 62,228,153,135,189, 55, 82, 92,190,141,170,198,107,207,254,198,
- 68,250, 2,255,190,174,120, 20,189, 55, 82, 92,190,141,170,198,148, 49,254,198, 68,250, 2,255, 62,221, 34,174,189,115, 9, 29,
-190,141,170,198, 82, 7, 64,225, 73,200, 0,255,190,167, 1, 59,189,115, 9, 29,190,141,170,198,173,249, 64,225, 73,200, 0,255,
- 62,200,155,220,189, 85, 45,188,190, 58, 76,146,117, 38,207, 66,239, 47, 0,255,190,146,122,105,189, 85, 45,188,190, 58, 76,146,
-138,218,207, 66,239, 47, 0,255, 62,198,190, 38,189,128,251,103,190,106,209, 15, 97,150, 18,139, 80,184, 0,255,190,144,156,179,
-189,128,251,103,190,106,209, 15,158,106, 18,139, 80,184, 0,255, 62,198,190, 38,189, 10,137, 74,190,114, 71,231,116, 17,240, 66,
- 51,154, 0,255,190,144,156,179,189, 10,137, 74,190,114, 71,231,139,239,240, 66, 51,154, 0,255, 62,217,103, 66, 61, 46,246, 45,
-190,125,122, 44,113,112,204,245, 30, 39, 0,255,190,163, 69,207, 61, 46,246, 45,190,125,122, 44,142,144,204,245, 30, 39, 0,255,
- 62,239,203,202, 61,121,154,159,190,139,205, 16, 90,105,185, 61, 56,146, 0,255,190,185,170, 88, 61,121,154,159,190,139,205, 16,
-165,151,185, 61, 56,146, 0,255, 62,239,203,202, 61,106,172,239,190,152,221, 10, 82,191,204,102, 82,230, 0,255,190,185,170, 88,
- 61,106,172,239,190,152,221, 10,173, 65,204,102, 82,230, 0,255, 62,221, 34,174,189,115, 9, 29,190,152,221, 10, 29,246, 98, 64,
- 76, 94, 0,255,190,167, 1, 59,189,115, 9, 29,190,152,221, 10,226, 10, 98, 64, 76, 94, 0,255, 62,230,119, 61,189, 55, 82, 92,
-190,152,221, 10, 77,150, 17,111,100, 75, 0,255,190,176, 85,202,189, 55, 82, 92,190,152,221, 10,178,106, 17,111,100, 75, 0,255,
- 62,224,222, 26,188,127,147, 98,190,152,221, 10, 60,239, 60,190, 94,195, 0,255,190,170,188,167,188,127,147, 98,190,152,221, 10,
-195, 17, 60,190, 94,195, 0,255, 62,209,240,106,188, 8, 37,223,190,152,221, 10, 83,199, 23,178, 93,209, 0,255,190,155,206,247,
-188, 8, 37,223,190,152,221, 10,172, 57, 23,178, 93,209, 0,255, 62,228,153,135, 60,230,126,216,190,152,221, 10, 73, 98,200, 1,
- 88,170, 0,255,190,174,120, 20, 60,230,126,216,190,152,221, 10,182,158,200, 1, 88,170, 0,255, 63, 9,160, 38, 61,206,232,154,
-190,175, 65,147, 68, 23,223,166,103,112, 0,255,190,221, 30,219, 61,206,232,154,190,175, 65,147,187,233,223,166,103,112, 0,255,
- 63, 27, 90,104, 61,221,214, 74,190,192, 12,249, 18,165,216,156,120, 89, 0,255,191, 0, 73,175, 61,221,214, 74,190,192, 12,249,
-237, 91,216,156,120, 89, 0,255, 63, 35,192, 27, 61,121,154,159,190,193,234,175,185, 25,231, 29,103,157, 0,255,191, 8,175, 98,
- 61,121,154,159,190,193,234,175, 70,231,231, 29,103,157, 0,255, 63, 30, 38,249,188, 67,220,161,190,192, 12,249,209, 43, 64, 0,
-100,119, 0,255,191, 3, 22, 64,188, 67,220,161,190,192, 12,249, 46,213, 64, 0,100,119, 0,255, 63, 10,143, 1,189, 85, 45,188,
-190,177, 31, 73, 26, 52, 92,240, 84, 3, 0,255,190,222,252,145,189, 85, 45,188,190,177, 31, 73,229,204, 92,240, 84, 3, 0,255,
- 62,237,238, 21,189,115, 9, 29,190,139,205, 16, 8, 58,111,116, 62,101, 0,255,190,183,204,162,189,115, 9, 29,190,139,205, 16,
-247,198,111,116, 62,101, 0,255, 62,254,185,122, 61,169,150, 97,190,158,118, 45, 80,198,213,102, 89,175, 0,255,190,200,152, 8,
- 61,169,150, 97,190,158,118, 45,175, 58,213,102, 89,175, 0,255, 62,239,203,202,186,133,194,226,190,154,186,192, 25,136, 0,130,
-125,108, 0,255,190,185,170, 88,186,133,194,226,190,154,186,192,230,120, 0,130,125,108, 0,255, 62,250,254, 14,188,187,128,115,
-190,156,152,119, 27, 2, 30, 58,121,104, 0,255,190,196,220,156,188,187,128,115,190,156,152,119,228,254, 30, 58,121,104, 0,255,
- 63, 4,245,223, 59,205,106, 77,190,164, 15, 79, 55,218,253,126,115, 35, 0,255,190,211,202, 76, 59,205,106, 77,190,164, 15, 79,
-200, 38,253,126,115, 35, 0,255, 63, 0, 75,152, 60,230,126,216,190,160, 83,227, 41,164,255,199,121, 8, 0,255,190,202,117,190,
- 60,230,126,216,190,160, 83,227,214, 92,255,199,121, 8, 0,255, 63, 6,211,149, 61,106,172,239,190,165,237, 5, 39,237, 9,191,
-121, 55, 0,255,190,215,133,185, 61,106,172,239,190,165,237, 5,216, 19, 9,191,121, 55, 0,255, 63, 11,125,220, 61, 17, 26,205,
-190,167,202,187, 46,208,244, 41,118,137, 0,255,190,224,218, 71, 61, 17, 26,205,190,167,202,187,209, 48,244, 41,118,137, 0,255,
- 63, 18, 5,218, 61, 61,227,222,190,169,168,113, 53, 70, 3, 84,116, 85, 2,255,190,237,234, 65, 61, 61,227,222,190,169,168,113,
-202,186, 3, 84,116, 85, 2,255, 63, 15, 57, 73, 61,154,168,176,190,169,168,113, 44, 99, 38, 36,113,212, 2,255,190,232, 81, 31,
- 61,154,168,176,190,169,168,113,211,157, 38, 36,113,212, 2,255, 63, 7,194,112, 62, 27,180, 54,190,192, 12,249,198,249, 72, 3,
-166,222, 3,255,190,217, 99,111, 62, 27,180, 54,190,192, 12,249, 57, 7, 72, 3,166,222, 3,255, 63, 34,209, 64, 62, 42,161,230,
-190,206,250,170, 37,198, 68,123,154,174, 3,255,191, 7,192,135, 62, 42,161,230,190,206,250,170,218, 58, 68,123,154,174, 3,255,
- 63, 48,208, 21, 61,177, 13, 57,190,195,200,102,121, 3, 17,201,218, 73, 3,255,191, 21,191, 93, 61,177, 13, 57,190,195,200,102,
-134,253, 17,201,218, 73, 3,255, 63, 42, 72, 24,188,217, 91,211,190,203, 63, 62, 82, 59,200, 75,175, 70, 3,255,191, 15, 55, 96,
-188,217, 91,211,190,203, 63, 62,173,197,200, 75,175, 70, 3,255, 63, 9,160, 38,189,188,178, 40,190,193,234,175,249,134,165,184,
-165,129, 3,255,190,221, 30,219,189,188,178, 40,190,193,234,175, 6,122,165,184,165,129, 3,255, 62,215,137,140,189,226, 4, 97,
-190,154,186,192,249,126,163,122,167,205, 1,255,190,161,104, 25,189,226, 4, 97,190,154,186,192, 6,130,163,122,167,205, 1,255,
- 62,232, 84,243, 62, 1,148, 65,190,167,202,187,193, 93, 65,224,165,229, 1,255,190,178, 51,128, 62, 1,148, 65,190,167,202,187,
- 62,163, 65,224,165,229, 1,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,206, 16, 0, 0, 0,242, 0, 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, 5, 31,136, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 47, 28, 5, 31,136, 32, 0, 0, 0, 53, 0, 0, 3,237, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 34,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 43, 0, 0, 0, 45,
- 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 34, 0, 0, 0, 44,
- 0, 0, 0, 46, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 34,
- 0, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 34, 0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 5,
- 0, 0, 0, 34, 0, 0, 0, 42, 0, 0, 0, 44, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 42, 0, 0, 0, 34, 0, 0, 0, 2,
- 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 34,
- 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 7,
- 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 34, 0, 0, 0, 9,
- 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 12, 0, 0, 0, 34,
- 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 13,
- 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 7,
- 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 19, 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 19, 0, 0, 0, 34,
- 0, 0, 0, 15, 0, 0, 0, 17, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 16, 0, 0, 0, 18,
- 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 21, 0, 0, 0, 34, 0, 0, 0, 19, 0, 0, 0, 21, 0, 0, 0, 34, 0, 0, 0, 20,
- 0, 0, 0, 22, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 22, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 23, 0, 0, 0, 34,
- 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 19, 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 26,
- 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 34, 0, 0, 0, 25,
- 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 34,
- 0, 0, 0, 18, 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 25, 0, 0, 0, 31, 0, 0, 0, 34, 0, 0, 0, 29, 0, 0, 0, 31,
- 0, 0, 0, 34, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 26,
- 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 34, 0, 0, 0, 23, 0, 0, 0, 33, 0, 0, 0, 34,
- 0, 0, 0, 31, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 34,
- 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 34, 0, 0, 0, 31,
- 0, 0, 0, 37, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 38, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 34,
- 0, 0, 0, 32, 0, 0, 0, 38, 0, 0, 0, 34, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 34, 0, 0, 0, 29, 0, 0, 0, 39,
- 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 40, 0, 0, 0, 34, 0, 0, 0, 37,
- 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 39, 0, 0, 0, 41, 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0, 44, 0, 0, 0, 34,
- 0, 0, 0, 40, 0, 0, 0, 42, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 46,
- 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 45,
- 0, 0, 0, 47, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 48, 0, 0, 0, 34,
- 0, 0, 0, 48, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 34, 0, 0, 0, 49, 0, 0, 0, 51,
- 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0, 52, 0, 0, 0, 34, 0, 0, 0, 23,
- 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 0, 34,
- 0, 0, 0, 52, 0, 0, 0, 54, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 55, 0, 0, 0, 34, 0, 0, 0, 53, 0, 0, 0, 55,
- 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 54, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 12,
- 0, 0, 0, 57, 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 57, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 58, 0, 0, 0, 34,
- 0, 0, 0, 56, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 61, 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 61,
- 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 0,
- 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 34,
- 0, 0, 0, 62, 0, 0, 0, 64, 0, 0, 0, 34, 0, 0, 0, 47, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 64,
- 0, 0, 0, 34, 0, 0, 0, 59, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 47, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 60,
- 0, 0, 0, 64, 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 59, 0, 0, 0, 61, 0, 0, 0, 34,
- 0, 0, 0, 60, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 60,
- 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 53,
- 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 51, 0, 0, 0, 59, 0, 0, 0, 34,
- 0, 0, 0, 52, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 49, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0, 60,
- 0, 0, 0, 34, 0, 0, 0, 87, 0, 0, 0,171, 0, 0, 0, 34, 0, 0, 0,171, 0, 0, 0,173, 0, 0, 0, 34, 0, 0, 0, 89,
- 0, 0, 0,173, 0, 0, 0, 34, 0, 0, 0, 87, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0, 34,
- 0, 0, 0, 88, 0, 0, 0,172, 0, 0, 0, 34, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 0,169,
- 0, 0, 0, 34, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0,170,
- 0, 0, 0,172, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0,170, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0, 88, 0, 0, 0, 34,
- 0, 0, 0, 83, 0, 0, 0,167, 0, 0, 0, 34, 0, 0, 0,167, 0, 0, 0,169, 0, 0, 0, 34, 0, 0, 0, 83, 0, 0, 0, 85,
- 0, 0, 0, 34, 0, 0, 0,168, 0, 0, 0,170, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0,168, 0, 0, 0, 34, 0, 0, 0, 84,
- 0, 0, 0, 86, 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 0,165, 0, 0, 0, 34, 0, 0, 0,165, 0, 0, 0,167, 0, 0, 0, 34,
- 0, 0, 0, 81, 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0,166, 0, 0, 0,168, 0, 0, 0, 34, 0, 0, 0, 82, 0, 0, 0,166,
- 0, 0, 0, 34, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0,163, 0, 0, 0, 34, 0, 0, 0,163,
- 0, 0, 0,165, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0, 81, 0, 0, 0, 34, 0, 0, 0,164, 0, 0, 0,166, 0, 0, 0, 34,
- 0, 0, 0, 80, 0, 0, 0,164, 0, 0, 0, 34, 0, 0, 0, 80, 0, 0, 0, 82, 0, 0, 0, 34, 0, 0, 0, 77, 0, 0, 0, 90,
- 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0,143, 0, 0, 0, 34, 0, 0, 0,143, 0, 0, 0,161, 0, 0, 0, 34, 0, 0, 0, 77,
- 0, 0, 0,161, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 0,144, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 0, 91, 0, 0, 0, 34,
- 0, 0, 0, 78, 0, 0, 0,162, 0, 0, 0, 34, 0, 0, 0,144, 0, 0, 0,162, 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0, 92,
- 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0,145, 0, 0, 0, 34, 0, 0, 0,143, 0, 0, 0,145, 0, 0, 0, 34, 0, 0, 0, 93,
- 0, 0, 0,146, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 0, 93, 0, 0, 0, 34, 0, 0, 0,144, 0, 0, 0,146, 0, 0, 0, 34,
- 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 0,147, 0, 0, 0, 34, 0, 0, 0,145, 0, 0, 0,147,
- 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 0,148, 0, 0, 0, 34, 0, 0, 0, 93, 0, 0, 0, 95, 0, 0, 0, 34, 0, 0, 0,146,
- 0, 0, 0,148, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 96, 0, 0, 0,149, 0, 0, 0, 34,
- 0, 0, 0,147, 0, 0, 0,149, 0, 0, 0, 34, 0, 0, 0, 97, 0, 0, 0,150, 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 0, 97,
- 0, 0, 0, 34, 0, 0, 0,148, 0, 0, 0,150, 0, 0, 0, 34, 0, 0, 0, 96, 0, 0, 0, 98, 0, 0, 0, 34, 0, 0, 0, 98,
- 0, 0, 0,151, 0, 0, 0, 34, 0, 0, 0,149, 0, 0, 0,151, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,152, 0, 0, 0, 34,
- 0, 0, 0, 97, 0, 0, 0, 99, 0, 0, 0, 34, 0, 0, 0,150, 0, 0, 0,152, 0, 0, 0, 34, 0, 0, 0, 98, 0, 0, 0,100,
- 0, 0, 0, 34, 0, 0, 0,100, 0, 0, 0,153, 0, 0, 0, 34, 0, 0, 0,151, 0, 0, 0,153, 0, 0, 0, 34, 0, 0, 0,101,
- 0, 0, 0,154, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,101, 0, 0, 0, 34, 0, 0, 0,152, 0, 0, 0,154, 0, 0, 0, 34,
- 0, 0, 0,100, 0, 0, 0,102, 0, 0, 0, 34, 0, 0, 0,102, 0, 0, 0,155, 0, 0, 0, 34, 0, 0, 0,153, 0, 0, 0,155,
- 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 0,156, 0, 0, 0, 34, 0, 0, 0,101, 0, 0, 0,103, 0, 0, 0, 34, 0, 0, 0,154,
- 0, 0, 0,156, 0, 0, 0, 34, 0, 0, 0,102, 0, 0, 0,104, 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,157, 0, 0, 0, 34,
- 0, 0, 0,155, 0, 0, 0,157, 0, 0, 0, 34, 0, 0, 0,105, 0, 0, 0,158, 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 0,105,
- 0, 0, 0, 34, 0, 0, 0,156, 0, 0, 0,158, 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,106, 0, 0, 0, 34, 0, 0, 0,106,
- 0, 0, 0,159, 0, 0, 0, 34, 0, 0, 0,157, 0, 0, 0,159, 0, 0, 0, 34, 0, 0, 0,107, 0, 0, 0,160, 0, 0, 0, 34,
- 0, 0, 0,105, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0,158, 0, 0, 0,160, 0, 0, 0, 34, 0, 0, 0, 65, 0, 0, 0,106,
- 0, 0, 0, 34, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0,159, 0, 0, 0, 34, 0, 0, 0, 65,
- 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0,160, 0, 0, 0, 34, 0, 0, 0,108, 0, 0, 0,125, 0, 0, 0, 34,
- 0, 0, 0,125, 0, 0, 0,157, 0, 0, 0, 34, 0, 0, 0,108, 0, 0, 0,159, 0, 0, 0, 34, 0, 0, 0,126, 0, 0, 0,158,
- 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,126, 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,160, 0, 0, 0, 34, 0, 0, 0,125,
- 0, 0, 0,176, 0, 0, 0, 34, 0, 0, 0,155, 0, 0, 0,176, 0, 0, 0, 34, 0, 0, 0,156, 0, 0, 0,177, 0, 0, 0, 34,
- 0, 0, 0,126, 0, 0, 0,177, 0, 0, 0, 34, 0, 0, 0,123, 0, 0, 0,153, 0, 0, 0, 34, 0, 0, 0,123, 0, 0, 0,176,
- 0, 0, 0, 34, 0, 0, 0,124, 0, 0, 0,154, 0, 0, 0, 34, 0, 0, 0,124, 0, 0, 0,177, 0, 0, 0, 34, 0, 0, 0,121,
- 0, 0, 0,151, 0, 0, 0, 34, 0, 0, 0,121, 0, 0, 0,123, 0, 0, 0, 34, 0, 0, 0,122, 0, 0, 0,152, 0, 0, 0, 34,
- 0, 0, 0,122, 0, 0, 0,124, 0, 0, 0, 34, 0, 0, 0,119, 0, 0, 0,149, 0, 0, 0, 34, 0, 0, 0,119, 0, 0, 0,121,
- 0, 0, 0, 34, 0, 0, 0,120, 0, 0, 0,150, 0, 0, 0, 34, 0, 0, 0,120, 0, 0, 0,122, 0, 0, 0, 34, 0, 0, 0,117,
- 0, 0, 0,147, 0, 0, 0, 34, 0, 0, 0,117, 0, 0, 0,119, 0, 0, 0, 34, 0, 0, 0,118, 0, 0, 0,148, 0, 0, 0, 34,
- 0, 0, 0,118, 0, 0, 0,120, 0, 0, 0, 34, 0, 0, 0,115, 0, 0, 0,145, 0, 0, 0, 34, 0, 0, 0,115, 0, 0, 0,117,
- 0, 0, 0, 34, 0, 0, 0,116, 0, 0, 0,146, 0, 0, 0, 34, 0, 0, 0,116, 0, 0, 0,118, 0, 0, 0, 34, 0, 0, 0,113,
- 0, 0, 0,143, 0, 0, 0, 34, 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0, 34, 0, 0, 0,114, 0, 0, 0,144, 0, 0, 0, 34,
- 0, 0, 0,114, 0, 0, 0,116, 0, 0, 0, 34, 0, 0, 0,112, 0, 0, 0,162, 0, 0, 0, 34, 0, 0, 0,112, 0, 0, 0,114,
- 0, 0, 0, 34, 0, 0, 0,174, 0, 0, 0,178, 0, 0, 0, 34, 0, 0, 0,161, 0, 0, 0,174, 0, 0, 0, 34, 0, 0, 0,174,
- 0, 0, 0,179, 0, 0, 0, 34, 0, 0, 0,112, 0, 0, 0,179, 0, 0, 0, 34, 0, 0, 0,162, 0, 0, 0,174, 0, 0, 0, 34,
- 0, 0, 0, 66, 0, 0, 0,110, 0, 0, 0, 34, 0, 0, 0,108, 0, 0, 0,110, 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,111,
- 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0,175, 0, 0, 0, 34, 0, 0, 0,175,
- 0, 0, 0,180, 0, 0, 0, 34, 0, 0, 0,110, 0, 0, 0,180, 0, 0, 0, 34, 0, 0, 0,111, 0, 0, 0,181, 0, 0, 0, 34,
- 0, 0, 0,175, 0, 0, 0,181, 0, 0, 0, 34, 0, 0, 0,178, 0, 0, 0,180, 0, 0, 0, 34, 0, 0, 0,174, 0, 0, 0,175,
- 0, 0, 0, 32, 0, 0, 0,179, 0, 0, 0,181, 0, 0, 0, 34, 0, 0, 0,132, 0, 0, 0,134, 0, 0, 0, 34, 0, 0, 0,134,
- 0, 0, 0,173, 0, 0, 0, 34, 0, 0, 0,132, 0, 0, 0,171, 0, 0, 0, 34, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0, 34,
- 0, 0, 0,133, 0, 0, 0,172, 0, 0, 0, 34, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0, 34, 0, 0, 0,130, 0, 0, 0,169,
- 0, 0, 0, 34, 0, 0, 0,131, 0, 0, 0,133, 0, 0, 0, 34, 0, 0, 0,131, 0, 0, 0,170, 0, 0, 0, 34, 0, 0, 0,128,
- 0, 0, 0,130, 0, 0, 0, 34, 0, 0, 0,128, 0, 0, 0,167, 0, 0, 0, 34, 0, 0, 0,129, 0, 0, 0,131, 0, 0, 0, 34,
- 0, 0, 0,129, 0, 0, 0,168, 0, 0, 0, 34, 0, 0, 0,163, 0, 0, 0,184, 0, 0, 0, 34, 0, 0, 0,182, 0, 0, 0,184,
- 0, 0, 0, 34, 0, 0, 0,165, 0, 0, 0,182, 0, 0, 0, 34, 0, 0, 0,183, 0, 0, 0,185, 0, 0, 0, 34, 0, 0, 0,164,
- 0, 0, 0,185, 0, 0, 0, 34, 0, 0, 0,166, 0, 0, 0,183, 0, 0, 0, 34, 0, 0, 0,128, 0, 0, 0,182, 0, 0, 0, 34,
- 0, 0, 0,129, 0, 0, 0,183, 0, 0, 0, 34, 0, 0, 0,141, 0, 0, 0,187, 0, 0, 0, 34, 0, 0, 0,186, 0, 0, 0,187,
- 0, 0, 0, 32, 0, 0, 0,184, 0, 0, 0,186, 0, 0, 0, 34, 0, 0, 0,141, 0, 0, 0,184, 0, 0, 0, 34, 0, 0, 0,142,
- 0, 0, 0,187, 0, 0, 0, 34, 0, 0, 0,142, 0, 0, 0,185, 0, 0, 0, 34, 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0, 34,
- 0, 0, 0, 67, 0, 0, 0,186, 0, 0, 0, 32, 0, 0, 0, 67, 0, 0, 0,182, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0,183,
- 0, 0, 0, 34, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0,127, 0, 0, 0, 32, 0, 0, 0,127,
- 0, 0, 0,129, 0, 0, 0, 34, 0, 0, 0,139, 0, 0, 0,190, 0, 0, 0, 34, 0, 0, 0,188, 0, 0, 0,190, 0, 0, 0, 34,
- 0, 0, 0,141, 0, 0, 0,188, 0, 0, 0, 34, 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0, 34, 0, 0, 0,189, 0, 0, 0,191,
- 0, 0, 0, 34, 0, 0, 0,140, 0, 0, 0,191, 0, 0, 0, 34, 0, 0, 0,140, 0, 0, 0,142, 0, 0, 0, 34, 0, 0, 0,142,
- 0, 0, 0,189, 0, 0, 0, 34, 0, 0, 0,137, 0, 0, 0,192, 0, 0, 0, 34, 0, 0, 0,190, 0, 0, 0,192, 0, 0, 0, 34,
- 0, 0, 0,137, 0, 0, 0,139, 0, 0, 0, 34, 0, 0, 0,191, 0, 0, 0,193, 0, 0, 0, 34, 0, 0, 0,138, 0, 0, 0,193,
- 0, 0, 0, 34, 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0, 34, 0, 0, 0,136, 0, 0, 0,194, 0, 0, 0, 34, 0, 0, 0,192,
- 0, 0, 0,194, 0, 0, 0, 34, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0, 34, 0, 0, 0,193, 0, 0, 0,195, 0, 0, 0, 34,
- 0, 0, 0,136, 0, 0, 0,195, 0, 0, 0, 34, 0, 0, 0,136, 0, 0, 0,138, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0,135,
- 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0,194, 0, 0, 0, 34, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0, 34, 0, 0, 0, 69,
- 0, 0, 0,195, 0, 0, 0, 34, 0, 0, 0, 68, 0, 0, 0,188, 0, 0, 0, 34, 0, 0, 0, 68, 0, 0, 0,187, 0, 0, 0, 34,
- 0, 0, 0, 68, 0, 0, 0,189, 0, 0, 0, 34, 0, 0, 0,188, 0, 0, 0,203, 0, 0, 0, 34, 0, 0, 0,203, 0, 0, 0,205,
- 0, 0, 0, 34, 0, 0, 0, 68, 0, 0, 0,205, 0, 0, 0, 34, 0, 0, 0,189, 0, 0, 0,204, 0, 0, 0, 34, 0, 0, 0,204,
- 0, 0, 0,205, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0,196, 0, 0, 0, 34, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0, 34,
- 0, 0, 0,194, 0, 0, 0,197, 0, 0, 0, 34, 0, 0, 0,196, 0, 0, 0,198, 0, 0, 0, 34, 0, 0, 0,195, 0, 0, 0,198,
- 0, 0, 0, 34, 0, 0, 0,197, 0, 0, 0,199, 0, 0, 0, 34, 0, 0, 0,192, 0, 0, 0,199, 0, 0, 0, 34, 0, 0, 0,198,
- 0, 0, 0,200, 0, 0, 0, 34, 0, 0, 0,193, 0, 0, 0,200, 0, 0, 0, 34, 0, 0, 0,199, 0, 0, 0,201, 0, 0, 0, 34,
- 0, 0, 0,190, 0, 0, 0,201, 0, 0, 0, 34, 0, 0, 0,200, 0, 0, 0,202, 0, 0, 0, 34, 0, 0, 0,191, 0, 0, 0,202,
- 0, 0, 0, 34, 0, 0, 0,201, 0, 0, 0,203, 0, 0, 0, 34, 0, 0, 0,202, 0, 0, 0,204, 0, 0, 0, 34, 0, 0, 0,196,
- 0, 0, 0,201, 0, 0, 0, 34, 0, 0, 0,196, 0, 0, 0,202, 0, 0, 0, 34, 0, 0, 0,196, 0, 0, 0,205, 0, 0, 0, 34,
- 0, 0, 0,137, 0, 0, 0,161, 0, 0, 0, 34, 0, 0, 0,136, 0, 0, 0,174, 0, 0, 0, 34, 0, 0, 0,138, 0, 0, 0,162,
- 0, 0, 0, 34, 0, 0, 0,139, 0, 0, 0,208, 0, 0, 0, 34, 0, 0, 0,161, 0, 0, 0,208, 0, 0, 0, 34, 0, 0, 0,140,
- 0, 0, 0,209, 0, 0, 0, 34, 0, 0, 0,162, 0, 0, 0,209, 0, 0, 0, 34, 0, 0, 0,141, 0, 0, 0,210, 0, 0, 0, 34,
- 0, 0, 0,208, 0, 0, 0,210, 0, 0, 0, 34, 0, 0, 0,142, 0, 0, 0,211, 0, 0, 0, 34, 0, 0, 0,209, 0, 0, 0,211,
- 0, 0, 0, 34, 0, 0, 0,163, 0, 0, 0,210, 0, 0, 0, 34, 0, 0, 0,164, 0, 0, 0,211, 0, 0, 0, 34, 0, 0, 0, 79,
- 0, 0, 0,206, 0, 0, 0, 34, 0, 0, 0,206, 0, 0, 0,210, 0, 0, 0, 34, 0, 0, 0,207, 0, 0, 0,211, 0, 0, 0, 34,
- 0, 0, 0, 80, 0, 0, 0,207, 0, 0, 0, 34, 0, 0, 0,206, 0, 0, 0,212, 0, 0, 0, 34, 0, 0, 0,208, 0, 0, 0,212,
- 0, 0, 0, 34, 0, 0, 0,209, 0, 0, 0,213, 0, 0, 0, 34, 0, 0, 0,207, 0, 0, 0,213, 0, 0, 0, 34, 0, 0, 0, 77,
- 0, 0, 0,212, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 0,213, 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0,127, 0, 0, 0, 34,
- 0, 0, 0, 70, 0, 0, 0,219, 0, 0, 0, 34, 0, 0, 0,128, 0, 0, 0,219, 0, 0, 0, 34, 0, 0, 0,129, 0, 0, 0,220,
- 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0,220, 0, 0, 0, 34, 0, 0, 0,217, 0, 0, 0,219, 0, 0, 0, 34, 0, 0, 0,130,
- 0, 0, 0,217, 0, 0, 0, 34, 0, 0, 0,131, 0, 0, 0,218, 0, 0, 0, 34, 0, 0, 0,218, 0, 0, 0,220, 0, 0, 0, 34,
- 0, 0, 0,215, 0, 0, 0,217, 0, 0, 0, 34, 0, 0, 0,132, 0, 0, 0,215, 0, 0, 0, 34, 0, 0, 0,133, 0, 0, 0,216,
- 0, 0, 0, 34, 0, 0, 0,216, 0, 0, 0,218, 0, 0, 0, 34, 0, 0, 0,214, 0, 0, 0,215, 0, 0, 0, 34, 0, 0, 0,134,
- 0, 0, 0,214, 0, 0, 0, 34, 0, 0, 0,214, 0, 0, 0,216, 0, 0, 0, 34, 0, 0, 0,215, 0, 0, 0,226, 0, 0, 0, 34,
- 0, 0, 0,226, 0, 0, 0,228, 0, 0, 0, 34, 0, 0, 0,214, 0, 0, 0,228, 0, 0, 0, 34, 0, 0, 0,216, 0, 0, 0,227,
- 0, 0, 0, 34, 0, 0, 0,227, 0, 0, 0,228, 0, 0, 0, 34, 0, 0, 0,217, 0, 0, 0,224, 0, 0, 0, 34, 0, 0, 0,224,
- 0, 0, 0,226, 0, 0, 0, 34, 0, 0, 0,218, 0, 0, 0,225, 0, 0, 0, 34, 0, 0, 0,225, 0, 0, 0,227, 0, 0, 0, 34,
- 0, 0, 0,219, 0, 0, 0,222, 0, 0, 0, 34, 0, 0, 0,222, 0, 0, 0,224, 0, 0, 0, 34, 0, 0, 0,220, 0, 0, 0,223,
- 0, 0, 0, 34, 0, 0, 0,223, 0, 0, 0,225, 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0,221, 0, 0, 0, 34, 0, 0, 0,221,
- 0, 0, 0,222, 0, 0, 0, 34, 0, 0, 0,221, 0, 0, 0,223, 0, 0, 0, 34, 0, 0, 0,221, 0, 0, 0,228, 0, 0, 0, 34,
- 0, 0, 0,222, 0, 0, 0,226, 0, 0, 0, 34, 0, 0, 0,223, 0, 0, 0,227, 0, 0, 0, 34, 0, 0, 0,178, 0, 0, 0,231,
- 0, 0, 0, 34, 0, 0, 0,229, 0, 0, 0,231, 0, 0, 0, 34, 0, 0, 0,180, 0, 0, 0,229, 0, 0, 0, 34, 0, 0, 0,179,
- 0, 0, 0,232, 0, 0, 0, 34, 0, 0, 0,181, 0, 0, 0,230, 0, 0, 0, 34, 0, 0, 0,230, 0, 0, 0,232, 0, 0, 0, 34,
- 0, 0, 0,229, 0, 0, 0,251, 0, 0, 0, 34, 0, 0, 0,110, 0, 0, 0,251, 0, 0, 0, 34, 0, 0, 0,111, 0, 0, 0,252,
- 0, 0, 0, 34, 0, 0, 0,230, 0, 0, 0,252, 0, 0, 0, 34, 0, 0, 0,251, 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 0,108,
- 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,254, 0, 0, 0, 34, 0, 0, 0,252, 0, 0, 0,254, 0, 0, 0, 34,
- 0, 0, 0,231, 0, 0, 0,249, 0, 0, 0, 34, 0, 0, 0,112, 0, 0, 0,250, 0, 0, 0, 34, 0, 0, 0,232, 0, 0, 0,250,
- 0, 0, 0, 34, 0, 0, 0,113, 0, 0, 0,247, 0, 0, 0, 34, 0, 0, 0,247, 0, 0, 0,249, 0, 0, 0, 34, 0, 0, 0,114,
- 0, 0, 0,248, 0, 0, 0, 34, 0, 0, 0,248, 0, 0, 0,250, 0, 0, 0, 34, 0, 0, 0,115, 0, 0, 0,245, 0, 0, 0, 34,
- 0, 0, 0,245, 0, 0, 0,247, 0, 0, 0, 34, 0, 0, 0,116, 0, 0, 0,246, 0, 0, 0, 34, 0, 0, 0,246, 0, 0, 0,248,
- 0, 0, 0, 34, 0, 0, 0,117, 0, 0, 0,243, 0, 0, 0, 34, 0, 0, 0,243, 0, 0, 0,245, 0, 0, 0, 34, 0, 0, 0,118,
- 0, 0, 0,244, 0, 0, 0, 34, 0, 0, 0,244, 0, 0, 0,246, 0, 0, 0, 34, 0, 0, 0,119, 0, 0, 0,241, 0, 0, 0, 34,
- 0, 0, 0,241, 0, 0, 0,243, 0, 0, 0, 34, 0, 0, 0,120, 0, 0, 0,242, 0, 0, 0, 34, 0, 0, 0,242, 0, 0, 0,244,
- 0, 0, 0, 34, 0, 0, 0,121, 0, 0, 0,239, 0, 0, 0, 34, 0, 0, 0,239, 0, 0, 0,241, 0, 0, 0, 34, 0, 0, 0,122,
- 0, 0, 0,240, 0, 0, 0, 34, 0, 0, 0,240, 0, 0, 0,242, 0, 0, 0, 34, 0, 0, 0,123, 0, 0, 0,237, 0, 0, 0, 34,
- 0, 0, 0,237, 0, 0, 0,239, 0, 0, 0, 34, 0, 0, 0,124, 0, 0, 0,238, 0, 0, 0, 34, 0, 0, 0,238, 0, 0, 0,240,
- 0, 0, 0, 34, 0, 0, 0,176, 0, 0, 0,233, 0, 0, 0, 34, 0, 0, 0,233, 0, 0, 0,237, 0, 0, 0, 34, 0, 0, 0,177,
- 0, 0, 0,234, 0, 0, 0, 34, 0, 0, 0,234, 0, 0, 0,238, 0, 0, 0, 34, 0, 0, 0,125, 0, 0, 0,235, 0, 0, 0, 34,
- 0, 0, 0,233, 0, 0, 0,235, 0, 0, 0, 34, 0, 0, 0,126, 0, 0, 0,236, 0, 0, 0, 34, 0, 0, 0,234, 0, 0, 0,236,
- 0, 0, 0, 34, 0, 0, 0,235, 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 0,236, 0, 0, 0,254, 0, 0, 0, 34, 0, 0, 0,253,
- 0, 0, 0,255, 0, 0, 0, 34, 0, 0, 0,255, 0, 0, 1, 17, 0, 0, 0, 34, 0, 0, 0,235, 0, 0, 1, 17, 0, 0, 0, 34,
- 0, 0, 0,254, 0, 0, 1, 0, 0, 0, 0, 34, 0, 0, 0,236, 0, 0, 1, 18, 0, 0, 0, 34, 0, 0, 1, 0, 0, 0, 1, 18,
- 0, 0, 0, 34, 0, 0, 1, 17, 0, 0, 1, 19, 0, 0, 0, 34, 0, 0, 0,233, 0, 0, 1, 19, 0, 0, 0, 34, 0, 0, 0,234,
- 0, 0, 1, 20, 0, 0, 0, 34, 0, 0, 1, 18, 0, 0, 1, 20, 0, 0, 0, 34, 0, 0, 1, 15, 0, 0, 1, 19, 0, 0, 0, 34,
- 0, 0, 0,237, 0, 0, 1, 15, 0, 0, 0, 34, 0, 0, 0,238, 0, 0, 1, 16, 0, 0, 0, 34, 0, 0, 1, 16, 0, 0, 1, 20,
- 0, 0, 0, 34, 0, 0, 1, 13, 0, 0, 1, 15, 0, 0, 0, 34, 0, 0, 0,239, 0, 0, 1, 13, 0, 0, 0, 34, 0, 0, 0,240,
- 0, 0, 1, 14, 0, 0, 0, 34, 0, 0, 1, 14, 0, 0, 1, 16, 0, 0, 0, 34, 0, 0, 1, 11, 0, 0, 1, 13, 0, 0, 0, 34,
- 0, 0, 0,241, 0, 0, 1, 11, 0, 0, 0, 34, 0, 0, 0,242, 0, 0, 1, 12, 0, 0, 0, 34, 0, 0, 1, 12, 0, 0, 1, 14,
- 0, 0, 0, 34, 0, 0, 1, 9, 0, 0, 1, 11, 0, 0, 0, 34, 0, 0, 0,243, 0, 0, 1, 9, 0, 0, 0, 34, 0, 0, 0,244,
- 0, 0, 1, 10, 0, 0, 0, 34, 0, 0, 1, 10, 0, 0, 1, 12, 0, 0, 0, 34, 0, 0, 1, 7, 0, 0, 1, 9, 0, 0, 0, 34,
- 0, 0, 0,245, 0, 0, 1, 7, 0, 0, 0, 34, 0, 0, 0,246, 0, 0, 1, 8, 0, 0, 0, 34, 0, 0, 1, 8, 0, 0, 1, 10,
- 0, 0, 0, 34, 0, 0, 1, 5, 0, 0, 1, 7, 0, 0, 0, 34, 0, 0, 0,247, 0, 0, 1, 5, 0, 0, 0, 34, 0, 0, 0,248,
- 0, 0, 1, 6, 0, 0, 0, 34, 0, 0, 1, 6, 0, 0, 1, 8, 0, 0, 0, 34, 0, 0, 1, 3, 0, 0, 1, 5, 0, 0, 0, 34,
- 0, 0, 0,249, 0, 0, 1, 3, 0, 0, 0, 34, 0, 0, 0,250, 0, 0, 1, 4, 0, 0, 0, 34, 0, 0, 1, 4, 0, 0, 1, 6,
- 0, 0, 0, 34, 0, 0, 1, 3, 0, 0, 1, 21, 0, 0, 0, 34, 0, 0, 0,231, 0, 0, 1, 21, 0, 0, 0, 34, 0, 0, 0,232,
- 0, 0, 1, 22, 0, 0, 0, 34, 0, 0, 1, 4, 0, 0, 1, 22, 0, 0, 0, 34, 0, 0, 0,251, 0, 0, 1, 1, 0, 0, 0, 34,
- 0, 0, 0,255, 0, 0, 1, 1, 0, 0, 0, 34, 0, 0, 0,252, 0, 0, 1, 2, 0, 0, 0, 34, 0, 0, 1, 0, 0, 0, 1, 2,
- 0, 0, 0, 34, 0, 0, 0,229, 0, 0, 1, 23, 0, 0, 0, 34, 0, 0, 1, 1, 0, 0, 1, 23, 0, 0, 0, 34, 0, 0, 0,230,
- 0, 0, 1, 24, 0, 0, 0, 34, 0, 0, 1, 2, 0, 0, 1, 24, 0, 0, 0, 34, 0, 0, 1, 21, 0, 0, 1, 23, 0, 0, 0, 34,
- 0, 0, 1, 22, 0, 0, 1, 24, 0, 0, 0, 34, 0, 0, 0,106, 0, 0, 1, 25, 0, 0, 0, 34, 0, 0, 0, 71, 0, 0, 1, 25,
- 0, 0, 0, 38, 0, 0, 0, 65, 0, 0, 0, 71, 0, 0, 0, 34, 0, 0, 0,107, 0, 0, 1, 26, 0, 0, 0, 34, 0, 0, 0, 71,
- 0, 0, 1, 26, 0, 0, 0, 38, 0, 0, 0,104, 0, 0, 1, 27, 0, 0, 0, 34, 0, 0, 1, 25, 0, 0, 1, 27, 0, 0, 0, 34,
- 0, 0, 0,105, 0, 0, 1, 28, 0, 0, 0, 34, 0, 0, 1, 26, 0, 0, 1, 28, 0, 0, 0, 34, 0, 0, 0,102, 0, 0, 1, 29,
- 0, 0, 0, 34, 0, 0, 1, 27, 0, 0, 1, 29, 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 1, 30, 0, 0, 0, 34, 0, 0, 1, 28,
- 0, 0, 1, 30, 0, 0, 0, 34, 0, 0, 0,100, 0, 0, 1, 31, 0, 0, 0, 34, 0, 0, 1, 29, 0, 0, 1, 31, 0, 0, 0, 34,
- 0, 0, 0,101, 0, 0, 1, 32, 0, 0, 0, 34, 0, 0, 1, 30, 0, 0, 1, 32, 0, 0, 0, 34, 0, 0, 0, 98, 0, 0, 1, 33,
- 0, 0, 0, 34, 0, 0, 1, 31, 0, 0, 1, 33, 0, 0, 0, 38, 0, 0, 0, 99, 0, 0, 1, 34, 0, 0, 0, 34, 0, 0, 1, 32,
- 0, 0, 1, 34, 0, 0, 0, 38, 0, 0, 0, 96, 0, 0, 1, 35, 0, 0, 0, 34, 0, 0, 1, 33, 0, 0, 1, 35, 0, 0, 0, 34,
- 0, 0, 0, 97, 0, 0, 1, 36, 0, 0, 0, 34, 0, 0, 1, 34, 0, 0, 1, 36, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 1, 37,
- 0, 0, 0, 34, 0, 0, 1, 35, 0, 0, 1, 37, 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 1, 38, 0, 0, 0, 34, 0, 0, 1, 36,
- 0, 0, 1, 38, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 1, 39, 0, 0, 0, 34, 0, 0, 1, 37, 0, 0, 1, 39, 0, 0, 0, 34,
- 0, 0, 0, 93, 0, 0, 1, 40, 0, 0, 0, 34, 0, 0, 1, 38, 0, 0, 1, 40, 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 1, 41,
- 0, 0, 0, 34, 0, 0, 1, 39, 0, 0, 1, 41, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 1, 42, 0, 0, 0, 34, 0, 0, 1, 40,
- 0, 0, 1, 42, 0, 0, 0, 34, 0, 0, 1, 49, 0, 0, 1, 50, 0, 0, 0, 38, 0, 0, 1, 50, 0, 0, 1, 69, 0, 0, 0, 34,
- 0, 0, 1, 69, 0, 0, 1, 79, 0, 0, 0, 34, 0, 0, 1, 49, 0, 0, 1, 79, 0, 0, 0, 34, 0, 0, 1, 50, 0, 0, 1, 70,
- 0, 0, 0, 34, 0, 0, 1, 49, 0, 0, 1, 80, 0, 0, 0, 34, 0, 0, 1, 70, 0, 0, 1, 80, 0, 0, 0, 34, 0, 0, 1, 48,
- 0, 0, 1, 49, 0, 0, 0, 38, 0, 0, 1, 77, 0, 0, 1, 79, 0, 0, 0, 34, 0, 0, 1, 48, 0, 0, 1, 77, 0, 0, 0, 34,
- 0, 0, 1, 48, 0, 0, 1, 78, 0, 0, 0, 34, 0, 0, 1, 78, 0, 0, 1, 80, 0, 0, 0, 34, 0, 0, 1, 47, 0, 0, 1, 48,
- 0, 0, 0, 38, 0, 0, 1, 77, 0, 0, 1, 81, 0, 0, 0, 34, 0, 0, 1, 47, 0, 0, 1, 81, 0, 0, 0, 34, 0, 0, 1, 47,
- 0, 0, 1, 82, 0, 0, 0, 34, 0, 0, 1, 78, 0, 0, 1, 82, 0, 0, 0, 34, 0, 0, 0, 89, 0, 0, 1, 47, 0, 0, 0, 38,
- 0, 0, 0, 87, 0, 0, 1, 81, 0, 0, 0, 34, 0, 0, 0, 88, 0, 0, 1, 82, 0, 0, 0, 34, 0, 0, 1, 75, 0, 0, 1, 81,
- 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 1, 75, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 1, 76, 0, 0, 0, 34, 0, 0, 1, 76,
- 0, 0, 1, 82, 0, 0, 0, 34, 0, 0, 1, 71, 0, 0, 1, 75, 0, 0, 0, 34, 0, 0, 0, 83, 0, 0, 1, 71, 0, 0, 0, 34,
- 0, 0, 0, 84, 0, 0, 1, 72, 0, 0, 0, 34, 0, 0, 1, 72, 0, 0, 1, 76, 0, 0, 0, 34, 0, 0, 1, 71, 0, 0, 1, 73,
- 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 1, 73, 0, 0, 0, 34, 0, 0, 0, 82, 0, 0, 1, 74, 0, 0, 0, 34, 0, 0, 1, 72,
- 0, 0, 1, 74, 0, 0, 0, 34, 0, 0, 1, 71, 0, 0, 1, 77, 0, 0, 0, 34, 0, 0, 1, 73, 0, 0, 1, 79, 0, 0, 0, 34,
- 0, 0, 1, 72, 0, 0, 1, 78, 0, 0, 0, 34, 0, 0, 1, 74, 0, 0, 1, 80, 0, 0, 0, 34, 0, 0, 1, 67, 0, 0, 1, 73,
- 0, 0, 0, 34, 0, 0, 1, 67, 0, 0, 1, 69, 0, 0, 0, 34, 0, 0, 1, 68, 0, 0, 1, 74, 0, 0, 0, 34, 0, 0, 1, 68,
- 0, 0, 1, 70, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 1, 67, 0, 0, 0, 34, 0, 0, 0, 80, 0, 0, 1, 68, 0, 0, 0, 34,
- 0, 0, 0,206, 0, 0, 1, 83, 0, 0, 0, 34, 0, 0, 1, 83, 0, 0, 1, 85, 0, 0, 0, 34, 0, 0, 0,212, 0, 0, 1, 85,
- 0, 0, 0, 34, 0, 0, 1, 84, 0, 0, 1, 86, 0, 0, 0, 34, 0, 0, 0,207, 0, 0, 1, 84, 0, 0, 0, 34, 0, 0, 0,213,
- 0, 0, 1, 86, 0, 0, 0, 34, 0, 0, 1, 67, 0, 0, 1, 83, 0, 0, 0, 34, 0, 0, 1, 68, 0, 0, 1, 84, 0, 0, 0, 34,
- 0, 0, 1, 85, 0, 0, 1, 87, 0, 0, 0, 34, 0, 0, 0, 77, 0, 0, 1, 87, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 1, 88,
- 0, 0, 0, 34, 0, 0, 1, 86, 0, 0, 1, 88, 0, 0, 0, 34, 0, 0, 1, 41, 0, 0, 1, 87, 0, 0, 0, 34, 0, 0, 1, 42,
- 0, 0, 1, 88, 0, 0, 0, 34, 0, 0, 0, 75, 0, 0, 1, 65, 0, 0, 0, 34, 0, 0, 1, 65, 0, 0, 1, 93, 0, 0, 0, 34,
- 0, 0, 1, 45, 0, 0, 1, 93, 0, 0, 0, 39, 0, 0, 0, 75, 0, 0, 1, 45, 0, 0, 0, 38, 0, 0, 1, 66, 0, 0, 1, 94,
- 0, 0, 0, 34, 0, 0, 0, 75, 0, 0, 1, 66, 0, 0, 0, 34, 0, 0, 1, 45, 0, 0, 1, 94, 0, 0, 0, 39, 0, 0, 1, 91,
- 0, 0, 1, 93, 0, 0, 0, 34, 0, 0, 0, 76, 0, 0, 1, 91, 0, 0, 0, 34, 0, 0, 0, 76, 0, 0, 1, 45, 0, 0, 0, 38,
- 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 34, 0, 0, 0, 76, 0, 0, 1, 92, 0, 0, 0, 34, 0, 0, 1, 89, 0, 0, 1, 91,
- 0, 0, 0, 34, 0, 0, 1, 46, 0, 0, 1, 89, 0, 0, 0, 34, 0, 0, 0, 76, 0, 0, 1, 46, 0, 0, 0, 38, 0, 0, 1, 90,
- 0, 0, 1, 92, 0, 0, 0, 34, 0, 0, 1, 46, 0, 0, 1, 90, 0, 0, 0, 34, 0, 0, 1, 69, 0, 0, 1, 89, 0, 0, 0, 34,
- 0, 0, 1, 46, 0, 0, 1, 50, 0, 0, 0, 38, 0, 0, 1, 70, 0, 0, 1, 90, 0, 0, 0, 34, 0, 0, 1, 83, 0, 0, 1, 89,
- 0, 0, 0, 34, 0, 0, 1, 84, 0, 0, 1, 90, 0, 0, 0, 34, 0, 0, 1, 39, 0, 0, 1, 59, 0, 0, 0, 34, 0, 0, 1, 51,
- 0, 0, 1, 59, 0, 0, 0, 34, 0, 0, 1, 37, 0, 0, 1, 51, 0, 0, 0, 34, 0, 0, 1, 40, 0, 0, 1, 60, 0, 0, 0, 34,
- 0, 0, 1, 38, 0, 0, 1, 52, 0, 0, 0, 34, 0, 0, 1, 52, 0, 0, 1, 60, 0, 0, 0, 34, 0, 0, 0, 74, 0, 0, 1, 57,
- 0, 0, 0, 39, 0, 0, 1, 57, 0, 0, 1, 65, 0, 0, 0, 34, 0, 0, 0, 74, 0, 0, 0, 75, 0, 0, 0, 38, 0, 0, 1, 58,
- 0, 0, 1, 66, 0, 0, 0, 34, 0, 0, 0, 74, 0, 0, 1, 58, 0, 0, 0, 39, 0, 0, 1, 43, 0, 0, 1, 99, 0, 0, 0, 34,
- 0, 0, 1, 97, 0, 0, 1, 99, 0, 0, 0, 34, 0, 0, 1, 44, 0, 0, 1, 97, 0, 0, 0, 34, 0, 0, 1, 43, 0, 0, 1, 44,
- 0, 0, 0, 38, 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 0, 34, 0, 0, 1, 43, 0, 0, 1,100, 0, 0, 0, 34, 0, 0, 1, 44,
- 0, 0, 1, 98, 0, 0, 0, 34, 0, 0, 1, 95, 0, 0, 1, 97, 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 1, 95, 0, 0, 0, 34,
- 0, 0, 0, 73, 0, 0, 1, 44, 0, 0, 0, 38, 0, 0, 1, 96, 0, 0, 1, 98, 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 1, 96,
- 0, 0, 0, 34, 0, 0, 1, 57, 0, 0, 1, 95, 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0, 38, 0, 0, 1, 58,
- 0, 0, 1, 96, 0, 0, 0, 34, 0, 0, 1, 35, 0, 0, 1,103, 0, 0, 0, 34, 0, 0, 1,103, 0, 0, 1,105, 0, 0, 0, 34,
- 0, 0, 1, 33, 0, 0, 1,105, 0, 0, 0, 34, 0, 0, 1, 36, 0, 0, 1,104, 0, 0, 0, 34, 0, 0, 1, 34, 0, 0, 1,106,
- 0, 0, 0, 34, 0, 0, 1,104, 0, 0, 1,106, 0, 0, 0, 34, 0, 0, 1,103, 0, 0, 1,109, 0, 0, 0, 34, 0, 0, 1,107,
- 0, 0, 1,109, 0, 0, 0, 34, 0, 0, 1,105, 0, 0, 1,107, 0, 0, 0, 34, 0, 0, 1,104, 0, 0, 1,110, 0, 0, 0, 34,
- 0, 0, 1,106, 0, 0, 1,108, 0, 0, 0, 34, 0, 0, 1,108, 0, 0, 1,110, 0, 0, 0, 34, 0, 0, 1,109, 0, 0, 1,111,
- 0, 0, 0, 34, 0, 0, 1,111, 0, 0, 1,113, 0, 0, 0, 34, 0, 0, 1,107, 0, 0, 1,113, 0, 0, 0, 34, 0, 0, 1,110,
- 0, 0, 1,112, 0, 0, 0, 34, 0, 0, 1,108, 0, 0, 1,114, 0, 0, 0, 34, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 0, 34,
- 0, 0, 1,111, 0, 0, 1,117, 0, 0, 0, 34, 0, 0, 1,115, 0, 0, 1,117, 0, 0, 0, 34, 0, 0, 1,113, 0, 0, 1,115,
- 0, 0, 0, 34, 0, 0, 1,112, 0, 0, 1,118, 0, 0, 0, 34, 0, 0, 1,114, 0, 0, 1,116, 0, 0, 0, 34, 0, 0, 1,116,
- 0, 0, 1,118, 0, 0, 0, 34, 0, 0, 1, 55, 0, 0, 1,119, 0, 0, 0, 39, 0, 0, 1,115, 0, 0, 1,119, 0, 0, 0, 34,
- 0, 0, 1, 55, 0, 0, 1,117, 0, 0, 0, 34, 0, 0, 1,116, 0, 0, 1,120, 0, 0, 0, 34, 0, 0, 1, 56, 0, 0, 1,120,
- 0, 0, 0, 39, 0, 0, 1, 56, 0, 0, 1,118, 0, 0, 0, 34, 0, 0, 1, 95, 0, 0, 1,115, 0, 0, 0, 34, 0, 0, 1, 57,
- 0, 0, 1,119, 0, 0, 0, 39, 0, 0, 1, 96, 0, 0, 1,116, 0, 0, 0, 34, 0, 0, 1, 58, 0, 0, 1,120, 0, 0, 0, 39,
- 0, 0, 1, 97, 0, 0, 1,113, 0, 0, 0, 34, 0, 0, 1, 98, 0, 0, 1,114, 0, 0, 0, 34, 0, 0, 1, 99, 0, 0, 1,107,
- 0, 0, 0, 34, 0, 0, 1,100, 0, 0, 1,108, 0, 0, 0, 34, 0, 0, 1, 99, 0, 0, 1,101, 0, 0, 0, 34, 0, 0, 1,101,
- 0, 0, 1,105, 0, 0, 0, 34, 0, 0, 1,102, 0, 0, 1,106, 0, 0, 0, 34, 0, 0, 1,100, 0, 0, 1,102, 0, 0, 0, 34,
- 0, 0, 1, 31, 0, 0, 1,101, 0, 0, 0, 34, 0, 0, 1, 32, 0, 0, 1,102, 0, 0, 0, 34, 0, 0, 0, 72, 0, 0, 1,101,
- 0, 0, 0, 34, 0, 0, 0, 72, 0, 0, 1, 43, 0, 0, 0, 38, 0, 0, 0, 72, 0, 0, 1,102, 0, 0, 0, 34, 0, 0, 1, 25,
- 0, 0, 1, 31, 0, 0, 0, 38, 0, 0, 1, 26, 0, 0, 1, 32, 0, 0, 0, 38, 0, 0, 0, 72, 0, 0, 1, 25, 0, 0, 0, 34,
- 0, 0, 0, 72, 0, 0, 1, 26, 0, 0, 0, 34, 0, 0, 0, 71, 0, 0, 0, 72, 0, 0, 0, 38, 0, 0, 1, 51, 0, 0, 1,103,
- 0, 0, 0, 34, 0, 0, 1, 52, 0, 0, 1,104, 0, 0, 0, 34, 0, 0, 1, 51, 0, 0, 1, 53, 0, 0, 0, 34, 0, 0, 1, 53,
- 0, 0, 1,109, 0, 0, 0, 34, 0, 0, 1, 54, 0, 0, 1,110, 0, 0, 0, 34, 0, 0, 1, 52, 0, 0, 1, 54, 0, 0, 0, 34,
- 0, 0, 1, 53, 0, 0, 1,123, 0, 0, 0, 34, 0, 0, 1,111, 0, 0, 1,123, 0, 0, 0, 34, 0, 0, 1,112, 0, 0, 1,124,
- 0, 0, 0, 34, 0, 0, 1, 54, 0, 0, 1,124, 0, 0, 0, 34, 0, 0, 1, 55, 0, 0, 1,123, 0, 0, 0, 34, 0, 0, 1, 56,
- 0, 0, 1,124, 0, 0, 0, 34, 0, 0, 1, 91, 0, 0, 1,127, 0, 0, 0, 34, 0, 0, 1,125, 0, 0, 1,127, 0, 0, 0, 34,
- 0, 0, 1, 89, 0, 0, 1,125, 0, 0, 0, 34, 0, 0, 1, 92, 0, 0, 1,128, 0, 0, 0, 34, 0, 0, 1, 90, 0, 0, 1,126,
- 0, 0, 0, 34, 0, 0, 1,126, 0, 0, 1,128, 0, 0, 0, 34, 0, 0, 1, 59, 0, 0, 1,125, 0, 0, 0, 34, 0, 0, 1, 61,
- 0, 0, 1,127, 0, 0, 0, 34, 0, 0, 1, 59, 0, 0, 1, 61, 0, 0, 0, 34, 0, 0, 1, 60, 0, 0, 1,126, 0, 0, 0, 34,
- 0, 0, 1, 60, 0, 0, 1, 62, 0, 0, 0, 34, 0, 0, 1, 62, 0, 0, 1,128, 0, 0, 0, 34, 0, 0, 1, 41, 0, 0, 1,125,
- 0, 0, 0, 34, 0, 0, 1, 42, 0, 0, 1,126, 0, 0, 0, 34, 0, 0, 1, 41, 0, 0, 1, 85, 0, 0, 0, 34, 0, 0, 1, 83,
- 0, 0, 1,125, 0, 0, 0, 34, 0, 0, 1, 42, 0, 0, 1, 86, 0, 0, 0, 34, 0, 0, 1, 84, 0, 0, 1,126, 0, 0, 0, 34,
- 0, 0, 1, 55, 0, 0, 1, 63, 0, 0, 0, 34, 0, 0, 1, 63, 0, 0, 1,121, 0, 0, 0, 39, 0, 0, 1,119, 0, 0, 1,121,
- 0, 0, 0, 34, 0, 0, 1, 64, 0, 0, 1,122, 0, 0, 0, 39, 0, 0, 1, 56, 0, 0, 1, 64, 0, 0, 0, 34, 0, 0, 1,120,
- 0, 0, 1,122, 0, 0, 0, 34, 0, 0, 1, 65, 0, 0, 1,121, 0, 0, 0, 34, 0, 0, 1, 66, 0, 0, 1,122, 0, 0, 0, 34,
- 0, 0, 1,121, 0, 0, 1,127, 0, 0, 0, 34, 0, 0, 1, 61, 0, 0, 1, 63, 0, 0, 0, 34, 0, 0, 1,122, 0, 0, 1,128,
- 0, 0, 0, 34, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 0, 34, 0, 0, 1, 93, 0, 0, 1,121, 0, 0, 0, 39, 0, 0, 1, 94,
- 0, 0, 1,122, 0, 0, 0, 39, 0, 0, 1,129, 0, 0, 1,141, 0, 0, 0, 34, 0, 0, 1,129, 0, 0, 1,155, 0, 0, 0, 34,
- 0, 0, 1,143, 0, 0, 1,155, 0, 0, 0, 34, 0, 0, 1,141, 0, 0, 1,143, 0, 0, 0, 34, 0, 0, 1,130, 0, 0, 1,156,
- 0, 0, 0, 34, 0, 0, 1,130, 0, 0, 1,142, 0, 0, 0, 34, 0, 0, 1,142, 0, 0, 1,144, 0, 0, 0, 34, 0, 0, 1,144,
- 0, 0, 1,156, 0, 0, 0, 34, 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 34, 0, 0, 1,139, 0, 0, 1,145, 0, 0, 0, 34,
- 0, 0, 1,139, 0, 0, 1,141, 0, 0, 0, 34, 0, 0, 1,144, 0, 0, 1,146, 0, 0, 0, 34, 0, 0, 1,140, 0, 0, 1,142,
- 0, 0, 0, 34, 0, 0, 1,140, 0, 0, 1,146, 0, 0, 0, 34, 0, 0, 1,145, 0, 0, 1,147, 0, 0, 0, 34, 0, 0, 1,137,
- 0, 0, 1,147, 0, 0, 0, 34, 0, 0, 1,137, 0, 0, 1,139, 0, 0, 0, 34, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 0, 34,
- 0, 0, 1,138, 0, 0, 1,140, 0, 0, 0, 34, 0, 0, 1,138, 0, 0, 1,148, 0, 0, 0, 34, 0, 0, 1,147, 0, 0, 1,149,
- 0, 0, 0, 34, 0, 0, 1,135, 0, 0, 1,149, 0, 0, 0, 34, 0, 0, 1,135, 0, 0, 1,137, 0, 0, 0, 34, 0, 0, 1,148,
- 0, 0, 1,150, 0, 0, 0, 34, 0, 0, 1,136, 0, 0, 1,138, 0, 0, 0, 34, 0, 0, 1,136, 0, 0, 1,150, 0, 0, 0, 34,
- 0, 0, 1,149, 0, 0, 1,151, 0, 0, 0, 34, 0, 0, 1,133, 0, 0, 1,151, 0, 0, 0, 34, 0, 0, 1,133, 0, 0, 1,135,
- 0, 0, 0, 34, 0, 0, 1,150, 0, 0, 1,152, 0, 0, 0, 34, 0, 0, 1,134, 0, 0, 1,136, 0, 0, 0, 34, 0, 0, 1,134,
- 0, 0, 1,152, 0, 0, 0, 34, 0, 0, 1,151, 0, 0, 1,153, 0, 0, 0, 34, 0, 0, 1,131, 0, 0, 1,153, 0, 0, 0, 34,
- 0, 0, 1,131, 0, 0, 1,133, 0, 0, 0, 34, 0, 0, 1,152, 0, 0, 1,154, 0, 0, 0, 34, 0, 0, 1,132, 0, 0, 1,134,
- 0, 0, 0, 34, 0, 0, 1,132, 0, 0, 1,154, 0, 0, 0, 34, 0, 0, 1,151, 0, 0, 1,161, 0, 0, 0, 34, 0, 0, 1,159,
- 0, 0, 1,161, 0, 0, 0, 34, 0, 0, 1,153, 0, 0, 1,159, 0, 0, 0, 34, 0, 0, 1,160, 0, 0, 1,162, 0, 0, 0, 34,
- 0, 0, 1,152, 0, 0, 1,162, 0, 0, 0, 34, 0, 0, 1,154, 0, 0, 1,160, 0, 0, 0, 34, 0, 0, 1,149, 0, 0, 1,163,
- 0, 0, 0, 34, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 0, 34, 0, 0, 1,162, 0, 0, 1,164, 0, 0, 0, 34, 0, 0, 1,150,
- 0, 0, 1,164, 0, 0, 0, 34, 0, 0, 1,147, 0, 0, 1,165, 0, 0, 0, 34, 0, 0, 1,163, 0, 0, 1,165, 0, 0, 0, 34,
- 0, 0, 1,164, 0, 0, 1,166, 0, 0, 0, 34, 0, 0, 1,148, 0, 0, 1,166, 0, 0, 0, 34, 0, 0, 1,145, 0, 0, 1,167,
- 0, 0, 0, 34, 0, 0, 1,165, 0, 0, 1,167, 0, 0, 0, 34, 0, 0, 1,166, 0, 0, 1,168, 0, 0, 0, 34, 0, 0, 1,146,
- 0, 0, 1,168, 0, 0, 0, 34, 0, 0, 1,143, 0, 0, 1,169, 0, 0, 0, 34, 0, 0, 1,167, 0, 0, 1,169, 0, 0, 0, 34,
- 0, 0, 1,168, 0, 0, 1,170, 0, 0, 0, 34, 0, 0, 1,144, 0, 0, 1,170, 0, 0, 0, 34, 0, 0, 1,155, 0, 0, 1,157,
- 0, 0, 0, 34, 0, 0, 1,157, 0, 0, 1,169, 0, 0, 0, 34, 0, 0, 1,156, 0, 0, 1,158, 0, 0, 0, 34, 0, 0, 1,158,
- 0, 0, 1,170, 0, 0, 0, 34, 0, 0, 1, 61, 0, 0, 1,185, 0, 0, 0, 34, 0, 0, 1,183, 0, 0, 1,185, 0, 0, 0, 34,
- 0, 0, 1, 59, 0, 0, 1,183, 0, 0, 0, 34, 0, 0, 1, 62, 0, 0, 1,186, 0, 0, 0, 34, 0, 0, 1, 60, 0, 0, 1,184,
- 0, 0, 0, 34, 0, 0, 1,184, 0, 0, 1,186, 0, 0, 0, 34, 0, 0, 1, 61, 0, 0, 1,131, 0, 0, 0, 34, 0, 0, 1,153,
- 0, 0, 1,185, 0, 0, 0, 34, 0, 0, 1, 62, 0, 0, 1,132, 0, 0, 0, 34, 0, 0, 1,154, 0, 0, 1,186, 0, 0, 0, 34,
- 0, 0, 1, 53, 0, 0, 1,183, 0, 0, 0, 34, 0, 0, 1, 54, 0, 0, 1,184, 0, 0, 0, 34, 0, 0, 1,123, 0, 0, 1,171,
- 0, 0, 0, 34, 0, 0, 1,155, 0, 0, 1,171, 0, 0, 0, 34, 0, 0, 1,123, 0, 0, 1,129, 0, 0, 0, 34, 0, 0, 1,156,
- 0, 0, 1,172, 0, 0, 0, 34, 0, 0, 1,124, 0, 0, 1,172, 0, 0, 0, 34, 0, 0, 1,124, 0, 0, 1,130, 0, 0, 0, 34,
- 0, 0, 1,159, 0, 0, 1,181, 0, 0, 0, 34, 0, 0, 1,181, 0, 0, 1,185, 0, 0, 0, 34, 0, 0, 1,160, 0, 0, 1,182,
- 0, 0, 0, 34, 0, 0, 1,182, 0, 0, 1,186, 0, 0, 0, 34, 0, 0, 1,179, 0, 0, 1,187, 0, 0, 0, 34, 0, 0, 1,185,
- 0, 0, 1,187, 0, 0, 0, 34, 0, 0, 1,179, 0, 0, 1,181, 0, 0, 0, 34, 0, 0, 1,186, 0, 0, 1,188, 0, 0, 0, 34,
- 0, 0, 1,180, 0, 0, 1,188, 0, 0, 0, 34, 0, 0, 1,180, 0, 0, 1,182, 0, 0, 0, 34, 0, 0, 1,175, 0, 0, 1,187,
- 0, 0, 0, 34, 0, 0, 1,177, 0, 0, 1,179, 0, 0, 0, 34, 0, 0, 1,175, 0, 0, 1,177, 0, 0, 0, 34, 0, 0, 1,176,
- 0, 0, 1,188, 0, 0, 0, 34, 0, 0, 1,176, 0, 0, 1,178, 0, 0, 0, 34, 0, 0, 1,178, 0, 0, 1,180, 0, 0, 0, 34,
- 0, 0, 1,173, 0, 0, 1,189, 0, 0, 0, 34, 0, 0, 1,187, 0, 0, 1,189, 0, 0, 0, 34, 0, 0, 1,173, 0, 0, 1,175,
- 0, 0, 0, 34, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 0, 34, 0, 0, 1,174, 0, 0, 1,190, 0, 0, 0, 34, 0, 0, 1,174,
- 0, 0, 1,176, 0, 0, 0, 34, 0, 0, 1,171, 0, 0, 1,189, 0, 0, 0, 34, 0, 0, 1,173, 0, 0, 1,191, 0, 0, 0, 34,
- 0, 0, 1,171, 0, 0, 1,191, 0, 0, 0, 32, 0, 0, 1,172, 0, 0, 1,190, 0, 0, 0, 34, 0, 0, 1,172, 0, 0, 1,192,
- 0, 0, 0, 32, 0, 0, 1,174, 0, 0, 1,192, 0, 0, 0, 34, 0, 0, 1,157, 0, 0, 1,191, 0, 0, 0, 34, 0, 0, 1,158,
- 0, 0, 1,192, 0, 0, 0, 34, 0, 0, 1, 53, 0, 0, 1,189, 0, 0, 0, 34, 0, 0, 1, 54, 0, 0, 1,190, 0, 0, 0, 34,
- 0, 0, 1,183, 0, 0, 1,187, 0, 0, 0, 34, 0, 0, 1,184, 0, 0, 1,188, 0, 0, 0, 34, 0, 0, 1,191, 0, 0, 1,193,
- 0, 0, 0, 34, 0, 0, 1,193, 0, 0, 1,217, 0, 0, 0, 34, 0, 0, 1,157, 0, 0, 1,217, 0, 0, 0, 34, 0, 0, 1,192,
- 0, 0, 1,194, 0, 0, 0, 34, 0, 0, 1,158, 0, 0, 1,218, 0, 0, 0, 34, 0, 0, 1,194, 0, 0, 1,218, 0, 0, 0, 34,
- 0, 0, 1,173, 0, 0, 1,203, 0, 0, 0, 34, 0, 0, 1,193, 0, 0, 1,203, 0, 0, 0, 34, 0, 0, 1,174, 0, 0, 1,204,
- 0, 0, 0, 34, 0, 0, 1,194, 0, 0, 1,204, 0, 0, 0, 34, 0, 0, 1,175, 0, 0, 1,201, 0, 0, 0, 34, 0, 0, 1,201,
- 0, 0, 1,203, 0, 0, 0, 34, 0, 0, 1,176, 0, 0, 1,202, 0, 0, 0, 34, 0, 0, 1,202, 0, 0, 1,204, 0, 0, 0, 34,
- 0, 0, 1,177, 0, 0, 1,199, 0, 0, 0, 34, 0, 0, 1,199, 0, 0, 1,201, 0, 0, 0, 34, 0, 0, 1,178, 0, 0, 1,200,
- 0, 0, 0, 34, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 0, 34, 0, 0, 1,179, 0, 0, 1,197, 0, 0, 0, 34, 0, 0, 1,197,
- 0, 0, 1,199, 0, 0, 0, 34, 0, 0, 1,180, 0, 0, 1,198, 0, 0, 0, 34, 0, 0, 1,198, 0, 0, 1,200, 0, 0, 0, 34,
- 0, 0, 1,181, 0, 0, 1,195, 0, 0, 0, 34, 0, 0, 1,195, 0, 0, 1,197, 0, 0, 0, 34, 0, 0, 1,182, 0, 0, 1,196,
- 0, 0, 0, 34, 0, 0, 1,196, 0, 0, 1,198, 0, 0, 0, 34, 0, 0, 1,159, 0, 0, 1,215, 0, 0, 0, 34, 0, 0, 1,195,
- 0, 0, 1,215, 0, 0, 0, 34, 0, 0, 1,160, 0, 0, 1,216, 0, 0, 0, 34, 0, 0, 1,196, 0, 0, 1,216, 0, 0, 0, 34,
- 0, 0, 1,205, 0, 0, 1,217, 0, 0, 0, 34, 0, 0, 1,169, 0, 0, 1,205, 0, 0, 0, 34, 0, 0, 1,170, 0, 0, 1,206,
- 0, 0, 0, 34, 0, 0, 1,206, 0, 0, 1,218, 0, 0, 0, 34, 0, 0, 1,205, 0, 0, 1,207, 0, 0, 0, 34, 0, 0, 1,167,
- 0, 0, 1,207, 0, 0, 0, 34, 0, 0, 1,168, 0, 0, 1,208, 0, 0, 0, 34, 0, 0, 1,206, 0, 0, 1,208, 0, 0, 0, 34,
- 0, 0, 1,207, 0, 0, 1,209, 0, 0, 0, 34, 0, 0, 1,165, 0, 0, 1,209, 0, 0, 0, 34, 0, 0, 1,166, 0, 0, 1,210,
- 0, 0, 0, 34, 0, 0, 1,208, 0, 0, 1,210, 0, 0, 0, 34, 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 34, 0, 0, 1,163,
- 0, 0, 1,211, 0, 0, 0, 34, 0, 0, 1,164, 0, 0, 1,212, 0, 0, 0, 34, 0, 0, 1,210, 0, 0, 1,212, 0, 0, 0, 34,
- 0, 0, 1,211, 0, 0, 1,213, 0, 0, 0, 34, 0, 0, 1,161, 0, 0, 1,213, 0, 0, 0, 34, 0, 0, 1,162, 0, 0, 1,214,
- 0, 0, 0, 34, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 34, 0, 0, 1,213, 0, 0, 1,215, 0, 0, 0, 34, 0, 0, 1,214,
- 0, 0, 1,216, 0, 0, 0, 34, 0, 0, 1,197, 0, 0, 1,221, 0, 0, 0, 34, 0, 0, 1,219, 0, 0, 1,221, 0, 0, 0, 34,
- 0, 0, 1,199, 0, 0, 1,219, 0, 0, 0, 34, 0, 0, 1,198, 0, 0, 1,222, 0, 0, 0, 34, 0, 0, 1,200, 0, 0, 1,220,
- 0, 0, 0, 34, 0, 0, 1,220, 0, 0, 1,222, 0, 0, 0, 34, 0, 0, 1,221, 0, 0, 1,223, 0, 0, 0, 34, 0, 0, 1,223,
- 0, 0, 1,225, 0, 0, 0, 32, 0, 0, 1,219, 0, 0, 1,225, 0, 0, 0, 34, 0, 0, 1,222, 0, 0, 1,224, 0, 0, 0, 34,
- 0, 0, 1,220, 0, 0, 1,226, 0, 0, 0, 34, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 0, 32, 0, 0, 1,223, 0, 0, 1,229,
- 0, 0, 0, 34, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 0, 34, 0, 0, 1,225, 0, 0, 1,227, 0, 0, 0, 34, 0, 0, 1,224,
- 0, 0, 1,230, 0, 0, 0, 34, 0, 0, 1,226, 0, 0, 1,228, 0, 0, 0, 34, 0, 0, 1,228, 0, 0, 1,230, 0, 0, 0, 34,
- 0, 0, 1,229, 0, 0, 1,231, 0, 0, 0, 34, 0, 0, 1,231, 0, 0, 1,233, 0, 0, 0, 34, 0, 0, 1,227, 0, 0, 1,233,
- 0, 0, 0, 34, 0, 0, 1,230, 0, 0, 1,232, 0, 0, 0, 34, 0, 0, 1,228, 0, 0, 1,234, 0, 0, 0, 34, 0, 0, 1,232,
- 0, 0, 1,234, 0, 0, 0, 34, 0, 0, 1,217, 0, 0, 1,227, 0, 0, 0, 34, 0, 0, 1,205, 0, 0, 1,233, 0, 0, 0, 34,
- 0, 0, 1,218, 0, 0, 1,228, 0, 0, 0, 34, 0, 0, 1,206, 0, 0, 1,234, 0, 0, 0, 34, 0, 0, 1,193, 0, 0, 1,225,
- 0, 0, 0, 34, 0, 0, 1,194, 0, 0, 1,226, 0, 0, 0, 34, 0, 0, 1,203, 0, 0, 1,219, 0, 0, 0, 34, 0, 0, 1,204,
- 0, 0, 1,220, 0, 0, 0, 34, 0, 0, 1,215, 0, 0, 1,221, 0, 0, 0, 34, 0, 0, 1,216, 0, 0, 1,222, 0, 0, 0, 34,
- 0, 0, 1,213, 0, 0, 1,223, 0, 0, 0, 34, 0, 0, 1,214, 0, 0, 1,224, 0, 0, 0, 34, 0, 0, 1,211, 0, 0, 1,229,
- 0, 0, 0, 34, 0, 0, 1,212, 0, 0, 1,230, 0, 0, 0, 34, 0, 0, 1,209, 0, 0, 1,231, 0, 0, 0, 34, 0, 0, 1,210,
- 0, 0, 1,232, 0, 0, 0, 34, 0, 0, 1,207, 0, 0, 1,233, 0, 0, 0, 34, 0, 0, 1,208, 0, 0, 1,234, 0, 0, 0, 34,
- 0, 0, 1,131, 0, 0, 1,245, 0, 0, 0, 34, 0, 0, 1,243, 0, 0, 1,245, 0, 0, 0, 39, 0, 0, 1,133, 0, 0, 1,243,
- 0, 0, 0, 34, 0, 0, 1,132, 0, 0, 1,246, 0, 0, 0, 34, 0, 0, 1,134, 0, 0, 1,244, 0, 0, 0, 34, 0, 0, 1,244,
- 0, 0, 1,246, 0, 0, 0, 39, 0, 0, 1,241, 0, 0, 1,243, 0, 0, 0, 39, 0, 0, 1,135, 0, 0, 1,241, 0, 0, 0, 34,
- 0, 0, 1,136, 0, 0, 1,242, 0, 0, 0, 34, 0, 0, 1,242, 0, 0, 1,244, 0, 0, 0, 39, 0, 0, 1,239, 0, 0, 1,241,
- 0, 0, 0, 39, 0, 0, 1,137, 0, 0, 1,239, 0, 0, 0, 34, 0, 0, 1,138, 0, 0, 1,240, 0, 0, 0, 34, 0, 0, 1,240,
- 0, 0, 1,242, 0, 0, 0, 39, 0, 0, 1,237, 0, 0, 1,239, 0, 0, 0, 39, 0, 0, 1,139, 0, 0, 1,237, 0, 0, 0, 34,
- 0, 0, 1,140, 0, 0, 1,238, 0, 0, 0, 34, 0, 0, 1,238, 0, 0, 1,240, 0, 0, 0, 39, 0, 0, 1,235, 0, 0, 1,237,
- 0, 0, 0, 39, 0, 0, 1,141, 0, 0, 1,235, 0, 0, 0, 34, 0, 0, 1,142, 0, 0, 1,236, 0, 0, 0, 34, 0, 0, 1,236,
- 0, 0, 1,238, 0, 0, 0, 39, 0, 0, 1,235, 0, 0, 1,247, 0, 0, 0, 39, 0, 0, 1,129, 0, 0, 1,247, 0, 0, 0, 34,
- 0, 0, 1,130, 0, 0, 1,248, 0, 0, 0, 34, 0, 0, 1,236, 0, 0, 1,248, 0, 0, 0, 39, 0, 0, 1,235, 0, 0, 1,243,
- 0, 0, 0, 34, 0, 0, 1,245, 0, 0, 1,247, 0, 0, 0, 34, 0, 0, 1,236, 0, 0, 1,244, 0, 0, 0, 34, 0, 0, 1,246,
- 0, 0, 1,248, 0, 0, 0, 34, 0, 0, 1,237, 0, 0, 1,241, 0, 0, 0, 34, 0, 0, 1,238, 0, 0, 1,242, 0, 0, 0, 34,
- 0, 0, 1, 55, 0, 0, 1,247, 0, 0, 0, 39, 0, 0, 1, 56, 0, 0, 1,248, 0, 0, 0, 39, 0, 0, 1, 63, 0, 0, 1,245,
- 0, 0, 0, 39, 0, 0, 1, 64, 0, 0, 1,246, 0, 0, 0, 39, 0, 0, 0, 14, 0, 0, 0,249, 0, 0, 0, 34, 0, 0, 0, 14,
- 0, 0, 0,178, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0,113, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0,161, 0, 0, 0, 34,
- 0, 0, 0, 20, 0, 0, 0,112, 0, 0, 0, 34, 0, 0, 0, 16, 0, 0, 0,112, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0,112,
- 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0,112, 0, 0, 0, 34, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,207, 64, 0, 0, 0,242,
- 0, 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, 5, 31,184, 32, 0, 0, 0, 5, 0, 0, 0, 20,
- 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8,102,176, 32, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 5, 31,232, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 39, 16, 5, 31,184, 32, 0, 0, 0, 52, 0, 0, 1,244, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 44,
- 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3,
- 0, 0, 0, 44, 0, 0, 0, 42, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8,
- 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 10,
- 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0,112, 0, 0, 0, 13, 0, 0, 0, 11, 0, 0, 0, 9,
- 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0,112,
- 0, 0, 0, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 19, 0, 0, 0, 17, 0, 0, 0, 15, 0, 0, 0, 1,
- 0, 0, 0, 18, 0, 0, 0, 20, 0, 0, 0,112, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 21, 0, 0, 0, 19,
- 0, 0, 0, 14, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0,112, 0, 0, 0, 1, 0, 0, 0, 21,
- 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 1, 0, 0, 0, 26, 0, 0, 0, 24, 0, 0, 0, 22, 0, 0, 0, 20,
- 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 26,
- 0, 0, 0, 20, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 31, 0, 0, 0, 29, 0, 0, 0, 27, 0, 0, 0, 1,
- 0, 0, 0, 30, 0, 0, 0, 32, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 1, 0, 0, 0, 23, 0, 0, 0, 33, 0, 0, 0, 31,
- 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 26, 0, 0, 0, 1, 0, 0, 0, 33,
- 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 36, 0, 0, 0, 34, 0, 0, 0, 32,
- 0, 0, 0, 1, 0, 0, 0, 31, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 29, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 38,
- 0, 0, 0, 32, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 39, 0, 0, 0, 1,
- 0, 0, 0, 42, 0, 0, 0, 44, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 0, 43,
- 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 44, 0, 0, 0, 46, 0, 0, 0, 36, 0, 0, 0, 38, 0, 0, 0, 1, 0, 0, 0, 45,
- 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 0, 36, 0, 0, 0, 46, 0, 0, 0, 48,
- 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 1, 0, 0, 0, 52, 0, 0, 0, 34,
- 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 0, 23, 0, 0, 0, 53, 0, 0, 0, 51, 0, 0, 0, 1,
- 0, 0, 0, 54, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 23, 0, 0, 0, 21, 0, 0, 0, 55,
- 0, 0, 0, 53, 0, 0, 0, 1, 0, 0, 0, 56, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 0, 1, 0, 0, 0, 21,
- 0, 0, 0, 12, 0, 0, 0, 57, 0, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 13, 0, 0, 0, 22, 0, 0, 0, 56,
- 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 10, 0, 0, 0, 61, 0, 0, 0, 57, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 0, 11,
- 0, 0, 0, 13, 0, 0, 0, 58, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 61, 0, 0, 0, 1,
- 0, 0, 0, 64, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 62, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 47,
- 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 48, 0, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 1, 0, 0, 0, 59,
- 0, 0, 0, 63, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 48, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 63, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 60, 0, 0, 0, 64,
- 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 62, 0, 0, 0, 58, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 55, 0, 0, 0, 57,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 59,
- 0, 0, 0, 53, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 56, 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 0, 52,
- 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 52, 0, 0, 0, 50, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 47, 0, 0, 0, 49,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 50, 0, 0, 0, 48, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 87,
- 0, 0, 0,171, 0, 0, 0,173, 0, 0, 0, 89, 0, 0, 0, 1, 0, 0, 0,173, 0, 0, 0,172, 0, 0, 0, 88, 0, 0, 0, 89,
- 0, 0, 0, 1, 0, 0, 0, 85, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0, 87, 0, 0, 0, 1, 0, 0, 0,172, 0, 0, 0,170,
- 0, 0, 0, 86, 0, 0, 0, 88, 0, 0, 0, 1, 0, 0, 0, 83, 0, 0, 0,167, 0, 0, 0,169, 0, 0, 0, 85, 0, 0, 0, 1,
- 0, 0, 0,170, 0, 0, 0,168, 0, 0, 0, 84, 0, 0, 0, 86, 0, 0, 0, 1, 0, 0, 0, 81, 0, 0, 0,165, 0, 0, 0,167,
- 0, 0, 0, 83, 0, 0, 0, 1, 0, 0, 0,168, 0, 0, 0,166, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 79,
- 0, 0, 0,163, 0, 0, 0,165, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0,166, 0, 0, 0,164, 0, 0, 0, 80, 0, 0, 0, 82,
- 0, 0, 0, 1, 0, 0, 0, 77, 0, 0, 0, 90, 0, 0, 0,143, 0, 0, 0,161, 0, 0, 0, 1, 0, 0, 0,144, 0, 0, 0, 91,
- 0, 0, 0, 78, 0, 0, 0,162, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 92, 0, 0, 0,145, 0, 0, 0,143, 0, 0, 0, 1,
- 0, 0, 0,146, 0, 0, 0, 93, 0, 0, 0, 91, 0, 0, 0,144, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0,147,
- 0, 0, 0,145, 0, 0, 0, 1, 0, 0, 0,148, 0, 0, 0, 95, 0, 0, 0, 93, 0, 0, 0,146, 0, 0, 0, 1, 0, 0, 0, 94,
- 0, 0, 0, 96, 0, 0, 0,149, 0, 0, 0,147, 0, 0, 0, 1, 0, 0, 0,150, 0, 0, 0, 97, 0, 0, 0, 95, 0, 0, 0,148,
- 0, 0, 0, 1, 0, 0, 0, 96, 0, 0, 0, 98, 0, 0, 0,151, 0, 0, 0,149, 0, 0, 0, 1, 0, 0, 0,152, 0, 0, 0, 99,
- 0, 0, 0, 97, 0, 0, 0,150, 0, 0, 0, 1, 0, 0, 0, 98, 0, 0, 0,100, 0, 0, 0,153, 0, 0, 0,151, 0, 0, 0, 1,
- 0, 0, 0,154, 0, 0, 0,101, 0, 0, 0, 99, 0, 0, 0,152, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0,102, 0, 0, 0,155,
- 0, 0, 0,153, 0, 0, 0, 1, 0, 0, 0,156, 0, 0, 0,103, 0, 0, 0,101, 0, 0, 0,154, 0, 0, 0, 1, 0, 0, 0,102,
- 0, 0, 0,104, 0, 0, 0,157, 0, 0, 0,155, 0, 0, 0, 1, 0, 0, 0,158, 0, 0, 0,105, 0, 0, 0,103, 0, 0, 0,156,
- 0, 0, 0, 1, 0, 0, 0,104, 0, 0, 0,106, 0, 0, 0,159, 0, 0, 0,157, 0, 0, 0, 1, 0, 0, 0,160, 0, 0, 0,107,
- 0, 0, 0,105, 0, 0, 0,158, 0, 0, 0, 1, 0, 0, 0,106, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0,159, 0, 0, 0, 1,
- 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0,107, 0, 0, 0,160, 0, 0, 0, 1, 0, 0, 0,108, 0, 0, 0,125, 0, 0, 0,157,
- 0, 0, 0,159, 0, 0, 0, 1, 0, 0, 0,158, 0, 0, 0,126, 0, 0, 0,109, 0, 0, 0,160, 0, 0, 0, 1, 0, 0, 0,125,
- 0, 0, 0,176, 0, 0, 0,155, 0, 0, 0,157, 0, 0, 0, 1, 0, 0, 0,156, 0, 0, 0,177, 0, 0, 0,126, 0, 0, 0,158,
- 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,153, 0, 0, 0,155, 0, 0, 0,176, 0, 0, 0, 1, 0, 0, 0,156, 0, 0, 0,154,
- 0, 0, 0,124, 0, 0, 0,177, 0, 0, 0, 1, 0, 0, 0,121, 0, 0, 0,151, 0, 0, 0,153, 0, 0, 0,123, 0, 0, 0, 1,
- 0, 0, 0,154, 0, 0, 0,152, 0, 0, 0,122, 0, 0, 0,124, 0, 0, 0, 1, 0, 0, 0,119, 0, 0, 0,149, 0, 0, 0,151,
- 0, 0, 0,121, 0, 0, 0, 1, 0, 0, 0,152, 0, 0, 0,150, 0, 0, 0,120, 0, 0, 0,122, 0, 0, 0, 1, 0, 0, 0,117,
- 0, 0, 0,147, 0, 0, 0,149, 0, 0, 0,119, 0, 0, 0, 1, 0, 0, 0,150, 0, 0, 0,148, 0, 0, 0,118, 0, 0, 0,120,
- 0, 0, 0, 1, 0, 0, 0,115, 0, 0, 0,145, 0, 0, 0,147, 0, 0, 0,117, 0, 0, 0, 1, 0, 0, 0,148, 0, 0, 0,146,
- 0, 0, 0,116, 0, 0, 0,118, 0, 0, 0, 1, 0, 0, 0,113, 0, 0, 0,143, 0, 0, 0,145, 0, 0, 0,115, 0, 0, 0, 1,
- 0, 0, 0,146, 0, 0, 0,144, 0, 0, 0,114, 0, 0, 0,116, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0,161, 0, 0, 0,143,
- 0, 0, 0,113, 0, 0, 0, 1, 0, 0, 0,144, 0, 0, 0,162, 0, 0, 0,112, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 14,
- 0, 0, 0,178, 0, 0, 0,174, 0, 0, 0,161, 0, 0, 0, 1, 0, 0, 0,174, 0, 0, 0,179, 0, 0, 0,112, 0, 0, 0,162,
- 0, 0, 0, 1, 0, 0, 0,108, 0, 0, 0,159, 0, 0, 0, 66, 0, 0, 0,110, 0, 0, 0, 1, 0, 0, 0, 66, 0, 0, 0,160,
- 0, 0, 0,109, 0, 0, 0,111, 0, 0, 0, 1, 0, 0, 0,110, 0, 0, 0, 66, 0, 0, 0,175, 0, 0, 0,180, 0, 0, 0, 1,
- 0, 0, 0,175, 0, 0, 0, 66, 0, 0, 0,111, 0, 0, 0,181, 0, 0, 0, 1, 0, 0, 0,174, 0, 0, 0,178, 0, 0, 0,180,
- 0, 0, 0,175, 0, 0, 0, 1, 0, 0, 0,181, 0, 0, 0,179, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0, 1, 0, 0, 0,132,
- 0, 0, 0,134, 0, 0, 0,173, 0, 0, 0,171, 0, 0, 0, 1, 0, 0, 0,173, 0, 0, 0,134, 0, 0, 0,133, 0, 0, 0,172,
- 0, 0, 0, 1, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0,171, 0, 0, 0,169, 0, 0, 0, 1, 0, 0, 0,172, 0, 0, 0,133,
- 0, 0, 0,131, 0, 0, 0,170, 0, 0, 0, 1, 0, 0, 0,128, 0, 0, 0,130, 0, 0, 0,169, 0, 0, 0,167, 0, 0, 0, 1,
- 0, 0, 0,170, 0, 0, 0,131, 0, 0, 0,129, 0, 0, 0,168, 0, 0, 0, 1, 0, 0, 0,163, 0, 0, 0,184, 0, 0, 0,182,
- 0, 0, 0,165, 0, 0, 0, 1, 0, 0, 0,183, 0, 0, 0,185, 0, 0, 0,164, 0, 0, 0,166, 0, 0, 0, 1, 0, 0, 0,128,
- 0, 0, 0,167, 0, 0, 0,165, 0, 0, 0,182, 0, 0, 0, 1, 0, 0, 0,166, 0, 0, 0,168, 0, 0, 0,129, 0, 0, 0,183,
- 0, 0, 0, 1, 0, 0, 0,141, 0, 0, 0,187, 0, 0, 0,186, 0, 0, 0,184, 0, 0, 0, 1, 0, 0, 0,186, 0, 0, 0,187,
- 0, 0, 0,142, 0, 0, 0,185, 0, 0, 0, 1, 0, 0, 0,182, 0, 0, 0,184, 0, 0, 0,186, 0, 0, 0, 67, 0, 0, 0, 1,
- 0, 0, 0,186, 0, 0, 0,185, 0, 0, 0,183, 0, 0, 0, 67, 0, 0, 0, 1, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0,182,
- 0, 0, 0, 67, 0, 0, 0, 1, 0, 0, 0,183, 0, 0, 0,129, 0, 0, 0,127, 0, 0, 0, 67, 0, 0, 0, 1, 0, 0, 0,139,
- 0, 0, 0,190, 0, 0, 0,188, 0, 0, 0,141, 0, 0, 0, 1, 0, 0, 0,189, 0, 0, 0,191, 0, 0, 0,140, 0, 0, 0,142,
- 0, 0, 0, 1, 0, 0, 0,137, 0, 0, 0,192, 0, 0, 0,190, 0, 0, 0,139, 0, 0, 0, 1, 0, 0, 0,191, 0, 0, 0,193,
- 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0, 1, 0, 0, 0,136, 0, 0, 0,194, 0, 0, 0,192, 0, 0, 0,137, 0, 0, 0, 1,
- 0, 0, 0,193, 0, 0, 0,195, 0, 0, 0,136, 0, 0, 0,138, 0, 0, 0, 1, 0, 0, 0,135, 0, 0, 0, 69, 0, 0, 0,194,
- 0, 0, 0,136, 0, 0, 0, 1, 0, 0, 0,195, 0, 0, 0, 69, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0, 1, 0, 0, 0,187,
- 0, 0, 0,141, 0, 0, 0,188, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0,189, 0, 0, 0,142, 0, 0, 0,187, 0, 0, 0, 68,
- 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0,188, 0, 0, 0,203, 0, 0, 0,205, 0, 0, 0, 1, 0, 0, 0,204, 0, 0, 0,189,
- 0, 0, 0, 68, 0, 0, 0,205, 0, 0, 0, 1, 0, 0, 0, 69, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0,194, 0, 0, 0, 1,
- 0, 0, 0,198, 0, 0, 0,196, 0, 0, 0, 69, 0, 0, 0,195, 0, 0, 0, 1, 0, 0, 0,194, 0, 0, 0,197, 0, 0, 0,199,
- 0, 0, 0,192, 0, 0, 0, 1, 0, 0, 0,200, 0, 0, 0,198, 0, 0, 0,195, 0, 0, 0,193, 0, 0, 0, 1, 0, 0, 0,192,
- 0, 0, 0,199, 0, 0, 0,201, 0, 0, 0,190, 0, 0, 0, 1, 0, 0, 0,202, 0, 0, 0,200, 0, 0, 0,193, 0, 0, 0,191,
- 0, 0, 0, 1, 0, 0, 0,190, 0, 0, 0,201, 0, 0, 0,203, 0, 0, 0,188, 0, 0, 0, 1, 0, 0, 0,204, 0, 0, 0,202,
- 0, 0, 0,191, 0, 0, 0,189, 0, 0, 0, 1, 0, 0, 0,196, 0, 0, 0,201, 0, 0, 0,199, 0, 0, 0,197, 0, 0, 0, 1,
- 0, 0, 0,200, 0, 0, 0,202, 0, 0, 0,196, 0, 0, 0,198, 0, 0, 0, 1, 0, 0, 0,196, 0, 0, 0,205, 0, 0, 0,203,
- 0, 0, 0,201, 0, 0, 0, 1, 0, 0, 0,204, 0, 0, 0,205, 0, 0, 0,196, 0, 0, 0,202, 0, 0, 0, 1, 0, 0, 0,136,
- 0, 0, 0,137, 0, 0, 0,161, 0, 0, 0,174, 0, 0, 0, 1, 0, 0, 0,162, 0, 0, 0,138, 0, 0, 0,136, 0, 0, 0,174,
- 0, 0, 0, 1, 0, 0, 0,137, 0, 0, 0,139, 0, 0, 0,208, 0, 0, 0,161, 0, 0, 0, 1, 0, 0, 0,209, 0, 0, 0,140,
- 0, 0, 0,138, 0, 0, 0,162, 0, 0, 0, 1, 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0,210, 0, 0, 0,208, 0, 0, 0, 1,
- 0, 0, 0,211, 0, 0, 0,142, 0, 0, 0,140, 0, 0, 0,209, 0, 0, 0, 1, 0, 0, 0,141, 0, 0, 0,184, 0, 0, 0,163,
- 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,164, 0, 0, 0,185, 0, 0, 0,142, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 79,
- 0, 0, 0,206, 0, 0, 0,210, 0, 0, 0,163, 0, 0, 0, 1, 0, 0, 0,211, 0, 0, 0,207, 0, 0, 0, 80, 0, 0, 0,164,
- 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 0,212, 0, 0, 0,208, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,209, 0, 0, 0,213,
- 0, 0, 0,207, 0, 0, 0,211, 0, 0, 0, 1, 0, 0, 0, 77, 0, 0, 0,161, 0, 0, 0,208, 0, 0, 0,212, 0, 0, 0, 1,
- 0, 0, 0,209, 0, 0, 0,162, 0, 0, 0, 78, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0,128, 0, 0, 0,127, 0, 0, 0, 70,
- 0, 0, 0,219, 0, 0, 0, 1, 0, 0, 0, 70, 0, 0, 0,127, 0, 0, 0,129, 0, 0, 0,220, 0, 0, 0, 1, 0, 0, 0,130,
- 0, 0, 0,128, 0, 0, 0,219, 0, 0, 0,217, 0, 0, 0, 1, 0, 0, 0,220, 0, 0, 0,129, 0, 0, 0,131, 0, 0, 0,218,
- 0, 0, 0, 1, 0, 0, 0,132, 0, 0, 0,130, 0, 0, 0,217, 0, 0, 0,215, 0, 0, 0, 1, 0, 0, 0,218, 0, 0, 0,131,
- 0, 0, 0,133, 0, 0, 0,216, 0, 0, 0, 1, 0, 0, 0,134, 0, 0, 0,132, 0, 0, 0,215, 0, 0, 0,214, 0, 0, 0, 1,
- 0, 0, 0,216, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,214, 0, 0, 0, 1, 0, 0, 0,214, 0, 0, 0,215, 0, 0, 0,226,
- 0, 0, 0,228, 0, 0, 0, 1, 0, 0, 0,227, 0, 0, 0,216, 0, 0, 0,214, 0, 0, 0,228, 0, 0, 0, 1, 0, 0, 0,215,
- 0, 0, 0,217, 0, 0, 0,224, 0, 0, 0,226, 0, 0, 0, 1, 0, 0, 0,225, 0, 0, 0,218, 0, 0, 0,216, 0, 0, 0,227,
- 0, 0, 0, 1, 0, 0, 0,217, 0, 0, 0,219, 0, 0, 0,222, 0, 0, 0,224, 0, 0, 0, 1, 0, 0, 0,223, 0, 0, 0,220,
- 0, 0, 0,218, 0, 0, 0,225, 0, 0, 0, 1, 0, 0, 0,219, 0, 0, 0, 70, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0, 1,
- 0, 0, 0,221, 0, 0, 0, 70, 0, 0, 0,220, 0, 0, 0,223, 0, 0, 0, 1, 0, 0, 0,221, 0, 0, 0,228, 0, 0, 0,226,
- 0, 0, 0,222, 0, 0, 0, 1, 0, 0, 0,227, 0, 0, 0,228, 0, 0, 0,221, 0, 0, 0,223, 0, 0, 0, 1, 0, 0, 0,222,
- 0, 0, 0,226, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,225, 0, 0, 0,227, 0, 0, 0,223, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,180, 0, 0, 0,178, 0, 0, 0,231, 0, 0, 0,229, 0, 0, 0, 1, 0, 0, 0,232, 0, 0, 0,179,
- 0, 0, 0,181, 0, 0, 0,230, 0, 0, 0, 1, 0, 0, 0,110, 0, 0, 0,180, 0, 0, 0,229, 0, 0, 0,251, 0, 0, 0, 1,
- 0, 0, 0,230, 0, 0, 0,181, 0, 0, 0,111, 0, 0, 0,252, 0, 0, 0, 1, 0, 0, 0,108, 0, 0, 0,110, 0, 0, 0,251,
- 0, 0, 0,253, 0, 0, 0, 1, 0, 0, 0,252, 0, 0, 0,111, 0, 0, 0,109, 0, 0, 0,254, 0, 0, 0, 1, 0, 0, 0,178,
- 0, 0, 0, 14, 0, 0, 0,249, 0, 0, 0,231, 0, 0, 0, 1, 0, 0, 0,250, 0, 0, 0,112, 0, 0, 0,179, 0, 0, 0,232,
- 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0,113, 0, 0, 0,247, 0, 0, 0,249, 0, 0, 0, 1, 0, 0, 0,248, 0, 0, 0,114,
- 0, 0, 0,112, 0, 0, 0,250, 0, 0, 0, 1, 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0,245, 0, 0, 0,247, 0, 0, 0, 1,
- 0, 0, 0,246, 0, 0, 0,116, 0, 0, 0,114, 0, 0, 0,248, 0, 0, 0, 1, 0, 0, 0,115, 0, 0, 0,117, 0, 0, 0,243,
- 0, 0, 0,245, 0, 0, 0, 1, 0, 0, 0,244, 0, 0, 0,118, 0, 0, 0,116, 0, 0, 0,246, 0, 0, 0, 1, 0, 0, 0,117,
- 0, 0, 0,119, 0, 0, 0,241, 0, 0, 0,243, 0, 0, 0, 1, 0, 0, 0,242, 0, 0, 0,120, 0, 0, 0,118, 0, 0, 0,244,
- 0, 0, 0, 1, 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0,239, 0, 0, 0,241, 0, 0, 0, 1, 0, 0, 0,240, 0, 0, 0,122,
- 0, 0, 0,120, 0, 0, 0,242, 0, 0, 0, 1, 0, 0, 0,121, 0, 0, 0,123, 0, 0, 0,237, 0, 0, 0,239, 0, 0, 0, 1,
- 0, 0, 0,238, 0, 0, 0,124, 0, 0, 0,122, 0, 0, 0,240, 0, 0, 0, 1, 0, 0, 0,123, 0, 0, 0,176, 0, 0, 0,233,
- 0, 0, 0,237, 0, 0, 0, 1, 0, 0, 0,234, 0, 0, 0,177, 0, 0, 0,124, 0, 0, 0,238, 0, 0, 0, 1, 0, 0, 0,176,
- 0, 0, 0,125, 0, 0, 0,235, 0, 0, 0,233, 0, 0, 0, 1, 0, 0, 0,236, 0, 0, 0,126, 0, 0, 0,177, 0, 0, 0,234,
- 0, 0, 0, 1, 0, 0, 0,125, 0, 0, 0,108, 0, 0, 0,253, 0, 0, 0,235, 0, 0, 0, 1, 0, 0, 0,254, 0, 0, 0,109,
- 0, 0, 0,126, 0, 0, 0,236, 0, 0, 0, 1, 0, 0, 0,235, 0, 0, 0,253, 0, 0, 0,255, 0, 0, 1, 17, 0, 0, 0, 1,
- 0, 0, 1, 0, 0, 0, 0,254, 0, 0, 0,236, 0, 0, 1, 18, 0, 0, 0, 1, 0, 0, 0,233, 0, 0, 0,235, 0, 0, 1, 17,
- 0, 0, 1, 19, 0, 0, 0, 1, 0, 0, 1, 18, 0, 0, 0,236, 0, 0, 0,234, 0, 0, 1, 20, 0, 0, 0, 1, 0, 0, 0,237,
- 0, 0, 0,233, 0, 0, 1, 19, 0, 0, 1, 15, 0, 0, 0, 1, 0, 0, 1, 20, 0, 0, 0,234, 0, 0, 0,238, 0, 0, 1, 16,
- 0, 0, 0, 1, 0, 0, 0,239, 0, 0, 0,237, 0, 0, 1, 15, 0, 0, 1, 13, 0, 0, 0, 1, 0, 0, 1, 16, 0, 0, 0,238,
- 0, 0, 0,240, 0, 0, 1, 14, 0, 0, 0, 1, 0, 0, 0,241, 0, 0, 0,239, 0, 0, 1, 13, 0, 0, 1, 11, 0, 0, 0, 1,
- 0, 0, 1, 14, 0, 0, 0,240, 0, 0, 0,242, 0, 0, 1, 12, 0, 0, 0, 1, 0, 0, 0,243, 0, 0, 0,241, 0, 0, 1, 11,
- 0, 0, 1, 9, 0, 0, 0, 1, 0, 0, 1, 12, 0, 0, 0,242, 0, 0, 0,244, 0, 0, 1, 10, 0, 0, 0, 1, 0, 0, 0,245,
- 0, 0, 0,243, 0, 0, 1, 9, 0, 0, 1, 7, 0, 0, 0, 1, 0, 0, 1, 10, 0, 0, 0,244, 0, 0, 0,246, 0, 0, 1, 8,
- 0, 0, 0, 1, 0, 0, 0,247, 0, 0, 0,245, 0, 0, 1, 7, 0, 0, 1, 5, 0, 0, 0, 1, 0, 0, 1, 8, 0, 0, 0,246,
- 0, 0, 0,248, 0, 0, 1, 6, 0, 0, 0, 1, 0, 0, 0,249, 0, 0, 0,247, 0, 0, 1, 5, 0, 0, 1, 3, 0, 0, 0, 1,
- 0, 0, 1, 6, 0, 0, 0,248, 0, 0, 0,250, 0, 0, 1, 4, 0, 0, 0, 1, 0, 0, 0,231, 0, 0, 0,249, 0, 0, 1, 3,
- 0, 0, 1, 21, 0, 0, 0, 1, 0, 0, 1, 4, 0, 0, 0,250, 0, 0, 0,232, 0, 0, 1, 22, 0, 0, 0, 1, 0, 0, 0,253,
- 0, 0, 0,251, 0, 0, 1, 1, 0, 0, 0,255, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 0,252, 0, 0, 0,254, 0, 0, 1, 0,
- 0, 0, 0, 1, 0, 0, 0,251, 0, 0, 0,229, 0, 0, 1, 23, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 24, 0, 0, 0,230,
- 0, 0, 0,252, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0,229, 0, 0, 0,231, 0, 0, 1, 21, 0, 0, 1, 23, 0, 0, 0, 1,
- 0, 0, 1, 22, 0, 0, 0,232, 0, 0, 0,230, 0, 0, 1, 24, 0, 0, 0, 1, 0, 0, 0, 65, 0, 0, 0,106, 0, 0, 1, 25,
- 0, 0, 0, 71, 0, 0, 0, 1, 0, 0, 1, 26, 0, 0, 0,107, 0, 0, 0, 65, 0, 0, 0, 71, 0, 0, 0, 1, 0, 0, 0,106,
- 0, 0, 0,104, 0, 0, 1, 27, 0, 0, 1, 25, 0, 0, 0, 1, 0, 0, 1, 28, 0, 0, 0,105, 0, 0, 0,107, 0, 0, 1, 26,
- 0, 0, 0, 1, 0, 0, 0,104, 0, 0, 0,102, 0, 0, 1, 29, 0, 0, 1, 27, 0, 0, 0, 1, 0, 0, 1, 30, 0, 0, 0,103,
- 0, 0, 0,105, 0, 0, 1, 28, 0, 0, 0, 1, 0, 0, 0,102, 0, 0, 0,100, 0, 0, 1, 31, 0, 0, 1, 29, 0, 0, 0, 1,
- 0, 0, 1, 32, 0, 0, 0,101, 0, 0, 0,103, 0, 0, 1, 30, 0, 0, 0, 1, 0, 0, 0,100, 0, 0, 0, 98, 0, 0, 1, 33,
- 0, 0, 1, 31, 0, 0, 0, 1, 0, 0, 1, 34, 0, 0, 0, 99, 0, 0, 0,101, 0, 0, 1, 32, 0, 0, 0, 1, 0, 0, 0, 98,
- 0, 0, 0, 96, 0, 0, 1, 35, 0, 0, 1, 33, 0, 0, 0, 1, 0, 0, 1, 36, 0, 0, 0, 97, 0, 0, 0, 99, 0, 0, 1, 34,
- 0, 0, 0, 1, 0, 0, 0, 96, 0, 0, 0, 94, 0, 0, 1, 37, 0, 0, 1, 35, 0, 0, 0, 1, 0, 0, 1, 38, 0, 0, 0, 95,
- 0, 0, 0, 97, 0, 0, 1, 36, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 92, 0, 0, 1, 39, 0, 0, 1, 37, 0, 0, 0, 1,
- 0, 0, 1, 40, 0, 0, 0, 93, 0, 0, 0, 95, 0, 0, 1, 38, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 90, 0, 0, 1, 41,
- 0, 0, 1, 39, 0, 0, 0, 1, 0, 0, 1, 42, 0, 0, 0, 91, 0, 0, 0, 93, 0, 0, 1, 40, 0, 0, 0, 1, 0, 0, 1, 49,
- 0, 0, 1, 50, 0, 0, 1, 69, 0, 0, 1, 79, 0, 0, 0, 1, 0, 0, 1, 70, 0, 0, 1, 50, 0, 0, 1, 49, 0, 0, 1, 80,
- 0, 0, 0, 1, 0, 0, 1, 48, 0, 0, 1, 49, 0, 0, 1, 79, 0, 0, 1, 77, 0, 0, 0, 1, 0, 0, 1, 80, 0, 0, 1, 49,
- 0, 0, 1, 48, 0, 0, 1, 78, 0, 0, 0, 1, 0, 0, 1, 47, 0, 0, 1, 48, 0, 0, 1, 77, 0, 0, 1, 81, 0, 0, 0, 1,
- 0, 0, 1, 78, 0, 0, 1, 48, 0, 0, 1, 47, 0, 0, 1, 82, 0, 0, 0, 1, 0, 0, 0, 87, 0, 0, 0, 89, 0, 0, 1, 47,
- 0, 0, 1, 81, 0, 0, 0, 1, 0, 0, 1, 47, 0, 0, 0, 89, 0, 0, 0, 88, 0, 0, 1, 82, 0, 0, 0, 1, 0, 0, 0, 85,
- 0, 0, 0, 87, 0, 0, 1, 81, 0, 0, 1, 75, 0, 0, 0, 1, 0, 0, 1, 82, 0, 0, 0, 88, 0, 0, 0, 86, 0, 0, 1, 76,
- 0, 0, 0, 1, 0, 0, 0, 83, 0, 0, 0, 85, 0, 0, 1, 75, 0, 0, 1, 71, 0, 0, 0, 1, 0, 0, 1, 76, 0, 0, 0, 86,
- 0, 0, 0, 84, 0, 0, 1, 72, 0, 0, 0, 1, 0, 0, 0, 81, 0, 0, 0, 83, 0, 0, 1, 71, 0, 0, 1, 73, 0, 0, 0, 1,
- 0, 0, 1, 72, 0, 0, 0, 84, 0, 0, 0, 82, 0, 0, 1, 74, 0, 0, 0, 1, 0, 0, 1, 71, 0, 0, 1, 77, 0, 0, 1, 79,
- 0, 0, 1, 73, 0, 0, 0, 1, 0, 0, 1, 80, 0, 0, 1, 78, 0, 0, 1, 72, 0, 0, 1, 74, 0, 0, 0, 1, 0, 0, 1, 71,
- 0, 0, 1, 75, 0, 0, 1, 81, 0, 0, 1, 77, 0, 0, 0, 1, 0, 0, 1, 82, 0, 0, 1, 76, 0, 0, 1, 72, 0, 0, 1, 78,
- 0, 0, 0, 1, 0, 0, 1, 67, 0, 0, 1, 73, 0, 0, 1, 79, 0, 0, 1, 69, 0, 0, 0, 1, 0, 0, 1, 80, 0, 0, 1, 74,
- 0, 0, 1, 68, 0, 0, 1, 70, 0, 0, 0, 1, 0, 0, 0, 79, 0, 0, 0, 81, 0, 0, 1, 73, 0, 0, 1, 67, 0, 0, 0, 1,
- 0, 0, 1, 74, 0, 0, 0, 82, 0, 0, 0, 80, 0, 0, 1, 68, 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 1, 83, 0, 0, 1, 85,
- 0, 0, 0,212, 0, 0, 0, 1, 0, 0, 1, 86, 0, 0, 1, 84, 0, 0, 0,207, 0, 0, 0,213, 0, 0, 0, 1, 0, 0, 0, 79,
- 0, 0, 1, 67, 0, 0, 1, 83, 0, 0, 0,206, 0, 0, 0, 1, 0, 0, 1, 84, 0, 0, 1, 68, 0, 0, 0, 80, 0, 0, 0,207,
- 0, 0, 0, 1, 0, 0, 0, 77, 0, 0, 0,212, 0, 0, 1, 85, 0, 0, 1, 87, 0, 0, 0, 1, 0, 0, 1, 86, 0, 0, 0,213,
- 0, 0, 0, 78, 0, 0, 1, 88, 0, 0, 0, 1, 0, 0, 0, 77, 0, 0, 1, 87, 0, 0, 1, 41, 0, 0, 0, 90, 0, 0, 0, 1,
- 0, 0, 1, 42, 0, 0, 1, 88, 0, 0, 0, 78, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 75, 0, 0, 1, 65, 0, 0, 1, 93,
- 0, 0, 1, 45, 0, 0, 0, 1, 0, 0, 1, 94, 0, 0, 1, 66, 0, 0, 0, 75, 0, 0, 1, 45, 0, 0, 0, 1, 0, 0, 1, 45,
- 0, 0, 1, 93, 0, 0, 1, 91, 0, 0, 0, 76, 0, 0, 0, 1, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 1, 45, 0, 0, 0, 76,
- 0, 0, 0, 1, 0, 0, 0, 76, 0, 0, 1, 91, 0, 0, 1, 89, 0, 0, 1, 46, 0, 0, 0, 1, 0, 0, 1, 90, 0, 0, 1, 92,
- 0, 0, 0, 76, 0, 0, 1, 46, 0, 0, 0, 1, 0, 0, 1, 46, 0, 0, 1, 89, 0, 0, 1, 69, 0, 0, 1, 50, 0, 0, 0, 1,
- 0, 0, 1, 70, 0, 0, 1, 90, 0, 0, 1, 46, 0, 0, 1, 50, 0, 0, 0, 1, 0, 0, 1, 67, 0, 0, 1, 69, 0, 0, 1, 89,
- 0, 0, 1, 83, 0, 0, 0, 1, 0, 0, 1, 90, 0, 0, 1, 70, 0, 0, 1, 68, 0, 0, 1, 84, 0, 0, 0, 1, 0, 0, 1, 37,
- 0, 0, 1, 39, 0, 0, 1, 59, 0, 0, 1, 51, 0, 0, 0, 1, 0, 0, 1, 60, 0, 0, 1, 40, 0, 0, 1, 38, 0, 0, 1, 52,
- 0, 0, 0, 1, 0, 0, 0, 74, 0, 0, 1, 57, 0, 0, 1, 65, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 1, 66, 0, 0, 1, 58,
- 0, 0, 0, 74, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 1, 43, 0, 0, 1, 99, 0, 0, 1, 97, 0, 0, 1, 44, 0, 0, 0, 1,
- 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 1, 43, 0, 0, 1, 44, 0, 0, 0, 1, 0, 0, 1, 44, 0, 0, 1, 97, 0, 0, 1, 95,
- 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 1, 96, 0, 0, 1, 98, 0, 0, 1, 44, 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 0, 73,
- 0, 0, 1, 95, 0, 0, 1, 57, 0, 0, 0, 74, 0, 0, 0, 1, 0, 0, 1, 58, 0, 0, 1, 96, 0, 0, 0, 73, 0, 0, 0, 74,
- 0, 0, 0, 1, 0, 0, 1, 33, 0, 0, 1, 35, 0, 0, 1,103, 0, 0, 1,105, 0, 0, 0, 1, 0, 0, 1,104, 0, 0, 1, 36,
- 0, 0, 1, 34, 0, 0, 1,106, 0, 0, 0, 1, 0, 0, 1,105, 0, 0, 1,103, 0, 0, 1,109, 0, 0, 1,107, 0, 0, 0, 1,
- 0, 0, 1,110, 0, 0, 1,104, 0, 0, 1,106, 0, 0, 1,108, 0, 0, 0, 1, 0, 0, 1,107, 0, 0, 1,109, 0, 0, 1,111,
- 0, 0, 1,113, 0, 0, 0, 1, 0, 0, 1,112, 0, 0, 1,110, 0, 0, 1,108, 0, 0, 1,114, 0, 0, 0, 1, 0, 0, 1,113,
- 0, 0, 1,111, 0, 0, 1,117, 0, 0, 1,115, 0, 0, 0, 1, 0, 0, 1,118, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 1,116,
- 0, 0, 0, 1, 0, 0, 1, 55, 0, 0, 1,119, 0, 0, 1,115, 0, 0, 1,117, 0, 0, 0, 1, 0, 0, 1,116, 0, 0, 1,120,
- 0, 0, 1, 56, 0, 0, 1,118, 0, 0, 0, 1, 0, 0, 1, 57, 0, 0, 1, 95, 0, 0, 1,115, 0, 0, 1,119, 0, 0, 0, 1,
- 0, 0, 1,116, 0, 0, 1, 96, 0, 0, 1, 58, 0, 0, 1,120, 0, 0, 0, 1, 0, 0, 1, 95, 0, 0, 1, 97, 0, 0, 1,113,
- 0, 0, 1,115, 0, 0, 0, 1, 0, 0, 1,114, 0, 0, 1, 98, 0, 0, 1, 96, 0, 0, 1,116, 0, 0, 0, 1, 0, 0, 1, 97,
- 0, 0, 1, 99, 0, 0, 1,107, 0, 0, 1,113, 0, 0, 0, 1, 0, 0, 1,108, 0, 0, 1,100, 0, 0, 1, 98, 0, 0, 1,114,
- 0, 0, 0, 1, 0, 0, 1, 99, 0, 0, 1,101, 0, 0, 1,105, 0, 0, 1,107, 0, 0, 0, 1, 0, 0, 1,106, 0, 0, 1,102,
- 0, 0, 1,100, 0, 0, 1,108, 0, 0, 0, 1, 0, 0, 1, 31, 0, 0, 1, 33, 0, 0, 1,105, 0, 0, 1,101, 0, 0, 0, 1,
- 0, 0, 1,106, 0, 0, 1, 34, 0, 0, 1, 32, 0, 0, 1,102, 0, 0, 0, 1, 0, 0, 0, 72, 0, 0, 1,101, 0, 0, 1, 99,
- 0, 0, 1, 43, 0, 0, 0, 1, 0, 0, 1,100, 0, 0, 1,102, 0, 0, 0, 72, 0, 0, 1, 43, 0, 0, 0, 1, 0, 0, 1, 25,
- 0, 0, 1, 27, 0, 0, 1, 29, 0, 0, 1, 31, 0, 0, 0, 1, 0, 0, 1, 30, 0, 0, 1, 28, 0, 0, 1, 26, 0, 0, 1, 32,
- 0, 0, 0, 1, 0, 0, 1, 25, 0, 0, 1, 31, 0, 0, 1,101, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 1,102, 0, 0, 1, 32,
- 0, 0, 1, 26, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 0, 71, 0, 0, 1, 25, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 72, 0, 0, 1, 26, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 35, 0, 0, 1, 37, 0, 0, 1, 51,
- 0, 0, 1,103, 0, 0, 0, 1, 0, 0, 1, 52, 0, 0, 1, 38, 0, 0, 1, 36, 0, 0, 1,104, 0, 0, 0, 1, 0, 0, 1, 51,
- 0, 0, 1, 53, 0, 0, 1,109, 0, 0, 1,103, 0, 0, 0, 1, 0, 0, 1,110, 0, 0, 1, 54, 0, 0, 1, 52, 0, 0, 1,104,
- 0, 0, 0, 1, 0, 0, 1, 53, 0, 0, 1,123, 0, 0, 1,111, 0, 0, 1,109, 0, 0, 0, 1, 0, 0, 1,112, 0, 0, 1,124,
- 0, 0, 1, 54, 0, 0, 1,110, 0, 0, 0, 1, 0, 0, 1, 55, 0, 0, 1,117, 0, 0, 1,111, 0, 0, 1,123, 0, 0, 0, 1,
- 0, 0, 1,112, 0, 0, 1,118, 0, 0, 1, 56, 0, 0, 1,124, 0, 0, 0, 1, 0, 0, 1, 89, 0, 0, 1, 91, 0, 0, 1,127,
- 0, 0, 1,125, 0, 0, 0, 1, 0, 0, 1,128, 0, 0, 1, 92, 0, 0, 1, 90, 0, 0, 1,126, 0, 0, 0, 1, 0, 0, 1, 59,
- 0, 0, 1,125, 0, 0, 1,127, 0, 0, 1, 61, 0, 0, 0, 1, 0, 0, 1,128, 0, 0, 1,126, 0, 0, 1, 60, 0, 0, 1, 62,
- 0, 0, 0, 1, 0, 0, 1, 39, 0, 0, 1, 41, 0, 0, 1,125, 0, 0, 1, 59, 0, 0, 0, 1, 0, 0, 1,126, 0, 0, 1, 42,
- 0, 0, 1, 40, 0, 0, 1, 60, 0, 0, 0, 1, 0, 0, 1, 41, 0, 0, 1, 85, 0, 0, 1, 83, 0, 0, 1,125, 0, 0, 0, 1,
- 0, 0, 1, 84, 0, 0, 1, 86, 0, 0, 1, 42, 0, 0, 1,126, 0, 0, 0, 1, 0, 0, 1, 83, 0, 0, 1, 89, 0, 0, 1,125,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,126, 0, 0, 1, 90, 0, 0, 1, 84, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 41,
- 0, 0, 1, 87, 0, 0, 1, 85, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 86, 0, 0, 1, 88, 0, 0, 1, 42, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 1, 55, 0, 0, 1, 63, 0, 0, 1,121, 0, 0, 1,119, 0, 0, 0, 1, 0, 0, 1,122, 0, 0, 1, 64,
- 0, 0, 1, 56, 0, 0, 1,120, 0, 0, 0, 1, 0, 0, 1, 57, 0, 0, 1,119, 0, 0, 1,121, 0, 0, 1, 65, 0, 0, 0, 1,
- 0, 0, 1,122, 0, 0, 1,120, 0, 0, 1, 58, 0, 0, 1, 66, 0, 0, 0, 1, 0, 0, 1, 61, 0, 0, 1,127, 0, 0, 1,121,
- 0, 0, 1, 63, 0, 0, 0, 1, 0, 0, 1,122, 0, 0, 1,128, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 0, 1, 0, 0, 1, 91,
- 0, 0, 1, 93, 0, 0, 1,121, 0, 0, 1,127, 0, 0, 0, 1, 0, 0, 1,122, 0, 0, 1, 94, 0, 0, 1, 92, 0, 0, 1,128,
- 0, 0, 0, 1, 0, 0, 1, 65, 0, 0, 1,121, 0, 0, 1, 93, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 94, 0, 0, 1,122,
- 0, 0, 1, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,141, 0, 0, 1,129, 0, 0, 1,155, 0, 0, 1,143, 0, 0, 0, 1,
- 0, 0, 1,156, 0, 0, 1,130, 0, 0, 1,142, 0, 0, 1,144, 0, 0, 0, 1, 0, 0, 1,141, 0, 0, 1,143, 0, 0, 1,145,
- 0, 0, 1,139, 0, 0, 0, 1, 0, 0, 1,146, 0, 0, 1,144, 0, 0, 1,142, 0, 0, 1,140, 0, 0, 0, 1, 0, 0, 1,139,
- 0, 0, 1,145, 0, 0, 1,147, 0, 0, 1,137, 0, 0, 0, 1, 0, 0, 1,148, 0, 0, 1,146, 0, 0, 1,140, 0, 0, 1,138,
- 0, 0, 0, 1, 0, 0, 1,137, 0, 0, 1,147, 0, 0, 1,149, 0, 0, 1,135, 0, 0, 0, 1, 0, 0, 1,150, 0, 0, 1,148,
- 0, 0, 1,138, 0, 0, 1,136, 0, 0, 0, 1, 0, 0, 1,135, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 1,133, 0, 0, 0, 1,
- 0, 0, 1,152, 0, 0, 1,150, 0, 0, 1,136, 0, 0, 1,134, 0, 0, 0, 1, 0, 0, 1,133, 0, 0, 1,151, 0, 0, 1,153,
- 0, 0, 1,131, 0, 0, 0, 1, 0, 0, 1,154, 0, 0, 1,152, 0, 0, 1,134, 0, 0, 1,132, 0, 0, 0, 1, 0, 0, 1,151,
- 0, 0, 1,161, 0, 0, 1,159, 0, 0, 1,153, 0, 0, 0, 1, 0, 0, 1,160, 0, 0, 1,162, 0, 0, 1,152, 0, 0, 1,154,
- 0, 0, 0, 1, 0, 0, 1,149, 0, 0, 1,163, 0, 0, 1,161, 0, 0, 1,151, 0, 0, 0, 1, 0, 0, 1,162, 0, 0, 1,164,
- 0, 0, 1,150, 0, 0, 1,152, 0, 0, 0, 1, 0, 0, 1,147, 0, 0, 1,165, 0, 0, 1,163, 0, 0, 1,149, 0, 0, 0, 1,
- 0, 0, 1,164, 0, 0, 1,166, 0, 0, 1,148, 0, 0, 1,150, 0, 0, 0, 1, 0, 0, 1,145, 0, 0, 1,167, 0, 0, 1,165,
- 0, 0, 1,147, 0, 0, 0, 1, 0, 0, 1,166, 0, 0, 1,168, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 0, 1, 0, 0, 1,143,
- 0, 0, 1,169, 0, 0, 1,167, 0, 0, 1,145, 0, 0, 0, 1, 0, 0, 1,168, 0, 0, 1,170, 0, 0, 1,144, 0, 0, 1,146,
- 0, 0, 0, 1, 0, 0, 1,143, 0, 0, 1,155, 0, 0, 1,157, 0, 0, 1,169, 0, 0, 0, 1, 0, 0, 1,158, 0, 0, 1,156,
- 0, 0, 1,144, 0, 0, 1,170, 0, 0, 0, 1, 0, 0, 1, 59, 0, 0, 1, 61, 0, 0, 1,185, 0, 0, 1,183, 0, 0, 0, 1,
- 0, 0, 1,186, 0, 0, 1, 62, 0, 0, 1, 60, 0, 0, 1,184, 0, 0, 0, 1, 0, 0, 1, 61, 0, 0, 1,131, 0, 0, 1,153,
- 0, 0, 1,185, 0, 0, 0, 1, 0, 0, 1,154, 0, 0, 1,132, 0, 0, 1, 62, 0, 0, 1,186, 0, 0, 0, 1, 0, 0, 1, 51,
- 0, 0, 1, 59, 0, 0, 1,183, 0, 0, 1, 53, 0, 0, 0, 1, 0, 0, 1,184, 0, 0, 1, 60, 0, 0, 1, 52, 0, 0, 1, 54,
- 0, 0, 0, 1, 0, 0, 1,123, 0, 0, 1,171, 0, 0, 1,155, 0, 0, 1,129, 0, 0, 0, 1, 0, 0, 1,156, 0, 0, 1,172,
- 0, 0, 1,124, 0, 0, 1,130, 0, 0, 0, 1, 0, 0, 1,153, 0, 0, 1,159, 0, 0, 1,181, 0, 0, 1,185, 0, 0, 0, 1,
- 0, 0, 1,182, 0, 0, 1,160, 0, 0, 1,154, 0, 0, 1,186, 0, 0, 0, 1, 0, 0, 1,179, 0, 0, 1,187, 0, 0, 1,185,
- 0, 0, 1,181, 0, 0, 0, 1, 0, 0, 1,186, 0, 0, 1,188, 0, 0, 1,180, 0, 0, 1,182, 0, 0, 0, 1, 0, 0, 1,175,
- 0, 0, 1,187, 0, 0, 1,179, 0, 0, 1,177, 0, 0, 0, 1, 0, 0, 1,180, 0, 0, 1,188, 0, 0, 1,176, 0, 0, 1,178,
- 0, 0, 0, 1, 0, 0, 1,173, 0, 0, 1,189, 0, 0, 1,187, 0, 0, 1,175, 0, 0, 0, 1, 0, 0, 1,188, 0, 0, 1,190,
- 0, 0, 1,174, 0, 0, 1,176, 0, 0, 0, 1, 0, 0, 1,171, 0, 0, 1,189, 0, 0, 1,173, 0, 0, 1,191, 0, 0, 0, 1,
- 0, 0, 1,174, 0, 0, 1,190, 0, 0, 1,172, 0, 0, 1,192, 0, 0, 0, 1, 0, 0, 1,155, 0, 0, 1,171, 0, 0, 1,191,
- 0, 0, 1,157, 0, 0, 0, 1, 0, 0, 1,192, 0, 0, 1,172, 0, 0, 1,156, 0, 0, 1,158, 0, 0, 0, 1, 0, 0, 1, 53,
- 0, 0, 1,189, 0, 0, 1,171, 0, 0, 1,123, 0, 0, 0, 1, 0, 0, 1,172, 0, 0, 1,190, 0, 0, 1, 54, 0, 0, 1,124,
- 0, 0, 0, 1, 0, 0, 1, 53, 0, 0, 1,183, 0, 0, 1,187, 0, 0, 1,189, 0, 0, 0, 1, 0, 0, 1,188, 0, 0, 1,184,
- 0, 0, 1, 54, 0, 0, 1,190, 0, 0, 0, 1, 0, 0, 1,183, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 1,188, 0, 0, 1,186, 0, 0, 1,184, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,157, 0, 0, 1,191, 0, 0, 1,193,
- 0, 0, 1,217, 0, 0, 0, 1, 0, 0, 1,194, 0, 0, 1,192, 0, 0, 1,158, 0, 0, 1,218, 0, 0, 0, 1, 0, 0, 1,191,
- 0, 0, 1,173, 0, 0, 1,203, 0, 0, 1,193, 0, 0, 0, 1, 0, 0, 1,204, 0, 0, 1,174, 0, 0, 1,192, 0, 0, 1,194,
- 0, 0, 0, 1, 0, 0, 1,173, 0, 0, 1,175, 0, 0, 1,201, 0, 0, 1,203, 0, 0, 0, 1, 0, 0, 1,202, 0, 0, 1,176,
- 0, 0, 1,174, 0, 0, 1,204, 0, 0, 0, 1, 0, 0, 1,175, 0, 0, 1,177, 0, 0, 1,199, 0, 0, 1,201, 0, 0, 0, 1,
- 0, 0, 1,200, 0, 0, 1,178, 0, 0, 1,176, 0, 0, 1,202, 0, 0, 0, 1, 0, 0, 1,177, 0, 0, 1,179, 0, 0, 1,197,
- 0, 0, 1,199, 0, 0, 0, 1, 0, 0, 1,198, 0, 0, 1,180, 0, 0, 1,178, 0, 0, 1,200, 0, 0, 0, 1, 0, 0, 1,179,
- 0, 0, 1,181, 0, 0, 1,195, 0, 0, 1,197, 0, 0, 0, 1, 0, 0, 1,196, 0, 0, 1,182, 0, 0, 1,180, 0, 0, 1,198,
- 0, 0, 0, 1, 0, 0, 1,181, 0, 0, 1,159, 0, 0, 1,215, 0, 0, 1,195, 0, 0, 0, 1, 0, 0, 1,216, 0, 0, 1,160,
- 0, 0, 1,182, 0, 0, 1,196, 0, 0, 0, 1, 0, 0, 1,169, 0, 0, 1,157, 0, 0, 1,217, 0, 0, 1,205, 0, 0, 0, 1,
- 0, 0, 1,218, 0, 0, 1,158, 0, 0, 1,170, 0, 0, 1,206, 0, 0, 0, 1, 0, 0, 1,167, 0, 0, 1,169, 0, 0, 1,205,
- 0, 0, 1,207, 0, 0, 0, 1, 0, 0, 1,206, 0, 0, 1,170, 0, 0, 1,168, 0, 0, 1,208, 0, 0, 0, 1, 0, 0, 1,165,
- 0, 0, 1,167, 0, 0, 1,207, 0, 0, 1,209, 0, 0, 0, 1, 0, 0, 1,208, 0, 0, 1,168, 0, 0, 1,166, 0, 0, 1,210,
- 0, 0, 0, 1, 0, 0, 1,163, 0, 0, 1,165, 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 1, 0, 0, 1,210, 0, 0, 1,166,
- 0, 0, 1,164, 0, 0, 1,212, 0, 0, 0, 1, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 1,211, 0, 0, 1,213, 0, 0, 0, 1,
- 0, 0, 1,212, 0, 0, 1,164, 0, 0, 1,162, 0, 0, 1,214, 0, 0, 0, 1, 0, 0, 1,159, 0, 0, 1,161, 0, 0, 1,213,
- 0, 0, 1,215, 0, 0, 0, 1, 0, 0, 1,214, 0, 0, 1,162, 0, 0, 1,160, 0, 0, 1,216, 0, 0, 0, 1, 0, 0, 1,199,
- 0, 0, 1,197, 0, 0, 1,221, 0, 0, 1,219, 0, 0, 0, 1, 0, 0, 1,222, 0, 0, 1,198, 0, 0, 1,200, 0, 0, 1,220,
- 0, 0, 0, 1, 0, 0, 1,219, 0, 0, 1,221, 0, 0, 1,223, 0, 0, 1,225, 0, 0, 0, 1, 0, 0, 1,224, 0, 0, 1,222,
- 0, 0, 1,220, 0, 0, 1,226, 0, 0, 0, 1, 0, 0, 1,225, 0, 0, 1,223, 0, 0, 1,229, 0, 0, 1,227, 0, 0, 0, 1,
- 0, 0, 1,230, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 1,228, 0, 0, 0, 1, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 1,231,
- 0, 0, 1,233, 0, 0, 0, 1, 0, 0, 1,232, 0, 0, 1,230, 0, 0, 1,228, 0, 0, 1,234, 0, 0, 0, 1, 0, 0, 1,205,
- 0, 0, 1,217, 0, 0, 1,227, 0, 0, 1,233, 0, 0, 0, 1, 0, 0, 1,228, 0, 0, 1,218, 0, 0, 1,206, 0, 0, 1,234,
- 0, 0, 0, 1, 0, 0, 1,193, 0, 0, 1,225, 0, 0, 1,227, 0, 0, 1,217, 0, 0, 0, 1, 0, 0, 1,228, 0, 0, 1,226,
- 0, 0, 1,194, 0, 0, 1,218, 0, 0, 0, 1, 0, 0, 1,193, 0, 0, 1,203, 0, 0, 1,219, 0, 0, 1,225, 0, 0, 0, 1,
- 0, 0, 1,220, 0, 0, 1,204, 0, 0, 1,194, 0, 0, 1,226, 0, 0, 0, 1, 0, 0, 1,199, 0, 0, 1,219, 0, 0, 1,203,
- 0, 0, 1,201, 0, 0, 0, 1, 0, 0, 1,204, 0, 0, 1,220, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 0, 1, 0, 0, 1,195,
- 0, 0, 1,215, 0, 0, 1,221, 0, 0, 1,197, 0, 0, 0, 1, 0, 0, 1,222, 0, 0, 1,216, 0, 0, 1,196, 0, 0, 1,198,
- 0, 0, 0, 1, 0, 0, 1,213, 0, 0, 1,223, 0, 0, 1,221, 0, 0, 1,215, 0, 0, 0, 1, 0, 0, 1,222, 0, 0, 1,224,
- 0, 0, 1,214, 0, 0, 1,216, 0, 0, 0, 1, 0, 0, 1,211, 0, 0, 1,229, 0, 0, 1,223, 0, 0, 1,213, 0, 0, 0, 1,
- 0, 0, 1,224, 0, 0, 1,230, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 1, 0, 0, 1,209, 0, 0, 1,231, 0, 0, 1,229,
- 0, 0, 1,211, 0, 0, 0, 1, 0, 0, 1,230, 0, 0, 1,232, 0, 0, 1,210, 0, 0, 1,212, 0, 0, 0, 1, 0, 0, 1,207,
- 0, 0, 1,233, 0, 0, 1,231, 0, 0, 1,209, 0, 0, 0, 1, 0, 0, 1,232, 0, 0, 1,234, 0, 0, 1,208, 0, 0, 1,210,
- 0, 0, 0, 1, 0, 0, 1,205, 0, 0, 1,233, 0, 0, 1,207, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,208, 0, 0, 1,234,
- 0, 0, 1,206, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,133, 0, 0, 1,131, 0, 0, 1,245, 0, 0, 1,243, 0, 0, 0, 1,
- 0, 0, 1,246, 0, 0, 1,132, 0, 0, 1,134, 0, 0, 1,244, 0, 0, 0, 1, 0, 0, 1,135, 0, 0, 1,133, 0, 0, 1,243,
- 0, 0, 1,241, 0, 0, 0, 1, 0, 0, 1,244, 0, 0, 1,134, 0, 0, 1,136, 0, 0, 1,242, 0, 0, 0, 1, 0, 0, 1,137,
- 0, 0, 1,135, 0, 0, 1,241, 0, 0, 1,239, 0, 0, 0, 1, 0, 0, 1,242, 0, 0, 1,136, 0, 0, 1,138, 0, 0, 1,240,
- 0, 0, 0, 1, 0, 0, 1,139, 0, 0, 1,137, 0, 0, 1,239, 0, 0, 1,237, 0, 0, 0, 1, 0, 0, 1,240, 0, 0, 1,138,
- 0, 0, 1,140, 0, 0, 1,238, 0, 0, 0, 1, 0, 0, 1,141, 0, 0, 1,139, 0, 0, 1,237, 0, 0, 1,235, 0, 0, 0, 1,
- 0, 0, 1,238, 0, 0, 1,140, 0, 0, 1,142, 0, 0, 1,236, 0, 0, 0, 1, 0, 0, 1,129, 0, 0, 1,141, 0, 0, 1,235,
- 0, 0, 1,247, 0, 0, 0, 1, 0, 0, 1,236, 0, 0, 1,142, 0, 0, 1,130, 0, 0, 1,248, 0, 0, 0, 1, 0, 0, 1,235,
- 0, 0, 1,243, 0, 0, 1,245, 0, 0, 1,247, 0, 0, 0, 1, 0, 0, 1,246, 0, 0, 1,244, 0, 0, 1,236, 0, 0, 1,248,
- 0, 0, 0, 1, 0, 0, 1,235, 0, 0, 1,237, 0, 0, 1,241, 0, 0, 1,243, 0, 0, 0, 1, 0, 0, 1,242, 0, 0, 1,238,
- 0, 0, 1,236, 0, 0, 1,244, 0, 0, 0, 1, 0, 0, 1,237, 0, 0, 1,239, 0, 0, 1,241, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 1,242, 0, 0, 1,240, 0, 0, 1,238, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 55, 0, 0, 1,123, 0, 0, 1,129,
- 0, 0, 1,247, 0, 0, 0, 1, 0, 0, 1,130, 0, 0, 1,124, 0, 0, 1, 56, 0, 0, 1,248, 0, 0, 0, 1, 0, 0, 1, 55,
- 0, 0, 1,247, 0, 0, 1,245, 0, 0, 1, 63, 0, 0, 0, 1, 0, 0, 1,246, 0, 0, 1,248, 0, 0, 1, 56, 0, 0, 1, 64,
- 0, 0, 0, 1, 0, 0, 1, 61, 0, 0, 1, 63, 0, 0, 1,245, 0, 0, 1,131, 0, 0, 0, 1, 0, 0, 1,246, 0, 0, 1, 64,
- 0, 0, 1, 62, 0, 0, 1,132, 0, 0, 0, 1, 68, 65, 84, 65, 0, 0, 85,240, 8,102,176, 32, 0, 0, 0, 60, 0, 0, 1,244,
- 63, 28,112, 3, 62,236,178,185, 63, 27,124,224, 62,232, 65,235, 63, 30, 63,144, 62,226,195,233, 63, 32,152,118, 62,236,167, 37,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,209,232, 2, 62,226, 21,222, 62,215,109,102, 62,231,147,222, 62,213,135, 28,
- 62,236, 4,172, 62,205, 54, 56, 62,235,249, 22, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 32,152,118, 62,236,167, 37,
- 63, 30, 63,144, 62,226,195,233, 63, 33,235,108, 62,220,235,197, 63, 37,151,209, 62,236,161, 89, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,202,144, 76, 62,220, 61,186, 62,209,232, 2, 62,226, 21,222, 62,205, 54, 56, 62,235,249, 22, 62,195, 55,128,
- 62,235,243, 70, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 30, 63,144, 62,226,195,233, 63, 25, 55, 20, 62,223, 35, 1,
- 63, 25,178,200, 62,214,233, 77, 63, 33,235,108, 62,220,235,197, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,219, 1,146,
- 62,214, 59, 66, 62,219,248,248, 62,222,116,246, 62,209,232, 2, 62,226, 21,222, 62,202,144, 76, 62,220, 61,186, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 27,124,224, 62,232, 65,235, 63, 24,252, 87, 62,230,111, 93, 63, 25, 55, 20, 62,223, 35, 1,
- 63, 30, 63,144, 62,226,195,233, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,219,248,248, 62,222,116,246, 62,220,110,118,
- 62,229,193, 78, 62,215,109,102, 62,231,147,222, 62,209,232, 2, 62,226, 21,222, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 24,252, 87, 62,230,111, 93, 63, 22,195, 22, 62,232, 90,195, 63, 20, 91,191, 62,227, 18,193, 63, 25, 55, 20, 62,223, 35, 1,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,229,175,162, 62,226,100,178, 62,224,224,248, 62,231,172,182, 62,220,110,118,
- 62,229,193, 78, 62,219,248,248, 62,222,116,246, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 25, 55, 20, 62,223, 35, 1,
- 63, 20, 91,191, 62,227, 18,193, 63, 17,165,187, 62,221, 6,225, 63, 25,178,200, 62,214,233, 77, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,235, 27,170, 62,220, 88,214, 62,229,175,162, 62,226,100,178, 62,219,248,248, 62,222,116,246, 62,219, 1,146,
- 62,214, 59, 66, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 20, 91,191, 62,227, 18,193, 63, 18, 18,164, 62,236,201,173,
- 63, 13,231,157, 62,236,161, 89, 63, 17,165,187, 62,221, 6,225, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,242,151,232,
- 62,235,243, 70, 62,234, 65,216, 62,236, 27,158, 62,229,175,162, 62,226,100,178, 62,235, 27,170, 62,220, 88,214, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 22,195, 22, 62,232, 90,195, 63, 21,202, 11, 62,236,189, 1, 63, 18, 18,164, 62,236,201,173,
- 63, 20, 91,191, 62,227, 18,193, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,234, 65,216, 62,236, 27,158, 62,226,211, 12,
- 62,236, 14,246, 62,224,224,248, 62,231,172,182, 62,229,175,162, 62,226,100,178, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 21,202, 11, 62,236,189, 1, 63, 22,202,215, 62,241,124,237, 63, 20,105,125, 62,246, 71, 1, 63, 18, 18,164, 62,236,201,173,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,229,148, 42, 62,245,152,246, 62,224,209,112, 62,240,206,226, 62,226,211, 12,
- 62,236, 14,246, 62,234, 65,216, 62,236, 27,158, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 18, 18,164, 62,236,201,173,
- 63, 20,105,125, 62,246, 71, 1, 63, 17,173, 44, 62,252,149,231, 63, 13,231,157, 62,236,161, 89, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,235, 12,206, 62,251,231,218, 62,229,148, 42, 62,245,152,246, 62,234, 65,216, 62,236, 27,158, 62,242,151,232,
- 62,235,243, 70, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 20,105,125, 62,246, 71, 1, 63, 25, 59, 37, 62,250, 73, 49,
- 63, 25,178,108, 63, 1,108,218, 63, 17,173, 44, 62,252,149,231, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,219, 2, 76,
- 63, 1, 21,213, 62,219,240,216, 62,249,155, 38, 62,229,148, 42, 62,245,152,246, 62,235, 12,206, 62,251,231,218, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 22,202,215, 62,241,124,237, 63, 25, 1,195, 62,243,102,169, 63, 25, 59, 37, 62,250, 73, 49,
- 63, 20,105,125, 62,246, 71, 1, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,219,240,216, 62,249,155, 38, 62,220, 99,156,
- 62,242,184,154, 62,224,209,112, 62,240,206,226, 62,229,148, 42, 62,245,152,246, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 25, 1,195, 62,243,102,169, 63, 27,125,176, 62,241,145,149, 63, 30, 74,167, 62,246,153, 3, 63, 25, 59, 37, 62,250, 73, 49,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,209,209,212, 62,245,234,246, 62,215,107,192, 62,240,227,138, 62,220, 99,156,
- 62,242,184,154, 62,219,240,216, 62,249,155, 38, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 25, 59, 37, 62,250, 73, 49,
- 63, 30, 74,167, 62,246,153, 3, 63, 33,230,204, 62,252,232,107, 63, 25,178,108, 63, 1,108,218, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,202,153,132, 62,252, 58, 94, 62,209,209,212, 62,245,234,246, 62,219,240,216, 62,249,155, 38, 62,219, 2, 76,
- 63, 1, 21,213, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 30, 74,167, 62,246,153, 3, 63, 32,152,118, 62,236,167, 37,
- 63, 37,151,209, 62,236,161, 89, 63, 33,230,204, 62,252,232,107, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,195, 55,128,
- 62,235,243, 70, 62,205, 54, 56, 62,235,249, 22, 62,209,209,212, 62,245,234,246, 62,202,153,132, 62,252, 58, 94, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 27,125,176, 62,241,145,149, 63, 28,112, 3, 62,236,178,185, 63, 32,152,118, 62,236,167, 37,
- 63, 30, 74,167, 62,246,153, 3, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,205, 54, 56, 62,235,249, 22, 62,213,135, 28,
- 62,236, 4,172, 62,215,107,192, 62,240,227,138, 62,209,209,212, 62,245,234,246, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 28,112, 3, 62,236,178,185, 63, 27,125,176, 62,241,145,149, 63, 27, 39, 42, 62,241, 1, 57, 63, 27,249,140, 62,236,186,115,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,216, 24,206, 62,240, 83, 46, 62,215,107,192, 62,240,227,138, 62,213,135, 28,
- 62,236, 4,172, 62,214,116, 8, 62,236, 12,102, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 27,125,176, 62,241,145,149,
- 63, 25, 1,195, 62,243,102,169, 63, 24,248, 6, 62,242, 91,185, 63, 27, 39, 42, 62,241, 1, 57, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,220,119, 22, 62,241,173,174, 62,220, 99,156, 62,242,184,154, 62,215,107,192, 62,240,227,138, 62,216, 24,206,
- 62,240, 83, 46, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 25, 1,195, 62,243,102,169, 63, 22,202,215, 62,241,124,237,
- 63, 23, 38,157, 62,240,173,225, 63, 24,248, 6, 62,242, 91,185, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,224, 25,234,
- 62,239,255,214, 62,224,209,112, 62,240,206,226, 62,220, 99,156, 62,242,184,154, 62,220,119, 22, 62,241,173,174, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 22,202,215, 62,241,124,237, 63, 21,202, 11, 62,236,189, 1, 63, 22, 89, 13, 62,236,196,247,
- 63, 23, 38,157, 62,240,173,225, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,225,181, 8, 62,236, 22,234, 62,226,211, 12,
- 62,236, 14,246, 62,224,209,112, 62,240,206,226, 62,224, 25,234, 62,239,255,214, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 21,202, 11, 62,236,189, 1, 63, 22,195, 22, 62,232, 90,195, 63, 23, 33, 88, 62,233, 47, 69, 63, 22, 89, 13, 62,236,196,247,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,224, 36,112, 62,232,129, 58, 62,224,224,248, 62,231,172,182, 62,226,211, 12,
- 62,236, 14,246, 62,225,181, 8, 62,236, 22,234, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 22,195, 22, 62,232, 90,195,
- 63, 24,252, 87, 62,230,111, 93, 63, 24,243,100, 62,231,123, 5, 63, 23, 33, 88, 62,233, 47, 69, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,220,128, 90, 62,230,204,248, 62,220,110,118, 62,229,193, 78, 62,224,224,248, 62,231,172,182, 62,224, 36,112,
- 62,232,129, 58, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240, 63, 24,252, 87, 62,230,111, 93, 63, 27,124,224, 62,232, 65,235,
- 63, 27, 37,169, 62,232,211, 35, 63, 24,243,100, 62,231,123, 5, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,216, 27,206,
- 62,232, 37, 22, 62,215,109,102, 62,231,147,222, 62,220,110,118, 62,229,193, 78, 62,220,128, 90, 62,230,204,248, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,240, 63, 27,124,224, 62,232, 65,235, 63, 28,112, 3, 62,236,178,185, 63, 27,249,140, 62,236,186,115,
- 63, 27, 37,169, 62,232,211, 35, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,214,116, 8, 62,236, 12,102, 62,213,135, 28,
- 62,236, 4,172, 62,215,109,102, 62,231,147,222, 62,216, 27,206, 62,232, 37, 22, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,240,
- 63, 24,242,138, 62,236,194, 21, 63, 27, 37,169, 62,232,211, 35, 63, 27,249,140, 62,236,186,115, 63,128, 0, 0, 63,128, 0, 0,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,214,116, 8, 62,236, 12,102, 62,216, 27,206, 62,232, 37, 22, 62,220,130, 16,
- 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112, 63, 24,243,100, 62,231,123, 5,
- 63, 27, 37,169, 62,232,211, 35, 63, 24,242,138, 62,236,194, 21, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,112, 62,220,130, 16, 62,236, 20, 6, 62,216, 27,206, 62,232, 37, 22, 62,220,128, 90, 62,230,204,248, 63,128, 0, 0,
- 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112, 63, 24,242,138, 62,236,194, 21, 63, 23, 33, 88, 62,233, 47, 69,
- 63, 24,243,100, 62,231,123, 5, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,220,128, 90,
- 62,230,204,248, 62,224, 36,112, 62,232,129, 58, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,112, 63, 24,242,138, 62,236,194, 21, 63, 22, 89, 13, 62,236,196,247, 63, 23, 33, 88, 62,233, 47, 69,
- 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,224, 36,112, 62,232,129, 58, 62,225,181, 8,
- 62,236, 22,234, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112,
- 63, 24,242,138, 62,236,194, 21, 63, 23, 38,157, 62,240,173,225, 63, 22, 89, 13, 62,236,196,247, 63,128, 0, 0, 63,128, 0, 0,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,225,181, 8, 62,236, 22,234, 62,224, 25,234, 62,239,255,214, 62,220,130, 16,
- 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112, 63, 24,242,138, 62,236,194, 21,
- 63, 24,248, 6, 62,242, 91,185, 63, 23, 38,157, 62,240,173,225, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,112, 62,224, 25,234, 62,239,255,214, 62,220,119, 22, 62,241,173,174, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0,
- 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112, 63, 24,242,138, 62,236,194, 21, 63, 27, 39, 42, 62,241, 1, 57,
- 63, 24,248, 6, 62,242, 91,185, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,220,119, 22,
- 62,241,173,174, 62,216, 24,206, 62,240, 83, 46, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32,
- 61, 0, 0, 5, 0, 0, 0,112, 63, 24,242,138, 62,236,194, 21, 63, 27,249,140, 62,236,186,115, 63, 27, 39, 42, 62,241, 1, 57,
- 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62,216, 24,206, 62,240, 83, 46, 62,214,116, 8,
- 62,236, 12,102, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 61, 0, 0, 5, 0, 0, 0,112,
- 63, 16,254,174, 62, 34, 45, 94, 63, 13,190, 79, 62, 46,193,160, 63, 3,199,220, 62, 24,219, 89, 63, 3,199,219, 61,229, 28, 18,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 63, 3,199,220, 62, 24,219, 89, 62,243,150, 14, 62, 47, 79,204, 62,236,248,140,
- 62, 34,202,182, 63, 3,199,219, 61,229, 28, 18, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 63, 21,152,184, 62, 53, 47,182,
- 63, 16,104,250, 62, 55,113, 16, 63, 13,190, 79, 62, 46,193,160, 63, 16,254,174, 62, 34, 45, 94, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,128, 62,243,150, 14, 62, 47, 79,204, 62,238, 68,200, 62, 56, 62, 76, 62,227,207,183, 62, 54, 75,250, 62,236,248,140,
- 62, 34,202,182, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 63, 22, 57,137, 62, 61, 93, 81, 63, 16,186,206, 62, 72,129, 85,
- 63, 16,104,250, 62, 55,113, 16, 63, 21,152,184, 62, 53, 47,182, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,238, 68,200,
- 62, 56, 62, 76, 62,237,187,192, 62, 73,118,194, 62,226,152,122, 62, 62,166,190, 62,227,207,183, 62, 54, 75,250, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 22,249,250, 62, 88,251,160, 63, 16, 32,222, 62, 93,106, 34, 63, 16,186,206, 62, 72,129, 85,
- 63, 22, 57,137, 62, 61, 93, 81, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,237,187,192, 62, 73,118,194, 62,239, 19, 21,
- 62, 94,110,121, 62,225, 83, 90, 62, 90,153, 21, 62,226,152,122, 62, 62,166,190, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 25, 81, 20, 62,132, 56, 17, 63, 15,243,206, 62,136,207,182, 63, 16, 32,222, 62, 93,106, 34, 63, 22,249,250, 62, 88,251,160,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239, 19, 21, 62, 94,110,121, 62,239,193, 92, 62,137, 61,113, 62,221, 42, 54,
- 62,133, 25,209, 62,225, 83, 90, 62, 90,153, 21, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,239,111, 62,166, 77,159,
- 63, 37, 94, 91, 62,187,120,107, 63, 30, 21, 66, 62,200,139,178, 63, 12,237,158, 62,187,241, 38, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,211,125,139, 62,200,171,170, 62,197, 28,156, 62,187,130,166, 62,216, 21,115, 62,166,177, 14, 62,245,175, 15,
- 62,188, 14,188, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 37, 94, 91, 62,187,120,107, 63, 43, 57, 87, 62,206, 58,222,
- 63, 39,163, 24, 62,216, 95,174, 63, 30, 21, 66, 62,200,139,178, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,191,194, 98,
- 62,216, 94, 42, 62,184,207,130, 62,206, 27, 42, 62,197, 28,156, 62,187,130,166, 62,211,125,139, 62,200,171,170, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 43, 57, 87, 62,206, 58,222, 63, 50,229, 38, 62,226, 32,169, 63, 43, 79,177, 62,231,194,202,
- 63, 39,163, 24, 62,216, 95,174, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,183,201, 60, 62,231,218, 82, 62,168, 39,196,
- 62,226, 11,206, 62,184,207,130, 62,206, 27, 42, 62,191,194, 98, 62,216, 94, 42, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 50,229, 38, 62,226, 32,169, 63, 48,134, 62, 62,249,107, 37, 63, 43,190,154, 62,249, 0,192, 63, 43, 79,177, 62,231,194,202,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,182,190,138, 62,249, 49, 35, 62,172,229,172, 62,249,127,116, 62,168, 39,196,
- 62,226, 11,206, 62,183,201, 60, 62,231,218, 82, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 48,134, 62, 62,249,107, 37,
- 63, 46, 88,238, 63, 2,223,146, 63, 40,207,123, 62,254,175,218, 63, 43,190,154, 62,249, 0,192, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,188,184, 2, 62,255, 0,140, 62,177, 87,173, 63, 3, 9,102, 62,172,229,172, 62,249,127,116, 62,182,190,138,
- 62,249, 49, 35, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 46, 88,238, 63, 2,223,146, 63, 34,158,220, 63, 10, 23,175,
- 63, 30, 77,126, 63, 5, 88,156, 63, 40,207,123, 62,254,175,218, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,210, 65, 89,
- 63, 5,158, 56, 62,201,109,124, 63, 10,121, 72, 62,177, 87,173, 63, 3, 9,102, 62,188,184, 2, 62,255, 0,140, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 34,158,220, 63, 10, 23,175, 63, 26,105, 28, 63, 11,194,242, 63, 25,120,244, 63, 7,242, 78,
- 63, 30, 77,126, 63, 5, 88,156, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,220, 39, 0, 63, 8, 58,252, 62,218, 73,220,
- 63, 12, 31,169, 62,201,109,124, 63, 10,121, 72, 62,210, 65, 89, 63, 5,158, 56, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 26,105, 28, 63, 11,194,242, 63, 22,244,173, 63, 11,215,236, 63, 22, 47,202, 63, 8, 60,156, 63, 25,120,244, 63, 7,242, 78,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,226,221, 11, 63, 8,125, 90, 62,225, 89,220, 63, 12, 42, 77, 62,218, 73,220,
- 63, 12, 31,169, 62,220, 39, 0, 63, 8, 58,252, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 22,244,173, 63, 11,215,236,
- 63, 11,169, 67, 63, 11,197, 18, 63, 12,252,106, 63, 3,173,180, 63, 22, 47,202, 63, 8, 60,156, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,245,114, 35, 63, 3,196,233, 62,248, 72, 55, 63, 11,232, 91, 62,225, 89,220, 63, 12, 42, 77, 62,226,221, 11,
- 63, 8,125, 90, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 11,169, 67, 63, 11,197, 18, 63, 3,232,148, 63, 11, 17,164,
- 63, 3,220,162, 63, 0, 88, 45, 63, 12,252,106, 63, 3,173,180, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,220,162,
- 63, 0, 88, 45, 63, 3,232,148, 63, 11, 17,164, 62,248, 72, 55, 63, 11,232, 91, 62,245,114, 35, 63, 3,196,233, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 17, 59,103, 62,255,195,120, 63, 22, 81,240, 63, 1, 70,114, 63, 22, 47,202, 63, 8, 60,156,
- 63, 12,252,106, 63, 3,173,180, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,226,221, 11, 63, 8,125, 90, 62,226,128,106,
- 63, 1,111,198, 62,236,213,209, 62,255,250, 4, 62,245,114, 35, 63, 3,196,233, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 22, 81,240, 63, 1, 70,114, 63, 25,182,151, 63, 1, 9,130, 63, 25,120,244, 63, 7,242, 78, 63, 22, 47,202, 63, 8, 60,156,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,220, 39, 0, 63, 8, 58,252, 62,219,150,213, 63, 1, 55, 50, 62,226,128,106,
- 63, 1,111,198, 62,226,221, 11, 63, 8,125, 90, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 30, 49, 96, 62,254,229,121,
- 63, 30, 77,126, 63, 5, 88,156, 63, 25,120,244, 63, 7,242, 78, 63, 25,182,151, 63, 1, 9,130, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,220, 39, 0, 63, 8, 58,252, 62,210, 65, 89, 63, 5,158, 56, 62,210,116,176, 62,255, 62,227, 62,219,150,213,
- 63, 1, 55, 50, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 37,113, 25, 62,247,157, 35, 63, 40,207,123, 62,254,175,218,
- 63, 30, 77,126, 63, 5, 88,156, 63, 30, 49, 96, 62,254,229,121, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,210, 65, 89,
- 63, 5,158, 56, 62,188,184, 2, 62,255, 0,140, 62,195,165,189, 62,247,232,139, 62,210,116,176, 62,255, 62,227, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 39, 62, 92, 62,240, 75,121, 63, 43,190,154, 62,249, 0,192, 63, 40,207,123, 62,254,175,218,
- 63, 37,113, 25, 62,247,157, 35, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,188,184, 2, 62,255, 0,140, 62,182,190,138,
- 62,249, 49, 35, 62,192, 10,222, 62,240,128,163, 62,195,165,189, 62,247,232,139, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 38,149,140, 62,229, 95, 38, 63, 43, 79,177, 62,231,194,202, 63, 43,190,154, 62,249, 0,192, 63, 39, 62, 92, 62,240, 75,121,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,182,190,138, 62,249, 49, 35, 62,183,201, 60, 62,231,218, 82, 62,193,140,168,
- 62,229,129, 94, 62,192, 10,222, 62,240,128,163, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 33,120, 14, 62,214,238,166,
- 63, 39,163, 24, 62,216, 95,174, 63, 43, 79,177, 62,231,194,202, 63, 38,149,140, 62,229, 95, 38, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,183,201, 60, 62,231,218, 82, 62,191,194, 98, 62,216, 94, 42, 62,204, 75,168, 62,215, 7, 62, 62,193,140,168,
- 62,229,129, 94, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,178,165, 62,208, 17,128, 63, 30, 21, 66, 62,200,139,178,
- 63, 39,163, 24, 62,216, 95,174, 63, 33,120, 14, 62,214,238,166, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,191,194, 98,
- 62,216, 94, 42, 62,211,125,139, 62,200,171,170, 62,216, 24, 6, 62,208, 57,128, 62,204, 75,168, 62,215, 7, 62, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 17, 97, 15, 62,214, 34,220, 63, 12,237,158, 62,187,241, 38, 63, 30, 21, 66, 62,200,139,178,
- 63, 27,178,165, 62,208, 17,128, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,211,125,139, 62,200,171,170, 62,245,175, 15,
- 62,188, 14,188, 62,236,200,217, 62,214, 49,134, 62,216, 24, 6, 62,208, 57,128, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 17, 97, 15, 62,214, 34,220, 63, 14,244,149, 62,221, 42, 4, 63, 3,230,147, 62,208, 47, 78, 63, 12,237,158, 62,187,241, 38,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,230,147, 62,208, 47, 78, 62,241,144,141, 62,221, 52,244, 62,236,200,217,
- 62,214, 49,134, 62,245,175, 15, 62,188, 14,188, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 17, 59,103, 62,255,195,120,
- 63, 12,252,106, 63, 3,173,180, 63, 3,220,162, 63, 0, 88, 45, 63, 13, 25, 71, 62,243,163,116, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 63, 3,220,162, 63, 0, 88, 45, 62,245,114, 35, 63, 3,196,233, 62,236,213,209, 62,255,250, 4, 62,245, 45, 0,
- 62,243,185,206, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 13, 25, 71, 62,243,163,116, 63, 3,220,162, 63, 0, 88, 45,
- 63, 3,220,215, 62,231,189,148, 63, 13, 2, 64, 62,230,215, 52, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,220,215,
- 62,231,189,148, 63, 3,220,162, 63, 0, 88, 45, 62,245, 45, 0, 62,243,185,206, 62,245,100,219, 62,230,230,184, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,230,147, 62,208, 47, 78, 63, 14,244,149, 62,221, 42, 4, 63, 13, 2, 64, 62,230,215, 52,
- 63, 3,220,215, 62,231,189,148, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,245,100,219, 62,230,230,184, 62,241,144,141,
- 62,221, 52,244, 63, 3,230,147, 62,208, 47, 78, 63, 3,220,215, 62,231,189,148, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 7, 61,250, 62, 54, 31,148, 63, 3,202,193, 62, 49,174,214, 63, 3,199,220, 62, 24,219, 89, 63, 13,190, 79, 62, 46,193,160,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,199,220, 62, 24,219, 89, 63, 3,202,193, 62, 49,174,214, 63, 0, 87,175,
- 62, 54, 90,251, 62,243,150, 14, 62, 47, 79,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 9,214, 68, 62, 66,237,246,
- 63, 7, 61,250, 62, 54, 31,148, 63, 13,190, 79, 62, 46,193,160, 63, 16,104,250, 62, 55,113, 16, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,243,150, 14, 62, 47, 79,204, 63, 0, 87,175, 62, 54, 90,251, 62,251,137,104, 62, 67, 92,179, 62,238, 68,200,
- 62, 56, 62, 76, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 8,221,237, 62, 91, 90,218, 63, 9,214, 68, 62, 66,237,246,
- 63, 16,104,250, 62, 55,113, 16, 63, 16,186,206, 62, 72,129, 85, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,238, 68,200,
- 62, 56, 62, 76, 62,251,137,104, 62, 67, 92,179, 62,253,153, 39, 62, 91,195, 27, 62,237,187,192, 62, 73,118,194, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 15,243,206, 62,136,207,182, 63, 8, 32, 77, 62,139, 39, 10, 63, 9,117, 22, 62, 97,203,146,
- 63, 16, 32,222, 62, 93,106, 34, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,252,110,192, 62, 98, 68, 79, 62,255, 89,219,
- 62,139, 79,116, 62,239,193, 92, 62,137, 61,113, 62,239, 19, 21, 62, 94,110,121, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 8,221,237, 62, 91, 90,218, 63, 16,186,206, 62, 72,129, 85, 63, 16, 32,222, 62, 93,106, 34, 63, 9,117, 22, 62, 97,203,146,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239, 19, 21, 62, 94,110,121, 62,237,187,192, 62, 73,118,194, 62,253,153, 39,
- 62, 91,195, 27, 62,252,110,192, 62, 98, 68, 79, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 9,125,119, 62,158,112, 7,
- 63, 3,233, 70, 62,154, 27, 88, 63, 3,229,235, 62,139,108, 97, 63, 8, 32, 77, 62,139, 39, 10, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 63, 3,229,235, 62,139,108, 97, 63, 3,233, 70, 62,154, 27, 88, 62,252,179,165, 62,158,140,163, 62,255, 89,219,
- 62,139, 79,116, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 9,117, 22, 62, 97,203,146, 63, 8, 32, 77, 62,139, 39, 10,
- 63, 3,229,235, 62,139,108, 97, 63, 3,215,246, 62,101, 56,143, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,229,235,
- 62,139,108, 97, 62,255, 89,219, 62,139, 79,116, 62,252,110,192, 62, 98, 68, 79, 63, 3,215,246, 62,101, 56,143, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,210,147, 62, 86, 95,221, 63, 8,221,237, 62, 91, 90,218, 63, 9,117, 22, 62, 97,203,146,
- 63, 3,215,246, 62,101, 56,143, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,252,110,192, 62, 98, 68, 79, 62,253,153, 39,
- 62, 91,195, 27, 63, 3,210,147, 62, 86, 95,221, 63, 3,215,246, 62,101, 56,143, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 12, 54, 5, 62,167,183,188, 63, 9, 61,250, 62,168,214,252, 63, 8,143,152, 62,163,107, 45, 63, 9,125,119, 62,158,112, 7,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,254,136,100, 62,163,123, 38, 62,253, 39,110, 62,168,224,103, 62,247, 68, 98,
- 62,167,206,146, 62,252,179,165, 62,158,140,163, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 10,196,135, 62,178,208, 52,
- 63, 8,233, 25, 62,175,110,116, 63, 9, 61,250, 62,168,214,252, 63, 12, 54, 5, 62,167,183,188, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,253, 39,110, 62,168,224,103, 62,253,195,102, 62,175,102,184, 62,250, 14, 98, 62,178,202,149, 62,247, 68, 98,
- 62,167,206,146, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 4, 17, 69, 62,182,176,105, 63, 6,138, 69, 62,177,180, 80,
- 63, 8,233, 25, 62,175,110,116, 63, 10,196,135, 62,178,208, 52, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,253,195,102,
- 62,175,102,184, 63, 1, 49, 14, 62,177,150, 62, 63, 4, 17, 69, 62,182,176,105, 62,250, 14, 98, 62,178,202,149, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,124,209, 62,177, 0, 70, 63, 3,232, 11, 62,174, 4,140, 63, 6,138, 69, 62,177,180, 80,
- 63, 4, 17, 69, 62,182,176,105, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 1, 49, 14, 62,177,150, 62, 63, 3,232, 11,
- 62,174, 4,140, 63, 3,124,209, 62,177, 0, 70, 63, 4, 17, 69, 62,182,176,105, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 3,233, 70, 62,154, 27, 88, 63, 9,125,119, 62,158,112, 7, 63, 8,143,152, 62,163,107, 45, 63, 3,232,212, 62,158,152, 58,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,254,136,100, 62,163,123, 38, 62,252,179,165, 62,158,140,163, 63, 3,233, 70,
- 62,154, 27, 88, 63, 3,232,212, 62,158,152, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,232,212, 62,158,152, 58,
- 63, 8,143,152, 62,163,107, 45, 63, 7, 91,121, 62,166, 51,134, 63, 3,231,205, 62,162,149, 58, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 63, 0,116, 44, 62,166, 56,255, 62,254,136,100, 62,163,123, 38, 63, 3,232,212, 62,158,152, 58, 63, 3,231,205,
- 62,162,149, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,232, 11, 62,174, 4,140, 63, 3,233,214, 62,170,154,198,
- 63, 6,110,233, 62,174,152, 94, 63, 6,138, 69, 62,177,180, 80, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 1, 82,228,
- 62,174,140, 95, 63, 3,233,214, 62,170,154,198, 63, 3,232, 11, 62,174, 4,140, 63, 1, 49, 14, 62,177,150, 62, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 6,138, 69, 62,177,180, 80, 63, 6,110,233, 62,174,152, 94, 63, 7,236, 59, 62,173,123, 19,
- 63, 8,233, 25, 62,175,110,116, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,255,185,217, 62,173,116, 92, 63, 1, 82,228,
- 62,174,140, 95, 63, 1, 49, 14, 62,177,150, 62, 62,253,195,102, 62,175,102,184, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 8,233, 25, 62,175,110,116, 63, 7,236, 59, 62,173,123, 19, 63, 7,249, 85, 62,169, 52, 92, 63, 9, 61,250, 62,168,214,252,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,255,169,160, 62,169, 57, 6, 62,255,185,217, 62,173,116, 92, 62,253,195,102,
- 62,175,102,184, 62,253, 39,110, 62,168,224,103, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 9, 61,250, 62,168,214,252,
- 63, 7,249, 85, 62,169, 52, 92, 63, 7, 91,121, 62,166, 51,134, 63, 8,143,152, 62,163,107, 45, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 63, 0,116, 44, 62,166, 56,255, 62,255,169,160, 62,169, 57, 6, 62,253, 39,110, 62,168,224,103, 62,254,136,100,
- 62,163,123, 38, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,233,214, 62,170,154,198, 63, 7,249, 85, 62,169, 52, 92,
- 63, 7,236, 59, 62,173,123, 19, 63, 6,110,233, 62,174,152, 94, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,255,185,217,
- 62,173,116, 92, 62,255,169,160, 62,169, 57, 6, 63, 3,233,214, 62,170,154,198, 63, 1, 82,228, 62,174,140, 95, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,233,214, 62,170,154,198, 63, 3,231,205, 62,162,149, 58, 63, 7, 91,121, 62,166, 51,134,
- 63, 7,249, 85, 62,169, 52, 92, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 0,116, 44, 62,166, 56,255, 63, 3,231,205,
- 62,162,149, 58, 63, 3,233,214, 62,170,154,198, 62,255,169,160, 62,169, 57, 6, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 4, 17, 69, 62,182,176,105, 63, 10,196,135, 62,178,208, 52, 63, 12,237,158, 62,187,241, 38, 63, 3,230,147, 62,208, 47, 78,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,245,175, 15, 62,188, 14,188, 62,250, 14, 98, 62,178,202,149, 63, 4, 17, 69,
- 62,182,176,105, 63, 3,230,147, 62,208, 47, 78, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 10,196,135, 62,178,208, 52,
- 63, 12, 54, 5, 62,167,183,188, 63, 16, 0,112, 62,164,246,254, 63, 12,237,158, 62,187,241, 38, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,239,187,207, 62,165, 42, 19, 62,247, 68, 98, 62,167,206,146, 62,250, 14, 98, 62,178,202,149, 62,245,175, 15,
- 62,188, 14,188, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 12, 54, 5, 62,167,183,188, 63, 9,125,119, 62,158,112, 7,
- 63, 15,250, 44, 62,154, 0,109, 63, 16, 0,112, 62,164,246,254, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239,205, 56,
- 62,154, 71, 8, 62,252,179,165, 62,158,140,163, 62,247, 68, 98, 62,167,206,146, 62,239,187,207, 62,165, 42, 19, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 9,125,119, 62,158,112, 7, 63, 8, 32, 77, 62,139, 39, 10, 63, 15,243,206, 62,136,207,182,
- 63, 15,250, 44, 62,154, 0,109, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239,193, 92, 62,137, 61,113, 62,255, 89,219,
- 62,139, 79,116, 62,252,179,165, 62,158,140,163, 62,239,205, 56, 62,154, 71, 8, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 25, 81, 20, 62,132, 56, 17, 63, 27, 46,208, 62,148, 35,149, 63, 15,250, 44, 62,154, 0,109, 63, 15,243,206, 62,136,207,182,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239,205, 56, 62,154, 71, 8, 62,217,166,238, 62,148,221,229, 62,221, 42, 54,
- 62,133, 25,209, 62,239,193, 92, 62,137, 61,113, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27, 46,208, 62,148, 35,149,
- 63, 27,177, 36, 62,156,151,158, 63, 16, 0,112, 62,164,246,254, 63, 15,250, 44, 62,154, 0,109, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,239,187,207, 62,165, 42, 19, 62,216,160, 0, 62,157, 44,127, 62,217,166,238, 62,148,221,229, 62,239,205, 56,
- 62,154, 71, 8, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,239,111, 62,166, 77,159, 63, 12,237,158, 62,187,241, 38,
- 63, 16, 0,112, 62,164,246,254, 63, 27,177, 36, 62,156,151,158, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239,187,207,
- 62,165, 42, 19, 62,245,175, 15, 62,188, 14,188, 62,216, 21,115, 62,166,177, 14, 62,216,160, 0, 62,157, 44,127, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 8,221,237, 62, 91, 90,218, 63, 3,210,147, 62, 86, 95,221, 63, 3,211,129, 62, 83,168,248,
- 63, 8, 33,170, 62, 86,149,254, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,211,129, 62, 83,168,248, 63, 3,210,147,
- 62, 86, 95,221, 62,253,153, 39, 62, 91,195, 27, 62,255, 14, 8, 62, 86,232, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 9,214, 68, 62, 66,237,246, 63, 8,221,237, 62, 91, 90,218, 63, 8, 33,170, 62, 86,149,254, 63, 8,180, 20, 62, 69, 29, 94,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,255, 14, 8, 62, 86,232, 58, 62,253,153, 39, 62, 91,195, 27, 62,251,137,104,
- 62, 67, 92,179, 62,253,210, 19, 62, 69,114, 55, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 7, 61,250, 62, 54, 31,148,
- 63, 9,214, 68, 62, 66,237,246, 63, 8,180, 20, 62, 69, 29, 94, 63, 6, 82,168, 62, 57, 43, 80, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,253,210, 19, 62, 69,114, 55, 62,251,137,104, 62, 67, 92,179, 63, 0, 87,175, 62, 54, 90,251, 63, 1, 68, 48,
- 62, 57, 84,166, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,202,193, 62, 49,174,214, 63, 7, 61,250, 62, 54, 31,148,
- 63, 6, 82,168, 62, 57, 43, 80, 63, 3,202,205, 62, 54, 22, 8, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 1, 68, 48,
- 62, 57, 84,166, 63, 0, 87,175, 62, 54, 90,251, 63, 3,202,193, 62, 49,174,214, 63, 3,202,205, 62, 54, 22, 8, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,202,205, 62, 54, 22, 8, 63, 6, 82,168, 62, 57, 43, 80, 63, 5, 24,246, 62, 66,150, 26,
- 63, 3,205,213, 62, 64,232,220, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 2,131, 29, 62, 66,172, 22, 63, 1, 68, 48,
- 62, 57, 84,166, 63, 3,202,205, 62, 54, 22, 8, 63, 3,205,213, 62, 64,232,220, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 6, 82,168, 62, 57, 43, 80, 63, 8,180, 20, 62, 69, 29, 94, 63, 6, 83, 39, 62, 70,114,191, 63, 5, 24,246, 62, 66,150, 26,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 1, 75,185, 62, 70,160,222, 62,253,210, 19, 62, 69,114, 55, 63, 1, 68, 48,
- 62, 57, 84,166, 63, 2,131, 29, 62, 66,172, 22, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 8,180, 20, 62, 69, 29, 94,
- 63, 8, 33,170, 62, 86,149,254, 63, 6,111, 4, 62, 76,172, 40, 63, 6, 83, 39, 62, 70,114,191, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 63, 1, 51,157, 62, 76,218,158, 62,255, 14, 8, 62, 86,232, 58, 62,253,210, 19, 62, 69,114, 55, 63, 1, 75,185,
- 62, 70,160,222, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 8, 33,170, 62, 86,149,254, 63, 3,211,129, 62, 83,168,248,
- 63, 3,208,234, 62, 75, 43,146, 63, 6,111, 4, 62, 76,172, 40, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,208,234,
- 62, 75, 43,146, 63, 3,211,129, 62, 83,168,248, 62,255, 14, 8, 62, 86,232, 58, 63, 1, 51,157, 62, 76,218,158, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,208,234, 62, 75, 43,146, 63, 3,205,213, 62, 64,232,220, 63, 5, 24,246, 62, 66,150, 26,
- 63, 6,111, 4, 62, 76,172, 40, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 2,131, 29, 62, 66,172, 22, 63, 3,205,213,
- 62, 64,232,220, 63, 3,208,234, 62, 75, 43,146, 63, 1, 51,157, 62, 76,218,158, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 6,111, 4, 62, 76,172, 40, 63, 5, 24,246, 62, 66,150, 26, 63, 6, 83, 39, 62, 70,114,191, 63,128, 0, 0, 63,128, 0, 0,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 1, 75,185, 62, 70,160,222, 63, 2,131, 29, 62, 66,172, 22, 63, 1, 51,157,
- 62, 76,218,158, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 13, 2, 64, 62,230,215, 52,
- 63, 14,244,149, 62,221, 42, 4, 63, 16,216, 4, 62,224, 24,160, 63, 15,200,120, 62,231,255, 84, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,237,193,119, 62,224, 38,190, 62,241,144,141, 62,221, 52,244, 62,245,100,219, 62,230,230,184, 62,239,211, 21,
- 62,232, 18,185, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 13, 25, 71, 62,243,163,116, 63, 13, 2, 64, 62,230,215, 52,
- 63, 15,200,120, 62,231,255, 84, 63, 16,171,184, 62,241,133, 40, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,239,211, 21,
- 62,232, 18,185, 62,245,100,219, 62,230,230,184, 62,245, 45, 0, 62,243,185,206, 62,237,252,218, 62,241,160, 62, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 17, 59,103, 62,255,195,120, 63, 13, 25, 71, 62,243,163,116, 63, 16,171,184, 62,241,133, 40,
- 63, 19, 44, 55, 62,250, 21, 86, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,237,252,218, 62,241,160, 62, 62,245, 45, 0,
- 62,243,185,206, 62,236,213,209, 62,255,250, 4, 62,232,228,153, 62,250, 67,154, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 14,244,149, 62,221, 42, 4, 63, 17, 97, 15, 62,214, 34,220, 63, 19, 53,217, 62,218,211, 16, 63, 16,216, 4, 62,224, 24,160,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,233, 14, 8, 62,218,226, 66, 62,236,200,217, 62,214, 49,134, 62,241,144,141,
- 62,221, 52,244, 62,237,193,119, 62,224, 38,190, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 17, 97, 15, 62,214, 34,220,
- 63, 27,178,165, 62,208, 17,128, 63, 26,198,205, 62,214,184,124, 63, 19, 53,217, 62,218,211, 16, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,217,214,216, 62,214,224,218, 62,216, 24, 6, 62,208, 57,128, 62,236,200,217, 62,214, 49,134, 62,233, 14, 8,
- 62,218,226, 66, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,178,165, 62,208, 17,128, 63, 33,120, 14, 62,214,238,166,
- 63, 31,136,156, 62,219,138,194, 63, 26,198,205, 62,214,184,124, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,208, 30,254,
- 62,219,177,204, 62,204, 75,168, 62,215, 7, 62, 62,216, 24, 6, 62,208, 57,128, 62,217,214,216, 62,214,224,218, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 33,120, 14, 62,214,238,166, 63, 38,149,140, 62,229, 95, 38, 63, 36, 9, 79, 62,229,224, 94,
- 63, 31,136,156, 62,219,138,194, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,198,192,148, 62,230, 11,182, 62,193,140,168,
- 62,229,129, 94, 62,204, 75,168, 62,215, 7, 62, 62,208, 30,254, 62,219,177,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 38,149,140, 62,229, 95, 38, 63, 39, 62, 92, 62,240, 75,121, 63, 36, 49, 14, 62,239, 88,253, 63, 36, 9, 79, 62,229,224, 94,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,198, 71, 97, 62,239,149,192, 62,192, 10,222, 62,240,128,163, 62,193,140,168,
- 62,229,129, 94, 62,198,192,148, 62,230, 11,182, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 39, 62, 92, 62,240, 75,121,
- 63, 37,113, 25, 62,247,157, 35, 63, 35, 33,243, 62,245,143, 80, 63, 36, 49, 14, 62,239, 88,253, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,200, 99, 87, 62,245,217,172, 62,195,165,189, 62,247,232,139, 62,192, 10,222, 62,240,128,163, 62,198, 71, 97,
- 62,239,149,192, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 37,113, 25, 62,247,157, 35, 63, 30, 49, 96, 62,254,229,121,
- 63, 29, 49,223, 62,250,140,199, 63, 35, 33,243, 62,245,143, 80, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,212,124,147,
- 62,250,215,146, 62,210,116,176, 62,255, 62,227, 62,195,165,189, 62,247,232,139, 62,200, 99, 87, 62,245,217,172, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 30, 49, 96, 62,254,229,121, 63, 25,182,151, 63, 1, 9,130, 63, 25,181, 50, 62,253,111,118,
- 63, 29, 49,223, 62,250,140,199, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,219,151, 52, 62,253,186, 68, 62,219,150,213,
- 63, 1, 55, 50, 62,210,116,176, 62,255, 62,227, 62,212,124,147, 62,250,215,146, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 25,182,151, 63, 1, 9,130, 63, 22, 81,240, 63, 1, 70,114, 63, 22,188,241, 62,253,149, 28, 63, 25,181, 50, 62,253,111,118,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,225,163,212, 62,253,215, 91, 62,226,128,106, 63, 1,111,198, 62,219,150,213,
- 63, 1, 55, 50, 62,219,151, 52, 62,253,186, 68, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 22, 81,240, 63, 1, 70,114,
- 63, 17, 59,103, 62,255,195,120, 63, 19, 44, 55, 62,250, 21, 86, 63, 22,188,241, 62,253,149, 28, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,232,228,153, 62,250, 67,154, 62,236,213,209, 62,255,250, 4, 62,226,128,106, 63, 1,111,198, 62,225,163,212,
- 62,253,215, 91, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 22,188,241, 62,253,149, 28, 63, 19, 44, 55, 62,250, 21, 86,
- 63, 20,165, 9, 62,247, 99,248, 63, 23, 0, 20, 62,251, 57, 6, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,229,232,232,
- 62,247,142, 74, 62,232,228,153, 62,250, 67,154, 62,225,163,212, 62,253,215, 91, 62,225, 26,145, 62,251,116,114, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 25,181, 50, 62,253,111,118, 63, 22,188,241, 62,253,149, 28, 63, 23, 0, 20, 62,251, 57, 6,
- 63, 25,144,130, 62,251, 7,128, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,225, 26,145, 62,251,116,114, 62,225,163,212,
- 62,253,215, 91, 62,219,151, 52, 62,253,186, 68, 62,219,225,177, 62,251, 75, 67, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 29, 49,223, 62,250,140,199, 63, 25,181, 50, 62,253,111,118, 63, 25,144,130, 62,251, 7,128, 63, 28,195, 80, 62,248,166, 55,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,219,225,177, 62,251, 75, 67, 62,219,151, 52, 62,253,186, 68, 62,212,124,147,
- 62,250,215,146, 62,213, 95,233, 62,248,237, 20, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 35, 33,243, 62,245,143, 80,
- 63, 29, 49,223, 62,250,140,199, 63, 28,195, 80, 62,248,166, 55, 63, 33,164, 22, 62,243, 75,102, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,213, 95,233, 62,248,237, 20, 62,212,124,147, 62,250,215,146, 62,200, 99, 87, 62,245,217,172, 62,203,114, 65,
- 62,243,143,159, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 36, 49, 14, 62,239, 88,253, 63, 35, 33,243, 62,245,143, 80,
- 63, 33,164, 22, 62,243, 75,102, 63, 34,160, 30, 62,238, 47,169, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,203,114, 65,
- 62,243,143,159, 62,200, 99, 87, 62,245,217,172, 62,198, 71, 97, 62,239,149,192, 62,201,128,188, 62,238,110,126, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 36, 9, 79, 62,229,224, 94, 63, 36, 49, 14, 62,239, 88,253, 63, 34,160, 30, 62,238, 47,169,
- 63, 34,144,131, 62,231, 87,253, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,201,128,188, 62,238,110,126, 62,198, 71, 97,
- 62,239,149,192, 62,198,192,148, 62,230, 11,182, 62,201,190,141, 62,231,140,124, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 31,136,156, 62,219,138,194, 63, 36, 9, 79, 62,229,224, 94, 63, 34,144,131, 62,231, 87,253, 63, 30,208, 21, 62,221,182,174,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,201,190,141, 62,231,140,124, 62,198,192,148, 62,230, 11,182, 62,208, 30,254,
- 62,219,177,204, 62,209,133,168, 62,221,221, 51, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 26,198,205, 62,214,184,124,
- 63, 31,136,156, 62,219,138,194, 63, 30,208, 21, 62,221,182,174, 63, 26,218,128, 62,217,206, 68, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,209,133,168, 62,221,221, 51, 62,208, 30,254, 62,219,177,204, 62,217,214,216, 62,214,224,218, 62,217,157, 11,
- 62,217,243, 64, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 19, 53,217, 62,218,211, 16, 63, 26,198,205, 62,214,184,124,
- 63, 26,218,128, 62,217,206, 68, 63, 20, 53,103, 62,221, 84,236, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,217,157, 11,
- 62,217,243, 64, 62,217,214,216, 62,214,224,218, 62,233, 14, 8, 62,218,226, 66, 62,231, 5, 68, 62,221,101,234, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 16,216, 4, 62,224, 24,160, 63, 19, 53,217, 62,218,211, 16, 63, 20, 53,103, 62,221, 84,236,
- 63, 18, 87, 81, 62,226,175, 33, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,231, 5, 68, 62,221,101,234, 62,233, 14, 8,
- 62,218,226, 66, 62,237,193,119, 62,224, 38,190, 62,234,187,180, 62,226,190,249, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 19, 44, 55, 62,250, 21, 86, 63, 16,171,184, 62,241,133, 40, 63, 18, 68, 98, 62,240,197,150, 63, 20,165, 9, 62,247, 99,248,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,234,197, 35, 62,240,226,215, 62,237,252,218, 62,241,160, 62, 62,232,228,153,
- 62,250, 67,154, 62,229,232,232, 62,247,142, 74, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 16,171,184, 62,241,133, 40,
- 63, 15,200,120, 62,231,255, 84, 63, 18, 4,161, 62,232,184,138, 63, 18, 68, 98, 62,240,197,150, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,235, 85,154, 62,232,206, 92, 62,239,211, 21, 62,232, 18,185, 62,237,252,218, 62,241,160, 62, 62,234,197, 35,
- 62,240,226,215, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 15,200,120, 62,231,255, 84, 63, 16,216, 4, 62,224, 24,160,
- 63, 18, 87, 81, 62,226,175, 33, 63, 18, 4,161, 62,232,184,138, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,234,187,180,
- 62,226,190,249, 62,237,193,119, 62,224, 38,190, 62,239,211, 21, 62,232, 18,185, 62,235, 85,154, 62,232,206, 92, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 3,232,148, 63, 11, 17,164, 63, 11,169, 67, 63, 11,197, 18, 63, 13,120,216, 63, 23, 81,160,
- 63, 4, 15,147, 63, 23,248,227, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,245, 27, 64, 63, 23,166,100, 62,248, 72, 55,
- 63, 11,232, 91, 63, 3,232,148, 63, 11, 17,164, 63, 4, 15,147, 63, 23,248,227, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 11,169, 67, 63, 11,197, 18, 63, 22,244,173, 63, 11,215,236, 63, 23,233, 94, 63, 16, 60,186, 63, 13,120,216, 63, 23, 81,160,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,223,130,109, 63, 16,165,118, 62,225, 89,220, 63, 12, 42, 77, 62,248, 72, 55,
- 63, 11,232, 91, 62,245, 27, 64, 63, 23,166,100, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 22,244,173, 63, 11,215,236,
- 63, 26,105, 28, 63, 11,194,242, 63, 28, 56,220, 63, 14,250, 66, 63, 23,233, 94, 63, 16, 60,186, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,214,161,157, 63, 15,110,219, 62,218, 73,220, 63, 12, 31,169, 62,225, 89,220, 63, 12, 42, 77, 62,223,130,109,
- 63, 16,165,118, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 26,105, 28, 63, 11,194,242, 63, 34,158,220, 63, 10, 23,175,
- 63, 39, 44,109, 63, 19,221,107, 63, 28, 56,220, 63, 14,250, 66, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,192, 26,156,
- 63, 20,139, 31, 62,201,109,124, 63, 10,121, 72, 62,218, 73,220, 63, 12, 31,169, 62,214,161,157, 63, 15,110,219, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 34,158,220, 63, 10, 23,175, 63, 46, 88,238, 63, 2,223,146, 63, 56, 80,242, 63, 6,244, 44,
- 63, 39, 44,109, 63, 19,221,107, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 62,156,208, 61, 63, 7, 16,204, 62,177, 87,173,
- 63, 3, 9,102, 62,201,109,124, 63, 10,121, 72, 62,192, 26,156, 63, 20,139, 31, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16,
- 63, 46, 88,238, 63, 2,223,146, 63, 48,134, 62, 62,249,107, 37, 63, 54,173,195, 62,252,106,239, 63, 56, 80,242, 63, 6,244, 44,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 62,160, 36,202, 62,252, 51, 94, 62,172,229,172, 62,249,127,116, 62,177, 87,173,
- 63, 3, 9,102, 62,156,208, 61, 63, 7, 16,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 63, 48,134, 62, 62,249,107, 37,
- 63, 50,229, 38, 62,226, 32,169, 63, 53, 88,154, 62,221,146,240, 63, 54,173,195, 62,252,106,239, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 64, 62,162,172,128, 62,221,169, 17, 62,168, 39,196, 62,226, 11,206, 62,172,229,172, 62,249,127,116, 62,160, 36,202,
- 62,252, 51, 94, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 63, 50,229, 38, 62,226, 32,169, 63, 43, 57, 87, 62,206, 58,222,
- 63, 49,117,240, 62,198,138,164, 63, 53, 88,154, 62,221,146,240, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 62,172,137,147,
- 62,198, 19,148, 62,184,207,130, 62,206, 27, 42, 62,168, 39,196, 62,226, 11,206, 62,162,172,128, 62,221,169, 17, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0,128, 63, 43, 57, 87, 62,206, 58,222, 63, 37, 94, 91, 62,187,120,107, 63, 41,160,156, 62,182,175, 56,
- 63, 49,117,240, 62,198,138,164, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,188,212,202, 62,182,163,245, 62,197, 28,156,
- 62,187,130,166, 62,184,207,130, 62,206, 27, 42, 62,172,137,147, 62,198, 19,148, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 48,252,165, 62, 85, 33,133, 63, 48, 54,112, 62, 96, 19, 20, 63, 46, 36,172, 62,129, 7,208, 63, 42, 17,240, 62, 97, 84,129,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,181, 71, 76, 62,131,200,204, 62,175,121,117, 62,106,185,183, 62,172, 24,217,
- 62, 92,237, 21, 62,187, 81,138, 62,103, 40, 59, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 48, 89,204, 62, 4,194,134,
- 63, 48,252,165, 62, 85, 33,133, 63, 42, 17,240, 62, 97, 84,129, 63, 37,125,160, 62, 46,211, 50, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 16, 62,187, 81,138, 62,103, 40, 59, 62,172, 24,217, 62, 92,237, 21, 62,172,197, 94, 62, 4,200,109, 62,195,121, 25,
- 62, 48,253, 46, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 63, 20, 44, 11, 61,163, 26, 20, 63, 48, 89,204, 62, 4,194,134,
- 63, 37,125,160, 62, 46,211, 50, 63, 24, 92, 40, 62, 21,184,214, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 62,195,121, 25,
- 62, 48,253, 46, 62,172,197, 94, 62, 4,200,109, 62,230,122,140, 61,161,248,202, 62,222, 13,216, 62, 22,116,222, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 32, 63, 16,254,174, 62, 34, 45, 94, 63, 3,199,219, 61,229, 28, 18, 63, 20, 44, 11, 61,163, 26, 20,
- 63, 24, 92, 40, 62, 21,184,214, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 62,230,122,140, 61,161,248,202, 63, 3,199,219,
- 61,229, 28, 18, 62,236,248,140, 62, 34,202,182, 62,222, 13,216, 62, 22,116,222, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64,
- 63, 21,152,184, 62, 53, 47,182, 63, 16,254,174, 62, 34, 45, 94, 63, 24, 92, 40, 62, 21,184,214, 63, 25, 52,209, 62, 51,140, 76,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 62,222, 13,216, 62, 22,116,222, 62,236,248,140, 62, 34,202,182, 62,227,207,183,
- 62, 54, 75,250, 62,220,137,229, 62, 52,228,185, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 63, 22, 57,137, 62, 61, 93, 81,
- 63, 21,152,184, 62, 53, 47,182, 63, 25, 52,209, 62, 51,140, 76, 63, 30,166,193, 62, 73,168,114, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,220,137,229, 62, 52,228,185, 62,227,207,183, 62, 54, 75,250, 62,226,152,122, 62, 62,166,190, 62,209,198, 54,
- 62, 75,240, 18, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 22,249,250, 62, 88,251,160, 63, 22, 57,137, 62, 61, 93, 81,
- 63, 30,166,193, 62, 73,168,114, 63, 36, 0, 75, 62,116, 47,229, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,209,198, 54,
- 62, 75,240, 18, 62,226,152,122, 62, 62,166,190, 62,225, 83, 90, 62, 90,153, 21, 62,199,231,211, 62,119,237,216, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 30,166,193, 62, 73,168,114, 63, 37,125,160, 62, 46,211, 50, 63, 42, 17,240, 62, 97, 84,129,
- 63, 36, 0, 75, 62,116, 47,229, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,187, 81,138, 62,103, 40, 59, 62,195,121, 25,
- 62, 48,253, 46, 62,209,198, 54, 62, 75,240, 18, 62,199,231,211, 62,119,237,216, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 30,166,193, 62, 73,168,114, 63, 25, 52,209, 62, 51,140, 76, 63, 24, 92, 40, 62, 21,184,214, 63, 37,125,160, 62, 46,211, 50,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,222, 13,216, 62, 22,116,222, 62,220,137,229, 62, 52,228,185, 62,209,198, 54,
- 62, 75,240, 18, 62,195,121, 25, 62, 48,253, 46, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 36,163, 37, 62,140,168,191,
- 63, 36, 0, 75, 62,116, 47,229, 63, 42, 17,240, 62, 97, 84,129, 63, 46, 36,172, 62,129, 7,208, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,187, 81,138, 62,103, 40, 59, 62,199,231,211, 62,119,237,216, 62,199, 64, 6, 62,142, 6,105, 62,181, 71, 76,
- 62,131,200,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 25, 81, 20, 62,132, 56, 17, 63, 22,249,250, 62, 88,251,160,
- 63, 36, 0, 75, 62,116, 47,229, 63, 36,163, 37, 62,140,168,191, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,199,231,211,
- 62,119,237,216, 62,225, 83, 90, 62, 90,153, 21, 62,221, 42, 54, 62,133, 25,209, 62,199, 64, 6, 62,142, 6,105, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 27, 46,208, 62,148, 35,149, 63, 36, 60, 91, 62,150,222,221, 63, 33,170,222, 62,158,126, 74,
- 63, 27,177, 36, 62,156,151,158, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,204,234, 72, 62,159, 63, 56, 62,199,245,150,
- 62,152, 15, 85, 62,217,166,238, 62,148,221,229, 62,216,160, 0, 62,157, 44,127, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 25, 81, 20, 62,132, 56, 17, 63, 36,163, 37, 62,140,168,191, 63, 36, 60, 91, 62,150,222,221, 63, 27, 46,208, 62,148, 35,149,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,199,245,150, 62,152, 15, 85, 62,199, 64, 6, 62,142, 6,105, 62,221, 42, 54,
- 62,133, 25,209, 62,217,166,238, 62,148,221,229, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,239,111, 62,166, 77,159,
- 63, 27,177, 36, 62,156,151,158, 63, 33,170,222, 62,158,126, 74, 63, 31,212,102, 62,164,192,144, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,204,234, 72, 62,159, 63, 56, 62,216,160, 0, 62,157, 44,127, 62,216, 21,115, 62,166,177, 14, 62,208,119, 17,
- 62,165, 65,201, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 27,239,111, 62,166, 77,159, 63, 31,212,102, 62,164,192,144,
- 63, 41,160,156, 62,182,175, 56, 63, 37, 94, 91, 62,187,120,107, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,188,212,202,
- 62,182,163,245, 62,208,119, 17, 62,165, 65,201, 62,216, 21,115, 62,166,177, 14, 62,197, 28,156, 62,187,130,166, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 62,194,119,104, 63, 82,189,164, 62,212, 73, 23, 63, 90,239,152, 62,205,192,100, 63, 97,238, 46,
- 62,185, 56, 38, 63, 91,154, 72, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,141, 94,228, 63,100,234, 86, 62,150, 66, 84,
- 63, 94,154,114, 62,173, 86,230, 63, 98, 66, 79, 62,162,143, 20, 63,106,173, 44, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240,
- 63, 87,122, 72, 62, 62, 8,216, 63, 84,106,202, 62,113,185,137, 63, 72, 77,226, 62,121, 21,204, 63, 71,225,158, 62, 68, 34,113,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 62,137, 32,132, 62,121, 65,181, 62,107,179,168, 62,103,127,139, 62,114,147,210,
- 62, 61,116,212, 62,142,125,248, 62, 80, 4, 30, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 63, 71,225,158, 62, 68, 34,113,
- 63, 72, 77,226, 62,121, 21,204, 63, 51, 7, 8, 62,130,186, 5, 63, 49,166, 3, 62, 96, 57,232, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,172,197, 18, 62,133,112, 41, 62,137, 32,132, 62,121, 65,181, 62,142,125,248, 62, 80, 4, 30, 62,174,228,121,
- 62,109, 79, 52, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 49,166, 3, 62, 96, 57,232, 63, 51, 7, 8, 62,130,186, 5,
- 63, 46, 36,172, 62,129, 7,208, 63, 48, 54,112, 62, 96, 19, 20, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,181, 71, 76,
- 62,131,200,204, 62,172,197, 18, 62,133,112, 41, 62,174,228,121, 62,109, 79, 52, 62,175,121,117, 62,106,185,183, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 36,163, 37, 62,140,168,191, 63, 46, 36,172, 62,129, 7,208, 63, 51, 7, 8, 62,130,186, 5,
- 63, 36, 60, 91, 62,150,222,221, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,172,197, 18, 62,133,112, 41, 62,181, 71, 76,
- 62,131,200,204, 62,199, 64, 6, 62,142, 6,105, 62,199,245,150, 62,152, 15, 85, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 53, 88,154, 62,221,146,240, 63, 49,117,240, 62,198,138,164, 63, 69, 19,224, 62,190, 68, 24, 63, 74, 64, 53, 62,224, 31,171,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 62,134, 78,250, 62,186,213,148, 62,172,137,147, 62,198, 19,148, 62,162,172,128,
- 62,221,169, 17, 62,114,112,184, 62,220,169,248, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 62,214, 74, 54, 63, 70, 55, 20,
- 62,233,130, 48, 63, 83, 69,188, 62,212, 73, 23, 63, 90,239,152, 62,194,119,104, 63, 82,189,164, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,150, 66, 84, 63, 94,154,114, 62,153, 1, 66, 63, 81,149,245, 62,185, 56, 38, 63, 83,110,102, 62,173, 86,230,
- 63, 98, 66, 79, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 63, 66,242,106, 63, 25, 94,202, 63, 70,100,190, 63, 15,234,222,
- 63, 77,189, 90, 63, 17, 88,233, 63, 74,206, 8, 63, 27,118, 88, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 96, 32, 22,
- 63, 16, 60, 66, 62,125, 87, 86, 63, 15, 5,174, 62,132,187, 78, 63, 24, 44,180, 62,108, 79, 26, 63, 26, 1,124, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 74,206, 8, 63, 27,118, 88, 63, 77,189, 90, 63, 17, 88,233, 63, 85,139, 72, 63, 19, 51,103,
- 63, 85,119,220, 63, 31, 71, 77, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 64,199, 64, 63, 18, 40, 26, 62, 96, 32, 22,
- 63, 16, 60, 66, 62,108, 79, 26, 63, 26, 1,124, 62, 67,191, 44, 63, 30, 89, 90, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 85,119,220, 63, 31, 71, 77, 63, 85,139, 72, 63, 19, 51,103, 63,100,213,228, 63, 20,156, 72, 63, 96, 82, 18, 63, 34,133,128,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 62, 1, 50,226, 63, 20, 68,184, 62, 64,199, 64, 63, 18, 40, 26, 62, 67,191, 44,
- 63, 30, 89, 90, 62, 24,204,194, 63, 34,186, 32, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 63, 56, 80,242, 63, 6,244, 44,
- 63, 54,173,195, 62,252,106,239, 63, 60,205,115, 62,253,150,213, 63, 64, 14,166, 63, 4, 80, 81, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 16, 62,147, 85,190, 62,252,176, 91, 62,160, 36,202, 62,252, 51, 94, 62,156,208, 61, 63, 7, 16,204, 62,140,121,160,
- 63, 3,197, 74, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 63, 64, 14,166, 63, 4, 80, 81, 63, 60,205,115, 62,253,150,213,
- 63, 73,103, 68, 63, 0,248,233, 63, 75, 12,248, 63, 8,206, 64, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,115, 59,144,
- 62,255,143,102, 62,147, 85,190, 62,252,176, 91, 62,140,121,160, 63, 3,197, 74, 62,107,135, 78, 63, 7,182, 88, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 75, 12,248, 63, 8,206, 64, 63, 73,103, 68, 63, 0,248,233, 63, 82,151,239, 63, 3,223, 86,
- 63, 82,227,181, 63, 11,102,189, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 77, 17, 82, 63, 2, 98,162, 62,115, 59,144,
- 62,255,143,102, 62,107,135, 78, 63, 7,182, 88, 62, 75, 98,202, 63, 10, 43,108, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 82,227,181, 63, 11,102,189, 63, 82,151,239, 63, 3,223, 86, 63, 91,224, 92, 63, 5,144,239, 63, 90,148,161, 63, 13, 95,146,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 38, 40,178, 63, 3,230, 14, 62, 77, 17, 82, 63, 2, 98,162, 62, 75, 98,202,
- 63, 10, 43,108, 62, 43,162, 10, 63, 12, 50, 8, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,103, 89,120, 63, 2, 76,105,
- 63,103,179,170, 63, 12,105,142, 63, 90,148,161, 63, 13, 95,146, 63, 91,224, 92, 63, 5,144,239, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 43,162, 10, 63, 12, 50, 8, 61,231, 41,168, 63, 11, 83,158, 61,234,128,116, 63, 0, 39,200, 62, 38, 40,178,
- 63, 3,230, 14, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,100,213,228, 63, 20,156, 72, 63, 85,139, 72, 63, 19, 51,103,
- 63, 90,148,161, 63, 13, 95,146, 63,103,179,170, 63, 12,105,142, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 43,162, 10,
- 63, 12, 50, 8, 62, 64,199, 64, 63, 18, 40, 26, 62, 1, 50,226, 63, 20, 68,184, 61,231, 41,168, 63, 11, 83,158, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 85,139, 72, 63, 19, 51,103, 63, 77,189, 90, 63, 17, 88,233, 63, 82,227,181, 63, 11,102,189,
- 63, 90,148,161, 63, 13, 95,146, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 75, 98,202, 63, 10, 43,108, 62, 96, 32, 22,
- 63, 16, 60, 66, 62, 64,199, 64, 63, 18, 40, 26, 62, 43,162, 10, 63, 12, 50, 8, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 77,189, 90, 63, 17, 88,233, 63, 70,100,190, 63, 15,234,222, 63, 75, 12,248, 63, 8,206, 64, 63, 82,227,181, 63, 11,102,189,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,107,135, 78, 63, 7,182, 88, 62,125, 87, 86, 63, 15, 5,174, 62, 96, 32, 22,
- 63, 16, 60, 66, 62, 75, 98,202, 63, 10, 43,108, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 70,100,190, 63, 15,234,222,
- 63, 60,235, 82, 63, 12, 12, 27, 63, 64, 14,166, 63, 4, 80, 81, 63, 75, 12,248, 63, 8,206, 64, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,140,121,160, 63, 3,197, 74, 62,145,230, 78, 63, 11,225,148, 62,125, 87, 86, 63, 15, 5,174, 62,107,135, 78,
- 63, 7,182, 88, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 57,118, 31, 63, 12, 79,230, 63, 56, 80,242, 63, 6,244, 44,
- 63, 64, 14,166, 63, 4, 80, 81, 63, 60,235, 82, 63, 12, 12, 27, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 62,140,121,160,
- 63, 3,197, 74, 62,156,208, 61, 63, 7, 16,204, 62,152,199, 0, 63, 12,133, 13, 62,145,230, 78, 63, 11,225,148, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 32, 63, 57,240,195, 63, 23,138, 10, 63, 60,235, 82, 63, 12, 12, 27, 63, 70,100,190, 63, 15,234,222,
- 63, 66,242,106, 63, 25, 94,202, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,125, 87, 86, 63, 15, 5,174, 62,145,230, 78,
- 63, 11,225,148, 62,150, 7,247, 63, 23, 12, 96, 62,132,187, 78, 63, 24, 44,180, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 13,120,216, 63, 23, 81,160, 63, 23,233, 94, 63, 16, 60,186, 63, 28, 56,220, 63, 14,250, 66, 63, 39, 44,109, 63, 19,221,107,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,214,161,157, 63, 15,110,219, 62,223,130,109, 63, 16,165,118, 62,245, 27, 64,
- 63, 23,166,100, 62,192, 26,156, 63, 20,139, 31, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 56, 29,176, 63, 20,206, 88,
- 63, 57,118, 31, 63, 12, 79,230, 63, 60,235, 82, 63, 12, 12, 27, 63, 57,240,195, 63, 23,138, 10, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,145,230, 78, 63, 11,225,148, 62,152,199, 0, 63, 12,133, 13, 62,153,211,239, 63, 20,159,220, 62,150, 7,247,
- 63, 23, 12, 96, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 54,148, 48, 63, 22,206,220, 63, 56, 29,176, 63, 20,206, 88,
- 63, 57,240,195, 63, 23,138, 10, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,150, 7,247,
- 63, 23, 12, 96, 62,153,211,239, 63, 20,159,220, 62,156,106,108, 63, 22,154,146, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 54,173,195, 62,252,106,239, 63, 53, 88,154, 62,221,146,240, 63, 74, 64, 53, 62,224, 31,171,
- 63, 60,205,115, 62,253,150,213, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 62,114,112,184, 62,220,169,248, 62,162,172,128,
- 62,221,169, 17, 62,160, 36,202, 62,252, 51, 94, 62,147, 85,190, 62,252,176, 91, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32,
- 63, 74, 64, 53, 62,224, 31,171, 63, 81,106,217, 62,232,214, 14, 63, 73,103, 68, 63, 0,248,233, 63, 60,205,115, 62,253,150,213,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,115, 59,144, 62,255,143,102, 62, 84, 93, 88, 62,228,105, 50, 62,114,112,184,
- 62,220,169,248, 62,147, 85,190, 62,252,176, 91, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 81,106,217, 62,232,214, 14,
- 63, 93,154,106, 62,233, 26,226, 63, 82,151,239, 63, 3,223, 86, 63, 73,103, 68, 63, 0,248,233, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 77, 17, 82, 63, 2, 98,162, 62, 33, 1,128, 62,226,210, 70, 62, 84, 93, 88, 62,228,105, 50, 62,115, 59,144,
- 62,255,143,102, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,103, 89,120, 63, 2, 76,105, 63, 91,224, 92, 63, 5,144,239,
- 63, 82,151,239, 63, 3,223, 86, 63, 93,154,106, 62,233, 26,226, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 77, 17, 82,
- 63, 2, 98,162, 62, 38, 40,178, 63, 3,230, 14, 61,234,128,116, 63, 0, 39,200, 62, 33, 1,128, 62,226,210, 70, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 51, 7, 8, 62,130,186, 5, 63, 72, 77,226, 62,121, 21,204, 63, 73,254,154, 62,140, 82,178,
- 63, 56,188, 90, 62,159,207,103, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,130,249,249, 62,137,175,246, 62,137, 32,132,
- 62,121, 65,181, 62,172,197, 18, 62,133,112, 41, 62,161, 5,192, 62,159, 40,228, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 69, 19,224, 62,190, 68, 24, 63, 56,188, 90, 62,159,207,103, 63, 73,254,154, 62,140, 82,178, 63, 77,217,216, 62,157,228, 7,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 62,130,249,249, 62,137,175,246, 62,161, 5,192, 62,159, 40,228, 62,134, 78,250,
- 62,186,213,148, 62,111,118,154, 62,152,108,120, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 63, 49,117,240, 62,198,138,164,
- 63, 41,160,156, 62,182,175, 56, 63, 56,188, 90, 62,159,207,103, 63, 69, 19,224, 62,190, 68, 24, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62,161, 5,192, 62,159, 40,228, 62,188,212,202, 62,182,163,245, 62,172,137,147, 62,198, 19,148, 62,134, 78,250,
- 62,186,213,148, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 41,160,156, 62,182,175, 56, 63, 33,170,222, 62,158,126, 74,
- 63, 36, 60, 91, 62,150,222,221, 63, 56,188, 90, 62,159,207,103, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,199,245,150,
- 62,152, 15, 85, 62,204,234, 72, 62,159, 63, 56, 62,188,212,202, 62,182,163,245, 62,161, 5,192, 62,159, 40,228, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 36, 60, 91, 62,150,222,221, 63, 51, 7, 8, 62,130,186, 5, 63, 56,188, 90, 62,159,207,103,
- 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,161, 5,192, 62,159, 40,228, 62,172,197, 18,
- 62,133,112, 41, 62,199,245,150, 62,152, 15, 85, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 41,160,156, 62,182,175, 56, 63, 31,212,102, 62,164,192,144, 63, 33,170,222, 62,158,126, 74, 63,128, 0, 0, 63,128, 0, 0,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,204,234, 72, 62,159, 63, 56, 62,208,119, 17, 62,165, 65,201, 62,188,212,202,
- 62,182,163,245, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,245, 44,226, 63, 96,140,129,
- 62,227,135, 42, 63,101, 2, 58, 62,219,168,136, 63, 95,236, 30, 62,238, 30,135, 63, 90, 41,200, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62,137,240,216, 63, 93,226, 90, 62,122,103,110, 63, 92,255,236, 62,120, 84, 74, 63, 83, 32,104, 62,138,193, 32,
- 63, 83, 3, 16, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,233,130, 48, 63, 83, 69,188, 62,238, 30,135, 63, 90, 41,200,
- 62,219,168,136, 63, 95,236, 30, 62,212, 73, 23, 63, 90,239,152, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62,137,240,216,
- 63, 93,226, 90, 62,138,193, 32, 63, 83, 3, 16, 62,153, 1, 66, 63, 81,149,245, 62,150, 66, 84, 63, 94,154,114, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0,240, 63, 77,217,216, 62,157,228, 7, 63, 73,254,154, 62,140, 82,178, 63, 90, 61, 33, 62,124,207,195,
- 63, 90,225,160, 62,137,121,110, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 62, 81,207, 98, 62,110, 1,109, 62,130,249,249,
- 62,137,175,246, 62,111,118,154, 62,152,108,120, 62, 74,125,166, 62,130, 30,252, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64,
- 63, 72, 77,226, 62,121, 21,204, 63, 84,106,202, 62,113,185,137, 63, 90, 61, 33, 62,124,207,195, 63, 73,254,154, 62,140, 82,178,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 81,207, 98, 62,110, 1,109, 62,107,179,168, 62,103,127,139, 62,137, 32,132,
- 62,121, 65,181, 62,130,249,249, 62,137,175,246, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,212, 73, 23, 63, 90,239,152,
- 62,219,168,136, 63, 95,236, 30, 62,205,192,100, 63, 97,238, 46, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,112, 62,141, 94,228, 63,100,234, 86, 62,137,240,216, 63, 93,226, 90, 62,150, 66, 84, 63, 94,154,114, 63,128, 0, 0,
- 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 63,109,178, 31, 62,228, 68,224, 63,102,178, 46, 62,232,184,100,
- 63,101,251,100, 62,227,198,238, 63,107,173, 94, 62,225,130,168, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,249,209, 68,
- 62,219,134, 70, 61,242,216,120, 62,225, 40,124, 61,177, 27, 28, 62,219,240, 42, 61,196,131, 76, 62,216, 97,196, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,109,178, 31, 62,228, 68,224, 63,107,173, 94, 62,225,130,168, 63,114,102,144, 62,220, 23,198,
- 63,116, 76, 41, 62,222,153,139, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,120,163, 56, 62,208,252, 58, 61,196,131, 76,
- 62,216, 97,196, 61,177, 27, 28, 62,219,240, 42, 61, 73,183,128, 62,213,108, 84, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,116, 76, 41, 62,222,153,139, 63,114,102,144, 62,220, 23,198, 63,117, 87, 84, 62,211,255,221, 63,119,115,183, 62,215, 49,140,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61, 55, 29,144, 62,194,183,207, 61,120,163, 56, 62,208,252, 58, 61, 73,183,128,
- 62,213,108, 84, 60,231,111,224, 62,198,142,100, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,119,115,183, 62,215, 49,140,
- 63,117, 87, 84, 62,211,255,221, 63,118, 20,150, 62,196,110, 60, 63,122, 12, 49, 62,197, 8,246, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,103,197, 96, 62,170,206, 15, 61, 55, 29,144, 62,194,183,207, 60,231,111,224, 62,198,142,100, 61, 16, 54,240,
- 62,167, 4,120, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,122, 12, 49, 62,197, 8,246, 63,118, 20,150, 62,196,110, 60,
- 63,108,155, 17, 62,178,201,130, 63,110,190, 84, 62,172, 77,223, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,246,252,148,
- 62,160,116,164, 61,103,197, 96, 62,170,206, 15, 61, 16, 54,240, 62,167, 4,120, 61,246, 66, 8, 62,152,161, 28, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,110,190, 84, 62,172, 77,223, 63,108,155, 17, 62,178,201,130, 63, 92,180, 21, 62,173, 95,202,
- 63, 90, 5,151, 62,167, 61,138, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 54,216,144, 62,163, 76, 35, 61,246,252,148,
- 62,160,116,164, 61,246, 66, 8, 62,152,161, 28, 62, 66,251,194, 62,158,102,163, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,108,155, 17, 62,178,201,130, 63,109,132,198, 62,186,157,182, 63, 97, 32, 68, 62,178, 12,192, 63, 92,180, 21, 62,173, 95,202,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 36,185, 48, 62,166, 7, 16, 61,221, 91, 40, 62,167,194, 4, 61,246,252,148,
- 62,160,116,164, 62, 54,216,144, 62,163, 76, 35, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,118, 20,150, 62,196,110, 60,
- 63,115,225, 84, 62,198, 85,208, 63,109,132,198, 62,186,157,182, 63,108,155, 17, 62,178,201,130, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,221, 91, 40, 62,167,194, 4, 61,134,221,244, 62,175,164,121, 61,103,197, 96, 62,170,206, 15, 61,246,252,148,
- 62,160,116,164, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,117, 87, 84, 62,211,255,221, 63,116, 48,222, 62,209, 8,169,
- 63,115,225, 84, 62,198, 85,208, 63,118, 20,150, 62,196,110, 60, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,134,221,244,
- 62,175,164,121, 61, 93,108,160, 62,190,207, 17, 61, 55, 29,144, 62,194,183,207, 61,103,197, 96, 62,170,206, 15, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,114,102,144, 62,220, 23,198, 63,113,151,174, 62,214,229, 26, 63,116, 48,222, 62,209, 8,169,
- 63,117, 87, 84, 62,211,255,221, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61, 93,108,160, 62,190,207, 17, 61,135,155, 12,
- 62,201, 39,166, 61,120,163, 56, 62,208,252, 58, 61, 55, 29,144, 62,194,183,207, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,107,173, 94, 62,225,130,168, 63,107,239,228, 62,218, 59, 62, 63,113,151,174, 62,214,229, 26, 63,114,102,144, 62,220, 23,198,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,135,155, 12, 62,201, 39,166, 61,195, 47,128, 62,207, 11, 6, 61,196,131, 76,
- 62,216, 97,196, 61,120,163, 56, 62,208,252, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,107,173, 94, 62,225,130,168,
- 63,101,251,100, 62,227,198,238, 63,102,205, 71, 62,219, 94,132, 63,107,239,228, 62,218, 59, 62, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,244,157,192, 62,209,137,157, 61,249,209, 68, 62,219,134, 70, 61,196,131, 76, 62,216, 97,196, 61,195, 47,128,
- 62,207, 11, 6, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 69, 19,224, 62,190, 68, 24, 63, 77,217,216, 62,157,228, 7,
- 63, 85, 35,236, 62,181,201,164, 63, 78, 92, 56, 62,188,114,177, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 32, 62, 80, 91,122,
- 62,174, 18, 72, 62,111,118,154, 62,152,108,120, 62,134, 78,250, 62,186,213,148, 62,104,163,162, 62,182,180,150, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 32, 63, 77,217,216, 62,157,228, 7, 63, 90, 5,151, 62,167, 61,138, 63, 92,180, 21, 62,173, 95,202,
- 63, 85, 35,236, 62,181,201,164, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 62, 54,216,144, 62,163, 76, 35, 62, 66,251,194,
- 62,158,102,163, 62,111,118,154, 62,152,108,120, 62, 80, 91,122, 62,174, 18, 72, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64,
- 63, 74, 64, 53, 62,224, 31,171, 63, 69, 19,224, 62,190, 68, 24, 63, 78, 92, 56, 62,188,114,177, 63, 81,106,217, 62,232,214, 14,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62,104,163,162, 62,182,180,150, 62,134, 78,250, 62,186,213,148, 62,114,112,184,
- 62,220,169,248, 62, 84, 93, 88, 62,228,105, 50, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 93,154,106, 62,233, 26,226,
- 63, 94,229,196, 62,224,195,128, 63,101,251,100, 62,227,198,238, 63,102,178, 46, 62,232,184,100, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,249,209, 68, 62,219,134, 70, 62, 28,187,108, 62,217, 86, 48, 62, 33, 1,128, 62,226,210, 70, 61,242,216,120,
- 62,225, 40,124, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 92,180, 21, 62,173, 95,202, 63, 97, 32, 68, 62,178, 12,192,
- 63, 94,215, 9, 62,186, 54, 4, 63, 85, 35,236, 62,181,201,164, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 41,122, 60,
- 62,175, 58, 16, 62, 36,185, 48, 62,166, 7, 16, 62, 54,216,144, 62,163, 76, 35, 62, 80, 91,122, 62,174, 18, 72, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 95, 78,230, 62,189,233, 4, 63, 86,188, 32, 62,190, 62, 44, 63, 85, 35,236, 62,181,201,164,
- 63, 94,215, 9, 62,186, 54, 4, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 80, 91,122, 62,174, 18, 72, 62, 71,118, 78,
- 62,182, 49, 27, 62, 37,225, 52, 62,179, 12, 40, 62, 41,122, 60, 62,175, 58, 16, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 92,166, 70, 62,197,166, 0, 63, 86,188, 32, 62,190, 62, 44, 63, 95, 78,230, 62,189,233, 4, 63, 95, 13,226, 62,194,152, 37,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 37,225, 52, 62,179, 12, 40, 62, 71,118, 78, 62,182, 49, 27, 62, 45,143,142,
- 62,188, 37,237, 62, 36,230,106, 62,184, 27,222, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 95, 90,248, 62,207,122,100,
- 63, 90,249,108, 62,212,199, 58, 63, 86,188, 32, 62,190, 62, 44, 63, 92,166, 70, 62,197,166, 0, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 71,118, 78, 62,182, 49, 27, 62, 48, 56,110, 62,205, 43,230, 62, 30,250,174, 62,198, 12, 26, 62, 45,143,142,
- 62,188, 37,237, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 94,229,196, 62,224,195,128, 63, 90,249,108, 62,212,199, 58,
- 63, 95, 90,248, 62,207,122,100, 63, 98,104, 92, 62,215,136,197, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 30,250,174,
- 62,198, 12, 26, 62, 48, 56,110, 62,205, 43,230, 62, 28,187,108, 62,217, 86, 48, 62, 15, 59,212, 62,206, 50,224, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,101,251,100, 62,227,198,238, 63, 94,229,196, 62,224,195,128, 63, 98,104, 92, 62,215,136,197,
- 63,102,205, 71, 62,219, 94,132, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 15, 59,212, 62,206, 50,224, 62, 28,187,108,
- 62,217, 86, 48, 61,249,209, 68, 62,219,134, 70, 61,244,157,192, 62,209,137,157, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 81,106,217, 62,232,214, 14, 63, 90,249,108, 62,212,199, 58, 63, 94,229,196, 62,224,195,128, 63, 93,154,106, 62,233, 26,226,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 28,187,108, 62,217, 86, 48, 62, 48, 56,110, 62,205, 43,230, 62, 84, 93, 88,
- 62,228,105, 50, 62, 33, 1,128, 62,226,210, 70, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 81,106,217, 62,232,214, 14,
- 63, 78, 92, 56, 62,188,114,177, 63, 86,188, 32, 62,190, 62, 44, 63, 90,249,108, 62,212,199, 58, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 71,118, 78, 62,182, 49, 27, 62,104,163,162, 62,182,180,150, 62, 84, 93, 88, 62,228,105, 50, 62, 48, 56,110,
- 62,205, 43,230, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 78, 92, 56, 62,188,114,177, 63, 85, 35,236, 62,181,201,164,
- 63, 86,188, 32, 62,190, 62, 44, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 71,118, 78,
- 62,182, 49, 27, 62, 80, 91,122, 62,174, 18, 72, 62,104,163,162, 62,182,180,150, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,102,205, 71, 62,219, 94,132, 63, 98,104, 92, 62,215,136,197, 63,100,109,182, 62,210,255,149,
- 63,104, 86, 54, 62,214,241,209, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 7,107,160, 62,200,103, 34, 62, 15, 59,212,
- 62,206, 50,224, 61,244,157,192, 62,209,137,157, 61,232, 2, 8, 62,203,214, 20, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 98,104, 92, 62,215,136,197, 63, 95, 90,248, 62,207,122,100, 63, 97,206,112, 62,204,202, 10, 63,100,109,182, 62,210,255,149,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 21, 68, 64, 62,194, 55,107, 62, 30,250,174, 62,198, 12, 26, 62, 15, 59,212,
- 62,206, 50,224, 62, 7,107,160, 62,200,103, 34, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 95, 90,248, 62,207,122,100,
- 63, 92,166, 70, 62,197,166, 0, 63, 94,241, 82, 62,198,103, 40, 63, 97,206,112, 62,204,202, 10, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 35,225, 20, 62,188, 50, 39, 62, 45,143,142, 62,188, 37,237, 62, 30,250,174, 62,198, 12, 26, 62, 21, 68, 64,
- 62,194, 55,107, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 92,166, 70, 62,197,166, 0, 63, 95, 13,226, 62,194,152, 37,
- 63, 97, 1,118, 62,195,226, 47, 63, 94,241, 82, 62,198,103, 40, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 28, 43, 12,
- 62,184,177,186, 62, 36,230,106, 62,184, 27,222, 62, 45,143,142, 62,188, 37,237, 62, 35,225, 20, 62,188, 50, 39, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 95, 13,226, 62,194,152, 37, 63, 95, 78,230, 62,189,233, 4, 63, 97,113, 51, 62,189,151, 92,
- 63, 97, 1,118, 62,195,226, 47, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 29, 67,104, 62,177,199, 58, 62, 37,225, 52,
- 62,179, 12, 40, 62, 36,230,106, 62,184, 27,222, 62, 28, 43, 12, 62,184,177,186, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 95, 78,230, 62,189,233, 4, 63, 94,215, 9, 62,186, 54, 4, 63, 96, 69, 96, 62,187,133,152, 63, 97,113, 51, 62,189,151, 92,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 35, 14,140, 62,176, 19, 33, 62, 41,122, 60, 62,175, 58, 16, 62, 37,225, 52,
- 62,179, 12, 40, 62, 29, 67,104, 62,177,199, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63, 94,215, 9, 62,186, 54, 4,
- 63, 97, 32, 68, 62,178, 12,192, 63, 98, 91,112, 62,182,128,149, 63, 96, 69, 96, 62,187,133,152, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 29,107,228, 62,169,230, 95, 62, 36,185, 48, 62,166, 7, 16, 62, 41,122, 60, 62,175, 58, 16, 62, 35, 14,140,
- 62,176, 19, 33, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,107,239,228, 62,218, 59, 62, 63,102,205, 71, 62,219, 94,132,
- 63,104, 86, 54, 62,214,241,209, 63,109, 27, 34, 62,214,254,155, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,232, 2, 8,
- 62,203,214, 20, 61,244,157,192, 62,209,137,157, 61,195, 47,128, 62,207, 11, 6, 61,184,174, 36, 62,202,130,216, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,113,151,174, 62,214,229, 26, 63,107,239,228, 62,218, 59, 62, 63,109, 27, 34, 62,214,254,155,
- 63,113,134, 69, 62,212, 82,156, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,184,174, 36, 62,202,130,216, 61,195, 47,128,
- 62,207, 11, 6, 61,135,155, 12, 62,201, 39,166, 61,138,114, 60, 62,197, 61, 28, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,116, 48,222, 62,209, 8,169, 63,113,151,174, 62,214,229, 26, 63,113,134, 69, 62,212, 82,156, 63,114,143, 42, 62,207,168, 24,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,138,114, 60, 62,197, 61, 28, 61,135,155, 12, 62,201, 39,166, 61, 93,108,160,
- 62,190,207, 17, 61,132, 85,184, 62,189,211, 22, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,115,225, 84, 62,198, 85,208,
- 63,116, 48,222, 62,209, 8,169, 63,114,143, 42, 62,207,168, 24, 63,114,125,203, 62,200,114, 96, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,132, 85,184, 62,189,211, 22, 61, 93,108,160, 62,190,207, 17, 61,134,221,244, 62,175,164,121, 61,145,152, 16,
- 62,179,214, 84, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,109,132,198, 62,186,157,182, 63,115,225, 84, 62,198, 85,208,
- 63,114,125,203, 62,200,114, 96, 63,109,192,177, 62,190,240,152, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,145,152, 16,
- 62,179,214, 84, 61,134,221,244, 62,175,164,121, 61,221, 91, 40, 62,167,194, 4, 61,208,226, 64, 62,172, 58,232, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 97, 32, 68, 62,178, 12,192, 63,109,132,198, 62,186,157,182, 63,109,192,177, 62,190,240,152,
- 63, 98, 91,112, 62,182,128,149, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,208,226, 64, 62,172, 58,232, 61,221, 91, 40,
- 62,167,194, 4, 62, 36,185, 48, 62,166, 7, 16, 62, 29,107,228, 62,169,230, 95, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 97, 1,118, 62,195,226, 47, 63, 97,113, 51, 62,189,151, 92, 63,102,139,215, 62,193,109, 15, 63,100, 47, 54, 62,198,115,186,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 5,169, 92, 62,179,115,168, 62, 29, 67,104, 62,177,199, 58, 62, 28, 43, 12,
- 62,184,177,186, 62, 13, 97, 50, 62,186, 42, 50, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,100, 47, 54, 62,198,115,186,
- 63,102,139,215, 62,193,109, 15, 63,105,241,174, 62,200, 8,204, 63,103,233, 71, 62,204, 42,178, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,229,171,228, 62,185, 42, 41, 62, 5,169, 92, 62,179,115,168, 62, 13, 97, 50, 62,186, 42, 50, 61,243,248, 92,
- 62,191, 22, 96, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,103,233, 71, 62,204, 42,178, 63,105,241,174, 62,200, 8,204,
- 63,108, 37, 51, 62,205, 3,249, 63,106,212, 56, 62,208,238, 96, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,202, 99,120,
- 62,190, 49,192, 61,229,171,228, 62,185, 42, 41, 61,243,248, 92, 62,191, 22, 96, 61,211,209,160, 62,195,159,108, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,106,212, 56, 62,208,238, 96, 63,108, 37, 51, 62,205, 3,249, 63,110, 73, 56, 62,206,119,186,
- 63,109,191, 46, 62,210, 64, 92, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,179,234,244, 62,190,219,240, 61,202, 99,120,
- 62,190, 49,192, 61,211,209,160, 62,195,159,108, 61,181,129,196, 62,196, 14,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,109, 27, 34, 62,214,254,155, 63,104, 86, 54, 62,214,241,209, 63,106,212, 56, 62,208,238, 96, 63,109,191, 46, 62,210, 64, 92,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,211,209,160, 62,195,159,108, 61,232, 2, 8, 62,203,214, 20, 61,184,174, 36,
- 62,202,130,216, 61,181,129,196, 62,196, 14,204, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,100,109,182, 62,210,255,149,
- 63,103,233, 71, 62,204, 42,178, 63,106,212, 56, 62,208,238, 96, 63,104, 86, 54, 62,214,241,209, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,211,209,160, 62,195,159,108, 61,243,248, 92, 62,191, 22, 96, 62, 7,107,160, 62,200,103, 34, 61,232, 2, 8,
- 62,203,214, 20, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,100,109,182, 62,210,255,149, 63, 97,206,112, 62,204,202, 10,
- 63,100, 47, 54, 62,198,115,186, 63,103,233, 71, 62,204, 42,178, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 13, 97, 50,
- 62,186, 42, 50, 62, 21, 68, 64, 62,194, 55,107, 62, 7,107,160, 62,200,103, 34, 61,243,248, 92, 62,191, 22, 96, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63, 97, 1,118, 62,195,226, 47, 63,100, 47, 54, 62,198,115,186, 63, 97,206,112, 62,204,202, 10,
- 63, 94,241, 82, 62,198,103, 40, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 21, 68, 64, 62,194, 55,107, 62, 13, 97, 50,
- 62,186, 42, 50, 62, 28, 43, 12, 62,184,177,186, 62, 35,225, 20, 62,188, 50, 39, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63, 96, 69, 96, 62,187,133,152, 63, 98, 91,112, 62,182,128,149, 63,102,139,215, 62,193,109, 15, 63, 97,113, 51, 62,189,151, 92,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 62, 5,169, 92, 62,179,115,168, 62, 29,107,228, 62,169,230, 95, 62, 35, 14,140,
- 62,176, 19, 33, 62, 29, 67,104, 62,177,199, 58, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,109,192,177, 62,190,240,152,
- 63,105,241,174, 62,200, 8,204, 63,102,139,215, 62,193,109, 15, 63, 98, 91,112, 62,182,128,149, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 62, 5,169, 92, 62,179,115,168, 61,229,171,228, 62,185, 42, 41, 61,208,226, 64, 62,172, 58,232, 62, 29,107,228,
- 62,169,230, 95, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,114,125,203, 62,200,114, 96, 63,108, 37, 51, 62,205, 3,249,
- 63,105,241,174, 62,200, 8,204, 63,109,192,177, 62,190,240,152, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,229,171,228,
- 62,185, 42, 41, 61,202, 99,120, 62,190, 49,192, 61,145,152, 16, 62,179,214, 84, 61,208,226, 64, 62,172, 58,232, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,114,143, 42, 62,207,168, 24, 63,110, 73, 56, 62,206,119,186, 63,108, 37, 51, 62,205, 3,249,
- 63,114,125,203, 62,200,114, 96, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,202, 99,120, 62,190, 49,192, 61,179,234,244,
- 62,190,219,240, 61,132, 85,184, 62,189,211, 22, 61,145,152, 16, 62,179,214, 84, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 63,113,134, 69, 62,212, 82,156, 63,109,191, 46, 62,210, 64, 92, 63,110, 73, 56, 62,206,119,186, 63,114,143, 42, 62,207,168, 24,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,179,234,244, 62,190,219,240, 61,181,129,196, 62,196, 14,204, 61,138,114, 60,
- 62,197, 61, 28, 61,132, 85,184, 62,189,211, 22, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,109, 27, 34, 62,214,254,155,
- 63,109,191, 46, 62,210, 64, 92, 63,113,134, 69, 62,212, 82,156, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 61,138,114, 60, 62,197, 61, 28, 61,181,129,196, 62,196, 14,204, 61,184,174, 36, 62,202,130,216, 63,128, 0, 0,
- 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,110,190, 84, 62,172, 77,223, 63, 90, 5,151, 62,167, 61,138,
- 63, 96, 25, 22, 62,149,248,246, 63,122,176,162, 62,161,215,145, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 62, 54,234, 64,
- 62,140,219,146, 62, 66,251,194, 62,158,102,163, 61,246, 66, 8, 62,152,161, 28, 61,189,241,172, 62,132,107, 13, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0, 0, 63,122, 12, 49, 62,197, 8,246, 63,110,190, 84, 62,172, 77,223, 63,122,176,162, 62,161,215,145,
- 63,126,255,188, 62,198,248,115, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 61,189,241,172, 62,132,107, 13, 61,246, 66, 8,
- 62,152,161, 28, 61, 16, 54,240, 62,167, 4,120, 58,163, 8, 0, 62,162, 69, 39, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128,
- 63,119,115,183, 62,215, 49,140, 63,122, 12, 49, 62,197, 8,246, 63,126,255,188, 62,198,248,115, 63,122, 6, 47, 62,216,157,248,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 58,163, 8, 0, 62,162, 69, 39, 61, 16, 54,240, 62,167, 4,120, 60,231,111,224,
- 62,198,142,100, 60, 14,248,224, 62,198,141, 70, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16, 63,116, 76, 41, 62,222,153,139,
- 63,119,115,183, 62,215, 49,140, 63,122, 6, 47, 62,216,157,248, 63,119, 98,134, 62,225, 37,204, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 0, 60, 14,248,224, 62,198,141, 70, 60,231,111,224, 62,198,142,100, 61, 73,183,128, 62,213,108, 84, 60,229,210, 80,
- 62,218,239, 32, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 63,109,178, 31, 62,228, 68,224, 63,116, 76, 41, 62,222,153,139,
- 63,119, 98,134, 62,225, 37,204, 63,115,185, 46, 62,234,157, 90, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,128, 60,229,210, 80,
- 62,218,239, 32, 61, 73,183,128, 62,213,108, 84, 61,177, 27, 28, 62,219,240, 42, 61,122,103, 56, 62,230, 10, 30, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0,128, 63,102,178, 46, 62,232,184,100, 63,109,178, 31, 62,228, 68,224, 63,115,185, 46, 62,234,157, 90,
- 63,106,134,244, 62,246, 64,234, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 61,122,103, 56, 62,230, 10, 30, 61,177, 27, 28,
- 62,219,240, 42, 61,242,216,120, 62,225, 40,124, 61,209,222,212, 62,240,123,238, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 16,
- 63, 5,188,235, 63, 98, 74,252, 62,248,111,200, 63,112,105,197, 62,231, 49, 0, 63,107,190,118, 62,255, 57,150, 63, 96, 14, 53,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62, 95, 99, 80, 63, 94,194,149, 62, 62, 8, 58, 63, 89,154, 10, 62, 92, 24, 40,
- 63, 74, 82, 14, 62,112, 11,112, 63, 78,133,157, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 63, 5,188,235, 63, 98, 74,252,
- 63, 12,139,136, 63,101,233,138, 63, 6, 45,116, 63,113,245,112, 62,248,111,200, 63,112,105,197, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0,240, 62, 36,219, 68, 63, 81,186,249, 62, 65,254, 28, 63, 70, 55, 20, 62, 92, 24, 40, 63, 74, 82, 14, 62, 62, 8, 58,
- 63, 89,154, 10, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 63, 12,139,136, 63,101,233,138, 63, 12,130, 5, 63,108,216,149,
- 63, 6, 45,116, 63,113,245,112, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,112, 62, 36,219, 68,
- 63, 81,186,249, 62, 42, 1, 76, 63, 73,178, 39, 62, 65,254, 28, 63, 70, 55, 20, 63,128, 0, 0, 63,128, 0, 0, 2,236,169, 32,
- 1, 0, 0, 5, 0, 0, 0,112, 63,103, 89,120, 63, 2, 76,105, 63, 93,154,106, 62,233, 26,226, 63,102,178, 46, 62,232,184,100,
- 63,106,134,244, 62,246, 64,234, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0, 61,242,216,120, 62,225, 40,124, 62, 33, 1,128,
- 62,226,210, 70, 61,234,128,116, 63, 0, 39,200, 61,209,222,212, 62,240,123,238, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 0,
- 62,245, 44,226, 63, 96,140,129, 62,255, 57,150, 63, 96, 14, 53, 62,231, 49, 0, 63,107,190,118, 62,227,135, 42, 63,101, 2, 58,
- 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 62, 95, 99, 80, 63, 94,194,149, 62,112, 11,112, 63, 78,133,157, 62,120, 84, 74,
- 63, 83, 32,104, 62,122,103,110, 63, 92,255,236, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0,240, 63, 77,217,216, 62,157,228, 7,
- 63, 90,225,160, 62,137,121,110, 63, 96, 25, 22, 62,149,248,246, 63, 90, 5,151, 62,167, 61,138, 2,236,169, 32, 1, 0, 0, 5,
- 0, 0, 0, 16, 62, 54,234, 64, 62,140,219,146, 62, 74,125,166, 62,130, 30,252, 62,111,118,154, 62,152,108,120, 62, 66,251,194,
- 62,158,102,163, 2,236,169, 32, 1, 0, 0, 5, 0, 0, 0, 64, 68, 65, 84, 65, 0, 0, 31, 64, 5, 31,232, 32, 0, 0, 0, 57,
- 0, 0, 7,208,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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, 68, 65, 84, 65,
+ 32, 0, 0, 0,216, 59,153, 2, 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, 77, 65, 0, 0, 68, 2, 0, 0, 0,147,165, 2, 39, 0, 0, 0,
+ 1, 0, 0, 0,248, 6,131, 2,152,140,165, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,116,101,120,116,117,114,101, 0,114,101,
+118,105,101,119, 46, 48, 48, 49, 0, 0, 0, 0, 1, 0, 0, 0, 69, 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,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, 0, 0,205,204, 76, 63, 0, 0, 0, 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,205,204,204, 61, 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, 71, 0, 1, 3,
+ 67, 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, 0, 0, 0, 0, 3, 0, 0, 0, 2, 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, 1, 8,129, 0, 48,150,165, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63,248, 16,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, 0, 0, 0, 0, 0, 0, 0, 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, 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,136, 0, 0, 0,248, 16,164, 2, 30, 0, 0, 0, 1, 0, 0, 0, 1, 0,129, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,112, 9,131, 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, 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, 16, 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, 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, 8, 3, 0, 0, 48,150,165, 2, 33, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,245, 40,220, 62, 0, 0, 0, 0,164,112,125, 63, 0, 0,128, 63,
+106,214, 24, 63, 0, 0,128, 63, 0, 0,128, 63, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 68, 2, 0, 0,248, 6,131, 2, 39, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,147,165, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 77, 65,116,101,120,116,117,114,101, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 70, 1, 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,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, 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, 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, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 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,224,155,165, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 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, 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, 8, 3, 0, 0,
+224,155,165, 2, 33, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,245, 40,220, 62, 0, 0, 0, 0,164,112,125, 63, 0, 0,128, 63,106,214, 24, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 1, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 4, 1, 0, 0,112, 9,131, 2,
+ 35, 0, 0, 0, 1, 0, 0, 0,168, 10,131, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69,112,114,101,118,105,101,
+119, 0,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 64, 1, 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, 0, 0, 0, 0, 5, 0, 8, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 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, 72, 63,155, 2, 68, 65, 84, 65, 32, 0, 0, 0, 72, 63,155, 2, 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, 4, 1, 0, 0,168, 10,131, 2, 35, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,112, 9,131, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 84, 69,102, 97,107,101,115,104, 97,100,111,119, 0, 0, 76,101,110,100, 0,101,120, 0, 0, 0, 2, 0, 0, 0,
+ 65, 1, 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,
+ 0, 0, 0, 0, 5, 0, 40, 0, 5, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 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, 77, 69, 0, 0, 12, 1, 0, 0,
+136,161,165, 2, 51, 0, 0, 0, 1, 0, 0, 0, 80,153,166, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117,
+ 98,101, 46, 48, 48, 49, 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, 96, 0,153, 2, 16, 63, 8, 3, 40,176,154, 2,
+ 0, 0, 0, 0,248,208,129, 2,208,213,166, 2, 0, 0, 0, 0, 96, 53,164, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+104,128,152, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,200,129,152, 2, 1, 0, 0, 0, 5, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0,160,120,152, 2, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,249, 1, 0, 0,
+237, 3, 0, 0,244, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,192,133, 88, 61,184, 45, 85,189,196,181, 24,190,
+185, 71, 35, 63,153, 31,235, 62,130,102,203, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 68, 65, 84, 65, 4, 0, 0, 0,
+ 96, 0,153, 2, 0, 0, 0, 0, 1, 0, 0, 0,152,140,165, 2, 68, 65, 84, 65, 44, 1, 0, 0,104,128,152, 2, 21, 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,248,208,129, 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, 68, 65, 84, 65,116, 39, 0, 0,248,208,129, 2, 57, 0, 0, 0,
+249, 1, 0, 0,140,144,131, 62,119,163,200, 60,156, 9, 85, 62,125, 92, 70,170,228, 21, 0,255, 50,222, 26,190,119,163,200, 60,
+156, 9, 85, 62,131,163, 70,170,228, 21, 0,255, 61,126,146, 62,223, 37, 8,188, 99,183, 47, 62,247, 76,191,194,228, 81, 2,255,
+147,185, 56,190,223, 37, 8,188, 99,183, 47, 62, 9,179,191,194,228, 81, 2,255,129,176,157, 62,211, 91,217,188,244,238,246, 61,
+ 31, 84,226,181,191, 61, 2,255, 28, 30, 79,190,211, 91,217,188,244,238,246, 61,225,171,226,181,191, 61, 2,255,115, 19, 94, 62,
+103,251,128,189,150, 32, 14, 62,241, 9,155,144, 64, 62, 2,255, 26,161,227,189,103,251,128,189,150, 32, 14, 62, 15,246,155,144,
+ 64, 62, 2,255,115, 19, 94, 62,251,118, 25,189, 20,165, 62, 62,184, 14,144,163, 76, 87, 2,255, 26,161,227,189,251,118, 25,189,
+ 20,165, 62, 62, 72,241,144,163, 76, 87, 2,255,115, 19, 94, 62,232,107, 34, 60,116,128, 92, 62, 3, 3,121,131,110, 29, 0,255,
+ 26,161,227,189,232,107, 34, 60,116,128, 92, 62,253,252,121,131,110, 29, 0,255, 58,193, 56, 62,119,163,200, 60, 77,247, 99, 62,
+ 56,171,117,167,206, 36, 0,255,168,252,152,189,119,163,200, 60, 77,247, 99, 62,200, 84,117,167,206, 36, 0,255,109, 42, 23, 62,
+223, 37, 8,188, 88,215, 73, 62,152,217,122,203, 56,110, 0,255,229,197, 0, 62,211, 91,217,188, 71, 14, 29, 62,179,184, 93,175,
+ 66, 69, 2,255,249, 23,164,188,211, 91,217,188, 71, 14, 29, 62, 77, 71, 93,175, 66, 69, 2,255, 88,231,182, 61,159,154,121, 61,
+179,201, 32, 62,181,151,104,255, 51, 74, 2,255,207,121,134, 60,159,154,121, 61,179,201, 32, 62, 75,104,104,255, 51, 74, 2,255,
+ 25,158,242, 61,159,154,121, 61, 88,215, 73, 62, 78,171,150,255,246, 95, 2,255,110,194, 80,188,159,154,121, 61, 88,215, 73, 62,
+178, 84,150,255,246, 95, 2,255,138,211, 41, 62,159,154,121, 61, 77,247, 99, 62,152,133,153,254, 98, 37, 0,255,143, 66,118,189,
+159,154,121, 61, 77,247, 99, 62,104,122,153,254, 98, 37, 0,255, 58,193, 56, 62,154,232,206, 61, 77,247, 99, 62, 24,170, 13, 88,
+ 89, 35, 0,255,168,252,152,189,154,232,206, 61, 77,247, 99, 62,232, 85, 13, 88, 89, 35, 0,255,109, 42, 23, 62,173, 79, 5, 62,
+ 88,215, 73, 62,249,200,221, 65,244, 94, 2,255, 31,158, 43,189,173, 79, 5, 62, 88,215, 73, 62, 7, 55,221, 65,244, 94, 2,255,
+229,197, 0, 62, 54,180, 27, 62, 71, 14, 29, 62, 51,186, 86, 78, 78, 73, 2,255,249, 23,164,188, 54,180, 27, 62, 71, 14, 29, 62,
+205, 69, 86, 78, 78, 73, 2,255,115, 19, 94, 62,111, 6, 65, 62,150, 32, 14, 62, 2, 11,152,107,114, 68, 2,255, 26,161,227,189,
+111, 6, 65, 62,150, 32, 14, 62,254,244,152,107,114, 68, 2,255,115, 19, 94, 62, 14, 43, 35, 62, 20,165, 62, 62,201, 14,180, 91,
+ 14, 88, 2,255, 26,161,227,189, 14, 43, 35, 62, 20,165, 62, 62, 55,241,180, 91, 14, 88, 2,255,115, 19, 94, 62,250,195,236, 61,
+116,128, 92, 62,134, 2, 29,125,228, 26, 0,255, 26,161,227,189,250,195,236, 61,116,128, 92, 62,122,253, 29,125,228, 26, 0,255,
+140,144,131, 62,154,232,206, 61,156, 9, 85, 62, 54, 93, 67, 85,154, 20, 0,255, 50,222, 26,190,154,232,206, 61,156, 9, 85, 62,
+202,162, 67, 85,154, 20, 0,255, 61,126,146, 62,173, 79, 5, 62, 99,183, 47, 62,241, 76,161, 60, 97, 82, 2,255,147,185, 56,190,
+173, 79, 5, 62, 99,183, 47, 62, 15,179,161, 60, 97, 82, 2,255,129,176,157, 62, 54,180, 27, 62,244,238,246, 61,179, 83,157, 71,
+ 45, 65, 2,255, 28, 30, 79,190, 54,180, 27, 62,244,238,246, 61, 77,172,157, 71, 45, 65, 2,255,157, 89,176, 62,159,154,121, 61,
+ 67, 1,232, 61, 40,111,113,255,117, 63, 2,255, 84,112,116,190,159,154,121, 61, 67, 1,232, 61,216,144,113,255,117, 63, 2,255,
+237,107,161, 62,159,154,121, 61,139, 64, 40, 62, 48,100,154,255,167, 79, 2,255,244,148, 86,190,159,154,121, 61,139, 64, 40, 62,
+208,155,154,255,167, 79, 2,255,100, 7,139, 62,159,154,121, 61, 48, 78, 81, 62,117,126,181,254,185, 19, 0,255,227,203, 41,190,
+159,154,121, 61, 48, 78, 81, 62,139,129,181,254,185, 19, 0,255, 26,229,140, 62,159,154,121, 61, 8,197, 88, 62,160,120,106,254,
+198, 42, 2,255, 79,135, 45,190,159,154,121, 61, 8,197, 88, 62, 96,135,106,254,198, 42, 2,255, 66,110,133, 62,114, 95,214, 61,
+116,128, 92, 62,173, 93,126, 74, 93, 45, 2,255,158,153, 30,190,114, 95,214, 61,116,128, 92, 62, 83,162,126, 74, 93, 45, 2,255,
+115, 19, 94, 62,170,177,251, 61,185,178,103, 62, 9, 11, 31,115,216, 54, 2,255, 26,161,227,189,170,177,251, 61,185,178,103, 62,
+247,244, 31,115,216, 54, 2,255,206, 5, 53, 62,114, 95,214, 61,145, 41,111, 62, 9,181,184, 80, 43, 65, 2,255,208,133,145,189,
+114, 95,214, 61,145, 41,111, 62,247, 74,184, 80, 43, 65, 2,255,178, 92, 34, 62,159,154,121, 61,145, 41,111, 62,116,146, 57,254,
+ 43, 66, 2,255, 48,103, 88,189,159,154,121, 61,145, 41,111, 62,140,109, 57,254, 43, 66, 2,255,206, 5, 53, 62, 22,200,170, 60,
+145, 41,111, 62, 34,182,181,173,115, 64, 2,255,208,133,145,189, 22,200,170, 60,145, 41,111, 62,222, 73,181,173,115, 64, 2,255,
+115, 19, 94, 62,159,154,121, 61,253,228,114, 62, 74, 24,139,255,171,125, 2,255, 26,161,227,189,159,154,121, 61,253,228,114, 62,
+182,231,139,255,171,125, 2,255,115, 19, 94, 62,149,249, 43, 59,185,178,103, 62,218, 10,140,140, 45, 54, 2,255, 26,161,227,189,
+149,249, 43, 59,185,178,103, 62, 38,245,140,140, 45, 54, 2,255, 66,110,133, 62, 22,200,170, 60,116,128, 92, 62,141, 92,203,179,
+210, 44, 2,255,158,153, 30,190, 22,200,170, 60,116,128, 92, 62,115,163,203,179,210, 44, 2,255,203,133, 88, 61,202,248, 23, 62,
+ 88,215, 73, 62, 0, 0, 43,124, 17, 31, 0,255,203,133, 88, 61, 34, 77,229, 61,145, 41,111, 62, 0, 0, 63,249,209,127, 0,255,
+203,133, 88, 61,150,254,188,190,236, 27, 70, 62, 0, 0,204,251,237,127, 0,255,203,133, 88, 61,191, 79, 78,190,116,128, 92, 62,
+ 0, 0, 33,150,238, 71, 2,255,203,133, 88, 61,146,221, 14,190, 77,247, 99, 62, 0, 0, 28,100,192, 79, 0,255,203,133, 88, 61,
+ 30, 99,211,190, 20,165, 62, 62, 0, 0,184,142,147, 59, 2,255,203,133, 88, 61,133,198, 12, 62,190,169, 6, 62, 0, 0,143,103,
+ 57, 75, 0,255,203,133, 88, 61, 99, 38, 91, 62, 28,120,239, 61, 0, 0,115, 78, 34,101, 0,255,203,133, 88, 61, 16,243,187, 62,
+170,250,206,190, 0, 0,190,110,212,191, 2,255,203,133, 88, 61,247,106, 87, 62,178,224, 11,191, 0, 0,144, 35, 12,133, 3,255,
+203,133, 88, 61, 18,165,157,188, 33, 20, 9,191, 0, 0,194,214,213,134, 2,255,203,133, 88, 61, 32, 43,108,190,227, 83,160,190,
+ 0, 0,154,134,113,215, 2,255,109, 42, 23, 62,146,221, 14,190, 67, 1,232, 61,144,113,122,198, 79, 13, 0,255, 31,158, 43,189,
+146,221, 14,190, 67, 1,232, 61,112,142,122,198, 79, 13, 0,255, 87,106, 75, 62,138, 37,131,190, 28,120,239, 61,196,122, 19, 31,
+152, 18, 2,255,225, 78,190,189,138, 37,131,190, 28,120,239, 61, 60,133, 19, 31,152, 18, 2,255,115, 19, 94, 62, 2,186,192,190,
+ 28,120,239, 61,167,125,146, 12,226, 20, 0,255, 26,161,227,189, 2,186,192,190, 28,120,239, 61, 89,130,146, 12,226, 20, 0,255,
+ 75,138,101, 62,200, 96,239,190,227, 37,202, 61,113,124,142,242,196, 26, 2,255,203,142,242,189,200, 96,239,190,227, 37,202, 61,
+143,131,142,242,196, 26, 2,255, 47,225, 82, 62,195,112,252,190, 10,175,194, 61,159, 79, 44,159,210, 25, 2,255,146, 60,205,189,
+195,112,252,190, 10,175,194, 61, 97,176, 44,159,210, 25, 2,255, 41,248, 11, 62,242, 4, 1,191,107,138,224, 61,143, 19, 13,131,
+178, 19, 2,255, 27,170,253,188,242, 4, 1,191,107,138,224, 61,113,236, 13,131,178, 19, 2,255,203,133, 88, 61,168,226, 2,191,
+244,238,246, 61, 0, 0, 75,130, 21, 24, 2,255,140,144,131, 62, 18,242,240,189,227, 37,202, 61,114, 47,117,137,232, 8, 2,255,
+ 50,222, 26,190, 18,242,240,189,227, 37,202, 61,142,208,117,137,232, 8, 2,255, 83, 55,178, 62, 23,233,143,189,187,156,209, 61,
+ 25, 77,198,154,214, 13, 2,255,193, 43,120,190, 23,233,143,189,187,156,209, 61,231,178,198,154,214, 13, 2,255, 26,222,224, 62,
+182,236,140, 60, 49, 21,112, 61,216,113,247,198,255, 12, 2,255,167,188,170,190,182,236,140, 60, 49, 21,112, 61, 40,142,247,198,
+255, 12, 2,255,243, 84,232, 62,202,248, 23, 62, 82,238, 2, 62,104,113, 31, 51, 32, 30, 2,255,128, 51,178,190,202,248, 23, 62,
+ 82,238, 2, 62,152,142, 31, 51, 32, 30, 2,255,112,224,196, 62,190, 24, 50, 62, 2,220, 17, 62,216, 64,225,106,121, 27, 0,255,
+253,190,142,190,190, 24, 50, 62, 2,220, 17, 62, 40,191,225,106,121, 27, 0,255,134,160,144, 62, 20, 20,106, 62, 99,183, 47, 62,
+137, 75, 82,101, 70, 20, 0,255, 39,254, 52,190, 20, 20,106, 62, 99,183, 47, 62,119,180, 82,101, 70, 20, 0,255,195, 37, 79, 62,
+ 67, 92,154, 62,236, 27, 70, 62,241, 38, 19,119, 54, 26, 2,255,186,197,197,189, 67, 92,154, 62,236, 27, 70, 62, 15,217, 19,119,
+ 54, 26, 2,255,229,197, 0, 62,181, 7,145, 62, 48, 78, 81, 62, 21,175, 54, 96, 12, 24, 2,255,249, 23,164,188,181, 7,145, 62,
+ 48, 78, 81, 62,235, 80, 54, 96, 12, 24, 2,255,168,249,167, 61, 42,212, 53, 62,196,146, 77, 62,174,155,128, 76,151, 21, 0,255,
+144, 48,194, 60, 42,212, 53, 62,196,146, 77, 62, 82,100,128, 76,151, 21, 0,255, 81,129, 4, 62,241,129, 16, 62, 8,197, 88, 62,
+ 0, 25, 4,237, 22,124, 0,255, 89,243,193,188,241,129, 16, 62, 8,197, 88, 62, 0,231, 4,237, 22,124, 0,255,105,176,227, 61,
+ 17,132,184, 61,156, 9, 85, 62,160,255,126,232,209,125, 0,255,214,169,178,187, 17,132,184, 61,156, 9, 85, 62, 96, 0,126,232,
+209,125, 0,255, 31,158, 43,189,223, 37, 8,188, 88,215, 73, 62,104, 38,122,203, 56,110, 0,255,184, 69,105, 62, 92, 82, 55,189,
+ 59, 46, 55, 62,106, 34,119,200, 16,110, 0,255,163, 5,250,189, 92, 82, 55,189, 59, 46, 55, 62,150,221,119,200, 16,110, 0,255,
+134,160,144, 62,115,128,187,188,139, 64, 40, 62,161, 55, 60,207,115,104, 0,255, 39,254, 52,190,115,128,187,188,139, 64, 40, 62,
+ 95,200, 60,207,115,104, 0,255,157, 89,176, 62,205, 26, 17, 61, 71, 14, 29, 62,181, 58,123,226,214,109, 0,255, 84,112,116,190,
+205, 26, 17, 61, 71, 14, 29, 62, 75,197,123,226,214,109, 0,255, 9, 21,180, 62, 57, 13,177, 61, 71, 14, 29, 62,157, 49, 61,230,
+ 36,115, 0,255, 45,231,123,190, 57, 13,177, 61, 71, 14, 29, 62, 99,206, 61,230, 36,115, 0,255,123,192,170, 62,170,177,251, 61,
+ 31,133, 36, 62,206, 39,175,234,196,119, 0,255, 16, 62,105,190,170,177,251, 61, 31,133, 36, 62, 50,216,175,234,196,119, 0,255,
+214,178,129, 62, 54,180, 27, 62, 20,165, 62, 62, 62, 24, 85,255,173,125, 0,255,198, 34, 23,190, 54,180, 27, 62, 20,165, 62, 62,
+194,231, 85,255,173,125, 0,255,246,142, 45, 62,230,161, 42, 62, 48, 78, 81, 62,251, 31, 40,247,158,123, 0,255, 32,152,130,189,
+230,161, 42, 62, 48, 78, 81, 62, 5,224, 40,247,158,123, 0,255,203,133, 88, 61,104,133,209,190,236, 27, 70, 62, 0, 0,148,210,
+170,119, 0,255,185,194,212, 61, 36, 83,198,190,236, 27, 70, 62, 39, 19, 65,222,248,121, 0,255,191,196,240, 58, 36, 83,198,190,
+236, 27, 70, 62,217,236, 65,222,248,121, 0,255,145, 57,220, 61,207, 80,226,190,167,233, 58, 62,134, 2,132,217, 12,122, 0,255,
+ 77,241,236,186,207, 80,226,190,167,233, 58, 62,122,253,132,217, 12,122, 0,255,168,249,167, 61, 19,131,237,190,207,114, 51, 62,
+ 13,252,169,214, 18,121, 0,255,144, 48,194, 60, 19,131,237,190,207,114, 51, 62,243, 3,169,214, 18,121, 0,255,203,133, 88, 61,
+200, 96,239,190, 99,183, 47, 62, 0, 0,150,219,180,122, 0,255,203,133, 88, 61,254,152, 18,190,196,146, 77, 62, 0, 0, 46, 97,
+ 76, 83, 0,255,203,133, 88, 61, 18,242,240,189, 88,215, 73, 62, 0, 0,197,104,134, 73, 0,255,225, 75,205, 61,235,104,248,189,
+ 88,215, 73, 62, 52, 36, 2, 53,187,110, 0,255,179,158,179, 59,235,104,248,189, 88,215, 73, 62,204,219, 2, 53,187,110, 0,255,
+105,176,227, 61,174,134, 33,190,196,146, 77, 62,187, 95, 14,212,182, 72, 0,255,214,169,178,187,174,134, 33,190,196,146, 77, 62,
+ 69,160, 14,212,182, 72, 0,255, 48, 94,190, 61, 15, 98, 63,190, 88,215, 73, 62,117, 64,117,207, 90, 99, 0,255,220, 60, 81, 60,
+ 15, 98, 63,190, 88,215, 73, 62,139,191,117,207, 90, 99, 0,255,252,119,116, 62,239, 95,151,189,139, 64, 40, 62,103, 49,157,196,
+ 13,102, 0,255, 22, 53, 8,190,239, 95,151,189,139, 64, 40, 62,153,206,157,196, 13,102, 0,255,231,123,174, 62,211, 91,217,188,
+ 2,220, 17, 62,142, 59,107,204,223,100, 2,255,232,180,112,190,211, 91,217,188, 2,220, 17, 62,114,196,107,204,223,100, 2,255,
+220,155,200, 62, 45,246, 46, 61,190,169, 6, 62,102, 66, 11,217, 65,102, 0,255,105,122,146,190, 45,246, 46, 61,190,169, 6, 62,
+154,189, 11,217, 65,102, 0,255, 72, 87,204, 62,170,177,251, 61,179,201, 32, 62, 87, 54,142,228,151,112, 0,255,213, 53,150,190,
+170,177,251, 61,179,201, 32, 62,169,201,142,228,151,112, 0,255, 78, 71,191, 62,241,129, 16, 62,128, 96, 66, 62, 82, 42, 97,247,
+125,120, 2,255,219, 37,137,190,241,129, 16, 62,128, 96, 66, 62,174,213, 97,247,125,120, 2,255,140,144,131, 62, 31,244, 79, 62,
+ 77,247, 99, 62,192, 41,216,254,253,120, 0,255, 50,222, 26,190, 31,244, 79, 62, 77,247, 99, 62, 64,214,216,254,253,120, 0,255,
+ 87,106, 75, 62, 48,189,124, 62,105,160,118, 62,217, 28, 53, 7,126,124, 0,255,225, 78,190,189, 48,189,124, 62,105,160,118, 62,
+ 39,227, 53, 7,126,124, 0,255,109, 42, 23, 62,236,138,113, 62, 65, 23,126, 62,125,255, 44, 5,227,127, 0,255, 31,158, 43,189,
+236,138,113, 62, 65, 23,126, 62,131, 0, 44, 5,227,127, 0,255,225, 75,205, 61,202,248, 23, 62,213, 91,122, 62,130,238, 89, 2,
+197,126, 0,255,179,158,179, 59,202,248, 23, 62,213, 91,122, 62,126, 17, 89, 2,197,126, 0,255,105,176,227, 61,217,159,203,189,
+ 37,110,107, 62,115, 23, 27,230, 34,123, 0,255,214,169,178,187,217,159,203,189, 37,110,107, 62,141,232, 27,230, 34,123, 0,255,
+218,229, 26, 62, 64, 3,133,190,167,233, 58, 62,212, 74, 28, 14,225,102, 2,255,207,139, 58,189, 64, 3,133,190,167,233, 58, 62,
+ 44,181, 28, 14,225,102, 2,255,246,142, 45, 62,184,151,194,190, 99,183, 47, 62,235, 72, 17,252, 31,105, 2,255, 32,152,130,189,
+184,151,194,190, 99,183, 47, 62, 21,183, 17,252, 31,105, 2,255,206, 5, 53, 62, 99,149,222,190, 31,133, 36, 62,179, 66,197,225,
+249,104, 2,255,208,133,145,189, 99,149,222,190, 31,133, 36, 62, 77,189,197,225,249,104, 2,255, 30, 24, 38, 62,234,249,244,190,
+111,151, 21, 62, 62, 44, 4,183, 98, 95, 2,255,224, 84,103,189,234,249,244,190,111,151, 21, 62,194,211, 4,183, 98, 95, 2,255,
+ 81,129, 4, 62, 86,181,248,190,111,151, 21, 62,155, 19, 52,158, 54, 80, 2,255, 89,243,193,188, 86,181,248,190,111,151, 21, 62,
+101,236, 52,158, 54, 80, 2,255,203,133, 88, 61,195,112,252,190,219, 82, 25, 62, 0, 0,201,154, 88, 78, 2,255,203,133, 88, 61,
+ 52, 55,247,188,128, 96, 66, 62, 0, 0, 2,252,239,127, 0,255,203,133, 88, 61,222,227, 61, 61,156, 9, 85, 62, 0, 0,112,227,
+196,124, 0,255, 47,225, 82, 62, 82, 93, 46, 62, 88,215, 73, 62, 58, 21,234,254, 56,126, 0,255,146, 60,205,189, 82, 93, 46, 62,
+ 88,215, 73, 62,198,234,234,254, 56,126, 0,255, 81,129, 4, 62,170, 34, 94, 60,196,146, 77, 62, 37,214,110,232,163,118, 0,255,
+ 89,243,193,188,170, 34, 94, 60,196,146, 77, 62,219, 41,110,232,163,118, 0,255, 65, 39,235, 61,222,227, 61, 61, 48, 78, 81, 62,
+150,232,127,230, 57,123, 0,255,173, 11, 21,188,222,227, 61, 61, 48, 78, 81, 62,106, 23,127,230, 57,123, 0,255,145, 57,220, 61,
+ 76,220,190,190,236, 27, 70, 62,117, 20,197,248, 36,126, 0,255, 77,241,236,186, 76,220,190,190,236, 27, 70, 62,139,235,197,248,
+ 36,126, 0,255, 88,231,182, 61, 64, 3,133,190,196,146, 77, 62, 43, 19,128, 0,141,126, 2,255,207,121,134, 60, 64, 3,133,190,
+196,146, 77, 62,213,236,128, 0,141,126, 2,255,203,133, 88, 61, 64, 3,133,190,196,146, 77, 62, 0, 0,122,255,254,127, 0,255,
+203,133, 88, 61, 43, 11, 82,190, 88,215, 73, 62, 0, 0,121,184, 36,106, 0,255, 8,213,197, 61, 55,235, 55,190,116,128, 92, 62,
+167, 66,139,160, 45, 53, 2,255, 27,134, 21, 60, 55,235, 55,190,116,128, 92, 62, 89,189,139,160, 45, 53, 2,255, 65, 39,235, 61,
+174,134, 33,190, 77,247, 99, 62,133,118,215,224,239, 36, 2,255,173, 11, 21,188,174,134, 33,190, 77,247, 99, 62,123,137,215,224,
+239, 36, 2,255,185,194,212, 61, 57,123,233,189,116,128, 92, 62,167, 81,141, 95, 49, 24, 2,255,191,196,240, 58, 57,123,233,189,
+116,128, 92, 62, 89,174,141, 95, 49, 24, 2,255, 31,149,145, 61, 97, 4,226,189,116,128, 92, 62,189,200,160,108, 26, 39, 2,255,
+ 89,225, 13, 61, 97, 4,226,189,116,128, 92, 62, 67, 55,160,108, 26, 39, 2,255,203,133, 88, 61,106, 84, 22,190,253,228,114, 62,
+ 0, 0, 42, 23,225,125, 0,255,247, 11,153, 61,235,104,248,189, 37,110,107, 62,186,231, 89, 78, 66, 98, 2,255, 82,231,253, 60,
+235,104,248,189, 37,110,107, 62, 70, 24, 89, 78, 66, 98, 2,255, 8,213,197, 61,195,223,255,189, 37,110,107, 62, 88, 43,134, 62,
+237,102, 2,255, 27,134, 21, 60,195,223,255,189, 37,110,107, 62,168,212,134, 62,237,102, 2,255,185,194,212, 61,174,134, 33,190,
+253,228,114, 62,247, 46, 89,233,228,116, 2,255,191,196,240, 58,174,134, 33,190,253,228,114, 62, 9,209, 89,233,228,116, 2,255,
+ 88,231,182, 61,243,184, 44,190,185,178,103, 62, 46, 31,198,181,128, 99, 2,255,207,121,134, 60,243,184, 44,190,185,178,103, 62,
+210,224,198,181,128, 99, 2,255,203,133, 88, 61, 15, 98, 63,190,185,178,103, 62, 0, 0,185,191,175,110, 2,255, 98, 74, 49, 62,
+ 83,148, 74,190,107,138,224, 61, 23,120, 34, 41, 99, 16, 0,255,248, 14,138,189, 83,148, 74,190,107,138,224, 61,233,135, 34, 41,
+ 99, 16, 0,255, 81,129, 4, 62,134,253, 40,190,167,233, 58, 62,251, 80, 26,250,241, 98, 0,255, 89,243,193,188,134,253, 40,190,
+167,233, 58, 62, 5,175, 26,250,241, 98, 0,255, 41,248, 11, 62, 83,148, 74,190,167,233, 58, 62,215, 83,153, 16, 71, 95, 0,255,
+ 27,170,253,188, 83,148, 74,190,167,233, 58, 62, 41,172,153, 16, 71, 95, 0,255, 30, 24, 38, 62,243,184, 44,190,107,138,224, 61,
+ 24,122, 67, 35, 64, 15, 0,255,224, 84,103,189,243,184, 44,190,107,138,224, 61,232,133, 67, 35, 64, 15, 0,255,203,133, 88, 61,
+ 93,165,235,190, 99,183, 47, 62, 0, 0,139, 86, 77, 94, 0,255,247, 11,153, 61,167,199,233,190, 99,183, 47, 62,144,206,200, 70,
+125, 94, 0,255, 82,231,253, 60,167,199,233,190, 99,183, 47, 62,112, 49,200, 70,125, 94, 0,255, 8,213,197, 61, 99,149,222,190,
+167,233, 58, 62,253,164,109, 17, 75, 88, 0,255, 27,134, 21, 60, 99,149,222,190,167,233, 58, 62, 3, 91,109, 17, 75, 88, 0,255,
+ 8,213,197, 61, 70,236,203,190,128, 96, 66, 62,141,225, 87,168, 39, 88, 0,255, 27,134, 21, 60, 70,236,203,190,128, 96, 66, 62,
+115, 30, 87,168, 39, 88, 0,255,203,133, 88, 61,212, 64,213,190,179,201, 32, 62, 0, 0, 20,159,153, 83, 0,255, 8,213,197, 61,
+252,201,205,190, 31,133, 36, 62, 5,230,250,177, 20, 98, 0,255, 27,134, 21, 60,252,201,205,190, 31,133, 36, 62,251, 25,250,177,
+ 20, 98, 0,255, 8,213,197, 61,173,183,220,190,219, 82, 25, 62, 18,152, 8, 24,188, 70, 0,255, 27,134, 21, 60,173,183,220,190,
+219, 82, 25, 62,238,103, 8, 24,188, 70, 0,255,247, 11,153, 61, 59, 12,230,190,111,151, 21, 62, 26,222,242, 49,221,112, 0,255,
+ 82,231,253, 60, 59, 12,230,190,111,151, 21, 62,230, 33,242, 49,221,112, 0,255,203,133, 88, 61,241,233,231,190,111,151, 21, 62,
+ 0, 0, 18, 60, 5,113, 0,255,189, 60, 8, 62,142,209, 76, 61,116,128, 92, 62, 4, 30, 93,244,225,123, 0,255,186,206,223,188,
+142,209, 76, 61,116,128, 92, 62,252,225, 93,244,225,123, 0,255,149,179, 15, 62, 22,200,170, 60, 8,197, 88, 62, 71, 9, 34,251,
+144,127, 0,255,190,194, 13,189, 22,200,170, 60, 8,197, 88, 62,185,246, 34,251,144,127, 0,255,155,156, 86, 62,202,248, 23, 62,
+ 48, 78, 81, 62, 81, 17, 74, 2,204,126, 0,255,106,179,212,189,202,248, 23, 62, 48, 78, 81, 62,175,238, 74, 2,204,126, 0,255,
+ 58,193, 56, 62, 94, 61, 20, 62, 8,197, 88, 62,218, 25,177,253, 86,125, 2,255,168,252,152,189, 94, 61, 20, 62, 8,197, 88, 62,
+ 38,230,177,253, 86,125, 2,255, 64,170,127, 62, 25, 11, 9, 62, 8,197, 88, 62,182, 21,210,240, 57,125, 2,255, 90,103, 19,190,
+ 25, 11, 9, 62, 8,197, 88, 62, 74,234,210,240, 57,125, 2,255,237,107,161, 62, 34, 77,229, 61,207,114, 51, 62,143, 28,249,237,
+117,123, 0,255,244,148, 86,190, 34, 77,229, 61,207,114, 51, 62,113,227,249,237,117,123, 0,255, 15, 5,167, 62, 97,150,169, 61,
+ 99,183, 47, 62,209, 15,217,246,175,126, 0,255, 56,199, 97,190, 97,150,169, 61, 99,183, 47, 62, 47,240,217,246,175,126, 0,255,
+ 89, 39,165, 62,125, 8, 32, 61,247,251, 43, 62,177, 24,190,253,146,125, 0,255,204, 11, 94,190,125, 8, 32, 61,247,251, 43, 62,
+ 79,231,190,253,146,125, 0,255, 26,229,140, 62, 60,222,152,187, 20,165, 62, 62, 20, 33, 75, 2,160,123, 0,255, 79,135, 45,190,
+ 60,222,152,187, 20,165, 62, 62,236,222, 75, 2,160,123, 0,255,184, 69,105, 62,115,128,187,188, 88,215, 73, 62, 85, 26,238,248,
+ 14,125, 0,255,163, 5,250,189,115,128,187,188, 88,215, 73, 62,171,229,238,248, 14,125, 0,255,178, 92, 34, 62,226,194,133,186,
+116,128, 92, 62, 8, 7,142,250,175,127, 0,255, 48,103, 88,189,226,194,133,186,116,128, 92, 62,248,248,142,250,175,127, 0,255,
+ 41,248, 11, 62, 57, 13,177, 61,116,128, 92, 62,169, 34, 2,240, 43,122, 0,255, 27,170,253,188, 57, 13,177, 61,116,128, 92, 62,
+ 87,221, 2,240, 43,122, 0,255,218,229, 26, 62,170,177,251, 61,116,128, 92, 62,126, 27,108,239,231,123, 0,255,207,139, 58,189,
+170,177,251, 61,116,128, 92, 62,130,228,108,239,231,123, 0,255, 30, 24, 38, 62,250,195,236, 61, 48, 78, 81, 62,226, 64, 13,207,
+224, 98, 0,255,224, 84,103,189,250,195,236, 61, 48, 78, 81, 62, 30,191, 13,207,224, 98, 0,255, 1,111, 19, 62, 57, 13,177, 61,
+ 48, 78, 81, 62, 29, 96,169,229, 81, 80, 0,255,110,176, 28,189, 57, 13,177, 61, 48, 78, 81, 62,227,159,169,229, 81, 80, 0,255,
+138,211, 41, 62, 77,106,205, 59, 48, 78, 81, 62, 36, 55,122, 71,188, 90, 0,255,143, 66,118,189, 77,106,205, 59, 48, 78, 81, 62,
+220,200,122, 71,188, 90, 0,255,184, 69,105, 62,161,220, 67,188,128, 96, 66, 62, 76, 21, 90, 78,241, 98, 0,255,163, 5,250,189,
+161,220, 67,188,128, 96, 66, 62,180,234, 90, 78,241, 98, 0,255,174, 41,137, 62,149,249, 43, 59, 59, 46, 55, 62, 85,245, 69, 69,
+ 25,107, 0,255,118, 16, 38,190,149,249, 43, 59, 59, 46, 55, 62,171, 10, 69, 69, 25,107, 0,255,129,176,157, 62,222,227, 61, 61,
+139, 64, 40, 62,232,223,211, 29, 67,120, 0,255, 28, 30, 79,190,222,227, 61, 61,139, 64, 40, 62, 24, 32,211, 29, 67,120, 0,255,
+ 55,142,159, 62,137, 31,162, 61,139, 64, 40, 62,148,210,123,238, 95,118, 0,255,136,217, 82,190,137, 31,162, 61,139, 64, 40, 62,
+108, 45,123,238, 95,118, 0,255, 21,245,153, 62,114, 95,214, 61,247,251, 43, 62,216,229,108,179, 43, 99, 0,255, 67,167, 71,190,
+114, 95,214, 61,247,251, 43, 62, 40, 26,108,179, 43, 99, 0,255,212,238,123, 62,173, 79, 5, 62,196,146, 77, 62,202,237,179,158,
+ 35, 81, 2,255,238,171, 15,190,173, 79, 5, 62,196,146, 77, 62, 54, 18,179,158, 35, 81, 2,255,166,124, 60, 62, 25, 11, 9, 62,
+156, 9, 85, 62, 24, 39,118,212,214,113, 2,255,129,115,160,189, 25, 11, 9, 62,156, 9, 85, 62,232,216,118,212,214,113, 2,255,
+155,156, 86, 62,133,198, 12, 62,196,146, 77, 62,213, 1,189,193,208,111, 0,255,106,179,212,189,133,198, 12, 62,196,146, 77, 62,
+ 43,254,189,193,208,111, 0,255,109, 42, 23, 62,216,126,230, 60,196,146, 77, 62,226, 84,192, 42,187, 85, 0,255, 31,158, 43,189,
+216,126,230, 60,196,146, 77, 62, 30,171,192, 42,187, 85, 0,255, 1,111, 19, 62, 63,191, 91, 61,196,146, 77, 62,235,102,196, 2,
+ 11, 76, 0,255,110,176, 28,189, 63,191, 91, 61,196,146, 77, 62, 21,153,196, 2, 11, 76, 0,255,185,194,212, 61,122,230, 38, 62,
+ 42,101, 10, 62,183,182,118,104, 5,246, 0,255,191,196,240, 58,122,230, 38, 62, 42,101, 10, 62, 73, 73,118,104, 5,246, 0,255,
+ 1,111, 19, 62,186,247,131, 62,150, 32, 14, 62,208,192,221, 66, 3,167, 2,255,110,176, 28,189,186,247,131, 62,150, 32, 14, 62,
+ 48, 63,221, 66, 3,167, 2,255,155,156, 86, 62,220,144,137, 62, 82,238, 2, 62, 59, 9, 89, 90,208,165, 2,255,106,179,212,189,
+220,144,137, 62, 82,238, 2, 62,197,246, 89, 90,208,165, 2,255,208,194,142, 62,139,175, 83, 62,107,138,224, 61,165, 37,104,114,
+176,212, 0,255,187, 66, 49,190,139,175, 83, 62,107,138,224, 61, 91,218,104,114,176,212, 0,255,152,105,189, 62, 14, 43, 35, 62,
+170,211,164, 61, 67, 45, 40,116, 1,227, 0,255, 37, 72,135,190, 14, 43, 35, 62,170,211,164, 61,189,210, 40,116, 1,227, 0,255,
+ 66,103,217, 62,133,198, 12, 62, 73,248,134, 61,100, 94,237, 79, 18,223, 0,255,207, 69,163,190,133,198, 12, 62, 73,248,134, 61,
+156,161,237, 79, 18,223, 0,255, 32,206,211, 62,119,163,200, 60,252,115,211, 60,247,120,255,221,165,231, 0,255,173,172,157,190,
+119,163,200, 60,252,115,211, 60, 9,135,255,221,165,231, 0,255,123,192,170, 62,188, 45, 85,189,112, 94, 52, 61,155, 76,106,154,
+ 19,242, 0,255, 16, 62,105,190,188, 45, 85,189,112, 94, 52, 61,101,179,106,154, 19,242, 0,255,140,144,131, 62, 0, 41,196,189,
+ 33,111,142, 61,204, 56, 26,142,138, 13, 0,255, 50,222, 26,190, 0, 41,196,189, 33,111,142, 61, 52,199, 26,142,138, 13, 0,255,
+203,133, 88, 61, 16,243,187, 62, 89,242,105,188, 0, 0,155,106,214, 70, 2,255,203,133, 88, 61,226,121,208, 62,254, 7, 62,190,
+ 0, 0,243,127, 82, 3, 2,255,203,133, 88, 61,254,152, 18,190, 11,214,236,190, 0, 0, 54,164,204,166, 3,255,203,133, 88, 61,
+173,190,136,190,139,142,124,189, 0, 0,179,129, 65,235, 0,255,203,133, 88, 61,205,243, 1,191, 73,248,134, 61, 0, 0,182,151,
+204,181, 2,255,203,133, 88, 61,247,217,218,190,241, 12, 56, 60, 0, 0,231,221,162,132, 2,255,203,133, 88, 61,161,222,162,190,
+147, 21,157, 57, 0, 0, 16,212,201,135, 0,255,203,133, 88, 61,207, 87,142,190,141,212,146,188, 0, 0,245,147, 97,187, 0,255,
+ 61,119,230, 62,239,172,106, 61,161, 43,253,189,164,125,181,235,156, 13, 0,255,202, 85,176,190,239,172,106, 61,161, 43,253,189,
+ 92,130,181,235,156, 13, 0,255,243, 84,232, 62,194,113,199, 61, 78, 26, 47,190,174,126, 23,238, 66,252, 0,255,128, 51,178,190,
+194,113,199, 61, 78, 26, 47,190, 82,129, 23,238, 66,252, 0,255, 32,206,211, 62,216, 49,147, 61,181,218,180,190, 70, 81,148, 13,
+ 15,158, 1,255,173,172,157,190,216, 49,147, 61,181,218,180,190,186,174,148, 13, 15,158, 1,255,174, 41,137, 62, 54,180, 27, 62,
+226, 76,244,190,123, 58,228, 21, 70,144, 3,255,118, 16, 38,190, 54,180, 27, 62,226, 76,244,190,133,197,228, 21, 70,144, 3,255,
+146,121,202, 62,239, 95,151,189,240, 61,238,189, 76, 89,139,164,161, 6, 2,255, 31, 88,148,190,239, 95,151,189,240, 61,238,189,
+180,166,139,164,161, 6, 2,255,197,226,168, 62, 97, 4,226,189,163, 21,103,190, 93, 38, 34,134,182, 7, 0,255,164,130,101,190,
+ 97, 4,226,189,163, 21,103,190,163,217, 34,134,182, 7, 0,255, 9, 21,180, 62,109, 27,100,189,255,252,178,190,106, 43,219,170,
+222,170, 1,255, 45,231,123,190,109, 27,100,189,255,252,178,190,150,212,219,170,222,170, 1,255,155,156, 86, 62,211, 91,217,188,
+ 85,248,234,190,168, 55,109,213,229,148, 2,255,106,179,212,189,211, 91,217,188, 85,248,234,190, 88,200,109,213,229,148, 2,255,
+ 30, 24, 38, 62,112, 61, 93,190,191,112, 37, 61,197,120, 36,255,158,213, 0,255,224, 84,103,189,112, 61, 93,190,191,112, 37, 61,
+ 59,135, 36,255,158,213, 0,255, 41,248, 11, 62,209, 24,123,190,176,102,236,188,188, 84, 20,181, 24,196, 0,255, 27,170,253,188,
+209, 24,123,190,176,102,236,188, 68,171, 20,181, 24,196, 0,255, 19, 56, 64, 62,110,117,196,190, 92, 79,241, 60,131, 79, 86,254,
+183,155, 2,255, 89,234,167,189,110,117,196,190, 92, 79,241, 60,125,176, 86,254,183,155, 2,255,246,142, 45, 62, 59, 19,146,190,
+ 95,149, 7, 61, 5, 99, 8, 1,231,174, 0,255, 32,152,130,189, 59, 19,146,190, 95,149, 7, 61,251,156, 8, 1,231,174, 0,255,
+ 47,225, 82, 62,234,249,244,190, 15,131, 22, 61, 65, 62,227,185,224,168, 2,255,146, 60,205,189,234,249,244,190, 15,131, 22, 61,
+191,193,227,185,224,168, 2,255, 25,158,242, 61,178,167,207,190,155,152,181, 60,133, 16,208,232, 55,131, 0,255,110,194, 80,188,
+178,167,207,190,155,152,181, 60,123,239,208,232, 55,131, 0,255,105,176,227, 61,201,103,155,190, 58,189,151, 60, 7, 48,163,224,
+149,141, 0,255,214,169,178,187,201,103,155,190, 58,189,151, 60,249,207,163,224,149,141, 0,255, 81,129, 4, 62,195,112,252,190,
+129, 39, 97, 61, 68, 12,218,158,147,173, 0,255, 89,243,193,188,195,112,252,190,129, 39, 97, 61,188,243,218,158,147,173, 0,255,
+ 70,161, 30, 62,163,166, 59,190,208, 57, 82, 61,195,124,106,227,203,255, 0,255,127,121, 73,189,163,166, 59,190,208, 57, 82, 61,
+ 61,131,106,227,203,255, 0,255,218,229, 26, 62,174,134, 33,190, 33,111,142, 61, 29,120,105,231,193, 36, 0,255,207,139, 58,189,
+174,134, 33,190, 33,111,142, 61,227,135,105,231,193, 36, 0,255,109, 42, 23, 62,186,102, 7,190,130, 74,172, 61,160,101,164,182,
+240, 25, 0,255, 31,158, 43,189,186,102, 7,190,130, 74,172, 61, 96,154,164,182,240, 25, 0,255,218,229, 26, 62,140,230,111,190,
+206,171,148,189,120, 84,221,159,198,253, 0,255,207,139, 58,189,140,230,111,190,206,171,148,189,136,171,221,159,198,253, 0,255,
+127,243, 67, 62, 83,148, 74,190, 16,205,139,190,255, 67, 42,151, 73,228, 2,255, 49, 97,175,189, 83,148, 74,190, 16,205,139,190,
+ 1,188, 42,151, 73,228, 2,255, 7, 88, 90, 62,235,104,248,189,244, 28,205,190,201, 63, 25,176, 0,179, 3,255, 66, 42,220,189,
+235,104,248,189,244, 28,205,190, 55,192, 25,176, 0,179, 3,255,248, 75,135, 62, 55,124,180, 62,187,202,167,190, 34, 56,160, 95,
+ 17,192, 2,255, 10, 85, 34,190, 55,124,180, 62,187,202,167,190,222,199,160, 95, 17,192, 2,255,248, 75,135, 62,232,105,195, 62,
+146, 76, 58,190, 54, 55,120,115,239, 0, 2,255, 10, 85, 34,190,232,105,195, 62,146, 76, 58,190,202,200,120,115,239, 0, 2,255,
+248, 75,135, 62,203,192,176, 62,105,252, 34,189,239, 63,164, 92,238, 60, 2,255, 10, 85, 34,190,203,192,176, 62,105,252, 34,189,
+ 17,192,164, 92,238, 60, 2,255,174, 41,137, 62,219,193, 68, 62,208, 57, 82, 61,123, 49,255,102,170, 57, 0,255,118, 16, 38,190,
+219,193, 68, 62,208, 57, 82, 61,133,206,255,102,170, 57, 0,255,220,155,200, 62,133,198, 12, 62, 95,172,248, 59,142, 98,198, 73,
+ 6, 35, 0,255,105,122,146,190,133,198, 12, 62, 95,172,248, 59,114,157,198, 73, 6, 35, 0,255, 83, 55,178, 62, 14, 43, 35, 62,
+141,212,146,188,129, 61,254,106,241, 33, 0,255,193, 43,120,190, 14, 43, 35, 62,141,212,146,188,127,194,254,106,241, 33, 0,255,
+ 9, 21,180, 62, 72, 76,141, 62,161, 43,253,189,234, 76,151, 87,221, 52, 0,255, 45,231,123,190, 72, 76,141, 62,161, 43,253,189,
+ 22,179,151, 87,221, 52, 0,255, 66,103,217, 62,247,106, 87, 62, 7,254,185,189,187,101, 28, 66,199, 40, 2,255,207, 69,163,190,
+247,106, 87, 62, 7,254,185,189, 69,154, 28, 66,199, 40, 2,255, 66,103,217, 62,236,138,113, 62, 26,177, 80,190,183,113, 68, 58,
+119,248, 2,255,207, 69,163,190,236,138,113, 62, 26,177, 80,190, 73,142, 68, 58,119,248, 2,255, 9, 21,180, 62,141,126,152, 62,
+ 83, 3,118,190,235, 86,238, 93,205,253, 0,255, 45,231,123,190,141,126,152, 62, 83, 3,118,190, 21,169,238, 93,205,253, 0,255,
+ 9, 21,180, 62, 38,179,135, 62,107,184,182,190,232, 85,154, 70,157,192, 2,255, 45,231,123,190, 38,179,135, 62,107,184,182,190,
+ 24,170,154, 70,157,192, 2,255, 66,103,217, 62,179, 56, 76, 62,153, 49,162,190,166,110,177, 42,222,207, 2,255,207, 69,163,190,
+179, 56, 76, 62,153, 49,162,190, 90,145,177, 42,222,207, 2,255,231,123,174, 62,154,232,206, 61, 56, 79,216,190, 58, 75, 57, 1,
+116,152, 3,255,232,180,112,190,154,232,206, 61, 56, 79,216,190,198,180, 57, 1,116,152, 3,255,208,194,142, 62,171,100, 40,189,
+170,250,206,190, 73, 70,147,187,200,173, 1,255,187, 66, 49,190,171,100, 40,189,170,250,206,190,183,185,147,187,200,173, 0,255,
+100, 0,223, 62,154,232,206, 61,191,190,121,190,194,114, 80, 41,207, 38, 0,255,241,222,168,190,154,232,206, 61,191,190,121,190,
+ 62,141, 80, 41,207, 38, 0,255,104, 51,120, 62,186,102, 7,190,127,153,163,189,232, 74,153,154, 28, 22, 0,255,130,240, 11,190,
+186,102, 7,190,127,153,163,189, 24,181,153,154, 28, 22, 0,255,214,178,129, 62,254,152, 18,190, 44,122,125,190, 89, 71,115,151,
+ 1,237, 0,255,198, 34, 23,190,254,152, 18,190, 44,122,125,190,167,184,115,151, 1,237, 0,255,202,203,239, 62,133,198, 12, 62,
+ 56, 86,132,190, 72,220,207, 93,106, 79, 2,255, 88,170,185,190,133,198, 12, 62, 56, 86,132,190,184, 35,207, 93,106, 79, 2,255,
+ 32,206,211, 62, 18,242,240,189,135,108, 84,190, 30, 15, 34,150, 84, 70, 2,255,173,172,157,190, 18,242,240,189,135,108, 84,190,
+226,240, 34,150, 84, 70, 2,255, 38,160, 9, 63,217,159,203,189,192,186,154,190,164, 67,138,166,172, 61, 0,255,219, 30,221,190,
+217,159,203,189,192,186,154,190, 92,188,138,166,172, 61, 0,255,172,140, 38, 63,211, 91,217,188,255,252,178,190,179, 83,223,206,
+114, 83, 0,255,244,123, 11,191,211, 91,217,188,255,252,178,190, 77,172,223,206,114, 83, 0,255, 95,242, 46, 63,194,113,199, 61,
+ 73, 31,177,190, 54, 92,232, 12,210, 87, 2,255,167,225, 19,191,194,113,199, 61, 73, 31,177,190,202,163,232, 12,210, 87, 2,255,
+138,243, 32, 63, 3, 75, 61, 62, 73, 31,177,190,247, 62,221, 83, 97, 73, 0,255,209,226, 5,191, 3, 75, 61, 62, 73, 31,177,190,
+ 9,193,221, 83, 97, 73, 0,255,112,194, 7, 63, 82, 93, 46, 62, 84,255,150,190,181, 5, 80,111,236, 62, 0,255,111, 99,217,190,
+ 82, 93, 46, 62, 84,255,150,190, 75,250, 80,111,236, 62, 0,255,149,211, 6, 63,241,129, 16, 62, 50,102,145,190,236, 69,117,239,
+236,105, 0,255,185,133,215,190,241,129, 16, 62, 50,102,145,190, 20,186,117,239,236,105, 0,255,104, 90, 27, 63, 54,180, 27, 62,
+113,168,169,190, 34, 24,205,231, 89,123, 0,255,175, 73, 0,191, 54,180, 27, 62,113,168,169,190,222,231,205,231, 89,123, 0,255,
+246,174, 36, 63, 97,150,169, 61,221, 99,173,190, 69,223, 16,252,173,123, 0,255, 62,158, 9,191, 97,150,169, 61,221, 99,173,190,
+187, 32, 16,252,173,123, 0,255,249, 38, 30, 63, 98,147,127,188,221, 99,173,190,171,239, 0, 39,207,120, 0,255, 64, 22, 3,191,
+ 98,147,127,188,221, 99,173,190, 85, 16, 0, 39,207,120, 0,255, 75,177, 8, 63, 23,233,143,189,158, 33,149,190, 9, 51, 56, 45,
+ 82,108, 0,255, 37, 65,219,190, 23,233,143,189,158, 33,149,190,247,204, 56, 45, 82,108, 0,255, 26,222,224, 62,120,196,173,189,
+243, 39, 88,190,147, 38,224, 62,153,104, 2,255,167,188,170,190,120,196,173,189,243, 39, 88,190,109,217,224, 62,153,104, 2,255,
+162, 66,247, 62,250,195,236, 61,204,154,128,190,218, 62,152,243,206,110, 2,255, 48, 33,193,190,250,195,236, 61,204,154,128,190,
+ 38,193,152,243,206,110, 2,255,196,219,252, 62, 17,132,184, 61, 50,102,145,190, 10, 87, 73,182, 19, 58, 0,255, 82,186,198,190,
+ 17,132,184, 61, 50,102,145,190,246,168, 73,182, 19, 58, 0,255, 21,238,237, 62,103,251,128,189, 44,122,125,190,232, 15,106,121,
+ 64, 37, 0,255,162,204,183,190,103,251,128,189, 44,122,125,190, 24,240,106,121, 64, 37, 0,255, 38,160, 9, 63,188, 45, 85,189,
+ 79, 15,164,190,157,239, 89,122,212, 33, 0,255,219, 30,221,190,188, 45, 85,189, 79, 15,164,190, 99, 16, 89,122,212, 33, 0,255,
+104, 90, 27, 63,223, 37, 8,188,107,184,182,190, 8,158,202, 81,185, 9, 0,255,175, 73, 0,191,223, 37, 8,188,107,184,182,190,
+248, 97,202, 81,185, 9, 0,255,138,243, 32, 63, 40, 68,132, 61,107,184,182,190, 60,131,145,239, 95, 23, 0,255,209,226, 5,191,
+ 40, 68,132, 61,107,184,182,190,196,124,145,239, 95, 23, 0,255,178,124, 25, 63,250,195,236, 61,181,218,180,190, 27,228, 22,153,
+206, 70, 0,255,242,215,252,190,250,195,236, 61,181,218,180,190,229, 27, 22,153,206, 70, 0,255,112,194, 7, 63, 74,214,221, 61,
+153, 49,162,190, 65, 68,253,168,113, 64, 0,255,111, 99,217,190, 74,214,221, 61,153, 49,162,190,191,187,253,168,113, 64, 0,255,
+135,153,228, 62, 97,150,169, 61, 44,122,125,190,113, 86,190,222, 87, 88, 0,255, 20,120,174,190, 97,150,169, 61, 44,122,125,190,
+143,169,190,222, 87, 88, 0,255,209,187,226, 62,216,126,230, 60,198,170,141,190,196, 95,107,182,100, 42, 0,255, 93,154,172,190,
+216,126,230, 60,198,170,141,190, 60,160,107,182,100, 42, 0,255,180, 18,208, 62,223, 37, 8,188,198,170,141,190, 42,111, 21, 14,
+220, 61, 0,255, 65,241,153,190,223, 37, 8,188,198,170,141,190,214,144, 21, 14,220, 61, 0,255,100, 0,223, 62,161,220, 67,188,
+198,170,141,190, 3, 79, 4, 91, 19, 43, 2,255,241,222,168,190,161,220, 67,188,198,170,141,190,253,176, 4, 91, 19, 43, 2,255,
+135,153,228, 62, 92, 82, 55,189,198,170,141,190,207,107,198,254,250, 68, 2,255, 20,120,174,190, 92, 82, 55,189,198,170,141,190,
+ 49,148,198,254,250, 68, 2,255,174, 34,221, 62, 29, 9,115,189,198,170,141,190, 7, 82,225, 64,200, 73, 0,255, 59, 1,167,190,
+ 29, 9,115,189,198,170,141,190,249,173,225, 64,200, 73, 0,255,220,155,200, 62,188, 45, 85,189,146, 76, 58,190, 38,117, 66,207,
+ 47,239, 0,255,105,122,146,190,188, 45, 85,189,146, 76, 58,190,218,138, 66,207, 47,239, 0,255, 38,190,198, 62,103,251,128,189,
+ 15,209,106,190,150, 97,139, 18,184, 80, 0,255,179,156,144,190,103,251,128,189, 15,209,106,190,106,158,139, 18,184, 80, 0,255,
+ 38,190,198, 62, 74,137, 10,189,231, 71,114,190, 17,116, 66,240,154, 51, 0,255,179,156,144,190, 74,137, 10,189,231, 71,114,190,
+239,139, 66,240,154, 51, 0,255, 66,103,217, 62, 45,246, 46, 61, 44,122,125,190,112,113,245,204, 39, 30, 0,255,207, 69,163,190,
+ 45,246, 46, 61, 44,122,125,190,144,142,245,204, 39, 30, 0,255,202,203,239, 62,159,154,121, 61, 16,205,139,190,105, 90, 61,185,
+146, 56, 0,255, 88,170,185,190,159,154,121, 61, 16,205,139,190,151,165, 61,185,146, 56, 0,255,202,203,239, 62,239,172,106, 61,
+ 10,221,152,190,191, 82,102,204,230, 82, 0,255, 88,170,185,190,239,172,106, 61, 10,221,152,190, 65,173,102,204,230, 82, 0,255,
+174, 34,221, 62, 29, 9,115,189, 10,221,152,190,246, 29, 64, 98, 94, 76, 0,255, 59, 1,167,190, 29, 9,115,189, 10,221,152,190,
+ 10,226, 64, 98, 94, 76, 0,255, 61,119,230, 62, 92, 82, 55,189, 10,221,152,190,150, 77,111, 17, 75,100, 0,255,202, 85,176,190,
+ 92, 82, 55,189, 10,221,152,190,106,178,111, 17, 75,100, 0,255, 26,222,224, 62, 98,147,127,188, 10,221,152,190,239, 60,190, 60,
+195, 94, 0,255,167,188,170,190, 98,147,127,188, 10,221,152,190, 17,195,190, 60,195, 94, 0,255,106,240,209, 62,223, 37, 8,188,
+ 10,221,152,190,199, 83,178, 23,209, 93, 0,255,247,206,155,190,223, 37, 8,188, 10,221,152,190, 57,172,178, 23,209, 93, 0,255,
+135,153,228, 62,216,126,230, 60, 10,221,152,190, 98, 73, 1,200,170, 88, 0,255, 20,120,174,190,216,126,230, 60, 10,221,152,190,
+158,182, 1,200,170, 88, 0,255, 38,160, 9, 63,154,232,206, 61,147, 65,175,190, 23, 68,166,223,112,103, 0,255,219, 30,221,190,
+154,232,206, 61,147, 65,175,190,233,187,166,223,112,103, 0,255,104, 90, 27, 63, 74,214,221, 61,249, 12,192,190,165, 18,156,216,
+ 89,120, 0,255,175, 73, 0,191, 74,214,221, 61,249, 12,192,190, 91,237,156,216, 89,120, 0,255, 27,192, 35, 63,159,154,121, 61,
+175,234,193,190, 25,185, 29,231,157,103, 0,255, 98,175, 8,191,159,154,121, 61,175,234,193,190,231, 70, 29,231,157,103, 0,255,
+249, 38, 30, 63,161,220, 67,188,249, 12,192,190, 43,209, 0, 64,119,100, 0,255, 64, 22, 3,191,161,220, 67,188,249, 12,192,190,
+213, 46, 0, 64,119,100, 0,255, 1,143, 10, 63,188, 45, 85,189, 73, 31,177,190, 52, 26,240, 92, 3, 84, 0,255,145,252,222,190,
+188, 45, 85,189, 73, 31,177,190,204,229,240, 92, 3, 84, 0,255, 21,238,237, 62, 29, 9,115,189, 16,205,139,190, 58, 8,116,111,
+101, 62, 0,255,162,204,183,190, 29, 9,115,189, 16,205,139,190,198,247,116,111,101, 62, 0,255,122,185,254, 62, 97,150,169, 61,
+ 45,118,158,190,198, 80,102,213,175, 89, 0,255, 8,152,200,190, 97,150,169, 61, 45,118,158,190, 58,175,102,213,175, 89, 0,255,
+202,203,239, 62,226,194,133,186,192,186,154,190,136, 25,130, 0,108,125, 0,255, 88,170,185,190,226,194,133,186,192,186,154,190,
+120,230,130, 0,108,125, 0,255, 14,254,250, 62,115,128,187,188,119,152,156,190, 2, 27, 58, 30,104,121, 0,255,156,220,196,190,
+115,128,187,188,119,152,156,190,254,228, 58, 30,104,121, 0,255,223,245, 4, 63, 77,106,205, 59, 79, 15,164,190,218, 55,126,253,
+ 35,115, 0,255, 76,202,211,190, 77,106,205, 59, 79, 15,164,190, 38,200,126,253, 35,115, 0,255,152, 75, 0, 63,216,126,230, 60,
+227, 83,160,190,164, 41,199,255, 8,121, 0,255,190,117,202,190,216,126,230, 60,227, 83,160,190, 92,214,199,255, 8,121, 0,255,
+149,211, 6, 63,239,172,106, 61, 5,237,165,190,237, 39,191, 9, 55,121, 0,255,185,133,215,190,239,172,106, 61, 5,237,165,190,
+ 19,216,191, 9, 55,121, 0,255,220,125, 11, 63,205, 26, 17, 61,187,202,167,190,208, 46, 41,244,137,118, 0,255, 71,218,224,190,
+205, 26, 17, 61,187,202,167,190, 48,209, 41,244,137,118, 0,255,218, 5, 18, 63,222,227, 61, 61,113,168,169,190, 70, 53, 84, 3,
+ 85,116, 2,255, 65,234,237,190,222,227, 61, 61,113,168,169,190,186,202, 84, 3, 85,116, 2,255, 73, 57, 15, 63,176,168,154, 61,
+113,168,169,190, 99, 44, 36, 38,212,113, 2,255, 31, 81,232,190,176,168,154, 61,113,168,169,190,157,211, 36, 38,212,113, 2,255,
+112,194, 7, 63, 54,180, 27, 62,249, 12,192,190,249,198, 3, 72,222,166, 3,255,111, 99,217,190, 54,180, 27, 62,249, 12,192,190,
+ 7, 57, 3, 72,222,166, 3,255, 64,209, 34, 63,230,161, 42, 62,170,250,206,190,198, 37,123, 68,174,154, 3,255,135,192, 7,191,
+230,161, 42, 62,170,250,206,190, 58,218,123, 68,174,154, 3,255, 21,208, 48, 63, 57, 13,177, 61,102,200,195,190, 3,121,201, 17,
+ 73,218, 3,255, 93,191, 21,191, 57, 13,177, 61,102,200,195,190,253,134,201, 17, 73,218, 3,255, 24, 72, 42, 63,211, 91,217,188,
+ 62, 63,203,190, 59, 82, 75,200, 70,175, 3,255, 96, 55, 15,191,211, 91,217,188, 62, 63,203,190,197,173, 75,200, 70,175, 3,255,
+ 38,160, 9, 63, 40,178,188,189,175,234,193,190,134,249,184,165,129,165, 3,255,219, 30,221,190, 40,178,188,189,175,234,193,190,
+122, 6,184,165,129,165, 3,255,140,137,215, 62, 97, 4,226,189,192,186,154,190,126,249,122,163,205,167, 1,255, 25,104,161,190,
+ 97, 4,226,189,192,186,154,190,130, 6,122,163,205,167, 1,255,243, 84,232, 62, 65,148, 1, 62,187,202,167,190, 93,193,224, 65,
+229,165, 1,255,128, 51,178,190, 65,148, 1, 62,187,202,167,190,163, 62,224, 65,229,165, 1,255, 68, 65, 84, 65, 44, 1, 0, 0,
+200,129,152, 2, 21, 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,208,213,166, 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, 68, 65, 84, 65, 28, 47, 0, 0,
+208,213,166, 2, 54, 0, 0, 0,237, 3, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 34, 0, 2, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0, 43, 0, 0, 0, 45, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 46, 0, 0, 0, 0, 0, 34, 0, 44, 0, 0, 0, 46, 0, 0, 0, 0, 0, 34, 0,
+ 3, 0, 0, 0, 44, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 41, 0, 0, 0,
+ 0, 0, 34, 0, 41, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 34, 0, 42, 0, 0, 0,
+ 44, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 42, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0,
+ 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 34, 0, 7, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 34, 0, 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 7, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 34, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0,
+ 1, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0, 10, 0, 0, 0, 12, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 14, 0, 0, 0,
+ 0, 0, 34, 0, 8, 0, 0, 0, 14, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0, 13, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0,
+ 15, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0, 0, 34, 0, 7, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0,
+ 14, 0, 0, 0, 19, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0, 19, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 34, 0, 18, 0, 0, 0, 20, 0, 0, 0, 0, 0, 34, 0, 16, 0, 0, 0, 18, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0,
+ 21, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0, 21, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0, 22, 0, 0, 0, 0, 0, 34, 0,
+ 13, 0, 0, 0, 22, 0, 0, 0, 0, 0, 34, 0, 21, 0, 0, 0, 23, 0, 0, 0, 0, 0, 34, 0, 23, 0, 0, 0, 25, 0, 0, 0,
+ 0, 0, 34, 0, 19, 0, 0, 0, 25, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 26, 0, 0, 0, 0, 0, 34, 0, 22, 0, 0, 0,
+ 24, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0, 26, 0, 0, 0, 0, 0, 34, 0, 25, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0,
+ 17, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0, 26, 0, 0, 0, 28, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 28, 0, 0, 0,
+ 0, 0, 34, 0, 25, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 29, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 27, 0, 0, 0,
+ 29, 0, 0, 0, 0, 0, 34, 0, 30, 0, 0, 0, 32, 0, 0, 0, 0, 0, 34, 0, 26, 0, 0, 0, 32, 0, 0, 0, 0, 0, 34, 0,
+ 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 34, 0, 23, 0, 0, 0, 33, 0, 0, 0, 0, 0, 34, 0, 31, 0, 0, 0, 33, 0, 0, 0,
+ 0, 0, 34, 0, 32, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 33, 0, 0, 0,
+ 35, 0, 0, 0, 0, 0, 34, 0, 35, 0, 0, 0, 37, 0, 0, 0, 0, 0, 34, 0, 31, 0, 0, 0, 37, 0, 0, 0, 0, 0, 34, 0,
+ 36, 0, 0, 0, 38, 0, 0, 0, 0, 0, 34, 0, 34, 0, 0, 0, 36, 0, 0, 0, 0, 0, 34, 0, 32, 0, 0, 0, 38, 0, 0, 0,
+ 0, 0, 34, 0, 37, 0, 0, 0, 39, 0, 0, 0, 0, 0, 34, 0, 29, 0, 0, 0, 39, 0, 0, 0, 0, 0, 34, 0, 38, 0, 0, 0,
+ 40, 0, 0, 0, 0, 0, 34, 0, 30, 0, 0, 0, 40, 0, 0, 0, 0, 0, 34, 0, 37, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0,
+ 39, 0, 0, 0, 41, 0, 0, 0, 0, 0, 34, 0, 38, 0, 0, 0, 44, 0, 0, 0, 0, 0, 34, 0, 40, 0, 0, 0, 42, 0, 0, 0,
+ 0, 0, 34, 0, 35, 0, 0, 0, 45, 0, 0, 0, 0, 0, 34, 0, 36, 0, 0, 0, 46, 0, 0, 0, 0, 0, 34, 0, 35, 0, 0, 0,
+ 49, 0, 0, 0, 0, 0, 34, 0, 47, 0, 0, 0, 49, 0, 0, 0, 0, 0, 34, 0, 45, 0, 0, 0, 47, 0, 0, 0, 0, 0, 34, 0,
+ 36, 0, 0, 0, 50, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0, 48, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 50, 0, 0, 0,
+ 0, 0, 34, 0, 33, 0, 0, 0, 51, 0, 0, 0, 0, 0, 34, 0, 49, 0, 0, 0, 51, 0, 0, 0, 0, 0, 34, 0, 34, 0, 0, 0,
+ 52, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0, 52, 0, 0, 0, 0, 0, 34, 0, 23, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0,
+ 51, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 54, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 54, 0, 0, 0,
+ 0, 0, 34, 0, 21, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 53, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 22, 0, 0, 0,
+ 56, 0, 0, 0, 0, 0, 34, 0, 54, 0, 0, 0, 56, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 57, 0, 0, 0, 0, 0, 34, 0,
+ 55, 0, 0, 0, 57, 0, 0, 0, 0, 0, 34, 0, 13, 0, 0, 0, 58, 0, 0, 0, 0, 0, 34, 0, 56, 0, 0, 0, 58, 0, 0, 0,
+ 0, 0, 34, 0, 10, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0,
+ 62, 0, 0, 0, 0, 0, 34, 0, 58, 0, 0, 0, 62, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0,
+ 61, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0, 62, 0, 0, 0, 64, 0, 0, 0,
+ 0, 0, 34, 0, 47, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0, 59, 0, 0, 0,
+ 63, 0, 0, 0, 0, 0, 34, 0, 47, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0,
+ 48, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 59, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0, 62, 0, 0, 0,
+ 0, 0, 34, 0, 57, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 58, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 55, 0, 0, 0,
+ 59, 0, 0, 0, 0, 0, 34, 0, 56, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 53, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0,
+ 54, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 51, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 60, 0, 0, 0,
+ 0, 0, 34, 0, 49, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 87, 0, 0, 0,
+171, 0, 0, 0, 0, 0, 34, 0,171, 0, 0, 0,173, 0, 0, 0, 0, 0, 34, 0, 89, 0, 0, 0,173, 0, 0, 0, 0, 0, 34, 0,
+ 87, 0, 0, 0, 89, 0, 0, 0, 0, 0, 34, 0,172, 0, 0, 0,173, 0, 0, 0, 0, 0, 34, 0, 88, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 34, 0, 88, 0, 0, 0, 89, 0, 0, 0, 0, 0, 34, 0, 85, 0, 0, 0,169, 0, 0, 0, 0, 0, 34, 0,169, 0, 0, 0,
+171, 0, 0, 0, 0, 0, 34, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 34, 0,170, 0, 0, 0,172, 0, 0, 0, 0, 0, 34, 0,
+ 86, 0, 0, 0,170, 0, 0, 0, 0, 0, 34, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0,167, 0, 0, 0,
+ 0, 0, 34, 0,167, 0, 0, 0,169, 0, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0, 85, 0, 0, 0, 0, 0, 34, 0,168, 0, 0, 0,
+170, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0,168, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0, 86, 0, 0, 0, 0, 0, 34, 0,
+ 81, 0, 0, 0,165, 0, 0, 0, 0, 0, 34, 0,165, 0, 0, 0,167, 0, 0, 0, 0, 0, 34, 0, 81, 0, 0, 0, 83, 0, 0, 0,
+ 0, 0, 34, 0,166, 0, 0, 0,168, 0, 0, 0, 0, 0, 34, 0, 82, 0, 0, 0,166, 0, 0, 0, 0, 0, 34, 0, 82, 0, 0, 0,
+ 84, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0,163, 0, 0, 0, 0, 0, 34, 0,163, 0, 0, 0,165, 0, 0, 0, 0, 0, 34, 0,
+ 79, 0, 0, 0, 81, 0, 0, 0, 0, 0, 34, 0,164, 0, 0, 0,166, 0, 0, 0, 0, 0, 34, 0, 80, 0, 0, 0,164, 0, 0, 0,
+ 0, 0, 34, 0, 80, 0, 0, 0, 82, 0, 0, 0, 0, 0, 34, 0, 77, 0, 0, 0, 90, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0,
+143, 0, 0, 0, 0, 0, 34, 0,143, 0, 0, 0,161, 0, 0, 0, 0, 0, 34, 0, 77, 0, 0, 0,161, 0, 0, 0, 0, 0, 34, 0,
+ 91, 0, 0, 0,144, 0, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0, 91, 0, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0,162, 0, 0, 0,
+ 0, 0, 34, 0,144, 0, 0, 0,162, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0, 92, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0,
+145, 0, 0, 0, 0, 0, 34, 0,143, 0, 0, 0,145, 0, 0, 0, 0, 0, 34, 0, 93, 0, 0, 0,146, 0, 0, 0, 0, 0, 34, 0,
+ 91, 0, 0, 0, 93, 0, 0, 0, 0, 0, 34, 0,144, 0, 0, 0,146, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0, 94, 0, 0, 0,
+ 0, 0, 34, 0, 94, 0, 0, 0,147, 0, 0, 0, 0, 0, 34, 0,145, 0, 0, 0,147, 0, 0, 0, 0, 0, 34, 0, 95, 0, 0, 0,
+148, 0, 0, 0, 0, 0, 34, 0, 93, 0, 0, 0, 95, 0, 0, 0, 0, 0, 34, 0,146, 0, 0, 0,148, 0, 0, 0, 0, 0, 34, 0,
+ 94, 0, 0, 0, 96, 0, 0, 0, 0, 0, 34, 0, 96, 0, 0, 0,149, 0, 0, 0, 0, 0, 34, 0,147, 0, 0, 0,149, 0, 0, 0,
+ 0, 0, 34, 0, 97, 0, 0, 0,150, 0, 0, 0, 0, 0, 34, 0, 95, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0,148, 0, 0, 0,
+150, 0, 0, 0, 0, 0, 34, 0, 96, 0, 0, 0, 98, 0, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0,151, 0, 0, 0, 0, 0, 34, 0,
+149, 0, 0, 0,151, 0, 0, 0, 0, 0, 34, 0, 99, 0, 0, 0,152, 0, 0, 0, 0, 0, 34, 0, 97, 0, 0, 0, 99, 0, 0, 0,
+ 0, 0, 34, 0,150, 0, 0, 0,152, 0, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0,100, 0, 0, 0, 0, 0, 34, 0,100, 0, 0, 0,
+153, 0, 0, 0, 0, 0, 34, 0,151, 0, 0, 0,153, 0, 0, 0, 0, 0, 34, 0,101, 0, 0, 0,154, 0, 0, 0, 0, 0, 34, 0,
+ 99, 0, 0, 0,101, 0, 0, 0, 0, 0, 34, 0,152, 0, 0, 0,154, 0, 0, 0, 0, 0, 34, 0,100, 0, 0, 0,102, 0, 0, 0,
+ 0, 0, 34, 0,102, 0, 0, 0,155, 0, 0, 0, 0, 0, 34, 0,153, 0, 0, 0,155, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,
+156, 0, 0, 0, 0, 0, 34, 0,101, 0, 0, 0,103, 0, 0, 0, 0, 0, 34, 0,154, 0, 0, 0,156, 0, 0, 0, 0, 0, 34, 0,
+102, 0, 0, 0,104, 0, 0, 0, 0, 0, 34, 0,104, 0, 0, 0,157, 0, 0, 0, 0, 0, 34, 0,155, 0, 0, 0,157, 0, 0, 0,
+ 0, 0, 34, 0,105, 0, 0, 0,158, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,105, 0, 0, 0, 0, 0, 34, 0,156, 0, 0, 0,
+158, 0, 0, 0, 0, 0, 34, 0,104, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0,106, 0, 0, 0,159, 0, 0, 0, 0, 0, 34, 0,
+157, 0, 0, 0,159, 0, 0, 0, 0, 0, 34, 0,107, 0, 0, 0,160, 0, 0, 0, 0, 0, 34, 0,105, 0, 0, 0,107, 0, 0, 0,
+ 0, 0, 34, 0,158, 0, 0, 0,160, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0,
+ 66, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0,159, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0,107, 0, 0, 0, 0, 0, 34, 0,
+ 66, 0, 0, 0,160, 0, 0, 0, 0, 0, 34, 0,108, 0, 0, 0,125, 0, 0, 0, 0, 0, 34, 0,125, 0, 0, 0,157, 0, 0, 0,
+ 0, 0, 34, 0,108, 0, 0, 0,159, 0, 0, 0, 0, 0, 34, 0,126, 0, 0, 0,158, 0, 0, 0, 0, 0, 34, 0,109, 0, 0, 0,
+126, 0, 0, 0, 0, 0, 34, 0,109, 0, 0, 0,160, 0, 0, 0, 0, 0, 34, 0,125, 0, 0, 0,176, 0, 0, 0, 0, 0, 34, 0,
+155, 0, 0, 0,176, 0, 0, 0, 0, 0, 34, 0,156, 0, 0, 0,177, 0, 0, 0, 0, 0, 34, 0,126, 0, 0, 0,177, 0, 0, 0,
+ 0, 0, 34, 0,123, 0, 0, 0,153, 0, 0, 0, 0, 0, 34, 0,123, 0, 0, 0,176, 0, 0, 0, 0, 0, 34, 0,124, 0, 0, 0,
+154, 0, 0, 0, 0, 0, 34, 0,124, 0, 0, 0,177, 0, 0, 0, 0, 0, 34, 0,121, 0, 0, 0,151, 0, 0, 0, 0, 0, 34, 0,
+121, 0, 0, 0,123, 0, 0, 0, 0, 0, 34, 0,122, 0, 0, 0,152, 0, 0, 0, 0, 0, 34, 0,122, 0, 0, 0,124, 0, 0, 0,
+ 0, 0, 34, 0,119, 0, 0, 0,149, 0, 0, 0, 0, 0, 34, 0,119, 0, 0, 0,121, 0, 0, 0, 0, 0, 34, 0,120, 0, 0, 0,
+150, 0, 0, 0, 0, 0, 34, 0,120, 0, 0, 0,122, 0, 0, 0, 0, 0, 34, 0,117, 0, 0, 0,147, 0, 0, 0, 0, 0, 34, 0,
+117, 0, 0, 0,119, 0, 0, 0, 0, 0, 34, 0,118, 0, 0, 0,148, 0, 0, 0, 0, 0, 34, 0,118, 0, 0, 0,120, 0, 0, 0,
+ 0, 0, 34, 0,115, 0, 0, 0,145, 0, 0, 0, 0, 0, 34, 0,115, 0, 0, 0,117, 0, 0, 0, 0, 0, 34, 0,116, 0, 0, 0,
+146, 0, 0, 0, 0, 0, 34, 0,116, 0, 0, 0,118, 0, 0, 0, 0, 0, 34, 0,113, 0, 0, 0,143, 0, 0, 0, 0, 0, 34, 0,
+113, 0, 0, 0,115, 0, 0, 0, 0, 0, 34, 0,114, 0, 0, 0,144, 0, 0, 0, 0, 0, 34, 0,114, 0, 0, 0,116, 0, 0, 0,
+ 0, 0, 34, 0,112, 0, 0, 0,162, 0, 0, 0, 0, 0, 34, 0,112, 0, 0, 0,114, 0, 0, 0, 0, 0, 34, 0,174, 0, 0, 0,
+178, 0, 0, 0, 0, 0, 34, 0,161, 0, 0, 0,174, 0, 0, 0, 0, 0, 34, 0,174, 0, 0, 0,179, 0, 0, 0, 0, 0, 34, 0,
+112, 0, 0, 0,179, 0, 0, 0, 0, 0, 34, 0,162, 0, 0, 0,174, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0,110, 0, 0, 0,
+ 0, 0, 34, 0,108, 0, 0, 0,110, 0, 0, 0, 0, 0, 34, 0,109, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0,
+111, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0,175, 0, 0, 0, 0, 0, 34, 0,175, 0, 0, 0,180, 0, 0, 0, 0, 0, 34, 0,
+110, 0, 0, 0,180, 0, 0, 0, 0, 0, 34, 0,111, 0, 0, 0,181, 0, 0, 0, 0, 0, 34, 0,175, 0, 0, 0,181, 0, 0, 0,
+ 0, 0, 34, 0,178, 0, 0, 0,180, 0, 0, 0, 0, 0, 34, 0,174, 0, 0, 0,175, 0, 0, 0, 0, 0, 32, 0,179, 0, 0, 0,
+181, 0, 0, 0, 0, 0, 34, 0,132, 0, 0, 0,134, 0, 0, 0, 0, 0, 34, 0,134, 0, 0, 0,173, 0, 0, 0, 0, 0, 34, 0,
+132, 0, 0, 0,171, 0, 0, 0, 0, 0, 34, 0,133, 0, 0, 0,134, 0, 0, 0, 0, 0, 34, 0,133, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 34, 0,130, 0, 0, 0,132, 0, 0, 0, 0, 0, 34, 0,130, 0, 0, 0,169, 0, 0, 0, 0, 0, 34, 0,131, 0, 0, 0,
+133, 0, 0, 0, 0, 0, 34, 0,131, 0, 0, 0,170, 0, 0, 0, 0, 0, 34, 0,128, 0, 0, 0,130, 0, 0, 0, 0, 0, 34, 0,
+128, 0, 0, 0,167, 0, 0, 0, 0, 0, 34, 0,129, 0, 0, 0,131, 0, 0, 0, 0, 0, 34, 0,129, 0, 0, 0,168, 0, 0, 0,
+ 0, 0, 34, 0,163, 0, 0, 0,184, 0, 0, 0, 0, 0, 34, 0,182, 0, 0, 0,184, 0, 0, 0, 0, 0, 34, 0,165, 0, 0, 0,
+182, 0, 0, 0, 0, 0, 34, 0,183, 0, 0, 0,185, 0, 0, 0, 0, 0, 34, 0,164, 0, 0, 0,185, 0, 0, 0, 0, 0, 34, 0,
+166, 0, 0, 0,183, 0, 0, 0, 0, 0, 34, 0,128, 0, 0, 0,182, 0, 0, 0, 0, 0, 34, 0,129, 0, 0, 0,183, 0, 0, 0,
+ 0, 0, 34, 0,141, 0, 0, 0,187, 0, 0, 0, 0, 0, 34, 0,186, 0, 0, 0,187, 0, 0, 0, 0, 0, 32, 0,184, 0, 0, 0,
+186, 0, 0, 0, 0, 0, 34, 0,141, 0, 0, 0,184, 0, 0, 0, 0, 0, 34, 0,142, 0, 0, 0,187, 0, 0, 0, 0, 0, 34, 0,
+142, 0, 0, 0,185, 0, 0, 0, 0, 0, 34, 0,185, 0, 0, 0,186, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0,186, 0, 0, 0,
+ 0, 0, 32, 0, 67, 0, 0, 0,182, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0,183, 0, 0, 0, 0, 0, 34, 0,127, 0, 0, 0,
+128, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0,127, 0, 0, 0, 0, 0, 32, 0,127, 0, 0, 0,129, 0, 0, 0, 0, 0, 34, 0,
+139, 0, 0, 0,190, 0, 0, 0, 0, 0, 34, 0,188, 0, 0, 0,190, 0, 0, 0, 0, 0, 34, 0,141, 0, 0, 0,188, 0, 0, 0,
+ 0, 0, 34, 0,139, 0, 0, 0,141, 0, 0, 0, 0, 0, 34, 0,189, 0, 0, 0,191, 0, 0, 0, 0, 0, 34, 0,140, 0, 0, 0,
+191, 0, 0, 0, 0, 0, 34, 0,140, 0, 0, 0,142, 0, 0, 0, 0, 0, 34, 0,142, 0, 0, 0,189, 0, 0, 0, 0, 0, 34, 0,
+137, 0, 0, 0,192, 0, 0, 0, 0, 0, 34, 0,190, 0, 0, 0,192, 0, 0, 0, 0, 0, 34, 0,137, 0, 0, 0,139, 0, 0, 0,
+ 0, 0, 34, 0,191, 0, 0, 0,193, 0, 0, 0, 0, 0, 34, 0,138, 0, 0, 0,193, 0, 0, 0, 0, 0, 34, 0,138, 0, 0, 0,
+140, 0, 0, 0, 0, 0, 34, 0,136, 0, 0, 0,194, 0, 0, 0, 0, 0, 34, 0,192, 0, 0, 0,194, 0, 0, 0, 0, 0, 34, 0,
+136, 0, 0, 0,137, 0, 0, 0, 0, 0, 34, 0,193, 0, 0, 0,195, 0, 0, 0, 0, 0, 34, 0,136, 0, 0, 0,195, 0, 0, 0,
+ 0, 0, 34, 0,136, 0, 0, 0,138, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0,135, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0,
+194, 0, 0, 0, 0, 0, 34, 0,135, 0, 0, 0,136, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0,195, 0, 0, 0, 0, 0, 34, 0,
+ 68, 0, 0, 0,188, 0, 0, 0, 0, 0, 34, 0, 68, 0, 0, 0,187, 0, 0, 0, 0, 0, 34, 0, 68, 0, 0, 0,189, 0, 0, 0,
+ 0, 0, 34, 0,188, 0, 0, 0,203, 0, 0, 0, 0, 0, 34, 0,203, 0, 0, 0,205, 0, 0, 0, 0, 0, 34, 0, 68, 0, 0, 0,
+205, 0, 0, 0, 0, 0, 34, 0,189, 0, 0, 0,204, 0, 0, 0, 0, 0, 34, 0,204, 0, 0, 0,205, 0, 0, 0, 0, 0, 34, 0,
+ 69, 0, 0, 0,196, 0, 0, 0, 0, 0, 34, 0,196, 0, 0, 0,197, 0, 0, 0, 0, 0, 34, 0,194, 0, 0, 0,197, 0, 0, 0,
+ 0, 0, 34, 0,196, 0, 0, 0,198, 0, 0, 0, 0, 0, 34, 0,195, 0, 0, 0,198, 0, 0, 0, 0, 0, 34, 0,197, 0, 0, 0,
+199, 0, 0, 0, 0, 0, 34, 0,192, 0, 0, 0,199, 0, 0, 0, 0, 0, 34, 0,198, 0, 0, 0,200, 0, 0, 0, 0, 0, 34, 0,
+193, 0, 0, 0,200, 0, 0, 0, 0, 0, 34, 0,199, 0, 0, 0,201, 0, 0, 0, 0, 0, 34, 0,190, 0, 0, 0,201, 0, 0, 0,
+ 0, 0, 34, 0,200, 0, 0, 0,202, 0, 0, 0, 0, 0, 34, 0,191, 0, 0, 0,202, 0, 0, 0, 0, 0, 34, 0,201, 0, 0, 0,
+203, 0, 0, 0, 0, 0, 34, 0,202, 0, 0, 0,204, 0, 0, 0, 0, 0, 34, 0,196, 0, 0, 0,201, 0, 0, 0, 0, 0, 34, 0,
+196, 0, 0, 0,202, 0, 0, 0, 0, 0, 34, 0,196, 0, 0, 0,205, 0, 0, 0, 0, 0, 34, 0,137, 0, 0, 0,161, 0, 0, 0,
+ 0, 0, 34, 0,136, 0, 0, 0,174, 0, 0, 0, 0, 0, 34, 0,138, 0, 0, 0,162, 0, 0, 0, 0, 0, 34, 0,139, 0, 0, 0,
+208, 0, 0, 0, 0, 0, 34, 0,161, 0, 0, 0,208, 0, 0, 0, 0, 0, 34, 0,140, 0, 0, 0,209, 0, 0, 0, 0, 0, 34, 0,
+162, 0, 0, 0,209, 0, 0, 0, 0, 0, 34, 0,141, 0, 0, 0,210, 0, 0, 0, 0, 0, 34, 0,208, 0, 0, 0,210, 0, 0, 0,
+ 0, 0, 34, 0,142, 0, 0, 0,211, 0, 0, 0, 0, 0, 34, 0,209, 0, 0, 0,211, 0, 0, 0, 0, 0, 34, 0,163, 0, 0, 0,
+210, 0, 0, 0, 0, 0, 34, 0,164, 0, 0, 0,211, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0,206, 0, 0, 0, 0, 0, 34, 0,
+206, 0, 0, 0,210, 0, 0, 0, 0, 0, 34, 0,207, 0, 0, 0,211, 0, 0, 0, 0, 0, 34, 0, 80, 0, 0, 0,207, 0, 0, 0,
+ 0, 0, 34, 0,206, 0, 0, 0,212, 0, 0, 0, 0, 0, 34, 0,208, 0, 0, 0,212, 0, 0, 0, 0, 0, 34, 0,209, 0, 0, 0,
+213, 0, 0, 0, 0, 0, 34, 0,207, 0, 0, 0,213, 0, 0, 0, 0, 0, 34, 0, 77, 0, 0, 0,212, 0, 0, 0, 0, 0, 34, 0,
+ 78, 0, 0, 0,213, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0,127, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0,219, 0, 0, 0,
+ 0, 0, 34, 0,128, 0, 0, 0,219, 0, 0, 0, 0, 0, 34, 0,129, 0, 0, 0,220, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0,
+220, 0, 0, 0, 0, 0, 34, 0,217, 0, 0, 0,219, 0, 0, 0, 0, 0, 34, 0,130, 0, 0, 0,217, 0, 0, 0, 0, 0, 34, 0,
+131, 0, 0, 0,218, 0, 0, 0, 0, 0, 34, 0,218, 0, 0, 0,220, 0, 0, 0, 0, 0, 34, 0,215, 0, 0, 0,217, 0, 0, 0,
+ 0, 0, 34, 0,132, 0, 0, 0,215, 0, 0, 0, 0, 0, 34, 0,133, 0, 0, 0,216, 0, 0, 0, 0, 0, 34, 0,216, 0, 0, 0,
+218, 0, 0, 0, 0, 0, 34, 0,214, 0, 0, 0,215, 0, 0, 0, 0, 0, 34, 0,134, 0, 0, 0,214, 0, 0, 0, 0, 0, 34, 0,
+214, 0, 0, 0,216, 0, 0, 0, 0, 0, 34, 0,215, 0, 0, 0,226, 0, 0, 0, 0, 0, 34, 0,226, 0, 0, 0,228, 0, 0, 0,
+ 0, 0, 34, 0,214, 0, 0, 0,228, 0, 0, 0, 0, 0, 34, 0,216, 0, 0, 0,227, 0, 0, 0, 0, 0, 34, 0,227, 0, 0, 0,
+228, 0, 0, 0, 0, 0, 34, 0,217, 0, 0, 0,224, 0, 0, 0, 0, 0, 34, 0,224, 0, 0, 0,226, 0, 0, 0, 0, 0, 34, 0,
+218, 0, 0, 0,225, 0, 0, 0, 0, 0, 34, 0,225, 0, 0, 0,227, 0, 0, 0, 0, 0, 34, 0,219, 0, 0, 0,222, 0, 0, 0,
+ 0, 0, 34, 0,222, 0, 0, 0,224, 0, 0, 0, 0, 0, 34, 0,220, 0, 0, 0,223, 0, 0, 0, 0, 0, 34, 0,223, 0, 0, 0,
+225, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0,221, 0, 0, 0, 0, 0, 34, 0,221, 0, 0, 0,222, 0, 0, 0, 0, 0, 34, 0,
+221, 0, 0, 0,223, 0, 0, 0, 0, 0, 34, 0,221, 0, 0, 0,228, 0, 0, 0, 0, 0, 34, 0,222, 0, 0, 0,226, 0, 0, 0,
+ 0, 0, 34, 0,223, 0, 0, 0,227, 0, 0, 0, 0, 0, 34, 0,178, 0, 0, 0,231, 0, 0, 0, 0, 0, 34, 0,229, 0, 0, 0,
+231, 0, 0, 0, 0, 0, 34, 0,180, 0, 0, 0,229, 0, 0, 0, 0, 0, 34, 0,179, 0, 0, 0,232, 0, 0, 0, 0, 0, 34, 0,
+181, 0, 0, 0,230, 0, 0, 0, 0, 0, 34, 0,230, 0, 0, 0,232, 0, 0, 0, 0, 0, 34, 0,229, 0, 0, 0,251, 0, 0, 0,
+ 0, 0, 34, 0,110, 0, 0, 0,251, 0, 0, 0, 0, 0, 34, 0,111, 0, 0, 0,252, 0, 0, 0, 0, 0, 34, 0,230, 0, 0, 0,
+252, 0, 0, 0, 0, 0, 34, 0,251, 0, 0, 0,253, 0, 0, 0, 0, 0, 34, 0,108, 0, 0, 0,253, 0, 0, 0, 0, 0, 34, 0,
+109, 0, 0, 0,254, 0, 0, 0, 0, 0, 34, 0,252, 0, 0, 0,254, 0, 0, 0, 0, 0, 34, 0,231, 0, 0, 0,249, 0, 0, 0,
+ 0, 0, 34, 0,112, 0, 0, 0,250, 0, 0, 0, 0, 0, 34, 0,232, 0, 0, 0,250, 0, 0, 0, 0, 0, 34, 0,113, 0, 0, 0,
+247, 0, 0, 0, 0, 0, 34, 0,247, 0, 0, 0,249, 0, 0, 0, 0, 0, 34, 0,114, 0, 0, 0,248, 0, 0, 0, 0, 0, 34, 0,
+248, 0, 0, 0,250, 0, 0, 0, 0, 0, 34, 0,115, 0, 0, 0,245, 0, 0, 0, 0, 0, 34, 0,245, 0, 0, 0,247, 0, 0, 0,
+ 0, 0, 34, 0,116, 0, 0, 0,246, 0, 0, 0, 0, 0, 34, 0,246, 0, 0, 0,248, 0, 0, 0, 0, 0, 34, 0,117, 0, 0, 0,
+243, 0, 0, 0, 0, 0, 34, 0,243, 0, 0, 0,245, 0, 0, 0, 0, 0, 34, 0,118, 0, 0, 0,244, 0, 0, 0, 0, 0, 34, 0,
+244, 0, 0, 0,246, 0, 0, 0, 0, 0, 34, 0,119, 0, 0, 0,241, 0, 0, 0, 0, 0, 34, 0,241, 0, 0, 0,243, 0, 0, 0,
+ 0, 0, 34, 0,120, 0, 0, 0,242, 0, 0, 0, 0, 0, 34, 0,242, 0, 0, 0,244, 0, 0, 0, 0, 0, 34, 0,121, 0, 0, 0,
+239, 0, 0, 0, 0, 0, 34, 0,239, 0, 0, 0,241, 0, 0, 0, 0, 0, 34, 0,122, 0, 0, 0,240, 0, 0, 0, 0, 0, 34, 0,
+240, 0, 0, 0,242, 0, 0, 0, 0, 0, 34, 0,123, 0, 0, 0,237, 0, 0, 0, 0, 0, 34, 0,237, 0, 0, 0,239, 0, 0, 0,
+ 0, 0, 34, 0,124, 0, 0, 0,238, 0, 0, 0, 0, 0, 34, 0,238, 0, 0, 0,240, 0, 0, 0, 0, 0, 34, 0,176, 0, 0, 0,
+233, 0, 0, 0, 0, 0, 34, 0,233, 0, 0, 0,237, 0, 0, 0, 0, 0, 34, 0,177, 0, 0, 0,234, 0, 0, 0, 0, 0, 34, 0,
+234, 0, 0, 0,238, 0, 0, 0, 0, 0, 34, 0,125, 0, 0, 0,235, 0, 0, 0, 0, 0, 34, 0,233, 0, 0, 0,235, 0, 0, 0,
+ 0, 0, 34, 0,126, 0, 0, 0,236, 0, 0, 0, 0, 0, 34, 0,234, 0, 0, 0,236, 0, 0, 0, 0, 0, 34, 0,235, 0, 0, 0,
+253, 0, 0, 0, 0, 0, 34, 0,236, 0, 0, 0,254, 0, 0, 0, 0, 0, 34, 0,253, 0, 0, 0,255, 0, 0, 0, 0, 0, 34, 0,
+255, 0, 0, 0, 17, 1, 0, 0, 0, 0, 34, 0,235, 0, 0, 0, 17, 1, 0, 0, 0, 0, 34, 0,254, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 34, 0,236, 0, 0, 0, 18, 1, 0, 0, 0, 0, 34, 0, 0, 1, 0, 0, 18, 1, 0, 0, 0, 0, 34, 0, 17, 1, 0, 0,
+ 19, 1, 0, 0, 0, 0, 34, 0,233, 0, 0, 0, 19, 1, 0, 0, 0, 0, 34, 0,234, 0, 0, 0, 20, 1, 0, 0, 0, 0, 34, 0,
+ 18, 1, 0, 0, 20, 1, 0, 0, 0, 0, 34, 0, 15, 1, 0, 0, 19, 1, 0, 0, 0, 0, 34, 0,237, 0, 0, 0, 15, 1, 0, 0,
+ 0, 0, 34, 0,238, 0, 0, 0, 16, 1, 0, 0, 0, 0, 34, 0, 16, 1, 0, 0, 20, 1, 0, 0, 0, 0, 34, 0, 13, 1, 0, 0,
+ 15, 1, 0, 0, 0, 0, 34, 0,239, 0, 0, 0, 13, 1, 0, 0, 0, 0, 34, 0,240, 0, 0, 0, 14, 1, 0, 0, 0, 0, 34, 0,
+ 14, 1, 0, 0, 16, 1, 0, 0, 0, 0, 34, 0, 11, 1, 0, 0, 13, 1, 0, 0, 0, 0, 34, 0,241, 0, 0, 0, 11, 1, 0, 0,
+ 0, 0, 34, 0,242, 0, 0, 0, 12, 1, 0, 0, 0, 0, 34, 0, 12, 1, 0, 0, 14, 1, 0, 0, 0, 0, 34, 0, 9, 1, 0, 0,
+ 11, 1, 0, 0, 0, 0, 34, 0,243, 0, 0, 0, 9, 1, 0, 0, 0, 0, 34, 0,244, 0, 0, 0, 10, 1, 0, 0, 0, 0, 34, 0,
+ 10, 1, 0, 0, 12, 1, 0, 0, 0, 0, 34, 0, 7, 1, 0, 0, 9, 1, 0, 0, 0, 0, 34, 0,245, 0, 0, 0, 7, 1, 0, 0,
+ 0, 0, 34, 0,246, 0, 0, 0, 8, 1, 0, 0, 0, 0, 34, 0, 8, 1, 0, 0, 10, 1, 0, 0, 0, 0, 34, 0, 5, 1, 0, 0,
+ 7, 1, 0, 0, 0, 0, 34, 0,247, 0, 0, 0, 5, 1, 0, 0, 0, 0, 34, 0,248, 0, 0, 0, 6, 1, 0, 0, 0, 0, 34, 0,
+ 6, 1, 0, 0, 8, 1, 0, 0, 0, 0, 34, 0, 3, 1, 0, 0, 5, 1, 0, 0, 0, 0, 34, 0,249, 0, 0, 0, 3, 1, 0, 0,
+ 0, 0, 34, 0,250, 0, 0, 0, 4, 1, 0, 0, 0, 0, 34, 0, 4, 1, 0, 0, 6, 1, 0, 0, 0, 0, 34, 0, 3, 1, 0, 0,
+ 21, 1, 0, 0, 0, 0, 34, 0,231, 0, 0, 0, 21, 1, 0, 0, 0, 0, 34, 0,232, 0, 0, 0, 22, 1, 0, 0, 0, 0, 34, 0,
+ 4, 1, 0, 0, 22, 1, 0, 0, 0, 0, 34, 0,251, 0, 0, 0, 1, 1, 0, 0, 0, 0, 34, 0,255, 0, 0, 0, 1, 1, 0, 0,
+ 0, 0, 34, 0,252, 0, 0, 0, 2, 1, 0, 0, 0, 0, 34, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0, 0, 34, 0,229, 0, 0, 0,
+ 23, 1, 0, 0, 0, 0, 34, 0, 1, 1, 0, 0, 23, 1, 0, 0, 0, 0, 34, 0,230, 0, 0, 0, 24, 1, 0, 0, 0, 0, 34, 0,
+ 2, 1, 0, 0, 24, 1, 0, 0, 0, 0, 34, 0, 21, 1, 0, 0, 23, 1, 0, 0, 0, 0, 34, 0, 22, 1, 0, 0, 24, 1, 0, 0,
+ 0, 0, 34, 0,106, 0, 0, 0, 25, 1, 0, 0, 0, 0, 34, 0, 71, 0, 0, 0, 25, 1, 0, 0, 0, 0, 38, 0, 65, 0, 0, 0,
+ 71, 0, 0, 0, 0, 0, 34, 0,107, 0, 0, 0, 26, 1, 0, 0, 0, 0, 34, 0, 71, 0, 0, 0, 26, 1, 0, 0, 0, 0, 38, 0,
+104, 0, 0, 0, 27, 1, 0, 0, 0, 0, 34, 0, 25, 1, 0, 0, 27, 1, 0, 0, 0, 0, 34, 0,105, 0, 0, 0, 28, 1, 0, 0,
+ 0, 0, 34, 0, 26, 1, 0, 0, 28, 1, 0, 0, 0, 0, 34, 0,102, 0, 0, 0, 29, 1, 0, 0, 0, 0, 34, 0, 27, 1, 0, 0,
+ 29, 1, 0, 0, 0, 0, 34, 0,103, 0, 0, 0, 30, 1, 0, 0, 0, 0, 34, 0, 28, 1, 0, 0, 30, 1, 0, 0, 0, 0, 34, 0,
+100, 0, 0, 0, 31, 1, 0, 0, 0, 0, 34, 0, 29, 1, 0, 0, 31, 1, 0, 0, 0, 0, 34, 0,101, 0, 0, 0, 32, 1, 0, 0,
+ 0, 0, 34, 0, 30, 1, 0, 0, 32, 1, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0, 33, 1, 0, 0, 0, 0, 34, 0, 31, 1, 0, 0,
+ 33, 1, 0, 0, 0, 0, 38, 0, 99, 0, 0, 0, 34, 1, 0, 0, 0, 0, 34, 0, 32, 1, 0, 0, 34, 1, 0, 0, 0, 0, 38, 0,
+ 96, 0, 0, 0, 35, 1, 0, 0, 0, 0, 34, 0, 33, 1, 0, 0, 35, 1, 0, 0, 0, 0, 34, 0, 97, 0, 0, 0, 36, 1, 0, 0,
+ 0, 0, 34, 0, 34, 1, 0, 0, 36, 1, 0, 0, 0, 0, 34, 0, 94, 0, 0, 0, 37, 1, 0, 0, 0, 0, 34, 0, 35, 1, 0, 0,
+ 37, 1, 0, 0, 0, 0, 34, 0, 95, 0, 0, 0, 38, 1, 0, 0, 0, 0, 34, 0, 36, 1, 0, 0, 38, 1, 0, 0, 0, 0, 34, 0,
+ 92, 0, 0, 0, 39, 1, 0, 0, 0, 0, 34, 0, 37, 1, 0, 0, 39, 1, 0, 0, 0, 0, 34, 0, 93, 0, 0, 0, 40, 1, 0, 0,
+ 0, 0, 34, 0, 38, 1, 0, 0, 40, 1, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0, 41, 1, 0, 0, 0, 0, 34, 0, 39, 1, 0, 0,
+ 41, 1, 0, 0, 0, 0, 34, 0, 91, 0, 0, 0, 42, 1, 0, 0, 0, 0, 34, 0, 40, 1, 0, 0, 42, 1, 0, 0, 0, 0, 34, 0,
+ 49, 1, 0, 0, 50, 1, 0, 0, 0, 0, 38, 0, 50, 1, 0, 0, 69, 1, 0, 0, 0, 0, 34, 0, 69, 1, 0, 0, 79, 1, 0, 0,
+ 0, 0, 34, 0, 49, 1, 0, 0, 79, 1, 0, 0, 0, 0, 34, 0, 50, 1, 0, 0, 70, 1, 0, 0, 0, 0, 34, 0, 49, 1, 0, 0,
+ 80, 1, 0, 0, 0, 0, 34, 0, 70, 1, 0, 0, 80, 1, 0, 0, 0, 0, 34, 0, 48, 1, 0, 0, 49, 1, 0, 0, 0, 0, 38, 0,
+ 77, 1, 0, 0, 79, 1, 0, 0, 0, 0, 34, 0, 48, 1, 0, 0, 77, 1, 0, 0, 0, 0, 34, 0, 48, 1, 0, 0, 78, 1, 0, 0,
+ 0, 0, 34, 0, 78, 1, 0, 0, 80, 1, 0, 0, 0, 0, 34, 0, 47, 1, 0, 0, 48, 1, 0, 0, 0, 0, 38, 0, 77, 1, 0, 0,
+ 81, 1, 0, 0, 0, 0, 34, 0, 47, 1, 0, 0, 81, 1, 0, 0, 0, 0, 34, 0, 47, 1, 0, 0, 82, 1, 0, 0, 0, 0, 34, 0,
+ 78, 1, 0, 0, 82, 1, 0, 0, 0, 0, 34, 0, 89, 0, 0, 0, 47, 1, 0, 0, 0, 0, 38, 0, 87, 0, 0, 0, 81, 1, 0, 0,
+ 0, 0, 34, 0, 88, 0, 0, 0, 82, 1, 0, 0, 0, 0, 34, 0, 75, 1, 0, 0, 81, 1, 0, 0, 0, 0, 34, 0, 85, 0, 0, 0,
+ 75, 1, 0, 0, 0, 0, 34, 0, 86, 0, 0, 0, 76, 1, 0, 0, 0, 0, 34, 0, 76, 1, 0, 0, 82, 1, 0, 0, 0, 0, 34, 0,
+ 71, 1, 0, 0, 75, 1, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0, 71, 1, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0, 72, 1, 0, 0,
+ 0, 0, 34, 0, 72, 1, 0, 0, 76, 1, 0, 0, 0, 0, 34, 0, 71, 1, 0, 0, 73, 1, 0, 0, 0, 0, 34, 0, 81, 0, 0, 0,
+ 73, 1, 0, 0, 0, 0, 34, 0, 82, 0, 0, 0, 74, 1, 0, 0, 0, 0, 34, 0, 72, 1, 0, 0, 74, 1, 0, 0, 0, 0, 34, 0,
+ 71, 1, 0, 0, 77, 1, 0, 0, 0, 0, 34, 0, 73, 1, 0, 0, 79, 1, 0, 0, 0, 0, 34, 0, 72, 1, 0, 0, 78, 1, 0, 0,
+ 0, 0, 34, 0, 74, 1, 0, 0, 80, 1, 0, 0, 0, 0, 34, 0, 67, 1, 0, 0, 73, 1, 0, 0, 0, 0, 34, 0, 67, 1, 0, 0,
+ 69, 1, 0, 0, 0, 0, 34, 0, 68, 1, 0, 0, 74, 1, 0, 0, 0, 0, 34, 0, 68, 1, 0, 0, 70, 1, 0, 0, 0, 0, 34, 0,
+ 79, 0, 0, 0, 67, 1, 0, 0, 0, 0, 34, 0, 80, 0, 0, 0, 68, 1, 0, 0, 0, 0, 34, 0,206, 0, 0, 0, 83, 1, 0, 0,
+ 0, 0, 34, 0, 83, 1, 0, 0, 85, 1, 0, 0, 0, 0, 34, 0,212, 0, 0, 0, 85, 1, 0, 0, 0, 0, 34, 0, 84, 1, 0, 0,
+ 86, 1, 0, 0, 0, 0, 34, 0,207, 0, 0, 0, 84, 1, 0, 0, 0, 0, 34, 0,213, 0, 0, 0, 86, 1, 0, 0, 0, 0, 34, 0,
+ 67, 1, 0, 0, 83, 1, 0, 0, 0, 0, 34, 0, 68, 1, 0, 0, 84, 1, 0, 0, 0, 0, 34, 0, 85, 1, 0, 0, 87, 1, 0, 0,
+ 0, 0, 34, 0, 77, 0, 0, 0, 87, 1, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0, 88, 1, 0, 0, 0, 0, 34, 0, 86, 1, 0, 0,
+ 88, 1, 0, 0, 0, 0, 34, 0, 41, 1, 0, 0, 87, 1, 0, 0, 0, 0, 34, 0, 42, 1, 0, 0, 88, 1, 0, 0, 0, 0, 34, 0,
+ 75, 0, 0, 0, 65, 1, 0, 0, 0, 0, 34, 0, 65, 1, 0, 0, 93, 1, 0, 0, 0, 0, 34, 0, 45, 1, 0, 0, 93, 1, 0, 0,
+ 0, 0, 39, 0, 75, 0, 0, 0, 45, 1, 0, 0, 0, 0, 38, 0, 66, 1, 0, 0, 94, 1, 0, 0, 0, 0, 34, 0, 75, 0, 0, 0,
+ 66, 1, 0, 0, 0, 0, 34, 0, 45, 1, 0, 0, 94, 1, 0, 0, 0, 0, 39, 0, 91, 1, 0, 0, 93, 1, 0, 0, 0, 0, 34, 0,
+ 76, 0, 0, 0, 91, 1, 0, 0, 0, 0, 34, 0, 76, 0, 0, 0, 45, 1, 0, 0, 0, 0, 38, 0, 92, 1, 0, 0, 94, 1, 0, 0,
+ 0, 0, 34, 0, 76, 0, 0, 0, 92, 1, 0, 0, 0, 0, 34, 0, 89, 1, 0, 0, 91, 1, 0, 0, 0, 0, 34, 0, 46, 1, 0, 0,
+ 89, 1, 0, 0, 0, 0, 34, 0, 76, 0, 0, 0, 46, 1, 0, 0, 0, 0, 38, 0, 90, 1, 0, 0, 92, 1, 0, 0, 0, 0, 34, 0,
+ 46, 1, 0, 0, 90, 1, 0, 0, 0, 0, 34, 0, 69, 1, 0, 0, 89, 1, 0, 0, 0, 0, 34, 0, 46, 1, 0, 0, 50, 1, 0, 0,
+ 0, 0, 38, 0, 70, 1, 0, 0, 90, 1, 0, 0, 0, 0, 34, 0, 83, 1, 0, 0, 89, 1, 0, 0, 0, 0, 34, 0, 84, 1, 0, 0,
+ 90, 1, 0, 0, 0, 0, 34, 0, 39, 1, 0, 0, 59, 1, 0, 0, 0, 0, 34, 0, 51, 1, 0, 0, 59, 1, 0, 0, 0, 0, 34, 0,
+ 37, 1, 0, 0, 51, 1, 0, 0, 0, 0, 34, 0, 40, 1, 0, 0, 60, 1, 0, 0, 0, 0, 34, 0, 38, 1, 0, 0, 52, 1, 0, 0,
+ 0, 0, 34, 0, 52, 1, 0, 0, 60, 1, 0, 0, 0, 0, 34, 0, 74, 0, 0, 0, 57, 1, 0, 0, 0, 0, 39, 0, 57, 1, 0, 0,
+ 65, 1, 0, 0, 0, 0, 34, 0, 74, 0, 0, 0, 75, 0, 0, 0, 0, 0, 38, 0, 58, 1, 0, 0, 66, 1, 0, 0, 0, 0, 34, 0,
+ 74, 0, 0, 0, 58, 1, 0, 0, 0, 0, 39, 0, 43, 1, 0, 0, 99, 1, 0, 0, 0, 0, 34, 0, 97, 1, 0, 0, 99, 1, 0, 0,
+ 0, 0, 34, 0, 44, 1, 0, 0, 97, 1, 0, 0, 0, 0, 34, 0, 43, 1, 0, 0, 44, 1, 0, 0, 0, 0, 38, 0, 98, 1, 0, 0,
+100, 1, 0, 0, 0, 0, 34, 0, 43, 1, 0, 0,100, 1, 0, 0, 0, 0, 34, 0, 44, 1, 0, 0, 98, 1, 0, 0, 0, 0, 34, 0,
+ 95, 1, 0, 0, 97, 1, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 95, 1, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 44, 1, 0, 0,
+ 0, 0, 38, 0, 96, 1, 0, 0, 98, 1, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 96, 1, 0, 0, 0, 0, 34, 0, 57, 1, 0, 0,
+ 95, 1, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 74, 0, 0, 0, 0, 0, 38, 0, 58, 1, 0, 0, 96, 1, 0, 0, 0, 0, 34, 0,
+ 35, 1, 0, 0,103, 1, 0, 0, 0, 0, 34, 0,103, 1, 0, 0,105, 1, 0, 0, 0, 0, 34, 0, 33, 1, 0, 0,105, 1, 0, 0,
+ 0, 0, 34, 0, 36, 1, 0, 0,104, 1, 0, 0, 0, 0, 34, 0, 34, 1, 0, 0,106, 1, 0, 0, 0, 0, 34, 0,104, 1, 0, 0,
+106, 1, 0, 0, 0, 0, 34, 0,103, 1, 0, 0,109, 1, 0, 0, 0, 0, 34, 0,107, 1, 0, 0,109, 1, 0, 0, 0, 0, 34, 0,
+105, 1, 0, 0,107, 1, 0, 0, 0, 0, 34, 0,104, 1, 0, 0,110, 1, 0, 0, 0, 0, 34, 0,106, 1, 0, 0,108, 1, 0, 0,
+ 0, 0, 34, 0,108, 1, 0, 0,110, 1, 0, 0, 0, 0, 34, 0,109, 1, 0, 0,111, 1, 0, 0, 0, 0, 34, 0,111, 1, 0, 0,
+113, 1, 0, 0, 0, 0, 34, 0,107, 1, 0, 0,113, 1, 0, 0, 0, 0, 34, 0,110, 1, 0, 0,112, 1, 0, 0, 0, 0, 34, 0,
+108, 1, 0, 0,114, 1, 0, 0, 0, 0, 34, 0,112, 1, 0, 0,114, 1, 0, 0, 0, 0, 34, 0,111, 1, 0, 0,117, 1, 0, 0,
+ 0, 0, 34, 0,115, 1, 0, 0,117, 1, 0, 0, 0, 0, 34, 0,113, 1, 0, 0,115, 1, 0, 0, 0, 0, 34, 0,112, 1, 0, 0,
+118, 1, 0, 0, 0, 0, 34, 0,114, 1, 0, 0,116, 1, 0, 0, 0, 0, 34, 0,116, 1, 0, 0,118, 1, 0, 0, 0, 0, 34, 0,
+ 55, 1, 0, 0,119, 1, 0, 0, 0, 0, 39, 0,115, 1, 0, 0,119, 1, 0, 0, 0, 0, 34, 0, 55, 1, 0, 0,117, 1, 0, 0,
+ 0, 0, 34, 0,116, 1, 0, 0,120, 1, 0, 0, 0, 0, 34, 0, 56, 1, 0, 0,120, 1, 0, 0, 0, 0, 39, 0, 56, 1, 0, 0,
+118, 1, 0, 0, 0, 0, 34, 0, 95, 1, 0, 0,115, 1, 0, 0, 0, 0, 34, 0, 57, 1, 0, 0,119, 1, 0, 0, 0, 0, 39, 0,
+ 96, 1, 0, 0,116, 1, 0, 0, 0, 0, 34, 0, 58, 1, 0, 0,120, 1, 0, 0, 0, 0, 39, 0, 97, 1, 0, 0,113, 1, 0, 0,
+ 0, 0, 34, 0, 98, 1, 0, 0,114, 1, 0, 0, 0, 0, 34, 0, 99, 1, 0, 0,107, 1, 0, 0, 0, 0, 34, 0,100, 1, 0, 0,
+108, 1, 0, 0, 0, 0, 34, 0, 99, 1, 0, 0,101, 1, 0, 0, 0, 0, 34, 0,101, 1, 0, 0,105, 1, 0, 0, 0, 0, 34, 0,
+102, 1, 0, 0,106, 1, 0, 0, 0, 0, 34, 0,100, 1, 0, 0,102, 1, 0, 0, 0, 0, 34, 0, 31, 1, 0, 0,101, 1, 0, 0,
+ 0, 0, 34, 0, 32, 1, 0, 0,102, 1, 0, 0, 0, 0, 34, 0, 72, 0, 0, 0,101, 1, 0, 0, 0, 0, 34, 0, 72, 0, 0, 0,
+ 43, 1, 0, 0, 0, 0, 38, 0, 72, 0, 0, 0,102, 1, 0, 0, 0, 0, 34, 0, 25, 1, 0, 0, 31, 1, 0, 0, 0, 0, 38, 0,
+ 26, 1, 0, 0, 32, 1, 0, 0, 0, 0, 38, 0, 72, 0, 0, 0, 25, 1, 0, 0, 0, 0, 34, 0, 72, 0, 0, 0, 26, 1, 0, 0,
+ 0, 0, 34, 0, 71, 0, 0, 0, 72, 0, 0, 0, 0, 0, 38, 0, 51, 1, 0, 0,103, 1, 0, 0, 0, 0, 34, 0, 52, 1, 0, 0,
+104, 1, 0, 0, 0, 0, 34, 0, 51, 1, 0, 0, 53, 1, 0, 0, 0, 0, 34, 0, 53, 1, 0, 0,109, 1, 0, 0, 0, 0, 34, 0,
+ 54, 1, 0, 0,110, 1, 0, 0, 0, 0, 34, 0, 52, 1, 0, 0, 54, 1, 0, 0, 0, 0, 34, 0, 53, 1, 0, 0,123, 1, 0, 0,
+ 0, 0, 34, 0,111, 1, 0, 0,123, 1, 0, 0, 0, 0, 34, 0,112, 1, 0, 0,124, 1, 0, 0, 0, 0, 34, 0, 54, 1, 0, 0,
+124, 1, 0, 0, 0, 0, 34, 0, 55, 1, 0, 0,123, 1, 0, 0, 0, 0, 34, 0, 56, 1, 0, 0,124, 1, 0, 0, 0, 0, 34, 0,
+ 91, 1, 0, 0,127, 1, 0, 0, 0, 0, 34, 0,125, 1, 0, 0,127, 1, 0, 0, 0, 0, 34, 0, 89, 1, 0, 0,125, 1, 0, 0,
+ 0, 0, 34, 0, 92, 1, 0, 0,128, 1, 0, 0, 0, 0, 34, 0, 90, 1, 0, 0,126, 1, 0, 0, 0, 0, 34, 0,126, 1, 0, 0,
+128, 1, 0, 0, 0, 0, 34, 0, 59, 1, 0, 0,125, 1, 0, 0, 0, 0, 34, 0, 61, 1, 0, 0,127, 1, 0, 0, 0, 0, 34, 0,
+ 59, 1, 0, 0, 61, 1, 0, 0, 0, 0, 34, 0, 60, 1, 0, 0,126, 1, 0, 0, 0, 0, 34, 0, 60, 1, 0, 0, 62, 1, 0, 0,
+ 0, 0, 34, 0, 62, 1, 0, 0,128, 1, 0, 0, 0, 0, 34, 0, 41, 1, 0, 0,125, 1, 0, 0, 0, 0, 34, 0, 42, 1, 0, 0,
+126, 1, 0, 0, 0, 0, 34, 0, 41, 1, 0, 0, 85, 1, 0, 0, 0, 0, 34, 0, 83, 1, 0, 0,125, 1, 0, 0, 0, 0, 34, 0,
+ 42, 1, 0, 0, 86, 1, 0, 0, 0, 0, 34, 0, 84, 1, 0, 0,126, 1, 0, 0, 0, 0, 34, 0, 55, 1, 0, 0, 63, 1, 0, 0,
+ 0, 0, 34, 0, 63, 1, 0, 0,121, 1, 0, 0, 0, 0, 39, 0,119, 1, 0, 0,121, 1, 0, 0, 0, 0, 34, 0, 64, 1, 0, 0,
+122, 1, 0, 0, 0, 0, 39, 0, 56, 1, 0, 0, 64, 1, 0, 0, 0, 0, 34, 0,120, 1, 0, 0,122, 1, 0, 0, 0, 0, 34, 0,
+ 65, 1, 0, 0,121, 1, 0, 0, 0, 0, 34, 0, 66, 1, 0, 0,122, 1, 0, 0, 0, 0, 34, 0,121, 1, 0, 0,127, 1, 0, 0,
+ 0, 0, 34, 0, 61, 1, 0, 0, 63, 1, 0, 0, 0, 0, 34, 0,122, 1, 0, 0,128, 1, 0, 0, 0, 0, 34, 0, 62, 1, 0, 0,
+ 64, 1, 0, 0, 0, 0, 34, 0, 93, 1, 0, 0,121, 1, 0, 0, 0, 0, 39, 0, 94, 1, 0, 0,122, 1, 0, 0, 0, 0, 39, 0,
+129, 1, 0, 0,141, 1, 0, 0, 0, 0, 34, 0,129, 1, 0, 0,155, 1, 0, 0, 0, 0, 34, 0,143, 1, 0, 0,155, 1, 0, 0,
+ 0, 0, 34, 0,141, 1, 0, 0,143, 1, 0, 0, 0, 0, 34, 0,130, 1, 0, 0,156, 1, 0, 0, 0, 0, 34, 0,130, 1, 0, 0,
+142, 1, 0, 0, 0, 0, 34, 0,142, 1, 0, 0,144, 1, 0, 0, 0, 0, 34, 0,144, 1, 0, 0,156, 1, 0, 0, 0, 0, 34, 0,
+143, 1, 0, 0,145, 1, 0, 0, 0, 0, 34, 0,139, 1, 0, 0,145, 1, 0, 0, 0, 0, 34, 0,139, 1, 0, 0,141, 1, 0, 0,
+ 0, 0, 34, 0,144, 1, 0, 0,146, 1, 0, 0, 0, 0, 34, 0,140, 1, 0, 0,142, 1, 0, 0, 0, 0, 34, 0,140, 1, 0, 0,
+146, 1, 0, 0, 0, 0, 34, 0,145, 1, 0, 0,147, 1, 0, 0, 0, 0, 34, 0,137, 1, 0, 0,147, 1, 0, 0, 0, 0, 34, 0,
+137, 1, 0, 0,139, 1, 0, 0, 0, 0, 34, 0,146, 1, 0, 0,148, 1, 0, 0, 0, 0, 34, 0,138, 1, 0, 0,140, 1, 0, 0,
+ 0, 0, 34, 0,138, 1, 0, 0,148, 1, 0, 0, 0, 0, 34, 0,147, 1, 0, 0,149, 1, 0, 0, 0, 0, 34, 0,135, 1, 0, 0,
+149, 1, 0, 0, 0, 0, 34, 0,135, 1, 0, 0,137, 1, 0, 0, 0, 0, 34, 0,148, 1, 0, 0,150, 1, 0, 0, 0, 0, 34, 0,
+136, 1, 0, 0,138, 1, 0, 0, 0, 0, 34, 0,136, 1, 0, 0,150, 1, 0, 0, 0, 0, 34, 0,149, 1, 0, 0,151, 1, 0, 0,
+ 0, 0, 34, 0,133, 1, 0, 0,151, 1, 0, 0, 0, 0, 34, 0,133, 1, 0, 0,135, 1, 0, 0, 0, 0, 34, 0,150, 1, 0, 0,
+152, 1, 0, 0, 0, 0, 34, 0,134, 1, 0, 0,136, 1, 0, 0, 0, 0, 34, 0,134, 1, 0, 0,152, 1, 0, 0, 0, 0, 34, 0,
+151, 1, 0, 0,153, 1, 0, 0, 0, 0, 34, 0,131, 1, 0, 0,153, 1, 0, 0, 0, 0, 34, 0,131, 1, 0, 0,133, 1, 0, 0,
+ 0, 0, 34, 0,152, 1, 0, 0,154, 1, 0, 0, 0, 0, 34, 0,132, 1, 0, 0,134, 1, 0, 0, 0, 0, 34, 0,132, 1, 0, 0,
+154, 1, 0, 0, 0, 0, 34, 0,151, 1, 0, 0,161, 1, 0, 0, 0, 0, 34, 0,159, 1, 0, 0,161, 1, 0, 0, 0, 0, 34, 0,
+153, 1, 0, 0,159, 1, 0, 0, 0, 0, 34, 0,160, 1, 0, 0,162, 1, 0, 0, 0, 0, 34, 0,152, 1, 0, 0,162, 1, 0, 0,
+ 0, 0, 34, 0,154, 1, 0, 0,160, 1, 0, 0, 0, 0, 34, 0,149, 1, 0, 0,163, 1, 0, 0, 0, 0, 34, 0,161, 1, 0, 0,
+163, 1, 0, 0, 0, 0, 34, 0,162, 1, 0, 0,164, 1, 0, 0, 0, 0, 34, 0,150, 1, 0, 0,164, 1, 0, 0, 0, 0, 34, 0,
+147, 1, 0, 0,165, 1, 0, 0, 0, 0, 34, 0,163, 1, 0, 0,165, 1, 0, 0, 0, 0, 34, 0,164, 1, 0, 0,166, 1, 0, 0,
+ 0, 0, 34, 0,148, 1, 0, 0,166, 1, 0, 0, 0, 0, 34, 0,145, 1, 0, 0,167, 1, 0, 0, 0, 0, 34, 0,165, 1, 0, 0,
+167, 1, 0, 0, 0, 0, 34, 0,166, 1, 0, 0,168, 1, 0, 0, 0, 0, 34, 0,146, 1, 0, 0,168, 1, 0, 0, 0, 0, 34, 0,
+143, 1, 0, 0,169, 1, 0, 0, 0, 0, 34, 0,167, 1, 0, 0,169, 1, 0, 0, 0, 0, 34, 0,168, 1, 0, 0,170, 1, 0, 0,
+ 0, 0, 34, 0,144, 1, 0, 0,170, 1, 0, 0, 0, 0, 34, 0,155, 1, 0, 0,157, 1, 0, 0, 0, 0, 34, 0,157, 1, 0, 0,
+169, 1, 0, 0, 0, 0, 34, 0,156, 1, 0, 0,158, 1, 0, 0, 0, 0, 34, 0,158, 1, 0, 0,170, 1, 0, 0, 0, 0, 34, 0,
+ 61, 1, 0, 0,185, 1, 0, 0, 0, 0, 34, 0,183, 1, 0, 0,185, 1, 0, 0, 0, 0, 34, 0, 59, 1, 0, 0,183, 1, 0, 0,
+ 0, 0, 34, 0, 62, 1, 0, 0,186, 1, 0, 0, 0, 0, 34, 0, 60, 1, 0, 0,184, 1, 0, 0, 0, 0, 34, 0,184, 1, 0, 0,
+186, 1, 0, 0, 0, 0, 34, 0, 61, 1, 0, 0,131, 1, 0, 0, 0, 0, 34, 0,153, 1, 0, 0,185, 1, 0, 0, 0, 0, 34, 0,
+ 62, 1, 0, 0,132, 1, 0, 0, 0, 0, 34, 0,154, 1, 0, 0,186, 1, 0, 0, 0, 0, 34, 0, 53, 1, 0, 0,183, 1, 0, 0,
+ 0, 0, 34, 0, 54, 1, 0, 0,184, 1, 0, 0, 0, 0, 34, 0,123, 1, 0, 0,171, 1, 0, 0, 0, 0, 34, 0,155, 1, 0, 0,
+171, 1, 0, 0, 0, 0, 34, 0,123, 1, 0, 0,129, 1, 0, 0, 0, 0, 34, 0,156, 1, 0, 0,172, 1, 0, 0, 0, 0, 34, 0,
+124, 1, 0, 0,172, 1, 0, 0, 0, 0, 34, 0,124, 1, 0, 0,130, 1, 0, 0, 0, 0, 34, 0,159, 1, 0, 0,181, 1, 0, 0,
+ 0, 0, 34, 0,181, 1, 0, 0,185, 1, 0, 0, 0, 0, 34, 0,160, 1, 0, 0,182, 1, 0, 0, 0, 0, 34, 0,182, 1, 0, 0,
+186, 1, 0, 0, 0, 0, 34, 0,179, 1, 0, 0,187, 1, 0, 0, 0, 0, 34, 0,185, 1, 0, 0,187, 1, 0, 0, 0, 0, 34, 0,
+179, 1, 0, 0,181, 1, 0, 0, 0, 0, 34, 0,186, 1, 0, 0,188, 1, 0, 0, 0, 0, 34, 0,180, 1, 0, 0,188, 1, 0, 0,
+ 0, 0, 34, 0,180, 1, 0, 0,182, 1, 0, 0, 0, 0, 34, 0,175, 1, 0, 0,187, 1, 0, 0, 0, 0, 34, 0,177, 1, 0, 0,
+179, 1, 0, 0, 0, 0, 34, 0,175, 1, 0, 0,177, 1, 0, 0, 0, 0, 34, 0,176, 1, 0, 0,188, 1, 0, 0, 0, 0, 34, 0,
+176, 1, 0, 0,178, 1, 0, 0, 0, 0, 34, 0,178, 1, 0, 0,180, 1, 0, 0, 0, 0, 34, 0,173, 1, 0, 0,189, 1, 0, 0,
+ 0, 0, 34, 0,187, 1, 0, 0,189, 1, 0, 0, 0, 0, 34, 0,173, 1, 0, 0,175, 1, 0, 0, 0, 0, 34, 0,188, 1, 0, 0,
+190, 1, 0, 0, 0, 0, 34, 0,174, 1, 0, 0,190, 1, 0, 0, 0, 0, 34, 0,174, 1, 0, 0,176, 1, 0, 0, 0, 0, 34, 0,
+171, 1, 0, 0,189, 1, 0, 0, 0, 0, 34, 0,173, 1, 0, 0,191, 1, 0, 0, 0, 0, 34, 0,171, 1, 0, 0,191, 1, 0, 0,
+ 0, 0, 32, 0,172, 1, 0, 0,190, 1, 0, 0, 0, 0, 34, 0,172, 1, 0, 0,192, 1, 0, 0, 0, 0, 32, 0,174, 1, 0, 0,
+192, 1, 0, 0, 0, 0, 34, 0,157, 1, 0, 0,191, 1, 0, 0, 0, 0, 34, 0,158, 1, 0, 0,192, 1, 0, 0, 0, 0, 34, 0,
+ 53, 1, 0, 0,189, 1, 0, 0, 0, 0, 34, 0, 54, 1, 0, 0,190, 1, 0, 0, 0, 0, 34, 0,183, 1, 0, 0,187, 1, 0, 0,
+ 0, 0, 34, 0,184, 1, 0, 0,188, 1, 0, 0, 0, 0, 34, 0,191, 1, 0, 0,193, 1, 0, 0, 0, 0, 34, 0,193, 1, 0, 0,
+217, 1, 0, 0, 0, 0, 34, 0,157, 1, 0, 0,217, 1, 0, 0, 0, 0, 34, 0,192, 1, 0, 0,194, 1, 0, 0, 0, 0, 34, 0,
+158, 1, 0, 0,218, 1, 0, 0, 0, 0, 34, 0,194, 1, 0, 0,218, 1, 0, 0, 0, 0, 34, 0,173, 1, 0, 0,203, 1, 0, 0,
+ 0, 0, 34, 0,193, 1, 0, 0,203, 1, 0, 0, 0, 0, 34, 0,174, 1, 0, 0,204, 1, 0, 0, 0, 0, 34, 0,194, 1, 0, 0,
+204, 1, 0, 0, 0, 0, 34, 0,175, 1, 0, 0,201, 1, 0, 0, 0, 0, 34, 0,201, 1, 0, 0,203, 1, 0, 0, 0, 0, 34, 0,
+176, 1, 0, 0,202, 1, 0, 0, 0, 0, 34, 0,202, 1, 0, 0,204, 1, 0, 0, 0, 0, 34, 0,177, 1, 0, 0,199, 1, 0, 0,
+ 0, 0, 34, 0,199, 1, 0, 0,201, 1, 0, 0, 0, 0, 34, 0,178, 1, 0, 0,200, 1, 0, 0, 0, 0, 34, 0,200, 1, 0, 0,
+202, 1, 0, 0, 0, 0, 34, 0,179, 1, 0, 0,197, 1, 0, 0, 0, 0, 34, 0,197, 1, 0, 0,199, 1, 0, 0, 0, 0, 34, 0,
+180, 1, 0, 0,198, 1, 0, 0, 0, 0, 34, 0,198, 1, 0, 0,200, 1, 0, 0, 0, 0, 34, 0,181, 1, 0, 0,195, 1, 0, 0,
+ 0, 0, 34, 0,195, 1, 0, 0,197, 1, 0, 0, 0, 0, 34, 0,182, 1, 0, 0,196, 1, 0, 0, 0, 0, 34, 0,196, 1, 0, 0,
+198, 1, 0, 0, 0, 0, 34, 0,159, 1, 0, 0,215, 1, 0, 0, 0, 0, 34, 0,195, 1, 0, 0,215, 1, 0, 0, 0, 0, 34, 0,
+160, 1, 0, 0,216, 1, 0, 0, 0, 0, 34, 0,196, 1, 0, 0,216, 1, 0, 0, 0, 0, 34, 0,205, 1, 0, 0,217, 1, 0, 0,
+ 0, 0, 34, 0,169, 1, 0, 0,205, 1, 0, 0, 0, 0, 34, 0,170, 1, 0, 0,206, 1, 0, 0, 0, 0, 34, 0,206, 1, 0, 0,
+218, 1, 0, 0, 0, 0, 34, 0,205, 1, 0, 0,207, 1, 0, 0, 0, 0, 34, 0,167, 1, 0, 0,207, 1, 0, 0, 0, 0, 34, 0,
+168, 1, 0, 0,208, 1, 0, 0, 0, 0, 34, 0,206, 1, 0, 0,208, 1, 0, 0, 0, 0, 34, 0,207, 1, 0, 0,209, 1, 0, 0,
+ 0, 0, 34, 0,165, 1, 0, 0,209, 1, 0, 0, 0, 0, 34, 0,166, 1, 0, 0,210, 1, 0, 0, 0, 0, 34, 0,208, 1, 0, 0,
+210, 1, 0, 0, 0, 0, 34, 0,209, 1, 0, 0,211, 1, 0, 0, 0, 0, 34, 0,163, 1, 0, 0,211, 1, 0, 0, 0, 0, 34, 0,
+164, 1, 0, 0,212, 1, 0, 0, 0, 0, 34, 0,210, 1, 0, 0,212, 1, 0, 0, 0, 0, 34, 0,211, 1, 0, 0,213, 1, 0, 0,
+ 0, 0, 34, 0,161, 1, 0, 0,213, 1, 0, 0, 0, 0, 34, 0,162, 1, 0, 0,214, 1, 0, 0, 0, 0, 34, 0,212, 1, 0, 0,
+214, 1, 0, 0, 0, 0, 34, 0,213, 1, 0, 0,215, 1, 0, 0, 0, 0, 34, 0,214, 1, 0, 0,216, 1, 0, 0, 0, 0, 34, 0,
+197, 1, 0, 0,221, 1, 0, 0, 0, 0, 34, 0,219, 1, 0, 0,221, 1, 0, 0, 0, 0, 34, 0,199, 1, 0, 0,219, 1, 0, 0,
+ 0, 0, 34, 0,198, 1, 0, 0,222, 1, 0, 0, 0, 0, 34, 0,200, 1, 0, 0,220, 1, 0, 0, 0, 0, 34, 0,220, 1, 0, 0,
+222, 1, 0, 0, 0, 0, 34, 0,221, 1, 0, 0,223, 1, 0, 0, 0, 0, 34, 0,223, 1, 0, 0,225, 1, 0, 0, 0, 0, 32, 0,
+219, 1, 0, 0,225, 1, 0, 0, 0, 0, 34, 0,222, 1, 0, 0,224, 1, 0, 0, 0, 0, 34, 0,220, 1, 0, 0,226, 1, 0, 0,
+ 0, 0, 34, 0,224, 1, 0, 0,226, 1, 0, 0, 0, 0, 32, 0,223, 1, 0, 0,229, 1, 0, 0, 0, 0, 34, 0,227, 1, 0, 0,
+229, 1, 0, 0, 0, 0, 34, 0,225, 1, 0, 0,227, 1, 0, 0, 0, 0, 34, 0,224, 1, 0, 0,230, 1, 0, 0, 0, 0, 34, 0,
+226, 1, 0, 0,228, 1, 0, 0, 0, 0, 34, 0,228, 1, 0, 0,230, 1, 0, 0, 0, 0, 34, 0,229, 1, 0, 0,231, 1, 0, 0,
+ 0, 0, 34, 0,231, 1, 0, 0,233, 1, 0, 0, 0, 0, 34, 0,227, 1, 0, 0,233, 1, 0, 0, 0, 0, 34, 0,230, 1, 0, 0,
+232, 1, 0, 0, 0, 0, 34, 0,228, 1, 0, 0,234, 1, 0, 0, 0, 0, 34, 0,232, 1, 0, 0,234, 1, 0, 0, 0, 0, 34, 0,
+217, 1, 0, 0,227, 1, 0, 0, 0, 0, 34, 0,205, 1, 0, 0,233, 1, 0, 0, 0, 0, 34, 0,218, 1, 0, 0,228, 1, 0, 0,
+ 0, 0, 34, 0,206, 1, 0, 0,234, 1, 0, 0, 0, 0, 34, 0,193, 1, 0, 0,225, 1, 0, 0, 0, 0, 34, 0,194, 1, 0, 0,
+226, 1, 0, 0, 0, 0, 34, 0,203, 1, 0, 0,219, 1, 0, 0, 0, 0, 34, 0,204, 1, 0, 0,220, 1, 0, 0, 0, 0, 34, 0,
+215, 1, 0, 0,221, 1, 0, 0, 0, 0, 34, 0,216, 1, 0, 0,222, 1, 0, 0, 0, 0, 34, 0,213, 1, 0, 0,223, 1, 0, 0,
+ 0, 0, 34, 0,214, 1, 0, 0,224, 1, 0, 0, 0, 0, 34, 0,211, 1, 0, 0,229, 1, 0, 0, 0, 0, 34, 0,212, 1, 0, 0,
+230, 1, 0, 0, 0, 0, 34, 0,209, 1, 0, 0,231, 1, 0, 0, 0, 0, 34, 0,210, 1, 0, 0,232, 1, 0, 0, 0, 0, 34, 0,
+207, 1, 0, 0,233, 1, 0, 0, 0, 0, 34, 0,208, 1, 0, 0,234, 1, 0, 0, 0, 0, 34, 0,131, 1, 0, 0,245, 1, 0, 0,
+ 0, 0, 34, 0,243, 1, 0, 0,245, 1, 0, 0, 0, 0, 39, 0,133, 1, 0, 0,243, 1, 0, 0, 0, 0, 34, 0,132, 1, 0, 0,
+246, 1, 0, 0, 0, 0, 34, 0,134, 1, 0, 0,244, 1, 0, 0, 0, 0, 34, 0,244, 1, 0, 0,246, 1, 0, 0, 0, 0, 39, 0,
+241, 1, 0, 0,243, 1, 0, 0, 0, 0, 39, 0,135, 1, 0, 0,241, 1, 0, 0, 0, 0, 34, 0,136, 1, 0, 0,242, 1, 0, 0,
+ 0, 0, 34, 0,242, 1, 0, 0,244, 1, 0, 0, 0, 0, 39, 0,239, 1, 0, 0,241, 1, 0, 0, 0, 0, 39, 0,137, 1, 0, 0,
+239, 1, 0, 0, 0, 0, 34, 0,138, 1, 0, 0,240, 1, 0, 0, 0, 0, 34, 0,240, 1, 0, 0,242, 1, 0, 0, 0, 0, 39, 0,
+237, 1, 0, 0,239, 1, 0, 0, 0, 0, 39, 0,139, 1, 0, 0,237, 1, 0, 0, 0, 0, 34, 0,140, 1, 0, 0,238, 1, 0, 0,
+ 0, 0, 34, 0,238, 1, 0, 0,240, 1, 0, 0, 0, 0, 39, 0,235, 1, 0, 0,237, 1, 0, 0, 0, 0, 39, 0,141, 1, 0, 0,
+235, 1, 0, 0, 0, 0, 34, 0,142, 1, 0, 0,236, 1, 0, 0, 0, 0, 34, 0,236, 1, 0, 0,238, 1, 0, 0, 0, 0, 39, 0,
+235, 1, 0, 0,247, 1, 0, 0, 0, 0, 39, 0,129, 1, 0, 0,247, 1, 0, 0, 0, 0, 34, 0,130, 1, 0, 0,248, 1, 0, 0,
+ 0, 0, 34, 0,236, 1, 0, 0,248, 1, 0, 0, 0, 0, 39, 0,235, 1, 0, 0,243, 1, 0, 0, 0, 0, 34, 0,245, 1, 0, 0,
+247, 1, 0, 0, 0, 0, 34, 0,236, 1, 0, 0,244, 1, 0, 0, 0, 0, 34, 0,246, 1, 0, 0,248, 1, 0, 0, 0, 0, 34, 0,
+237, 1, 0, 0,241, 1, 0, 0, 0, 0, 34, 0,238, 1, 0, 0,242, 1, 0, 0, 0, 0, 34, 0, 55, 1, 0, 0,247, 1, 0, 0,
+ 0, 0, 39, 0, 56, 1, 0, 0,248, 1, 0, 0, 0, 0, 39, 0, 63, 1, 0, 0,245, 1, 0, 0, 0, 0, 39, 0, 64, 1, 0, 0,
+246, 1, 0, 0, 0, 0, 39, 0, 14, 0, 0, 0,249, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0,178, 0, 0, 0, 0, 0, 34, 0,
+ 14, 0, 0, 0,113, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0,161, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0,112, 0, 0, 0,
+ 0, 0, 34, 0, 16, 0, 0, 0,112, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0,112, 0, 0, 0, 0, 0, 34, 0, 13, 0, 0, 0,
+112, 0, 0, 0, 0, 0, 34, 0, 68, 65, 84, 65, 44, 1, 0, 0,160,120,152, 2, 21, 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, 16, 63, 8, 3, 5, 0, 0, 0, 20, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,176,154, 2, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 96, 53,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 16, 39, 0, 0, 16, 63, 8, 3, 53, 0, 0, 0,244, 1, 0, 0, 45, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 0, 1, 43, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 3, 0, 0, 0,
+ 44, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1,
+ 7, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 1, 9, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 10, 0, 0, 0,
+ 12, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1,112, 0, 0, 0, 13, 0, 0, 0, 11, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 1, 8, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 1, 16, 0, 0, 0,112, 0, 0, 0,
+ 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, 0, 19, 0, 0, 0, 17, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 1,
+ 18, 0, 0, 0, 20, 0, 0, 0,112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1, 12, 0, 0, 0, 21, 0, 0, 0, 19, 0, 0, 0,
+ 14, 0, 0, 0, 0, 0, 0, 1, 20, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 1, 21, 0, 0, 0,
+ 23, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 1, 26, 0, 0, 0, 24, 0, 0, 0, 22, 0, 0, 0, 20, 0, 0, 0,
+ 0, 0, 0, 1, 19, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 28, 0, 0, 0, 26, 0, 0, 0,
+ 20, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 1, 25, 0, 0, 0, 31, 0, 0, 0, 29, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 1,
+ 30, 0, 0, 0, 32, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 1, 23, 0, 0, 0, 33, 0, 0, 0, 31, 0, 0, 0,
+ 25, 0, 0, 0, 0, 0, 0, 1, 32, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 1, 33, 0, 0, 0,
+ 35, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 1, 38, 0, 0, 0, 36, 0, 0, 0, 34, 0, 0, 0, 32, 0, 0, 0,
+ 0, 0, 0, 1, 31, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 1, 40, 0, 0, 0, 38, 0, 0, 0,
+ 32, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 1, 37, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 1,
+ 42, 0, 0, 0, 44, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 1, 35, 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0,
+ 37, 0, 0, 0, 0, 0, 0, 1, 44, 0, 0, 0, 46, 0, 0, 0, 36, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 45, 0, 0, 0,
+ 35, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 1, 50, 0, 0, 0, 36, 0, 0, 0, 46, 0, 0, 0, 48, 0, 0, 0,
+ 0, 0, 0, 1, 35, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 1, 52, 0, 0, 0, 34, 0, 0, 0,
+ 36, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 1, 33, 0, 0, 0, 23, 0, 0, 0, 53, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 1,
+ 54, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 1, 23, 0, 0, 0, 21, 0, 0, 0, 55, 0, 0, 0,
+ 53, 0, 0, 0, 0, 0, 0, 1, 56, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 1, 21, 0, 0, 0,
+ 12, 0, 0, 0, 57, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 1, 58, 0, 0, 0, 13, 0, 0, 0, 22, 0, 0, 0, 56, 0, 0, 0,
+ 0, 0, 0, 1, 12, 0, 0, 0, 10, 0, 0, 0, 61, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 1, 62, 0, 0, 0, 11, 0, 0, 0,
+ 13, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 1,
+ 64, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0,
+ 63, 0, 0, 0, 0, 0, 0, 1, 48, 0, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0,
+ 63, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 48, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 61, 0, 0, 0, 63, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 64, 0, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 62, 0, 0, 0, 58, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0, 55, 0, 0, 0, 57, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 58, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0,
+ 53, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 56, 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 59, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 0, 0, 0, 52, 0, 0, 0,
+ 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 52, 0, 0, 0, 50, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 59, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 50, 0, 0, 0, 48, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 87, 0, 0, 0,
+171, 0, 0, 0,173, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 1,173, 0, 0, 0,172, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0,
+ 0, 0, 0, 1, 85, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 1,172, 0, 0, 0,170, 0, 0, 0,
+ 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 1, 83, 0, 0, 0,167, 0, 0, 0,169, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 1,
+170, 0, 0, 0,168, 0, 0, 0, 84, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0,165, 0, 0, 0,167, 0, 0, 0,
+ 83, 0, 0, 0, 0, 0, 0, 1,168, 0, 0, 0,166, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 1, 79, 0, 0, 0,
+163, 0, 0, 0,165, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 1,166, 0, 0, 0,164, 0, 0, 0, 80, 0, 0, 0, 82, 0, 0, 0,
+ 0, 0, 0, 1, 77, 0, 0, 0, 90, 0, 0, 0,143, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 1,144, 0, 0, 0, 91, 0, 0, 0,
+ 78, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 1, 90, 0, 0, 0, 92, 0, 0, 0,145, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 1,
+146, 0, 0, 0, 93, 0, 0, 0, 91, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 1, 92, 0, 0, 0, 94, 0, 0, 0,147, 0, 0, 0,
+145, 0, 0, 0, 0, 0, 0, 1,148, 0, 0, 0, 95, 0, 0, 0, 93, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 1, 94, 0, 0, 0,
+ 96, 0, 0, 0,149, 0, 0, 0,147, 0, 0, 0, 0, 0, 0, 1,150, 0, 0, 0, 97, 0, 0, 0, 95, 0, 0, 0,148, 0, 0, 0,
+ 0, 0, 0, 1, 96, 0, 0, 0, 98, 0, 0, 0,151, 0, 0, 0,149, 0, 0, 0, 0, 0, 0, 1,152, 0, 0, 0, 99, 0, 0, 0,
+ 97, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 1, 98, 0, 0, 0,100, 0, 0, 0,153, 0, 0, 0,151, 0, 0, 0, 0, 0, 0, 1,
+154, 0, 0, 0,101, 0, 0, 0, 99, 0, 0, 0,152, 0, 0, 0, 0, 0, 0, 1,100, 0, 0, 0,102, 0, 0, 0,155, 0, 0, 0,
+153, 0, 0, 0, 0, 0, 0, 1,156, 0, 0, 0,103, 0, 0, 0,101, 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 1,102, 0, 0, 0,
+104, 0, 0, 0,157, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 1,158, 0, 0, 0,105, 0, 0, 0,103, 0, 0, 0,156, 0, 0, 0,
+ 0, 0, 0, 1,104, 0, 0, 0,106, 0, 0, 0,159, 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 1,160, 0, 0, 0,107, 0, 0, 0,
+105, 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 1,106, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 1,
+ 66, 0, 0, 0, 65, 0, 0, 0,107, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 1,108, 0, 0, 0,125, 0, 0, 0,157, 0, 0, 0,
+159, 0, 0, 0, 0, 0, 0, 1,158, 0, 0, 0,126, 0, 0, 0,109, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 1,125, 0, 0, 0,
+176, 0, 0, 0,155, 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 1,156, 0, 0, 0,177, 0, 0, 0,126, 0, 0, 0,158, 0, 0, 0,
+ 0, 0, 0, 1,123, 0, 0, 0,153, 0, 0, 0,155, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 1,156, 0, 0, 0,154, 0, 0, 0,
+124, 0, 0, 0,177, 0, 0, 0, 0, 0, 0, 1,121, 0, 0, 0,151, 0, 0, 0,153, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 1,
+154, 0, 0, 0,152, 0, 0, 0,122, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 1,119, 0, 0, 0,149, 0, 0, 0,151, 0, 0, 0,
+121, 0, 0, 0, 0, 0, 0, 1,152, 0, 0, 0,150, 0, 0, 0,120, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 1,117, 0, 0, 0,
+147, 0, 0, 0,149, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 1,150, 0, 0, 0,148, 0, 0, 0,118, 0, 0, 0,120, 0, 0, 0,
+ 0, 0, 0, 1,115, 0, 0, 0,145, 0, 0, 0,147, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 1,148, 0, 0, 0,146, 0, 0, 0,
+116, 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 1,113, 0, 0, 0,143, 0, 0, 0,145, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 1,
+146, 0, 0, 0,144, 0, 0, 0,114, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, 0,161, 0, 0, 0,143, 0, 0, 0,
+113, 0, 0, 0, 0, 0, 0, 1,144, 0, 0, 0,162, 0, 0, 0,112, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, 0,
+178, 0, 0, 0,174, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 1,174, 0, 0, 0,179, 0, 0, 0,112, 0, 0, 0,162, 0, 0, 0,
+ 0, 0, 0, 1,108, 0, 0, 0,159, 0, 0, 0, 66, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 1, 66, 0, 0, 0,160, 0, 0, 0,
+109, 0, 0, 0,111, 0, 0, 0, 0, 0, 0, 1,110, 0, 0, 0, 66, 0, 0, 0,175, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 1,
+175, 0, 0, 0, 66, 0, 0, 0,111, 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 1,174, 0, 0, 0,178, 0, 0, 0,180, 0, 0, 0,
+175, 0, 0, 0, 0, 0, 0, 1,181, 0, 0, 0,179, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 1,132, 0, 0, 0,
+134, 0, 0, 0,173, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 1,173, 0, 0, 0,134, 0, 0, 0,133, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 0, 1,130, 0, 0, 0,132, 0, 0, 0,171, 0, 0, 0,169, 0, 0, 0, 0, 0, 0, 1,172, 0, 0, 0,133, 0, 0, 0,
+131, 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 1,128, 0, 0, 0,130, 0, 0, 0,169, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 1,
+170, 0, 0, 0,131, 0, 0, 0,129, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 1,163, 0, 0, 0,184, 0, 0, 0,182, 0, 0, 0,
+165, 0, 0, 0, 0, 0, 0, 1,183, 0, 0, 0,185, 0, 0, 0,164, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 1,128, 0, 0, 0,
+167, 0, 0, 0,165, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 1,166, 0, 0, 0,168, 0, 0, 0,129, 0, 0, 0,183, 0, 0, 0,
+ 0, 0, 0, 1,141, 0, 0, 0,187, 0, 0, 0,186, 0, 0, 0,184, 0, 0, 0, 0, 0, 0, 1,186, 0, 0, 0,187, 0, 0, 0,
+142, 0, 0, 0,185, 0, 0, 0, 0, 0, 0, 1,182, 0, 0, 0,184, 0, 0, 0,186, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 1,
+186, 0, 0, 0,185, 0, 0, 0,183, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 1,127, 0, 0, 0,128, 0, 0, 0,182, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 1,183, 0, 0, 0,129, 0, 0, 0,127, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 1,139, 0, 0, 0,
+190, 0, 0, 0,188, 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 1,189, 0, 0, 0,191, 0, 0, 0,140, 0, 0, 0,142, 0, 0, 0,
+ 0, 0, 0, 1,137, 0, 0, 0,192, 0, 0, 0,190, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 1,191, 0, 0, 0,193, 0, 0, 0,
+138, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 1,136, 0, 0, 0,194, 0, 0, 0,192, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 1,
+193, 0, 0, 0,195, 0, 0, 0,136, 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 1,135, 0, 0, 0, 69, 0, 0, 0,194, 0, 0, 0,
+136, 0, 0, 0, 0, 0, 0, 1,195, 0, 0, 0, 69, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 1,187, 0, 0, 0,
+141, 0, 0, 0,188, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 1,189, 0, 0, 0,142, 0, 0, 0,187, 0, 0, 0, 68, 0, 0, 0,
+ 0, 0, 0, 1, 68, 0, 0, 0,188, 0, 0, 0,203, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 1,204, 0, 0, 0,189, 0, 0, 0,
+ 68, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 1, 69, 0, 0, 0,196, 0, 0, 0,197, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 1,
+198, 0, 0, 0,196, 0, 0, 0, 69, 0, 0, 0,195, 0, 0, 0, 0, 0, 0, 1,194, 0, 0, 0,197, 0, 0, 0,199, 0, 0, 0,
+192, 0, 0, 0, 0, 0, 0, 1,200, 0, 0, 0,198, 0, 0, 0,195, 0, 0, 0,193, 0, 0, 0, 0, 0, 0, 1,192, 0, 0, 0,
+199, 0, 0, 0,201, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 1,202, 0, 0, 0,200, 0, 0, 0,193, 0, 0, 0,191, 0, 0, 0,
+ 0, 0, 0, 1,190, 0, 0, 0,201, 0, 0, 0,203, 0, 0, 0,188, 0, 0, 0, 0, 0, 0, 1,204, 0, 0, 0,202, 0, 0, 0,
+191, 0, 0, 0,189, 0, 0, 0, 0, 0, 0, 1,196, 0, 0, 0,201, 0, 0, 0,199, 0, 0, 0,197, 0, 0, 0, 0, 0, 0, 1,
+200, 0, 0, 0,202, 0, 0, 0,196, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 1,196, 0, 0, 0,205, 0, 0, 0,203, 0, 0, 0,
+201, 0, 0, 0, 0, 0, 0, 1,204, 0, 0, 0,205, 0, 0, 0,196, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 1,136, 0, 0, 0,
+137, 0, 0, 0,161, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 1,162, 0, 0, 0,138, 0, 0, 0,136, 0, 0, 0,174, 0, 0, 0,
+ 0, 0, 0, 1,137, 0, 0, 0,139, 0, 0, 0,208, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 1,209, 0, 0, 0,140, 0, 0, 0,
+138, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 1,139, 0, 0, 0,141, 0, 0, 0,210, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 1,
+211, 0, 0, 0,142, 0, 0, 0,140, 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 1,141, 0, 0, 0,184, 0, 0, 0,163, 0, 0, 0,
+210, 0, 0, 0, 0, 0, 0, 1,164, 0, 0, 0,185, 0, 0, 0,142, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 1, 79, 0, 0, 0,
+206, 0, 0, 0,210, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 1,211, 0, 0, 0,207, 0, 0, 0, 80, 0, 0, 0,164, 0, 0, 0,
+ 0, 0, 0, 1,206, 0, 0, 0,212, 0, 0, 0,208, 0, 0, 0,210, 0, 0, 0, 0, 0, 0, 1,209, 0, 0, 0,213, 0, 0, 0,
+207, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 1, 77, 0, 0, 0,161, 0, 0, 0,208, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 1,
+209, 0, 0, 0,162, 0, 0, 0, 78, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 1,128, 0, 0, 0,127, 0, 0, 0, 70, 0, 0, 0,
+219, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 0,127, 0, 0, 0,129, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 1,130, 0, 0, 0,
+128, 0, 0, 0,219, 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 1,220, 0, 0, 0,129, 0, 0, 0,131, 0, 0, 0,218, 0, 0, 0,
+ 0, 0, 0, 1,132, 0, 0, 0,130, 0, 0, 0,217, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 1,218, 0, 0, 0,131, 0, 0, 0,
+133, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 1,134, 0, 0, 0,132, 0, 0, 0,215, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 1,
+216, 0, 0, 0,133, 0, 0, 0,134, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 1,214, 0, 0, 0,215, 0, 0, 0,226, 0, 0, 0,
+228, 0, 0, 0, 0, 0, 0, 1,227, 0, 0, 0,216, 0, 0, 0,214, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 1,215, 0, 0, 0,
+217, 0, 0, 0,224, 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 1,225, 0, 0, 0,218, 0, 0, 0,216, 0, 0, 0,227, 0, 0, 0,
+ 0, 0, 0, 1,217, 0, 0, 0,219, 0, 0, 0,222, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 1,223, 0, 0, 0,220, 0, 0, 0,
+218, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 1,219, 0, 0, 0, 70, 0, 0, 0,221, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 1,
+221, 0, 0, 0, 70, 0, 0, 0,220, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 1,221, 0, 0, 0,228, 0, 0, 0,226, 0, 0, 0,
+222, 0, 0, 0, 0, 0, 0, 1,227, 0, 0, 0,228, 0, 0, 0,221, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 1,222, 0, 0, 0,
+226, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,225, 0, 0, 0,227, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1,180, 0, 0, 0,178, 0, 0, 0,231, 0, 0, 0,229, 0, 0, 0, 0, 0, 0, 1,232, 0, 0, 0,179, 0, 0, 0,
+181, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 1,110, 0, 0, 0,180, 0, 0, 0,229, 0, 0, 0,251, 0, 0, 0, 0, 0, 0, 1,
+230, 0, 0, 0,181, 0, 0, 0,111, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 1,108, 0, 0, 0,110, 0, 0, 0,251, 0, 0, 0,
+253, 0, 0, 0, 0, 0, 0, 1,252, 0, 0, 0,111, 0, 0, 0,109, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 1,178, 0, 0, 0,
+ 14, 0, 0, 0,249, 0, 0, 0,231, 0, 0, 0, 0, 0, 0, 1,250, 0, 0, 0,112, 0, 0, 0,179, 0, 0, 0,232, 0, 0, 0,
+ 0, 0, 0, 1, 14, 0, 0, 0,113, 0, 0, 0,247, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 1,248, 0, 0, 0,114, 0, 0, 0,
+112, 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 1,113, 0, 0, 0,115, 0, 0, 0,245, 0, 0, 0,247, 0, 0, 0, 0, 0, 0, 1,
+246, 0, 0, 0,116, 0, 0, 0,114, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 1,115, 0, 0, 0,117, 0, 0, 0,243, 0, 0, 0,
+245, 0, 0, 0, 0, 0, 0, 1,244, 0, 0, 0,118, 0, 0, 0,116, 0, 0, 0,246, 0, 0, 0, 0, 0, 0, 1,117, 0, 0, 0,
+119, 0, 0, 0,241, 0, 0, 0,243, 0, 0, 0, 0, 0, 0, 1,242, 0, 0, 0,120, 0, 0, 0,118, 0, 0, 0,244, 0, 0, 0,
+ 0, 0, 0, 1,119, 0, 0, 0,121, 0, 0, 0,239, 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 1,240, 0, 0, 0,122, 0, 0, 0,
+120, 0, 0, 0,242, 0, 0, 0, 0, 0, 0, 1,121, 0, 0, 0,123, 0, 0, 0,237, 0, 0, 0,239, 0, 0, 0, 0, 0, 0, 1,
+238, 0, 0, 0,124, 0, 0, 0,122, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 1,123, 0, 0, 0,176, 0, 0, 0,233, 0, 0, 0,
+237, 0, 0, 0, 0, 0, 0, 1,234, 0, 0, 0,177, 0, 0, 0,124, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 1,176, 0, 0, 0,
+125, 0, 0, 0,235, 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 1,236, 0, 0, 0,126, 0, 0, 0,177, 0, 0, 0,234, 0, 0, 0,
+ 0, 0, 0, 1,125, 0, 0, 0,108, 0, 0, 0,253, 0, 0, 0,235, 0, 0, 0, 0, 0, 0, 1,254, 0, 0, 0,109, 0, 0, 0,
+126, 0, 0, 0,236, 0, 0, 0, 0, 0, 0, 1,235, 0, 0, 0,253, 0, 0, 0,255, 0, 0, 0, 17, 1, 0, 0, 0, 0, 0, 1,
+ 0, 1, 0, 0,254, 0, 0, 0,236, 0, 0, 0, 18, 1, 0, 0, 0, 0, 0, 1,233, 0, 0, 0,235, 0, 0, 0, 17, 1, 0, 0,
+ 19, 1, 0, 0, 0, 0, 0, 1, 18, 1, 0, 0,236, 0, 0, 0,234, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 1,237, 0, 0, 0,
+233, 0, 0, 0, 19, 1, 0, 0, 15, 1, 0, 0, 0, 0, 0, 1, 20, 1, 0, 0,234, 0, 0, 0,238, 0, 0, 0, 16, 1, 0, 0,
+ 0, 0, 0, 1,239, 0, 0, 0,237, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 0, 0, 0, 1, 16, 1, 0, 0,238, 0, 0, 0,
+240, 0, 0, 0, 14, 1, 0, 0, 0, 0, 0, 1,241, 0, 0, 0,239, 0, 0, 0, 13, 1, 0, 0, 11, 1, 0, 0, 0, 0, 0, 1,
+ 14, 1, 0, 0,240, 0, 0, 0,242, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 1,243, 0, 0, 0,241, 0, 0, 0, 11, 1, 0, 0,
+ 9, 1, 0, 0, 0, 0, 0, 1, 12, 1, 0, 0,242, 0, 0, 0,244, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 1,245, 0, 0, 0,
+243, 0, 0, 0, 9, 1, 0, 0, 7, 1, 0, 0, 0, 0, 0, 1, 10, 1, 0, 0,244, 0, 0, 0,246, 0, 0, 0, 8, 1, 0, 0,
+ 0, 0, 0, 1,247, 0, 0, 0,245, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 0, 0, 0, 1, 8, 1, 0, 0,246, 0, 0, 0,
+248, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 1,249, 0, 0, 0,247, 0, 0, 0, 5, 1, 0, 0, 3, 1, 0, 0, 0, 0, 0, 1,
+ 6, 1, 0, 0,248, 0, 0, 0,250, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 1,231, 0, 0, 0,249, 0, 0, 0, 3, 1, 0, 0,
+ 21, 1, 0, 0, 0, 0, 0, 1, 4, 1, 0, 0,250, 0, 0, 0,232, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1,253, 0, 0, 0,
+251, 0, 0, 0, 1, 1, 0, 0,255, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0,252, 0, 0, 0,254, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 1,251, 0, 0, 0,229, 0, 0, 0, 23, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 24, 1, 0, 0,230, 0, 0, 0,
+252, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1,229, 0, 0, 0,231, 0, 0, 0, 21, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 1,
+ 22, 1, 0, 0,232, 0, 0, 0,230, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 1, 65, 0, 0, 0,106, 0, 0, 0, 25, 1, 0, 0,
+ 71, 0, 0, 0, 0, 0, 0, 1, 26, 1, 0, 0,107, 0, 0, 0, 65, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 1,106, 0, 0, 0,
+104, 0, 0, 0, 27, 1, 0, 0, 25, 1, 0, 0, 0, 0, 0, 1, 28, 1, 0, 0,105, 0, 0, 0,107, 0, 0, 0, 26, 1, 0, 0,
+ 0, 0, 0, 1,104, 0, 0, 0,102, 0, 0, 0, 29, 1, 0, 0, 27, 1, 0, 0, 0, 0, 0, 1, 30, 1, 0, 0,103, 0, 0, 0,
+105, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 1,102, 0, 0, 0,100, 0, 0, 0, 31, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 1,
+ 32, 1, 0, 0,101, 0, 0, 0,103, 0, 0, 0, 30, 1, 0, 0, 0, 0, 0, 1,100, 0, 0, 0, 98, 0, 0, 0, 33, 1, 0, 0,
+ 31, 1, 0, 0, 0, 0, 0, 1, 34, 1, 0, 0, 99, 0, 0, 0,101, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 1, 98, 0, 0, 0,
+ 96, 0, 0, 0, 35, 1, 0, 0, 33, 1, 0, 0, 0, 0, 0, 1, 36, 1, 0, 0, 97, 0, 0, 0, 99, 0, 0, 0, 34, 1, 0, 0,
+ 0, 0, 0, 1, 96, 0, 0, 0, 94, 0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 0, 0, 0, 1, 38, 1, 0, 0, 95, 0, 0, 0,
+ 97, 0, 0, 0, 36, 1, 0, 0, 0, 0, 0, 1, 94, 0, 0, 0, 92, 0, 0, 0, 39, 1, 0, 0, 37, 1, 0, 0, 0, 0, 0, 1,
+ 40, 1, 0, 0, 93, 0, 0, 0, 95, 0, 0, 0, 38, 1, 0, 0, 0, 0, 0, 1, 92, 0, 0, 0, 90, 0, 0, 0, 41, 1, 0, 0,
+ 39, 1, 0, 0, 0, 0, 0, 1, 42, 1, 0, 0, 91, 0, 0, 0, 93, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 49, 1, 0, 0,
+ 50, 1, 0, 0, 69, 1, 0, 0, 79, 1, 0, 0, 0, 0, 0, 1, 70, 1, 0, 0, 50, 1, 0, 0, 49, 1, 0, 0, 80, 1, 0, 0,
+ 0, 0, 0, 1, 48, 1, 0, 0, 49, 1, 0, 0, 79, 1, 0, 0, 77, 1, 0, 0, 0, 0, 0, 1, 80, 1, 0, 0, 49, 1, 0, 0,
+ 48, 1, 0, 0, 78, 1, 0, 0, 0, 0, 0, 1, 47, 1, 0, 0, 48, 1, 0, 0, 77, 1, 0, 0, 81, 1, 0, 0, 0, 0, 0, 1,
+ 78, 1, 0, 0, 48, 1, 0, 0, 47, 1, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 87, 0, 0, 0, 89, 0, 0, 0, 47, 1, 0, 0,
+ 81, 1, 0, 0, 0, 0, 0, 1, 47, 1, 0, 0, 89, 0, 0, 0, 88, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0,
+ 87, 0, 0, 0, 81, 1, 0, 0, 75, 1, 0, 0, 0, 0, 0, 1, 82, 1, 0, 0, 88, 0, 0, 0, 86, 0, 0, 0, 76, 1, 0, 0,
+ 0, 0, 0, 1, 83, 0, 0, 0, 85, 0, 0, 0, 75, 1, 0, 0, 71, 1, 0, 0, 0, 0, 0, 1, 76, 1, 0, 0, 86, 0, 0, 0,
+ 84, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 83, 0, 0, 0, 71, 1, 0, 0, 73, 1, 0, 0, 0, 0, 0, 1,
+ 72, 1, 0, 0, 84, 0, 0, 0, 82, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 1, 71, 1, 0, 0, 77, 1, 0, 0, 79, 1, 0, 0,
+ 73, 1, 0, 0, 0, 0, 0, 1, 80, 1, 0, 0, 78, 1, 0, 0, 72, 1, 0, 0, 74, 1, 0, 0, 0, 0, 0, 1, 71, 1, 0, 0,
+ 75, 1, 0, 0, 81, 1, 0, 0, 77, 1, 0, 0, 0, 0, 0, 1, 82, 1, 0, 0, 76, 1, 0, 0, 72, 1, 0, 0, 78, 1, 0, 0,
+ 0, 0, 0, 1, 67, 1, 0, 0, 73, 1, 0, 0, 79, 1, 0, 0, 69, 1, 0, 0, 0, 0, 0, 1, 80, 1, 0, 0, 74, 1, 0, 0,
+ 68, 1, 0, 0, 70, 1, 0, 0, 0, 0, 0, 1, 79, 0, 0, 0, 81, 0, 0, 0, 73, 1, 0, 0, 67, 1, 0, 0, 0, 0, 0, 1,
+ 74, 1, 0, 0, 82, 0, 0, 0, 80, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 1,206, 0, 0, 0, 83, 1, 0, 0, 85, 1, 0, 0,
+212, 0, 0, 0, 0, 0, 0, 1, 86, 1, 0, 0, 84, 1, 0, 0,207, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 1, 79, 0, 0, 0,
+ 67, 1, 0, 0, 83, 1, 0, 0,206, 0, 0, 0, 0, 0, 0, 1, 84, 1, 0, 0, 68, 1, 0, 0, 80, 0, 0, 0,207, 0, 0, 0,
+ 0, 0, 0, 1, 77, 0, 0, 0,212, 0, 0, 0, 85, 1, 0, 0, 87, 1, 0, 0, 0, 0, 0, 1, 86, 1, 0, 0,213, 0, 0, 0,
+ 78, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 1, 77, 0, 0, 0, 87, 1, 0, 0, 41, 1, 0, 0, 90, 0, 0, 0, 0, 0, 0, 1,
+ 42, 1, 0, 0, 88, 1, 0, 0, 78, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 1, 75, 0, 0, 0, 65, 1, 0, 0, 93, 1, 0, 0,
+ 45, 1, 0, 0, 0, 0, 0, 1, 94, 1, 0, 0, 66, 1, 0, 0, 75, 0, 0, 0, 45, 1, 0, 0, 0, 0, 0, 1, 45, 1, 0, 0,
+ 93, 1, 0, 0, 91, 1, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 92, 1, 0, 0, 94, 1, 0, 0, 45, 1, 0, 0, 76, 0, 0, 0,
+ 0, 0, 0, 1, 76, 0, 0, 0, 91, 1, 0, 0, 89, 1, 0, 0, 46, 1, 0, 0, 0, 0, 0, 1, 90, 1, 0, 0, 92, 1, 0, 0,
+ 76, 0, 0, 0, 46, 1, 0, 0, 0, 0, 0, 1, 46, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 50, 1, 0, 0, 0, 0, 0, 1,
+ 70, 1, 0, 0, 90, 1, 0, 0, 46, 1, 0, 0, 50, 1, 0, 0, 0, 0, 0, 1, 67, 1, 0, 0, 69, 1, 0, 0, 89, 1, 0, 0,
+ 83, 1, 0, 0, 0, 0, 0, 1, 90, 1, 0, 0, 70, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 0, 0, 0, 1, 37, 1, 0, 0,
+ 39, 1, 0, 0, 59, 1, 0, 0, 51, 1, 0, 0, 0, 0, 0, 1, 60, 1, 0, 0, 40, 1, 0, 0, 38, 1, 0, 0, 52, 1, 0, 0,
+ 0, 0, 0, 1, 74, 0, 0, 0, 57, 1, 0, 0, 65, 1, 0, 0, 75, 0, 0, 0, 0, 0, 0, 1, 66, 1, 0, 0, 58, 1, 0, 0,
+ 74, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 1, 43, 1, 0, 0, 99, 1, 0, 0, 97, 1, 0, 0, 44, 1, 0, 0, 0, 0, 0, 1,
+ 98, 1, 0, 0,100, 1, 0, 0, 43, 1, 0, 0, 44, 1, 0, 0, 0, 0, 0, 1, 44, 1, 0, 0, 97, 1, 0, 0, 95, 1, 0, 0,
+ 73, 0, 0, 0, 0, 0, 0, 1, 96, 1, 0, 0, 98, 1, 0, 0, 44, 1, 0, 0, 73, 0, 0, 0, 0, 0, 0, 1, 73, 0, 0, 0,
+ 95, 1, 0, 0, 57, 1, 0, 0, 74, 0, 0, 0, 0, 0, 0, 1, 58, 1, 0, 0, 96, 1, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0,
+ 0, 0, 0, 1, 33, 1, 0, 0, 35, 1, 0, 0,103, 1, 0, 0,105, 1, 0, 0, 0, 0, 0, 1,104, 1, 0, 0, 36, 1, 0, 0,
+ 34, 1, 0, 0,106, 1, 0, 0, 0, 0, 0, 1,105, 1, 0, 0,103, 1, 0, 0,109, 1, 0, 0,107, 1, 0, 0, 0, 0, 0, 1,
+110, 1, 0, 0,104, 1, 0, 0,106, 1, 0, 0,108, 1, 0, 0, 0, 0, 0, 1,107, 1, 0, 0,109, 1, 0, 0,111, 1, 0, 0,
+113, 1, 0, 0, 0, 0, 0, 1,112, 1, 0, 0,110, 1, 0, 0,108, 1, 0, 0,114, 1, 0, 0, 0, 0, 0, 1,113, 1, 0, 0,
+111, 1, 0, 0,117, 1, 0, 0,115, 1, 0, 0, 0, 0, 0, 1,118, 1, 0, 0,112, 1, 0, 0,114, 1, 0, 0,116, 1, 0, 0,
+ 0, 0, 0, 1, 55, 1, 0, 0,119, 1, 0, 0,115, 1, 0, 0,117, 1, 0, 0, 0, 0, 0, 1,116, 1, 0, 0,120, 1, 0, 0,
+ 56, 1, 0, 0,118, 1, 0, 0, 0, 0, 0, 1, 57, 1, 0, 0, 95, 1, 0, 0,115, 1, 0, 0,119, 1, 0, 0, 0, 0, 0, 1,
+116, 1, 0, 0, 96, 1, 0, 0, 58, 1, 0, 0,120, 1, 0, 0, 0, 0, 0, 1, 95, 1, 0, 0, 97, 1, 0, 0,113, 1, 0, 0,
+115, 1, 0, 0, 0, 0, 0, 1,114, 1, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0,116, 1, 0, 0, 0, 0, 0, 1, 97, 1, 0, 0,
+ 99, 1, 0, 0,107, 1, 0, 0,113, 1, 0, 0, 0, 0, 0, 1,108, 1, 0, 0,100, 1, 0, 0, 98, 1, 0, 0,114, 1, 0, 0,
+ 0, 0, 0, 1, 99, 1, 0, 0,101, 1, 0, 0,105, 1, 0, 0,107, 1, 0, 0, 0, 0, 0, 1,106, 1, 0, 0,102, 1, 0, 0,
+100, 1, 0, 0,108, 1, 0, 0, 0, 0, 0, 1, 31, 1, 0, 0, 33, 1, 0, 0,105, 1, 0, 0,101, 1, 0, 0, 0, 0, 0, 1,
+106, 1, 0, 0, 34, 1, 0, 0, 32, 1, 0, 0,102, 1, 0, 0, 0, 0, 0, 1, 72, 0, 0, 0,101, 1, 0, 0, 99, 1, 0, 0,
+ 43, 1, 0, 0, 0, 0, 0, 1,100, 1, 0, 0,102, 1, 0, 0, 72, 0, 0, 0, 43, 1, 0, 0, 0, 0, 0, 1, 25, 1, 0, 0,
+ 27, 1, 0, 0, 29, 1, 0, 0, 31, 1, 0, 0, 0, 0, 0, 1, 30, 1, 0, 0, 28, 1, 0, 0, 26, 1, 0, 0, 32, 1, 0, 0,
+ 0, 0, 0, 1, 25, 1, 0, 0, 31, 1, 0, 0,101, 1, 0, 0, 72, 0, 0, 0, 0, 0, 0, 1,102, 1, 0, 0, 32, 1, 0, 0,
+ 26, 1, 0, 0, 72, 0, 0, 0, 0, 0, 0, 1, 71, 0, 0, 0, 25, 1, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 72, 0, 0, 0, 26, 1, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 35, 1, 0, 0, 37, 1, 0, 0, 51, 1, 0, 0,
+103, 1, 0, 0, 0, 0, 0, 1, 52, 1, 0, 0, 38, 1, 0, 0, 36, 1, 0, 0,104, 1, 0, 0, 0, 0, 0, 1, 51, 1, 0, 0,
+ 53, 1, 0, 0,109, 1, 0, 0,103, 1, 0, 0, 0, 0, 0, 1,110, 1, 0, 0, 54, 1, 0, 0, 52, 1, 0, 0,104, 1, 0, 0,
+ 0, 0, 0, 1, 53, 1, 0, 0,123, 1, 0, 0,111, 1, 0, 0,109, 1, 0, 0, 0, 0, 0, 1,112, 1, 0, 0,124, 1, 0, 0,
+ 54, 1, 0, 0,110, 1, 0, 0, 0, 0, 0, 1, 55, 1, 0, 0,117, 1, 0, 0,111, 1, 0, 0,123, 1, 0, 0, 0, 0, 0, 1,
+112, 1, 0, 0,118, 1, 0, 0, 56, 1, 0, 0,124, 1, 0, 0, 0, 0, 0, 1, 89, 1, 0, 0, 91, 1, 0, 0,127, 1, 0, 0,
+125, 1, 0, 0, 0, 0, 0, 1,128, 1, 0, 0, 92, 1, 0, 0, 90, 1, 0, 0,126, 1, 0, 0, 0, 0, 0, 1, 59, 1, 0, 0,
+125, 1, 0, 0,127, 1, 0, 0, 61, 1, 0, 0, 0, 0, 0, 1,128, 1, 0, 0,126, 1, 0, 0, 60, 1, 0, 0, 62, 1, 0, 0,
+ 0, 0, 0, 1, 39, 1, 0, 0, 41, 1, 0, 0,125, 1, 0, 0, 59, 1, 0, 0, 0, 0, 0, 1,126, 1, 0, 0, 42, 1, 0, 0,
+ 40, 1, 0, 0, 60, 1, 0, 0, 0, 0, 0, 1, 41, 1, 0, 0, 85, 1, 0, 0, 83, 1, 0, 0,125, 1, 0, 0, 0, 0, 0, 1,
+ 84, 1, 0, 0, 86, 1, 0, 0, 42, 1, 0, 0,126, 1, 0, 0, 0, 0, 0, 1, 83, 1, 0, 0, 89, 1, 0, 0,125, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1,126, 1, 0, 0, 90, 1, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 41, 1, 0, 0,
+ 87, 1, 0, 0, 85, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 86, 1, 0, 0, 88, 1, 0, 0, 42, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 55, 1, 0, 0, 63, 1, 0, 0,121, 1, 0, 0,119, 1, 0, 0, 0, 0, 0, 1,122, 1, 0, 0, 64, 1, 0, 0,
+ 56, 1, 0, 0,120, 1, 0, 0, 0, 0, 0, 1, 57, 1, 0, 0,119, 1, 0, 0,121, 1, 0, 0, 65, 1, 0, 0, 0, 0, 0, 1,
+122, 1, 0, 0,120, 1, 0, 0, 58, 1, 0, 0, 66, 1, 0, 0, 0, 0, 0, 1, 61, 1, 0, 0,127, 1, 0, 0,121, 1, 0, 0,
+ 63, 1, 0, 0, 0, 0, 0, 1,122, 1, 0, 0,128, 1, 0, 0, 62, 1, 0, 0, 64, 1, 0, 0, 0, 0, 0, 1, 91, 1, 0, 0,
+ 93, 1, 0, 0,121, 1, 0, 0,127, 1, 0, 0, 0, 0, 0, 1,122, 1, 0, 0, 94, 1, 0, 0, 92, 1, 0, 0,128, 1, 0, 0,
+ 0, 0, 0, 1, 65, 1, 0, 0,121, 1, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 94, 1, 0, 0,122, 1, 0, 0,
+ 66, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,141, 1, 0, 0,129, 1, 0, 0,155, 1, 0, 0,143, 1, 0, 0, 0, 0, 0, 1,
+156, 1, 0, 0,130, 1, 0, 0,142, 1, 0, 0,144, 1, 0, 0, 0, 0, 0, 1,141, 1, 0, 0,143, 1, 0, 0,145, 1, 0, 0,
+139, 1, 0, 0, 0, 0, 0, 1,146, 1, 0, 0,144, 1, 0, 0,142, 1, 0, 0,140, 1, 0, 0, 0, 0, 0, 1,139, 1, 0, 0,
+145, 1, 0, 0,147, 1, 0, 0,137, 1, 0, 0, 0, 0, 0, 1,148, 1, 0, 0,146, 1, 0, 0,140, 1, 0, 0,138, 1, 0, 0,
+ 0, 0, 0, 1,137, 1, 0, 0,147, 1, 0, 0,149, 1, 0, 0,135, 1, 0, 0, 0, 0, 0, 1,150, 1, 0, 0,148, 1, 0, 0,
+138, 1, 0, 0,136, 1, 0, 0, 0, 0, 0, 1,135, 1, 0, 0,149, 1, 0, 0,151, 1, 0, 0,133, 1, 0, 0, 0, 0, 0, 1,
+152, 1, 0, 0,150, 1, 0, 0,136, 1, 0, 0,134, 1, 0, 0, 0, 0, 0, 1,133, 1, 0, 0,151, 1, 0, 0,153, 1, 0, 0,
+131, 1, 0, 0, 0, 0, 0, 1,154, 1, 0, 0,152, 1, 0, 0,134, 1, 0, 0,132, 1, 0, 0, 0, 0, 0, 1,151, 1, 0, 0,
+161, 1, 0, 0,159, 1, 0, 0,153, 1, 0, 0, 0, 0, 0, 1,160, 1, 0, 0,162, 1, 0, 0,152, 1, 0, 0,154, 1, 0, 0,
+ 0, 0, 0, 1,149, 1, 0, 0,163, 1, 0, 0,161, 1, 0, 0,151, 1, 0, 0, 0, 0, 0, 1,162, 1, 0, 0,164, 1, 0, 0,
+150, 1, 0, 0,152, 1, 0, 0, 0, 0, 0, 1,147, 1, 0, 0,165, 1, 0, 0,163, 1, 0, 0,149, 1, 0, 0, 0, 0, 0, 1,
+164, 1, 0, 0,166, 1, 0, 0,148, 1, 0, 0,150, 1, 0, 0, 0, 0, 0, 1,145, 1, 0, 0,167, 1, 0, 0,165, 1, 0, 0,
+147, 1, 0, 0, 0, 0, 0, 1,166, 1, 0, 0,168, 1, 0, 0,146, 1, 0, 0,148, 1, 0, 0, 0, 0, 0, 1,143, 1, 0, 0,
+169, 1, 0, 0,167, 1, 0, 0,145, 1, 0, 0, 0, 0, 0, 1,168, 1, 0, 0,170, 1, 0, 0,144, 1, 0, 0,146, 1, 0, 0,
+ 0, 0, 0, 1,143, 1, 0, 0,155, 1, 0, 0,157, 1, 0, 0,169, 1, 0, 0, 0, 0, 0, 1,158, 1, 0, 0,156, 1, 0, 0,
+144, 1, 0, 0,170, 1, 0, 0, 0, 0, 0, 1, 59, 1, 0, 0, 61, 1, 0, 0,185, 1, 0, 0,183, 1, 0, 0, 0, 0, 0, 1,
+186, 1, 0, 0, 62, 1, 0, 0, 60, 1, 0, 0,184, 1, 0, 0, 0, 0, 0, 1, 61, 1, 0, 0,131, 1, 0, 0,153, 1, 0, 0,
+185, 1, 0, 0, 0, 0, 0, 1,154, 1, 0, 0,132, 1, 0, 0, 62, 1, 0, 0,186, 1, 0, 0, 0, 0, 0, 1, 51, 1, 0, 0,
+ 59, 1, 0, 0,183, 1, 0, 0, 53, 1, 0, 0, 0, 0, 0, 1,184, 1, 0, 0, 60, 1, 0, 0, 52, 1, 0, 0, 54, 1, 0, 0,
+ 0, 0, 0, 1,123, 1, 0, 0,171, 1, 0, 0,155, 1, 0, 0,129, 1, 0, 0, 0, 0, 0, 1,156, 1, 0, 0,172, 1, 0, 0,
+124, 1, 0, 0,130, 1, 0, 0, 0, 0, 0, 1,153, 1, 0, 0,159, 1, 0, 0,181, 1, 0, 0,185, 1, 0, 0, 0, 0, 0, 1,
+182, 1, 0, 0,160, 1, 0, 0,154, 1, 0, 0,186, 1, 0, 0, 0, 0, 0, 1,179, 1, 0, 0,187, 1, 0, 0,185, 1, 0, 0,
+181, 1, 0, 0, 0, 0, 0, 1,186, 1, 0, 0,188, 1, 0, 0,180, 1, 0, 0,182, 1, 0, 0, 0, 0, 0, 1,175, 1, 0, 0,
+187, 1, 0, 0,179, 1, 0, 0,177, 1, 0, 0, 0, 0, 0, 1,180, 1, 0, 0,188, 1, 0, 0,176, 1, 0, 0,178, 1, 0, 0,
+ 0, 0, 0, 1,173, 1, 0, 0,189, 1, 0, 0,187, 1, 0, 0,175, 1, 0, 0, 0, 0, 0, 1,188, 1, 0, 0,190, 1, 0, 0,
+174, 1, 0, 0,176, 1, 0, 0, 0, 0, 0, 1,171, 1, 0, 0,189, 1, 0, 0,173, 1, 0, 0,191, 1, 0, 0, 0, 0, 0, 1,
+174, 1, 0, 0,190, 1, 0, 0,172, 1, 0, 0,192, 1, 0, 0, 0, 0, 0, 1,155, 1, 0, 0,171, 1, 0, 0,191, 1, 0, 0,
+157, 1, 0, 0, 0, 0, 0, 1,192, 1, 0, 0,172, 1, 0, 0,156, 1, 0, 0,158, 1, 0, 0, 0, 0, 0, 1, 53, 1, 0, 0,
+189, 1, 0, 0,171, 1, 0, 0,123, 1, 0, 0, 0, 0, 0, 1,172, 1, 0, 0,190, 1, 0, 0, 54, 1, 0, 0,124, 1, 0, 0,
+ 0, 0, 0, 1, 53, 1, 0, 0,183, 1, 0, 0,187, 1, 0, 0,189, 1, 0, 0, 0, 0, 0, 1,188, 1, 0, 0,184, 1, 0, 0,
+ 54, 1, 0, 0,190, 1, 0, 0, 0, 0, 0, 1,183, 1, 0, 0,185, 1, 0, 0,187, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+188, 1, 0, 0,186, 1, 0, 0,184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,157, 1, 0, 0,191, 1, 0, 0,193, 1, 0, 0,
+217, 1, 0, 0, 0, 0, 0, 1,194, 1, 0, 0,192, 1, 0, 0,158, 1, 0, 0,218, 1, 0, 0, 0, 0, 0, 1,191, 1, 0, 0,
+173, 1, 0, 0,203, 1, 0, 0,193, 1, 0, 0, 0, 0, 0, 1,204, 1, 0, 0,174, 1, 0, 0,192, 1, 0, 0,194, 1, 0, 0,
+ 0, 0, 0, 1,173, 1, 0, 0,175, 1, 0, 0,201, 1, 0, 0,203, 1, 0, 0, 0, 0, 0, 1,202, 1, 0, 0,176, 1, 0, 0,
+174, 1, 0, 0,204, 1, 0, 0, 0, 0, 0, 1,175, 1, 0, 0,177, 1, 0, 0,199, 1, 0, 0,201, 1, 0, 0, 0, 0, 0, 1,
+200, 1, 0, 0,178, 1, 0, 0,176, 1, 0, 0,202, 1, 0, 0, 0, 0, 0, 1,177, 1, 0, 0,179, 1, 0, 0,197, 1, 0, 0,
+199, 1, 0, 0, 0, 0, 0, 1,198, 1, 0, 0,180, 1, 0, 0,178, 1, 0, 0,200, 1, 0, 0, 0, 0, 0, 1,179, 1, 0, 0,
+181, 1, 0, 0,195, 1, 0, 0,197, 1, 0, 0, 0, 0, 0, 1,196, 1, 0, 0,182, 1, 0, 0,180, 1, 0, 0,198, 1, 0, 0,
+ 0, 0, 0, 1,181, 1, 0, 0,159, 1, 0, 0,215, 1, 0, 0,195, 1, 0, 0, 0, 0, 0, 1,216, 1, 0, 0,160, 1, 0, 0,
+182, 1, 0, 0,196, 1, 0, 0, 0, 0, 0, 1,169, 1, 0, 0,157, 1, 0, 0,217, 1, 0, 0,205, 1, 0, 0, 0, 0, 0, 1,
+218, 1, 0, 0,158, 1, 0, 0,170, 1, 0, 0,206, 1, 0, 0, 0, 0, 0, 1,167, 1, 0, 0,169, 1, 0, 0,205, 1, 0, 0,
+207, 1, 0, 0, 0, 0, 0, 1,206, 1, 0, 0,170, 1, 0, 0,168, 1, 0, 0,208, 1, 0, 0, 0, 0, 0, 1,165, 1, 0, 0,
+167, 1, 0, 0,207, 1, 0, 0,209, 1, 0, 0, 0, 0, 0, 1,208, 1, 0, 0,168, 1, 0, 0,166, 1, 0, 0,210, 1, 0, 0,
+ 0, 0, 0, 1,163, 1, 0, 0,165, 1, 0, 0,209, 1, 0, 0,211, 1, 0, 0, 0, 0, 0, 1,210, 1, 0, 0,166, 1, 0, 0,
+164, 1, 0, 0,212, 1, 0, 0, 0, 0, 0, 1,161, 1, 0, 0,163, 1, 0, 0,211, 1, 0, 0,213, 1, 0, 0, 0, 0, 0, 1,
+212, 1, 0, 0,164, 1, 0, 0,162, 1, 0, 0,214, 1, 0, 0, 0, 0, 0, 1,159, 1, 0, 0,161, 1, 0, 0,213, 1, 0, 0,
+215, 1, 0, 0, 0, 0, 0, 1,214, 1, 0, 0,162, 1, 0, 0,160, 1, 0, 0,216, 1, 0, 0, 0, 0, 0, 1,199, 1, 0, 0,
+197, 1, 0, 0,221, 1, 0, 0,219, 1, 0, 0, 0, 0, 0, 1,222, 1, 0, 0,198, 1, 0, 0,200, 1, 0, 0,220, 1, 0, 0,
+ 0, 0, 0, 1,219, 1, 0, 0,221, 1, 0, 0,223, 1, 0, 0,225, 1, 0, 0, 0, 0, 0, 1,224, 1, 0, 0,222, 1, 0, 0,
+220, 1, 0, 0,226, 1, 0, 0, 0, 0, 0, 1,225, 1, 0, 0,223, 1, 0, 0,229, 1, 0, 0,227, 1, 0, 0, 0, 0, 0, 1,
+230, 1, 0, 0,224, 1, 0, 0,226, 1, 0, 0,228, 1, 0, 0, 0, 0, 0, 1,227, 1, 0, 0,229, 1, 0, 0,231, 1, 0, 0,
+233, 1, 0, 0, 0, 0, 0, 1,232, 1, 0, 0,230, 1, 0, 0,228, 1, 0, 0,234, 1, 0, 0, 0, 0, 0, 1,205, 1, 0, 0,
+217, 1, 0, 0,227, 1, 0, 0,233, 1, 0, 0, 0, 0, 0, 1,228, 1, 0, 0,218, 1, 0, 0,206, 1, 0, 0,234, 1, 0, 0,
+ 0, 0, 0, 1,193, 1, 0, 0,225, 1, 0, 0,227, 1, 0, 0,217, 1, 0, 0, 0, 0, 0, 1,228, 1, 0, 0,226, 1, 0, 0,
+194, 1, 0, 0,218, 1, 0, 0, 0, 0, 0, 1,193, 1, 0, 0,203, 1, 0, 0,219, 1, 0, 0,225, 1, 0, 0, 0, 0, 0, 1,
+220, 1, 0, 0,204, 1, 0, 0,194, 1, 0, 0,226, 1, 0, 0, 0, 0, 0, 1,199, 1, 0, 0,219, 1, 0, 0,203, 1, 0, 0,
+201, 1, 0, 0, 0, 0, 0, 1,204, 1, 0, 0,220, 1, 0, 0,200, 1, 0, 0,202, 1, 0, 0, 0, 0, 0, 1,195, 1, 0, 0,
+215, 1, 0, 0,221, 1, 0, 0,197, 1, 0, 0, 0, 0, 0, 1,222, 1, 0, 0,216, 1, 0, 0,196, 1, 0, 0,198, 1, 0, 0,
+ 0, 0, 0, 1,213, 1, 0, 0,223, 1, 0, 0,221, 1, 0, 0,215, 1, 0, 0, 0, 0, 0, 1,222, 1, 0, 0,224, 1, 0, 0,
+214, 1, 0, 0,216, 1, 0, 0, 0, 0, 0, 1,211, 1, 0, 0,229, 1, 0, 0,223, 1, 0, 0,213, 1, 0, 0, 0, 0, 0, 1,
+224, 1, 0, 0,230, 1, 0, 0,212, 1, 0, 0,214, 1, 0, 0, 0, 0, 0, 1,209, 1, 0, 0,231, 1, 0, 0,229, 1, 0, 0,
+211, 1, 0, 0, 0, 0, 0, 1,230, 1, 0, 0,232, 1, 0, 0,210, 1, 0, 0,212, 1, 0, 0, 0, 0, 0, 1,207, 1, 0, 0,
+233, 1, 0, 0,231, 1, 0, 0,209, 1, 0, 0, 0, 0, 0, 1,232, 1, 0, 0,234, 1, 0, 0,208, 1, 0, 0,210, 1, 0, 0,
+ 0, 0, 0, 1,205, 1, 0, 0,233, 1, 0, 0,207, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,208, 1, 0, 0,234, 1, 0, 0,
+206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,133, 1, 0, 0,131, 1, 0, 0,245, 1, 0, 0,243, 1, 0, 0, 0, 0, 0, 1,
+246, 1, 0, 0,132, 1, 0, 0,134, 1, 0, 0,244, 1, 0, 0, 0, 0, 0, 1,135, 1, 0, 0,133, 1, 0, 0,243, 1, 0, 0,
+241, 1, 0, 0, 0, 0, 0, 1,244, 1, 0, 0,134, 1, 0, 0,136, 1, 0, 0,242, 1, 0, 0, 0, 0, 0, 1,137, 1, 0, 0,
+135, 1, 0, 0,241, 1, 0, 0,239, 1, 0, 0, 0, 0, 0, 1,242, 1, 0, 0,136, 1, 0, 0,138, 1, 0, 0,240, 1, 0, 0,
+ 0, 0, 0, 1,139, 1, 0, 0,137, 1, 0, 0,239, 1, 0, 0,237, 1, 0, 0, 0, 0, 0, 1,240, 1, 0, 0,138, 1, 0, 0,
+140, 1, 0, 0,238, 1, 0, 0, 0, 0, 0, 1,141, 1, 0, 0,139, 1, 0, 0,237, 1, 0, 0,235, 1, 0, 0, 0, 0, 0, 1,
+238, 1, 0, 0,140, 1, 0, 0,142, 1, 0, 0,236, 1, 0, 0, 0, 0, 0, 1,129, 1, 0, 0,141, 1, 0, 0,235, 1, 0, 0,
+247, 1, 0, 0, 0, 0, 0, 1,236, 1, 0, 0,142, 1, 0, 0,130, 1, 0, 0,248, 1, 0, 0, 0, 0, 0, 1,235, 1, 0, 0,
+243, 1, 0, 0,245, 1, 0, 0,247, 1, 0, 0, 0, 0, 0, 1,246, 1, 0, 0,244, 1, 0, 0,236, 1, 0, 0,248, 1, 0, 0,
+ 0, 0, 0, 1,235, 1, 0, 0,237, 1, 0, 0,241, 1, 0, 0,243, 1, 0, 0, 0, 0, 0, 1,242, 1, 0, 0,238, 1, 0, 0,
+236, 1, 0, 0,244, 1, 0, 0, 0, 0, 0, 1,237, 1, 0, 0,239, 1, 0, 0,241, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+242, 1, 0, 0,240, 1, 0, 0,238, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 55, 1, 0, 0,123, 1, 0, 0,129, 1, 0, 0,
+247, 1, 0, 0, 0, 0, 0, 1,130, 1, 0, 0,124, 1, 0, 0, 56, 1, 0, 0,248, 1, 0, 0, 0, 0, 0, 1, 55, 1, 0, 0,
+247, 1, 0, 0,245, 1, 0, 0, 63, 1, 0, 0, 0, 0, 0, 1,246, 1, 0, 0,248, 1, 0, 0, 56, 1, 0, 0, 64, 1, 0, 0,
+ 0, 0, 0, 1, 61, 1, 0, 0, 63, 1, 0, 0,245, 1, 0, 0,131, 1, 0, 0, 0, 0, 0, 1,246, 1, 0, 0, 64, 1, 0, 0,
+ 62, 1, 0, 0,132, 1, 0, 0, 0, 0, 0, 1, 68, 65, 84, 65,240, 85, 0, 0, 40,176,154, 2, 61, 0, 0, 0,244, 1, 0, 0,
+ 3,112, 28, 63,185,178,236, 62,224,124, 27, 63,235, 65,232, 62,144, 63, 30, 63,233,195,226, 62,118,152, 32, 63, 37,167,236, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 2,232,209, 62,222, 21,226, 62,102,109,215, 62,222,147,231, 62, 28,135,213, 62,
+172, 4,236, 62, 56, 54,205, 62, 22,249,235, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,118,152, 32, 63, 37,167,236, 62,
+144, 63, 30, 63,233,195,226, 62,108,235, 33, 63,197,235,220, 62,209,151, 37, 63, 89,161,236, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0, 76,144,202, 62,186, 61,220, 62, 2,232,209, 62,222, 21,226, 62, 56, 54,205, 62, 22,249,235, 62,128, 55,195, 62,
+ 70,243,235, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,144, 63, 30, 63,233,195,226, 62, 20, 55, 25, 63, 1, 35,223, 62,
+200,178, 25, 63, 77,233,214, 62,108,235, 33, 63,197,235,220, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,146, 1,219, 62,
+ 66, 59,214, 62,248,248,219, 62,246,116,222, 62, 2,232,209, 62,222, 21,226, 62, 76,144,202, 62,186, 61,220, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0,224,124, 27, 63,235, 65,232, 62, 87,252, 24, 63, 93,111,230, 62, 20, 55, 25, 63, 1, 35,223, 62,
+144, 63, 30, 63,233,195,226, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,248,248,219, 62,246,116,222, 62,118,110,220, 62,
+ 78,193,229, 62,102,109,215, 62,222,147,231, 62, 2,232,209, 62,222, 21,226, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+ 87,252, 24, 63, 93,111,230, 62, 22,195, 22, 63,195, 90,232, 62,191, 91, 20, 63,193, 18,227, 62, 20, 55, 25, 63, 1, 35,223, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,162,175,229, 62,178,100,226, 62,248,224,224, 62,182,172,231, 62,118,110,220, 62,
+ 78,193,229, 62,248,248,219, 62,246,116,222, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0, 20, 55, 25, 63, 1, 35,223, 62,
+191, 91, 20, 63,193, 18,227, 62,187,165, 17, 63,225, 6,221, 62,200,178, 25, 63, 77,233,214, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0,170, 27,235, 62,214, 88,220, 62,162,175,229, 62,178,100,226, 62,248,248,219, 62,246,116,222, 62,146, 1,219, 62,
+ 66, 59,214, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,191, 91, 20, 63,193, 18,227, 62,164, 18, 18, 63,173,201,236, 62,
+157,231, 13, 63, 89,161,236, 62,187,165, 17, 63,225, 6,221, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,232,151,242, 62,
+ 70,243,235, 62,216, 65,234, 62,158, 27,236, 62,162,175,229, 62,178,100,226, 62,170, 27,235, 62,214, 88,220, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0, 22,195, 22, 63,195, 90,232, 62, 11,202, 21, 63, 1,189,236, 62,164, 18, 18, 63,173,201,236, 62,
+191, 91, 20, 63,193, 18,227, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,216, 65,234, 62,158, 27,236, 62, 12,211,226, 62,
+246, 14,236, 62,248,224,224, 62,182,172,231, 62,162,175,229, 62,178,100,226, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+ 11,202, 21, 63, 1,189,236, 62,215,202, 22, 63,237,124,241, 62,125,105, 20, 63, 1, 71,246, 62,164, 18, 18, 63,173,201,236, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 42,148,229, 62,246,152,245, 62,112,209,224, 62,226,206,240, 62, 12,211,226, 62,
+246, 14,236, 62,216, 65,234, 62,158, 27,236, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,164, 18, 18, 63,173,201,236, 62,
+125,105, 20, 63, 1, 71,246, 62, 44,173, 17, 63,231,149,252, 62,157,231, 13, 63, 89,161,236, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0,206, 12,235, 62,218,231,251, 62, 42,148,229, 62,246,152,245, 62,216, 65,234, 62,158, 27,236, 62,232,151,242, 62,
+ 70,243,235, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,125,105, 20, 63, 1, 71,246, 62, 37, 59, 25, 63, 49, 73,250, 62,
+108,178, 25, 63,218,108, 1, 63, 44,173, 17, 63,231,149,252, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 76, 2,219, 62,
+213, 21, 1, 63,216,240,219, 62, 38,155,249, 62, 42,148,229, 62,246,152,245, 62,206, 12,235, 62,218,231,251, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0,215,202, 22, 63,237,124,241, 62,195, 1, 25, 63,169,102,243, 62, 37, 59, 25, 63, 49, 73,250, 62,
+125,105, 20, 63, 1, 71,246, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,216,240,219, 62, 38,155,249, 62,156, 99,220, 62,
+154,184,242, 62,112,209,224, 62,226,206,240, 62, 42,148,229, 62,246,152,245, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+195, 1, 25, 63,169,102,243, 62,176,125, 27, 63,149,145,241, 62,167, 74, 30, 63, 3,153,246, 62, 37, 59, 25, 63, 49, 73,250, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,212,209,209, 62,246,234,245, 62,192,107,215, 62,138,227,240, 62,156, 99,220, 62,
+154,184,242, 62,216,240,219, 62, 38,155,249, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0, 37, 59, 25, 63, 49, 73,250, 62,
+167, 74, 30, 63, 3,153,246, 62,204,230, 33, 63,107,232,252, 62,108,178, 25, 63,218,108, 1, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0,132,153,202, 62, 94, 58,252, 62,212,209,209, 62,246,234,245, 62,216,240,219, 62, 38,155,249, 62, 76, 2,219, 62,
+213, 21, 1, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,167, 74, 30, 63, 3,153,246, 62,118,152, 32, 63, 37,167,236, 62,
+209,151, 37, 63, 89,161,236, 62,204,230, 33, 63,107,232,252, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,128, 55,195, 62,
+ 70,243,235, 62, 56, 54,205, 62, 22,249,235, 62,212,209,209, 62,246,234,245, 62,132,153,202, 62, 94, 58,252, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0,176,125, 27, 63,149,145,241, 62, 3,112, 28, 63,185,178,236, 62,118,152, 32, 63, 37,167,236, 62,
+167, 74, 30, 63, 3,153,246, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 56, 54,205, 62, 22,249,235, 62, 28,135,213, 62,
+172, 4,236, 62,192,107,215, 62,138,227,240, 62,212,209,209, 62,246,234,245, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+ 3,112, 28, 63,185,178,236, 62,176,125, 27, 63,149,145,241, 62, 42, 39, 27, 63, 57, 1,241, 62,140,249, 27, 63,115,186,236, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,206, 24,216, 62, 46, 83,240, 62,192,107,215, 62,138,227,240, 62, 28,135,213, 62,
+172, 4,236, 62, 8,116,214, 62,102, 12,236, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,176,125, 27, 63,149,145,241, 62,
+195, 1, 25, 63,169,102,243, 62, 6,248, 24, 63,185, 91,242, 62, 42, 39, 27, 63, 57, 1,241, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0, 22,119,220, 62,174,173,241, 62,156, 99,220, 62,154,184,242, 62,192,107,215, 62,138,227,240, 62,206, 24,216, 62,
+ 46, 83,240, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,195, 1, 25, 63,169,102,243, 62,215,202, 22, 63,237,124,241, 62,
+157, 38, 23, 63,225,173,240, 62, 6,248, 24, 63,185, 91,242, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,234, 25,224, 62,
+214,255,239, 62,112,209,224, 62,226,206,240, 62,156, 99,220, 62,154,184,242, 62, 22,119,220, 62,174,173,241, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0,215,202, 22, 63,237,124,241, 62, 11,202, 21, 63, 1,189,236, 62, 13, 89, 22, 63,247,196,236, 62,
+157, 38, 23, 63,225,173,240, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 8,181,225, 62,234, 22,236, 62, 12,211,226, 62,
+246, 14,236, 62,112,209,224, 62,226,206,240, 62,234, 25,224, 62,214,255,239, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+ 11,202, 21, 63, 1,189,236, 62, 22,195, 22, 63,195, 90,232, 62, 88, 33, 23, 63, 69, 47,233, 62, 13, 89, 22, 63,247,196,236, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,112, 36,224, 62, 58,129,232, 62,248,224,224, 62,182,172,231, 62, 12,211,226, 62,
+246, 14,236, 62, 8,181,225, 62,234, 22,236, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0, 22,195, 22, 63,195, 90,232, 62,
+ 87,252, 24, 63, 93,111,230, 62,100,243, 24, 63, 5,123,231, 62, 88, 33, 23, 63, 69, 47,233, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0, 90,128,220, 62,248,204,230, 62,118,110,220, 62, 78,193,229, 62,248,224,224, 62,182,172,231, 62,112, 36,224, 62,
+ 58,129,232, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0, 87,252, 24, 63, 93,111,230, 62,224,124, 27, 63,235, 65,232, 62,
+169, 37, 27, 63, 35,211,232, 62,100,243, 24, 63, 5,123,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,206, 27,216, 62,
+ 22, 37,232, 62,102,109,215, 62,222,147,231, 62,118,110,220, 62, 78,193,229, 62, 90,128,220, 62,248,204,230, 62,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,240, 0,224,124, 27, 63,235, 65,232, 62, 3,112, 28, 63,185,178,236, 62,140,249, 27, 63,115,186,236, 62,
+169, 37, 27, 63, 35,211,232, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 8,116,214, 62,102, 12,236, 62, 28,135,213, 62,
+172, 4,236, 62,102,109,215, 62,222,147,231, 62,206, 27,216, 62, 22, 37,232, 62,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,240, 0,
+138,242, 24, 63, 21,194,236, 62,169, 37, 27, 63, 35,211,232, 62,140,249, 27, 63,115,186,236, 62, 0, 0,128, 63, 0, 0,128, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 8,116,214, 62,102, 12,236, 62,206, 27,216, 62, 22, 37,232, 62, 16,130,220, 62,
+ 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,100,243, 24, 63, 5,123,231, 62,
+169, 37, 27, 63, 35,211,232, 62,138,242, 24, 63, 21,194,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,112, 0, 16,130,220, 62, 6, 20,236, 62,206, 27,216, 62, 22, 37,232, 62, 90,128,220, 62,248,204,230, 62, 0, 0,128, 63,
+ 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,138,242, 24, 63, 21,194,236, 62, 88, 33, 23, 63, 69, 47,233, 62,
+100,243, 24, 63, 5,123,231, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 90,128,220, 62,
+248,204,230, 62,112, 36,224, 62, 58,129,232, 62, 16,130,220, 62, 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,112, 0,138,242, 24, 63, 21,194,236, 62, 13, 89, 22, 63,247,196,236, 62, 88, 33, 23, 63, 69, 47,233, 62,
+ 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0,112, 36,224, 62, 58,129,232, 62, 8,181,225, 62,
+234, 22,236, 62, 16,130,220, 62, 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,
+138,242, 24, 63, 21,194,236, 62,157, 38, 23, 63,225,173,240, 62, 13, 89, 22, 63,247,196,236, 62, 0, 0,128, 63, 0, 0,128, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 8,181,225, 62,234, 22,236, 62,234, 25,224, 62,214,255,239, 62, 16,130,220, 62,
+ 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,138,242, 24, 63, 21,194,236, 62,
+ 6,248, 24, 63,185, 91,242, 62,157, 38, 23, 63,225,173,240, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,112, 0,234, 25,224, 62,214,255,239, 62, 22,119,220, 62,174,173,241, 62, 16,130,220, 62, 6, 20,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,138,242, 24, 63, 21,194,236, 62, 42, 39, 27, 63, 57, 1,241, 62,
+ 6,248, 24, 63,185, 91,242, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 22,119,220, 62,
+174,173,241, 62,206, 24,216, 62, 46, 83,240, 62, 16,130,220, 62, 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3,
+ 61, 0, 5, 0, 0, 0,112, 0,138,242, 24, 63, 21,194,236, 62,140,249, 27, 63,115,186,236, 62, 42, 39, 27, 63, 57, 1,241, 62,
+ 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0,206, 24,216, 62, 46, 83,240, 62, 8,116,214, 62,
+102, 12,236, 62, 16,130,220, 62, 6, 20,236, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 61, 0, 5, 0, 0, 0,112, 0,
+174,254, 16, 63, 94, 45, 34, 62, 79,190, 13, 63,160,193, 46, 62,220,199, 3, 63, 89,219, 24, 62,219,199, 3, 63, 18, 28,229, 61,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,220,199, 3, 63, 89,219, 24, 62, 14,150,243, 62,204, 79, 47, 62,140,248,236, 62,
+182,202, 34, 62,219,199, 3, 63, 18, 28,229, 61,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,184,152, 21, 63,182, 47, 53, 62,
+250,104, 16, 63, 16,113, 55, 62, 79,190, 13, 63,160,193, 46, 62,174,254, 16, 63, 94, 45, 34, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,128, 0, 14,150,243, 62,204, 79, 47, 62,200, 68,238, 62, 76, 62, 56, 62,183,207,227, 62,250, 75, 54, 62,140,248,236, 62,
+182,202, 34, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,137, 57, 22, 63, 81, 93, 61, 62,206,186, 16, 63, 85,129, 72, 62,
+250,104, 16, 63, 16,113, 55, 62,184,152, 21, 63,182, 47, 53, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,200, 68,238, 62,
+ 76, 62, 56, 62,192,187,237, 62,194,118, 73, 62,122,152,226, 62,190,166, 62, 62,183,207,227, 62,250, 75, 54, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,250,249, 22, 63,160,251, 88, 62,222, 32, 16, 63, 34,106, 93, 62,206,186, 16, 63, 85,129, 72, 62,
+137, 57, 22, 63, 81, 93, 61, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,192,187,237, 62,194,118, 73, 62, 21, 19,239, 62,
+121,110, 94, 62, 90, 83,225, 62, 21,153, 90, 62,122,152,226, 62,190,166, 62, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 20, 81, 25, 63, 17, 56,132, 62,206,243, 15, 63,182,207,136, 62,222, 32, 16, 63, 34,106, 93, 62,250,249, 22, 63,160,251, 88, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 21, 19,239, 62,121,110, 94, 62, 92,193,239, 62,113, 61,137, 62, 54, 42,221, 62,
+209, 25,133, 62, 90, 83,225, 62, 21,153, 90, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,111,239, 27, 63,159, 77,166, 62,
+ 91, 94, 37, 63,107,120,187, 62, 66, 21, 30, 63,178,139,200, 62,158,237, 12, 63, 38,241,187, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,139,125,211, 62,170,171,200, 62,156, 28,197, 62,166,130,187, 62,115, 21,216, 62, 14,177,166, 62, 15,175,245, 62,
+188, 14,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 91, 94, 37, 63,107,120,187, 62, 87, 57, 43, 63,222, 58,206, 62,
+ 24,163, 39, 63,174, 95,216, 62, 66, 21, 30, 63,178,139,200, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 98,194,191, 62,
+ 42, 94,216, 62,130,207,184, 62, 42, 27,206, 62,156, 28,197, 62,166,130,187, 62,139,125,211, 62,170,171,200, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 87, 57, 43, 63,222, 58,206, 62, 38,229, 50, 63,169, 32,226, 62,177, 79, 43, 63,202,194,231, 62,
+ 24,163, 39, 63,174, 95,216, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 60,201,183, 62, 82,218,231, 62,196, 39,168, 62,
+206, 11,226, 62,130,207,184, 62, 42, 27,206, 62, 98,194,191, 62, 42, 94,216, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 38,229, 50, 63,169, 32,226, 62, 62,134, 48, 63, 37,107,249, 62,154,190, 43, 63,192, 0,249, 62,177, 79, 43, 63,202,194,231, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,138,190,182, 62, 35, 49,249, 62,172,229,172, 62,116,127,249, 62,196, 39,168, 62,
+206, 11,226, 62, 60,201,183, 62, 82,218,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 62,134, 48, 63, 37,107,249, 62,
+238, 88, 46, 63,146,223, 2, 63,123,207, 40, 63,218,175,254, 62,154,190, 43, 63,192, 0,249, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 2,184,188, 62,140, 0,255, 62,173, 87,177, 62,102, 9, 3, 63,172,229,172, 62,116,127,249, 62,138,190,182, 62,
+ 35, 49,249, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,238, 88, 46, 63,146,223, 2, 63,220,158, 34, 63,175, 23, 10, 63,
+126, 77, 30, 63,156, 88, 5, 63,123,207, 40, 63,218,175,254, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 89, 65,210, 62,
+ 56,158, 5, 63,124,109,201, 62, 72,121, 10, 63,173, 87,177, 62,102, 9, 3, 63, 2,184,188, 62,140, 0,255, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,220,158, 34, 63,175, 23, 10, 63, 28,105, 26, 63,242,194, 11, 63,244,120, 25, 63, 78,242, 7, 63,
+126, 77, 30, 63,156, 88, 5, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 0, 39,220, 62,252, 58, 8, 63,220, 73,218, 62,
+169, 31, 12, 63,124,109,201, 62, 72,121, 10, 63, 89, 65,210, 62, 56,158, 5, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 28,105, 26, 63,242,194, 11, 63,173,244, 22, 63,236,215, 11, 63,202, 47, 22, 63,156, 60, 8, 63,244,120, 25, 63, 78,242, 7, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 11,221,226, 62, 90,125, 8, 63,220, 89,225, 62, 77, 42, 12, 63,220, 73,218, 62,
+169, 31, 12, 63, 0, 39,220, 62,252, 58, 8, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,173,244, 22, 63,236,215, 11, 63,
+ 67,169, 11, 63, 18,197, 11, 63,106,252, 12, 63,180,173, 3, 63,202, 47, 22, 63,156, 60, 8, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 35,114,245, 62,233,196, 3, 63, 55, 72,248, 62, 91,232, 11, 63,220, 89,225, 62, 77, 42, 12, 63, 11,221,226, 62,
+ 90,125, 8, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 67,169, 11, 63, 18,197, 11, 63,148,232, 3, 63,164, 17, 11, 63,
+162,220, 3, 63, 45, 88, 0, 63,106,252, 12, 63,180,173, 3, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,162,220, 3, 63,
+ 45, 88, 0, 63,148,232, 3, 63,164, 17, 11, 63, 55, 72,248, 62, 91,232, 11, 63, 35,114,245, 62,233,196, 3, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,103, 59, 17, 63,120,195,255, 62,240, 81, 22, 63,114, 70, 1, 63,202, 47, 22, 63,156, 60, 8, 63,
+106,252, 12, 63,180,173, 3, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 11,221,226, 62, 90,125, 8, 63,106,128,226, 62,
+198,111, 1, 63,209,213,236, 62, 4,250,255, 62, 35,114,245, 62,233,196, 3, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+240, 81, 22, 63,114, 70, 1, 63,151,182, 25, 63,130, 9, 1, 63,244,120, 25, 63, 78,242, 7, 63,202, 47, 22, 63,156, 60, 8, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 0, 39,220, 62,252, 58, 8, 63,213,150,219, 62, 50, 55, 1, 63,106,128,226, 62,
+198,111, 1, 63, 11,221,226, 62, 90,125, 8, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 96, 49, 30, 63,121,229,254, 62,
+126, 77, 30, 63,156, 88, 5, 63,244,120, 25, 63, 78,242, 7, 63,151,182, 25, 63,130, 9, 1, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 0, 39,220, 62,252, 58, 8, 63, 89, 65,210, 62, 56,158, 5, 63,176,116,210, 62,227, 62,255, 62,213,150,219, 62,
+ 50, 55, 1, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 25,113, 37, 63, 35,157,247, 62,123,207, 40, 63,218,175,254, 62,
+126, 77, 30, 63,156, 88, 5, 63, 96, 49, 30, 63,121,229,254, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 89, 65,210, 62,
+ 56,158, 5, 63, 2,184,188, 62,140, 0,255, 62,189,165,195, 62,139,232,247, 62,176,116,210, 62,227, 62,255, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 92, 62, 39, 63,121, 75,240, 62,154,190, 43, 63,192, 0,249, 62,123,207, 40, 63,218,175,254, 62,
+ 25,113, 37, 63, 35,157,247, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 2,184,188, 62,140, 0,255, 62,138,190,182, 62,
+ 35, 49,249, 62,222, 10,192, 62,163,128,240, 62,189,165,195, 62,139,232,247, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+140,149, 38, 63, 38, 95,229, 62,177, 79, 43, 63,202,194,231, 62,154,190, 43, 63,192, 0,249, 62, 92, 62, 39, 63,121, 75,240, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,138,190,182, 62, 35, 49,249, 62, 60,201,183, 62, 82,218,231, 62,168,140,193, 62,
+ 94,129,229, 62,222, 10,192, 62,163,128,240, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 14,120, 33, 63,166,238,214, 62,
+ 24,163, 39, 63,174, 95,216, 62,177, 79, 43, 63,202,194,231, 62,140,149, 38, 63, 38, 95,229, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 60,201,183, 62, 82,218,231, 62, 98,194,191, 62, 42, 94,216, 62,168, 75,204, 62, 62, 7,215, 62,168,140,193, 62,
+ 94,129,229, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,165,178, 27, 63,128, 17,208, 62, 66, 21, 30, 63,178,139,200, 62,
+ 24,163, 39, 63,174, 95,216, 62, 14,120, 33, 63,166,238,214, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 98,194,191, 62,
+ 42, 94,216, 62,139,125,211, 62,170,171,200, 62, 6, 24,216, 62,128, 57,208, 62,168, 75,204, 62, 62, 7,215, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 15, 97, 17, 63,220, 34,214, 62,158,237, 12, 63, 38,241,187, 62, 66, 21, 30, 63,178,139,200, 62,
+165,178, 27, 63,128, 17,208, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,139,125,211, 62,170,171,200, 62, 15,175,245, 62,
+188, 14,188, 62,217,200,236, 62,134, 49,214, 62, 6, 24,216, 62,128, 57,208, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 15, 97, 17, 63,220, 34,214, 62,149,244, 14, 63, 4, 42,221, 62,147,230, 3, 63, 78, 47,208, 62,158,237, 12, 63, 38,241,187, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,147,230, 3, 63, 78, 47,208, 62,141,144,241, 62,244, 52,221, 62,217,200,236, 62,
+134, 49,214, 62, 15,175,245, 62,188, 14,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,103, 59, 17, 63,120,195,255, 62,
+106,252, 12, 63,180,173, 3, 63,162,220, 3, 63, 45, 88, 0, 63, 71, 25, 13, 63,116,163,243, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,162,220, 3, 63, 45, 88, 0, 63, 35,114,245, 62,233,196, 3, 63,209,213,236, 62, 4,250,255, 62, 0, 45,245, 62,
+206,185,243, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 71, 25, 13, 63,116,163,243, 62,162,220, 3, 63, 45, 88, 0, 63,
+215,220, 3, 63,148,189,231, 62, 64, 2, 13, 63, 52,215,230, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,215,220, 3, 63,
+148,189,231, 62,162,220, 3, 63, 45, 88, 0, 63, 0, 45,245, 62,206,185,243, 62,219,100,245, 62,184,230,230, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,147,230, 3, 63, 78, 47,208, 62,149,244, 14, 63, 4, 42,221, 62, 64, 2, 13, 63, 52,215,230, 62,
+215,220, 3, 63,148,189,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,219,100,245, 62,184,230,230, 62,141,144,241, 62,
+244, 52,221, 62,147,230, 3, 63, 78, 47,208, 62,215,220, 3, 63,148,189,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+250, 61, 7, 63,148, 31, 54, 62,193,202, 3, 63,214,174, 49, 62,220,199, 3, 63, 89,219, 24, 62, 79,190, 13, 63,160,193, 46, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,220,199, 3, 63, 89,219, 24, 62,193,202, 3, 63,214,174, 49, 62,175, 87, 0, 63,
+251, 90, 54, 62, 14,150,243, 62,204, 79, 47, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 68,214, 9, 63,246,237, 66, 62,
+250, 61, 7, 63,148, 31, 54, 62, 79,190, 13, 63,160,193, 46, 62,250,104, 16, 63, 16,113, 55, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 14,150,243, 62,204, 79, 47, 62,175, 87, 0, 63,251, 90, 54, 62,104,137,251, 62,179, 92, 67, 62,200, 68,238, 62,
+ 76, 62, 56, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,237,221, 8, 63,218, 90, 91, 62, 68,214, 9, 63,246,237, 66, 62,
+250,104, 16, 63, 16,113, 55, 62,206,186, 16, 63, 85,129, 72, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,200, 68,238, 62,
+ 76, 62, 56, 62,104,137,251, 62,179, 92, 67, 62, 39,153,253, 62, 27,195, 91, 62,192,187,237, 62,194,118, 73, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,206,243, 15, 63,182,207,136, 62, 77, 32, 8, 63, 10, 39,139, 62, 22,117, 9, 63,146,203, 97, 62,
+222, 32, 16, 63, 34,106, 93, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,192,110,252, 62, 79, 68, 98, 62,219, 89,255, 62,
+116, 79,139, 62, 92,193,239, 62,113, 61,137, 62, 21, 19,239, 62,121,110, 94, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+237,221, 8, 63,218, 90, 91, 62,206,186, 16, 63, 85,129, 72, 62,222, 32, 16, 63, 34,106, 93, 62, 22,117, 9, 63,146,203, 97, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 21, 19,239, 62,121,110, 94, 62,192,187,237, 62,194,118, 73, 62, 39,153,253, 62,
+ 27,195, 91, 62,192,110,252, 62, 79, 68, 98, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,119,125, 9, 63, 7,112,158, 62,
+ 70,233, 3, 63, 88, 27,154, 62,235,229, 3, 63, 97,108,139, 62, 77, 32, 8, 63, 10, 39,139, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,235,229, 3, 63, 97,108,139, 62, 70,233, 3, 63, 88, 27,154, 62,165,179,252, 62,163,140,158, 62,219, 89,255, 62,
+116, 79,139, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 22,117, 9, 63,146,203, 97, 62, 77, 32, 8, 63, 10, 39,139, 62,
+235,229, 3, 63, 97,108,139, 62,246,215, 3, 63,143, 56,101, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,235,229, 3, 63,
+ 97,108,139, 62,219, 89,255, 62,116, 79,139, 62,192,110,252, 62, 79, 68, 98, 62,246,215, 3, 63,143, 56,101, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,147,210, 3, 63,221, 95, 86, 62,237,221, 8, 63,218, 90, 91, 62, 22,117, 9, 63,146,203, 97, 62,
+246,215, 3, 63,143, 56,101, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,192,110,252, 62, 79, 68, 98, 62, 39,153,253, 62,
+ 27,195, 91, 62,147,210, 3, 63,221, 95, 86, 62,246,215, 3, 63,143, 56,101, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 5, 54, 12, 63,188,183,167, 62,250, 61, 9, 63,252,214,168, 62,152,143, 8, 63, 45,107,163, 62,119,125, 9, 63, 7,112,158, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,100,136,254, 62, 38,123,163, 62,110, 39,253, 62,103,224,168, 62, 98, 68,247, 62,
+146,206,167, 62,165,179,252, 62,163,140,158, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,135,196, 10, 63, 52,208,178, 62,
+ 25,233, 8, 63,116,110,175, 62,250, 61, 9, 63,252,214,168, 62, 5, 54, 12, 63,188,183,167, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,110, 39,253, 62,103,224,168, 62,102,195,253, 62,184,102,175, 62, 98, 14,250, 62,149,202,178, 62, 98, 68,247, 62,
+146,206,167, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 69, 17, 4, 63,105,176,182, 62, 69,138, 6, 63, 80,180,177, 62,
+ 25,233, 8, 63,116,110,175, 62,135,196, 10, 63, 52,208,178, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,102,195,253, 62,
+184,102,175, 62, 14, 49, 1, 63, 62,150,177, 62, 69, 17, 4, 63,105,176,182, 62, 98, 14,250, 62,149,202,178, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,209,124, 3, 63, 70, 0,177, 62, 11,232, 3, 63,140, 4,174, 62, 69,138, 6, 63, 80,180,177, 62,
+ 69, 17, 4, 63,105,176,182, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 14, 49, 1, 63, 62,150,177, 62, 11,232, 3, 63,
+140, 4,174, 62,209,124, 3, 63, 70, 0,177, 62, 69, 17, 4, 63,105,176,182, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 70,233, 3, 63, 88, 27,154, 62,119,125, 9, 63, 7,112,158, 62,152,143, 8, 63, 45,107,163, 62,212,232, 3, 63, 58,152,158, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,100,136,254, 62, 38,123,163, 62,165,179,252, 62,163,140,158, 62, 70,233, 3, 63,
+ 88, 27,154, 62,212,232, 3, 63, 58,152,158, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,212,232, 3, 63, 58,152,158, 62,
+152,143, 8, 63, 45,107,163, 62,121, 91, 7, 63,134, 51,166, 62,205,231, 3, 63, 58,149,162, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 44,116, 0, 63,255, 56,166, 62,100,136,254, 62, 38,123,163, 62,212,232, 3, 63, 58,152,158, 62,205,231, 3, 63,
+ 58,149,162, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 11,232, 3, 63,140, 4,174, 62,214,233, 3, 63,198,154,170, 62,
+233,110, 6, 63, 94,152,174, 62, 69,138, 6, 63, 80,180,177, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,228, 82, 1, 63,
+ 95,140,174, 62,214,233, 3, 63,198,154,170, 62, 11,232, 3, 63,140, 4,174, 62, 14, 49, 1, 63, 62,150,177, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 69,138, 6, 63, 80,180,177, 62,233,110, 6, 63, 94,152,174, 62, 59,236, 7, 63, 19,123,173, 62,
+ 25,233, 8, 63,116,110,175, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,217,185,255, 62, 92,116,173, 62,228, 82, 1, 63,
+ 95,140,174, 62, 14, 49, 1, 63, 62,150,177, 62,102,195,253, 62,184,102,175, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 25,233, 8, 63,116,110,175, 62, 59,236, 7, 63, 19,123,173, 62, 85,249, 7, 63, 92, 52,169, 62,250, 61, 9, 63,252,214,168, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,160,169,255, 62, 6, 57,169, 62,217,185,255, 62, 92,116,173, 62,102,195,253, 62,
+184,102,175, 62,110, 39,253, 62,103,224,168, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,250, 61, 9, 63,252,214,168, 62,
+ 85,249, 7, 63, 92, 52,169, 62,121, 91, 7, 63,134, 51,166, 62,152,143, 8, 63, 45,107,163, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 44,116, 0, 63,255, 56,166, 62,160,169,255, 62, 6, 57,169, 62,110, 39,253, 62,103,224,168, 62,100,136,254, 62,
+ 38,123,163, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,214,233, 3, 63,198,154,170, 62, 85,249, 7, 63, 92, 52,169, 62,
+ 59,236, 7, 63, 19,123,173, 62,233,110, 6, 63, 94,152,174, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,217,185,255, 62,
+ 92,116,173, 62,160,169,255, 62, 6, 57,169, 62,214,233, 3, 63,198,154,170, 62,228, 82, 1, 63, 95,140,174, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,214,233, 3, 63,198,154,170, 62,205,231, 3, 63, 58,149,162, 62,121, 91, 7, 63,134, 51,166, 62,
+ 85,249, 7, 63, 92, 52,169, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 44,116, 0, 63,255, 56,166, 62,205,231, 3, 63,
+ 58,149,162, 62,214,233, 3, 63,198,154,170, 62,160,169,255, 62, 6, 57,169, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 69, 17, 4, 63,105,176,182, 62,135,196, 10, 63, 52,208,178, 62,158,237, 12, 63, 38,241,187, 62,147,230, 3, 63, 78, 47,208, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 15,175,245, 62,188, 14,188, 62, 98, 14,250, 62,149,202,178, 62, 69, 17, 4, 63,
+105,176,182, 62,147,230, 3, 63, 78, 47,208, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,135,196, 10, 63, 52,208,178, 62,
+ 5, 54, 12, 63,188,183,167, 62,112, 0, 16, 63,254,246,164, 62,158,237, 12, 63, 38,241,187, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,207,187,239, 62, 19, 42,165, 62, 98, 68,247, 62,146,206,167, 62, 98, 14,250, 62,149,202,178, 62, 15,175,245, 62,
+188, 14,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 5, 54, 12, 63,188,183,167, 62,119,125, 9, 63, 7,112,158, 62,
+ 44,250, 15, 63,109, 0,154, 62,112, 0, 16, 63,254,246,164, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 56,205,239, 62,
+ 8, 71,154, 62,165,179,252, 62,163,140,158, 62, 98, 68,247, 62,146,206,167, 62,207,187,239, 62, 19, 42,165, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,119,125, 9, 63, 7,112,158, 62, 77, 32, 8, 63, 10, 39,139, 62,206,243, 15, 63,182,207,136, 62,
+ 44,250, 15, 63,109, 0,154, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 92,193,239, 62,113, 61,137, 62,219, 89,255, 62,
+116, 79,139, 62,165,179,252, 62,163,140,158, 62, 56,205,239, 62, 8, 71,154, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 20, 81, 25, 63, 17, 56,132, 62,208, 46, 27, 63,149, 35,148, 62, 44,250, 15, 63,109, 0,154, 62,206,243, 15, 63,182,207,136, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 56,205,239, 62, 8, 71,154, 62,238,166,217, 62,229,221,148, 62, 54, 42,221, 62,
+209, 25,133, 62, 92,193,239, 62,113, 61,137, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,208, 46, 27, 63,149, 35,148, 62,
+ 36,177, 27, 63,158,151,156, 62,112, 0, 16, 63,254,246,164, 62, 44,250, 15, 63,109, 0,154, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,207,187,239, 62, 19, 42,165, 62, 0,160,216, 62,127, 44,157, 62,238,166,217, 62,229,221,148, 62, 56,205,239, 62,
+ 8, 71,154, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,111,239, 27, 63,159, 77,166, 62,158,237, 12, 63, 38,241,187, 62,
+112, 0, 16, 63,254,246,164, 62, 36,177, 27, 63,158,151,156, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,207,187,239, 62,
+ 19, 42,165, 62, 15,175,245, 62,188, 14,188, 62,115, 21,216, 62, 14,177,166, 62, 0,160,216, 62,127, 44,157, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,237,221, 8, 63,218, 90, 91, 62,147,210, 3, 63,221, 95, 86, 62,129,211, 3, 63,248,168, 83, 62,
+170, 33, 8, 63,254,149, 86, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,129,211, 3, 63,248,168, 83, 62,147,210, 3, 63,
+221, 95, 86, 62, 39,153,253, 62, 27,195, 91, 62, 8, 14,255, 62, 58,232, 86, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 68,214, 9, 63,246,237, 66, 62,237,221, 8, 63,218, 90, 91, 62,170, 33, 8, 63,254,149, 86, 62, 20,180, 8, 63, 94, 29, 69, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 8, 14,255, 62, 58,232, 86, 62, 39,153,253, 62, 27,195, 91, 62,104,137,251, 62,
+179, 92, 67, 62, 19,210,253, 62, 55,114, 69, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,250, 61, 7, 63,148, 31, 54, 62,
+ 68,214, 9, 63,246,237, 66, 62, 20,180, 8, 63, 94, 29, 69, 62,168, 82, 6, 63, 80, 43, 57, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 19,210,253, 62, 55,114, 69, 62,104,137,251, 62,179, 92, 67, 62,175, 87, 0, 63,251, 90, 54, 62, 48, 68, 1, 63,
+166, 84, 57, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,193,202, 3, 63,214,174, 49, 62,250, 61, 7, 63,148, 31, 54, 62,
+168, 82, 6, 63, 80, 43, 57, 62,205,202, 3, 63, 8, 22, 54, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 48, 68, 1, 63,
+166, 84, 57, 62,175, 87, 0, 63,251, 90, 54, 62,193,202, 3, 63,214,174, 49, 62,205,202, 3, 63, 8, 22, 54, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,205,202, 3, 63, 8, 22, 54, 62,168, 82, 6, 63, 80, 43, 57, 62,246, 24, 5, 63, 26,150, 66, 62,
+213,205, 3, 63,220,232, 64, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 29,131, 2, 63, 22,172, 66, 62, 48, 68, 1, 63,
+166, 84, 57, 62,205,202, 3, 63, 8, 22, 54, 62,213,205, 3, 63,220,232, 64, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+168, 82, 6, 63, 80, 43, 57, 62, 20,180, 8, 63, 94, 29, 69, 62, 39, 83, 6, 63,191,114, 70, 62,246, 24, 5, 63, 26,150, 66, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,185, 75, 1, 63,222,160, 70, 62, 19,210,253, 62, 55,114, 69, 62, 48, 68, 1, 63,
+166, 84, 57, 62, 29,131, 2, 63, 22,172, 66, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 20,180, 8, 63, 94, 29, 69, 62,
+170, 33, 8, 63,254,149, 86, 62, 4,111, 6, 63, 40,172, 76, 62, 39, 83, 6, 63,191,114, 70, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,157, 51, 1, 63,158,218, 76, 62, 8, 14,255, 62, 58,232, 86, 62, 19,210,253, 62, 55,114, 69, 62,185, 75, 1, 63,
+222,160, 70, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,170, 33, 8, 63,254,149, 86, 62,129,211, 3, 63,248,168, 83, 62,
+234,208, 3, 63,146, 43, 75, 62, 4,111, 6, 63, 40,172, 76, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,234,208, 3, 63,
+146, 43, 75, 62,129,211, 3, 63,248,168, 83, 62, 8, 14,255, 62, 58,232, 86, 62,157, 51, 1, 63,158,218, 76, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,234,208, 3, 63,146, 43, 75, 62,213,205, 3, 63,220,232, 64, 62,246, 24, 5, 63, 26,150, 66, 62,
+ 4,111, 6, 63, 40,172, 76, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 29,131, 2, 63, 22,172, 66, 62,213,205, 3, 63,
+220,232, 64, 62,234,208, 3, 63,146, 43, 75, 62,157, 51, 1, 63,158,218, 76, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 4,111, 6, 63, 40,172, 76, 62,246, 24, 5, 63, 26,150, 66, 62, 39, 83, 6, 63,191,114, 70, 62, 0, 0,128, 63, 0, 0,128, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,185, 75, 1, 63,222,160, 70, 62, 29,131, 2, 63, 22,172, 66, 62,157, 51, 1, 63,
+158,218, 76, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64, 2, 13, 63, 52,215,230, 62,
+149,244, 14, 63, 4, 42,221, 62, 4,216, 16, 63,160, 24,224, 62,120,200, 15, 63, 84,255,231, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,119,193,237, 62,190, 38,224, 62,141,144,241, 62,244, 52,221, 62,219,100,245, 62,184,230,230, 62, 21,211,239, 62,
+185, 18,232, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 71, 25, 13, 63,116,163,243, 62, 64, 2, 13, 63, 52,215,230, 62,
+120,200, 15, 63, 84,255,231, 62,184,171, 16, 63, 40,133,241, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 21,211,239, 62,
+185, 18,232, 62,219,100,245, 62,184,230,230, 62, 0, 45,245, 62,206,185,243, 62,218,252,237, 62, 62,160,241, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,103, 59, 17, 63,120,195,255, 62, 71, 25, 13, 63,116,163,243, 62,184,171, 16, 63, 40,133,241, 62,
+ 55, 44, 19, 63, 86, 21,250, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,218,252,237, 62, 62,160,241, 62, 0, 45,245, 62,
+206,185,243, 62,209,213,236, 62, 4,250,255, 62,153,228,232, 62,154, 67,250, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+149,244, 14, 63, 4, 42,221, 62, 15, 97, 17, 63,220, 34,214, 62,217, 53, 19, 63, 16,211,218, 62, 4,216, 16, 63,160, 24,224, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 8, 14,233, 62, 66,226,218, 62,217,200,236, 62,134, 49,214, 62,141,144,241, 62,
+244, 52,221, 62,119,193,237, 62,190, 38,224, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 15, 97, 17, 63,220, 34,214, 62,
+165,178, 27, 63,128, 17,208, 62,205,198, 26, 63,124,184,214, 62,217, 53, 19, 63, 16,211,218, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,216,214,217, 62,218,224,214, 62, 6, 24,216, 62,128, 57,208, 62,217,200,236, 62,134, 49,214, 62, 8, 14,233, 62,
+ 66,226,218, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,165,178, 27, 63,128, 17,208, 62, 14,120, 33, 63,166,238,214, 62,
+156,136, 31, 63,194,138,219, 62,205,198, 26, 63,124,184,214, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,254, 30,208, 62,
+204,177,219, 62,168, 75,204, 62, 62, 7,215, 62, 6, 24,216, 62,128, 57,208, 62,216,214,217, 62,218,224,214, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 14,120, 33, 63,166,238,214, 62,140,149, 38, 63, 38, 95,229, 62, 79, 9, 36, 63, 94,224,229, 62,
+156,136, 31, 63,194,138,219, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,148,192,198, 62,182, 11,230, 62,168,140,193, 62,
+ 94,129,229, 62,168, 75,204, 62, 62, 7,215, 62,254, 30,208, 62,204,177,219, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+140,149, 38, 63, 38, 95,229, 62, 92, 62, 39, 63,121, 75,240, 62, 14, 49, 36, 63,253, 88,239, 62, 79, 9, 36, 63, 94,224,229, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 97, 71,198, 62,192,149,239, 62,222, 10,192, 62,163,128,240, 62,168,140,193, 62,
+ 94,129,229, 62,148,192,198, 62,182, 11,230, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 92, 62, 39, 63,121, 75,240, 62,
+ 25,113, 37, 63, 35,157,247, 62,243, 33, 35, 63, 80,143,245, 62, 14, 49, 36, 63,253, 88,239, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 87, 99,200, 62,172,217,245, 62,189,165,195, 62,139,232,247, 62,222, 10,192, 62,163,128,240, 62, 97, 71,198, 62,
+192,149,239, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 25,113, 37, 63, 35,157,247, 62, 96, 49, 30, 63,121,229,254, 62,
+223, 49, 29, 63,199,140,250, 62,243, 33, 35, 63, 80,143,245, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,147,124,212, 62,
+146,215,250, 62,176,116,210, 62,227, 62,255, 62,189,165,195, 62,139,232,247, 62, 87, 99,200, 62,172,217,245, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 96, 49, 30, 63,121,229,254, 62,151,182, 25, 63,130, 9, 1, 63, 50,181, 25, 63,118,111,253, 62,
+223, 49, 29, 63,199,140,250, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 52,151,219, 62, 68,186,253, 62,213,150,219, 62,
+ 50, 55, 1, 63,176,116,210, 62,227, 62,255, 62,147,124,212, 62,146,215,250, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+151,182, 25, 63,130, 9, 1, 63,240, 81, 22, 63,114, 70, 1, 63,241,188, 22, 63, 28,149,253, 62, 50,181, 25, 63,118,111,253, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,212,163,225, 62, 91,215,253, 62,106,128,226, 62,198,111, 1, 63,213,150,219, 62,
+ 50, 55, 1, 63, 52,151,219, 62, 68,186,253, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,240, 81, 22, 63,114, 70, 1, 63,
+103, 59, 17, 63,120,195,255, 62, 55, 44, 19, 63, 86, 21,250, 62,241,188, 22, 63, 28,149,253, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,153,228,232, 62,154, 67,250, 62,209,213,236, 62, 4,250,255, 62,106,128,226, 62,198,111, 1, 63,212,163,225, 62,
+ 91,215,253, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,241,188, 22, 63, 28,149,253, 62, 55, 44, 19, 63, 86, 21,250, 62,
+ 9,165, 20, 63,248, 99,247, 62, 20, 0, 23, 63, 6, 57,251, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,232,232,229, 62,
+ 74,142,247, 62,153,228,232, 62,154, 67,250, 62,212,163,225, 62, 91,215,253, 62,145, 26,225, 62,114,116,251, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 50,181, 25, 63,118,111,253, 62,241,188, 22, 63, 28,149,253, 62, 20, 0, 23, 63, 6, 57,251, 62,
+130,144, 25, 63,128, 7,251, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,145, 26,225, 62,114,116,251, 62,212,163,225, 62,
+ 91,215,253, 62, 52,151,219, 62, 68,186,253, 62,177,225,219, 62, 67, 75,251, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+223, 49, 29, 63,199,140,250, 62, 50,181, 25, 63,118,111,253, 62,130,144, 25, 63,128, 7,251, 62, 80,195, 28, 63, 55,166,248, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,177,225,219, 62, 67, 75,251, 62, 52,151,219, 62, 68,186,253, 62,147,124,212, 62,
+146,215,250, 62,233, 95,213, 62, 20,237,248, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,243, 33, 35, 63, 80,143,245, 62,
+223, 49, 29, 63,199,140,250, 62, 80,195, 28, 63, 55,166,248, 62, 22,164, 33, 63,102, 75,243, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,233, 95,213, 62, 20,237,248, 62,147,124,212, 62,146,215,250, 62, 87, 99,200, 62,172,217,245, 62, 65,114,203, 62,
+159,143,243, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 14, 49, 36, 63,253, 88,239, 62,243, 33, 35, 63, 80,143,245, 62,
+ 22,164, 33, 63,102, 75,243, 62, 30,160, 34, 63,169, 47,238, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 65,114,203, 62,
+159,143,243, 62, 87, 99,200, 62,172,217,245, 62, 97, 71,198, 62,192,149,239, 62,188,128,201, 62,126,110,238, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 79, 9, 36, 63, 94,224,229, 62, 14, 49, 36, 63,253, 88,239, 62, 30,160, 34, 63,169, 47,238, 62,
+131,144, 34, 63,253, 87,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,188,128,201, 62,126,110,238, 62, 97, 71,198, 62,
+192,149,239, 62,148,192,198, 62,182, 11,230, 62,141,190,201, 62,124,140,231, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+156,136, 31, 63,194,138,219, 62, 79, 9, 36, 63, 94,224,229, 62,131,144, 34, 63,253, 87,231, 62, 21,208, 30, 63,174,182,221, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,141,190,201, 62,124,140,231, 62,148,192,198, 62,182, 11,230, 62,254, 30,208, 62,
+204,177,219, 62,168,133,209, 62, 51,221,221, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,205,198, 26, 63,124,184,214, 62,
+156,136, 31, 63,194,138,219, 62, 21,208, 30, 63,174,182,221, 62,128,218, 26, 63, 68,206,217, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,168,133,209, 62, 51,221,221, 62,254, 30,208, 62,204,177,219, 62,216,214,217, 62,218,224,214, 62, 11,157,217, 62,
+ 64,243,217, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,217, 53, 19, 63, 16,211,218, 62,205,198, 26, 63,124,184,214, 62,
+128,218, 26, 63, 68,206,217, 62,103, 53, 20, 63,236, 84,221, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 11,157,217, 62,
+ 64,243,217, 62,216,214,217, 62,218,224,214, 62, 8, 14,233, 62, 66,226,218, 62, 68, 5,231, 62,234,101,221, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 4,216, 16, 63,160, 24,224, 62,217, 53, 19, 63, 16,211,218, 62,103, 53, 20, 63,236, 84,221, 62,
+ 81, 87, 18, 63, 33,175,226, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 68, 5,231, 62,234,101,221, 62, 8, 14,233, 62,
+ 66,226,218, 62,119,193,237, 62,190, 38,224, 62,180,187,234, 62,249,190,226, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 55, 44, 19, 63, 86, 21,250, 62,184,171, 16, 63, 40,133,241, 62, 98, 68, 18, 63,150,197,240, 62, 9,165, 20, 63,248, 99,247, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 35,197,234, 62,215,226,240, 62,218,252,237, 62, 62,160,241, 62,153,228,232, 62,
+154, 67,250, 62,232,232,229, 62, 74,142,247, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,184,171, 16, 63, 40,133,241, 62,
+120,200, 15, 63, 84,255,231, 62,161, 4, 18, 63,138,184,232, 62, 98, 68, 18, 63,150,197,240, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,154, 85,235, 62, 92,206,232, 62, 21,211,239, 62,185, 18,232, 62,218,252,237, 62, 62,160,241, 62, 35,197,234, 62,
+215,226,240, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120,200, 15, 63, 84,255,231, 62, 4,216, 16, 63,160, 24,224, 62,
+ 81, 87, 18, 63, 33,175,226, 62,161, 4, 18, 63,138,184,232, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,180,187,234, 62,
+249,190,226, 62,119,193,237, 62,190, 38,224, 62, 21,211,239, 62,185, 18,232, 62,154, 85,235, 62, 92,206,232, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,148,232, 3, 63,164, 17, 11, 63, 67,169, 11, 63, 18,197, 11, 63,216,120, 13, 63,160, 81, 23, 63,
+147, 15, 4, 63,227,248, 23, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64, 27,245, 62,100,166, 23, 63, 55, 72,248, 62,
+ 91,232, 11, 63,148,232, 3, 63,164, 17, 11, 63,147, 15, 4, 63,227,248, 23, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 67,169, 11, 63, 18,197, 11, 63,173,244, 22, 63,236,215, 11, 63, 94,233, 23, 63,186, 60, 16, 63,216,120, 13, 63,160, 81, 23, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,109,130,223, 62,118,165, 16, 63,220, 89,225, 62, 77, 42, 12, 63, 55, 72,248, 62,
+ 91,232, 11, 63, 64, 27,245, 62,100,166, 23, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,173,244, 22, 63,236,215, 11, 63,
+ 28,105, 26, 63,242,194, 11, 63,220, 56, 28, 63, 66,250, 14, 63, 94,233, 23, 63,186, 60, 16, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,157,161,214, 62,219,110, 15, 63,220, 73,218, 62,169, 31, 12, 63,220, 89,225, 62, 77, 42, 12, 63,109,130,223, 62,
+118,165, 16, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 28,105, 26, 63,242,194, 11, 63,220,158, 34, 63,175, 23, 10, 63,
+109, 44, 39, 63,107,221, 19, 63,220, 56, 28, 63, 66,250, 14, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,156, 26,192, 62,
+ 31,139, 20, 63,124,109,201, 62, 72,121, 10, 63,220, 73,218, 62,169, 31, 12, 63,157,161,214, 62,219,110, 15, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,220,158, 34, 63,175, 23, 10, 63,238, 88, 46, 63,146,223, 2, 63,242, 80, 56, 63, 44,244, 6, 63,
+109, 44, 39, 63,107,221, 19, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0, 61,208,156, 62,204, 16, 7, 63,173, 87,177, 62,
+102, 9, 3, 63,124,109,201, 62, 72,121, 10, 63,156, 26,192, 62, 31,139, 20, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,
+238, 88, 46, 63,146,223, 2, 63, 62,134, 48, 63, 37,107,249, 62,195,173, 54, 63,239,106,252, 62,242, 80, 56, 63, 44,244, 6, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,202, 36,160, 62, 94, 51,252, 62,172,229,172, 62,116,127,249, 62,173, 87,177, 62,
+102, 9, 3, 63, 61,208,156, 62,204, 16, 7, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0, 62,134, 48, 63, 37,107,249, 62,
+ 38,229, 50, 63,169, 32,226, 62,154, 88, 53, 63,240,146,221, 62,195,173, 54, 63,239,106,252, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 64, 0,128,172,162, 62, 17,169,221, 62,196, 39,168, 62,206, 11,226, 62,172,229,172, 62,116,127,249, 62,202, 36,160, 62,
+ 94, 51,252, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0, 38,229, 50, 63,169, 32,226, 62, 87, 57, 43, 63,222, 58,206, 62,
+240,117, 49, 63,164,138,198, 62,154, 88, 53, 63,240,146,221, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,147,137,172, 62,
+148, 19,198, 62,130,207,184, 62, 42, 27,206, 62,196, 39,168, 62,206, 11,226, 62,128,172,162, 62, 17,169,221, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0,128, 0, 87, 57, 43, 63,222, 58,206, 62, 91, 94, 37, 63,107,120,187, 62,156,160, 41, 63, 56,175,182, 62,
+240,117, 49, 63,164,138,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,202,212,188, 62,245,163,182, 62,156, 28,197, 62,
+166,130,187, 62,130,207,184, 62, 42, 27,206, 62,147,137,172, 62,148, 19,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+165,252, 48, 63,133, 33, 85, 62,112, 54, 48, 63, 20, 19, 96, 62,172, 36, 46, 63,208, 7,129, 62,240, 17, 42, 63,129, 84, 97, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 76, 71,181, 62,204,200,131, 62,117,121,175, 62,183,185,106, 62,217, 24,172, 62,
+ 21,237, 92, 62,138, 81,187, 62, 59, 40,103, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,204, 89, 48, 63,134,194, 4, 62,
+165,252, 48, 63,133, 33, 85, 62,240, 17, 42, 63,129, 84, 97, 62,160,125, 37, 63, 50,211, 46, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 16, 0,138, 81,187, 62, 59, 40,103, 62,217, 24,172, 62, 21,237, 92, 62, 94,197,172, 62,109,200, 4, 62, 25,121,195, 62,
+ 46,253, 48, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0, 11, 44, 20, 63, 20, 26,163, 61,204, 89, 48, 63,134,194, 4, 62,
+160,125, 37, 63, 50,211, 46, 62, 40, 92, 24, 63,214,184, 21, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0, 25,121,195, 62,
+ 46,253, 48, 62, 94,197,172, 62,109,200, 4, 62,140,122,230, 62,202,248,161, 61,216, 13,222, 62,222,116, 22, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 32, 0,174,254, 16, 63, 94, 45, 34, 62,219,199, 3, 63, 18, 28,229, 61, 11, 44, 20, 63, 20, 26,163, 61,
+ 40, 92, 24, 63,214,184, 21, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,140,122,230, 62,202,248,161, 61,219,199, 3, 63,
+ 18, 28,229, 61,140,248,236, 62,182,202, 34, 62,216, 13,222, 62,222,116, 22, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,
+184,152, 21, 63,182, 47, 53, 62,174,254, 16, 63, 94, 45, 34, 62, 40, 92, 24, 63,214,184, 21, 62,209, 52, 25, 63, 76,140, 51, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,216, 13,222, 62,222,116, 22, 62,140,248,236, 62,182,202, 34, 62,183,207,227, 62,
+250, 75, 54, 62,229,137,220, 62,185,228, 52, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,137, 57, 22, 63, 81, 93, 61, 62,
+184,152, 21, 63,182, 47, 53, 62,209, 52, 25, 63, 76,140, 51, 62,193,166, 30, 63,114,168, 73, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,229,137,220, 62,185,228, 52, 62,183,207,227, 62,250, 75, 54, 62,122,152,226, 62,190,166, 62, 62, 54,198,209, 62,
+ 18,240, 75, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,250,249, 22, 63,160,251, 88, 62,137, 57, 22, 63, 81, 93, 61, 62,
+193,166, 30, 63,114,168, 73, 62, 75, 0, 36, 63,229, 47,116, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 54,198,209, 62,
+ 18,240, 75, 62,122,152,226, 62,190,166, 62, 62, 90, 83,225, 62, 21,153, 90, 62,211,231,199, 62,216,237,119, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,193,166, 30, 63,114,168, 73, 62,160,125, 37, 63, 50,211, 46, 62,240, 17, 42, 63,129, 84, 97, 62,
+ 75, 0, 36, 63,229, 47,116, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,138, 81,187, 62, 59, 40,103, 62, 25,121,195, 62,
+ 46,253, 48, 62, 54,198,209, 62, 18,240, 75, 62,211,231,199, 62,216,237,119, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+193,166, 30, 63,114,168, 73, 62,209, 52, 25, 63, 76,140, 51, 62, 40, 92, 24, 63,214,184, 21, 62,160,125, 37, 63, 50,211, 46, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,216, 13,222, 62,222,116, 22, 62,229,137,220, 62,185,228, 52, 62, 54,198,209, 62,
+ 18,240, 75, 62, 25,121,195, 62, 46,253, 48, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 37,163, 36, 63,191,168,140, 62,
+ 75, 0, 36, 63,229, 47,116, 62,240, 17, 42, 63,129, 84, 97, 62,172, 36, 46, 63,208, 7,129, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,138, 81,187, 62, 59, 40,103, 62,211,231,199, 62,216,237,119, 62, 6, 64,199, 62,105, 6,142, 62, 76, 71,181, 62,
+204,200,131, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 20, 81, 25, 63, 17, 56,132, 62,250,249, 22, 63,160,251, 88, 62,
+ 75, 0, 36, 63,229, 47,116, 62, 37,163, 36, 63,191,168,140, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,211,231,199, 62,
+216,237,119, 62, 90, 83,225, 62, 21,153, 90, 62, 54, 42,221, 62,209, 25,133, 62, 6, 64,199, 62,105, 6,142, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,208, 46, 27, 63,149, 35,148, 62, 91, 60, 36, 63,221,222,150, 62,222,170, 33, 63, 74,126,158, 62,
+ 36,177, 27, 63,158,151,156, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 72,234,204, 62, 56, 63,159, 62,150,245,199, 62,
+ 85, 15,152, 62,238,166,217, 62,229,221,148, 62, 0,160,216, 62,127, 44,157, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 20, 81, 25, 63, 17, 56,132, 62, 37,163, 36, 63,191,168,140, 62, 91, 60, 36, 63,221,222,150, 62,208, 46, 27, 63,149, 35,148, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,150,245,199, 62, 85, 15,152, 62, 6, 64,199, 62,105, 6,142, 62, 54, 42,221, 62,
+209, 25,133, 62,238,166,217, 62,229,221,148, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,111,239, 27, 63,159, 77,166, 62,
+ 36,177, 27, 63,158,151,156, 62,222,170, 33, 63, 74,126,158, 62,102,212, 31, 63,144,192,164, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 72,234,204, 62, 56, 63,159, 62, 0,160,216, 62,127, 44,157, 62,115, 21,216, 62, 14,177,166, 62, 17,119,208, 62,
+201, 65,165, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,111,239, 27, 63,159, 77,166, 62,102,212, 31, 63,144,192,164, 62,
+156,160, 41, 63, 56,175,182, 62, 91, 94, 37, 63,107,120,187, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,202,212,188, 62,
+245,163,182, 62, 17,119,208, 62,201, 65,165, 62,115, 21,216, 62, 14,177,166, 62,156, 28,197, 62,166,130,187, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,104,119,194, 62,164,189, 82, 63, 23, 73,212, 62,152,239, 90, 63,100,192,205, 62, 46,238, 97, 63,
+ 38, 56,185, 62, 72,154, 91, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,228, 94,141, 62, 86,234,100, 63, 84, 66,150, 62,
+114,154, 94, 63,230, 86,173, 62, 79, 66, 98, 63, 20,143,162, 62, 44,173,106, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,
+ 72,122, 87, 63,216, 8, 62, 62,202,106, 84, 63,137,185,113, 62,226, 77, 72, 63,204, 21,121, 62,158,225, 71, 63,113, 34, 68, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,132, 32,137, 62,181, 65,121, 62,168,179,107, 62,139,127,103, 62,210,147,114, 62,
+212,116, 61, 62,248,125,142, 62, 30, 4, 80, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,158,225, 71, 63,113, 34, 68, 62,
+226, 77, 72, 63,204, 21,121, 62, 8, 7, 51, 63, 5,186,130, 62, 3,166, 49, 63,232, 57, 96, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 18,197,172, 62, 41,112,133, 62,132, 32,137, 62,181, 65,121, 62,248,125,142, 62, 30, 4, 80, 62,121,228,174, 62,
+ 52, 79,109, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 3,166, 49, 63,232, 57, 96, 62, 8, 7, 51, 63, 5,186,130, 62,
+172, 36, 46, 63,208, 7,129, 62,112, 54, 48, 63, 20, 19, 96, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 76, 71,181, 62,
+204,200,131, 62, 18,197,172, 62, 41,112,133, 62,121,228,174, 62, 52, 79,109, 62,117,121,175, 62,183,185,106, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 37,163, 36, 63,191,168,140, 62,172, 36, 46, 63,208, 7,129, 62, 8, 7, 51, 63, 5,186,130, 62,
+ 91, 60, 36, 63,221,222,150, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 18,197,172, 62, 41,112,133, 62, 76, 71,181, 62,
+204,200,131, 62, 6, 64,199, 62,105, 6,142, 62,150,245,199, 62, 85, 15,152, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+154, 88, 53, 63,240,146,221, 62,240,117, 49, 63,164,138,198, 62,224, 19, 69, 63, 24, 68,190, 62, 53, 64, 74, 63,171, 31,224, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,250, 78,134, 62,148,213,186, 62,147,137,172, 62,148, 19,198, 62,128,172,162, 62,
+ 17,169,221, 62,184,112,114, 62,248,169,220, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0, 54, 74,214, 62, 20, 55, 70, 63,
+ 48,130,233, 62,188, 69, 83, 63, 23, 73,212, 62,152,239, 90, 63,104,119,194, 62,164,189, 82, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0, 84, 66,150, 62,114,154, 94, 63, 66, 1,153, 62,245,149, 81, 63, 38, 56,185, 62,102,110, 83, 63,230, 86,173, 62,
+ 79, 66, 98, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,106,242, 66, 63,202, 94, 25, 63,190,100, 70, 63,222,234, 15, 63,
+ 90,189, 77, 63,233, 88, 17, 63, 8,206, 74, 63, 88,118, 27, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 22, 32, 96, 62,
+ 66, 60, 16, 63, 86, 87,125, 62,174, 5, 15, 63, 78,187,132, 62,180, 44, 24, 63, 26, 79,108, 62,124, 1, 26, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 8,206, 74, 63, 88,118, 27, 63, 90,189, 77, 63,233, 88, 17, 63, 72,139, 85, 63,103, 51, 19, 63,
+220,119, 85, 63, 77, 71, 31, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64,199, 64, 62, 26, 40, 18, 63, 22, 32, 96, 62,
+ 66, 60, 16, 63, 26, 79,108, 62,124, 1, 26, 63, 44,191, 67, 62, 90, 89, 30, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+220,119, 85, 63, 77, 71, 31, 63, 72,139, 85, 63,103, 51, 19, 63,228,213,100, 63, 72,156, 20, 63, 18, 82, 96, 63,128,133, 34, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,226, 50, 1, 62,184, 68, 20, 63, 64,199, 64, 62, 26, 40, 18, 63, 44,191, 67, 62,
+ 90, 89, 30, 63,194,204, 24, 62, 32,186, 34, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,242, 80, 56, 63, 44,244, 6, 63,
+195,173, 54, 63,239,106,252, 62,115,205, 60, 63,213,150,253, 62,166, 14, 64, 63, 81, 80, 4, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 16, 0,190, 85,147, 62, 91,176,252, 62,202, 36,160, 62, 94, 51,252, 62, 61,208,156, 62,204, 16, 7, 63,160,121,140, 62,
+ 74,197, 3, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,166, 14, 64, 63, 81, 80, 4, 63,115,205, 60, 63,213,150,253, 62,
+ 68,103, 73, 63,233,248, 0, 63,248, 12, 75, 63, 64,206, 8, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,144, 59,115, 62,
+102,143,255, 62,190, 85,147, 62, 91,176,252, 62,160,121,140, 62, 74,197, 3, 63, 78,135,107, 62, 88,182, 7, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,248, 12, 75, 63, 64,206, 8, 63, 68,103, 73, 63,233,248, 0, 63,239,151, 82, 63, 86,223, 3, 63,
+181,227, 82, 63,189,102, 11, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 82, 17, 77, 62,162, 98, 2, 63,144, 59,115, 62,
+102,143,255, 62, 78,135,107, 62, 88,182, 7, 63,202, 98, 75, 62,108, 43, 10, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+181,227, 82, 63,189,102, 11, 63,239,151, 82, 63, 86,223, 3, 63, 92,224, 91, 63,239,144, 5, 63,161,148, 90, 63,146, 95, 13, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,178, 40, 38, 62, 14,230, 3, 63, 82, 17, 77, 62,162, 98, 2, 63,202, 98, 75, 62,
+108, 43, 10, 63, 10,162, 43, 62, 8, 50, 12, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120, 89,103, 63,105, 76, 2, 63,
+170,179,103, 63,142,105, 12, 63,161,148, 90, 63,146, 95, 13, 63, 92,224, 91, 63,239,144, 5, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 10,162, 43, 62, 8, 50, 12, 63,168, 41,231, 61,158, 83, 11, 63,116,128,234, 61,200, 39, 0, 63,178, 40, 38, 62,
+ 14,230, 3, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,228,213,100, 63, 72,156, 20, 63, 72,139, 85, 63,103, 51, 19, 63,
+161,148, 90, 63,146, 95, 13, 63,170,179,103, 63,142,105, 12, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 10,162, 43, 62,
+ 8, 50, 12, 63, 64,199, 64, 62, 26, 40, 18, 63,226, 50, 1, 62,184, 68, 20, 63,168, 41,231, 61,158, 83, 11, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 72,139, 85, 63,103, 51, 19, 63, 90,189, 77, 63,233, 88, 17, 63,181,227, 82, 63,189,102, 11, 63,
+161,148, 90, 63,146, 95, 13, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,202, 98, 75, 62,108, 43, 10, 63, 22, 32, 96, 62,
+ 66, 60, 16, 63, 64,199, 64, 62, 26, 40, 18, 63, 10,162, 43, 62, 8, 50, 12, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 90,189, 77, 63,233, 88, 17, 63,190,100, 70, 63,222,234, 15, 63,248, 12, 75, 63, 64,206, 8, 63,181,227, 82, 63,189,102, 11, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 78,135,107, 62, 88,182, 7, 63, 86, 87,125, 62,174, 5, 15, 63, 22, 32, 96, 62,
+ 66, 60, 16, 63,202, 98, 75, 62,108, 43, 10, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,190,100, 70, 63,222,234, 15, 63,
+ 82,235, 60, 63, 27, 12, 12, 63,166, 14, 64, 63, 81, 80, 4, 63,248, 12, 75, 63, 64,206, 8, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,160,121,140, 62, 74,197, 3, 63, 78,230,145, 62,148,225, 11, 63, 86, 87,125, 62,174, 5, 15, 63, 78,135,107, 62,
+ 88,182, 7, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 31,118, 57, 63,230, 79, 12, 63,242, 80, 56, 63, 44,244, 6, 63,
+166, 14, 64, 63, 81, 80, 4, 63, 82,235, 60, 63, 27, 12, 12, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,160,121,140, 62,
+ 74,197, 3, 63, 61,208,156, 62,204, 16, 7, 63, 0,199,152, 62, 13,133, 12, 63, 78,230,145, 62,148,225, 11, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 32, 0,195,240, 57, 63, 10,138, 23, 63, 82,235, 60, 63, 27, 12, 12, 63,190,100, 70, 63,222,234, 15, 63,
+106,242, 66, 63,202, 94, 25, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 86, 87,125, 62,174, 5, 15, 63, 78,230,145, 62,
+148,225, 11, 63,247, 7,150, 62, 96, 12, 23, 63, 78,187,132, 62,180, 44, 24, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+216,120, 13, 63,160, 81, 23, 63, 94,233, 23, 63,186, 60, 16, 63,220, 56, 28, 63, 66,250, 14, 63,109, 44, 39, 63,107,221, 19, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,157,161,214, 62,219,110, 15, 63,109,130,223, 62,118,165, 16, 63, 64, 27,245, 62,
+100,166, 23, 63,156, 26,192, 62, 31,139, 20, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,176, 29, 56, 63, 88,206, 20, 63,
+ 31,118, 57, 63,230, 79, 12, 63, 82,235, 60, 63, 27, 12, 12, 63,195,240, 57, 63, 10,138, 23, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 78,230,145, 62,148,225, 11, 63, 0,199,152, 62, 13,133, 12, 63,239,211,153, 62,220,159, 20, 63,247, 7,150, 62,
+ 96, 12, 23, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 48,148, 54, 63,220,206, 22, 63,176, 29, 56, 63, 88,206, 20, 63,
+195,240, 57, 63, 10,138, 23, 63, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,247, 7,150, 62,
+ 96, 12, 23, 63,239,211,153, 62,220,159, 20, 63,108,106,156, 62,146,154, 22, 63, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,195,173, 54, 63,239,106,252, 62,154, 88, 53, 63,240,146,221, 62, 53, 64, 74, 63,171, 31,224, 62,
+115,205, 60, 63,213,150,253, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,184,112,114, 62,248,169,220, 62,128,172,162, 62,
+ 17,169,221, 62,202, 36,160, 62, 94, 51,252, 62,190, 85,147, 62, 91,176,252, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,
+ 53, 64, 74, 63,171, 31,224, 62,217,106, 81, 63, 14,214,232, 62, 68,103, 73, 63,233,248, 0, 63,115,205, 60, 63,213,150,253, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,144, 59,115, 62,102,143,255, 62, 88, 93, 84, 62, 50,105,228, 62,184,112,114, 62,
+248,169,220, 62,190, 85,147, 62, 91,176,252, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,217,106, 81, 63, 14,214,232, 62,
+106,154, 93, 63,226, 26,233, 62,239,151, 82, 63, 86,223, 3, 63, 68,103, 73, 63,233,248, 0, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 82, 17, 77, 62,162, 98, 2, 63,128, 1, 33, 62, 70,210,226, 62, 88, 93, 84, 62, 50,105,228, 62,144, 59,115, 62,
+102,143,255, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120, 89,103, 63,105, 76, 2, 63, 92,224, 91, 63,239,144, 5, 63,
+239,151, 82, 63, 86,223, 3, 63,106,154, 93, 63,226, 26,233, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 82, 17, 77, 62,
+162, 98, 2, 63,178, 40, 38, 62, 14,230, 3, 63,116,128,234, 61,200, 39, 0, 63,128, 1, 33, 62, 70,210,226, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 8, 7, 51, 63, 5,186,130, 62,226, 77, 72, 63,204, 21,121, 62,154,254, 73, 63,178, 82,140, 62,
+ 90,188, 56, 63,103,207,159, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,249,249,130, 62,246,175,137, 62,132, 32,137, 62,
+181, 65,121, 62, 18,197,172, 62, 41,112,133, 62,192, 5,161, 62,228, 40,159, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+224, 19, 69, 63, 24, 68,190, 62, 90,188, 56, 63,103,207,159, 62,154,254, 73, 63,178, 82,140, 62,216,217, 77, 63, 7,228,157, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,249,249,130, 62,246,175,137, 62,192, 5,161, 62,228, 40,159, 62,250, 78,134, 62,
+148,213,186, 62,154,118,111, 62,120,108,152, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,240,117, 49, 63,164,138,198, 62,
+156,160, 41, 63, 56,175,182, 62, 90,188, 56, 63,103,207,159, 62,224, 19, 69, 63, 24, 68,190, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,192, 5,161, 62,228, 40,159, 62,202,212,188, 62,245,163,182, 62,147,137,172, 62,148, 19,198, 62,250, 78,134, 62,
+148,213,186, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,156,160, 41, 63, 56,175,182, 62,222,170, 33, 63, 74,126,158, 62,
+ 91, 60, 36, 63,221,222,150, 62, 90,188, 56, 63,103,207,159, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,150,245,199, 62,
+ 85, 15,152, 62, 72,234,204, 62, 56, 63,159, 62,202,212,188, 62,245,163,182, 62,192, 5,161, 62,228, 40,159, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 91, 60, 36, 63,221,222,150, 62, 8, 7, 51, 63, 5,186,130, 62, 90,188, 56, 63,103,207,159, 62,
+ 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,192, 5,161, 62,228, 40,159, 62, 18,197,172, 62,
+ 41,112,133, 62,150,245,199, 62, 85, 15,152, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+156,160, 41, 63, 56,175,182, 62,102,212, 31, 63,144,192,164, 62,222,170, 33, 63, 74,126,158, 62, 0, 0,128, 63, 0, 0,128, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 72,234,204, 62, 56, 63,159, 62, 17,119,208, 62,201, 65,165, 62,202,212,188, 62,
+245,163,182, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,226, 44,245, 62,129,140, 96, 63,
+ 42,135,227, 62, 58, 2,101, 63,136,168,219, 62, 30,236, 95, 63,135, 30,238, 62,200, 41, 90, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0,216,240,137, 62, 90,226, 93, 63,110,103,122, 62,236,255, 92, 63, 74, 84,120, 62,104, 32, 83, 63, 32,193,138, 62,
+ 16, 3, 83, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 48,130,233, 62,188, 69, 83, 63,135, 30,238, 62,200, 41, 90, 63,
+136,168,219, 62, 30,236, 95, 63, 23, 73,212, 62,152,239, 90, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,216,240,137, 62,
+ 90,226, 93, 63, 32,193,138, 62, 16, 3, 83, 63, 66, 1,153, 62,245,149, 81, 63, 84, 66,150, 62,114,154, 94, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0,240, 0,216,217, 77, 63, 7,228,157, 62,154,254, 73, 63,178, 82,140, 62, 33, 61, 90, 63,195,207,124, 62,
+160,225, 90, 63,110,121,137, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0, 98,207, 81, 62,109, 1,110, 62,249,249,130, 62,
+246,175,137, 62,154,118,111, 62,120,108,152, 62,166,125, 74, 62,252, 30,130, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,
+226, 77, 72, 63,204, 21,121, 62,202,106, 84, 63,137,185,113, 62, 33, 61, 90, 63,195,207,124, 62,154,254, 73, 63,178, 82,140, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 98,207, 81, 62,109, 1,110, 62,168,179,107, 62,139,127,103, 62,132, 32,137, 62,
+181, 65,121, 62,249,249,130, 62,246,175,137, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 23, 73,212, 62,152,239, 90, 63,
+136,168,219, 62, 30,236, 95, 63,100,192,205, 62, 46,238, 97, 63, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,112, 0,228, 94,141, 62, 86,234,100, 63,216,240,137, 62, 90,226, 93, 63, 84, 66,150, 62,114,154, 94, 63, 0, 0,128, 63,
+ 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 31,178,109, 63,224, 68,228, 62, 46,178,102, 63,100,184,232, 62,
+100,251,101, 63,238,198,227, 62, 94,173,107, 63,168,130,225, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 68,209,249, 61,
+ 70,134,219, 62,120,216,242, 61,124, 40,225, 62, 28, 27,177, 61, 42,240,219, 62, 76,131,196, 61,196, 97,216, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 31,178,109, 63,224, 68,228, 62, 94,173,107, 63,168,130,225, 62,144,102,114, 63,198, 23,220, 62,
+ 41, 76,116, 63,139,153,222, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 56,163,120, 61, 58,252,208, 62, 76,131,196, 61,
+196, 97,216, 62, 28, 27,177, 61, 42,240,219, 62,128,183, 73, 61, 84,108,213, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 41, 76,116, 63,139,153,222, 62,144,102,114, 63,198, 23,220, 62, 84, 87,117, 63,221,255,211, 62,183,115,119, 63,140, 49,215, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,144, 29, 55, 61,207,183,194, 62, 56,163,120, 61, 58,252,208, 62,128,183, 73, 61,
+ 84,108,213, 62,224,111,231, 60,100,142,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,183,115,119, 63,140, 49,215, 62,
+ 84, 87,117, 63,221,255,211, 62,150, 20,118, 63, 60,110,196, 62, 49, 12,122, 63,246, 8,197, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 96,197,103, 61, 15,206,170, 62,144, 29, 55, 61,207,183,194, 62,224,111,231, 60,100,142,198, 62,240, 54, 16, 61,
+120, 4,167, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 49, 12,122, 63,246, 8,197, 62,150, 20,118, 63, 60,110,196, 62,
+ 17,155,108, 63,130,201,178, 62, 84,190,110, 63,223, 77,172, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,148,252,246, 61,
+164,116,160, 62, 96,197,103, 61, 15,206,170, 62,240, 54, 16, 61,120, 4,167, 62, 8, 66,246, 61, 28,161,152, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 84,190,110, 63,223, 77,172, 62, 17,155,108, 63,130,201,178, 62, 21,180, 92, 63,202, 95,173, 62,
+151, 5, 90, 63,138, 61,167, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,144,216, 54, 62, 35, 76,163, 62,148,252,246, 61,
+164,116,160, 62, 8, 66,246, 61, 28,161,152, 62,194,251, 66, 62,163,102,158, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 17,155,108, 63,130,201,178, 62,198,132,109, 63,182,157,186, 62, 68, 32, 97, 63,192, 12,178, 62, 21,180, 92, 63,202, 95,173, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 48,185, 36, 62, 16, 7,166, 62, 40, 91,221, 61, 4,194,167, 62,148,252,246, 61,
+164,116,160, 62,144,216, 54, 62, 35, 76,163, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,150, 20,118, 63, 60,110,196, 62,
+ 84,225,115, 63,208, 85,198, 62,198,132,109, 63,182,157,186, 62, 17,155,108, 63,130,201,178, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 40, 91,221, 61, 4,194,167, 62,244,221,134, 61,121,164,175, 62, 96,197,103, 61, 15,206,170, 62,148,252,246, 61,
+164,116,160, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 84, 87,117, 63,221,255,211, 62,222, 48,116, 63,169, 8,209, 62,
+ 84,225,115, 63,208, 85,198, 62,150, 20,118, 63, 60,110,196, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,244,221,134, 61,
+121,164,175, 62,160,108, 93, 61, 17,207,190, 62,144, 29, 55, 61,207,183,194, 62, 96,197,103, 61, 15,206,170, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,144,102,114, 63,198, 23,220, 62,174,151,113, 63, 26,229,214, 62,222, 48,116, 63,169, 8,209, 62,
+ 84, 87,117, 63,221,255,211, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,160,108, 93, 61, 17,207,190, 62, 12,155,135, 61,
+166, 39,201, 62, 56,163,120, 61, 58,252,208, 62,144, 29, 55, 61,207,183,194, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 94,173,107, 63,168,130,225, 62,228,239,107, 63, 62, 59,218, 62,174,151,113, 63, 26,229,214, 62,144,102,114, 63,198, 23,220, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 12,155,135, 61,166, 39,201, 62,128, 47,195, 61, 6, 11,207, 62, 76,131,196, 61,
+196, 97,216, 62, 56,163,120, 61, 58,252,208, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 94,173,107, 63,168,130,225, 62,
+100,251,101, 63,238,198,227, 62, 71,205,102, 63,132, 94,219, 62,228,239,107, 63, 62, 59,218, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,192,157,244, 61,157,137,209, 62, 68,209,249, 61, 70,134,219, 62, 76,131,196, 61,196, 97,216, 62,128, 47,195, 61,
+ 6, 11,207, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,224, 19, 69, 63, 24, 68,190, 62,216,217, 77, 63, 7,228,157, 62,
+236, 35, 85, 63,164,201,181, 62, 56, 92, 78, 63,177,114,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 32, 0,122, 91, 80, 62,
+ 72, 18,174, 62,154,118,111, 62,120,108,152, 62,250, 78,134, 62,148,213,186, 62,162,163,104, 62,150,180,182, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 32, 0,216,217, 77, 63, 7,228,157, 62,151, 5, 90, 63,138, 61,167, 62, 21,180, 92, 63,202, 95,173, 62,
+236, 35, 85, 63,164,201,181, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,144,216, 54, 62, 35, 76,163, 62,194,251, 66, 62,
+163,102,158, 62,154,118,111, 62,120,108,152, 62,122, 91, 80, 62, 72, 18,174, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,
+ 53, 64, 74, 63,171, 31,224, 62,224, 19, 69, 63, 24, 68,190, 62, 56, 92, 78, 63,177,114,188, 62,217,106, 81, 63, 14,214,232, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,162,163,104, 62,150,180,182, 62,250, 78,134, 62,148,213,186, 62,184,112,114, 62,
+248,169,220, 62, 88, 93, 84, 62, 50,105,228, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,106,154, 93, 63,226, 26,233, 62,
+196,229, 94, 63,128,195,224, 62,100,251,101, 63,238,198,227, 62, 46,178,102, 63,100,184,232, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 68,209,249, 61, 70,134,219, 62,108,187, 28, 62, 48, 86,217, 62,128, 1, 33, 62, 70,210,226, 62,120,216,242, 61,
+124, 40,225, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 21,180, 92, 63,202, 95,173, 62, 68, 32, 97, 63,192, 12,178, 62,
+ 9,215, 94, 63, 4, 54,186, 62,236, 35, 85, 63,164,201,181, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 60,122, 41, 62,
+ 16, 58,175, 62, 48,185, 36, 62, 16, 7,166, 62,144,216, 54, 62, 35, 76,163, 62,122, 91, 80, 62, 72, 18,174, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,230, 78, 95, 63, 4,233,189, 62, 32,188, 86, 63, 44, 62,190, 62,236, 35, 85, 63,164,201,181, 62,
+ 9,215, 94, 63, 4, 54,186, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,122, 91, 80, 62, 72, 18,174, 62, 78,118, 71, 62,
+ 27, 49,182, 62, 52,225, 37, 62, 40, 12,179, 62, 60,122, 41, 62, 16, 58,175, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 70,166, 92, 63, 0,166,197, 62, 32,188, 86, 63, 44, 62,190, 62,230, 78, 95, 63, 4,233,189, 62,226, 13, 95, 63, 37,152,194, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 52,225, 37, 62, 40, 12,179, 62, 78,118, 71, 62, 27, 49,182, 62,142,143, 45, 62,
+237, 37,188, 62,106,230, 36, 62,222, 27,184, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,248, 90, 95, 63,100,122,207, 62,
+108,249, 90, 63, 58,199,212, 62, 32,188, 86, 63, 44, 62,190, 62, 70,166, 92, 63, 0,166,197, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 78,118, 71, 62, 27, 49,182, 62,110, 56, 48, 62,230, 43,205, 62,174,250, 30, 62, 26, 12,198, 62,142,143, 45, 62,
+237, 37,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,196,229, 94, 63,128,195,224, 62,108,249, 90, 63, 58,199,212, 62,
+248, 90, 95, 63,100,122,207, 62, 92,104, 98, 63,197,136,215, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,174,250, 30, 62,
+ 26, 12,198, 62,110, 56, 48, 62,230, 43,205, 62,108,187, 28, 62, 48, 86,217, 62,212, 59, 15, 62,224, 50,206, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,100,251,101, 63,238,198,227, 62,196,229, 94, 63,128,195,224, 62, 92,104, 98, 63,197,136,215, 62,
+ 71,205,102, 63,132, 94,219, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,212, 59, 15, 62,224, 50,206, 62,108,187, 28, 62,
+ 48, 86,217, 62, 68,209,249, 61, 70,134,219, 62,192,157,244, 61,157,137,209, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+217,106, 81, 63, 14,214,232, 62,108,249, 90, 63, 58,199,212, 62,196,229, 94, 63,128,195,224, 62,106,154, 93, 63,226, 26,233, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,108,187, 28, 62, 48, 86,217, 62,110, 56, 48, 62,230, 43,205, 62, 88, 93, 84, 62,
+ 50,105,228, 62,128, 1, 33, 62, 70,210,226, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,217,106, 81, 63, 14,214,232, 62,
+ 56, 92, 78, 63,177,114,188, 62, 32,188, 86, 63, 44, 62,190, 62,108,249, 90, 63, 58,199,212, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 78,118, 71, 62, 27, 49,182, 62,162,163,104, 62,150,180,182, 62, 88, 93, 84, 62, 50,105,228, 62,110, 56, 48, 62,
+230, 43,205, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 56, 92, 78, 63,177,114,188, 62,236, 35, 85, 63,164,201,181, 62,
+ 32,188, 86, 63, 44, 62,190, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 78,118, 71, 62,
+ 27, 49,182, 62,122, 91, 80, 62, 72, 18,174, 62,162,163,104, 62,150,180,182, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 71,205,102, 63,132, 94,219, 62, 92,104, 98, 63,197,136,215, 62,182,109,100, 63,149,255,210, 62,
+ 54, 86,104, 63,209,241,214, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,160,107, 7, 62, 34,103,200, 62,212, 59, 15, 62,
+224, 50,206, 62,192,157,244, 61,157,137,209, 62, 8, 2,232, 61, 20,214,203, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 92,104, 98, 63,197,136,215, 62,248, 90, 95, 63,100,122,207, 62,112,206, 97, 63, 10,202,204, 62,182,109,100, 63,149,255,210, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64, 68, 21, 62,107, 55,194, 62,174,250, 30, 62, 26, 12,198, 62,212, 59, 15, 62,
+224, 50,206, 62,160,107, 7, 62, 34,103,200, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,248, 90, 95, 63,100,122,207, 62,
+ 70,166, 92, 63, 0,166,197, 62, 82,241, 94, 63, 40,103,198, 62,112,206, 97, 63, 10,202,204, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 20,225, 35, 62, 39, 50,188, 62,142,143, 45, 62,237, 37,188, 62,174,250, 30, 62, 26, 12,198, 62, 64, 68, 21, 62,
+107, 55,194, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 70,166, 92, 63, 0,166,197, 62,226, 13, 95, 63, 37,152,194, 62,
+118, 1, 97, 63, 47,226,195, 62, 82,241, 94, 63, 40,103,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 12, 43, 28, 62,
+186,177,184, 62,106,230, 36, 62,222, 27,184, 62,142,143, 45, 62,237, 37,188, 62, 20,225, 35, 62, 39, 50,188, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,226, 13, 95, 63, 37,152,194, 62,230, 78, 95, 63, 4,233,189, 62, 51,113, 97, 63, 92,151,189, 62,
+118, 1, 97, 63, 47,226,195, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,104, 67, 29, 62, 58,199,177, 62, 52,225, 37, 62,
+ 40, 12,179, 62,106,230, 36, 62,222, 27,184, 62, 12, 43, 28, 62,186,177,184, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+230, 78, 95, 63, 4,233,189, 62, 9,215, 94, 63, 4, 54,186, 62, 96, 69, 96, 63,152,133,187, 62, 51,113, 97, 63, 92,151,189, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,140, 14, 35, 62, 33, 19,176, 62, 60,122, 41, 62, 16, 58,175, 62, 52,225, 37, 62,
+ 40, 12,179, 62,104, 67, 29, 62, 58,199,177, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 9,215, 94, 63, 4, 54,186, 62,
+ 68, 32, 97, 63,192, 12,178, 62,112, 91, 98, 63,149,128,182, 62, 96, 69, 96, 63,152,133,187, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,228,107, 29, 62, 95,230,169, 62, 48,185, 36, 62, 16, 7,166, 62, 60,122, 41, 62, 16, 58,175, 62,140, 14, 35, 62,
+ 33, 19,176, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,228,239,107, 63, 62, 59,218, 62, 71,205,102, 63,132, 94,219, 62,
+ 54, 86,104, 63,209,241,214, 62, 34, 27,109, 63,155,254,214, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 8, 2,232, 61,
+ 20,214,203, 62,192,157,244, 61,157,137,209, 62,128, 47,195, 61, 6, 11,207, 62, 36,174,184, 61,216,130,202, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,174,151,113, 63, 26,229,214, 62,228,239,107, 63, 62, 59,218, 62, 34, 27,109, 63,155,254,214, 62,
+ 69,134,113, 63,156, 82,212, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 36,174,184, 61,216,130,202, 62,128, 47,195, 61,
+ 6, 11,207, 62, 12,155,135, 61,166, 39,201, 62, 60,114,138, 61, 28, 61,197, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+222, 48,116, 63,169, 8,209, 62,174,151,113, 63, 26,229,214, 62, 69,134,113, 63,156, 82,212, 62, 42,143,114, 63, 24,168,207, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 60,114,138, 61, 28, 61,197, 62, 12,155,135, 61,166, 39,201, 62,160,108, 93, 61,
+ 17,207,190, 62,184, 85,132, 61, 22,211,189, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 84,225,115, 63,208, 85,198, 62,
+222, 48,116, 63,169, 8,209, 62, 42,143,114, 63, 24,168,207, 62,203,125,114, 63, 96,114,200, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,184, 85,132, 61, 22,211,189, 62,160,108, 93, 61, 17,207,190, 62,244,221,134, 61,121,164,175, 62, 16,152,145, 61,
+ 84,214,179, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,198,132,109, 63,182,157,186, 62, 84,225,115, 63,208, 85,198, 62,
+203,125,114, 63, 96,114,200, 62,177,192,109, 63,152,240,190, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 16,152,145, 61,
+ 84,214,179, 62,244,221,134, 61,121,164,175, 62, 40, 91,221, 61, 4,194,167, 62, 64,226,208, 61,232, 58,172, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 68, 32, 97, 63,192, 12,178, 62,198,132,109, 63,182,157,186, 62,177,192,109, 63,152,240,190, 62,
+112, 91, 98, 63,149,128,182, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64,226,208, 61,232, 58,172, 62, 40, 91,221, 61,
+ 4,194,167, 62, 48,185, 36, 62, 16, 7,166, 62,228,107, 29, 62, 95,230,169, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+118, 1, 97, 63, 47,226,195, 62, 51,113, 97, 63, 92,151,189, 62,215,139,102, 63, 15,109,193, 62, 54, 47,100, 63,186,115,198, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 92,169, 5, 62,168,115,179, 62,104, 67, 29, 62, 58,199,177, 62, 12, 43, 28, 62,
+186,177,184, 62, 50, 97, 13, 62, 50, 42,186, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 54, 47,100, 63,186,115,198, 62,
+215,139,102, 63, 15,109,193, 62,174,241,105, 63,204, 8,200, 62, 71,233,103, 63,178, 42,204, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,228,171,229, 61, 41, 42,185, 62, 92,169, 5, 62,168,115,179, 62, 50, 97, 13, 62, 50, 42,186, 62, 92,248,243, 61,
+ 96, 22,191, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 71,233,103, 63,178, 42,204, 62,174,241,105, 63,204, 8,200, 62,
+ 51, 37,108, 63,249, 3,205, 62, 56,212,106, 63, 96,238,208, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120, 99,202, 61,
+192, 49,190, 62,228,171,229, 61, 41, 42,185, 62, 92,248,243, 61, 96, 22,191, 62,160,209,211, 61,108,159,195, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 56,212,106, 63, 96,238,208, 62, 51, 37,108, 63,249, 3,205, 62, 56, 73,110, 63,186,119,206, 62,
+ 46,191,109, 63, 92, 64,210, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,244,234,179, 61,240,219,190, 62,120, 99,202, 61,
+192, 49,190, 62,160,209,211, 61,108,159,195, 62,196,129,181, 61,204, 14,196, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 34, 27,109, 63,155,254,214, 62, 54, 86,104, 63,209,241,214, 62, 56,212,106, 63, 96,238,208, 62, 46,191,109, 63, 92, 64,210, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,160,209,211, 61,108,159,195, 62, 8, 2,232, 61, 20,214,203, 62, 36,174,184, 61,
+216,130,202, 62,196,129,181, 61,204, 14,196, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,182,109,100, 63,149,255,210, 62,
+ 71,233,103, 63,178, 42,204, 62, 56,212,106, 63, 96,238,208, 62, 54, 86,104, 63,209,241,214, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,160,209,211, 61,108,159,195, 62, 92,248,243, 61, 96, 22,191, 62,160,107, 7, 62, 34,103,200, 62, 8, 2,232, 61,
+ 20,214,203, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,182,109,100, 63,149,255,210, 62,112,206, 97, 63, 10,202,204, 62,
+ 54, 47,100, 63,186,115,198, 62, 71,233,103, 63,178, 42,204, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 50, 97, 13, 62,
+ 50, 42,186, 62, 64, 68, 21, 62,107, 55,194, 62,160,107, 7, 62, 34,103,200, 62, 92,248,243, 61, 96, 22,191, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0,118, 1, 97, 63, 47,226,195, 62, 54, 47,100, 63,186,115,198, 62,112,206, 97, 63, 10,202,204, 62,
+ 82,241, 94, 63, 40,103,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 64, 68, 21, 62,107, 55,194, 62, 50, 97, 13, 62,
+ 50, 42,186, 62, 12, 43, 28, 62,186,177,184, 62, 20,225, 35, 62, 39, 50,188, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 96, 69, 96, 63,152,133,187, 62,112, 91, 98, 63,149,128,182, 62,215,139,102, 63, 15,109,193, 62, 51,113, 97, 63, 92,151,189, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 92,169, 5, 62,168,115,179, 62,228,107, 29, 62, 95,230,169, 62,140, 14, 35, 62,
+ 33, 19,176, 62,104, 67, 29, 62, 58,199,177, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,177,192,109, 63,152,240,190, 62,
+174,241,105, 63,204, 8,200, 62,215,139,102, 63, 15,109,193, 62,112, 91, 98, 63,149,128,182, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 92,169, 5, 62,168,115,179, 62,228,171,229, 61, 41, 42,185, 62, 64,226,208, 61,232, 58,172, 62,228,107, 29, 62,
+ 95,230,169, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,203,125,114, 63, 96,114,200, 62, 51, 37,108, 63,249, 3,205, 62,
+174,241,105, 63,204, 8,200, 62,177,192,109, 63,152,240,190, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,228,171,229, 61,
+ 41, 42,185, 62,120, 99,202, 61,192, 49,190, 62, 16,152,145, 61, 84,214,179, 62, 64,226,208, 61,232, 58,172, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 42,143,114, 63, 24,168,207, 62, 56, 73,110, 63,186,119,206, 62, 51, 37,108, 63,249, 3,205, 62,
+203,125,114, 63, 96,114,200, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120, 99,202, 61,192, 49,190, 62,244,234,179, 61,
+240,219,190, 62,184, 85,132, 61, 22,211,189, 62, 16,152,145, 61, 84,214,179, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+ 69,134,113, 63,156, 82,212, 62, 46,191,109, 63, 92, 64,210, 62, 56, 73,110, 63,186,119,206, 62, 42,143,114, 63, 24,168,207, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,244,234,179, 61,240,219,190, 62,196,129,181, 61,204, 14,196, 62, 60,114,138, 61,
+ 28, 61,197, 62,184, 85,132, 61, 22,211,189, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 34, 27,109, 63,155,254,214, 62,
+ 46,191,109, 63, 92, 64,210, 62, 69,134,113, 63,156, 82,212, 62, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0, 60,114,138, 61, 28, 61,197, 62,196,129,181, 61,204, 14,196, 62, 36,174,184, 61,216,130,202, 62, 0, 0,128, 63,
+ 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 84,190,110, 63,223, 77,172, 62,151, 5, 90, 63,138, 61,167, 62,
+ 22, 25, 96, 63,246,248,149, 62,162,176,122, 63,145,215,161, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0, 64,234, 54, 62,
+146,219,140, 62,194,251, 66, 62,163,102,158, 62, 8, 66,246, 61, 28,161,152, 62,172,241,189, 61, 13,107,132, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0, 0, 0, 49, 12,122, 63,246, 8,197, 62, 84,190,110, 63,223, 77,172, 62,162,176,122, 63,145,215,161, 62,
+188,255,126, 63,115,248,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0,172,241,189, 61, 13,107,132, 62, 8, 66,246, 61,
+ 28,161,152, 62,240, 54, 16, 61,120, 4,167, 62, 0, 8,163, 58, 39, 69,162, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0,
+183,115,119, 63,140, 49,215, 62, 49, 12,122, 63,246, 8,197, 62,188,255,126, 63,115,248,198, 62, 47, 6,122, 63,248,157,216, 62,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 0, 8,163, 58, 39, 69,162, 62,240, 54, 16, 61,120, 4,167, 62,224,111,231, 60,
+100,142,198, 62,224,248, 14, 60, 70,141,198, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0, 41, 76,116, 63,139,153,222, 62,
+183,115,119, 63,140, 49,215, 62, 47, 6,122, 63,248,157,216, 62,134, 98,119, 63,204, 37,225, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 0, 0,224,248, 14, 60, 70,141,198, 62,224,111,231, 60,100,142,198, 62,128,183, 73, 61, 84,108,213, 62, 80,210,229, 60,
+ 32,239,218, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0, 31,178,109, 63,224, 68,228, 62, 41, 76,116, 63,139,153,222, 62,
+134, 98,119, 63,204, 37,225, 62, 46,185,115, 63, 90,157,234, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,128, 0, 80,210,229, 60,
+ 32,239,218, 62,128,183, 73, 61, 84,108,213, 62, 28, 27,177, 61, 42,240,219, 62, 56,103,122, 61, 30, 10,230, 62,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0,128, 0, 46,178,102, 63,100,184,232, 62, 31,178,109, 63,224, 68,228, 62, 46,185,115, 63, 90,157,234, 62,
+244,134,106, 63,234, 64,246, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0, 56,103,122, 61, 30, 10,230, 62, 28, 27,177, 61,
+ 42,240,219, 62,120,216,242, 61,124, 40,225, 62,212,222,209, 61,238,123,240, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 16, 0,
+235,188, 5, 63,252, 74, 98, 63,200,111,248, 62,197,105,112, 63, 0, 49,231, 62,118,190,107, 63,150, 57,255, 62, 53, 14, 96, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 80, 99, 95, 62,149,194, 94, 63, 58, 8, 62, 62, 10,154, 89, 63, 40, 24, 92, 62,
+ 14, 82, 74, 63,112, 11,112, 62,157,133, 78, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,235,188, 5, 63,252, 74, 98, 63,
+136,139, 12, 63,138,233,101, 63,116, 45, 6, 63,112,245,113, 63,200,111,248, 62,197,105,112, 63,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0,240, 0, 68,219, 36, 62,249,186, 81, 63, 28,254, 65, 62, 20, 55, 70, 63, 40, 24, 92, 62, 14, 82, 74, 63, 58, 8, 62, 62,
+ 10,154, 89, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,136,139, 12, 63,138,233,101, 63, 5,130, 12, 63,149,216,108, 63,
+116, 45, 6, 63,112,245,113, 63, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,112, 0, 68,219, 36, 62,
+249,186, 81, 63, 76, 1, 42, 62, 39,178, 73, 63, 28,254, 65, 62, 20, 55, 70, 63, 0, 0,128, 63, 0, 0,128, 63,184, 62, 18, 3,
+ 1, 0, 5, 0, 0, 0,112, 0,120, 89,103, 63,105, 76, 2, 63,106,154, 93, 63,226, 26,233, 62, 46,178,102, 63,100,184,232, 62,
+244,134,106, 63,234, 64,246, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,120,216,242, 61,124, 40,225, 62,128, 1, 33, 62,
+ 70,210,226, 62,116,128,234, 61,200, 39, 0, 63,212,222,209, 61,238,123,240, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 0, 0,
+226, 44,245, 62,129,140, 96, 63,150, 57,255, 62, 53, 14, 96, 63, 0, 49,231, 62,118,190,107, 63, 42,135,227, 62, 58, 2,101, 63,
+184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0, 80, 99, 95, 62,149,194, 94, 63,112, 11,112, 62,157,133, 78, 63, 74, 84,120, 62,
+104, 32, 83, 63,110,103,122, 62,236,255, 92, 63,184, 62, 18, 3, 1, 0, 5, 0, 0, 0,240, 0,216,217, 77, 63, 7,228,157, 62,
+160,225, 90, 63,110,121,137, 62, 22, 25, 96, 63,246,248,149, 62,151, 5, 90, 63,138, 61,167, 62,184, 62, 18, 3, 1, 0, 5, 0,
+ 0, 0, 16, 0, 64,234, 54, 62,146,219,140, 62,166,125, 74, 62,252, 30,130, 62,154,118,111, 62,120,108,152, 62,194,251, 66, 62,
+163,102,158, 62,184, 62, 18, 3, 1, 0, 5, 0, 0, 0, 64, 0, 68, 65, 84, 65, 64, 31, 0, 0, 96, 53,164, 2, 58, 0, 0, 0,
+208, 7, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
@@ -3979,6110 +6547,4879 @@ char datatoc_preview_blend[]= {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 68, 65, 84, 65, 0, 0,117, 48, 8,170,144, 32, 0, 0, 0, 51, 0, 0, 1,244, 2,236,169, 32, 63, 28,112, 3,
- 62,236,178,185, 63, 27,124,224, 62,232, 65,235, 63, 30, 63,144, 62,226,195,233, 63, 32,152,118, 62,236,167, 37,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,209,232, 2, 62,226, 21,222,
- 62,215,109,102, 62,231,147,222, 62,213,135, 28, 62,236, 4,172, 62,205, 54, 56, 62,235,249, 22,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 32,152,118, 62,236,167, 37, 63, 30, 63,144,
- 62,226,195,233, 63, 33,235,108, 62,220,235,197, 63, 37,151,209, 62,236,161, 89,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,202,144, 76, 62,220, 61,186, 62,209,232, 2, 62,226, 21,222,
- 62,205, 54, 56, 62,235,249, 22, 62,195, 55,128, 62,235,243, 70,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 30, 63,144, 62,226,195,233, 63, 25, 55, 20, 62,223, 35, 1, 63, 25,178,200,
- 62,214,233, 77, 63, 33,235,108, 62,220,235,197,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,219, 1,146, 62,214, 59, 66, 62,219,248,248, 62,222,116,246, 62,209,232, 2, 62,226, 21,222,
- 62,202,144, 76, 62,220, 61,186,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 27,124,224, 62,232, 65,235, 63, 24,252, 87, 62,230,111, 93, 63, 25, 55, 20, 62,223, 35, 1, 63, 30, 63,144,
- 62,226,195,233,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,219,248,248, 62,222,116,246, 62,220,110,118, 62,229,193, 78, 62,215,109,102, 62,231,147,222, 62,209,232, 2, 62,226, 21,222,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 24,252, 87,
- 62,230,111, 93, 63, 22,195, 22, 62,232, 90,195, 63, 20, 91,191, 62,227, 18,193, 63, 25, 55, 20, 62,223, 35, 1,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,229,175,162, 62,226,100,178,
- 62,224,224,248, 62,231,172,182, 62,220,110,118, 62,229,193, 78, 62,219,248,248, 62,222,116,246,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 25, 55, 20, 62,223, 35, 1, 63, 20, 91,191,
- 62,227, 18,193, 63, 17,165,187, 62,221, 6,225, 63, 25,178,200, 62,214,233, 77,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,235, 27,170, 62,220, 88,214, 62,229,175,162, 62,226,100,178,
- 62,219,248,248, 62,222,116,246, 62,219, 1,146, 62,214, 59, 66,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 20, 91,191, 62,227, 18,193, 63, 18, 18,164, 62,236,201,173, 63, 13,231,157,
- 62,236,161, 89, 63, 17,165,187, 62,221, 6,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,242,151,232, 62,235,243, 70, 62,234, 65,216, 62,236, 27,158, 62,229,175,162, 62,226,100,178,
- 62,235, 27,170, 62,220, 88,214,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 22,195, 22, 62,232, 90,195, 63, 21,202, 11, 62,236,189, 1, 63, 18, 18,164, 62,236,201,173, 63, 20, 91,191,
- 62,227, 18,193,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,234, 65,216, 62,236, 27,158, 62,226,211, 12, 62,236, 14,246, 62,224,224,248, 62,231,172,182, 62,229,175,162, 62,226,100,178,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 21,202, 11,
- 62,236,189, 1, 63, 22,202,215, 62,241,124,237, 63, 20,105,125, 62,246, 71, 1, 63, 18, 18,164, 62,236,201,173,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,229,148, 42, 62,245,152,246,
- 62,224,209,112, 62,240,206,226, 62,226,211, 12, 62,236, 14,246, 62,234, 65,216, 62,236, 27,158,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 18, 18,164, 62,236,201,173, 63, 20,105,125,
- 62,246, 71, 1, 63, 17,173, 44, 62,252,149,231, 63, 13,231,157, 62,236,161, 89,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,235, 12,206, 62,251,231,218, 62,229,148, 42, 62,245,152,246,
- 62,234, 65,216, 62,236, 27,158, 62,242,151,232, 62,235,243, 70,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 20,105,125, 62,246, 71, 1, 63, 25, 59, 37, 62,250, 73, 49, 63, 25,178,108,
- 63, 1,108,218, 63, 17,173, 44, 62,252,149,231,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,219, 2, 76, 63, 1, 21,213, 62,219,240,216, 62,249,155, 38, 62,229,148, 42, 62,245,152,246,
- 62,235, 12,206, 62,251,231,218,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 22,202,215, 62,241,124,237, 63, 25, 1,195, 62,243,102,169, 63, 25, 59, 37, 62,250, 73, 49, 63, 20,105,125,
- 62,246, 71, 1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,219,240,216, 62,249,155, 38, 62,220, 99,156, 62,242,184,154, 62,224,209,112, 62,240,206,226, 62,229,148, 42, 62,245,152,246,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 25, 1,195,
- 62,243,102,169, 63, 27,125,176, 62,241,145,149, 63, 30, 74,167, 62,246,153, 3, 63, 25, 59, 37, 62,250, 73, 49,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,209,209,212, 62,245,234,246,
- 62,215,107,192, 62,240,227,138, 62,220, 99,156, 62,242,184,154, 62,219,240,216, 62,249,155, 38,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 25, 59, 37, 62,250, 73, 49, 63, 30, 74,167,
- 62,246,153, 3, 63, 33,230,204, 62,252,232,107, 63, 25,178,108, 63, 1,108,218,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,202,153,132, 62,252, 58, 94, 62,209,209,212, 62,245,234,246,
- 62,219,240,216, 62,249,155, 38, 62,219, 2, 76, 63, 1, 21,213,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 30, 74,167, 62,246,153, 3, 63, 32,152,118, 62,236,167, 37, 63, 37,151,209,
- 62,236,161, 89, 63, 33,230,204, 62,252,232,107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,195, 55,128, 62,235,243, 70, 62,205, 54, 56, 62,235,249, 22, 62,209,209,212, 62,245,234,246,
- 62,202,153,132, 62,252, 58, 94,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 27,125,176, 62,241,145,149, 63, 28,112, 3, 62,236,178,185, 63, 32,152,118, 62,236,167, 37, 63, 30, 74,167,
- 62,246,153, 3,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,205, 54, 56, 62,235,249, 22, 62,213,135, 28, 62,236, 4,172, 62,215,107,192, 62,240,227,138, 62,209,209,212, 62,245,234,246,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 28,112, 3,
- 62,236,178,185, 63, 27,125,176, 62,241,145,149, 63, 27, 39, 42, 62,241, 1, 57, 63, 27,249,140, 62,236,186,115,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,216, 24,206, 62,240, 83, 46,
- 62,215,107,192, 62,240,227,138, 62,213,135, 28, 62,236, 4,172, 62,214,116, 8, 62,236, 12,102,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 27,125,176, 62,241,145,149, 63, 25, 1,195,
- 62,243,102,169, 63, 24,248, 6, 62,242, 91,185, 63, 27, 39, 42, 62,241, 1, 57,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,220,119, 22, 62,241,173,174, 62,220, 99,156, 62,242,184,154,
- 62,215,107,192, 62,240,227,138, 62,216, 24,206, 62,240, 83, 46,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 25, 1,195, 62,243,102,169, 63, 22,202,215, 62,241,124,237, 63, 23, 38,157,
- 62,240,173,225, 63, 24,248, 6, 62,242, 91,185,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,224, 25,234, 62,239,255,214, 62,224,209,112, 62,240,206,226, 62,220, 99,156, 62,242,184,154,
- 62,220,119, 22, 62,241,173,174,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 22,202,215, 62,241,124,237, 63, 21,202, 11, 62,236,189, 1, 63, 22, 89, 13, 62,236,196,247, 63, 23, 38,157,
- 62,240,173,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,225,181, 8, 62,236, 22,234, 62,226,211, 12, 62,236, 14,246, 62,224,209,112, 62,240,206,226, 62,224, 25,234, 62,239,255,214,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 21,202, 11,
- 62,236,189, 1, 63, 22,195, 22, 62,232, 90,195, 63, 23, 33, 88, 62,233, 47, 69, 63, 22, 89, 13, 62,236,196,247,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,224, 36,112, 62,232,129, 58,
- 62,224,224,248, 62,231,172,182, 62,226,211, 12, 62,236, 14,246, 62,225,181, 8, 62,236, 22,234,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 22,195, 22, 62,232, 90,195, 63, 24,252, 87,
- 62,230,111, 93, 63, 24,243,100, 62,231,123, 5, 63, 23, 33, 88, 62,233, 47, 69,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,220,128, 90, 62,230,204,248, 62,220,110,118, 62,229,193, 78,
- 62,224,224,248, 62,231,172,182, 62,224, 36,112, 62,232,129, 58,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 24,252, 87, 62,230,111, 93, 63, 27,124,224, 62,232, 65,235, 63, 27, 37,169,
- 62,232,211, 35, 63, 24,243,100, 62,231,123, 5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,216, 27,206, 62,232, 37, 22, 62,215,109,102, 62,231,147,222, 62,220,110,118, 62,229,193, 78,
- 62,220,128, 90, 62,230,204,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 27,124,224, 62,232, 65,235, 63, 28,112, 3, 62,236,178,185, 63, 27,249,140, 62,236,186,115, 63, 27, 37,169,
- 62,232,211, 35,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,214,116, 8, 62,236, 12,102, 62,213,135, 28, 62,236, 4,172, 62,215,109,102, 62,231,147,222, 62,216, 27,206, 62,232, 37, 22,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 24,242,138,
- 62,236,194, 21, 63, 27, 37,169, 62,232,211, 35, 63, 27,249,140, 62,236,186,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 62,214,116, 8, 62,236, 12,102,
- 62,216, 27,206, 62,232, 37, 22, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 24,243,100, 62,231,123, 5, 63, 27, 37,169,
- 62,232,211, 35, 63, 24,242,138, 62,236,194, 21, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 62,220,130, 16, 62,236, 20, 6, 62,216, 27,206, 62,232, 37, 22,
- 62,220,128, 90, 62,230,204,248, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 24,242,138, 62,236,194, 21, 63, 23, 33, 88, 62,233, 47, 69, 63, 24,243,100,
- 62,231,123, 5, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,112, 2,236,169, 32, 62,220,128, 90, 62,230,204,248, 62,224, 36,112, 62,232,129, 58, 62,220,130, 16, 62,236, 20, 6,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112,
- 2,236,169, 32, 63, 24,242,138, 62,236,194, 21, 63, 22, 89, 13, 62,236,196,247, 63, 23, 33, 88, 62,233, 47, 69, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32,
- 62,224, 36,112, 62,232,129, 58, 62,225,181, 8, 62,236, 22,234, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 24,242,138,
- 62,236,194, 21, 63, 23, 38,157, 62,240,173,225, 63, 22, 89, 13, 62,236,196,247, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 62,225,181, 8, 62,236, 22,234,
- 62,224, 25,234, 62,239,255,214, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 24,242,138, 62,236,194, 21, 63, 24,248, 6,
- 62,242, 91,185, 63, 23, 38,157, 62,240,173,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 62,224, 25,234, 62,239,255,214, 62,220,119, 22, 62,241,173,174,
- 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 24,242,138, 62,236,194, 21, 63, 27, 39, 42, 62,241, 1, 57, 63, 24,248, 6,
- 62,242, 91,185, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,112, 2,236,169, 32, 62,220,119, 22, 62,241,173,174, 62,216, 24,206, 62,240, 83, 46, 62,220,130, 16, 62,236, 20, 6,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112,
- 2,236,169, 32, 63, 24,242,138, 62,236,194, 21, 63, 27,249,140, 62,236,186,115, 63, 27, 39, 42, 62,241, 1, 57, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32,
- 62,216, 24,206, 62,240, 83, 46, 62,214,116, 8, 62,236, 12,102, 62,220,130, 16, 62,236, 20, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63, 16,254,174,
- 62, 34, 45, 94, 63, 13,190, 79, 62, 46,193,160, 63, 3,199,220, 62, 24,219, 89, 63, 3,199,219, 61,229, 28, 18,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 63, 3,199,220, 62, 24,219, 89,
- 62,243,150, 14, 62, 47, 79,204, 62,236,248,140, 62, 34,202,182, 63, 3,199,219, 61,229, 28, 18,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 21,152,184, 62, 53, 47,182, 63, 16,104,250,
- 62, 55,113, 16, 63, 13,190, 79, 62, 46,193,160, 63, 16,254,174, 62, 34, 45, 94,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 62,243,150, 14, 62, 47, 79,204, 62,238, 68,200, 62, 56, 62, 76,
- 62,227,207,183, 62, 54, 75,250, 62,236,248,140, 62, 34,202,182,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 63, 22, 57,137, 62, 61, 93, 81, 63, 16,186,206, 62, 72,129, 85, 63, 16,104,250,
- 62, 55,113, 16, 63, 21,152,184, 62, 53, 47,182,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,238, 68,200, 62, 56, 62, 76, 62,237,187,192, 62, 73,118,194, 62,226,152,122, 62, 62,166,190,
- 62,227,207,183, 62, 54, 75,250,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 22,249,250, 62, 88,251,160, 63, 16, 32,222, 62, 93,106, 34, 63, 16,186,206, 62, 72,129, 85, 63, 22, 57,137,
- 62, 61, 93, 81,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,237,187,192, 62, 73,118,194, 62,239, 19, 21, 62, 94,110,121, 62,225, 83, 90, 62, 90,153, 21, 62,226,152,122, 62, 62,166,190,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 25, 81, 20,
- 62,132, 56, 17, 63, 15,243,206, 62,136,207,182, 63, 16, 32,222, 62, 93,106, 34, 63, 22,249,250, 62, 88,251,160,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,239, 19, 21, 62, 94,110,121,
- 62,239,193, 92, 62,137, 61,113, 62,221, 42, 54, 62,133, 25,209, 62,225, 83, 90, 62, 90,153, 21,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,239,111, 62,166, 77,159, 63, 37, 94, 91,
- 62,187,120,107, 63, 30, 21, 66, 62,200,139,178, 63, 12,237,158, 62,187,241, 38,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,211,125,139, 62,200,171,170, 62,197, 28,156, 62,187,130,166,
- 62,216, 21,115, 62,166,177, 14, 62,245,175, 15, 62,188, 14,188,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 37, 94, 91, 62,187,120,107, 63, 43, 57, 87, 62,206, 58,222, 63, 39,163, 24,
- 62,216, 95,174, 63, 30, 21, 66, 62,200,139,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,191,194, 98, 62,216, 94, 42, 62,184,207,130, 62,206, 27, 42, 62,197, 28,156, 62,187,130,166,
- 62,211,125,139, 62,200,171,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 43, 57, 87, 62,206, 58,222, 63, 50,229, 38, 62,226, 32,169, 63, 43, 79,177, 62,231,194,202, 63, 39,163, 24,
- 62,216, 95,174,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,183,201, 60, 62,231,218, 82, 62,168, 39,196, 62,226, 11,206, 62,184,207,130, 62,206, 27, 42, 62,191,194, 98, 62,216, 94, 42,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 50,229, 38,
- 62,226, 32,169, 63, 48,134, 62, 62,249,107, 37, 63, 43,190,154, 62,249, 0,192, 63, 43, 79,177, 62,231,194,202,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,182,190,138, 62,249, 49, 35,
- 62,172,229,172, 62,249,127,116, 62,168, 39,196, 62,226, 11,206, 62,183,201, 60, 62,231,218, 82,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 48,134, 62, 62,249,107, 37, 63, 46, 88,238,
- 63, 2,223,146, 63, 40,207,123, 62,254,175,218, 63, 43,190,154, 62,249, 0,192,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,188,184, 2, 62,255, 0,140, 62,177, 87,173, 63, 3, 9,102,
- 62,172,229,172, 62,249,127,116, 62,182,190,138, 62,249, 49, 35,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 46, 88,238, 63, 2,223,146, 63, 34,158,220, 63, 10, 23,175, 63, 30, 77,126,
- 63, 5, 88,156, 63, 40,207,123, 62,254,175,218,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,210, 65, 89, 63, 5,158, 56, 62,201,109,124, 63, 10,121, 72, 62,177, 87,173, 63, 3, 9,102,
- 62,188,184, 2, 62,255, 0,140,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 34,158,220, 63, 10, 23,175, 63, 26,105, 28, 63, 11,194,242, 63, 25,120,244, 63, 7,242, 78, 63, 30, 77,126,
- 63, 5, 88,156,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,220, 39, 0, 63, 8, 58,252, 62,218, 73,220, 63, 12, 31,169, 62,201,109,124, 63, 10,121, 72, 62,210, 65, 89, 63, 5,158, 56,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 26,105, 28,
- 63, 11,194,242, 63, 22,244,173, 63, 11,215,236, 63, 22, 47,202, 63, 8, 60,156, 63, 25,120,244, 63, 7,242, 78,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,226,221, 11, 63, 8,125, 90,
- 62,225, 89,220, 63, 12, 42, 77, 62,218, 73,220, 63, 12, 31,169, 62,220, 39, 0, 63, 8, 58,252,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22,244,173, 63, 11,215,236, 63, 11,169, 67,
- 63, 11,197, 18, 63, 12,252,106, 63, 3,173,180, 63, 22, 47,202, 63, 8, 60,156,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,245,114, 35, 63, 3,196,233, 62,248, 72, 55, 63, 11,232, 91,
- 62,225, 89,220, 63, 12, 42, 77, 62,226,221, 11, 63, 8,125, 90,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 11,169, 67, 63, 11,197, 18, 63, 3,232,148, 63, 11, 17,164, 63, 3,220,162,
- 63, 0, 88, 45, 63, 12,252,106, 63, 3,173,180,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 3,220,162, 63, 0, 88, 45, 63, 3,232,148, 63, 11, 17,164, 62,248, 72, 55, 63, 11,232, 91,
- 62,245,114, 35, 63, 3,196,233,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 17, 59,103, 62,255,195,120, 63, 22, 81,240, 63, 1, 70,114, 63, 22, 47,202, 63, 8, 60,156, 63, 12,252,106,
- 63, 3,173,180,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,226,221, 11, 63, 8,125, 90, 62,226,128,106, 63, 1,111,198, 62,236,213,209, 62,255,250, 4, 62,245,114, 35, 63, 3,196,233,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22, 81,240,
- 63, 1, 70,114, 63, 25,182,151, 63, 1, 9,130, 63, 25,120,244, 63, 7,242, 78, 63, 22, 47,202, 63, 8, 60,156,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,220, 39, 0, 63, 8, 58,252,
- 62,219,150,213, 63, 1, 55, 50, 62,226,128,106, 63, 1,111,198, 62,226,221, 11, 63, 8,125, 90,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 30, 49, 96, 62,254,229,121, 63, 30, 77,126,
- 63, 5, 88,156, 63, 25,120,244, 63, 7,242, 78, 63, 25,182,151, 63, 1, 9,130,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,220, 39, 0, 63, 8, 58,252, 62,210, 65, 89, 63, 5,158, 56,
- 62,210,116,176, 62,255, 62,227, 62,219,150,213, 63, 1, 55, 50,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 37,113, 25, 62,247,157, 35, 63, 40,207,123, 62,254,175,218, 63, 30, 77,126,
- 63, 5, 88,156, 63, 30, 49, 96, 62,254,229,121,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,210, 65, 89, 63, 5,158, 56, 62,188,184, 2, 62,255, 0,140, 62,195,165,189, 62,247,232,139,
- 62,210,116,176, 62,255, 62,227,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 39, 62, 92, 62,240, 75,121, 63, 43,190,154, 62,249, 0,192, 63, 40,207,123, 62,254,175,218, 63, 37,113, 25,
- 62,247,157, 35,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,188,184, 2, 62,255, 0,140, 62,182,190,138, 62,249, 49, 35, 62,192, 10,222, 62,240,128,163, 62,195,165,189, 62,247,232,139,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 38,149,140,
- 62,229, 95, 38, 63, 43, 79,177, 62,231,194,202, 63, 43,190,154, 62,249, 0,192, 63, 39, 62, 92, 62,240, 75,121,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,182,190,138, 62,249, 49, 35,
- 62,183,201, 60, 62,231,218, 82, 62,193,140,168, 62,229,129, 94, 62,192, 10,222, 62,240,128,163,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 33,120, 14, 62,214,238,166, 63, 39,163, 24,
- 62,216, 95,174, 63, 43, 79,177, 62,231,194,202, 63, 38,149,140, 62,229, 95, 38,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,183,201, 60, 62,231,218, 82, 62,191,194, 98, 62,216, 94, 42,
- 62,204, 75,168, 62,215, 7, 62, 62,193,140,168, 62,229,129, 94,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,178,165, 62,208, 17,128, 63, 30, 21, 66, 62,200,139,178, 63, 39,163, 24,
- 62,216, 95,174, 63, 33,120, 14, 62,214,238,166,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,191,194, 98, 62,216, 94, 42, 62,211,125,139, 62,200,171,170, 62,216, 24, 6, 62,208, 57,128,
- 62,204, 75,168, 62,215, 7, 62,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 17, 97, 15, 62,214, 34,220, 63, 12,237,158, 62,187,241, 38, 63, 30, 21, 66, 62,200,139,178, 63, 27,178,165,
- 62,208, 17,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,211,125,139, 62,200,171,170, 62,245,175, 15, 62,188, 14,188, 62,236,200,217, 62,214, 49,134, 62,216, 24, 6, 62,208, 57,128,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 17, 97, 15,
- 62,214, 34,220, 63, 14,244,149, 62,221, 42, 4, 63, 3,230,147, 62,208, 47, 78, 63, 12,237,158, 62,187,241, 38,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,230,147, 62,208, 47, 78,
- 62,241,144,141, 62,221, 52,244, 62,236,200,217, 62,214, 49,134, 62,245,175, 15, 62,188, 14,188,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 17, 59,103, 62,255,195,120, 63, 12,252,106,
- 63, 3,173,180, 63, 3,220,162, 63, 0, 88, 45, 63, 13, 25, 71, 62,243,163,116,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,220,162, 63, 0, 88, 45, 62,245,114, 35, 63, 3,196,233,
- 62,236,213,209, 62,255,250, 4, 62,245, 45, 0, 62,243,185,206,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 13, 25, 71, 62,243,163,116, 63, 3,220,162, 63, 0, 88, 45, 63, 3,220,215,
- 62,231,189,148, 63, 13, 2, 64, 62,230,215, 52,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 3,220,215, 62,231,189,148, 63, 3,220,162, 63, 0, 88, 45, 62,245, 45, 0, 62,243,185,206,
- 62,245,100,219, 62,230,230,184,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,230,147, 62,208, 47, 78, 63, 14,244,149, 62,221, 42, 4, 63, 13, 2, 64, 62,230,215, 52, 63, 3,220,215,
- 62,231,189,148,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,245,100,219, 62,230,230,184, 62,241,144,141, 62,221, 52,244, 63, 3,230,147, 62,208, 47, 78, 63, 3,220,215, 62,231,189,148,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 7, 61,250,
- 62, 54, 31,148, 63, 3,202,193, 62, 49,174,214, 63, 3,199,220, 62, 24,219, 89, 63, 13,190, 79, 62, 46,193,160,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,199,220, 62, 24,219, 89,
- 63, 3,202,193, 62, 49,174,214, 63, 0, 87,175, 62, 54, 90,251, 62,243,150, 14, 62, 47, 79,204,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 9,214, 68, 62, 66,237,246, 63, 7, 61,250,
- 62, 54, 31,148, 63, 13,190, 79, 62, 46,193,160, 63, 16,104,250, 62, 55,113, 16,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,243,150, 14, 62, 47, 79,204, 63, 0, 87,175, 62, 54, 90,251,
- 62,251,137,104, 62, 67, 92,179, 62,238, 68,200, 62, 56, 62, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 8,221,237, 62, 91, 90,218, 63, 9,214, 68, 62, 66,237,246, 63, 16,104,250,
- 62, 55,113, 16, 63, 16,186,206, 62, 72,129, 85,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,238, 68,200, 62, 56, 62, 76, 62,251,137,104, 62, 67, 92,179, 62,253,153, 39, 62, 91,195, 27,
- 62,237,187,192, 62, 73,118,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 15,243,206, 62,136,207,182, 63, 8, 32, 77, 62,139, 39, 10, 63, 9,117, 22, 62, 97,203,146, 63, 16, 32,222,
- 62, 93,106, 34,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,252,110,192, 62, 98, 68, 79, 62,255, 89,219, 62,139, 79,116, 62,239,193, 92, 62,137, 61,113, 62,239, 19, 21, 62, 94,110,121,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 8,221,237,
- 62, 91, 90,218, 63, 16,186,206, 62, 72,129, 85, 63, 16, 32,222, 62, 93,106, 34, 63, 9,117, 22, 62, 97,203,146,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,239, 19, 21, 62, 94,110,121,
- 62,237,187,192, 62, 73,118,194, 62,253,153, 39, 62, 91,195, 27, 62,252,110,192, 62, 98, 68, 79,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 9,125,119, 62,158,112, 7, 63, 3,233, 70,
- 62,154, 27, 88, 63, 3,229,235, 62,139,108, 97, 63, 8, 32, 77, 62,139, 39, 10,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,229,235, 62,139,108, 97, 63, 3,233, 70, 62,154, 27, 88,
- 62,252,179,165, 62,158,140,163, 62,255, 89,219, 62,139, 79,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 9,117, 22, 62, 97,203,146, 63, 8, 32, 77, 62,139, 39, 10, 63, 3,229,235,
- 62,139,108, 97, 63, 3,215,246, 62,101, 56,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 3,229,235, 62,139,108, 97, 62,255, 89,219, 62,139, 79,116, 62,252,110,192, 62, 98, 68, 79,
- 63, 3,215,246, 62,101, 56,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,210,147, 62, 86, 95,221, 63, 8,221,237, 62, 91, 90,218, 63, 9,117, 22, 62, 97,203,146, 63, 3,215,246,
- 62,101, 56,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,252,110,192, 62, 98, 68, 79, 62,253,153, 39, 62, 91,195, 27, 63, 3,210,147, 62, 86, 95,221, 63, 3,215,246, 62,101, 56,143,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 12, 54, 5,
- 62,167,183,188, 63, 9, 61,250, 62,168,214,252, 63, 8,143,152, 62,163,107, 45, 63, 9,125,119, 62,158,112, 7,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,254,136,100, 62,163,123, 38,
- 62,253, 39,110, 62,168,224,103, 62,247, 68, 98, 62,167,206,146, 62,252,179,165, 62,158,140,163,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 10,196,135, 62,178,208, 52, 63, 8,233, 25,
- 62,175,110,116, 63, 9, 61,250, 62,168,214,252, 63, 12, 54, 5, 62,167,183,188,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,253, 39,110, 62,168,224,103, 62,253,195,102, 62,175,102,184,
- 62,250, 14, 98, 62,178,202,149, 62,247, 68, 98, 62,167,206,146,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 4, 17, 69, 62,182,176,105, 63, 6,138, 69, 62,177,180, 80, 63, 8,233, 25,
- 62,175,110,116, 63, 10,196,135, 62,178,208, 52,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,253,195,102, 62,175,102,184, 63, 1, 49, 14, 62,177,150, 62, 63, 4, 17, 69, 62,182,176,105,
- 62,250, 14, 98, 62,178,202,149,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,124,209, 62,177, 0, 70, 63, 3,232, 11, 62,174, 4,140, 63, 6,138, 69, 62,177,180, 80, 63, 4, 17, 69,
- 62,182,176,105,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 63, 1, 49, 14, 62,177,150, 62, 63, 3,232, 11, 62,174, 4,140, 63, 3,124,209, 62,177, 0, 70, 63, 4, 17, 69, 62,182,176,105,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,233, 70,
- 62,154, 27, 88, 63, 9,125,119, 62,158,112, 7, 63, 8,143,152, 62,163,107, 45, 63, 3,232,212, 62,158,152, 58,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,254,136,100, 62,163,123, 38,
- 62,252,179,165, 62,158,140,163, 63, 3,233, 70, 62,154, 27, 88, 63, 3,232,212, 62,158,152, 58,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,232,212, 62,158,152, 58, 63, 8,143,152,
- 62,163,107, 45, 63, 7, 91,121, 62,166, 51,134, 63, 3,231,205, 62,162,149, 58,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 0,116, 44, 62,166, 56,255, 62,254,136,100, 62,163,123, 38,
- 63, 3,232,212, 62,158,152, 58, 63, 3,231,205, 62,162,149, 58,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,232, 11, 62,174, 4,140, 63, 3,233,214, 62,170,154,198, 63, 6,110,233,
- 62,174,152, 94, 63, 6,138, 69, 62,177,180, 80,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 1, 82,228, 62,174,140, 95, 63, 3,233,214, 62,170,154,198, 63, 3,232, 11, 62,174, 4,140,
- 63, 1, 49, 14, 62,177,150, 62,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 6,138, 69, 62,177,180, 80, 63, 6,110,233, 62,174,152, 94, 63, 7,236, 59, 62,173,123, 19, 63, 8,233, 25,
- 62,175,110,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,255,185,217, 62,173,116, 92, 63, 1, 82,228, 62,174,140, 95, 63, 1, 49, 14, 62,177,150, 62, 62,253,195,102, 62,175,102,184,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 8,233, 25,
- 62,175,110,116, 63, 7,236, 59, 62,173,123, 19, 63, 7,249, 85, 62,169, 52, 92, 63, 9, 61,250, 62,168,214,252,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,255,169,160, 62,169, 57, 6,
- 62,255,185,217, 62,173,116, 92, 62,253,195,102, 62,175,102,184, 62,253, 39,110, 62,168,224,103,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 9, 61,250, 62,168,214,252, 63, 7,249, 85,
- 62,169, 52, 92, 63, 7, 91,121, 62,166, 51,134, 63, 8,143,152, 62,163,107, 45,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 0,116, 44, 62,166, 56,255, 62,255,169,160, 62,169, 57, 6,
- 62,253, 39,110, 62,168,224,103, 62,254,136,100, 62,163,123, 38,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,233,214, 62,170,154,198, 63, 7,249, 85, 62,169, 52, 92, 63, 7,236, 59,
- 62,173,123, 19, 63, 6,110,233, 62,174,152, 94,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,255,185,217, 62,173,116, 92, 62,255,169,160, 62,169, 57, 6, 63, 3,233,214, 62,170,154,198,
- 63, 1, 82,228, 62,174,140, 95,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,233,214, 62,170,154,198, 63, 3,231,205, 62,162,149, 58, 63, 7, 91,121, 62,166, 51,134, 63, 7,249, 85,
- 62,169, 52, 92,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 63, 0,116, 44, 62,166, 56,255, 63, 3,231,205, 62,162,149, 58, 63, 3,233,214, 62,170,154,198, 62,255,169,160, 62,169, 57, 6,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 4, 17, 69,
- 62,182,176,105, 63, 10,196,135, 62,178,208, 52, 63, 12,237,158, 62,187,241, 38, 63, 3,230,147, 62,208, 47, 78,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,245,175, 15, 62,188, 14,188,
- 62,250, 14, 98, 62,178,202,149, 63, 4, 17, 69, 62,182,176,105, 63, 3,230,147, 62,208, 47, 78,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 10,196,135, 62,178,208, 52, 63, 12, 54, 5,
- 62,167,183,188, 63, 16, 0,112, 62,164,246,254, 63, 12,237,158, 62,187,241, 38,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,239,187,207, 62,165, 42, 19, 62,247, 68, 98, 62,167,206,146,
- 62,250, 14, 98, 62,178,202,149, 62,245,175, 15, 62,188, 14,188,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 12, 54, 5, 62,167,183,188, 63, 9,125,119, 62,158,112, 7, 63, 15,250, 44,
- 62,154, 0,109, 63, 16, 0,112, 62,164,246,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,239,205, 56, 62,154, 71, 8, 62,252,179,165, 62,158,140,163, 62,247, 68, 98, 62,167,206,146,
- 62,239,187,207, 62,165, 42, 19,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 9,125,119, 62,158,112, 7, 63, 8, 32, 77, 62,139, 39, 10, 63, 15,243,206, 62,136,207,182, 63, 15,250, 44,
- 62,154, 0,109,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,239,193, 92, 62,137, 61,113, 62,255, 89,219, 62,139, 79,116, 62,252,179,165, 62,158,140,163, 62,239,205, 56, 62,154, 71, 8,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 25, 81, 20,
- 62,132, 56, 17, 63, 27, 46,208, 62,148, 35,149, 63, 15,250, 44, 62,154, 0,109, 63, 15,243,206, 62,136,207,182,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,239,205, 56, 62,154, 71, 8,
- 62,217,166,238, 62,148,221,229, 62,221, 42, 54, 62,133, 25,209, 62,239,193, 92, 62,137, 61,113,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27, 46,208, 62,148, 35,149, 63, 27,177, 36,
- 62,156,151,158, 63, 16, 0,112, 62,164,246,254, 63, 15,250, 44, 62,154, 0,109,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,239,187,207, 62,165, 42, 19, 62,216,160, 0, 62,157, 44,127,
- 62,217,166,238, 62,148,221,229, 62,239,205, 56, 62,154, 71, 8,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,239,111, 62,166, 77,159, 63, 12,237,158, 62,187,241, 38, 63, 16, 0,112,
- 62,164,246,254, 63, 27,177, 36, 62,156,151,158,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,239,187,207, 62,165, 42, 19, 62,245,175, 15, 62,188, 14,188, 62,216, 21,115, 62,166,177, 14,
- 62,216,160, 0, 62,157, 44,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 8,221,237, 62, 91, 90,218, 63, 3,210,147, 62, 86, 95,221, 63, 3,211,129, 62, 83,168,248, 63, 8, 33,170,
- 62, 86,149,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 63, 3,211,129, 62, 83,168,248, 63, 3,210,147, 62, 86, 95,221, 62,253,153, 39, 62, 91,195, 27, 62,255, 14, 8, 62, 86,232, 58,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 9,214, 68,
- 62, 66,237,246, 63, 8,221,237, 62, 91, 90,218, 63, 8, 33,170, 62, 86,149,254, 63, 8,180, 20, 62, 69, 29, 94,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,255, 14, 8, 62, 86,232, 58,
- 62,253,153, 39, 62, 91,195, 27, 62,251,137,104, 62, 67, 92,179, 62,253,210, 19, 62, 69,114, 55,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 7, 61,250, 62, 54, 31,148, 63, 9,214, 68,
- 62, 66,237,246, 63, 8,180, 20, 62, 69, 29, 94, 63, 6, 82,168, 62, 57, 43, 80,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,253,210, 19, 62, 69,114, 55, 62,251,137,104, 62, 67, 92,179,
- 63, 0, 87,175, 62, 54, 90,251, 63, 1, 68, 48, 62, 57, 84,166,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 3,202,193, 62, 49,174,214, 63, 7, 61,250, 62, 54, 31,148, 63, 6, 82,168,
- 62, 57, 43, 80, 63, 3,202,205, 62, 54, 22, 8,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 1, 68, 48, 62, 57, 84,166, 63, 0, 87,175, 62, 54, 90,251, 63, 3,202,193, 62, 49,174,214,
- 63, 3,202,205, 62, 54, 22, 8,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,202,205, 62, 54, 22, 8, 63, 6, 82,168, 62, 57, 43, 80, 63, 5, 24,246, 62, 66,150, 26, 63, 3,205,213,
- 62, 64,232,220,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 63, 2,131, 29, 62, 66,172, 22, 63, 1, 68, 48, 62, 57, 84,166, 63, 3,202,205, 62, 54, 22, 8, 63, 3,205,213, 62, 64,232,220,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 6, 82,168,
- 62, 57, 43, 80, 63, 8,180, 20, 62, 69, 29, 94, 63, 6, 83, 39, 62, 70,114,191, 63, 5, 24,246, 62, 66,150, 26,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 1, 75,185, 62, 70,160,222,
- 62,253,210, 19, 62, 69,114, 55, 63, 1, 68, 48, 62, 57, 84,166, 63, 2,131, 29, 62, 66,172, 22,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 8,180, 20, 62, 69, 29, 94, 63, 8, 33,170,
- 62, 86,149,254, 63, 6,111, 4, 62, 76,172, 40, 63, 6, 83, 39, 62, 70,114,191,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 1, 51,157, 62, 76,218,158, 62,255, 14, 8, 62, 86,232, 58,
- 62,253,210, 19, 62, 69,114, 55, 63, 1, 75,185, 62, 70,160,222,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 8, 33,170, 62, 86,149,254, 63, 3,211,129, 62, 83,168,248, 63, 3,208,234,
- 62, 75, 43,146, 63, 6,111, 4, 62, 76,172, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 63, 3,208,234, 62, 75, 43,146, 63, 3,211,129, 62, 83,168,248, 62,255, 14, 8, 62, 86,232, 58,
- 63, 1, 51,157, 62, 76,218,158,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,208,234, 62, 75, 43,146, 63, 3,205,213, 62, 64,232,220, 63, 5, 24,246, 62, 66,150, 26, 63, 6,111, 4,
- 62, 76,172, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 63, 2,131, 29, 62, 66,172, 22, 63, 3,205,213, 62, 64,232,220, 63, 3,208,234, 62, 75, 43,146, 63, 1, 51,157, 62, 76,218,158,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 6,111, 4,
- 62, 76,172, 40, 63, 5, 24,246, 62, 66,150, 26, 63, 6, 83, 39, 62, 70,114,191, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 1, 75,185, 62, 70,160,222,
- 63, 2,131, 29, 62, 66,172, 22, 63, 1, 51,157, 62, 76,218,158, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 13, 2, 64, 62,230,215, 52, 63, 14,244,149,
- 62,221, 42, 4, 63, 16,216, 4, 62,224, 24,160, 63, 15,200,120, 62,231,255, 84,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,237,193,119, 62,224, 38,190, 62,241,144,141, 62,221, 52,244,
- 62,245,100,219, 62,230,230,184, 62,239,211, 21, 62,232, 18,185,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 13, 25, 71, 62,243,163,116, 63, 13, 2, 64, 62,230,215, 52, 63, 15,200,120,
- 62,231,255, 84, 63, 16,171,184, 62,241,133, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,239,211, 21, 62,232, 18,185, 62,245,100,219, 62,230,230,184, 62,245, 45, 0, 62,243,185,206,
- 62,237,252,218, 62,241,160, 62,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 17, 59,103, 62,255,195,120, 63, 13, 25, 71, 62,243,163,116, 63, 16,171,184, 62,241,133, 40, 63, 19, 44, 55,
- 62,250, 21, 86,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,237,252,218, 62,241,160, 62, 62,245, 45, 0, 62,243,185,206, 62,236,213,209, 62,255,250, 4, 62,232,228,153, 62,250, 67,154,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 14,244,149,
- 62,221, 42, 4, 63, 17, 97, 15, 62,214, 34,220, 63, 19, 53,217, 62,218,211, 16, 63, 16,216, 4, 62,224, 24,160,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,233, 14, 8, 62,218,226, 66,
- 62,236,200,217, 62,214, 49,134, 62,241,144,141, 62,221, 52,244, 62,237,193,119, 62,224, 38,190,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 17, 97, 15, 62,214, 34,220, 63, 27,178,165,
- 62,208, 17,128, 63, 26,198,205, 62,214,184,124, 63, 19, 53,217, 62,218,211, 16,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,217,214,216, 62,214,224,218, 62,216, 24, 6, 62,208, 57,128,
- 62,236,200,217, 62,214, 49,134, 62,233, 14, 8, 62,218,226, 66,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,178,165, 62,208, 17,128, 63, 33,120, 14, 62,214,238,166, 63, 31,136,156,
- 62,219,138,194, 63, 26,198,205, 62,214,184,124,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,208, 30,254, 62,219,177,204, 62,204, 75,168, 62,215, 7, 62, 62,216, 24, 6, 62,208, 57,128,
- 62,217,214,216, 62,214,224,218,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 33,120, 14, 62,214,238,166, 63, 38,149,140, 62,229, 95, 38, 63, 36, 9, 79, 62,229,224, 94, 63, 31,136,156,
- 62,219,138,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,198,192,148, 62,230, 11,182, 62,193,140,168, 62,229,129, 94, 62,204, 75,168, 62,215, 7, 62, 62,208, 30,254, 62,219,177,204,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 38,149,140,
- 62,229, 95, 38, 63, 39, 62, 92, 62,240, 75,121, 63, 36, 49, 14, 62,239, 88,253, 63, 36, 9, 79, 62,229,224, 94,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,198, 71, 97, 62,239,149,192,
- 62,192, 10,222, 62,240,128,163, 62,193,140,168, 62,229,129, 94, 62,198,192,148, 62,230, 11,182,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 39, 62, 92, 62,240, 75,121, 63, 37,113, 25,
- 62,247,157, 35, 63, 35, 33,243, 62,245,143, 80, 63, 36, 49, 14, 62,239, 88,253,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,200, 99, 87, 62,245,217,172, 62,195,165,189, 62,247,232,139,
- 62,192, 10,222, 62,240,128,163, 62,198, 71, 97, 62,239,149,192,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 37,113, 25, 62,247,157, 35, 63, 30, 49, 96, 62,254,229,121, 63, 29, 49,223,
- 62,250,140,199, 63, 35, 33,243, 62,245,143, 80,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,212,124,147, 62,250,215,146, 62,210,116,176, 62,255, 62,227, 62,195,165,189, 62,247,232,139,
- 62,200, 99, 87, 62,245,217,172,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 30, 49, 96, 62,254,229,121, 63, 25,182,151, 63, 1, 9,130, 63, 25,181, 50, 62,253,111,118, 63, 29, 49,223,
- 62,250,140,199,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,219,151, 52, 62,253,186, 68, 62,219,150,213, 63, 1, 55, 50, 62,210,116,176, 62,255, 62,227, 62,212,124,147, 62,250,215,146,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 25,182,151,
- 63, 1, 9,130, 63, 22, 81,240, 63, 1, 70,114, 63, 22,188,241, 62,253,149, 28, 63, 25,181, 50, 62,253,111,118,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,225,163,212, 62,253,215, 91,
- 62,226,128,106, 63, 1,111,198, 62,219,150,213, 63, 1, 55, 50, 62,219,151, 52, 62,253,186, 68,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22, 81,240, 63, 1, 70,114, 63, 17, 59,103,
- 62,255,195,120, 63, 19, 44, 55, 62,250, 21, 86, 63, 22,188,241, 62,253,149, 28,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,232,228,153, 62,250, 67,154, 62,236,213,209, 62,255,250, 4,
- 62,226,128,106, 63, 1,111,198, 62,225,163,212, 62,253,215, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22,188,241, 62,253,149, 28, 63, 19, 44, 55, 62,250, 21, 86, 63, 20,165, 9,
- 62,247, 99,248, 63, 23, 0, 20, 62,251, 57, 6,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,229,232,232, 62,247,142, 74, 62,232,228,153, 62,250, 67,154, 62,225,163,212, 62,253,215, 91,
- 62,225, 26,145, 62,251,116,114,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 25,181, 50, 62,253,111,118, 63, 22,188,241, 62,253,149, 28, 63, 23, 0, 20, 62,251, 57, 6, 63, 25,144,130,
- 62,251, 7,128,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,225, 26,145, 62,251,116,114, 62,225,163,212, 62,253,215, 91, 62,219,151, 52, 62,253,186, 68, 62,219,225,177, 62,251, 75, 67,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 29, 49,223,
- 62,250,140,199, 63, 25,181, 50, 62,253,111,118, 63, 25,144,130, 62,251, 7,128, 63, 28,195, 80, 62,248,166, 55,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,219,225,177, 62,251, 75, 67,
- 62,219,151, 52, 62,253,186, 68, 62,212,124,147, 62,250,215,146, 62,213, 95,233, 62,248,237, 20,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 35, 33,243, 62,245,143, 80, 63, 29, 49,223,
- 62,250,140,199, 63, 28,195, 80, 62,248,166, 55, 63, 33,164, 22, 62,243, 75,102,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,213, 95,233, 62,248,237, 20, 62,212,124,147, 62,250,215,146,
- 62,200, 99, 87, 62,245,217,172, 62,203,114, 65, 62,243,143,159,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 36, 49, 14, 62,239, 88,253, 63, 35, 33,243, 62,245,143, 80, 63, 33,164, 22,
- 62,243, 75,102, 63, 34,160, 30, 62,238, 47,169,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,203,114, 65, 62,243,143,159, 62,200, 99, 87, 62,245,217,172, 62,198, 71, 97, 62,239,149,192,
- 62,201,128,188, 62,238,110,126,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 36, 9, 79, 62,229,224, 94, 63, 36, 49, 14, 62,239, 88,253, 63, 34,160, 30, 62,238, 47,169, 63, 34,144,131,
- 62,231, 87,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,201,128,188, 62,238,110,126, 62,198, 71, 97, 62,239,149,192, 62,198,192,148, 62,230, 11,182, 62,201,190,141, 62,231,140,124,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 31,136,156,
- 62,219,138,194, 63, 36, 9, 79, 62,229,224, 94, 63, 34,144,131, 62,231, 87,253, 63, 30,208, 21, 62,221,182,174,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,201,190,141, 62,231,140,124,
- 62,198,192,148, 62,230, 11,182, 62,208, 30,254, 62,219,177,204, 62,209,133,168, 62,221,221, 51,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 26,198,205, 62,214,184,124, 63, 31,136,156,
- 62,219,138,194, 63, 30,208, 21, 62,221,182,174, 63, 26,218,128, 62,217,206, 68,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,209,133,168, 62,221,221, 51, 62,208, 30,254, 62,219,177,204,
- 62,217,214,216, 62,214,224,218, 62,217,157, 11, 62,217,243, 64,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 19, 53,217, 62,218,211, 16, 63, 26,198,205, 62,214,184,124, 63, 26,218,128,
- 62,217,206, 68, 63, 20, 53,103, 62,221, 84,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,217,157, 11, 62,217,243, 64, 62,217,214,216, 62,214,224,218, 62,233, 14, 8, 62,218,226, 66,
- 62,231, 5, 68, 62,221,101,234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 16,216, 4, 62,224, 24,160, 63, 19, 53,217, 62,218,211, 16, 63, 20, 53,103, 62,221, 84,236, 63, 18, 87, 81,
- 62,226,175, 33,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,231, 5, 68, 62,221,101,234, 62,233, 14, 8, 62,218,226, 66, 62,237,193,119, 62,224, 38,190, 62,234,187,180, 62,226,190,249,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 19, 44, 55,
- 62,250, 21, 86, 63, 16,171,184, 62,241,133, 40, 63, 18, 68, 98, 62,240,197,150, 63, 20,165, 9, 62,247, 99,248,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,234,197, 35, 62,240,226,215,
- 62,237,252,218, 62,241,160, 62, 62,232,228,153, 62,250, 67,154, 62,229,232,232, 62,247,142, 74,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 16,171,184, 62,241,133, 40, 63, 15,200,120,
- 62,231,255, 84, 63, 18, 4,161, 62,232,184,138, 63, 18, 68, 98, 62,240,197,150,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,235, 85,154, 62,232,206, 92, 62,239,211, 21, 62,232, 18,185,
- 62,237,252,218, 62,241,160, 62, 62,234,197, 35, 62,240,226,215,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 15,200,120, 62,231,255, 84, 63, 16,216, 4, 62,224, 24,160, 63, 18, 87, 81,
- 62,226,175, 33, 63, 18, 4,161, 62,232,184,138,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,234,187,180, 62,226,190,249, 62,237,193,119, 62,224, 38,190, 62,239,211, 21, 62,232, 18,185,
- 62,235, 85,154, 62,232,206, 92,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 3,232,148, 63, 11, 17,164, 63, 11,169, 67, 63, 11,197, 18, 63, 13,120,216, 63, 23, 81,160, 63, 4, 15,147,
- 63, 23,248,227,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,245, 27, 64, 63, 23,166,100, 62,248, 72, 55, 63, 11,232, 91, 63, 3,232,148, 63, 11, 17,164, 63, 4, 15,147, 63, 23,248,227,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 11,169, 67,
- 63, 11,197, 18, 63, 22,244,173, 63, 11,215,236, 63, 23,233, 94, 63, 16, 60,186, 63, 13,120,216, 63, 23, 81,160,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,223,130,109, 63, 16,165,118,
- 62,225, 89,220, 63, 12, 42, 77, 62,248, 72, 55, 63, 11,232, 91, 62,245, 27, 64, 63, 23,166,100,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22,244,173, 63, 11,215,236, 63, 26,105, 28,
- 63, 11,194,242, 63, 28, 56,220, 63, 14,250, 66, 63, 23,233, 94, 63, 16, 60,186,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,214,161,157, 63, 15,110,219, 62,218, 73,220, 63, 12, 31,169,
- 62,225, 89,220, 63, 12, 42, 77, 62,223,130,109, 63, 16,165,118,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 26,105, 28, 63, 11,194,242, 63, 34,158,220, 63, 10, 23,175, 63, 39, 44,109,
- 63, 19,221,107, 63, 28, 56,220, 63, 14,250, 66,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,192, 26,156, 63, 20,139, 31, 62,201,109,124, 63, 10,121, 72, 62,218, 73,220, 63, 12, 31,169,
- 62,214,161,157, 63, 15,110,219,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 34,158,220, 63, 10, 23,175, 63, 46, 88,238, 63, 2,223,146, 63, 56, 80,242, 63, 6,244, 44, 63, 39, 44,109,
- 63, 19,221,107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32,
- 62,156,208, 61, 63, 7, 16,204, 62,177, 87,173, 63, 3, 9,102, 62,201,109,124, 63, 10,121, 72, 62,192, 26,156, 63, 20,139, 31,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 63, 46, 88,238,
- 63, 2,223,146, 63, 48,134, 62, 62,249,107, 37, 63, 54,173,195, 62,252,106,239, 63, 56, 80,242, 63, 6,244, 44,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 62,160, 36,202, 62,252, 51, 94,
- 62,172,229,172, 62,249,127,116, 62,177, 87,173, 63, 3, 9,102, 62,156,208, 61, 63, 7, 16,204,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 63, 48,134, 62, 62,249,107, 37, 63, 50,229, 38,
- 62,226, 32,169, 63, 53, 88,154, 62,221,146,240, 63, 54,173,195, 62,252,106,239,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 62,162,172,128, 62,221,169, 17, 62,168, 39,196, 62,226, 11,206,
- 62,172,229,172, 62,249,127,116, 62,160, 36,202, 62,252, 51, 94,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 63, 50,229, 38, 62,226, 32,169, 63, 43, 57, 87, 62,206, 58,222, 63, 49,117,240,
- 62,198,138,164, 63, 53, 88,154, 62,221,146,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,128, 2,236,169, 32, 62,172,137,147, 62,198, 19,148, 62,184,207,130, 62,206, 27, 42, 62,168, 39,196, 62,226, 11,206,
- 62,162,172,128, 62,221,169, 17,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128,
- 2,236,169, 32, 63, 43, 57, 87, 62,206, 58,222, 63, 37, 94, 91, 62,187,120,107, 63, 41,160,156, 62,182,175, 56, 63, 49,117,240,
- 62,198,138,164,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,188,212,202, 62,182,163,245, 62,197, 28,156, 62,187,130,166, 62,184,207,130, 62,206, 27, 42, 62,172,137,147, 62,198, 19,148,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 48,252,165,
- 62, 85, 33,133, 63, 48, 54,112, 62, 96, 19, 20, 63, 46, 36,172, 62,129, 7,208, 63, 42, 17,240, 62, 97, 84,129,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,181, 71, 76, 62,131,200,204,
- 62,175,121,117, 62,106,185,183, 62,172, 24,217, 62, 92,237, 21, 62,187, 81,138, 62,103, 40, 59,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 48, 89,204, 62, 4,194,134, 63, 48,252,165,
- 62, 85, 33,133, 63, 42, 17,240, 62, 97, 84,129, 63, 37,125,160, 62, 46,211, 50,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 62,187, 81,138, 62,103, 40, 59, 62,172, 24,217, 62, 92,237, 21,
- 62,172,197, 94, 62, 4,200,109, 62,195,121, 25, 62, 48,253, 46,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 20, 44, 11, 61,163, 26, 20, 63, 48, 89,204, 62, 4,194,134, 63, 37,125,160,
- 62, 46,211, 50, 63, 24, 92, 40, 62, 21,184,214,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 32, 2,236,169, 32, 62,195,121, 25, 62, 48,253, 46, 62,172,197, 94, 62, 4,200,109, 62,230,122,140, 61,161,248,202,
- 62,222, 13,216, 62, 22,116,222,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32,
- 2,236,169, 32, 63, 16,254,174, 62, 34, 45, 94, 63, 3,199,219, 61,229, 28, 18, 63, 20, 44, 11, 61,163, 26, 20, 63, 24, 92, 40,
- 62, 21,184,214,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32,
- 62,230,122,140, 61,161,248,202, 63, 3,199,219, 61,229, 28, 18, 62,236,248,140, 62, 34,202,182, 62,222, 13,216, 62, 22,116,222,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 21,152,184,
- 62, 53, 47,182, 63, 16,254,174, 62, 34, 45, 94, 63, 24, 92, 40, 62, 21,184,214, 63, 25, 52,209, 62, 51,140, 76,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32, 2,236,169, 32, 62,222, 13,216, 62, 22,116,222,
- 62,236,248,140, 62, 34,202,182, 62,227,207,183, 62, 54, 75,250, 62,220,137,229, 62, 52,228,185,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32, 2,236,169, 32, 63, 22, 57,137, 62, 61, 93, 81, 63, 21,152,184,
- 62, 53, 47,182, 63, 25, 52,209, 62, 51,140, 76, 63, 30,166,193, 62, 73,168,114,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,220,137,229, 62, 52,228,185, 62,227,207,183, 62, 54, 75,250,
- 62,226,152,122, 62, 62,166,190, 62,209,198, 54, 62, 75,240, 18,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 22,249,250, 62, 88,251,160, 63, 22, 57,137, 62, 61, 93, 81, 63, 30,166,193,
- 62, 73,168,114, 63, 36, 0, 75, 62,116, 47,229,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,209,198, 54, 62, 75,240, 18, 62,226,152,122, 62, 62,166,190, 62,225, 83, 90, 62, 90,153, 21,
- 62,199,231,211, 62,119,237,216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 30,166,193, 62, 73,168,114, 63, 37,125,160, 62, 46,211, 50, 63, 42, 17,240, 62, 97, 84,129, 63, 36, 0, 75,
- 62,116, 47,229,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,187, 81,138, 62,103, 40, 59, 62,195,121, 25, 62, 48,253, 46, 62,209,198, 54, 62, 75,240, 18, 62,199,231,211, 62,119,237,216,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 30,166,193,
- 62, 73,168,114, 63, 25, 52,209, 62, 51,140, 76, 63, 24, 92, 40, 62, 21,184,214, 63, 37,125,160, 62, 46,211, 50,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,222, 13,216, 62, 22,116,222,
- 62,220,137,229, 62, 52,228,185, 62,209,198, 54, 62, 75,240, 18, 62,195,121, 25, 62, 48,253, 46,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 36,163, 37, 62,140,168,191, 63, 36, 0, 75,
- 62,116, 47,229, 63, 42, 17,240, 62, 97, 84,129, 63, 46, 36,172, 62,129, 7,208,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,187, 81,138, 62,103, 40, 59, 62,199,231,211, 62,119,237,216,
- 62,199, 64, 6, 62,142, 6,105, 62,181, 71, 76, 62,131,200,204,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 25, 81, 20, 62,132, 56, 17, 63, 22,249,250, 62, 88,251,160, 63, 36, 0, 75,
- 62,116, 47,229, 63, 36,163, 37, 62,140,168,191,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,199,231,211, 62,119,237,216, 62,225, 83, 90, 62, 90,153, 21, 62,221, 42, 54, 62,133, 25,209,
- 62,199, 64, 6, 62,142, 6,105,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 27, 46,208, 62,148, 35,149, 63, 36, 60, 91, 62,150,222,221, 63, 33,170,222, 62,158,126, 74, 63, 27,177, 36,
- 62,156,151,158,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,204,234, 72, 62,159, 63, 56, 62,199,245,150, 62,152, 15, 85, 62,217,166,238, 62,148,221,229, 62,216,160, 0, 62,157, 44,127,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 25, 81, 20,
- 62,132, 56, 17, 63, 36,163, 37, 62,140,168,191, 63, 36, 60, 91, 62,150,222,221, 63, 27, 46,208, 62,148, 35,149,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,199,245,150, 62,152, 15, 85,
- 62,199, 64, 6, 62,142, 6,105, 62,221, 42, 54, 62,133, 25,209, 62,217,166,238, 62,148,221,229,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,239,111, 62,166, 77,159, 63, 27,177, 36,
- 62,156,151,158, 63, 33,170,222, 62,158,126, 74, 63, 31,212,102, 62,164,192,144,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,204,234, 72, 62,159, 63, 56, 62,216,160, 0, 62,157, 44,127,
- 62,216, 21,115, 62,166,177, 14, 62,208,119, 17, 62,165, 65,201,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 27,239,111, 62,166, 77,159, 63, 31,212,102, 62,164,192,144, 63, 41,160,156,
- 62,182,175, 56, 63, 37, 94, 91, 62,187,120,107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,188,212,202, 62,182,163,245, 62,208,119, 17, 62,165, 65,201, 62,216, 21,115, 62,166,177, 14,
- 62,197, 28,156, 62,187,130,166,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 62,194,119,104, 63, 82,189,164, 62,212, 73, 23, 63, 90,239,152, 62,205,192,100, 63, 97,238, 46, 62,185, 56, 38,
- 63, 91,154, 72,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32,
- 62,141, 94,228, 63,100,234, 86, 62,150, 66, 84, 63, 94,154,114, 62,173, 86,230, 63, 98, 66, 79, 62,162,143, 20, 63,106,173, 44,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 87,122, 72,
- 62, 62, 8,216, 63, 84,106,202, 62,113,185,137, 63, 72, 77,226, 62,121, 21,204, 63, 71,225,158, 62, 68, 34,113,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 62,137, 32,132, 62,121, 65,181,
- 62,107,179,168, 62,103,127,139, 62,114,147,210, 62, 61,116,212, 62,142,125,248, 62, 80, 4, 30,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 71,225,158, 62, 68, 34,113, 63, 72, 77,226,
- 62,121, 21,204, 63, 51, 7, 8, 62,130,186, 5, 63, 49,166, 3, 62, 96, 57,232,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,172,197, 18, 62,133,112, 41, 62,137, 32,132, 62,121, 65,181,
- 62,142,125,248, 62, 80, 4, 30, 62,174,228,121, 62,109, 79, 52,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 49,166, 3, 62, 96, 57,232, 63, 51, 7, 8, 62,130,186, 5, 63, 46, 36,172,
- 62,129, 7,208, 63, 48, 54,112, 62, 96, 19, 20,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,181, 71, 76, 62,131,200,204, 62,172,197, 18, 62,133,112, 41, 62,174,228,121, 62,109, 79, 52,
- 62,175,121,117, 62,106,185,183,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 36,163, 37, 62,140,168,191, 63, 46, 36,172, 62,129, 7,208, 63, 51, 7, 8, 62,130,186, 5, 63, 36, 60, 91,
- 62,150,222,221,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,172,197, 18, 62,133,112, 41, 62,181, 71, 76, 62,131,200,204, 62,199, 64, 6, 62,142, 6,105, 62,199,245,150, 62,152, 15, 85,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 53, 88,154,
- 62,221,146,240, 63, 49,117,240, 62,198,138,164, 63, 69, 19,224, 62,190, 68, 24, 63, 74, 64, 53, 62,224, 31,171,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 62,134, 78,250, 62,186,213,148,
- 62,172,137,147, 62,198, 19,148, 62,162,172,128, 62,221,169, 17, 62,114,112,184, 62,220,169,248,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 62,214, 74, 54, 63, 70, 55, 20, 62,233,130, 48,
- 63, 83, 69,188, 62,212, 73, 23, 63, 90,239,152, 62,194,119,104, 63, 82,189,164,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,150, 66, 84, 63, 94,154,114, 62,153, 1, 66, 63, 81,149,245,
- 62,185, 56, 38, 63, 83,110,102, 62,173, 86,230, 63, 98, 66, 79,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 66,242,106, 63, 25, 94,202, 63, 70,100,190, 63, 15,234,222, 63, 77,189, 90,
- 63, 17, 88,233, 63, 74,206, 8, 63, 27,118, 88,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 96, 32, 22, 63, 16, 60, 66, 62,125, 87, 86, 63, 15, 5,174, 62,132,187, 78, 63, 24, 44,180,
- 62,108, 79, 26, 63, 26, 1,124,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 74,206, 8, 63, 27,118, 88, 63, 77,189, 90, 63, 17, 88,233, 63, 85,139, 72, 63, 19, 51,103, 63, 85,119,220,
- 63, 31, 71, 77,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 64,199, 64, 63, 18, 40, 26, 62, 96, 32, 22, 63, 16, 60, 66, 62,108, 79, 26, 63, 26, 1,124, 62, 67,191, 44, 63, 30, 89, 90,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 85,119,220,
- 63, 31, 71, 77, 63, 85,139, 72, 63, 19, 51,103, 63,100,213,228, 63, 20,156, 72, 63, 96, 82, 18, 63, 34,133,128,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 62, 1, 50,226, 63, 20, 68,184,
- 62, 64,199, 64, 63, 18, 40, 26, 62, 67,191, 44, 63, 30, 89, 90, 62, 24,204,194, 63, 34,186, 32,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 63, 56, 80,242, 63, 6,244, 44, 63, 54,173,195,
- 62,252,106,239, 63, 60,205,115, 62,253,150,213, 63, 64, 14,166, 63, 4, 80, 81,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 62,147, 85,190, 62,252,176, 91, 62,160, 36,202, 62,252, 51, 94,
- 62,156,208, 61, 63, 7, 16,204, 62,140,121,160, 63, 3,197, 74,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 64, 14,166, 63, 4, 80, 81, 63, 60,205,115, 62,253,150,213, 63, 73,103, 68,
- 63, 0,248,233, 63, 75, 12,248, 63, 8,206, 64,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,115, 59,144, 62,255,143,102, 62,147, 85,190, 62,252,176, 91, 62,140,121,160, 63, 3,197, 74,
- 62,107,135, 78, 63, 7,182, 88,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 75, 12,248, 63, 8,206, 64, 63, 73,103, 68, 63, 0,248,233, 63, 82,151,239, 63, 3,223, 86, 63, 82,227,181,
- 63, 11,102,189,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 77, 17, 82, 63, 2, 98,162, 62,115, 59,144, 62,255,143,102, 62,107,135, 78, 63, 7,182, 88, 62, 75, 98,202, 63, 10, 43,108,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 82,227,181,
- 63, 11,102,189, 63, 82,151,239, 63, 3,223, 86, 63, 91,224, 92, 63, 5,144,239, 63, 90,148,161, 63, 13, 95,146,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 38, 40,178, 63, 3,230, 14,
- 62, 77, 17, 82, 63, 2, 98,162, 62, 75, 98,202, 63, 10, 43,108, 62, 43,162, 10, 63, 12, 50, 8,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,103, 89,120, 63, 2, 76,105, 63,103,179,170,
- 63, 12,105,142, 63, 90,148,161, 63, 13, 95,146, 63, 91,224, 92, 63, 5,144,239,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 43,162, 10, 63, 12, 50, 8, 61,231, 41,168, 63, 11, 83,158,
- 61,234,128,116, 63, 0, 39,200, 62, 38, 40,178, 63, 3,230, 14,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,100,213,228, 63, 20,156, 72, 63, 85,139, 72, 63, 19, 51,103, 63, 90,148,161,
- 63, 13, 95,146, 63,103,179,170, 63, 12,105,142,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 43,162, 10, 63, 12, 50, 8, 62, 64,199, 64, 63, 18, 40, 26, 62, 1, 50,226, 63, 20, 68,184,
- 61,231, 41,168, 63, 11, 83,158,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 85,139, 72, 63, 19, 51,103, 63, 77,189, 90, 63, 17, 88,233, 63, 82,227,181, 63, 11,102,189, 63, 90,148,161,
- 63, 13, 95,146,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 75, 98,202, 63, 10, 43,108, 62, 96, 32, 22, 63, 16, 60, 66, 62, 64,199, 64, 63, 18, 40, 26, 62, 43,162, 10, 63, 12, 50, 8,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 77,189, 90,
- 63, 17, 88,233, 63, 70,100,190, 63, 15,234,222, 63, 75, 12,248, 63, 8,206, 64, 63, 82,227,181, 63, 11,102,189,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,107,135, 78, 63, 7,182, 88,
- 62,125, 87, 86, 63, 15, 5,174, 62, 96, 32, 22, 63, 16, 60, 66, 62, 75, 98,202, 63, 10, 43,108,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 70,100,190, 63, 15,234,222, 63, 60,235, 82,
- 63, 12, 12, 27, 63, 64, 14,166, 63, 4, 80, 81, 63, 75, 12,248, 63, 8,206, 64,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,140,121,160, 63, 3,197, 74, 62,145,230, 78, 63, 11,225,148,
- 62,125, 87, 86, 63, 15, 5,174, 62,107,135, 78, 63, 7,182, 88,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 57,118, 31, 63, 12, 79,230, 63, 56, 80,242, 63, 6,244, 44, 63, 64, 14,166,
- 63, 4, 80, 81, 63, 60,235, 82, 63, 12, 12, 27,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 32, 2,236,169, 32, 62,140,121,160, 63, 3,197, 74, 62,156,208, 61, 63, 7, 16,204, 62,152,199, 0, 63, 12,133, 13,
- 62,145,230, 78, 63, 11,225,148,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32,
- 2,236,169, 32, 63, 57,240,195, 63, 23,138, 10, 63, 60,235, 82, 63, 12, 12, 27, 63, 70,100,190, 63, 15,234,222, 63, 66,242,106,
- 63, 25, 94,202,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,125, 87, 86, 63, 15, 5,174, 62,145,230, 78, 63, 11,225,148, 62,150, 7,247, 63, 23, 12, 96, 62,132,187, 78, 63, 24, 44,180,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 13,120,216,
- 63, 23, 81,160, 63, 23,233, 94, 63, 16, 60,186, 63, 28, 56,220, 63, 14,250, 66, 63, 39, 44,109, 63, 19,221,107,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,214,161,157, 63, 15,110,219,
- 62,223,130,109, 63, 16,165,118, 62,245, 27, 64, 63, 23,166,100, 62,192, 26,156, 63, 20,139, 31,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 56, 29,176, 63, 20,206, 88, 63, 57,118, 31,
- 63, 12, 79,230, 63, 60,235, 82, 63, 12, 12, 27, 63, 57,240,195, 63, 23,138, 10,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,145,230, 78, 63, 11,225,148, 62,152,199, 0, 63, 12,133, 13,
- 62,153,211,239, 63, 20,159,220, 62,150, 7,247, 63, 23, 12, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 54,148, 48, 63, 22,206,220, 63, 56, 29,176, 63, 20,206, 88, 63, 57,240,195,
- 63, 23,138, 10, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,150, 7,247, 63, 23, 12, 96, 62,153,211,239, 63, 20,159,220, 62,156,106,108, 63, 22,154,146,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 54,173,195, 62,252,106,239, 63, 53, 88,154, 62,221,146,240, 63, 74, 64, 53, 62,224, 31,171, 63, 60,205,115,
- 62,253,150,213,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32, 2,236,169, 32,
- 62,114,112,184, 62,220,169,248, 62,162,172,128, 62,221,169, 17, 62,160, 36,202, 62,252, 51, 94, 62,147, 85,190, 62,252,176, 91,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32, 2,236,169, 32, 63, 74, 64, 53,
- 62,224, 31,171, 63, 81,106,217, 62,232,214, 14, 63, 73,103, 68, 63, 0,248,233, 63, 60,205,115, 62,253,150,213,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,115, 59,144, 62,255,143,102,
- 62, 84, 93, 88, 62,228,105, 50, 62,114,112,184, 62,220,169,248, 62,147, 85,190, 62,252,176, 91,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 81,106,217, 62,232,214, 14, 63, 93,154,106,
- 62,233, 26,226, 63, 82,151,239, 63, 3,223, 86, 63, 73,103, 68, 63, 0,248,233,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 77, 17, 82, 63, 2, 98,162, 62, 33, 1,128, 62,226,210, 70,
- 62, 84, 93, 88, 62,228,105, 50, 62,115, 59,144, 62,255,143,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,103, 89,120, 63, 2, 76,105, 63, 91,224, 92, 63, 5,144,239, 63, 82,151,239,
- 63, 3,223, 86, 63, 93,154,106, 62,233, 26,226,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 77, 17, 82, 63, 2, 98,162, 62, 38, 40,178, 63, 3,230, 14, 61,234,128,116, 63, 0, 39,200,
- 62, 33, 1,128, 62,226,210, 70,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 51, 7, 8, 62,130,186, 5, 63, 72, 77,226, 62,121, 21,204, 63, 73,254,154, 62,140, 82,178, 63, 56,188, 90,
- 62,159,207,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,130,249,249, 62,137,175,246, 62,137, 32,132, 62,121, 65,181, 62,172,197, 18, 62,133,112, 41, 62,161, 5,192, 62,159, 40,228,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 69, 19,224,
- 62,190, 68, 24, 63, 56,188, 90, 62,159,207,103, 63, 73,254,154, 62,140, 82,178, 63, 77,217,216, 62,157,228, 7,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 62,130,249,249, 62,137,175,246,
- 62,161, 5,192, 62,159, 40,228, 62,134, 78,250, 62,186,213,148, 62,111,118,154, 62,152,108,120,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 63, 49,117,240, 62,198,138,164, 63, 41,160,156,
- 62,182,175, 56, 63, 56,188, 90, 62,159,207,103, 63, 69, 19,224, 62,190, 68, 24,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,161, 5,192, 62,159, 40,228, 62,188,212,202, 62,182,163,245,
- 62,172,137,147, 62,198, 19,148, 62,134, 78,250, 62,186,213,148,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 41,160,156, 62,182,175, 56, 63, 33,170,222, 62,158,126, 74, 63, 36, 60, 91,
- 62,150,222,221, 63, 56,188, 90, 62,159,207,103,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62,199,245,150, 62,152, 15, 85, 62,204,234, 72, 62,159, 63, 56, 62,188,212,202, 62,182,163,245,
- 62,161, 5,192, 62,159, 40,228,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 36, 60, 91, 62,150,222,221, 63, 51, 7, 8, 62,130,186, 5, 63, 56,188, 90, 62,159,207,103, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62,161, 5,192, 62,159, 40,228, 62,172,197, 18, 62,133,112, 41, 62,199,245,150, 62,152, 15, 85, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 41,160,156,
- 62,182,175, 56, 63, 31,212,102, 62,164,192,144, 63, 33,170,222, 62,158,126, 74, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,204,234, 72, 62,159, 63, 56,
- 62,208,119, 17, 62,165, 65,201, 62,188,212,202, 62,182,163,245, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,245, 44,226, 63, 96,140,129, 62,227,135, 42,
- 63,101, 2, 58, 62,219,168,136, 63, 95,236, 30, 62,238, 30,135, 63, 90, 41,200,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,137,240,216, 63, 93,226, 90, 62,122,103,110, 63, 92,255,236,
- 62,120, 84, 74, 63, 83, 32,104, 62,138,193, 32, 63, 83, 3, 16,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62,233,130, 48, 63, 83, 69,188, 62,238, 30,135, 63, 90, 41,200, 62,219,168,136,
- 63, 95,236, 30, 62,212, 73, 23, 63, 90,239,152,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,240, 2,236,169, 32, 62,137,240,216, 63, 93,226, 90, 62,138,193, 32, 63, 83, 3, 16, 62,153, 1, 66, 63, 81,149,245,
- 62,150, 66, 84, 63, 94,154,114,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240,
- 2,236,169, 32, 63, 77,217,216, 62,157,228, 7, 63, 73,254,154, 62,140, 82,178, 63, 90, 61, 33, 62,124,207,195, 63, 90,225,160,
- 62,137,121,110,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32,
- 62, 81,207, 98, 62,110, 1,109, 62,130,249,249, 62,137,175,246, 62,111,118,154, 62,152,108,120, 62, 74,125,166, 62,130, 30,252,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 72, 77,226,
- 62,121, 21,204, 63, 84,106,202, 62,113,185,137, 63, 90, 61, 33, 62,124,207,195, 63, 73,254,154, 62,140, 82,178,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 81,207, 98, 62,110, 1,109,
- 62,107,179,168, 62,103,127,139, 62,137, 32,132, 62,121, 65,181, 62,130,249,249, 62,137,175,246,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,212, 73, 23, 63, 90,239,152, 62,219,168,136,
- 63, 95,236, 30, 62,205,192,100, 63, 97,238, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 62,141, 94,228, 63,100,234, 86, 62,137,240,216, 63, 93,226, 90,
- 62,150, 66, 84, 63, 94,154,114, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0,112, 2,236,169, 32, 63,109,178, 31, 62,228, 68,224, 63,102,178, 46, 62,232,184,100, 63,101,251,100,
- 62,227,198,238, 63,107,173, 94, 62,225,130,168,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,249,209, 68, 62,219,134, 70, 61,242,216,120, 62,225, 40,124, 61,177, 27, 28, 62,219,240, 42,
- 61,196,131, 76, 62,216, 97,196,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,109,178, 31, 62,228, 68,224, 63,107,173, 94, 62,225,130,168, 63,114,102,144, 62,220, 23,198, 63,116, 76, 41,
- 62,222,153,139,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,120,163, 56, 62,208,252, 58, 61,196,131, 76, 62,216, 97,196, 61,177, 27, 28, 62,219,240, 42, 61, 73,183,128, 62,213,108, 84,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,116, 76, 41,
- 62,222,153,139, 63,114,102,144, 62,220, 23,198, 63,117, 87, 84, 62,211,255,221, 63,119,115,183, 62,215, 49,140,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61, 55, 29,144, 62,194,183,207,
- 61,120,163, 56, 62,208,252, 58, 61, 73,183,128, 62,213,108, 84, 60,231,111,224, 62,198,142,100,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,119,115,183, 62,215, 49,140, 63,117, 87, 84,
- 62,211,255,221, 63,118, 20,150, 62,196,110, 60, 63,122, 12, 49, 62,197, 8,246,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,103,197, 96, 62,170,206, 15, 61, 55, 29,144, 62,194,183,207,
- 60,231,111,224, 62,198,142,100, 61, 16, 54,240, 62,167, 4,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,122, 12, 49, 62,197, 8,246, 63,118, 20,150, 62,196,110, 60, 63,108,155, 17,
- 62,178,201,130, 63,110,190, 84, 62,172, 77,223,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,246,252,148, 62,160,116,164, 61,103,197, 96, 62,170,206, 15, 61, 16, 54,240, 62,167, 4,120,
- 61,246, 66, 8, 62,152,161, 28,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,110,190, 84, 62,172, 77,223, 63,108,155, 17, 62,178,201,130, 63, 92,180, 21, 62,173, 95,202, 63, 90, 5,151,
- 62,167, 61,138,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 54,216,144, 62,163, 76, 35, 61,246,252,148, 62,160,116,164, 61,246, 66, 8, 62,152,161, 28, 62, 66,251,194, 62,158,102,163,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,108,155, 17,
- 62,178,201,130, 63,109,132,198, 62,186,157,182, 63, 97, 32, 68, 62,178, 12,192, 63, 92,180, 21, 62,173, 95,202,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 36,185, 48, 62,166, 7, 16,
- 61,221, 91, 40, 62,167,194, 4, 61,246,252,148, 62,160,116,164, 62, 54,216,144, 62,163, 76, 35,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,118, 20,150, 62,196,110, 60, 63,115,225, 84,
- 62,198, 85,208, 63,109,132,198, 62,186,157,182, 63,108,155, 17, 62,178,201,130,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,221, 91, 40, 62,167,194, 4, 61,134,221,244, 62,175,164,121,
- 61,103,197, 96, 62,170,206, 15, 61,246,252,148, 62,160,116,164,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,117, 87, 84, 62,211,255,221, 63,116, 48,222, 62,209, 8,169, 63,115,225, 84,
- 62,198, 85,208, 63,118, 20,150, 62,196,110, 60,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,134,221,244, 62,175,164,121, 61, 93,108,160, 62,190,207, 17, 61, 55, 29,144, 62,194,183,207,
- 61,103,197, 96, 62,170,206, 15,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,114,102,144, 62,220, 23,198, 63,113,151,174, 62,214,229, 26, 63,116, 48,222, 62,209, 8,169, 63,117, 87, 84,
- 62,211,255,221,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61, 93,108,160, 62,190,207, 17, 61,135,155, 12, 62,201, 39,166, 61,120,163, 56, 62,208,252, 58, 61, 55, 29,144, 62,194,183,207,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,107,173, 94,
- 62,225,130,168, 63,107,239,228, 62,218, 59, 62, 63,113,151,174, 62,214,229, 26, 63,114,102,144, 62,220, 23,198,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,135,155, 12, 62,201, 39,166,
- 61,195, 47,128, 62,207, 11, 6, 61,196,131, 76, 62,216, 97,196, 61,120,163, 56, 62,208,252, 58,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,107,173, 94, 62,225,130,168, 63,101,251,100,
- 62,227,198,238, 63,102,205, 71, 62,219, 94,132, 63,107,239,228, 62,218, 59, 62,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,244,157,192, 62,209,137,157, 61,249,209, 68, 62,219,134, 70,
- 61,196,131, 76, 62,216, 97,196, 61,195, 47,128, 62,207, 11, 6,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 69, 19,224, 62,190, 68, 24, 63, 77,217,216, 62,157,228, 7, 63, 85, 35,236,
- 62,181,201,164, 63, 78, 92, 56, 62,188,114,177,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 32, 2,236,169, 32, 62, 80, 91,122, 62,174, 18, 72, 62,111,118,154, 62,152,108,120, 62,134, 78,250, 62,186,213,148,
- 62,104,163,162, 62,182,180,150,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 32,
- 2,236,169, 32, 63, 77,217,216, 62,157,228, 7, 63, 90, 5,151, 62,167, 61,138, 63, 92,180, 21, 62,173, 95,202, 63, 85, 35,236,
- 62,181,201,164,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32,
- 62, 54,216,144, 62,163, 76, 35, 62, 66,251,194, 62,158,102,163, 62,111,118,154, 62,152,108,120, 62, 80, 91,122, 62,174, 18, 72,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32, 63, 74, 64, 53,
- 62,224, 31,171, 63, 69, 19,224, 62,190, 68, 24, 63, 78, 92, 56, 62,188,114,177, 63, 81,106,217, 62,232,214, 14,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,104,163,162, 62,182,180,150,
- 62,134, 78,250, 62,186,213,148, 62,114,112,184, 62,220,169,248, 62, 84, 93, 88, 62,228,105, 50,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 93,154,106, 62,233, 26,226, 63, 94,229,196,
- 62,224,195,128, 63,101,251,100, 62,227,198,238, 63,102,178, 46, 62,232,184,100,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,249,209, 68, 62,219,134, 70, 62, 28,187,108, 62,217, 86, 48,
- 62, 33, 1,128, 62,226,210, 70, 61,242,216,120, 62,225, 40,124,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 92,180, 21, 62,173, 95,202, 63, 97, 32, 68, 62,178, 12,192, 63, 94,215, 9,
- 62,186, 54, 4, 63, 85, 35,236, 62,181,201,164,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 41,122, 60, 62,175, 58, 16, 62, 36,185, 48, 62,166, 7, 16, 62, 54,216,144, 62,163, 76, 35,
- 62, 80, 91,122, 62,174, 18, 72,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 95, 78,230, 62,189,233, 4, 63, 86,188, 32, 62,190, 62, 44, 63, 85, 35,236, 62,181,201,164, 63, 94,215, 9,
- 62,186, 54, 4,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 80, 91,122, 62,174, 18, 72, 62, 71,118, 78, 62,182, 49, 27, 62, 37,225, 52, 62,179, 12, 40, 62, 41,122, 60, 62,175, 58, 16,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 92,166, 70,
- 62,197,166, 0, 63, 86,188, 32, 62,190, 62, 44, 63, 95, 78,230, 62,189,233, 4, 63, 95, 13,226, 62,194,152, 37,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 37,225, 52, 62,179, 12, 40,
- 62, 71,118, 78, 62,182, 49, 27, 62, 45,143,142, 62,188, 37,237, 62, 36,230,106, 62,184, 27,222,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 95, 90,248, 62,207,122,100, 63, 90,249,108,
- 62,212,199, 58, 63, 86,188, 32, 62,190, 62, 44, 63, 92,166, 70, 62,197,166, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 71,118, 78, 62,182, 49, 27, 62, 48, 56,110, 62,205, 43,230,
- 62, 30,250,174, 62,198, 12, 26, 62, 45,143,142, 62,188, 37,237,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 94,229,196, 62,224,195,128, 63, 90,249,108, 62,212,199, 58, 63, 95, 90,248,
- 62,207,122,100, 63, 98,104, 92, 62,215,136,197,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 30,250,174, 62,198, 12, 26, 62, 48, 56,110, 62,205, 43,230, 62, 28,187,108, 62,217, 86, 48,
- 62, 15, 59,212, 62,206, 50,224,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,101,251,100, 62,227,198,238, 63, 94,229,196, 62,224,195,128, 63, 98,104, 92, 62,215,136,197, 63,102,205, 71,
- 62,219, 94,132,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 15, 59,212, 62,206, 50,224, 62, 28,187,108, 62,217, 86, 48, 61,249,209, 68, 62,219,134, 70, 61,244,157,192, 62,209,137,157,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 81,106,217,
- 62,232,214, 14, 63, 90,249,108, 62,212,199, 58, 63, 94,229,196, 62,224,195,128, 63, 93,154,106, 62,233, 26,226,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 28,187,108, 62,217, 86, 48,
- 62, 48, 56,110, 62,205, 43,230, 62, 84, 93, 88, 62,228,105, 50, 62, 33, 1,128, 62,226,210, 70,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 81,106,217, 62,232,214, 14, 63, 78, 92, 56,
- 62,188,114,177, 63, 86,188, 32, 62,190, 62, 44, 63, 90,249,108, 62,212,199, 58,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 71,118, 78, 62,182, 49, 27, 62,104,163,162, 62,182,180,150,
- 62, 84, 93, 88, 62,228,105, 50, 62, 48, 56,110, 62,205, 43,230,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 78, 92, 56, 62,188,114,177, 63, 85, 35,236, 62,181,201,164, 63, 86,188, 32,
- 62,190, 62, 44, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 71,118, 78, 62,182, 49, 27, 62, 80, 91,122, 62,174, 18, 72, 62,104,163,162, 62,182,180,150,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,102,205, 71, 62,219, 94,132, 63, 98,104, 92, 62,215,136,197, 63,100,109,182, 62,210,255,149, 63,104, 86, 54,
- 62,214,241,209,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 7,107,160, 62,200,103, 34, 62, 15, 59,212, 62,206, 50,224, 61,244,157,192, 62,209,137,157, 61,232, 2, 8, 62,203,214, 20,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 98,104, 92,
- 62,215,136,197, 63, 95, 90,248, 62,207,122,100, 63, 97,206,112, 62,204,202, 10, 63,100,109,182, 62,210,255,149,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 21, 68, 64, 62,194, 55,107,
- 62, 30,250,174, 62,198, 12, 26, 62, 15, 59,212, 62,206, 50,224, 62, 7,107,160, 62,200,103, 34,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 95, 90,248, 62,207,122,100, 63, 92,166, 70,
- 62,197,166, 0, 63, 94,241, 82, 62,198,103, 40, 63, 97,206,112, 62,204,202, 10,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 35,225, 20, 62,188, 50, 39, 62, 45,143,142, 62,188, 37,237,
- 62, 30,250,174, 62,198, 12, 26, 62, 21, 68, 64, 62,194, 55,107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 92,166, 70, 62,197,166, 0, 63, 95, 13,226, 62,194,152, 37, 63, 97, 1,118,
- 62,195,226, 47, 63, 94,241, 82, 62,198,103, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 28, 43, 12, 62,184,177,186, 62, 36,230,106, 62,184, 27,222, 62, 45,143,142, 62,188, 37,237,
- 62, 35,225, 20, 62,188, 50, 39,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 95, 13,226, 62,194,152, 37, 63, 95, 78,230, 62,189,233, 4, 63, 97,113, 51, 62,189,151, 92, 63, 97, 1,118,
- 62,195,226, 47,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 29, 67,104, 62,177,199, 58, 62, 37,225, 52, 62,179, 12, 40, 62, 36,230,106, 62,184, 27,222, 62, 28, 43, 12, 62,184,177,186,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 95, 78,230,
- 62,189,233, 4, 63, 94,215, 9, 62,186, 54, 4, 63, 96, 69, 96, 62,187,133,152, 63, 97,113, 51, 62,189,151, 92,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 35, 14,140, 62,176, 19, 33,
- 62, 41,122, 60, 62,175, 58, 16, 62, 37,225, 52, 62,179, 12, 40, 62, 29, 67,104, 62,177,199, 58,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 94,215, 9, 62,186, 54, 4, 63, 97, 32, 68,
- 62,178, 12,192, 63, 98, 91,112, 62,182,128,149, 63, 96, 69, 96, 62,187,133,152,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 29,107,228, 62,169,230, 95, 62, 36,185, 48, 62,166, 7, 16,
- 62, 41,122, 60, 62,175, 58, 16, 62, 35, 14,140, 62,176, 19, 33,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,107,239,228, 62,218, 59, 62, 63,102,205, 71, 62,219, 94,132, 63,104, 86, 54,
- 62,214,241,209, 63,109, 27, 34, 62,214,254,155,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,232, 2, 8, 62,203,214, 20, 61,244,157,192, 62,209,137,157, 61,195, 47,128, 62,207, 11, 6,
- 61,184,174, 36, 62,202,130,216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,113,151,174, 62,214,229, 26, 63,107,239,228, 62,218, 59, 62, 63,109, 27, 34, 62,214,254,155, 63,113,134, 69,
- 62,212, 82,156,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,184,174, 36, 62,202,130,216, 61,195, 47,128, 62,207, 11, 6, 61,135,155, 12, 62,201, 39,166, 61,138,114, 60, 62,197, 61, 28,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,116, 48,222,
- 62,209, 8,169, 63,113,151,174, 62,214,229, 26, 63,113,134, 69, 62,212, 82,156, 63,114,143, 42, 62,207,168, 24,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,138,114, 60, 62,197, 61, 28,
- 61,135,155, 12, 62,201, 39,166, 61, 93,108,160, 62,190,207, 17, 61,132, 85,184, 62,189,211, 22,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,115,225, 84, 62,198, 85,208, 63,116, 48,222,
- 62,209, 8,169, 63,114,143, 42, 62,207,168, 24, 63,114,125,203, 62,200,114, 96,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,132, 85,184, 62,189,211, 22, 61, 93,108,160, 62,190,207, 17,
- 61,134,221,244, 62,175,164,121, 61,145,152, 16, 62,179,214, 84,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,109,132,198, 62,186,157,182, 63,115,225, 84, 62,198, 85,208, 63,114,125,203,
- 62,200,114, 96, 63,109,192,177, 62,190,240,152,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,145,152, 16, 62,179,214, 84, 61,134,221,244, 62,175,164,121, 61,221, 91, 40, 62,167,194, 4,
- 61,208,226, 64, 62,172, 58,232,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 97, 32, 68, 62,178, 12,192, 63,109,132,198, 62,186,157,182, 63,109,192,177, 62,190,240,152, 63, 98, 91,112,
- 62,182,128,149,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,208,226, 64, 62,172, 58,232, 61,221, 91, 40, 62,167,194, 4, 62, 36,185, 48, 62,166, 7, 16, 62, 29,107,228, 62,169,230, 95,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 97, 1,118,
- 62,195,226, 47, 63, 97,113, 51, 62,189,151, 92, 63,102,139,215, 62,193,109, 15, 63,100, 47, 54, 62,198,115,186,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 5,169, 92, 62,179,115,168,
- 62, 29, 67,104, 62,177,199, 58, 62, 28, 43, 12, 62,184,177,186, 62, 13, 97, 50, 62,186, 42, 50,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,100, 47, 54, 62,198,115,186, 63,102,139,215,
- 62,193,109, 15, 63,105,241,174, 62,200, 8,204, 63,103,233, 71, 62,204, 42,178,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,229,171,228, 62,185, 42, 41, 62, 5,169, 92, 62,179,115,168,
- 62, 13, 97, 50, 62,186, 42, 50, 61,243,248, 92, 62,191, 22, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,103,233, 71, 62,204, 42,178, 63,105,241,174, 62,200, 8,204, 63,108, 37, 51,
- 62,205, 3,249, 63,106,212, 56, 62,208,238, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,202, 99,120, 62,190, 49,192, 61,229,171,228, 62,185, 42, 41, 61,243,248, 92, 62,191, 22, 96,
- 61,211,209,160, 62,195,159,108,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,106,212, 56, 62,208,238, 96, 63,108, 37, 51, 62,205, 3,249, 63,110, 73, 56, 62,206,119,186, 63,109,191, 46,
- 62,210, 64, 92,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,179,234,244, 62,190,219,240, 61,202, 99,120, 62,190, 49,192, 61,211,209,160, 62,195,159,108, 61,181,129,196, 62,196, 14,204,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,109, 27, 34,
- 62,214,254,155, 63,104, 86, 54, 62,214,241,209, 63,106,212, 56, 62,208,238, 96, 63,109,191, 46, 62,210, 64, 92,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,211,209,160, 62,195,159,108,
- 61,232, 2, 8, 62,203,214, 20, 61,184,174, 36, 62,202,130,216, 61,181,129,196, 62,196, 14,204,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,100,109,182, 62,210,255,149, 63,103,233, 71,
- 62,204, 42,178, 63,106,212, 56, 62,208,238, 96, 63,104, 86, 54, 62,214,241,209,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,211,209,160, 62,195,159,108, 61,243,248, 92, 62,191, 22, 96,
- 62, 7,107,160, 62,200,103, 34, 61,232, 2, 8, 62,203,214, 20,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,100,109,182, 62,210,255,149, 63, 97,206,112, 62,204,202, 10, 63,100, 47, 54,
- 62,198,115,186, 63,103,233, 71, 62,204, 42,178,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 62, 13, 97, 50, 62,186, 42, 50, 62, 21, 68, 64, 62,194, 55,107, 62, 7,107,160, 62,200,103, 34,
- 61,243,248, 92, 62,191, 22, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63, 97, 1,118, 62,195,226, 47, 63,100, 47, 54, 62,198,115,186, 63, 97,206,112, 62,204,202, 10, 63, 94,241, 82,
- 62,198,103, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 62, 21, 68, 64, 62,194, 55,107, 62, 13, 97, 50, 62,186, 42, 50, 62, 28, 43, 12, 62,184,177,186, 62, 35,225, 20, 62,188, 50, 39,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63, 96, 69, 96,
- 62,187,133,152, 63, 98, 91,112, 62,182,128,149, 63,102,139,215, 62,193,109, 15, 63, 97,113, 51, 62,189,151, 92,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 5,169, 92, 62,179,115,168,
- 62, 29,107,228, 62,169,230, 95, 62, 35, 14,140, 62,176, 19, 33, 62, 29, 67,104, 62,177,199, 58,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,109,192,177, 62,190,240,152, 63,105,241,174,
- 62,200, 8,204, 63,102,139,215, 62,193,109, 15, 63, 98, 91,112, 62,182,128,149,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62, 5,169, 92, 62,179,115,168, 61,229,171,228, 62,185, 42, 41,
- 61,208,226, 64, 62,172, 58,232, 62, 29,107,228, 62,169,230, 95,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,114,125,203, 62,200,114, 96, 63,108, 37, 51, 62,205, 3,249, 63,105,241,174,
- 62,200, 8,204, 63,109,192,177, 62,190,240,152,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0, 0, 2,236,169, 32, 61,229,171,228, 62,185, 42, 41, 61,202, 99,120, 62,190, 49,192, 61,145,152, 16, 62,179,214, 84,
- 61,208,226, 64, 62,172, 58,232,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,114,143, 42, 62,207,168, 24, 63,110, 73, 56, 62,206,119,186, 63,108, 37, 51, 62,205, 3,249, 63,114,125,203,
- 62,200,114, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,202, 99,120, 62,190, 49,192, 61,179,234,244, 62,190,219,240, 61,132, 85,184, 62,189,211, 22, 61,145,152, 16, 62,179,214, 84,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,113,134, 69,
- 62,212, 82,156, 63,109,191, 46, 62,210, 64, 92, 63,110, 73, 56, 62,206,119,186, 63,114,143, 42, 62,207,168, 24,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,179,234,244, 62,190,219,240,
- 61,181,129,196, 62,196, 14,204, 61,138,114, 60, 62,197, 61, 28, 61,132, 85,184, 62,189,211, 22,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,109, 27, 34, 62,214,254,155, 63,109,191, 46,
- 62,210, 64, 92, 63,113,134, 69, 62,212, 82,156, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 61,138,114, 60, 62,197, 61, 28, 61,181,129,196, 62,196, 14,204,
- 61,184,174, 36, 62,202,130,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,110,190, 84, 62,172, 77,223, 63, 90, 5,151, 62,167, 61,138, 63, 96, 25, 22,
- 62,149,248,246, 63,122,176,162, 62,161,215,145,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,128, 2,236,169, 32, 62, 54,234, 64, 62,140,219,146, 62, 66,251,194, 62,158,102,163, 61,246, 66, 8, 62,152,161, 28,
- 61,189,241,172, 62,132,107, 13,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0,
- 2,236,169, 32, 63,122, 12, 49, 62,197, 8,246, 63,110,190, 84, 62,172, 77,223, 63,122,176,162, 62,161,215,145, 63,126,255,188,
- 62,198,248,115,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32,
- 61,189,241,172, 62,132,107, 13, 61,246, 66, 8, 62,152,161, 28, 61, 16, 54,240, 62,167, 4,120, 58,163, 8, 0, 62,162, 69, 39,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128, 2,236,169, 32, 63,119,115,183,
- 62,215, 49,140, 63,122, 12, 49, 62,197, 8,246, 63,126,255,188, 62,198,248,115, 63,122, 6, 47, 62,216,157,248,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 58,163, 8, 0, 62,162, 69, 39,
- 61, 16, 54,240, 62,167, 4,120, 60,231,111,224, 62,198,142,100, 60, 14,248,224, 62,198,141, 70,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 63,116, 76, 41, 62,222,153,139, 63,119,115,183,
- 62,215, 49,140, 63,122, 6, 47, 62,216,157,248, 63,119, 98,134, 62,225, 37,204,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 60, 14,248,224, 62,198,141, 70, 60,231,111,224, 62,198,142,100,
- 61, 73,183,128, 62,213,108, 84, 60,229,210, 80, 62,218,239, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 63,109,178, 31, 62,228, 68,224, 63,116, 76, 41, 62,222,153,139, 63,119, 98,134,
- 62,225, 37,204, 63,115,185, 46, 62,234,157, 90,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,128, 2,236,169, 32, 60,229,210, 80, 62,218,239, 32, 61, 73,183,128, 62,213,108, 84, 61,177, 27, 28, 62,219,240, 42,
- 61,122,103, 56, 62,230, 10, 30,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,128,
- 2,236,169, 32, 63,102,178, 46, 62,232,184,100, 63,109,178, 31, 62,228, 68,224, 63,115,185, 46, 62,234,157, 90, 63,106,134,244,
- 62,246, 64,234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 64, 2,236,169, 32,
- 61,122,103, 56, 62,230, 10, 30, 61,177, 27, 28, 62,219,240, 42, 61,242,216,120, 62,225, 40,124, 61,209,222,212, 62,240,123,238,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 63, 5,188,235,
- 63, 98, 74,252, 62,248,111,200, 63,112,105,197, 62,231, 49, 0, 63,107,190,118, 62,255, 57,150, 63, 96, 14, 53,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62, 95, 99, 80, 63, 94,194,149,
- 62, 62, 8, 58, 63, 89,154, 10, 62, 92, 24, 40, 63, 74, 82, 14, 62,112, 11,112, 63, 78,133,157,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 5,188,235, 63, 98, 74,252, 63, 12,139,136,
- 63,101,233,138, 63, 6, 45,116, 63,113,245,112, 62,248,111,200, 63,112,105,197,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62, 36,219, 68, 63, 81,186,249, 62, 65,254, 28, 63, 70, 55, 20,
- 62, 92, 24, 40, 63, 74, 82, 14, 62, 62, 8, 58, 63, 89,154, 10,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 12,139,136, 63,101,233,138, 63, 12,130, 5, 63,108,216,149, 63, 6, 45,116,
- 63,113,245,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5,
- 0, 0, 0,112, 2,236,169, 32, 62, 36,219, 68, 63, 81,186,249, 62, 42, 1, 76, 63, 73,178, 39, 62, 65,254, 28, 63, 70, 55, 20,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,112,
- 2,236,169, 32, 63,103, 89,120, 63, 2, 76,105, 63, 93,154,106, 62,233, 26,226, 63,102,178, 46, 62,232,184,100, 63,106,134,244,
- 62,246, 64,234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32,
- 61,242,216,120, 62,225, 40,124, 62, 33, 1,128, 62,226,210, 70, 61,234,128,116, 63, 0, 39,200, 61,209,222,212, 62,240,123,238,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 0, 2,236,169, 32, 62,245, 44,226,
- 63, 96,140,129, 62,255, 57,150, 63, 96, 14, 53, 62,231, 49, 0, 63,107,190,118, 62,227,135, 42, 63,101, 2, 58,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 62, 95, 99, 80, 63, 94,194,149,
- 62,112, 11,112, 63, 78,133,157, 62,120, 84, 74, 63, 83, 32,104, 62,122,103,110, 63, 92,255,236,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 5, 0, 0, 0,240, 2,236,169, 32, 63, 77,217,216, 62,157,228, 7, 63, 90,225,160,
- 62,137,121,110, 63, 96, 25, 22, 62,149,248,246, 63, 90, 5,151, 62,167, 61,138,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 5, 0, 0, 0, 16, 2,236,169, 32, 62, 54,234, 64, 62,140,219,146, 62, 74,125,166, 62,130, 30,252,
- 62,111,118,154, 62,152,108,120, 62, 66,251,194, 62,158,102,163,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 5, 0, 0, 0, 64, 0, 0, 77, 69, 0, 0, 1, 20, 2,236,208,112, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,213, 64,
- 2,236,203,160, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 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, 2,235,189,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,230, 87, 96, 5, 32, 40, 32, 5, 32, 48, 32, 5, 30, 70, 32, 5, 32, 8, 32, 5, 32, 24, 32, 0, 0, 0, 0,
- 5, 32, 62, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,209,176, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,236,210,224, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0,
- 2,236,212, 16, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,188, 0, 0, 1, 53, 0, 0, 0, 76,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 63, 76,204,213, 63, 76,204,255,182,104, 0, 0, 63,128, 0, 30, 63,128, 0,140,
- 63,127,255,214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,230, 87, 96, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,209,176, 0, 0, 0,242, 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, 5, 32, 8, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 14,176, 5, 32, 8, 32, 0, 0, 0, 56, 0, 0, 0,188, 63,230,102,133, 63,179, 51,208, 63,127,255,146,
-165,127, 0, 0, 90,129, 2,255, 63,230,102,133, 63, 25,154,206, 63,127,255,146,165,127, 0, 0, 90,129, 2,255, 63,179, 51, 81,
- 63,179, 51,210, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28, 63,179, 51,212, 63,127,255,152, 0, 0, 0, 0,
-127,255, 2,255, 63, 25,153,207, 63,179, 51,214, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,152, 63,179, 51,216,
- 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63,128, 0,158, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,
- 63,128, 0, 27, 63,128, 0,160, 63,127,255,150, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 63,128, 0,162, 63,127,255,154,
- 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63,128, 0,163, 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80,
- 63, 25,154,209, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27, 63, 25,154,213, 63,127,255,150, 0, 0, 0, 0,
-127,255, 2,255, 63, 25,153,204, 63, 25,154,217, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63, 25,154,221,
- 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 62, 76,209,160, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,
- 63,128, 0, 27, 62, 76,209,176, 63,127,255,150, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 62, 76,209,188, 63,127,255,152,
- 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 62, 76,209,204, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140,
- 63,230,103, 8, 63,127,255,148, 0, 0,165,127, 90,129, 0,255, 63, 25,153,204, 63,230,103, 10, 63,127,255,146, 0, 0,165,127,
- 90,129, 0,255, 63,128, 0, 27, 63,230,103, 10, 63,127,255,142, 0, 0,165,127, 90,129, 0,255, 63,179, 51, 80, 63,230,103, 12,
- 63,127,255,140, 0, 0,165,127, 90,129, 0,255,190, 76,205,152, 63,230,103, 12, 63,127,255,140, 0, 0,165,127, 90,129, 0,255,
-190, 76,205,152, 62, 76,209,160, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63, 25,154,209, 63,127,255,148,
- 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63,128, 0,158, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,190, 76,205,144,
- 63,179, 51,210, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,230,102,131, 63,230,103, 7, 63,127,255,148, 0, 0,165,127,
- 90,129, 0,255, 63,230,102,131, 63,128, 0,160, 63,127,255,142,165,127, 0, 0, 90,129, 2,255, 63,230,102,127, 62, 76,208, 28,
- 63,127,255,148,165,127, 0, 0, 90,129, 2,255,190, 76,205,146,190, 76,208, 72, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,
- 62, 76,205,150,190, 76,208, 24, 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,207,190, 76,208, 40, 63,127,255,154,
- 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28,190, 76,208, 56, 63,127,255,152, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 81,
-190, 76,208, 72, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,230,102,133,190, 76,208, 88, 63,127,255,146, 0, 0, 0, 0,
-127,255, 2,255, 63,230,102,133,190, 76,208, 88,191,128, 0, 4, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 81,190, 76,208, 72,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28,190, 76,208, 56,191,128, 0, 1, 0, 0, 0, 0,127,255, 2,255,
- 63, 25,153,207,190, 76,208, 40,191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,150,190, 76,208, 24,191,127,255,254,
- 0, 0, 0, 0,127,255, 2,255,190, 76,205,146,190, 76,208, 72,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,230,102,127,
- 62, 76,208, 28,191, 25,153,155,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,190, 76,201,136,191, 25,153,159,128, 1, 0, 0,
- 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28,190, 76,204,193,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,190, 76,201,136,
-190, 76,204,209,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28, 62, 76,204,219,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,131,190, 76,201,136, 62, 76,204,203,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28, 63, 25,153,159,
-128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,190, 76,201,136, 63, 25,153,155,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127,
- 62, 76,208, 28,191,128, 0, 3,165,127, 0, 0, 90,129, 2,255, 63,230,102,131, 63,128, 0,160,191,128, 0, 6,165,127, 0, 0,
- 90,129, 2,255, 63,230,102,131, 63,230,103, 7,191,128, 0, 3, 0, 0,165,127, 90,129, 0,255, 63,230,102,135, 63, 25,154,207,
- 63, 25,153,151,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,128, 0,156, 63, 25,153,151,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,131, 63,179, 51,212, 63, 25,153,155,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7, 63, 25,153,159,
-165,127,165,127, 0, 0, 2,255, 63,230,102,135, 63, 25,154,207, 62, 76,204,171,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,
- 63,128, 0,160, 62, 76,204,187,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,179, 51,212, 62, 76,204,203,128, 1, 0, 0,
- 0, 0, 2,255, 63,230,102,131, 63,230,103, 7, 62, 76,204,219,165,127,165,127, 0, 0, 2,255, 63,230,102,135, 63, 25,154,207,
-190, 76,204,241,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,128, 0,160,190, 76,204,225,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,131, 63,179, 51,212,190, 76,204,209,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7,190, 76,204,193,
-165,127,165,127, 0, 0, 2,255, 63,230,102,135, 63, 25,154,207,191, 25,153,167,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,
- 63,128, 0,160,191, 25,153,163,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,179, 51,212,191, 25,153,159,128, 1, 0, 0,
- 0, 0, 2,255, 63,230,102,131, 63,230,103, 7,191, 25,153,155,165,127,165,127, 0, 0, 2,255,190, 76,205,144, 63,179, 51,210,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63,128, 0,158,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,
-190, 76,205,152, 63, 25,154,209,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 62, 76,209,160,191,128, 0, 3,
- 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63,230,103, 12,191, 25,153,168, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152,
- 63,230,103, 12,190, 76,204,244, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152, 63,230,103, 12, 62, 76,204,168, 0, 0,128, 1,
- 0, 0, 2,255,190, 76,205,144, 63,230,103, 12, 63, 25,153,150, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152, 63,230,103, 12,
-191,128, 0, 7, 0, 0,165,127, 90,129, 0,255, 63,179, 51, 80, 63,230,103, 12,191,128, 0, 7, 0, 0,165,127, 90,129, 0,255,
- 63,128, 0, 27, 63,230,103, 10,191,128, 0, 6, 0, 0,165,127, 90,129, 0,255, 63, 25,153,204, 63,230,103, 10,191,128, 0, 4,
- 0, 0,165,127, 90,129, 0,255, 62, 76,205,140, 63,230,103, 8,191,128, 0, 3, 0, 0,165,127, 90,129, 0,255, 63,179, 51, 81,
- 63,230,103, 12, 63, 25,153,150, 0, 0,128, 1, 0, 0, 2,255, 63,128, 0, 28, 63,230,103, 10, 63, 25,153,150, 0, 0,128, 1,
- 0, 0, 2,255, 63, 25,153,207, 63,230,103, 10, 63, 25,153,154, 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,152, 63,230,103, 8,
- 63, 25,153,158, 0, 0,128, 1, 0, 0, 2,255, 63,179, 51, 80, 63,230,103, 12, 62, 76,204,168, 0, 0,128, 1, 0, 0, 2,255,
- 63,128, 0, 27, 63,230,103, 10, 62, 76,204,184, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,204, 63,230,103, 10, 62, 76,204,200,
- 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8, 62, 76,204,216, 0, 0,128, 1, 0, 0, 2,255, 63,179, 51, 80,
- 63,230,103, 12,190, 76,204,244, 0, 0,128, 1, 0, 0, 2,255, 63,128, 0, 27, 63,230,103, 10,190, 76,204,228, 0, 0,128, 1,
- 0, 0, 2,255, 63, 25,153,204, 63,230,103, 10,190, 76,204,212, 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8,
-190, 76,204,196, 0, 0,128, 1, 0, 0, 2,255, 63,179, 51, 80, 63,230,103, 12,191, 25,153,168, 0, 0,128, 1, 0, 0, 2,255,
- 63,128, 0, 27, 63,230,103, 10,191, 25,153,164, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,204, 63,230,103, 10,191, 25,153,160,
- 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8,191, 25,153,156, 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140,
- 62, 76,209,204,191,127,255,255, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 62, 76,209,188,191,128, 0, 1, 0, 0, 0, 0,
-127,255, 2,255, 63,128, 0, 27, 62, 76,209,176,191,128, 0, 2, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 62, 76,209,160,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63, 25,154,221,191,127,255,254, 0, 0, 0, 0,127,255, 2,255,
- 63, 25,153,204, 63, 25,154,217,191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27, 63, 25,154,213,191,128, 0, 2,
- 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63, 25,154,209,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140,
- 63,128, 0,163,191,127,255,254, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 63,128, 0,162,191,128, 0, 0, 0, 0, 0, 0,
-127,255, 2,255, 63,128, 0, 27, 63,128, 0,160,191,128, 0, 2, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63,128, 0,158,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,152, 63,179, 51,216,191,127,255,254, 0, 0, 0, 0,127,255, 2,255,
- 63, 25,153,207, 63,179, 51,214,191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28, 63,179, 51,212,191,128, 0, 1,
- 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 81, 63,179, 51,210,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,230,102,133,
- 63, 25,154,206,191,128, 0, 4,165,127, 0, 0, 90,129, 2,255, 63,230,102,133, 63,179, 51,208,191,128, 0, 4,165,127, 0, 0,
- 90,129, 2,255,190, 76,205,128, 62, 76,201,116,191,128, 0, 5,127,255, 0, 0, 0, 0, 16,255,190, 76,205,136, 63,127,255, 48,
-191,128, 0, 5,127,255, 0, 0, 0, 0, 16,255,190, 76,205,112,190, 76,208, 64,191, 25,153,156,127,255, 0, 0, 0, 0, 16,255,
-190, 76,205,112, 62, 76,201, 84,191, 25,153,160,127,255, 0, 0, 0, 0, 18,255,190, 76,205,120, 63, 25,152,190,191, 25,153,164,
-127,255, 0, 0, 0, 0, 18,255,190, 76,205,152, 63,127,255, 46,191, 25,153,168,127,255, 0, 0, 0, 0, 18,255,190, 76,205,112,
-190, 76,208, 64,190, 76,204,195,127,255, 0, 0, 0, 0, 16,255,190, 76,205,112, 62, 76,201, 84,190, 76,204,211,127,255, 0, 0,
- 0, 0, 18,255,190, 76,205,120, 63, 25,152,190,190, 76,204,227,127,255, 0, 0, 0, 0, 18,255,190, 76,205,152, 63,127,255, 46,
-190, 76,204,243,127,255, 0, 0, 0, 0, 18,255,190, 76,205,112,190, 76,208, 64, 62, 76,204,221,127,255, 0, 0, 0, 0, 16,255,
-190, 76,205,112, 62, 76,201, 84, 62, 76,204,205,127,255, 0, 0, 0, 0, 18,255,190, 76,205,120, 63, 25,152,190, 62, 76,204,189,
-127,255, 0, 0, 0, 0, 18,255,190, 76,205,152, 63,127,255, 46, 62, 76,204,173,127,255, 0, 0, 0, 0, 18,255,190, 76,205,112,
-190, 76,208, 64, 63, 25,153,160,127,255, 0, 0, 0, 0, 16,255,190, 76,205,112, 62, 76,201, 84, 63, 25,153,156,127,255, 0, 0,
- 0, 0, 18,255,190, 76,205,120, 63, 25,152,198, 63, 25,153,152,127,255, 0, 0, 0, 0, 18,255,190, 76,205,152, 63,127,255, 46,
- 63, 25,153,152,127,255, 0, 0, 0, 0, 18,255,190, 76,205,112,190, 76,208, 64,191,128, 0, 4,231, 94,231, 94,132,215, 16,255,
-190, 76,205,120, 63, 25,152,190,191,128, 0, 7,127,255, 0, 0, 0, 0, 16,255,190, 76,205, 96, 63,179, 50,251,191,128, 0, 4,
-127,255, 0, 0, 0, 0, 16,255,190, 76,205,128, 63,230,102, 48, 63, 25,153,156,127,255, 0, 0, 0, 0, 18,255,190, 76,205, 96,
- 63,179, 50,251, 63, 25,153,160,127,255, 0, 0, 0, 0, 18,255,190, 76,205,128, 63,230,102, 48, 62, 76,204,205,127,255, 0, 0,
- 0, 0, 18,255,190, 76,205, 96, 63,179, 50,251, 62, 76,204,221,127,255, 0, 0, 0, 0, 18,255,190, 76,205,128, 63,230,102, 48,
-190, 76,204,211,127,255, 0, 0, 0, 0, 18,255,190, 76,205, 96, 63,179, 50,251,190, 76,204,195,127,255, 0, 0, 0, 0, 18,255,
-190, 76,205,128, 63,230,102, 48,191, 25,153,160,127,255, 0, 0, 0, 0, 18,255,190, 76,205, 96, 63,179, 50,251,191, 25,153,156,
-127,255, 0, 0, 0, 0, 18,255,190, 76,205,144, 63,230,103, 10,191,128, 0, 5,243,161,111, 93,194, 34, 16,255,190, 76,205,144,
- 63,230,103, 10, 63,127,255,148,243,161,111, 93, 61,222, 16,255,190, 76,205, 96, 63,179, 50,251, 63,127,255,150,127,255, 0, 0,
- 0, 0, 16,255,190, 76,205,120, 63, 25,152,190, 63,127,255,144,127,255, 0, 0, 0, 0, 16,255,190, 76,205,112,190, 76,208, 64,
- 63,127,255,150,231, 94,231, 94,123, 41, 16,255,190, 76,205,136, 63,127,255, 48, 63,127,255,148,127,255, 0, 0, 0, 0, 16,255,
-190, 76,205,128, 62, 76,201,116, 63,127,255,148,127,255, 0, 0, 0, 0, 16,255, 63,179, 51, 36,190, 76,208, 56,191, 25,153,157,
- 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80,191, 25,153,161, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,
-190, 76,208, 80,191, 25,153,165, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,191, 25,153,169, 0, 0,127,255,
- 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56,190, 76,204,198, 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80,
-190, 76,204,214, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80,190, 76,204,230, 0, 0,127,255, 0, 0, 3,255,
- 62, 76,204, 44,190, 76,208,104,190, 76,204,246, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56, 62, 76,204,218,
- 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80, 62, 76,204,202, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,
-190, 76,208, 80, 62, 76,204,186, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104, 62, 76,204,170, 0, 0,127,255,
- 0, 0, 3,255, 63,179, 51, 34,190, 76,208, 56, 63, 25,153,159, 0, 0,127,255, 0, 0, 3,255, 63,127,255,220,190, 76,208, 80,
- 63, 25,153,155, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,114,190, 76,208, 80, 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255,
- 62, 76,204, 36,190, 76,208,104, 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56,191,128, 0, 4,
- 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80,191,128, 0, 5, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,
-190, 76,208, 80,191,128, 0, 7, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,191,128, 0, 8, 0, 0,127,255,
- 0, 0, 3,255, 63,230,102,136,190, 76,208, 88,191,128, 0, 8, 0, 0,127,255, 0, 0, 3,255, 63,230,102,135,190, 76,208, 88,
- 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255, 63,230,102,136,190, 76,208, 88, 62, 76,204,170, 0, 0,127,255, 0, 0, 3,255,
- 63,230,102,136,190, 76,208, 88,190, 76,204,246, 0, 0,127,255, 0, 0, 3,255, 63,230,102,136,190, 76,208, 88,191, 25,153,169,
- 0, 0,127,255, 0, 0, 3,255,190, 76,205,112,190, 76,208, 64,191, 25,153,156, 0, 0,127,255, 0, 0, 1,255,190, 76,205,112,
-190, 76,208, 64,190, 76,204,195, 0, 0,127,255, 0, 0, 1,255,190, 76,205,112,190, 76,208, 64, 62, 76,204,221, 0, 0,127,255,
- 0, 0, 1,255,190, 76,205,112,190, 76,208, 64, 63, 25,153,160, 0, 0,127,255, 0, 0, 1,255,190, 76,205,112,190, 76,208, 64,
-191,128, 0, 4, 0, 0,127,255, 0, 0, 3,255,190, 76,205,112,190, 76,208, 64, 63,127,255,150, 0, 0,127,255, 0, 0, 3,255,
- 63,230,102,136,190, 76,208, 88, 63,127,255,142, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104, 63,127,255,142,
- 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80, 63,127,255,144, 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,
-190, 76,208, 80, 63,127,255,148, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56, 63,127,255,150, 0, 0,127,255,
- 0, 0, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,210,224, 0, 0, 0,242, 0, 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, 5, 32, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0, 80,153,166, 2, 51, 0, 0, 0, 1, 0, 0, 0,240, 0, 18, 3,136,161,165, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 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,
+144,171,128, 2, 32, 5,167, 2, 40,176,131, 2, 0, 0, 0, 0,224, 11,131, 2, 72, 6,155, 2, 0, 0, 0, 0, 80,102, 8, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216,144,150, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
+ 96, 76,150, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,192,166,132, 2, 3, 0, 0, 0, 5, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0,188, 0, 0, 0, 53, 1, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+213,204, 76, 63,255,204, 76, 63, 0, 0,104,182, 30, 0,128, 63,140, 0,128, 63,214,255,127, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,144,171,128, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 44, 1, 0, 0,216,144,150, 2, 21, 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,224, 11,131, 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, 68, 65, 84, 65,
- 0, 0, 14,124, 5, 32, 24, 32, 0, 0, 0, 53, 0, 0, 1, 53, 0, 0, 0, 21, 0, 0, 0, 82, 0, 0, 0, 34, 0, 0, 0, 20,
- 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0, 19, 0, 0, 0, 84, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 85, 0, 0, 0, 34,
- 0, 0, 0, 22, 0, 0, 0, 76, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 54,
- 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 34, 0, 0, 0, 27, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 29,
- 0, 0, 0, 48, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 34,
- 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 9,
- 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 7,
- 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 34,
- 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 13, 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 13,
- 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 7,
- 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 34,
- 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 17, 0, 0, 0, 34, 0, 0, 0, 16, 0, 0, 0, 17,
- 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 11,
- 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 14, 0, 0, 0, 34,
- 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 20,
- 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 19, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 18, 0, 0, 0, 34, 0, 0, 0, 22,
- 0, 0, 0, 26, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 22, 0, 0, 0, 34,
- 0, 0, 0, 17, 0, 0, 0, 23, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 25,
- 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 26, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 0,
- 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 29, 0, 0, 0, 34,
- 0, 0, 0, 21, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 29, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 28,
- 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 32,
- 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 34,
- 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 15, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 16, 0, 0, 0, 32,
- 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 31, 0, 0, 0, 34, 0, 0, 0, 40, 0, 0, 0, 98, 0, 0, 0, 34, 0, 0, 0, 39,
- 0, 0, 0, 99, 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0,100, 0, 0, 0, 34, 0, 0, 0, 37, 0, 0, 0,101, 0, 0, 0, 34,
- 0, 0, 0, 41, 0, 0, 0, 72, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0, 39,
- 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 34, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 34, 0, 0, 0, 51,
- 0, 0, 0,109, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0,101, 0, 0, 0, 34, 0, 0, 0, 68, 0, 0, 0, 94, 0, 0, 0, 34,
- 0, 0, 0, 64, 0, 0, 0, 90, 0, 0, 0, 34, 0, 0, 0, 60, 0, 0, 0, 86, 0, 0, 0, 34, 0, 0, 0, 56, 0, 0, 0, 82,
- 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 78, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0,114, 0, 0, 0, 34, 0, 0, 0, 65,
- 0, 0, 0,114, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0,115, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0,115, 0, 0, 0, 34,
- 0, 0, 0, 51, 0, 0, 0,115, 0, 0, 0, 34, 0, 0, 0, 51, 0, 0, 0,114, 0, 0, 0, 34, 0, 0, 0, 42, 0, 0, 0, 50,
- 0, 0, 0, 34, 0, 0, 0, 43, 0, 0, 0, 45, 0, 0, 0, 34, 0, 0, 0, 42, 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 42,
- 0, 0, 0, 44, 0, 0, 0, 34, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 34, 0, 0, 0, 44, 0, 0, 0, 46, 0, 0, 0, 34,
- 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 48,
- 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 54,
- 0, 0, 0, 55, 0, 0, 0, 34, 0, 0, 0, 53, 0, 0, 0, 54, 0, 0, 0, 34, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 34,
- 0, 0, 0, 59, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 59,
- 0, 0, 0, 34, 0, 0, 0, 54, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 53,
- 0, 0, 0, 57, 0, 0, 0, 34, 0, 0, 0, 60, 0, 0, 0, 64, 0, 0, 0, 34, 0, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 34,
- 0, 0, 0, 59, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 62, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 62,
- 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 34, 0, 0, 0, 64,
- 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 63, 0, 0, 0, 67, 0, 0, 0, 34,
- 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 34, 0, 0, 0, 62, 0, 0, 0, 66, 0, 0, 0, 34, 0, 0, 0, 65, 0, 0, 0, 66,
- 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 51,
- 0, 0, 0, 66, 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 57, 0, 0, 0, 34,
- 0, 0, 0, 44, 0, 0, 0, 61, 0, 0, 0, 34, 0, 0, 0, 42, 0, 0, 0, 65, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0,110,
- 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0,106, 0, 0, 0, 34, 0, 0, 0, 71, 0, 0, 0,102, 0, 0, 0, 34, 0, 0, 0, 72,
- 0, 0, 0, 98, 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 74, 0, 0, 0, 93, 0, 0, 0, 34,
- 0, 0, 0, 75, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0, 76, 0, 0, 0, 85, 0, 0, 0, 34, 0, 0, 0, 77, 0, 0, 0, 81,
- 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 0, 77, 0, 0, 0, 34, 0, 0, 0, 74,
- 0, 0, 0, 75, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0, 77, 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 0,110, 0, 0, 0, 34,
- 0, 0, 0, 80, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0,112, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 0,113,
- 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0, 80, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0, 85, 0, 0, 0, 34, 0, 0, 0, 83,
- 0, 0, 0, 84, 0, 0, 0, 34, 0, 0, 0, 82, 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 0, 89, 0, 0, 0, 34,
- 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0, 88, 0, 0, 0, 34, 0, 0, 0, 87, 0, 0, 0, 88,
- 0, 0, 0, 34, 0, 0, 0, 83, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0, 82,
- 0, 0, 0, 86, 0, 0, 0, 34, 0, 0, 0, 89, 0, 0, 0, 93, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, 34,
- 0, 0, 0, 88, 0, 0, 0, 92, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 34, 0, 0, 0, 87, 0, 0, 0, 91,
- 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0, 90, 0, 0, 0, 34, 0, 0, 0, 93,
- 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0, 96, 0, 0, 0, 34,
- 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 0, 95, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 0, 95,
- 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0, 94, 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 80,
- 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0, 95, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 0, 94, 0, 0, 0, 34,
- 0, 0, 0,101, 0, 0, 0,105, 0, 0, 0, 34, 0, 0, 0,100, 0, 0, 0,101, 0, 0, 0, 34, 0, 0, 0,100, 0, 0, 0,104,
- 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,103, 0, 0, 0, 34, 0, 0, 0, 98,
- 0, 0, 0, 99, 0, 0, 0, 34, 0, 0, 0, 98, 0, 0, 0,102, 0, 0, 0, 34, 0, 0, 0,105, 0, 0, 0,114, 0, 0, 0, 34,
- 0, 0, 0,105, 0, 0, 0,109, 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,105, 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,108,
- 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 0,104, 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0,102,
- 0, 0, 0,103, 0, 0, 0, 34, 0, 0, 0,102, 0, 0, 0,106, 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,113, 0, 0, 0, 34,
- 0, 0, 0,108, 0, 0, 0,109, 0, 0, 0, 34, 0, 0, 0,108, 0, 0, 0,112, 0, 0, 0, 34, 0, 0, 0,107, 0, 0, 0,108,
- 0, 0, 0, 34, 0, 0, 0,107, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0,106, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0,106,
- 0, 0, 0,110, 0, 0, 0, 34, 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0, 34, 0, 0, 0,112, 0, 0, 0,113, 0, 0, 0, 34,
- 0, 0, 0,111, 0, 0, 0,112, 0, 0, 0, 34, 0, 0, 0,110, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0,121, 0, 0, 0,144,
- 0, 0, 0, 50, 0, 0, 0,125, 0, 0, 0,142, 0, 0, 0, 50, 0, 0, 0,129, 0, 0, 0,140, 0, 0, 0, 50, 0, 0, 0,133,
- 0, 0, 0,138, 0, 0, 0, 50, 0, 0, 0,120, 0, 0, 0,135, 0, 0, 0, 50, 0, 0, 0,118, 0, 0, 0,134, 0, 0, 0,178,
- 0, 0, 0,121, 0, 0, 0,125, 0, 0, 0, 50, 0, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 50, 0, 0, 0,120, 0, 0, 0,124,
- 0, 0, 0, 50, 0, 0, 0,120, 0, 0, 0,119, 0, 0, 0, 50, 0, 0, 0,119, 0, 0, 0,123, 0, 0, 0, 50, 0, 0, 0,118,
- 0, 0, 0,119, 0, 0, 0, 50, 0, 0, 0,118, 0, 0, 0,122, 0, 0, 0, 50, 0, 0, 0,125, 0, 0, 0,129, 0, 0, 0, 50,
- 0, 0, 0,124, 0, 0, 0,125, 0, 0, 0, 50, 0, 0, 0,124, 0, 0, 0,128, 0, 0, 0, 50, 0, 0, 0,123, 0, 0, 0,124,
- 0, 0, 0, 50, 0, 0, 0,123, 0, 0, 0,127, 0, 0, 0, 50, 0, 0, 0,122, 0, 0, 0,123, 0, 0, 0, 50, 0, 0, 0,122,
- 0, 0, 0,126, 0, 0, 0,178, 0, 0, 0,129, 0, 0, 0,133, 0, 0, 0, 50, 0, 0, 0,128, 0, 0, 0,129, 0, 0, 0, 50,
- 0, 0, 0,128, 0, 0, 0,132, 0, 0, 0, 50, 0, 0, 0,127, 0, 0, 0,128, 0, 0, 0, 50, 0, 0, 0,127, 0, 0, 0,131,
- 0, 0, 0, 50, 0, 0, 0,126, 0, 0, 0,127, 0, 0, 0, 50, 0, 0, 0,126, 0, 0, 0,130, 0, 0, 0, 50, 0, 0, 0,132,
- 0, 0, 0,133, 0, 0, 0, 50, 0, 0, 0,131, 0, 0, 0,132, 0, 0, 0, 50, 0, 0, 0,130, 0, 0, 0,131, 0, 0, 0, 50,
- 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0, 50, 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0, 50, 0, 0, 0,139, 0, 0, 0,140,
- 0, 0, 0, 50, 0, 0, 0,137, 0, 0, 0,139, 0, 0, 0, 50, 0, 0, 0,140, 0, 0, 0,142, 0, 0, 0, 50, 0, 0, 0,141,
- 0, 0, 0,142, 0, 0, 0, 50, 0, 0, 0,142, 0, 0, 0,144, 0, 0, 0, 50, 0, 0, 0,143, 0, 0, 0,144, 0, 0, 0, 50,
- 0, 0, 0,141, 0, 0, 0,143, 0, 0, 0, 50, 0, 0, 0,136, 0, 0, 0,144, 0, 0, 0, 50, 0, 0, 0,117, 0, 0, 0,135,
- 0, 0, 0,178, 0, 0, 0,116, 0, 0, 0,135, 0, 0, 0, 50, 0, 0, 0,116, 0, 0, 0,134, 0, 0, 0,178, 0, 0, 0,119,
- 0, 0, 0,116, 0, 0, 0, 50, 0, 0, 0,117, 0, 0, 0,121, 0, 0, 0, 50, 0, 0, 0,117, 0, 0, 0,136, 0, 0, 0, 50,
- 0, 0, 0,136, 0, 0, 0,145, 0, 0, 0,178, 0, 0, 0,146, 0, 0, 0,147, 0, 0, 0,178, 0, 0, 0,147, 0, 0, 0,150,
- 0, 0, 0, 50, 0, 0, 0,149, 0, 0, 0,151, 0, 0, 0,178, 0, 0, 0,148, 0, 0, 0,151, 0, 0, 0, 50, 0, 0, 0,148,
- 0, 0, 0,150, 0, 0, 0,178, 0, 0, 0,138, 0, 0, 0,147, 0, 0, 0, 50, 0, 0, 0,130, 0, 0, 0,149, 0, 0, 0,178,
- 0, 0, 0,131, 0, 0, 0,151, 0, 0, 0, 50, 0, 0, 0,132, 0, 0, 0,148, 0, 0, 0, 50, 0, 0, 0,133, 0, 0, 0,150,
- 0, 0, 0, 50, 0, 0, 0,155, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0,153,
- 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 0,159, 0, 0, 0, 35,
- 0, 0, 0,154, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 0,154,
- 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 0,152,
- 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 0,159, 0, 0, 0, 35,
- 0, 0, 0,158, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 0,161,
- 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 0,163,
- 0, 0, 0,167, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,166, 0, 0, 0, 35,
- 0, 0, 0,161, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 0,165, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 0,161,
- 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,167, 0, 0, 0, 35, 0, 0, 0,165,
- 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,165, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 0,170, 0, 0, 0, 35,
- 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,172,
- 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,156,
- 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 0,181, 0, 0, 0, 35,
- 0, 0, 0,177, 0, 0, 0,178, 0, 0, 0,163, 0, 0, 0,178, 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 0,180,
- 0, 0, 0,163, 0, 0, 0,171, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,163,
- 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 0,177, 0, 0, 0, 35,
- 0, 0, 0,182, 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 0,186,
- 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 0,183, 0, 0, 0, 35, 0, 0, 0,164,
- 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,185, 0, 0, 0, 35,
- 0, 0, 0,167, 0, 0, 0,184, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,212, 16, 0, 0, 0,242, 0, 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, 5, 32, 40, 32, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0,
- 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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, 32, 48, 32, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 5, 32, 62, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 5,240, 5, 32, 40, 32, 0, 0, 0, 52, 0, 0, 0, 76, 0, 0, 0, 18, 0, 0, 0, 22,
- 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0,
- 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 9,
- 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 9,
- 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 11,
- 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 13,
- 0, 0, 0, 17, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 14, 0, 0, 0, 0,
- 0, 0, 0, 17, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 32,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 42,
- 0, 0, 0, 65, 0, 0, 0,114, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0, 44, 0, 0, 0, 42, 0, 0, 0, 43,
- 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 48,
- 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 1, 0, 0, 0, 53, 0, 0, 0, 48, 0, 0, 0, 0,
- 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 60,
- 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 54, 0, 0, 0, 58, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 58,
- 0, 0, 0, 59, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 67,
- 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 62, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, 0, 51,
- 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 22, 0, 0, 0, 76, 0, 0, 0, 85, 0, 0, 0, 0,
- 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 84, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 82,
- 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 85, 0, 0, 0, 89, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 82,
- 0, 0, 0, 83, 0, 0, 0, 87, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 75, 0, 0, 0, 74, 0, 0, 0, 93,
- 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 88, 0, 0, 0, 92, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 86,
- 0, 0, 0, 90, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, 97, 0, 0, 0, 96, 0, 0, 0, 0,
- 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 95, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 73, 0, 0, 0, 77,
- 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 78,
- 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0,101,
- 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 99, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 72,
- 0, 0, 0, 41, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0,104, 0, 0, 0,100, 0, 0, 0,101, 0, 0, 0, 0,
- 0, 0, 0,103, 0, 0, 0,102, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0,109, 0, 0, 0,105,
- 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0,108, 0, 0, 0,107, 0, 0, 0,103, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0,106,
- 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0,112, 0, 0, 0,108, 0, 0, 0,109,
- 0, 0, 0, 0, 0, 0, 0,111, 0, 0, 0,110, 0, 0, 0,106, 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0,115,
- 0, 0, 0, 52, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 80, 0, 0, 0,111, 0, 0, 0,112, 0, 0, 0, 0,
- 0, 0, 0, 81, 0, 0, 0, 77, 0, 0, 0, 69, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0,135, 0, 0, 0,120,
- 0, 0, 0,119, 0, 0, 0, 16, 0, 0, 0,125, 0, 0, 0,124, 0, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 16, 0, 0, 0,123,
- 0, 0, 0,122, 0, 0, 0,118, 0, 0, 0,119, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 0,127, 0, 0, 0,123, 0, 0, 0,124,
- 0, 0, 0, 16, 0, 0, 0,133, 0, 0, 0,132, 0, 0, 0,128, 0, 0, 0,129, 0, 0, 0, 16, 0, 0, 0,131, 0, 0, 0,130,
- 0, 0, 0,126, 0, 0, 0,127, 0, 0, 0, 16, 0, 0, 0,148, 0, 0, 0,151, 0, 0, 0,131, 0, 0, 0,132, 0, 0, 0, 16,
- 0, 0, 0,147, 0, 0, 0,150, 0, 0, 0,133, 0, 0, 0,138, 0, 0, 0, 16, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,140,
- 0, 0, 0,139, 0, 0, 0, 16, 0, 0, 0,140, 0, 0, 0,129, 0, 0, 0,125, 0, 0, 0,142, 0, 0, 0, 16, 0, 0, 0,141,
- 0, 0, 0,142, 0, 0, 0,144, 0, 0, 0,143, 0, 0, 0, 16, 0, 0, 0,144, 0, 0, 0,121, 0, 0, 0,117, 0, 0, 0,136,
- 0, 0, 0, 16, 0, 0, 0,171, 0, 0, 0,181, 0, 0, 0,177, 0, 0, 0,155, 0, 0, 0, 2, 0, 0, 0,154, 0, 0, 0,153,
- 0, 0, 0,169, 0, 0, 0,170, 0, 0, 0, 2, 0, 0, 0,152, 0, 0, 0,176, 0, 0, 0,172, 0, 0, 0,168, 0, 0, 0, 2,
- 0, 0, 0,159, 0, 0, 0,158, 0, 0, 0,154, 0, 0, 0,155, 0, 0, 0, 2, 0, 0, 0,157, 0, 0, 0,156, 0, 0, 0,152,
- 0, 0, 0,153, 0, 0, 0, 2, 0, 0, 0,179, 0, 0, 0,163, 0, 0, 0,159, 0, 0, 0,178, 0, 0, 0, 2, 0, 0, 0,162,
- 0, 0, 0,161, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0, 2, 0, 0, 0,160, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0,156,
- 0, 0, 0, 2, 0, 0, 0,167, 0, 0, 0,166, 0, 0, 0,162, 0, 0, 0,163, 0, 0, 0, 2, 0, 0, 0,165, 0, 0, 0,164,
- 0, 0, 0,160, 0, 0, 0,161, 0, 0, 0, 2, 0, 0, 0,182, 0, 0, 0,184, 0, 0, 0,167, 0, 0, 0,180, 0, 0, 0, 2,
- 0, 0, 0,185, 0, 0, 0,186, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0, 2, 0, 0, 0,187, 0, 0, 0,183, 0, 0, 0,173,
- 0, 0, 0,164, 0, 0, 0, 2, 68, 65, 84, 65, 0, 0, 13, 16, 5, 32, 48, 32, 0, 0, 0, 60, 0, 0, 0, 76, 63, 27,168,250,
- 59, 93,211, 96, 62,203,162, 84, 59, 93,211, 96, 62,203,162, 84, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96, 0, 0, 0, 0,
- 61, 0, 0, 1, 0, 0, 0, 0, 63,131,172, 21, 59, 93,211, 96, 63, 81,128,146, 59, 93,211, 96, 63, 81,128,149, 59, 93,211, 96,
- 63,131,172, 22, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,227, 59, 93,211, 96, 63,185,131,174,
- 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96, 63,158,151,225, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 63, 81,128,149, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96, 63, 27,168,246, 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,227, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 63,131,172, 24,
- 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 27,168,246, 59, 93,211, 96,
- 62,203,162, 86, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1,
- 0, 0, 0, 0, 63,131,172, 24, 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63,131,172, 21,
- 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,185,131,174, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96,
- 63,158,151,226, 59, 93,211, 96, 63,185,131,176, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 81,128,144,
- 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 0, 0, 0, 0,
- 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,131,172, 21, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96,
- 63,158,151,224, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 27,168,247, 59, 93,211, 96, 62,203,162, 85,
- 59, 93,211, 96, 62,203,162, 86, 59, 93,211, 96, 63, 27,168,248, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 63,131,172, 22, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,185,131,176, 59, 93,211, 96, 63,185,131,174,
- 59, 93,211, 96, 63,158,151,224, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76,
- 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161,
- 63, 3, 28,210, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236,
- 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,161,
- 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 72, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236,
- 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52,
- 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,174, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,172,
- 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102,
- 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52,
- 63,141,179,111, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102,
- 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 56,
- 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,190,118,127, 56, 63, 3, 28,220,190,118,127, 56, 63, 3, 28,220,
-189,188,105, 96, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200,
- 63, 79, 65,244, 61,104, 84,200, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 0,188,190, 63,160,188,171, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,200, 63, 79, 65,242,189,188,105, 96, 63, 41, 47,120,189,188,105,128,
- 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113,
- 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128,
- 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242,
- 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188,
- 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120,
- 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26,
- 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
-189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160,
- 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113,
- 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63,140,131,180, 62,186, 19,116, 63,159,140,244, 63, 3, 28, 50, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 42,
- 63, 3, 28,244, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 62,186, 21, 0, 63, 38,207, 51, 62, 91,224, 24,
- 63, 76,226,112, 61,135, 38, 64, 63,114,244,240, 62, 91,221, 4, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,185,
- 61,135, 44, 96, 62,181, 84, 61,189,169,104,176, 63, 0,189, 93,190,109, 1, 80, 63, 38,207,248,189,169,109,144, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 63, 41, 47,116, 63, 38,207, 52, 63, 3, 28,248, 63, 76,225,174, 62,186, 21, 0,
- 63,114,244, 42, 63, 3, 28,244, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,185, 62,186, 21, 0, 62,181, 84,122,
- 62, 91,224, 32, 63, 0,188,185, 61,135, 44, 96, 63, 38,207, 51, 62, 91,224, 24, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63, 79, 65,236, 63, 76,225,174, 63, 41, 47,116, 63,114,244, 44, 63, 79, 65,236,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188, 63, 41, 47,120, 62,181, 84,122, 63, 3, 28,248, 63, 0,188,185,
- 62,186, 21, 0, 63, 38,207, 52, 63, 3, 28,248, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 14, 62,186, 21, 0,
- 61,104, 82,144, 62, 91,223,128, 62, 82, 94,138, 61,135, 43, 48, 62,181, 84,122, 62, 91,224, 32, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63, 0,188,190, 63,117, 84,102, 62,181, 84,127, 63, 79, 65,242, 63, 0,188,188, 63, 41, 47,120, 63, 38,207, 52,
- 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63, 41, 47,120, 61,104, 84,160, 63, 3, 29, 0,
- 62, 82, 95, 14, 62,186, 21, 0, 62,181, 84,122, 63, 3, 28,248, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,190,
- 63,117, 84,102, 63, 38,207, 56, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63, 41, 47,120,
- 62,181, 84,127, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64,
- 63, 3, 28,216,189,188,106,128, 62,186, 20,176, 61,104, 84,160, 63, 3, 29, 0, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,207, 56, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172,
- 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111,
- 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172,
- 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102,
- 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 52,
- 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111,
- 63, 76,225,174, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 72, 63,114,244, 44,
- 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44,
- 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210,
- 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99,
- 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,
- 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26,
- 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,
-189,188,105,128, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26,
- 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122,
- 63,141,179,113, 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102,
- 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128,
- 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102,
- 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,200,
- 63, 79, 65,242,189,188,105, 96, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,190, 63,160,188,171, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113,
- 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200,
- 63, 79, 65,244, 61,104, 84,200, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
-189,188,105, 96, 63, 41, 47,120,190,118,127, 56, 63, 3, 28,220,190,118,127, 56, 63, 3, 28,220,189,188,105, 96, 63, 41, 47,120,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 4,192, 5, 32, 62, 32, 0, 0, 0, 57, 0, 0, 1, 48,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 68, 65, 84, 65, 0, 0, 17,208, 5, 30, 70, 32, 0, 0, 0, 51, 0, 0, 0, 76, 0, 0, 0, 0, 63, 27,168,250, 59, 93,211, 96,
- 62,203,162, 84, 59, 93,211, 96, 62,203,162, 84, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131,172, 21, 59, 93,211, 96, 63, 81,128,146,
- 59, 93,211, 96, 63, 81,128,149, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,158,151,227, 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96,
- 63,185,131,174, 59, 93,211, 96, 63,158,151,225, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 81,128,149, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96, 63, 27,168,246,
- 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,158,151,227, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 63,131,172, 24, 59, 93,211, 96,
- 63,158,151,226, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 27,168,246, 59, 93,211, 96, 62,203,162, 86, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96, 63, 27,168,247,
- 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,131,172, 24, 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63,131,172, 21, 59, 93,211, 96,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,185,131,174,
- 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 63,185,131,176, 59, 93,211, 96,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 81,128,144, 59, 93,211, 96,
- 63, 27,168,247, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,131,172, 21,
- 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 63,158,151,224, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 27,168,247, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96,
- 62,203,162, 86, 59, 93,211, 96, 63, 27,168,248, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131,172, 22, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63, 81,128,144,
- 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,185,131,176, 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96,
- 63,158,151,224, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99,
- 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99,
- 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210,
- 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 72, 63,114,244, 44,
- 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,
- 63, 38,207, 52, 63,141,179,111, 63, 76,225,174, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188,
- 63,160,188,173, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102,
- 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172,
- 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44,
- 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 56, 63,141,179,111,
- 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,190,118,127, 56,
- 63, 3, 28,220,190,118,127, 56, 63, 3, 28,220,189,188,105, 96, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200, 63, 79, 65,244,
- 61,104, 84,200, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,190, 63,160,188,171, 62,181, 84,122, 63,141,179,113, 62,181, 84,122,
- 63,141,179,113, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,200, 63, 79, 65,242,189,188,105, 96, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120,
- 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122,
- 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26,
- 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173,
- 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128,
- 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102,
- 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64,
- 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242,
- 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 62,181, 84,122,
- 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,140,131,180, 62,186, 19,116, 63,159,140,244, 63, 3, 28, 50, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 42, 63, 3, 28,244,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174,
- 62,186, 21, 0, 63, 38,207, 51, 62, 91,224, 24, 63, 76,226,112, 61,135, 38, 64, 63,114,244,240, 62, 91,221, 4,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,185, 61,135, 44, 96,
- 62,181, 84, 61,189,169,104,176, 63, 0,189, 93,190,109, 1, 80, 63, 38,207,248,189,169,109,144,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174, 63, 41, 47,116, 63, 38,207, 52,
- 63, 3, 28,248, 63, 76,225,174, 62,186, 21, 0, 63,114,244, 42, 63, 3, 28,244,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,185, 62,186, 21, 0, 62,181, 84,122, 62, 91,224, 32,
- 63, 0,188,185, 61,135, 44, 96, 63, 38,207, 51, 62, 91,224, 24,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63, 79, 65,236, 63, 76,225,174,
- 63, 41, 47,116, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63, 41, 47,120, 62,181, 84,122, 63, 3, 28,248, 63, 0,188,185, 62,186, 21, 0,
- 63, 38,207, 52, 63, 3, 28,248,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 82, 95, 14, 62,186, 21, 0, 61,104, 82,144, 62, 91,223,128, 62, 82, 94,138, 61,135, 43, 48, 62,181, 84,122,
- 62, 91,224, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 0,188,190, 63,117, 84,102, 62,181, 84,127, 63, 79, 65,242, 63, 0,188,188, 63, 41, 47,120, 63, 38,207, 52, 63, 79, 65,236,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26,
- 63, 41, 47,120, 61,104, 84,160, 63, 3, 29, 0, 62, 82, 95, 14, 62,186, 21, 0, 62,181, 84,122, 63, 3, 28,248,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,190, 63,117, 84,102,
- 63, 38,207, 56, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160,
- 63, 79, 65,242, 62, 82, 95, 26, 63, 41, 47,120, 62,181, 84,127, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,
-189,188,106,128, 62,186, 20,176, 61,104, 84,160, 63, 3, 29, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 56, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172,
- 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102,
- 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52,
- 63,141,179,111,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44,
- 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111,
- 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52,
- 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,174, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 72, 63,114,244, 44, 63, 79, 65,236,
- 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99,
- 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236,
- 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161,
- 63, 3, 28,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122,
- 63,141,179,113, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102,
- 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64,
- 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102,
- 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128,
- 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113,
- 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26,
- 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122,
- 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,200, 63, 79, 65,242,
-189,188,105, 96, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,190, 63,160,188,171, 62,181, 84,122,
- 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200, 63, 79, 65,244,
- 61,104, 84,200, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,190,118,127, 56, 63, 3, 28,220,190,118,127, 56,
- 63, 3, 28,220,189,188,105, 96, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,236,213, 64, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,218, 64, 2,236,208,112,
- 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 49, 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, 2,235,202, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236,214,128, 5, 32,118, 32, 5, 32,124, 32, 5, 30, 70, 32, 5, 32, 86, 32, 5, 32,102, 32, 0, 0, 0, 0, 5, 32,138, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,214,176, 0, 0, 0, 1, 0, 0, 0, 5,
- 0, 0, 0, 20, 0, 0, 0, 0, 2,236,215,224, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 2,236,217, 16,
- 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 1, 45, 0, 0, 0, 74, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 63, 76,204,213, 63, 76,204,255,182,104, 0, 0, 63,128, 0, 30, 63,128, 0,140, 63,127,255,214,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,236,214,128, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,214,176, 0, 0, 0,242, 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, 5, 32, 86, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+176, 14, 0, 0,224, 11,131, 2, 57, 0, 0, 0,188, 0, 0, 0,133,102,230, 63,208, 51,179, 63,146,255,127, 63,127,165, 0, 0,
+129, 90, 2,255,133,102,230, 63,206,154, 25, 63,146,255,127, 63,127,165, 0, 0,129, 90, 2,255, 81, 51,179, 63,210, 51,179, 63,
+148,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63,212, 51,179, 63,152,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+207,153, 25, 63,214, 51,179, 63,154,255,127, 63, 0, 0, 0, 0,255,127, 2,255,152,205, 76, 62,216, 51,179, 63,156,255,127, 63,
+ 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,158, 0,128, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,
+160, 0,128, 63,150,255,127, 63, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,162, 0,128, 63,154,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,140,205, 76, 62,163, 0,128, 63,156,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,209,154, 25, 63,
+148,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,213,154, 25, 63,150,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+204,153, 25, 63,217,154, 25, 63,154,255,127, 63, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,221,154, 25, 63,156,255,127, 63,
+ 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,160,209, 76, 62,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,
+176,209, 76, 62,150,255,127, 63, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,188,209, 76, 62,152,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,140,205, 76, 62,204,209, 76, 62,154,255,127, 63, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62, 8,103,230, 63,
+148,255,127, 63, 0, 0,127,165,129, 90, 0,255,204,153, 25, 63, 10,103,230, 63,146,255,127, 63, 0, 0,127,165,129, 90, 0,255,
+ 27, 0,128, 63, 10,103,230, 63,142,255,127, 63, 0, 0,127,165,129, 90, 0,255, 80, 51,179, 63, 12,103,230, 63,140,255,127, 63,
+ 0, 0,127,165,129, 90, 0,255,152,205, 76,190, 12,103,230, 63,140,255,127, 63, 0, 0,127,165,129, 90, 0,255,152,205, 76,190,
+160,209, 76, 62,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,209,154, 25, 63,148,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,152,205, 76,190,158, 0,128, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,144,205, 76,190,210, 51,179, 63,
+148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,131,102,230, 63, 7,103,230, 63,148,255,127, 63, 0, 0,127,165,129, 90, 0,255,
+131,102,230, 63,160, 0,128, 63,142,255,127, 63,127,165, 0, 0,129, 90, 2,255,127,102,230, 63, 28,208, 76, 62,148,255,127, 63,
+127,165, 0, 0,129, 90, 2,255,146,205, 76,190, 72,208, 76,190,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,150,205, 76, 62,
+ 24,208, 76,190,156,255,127, 63, 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63, 40,208, 76,190,154,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255, 28, 0,128, 63, 56,208, 76,190,152,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 81, 51,179, 63, 72,208, 76,190,
+148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,133,102,230, 63, 88,208, 76,190,146,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+133,102,230, 63, 88,208, 76,190, 4, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 81, 51,179, 63, 72,208, 76,190, 3, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63, 56,208, 76,190, 1, 0,128,191, 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63,
+ 40,208, 76,190, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255,150,205, 76, 62, 24,208, 76,190,254,255,127,191, 0, 0, 0, 0,
+255,127, 2,255,146,205, 76,190, 72,208, 76,190, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,127,102,230, 63, 28,208, 76, 62,
+155,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,136,201, 76,190,159,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,
+127,102,230, 63, 28,208, 76, 62,193,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,136,201, 76,190,209,204, 76,190,
+ 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,219,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,
+136,201, 76,190,203,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,159,153, 25, 63, 1,128, 0, 0,
+ 0, 0, 2,255,131,102,230, 63,136,201, 76,190,155,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,
+ 3, 0,128,191,127,165, 0, 0,129, 90, 2,255,131,102,230, 63,160, 0,128, 63, 6, 0,128,191,127,165, 0, 0,129, 90, 2,255,
+131,102,230, 63, 7,103,230, 63, 3, 0,128,191, 0, 0,127,165,129, 90, 0,255,135,102,230, 63,207,154, 25, 63,151,153, 25, 63,
+ 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,156, 0,128, 63,151,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,
+212, 51,179, 63,155,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63, 7,103,230, 63,159,153, 25, 63,127,165,127,165,
+ 0, 0, 2,255,135,102,230, 63,207,154, 25, 63,171,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,
+187,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,203,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,
+131,102,230, 63, 7,103,230, 63,219,204, 76, 62,127,165,127,165, 0, 0, 2,255,135,102,230, 63,207,154, 25, 63,241,204, 76,190,
+ 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,225,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,
+212, 51,179, 63,209,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63, 7,103,230, 63,193,204, 76,190,127,165,127,165,
+ 0, 0, 2,255,135,102,230, 63,207,154, 25, 63,167,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,
+163,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,159,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,
+131,102,230, 63, 7,103,230, 63,155,153, 25,191,127,165,127,165, 0, 0, 2,255,144,205, 76,190,210, 51,179, 63, 3, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,158, 0,128, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,
+209,154, 25, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,160,209, 76, 62, 3, 0,128,191, 0, 0, 0, 0,
+255,127, 2,255,152,205, 76,190, 12,103,230, 63,168,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,152,205, 76,190, 12,103,230, 63,
+244,204, 76,190, 0, 0, 1,128, 0, 0, 2,255,152,205, 76,190, 12,103,230, 63,168,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255,
+144,205, 76,190, 12,103,230, 63,150,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255,152,205, 76,190, 12,103,230, 63, 7, 0,128,191,
+ 0, 0,127,165,129, 90, 0,255, 80, 51,179, 63, 12,103,230, 63, 7, 0,128,191, 0, 0,127,165,129, 90, 0,255, 27, 0,128, 63,
+ 10,103,230, 63, 6, 0,128,191, 0, 0,127,165,129, 90, 0,255,204,153, 25, 63, 10,103,230, 63, 4, 0,128,191, 0, 0,127,165,
+129, 90, 0,255,140,205, 76, 62, 8,103,230, 63, 3, 0,128,191, 0, 0,127,165,129, 90, 0,255, 81, 51,179, 63, 12,103,230, 63,
+150,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255, 28, 0,128, 63, 10,103,230, 63,150,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255,
+207,153, 25, 63, 10,103,230, 63,154,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255,152,205, 76, 62, 8,103,230, 63,158,153, 25, 63,
+ 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63, 12,103,230, 63,168,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63,
+ 10,103,230, 63,184,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255,204,153, 25, 63, 10,103,230, 63,200,204, 76, 62, 0, 0, 1,128,
+ 0, 0, 2,255,140,205, 76, 62, 8,103,230, 63,216,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63, 12,103,230, 63,
+244,204, 76,190, 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63, 10,103,230, 63,228,204, 76,190, 0, 0, 1,128, 0, 0, 2,255,
+204,153, 25, 63, 10,103,230, 63,212,204, 76,190, 0, 0, 1,128, 0, 0, 2,255,140,205, 76, 62, 8,103,230, 63,196,204, 76,190,
+ 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63, 12,103,230, 63,168,153, 25,191, 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63,
+ 10,103,230, 63,164,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,204,153, 25, 63, 10,103,230, 63,160,153, 25,191, 0, 0, 1,128,
+ 0, 0, 2,255,140,205, 76, 62, 8,103,230, 63,156,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,140,205, 76, 62,204,209, 76, 62,
+255,255,127,191, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,188,209, 76, 62, 1, 0,128,191, 0, 0, 0, 0,255,127, 2,255,
+ 27, 0,128, 63,176,209, 76, 62, 2, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,160,209, 76, 62, 3, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,221,154, 25, 63,254,255,127,191, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,
+217,154, 25, 63, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,213,154, 25, 63, 2, 0,128,191, 0, 0, 0, 0,
+255,127, 2,255, 80, 51,179, 63,209,154, 25, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,163, 0,128, 63,
+254,255,127,191, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,162, 0,128, 63, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255,
+ 27, 0,128, 63,160, 0,128, 63, 2, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,158, 0,128, 63, 3, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,152,205, 76, 62,216, 51,179, 63,254,255,127,191, 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63,
+214, 51,179, 63, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63,212, 51,179, 63, 1, 0,128,191, 0, 0, 0, 0,
+255,127, 2,255, 81, 51,179, 63,210, 51,179, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,133,102,230, 63,206,154, 25, 63,
+ 4, 0,128,191,127,165, 0, 0,129, 90, 2,255,133,102,230, 63,208, 51,179, 63, 4, 0,128,191,127,165, 0, 0,129, 90, 2,255,
+128,205, 76,190,116,201, 76, 62, 5, 0,128,191,255,127, 0, 0, 0, 0, 16,255,136,205, 76,190, 48,255,127, 63, 5, 0,128,191,
+255,127, 0, 0, 0, 0, 16,255,112,205, 76,190, 64,208, 76,190,156,153, 25,191,255,127, 0, 0, 0, 0, 16,255,112,205, 76,190,
+ 84,201, 76, 62,160,153, 25,191,255,127, 0, 0, 0, 0, 18,255,120,205, 76,190,190,152, 25, 63,164,153, 25,191,255,127, 0, 0,
+ 0, 0, 18,255,152,205, 76,190, 46,255,127, 63,168,153, 25,191,255,127, 0, 0, 0, 0, 18,255,112,205, 76,190, 64,208, 76,190,
+195,204, 76,190,255,127, 0, 0, 0, 0, 16,255,112,205, 76,190, 84,201, 76, 62,211,204, 76,190,255,127, 0, 0, 0, 0, 18,255,
+120,205, 76,190,190,152, 25, 63,227,204, 76,190,255,127, 0, 0, 0, 0, 18,255,152,205, 76,190, 46,255,127, 63,243,204, 76,190,
+255,127, 0, 0, 0, 0, 18,255,112,205, 76,190, 64,208, 76,190,221,204, 76, 62,255,127, 0, 0, 0, 0, 16,255,112,205, 76,190,
+ 84,201, 76, 62,205,204, 76, 62,255,127, 0, 0, 0, 0, 18,255,120,205, 76,190,190,152, 25, 63,189,204, 76, 62,255,127, 0, 0,
+ 0, 0, 18,255,152,205, 76,190, 46,255,127, 63,173,204, 76, 62,255,127, 0, 0, 0, 0, 18,255,112,205, 76,190, 64,208, 76,190,
+160,153, 25, 63,255,127, 0, 0, 0, 0, 16,255,112,205, 76,190, 84,201, 76, 62,156,153, 25, 63,255,127, 0, 0, 0, 0, 18,255,
+120,205, 76,190,198,152, 25, 63,152,153, 25, 63,255,127, 0, 0, 0, 0, 18,255,152,205, 76,190, 46,255,127, 63,152,153, 25, 63,
+255,127, 0, 0, 0, 0, 18,255,112,205, 76,190, 64,208, 76,190, 4, 0,128,191, 94,231, 94,231,215,132, 16,255,120,205, 76,190,
+190,152, 25, 63, 7, 0,128,191,255,127, 0, 0, 0, 0, 16,255, 96,205, 76,190,251, 50,179, 63, 4, 0,128,191,255,127, 0, 0,
+ 0, 0, 16,255,128,205, 76,190, 48,102,230, 63,156,153, 25, 63,255,127, 0, 0, 0, 0, 18,255, 96,205, 76,190,251, 50,179, 63,
+160,153, 25, 63,255,127, 0, 0, 0, 0, 18,255,128,205, 76,190, 48,102,230, 63,205,204, 76, 62,255,127, 0, 0, 0, 0, 18,255,
+ 96,205, 76,190,251, 50,179, 63,221,204, 76, 62,255,127, 0, 0, 0, 0, 18,255,128,205, 76,190, 48,102,230, 63,211,204, 76,190,
+255,127, 0, 0, 0, 0, 18,255, 96,205, 76,190,251, 50,179, 63,195,204, 76,190,255,127, 0, 0, 0, 0, 18,255,128,205, 76,190,
+ 48,102,230, 63,160,153, 25,191,255,127, 0, 0, 0, 0, 18,255, 96,205, 76,190,251, 50,179, 63,156,153, 25,191,255,127, 0, 0,
+ 0, 0, 18,255,144,205, 76,190, 10,103,230, 63, 5, 0,128,191,161,243, 93,111, 34,194, 16,255,144,205, 76,190, 10,103,230, 63,
+148,255,127, 63,161,243, 93,111,222, 61, 16,255, 96,205, 76,190,251, 50,179, 63,150,255,127, 63,255,127, 0, 0, 0, 0, 16,255,
+120,205, 76,190,190,152, 25, 63,144,255,127, 63,255,127, 0, 0, 0, 0, 16,255,112,205, 76,190, 64,208, 76,190,150,255,127, 63,
+ 94,231, 94,231, 41,123, 16,255,136,205, 76,190, 48,255,127, 63,148,255,127, 63,255,127, 0, 0, 0, 0, 16,255,128,205, 76,190,
+116,201, 76, 62,148,255,127, 63,255,127, 0, 0, 0, 0, 16,255, 36, 51,179, 63, 56,208, 76,190,157,153, 25,191, 0, 0,255,127,
+ 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,161,153, 25,191, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,
+165,153, 25,191, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190,169,153, 25,191, 0, 0,255,127, 0, 0, 3,255,
+ 36, 51,179, 63, 56,208, 76,190,198,204, 76,190, 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,214,204, 76,190,
+ 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,230,204, 76,190, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,
+104,208, 76,190,246,204, 76,190, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63, 56,208, 76,190,218,204, 76, 62, 0, 0,255,127,
+ 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,202,204, 76, 62, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,
+186,204, 76, 62, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190,170,204, 76, 62, 0, 0,255,127, 0, 0, 3,255,
+ 34, 51,179, 63, 56,208, 76,190,159,153, 25, 63, 0, 0,255,127, 0, 0, 3,255,220,255,127, 63, 80,208, 76,190,155,153, 25, 63,
+ 0, 0,255,127, 0, 0, 3,255,114,153, 25, 63, 80,208, 76,190,151,153, 25, 63, 0, 0,255,127, 0, 0, 3,255, 36,204, 76, 62,
+104,208, 76,190,151,153, 25, 63, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63, 56,208, 76,190, 4, 0,128,191, 0, 0,255,127,
+ 0, 0, 3,255,222,255,127, 63, 80,208, 76,190, 5, 0,128,191, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,
+ 7, 0,128,191, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190, 8, 0,128,191, 0, 0,255,127, 0, 0, 3,255,
+136,102,230, 63, 88,208, 76,190, 8, 0,128,191, 0, 0,255,127, 0, 0, 3,255,135,102,230, 63, 88,208, 76,190,151,153, 25, 63,
+ 0, 0,255,127, 0, 0, 3,255,136,102,230, 63, 88,208, 76,190,170,204, 76, 62, 0, 0,255,127, 0, 0, 3,255,136,102,230, 63,
+ 88,208, 76,190,246,204, 76,190, 0, 0,255,127, 0, 0, 3,255,136,102,230, 63, 88,208, 76,190,169,153, 25,191, 0, 0,255,127,
+ 0, 0, 3,255,112,205, 76,190, 64,208, 76,190,156,153, 25,191, 0, 0,255,127, 0, 0, 1,255,112,205, 76,190, 64,208, 76,190,
+195,204, 76,190, 0, 0,255,127, 0, 0, 1,255,112,205, 76,190, 64,208, 76,190,221,204, 76, 62, 0, 0,255,127, 0, 0, 1,255,
+112,205, 76,190, 64,208, 76,190,160,153, 25, 63, 0, 0,255,127, 0, 0, 1,255,112,205, 76,190, 64,208, 76,190, 4, 0,128,191,
+ 0, 0,255,127, 0, 0, 3,255,112,205, 76,190, 64,208, 76,190,150,255,127, 63, 0, 0,255,127, 0, 0, 3,255,136,102,230, 63,
+ 88,208, 76,190,142,255,127, 63, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190,142,255,127, 63, 0, 0,255,127,
+ 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,144,255,127, 63, 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,
+148,255,127, 63, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63, 56,208, 76,190,150,255,127, 63, 0, 0,255,127, 0, 0, 3,255,
+ 68, 65, 84, 65, 44, 1, 0, 0, 96, 76,150, 2, 21, 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, 72, 6,155, 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,
+ 68, 65, 84, 65,124, 14, 0, 0, 72, 6,155, 2, 54, 0, 0, 0, 53, 1, 0, 0, 21, 0, 0, 0, 82, 0, 0, 0, 0, 0, 34, 0,
+ 20, 0, 0, 0, 83, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0, 84, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 85, 0, 0, 0,
+ 0, 0, 34, 0, 22, 0, 0, 0, 76, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0, 28, 0, 0, 0,
+ 54, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 27, 0, 0, 0, 56, 0, 0, 0, 0, 0, 34, 0,
+ 29, 0, 0, 0, 48, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 34, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 34, 0, 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0,
+ 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 34, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 13, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 34, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 34, 0,
+ 7, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 34, 0, 1, 0, 0, 0, 10, 0, 0, 0, 0, 0, 34, 0, 13, 0, 0, 0, 17, 0, 0, 0, 0, 0, 34, 0, 16, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0,
+ 11, 0, 0, 0, 15, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0, 15, 0, 0, 0, 0, 0, 34, 0, 10, 0, 0, 0, 14, 0, 0, 0,
+ 0, 0, 34, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 21, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 19, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 18, 0, 0, 0, 0, 0, 34, 0,
+ 22, 0, 0, 0, 26, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 25, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 22, 0, 0, 0,
+ 0, 0, 34, 0, 17, 0, 0, 0, 23, 0, 0, 0, 0, 0, 34, 0, 13, 0, 0, 0, 24, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0,
+ 25, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 26, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 0, 34, 0,
+ 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 29, 0, 0, 0,
+ 0, 0, 34, 0, 21, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0, 29, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0,
+ 28, 0, 0, 0, 0, 0, 34, 0, 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 34, 0,
+ 32, 0, 0, 0, 33, 0, 0, 0, 0, 0, 34, 0, 29, 0, 0, 0, 35, 0, 0, 0, 0, 0, 34, 0, 23, 0, 0, 0, 30, 0, 0, 0,
+ 0, 0, 34, 0, 14, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 33, 0, 0, 0, 0, 0, 34, 0, 16, 0, 0, 0,
+ 32, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 40, 0, 0, 0, 98, 0, 0, 0, 0, 0, 34, 0,
+ 39, 0, 0, 0, 99, 0, 0, 0, 0, 0, 34, 0, 38, 0, 0, 0,100, 0, 0, 0, 0, 0, 34, 0, 37, 0, 0, 0,101, 0, 0, 0,
+ 0, 0, 34, 0, 41, 0, 0, 0, 72, 0, 0, 0, 0, 0, 34, 0, 36, 0, 0, 0, 50, 0, 0, 0, 0, 0, 34, 0, 38, 0, 0, 0,
+ 39, 0, 0, 0, 0, 0, 34, 0, 36, 0, 0, 0, 37, 0, 0, 0, 0, 0, 34, 0, 40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 34, 0,
+ 51, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0,101, 0, 0, 0, 0, 0, 34, 0, 68, 0, 0, 0, 94, 0, 0, 0,
+ 0, 0, 34, 0, 64, 0, 0, 0, 90, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0, 86, 0, 0, 0, 0, 0, 34, 0, 56, 0, 0, 0,
+ 82, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 78, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0,114, 0, 0, 0, 0, 0, 34, 0,
+ 65, 0, 0, 0,114, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0,115, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0,115, 0, 0, 0,
+ 0, 0, 34, 0, 51, 0, 0, 0,115, 0, 0, 0, 0, 0, 34, 0, 51, 0, 0, 0,114, 0, 0, 0, 0, 0, 34, 0, 42, 0, 0, 0,
+ 50, 0, 0, 0, 0, 0, 34, 0, 43, 0, 0, 0, 45, 0, 0, 0, 0, 0, 34, 0, 42, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0,
+ 42, 0, 0, 0, 44, 0, 0, 0, 0, 0, 34, 0, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 34, 0, 44, 0, 0, 0, 46, 0, 0, 0,
+ 0, 0, 34, 0, 47, 0, 0, 0, 49, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0,
+ 48, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, 0, 34, 0, 55, 0, 0, 0, 56, 0, 0, 0, 0, 0, 34, 0,
+ 54, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 53, 0, 0, 0, 54, 0, 0, 0, 0, 0, 34, 0, 56, 0, 0, 0, 60, 0, 0, 0,
+ 0, 0, 34, 0, 59, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 55, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 58, 0, 0, 0,
+ 59, 0, 0, 0, 0, 0, 34, 0, 54, 0, 0, 0, 58, 0, 0, 0, 0, 0, 34, 0, 57, 0, 0, 0, 58, 0, 0, 0, 0, 0, 34, 0,
+ 53, 0, 0, 0, 57, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0, 63, 0, 0, 0, 64, 0, 0, 0,
+ 0, 0, 34, 0, 59, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0, 62, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0, 58, 0, 0, 0,
+ 62, 0, 0, 0, 0, 0, 34, 0, 61, 0, 0, 0, 62, 0, 0, 0, 0, 0, 34, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0,
+ 64, 0, 0, 0, 68, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 34, 0, 63, 0, 0, 0, 67, 0, 0, 0,
+ 0, 0, 34, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 34, 0, 62, 0, 0, 0, 66, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0,
+ 66, 0, 0, 0, 0, 0, 34, 0, 61, 0, 0, 0, 65, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 68, 0, 0, 0, 0, 0, 34, 0,
+ 51, 0, 0, 0, 66, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0, 57, 0, 0, 0,
+ 0, 0, 34, 0, 44, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0, 42, 0, 0, 0, 65, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0,
+110, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0, 71, 0, 0, 0,102, 0, 0, 0, 0, 0, 34, 0,
+ 72, 0, 0, 0, 98, 0, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 74, 0, 0, 0, 93, 0, 0, 0,
+ 0, 0, 34, 0, 75, 0, 0, 0, 89, 0, 0, 0, 0, 0, 34, 0, 76, 0, 0, 0, 85, 0, 0, 0, 0, 0, 34, 0, 77, 0, 0, 0,
+ 81, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0, 71, 0, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 77, 0, 0, 0, 0, 0, 34, 0,
+ 74, 0, 0, 0, 75, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0, 77, 0, 0, 0, 0, 0, 34, 0, 81, 0, 0, 0,110, 0, 0, 0,
+ 0, 0, 34, 0, 80, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0,112, 0, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0,
+113, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0, 80, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0, 85, 0, 0, 0, 0, 0, 34, 0,
+ 83, 0, 0, 0, 84, 0, 0, 0, 0, 0, 34, 0, 82, 0, 0, 0, 83, 0, 0, 0, 0, 0, 34, 0, 85, 0, 0, 0, 89, 0, 0, 0,
+ 0, 0, 34, 0, 88, 0, 0, 0, 89, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0, 88, 0, 0, 0, 0, 0, 34, 0, 87, 0, 0, 0,
+ 88, 0, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0, 87, 0, 0, 0, 0, 0, 34, 0, 86, 0, 0, 0, 87, 0, 0, 0, 0, 0, 34, 0,
+ 82, 0, 0, 0, 86, 0, 0, 0, 0, 0, 34, 0, 89, 0, 0, 0, 93, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0, 93, 0, 0, 0,
+ 0, 0, 34, 0, 88, 0, 0, 0, 92, 0, 0, 0, 0, 0, 34, 0, 91, 0, 0, 0, 92, 0, 0, 0, 0, 0, 34, 0, 87, 0, 0, 0,
+ 91, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 34, 0, 86, 0, 0, 0, 90, 0, 0, 0, 0, 0, 34, 0,
+ 93, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 96, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0, 96, 0, 0, 0,
+ 0, 0, 34, 0, 95, 0, 0, 0, 96, 0, 0, 0, 0, 0, 34, 0, 91, 0, 0, 0, 95, 0, 0, 0, 0, 0, 34, 0, 94, 0, 0, 0,
+ 95, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0, 94, 0, 0, 0, 0, 0, 34, 0, 81, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0,
+ 80, 0, 0, 0, 96, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0, 95, 0, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0, 94, 0, 0, 0,
+ 0, 0, 34, 0,101, 0, 0, 0,105, 0, 0, 0, 0, 0, 34, 0,100, 0, 0, 0,101, 0, 0, 0, 0, 0, 34, 0,100, 0, 0, 0,
+104, 0, 0, 0, 0, 0, 34, 0, 99, 0, 0, 0,100, 0, 0, 0, 0, 0, 34, 0, 99, 0, 0, 0,103, 0, 0, 0, 0, 0, 34, 0,
+ 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0,102, 0, 0, 0, 0, 0, 34, 0,105, 0, 0, 0,114, 0, 0, 0,
+ 0, 0, 34, 0,105, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0,104, 0, 0, 0,105, 0, 0, 0, 0, 0, 34, 0,104, 0, 0, 0,
+108, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,104, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,107, 0, 0, 0, 0, 0, 34, 0,
+102, 0, 0, 0,103, 0, 0, 0, 0, 0, 34, 0,102, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0,109, 0, 0, 0,113, 0, 0, 0,
+ 0, 0, 34, 0,108, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0,108, 0, 0, 0,112, 0, 0, 0, 0, 0, 34, 0,107, 0, 0, 0,
+108, 0, 0, 0, 0, 0, 34, 0,107, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0,106, 0, 0, 0,107, 0, 0, 0, 0, 0, 34, 0,
+106, 0, 0, 0,110, 0, 0, 0, 0, 0, 34, 0,113, 0, 0, 0,115, 0, 0, 0, 0, 0, 34, 0,112, 0, 0, 0,113, 0, 0, 0,
+ 0, 0, 34, 0,111, 0, 0, 0,112, 0, 0, 0, 0, 0, 34, 0,110, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0,121, 0, 0, 0,
+144, 0, 0, 0, 0, 0, 50, 0,125, 0, 0, 0,142, 0, 0, 0, 0, 0, 50, 0,129, 0, 0, 0,140, 0, 0, 0, 0, 0, 50, 0,
+133, 0, 0, 0,138, 0, 0, 0, 0, 0, 50, 0,120, 0, 0, 0,135, 0, 0, 0, 0, 0, 50, 0,118, 0, 0, 0,134, 0, 0, 0,
+ 0, 0,178, 0,121, 0, 0, 0,125, 0, 0, 0, 0, 0, 50, 0,120, 0, 0, 0,121, 0, 0, 0, 0, 0, 50, 0,120, 0, 0, 0,
+124, 0, 0, 0, 0, 0, 50, 0,120, 0, 0, 0,119, 0, 0, 0, 0, 0, 50, 0,119, 0, 0, 0,123, 0, 0, 0, 0, 0, 50, 0,
+118, 0, 0, 0,119, 0, 0, 0, 0, 0, 50, 0,118, 0, 0, 0,122, 0, 0, 0, 0, 0, 50, 0,125, 0, 0, 0,129, 0, 0, 0,
+ 0, 0, 50, 0,124, 0, 0, 0,125, 0, 0, 0, 0, 0, 50, 0,124, 0, 0, 0,128, 0, 0, 0, 0, 0, 50, 0,123, 0, 0, 0,
+124, 0, 0, 0, 0, 0, 50, 0,123, 0, 0, 0,127, 0, 0, 0, 0, 0, 50, 0,122, 0, 0, 0,123, 0, 0, 0, 0, 0, 50, 0,
+122, 0, 0, 0,126, 0, 0, 0, 0, 0,178, 0,129, 0, 0, 0,133, 0, 0, 0, 0, 0, 50, 0,128, 0, 0, 0,129, 0, 0, 0,
+ 0, 0, 50, 0,128, 0, 0, 0,132, 0, 0, 0, 0, 0, 50, 0,127, 0, 0, 0,128, 0, 0, 0, 0, 0, 50, 0,127, 0, 0, 0,
+131, 0, 0, 0, 0, 0, 50, 0,126, 0, 0, 0,127, 0, 0, 0, 0, 0, 50, 0,126, 0, 0, 0,130, 0, 0, 0, 0, 0, 50, 0,
+132, 0, 0, 0,133, 0, 0, 0, 0, 0, 50, 0,131, 0, 0, 0,132, 0, 0, 0, 0, 0, 50, 0,130, 0, 0, 0,131, 0, 0, 0,
+ 0, 0, 50, 0,137, 0, 0, 0,138, 0, 0, 0, 0, 0, 50, 0,138, 0, 0, 0,140, 0, 0, 0, 0, 0, 50, 0,139, 0, 0, 0,
+140, 0, 0, 0, 0, 0, 50, 0,137, 0, 0, 0,139, 0, 0, 0, 0, 0, 50, 0,140, 0, 0, 0,142, 0, 0, 0, 0, 0, 50, 0,
+141, 0, 0, 0,142, 0, 0, 0, 0, 0, 50, 0,142, 0, 0, 0,144, 0, 0, 0, 0, 0, 50, 0,143, 0, 0, 0,144, 0, 0, 0,
+ 0, 0, 50, 0,141, 0, 0, 0,143, 0, 0, 0, 0, 0, 50, 0,136, 0, 0, 0,144, 0, 0, 0, 0, 0, 50, 0,117, 0, 0, 0,
+135, 0, 0, 0, 0, 0,178, 0,116, 0, 0, 0,135, 0, 0, 0, 0, 0, 50, 0,116, 0, 0, 0,134, 0, 0, 0, 0, 0,178, 0,
+119, 0, 0, 0,116, 0, 0, 0, 0, 0, 50, 0,117, 0, 0, 0,121, 0, 0, 0, 0, 0, 50, 0,117, 0, 0, 0,136, 0, 0, 0,
+ 0, 0, 50, 0,136, 0, 0, 0,145, 0, 0, 0, 0, 0,178, 0,146, 0, 0, 0,147, 0, 0, 0, 0, 0,178, 0,147, 0, 0, 0,
+150, 0, 0, 0, 0, 0, 50, 0,149, 0, 0, 0,151, 0, 0, 0, 0, 0,178, 0,148, 0, 0, 0,151, 0, 0, 0, 0, 0, 50, 0,
+148, 0, 0, 0,150, 0, 0, 0, 0, 0,178, 0,138, 0, 0, 0,147, 0, 0, 0, 0, 0, 50, 0,130, 0, 0, 0,149, 0, 0, 0,
+ 0, 0,178, 0,131, 0, 0, 0,151, 0, 0, 0, 0, 0, 50, 0,132, 0, 0, 0,148, 0, 0, 0, 0, 0, 50, 0,133, 0, 0, 0,
+150, 0, 0, 0, 0, 0, 50, 0,155, 0, 0, 0,171, 0, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,170, 0, 0, 0, 0, 0, 35, 0,
+153, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0,152, 0, 0, 0,168, 0, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,159, 0, 0, 0,
+ 0, 0, 35, 0,154, 0, 0, 0,155, 0, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,158, 0, 0, 0, 0, 0, 35, 0,153, 0, 0, 0,
+154, 0, 0, 0, 0, 0, 35, 0,153, 0, 0, 0,157, 0, 0, 0, 0, 0, 35, 0,152, 0, 0, 0,153, 0, 0, 0, 0, 0, 35, 0,
+152, 0, 0, 0,156, 0, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,163, 0, 0, 0, 0, 0, 35, 0,158, 0, 0, 0,159, 0, 0, 0,
+ 0, 0, 35, 0,158, 0, 0, 0,162, 0, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,158, 0, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,
+161, 0, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,157, 0, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,160, 0, 0, 0, 0, 0, 35, 0,
+163, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,163, 0, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,166, 0, 0, 0,
+ 0, 0, 35, 0,161, 0, 0, 0,162, 0, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,165, 0, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,
+161, 0, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,164, 0, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0,
+165, 0, 0, 0,166, 0, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,165, 0, 0, 0, 0, 0, 35, 0,169, 0, 0, 0,170, 0, 0, 0,
+ 0, 0, 35, 0,174, 0, 0, 0,175, 0, 0, 0, 0, 0, 35, 0,172, 0, 0, 0,176, 0, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,
+172, 0, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,174, 0, 0, 0, 0, 0, 35, 0,
+156, 0, 0, 0,175, 0, 0, 0, 0, 0, 35, 0,152, 0, 0, 0,176, 0, 0, 0, 0, 0, 35, 0,177, 0, 0, 0,181, 0, 0, 0,
+ 0, 0, 35, 0,177, 0, 0, 0,178, 0, 0, 0, 0, 0,163, 0,178, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0,179, 0, 0, 0,
+180, 0, 0, 0, 0, 0,163, 0,171, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0,167, 0, 0, 0,180, 0, 0, 0, 0, 0, 35, 0,
+163, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,177, 0, 0, 0,
+ 0, 0, 35, 0,182, 0, 0, 0,184, 0, 0, 0, 0, 0, 35, 0,183, 0, 0, 0,187, 0, 0, 0, 0, 0, 35, 0,185, 0, 0, 0,
+186, 0, 0, 0, 0, 0, 35, 0,180, 0, 0, 0,182, 0, 0, 0, 0, 0, 35, 0,173, 0, 0, 0,183, 0, 0, 0, 0, 0, 35, 0,
+164, 0, 0, 0,187, 0, 0, 0, 0, 0, 35, 0,165, 0, 0, 0,186, 0, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,185, 0, 0, 0,
+ 0, 0, 35, 0,167, 0, 0, 0,184, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65, 44, 1, 0, 0,192,166,132, 2, 21, 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, 32, 5,167, 2,
+ 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,176,131, 2, 6, 0, 0, 0,
+ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 80,102, 8, 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, 68, 65, 84, 65,240, 5, 0, 0, 32, 5,167, 2, 53, 0, 0, 0,
+ 76, 0, 0, 0, 18, 0, 0, 0, 22, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0,
+ 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 8, 0, 0, 0, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 17, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0,
+ 15, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0,
+ 15, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0,
+ 14, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 65, 0, 0, 0,114, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0,
+ 44, 0, 0, 0, 42, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 0, 0, 49, 0, 0, 0, 48, 0, 0, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 1, 0, 0, 0,
+ 53, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
+ 55, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 54, 0, 0, 0, 58, 0, 0, 0,
+ 57, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0,
+ 64, 0, 0, 0, 68, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 62, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0,
+ 0, 0, 0, 0,115, 0, 0, 0, 51, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 22, 0, 0, 0,
+ 76, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 84, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0,
+ 27, 0, 0, 0, 21, 0, 0, 0, 82, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 85, 0, 0, 0, 89, 0, 0, 0,
+ 88, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 83, 0, 0, 0, 87, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0,
+ 75, 0, 0, 0, 74, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 88, 0, 0, 0, 92, 0, 0, 0, 91, 0, 0, 0,
+ 0, 0, 0, 0, 60, 0, 0, 0, 86, 0, 0, 0, 90, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0,
+ 97, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 95, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0,
+ 97, 0, 0, 0, 73, 0, 0, 0, 77, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 80, 0, 0, 0,
+ 79, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0,
+ 36, 0, 0, 0, 50, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 99, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0,
+ 0, 0, 0, 0, 98, 0, 0, 0, 72, 0, 0, 0, 41, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0,104, 0, 0, 0,
+100, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0,103, 0, 0, 0,102, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0,
+ 51, 0, 0, 0,109, 0, 0, 0,105, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0,108, 0, 0, 0,107, 0, 0, 0,103, 0, 0, 0,
+104, 0, 0, 0, 0, 0, 0, 0,106, 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0,113, 0, 0, 0,
+112, 0, 0, 0,108, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0,111, 0, 0, 0,110, 0, 0, 0,106, 0, 0, 0,107, 0, 0, 0,
+ 0, 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0, 52, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 80, 0, 0, 0,
+111, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 77, 0, 0, 0, 69, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0,
+116, 0, 0, 0,135, 0, 0, 0,120, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 16,125, 0, 0, 0,124, 0, 0, 0,120, 0, 0, 0,
+121, 0, 0, 0, 0, 0, 0, 16,123, 0, 0, 0,122, 0, 0, 0,118, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 16,128, 0, 0, 0,
+127, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 16,133, 0, 0, 0,132, 0, 0, 0,128, 0, 0, 0,129, 0, 0, 0,
+ 0, 0, 0, 16,131, 0, 0, 0,130, 0, 0, 0,126, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 16,148, 0, 0, 0,151, 0, 0, 0,
+131, 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 16,147, 0, 0, 0,150, 0, 0, 0,133, 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 16,
+137, 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 16,140, 0, 0, 0,129, 0, 0, 0,125, 0, 0, 0,
+142, 0, 0, 0, 0, 0, 0, 16,141, 0, 0, 0,142, 0, 0, 0,144, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 16,144, 0, 0, 0,
+121, 0, 0, 0,117, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 16,171, 0, 0, 0,181, 0, 0, 0,177, 0, 0, 0,155, 0, 0, 0,
+ 0, 0, 0, 2,154, 0, 0, 0,153, 0, 0, 0,169, 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 2,152, 0, 0, 0,176, 0, 0, 0,
+172, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 2,159, 0, 0, 0,158, 0, 0, 0,154, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 2,
+157, 0, 0, 0,156, 0, 0, 0,152, 0, 0, 0,153, 0, 0, 0, 0, 0, 0, 2,179, 0, 0, 0,163, 0, 0, 0,159, 0, 0, 0,
+178, 0, 0, 0, 0, 0, 0, 2,162, 0, 0, 0,161, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 2,160, 0, 0, 0,
+174, 0, 0, 0,175, 0, 0, 0,156, 0, 0, 0, 0, 0, 0, 2,167, 0, 0, 0,166, 0, 0, 0,162, 0, 0, 0,163, 0, 0, 0,
+ 0, 0, 0, 2,165, 0, 0, 0,164, 0, 0, 0,160, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 2,182, 0, 0, 0,184, 0, 0, 0,
+167, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 2,185, 0, 0, 0,186, 0, 0, 0,165, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 2,
+187, 0, 0, 0,183, 0, 0, 0,173, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 2, 68, 65, 84, 65, 16, 13, 0, 0, 40,176,131, 2,
+ 61, 0, 0, 0, 76, 0, 0, 0,250,168, 27, 63, 96,211, 93, 59, 84,162,203, 62, 96,211, 93, 59, 84,162,203, 62, 96,211, 93, 59,
+251,168, 27, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 21,172,131, 63, 96,211, 93, 59,146,128, 81, 63,
+ 96,211, 93, 59,149,128, 81, 63, 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,
+227,151,158, 63, 96,211, 93, 59,174,131,185, 63, 96,211, 93, 59,174,131,185, 63, 96,211, 93, 59,225,151,158, 63, 96,211, 93, 59,
+ 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,149,128, 81, 63, 96,211, 93, 59,251,168, 27, 63, 96,211, 93, 59,246,168, 27, 63,
+ 96,211, 93, 59,142,128, 81, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,227,151,158, 63, 96,211, 93, 59,
+ 22,172,131, 63, 96,211, 93, 59, 24,172,131, 63, 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0,246,168, 27, 63, 96,211, 93, 59, 86,162,203, 62, 96,211, 93, 59, 85,162,203, 62, 96,211, 93, 59,247,168, 27, 63,
+ 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 24,172,131, 63, 96,211, 93, 59,142,128, 81, 63, 96,211, 93, 59,
+144,128, 81, 63, 96,211, 93, 59, 21,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,174,131,185, 63,
+ 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59,176,131,185, 63, 96,211, 93, 59, 0, 0, 0, 0,
+ 61, 0, 1, 0, 0, 0, 0, 0,144,128, 81, 63, 96,211, 93, 59,247,168, 27, 63, 96,211, 93, 59,247,168, 27, 63, 96,211, 93, 59,
+144,128, 81, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,226,151,158, 63, 96,211, 93, 59, 21,172,131, 63,
+ 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59,224,151,158, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,
+247,168, 27, 63, 96,211, 93, 59, 85,162,203, 62, 96,211, 93, 59, 86,162,203, 62, 96,211, 93, 59,248,168, 27, 63, 96,211, 93, 59,
+ 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 22,172,131, 63, 96,211, 93, 59,144,128, 81, 63, 96,211, 93, 59,144,128, 81, 63,
+ 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,226,151,158, 63, 96,211, 93, 59,
+176,131,185, 63, 96,211, 93, 59,174,131,185, 63, 96,211, 93, 59,224,151,158, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0, 99,131,140, 63, 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63,
+ 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63,
+ 99,131,140, 63, 76, 47, 41, 63,161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63,
+ 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,
+161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63, 72, 47, 41, 63, 44,244,114, 63,
+236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+174,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63, 52,207, 38, 63,111,179,141, 63,174,225, 76, 63,102, 84,117, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,
+173,188,160, 63, 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,
+174,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,172,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63, 52,207, 38, 63,111,179,141, 63,172,225, 76, 63,
+102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,
+188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,
+236, 65, 79, 63,172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 56,207, 38, 63,111,179,141, 63,172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63,
+ 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 96,105,188,189,120, 47, 41, 63, 56,127,118,190,
+220, 28, 3, 63, 56,127,118,190,220, 28, 3, 63, 96,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 26, 95, 82, 62,102, 84,117, 63,200, 84,104, 61,244, 65, 79, 63,200, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,190,188, 0, 63,171,188,160, 63,122, 84,181, 62,113,179,141, 63,122, 84,181, 62,
+113,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,200, 84,104, 61,242, 65, 79, 63,
+ 96,105,188,189,120, 47, 41, 63,128,105,188,189,120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,
+113,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63,
+ 64,127,118,190,216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,
+102, 84,117, 63,160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,113,179,141, 63,122, 84,181, 62,113,179,141, 63,
+188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,
+120, 47, 41, 63,128,105,188,189,120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63, 64,127,118,190,
+216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,
+160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,
+113,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,180,131,140, 63,116, 19,186, 62,244,140,159, 63, 50, 28, 3, 63,
+ 99,131,140, 63, 76, 47, 41, 63, 42,244,114, 63,244, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,174,225, 76, 63,
+ 0, 21,186, 62, 51,207, 38, 63, 24,224, 91, 62,112,226, 76, 63, 64, 38,135, 61,240,244,114, 63, 4,221, 91, 62, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,185,188, 0, 63, 96, 44,135, 61, 61, 84,181, 62,176,104,169,189, 93,189, 0, 63, 80, 1,109,190,
+248,207, 38, 63,144,109,169,189, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,174,225, 76, 63,116, 47, 41, 63, 52,207, 38, 63,
+248, 28, 3, 63,174,225, 76, 63, 0, 21,186, 62, 42,244,114, 63,244, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+185,188, 0, 63, 0, 21,186, 62,122, 84,181, 62, 32,224, 91, 62,185,188, 0, 63, 96, 44,135, 61, 51,207, 38, 63, 24,224, 91, 62,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,172,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,236, 65, 79, 63,174,225, 76, 63,
+116, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,120, 47, 41, 63,
+122, 84,181, 62,248, 28, 3, 63,185,188, 0, 63, 0, 21,186, 62, 52,207, 38, 63,248, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 14, 95, 82, 62, 0, 21,186, 62,144, 82,104, 61,128,223, 91, 62,138, 94, 82, 62, 48, 43,135, 61,122, 84,181, 62,
+ 32,224, 91, 62, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,190,188, 0, 63,102, 84,117, 63,127, 84,181, 62,242, 65, 79, 63,
+188,188, 0, 63,120, 47, 41, 63, 52,207, 38, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,
+120, 47, 41, 63,160, 84,104, 61, 0, 29, 3, 63, 14, 95, 82, 62, 0, 21,186, 62,122, 84,181, 62,248, 28, 3, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,190,188, 0, 63,102, 84,117, 63, 56,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,
+122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,160, 84,104, 61,
+242, 65, 79, 63, 26, 95, 82, 62,120, 47, 41, 63,127, 84,181, 62,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63,128,106,188,189,176, 20,186, 62,160, 84,104, 61, 0, 29, 3, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 56,207, 38, 63,111,179,141, 63,172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,
+102, 84,117, 63, 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,
+172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,
+111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,172,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63,
+ 52,207, 38, 63,111,179,141, 63,172,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,
+236, 65, 79, 63,174,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63,
+ 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,174,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,
+111,179,141, 63, 52,207, 38, 63,111,179,141, 63,174,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 99,131,140, 63, 72, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63,
+ 76, 47, 41, 63,161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63, 76, 47, 41, 63,
+ 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,161,140,159, 63,
+210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63, 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63,
+ 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,
+113,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63,
+ 26, 95, 82, 62,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,
+216, 28, 3, 63, 64,127,118,190,216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,120, 47, 41, 63,128,105,188,189,
+120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,
+122, 84,181, 62,113,179,141, 63,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,
+102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63,
+ 64,127,118,190,216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,
+113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,200, 84,104, 61,242, 65, 79, 63, 96,105,188,189,120, 47, 41, 63,128,105,188,189,120, 47, 41, 63,
+160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,190,188, 0, 63,171,188,160, 63,122, 84,181, 62,
+113,179,141, 63,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 26, 95, 82, 62,102, 84,117, 63,200, 84,104, 61,244, 65, 79, 63,200, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 96,105,188,189,120, 47, 41, 63, 56,127,118,190,220, 28, 3, 63, 56,127,118,190,
+220, 28, 3, 63, 96,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65,192, 4, 0, 0,
+ 80,102, 8, 3, 58, 0, 0, 0, 48, 1, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,240, 0, 18, 3, 51, 0, 0, 0, 1, 0, 0, 0,
+208, 84,164, 2, 80,153,166, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 49, 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, 32,101,169, 2,208,203,131, 2,176, 30,161, 2, 0, 0, 0, 0,104,189,131, 2, 96, 16,161, 2,
+ 0, 0, 0, 0,248, 20,155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,232, 96,130, 2, 1, 0, 0, 0, 5, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 0, 0,193,149, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 88, 7,153, 2,
+ 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 0, 45, 1, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,213,204, 76, 63,255,204, 76, 63, 0, 0,104,182, 30, 0,128, 63,140, 0,128, 63,214,255,127, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 32,101,169, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 44, 1, 0, 0,232, 96,130, 2, 21, 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,104,189,131, 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, 68, 65, 84, 65, 56, 14, 0, 0,104,189,131, 2, 57, 0, 0, 0,182, 0, 0, 0,133,102,230, 63,208, 51,179, 63,
+ 4, 0,128,191,127,165, 0, 0,129, 90, 2,255,133,102,230, 63,206,154, 25, 63, 4, 0,128,191,127,165, 0, 0,129, 90, 2,255,
+ 81, 51,179, 63,210, 51,179, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63,212, 51,179, 63, 1, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63,214, 51,179, 63, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255,152,205, 76, 62,
+216, 51,179, 63,254,255,127,191, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,158, 0,128, 63, 3, 0,128,191, 0, 0, 0, 0,
+255,127, 2,255, 27, 0,128, 63,160, 0,128, 63, 2, 0,128,191, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,162, 0,128, 63,
+ 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,163, 0,128, 63,254,255,127,191, 0, 0, 0, 0,255,127, 2,255,
+ 80, 51,179, 63,209,154, 25, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,213,154, 25, 63, 2, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,217,154, 25, 63, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,
+221,154, 25, 63,254,255,127,191, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,160,209, 76, 62, 3, 0,128,191, 0, 0, 0, 0,
+255,127, 2,255, 27, 0,128, 63,176,209, 76, 62, 2, 0,128,191, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,188,209, 76, 62,
+ 1, 0,128,191, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,204,209, 76, 62,255,255,127,191, 0, 0, 0, 0,255,127, 2,255,
+140,205, 76, 62, 8,103,230, 63,156,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,204,153, 25, 63, 10,103,230, 63,160,153, 25,191,
+ 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63, 10,103,230, 63,164,153, 25,191, 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63,
+ 12,103,230, 63,168,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,140,205, 76, 62, 8,103,230, 63,196,204, 76,190, 0, 0, 1,128,
+ 0, 0, 2,255,204,153, 25, 63, 10,103,230, 63,212,204, 76,190, 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63, 10,103,230, 63,
+228,204, 76,190, 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63, 12,103,230, 63,244,204, 76,190, 0, 0, 1,128, 0, 0, 2,255,
+140,205, 76, 62, 8,103,230, 63,216,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255,204,153, 25, 63, 10,103,230, 63,200,204, 76, 62,
+ 0, 0, 1,128, 0, 0, 2,255, 27, 0,128, 63, 10,103,230, 63,184,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255, 80, 51,179, 63,
+ 12,103,230, 63,168,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255,152,205, 76, 62, 8,103,230, 63,158,153, 25, 63, 0, 0, 1,128,
+ 0, 0, 2,255,207,153, 25, 63, 10,103,230, 63,154,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255, 28, 0,128, 63, 10,103,230, 63,
+150,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255, 81, 51,179, 63, 12,103,230, 63,150,153, 25, 63, 0, 0, 1,128, 0, 0, 2,255,
+140,205, 76, 62, 8,103,230, 63, 3, 0,128,191, 0, 0,127,165,129, 90, 0,255,204,153, 25, 63, 10,103,230, 63, 4, 0,128,191,
+ 0, 0,127,165,129, 90, 0,255, 27, 0,128, 63, 10,103,230, 63, 6, 0,128,191, 0, 0,127,165,129, 90, 0,255, 80, 51,179, 63,
+ 12,103,230, 63, 7, 0,128,191, 0, 0,127,165,129, 90, 0,255,144,205, 76,190, 12,103,230, 63,150,153, 25, 63, 0, 0, 1,128,
+ 0, 0, 2,255,152,205, 76,190, 12,103,230, 63,168,204, 76, 62, 0, 0, 1,128, 0, 0, 2,255,152,205, 76,190, 12,103,230, 63,
+244,204, 76,190, 0, 0, 1,128, 0, 0, 2,255,152,205, 76,190, 12,103,230, 63,168,153, 25,191, 0, 0, 1,128, 0, 0, 2,255,
+152,205, 76,190,160,209, 76, 62, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,209,154, 25, 63, 3, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,158, 0,128, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,144,205, 76,190,
+210, 51,179, 63, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,131,102,230, 63, 7,103,230, 63,155,153, 25,191,127,165,127,165,
+ 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,159,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,
+163,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,135,102,230, 63,207,154, 25, 63,167,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,
+131,102,230, 63, 7,103,230, 63,193,204, 76,190,127,165,127,165, 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,209,204, 76,190,
+ 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,225,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,135,102,230, 63,
+207,154, 25, 63,241,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63, 7,103,230, 63,219,204, 76, 62,127,165,127,165,
+ 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,203,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,160, 0,128, 63,
+187,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,135,102,230, 63,207,154, 25, 63,171,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,
+131,102,230, 63, 7,103,230, 63,159,153, 25, 63,127,165,127,165, 0, 0, 2,255,131,102,230, 63,212, 51,179, 63,155,153, 25, 63,
+ 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,156, 0,128, 63,151,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,135,102,230, 63,
+207,154, 25, 63,151,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63, 7,103,230, 63, 3, 0,128,191, 1,128, 0, 0,
+ 0, 0, 2,255,131,102,230, 63,160, 0,128, 63, 6, 0,128,191,127,165, 0, 0,129, 90, 2,255,127,102,230, 63, 28,208, 76, 62,
+ 3, 0,128,191,127,165, 0, 0,129, 90, 2,255,131,102,230, 63,136,201, 76,190,155,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,
+127,102,230, 63, 28,208, 76, 62,159,153, 25, 63, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,136,201, 76,190,203,204, 76, 62,
+ 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,219,204, 76, 62, 1,128, 0, 0, 0, 0, 2,255,131,102,230, 63,
+136,201, 76,190,209,204, 76,190, 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,193,204, 76,190, 1,128, 0, 0,
+ 0, 0, 2,255,131,102,230, 63,136,201, 76,190,159,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,127,102,230, 63, 28,208, 76, 62,
+155,153, 25,191, 1,128, 0, 0, 0, 0, 2,255,150,205, 76, 62, 24,208, 76,190,254,255,127,191, 0, 0, 0, 0,255,127, 2,255,
+207,153, 25, 63, 40,208, 76,190, 0, 0,128,191, 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63, 56,208, 76,190, 1, 0,128,191,
+ 0, 0, 0, 0,255,127, 2,255, 81, 51,179, 63, 72,208, 76,190, 3, 0,128,191, 0, 0, 0, 0,255,127, 2,255,133,102,230, 63,
+ 88,208, 76,190, 4, 0,128,191, 1,128, 0, 0, 0, 0, 2,255,133,102,230, 63, 88,208, 76,190,146,255,127, 63, 1,128, 0, 0,
+ 0, 0, 2,255, 81, 51,179, 63, 72,208, 76,190,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63, 56,208, 76,190,
+152,255,127, 63, 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63, 40,208, 76,190,154,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+150,205, 76, 62, 24,208, 76,190,156,255,127, 63, 0, 0, 0, 0,255,127, 2,255,127,102,230, 63, 28,208, 76, 62,148,255,127, 63,
+127,165, 0, 0,129, 90, 2,255,131,102,230, 63,160, 0,128, 63,142,255,127, 63,127,165, 0, 0,129, 90, 2,255,131,102,230, 63,
+ 7,103,230, 63,148,255,127, 63, 1,128, 0, 0, 0, 0, 2,255,144,205, 76,190,210, 51,179, 63,148,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,152,205, 76,190,158, 0,128, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,209,154, 25, 63,
+148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,152,205, 76,190,160,209, 76, 62,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+ 80, 51,179, 63, 12,103,230, 63,140,255,127, 63, 0, 0,127,165,129, 90, 2,255, 27, 0,128, 63, 10,103,230, 63,142,255,127, 63,
+ 0, 0,127,165,129, 90, 2,255,204,153, 25, 63, 10,103,230, 63,146,255,127, 63, 0, 0,127,165,129, 90, 2,255,140,205, 76, 62,
+ 8,103,230, 63,148,255,127, 63, 0, 0,127,165,129, 90, 2,255,140,205, 76, 62,204,209, 76, 62,154,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,204,153, 25, 63,188,209, 76, 62,152,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,176,209, 76, 62,
+150,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,160,209, 76, 62,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+140,205, 76, 62,221,154, 25, 63,156,255,127, 63, 0, 0, 0, 0,255,127, 2,255,204,153, 25, 63,217,154, 25, 63,154,255,127, 63,
+ 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,213,154, 25, 63,150,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,
+209,154, 25, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,140,205, 76, 62,163, 0,128, 63,156,255,127, 63, 0, 0, 0, 0,
+255,127, 2,255,204,153, 25, 63,162, 0,128, 63,154,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 27, 0,128, 63,160, 0,128, 63,
+150,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 80, 51,179, 63,158, 0,128, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,
+152,205, 76, 62,216, 51,179, 63,156,255,127, 63, 0, 0, 0, 0,255,127, 2,255,207,153, 25, 63,214, 51,179, 63,154,255,127, 63,
+ 0, 0, 0, 0,255,127, 2,255, 28, 0,128, 63,212, 51,179, 63,152,255,127, 63, 0, 0, 0, 0,255,127, 2,255, 81, 51,179, 63,
+210, 51,179, 63,148,255,127, 63, 0, 0, 0, 0,255,127, 2,255,133,102,230, 63,206,154, 25, 63,146,255,127, 63,127,165, 0, 0,
+129, 90, 2,255,133,102,230, 63,208, 51,179, 63,146,255,127, 63,127,165, 0, 0,129, 90, 2,255,144,205, 76,190,140,201, 76, 62,
+148,255,127, 63,255,127, 0, 0, 0, 0, 1,255,136,205, 76,190, 52,255,127, 63,148,255,127, 63,255,127, 0, 0, 0, 0, 1,255,
+128,205, 76,190, 48,208, 76,190,150,255,127, 63,255,127, 0, 0, 0, 0, 3,255,120,205, 76,190,194,152, 25, 63,144,255,127, 63,
+255,127, 0, 0, 0, 0, 1,255, 80,205, 76,190,254, 50,179, 63,150,255,127, 63,255,127, 0, 0, 0, 0, 1,255,128,205, 76,190,
+ 12,103,230, 63,148,255,127, 63,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190, 12,103,230, 63, 5, 0,128,191,255,127, 0, 0,
+ 0, 0, 3,255, 80,205, 76,190,254, 50,179, 63,156,153, 25,191,255,127, 0, 0, 0, 0, 3,255,112,205, 76,190, 50,102,230, 63,
+160,153, 25,191,255,127, 0, 0, 0, 0, 3,255, 80,205, 76,190,254, 50,179, 63,195,204, 76,190,255,127, 0, 0, 0, 0, 3,255,
+112,205, 76,190, 50,102,230, 63,211,204, 76,190,255,127, 0, 0, 0, 0, 3,255, 80,205, 76,190,254, 50,179, 63,221,204, 76, 62,
+255,127, 0, 0, 0, 0, 3,255,112,205, 76,190, 50,102,230, 63,205,204, 76, 62,255,127, 0, 0, 0, 0, 3,255, 80,205, 76,190,
+254, 50,179, 63,160,153, 25, 63,255,127, 0, 0, 0, 0, 3,255,112,205, 76,190, 50,102,230, 63,156,153, 25, 63,255,127, 0, 0,
+ 0, 0, 3,255, 80,205, 76,190,254, 50,179, 63, 4, 0,128,191,255,127, 0, 0, 0, 0, 1,255,120,205, 76,190,194,152, 25, 63,
+ 7, 0,128,191,255,127, 0, 0, 0, 0, 1,255,128,205, 76,190, 48,208, 76,190, 4, 0,128,191,255,127, 0, 0, 0, 0, 3,255,
+152,205, 76,190, 52,255,127, 63,152,153, 25, 63,255,127, 0, 0, 0, 0, 3,255,120,205, 76,190,202,152, 25, 63,152,153, 25, 63,
+255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,108,201, 76, 62,156,153, 25, 63,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,
+ 48,208, 76,190,160,153, 25, 63,255,127, 0, 0, 0, 0, 1,255,152,205, 76,190, 52,255,127, 63,173,204, 76, 62,255,127, 0, 0,
+ 0, 0, 3,255,120,205, 76,190,194,152, 25, 63,189,204, 76, 62,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,108,201, 76, 62,
+205,204, 76, 62,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190, 48,208, 76,190,221,204, 76, 62,255,127, 0, 0, 0, 0, 1,255,
+152,205, 76,190, 52,255,127, 63,243,204, 76,190,255,127, 0, 0, 0, 0, 3,255,120,205, 76,190,194,152, 25, 63,227,204, 76,190,
+255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,108,201, 76, 62,211,204, 76,190,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,
+ 48,208, 76,190,195,204, 76,190,255,127, 0, 0, 0, 0, 1,255,152,205, 76,190, 52,255,127, 63,168,153, 25,191,255,127, 0, 0,
+ 0, 0, 3,255,120,205, 76,190,194,152, 25, 63,164,153, 25,191,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190,108,201, 76, 62,
+160,153, 25,191,255,127, 0, 0, 0, 0, 3,255,128,205, 76,190, 48,208, 76,190,156,153, 25,191,255,127, 0, 0, 0, 0, 1,255,
+136,205, 76,190, 52,255,127, 63, 5, 0,128,191,255,127, 0, 0, 0, 0, 1,255,144,205, 76,190,140,201, 76, 62, 5, 0,128,191,
+255,127, 0, 0, 0, 0, 1,255, 36, 51,179, 63, 56,208, 76,190,150,255,127, 63, 0, 0,255,127, 0, 0, 3,255,222,255,127, 63,
+ 80,208, 76,190,148,255,127, 63, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,144,255,127, 63, 0, 0,255,127,
+ 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190,142,255,127, 63, 0, 0,255,127, 0, 0, 3,255,112,205, 76,190, 64,208, 76,190,
+150,255,127, 63, 94,231, 94,231, 41,123, 1,255,112,205, 76,190, 64,208, 76,190, 4, 0,128,191, 94,231, 94,231,215,132, 1,255,
+112,205, 76,190, 64,208, 76,190,160,153, 25, 63, 0, 0,255,127, 0, 0, 1,255,112,205, 76,190, 64,208, 76,190,221,204, 76, 62,
+ 0, 0,255,127, 0, 0, 1,255,112,205, 76,190, 64,208, 76,190,195,204, 76,190, 0, 0,255,127, 0, 0, 1,255,112,205, 76,190,
+ 64,208, 76,190,156,153, 25,191, 0, 0,255,127, 0, 0, 1,255,136,102,230, 63, 88,208, 76,190,169,153, 25,191, 0, 0,255,127,
+ 0, 0, 3,255,136,102,230, 63, 88,208, 76,190,246,204, 76,190, 0, 0,255,127, 0, 0, 3,255,136,102,230, 63, 88,208, 76,190,
+170,204, 76, 62, 0, 0,255,127, 0, 0, 3,255,135,102,230, 63, 88,208, 76,190,151,153, 25, 63, 0, 0,255,127, 0, 0, 3,255,
+ 44,204, 76, 62,104,208, 76,190, 8, 0,128,191, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190, 7, 0,128,191,
+ 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190, 5, 0,128,191, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63,
+ 56,208, 76,190, 4, 0,128,191, 0, 0,255,127, 0, 0, 3,255, 36,204, 76, 62,104,208, 76,190,151,153, 25, 63, 0, 0,255,127,
+ 0, 0, 3,255,114,153, 25, 63, 80,208, 76,190,151,153, 25, 63, 0, 0,255,127, 0, 0, 3,255,220,255,127, 63, 80,208, 76,190,
+155,153, 25, 63, 0, 0,255,127, 0, 0, 3,255, 34, 51,179, 63, 56,208, 76,190,159,153, 25, 63, 0, 0,255,127, 0, 0, 3,255,
+ 44,204, 76, 62,104,208, 76,190,170,204, 76, 62, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,186,204, 76, 62,
+ 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,202,204, 76, 62, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63,
+ 56,208, 76,190,218,204, 76, 62, 0, 0,255,127, 0, 0, 3,255, 44,204, 76, 62,104,208, 76,190,246,204, 76,190, 0, 0,255,127,
+ 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,230,204, 76,190, 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,
+214,204, 76,190, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63, 56,208, 76,190,198,204, 76,190, 0, 0,255,127, 0, 0, 3,255,
+ 44,204, 76, 62,104,208, 76,190,169,153, 25,191, 0, 0,255,127, 0, 0, 3,255,116,153, 25, 63, 80,208, 76,190,165,153, 25,191,
+ 0, 0,255,127, 0, 0, 3,255,222,255,127, 63, 80,208, 76,190,161,153, 25,191, 0, 0,255,127, 0, 0, 3,255, 36, 51,179, 63,
+ 56,208, 76,190,157,153, 25,191, 0, 0,255,127, 0, 0, 3,255, 68, 65, 84, 65, 44, 1, 0, 0, 0,193,149, 2, 21, 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, 96, 16,161, 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, 68, 65, 84, 65, 28, 14, 0, 0, 96, 16,161, 2, 54, 0, 0, 0,
+ 45, 1, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 34, 0,
+ 8, 0, 0, 0, 9, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0, 7, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 34, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 13, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 13, 0, 0, 0, 0, 0, 34, 0,
+ 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 34, 0, 7, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 34, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0, 10, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 34, 0, 13, 0, 0, 0, 17, 0, 0, 0, 0, 0, 34, 0, 16, 0, 0, 0, 17, 0, 0, 0, 0, 0, 34, 0,
+ 12, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 34, 0, 14, 0, 0, 0, 15, 0, 0, 0, 0, 0, 34, 0, 10, 0, 0, 0, 14, 0, 0, 0, 0, 0, 34, 0, 21, 0, 0, 0,
+ 37, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0, 36, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0, 35, 0, 0, 0, 0, 0, 34, 0,
+ 18, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 21, 0, 0, 0, 25, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0, 21, 0, 0, 0,
+ 0, 0, 34, 0, 20, 0, 0, 0, 24, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0,
+ 23, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 19, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 22, 0, 0, 0, 0, 0, 34, 0,
+ 25, 0, 0, 0, 29, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 25, 0, 0, 0, 0, 0, 34, 0, 24, 0, 0, 0, 28, 0, 0, 0,
+ 0, 0, 34, 0, 23, 0, 0, 0, 24, 0, 0, 0, 0, 0, 34, 0, 23, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0, 22, 0, 0, 0,
+ 23, 0, 0, 0, 0, 0, 34, 0, 22, 0, 0, 0, 26, 0, 0, 0, 0, 0, 34, 0, 29, 0, 0, 0, 33, 0, 0, 0, 0, 0, 34, 0,
+ 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 34, 0, 28, 0, 0, 0, 32, 0, 0, 0, 0, 0, 34, 0, 27, 0, 0, 0, 28, 0, 0, 0,
+ 0, 0, 34, 0, 27, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 26, 0, 0, 0, 27, 0, 0, 0, 0, 0, 34, 0, 26, 0, 0, 0,
+ 30, 0, 0, 0, 0, 0, 34, 0, 32, 0, 0, 0, 33, 0, 0, 0, 0, 0, 34, 0, 31, 0, 0, 0, 32, 0, 0, 0, 0, 0, 34, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 34, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 34, 0, 36, 0, 0, 0, 37, 0, 0, 0,
+ 0, 0, 34, 0, 2, 0, 0, 0, 37, 0, 0, 0, 0, 0, 34, 0, 3, 0, 0, 0, 36, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0,
+ 35, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 38, 0, 0, 0, 39, 0, 0, 0, 0, 0, 34, 0,
+ 40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 34, 0, 42, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0, 44, 0, 0, 0, 45, 0, 0, 0,
+ 0, 0, 34, 0, 30, 0, 0, 0, 38, 0, 0, 0, 0, 0, 34, 0, 26, 0, 0, 0, 39, 0, 0, 0, 0, 0, 34, 0, 22, 0, 0, 0,
+ 40, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0, 41, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0, 42, 0, 0, 0, 0, 0, 34, 0,
+ 13, 0, 0, 0, 43, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 44, 0, 0, 0, 0, 0, 34, 0, 5, 0, 0, 0, 45, 0, 0, 0,
+ 0, 0, 34, 0, 49, 0, 0, 0, 72, 0, 0, 0, 0, 0, 34, 0, 53, 0, 0, 0, 70, 0, 0, 0, 0, 0, 34, 0, 57, 0, 0, 0,
+ 68, 0, 0, 0, 0, 0, 34, 0, 61, 0, 0, 0, 66, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0,
+ 46, 0, 0, 0, 62, 0, 0, 0, 0, 0, 34, 0, 49, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0, 48, 0, 0, 0, 49, 0, 0, 0,
+ 0, 0, 34, 0, 48, 0, 0, 0, 52, 0, 0, 0, 0, 0, 34, 0, 47, 0, 0, 0, 48, 0, 0, 0, 0, 0, 34, 0, 47, 0, 0, 0,
+ 51, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 34, 0, 46, 0, 0, 0, 50, 0, 0, 0, 0, 0, 34, 0,
+ 53, 0, 0, 0, 57, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 53, 0, 0, 0, 0, 0, 34, 0, 52, 0, 0, 0, 56, 0, 0, 0,
+ 0, 0, 34, 0, 51, 0, 0, 0, 52, 0, 0, 0, 0, 0, 34, 0, 51, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0,
+ 51, 0, 0, 0, 0, 0, 34, 0, 50, 0, 0, 0, 54, 0, 0, 0, 0, 0, 34, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0,
+ 56, 0, 0, 0, 57, 0, 0, 0, 0, 0, 34, 0, 56, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0, 55, 0, 0, 0, 56, 0, 0, 0,
+ 0, 0, 34, 0, 55, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 54, 0, 0, 0, 55, 0, 0, 0, 0, 0, 34, 0, 54, 0, 0, 0,
+ 58, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0, 61, 0, 0, 0, 0, 0, 34, 0, 59, 0, 0, 0, 60, 0, 0, 0, 0, 0, 34, 0,
+ 58, 0, 0, 0, 59, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0, 66, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0, 68, 0, 0, 0,
+ 0, 0, 34, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 34, 0, 68, 0, 0, 0, 70, 0, 0, 0, 0, 0, 34, 0, 69, 0, 0, 0,
+ 70, 0, 0, 0, 0, 0, 34, 0, 67, 0, 0, 0, 69, 0, 0, 0, 0, 0, 34, 0, 70, 0, 0, 0, 72, 0, 0, 0, 0, 0, 34, 0,
+ 71, 0, 0, 0, 72, 0, 0, 0, 0, 0, 34, 0, 64, 0, 0, 0, 72, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 63, 0, 0, 0,
+ 0, 0, 34, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
+ 47, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 49, 0, 0, 0, 0, 0, 34, 0, 1, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0,
+ 33, 0, 0, 0, 58, 0, 0, 0, 0, 0, 34, 0, 29, 0, 0, 0, 54, 0, 0, 0, 0, 0, 34, 0, 25, 0, 0, 0, 50, 0, 0, 0,
+ 0, 0, 34, 0, 21, 0, 0, 0, 46, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0, 64, 0, 0, 0, 0, 0, 34, 0, 6, 0, 0, 0,
+ 63, 0, 0, 0, 0, 0, 34, 0, 75, 0, 0, 0, 76, 0, 0, 0, 0, 0, 34, 0, 73, 0, 0, 0, 74, 0, 0, 0, 0, 0, 34, 0,
+ 71, 0, 0, 0, 77, 0, 0, 0, 0, 0, 34, 0, 64, 0, 0, 0, 77, 0, 0, 0, 0, 0, 34, 0, 14, 0, 0, 0, 76, 0, 0, 0,
+ 0, 0, 34, 0, 15, 0, 0, 0, 75, 0, 0, 0, 0, 0, 34, 0, 16, 0, 0, 0, 74, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0,
+ 73, 0, 0, 0, 0, 0, 34, 0, 82, 0, 0, 0, 94, 0, 0, 0, 0, 0, 34, 0, 81, 0, 0, 0, 95, 0, 0, 0, 0, 0, 34, 0,
+ 80, 0, 0, 0, 96, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 78, 0, 0, 0, 83, 0, 0, 0,
+ 0, 0, 34, 0, 81, 0, 0, 0, 82, 0, 0, 0, 0, 0, 34, 0, 79, 0, 0, 0, 80, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0,
+105, 0, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 83, 0, 0, 0,110, 0, 0, 0, 0, 0, 34, 0,
+ 85, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0, 84, 0, 0, 0,110, 0, 0, 0,
+ 0, 0, 34, 0, 86, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0, 87, 0, 0, 0,102, 0, 0, 0, 0, 0, 34, 0, 88, 0, 0, 0,
+ 98, 0, 0, 0, 0, 0, 34, 0, 89, 0, 0, 0, 94, 0, 0, 0, 0, 0, 34, 0, 86, 0, 0, 0, 87, 0, 0, 0, 0, 0, 34, 0,
+ 88, 0, 0, 0, 89, 0, 0, 0, 0, 0, 34, 0, 93, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0,107, 0, 0, 0,
+ 0, 0, 34, 0, 91, 0, 0, 0,108, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0, 90, 0, 0, 0,
+ 91, 0, 0, 0, 0, 0, 34, 0, 92, 0, 0, 0, 93, 0, 0, 0, 0, 0, 34, 0, 97, 0, 0, 0,101, 0, 0, 0, 0, 0, 34, 0,
+ 96, 0, 0, 0, 97, 0, 0, 0, 0, 0, 34, 0, 96, 0, 0, 0,100, 0, 0, 0, 0, 0, 34, 0, 95, 0, 0, 0, 96, 0, 0, 0,
+ 0, 0, 34, 0, 95, 0, 0, 0, 99, 0, 0, 0, 0, 0, 34, 0, 94, 0, 0, 0, 95, 0, 0, 0, 0, 0, 34, 0, 94, 0, 0, 0,
+ 98, 0, 0, 0, 0, 0, 34, 0,101, 0, 0, 0,110, 0, 0, 0, 0, 0, 34, 0,101, 0, 0, 0,105, 0, 0, 0, 0, 0, 34, 0,
+100, 0, 0, 0,101, 0, 0, 0, 0, 0, 34, 0,100, 0, 0, 0,104, 0, 0, 0, 0, 0, 34, 0, 99, 0, 0, 0,100, 0, 0, 0,
+ 0, 0, 34, 0, 99, 0, 0, 0,103, 0, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 34, 0, 98, 0, 0, 0,
+102, 0, 0, 0, 0, 0, 34, 0,105, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0,104, 0, 0, 0,105, 0, 0, 0, 0, 0, 34, 0,
+104, 0, 0, 0,108, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,104, 0, 0, 0, 0, 0, 34, 0,103, 0, 0, 0,107, 0, 0, 0,
+ 0, 0, 34, 0,102, 0, 0, 0,103, 0, 0, 0, 0, 0, 34, 0,102, 0, 0, 0,106, 0, 0, 0, 0, 0, 34, 0,109, 0, 0, 0,
+111, 0, 0, 0, 0, 0, 34, 0,108, 0, 0, 0,109, 0, 0, 0, 0, 0, 34, 0,107, 0, 0, 0,108, 0, 0, 0, 0, 0, 34, 0,
+106, 0, 0, 0,107, 0, 0, 0, 0, 0, 34, 0, 65, 0, 0, 0, 78, 0, 0, 0, 0, 0, 34, 0, 66, 0, 0, 0, 83, 0, 0, 0,
+ 0, 0, 34, 0, 58, 0, 0, 0, 85, 0, 0, 0, 0, 0, 34, 0, 59, 0, 0, 0,111, 0, 0, 0, 0, 0, 34, 0, 60, 0, 0, 0,
+ 84, 0, 0, 0, 0, 0, 34, 0, 61, 0, 0, 0,110, 0, 0, 0, 0, 0, 34, 0, 30, 0, 0, 0, 93, 0, 0, 0, 0, 0, 34, 0,
+ 31, 0, 0, 0, 92, 0, 0, 0, 0, 0, 34, 0, 32, 0, 0, 0, 91, 0, 0, 0, 0, 0, 34, 0, 33, 0, 0, 0, 90, 0, 0, 0,
+ 0, 0, 34, 0,113, 0, 0, 0,130, 0, 0, 0, 0, 0, 35, 0,115, 0, 0, 0,131, 0, 0, 0, 0, 0, 35, 0,112, 0, 0, 0,
+132, 0, 0, 0, 0, 0, 35, 0,114, 0, 0, 0,133, 0, 0, 0, 0, 0, 35, 0,116, 0, 0, 0,125, 0, 0, 0, 0, 0, 35, 0,
+117, 0, 0, 0,126, 0, 0, 0, 0, 0, 35, 0,113, 0, 0, 0,115, 0, 0, 0, 0, 0, 35, 0,112, 0, 0, 0,115, 0, 0, 0,
+ 0, 0,163, 0,112, 0, 0, 0,114, 0, 0, 0, 0, 0, 35, 0,113, 0, 0, 0,116, 0, 0, 0, 0, 0,163, 0,116, 0, 0, 0,
+117, 0, 0, 0, 0, 0, 35, 0,118, 0, 0, 0,127, 0, 0, 0, 0, 0, 35, 0,118, 0, 0, 0,120, 0, 0, 0, 0, 0, 35, 0,
+127, 0, 0, 0,146, 0, 0, 0, 0, 0,163, 0,142, 0, 0, 0,146, 0, 0, 0, 0, 0, 35, 0,144, 0, 0, 0,147, 0, 0, 0,
+ 0, 0, 35, 0,129, 0, 0, 0,147, 0, 0, 0, 0, 0, 35, 0,128, 0, 0, 0,147, 0, 0, 0, 0, 0,163, 0,128, 0, 0, 0,
+146, 0, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,127, 0, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,120, 0, 0, 0, 0, 0, 35, 0,
+119, 0, 0, 0,121, 0, 0, 0, 0, 0, 35, 0,122, 0, 0, 0,124, 0, 0, 0, 0, 0, 35, 0,121, 0, 0, 0,122, 0, 0, 0,
+ 0, 0, 35, 0,121, 0, 0, 0,123, 0, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,124, 0, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,
+125, 0, 0, 0, 0, 0, 35, 0,125, 0, 0, 0,126, 0, 0, 0, 0, 0, 35, 0,132, 0, 0, 0,133, 0, 0, 0, 0, 0, 35, 0,
+131, 0, 0, 0,132, 0, 0, 0, 0, 0, 35, 0,130, 0, 0, 0,131, 0, 0, 0, 0, 0, 35, 0,133, 0, 0, 0,137, 0, 0, 0,
+ 0, 0,163, 0,136, 0, 0, 0,137, 0, 0, 0, 0, 0, 35, 0,132, 0, 0, 0,136, 0, 0, 0, 0, 0, 35, 0,135, 0, 0, 0,
+136, 0, 0, 0, 0, 0, 35, 0,131, 0, 0, 0,135, 0, 0, 0, 0, 0, 35, 0,134, 0, 0, 0,135, 0, 0, 0, 0, 0, 35, 0,
+130, 0, 0, 0,134, 0, 0, 0, 0, 0, 35, 0,137, 0, 0, 0,141, 0, 0, 0, 0, 0, 35, 0,140, 0, 0, 0,141, 0, 0, 0,
+ 0, 0, 35, 0,136, 0, 0, 0,140, 0, 0, 0, 0, 0, 35, 0,139, 0, 0, 0,140, 0, 0, 0, 0, 0, 35, 0,135, 0, 0, 0,
+139, 0, 0, 0, 0, 0, 35, 0,138, 0, 0, 0,139, 0, 0, 0, 0, 0, 35, 0,134, 0, 0, 0,138, 0, 0, 0, 0, 0, 35, 0,
+141, 0, 0, 0,145, 0, 0, 0, 0, 0,163, 0,144, 0, 0, 0,145, 0, 0, 0, 0, 0, 35, 0,140, 0, 0, 0,144, 0, 0, 0,
+ 0, 0, 35, 0,143, 0, 0, 0,144, 0, 0, 0, 0, 0, 35, 0,139, 0, 0, 0,143, 0, 0, 0, 0, 0, 35, 0,142, 0, 0, 0,
+143, 0, 0, 0, 0, 0, 35, 0,138, 0, 0, 0,142, 0, 0, 0, 0, 0, 35, 0,129, 0, 0, 0,145, 0, 0, 0, 0, 0, 35, 0,
+128, 0, 0, 0,143, 0, 0, 0, 0, 0, 35, 0,125, 0, 0, 0,130, 0, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,134, 0, 0, 0,
+ 0, 0, 35, 0,121, 0, 0, 0,138, 0, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,142, 0, 0, 0, 0, 0, 35, 0,151, 0, 0, 0,
+166, 0, 0, 0, 0, 0, 35, 0,150, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0,149, 0, 0, 0,168, 0, 0, 0, 0, 0, 35, 0,
+148, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0,152, 0, 0, 0,154, 0, 0, 0, 0, 0,163, 0,148, 0, 0, 0,149, 0, 0, 0,
+ 0, 0, 35, 0,150, 0, 0, 0,151, 0, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,
+174, 0, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,170, 0, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,166, 0, 0, 0, 0, 0, 35, 0,
+154, 0, 0, 0,155, 0, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,156, 0, 0, 0, 0, 0,163, 0,156, 0, 0, 0,157, 0, 0, 0,
+ 0, 0, 35, 0,153, 0, 0, 0,157, 0, 0, 0, 0, 0,163, 0,158, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,
+177, 0, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0,
+158, 0, 0, 0,159, 0, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,161, 0, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,163, 0, 0, 0,
+ 0, 0, 35, 0,164, 0, 0, 0,165, 0, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0,167, 0, 0, 0,
+168, 0, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0,169, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0,
+172, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,172, 0, 0, 0, 0, 0, 35, 0,171, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 35, 0,167, 0, 0, 0,171, 0, 0, 0, 0, 0, 35, 0,170, 0, 0, 0,171, 0, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,
+170, 0, 0, 0, 0, 0, 35, 0,173, 0, 0, 0,177, 0, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,177, 0, 0, 0, 0, 0, 35, 0,
+172, 0, 0, 0,176, 0, 0, 0, 0, 0, 35, 0,175, 0, 0, 0,176, 0, 0, 0, 0, 0, 35, 0,171, 0, 0, 0,175, 0, 0, 0,
+ 0, 0, 35, 0,174, 0, 0, 0,175, 0, 0, 0, 0, 0, 35, 0,170, 0, 0, 0,174, 0, 0, 0, 0, 0, 35, 0,177, 0, 0, 0,
+181, 0, 0, 0, 0, 0, 35, 0,180, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,180, 0, 0, 0, 0, 0, 35, 0,
+179, 0, 0, 0,180, 0, 0, 0, 0, 0, 35, 0,175, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0,178, 0, 0, 0,179, 0, 0, 0,
+ 0, 0, 35, 0,174, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0,165, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,
+180, 0, 0, 0, 0, 0, 35, 0,163, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0,
+ 68, 65, 84, 65, 44, 1, 0, 0, 88, 7,153, 2, 21, 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,208,203,131, 2, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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, 30,161, 2, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,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,248, 20,155, 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,
+ 68, 65, 84, 65,200, 5, 0, 0,208,203,131, 2, 53, 0, 0, 0, 74, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 45, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0,
+ 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 16, 0, 0, 0,
+ 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 14, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 17, 0, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 76, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0,
+ 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 25, 0, 0, 0, 21, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0,
+ 24, 0, 0, 0, 23, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0,
+ 18, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 28, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0,
+ 26, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 33, 0, 0, 0, 29, 0, 0, 0, 54, 0, 0, 0,
+ 0, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 38, 0, 0, 0,
+ 39, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0,
+ 92, 0, 0, 0, 93, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 48, 0, 0, 0, 63, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0,
+ 51, 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 56, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0,
+ 0, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 50, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0,
+ 55, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, 0, 84, 0, 0, 0, 60, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0,
+111, 0, 0, 0, 85, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 83, 0, 0, 0, 66, 0, 0, 0,
+ 65, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 61, 0, 0, 0, 57, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0,
+ 68, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 72, 0, 0, 0,
+ 0, 0, 0, 0, 71, 0, 0, 0, 72, 0, 0, 0, 64, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0,
+ 97, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 94, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0,
+110, 0, 0, 0,101, 0, 0, 0, 97, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 99, 0, 0, 0, 95, 0, 0, 0,
+ 96, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0,
+104, 0, 0, 0,100, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0,103, 0, 0, 0,102, 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0,
+ 0, 0, 0, 0,111, 0, 0, 0,109, 0, 0, 0,105, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0,108, 0, 0, 0,107, 0, 0, 0,
+103, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0,106, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0,
+ 90, 0, 0, 0, 91, 0, 0, 0,108, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0,106, 0, 0, 0,
+107, 0, 0, 0, 0, 0, 0, 0,120, 0, 0, 0,119, 0, 0, 0,127, 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 2,121, 0, 0, 0,
+138, 0, 0, 0,142, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 2,124, 0, 0, 0,123, 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0,
+ 0, 0, 0, 2,125, 0, 0, 0,130, 0, 0, 0,134, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 2,117, 0, 0, 0,116, 0, 0, 0,
+125, 0, 0, 0,126, 0, 0, 0, 0, 0, 0, 2,112, 0, 0, 0,114, 0, 0, 0,133, 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 2,
+113, 0, 0, 0,115, 0, 0, 0,131, 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 2,131, 0, 0, 0,132, 0, 0, 0,136, 0, 0, 0,
+135, 0, 0, 0, 0, 0, 0, 2,136, 0, 0, 0,137, 0, 0, 0,141, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 2,134, 0, 0, 0,
+135, 0, 0, 0,139, 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 2,139, 0, 0, 0,140, 0, 0, 0,144, 0, 0, 0,143, 0, 0, 0,
+ 0, 0, 0, 2,129, 0, 0, 0,147, 0, 0, 0,144, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 2,142, 0, 0, 0,143, 0, 0, 0,
+128, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 2,149, 0, 0, 0,148, 0, 0, 0,169, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 2,
+151, 0, 0, 0,150, 0, 0, 0,167, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 2,169, 0, 0, 0,161, 0, 0, 0,160, 0, 0, 0,
+173, 0, 0, 0, 0, 0, 0, 2,167, 0, 0, 0,168, 0, 0, 0,172, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 2,154, 0, 0, 0,
+166, 0, 0, 0,170, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 2,172, 0, 0, 0,173, 0, 0, 0,177, 0, 0, 0,176, 0, 0, 0,
+ 0, 0, 0, 2,170, 0, 0, 0,171, 0, 0, 0,175, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 2,177, 0, 0, 0,159, 0, 0, 0,
+158, 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 2,175, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 0,179, 0, 0, 0, 0, 0, 0, 2,
+156, 0, 0, 0,174, 0, 0, 0,178, 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 2,180, 0, 0, 0,181, 0, 0, 0,165, 0, 0, 0,
+164, 0, 0, 0, 0, 0, 0, 2,178, 0, 0, 0,179, 0, 0, 0,163, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 2, 68, 65, 84, 65,
+184, 12, 0, 0,176, 30,161, 2, 61, 0, 0, 0, 74, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,120, 47, 41, 63,
+160, 84,104, 61, 0, 29, 3, 63, 26, 95, 82, 62,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,
+113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63,127, 84,181, 62,242, 65, 79, 63,190,188, 0, 63,102, 84,117, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61, 0, 29, 3, 63,128,106,188,189,176, 20,186, 62,144, 82,104, 61,128,223, 91, 62,
+ 14, 95, 82, 62, 0, 21,186, 62, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,127, 84,181, 62,242, 65, 79, 63, 26, 95, 82, 62,
+120, 47, 41, 63,122, 84,181, 62,248, 28, 3, 63,188,188, 0, 63,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 56,207, 38, 63,111,179,141, 63,190,188, 0, 63,102, 84,117, 63, 52,207, 38, 63,236, 65, 79, 63,172,225, 76, 63,102, 84,117, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,248, 28, 3, 63, 14, 95, 82, 62, 0, 21,186, 62,122, 84,181, 62,
+ 32,224, 91, 62,185,188, 0, 63, 0, 21,186, 62, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,236, 65, 79, 63,
+188,188, 0, 63,120, 47, 41, 63, 52,207, 38, 63,248, 28, 3, 63,174,225, 76, 63,116, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,122, 84,181, 62, 32,224, 91, 62,138, 94, 82, 62, 48, 43,135, 61, 61, 84,181, 62,176,104,169,189,185,188, 0, 63,
+ 96, 44,135, 61, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,248, 28, 3, 63,185,188, 0, 63, 0, 21,186, 62,
+ 51,207, 38, 63, 24,224, 91, 62,174,225, 76, 63, 0, 21,186, 62, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,
+236, 65, 79, 63,174,225, 76, 63,116, 47, 41, 63, 42,244,114, 63,244, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 51,207, 38, 63, 24,224, 91, 62,185,188, 0, 63, 96, 44,135, 61,248,207, 38, 63,144,109,169,189,
+112,226, 76, 63, 64, 38,135, 61, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,240,244,114, 63, 4,221, 91, 62,180,131,140, 63,
+116, 19,186, 62, 42,244,114, 63,244, 28, 3, 63,174,225, 76, 63, 0, 21,186, 62, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,120, 47, 41, 63,128,105,188,189,
+120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,
+122, 84,181, 62,113,179,141, 63,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,
+102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63,
+ 64,127,118,190,216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,
+113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,120, 47, 41, 63,128,105,188,189,120, 47, 41, 63,
+160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,
+113,179,141, 63,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 26, 95, 82, 62,102, 84,117, 63,200, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 96,105,188,189,120, 47, 41, 63, 56,127,118,190,220, 28, 3, 63, 64,127,118,190,
+216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,113,179,141, 63,
+ 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,200, 84,104, 61,244, 65, 79, 63, 96,105,188,189,120, 47, 41, 63, 96,105,188,189,120, 47, 41, 63,200, 84,104, 61,
+242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,172,225, 76, 63,102, 84,117, 63,
+172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,
+173,188,160, 63, 56,207, 38, 63,111,179,141, 63, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,172,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63, 52,207, 38, 63,111,179,141, 63,
+172,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,172,225, 76, 63,
+102, 84,117, 63,172,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,111,179,141, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,174,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63, 52,207, 38, 63,
+111,179,141, 63,172,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,
+174,225, 76, 63,102, 84,117, 63,174,225, 76, 63,102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,190,188, 0, 63,171,188,160, 63,188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,
+111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,162,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 72, 47, 41, 63,
+ 99,131,140, 63, 76, 47, 41, 63,161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63,
+ 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,
+161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63, 76, 47, 41, 63, 44,244,114, 63,
+236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+161,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,244,140,159, 63, 50, 28, 3, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 22,172,131, 63, 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59,224,151,158, 63,
+ 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,144,128, 81, 63, 96,211, 93, 59,
+247,168, 27, 63, 96,211, 93, 59,248,168, 27, 63, 96,211, 93, 59,144,128, 81, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0,176,131,185, 63, 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59,224,151,158, 63, 96,211, 93, 59,174,131,185, 63,
+ 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 21,172,131, 63, 96,211, 93, 59,144,128, 81, 63, 96,211, 93, 59,
+144,128, 81, 63, 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,247,168, 27, 63,
+ 96,211, 93, 59, 85,162,203, 62, 96,211, 93, 59, 85,162,203, 62, 96,211, 93, 59,247,168, 27, 63, 96,211, 93, 59, 0, 0, 0, 0,
+ 61, 0, 1, 0, 0, 0, 0, 0,226,151,158, 63, 96,211, 93, 59, 24,172,131, 63, 96,211, 93, 59, 21,172,131, 63, 96,211, 93, 59,
+226,151,158, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,142,128, 81, 63, 96,211, 93, 59,246,168, 27, 63,
+ 96,211, 93, 59,247,168, 27, 63, 96,211, 93, 59,144,128, 81, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,
+174,131,185, 63, 96,211, 93, 59,227,151,158, 63, 96,211, 93, 59,226,151,158, 63, 96,211, 93, 59,174,131,185, 63, 96,211, 93, 59,
+ 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 22,172,131, 63, 96,211, 93, 59,149,128, 81, 63, 96,211, 93, 59,142,128, 81, 63,
+ 96,211, 93, 59, 24,172,131, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,251,168, 27, 63, 96,211, 93, 59,
+ 84,162,203, 62, 96,211, 93, 59, 86,162,203, 62, 96,211, 93, 59,246,168, 27, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0,225,151,158, 63, 96,211, 93, 59, 21,172,131, 63, 96,211, 93, 59, 22,172,131, 63, 96,211, 93, 59,227,151,158, 63,
+ 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,146,128, 81, 63, 96,211, 93, 59,250,168, 27, 63, 96,211, 93, 59,
+251,168, 27, 63, 96,211, 93, 59,149,128, 81, 63, 96,211, 93, 59, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,
+210, 28, 3, 63, 99,131,140, 63, 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,244,140,159, 63, 50, 28, 3, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 99,131,140, 63, 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63,
+ 99,131,140, 63, 76, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,161,140,159, 63,210, 28, 3, 63, 99,131,140, 63,
+ 76, 47, 41, 63, 99,131,140, 63, 76, 47, 41, 63,161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+ 99,131,140, 63, 76, 47, 41, 63, 44,244,114, 63,236, 65, 79, 63, 44,244,114, 63,236, 65, 79, 63, 99,131,140, 63, 76, 47, 41, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,162,140,159, 63,210, 28, 3, 63, 99,131,140, 63, 72, 47, 41, 63, 99,131,140, 63,
+ 76, 47, 41, 63,161,140,159, 63,210, 28, 3, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,111,179,141, 63,
+190,188, 0, 63,171,188,160, 63,188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,174,225, 76, 63,102, 84,117, 63,174,225, 76, 63,102, 84,117, 63, 44,244,114, 63,
+236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,174,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,111,179,141, 63,
+ 52,207, 38, 63,111,179,141, 63,172,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 52,207, 38, 63,
+111,179,141, 63,188,188, 0, 63,173,188,160, 63,188,188, 0, 63,173,188,160, 63, 52,207, 38, 63,111,179,141, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,102, 84,117, 63,
+ 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,172,225, 76, 63,102, 84,117, 63, 52,207, 38, 63,
+111,179,141, 63, 52,207, 38, 63,111,179,141, 63,172,225, 76, 63,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+188,188, 0, 63,173,188,160, 63, 56,207, 38, 63,111,179,141, 63, 52,207, 38, 63,111,179,141, 63,188,188, 0, 63,173,188,160, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 44,244,114, 63,236, 65, 79, 63,172,225, 76, 63,102, 84,117, 63,172,225, 76, 63,
+102, 84,117, 63, 44,244,114, 63,236, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,200, 84,104, 61,244, 65, 79, 63,
+ 96,105,188,189,120, 47, 41, 63, 96,105,188,189,120, 47, 41, 63,200, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,
+113,179,141, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 96,105,188,189,120, 47, 41, 63, 56,127,118,190,220, 28, 3, 63,
+ 64,127,118,190,216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,
+102, 84,117, 63,200, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,113,179,141, 63,122, 84,181, 62,113,179,141, 63,
+188,188, 0, 63,173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,
+120, 47, 41, 63,128,105,188,189,120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,
+122, 84,181, 62,113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63,
+ 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,128,105,188,189,120, 47, 41, 63, 64,127,118,190,216, 28, 3, 63, 64,127,118,190,
+216, 28, 3, 63,128,105,188,189,120, 47, 41, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 26, 95, 82, 62,102, 84,117, 63,
+160, 84,104, 61,242, 65, 79, 63,160, 84,104, 61,242, 65, 79, 63, 26, 95, 82, 62,102, 84,117, 63, 0, 0, 0, 0, 60, 0, 1, 0,
+ 0, 0, 0, 0,188,188, 0, 63,173,188,160, 63,122, 84,181, 62,113,179,141, 63,122, 84,181, 62,113,179,141, 63,188,188, 0, 63,
+173,188,160, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,160, 84,104, 61,242, 65, 79, 63,128,105,188,189,120, 47, 41, 63,
+128,105,188,189,120, 47, 41, 63,160, 84,104, 61,242, 65, 79, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0,122, 84,181, 62,
+113,179,141, 63, 26, 95, 82, 62,102, 84,117, 63, 26, 95, 82, 62,102, 84,117, 63,122, 84,181, 62,113,179,141, 63, 0, 0, 0, 0,
+ 60, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65,160, 4, 0, 0,248, 20,155, 2, 58, 0, 0, 0, 40, 1, 0, 0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0,
+ 12, 1, 0, 0,208, 84,164, 2, 51, 0, 0, 0, 1, 0, 0, 0,192, 26,131, 2,240, 0, 18, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 77, 69, 80,108, 97,110,101, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,208,194,149, 2,224,100,152, 2,
+248, 27,129, 2, 0, 0, 0, 0, 48, 17,167, 2, 64, 11,167, 2, 0, 0, 0, 0,200,209,131, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,136,237,150, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,104, 64, 18, 3, 1, 0, 0, 0,
+ 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,152,126, 20, 3, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+ 23, 0, 0, 0, 32, 0, 0, 0, 8, 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, 4,205, 76, 63,172,197, 39, 55,214,204, 76, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 30, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 4, 0, 0, 0,208,194,149, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 44, 1, 0, 0,136,237,150, 2,
+ 21, 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,
+ 48, 17,167, 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, 68, 65, 84, 65,204, 1, 0, 0, 48, 17,167, 2,
+ 57, 0, 0, 0, 23, 0, 0, 0, 4,205, 76,191, 0, 0, 0, 0,208,204,204,190, 0, 0, 1,128, 0, 0, 3, 1, 55,205,204,190,
+ 0, 0, 0, 0,216,204,204,190, 0, 0, 1,128, 0, 0, 3, 1, 0, 0, 70,182, 0, 0,128, 52,224,204,204,190, 0, 0, 1,128,
+ 0, 0, 3, 1, 4,205, 76,191, 0, 0, 0, 0, 0, 0, 96, 52, 0, 0, 1,128, 0, 0, 3, 1, 55,205,204,190, 0, 0, 0, 0,
+ 0, 0, 0,179, 0, 0, 1,128, 0, 0, 3, 1, 0, 0, 70,182, 0, 0,128, 52, 0, 0,144,180, 0, 0, 1,128, 0, 0, 3, 1,
+ 4,205, 76,191, 0, 0, 0, 0,213,204,204, 62, 0, 0, 1,128, 0, 0, 3, 1, 55,205,204,190, 0, 0, 0, 0,205,204,204, 62,
+ 0, 0, 1,128, 0, 0, 3, 1, 0, 0, 70,182, 0, 0,128, 52,197,204,204, 62, 0, 0, 1,128, 0, 0, 3, 1, 47,205,204,190,
+ 0, 0, 0, 0,206,204, 76, 63, 0, 0, 1,128, 0, 0, 3, 1, 0, 0, 62,182, 0, 0,128, 52,206,204, 76, 63, 0, 0, 1,128,
+ 0, 0, 3, 1, 4,205, 76,191, 0, 0, 0, 0,208,204, 76,191, 0, 0, 1,128, 0, 0, 3, 1, 55,205,204,190, 0, 0, 0, 0,
+212,204, 76,191, 0, 0, 1,128, 0, 0, 3, 1, 0, 0, 70,182, 0, 0,128, 52,214,204, 76,191, 0, 0, 1,128, 0, 0, 3, 1,
+ 47,205,204, 62, 0, 0,128,180,206,204, 76,191, 0, 0, 1,128, 0, 0, 3, 1, 4,205, 76, 63, 0, 0, 0, 0,210,204, 76, 63,
+ 0, 0, 1,128, 0, 0, 3, 1, 53,205,204, 62, 0, 0,128,180,214,204, 76, 63, 0, 0, 1,128, 0, 0, 3, 1, 0,205, 76, 63,
+ 0, 0, 0, 0,213,204,204, 62, 0, 0, 1,128, 0, 0, 3, 1, 47,205,204, 62, 0, 0,128,180,221,204,204, 62, 0, 0, 1,128,
+ 0, 0, 3, 1, 0,205, 76, 63, 0, 0, 0, 0, 0, 0, 96, 52, 0, 0, 1,128, 0, 0, 3, 1, 47,205,204, 62, 0, 0,128,180,
+ 0, 0,240, 52, 0, 0, 1,128, 0, 0, 3, 1, 0,205, 76, 63, 0, 0, 0, 0,208,204,204,190, 0, 0, 1,128, 0, 0, 3, 1,
+ 47,205,204, 62, 0, 0,128,180,200,204,204,190, 0, 0, 1,128, 0, 0, 3, 1, 68, 65, 84, 65, 44, 1, 0, 0,104, 64, 18, 3,
+ 21, 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,
+ 64, 11,167, 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, 68, 65, 84, 65,128, 1, 0, 0, 64, 11,167, 2,
+ 54, 0, 0, 0, 32, 0, 0, 0, 2, 0, 0, 0, 22, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 35, 0,
+ 8, 0, 0, 0, 18, 0, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0, 13, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 13, 0, 0, 0,
+ 0, 0, 35, 0, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 35, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 35, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0,
+ 7, 0, 0, 0, 9, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 35, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 35, 0, 16, 0, 0, 0,
+ 18, 0, 0, 0, 0, 0, 35, 0, 17, 0, 0, 0, 18, 0, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0, 17, 0, 0, 0, 0, 0, 35, 0,
+ 18, 0, 0, 0, 20, 0, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 35, 0, 20, 0, 0, 0, 22, 0, 0, 0,
+ 0, 0, 35, 0, 21, 0, 0, 0, 22, 0, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0, 21, 0, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0,
+ 22, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65, 44, 1, 0, 0,152,126, 20, 3, 21, 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,224,100,152, 2, 5, 0, 0, 0, 20, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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, 27,129, 2, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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,200,209,131, 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, 68, 65, 84, 65,160, 0, 0, 0,224,100,152, 2, 53, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 2, 7, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 2, 10, 0, 0, 0, 9, 0, 0, 0,
+ 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2, 15, 0, 0, 0, 16, 0, 0, 0, 18, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 2,
+ 18, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 2, 22, 0, 0, 0, 21, 0, 0, 0, 19, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 2, 22, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 2, 68, 65, 84, 65,
+ 96, 1, 0, 0,248, 27,129, 2, 61, 0, 0, 0, 8, 0, 0, 0, 12,192,137, 62,162,226,125, 63,144,108,246, 61,162,226,125, 63,
+144,108,246, 61,162,226,125, 63, 12,192,137, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,252,228,213, 62,
+162,226,125, 63, 12,192,137, 62,162,226,125, 63, 12,192,137, 62,162,226,125, 63,252,228,213, 62,162,226,125, 63, 0, 0, 0, 0,
+ 61, 0, 1, 0, 0, 0, 0, 0, 12,192,137, 62,162,226,125, 63,144,108,246, 61,162,226,125, 63,144,108,246, 61,162,226,125, 63,
+ 12,192,137, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 0,229,213, 62,162,226,125, 63, 18,192,137, 62,
+162,226,125, 63, 12,192,137, 62,162,226,125, 63,252,228,213, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,
+154, 23, 55, 63,162,226,125, 63, 34, 5, 17, 63,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63,152, 23, 55, 63,162,226,125, 63,
+ 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 30, 5, 17, 63,162,226,125, 63,252,228,213, 62,162,226,125, 63,252,228,213, 62,
+162,226,125, 63, 30, 5, 17, 63,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 30, 5, 17, 63,162,226,125, 63,
+152, 23, 55, 63,162,226,125, 63,152, 23, 55, 63,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0, 30, 5, 17, 63,162,226,125, 63,252,228,213, 62,162,226,125, 63,252,228,213, 62,162,226,125, 63, 30, 5, 17, 63,
+162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65,128, 0, 0, 0,200,209,131, 2, 58, 0, 0, 0,
+ 32, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,192, 26,131, 2, 51, 0, 0, 0, 1, 0, 0, 0,200, 25,155, 2,208, 84,164, 2,
+192,139, 5, 8, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 51, 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,
+120, 97,155, 2, 64,107, 8, 3, 0,235,128, 2, 0, 0, 0, 0,184, 28,167, 2,160,248,129, 2, 0, 0, 0, 0, 40,197, 32, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56,133, 20, 3, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 28,131, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 80,250,129, 2, 3, 0, 0, 0, 5, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 0, 2,205, 76, 63,172,197, 39, 55,214,204, 76, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,120, 97,155, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
+ 44, 1, 0, 0, 56,133, 20, 3, 21, 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,184, 28,167, 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, 68, 65, 84, 65,
- 0, 0, 14, 56, 5, 32, 86, 32, 0, 0, 0, 56, 0, 0, 0,182, 63,230,102,133, 63,179, 51,208,191,128, 0, 4,165,127, 0, 0,
- 90,129, 2,255, 63,230,102,133, 63, 25,154,206,191,128, 0, 4,165,127, 0, 0, 90,129, 2,255, 63,179, 51, 81, 63,179, 51,210,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28, 63,179, 51,212,191,128, 0, 1, 0, 0, 0, 0,127,255, 2,255,
- 63, 25,153,207, 63,179, 51,214,191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,152, 63,179, 51,216,191,127,255,254,
- 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63,128, 0,158,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27,
- 63,128, 0,160,191,128, 0, 2, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 63,128, 0,162,191,128, 0, 0, 0, 0, 0, 0,
-127,255, 2,255, 62, 76,205,140, 63,128, 0,163,191,127,255,254, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63, 25,154,209,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27, 63, 25,154,213,191,128, 0, 2, 0, 0, 0, 0,127,255, 2,255,
- 63, 25,153,204, 63, 25,154,217,191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63, 25,154,221,191,127,255,254,
- 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 62, 76,209,160,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27,
- 62, 76,209,176,191,128, 0, 2, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 62, 76,209,188,191,128, 0, 1, 0, 0, 0, 0,
-127,255, 2,255, 62, 76,205,140, 62, 76,209,204,191,127,255,255, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63,230,103, 8,
-191, 25,153,156, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,204, 63,230,103, 10,191, 25,153,160, 0, 0,128, 1, 0, 0, 2,255,
- 63,128, 0, 27, 63,230,103, 10,191, 25,153,164, 0, 0,128, 1, 0, 0, 2,255, 63,179, 51, 80, 63,230,103, 12,191, 25,153,168,
- 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8,190, 76,204,196, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,204,
- 63,230,103, 10,190, 76,204,212, 0, 0,128, 1, 0, 0, 2,255, 63,128, 0, 27, 63,230,103, 10,190, 76,204,228, 0, 0,128, 1,
- 0, 0, 2,255, 63,179, 51, 80, 63,230,103, 12,190, 76,204,244, 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8,
- 62, 76,204,216, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,204, 63,230,103, 10, 62, 76,204,200, 0, 0,128, 1, 0, 0, 2,255,
- 63,128, 0, 27, 63,230,103, 10, 62, 76,204,184, 0, 0,128, 1, 0, 0, 2,255, 63,179, 51, 80, 63,230,103, 12, 62, 76,204,168,
- 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,152, 63,230,103, 8, 63, 25,153,158, 0, 0,128, 1, 0, 0, 2,255, 63, 25,153,207,
- 63,230,103, 10, 63, 25,153,154, 0, 0,128, 1, 0, 0, 2,255, 63,128, 0, 28, 63,230,103, 10, 63, 25,153,150, 0, 0,128, 1,
- 0, 0, 2,255, 63,179, 51, 81, 63,230,103, 12, 63, 25,153,150, 0, 0,128, 1, 0, 0, 2,255, 62, 76,205,140, 63,230,103, 8,
-191,128, 0, 3, 0, 0,165,127, 90,129, 0,255, 63, 25,153,204, 63,230,103, 10,191,128, 0, 4, 0, 0,165,127, 90,129, 0,255,
- 63,128, 0, 27, 63,230,103, 10,191,128, 0, 6, 0, 0,165,127, 90,129, 0,255, 63,179, 51, 80, 63,230,103, 12,191,128, 0, 7,
- 0, 0,165,127, 90,129, 0,255,190, 76,205,144, 63,230,103, 12, 63, 25,153,150, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152,
- 63,230,103, 12, 62, 76,204,168, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152, 63,230,103, 12,190, 76,204,244, 0, 0,128, 1,
- 0, 0, 2,255,190, 76,205,152, 63,230,103, 12,191, 25,153,168, 0, 0,128, 1, 0, 0, 2,255,190, 76,205,152, 62, 76,209,160,
-191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63, 25,154,209,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,
-190, 76,205,152, 63,128, 0,158,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255,190, 76,205,144, 63,179, 51,210,191,128, 0, 3,
- 0, 0, 0, 0,127,255, 2,255, 63,230,102,131, 63,230,103, 7,191, 25,153,155,165,127,165,127, 0, 0, 2,255, 63,230,102,131,
- 63,179, 51,212,191, 25,153,159,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,128, 0,160,191, 25,153,163,128, 1, 0, 0,
- 0, 0, 2,255, 63,230,102,135, 63, 25,154,207,191, 25,153,167,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7,
-190, 76,204,193,165,127,165,127, 0, 0, 2,255, 63,230,102,131, 63,179, 51,212,190, 76,204,209,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,131, 63,128, 0,160,190, 76,204,225,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,135, 63, 25,154,207,190, 76,204,241,
-128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7, 62, 76,204,219,165,127,165,127, 0, 0, 2,255, 63,230,102,131,
- 63,179, 51,212, 62, 76,204,203,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,128, 0,160, 62, 76,204,187,128, 1, 0, 0,
- 0, 0, 2,255, 63,230,102,135, 63, 25,154,207, 62, 76,204,171,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7,
- 63, 25,153,159,165,127,165,127, 0, 0, 2,255, 63,230,102,131, 63,179, 51,212, 63, 25,153,155,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,131, 63,128, 0,156, 63, 25,153,151,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,135, 63, 25,154,207, 63, 25,153,151,
-128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131, 63,230,103, 7,191,128, 0, 3,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,
- 63,128, 0,160,191,128, 0, 6,165,127, 0, 0, 90,129, 2,255, 63,230,102,127, 62, 76,208, 28,191,128, 0, 3,165,127, 0, 0,
- 90,129, 2,255, 63,230,102,131,190, 76,201,136, 63, 25,153,155,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28,
- 63, 25,153,159,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,190, 76,201,136, 62, 76,204,203,128, 1, 0, 0, 0, 0, 2,255,
- 63,230,102,127, 62, 76,208, 28, 62, 76,204,219,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,190, 76,201,136,190, 76,204,209,
-128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28,190, 76,204,193,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,131,
-190, 76,201,136,191, 25,153,159,128, 1, 0, 0, 0, 0, 2,255, 63,230,102,127, 62, 76,208, 28,191, 25,153,155,128, 1, 0, 0,
- 0, 0, 2,255, 62, 76,205,150,190, 76,208, 24,191,127,255,254, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,207,190, 76,208, 40,
-191,128, 0, 0, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28,190, 76,208, 56,191,128, 0, 1, 0, 0, 0, 0,127,255, 2,255,
- 63,179, 51, 81,190, 76,208, 72,191,128, 0, 3, 0, 0, 0, 0,127,255, 2,255, 63,230,102,133,190, 76,208, 88,191,128, 0, 4,
-128, 1, 0, 0, 0, 0, 2,255, 63,230,102,133,190, 76,208, 88, 63,127,255,146,128, 1, 0, 0, 0, 0, 2,255, 63,179, 51, 81,
-190, 76,208, 72, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 28,190, 76,208, 56, 63,127,255,152, 0, 0, 0, 0,
-127,255, 2,255, 63, 25,153,207,190, 76,208, 40, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,150,190, 76,208, 24,
- 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63,230,102,127, 62, 76,208, 28, 63,127,255,148,165,127, 0, 0, 90,129, 2,255,
- 63,230,102,131, 63,128, 0,160, 63,127,255,142,165,127, 0, 0, 90,129, 2,255, 63,230,102,131, 63,230,103, 7, 63,127,255,148,
-128, 1, 0, 0, 0, 0, 2,255,190, 76,205,144, 63,179, 51,210, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152,
- 63,128, 0,158, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255,190, 76,205,152, 63, 25,154,209, 63,127,255,148, 0, 0, 0, 0,
-127,255, 2,255,190, 76,205,152, 62, 76,209,160, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63,230,103, 12,
- 63,127,255,140, 0, 0,165,127, 90,129, 2,255, 63,128, 0, 27, 63,230,103, 10, 63,127,255,142, 0, 0,165,127, 90,129, 2,255,
- 63, 25,153,204, 63,230,103, 10, 63,127,255,146, 0, 0,165,127, 90,129, 2,255, 62, 76,205,140, 63,230,103, 8, 63,127,255,148,
- 0, 0,165,127, 90,129, 2,255, 62, 76,205,140, 62, 76,209,204, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204,
- 62, 76,209,188, 63,127,255,152, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27, 62, 76,209,176, 63,127,255,150, 0, 0, 0, 0,
-127,255, 2,255, 63,179, 51, 80, 62, 76,209,160, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63, 25,154,221,
- 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204, 63, 25,154,217, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255,
- 63,128, 0, 27, 63, 25,154,213, 63,127,255,150, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 80, 63, 25,154,209, 63,127,255,148,
- 0, 0, 0, 0,127,255, 2,255, 62, 76,205,140, 63,128, 0,163, 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,204,
- 63,128, 0,162, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 27, 63,128, 0,160, 63,127,255,150, 0, 0, 0, 0,
-127,255, 2,255, 63,179, 51, 80, 63,128, 0,158, 63,127,255,148, 0, 0, 0, 0,127,255, 2,255, 62, 76,205,152, 63,179, 51,216,
- 63,127,255,156, 0, 0, 0, 0,127,255, 2,255, 63, 25,153,207, 63,179, 51,214, 63,127,255,154, 0, 0, 0, 0,127,255, 2,255,
- 63,128, 0, 28, 63,179, 51,212, 63,127,255,152, 0, 0, 0, 0,127,255, 2,255, 63,179, 51, 81, 63,179, 51,210, 63,127,255,148,
- 0, 0, 0, 0,127,255, 2,255, 63,230,102,133, 63, 25,154,206, 63,127,255,146,165,127, 0, 0, 90,129, 2,255, 63,230,102,133,
- 63,179, 51,208, 63,127,255,146,165,127, 0, 0, 90,129, 2,255,190, 76,205,144, 62, 76,201,140, 63,127,255,148,127,255, 0, 0,
- 0, 0, 1,255,190, 76,205,136, 63,127,255, 52, 63,127,255,148,127,255, 0, 0, 0, 0, 1,255,190, 76,205,128,190, 76,208, 48,
- 63,127,255,150,127,255, 0, 0, 0, 0, 3,255,190, 76,205,120, 63, 25,152,194, 63,127,255,144,127,255, 0, 0, 0, 0, 1,255,
-190, 76,205, 80, 63,179, 50,254, 63,127,255,150,127,255, 0, 0, 0, 0, 1,255,190, 76,205,128, 63,230,103, 12, 63,127,255,148,
-127,255, 0, 0, 0, 0, 3,255,190, 76,205,128, 63,230,103, 12,191,128, 0, 5,127,255, 0, 0, 0, 0, 3,255,190, 76,205, 80,
- 63,179, 50,254,191, 25,153,156,127,255, 0, 0, 0, 0, 3,255,190, 76,205,112, 63,230,102, 50,191, 25,153,160,127,255, 0, 0,
- 0, 0, 3,255,190, 76,205, 80, 63,179, 50,254,190, 76,204,195,127,255, 0, 0, 0, 0, 3,255,190, 76,205,112, 63,230,102, 50,
-190, 76,204,211,127,255, 0, 0, 0, 0, 3,255,190, 76,205, 80, 63,179, 50,254, 62, 76,204,221,127,255, 0, 0, 0, 0, 3,255,
-190, 76,205,112, 63,230,102, 50, 62, 76,204,205,127,255, 0, 0, 0, 0, 3,255,190, 76,205, 80, 63,179, 50,254, 63, 25,153,160,
-127,255, 0, 0, 0, 0, 3,255,190, 76,205,112, 63,230,102, 50, 63, 25,153,156,127,255, 0, 0, 0, 0, 3,255,190, 76,205, 80,
- 63,179, 50,254,191,128, 0, 4,127,255, 0, 0, 0, 0, 1,255,190, 76,205,120, 63, 25,152,194,191,128, 0, 7,127,255, 0, 0,
- 0, 0, 1,255,190, 76,205,128,190, 76,208, 48,191,128, 0, 4,127,255, 0, 0, 0, 0, 3,255,190, 76,205,152, 63,127,255, 52,
- 63, 25,153,152,127,255, 0, 0, 0, 0, 3,255,190, 76,205,120, 63, 25,152,202, 63, 25,153,152,127,255, 0, 0, 0, 0, 3,255,
-190, 76,205,128, 62, 76,201,108, 63, 25,153,156,127,255, 0, 0, 0, 0, 3,255,190, 76,205,128,190, 76,208, 48, 63, 25,153,160,
-127,255, 0, 0, 0, 0, 1,255,190, 76,205,152, 63,127,255, 52, 62, 76,204,173,127,255, 0, 0, 0, 0, 3,255,190, 76,205,120,
- 63, 25,152,194, 62, 76,204,189,127,255, 0, 0, 0, 0, 3,255,190, 76,205,128, 62, 76,201,108, 62, 76,204,205,127,255, 0, 0,
- 0, 0, 3,255,190, 76,205,128,190, 76,208, 48, 62, 76,204,221,127,255, 0, 0, 0, 0, 1,255,190, 76,205,152, 63,127,255, 52,
-190, 76,204,243,127,255, 0, 0, 0, 0, 3,255,190, 76,205,120, 63, 25,152,194,190, 76,204,227,127,255, 0, 0, 0, 0, 3,255,
-190, 76,205,128, 62, 76,201,108,190, 76,204,211,127,255, 0, 0, 0, 0, 3,255,190, 76,205,128,190, 76,208, 48,190, 76,204,195,
-127,255, 0, 0, 0, 0, 1,255,190, 76,205,152, 63,127,255, 52,191, 25,153,168,127,255, 0, 0, 0, 0, 3,255,190, 76,205,120,
- 63, 25,152,194,191, 25,153,164,127,255, 0, 0, 0, 0, 3,255,190, 76,205,128, 62, 76,201,108,191, 25,153,160,127,255, 0, 0,
- 0, 0, 3,255,190, 76,205,128,190, 76,208, 48,191, 25,153,156,127,255, 0, 0, 0, 0, 1,255,190, 76,205,136, 63,127,255, 52,
-191,128, 0, 5,127,255, 0, 0, 0, 0, 1,255,190, 76,205,144, 62, 76,201,140,191,128, 0, 5,127,255, 0, 0, 0, 0, 1,255,
- 63,179, 51, 36,190, 76,208, 56, 63,127,255,150, 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80, 63,127,255,148,
- 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80, 63,127,255,144, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,
-190, 76,208,104, 63,127,255,142, 0, 0,127,255, 0, 0, 3,255,190, 76,205,112,190, 76,208, 64, 63,127,255,150,231, 94,231, 94,
-123, 41, 1,255,190, 76,205,112,190, 76,208, 64,191,128, 0, 4,231, 94,231, 94,132,215, 1,255,190, 76,205,112,190, 76,208, 64,
- 63, 25,153,160, 0, 0,127,255, 0, 0, 1,255,190, 76,205,112,190, 76,208, 64, 62, 76,204,221, 0, 0,127,255, 0, 0, 1,255,
-190, 76,205,112,190, 76,208, 64,190, 76,204,195, 0, 0,127,255, 0, 0, 1,255,190, 76,205,112,190, 76,208, 64,191, 25,153,156,
- 0, 0,127,255, 0, 0, 1,255, 63,230,102,136,190, 76,208, 88,191, 25,153,169, 0, 0,127,255, 0, 0, 3,255, 63,230,102,136,
-190, 76,208, 88,190, 76,204,246, 0, 0,127,255, 0, 0, 3,255, 63,230,102,136,190, 76,208, 88, 62, 76,204,170, 0, 0,127,255,
- 0, 0, 3,255, 63,230,102,135,190, 76,208, 88, 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,
-191,128, 0, 8, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80,191,128, 0, 7, 0, 0,127,255, 0, 0, 3,255,
- 63,127,255,222,190, 76,208, 80,191,128, 0, 5, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56,191,128, 0, 4,
- 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 36,190, 76,208,104, 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,114,
-190, 76,208, 80, 63, 25,153,151, 0, 0,127,255, 0, 0, 3,255, 63,127,255,220,190, 76,208, 80, 63, 25,153,155, 0, 0,127,255,
- 0, 0, 3,255, 63,179, 51, 34,190, 76,208, 56, 63, 25,153,159, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,
- 62, 76,204,170, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80, 62, 76,204,186, 0, 0,127,255, 0, 0, 3,255,
- 63,127,255,222,190, 76,208, 80, 62, 76,204,202, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56, 62, 76,204,218,
- 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,190, 76,204,246, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,
-190, 76,208, 80,190, 76,204,230, 0, 0,127,255, 0, 0, 3,255, 63,127,255,222,190, 76,208, 80,190, 76,204,214, 0, 0,127,255,
- 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56,190, 76,204,198, 0, 0,127,255, 0, 0, 3,255, 62, 76,204, 44,190, 76,208,104,
-191, 25,153,169, 0, 0,127,255, 0, 0, 3,255, 63, 25,153,116,190, 76,208, 80,191, 25,153,165, 0, 0,127,255, 0, 0, 3,255,
- 63,127,255,222,190, 76,208, 80,191, 25,153,161, 0, 0,127,255, 0, 0, 3,255, 63,179, 51, 36,190, 76,208, 56,191, 25,153,157,
- 0, 0,127,255, 0, 0, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,215,224, 0, 0, 0,242, 0, 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, 5, 32,102, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 14, 28, 5, 32,102, 32, 0, 0, 0, 53, 0, 0, 1, 45, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 34,
- 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 2,
- 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 4,
- 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 34,
- 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 13,
- 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 11,
- 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 34,
- 0, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 17,
- 0, 0, 0, 34, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 15,
- 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 34,
- 0, 0, 0, 10, 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 37, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 36,
- 0, 0, 0, 34, 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 21,
- 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 34,
- 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 19, 0, 0, 0, 23, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 19,
- 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 22, 0, 0, 0, 34, 0, 0, 0, 25, 0, 0, 0, 29, 0, 0, 0, 34, 0, 0, 0, 24,
- 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 34,
- 0, 0, 0, 23, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 26,
- 0, 0, 0, 34, 0, 0, 0, 29, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 34, 0, 0, 0, 28,
- 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 27, 0, 0, 0, 31, 0, 0, 0, 34,
- 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 26, 0, 0, 0, 30, 0, 0, 0, 34, 0, 0, 0, 32, 0, 0, 0, 33,
- 0, 0, 0, 34, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 34, 0, 0, 0, 34,
- 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 34,
- 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 34,
- 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0, 39, 0, 0, 0, 34, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 34, 0, 0, 0, 42,
- 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 38, 0, 0, 0, 34,
- 0, 0, 0, 26, 0, 0, 0, 39, 0, 0, 0, 34, 0, 0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 41,
- 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 42, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 9,
- 0, 0, 0, 44, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 45, 0, 0, 0, 34, 0, 0, 0, 49, 0, 0, 0, 72, 0, 0, 0, 34,
- 0, 0, 0, 53, 0, 0, 0, 70, 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0, 66,
- 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 49,
- 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 48, 0, 0, 0, 52, 0, 0, 0, 34,
- 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 34, 0, 0, 0, 47, 0, 0, 0, 51, 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 47,
- 0, 0, 0, 34, 0, 0, 0, 46, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 53, 0, 0, 0, 57, 0, 0, 0, 34, 0, 0, 0, 52,
- 0, 0, 0, 53, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 51, 0, 0, 0, 52, 0, 0, 0, 34,
- 0, 0, 0, 51, 0, 0, 0, 55, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0, 51, 0, 0, 0, 34, 0, 0, 0, 50, 0, 0, 0, 54,
- 0, 0, 0, 34, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 34, 0, 0, 0, 56, 0, 0, 0, 57, 0, 0, 0, 34, 0, 0, 0, 56,
- 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 34, 0, 0, 0, 55, 0, 0, 0, 59, 0, 0, 0, 34,
- 0, 0, 0, 54, 0, 0, 0, 55, 0, 0, 0, 34, 0, 0, 0, 54, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 60, 0, 0, 0, 61,
- 0, 0, 0, 34, 0, 0, 0, 59, 0, 0, 0, 60, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 34, 0, 0, 0, 65,
- 0, 0, 0, 66, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 34,
- 0, 0, 0, 68, 0, 0, 0, 70, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0, 70, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0, 69,
- 0, 0, 0, 34, 0, 0, 0, 70, 0, 0, 0, 72, 0, 0, 0, 34, 0, 0, 0, 71, 0, 0, 0, 72, 0, 0, 0, 34, 0, 0, 0, 64,
- 0, 0, 0, 72, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 34,
- 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 49,
- 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 64, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 29,
- 0, 0, 0, 54, 0, 0, 0, 34, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 46, 0, 0, 0, 34,
- 0, 0, 0, 14, 0, 0, 0, 64, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 75, 0, 0, 0, 76,
- 0, 0, 0, 34, 0, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0, 34, 0, 0, 0, 71, 0, 0, 0, 77, 0, 0, 0, 34, 0, 0, 0, 64,
- 0, 0, 0, 77, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 76, 0, 0, 0, 34, 0, 0, 0, 15, 0, 0, 0, 75, 0, 0, 0, 34,
- 0, 0, 0, 16, 0, 0, 0, 74, 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 73, 0, 0, 0, 34, 0, 0, 0, 82, 0, 0, 0, 94,
- 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 0, 95, 0, 0, 0, 34, 0, 0, 0, 80, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 79,
- 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 78, 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 34,
- 0, 0, 0, 79, 0, 0, 0, 80, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0,105, 0, 0, 0, 34, 0, 0, 0, 83, 0, 0, 0, 97,
- 0, 0, 0, 34, 0, 0, 0, 83, 0, 0, 0,110, 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0, 84,
- 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0,110, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0,106, 0, 0, 0, 34,
- 0, 0, 0, 87, 0, 0, 0,102, 0, 0, 0, 34, 0, 0, 0, 88, 0, 0, 0, 98, 0, 0, 0, 34, 0, 0, 0, 89, 0, 0, 0, 94,
- 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0, 93,
- 0, 0, 0,106, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0, 91, 0, 0, 0,108, 0, 0, 0, 34,
- 0, 0, 0, 90, 0, 0, 0,109, 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0, 93,
- 0, 0, 0, 34, 0, 0, 0, 97, 0, 0, 0,101, 0, 0, 0, 34, 0, 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 34, 0, 0, 0, 96,
- 0, 0, 0,100, 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 0, 99, 0, 0, 0, 34,
- 0, 0, 0, 94, 0, 0, 0, 95, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 0, 98, 0, 0, 0, 34, 0, 0, 0,101, 0, 0, 0,110,
- 0, 0, 0, 34, 0, 0, 0,101, 0, 0, 0,105, 0, 0, 0, 34, 0, 0, 0,100, 0, 0, 0,101, 0, 0, 0, 34, 0, 0, 0,100,
- 0, 0, 0,104, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,100, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0,103, 0, 0, 0, 34,
- 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 34, 0, 0, 0, 98, 0, 0, 0,102, 0, 0, 0, 34, 0, 0, 0,105, 0, 0, 0,109,
- 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,105, 0, 0, 0, 34, 0, 0, 0,104, 0, 0, 0,108, 0, 0, 0, 34, 0, 0, 0,103,
- 0, 0, 0,104, 0, 0, 0, 34, 0, 0, 0,103, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0,102, 0, 0, 0,103, 0, 0, 0, 34,
- 0, 0, 0,102, 0, 0, 0,106, 0, 0, 0, 34, 0, 0, 0,109, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0,108, 0, 0, 0,109,
- 0, 0, 0, 34, 0, 0, 0,107, 0, 0, 0,108, 0, 0, 0, 34, 0, 0, 0,106, 0, 0, 0,107, 0, 0, 0, 34, 0, 0, 0, 65,
- 0, 0, 0, 78, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0, 58, 0, 0, 0, 85, 0, 0, 0, 34,
- 0, 0, 0, 59, 0, 0, 0,111, 0, 0, 0, 34, 0, 0, 0, 60, 0, 0, 0, 84, 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0,110,
- 0, 0, 0, 34, 0, 0, 0, 30, 0, 0, 0, 93, 0, 0, 0, 34, 0, 0, 0, 31, 0, 0, 0, 92, 0, 0, 0, 34, 0, 0, 0, 32,
- 0, 0, 0, 91, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 90, 0, 0, 0, 34, 0, 0, 0,113, 0, 0, 0,130, 0, 0, 0, 35,
- 0, 0, 0,115, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 0,133,
- 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 0,126, 0, 0, 0, 35, 0, 0, 0,113,
- 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 0,115, 0, 0, 0,163, 0, 0, 0,112, 0, 0, 0,114, 0, 0, 0, 35,
- 0, 0, 0,113, 0, 0, 0,116, 0, 0, 0,163, 0, 0, 0,116, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 0,127,
- 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 0,120, 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 0,146, 0, 0, 0,163, 0, 0, 0,142,
- 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 0,147, 0, 0, 0, 35,
- 0, 0, 0,128, 0, 0, 0,147, 0, 0, 0,163, 0, 0, 0,128, 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 0,127,
- 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 0,120, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 0,122,
- 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 0,123, 0, 0, 0, 35,
- 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 0,126,
- 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 0,130,
- 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 0,137, 0, 0, 0,163, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0, 35,
- 0, 0, 0,132, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 0,135,
- 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 0,134, 0, 0, 0, 35, 0, 0, 0,137,
- 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 0,140, 0, 0, 0, 35,
- 0, 0, 0,139, 0, 0, 0,140, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,139,
- 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 0,138, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 0,145, 0, 0, 0,163, 0, 0, 0,144,
- 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 0,144, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 0,144, 0, 0, 0, 35,
- 0, 0, 0,139, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,142,
- 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 0,125,
- 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 0,134, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 0,138, 0, 0, 0, 35,
- 0, 0, 0,119, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 0,151, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 0,167,
- 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0,148, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,152,
- 0, 0, 0,154, 0, 0, 0,163, 0, 0, 0,148, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 0,151, 0, 0, 0, 35,
- 0, 0, 0,157, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 0,170,
- 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 0,155,
- 0, 0, 0,156, 0, 0, 0,163, 0, 0, 0,156, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 0,157, 0, 0, 0,163,
- 0, 0, 0,158, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 0,177, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 0,173,
- 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 0,160,
- 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,165, 0, 0, 0, 35,
- 0, 0, 0,168, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,167,
- 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0,168,
- 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0,171, 0, 0, 0, 35,
- 0, 0, 0,170, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 0,177,
- 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,177, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0,175,
- 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0,175, 0, 0, 0, 35,
- 0, 0, 0,170, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 0,181,
- 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,175,
- 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0,178, 0, 0, 0, 35,
- 0, 0, 0,165, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 0,179,
- 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,178, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,217, 16, 0, 0, 0,242,
- 0, 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, 5, 32,118, 32, 0, 0, 0, 5, 0, 0, 0, 20,
- 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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, 32,124, 32, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 5, 32,138, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 5,200, 5, 32,118, 32, 0, 0, 0, 52, 0, 0, 0, 74, 0, 0, 0, 35,
- 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 3, 0, 0, 0, 2,
- 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 45, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4,
- 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 63, 0, 0, 0, 0,
- 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 11,
- 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 11,
- 0, 0, 0, 12, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 10, 0, 0, 0, 14, 0, 0, 0, 64,
- 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 76,
- 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 0,
- 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 25, 0, 0, 0, 21,
- 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22,
- 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 28, 0, 0, 0, 24, 0, 0, 0, 25,
- 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 33,
- 0, 0, 0, 29, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0,
- 0, 0, 0, 30, 0, 0, 0, 38, 0, 0, 0, 39, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 32,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 49,
- 0, 0, 0, 48, 0, 0, 0, 63, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 46,
- 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 56,
- 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 50, 0, 0, 0, 51, 0, 0, 0, 0,
- 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 55, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, 0, 84, 0, 0, 0, 60,
- 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0,111, 0, 0, 0, 85, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 78,
- 0, 0, 0, 83, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 61, 0, 0, 0, 57, 0, 0, 0, 68,
- 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 53,
- 0, 0, 0, 49, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 72, 0, 0, 0, 64, 0, 0, 0, 77, 0, 0, 0, 0,
- 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 97, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 94, 0, 0, 0, 82,
- 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, 0,101, 0, 0, 0, 97, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0,100,
- 0, 0, 0, 99, 0, 0, 0, 95, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 98, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 94,
- 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0,104, 0, 0, 0,100, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0,103, 0, 0, 0,102,
- 0, 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0,111, 0, 0, 0,109, 0, 0, 0,105, 0, 0, 0, 84, 0, 0, 0, 0,
- 0, 0, 0,108, 0, 0, 0,107, 0, 0, 0,103, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0,106, 0, 0, 0, 86, 0, 0, 0, 87,
- 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0,108, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 92,
- 0, 0, 0, 93, 0, 0, 0,106, 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0,120, 0, 0, 0,119, 0, 0, 0,127, 0, 0, 0,118,
- 0, 0, 0, 2, 0, 0, 0,121, 0, 0, 0,138, 0, 0, 0,142, 0, 0, 0,119, 0, 0, 0, 2, 0, 0, 0,124, 0, 0, 0,123,
- 0, 0, 0,121, 0, 0, 0,122, 0, 0, 0, 2, 0, 0, 0,125, 0, 0, 0,130, 0, 0, 0,134, 0, 0, 0,123, 0, 0, 0, 2,
- 0, 0, 0,117, 0, 0, 0,116, 0, 0, 0,125, 0, 0, 0,126, 0, 0, 0, 2, 0, 0, 0,112, 0, 0, 0,114, 0, 0, 0,133,
- 0, 0, 0,132, 0, 0, 0, 2, 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0,131, 0, 0, 0,130, 0, 0, 0, 2, 0, 0, 0,131,
- 0, 0, 0,132, 0, 0, 0,136, 0, 0, 0,135, 0, 0, 0, 2, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,141, 0, 0, 0,140,
- 0, 0, 0, 2, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,139, 0, 0, 0,138, 0, 0, 0, 2, 0, 0, 0,139, 0, 0, 0,140,
- 0, 0, 0,144, 0, 0, 0,143, 0, 0, 0, 2, 0, 0, 0,129, 0, 0, 0,147, 0, 0, 0,144, 0, 0, 0,145, 0, 0, 0, 2,
- 0, 0, 0,142, 0, 0, 0,143, 0, 0, 0,128, 0, 0, 0,146, 0, 0, 0, 2, 0, 0, 0,149, 0, 0, 0,148, 0, 0, 0,169,
- 0, 0, 0,168, 0, 0, 0, 2, 0, 0, 0,151, 0, 0, 0,150, 0, 0, 0,167, 0, 0, 0,166, 0, 0, 0, 2, 0, 0, 0,169,
- 0, 0, 0,161, 0, 0, 0,160, 0, 0, 0,173, 0, 0, 0, 2, 0, 0, 0,167, 0, 0, 0,168, 0, 0, 0,172, 0, 0, 0,171,
- 0, 0, 0, 2, 0, 0, 0,154, 0, 0, 0,166, 0, 0, 0,170, 0, 0, 0,155, 0, 0, 0, 2, 0, 0, 0,172, 0, 0, 0,173,
- 0, 0, 0,177, 0, 0, 0,176, 0, 0, 0, 2, 0, 0, 0,170, 0, 0, 0,171, 0, 0, 0,175, 0, 0, 0,174, 0, 0, 0, 2,
- 0, 0, 0,177, 0, 0, 0,159, 0, 0, 0,158, 0, 0, 0,181, 0, 0, 0, 2, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0,180,
- 0, 0, 0,179, 0, 0, 0, 2, 0, 0, 0,156, 0, 0, 0,174, 0, 0, 0,178, 0, 0, 0,157, 0, 0, 0, 2, 0, 0, 0,180,
- 0, 0, 0,181, 0, 0, 0,165, 0, 0, 0,164, 0, 0, 0, 2, 0, 0, 0,178, 0, 0, 0,179, 0, 0, 0,163, 0, 0, 0,162,
- 0, 0, 0, 2, 68, 65, 84, 65, 0, 0, 12,184, 5, 32,124, 32, 0, 0, 0, 60, 0, 0, 0, 74, 61,104, 84,160, 63, 79, 65,242,
-189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 3, 29, 0, 62, 82, 95, 26, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,127, 63, 79, 65,242, 63, 0,188,190,
- 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160, 63, 3, 29, 0,189,188,106,128, 62,186, 20,176,
- 61,104, 82,144, 62, 91,223,128, 62, 82, 95, 14, 62,186, 21, 0, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,127,
- 63, 79, 65,242, 62, 82, 95, 26, 63, 41, 47,120, 62,181, 84,122, 63, 3, 28,248, 63, 0,188,188, 63, 41, 47,120, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 56, 63,141,179,111, 63, 0,188,190, 63,117, 84,102, 63, 38,207, 52, 63, 79, 65,236,
- 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63, 3, 28,248, 62, 82, 95, 14,
- 62,186, 21, 0, 62,181, 84,122, 62, 91,224, 32, 63, 0,188,185, 62,186, 21, 0, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,207, 52, 63, 79, 65,236, 63, 0,188,188, 63, 41, 47,120, 63, 38,207, 52, 63, 3, 28,248, 63, 76,225,174, 63, 41, 47,116,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 62, 91,224, 32, 62, 82, 94,138, 61,135, 43, 48, 62,181, 84, 61,
-189,169,104,176, 63, 0,188,185, 61,135, 44, 96, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 52, 63, 3, 28,248,
- 63, 0,188,185, 62,186, 21, 0, 63, 38,207, 51, 62, 91,224, 24, 63, 76,225,174, 62,186, 21, 0, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63, 41, 47,116, 63,114,244, 42, 63, 3, 28,244, 63,140,131, 99,
- 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 51, 62, 91,224, 24, 63, 0,188,185, 61,135, 44, 96,
- 63, 38,207,248,189,169,109,144, 63, 76,226,112, 61,135, 38, 64, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244,240,
- 62, 91,221, 4, 63,140,131,180, 62,186, 19,116, 63,114,244, 42, 63, 3, 28,244, 63, 76,225,174, 62,186, 21, 0, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102,
- 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128,
- 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160,
- 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,
-190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122,
- 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,
-189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188,
- 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242,
- 62, 82, 95, 26, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,190,118,127, 56,
- 63, 3, 28,220,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,200, 63, 79, 65,244,189,188,105, 96, 63, 41, 47,120,189,188,105, 96,
- 63, 41, 47,120, 61,104, 84,200, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236,
- 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 63, 38,207, 56, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188,
- 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,
- 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44,
- 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173,
- 63, 38,207, 52, 63,141,179,111, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52,
- 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,174, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,190, 63,160,188,171, 63, 0,188,188,
- 63,160,188,173, 63, 38,207, 52, 63,141,179,111, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,162, 63, 3, 28,210,
- 63,140,131, 99, 63, 41, 47, 72, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99,
- 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76,
- 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99,
- 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76,
- 63,159,140,244, 63, 3, 28, 50, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,131,172, 22, 59, 93,211, 96, 63,158,151,226,
- 59, 93,211, 96, 63,158,151,224, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 63, 81,128,144, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 27,168,248, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,185,131,176, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 63,158,151,224,
- 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,131,172, 21, 59, 93,211, 96,
- 63, 81,128,144, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1,
- 0, 0, 0, 0, 63, 27,168,247, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96, 63, 27,168,247,
- 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,131,172, 24, 59, 93,211, 96,
- 63,131,172, 21, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 81,128,142,
- 59, 93,211, 96, 63, 27,168,246, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 0, 0, 0, 0,
- 61, 0, 0, 1, 0, 0, 0, 0, 63,185,131,174, 59, 93,211, 96, 63,158,151,227, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96,
- 63,185,131,174, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,131,172, 22, 59, 93,211, 96, 63, 81,128,149,
- 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96, 63,131,172, 24, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 63, 27,168,251, 59, 93,211, 96, 62,203,162, 84, 59, 93,211, 96, 62,203,162, 86, 59, 93,211, 96, 63, 27,168,246, 59, 93,211, 96,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63,158,151,225, 59, 93,211, 96, 63,131,172, 21, 59, 93,211, 96, 63,131,172, 22,
- 59, 93,211, 96, 63,158,151,227, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 81,128,146, 59, 93,211, 96,
- 63, 27,168,250, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96, 63, 81,128,149, 59, 93,211, 96, 0, 0, 0, 0, 61, 0, 0, 1,
- 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,244,
- 63, 3, 28, 50, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236,
- 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,161,
- 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236,
- 63,140,131, 99, 63, 41, 47, 76, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,159,140,162, 63, 3, 28,210, 63,140,131, 99,
- 63, 41, 47, 72, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,207, 52, 63,141,179,111, 63, 0,188,190, 63,160,188,171, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,174,
- 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102,
- 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52,
- 63,141,179,111, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102,
- 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 76,225,172,
- 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 63, 38,207, 56, 63,141,179,111, 63, 38,207, 52, 63,141,179,111,
- 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172,
- 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 61,104, 84,200, 63, 79, 65,244,189,188,105, 96, 63, 41, 47,120,189,188,105, 96, 63, 41, 47,120, 61,104, 84,200, 63, 79, 65,242,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26,
- 63,117, 84,102, 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,
-190,118,127, 56, 63, 3, 28,220,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26,
- 63,117, 84,102, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113,
- 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160,
- 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0,
- 60, 0, 0, 1, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102,
- 62,181, 84,122, 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64,
- 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0,
- 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,
- 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122,
- 63,141,179,113, 63, 0,188,188, 63,160,188,173, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,
-189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242, 0, 0, 0, 0, 60, 0, 0, 1,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122,
- 63,141,179,113, 0, 0, 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 4,160, 5, 32,138, 32, 0, 0, 0, 57,
- 0, 0, 1, 40,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 68, 65, 84, 65, 0, 0, 17, 88, 5, 30, 70, 32, 0, 0, 0, 51, 0, 0, 0, 74, 0, 0, 0, 0, 61,104, 84,160,
- 63, 79, 65,242,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 3, 29, 0, 62, 82, 95, 26, 63, 41, 47,120,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113,
- 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,127, 63, 79, 65,242, 63, 0,188,190, 63,117, 84,102,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 3, 29, 0,189,188,106,128,
- 62,186, 20,176, 61,104, 82,144, 62, 91,223,128, 62, 82, 95, 14, 62,186, 21, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,127, 63, 79, 65,242, 62, 82, 95, 26, 63, 41, 47,120,
- 62,181, 84,122, 63, 3, 28,248, 63, 0,188,188, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 56, 63,141,179,111, 63, 0,188,190, 63,117, 84,102, 63, 38,207, 52,
- 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63, 3, 28,248, 62, 82, 95, 14, 62,186, 21, 0, 62,181, 84,122, 62, 91,224, 32,
- 63, 0,188,185, 62,186, 21, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,207, 52, 63, 79, 65,236, 63, 0,188,188, 63, 41, 47,120, 63, 38,207, 52, 63, 3, 28,248, 63, 76,225,174,
- 63, 41, 47,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,181, 84,122, 62, 91,224, 32, 62, 82, 94,138, 61,135, 43, 48, 62,181, 84, 61,189,169,104,176, 63, 0,188,185, 61,135, 44, 96,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 52,
- 63, 3, 28,248, 63, 0,188,185, 62,186, 21, 0, 63, 38,207, 51, 62, 91,224, 24, 63, 76,225,174, 62,186, 21, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236,
- 63, 76,225,174, 63, 41, 47,116, 63,114,244, 42, 63, 3, 28,244, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 51, 62, 91,224, 24, 63, 0,188,185,
- 61,135, 44, 96, 63, 38,207,248,189,169,109,144, 63, 76,226,112, 61,135, 38, 64,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244,240, 62, 91,221, 4, 63,140,131,180, 62,186, 19,116,
- 63,114,244, 42, 63, 3, 28,244, 63, 76,225,174, 62,186, 21, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26,
- 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120,
- 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188,
- 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105,128,
- 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113,
- 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128,
- 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113,
- 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,200, 63, 79, 65,242, 61,104, 84,160,
- 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,189,188,105, 96, 63, 41, 47,120,190,118,127, 56, 63, 3, 28,220,190,118,127, 64, 63, 3, 28,216,
-189,188,105,128, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122,
- 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,104, 84,200, 63, 79, 65,244,189,188,105, 96, 63, 41, 47,120,189,188,105, 96, 63, 41, 47,120, 61,104, 84,200, 63, 79, 65,242,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44,
- 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173,
- 63, 38,207, 56, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52,
- 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102,
- 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,188, 63,160,188,173, 63, 0,188,188,
- 63,160,188,173, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111,
- 63, 76,225,172, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,174, 63,117, 84,102, 63,114,244, 44,
- 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 38,207, 52, 63,141,179,111, 63, 0,188,190, 63,160,188,171, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,162,
- 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 72, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76,
- 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99,
- 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236,
- 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99,
- 63, 41, 47, 76, 63,159,140,244, 63, 3, 28, 50,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,131,172, 22, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 63,158,151,224, 59, 93,211, 96,
- 63,131,172, 22, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 81,128,144, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96, 63, 27,168,248, 59, 93,211, 96, 63, 81,128,144,
- 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,185,131,176, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96, 63,158,151,224, 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131,172, 21,
- 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 27,168,247, 59, 93,211, 96,
- 62,203,162, 85, 59, 93,211, 96, 62,203,162, 85, 59, 93,211, 96, 63, 27,168,247, 59, 93,211, 96,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,158,151,226, 59, 93,211, 96, 63,131,172, 24,
- 59, 93,211, 96, 63,131,172, 21, 59, 93,211, 96, 63,158,151,226, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 81,128,142, 59, 93,211, 96, 63, 27,168,246, 59, 93,211, 96,
- 63, 27,168,247, 59, 93,211, 96, 63, 81,128,144, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,185,131,174, 59, 93,211, 96, 63,158,151,227, 59, 93,211, 96, 63,158,151,226,
- 59, 93,211, 96, 63,185,131,174, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,131,172, 22, 59, 93,211, 96, 63, 81,128,149, 59, 93,211, 96, 63, 81,128,142, 59, 93,211, 96,
- 63,131,172, 24, 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 27,168,251, 59, 93,211, 96, 62,203,162, 84, 59, 93,211, 96, 62,203,162, 86, 59, 93,211, 96, 63, 27,168,246,
- 59, 93,211, 96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,158,151,225, 59, 93,211, 96, 63,131,172, 21, 59, 93,211, 96, 63,131,172, 22, 59, 93,211, 96, 63,158,151,227, 59, 93,211, 96,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 81,128,146,
- 59, 93,211, 96, 63, 27,168,250, 59, 93,211, 96, 63, 27,168,251, 59, 93,211, 96, 63, 81,128,149, 59, 93,211, 96,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210,
- 63,140,131, 99, 63, 41, 47, 76, 63,140,131, 99, 63, 41, 47, 76, 63,159,140,244, 63, 3, 28, 50,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44,
- 63, 79, 65,236, 63,114,244, 44, 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,161, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 76,
- 63,140,131, 99, 63, 41, 47, 76, 63,159,140,161, 63, 3, 28,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,140,131, 99, 63, 41, 47, 76, 63,114,244, 44, 63, 79, 65,236, 63,114,244, 44,
- 63, 79, 65,236, 63,140,131, 99, 63, 41, 47, 76,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,159,140,162, 63, 3, 28,210, 63,140,131, 99, 63, 41, 47, 72, 63,140,131, 99, 63, 41, 47, 76,
- 63,159,140,161, 63, 3, 28,210,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111, 63, 0,188,190, 63,160,188,171, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52,
- 63,141,179,111,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,114,244, 44, 63, 79, 65,236, 63, 76,225,174, 63,117, 84,102, 63, 76,225,174, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,174,
- 63,117, 84,102, 63, 38,207, 52, 63,141,179,111, 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,207, 52, 63,141,179,111,
- 63, 0,188,188, 63,160,188,173, 63, 0,188,188, 63,160,188,173, 63, 38,207, 52, 63,141,179,111,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172,
- 63,117, 84,102, 63, 76,225,172, 63,117, 84,102, 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,225,172, 63,117, 84,102, 63, 38,207, 52, 63,141,179,111,
- 63, 38,207, 52, 63,141,179,111, 63, 76,225,172, 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 63, 38,207, 56, 63,141,179,111, 63, 38,207, 52,
- 63,141,179,111, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,114,244, 44, 63, 79, 65,236, 63, 76,225,172, 63,117, 84,102, 63, 76,225,172, 63,117, 84,102,
- 63,114,244, 44, 63, 79, 65,236,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,104, 84,200, 63, 79, 65,244,189,188,105, 96, 63, 41, 47,120,189,188,105, 96, 63, 41, 47,120, 61,104, 84,200,
- 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,189,188,105, 96,
- 63, 41, 47,120,190,118,127, 56, 63, 3, 28,220,190,118,127, 64, 63, 3, 28,216,189,188,105,128, 63, 41, 47,120,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102,
- 61,104, 84,200, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26, 63,117, 84,102,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0,188,188, 63,160,188,173, 62,181, 84,122,
- 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160, 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,
-189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113, 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26,
- 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0,189,188,105,128, 63, 41, 47,120,190,118,127, 64, 63, 3, 28,216,190,118,127, 64, 63, 3, 28,216,
-189,188,105,128, 63, 41, 47,120,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 82, 95, 26, 63,117, 84,102, 61,104, 84,160, 63, 79, 65,242, 61,104, 84,160, 63, 79, 65,242, 62, 82, 95, 26,
- 63,117, 84,102,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 0,188,188, 63,160,188,173, 62,181, 84,122, 63,141,179,113, 62,181, 84,122, 63,141,179,113, 63, 0,188,188, 63,160,188,173,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,104, 84,160,
- 63, 79, 65,242,189,188,105,128, 63, 41, 47,120,189,188,105,128, 63, 41, 47,120, 61,104, 84,160, 63, 79, 65,242,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,181, 84,122, 63,141,179,113,
- 62, 82, 95, 26, 63,117, 84,102, 62, 82, 95, 26, 63,117, 84,102, 62,181, 84,122, 63,141,179,113,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 60, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,236,218, 64, 0, 0, 0, 50,
- 0, 0, 0, 1, 2,236,228, 0, 2,236,213, 64, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 50, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,232,181, 64, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,219,128, 2,236,224,240, 2,236,225,192, 5, 30, 54, 32, 5, 15,188, 32,
- 2,236,222, 16, 0, 0, 0, 0, 2,236,227, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2,236,219,176, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,236,220,224, 0, 0, 0, 1, 0, 0, 0, 5,
- 0, 0, 0, 12, 0, 0, 0, 0, 2,236,223,192, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 23,
- 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 76,205, 4, 55, 39,197,172, 63, 76,204,214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 30, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4,
- 2,236,219,128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,219,176, 0, 0, 0,242,
- 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, 5, 15,188, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1,204, 5, 15,188, 32, 0, 0, 0, 56, 0, 0, 0, 23,191, 76,205, 4,
- 0, 0, 0, 0,190,204,204,208, 0, 0,128, 1, 0, 0, 3, 1,190,204,205, 55, 0, 0, 0, 0,190,204,204,216, 0, 0,128, 1,
- 0, 0, 3, 1,182, 70, 0, 0, 52,128, 0, 0,190,204,204,224, 0, 0,128, 1, 0, 0, 3, 1,191, 76,205, 4, 0, 0, 0, 0,
- 52, 96, 0, 0, 0, 0,128, 1, 0, 0, 3, 1,190,204,205, 55, 0, 0, 0, 0,179, 0, 0, 0, 0, 0,128, 1, 0, 0, 3, 1,
-182, 70, 0, 0, 52,128, 0, 0,180,144, 0, 0, 0, 0,128, 1, 0, 0, 3, 1,191, 76,205, 4, 0, 0, 0, 0, 62,204,204,213,
- 0, 0,128, 1, 0, 0, 3, 1,190,204,205, 55, 0, 0, 0, 0, 62,204,204,205, 0, 0,128, 1, 0, 0, 3, 1,182, 70, 0, 0,
- 52,128, 0, 0, 62,204,204,197, 0, 0,128, 1, 0, 0, 3, 1,190,204,205, 47, 0, 0, 0, 0, 63, 76,204,206, 0, 0,128, 1,
- 0, 0, 3, 1,182, 62, 0, 0, 52,128, 0, 0, 63, 76,204,206, 0, 0,128, 1, 0, 0, 3, 1,191, 76,205, 4, 0, 0, 0, 0,
-191, 76,204,208, 0, 0,128, 1, 0, 0, 3, 1,190,204,205, 55, 0, 0, 0, 0,191, 76,204,212, 0, 0,128, 1, 0, 0, 3, 1,
-182, 70, 0, 0, 52,128, 0, 0,191, 76,204,214, 0, 0,128, 1, 0, 0, 3, 1, 62,204,205, 47,180,128, 0, 0,191, 76,204,206,
- 0, 0,128, 1, 0, 0, 3, 1, 63, 76,205, 4, 0, 0, 0, 0, 63, 76,204,210, 0, 0,128, 1, 0, 0, 3, 1, 62,204,205, 53,
-180,128, 0, 0, 63, 76,204,214, 0, 0,128, 1, 0, 0, 3, 1, 63, 76,205, 0, 0, 0, 0, 0, 62,204,204,213, 0, 0,128, 1,
- 0, 0, 3, 1, 62,204,205, 47,180,128, 0, 0, 62,204,204,221, 0, 0,128, 1, 0, 0, 3, 1, 63, 76,205, 0, 0, 0, 0, 0,
- 52, 96, 0, 0, 0, 0,128, 1, 0, 0, 3, 1, 62,204,205, 47,180,128, 0, 0, 52,240, 0, 0, 0, 0,128, 1, 0, 0, 3, 1,
- 63, 76,205, 0, 0, 0, 0, 0,190,204,204,208, 0, 0,128, 1, 0, 0, 3, 1, 62,204,205, 47,180,128, 0, 0,190,204,204,200,
- 0, 0,128, 1, 0, 0, 3, 1, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,220,224, 0, 0, 0,242, 0, 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, 2,236,222, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1,128, 2,236,222, 16, 0, 0, 0, 53, 0, 0, 0, 32, 0, 0, 0, 2, 0, 0, 0, 22, 0, 0, 0, 35,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 0, 13,
- 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 0, 0,
- 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 35,
- 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8,
- 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 4,
- 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 35,
- 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0, 7,
- 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 0, 15,
- 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 35,
- 0, 0, 0, 15, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 0, 20,
- 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 0, 19,
- 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 0, 22, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,223,192,
- 0, 0, 0,242, 0, 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, 2,236,224,240, 0, 0, 0, 5,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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,236,225,192, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0,
- 67,111,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,
- 2,236,227, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0,160, 2,236,224,240, 0, 0, 0, 52, 0, 0, 0, 8,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 10,
- 0, 0, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 18, 0, 0, 0, 17,
- 0, 0, 0, 2, 0, 0, 0, 18, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 2, 0, 0, 0, 22, 0, 0, 0, 21,
- 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 2, 0, 0, 0, 22, 0, 0, 0, 2, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 2,
- 68, 65, 84, 65, 0, 0, 1, 96, 2,236,225,192, 0, 0, 0, 60, 0, 0, 0, 8, 62,137,192, 12, 63,125,226,162, 61,246,108,144,
- 63,125,226,162, 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 62,213,228,252, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,137,192, 12, 63,125,226,162, 61,246,108,144, 63,125,226,162, 61,246,108,144,
- 63,125,226,162, 62,137,192, 12, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,213,229, 0, 63,125,226,162,
- 62,137,192, 18, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1,
- 0, 0, 0, 0, 63, 55, 23,154, 63,125,226,162, 63, 17, 5, 34, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152,
- 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 17, 5, 30, 63,125,226,162, 62,213,228,252, 63,125,226,162,
- 62,213,228,252, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 17, 5, 30,
- 63,125,226,162, 63, 55, 23,152, 63,125,226,162, 63, 55, 23,152, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 0, 0, 0, 0,
- 61, 0, 0, 1, 0, 0, 0, 0, 63, 17, 5, 30, 63,125,226,162, 62,213,228,252, 63,125,226,162, 62,213,228,252, 63,125,226,162,
- 63, 17, 5, 30, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,128, 2,236,227, 80,
- 0, 0, 0, 57, 0, 0, 0, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 68, 65, 84, 65, 0, 0, 1,224, 5, 30, 54, 32, 0, 0, 0, 51, 0, 0, 0, 8, 0, 0, 0, 0,
- 62,137,192, 12, 63,125,226,162, 61,246,108,144, 63,125,226,162, 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,213,228,252,
- 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,137,192, 12, 63,125,226,162,
- 61,246,108,144, 63,125,226,162, 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,213,229, 0, 63,125,226,162, 62,137,192, 18,
- 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 55, 23,154, 63,125,226,162, 63, 17, 5, 34, 63,125,226,162,
- 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 17, 5, 30, 63,125,226,162, 62,213,228,252, 63,125,226,162, 62,213,228,252,
- 63,125,226,162, 63, 17, 5, 30, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152, 63,125,226,162, 63, 55, 23,152, 63,125,226,162,
- 63, 17, 5, 30, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 17, 5, 30, 63,125,226,162, 62,213,228,252, 63,125,226,162, 62,213,228,252, 63,125,226,162, 63, 17, 5, 30,
- 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69,
- 0, 0, 1, 20, 2,236,228, 0, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,237,192, 2,236,218, 64, 1, 94, 44, 64, 0, 0, 0, 0,
- 77, 69, 80,108, 97,110,101, 46, 48, 48, 51, 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, 2,231, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,229, 64, 2,236,234,176,
- 2,236,235,128, 5, 30, 54, 32, 5, 15,190, 32, 2,236,231,208, 0, 0, 0, 0, 2,236,237, 16, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,229,112, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0,
- 2,236,230,160, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 2,236,233,128, 0, 0, 0, 3, 0, 0, 0, 5,
- 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,205, 2, 55, 39,197,172, 63, 76,204,214, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,236,229, 64, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 1, 4, 2,236,229,112, 0, 0, 0,242, 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,
- 5, 15,190, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1,204, 5, 15,190, 32,
- 0, 0, 0, 56, 0, 0, 0, 23, 62,204,205, 47,180,128, 0, 0,190,204,204,200, 0, 0,128, 1, 0, 0, 2, 0, 63, 76,205, 0,
- 0, 0, 0, 0,190,204,204,208, 0, 0,128, 1, 0, 0, 2, 0, 62,204,205, 47,180,128, 0, 0, 52,240, 0, 0, 0, 0,128, 1,
- 0, 0, 2, 0, 63, 76,205, 0, 0, 0, 0, 0, 52, 96, 0, 0, 0, 0,128, 1, 0, 0, 2, 0, 62,204,205, 47,180,128, 0, 0,
- 62,204,204,221, 0, 0,128, 1, 0, 0, 2, 0, 63, 76,205, 0, 0, 0, 0, 0, 62,204,204,213, 0, 0,128, 1, 0, 0, 2, 0,
- 62,204,205, 53,180,128, 0, 0, 63, 76,204,214, 0, 0,128, 1, 0, 0, 2, 0, 62,204,205, 47,180,128, 0, 0,191, 76,204,206,
- 0, 0,128, 1, 0, 0, 2, 0, 63, 76,205, 0, 0, 0, 0, 0,191, 76,204,208, 0, 0,128, 1, 0, 0, 2, 0,182, 70, 0, 0,
- 52,128, 0, 0,191, 76,204,214, 0, 0,128, 1, 0, 0, 2, 0,190,204,205, 55, 0, 0, 0, 0,191, 76,204,212, 0, 0,128, 1,
- 0, 0, 2, 0,182, 62, 0, 0, 52,128, 0, 0, 63, 76,204,206, 0, 0,128, 1, 0, 0, 2, 0,190,204,205, 47, 0, 0, 0, 0,
- 63, 76,204,206, 0, 0,128, 1, 0, 0, 2, 0,191, 76,205, 4, 0, 0, 0, 0, 63, 76,204,210, 0, 0,128, 1, 0, 0, 2, 0,
-182, 70, 0, 0, 52,128, 0, 0, 62,204,204,197, 0, 0,128, 1, 0, 0, 2, 0,190,204,205, 55, 0, 0, 0, 0, 62,204,204,205,
- 0, 0,128, 1, 0, 0, 2, 0,191, 76,205, 4, 0, 0, 0, 0, 62,204,204,213, 0, 0,128, 1, 0, 0, 2, 0,182, 70, 0, 0,
- 52,128, 0, 0,180,144, 0, 0, 0, 0,128, 1, 0, 0, 2, 0,190,204,205, 55, 0, 0, 0, 0,179, 0, 0, 0, 0, 0,128, 1,
- 0, 0, 2, 0,191, 76,205, 4, 0, 0, 0, 0, 52, 96, 0, 0, 0, 0,128, 1, 0, 0, 2, 0,182, 70, 0, 0, 52,128, 0, 0,
-190,204,204,224, 0, 0,128, 1, 0, 0, 2, 0,190,204,205, 55, 0, 0, 0, 0,190,204,204,216, 0, 0,128, 1, 0, 0, 2, 0,
-191, 76,205, 4, 0, 0, 0, 0,190,204,204,208, 0, 0,128, 1, 0, 0, 2, 0, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,230,160,
- 0, 0, 0,242, 0, 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, 2,236,231,208, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1,128, 2,236,231,208, 0, 0, 0, 53, 0, 0, 0, 32,
- 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 2,
- 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 34,
- 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 10,
- 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 34, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 15,
- 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 34,
- 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 34, 0, 0, 0, 15, 0, 0, 0, 18,
- 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 34, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 34, 0, 0, 0, 19,
- 0, 0, 0, 22, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 34,
- 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 34, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 21,
- 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 4,
- 0, 0, 0, 14, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 34,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,236,233,128, 0, 0, 0,242, 0, 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, 2,236,234,176, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0,
- 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,236,235,128, 0, 0, 0, 6,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 2,236,237, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0, 0,160,
- 2,236,234,176, 0, 0, 0, 52, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 2,
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 12,
- 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 17,
- 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 21,
- 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 96, 2,236,235,128, 0, 0, 0, 60, 0, 0, 0, 8,
- 63, 55, 23,152, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152, 63,125,226,162,
- 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,213,228,252, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30,
- 63,125,226,162, 62,213,228,252, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 63, 55, 23,152, 63,125,226,162,
- 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1,
- 0, 0, 0, 0, 63, 17, 5, 34, 63,125,226,162, 62,213,229, 0, 63,125,226,162, 62,213,228,252, 63,125,226,162, 63, 17, 5, 30,
- 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,137,192, 18, 63,125,226,162, 61,246,108,144, 63,125,226,162,
- 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,213,228,252,
- 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162, 0, 0, 0, 0,
- 61, 0, 0, 1, 0, 0, 0, 0, 62,137,192, 12, 63,125,226,162, 61,246,108,144, 63,125,226,162, 61,246,108,144, 63,125,226,162,
- 62,137,192, 12, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0, 62,213,228,252, 63,125,226,162, 62,137,192, 12,
- 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162, 0, 0, 0, 0, 61, 0, 0, 1, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0,128, 2,236,237, 16, 0, 0, 0, 57, 0, 0, 0, 32,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65, 0, 0, 1,224, 5, 30, 54, 32,
- 0, 0, 0, 51, 0, 0, 0, 8, 0, 0, 0, 0, 63, 55, 23,152, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30,
- 63,125,226,162, 63, 55, 23,152, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,213,228,252, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162,
- 62,213,228,252, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 55, 23,152, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162, 63, 55, 23,152,
- 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 17, 5, 34, 63,125,226,162, 62,213,229, 0, 63,125,226,162, 62,213,228,252, 63,125,226,162, 63, 17, 5, 30, 63,125,226,162,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,137,192, 18,
- 63,125,226,162, 61,246,108,144, 63,125,226,162, 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,213,228,252, 63,125,226,162,
- 62,137,192, 12, 63,125,226,162, 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,137,192, 12, 63,125,226,162, 61,246,108,144,
- 63,125,226,162, 61,246,108,144, 63,125,226,162, 62,137,192, 12, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,213,228,252, 63,125,226,162, 62,137,192, 12, 63,125,226,162,
- 62,137,192, 12, 63,125,226,162, 62,213,228,252, 63,125,226,162,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 61, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,236,237,192, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,243,224,
- 2,236,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 52, 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, 2,236,239, 0, 2,236,243,160, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,240, 96, 2,236,242, 16, 0, 0, 0, 0,
- 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,236,239, 48, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,236,240,224, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0,
- 2,236,242,112, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,179,128, 0, 0, 52, 64, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 2,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,236,239, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 2,236,194, 96, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,239, 48, 0, 0, 0,242, 0, 0, 0, 5, 0, 0, 0, 0,
+204, 1, 0, 0,184, 28,167, 2, 57, 0, 0, 0, 23, 0, 0, 0, 47,205,204, 62, 0, 0,128,180,200,204,204,190, 0, 0, 1,128,
+ 0, 0, 2, 0, 0,205, 76, 63, 0, 0, 0, 0,208,204,204,190, 0, 0, 1,128, 0, 0, 2, 0, 47,205,204, 62, 0, 0,128,180,
+ 0, 0,240, 52, 0, 0, 1,128, 0, 0, 2, 0, 0,205, 76, 63, 0, 0, 0, 0, 0, 0, 96, 52, 0, 0, 1,128, 0, 0, 2, 0,
+ 47,205,204, 62, 0, 0,128,180,221,204,204, 62, 0, 0, 1,128, 0, 0, 2, 0, 0,205, 76, 63, 0, 0, 0, 0,213,204,204, 62,
+ 0, 0, 1,128, 0, 0, 2, 0, 53,205,204, 62, 0, 0,128,180,214,204, 76, 63, 0, 0, 1,128, 0, 0, 2, 0, 47,205,204, 62,
+ 0, 0,128,180,206,204, 76,191, 0, 0, 1,128, 0, 0, 2, 0, 0,205, 76, 63, 0, 0, 0, 0,208,204, 76,191, 0, 0, 1,128,
+ 0, 0, 2, 0, 0, 0, 70,182, 0, 0,128, 52,214,204, 76,191, 0, 0, 1,128, 0, 0, 2, 0, 55,205,204,190, 0, 0, 0, 0,
+212,204, 76,191, 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 62,182, 0, 0,128, 52,206,204, 76, 63, 0, 0, 1,128, 0, 0, 2, 0,
+ 47,205,204,190, 0, 0, 0, 0,206,204, 76, 63, 0, 0, 1,128, 0, 0, 2, 0, 4,205, 76,191, 0, 0, 0, 0,210,204, 76, 63,
+ 0, 0, 1,128, 0, 0, 2, 0, 0, 0, 70,182, 0, 0,128, 52,197,204,204, 62, 0, 0, 1,128, 0, 0, 2, 0, 55,205,204,190,
+ 0, 0, 0, 0,205,204,204, 62, 0, 0, 1,128, 0, 0, 2, 0, 4,205, 76,191, 0, 0, 0, 0,213,204,204, 62, 0, 0, 1,128,
+ 0, 0, 2, 0, 0, 0, 70,182, 0, 0,128, 52, 0, 0,144,180, 0, 0, 1,128, 0, 0, 2, 0, 55,205,204,190, 0, 0, 0, 0,
+ 0, 0, 0,179, 0, 0, 1,128, 0, 0, 2, 0, 4,205, 76,191, 0, 0, 0, 0, 0, 0, 96, 52, 0, 0, 1,128, 0, 0, 2, 0,
+ 0, 0, 70,182, 0, 0,128, 52,224,204,204,190, 0, 0, 1,128, 0, 0, 2, 0, 55,205,204,190, 0, 0, 0, 0,216,204,204,190,
+ 0, 0, 1,128, 0, 0, 2, 0, 4,205, 76,191, 0, 0, 0, 0,208,204,204,190, 0, 0, 1,128, 0, 0, 2, 0, 68, 65, 84, 65,
+ 44, 1, 0, 0, 0, 28,131, 2, 21, 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, 2,236,240, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,160,248,129, 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,
- 68, 65, 84, 65, 0, 0, 0, 80, 2,236,240, 96, 0, 0, 0, 56, 0, 0, 0, 4, 63,128, 0, 0, 63,127,255,255, 0, 0, 0, 0,
- 0, 0, 0, 0,127,255, 3,255, 63,128, 0, 0,191,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127,255, 3,255,191,128, 0, 1,
-191,127,255,253, 0, 0, 0, 0, 0, 0, 0, 0,127,255, 3,255,191,127,255,250, 63,128, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
-127,255, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,240,224, 0, 0, 0,242, 0, 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, 2,236,242, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 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, 0, 0, 48, 2,236,242, 16, 0, 0, 0, 53, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 35,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,236,242,112, 0, 0, 0,242, 0, 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, 2,236,243,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0, 0, 20,
- 2,236,243,160, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2,
- 0, 0, 77, 69, 0, 0, 1, 20, 2,236,243,224, 0, 0, 0, 50, 0, 0, 0, 1, 2,236,248,224, 2,236,237,192, 0, 0, 0, 0,
- 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 0, 0, 0, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2,235,212, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,245, 32,
- 8,108, 16, 32, 8,108,128, 32, 8,172, 96, 32, 5, 32,170, 32, 8,107,176, 32, 0, 0, 0, 0, 8,109, 96, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,245, 80, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20,
- 0, 0, 0, 0, 2,236,246,128, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 2,236,247,176, 0, 0, 0, 3,
- 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 2,130, 0, 0, 7,128, 0, 0, 5, 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, 64,186,224,117, 64,187, 13, 91, 64,186,240,160, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,236,245, 32, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,194, 96,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,236,245, 80, 0, 0, 0,242, 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, 5, 32,170, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0, 50, 40,
- 5, 32,170, 32, 0, 0, 0, 56, 0, 0, 2,130,191,141,136, 28, 62,244,243, 12,192,183, 86,198,231,212, 10,117,130,191, 3,255,
-192,131,102,240, 64,119,183, 30,191,199,169,109,166, 58, 84,158,221,230, 3,255, 63,239,108,119, 64,156, 85,213,192, 40, 58,188,
- 40,228,106,207,198,137, 3,255, 64,146,135, 95,191, 14, 54, 63,192,102,194,241,100, 27,243,219,177, 45, 3,255, 62,141, 84,239,
-192,157,220, 16,192, 73, 2, 14, 6, 8,148, 39,187, 86, 3,255,192,162,239,132,192, 12,165,206,191,240, 45,150,144,175,207,245,
-214,251, 3,255,190,141, 84,239, 64,157,220, 16, 64, 73, 2, 14,249,248,107,217, 68,170, 3,255, 64,162,239,132, 64, 12,165,206,
- 63,240, 45,150,111, 81, 48, 11, 41, 5, 3,255, 64,131,102,240,192,119,183, 30, 63,199,169,109, 89,198,171, 98, 34, 26, 3,255,
-191,239,108,119,192,156, 85,213, 64, 40, 58,188,215, 28,149, 49, 57,119, 3,255,192,146,135, 95, 63, 14, 54, 63, 64,102,194,241,
-155,229, 12, 37, 78,211, 3,255, 63,141,136, 28,190,244,243, 12, 64,183, 86,198, 24, 44,245,139,125, 65, 3,255,192, 68, 17,114,
- 64, 35,153,226,192,137, 26,154,189, 6, 55,226,162, 85, 3,255, 62,230, 40,155, 64, 73,199,239,192,157, 52,176, 9,211, 68,237,
-148,153, 3,255,191,168, 55,124, 64,164,177,224,192, 29,144, 58,227, 69,112,132,202, 46, 3,255,192,105, 35, 94,191,129, 88,230,
-192,143, 14,195,176, 93,233,233,158, 68, 3,255,192,173, 2, 37, 63,123,187,137,192, 1, 68, 56,137,206, 21,127,211,216, 3,255,
- 64, 2,168,234,189, 57,158,231,192,175,149, 65, 44,162,255, 3,136, 11, 3,255, 64,114,159, 19, 64, 34,226,254,192,106,133,196,
- 82,225, 55,164,175,228, 3,255,190,249,176,105,192, 39,148, 21,192,166,214,217,245, 87,198,194,142, 5, 3,255, 64, 54,163,227,
-192, 78,121, 86,192,125,202, 22, 62, 99,185,120,169, 79, 3,255,192, 53, 40,241,192,134, 31,200,192, 60,188,229,194, 30,164, 94,
-191,136, 3,255,192,181,230, 96,191,119, 24, 33, 63,130, 26,174,131,186,234,231, 22, 56, 3,255,192,163, 93,103, 64, 38,128,136,
- 63,153,235, 83,144,100, 56,224, 26, 74, 3,255,192, 36,219,238, 64,165,151,132, 63,109,226,165,199,176,113, 33, 20, 80, 3,255,
- 63,111,237, 24, 64,184,174,118, 62,154, 34,212, 20,125,126, 44, 6,148, 3,255, 64,130,244,163, 64,133, 58,157,190,226, 95,125,
- 89,119, 91, 5,246, 86, 3,255, 64,181,230, 96, 63,119, 24, 33,191,130, 26,174,124, 70, 21, 25,233,200, 3,255, 64,163, 93,103,
-192, 38,128,136,191,153,235, 83,111,156,199, 32,229,182, 3,255, 64, 36,219,238,192,165,151,132,191,109,226,165, 56, 80,142,223,
-235,176, 3,255,191,111,237, 24,192,184,174,118,190,154, 34,212,235,131,129,212,249,108, 3,255,192,130,244,163,192,133, 58,157,
- 62,226, 95,125,166,137,164,251, 9,170, 3,255,192, 54,163,227, 64, 78,121, 86, 64,125,202, 22,193,157, 70,136, 86,177, 3,255,
- 64, 53, 40,241, 64,134, 31,200, 64, 60,188,229, 61,226, 91,162, 64,120, 3,255, 64,173, 2, 37,191,123,187,137, 64, 1, 68, 56,
-118, 50,234,129, 44, 40, 3,255, 63,168, 55,124,192,164,177,224, 64, 29,144, 58, 28,187,143,124, 53,210, 3,255,192,114,159, 19,
-192, 34,226,254, 64,106,133,196,173, 31,200, 92, 80, 28, 3,255,192, 2,168,234, 61, 57,158,231, 64,175,149, 65,211, 94, 0,253,
-119,245, 3,255, 62,249,176,105, 64, 39,148, 21, 64,166,214,217, 10,169, 57, 62,113,251, 3,255, 64,105, 35, 94, 63,129, 88,230,
- 64,143, 14,195, 79,163, 22, 23, 97,188, 3,255, 64, 68, 17,114,192, 35,153,226, 64,137, 26,154, 66,250,200, 30, 93,171, 3,255,
-190,230, 40,155,192, 73,199,239, 64,157, 52,176,246, 45,187, 19,107,103, 3,255,192, 10,178, 37, 63,201,231,138,192,166,143,149,
-209,129, 33,140,141,145, 3,255,192,110,132, 3, 64, 85,203,243,192, 66,107,151,174, 16, 73,158,190,209, 3,255,190,174,161,116,
- 63,241,152, 81,192,177, 2,110,247,217, 40, 15,134,182, 3,255, 63,154, 91,138, 64,133,179,218,192,122,222,209, 27, 0, 92, 30,
-171, 86, 3,255,192, 52, 82, 7, 64,149,252, 82,192, 5,202, 64,193, 39,101,227,210,181, 3,255, 62,148, 12,179, 64,166,221,251,
-192, 41, 87,188, 7,192,113,224,198, 21, 3,255,192, 29,246,216,190,141,156, 17,192,169,167,209,203, 47,250,160,139,137, 3,255,
-192,145, 72, 99,191,213,114, 79,192, 83, 35,183,156, 26,219, 3,185, 12, 3,255,192,158, 58,115, 64, 33,120,129,191,238, 41,198,
-148,126, 56,116,215,137, 3,255,192,174,158,118,191, 33,148,103,192, 1,156,140,136,218,240,198,211,203, 3,255, 62,249, 14, 55,
- 62,102,133, 95,192,186,143,210, 9, 56, 5, 40,128,113, 3,255, 64, 92, 61,220,190,159,230, 56,192,151, 61, 6, 76, 94,248,242,
-153,135, 3,255, 64, 60, 86, 7, 64,119, 48, 60,192, 81, 88, 93, 63,119, 85,124,184,246, 3,255, 64,139, 55,252, 63,132, 95, 62,
-192,113,216,225, 95,118, 21, 54,173,107, 3,255,191, 84, 6, 18,191,142, 96,251,192,182, 4, 76,237,158,233, 20,131,109, 3,255,
-189,225, 74,109,192,123, 54, 51,192,138,246, 34,253,241,169, 39,162, 1, 3,255, 64,119, 66,153,191,251,154,127,192,123,220,161,
- 85, 59,214, 59,170, 34, 3,255, 63,208, 59,201,192,135,182,241,192,108,101,212, 34,103,162,133,175,160, 3,255,191,169,246,161,
-192,151,196,235,192, 74,149,170,228, 95,151,253,186,184, 3,255,192,131,198, 33,192, 84,137,218,192, 32,134, 37,164,247,184, 77,
-201,167, 3,255,192,179, 61,176,191,210,110,138,190,228,220, 24,133,210,219,130,244,238, 3,255,192,170,182, 73,190, 90, 16,136,
- 64, 25,194, 90,139,224,252, 8, 53,174, 3,255,192,153, 55, 75, 64, 87, 78, 4,190, 62, 54, 12,151,200, 74, 29,250,179, 3,255,
-192,161, 19,235, 63,210, 12,207, 64, 31,242,210,146, 50, 34,244, 55,182, 3,255,192, 94, 75, 60, 64,150,115,189,190,167,211,186,
-179, 98,102, 49,247,183, 3,255,191,189,191,186, 64,168, 32, 63, 64, 7,100,213,224,161,114,191, 47, 61, 3,255, 63,186,205,242,
- 64,177, 65,141,191,154,219,127, 32, 82,120,177,228, 61, 3,255, 62,175,245, 99, 64,178, 12, 97, 63,228,253,255, 6,247,121, 65,
- 40, 98, 3,255, 64, 70, 92,226, 64,150,131, 8,191,204, 77,182, 66,193,103, 37,220, 32, 3,255, 64,152,194,200, 64, 83,155,180,
- 63, 62,217,154,104,207, 71,101, 17, 87, 3,255, 64,170,182, 73, 62, 90, 16,136,192, 25,194, 90,116, 32, 3,248,202, 82, 3,255,
- 64,179, 61,176, 63,210,110,138, 62,228,220, 24,122, 46, 36,126, 11, 18, 3,255, 64,161, 19,235,191,210, 12,207,192, 31,242,210,
-109,206,221, 12,200, 74, 3,255, 64,153, 55, 75,192, 87, 78, 4, 62, 62, 54, 12,104, 56,181,227, 5, 77, 3,255, 63,189,191,186,
-192,168, 32, 63,192, 7,100,213, 31, 95,141, 65,208,195, 3,255, 64, 94, 75, 60,192,150,115,189, 62,167,211,186, 76,158,153,207,
- 8, 73, 3,255,190,175,245, 99,192,178, 12, 97,191,228,253,255,249, 9,134,191,215,158, 3,255,191,186,205,242,192,177, 65,141,
- 63,154,219,127,223,174,135, 79, 27,195, 3,255,192,152,194,200,192, 83,155,180,191, 62,217,154,151, 49,184,155,238,169, 3,255,
-192, 70, 92,226,192,150,131, 8, 63,204, 77,182,189, 63,152,219, 35,224, 3,255,191,208, 59,201, 64,135,182,241, 64,108,101,212,
-221,153, 93,123, 80, 96, 3,255,192,119, 66,153, 63,251,154,127, 64,123,220,161,170,197, 41,197, 85,222, 3,255, 63,169,246,161,
- 64,151,196,235, 64, 74,149,170, 27,161,104, 3, 69, 72, 3,255, 64,131,198, 33, 64, 84,137,218, 64, 32,134, 37, 91, 9, 71,179,
- 54, 89, 3,255, 64,174,158,118, 63, 33,148,103, 64, 1,156,140,119, 38, 15, 58, 44, 53, 3,255, 64,158, 58,115,192, 33,120,129,
- 63,238, 41,198,107,130,199,140, 40,119, 3,255, 64, 52, 82, 7,192,149,252, 82, 64, 5,202, 64, 62,217,154, 29, 45, 75, 3,255,
-190,148, 12,179,192,166,221,251, 64, 41, 87,188,248, 64,142, 32, 57,235, 3,255,192, 60, 86, 7,192,119, 48, 60, 64, 81, 88, 93,
-192,137,170,132, 71, 10, 3,255,192,139, 55,252,191,132, 95, 62, 64,113,216,225,160,138,234,202, 82,149, 3,255,192, 92, 61,220,
- 62,159,230, 56, 64,151, 61, 6,179,162, 7, 14,102,121, 3,255,190,249, 14, 55,190,102,133, 95, 64,186,143,210,246,200,250,216,
-127,143, 3,255, 61,225, 74,109, 64,123, 54, 51, 64,138,246, 34, 2, 15, 86,217, 93,255, 3,255, 63, 84, 6, 18, 63,142, 96,251,
- 64,182, 4, 76, 18, 98, 22,236,124,147, 3,255, 64,145, 72, 99, 63,213,114, 79, 64, 83, 35,183, 99,230, 36,253, 70,244, 3,255,
- 64, 29,246,216, 62,141,156, 17, 64,169,167,209, 52,209, 5, 96,116,119, 3,255, 64,110,132, 3,192, 85,203,243, 64, 66,107,151,
- 81,240,182, 98, 65, 47, 3,255, 64, 10,178, 37,191,201,231,138, 64,166,143,149, 46,127,222,116,114,111, 3,255,191,154, 91,138,
-192,133,179,218, 64,122,222,209,229, 0,163,226, 84,170, 3,255, 62,174,161,116,191,241,152, 81, 64,177, 2,110, 8, 39,215,241,
-121, 74, 3,255,192, 19, 76, 36, 64,129,151, 25,192, 98,254,212,206,231, 88, 97,177,131, 3,255,191,175,232, 93, 64, 64, 23,177,
-192,154,186, 69,225,227, 66,235,151, 34, 3,255,190,232,190,208, 64,139,160, 93,192,120, 33,191,244,183, 94,205,170,192, 3,255,
-192,142,126,210, 63,238, 49, 43,192, 84, 30,112,158,187, 39, 95,182,183, 3,255,192, 97,165,138, 63, 80, 9, 92,192,147, 74, 20,
-177,183, 17,233,156, 86, 3,255,192,152, 61, 98,188,106, 63, 87,192, 90, 97, 6,152,127, 0,251,180,183, 3,255, 64, 14,173,200,
- 64, 63,183,155,192,144, 75,192, 48,206, 64, 45,156,152, 3,255, 63,167,162, 95, 63,209, 29,144,192,174,245, 25, 29,250, 36, 75,
-136,250, 3,255, 64, 68, 62,211, 63,168, 56, 51,192,153,245, 13, 65,241, 29,192,150,106, 3,255, 64, 36,182, 33,191,220, 38, 34,
-192,159, 5,150, 54,233,217,211,146,223, 3,255, 63, 81, 34, 16,191,179, 64,129,192,180, 5,162, 18,242,224, 93,133,111, 3,255,
- 63,159, 56,212,192, 68,166,172,192,154,108,212, 27,176,190, 32,149,208, 3,255,191,223, 76,204,192,101, 32,170,192,137, 83, 65,
-216,199,178,195,161,198, 3,255,192, 10,249,249,191,244, 52, 62,192,162,236, 25,208, 9,213, 0,145,102, 3,255,192, 89,207, 42,
-192, 47, 6,251,192,121,165, 27,182,209,196, 18,169,198, 3,255,192,176,215,137, 63,241, 62, 25,190,219,254,179,134,179, 39,232,
-247, 78, 3,255,192,186,150, 28, 60, 28, 16,150,191, 7, 9,191,128,118, 1,131,245, 77, 3,255,192,181,132, 34, 63, 92, 60, 99,
- 63,149, 81,217,131,181, 18,238, 23,252, 3,255,190, 74,242,175, 64,183,173,164,191,145,105,227,250,117,125,160,232, 31, 3,255,
-192, 2,227,219, 64,173,164, 96,191, 78, 71,200,212,164,119, 52,238,226, 3,255,191, 92,140,181, 64,184, 38, 75, 63, 37,148,176,
-236,224,125,237, 12,159, 3,255, 64,159,104, 75, 63,236, 56,212,192, 29,126,240,108,211, 41,166,203, 9, 3,255, 64,132,159,215,
- 64, 97,184, 84,192, 10, 44, 30, 91,176, 76, 19,209, 56, 3,255, 64,164,122, 95, 64, 44,143,199,191, 68, 78, 53,112, 17, 59, 17,
-237,185, 3,255, 64, 54,176,255,192,141, 84,243,192, 36,176,237, 63,192,160, 9,200, 63, 3,255, 64,133,229, 93,192, 68, 21,217,
-192, 45,226,157, 90,249,187,187,197, 78, 3,255, 64,129, 56,203,192,130,211, 21,191,143,115,187, 87,252,166,194,229,252, 3,255,
-192,104,239,189,192,140,142, 82,191,168,178,178,177,134,158,245,227,155, 3,255,191,253,141, 50,192,167,155, 52,191,218,181,170,
-211,125,141,166,219,155, 3,255,192, 41, 58,164,192,167, 34,172, 61,151,232,206,197,232,141,243, 0, 26, 3,255,192,133,229, 93,
- 64, 68, 21,217, 64, 45,226,157,165, 7, 68, 69, 58,178, 3,255,192,129, 56,203, 64,130,211, 21, 63,143,115,187,168, 4, 89, 62,
- 26, 4, 3,255,192, 54,176,255, 64,141, 84,243, 64, 36,176,237,192, 64, 95,247, 55,193, 3,255, 63,253,141, 50, 64,167,155, 52,
- 63,218,181,170, 44,131,114, 90, 36,101, 3,255, 64, 41, 58,164, 64,167, 34,172,189,151,232,206, 58, 24,114, 13,255,230, 3,255,
- 64,104,239,189, 64,140,142, 82, 63,168,178,178, 78,122, 97, 11, 28,101, 3,255, 64,186,150, 28,188, 28, 16,150, 63, 7, 9,191,
-127,138,254,125, 10,179, 3,255, 64,181,132, 34,191, 92, 60, 99,191,149, 81,217,124, 75,237, 18,232, 4, 3,255, 64,176,215,137,
-191,241, 62, 25, 62,219,254,179,121, 77,216, 24, 8,178, 3,255, 64, 2,227,219,192,173,164, 96, 63, 78, 71,200, 43, 92,136,204,
- 17, 30, 3,255, 63, 92,140,181,192,184, 38, 75,191, 37,148,176, 19, 32,130, 19,243, 97, 3,255, 62, 74,242,175,192,183,173,164,
- 63,145,105,227, 5,139,130, 96, 23,225, 3,255,192,132,159,215,192, 97,184, 84, 64, 10, 44, 30,164, 80,179,237, 46,200, 3,255,
-192,164,122, 95,192, 44,143,199, 63, 68, 78, 53,143,239,196,239, 18, 71, 3,255,192,159,104, 75,191,236, 56,212, 64, 29,126,240,
-147, 45,214, 90, 52,247, 3,255,191,159, 56,212, 64, 68,166,172, 64,154,108,212,228, 80, 65,224,106, 48, 3,255,192, 36,182, 33,
- 63,220, 38, 34, 64,159, 5,150,201, 23, 38, 45,109, 33, 3,255,191, 81, 34, 16, 63,179, 64,129, 64,180, 5,162,237, 14, 31,163,
-122,145, 3,255, 64, 89,207, 42, 64, 47, 6,251, 64,121,165, 27, 73, 47, 59,238, 86, 58, 3,255, 63,223, 76,208, 64,101, 32,170,
- 64,137, 83, 65, 39, 57, 77, 61, 94, 58, 3,255, 64, 10,249,249, 63,244, 52, 62, 64,162,236, 25, 47,247, 43, 0,110,154, 3,255,
- 64,142,126,210,191,238, 49, 43, 64, 84, 30,112, 97, 69,216,161, 73, 73, 3,255, 64,152, 61, 98, 60,106, 63, 87, 64, 90, 97, 6,
-103,129,255, 5, 75, 73, 3,255, 64, 97,165,138,191, 80, 9, 92, 64,147, 74, 20, 78, 73,238, 23, 99,170, 3,255, 62,232,190,208,
-192,139,160, 93, 64,120, 33,191, 11, 73,161, 51, 85, 64, 3,255, 64, 19, 76, 36,192,129,151, 25, 64, 98,254,212, 49, 25,167,159,
- 78,125, 3,255, 63,175,232, 93,192, 64, 23,177, 64,154,186, 69, 30, 29,189, 21,104,222, 3,255,192, 68, 62,211,191,168, 56, 51,
- 64,153,245, 13,190, 15,226, 64,105,150, 3,255,192, 14,173,200,192, 63,183,155, 64,144, 75,192,207, 50,191,211, 99,104, 3,255,
-191,167,162, 95,191,209, 29,144, 64,174,245, 25,226, 6,219,181,119, 6, 3,255,191,211,156,158, 63,132,228,185,192,176,207,190,
-220,164, 21,231,134,244, 3,255,192, 41, 76, 0, 64, 5,199,190,192,153,157, 83,198,146, 45, 75,150,246, 3,255,192,125, 83,204,
- 64,105, 55,169,192, 20,162,244,169, 72, 79,246,206, 82, 3,255,192, 91,215,178, 64, 62,235,222,192,108,254,190,180,215, 65, 87,
-175,155, 3,255,191, 59, 63,242, 63,152,237,210,192,182, 21,251,239,125, 25, 26,131,149, 3,255, 61, 94,230, 86, 64, 35, 30,198,
-192,169, 15,233, 0,238, 55, 52,140,135, 3,255, 63,199, 4,220, 64,146,145, 7,192, 83,186,104, 34,109,100,137,184,168, 3,255,
- 63, 86,120, 9, 64,109, 91,149,192,142,242, 79, 18,133, 81, 64,158,218, 3,255,192, 95,243,103, 64,138, 91,221,191,236, 15,186,
-178,170, 93,219,216, 25, 3,255,192, 5,206, 46, 64,159, 41,121,192, 19, 91,154,209,230,108, 96,205,226, 3,255, 63,139,200,169,
- 64,163, 78,198,192, 42,146,201, 24,247,111, 59,197,206, 3,255,191, 4,128,187, 64,167,181,206,192, 37, 92, 74,245, 57,114, 96,
-199,145, 3,255,191,231, 16,151, 61,209,166,160,192,178, 95,167,217,136, 2,196,133,245, 3,255,192, 69,200,163,191, 38,143,178,
-192,158, 48,148,188,243,242, 11,147,223, 3,255,192,155,192, 43,191,250, 6,151,192, 39, 82,170,149, 79,212,247,199,231, 3,255,
-192,132,118,233,191,173,111,217,192,123,122, 67,165,100,226, 58,170,165, 3,255,192,146, 85,238, 64, 78,205,178,191,221, 54, 70,
-156,183, 71,134,218,120, 3,255,192,167,137, 76, 63,227, 31,111,191,251, 57,158,141,234, 39, 54,213, 59, 3,255,192,170,143, 39,
-191,183, 15,167,191,252, 85,251,139,217,223,169,213, 13, 3,255,192,175,214, 8, 62, 53,124,177,192, 2,241,206,136, 23, 3, 89,
-211, 92, 3,255,190,160,160, 77, 62,182, 20, 9,192,186,232,108,248, 8, 7,241,128,128, 3,255, 63,163,144, 33, 61,186,144,151,
-192,183, 47, 50, 27, 97, 2, 19,130,252, 3,255, 64,129,179,222,190,224,147,234,192,134,180, 38, 89, 83,246, 64,164,218, 3,255,
- 64, 49,138,114,190, 57, 97,246,192,165, 76, 57, 60,250,251,247,143,138, 3,255, 64, 27,158,249, 64,141,118,197,192, 62,196, 58,
- 52, 90, 97, 70,191, 90, 3,255, 64, 89,244, 98, 64, 79,120, 8,192, 96,128, 65, 74, 8, 71, 39,179,151, 3,255, 64,144,100, 13,
- 62,118,214,200,192,110,205, 64, 98,182, 4, 37,174,161, 3,255, 64,131,202, 42, 63,231,161, 60,192,112,245,142, 90, 10, 38,255,
-173,209, 3,255,191,122, 51,149,190,163,151, 52,192,184,157, 15,234,118,250, 36,129,248, 3,255,191, 42,113, 5,191,241,112, 31,
-192,176,119, 15,241, 93,215, 84,135,135, 3,255, 61,172, 55, 60,192,143, 64, 22,192,113,246,164, 2, 27,157,132,174, 71, 3,255,
-190,154,173,167,192, 83,224,111,192,154,169,198,249,136,183, 89,150,211, 3,255, 64,136,133,151,191,162,249, 9,192,115,219,106,
- 93,175,229, 47,173, 3, 3,255, 64, 89,124,110,192, 40, 6,135,192,127,195,223, 74,120,199, 31,168,208, 3,255, 63,117,248,244,
-192,148, 90,109,192, 93, 0,123, 20, 8,154, 66,180,249, 3,255, 64, 17, 0,162,192,113,196, 63,192,119,239, 52, 49, 10,173, 64,
-171,144, 3,255,191, 7,217,162,192,156,117, 21,192, 75,238,222,245,139,149, 20,186,108, 3,255,192, 6,144,171,192,144,158,112,
-192, 69,241,198,210,156,157, 55,188,115, 3,255,192,148,238,110,192, 50,109,115,192, 13,197,187,153,170,195,231,208, 17, 3,255,
-192, 96,252, 79,192,115, 40,140,192, 48,165,116,178,226,173, 98,195,236, 3,255,192,172,228,100,191,248,128,217,191,150, 93, 8,
-138, 91,213, 53,229, 86, 3,255,192,182,171, 82,191,168,250,216, 62,147, 15, 15,131,122,226,250, 5,203, 3,255,192,160, 73,215,
- 62, 49,165,124, 64, 66, 85,232,147, 33, 4, 84, 67, 42, 3,255,192,178, 89,171,191, 24,115,192, 63,221,116, 78,134,129,243, 64,
- 38, 50, 3,255,192,143,206, 51, 64,105,250,133,191, 97,251,119,158, 85, 80, 53,235,193, 3,255,192,160, 32, 62, 64, 65, 38,163,
- 63, 3,117,164,146,236, 66, 24, 10,193, 3,255,192,155,108,216, 63,141,255, 59, 64, 69,117,189,150, 61, 23,119, 68, 42, 3,255,
-192,164, 27, 85, 64, 9, 78,244, 63,239,193, 87,144, 33, 46,128, 41, 73, 3,255,192,117, 35,134, 64,138,152, 39,191,116, 86, 73,
-171,230, 94, 2,234, 73, 3,255,192, 67,220, 35, 64,159,218, 6, 62,155,103,242,188,240,108,215, 6, 55, 3,255,191, 99, 79,130,
- 64,164,182,215, 64, 42, 4, 10,237,118,112, 50, 58,190, 3,255,192, 3, 86,161, 64,168,205, 14, 63,197, 55, 60,211,148,115, 31,
- 33,255, 3,255, 63,215,101,229, 64,168,141, 84,191,248, 90, 16, 37, 11,114,148,212,159, 3,255, 63,155, 52, 99, 64,183, 17,198,
-190,235,199,232, 26,159,124,192,245,120, 3,255, 61, 10,179,105, 64,169,185, 25, 64, 31,119,120, 0, 77,115,101, 55, 96, 3,255,
- 63, 37,198,143, 64,183,120,123, 63,135,108,160, 13,240,125, 8, 23,144, 3,255, 64, 32,174,180, 64,155, 13, 65,192, 8,167,238,
- 53,247,105,245,208,163, 3,255, 64,104,199, 69, 64,143,135,177,191,132, 12, 41, 79, 10, 98, 10,233, 31, 3,255, 64,159,134,121,
- 64, 49,245, 49, 63,169,166,210,109, 27, 59,242, 29,190, 3,255, 64,143,133, 52, 64,113,200,119, 62, 29,206,186, 98, 20, 82, 39,
- 3,190, 3,255, 64,160, 73,215,190, 49,165,124,192, 66, 85,232,108,223,251,172,188,214, 3,255, 64,178, 89,171, 63, 24,115,192,
-191,221,116, 78,121,127, 12,192,217,206, 3,255, 64,172,228,100, 63,248,128,217, 63,150, 93, 8,117,165, 42,203, 26,170, 3,255,
- 64,182,171, 82, 63,168,250,216,190,147, 15, 15,124,134, 29, 6,250, 53, 3,255, 64,155,108,216,191,141,255, 59,192, 69,117,189,
-105,195,232,137,187,214, 3,255, 64,164, 27, 85,192, 9, 78,244,191,239,193, 87,111,223,209,128,214,183, 3,255, 64,143,206, 51,
-192,105,250,133, 63, 97,251,119, 97,171,175,203, 20, 63, 3,255, 64,160, 32, 62,192, 65, 38,163,191, 3,117,164,109, 20,189,232,
-245, 63, 3,255, 63, 99, 79,130,192,164,182,215,192, 42, 4, 10, 18,138,143,206,197, 66, 3,255, 64, 3, 86,161,192,168,205, 14,
-191,197, 55, 60, 44,108,140,225,222, 1, 3,255, 64,117, 35,134,192,138,152, 39, 63,116, 86, 73, 84, 26,161,254, 21,183, 3,255,
- 64, 67,220, 35,192,159,218, 6,190,155,103,242, 67, 16,147, 41,249,201, 3,255,189, 10,179,105,192,169,185, 25,192, 31,119,120,
-255,179,140,155,200,160, 3,255,191, 37,198,143,192,183,120,123,191,135,108,160,242, 16,130,248,232,112, 3,255,191,215,101,229,
-192,168,141, 84, 63,248, 90, 16,218,245,141,108, 43, 97, 3,255,191,155, 52, 99,192,183, 17,198, 62,235,199,232,229, 97,131, 64,
- 10,136, 3,255,192,159,134,121,192, 49,245, 49,191,169,166,210,146,229,196, 14,226, 66, 3,255,192,143,133, 52,192,113,200,119,
-190, 29,206,186,157,236,173,217,252, 66, 3,255,192, 32,174,180,192,155, 13, 65, 64, 8,167,238,202, 9,150, 11, 47, 93, 3,255,
-192,104,199, 69,192,143,135,177, 63,132, 12, 41,176,246,157,246, 22,225, 3,255,191,117,248,244, 64,148, 90,109, 64, 93, 0,123,
-235,248,101,190, 75, 7, 3,255,192, 17, 0,162, 64,113,196, 63, 64,119,239, 52,206,246, 82,192, 84,112, 3,255,192,136,133,151,
- 63,162,249, 9, 64,115,219,106,162, 81, 26,209, 82,253, 3,255,192, 89,124,110, 64, 40, 6,135, 64,127,195,223,181,136, 56,225,
- 87, 48, 3,255, 63, 7,217,162, 64,156,117, 21, 64, 75,238,222, 10,117,106,236, 69,148, 3,255, 64, 6,144,171, 64,144,158,112,
- 64, 69,241,198, 45,100, 98,201, 67,141, 3,255, 64,148,238,110, 64, 50,109,115, 64, 13,197,187,102, 86, 60, 25, 47,239, 3,255,
- 64, 96,252, 79, 64,115, 40,140, 64, 48,165,116, 77, 30, 82,158, 60, 20, 3,255, 64,170,143, 39, 63,183, 15,167, 63,252, 85,251,
-116, 39, 32, 87, 42,243, 3,255, 64,175,214, 8,190, 53,124,177, 64, 2,241,206,119,233,252,167, 44,164, 3,255, 64,146, 85,238,
-192, 78,205,178, 63,221, 54, 70, 99, 73,184,122, 37,136, 3,255, 64,167,137, 76,191,227, 31,111, 63,251, 57,158,114, 22,216,202,
- 42,197, 3,255, 64, 95,243,103,192,138, 91,221, 63,236, 15,186, 77, 86,162, 37, 39,231, 3,255, 64, 5,206, 46,192,159, 41,121,
- 64, 19, 91,154, 46, 26,147,160, 50, 30, 3,255,191,139,200,169,192,163, 78,198, 64, 42,146,201,231, 9,144,197, 58, 50, 3,255,
- 63, 4,128,187,192,167,181,206, 64, 37, 92, 74, 10,199,141,160, 56,111, 3,255,192, 27,158,249,192,141,118,197, 64, 62,196, 58,
-203,166,158,186, 64,166, 3,255,192, 89,244, 98,192, 79,120, 8, 64, 96,128, 65,181,248,184,217, 76,105, 3,255,192,144,100, 13,
-190,118,214,200, 64,110,205, 64,157, 74,251,219, 81, 95, 3,255,192,131,202, 42,191,231,161, 60, 64,112,245,142,165,246,217, 1,
- 82, 47, 3,255,192,129,179,222, 62,224,147,234, 64,134,180, 38,166,173, 9,192, 91, 38, 3,255,192, 49,138,114, 62, 57, 97,246,
- 64,165, 76, 57,195, 6, 4, 9,112,118, 3,255, 62,160,160, 77,190,182, 20, 9, 64,186,232,108, 7,248,248, 15,127,128, 3,255,
-191,163,144, 33,189,186,144,151, 64,183, 47, 50,228,159,253,237,125, 4, 3,255,189,172, 55, 60, 64,143, 64, 22, 64,113,246,164,
-253,229, 98,124, 81,185, 3,255, 62,154,173,167, 64, 83,224,111, 64,154,169,198, 6,120, 72,167,105, 45, 3,255, 63,122, 51,149,
- 62,163,151, 52, 64,184,157, 15, 21,138, 5,220,126, 8, 3,255, 63, 42,113, 5, 63,241,112, 31, 64,176,119, 15, 14,163, 40,172,
-120,121, 3,255, 64,155,192, 43, 63,250, 6,151, 64, 39, 82,170,106,177, 43, 9, 56, 25, 3,255, 64,132,118,233, 63,173,111,217,
- 64,123,122, 67, 90,156, 29,198, 85, 91, 3,255, 63,231, 16,151,189,209,166,160, 64,178, 95,167, 38,120,253, 60,122, 11, 3,255,
- 64, 69,200,163, 63, 38,143,178, 64,158, 48,148, 67, 13, 13,245,108, 33, 3,255, 64,125, 83,204,192,105, 55,169, 64, 20,162,244,
- 86,184,176, 10, 49,174, 3,255, 64, 91,215,178,192, 62,235,222, 64,108,254,190, 75, 41,190,169, 80,101, 3,255, 63,211,156,158,
-191,132,228,185, 64,176,207,190, 35, 92,234, 25,121, 12, 3,255, 64, 41, 76, 0,192, 5,199,190, 64,153,157, 83, 57,110,210,181,
-105, 10, 3,255,191,199, 4,220,192,146,145, 7, 64, 83,186,104,221,147,155,119, 71, 88, 3,255,191, 86,120, 9,192,109, 91,149,
- 64,142,242, 79,237,123,174,192, 97, 38, 3,255, 63, 59, 63,242,191,152,237,210, 64,182, 21,251, 16,131,230,230,124,107, 3,255,
-189, 94,230, 86,192, 35, 30,198, 64,169, 15,233,255, 18,200,204,115,121, 3,255,192, 46, 27,208, 64, 86,104,124,192,126, 52, 85,
-197,137, 72,226,168,134, 3,255,191,234,168, 82, 64,149, 62, 87,192, 67, 12,118,217, 5,101,188,188,210, 3,255,192, 16, 10,186,
- 64, 52,106,249,192,147,253,210,206,182, 62,131,155,198, 3,255,190,240, 33, 93, 64, 71,199,191,192,158, 47,142,245,214, 69, 40,
-148,199, 3,255,187, 71, 46, 19, 64,115,240,194,192,142,166,175,254,240, 82,161,158, 66, 3,255,191,101,194,188, 64,154, 84, 17,
-192, 77,193,240,235, 76,104,214,185,142, 3,255,192,115,246,246, 64, 15, 86,183,192,118,168, 51,172,249, 47,229,171, 45, 3,255,
-192,160, 1,101, 63,184,146, 47,192, 45, 38,153,146,225, 30, 96,196,102, 3,255,192, 85,229,215, 63,218,178,166,192,144, 55,183,
-182, 38, 37,133,158,110, 3,255,192,104,178,151,189,205,107,245,192,147, 60,175,175,178,253,205,156, 91, 3,255,192,136, 81,192,
-191, 4,239, 55,192,127,222, 24,163,130,245,158,168, 35, 3,255,192,164,241, 70, 62,251,218,102,192, 48, 82,143,143,222, 11,210,
-195,110, 3,255, 63,173,230,209, 64, 71,135,231,192,152,234, 27, 29,148, 67, 4,151, 11, 3,255, 64, 67,103,158, 64, 51,206, 82,
-192,132,168, 39, 66,203, 60, 63,164,242, 3,255, 63,100,131,136, 64, 27, 95, 16,192,168,115, 4, 20,122, 53,138,141,143, 3,255,
- 63,217,154, 77, 63, 78, 69,185,192,177,196,221, 38, 53, 17,236,135, 42, 3,255, 64, 37,195,107, 63, 36,213, 4,192,167, 33, 20,
- 55,151, 14,194,141,168, 3,255, 64, 94,139,103, 63,250,146,153,192,137,141, 72, 75, 19, 43,156,161,245, 3,255, 64, 21,195,231,
-191,101, 58,236,192,169,178,218, 49,247,236, 31,139,218, 3,255, 64, 48, 32,142,192, 32,140,155,192,145, 1,195, 59, 3,200,178,
-156,204, 3,255, 63,185,155, 70,191, 59,202, 12,192,180, 86,163, 32,149,239, 73,133, 91, 3,255, 62, 43, 97, 29,192, 2,118,144,
-192,175,231,125, 4,106,210,160,136,103, 3,255, 62,196,116, 97,192, 56,176, 10,192,162,239,120, 8,164,194, 20,144, 81, 3,255,
- 64, 5, 2,185,192, 76,105,217,192,142,173,135, 45,218,187, 79,158, 56, 3,255,191,144,243,163,192, 73, 41,252,192,154, 66,148,
-230,134,188, 73,150,107, 3,255,192, 20,133,147,192,124, 55,234,192,107, 3,176,204,110,170,196,175,164, 3,255,192, 60,186, 42,
-191,189,128,219,192,155, 43, 23,191, 41,222,189,150,199, 3,255,191,172,164, 52,192, 18,240,106,192,167, 58,141,226, 76,204,213,
-142,128, 3,255,192,100,171, 12,191,243, 33,249,192,135,221,106,178,248,214,143,162,143, 3,255,192, 74, 78,195,192, 96,206,241,
-192, 94, 88, 98,188, 4,179, 34,179,129, 3,255,192,177,110, 41, 63,186, 30, 81,191,158,249,105,134,160, 30,165,229, 86, 3,255,
-192,172,138, 45, 64, 17,149,114, 62,200,203,127,137,251, 48,171, 9, 56, 3,255,192,182, 94, 10, 63, 1, 5, 48,191,165, 81, 86,
-131,156, 12, 24,228, 94, 3,255,192,186,224,117,190,247,234, 37, 62,126, 56,147,128,132,246,101, 6, 46, 3,255,192,184, 78,204,
-189, 89,193, 19, 63,141,163,187,130, 22,254,208, 22,241, 3,255,192,174,232,105, 63,224,187,151, 63,153,183,156,136,137, 38,137,
- 25, 3, 3,255,191, 68,118, 42, 64,176,173,101,191,233,132,114,238, 57,120,142,216,217, 3,255, 62,191,172, 81, 64,186,208, 67,
-190,216,163,195, 7, 75,127,131,247,159, 3,255,191,218, 2,113, 64,171,151,172,191,212, 25,114,219,243,117,116,220, 30, 3,255,
-192, 21,244,251, 64,172, 12, 28, 61,128,151, 13,205,229,117,196, 1,226, 3,255,191,223, 39, 51, 64,177, 94,248, 63, 76,122,104,
-217,155,121, 3, 16, 65, 3,255, 61, 28,208, 72, 64,187, 13, 91, 62,245,215, 64, 0,187,127,168, 9, 66, 3,255, 64,142, 93, 45,
- 64, 14,137, 70,192, 70,202,147, 96,241, 49,173,188,202, 3,255, 64,173, 23,106, 63,182,131,157,191,225,176,175,118, 7, 32, 20,
-218, 72, 3,255, 64,128,203, 78, 64, 69, 14,124,192, 61, 0, 55, 88,168, 66, 80,191,199, 3,255, 64,133,175,133, 64,121,149, 28,
-191,168,212, 51, 92, 4, 84, 86,227,170, 3,255, 64,149,211, 8, 64, 94,166, 84,191, 29, 24, 68,101,221, 76, 30,241,113, 3,255,
- 64,175,169, 31, 63,237,176,138,191,103,168, 15,119,152, 40,128,235, 11, 3,255, 64, 57, 78,122,192,120, 12,224,192, 84, 56, 7,
- 64, 62,171,247,183,239, 3,255, 64, 48, 74, 0,192,155,165,245,191,227, 87,208, 61, 38,150, 68,217,192, 3,255, 64,100,108, 85,
-192, 76, 47,115,192, 88,224,149, 77,102,185, 90,182,131, 3,255, 64,150,191,173,192, 55,233,227,191,254,101,198,102,121,192, 79,
-213, 73, 3,255, 64,148, 97,119,192, 89, 33,200,191,150,225, 24,101, 7,182, 44,229, 20, 3,255, 64, 86,171, 75,192,150, 83, 36,
-191,133, 36, 22, 72,220,153,131,232, 32, 3,255,192, 81,251,116,192,139, 80,115,192, 10,124, 57,185, 81,160, 53,208,254, 3,255,
-192,122,239, 70,192,138,220, 53,190,227, 86,113,171, 68,160,132,246,195, 3,255,192, 28, 50, 14,192,153, 4,245,192, 23, 39,141,
-201,187,151,215,205, 33, 3,255,191,189,123, 34,192,178,168,203,191,130,106,149,222,209,134, 63,234,158, 3,255,191,232,127,176,
-192,178,107,177,189,236,189, 47,216, 65,134,100,252, 66, 3,255,192, 90,168, 53,192,152, 83,169, 62,133,201,227,181, 29,152, 77,
- 4,136, 3,255,192,150,191,173, 64, 55,233,227, 63,254,101,198,153,135, 63,177, 42,183, 3,255,192,100,108, 85, 64, 76, 47,115,
- 64, 88,224,149,178,154, 70,166, 73,125, 3,255,192,148, 97,119, 64, 89, 33,200, 63,150,225, 24,154,249, 73,212, 26,236, 3,255,
-192, 86,171, 75, 64,150, 83, 36, 63,133, 36, 22,183, 36,102,125, 23,224, 3,255,192, 48, 74, 0, 64,155,165,245, 63,227, 87,208,
-194,218,105,188, 38, 64, 3,255,192, 57, 78,122, 64,120, 12,224, 64, 84, 56, 7,191,194, 84, 9, 72, 17, 3,255, 63,189,123, 34,
- 64,178,168,203, 63,130,106,149, 33, 47,121,193, 21, 98, 3,255, 64, 28, 50, 14, 64,153, 4,245, 64, 23, 39,141, 54, 69,104, 41,
- 50,223, 3,255, 63,232,127,176, 64,178,107,177, 61,236,189, 47, 39,191,121,156, 3,190, 3,255, 64, 90,168, 53, 64,152, 83,169,
-190,133,201,227, 74,227,103,179,251,120, 3,255, 64,122,239, 70, 64,138,220, 53, 62,227, 86,113, 84,188, 95,124, 9, 61, 3,255,
- 64, 81,251,116, 64,139, 80,115, 64, 10,124, 57, 70,175, 95,203, 47, 2, 3,255, 64,186,224,117, 62,247,234, 37,190,126, 56,147,
-127,124, 9,155,249,210, 3,255, 64,182, 94, 10,191, 1, 5, 48, 63,165, 81, 86,124,100,243,232, 27,162, 3,255, 64,184, 78,204,
- 61, 89,193, 19,191,141,163,187,125,234, 1, 48,233, 15, 3,255, 64,174,232,105,191,224,187,151,191,153,183,156,119,119,217,119,
-230,253, 3,255, 64,172,138, 45,192, 17,149,114,190,200,203,127,118, 5,207, 85,246,200, 3,255, 64,177,110, 41,191,186, 30, 81,
- 63,158,249,105,121, 96,225, 91, 26,170, 3,255, 64, 21,244,251,192,172, 12, 28,189,128,151, 13, 50, 27,138, 60,254, 30, 3,255,
- 63,218, 2,113,192,171,151,172, 63,212, 25,114, 36, 13,138,140, 35,226, 3,255, 63,223, 39, 51,192,177, 94,248,191, 76,122,104,
- 38,101,134,253,239,191, 3,255,189, 28,208, 72,192,187, 13, 91,190,245,215, 64,255, 69,128, 88,246,190, 3,255,190,191,172, 81,
-192,186,208, 67, 62,216,163,195,248,181,128,125, 8, 97, 3,255, 63, 68,118, 42,192,176,173,101, 63,233,132,114, 17,199,135,114,
- 39, 39, 3,255,192,133,175,133,192,121,149, 28, 63,168,212, 51,163,252,171,170, 28, 86, 3,255,192,128,203, 78,192, 69, 14,124,
- 64, 61, 0, 55,167, 88,189,176, 64, 57, 3,255,192,175,169, 31,191,237,176,138, 63,103,168, 15,136,104,215,128, 20,245, 3,255,
-192,149,211, 8,192, 94,166, 84, 63, 29, 24, 68,154, 35,179,226, 14,143, 3,255,192,173, 23,106,191,182,131,157, 63,225,176,175,
-137,249,223,236, 37,184, 3,255,192,142, 93, 45,192, 14,137, 70, 64, 70,202,147,159, 15,206, 83, 67, 54, 3,255,192, 5, 2,185,
- 64, 76,105,217, 64,142,173,135,210, 38, 68,177, 97,200, 3,255,190,196,116, 97, 64, 56,176, 10, 64,162,239,120,247, 92, 61,236,
-111,175, 3,255,192, 48, 32,142, 64, 32,140,155, 64,145, 1,195,196,253, 55, 78, 99, 52, 3,255,192, 21,195,231, 63,101, 58,236,
- 64,169,178,218,206, 9, 19,225,116, 38, 3,255,191,185,155, 70, 63, 59,202, 12, 64,180, 86,163,223,107, 16,183,122,165, 3,255,
-190, 43, 97, 29, 64, 2,118,144, 64,175,231,125,251,150, 45, 96,119,153, 3,255, 64, 74, 78,195, 64, 96,206,241, 64, 94, 88, 98,
- 67,252, 76,222, 76,127, 3,255, 64,100,171, 12, 63,243, 33,249, 64,135,221,106, 77, 8, 41,113, 93,113, 3,255, 64, 20,133,147,
- 64,124, 55,234, 64,107, 3,176, 51,146, 85, 60, 80, 92, 3,255, 63,144,243,164, 64, 73, 41,252, 64,154, 66,148, 25,122, 67,183,
-105,149, 3,255, 63,172,164, 52, 64, 18,240,106, 64,167, 58,141, 29,180, 51, 43,113,128, 3,255, 64, 60,186, 42, 63,189,128,219,
- 64,155, 43, 23, 64,215, 33, 67,105, 57, 3,255, 64,160, 1,101,191,184,146, 47, 64, 45, 38,153,109, 31,225,160, 59,154, 3,255,
- 64,115,246,246,192, 15, 86,183, 64,118,168, 51, 83, 7,208, 27, 84,211, 3,255, 64,164,241, 70,190,251,218,102, 64, 48, 82,143,
-112, 34,244, 46, 60,146, 3,255, 64,136, 81,192, 63, 4,239, 55, 64,127,222, 24, 92,126, 10, 98, 87,221, 3,255, 64,104,178,151,
- 61,205,107,245, 64,147, 60,175, 80, 78, 2, 51, 99,165, 3,255, 64, 85,229,215,191,218,178,166, 64,144, 55,183, 73,218,218,123,
- 97,146, 3,255, 63,101,194,188,192,154, 84, 17, 64, 77,193,240, 20,180,151, 42, 70,114, 3,255, 59, 71, 46, 19,192,115,240,194,
- 64,142,166,175, 1, 16,173, 95, 97,190, 3,255, 63,234,168, 82,192,149, 62, 87, 64, 67, 12,118, 38,251,154, 68, 67, 46, 3,255,
- 64, 46, 27,208,192, 86,104,124, 64,126, 52, 85, 58,119,183, 30, 87,122, 3,255, 64, 16, 10,186,192, 52,106,249, 64,147,253,210,
- 49, 74,193,125,100, 58, 3,255, 62,240, 33, 93,192, 71,199,191, 64,158, 47,142, 10, 42,186,216,107, 57, 3,255,192, 94,139,103,
-191,250,146,153, 64,137,141, 72,180,237,212,100, 94, 11, 3,255,192, 37,195,107,191, 36,213, 4, 64,167, 33, 20,200,105,241, 62,
-114, 88, 3,255,192, 67,103,158,192, 51,206, 82, 64,132,168, 39,189, 53,195,193, 91, 14, 3,255,191,173,230,209,192, 71,135,231,
- 64,152,234, 27,226,108,188,252,104,245, 3,255,191,217,154, 77,191, 78, 69,185, 64,177,196,221,217,203,238, 20,120,214, 3,255,
-191,100,131,136,192, 27, 95, 16, 64,168,115, 4,235,134,202,118,114,113, 3,255,192, 37,220,139, 64,141,135,245,192, 54,173,114,
-199, 45, 96, 95,193,211, 3,255,192, 84,119,204, 64,130, 73, 93,192, 38,107,212,183, 58, 88,223,199,137, 3,255,192, 67, 76,208,
- 64,111,120, 62,192, 85, 89, 14,189, 80, 81,196,183,140, 3,255,191,238,147, 68, 64,100,230,166,192,136, 9,234,215,216, 78,130,
-163, 59, 3,255,191,109,149, 30, 64,111, 18, 40,192,141,100,171,235, 37, 81,201,159,199, 3,255,191,178,237,144, 64,136,136, 25,
-192,113, 1,121,225,117, 92,189,173, 62, 3,255, 63, 66, 82,214, 64,152,115,128,192, 85, 25,164, 16,241,104, 27,183,126, 3,255,
-189,171,155,119, 64,155, 40,138,192, 83, 96,113,254,128,105,196,183,238, 3,255, 62,194,138, 67, 64,138, 97,177,192,124,158, 75,
- 8,112, 94,134,170, 29, 3,255,191, 94,106,158, 64, 30,106,167,192,167,240,254,236,229, 53,187,141,105, 3,255,191,229,114, 22,
- 64, 20, 96,193,192,162,167,253,217, 22, 50, 93,144,244, 3,255,191,162,210, 45, 63,224,211,233,192,174, 67,184,228, 69, 37,245,
-136,244, 3,255,192,152, 61, 37, 64, 14, 9,230,192, 39,179,137,152, 85, 48,183,198,226, 3,255,192,140,187,232, 64, 62, 96, 6,
-192, 30,247,107,160, 7, 65, 68,202, 11, 3,255,192,132,134,116, 64, 40,130, 40,192, 77,207,237,165,139, 57,149,186, 30, 3,255,
-192,129,129, 12, 63,173,129,231,192,128,125,159,167, 62, 29, 15,168,123, 3,255,192,134,112,254, 62,207,146,126,192,130, 19,159,
-164, 15, 9,119,167,117, 3,255,192,149,121,189, 63,111,192,142,192, 90, 95, 76,154, 95, 20,107,180,236, 3,255,192,162, 65, 12,
-191,149, 84, 11,192, 44,202,172,145, 60,230, 47,197, 75, 3,255,192,165,120, 74,190,167, 78, 95,192, 48, 51,139,143, 54,248,140,
-195,244, 3,255,192,150,161, 61,191, 89,221,107,192, 89,113,118,153, 40,237, 79,182, 35, 3,255,192, 66, 56, 52, 62,139, 40,206,
-192,160,116, 21,190, 13, 6, 19,146,121, 3,255,192, 56,120,245, 63,154,213,118,192,158,227, 81,193, 81, 26, 47,147,133, 3,255,
-192, 22,104,220, 63, 40,221,204,192,170,137,115,205, 16, 14, 89,139,117, 3,255, 64, 39,143,145, 64, 94, 49,190,192,124, 27,165,
- 56,238, 75,252,170, 43, 3,255, 64, 6,168,130, 64,130,132,190,192,105, 96, 12, 45,226, 89, 91,176,173, 3,255, 63,222,169, 76,
- 64,104,107,205,192,136,142,150, 38, 23, 79,105,163, 33, 3,255, 63,229,207,137, 64, 22, 63, 30,192,161,235,207, 39,198, 50,227,
-145,127, 3,255, 64, 14, 11,239, 63,191,114,175,192,166,208,254, 48,133, 33, 81,142, 87, 3,255, 64, 43,222,239, 64, 11,226,212,
-192,151, 71,227, 58, 33, 47,140,152, 91, 3,255, 64,124,245, 0, 62,187, 32, 27,192,138, 6, 57, 86,138, 7,176,162, 2, 3,255,
- 64,112, 75, 42, 63,152, 42,228,192,139, 44, 25, 82, 0, 25,159,161, 31, 3,255, 64, 82,218,178, 63, 1,247,178,192,154,129,211,
- 72, 35, 11, 4,150,217, 3,255, 63,104,203,208, 63,113, 6,146,192,183, 5,108, 19,132, 20,150,131, 49, 3,255, 62,251, 68, 26,
- 63,228, 38,111,192,178, 48,114, 10,139, 38,158,134,109, 3,255, 61,149, 78,163, 63,137, 25, 65,192,184,102,234, 1, 54, 23, 52,
-130, 34, 3,255, 64, 80,140, 98,191,238,205,169,192,144, 69, 83, 71, 70,215,145,157,173, 3,255, 64,109, 39,177,191,147,213,155,
-192,140,143,238, 81, 57,230,247,160, 77, 3,255, 64, 66,225,100,191,131,191,146,192,157, 18,152, 66,178,233,128,149, 25, 3,255,
- 63,220, 24,190,191,202,163,163,192,171,244,160, 37, 99,220,199,138,196, 3,255, 63,133,219,227,192, 17, 47,172,192,169,160, 93,
- 23,126,206,164,140, 68, 3,255, 63,247,202, 46,192, 27,140, 23,192,158,252,116, 41,217,203, 77,147, 32, 3,255, 63, 68,220, 36,
-192,132,143, 24,192,130,105, 20, 16,163,165, 66,167, 72, 3,255, 63,185,255, 60,192,108,244,215,192,138, 7,129, 31,113,175, 11,
-161,251, 3,255, 63, 19, 18,220,192, 98,186,168,192,148,136, 66, 12,155,178,121,154,241, 3,255,187,172,119,131,191,162,209,182,
-192,183, 73,170,255,209,228,144,130,251, 3,255, 63, 40,230,165,191, 24,111,246,192,185,150, 50, 14, 19,243, 18,129,113, 3,255,
-190, 50, 45,123,190,230, 16,213,192,186,240,160,251,231,246,124,128,109, 3,255,191,199, 22,221,192,134,211, 71,192,113,161, 37,
-222, 98,163,255,173,157, 3,255,191, 58,131,171,192,140,178, 57,192,115,174,214,240,105,159,201,173, 11, 3,255,191,112,119,228,
-192,115, 46, 49,192,139,222,186,235,152,172,221,160,217, 3,255,191,254, 75,122,192, 50, 36, 18,192,152, 70, 84,211,253,195, 46,
-152, 87, 3,255,192, 52,239,190,192, 22,186,193,192,145,240,166,194,167,204, 3,156,108, 3,255,192, 39, 23, 51,192, 76,245, 14,
-192,132,248,105,199, 29,186,137,164,200, 3,255,192,140,137,202,192, 33,234, 4,192, 60,117,152,159,215,200,216,192, 6, 3,255,
-192,115,176, 68,192, 68, 49, 85,192, 79,173, 65,172,178,189, 81,185, 81, 3,255,192,128,173,131,192, 14,170, 50,192,105, 71,247,
-168, 30,207, 64,176,189, 3,255,192, 22, 80,230,191,141,155, 50,192,168, 95,108,205, 3,232, 6,141, 19, 3,255,191,194,113, 96,
-191,195,184,166,192,174,160, 31,222,205,222,245,136,227, 3,255,191,213,244,249,191, 52, 33, 10,192,178, 94,248,219,172,241, 3,
-134, 48, 3,255,192,167, 26, 30, 64, 42, 11, 62,190,159,163,199,142, 45, 58, 26,248,236, 3,255,192,157,242, 15, 64, 63, 35,177,
-191,132,230,242,148,115, 65,134,233, 39, 3,255,192,169,163, 58, 64, 14,207,184,191,148, 92, 43,140,122, 48,250,230,193, 3,255,
-192,184, 83,241, 63,117,241, 33,190,248, 69,204,130, 32, 20,245,246, 22, 3,255,192,186,178, 88, 62,226, 33,180, 62,165,211, 69,
-128,153, 10, 65, 6,196, 3,255,192,181,194,100, 63,178, 37,227, 62,191, 51, 65,131,199, 29,217, 7,201, 3,255,192,168, 68,140,
- 63, 57,100,162, 64, 31, 41, 90,141, 91, 15,195, 54,175, 3,255,192,173,114,185, 63,162, 11,147, 63,237,131,136,137,204, 27,106,
- 40,187, 3,255,192,178, 82, 90, 62,168, 0,181, 63,231, 64,125,134,136, 7, 78, 39,175, 3,255,192,185, 52,235,191, 83,185,191,
-190,252,176, 39,129,201,237,211,244,241, 3,255,192,182,222, 95,190,161, 32,178,191,165, 92, 48,131, 90,248,208,227,211, 3,255,
-192,179,119, 52,191,147,204,223,191,160,141,116,133,169,230,113,228,103, 3,255, 63, 35, 88,109, 64,182,186,129,191,152, 8,207,
- 14, 5,124,127,229,202, 3,255, 63, 99, 54,226, 64,174,134,172,191,250, 98, 96, 19,180,118,244,213, 14, 3,255, 61, 60,195,150,
- 64,177,121, 46,191,245, 6,174, 1, 84,120,249,214, 55, 3,255,191,145,160,228, 64,181, 59,121,191,123,252,246,231, 63,123,214,
-235, 42, 3,255,191,188,166, 29, 64,181,120,167,189,165,224, 4,224, 81,123,253,253,203, 3,255,191, 9,186, 26, 64,186,142,104,
-190,126, 74,128,243,158,127, 69,250, 88, 3,255,191, 19,205,179, 64,175,145, 33, 63,253,151,102,243,125,119,171, 43,167, 3,255,
-190,134,114,163, 64,183, 94, 81, 63,157,210, 73,250, 40,124,240, 27, 49, 3,255,191,151,217,253, 64,178, 89, 90, 63,178,246,210,
-230, 89,121,146, 30,187, 3,255,192, 50,200,107, 64,164, 21, 4,191, 18,252,143,194,229,111,189,243, 58, 3,255,192, 29,140,219,
- 64,163,216,164,191,187,160,163,202, 2,111,148,224, 27, 3,255,192, 76, 63, 8, 64,152, 92,149,191,157, 6,201,185,254,103,184,
-229, 25, 3,255, 64,167, 31,102, 63,133,113, 18,192, 29,150,122,113,214, 22,149,202, 5, 3,255, 64,157, 48,115, 63, 33,183, 74,
-192, 72,172, 21,107, 50, 13,106,187, 91, 3,255, 64,151, 48,250, 63,186,157,117,192, 74, 37,236,103, 41, 31,126,187, 23, 3,255,
- 64,148, 31,118, 64, 46, 99,144,192, 21,237, 95,101,101, 59,141,205,115, 3,255, 64,150,177, 40, 64, 73,250,101,191,189,252,104,
-103, 13, 68,113,223, 39, 3,255, 64,164, 67, 59, 64, 19,116,106,191,209,145, 96,111,204, 50,223,219,255, 3,255, 64,168, 99, 9,
- 64, 32,173,184, 63, 27, 16,129,114,228, 54,189, 13,164, 3,255, 64,174, 1,225, 64, 12,167, 65,190, 38, 1,199,118,149, 48, 17,
-252,195, 3,255, 64,160,156,172, 64, 66,121, 23,188, 53,253,220,109,155, 66, 25, 0, 0, 3,255, 64,106,184,230, 64,133, 83,117,
-191,243, 95, 76, 79,202, 90,251,214, 77, 3,255, 64,101,166,116, 64,111,107, 67,192, 47,233, 69, 78, 23, 81,219,196, 34, 3,255,
- 64, 68, 20,109, 64,139, 9,202,192, 29,255,124, 66,138, 95, 22,202, 6, 3,255, 64, 12,138, 46,192,156,168,195,192, 23,240, 99,
- 47,172,149, 54,203,252, 3,255, 63,201,189,110,192,154, 28, 48,192, 60,148,180, 34, 2,150,195,191,147, 3,255, 64, 17, 55, 21,
-192,140, 67,125,192, 75, 8,118, 49, 61,160, 50,186,221, 3,255, 64,100,126, 85,192,114,211,103,192, 43,176,187, 78, 60,172,241,
-198, 2, 3,255, 64,133,112, 29,192,104, 45,168,191,249, 44, 95, 90,154,176, 96,213, 48, 3,255, 64, 95,193,192,192,138, 5,221,
-191,239,219, 42, 76,181,162, 61,214,177, 3,255, 64,134, 21, 28,192,130,231,185, 62,133,210,175, 91,128,166,182, 6, 33, 3,255,
- 64,115,101,128,192,142,100,106,190,205,174,214, 83, 32,159, 12,247,127, 3,255, 64,142,250,187,192,113,123,178,190,242,120, 90,
- 97, 99,173,142,245,244, 3,255, 64,149, 83,115,192, 24,118, 25,192, 41, 5, 96,101,195,204, 61,198, 36, 3,255, 64,130, 97,236,
-192, 34,248,181,192, 87,132, 49, 89, 17,200,184,182,144, 3,255, 64,144,103,186,191,234, 9, 91,192, 80,226,150, 98,152,216,121,
-184,152, 3,255,192,136, 74,208,192,121,117,231,191,133,193, 32,162,248,171, 42,232,249, 3,255,192,144, 84, 31,192, 87, 19, 24,
-191,211, 65, 53,157, 74,182,248,219,224, 3,255,192,123, 90, 7,192,121,238,107,191,247,227,115,170, 22,171, 1,213,218, 3,255,
-192, 54,112,161,192,156, 77, 94,191,196,107,207,193,198,149, 23,223, 32, 3,255,192, 22, 41, 24,192,169,197, 1,191, 84, 68,191,
-204, 45,140,105,237,172, 3,255,192, 75,243, 73,192,156, 16, 86,191, 33,150,180,186,216,149, 63,241,194, 3,255,192, 19,246,140,
-192,166, 60,148, 63,182, 70, 11,205,164,142,159, 31,127, 3,255,192, 58, 21, 17,192,160,209,224, 63, 88,100,103,192,202,146, 72,
- 18,171, 3,255,192, 4,252,151,192,174, 89, 71, 63, 38, 93,215,210,148,137, 55, 14,122, 3,255,191,150,176, 53,192,174,252,238,
-191,226,172, 37,230,114,136,199,217, 20, 3,255,191,214,105,225,192,161,177,211,192, 29,229,160,219,197,145,175,202, 38, 3,255,
-191, 88,213, 62,192,167, 70,193,192, 32,217,212,237,221,141,232,200,230, 3,255,192,130, 97,236, 64, 34,248,181, 64, 87,132, 49,
-166,239, 55, 72, 73,112, 3,255,192,144,103,186, 63,234, 9, 91, 64, 80,226,150,157,104, 39,135, 71,104, 3,255,192,149, 83,115,
- 64, 24,118, 25, 64, 41, 5, 96,154, 61, 51,195, 57,220, 3,255,192,133,112, 29, 64,104, 45,168, 63,249, 44, 95,165,102, 79,160,
- 42,208, 3,255,192, 95,193,192, 64,138, 5,221, 63,239,219, 42,179, 75, 93,195, 41, 79, 3,255,192,100,126, 85, 64,114,211,103,
- 64, 43,176,187,177,196, 83, 15, 57,254, 3,255,191,201,189,110, 64,154, 28, 48, 64, 60,148,180,221,254,105, 61, 64,109, 3,255,
-192, 17, 55, 21, 64,140, 67,125, 64, 75, 8,118,206,195, 95,206, 69, 35, 3,255,192, 12,138, 46, 64,156,168,195, 64, 23,240, 99,
-208, 84,106,202, 52, 4, 3,255,192,115,101,128, 64,142,100,106, 62,205,174,214,172,224, 96,244, 8,129, 3,255,192,142,250,187,
- 64,113,123,178, 62,242,120, 90,158,157, 82,114, 10, 12, 3,255,192,134, 21, 28, 64,130,231,185,190,133,210,175,164,128, 89, 74,
-249,223, 3,255, 63,214,105,225, 64,161,177,211, 64, 29,229,160, 36, 59,110, 81, 53,218, 3,255, 63, 88,213, 62, 64,167, 70,193,
- 64, 32,217,212, 18, 35,114, 24, 55, 26, 3,255, 63,150,176, 53, 64,174,252,238, 63,226,172, 37, 25,142,119, 57, 38,236, 3,255,
- 64, 22, 41, 24, 64,169,197, 1, 63, 84, 68,191, 51,211,115,151, 18, 84, 3,255, 64, 75,243, 73, 64,156, 16, 86, 63, 33,150,180,
- 69, 40,106,193, 14, 62, 3,255, 64, 54,112,161, 64,156, 77, 94, 63,196,107,208, 62, 58,106,233, 32,224, 3,255, 64,144, 84, 31,
- 64, 87, 19, 24, 63,211, 65, 53, 98,182, 73, 8, 36, 32, 3,255, 64,123, 90, 7, 64,121,238,107, 63,247,227,115, 85,234, 84,255,
- 42, 38, 3,255, 64,136, 74,208, 64,121,117,231, 63,133,193, 32, 93, 8, 84,214, 23, 7, 3,255, 64, 58, 21, 17, 64,160,209,224,
-191, 88,100,103, 63, 54,109,184,237, 85, 3,255, 64, 4,252,151, 64,174, 89, 71,191, 38, 93,215, 45,108,118,201,241,134, 3,255,
- 64, 19,246,140, 64,166, 60,148,191,182, 70, 11, 50, 92,113, 97,224,129, 3,255, 64,182,222, 95, 62,161, 32,178, 63,165, 92, 48,
-124,166, 7, 48, 28, 45, 3,255, 64,179,119, 52, 63,147,204,223, 63,160,141,116,122, 87, 25,143, 27,153, 3,255, 64,185, 52,235,
- 63, 83,185,191, 62,252,176, 39,126, 55, 18, 45, 11, 15, 3,255, 64,186,178, 88,190,226, 33,180,190,165,211, 69,127,103,245,191,
-249, 60, 3,255, 64,181,194,100,191,178, 37,227,190,191, 51, 65,124, 57,226, 39,248, 55, 3,255, 64,184, 83,241,191,117,241, 33,
- 62,248, 69,204,125,224,235, 11, 9,234, 3,255, 64,157,242, 15,192, 63, 35,177, 63,132,230,242,107,141,190,122, 22,217, 3,255,
- 64,169,163, 58,192, 14,207,184, 63,148, 92, 43,115,134,207, 6, 25, 63, 3,255, 64,167, 26, 30,192, 42, 11, 62, 62,159,163,199,
-113,211,197,230, 7, 20, 3,255, 64,173,114,185,191,162, 11,147,191,237,131,136,118, 52,228,150,215, 69, 3,255, 64,178, 82, 90,
-190,168, 0,181,191,231, 64,125,121,120,248,178,216, 81, 3,255, 64,168, 68,140,191, 57,100,162,192, 31, 41, 90,114,165,240, 61,
-201, 81, 3,255, 64, 29,140,219,192,163,216,164, 63,187,160,163, 53,254,144,108, 31,229, 3,255, 64, 76, 63, 8,192,152, 92,149,
- 63,157, 6,201, 70, 2,152, 72, 26,231, 3,255, 64, 50,200,107,192,164, 21, 4, 63, 18,252,143, 61, 27,144, 67, 12,198, 3,255,
- 63,188,166, 29,192,181,120,167, 61,165,224, 4, 31,175,132, 3, 2, 53, 3,255, 63, 9,186, 26,192,186,142,104, 62,126, 74,128,
- 12, 98,128,187, 5,168, 3,255, 63,145,160,228,192,181, 59,121, 63,123,252,246, 24,193,132, 42, 20,214, 3,255,191, 99, 54,226,
-192,174,134,172, 63,250, 98, 96,236, 76,137, 12, 42,242, 3,255,189, 60,195,150,192,177,121, 46, 63,245, 6,174,254,172,135, 7,
- 41,201, 3,255,191, 35, 88,109,192,182,186,129, 63,152, 8,207,241,251,131,129, 26, 54, 3,255, 62,134,114,163,192,183, 94, 81,
-191,157,210, 73, 5,216,131, 16,228,207, 3,255, 63,151,217,253,192,178, 89, 90,191,178,246,210, 25,167,134,110,225, 69, 3,255,
- 63, 19,205,179,192,175,145, 33,191,253,151,102, 12,131,136, 85,212, 89, 3,255,192,101,166,116,192,111,107, 67, 64, 47,233, 69,
-177,233,174, 37, 59,222, 3,255,192, 68, 20,109,192,139, 9,202, 64, 29,255,124,189,118,160,234, 53,250, 3,255,192,106,184,230,
-192,133, 83,117, 63,243, 95, 76,176, 54,165, 5, 41,179, 3,255,192,150,177, 40,192, 73,250,101, 63,189,252,104,152,243,187,143,
- 32,217, 3,255,192,164, 67, 59,192, 19,116,106, 63,209,145, 96,144, 52,205, 33, 36, 1, 3,255,192,148, 31,118,192, 46, 99,144,
- 64, 21,237, 95,154,155,196,115, 50,141, 3,255,192,157, 48,115,191, 33,183, 74, 64, 72,172, 21,148,206,242,150, 68,165, 3,255,
-192,151, 48,250,191,186,157,117, 64, 74, 37,236,152,215,224,130, 68,233, 3,255,192,167, 31,102,191,133,113, 18, 64, 29,150,122,
-142, 42,233,107, 53,251, 3,255,192,174, 1,225,192, 12,167, 65, 62, 38, 1,199,137,107,207,239, 3, 61, 3,255,192,160,156,172,
-192, 66,121, 23, 60, 53,253,220,146,101,189,231, 0, 0, 3,255,192,168, 99, 9,192, 32,173,184,191, 27, 16,129,141, 28,201, 67,
-242, 92, 3,255,191, 19, 18,220, 64, 98,186,168, 64,148,136, 66,243,101, 77,135,101, 15, 3,255,191, 68,220, 36, 64,132,143, 24,
- 64,130,105, 20,239, 93, 90,190, 88,184, 3,255,191,185,255, 60, 64,108,244,215, 64,138, 7,129,224,143, 80,245, 94, 5, 3,255,
-191,247,202, 46, 64, 27,140, 23, 64,158,252,116,214, 39, 52,179,108,224, 3,255,191,220, 24,190, 63,202,163,163, 64,171,244,160,
-218,157, 35, 57,117, 60, 3,255,191,133,219,227, 64, 17, 47,172, 64,169,160, 93,232,130, 49, 92,115,188, 3,255, 62, 50, 45,123,
- 62,230, 16,213, 64,186,240,160, 4, 25, 9,132,127,147, 3,255, 59,172,119,131, 63,162,209,182, 64,183, 73,170, 0, 47, 27,112,
-125, 5, 3,255,191, 40,230,165, 63, 24,111,246, 64,185,150, 50,241,237, 12,238,126,143, 3,255,192, 66,225,100, 63,131,191,146,
- 64,157, 18,152,189, 78, 22,128,106,231, 3,255,192, 80,140, 98, 63,238,205,169, 64,144, 69, 83,184,186, 40,111, 98, 83, 3,255,
-192,109, 39,177, 63,147,213,154, 64,140,143,239,174,199, 25, 9, 95,179, 3,255, 64,128,173,131, 64, 14,170, 50, 64,105, 71,247,
- 87,226, 48,192, 79, 67, 3,255, 64,140,137,202, 64, 33,234, 4, 64, 60,117,152, 96, 41, 55, 40, 63,250, 3,255, 64,115,176, 68,
- 64, 68, 49, 85, 64, 79,173, 65, 83, 78, 66,175, 70,175, 3,255, 64, 39, 23, 51, 64, 76,245, 14, 64,132,248,105, 56,227, 69,119,
- 91, 56, 3,255, 63,254, 75,122, 64, 50, 36, 17, 64,152, 70, 83, 44, 3, 60,210,103,169, 3,255, 64, 52,239,190, 64, 22,186,193,
- 64,145,240,166, 61, 89, 51,253, 99,148, 3,255, 63,213,244,249, 63, 52, 33, 10, 64,178, 94,248, 36, 84, 14,253,121,208, 3,255,
- 64, 22, 80,230, 63,141,155, 50, 64,168, 95,108, 50,253, 23,250,114,237, 3,255, 63,194,113, 96, 63,195,184,166, 64,174,160, 31,
- 33, 51, 33, 11,119, 29, 3,255, 63,112,119,228, 64,115, 46, 49, 64,139,222,186, 20,104, 83, 35, 95, 40, 3,255, 63,199, 22,221,
- 64,134,211, 71, 64,113,161, 37, 33,158, 92, 1, 82, 99, 3,255, 63, 58,131,170, 64,140,178, 58, 64,115,174,213, 15,151, 96, 55,
- 82,245, 3,255, 64,132,134,116,192, 40,130, 40, 64, 77,207,237, 90,117,198,107, 69,226, 3,255, 64,140,187,232,192, 62, 96, 6,
- 64, 30,247,107, 95,249,190,188, 53,245, 3,255, 64,152, 61, 37,192, 14, 9,230, 64, 39,179,137,103,171,207, 73, 57, 30, 3,255,
- 64,149,121,189,191,111,192,142, 64, 90, 95, 76,101,161,235,149, 75, 20, 3,255, 64,134,112,254,190,207,146,126, 64,130, 19,159,
- 91,241,246,137, 88,139, 3,255, 64,129,129, 12,191,173,129,231, 64,128,125,159, 88,194,226,241, 87,133, 3,255, 64, 22,104,220,
-191, 40,221,204, 64,170,137,115, 50,240,241,167,116,139, 3,255, 64, 56,120,245,191,154,213,118, 64,158,227, 81, 62,175,229,209,
-108,123, 3,255, 64, 66, 56, 52,190,139, 40,206, 64,160,116, 21, 65,243,249,237,109,135, 3,255, 64,150,161, 61, 63, 89,221,107,
- 64, 89,113,118,102,216, 18,177, 73,221, 3,255, 64,165,120, 74, 62,167, 78, 95, 64, 48, 51,139,112,202, 7,116, 60, 12, 3,255,
- 64,162, 65, 12, 63,149, 84, 11, 64, 44,202,172,110,196, 25,209, 58,181, 3,255,190,194,138, 67,192,138, 97,177, 64,124,158, 75,
-247,144,161,122, 85,227, 3,255,191, 66, 82,214,192,152,115,128, 64, 85, 25,164,239, 15,151,229, 72,130, 3,255, 61,171,155,119,
-192,155, 40,138, 64, 83, 96,113, 1,128,150, 60, 72, 18, 3,255, 63,178,237,144,192,136,136, 25, 64,113, 1,121, 30,139,163, 67,
- 82,194, 3,255, 63,238,147, 68,192,100,230,166, 64,136, 9,234, 40, 40,177,126, 92,197, 3,255, 63,109,149, 30,192,111, 18, 40,
- 64,141,100,171, 20,219,174, 55, 96, 57, 3,255, 63,162,210, 45,191,224,211,233, 64,174, 67,184, 27,187,218, 11,119, 12, 3,255,
- 63, 94,106,158,192, 30,106,167, 64,167,240,254, 19, 27,202, 69,114,151, 3,255, 63,229,114, 22,192, 20, 96,193, 64,162,167,253,
- 38,234,205,163,111, 12, 3,255, 64, 67, 76,208,192,111,120, 62, 64, 85, 89, 14, 66,176,174, 60, 72,116, 3,255, 64, 37,220,139,
-192,141,135,245, 64, 54,173,114, 56,211,159,161, 62, 45, 3,255, 64, 84,119,204,192,130, 73, 93, 64, 38,107,212, 72,198,167, 33,
- 56,119, 3,255,192, 82,218,178,191, 1,247,178, 64,154,129,211,183,221,244,252,105, 39, 3,255,192,124,245, 0,190,187, 32, 27,
- 64,138, 6, 57,169,118,248, 80, 93,254, 3,255,192,112, 75, 42,191,152, 42,228, 64,139, 44, 25,174, 0,230, 97, 94,225, 3,255,
-192, 43,222,239,192, 11,226,212, 64,151, 71,227,197,223,208,116,103,165, 3,255,191,229,207,137,192, 22, 63, 30, 64,161,235,207,
-216, 58,205, 29,110,129, 3,255,192, 14, 11,239,191,191,114,175, 64,166,208,254,207,123,222,175,113,169, 3,255,189,149, 78,163,
-191,137, 25, 65, 64,184,102,234,254,202,232,204,125,222, 3,255,191,104,203,208,191,113, 6,146, 64,183, 5,108,236,124,235,106,
-124,207, 3,255,190,251, 68, 26,191,228, 38,111, 64,178, 48,114,245,117,217, 98,121,147, 3,255,191,222,169, 76,192,104,107,205,
- 64,136,142,150,217,233,176,151, 92,223, 3,255,192, 39,143,145,192, 94, 49,190, 64,124, 27,165,199, 18,180, 4, 85,213, 3,255,
-192, 6,168,130,192,130,132,190, 64,105, 96, 12,210, 30,166,165, 79, 83, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,246,128,
- 0, 0, 0,242, 0, 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, 8,107,176, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 90, 0, 8,107,176, 32, 0, 0, 0, 53, 0, 0, 7,128,
- 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0,163,
- 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0, 43,
- 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0,165, 0, 0, 0, 35, 0, 0, 0, 43, 0, 0, 0,165, 0, 0, 0, 35,
- 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 0,167,
- 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 0,167, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0, 45,
- 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 0,169, 0, 0, 0, 35,
- 0, 0, 0, 1, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0, 46, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 0,171,
- 0, 0, 0, 35, 0, 0, 0, 46, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0, 47,
- 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0, 47, 0, 0, 0,173, 0, 0, 0, 35,
- 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 0,175,
- 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0, 49,
- 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 0,177, 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 0,177, 0, 0, 0, 35,
- 0, 0, 0, 1, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0, 50, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0,179,
- 0, 0, 0, 35, 0, 0, 0, 50, 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0, 51,
- 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 0,181, 0, 0, 0, 35,
- 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0, 17, 0, 0, 0,183,
- 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 0,183, 0, 0, 0, 35, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0, 53,
- 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0, 17, 0, 0, 0,185, 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 0,185, 0, 0, 0, 35,
- 0, 0, 0, 2, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0, 54, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 0,187,
- 0, 0, 0, 35, 0, 0, 0, 54, 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 0, 3, 0, 0, 0,188, 0, 0, 0, 35, 0, 0, 0, 55,
- 0, 0, 0,188, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 0,189, 0, 0, 0, 35, 0, 0, 0, 55, 0, 0, 0,189, 0, 0, 0, 35,
- 0, 0, 0, 0, 0, 0, 0,190, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0,190, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 0,191,
- 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0,191, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 0, 57,
- 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 0,193, 0, 0, 0, 35, 0, 0, 0, 57, 0, 0, 0,193, 0, 0, 0, 35,
- 0, 0, 0, 3, 0, 0, 0,194, 0, 0, 0, 35, 0, 0, 0, 58, 0, 0, 0,194, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0,195,
- 0, 0, 0, 35, 0, 0, 0, 58, 0, 0, 0,195, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0,196, 0, 0, 0, 35, 0, 0, 0, 59,
- 0, 0, 0,196, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0,197, 0, 0, 0, 35, 0, 0, 0, 59, 0, 0, 0,197, 0, 0, 0, 35,
- 0, 0, 0, 4, 0, 0, 0,198, 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 0,198, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0,199,
- 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 0,199, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0,200, 0, 0, 0, 35, 0, 0, 0, 61,
- 0, 0, 0,200, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0,201, 0, 0, 0, 35, 0, 0, 0, 61, 0, 0, 0,201, 0, 0, 0, 35,
- 0, 0, 0, 5, 0, 0, 0,202, 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 0,202, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 0,203,
- 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 0,203, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 0,204, 0, 0, 0, 35, 0, 0, 0, 63,
- 0, 0, 0,204, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 0,205, 0, 0, 0, 35, 0, 0, 0, 63, 0, 0, 0,205, 0, 0, 0, 35,
- 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0,206, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 0,207,
- 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0,207, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 0,208, 0, 0, 0, 35, 0, 0, 0, 65,
- 0, 0, 0,208, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 0,209, 0, 0, 0, 35, 0, 0, 0, 65, 0, 0, 0,209, 0, 0, 0, 35,
- 0, 0, 0, 1, 0, 0, 0,210, 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 0,210, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0,211,
- 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 0,211, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0, 67,
- 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0,213, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,213, 0, 0, 0, 35,
- 0, 0, 0, 2, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 0,215,
- 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 0,215, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0,216, 0, 0, 0, 35, 0, 0, 0, 69,
- 0, 0, 0,216, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 0,217, 0, 0, 0, 35, 0, 0, 0, 69, 0, 0, 0,217, 0, 0, 0, 35,
- 0, 0, 0, 2, 0, 0, 0,218, 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 0,218, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 0,219,
- 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 0,219, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0,220, 0, 0, 0, 35, 0, 0, 0, 71,
- 0, 0, 0,220, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 0,221, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 0,221, 0, 0, 0, 35,
- 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 0,223,
- 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0,223, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0,224, 0, 0, 0, 35, 0, 0, 0, 73,
- 0, 0, 0,224, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 0,225, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 0,225, 0, 0, 0, 35,
- 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 0,226, 0, 0, 0, 35, 0, 0, 0, 28, 0, 0, 0,227,
- 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 0,227, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0,228, 0, 0, 0, 35, 0, 0, 0, 75,
- 0, 0, 0,228, 0, 0, 0, 35, 0, 0, 0, 28, 0, 0, 0,229, 0, 0, 0, 35, 0, 0, 0, 75, 0, 0, 0,229, 0, 0, 0, 35,
- 0, 0, 0, 4, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 0, 76, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0,231,
- 0, 0, 0, 35, 0, 0, 0, 76, 0, 0, 0,231, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0,232, 0, 0, 0, 35, 0, 0, 0, 77,
- 0, 0, 0,232, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0,233, 0, 0, 0, 35, 0, 0, 0, 77, 0, 0, 0,233, 0, 0, 0, 35,
- 0, 0, 0, 4, 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0, 78, 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 0,235,
- 0, 0, 0, 35, 0, 0, 0, 78, 0, 0, 0,235, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0,236, 0, 0, 0, 35, 0, 0, 0, 79,
- 0, 0, 0,236, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 0,237, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 0,237, 0, 0, 0, 35,
- 0, 0, 0, 5, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 0,239,
- 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0,239, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0,240, 0, 0, 0, 35, 0, 0, 0, 81,
- 0, 0, 0,240, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 0,241, 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 0,241, 0, 0, 0, 35,
- 0, 0, 0, 6, 0, 0, 0,242, 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 0,242, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0,243,
- 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 0,243, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 0,244, 0, 0, 0, 35, 0, 0, 0, 83,
- 0, 0, 0,244, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0,245, 0, 0, 0, 35, 0, 0, 0, 83, 0, 0, 0,245, 0, 0, 0, 35,
- 0, 0, 0, 6, 0, 0, 0,246, 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 0,246, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0,247,
- 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 0,247, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0,248, 0, 0, 0, 35, 0, 0, 0, 85,
- 0, 0, 0,248, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0,249, 0, 0, 0, 35, 0, 0, 0, 85, 0, 0, 0,249, 0, 0, 0, 35,
- 0, 0, 0, 7, 0, 0, 0,250, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 0,250, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0,251,
- 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 0,251, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 0, 87,
- 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0,253, 0, 0, 0, 35, 0, 0, 0, 87, 0, 0, 0,253, 0, 0, 0, 35,
- 0, 0, 0, 8, 0, 0, 0,254, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 0,254, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,255,
- 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 0,255, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 0, 89,
- 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 0, 35, 0, 0, 0, 89, 0, 0, 1, 1, 0, 0, 0, 35,
- 0, 0, 0, 9, 0, 0, 1, 2, 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 1, 2, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 1, 3,
- 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 1, 3, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 1, 4, 0, 0, 0, 35, 0, 0, 0, 91,
- 0, 0, 1, 4, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 1, 5, 0, 0, 0, 35, 0, 0, 0, 91, 0, 0, 1, 5, 0, 0, 0, 35,
- 0, 0, 0, 10, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1, 7,
- 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 1, 7, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 1, 8, 0, 0, 0, 35, 0, 0, 0, 93,
- 0, 0, 1, 8, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1, 9, 0, 0, 0, 35, 0, 0, 0, 93, 0, 0, 1, 9, 0, 0, 0, 35,
- 0, 0, 0, 6, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 0, 94, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 1, 11,
- 0, 0, 0, 35, 0, 0, 0, 94, 0, 0, 1, 11, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 1, 12, 0, 0, 0, 35, 0, 0, 0, 95,
- 0, 0, 1, 12, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 1, 13, 0, 0, 0, 35, 0, 0, 0, 95, 0, 0, 1, 13, 0, 0, 0, 35,
- 0, 0, 0, 7, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1, 15,
- 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 1, 15, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 1, 16, 0, 0, 0, 35, 0, 0, 0, 97,
- 0, 0, 1, 16, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1, 17, 0, 0, 0, 35, 0, 0, 0, 97, 0, 0, 1, 17, 0, 0, 0, 35,
- 0, 0, 0, 8, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 1, 19,
- 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 1, 19, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 1, 20, 0, 0, 0, 35, 0, 0, 0, 99,
- 0, 0, 1, 20, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 1, 21, 0, 0, 0, 35, 0, 0, 0, 99, 0, 0, 1, 21, 0, 0, 0, 35,
- 0, 0, 0, 9, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1, 23,
- 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 1, 23, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 0,101,
- 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1, 25, 0, 0, 0, 35, 0, 0, 0,101, 0, 0, 1, 25, 0, 0, 0, 35,
- 0, 0, 0, 12, 0, 0, 1, 26, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1, 26, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 1, 27,
- 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1, 27, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 0,103,
- 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 1, 29, 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 1, 29, 0, 0, 0, 35,
- 0, 0, 0, 13, 0, 0, 1, 30, 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1, 30, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 1, 31,
- 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1, 31, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 1, 32, 0, 0, 0, 35, 0, 0, 0,105,
- 0, 0, 1, 32, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 1, 33, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 1, 33, 0, 0, 0, 35,
- 0, 0, 0, 12, 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 1, 35,
- 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 1, 35, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 0,107,
- 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 0,107, 0, 0, 1, 37, 0, 0, 0, 35,
- 0, 0, 0, 13, 0, 0, 1, 38, 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1, 38, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 1, 39,
- 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1, 39, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 0,109,
- 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 0, 17, 0, 0, 1, 41, 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 1, 41, 0, 0, 0, 35,
- 0, 0, 0, 17, 0, 0, 1, 42, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1, 42, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 1, 43,
- 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1, 43, 0, 0, 0, 35, 0, 0, 0, 17, 0, 0, 1, 44, 0, 0, 0, 35, 0, 0, 0,111,
- 0, 0, 1, 44, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 1, 45, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 1, 45, 0, 0, 0, 35,
- 0, 0, 0, 17, 0, 0, 1, 46, 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 1, 46, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 1, 47,
- 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 1, 47, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 1, 48, 0, 0, 0, 35, 0, 0, 0,113,
- 0, 0, 1, 48, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 1, 49, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 1, 49, 0, 0, 0, 35,
- 0, 0, 0, 19, 0, 0, 1, 50, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 1, 50, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 1, 51,
- 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 1, 51, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 1, 52, 0, 0, 0, 35, 0, 0, 0,115,
- 0, 0, 1, 52, 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 1, 53, 0, 0, 0, 35, 0, 0, 0,115, 0, 0, 1, 53, 0, 0, 0, 35,
- 0, 0, 0, 15, 0, 0, 1, 54, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1, 54, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 1, 55,
- 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1, 55, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 1, 56, 0, 0, 0, 35, 0, 0, 0,117,
- 0, 0, 1, 56, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 1, 57, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 1, 57, 0, 0, 0, 35,
- 0, 0, 0, 16, 0, 0, 1, 58, 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 1, 58, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 1, 59,
- 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 1, 59, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 1, 60, 0, 0, 0, 35, 0, 0, 0,119,
- 0, 0, 1, 60, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 1, 61, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 1, 61, 0, 0, 0, 35,
- 0, 0, 0, 14, 0, 0, 1, 62, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 1, 62, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 1, 63,
- 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 1, 63, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 1, 64, 0, 0, 0, 35, 0, 0, 0,121,
- 0, 0, 1, 64, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 1, 65, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 1, 65, 0, 0, 0, 35,
- 0, 0, 0, 24, 0, 0, 1, 66, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1, 66, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 1, 67,
- 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1, 67, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 1, 68, 0, 0, 0, 35, 0, 0, 0,123,
- 0, 0, 1, 68, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 1, 69, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 1, 69, 0, 0, 0, 35,
- 0, 0, 0, 18, 0, 0, 1, 70, 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 1, 70, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 1, 71,
- 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 1, 71, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 0,125,
- 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 1, 73, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 1, 73, 0, 0, 0, 35,
- 0, 0, 0, 20, 0, 0, 1, 74, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 1, 74, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 1, 75,
- 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 1, 75, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 0,127,
- 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 0, 28, 0, 0, 1, 77, 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 1, 77, 0, 0, 0, 35,
- 0, 0, 0, 28, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 1, 79,
- 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1, 79, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 1, 80, 0, 0, 0, 35, 0, 0, 0,129,
- 0, 0, 1, 80, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 1, 81, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 1, 81, 0, 0, 0, 35,
- 0, 0, 0, 21, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 1, 83,
- 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 1, 83, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 0,131,
- 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 1, 85, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 1, 85, 0, 0, 0, 35,
- 0, 0, 0, 23, 0, 0, 1, 86, 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 1, 86, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 1, 87,
- 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 1, 87, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 0,133,
- 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 1, 89, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 1, 89, 0, 0, 0, 35,
- 0, 0, 0, 24, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 1, 91,
- 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 1, 91, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 1, 92, 0, 0, 0, 35, 0, 0, 0,135,
- 0, 0, 1, 92, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 1, 93, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 1, 93, 0, 0, 0, 35,
- 0, 0, 0, 25, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 1, 95,
- 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 1, 95, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 0,137,
- 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 1, 97, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 1, 97, 0, 0, 0, 35,
- 0, 0, 0, 27, 0, 0, 1, 98, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 1, 98, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 1, 99,
- 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 1, 99, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 0,139,
- 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 0, 28, 0, 0, 1,101, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 1,101, 0, 0, 0, 35,
- 0, 0, 0, 28, 0, 0, 1,102, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 1,102, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 1,103,
- 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 1,103, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 0,141,
- 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 1,105, 0, 0, 0, 35,
- 0, 0, 0, 29, 0, 0, 1,106, 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 1,106, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 1,107,
- 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 1,107, 0, 0, 0, 35, 0, 0, 0, 30, 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 0,143,
- 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 1,109, 0, 0, 0, 35,
- 0, 0, 0, 31, 0, 0, 1,110, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 1,110, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 1,111,
- 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 1,111, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 0,145,
- 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 1,113, 0, 0, 0, 35, 0, 0, 0,145, 0, 0, 1,113, 0, 0, 0, 35,
- 0, 0, 0, 22, 0, 0, 1,114, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 1,114, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 1,115,
- 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 1,115, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 0,147,
- 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 1,117, 0, 0, 0, 35, 0, 0, 0,147, 0, 0, 1,117, 0, 0, 0, 35,
- 0, 0, 0, 32, 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 0,148, 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1,119,
- 0, 0, 0, 35, 0, 0, 0,148, 0, 0, 1,119, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1,120, 0, 0, 0, 35, 0, 0, 0,149,
- 0, 0, 1,120, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 1,121, 0, 0, 0, 35,
- 0, 0, 0, 33, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1,123,
- 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 0,151,
- 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 1,125, 0, 0, 0, 35, 0, 0, 0,151, 0, 0, 1,125, 0, 0, 0, 35,
- 0, 0, 0, 38, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1,127,
- 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 0,153,
- 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 1,129, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 1,129, 0, 0, 0, 35,
- 0, 0, 0, 34, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1,131,
- 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 1,131, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 1,132, 0, 0, 0, 35, 0, 0, 0,155,
- 0, 0, 1,132, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 1,133, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 1,133, 0, 0, 0, 35,
- 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1,135,
- 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 1,135, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 0,157,
- 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 1,137, 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 1,137, 0, 0, 0, 35,
- 0, 0, 0, 40, 0, 0, 1,138, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 1,138, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1,139,
- 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 1,139, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 1,140, 0, 0, 0, 35, 0, 0, 0,159,
- 0, 0, 1,140, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1,141, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 1,141, 0, 0, 0, 35,
- 0, 0, 0, 36, 0, 0, 1,142, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 1,142, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1,143,
- 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 1,143, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 0,161,
- 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 1,145, 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 1,145, 0, 0, 0, 35,
- 0, 0, 0, 46, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 0, 43, 0, 0, 1,147,
- 0, 0, 0, 33, 0, 0, 0, 46, 0, 0, 1,147, 0, 0, 0, 33, 0, 0, 0, 43, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,102,
- 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 1,149, 0, 0, 0, 35,
- 0, 0, 0,103, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1,151,
- 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 1,152, 0, 0, 0, 33, 0, 0, 0, 47,
- 0, 0, 1,152, 0, 0, 0, 33, 0, 0, 0, 47, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1,153, 0, 0, 0, 35,
- 0, 0, 0, 45, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 1,155,
- 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 0,103,
- 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 1,157, 0, 0, 0, 33, 0, 0, 0, 44, 0, 0, 1,157, 0, 0, 0, 33,
- 0, 0, 0, 50, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 0, 43, 0, 0, 1,159,
- 0, 0, 0, 33, 0, 0, 0, 50, 0, 0, 1,159, 0, 0, 0, 33, 0, 0, 0, 43, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,105,
- 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 1,161, 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 1,161, 0, 0, 0, 35,
- 0, 0, 0,106, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 0,107, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 1,163,
- 0, 0, 0, 35, 0, 0, 0,107, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 1,164, 0, 0, 0, 33, 0, 0, 0, 51,
- 0, 0, 1,164, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 0,107, 0, 0, 1,165, 0, 0, 0, 35,
- 0, 0, 0, 49, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 0,107, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 1,167,
- 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 0,106,
- 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 0, 42, 0, 0, 1,169, 0, 0, 0, 33, 0, 0, 0, 48, 0, 0, 1,169, 0, 0, 0, 33,
- 0, 0, 0, 54, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 1,171,
- 0, 0, 0, 33, 0, 0, 0, 54, 0, 0, 1,171, 0, 0, 0, 33, 0, 0, 0, 45, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,108,
- 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 1,173, 0, 0, 0, 35,
- 0, 0, 0,109, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1,175,
- 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 1,176, 0, 0, 0, 33, 0, 0, 0, 55,
- 0, 0, 1,176, 0, 0, 0, 33, 0, 0, 0, 55, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1,177, 0, 0, 0, 35,
- 0, 0, 0, 53, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 1,179,
- 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 0,109,
- 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 1,181, 0, 0, 0, 33, 0, 0, 0, 52, 0, 0, 1,181, 0, 0, 0, 33,
- 0, 0, 0, 58, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 1,183,
- 0, 0, 0, 33, 0, 0, 0, 58, 0, 0, 1,183, 0, 0, 0, 33, 0, 0, 0, 53, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,111,
- 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 1,185, 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 1,185, 0, 0, 0, 35,
- 0, 0, 0,112, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 1,187,
- 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 0, 57, 0, 0, 1,188, 0, 0, 0, 33, 0, 0, 0, 59,
- 0, 0, 1,188, 0, 0, 0, 33, 0, 0, 0, 59, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 1,189, 0, 0, 0, 35,
- 0, 0, 0, 57, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 1,191,
- 0, 0, 0, 35, 0, 0, 0,112, 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 0,112,
- 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 1,193, 0, 0, 0, 33, 0, 0, 0, 56, 0, 0, 1,193, 0, 0, 0, 33,
- 0, 0, 0, 60, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 0, 57, 0, 0, 1,195,
- 0, 0, 0, 33, 0, 0, 0, 60, 0, 0, 1,195, 0, 0, 0, 33, 0, 0, 0, 57, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,114,
- 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 1,197, 0, 0, 0, 35, 0, 0, 0,115, 0, 0, 1,197, 0, 0, 0, 35,
- 0, 0, 0,115, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 1,199,
- 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 1,200, 0, 0, 0, 33, 0, 0, 0, 61,
- 0, 0, 1,200, 0, 0, 0, 33, 0, 0, 0, 61, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1,201, 0, 0, 0, 35,
- 0, 0, 0, 49, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 1,203,
- 0, 0, 0, 35, 0, 0, 0,115, 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 0,115,
- 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 1,205, 0, 0, 0, 33, 0, 0, 0, 56, 0, 0, 1,205, 0, 0, 0, 33,
- 0, 0, 0, 64, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 0, 50, 0, 0, 1,207,
- 0, 0, 0, 33, 0, 0, 0, 64, 0, 0, 1,207, 0, 0, 0, 33, 0, 0, 0, 50, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,117,
- 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 1,209, 0, 0, 0, 35,
- 0, 0, 0,118, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 1,211,
- 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 0, 63, 0, 0, 1,212, 0, 0, 0, 33, 0, 0, 0, 65,
- 0, 0, 1,212, 0, 0, 0, 33, 0, 0, 0, 65, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 1,213, 0, 0, 0, 35,
- 0, 0, 0, 63, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 1,215,
- 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 1,215, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 0,118,
- 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 1,217, 0, 0, 0, 33, 0, 0, 0, 62, 0, 0, 1,217, 0, 0, 0, 33,
- 0, 0, 0, 68, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 0, 47, 0, 0, 1,219,
- 0, 0, 0, 33, 0, 0, 0, 68, 0, 0, 1,219, 0, 0, 0, 33, 0, 0, 0, 47, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,120,
- 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 1,221, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 1,221, 0, 0, 0, 35,
- 0, 0, 0,121, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 1,223,
- 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 1,224, 0, 0, 0, 33, 0, 0, 0, 69,
- 0, 0, 1,224, 0, 0, 0, 33, 0, 0, 0, 69, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1,225, 0, 0, 0, 35,
- 0, 0, 0, 67, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 1,227,
- 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 0, 46, 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 0,121,
- 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 0, 46, 0, 0, 1,229, 0, 0, 0, 33, 0, 0, 0, 66, 0, 0, 1,229, 0, 0, 0, 33,
- 0, 0, 0, 72, 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 0, 55, 0, 0, 1,231,
- 0, 0, 0, 33, 0, 0, 0, 72, 0, 0, 1,231, 0, 0, 0, 33, 0, 0, 0, 55, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,123,
- 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 1,233, 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 1,233, 0, 0, 0, 35,
- 0, 0, 0,124, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 1,235,
- 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 1,236, 0, 0, 0, 33, 0, 0, 0, 73,
- 0, 0, 1,236, 0, 0, 0, 33, 0, 0, 0, 73, 0, 0, 1,237, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 1,237, 0, 0, 0, 35,
- 0, 0, 0, 71, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 1,239,
- 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 0, 54, 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 0,124,
- 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 0, 54, 0, 0, 1,241, 0, 0, 0, 33, 0, 0, 0, 70, 0, 0, 1,241, 0, 0, 0, 33,
- 0, 0, 0, 76, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 0, 59, 0, 0, 1,243,
- 0, 0, 0, 33, 0, 0, 0, 76, 0, 0, 1,243, 0, 0, 0, 33, 0, 0, 0, 59, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,126,
- 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 1,245, 0, 0, 0, 35,
- 0, 0, 0,127, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 1,247,
- 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 0, 75, 0, 0, 1,248, 0, 0, 0, 33, 0, 0, 0, 77,
- 0, 0, 1,248, 0, 0, 0, 33, 0, 0, 0, 77, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1,249, 0, 0, 0, 35,
- 0, 0, 0, 75, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 1,251,
- 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 1,251, 0, 0, 0, 35, 0, 0, 0, 58, 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 0,127,
- 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 0, 58, 0, 0, 1,253, 0, 0, 0, 33, 0, 0, 0, 74, 0, 0, 1,253, 0, 0, 0, 33,
- 0, 0, 0, 80, 0, 0, 1,254, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 1,254, 0, 0, 0, 35, 0, 0, 0, 61, 0, 0, 1,255,
- 0, 0, 0, 33, 0, 0, 0, 80, 0, 0, 1,255, 0, 0, 0, 33, 0, 0, 0, 61, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,129,
- 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 2, 1, 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 2, 1, 0, 0, 0, 35,
- 0, 0, 0,130, 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 2, 3,
- 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 2, 4, 0, 0, 0, 33, 0, 0, 0, 81,
- 0, 0, 2, 4, 0, 0, 0, 33, 0, 0, 0, 81, 0, 0, 2, 5, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 2, 5, 0, 0, 0, 35,
- 0, 0, 0, 79, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 0, 78, 0, 0, 2, 7,
- 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 2, 7, 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 0,130,
- 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 2, 9, 0, 0, 0, 33, 0, 0, 0, 78, 0, 0, 2, 9, 0, 0, 0, 33,
- 0, 0, 0, 83, 0, 0, 2, 10, 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 2, 10, 0, 0, 0, 35, 0, 0, 0, 65, 0, 0, 2, 11,
- 0, 0, 0, 33, 0, 0, 0, 83, 0, 0, 2, 11, 0, 0, 0, 33, 0, 0, 0, 65, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,132,
- 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 2, 13, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 2, 13, 0, 0, 0, 35,
- 0, 0, 0,133, 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 2, 15,
- 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 2, 16, 0, 0, 0, 33, 0, 0, 0, 82,
- 0, 0, 2, 16, 0, 0, 0, 33, 0, 0, 0, 82, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 2, 17, 0, 0, 0, 35,
- 0, 0, 0, 67, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 2, 19,
- 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 2, 19, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 0,133,
- 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 2, 21, 0, 0, 0, 33, 0, 0, 0, 66, 0, 0, 2, 21, 0, 0, 0, 33,
- 0, 0, 0, 84, 0, 0, 2, 22, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 2, 22, 0, 0, 0, 35, 0, 0, 0, 69, 0, 0, 2, 23,
- 0, 0, 0, 33, 0, 0, 0, 84, 0, 0, 2, 23, 0, 0, 0, 33, 0, 0, 0, 69, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,135,
- 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 2, 25, 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 2, 25, 0, 0, 0, 35,
- 0, 0, 0,136, 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 2, 27,
- 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 2, 28, 0, 0, 0, 33, 0, 0, 0, 85,
- 0, 0, 2, 28, 0, 0, 0, 33, 0, 0, 0, 85, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 2, 29, 0, 0, 0, 35,
- 0, 0, 0, 71, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 2, 31,
- 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 2, 31, 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 0,136,
- 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 2, 33, 0, 0, 0, 33, 0, 0, 0, 70, 0, 0, 2, 33, 0, 0, 0, 33,
- 0, 0, 0, 86, 0, 0, 2, 34, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 2, 34, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 2, 35,
- 0, 0, 0, 33, 0, 0, 0, 86, 0, 0, 2, 35, 0, 0, 0, 33, 0, 0, 0, 73, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,138,
- 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 2, 37, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 2, 37, 0, 0, 0, 35,
- 0, 0, 0,139, 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 2, 39,
- 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 0, 75, 0, 0, 2, 40, 0, 0, 0, 33, 0, 0, 0, 87,
- 0, 0, 2, 40, 0, 0, 0, 33, 0, 0, 0, 87, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 2, 41, 0, 0, 0, 35,
- 0, 0, 0, 75, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 2, 43,
- 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 2, 43, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 0,139,
- 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 2, 45, 0, 0, 0, 33, 0, 0, 0, 74, 0, 0, 2, 45, 0, 0, 0, 33,
- 0, 0, 0, 88, 0, 0, 2, 46, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 2, 46, 0, 0, 0, 35, 0, 0, 0, 77, 0, 0, 2, 47,
- 0, 0, 0, 33, 0, 0, 0, 88, 0, 0, 2, 47, 0, 0, 0, 33, 0, 0, 0, 77, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,141,
- 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 2, 49, 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 2, 49, 0, 0, 0, 35,
- 0, 0, 0,142, 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 2, 51,
- 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 2, 52, 0, 0, 0, 33, 0, 0, 0, 89,
- 0, 0, 2, 52, 0, 0, 0, 33, 0, 0, 0, 89, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 2, 53, 0, 0, 0, 35,
- 0, 0, 0, 79, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 0, 78, 0, 0, 2, 55,
- 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 2, 55, 0, 0, 0, 35, 0, 0, 0, 76, 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 0,142,
- 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 0, 76, 0, 0, 2, 57, 0, 0, 0, 33, 0, 0, 0, 78, 0, 0, 2, 57, 0, 0, 0, 33,
- 0, 0, 0, 90, 0, 0, 2, 58, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 2, 58, 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 2, 59,
- 0, 0, 0, 33, 0, 0, 0, 90, 0, 0, 2, 59, 0, 0, 0, 33, 0, 0, 0, 81, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,144,
- 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 2, 61, 0, 0, 0, 35, 0, 0, 0,145, 0, 0, 2, 61, 0, 0, 0, 35,
- 0, 0, 0,145, 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 2, 63,
- 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 0, 63, 0, 0, 2, 64, 0, 0, 0, 33, 0, 0, 0, 91,
- 0, 0, 2, 64, 0, 0, 0, 33, 0, 0, 0, 91, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 2, 65, 0, 0, 0, 35,
- 0, 0, 0, 63, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 2, 67,
- 0, 0, 0, 35, 0, 0, 0,145, 0, 0, 2, 67, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 0,145,
- 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 2, 69, 0, 0, 0, 33, 0, 0, 0, 80, 0, 0, 2, 69, 0, 0, 0, 33,
- 0, 0, 0, 94, 0, 0, 2, 70, 0, 0, 0, 35, 0, 0, 0,147, 0, 0, 2, 70, 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 2, 71,
- 0, 0, 0, 33, 0, 0, 0, 94, 0, 0, 2, 71, 0, 0, 0, 33, 0, 0, 0, 82, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,147,
- 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,147, 0, 0, 2, 73, 0, 0, 0, 35, 0, 0, 0,148, 0, 0, 2, 73, 0, 0, 0, 35,
- 0, 0, 0,148, 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 0,147, 0, 0, 2, 75,
- 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 0, 93, 0, 0, 2, 76, 0, 0, 0, 33, 0, 0, 0, 95,
- 0, 0, 2, 76, 0, 0, 0, 33, 0, 0, 0, 95, 0, 0, 2, 77, 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 2, 77, 0, 0, 0, 35,
- 0, 0, 0, 93, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 2, 79,
- 0, 0, 0, 35, 0, 0, 0,148, 0, 0, 2, 79, 0, 0, 0, 35, 0, 0, 0, 83, 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 0,148,
- 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 0, 83, 0, 0, 2, 81, 0, 0, 0, 33, 0, 0, 0, 92, 0, 0, 2, 81, 0, 0, 0, 33,
- 0, 0, 0, 96, 0, 0, 2, 82, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 2, 82, 0, 0, 0, 35, 0, 0, 0, 85, 0, 0, 2, 83,
- 0, 0, 0, 33, 0, 0, 0, 96, 0, 0, 2, 83, 0, 0, 0, 33, 0, 0, 0, 85, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,150,
- 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 2, 85, 0, 0, 0, 35, 0, 0, 0,151, 0, 0, 2, 85, 0, 0, 0, 35,
- 0, 0, 0,151, 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 2, 87,
- 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 0, 95, 0, 0, 2, 88, 0, 0, 0, 33, 0, 0, 0, 97,
- 0, 0, 2, 88, 0, 0, 0, 33, 0, 0, 0, 97, 0, 0, 2, 89, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 2, 89, 0, 0, 0, 35,
- 0, 0, 0, 95, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 0, 94, 0, 0, 2, 91,
- 0, 0, 0, 35, 0, 0, 0,151, 0, 0, 2, 91, 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 0,151,
- 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 2, 93, 0, 0, 0, 33, 0, 0, 0, 94, 0, 0, 2, 93, 0, 0, 0, 33,
- 0, 0, 0, 98, 0, 0, 2, 94, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 2, 94, 0, 0, 0, 35, 0, 0, 0, 87, 0, 0, 2, 95,
- 0, 0, 0, 33, 0, 0, 0, 98, 0, 0, 2, 95, 0, 0, 0, 33, 0, 0, 0, 87, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,153,
- 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 2, 97, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 2, 97, 0, 0, 0, 35,
- 0, 0, 0,154, 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 2, 99,
- 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 0, 97, 0, 0, 2,100, 0, 0, 0, 33, 0, 0, 0, 99,
- 0, 0, 2,100, 0, 0, 0, 33, 0, 0, 0, 99, 0, 0, 2,101, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 2,101, 0, 0, 0, 35,
- 0, 0, 0, 97, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 0,155, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 2,103,
- 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 2,103, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 0,154,
- 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 2,105, 0, 0, 0, 33, 0, 0, 0, 96, 0, 0, 2,105, 0, 0, 0, 33,
- 0, 0, 0,100, 0, 0, 2,106, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 2,106, 0, 0, 0, 35, 0, 0, 0, 89, 0, 0, 2,107,
- 0, 0, 0, 33, 0, 0, 0,100, 0, 0, 2,107, 0, 0, 0, 33, 0, 0, 0, 89, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 0,156,
- 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 2,109, 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 2,109, 0, 0, 0, 35,
- 0, 0, 0,157, 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 0,156, 0, 0, 2,111,
- 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 0, 99, 0, 0, 2,112, 0, 0, 0, 33, 0, 0, 0,101,
- 0, 0, 2,112, 0, 0, 0, 33, 0, 0, 0,101, 0, 0, 2,113, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 2,113, 0, 0, 0, 35,
- 0, 0, 0, 99, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 2,115,
- 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 2,115, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 0,157,
- 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 2,117, 0, 0, 0, 33, 0, 0, 0, 98, 0, 0, 2,117, 0, 0, 0, 33,
- 0, 0, 0, 92, 0, 0, 2,118, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 2,118, 0, 0, 0, 35, 0, 0, 0, 91, 0, 0, 2,119,
- 0, 0, 0, 33, 0, 0, 0, 92, 0, 0, 2,119, 0, 0, 0, 33, 0, 0, 0, 91, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 0,159,
- 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 2,121, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 2,121, 0, 0, 0, 35,
- 0, 0, 0,160, 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 2,123,
- 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 0, 93, 0, 0, 2,124, 0, 0, 0, 33, 0, 0, 0,101,
- 0, 0, 2,124, 0, 0, 0, 33, 0, 0, 0, 93, 0, 0, 2,125, 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 2,125, 0, 0, 0, 35,
- 0, 0, 0,101, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 0,161, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 2,127,
- 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 2,127, 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 0,160,
- 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 2,129, 0, 0, 0, 33, 0, 0, 0,100, 0, 0, 2,129, 0, 0, 0, 33,
- 0, 0, 1, 27, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1, 27,
- 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 1,147,
- 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1, 26, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1,148, 0, 0, 0, 35,
- 0, 0, 1, 26, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,170,
- 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1, 28,
- 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 1,149, 0, 0, 1,150, 0, 0, 0, 35,
- 0, 0, 1,149, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1,150, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 1, 31,
- 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1, 30,
- 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 1, 30, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 1,150, 0, 0, 0, 35,
- 0, 0, 0,168, 0, 0, 1,152, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 1,152, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,172,
- 0, 0, 0, 35, 0, 0, 1,152, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 1,152, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 1,153,
- 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1, 30, 0, 0, 0, 35, 0, 0, 1, 30, 0, 0, 1,154, 0, 0, 0, 35,
- 0, 0, 0,169, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1, 31,
- 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 1, 29,
- 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1, 29, 0, 0, 0, 35, 0, 0, 1,155, 0, 0, 1,156, 0, 0, 0, 35,
- 0, 0, 1,155, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 1,156, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,166,
- 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 0,163,
- 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 1, 28, 0, 0, 1,156, 0, 0, 0, 35,
- 0, 0, 1, 33, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1, 33, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1,158,
- 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 1,159, 0, 0, 0, 35, 0, 0, 1,159, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 1,158,
- 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1, 32, 0, 0, 0, 35, 0, 0, 1, 32, 0, 0, 1,160, 0, 0, 0, 35,
- 0, 0, 0,165, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 1,159, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 1,159,
- 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 1, 32, 0, 0, 1,161, 0, 0, 0, 35, 0, 0, 1, 32,
- 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 1,161, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,162, 0, 0, 0, 35,
- 0, 0, 1,162, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1, 37,
- 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1, 37, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1, 36,
- 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1, 36, 0, 0, 0, 35,
- 0, 0, 0,176, 0, 0, 1,164, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 1,164,
- 0, 0, 0, 35, 0, 0, 1,164, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 1,165, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1,164,
- 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1,166, 0, 0, 0, 35,
- 0, 0, 1, 36, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1, 37, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1,165,
- 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 0,175,
- 0, 0, 1, 35, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 1,168, 0, 0, 0, 35,
- 0, 0, 1,168, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,174,
- 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 0,163,
- 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 1, 34, 0, 0, 0, 35,
- 0, 0, 1, 39, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1, 39,
- 0, 0, 0, 35, 0, 0, 1,170, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1,170, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 1,171,
- 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1, 38, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1,172, 0, 0, 0, 35,
- 0, 0, 1, 38, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,186,
- 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 1, 40,
- 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 1,173, 0, 0, 1,174, 0, 0, 0, 35,
- 0, 0, 1,173, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1,174, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 1, 43,
- 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1, 42,
- 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1, 42, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1,174, 0, 0, 0, 35,
- 0, 0, 0,184, 0, 0, 1,176, 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 1,176, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 0,188,
- 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 1,177,
- 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1, 42, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 1,178, 0, 0, 0, 35,
- 0, 0, 0,185, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1, 43,
- 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 1, 41,
- 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1, 41, 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 1,180, 0, 0, 0, 35,
- 0, 0, 1,179, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 1,180, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,182,
- 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 0,167,
- 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 1, 40, 0, 0, 1,180, 0, 0, 0, 35,
- 0, 0, 1, 45, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1, 45,
- 0, 0, 0, 35, 0, 0, 1,182, 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 1,182, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 1,183,
- 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1, 44, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1,184, 0, 0, 0, 35,
- 0, 0, 1, 44, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 0,194,
- 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1,185, 0, 0, 0, 35, 0, 0, 1, 46,
- 0, 0, 1,185, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1, 46, 0, 0, 0, 35, 0, 0, 1,185, 0, 0, 1,186, 0, 0, 0, 35,
- 0, 0, 1,185, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1,186, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1, 49,
- 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 48,
- 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1, 48, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1,186, 0, 0, 0, 35,
- 0, 0, 0,192, 0, 0, 1,188, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 1,188, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 0,196,
- 0, 0, 0, 35, 0, 0, 1,188, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1,189,
- 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1, 48, 0, 0, 0, 35, 0, 0, 1, 48, 0, 0, 1,190, 0, 0, 0, 35,
- 0, 0, 0,193, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1, 49,
- 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 1, 47,
- 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1, 47, 0, 0, 0, 35, 0, 0, 1,191, 0, 0, 1,192, 0, 0, 0, 35,
- 0, 0, 1,191, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 1,192, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 0,190,
- 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 0,183,
- 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1, 46, 0, 0, 0, 35, 0, 0, 1, 46, 0, 0, 1,192, 0, 0, 0, 35,
- 0, 0, 1, 51, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 1, 51,
- 0, 0, 0, 35, 0, 0, 1,194, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 1,194, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 1,195,
- 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1, 50, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1,196, 0, 0, 0, 35,
- 0, 0, 1, 50, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 0,198,
- 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1,197, 0, 0, 0, 35, 0, 0, 1, 53,
- 0, 0, 1,197, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1, 53, 0, 0, 0, 35, 0, 0, 1,197, 0, 0, 1,198, 0, 0, 0, 35,
- 0, 0, 1,197, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 1, 55,
- 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1, 54,
- 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1, 54, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1,198, 0, 0, 0, 35,
- 0, 0, 0,176, 0, 0, 1,200, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 1,200, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,200,
- 0, 0, 0, 35, 0, 0, 1,200, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1,201,
- 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1, 54, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 1,202, 0, 0, 0, 35,
- 0, 0, 0,177, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1, 55,
- 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 1, 52,
- 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 1, 52, 0, 0, 0, 35, 0, 0, 1,203, 0, 0, 1,204, 0, 0, 0, 35,
- 0, 0, 1,203, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 1,204, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0,190,
- 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 0,191,
- 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1, 53, 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 1,204, 0, 0, 0, 35,
- 0, 0, 1, 57, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1, 57, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1,206,
- 0, 0, 0, 35, 0, 0, 1,206, 0, 0, 1,207, 0, 0, 0, 35, 0, 0, 1,207, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 1,206,
- 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1, 56, 0, 0, 0, 35, 0, 0, 1, 56, 0, 0, 1,208, 0, 0, 0, 35,
- 0, 0, 0,179, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 1,207, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 1,207,
- 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 0,206, 0, 0, 0, 35, 0, 0, 1, 56, 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 1, 56,
- 0, 0, 1, 58, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 1,209, 0, 0, 1,210, 0, 0, 0, 35,
- 0, 0, 1,210, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1, 61,
- 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1, 60,
- 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1, 60, 0, 0, 0, 35,
- 0, 0, 0,204, 0, 0, 1,212, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 0,208, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 1,212,
- 0, 0, 0, 35, 0, 0, 1,212, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 1,213, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1,212,
- 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 1, 60, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 1,214, 0, 0, 0, 35,
- 0, 0, 1, 60, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1,213,
- 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1, 61, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 1,215, 0, 0, 0, 35, 0, 0, 0,203,
- 0, 0, 1, 59, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1,215, 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 1,216, 0, 0, 0, 35,
- 0, 0, 1,216, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 0,202,
- 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 0,181,
- 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1, 58, 0, 0, 0, 35,
- 0, 0, 1, 63, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1, 63, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1,218,
- 0, 0, 0, 35, 0, 0, 1,218, 0, 0, 1,219, 0, 0, 0, 35, 0, 0, 1,219, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 1,218,
- 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1, 62, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1,220, 0, 0, 0, 35,
- 0, 0, 0,173, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 1,219, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 1,219,
- 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1,221, 0, 0, 0, 35, 0, 0, 1, 62,
- 0, 0, 1, 64, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 1,221, 0, 0, 0, 35, 0, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 35,
- 0, 0, 1,222, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1,221, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1, 67,
- 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1, 66,
- 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1, 66, 0, 0, 0, 35,
- 0, 0, 0,212, 0, 0, 1,224, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 0,216, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 1,224,
- 0, 0, 0, 35, 0, 0, 1,224, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 1,225, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1,224,
- 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 1, 66, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 1,226, 0, 0, 0, 35,
- 0, 0, 1, 66, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 1,225,
- 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 1, 67, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 0,211,
- 0, 0, 1, 65, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 1,228, 0, 0, 0, 35,
- 0, 0, 1,228, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 0,210,
- 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 0,171,
- 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1, 64, 0, 0, 0, 35,
- 0, 0, 1, 69, 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 1, 69, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 1,230,
- 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 1,231, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 1,230,
- 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1, 68, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 1,232, 0, 0, 0, 35,
- 0, 0, 0,189, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 1,231,
- 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 1,233, 0, 0, 0, 35, 0, 0, 1, 68,
- 0, 0, 1, 70, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1,233, 0, 0, 0, 35, 0, 0, 1,233, 0, 0, 1,234, 0, 0, 0, 35,
- 0, 0, 1,234, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,233, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1, 73,
- 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1, 72,
- 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1, 72, 0, 0, 0, 35,
- 0, 0, 0,220, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 0,224, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 1,236,
- 0, 0, 0, 35, 0, 0, 1,236, 0, 0, 1,237, 0, 0, 0, 35, 0, 0, 1,237, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1,236,
- 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 1,238, 0, 0, 0, 35,
- 0, 0, 1, 72, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 1,237, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 1,237,
- 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 1, 73, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 0,219,
- 0, 0, 1, 71, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 1,239, 0, 0, 1,240, 0, 0, 0, 35,
- 0, 0, 1,240, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 1,239, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 0,218,
- 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 0,187,
- 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1, 70, 0, 0, 0, 35,
- 0, 0, 1, 75, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1, 75, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1,242,
- 0, 0, 0, 35, 0, 0, 1,242, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 1,243, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 1,242,
- 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1, 74, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 1,244, 0, 0, 0, 35,
- 0, 0, 0,197, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 1,243,
- 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1, 74,
- 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 1, 76, 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1,245, 0, 0, 1,246, 0, 0, 0, 35,
- 0, 0, 1,246, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1,245, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1, 79,
- 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 78,
- 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1, 78, 0, 0, 0, 35,
- 0, 0, 0,228, 0, 0, 1,248, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0,232, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 1,248,
- 0, 0, 0, 35, 0, 0, 1,248, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 1,249, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1,248,
- 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 1,250, 0, 0, 0, 35,
- 0, 0, 1, 78, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1,249,
- 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1, 79, 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 1,251, 0, 0, 0, 35, 0, 0, 0,227,
- 0, 0, 1, 77, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1,251, 0, 0, 0, 35, 0, 0, 1,251, 0, 0, 1,252, 0, 0, 0, 35,
- 0, 0, 1,252, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 1,251, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0,226,
- 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 0,195,
- 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 1, 76, 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1, 76, 0, 0, 0, 35,
- 0, 0, 1, 81, 0, 0, 1,254, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1, 81, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1,254,
- 0, 0, 0, 35, 0, 0, 1,254, 0, 0, 1,255, 0, 0, 0, 35, 0, 0, 1,255, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 1,254,
- 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1, 80, 0, 0, 0, 35, 0, 0, 1, 80, 0, 0, 2, 0, 0, 0, 0, 35,
- 0, 0, 0,201, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 1,255, 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 1,255,
- 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 1, 80, 0, 0, 2, 1, 0, 0, 0, 35, 0, 0, 1, 80,
- 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 2, 1, 0, 0, 0, 35, 0, 0, 2, 1, 0, 0, 2, 2, 0, 0, 0, 35,
- 0, 0, 2, 2, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 1, 85,
- 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 1, 84,
- 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 1, 84, 0, 0, 0, 35,
- 0, 0, 0,236, 0, 0, 2, 4, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 0,240, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 2, 4,
- 0, 0, 0, 35, 0, 0, 2, 4, 0, 0, 2, 5, 0, 0, 0, 35, 0, 0, 2, 5, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 2, 4,
- 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 2, 6, 0, 0, 0, 35,
- 0, 0, 1, 84, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 2, 5, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 2, 5,
- 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 1, 85, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 2, 7, 0, 0, 0, 35, 0, 0, 0,235,
- 0, 0, 1, 83, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 2, 7, 0, 0, 0, 35, 0, 0, 2, 7, 0, 0, 2, 8, 0, 0, 0, 35,
- 0, 0, 2, 8, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 2, 7, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,234,
- 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 0,199,
- 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 1, 82, 0, 0, 0, 35,
- 0, 0, 1, 87, 0, 0, 2, 10, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 2, 10, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 1, 87,
- 0, 0, 0, 35, 0, 0, 2, 10, 0, 0, 2, 11, 0, 0, 0, 35, 0, 0, 2, 10, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 2, 11,
- 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1, 86, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 2, 12, 0, 0, 0, 35,
- 0, 0, 1, 86, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 2, 11, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 0,244,
- 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 2, 11, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 2, 13, 0, 0, 0, 35, 0, 0, 1, 88,
- 0, 0, 2, 13, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 2, 13, 0, 0, 2, 14, 0, 0, 0, 35,
- 0, 0, 2, 13, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 2, 14, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 1, 91,
- 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 1, 90,
- 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 1, 89, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 1, 89, 0, 0, 2, 14, 0, 0, 0, 35,
- 0, 0, 0,212, 0, 0, 2, 16, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 2, 16, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 0,242,
- 0, 0, 0, 35, 0, 0, 2, 16, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 2, 16, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 2, 17,
- 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 1, 90, 0, 0, 2, 18, 0, 0, 0, 35,
- 0, 0, 0,213, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 1, 91,
- 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 2, 19, 0, 0, 0, 35, 0, 0, 1, 89,
- 0, 0, 2, 19, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 1, 89, 0, 0, 0, 35, 0, 0, 2, 19, 0, 0, 2, 20, 0, 0, 0, 35,
- 0, 0, 2, 19, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 2, 20, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0,210,
- 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 0,207,
- 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 1, 88, 0, 0, 2, 20, 0, 0, 0, 35,
- 0, 0, 1, 93, 0, 0, 2, 22, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 2, 22, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 1, 93,
- 0, 0, 0, 35, 0, 0, 2, 22, 0, 0, 2, 23, 0, 0, 0, 35, 0, 0, 2, 22, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 2, 23,
- 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 1, 92, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 2, 24, 0, 0, 0, 35,
- 0, 0, 1, 92, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 2, 23, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 0,246,
- 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 2, 23, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 2, 25, 0, 0, 0, 35, 0, 0, 1, 94,
- 0, 0, 2, 25, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 2, 25, 0, 0, 2, 26, 0, 0, 0, 35,
- 0, 0, 2, 25, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 2, 26, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 1, 97,
- 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 1, 96,
- 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 2, 26, 0, 0, 0, 35,
- 0, 0, 0,220, 0, 0, 2, 28, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 2, 28, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 0,248,
- 0, 0, 0, 35, 0, 0, 2, 28, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 2, 28, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 2, 29,
- 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 1, 96, 0, 0, 2, 30, 0, 0, 0, 35,
- 0, 0, 0,221, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 1, 97,
- 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 2, 31, 0, 0, 0, 35, 0, 0, 1, 95,
- 0, 0, 2, 31, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 1, 95, 0, 0, 0, 35, 0, 0, 2, 31, 0, 0, 2, 32, 0, 0, 0, 35,
- 0, 0, 2, 31, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 2, 32, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 0,218,
- 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 0,215,
- 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 1, 94, 0, 0, 2, 32, 0, 0, 0, 35,
- 0, 0, 1, 99, 0, 0, 2, 34, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 2, 34, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 1, 99,
- 0, 0, 0, 35, 0, 0, 2, 34, 0, 0, 2, 35, 0, 0, 0, 35, 0, 0, 2, 34, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 2, 35,
- 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 1, 98, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 2, 36, 0, 0, 0, 35,
- 0, 0, 1, 98, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 2, 35, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 0,250,
- 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 2, 35, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 2, 37, 0, 0, 0, 35, 0, 0, 1,100,
- 0, 0, 2, 37, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 2, 37, 0, 0, 2, 38, 0, 0, 0, 35,
- 0, 0, 2, 37, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 2, 38, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 1,103,
- 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 1,102,
- 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 1,102, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 2, 38, 0, 0, 0, 35,
- 0, 0, 0,228, 0, 0, 2, 40, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 2, 40, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0,252,
- 0, 0, 0, 35, 0, 0, 2, 40, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 2, 40, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 2, 41,
- 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 1,102, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 2, 42, 0, 0, 0, 35,
- 0, 0, 0,229, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 1,103,
- 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 2, 43, 0, 0, 0, 35, 0, 0, 1,101,
- 0, 0, 2, 43, 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 1,101, 0, 0, 0, 35, 0, 0, 2, 43, 0, 0, 2, 44, 0, 0, 0, 35,
- 0, 0, 2, 43, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 2, 44, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 0,226,
- 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 0,223,
- 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 1,100, 0, 0, 2, 44, 0, 0, 0, 35,
- 0, 0, 1,105, 0, 0, 2, 46, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 2, 46, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 1,105,
- 0, 0, 0, 35, 0, 0, 2, 46, 0, 0, 2, 47, 0, 0, 0, 35, 0, 0, 2, 46, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 2, 47,
- 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 2, 48, 0, 0, 0, 35,
- 0, 0, 1,104, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 2, 47, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 0,254,
- 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 2, 47, 0, 0, 0, 35, 0, 0, 1,104, 0, 0, 2, 49, 0, 0, 0, 35, 0, 0, 1,106,
- 0, 0, 2, 49, 0, 0, 0, 35, 0, 0, 1,104, 0, 0, 1,106, 0, 0, 0, 35, 0, 0, 2, 49, 0, 0, 2, 50, 0, 0, 0, 35,
- 0, 0, 2, 49, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 2, 50, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 1,109,
- 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 1,108,
- 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 1,107, 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 1,107, 0, 0, 2, 50, 0, 0, 0, 35,
- 0, 0, 0,236, 0, 0, 2, 52, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 2, 52, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 1, 0,
- 0, 0, 0, 35, 0, 0, 2, 52, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 2, 52, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 2, 53,
- 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 1,108, 0, 0, 2, 54, 0, 0, 0, 35,
- 0, 0, 0,237, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 1,109,
- 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 2, 55, 0, 0, 0, 35, 0, 0, 1,107,
- 0, 0, 2, 55, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 1,107, 0, 0, 0, 35, 0, 0, 2, 55, 0, 0, 2, 56, 0, 0, 0, 35,
- 0, 0, 2, 55, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 2, 56, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 0,234,
- 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 0,231,
- 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1,106, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 2, 56, 0, 0, 0, 35,
- 0, 0, 1,111, 0, 0, 2, 58, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 2, 58, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 1,111,
- 0, 0, 0, 35, 0, 0, 2, 58, 0, 0, 2, 59, 0, 0, 0, 35, 0, 0, 2, 58, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 2, 59,
- 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 1,110, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 2, 60, 0, 0, 0, 35,
- 0, 0, 1,110, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 2, 59, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 1, 2,
- 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 2, 59, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 2, 61, 0, 0, 0, 35, 0, 0, 1,113,
- 0, 0, 2, 61, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 1,113, 0, 0, 0, 35, 0, 0, 2, 61, 0, 0, 2, 62, 0, 0, 0, 35,
- 0, 0, 2, 61, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 2, 62, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 1,115,
- 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 1,114,
- 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 2, 62, 0, 0, 0, 35,
- 0, 0, 0,204, 0, 0, 2, 64, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 2, 64, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 1, 4,
- 0, 0, 0, 35, 0, 0, 2, 64, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 2, 64, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 2, 65,
- 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 1,114, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 2, 66, 0, 0, 0, 35,
- 0, 0, 0,205, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1,115,
- 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 2, 67, 0, 0, 0, 35, 0, 0, 1,112,
- 0, 0, 2, 67, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 2, 67, 0, 0, 2, 68, 0, 0, 0, 35,
- 0, 0, 2, 67, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 2, 68, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0,238,
- 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 0,239,
- 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1,113, 0, 0, 0, 35, 0, 0, 1,113, 0, 0, 2, 68, 0, 0, 0, 35,
- 0, 0, 1,117, 0, 0, 2, 70, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 1,117, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 2, 70,
- 0, 0, 0, 35, 0, 0, 2, 70, 0, 0, 2, 71, 0, 0, 0, 35, 0, 0, 2, 71, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 2, 70,
- 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 1,116, 0, 0, 2, 72, 0, 0, 0, 35,
- 0, 0, 0,243, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 2, 71, 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 2, 71,
- 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 1,116, 0, 0, 2, 73, 0, 0, 0, 35, 0, 0, 1,116,
- 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 2, 73, 0, 0, 0, 35, 0, 0, 2, 73, 0, 0, 2, 74, 0, 0, 0, 35,
- 0, 0, 2, 74, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 2, 73, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 1,121,
- 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 1,121, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 1,120,
- 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 1,120, 0, 0, 0, 35,
- 0, 0, 1, 8, 0, 0, 2, 76, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 1, 12, 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 2, 76,
- 0, 0, 0, 35, 0, 0, 2, 76, 0, 0, 2, 77, 0, 0, 0, 35, 0, 0, 2, 77, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 2, 76,
- 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 1,120, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 2, 78, 0, 0, 0, 35,
- 0, 0, 1,120, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 1,121, 0, 0, 2, 77, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 2, 77,
- 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 2, 79, 0, 0, 0, 35, 0, 0, 1, 7,
- 0, 0, 1,119, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 2, 79, 0, 0, 0, 35, 0, 0, 2, 79, 0, 0, 2, 80, 0, 0, 0, 35,
- 0, 0, 2, 80, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 2, 79, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 1, 6,
- 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 0,245,
- 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 1,118, 0, 0, 0, 35,
- 0, 0, 1,123, 0, 0, 2, 82, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 2, 82,
- 0, 0, 0, 35, 0, 0, 2, 82, 0, 0, 2, 83, 0, 0, 0, 35, 0, 0, 2, 83, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 2, 82,
- 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 2, 84, 0, 0, 0, 35,
- 0, 0, 0,249, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 2, 83, 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 2, 83,
- 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 2, 85, 0, 0, 0, 35, 0, 0, 1,122,
- 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 2, 85, 0, 0, 0, 35, 0, 0, 2, 85, 0, 0, 2, 86, 0, 0, 0, 35,
- 0, 0, 2, 86, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 2, 85, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 1,127,
- 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 1,126,
- 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 1,126, 0, 0, 0, 35,
- 0, 0, 1, 12, 0, 0, 2, 88, 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 1, 16, 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 2, 88,
- 0, 0, 0, 35, 0, 0, 2, 88, 0, 0, 2, 89, 0, 0, 0, 35, 0, 0, 2, 89, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 2, 88,
- 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 2, 90, 0, 0, 0, 35,
- 0, 0, 1,126, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 2, 89, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 2, 89,
- 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 2, 91, 0, 0, 0, 35, 0, 0, 1, 11,
- 0, 0, 1,125, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 2, 91, 0, 0, 0, 35, 0, 0, 2, 91, 0, 0, 2, 92, 0, 0, 0, 35,
- 0, 0, 2, 92, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 2, 91, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 1, 10,
- 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 0,247,
- 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 1,124, 0, 0, 0, 35,
- 0, 0, 1,129, 0, 0, 2, 94, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 1,129, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 2, 94,
- 0, 0, 0, 35, 0, 0, 2, 94, 0, 0, 2, 95, 0, 0, 0, 35, 0, 0, 2, 95, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 2, 94,
- 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 1,128, 0, 0, 2, 96, 0, 0, 0, 35,
- 0, 0, 0,253, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 2, 95, 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 2, 95,
- 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 1,128, 0, 0, 2, 97, 0, 0, 0, 35, 0, 0, 1,128,
- 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 2, 97, 0, 0, 0, 35, 0, 0, 2, 97, 0, 0, 2, 98, 0, 0, 0, 35,
- 0, 0, 2, 98, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 2, 97, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 1,133,
- 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 1,132,
- 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 1,132, 0, 0, 0, 35,
- 0, 0, 1, 16, 0, 0, 2,100, 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 1, 20, 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 2,100,
- 0, 0, 0, 35, 0, 0, 2,100, 0, 0, 2,101, 0, 0, 0, 35, 0, 0, 2,101, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 2,100,
- 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 1,132, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 2,102, 0, 0, 0, 35,
- 0, 0, 1,132, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 2,101, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 2,101,
- 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 1,133, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 2,103, 0, 0, 0, 35, 0, 0, 1, 15,
- 0, 0, 1,131, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 2,103, 0, 0, 0, 35, 0, 0, 2,103, 0, 0, 2,104, 0, 0, 0, 35,
- 0, 0, 2,104, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 2,103, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 1, 14,
- 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 0,251,
- 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 1,130, 0, 0, 0, 35,
- 0, 0, 1,135, 0, 0, 2,106, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 1,135, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 2,106,
- 0, 0, 0, 35, 0, 0, 2,106, 0, 0, 2,107, 0, 0, 0, 35, 0, 0, 2,107, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 2,106,
- 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 2,108, 0, 0, 0, 35,
- 0, 0, 1, 1, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 2,107, 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 2,107,
- 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 2,109, 0, 0, 0, 35, 0, 0, 1,134,
- 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 2,109, 0, 0, 0, 35, 0, 0, 2,109, 0, 0, 2,110, 0, 0, 0, 35,
- 0, 0, 2,110, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 2,109, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 1,139,
- 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 1,138,
- 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 1,138, 0, 0, 0, 35,
- 0, 0, 1, 20, 0, 0, 2,112, 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 1, 24, 0, 0, 2,112,
- 0, 0, 0, 35, 0, 0, 2,112, 0, 0, 2,113, 0, 0, 0, 35, 0, 0, 2,113, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 2,112,
- 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 1,138, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 2,114, 0, 0, 0, 35,
- 0, 0, 1,138, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 2,113, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 2,113,
- 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 1,139, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 2,115, 0, 0, 0, 35, 0, 0, 1, 19,
- 0, 0, 1,137, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 2,115, 0, 0, 0, 35, 0, 0, 2,115, 0, 0, 2,116, 0, 0, 0, 35,
- 0, 0, 2,116, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 2,115, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 1, 18,
- 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 0,255,
- 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 1,136, 0, 0, 0, 35,
- 0, 0, 1,141, 0, 0, 2,118, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 1,141, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 2,118,
- 0, 0, 0, 35, 0, 0, 2,118, 0, 0, 2,119, 0, 0, 0, 35, 0, 0, 2,119, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 2,118,
- 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1,140, 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 2,120, 0, 0, 0, 35,
- 0, 0, 1, 5, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 2,119, 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 2,119,
- 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 2,121, 0, 0, 0, 35, 0, 0, 1,140,
- 0, 0, 1,142, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 2,121, 0, 0, 0, 35, 0, 0, 2,121, 0, 0, 2,122, 0, 0, 0, 35,
- 0, 0, 2,122, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 2,121, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 1,144,
- 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 1,145,
- 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 35,
- 0, 0, 1, 24, 0, 0, 2,124, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 2,124,
- 0, 0, 0, 35, 0, 0, 2,124, 0, 0, 2,125, 0, 0, 0, 35, 0, 0, 2,125, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 2,124,
- 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 1,145, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 2,126, 0, 0, 0, 35,
- 0, 0, 1,145, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 2,125, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 2,125,
- 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 2,127, 0, 0, 0, 35, 0, 0, 1, 23,
- 0, 0, 1,143, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 2,127, 0, 0, 0, 35, 0, 0, 2,127, 0, 0, 2,128, 0, 0, 0, 35,
- 0, 0, 2,128, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 2,127, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 1, 22,
- 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 1, 3,
- 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 1,142, 0, 0, 0, 35,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,236,247,176, 0, 0, 0,242, 0, 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, 8,108, 16, 32, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,108,128, 32, 0, 0, 0, 6,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 8,109, 96, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0,100, 0,
- 8,108, 16, 32, 0, 0, 0, 52, 0, 0, 5, 0, 0, 0, 1, 27, 0, 0, 0,102, 0, 0, 1,146, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,146, 0, 0, 0,171, 0, 0, 1, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 1, 27, 0, 0, 0,171,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,171, 0, 0, 1,146, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,147,
- 0, 0, 0, 46, 0, 0, 1,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 1,147, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 1,147, 0, 0, 1,148, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,148, 0, 0, 1,146,
- 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 26, 0, 0, 0, 12, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,165, 0, 0, 1,148, 0, 0, 1, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,102, 0, 0, 1, 26, 0, 0, 1,148,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,148, 0, 0, 0,165, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,147,
- 0, 0, 0, 43, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 1,147, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 46, 0, 0, 1,147, 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,170, 0, 0, 0,164,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 26, 0, 0, 0,102, 0, 0, 1,149, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,149, 0, 0, 1, 28, 0, 0, 1, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 1, 26, 0, 0, 1, 28,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 28, 0, 0, 1,149, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,150,
- 0, 0, 0,103, 0, 0, 1,149, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 1,150, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,104, 0, 0, 1,150, 0, 0, 1,151, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,151, 0, 0, 1,149,
- 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 27, 0, 0, 0, 14, 0, 0, 1, 31, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 31, 0, 0, 1,151, 0, 0, 1, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,102, 0, 0, 1, 27, 0, 0, 1,151,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,151, 0, 0, 1, 31, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,150,
- 0, 0, 0,104, 0, 0, 1, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 30, 0, 0, 1, 29, 0, 0, 1,150, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 1,150, 0, 0, 1, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 29, 0, 0, 1, 30,
- 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,168, 0, 0, 0, 45, 0, 0, 1,152, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,152, 0, 0, 0,172, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,168, 0, 0, 0,172,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,172, 0, 0, 1,152, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,153,
- 0, 0, 0, 47, 0, 0, 1,152, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,152, 0, 0, 1,154, 0, 0, 1,153, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,104, 0, 0, 1,153, 0, 0, 1,154, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,154, 0, 0, 1,152,
- 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,169, 0, 0, 0, 13, 0, 0, 1, 30, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 30, 0, 0, 1,154, 0, 0, 0,169, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0,169, 0, 0, 1,154,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,154, 0, 0, 1, 30, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,153,
- 0, 0, 0,104, 0, 0, 1, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 31, 0, 0, 0,173, 0, 0, 1,153, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 1,153, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,173, 0, 0, 1, 31,
- 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,167, 0, 0, 0, 44, 0, 0, 1,155, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,155, 0, 0, 1, 29, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0,167, 0, 0, 1, 29,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 29, 0, 0, 1,155, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,156,
- 0, 0, 0,103, 0, 0, 1,155, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,155, 0, 0, 1,157, 0, 0, 1,156, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 1,156, 0, 0, 1,157, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,157, 0, 0, 1,155,
- 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,162, 0, 0, 1,157, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0,166, 0, 0, 1,157,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,157, 0, 0, 0,162, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,156,
- 0, 0, 0, 42, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,163, 0, 0, 1, 28, 0, 0, 1,156, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 1,156, 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 28, 0, 0, 0,163,
- 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,158, 0, 0, 0,105, 0, 0, 1, 33, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 33, 0, 0, 0,179, 0, 0, 1,158, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 1,158, 0, 0, 0,179,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,179, 0, 0, 1, 33, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,158,
- 0, 0, 0, 50, 0, 0, 1,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,159, 0, 0, 1,160, 0, 0, 1,158, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,105, 0, 0, 1,158, 0, 0, 1,160, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,160, 0, 0, 1,159,
- 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,165, 0, 0, 0, 12, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 32, 0, 0, 1,160, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0,165, 0, 0, 1,160,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,160, 0, 0, 1, 32, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,164,
- 0, 0, 0, 43, 0, 0, 1,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,159, 0, 0, 0,178, 0, 0, 0,164, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0,164, 0, 0, 0,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,178, 0, 0, 1,159,
- 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,161, 0, 0, 0,105, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 32, 0, 0, 1, 34, 0, 0, 1,161, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,106, 0, 0, 1,161, 0, 0, 1, 34,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 34, 0, 0, 1, 32, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,161,
- 0, 0, 0,106, 0, 0, 1,162, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,162, 0, 0, 1,163, 0, 0, 1,161, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,105, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,163, 0, 0, 1,162,
- 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 37, 0, 0, 0, 16, 0, 0, 1, 33, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 33, 0, 0, 1,163, 0, 0, 1, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 1, 37, 0, 0, 1,163,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,163, 0, 0, 1, 33, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 36,
- 0, 0, 0,107, 0, 0, 1,162, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,162, 0, 0, 1, 35, 0, 0, 1, 36, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 1, 36, 0, 0, 1, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 35, 0, 0, 1,162,
- 0, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,164, 0, 0, 0, 49, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,176, 0, 0, 0,180, 0, 0, 1,164, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 1,164, 0, 0, 0,180,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,180, 0, 0, 0,176, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,164,
- 0, 0, 0, 51, 0, 0, 1,165, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,165, 0, 0, 1,166, 0, 0, 1,164, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 1,164, 0, 0, 1,166, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,166, 0, 0, 1,165,
- 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 36, 0, 0, 0, 15, 0, 0, 0,177, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,177, 0, 0, 1,166, 0, 0, 1, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 1, 36, 0, 0, 1,166,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,166, 0, 0, 0,177, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 37,
- 0, 0, 0,107, 0, 0, 1,165, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,165, 0, 0, 0,181, 0, 0, 1, 37, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 1, 37, 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,181, 0, 0, 1,165,
- 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,167, 0, 0, 0, 48, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,175, 0, 0, 1, 35, 0, 0, 1,167, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,106, 0, 0, 1,167, 0, 0, 1, 35,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 35, 0, 0, 0,175, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,167,
- 0, 0, 0,106, 0, 0, 1,168, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,168, 0, 0, 1,169, 0, 0, 1,167, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 48, 0, 0, 1,167, 0, 0, 1,169, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,169, 0, 0, 1,168,
- 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,174, 0, 0, 1,169, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0,162, 0, 0, 1,169,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,169, 0, 0, 0,174, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,163,
- 0, 0, 0, 42, 0, 0, 1,168, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,168, 0, 0, 1, 34, 0, 0, 0,163, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 0,163, 0, 0, 1, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 34, 0, 0, 1,168,
- 0, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 39, 0, 0, 0,108, 0, 0, 1,170, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,170, 0, 0, 0,187, 0, 0, 1, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 0, 0, 1, 39, 0, 0, 0,187,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,187, 0, 0, 1,170, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,171,
- 0, 0, 0, 54, 0, 0, 1,170, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,170, 0, 0, 1,172, 0, 0, 1,171, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 1,171, 0, 0, 1,172, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,172, 0, 0, 1,170,
- 0, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 38, 0, 0, 0, 13, 0, 0, 0,169, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,169, 0, 0, 1,172, 0, 0, 1, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,108, 0, 0, 1, 38, 0, 0, 1,172,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,172, 0, 0, 0,169, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,171,
- 0, 0, 0, 45, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,168, 0, 0, 0,186, 0, 0, 1,171, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 1,171, 0, 0, 0,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,186, 0, 0, 0,168,
- 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 38, 0, 0, 0,108, 0, 0, 1,173, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,173, 0, 0, 1, 40, 0, 0, 1, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 1, 38, 0, 0, 1, 40,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 40, 0, 0, 1,173, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,174,
- 0, 0, 0,109, 0, 0, 1,173, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,173, 0, 0, 1,175, 0, 0, 1,174, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,110, 0, 0, 1,174, 0, 0, 1,175, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,175, 0, 0, 1,173,
- 0, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 39, 0, 0, 0, 18, 0, 0, 1, 43, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 43, 0, 0, 1,175, 0, 0, 1, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,108, 0, 0, 1, 39, 0, 0, 1,175,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,175, 0, 0, 1, 43, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,174,
- 0, 0, 0,110, 0, 0, 1, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 42, 0, 0, 1, 41, 0, 0, 1,174, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 1,174, 0, 0, 1, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 41, 0, 0, 1, 42,
- 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0, 53, 0, 0, 1,176, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,176, 0, 0, 0,188, 0, 0, 0,184, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0,188,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,188, 0, 0, 1,176, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,177,
- 0, 0, 0, 55, 0, 0, 1,176, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,176, 0, 0, 1,178, 0, 0, 1,177, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,110, 0, 0, 1,177, 0, 0, 1,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,178, 0, 0, 1,176,
- 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,185, 0, 0, 0, 17, 0, 0, 1, 42, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 42, 0, 0, 1,178, 0, 0, 0,185, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 0,185, 0, 0, 1,178,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,178, 0, 0, 1, 42, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,177,
- 0, 0, 0,110, 0, 0, 1, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 43, 0, 0, 0,189, 0, 0, 1,177, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 1,177, 0, 0, 0,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,189, 0, 0, 1, 43,
- 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,183, 0, 0, 0, 52, 0, 0, 1,179, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,179, 0, 0, 1, 41, 0, 0, 0,183, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0,183, 0, 0, 1, 41,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 41, 0, 0, 1,179, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,180,
- 0, 0, 0,109, 0, 0, 1,179, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,179, 0, 0, 1,181, 0, 0, 1,180, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 1,180, 0, 0, 1,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,181, 0, 0, 1,179,
- 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,166, 0, 0, 1,181, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 0,182, 0, 0, 1,181,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,181, 0, 0, 0,166, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,180,
- 0, 0, 0, 44, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,167, 0, 0, 1, 40, 0, 0, 1,180, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 1,180, 0, 0, 1, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 40, 0, 0, 0,167,
- 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 45, 0, 0, 0,111, 0, 0, 1,182, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,182, 0, 0, 0,195, 0, 0, 1, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 1, 45, 0, 0, 0,195,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,195, 0, 0, 1,182, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,183,
- 0, 0, 0, 58, 0, 0, 1,182, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,182, 0, 0, 1,184, 0, 0, 1,183, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 1,183, 0, 0, 1,184, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,184, 0, 0, 1,182,
- 0, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 44, 0, 0, 0, 17, 0, 0, 0,185, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,185, 0, 0, 1,184, 0, 0, 1, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 1, 44, 0, 0, 1,184,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,184, 0, 0, 0,185, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,183,
- 0, 0, 0, 53, 0, 0, 0,184, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0,194, 0, 0, 1,183, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 58, 0, 0, 1,183, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,194, 0, 0, 0,184,
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 44, 0, 0, 0,111, 0, 0, 1,185, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,185, 0, 0, 1, 46, 0, 0, 1, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 1, 44, 0, 0, 1, 46,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 46, 0, 0, 1,185, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,186,
- 0, 0, 0,112, 0, 0, 1,185, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 1,186, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 1,186, 0, 0, 1,187, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,187, 0, 0, 1,185,
- 0, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 45, 0, 0, 0, 20, 0, 0, 1, 49, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 49, 0, 0, 1,187, 0, 0, 1, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 1, 45, 0, 0, 1,187,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,187, 0, 0, 1, 49, 0, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,186,
- 0, 0, 0,113, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 48, 0, 0, 1, 47, 0, 0, 1,186, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,112, 0, 0, 1,186, 0, 0, 1, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 47, 0, 0, 1, 48,
- 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,192, 0, 0, 0, 57, 0, 0, 1,188, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,188, 0, 0, 0,196, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0,192, 0, 0, 0,196,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,196, 0, 0, 1,188, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,189,
- 0, 0, 0, 59, 0, 0, 1,188, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 1,189, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 1,189, 0, 0, 1,190, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,190, 0, 0, 1,188,
- 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,193, 0, 0, 0, 19, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 48, 0, 0, 1,190, 0, 0, 0,193, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 0,193, 0, 0, 1,190,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,190, 0, 0, 1, 48, 0, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,189,
- 0, 0, 0,113, 0, 0, 1, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 49, 0, 0, 0,197, 0, 0, 1,189, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 1,189, 0, 0, 0,197, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,197, 0, 0, 1, 49,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,191, 0, 0, 0, 56, 0, 0, 1,191, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,191, 0, 0, 1, 47, 0, 0, 0,191, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 19, 0, 0, 0,191, 0, 0, 1, 47,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 47, 0, 0, 1,191, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,192,
- 0, 0, 0,112, 0, 0, 1,191, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,191, 0, 0, 1,193, 0, 0, 1,192, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 1,192, 0, 0, 1,193, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,193, 0, 0, 1,191,
- 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,182, 0, 0, 1,193, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 56, 0, 0, 0,190, 0, 0, 1,193,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,193, 0, 0, 0,182, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,192,
- 0, 0, 0, 52, 0, 0, 0,183, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,183, 0, 0, 1, 46, 0, 0, 1,192, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,112, 0, 0, 1,192, 0, 0, 1, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 46, 0, 0, 0,183,
- 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 51, 0, 0, 0,114, 0, 0, 1,194, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,194, 0, 0, 0,199, 0, 0, 1, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 1, 51, 0, 0, 0,199,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,199, 0, 0, 1,194, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,195,
- 0, 0, 0, 60, 0, 0, 1,194, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,194, 0, 0, 1,196, 0, 0, 1,195, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 1,195, 0, 0, 1,196, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,196, 0, 0, 1,194,
- 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 50, 0, 0, 0, 19, 0, 0, 0,193, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,193, 0, 0, 1,196, 0, 0, 1, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,114, 0, 0, 1, 50, 0, 0, 1,196,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,196, 0, 0, 0,193, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,195,
- 0, 0, 0, 57, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,192, 0, 0, 0,198, 0, 0, 1,195, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 1,195, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,198, 0, 0, 0,192,
- 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 50, 0, 0, 0,114, 0, 0, 1,197, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,197, 0, 0, 1, 53, 0, 0, 1, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 19, 0, 0, 1, 50, 0, 0, 1, 53,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 53, 0, 0, 1,197, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,198,
- 0, 0, 0,115, 0, 0, 1,197, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,197, 0, 0, 1,199, 0, 0, 1,198, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,116, 0, 0, 1,198, 0, 0, 1,199, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,199, 0, 0, 1,197,
- 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 51, 0, 0, 0, 21, 0, 0, 1, 55, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 55, 0, 0, 1,199, 0, 0, 1, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,114, 0, 0, 1, 51, 0, 0, 1,199,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,199, 0, 0, 1, 55, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,198,
- 0, 0, 0,116, 0, 0, 1, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 54, 0, 0, 1, 52, 0, 0, 1,198, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 1,198, 0, 0, 1, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 52, 0, 0, 1, 54,
- 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,176, 0, 0, 0, 49, 0, 0, 1,200, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,200, 0, 0, 0,200, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0,176, 0, 0, 0,200,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,200, 0, 0, 1,200, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,201,
- 0, 0, 0, 61, 0, 0, 1,200, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 1,201, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,116, 0, 0, 1,201, 0, 0, 1,202, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,202, 0, 0, 1,200,
- 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,177, 0, 0, 0, 15, 0, 0, 1, 54, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 54, 0, 0, 1,202, 0, 0, 0,177, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 0,177, 0, 0, 1,202,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,202, 0, 0, 1, 54, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,201,
- 0, 0, 0,116, 0, 0, 1, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 55, 0, 0, 0,201, 0, 0, 1,201, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 1,201, 0, 0, 0,201, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,201, 0, 0, 1, 55,
- 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,175, 0, 0, 0, 48, 0, 0, 1,203, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,203, 0, 0, 1, 52, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0,175, 0, 0, 1, 52,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 52, 0, 0, 1,203, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,204,
- 0, 0, 0,115, 0, 0, 1,203, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,203, 0, 0, 1,205, 0, 0, 1,204, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 56, 0, 0, 1,204, 0, 0, 1,205, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,205, 0, 0, 1,203,
- 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,190, 0, 0, 1,205, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 0, 0, 0,174, 0, 0, 1,205,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,205, 0, 0, 0,190, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,204,
- 0, 0, 0, 56, 0, 0, 0,191, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,191, 0, 0, 1, 53, 0, 0, 1,204, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 1,204, 0, 0, 1, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 53, 0, 0, 0,191,
- 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,206, 0, 0, 0,117, 0, 0, 1, 57, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 57, 0, 0, 0,207, 0, 0, 1,206, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 1,206, 0, 0, 0,207,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,207, 0, 0, 1, 57, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,206,
- 0, 0, 0, 64, 0, 0, 1,207, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,207, 0, 0, 1,208, 0, 0, 1,206, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,117, 0, 0, 1,206, 0, 0, 1,208, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,208, 0, 0, 1,207,
- 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,179, 0, 0, 0, 16, 0, 0, 1, 56, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 56, 0, 0, 1,208, 0, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 0,179, 0, 0, 1,208,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,208, 0, 0, 1, 56, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,178,
- 0, 0, 0, 50, 0, 0, 1,207, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,207, 0, 0, 0,206, 0, 0, 0,178, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0,178, 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 1,207,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,209, 0, 0, 0,117, 0, 0, 1, 56, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 56, 0, 0, 1, 58, 0, 0, 1,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,118, 0, 0, 1,209, 0, 0, 1, 58,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 58, 0, 0, 1, 56, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,209,
- 0, 0, 0,118, 0, 0, 1,210, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1,211, 0, 0, 1,209, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,117, 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,211, 0, 0, 1,210,
- 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 61, 0, 0, 0, 23, 0, 0, 1, 57, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 57, 0, 0, 1,211, 0, 0, 1, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 1, 61, 0, 0, 1,211,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,211, 0, 0, 1, 57, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 60,
- 0, 0, 0,119, 0, 0, 1,210, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1, 59, 0, 0, 1, 60, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 1, 60, 0, 0, 1, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 59, 0, 0, 1,210,
- 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,212, 0, 0, 0, 63, 0, 0, 0,204, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,204, 0, 0, 0,208, 0, 0, 1,212, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 65, 0, 0, 1,212, 0, 0, 0,208,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,208, 0, 0, 0,204, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,212,
- 0, 0, 0, 65, 0, 0, 1,213, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,213, 0, 0, 1,214, 0, 0, 1,212, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 63, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,214, 0, 0, 1,213,
- 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 60, 0, 0, 0, 22, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,205, 0, 0, 1,214, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 1, 60, 0, 0, 1,214,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,214, 0, 0, 0,205, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 61,
- 0, 0, 0,119, 0, 0, 1,213, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,213, 0, 0, 0,209, 0, 0, 1, 61, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 23, 0, 0, 1, 61, 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,209, 0, 0, 1,213,
- 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,215, 0, 0, 0, 62, 0, 0, 0,203, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,203, 0, 0, 1, 59, 0, 0, 1,215, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,118, 0, 0, 1,215, 0, 0, 1, 59,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 59, 0, 0, 0,203, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,215,
- 0, 0, 0,118, 0, 0, 1,216, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,216, 0, 0, 1,217, 0, 0, 1,215, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1,215, 0, 0, 1,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,217, 0, 0, 1,216,
- 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,180, 0, 0, 0, 5, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,202, 0, 0, 1,217, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0,180, 0, 0, 1,217,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,217, 0, 0, 0,202, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,181,
- 0, 0, 0, 51, 0, 0, 1,216, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,216, 0, 0, 1, 58, 0, 0, 0,181, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0,181, 0, 0, 1, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 58, 0, 0, 1,216,
- 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,218, 0, 0, 0,120, 0, 0, 1, 63, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 63, 0, 0, 0,215, 0, 0, 1,218, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 68, 0, 0, 1,218, 0, 0, 0,215,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,215, 0, 0, 1, 63, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,218,
- 0, 0, 0, 68, 0, 0, 1,219, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,219, 0, 0, 1,220, 0, 0, 1,218, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,120, 0, 0, 1,218, 0, 0, 1,220, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,220, 0, 0, 1,219,
- 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,173, 0, 0, 0, 14, 0, 0, 1, 62, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 62, 0, 0, 1,220, 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 0,173, 0, 0, 1,220,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,220, 0, 0, 1, 62, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,172,
- 0, 0, 0, 47, 0, 0, 1,219, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,219, 0, 0, 0,214, 0, 0, 0,172, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,172, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,214, 0, 0, 1,219,
- 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,221, 0, 0, 0,120, 0, 0, 1, 62, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 1,221, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,121, 0, 0, 1,221, 0, 0, 1, 64,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 64, 0, 0, 1, 62, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,221,
- 0, 0, 0,121, 0, 0, 1,222, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,222, 0, 0, 1,223, 0, 0, 1,221, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,120, 0, 0, 1,221, 0, 0, 1,223, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,223, 0, 0, 1,222,
- 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 67, 0, 0, 0, 25, 0, 0, 1, 63, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 63, 0, 0, 1,223, 0, 0, 1, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,122, 0, 0, 1, 67, 0, 0, 1,223,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,223, 0, 0, 1, 63, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 66,
- 0, 0, 0,122, 0, 0, 1,222, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,222, 0, 0, 1, 65, 0, 0, 1, 66, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 1, 66, 0, 0, 1, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 65, 0, 0, 1,222,
- 0, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,224, 0, 0, 0, 67, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,212, 0, 0, 0,216, 0, 0, 1,224, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 1,224, 0, 0, 0,216,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,216, 0, 0, 0,212, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,224,
- 0, 0, 0, 69, 0, 0, 1,225, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,225, 0, 0, 1,226, 0, 0, 1,224, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 67, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,226, 0, 0, 1,225,
- 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 66, 0, 0, 0, 24, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,213, 0, 0, 1,226, 0, 0, 1, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,122, 0, 0, 1, 66, 0, 0, 1,226,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,226, 0, 0, 0,213, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 67,
- 0, 0, 0,122, 0, 0, 1,225, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,225, 0, 0, 0,217, 0, 0, 1, 67, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 25, 0, 0, 1, 67, 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,217, 0, 0, 1,225,
- 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,227, 0, 0, 0, 66, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,211, 0, 0, 1, 65, 0, 0, 1,227, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,121, 0, 0, 1,227, 0, 0, 1, 65,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 65, 0, 0, 0,211, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,227,
- 0, 0, 0,121, 0, 0, 1,228, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,228, 0, 0, 1,229, 0, 0, 1,227, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 66, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,229, 0, 0, 1,228,
- 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,170, 0, 0, 0, 1, 0, 0, 0,210, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,210, 0, 0, 1,229, 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 46, 0, 0, 0,170, 0, 0, 1,229,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,229, 0, 0, 0,210, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,171,
- 0, 0, 0, 46, 0, 0, 1,228, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,228, 0, 0, 1, 64, 0, 0, 0,171, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0,171, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 64, 0, 0, 1,228,
- 0, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,230, 0, 0, 0,123, 0, 0, 1, 69, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 69, 0, 0, 0,223, 0, 0, 1,230, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 1,230, 0, 0, 0,223,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,223, 0, 0, 1, 69, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,230,
- 0, 0, 0, 72, 0, 0, 1,231, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,231, 0, 0, 1,232, 0, 0, 1,230, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 1,230, 0, 0, 1,232, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,232, 0, 0, 1,231,
- 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,189, 0, 0, 0, 18, 0, 0, 1, 68, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 68, 0, 0, 1,232, 0, 0, 0,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 0,189, 0, 0, 1,232,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,232, 0, 0, 1, 68, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,188,
- 0, 0, 0, 55, 0, 0, 1,231, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,231, 0, 0, 0,222, 0, 0, 0,188, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,188, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 1,231,
- 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,233, 0, 0, 0,123, 0, 0, 1, 68, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 68, 0, 0, 1, 70, 0, 0, 1,233, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,124, 0, 0, 1,233, 0, 0, 1, 70,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 70, 0, 0, 1, 68, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,233,
- 0, 0, 0,124, 0, 0, 1,234, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1,235, 0, 0, 1,233, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 1,233, 0, 0, 1,235, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,235, 0, 0, 1,234,
- 0, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 73, 0, 0, 0, 27, 0, 0, 1, 69, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 69, 0, 0, 1,235, 0, 0, 1, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,125, 0, 0, 1, 73, 0, 0, 1,235,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,235, 0, 0, 1, 69, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 72,
- 0, 0, 0,125, 0, 0, 1,234, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1, 71, 0, 0, 1, 72, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 1, 72, 0, 0, 1, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 71, 0, 0, 1,234,
- 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,236, 0, 0, 0, 71, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,220, 0, 0, 0,224, 0, 0, 1,236, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 73, 0, 0, 1,236, 0, 0, 0,224,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,224, 0, 0, 0,220, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,236,
- 0, 0, 0, 73, 0, 0, 1,237, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,237, 0, 0, 1,238, 0, 0, 1,236, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 71, 0, 0, 1,236, 0, 0, 1,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,238, 0, 0, 1,237,
- 0, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 72, 0, 0, 0, 26, 0, 0, 0,221, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,221, 0, 0, 1,238, 0, 0, 1, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,125, 0, 0, 1, 72, 0, 0, 1,238,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,238, 0, 0, 0,221, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 73,
- 0, 0, 0,125, 0, 0, 1,237, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,237, 0, 0, 0,225, 0, 0, 1, 73, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 1, 73, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,225, 0, 0, 1,237,
- 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,239, 0, 0, 0, 70, 0, 0, 0,219, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,219, 0, 0, 1, 71, 0, 0, 1,239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,124, 0, 0, 1,239, 0, 0, 1, 71,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 71, 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,239,
- 0, 0, 0,124, 0, 0, 1,240, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,240, 0, 0, 1,241, 0, 0, 1,239, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 70, 0, 0, 1,239, 0, 0, 1,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,241, 0, 0, 1,240,
- 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,186, 0, 0, 0, 2, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,218, 0, 0, 1,241, 0, 0, 0,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 0,186, 0, 0, 1,241,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,241, 0, 0, 0,218, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,187,
- 0, 0, 0, 54, 0, 0, 1,240, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,240, 0, 0, 1, 70, 0, 0, 0,187, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 18, 0, 0, 0,187, 0, 0, 1, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 70, 0, 0, 1,240,
- 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,242, 0, 0, 0,126, 0, 0, 1, 75, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 75, 0, 0, 0,231, 0, 0, 1,242, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 1,242, 0, 0, 0,231,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,231, 0, 0, 1, 75, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,242,
- 0, 0, 0, 76, 0, 0, 1,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,243, 0, 0, 1,244, 0, 0, 1,242, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,126, 0, 0, 1,242, 0, 0, 1,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,244, 0, 0, 1,243,
- 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,197, 0, 0, 0, 20, 0, 0, 1, 74, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 74, 0, 0, 1,244, 0, 0, 0,197, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 0,197, 0, 0, 1,244,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,244, 0, 0, 1, 74, 0, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,196,
- 0, 0, 0, 59, 0, 0, 1,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,243, 0, 0, 0,230, 0, 0, 0,196, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0,196, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,230, 0, 0, 1,243,
- 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,245, 0, 0, 0,126, 0, 0, 1, 74, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 74, 0, 0, 1, 76, 0, 0, 1,245, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,127, 0, 0, 1,245, 0, 0, 1, 76,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 76, 0, 0, 1, 74, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,245,
- 0, 0, 0,127, 0, 0, 1,246, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,246, 0, 0, 1,247, 0, 0, 1,245, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,126, 0, 0, 1,245, 0, 0, 1,247, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,247, 0, 0, 1,246,
- 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 79, 0, 0, 0, 29, 0, 0, 1, 75, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 75, 0, 0, 1,247, 0, 0, 1, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,128, 0, 0, 1, 79, 0, 0, 1,247,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,247, 0, 0, 1, 75, 0, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 78,
- 0, 0, 0,128, 0, 0, 1,246, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,246, 0, 0, 1, 77, 0, 0, 1, 78, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 1, 78, 0, 0, 1, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 77, 0, 0, 1,246,
- 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,248, 0, 0, 0, 75, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,228, 0, 0, 0,232, 0, 0, 1,248, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 77, 0, 0, 1,248, 0, 0, 0,232,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,232, 0, 0, 0,228, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,248,
- 0, 0, 0, 77, 0, 0, 1,249, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,249, 0, 0, 1,250, 0, 0, 1,248, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 75, 0, 0, 1,248, 0, 0, 1,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,250, 0, 0, 1,249,
- 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 78, 0, 0, 0, 28, 0, 0, 0,229, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,229, 0, 0, 1,250, 0, 0, 1, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,128, 0, 0, 1, 78, 0, 0, 1,250,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,250, 0, 0, 0,229, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 79,
- 0, 0, 0,128, 0, 0, 1,249, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,249, 0, 0, 0,233, 0, 0, 1, 79, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 1, 79, 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,233, 0, 0, 1,249,
- 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,251, 0, 0, 0, 74, 0, 0, 0,227, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,227, 0, 0, 1, 77, 0, 0, 1,251, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,127, 0, 0, 1,251, 0, 0, 1, 77,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 77, 0, 0, 0,227, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,251,
- 0, 0, 0,127, 0, 0, 1,252, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,252, 0, 0, 1,253, 0, 0, 1,251, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 74, 0, 0, 1,251, 0, 0, 1,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,253, 0, 0, 1,252,
- 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,194, 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,226, 0, 0, 1,253, 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 0, 0,194, 0, 0, 1,253,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,253, 0, 0, 0,226, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,195,
- 0, 0, 0, 58, 0, 0, 1,252, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,252, 0, 0, 1, 76, 0, 0, 0,195, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0,195, 0, 0, 1, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 76, 0, 0, 1,252,
- 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,254, 0, 0, 0,129, 0, 0, 1, 81, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 81, 0, 0, 0,239, 0, 0, 1,254, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 1,254, 0, 0, 0,239,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,239, 0, 0, 1, 81, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,254,
- 0, 0, 0, 80, 0, 0, 1,255, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,255, 0, 0, 2, 0, 0, 0, 1,254, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,129, 0, 0, 1,254, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 1,255,
- 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,201, 0, 0, 0, 21, 0, 0, 1, 80, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 80, 0, 0, 2, 0, 0, 0, 0,201, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 0,201, 0, 0, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 1, 80, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,200,
- 0, 0, 0, 61, 0, 0, 1,255, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,255, 0, 0, 0,238, 0, 0, 0,200, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0,200, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,238, 0, 0, 1,255,
- 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 1, 0, 0, 0,129, 0, 0, 1, 80, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 80, 0, 0, 1, 82, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 2, 1, 0, 0, 1, 82,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 1, 80, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 1,
- 0, 0, 0,130, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 2, 0, 0, 2, 3, 0, 0, 2, 1, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,129, 0, 0, 2, 1, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, 0, 0, 2, 2,
- 0, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 85, 0, 0, 0, 31, 0, 0, 1, 81, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 81, 0, 0, 2, 3, 0, 0, 1, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,131, 0, 0, 1, 85, 0, 0, 2, 3,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, 0, 0, 1, 81, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 84,
- 0, 0, 0,131, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 2, 0, 0, 1, 83, 0, 0, 1, 84, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 1, 84, 0, 0, 1, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 83, 0, 0, 2, 2,
- 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 79, 0, 0, 0,236, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,236, 0, 0, 0,240, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 81, 0, 0, 2, 4, 0, 0, 0,240,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,240, 0, 0, 0,236, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 4,
- 0, 0, 0, 81, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 5, 0, 0, 2, 6, 0, 0, 2, 4, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 79, 0, 0, 2, 4, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 6, 0, 0, 2, 5,
- 0, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 84, 0, 0, 0, 30, 0, 0, 0,237, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,237, 0, 0, 2, 6, 0, 0, 1, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,131, 0, 0, 1, 84, 0, 0, 2, 6,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 6, 0, 0, 0,237, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 85,
- 0, 0, 0,131, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 5, 0, 0, 0,241, 0, 0, 1, 85, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 1, 85, 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,241, 0, 0, 2, 5,
- 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 7, 0, 0, 0, 78, 0, 0, 0,235, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,235, 0, 0, 1, 83, 0, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 2, 7, 0, 0, 1, 83,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 83, 0, 0, 0,235, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 7,
- 0, 0, 0,130, 0, 0, 2, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 8, 0, 0, 2, 9, 0, 0, 2, 7, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 2, 7, 0, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 9, 0, 0, 2, 8,
- 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,198, 0, 0, 0, 4, 0, 0, 0,234, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,234, 0, 0, 2, 9, 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0,198, 0, 0, 2, 9,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 9, 0, 0, 0,234, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,199,
- 0, 0, 0, 60, 0, 0, 2, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 8, 0, 0, 1, 82, 0, 0, 0,199, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0,199, 0, 0, 1, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 2, 8,
- 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 87, 0, 0, 0,132, 0, 0, 2, 10, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 10, 0, 0, 0,245, 0, 0, 1, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 1, 87, 0, 0, 0,245,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,245, 0, 0, 2, 10, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 11,
- 0, 0, 0, 83, 0, 0, 2, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 10, 0, 0, 2, 12, 0, 0, 2, 11, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 65, 0, 0, 2, 11, 0, 0, 2, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 12, 0, 0, 2, 10,
- 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 86, 0, 0, 0, 23, 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,209, 0, 0, 2, 12, 0, 0, 1, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,132, 0, 0, 1, 86, 0, 0, 2, 12,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 12, 0, 0, 0,209, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 11,
- 0, 0, 0, 65, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,208, 0, 0, 0,244, 0, 0, 2, 11, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 83, 0, 0, 2, 11, 0, 0, 0,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,244, 0, 0, 0,208,
- 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 86, 0, 0, 0,132, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 13, 0, 0, 1, 88, 0, 0, 1, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 23, 0, 0, 1, 86, 0, 0, 1, 88,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 2, 13, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 14,
- 0, 0, 0,133, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 13, 0, 0, 2, 15, 0, 0, 2, 14, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,134, 0, 0, 2, 14, 0, 0, 2, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 15, 0, 0, 2, 13,
- 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 87, 0, 0, 0, 32, 0, 0, 1, 91, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 91, 0, 0, 2, 15, 0, 0, 1, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,132, 0, 0, 1, 87, 0, 0, 2, 15,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 15, 0, 0, 1, 91, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 14,
- 0, 0, 0,134, 0, 0, 1, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 90, 0, 0, 1, 89, 0, 0, 2, 14, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,133, 0, 0, 2, 14, 0, 0, 1, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 89, 0, 0, 1, 90,
- 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,212, 0, 0, 0, 67, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 16, 0, 0, 0,242, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0,212, 0, 0, 0,242,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,242, 0, 0, 2, 16, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 17,
- 0, 0, 0, 82, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 16, 0, 0, 2, 18, 0, 0, 2, 17, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,134, 0, 0, 2, 17, 0, 0, 2, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 18, 0, 0, 2, 16,
- 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,213, 0, 0, 0, 24, 0, 0, 1, 90, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 90, 0, 0, 2, 18, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 67, 0, 0, 0,213, 0, 0, 2, 18,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 18, 0, 0, 1, 90, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 17,
- 0, 0, 0,134, 0, 0, 1, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 91, 0, 0, 0,243, 0, 0, 2, 17, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 2, 17, 0, 0, 0,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,243, 0, 0, 1, 91,
- 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,211, 0, 0, 0, 66, 0, 0, 2, 19, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 19, 0, 0, 1, 89, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0,211, 0, 0, 1, 89,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 89, 0, 0, 2, 19, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 20,
- 0, 0, 0,133, 0, 0, 2, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 19, 0, 0, 2, 21, 0, 0, 2, 20, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 2, 20, 0, 0, 2, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 21, 0, 0, 2, 19,
- 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,206, 0, 0, 2, 21, 0, 0, 0,210, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 66, 0, 0, 0,210, 0, 0, 2, 21,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 21, 0, 0, 0,206, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 20,
- 0, 0, 0, 64, 0, 0, 0,207, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,207, 0, 0, 1, 88, 0, 0, 2, 20, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,133, 0, 0, 2, 20, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 0,207,
- 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 93, 0, 0, 0,135, 0, 0, 2, 22, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 22, 0, 0, 0,247, 0, 0, 1, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 1, 93, 0, 0, 0,247,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,247, 0, 0, 2, 22, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 23,
- 0, 0, 0, 84, 0, 0, 2, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 22, 0, 0, 2, 24, 0, 0, 2, 23, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 2, 23, 0, 0, 2, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 24, 0, 0, 2, 22,
- 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 92, 0, 0, 0, 25, 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,217, 0, 0, 2, 24, 0, 0, 1, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,135, 0, 0, 1, 92, 0, 0, 2, 24,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 24, 0, 0, 0,217, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 23,
- 0, 0, 0, 69, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,216, 0, 0, 0,246, 0, 0, 2, 23, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 2, 23, 0, 0, 0,246, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,246, 0, 0, 0,216,
- 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 92, 0, 0, 0,135, 0, 0, 2, 25, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 25, 0, 0, 1, 94, 0, 0, 1, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 25, 0, 0, 1, 92, 0, 0, 1, 94,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 94, 0, 0, 2, 25, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 26,
- 0, 0, 0,136, 0, 0, 2, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 25, 0, 0, 2, 27, 0, 0, 2, 26, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,137, 0, 0, 2, 26, 0, 0, 2, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 27, 0, 0, 2, 25,
- 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 93, 0, 0, 0, 33, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 97, 0, 0, 2, 27, 0, 0, 1, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,135, 0, 0, 1, 93, 0, 0, 2, 27,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 27, 0, 0, 1, 97, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 26,
- 0, 0, 0,137, 0, 0, 1, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 96, 0, 0, 1, 95, 0, 0, 2, 26, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,136, 0, 0, 2, 26, 0, 0, 1, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 95, 0, 0, 1, 96,
- 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,220, 0, 0, 0, 71, 0, 0, 2, 28, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 28, 0, 0, 0,248, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0,220, 0, 0, 0,248,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,248, 0, 0, 2, 28, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 29,
- 0, 0, 0, 85, 0, 0, 2, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 28, 0, 0, 2, 30, 0, 0, 2, 29, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,137, 0, 0, 2, 29, 0, 0, 2, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 30, 0, 0, 2, 28,
- 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,221, 0, 0, 0, 26, 0, 0, 1, 96, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 96, 0, 0, 2, 30, 0, 0, 0,221, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 71, 0, 0, 0,221, 0, 0, 2, 30,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 30, 0, 0, 1, 96, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 29,
- 0, 0, 0,137, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 97, 0, 0, 0,249, 0, 0, 2, 29, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 2, 29, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,249, 0, 0, 1, 97,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,219, 0, 0, 0, 70, 0, 0, 2, 31, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 31, 0, 0, 1, 95, 0, 0, 0,219, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0,219, 0, 0, 1, 95,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 95, 0, 0, 2, 31, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 32,
- 0, 0, 0,136, 0, 0, 2, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 31, 0, 0, 2, 33, 0, 0, 2, 32, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 68, 0, 0, 2, 32, 0, 0, 2, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 33, 0, 0, 2, 31,
- 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,218, 0, 0, 0, 2, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,214, 0, 0, 2, 33, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 70, 0, 0, 0,218, 0, 0, 2, 33,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 33, 0, 0, 0,214, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 32,
- 0, 0, 0, 68, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,215, 0, 0, 1, 94, 0, 0, 2, 32, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,136, 0, 0, 2, 32, 0, 0, 1, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 94, 0, 0, 0,215,
- 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 99, 0, 0, 0,138, 0, 0, 2, 34, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 34, 0, 0, 0,251, 0, 0, 1, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 1, 99, 0, 0, 0,251,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,251, 0, 0, 2, 34, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 35,
- 0, 0, 0, 86, 0, 0, 2, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 34, 0, 0, 2, 36, 0, 0, 2, 35, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 73, 0, 0, 2, 35, 0, 0, 2, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 36, 0, 0, 2, 34,
- 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 98, 0, 0, 0, 27, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,225, 0, 0, 2, 36, 0, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 1, 98, 0, 0, 2, 36,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 36, 0, 0, 0,225, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 35,
- 0, 0, 0, 73, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,224, 0, 0, 0,250, 0, 0, 2, 35, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 2, 35, 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,250, 0, 0, 0,224,
- 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 98, 0, 0, 0,138, 0, 0, 2, 37, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 37, 0, 0, 1,100, 0, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 1, 98, 0, 0, 1,100,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,100, 0, 0, 2, 37, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 38,
- 0, 0, 0,139, 0, 0, 2, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 37, 0, 0, 2, 39, 0, 0, 2, 38, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,140, 0, 0, 2, 38, 0, 0, 2, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 39, 0, 0, 2, 37,
- 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 99, 0, 0, 0, 34, 0, 0, 1,103, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,103, 0, 0, 2, 39, 0, 0, 1, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 1, 99, 0, 0, 2, 39,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 39, 0, 0, 1,103, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 38,
- 0, 0, 0,140, 0, 0, 1,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,102, 0, 0, 1,101, 0, 0, 2, 38, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,139, 0, 0, 2, 38, 0, 0, 1,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,101, 0, 0, 1,102,
- 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,228, 0, 0, 0, 75, 0, 0, 2, 40, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 40, 0, 0, 0,252, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,228, 0, 0, 0,252,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,252, 0, 0, 2, 40, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 41,
- 0, 0, 0, 87, 0, 0, 2, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 40, 0, 0, 2, 42, 0, 0, 2, 41, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,140, 0, 0, 2, 41, 0, 0, 2, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 42, 0, 0, 2, 40,
- 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,229, 0, 0, 0, 28, 0, 0, 1,102, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,102, 0, 0, 2, 42, 0, 0, 0,229, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 75, 0, 0, 0,229, 0, 0, 2, 42,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 42, 0, 0, 1,102, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 41,
- 0, 0, 0,140, 0, 0, 1,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,103, 0, 0, 0,253, 0, 0, 2, 41, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 2, 41, 0, 0, 0,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,253, 0, 0, 1,103,
- 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,227, 0, 0, 0, 74, 0, 0, 2, 43, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 43, 0, 0, 1,101, 0, 0, 0,227, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0,227, 0, 0, 1,101,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,101, 0, 0, 2, 43, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 44,
- 0, 0, 0,139, 0, 0, 2, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 43, 0, 0, 2, 45, 0, 0, 2, 44, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 2, 44, 0, 0, 2, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 45, 0, 0, 2, 43,
- 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,222, 0, 0, 2, 45, 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 74, 0, 0, 0,226, 0, 0, 2, 45,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 45, 0, 0, 0,222, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 44,
- 0, 0, 0, 72, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,223, 0, 0, 1,100, 0, 0, 2, 44, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,139, 0, 0, 2, 44, 0, 0, 1,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,100, 0, 0, 0,223,
- 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,105, 0, 0, 0,141, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 46, 0, 0, 0,255, 0, 0, 1,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 0,255,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255, 0, 0, 2, 46, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 47,
- 0, 0, 0, 88, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 46, 0, 0, 2, 48, 0, 0, 2, 47, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 77, 0, 0, 2, 47, 0, 0, 2, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 48, 0, 0, 2, 46,
- 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,104, 0, 0, 0, 29, 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,233, 0, 0, 2, 48, 0, 0, 1,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 1,104, 0, 0, 2, 48,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 48, 0, 0, 0,233, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 47,
- 0, 0, 0, 77, 0, 0, 0,232, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,232, 0, 0, 0,254, 0, 0, 2, 47, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 2, 47, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,254, 0, 0, 0,232,
- 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,104, 0, 0, 0,141, 0, 0, 2, 49, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 49, 0, 0, 1,106, 0, 0, 1,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 1,104, 0, 0, 1,106,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,106, 0, 0, 2, 49, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 50,
- 0, 0, 0,142, 0, 0, 2, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 49, 0, 0, 2, 51, 0, 0, 2, 50, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,143, 0, 0, 2, 50, 0, 0, 2, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 51, 0, 0, 2, 49,
- 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,109, 0, 0, 2, 51, 0, 0, 1,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 1,105, 0, 0, 2, 51,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 51, 0, 0, 1,109, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 50,
- 0, 0, 0,143, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,108, 0, 0, 1,107, 0, 0, 2, 50, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,142, 0, 0, 2, 50, 0, 0, 1,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,107, 0, 0, 1,108,
- 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,236, 0, 0, 0, 79, 0, 0, 2, 52, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 52, 0, 0, 1, 0, 0, 0, 0,236, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0,236, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 2, 52, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 53,
- 0, 0, 0, 89, 0, 0, 2, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 52, 0, 0, 2, 54, 0, 0, 2, 53, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,143, 0, 0, 2, 53, 0, 0, 2, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 54, 0, 0, 2, 52,
- 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,237, 0, 0, 0, 30, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,108, 0, 0, 2, 54, 0, 0, 0,237, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 79, 0, 0, 0,237, 0, 0, 2, 54,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 54, 0, 0, 1,108, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 53,
- 0, 0, 0,143, 0, 0, 1,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,109, 0, 0, 1, 1, 0, 0, 2, 53, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 2, 53, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 1,109,
- 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,235, 0, 0, 0, 78, 0, 0, 2, 55, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 55, 0, 0, 1,107, 0, 0, 0,235, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0,235, 0, 0, 1,107,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,107, 0, 0, 2, 55, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 56,
- 0, 0, 0,142, 0, 0, 2, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 55, 0, 0, 2, 57, 0, 0, 2, 56, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 2, 56, 0, 0, 2, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 57, 0, 0, 2, 55,
- 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,234, 0, 0, 0, 4, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,230, 0, 0, 2, 57, 0, 0, 0,234, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 0,234, 0, 0, 2, 57,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 57, 0, 0, 0,230, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 56,
- 0, 0, 0, 76, 0, 0, 0,231, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,231, 0, 0, 1,106, 0, 0, 2, 56, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,142, 0, 0, 2, 56, 0, 0, 1,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,106, 0, 0, 0,231,
- 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,111, 0, 0, 0,144, 0, 0, 2, 58, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 58, 0, 0, 1, 3, 0, 0, 1,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 1,111, 0, 0, 1, 3,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3, 0, 0, 2, 58, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 59,
- 0, 0, 0, 90, 0, 0, 2, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 58, 0, 0, 2, 60, 0, 0, 2, 59, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 81, 0, 0, 2, 59, 0, 0, 2, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 60, 0, 0, 2, 58,
- 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,110, 0, 0, 0, 31, 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,241, 0, 0, 2, 60, 0, 0, 1,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,144, 0, 0, 1,110, 0, 0, 2, 60,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 60, 0, 0, 0,241, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 59,
- 0, 0, 0, 81, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,240, 0, 0, 1, 2, 0, 0, 2, 59, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 90, 0, 0, 2, 59, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 2, 0, 0, 0,240,
- 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,110, 0, 0, 0,144, 0, 0, 2, 61, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 61, 0, 0, 1,113, 0, 0, 1,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 1,110, 0, 0, 1,113,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,113, 0, 0, 2, 61, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 62,
- 0, 0, 0,145, 0, 0, 2, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 61, 0, 0, 2, 63, 0, 0, 2, 62, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 2, 62, 0, 0, 2, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 63, 0, 0, 2, 61,
- 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,111, 0, 0, 0, 36, 0, 0, 1,115, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,115, 0, 0, 2, 63, 0, 0, 1,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,144, 0, 0, 1,111, 0, 0, 2, 63,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 63, 0, 0, 1,115, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 62,
- 0, 0, 0,146, 0, 0, 1,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,114, 0, 0, 1,112, 0, 0, 2, 62, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,145, 0, 0, 2, 62, 0, 0, 1,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,112, 0, 0, 1,114,
- 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,204, 0, 0, 0, 63, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 0,204, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0,204, 0, 0, 1, 4,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 4, 0, 0, 2, 64, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 65,
- 0, 0, 0, 91, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 64, 0, 0, 2, 66, 0, 0, 2, 65, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 2, 65, 0, 0, 2, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 66, 0, 0, 2, 64,
- 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,205, 0, 0, 0, 22, 0, 0, 1,114, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,114, 0, 0, 2, 66, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 63, 0, 0, 0,205, 0, 0, 2, 66,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 66, 0, 0, 1,114, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 65,
- 0, 0, 0,146, 0, 0, 1,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,115, 0, 0, 1, 5, 0, 0, 2, 65, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 91, 0, 0, 2, 65, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 5, 0, 0, 1,115,
- 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,203, 0, 0, 0, 62, 0, 0, 2, 67, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 2, 67, 0, 0, 1,112, 0, 0, 0,203, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 0,203, 0, 0, 1,112,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,112, 0, 0, 2, 67, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 68,
- 0, 0, 0,145, 0, 0, 2, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 67, 0, 0, 2, 69, 0, 0, 2, 68, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 2, 68, 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 69, 0, 0, 2, 67,
- 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,202, 0, 0, 0, 5, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0,238, 0, 0, 2, 69, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 0,202, 0, 0, 2, 69,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 69, 0, 0, 0,238, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 68,
- 0, 0, 0, 80, 0, 0, 0,239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,239, 0, 0, 1,113, 0, 0, 2, 68, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,145, 0, 0, 2, 68, 0, 0, 1,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,113, 0, 0, 0,239,
- 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 70, 0, 0, 0,147, 0, 0, 1,117, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,117, 0, 0, 1, 11, 0, 0, 2, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 94, 0, 0, 2, 70, 0, 0, 1, 11,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 11, 0, 0, 1,117, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 70,
- 0, 0, 0, 94, 0, 0, 2, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 71, 0, 0, 2, 72, 0, 0, 2, 70, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,147, 0, 0, 2, 70, 0, 0, 2, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 72, 0, 0, 2, 71,
- 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,243, 0, 0, 0, 32, 0, 0, 1,116, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,116, 0, 0, 2, 72, 0, 0, 0,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0,243, 0, 0, 2, 72,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 72, 0, 0, 1,116, 0, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,242,
- 0, 0, 0, 82, 0, 0, 2, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 71, 0, 0, 1, 10, 0, 0, 0,242, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0,242, 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 10, 0, 0, 2, 71,
- 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 73, 0, 0, 0,147, 0, 0, 1,116, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,116, 0, 0, 1,118, 0, 0, 2, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,148, 0, 0, 2, 73, 0, 0, 1,118,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,118, 0, 0, 1,116, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 73,
- 0, 0, 0,148, 0, 0, 2, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 74, 0, 0, 2, 75, 0, 0, 2, 73, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,147, 0, 0, 2, 73, 0, 0, 2, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 75, 0, 0, 2, 74,
- 0, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,121, 0, 0, 0, 38, 0, 0, 1,117, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,117, 0, 0, 2, 75, 0, 0, 1,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,149, 0, 0, 1,121, 0, 0, 2, 75,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 75, 0, 0, 1,117, 0, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,120,
- 0, 0, 0,149, 0, 0, 2, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 74, 0, 0, 1,119, 0, 0, 1,120, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 1,120, 0, 0, 1,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,119, 0, 0, 2, 74,
- 0, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 76, 0, 0, 0, 93, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 8, 0, 0, 1, 12, 0, 0, 2, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 2, 76, 0, 0, 1, 12,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 12, 0, 0, 1, 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 76,
- 0, 0, 0, 95, 0, 0, 2, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 77, 0, 0, 2, 78, 0, 0, 2, 76, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 2, 76, 0, 0, 2, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 78, 0, 0, 2, 77,
- 0, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,120, 0, 0, 0, 37, 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 9, 0, 0, 2, 78, 0, 0, 1,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,149, 0, 0, 1,120, 0, 0, 2, 78,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 78, 0, 0, 1, 9, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,121,
- 0, 0, 0,149, 0, 0, 2, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 77, 0, 0, 1, 13, 0, 0, 1,121, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 1,121, 0, 0, 1, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 13, 0, 0, 2, 77,
- 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 79, 0, 0, 0, 92, 0, 0, 1, 7, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 7, 0, 0, 1,119, 0, 0, 2, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,148, 0, 0, 2, 79, 0, 0, 1,119,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,119, 0, 0, 1, 7, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 79,
- 0, 0, 0,148, 0, 0, 2, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 80, 0, 0, 2, 81, 0, 0, 2, 79, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 92, 0, 0, 2, 79, 0, 0, 2, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 81, 0, 0, 2, 80,
- 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,244, 0, 0, 0, 10, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 6, 0, 0, 2, 81, 0, 0, 0,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 83, 0, 0, 0,244, 0, 0, 2, 81,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 81, 0, 0, 1, 6, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,245,
- 0, 0, 0, 83, 0, 0, 2, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 80, 0, 0, 1,118, 0, 0, 0,245, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0,245, 0, 0, 1,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,118, 0, 0, 2, 80,
- 0, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 82, 0, 0, 0,150, 0, 0, 1,123, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,123, 0, 0, 1, 15, 0, 0, 2, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 96, 0, 0, 2, 82, 0, 0, 1, 15,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 15, 0, 0, 1,123, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 82,
- 0, 0, 0, 96, 0, 0, 2, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 83, 0, 0, 2, 84, 0, 0, 2, 82, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 2, 82, 0, 0, 2, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 84, 0, 0, 2, 83,
- 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,249, 0, 0, 0, 33, 0, 0, 1,122, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,122, 0, 0, 2, 84, 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 0,249, 0, 0, 2, 84,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 84, 0, 0, 1,122, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,248,
- 0, 0, 0, 85, 0, 0, 2, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 83, 0, 0, 1, 14, 0, 0, 0,248, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0,248, 0, 0, 1, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 14, 0, 0, 2, 83,
- 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 85, 0, 0, 0,150, 0, 0, 1,122, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,122, 0, 0, 1,124, 0, 0, 2, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,151, 0, 0, 2, 85, 0, 0, 1,124,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 1,122, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 85,
- 0, 0, 0,151, 0, 0, 2, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 86, 0, 0, 2, 87, 0, 0, 2, 85, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 2, 85, 0, 0, 2, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 87, 0, 0, 2, 86,
- 0, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,127, 0, 0, 0, 39, 0, 0, 1,123, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,123, 0, 0, 2, 87, 0, 0, 1,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 1,127, 0, 0, 2, 87,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 87, 0, 0, 1,123, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,126,
- 0, 0, 0,152, 0, 0, 2, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 86, 0, 0, 1,125, 0, 0, 1,126, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 1,126, 0, 0, 1,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,125, 0, 0, 2, 86,
- 0, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 88, 0, 0, 0, 95, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 12, 0, 0, 1, 16, 0, 0, 2, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 97, 0, 0, 2, 88, 0, 0, 1, 16,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 16, 0, 0, 1, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 88,
- 0, 0, 0, 97, 0, 0, 2, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 89, 0, 0, 2, 90, 0, 0, 2, 88, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 2, 88, 0, 0, 2, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 90, 0, 0, 2, 89,
- 0, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,126, 0, 0, 0, 38, 0, 0, 1, 13, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 13, 0, 0, 2, 90, 0, 0, 1,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 1,126, 0, 0, 2, 90,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 90, 0, 0, 1, 13, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,127,
- 0, 0, 0,152, 0, 0, 2, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 89, 0, 0, 1, 17, 0, 0, 1,127, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 1,127, 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 17, 0, 0, 2, 89,
- 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 91, 0, 0, 0, 94, 0, 0, 1, 11, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 11, 0, 0, 1,125, 0, 0, 2, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,151, 0, 0, 2, 91, 0, 0, 1,125,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,125, 0, 0, 1, 11, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 91,
- 0, 0, 0,151, 0, 0, 2, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 92, 0, 0, 2, 93, 0, 0, 2, 91, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 94, 0, 0, 2, 91, 0, 0, 2, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 93, 0, 0, 2, 92,
- 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,246, 0, 0, 0, 6, 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 10, 0, 0, 2, 93, 0, 0, 0,246, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 0,246, 0, 0, 2, 93,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 93, 0, 0, 1, 10, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,247,
- 0, 0, 0, 84, 0, 0, 2, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 92, 0, 0, 1,124, 0, 0, 0,247, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0,247, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 2, 92,
- 0, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 94, 0, 0, 0,153, 0, 0, 1,129, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,129, 0, 0, 1, 19, 0, 0, 2, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 2, 94, 0, 0, 1, 19,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 19, 0, 0, 1,129, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 94,
- 0, 0, 0, 98, 0, 0, 2, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 95, 0, 0, 2, 96, 0, 0, 2, 94, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,153, 0, 0, 2, 94, 0, 0, 2, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 96, 0, 0, 2, 95,
- 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 1,128, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,128, 0, 0, 2, 96, 0, 0, 0,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 0,253, 0, 0, 2, 96,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 96, 0, 0, 1,128, 0, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,252,
- 0, 0, 0, 87, 0, 0, 2, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 95, 0, 0, 1, 18, 0, 0, 0,252, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,252, 0, 0, 1, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 18, 0, 0, 2, 95,
- 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 97, 0, 0, 0,153, 0, 0, 1,128, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,128, 0, 0, 1,130, 0, 0, 2, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 2, 97, 0, 0, 1,130,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,130, 0, 0, 1,128, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 97,
- 0, 0, 0,154, 0, 0, 2, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 98, 0, 0, 2, 99, 0, 0, 2, 97, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,153, 0, 0, 2, 97, 0, 0, 2, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 99, 0, 0, 2, 98,
- 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,133, 0, 0, 0, 40, 0, 0, 1,129, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,129, 0, 0, 2, 99, 0, 0, 1,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,155, 0, 0, 1,133, 0, 0, 2, 99,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 99, 0, 0, 1,129, 0, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,132,
- 0, 0, 0,155, 0, 0, 2, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 98, 0, 0, 1,131, 0, 0, 1,132, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 1,132, 0, 0, 1,131, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,131, 0, 0, 2, 98,
- 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,100, 0, 0, 0, 97, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 16, 0, 0, 1, 20, 0, 0, 2,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 2,100, 0, 0, 1, 20,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 20, 0, 0, 1, 16, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,100,
- 0, 0, 0, 99, 0, 0, 2,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,101, 0, 0, 2,102, 0, 0, 2,100, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 97, 0, 0, 2,100, 0, 0, 2,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,102, 0, 0, 2,101,
- 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,132, 0, 0, 0, 39, 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 17, 0, 0, 2,102, 0, 0, 1,132, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,155, 0, 0, 1,132, 0, 0, 2,102,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,102, 0, 0, 1, 17, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,133,
- 0, 0, 0,155, 0, 0, 2,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,101, 0, 0, 1, 21, 0, 0, 1,133, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 1,133, 0, 0, 1, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 21, 0, 0, 2,101,
- 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,103, 0, 0, 0, 96, 0, 0, 1, 15, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 15, 0, 0, 1,131, 0, 0, 2,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 2,103, 0, 0, 1,131,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,131, 0, 0, 1, 15, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,103,
- 0, 0, 0,154, 0, 0, 2,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,104, 0, 0, 2,105, 0, 0, 2,103, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 96, 0, 0, 2,103, 0, 0, 2,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,105, 0, 0, 2,104,
- 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,250, 0, 0, 0, 7, 0, 0, 1, 14, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 14, 0, 0, 2,105, 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 0,250, 0, 0, 2,105,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,105, 0, 0, 1, 14, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,251,
- 0, 0, 0, 86, 0, 0, 2,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,104, 0, 0, 1,130, 0, 0, 0,251, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0,251, 0, 0, 1,130, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,130, 0, 0, 2,104,
- 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,106, 0, 0, 0,156, 0, 0, 1,135, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,135, 0, 0, 1, 23, 0, 0, 2,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,100, 0, 0, 2,106, 0, 0, 1, 23,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 23, 0, 0, 1,135, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,106,
- 0, 0, 0,100, 0, 0, 2,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,107, 0, 0, 2,108, 0, 0, 2,106, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,156, 0, 0, 2,106, 0, 0, 2,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,108, 0, 0, 2,107,
- 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,134, 0, 0, 2,108, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 1, 1, 0, 0, 2,108,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,108, 0, 0, 1,134, 0, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0,
- 0, 0, 0, 89, 0, 0, 2,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,107, 0, 0, 1, 22, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 1, 0, 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 22, 0, 0, 2,107,
- 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,109, 0, 0, 0,156, 0, 0, 1,134, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,134, 0, 0, 1,136, 0, 0, 2,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,157, 0, 0, 2,109, 0, 0, 1,136,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,136, 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,109,
- 0, 0, 0,157, 0, 0, 2,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,110, 0, 0, 2,111, 0, 0, 2,109, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,156, 0, 0, 2,109, 0, 0, 2,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,111, 0, 0, 2,110,
- 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,139, 0, 0, 0, 41, 0, 0, 1,135, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,135, 0, 0, 2,111, 0, 0, 1,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 1,139, 0, 0, 2,111,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,111, 0, 0, 1,135, 0, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,138,
- 0, 0, 0,158, 0, 0, 2,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,110, 0, 0, 1,137, 0, 0, 1,138, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 1,138, 0, 0, 1,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,137, 0, 0, 2,110,
- 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,112, 0, 0, 0, 99, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 20, 0, 0, 1, 24, 0, 0, 2,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 2,112, 0, 0, 1, 24,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 24, 0, 0, 1, 20, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,112,
- 0, 0, 0,101, 0, 0, 2,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,113, 0, 0, 2,114, 0, 0, 2,112, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 2,112, 0, 0, 2,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,114, 0, 0, 2,113,
- 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,138, 0, 0, 0, 40, 0, 0, 1, 21, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 21, 0, 0, 2,114, 0, 0, 1,138, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 1,138, 0, 0, 2,114,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,114, 0, 0, 1, 21, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,139,
- 0, 0, 0,158, 0, 0, 2,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,113, 0, 0, 1, 25, 0, 0, 1,139, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 1,139, 0, 0, 1, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 25, 0, 0, 2,113,
- 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,115, 0, 0, 0, 98, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 19, 0, 0, 1,137, 0, 0, 2,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,157, 0, 0, 2,115, 0, 0, 1,137,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,137, 0, 0, 1, 19, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,115,
- 0, 0, 0,157, 0, 0, 2,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,116, 0, 0, 2,117, 0, 0, 2,115, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 2,115, 0, 0, 2,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,117, 0, 0, 2,116,
- 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,254, 0, 0, 0, 8, 0, 0, 1, 18, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 18, 0, 0, 2,117, 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 0,254, 0, 0, 2,117,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,117, 0, 0, 1, 18, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255,
- 0, 0, 0, 88, 0, 0, 2,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,116, 0, 0, 1,136, 0, 0, 0,255, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 1,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,136, 0, 0, 2,116,
- 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,118, 0, 0, 0,159, 0, 0, 1,141, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,141, 0, 0, 1, 7, 0, 0, 2,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 92, 0, 0, 2,118, 0, 0, 1, 7,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 7, 0, 0, 1,141, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,118,
- 0, 0, 0, 92, 0, 0, 2,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,119, 0, 0, 2,120, 0, 0, 2,118, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,159, 0, 0, 2,118, 0, 0, 2,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,120, 0, 0, 2,119,
- 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 5, 0, 0, 0, 36, 0, 0, 1,140, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,140, 0, 0, 2,120, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 91, 0, 0, 1, 5, 0, 0, 2,120,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,120, 0, 0, 1,140, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 4,
- 0, 0, 0, 91, 0, 0, 2,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,119, 0, 0, 1, 6, 0, 0, 1, 4, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 1, 4, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 6, 0, 0, 2,119,
- 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,121, 0, 0, 0,159, 0, 0, 1,140, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,140, 0, 0, 1,142, 0, 0, 2,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 2,121, 0, 0, 1,142,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,142, 0, 0, 1,140, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,121,
- 0, 0, 0,160, 0, 0, 2,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,122, 0, 0, 2,123, 0, 0, 2,121, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,159, 0, 0, 2,121, 0, 0, 2,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,123, 0, 0, 2,122,
- 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,144, 0, 0, 0, 37, 0, 0, 1,141, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1,141, 0, 0, 2,123, 0, 0, 1,144, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,161, 0, 0, 1,144, 0, 0, 2,123,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,123, 0, 0, 1,141, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,145,
- 0, 0, 0,161, 0, 0, 2,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,122, 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 1,145, 0, 0, 1,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 2,122,
- 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,124, 0, 0, 0,101, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 24, 0, 0, 1, 8, 0, 0, 2,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 2,124, 0, 0, 1, 8,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 8, 0, 0, 1, 24, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,124,
- 0, 0, 0, 93, 0, 0, 2,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,125, 0, 0, 2,126, 0, 0, 2,124, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 2,124, 0, 0, 2,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,126, 0, 0, 2,125,
- 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,145, 0, 0, 0, 41, 0, 0, 1, 25, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 25, 0, 0, 2,126, 0, 0, 1,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,161, 0, 0, 1,145, 0, 0, 2,126,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,126, 0, 0, 1, 25, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,144,
- 0, 0, 0,161, 0, 0, 2,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,125, 0, 0, 1, 9, 0, 0, 1,144, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 1,144, 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 9, 0, 0, 2,125,
- 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,127, 0, 0, 0,100, 0, 0, 1, 23, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 23, 0, 0, 1,143, 0, 0, 2,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 2,127, 0, 0, 1,143,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 1, 23, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,127,
- 0, 0, 0,160, 0, 0, 2,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,128, 0, 0, 2,129, 0, 0, 2,127, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0,100, 0, 0, 2,127, 0, 0, 2,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,129, 0, 0, 2,128,
- 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 2, 0, 0, 0, 9, 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 1, 22, 0, 0, 2,129, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 90, 0, 0, 1, 2, 0, 0, 2,129,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,129, 0, 0, 1, 22, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3,
- 0, 0, 0, 90, 0, 0, 2,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,128, 0, 0, 1,142, 0, 0, 1, 3, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 1, 3, 0, 0, 1,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,142, 0, 0, 2,128,
- 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 3, 68, 65, 84, 65, 0, 0,220, 0, 8,108,128, 32, 0, 0, 0, 60, 0, 0, 5, 0,
- 63,110,222,166, 63, 55,205, 9, 63,105,132,212, 63, 65,236,201, 63,103,153,218, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,103,153,218, 63, 54,155,119, 63,108,148,118, 63, 44,160,211, 63,110,222,166,
- 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 36, 63, 45, 28, 36,
- 63,110,222,166, 63, 55,205, 9, 63,108,148,118, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,108,148,118, 63, 44,160,211, 63,103,153,218, 63, 54,155,119, 63,102, 17, 87, 63, 43, 52,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 96, 81, 56, 63, 52, 55,170, 63,102, 17, 87, 63, 43, 52,229,
- 63,103,153,218, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,103,153,218,
- 63, 54,155,119, 63, 97, 75, 9, 63, 63,233, 92, 63, 96, 81, 56, 63, 52, 55,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63, 60, 86, 49, 63, 96, 81, 56, 63, 52, 55,170, 63, 97, 75, 9, 63, 63,233, 92,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 97, 75, 9, 63, 63,233, 92, 63,103,153,218,
- 63, 54,155,119, 63,105,132,212, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 98,167,103, 63, 75, 39,168, 63, 89,153,138, 63, 82,228, 39, 63, 89,153,139, 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,139, 63, 71,153,255, 63, 97, 75, 9, 63, 63,233, 92, 63, 98,167,103,
- 63, 75, 39,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,132,212, 63, 65,236,201,
- 63, 98,167,103, 63, 75, 39,168, 63, 97, 75, 9, 63, 63,233, 92, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 97, 75, 9, 63, 63,233, 92, 63, 89,153,139, 63, 71,153,255, 63, 89,153,138, 63, 60, 86, 49, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 96, 81, 56, 63, 52, 55,170, 63, 89,153,138, 63, 60, 86, 49,
- 63, 89,153,139, 63, 49, 12, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,139,
- 63, 49, 12, 79, 63, 95,182,205, 63, 40,228,222, 63, 96, 81, 56, 63, 52, 55,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,102, 17, 87, 63, 43, 52,229, 63, 96, 81, 56, 63, 52, 55,170, 63, 95,182,205, 63, 40,228,222,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 95,182,205, 63, 40,228,222, 63, 89,153,139,
- 63, 49, 12, 79, 63, 89,153,139, 63, 37,200, 45, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 98,167,103, 63, 75, 39,168, 63,105,132,212, 63, 65,236,201, 63,109, 83,168, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,109, 83,168, 63, 78, 83,207, 63,101, 85,135, 63, 88, 64,148, 63, 98,167,103,
- 63, 75, 39,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63, 82,228, 39,
- 63, 98,167,103, 63, 75, 39,168, 63,101, 85,135, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,101, 85,135, 63, 88, 64,148, 63,109, 83,168, 63, 78, 83,207, 63,115, 51, 36, 63, 90, 56, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121, 18,162, 63, 78, 83,207, 63,115, 51, 36, 63, 90, 56, 22,
- 63,109, 83,168, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,109, 83,168,
- 63, 78, 83,207, 63,115, 51, 36, 63, 67, 23,115, 63,121, 18,162, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,124,225,116, 63, 65,236,202, 63,121, 18,162, 63, 78, 83,207, 63,115, 51, 36, 63, 67, 23,115,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 36, 63, 67, 23,115, 63,109, 83,168,
- 63, 78, 83,207, 63,105,132,212, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,110,222,166, 63, 55,205, 9, 63,115, 51, 36, 63, 45, 28, 36, 63,119,135,163, 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,119,135,163, 63, 55,205, 11, 63,115, 51, 36, 63, 67, 23,115, 63,110,222,166,
- 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,132,212, 63, 65,236,201,
- 63,110,222,166, 63, 55,205, 9, 63,115, 51, 36, 63, 67, 23,115, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,115, 51, 36, 63, 67, 23,115, 63,119,135,163, 63, 55,205, 11, 63,124,225,116, 63, 65,236,202, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121, 18,162, 63, 78, 83,207, 63,124,225,116, 63, 65,236,202,
- 63,129,223,113, 63, 75, 39,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,129,223,113,
- 63, 75, 39,170, 63,128,136, 98, 63, 88, 64,148, 63,121, 18,162, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 36, 63, 90, 56, 22, 63,121, 18,162, 63, 78, 83,207, 63,128,136, 98, 63, 88, 64,148,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 59,136, 98, 95, 63, 88, 64,148, 60,111,184,160,
- 63, 75, 39,170, 61, 76,203,243, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61, 76,203,243, 63, 49, 12, 82, 61, 76,203,246, 63, 60, 86, 53, 60,194,162, 31, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,194,162, 31, 63, 52, 55,172, 60,213,239,111, 63, 40,228,223, 61, 76,203,243,
- 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,246, 63, 37,200, 48,
- 61, 76,203,243, 63, 49, 12, 82, 60,213,239,111, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 60,213,239,111, 63, 40,228,223, 60,194,162, 31, 63, 52, 55,172, 58,169,226,120, 63, 43, 52,230, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,126,204,111, 63, 54,155,121, 63,128, 42,121, 63, 43, 52,230,
- 63,131, 10,136, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,131, 10,136,
- 63, 52, 55,172, 63,130,141,160, 63, 63,233, 95, 63,126,204,111, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,124,225,116, 63, 65,236,202, 63,126,204,111, 63, 54,155,121, 63,130,141,160, 63, 63,233, 95,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,163,104, 11, 63, 63,233, 95, 60,194,162, 31,
- 63, 52, 55,172, 61, 76,203,246, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61, 76,203,244, 63, 71,154, 2, 61, 76,203,243, 63, 82,228, 41, 60,111,184,160, 63, 75, 39,170, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,111,184,160, 63, 75, 39,170, 60,163,104, 11, 63, 63,233, 95, 61, 76,203,244,
- 63, 71,154, 2, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,246, 63, 60, 86, 53,
- 61, 76,203,244, 63, 71,154, 2, 60,163,104, 11, 63, 63,233, 95, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,130,141,160, 63, 63,233, 95, 63,129,223,113, 63, 75, 39,170, 63,124,225,116, 63, 65,236,202, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,126,204,111, 63, 54,155,121, 63,124,225,116, 63, 65,236,202,
- 63,119,135,163, 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,119,135,163,
- 63, 55,205, 11, 63,121,209,210, 63, 44,160,212, 63,126,204,111, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,128, 42,121, 63, 43, 52,230, 63,126,204,111, 63, 54,155,121, 63,121,209,210, 63, 44,160,212,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121,209,210, 63, 44,160,212, 63,119,135,163,
- 63, 55,205, 11, 63,115, 51, 36, 63, 45, 28, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,134,102, 95, 63, 94, 46, 79, 63,134,102, 95, 63,105,114, 22, 63,124,205, 52, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,124,205, 52, 63, 99, 26, 58, 63,128,136, 98, 63, 88, 64,148, 63,134,102, 95,
- 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,243, 63, 82,228, 41,
- 61, 76,203,234, 63, 94, 46, 79, 59,136, 98, 95, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,128,136, 98, 63, 88, 64,148, 63,124,205, 52, 63, 99, 26, 58, 63,115, 51, 36, 63, 90, 56, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,153, 21, 63, 99, 26, 58, 63,115, 51, 36, 63, 90, 56, 22,
- 63,124,205, 52, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,124,205, 52,
- 63, 99, 26, 58, 63,115, 51, 32, 63,109,154,212, 63,105,153, 21, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63,105,114, 19, 63,105,153, 21, 63, 99, 26, 58, 63,115, 51, 32, 63,109,154,212,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 32, 63,109,154,212, 63,124,205, 52,
- 63, 99, 26, 58, 63,134,102, 95, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,134,102, 95, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 63, 89,153,136, 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,136, 63,116,187,242, 63,115, 51, 32, 63,109,154,212, 63,134,102, 95,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,134,102, 95, 63,105,114, 22,
- 63,134,102, 95, 63,116,187,242, 63,115, 51, 32, 63,109,154,212, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,115, 51, 32, 63,109,154,212, 63, 89,153,136, 63,116,187,242, 63, 89,153,138, 63,105,114, 19, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,153, 21, 63, 99, 26, 58, 63, 89,153,138, 63,105,114, 19,
- 63, 89,153,138, 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138,
- 63, 94, 46, 77, 63,101, 85,135, 63, 88, 64,148, 63,105,153, 21, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 36, 63, 90, 56, 22, 63,105,153, 21, 63, 99, 26, 58, 63,101, 85,135, 63, 88, 64,148,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,101, 85,135, 63, 88, 64,148, 63, 89,153,138,
- 63, 94, 46, 77, 63, 89,153,138, 63, 82,228, 39, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 75,153, 67, 63, 54,155,113, 63, 73,174, 74, 63, 65,236,193, 63, 68, 84,124, 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 68, 84,124, 63, 55,204,255, 63, 70,158,169, 63, 44,160,200, 63, 75,153, 67,
- 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 77, 33,196, 63, 43, 52,221,
- 63, 75,153, 67, 63, 54,155,113, 63, 70,158,169, 63, 44,160,200, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 70,158,169, 63, 44,160,200, 63, 68, 84,124, 63, 55,204,255, 63, 64, 0, 0, 63, 45, 28, 24, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 75,153, 67, 63, 54,155,113, 63, 77, 33,196, 63, 43, 52,221,
- 63, 82,225,225, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,225,225,
- 63, 52, 55,165, 63, 81,232, 16, 63, 63,233, 89, 63, 75,153, 67, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,174, 74, 63, 65,236,193, 63, 75,153, 67, 63, 54,155,113, 63, 81,232, 16, 63, 63,233, 89,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 81,232, 16, 63, 63,233, 89, 63, 82,225,225,
- 63, 52, 55,165, 63, 89,153,138, 63, 60, 86, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 89,153,139, 63, 71,153,255, 63, 89,153,138, 63, 82,228, 39, 63, 80,139,179, 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 80,139,179, 63, 75, 39,164, 63, 81,232, 16, 63, 63,233, 89, 63, 89,153,139,
- 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63, 60, 86, 49,
- 63, 89,153,139, 63, 71,153,255, 63, 81,232, 16, 63, 63,233, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 81,232, 16, 63, 63,233, 89, 63, 80,139,179, 63, 75, 39,164, 63, 73,174, 74, 63, 65,236,193, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,139, 63, 49, 12, 79, 63, 89,153,138, 63, 60, 86, 49,
- 63, 82,225,225, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,225,225,
- 63, 52, 55,165, 63, 83,124, 75, 63, 40,228,217, 63, 89,153,139, 63, 49, 12, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,139, 63, 37,200, 45, 63, 89,153,139, 63, 49, 12, 79, 63, 83,124, 75, 63, 40,228,217,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 83,124, 75, 63, 40,228,217, 63, 82,225,225,
- 63, 52, 55,165, 63, 77, 33,196, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 69,223,120, 63, 78, 83,198, 63, 73,174, 74, 63, 65,236,193, 63, 80,139,179, 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 80,139,179, 63, 75, 39,164, 63, 77,221,148, 63, 88, 64,140, 63, 69,223,120,
- 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 90, 56, 12,
- 63, 69,223,120, 63, 78, 83,198, 63, 77,221,148, 63, 88, 64,140, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 77,221,148, 63, 88, 64,140, 63, 80,139,179, 63, 75, 39,164, 63, 89,153,138, 63, 82,228, 39, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 69,223,120, 63, 78, 83,198, 63, 64, 0, 0, 63, 90, 56, 12,
- 63, 58, 32,136, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 58, 32,136,
- 63, 78, 83,198, 63, 64, 0, 0, 63, 67, 23,106, 63, 69,223,120, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,174, 74, 63, 65,236,193, 63, 69,223,120, 63, 78, 83,198, 63, 64, 0, 0, 63, 67, 23,106,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 67, 23,106, 63, 58, 32,136,
- 63, 78, 83,198, 63, 54, 81,182, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 59,171,132, 63, 55,204,255, 63, 64, 0, 0, 63, 45, 28, 24, 63, 68, 84,124, 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 68, 84,124, 63, 55,204,255, 63, 64, 0, 0, 63, 67, 23,106, 63, 59,171,132,
- 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 81,182, 63, 65,236,193,
- 63, 59,171,132, 63, 55,204,255, 63, 64, 0, 0, 63, 67, 23,106, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 64, 0, 0, 63, 67, 23,106, 63, 68, 84,124, 63, 55,204,255, 63, 73,174, 74, 63, 65,236,193, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 47,116, 77, 63, 75, 39,164, 63, 54, 81,182, 63, 65,236,193,
- 63, 58, 32,136, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 58, 32,136,
- 63, 78, 83,198, 63, 50, 34,108, 63, 88, 64,140, 63, 47,116, 77, 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,118, 63, 82,228, 38, 63, 47,116, 77, 63, 75, 39,164, 63, 50, 34,108, 63, 88, 64,140,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 50, 34,108, 63, 88, 64,140, 63, 58, 32,136,
- 63, 78, 83,198, 63, 64, 0, 0, 63, 90, 56, 12, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 45, 30, 31, 63, 52, 55,165, 63, 38,102,117, 63, 60, 86, 50, 63, 38,102,117, 63, 49, 12, 78, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 49, 12, 78, 63, 44,131,181, 63, 40,228,216, 63, 45, 30, 31,
- 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 50,222, 60, 63, 43, 52,221,
- 63, 45, 30, 31, 63, 52, 55,165, 63, 44,131,181, 63, 40,228,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 44,131,181, 63, 40,228,216, 63, 38,102,117, 63, 49, 12, 78, 63, 38,102,117, 63, 37,200, 45, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 30, 31, 63, 52, 55,165, 63, 50,222, 60, 63, 43, 52,221,
- 63, 52,102,189, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 52,102,189,
- 63, 54,155,113, 63, 46, 23,240, 63, 63,233, 89, 63, 45, 30, 31, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 60, 86, 50, 63, 45, 30, 31, 63, 52, 55,165, 63, 46, 23,240, 63, 63,233, 89,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 46, 23,240, 63, 63,233, 89, 63, 52,102,189,
- 63, 54,155,113, 63, 54, 81,182, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 47,116, 77, 63, 75, 39,164, 63, 38,102,118, 63, 82,228, 38, 63, 38,102,117, 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 71,153,255, 63, 46, 23,240, 63, 63,233, 89, 63, 47,116, 77,
- 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 81,182, 63, 65,236,193,
- 63, 47,116, 77, 63, 75, 39,164, 63, 46, 23,240, 63, 63,233, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 46, 23,240, 63, 63,233, 89, 63, 38,102,117, 63, 71,153,255, 63, 38,102,117, 63, 60, 86, 50, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 59,171,132, 63, 55,204,255, 63, 54, 81,182, 63, 65,236,193,
- 63, 52,102,189, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 52,102,189,
- 63, 54,155,113, 63, 57, 97, 87, 63, 44,160,200, 63, 59,171,132, 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 45, 28, 24, 63, 59,171,132, 63, 55,204,255, 63, 57, 97, 87, 63, 44,160,200,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 97, 87, 63, 44,160,200, 63, 52,102,189,
- 63, 54,155,113, 63, 50,222, 60, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 54,101,250, 63, 99, 26, 51, 63, 38,102,118, 63,105,114, 19, 63, 38,102,118, 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,118, 63, 94, 46, 77, 63, 50, 34,108, 63, 88, 64,140, 63, 54,101,250,
- 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 90, 56, 12,
- 63, 54,101,250, 63, 99, 26, 51, 63, 50, 34,108, 63, 88, 64,140, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 50, 34,108, 63, 88, 64,140, 63, 38,102,118, 63, 94, 46, 77, 63, 38,102,118, 63, 82,228, 38, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54,101,250, 63, 99, 26, 51, 63, 64, 0, 0, 63, 90, 56, 12,
- 63, 73,154, 6, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,154, 6,
- 63, 99, 26, 51, 63, 64, 0, 0, 63,109,154,206, 63, 54,101,250, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,118, 63,105,114, 19, 63, 54,101,250, 63, 99, 26, 51, 63, 64, 0, 0, 63,109,154,206,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63,109,154,206, 63, 73,154, 6,
- 63, 99, 26, 51, 63, 89,153,138, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 89,153,136, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 63, 38,102,120, 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,120, 63,116,187,242, 63, 64, 0, 0, 63,109,154,206, 63, 89,153,136,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63,105,114, 19,
- 63, 89,153,136, 63,116,187,242, 63, 64, 0, 0, 63,109,154,206, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 64, 0, 0, 63,109,154,206, 63, 38,102,120, 63,116,187,242, 63, 38,102,118, 63,105,114, 19, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63, 94, 46, 77, 63, 89,153,138, 63,105,114, 19,
- 63, 73,154, 6, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,154, 6,
- 63, 99, 26, 51, 63, 77,221,148, 63, 88, 64,140, 63, 89,153,138, 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,138, 63, 82,228, 39, 63, 89,153,138, 63, 94, 46, 77, 63, 77,221,148, 63, 88, 64,140,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 77,221,148, 63, 88, 64,140, 63, 73,154, 6,
- 63, 99, 26, 51, 63, 64, 0, 0, 63, 90, 56, 12, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 8, 71,167, 63, 55,205, 7, 61,229,192,170, 63, 65,236,200, 61,214,104,203, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,214,104,203, 63, 54,155,120, 61,254, 61,201, 63, 44,160,207, 62, 8, 71,167,
- 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,173, 63, 45, 28, 27,
- 62, 8, 71,167, 63, 55,205, 7, 61,254, 61,201, 63, 44,160,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,254, 61,201, 63, 44,160,207, 61,214,104,203, 63, 54,155,120, 61,202, 36,175, 63, 43, 52,228, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,156, 35,145, 63, 52, 55,172, 61,202, 36,175, 63, 43, 52,228,
- 61,214,104,203, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,214,104,203,
- 63, 54,155,120, 61,163,242, 32, 63, 63,233, 96, 61,156, 35,145, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,246, 63, 60, 86, 53, 61,156, 35,145, 63, 52, 55,172, 61,163,242, 32, 63, 63,233, 96,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,163,242, 32, 63, 63,233, 96, 61,214,104,203,
- 63, 54,155,120, 61,229,192,170, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,174,213, 17, 63, 75, 39,171, 61, 76,203,243, 63, 82,228, 41, 61, 76,203,244, 63, 71,154, 2, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,244, 63, 71,154, 2, 61,163,242, 32, 63, 63,233, 96, 61,174,213, 17,
- 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,229,192,170, 63, 65,236,200,
- 61,174,213, 17, 63, 75, 39,171, 61,163,242, 32, 63, 63,233, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,163,242, 32, 63, 63,233, 96, 61, 76,203,244, 63, 71,154, 2, 61, 76,203,246, 63, 60, 86, 53, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,156, 35,145, 63, 52, 55,172, 61, 76,203,246, 63, 60, 86, 53,
- 61, 76,203,243, 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,243,
- 63, 49, 12, 82, 61,151, 80, 53, 63, 40,228,223, 61,156, 35,145, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,202, 36,175, 63, 43, 52,228, 61,156, 35,145, 63, 52, 55,172, 61,151, 80, 53, 63, 40,228,223,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,151, 80, 53, 63, 40,228,223, 61, 76,203,243,
- 63, 49, 12, 82, 61, 76,203,246, 63, 37,200, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,174,213, 17, 63, 75, 39,171, 61,229,192,170, 63, 65,236,200, 62, 2, 27,169, 63, 78, 83,204, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 2, 27,169, 63, 78, 83,204, 61,196, 70, 23, 63, 88, 64,147, 61,174,213, 17,
- 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,243, 63, 82,228, 41,
- 61,174,213, 17, 63, 75, 39,171, 61,196, 70, 23, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,196, 70, 23, 63, 88, 64,147, 62, 2, 27,169, 63, 78, 83,204, 62, 25,153,160, 63, 90, 56, 14, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 49, 23,162, 63, 78, 83,195, 62, 25,153,160, 63, 90, 56, 14,
- 62, 2, 27,169, 63, 78, 83,204, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 2, 27,169,
- 63, 78, 83,204, 62, 25,153,172, 63, 67, 23,108, 62, 49, 23,162, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 64, 82,240, 63, 65,236,183, 62, 49, 23,162, 63, 78, 83,195, 62, 25,153,172, 63, 67, 23,108,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,172, 63, 67, 23,108, 62, 2, 27,169,
- 63, 78, 83,204, 61,229,192,170, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 8, 71,167, 63, 55,205, 7, 62, 25,153,173, 63, 45, 28, 27, 62, 42,235,173, 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 42,235,173, 63, 55,204,254, 62, 25,153,172, 63, 67, 23,108, 62, 8, 71,167,
- 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,229,192,170, 63, 65,236,200,
- 62, 8, 71,167, 63, 55,205, 7, 62, 25,153,172, 63, 67, 23,108, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 25,153,172, 63, 67, 23,108, 62, 42,235,173, 63, 55,204,254, 62, 64, 82,240, 63, 65,236,183, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 49, 23,162, 63, 78, 83,195, 62, 64, 82,240, 63, 65,236,183,
- 62, 91,200,166, 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 91,200,166,
- 63, 75, 39,147, 62, 81, 16, 34, 63, 88, 64,131, 62, 49, 23,162, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,160, 63, 90, 56, 14, 62, 49, 23,162, 63, 78, 83,195, 62, 81, 16, 34, 63, 88, 64,131,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 81, 16, 34, 63, 88, 64,131, 62, 91,200,166,
- 63, 75, 39,147, 62,128, 0, 0, 63, 82,228, 13, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,128, 0, 0, 63, 49, 12, 47, 62,128, 0, 0, 63, 60, 86, 19, 62,101, 33, 92, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,101, 33, 92, 63, 52, 55,146, 62,103,139, 14, 63, 40,228,199, 62,128, 0, 0,
- 63, 49, 12, 47, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 37,200, 23,
- 62,128, 0, 0, 63, 49, 12, 47, 62,103,139, 14, 63, 40,228,199, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,103,139, 14, 63, 40,228,199, 62,101, 33, 92, 63, 52, 55,146, 62, 78, 32,230, 63, 43, 52,211, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 71,254,223, 63, 54,155,102, 62, 78, 32,230, 63, 43, 52,211,
- 62,101, 33, 92, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,101, 33, 92,
- 63, 52, 55,146, 62, 97, 58, 23, 63, 63,233, 69, 62, 71,254,223, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 64, 82,240, 63, 65,236,183, 62, 71,254,223, 63, 54,155,102, 62, 97, 58, 23, 63, 63,233, 69,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 97, 58, 23, 63, 63,233, 69, 62,101, 33, 92,
- 63, 52, 55,146, 62,128, 0, 0, 63, 60, 86, 19, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,128, 0, 0, 63, 71,153,228, 62,128, 0, 0, 63, 82,228, 13, 62, 91,200,166, 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 91,200,166, 63, 75, 39,147, 62, 97, 58, 23, 63, 63,233, 69, 62,128, 0, 0,
- 63, 71,153,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 60, 86, 19,
- 62,128, 0, 0, 63, 71,153,228, 62, 97, 58, 23, 63, 63,233, 69, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 97, 58, 23, 63, 63,233, 69, 62, 91,200,166, 63, 75, 39,147, 62, 64, 82,240, 63, 65,236,183, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 71,254,223, 63, 54,155,102, 62, 64, 82,240, 63, 65,236,183,
- 62, 42,235,173, 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 42,235,173,
- 63, 55,204,254, 62, 52, 20,105, 63, 44,160,198, 62, 71,254,223, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 78, 32,230, 63, 43, 52,211, 62, 71,254,223, 63, 54,155,102, 62, 52, 20,105, 63, 44,160,198,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 52, 20,105, 63, 44,160,198, 62, 42,235,173,
- 63, 55,204,254, 62, 25,153,173, 63, 45, 28, 27, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,128, 0, 0, 63, 94, 46, 58, 62,128, 0, 0, 63,105,114, 8, 62, 64, 1,230, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 64, 1,230, 63, 99, 26, 49, 62, 81, 16, 34, 63, 88, 64,131, 62,128, 0, 0,
- 63, 94, 46, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 82,228, 13,
- 62,128, 0, 0, 63, 94, 46, 58, 62, 81, 16, 34, 63, 88, 64,131, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 81, 16, 34, 63, 88, 64,131, 62, 64, 1,230, 63, 99, 26, 49, 62, 25,153,160, 63, 90, 56, 14, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,230, 98,164, 63, 99, 26, 58, 62, 25,153,160, 63, 90, 56, 14,
- 62, 64, 1,230, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 64, 1,230,
- 63, 99, 26, 49, 62, 25,153,159, 63,109,154,210, 61,230, 98,164, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,237, 63,105,114, 22, 61,230, 98,164, 63, 99, 26, 58, 62, 25,153,159, 63,109,154,210,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,159, 63,109,154,210, 62, 64, 1,230,
- 63, 99, 26, 49, 62,128, 0, 0, 63,105,114, 8, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,128, 0, 0, 63,116,187,232, 63, 59,153, 3, 63,128, 0, 0, 63,134,102, 95, 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,210, 63,116,187,242, 62, 25,153,159, 63,109,154,210, 62,128, 0, 0,
- 63,116,187,232, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63,105,114, 8,
- 62,128, 0, 0, 63,116,187,232, 62, 25,153,159, 63,109,154,210, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 25,153,159, 63,109,154,210, 61, 76,203,210, 63,116,187,242, 61, 76,203,237, 63,105,114, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,230, 98,164, 63, 99, 26, 58, 61, 76,203,237, 63,105,114, 22,
- 61, 76,203,234, 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,234,
- 63, 94, 46, 79, 61,196, 70, 23, 63, 88, 64,147, 61,230, 98,164, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,160, 63, 90, 56, 14, 61,230, 98,164, 63, 99, 26, 58, 61,196, 70, 23, 63, 88, 64,147,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,196, 70, 23, 63, 88, 64,147, 61, 76,203,234,
- 63, 94, 46, 79, 61, 76,203,243, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,170,138, 42, 63, 55,204,254, 62,159,214,136, 63, 65,236,183, 62,156, 0,145, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,156, 0,145, 63, 54,155,102, 62,165,245,204, 63, 44,160,198, 62,170,138, 42,
- 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 42, 63, 45, 28, 28,
- 62,170,138, 42, 63, 55,204,254, 62,165,245,204, 63, 44,160,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,165,245,204, 63, 44,160,198, 62,156, 0,145, 63, 54,155,102, 62,152,239,141, 63, 43, 52,211, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,141,111, 82, 63, 52, 55,146, 62,152,239,141, 63, 43, 52,211,
- 62,156, 0,145, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,156, 0,145,
- 63, 54,155,102, 62,143, 98,245, 63, 63,233, 68, 62,141,111, 82, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 60, 86, 19, 62,141,111, 82, 63, 52, 55,146, 62,143, 98,245, 63, 63,233, 68,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,143, 98,245, 63, 63,233, 68, 62,156, 0,145,
- 63, 54,155,102, 62,159,214,136, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,146, 27,173, 63, 75, 39,147, 62,128, 0, 0, 63, 82,228, 13, 62,128, 0, 0, 63, 71,153,228, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 71,153,228, 62,143, 98,245, 63, 63,233, 68, 62,146, 27,173,
- 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,214,136, 63, 65,236,183,
- 62,146, 27,173, 63, 75, 39,147, 62,143, 98,245, 63, 63,233, 68, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,143, 98,245, 63, 63,233, 68, 62,128, 0, 0, 63, 71,153,228, 62,128, 0, 0, 63, 60, 86, 19, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,141,111, 82, 63, 52, 55,146, 62,128, 0, 0, 63, 60, 86, 19,
- 62,128, 0, 0, 63, 49, 12, 47, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0,
- 63, 49, 12, 47, 62,140, 58,121, 63, 40,228,199, 62,141,111, 82, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,152,239,141, 63, 43, 52,211, 62,141,111, 82, 63, 52, 55,146, 62,140, 58,121, 63, 40,228,199,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,140, 58,121, 63, 40,228,199, 62,128, 0, 0,
- 63, 49, 12, 47, 62,128, 0, 0, 63, 37,200, 23, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,146, 27,173, 63, 75, 39,147, 62,159,214,136, 63, 65,236,183, 62,167,116, 47, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,167,116, 47, 63, 78, 83,195, 62,151,119,239, 63, 88, 64,131, 62,146, 27,173,
- 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 82,228, 13,
- 62,146, 27,173, 63, 75, 39,147, 62,151,119,239, 63, 88, 64,131, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,151,119,239, 63, 88, 64,131, 62,167,116, 47, 63, 78, 83,195, 62,179, 51, 49, 63, 90, 56, 14, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,190,242, 44, 63, 78, 83,205, 62,179, 51, 49, 63, 90, 56, 14,
- 62,167,116, 47, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,167,116, 47,
- 63, 78, 83,195, 62,179, 51, 42, 63, 67, 23,108, 62,190,242, 44, 63, 78, 83,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,198,143,214, 63, 65,236,200, 62,190,242, 44, 63, 78, 83,205, 62,179, 51, 42, 63, 67, 23,108,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 42, 63, 67, 23,108, 62,167,116, 47,
- 63, 78, 83,195, 62,159,214,136, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,170,138, 42, 63, 55,204,254, 62,179, 51, 42, 63, 45, 28, 28, 62,187,220, 45, 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,187,220, 45, 63, 55,205, 7, 62,179, 51, 42, 63, 67, 23,108, 62,170,138, 42,
- 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,214,136, 63, 65,236,183,
- 62,170,138, 42, 63, 55,204,254, 62,179, 51, 42, 63, 67, 23,108, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,179, 51, 42, 63, 67, 23,108, 62,187,220, 45, 63, 55,205, 7, 62,198,143,214, 63, 65,236,200, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,190,242, 44, 63, 78, 83,205, 62,198,143,214, 63, 65,236,200,
- 62,212, 74,188, 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,212, 74,188,
- 63, 75, 39,171, 62,206,238,122, 63, 88, 64,147, 62,190,242, 44, 63, 78, 83,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 49, 63, 90, 56, 14, 62,190,242, 44, 63, 78, 83,205, 62,206,238,122, 63, 88, 64,147,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,206,238,122, 63, 88, 64,147, 62,212, 74,188,
- 63, 75, 39,171, 62,230,102,130, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102,130, 63, 49, 12, 82, 62,230,102,129, 63, 60, 86, 53, 62,216,247, 28, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,216,247, 28, 63, 52, 55,172, 62,218, 43,243, 63, 40,228,223, 62,230,102,130,
- 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,129, 63, 37,200, 48,
- 62,230,102,130, 63, 49, 12, 82, 62,218, 43,243, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,218, 43,243, 63, 40,228,223, 62,216,247, 28, 63, 52, 55,172, 62,205,118,212, 63, 43, 52,228, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,202,101,206, 63, 54,155,120, 62,205,118,212, 63, 43, 52,228,
- 62,216,247, 28, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,216,247, 28,
- 63, 52, 55,172, 62,215, 3,120, 63, 63,233, 95, 62,202,101,206, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,198,143,214, 63, 65,236,200, 62,202,101,206, 63, 54,155,120, 62,215, 3,120, 63, 63,233, 95,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,215, 3,120, 63, 63,233, 95, 62,216,247, 28,
- 63, 52, 55,172, 62,230,102,129, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102,130, 63, 71,154, 1, 62,230,102,130, 63, 82,228, 41, 62,212, 74,188, 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,212, 74,188, 63, 75, 39,171, 62,215, 3,120, 63, 63,233, 95, 62,230,102,130,
- 63, 71,154, 1, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,129, 63, 60, 86, 53,
- 62,230,102,130, 63, 71,154, 1, 62,215, 3,120, 63, 63,233, 95, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,215, 3,120, 63, 63,233, 95, 62,212, 74,188, 63, 75, 39,171, 62,198,143,214, 63, 65,236,200, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,202,101,206, 63, 54,155,120, 62,198,143,214, 63, 65,236,200,
- 62,187,220, 45, 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,187,220, 45,
- 63, 55,205, 7, 62,192,112,142, 63, 44,160,207, 62,202,101,206, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,205,118,212, 63, 43, 52,228, 62,202,101,206, 63, 54,155,120, 62,192,112,142, 63, 44,160,207,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,192,112,142, 63, 44,160,207, 62,187,220, 45,
- 63, 55,205, 7, 62,179, 51, 42, 63, 45, 28, 28, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102,131, 63, 94, 46, 79, 62,230,102,131, 63,105,114, 22, 62,198,103, 87, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198,103, 87, 63, 99, 26, 58, 62,206,238,122, 63, 88, 64,147, 62,230,102,131,
- 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,130, 63, 82,228, 41,
- 62,230,102,131, 63, 94, 46, 79, 62,206,238,122, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,206,238,122, 63, 88, 64,147, 62,198,103, 87, 63, 99, 26, 58, 62,179, 51, 49, 63, 90, 56, 14, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,255, 14, 63, 99, 26, 49, 62,179, 51, 49, 63, 90, 56, 14,
- 62,198,103, 87, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198,103, 87,
- 63, 99, 26, 58, 62,179, 51, 49, 63,109,154,210, 62,159,255, 14, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63,105,114, 8, 62,159,255, 14, 63, 99, 26, 49, 62,179, 51, 49, 63,109,154,210,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 49, 63,109,154,210, 62,198,103, 87,
- 63, 99, 26, 58, 62,230,102,131, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102,134, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 62,128, 0, 0, 63,116,187,232, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63,116,187,232, 62,179, 51, 49, 63,109,154,210, 62,230,102,134,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,131, 63,105,114, 22,
- 62,230,102,134, 63,116,187,242, 62,179, 51, 49, 63,109,154,210, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,179, 51, 49, 63,109,154,210, 62,128, 0, 0, 63,116,187,232, 62,128, 0, 0, 63,105,114, 8, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,255, 14, 63, 99, 26, 49, 62,128, 0, 0, 63,105,114, 8,
- 62,128, 0, 0, 63, 94, 46, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0,
- 63, 94, 46, 58, 62,151,119,239, 63, 88, 64,131, 62,159,255, 14, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 49, 63, 90, 56, 14, 62,159,255, 14, 63, 99, 26, 49, 62,151,119,239, 63, 88, 64,131,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,151,119,239, 63, 88, 64,131, 62,128, 0, 0,
- 63, 94, 46, 58, 62,128, 0, 0, 63, 82,228, 13, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 8,120, 93, 63, 55,205, 11, 63, 3, 30,140, 63, 65,236,201, 63, 1, 51,145, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 1, 51,145, 63, 54,155,121, 63, 6, 46, 46, 63, 44,160,211, 63, 8,120, 93,
- 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,220, 63, 45, 28, 35,
- 63, 8,120, 93, 63, 55,205, 11, 63, 6, 46, 46, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 6, 46, 46, 63, 44,160,211, 63, 1, 51,145, 63, 54,155,121, 62,255, 86, 30, 63, 43, 52,230, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,243,213,222, 63, 52, 55,172, 62,255, 86, 30, 63, 43, 52,230,
- 63, 1, 51,145, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 1, 51,145,
- 63, 54,155,121, 62,245,201,128, 63, 63,233, 94, 62,243,213,222, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,129, 63, 60, 86, 53, 62,243,213,222, 63, 52, 55,172, 62,245,201,128, 63, 63,233, 94,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,245,201,128, 63, 63,233, 94, 63, 1, 51,145,
- 63, 54,155,121, 63, 3, 30,140, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,248,130, 59, 63, 75, 39,169, 62,230,102,130, 63, 82,228, 41, 62,230,102,130, 63, 71,154, 1, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,130, 63, 71,154, 1, 62,245,201,128, 63, 63,233, 94, 62,248,130, 59,
- 63, 75, 39,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 30,140, 63, 65,236,201,
- 62,248,130, 59, 63, 75, 39,169, 62,245,201,128, 63, 63,233, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,245,201,128, 63, 63,233, 94, 62,230,102,130, 63, 71,154, 1, 62,230,102,129, 63, 60, 86, 53, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,243,213,222, 63, 52, 55,172, 62,230,102,129, 63, 60, 86, 53,
- 62,230,102,130, 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,130,
- 63, 49, 12, 82, 62,242,161, 9, 63, 40,228,223, 62,243,213,222, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,255, 86, 30, 63, 43, 52,230, 62,243,213,222, 63, 52, 55,172, 62,242,161, 9, 63, 40,228,223,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,242,161, 9, 63, 40,228,223, 62,230,102,130,
- 63, 49, 12, 82, 62,230,102,129, 63, 37,200, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,248,130, 59, 63, 75, 39,169, 63, 3, 30,140, 63, 65,236,201, 63, 6,237, 94, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6,237, 94, 63, 78, 83,207, 62,253,222,118, 63, 88, 64,148, 62,248,130, 59,
- 63, 75, 39,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,130, 63, 82,228, 41,
- 62,248,130, 59, 63, 75, 39,169, 62,253,222,118, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,253,222,118, 63, 88, 64,148, 63, 6,237, 94, 63, 78, 83,207, 63, 12,204,220, 63, 90, 56, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 18,172, 88, 63, 78, 83,207, 63, 12,204,220, 63, 90, 56, 22,
- 63, 6,237, 94, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6,237, 94,
- 63, 78, 83,207, 63, 12,204,220, 63, 67, 23,115, 63, 18,172, 88, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,123, 44, 63, 65,236,201, 63, 18,172, 88, 63, 78, 83,207, 63, 12,204,220, 63, 67, 23,115,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,220, 63, 67, 23,115, 63, 6,237, 94,
- 63, 78, 83,207, 63, 3, 30,140, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 8,120, 93, 63, 55,205, 11, 63, 12,204,220, 63, 45, 28, 35, 63, 17, 33, 91, 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 17, 33, 91, 63, 55,205, 9, 63, 12,204,220, 63, 67, 23,115, 63, 8,120, 93,
- 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 30,140, 63, 65,236,201,
- 63, 8,120, 93, 63, 55,205, 11, 63, 12,204,220, 63, 67, 23,115, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 12,204,220, 63, 67, 23,115, 63, 17, 33, 91, 63, 55,205, 9, 63, 22,123, 44, 63, 65,236,201, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 18,172, 88, 63, 78, 83,207, 63, 22,123, 44, 63, 65,236,201,
- 63, 29, 88,153, 63, 75, 39,167, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 29, 88,153,
- 63, 75, 39,167, 63, 26,170,121, 63, 88, 64,147, 63, 18,172, 88, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,220, 63, 90, 56, 22, 63, 18,172, 88, 63, 78, 83,207, 63, 26,170,121, 63, 88, 64,147,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 26,170,121, 63, 88, 64,147, 63, 29, 88,153,
- 63, 75, 39,167, 63, 38,102,118, 63, 82,228, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,117, 63, 49, 12, 78, 63, 38,102,117, 63, 60, 86, 50, 63, 31,174,200, 63, 52, 55,169, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,174,200, 63, 52, 55,169, 63, 32, 73, 51, 63, 40,228,221, 63, 38,102,117,
- 63, 49, 12, 78, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 37,200, 45,
- 63, 38,102,117, 63, 49, 12, 78, 63, 32, 73, 51, 63, 40,228,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 32, 73, 51, 63, 40,228,221, 63, 31,174,200, 63, 52, 55,169, 63, 25,238,169, 63, 43, 52,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 24,102, 39, 63, 54,155,119, 63, 25,238,169, 63, 43, 52,229,
- 63, 31,174,200, 63, 52, 55,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,174,200,
- 63, 52, 55,169, 63, 30,180,246, 63, 63,233, 92, 63, 24,102, 39, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,123, 44, 63, 65,236,201, 63, 24,102, 39, 63, 54,155,119, 63, 30,180,246, 63, 63,233, 92,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 30,180,246, 63, 63,233, 92, 63, 31,174,200,
- 63, 52, 55,169, 63, 38,102,117, 63, 60, 86, 50, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,117, 63, 71,153,255, 63, 38,102,118, 63, 82,228, 38, 63, 29, 88,153, 63, 75, 39,167, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 29, 88,153, 63, 75, 39,167, 63, 30,180,246, 63, 63,233, 92, 63, 38,102,117,
- 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 60, 86, 50,
- 63, 38,102,117, 63, 71,153,255, 63, 30,180,246, 63, 63,233, 92, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 30,180,246, 63, 63,233, 92, 63, 29, 88,153, 63, 75, 39,167, 63, 22,123, 44, 63, 65,236,201, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 24,102, 39, 63, 54,155,119, 63, 22,123, 44, 63, 65,236,201,
- 63, 17, 33, 91, 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 17, 33, 91,
- 63, 55,205, 9, 63, 19,107,138, 63, 44,160,211, 63, 24,102, 39, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,238,169, 63, 43, 52,229, 63, 24,102, 39, 63, 54,155,119, 63, 19,107,138, 63, 44,160,211,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,107,138, 63, 44,160,211, 63, 17, 33, 91,
- 63, 55,205, 9, 63, 12,204,220, 63, 45, 28, 35, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,118, 63, 94, 46, 77, 63, 38,102,118, 63,105,114, 19, 63, 22,102,235, 63, 99, 26, 59, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,102,235, 63, 99, 26, 59, 63, 26,170,121, 63, 88, 64,147, 63, 38,102,118,
- 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,118, 63, 82,228, 38,
- 63, 38,102,118, 63, 94, 46, 77, 63, 26,170,121, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 26,170,121, 63, 88, 64,147, 63, 22,102,235, 63, 99, 26, 59, 63, 12,204,220, 63, 90, 56, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 50,204, 63, 99, 26, 58, 63, 12,204,220, 63, 90, 56, 22,
- 63, 22,102,235, 63, 99, 26, 59, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,102,235,
- 63, 99, 26, 59, 63, 12,204,224, 63,109,154,212, 63, 3, 50,204, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,131, 63,105,114, 22, 63, 3, 50,204, 63, 99, 26, 58, 63, 12,204,224, 63,109,154,212,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,224, 63,109,154,212, 63, 22,102,235,
- 63, 99, 26, 59, 63, 38,102,118, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,120, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 62,230,102,134, 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,134, 63,116,187,242, 63, 12,204,224, 63,109,154,212, 63, 38,102,120,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,118, 63,105,114, 19,
- 63, 38,102,120, 63,116,187,242, 63, 12,204,224, 63,109,154,212, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 12,204,224, 63,109,154,212, 62,230,102,134, 63,116,187,242, 62,230,102,131, 63,105,114, 22, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 50,204, 63, 99, 26, 58, 62,230,102,131, 63,105,114, 22,
- 62,230,102,131, 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,131,
- 63, 94, 46, 79, 62,253,222,118, 63, 88, 64,148, 63, 3, 50,204, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,220, 63, 90, 56, 22, 63, 3, 50,204, 63, 99, 26, 58, 62,253,222,118, 63, 88, 64,148,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,253,222,118, 63, 88, 64,148, 62,230,102,131,
- 63, 94, 46, 79, 62,230,102,130, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 76,233,213, 63, 21, 48, 35, 63, 70,235,176, 63, 22,209,226, 63, 73,234, 80, 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,234, 80, 63, 11,111,146, 63, 79,200, 1, 63, 9,152, 94, 63, 76,233,213,
- 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,215, 19, 63, 19, 29,252,
- 63, 76,233,213, 63, 21, 48, 35, 63, 79,200, 1, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 79,200, 1, 63, 9,152, 94, 63, 73,234, 80, 63, 11,111,146, 63, 76,204,193, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,233,213, 63, 21, 48, 35, 63, 82,215, 19, 63, 19, 29,252,
- 63, 80, 41,220, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 80, 41,220,
- 63, 31, 60,105, 63, 73,219,164, 63, 33, 23,173, 63, 76,233,213, 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,235,176, 63, 22,209,226, 63, 76,233,213, 63, 21, 48, 35, 63, 73,219,164, 63, 33, 23,173,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,219,164, 63, 33, 23,173, 63, 80, 41,220,
- 63, 31, 60,105, 63, 77, 33,196, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 70,158,169, 63, 44,160,200, 63, 64, 0, 0, 63, 45, 28, 24, 63, 67,171, 5, 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67,171, 5, 63, 34, 17,216, 63, 73,219,164, 63, 33, 23,173, 63, 70,158,169,
- 63, 44,160,200, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 77, 33,196, 63, 43, 52,221,
- 63, 70,158,169, 63, 44,160,200, 63, 73,219,164, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 73,219,164, 63, 33, 23,173, 63, 67,171, 5, 63, 34, 17,216, 63, 70,235,176, 63, 22,209,226, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 83,124, 75, 63, 40,228,217, 63, 77, 33,196, 63, 43, 52,221,
- 63, 80, 41,220, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 80, 41,220,
- 63, 31, 60,105, 63, 86, 20,218, 63, 28,140,143, 63, 83,124, 75, 63, 40,228,217, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,139, 63, 37,200, 45, 63, 83,124, 75, 63, 40,228,217, 63, 86, 20,218, 63, 28,140,143,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 20,218, 63, 28,140,143, 63, 80, 41,220,
- 63, 31, 60,105, 63, 82,215, 19, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 64, 0, 0, 63, 23, 32,182, 63, 70,235,176, 63, 22,209,226, 63, 67,171, 5, 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67,171, 5, 63, 34, 17,216, 63, 60, 84,251, 63, 34, 17,216, 63, 64, 0, 0,
- 63, 23, 32,182, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 20, 80, 63, 22,209,226,
- 63, 64, 0, 0, 63, 23, 32,182, 63, 60, 84,251, 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 60, 84,251, 63, 34, 17,216, 63, 67,171, 5, 63, 34, 17,216, 63, 64, 0, 0, 63, 45, 28, 24, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 23, 32,182, 63, 57, 20, 80, 63, 22,209,226,
- 63, 60,156,169, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 60,156,169,
- 63, 11,116, 96, 63, 67, 99, 87, 63, 11,116, 96, 63, 64, 0, 0, 63, 23, 32,182, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,235,176, 63, 22,209,226, 63, 64, 0, 0, 63, 23, 32,182, 63, 67, 99, 87, 63, 11,116, 96,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67, 99, 87, 63, 11,116, 96, 63, 60,156,169,
- 63, 11,116, 96, 63, 64, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 70,102, 96, 63, 0, 1,244, 63, 76,204,193, 63, 0, 0, 0, 63, 73,234, 80, 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,234, 80, 63, 11,111,146, 63, 67, 99, 87, 63, 11,116, 96, 63, 70,102, 96,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 0, 0, 0,
- 63, 70,102, 96, 63, 0, 1,244, 63, 67, 99, 87, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 67, 99, 87, 63, 11,116, 96, 63, 73,234, 80, 63, 11,111,146, 63, 70,235,176, 63, 22,209,226, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57,153,160, 63, 0, 1,244, 63, 64, 0, 0, 63, 0, 0, 0,
- 63, 60,156,169, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 60,156,169,
- 63, 11,116, 96, 63, 54, 21,176, 63, 11,111,146, 63, 57,153,160, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 51, 51, 63, 63, 0, 0, 0, 63, 57,153,160, 63, 0, 1,244, 63, 54, 21,176, 63, 11,111,146,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 21,176, 63, 11,111,146, 63, 60,156,169,
- 63, 11,116, 96, 63, 57, 20, 80, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 64, 0, 0, 62,217, 58, 93, 63, 57, 61,144, 62,217,196, 19, 63, 60,123, 85, 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 60,123, 85, 62,198,230,253, 63, 67,132,171, 62,198,230,253, 63, 64, 0, 0,
- 62,217, 58, 93, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,194,112, 62,217,196, 19,
- 63, 64, 0, 0, 62,217, 58, 93, 63, 67,132,171, 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 67,132,171, 62,198,230,253, 63, 60,123, 85, 62,198,230,253, 63, 64, 0, 0, 62,180,111,211, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,217, 58, 93, 63, 70,194,112, 62,217,196, 19,
- 63, 67, 84,125, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67, 84,125,
- 62,236,211, 42, 63, 60,171,131, 62,236,211, 42, 63, 64, 0, 0, 62,217, 58, 93, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 61,144, 62,217,196, 19, 63, 64, 0, 0, 62,217, 58, 93, 63, 60,171,131, 62,236,211, 42,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 60,171,131, 62,236,211, 42, 63, 67, 84,125,
- 62,236,211, 42, 63, 64, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 57,153,160, 63, 0, 1,244, 63, 51, 51, 63, 63, 0, 0, 0, 63, 54, 46,128, 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 46,128, 62,236,207, 75, 63, 60,171,131, 62,236,211, 42, 63, 57,153,160,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 0, 0, 0,
- 63, 57,153,160, 63, 0, 1,244, 63, 60,171,131, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 60,171,131, 62,236,211, 42, 63, 54, 46,128, 62,236,207, 75, 63, 57, 61,144, 62,217,196, 19, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,102, 96, 63, 0, 1,244, 63, 64, 0, 0, 63, 0, 0, 0,
- 63, 67, 84,125, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67, 84,125,
- 62,236,211, 42, 63, 73,209,128, 62,236,207, 75, 63, 70,102, 96, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,204,193, 63, 0, 0, 0, 63, 70,102, 96, 63, 0, 1,244, 63, 73,209,128, 62,236,207, 75,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,209,128, 62,236,207, 75, 63, 67, 84,125,
- 62,236,211, 42, 63, 70,194,112, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 51, 22, 43, 63, 21, 48, 35, 63, 45, 40,237, 63, 19, 29,252, 63, 48, 55,255, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 55,255, 63, 9,152, 94, 63, 54, 21,176, 63, 11,111,146, 63, 51, 22, 43,
- 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 20, 80, 63, 22,209,226,
- 63, 51, 22, 43, 63, 21, 48, 35, 63, 54, 21,176, 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 54, 21,176, 63, 11,111,146, 63, 48, 55,255, 63, 9,152, 94, 63, 51, 51, 63, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 51, 22, 43, 63, 21, 48, 35, 63, 57, 20, 80, 63, 22,209,226,
- 63, 54, 36, 91, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 36, 91,
- 63, 33, 23,173, 63, 47,214, 36, 63, 31, 60,105, 63, 51, 22, 43, 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 40,237, 63, 19, 29,252, 63, 51, 22, 43, 63, 21, 48, 35, 63, 47,214, 36, 63, 31, 60,105,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 47,214, 36, 63, 31, 60,105, 63, 54, 36, 91,
- 63, 33, 23,173, 63, 50,222, 60, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 44,131,181, 63, 40,228,216, 63, 38,102,117, 63, 37,200, 45, 63, 41,235, 38, 63, 28,140,141, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 41,235, 38, 63, 28,140,141, 63, 47,214, 36, 63, 31, 60,105, 63, 44,131,181,
- 63, 40,228,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 50,222, 60, 63, 43, 52,221,
- 63, 44,131,181, 63, 40,228,216, 63, 47,214, 36, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 47,214, 36, 63, 31, 60,105, 63, 41,235, 38, 63, 28,140,141, 63, 45, 40,237, 63, 19, 29,252, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 97, 87, 63, 44,160,200, 63, 50,222, 60, 63, 43, 52,221,
- 63, 54, 36, 91, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54, 36, 91,
- 63, 33, 23,173, 63, 60, 84,251, 63, 34, 17,216, 63, 57, 97, 87, 63, 44,160,200, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 63, 45, 28, 24, 63, 57, 97, 87, 63, 44,160,200, 63, 60, 84,251, 63, 34, 17,216,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 60, 84,251, 63, 34, 17,216, 63, 54, 36, 91,
- 63, 33, 23,173, 63, 57, 20, 80, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,128, 14,134, 63, 21, 48, 39, 63,122, 30,227, 63, 22,209,233, 63,125, 29,138, 63, 11,111,150, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,125, 29,138, 63, 11,111,150, 63,129,125,159, 63, 9,152, 94, 63,128, 14,134,
- 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,193, 73,174, 63, 19, 29,253,
- 57,232, 92,209, 63, 21, 48, 39, 60, 62,207,114, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,129,125,159, 63, 9,152, 94, 63,125, 29,138, 63, 11,111,150, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 57,232, 92,209, 63, 21, 48, 39, 60,193, 73,174, 63, 19, 29,253,
- 60, 87, 67,214, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,129,174,136,
- 63, 31, 60,110, 63,125, 14,213, 63, 33, 23,180, 63,128, 14,134, 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,122, 30,227, 63, 22,209,233, 63,128, 14,134, 63, 21, 48, 39, 63,125, 14,213, 63, 33, 23,180,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,125, 14,213, 63, 33, 23,180, 63,129,174,136,
- 63, 31, 60,110, 63,128, 42,121, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,121,209,210, 63, 44,160,212, 63,115, 51, 36, 63, 45, 28, 36, 63,118,222, 49, 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,222, 49, 63, 34, 17,226, 63,125, 14,213, 63, 33, 23,180, 63,121,209,210,
- 63, 44,160,212, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,128, 42,121, 63, 43, 52,230,
- 63,121,209,210, 63, 44,160,212, 63,125, 14,213, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,125, 14,213, 63, 33, 23,180, 63,118,222, 49, 63, 34, 17,226, 63,122, 30,227, 63, 22,209,233, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,213,239,111, 63, 40,228,223, 58,169,226,120, 63, 43, 52,230,
- 60, 87, 67,214, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60, 87, 67,214,
- 63, 31, 60,110, 61, 20,129, 13, 63, 28,140,143, 60,213,239,111, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,203,246, 63, 37,200, 48, 60,213,239,111, 63, 40,228,223, 61, 20,129, 13, 63, 28,140,143,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 20,129, 13, 63, 28,140,143, 60, 87, 67,214,
- 63, 31, 60,110, 60,193, 73,174, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,115, 51, 44, 63, 23, 32,188, 63,122, 30,227, 63, 22,209,233, 63,118,222, 49, 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,222, 49, 63, 34, 17,226, 63,111,136, 31, 63, 34, 17,225, 63,115, 51, 44,
- 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108, 71,116, 63, 22,209,232,
- 63,115, 51, 44, 63, 23, 32,188, 63,111,136, 31, 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,111,136, 31, 63, 34, 17,225, 63,118,222, 49, 63, 34, 17,226, 63,115, 51, 36, 63, 45, 28, 36, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 44, 63, 23, 32,188, 63,108, 71,116, 63, 22,209,232,
- 63,111,207,213, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,111,207,213,
- 63, 11,116,100, 63,118,150,138, 63, 11,116,101, 63,115, 51, 44, 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,122, 30,227, 63, 22,209,233, 63,115, 51, 44, 63, 23, 32,188, 63,118,150,138, 63, 11,116,101,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,150,138, 63, 11,116,101, 63,111,207,213,
- 63, 11,116,100, 63,115, 51, 51, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,121,153,154, 63, 0, 1,244, 63,128, 0, 0, 63, 0, 0, 0, 63,125, 29,138, 63, 11,111,150, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,125, 29,138, 63, 11,111,150, 63,118,150,138, 63, 11,116,101, 63,121,153,154,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 51, 63, 0, 0, 0,
- 63,121,153,154, 63, 0, 1,244, 63,118,150,138, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,118,150,138, 63, 11,116,101, 63,125, 29,138, 63, 11,111,150, 63,122, 30,227, 63, 22,209,233, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108,204,205, 63, 0, 1,244, 63,115, 51, 51, 63, 0, 0, 0,
- 63,111,207,213, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,111,207,213,
- 63, 11,116,100, 63,105, 72,213, 63, 11,111,149, 63,108,204,205, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,102,102,101, 63, 0, 0, 0, 63,108,204,205, 63, 0, 1,244, 63,105, 72,213, 63, 11,111,149,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105, 72,213, 63, 11,111,149, 63,111,207,213,
- 63, 11,116,100, 63,108, 71,116, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,115, 51, 58, 62,217, 58, 73, 63,108,112,192, 62,217,196, 4, 63,111,174,139, 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,111,174,139, 62,198,230,223, 63,118,183,239, 62,198,230,227, 63,115, 51, 58,
- 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121,245,179, 62,217,196, 6,
- 63,115, 51, 58, 62,217, 58, 73, 63,118,183,239, 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,118,183,239, 62,198,230,227, 63,111,174,139, 62,198,230,223, 63,115, 51, 65, 62,180,111,160, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 58, 62,217, 58, 73, 63,121,245,179, 62,217,196, 6,
- 63,118,135,185, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,135,185,
- 62,236,211, 30, 63,111,222,180, 62,236,211, 30, 63,115, 51, 58, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,108,112,192, 62,217,196, 4, 63,115, 51, 58, 62,217, 58, 73, 63,111,222,180, 62,236,211, 30,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,111,222,180, 62,236,211, 30, 63,118,135,185,
- 62,236,211, 30, 63,115, 51, 51, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,108,204,205, 63, 0, 1,244, 63,102,102,101, 63, 0, 0, 0, 63,105, 97,170, 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105, 97,170, 62,236,207, 65, 63,111,222,180, 62,236,211, 30, 63,108,204,205,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 51, 63, 0, 0, 0,
- 63,108,204,205, 63, 0, 1,244, 63,111,222,180, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,111,222,180, 62,236,211, 30, 63,105, 97,170, 62,236,207, 65, 63,108,112,192, 62,217,196, 4, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121,153,154, 63, 0, 1,244, 63,115, 51, 51, 63, 0, 0, 0,
- 63,118,135,185, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,135,185,
- 62,236,211, 30, 63,125, 4,194, 62,236,207, 67, 63,121,153,154, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,121,153,154, 63, 0, 1,244, 63,125, 4,194, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,125, 4,194, 62,236,207, 67, 63,118,135,185,
- 62,236,211, 30, 63,121,245,179, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,102, 73, 76, 63, 21, 48, 38, 63, 96, 92, 11, 63, 19, 29,253, 63, 99,107, 33, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99,107, 33, 63, 9,152, 94, 63,105, 72,213, 63, 11,111,149, 63,102, 73, 76,
- 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108, 71,116, 63, 22,209,232,
- 63,102, 73, 76, 63, 21, 48, 38, 63,105, 72,213, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,105, 72,213, 63, 11,111,149, 63, 99,107, 33, 63, 9,152, 94, 63,102,102,101, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,102, 73, 76, 63, 21, 48, 38, 63,108, 71,116, 63, 22,209,232,
- 63,105, 87,124, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105, 87,124,
- 63, 33, 23,180, 63, 99, 9, 65, 63, 31, 60,109, 63,102, 73, 76, 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 96, 92, 11, 63, 19, 29,253, 63,102, 73, 76, 63, 21, 48, 38, 63, 99, 9, 65, 63, 31, 60,109,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99, 9, 65, 63, 31, 60,109, 63,105, 87,124,
- 63, 33, 23,180, 63,102, 17, 87, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 95,182,205, 63, 40,228,222, 63, 89,153,139, 63, 37,200, 45, 63, 93, 30, 63, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 93, 30, 63, 63, 28,140,143, 63, 99, 9, 65, 63, 31, 60,109, 63, 95,182,205,
- 63, 40,228,222, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,102, 17, 87, 63, 43, 52,229,
- 63, 95,182,205, 63, 40,228,222, 63, 99, 9, 65, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 99, 9, 65, 63, 31, 60,109, 63, 93, 30, 63, 63, 28,140,143, 63, 96, 92, 11, 63, 19, 29,253, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108,148,118, 63, 44,160,211, 63,102, 17, 87, 63, 43, 52,229,
- 63,105, 87,124, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105, 87,124,
- 63, 33, 23,180, 63,111,136, 31, 63, 34, 17,225, 63,108,148,118, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 36, 63, 45, 28, 36, 63,108,148,118, 63, 44,160,211, 63,111,136, 31, 63, 34, 17,225,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,111,136, 31, 63, 34, 17,225, 63,105, 87,124,
- 63, 33, 23,180, 63,108, 71,116, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 77, 65, 65, 63, 21, 48, 32, 62, 53, 72,152, 63, 22,209,229, 62, 65, 67, 47, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 65, 67, 47, 63, 11,111,147, 62, 88,185,255, 63, 9,152, 90, 62, 77, 65, 65,
- 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,100,246, 64, 63, 19, 29,246,
- 62, 77, 65, 65, 63, 21, 48, 32, 62, 88,185,255, 63, 9,152, 90, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 88,185,255, 63, 9,152, 90, 62, 65, 67, 47, 63, 11,111,147, 62, 76,204,254, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 77, 65, 65, 63, 21, 48, 32, 62,100,246, 64, 63, 19, 29,246,
- 62, 90, 65, 89, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 90, 65, 89,
- 63, 31, 60, 94, 62, 65, 8,107, 63, 33, 23,170, 62, 77, 65, 65, 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 53, 72,152, 63, 22,209,229, 62, 77, 65, 65, 63, 21, 48, 32, 62, 65, 8,107, 63, 33, 23,170,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 65, 8,107, 63, 33, 23,170, 62, 90, 65, 89,
- 63, 31, 60, 94, 62, 78, 32,230, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 52, 20,105, 63, 44,160,198, 62, 25,153,173, 63, 45, 28, 27, 62, 40, 69,216, 63, 34, 17,220, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 40, 69,216, 63, 34, 17,220, 62, 65, 8,107, 63, 33, 23,170, 62, 52, 20,105,
- 63, 44,160,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 78, 32,230, 63, 43, 52,211,
- 62, 52, 20,105, 63, 44,160,198, 62, 65, 8,107, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 65, 8,107, 63, 33, 23,170, 62, 40, 69,216, 63, 34, 17,220, 62, 53, 72,152, 63, 22,209,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,103,139, 14, 63, 40,228,199, 62, 78, 32,230, 63, 43, 52,211,
- 62, 90, 65, 89, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 90, 65, 89,
- 63, 31, 60, 94, 62,113,237, 83, 63, 28,140,130, 62,103,139, 14, 63, 40,228,199, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 37,200, 23, 62,103,139, 14, 63, 40,228,199, 62,113,237, 83, 63, 28,140,130,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,113,237, 83, 63, 28,140,130, 62, 90, 65, 89,
- 63, 31, 60, 94, 62,100,246, 64, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 25,153,180, 63, 23, 32,185, 62, 53, 72,152, 63, 22,209,229, 62, 40, 69,216, 63, 34, 17,220, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 40, 69,216, 63, 34, 17,220, 62, 10,237,133, 63, 34, 17,219, 62, 25,153,180,
- 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,251,213,147, 63, 22,209,228,
- 62, 25,153,180, 63, 23, 32,185, 62, 10,237,133, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 10,237,133, 63, 34, 17,219, 62, 40, 69,216, 63, 34, 17,220, 62, 25,153,173, 63, 45, 28, 27, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,180, 63, 23, 32,185, 61,251,213,147, 63, 22,209,228,
- 62, 12, 12, 67, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 12, 12, 67,
- 63, 11,116, 98, 62, 39, 39, 34, 63, 11,116, 98, 62, 25,153,180, 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 53, 72,152, 63, 22,209,229, 62, 25,153,180, 63, 23, 32,185, 62, 39, 39, 34, 63, 11,116, 98,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 39, 39, 34, 63, 11,116, 98, 62, 12, 12, 67,
- 63, 11,116, 98, 62, 25,153,181, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 51, 51, 92, 63, 0, 1,244, 62, 76,204,254, 63, 0, 0, 0, 62, 65, 67, 47, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 65, 67, 47, 63, 11,111,147, 62, 39, 39, 34, 63, 11,116, 98, 62, 51, 51, 92,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,181, 63, 0, 0, 0,
- 62, 51, 51, 92, 63, 0, 1,244, 62, 39, 39, 34, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 39, 39, 34, 63, 11,116, 98, 62, 65, 67, 47, 63, 11,111,147, 62, 53, 72,152, 63, 22,209,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 0, 0, 8, 63, 0, 1,244, 62, 25,153,181, 63, 0, 0, 0,
- 62, 12, 12, 67, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 12, 12, 67,
- 63, 11,116, 98, 61,227,224,109, 63, 11,111,147, 62, 0, 0, 8, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,204,204,215, 63, 0, 0, 0, 62, 0, 0, 8, 63, 0, 1,244, 61,227,224,109, 63, 11,111,147,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,227,224,109, 63, 11,111,147, 62, 12, 12, 67,
- 63, 11,116, 98, 61,251,213,147, 63, 22,209,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 25,153,196, 62,217, 58, 73, 61,253, 31,171, 62,217,196, 6, 62, 11,135, 1, 62,198,230,228, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 11,135, 1, 62,198,230,228, 62, 39,172,153, 62,198,230,230, 62, 25,153,196,
- 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 52,163,179, 62,217,196, 7,
- 62, 25,153,196, 62,217, 58, 73, 62, 39,172,153, 62,198,230,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 39,172,153, 62,198,230,230, 62, 11,135, 1, 62,198,230,228, 62, 25,153,214, 62,180,111,165, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,196, 62,217, 58, 73, 62, 52,163,179, 62,217,196, 7,
- 62, 38,235,202, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 38,235,202,
- 62,236,211, 33, 62, 12, 71,173, 62,236,211, 31, 62, 25,153,196, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,253, 31,171, 62,217,196, 6, 62, 25,153,196, 62,217, 58, 73, 62, 12, 71,173, 62,236,211, 31,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 12, 71,173, 62,236,211, 31, 62, 38,235,202,
- 62,236,211, 33, 62, 25,153,181, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 0, 0, 8, 63, 0, 1,244, 61,204,204,215, 63, 0, 0, 0, 61,228,166,251, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,228,166,251, 62,236,207, 67, 62, 12, 71,173, 62,236,211, 31, 62, 0, 0, 8,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,181, 63, 0, 0, 0,
- 62, 0, 0, 8, 63, 0, 1,244, 62, 12, 71,173, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 12, 71,173, 62,236,211, 31, 61,228,166,251, 62,236,207, 67, 61,253, 31,171, 62,217,196, 6, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 51, 51, 92, 63, 0, 1,244, 62, 25,153,181, 63, 0, 0, 0,
- 62, 38,235,202, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 38,235,202,
- 62,236,211, 33, 62, 64,223,251, 62,236,207, 67, 62, 51, 51, 92, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 76,204,254, 63, 0, 0, 0, 62, 51, 51, 92, 63, 0, 1,244, 62, 64,223,251, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 64,223,251, 62,236,207, 67, 62, 38,235,202,
- 62,236,211, 33, 62, 52,163,179, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,203,228, 42, 63, 21, 48, 37, 61,156,122, 1, 63, 19, 29,254, 61,180,242,172, 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,180,242,172, 63, 9,152, 96, 61,227,224,109, 63, 11,111,147, 61,203,228, 42,
- 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,251,213,147, 63, 22,209,228,
- 61,203,228, 42, 63, 21, 48, 37, 61,227,224,109, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,227,224,109, 63, 11,111,147, 61,180,242,172, 63, 9,152, 96, 61,204,204,215, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,203,228, 42, 63, 21, 48, 37, 61,251,213,147, 63, 22,209,228,
- 61,228, 85,208, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,228, 85,208,
- 63, 33, 23,179, 61,177,227,212, 63, 31, 60,110, 61,203,228, 42, 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,156,122, 1, 63, 19, 29,254, 61,203,228, 42, 63, 21, 48, 37, 61,177,227,212, 63, 31, 60,110,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,177,227,212, 63, 31, 60,110, 61,228, 85,208,
- 63, 33, 23,179, 61,202, 36,175, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,151, 80, 53, 63, 40,228,223, 61, 76,203,246, 63, 37,200, 48, 61,130,139,166, 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,130,139,166, 63, 28,140,145, 61,177,227,212, 63, 31, 60,110, 61,151, 80, 53,
- 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,202, 36,175, 63, 43, 52,228,
- 61,151, 80, 53, 63, 40,228,223, 61,177,227,212, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,177,227,212, 63, 31, 60,110, 61,130,139,166, 63, 28,140,145, 61,156,122, 1, 63, 19, 29,254, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,254, 61,201, 63, 44,160,207, 61,202, 36,175, 63, 43, 52,228,
- 61,228, 85,208, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,228, 85,208,
- 63, 33, 23,179, 62, 10,237,133, 63, 34, 17,219, 61,254, 61,201, 63, 44,160,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,173, 63, 45, 28, 27, 61,254, 61,201, 63, 44,160,207, 62, 10,237,133, 63, 34, 17,219,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 10,237,133, 63, 34, 17,219, 61,228, 85,208,
- 63, 33, 23,179, 61,251,213,147, 63, 22,209,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,205, 6,245, 63, 21, 48, 37, 62,193, 10,155, 63, 22,209,229, 62,199, 7,229, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,199, 7,229, 63, 11,111,147, 62,210,195, 85, 63, 9,152, 96, 62,205, 6,245,
- 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,216,225,128, 63, 19, 29,254,
- 62,205, 6,245, 63, 21, 48, 37, 62,210,195, 85, 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,210,195, 85, 63, 9,152, 96, 62,199, 7,229, 63, 11,111,147, 62,204,204,202, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,205, 6,245, 63, 21, 48, 37, 62,216,225,128, 63, 19, 29,254,
- 62,211,135, 11, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,211,135, 11,
- 63, 31, 60,110, 62,198,234,140, 63, 33, 23,179, 62,205, 6,245, 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,193, 10,155, 63, 22,209,229, 62,205, 6,245, 63, 21, 48, 37, 62,198,234,140, 63, 33, 23,179,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198,234,140, 63, 33, 23,179, 62,211,135, 11,
- 63, 31, 60,110, 62,205,118,212, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,192,112,142, 63, 44,160,207, 62,179, 51, 42, 63, 45, 28, 28, 62,186,137, 61, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,186,137, 61, 63, 34, 17,219, 62,198,234,140, 63, 33, 23,179, 62,192,112,142,
- 63, 44,160,207, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,205,118,212, 63, 43, 52,228,
- 62,192,112,142, 63, 44,160,207, 62,198,234,140, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,198,234,140, 63, 33, 23,179, 62,186,137, 61, 63, 34, 17,219, 62,193, 10,155, 63, 22,209,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,218, 43,243, 63, 40,228,223, 62,205,118,212, 63, 43, 52,228,
- 62,211,135, 11, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,211,135, 11,
- 63, 31, 60,110, 62,223, 93, 22, 63, 28,140,145, 62,218, 43,243, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,129, 63, 37,200, 48, 62,218, 43,243, 63, 40,228,223, 62,223, 93, 22, 63, 28,140,145,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223, 93, 22, 63, 28,140,145, 62,211,135, 11,
- 63, 31, 60,110, 62,216,225,128, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,179, 51, 38, 63, 23, 32,185, 62,193, 10,155, 63, 22,209,229, 62,186,137, 61, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,186,137, 61, 63, 34, 17,219, 62,171,221, 20, 63, 34, 17,219, 62,179, 51, 38,
- 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165, 91,180, 63, 22,209,229,
- 62,179, 51, 38, 63, 23, 32,185, 62,171,221, 20, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,171,221, 20, 63, 34, 17,219, 62,186,137, 61, 63, 34, 17,219, 62,179, 51, 42, 63, 45, 28, 28, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 38, 63, 23, 32,185, 62,165, 91,180, 63, 22,209,229,
- 62,172,108,111, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,172,108,111,
- 63, 11,116, 98, 62,185,249,222, 63, 11,116, 98, 62,179, 51, 38, 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,193, 10,155, 63, 22,209,229, 62,179, 51, 38, 63, 23, 32,185, 62,185,249,222, 63, 11,116, 98,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,185,249,222, 63, 11,116, 98, 62,172,108,111,
- 63, 11,116, 98, 62,179, 51, 38, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,191,255,252, 63, 0, 1,244, 62,204,204,202, 63, 0, 0, 0, 62,199, 7,229, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,199, 7,229, 63, 11,111,147, 62,185,249,222, 63, 11,116, 98, 62,191,255,252,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 38, 63, 0, 0, 0,
- 62,191,255,252, 63, 0, 1,244, 62,185,249,222, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,185,249,222, 63, 11,116, 98, 62,199, 7,229, 63, 11,111,147, 62,193, 10,155, 63, 22,209,229, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,166,102, 82, 63, 0, 1,244, 62,179, 51, 38, 63, 0, 0, 0,
- 62,172,108,111, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,172,108,111,
- 63, 11,116, 98, 62,159, 94,104, 63, 11,111,147, 62,166,102, 82, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,153,153,129, 63, 0, 0, 0, 62,166,102, 82, 63, 0, 1,244, 62,159, 94,104, 63, 11,111,147,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159, 94,104, 63, 11,111,147, 62,172,108,111,
- 63, 11,116, 98, 62,165, 91,180, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,179, 51, 30, 62,217, 58, 73, 62,165,174, 39, 62,217,196, 7, 62,172, 41,180, 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,172, 41,180, 62,198,230,227, 62,186, 60,127, 62,198,230,225, 62,179, 51, 30,
- 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,192,184, 21, 62,217,196, 6,
- 62,179, 51, 30, 62,217, 58, 73, 62,186, 60,127, 62,198,230,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,186, 60,127, 62,198,230,225, 62,172, 41,180, 62,198,230,227, 62,179, 51, 21, 62,180,111,165, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 30, 62,217, 58, 73, 62,192,184, 21, 62,217,196, 6,
- 62,185,220, 42, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,185,220, 42,
- 62,236,211, 31, 62,172,138, 27, 62,236,211, 33, 62,179, 51, 30, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,165,174, 39, 62,217,196, 7, 62,179, 51, 30, 62,217, 58, 73, 62,172,138, 27, 62,236,211, 33,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,172,138, 27, 62,236,211, 33, 62,185,220, 42,
- 62,236,211, 31, 62,179, 51, 38, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,166,102, 82, 63, 0, 1,244, 62,153,153,129, 63, 0, 0, 0, 62,159,144, 3, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,144, 3, 62,236,207, 67, 62,172,138, 27, 62,236,211, 33, 62,166,102, 82,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 38, 63, 0, 0, 0,
- 62,166,102, 82, 63, 0, 1,244, 62,172,138, 27, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,172,138, 27, 62,236,211, 33, 62,159,144, 3, 62,236,207, 67, 62,165,174, 39, 62,217,196, 7, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,191,255,252, 63, 0, 1,244, 62,179, 51, 38, 63, 0, 0, 0,
- 62,185,220, 42, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,185,220, 42,
- 62,236,211, 31, 62,198,214, 65, 62,236,207, 67, 62,191,255,252, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,204,204,202, 63, 0, 0, 0, 62,191,255,252, 63, 0, 1,244, 62,198,214, 65, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198,214, 65, 62,236,207, 67, 62,185,220, 42,
- 62,236,211, 31, 62,192,184, 21, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,153, 95, 95, 63, 21, 48, 32, 62,141,132,224, 63, 19, 29,246, 62,147,163, 1, 63, 9,152, 91, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147,163, 1, 63, 9,152, 91, 62,159, 94,104, 63, 11,111,147, 62,153, 95, 95,
- 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165, 91,180, 63, 22,209,229,
- 62,153, 95, 95, 63, 21, 48, 32, 62,159, 94,104, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,159, 94,104, 63, 11,111,147, 62,147,163, 1, 63, 9,152, 91, 62,153,153,129, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,153, 95, 95, 63, 21, 48, 32, 62,165, 91,180, 63, 22,209,229,
- 62,159,123,203, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,123,203,
- 63, 33, 23,170, 62,146,223, 84, 63, 31, 60, 94, 62,153, 95, 95, 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,141,132,224, 63, 19, 29,246, 62,153, 95, 95, 63, 21, 48, 32, 62,146,223, 84, 63, 31, 60, 94,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,146,223, 84, 63, 31, 60, 94, 62,159,123,203,
- 63, 33, 23,170, 62,152,239,141, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,140, 58,121, 63, 40,228,199, 62,128, 0, 0, 63, 37,200, 23, 62,135, 9, 86, 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,135, 9, 86, 63, 28,140,130, 62,146,223, 84, 63, 31, 60, 94, 62,140, 58,121,
- 63, 40,228,199, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,152,239,141, 63, 43, 52,211,
- 62,140, 58,121, 63, 40,228,199, 62,146,223, 84, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,146,223, 84, 63, 31, 60, 94, 62,135, 9, 86, 63, 28,140,130, 62,141,132,224, 63, 19, 29,246, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165,245,204, 63, 44,160,198, 62,152,239,141, 63, 43, 52,211,
- 62,159,123,203, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,159,123,203,
- 63, 33, 23,170, 62,171,221, 20, 63, 34, 17,219, 62,165,245,204, 63, 44,160,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 42, 63, 45, 28, 28, 62,165,245,204, 63, 44,160,198, 62,171,221, 20, 63, 34, 17,219,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,171,221, 20, 63, 34, 17,219, 62,159,123,203,
- 63, 33, 23,170, 62,165, 91,180, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 25,182,180, 63, 21, 48, 38, 63, 19,184,140, 63, 22,209,232, 63, 22,183, 43, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,183, 43, 63, 11,111,149, 63, 28,148,223, 63, 9,152, 94, 63, 25,182,180,
- 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,163,245, 63, 19, 29,253,
- 63, 25,182,180, 63, 21, 48, 38, 63, 28,148,223, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 28,148,223, 63, 9,152, 94, 63, 22,183, 43, 63, 11,111,149, 63, 25,153,155, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,182,180, 63, 21, 48, 38, 63, 31,163,245, 63, 19, 29,253,
- 63, 28,246,191, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,246,191,
- 63, 31, 60,109, 63, 22,168,132, 63, 33, 23,180, 63, 25,182,180, 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,184,140, 63, 22,209,232, 63, 25,182,180, 63, 21, 48, 38, 63, 22,168,132, 63, 33, 23,180,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,168,132, 63, 33, 23,180, 63, 28,246,191,
- 63, 31, 60,109, 63, 25,238,169, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 19,107,138, 63, 44,160,211, 63, 12,204,220, 63, 45, 28, 35, 63, 16,119,225, 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16,119,225, 63, 34, 17,225, 63, 22,168,132, 63, 33, 23,180, 63, 19,107,138,
- 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,238,169, 63, 43, 52,229,
- 63, 19,107,138, 63, 44,160,211, 63, 22,168,132, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 22,168,132, 63, 33, 23,180, 63, 16,119,225, 63, 34, 17,225, 63, 19,184,140, 63, 22,209,232, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 32, 73, 51, 63, 40,228,221, 63, 25,238,169, 63, 43, 52,229,
- 63, 28,246,191, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,246,191,
- 63, 31, 60,109, 63, 34,225,192, 63, 28,140,142, 63, 32, 73, 51, 63, 40,228,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,117, 63, 37,200, 45, 63, 32, 73, 51, 63, 40,228,221, 63, 34,225,192, 63, 28,140,142,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 34,225,192, 63, 28,140,142, 63, 28,246,191,
- 63, 31, 60,109, 63, 31,163,245, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 12,204,212, 63, 23, 32,188, 63, 19,184,140, 63, 22,209,232, 63, 16,119,225, 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16,119,225, 63, 34, 17,225, 63, 9, 33,207, 63, 34, 17,226, 63, 12,204,212,
- 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 5,225, 29, 63, 22,209,233,
- 63, 12,204,212, 63, 23, 32,188, 63, 9, 33,207, 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 9, 33,207, 63, 34, 17,226, 63, 16,119,225, 63, 34, 17,225, 63, 12,204,220, 63, 45, 28, 35, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,212, 63, 23, 32,188, 63, 5,225, 29, 63, 22,209,233,
- 63, 9,105,118, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 9,105,118,
- 63, 11,116,101, 63, 16, 48, 43, 63, 11,116,100, 63, 12,204,212, 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,184,140, 63, 22,209,232, 63, 12,204,212, 63, 23, 32,188, 63, 16, 48, 43, 63, 11,116,100,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16, 48, 43, 63, 11,116,100, 63, 9,105,118,
- 63, 11,116,101, 63, 12,204,205, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 19, 51, 51, 63, 0, 1,244, 63, 25,153,155, 63, 0, 0, 0, 63, 22,183, 43, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,183, 43, 63, 11,111,149, 63, 16, 48, 43, 63, 11,116,100, 63, 19, 51, 51,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,205, 63, 0, 0, 0,
- 63, 19, 51, 51, 63, 0, 1,244, 63, 16, 48, 43, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 16, 48, 43, 63, 11,116,100, 63, 22,183, 43, 63, 11,111,149, 63, 19,184,140, 63, 22,209,232, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6,102,102, 63, 0, 1,244, 63, 12,204,205, 63, 0, 0, 0,
- 63, 9,105,118, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 9,105,118,
- 63, 11,116,101, 63, 2,226,118, 63, 11,111,149, 63, 6,102,102, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 6,102,102, 63, 0, 1,244, 63, 2,226,118, 63, 11,111,149,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 2,226,118, 63, 11,111,149, 63, 9,105,118,
- 63, 11,116,101, 63, 5,225, 29, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 12,204,198, 62,217, 58, 72, 63, 6, 10, 77, 62,217,196, 6, 63, 9, 72, 17, 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 9, 72, 17, 62,198,230,227, 63, 16, 81,117, 62,198,230,223, 63, 12,204,198,
- 62,217, 58, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,143, 64, 62,217,196, 4,
- 63, 12,204,198, 62,217, 58, 72, 63, 16, 81,117, 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 16, 81,117, 62,198,230,223, 63, 9, 72, 17, 62,198,230,227, 63, 12,204,191, 62,180,111,160, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,198, 62,217, 58, 72, 63, 19,143, 64, 62,217,196, 4,
- 63, 16, 33, 76, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16, 33, 76,
- 62,236,211, 30, 63, 9,120, 71, 62,236,211, 30, 63, 12,204,198, 62,217, 58, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 6, 10, 77, 62,217,196, 6, 63, 12,204,198, 62,217, 58, 72, 63, 9,120, 71, 62,236,211, 30,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 9,120, 71, 62,236,211, 30, 63, 16, 33, 76,
- 62,236,211, 30, 63, 12,204,205, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 6,102,102, 63, 0, 1,244, 63, 0, 0, 0, 63, 0, 0, 0, 63, 2,251, 62, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 2,251, 62, 62,236,207, 67, 63, 9,120, 71, 62,236,211, 30, 63, 6,102,102,
- 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,205, 63, 0, 0, 0,
- 63, 6,102,102, 63, 0, 1,244, 63, 9,120, 71, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 9,120, 71, 62,236,211, 30, 63, 2,251, 62, 62,236,207, 67, 63, 6, 10, 77, 62,217,196, 6, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 19, 51, 51, 63, 0, 1,244, 63, 12,204,205, 63, 0, 0, 0,
- 63, 16, 33, 76, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16, 33, 76,
- 62,236,211, 30, 63, 22,158, 86, 62,236,207, 65, 63, 19, 51, 51, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,153,155, 63, 0, 0, 0, 63, 19, 51, 51, 63, 0, 1,244, 63, 22,158, 86, 62,236,207, 65,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,158, 86, 62,236,207, 65, 63, 16, 33, 76,
- 62,236,211, 30, 63, 19,143, 64, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,255,197,233, 63, 21, 48, 39, 62,243,235,101, 63, 19, 29,252, 62,250, 9,132, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,250, 9,132, 63, 9,152, 94, 63, 2,226,118, 63, 11,111,149, 62,255,197,233,
- 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 5,225, 29, 63, 22,209,233,
- 62,255,197,233, 63, 21, 48, 39, 63, 2,226,118, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 2,226,118, 63, 11,111,149, 62,250, 9,132, 63, 9,152, 94, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,255,197,233, 63, 21, 48, 39, 63, 5,225, 29, 63, 22,209,233,
- 63, 2,241, 43, 63, 33, 23,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 2,241, 43,
- 63, 33, 23,181, 62,249, 69,225, 63, 31, 60,110, 62,255,197,233, 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,243,235,101, 63, 19, 29,252, 62,255,197,233, 63, 21, 48, 39, 62,249, 69,225, 63, 31, 60,110,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,249, 69,225, 63, 31, 60,110, 63, 2,241, 43,
- 63, 33, 23,181, 62,255, 86, 30, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,242,161, 9, 63, 40,228,223, 62,230,102,129, 63, 37,200, 48, 62,237,111,222, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237,111,222, 63, 28,140,143, 62,249, 69,225, 63, 31, 60,110, 62,242,161, 9,
- 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,255, 86, 30, 63, 43, 52,230,
- 62,242,161, 9, 63, 40,228,223, 62,249, 69,225, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,249, 69,225, 63, 31, 60,110, 62,237,111,222, 63, 28,140,143, 62,243,235,101, 63, 19, 29,252, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6, 46, 46, 63, 44,160,211, 62,255, 86, 30, 63, 43, 52,230,
- 63, 2,241, 43, 63, 33, 23,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 2,241, 43,
- 63, 33, 23,181, 63, 9, 33,207, 63, 34, 17,226, 63, 6, 46, 46, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,220, 63, 45, 28, 35, 63, 6, 46, 46, 63, 44,160,211, 63, 9, 33,207, 63, 34, 17,226,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 9, 33,207, 63, 34, 17,226, 63, 2,241, 43,
- 63, 33, 23,181, 63, 5,225, 29, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 85,238,138, 62,187,220, 72, 63, 82,173,218, 62,210, 92, 55, 63, 79,189,229, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,189,229, 62,189,208,173, 63, 82,250,230, 62,166,190,117, 63, 85,238,138,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,149, 62,165,199,201,
- 63, 85,238,138, 62,187,220, 72, 63, 82,250,230, 62,166,190,117, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 82,250,230, 62,166,190,117, 63, 79,189,229, 62,189,208,173, 63, 76,119,198, 62,169,150, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,111,170, 62,193,135, 68, 63, 76,119,198, 62,169,150, 90,
- 63, 79,189,229, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,189,229,
- 62,189,208,173, 63, 76,175,176, 62,213,159,192, 63, 73,111,170, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,194,112, 62,217,196, 19, 63, 73,111,170, 62,193,135, 68, 63, 76,175,176, 62,213,159,192,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,175,176, 62,213,159,192, 63, 79,189,229,
- 62,189,208,173, 63, 82,173,218, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 79,175, 52, 62,233, 32,218, 63, 76,204,193, 63, 0, 0, 0, 63, 73,209,128, 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,209,128, 62,236,207, 75, 63, 76,175,176, 62,213,159,192, 63, 79,175, 52,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,173,218, 62,210, 92, 55,
- 63, 79,175, 52, 62,233, 32,218, 63, 76,175,176, 62,213,159,192, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 76,175,176, 62,213,159,192, 63, 73,209,128, 62,236,207, 75, 63, 70,194,112, 62,217,196, 19, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73,111,170, 62,193,135, 68, 63, 70,194,112, 62,217,196, 19,
- 63, 67,132,171, 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 67,132,171,
- 62,198,230,253, 63, 70, 29, 61, 62,174, 54,114, 63, 73,111,170, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,119,198, 62,169,150, 90, 63, 73,111,170, 62,193,135, 68, 63, 70, 29, 61, 62,174, 54,114,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 70, 29, 61, 62,174, 54,114, 63, 67,132,171,
- 62,198,230,253, 63, 64, 0, 0, 62,180,111,211, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 79,175, 52, 62,233, 32,218, 63, 82,173,218, 62,210, 92, 55, 63, 86, 54, 56, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 54, 56, 62,233, 23, 58, 63, 83, 51, 41, 62,255,252, 24, 63, 79,175, 52,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,204,193, 63, 0, 0, 0,
- 63, 79,175, 52, 62,233, 32,218, 63, 83, 51, 41, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 83, 51, 41, 62,255,252, 24, 63, 86, 54, 56, 62,233, 23, 58, 63, 89,153,147, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 92,252,239, 62,233, 23, 58, 63, 89,153,147, 63, 0, 0, 0,
- 63, 86, 54, 56, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 54, 56,
- 62,233, 23, 58, 63, 89,153,147, 62,209,190,143, 63, 92,252,239, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 96,133, 78, 62,210, 92, 55, 63, 92,252,239, 62,233, 23, 58, 63, 89,153,147, 62,209,190,143,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,147, 62,209,190,143, 63, 86, 54, 56,
- 62,233, 23, 58, 63, 82,173,218, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 85,238,138, 62,187,220, 72, 63, 89,153,149, 62,165,199,201, 63, 93, 68,159, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 93, 68,159, 62,187,220, 72, 63, 89,153,147, 62,209,190,143, 63, 85,238,138,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,173,218, 62,210, 92, 55,
- 63, 85,238,138, 62,187,220, 72, 63, 89,153,147, 62,209,190,143, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 89,153,147, 62,209,190,143, 63, 93, 68,159, 62,187,220, 72, 63, 96,133, 78, 62,210, 92, 55, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 92,252,239, 62,233, 23, 58, 63, 96,133, 78, 62,210, 92, 55,
- 63, 99,131,242, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99,131,242,
- 62,233, 32,218, 63, 95,255,254, 62,255,252, 24, 63, 92,252,239, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,147, 63, 0, 0, 0, 63, 92,252,239, 62,233, 23, 58, 63, 95,255,254, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 95,255,254, 62,255,252, 24, 63, 99,131,242,
- 62,233, 32,218, 63,102,102,101, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,111,174,139, 62,198,230,223, 63,108,112,192, 62,217,196, 4, 63,105,195,133, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,195,133, 62,193,135, 37, 63,109, 21,249, 62,174, 54, 65, 63,111,174,139,
- 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,180,111,160,
- 63,111,174,139, 62,198,230,223, 63,109, 21,249, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,109, 21,249, 62,174, 54, 65, 63,105,195,133, 62,193,135, 37, 63,102,187,106, 62,169,150, 54, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99,117, 70, 62,189,208,155, 63,102,187,106, 62,169,150, 54,
- 63,105,195,133, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,105,195,133,
- 62,193,135, 37, 63,102,131,123, 62,213,159,181, 63, 99,117, 70, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 96,133, 78, 62,210, 92, 55, 63, 99,117, 70, 62,189,208,155, 63,102,131,123, 62,213,159,181,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,102,131,123, 62,213,159,181, 63,105,195,133,
- 62,193,135, 37, 63,108,112,192, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,105, 97,170, 62,236,207, 65, 63,102,102,101, 63, 0, 0, 0, 63, 99,131,242, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99,131,242, 62,233, 32,218, 63,102,131,123, 62,213,159,181, 63,105, 97,170,
- 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108,112,192, 62,217,196, 4,
- 63,105, 97,170, 62,236,207, 65, 63,102,131,123, 62,213,159,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,102,131,123, 62,213,159,181, 63, 99,131,242, 62,233, 32,218, 63, 96,133, 78, 62,210, 92, 55, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99,117, 70, 62,189,208,155, 63, 96,133, 78, 62,210, 92, 55,
- 63, 93, 68,159, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 93, 68,159,
- 62,187,220, 72, 63, 96, 56, 71, 62,166,190, 99, 63, 99,117, 70, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,102,187,106, 62,169,150, 54, 63, 99,117, 70, 62,189,208,155, 63, 96, 56, 71, 62,166,190, 99,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 96, 56, 71, 62,166,190, 99, 63, 93, 68,159,
- 62,187,220, 72, 63, 89,153,149, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 99,107, 33, 63, 9,152, 94, 63, 96, 92, 11, 63, 19, 29,253, 63, 92,238, 21, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 92,238, 21, 63, 9,150,112, 63, 95,255,254, 62,255,252, 24, 63, 99,107, 33,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,102,102,101, 63, 0, 0, 0,
- 63, 99,107, 33, 63, 9,152, 94, 63, 95,255,254, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 95,255,254, 62,255,252, 24, 63, 92,238, 21, 63, 9,150,112, 63, 89,153,147, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 69, 14, 63, 9,150,112, 63, 89,153,147, 63, 0, 0, 0,
- 63, 92,238, 21, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 92,238, 21,
- 63, 9,150,112, 63, 89,153,143, 63, 19, 98,219, 63, 86, 69, 14, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,215, 19, 63, 19, 29,252, 63, 86, 69, 14, 63, 9,150,112, 63, 89,153,143, 63, 19, 98,219,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,143, 63, 19, 98,219, 63, 92,238, 21,
- 63, 9,150,112, 63, 96, 92, 11, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 93, 30, 63, 63, 28,140,143, 63, 89,153,139, 63, 37,200, 45, 63, 86, 20,218, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 20,218, 63, 28,140,143, 63, 89,153,143, 63, 19, 98,219, 63, 93, 30, 63,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 96, 92, 11, 63, 19, 29,253,
- 63, 93, 30, 63, 63, 28,140,143, 63, 89,153,143, 63, 19, 98,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 89,153,143, 63, 19, 98,219, 63, 86, 20,218, 63, 28,140,143, 63, 82,215, 19, 63, 19, 29,252, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 86, 69, 14, 63, 9,150,112, 63, 82,215, 19, 63, 19, 29,252,
- 63, 79,200, 1, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,200, 1,
- 63, 9,152, 94, 63, 83, 51, 41, 62,255,252, 24, 63, 86, 69, 14, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,147, 63, 0, 0, 0, 63, 86, 69, 14, 63, 9,150,112, 63, 83, 51, 41, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 83, 51, 41, 62,255,252, 24, 63, 79,200, 1,
- 63, 9,152, 94, 63, 76,204,193, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61, 18, 28,237, 62,187,220, 60, 60,188, 35,151, 62,210, 92, 46, 60, 60, 74,218, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60, 60, 74,218, 62,189,208,150, 60,197,197,195, 62,166,190, 89, 61, 18, 28,237,
- 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,205,194, 62,165,199,186,
- 61, 18, 28,237, 62,187,220, 60, 60,197,197,195, 62,166,190, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,131, 23, 23, 62,166,190, 89, 63,129,120,150, 62,189,208,150, 63,127,171, 15, 62,169,150, 52, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,124,162,241, 62,193,135, 36, 63,127,171, 15, 62,169,150, 52,
- 63,129,120,150, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,129,120,150,
- 62,189,208,150, 63,127,226,244, 62,213,159,179, 63,124,162,241, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,121,245,179, 62,217,196, 6, 63,124,162,241, 62,193,135, 36, 63,127,226,244, 62,213,159,179,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,127,226,244, 62,213,159,179, 63,129,120,150,
- 62,189,208,150, 63,130,240,142, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,129,113, 59, 62,233, 32,214, 63,128, 0, 0, 63, 0, 0, 0, 63,125, 4,194, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,125, 4,194, 62,236,207, 67, 63,127,226,244, 62,213,159,179, 63,129,113, 59,
- 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,130,240,142, 62,210, 92, 46,
- 63,129,113, 59, 62,233, 32,214, 63,127,226,244, 62,213,159,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,127,226,244, 62,213,159,179, 63,125, 4,194, 62,236,207, 67, 63,121,245,179, 62,217,196, 6, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,124,162,241, 62,193,135, 36, 63,121,245,179, 62,217,196, 6,
- 63,118,183,239, 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,118,183,239,
- 62,198,230,227, 63,121, 80,133, 62,174, 54, 65, 63,124,162,241, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,127,171, 15, 62,169,150, 52, 63,124,162,241, 62,193,135, 36, 63,121, 80,133, 62,174, 54, 65,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121, 80,133, 62,174, 54, 65, 63,118,183,239,
- 62,198,230,227, 63,115, 51, 65, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 60, 56,157,110, 62,233, 32,214, 60,188, 35,151, 62,210, 92, 46, 61, 22,151, 95, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 22,151, 95, 62,233, 23, 55, 60,204,204,176, 62,255,252, 24, 60, 56,157,110,
- 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 38, 11, 79,167, 63, 0, 0, 0,
- 60, 56,157,110, 62,233, 32,214, 60,204,204,176, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 60,204,204,176, 62,255,252, 24, 61, 22,151, 95, 62,233, 23, 55, 61, 76,204,215, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,129,129, 87, 62,233, 23, 57, 61, 76,204,215, 63, 0, 0, 0,
- 61, 22,151, 95, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 22,151, 95,
- 62,233, 23, 55, 61, 76,205, 68, 62,209,190,135, 61,129,129, 87, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,157,196, 92, 62,210, 92, 49, 61,129,129, 87, 62,233, 23, 57, 61, 76,205, 68, 62,209,190,135,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,205, 68, 62,209,190,135, 61, 22,151, 95,
- 62,233, 23, 55, 60,188, 35,151, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61, 18, 28,237, 62,187,220, 60, 61, 76,205,194, 62,165,199,186, 61,131,191, 7, 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,131,191, 7, 62,187,220, 62, 61, 76,205, 68, 62,209,190,135, 61, 18, 28,237,
- 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,188, 35,151, 62,210, 92, 46,
- 61, 18, 28,237, 62,187,220, 60, 61, 76,205, 68, 62,209,190,135, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61, 76,205, 68, 62,209,190,135, 61,131,191, 7, 62,187,220, 62, 61,157,196, 92, 62,210, 92, 49, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,129,129, 87, 62,233, 23, 57, 61,157,196, 92, 62,210, 92, 49,
- 61,181,185, 89, 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,181,185, 89,
- 62,233, 32,214, 61,153,153,154, 62,255,252, 25, 61,129,129, 87, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,204,215, 63, 0, 0, 0, 61,129,129, 87, 62,233, 23, 57, 61,153,153,154, 62,255,252, 25,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,153,153,154, 62,255,252, 25, 61,181,185, 89,
- 62,233, 32,214, 61,204,204,215, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 11,135, 1, 62,198,230,228, 61,253, 31,171, 62,217,196, 6, 61,231,181,251, 62,193,135, 38, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,231,181,251, 62,193,135, 38, 62, 1, 36,204, 62,174, 54, 70, 62, 11,135, 1,
- 62,198,230,228, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62,180,111,165,
- 62, 11,135, 1, 62,198,230,228, 62, 1, 36,204, 62,174, 54, 70, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 1, 36,204, 62,174, 54, 70, 61,231,181,251, 62,193,135, 38, 61,207,117, 70, 62,169,150, 54, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,181, 68, 35, 62,189,208,153, 61,207,117, 70, 62,169,150, 54,
- 61,231,181,251, 62,193,135, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,231,181,251,
- 62,193,135, 38, 61,205,181,164, 62,213,159,180, 61,181, 68, 35, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,157,196, 92, 62,210, 92, 49, 61,181, 68, 35, 62,189,208,153, 61,205,181,164, 62,213,159,180,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,205,181,164, 62,213,159,180, 61,231,181,251,
- 62,193,135, 38, 61,253, 31,171, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,228,166,251, 62,236,207, 67, 61,204,204,215, 63, 0, 0, 0, 61,181,185, 89, 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,181,185, 89, 62,233, 32,214, 61,205,181,164, 62,213,159,180, 61,228,166,251,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,253, 31,171, 62,217,196, 6,
- 61,228,166,251, 62,236,207, 67, 61,205,181,164, 62,213,159,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,205,181,164, 62,213,159,180, 61,181,185, 89, 62,233, 32,214, 61,157,196, 92, 62,210, 92, 49, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,181, 68, 35, 62,189,208,153, 61,157,196, 92, 62,210, 92, 49,
- 61,131,191, 7, 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,131,191, 7,
- 62,187,220, 62, 61,155, 92, 79, 62,166,190, 91, 61,181, 68, 35, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,207,117, 70, 62,169,150, 54, 61,181, 68, 35, 62,189,208,153, 61,155, 92, 79, 62,166,190, 91,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,155, 92, 79, 62,166,190, 91, 61,131,191, 7,
- 62,187,220, 62, 61, 76,205,194, 62,165,199,186, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,180,242,172, 63, 9,152, 96, 61,156,122, 1, 63, 19, 29,254, 61,129, 10,100, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,129, 10,100, 63, 9,150,113, 61,153,153,154, 62,255,252, 25, 61,180,242,172,
- 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,204,204,215, 63, 0, 0, 0,
- 61,180,242,172, 63, 9,152, 96, 61,153,153,154, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,153,153,154, 62,255,252, 25, 61,129, 10,100, 63, 9,150,113, 61, 76,204,215, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 23,132,109, 63, 9,150,113, 61, 76,204,215, 63, 0, 0, 0,
- 61,129, 10,100, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,129, 10,100,
- 63, 9,150,113, 61, 76,204, 91, 63, 19, 98,220, 61, 23,132,109, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 60,193, 73,174, 63, 19, 29,253, 61, 23,132,109, 63, 9,150,113, 61, 76,204, 91, 63, 19, 98,220,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,204, 91, 63, 19, 98,220, 61,129, 10,100,
- 63, 9,150,113, 61,156,122, 1, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,130,139,166, 63, 28,140,145, 61, 76,203,246, 63, 37,200, 48, 61, 20,129, 13, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 20,129, 13, 63, 28,140,143, 61, 76,204, 91, 63, 19, 98,220, 61,130,139,166,
- 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,156,122, 1, 63, 19, 29,254,
- 61,130,139,166, 63, 28,140,145, 61, 76,204, 91, 63, 19, 98,220, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61, 76,204, 91, 63, 19, 98,220, 61, 20,129, 13, 63, 28,140,143, 60,193, 73,174, 63, 19, 29,253, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 23,132,109, 63, 9,150,113, 60,193, 73,174, 63, 19, 29,253,
- 60, 62,207,114, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60, 62,207,114,
- 63, 9,152, 94, 60,204,204,176, 62,255,252, 24, 61, 23,132,109, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,204,215, 63, 0, 0, 0, 61, 23,132,109, 63, 9,150,113, 60,204,204,176, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,204,204,176, 62,255,252, 24, 60, 62,207,114,
- 63, 9,152, 94, 38, 11, 79,167, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,113, 83,237, 62,187,220, 79, 62,100, 81, 63, 62,210, 92, 60, 62, 88,145,110, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 88,145,110, 62,189,208,167, 62,101,133, 91, 62,166,190,112, 62,113, 83,237,
- 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62,165,199,206,
- 62,113, 83,237, 62,187,220, 79, 62,101,133, 91, 62,166,190,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,101,133, 91, 62,166,190,112, 62, 88,145,110, 62,189,208,167, 62, 75,120,239, 62,169,150, 70, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 63, 88,144, 62,193,135, 46, 62, 75,120,239, 62,169,150, 70,
- 62, 88,145,110, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 88,145,110,
- 62,189,208,167, 62, 76, 88,170, 62,213,159,187, 62, 63, 88,144, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 52,163,179, 62,217,196, 7, 62, 63, 88,144, 62,193,135, 46, 62, 76, 88,170, 62,213,159,187,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 76, 88,170, 62,213,159,187, 62, 88,145,110,
- 62,189,208,167, 62,100, 81, 63, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 88, 86,190, 62,233, 32,221, 62, 76,204,254, 63, 0, 0, 0, 62, 64,223,251, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 64,223,251, 62,236,207, 67, 62, 76, 88,170, 62,213,159,187, 62, 88, 86,190,
- 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,100, 81, 63, 62,210, 92, 60,
- 62, 88, 86,190, 62,233, 32,221, 62, 76, 88,170, 62,213,159,187, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 76, 88,170, 62,213,159,187, 62, 64,223,251, 62,236,207, 67, 62, 52,163,179, 62,217,196, 7, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 63, 88,144, 62,193,135, 46, 62, 52,163,179, 62,217,196, 7,
- 62, 39,172,153, 62,198,230,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 39,172,153,
- 62,198,230,230, 62, 50, 14,213, 62,174, 54, 78, 62, 63, 88,144, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 75,120,239, 62,169,150, 70, 62, 63, 88,144, 62,193,135, 46, 62, 50, 14,213, 62,174, 54, 78,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 50, 14,213, 62,174, 54, 78, 62, 39,172,153,
- 62,198,230,230, 62, 25,153,214, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 88, 86,190, 62,233, 32,221, 62,100, 81, 63, 62,210, 92, 60, 62,114,114,166, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,114,114,166, 62,233, 23, 63, 62,102,102,126, 62,255,252, 25, 62, 88, 86,190,
- 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 76,204,254, 63, 0, 0, 0,
- 62, 88, 86,190, 62,233, 32,221, 62,102,102,126, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,102,102,126, 62,255,252, 25, 62,114,114,166, 62,233, 23, 63, 62,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,134,198,173, 62,233, 23, 63, 62,128, 0, 0, 63, 0, 0, 0,
- 62,114,114,166, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,114,114,166,
- 62,233, 23, 63, 62,128, 0, 0, 62,209,190,149, 62,134,198,173, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,141,215, 97, 62,210, 92, 60, 62,134,198,173, 62,233, 23, 63, 62,128, 0, 0, 62,209,190,149,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62,209,190,149, 62,114,114,166,
- 62,233, 23, 63, 62,100, 81, 63, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,113, 83,237, 62,187,220, 79, 62,128, 0, 0, 62,165,199,206, 62,135, 86, 9, 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,135, 86, 9, 62,187,220, 79, 62,128, 0, 0, 62,209,190,149, 62,113, 83,237,
- 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,100, 81, 63, 62,210, 92, 60,
- 62,113, 83,237, 62,187,220, 79, 62,128, 0, 0, 62,209,190,149, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,128, 0, 0, 62,209,190,149, 62,135, 86, 9, 62,187,220, 79, 62,141,215, 97, 62,210, 92, 60, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,134,198,173, 62,233, 23, 63, 62,141,215, 97, 62,210, 92, 60,
- 62,147,212,161, 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147,212,161,
- 62,233, 32,221, 62,140,204,193, 62,255,252, 25, 62,134,198,173, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 0, 0, 0, 62,134,198,173, 62,233, 23, 63, 62,140,204,193, 62,255,252, 25,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,140,204,193, 62,255,252, 25, 62,147,212,161,
- 62,233, 32,221, 62,153,153,129, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,172, 41,180, 62,198,230,227, 62,165,174, 39, 62,217,196, 7, 62,160, 83,184, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,160, 83,184, 62,193,135, 46, 62,166,248,150, 62,174, 54, 78, 62,172, 41,180,
- 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,180,111,165,
- 62,172, 41,180, 62,198,230,227, 62,166,248,150, 62,174, 54, 78, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,166,248,150, 62,174, 54, 78, 62,160, 83,184, 62,193,135, 46, 62,154, 67,137, 62,169,150, 70, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147,183, 73, 62,189,208,167, 62,154, 67,137, 62,169,150, 70,
- 62,160, 83,184, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,160, 83,184,
- 62,193,135, 46, 62,153,211,171, 62,213,159,187, 62,147,183, 73, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,141,215, 97, 62,210, 92, 60, 62,147,183, 73, 62,189,208,167, 62,153,211,171, 62,213,159,187,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,153,211,171, 62,213,159,187, 62,160, 83,184,
- 62,193,135, 46, 62,165,174, 39, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,159,144, 3, 62,236,207, 67, 62,153,153,129, 63, 0, 0, 0, 62,147,212,161, 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147,212,161, 62,233, 32,221, 62,153,211,171, 62,213,159,187, 62,159,144, 3,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165,174, 39, 62,217,196, 7,
- 62,159,144, 3, 62,236,207, 67, 62,153,211,171, 62,213,159,187, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,153,211,171, 62,213,159,187, 62,147,212,161, 62,233, 32,221, 62,141,215, 97, 62,210, 92, 60, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147,183, 73, 62,189,208,167, 62,141,215, 97, 62,210, 92, 60,
- 62,135, 86, 9, 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,135, 86, 9,
- 62,187,220, 79, 62,141, 61, 82, 62,166,190,112, 62,147,183, 73, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,154, 67,137, 62,169,150, 70, 62,147,183, 73, 62,189,208,167, 62,141, 61, 82, 62,166,190,112,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,141, 61, 82, 62,166,190,112, 62,135, 86, 9,
- 62,187,220, 79, 62,128, 0, 0, 62,165,199,206, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,147,163, 1, 63, 9,152, 91, 62,141,132,224, 63, 19, 29,246, 62,134,168,251, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,134,168,251, 63, 9,150,107, 62,140,204,193, 62,255,252, 25, 62,147,163, 1,
- 63, 9,152, 91, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,153,153,129, 63, 0, 0, 0,
- 62,147,163, 1, 63, 9,152, 91, 62,140,204,193, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,140,204,193, 62,255,252, 25, 62,134,168,251, 63, 9,150,107, 62,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,114,174, 11, 63, 9,150,107, 62,128, 0, 0, 63, 0, 0, 0,
- 62,134,168,251, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,134,168,251,
- 63, 9,150,107, 62,128, 0, 0, 63, 19, 98,209, 62,114,174, 11, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,100,246, 64, 63, 19, 29,246, 62,114,174, 11, 63, 9,150,107, 62,128, 0, 0, 63, 19, 98,209,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 19, 98,209, 62,134,168,251,
- 63, 9,150,107, 62,141,132,224, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,135, 9, 86, 63, 28,140,130, 62,128, 0, 0, 63, 37,200, 23, 62,113,237, 83, 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,113,237, 83, 63, 28,140,130, 62,128, 0, 0, 63, 19, 98,209, 62,135, 9, 86,
- 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,141,132,224, 63, 19, 29,246,
- 62,135, 9, 86, 63, 28,140,130, 62,128, 0, 0, 63, 19, 98,209, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,128, 0, 0, 63, 19, 98,209, 62,113,237, 83, 63, 28,140,130, 62,100,246, 64, 63, 19, 29,246, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,114,174, 11, 63, 9,150,107, 62,100,246, 64, 63, 19, 29,246,
- 62, 88,185,255, 63, 9,152, 90, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 88,185,255,
- 63, 9,152, 90, 62,102,102,126, 62,255,252, 25, 62,114,174, 11, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 63, 0, 0, 0, 62,114,174, 11, 63, 9,150,107, 62,102,102,126, 62,255,252, 25,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,102,102,126, 62,255,252, 25, 62, 88,185,255,
- 63, 9,152, 90, 62, 76,204,254, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,223, 16, 63, 62,187,220, 62, 62,216,142,233, 62,210, 92, 49, 62,210,174,248, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,210,174,248, 62,189,208,153, 62,217, 40,237, 62,166,190, 91, 62,223, 16, 63,
- 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 72, 62,165,199,183,
- 62,223, 16, 63, 62,187,220, 62, 62,217, 40,237, 62,166,190, 91, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,217, 40,237, 62,166,190, 91, 62,210,174,248, 62,189,208,153, 62,204, 34,175, 62,169,150, 54, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198, 18,129, 62,193,135, 37, 62,204, 34,175, 62,169,150, 54,
- 62,210,174,248, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,210,174,248,
- 62,189,208,153, 62,204,146,151, 62,213,159,180, 62,198, 18,129, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,192,184, 21, 62,217,196, 6, 62,198, 18,129, 62,193,135, 37, 62,204,146,151, 62,213,159,180,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,204,146,151, 62,213,159,180, 62,210,174,248,
- 62,189,208,153, 62,216,142,233, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,210,145,170, 62,233, 32,214, 62,204,204,202, 63, 0, 0, 0, 62,198,214, 65, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198,214, 65, 62,236,207, 67, 62,204,146,151, 62,213,159,180, 62,210,145,170,
- 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,216,142,233, 62,210, 92, 49,
- 62,210,145,170, 62,233, 32,214, 62,204,146,151, 62,213,159,180, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,204,146,151, 62,213,159,180, 62,198,214, 65, 62,236,207, 67, 62,192,184, 21, 62,217,196, 6, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,198, 18,129, 62,193,135, 37, 62,192,184, 21, 62,217,196, 6,
- 62,186, 60,127, 62,198,230,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,186, 60,127,
- 62,198,230,225, 62,191,109,154, 62,174, 54, 68, 62,198, 18,129, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,204, 34,175, 62,169,150, 54, 62,198, 18,129, 62,193,135, 37, 62,191,109,154, 62,174, 54, 68,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,191,109,154, 62,174, 54, 68, 62,186, 60,127,
- 62,198,230,225, 62,179, 51, 21, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,210,145,170, 62,233, 32,214, 62,216,142,233, 62,210, 92, 49, 62,223,159,171, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223,159,171, 62,233, 23, 57, 62,217,153,154, 62,255,252, 24, 62,210,145,170,
- 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,204,204,202, 63, 0, 0, 0,
- 62,210,145,170, 62,233, 32,214, 62,217,153,154, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,217,153,154, 62,255,252, 24, 62,223,159,171, 62,233, 23, 57, 62,230,102,101, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237, 45, 20, 62,233, 23, 55, 62,230,102,101, 63, 0, 0, 0,
- 62,223,159,171, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223,159,171,
- 62,233, 23, 57, 62,230,102, 88, 62,209,190,135, 62,237, 45, 20, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,244, 61,199, 62,210, 92, 46, 62,237, 45, 20, 62,233, 23, 55, 62,230,102, 88, 62,209,190,135,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 88, 62,209,190,135, 62,223,159,171,
- 62,233, 23, 57, 62,216,142,233, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,223, 16, 63, 62,187,220, 62, 62,230,102, 72, 62,165,199,183, 62,237,188, 99, 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237,188, 99, 62,187,220, 60, 62,230,102, 88, 62,209,190,135, 62,223, 16, 63,
- 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,216,142,233, 62,210, 92, 49,
- 62,223, 16, 63, 62,187,220, 62, 62,230,102, 88, 62,209,190,135, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,230,102, 88, 62,209,190,135, 62,237,188, 99, 62,187,220, 60, 62,244, 61,199, 62,210, 92, 46, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237, 45, 20, 62,233, 23, 55, 62,244, 61,199, 62,210, 92, 46,
- 62,250, 59, 21, 62,233, 32,213, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,250, 59, 21,
- 62,233, 32,213, 62,243, 51, 53, 62,255,252, 24, 62,237, 45, 20, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,101, 63, 0, 0, 0, 62,237, 45, 20, 62,233, 23, 55, 62,243, 51, 53, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,243, 51, 53, 62,255,252, 24, 62,250, 59, 21,
- 62,233, 32,213, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 9, 72, 17, 62,198,230,227, 63, 6, 10, 77, 62,217,196, 6, 63, 3, 93, 15, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 93, 15, 62,193,135, 36, 63, 6,175,123, 62,174, 54, 65, 63, 9, 72, 17,
- 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,180,111,160,
- 63, 9, 72, 17, 62,198,230,227, 63, 6,175,123, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 6,175,123, 62,174, 54, 65, 63, 3, 93, 15, 62,193,135, 36, 63, 0, 84,241, 62,169,150, 52, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,250, 29,169, 62,189,208,150, 63, 0, 84,241, 62,169,150, 52,
- 63, 3, 93, 15, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3, 93, 15,
- 62,193,135, 36, 63, 0, 29, 12, 62,213,159,179, 62,250, 29,169, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,244, 61,199, 62,210, 92, 46, 62,250, 29,169, 62,189,208,150, 63, 0, 29, 12, 62,213,159,179,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 0, 29, 12, 62,213,159,179, 63, 3, 93, 15,
- 62,193,135, 36, 63, 6, 10, 77, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 2,251, 62, 62,236,207, 67, 63, 0, 0, 0, 63, 0, 0, 0, 62,250, 59, 21, 62,233, 32,213, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,250, 59, 21, 62,233, 32,213, 63, 0, 29, 12, 62,213,159,179, 63, 2,251, 62,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6, 10, 77, 62,217,196, 6,
- 63, 2,251, 62, 62,236,207, 67, 63, 0, 29, 12, 62,213,159,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 0, 29, 12, 62,213,159,179, 62,250, 59, 21, 62,233, 32,213, 62,244, 61,199, 62,210, 92, 46, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,250, 29,169, 62,189,208,150, 62,244, 61,199, 62,210, 92, 46,
- 62,237,188, 99, 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237,188, 99,
- 62,187,220, 60, 62,243,163,164, 62,166,190, 89, 62,250, 29,169, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 0, 84,241, 62,169,150, 52, 62,250, 29,169, 62,189,208,150, 62,243,163,164, 62,166,190, 89,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,243,163,164, 62,166,190, 89, 62,237,188, 99,
- 62,187,220, 60, 62,230,102, 72, 62,165,199,183, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,250, 9,132, 63, 9,152, 94, 62,243,235,101, 63, 19, 29,252, 62,237, 15,114, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237, 15,114, 63, 9,150,113, 62,243, 51, 53, 62,255,252, 24, 62,250, 9,132,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0,
- 62,250, 9,132, 63, 9,152, 94, 62,243, 51, 53, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,243, 51, 53, 62,255,252, 24, 62,237, 15,114, 63, 9,150,113, 62,230,102,101, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223,189,103, 63, 9,150,112, 62,230,102,101, 63, 0, 0, 0,
- 62,237, 15,114, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,237, 15,114,
- 63, 9,150,113, 62,230,102,117, 63, 19, 98,220, 62,223,189,103, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,216,225,128, 63, 19, 29,254, 62,223,189,103, 63, 9,150,112, 62,230,102,117, 63, 19, 98,220,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,117, 63, 19, 98,220, 62,237, 15,114,
- 63, 9,150,113, 62,243,235,101, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,237,111,222, 63, 28,140,143, 62,230,102,129, 63, 37,200, 48, 62,223, 93, 22, 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223, 93, 22, 63, 28,140,145, 62,230,102,117, 63, 19, 98,220, 62,237,111,222,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,243,235,101, 63, 19, 29,252,
- 62,237,111,222, 63, 28,140,143, 62,230,102,117, 63, 19, 98,220, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,230,102,117, 63, 19, 98,220, 62,223, 93, 22, 63, 28,140,145, 62,216,225,128, 63, 19, 29,254, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,223,189,103, 63, 9,150,112, 62,216,225,128, 63, 19, 29,254,
- 62,210,195, 85, 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,210,195, 85,
- 63, 9,152, 96, 62,217,153,154, 62,255,252, 24, 62,223,189,103, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102,101, 63, 0, 0, 0, 62,223,189,103, 63, 9,150,112, 62,217,153,154, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,217,153,154, 62,255,252, 24, 62,210,195, 85,
- 63, 9,152, 96, 62,204,204,202, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 34,187, 97, 62,187,220, 72, 63, 31,122,178, 62,210, 92, 55, 63, 28,138,186, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,138,186, 62,189,208,155, 63, 31,199,185, 62,166,190, 96, 63, 34,187, 97,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,107, 62,165,199,201,
- 63, 34,187, 97, 62,187,220, 72, 63, 31,199,185, 62,166,190, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 31,199,185, 62,166,190, 96, 63, 28,138,186, 62,189,208,155, 63, 25, 68,150, 62,169,150, 54, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22, 60,123, 62,193,135, 36, 63, 25, 68,150, 62,169,150, 54,
- 63, 28,138,186, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,138,186,
- 62,189,208,155, 63, 25,124,133, 62,213,159,181, 63, 22, 60,123, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,143, 64, 62,217,196, 4, 63, 22, 60,123, 62,193,135, 36, 63, 25,124,133, 62,213,159,181,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,124,133, 62,213,159,181, 63, 28,138,186,
- 62,189,208,155, 63, 31,122,178, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 28,124, 14, 62,233, 32,218, 63, 25,153,155, 63, 0, 0, 0, 63, 22,158, 86, 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22,158, 86, 62,236,207, 65, 63, 25,124,133, 62,213,159,181, 63, 28,124, 14,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,122,178, 62,210, 92, 55,
- 63, 28,124, 14, 62,233, 32,218, 63, 25,124,133, 62,213,159,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 25,124,133, 62,213,159,181, 63, 22,158, 86, 62,236,207, 65, 63, 19,143, 64, 62,217,196, 4, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 22, 60,123, 62,193,135, 36, 63, 19,143, 64, 62,217,196, 4,
- 63, 16, 81,117, 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 16, 81,117,
- 62,198,230,223, 63, 18,234, 7, 62,174, 54, 65, 63, 22, 60,123, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 25, 68,150, 62,169,150, 54, 63, 22, 60,123, 62,193,135, 36, 63, 18,234, 7, 62,174, 54, 65,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 18,234, 7, 62,174, 54, 65, 63, 16, 81,117,
- 62,198,230,223, 63, 12,204,191, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 28,124, 14, 62,233, 32,218, 63, 31,122,178, 62,210, 92, 55, 63, 35, 3, 17, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 35, 3, 17, 62,233, 23, 58, 63, 32, 0, 2, 62,255,252, 24, 63, 28,124, 14,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 25,153,155, 63, 0, 0, 0,
- 63, 28,124, 14, 62,233, 32,218, 63, 32, 0, 2, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 32, 0, 2, 62,255,252, 24, 63, 35, 3, 17, 62,233, 23, 58, 63, 38,102,109, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 41,201,200, 62,233, 23, 58, 63, 38,102,109, 63, 0, 0, 0,
- 63, 35, 3, 17, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 35, 3, 17,
- 62,233, 23, 58, 63, 38,102,109, 62,209,190,143, 63, 41,201,200, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 82, 38, 62,210, 92, 55, 63, 41,201,200, 62,233, 23, 58, 63, 38,102,109, 62,209,190,143,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,109, 62,209,190,143, 63, 35, 3, 17,
- 62,233, 23, 58, 63, 31,122,178, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 34,187, 97, 62,187,220, 72, 63, 38,102,107, 62,165,199,201, 63, 42, 17,118, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 42, 17,118, 62,187,220, 72, 63, 38,102,109, 62,209,190,143, 63, 34,187, 97,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,122,178, 62,210, 92, 55,
- 63, 34,187, 97, 62,187,220, 72, 63, 38,102,109, 62,209,190,143, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 38,102,109, 62,209,190,143, 63, 42, 17,118, 62,187,220, 72, 63, 45, 82, 38, 62,210, 92, 55, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 41,201,200, 62,233, 23, 58, 63, 45, 82, 38, 62,210, 92, 55,
- 63, 48, 80,204, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 80,204,
- 62,233, 32,218, 63, 44,204,215, 62,255,252, 23, 63, 41,201,200, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,109, 63, 0, 0, 0, 63, 41,201,200, 62,233, 23, 58, 63, 44,204,215, 62,255,252, 23,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 44,204,215, 62,255,252, 23, 63, 48, 80,204,
- 62,233, 32,218, 63, 51, 51, 63, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 60,123, 85, 62,198,230,253, 63, 57, 61,144, 62,217,196, 19, 63, 54,144, 86, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54,144, 86, 62,193,135, 68, 63, 57,226,196, 62,174, 54,114, 63, 60,123, 85,
- 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,180,111,211,
- 63, 60,123, 85, 62,198,230,253, 63, 57,226,196, 62,174, 54,114, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 57,226,196, 62,174, 54,114, 63, 54,144, 86, 62,193,135, 68, 63, 51,136, 58, 62,169,150, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 66, 27, 62,189,208,173, 63, 51,136, 58, 62,169,150, 90,
- 63, 54,144, 86, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54,144, 86,
- 62,193,135, 68, 63, 51, 80, 80, 62,213,159,192, 63, 48, 66, 27, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 82, 38, 62,210, 92, 55, 63, 48, 66, 27, 62,189,208,173, 63, 51, 80, 80, 62,213,159,192,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 51, 80, 80, 62,213,159,192, 63, 54,144, 86,
- 62,193,135, 68, 63, 57, 61,144, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 54, 46,128, 62,236,207, 75, 63, 51, 51, 63, 63, 0, 0, 0, 63, 48, 80,204, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 80,204, 62,233, 32,218, 63, 51, 80, 80, 62,213,159,192, 63, 54, 46,128,
- 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 61,144, 62,217,196, 19,
- 63, 54, 46,128, 62,236,207, 75, 63, 51, 80, 80, 62,213,159,192, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 51, 80, 80, 62,213,159,192, 63, 48, 80,204, 62,233, 32,218, 63, 45, 82, 38, 62,210, 92, 55, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 66, 27, 62,189,208,173, 63, 45, 82, 38, 62,210, 92, 55,
- 63, 42, 17,118, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 42, 17,118,
- 62,187,220, 72, 63, 45, 5, 26, 62,166,190,117, 63, 48, 66, 27, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 51,136, 58, 62,169,150, 90, 63, 48, 66, 27, 62,189,208,173, 63, 45, 5, 26, 62,166,190,117,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 5, 26, 62,166,190,117, 63, 42, 17,118,
- 62,187,220, 72, 63, 38,102,107, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 48, 55,255, 63, 9,152, 94, 63, 45, 40,237, 63, 19, 29,252, 63, 41,186,242, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 41,186,242, 63, 9,150,112, 63, 44,204,215, 62,255,252, 23, 63, 48, 55,255,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 51, 51, 63, 63, 0, 0, 0,
- 63, 48, 55,255, 63, 9,152, 94, 63, 44,204,215, 62,255,252, 23, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 44,204,215, 62,255,252, 23, 63, 41,186,242, 63, 9,150,112, 63, 38,102,109, 63, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 35, 17,235, 63, 9,150,112, 63, 38,102,109, 63, 0, 0, 0,
- 63, 41,186,242, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 41,186,242,
- 63, 9,150,112, 63, 38,102,113, 63, 19, 98,219, 63, 35, 17,235, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,163,245, 63, 19, 29,253, 63, 35, 17,235, 63, 9,150,112, 63, 38,102,113, 63, 19, 98,219,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,113, 63, 19, 98,219, 63, 41,186,242,
- 63, 9,150,112, 63, 45, 40,237, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 41,235, 38, 63, 28,140,141, 63, 38,102,117, 63, 37,200, 45, 63, 34,225,192, 63, 28,140,142, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 34,225,192, 63, 28,140,142, 63, 38,102,113, 63, 19, 98,219, 63, 41,235, 38,
- 63, 28,140,141, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 45, 40,237, 63, 19, 29,252,
- 63, 41,235, 38, 63, 28,140,141, 63, 38,102,113, 63, 19, 98,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 38,102,113, 63, 19, 98,219, 63, 34,225,192, 63, 28,140,142, 63, 31,163,245, 63, 19, 29,253, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 35, 17,235, 63, 9,150,112, 63, 31,163,245, 63, 19, 29,253,
- 63, 28,148,223, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,148,223,
- 63, 9,152, 94, 63, 32, 0, 2, 62,255,252, 24, 63, 35, 17,235, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,109, 63, 0, 0, 0, 63, 35, 17,235, 63, 9,150,112, 63, 32, 0, 2, 62,255,252, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 32, 0, 2, 62,255,252, 24, 63, 28,148,223,
- 63, 9,152, 94, 63, 25,153,155, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,107,129,188, 62,128, 45, 66, 63, 99, 71,235, 62,120, 76,222, 63,106, 37, 94, 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,106, 37, 94, 62, 83, 97, 84, 63,115, 51, 65, 62, 97,151,248, 63,107,129,188,
- 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,135, 83,151,
- 63,107,129,188, 62,128, 45, 66, 63,115, 51, 65, 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,115, 51, 65, 62, 97,151,248, 63,106, 37, 94, 62, 83, 97, 84, 63,115, 51, 65, 62, 52,111, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,107,129,188, 62,128, 45, 66, 63,115, 51, 65, 62,135, 83,151,
- 63,108,123,142, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108,123,142,
- 62,151,144,169, 63,101, 50,231, 62,146,201, 17, 63,107,129,188, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 99, 71,235, 62,120, 76,222, 63,107,129,188, 62,128, 45, 66, 63,101, 50,231, 62,146,201, 17,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,101, 50,231, 62,146,201, 17, 63,108,123,142,
- 62,151,144,169, 63,102,187,106, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 96, 56, 71, 62,166,190, 99, 63, 89,153,149, 62,165,199,201, 63, 93,238, 22, 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 93,238, 22, 62,144,101,243, 63,101, 50,231, 62,146,201, 17, 63, 96, 56, 71,
- 62,166,190, 99, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,102,187,106, 62,169,150, 54,
- 63, 96, 56, 71, 62,166,190, 99, 63,101, 50,231, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,101, 50,231, 62,146,201, 17, 63, 93,238, 22, 62,144,101,243, 63, 99, 71,235, 62,120, 76,222, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,109, 21,249, 62,174, 54, 65, 63,102,187,106, 62,169,150, 54,
- 63,108,123,142, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,108,123,142,
- 62,151,144,169, 63,115, 51, 65, 62,157,231, 93, 63,109, 21,249, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,180,111,160, 63,109, 21,249, 62,174, 54, 65, 63,115, 51, 65, 62,157,231, 93,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,157,231, 93, 63,108,123,142,
- 62,151,144,169, 63,115, 51, 65, 62,135, 83,151, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 89,153,149, 62,115,162, 79, 63, 99, 71,235, 62,120, 76,222, 63, 93,238, 22, 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 93,238, 22, 62,144,101,243, 63, 85, 69, 21, 62,144,102, 3, 63, 89,153,149,
- 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,235, 68, 62,120, 77, 37,
- 63, 89,153,149, 62,115,162, 79, 63, 85, 69, 21, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 85, 69, 21, 62,144,102, 3, 63, 93,238, 22, 62,144,101,243, 63, 89,153,149, 62,165,199,201, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,149, 62,115,162, 79, 63, 79,235, 68, 62,120, 77, 37,
- 63, 83,186, 24, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 83,186, 24,
- 62, 70,176,245, 63, 95,121, 22, 62, 70,176,204, 63, 89,153,149, 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 99, 71,235, 62,120, 76,222, 63, 89,153,149, 62,115,162, 79, 63, 95,121, 22, 62, 70,176,204,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 95,121, 22, 62, 70,176,204, 63, 83,186, 24,
- 62, 70,176,245, 63, 89,153,152, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,103,119, 61, 62, 30,253,179, 63,115, 51, 65, 62, 52,111, 90, 63,106, 37, 94, 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,106, 37, 94, 62, 83, 97, 84, 63, 95,121, 22, 62, 70,176,204, 63,103,119, 61,
- 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,152, 62, 23, 31,198,
- 63,103,119, 61, 62, 30,253,179, 63, 95,121, 22, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 95,121, 22, 62, 70,176,204, 63,106, 37, 94, 62, 83, 97, 84, 63, 99, 71,235, 62,120, 76,222, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 75,187,248, 62, 30,253,241, 63, 89,153,152, 62, 23, 31,198,
- 63, 83,186, 24, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 83,186, 24,
- 62, 70,176,245, 63, 73, 13,214, 62, 83, 97,181, 63, 75,187,248, 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62, 52,111,202, 63, 75,187,248, 62, 30,253,241, 63, 73, 13,214, 62, 83, 97,181,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 73, 13,214, 62, 83, 97,181, 63, 83,186, 24,
- 62, 70,176,245, 63, 79,235, 68, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 89,153,152, 61,147, 41,111, 63, 64, 0, 0, 61,180,111,195, 63, 64, 0, 0, 61, 52, 65,111, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 61, 52, 65,111, 63,117, 49, 38, 61, 52, 64,225, 63, 89,153,152,
- 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 61,180,111, 83,
- 63, 89,153,152, 61,147, 41,111, 63,117, 49, 38, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,117, 49, 38, 61, 52, 64,225, 63, 64, 0, 0, 61, 52, 65,111, 63,121,222,208,178,239, 9,102, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,152, 61,147, 41,111, 63,115, 51, 65, 61,180,111, 83,
- 63, 99, 51,172, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99, 51,172,
- 61,231, 46, 48, 63, 79,255,135, 61,231, 46,120, 63, 89,153,152, 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 61,180,111,195, 63, 89,153,152, 61,147, 41,111, 63, 79,255,135, 61,231, 46,120,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,255,135, 61,231, 46,120, 63, 99, 51,172,
- 61,231, 46, 48, 63, 89,153,152, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 75,187,248, 62, 30,253,241, 63, 64, 0, 0, 62, 52,111,202, 63, 64, 0, 0, 62, 7, 71, 24, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62, 7, 71, 24, 63, 79,255,135, 61,231, 46,120, 63, 75,187,248,
- 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,152, 62, 23, 31,198,
- 63, 75,187,248, 62, 30,253,241, 63, 79,255,135, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 79,255,135, 61,231, 46,120, 63, 64, 0, 0, 62, 7, 71, 24, 63, 64, 0, 0, 61,180,111,195, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,103,119, 61, 62, 30,253,179, 63, 89,153,152, 62, 23, 31,198,
- 63, 99, 51,172, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 99, 51,172,
- 61,231, 46, 48, 63,115, 51, 66, 62, 7, 70,199, 63,103,119, 61, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62, 52,111, 90, 63,103,119, 61, 62, 30,253,179, 63,115, 51, 66, 62, 7, 70,199,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 66, 62, 7, 70,199, 63, 99, 51,172,
- 61,231, 46, 48, 63,115, 51, 65, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 71,177,122, 62,128, 45,120, 63, 64, 0, 0, 62,135, 83,218, 63, 64, 0, 0, 62, 97,152,115, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62, 97,152,115, 63, 73, 13,214, 62, 83, 97,181, 63, 71,177,122,
- 62,128, 45,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 79,235, 68, 62,120, 77, 37,
- 63, 71,177,122, 62,128, 45,120, 63, 73, 13,214, 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 73, 13,214, 62, 83, 97,181, 63, 64, 0, 0, 62, 97,152,115, 63, 64, 0, 0, 62, 52,111,202, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 71,177,122, 62,128, 45,120, 63, 79,235, 68, 62,120, 77, 37,
- 63, 78, 0, 72, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 78, 0, 72,
- 62,146,201, 52, 63, 70,183,169, 62,151,144,219, 63, 71,177,122, 62,128, 45,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,135, 83,218, 63, 71,177,122, 62,128, 45,120, 63, 70,183,169, 62,151,144,219,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 70,183,169, 62,151,144,219, 63, 78, 0, 72,
- 62,146,201, 52, 63, 76,119,198, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 70, 29, 61, 62,174, 54,114, 63, 64, 0, 0, 62,180,111,211, 63, 64, 0, 0, 62,157,231,162, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,157,231,162, 63, 70,183,169, 62,151,144,219, 63, 70, 29, 61,
- 62,174, 54,114, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 76,119,198, 62,169,150, 90,
- 63, 70, 29, 61, 62,174, 54,114, 63, 70,183,169, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 70,183,169, 62,151,144,219, 63, 64, 0, 0, 62,157,231,162, 63, 64, 0, 0, 62,135, 83,218, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 82,250,230, 62,166,190,117, 63, 76,119,198, 62,169,150, 90,
- 63, 78, 0, 72, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 78, 0, 72,
- 62,146,201, 52, 63, 85, 69, 21, 62,144,102, 3, 63, 82,250,230, 62,166,190,117, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 89,153,149, 62,165,199,201, 63, 82,250,230, 62,166,190,117, 63, 85, 69, 21, 62,144,102, 3,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 85, 69, 21, 62,144,102, 3, 63, 78, 0, 72,
- 62,146,201, 52, 63, 79,235, 68, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,245,167,179, 62,128, 45, 72, 61,179,217, 94, 62,120, 76,222, 61,234,196,202, 62, 83, 97,100, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,234,196,202, 62, 83, 97,100, 62, 25,153,212, 62, 97,152, 2, 61,245,167,179,
- 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62,135, 83,156,
- 61,245,167,179, 62,128, 45, 72, 62, 25,153,212, 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 25,153,212, 62, 97,152, 2, 61,234,196,202, 62, 83, 97,100, 62, 25,153,214, 62, 52,111,106, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,245,167,179, 62,128, 45, 72, 62, 25,153,214, 62,135, 83,156,
- 61,253,118, 62, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,253,118, 62,
- 62,151,144,174, 61,195, 49, 53, 62,146,201, 17, 61,245,167,179, 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,179,217, 94, 62,120, 76,222, 61,245,167,179, 62,128, 45, 72, 61,195, 49, 53, 62,146,201, 17,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,195, 49, 53, 62,146,201, 17, 61,253,118, 62,
- 62,151,144,174, 61,207,117, 70, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,155, 92, 79, 62,166,190, 91, 61, 76,205,194, 62,165,199,186, 61,137, 10,212, 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,137, 10,212, 62,144,101,238, 61,195, 49, 53, 62,146,201, 17, 61,155, 92, 79,
- 62,166,190, 91, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,207,117, 70, 62,169,150, 54,
- 61,155, 92, 79, 62,166,190, 91, 61,195, 49, 53, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,195, 49, 53, 62,146,201, 17, 61,137, 10,212, 62,144,101,238, 61,179,217, 94, 62,120, 76,222, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 1, 36,204, 62,174, 54, 70, 61,207,117, 70, 62,169,150, 54,
- 61,253,118, 62, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,253,118, 62,
- 62,151,144,174, 62, 25,153,213, 62,157,231,100, 62, 1, 36,204, 62,174, 54, 70, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62,180,111,165, 62, 1, 36,204, 62,174, 54, 70, 62, 25,153,213, 62,157,231,100,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,213, 62,157,231,100, 61,253,118, 62,
- 62,151,144,174, 62, 25,153,214, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61, 76,205,188, 62,115,162, 53, 61,179,217, 94, 62,120, 76,222, 61,137, 10,212, 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,137, 10,212, 62,144,101,238, 61, 7,133,207, 62,144,101,236, 61, 76,205,188,
- 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60, 71,162,255, 62,120, 76,216,
- 61, 76,205,188, 62,115,162, 53, 61, 7,133,207, 62,144,101,236, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61, 7,133,207, 62,144,101,236, 61,137, 10,212, 62,144,101,238, 61, 76,205,194, 62,165,199,186, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,205,188, 62,115,162, 53, 60, 71,162,255, 62,120, 76,216,
- 60,221,171,190, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,221,171,190,
- 62, 70,176,194, 61,149, 98,194, 62, 70,176,194, 61, 76,205,188, 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61,179,217, 94, 62,120, 76,222, 61, 76,205,188, 62,115,162, 53, 61,149, 98,194, 62, 70,176,194,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,149, 98,194, 62, 70,176,194, 60,221,171,190,
- 62, 70,176,194, 61, 76,205,193, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 61,213, 83,198, 62, 30,253,179, 62, 25,153,214, 62, 52,111,106, 61,234,196,202, 62, 83, 97,100, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,234,196,202, 62, 83, 97,100, 61,149, 98,194, 62, 70,176,194, 61,213, 83,198,
- 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,205,193, 62, 23, 31,168,
- 61,213, 83,198, 62, 30,253,179, 61,149, 98,194, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 61,149, 98,194, 62, 70,176,194, 61,234,196,202, 62, 83, 97,100, 61,179,217, 94, 62,120, 76,222, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,126,239, 59, 62, 30,253,174, 63,131,105,154, 62, 23, 31,168,
- 63,131,118,175, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,131,118,175,
- 62, 70,176,194, 63,124, 65, 30, 62, 83, 97, 90, 63,126,239, 59, 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62, 52,111, 90, 63,126,239, 59, 62, 30,253,174, 63,124, 65, 30, 62, 83, 97, 90,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,124, 65, 30, 62, 83, 97, 90, 63,131,118,175,
- 62, 70,176,194, 63,129,143, 70, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,131,105,156, 61,147, 41,101, 63,115, 51, 65, 61,180,111, 83, 63,117, 49, 38, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,117, 49, 38, 61, 52, 64,225, 63,135,148,232, 60,125,158,144, 63,131,105,156,
- 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,215, 61,180,111,104,
- 61,128,245,122, 61,147, 41,101, 62, 25,153,224, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,135,148,232, 60,125,158,144, 63,117, 49, 38, 61, 52, 64,225, 63,121,222,208,178,239, 9,102, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,128,245,122, 61,147, 41,101, 62, 25,153,215, 61,180,111,104,
- 61,179, 55, 89, 61,231, 46, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,179, 55, 89,
- 61,231, 46, 38, 60,208,147, 96, 61,231, 46, 48, 61,128,245,122, 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 61,180,111, 83, 63,131,105,156, 61,147, 41,101, 63,129,153,102, 61,231, 46, 48,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 60,208,147, 96, 61,231, 46, 48, 61,179, 55, 89,
- 61,231, 46, 38, 61, 76,205,193, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,126,239, 59, 62, 30,253,174, 63,115, 51, 65, 62, 52,111, 90, 63,115, 51, 66, 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 66, 62, 7, 70,199, 63,129,153,102, 61,231, 46, 48, 63,126,239, 59,
- 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,131,105,154, 62, 23, 31,168,
- 63,126,239, 59, 62, 30,253,174, 63,129,153,102, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,129,153,102, 61,231, 46, 48, 63,115, 51, 66, 62, 7, 70,199, 63,115, 51, 65, 61,180,111, 83, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,213, 83,198, 62, 30,253,179, 61, 76,205,193, 62, 23, 31,168,
- 61,179, 55, 89, 61,231, 46, 38, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61,179, 55, 89,
- 61,231, 46, 38, 62, 25,153,217, 62, 7, 70,204, 61,213, 83,198, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62, 52,111,106, 61,213, 83,198, 62, 30,253,179, 62, 25,153,217, 62, 7, 70,204,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,217, 62, 7, 70,204, 61,179, 55, 89,
- 61,231, 46, 38, 62, 25,153,215, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,122,228,192, 62,128, 45, 66, 63,115, 51, 65, 62,135, 83,151, 63,115, 51, 65, 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62, 97,151,248, 63,124, 65, 30, 62, 83, 97, 90, 63,122,228,192,
- 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,129,143, 70, 62,120, 76,216,
- 63,122,228,192, 62,128, 45, 66, 63,124, 65, 30, 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,124, 65, 30, 62, 83, 97, 90, 63,115, 51, 65, 62, 97,151,248, 63,115, 51, 65, 62, 52,111, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,122,228,192, 62,128, 45, 66, 63,129,143, 70, 62,120, 76,216,
- 63,128,153,201, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,128,153,201,
- 62,146,201, 14, 63,121,234,239, 62,151,144,169, 63,122,228,192, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,135, 83,151, 63,122,228,192, 62,128, 45, 66, 63,121,234,239, 62,151,144,169,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,121,234,239, 62,151,144,169, 63,128,153,201,
- 62,146,201, 14, 63,127,171, 15, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63,121, 80,133, 62,174, 54, 65, 63,115, 51, 65, 62,180,111,160, 63,115, 51, 65, 62,157,231, 93, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,115, 51, 65, 62,157,231, 93, 63,121,234,239, 62,151,144,169, 63,121, 80,133,
- 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,127,171, 15, 62,169,150, 52,
- 63,121, 80,133, 62,174, 54, 65, 63,121,234,239, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63,121,234,239, 62,151,144,169, 63,115, 51, 65, 62,157,231, 93, 63,115, 51, 65, 62,135, 83,151, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63,131, 23, 23, 62,166,190, 89, 63,127,171, 15, 62,169,150, 52,
- 63,128,153,201, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 59,153,200,136,
- 62,146,201, 14, 61, 7,133,207, 62,144,101,236, 60,197,197,195, 62,166,190, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 61, 76,205,194, 62,165,199,186, 60,197,197,195, 62,166,190, 89, 61, 7,133,207, 62,144,101,236,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 61, 7,133,207, 62,144,101,236, 59,153,200,136,
- 62,146,201, 14, 60, 71,162,255, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,163,208, 32, 62,128, 45, 79, 62,147, 92,147, 62,120, 76,252, 62,161, 23,102, 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,161, 23,102, 62, 83, 97,115, 62,179, 51, 22, 62, 97,152, 2, 62,163,208, 32,
- 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,135, 83,156,
- 62,163,208, 32, 62,128, 45, 79, 62,179, 51, 22, 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,179, 51, 22, 62, 97,152, 2, 62,161, 23,102, 62, 83, 97,115, 62,179, 51, 21, 62, 52,111,101, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,163,208, 32, 62,128, 45, 79, 62,179, 51, 21, 62,135, 83,156,
- 62,165,195,194, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165,195,194,
- 62,151,144,181, 62,151, 50,134, 62,146,201, 29, 62,163,208, 32, 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,147, 92,147, 62,120, 76,252, 62,163,208, 32, 62,128, 45, 79, 62,151, 50,134, 62,146,201, 29,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,151, 50,134, 62,146,201, 29, 62,165,195,194,
- 62,151,144,181, 62,154, 67,137, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,141, 61, 82, 62,166,190,112, 62,128, 0, 0, 62,165,199,206, 62,136,168,247, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,136,168,247, 62,144,102, 3, 62,151, 50,134, 62,146,201, 29, 62,141, 61, 82,
- 62,166,190,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,154, 67,137, 62,169,150, 70,
- 62,141, 61, 82, 62,166,190,112, 62,151, 50,134, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,151, 50,134, 62,146,201, 29, 62,136,168,247, 62,144,102, 3, 62,147, 92,147, 62,120, 76,252, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,166,248,150, 62,174, 54, 78, 62,154, 67,137, 62,169,150, 70,
- 62,165,195,194, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,165,195,194,
- 62,151,144,181, 62,179, 51, 21, 62,157,231, 98, 62,166,248,150, 62,174, 54, 78, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,180,111,165, 62,166,248,150, 62,174, 54, 78, 62,179, 51, 21, 62,157,231, 98,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,157,231, 98, 62,165,195,194,
- 62,151,144,181, 62,179, 51, 21, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,128, 0, 0, 62,115,162, 89, 62,147, 92,147, 62,120, 76,252, 62,136,168,247, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,136,168,247, 62,144,102, 3, 62,110,174, 18, 62,144,102, 3, 62,128, 0, 0,
- 62,115,162, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 89, 70,217, 62,120, 76,252,
- 62,128, 0, 0, 62,115,162, 89, 62,110,174, 18, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,110,174, 18, 62,144,102, 3, 62,136,168,247, 62,144,102, 3, 62,128, 0, 0, 62,165,199,206, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62,115,162, 89, 62, 89, 70,217, 62,120, 76,252,
- 62,104,130, 30, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,104,130, 30,
- 62, 70,176,230, 62,139,190,241, 62, 70,176,230, 62,128, 0, 0, 62,115,162, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,147, 92,147, 62,120, 76,252, 62,128, 0, 0, 62,115,162, 89, 62,139,190,241, 62, 70,176,230,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,139,190,241, 62, 70,176,230, 62,104,130, 30,
- 62, 70,176,230, 62,128, 0, 0, 62, 23, 31,208, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,155,187, 41, 62, 30,253,205, 62,179, 51, 21, 62, 52,111,101, 62,161, 23,102, 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,161, 23,102, 62, 83, 97,115, 62,139,190,241, 62, 70,176,230, 62,155,187, 41,
- 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62, 23, 31,208,
- 62,155,187, 41, 62, 30,253,205, 62,139,190,241, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,139,190,241, 62, 70,176,230, 62,161, 23,102, 62, 83, 97,115, 62,147, 92,147, 62,120, 76,252, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 72,137,174, 62, 30,253,205, 62,128, 0, 0, 62, 23, 31,208,
- 62,104,130, 30, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,104,130, 30,
- 62, 70,176,230, 62, 61,209, 51, 62, 83, 97,115, 62, 72,137,174, 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62, 52,111,106, 62, 72,137,174, 62, 30,253,205, 62, 61,209, 51, 62, 83, 97,115,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 61,209, 51, 62, 83, 97,115, 62,104,130, 30,
- 62, 70,176,230, 62, 89, 70,217, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,127,255,255, 61,147, 41,141, 62, 25,153,215, 61,180,111,104, 62, 25,153,224, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,224, 61, 52, 64,225, 62,179, 51, 15, 61, 52, 64,225, 62,127,255,255,
- 61,147, 41,141, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 20, 61,180,111,104,
- 62,127,255,255, 61,147, 41,141, 62,179, 51, 15, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,179, 51, 15, 61, 52, 64,225, 62, 25,153,224, 61, 52, 64,225, 62,161,175,144,178,239, 9,102, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,127,255,255, 61,147, 41,141, 62,179, 51, 20, 61,180,111,104,
- 62,147, 52, 12, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147, 52, 12,
- 61,231, 46,109, 62, 89,151,231, 61,231, 46,109, 62,127,255,255, 61,147, 41,141, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,215, 61,180,111,104, 62,127,255,255, 61,147, 41,141, 62, 89,151,231, 61,231, 46,109,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 89,151,231, 61,231, 46,109, 62,147, 52, 12,
- 61,231, 46,109, 62,128, 0, 0, 62, 23, 31,208, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 72,137,174, 62, 30,253,205, 62, 25,153,214, 62, 52,111,106, 62, 25,153,217, 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,217, 62, 7, 70,204, 62, 89,151,231, 61,231, 46,109, 62, 72,137,174,
- 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62, 23, 31,208,
- 62, 72,137,174, 62, 30,253,205, 62, 89,151,231, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 89,151,231, 61,231, 46,109, 62, 25,153,217, 62, 7, 70,204, 62, 25,153,215, 61,180,111,104, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,155,187, 41, 62, 30,253,205, 62,128, 0, 0, 62, 23, 31,208,
- 62,147, 52, 12, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,147, 52, 12,
- 61,231, 46,109, 62,179, 51, 19, 62, 7, 70,204, 62,155,187, 41, 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62, 52,111,101, 62,155,187, 41, 62, 30,253,205, 62,179, 51, 19, 62, 7, 70,204,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 19, 62, 7, 70,204, 62,147, 52, 12,
- 61,231, 46,109, 62,179, 51, 20, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 56, 95,192, 62,128, 45, 79, 62, 25,153,214, 62,135, 83,156, 62, 25,153,212, 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,212, 62, 97,152, 2, 62, 61,209, 51, 62, 83, 97,115, 62, 56, 95,192,
- 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 89, 70,217, 62,120, 76,252,
- 62, 56, 95,192, 62,128, 45, 79, 62, 61,209, 51, 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 61,209, 51, 62, 83, 97,115, 62, 25,153,212, 62, 97,152, 2, 62, 25,153,214, 62, 52,111,106, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 56, 95,192, 62,128, 45, 79, 62, 89, 70,217, 62,120, 76,252,
- 62, 81,154,245, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 81,154,245,
- 62,146,201, 29, 62, 52,120,125, 62,151,144,181, 62, 56, 95,192, 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,214, 62,135, 83,156, 62, 56, 95,192, 62,128, 45, 79, 62, 52,120,125, 62,151,144,181,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 52,120,125, 62,151,144,181, 62, 81,154,245,
- 62,146,201, 29, 62, 75,120,239, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62, 50, 14,213, 62,174, 54, 78, 62, 25,153,214, 62,180,111,165, 62, 25,153,213, 62,157,231,100, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 25,153,213, 62,157,231,100, 62, 52,120,125, 62,151,144,181, 62, 50, 14,213,
- 62,174, 54, 78, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 75,120,239, 62,169,150, 70,
- 62, 50, 14,213, 62,174, 54, 78, 62, 52,120,125, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62, 52,120,125, 62,151,144,181, 62, 25,153,213, 62,157,231,100, 62, 25,153,214, 62,135, 83,156, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,101,133, 91, 62,166,190,112, 62, 75,120,239, 62,169,150, 70,
- 62, 81,154,245, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62, 81,154,245,
- 62,146,201, 29, 62,110,174, 18, 62,144,102, 3, 62,101,133, 91, 62,166,190,112, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,128, 0, 0, 62,165,199,206, 62,101,133, 91, 62,166,190,112, 62,110,174, 18, 62,144,102, 3,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,110,174, 18, 62,144,102, 3, 62, 81,154,245,
- 62,146,201, 29, 62, 89, 70,217, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 5, 27, 64, 62,128, 45, 66, 62,249,194,232, 62,120, 76,216, 63, 3,190,226, 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3,190,226, 62, 83, 97, 90, 63, 12,204,191, 62, 97,151,248, 63, 5, 27, 64,
- 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,135, 83,149,
- 63, 5, 27, 64, 62,128, 45, 66, 63, 12,204,191, 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 12,204,191, 62, 97,151,248, 63, 3,190,226, 62, 83, 97, 90, 63, 12,204,191, 62, 52,111, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 5, 27, 64, 62,128, 45, 66, 63, 12,204,191, 62,135, 83,149,
- 63, 6, 21, 17, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6, 21, 17,
- 62,151,144,169, 62,253,152,222, 62,146,201, 14, 63, 5, 27, 64, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,249,194,232, 62,120, 76,216, 63, 5, 27, 64, 62,128, 45, 66, 62,253,152,222, 62,146,201, 14,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,253,152,222, 62,146,201, 14, 63, 6, 21, 17,
- 62,151,144,169, 63, 0, 84,241, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,243,163,164, 62,166,190, 89, 62,230,102, 72, 62,165,199,183, 62,239, 15, 70, 62,144,101,233, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,239, 15, 70, 62,144,101,233, 62,253,152,222, 62,146,201, 14, 62,243,163,164,
- 62,166,190, 89, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 0, 84,241, 62,169,150, 52,
- 62,243,163,164, 62,166,190, 89, 62,253,152,222, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,253,152,222, 62,146,201, 14, 62,239, 15, 70, 62,144,101,233, 62,249,194,232, 62,120, 76,216, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6,175,123, 62,174, 54, 65, 63, 0, 84,241, 62,169,150, 52,
- 63, 6, 21, 17, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 6, 21, 17,
- 62,151,144,169, 63, 12,204,191, 62,157,231, 90, 63, 6,175,123, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,180,111,160, 63, 6,175,123, 62,174, 54, 65, 63, 12,204,191, 62,157,231, 90,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,157,231, 90, 63, 6, 21, 17,
- 62,151,144,169, 63, 12,204,191, 62,135, 83,149, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102, 72, 62,115,162, 53, 62,249,194,232, 62,120, 76,216, 62,239, 15, 70, 62,144,101,233, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,239, 15, 70, 62,144,101,233, 62,221,189, 75, 62,144,101,238, 62,230,102, 72,
- 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,211, 9,168, 62,120, 76,222,
- 62,230,102, 72, 62,115,162, 53, 62,221,189, 75, 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,221,189, 75, 62,144,101,238, 62,239, 15, 70, 62,144,101,233, 62,230,102, 72, 62,165,199,183, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 72, 62,115,162, 53, 62,211, 9,168, 62,120, 76,222,
- 62,218,167, 80, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,218,167, 80,
- 62, 70,176,194, 62,242, 37, 68, 62, 70,176,194, 62,230,102, 72, 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,249,194,232, 62,120, 76,216, 62,230,102, 72, 62,115,162, 53, 62,242, 37, 68, 62, 70,176,194,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,242, 37, 68, 62, 70,176,194, 62,218,167, 80,
- 62, 70,176,194, 62,230,102, 72, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 1, 16,197, 62, 30,253,174, 63, 12,204,191, 62, 52,111, 90, 63, 3,190,226, 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 3,190,226, 62, 83, 97, 90, 62,242, 37, 68, 62, 70,176,194, 63, 1, 16,197,
- 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 72, 62, 23, 31,168,
- 63, 1, 16,197, 62, 30,253,174, 62,242, 37, 68, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,242, 37, 68, 62, 70,176,194, 63, 3,190,226, 62, 83, 97, 90, 62,249,194,232, 62,120, 76,216, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,202,171, 14, 62, 30,253,179, 62,230,102, 72, 62, 23, 31,168,
- 62,218,167, 80, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,218,167, 80,
- 62, 70,176,194, 62,197, 78,205, 62, 83, 97, 95, 62,202,171, 14, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62, 52,111,101, 62,202,171, 14, 62, 30,253,179, 62,197, 78,205, 62, 83, 97, 95,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,197, 78,205, 62, 83, 97, 95, 62,218,167, 80,
- 62, 70,176,194, 62,211, 9,168, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,230,102, 63, 61,147, 41,101, 62,179, 51, 20, 61,180,111,104, 62,179, 51, 15, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 15, 61, 52, 64,225, 63, 12,204,189, 61, 52, 64,225, 62,230,102, 63,
- 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 61,180,111, 83,
- 62,230,102, 63, 61,147, 41,101, 63, 12,204,189, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 12,204,189, 61, 52, 64,225, 62,179, 51, 15, 61, 52, 64,225, 62,161,175,144,178,239, 9,102, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 63, 61,147, 41,101, 63, 12,204,191, 61,180,111, 83,
- 62,249,154,104, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,249,154,104,
- 61,231, 46, 48, 62,211, 50, 42, 61,231, 46, 48, 62,230,102, 63, 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 20, 61,180,111,104, 62,230,102, 63, 61,147, 41,101, 62,211, 50, 42, 61,231, 46, 48,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,211, 50, 42, 61,231, 46, 48, 62,249,154,104,
- 61,231, 46, 48, 62,230,102, 72, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,202,171, 14, 62, 30,253,179, 62,179, 51, 21, 62, 52,111,101, 62,179, 51, 19, 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 19, 62, 7, 70,204, 62,211, 50, 42, 61,231, 46, 48, 62,202,171, 14,
- 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 72, 62, 23, 31,168,
- 62,202,171, 14, 62, 30,253,179, 62,211, 50, 42, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,211, 50, 42, 61,231, 46, 48, 62,179, 51, 19, 62, 7, 70,204, 62,179, 51, 20, 61,180,111,104, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 1, 16,197, 62, 30,253,174, 62,230,102, 72, 62, 23, 31,168,
- 62,249,154,104, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,249,154,104,
- 61,231, 46, 48, 63, 12,204,191, 62, 7, 70,199, 63, 1, 16,197, 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62, 52,111, 90, 63, 1, 16,197, 62, 30,253,174, 63, 12,204,191, 62, 7, 70,199,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62, 7, 70,199, 62,249,154,104,
- 61,231, 46, 48, 63, 12,204,191, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,194,150, 19, 62,128, 45, 72, 62,179, 51, 21, 62,135, 83,156, 62,179, 51, 22, 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 22, 62, 97,152, 2, 62,197, 78,205, 62, 83, 97, 95, 62,194,150, 19,
- 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,211, 9,168, 62,120, 76,222,
- 62,194,150, 19, 62,128, 45, 72, 62,197, 78,205, 62, 83, 97, 95, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,197, 78,205, 62, 83, 97, 95, 62,179, 51, 22, 62, 97,152, 2, 62,179, 51, 21, 62, 52,111,101, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,194,150, 19, 62,128, 45, 72, 62,211, 9,168, 62,120, 76,222,
- 62,207, 51,179, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,207, 51,179,
- 62,146,201, 17, 62,192,162,113, 62,151,144,174, 62,194,150, 19, 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,135, 83,156, 62,194,150, 19, 62,128, 45, 72, 62,192,162,113, 62,151,144,174,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,192,162,113, 62,151,144,174, 62,207, 51,179,
- 62,146,201, 17, 62,204, 34,175, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 62,191,109,154, 62,174, 54, 68, 62,179, 51, 21, 62,180,111,165, 62,179, 51, 21, 62,157,231, 98, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,179, 51, 21, 62,157,231, 98, 62,192,162,113, 62,151,144,174, 62,191,109,154,
- 62,174, 54, 68, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,204, 34,175, 62,169,150, 54,
- 62,191,109,154, 62,174, 54, 68, 62,192,162,113, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 62,192,162,113, 62,151,144,174, 62,179, 51, 21, 62,157,231, 98, 62,179, 51, 21, 62,135, 83,156, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,217, 40,237, 62,166,190, 91, 62,204, 34,175, 62,169,150, 54,
- 62,207, 51,179, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,207, 51,179,
- 62,146,201, 17, 62,221,189, 75, 62,144,101,238, 62,217, 40,237, 62,166,190, 91, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 62,230,102, 72, 62,165,199,183, 62,217, 40,237, 62,166,190, 91, 62,221,189, 75, 62,144,101,238,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 62,221,189, 75, 62,144,101,238, 62,207, 51,179,
- 62,146,201, 17, 62,211, 9,168, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 56, 78,134, 62,128, 45,117, 63, 48, 20,188, 62,120, 77, 37, 63, 54,242, 42, 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54,242, 42, 62, 83, 97,181, 63, 64, 0, 0, 62, 97,152,115, 63, 56, 78,134,
- 62,128, 45,117, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,135, 83,218,
- 63, 56, 78,134, 62,128, 45,117, 63, 64, 0, 0, 62, 97,152,115, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 64, 0, 0, 62, 97,152,115, 63, 54,242, 42, 62, 83, 97,181, 63, 64, 0, 0, 62, 52,111,202, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 56, 78,134, 62,128, 45,117, 63, 64, 0, 0, 62,135, 83,218,
- 63, 57, 72, 87, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 72, 87,
- 62,151,144,219, 63, 49,255,184, 62,146,201, 52, 63, 56, 78,134, 62,128, 45,117, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 20,188, 62,120, 77, 37, 63, 56, 78,134, 62,128, 45,117, 63, 49,255,184, 62,146,201, 52,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 49,255,184, 62,146,201, 52, 63, 57, 72, 87,
- 62,151,144,219, 63, 51,136, 58, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 45, 5, 26, 62,166,190,117, 63, 38,102,107, 62,165,199,201, 63, 42,186,235, 62,144,102, 5, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 42,186,235, 62,144,102, 5, 63, 49,255,184, 62,146,201, 52, 63, 45, 5, 26,
- 62,166,190,117, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 51,136, 58, 62,169,150, 90,
- 63, 45, 5, 26, 62,166,190,117, 63, 49,255,184, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 49,255,184, 62,146,201, 52, 63, 42,186,235, 62,144,102, 5, 63, 48, 20,188, 62,120, 77, 37, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57,226,196, 62,174, 54,114, 63, 51,136, 58, 62,169,150, 90,
- 63, 57, 72, 87, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 57, 72, 87,
- 62,151,144,219, 63, 64, 0, 0, 62,157,231,162, 63, 57,226,196, 62,174, 54,114, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,180,111,211, 63, 57,226,196, 62,174, 54,114, 63, 64, 0, 0, 62,157,231,162,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62,157,231,162, 63, 57, 72, 87,
- 62,151,144,219, 63, 64, 0, 0, 62,135, 83,218, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,107, 62,115,162, 79, 63, 48, 20,188, 62,120, 77, 37, 63, 42,186,235, 62,144,102, 5, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 42,186,235, 62,144,102, 5, 63, 34, 17,234, 62,144,101,243, 63, 38,102,107,
- 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,184, 21, 62,120, 76,222,
- 63, 38,102,107, 62,115,162, 79, 63, 34, 17,234, 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 34, 17,234, 62,144,101,243, 63, 42,186,235, 62,144,102, 5, 63, 38,102,107, 62,165,199,201, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,107, 62,115,162, 79, 63, 28,184, 21, 62,120, 76,222,
- 63, 32,134,234, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 32,134,234,
- 62, 70,176,204, 63, 44, 69,233, 62, 70,176,245, 63, 38,102,107, 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 20,188, 62,120, 77, 37, 63, 38,102,107, 62,115,162, 79, 63, 44, 69,233, 62, 70,176,245,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 44, 69,233, 62, 70,176,245, 63, 32,134,234,
- 62, 70,176,204, 63, 38,102,104, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 52, 68, 9, 62, 30,253,241, 63, 64, 0, 0, 62, 52,111,202, 63, 54,242, 42, 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 54,242, 42, 62, 83, 97,181, 63, 44, 69,233, 62, 70,176,245, 63, 52, 68, 9,
- 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,104, 62, 23, 31,198,
- 63, 52, 68, 9, 62, 30,253,241, 63, 44, 69,233, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 44, 69,233, 62, 70,176,245, 63, 54,242, 42, 62, 83, 97,181, 63, 48, 20,188, 62,120, 77, 37, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 24,136,195, 62, 30,253,179, 63, 38,102,104, 62, 23, 31,198,
- 63, 32,134,234, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 32,134,234,
- 62, 70,176,204, 63, 21,218,162, 62, 83, 97, 84, 63, 24,136,195, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62, 52,111, 90, 63, 24,136,195, 62, 30,253,179, 63, 21,218,162, 62, 83, 97, 84,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 21,218,162, 62, 83, 97, 84, 63, 32,134,234,
- 62, 70,176,204, 63, 28,184, 21, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 38,102,104, 61,147, 41,111, 63, 12,204,191, 61,180,111, 83, 63, 12,204,189, 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,189, 61, 52, 64,225, 63, 64, 0, 0, 61, 52, 65,111, 63, 38,102,104,
- 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 61,180,111,195,
- 63, 38,102,104, 61,147, 41,111, 63, 64, 0, 0, 61, 52, 65,111, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 64, 0, 0, 61, 52, 65,111, 63, 12,204,189, 61, 52, 64,225, 63,121,222,208,178,239, 9,102, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,104, 61,147, 41,111, 63, 64, 0, 0, 61,180,111,195,
- 63, 48, 0,122, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 0,122,
- 61,231, 46,120, 63, 28,204, 85, 61,231, 46, 48, 63, 38,102,104, 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 61,180,111, 83, 63, 38,102,104, 61,147, 41,111, 63, 28,204, 85, 61,231, 46, 48,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,204, 85, 61,231, 46, 48, 63, 48, 0,122,
- 61,231, 46,120, 63, 38,102,104, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 24,136,195, 62, 30,253,179, 63, 12,204,191, 62, 52,111, 90, 63, 12,204,191, 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62, 7, 70,199, 63, 28,204, 85, 61,231, 46, 48, 63, 24,136,195,
- 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,104, 62, 23, 31,198,
- 63, 24,136,195, 62, 30,253,179, 63, 28,204, 85, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 28,204, 85, 61,231, 46, 48, 63, 12,204,191, 62, 7, 70,199, 63, 12,204,191, 61,180,111, 83, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 52, 68, 9, 62, 30,253,241, 63, 38,102,104, 62, 23, 31,198,
- 63, 48, 0,122, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 48, 0,122,
- 61,231, 46,120, 63, 64, 0, 0, 62, 7, 71, 24, 63, 52, 68, 9, 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62, 52,111,202, 63, 52, 68, 9, 62, 30,253,241, 63, 64, 0, 0, 62, 7, 71, 24,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 64, 0, 0, 62, 7, 71, 24, 63, 48, 0,122,
- 61,231, 46,120, 63, 64, 0, 0, 61,180,111,195, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 20,126, 68, 62,128, 45, 64, 63, 12,204,191, 62,135, 83,149, 63, 12,204,191, 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62, 97,151,248, 63, 21,218,162, 62, 83, 97, 84, 63, 20,126, 68,
- 62,128, 45, 64, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 28,184, 21, 62,120, 76,222,
- 63, 20,126, 68, 62,128, 45, 64, 63, 21,218,162, 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 21,218,162, 62, 83, 97, 84, 63, 12,204,191, 62, 97,151,248, 63, 12,204,191, 62, 52,111, 90, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 20,126, 68, 62,128, 45, 64, 63, 28,184, 21, 62,120, 76,222,
- 63, 26,205, 25, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 26,205, 25,
- 62,146,201, 14, 63, 19,132,114, 62,151,144,169, 63, 20,126, 68, 62,128, 45, 64, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,135, 83,149, 63, 20,126, 68, 62,128, 45, 64, 63, 19,132,114, 62,151,144,169,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 19,132,114, 62,151,144,169, 63, 26,205, 25,
- 62,146,201, 14, 63, 25, 68,150, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 63, 18,234, 7, 62,174, 54, 65, 63, 12,204,191, 62,180,111,160, 63, 12,204,191, 62,157,231, 90, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 12,204,191, 62,157,231, 90, 63, 19,132,114, 62,151,144,169, 63, 18,234, 7,
- 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 25, 68,150, 62,169,150, 54,
- 63, 18,234, 7, 62,174, 54, 65, 63, 19,132,114, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 63, 19,132,114, 62,151,144,169, 63, 12,204,191, 62,157,231, 90, 63, 12,204,191, 62,135, 83,149, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 31,199,185, 62,166,190, 96, 63, 25, 68,150, 62,169,150, 54,
- 63, 26,205, 25, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 26,205, 25,
- 62,146,201, 14, 63, 34, 17,234, 62,144,101,243, 63, 31,199,185, 62,166,190, 96, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 63, 38,102,107, 62,165,199,201, 63, 31,199,185, 62,166,190, 96, 63, 34, 17,234, 62,144,101,243,
- 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 63, 34, 17,234, 62,144,101,243, 63, 26,205, 25,
- 62,146,201, 14, 63, 28,184, 21, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 80, 0, 8,109, 96, 32, 0, 0, 0, 57, 0, 0, 20, 0,255,255,255,255,255,255,255,255,255,255,255,255,
+128, 1, 0, 0,160,248,129, 2, 54, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 34, 0,
+ 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 34, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 34, 0, 7, 0, 0, 0,
+ 8, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 10, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 13, 0, 0, 0, 0, 0, 34, 0,
+ 13, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 34, 0, 12, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 34, 0, 14, 0, 0, 0, 15, 0, 0, 0, 0, 0, 34, 0, 11, 0, 0, 0, 14, 0, 0, 0, 0, 0, 34, 0, 18, 0, 0, 0,
+ 19, 0, 0, 0, 0, 0, 34, 0, 15, 0, 0, 0, 18, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0, 18, 0, 0, 0, 0, 0, 34, 0,
+ 14, 0, 0, 0, 17, 0, 0, 0, 0, 0, 34, 0, 19, 0, 0, 0, 22, 0, 0, 0, 0, 0, 34, 0, 21, 0, 0, 0, 22, 0, 0, 0,
+ 0, 0, 34, 0, 18, 0, 0, 0, 21, 0, 0, 0, 0, 0, 34, 0, 20, 0, 0, 0, 21, 0, 0, 0, 0, 0, 34, 0, 17, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 34, 0, 10, 0, 0, 0, 21, 0, 0, 0, 0, 0, 34, 0, 9, 0, 0, 0, 20, 0, 0, 0, 0, 0, 34, 0,
+ 6, 0, 0, 0, 11, 0, 0, 0, 0, 0, 34, 0, 4, 0, 0, 0, 14, 0, 0, 0, 0, 0, 34, 0, 2, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 34, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 34, 0, 68, 65, 84, 65, 44, 1, 0, 0, 80,250,129, 2, 21, 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, 64,107, 8, 3,
+ 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,235,128, 2, 6, 0, 0, 0,
+ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 40,197, 32, 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, 68, 65, 84, 65,160, 0, 0, 0, 64,107, 8, 3, 53, 0, 0, 0,
+ 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0,
+ 15, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0,
+ 19, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 96, 1, 0, 0, 0,235,128, 2, 61, 0, 0, 0, 8, 0, 0, 0,152, 23, 55, 63,162,226,125, 63,
+ 30, 5, 17, 63,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63,152, 23, 55, 63,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0,
+ 0, 0, 0, 0,252,228,213, 62,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63,252,228,213, 62,
+162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,152, 23, 55, 63,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63,
+ 30, 5, 17, 63,162,226,125, 63,152, 23, 55, 63,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 34, 5, 17, 63,
+162,226,125, 63, 0,229,213, 62,162,226,125, 63,252,228,213, 62,162,226,125, 63, 30, 5, 17, 63,162,226,125, 63, 0, 0, 0, 0,
+ 61, 0, 1, 0, 0, 0, 0, 0, 18,192,137, 62,162,226,125, 63,144,108,246, 61,162,226,125, 63,144,108,246, 61,162,226,125, 63,
+ 12,192,137, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,252,228,213, 62,162,226,125, 63, 12,192,137, 62,
+162,226,125, 63, 12,192,137, 62,162,226,125, 63,252,228,213, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,
+ 12,192,137, 62,162,226,125, 63,144,108,246, 61,162,226,125, 63,144,108,246, 61,162,226,125, 63, 12,192,137, 62,162,226,125, 63,
+ 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0,252,228,213, 62,162,226,125, 63, 12,192,137, 62,162,226,125, 63, 12,192,137, 62,
+162,226,125, 63,252,228,213, 62,162,226,125, 63, 0, 0, 0, 0, 61, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65,128, 0, 0, 0,
+ 40,197, 32, 3, 58, 0, 0, 0, 32, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,200, 25,155, 2, 51, 0, 0, 0, 1, 0, 0, 0,
+152, 43,161, 2,192, 26,131, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 80,108, 97,110,101, 46, 48, 48, 52, 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,160,206,148, 2, 0, 21,130, 2,200, 94,140, 2, 0, 0, 0, 0, 40, 79,169, 2,128, 86,169, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 28,155, 2, 1, 0, 0, 0, 5, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 0, 8, 27,155, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,200, 29,155, 2,
+ 2, 0, 0, 0, 5, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128,179, 0, 0, 64, 52, 0, 0, 0, 0, 0, 0,128, 63, 2, 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, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,160,206,148, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+152,140,165, 2, 68, 65, 84, 65, 44, 1, 0, 0,104, 28,155, 2, 21, 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, 40, 79,169, 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, 68, 65, 84, 65, 80, 0, 0, 0, 40, 79,169, 2, 57, 0, 0, 0, 4, 0, 0, 0, 0, 0,128, 63,255,255,127, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0,255,127, 3,255, 0, 0,128, 63, 0, 0,128,191, 0, 0, 0, 0, 0, 0, 0, 0,255,127, 3,255,
+ 1, 0,128,191,253,255,127,191, 0, 0, 0, 0, 0, 0, 0, 0,255,127, 3,255,250,255,127,191, 3, 0,128, 63, 0, 0, 0, 0,
+ 0, 0, 0, 0,255,127, 3,255, 68, 65, 84, 65, 44, 1, 0, 0, 8, 27,155, 2, 21, 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,128, 86,169, 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, 68, 65, 84, 65, 48, 0, 0, 0,128, 86,169, 2, 54, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 35, 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,
+ 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65, 44, 1, 0, 0,200, 29,155, 2, 21, 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, 86, 84,101,120, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,130, 2, 5, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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, 94,140, 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, 68, 65, 84, 65, 20, 0, 0, 0, 0, 21,130, 2, 53, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 68, 65, 84, 65, 44, 0, 0, 0,200, 94,140, 2,
+ 61, 0, 0, 0, 1, 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, 0, 0,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 60, 0, 1, 0, 0, 0, 0, 0, 77, 69, 0, 0, 12, 1, 0, 0,152, 43,161, 2,
+ 51, 0, 0, 0, 1, 0, 0, 0, 8,197,152, 2,200, 25,155, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,
+119, 0, 0, 0, 0,112,104,101,114,101, 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, 80, 29,153, 2,224, 47,167, 2, 8, 75, 18, 3, 0, 0, 0, 0,
+240,143,152, 2, 40,112,155, 2, 0, 0, 0, 0, 16,148,167, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 44,161, 2,
+ 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 72,194,152, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0,
+ 0, 0, 0, 0,168,195,152, 2, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,130, 2, 0, 0,128, 7, 0, 0,
+ 0, 5, 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,117,224,186, 64,
+ 91, 13,187, 64,160,240,186, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 80, 29,153, 2,
+ 0, 0, 0, 0, 1, 0, 0, 0,152,140,165, 2, 68, 65, 84, 65, 44, 1, 0, 0,216, 44,161, 2, 21, 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,240,143,152, 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, 68, 65, 84, 65, 40, 50, 0, 0,240,143,152, 2, 57, 0, 0, 0,130, 2, 0, 0,
+ 28,136,141,191, 12,243,244, 62,198, 86,183,192,212,231,117, 10,191,130, 3,255,240,102,131,192, 30,183,119, 64,109,169,199,191,
+ 58,166,158, 84,230,221, 3,255,119,108,239, 63,213, 85,156, 64,188, 58, 40,192,228, 40,207,106,137,198, 3,255, 95,135,146, 64,
+ 63, 54, 14,191,241,194,102,192, 27,100,219,243, 45,177, 3,255,239, 84,141, 62, 16,220,157,192, 14, 2, 73,192, 8, 6, 39,148,
+ 86,187, 3,255,132,239,162,192,206,165, 12,192,150, 45,240,191,175,144,245,207,251,214, 3,255,239, 84,141,190, 16,220,157, 64,
+ 14, 2, 73, 64,248,249,217,107,170, 68, 3,255,132,239,162, 64,206,165, 12, 64,150, 45,240, 63, 81,111, 11, 48, 5, 41, 3,255,
+240,102,131, 64, 30,183,119,192,109,169,199, 63,198, 89, 98,171, 26, 34, 3,255,119,108,239,191,213, 85,156,192,188, 58, 40, 64,
+ 28,215, 49,149,119, 57, 3,255, 95,135,146,192, 63, 54, 14, 63,241,194,102, 64,229,155, 37, 12,211, 78, 3,255, 28,136,141, 63,
+ 12,243,244,190,198, 86,183, 64, 44, 24,139,245, 65,125, 3,255,114, 17, 68,192,226,153, 35, 64,154, 26,137,192, 6,189,226, 55,
+ 85,162, 3,255,155, 40,230, 62,239,199, 73, 64,176, 52,157,192,211, 9,237, 68,153,148, 3,255,124, 55,168,191,224,177,164, 64,
+ 58,144, 29,192, 69,227,132,112, 46,202, 3,255, 94, 35,105,192,230, 88,129,191,195, 14,143,192, 93,176,233,233, 68,158, 3,255,
+ 37, 2,173,192,137,187,123, 63, 56, 68, 1,192,206,137,127, 21,216,211, 3,255,234,168, 2, 64,231,158, 57,189, 65,149,175,192,
+162, 44, 3,255, 11,136, 3,255, 19,159,114, 64,254,226, 34, 64,196,133,106,192,225, 82,164, 55,228,175, 3,255,105,176,249,190,
+ 21,148, 39,192,217,214,166,192, 87,245,194,198, 5,142, 3,255,227,163, 54, 64, 86,121, 78,192, 22,202,125,192, 99, 62,120,185,
+ 79,169, 3,255,241, 40, 53,192,200, 31,134,192,229,188, 60,192, 30,194, 94,164,136,191, 3,255, 96,230,181,192, 33, 24,119,191,
+174, 26,130, 63,186,131,231,234, 56, 22, 3,255,103, 93,163,192,136,128, 38, 64, 83,235,153, 63,100,144,224, 56, 74, 26, 3,255,
+238,219, 36,192,132,151,165, 64,165,226,109, 63,176,199, 33,113, 80, 20, 3,255, 24,237,111, 63,118,174,184, 64,212, 34,154, 62,
+125, 20, 44,126,148, 6, 3,255,163,244,130, 64,157, 58,133, 64,125, 95,226,190,119, 89, 5, 91, 86,246, 3,255, 96,230,181, 64,
+ 33, 24,119, 63,174, 26,130,191, 70,124, 25, 21,200,233, 3,255,103, 93,163, 64,136,128, 38,192, 83,235,153,191,156,111, 32,199,
+182,229, 3,255,238,219, 36, 64,132,151,165,192,165,226,109,191, 80, 56,223,142,176,235, 3,255, 24,237,111,191,118,174,184,192,
+212, 34,154,190,131,235,212,129,108,249, 3,255,163,244,130,192,157, 58,133,192,125, 95,226, 62,137,166,251,164,170, 9, 3,255,
+227,163, 54,192, 86,121, 78, 64, 22,202,125, 64,157,193,136, 70,177, 86, 3,255,241, 40, 53, 64,200, 31,134, 64,229,188, 60, 64,
+226, 61,162, 91,120, 64, 3,255, 37, 2,173, 64,137,187,123,191, 56, 68, 1, 64, 50,118,129,234, 40, 44, 3,255,124, 55,168, 63,
+224,177,164,192, 58,144, 29, 64,187, 28,124,143,210, 53, 3,255, 19,159,114,192,254,226, 34,192,196,133,106, 64, 31,173, 92,200,
+ 28, 80, 3,255,234,168, 2,192,231,158, 57, 61, 65,149,175, 64, 94,211,253, 0,245,119, 3,255,105,176,249, 62, 21,148, 39, 64,
+217,214,166, 64,169, 10, 62, 57,251,113, 3,255, 94, 35,105, 64,230, 88,129, 63,195, 14,143, 64,163, 79, 23, 22,188, 97, 3,255,
+114, 17, 68, 64,226,153, 35,192,154, 26,137, 64,250, 66, 30,200,171, 93, 3,255,155, 40,230,190,239,199, 73,192,176, 52,157, 64,
+ 45,246, 19,187,103,107, 3,255, 37,178, 10,192,138,231,201, 63,149,143,166,192,129,209,140, 33,145,141, 3,255, 3,132,110,192,
+243,203, 85, 64,151,107, 66,192, 16,174,158, 73,209,190, 3,255,116,161,174,190, 81,152,241, 63,110, 2,177,192,217,247, 15, 40,
+182,134, 3,255,138, 91,154, 63,218,179,133, 64,209,222,122,192, 0, 27, 30, 92, 86,171, 3,255, 7, 82, 52,192, 82,252,149, 64,
+ 64,202, 5,192, 39,193,227,101,181,210, 3,255,179, 12,148, 62,251,221,166, 64,188, 87, 41,192,192, 7,224,113, 21,198, 3,255,
+216,246, 29,192, 17,156,141,190,209,167,169,192, 47,203,160,250,137,139, 3,255, 99, 72,145,192, 79,114,213,191,183, 35, 83,192,
+ 26,156, 3,219, 12,185, 3,255,115, 58,158,192,129,120, 33, 64,198, 41,238,191,126,148,116, 56,137,215, 3,255,118,158,174,192,
+103,148, 33,191,140,156, 1,192,218,136,198,240,203,211, 3,255, 55, 14,249, 62, 95,133,102, 62,210,143,186,192, 56, 9, 40, 5,
+113,128, 3,255,220, 61, 92, 64, 56,230,159,190, 6, 61,151,192, 94, 76,242,248,135,153, 3,255, 7, 86, 60, 64, 60, 48,119, 64,
+ 93, 88, 81,192,119, 63,124, 85,246,184, 3,255,252, 55,139, 64, 62, 95,132, 63,225,216,113,192,118, 95, 54, 21,107,173, 3,255,
+ 18, 6, 84,191,251, 96,142,191, 76, 4,182,192,158,237, 20,233,109,131, 3,255,109, 74,225,189, 51, 54,123,192, 34,246,138,192,
+241,253, 39,169, 1,162, 3,255,153, 66,119, 64,127,154,251,191,161,220,123,192, 59, 85, 59,214, 34,170, 3,255,201, 59,208, 63,
+241,182,135,192,212,101,108,192,103, 34,133,162,160,175, 3,255,161,246,169,191,235,196,151,192,170,149, 74,192, 95,228,253,151,
+184,186, 3,255, 33,198,131,192,218,137, 84,192, 37,134, 32,192,247,164, 77,184,167,201, 3,255,176, 61,179,192,138,110,210,191,
+ 24,220,228,190,210,133,130,219,238,244, 3,255, 73,182,170,192,136, 16, 90,190, 90,194, 25, 64,224,139, 8,252,174, 53, 3,255,
+ 75, 55,153,192, 4, 78, 87, 64, 12, 54, 62,190,200,151, 29, 74,179,250, 3,255,235, 19,161,192,207, 12,210, 63,210,242, 31, 64,
+ 50,146,244, 34,182, 55, 3,255, 60, 75, 94,192,189,115,150, 64,186,211,167,190, 98,179, 49,102,183,247, 3,255,186,191,189,191,
+ 63, 32,168, 64,213,100, 7, 64,161,224,191,114, 61, 47, 3,255,242,205,186, 63,141, 65,177, 64,127,219,154,191, 82, 32,177,120,
+ 61,228, 3,255, 99,245,175, 62, 97, 12,178, 64,255,253,228, 63,247, 6, 65,121, 98, 40, 3,255,226, 92, 70, 64, 8,131,150, 64,
+182, 77,204,191,193, 66, 37,103, 32,220, 3,255,200,194,152, 64,180,155, 83, 64,154,217, 62, 63,207,104,101, 71, 87, 17, 3,255,
+ 73,182,170, 64,136, 16, 90, 62, 90,194, 25,192, 32,116,248, 3, 82,202, 3,255,176, 61,179, 64,138,110,210, 63, 24,220,228, 62,
+ 46,122,126, 36, 18, 11, 3,255,235, 19,161, 64,207, 12,210,191,210,242, 31,192,206,109, 12,221, 74,200, 3,255, 75, 55,153, 64,
+ 4, 78, 87,192, 12, 54, 62, 62, 56,104,227,181, 77, 5, 3,255,186,191,189, 63, 63, 32,168,192,213,100, 7,192, 95, 31, 65,141,
+195,208, 3,255, 60, 75, 94, 64,189,115,150,192,186,211,167, 62,158, 76,207,153, 73, 8, 3,255, 99,245,175,190, 97, 12,178,192,
+255,253,228,191, 9,249,191,134,158,215, 3,255,242,205,186,191,141, 65,177,192,127,219,154, 63,174,223, 79,135,195, 27, 3,255,
+200,194,152,192,180,155, 83,192,154,217, 62,191, 49,151,155,184,169,238, 3,255,226, 92, 70,192, 8,131,150,192,182, 77,204, 63,
+ 63,189,219,152,224, 35, 3,255,201, 59,208,191,241,182,135, 64,212,101,108, 64,153,221,123, 93, 96, 80, 3,255,153, 66,119,192,
+127,154,251, 63,161,220,123, 64,197,170,197, 41,222, 85, 3,255,161,246,169, 63,235,196,151, 64,170,149, 74, 64,161, 27, 3,104,
+ 72, 69, 3,255, 33,198,131, 64,218,137, 84, 64, 37,134, 32, 64, 9, 91,179, 71, 89, 54, 3,255,118,158,174, 64,103,148, 33, 63,
+140,156, 1, 64, 38,119, 58, 15, 53, 44, 3,255,115, 58,158, 64,129,120, 33,192,198, 41,238, 63,130,107,140,199,119, 40, 3,255,
+ 7, 82, 52, 64, 82,252,149,192, 64,202, 5, 64,217, 62, 29,154, 75, 45, 3,255,179, 12,148,190,251,221,166,192,188, 87, 41, 64,
+ 64,248, 32,142,235, 57, 3,255, 7, 86, 60,192, 60, 48,119,192, 93, 88, 81, 64,137,192,132,170, 10, 71, 3,255,252, 55,139,192,
+ 62, 95,132,191,225,216,113, 64,138,160,202,234,149, 82, 3,255,220, 61, 92,192, 56,230,159, 62, 6, 61,151, 64,162,179, 14, 7,
+121,102, 3,255, 55, 14,249,190, 95,133,102,190,210,143,186, 64,200,246,216,250,143,127, 3,255,109, 74,225, 61, 51, 54,123, 64,
+ 34,246,138, 64, 15, 2,217, 86,255, 93, 3,255, 18, 6, 84, 63,251, 96,142, 63, 76, 4,182, 64, 98, 18,236, 22,147,124, 3,255,
+ 99, 72,145, 64, 79,114,213, 63,183, 35, 83, 64,230, 99,253, 36,244, 70, 3,255,216,246, 29, 64, 17,156,141, 62,209,167,169, 64,
+209, 52, 96, 5,119,116, 3,255, 3,132,110, 64,243,203, 85,192,151,107, 66, 64,240, 81, 98,182, 47, 65, 3,255, 37,178, 10, 64,
+138,231,201,191,149,143,166, 64,127, 46,116,222,111,114, 3,255,138, 91,154,191,218,179,133,192,209,222,122, 64, 0,229,226,163,
+170, 84, 3,255,116,161,174, 62, 81,152,241,191,110, 2,177, 64, 39, 8,241,215, 74,121, 3,255, 36, 76, 19,192, 25,151,129, 64,
+212,254, 98,192,231,206, 97, 88,131,177, 3,255, 93,232,175,191,177, 23, 64, 64, 69,186,154,192,227,225,235, 66, 34,151, 3,255,
+208,190,232,190, 93,160,139, 64,191, 33,120,192,183,244,205, 94,192,170, 3,255,210,126,142,192, 43, 49,238, 63,112, 30, 84,192,
+187,158, 95, 39,183,182, 3,255,138,165, 97,192, 92, 9, 80, 63, 20, 74,147,192,183,177,233, 17, 86,156, 3,255, 98, 61,152,192,
+ 87, 63,106,188, 6, 97, 90,192,127,152,251, 0,183,180, 3,255,200,173, 14, 64,155,183, 63, 64,192, 75,144,192,206, 48, 45, 64,
+152,156, 3,255, 95,162,167, 63,144, 29,209, 63, 25,245,174,192,250, 29, 75, 36,250,136, 3,255,211, 62, 68, 64, 51, 56,168, 63,
+ 13,245,153,192,241, 65,192, 29,106,150, 3,255, 33,182, 36, 64, 34, 38,220,191,150, 5,159,192,233, 54,211,217,223,146, 3,255,
+ 16, 34, 81, 63,129, 64,179,191,162, 5,180,192,242, 18, 93,224,111,133, 3,255,212, 56,159, 63,172,166, 68,192,212,108,154,192,
+176, 27, 32,190,208,149, 3,255,204, 76,223,191,170, 32,101,192, 65, 83,137,192,199,216,195,178,198,161, 3,255,249,249, 10,192,
+ 62, 52,244,191, 25,236,162,192, 9,208, 0,213,102,145, 3,255, 42,207, 89,192,251, 6, 47,192, 27,165,121,192,209,182, 18,196,
+198,169, 3,255,137,215,176,192, 25, 62,241, 63,179,254,219,190,179,134,232, 39, 78,247, 3,255, 28,150,186,192,150, 16, 28, 60,
+191, 9, 7,191,118,128,131, 1, 77,245, 3,255, 34,132,181,192, 99, 60, 92, 63,217, 81,149, 63,181,131,238, 18,252, 23, 3,255,
+175,242, 74,190,164,173,183, 64,227,105,145,191,117,250,160,125, 31,232, 3,255,219,227, 2,192, 96,164,173, 64,200, 71, 78,191,
+164,212, 52,119,226,238, 3,255,181,140, 92,191, 75, 38,184, 64,176,148, 37, 63,224,236,237,125,159, 12, 3,255, 75,104,159, 64,
+212, 56,236, 63,240,126, 29,192,211,108,166, 41, 9,203, 3,255,215,159,132, 64, 84,184, 97, 64, 30, 44, 10,192,176, 91, 19, 76,
+ 56,209, 3,255, 95,122,164, 64,199,143, 44, 64, 53, 78, 68,191, 17,112, 17, 59,185,237, 3,255,255,176, 54, 64,243, 84,141,192,
+237,176, 36,192,192, 63, 9,160, 63,200, 3,255, 93,229,133, 64,217, 21, 68,192,157,226, 45,192,249, 90,187,187, 78,197, 3,255,
+203, 56,129, 64, 21,211,130,192,187,115,143,191,252, 87,194,166,252,229, 3,255,189,239,104,192, 82,142,140,192,178,178,168,191,
+134,177,245,158,155,227, 3,255, 50,141,253,191, 52,155,167,192,170,181,218,191,125,211,166,141,155,219, 3,255,164, 58, 41,192,
+172, 34,167,192,206,232,151, 61,232,197,243,141, 26, 0, 3,255, 93,229,133,192,217, 21, 68, 64,157,226, 45, 64, 7,165, 69, 68,
+178, 58, 3,255,203, 56,129,192, 21,211,130, 64,187,115,143, 63, 4,168, 62, 89, 4, 26, 3,255,255,176, 54,192,243, 84,141, 64,
+237,176, 36, 64, 64,192,247, 95,193, 55, 3,255, 50,141,253, 63, 52,155,167, 64,170,181,218, 63,131, 44, 90,114,101, 36, 3,255,
+164, 58, 41, 64,172, 34,167, 64,206,232,151,189, 24, 58, 13,114,230,255, 3,255,189,239,104, 64, 82,142,140, 64,178,178,168, 63,
+122, 78, 11, 97,101, 28, 3,255, 28,150,186, 64,150, 16, 28,188,191, 9, 7, 63,138,127,125,254,179, 10, 3,255, 34,132,181, 64,
+ 99, 60, 92,191,217, 81,149,191, 75,124, 18,237, 4,232, 3,255,137,215,176, 64, 25, 62,241,191,179,254,219, 62, 77,121, 24,216,
+178, 8, 3,255,219,227, 2, 64, 96,164,173,192,200, 71, 78, 63, 92, 43,204,136, 30, 17, 3,255,181,140, 92, 63, 75, 38,184,192,
+176,148, 37,191, 32, 19, 19,130, 97,243, 3,255,175,242, 74, 62,164,173,183,192,227,105,145, 63,139, 5, 96,130,225, 23, 3,255,
+215,159,132,192, 84,184, 97,192, 30, 44, 10, 64, 80,164,237,179,200, 46, 3,255, 95,122,164,192,199,143, 44,192, 53, 78, 68, 63,
+239,143,239,196, 71, 18, 3,255, 75,104,159,192,212, 56,236,191,240,126, 29, 64, 45,147, 90,214,247, 52, 3,255,212, 56,159,191,
+172,166, 68, 64,212,108,154, 64, 80,228,224, 65, 48,106, 3,255, 33,182, 36,192, 34, 38,220, 63,150, 5,159, 64, 23,201, 45, 38,
+ 33,109, 3,255, 16, 34, 81,191,129, 64,179, 63,162, 5,180, 64, 14,237,163, 31,145,122, 3,255, 42,207, 89, 64,251, 6, 47, 64,
+ 27,165,121, 64, 47, 73,238, 59, 58, 86, 3,255,208, 76,223, 63,170, 32,101, 64, 65, 83,137, 64, 57, 39, 61, 77, 58, 94, 3,255,
+249,249, 10, 64, 62, 52,244, 63, 25,236,162, 64,247, 47, 0, 43,154,110, 3,255,210,126,142, 64, 43, 49,238,191,112, 30, 84, 64,
+ 69, 97,161,216, 73, 73, 3,255, 98, 61,152, 64, 87, 63,106, 60, 6, 97, 90, 64,129,103, 5,255, 73, 75, 3,255,138,165, 97, 64,
+ 92, 9, 80,191, 20, 74,147, 64, 73, 78, 23,238,170, 99, 3,255,208,190,232, 62, 93,160,139,192,191, 33,120, 64, 73, 11, 51,161,
+ 64, 85, 3,255, 36, 76, 19, 64, 25,151,129,192,212,254, 98, 64, 25, 49,159,167,125, 78, 3,255, 93,232,175, 63,177, 23, 64,192,
+ 69,186,154, 64, 29, 30, 21,189,222,104, 3,255,211, 62, 68,192, 51, 56,168,191, 13,245,153, 64, 15,190, 64,226,150,105, 3,255,
+200,173, 14,192,155,183, 63,192,192, 75,144, 64, 50,207,211,191,104, 99, 3,255, 95,162,167,191,144, 29,209,191, 25,245,174, 64,
+ 6,226,181,219, 6,119, 3,255,158,156,211,191,185,228,132, 63,190,207,176,192,164,220,231, 21,244,134, 3,255, 0, 76, 41,192,
+190,199, 5, 64, 83,157,153,192,146,198, 75, 45,246,150, 3,255,204, 83,125,192,169, 55,105, 64,244,162, 20,192, 72,169,246, 79,
+ 82,206, 3,255,178,215, 91,192,222,235, 62, 64,190,254,108,192,215,180, 87, 65,155,175, 3,255,242, 63, 59,191,210,237,152, 63,
+251, 21,182,192,125,239, 26, 25,149,131, 3,255, 86,230, 94, 61,198, 30, 35, 64,233, 15,169,192,238, 0, 52, 55,135,140, 3,255,
+220, 4,199, 63, 7,145,146, 64,104,186, 83,192,109, 34,137,100,168,184, 3,255, 9,120, 86, 63,149, 91,109, 64, 79,242,142,192,
+133, 18, 64, 81,218,158, 3,255,103,243, 95,192,221, 91,138, 64,186, 15,236,191,170,178,219, 93, 25,216, 3,255, 46,206, 5,192,
+121, 41,159, 64,154, 91, 19,192,230,209, 96,108,226,205, 3,255,169,200,139, 63,198, 78,163, 64,201,146, 42,192,247, 24, 59,111,
+206,197, 3,255,187,128, 4,191,206,181,167, 64, 74, 92, 37,192, 57,245, 96,114,145,199, 3,255,151, 16,231,191,160,166,209, 61,
+167, 95,178,192,136,217,196, 2,245,133, 3,255,163,200, 69,192,178,143, 38,191,148, 48,158,192,243,188, 11,242,223,147, 3,255,
+ 43,192,155,192,151, 6,250,191,170, 82, 39,192, 79,149,247,212,231,199, 3,255,233,118,132,192,217,111,173,191, 67,122,123,192,
+100,165, 58,226,165,170, 3,255,238, 85,146,192,178,205, 78, 64, 70, 54,221,191,183,156,134, 71,120,218, 3,255, 76,137,167,192,
+111, 31,227, 63,158, 57,251,191,234,141, 54, 39, 59,213, 3,255, 39,143,170,192,167, 15,183,191,251, 85,252,191,217,139,169,223,
+ 13,213, 3,255, 8,214,175,192,177,124, 53, 62,206,241, 2,192, 23,136, 89, 3, 92,211, 3,255, 77,160,160,190, 9, 20,182, 62,
+108,232,186,192, 8,248,241, 7,128,128, 3,255, 33,144,163, 63,151,144,186, 61, 50, 47,183,192, 97, 27, 19, 2,252,130, 3,255,
+222,179,129, 64,234,147,224,190, 38,180,134,192, 83, 89, 64,246,218,164, 3,255,114,138, 49, 64,246, 97, 57,190, 57, 76,165,192,
+250, 60,247,251,138,143, 3,255,249,158, 27, 64,197,118,141, 64, 58,196, 62,192, 90, 52, 70, 97, 90,191, 3,255, 98,244, 89, 64,
+ 8,120, 79, 64, 65,128, 96,192, 8, 74, 39, 71,151,179, 3,255, 13,100,144, 64,200,214,118, 62, 64,205,110,192,182, 98, 37, 4,
+161,174, 3,255, 42,202,131, 64, 60,161,231, 63,142,245,112,192, 10, 90,255, 38,209,173, 3,255,149, 51,122,191, 52,151,163,190,
+ 15,157,184,192,118,234, 36,250,248,129, 3,255, 5,113, 42,191, 31,112,241,191, 15,119,176,192, 93,241, 84,215,135,135, 3,255,
+ 60, 55,172, 61, 22, 64,143,192,164,246,113,192, 27, 2,132,157, 71,174, 3,255,167,173,154,190,111,224, 83,192,198,169,154,192,
+136,249, 89,183,211,150, 3,255,151,133,136, 64, 9,249,162,191,106,219,115,192,175, 93, 47,229, 3,173, 3,255,110,124, 89, 64,
+135, 6, 40,192,223,195,127,192,120, 74, 31,199,208,168, 3,255,244,248,117, 63,109, 90,148,192,123, 0, 93,192, 8, 20, 66,154,
+249,180, 3,255,162, 0, 17, 64, 63,196,113,192, 52,239,119,192, 10, 49, 64,173,144,171, 3,255,162,217, 7,191, 21,117,156,192,
+222,238, 75,192,139,245, 20,149,108,186, 3,255,171,144, 6,192,112,158,144,192,198,241, 69,192,156,210, 55,157,115,188, 3,255,
+110,238,148,192,115,109, 50,192,187,197, 13,192,170,153,231,195, 17,208, 3,255, 79,252, 96,192,140, 40,115,192,116,165, 48,192,
+226,178, 98,173,236,195, 3,255,100,228,172,192,217,128,248,191, 8, 93,150,191, 91,138, 53,213, 86,229, 3,255, 82,171,182,192,
+216,250,168,191, 15, 15,147, 62,122,131,250,226,203, 5, 3,255,215, 73,160,192,124,165, 49, 62,232, 85, 66, 64, 33,147, 84, 4,
+ 42, 67, 3,255,171, 89,178,192,192,115, 24,191, 78,116,221, 63,129,134, 64,243, 50, 38, 3,255, 51,206,143,192,133,250,105, 64,
+119,251, 97,191, 85,158, 53, 80,193,235, 3,255, 62, 32,160,192,163, 38, 65, 64,164,117, 3, 63,236,146, 24, 66,193, 10, 3,255,
+216,108,155,192, 59,255,141, 63,189,117, 69, 64, 61,150,119, 23, 42, 68, 3,255, 85, 27,164,192,244, 78, 9, 64, 87,193,239, 63,
+ 33,144,128, 46, 73, 41, 3,255,134, 35,117,192, 39,152,138, 64, 73, 86,116,191,230,171, 2, 94, 73,234, 3,255, 35,220, 67,192,
+ 6,218,159, 64,242,103,155, 62,240,188,215,108, 55, 6, 3,255,130, 79, 99,191,215,182,164, 64, 10, 4, 42, 64,118,237, 50,112,
+190, 58, 3,255,161, 86, 3,192, 14,205,168, 64, 60, 55,197, 63,148,211, 31,115,255, 33, 3,255,229,101,215, 63, 84,141,168, 64,
+ 16, 90,248,191, 11, 37,148,114,159,212, 3,255, 99, 52,155, 63,198, 17,183, 64,232,199,235,190,159, 26,192,124,120,245, 3,255,
+105,179, 10, 61, 25,185,169, 64,120,119, 31, 64, 77, 0,101,115, 96, 55, 3,255,143,198, 37, 63,123,120,183, 64,160,108,135, 63,
+240, 13, 8,125,144, 23, 3,255,180,174, 32, 64, 65, 13,155, 64,238,167, 8,192,247, 53,245,105,163,208, 3,255, 69,199,104, 64,
+177,135,143, 64, 41, 12,132,191, 10, 79, 10, 98, 31,233, 3,255,121,134,159, 64, 49,245, 49, 64,210,166,169, 63, 27,109,242, 59,
+190, 29, 3,255, 52,133,143, 64,119,200,113, 64,186,206, 29, 62, 20, 98, 39, 82,190, 3, 3,255,215, 73,160, 64,124,165, 49,190,
+232, 85, 66,192,223,108,172,251,214,188, 3,255,171, 89,178, 64,192,115, 24, 63, 78,116,221,191,127,121,192, 12,206,217, 3,255,
+100,228,172, 64,217,128,248, 63, 8, 93,150, 63,165,117,203, 42,170, 26, 3,255, 82,171,182, 64,216,250,168, 63, 15, 15,147,190,
+134,124, 6, 29, 53,250, 3,255,216,108,155, 64, 59,255,141,191,189,117, 69,192,195,105,137,232,214,187, 3,255, 85, 27,164, 64,
+244, 78, 9,192, 87,193,239,191,223,111,128,209,183,214, 3,255, 51,206,143, 64,133,250,105,192,119,251, 97, 63,171, 97,203,175,
+ 63, 20, 3,255, 62, 32,160, 64,163, 38, 65,192,164,117, 3,191, 20,109,232,189, 63,245, 3,255,130, 79, 99, 63,215,182,164,192,
+ 10, 4, 42,192,138, 18,206,143, 66,197, 3,255,161, 86, 3, 64, 14,205,168,192, 60, 55,197,191,108, 44,225,140, 1,222, 3,255,
+134, 35,117, 64, 39,152,138,192, 73, 86,116, 63, 26, 84,254,161,183, 21, 3,255, 35,220, 67, 64, 6,218,159,192,242,103,155,190,
+ 16, 67, 41,147,201,249, 3,255,105,179, 10,189, 25,185,169,192,120,119, 31,192,179,255,155,140,160,200, 3,255,143,198, 37,191,
+123,120,183,192,160,108,135,191, 16,242,248,130,112,232, 3,255,229,101,215,191, 84,141,168,192, 16, 90,248, 63,245,218,108,141,
+ 97, 43, 3,255, 99, 52,155,191,198, 17,183,192,232,199,235, 62, 97,229, 64,131,136, 10, 3,255,121,134,159,192, 49,245, 49,192,
+210,166,169,191,229,146, 14,196, 66,226, 3,255, 52,133,143,192,119,200,113,192,186,206, 29,190,236,157,217,173, 66,252, 3,255,
+180,174, 32,192, 65, 13,155,192,238,167, 8, 64, 9,202, 11,150, 93, 47, 3,255, 69,199,104,192,177,135,143,192, 41, 12,132, 63,
+246,176,246,157,225, 22, 3,255,244,248,117,191,109, 90,148, 64,123, 0, 93, 64,248,235,190,101, 7, 75, 3,255,162, 0, 17,192,
+ 63,196,113, 64, 52,239,119, 64,246,206,192, 82,112, 84, 3,255,151,133,136,192, 9,249,162, 63,106,219,115, 64, 81,162,209, 26,
+253, 82, 3,255,110,124, 89,192,135, 6, 40, 64,223,195,127, 64,136,181,225, 56, 48, 87, 3,255,162,217, 7, 63, 21,117,156, 64,
+222,238, 75, 64,117, 10,236,106,148, 69, 3,255,171,144, 6, 64,112,158,144, 64,198,241, 69, 64,100, 45,201, 98,141, 67, 3,255,
+110,238,148, 64,115,109, 50, 64,187,197, 13, 64, 86,102, 25, 60,239, 47, 3,255, 79,252, 96, 64,140, 40,115, 64,116,165, 48, 64,
+ 30, 77,158, 82, 20, 60, 3,255, 39,143,170, 64,167, 15,183, 63,251, 85,252, 63, 39,116, 87, 32,243, 42, 3,255, 8,214,175, 64,
+177,124, 53,190,206,241, 2, 64,233,119,167,252,164, 44, 3,255,238, 85,146, 64,178,205, 78,192, 70, 54,221, 63, 73, 99,122,184,
+136, 37, 3,255, 76,137,167, 64,111, 31,227,191,158, 57,251, 63, 22,114,202,216,197, 42, 3,255,103,243, 95, 64,221, 91,138,192,
+186, 15,236, 63, 86, 77, 37,162,231, 39, 3,255, 46,206, 5, 64,121, 41,159,192,154, 91, 19, 64, 26, 46,160,147, 30, 50, 3,255,
+169,200,139,191,198, 78,163,192,201,146, 42, 64, 9,231,197,144, 50, 58, 3,255,187,128, 4, 63,206,181,167,192, 74, 92, 37, 64,
+199, 10,160,141,111, 56, 3,255,249,158, 27,192,197,118,141,192, 58,196, 62, 64,166,203,186,158,166, 64, 3,255, 98,244, 89,192,
+ 8,120, 79,192, 65,128, 96, 64,248,181,217,184,105, 76, 3,255, 13,100,144,192,200,214,118,190, 64,205,110, 64, 74,157,219,251,
+ 95, 81, 3,255, 42,202,131,192, 60,161,231,191,142,245,112, 64,246,165, 1,217, 47, 82, 3,255,222,179,129,192,234,147,224, 62,
+ 38,180,134, 64,173,166,192, 9, 38, 91, 3,255,114,138, 49,192,246, 97, 57, 62, 57, 76,165, 64, 6,195, 9, 4,118,112, 3,255,
+ 77,160,160, 62, 9, 20,182,190,108,232,186, 64,248, 7, 15,248,128,127, 3,255, 33,144,163,191,151,144,186,189, 50, 47,183, 64,
+159,228,237,253, 4,125, 3,255, 60, 55,172,189, 22, 64,143, 64,164,246,113, 64,229,253,124, 98,185, 81, 3,255,167,173,154, 62,
+111,224, 83, 64,198,169,154, 64,120, 6,167, 72, 45,105, 3,255,149, 51,122, 63, 52,151,163, 62, 15,157,184, 64,138, 21,220, 5,
+ 8,126, 3,255, 5,113, 42, 63, 31,112,241, 63, 15,119,176, 64,163, 14,172, 40,121,120, 3,255, 43,192,155, 64,151, 6,250, 63,
+170, 82, 39, 64,177,106, 9, 43, 25, 56, 3,255,233,118,132, 64,217,111,173, 63, 67,122,123, 64,156, 90,198, 29, 91, 85, 3,255,
+151, 16,231, 63,160,166,209,189,167, 95,178, 64,120, 38, 60,253, 11,122, 3,255,163,200, 69, 64,178,143, 38, 63,148, 48,158, 64,
+ 13, 67,245, 13, 33,108, 3,255,204, 83,125, 64,169, 55,105,192,244,162, 20, 64,184, 86, 10,176,174, 49, 3,255,178,215, 91, 64,
+222,235, 62,192,190,254,108, 64, 41, 75,169,190,101, 80, 3,255,158,156,211, 63,185,228,132,191,190,207,176, 64, 92, 35, 25,234,
+ 12,121, 3,255, 0, 76, 41, 64,190,199, 5,192, 83,157,153, 64,110, 57,181,210, 10,105, 3,255,220, 4,199,191, 7,145,146,192,
+104,186, 83, 64,147,221,119,155, 88, 71, 3,255, 9,120, 86,191,149, 91,109,192, 79,242,142, 64,123,237,192,174, 38, 97, 3,255,
+242, 63, 59, 63,210,237,152,191,251, 21,182, 64,131, 16,230,230,107,124, 3,255, 86,230, 94,189,198, 30, 35,192,233, 15,169, 64,
+ 18,255,204,200,121,115, 3,255,208, 27, 46,192,124,104, 86, 64, 85, 52,126,192,137,197,226, 72,134,168, 3,255, 82,168,234,191,
+ 87, 62,149, 64,118, 12, 67,192, 5,217,188,101,210,188, 3,255,186, 10, 16,192,249,106, 52, 64,210,253,147,192,182,206,131, 62,
+198,155, 3,255, 93, 33,240,190,191,199, 71, 64,142, 47,158,192,214,245, 40, 69,199,148, 3,255, 19, 46, 71,187,194,240,115, 64,
+175,166,142,192,240,254,161, 82, 66,158, 3,255,188,194,101,191, 17, 84,154, 64,240,193, 77,192, 76,235,214,104,142,185, 3,255,
+246,246,115,192,183, 86, 15, 64, 51,168,118,192,249,172,229, 47, 45,171, 3,255,101, 1,160,192, 47,146,184, 63,153, 38, 45,192,
+225,146, 96, 30,102,196, 3,255,215,229, 85,192,166,178,218, 63,183, 55,144,192, 38,182,133, 37,110,158, 3,255,151,178,104,192,
+245,107,205,189,175, 60,147,192,178,175,205,253, 91,156, 3,255,192, 81,136,192, 55,239, 4,191, 24,222,127,192,130,163,158,245,
+ 35,168, 3,255, 70,241,164,192,102,218,251, 62,143, 82, 48,192,222,143,210, 11,110,195, 3,255,209,230,173, 63,231,135, 71, 64,
+ 27,234,152,192,148, 29, 4, 67, 11,151, 3,255,158,103, 67, 64, 82,206, 51, 64, 39,168,132,192,203, 66, 63, 60,242,164, 3,255,
+136,131,100, 63, 16, 95, 27, 64, 4,115,168,192,122, 20,138, 53,143,141, 3,255, 77,154,217, 63,185, 69, 78, 63,221,196,177,192,
+ 53, 38,236, 17, 42,135, 3,255,107,195, 37, 64, 4,213, 36, 63, 20, 33,167,192,151, 55,194, 14,168,141, 3,255,103,139, 94, 64,
+153,146,250, 63, 72,141,137,192, 19, 75,156, 43,245,161, 3,255,231,195, 21, 64,236, 58,101,191,218,178,169,192,247, 49, 31,236,
+218,139, 3,255,142, 32, 48, 64,155,140, 32,192,195, 1,145,192, 3, 59,178,200,204,156, 3,255, 70,155,185, 63, 12,202, 59,191,
+163, 86,180,192,149, 32, 73,239, 91,133, 3,255, 29, 97, 43, 62,144,118, 2,192,125,231,175,192,106, 4,160,210,103,136, 3,255,
+ 97,116,196, 62, 10,176, 56,192,120,239,162,192,164, 8, 20,194, 81,144, 3,255,185, 2, 5, 64,217,105, 76,192,135,173,142,192,
+218, 45, 79,187, 56,158, 3,255,163,243,144,191,252, 41, 73,192,148, 66,154,192,134,230, 73,188,107,150, 3,255,147,133, 20,192,
+234, 55,124,192,176, 3,107,192,110,204,196,170,164,175, 3,255, 42,186, 60,192,219,128,189,191, 23, 43,155,192, 41,191,189,222,
+199,150, 3,255, 52,164,172,191,106,240, 18,192,141, 58,167,192, 76,226,213,204,128,142, 3,255, 12,171,100,192,249, 33,243,191,
+106,221,135,192,248,178,143,214,143,162, 3,255,195, 78, 74,192,241,206, 96,192, 98, 88, 94,192, 4,188, 34,179,129,179, 3,255,
+ 41,110,177,192, 81, 30,186, 63,105,249,158,191,160,134,165, 30, 86,229, 3,255, 45,138,172,192,114,149, 17, 64,127,203,200, 62,
+251,137,171, 48, 56, 9, 3,255, 10, 94,182,192, 48, 5, 1, 63, 86, 81,165,191,156,131, 24, 12, 94,228, 3,255,117,224,186,192,
+ 37,234,247,190,147, 56,126, 62,132,128,101,246, 46, 6, 3,255,204, 78,184,192, 19,193, 89,189,187,163,141, 63, 22,130,208,254,
+241, 22, 3,255,105,232,174,192,151,187,224, 63,156,183,153, 63,137,136,137, 38, 3, 25, 3,255, 42,118, 68,191,101,173,176, 64,
+114,132,233,191, 57,238,142,120,217,216, 3,255, 81,172,191, 62, 67,208,186, 64,195,163,216,190, 75, 7,131,127,159,247, 3,255,
+113, 2,218,191,172,151,171, 64,114, 25,212,191,243,219,116,117, 30,220, 3,255,251,244, 21,192, 28, 12,172, 64, 13,151,128, 61,
+229,205,196,117,226, 1, 3,255, 51, 39,223,191,248, 94,177, 64,104,122, 76, 63,155,217, 3,121, 65, 16, 3,255, 72,208, 28, 61,
+ 91, 13,187, 64, 64,215,245, 62,187, 0,168,127, 66, 9, 3,255, 45, 93,142, 64, 70,137, 14, 64,147,202, 70,192,241, 96,173, 49,
+202,188, 3,255,106, 23,173, 64,157,131,182, 63,175,176,225,191, 7,118, 20, 32, 72,218, 3,255, 78,203,128, 64,124, 14, 69, 64,
+ 55, 0, 61,192,168, 88, 80, 66,199,191, 3,255,133,175,133, 64, 28,149,121, 64, 51,212,168,191, 4, 92, 86, 84,170,227, 3,255,
+ 8,211,149, 64, 84,166, 94, 64, 68, 24, 29,191,221,101, 30, 76,113,241, 3,255, 31,169,175, 64,138,176,237, 63, 15,168,103,191,
+152,119,128, 40, 11,235, 3,255,122, 78, 57, 64,224, 12,120,192, 7, 56, 84,192, 62, 64,247,171,239,183, 3,255, 0, 74, 48, 64,
+245,165,155,192,208, 87,227,191, 38, 61, 68,150,192,217, 3,255, 85,108,100, 64,115, 47, 76,192,149,224, 88,192,102, 77, 90,185,
+131,182, 3,255,173,191,150, 64,227,233, 55,192,198,101,254,191,121,102, 79,192, 73,213, 3,255,119, 97,148, 64,200, 33, 89,192,
+ 24,225,150,191, 7,101, 44,182, 20,229, 3,255, 75,171, 86, 64, 36, 83,150,192, 22, 36,133,191,220, 72,131,153, 32,232, 3,255,
+116,251, 81,192,115, 80,139,192, 57,124, 10,192, 81,185, 53,160,254,208, 3,255, 70,239,122,192, 53,220,138,192,113, 86,227,190,
+ 68,171,132,160,195,246, 3,255, 14, 50, 28,192,245, 4,153,192,141, 39, 23,192,187,201,215,151, 33,205, 3,255, 34,123,189,191,
+203,168,178,192,149,106,130,191,209,222, 63,134,158,234, 3,255,176,127,232,191,177,107,178,192, 47,189,236,189, 65,216,100,134,
+ 66,252, 3,255, 53,168, 90,192,169, 83,152,192,227,201,133, 62, 29,181, 77,152,136, 4, 3,255,173,191,150,192,227,233, 55, 64,
+198,101,254, 63,135,153,177, 63,183, 42, 3,255, 85,108,100,192,115, 47, 76, 64,149,224, 88, 64,154,178,166, 70,125, 73, 3,255,
+119, 97,148,192,200, 33, 89, 64, 24,225,150, 63,249,154,212, 73,236, 26, 3,255, 75,171, 86,192, 36, 83,150, 64, 22, 36,133, 63,
+ 36,183,125,102,224, 23, 3,255, 0, 74, 48,192,245,165,155, 64,208, 87,227, 63,218,194,188,105, 64, 38, 3,255,122, 78, 57,192,
+224, 12,120, 64, 7, 56, 84, 64,194,191, 9, 84, 17, 72, 3,255, 34,123,189, 63,203,168,178, 64,149,106,130, 63, 47, 33,193,121,
+ 98, 21, 3,255, 14, 50, 28, 64,245, 4,153, 64,141, 39, 23, 64, 69, 54, 41,104,223, 50, 3,255,176,127,232, 63,177,107,178, 64,
+ 47,189,236, 61,191, 39,156,121,190, 3, 3,255, 53,168, 90, 64,169, 83,152, 64,227,201,133,190,227, 74,179,103,120,251, 3,255,
+ 70,239,122, 64, 53,220,138, 64,113, 86,227, 62,188, 84,124, 95, 61, 9, 3,255,116,251, 81, 64,115, 80,139, 64, 57,124, 10, 64,
+175, 70,203, 95, 2, 47, 3,255,117,224,186, 64, 37,234,247, 62,147, 56,126,190,124,127,155, 9,210,249, 3,255, 10, 94,182, 64,
+ 48, 5, 1,191, 86, 81,165, 63,100,124,232,243,162, 27, 3,255,204, 78,184, 64, 19,193, 89, 61,187,163,141,191,234,125, 48, 1,
+ 15,233, 3,255,105,232,174, 64,151,187,224,191,156,183,153,191,119,119,119,217,253,230, 3,255, 45,138,172, 64,114,149, 17,192,
+127,203,200,190, 5,118, 85,207,200,246, 3,255, 41,110,177, 64, 81, 30,186,191,105,249,158, 63, 96,121, 91,225,170, 26, 3,255,
+251,244, 21, 64, 28, 12,172,192, 13,151,128,189, 27, 50, 60,138, 30,254, 3,255,113, 2,218, 63,172,151,171,192,114, 25,212, 63,
+ 13, 36,140,138,226, 35, 3,255, 51, 39,223, 63,248, 94,177,192,104,122, 76,191,101, 38,253,134,191,239, 3,255, 72,208, 28,189,
+ 91, 13,187,192, 64,215,245,190, 69,255, 88,128,190,246, 3,255, 81,172,191,190, 67,208,186,192,195,163,216, 62,181,248,125,128,
+ 97, 8, 3,255, 42,118, 68, 63,101,173,176,192,114,132,233, 63,199, 17,114,135, 39, 39, 3,255,133,175,133,192, 28,149,121,192,
+ 51,212,168, 63,252,163,170,171, 86, 28, 3,255, 78,203,128,192,124, 14, 69,192, 55, 0, 61, 64, 88,167,176,189, 57, 64, 3,255,
+ 31,169,175,192,138,176,237,191, 15,168,103, 63,104,136,128,215,245, 20, 3,255, 8,211,149,192, 84,166, 94,192, 68, 24, 29, 63,
+ 35,154,226,179,143, 14, 3,255,106, 23,173,192,157,131,182,191,175,176,225, 63,249,137,236,223,184, 37, 3,255, 45, 93,142,192,
+ 70,137, 14,192,147,202, 70, 64, 15,159, 83,206, 54, 67, 3,255,185, 2, 5,192,217,105, 76, 64,135,173,142, 64, 38,210,177, 68,
+200, 97, 3,255, 97,116,196,190, 10,176, 56, 64,120,239,162, 64, 92,247,236, 61,175,111, 3,255,142, 32, 48,192,155,140, 32, 64,
+195, 1,145, 64,253,196, 78, 55, 52, 99, 3,255,231,195, 21,192,236, 58,101, 63,218,178,169, 64, 9,206,225, 19, 38,116, 3,255,
+ 70,155,185,191, 12,202, 59, 63,163, 86,180, 64,107,223,183, 16,165,122, 3,255, 29, 97, 43,190,144,118, 2, 64,125,231,175, 64,
+150,251, 96, 45,153,119, 3,255,195, 78, 74, 64,241,206, 96, 64, 98, 88, 94, 64,252, 67,222, 76,127, 76, 3,255, 12,171,100, 64,
+249, 33,243, 63,106,221,135, 64, 8, 77,113, 41,113, 93, 3,255,147,133, 20, 64,234, 55,124, 64,176, 3,107, 64,146, 51, 60, 85,
+ 92, 80, 3,255,164,243,144, 63,252, 41, 73, 64,148, 66,154, 64,122, 25,183, 67,149,105, 3,255, 52,164,172, 63,106,240, 18, 64,
+141, 58,167, 64,180, 29, 43, 51,128,113, 3,255, 42,186, 60, 64,219,128,189, 63, 23, 43,155, 64,215, 64, 67, 33, 57,105, 3,255,
+101, 1,160, 64, 47,146,184,191,153, 38, 45, 64, 31,109,160,225,154, 59, 3,255,246,246,115, 64,183, 86, 15,192, 51,168,118, 64,
+ 7, 83, 27,208,211, 84, 3,255, 70,241,164, 64,102,218,251,190,143, 82, 48, 64, 34,112, 46,244,146, 60, 3,255,192, 81,136, 64,
+ 55,239, 4, 63, 24,222,127, 64,126, 92, 98, 10,221, 87, 3,255,151,178,104, 64,245,107,205, 61,175, 60,147, 64, 78, 80, 51, 2,
+165, 99, 3,255,215,229, 85, 64,166,178,218,191,183, 55,144, 64,218, 73,123,218,146, 97, 3,255,188,194,101, 63, 17, 84,154,192,
+240,193, 77, 64,180, 20, 42,151,114, 70, 3,255, 19, 46, 71, 59,194,240,115,192,175,166,142, 64, 16, 1, 95,173,190, 97, 3,255,
+ 82,168,234, 63, 87, 62,149,192,118, 12, 67, 64,251, 38, 68,154, 46, 67, 3,255,208, 27, 46, 64,124,104, 86,192, 85, 52,126, 64,
+119, 58, 30,183,122, 87, 3,255,186, 10, 16, 64,249,106, 52,192,210,253,147, 64, 74, 49,125,193, 58,100, 3,255, 93, 33,240, 62,
+191,199, 71,192,142, 47,158, 64, 42, 10,216,186, 57,107, 3,255,103,139, 94,192,153,146,250,191, 72,141,137, 64,237,180,100,212,
+ 11, 94, 3,255,107,195, 37,192, 4,213, 36,191, 20, 33,167, 64,105,200, 62,241, 88,114, 3,255,158,103, 67,192, 82,206, 51,192,
+ 39,168,132, 64, 53,189,193,195, 14, 91, 3,255,209,230,173,191,231,135, 71,192, 27,234,152, 64,108,226,252,188,245,104, 3,255,
+ 77,154,217,191,185, 69, 78,191,221,196,177, 64,203,217, 20,238,214,120, 3,255,136,131,100,191, 16, 95, 27,192, 4,115,168, 64,
+134,235,118,202,113,114, 3,255,139,220, 37,192,245,135,141, 64,114,173, 54,192, 45,199, 95, 96,211,193, 3,255,204,119, 84,192,
+ 93, 73,130, 64,212,107, 38,192, 58,183,223, 88,137,199, 3,255,208, 76, 67,192, 62,120,111, 64, 14, 89, 85,192, 80,189,196, 81,
+140,183, 3,255, 68,147,238,191,166,230,100, 64,234, 9,136,192,216,215,130, 78, 59,163, 3,255, 30,149,109,191, 40, 18,111, 64,
+171,100,141,192, 37,235,201, 81,199,159, 3,255,144,237,178,191, 25,136,136, 64,121, 1,113,192,117,225,189, 92, 62,173, 3,255,
+214, 82, 66, 63,128,115,152, 64,164, 25, 85,192,241, 16, 27,104,126,183, 3,255,119,155,171,189,138, 40,155, 64,113, 96, 83,192,
+128,254,196,105,238,183, 3,255, 67,138,194, 62,177, 97,138, 64, 75,158,124,192,112, 8,134, 94, 29,170, 3,255,158,106, 94,191,
+167,106, 30, 64,254,240,167,192,229,236,187, 53,105,141, 3,255, 22,114,229,191,193, 96, 20, 64,253,167,162,192, 22,217, 93, 50,
+244,144, 3,255, 45,210,162,191,233,211,224, 63,184, 67,174,192, 69,228,245, 37,244,136, 3,255, 37, 61,152,192,230, 9, 14, 64,
+137,179, 39,192, 85,152,183, 48,226,198, 3,255,232,187,140,192, 6, 96, 62, 64,107,247, 30,192, 7,160, 68, 65, 11,202, 3,255,
+116,134,132,192, 40,130, 40, 64,237,207, 77,192,139,165,149, 57, 30,186, 3,255, 12,129,129,192,231,129,173, 63,159,125,128,192,
+ 62,167, 15, 29,123,168, 3,255,254,112,134,192,126,146,207, 62,159, 19,130,192, 15,164,119, 9,117,167, 3,255,189,121,149,192,
+142,192,111, 63, 76, 95, 90,192, 95,154,107, 20,236,180, 3,255, 12, 65,162,192, 11, 84,149,191,172,202, 44,192, 60,145, 47,230,
+ 75,197, 3,255, 74,120,165,192, 95, 78,167,190,139, 51, 48,192, 54,143,140,248,244,195, 3,255, 61,161,150,192,107,221, 89,191,
+118,113, 89,192, 40,153, 79,237, 35,182, 3,255, 52, 56, 66,192,206, 40,139, 62, 21,116,160,192, 13,190, 19, 6,121,146, 3,255,
+245,120, 56,192,118,213,154, 63, 81,227,158,192, 81,193, 47, 26,133,147, 3,255,220,104, 22,192,204,221, 40, 63,115,137,170,192,
+ 16,205, 89, 14,117,139, 3,255,145,143, 39, 64,190, 49, 94, 64,165, 27,124,192,238, 56,252, 75, 43,170, 3,255,130,168, 6, 64,
+190,132,130, 64, 12, 96,105,192,226, 45, 91, 89,173,176, 3,255, 76,169,222, 63,205,107,104, 64,150,142,136,192, 23, 38,105, 79,
+ 33,163, 3,255,137,207,229, 63, 30, 63, 22, 64,207,235,161,192,198, 39,227, 50,127,145, 3,255,239, 11, 14, 64,175,114,191, 63,
+254,208,166,192,133, 48, 81, 33, 87,142, 3,255,239,222, 43, 64,212,226, 11, 64,227, 71,151,192, 33, 58,140, 47, 91,152, 3,255,
+ 0,245,124, 64, 27, 32,187, 62, 57, 6,138,192,138, 86,176, 7, 2,162, 3,255, 42, 75,112, 64,228, 42,152, 63, 25, 44,139,192,
+ 0, 82,159, 25, 31,161, 3,255,178,218, 82, 64,178,247, 1, 63,211,129,154,192, 35, 72, 4, 11,217,150, 3,255,208,203,104, 63,
+146, 6,113, 63,108, 5,183,192,132, 19,150, 20, 49,131, 3,255, 26, 68,251, 62,111, 38,228, 63,114, 48,178,192,139, 10,158, 38,
+109,134, 3,255,163, 78,149, 61, 65, 25,137, 63,234,102,184,192, 54, 1, 52, 23, 34,130, 3,255, 98,140, 80, 64,169,205,238,191,
+ 83, 69,144,192, 70, 71,145,215,173,157, 3,255,177, 39,109, 64,155,213,147,191,238,143,140,192, 57, 81,247,230, 77,160, 3,255,
+100,225, 66, 64,146,191,131,191,152, 18,157,192,178, 66,128,233, 25,149, 3,255,190, 24,220, 63,163,163,202,191,160,244,171,192,
+ 99, 37,199,220,196,138, 3,255,227,219,133, 63,172, 47, 17,192, 93,160,169,192,126, 23,164,206, 68,140, 3,255, 46,202,247, 63,
+ 23,140, 27,192,116,252,158,192,217, 41, 77,203, 32,147, 3,255, 36,220, 68, 63, 24,143,132,192, 20,105,130,192,163, 16, 66,165,
+ 72,167, 3,255, 60,255,185, 63,215,244,108,192,129, 7,138,192,113, 31, 11,175,251,161, 3,255,220, 18, 19, 63,168,186, 98,192,
+ 66,136,148,192,155, 12,121,178,241,154, 3,255,131,119,172,187,182,209,162,191,170, 73,183,192,209,255,144,228,251,130, 3,255,
+165,230, 40, 63,246,111, 24,191, 50,150,185,192, 19, 14, 18,243,113,129, 3,255,123, 45, 50,190,213, 16,230,190,160,240,186,192,
+231,251,124,246,109,128, 3,255,221, 22,199,191, 71,211,134,192, 37,161,113,192, 98,222,255,163,157,173, 3,255,171,131, 58,191,
+ 57,178,140,192,214,174,115,192,105,240,201,159, 11,173, 3,255,228,119,112,191, 49, 46,115,192,186,222,139,192,152,235,221,172,
+217,160, 3,255,122, 75,254,191, 18, 36, 50,192, 84, 70,152,192,253,211, 46,195, 87,152, 3,255,190,239, 52,192,193,186, 22,192,
+166,240,145,192,167,194, 3,204,108,156, 3,255, 51, 23, 39,192, 14,245, 76,192,105,248,132,192, 29,199,137,186,200,164, 3,255,
+202,137,140,192, 4,234, 33,192,152,117, 60,192,215,159,216,200, 6,192, 3,255, 68,176,115,192, 85, 49, 68,192, 65,173, 79,192,
+178,172, 81,189, 81,185, 3,255,131,173,128,192, 50,170, 14,192,247, 71,105,192, 30,168, 64,207,189,176, 3,255,230, 80, 22,192,
+ 50,155,141,191,108, 95,168,192, 3,205, 6,232, 19,141, 3,255, 96,113,194,191,166,184,195,191, 31,160,174,192,205,222,245,222,
+227,136, 3,255,249,244,213,191, 10, 33, 52,191,248, 94,178,192,172,219, 3,241, 48,134, 3,255, 30, 26,167,192, 62, 11, 42, 64,
+199,163,159,190, 45,142, 26, 58,236,248, 3,255, 15,242,157,192,177, 35, 63, 64,242,230,132,191,115,148,134, 65, 39,233, 3,255,
+ 58,163,169,192,184,207, 14, 64, 43, 92,148,191,122,140,250, 48,193,230, 3,255,241, 83,184,192, 33,241,117, 63,204, 69,248,190,
+ 32,130,245, 20, 22,246, 3,255, 88,178,186,192,180, 33,226, 62, 69,211,165, 62,153,128, 65, 10,196, 6, 3,255,100,194,181,192,
+227, 37,178, 63, 65, 51,191, 62,199,131,217, 29,201, 7, 3,255,140, 68,168,192,162,100, 57, 63, 90, 41, 31, 64, 91,141,195, 15,
+175, 54, 3,255,185,114,173,192,147, 11,162, 63,136,131,237, 63,204,137,106, 27,187, 40, 3,255, 90, 82,178,192,181, 0,168, 62,
+125, 64,231, 63,136,134, 78, 7,175, 39, 3,255,235, 52,185,192,191,185, 83,191, 39,176,252,190,201,129,211,237,241,244, 3,255,
+ 95,222,182,192,178, 32,161,190, 48, 92,165,191, 90,131,208,248,211,227, 3,255, 52,119,179,192,223,204,147,191,116,141,160,191,
+169,133,113,230,103,228, 3,255,109, 88, 35, 63,129,186,182, 64,207, 8,152,191, 5, 14,127,124,202,229, 3,255,226, 54, 99, 63,
+172,134,174, 64, 96, 98,250,191,180, 19,244,118, 14,213, 3,255,150,195, 60, 61, 46,121,177, 64,174, 6,245,191, 84, 1,249,120,
+ 55,214, 3,255,228,160,145,191,121, 59,181, 64,246,252,123,191, 63,231,214,123, 42,235, 3,255, 29,166,188,191,167,120,181, 64,
+ 4,224,165,189, 81,224,253,123,203,253, 3,255, 26,186, 9,191,104,142,186, 64,128, 74,126,190,158,243, 69,127, 88,250, 3,255,
+179,205, 19,191, 33,145,175, 64,102,151,253, 63,125,243,171,119,167, 43, 3,255,163,114,134,190, 81, 94,183, 64, 73,210,157, 63,
+ 40,250,240,124, 49, 27, 3,255,253,217,151,191, 90, 89,178, 64,210,246,178, 63, 89,230,146,121,187, 30, 3,255,107,200, 50,192,
+ 4, 21,164, 64,143,252, 18,191,229,194,189,111, 58,243, 3,255,219,140, 29,192,164,216,163, 64,163,160,187,191, 2,202,148,111,
+ 27,224, 3,255, 8, 63, 76,192,149, 92,152, 64,201, 6,157,191,254,185,184,103, 25,229, 3,255,102, 31,167, 64, 18,113,133, 63,
+122,150, 29,192,214,113,149, 22, 5,202, 3,255,115, 48,157, 64, 74,183, 33, 63, 21,172, 72,192, 50,107,106, 13, 91,187, 3,255,
+250, 48,151, 64,117,157,186, 63,236, 37, 74,192, 41,103,126, 31, 23,187, 3,255,118, 31,148, 64,144, 99, 46, 64, 95,237, 21,192,
+101,101,141, 59,115,205, 3,255, 40,177,150, 64,101,250, 73, 64,104,252,189,191, 13,103,113, 68, 39,223, 3,255, 59, 67,164, 64,
+106,116, 19, 64, 96,145,209,191,204,111,223, 50,255,219, 3,255, 9, 99,168, 64,184,173, 32, 64,129, 16, 27, 63,228,114,189, 54,
+164, 13, 3,255,225, 1,174, 64, 65,167, 12, 64,199, 1, 38,190,149,118, 17, 48,195,252, 3,255,172,156,160, 64, 23,121, 66, 64,
+220,253, 53,188,155,109, 25, 66, 0, 0, 3,255,230,184,106, 64,117, 83,133, 64, 76, 95,243,191,202, 79,251, 90, 77,214, 3,255,
+116,166,101, 64, 67,107,111, 64, 69,233, 47,192, 23, 78,219, 81, 34,196, 3,255,109, 20, 68, 64,202, 9,139, 64,124,255, 29,192,
+138, 66, 22, 95, 6,202, 3,255, 46,138, 12, 64,195,168,156,192, 99,240, 23,192,172, 47, 54,149,252,203, 3,255,110,189,201, 63,
+ 48, 28,154,192,180,148, 60,192, 2, 34,195,150,147,191, 3,255, 21, 55, 17, 64,125, 67,140,192,118, 8, 75,192, 61, 49, 50,160,
+221,186, 3,255, 85,126,100, 64,103,211,114,192,187,176, 43,192, 60, 78,241,172, 2,198, 3,255, 29,112,133, 64,168, 45,104,192,
+ 95, 44,249,191,154, 90, 96,176, 48,213, 3,255,192,193, 95, 64,221, 5,138,192, 42,219,239,191,181, 76, 61,162,177,214, 3,255,
+ 28, 21,134, 64,185,231,130,192,175,210,133, 62,128, 91,182,166, 33, 6, 3,255,128,101,115, 64,106,100,142,192,214,174,205,190,
+ 32, 83, 12,159,127,247, 3,255,187,250,142, 64,178,123,113,192, 90,120,242,190, 99, 97,142,173,244,245, 3,255,115, 83,149, 64,
+ 25,118, 24,192, 96, 5, 41,192,195,101, 61,204, 36,198, 3,255,236, 97,130, 64,181,248, 34,192, 49,132, 87,192, 17, 89,184,200,
+144,182, 3,255,186,103,144, 64, 91, 9,234,191,150,226, 80,192,152, 98,121,216,152,184, 3,255,208, 74,136,192,231,117,121,192,
+ 32,193,133,191,248,162, 42,171,249,232, 3,255, 31, 84,144,192, 24, 19, 87,192, 53, 65,211,191, 74,157,248,182,224,219, 3,255,
+ 7, 90,123,192,107,238,121,192,115,227,247,191, 22,170, 1,171,218,213, 3,255,161,112, 54,192, 94, 77,156,192,207,107,196,191,
+198,193, 23,149, 32,223, 3,255, 24, 41, 22,192, 1,197,169,192,191, 68, 84,191, 45,204,105,140,172,237, 3,255, 73,243, 75,192,
+ 86, 16,156,192,180,150, 33,191,216,186, 63,149,194,241, 3,255,140,246, 19,192,148, 60,166,192, 11, 70,182, 63,164,205,159,142,
+127, 31, 3,255, 17, 21, 58,192,224,209,160,192,103,100, 88, 63,202,192, 72,146,171, 18, 3,255,151,252, 4,192, 71, 89,174,192,
+215, 93, 38, 63,148,210, 55,137,122, 14, 3,255, 53,176,150,191,238,252,174,192, 37,172,226,191,114,230,199,136, 20,217, 3,255,
+225,105,214,191,211,177,161,192,160,229, 29,192,197,219,175,145, 38,202, 3,255, 62,213, 88,191,193, 70,167,192,212,217, 32,192,
+221,237,232,141,230,200, 3,255,236, 97,130,192,181,248, 34, 64, 49,132, 87, 64,239,166, 72, 55,112, 73, 3,255,186,103,144,192,
+ 91, 9,234, 63,150,226, 80, 64,104,157,135, 39,104, 71, 3,255,115, 83,149,192, 25,118, 24, 64, 96, 5, 41, 64, 61,154,195, 51,
+220, 57, 3,255, 29,112,133,192,168, 45,104, 64, 95, 44,249, 63,102,165,160, 79,208, 42, 3,255,192,193, 95,192,221, 5,138, 64,
+ 42,219,239, 63, 75,179,195, 93, 79, 41, 3,255, 85,126,100,192,103,211,114, 64,187,176, 43, 64,196,177, 15, 83,254, 57, 3,255,
+110,189,201,191, 48, 28,154, 64,180,148, 60, 64,254,221, 61,105,109, 64, 3,255, 21, 55, 17,192,125, 67,140, 64,118, 8, 75, 64,
+195,206,206, 95, 35, 69, 3,255, 46,138, 12,192,195,168,156, 64, 99,240, 23, 64, 84,208,202,106, 4, 52, 3,255,128,101,115,192,
+106,100,142, 64,214,174,205, 62,224,172,244, 96,129, 8, 3,255,187,250,142,192,178,123,113, 64, 90,120,242, 62,157,158,114, 82,
+ 12, 10, 3,255, 28, 21,134,192,185,231,130, 64,175,210,133,190,128,164, 74, 89,223,249, 3,255,225,105,214, 63,211,177,161, 64,
+160,229, 29, 64, 59, 36, 81,110,218, 53, 3,255, 62,213, 88, 63,193, 70,167, 64,212,217, 32, 64, 35, 18, 24,114, 26, 55, 3,255,
+ 53,176,150, 63,238,252,174, 64, 37,172,226, 63,142, 25, 57,119,236, 38, 3,255, 24, 41, 22, 64, 1,197,169, 64,191, 68, 84, 63,
+211, 51,151,115, 84, 18, 3,255, 73,243, 75, 64, 86, 16,156, 64,180,150, 33, 63, 40, 69,193,106, 62, 14, 3,255,161,112, 54, 64,
+ 94, 77,156, 64,208,107,196, 63, 58, 62,233,106,224, 32, 3,255, 31, 84,144, 64, 24, 19, 87, 64, 53, 65,211, 63,182, 98, 8, 73,
+ 32, 36, 3,255, 7, 90,123, 64,107,238,121, 64,115,227,247, 63,234, 85,255, 84, 38, 42, 3,255,208, 74,136, 64,231,117,121, 64,
+ 32,193,133, 63, 8, 93,214, 84, 7, 23, 3,255, 17, 21, 58, 64,224,209,160, 64,103,100, 88,191, 54, 63,184,109, 85,237, 3,255,
+151,252, 4, 64, 71, 89,174, 64,215, 93, 38,191,108, 45,201,118,134,241, 3,255,140,246, 19, 64,148, 60,166, 64, 11, 70,182,191,
+ 92, 50, 97,113,129,224, 3,255, 95,222,182, 64,178, 32,161, 62, 48, 92,165, 63,166,124, 48, 7, 45, 28, 3,255, 52,119,179, 64,
+223,204,147, 63,116,141,160, 63, 87,122,143, 25,153, 27, 3,255,235, 52,185, 64,191,185, 83, 63, 39,176,252, 62, 55,126, 45, 18,
+ 15, 11, 3,255, 88,178,186, 64,180, 33,226,190, 69,211,165,190,103,127,191,245, 60,249, 3,255,100,194,181, 64,227, 37,178,191,
+ 65, 51,191,190, 57,124, 39,226, 55,248, 3,255,241, 83,184, 64, 33,241,117,191,204, 69,248, 62,224,125, 11,235,234, 9, 3,255,
+ 15,242,157, 64,177, 35, 63,192,242,230,132, 63,141,107,122,190,217, 22, 3,255, 58,163,169, 64,184,207, 14,192, 43, 92,148, 63,
+134,115, 6,207, 63, 25, 3,255, 30, 26,167, 64, 62, 11, 42,192,199,163,159, 62,211,113,230,197, 20, 7, 3,255,185,114,173, 64,
+147, 11,162,191,136,131,237,191, 52,118,150,228, 69,215, 3,255, 90, 82,178, 64,181, 0,168,190,125, 64,231,191,120,121,178,248,
+ 81,216, 3,255,140, 68,168, 64,162,100, 57,191, 90, 41, 31,192,165,114, 61,240, 81,201, 3,255,219,140, 29, 64,164,216,163,192,
+163,160,187, 63,254, 53,108,144,229, 31, 3,255, 8, 63, 76, 64,149, 92,152,192,201, 6,157, 63, 2, 70, 72,152,231, 26, 3,255,
+107,200, 50, 64, 4, 21,164,192,143,252, 18, 63, 27, 61, 67,144,198, 12, 3,255, 29,166,188, 63,167,120,181,192, 4,224,165, 61,
+175, 31, 3,132, 53, 2, 3,255, 26,186, 9, 63,104,142,186,192,128, 74,126, 62, 98, 12,187,128,168, 5, 3,255,228,160,145, 63,
+121, 59,181,192,246,252,123, 63,193, 24, 42,132,214, 20, 3,255,226, 54, 99,191,172,134,174,192, 96, 98,250, 63, 76,236, 12,137,
+242, 42, 3,255,150,195, 60,189, 46,121,177,192,174, 6,245, 63,172,254, 7,135,201, 41, 3,255,109, 88, 35,191,129,186,182,192,
+207, 8,152, 63,251,241,129,131, 54, 26, 3,255,163,114,134, 62, 81, 94,183,192, 73,210,157,191,216, 5, 16,131,207,228, 3,255,
+253,217,151, 63, 90, 89,178,192,210,246,178,191,167, 25,110,134, 69,225, 3,255,179,205, 19, 63, 33,145,175,192,102,151,253,191,
+131, 12, 85,136, 89,212, 3,255,116,166,101,192, 67,107,111,192, 69,233, 47, 64,233,177, 37,174,222, 59, 3,255,109, 20, 68,192,
+202, 9,139,192,124,255, 29, 64,118,189,234,160,250, 53, 3,255,230,184,106,192,117, 83,133,192, 76, 95,243, 63, 54,176, 5,165,
+179, 41, 3,255, 40,177,150,192,101,250, 73,192,104,252,189, 63,243,152,143,187,217, 32, 3,255, 59, 67,164,192,106,116, 19,192,
+ 96,145,209, 63, 52,144, 33,205, 1, 36, 3,255,118, 31,148,192,144, 99, 46,192, 95,237, 21, 64,155,154,115,196,141, 50, 3,255,
+115, 48,157,192, 74,183, 33,191, 21,172, 72, 64,206,148,150,242,165, 68, 3,255,250, 48,151,192,117,157,186,191,236, 37, 74, 64,
+215,152,130,224,233, 68, 3,255,102, 31,167,192, 18,113,133,191,122,150, 29, 64, 42,142,107,233,251, 53, 3,255,225, 1,174,192,
+ 65,167, 12,192,199, 1, 38, 62,107,137,239,207, 61, 3, 3,255,172,156,160,192, 23,121, 66,192,220,253, 53, 60,101,146,231,189,
+ 0, 0, 3,255, 9, 99,168,192,184,173, 32,192,129, 16, 27,191, 28,141, 67,201, 92,242, 3,255,220, 18, 19,191,168,186, 98, 64,
+ 66,136,148, 64,101,243,135, 77, 15,101, 3,255, 36,220, 68,191, 24,143,132, 64, 20,105,130, 64, 93,239,190, 90,184, 88, 3,255,
+ 60,255,185,191,215,244,108, 64,129, 7,138, 64,143,224,245, 80, 5, 94, 3,255, 46,202,247,191, 23,140, 27, 64,116,252,158, 64,
+ 39,214,179, 52,224,108, 3,255,190, 24,220,191,163,163,202, 63,160,244,171, 64,157,218, 57, 35, 60,117, 3,255,227,219,133,191,
+172, 47, 17, 64, 93,160,169, 64,130,232, 92, 49,188,115, 3,255,123, 45, 50, 62,213, 16,230, 62,160,240,186, 64, 25, 4,132, 9,
+147,127, 3,255,131,119,172, 59,182,209,162, 63,170, 73,183, 64, 47, 0,112, 27, 5,125, 3,255,165,230, 40,191,246,111, 24, 63,
+ 50,150,185, 64,237,241,238, 12,143,126, 3,255,100,225, 66,192,146,191,131, 63,152, 18,157, 64, 78,189,128, 22,231,106, 3,255,
+ 98,140, 80,192,169,205,238, 63, 83, 69,144, 64,186,184,111, 40, 83, 98, 3,255,177, 39,109,192,154,213,147, 63,239,143,140, 64,
+199,174, 9, 25,179, 95, 3,255,131,173,128, 64, 50,170, 14, 64,247, 71,105, 64,226, 87,192, 48, 67, 79, 3,255,202,137,140, 64,
+ 4,234, 33, 64,152,117, 60, 64, 41, 96, 40, 55,250, 63, 3,255, 68,176,115, 64, 85, 49, 68, 64, 65,173, 79, 64, 78, 83,175, 66,
+175, 70, 3,255, 51, 23, 39, 64, 14,245, 76, 64,105,248,132, 64,227, 56,119, 69, 56, 91, 3,255,122, 75,254, 63, 17, 36, 50, 64,
+ 83, 70,152, 64, 3, 44,210, 60,169,103, 3,255,190,239, 52, 64,193,186, 22, 64,166,240,145, 64, 89, 61,253, 51,148, 99, 3,255,
+249,244,213, 63, 10, 33, 52, 63,248, 94,178, 64, 84, 36,253, 14,208,121, 3,255,230, 80, 22, 64, 50,155,141, 63,108, 95,168, 64,
+253, 50,250, 23,237,114, 3,255, 96,113,194, 63,166,184,195, 63, 31,160,174, 64, 51, 33, 11, 33, 29,119, 3,255,228,119,112, 63,
+ 49, 46,115, 64,186,222,139, 64,104, 20, 35, 83, 40, 95, 3,255,221, 22,199, 63, 71,211,134, 64, 37,161,113, 64,158, 33, 1, 92,
+ 99, 82, 3,255,170,131, 58, 63, 58,178,140, 64,213,174,115, 64,151, 15, 55, 96,245, 82, 3,255,116,134,132, 64, 40,130, 40,192,
+237,207, 77, 64,117, 90,107,198,226, 69, 3,255,232,187,140, 64, 6, 96, 62,192,107,247, 30, 64,249, 95,188,190,245, 53, 3,255,
+ 37, 61,152, 64,230, 9, 14,192,137,179, 39, 64,171,103, 73,207, 30, 57, 3,255,189,121,149, 64,142,192,111,191, 76, 95, 90, 64,
+161,101,149,235, 20, 75, 3,255,254,112,134, 64,126,146,207,190,159, 19,130, 64,241, 91,137,246,139, 88, 3,255, 12,129,129, 64,
+231,129,173,191,159,125,128, 64,194, 88,241,226,133, 87, 3,255,220,104, 22, 64,204,221, 40,191,115,137,170, 64,240, 50,167,241,
+139,116, 3,255,245,120, 56, 64,118,213,154,191, 81,227,158, 64,175, 62,209,229,123,108, 3,255, 52, 56, 66, 64,206, 40,139,190,
+ 21,116,160, 64,243, 65,237,249,135,109, 3,255, 61,161,150, 64,107,221, 89, 63,118,113, 89, 64,216,102,177, 18,221, 73, 3,255,
+ 74,120,165, 64, 95, 78,167, 62,139, 51, 48, 64,202,112,116, 7, 12, 60, 3,255, 12, 65,162, 64, 11, 84,149, 63,172,202, 44, 64,
+196,110,209, 25,181, 58, 3,255, 67,138,194,190,177, 97,138,192, 75,158,124, 64,144,247,122,161,227, 85, 3,255,214, 82, 66,191,
+128,115,152,192,164, 25, 85, 64, 15,239,229,151,130, 72, 3,255,119,155,171, 61,138, 40,155,192,113, 96, 83, 64,128, 1, 60,150,
+ 18, 72, 3,255,144,237,178, 63, 25,136,136,192,121, 1,113, 64,139, 30, 67,163,194, 82, 3,255, 68,147,238, 63,166,230,100,192,
+234, 9,136, 64, 40, 40,126,177,197, 92, 3,255, 30,149,109, 63, 40, 18,111,192,171,100,141, 64,219, 20, 55,174, 57, 96, 3,255,
+ 45,210,162, 63,233,211,224,191,184, 67,174, 64,187, 27, 11,218, 12,119, 3,255,158,106, 94, 63,167,106, 30,192,254,240,167, 64,
+ 27, 19, 69,202,151,114, 3,255, 22,114,229, 63,193, 96, 20,192,253,167,162, 64,234, 38,163,205, 12,111, 3,255,208, 76, 67, 64,
+ 62,120,111,192, 14, 89, 85, 64,176, 66, 60,174,116, 72, 3,255,139,220, 37, 64,245,135,141,192,114,173, 54, 64,211, 56,161,159,
+ 45, 62, 3,255,204,119, 84, 64, 93, 73,130,192,212,107, 38, 64,198, 72, 33,167,119, 56, 3,255,178,218, 82,192,178,247, 1,191,
+211,129,154, 64,221,183,252,244, 39,105, 3,255, 0,245,124,192, 27, 32,187,190, 57, 6,138, 64,118,169, 80,248,254, 93, 3,255,
+ 42, 75,112,192,228, 42,152,191, 25, 44,139, 64, 0,174, 97,230,225, 94, 3,255,239,222, 43,192,212,226, 11,192,227, 71,151, 64,
+223,197,116,208,165,103, 3,255,137,207,229,191, 30, 63, 22,192,207,235,161, 64, 58,216, 29,205,129,110, 3,255,239, 11, 14,192,
+175,114,191,191,254,208,166, 64,123,207,175,222,169,113, 3,255,163, 78,149,189, 65, 25,137,191,234,102,184, 64,202,254,204,232,
+222,125, 3,255,208,203,104,191,146, 6,113,191,108, 5,183, 64,124,236,106,235,207,124, 3,255, 26, 68,251,190,111, 38,228,191,
+114, 48,178, 64,117,245, 98,217,147,121, 3,255, 76,169,222,191,205,107,104,192,150,142,136, 64,233,217,151,176,223, 92, 3,255,
+145,143, 39,192,190, 49, 94,192,165, 27,124, 64, 18,199, 4,180,213, 85, 3,255,130,168, 6,192,190,132,130,192, 12, 96,105, 64,
+ 30,210,165,166, 83, 79, 3,255, 68, 65, 84, 65, 44, 1, 0, 0, 72,194,152, 2, 21, 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, 40,112,155, 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, 68, 65, 84, 65, 0, 90, 0, 0, 40,112,155, 2, 54, 0, 0, 0,128, 7, 0, 0, 0, 0, 0, 0,
+162, 0, 0, 0, 0, 0, 35, 0, 42, 0, 0, 0,162, 0, 0, 0, 0, 0, 35, 0, 12, 0, 0, 0,163, 0, 0, 0, 0, 0, 35, 0,
+ 42, 0, 0, 0,163, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0,164, 0, 0, 0, 0, 0, 35, 0, 43, 0, 0, 0,164, 0, 0, 0,
+ 0, 0, 35, 0, 12, 0, 0, 0,165, 0, 0, 0, 0, 0, 35, 0, 43, 0, 0, 0,165, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+166, 0, 0, 0, 0, 0, 35, 0, 44, 0, 0, 0,166, 0, 0, 0, 0, 0, 35, 0, 13, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0,
+ 44, 0, 0, 0,167, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,168, 0, 0, 0, 0, 0, 35, 0, 45, 0, 0, 0,168, 0, 0, 0,
+ 0, 0, 35, 0, 13, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0, 45, 0, 0, 0,169, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0,
+170, 0, 0, 0, 0, 0, 35, 0, 46, 0, 0, 0,170, 0, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0,171, 0, 0, 0, 0, 0, 35, 0,
+ 46, 0, 0, 0,171, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,172, 0, 0, 0, 0, 0, 35, 0, 47, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 35, 0, 14, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0, 47, 0, 0, 0,173, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+174, 0, 0, 0, 0, 0, 35, 0, 48, 0, 0, 0,174, 0, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0,175, 0, 0, 0, 0, 0, 35, 0,
+ 48, 0, 0, 0,175, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,176, 0, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,176, 0, 0, 0,
+ 0, 0, 35, 0, 15, 0, 0, 0,177, 0, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,177, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0,
+178, 0, 0, 0, 0, 0, 35, 0, 50, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0, 16, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0,
+ 50, 0, 0, 0,179, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,180, 0, 0, 0, 0, 0, 35, 0, 51, 0, 0, 0,180, 0, 0, 0,
+ 0, 0, 35, 0, 16, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0, 51, 0, 0, 0,181, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+182, 0, 0, 0, 0, 0, 35, 0, 52, 0, 0, 0,182, 0, 0, 0, 0, 0, 35, 0, 17, 0, 0, 0,183, 0, 0, 0, 0, 0, 35, 0,
+ 52, 0, 0, 0,183, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,184, 0, 0, 0, 0, 0, 35, 0, 53, 0, 0, 0,184, 0, 0, 0,
+ 0, 0, 35, 0, 17, 0, 0, 0,185, 0, 0, 0, 0, 0, 35, 0, 53, 0, 0, 0,185, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,
+186, 0, 0, 0, 0, 0, 35, 0, 54, 0, 0, 0,186, 0, 0, 0, 0, 0, 35, 0, 18, 0, 0, 0,187, 0, 0, 0, 0, 0, 35, 0,
+ 54, 0, 0, 0,187, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,188, 0, 0, 0, 0, 0, 35, 0, 55, 0, 0, 0,188, 0, 0, 0,
+ 0, 0, 35, 0, 18, 0, 0, 0,189, 0, 0, 0, 0, 0, 35, 0, 55, 0, 0, 0,189, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+190, 0, 0, 0, 0, 0, 35, 0, 56, 0, 0, 0,190, 0, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0,191, 0, 0, 0, 0, 0, 35, 0,
+ 56, 0, 0, 0,191, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0,192, 0, 0, 0, 0, 0, 35, 0, 57, 0, 0, 0,192, 0, 0, 0,
+ 0, 0, 35, 0, 19, 0, 0, 0,193, 0, 0, 0, 0, 0, 35, 0, 57, 0, 0, 0,193, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,
+194, 0, 0, 0, 0, 0, 35, 0, 58, 0, 0, 0,194, 0, 0, 0, 0, 0, 35, 0, 20, 0, 0, 0,195, 0, 0, 0, 0, 0, 35, 0,
+ 58, 0, 0, 0,195, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0,196, 0, 0, 0, 0, 0, 35, 0, 59, 0, 0, 0,196, 0, 0, 0,
+ 0, 0, 35, 0, 20, 0, 0, 0,197, 0, 0, 0, 0, 0, 35, 0, 59, 0, 0, 0,197, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0,
+198, 0, 0, 0, 0, 0, 35, 0, 60, 0, 0, 0,198, 0, 0, 0, 0, 0, 35, 0, 21, 0, 0, 0,199, 0, 0, 0, 0, 0, 35, 0,
+ 60, 0, 0, 0,199, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,200, 0, 0, 0, 0, 0, 35, 0, 61, 0, 0, 0,200, 0, 0, 0,
+ 0, 0, 35, 0, 21, 0, 0, 0,201, 0, 0, 0, 0, 0, 35, 0, 61, 0, 0, 0,201, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,
+202, 0, 0, 0, 0, 0, 35, 0, 62, 0, 0, 0,202, 0, 0, 0, 0, 0, 35, 0, 22, 0, 0, 0,203, 0, 0, 0, 0, 0, 35, 0,
+ 62, 0, 0, 0,203, 0, 0, 0, 0, 0, 35, 0, 10, 0, 0, 0,204, 0, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0,204, 0, 0, 0,
+ 0, 0, 35, 0, 22, 0, 0, 0,205, 0, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0,205, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0,
+206, 0, 0, 0, 0, 0, 35, 0, 64, 0, 0, 0,206, 0, 0, 0, 0, 0, 35, 0, 23, 0, 0, 0,207, 0, 0, 0, 0, 0, 35, 0,
+ 64, 0, 0, 0,207, 0, 0, 0, 0, 0, 35, 0, 10, 0, 0, 0,208, 0, 0, 0, 0, 0, 35, 0, 65, 0, 0, 0,208, 0, 0, 0,
+ 0, 0, 35, 0, 23, 0, 0, 0,209, 0, 0, 0, 0, 0, 35, 0, 65, 0, 0, 0,209, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0,
+210, 0, 0, 0, 0, 0, 35, 0, 66, 0, 0, 0,210, 0, 0, 0, 0, 0, 35, 0, 24, 0, 0, 0,211, 0, 0, 0, 0, 0, 35, 0,
+ 66, 0, 0, 0,211, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,212, 0, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0,212, 0, 0, 0,
+ 0, 0, 35, 0, 24, 0, 0, 0,213, 0, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0,213, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,
+214, 0, 0, 0, 0, 0, 35, 0, 68, 0, 0, 0,214, 0, 0, 0, 0, 0, 35, 0, 25, 0, 0, 0,215, 0, 0, 0, 0, 0, 35, 0,
+ 68, 0, 0, 0,215, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,216, 0, 0, 0, 0, 0, 35, 0, 69, 0, 0, 0,216, 0, 0, 0,
+ 0, 0, 35, 0, 25, 0, 0, 0,217, 0, 0, 0, 0, 0, 35, 0, 69, 0, 0, 0,217, 0, 0, 0, 0, 0, 35, 0, 2, 0, 0, 0,
+218, 0, 0, 0, 0, 0, 35, 0, 70, 0, 0, 0,218, 0, 0, 0, 0, 0, 35, 0, 26, 0, 0, 0,219, 0, 0, 0, 0, 0, 35, 0,
+ 70, 0, 0, 0,219, 0, 0, 0, 0, 0, 35, 0, 7, 0, 0, 0,220, 0, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0,220, 0, 0, 0,
+ 0, 0, 35, 0, 26, 0, 0, 0,221, 0, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0,221, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,
+222, 0, 0, 0, 0, 0, 35, 0, 72, 0, 0, 0,222, 0, 0, 0, 0, 0, 35, 0, 27, 0, 0, 0,223, 0, 0, 0, 0, 0, 35, 0,
+ 72, 0, 0, 0,223, 0, 0, 0, 0, 0, 35, 0, 7, 0, 0, 0,224, 0, 0, 0, 0, 0, 35, 0, 73, 0, 0, 0,224, 0, 0, 0,
+ 0, 0, 35, 0, 27, 0, 0, 0,225, 0, 0, 0, 0, 0, 35, 0, 73, 0, 0, 0,225, 0, 0, 0, 0, 0, 35, 0, 3, 0, 0, 0,
+226, 0, 0, 0, 0, 0, 35, 0, 74, 0, 0, 0,226, 0, 0, 0, 0, 0, 35, 0, 28, 0, 0, 0,227, 0, 0, 0, 0, 0, 35, 0,
+ 74, 0, 0, 0,227, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0,228, 0, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0,228, 0, 0, 0,
+ 0, 0, 35, 0, 28, 0, 0, 0,229, 0, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0,229, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0,
+230, 0, 0, 0, 0, 0, 35, 0, 76, 0, 0, 0,230, 0, 0, 0, 0, 0, 35, 0, 29, 0, 0, 0,231, 0, 0, 0, 0, 0, 35, 0,
+ 76, 0, 0, 0,231, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0,232, 0, 0, 0, 0, 0, 35, 0, 77, 0, 0, 0,232, 0, 0, 0,
+ 0, 0, 35, 0, 29, 0, 0, 0,233, 0, 0, 0, 0, 0, 35, 0, 77, 0, 0, 0,233, 0, 0, 0, 0, 0, 35, 0, 4, 0, 0, 0,
+234, 0, 0, 0, 0, 0, 35, 0, 78, 0, 0, 0,234, 0, 0, 0, 0, 0, 35, 0, 30, 0, 0, 0,235, 0, 0, 0, 0, 0, 35, 0,
+ 78, 0, 0, 0,235, 0, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0,236, 0, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0,236, 0, 0, 0,
+ 0, 0, 35, 0, 30, 0, 0, 0,237, 0, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0,237, 0, 0, 0, 0, 0, 35, 0, 5, 0, 0, 0,
+238, 0, 0, 0, 0, 0, 35, 0, 80, 0, 0, 0,238, 0, 0, 0, 0, 0, 35, 0, 31, 0, 0, 0,239, 0, 0, 0, 0, 0, 35, 0,
+ 80, 0, 0, 0,239, 0, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0,240, 0, 0, 0, 0, 0, 35, 0, 81, 0, 0, 0,240, 0, 0, 0,
+ 0, 0, 35, 0, 31, 0, 0, 0,241, 0, 0, 0, 0, 0, 35, 0, 81, 0, 0, 0,241, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,
+242, 0, 0, 0, 0, 0, 35, 0, 82, 0, 0, 0,242, 0, 0, 0, 0, 0, 35, 0, 32, 0, 0, 0,243, 0, 0, 0, 0, 0, 35, 0,
+ 82, 0, 0, 0,243, 0, 0, 0, 0, 0, 35, 0, 10, 0, 0, 0,244, 0, 0, 0, 0, 0, 35, 0, 83, 0, 0, 0,244, 0, 0, 0,
+ 0, 0, 35, 0, 32, 0, 0, 0,245, 0, 0, 0, 0, 0, 35, 0, 83, 0, 0, 0,245, 0, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,
+246, 0, 0, 0, 0, 0, 35, 0, 84, 0, 0, 0,246, 0, 0, 0, 0, 0, 35, 0, 33, 0, 0, 0,247, 0, 0, 0, 0, 0, 35, 0,
+ 84, 0, 0, 0,247, 0, 0, 0, 0, 0, 35, 0, 7, 0, 0, 0,248, 0, 0, 0, 0, 0, 35, 0, 85, 0, 0, 0,248, 0, 0, 0,
+ 0, 0, 35, 0, 33, 0, 0, 0,249, 0, 0, 0, 0, 0, 35, 0, 85, 0, 0, 0,249, 0, 0, 0, 0, 0, 35, 0, 7, 0, 0, 0,
+250, 0, 0, 0, 0, 0, 35, 0, 86, 0, 0, 0,250, 0, 0, 0, 0, 0, 35, 0, 34, 0, 0, 0,251, 0, 0, 0, 0, 0, 35, 0,
+ 86, 0, 0, 0,251, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0,252, 0, 0, 0, 0, 0, 35, 0, 87, 0, 0, 0,252, 0, 0, 0,
+ 0, 0, 35, 0, 34, 0, 0, 0,253, 0, 0, 0, 0, 0, 35, 0, 87, 0, 0, 0,253, 0, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0,
+254, 0, 0, 0, 0, 0, 35, 0, 88, 0, 0, 0,254, 0, 0, 0, 0, 0, 35, 0, 35, 0, 0, 0,255, 0, 0, 0, 0, 0, 35, 0,
+ 88, 0, 0, 0,255, 0, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0, 0, 1, 0, 0, 0, 0, 35, 0, 89, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 35, 0, 35, 0, 0, 0, 1, 1, 0, 0, 0, 0, 35, 0, 89, 0, 0, 0, 1, 1, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0,
+ 2, 1, 0, 0, 0, 0, 35, 0, 90, 0, 0, 0, 2, 1, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 3, 1, 0, 0, 0, 0, 35, 0,
+ 90, 0, 0, 0, 3, 1, 0, 0, 0, 0, 35, 0, 10, 0, 0, 0, 4, 1, 0, 0, 0, 0, 35, 0, 91, 0, 0, 0, 4, 1, 0, 0,
+ 0, 0, 35, 0, 36, 0, 0, 0, 5, 1, 0, 0, 0, 0, 35, 0, 91, 0, 0, 0, 5, 1, 0, 0, 0, 0, 35, 0, 10, 0, 0, 0,
+ 6, 1, 0, 0, 0, 0, 35, 0, 92, 0, 0, 0, 6, 1, 0, 0, 0, 0, 35, 0, 37, 0, 0, 0, 7, 1, 0, 0, 0, 0, 35, 0,
+ 92, 0, 0, 0, 7, 1, 0, 0, 0, 0, 35, 0, 11, 0, 0, 0, 8, 1, 0, 0, 0, 0, 35, 0, 93, 0, 0, 0, 8, 1, 0, 0,
+ 0, 0, 35, 0, 37, 0, 0, 0, 9, 1, 0, 0, 0, 0, 35, 0, 93, 0, 0, 0, 9, 1, 0, 0, 0, 0, 35, 0, 6, 0, 0, 0,
+ 10, 1, 0, 0, 0, 0, 35, 0, 94, 0, 0, 0, 10, 1, 0, 0, 0, 0, 35, 0, 38, 0, 0, 0, 11, 1, 0, 0, 0, 0, 35, 0,
+ 94, 0, 0, 0, 11, 1, 0, 0, 0, 0, 35, 0, 11, 0, 0, 0, 12, 1, 0, 0, 0, 0, 35, 0, 95, 0, 0, 0, 12, 1, 0, 0,
+ 0, 0, 35, 0, 38, 0, 0, 0, 13, 1, 0, 0, 0, 0, 35, 0, 95, 0, 0, 0, 13, 1, 0, 0, 0, 0, 35, 0, 7, 0, 0, 0,
+ 14, 1, 0, 0, 0, 0, 35, 0, 96, 0, 0, 0, 14, 1, 0, 0, 0, 0, 35, 0, 39, 0, 0, 0, 15, 1, 0, 0, 0, 0, 35, 0,
+ 96, 0, 0, 0, 15, 1, 0, 0, 0, 0, 35, 0, 11, 0, 0, 0, 16, 1, 0, 0, 0, 0, 35, 0, 97, 0, 0, 0, 16, 1, 0, 0,
+ 0, 0, 35, 0, 39, 0, 0, 0, 17, 1, 0, 0, 0, 0, 35, 0, 97, 0, 0, 0, 17, 1, 0, 0, 0, 0, 35, 0, 8, 0, 0, 0,
+ 18, 1, 0, 0, 0, 0, 35, 0, 98, 0, 0, 0, 18, 1, 0, 0, 0, 0, 35, 0, 40, 0, 0, 0, 19, 1, 0, 0, 0, 0, 35, 0,
+ 98, 0, 0, 0, 19, 1, 0, 0, 0, 0, 35, 0, 11, 0, 0, 0, 20, 1, 0, 0, 0, 0, 35, 0, 99, 0, 0, 0, 20, 1, 0, 0,
+ 0, 0, 35, 0, 40, 0, 0, 0, 21, 1, 0, 0, 0, 0, 35, 0, 99, 0, 0, 0, 21, 1, 0, 0, 0, 0, 35, 0, 9, 0, 0, 0,
+ 22, 1, 0, 0, 0, 0, 35, 0,100, 0, 0, 0, 22, 1, 0, 0, 0, 0, 35, 0, 41, 0, 0, 0, 23, 1, 0, 0, 0, 0, 35, 0,
+100, 0, 0, 0, 23, 1, 0, 0, 0, 0, 35, 0, 11, 0, 0, 0, 24, 1, 0, 0, 0, 0, 35, 0,101, 0, 0, 0, 24, 1, 0, 0,
+ 0, 0, 35, 0, 41, 0, 0, 0, 25, 1, 0, 0, 0, 0, 35, 0,101, 0, 0, 0, 25, 1, 0, 0, 0, 0, 35, 0, 12, 0, 0, 0,
+ 26, 1, 0, 0, 0, 0, 35, 0,102, 0, 0, 0, 26, 1, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0, 27, 1, 0, 0, 0, 0, 35, 0,
+102, 0, 0, 0, 27, 1, 0, 0, 0, 0, 35, 0, 12, 0, 0, 0, 28, 1, 0, 0, 0, 0, 35, 0,103, 0, 0, 0, 28, 1, 0, 0,
+ 0, 0, 35, 0, 13, 0, 0, 0, 29, 1, 0, 0, 0, 0, 35, 0,103, 0, 0, 0, 29, 1, 0, 0, 0, 0, 35, 0, 13, 0, 0, 0,
+ 30, 1, 0, 0, 0, 0, 35, 0,104, 0, 0, 0, 30, 1, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0, 31, 1, 0, 0, 0, 0, 35, 0,
+104, 0, 0, 0, 31, 1, 0, 0, 0, 0, 35, 0, 12, 0, 0, 0, 32, 1, 0, 0, 0, 0, 35, 0,105, 0, 0, 0, 32, 1, 0, 0,
+ 0, 0, 35, 0, 16, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 0,105, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 0, 12, 0, 0, 0,
+ 34, 1, 0, 0, 0, 0, 35, 0,106, 0, 0, 0, 34, 1, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0, 35, 1, 0, 0, 0, 0, 35, 0,
+106, 0, 0, 0, 35, 1, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0, 36, 1, 0, 0, 0, 0, 35, 0,107, 0, 0, 0, 36, 1, 0, 0,
+ 0, 0, 35, 0, 16, 0, 0, 0, 37, 1, 0, 0, 0, 0, 35, 0,107, 0, 0, 0, 37, 1, 0, 0, 0, 0, 35, 0, 13, 0, 0, 0,
+ 38, 1, 0, 0, 0, 0, 35, 0,108, 0, 0, 0, 38, 1, 0, 0, 0, 0, 35, 0, 18, 0, 0, 0, 39, 1, 0, 0, 0, 0, 35, 0,
+108, 0, 0, 0, 39, 1, 0, 0, 0, 0, 35, 0, 13, 0, 0, 0, 40, 1, 0, 0, 0, 0, 35, 0,109, 0, 0, 0, 40, 1, 0, 0,
+ 0, 0, 35, 0, 17, 0, 0, 0, 41, 1, 0, 0, 0, 0, 35, 0,109, 0, 0, 0, 41, 1, 0, 0, 0, 0, 35, 0, 17, 0, 0, 0,
+ 42, 1, 0, 0, 0, 0, 35, 0,110, 0, 0, 0, 42, 1, 0, 0, 0, 0, 35, 0, 18, 0, 0, 0, 43, 1, 0, 0, 0, 0, 35, 0,
+110, 0, 0, 0, 43, 1, 0, 0, 0, 0, 35, 0, 17, 0, 0, 0, 44, 1, 0, 0, 0, 0, 35, 0,111, 0, 0, 0, 44, 1, 0, 0,
+ 0, 0, 35, 0, 20, 0, 0, 0, 45, 1, 0, 0, 0, 0, 35, 0,111, 0, 0, 0, 45, 1, 0, 0, 0, 0, 35, 0, 17, 0, 0, 0,
+ 46, 1, 0, 0, 0, 0, 35, 0,112, 0, 0, 0, 46, 1, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0, 47, 1, 0, 0, 0, 0, 35, 0,
+112, 0, 0, 0, 47, 1, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0, 48, 1, 0, 0, 0, 0, 35, 0,113, 0, 0, 0, 48, 1, 0, 0,
+ 0, 0, 35, 0, 20, 0, 0, 0, 49, 1, 0, 0, 0, 0, 35, 0,113, 0, 0, 0, 49, 1, 0, 0, 0, 0, 35, 0, 19, 0, 0, 0,
+ 50, 1, 0, 0, 0, 0, 35, 0,114, 0, 0, 0, 50, 1, 0, 0, 0, 0, 35, 0, 21, 0, 0, 0, 51, 1, 0, 0, 0, 0, 35, 0,
+114, 0, 0, 0, 51, 1, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0, 52, 1, 0, 0, 0, 0, 35, 0,115, 0, 0, 0, 52, 1, 0, 0,
+ 0, 0, 35, 0, 19, 0, 0, 0, 53, 1, 0, 0, 0, 0, 35, 0,115, 0, 0, 0, 53, 1, 0, 0, 0, 0, 35, 0, 15, 0, 0, 0,
+ 54, 1, 0, 0, 0, 0, 35, 0,116, 0, 0, 0, 54, 1, 0, 0, 0, 0, 35, 0, 21, 0, 0, 0, 55, 1, 0, 0, 0, 0, 35, 0,
+116, 0, 0, 0, 55, 1, 0, 0, 0, 0, 35, 0, 16, 0, 0, 0, 56, 1, 0, 0, 0, 0, 35, 0,117, 0, 0, 0, 56, 1, 0, 0,
+ 0, 0, 35, 0, 23, 0, 0, 0, 57, 1, 0, 0, 0, 0, 35, 0,117, 0, 0, 0, 57, 1, 0, 0, 0, 0, 35, 0, 16, 0, 0, 0,
+ 58, 1, 0, 0, 0, 0, 35, 0,118, 0, 0, 0, 58, 1, 0, 0, 0, 0, 35, 0, 22, 0, 0, 0, 59, 1, 0, 0, 0, 0, 35, 0,
+118, 0, 0, 0, 59, 1, 0, 0, 0, 0, 35, 0, 22, 0, 0, 0, 60, 1, 0, 0, 0, 0, 35, 0,119, 0, 0, 0, 60, 1, 0, 0,
+ 0, 0, 35, 0, 23, 0, 0, 0, 61, 1, 0, 0, 0, 0, 35, 0,119, 0, 0, 0, 61, 1, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0,
+ 62, 1, 0, 0, 0, 0, 35, 0,120, 0, 0, 0, 62, 1, 0, 0, 0, 0, 35, 0, 25, 0, 0, 0, 63, 1, 0, 0, 0, 0, 35, 0,
+120, 0, 0, 0, 63, 1, 0, 0, 0, 0, 35, 0, 14, 0, 0, 0, 64, 1, 0, 0, 0, 0, 35, 0,121, 0, 0, 0, 64, 1, 0, 0,
+ 0, 0, 35, 0, 24, 0, 0, 0, 65, 1, 0, 0, 0, 0, 35, 0,121, 0, 0, 0, 65, 1, 0, 0, 0, 0, 35, 0, 24, 0, 0, 0,
+ 66, 1, 0, 0, 0, 0, 35, 0,122, 0, 0, 0, 66, 1, 0, 0, 0, 0, 35, 0, 25, 0, 0, 0, 67, 1, 0, 0, 0, 0, 35, 0,
+122, 0, 0, 0, 67, 1, 0, 0, 0, 0, 35, 0, 18, 0, 0, 0, 68, 1, 0, 0, 0, 0, 35, 0,123, 0, 0, 0, 68, 1, 0, 0,
+ 0, 0, 35, 0, 27, 0, 0, 0, 69, 1, 0, 0, 0, 0, 35, 0,123, 0, 0, 0, 69, 1, 0, 0, 0, 0, 35, 0, 18, 0, 0, 0,
+ 70, 1, 0, 0, 0, 0, 35, 0,124, 0, 0, 0, 70, 1, 0, 0, 0, 0, 35, 0, 26, 0, 0, 0, 71, 1, 0, 0, 0, 0, 35, 0,
+124, 0, 0, 0, 71, 1, 0, 0, 0, 0, 35, 0, 26, 0, 0, 0, 72, 1, 0, 0, 0, 0, 35, 0,125, 0, 0, 0, 72, 1, 0, 0,
+ 0, 0, 35, 0, 27, 0, 0, 0, 73, 1, 0, 0, 0, 0, 35, 0,125, 0, 0, 0, 73, 1, 0, 0, 0, 0, 35, 0, 20, 0, 0, 0,
+ 74, 1, 0, 0, 0, 0, 35, 0,126, 0, 0, 0, 74, 1, 0, 0, 0, 0, 35, 0, 29, 0, 0, 0, 75, 1, 0, 0, 0, 0, 35, 0,
+126, 0, 0, 0, 75, 1, 0, 0, 0, 0, 35, 0, 20, 0, 0, 0, 76, 1, 0, 0, 0, 0, 35, 0,127, 0, 0, 0, 76, 1, 0, 0,
+ 0, 0, 35, 0, 28, 0, 0, 0, 77, 1, 0, 0, 0, 0, 35, 0,127, 0, 0, 0, 77, 1, 0, 0, 0, 0, 35, 0, 28, 0, 0, 0,
+ 78, 1, 0, 0, 0, 0, 35, 0,128, 0, 0, 0, 78, 1, 0, 0, 0, 0, 35, 0, 29, 0, 0, 0, 79, 1, 0, 0, 0, 0, 35, 0,
+128, 0, 0, 0, 79, 1, 0, 0, 0, 0, 35, 0, 21, 0, 0, 0, 80, 1, 0, 0, 0, 0, 35, 0,129, 0, 0, 0, 80, 1, 0, 0,
+ 0, 0, 35, 0, 31, 0, 0, 0, 81, 1, 0, 0, 0, 0, 35, 0,129, 0, 0, 0, 81, 1, 0, 0, 0, 0, 35, 0, 21, 0, 0, 0,
+ 82, 1, 0, 0, 0, 0, 35, 0,130, 0, 0, 0, 82, 1, 0, 0, 0, 0, 35, 0, 30, 0, 0, 0, 83, 1, 0, 0, 0, 0, 35, 0,
+130, 0, 0, 0, 83, 1, 0, 0, 0, 0, 35, 0, 30, 0, 0, 0, 84, 1, 0, 0, 0, 0, 35, 0,131, 0, 0, 0, 84, 1, 0, 0,
+ 0, 0, 35, 0, 31, 0, 0, 0, 85, 1, 0, 0, 0, 0, 35, 0,131, 0, 0, 0, 85, 1, 0, 0, 0, 0, 35, 0, 23, 0, 0, 0,
+ 86, 1, 0, 0, 0, 0, 35, 0,132, 0, 0, 0, 86, 1, 0, 0, 0, 0, 35, 0, 32, 0, 0, 0, 87, 1, 0, 0, 0, 0, 35, 0,
+132, 0, 0, 0, 87, 1, 0, 0, 0, 0, 35, 0, 23, 0, 0, 0, 88, 1, 0, 0, 0, 0, 35, 0,133, 0, 0, 0, 88, 1, 0, 0,
+ 0, 0, 35, 0, 24, 0, 0, 0, 89, 1, 0, 0, 0, 0, 35, 0,133, 0, 0, 0, 89, 1, 0, 0, 0, 0, 35, 0, 24, 0, 0, 0,
+ 90, 1, 0, 0, 0, 0, 35, 0,134, 0, 0, 0, 90, 1, 0, 0, 0, 0, 35, 0, 32, 0, 0, 0, 91, 1, 0, 0, 0, 0, 35, 0,
+134, 0, 0, 0, 91, 1, 0, 0, 0, 0, 35, 0, 25, 0, 0, 0, 92, 1, 0, 0, 0, 0, 35, 0,135, 0, 0, 0, 92, 1, 0, 0,
+ 0, 0, 35, 0, 33, 0, 0, 0, 93, 1, 0, 0, 0, 0, 35, 0,135, 0, 0, 0, 93, 1, 0, 0, 0, 0, 35, 0, 25, 0, 0, 0,
+ 94, 1, 0, 0, 0, 0, 35, 0,136, 0, 0, 0, 94, 1, 0, 0, 0, 0, 35, 0, 26, 0, 0, 0, 95, 1, 0, 0, 0, 0, 35, 0,
+136, 0, 0, 0, 95, 1, 0, 0, 0, 0, 35, 0, 26, 0, 0, 0, 96, 1, 0, 0, 0, 0, 35, 0,137, 0, 0, 0, 96, 1, 0, 0,
+ 0, 0, 35, 0, 33, 0, 0, 0, 97, 1, 0, 0, 0, 0, 35, 0,137, 0, 0, 0, 97, 1, 0, 0, 0, 0, 35, 0, 27, 0, 0, 0,
+ 98, 1, 0, 0, 0, 0, 35, 0,138, 0, 0, 0, 98, 1, 0, 0, 0, 0, 35, 0, 34, 0, 0, 0, 99, 1, 0, 0, 0, 0, 35, 0,
+138, 0, 0, 0, 99, 1, 0, 0, 0, 0, 35, 0, 27, 0, 0, 0,100, 1, 0, 0, 0, 0, 35, 0,139, 0, 0, 0,100, 1, 0, 0,
+ 0, 0, 35, 0, 28, 0, 0, 0,101, 1, 0, 0, 0, 0, 35, 0,139, 0, 0, 0,101, 1, 0, 0, 0, 0, 35, 0, 28, 0, 0, 0,
+102, 1, 0, 0, 0, 0, 35, 0,140, 0, 0, 0,102, 1, 0, 0, 0, 0, 35, 0, 34, 0, 0, 0,103, 1, 0, 0, 0, 0, 35, 0,
+140, 0, 0, 0,103, 1, 0, 0, 0, 0, 35, 0, 29, 0, 0, 0,104, 1, 0, 0, 0, 0, 35, 0,141, 0, 0, 0,104, 1, 0, 0,
+ 0, 0, 35, 0, 35, 0, 0, 0,105, 1, 0, 0, 0, 0, 35, 0,141, 0, 0, 0,105, 1, 0, 0, 0, 0, 35, 0, 29, 0, 0, 0,
+106, 1, 0, 0, 0, 0, 35, 0,142, 0, 0, 0,106, 1, 0, 0, 0, 0, 35, 0, 30, 0, 0, 0,107, 1, 0, 0, 0, 0, 35, 0,
+142, 0, 0, 0,107, 1, 0, 0, 0, 0, 35, 0, 30, 0, 0, 0,108, 1, 0, 0, 0, 0, 35, 0,143, 0, 0, 0,108, 1, 0, 0,
+ 0, 0, 35, 0, 35, 0, 0, 0,109, 1, 0, 0, 0, 0, 35, 0,143, 0, 0, 0,109, 1, 0, 0, 0, 0, 35, 0, 31, 0, 0, 0,
+110, 1, 0, 0, 0, 0, 35, 0,144, 0, 0, 0,110, 1, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0,111, 1, 0, 0, 0, 0, 35, 0,
+144, 0, 0, 0,111, 1, 0, 0, 0, 0, 35, 0, 22, 0, 0, 0,112, 1, 0, 0, 0, 0, 35, 0,145, 0, 0, 0,112, 1, 0, 0,
+ 0, 0, 35, 0, 31, 0, 0, 0,113, 1, 0, 0, 0, 0, 35, 0,145, 0, 0, 0,113, 1, 0, 0, 0, 0, 35, 0, 22, 0, 0, 0,
+114, 1, 0, 0, 0, 0, 35, 0,146, 0, 0, 0,114, 1, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0,115, 1, 0, 0, 0, 0, 35, 0,
+146, 0, 0, 0,115, 1, 0, 0, 0, 0, 35, 0, 32, 0, 0, 0,116, 1, 0, 0, 0, 0, 35, 0,147, 0, 0, 0,116, 1, 0, 0,
+ 0, 0, 35, 0, 38, 0, 0, 0,117, 1, 0, 0, 0, 0, 35, 0,147, 0, 0, 0,117, 1, 0, 0, 0, 0, 35, 0, 32, 0, 0, 0,
+118, 1, 0, 0, 0, 0, 35, 0,148, 0, 0, 0,118, 1, 0, 0, 0, 0, 35, 0, 37, 0, 0, 0,119, 1, 0, 0, 0, 0, 35, 0,
+148, 0, 0, 0,119, 1, 0, 0, 0, 0, 35, 0, 37, 0, 0, 0,120, 1, 0, 0, 0, 0, 35, 0,149, 0, 0, 0,120, 1, 0, 0,
+ 0, 0, 35, 0, 38, 0, 0, 0,121, 1, 0, 0, 0, 0, 35, 0,149, 0, 0, 0,121, 1, 0, 0, 0, 0, 35, 0, 33, 0, 0, 0,
+122, 1, 0, 0, 0, 0, 35, 0,150, 0, 0, 0,122, 1, 0, 0, 0, 0, 35, 0, 39, 0, 0, 0,123, 1, 0, 0, 0, 0, 35, 0,
+150, 0, 0, 0,123, 1, 0, 0, 0, 0, 35, 0, 33, 0, 0, 0,124, 1, 0, 0, 0, 0, 35, 0,151, 0, 0, 0,124, 1, 0, 0,
+ 0, 0, 35, 0, 38, 0, 0, 0,125, 1, 0, 0, 0, 0, 35, 0,151, 0, 0, 0,125, 1, 0, 0, 0, 0, 35, 0, 38, 0, 0, 0,
+126, 1, 0, 0, 0, 0, 35, 0,152, 0, 0, 0,126, 1, 0, 0, 0, 0, 35, 0, 39, 0, 0, 0,127, 1, 0, 0, 0, 0, 35, 0,
+152, 0, 0, 0,127, 1, 0, 0, 0, 0, 35, 0, 34, 0, 0, 0,128, 1, 0, 0, 0, 0, 35, 0,153, 0, 0, 0,128, 1, 0, 0,
+ 0, 0, 35, 0, 40, 0, 0, 0,129, 1, 0, 0, 0, 0, 35, 0,153, 0, 0, 0,129, 1, 0, 0, 0, 0, 35, 0, 34, 0, 0, 0,
+130, 1, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,130, 1, 0, 0, 0, 0, 35, 0, 39, 0, 0, 0,131, 1, 0, 0, 0, 0, 35, 0,
+154, 0, 0, 0,131, 1, 0, 0, 0, 0, 35, 0, 39, 0, 0, 0,132, 1, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,132, 1, 0, 0,
+ 0, 0, 35, 0, 40, 0, 0, 0,133, 1, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,133, 1, 0, 0, 0, 0, 35, 0, 35, 0, 0, 0,
+134, 1, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,134, 1, 0, 0, 0, 0, 35, 0, 41, 0, 0, 0,135, 1, 0, 0, 0, 0, 35, 0,
+156, 0, 0, 0,135, 1, 0, 0, 0, 0, 35, 0, 35, 0, 0, 0,136, 1, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,136, 1, 0, 0,
+ 0, 0, 35, 0, 40, 0, 0, 0,137, 1, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,137, 1, 0, 0, 0, 0, 35, 0, 40, 0, 0, 0,
+138, 1, 0, 0, 0, 0, 35, 0,158, 0, 0, 0,138, 1, 0, 0, 0, 0, 35, 0, 41, 0, 0, 0,139, 1, 0, 0, 0, 0, 35, 0,
+158, 0, 0, 0,139, 1, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0,140, 1, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,140, 1, 0, 0,
+ 0, 0, 35, 0, 37, 0, 0, 0,141, 1, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,141, 1, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0,
+142, 1, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,142, 1, 0, 0, 0, 0, 35, 0, 41, 0, 0, 0,143, 1, 0, 0, 0, 0, 35, 0,
+160, 0, 0, 0,143, 1, 0, 0, 0, 0, 35, 0, 37, 0, 0, 0,144, 1, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,144, 1, 0, 0,
+ 0, 0, 35, 0, 41, 0, 0, 0,145, 1, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,145, 1, 0, 0, 0, 0, 35, 0, 46, 0, 0, 0,
+146, 1, 0, 0, 0, 0, 35, 0,102, 0, 0, 0,146, 1, 0, 0, 0, 0, 35, 0, 43, 0, 0, 0,147, 1, 0, 0, 0, 0, 33, 0,
+ 46, 0, 0, 0,147, 1, 0, 0, 0, 0, 33, 0, 43, 0, 0, 0,148, 1, 0, 0, 0, 0, 35, 0,102, 0, 0, 0,148, 1, 0, 0,
+ 0, 0, 35, 0,102, 0, 0, 0,149, 1, 0, 0, 0, 0, 35, 0,103, 0, 0, 0,149, 1, 0, 0, 0, 0, 35, 0,103, 0, 0, 0,
+150, 1, 0, 0, 0, 0, 35, 0,104, 0, 0, 0,150, 1, 0, 0, 0, 0, 35, 0,102, 0, 0, 0,151, 1, 0, 0, 0, 0, 35, 0,
+104, 0, 0, 0,151, 1, 0, 0, 0, 0, 35, 0, 45, 0, 0, 0,152, 1, 0, 0, 0, 0, 33, 0, 47, 0, 0, 0,152, 1, 0, 0,
+ 0, 0, 33, 0, 47, 0, 0, 0,153, 1, 0, 0, 0, 0, 35, 0,104, 0, 0, 0,153, 1, 0, 0, 0, 0, 35, 0, 45, 0, 0, 0,
+154, 1, 0, 0, 0, 0, 35, 0,104, 0, 0, 0,154, 1, 0, 0, 0, 0, 35, 0, 44, 0, 0, 0,155, 1, 0, 0, 0, 0, 35, 0,
+103, 0, 0, 0,155, 1, 0, 0, 0, 0, 35, 0, 42, 0, 0, 0,156, 1, 0, 0, 0, 0, 35, 0,103, 0, 0, 0,156, 1, 0, 0,
+ 0, 0, 35, 0, 42, 0, 0, 0,157, 1, 0, 0, 0, 0, 33, 0, 44, 0, 0, 0,157, 1, 0, 0, 0, 0, 33, 0, 50, 0, 0, 0,
+158, 1, 0, 0, 0, 0, 35, 0,105, 0, 0, 0,158, 1, 0, 0, 0, 0, 35, 0, 43, 0, 0, 0,159, 1, 0, 0, 0, 0, 33, 0,
+ 50, 0, 0, 0,159, 1, 0, 0, 0, 0, 33, 0, 43, 0, 0, 0,160, 1, 0, 0, 0, 0, 35, 0,105, 0, 0, 0,160, 1, 0, 0,
+ 0, 0, 35, 0,105, 0, 0, 0,161, 1, 0, 0, 0, 0, 35, 0,106, 0, 0, 0,161, 1, 0, 0, 0, 0, 35, 0,106, 0, 0, 0,
+162, 1, 0, 0, 0, 0, 35, 0,107, 0, 0, 0,162, 1, 0, 0, 0, 0, 35, 0,105, 0, 0, 0,163, 1, 0, 0, 0, 0, 35, 0,
+107, 0, 0, 0,163, 1, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,164, 1, 0, 0, 0, 0, 33, 0, 51, 0, 0, 0,164, 1, 0, 0,
+ 0, 0, 33, 0, 51, 0, 0, 0,165, 1, 0, 0, 0, 0, 35, 0,107, 0, 0, 0,165, 1, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,
+166, 1, 0, 0, 0, 0, 35, 0,107, 0, 0, 0,166, 1, 0, 0, 0, 0, 35, 0, 48, 0, 0, 0,167, 1, 0, 0, 0, 0, 35, 0,
+106, 0, 0, 0,167, 1, 0, 0, 0, 0, 35, 0, 42, 0, 0, 0,168, 1, 0, 0, 0, 0, 35, 0,106, 0, 0, 0,168, 1, 0, 0,
+ 0, 0, 35, 0, 42, 0, 0, 0,169, 1, 0, 0, 0, 0, 33, 0, 48, 0, 0, 0,169, 1, 0, 0, 0, 0, 33, 0, 54, 0, 0, 0,
+170, 1, 0, 0, 0, 0, 35, 0,108, 0, 0, 0,170, 1, 0, 0, 0, 0, 35, 0, 45, 0, 0, 0,171, 1, 0, 0, 0, 0, 33, 0,
+ 54, 0, 0, 0,171, 1, 0, 0, 0, 0, 33, 0, 45, 0, 0, 0,172, 1, 0, 0, 0, 0, 35, 0,108, 0, 0, 0,172, 1, 0, 0,
+ 0, 0, 35, 0,108, 0, 0, 0,173, 1, 0, 0, 0, 0, 35, 0,109, 0, 0, 0,173, 1, 0, 0, 0, 0, 35, 0,109, 0, 0, 0,
+174, 1, 0, 0, 0, 0, 35, 0,110, 0, 0, 0,174, 1, 0, 0, 0, 0, 35, 0,108, 0, 0, 0,175, 1, 0, 0, 0, 0, 35, 0,
+110, 0, 0, 0,175, 1, 0, 0, 0, 0, 35, 0, 53, 0, 0, 0,176, 1, 0, 0, 0, 0, 33, 0, 55, 0, 0, 0,176, 1, 0, 0,
+ 0, 0, 33, 0, 55, 0, 0, 0,177, 1, 0, 0, 0, 0, 35, 0,110, 0, 0, 0,177, 1, 0, 0, 0, 0, 35, 0, 53, 0, 0, 0,
+178, 1, 0, 0, 0, 0, 35, 0,110, 0, 0, 0,178, 1, 0, 0, 0, 0, 35, 0, 52, 0, 0, 0,179, 1, 0, 0, 0, 0, 35, 0,
+109, 0, 0, 0,179, 1, 0, 0, 0, 0, 35, 0, 44, 0, 0, 0,180, 1, 0, 0, 0, 0, 35, 0,109, 0, 0, 0,180, 1, 0, 0,
+ 0, 0, 35, 0, 44, 0, 0, 0,181, 1, 0, 0, 0, 0, 33, 0, 52, 0, 0, 0,181, 1, 0, 0, 0, 0, 33, 0, 58, 0, 0, 0,
+182, 1, 0, 0, 0, 0, 35, 0,111, 0, 0, 0,182, 1, 0, 0, 0, 0, 35, 0, 53, 0, 0, 0,183, 1, 0, 0, 0, 0, 33, 0,
+ 58, 0, 0, 0,183, 1, 0, 0, 0, 0, 33, 0, 53, 0, 0, 0,184, 1, 0, 0, 0, 0, 35, 0,111, 0, 0, 0,184, 1, 0, 0,
+ 0, 0, 35, 0,111, 0, 0, 0,185, 1, 0, 0, 0, 0, 35, 0,112, 0, 0, 0,185, 1, 0, 0, 0, 0, 35, 0,112, 0, 0, 0,
+186, 1, 0, 0, 0, 0, 35, 0,113, 0, 0, 0,186, 1, 0, 0, 0, 0, 35, 0,111, 0, 0, 0,187, 1, 0, 0, 0, 0, 35, 0,
+113, 0, 0, 0,187, 1, 0, 0, 0, 0, 35, 0, 57, 0, 0, 0,188, 1, 0, 0, 0, 0, 33, 0, 59, 0, 0, 0,188, 1, 0, 0,
+ 0, 0, 33, 0, 59, 0, 0, 0,189, 1, 0, 0, 0, 0, 35, 0,113, 0, 0, 0,189, 1, 0, 0, 0, 0, 35, 0, 57, 0, 0, 0,
+190, 1, 0, 0, 0, 0, 35, 0,113, 0, 0, 0,190, 1, 0, 0, 0, 0, 35, 0, 56, 0, 0, 0,191, 1, 0, 0, 0, 0, 35, 0,
+112, 0, 0, 0,191, 1, 0, 0, 0, 0, 35, 0, 52, 0, 0, 0,192, 1, 0, 0, 0, 0, 35, 0,112, 0, 0, 0,192, 1, 0, 0,
+ 0, 0, 35, 0, 52, 0, 0, 0,193, 1, 0, 0, 0, 0, 33, 0, 56, 0, 0, 0,193, 1, 0, 0, 0, 0, 33, 0, 60, 0, 0, 0,
+194, 1, 0, 0, 0, 0, 35, 0,114, 0, 0, 0,194, 1, 0, 0, 0, 0, 35, 0, 57, 0, 0, 0,195, 1, 0, 0, 0, 0, 33, 0,
+ 60, 0, 0, 0,195, 1, 0, 0, 0, 0, 33, 0, 57, 0, 0, 0,196, 1, 0, 0, 0, 0, 35, 0,114, 0, 0, 0,196, 1, 0, 0,
+ 0, 0, 35, 0,114, 0, 0, 0,197, 1, 0, 0, 0, 0, 35, 0,115, 0, 0, 0,197, 1, 0, 0, 0, 0, 35, 0,115, 0, 0, 0,
+198, 1, 0, 0, 0, 0, 35, 0,116, 0, 0, 0,198, 1, 0, 0, 0, 0, 35, 0,114, 0, 0, 0,199, 1, 0, 0, 0, 0, 35, 0,
+116, 0, 0, 0,199, 1, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,200, 1, 0, 0, 0, 0, 33, 0, 61, 0, 0, 0,200, 1, 0, 0,
+ 0, 0, 33, 0, 61, 0, 0, 0,201, 1, 0, 0, 0, 0, 35, 0,116, 0, 0, 0,201, 1, 0, 0, 0, 0, 35, 0, 49, 0, 0, 0,
+202, 1, 0, 0, 0, 0, 35, 0,116, 0, 0, 0,202, 1, 0, 0, 0, 0, 35, 0, 48, 0, 0, 0,203, 1, 0, 0, 0, 0, 35, 0,
+115, 0, 0, 0,203, 1, 0, 0, 0, 0, 35, 0, 56, 0, 0, 0,204, 1, 0, 0, 0, 0, 35, 0,115, 0, 0, 0,204, 1, 0, 0,
+ 0, 0, 35, 0, 48, 0, 0, 0,205, 1, 0, 0, 0, 0, 33, 0, 56, 0, 0, 0,205, 1, 0, 0, 0, 0, 33, 0, 64, 0, 0, 0,
+206, 1, 0, 0, 0, 0, 35, 0,117, 0, 0, 0,206, 1, 0, 0, 0, 0, 35, 0, 50, 0, 0, 0,207, 1, 0, 0, 0, 0, 33, 0,
+ 64, 0, 0, 0,207, 1, 0, 0, 0, 0, 33, 0, 50, 0, 0, 0,208, 1, 0, 0, 0, 0, 35, 0,117, 0, 0, 0,208, 1, 0, 0,
+ 0, 0, 35, 0,117, 0, 0, 0,209, 1, 0, 0, 0, 0, 35, 0,118, 0, 0, 0,209, 1, 0, 0, 0, 0, 35, 0,118, 0, 0, 0,
+210, 1, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,210, 1, 0, 0, 0, 0, 35, 0,117, 0, 0, 0,211, 1, 0, 0, 0, 0, 35, 0,
+119, 0, 0, 0,211, 1, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0,212, 1, 0, 0, 0, 0, 33, 0, 65, 0, 0, 0,212, 1, 0, 0,
+ 0, 0, 33, 0, 65, 0, 0, 0,213, 1, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,213, 1, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0,
+214, 1, 0, 0, 0, 0, 35, 0,119, 0, 0, 0,214, 1, 0, 0, 0, 0, 35, 0, 62, 0, 0, 0,215, 1, 0, 0, 0, 0, 35, 0,
+118, 0, 0, 0,215, 1, 0, 0, 0, 0, 35, 0, 51, 0, 0, 0,216, 1, 0, 0, 0, 0, 35, 0,118, 0, 0, 0,216, 1, 0, 0,
+ 0, 0, 35, 0, 51, 0, 0, 0,217, 1, 0, 0, 0, 0, 33, 0, 62, 0, 0, 0,217, 1, 0, 0, 0, 0, 33, 0, 68, 0, 0, 0,
+218, 1, 0, 0, 0, 0, 35, 0,120, 0, 0, 0,218, 1, 0, 0, 0, 0, 35, 0, 47, 0, 0, 0,219, 1, 0, 0, 0, 0, 33, 0,
+ 68, 0, 0, 0,219, 1, 0, 0, 0, 0, 33, 0, 47, 0, 0, 0,220, 1, 0, 0, 0, 0, 35, 0,120, 0, 0, 0,220, 1, 0, 0,
+ 0, 0, 35, 0,120, 0, 0, 0,221, 1, 0, 0, 0, 0, 35, 0,121, 0, 0, 0,221, 1, 0, 0, 0, 0, 35, 0,121, 0, 0, 0,
+222, 1, 0, 0, 0, 0, 35, 0,122, 0, 0, 0,222, 1, 0, 0, 0, 0, 35, 0,120, 0, 0, 0,223, 1, 0, 0, 0, 0, 35, 0,
+122, 0, 0, 0,223, 1, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0,224, 1, 0, 0, 0, 0, 33, 0, 69, 0, 0, 0,224, 1, 0, 0,
+ 0, 0, 33, 0, 69, 0, 0, 0,225, 1, 0, 0, 0, 0, 35, 0,122, 0, 0, 0,225, 1, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0,
+226, 1, 0, 0, 0, 0, 35, 0,122, 0, 0, 0,226, 1, 0, 0, 0, 0, 35, 0, 66, 0, 0, 0,227, 1, 0, 0, 0, 0, 35, 0,
+121, 0, 0, 0,227, 1, 0, 0, 0, 0, 35, 0, 46, 0, 0, 0,228, 1, 0, 0, 0, 0, 35, 0,121, 0, 0, 0,228, 1, 0, 0,
+ 0, 0, 35, 0, 46, 0, 0, 0,229, 1, 0, 0, 0, 0, 33, 0, 66, 0, 0, 0,229, 1, 0, 0, 0, 0, 33, 0, 72, 0, 0, 0,
+230, 1, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,230, 1, 0, 0, 0, 0, 35, 0, 55, 0, 0, 0,231, 1, 0, 0, 0, 0, 33, 0,
+ 72, 0, 0, 0,231, 1, 0, 0, 0, 0, 33, 0, 55, 0, 0, 0,232, 1, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,232, 1, 0, 0,
+ 0, 0, 35, 0,123, 0, 0, 0,233, 1, 0, 0, 0, 0, 35, 0,124, 0, 0, 0,233, 1, 0, 0, 0, 0, 35, 0,124, 0, 0, 0,
+234, 1, 0, 0, 0, 0, 35, 0,125, 0, 0, 0,234, 1, 0, 0, 0, 0, 35, 0,123, 0, 0, 0,235, 1, 0, 0, 0, 0, 35, 0,
+125, 0, 0, 0,235, 1, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0,236, 1, 0, 0, 0, 0, 33, 0, 73, 0, 0, 0,236, 1, 0, 0,
+ 0, 0, 33, 0, 73, 0, 0, 0,237, 1, 0, 0, 0, 0, 35, 0,125, 0, 0, 0,237, 1, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0,
+238, 1, 0, 0, 0, 0, 35, 0,125, 0, 0, 0,238, 1, 0, 0, 0, 0, 35, 0, 70, 0, 0, 0,239, 1, 0, 0, 0, 0, 35, 0,
+124, 0, 0, 0,239, 1, 0, 0, 0, 0, 35, 0, 54, 0, 0, 0,240, 1, 0, 0, 0, 0, 35, 0,124, 0, 0, 0,240, 1, 0, 0,
+ 0, 0, 35, 0, 54, 0, 0, 0,241, 1, 0, 0, 0, 0, 33, 0, 70, 0, 0, 0,241, 1, 0, 0, 0, 0, 33, 0, 76, 0, 0, 0,
+242, 1, 0, 0, 0, 0, 35, 0,126, 0, 0, 0,242, 1, 0, 0, 0, 0, 35, 0, 59, 0, 0, 0,243, 1, 0, 0, 0, 0, 33, 0,
+ 76, 0, 0, 0,243, 1, 0, 0, 0, 0, 33, 0, 59, 0, 0, 0,244, 1, 0, 0, 0, 0, 35, 0,126, 0, 0, 0,244, 1, 0, 0,
+ 0, 0, 35, 0,126, 0, 0, 0,245, 1, 0, 0, 0, 0, 35, 0,127, 0, 0, 0,245, 1, 0, 0, 0, 0, 35, 0,127, 0, 0, 0,
+246, 1, 0, 0, 0, 0, 35, 0,128, 0, 0, 0,246, 1, 0, 0, 0, 0, 35, 0,126, 0, 0, 0,247, 1, 0, 0, 0, 0, 35, 0,
+128, 0, 0, 0,247, 1, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0,248, 1, 0, 0, 0, 0, 33, 0, 77, 0, 0, 0,248, 1, 0, 0,
+ 0, 0, 33, 0, 77, 0, 0, 0,249, 1, 0, 0, 0, 0, 35, 0,128, 0, 0, 0,249, 1, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0,
+250, 1, 0, 0, 0, 0, 35, 0,128, 0, 0, 0,250, 1, 0, 0, 0, 0, 35, 0, 74, 0, 0, 0,251, 1, 0, 0, 0, 0, 35, 0,
+127, 0, 0, 0,251, 1, 0, 0, 0, 0, 35, 0, 58, 0, 0, 0,252, 1, 0, 0, 0, 0, 35, 0,127, 0, 0, 0,252, 1, 0, 0,
+ 0, 0, 35, 0, 58, 0, 0, 0,253, 1, 0, 0, 0, 0, 33, 0, 74, 0, 0, 0,253, 1, 0, 0, 0, 0, 33, 0, 80, 0, 0, 0,
+254, 1, 0, 0, 0, 0, 35, 0,129, 0, 0, 0,254, 1, 0, 0, 0, 0, 35, 0, 61, 0, 0, 0,255, 1, 0, 0, 0, 0, 33, 0,
+ 80, 0, 0, 0,255, 1, 0, 0, 0, 0, 33, 0, 61, 0, 0, 0, 0, 2, 0, 0, 0, 0, 35, 0,129, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 35, 0,129, 0, 0, 0, 1, 2, 0, 0, 0, 0, 35, 0,130, 0, 0, 0, 1, 2, 0, 0, 0, 0, 35, 0,130, 0, 0, 0,
+ 2, 2, 0, 0, 0, 0, 35, 0,131, 0, 0, 0, 2, 2, 0, 0, 0, 0, 35, 0,129, 0, 0, 0, 3, 2, 0, 0, 0, 0, 35, 0,
+131, 0, 0, 0, 3, 2, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0, 4, 2, 0, 0, 0, 0, 33, 0, 81, 0, 0, 0, 4, 2, 0, 0,
+ 0, 0, 33, 0, 81, 0, 0, 0, 5, 2, 0, 0, 0, 0, 35, 0,131, 0, 0, 0, 5, 2, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0,
+ 6, 2, 0, 0, 0, 0, 35, 0,131, 0, 0, 0, 6, 2, 0, 0, 0, 0, 35, 0, 78, 0, 0, 0, 7, 2, 0, 0, 0, 0, 35, 0,
+130, 0, 0, 0, 7, 2, 0, 0, 0, 0, 35, 0, 60, 0, 0, 0, 8, 2, 0, 0, 0, 0, 35, 0,130, 0, 0, 0, 8, 2, 0, 0,
+ 0, 0, 35, 0, 60, 0, 0, 0, 9, 2, 0, 0, 0, 0, 33, 0, 78, 0, 0, 0, 9, 2, 0, 0, 0, 0, 33, 0, 83, 0, 0, 0,
+ 10, 2, 0, 0, 0, 0, 35, 0,132, 0, 0, 0, 10, 2, 0, 0, 0, 0, 35, 0, 65, 0, 0, 0, 11, 2, 0, 0, 0, 0, 33, 0,
+ 83, 0, 0, 0, 11, 2, 0, 0, 0, 0, 33, 0, 65, 0, 0, 0, 12, 2, 0, 0, 0, 0, 35, 0,132, 0, 0, 0, 12, 2, 0, 0,
+ 0, 0, 35, 0,132, 0, 0, 0, 13, 2, 0, 0, 0, 0, 35, 0,133, 0, 0, 0, 13, 2, 0, 0, 0, 0, 35, 0,133, 0, 0, 0,
+ 14, 2, 0, 0, 0, 0, 35, 0,134, 0, 0, 0, 14, 2, 0, 0, 0, 0, 35, 0,132, 0, 0, 0, 15, 2, 0, 0, 0, 0, 35, 0,
+134, 0, 0, 0, 15, 2, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0, 16, 2, 0, 0, 0, 0, 33, 0, 82, 0, 0, 0, 16, 2, 0, 0,
+ 0, 0, 33, 0, 82, 0, 0, 0, 17, 2, 0, 0, 0, 0, 35, 0,134, 0, 0, 0, 17, 2, 0, 0, 0, 0, 35, 0, 67, 0, 0, 0,
+ 18, 2, 0, 0, 0, 0, 35, 0,134, 0, 0, 0, 18, 2, 0, 0, 0, 0, 35, 0, 66, 0, 0, 0, 19, 2, 0, 0, 0, 0, 35, 0,
+133, 0, 0, 0, 19, 2, 0, 0, 0, 0, 35, 0, 64, 0, 0, 0, 20, 2, 0, 0, 0, 0, 35, 0,133, 0, 0, 0, 20, 2, 0, 0,
+ 0, 0, 35, 0, 64, 0, 0, 0, 21, 2, 0, 0, 0, 0, 33, 0, 66, 0, 0, 0, 21, 2, 0, 0, 0, 0, 33, 0, 84, 0, 0, 0,
+ 22, 2, 0, 0, 0, 0, 35, 0,135, 0, 0, 0, 22, 2, 0, 0, 0, 0, 35, 0, 69, 0, 0, 0, 23, 2, 0, 0, 0, 0, 33, 0,
+ 84, 0, 0, 0, 23, 2, 0, 0, 0, 0, 33, 0, 69, 0, 0, 0, 24, 2, 0, 0, 0, 0, 35, 0,135, 0, 0, 0, 24, 2, 0, 0,
+ 0, 0, 35, 0,135, 0, 0, 0, 25, 2, 0, 0, 0, 0, 35, 0,136, 0, 0, 0, 25, 2, 0, 0, 0, 0, 35, 0,136, 0, 0, 0,
+ 26, 2, 0, 0, 0, 0, 35, 0,137, 0, 0, 0, 26, 2, 0, 0, 0, 0, 35, 0,135, 0, 0, 0, 27, 2, 0, 0, 0, 0, 35, 0,
+137, 0, 0, 0, 27, 2, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0, 28, 2, 0, 0, 0, 0, 33, 0, 85, 0, 0, 0, 28, 2, 0, 0,
+ 0, 0, 33, 0, 85, 0, 0, 0, 29, 2, 0, 0, 0, 0, 35, 0,137, 0, 0, 0, 29, 2, 0, 0, 0, 0, 35, 0, 71, 0, 0, 0,
+ 30, 2, 0, 0, 0, 0, 35, 0,137, 0, 0, 0, 30, 2, 0, 0, 0, 0, 35, 0, 70, 0, 0, 0, 31, 2, 0, 0, 0, 0, 35, 0,
+136, 0, 0, 0, 31, 2, 0, 0, 0, 0, 35, 0, 68, 0, 0, 0, 32, 2, 0, 0, 0, 0, 35, 0,136, 0, 0, 0, 32, 2, 0, 0,
+ 0, 0, 35, 0, 68, 0, 0, 0, 33, 2, 0, 0, 0, 0, 33, 0, 70, 0, 0, 0, 33, 2, 0, 0, 0, 0, 33, 0, 86, 0, 0, 0,
+ 34, 2, 0, 0, 0, 0, 35, 0,138, 0, 0, 0, 34, 2, 0, 0, 0, 0, 35, 0, 73, 0, 0, 0, 35, 2, 0, 0, 0, 0, 33, 0,
+ 86, 0, 0, 0, 35, 2, 0, 0, 0, 0, 33, 0, 73, 0, 0, 0, 36, 2, 0, 0, 0, 0, 35, 0,138, 0, 0, 0, 36, 2, 0, 0,
+ 0, 0, 35, 0,138, 0, 0, 0, 37, 2, 0, 0, 0, 0, 35, 0,139, 0, 0, 0, 37, 2, 0, 0, 0, 0, 35, 0,139, 0, 0, 0,
+ 38, 2, 0, 0, 0, 0, 35, 0,140, 0, 0, 0, 38, 2, 0, 0, 0, 0, 35, 0,138, 0, 0, 0, 39, 2, 0, 0, 0, 0, 35, 0,
+140, 0, 0, 0, 39, 2, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0, 40, 2, 0, 0, 0, 0, 33, 0, 87, 0, 0, 0, 40, 2, 0, 0,
+ 0, 0, 33, 0, 87, 0, 0, 0, 41, 2, 0, 0, 0, 0, 35, 0,140, 0, 0, 0, 41, 2, 0, 0, 0, 0, 35, 0, 75, 0, 0, 0,
+ 42, 2, 0, 0, 0, 0, 35, 0,140, 0, 0, 0, 42, 2, 0, 0, 0, 0, 35, 0, 74, 0, 0, 0, 43, 2, 0, 0, 0, 0, 35, 0,
+139, 0, 0, 0, 43, 2, 0, 0, 0, 0, 35, 0, 72, 0, 0, 0, 44, 2, 0, 0, 0, 0, 35, 0,139, 0, 0, 0, 44, 2, 0, 0,
+ 0, 0, 35, 0, 72, 0, 0, 0, 45, 2, 0, 0, 0, 0, 33, 0, 74, 0, 0, 0, 45, 2, 0, 0, 0, 0, 33, 0, 88, 0, 0, 0,
+ 46, 2, 0, 0, 0, 0, 35, 0,141, 0, 0, 0, 46, 2, 0, 0, 0, 0, 35, 0, 77, 0, 0, 0, 47, 2, 0, 0, 0, 0, 33, 0,
+ 88, 0, 0, 0, 47, 2, 0, 0, 0, 0, 33, 0, 77, 0, 0, 0, 48, 2, 0, 0, 0, 0, 35, 0,141, 0, 0, 0, 48, 2, 0, 0,
+ 0, 0, 35, 0,141, 0, 0, 0, 49, 2, 0, 0, 0, 0, 35, 0,142, 0, 0, 0, 49, 2, 0, 0, 0, 0, 35, 0,142, 0, 0, 0,
+ 50, 2, 0, 0, 0, 0, 35, 0,143, 0, 0, 0, 50, 2, 0, 0, 0, 0, 35, 0,141, 0, 0, 0, 51, 2, 0, 0, 0, 0, 35, 0,
+143, 0, 0, 0, 51, 2, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0, 52, 2, 0, 0, 0, 0, 33, 0, 89, 0, 0, 0, 52, 2, 0, 0,
+ 0, 0, 33, 0, 89, 0, 0, 0, 53, 2, 0, 0, 0, 0, 35, 0,143, 0, 0, 0, 53, 2, 0, 0, 0, 0, 35, 0, 79, 0, 0, 0,
+ 54, 2, 0, 0, 0, 0, 35, 0,143, 0, 0, 0, 54, 2, 0, 0, 0, 0, 35, 0, 78, 0, 0, 0, 55, 2, 0, 0, 0, 0, 35, 0,
+142, 0, 0, 0, 55, 2, 0, 0, 0, 0, 35, 0, 76, 0, 0, 0, 56, 2, 0, 0, 0, 0, 35, 0,142, 0, 0, 0, 56, 2, 0, 0,
+ 0, 0, 35, 0, 76, 0, 0, 0, 57, 2, 0, 0, 0, 0, 33, 0, 78, 0, 0, 0, 57, 2, 0, 0, 0, 0, 33, 0, 90, 0, 0, 0,
+ 58, 2, 0, 0, 0, 0, 35, 0,144, 0, 0, 0, 58, 2, 0, 0, 0, 0, 35, 0, 81, 0, 0, 0, 59, 2, 0, 0, 0, 0, 33, 0,
+ 90, 0, 0, 0, 59, 2, 0, 0, 0, 0, 33, 0, 81, 0, 0, 0, 60, 2, 0, 0, 0, 0, 35, 0,144, 0, 0, 0, 60, 2, 0, 0,
+ 0, 0, 35, 0,144, 0, 0, 0, 61, 2, 0, 0, 0, 0, 35, 0,145, 0, 0, 0, 61, 2, 0, 0, 0, 0, 35, 0,145, 0, 0, 0,
+ 62, 2, 0, 0, 0, 0, 35, 0,146, 0, 0, 0, 62, 2, 0, 0, 0, 0, 35, 0,144, 0, 0, 0, 63, 2, 0, 0, 0, 0, 35, 0,
+146, 0, 0, 0, 63, 2, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0, 64, 2, 0, 0, 0, 0, 33, 0, 91, 0, 0, 0, 64, 2, 0, 0,
+ 0, 0, 33, 0, 91, 0, 0, 0, 65, 2, 0, 0, 0, 0, 35, 0,146, 0, 0, 0, 65, 2, 0, 0, 0, 0, 35, 0, 63, 0, 0, 0,
+ 66, 2, 0, 0, 0, 0, 35, 0,146, 0, 0, 0, 66, 2, 0, 0, 0, 0, 35, 0, 62, 0, 0, 0, 67, 2, 0, 0, 0, 0, 35, 0,
+145, 0, 0, 0, 67, 2, 0, 0, 0, 0, 35, 0, 80, 0, 0, 0, 68, 2, 0, 0, 0, 0, 35, 0,145, 0, 0, 0, 68, 2, 0, 0,
+ 0, 0, 35, 0, 62, 0, 0, 0, 69, 2, 0, 0, 0, 0, 33, 0, 80, 0, 0, 0, 69, 2, 0, 0, 0, 0, 33, 0, 94, 0, 0, 0,
+ 70, 2, 0, 0, 0, 0, 35, 0,147, 0, 0, 0, 70, 2, 0, 0, 0, 0, 35, 0, 82, 0, 0, 0, 71, 2, 0, 0, 0, 0, 33, 0,
+ 94, 0, 0, 0, 71, 2, 0, 0, 0, 0, 33, 0, 82, 0, 0, 0, 72, 2, 0, 0, 0, 0, 35, 0,147, 0, 0, 0, 72, 2, 0, 0,
+ 0, 0, 35, 0,147, 0, 0, 0, 73, 2, 0, 0, 0, 0, 35, 0,148, 0, 0, 0, 73, 2, 0, 0, 0, 0, 35, 0,148, 0, 0, 0,
+ 74, 2, 0, 0, 0, 0, 35, 0,149, 0, 0, 0, 74, 2, 0, 0, 0, 0, 35, 0,147, 0, 0, 0, 75, 2, 0, 0, 0, 0, 35, 0,
+149, 0, 0, 0, 75, 2, 0, 0, 0, 0, 35, 0, 93, 0, 0, 0, 76, 2, 0, 0, 0, 0, 33, 0, 95, 0, 0, 0, 76, 2, 0, 0,
+ 0, 0, 33, 0, 95, 0, 0, 0, 77, 2, 0, 0, 0, 0, 35, 0,149, 0, 0, 0, 77, 2, 0, 0, 0, 0, 35, 0, 93, 0, 0, 0,
+ 78, 2, 0, 0, 0, 0, 35, 0,149, 0, 0, 0, 78, 2, 0, 0, 0, 0, 35, 0, 92, 0, 0, 0, 79, 2, 0, 0, 0, 0, 35, 0,
+148, 0, 0, 0, 79, 2, 0, 0, 0, 0, 35, 0, 83, 0, 0, 0, 80, 2, 0, 0, 0, 0, 35, 0,148, 0, 0, 0, 80, 2, 0, 0,
+ 0, 0, 35, 0, 83, 0, 0, 0, 81, 2, 0, 0, 0, 0, 33, 0, 92, 0, 0, 0, 81, 2, 0, 0, 0, 0, 33, 0, 96, 0, 0, 0,
+ 82, 2, 0, 0, 0, 0, 35, 0,150, 0, 0, 0, 82, 2, 0, 0, 0, 0, 35, 0, 85, 0, 0, 0, 83, 2, 0, 0, 0, 0, 33, 0,
+ 96, 0, 0, 0, 83, 2, 0, 0, 0, 0, 33, 0, 85, 0, 0, 0, 84, 2, 0, 0, 0, 0, 35, 0,150, 0, 0, 0, 84, 2, 0, 0,
+ 0, 0, 35, 0,150, 0, 0, 0, 85, 2, 0, 0, 0, 0, 35, 0,151, 0, 0, 0, 85, 2, 0, 0, 0, 0, 35, 0,151, 0, 0, 0,
+ 86, 2, 0, 0, 0, 0, 35, 0,152, 0, 0, 0, 86, 2, 0, 0, 0, 0, 35, 0,150, 0, 0, 0, 87, 2, 0, 0, 0, 0, 35, 0,
+152, 0, 0, 0, 87, 2, 0, 0, 0, 0, 35, 0, 95, 0, 0, 0, 88, 2, 0, 0, 0, 0, 33, 0, 97, 0, 0, 0, 88, 2, 0, 0,
+ 0, 0, 33, 0, 97, 0, 0, 0, 89, 2, 0, 0, 0, 0, 35, 0,152, 0, 0, 0, 89, 2, 0, 0, 0, 0, 35, 0, 95, 0, 0, 0,
+ 90, 2, 0, 0, 0, 0, 35, 0,152, 0, 0, 0, 90, 2, 0, 0, 0, 0, 35, 0, 94, 0, 0, 0, 91, 2, 0, 0, 0, 0, 35, 0,
+151, 0, 0, 0, 91, 2, 0, 0, 0, 0, 35, 0, 84, 0, 0, 0, 92, 2, 0, 0, 0, 0, 35, 0,151, 0, 0, 0, 92, 2, 0, 0,
+ 0, 0, 35, 0, 84, 0, 0, 0, 93, 2, 0, 0, 0, 0, 33, 0, 94, 0, 0, 0, 93, 2, 0, 0, 0, 0, 33, 0, 98, 0, 0, 0,
+ 94, 2, 0, 0, 0, 0, 35, 0,153, 0, 0, 0, 94, 2, 0, 0, 0, 0, 35, 0, 87, 0, 0, 0, 95, 2, 0, 0, 0, 0, 33, 0,
+ 98, 0, 0, 0, 95, 2, 0, 0, 0, 0, 33, 0, 87, 0, 0, 0, 96, 2, 0, 0, 0, 0, 35, 0,153, 0, 0, 0, 96, 2, 0, 0,
+ 0, 0, 35, 0,153, 0, 0, 0, 97, 2, 0, 0, 0, 0, 35, 0,154, 0, 0, 0, 97, 2, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,
+ 98, 2, 0, 0, 0, 0, 35, 0,155, 0, 0, 0, 98, 2, 0, 0, 0, 0, 35, 0,153, 0, 0, 0, 99, 2, 0, 0, 0, 0, 35, 0,
+155, 0, 0, 0, 99, 2, 0, 0, 0, 0, 35, 0, 97, 0, 0, 0,100, 2, 0, 0, 0, 0, 33, 0, 99, 0, 0, 0,100, 2, 0, 0,
+ 0, 0, 33, 0, 99, 0, 0, 0,101, 2, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,101, 2, 0, 0, 0, 0, 35, 0, 97, 0, 0, 0,
+102, 2, 0, 0, 0, 0, 35, 0,155, 0, 0, 0,102, 2, 0, 0, 0, 0, 35, 0, 96, 0, 0, 0,103, 2, 0, 0, 0, 0, 35, 0,
+154, 0, 0, 0,103, 2, 0, 0, 0, 0, 35, 0, 86, 0, 0, 0,104, 2, 0, 0, 0, 0, 35, 0,154, 0, 0, 0,104, 2, 0, 0,
+ 0, 0, 35, 0, 86, 0, 0, 0,105, 2, 0, 0, 0, 0, 33, 0, 96, 0, 0, 0,105, 2, 0, 0, 0, 0, 33, 0,100, 0, 0, 0,
+106, 2, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,106, 2, 0, 0, 0, 0, 35, 0, 89, 0, 0, 0,107, 2, 0, 0, 0, 0, 33, 0,
+100, 0, 0, 0,107, 2, 0, 0, 0, 0, 33, 0, 89, 0, 0, 0,108, 2, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,108, 2, 0, 0,
+ 0, 0, 35, 0,156, 0, 0, 0,109, 2, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,109, 2, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,
+110, 2, 0, 0, 0, 0, 35, 0,158, 0, 0, 0,110, 2, 0, 0, 0, 0, 35, 0,156, 0, 0, 0,111, 2, 0, 0, 0, 0, 35, 0,
+158, 0, 0, 0,111, 2, 0, 0, 0, 0, 35, 0, 99, 0, 0, 0,112, 2, 0, 0, 0, 0, 33, 0,101, 0, 0, 0,112, 2, 0, 0,
+ 0, 0, 33, 0,101, 0, 0, 0,113, 2, 0, 0, 0, 0, 35, 0,158, 0, 0, 0,113, 2, 0, 0, 0, 0, 35, 0, 99, 0, 0, 0,
+114, 2, 0, 0, 0, 0, 35, 0,158, 0, 0, 0,114, 2, 0, 0, 0, 0, 35, 0, 98, 0, 0, 0,115, 2, 0, 0, 0, 0, 35, 0,
+157, 0, 0, 0,115, 2, 0, 0, 0, 0, 35, 0, 88, 0, 0, 0,116, 2, 0, 0, 0, 0, 35, 0,157, 0, 0, 0,116, 2, 0, 0,
+ 0, 0, 35, 0, 88, 0, 0, 0,117, 2, 0, 0, 0, 0, 33, 0, 98, 0, 0, 0,117, 2, 0, 0, 0, 0, 33, 0, 92, 0, 0, 0,
+118, 2, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,118, 2, 0, 0, 0, 0, 35, 0, 91, 0, 0, 0,119, 2, 0, 0, 0, 0, 33, 0,
+ 92, 0, 0, 0,119, 2, 0, 0, 0, 0, 33, 0, 91, 0, 0, 0,120, 2, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,120, 2, 0, 0,
+ 0, 0, 35, 0,159, 0, 0, 0,121, 2, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,121, 2, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,
+122, 2, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,122, 2, 0, 0, 0, 0, 35, 0,159, 0, 0, 0,123, 2, 0, 0, 0, 0, 35, 0,
+161, 0, 0, 0,123, 2, 0, 0, 0, 0, 35, 0, 93, 0, 0, 0,124, 2, 0, 0, 0, 0, 33, 0,101, 0, 0, 0,124, 2, 0, 0,
+ 0, 0, 33, 0, 93, 0, 0, 0,125, 2, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,125, 2, 0, 0, 0, 0, 35, 0,101, 0, 0, 0,
+126, 2, 0, 0, 0, 0, 35, 0,161, 0, 0, 0,126, 2, 0, 0, 0, 0, 35, 0,100, 0, 0, 0,127, 2, 0, 0, 0, 0, 35, 0,
+160, 0, 0, 0,127, 2, 0, 0, 0, 0, 35, 0, 90, 0, 0, 0,128, 2, 0, 0, 0, 0, 35, 0,160, 0, 0, 0,128, 2, 0, 0,
+ 0, 0, 35, 0, 90, 0, 0, 0,129, 2, 0, 0, 0, 0, 33, 0,100, 0, 0, 0,129, 2, 0, 0, 0, 0, 33, 0, 27, 1, 0, 0,
+146, 1, 0, 0, 0, 0, 35, 0,171, 0, 0, 0,146, 1, 0, 0, 0, 0, 35, 0,171, 0, 0, 0, 27, 1, 0, 0, 0, 0, 35, 0,
+146, 1, 0, 0,147, 1, 0, 0, 0, 0, 35, 0,146, 1, 0, 0,148, 1, 0, 0, 0, 0, 35, 0,147, 1, 0, 0,148, 1, 0, 0,
+ 0, 0, 35, 0,165, 0, 0, 0, 26, 1, 0, 0, 0, 0, 35, 0,165, 0, 0, 0,148, 1, 0, 0, 0, 0, 35, 0, 26, 1, 0, 0,
+148, 1, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,147, 1, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,170, 0, 0, 0, 0, 0, 35, 0,
+170, 0, 0, 0,147, 1, 0, 0, 0, 0, 35, 0, 26, 1, 0, 0,149, 1, 0, 0, 0, 0, 35, 0, 28, 1, 0, 0,149, 1, 0, 0,
+ 0, 0, 35, 0, 26, 1, 0, 0, 28, 1, 0, 0, 0, 0, 35, 0,149, 1, 0, 0,150, 1, 0, 0, 0, 0, 35, 0,149, 1, 0, 0,
+151, 1, 0, 0, 0, 0, 35, 0,150, 1, 0, 0,151, 1, 0, 0, 0, 0, 35, 0, 27, 1, 0, 0, 31, 1, 0, 0, 0, 0, 35, 0,
+ 31, 1, 0, 0,151, 1, 0, 0, 0, 0, 35, 0, 27, 1, 0, 0,151, 1, 0, 0, 0, 0, 35, 0, 30, 1, 0, 0,150, 1, 0, 0,
+ 0, 0, 35, 0, 29, 1, 0, 0, 30, 1, 0, 0, 0, 0, 35, 0, 29, 1, 0, 0,150, 1, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,
+152, 1, 0, 0, 0, 0, 35, 0,172, 0, 0, 0,152, 1, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,172, 0, 0, 0, 0, 0, 35, 0,
+152, 1, 0, 0,153, 1, 0, 0, 0, 0, 35, 0,152, 1, 0, 0,154, 1, 0, 0, 0, 0, 35, 0,153, 1, 0, 0,154, 1, 0, 0,
+ 0, 0, 35, 0,169, 0, 0, 0, 30, 1, 0, 0, 0, 0, 35, 0, 30, 1, 0, 0,154, 1, 0, 0, 0, 0, 35, 0,169, 0, 0, 0,
+154, 1, 0, 0, 0, 0, 35, 0, 31, 1, 0, 0,153, 1, 0, 0, 0, 0, 35, 0,173, 0, 0, 0, 31, 1, 0, 0, 0, 0, 35, 0,
+173, 0, 0, 0,153, 1, 0, 0, 0, 0, 35, 0,167, 0, 0, 0,155, 1, 0, 0, 0, 0, 35, 0, 29, 1, 0, 0,155, 1, 0, 0,
+ 0, 0, 35, 0,167, 0, 0, 0, 29, 1, 0, 0, 0, 0, 35, 0,155, 1, 0, 0,156, 1, 0, 0, 0, 0, 35, 0,155, 1, 0, 0,
+157, 1, 0, 0, 0, 0, 35, 0,156, 1, 0, 0,157, 1, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,166, 0, 0, 0, 0, 0, 35, 0,
+162, 0, 0, 0,157, 1, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,157, 1, 0, 0, 0, 0, 35, 0,163, 0, 0, 0,156, 1, 0, 0,
+ 0, 0, 35, 0,163, 0, 0, 0, 28, 1, 0, 0, 0, 0, 35, 0, 28, 1, 0, 0,156, 1, 0, 0, 0, 0, 35, 0, 33, 1, 0, 0,
+158, 1, 0, 0, 0, 0, 35, 0,179, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 0,179, 0, 0, 0,158, 1, 0, 0, 0, 0, 35, 0,
+158, 1, 0, 0,159, 1, 0, 0, 0, 0, 35, 0,159, 1, 0, 0,160, 1, 0, 0, 0, 0, 35, 0,158, 1, 0, 0,160, 1, 0, 0,
+ 0, 0, 35, 0,165, 0, 0, 0, 32, 1, 0, 0, 0, 0, 35, 0, 32, 1, 0, 0,160, 1, 0, 0, 0, 0, 35, 0,165, 0, 0, 0,
+160, 1, 0, 0, 0, 0, 35, 0,164, 0, 0, 0,159, 1, 0, 0, 0, 0, 35, 0,178, 0, 0, 0,159, 1, 0, 0, 0, 0, 35, 0,
+164, 0, 0, 0,178, 0, 0, 0, 0, 0, 35, 0, 32, 1, 0, 0,161, 1, 0, 0, 0, 0, 35, 0, 32, 1, 0, 0, 34, 1, 0, 0,
+ 0, 0, 35, 0, 34, 1, 0, 0,161, 1, 0, 0, 0, 0, 35, 0,161, 1, 0, 0,162, 1, 0, 0, 0, 0, 35, 0,162, 1, 0, 0,
+163, 1, 0, 0, 0, 0, 35, 0,161, 1, 0, 0,163, 1, 0, 0, 0, 0, 35, 0, 33, 1, 0, 0, 37, 1, 0, 0, 0, 0, 35, 0,
+ 33, 1, 0, 0,163, 1, 0, 0, 0, 0, 35, 0, 37, 1, 0, 0,163, 1, 0, 0, 0, 0, 35, 0, 36, 1, 0, 0,162, 1, 0, 0,
+ 0, 0, 35, 0, 35, 1, 0, 0,162, 1, 0, 0, 0, 0, 35, 0, 35, 1, 0, 0, 36, 1, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,
+164, 1, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,180, 0, 0, 0, 0, 0, 35, 0,180, 0, 0, 0,164, 1, 0, 0, 0, 0, 35, 0,
+164, 1, 0, 0,165, 1, 0, 0, 0, 0, 35, 0,165, 1, 0, 0,166, 1, 0, 0, 0, 0, 35, 0,164, 1, 0, 0,166, 1, 0, 0,
+ 0, 0, 35, 0,177, 0, 0, 0, 36, 1, 0, 0, 0, 0, 35, 0,177, 0, 0, 0,166, 1, 0, 0, 0, 0, 35, 0, 36, 1, 0, 0,
+166, 1, 0, 0, 0, 0, 35, 0, 37, 1, 0, 0,165, 1, 0, 0, 0, 0, 35, 0,181, 0, 0, 0,165, 1, 0, 0, 0, 0, 35, 0,
+181, 0, 0, 0, 37, 1, 0, 0, 0, 0, 35, 0,175, 0, 0, 0,167, 1, 0, 0, 0, 0, 35, 0,175, 0, 0, 0, 35, 1, 0, 0,
+ 0, 0, 35, 0, 35, 1, 0, 0,167, 1, 0, 0, 0, 0, 35, 0,167, 1, 0, 0,168, 1, 0, 0, 0, 0, 35, 0,168, 1, 0, 0,
+169, 1, 0, 0, 0, 0, 35, 0,167, 1, 0, 0,169, 1, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,174, 0, 0, 0, 0, 0, 35, 0,
+174, 0, 0, 0,169, 1, 0, 0, 0, 0, 35, 0,162, 0, 0, 0,169, 1, 0, 0, 0, 0, 35, 0,163, 0, 0, 0,168, 1, 0, 0,
+ 0, 0, 35, 0, 34, 1, 0, 0,168, 1, 0, 0, 0, 0, 35, 0,163, 0, 0, 0, 34, 1, 0, 0, 0, 0, 35, 0, 39, 1, 0, 0,
+170, 1, 0, 0, 0, 0, 35, 0,187, 0, 0, 0,170, 1, 0, 0, 0, 0, 35, 0,187, 0, 0, 0, 39, 1, 0, 0, 0, 0, 35, 0,
+170, 1, 0, 0,171, 1, 0, 0, 0, 0, 35, 0,170, 1, 0, 0,172, 1, 0, 0, 0, 0, 35, 0,171, 1, 0, 0,172, 1, 0, 0,
+ 0, 0, 35, 0,169, 0, 0, 0, 38, 1, 0, 0, 0, 0, 35, 0,169, 0, 0, 0,172, 1, 0, 0, 0, 0, 35, 0, 38, 1, 0, 0,
+172, 1, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,171, 1, 0, 0, 0, 0, 35, 0,168, 0, 0, 0,186, 0, 0, 0, 0, 0, 35, 0,
+186, 0, 0, 0,171, 1, 0, 0, 0, 0, 35, 0, 38, 1, 0, 0,173, 1, 0, 0, 0, 0, 35, 0, 40, 1, 0, 0,173, 1, 0, 0,
+ 0, 0, 35, 0, 38, 1, 0, 0, 40, 1, 0, 0, 0, 0, 35, 0,173, 1, 0, 0,174, 1, 0, 0, 0, 0, 35, 0,173, 1, 0, 0,
+175, 1, 0, 0, 0, 0, 35, 0,174, 1, 0, 0,175, 1, 0, 0, 0, 0, 35, 0, 39, 1, 0, 0, 43, 1, 0, 0, 0, 0, 35, 0,
+ 43, 1, 0, 0,175, 1, 0, 0, 0, 0, 35, 0, 39, 1, 0, 0,175, 1, 0, 0, 0, 0, 35, 0, 42, 1, 0, 0,174, 1, 0, 0,
+ 0, 0, 35, 0, 41, 1, 0, 0, 42, 1, 0, 0, 0, 0, 35, 0, 41, 1, 0, 0,174, 1, 0, 0, 0, 0, 35, 0,184, 0, 0, 0,
+176, 1, 0, 0, 0, 0, 35, 0,188, 0, 0, 0,176, 1, 0, 0, 0, 0, 35, 0,184, 0, 0, 0,188, 0, 0, 0, 0, 0, 35, 0,
+176, 1, 0, 0,177, 1, 0, 0, 0, 0, 35, 0,176, 1, 0, 0,178, 1, 0, 0, 0, 0, 35, 0,177, 1, 0, 0,178, 1, 0, 0,
+ 0, 0, 35, 0,185, 0, 0, 0, 42, 1, 0, 0, 0, 0, 35, 0, 42, 1, 0, 0,178, 1, 0, 0, 0, 0, 35, 0,185, 0, 0, 0,
+178, 1, 0, 0, 0, 0, 35, 0, 43, 1, 0, 0,177, 1, 0, 0, 0, 0, 35, 0,189, 0, 0, 0, 43, 1, 0, 0, 0, 0, 35, 0,
+189, 0, 0, 0,177, 1, 0, 0, 0, 0, 35, 0,183, 0, 0, 0,179, 1, 0, 0, 0, 0, 35, 0, 41, 1, 0, 0,179, 1, 0, 0,
+ 0, 0, 35, 0,183, 0, 0, 0, 41, 1, 0, 0, 0, 0, 35, 0,179, 1, 0, 0,180, 1, 0, 0, 0, 0, 35, 0,179, 1, 0, 0,
+181, 1, 0, 0, 0, 0, 35, 0,180, 1, 0, 0,181, 1, 0, 0, 0, 0, 35, 0,166, 0, 0, 0,182, 0, 0, 0, 0, 0, 35, 0,
+166, 0, 0, 0,181, 1, 0, 0, 0, 0, 35, 0,182, 0, 0, 0,181, 1, 0, 0, 0, 0, 35, 0,167, 0, 0, 0,180, 1, 0, 0,
+ 0, 0, 35, 0,167, 0, 0, 0, 40, 1, 0, 0, 0, 0, 35, 0, 40, 1, 0, 0,180, 1, 0, 0, 0, 0, 35, 0, 45, 1, 0, 0,
+182, 1, 0, 0, 0, 0, 35, 0,195, 0, 0, 0,182, 1, 0, 0, 0, 0, 35, 0,195, 0, 0, 0, 45, 1, 0, 0, 0, 0, 35, 0,
+182, 1, 0, 0,183, 1, 0, 0, 0, 0, 35, 0,182, 1, 0, 0,184, 1, 0, 0, 0, 0, 35, 0,183, 1, 0, 0,184, 1, 0, 0,
+ 0, 0, 35, 0,185, 0, 0, 0, 44, 1, 0, 0, 0, 0, 35, 0,185, 0, 0, 0,184, 1, 0, 0, 0, 0, 35, 0, 44, 1, 0, 0,
+184, 1, 0, 0, 0, 0, 35, 0,184, 0, 0, 0,183, 1, 0, 0, 0, 0, 35, 0,184, 0, 0, 0,194, 0, 0, 0, 0, 0, 35, 0,
+194, 0, 0, 0,183, 1, 0, 0, 0, 0, 35, 0, 44, 1, 0, 0,185, 1, 0, 0, 0, 0, 35, 0, 46, 1, 0, 0,185, 1, 0, 0,
+ 0, 0, 35, 0, 44, 1, 0, 0, 46, 1, 0, 0, 0, 0, 35, 0,185, 1, 0, 0,186, 1, 0, 0, 0, 0, 35, 0,185, 1, 0, 0,
+187, 1, 0, 0, 0, 0, 35, 0,186, 1, 0, 0,187, 1, 0, 0, 0, 0, 35, 0, 45, 1, 0, 0, 49, 1, 0, 0, 0, 0, 35, 0,
+ 49, 1, 0, 0,187, 1, 0, 0, 0, 0, 35, 0, 45, 1, 0, 0,187, 1, 0, 0, 0, 0, 35, 0, 48, 1, 0, 0,186, 1, 0, 0,
+ 0, 0, 35, 0, 47, 1, 0, 0, 48, 1, 0, 0, 0, 0, 35, 0, 47, 1, 0, 0,186, 1, 0, 0, 0, 0, 35, 0,192, 0, 0, 0,
+188, 1, 0, 0, 0, 0, 35, 0,196, 0, 0, 0,188, 1, 0, 0, 0, 0, 35, 0,192, 0, 0, 0,196, 0, 0, 0, 0, 0, 35, 0,
+188, 1, 0, 0,189, 1, 0, 0, 0, 0, 35, 0,188, 1, 0, 0,190, 1, 0, 0, 0, 0, 35, 0,189, 1, 0, 0,190, 1, 0, 0,
+ 0, 0, 35, 0,193, 0, 0, 0, 48, 1, 0, 0, 0, 0, 35, 0, 48, 1, 0, 0,190, 1, 0, 0, 0, 0, 35, 0,193, 0, 0, 0,
+190, 1, 0, 0, 0, 0, 35, 0, 49, 1, 0, 0,189, 1, 0, 0, 0, 0, 35, 0,197, 0, 0, 0, 49, 1, 0, 0, 0, 0, 35, 0,
+197, 0, 0, 0,189, 1, 0, 0, 0, 0, 35, 0,191, 0, 0, 0,191, 1, 0, 0, 0, 0, 35, 0, 47, 1, 0, 0,191, 1, 0, 0,
+ 0, 0, 35, 0,191, 0, 0, 0, 47, 1, 0, 0, 0, 0, 35, 0,191, 1, 0, 0,192, 1, 0, 0, 0, 0, 35, 0,191, 1, 0, 0,
+193, 1, 0, 0, 0, 0, 35, 0,192, 1, 0, 0,193, 1, 0, 0, 0, 0, 35, 0,182, 0, 0, 0,190, 0, 0, 0, 0, 0, 35, 0,
+182, 0, 0, 0,193, 1, 0, 0, 0, 0, 35, 0,190, 0, 0, 0,193, 1, 0, 0, 0, 0, 35, 0,183, 0, 0, 0,192, 1, 0, 0,
+ 0, 0, 35, 0,183, 0, 0, 0, 46, 1, 0, 0, 0, 0, 35, 0, 46, 1, 0, 0,192, 1, 0, 0, 0, 0, 35, 0, 51, 1, 0, 0,
+194, 1, 0, 0, 0, 0, 35, 0,199, 0, 0, 0,194, 1, 0, 0, 0, 0, 35, 0,199, 0, 0, 0, 51, 1, 0, 0, 0, 0, 35, 0,
+194, 1, 0, 0,195, 1, 0, 0, 0, 0, 35, 0,194, 1, 0, 0,196, 1, 0, 0, 0, 0, 35, 0,195, 1, 0, 0,196, 1, 0, 0,
+ 0, 0, 35, 0,193, 0, 0, 0, 50, 1, 0, 0, 0, 0, 35, 0,193, 0, 0, 0,196, 1, 0, 0, 0, 0, 35, 0, 50, 1, 0, 0,
+196, 1, 0, 0, 0, 0, 35, 0,192, 0, 0, 0,195, 1, 0, 0, 0, 0, 35, 0,192, 0, 0, 0,198, 0, 0, 0, 0, 0, 35, 0,
+198, 0, 0, 0,195, 1, 0, 0, 0, 0, 35, 0, 50, 1, 0, 0,197, 1, 0, 0, 0, 0, 35, 0, 53, 1, 0, 0,197, 1, 0, 0,
+ 0, 0, 35, 0, 50, 1, 0, 0, 53, 1, 0, 0, 0, 0, 35, 0,197, 1, 0, 0,198, 1, 0, 0, 0, 0, 35, 0,197, 1, 0, 0,
+199, 1, 0, 0, 0, 0, 35, 0,198, 1, 0, 0,199, 1, 0, 0, 0, 0, 35, 0, 51, 1, 0, 0, 55, 1, 0, 0, 0, 0, 35, 0,
+ 55, 1, 0, 0,199, 1, 0, 0, 0, 0, 35, 0, 51, 1, 0, 0,199, 1, 0, 0, 0, 0, 35, 0, 54, 1, 0, 0,198, 1, 0, 0,
+ 0, 0, 35, 0, 52, 1, 0, 0, 54, 1, 0, 0, 0, 0, 35, 0, 52, 1, 0, 0,198, 1, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,
+200, 1, 0, 0, 0, 0, 35, 0,200, 0, 0, 0,200, 1, 0, 0, 0, 0, 35, 0,176, 0, 0, 0,200, 0, 0, 0, 0, 0, 35, 0,
+200, 1, 0, 0,201, 1, 0, 0, 0, 0, 35, 0,200, 1, 0, 0,202, 1, 0, 0, 0, 0, 35, 0,201, 1, 0, 0,202, 1, 0, 0,
+ 0, 0, 35, 0,177, 0, 0, 0, 54, 1, 0, 0, 0, 0, 35, 0, 54, 1, 0, 0,202, 1, 0, 0, 0, 0, 35, 0,177, 0, 0, 0,
+202, 1, 0, 0, 0, 0, 35, 0, 55, 1, 0, 0,201, 1, 0, 0, 0, 0, 35, 0,201, 0, 0, 0, 55, 1, 0, 0, 0, 0, 35, 0,
+201, 0, 0, 0,201, 1, 0, 0, 0, 0, 35, 0,175, 0, 0, 0,203, 1, 0, 0, 0, 0, 35, 0, 52, 1, 0, 0,203, 1, 0, 0,
+ 0, 0, 35, 0,175, 0, 0, 0, 52, 1, 0, 0, 0, 0, 35, 0,203, 1, 0, 0,204, 1, 0, 0, 0, 0, 35, 0,203, 1, 0, 0,
+205, 1, 0, 0, 0, 0, 35, 0,204, 1, 0, 0,205, 1, 0, 0, 0, 0, 35, 0,174, 0, 0, 0,190, 0, 0, 0, 0, 0, 35, 0,
+190, 0, 0, 0,205, 1, 0, 0, 0, 0, 35, 0,174, 0, 0, 0,205, 1, 0, 0, 0, 0, 35, 0,191, 0, 0, 0,204, 1, 0, 0,
+ 0, 0, 35, 0,191, 0, 0, 0, 53, 1, 0, 0, 0, 0, 35, 0, 53, 1, 0, 0,204, 1, 0, 0, 0, 0, 35, 0, 57, 1, 0, 0,
+206, 1, 0, 0, 0, 0, 35, 0,207, 0, 0, 0, 57, 1, 0, 0, 0, 0, 35, 0,207, 0, 0, 0,206, 1, 0, 0, 0, 0, 35, 0,
+206, 1, 0, 0,207, 1, 0, 0, 0, 0, 35, 0,207, 1, 0, 0,208, 1, 0, 0, 0, 0, 35, 0,206, 1, 0, 0,208, 1, 0, 0,
+ 0, 0, 35, 0,179, 0, 0, 0, 56, 1, 0, 0, 0, 0, 35, 0, 56, 1, 0, 0,208, 1, 0, 0, 0, 0, 35, 0,179, 0, 0, 0,
+208, 1, 0, 0, 0, 0, 35, 0,178, 0, 0, 0,207, 1, 0, 0, 0, 0, 35, 0,206, 0, 0, 0,207, 1, 0, 0, 0, 0, 35, 0,
+178, 0, 0, 0,206, 0, 0, 0, 0, 0, 35, 0, 56, 1, 0, 0,209, 1, 0, 0, 0, 0, 35, 0, 56, 1, 0, 0, 58, 1, 0, 0,
+ 0, 0, 35, 0, 58, 1, 0, 0,209, 1, 0, 0, 0, 0, 35, 0,209, 1, 0, 0,210, 1, 0, 0, 0, 0, 35, 0,210, 1, 0, 0,
+211, 1, 0, 0, 0, 0, 35, 0,209, 1, 0, 0,211, 1, 0, 0, 0, 0, 35, 0, 57, 1, 0, 0, 61, 1, 0, 0, 0, 0, 35, 0,
+ 57, 1, 0, 0,211, 1, 0, 0, 0, 0, 35, 0, 61, 1, 0, 0,211, 1, 0, 0, 0, 0, 35, 0, 60, 1, 0, 0,210, 1, 0, 0,
+ 0, 0, 35, 0, 59, 1, 0, 0,210, 1, 0, 0, 0, 0, 35, 0, 59, 1, 0, 0, 60, 1, 0, 0, 0, 0, 35, 0,204, 0, 0, 0,
+212, 1, 0, 0, 0, 0, 35, 0,204, 0, 0, 0,208, 0, 0, 0, 0, 0, 35, 0,208, 0, 0, 0,212, 1, 0, 0, 0, 0, 35, 0,
+212, 1, 0, 0,213, 1, 0, 0, 0, 0, 35, 0,213, 1, 0, 0,214, 1, 0, 0, 0, 0, 35, 0,212, 1, 0, 0,214, 1, 0, 0,
+ 0, 0, 35, 0,205, 0, 0, 0, 60, 1, 0, 0, 0, 0, 35, 0,205, 0, 0, 0,214, 1, 0, 0, 0, 0, 35, 0, 60, 1, 0, 0,
+214, 1, 0, 0, 0, 0, 35, 0, 61, 1, 0, 0,213, 1, 0, 0, 0, 0, 35, 0,209, 0, 0, 0,213, 1, 0, 0, 0, 0, 35, 0,
+209, 0, 0, 0, 61, 1, 0, 0, 0, 0, 35, 0,203, 0, 0, 0,215, 1, 0, 0, 0, 0, 35, 0,203, 0, 0, 0, 59, 1, 0, 0,
+ 0, 0, 35, 0, 59, 1, 0, 0,215, 1, 0, 0, 0, 0, 35, 0,215, 1, 0, 0,216, 1, 0, 0, 0, 0, 35, 0,216, 1, 0, 0,
+217, 1, 0, 0, 0, 0, 35, 0,215, 1, 0, 0,217, 1, 0, 0, 0, 0, 35, 0,180, 0, 0, 0,202, 0, 0, 0, 0, 0, 35, 0,
+202, 0, 0, 0,217, 1, 0, 0, 0, 0, 35, 0,180, 0, 0, 0,217, 1, 0, 0, 0, 0, 35, 0,181, 0, 0, 0,216, 1, 0, 0,
+ 0, 0, 35, 0, 58, 1, 0, 0,216, 1, 0, 0, 0, 0, 35, 0,181, 0, 0, 0, 58, 1, 0, 0, 0, 0, 35, 0, 63, 1, 0, 0,
+218, 1, 0, 0, 0, 0, 35, 0,215, 0, 0, 0, 63, 1, 0, 0, 0, 0, 35, 0,215, 0, 0, 0,218, 1, 0, 0, 0, 0, 35, 0,
+218, 1, 0, 0,219, 1, 0, 0, 0, 0, 35, 0,219, 1, 0, 0,220, 1, 0, 0, 0, 0, 35, 0,218, 1, 0, 0,220, 1, 0, 0,
+ 0, 0, 35, 0,173, 0, 0, 0, 62, 1, 0, 0, 0, 0, 35, 0, 62, 1, 0, 0,220, 1, 0, 0, 0, 0, 35, 0,173, 0, 0, 0,
+220, 1, 0, 0, 0, 0, 35, 0,172, 0, 0, 0,219, 1, 0, 0, 0, 0, 35, 0,214, 0, 0, 0,219, 1, 0, 0, 0, 0, 35, 0,
+172, 0, 0, 0,214, 0, 0, 0, 0, 0, 35, 0, 62, 1, 0, 0,221, 1, 0, 0, 0, 0, 35, 0, 62, 1, 0, 0, 64, 1, 0, 0,
+ 0, 0, 35, 0, 64, 1, 0, 0,221, 1, 0, 0, 0, 0, 35, 0,221, 1, 0, 0,222, 1, 0, 0, 0, 0, 35, 0,222, 1, 0, 0,
+223, 1, 0, 0, 0, 0, 35, 0,221, 1, 0, 0,223, 1, 0, 0, 0, 0, 35, 0, 63, 1, 0, 0, 67, 1, 0, 0, 0, 0, 35, 0,
+ 63, 1, 0, 0,223, 1, 0, 0, 0, 0, 35, 0, 67, 1, 0, 0,223, 1, 0, 0, 0, 0, 35, 0, 66, 1, 0, 0,222, 1, 0, 0,
+ 0, 0, 35, 0, 65, 1, 0, 0,222, 1, 0, 0, 0, 0, 35, 0, 65, 1, 0, 0, 66, 1, 0, 0, 0, 0, 35, 0,212, 0, 0, 0,
+224, 1, 0, 0, 0, 0, 35, 0,212, 0, 0, 0,216, 0, 0, 0, 0, 0, 35, 0,216, 0, 0, 0,224, 1, 0, 0, 0, 0, 35, 0,
+224, 1, 0, 0,225, 1, 0, 0, 0, 0, 35, 0,225, 1, 0, 0,226, 1, 0, 0, 0, 0, 35, 0,224, 1, 0, 0,226, 1, 0, 0,
+ 0, 0, 35, 0,213, 0, 0, 0, 66, 1, 0, 0, 0, 0, 35, 0,213, 0, 0, 0,226, 1, 0, 0, 0, 0, 35, 0, 66, 1, 0, 0,
+226, 1, 0, 0, 0, 0, 35, 0, 67, 1, 0, 0,225, 1, 0, 0, 0, 0, 35, 0,217, 0, 0, 0,225, 1, 0, 0, 0, 0, 35, 0,
+217, 0, 0, 0, 67, 1, 0, 0, 0, 0, 35, 0,211, 0, 0, 0,227, 1, 0, 0, 0, 0, 35, 0,211, 0, 0, 0, 65, 1, 0, 0,
+ 0, 0, 35, 0, 65, 1, 0, 0,227, 1, 0, 0, 0, 0, 35, 0,227, 1, 0, 0,228, 1, 0, 0, 0, 0, 35, 0,228, 1, 0, 0,
+229, 1, 0, 0, 0, 0, 35, 0,227, 1, 0, 0,229, 1, 0, 0, 0, 0, 35, 0,170, 0, 0, 0,210, 0, 0, 0, 0, 0, 35, 0,
+210, 0, 0, 0,229, 1, 0, 0, 0, 0, 35, 0,170, 0, 0, 0,229, 1, 0, 0, 0, 0, 35, 0,171, 0, 0, 0,228, 1, 0, 0,
+ 0, 0, 35, 0, 64, 1, 0, 0,228, 1, 0, 0, 0, 0, 35, 0,171, 0, 0, 0, 64, 1, 0, 0, 0, 0, 35, 0, 69, 1, 0, 0,
+230, 1, 0, 0, 0, 0, 35, 0,223, 0, 0, 0, 69, 1, 0, 0, 0, 0, 35, 0,223, 0, 0, 0,230, 1, 0, 0, 0, 0, 35, 0,
+230, 1, 0, 0,231, 1, 0, 0, 0, 0, 35, 0,231, 1, 0, 0,232, 1, 0, 0, 0, 0, 35, 0,230, 1, 0, 0,232, 1, 0, 0,
+ 0, 0, 35, 0,189, 0, 0, 0, 68, 1, 0, 0, 0, 0, 35, 0, 68, 1, 0, 0,232, 1, 0, 0, 0, 0, 35, 0,189, 0, 0, 0,
+232, 1, 0, 0, 0, 0, 35, 0,188, 0, 0, 0,231, 1, 0, 0, 0, 0, 35, 0,222, 0, 0, 0,231, 1, 0, 0, 0, 0, 35, 0,
+188, 0, 0, 0,222, 0, 0, 0, 0, 0, 35, 0, 68, 1, 0, 0,233, 1, 0, 0, 0, 0, 35, 0, 68, 1, 0, 0, 70, 1, 0, 0,
+ 0, 0, 35, 0, 70, 1, 0, 0,233, 1, 0, 0, 0, 0, 35, 0,233, 1, 0, 0,234, 1, 0, 0, 0, 0, 35, 0,234, 1, 0, 0,
+235, 1, 0, 0, 0, 0, 35, 0,233, 1, 0, 0,235, 1, 0, 0, 0, 0, 35, 0, 69, 1, 0, 0, 73, 1, 0, 0, 0, 0, 35, 0,
+ 69, 1, 0, 0,235, 1, 0, 0, 0, 0, 35, 0, 73, 1, 0, 0,235, 1, 0, 0, 0, 0, 35, 0, 72, 1, 0, 0,234, 1, 0, 0,
+ 0, 0, 35, 0, 71, 1, 0, 0,234, 1, 0, 0, 0, 0, 35, 0, 71, 1, 0, 0, 72, 1, 0, 0, 0, 0, 35, 0,220, 0, 0, 0,
+236, 1, 0, 0, 0, 0, 35, 0,220, 0, 0, 0,224, 0, 0, 0, 0, 0, 35, 0,224, 0, 0, 0,236, 1, 0, 0, 0, 0, 35, 0,
+236, 1, 0, 0,237, 1, 0, 0, 0, 0, 35, 0,237, 1, 0, 0,238, 1, 0, 0, 0, 0, 35, 0,236, 1, 0, 0,238, 1, 0, 0,
+ 0, 0, 35, 0,221, 0, 0, 0, 72, 1, 0, 0, 0, 0, 35, 0,221, 0, 0, 0,238, 1, 0, 0, 0, 0, 35, 0, 72, 1, 0, 0,
+238, 1, 0, 0, 0, 0, 35, 0, 73, 1, 0, 0,237, 1, 0, 0, 0, 0, 35, 0,225, 0, 0, 0,237, 1, 0, 0, 0, 0, 35, 0,
+225, 0, 0, 0, 73, 1, 0, 0, 0, 0, 35, 0,219, 0, 0, 0,239, 1, 0, 0, 0, 0, 35, 0,219, 0, 0, 0, 71, 1, 0, 0,
+ 0, 0, 35, 0, 71, 1, 0, 0,239, 1, 0, 0, 0, 0, 35, 0,239, 1, 0, 0,240, 1, 0, 0, 0, 0, 35, 0,240, 1, 0, 0,
+241, 1, 0, 0, 0, 0, 35, 0,239, 1, 0, 0,241, 1, 0, 0, 0, 0, 35, 0,186, 0, 0, 0,218, 0, 0, 0, 0, 0, 35, 0,
+218, 0, 0, 0,241, 1, 0, 0, 0, 0, 35, 0,186, 0, 0, 0,241, 1, 0, 0, 0, 0, 35, 0,187, 0, 0, 0,240, 1, 0, 0,
+ 0, 0, 35, 0, 70, 1, 0, 0,240, 1, 0, 0, 0, 0, 35, 0,187, 0, 0, 0, 70, 1, 0, 0, 0, 0, 35, 0, 75, 1, 0, 0,
+242, 1, 0, 0, 0, 0, 35, 0,231, 0, 0, 0, 75, 1, 0, 0, 0, 0, 35, 0,231, 0, 0, 0,242, 1, 0, 0, 0, 0, 35, 0,
+242, 1, 0, 0,243, 1, 0, 0, 0, 0, 35, 0,243, 1, 0, 0,244, 1, 0, 0, 0, 0, 35, 0,242, 1, 0, 0,244, 1, 0, 0,
+ 0, 0, 35, 0,197, 0, 0, 0, 74, 1, 0, 0, 0, 0, 35, 0, 74, 1, 0, 0,244, 1, 0, 0, 0, 0, 35, 0,197, 0, 0, 0,
+244, 1, 0, 0, 0, 0, 35, 0,196, 0, 0, 0,243, 1, 0, 0, 0, 0, 35, 0,230, 0, 0, 0,243, 1, 0, 0, 0, 0, 35, 0,
+196, 0, 0, 0,230, 0, 0, 0, 0, 0, 35, 0, 74, 1, 0, 0,245, 1, 0, 0, 0, 0, 35, 0, 74, 1, 0, 0, 76, 1, 0, 0,
+ 0, 0, 35, 0, 76, 1, 0, 0,245, 1, 0, 0, 0, 0, 35, 0,245, 1, 0, 0,246, 1, 0, 0, 0, 0, 35, 0,246, 1, 0, 0,
+247, 1, 0, 0, 0, 0, 35, 0,245, 1, 0, 0,247, 1, 0, 0, 0, 0, 35, 0, 75, 1, 0, 0, 79, 1, 0, 0, 0, 0, 35, 0,
+ 75, 1, 0, 0,247, 1, 0, 0, 0, 0, 35, 0, 79, 1, 0, 0,247, 1, 0, 0, 0, 0, 35, 0, 78, 1, 0, 0,246, 1, 0, 0,
+ 0, 0, 35, 0, 77, 1, 0, 0,246, 1, 0, 0, 0, 0, 35, 0, 77, 1, 0, 0, 78, 1, 0, 0, 0, 0, 35, 0,228, 0, 0, 0,
+248, 1, 0, 0, 0, 0, 35, 0,228, 0, 0, 0,232, 0, 0, 0, 0, 0, 35, 0,232, 0, 0, 0,248, 1, 0, 0, 0, 0, 35, 0,
+248, 1, 0, 0,249, 1, 0, 0, 0, 0, 35, 0,249, 1, 0, 0,250, 1, 0, 0, 0, 0, 35, 0,248, 1, 0, 0,250, 1, 0, 0,
+ 0, 0, 35, 0,229, 0, 0, 0, 78, 1, 0, 0, 0, 0, 35, 0,229, 0, 0, 0,250, 1, 0, 0, 0, 0, 35, 0, 78, 1, 0, 0,
+250, 1, 0, 0, 0, 0, 35, 0, 79, 1, 0, 0,249, 1, 0, 0, 0, 0, 35, 0,233, 0, 0, 0,249, 1, 0, 0, 0, 0, 35, 0,
+233, 0, 0, 0, 79, 1, 0, 0, 0, 0, 35, 0,227, 0, 0, 0,251, 1, 0, 0, 0, 0, 35, 0,227, 0, 0, 0, 77, 1, 0, 0,
+ 0, 0, 35, 0, 77, 1, 0, 0,251, 1, 0, 0, 0, 0, 35, 0,251, 1, 0, 0,252, 1, 0, 0, 0, 0, 35, 0,252, 1, 0, 0,
+253, 1, 0, 0, 0, 0, 35, 0,251, 1, 0, 0,253, 1, 0, 0, 0, 0, 35, 0,194, 0, 0, 0,226, 0, 0, 0, 0, 0, 35, 0,
+226, 0, 0, 0,253, 1, 0, 0, 0, 0, 35, 0,194, 0, 0, 0,253, 1, 0, 0, 0, 0, 35, 0,195, 0, 0, 0,252, 1, 0, 0,
+ 0, 0, 35, 0, 76, 1, 0, 0,252, 1, 0, 0, 0, 0, 35, 0,195, 0, 0, 0, 76, 1, 0, 0, 0, 0, 35, 0, 81, 1, 0, 0,
+254, 1, 0, 0, 0, 0, 35, 0,239, 0, 0, 0, 81, 1, 0, 0, 0, 0, 35, 0,239, 0, 0, 0,254, 1, 0, 0, 0, 0, 35, 0,
+254, 1, 0, 0,255, 1, 0, 0, 0, 0, 35, 0,255, 1, 0, 0, 0, 2, 0, 0, 0, 0, 35, 0,254, 1, 0, 0, 0, 2, 0, 0,
+ 0, 0, 35, 0,201, 0, 0, 0, 80, 1, 0, 0, 0, 0, 35, 0, 80, 1, 0, 0, 0, 2, 0, 0, 0, 0, 35, 0,201, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0, 35, 0,200, 0, 0, 0,255, 1, 0, 0, 0, 0, 35, 0,238, 0, 0, 0,255, 1, 0, 0, 0, 0, 35, 0,
+200, 0, 0, 0,238, 0, 0, 0, 0, 0, 35, 0, 80, 1, 0, 0, 1, 2, 0, 0, 0, 0, 35, 0, 80, 1, 0, 0, 82, 1, 0, 0,
+ 0, 0, 35, 0, 82, 1, 0, 0, 1, 2, 0, 0, 0, 0, 35, 0, 1, 2, 0, 0, 2, 2, 0, 0, 0, 0, 35, 0, 2, 2, 0, 0,
+ 3, 2, 0, 0, 0, 0, 35, 0, 1, 2, 0, 0, 3, 2, 0, 0, 0, 0, 35, 0, 81, 1, 0, 0, 85, 1, 0, 0, 0, 0, 35, 0,
+ 81, 1, 0, 0, 3, 2, 0, 0, 0, 0, 35, 0, 85, 1, 0, 0, 3, 2, 0, 0, 0, 0, 35, 0, 84, 1, 0, 0, 2, 2, 0, 0,
+ 0, 0, 35, 0, 83, 1, 0, 0, 2, 2, 0, 0, 0, 0, 35, 0, 83, 1, 0, 0, 84, 1, 0, 0, 0, 0, 35, 0,236, 0, 0, 0,
+ 4, 2, 0, 0, 0, 0, 35, 0,236, 0, 0, 0,240, 0, 0, 0, 0, 0, 35, 0,240, 0, 0, 0, 4, 2, 0, 0, 0, 0, 35, 0,
+ 4, 2, 0, 0, 5, 2, 0, 0, 0, 0, 35, 0, 5, 2, 0, 0, 6, 2, 0, 0, 0, 0, 35, 0, 4, 2, 0, 0, 6, 2, 0, 0,
+ 0, 0, 35, 0,237, 0, 0, 0, 84, 1, 0, 0, 0, 0, 35, 0,237, 0, 0, 0, 6, 2, 0, 0, 0, 0, 35, 0, 84, 1, 0, 0,
+ 6, 2, 0, 0, 0, 0, 35, 0, 85, 1, 0, 0, 5, 2, 0, 0, 0, 0, 35, 0,241, 0, 0, 0, 5, 2, 0, 0, 0, 0, 35, 0,
+241, 0, 0, 0, 85, 1, 0, 0, 0, 0, 35, 0,235, 0, 0, 0, 7, 2, 0, 0, 0, 0, 35, 0,235, 0, 0, 0, 83, 1, 0, 0,
+ 0, 0, 35, 0, 83, 1, 0, 0, 7, 2, 0, 0, 0, 0, 35, 0, 7, 2, 0, 0, 8, 2, 0, 0, 0, 0, 35, 0, 8, 2, 0, 0,
+ 9, 2, 0, 0, 0, 0, 35, 0, 7, 2, 0, 0, 9, 2, 0, 0, 0, 0, 35, 0,198, 0, 0, 0,234, 0, 0, 0, 0, 0, 35, 0,
+234, 0, 0, 0, 9, 2, 0, 0, 0, 0, 35, 0,198, 0, 0, 0, 9, 2, 0, 0, 0, 0, 35, 0,199, 0, 0, 0, 8, 2, 0, 0,
+ 0, 0, 35, 0, 82, 1, 0, 0, 8, 2, 0, 0, 0, 0, 35, 0,199, 0, 0, 0, 82, 1, 0, 0, 0, 0, 35, 0, 87, 1, 0, 0,
+ 10, 2, 0, 0, 0, 0, 35, 0,245, 0, 0, 0, 10, 2, 0, 0, 0, 0, 35, 0,245, 0, 0, 0, 87, 1, 0, 0, 0, 0, 35, 0,
+ 10, 2, 0, 0, 11, 2, 0, 0, 0, 0, 35, 0, 10, 2, 0, 0, 12, 2, 0, 0, 0, 0, 35, 0, 11, 2, 0, 0, 12, 2, 0, 0,
+ 0, 0, 35, 0,209, 0, 0, 0, 86, 1, 0, 0, 0, 0, 35, 0,209, 0, 0, 0, 12, 2, 0, 0, 0, 0, 35, 0, 86, 1, 0, 0,
+ 12, 2, 0, 0, 0, 0, 35, 0,208, 0, 0, 0, 11, 2, 0, 0, 0, 0, 35, 0,208, 0, 0, 0,244, 0, 0, 0, 0, 0, 35, 0,
+244, 0, 0, 0, 11, 2, 0, 0, 0, 0, 35, 0, 86, 1, 0, 0, 13, 2, 0, 0, 0, 0, 35, 0, 88, 1, 0, 0, 13, 2, 0, 0,
+ 0, 0, 35, 0, 86, 1, 0, 0, 88, 1, 0, 0, 0, 0, 35, 0, 13, 2, 0, 0, 14, 2, 0, 0, 0, 0, 35, 0, 13, 2, 0, 0,
+ 15, 2, 0, 0, 0, 0, 35, 0, 14, 2, 0, 0, 15, 2, 0, 0, 0, 0, 35, 0, 87, 1, 0, 0, 91, 1, 0, 0, 0, 0, 35, 0,
+ 91, 1, 0, 0, 15, 2, 0, 0, 0, 0, 35, 0, 87, 1, 0, 0, 15, 2, 0, 0, 0, 0, 35, 0, 90, 1, 0, 0, 14, 2, 0, 0,
+ 0, 0, 35, 0, 89, 1, 0, 0, 90, 1, 0, 0, 0, 0, 35, 0, 89, 1, 0, 0, 14, 2, 0, 0, 0, 0, 35, 0,212, 0, 0, 0,
+ 16, 2, 0, 0, 0, 0, 35, 0,242, 0, 0, 0, 16, 2, 0, 0, 0, 0, 35, 0,212, 0, 0, 0,242, 0, 0, 0, 0, 0, 35, 0,
+ 16, 2, 0, 0, 17, 2, 0, 0, 0, 0, 35, 0, 16, 2, 0, 0, 18, 2, 0, 0, 0, 0, 35, 0, 17, 2, 0, 0, 18, 2, 0, 0,
+ 0, 0, 35, 0,213, 0, 0, 0, 90, 1, 0, 0, 0, 0, 35, 0, 90, 1, 0, 0, 18, 2, 0, 0, 0, 0, 35, 0,213, 0, 0, 0,
+ 18, 2, 0, 0, 0, 0, 35, 0, 91, 1, 0, 0, 17, 2, 0, 0, 0, 0, 35, 0,243, 0, 0, 0, 91, 1, 0, 0, 0, 0, 35, 0,
+243, 0, 0, 0, 17, 2, 0, 0, 0, 0, 35, 0,211, 0, 0, 0, 19, 2, 0, 0, 0, 0, 35, 0, 89, 1, 0, 0, 19, 2, 0, 0,
+ 0, 0, 35, 0,211, 0, 0, 0, 89, 1, 0, 0, 0, 0, 35, 0, 19, 2, 0, 0, 20, 2, 0, 0, 0, 0, 35, 0, 19, 2, 0, 0,
+ 21, 2, 0, 0, 0, 0, 35, 0, 20, 2, 0, 0, 21, 2, 0, 0, 0, 0, 35, 0,206, 0, 0, 0,210, 0, 0, 0, 0, 0, 35, 0,
+206, 0, 0, 0, 21, 2, 0, 0, 0, 0, 35, 0,210, 0, 0, 0, 21, 2, 0, 0, 0, 0, 35, 0,207, 0, 0, 0, 20, 2, 0, 0,
+ 0, 0, 35, 0,207, 0, 0, 0, 88, 1, 0, 0, 0, 0, 35, 0, 88, 1, 0, 0, 20, 2, 0, 0, 0, 0, 35, 0, 93, 1, 0, 0,
+ 22, 2, 0, 0, 0, 0, 35, 0,247, 0, 0, 0, 22, 2, 0, 0, 0, 0, 35, 0,247, 0, 0, 0, 93, 1, 0, 0, 0, 0, 35, 0,
+ 22, 2, 0, 0, 23, 2, 0, 0, 0, 0, 35, 0, 22, 2, 0, 0, 24, 2, 0, 0, 0, 0, 35, 0, 23, 2, 0, 0, 24, 2, 0, 0,
+ 0, 0, 35, 0,217, 0, 0, 0, 92, 1, 0, 0, 0, 0, 35, 0,217, 0, 0, 0, 24, 2, 0, 0, 0, 0, 35, 0, 92, 1, 0, 0,
+ 24, 2, 0, 0, 0, 0, 35, 0,216, 0, 0, 0, 23, 2, 0, 0, 0, 0, 35, 0,216, 0, 0, 0,246, 0, 0, 0, 0, 0, 35, 0,
+246, 0, 0, 0, 23, 2, 0, 0, 0, 0, 35, 0, 92, 1, 0, 0, 25, 2, 0, 0, 0, 0, 35, 0, 94, 1, 0, 0, 25, 2, 0, 0,
+ 0, 0, 35, 0, 92, 1, 0, 0, 94, 1, 0, 0, 0, 0, 35, 0, 25, 2, 0, 0, 26, 2, 0, 0, 0, 0, 35, 0, 25, 2, 0, 0,
+ 27, 2, 0, 0, 0, 0, 35, 0, 26, 2, 0, 0, 27, 2, 0, 0, 0, 0, 35, 0, 93, 1, 0, 0, 97, 1, 0, 0, 0, 0, 35, 0,
+ 97, 1, 0, 0, 27, 2, 0, 0, 0, 0, 35, 0, 93, 1, 0, 0, 27, 2, 0, 0, 0, 0, 35, 0, 96, 1, 0, 0, 26, 2, 0, 0,
+ 0, 0, 35, 0, 95, 1, 0, 0, 96, 1, 0, 0, 0, 0, 35, 0, 95, 1, 0, 0, 26, 2, 0, 0, 0, 0, 35, 0,220, 0, 0, 0,
+ 28, 2, 0, 0, 0, 0, 35, 0,248, 0, 0, 0, 28, 2, 0, 0, 0, 0, 35, 0,220, 0, 0, 0,248, 0, 0, 0, 0, 0, 35, 0,
+ 28, 2, 0, 0, 29, 2, 0, 0, 0, 0, 35, 0, 28, 2, 0, 0, 30, 2, 0, 0, 0, 0, 35, 0, 29, 2, 0, 0, 30, 2, 0, 0,
+ 0, 0, 35, 0,221, 0, 0, 0, 96, 1, 0, 0, 0, 0, 35, 0, 96, 1, 0, 0, 30, 2, 0, 0, 0, 0, 35, 0,221, 0, 0, 0,
+ 30, 2, 0, 0, 0, 0, 35, 0, 97, 1, 0, 0, 29, 2, 0, 0, 0, 0, 35, 0,249, 0, 0, 0, 97, 1, 0, 0, 0, 0, 35, 0,
+249, 0, 0, 0, 29, 2, 0, 0, 0, 0, 35, 0,219, 0, 0, 0, 31, 2, 0, 0, 0, 0, 35, 0, 95, 1, 0, 0, 31, 2, 0, 0,
+ 0, 0, 35, 0,219, 0, 0, 0, 95, 1, 0, 0, 0, 0, 35, 0, 31, 2, 0, 0, 32, 2, 0, 0, 0, 0, 35, 0, 31, 2, 0, 0,
+ 33, 2, 0, 0, 0, 0, 35, 0, 32, 2, 0, 0, 33, 2, 0, 0, 0, 0, 35, 0,214, 0, 0, 0,218, 0, 0, 0, 0, 0, 35, 0,
+214, 0, 0, 0, 33, 2, 0, 0, 0, 0, 35, 0,218, 0, 0, 0, 33, 2, 0, 0, 0, 0, 35, 0,215, 0, 0, 0, 32, 2, 0, 0,
+ 0, 0, 35, 0,215, 0, 0, 0, 94, 1, 0, 0, 0, 0, 35, 0, 94, 1, 0, 0, 32, 2, 0, 0, 0, 0, 35, 0, 99, 1, 0, 0,
+ 34, 2, 0, 0, 0, 0, 35, 0,251, 0, 0, 0, 34, 2, 0, 0, 0, 0, 35, 0,251, 0, 0, 0, 99, 1, 0, 0, 0, 0, 35, 0,
+ 34, 2, 0, 0, 35, 2, 0, 0, 0, 0, 35, 0, 34, 2, 0, 0, 36, 2, 0, 0, 0, 0, 35, 0, 35, 2, 0, 0, 36, 2, 0, 0,
+ 0, 0, 35, 0,225, 0, 0, 0, 98, 1, 0, 0, 0, 0, 35, 0,225, 0, 0, 0, 36, 2, 0, 0, 0, 0, 35, 0, 98, 1, 0, 0,
+ 36, 2, 0, 0, 0, 0, 35, 0,224, 0, 0, 0, 35, 2, 0, 0, 0, 0, 35, 0,224, 0, 0, 0,250, 0, 0, 0, 0, 0, 35, 0,
+250, 0, 0, 0, 35, 2, 0, 0, 0, 0, 35, 0, 98, 1, 0, 0, 37, 2, 0, 0, 0, 0, 35, 0,100, 1, 0, 0, 37, 2, 0, 0,
+ 0, 0, 35, 0, 98, 1, 0, 0,100, 1, 0, 0, 0, 0, 35, 0, 37, 2, 0, 0, 38, 2, 0, 0, 0, 0, 35, 0, 37, 2, 0, 0,
+ 39, 2, 0, 0, 0, 0, 35, 0, 38, 2, 0, 0, 39, 2, 0, 0, 0, 0, 35, 0, 99, 1, 0, 0,103, 1, 0, 0, 0, 0, 35, 0,
+103, 1, 0, 0, 39, 2, 0, 0, 0, 0, 35, 0, 99, 1, 0, 0, 39, 2, 0, 0, 0, 0, 35, 0,102, 1, 0, 0, 38, 2, 0, 0,
+ 0, 0, 35, 0,101, 1, 0, 0,102, 1, 0, 0, 0, 0, 35, 0,101, 1, 0, 0, 38, 2, 0, 0, 0, 0, 35, 0,228, 0, 0, 0,
+ 40, 2, 0, 0, 0, 0, 35, 0,252, 0, 0, 0, 40, 2, 0, 0, 0, 0, 35, 0,228, 0, 0, 0,252, 0, 0, 0, 0, 0, 35, 0,
+ 40, 2, 0, 0, 41, 2, 0, 0, 0, 0, 35, 0, 40, 2, 0, 0, 42, 2, 0, 0, 0, 0, 35, 0, 41, 2, 0, 0, 42, 2, 0, 0,
+ 0, 0, 35, 0,229, 0, 0, 0,102, 1, 0, 0, 0, 0, 35, 0,102, 1, 0, 0, 42, 2, 0, 0, 0, 0, 35, 0,229, 0, 0, 0,
+ 42, 2, 0, 0, 0, 0, 35, 0,103, 1, 0, 0, 41, 2, 0, 0, 0, 0, 35, 0,253, 0, 0, 0,103, 1, 0, 0, 0, 0, 35, 0,
+253, 0, 0, 0, 41, 2, 0, 0, 0, 0, 35, 0,227, 0, 0, 0, 43, 2, 0, 0, 0, 0, 35, 0,101, 1, 0, 0, 43, 2, 0, 0,
+ 0, 0, 35, 0,227, 0, 0, 0,101, 1, 0, 0, 0, 0, 35, 0, 43, 2, 0, 0, 44, 2, 0, 0, 0, 0, 35, 0, 43, 2, 0, 0,
+ 45, 2, 0, 0, 0, 0, 35, 0, 44, 2, 0, 0, 45, 2, 0, 0, 0, 0, 35, 0,222, 0, 0, 0,226, 0, 0, 0, 0, 0, 35, 0,
+222, 0, 0, 0, 45, 2, 0, 0, 0, 0, 35, 0,226, 0, 0, 0, 45, 2, 0, 0, 0, 0, 35, 0,223, 0, 0, 0, 44, 2, 0, 0,
+ 0, 0, 35, 0,223, 0, 0, 0,100, 1, 0, 0, 0, 0, 35, 0,100, 1, 0, 0, 44, 2, 0, 0, 0, 0, 35, 0,105, 1, 0, 0,
+ 46, 2, 0, 0, 0, 0, 35, 0,255, 0, 0, 0, 46, 2, 0, 0, 0, 0, 35, 0,255, 0, 0, 0,105, 1, 0, 0, 0, 0, 35, 0,
+ 46, 2, 0, 0, 47, 2, 0, 0, 0, 0, 35, 0, 46, 2, 0, 0, 48, 2, 0, 0, 0, 0, 35, 0, 47, 2, 0, 0, 48, 2, 0, 0,
+ 0, 0, 35, 0,233, 0, 0, 0,104, 1, 0, 0, 0, 0, 35, 0,233, 0, 0, 0, 48, 2, 0, 0, 0, 0, 35, 0,104, 1, 0, 0,
+ 48, 2, 0, 0, 0, 0, 35, 0,232, 0, 0, 0, 47, 2, 0, 0, 0, 0, 35, 0,232, 0, 0, 0,254, 0, 0, 0, 0, 0, 35, 0,
+254, 0, 0, 0, 47, 2, 0, 0, 0, 0, 35, 0,104, 1, 0, 0, 49, 2, 0, 0, 0, 0, 35, 0,106, 1, 0, 0, 49, 2, 0, 0,
+ 0, 0, 35, 0,104, 1, 0, 0,106, 1, 0, 0, 0, 0, 35, 0, 49, 2, 0, 0, 50, 2, 0, 0, 0, 0, 35, 0, 49, 2, 0, 0,
+ 51, 2, 0, 0, 0, 0, 35, 0, 50, 2, 0, 0, 51, 2, 0, 0, 0, 0, 35, 0,105, 1, 0, 0,109, 1, 0, 0, 0, 0, 35, 0,
+109, 1, 0, 0, 51, 2, 0, 0, 0, 0, 35, 0,105, 1, 0, 0, 51, 2, 0, 0, 0, 0, 35, 0,108, 1, 0, 0, 50, 2, 0, 0,
+ 0, 0, 35, 0,107, 1, 0, 0,108, 1, 0, 0, 0, 0, 35, 0,107, 1, 0, 0, 50, 2, 0, 0, 0, 0, 35, 0,236, 0, 0, 0,
+ 52, 2, 0, 0, 0, 0, 35, 0, 0, 1, 0, 0, 52, 2, 0, 0, 0, 0, 35, 0,236, 0, 0, 0, 0, 1, 0, 0, 0, 0, 35, 0,
+ 52, 2, 0, 0, 53, 2, 0, 0, 0, 0, 35, 0, 52, 2, 0, 0, 54, 2, 0, 0, 0, 0, 35, 0, 53, 2, 0, 0, 54, 2, 0, 0,
+ 0, 0, 35, 0,237, 0, 0, 0,108, 1, 0, 0, 0, 0, 35, 0,108, 1, 0, 0, 54, 2, 0, 0, 0, 0, 35, 0,237, 0, 0, 0,
+ 54, 2, 0, 0, 0, 0, 35, 0,109, 1, 0, 0, 53, 2, 0, 0, 0, 0, 35, 0, 1, 1, 0, 0,109, 1, 0, 0, 0, 0, 35, 0,
+ 1, 1, 0, 0, 53, 2, 0, 0, 0, 0, 35, 0,235, 0, 0, 0, 55, 2, 0, 0, 0, 0, 35, 0,107, 1, 0, 0, 55, 2, 0, 0,
+ 0, 0, 35, 0,235, 0, 0, 0,107, 1, 0, 0, 0, 0, 35, 0, 55, 2, 0, 0, 56, 2, 0, 0, 0, 0, 35, 0, 55, 2, 0, 0,
+ 57, 2, 0, 0, 0, 0, 35, 0, 56, 2, 0, 0, 57, 2, 0, 0, 0, 0, 35, 0,230, 0, 0, 0,234, 0, 0, 0, 0, 0, 35, 0,
+230, 0, 0, 0, 57, 2, 0, 0, 0, 0, 35, 0,234, 0, 0, 0, 57, 2, 0, 0, 0, 0, 35, 0,231, 0, 0, 0, 56, 2, 0, 0,
+ 0, 0, 35, 0,231, 0, 0, 0,106, 1, 0, 0, 0, 0, 35, 0,106, 1, 0, 0, 56, 2, 0, 0, 0, 0, 35, 0,111, 1, 0, 0,
+ 58, 2, 0, 0, 0, 0, 35, 0, 3, 1, 0, 0, 58, 2, 0, 0, 0, 0, 35, 0, 3, 1, 0, 0,111, 1, 0, 0, 0, 0, 35, 0,
+ 58, 2, 0, 0, 59, 2, 0, 0, 0, 0, 35, 0, 58, 2, 0, 0, 60, 2, 0, 0, 0, 0, 35, 0, 59, 2, 0, 0, 60, 2, 0, 0,
+ 0, 0, 35, 0,241, 0, 0, 0,110, 1, 0, 0, 0, 0, 35, 0,241, 0, 0, 0, 60, 2, 0, 0, 0, 0, 35, 0,110, 1, 0, 0,
+ 60, 2, 0, 0, 0, 0, 35, 0,240, 0, 0, 0, 59, 2, 0, 0, 0, 0, 35, 0,240, 0, 0, 0, 2, 1, 0, 0, 0, 0, 35, 0,
+ 2, 1, 0, 0, 59, 2, 0, 0, 0, 0, 35, 0,110, 1, 0, 0, 61, 2, 0, 0, 0, 0, 35, 0,113, 1, 0, 0, 61, 2, 0, 0,
+ 0, 0, 35, 0,110, 1, 0, 0,113, 1, 0, 0, 0, 0, 35, 0, 61, 2, 0, 0, 62, 2, 0, 0, 0, 0, 35, 0, 61, 2, 0, 0,
+ 63, 2, 0, 0, 0, 0, 35, 0, 62, 2, 0, 0, 63, 2, 0, 0, 0, 0, 35, 0,111, 1, 0, 0,115, 1, 0, 0, 0, 0, 35, 0,
+115, 1, 0, 0, 63, 2, 0, 0, 0, 0, 35, 0,111, 1, 0, 0, 63, 2, 0, 0, 0, 0, 35, 0,114, 1, 0, 0, 62, 2, 0, 0,
+ 0, 0, 35, 0,112, 1, 0, 0,114, 1, 0, 0, 0, 0, 35, 0,112, 1, 0, 0, 62, 2, 0, 0, 0, 0, 35, 0,204, 0, 0, 0,
+ 64, 2, 0, 0, 0, 0, 35, 0, 4, 1, 0, 0, 64, 2, 0, 0, 0, 0, 35, 0,204, 0, 0, 0, 4, 1, 0, 0, 0, 0, 35, 0,
+ 64, 2, 0, 0, 65, 2, 0, 0, 0, 0, 35, 0, 64, 2, 0, 0, 66, 2, 0, 0, 0, 0, 35, 0, 65, 2, 0, 0, 66, 2, 0, 0,
+ 0, 0, 35, 0,205, 0, 0, 0,114, 1, 0, 0, 0, 0, 35, 0,114, 1, 0, 0, 66, 2, 0, 0, 0, 0, 35, 0,205, 0, 0, 0,
+ 66, 2, 0, 0, 0, 0, 35, 0,115, 1, 0, 0, 65, 2, 0, 0, 0, 0, 35, 0, 5, 1, 0, 0,115, 1, 0, 0, 0, 0, 35, 0,
+ 5, 1, 0, 0, 65, 2, 0, 0, 0, 0, 35, 0,203, 0, 0, 0, 67, 2, 0, 0, 0, 0, 35, 0,112, 1, 0, 0, 67, 2, 0, 0,
+ 0, 0, 35, 0,203, 0, 0, 0,112, 1, 0, 0, 0, 0, 35, 0, 67, 2, 0, 0, 68, 2, 0, 0, 0, 0, 35, 0, 67, 2, 0, 0,
+ 69, 2, 0, 0, 0, 0, 35, 0, 68, 2, 0, 0, 69, 2, 0, 0, 0, 0, 35, 0,202, 0, 0, 0,238, 0, 0, 0, 0, 0, 35, 0,
+238, 0, 0, 0, 69, 2, 0, 0, 0, 0, 35, 0,202, 0, 0, 0, 69, 2, 0, 0, 0, 0, 35, 0,239, 0, 0, 0, 68, 2, 0, 0,
+ 0, 0, 35, 0,239, 0, 0, 0,113, 1, 0, 0, 0, 0, 35, 0,113, 1, 0, 0, 68, 2, 0, 0, 0, 0, 35, 0,117, 1, 0, 0,
+ 70, 2, 0, 0, 0, 0, 35, 0, 11, 1, 0, 0,117, 1, 0, 0, 0, 0, 35, 0, 11, 1, 0, 0, 70, 2, 0, 0, 0, 0, 35, 0,
+ 70, 2, 0, 0, 71, 2, 0, 0, 0, 0, 35, 0, 71, 2, 0, 0, 72, 2, 0, 0, 0, 0, 35, 0, 70, 2, 0, 0, 72, 2, 0, 0,
+ 0, 0, 35, 0,243, 0, 0, 0,116, 1, 0, 0, 0, 0, 35, 0,116, 1, 0, 0, 72, 2, 0, 0, 0, 0, 35, 0,243, 0, 0, 0,
+ 72, 2, 0, 0, 0, 0, 35, 0,242, 0, 0, 0, 71, 2, 0, 0, 0, 0, 35, 0, 10, 1, 0, 0, 71, 2, 0, 0, 0, 0, 35, 0,
+242, 0, 0, 0, 10, 1, 0, 0, 0, 0, 35, 0,116, 1, 0, 0, 73, 2, 0, 0, 0, 0, 35, 0,116, 1, 0, 0,118, 1, 0, 0,
+ 0, 0, 35, 0,118, 1, 0, 0, 73, 2, 0, 0, 0, 0, 35, 0, 73, 2, 0, 0, 74, 2, 0, 0, 0, 0, 35, 0, 74, 2, 0, 0,
+ 75, 2, 0, 0, 0, 0, 35, 0, 73, 2, 0, 0, 75, 2, 0, 0, 0, 0, 35, 0,117, 1, 0, 0,121, 1, 0, 0, 0, 0, 35, 0,
+117, 1, 0, 0, 75, 2, 0, 0, 0, 0, 35, 0,121, 1, 0, 0, 75, 2, 0, 0, 0, 0, 35, 0,120, 1, 0, 0, 74, 2, 0, 0,
+ 0, 0, 35, 0,119, 1, 0, 0, 74, 2, 0, 0, 0, 0, 35, 0,119, 1, 0, 0,120, 1, 0, 0, 0, 0, 35, 0, 8, 1, 0, 0,
+ 76, 2, 0, 0, 0, 0, 35, 0, 8, 1, 0, 0, 12, 1, 0, 0, 0, 0, 35, 0, 12, 1, 0, 0, 76, 2, 0, 0, 0, 0, 35, 0,
+ 76, 2, 0, 0, 77, 2, 0, 0, 0, 0, 35, 0, 77, 2, 0, 0, 78, 2, 0, 0, 0, 0, 35, 0, 76, 2, 0, 0, 78, 2, 0, 0,
+ 0, 0, 35, 0, 9, 1, 0, 0,120, 1, 0, 0, 0, 0, 35, 0, 9, 1, 0, 0, 78, 2, 0, 0, 0, 0, 35, 0,120, 1, 0, 0,
+ 78, 2, 0, 0, 0, 0, 35, 0,121, 1, 0, 0, 77, 2, 0, 0, 0, 0, 35, 0, 13, 1, 0, 0, 77, 2, 0, 0, 0, 0, 35, 0,
+ 13, 1, 0, 0,121, 1, 0, 0, 0, 0, 35, 0, 7, 1, 0, 0, 79, 2, 0, 0, 0, 0, 35, 0, 7, 1, 0, 0,119, 1, 0, 0,
+ 0, 0, 35, 0,119, 1, 0, 0, 79, 2, 0, 0, 0, 0, 35, 0, 79, 2, 0, 0, 80, 2, 0, 0, 0, 0, 35, 0, 80, 2, 0, 0,
+ 81, 2, 0, 0, 0, 0, 35, 0, 79, 2, 0, 0, 81, 2, 0, 0, 0, 0, 35, 0,244, 0, 0, 0, 6, 1, 0, 0, 0, 0, 35, 0,
+ 6, 1, 0, 0, 81, 2, 0, 0, 0, 0, 35, 0,244, 0, 0, 0, 81, 2, 0, 0, 0, 0, 35, 0,245, 0, 0, 0, 80, 2, 0, 0,
+ 0, 0, 35, 0,118, 1, 0, 0, 80, 2, 0, 0, 0, 0, 35, 0,245, 0, 0, 0,118, 1, 0, 0, 0, 0, 35, 0,123, 1, 0, 0,
+ 82, 2, 0, 0, 0, 0, 35, 0, 15, 1, 0, 0,123, 1, 0, 0, 0, 0, 35, 0, 15, 1, 0, 0, 82, 2, 0, 0, 0, 0, 35, 0,
+ 82, 2, 0, 0, 83, 2, 0, 0, 0, 0, 35, 0, 83, 2, 0, 0, 84, 2, 0, 0, 0, 0, 35, 0, 82, 2, 0, 0, 84, 2, 0, 0,
+ 0, 0, 35, 0,249, 0, 0, 0,122, 1, 0, 0, 0, 0, 35, 0,122, 1, 0, 0, 84, 2, 0, 0, 0, 0, 35, 0,249, 0, 0, 0,
+ 84, 2, 0, 0, 0, 0, 35, 0,248, 0, 0, 0, 83, 2, 0, 0, 0, 0, 35, 0, 14, 1, 0, 0, 83, 2, 0, 0, 0, 0, 35, 0,
+248, 0, 0, 0, 14, 1, 0, 0, 0, 0, 35, 0,122, 1, 0, 0, 85, 2, 0, 0, 0, 0, 35, 0,122, 1, 0, 0,124, 1, 0, 0,
+ 0, 0, 35, 0,124, 1, 0, 0, 85, 2, 0, 0, 0, 0, 35, 0, 85, 2, 0, 0, 86, 2, 0, 0, 0, 0, 35, 0, 86, 2, 0, 0,
+ 87, 2, 0, 0, 0, 0, 35, 0, 85, 2, 0, 0, 87, 2, 0, 0, 0, 0, 35, 0,123, 1, 0, 0,127, 1, 0, 0, 0, 0, 35, 0,
+123, 1, 0, 0, 87, 2, 0, 0, 0, 0, 35, 0,127, 1, 0, 0, 87, 2, 0, 0, 0, 0, 35, 0,126, 1, 0, 0, 86, 2, 0, 0,
+ 0, 0, 35, 0,125, 1, 0, 0, 86, 2, 0, 0, 0, 0, 35, 0,125, 1, 0, 0,126, 1, 0, 0, 0, 0, 35, 0, 12, 1, 0, 0,
+ 88, 2, 0, 0, 0, 0, 35, 0, 12, 1, 0, 0, 16, 1, 0, 0, 0, 0, 35, 0, 16, 1, 0, 0, 88, 2, 0, 0, 0, 0, 35, 0,
+ 88, 2, 0, 0, 89, 2, 0, 0, 0, 0, 35, 0, 89, 2, 0, 0, 90, 2, 0, 0, 0, 0, 35, 0, 88, 2, 0, 0, 90, 2, 0, 0,
+ 0, 0, 35, 0, 13, 1, 0, 0,126, 1, 0, 0, 0, 0, 35, 0, 13, 1, 0, 0, 90, 2, 0, 0, 0, 0, 35, 0,126, 1, 0, 0,
+ 90, 2, 0, 0, 0, 0, 35, 0,127, 1, 0, 0, 89, 2, 0, 0, 0, 0, 35, 0, 17, 1, 0, 0, 89, 2, 0, 0, 0, 0, 35, 0,
+ 17, 1, 0, 0,127, 1, 0, 0, 0, 0, 35, 0, 11, 1, 0, 0, 91, 2, 0, 0, 0, 0, 35, 0, 11, 1, 0, 0,125, 1, 0, 0,
+ 0, 0, 35, 0,125, 1, 0, 0, 91, 2, 0, 0, 0, 0, 35, 0, 91, 2, 0, 0, 92, 2, 0, 0, 0, 0, 35, 0, 92, 2, 0, 0,
+ 93, 2, 0, 0, 0, 0, 35, 0, 91, 2, 0, 0, 93, 2, 0, 0, 0, 0, 35, 0,246, 0, 0, 0, 10, 1, 0, 0, 0, 0, 35, 0,
+ 10, 1, 0, 0, 93, 2, 0, 0, 0, 0, 35, 0,246, 0, 0, 0, 93, 2, 0, 0, 0, 0, 35, 0,247, 0, 0, 0, 92, 2, 0, 0,
+ 0, 0, 35, 0,124, 1, 0, 0, 92, 2, 0, 0, 0, 0, 35, 0,247, 0, 0, 0,124, 1, 0, 0, 0, 0, 35, 0,129, 1, 0, 0,
+ 94, 2, 0, 0, 0, 0, 35, 0, 19, 1, 0, 0,129, 1, 0, 0, 0, 0, 35, 0, 19, 1, 0, 0, 94, 2, 0, 0, 0, 0, 35, 0,
+ 94, 2, 0, 0, 95, 2, 0, 0, 0, 0, 35, 0, 95, 2, 0, 0, 96, 2, 0, 0, 0, 0, 35, 0, 94, 2, 0, 0, 96, 2, 0, 0,
+ 0, 0, 35, 0,253, 0, 0, 0,128, 1, 0, 0, 0, 0, 35, 0,128, 1, 0, 0, 96, 2, 0, 0, 0, 0, 35, 0,253, 0, 0, 0,
+ 96, 2, 0, 0, 0, 0, 35, 0,252, 0, 0, 0, 95, 2, 0, 0, 0, 0, 35, 0, 18, 1, 0, 0, 95, 2, 0, 0, 0, 0, 35, 0,
+252, 0, 0, 0, 18, 1, 0, 0, 0, 0, 35, 0,128, 1, 0, 0, 97, 2, 0, 0, 0, 0, 35, 0,128, 1, 0, 0,130, 1, 0, 0,
+ 0, 0, 35, 0,130, 1, 0, 0, 97, 2, 0, 0, 0, 0, 35, 0, 97, 2, 0, 0, 98, 2, 0, 0, 0, 0, 35, 0, 98, 2, 0, 0,
+ 99, 2, 0, 0, 0, 0, 35, 0, 97, 2, 0, 0, 99, 2, 0, 0, 0, 0, 35, 0,129, 1, 0, 0,133, 1, 0, 0, 0, 0, 35, 0,
+129, 1, 0, 0, 99, 2, 0, 0, 0, 0, 35, 0,133, 1, 0, 0, 99, 2, 0, 0, 0, 0, 35, 0,132, 1, 0, 0, 98, 2, 0, 0,
+ 0, 0, 35, 0,131, 1, 0, 0, 98, 2, 0, 0, 0, 0, 35, 0,131, 1, 0, 0,132, 1, 0, 0, 0, 0, 35, 0, 16, 1, 0, 0,
+100, 2, 0, 0, 0, 0, 35, 0, 16, 1, 0, 0, 20, 1, 0, 0, 0, 0, 35, 0, 20, 1, 0, 0,100, 2, 0, 0, 0, 0, 35, 0,
+100, 2, 0, 0,101, 2, 0, 0, 0, 0, 35, 0,101, 2, 0, 0,102, 2, 0, 0, 0, 0, 35, 0,100, 2, 0, 0,102, 2, 0, 0,
+ 0, 0, 35, 0, 17, 1, 0, 0,132, 1, 0, 0, 0, 0, 35, 0, 17, 1, 0, 0,102, 2, 0, 0, 0, 0, 35, 0,132, 1, 0, 0,
+102, 2, 0, 0, 0, 0, 35, 0,133, 1, 0, 0,101, 2, 0, 0, 0, 0, 35, 0, 21, 1, 0, 0,101, 2, 0, 0, 0, 0, 35, 0,
+ 21, 1, 0, 0,133, 1, 0, 0, 0, 0, 35, 0, 15, 1, 0, 0,103, 2, 0, 0, 0, 0, 35, 0, 15, 1, 0, 0,131, 1, 0, 0,
+ 0, 0, 35, 0,131, 1, 0, 0,103, 2, 0, 0, 0, 0, 35, 0,103, 2, 0, 0,104, 2, 0, 0, 0, 0, 35, 0,104, 2, 0, 0,
+105, 2, 0, 0, 0, 0, 35, 0,103, 2, 0, 0,105, 2, 0, 0, 0, 0, 35, 0,250, 0, 0, 0, 14, 1, 0, 0, 0, 0, 35, 0,
+ 14, 1, 0, 0,105, 2, 0, 0, 0, 0, 35, 0,250, 0, 0, 0,105, 2, 0, 0, 0, 0, 35, 0,251, 0, 0, 0,104, 2, 0, 0,
+ 0, 0, 35, 0,130, 1, 0, 0,104, 2, 0, 0, 0, 0, 35, 0,251, 0, 0, 0,130, 1, 0, 0, 0, 0, 35, 0,135, 1, 0, 0,
+106, 2, 0, 0, 0, 0, 35, 0, 23, 1, 0, 0,135, 1, 0, 0, 0, 0, 35, 0, 23, 1, 0, 0,106, 2, 0, 0, 0, 0, 35, 0,
+106, 2, 0, 0,107, 2, 0, 0, 0, 0, 35, 0,107, 2, 0, 0,108, 2, 0, 0, 0, 0, 35, 0,106, 2, 0, 0,108, 2, 0, 0,
+ 0, 0, 35, 0, 1, 1, 0, 0,134, 1, 0, 0, 0, 0, 35, 0,134, 1, 0, 0,108, 2, 0, 0, 0, 0, 35, 0, 1, 1, 0, 0,
+108, 2, 0, 0, 0, 0, 35, 0, 0, 1, 0, 0,107, 2, 0, 0, 0, 0, 35, 0, 22, 1, 0, 0,107, 2, 0, 0, 0, 0, 35, 0,
+ 0, 1, 0, 0, 22, 1, 0, 0, 0, 0, 35, 0,134, 1, 0, 0,109, 2, 0, 0, 0, 0, 35, 0,134, 1, 0, 0,136, 1, 0, 0,
+ 0, 0, 35, 0,136, 1, 0, 0,109, 2, 0, 0, 0, 0, 35, 0,109, 2, 0, 0,110, 2, 0, 0, 0, 0, 35, 0,110, 2, 0, 0,
+111, 2, 0, 0, 0, 0, 35, 0,109, 2, 0, 0,111, 2, 0, 0, 0, 0, 35, 0,135, 1, 0, 0,139, 1, 0, 0, 0, 0, 35, 0,
+135, 1, 0, 0,111, 2, 0, 0, 0, 0, 35, 0,139, 1, 0, 0,111, 2, 0, 0, 0, 0, 35, 0,138, 1, 0, 0,110, 2, 0, 0,
+ 0, 0, 35, 0,137, 1, 0, 0,110, 2, 0, 0, 0, 0, 35, 0,137, 1, 0, 0,138, 1, 0, 0, 0, 0, 35, 0, 20, 1, 0, 0,
+112, 2, 0, 0, 0, 0, 35, 0, 20, 1, 0, 0, 24, 1, 0, 0, 0, 0, 35, 0, 24, 1, 0, 0,112, 2, 0, 0, 0, 0, 35, 0,
+112, 2, 0, 0,113, 2, 0, 0, 0, 0, 35, 0,113, 2, 0, 0,114, 2, 0, 0, 0, 0, 35, 0,112, 2, 0, 0,114, 2, 0, 0,
+ 0, 0, 35, 0, 21, 1, 0, 0,138, 1, 0, 0, 0, 0, 35, 0, 21, 1, 0, 0,114, 2, 0, 0, 0, 0, 35, 0,138, 1, 0, 0,
+114, 2, 0, 0, 0, 0, 35, 0,139, 1, 0, 0,113, 2, 0, 0, 0, 0, 35, 0, 25, 1, 0, 0,113, 2, 0, 0, 0, 0, 35, 0,
+ 25, 1, 0, 0,139, 1, 0, 0, 0, 0, 35, 0, 19, 1, 0, 0,115, 2, 0, 0, 0, 0, 35, 0, 19, 1, 0, 0,137, 1, 0, 0,
+ 0, 0, 35, 0,137, 1, 0, 0,115, 2, 0, 0, 0, 0, 35, 0,115, 2, 0, 0,116, 2, 0, 0, 0, 0, 35, 0,116, 2, 0, 0,
+117, 2, 0, 0, 0, 0, 35, 0,115, 2, 0, 0,117, 2, 0, 0, 0, 0, 35, 0,254, 0, 0, 0, 18, 1, 0, 0, 0, 0, 35, 0,
+ 18, 1, 0, 0,117, 2, 0, 0, 0, 0, 35, 0,254, 0, 0, 0,117, 2, 0, 0, 0, 0, 35, 0,255, 0, 0, 0,116, 2, 0, 0,
+ 0, 0, 35, 0,136, 1, 0, 0,116, 2, 0, 0, 0, 0, 35, 0,255, 0, 0, 0,136, 1, 0, 0, 0, 0, 35, 0,141, 1, 0, 0,
+118, 2, 0, 0, 0, 0, 35, 0, 7, 1, 0, 0,141, 1, 0, 0, 0, 0, 35, 0, 7, 1, 0, 0,118, 2, 0, 0, 0, 0, 35, 0,
+118, 2, 0, 0,119, 2, 0, 0, 0, 0, 35, 0,119, 2, 0, 0,120, 2, 0, 0, 0, 0, 35, 0,118, 2, 0, 0,120, 2, 0, 0,
+ 0, 0, 35, 0, 5, 1, 0, 0,140, 1, 0, 0, 0, 0, 35, 0,140, 1, 0, 0,120, 2, 0, 0, 0, 0, 35, 0, 5, 1, 0, 0,
+120, 2, 0, 0, 0, 0, 35, 0, 4, 1, 0, 0,119, 2, 0, 0, 0, 0, 35, 0, 6, 1, 0, 0,119, 2, 0, 0, 0, 0, 35, 0,
+ 4, 1, 0, 0, 6, 1, 0, 0, 0, 0, 35, 0,140, 1, 0, 0,121, 2, 0, 0, 0, 0, 35, 0,140, 1, 0, 0,142, 1, 0, 0,
+ 0, 0, 35, 0,142, 1, 0, 0,121, 2, 0, 0, 0, 0, 35, 0,121, 2, 0, 0,122, 2, 0, 0, 0, 0, 35, 0,122, 2, 0, 0,
+123, 2, 0, 0, 0, 0, 35, 0,121, 2, 0, 0,123, 2, 0, 0, 0, 0, 35, 0,141, 1, 0, 0,144, 1, 0, 0, 0, 0, 35, 0,
+141, 1, 0, 0,123, 2, 0, 0, 0, 0, 35, 0,144, 1, 0, 0,123, 2, 0, 0, 0, 0, 35, 0,145, 1, 0, 0,122, 2, 0, 0,
+ 0, 0, 35, 0,143, 1, 0, 0,122, 2, 0, 0, 0, 0, 35, 0,143, 1, 0, 0,145, 1, 0, 0, 0, 0, 35, 0, 24, 1, 0, 0,
+124, 2, 0, 0, 0, 0, 35, 0, 8, 1, 0, 0, 24, 1, 0, 0, 0, 0, 35, 0, 8, 1, 0, 0,124, 2, 0, 0, 0, 0, 35, 0,
+124, 2, 0, 0,125, 2, 0, 0, 0, 0, 35, 0,125, 2, 0, 0,126, 2, 0, 0, 0, 0, 35, 0,124, 2, 0, 0,126, 2, 0, 0,
+ 0, 0, 35, 0, 25, 1, 0, 0,145, 1, 0, 0, 0, 0, 35, 0, 25, 1, 0, 0,126, 2, 0, 0, 0, 0, 35, 0,145, 1, 0, 0,
+126, 2, 0, 0, 0, 0, 35, 0,144, 1, 0, 0,125, 2, 0, 0, 0, 0, 35, 0, 9, 1, 0, 0,125, 2, 0, 0, 0, 0, 35, 0,
+ 9, 1, 0, 0,144, 1, 0, 0, 0, 0, 35, 0, 23, 1, 0, 0,127, 2, 0, 0, 0, 0, 35, 0, 23, 1, 0, 0,143, 1, 0, 0,
+ 0, 0, 35, 0,143, 1, 0, 0,127, 2, 0, 0, 0, 0, 35, 0,127, 2, 0, 0,128, 2, 0, 0, 0, 0, 35, 0,128, 2, 0, 0,
+129, 2, 0, 0, 0, 0, 35, 0,127, 2, 0, 0,129, 2, 0, 0, 0, 0, 35, 0, 2, 1, 0, 0, 22, 1, 0, 0, 0, 0, 35, 0,
+ 22, 1, 0, 0,129, 2, 0, 0, 0, 0, 35, 0, 2, 1, 0, 0,129, 2, 0, 0, 0, 0, 35, 0, 3, 1, 0, 0,128, 2, 0, 0,
+ 0, 0, 35, 0,142, 1, 0, 0,128, 2, 0, 0, 0, 0, 35, 0, 3, 1, 0, 0,142, 1, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65,
+ 44, 1, 0, 0,168,195,152, 2, 21, 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,224, 47,167, 2, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 75, 18, 3, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 67,111,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,
+ 16,148,167, 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, 68, 65, 84, 65,
+ 0,100, 0, 0,224, 47,167, 2, 53, 0, 0, 0, 0, 5, 0, 0, 27, 1, 0, 0,102, 0, 0, 0,146, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,146, 1, 0, 0,171, 0, 0, 0, 27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 14, 0, 0, 0, 27, 1, 0, 0,
+171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,171, 0, 0, 0,146, 1, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+147, 1, 0, 0, 46, 0, 0, 0,146, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,146, 1, 0, 0,148, 1, 0, 0,147, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 43, 0, 0, 0,147, 1, 0, 0,148, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,148, 1, 0, 0,
+146, 1, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 26, 1, 0, 0, 12, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,165, 0, 0, 0,148, 1, 0, 0, 26, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,102, 0, 0, 0, 26, 1, 0, 0,
+148, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,148, 1, 0, 0,165, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+147, 1, 0, 0, 43, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,164, 0, 0, 0,170, 0, 0, 0,147, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 46, 0, 0, 0,147, 1, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,170, 0, 0, 0,
+164, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 26, 1, 0, 0,102, 0, 0, 0,149, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,149, 1, 0, 0, 28, 1, 0, 0, 26, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 0, 26, 1, 0, 0,
+ 28, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 28, 1, 0, 0,149, 1, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+150, 1, 0, 0,103, 0, 0, 0,149, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,149, 1, 0, 0,151, 1, 0, 0,150, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,104, 0, 0, 0,150, 1, 0, 0,151, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,151, 1, 0, 0,
+149, 1, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 27, 1, 0, 0, 14, 0, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 31, 1, 0, 0,151, 1, 0, 0, 27, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,102, 0, 0, 0, 27, 1, 0, 0,
+151, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,151, 1, 0, 0, 31, 1, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+150, 1, 0, 0,104, 0, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 30, 1, 0, 0, 29, 1, 0, 0,150, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,103, 0, 0, 0,150, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 29, 1, 0, 0,
+ 30, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,168, 0, 0, 0, 45, 0, 0, 0,152, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,152, 1, 0, 0,172, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0,168, 0, 0, 0,
+172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,172, 0, 0, 0,152, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+153, 1, 0, 0, 47, 0, 0, 0,152, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152, 1, 0, 0,154, 1, 0, 0,153, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,104, 0, 0, 0,153, 1, 0, 0,154, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,154, 1, 0, 0,
+152, 1, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,169, 0, 0, 0, 13, 0, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 30, 1, 0, 0,154, 1, 0, 0,169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 45, 0, 0, 0,169, 0, 0, 0,
+154, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,154, 1, 0, 0, 30, 1, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+153, 1, 0, 0,104, 0, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 31, 1, 0, 0,173, 0, 0, 0,153, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 47, 0, 0, 0,153, 1, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,173, 0, 0, 0,
+ 31, 1, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,167, 0, 0, 0, 44, 0, 0, 0,155, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,155, 1, 0, 0, 29, 1, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 13, 0, 0, 0,167, 0, 0, 0,
+ 29, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 29, 1, 0, 0,155, 1, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+156, 1, 0, 0,103, 0, 0, 0,155, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,155, 1, 0, 0,157, 1, 0, 0,156, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 42, 0, 0, 0,156, 1, 0, 0,157, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,157, 1, 0, 0,
+155, 1, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,166, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,162, 0, 0, 0,157, 1, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 44, 0, 0, 0,166, 0, 0, 0,
+157, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,157, 1, 0, 0,162, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+156, 1, 0, 0, 42, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,163, 0, 0, 0, 28, 1, 0, 0,156, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,103, 0, 0, 0,156, 1, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 28, 1, 0, 0,
+163, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,158, 1, 0, 0,105, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 33, 1, 0, 0,179, 0, 0, 0,158, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 50, 0, 0, 0,158, 1, 0, 0,
+179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,179, 0, 0, 0, 33, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+158, 1, 0, 0, 50, 0, 0, 0,159, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,159, 1, 0, 0,160, 1, 0, 0,158, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,105, 0, 0, 0,158, 1, 0, 0,160, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,160, 1, 0, 0,
+159, 1, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,165, 0, 0, 0, 12, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 32, 1, 0, 0,160, 1, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 43, 0, 0, 0,165, 0, 0, 0,
+160, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,160, 1, 0, 0, 32, 1, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+164, 0, 0, 0, 43, 0, 0, 0,159, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,159, 1, 0, 0,178, 0, 0, 0,164, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0,164, 0, 0, 0,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,178, 0, 0, 0,
+159, 1, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,161, 1, 0, 0,105, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 32, 1, 0, 0, 34, 1, 0, 0,161, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,106, 0, 0, 0,161, 1, 0, 0,
+ 34, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34, 1, 0, 0, 32, 1, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+161, 1, 0, 0,106, 0, 0, 0,162, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,162, 1, 0, 0,163, 1, 0, 0,161, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,105, 0, 0, 0,161, 1, 0, 0,163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,163, 1, 0, 0,
+162, 1, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 1, 0, 0, 16, 0, 0, 0, 33, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 33, 1, 0, 0,163, 1, 0, 0, 37, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 0, 0, 0, 37, 1, 0, 0,
+163, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,163, 1, 0, 0, 33, 1, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 36, 1, 0, 0,107, 0, 0, 0,162, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,162, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 15, 0, 0, 0, 36, 1, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 35, 1, 0, 0,
+162, 1, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,164, 1, 0, 0, 49, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,176, 0, 0, 0,180, 0, 0, 0,164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 0, 0, 0,164, 1, 0, 0,
+180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,180, 0, 0, 0,176, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+164, 1, 0, 0, 51, 0, 0, 0,165, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,165, 1, 0, 0,166, 1, 0, 0,164, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 49, 0, 0, 0,164, 1, 0, 0,166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,166, 1, 0, 0,
+165, 1, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 36, 1, 0, 0, 15, 0, 0, 0,177, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,177, 0, 0, 0,166, 1, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 0, 0, 0, 36, 1, 0, 0,
+166, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,166, 1, 0, 0,177, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 37, 1, 0, 0,107, 0, 0, 0,165, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,165, 1, 0, 0,181, 0, 0, 0, 37, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 16, 0, 0, 0, 37, 1, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,181, 0, 0, 0,
+165, 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,167, 1, 0, 0, 48, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,175, 0, 0, 0, 35, 1, 0, 0,167, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,106, 0, 0, 0,167, 1, 0, 0,
+ 35, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 35, 1, 0, 0,175, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+167, 1, 0, 0,106, 0, 0, 0,168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,168, 1, 0, 0,169, 1, 0, 0,167, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 48, 0, 0, 0,167, 1, 0, 0,169, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,169, 1, 0, 0,
+168, 1, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,162, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,174, 0, 0, 0,169, 1, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 42, 0, 0, 0,162, 0, 0, 0,
+169, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,169, 1, 0, 0,174, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+163, 0, 0, 0, 42, 0, 0, 0,168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,168, 1, 0, 0, 34, 1, 0, 0,163, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 0,163, 0, 0, 0, 34, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34, 1, 0, 0,
+168, 1, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 39, 1, 0, 0,108, 0, 0, 0,170, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,170, 1, 0, 0,187, 0, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 0, 0, 0, 39, 1, 0, 0,
+187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,187, 0, 0, 0,170, 1, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+171, 1, 0, 0, 54, 0, 0, 0,170, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,170, 1, 0, 0,172, 1, 0, 0,171, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 45, 0, 0, 0,171, 1, 0, 0,172, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,172, 1, 0, 0,
+170, 1, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 38, 1, 0, 0, 13, 0, 0, 0,169, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,169, 0, 0, 0,172, 1, 0, 0, 38, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,108, 0, 0, 0, 38, 1, 0, 0,
+172, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,172, 1, 0, 0,169, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+171, 1, 0, 0, 45, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,168, 0, 0, 0,186, 0, 0, 0,171, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 54, 0, 0, 0,171, 1, 0, 0,186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,186, 0, 0, 0,
+168, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 38, 1, 0, 0,108, 0, 0, 0,173, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,173, 1, 0, 0, 40, 1, 0, 0, 38, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 13, 0, 0, 0, 38, 1, 0, 0,
+ 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 40, 1, 0, 0,173, 1, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+174, 1, 0, 0,109, 0, 0, 0,173, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,173, 1, 0, 0,175, 1, 0, 0,174, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,110, 0, 0, 0,174, 1, 0, 0,175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,175, 1, 0, 0,
+173, 1, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 39, 1, 0, 0, 18, 0, 0, 0, 43, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 43, 1, 0, 0,175, 1, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,108, 0, 0, 0, 39, 1, 0, 0,
+175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,175, 1, 0, 0, 43, 1, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+174, 1, 0, 0,110, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 42, 1, 0, 0, 41, 1, 0, 0,174, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,109, 0, 0, 0,174, 1, 0, 0, 41, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 41, 1, 0, 0,
+ 42, 1, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,184, 0, 0, 0, 53, 0, 0, 0,176, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,176, 1, 0, 0,188, 0, 0, 0,184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0,184, 0, 0, 0,
+188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,188, 0, 0, 0,176, 1, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+177, 1, 0, 0, 55, 0, 0, 0,176, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,176, 1, 0, 0,178, 1, 0, 0,177, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,110, 0, 0, 0,177, 1, 0, 0,178, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,178, 1, 0, 0,
+176, 1, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,185, 0, 0, 0, 17, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 42, 1, 0, 0,178, 1, 0, 0,185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 53, 0, 0, 0,185, 0, 0, 0,
+178, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,178, 1, 0, 0, 42, 1, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+177, 1, 0, 0,110, 0, 0, 0, 43, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 43, 1, 0, 0,189, 0, 0, 0,177, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 55, 0, 0, 0,177, 1, 0, 0,189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,189, 0, 0, 0,
+ 43, 1, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,183, 0, 0, 0, 52, 0, 0, 0,179, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,179, 1, 0, 0, 41, 1, 0, 0,183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 17, 0, 0, 0,183, 0, 0, 0,
+ 41, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 41, 1, 0, 0,179, 1, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+180, 1, 0, 0,109, 0, 0, 0,179, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,179, 1, 0, 0,181, 1, 0, 0,180, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 44, 0, 0, 0,180, 1, 0, 0,181, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,181, 1, 0, 0,
+179, 1, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,182, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,166, 0, 0, 0,181, 1, 0, 0,182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 52, 0, 0, 0,182, 0, 0, 0,
+181, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,181, 1, 0, 0,166, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+180, 1, 0, 0, 44, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,167, 0, 0, 0, 40, 1, 0, 0,180, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,109, 0, 0, 0,180, 1, 0, 0, 40, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 40, 1, 0, 0,
+167, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 45, 1, 0, 0,111, 0, 0, 0,182, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,182, 1, 0, 0,195, 0, 0, 0, 45, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 0, 0, 0, 45, 1, 0, 0,
+195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,195, 0, 0, 0,182, 1, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+183, 1, 0, 0, 58, 0, 0, 0,182, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,182, 1, 0, 0,184, 1, 0, 0,183, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 53, 0, 0, 0,183, 1, 0, 0,184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,184, 1, 0, 0,
+182, 1, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 44, 1, 0, 0, 17, 0, 0, 0,185, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,185, 0, 0, 0,184, 1, 0, 0, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 0, 0, 0, 44, 1, 0, 0,
+184, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,184, 1, 0, 0,185, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+183, 1, 0, 0, 53, 0, 0, 0,184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,184, 0, 0, 0,194, 0, 0, 0,183, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 58, 0, 0, 0,183, 1, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,194, 0, 0, 0,
+184, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 44, 1, 0, 0,111, 0, 0, 0,185, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,185, 1, 0, 0, 46, 1, 0, 0, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 17, 0, 0, 0, 44, 1, 0, 0,
+ 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 46, 1, 0, 0,185, 1, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+186, 1, 0, 0,112, 0, 0, 0,185, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,185, 1, 0, 0,187, 1, 0, 0,186, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,113, 0, 0, 0,186, 1, 0, 0,187, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,187, 1, 0, 0,
+185, 1, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 45, 1, 0, 0, 20, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 49, 1, 0, 0,187, 1, 0, 0, 45, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 0, 0, 0, 45, 1, 0, 0,
+187, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,187, 1, 0, 0, 49, 1, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+186, 1, 0, 0,113, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 48, 1, 0, 0, 47, 1, 0, 0,186, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,112, 0, 0, 0,186, 1, 0, 0, 47, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 1, 0, 0,
+ 48, 1, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,192, 0, 0, 0, 57, 0, 0, 0,188, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,188, 1, 0, 0,196, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0,192, 0, 0, 0,
+196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,196, 0, 0, 0,188, 1, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+189, 1, 0, 0, 59, 0, 0, 0,188, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,188, 1, 0, 0,190, 1, 0, 0,189, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,113, 0, 0, 0,189, 1, 0, 0,190, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,190, 1, 0, 0,
+188, 1, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,193, 0, 0, 0, 19, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 48, 1, 0, 0,190, 1, 0, 0,193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 57, 0, 0, 0,193, 0, 0, 0,
+190, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,190, 1, 0, 0, 48, 1, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+189, 1, 0, 0,113, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 49, 1, 0, 0,197, 0, 0, 0,189, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 59, 0, 0, 0,189, 1, 0, 0,197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,197, 0, 0, 0,
+ 49, 1, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,191, 0, 0, 0, 56, 0, 0, 0,191, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,191, 1, 0, 0, 47, 1, 0, 0,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 0, 0, 0,191, 0, 0, 0,
+ 47, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 1, 0, 0,191, 1, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+192, 1, 0, 0,112, 0, 0, 0,191, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,191, 1, 0, 0,193, 1, 0, 0,192, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 52, 0, 0, 0,192, 1, 0, 0,193, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,193, 1, 0, 0,
+191, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,190, 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,182, 0, 0, 0,193, 1, 0, 0,190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 56, 0, 0, 0,190, 0, 0, 0,
+193, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,193, 1, 0, 0,182, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+192, 1, 0, 0, 52, 0, 0, 0,183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,183, 0, 0, 0, 46, 1, 0, 0,192, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,112, 0, 0, 0,192, 1, 0, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 46, 1, 0, 0,
+183, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 1, 0, 0,114, 0, 0, 0,194, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,194, 1, 0, 0,199, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 21, 0, 0, 0, 51, 1, 0, 0,
+199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,199, 0, 0, 0,194, 1, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+195, 1, 0, 0, 60, 0, 0, 0,194, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,194, 1, 0, 0,196, 1, 0, 0,195, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 57, 0, 0, 0,195, 1, 0, 0,196, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,196, 1, 0, 0,
+194, 1, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 50, 1, 0, 0, 19, 0, 0, 0,193, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,193, 0, 0, 0,196, 1, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,114, 0, 0, 0, 50, 1, 0, 0,
+196, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,196, 1, 0, 0,193, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+195, 1, 0, 0, 57, 0, 0, 0,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,192, 0, 0, 0,198, 0, 0, 0,195, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 60, 0, 0, 0,195, 1, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,198, 0, 0, 0,
+192, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 50, 1, 0, 0,114, 0, 0, 0,197, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,197, 1, 0, 0, 53, 1, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 0, 0, 0, 50, 1, 0, 0,
+ 53, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 53, 1, 0, 0,197, 1, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+198, 1, 0, 0,115, 0, 0, 0,197, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,197, 1, 0, 0,199, 1, 0, 0,198, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,116, 0, 0, 0,198, 1, 0, 0,199, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,199, 1, 0, 0,
+197, 1, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 1, 0, 0, 21, 0, 0, 0, 55, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 55, 1, 0, 0,199, 1, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,114, 0, 0, 0, 51, 1, 0, 0,
+199, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,199, 1, 0, 0, 55, 1, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+198, 1, 0, 0,116, 0, 0, 0, 54, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54, 1, 0, 0, 52, 1, 0, 0,198, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,115, 0, 0, 0,198, 1, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 52, 1, 0, 0,
+ 54, 1, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,176, 0, 0, 0, 49, 0, 0, 0,200, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,200, 1, 0, 0,200, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0,176, 0, 0, 0,
+200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,200, 0, 0, 0,200, 1, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+201, 1, 0, 0, 61, 0, 0, 0,200, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,200, 1, 0, 0,202, 1, 0, 0,201, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,116, 0, 0, 0,201, 1, 0, 0,202, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,202, 1, 0, 0,
+200, 1, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,177, 0, 0, 0, 15, 0, 0, 0, 54, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 54, 1, 0, 0,202, 1, 0, 0,177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 49, 0, 0, 0,177, 0, 0, 0,
+202, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,202, 1, 0, 0, 54, 1, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+201, 1, 0, 0,116, 0, 0, 0, 55, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 55, 1, 0, 0,201, 0, 0, 0,201, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 61, 0, 0, 0,201, 1, 0, 0,201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,201, 0, 0, 0,
+ 55, 1, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,175, 0, 0, 0, 48, 0, 0, 0,203, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,203, 1, 0, 0, 52, 1, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 0, 0, 0,175, 0, 0, 0,
+ 52, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 52, 1, 0, 0,203, 1, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+204, 1, 0, 0,115, 0, 0, 0,203, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,203, 1, 0, 0,205, 1, 0, 0,204, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 56, 0, 0, 0,204, 1, 0, 0,205, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,205, 1, 0, 0,
+203, 1, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,174, 0, 0, 0, 0, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,190, 0, 0, 0,205, 1, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 48, 0, 0, 0,174, 0, 0, 0,
+205, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,205, 1, 0, 0,190, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+204, 1, 0, 0, 56, 0, 0, 0,191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,191, 0, 0, 0, 53, 1, 0, 0,204, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,115, 0, 0, 0,204, 1, 0, 0, 53, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 53, 1, 0, 0,
+191, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,206, 1, 0, 0,117, 0, 0, 0, 57, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 57, 1, 0, 0,207, 0, 0, 0,206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 64, 0, 0, 0,206, 1, 0, 0,
+207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,207, 0, 0, 0, 57, 1, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+206, 1, 0, 0, 64, 0, 0, 0,207, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,207, 1, 0, 0,208, 1, 0, 0,206, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,117, 0, 0, 0,206, 1, 0, 0,208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,208, 1, 0, 0,
+207, 1, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,179, 0, 0, 0, 16, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 56, 1, 0, 0,208, 1, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 50, 0, 0, 0,179, 0, 0, 0,
+208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,208, 1, 0, 0, 56, 1, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+178, 0, 0, 0, 50, 0, 0, 0,207, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,207, 1, 0, 0,206, 0, 0, 0,178, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0,178, 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,206, 0, 0, 0,
+207, 1, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,209, 1, 0, 0,117, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 56, 1, 0, 0, 58, 1, 0, 0,209, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,118, 0, 0, 0,209, 1, 0, 0,
+ 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 58, 1, 0, 0, 56, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+209, 1, 0, 0,118, 0, 0, 0,210, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 1, 0, 0,211, 1, 0, 0,209, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,117, 0, 0, 0,209, 1, 0, 0,211, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,211, 1, 0, 0,
+210, 1, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 61, 1, 0, 0, 23, 0, 0, 0, 57, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 57, 1, 0, 0,211, 1, 0, 0, 61, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 0, 0, 0, 61, 1, 0, 0,
+211, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,211, 1, 0, 0, 57, 1, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 60, 1, 0, 0,119, 0, 0, 0,210, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 1, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 22, 0, 0, 0, 60, 1, 0, 0, 59, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 1, 0, 0,
+210, 1, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,212, 1, 0, 0, 63, 0, 0, 0,204, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,204, 0, 0, 0,208, 0, 0, 0,212, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 65, 0, 0, 0,212, 1, 0, 0,
+208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,208, 0, 0, 0,204, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+212, 1, 0, 0, 65, 0, 0, 0,213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,213, 1, 0, 0,214, 1, 0, 0,212, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 63, 0, 0, 0,212, 1, 0, 0,214, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,214, 1, 0, 0,
+213, 1, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 60, 1, 0, 0, 22, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,205, 0, 0, 0,214, 1, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 0, 0, 0, 60, 1, 0, 0,
+214, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,214, 1, 0, 0,205, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 61, 1, 0, 0,119, 0, 0, 0,213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,213, 1, 0, 0,209, 0, 0, 0, 61, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 23, 0, 0, 0, 61, 1, 0, 0,209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,209, 0, 0, 0,
+213, 1, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,215, 1, 0, 0, 62, 0, 0, 0,203, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,203, 0, 0, 0, 59, 1, 0, 0,215, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,118, 0, 0, 0,215, 1, 0, 0,
+ 59, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 1, 0, 0,203, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+215, 1, 0, 0,118, 0, 0, 0,216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,216, 1, 0, 0,217, 1, 0, 0,215, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 62, 0, 0, 0,215, 1, 0, 0,217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,217, 1, 0, 0,
+216, 1, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,180, 0, 0, 0, 5, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,202, 0, 0, 0,217, 1, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 0, 0, 0,180, 0, 0, 0,
+217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,217, 1, 0, 0,202, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+181, 0, 0, 0, 51, 0, 0, 0,216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,216, 1, 0, 0, 58, 1, 0, 0,181, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 16, 0, 0, 0,181, 0, 0, 0, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 58, 1, 0, 0,
+216, 1, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,218, 1, 0, 0,120, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 63, 1, 0, 0,215, 0, 0, 0,218, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 68, 0, 0, 0,218, 1, 0, 0,
+215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,215, 0, 0, 0, 63, 1, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+218, 1, 0, 0, 68, 0, 0, 0,219, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,219, 1, 0, 0,220, 1, 0, 0,218, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,120, 0, 0, 0,218, 1, 0, 0,220, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,220, 1, 0, 0,
+219, 1, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,173, 0, 0, 0, 14, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 62, 1, 0, 0,220, 1, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 0, 0, 0,173, 0, 0, 0,
+220, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,220, 1, 0, 0, 62, 1, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+172, 0, 0, 0, 47, 0, 0, 0,219, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,219, 1, 0, 0,214, 0, 0, 0,172, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0,172, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,214, 0, 0, 0,
+219, 1, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,221, 1, 0, 0,120, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 62, 1, 0, 0, 64, 1, 0, 0,221, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,121, 0, 0, 0,221, 1, 0, 0,
+ 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 64, 1, 0, 0, 62, 1, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+221, 1, 0, 0,121, 0, 0, 0,222, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,222, 1, 0, 0,223, 1, 0, 0,221, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,120, 0, 0, 0,221, 1, 0, 0,223, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,223, 1, 0, 0,
+222, 1, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 67, 1, 0, 0, 25, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 63, 1, 0, 0,223, 1, 0, 0, 67, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,122, 0, 0, 0, 67, 1, 0, 0,
+223, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,223, 1, 0, 0, 63, 1, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 66, 1, 0, 0,122, 0, 0, 0,222, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,222, 1, 0, 0, 65, 1, 0, 0, 66, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 24, 0, 0, 0, 66, 1, 0, 0, 65, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 65, 1, 0, 0,
+222, 1, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,224, 1, 0, 0, 67, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,212, 0, 0, 0,216, 0, 0, 0,224, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 69, 0, 0, 0,224, 1, 0, 0,
+216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,216, 0, 0, 0,212, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+224, 1, 0, 0, 69, 0, 0, 0,225, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,225, 1, 0, 0,226, 1, 0, 0,224, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 67, 0, 0, 0,224, 1, 0, 0,226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,226, 1, 0, 0,
+225, 1, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 66, 1, 0, 0, 24, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,213, 0, 0, 0,226, 1, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,122, 0, 0, 0, 66, 1, 0, 0,
+226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,226, 1, 0, 0,213, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 67, 1, 0, 0,122, 0, 0, 0,225, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,225, 1, 0, 0,217, 0, 0, 0, 67, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 25, 0, 0, 0, 67, 1, 0, 0,217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,217, 0, 0, 0,
+225, 1, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,227, 1, 0, 0, 66, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,211, 0, 0, 0, 65, 1, 0, 0,227, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,121, 0, 0, 0,227, 1, 0, 0,
+ 65, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 65, 1, 0, 0,211, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+227, 1, 0, 0,121, 0, 0, 0,228, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,228, 1, 0, 0,229, 1, 0, 0,227, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 66, 0, 0, 0,227, 1, 0, 0,229, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,229, 1, 0, 0,
+228, 1, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,170, 0, 0, 0, 1, 0, 0, 0,210, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,210, 0, 0, 0,229, 1, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 46, 0, 0, 0,170, 0, 0, 0,
+229, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,229, 1, 0, 0,210, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+171, 0, 0, 0, 46, 0, 0, 0,228, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,228, 1, 0, 0, 64, 1, 0, 0,171, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 14, 0, 0, 0,171, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 64, 1, 0, 0,
+228, 1, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,230, 1, 0, 0,123, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 69, 1, 0, 0,223, 0, 0, 0,230, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 72, 0, 0, 0,230, 1, 0, 0,
+223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,223, 0, 0, 0, 69, 1, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+230, 1, 0, 0, 72, 0, 0, 0,231, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,231, 1, 0, 0,232, 1, 0, 0,230, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,123, 0, 0, 0,230, 1, 0, 0,232, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,232, 1, 0, 0,
+231, 1, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,189, 0, 0, 0, 18, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 68, 1, 0, 0,232, 1, 0, 0,189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 55, 0, 0, 0,189, 0, 0, 0,
+232, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,232, 1, 0, 0, 68, 1, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+188, 0, 0, 0, 55, 0, 0, 0,231, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,231, 1, 0, 0,222, 0, 0, 0,188, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0,188, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,222, 0, 0, 0,
+231, 1, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,233, 1, 0, 0,123, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 68, 1, 0, 0, 70, 1, 0, 0,233, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,124, 0, 0, 0,233, 1, 0, 0,
+ 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 70, 1, 0, 0, 68, 1, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+233, 1, 0, 0,124, 0, 0, 0,234, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,234, 1, 0, 0,235, 1, 0, 0,233, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,123, 0, 0, 0,233, 1, 0, 0,235, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,235, 1, 0, 0,
+234, 1, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 73, 1, 0, 0, 27, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 69, 1, 0, 0,235, 1, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 0, 0, 0, 73, 1, 0, 0,
+235, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,235, 1, 0, 0, 69, 1, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 72, 1, 0, 0,125, 0, 0, 0,234, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,234, 1, 0, 0, 71, 1, 0, 0, 72, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 26, 0, 0, 0, 72, 1, 0, 0, 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 1, 0, 0,
+234, 1, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,236, 1, 0, 0, 71, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,220, 0, 0, 0,224, 0, 0, 0,236, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 73, 0, 0, 0,236, 1, 0, 0,
+224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,224, 0, 0, 0,220, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+236, 1, 0, 0, 73, 0, 0, 0,237, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,237, 1, 0, 0,238, 1, 0, 0,236, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 71, 0, 0, 0,236, 1, 0, 0,238, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,238, 1, 0, 0,
+237, 1, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 72, 1, 0, 0, 26, 0, 0, 0,221, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,221, 0, 0, 0,238, 1, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 0, 0, 0, 72, 1, 0, 0,
+238, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,238, 1, 0, 0,221, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 73, 1, 0, 0,125, 0, 0, 0,237, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,237, 1, 0, 0,225, 0, 0, 0, 73, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 27, 0, 0, 0, 73, 1, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,225, 0, 0, 0,
+237, 1, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,239, 1, 0, 0, 70, 0, 0, 0,219, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,219, 0, 0, 0, 71, 1, 0, 0,239, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,124, 0, 0, 0,239, 1, 0, 0,
+ 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 1, 0, 0,219, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+239, 1, 0, 0,124, 0, 0, 0,240, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 1, 0, 0,241, 1, 0, 0,239, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 70, 0, 0, 0,239, 1, 0, 0,241, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,241, 1, 0, 0,
+240, 1, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,186, 0, 0, 0, 2, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,218, 0, 0, 0,241, 1, 0, 0,186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54, 0, 0, 0,186, 0, 0, 0,
+241, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,241, 1, 0, 0,218, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+187, 0, 0, 0, 54, 0, 0, 0,240, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 1, 0, 0, 70, 1, 0, 0,187, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 18, 0, 0, 0,187, 0, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 70, 1, 0, 0,
+240, 1, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,242, 1, 0, 0,126, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 75, 1, 0, 0,231, 0, 0, 0,242, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 76, 0, 0, 0,242, 1, 0, 0,
+231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,231, 0, 0, 0, 75, 1, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+242, 1, 0, 0, 76, 0, 0, 0,243, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,243, 1, 0, 0,244, 1, 0, 0,242, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,126, 0, 0, 0,242, 1, 0, 0,244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,244, 1, 0, 0,
+243, 1, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,197, 0, 0, 0, 20, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 74, 1, 0, 0,244, 1, 0, 0,197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 0, 0, 0,197, 0, 0, 0,
+244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,244, 1, 0, 0, 74, 1, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+196, 0, 0, 0, 59, 0, 0, 0,243, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,243, 1, 0, 0,230, 0, 0, 0,196, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0,196, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,230, 0, 0, 0,
+243, 1, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,245, 1, 0, 0,126, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 74, 1, 0, 0, 76, 1, 0, 0,245, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,127, 0, 0, 0,245, 1, 0, 0,
+ 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 76, 1, 0, 0, 74, 1, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+245, 1, 0, 0,127, 0, 0, 0,246, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,246, 1, 0, 0,247, 1, 0, 0,245, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,126, 0, 0, 0,245, 1, 0, 0,247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,247, 1, 0, 0,
+246, 1, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 79, 1, 0, 0, 29, 0, 0, 0, 75, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 75, 1, 0, 0,247, 1, 0, 0, 79, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,128, 0, 0, 0, 79, 1, 0, 0,
+247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,247, 1, 0, 0, 75, 1, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 78, 1, 0, 0,128, 0, 0, 0,246, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,246, 1, 0, 0, 77, 1, 0, 0, 78, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 28, 0, 0, 0, 78, 1, 0, 0, 77, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 77, 1, 0, 0,
+246, 1, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,248, 1, 0, 0, 75, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,228, 0, 0, 0,232, 0, 0, 0,248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 77, 0, 0, 0,248, 1, 0, 0,
+232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 0,228, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+248, 1, 0, 0, 77, 0, 0, 0,249, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,249, 1, 0, 0,250, 1, 0, 0,248, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 75, 0, 0, 0,248, 1, 0, 0,250, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,250, 1, 0, 0,
+249, 1, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 1, 0, 0, 28, 0, 0, 0,229, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,229, 0, 0, 0,250, 1, 0, 0, 78, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,128, 0, 0, 0, 78, 1, 0, 0,
+250, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,250, 1, 0, 0,229, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 79, 1, 0, 0,128, 0, 0, 0,249, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,249, 1, 0, 0,233, 0, 0, 0, 79, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 29, 0, 0, 0, 79, 1, 0, 0,233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,233, 0, 0, 0,
+249, 1, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,251, 1, 0, 0, 74, 0, 0, 0,227, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,227, 0, 0, 0, 77, 1, 0, 0,251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,127, 0, 0, 0,251, 1, 0, 0,
+ 77, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 77, 1, 0, 0,227, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+251, 1, 0, 0,127, 0, 0, 0,252, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,252, 1, 0, 0,253, 1, 0, 0,251, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 74, 0, 0, 0,251, 1, 0, 0,253, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,253, 1, 0, 0,
+252, 1, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,194, 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,226, 0, 0, 0,253, 1, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 58, 0, 0, 0,194, 0, 0, 0,
+253, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,253, 1, 0, 0,226, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+195, 0, 0, 0, 58, 0, 0, 0,252, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,252, 1, 0, 0, 76, 1, 0, 0,195, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 20, 0, 0, 0,195, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 76, 1, 0, 0,
+252, 1, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,254, 1, 0, 0,129, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 81, 1, 0, 0,239, 0, 0, 0,254, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 80, 0, 0, 0,254, 1, 0, 0,
+239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,239, 0, 0, 0, 81, 1, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+254, 1, 0, 0, 80, 0, 0, 0,255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,255, 1, 0, 0, 0, 2, 0, 0,254, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,129, 0, 0, 0,254, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0,
+255, 1, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,201, 0, 0, 0, 21, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 80, 1, 0, 0, 0, 2, 0, 0,201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 61, 0, 0, 0,201, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 80, 1, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+200, 0, 0, 0, 61, 0, 0, 0,255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,255, 1, 0, 0,238, 0, 0, 0,200, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 5, 0, 0, 0,200, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,238, 0, 0, 0,
+255, 1, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 0, 0,129, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 80, 1, 0, 0, 82, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,130, 0, 0, 0, 1, 2, 0, 0,
+ 82, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 82, 1, 0, 0, 80, 1, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 1, 2, 0, 0,130, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 0, 0, 3, 2, 0, 0, 1, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,129, 0, 0, 0, 1, 2, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 0, 0,
+ 2, 2, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 85, 1, 0, 0, 31, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 81, 1, 0, 0, 3, 2, 0, 0, 85, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,131, 0, 0, 0, 85, 1, 0, 0,
+ 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 0, 0, 81, 1, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 84, 1, 0, 0,131, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 0, 0, 83, 1, 0, 0, 84, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 30, 0, 0, 0, 84, 1, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 83, 1, 0, 0,
+ 2, 2, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 0, 79, 0, 0, 0,236, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,236, 0, 0, 0,240, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 81, 0, 0, 0, 4, 2, 0, 0,
+240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 0, 0, 0,236, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 4, 2, 0, 0, 81, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 79, 0, 0, 0, 4, 2, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 2, 0, 0,
+ 5, 2, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 84, 1, 0, 0, 30, 0, 0, 0,237, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,237, 0, 0, 0, 6, 2, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,131, 0, 0, 0, 84, 1, 0, 0,
+ 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 2, 0, 0,237, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 85, 1, 0, 0,131, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 0, 0,241, 0, 0, 0, 85, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 31, 0, 0, 0, 85, 1, 0, 0,241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,241, 0, 0, 0,
+ 5, 2, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 2, 0, 0, 78, 0, 0, 0,235, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,235, 0, 0, 0, 83, 1, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,130, 0, 0, 0, 7, 2, 0, 0,
+ 83, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 83, 1, 0, 0,235, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 7, 2, 0, 0,130, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 2, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 78, 0, 0, 0, 7, 2, 0, 0, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 2, 0, 0,
+ 8, 2, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,198, 0, 0, 0, 4, 0, 0, 0,234, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,234, 0, 0, 0, 9, 2, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 60, 0, 0, 0,198, 0, 0, 0,
+ 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 2, 0, 0,234, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+199, 0, 0, 0, 60, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 2, 0, 0, 82, 1, 0, 0,199, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 21, 0, 0, 0,199, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 82, 1, 0, 0,
+ 8, 2, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, 1, 0, 0,132, 0, 0, 0, 10, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 10, 2, 0, 0,245, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 32, 0, 0, 0, 87, 1, 0, 0,
+245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,245, 0, 0, 0, 10, 2, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 11, 2, 0, 0, 83, 0, 0, 0, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 2, 0, 0, 12, 2, 0, 0, 11, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 65, 0, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 2, 0, 0,
+ 10, 2, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 86, 1, 0, 0, 23, 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,209, 0, 0, 0, 12, 2, 0, 0, 86, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,132, 0, 0, 0, 86, 1, 0, 0,
+ 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 2, 0, 0,209, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 11, 2, 0, 0, 65, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,208, 0, 0, 0,244, 0, 0, 0, 11, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 83, 0, 0, 0, 11, 2, 0, 0,244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,244, 0, 0, 0,
+208, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 86, 1, 0, 0,132, 0, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 13, 2, 0, 0, 88, 1, 0, 0, 86, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 23, 0, 0, 0, 86, 1, 0, 0,
+ 88, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 88, 1, 0, 0, 13, 2, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 14, 2, 0, 0,133, 0, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 13, 2, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,134, 0, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 2, 0, 0,
+ 13, 2, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, 1, 0, 0, 32, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 91, 1, 0, 0, 15, 2, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,132, 0, 0, 0, 87, 1, 0, 0,
+ 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 2, 0, 0, 91, 1, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 14, 2, 0, 0,134, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 90, 1, 0, 0, 89, 1, 0, 0, 14, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,133, 0, 0, 0, 14, 2, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 89, 1, 0, 0,
+ 90, 1, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,212, 0, 0, 0, 67, 0, 0, 0, 16, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 16, 2, 0, 0,242, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 0, 0, 0,212, 0, 0, 0,
+242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,242, 0, 0, 0, 16, 2, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 17, 2, 0, 0, 82, 0, 0, 0, 16, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 16, 2, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,134, 0, 0, 0, 17, 2, 0, 0, 18, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 2, 0, 0,
+ 16, 2, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,213, 0, 0, 0, 24, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 90, 1, 0, 0, 18, 2, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 67, 0, 0, 0,213, 0, 0, 0,
+ 18, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 2, 0, 0, 90, 1, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 17, 2, 0, 0,134, 0, 0, 0, 91, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 91, 1, 0, 0,243, 0, 0, 0, 17, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 82, 0, 0, 0, 17, 2, 0, 0,243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,243, 0, 0, 0,
+ 91, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,211, 0, 0, 0, 66, 0, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 19, 2, 0, 0, 89, 1, 0, 0,211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 0, 0, 0,211, 0, 0, 0,
+ 89, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 89, 1, 0, 0, 19, 2, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 20, 2, 0, 0,133, 0, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 64, 0, 0, 0, 20, 2, 0, 0, 21, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 21, 2, 0, 0,
+ 19, 2, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,206, 0, 0, 0, 21, 2, 0, 0,210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 66, 0, 0, 0,210, 0, 0, 0,
+ 21, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 21, 2, 0, 0,206, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 20, 2, 0, 0, 64, 0, 0, 0,207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,207, 0, 0, 0, 88, 1, 0, 0, 20, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,133, 0, 0, 0, 20, 2, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 88, 1, 0, 0,
+207, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 93, 1, 0, 0,135, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 22, 2, 0, 0,247, 0, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 33, 0, 0, 0, 93, 1, 0, 0,
+247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,247, 0, 0, 0, 22, 2, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 23, 2, 0, 0, 84, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 22, 2, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 69, 0, 0, 0, 23, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 2, 0, 0,
+ 22, 2, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 92, 1, 0, 0, 25, 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,217, 0, 0, 0, 24, 2, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,135, 0, 0, 0, 92, 1, 0, 0,
+ 24, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 2, 0, 0,217, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 23, 2, 0, 0, 69, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,216, 0, 0, 0,246, 0, 0, 0, 23, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 84, 0, 0, 0, 23, 2, 0, 0,246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,246, 0, 0, 0,
+216, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 92, 1, 0, 0,135, 0, 0, 0, 25, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 25, 2, 0, 0, 94, 1, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 25, 0, 0, 0, 92, 1, 0, 0,
+ 94, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 94, 1, 0, 0, 25, 2, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 26, 2, 0, 0,136, 0, 0, 0, 25, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 25, 2, 0, 0, 27, 2, 0, 0, 26, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,137, 0, 0, 0, 26, 2, 0, 0, 27, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 27, 2, 0, 0,
+ 25, 2, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 93, 1, 0, 0, 33, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 97, 1, 0, 0, 27, 2, 0, 0, 93, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,135, 0, 0, 0, 93, 1, 0, 0,
+ 27, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 27, 2, 0, 0, 97, 1, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 26, 2, 0, 0,137, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 96, 1, 0, 0, 95, 1, 0, 0, 26, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,136, 0, 0, 0, 26, 2, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 95, 1, 0, 0,
+ 96, 1, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,220, 0, 0, 0, 71, 0, 0, 0, 28, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 28, 2, 0, 0,248, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 0, 0, 0,220, 0, 0, 0,
+248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,248, 0, 0, 0, 28, 2, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 29, 2, 0, 0, 85, 0, 0, 0, 28, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 28, 2, 0, 0, 30, 2, 0, 0, 29, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,137, 0, 0, 0, 29, 2, 0, 0, 30, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 30, 2, 0, 0,
+ 28, 2, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,221, 0, 0, 0, 26, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 96, 1, 0, 0, 30, 2, 0, 0,221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 0, 0, 0,221, 0, 0, 0,
+ 30, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 30, 2, 0, 0, 96, 1, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 29, 2, 0, 0,137, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 97, 1, 0, 0,249, 0, 0, 0, 29, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 85, 0, 0, 0, 29, 2, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,249, 0, 0, 0,
+ 97, 1, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,219, 0, 0, 0, 70, 0, 0, 0, 31, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 31, 2, 0, 0, 95, 1, 0, 0,219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 26, 0, 0, 0,219, 0, 0, 0,
+ 95, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 95, 1, 0, 0, 31, 2, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 32, 2, 0, 0,136, 0, 0, 0, 31, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 31, 2, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 68, 0, 0, 0, 32, 2, 0, 0, 33, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 33, 2, 0, 0,
+ 31, 2, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,218, 0, 0, 0, 2, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,214, 0, 0, 0, 33, 2, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 70, 0, 0, 0,218, 0, 0, 0,
+ 33, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 33, 2, 0, 0,214, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 32, 2, 0, 0, 68, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,215, 0, 0, 0, 94, 1, 0, 0, 32, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,136, 0, 0, 0, 32, 2, 0, 0, 94, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 94, 1, 0, 0,
+215, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 99, 1, 0, 0,138, 0, 0, 0, 34, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 34, 2, 0, 0,251, 0, 0, 0, 99, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34, 0, 0, 0, 99, 1, 0, 0,
+251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,251, 0, 0, 0, 34, 2, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 35, 2, 0, 0, 86, 0, 0, 0, 34, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34, 2, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 73, 0, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 36, 2, 0, 0,
+ 34, 2, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 1, 0, 0, 27, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,225, 0, 0, 0, 36, 2, 0, 0, 98, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,138, 0, 0, 0, 98, 1, 0, 0,
+ 36, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 36, 2, 0, 0,225, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 35, 2, 0, 0, 73, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,224, 0, 0, 0,250, 0, 0, 0, 35, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 86, 0, 0, 0, 35, 2, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,250, 0, 0, 0,
+224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 1, 0, 0,138, 0, 0, 0, 37, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 37, 2, 0, 0,100, 1, 0, 0, 98, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 27, 0, 0, 0, 98, 1, 0, 0,
+100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,100, 1, 0, 0, 37, 2, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 38, 2, 0, 0,139, 0, 0, 0, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 2, 0, 0, 39, 2, 0, 0, 38, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,140, 0, 0, 0, 38, 2, 0, 0, 39, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 39, 2, 0, 0,
+ 37, 2, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 99, 1, 0, 0, 34, 0, 0, 0,103, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,103, 1, 0, 0, 39, 2, 0, 0, 99, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,138, 0, 0, 0, 99, 1, 0, 0,
+ 39, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 39, 2, 0, 0,103, 1, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 38, 2, 0, 0,140, 0, 0, 0,102, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,102, 1, 0, 0,101, 1, 0, 0, 38, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,139, 0, 0, 0, 38, 2, 0, 0,101, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,101, 1, 0, 0,
+102, 1, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,228, 0, 0, 0, 75, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 40, 2, 0, 0,252, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 0, 0, 0,228, 0, 0, 0,
+252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,252, 0, 0, 0, 40, 2, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 41, 2, 0, 0, 87, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 40, 2, 0, 0, 42, 2, 0, 0, 41, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,140, 0, 0, 0, 41, 2, 0, 0, 42, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 42, 2, 0, 0,
+ 40, 2, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,229, 0, 0, 0, 28, 0, 0, 0,102, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,102, 1, 0, 0, 42, 2, 0, 0,229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 75, 0, 0, 0,229, 0, 0, 0,
+ 42, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 42, 2, 0, 0,102, 1, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 41, 2, 0, 0,140, 0, 0, 0,103, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,103, 1, 0, 0,253, 0, 0, 0, 41, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 87, 0, 0, 0, 41, 2, 0, 0,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,253, 0, 0, 0,
+103, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,227, 0, 0, 0, 74, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 43, 2, 0, 0,101, 1, 0, 0,227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 28, 0, 0, 0,227, 0, 0, 0,
+101, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,101, 1, 0, 0, 43, 2, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 44, 2, 0, 0,139, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 43, 2, 0, 0, 45, 2, 0, 0, 44, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 72, 0, 0, 0, 44, 2, 0, 0, 45, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 45, 2, 0, 0,
+ 43, 2, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,226, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,222, 0, 0, 0, 45, 2, 0, 0,226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 74, 0, 0, 0,226, 0, 0, 0,
+ 45, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 45, 2, 0, 0,222, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 44, 2, 0, 0, 72, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,223, 0, 0, 0,100, 1, 0, 0, 44, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,139, 0, 0, 0, 44, 2, 0, 0,100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,100, 1, 0, 0,
+223, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,105, 1, 0, 0,141, 0, 0, 0, 46, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 46, 2, 0, 0,255, 0, 0, 0,105, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 35, 0, 0, 0,105, 1, 0, 0,
+255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,255, 0, 0, 0, 46, 2, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 47, 2, 0, 0, 88, 0, 0, 0, 46, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 46, 2, 0, 0, 48, 2, 0, 0, 47, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 77, 0, 0, 0, 47, 2, 0, 0, 48, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 48, 2, 0, 0,
+ 46, 2, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,104, 1, 0, 0, 29, 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,233, 0, 0, 0, 48, 2, 0, 0,104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,141, 0, 0, 0,104, 1, 0, 0,
+ 48, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 48, 2, 0, 0,233, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 47, 2, 0, 0, 77, 0, 0, 0,232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 0,254, 0, 0, 0, 47, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 88, 0, 0, 0, 47, 2, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,254, 0, 0, 0,
+232, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,104, 1, 0, 0,141, 0, 0, 0, 49, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 49, 2, 0, 0,106, 1, 0, 0,104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 29, 0, 0, 0,104, 1, 0, 0,
+106, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,106, 1, 0, 0, 49, 2, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 50, 2, 0, 0,142, 0, 0, 0, 49, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 49, 2, 0, 0, 51, 2, 0, 0, 50, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,143, 0, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 2, 0, 0,
+ 49, 2, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,105, 1, 0, 0, 35, 0, 0, 0,109, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,109, 1, 0, 0, 51, 2, 0, 0,105, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,141, 0, 0, 0,105, 1, 0, 0,
+ 51, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 2, 0, 0,109, 1, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 50, 2, 0, 0,143, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,108, 1, 0, 0,107, 1, 0, 0, 50, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,142, 0, 0, 0, 50, 2, 0, 0,107, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 1, 0, 0,
+108, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,236, 0, 0, 0, 79, 0, 0, 0, 52, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 52, 2, 0, 0, 0, 1, 0, 0,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 0, 0, 0,236, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 52, 2, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 53, 2, 0, 0, 89, 0, 0, 0, 52, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 52, 2, 0, 0, 54, 2, 0, 0, 53, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,143, 0, 0, 0, 53, 2, 0, 0, 54, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54, 2, 0, 0,
+ 52, 2, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,237, 0, 0, 0, 30, 0, 0, 0,108, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,108, 1, 0, 0, 54, 2, 0, 0,237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 79, 0, 0, 0,237, 0, 0, 0,
+ 54, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54, 2, 0, 0,108, 1, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 53, 2, 0, 0,143, 0, 0, 0,109, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,109, 1, 0, 0, 1, 1, 0, 0, 53, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 89, 0, 0, 0, 53, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0,
+109, 1, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,235, 0, 0, 0, 78, 0, 0, 0, 55, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 55, 2, 0, 0,107, 1, 0, 0,235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 30, 0, 0, 0,235, 0, 0, 0,
+107, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 1, 0, 0, 55, 2, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 56, 2, 0, 0,142, 0, 0, 0, 55, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 55, 2, 0, 0, 57, 2, 0, 0, 56, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 76, 0, 0, 0, 56, 2, 0, 0, 57, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 57, 2, 0, 0,
+ 55, 2, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,234, 0, 0, 0, 4, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,230, 0, 0, 0, 57, 2, 0, 0,234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 0, 0, 0,234, 0, 0, 0,
+ 57, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 57, 2, 0, 0,230, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 56, 2, 0, 0, 76, 0, 0, 0,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,231, 0, 0, 0,106, 1, 0, 0, 56, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,142, 0, 0, 0, 56, 2, 0, 0,106, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,106, 1, 0, 0,
+231, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 1, 0, 0,144, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 58, 2, 0, 0, 3, 1, 0, 0,111, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 36, 0, 0, 0,111, 1, 0, 0,
+ 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 0, 0, 58, 2, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 59, 2, 0, 0, 90, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 58, 2, 0, 0, 60, 2, 0, 0, 59, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 81, 0, 0, 0, 59, 2, 0, 0, 60, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 60, 2, 0, 0,
+ 58, 2, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,110, 1, 0, 0, 31, 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,241, 0, 0, 0, 60, 2, 0, 0,110, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,144, 0, 0, 0,110, 1, 0, 0,
+ 60, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 60, 2, 0, 0,241, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 59, 2, 0, 0, 81, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,240, 0, 0, 0, 2, 1, 0, 0, 59, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 90, 0, 0, 0, 59, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 0, 0,
+240, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,110, 1, 0, 0,144, 0, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 61, 2, 0, 0,113, 1, 0, 0,110, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 31, 0, 0, 0,110, 1, 0, 0,
+113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,113, 1, 0, 0, 61, 2, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 62, 2, 0, 0,145, 0, 0, 0, 61, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 61, 2, 0, 0, 63, 2, 0, 0, 62, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,146, 0, 0, 0, 62, 2, 0, 0, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 63, 2, 0, 0,
+ 61, 2, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 1, 0, 0, 36, 0, 0, 0,115, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,115, 1, 0, 0, 63, 2, 0, 0,111, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,144, 0, 0, 0,111, 1, 0, 0,
+ 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 63, 2, 0, 0,115, 1, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 62, 2, 0, 0,146, 0, 0, 0,114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,114, 1, 0, 0,112, 1, 0, 0, 62, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,145, 0, 0, 0, 62, 2, 0, 0,112, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,112, 1, 0, 0,
+114, 1, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,204, 0, 0, 0, 63, 0, 0, 0, 64, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 64, 2, 0, 0, 4, 1, 0, 0,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 0, 0, 0,204, 0, 0, 0,
+ 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 1, 0, 0, 64, 2, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 65, 2, 0, 0, 91, 0, 0, 0, 64, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 64, 2, 0, 0, 66, 2, 0, 0, 65, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,146, 0, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 66, 2, 0, 0,
+ 64, 2, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,205, 0, 0, 0, 22, 0, 0, 0,114, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,114, 1, 0, 0, 66, 2, 0, 0,205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 63, 0, 0, 0,205, 0, 0, 0,
+ 66, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 66, 2, 0, 0,114, 1, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 65, 2, 0, 0,146, 0, 0, 0,115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,115, 1, 0, 0, 5, 1, 0, 0, 65, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 91, 0, 0, 0, 65, 2, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 1, 0, 0,
+115, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,203, 0, 0, 0, 62, 0, 0, 0, 67, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 67, 2, 0, 0,112, 1, 0, 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 22, 0, 0, 0,203, 0, 0, 0,
+112, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,112, 1, 0, 0, 67, 2, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 68, 2, 0, 0,145, 0, 0, 0, 67, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 67, 2, 0, 0, 69, 2, 0, 0, 68, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 80, 0, 0, 0, 68, 2, 0, 0, 69, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 69, 2, 0, 0,
+ 67, 2, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,202, 0, 0, 0, 5, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,238, 0, 0, 0, 69, 2, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 62, 0, 0, 0,202, 0, 0, 0,
+ 69, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 69, 2, 0, 0,238, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 68, 2, 0, 0, 80, 0, 0, 0,239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,239, 0, 0, 0,113, 1, 0, 0, 68, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,145, 0, 0, 0, 68, 2, 0, 0,113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,113, 1, 0, 0,
+239, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 70, 2, 0, 0,147, 0, 0, 0,117, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,117, 1, 0, 0, 11, 1, 0, 0, 70, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 94, 0, 0, 0, 70, 2, 0, 0,
+ 11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 11, 1, 0, 0,117, 1, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 70, 2, 0, 0, 94, 0, 0, 0, 71, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 2, 0, 0, 72, 2, 0, 0, 70, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,147, 0, 0, 0, 70, 2, 0, 0, 72, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 72, 2, 0, 0,
+ 71, 2, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,243, 0, 0, 0, 32, 0, 0, 0,116, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,116, 1, 0, 0, 72, 2, 0, 0,243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 82, 0, 0, 0,243, 0, 0, 0,
+ 72, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 72, 2, 0, 0,116, 1, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+242, 0, 0, 0, 82, 0, 0, 0, 71, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 2, 0, 0, 10, 1, 0, 0,242, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 6, 0, 0, 0,242, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 10, 1, 0, 0,
+ 71, 2, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 73, 2, 0, 0,147, 0, 0, 0,116, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,116, 1, 0, 0,118, 1, 0, 0, 73, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,148, 0, 0, 0, 73, 2, 0, 0,
+118, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,118, 1, 0, 0,116, 1, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 73, 2, 0, 0,148, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 74, 2, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,147, 0, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 75, 2, 0, 0,
+ 74, 2, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,121, 1, 0, 0, 38, 0, 0, 0,117, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,117, 1, 0, 0, 75, 2, 0, 0,121, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,149, 0, 0, 0,121, 1, 0, 0,
+ 75, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 75, 2, 0, 0,117, 1, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+120, 1, 0, 0,149, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 74, 2, 0, 0,119, 1, 0, 0,120, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 37, 0, 0, 0,120, 1, 0, 0,119, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 1, 0, 0,
+ 74, 2, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 76, 2, 0, 0, 93, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 8, 1, 0, 0, 12, 1, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 95, 0, 0, 0, 76, 2, 0, 0,
+ 12, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 12, 1, 0, 0, 8, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 76, 2, 0, 0, 95, 0, 0, 0, 77, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 77, 2, 0, 0, 78, 2, 0, 0, 76, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 93, 0, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 2, 0, 0,
+ 77, 2, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,120, 1, 0, 0, 37, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 9, 1, 0, 0, 78, 2, 0, 0,120, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,149, 0, 0, 0,120, 1, 0, 0,
+ 78, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 78, 2, 0, 0, 9, 1, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+121, 1, 0, 0,149, 0, 0, 0, 77, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 77, 2, 0, 0, 13, 1, 0, 0,121, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 38, 0, 0, 0,121, 1, 0, 0, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 13, 1, 0, 0,
+ 77, 2, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 79, 2, 0, 0, 92, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 7, 1, 0, 0,119, 1, 0, 0, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,148, 0, 0, 0, 79, 2, 0, 0,
+119, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 1, 0, 0, 7, 1, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 79, 2, 0, 0,148, 0, 0, 0, 80, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 80, 2, 0, 0, 81, 2, 0, 0, 79, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 92, 0, 0, 0, 79, 2, 0, 0, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 81, 2, 0, 0,
+ 80, 2, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,244, 0, 0, 0, 10, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 6, 1, 0, 0, 81, 2, 0, 0,244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 83, 0, 0, 0,244, 0, 0, 0,
+ 81, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 81, 2, 0, 0, 6, 1, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+245, 0, 0, 0, 83, 0, 0, 0, 80, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 80, 2, 0, 0,118, 1, 0, 0,245, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 32, 0, 0, 0,245, 0, 0, 0,118, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,118, 1, 0, 0,
+ 80, 2, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 82, 2, 0, 0,150, 0, 0, 0,123, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,123, 1, 0, 0, 15, 1, 0, 0, 82, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 96, 0, 0, 0, 82, 2, 0, 0,
+ 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 1, 0, 0,123, 1, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 82, 2, 0, 0, 96, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 83, 2, 0, 0, 84, 2, 0, 0, 82, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,150, 0, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 84, 2, 0, 0,
+ 83, 2, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,249, 0, 0, 0, 33, 0, 0, 0,122, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,122, 1, 0, 0, 84, 2, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 85, 0, 0, 0,249, 0, 0, 0,
+ 84, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 84, 2, 0, 0,122, 1, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+248, 0, 0, 0, 85, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 83, 2, 0, 0, 14, 1, 0, 0,248, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 7, 0, 0, 0,248, 0, 0, 0, 14, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 14, 1, 0, 0,
+ 83, 2, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 85, 2, 0, 0,150, 0, 0, 0,122, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,122, 1, 0, 0,124, 1, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,151, 0, 0, 0, 85, 2, 0, 0,
+124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,124, 1, 0, 0,122, 1, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 85, 2, 0, 0,151, 0, 0, 0, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 86, 2, 0, 0, 87, 2, 0, 0, 85, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,150, 0, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, 2, 0, 0,
+ 86, 2, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,127, 1, 0, 0, 39, 0, 0, 0,123, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,123, 1, 0, 0, 87, 2, 0, 0,127, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152, 0, 0, 0,127, 1, 0, 0,
+ 87, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, 2, 0, 0,123, 1, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+126, 1, 0, 0,152, 0, 0, 0, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 86, 2, 0, 0,125, 1, 0, 0,126, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 38, 0, 0, 0,126, 1, 0, 0,125, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 1, 0, 0,
+ 86, 2, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 88, 2, 0, 0, 95, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 12, 1, 0, 0, 16, 1, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 97, 0, 0, 0, 88, 2, 0, 0,
+ 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 16, 1, 0, 0, 12, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 88, 2, 0, 0, 97, 0, 0, 0, 89, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 89, 2, 0, 0, 90, 2, 0, 0, 88, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 95, 0, 0, 0, 88, 2, 0, 0, 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 90, 2, 0, 0,
+ 89, 2, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,126, 1, 0, 0, 38, 0, 0, 0, 13, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 13, 1, 0, 0, 90, 2, 0, 0,126, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152, 0, 0, 0,126, 1, 0, 0,
+ 90, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 90, 2, 0, 0, 13, 1, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+127, 1, 0, 0,152, 0, 0, 0, 89, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 89, 2, 0, 0, 17, 1, 0, 0,127, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 39, 0, 0, 0,127, 1, 0, 0, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 17, 1, 0, 0,
+ 89, 2, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 91, 2, 0, 0, 94, 0, 0, 0, 11, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 11, 1, 0, 0,125, 1, 0, 0, 91, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,151, 0, 0, 0, 91, 2, 0, 0,
+125, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 1, 0, 0, 11, 1, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 91, 2, 0, 0,151, 0, 0, 0, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 92, 2, 0, 0, 93, 2, 0, 0, 91, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 94, 0, 0, 0, 91, 2, 0, 0, 93, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 93, 2, 0, 0,
+ 92, 2, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,246, 0, 0, 0, 6, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 10, 1, 0, 0, 93, 2, 0, 0,246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 84, 0, 0, 0,246, 0, 0, 0,
+ 93, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 93, 2, 0, 0, 10, 1, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+247, 0, 0, 0, 84, 0, 0, 0, 92, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 92, 2, 0, 0,124, 1, 0, 0,247, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 33, 0, 0, 0,247, 0, 0, 0,124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,124, 1, 0, 0,
+ 92, 2, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 94, 2, 0, 0,153, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,129, 1, 0, 0, 19, 1, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 0, 0, 0, 94, 2, 0, 0,
+ 19, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 1, 0, 0,129, 1, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 94, 2, 0, 0, 98, 0, 0, 0, 95, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 95, 2, 0, 0, 96, 2, 0, 0, 94, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,153, 0, 0, 0, 94, 2, 0, 0, 96, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 96, 2, 0, 0,
+ 95, 2, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,253, 0, 0, 0, 34, 0, 0, 0,128, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,128, 1, 0, 0, 96, 2, 0, 0,253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, 0, 0, 0,253, 0, 0, 0,
+ 96, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 96, 2, 0, 0,128, 1, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+252, 0, 0, 0, 87, 0, 0, 0, 95, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 95, 2, 0, 0, 18, 1, 0, 0,252, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 8, 0, 0, 0,252, 0, 0, 0, 18, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 1, 0, 0,
+ 95, 2, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 97, 2, 0, 0,153, 0, 0, 0,128, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,128, 1, 0, 0,130, 1, 0, 0, 97, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,154, 0, 0, 0, 97, 2, 0, 0,
+130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,130, 1, 0, 0,128, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 97, 2, 0, 0,154, 0, 0, 0, 98, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 2, 0, 0, 99, 2, 0, 0, 97, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,153, 0, 0, 0, 97, 2, 0, 0, 99, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 99, 2, 0, 0,
+ 98, 2, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,133, 1, 0, 0, 40, 0, 0, 0,129, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,129, 1, 0, 0, 99, 2, 0, 0,133, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,155, 0, 0, 0,133, 1, 0, 0,
+ 99, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 99, 2, 0, 0,129, 1, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+132, 1, 0, 0,155, 0, 0, 0, 98, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 98, 2, 0, 0,131, 1, 0, 0,132, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 39, 0, 0, 0,132, 1, 0, 0,131, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,131, 1, 0, 0,
+ 98, 2, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,100, 2, 0, 0, 97, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 16, 1, 0, 0, 20, 1, 0, 0,100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 99, 0, 0, 0,100, 2, 0, 0,
+ 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 1, 0, 0, 16, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+100, 2, 0, 0, 99, 0, 0, 0,101, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,101, 2, 0, 0,102, 2, 0, 0,100, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 97, 0, 0, 0,100, 2, 0, 0,102, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,102, 2, 0, 0,
+101, 2, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,132, 1, 0, 0, 39, 0, 0, 0, 17, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 17, 1, 0, 0,102, 2, 0, 0,132, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,155, 0, 0, 0,132, 1, 0, 0,
+102, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,102, 2, 0, 0, 17, 1, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+133, 1, 0, 0,155, 0, 0, 0,101, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,101, 2, 0, 0, 21, 1, 0, 0,133, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 40, 0, 0, 0,133, 1, 0, 0, 21, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 21, 1, 0, 0,
+101, 2, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,103, 2, 0, 0, 96, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 15, 1, 0, 0,131, 1, 0, 0,103, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,154, 0, 0, 0,103, 2, 0, 0,
+131, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,131, 1, 0, 0, 15, 1, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+103, 2, 0, 0,154, 0, 0, 0,104, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,104, 2, 0, 0,105, 2, 0, 0,103, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 96, 0, 0, 0,103, 2, 0, 0,105, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,105, 2, 0, 0,
+104, 2, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,250, 0, 0, 0, 7, 0, 0, 0, 14, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 14, 1, 0, 0,105, 2, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 86, 0, 0, 0,250, 0, 0, 0,
+105, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,105, 2, 0, 0, 14, 1, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+251, 0, 0, 0, 86, 0, 0, 0,104, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,104, 2, 0, 0,130, 1, 0, 0,251, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 34, 0, 0, 0,251, 0, 0, 0,130, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,130, 1, 0, 0,
+104, 2, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,106, 2, 0, 0,156, 0, 0, 0,135, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,135, 1, 0, 0, 23, 1, 0, 0,106, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,100, 0, 0, 0,106, 2, 0, 0,
+ 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 23, 1, 0, 0,135, 1, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+106, 2, 0, 0,100, 0, 0, 0,107, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 2, 0, 0,108, 2, 0, 0,106, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,156, 0, 0, 0,106, 2, 0, 0,108, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,108, 2, 0, 0,
+107, 2, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 35, 0, 0, 0,134, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,134, 1, 0, 0,108, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 89, 0, 0, 0, 1, 1, 0, 0,
+108, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,108, 2, 0, 0,134, 1, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 1, 0, 0, 89, 0, 0, 0,107, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,107, 2, 0, 0, 22, 1, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 9, 0, 0, 0, 0, 1, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 22, 1, 0, 0,
+107, 2, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,109, 2, 0, 0,156, 0, 0, 0,134, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,134, 1, 0, 0,136, 1, 0, 0,109, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,157, 0, 0, 0,109, 2, 0, 0,
+136, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,136, 1, 0, 0,134, 1, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+109, 2, 0, 0,157, 0, 0, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,110, 2, 0, 0,111, 2, 0, 0,109, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,156, 0, 0, 0,109, 2, 0, 0,111, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 2, 0, 0,
+110, 2, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,139, 1, 0, 0, 41, 0, 0, 0,135, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,135, 1, 0, 0,111, 2, 0, 0,139, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,158, 0, 0, 0,139, 1, 0, 0,
+111, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,111, 2, 0, 0,135, 1, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+138, 1, 0, 0,158, 0, 0, 0,110, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,110, 2, 0, 0,137, 1, 0, 0,138, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 40, 0, 0, 0,138, 1, 0, 0,137, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,137, 1, 0, 0,
+110, 2, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,112, 2, 0, 0, 99, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 20, 1, 0, 0, 24, 1, 0, 0,112, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,101, 0, 0, 0,112, 2, 0, 0,
+ 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 24, 1, 0, 0, 20, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+112, 2, 0, 0,101, 0, 0, 0,113, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,113, 2, 0, 0,114, 2, 0, 0,112, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 99, 0, 0, 0,112, 2, 0, 0,114, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,114, 2, 0, 0,
+113, 2, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,138, 1, 0, 0, 40, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 21, 1, 0, 0,114, 2, 0, 0,138, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,158, 0, 0, 0,138, 1, 0, 0,
+114, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,114, 2, 0, 0, 21, 1, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+139, 1, 0, 0,158, 0, 0, 0,113, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,113, 2, 0, 0, 25, 1, 0, 0,139, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 41, 0, 0, 0,139, 1, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 25, 1, 0, 0,
+113, 2, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,115, 2, 0, 0, 98, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 19, 1, 0, 0,137, 1, 0, 0,115, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,157, 0, 0, 0,115, 2, 0, 0,
+137, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,137, 1, 0, 0, 19, 1, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+115, 2, 0, 0,157, 0, 0, 0,116, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,116, 2, 0, 0,117, 2, 0, 0,115, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 98, 0, 0, 0,115, 2, 0, 0,117, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,117, 2, 0, 0,
+116, 2, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,254, 0, 0, 0, 8, 0, 0, 0, 18, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 18, 1, 0, 0,117, 2, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 88, 0, 0, 0,254, 0, 0, 0,
+117, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,117, 2, 0, 0, 18, 1, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+255, 0, 0, 0, 88, 0, 0, 0,116, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,116, 2, 0, 0,136, 1, 0, 0,255, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 35, 0, 0, 0,255, 0, 0, 0,136, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,136, 1, 0, 0,
+116, 2, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,118, 2, 0, 0,159, 0, 0, 0,141, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,141, 1, 0, 0, 7, 1, 0, 0,118, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 92, 0, 0, 0,118, 2, 0, 0,
+ 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 1, 0, 0,141, 1, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+118, 2, 0, 0, 92, 0, 0, 0,119, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 2, 0, 0,120, 2, 0, 0,118, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,159, 0, 0, 0,118, 2, 0, 0,120, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,120, 2, 0, 0,
+119, 2, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 1, 0, 0, 36, 0, 0, 0,140, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,140, 1, 0, 0,120, 2, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 91, 0, 0, 0, 5, 1, 0, 0,
+120, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,120, 2, 0, 0,140, 1, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 4, 1, 0, 0, 91, 0, 0, 0,119, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,119, 2, 0, 0, 6, 1, 0, 0, 4, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 10, 0, 0, 0, 4, 1, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 1, 0, 0,
+119, 2, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,121, 2, 0, 0,159, 0, 0, 0,140, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,140, 1, 0, 0,142, 1, 0, 0,121, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,160, 0, 0, 0,121, 2, 0, 0,
+142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,142, 1, 0, 0,140, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+121, 2, 0, 0,160, 0, 0, 0,122, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,122, 2, 0, 0,123, 2, 0, 0,121, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,159, 0, 0, 0,121, 2, 0, 0,123, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,123, 2, 0, 0,
+122, 2, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,144, 1, 0, 0, 37, 0, 0, 0,141, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3,141, 1, 0, 0,123, 2, 0, 0,144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,161, 0, 0, 0,144, 1, 0, 0,
+123, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,123, 2, 0, 0,141, 1, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+145, 1, 0, 0,161, 0, 0, 0,122, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,122, 2, 0, 0,143, 1, 0, 0,145, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 41, 0, 0, 0,145, 1, 0, 0,143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,143, 1, 0, 0,
+122, 2, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,124, 2, 0, 0,101, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 24, 1, 0, 0, 8, 1, 0, 0,124, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 93, 0, 0, 0,124, 2, 0, 0,
+ 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 1, 0, 0, 24, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+124, 2, 0, 0, 93, 0, 0, 0,125, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 2, 0, 0,126, 2, 0, 0,124, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,101, 0, 0, 0,124, 2, 0, 0,126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,126, 2, 0, 0,
+125, 2, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,145, 1, 0, 0, 41, 0, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 25, 1, 0, 0,126, 2, 0, 0,145, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,161, 0, 0, 0,145, 1, 0, 0,
+126, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,126, 2, 0, 0, 25, 1, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+144, 1, 0, 0,161, 0, 0, 0,125, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,125, 2, 0, 0, 9, 1, 0, 0,144, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 37, 0, 0, 0,144, 1, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 1, 0, 0,
+125, 2, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,127, 2, 0, 0,100, 0, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 23, 1, 0, 0,143, 1, 0, 0,127, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,160, 0, 0, 0,127, 2, 0, 0,
+143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,143, 1, 0, 0, 23, 1, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+127, 2, 0, 0,160, 0, 0, 0,128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,128, 2, 0, 0,129, 2, 0, 0,127, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3,100, 0, 0, 0,127, 2, 0, 0,129, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,129, 2, 0, 0,
+128, 2, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 0, 0, 9, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 22, 1, 0, 0,129, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 90, 0, 0, 0, 2, 1, 0, 0,
+129, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,129, 2, 0, 0, 22, 1, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 3, 1, 0, 0, 90, 0, 0, 0,128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,128, 2, 0, 0,142, 1, 0, 0, 3, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 36, 0, 0, 0, 3, 1, 0, 0,142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,142, 1, 0, 0,
+128, 2, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 68, 65, 84, 65, 0,220, 0, 0, 8, 75, 18, 3, 61, 0, 0, 0,
+ 0, 5, 0, 0,166,222,110, 63, 9,205, 55, 63,212,132,105, 63,201,236, 65, 63,218,153,103, 63,119,155, 54, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218,153,103, 63,119,155, 54, 63,118,148,108, 63,211,160, 44, 63,
+166,222,110, 63, 9,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63,
+ 36, 28, 45, 63,166,222,110, 63, 9,205, 55, 63,118,148,108, 63,211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,118,148,108, 63,211,160, 44, 63,218,153,103, 63,119,155, 54, 63, 87, 17,102, 63,229, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 56, 81, 96, 63,170, 55, 52, 63, 87, 17,102, 63,
+229, 52, 43, 63,218,153,103, 63,119,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+218,153,103, 63,119,155, 54, 63, 9, 75, 97, 63, 92,233, 63, 63, 56, 81, 96, 63,170, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63, 49, 86, 60, 63, 56, 81, 96, 63,170, 55, 52, 63, 9, 75, 97, 63,
+ 92,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 9, 75, 97, 63, 92,233, 63, 63,
+218,153,103, 63,119,155, 54, 63,212,132,105, 63,201,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,103,167, 98, 63,168, 39, 75, 63,138,153, 89, 63, 39,228, 82, 63,139,153, 89, 63,255,153, 71, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,139,153, 89, 63,255,153, 71, 63, 9, 75, 97, 63, 92,233, 63, 63,
+103,167, 98, 63,168, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,132,105, 63,
+201,236, 65, 63,103,167, 98, 63,168, 39, 75, 63, 9, 75, 97, 63, 92,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 9, 75, 97, 63, 92,233, 63, 63,139,153, 89, 63,255,153, 71, 63,138,153, 89, 63, 49, 86, 60, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 56, 81, 96, 63,170, 55, 52, 63,138,153, 89, 63,
+ 49, 86, 60, 63,139,153, 89, 63, 79, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+139,153, 89, 63, 79, 12, 49, 63,205,182, 95, 63,222,228, 40, 63, 56, 81, 96, 63,170, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87, 17,102, 63,229, 52, 43, 63, 56, 81, 96, 63,170, 55, 52, 63,205,182, 95, 63,
+222,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,205,182, 95, 63,222,228, 40, 63,
+139,153, 89, 63, 79, 12, 49, 63,139,153, 89, 63, 45,200, 37, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,103,167, 98, 63,168, 39, 75, 63,212,132,105, 63,201,236, 65, 63,168, 83,109, 63,207, 83, 78, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,168, 83,109, 63,207, 83, 78, 63,135, 85,101, 63,148, 64, 88, 63,
+103,167, 98, 63,168, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63,
+ 39,228, 82, 63,103,167, 98, 63,168, 39, 75, 63,135, 85,101, 63,148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,135, 85,101, 63,148, 64, 88, 63,168, 83,109, 63,207, 83, 78, 63, 36, 51,115, 63, 22, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,162, 18,121, 63,207, 83, 78, 63, 36, 51,115, 63,
+ 22, 56, 90, 63,168, 83,109, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+168, 83,109, 63,207, 83, 78, 63, 36, 51,115, 63,115, 23, 67, 63,162, 18,121, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,116,225,124, 63,202,236, 65, 63,162, 18,121, 63,207, 83, 78, 63, 36, 51,115, 63,
+115, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63,115, 23, 67, 63,
+168, 83,109, 63,207, 83, 78, 63,212,132,105, 63,201,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,166,222,110, 63, 9,205, 55, 63, 36, 51,115, 63, 36, 28, 45, 63,163,135,119, 63, 11,205, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,163,135,119, 63, 11,205, 55, 63, 36, 51,115, 63,115, 23, 67, 63,
+166,222,110, 63, 9,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,132,105, 63,
+201,236, 65, 63,166,222,110, 63, 9,205, 55, 63, 36, 51,115, 63,115, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63,115, 23, 67, 63,163,135,119, 63, 11,205, 55, 63,116,225,124, 63,202,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,162, 18,121, 63,207, 83, 78, 63,116,225,124, 63,
+202,236, 65, 63,113,223,129, 63,170, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+113,223,129, 63,170, 39, 75, 63, 98,136,128, 63,148, 64, 88, 63,162, 18,121, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63, 22, 56, 90, 63,162, 18,121, 63,207, 83, 78, 63, 98,136,128, 63,
+148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 95, 98,136, 59,148, 64, 88, 63,
+160,184,111, 60,170, 39, 75, 63,243,203, 76, 61, 41,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,243,203, 76, 61, 82, 12, 49, 63,246,203, 76, 61, 53, 86, 60, 63, 31,162,194, 60,172, 55, 52, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 31,162,194, 60,172, 55, 52, 63,111,239,213, 60,223,228, 40, 63,
+243,203, 76, 61, 82, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,246,203, 76, 61,
+ 48,200, 37, 63,243,203, 76, 61, 82, 12, 49, 63,111,239,213, 60,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,111,239,213, 60,223,228, 40, 63, 31,162,194, 60,172, 55, 52, 63,120,226,169, 58,230, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,111,204,126, 63,121,155, 54, 63,121, 42,128, 63,
+230, 52, 43, 63,136, 10,131, 63,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+136, 10,131, 63,172, 55, 52, 63,160,141,130, 63, 95,233, 63, 63,111,204,126, 63,121,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,116,225,124, 63,202,236, 65, 63,111,204,126, 63,121,155, 54, 63,160,141,130, 63,
+ 95,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 11,104,163, 60, 95,233, 63, 63,
+ 31,162,194, 60,172, 55, 52, 63,246,203, 76, 61, 53, 86, 60, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,244,203, 76, 61, 2,154, 71, 63,243,203, 76, 61, 41,228, 82, 63,160,184,111, 60,170, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,160,184,111, 60,170, 39, 75, 63, 11,104,163, 60, 95,233, 63, 63,
+244,203, 76, 61, 2,154, 71, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,246,203, 76, 61,
+ 53, 86, 60, 63,244,203, 76, 61, 2,154, 71, 63, 11,104,163, 60, 95,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,160,141,130, 63, 95,233, 63, 63,113,223,129, 63,170, 39, 75, 63,116,225,124, 63,202,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,111,204,126, 63,121,155, 54, 63,116,225,124, 63,
+202,236, 65, 63,163,135,119, 63, 11,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+163,135,119, 63, 11,205, 55, 63,210,209,121, 63,212,160, 44, 63,111,204,126, 63,121,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,121, 42,128, 63,230, 52, 43, 63,111,204,126, 63,121,155, 54, 63,210,209,121, 63,
+212,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,210,209,121, 63,212,160, 44, 63,
+163,135,119, 63, 11,205, 55, 63, 36, 51,115, 63, 36, 28, 45, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 95,102,134, 63, 79, 46, 94, 63, 95,102,134, 63, 22,114,105, 63, 52,205,124, 63, 58, 26, 99, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 52,205,124, 63, 58, 26, 99, 63, 98,136,128, 63,148, 64, 88, 63,
+ 95,102,134, 63, 79, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,243,203, 76, 61,
+ 41,228, 82, 63,234,203, 76, 61, 79, 46, 94, 63, 95, 98,136, 59,148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 98,136,128, 63,148, 64, 88, 63, 52,205,124, 63, 58, 26, 99, 63, 36, 51,115, 63, 22, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,153,105, 63, 58, 26, 99, 63, 36, 51,115, 63,
+ 22, 56, 90, 63, 52,205,124, 63, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 52,205,124, 63, 58, 26, 99, 63, 32, 51,115, 63,212,154,109, 63, 21,153,105, 63, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63, 19,114,105, 63, 21,153,105, 63, 58, 26, 99, 63, 32, 51,115, 63,
+212,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 32, 51,115, 63,212,154,109, 63,
+ 52,205,124, 63, 58, 26, 99, 63, 95,102,134, 63, 22,114,105, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 95,102,134, 63,242,187,116, 63, 3,153, 59, 63, 0, 0,128, 63,136,153, 89, 63,242,187,116, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,136,153, 89, 63,242,187,116, 63, 32, 51,115, 63,212,154,109, 63,
+ 95,102,134, 63,242,187,116, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 95,102,134, 63,
+ 22,114,105, 63, 95,102,134, 63,242,187,116, 63, 32, 51,115, 63,212,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 32, 51,115, 63,212,154,109, 63,136,153, 89, 63,242,187,116, 63,138,153, 89, 63, 19,114,105, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,153,105, 63, 58, 26, 99, 63,138,153, 89, 63,
+ 19,114,105, 63,138,153, 89, 63, 77, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+138,153, 89, 63, 77, 46, 94, 63,135, 85,101, 63,148, 64, 88, 63, 21,153,105, 63, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63, 22, 56, 90, 63, 21,153,105, 63, 58, 26, 99, 63,135, 85,101, 63,
+148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,135, 85,101, 63,148, 64, 88, 63,
+138,153, 89, 63, 77, 46, 94, 63,138,153, 89, 63, 39,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 67,153, 75, 63,113,155, 54, 63, 74,174, 73, 63,193,236, 65, 63,124, 84, 68, 63,255,204, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,124, 84, 68, 63,255,204, 55, 63,169,158, 70, 63,200,160, 44, 63,
+ 67,153, 75, 63,113,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,196, 33, 77, 63,
+221, 52, 43, 63, 67,153, 75, 63,113,155, 54, 63,169,158, 70, 63,200,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,169,158, 70, 63,200,160, 44, 63,124, 84, 68, 63,255,204, 55, 63, 0, 0, 64, 63, 24, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 67,153, 75, 63,113,155, 54, 63,196, 33, 77, 63,
+221, 52, 43, 63,225,225, 82, 63,165, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+225,225, 82, 63,165, 55, 52, 63, 16,232, 81, 63, 89,233, 63, 63, 67,153, 75, 63,113,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 74,174, 73, 63,193,236, 65, 63, 67,153, 75, 63,113,155, 54, 63, 16,232, 81, 63,
+ 89,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 16,232, 81, 63, 89,233, 63, 63,
+225,225, 82, 63,165, 55, 52, 63,138,153, 89, 63, 49, 86, 60, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,139,153, 89, 63,255,153, 71, 63,138,153, 89, 63, 39,228, 82, 63,179,139, 80, 63,164, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,139, 80, 63,164, 39, 75, 63, 16,232, 81, 63, 89,233, 63, 63,
+139,153, 89, 63,255,153, 71, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63,
+ 49, 86, 60, 63,139,153, 89, 63,255,153, 71, 63, 16,232, 81, 63, 89,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 16,232, 81, 63, 89,233, 63, 63,179,139, 80, 63,164, 39, 75, 63, 74,174, 73, 63,193,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,139,153, 89, 63, 79, 12, 49, 63,138,153, 89, 63,
+ 49, 86, 60, 63,225,225, 82, 63,165, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+225,225, 82, 63,165, 55, 52, 63, 75,124, 83, 63,217,228, 40, 63,139,153, 89, 63, 79, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,139,153, 89, 63, 45,200, 37, 63,139,153, 89, 63, 79, 12, 49, 63, 75,124, 83, 63,
+217,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 75,124, 83, 63,217,228, 40, 63,
+225,225, 82, 63,165, 55, 52, 63,196, 33, 77, 63,221, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,120,223, 69, 63,198, 83, 78, 63, 74,174, 73, 63,193,236, 65, 63,179,139, 80, 63,164, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,139, 80, 63,164, 39, 75, 63,148,221, 77, 63,140, 64, 88, 63,
+120,223, 69, 63,198, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+ 12, 56, 90, 63,120,223, 69, 63,198, 83, 78, 63,148,221, 77, 63,140, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,148,221, 77, 63,140, 64, 88, 63,179,139, 80, 63,164, 39, 75, 63,138,153, 89, 63, 39,228, 82, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,120,223, 69, 63,198, 83, 78, 63, 0, 0, 64, 63,
+ 12, 56, 90, 63,136, 32, 58, 63,198, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+136, 32, 58, 63,198, 83, 78, 63, 0, 0, 64, 63,106, 23, 67, 63,120,223, 69, 63,198, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 74,174, 73, 63,193,236, 65, 63,120,223, 69, 63,198, 83, 78, 63, 0, 0, 64, 63,
+106, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,106, 23, 67, 63,
+136, 32, 58, 63,198, 83, 78, 63,182, 81, 54, 63,193,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,132,171, 59, 63,255,204, 55, 63, 0, 0, 64, 63, 24, 28, 45, 63,124, 84, 68, 63,255,204, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,124, 84, 68, 63,255,204, 55, 63, 0, 0, 64, 63,106, 23, 67, 63,
+132,171, 59, 63,255,204, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,182, 81, 54, 63,
+193,236, 65, 63,132,171, 59, 63,255,204, 55, 63, 0, 0, 64, 63,106, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,106, 23, 67, 63,124, 84, 68, 63,255,204, 55, 63, 74,174, 73, 63,193,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 77,116, 47, 63,164, 39, 75, 63,182, 81, 54, 63,
+193,236, 65, 63,136, 32, 58, 63,198, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+136, 32, 58, 63,198, 83, 78, 63,108, 34, 50, 63,140, 64, 88, 63, 77,116, 47, 63,164, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,102, 38, 63, 38,228, 82, 63, 77,116, 47, 63,164, 39, 75, 63,108, 34, 50, 63,
+140, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,108, 34, 50, 63,140, 64, 88, 63,
+136, 32, 58, 63,198, 83, 78, 63, 0, 0, 64, 63, 12, 56, 90, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 31, 30, 45, 63,165, 55, 52, 63,117,102, 38, 63, 50, 86, 60, 63,117,102, 38, 63, 78, 12, 49, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63, 78, 12, 49, 63,181,131, 44, 63,216,228, 40, 63,
+ 31, 30, 45, 63,165, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 60,222, 50, 63,
+221, 52, 43, 63, 31, 30, 45, 63,165, 55, 52, 63,181,131, 44, 63,216,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,181,131, 44, 63,216,228, 40, 63,117,102, 38, 63, 78, 12, 49, 63,117,102, 38, 63, 45,200, 37, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 31, 30, 45, 63,165, 55, 52, 63, 60,222, 50, 63,
+221, 52, 43, 63,189,102, 52, 63,113,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+189,102, 52, 63,113,155, 54, 63,240, 23, 46, 63, 89,233, 63, 63, 31, 30, 45, 63,165, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63, 50, 86, 60, 63, 31, 30, 45, 63,165, 55, 52, 63,240, 23, 46, 63,
+ 89,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,240, 23, 46, 63, 89,233, 63, 63,
+189,102, 52, 63,113,155, 54, 63,182, 81, 54, 63,193,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 77,116, 47, 63,164, 39, 75, 63,118,102, 38, 63, 38,228, 82, 63,117,102, 38, 63,255,153, 71, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63,255,153, 71, 63,240, 23, 46, 63, 89,233, 63, 63,
+ 77,116, 47, 63,164, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,182, 81, 54, 63,
+193,236, 65, 63, 77,116, 47, 63,164, 39, 75, 63,240, 23, 46, 63, 89,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,240, 23, 46, 63, 89,233, 63, 63,117,102, 38, 63,255,153, 71, 63,117,102, 38, 63, 50, 86, 60, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,132,171, 59, 63,255,204, 55, 63,182, 81, 54, 63,
+193,236, 65, 63,189,102, 52, 63,113,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+189,102, 52, 63,113,155, 54, 63, 87, 97, 57, 63,200,160, 44, 63,132,171, 59, 63,255,204, 55, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63, 24, 28, 45, 63,132,171, 59, 63,255,204, 55, 63, 87, 97, 57, 63,
+200,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87, 97, 57, 63,200,160, 44, 63,
+189,102, 52, 63,113,155, 54, 63, 60,222, 50, 63,221, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,250,101, 54, 63, 51, 26, 99, 63,118,102, 38, 63, 19,114,105, 63,118,102, 38, 63, 77, 46, 94, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,102, 38, 63, 77, 46, 94, 63,108, 34, 50, 63,140, 64, 88, 63,
+250,101, 54, 63, 51, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+ 12, 56, 90, 63,250,101, 54, 63, 51, 26, 99, 63,108, 34, 50, 63,140, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,108, 34, 50, 63,140, 64, 88, 63,118,102, 38, 63, 77, 46, 94, 63,118,102, 38, 63, 38,228, 82, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,250,101, 54, 63, 51, 26, 99, 63, 0, 0, 64, 63,
+ 12, 56, 90, 63, 6,154, 73, 63, 51, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 6,154, 73, 63, 51, 26, 99, 63, 0, 0, 64, 63,206,154,109, 63,250,101, 54, 63, 51, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,102, 38, 63, 19,114,105, 63,250,101, 54, 63, 51, 26, 99, 63, 0, 0, 64, 63,
+206,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,206,154,109, 63,
+ 6,154, 73, 63, 51, 26, 99, 63,138,153, 89, 63, 19,114,105, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,136,153, 89, 63,242,187,116, 63, 3,153, 59, 63, 0, 0,128, 63,120,102, 38, 63,242,187,116, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,120,102, 38, 63,242,187,116, 63, 0, 0, 64, 63,206,154,109, 63,
+136,153, 89, 63,242,187,116, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63,
+ 19,114,105, 63,136,153, 89, 63,242,187,116, 63, 0, 0, 64, 63,206,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,206,154,109, 63,120,102, 38, 63,242,187,116, 63,118,102, 38, 63, 19,114,105, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63, 77, 46, 94, 63,138,153, 89, 63,
+ 19,114,105, 63, 6,154, 73, 63, 51, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 6,154, 73, 63, 51, 26, 99, 63,148,221, 77, 63,140, 64, 88, 63,138,153, 89, 63, 77, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,153, 89, 63, 39,228, 82, 63,138,153, 89, 63, 77, 46, 94, 63,148,221, 77, 63,
+140, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,148,221, 77, 63,140, 64, 88, 63,
+ 6,154, 73, 63, 51, 26, 99, 63, 0, 0, 64, 63, 12, 56, 90, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,167, 71, 8, 62, 7,205, 55, 63,170,192,229, 61,200,236, 65, 63,203,104,214, 61,120,155, 54, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,203,104,214, 61,120,155, 54, 63,201, 61,254, 61,207,160, 44, 63,
+167, 71, 8, 62, 7,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173,153, 25, 62,
+ 27, 28, 45, 63,167, 71, 8, 62, 7,205, 55, 63,201, 61,254, 61,207,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,201, 61,254, 61,207,160, 44, 63,203,104,214, 61,120,155, 54, 63,175, 36,202, 61,228, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,145, 35,156, 61,172, 55, 52, 63,175, 36,202, 61,
+228, 52, 43, 63,203,104,214, 61,120,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+203,104,214, 61,120,155, 54, 63, 32,242,163, 61, 96,233, 63, 63,145, 35,156, 61,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,246,203, 76, 61, 53, 86, 60, 63,145, 35,156, 61,172, 55, 52, 63, 32,242,163, 61,
+ 96,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 32,242,163, 61, 96,233, 63, 63,
+203,104,214, 61,120,155, 54, 63,170,192,229, 61,200,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 17,213,174, 61,171, 39, 75, 63,243,203, 76, 61, 41,228, 82, 63,244,203, 76, 61, 2,154, 71, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,244,203, 76, 61, 2,154, 71, 63, 32,242,163, 61, 96,233, 63, 63,
+ 17,213,174, 61,171, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170,192,229, 61,
+200,236, 65, 63, 17,213,174, 61,171, 39, 75, 63, 32,242,163, 61, 96,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 32,242,163, 61, 96,233, 63, 63,244,203, 76, 61, 2,154, 71, 63,246,203, 76, 61, 53, 86, 60, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,145, 35,156, 61,172, 55, 52, 63,246,203, 76, 61,
+ 53, 86, 60, 63,243,203, 76, 61, 82, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+243,203, 76, 61, 82, 12, 49, 63, 53, 80,151, 61,223,228, 40, 63,145, 35,156, 61,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,175, 36,202, 61,228, 52, 43, 63,145, 35,156, 61,172, 55, 52, 63, 53, 80,151, 61,
+223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 53, 80,151, 61,223,228, 40, 63,
+243,203, 76, 61, 82, 12, 49, 63,246,203, 76, 61, 48,200, 37, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 17,213,174, 61,171, 39, 75, 63,170,192,229, 61,200,236, 65, 63,169, 27, 2, 62,204, 83, 78, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169, 27, 2, 62,204, 83, 78, 63, 23, 70,196, 61,147, 64, 88, 63,
+ 17,213,174, 61,171, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,243,203, 76, 61,
+ 41,228, 82, 63, 17,213,174, 61,171, 39, 75, 63, 23, 70,196, 61,147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 23, 70,196, 61,147, 64, 88, 63,169, 27, 2, 62,204, 83, 78, 63,160,153, 25, 62, 14, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,162, 23, 49, 62,195, 83, 78, 63,160,153, 25, 62,
+ 14, 56, 90, 63,169, 27, 2, 62,204, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+169, 27, 2, 62,204, 83, 78, 63,172,153, 25, 62,108, 23, 67, 63,162, 23, 49, 62,195, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,240, 82, 64, 62,183,236, 65, 63,162, 23, 49, 62,195, 83, 78, 63,172,153, 25, 62,
+108, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,172,153, 25, 62,108, 23, 67, 63,
+169, 27, 2, 62,204, 83, 78, 63,170,192,229, 61,200,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,167, 71, 8, 62, 7,205, 55, 63,173,153, 25, 62, 27, 28, 45, 63,173,235, 42, 62,254,204, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173,235, 42, 62,254,204, 55, 63,172,153, 25, 62,108, 23, 67, 63,
+167, 71, 8, 62, 7,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170,192,229, 61,
+200,236, 65, 63,167, 71, 8, 62, 7,205, 55, 63,172,153, 25, 62,108, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,172,153, 25, 62,108, 23, 67, 63,173,235, 42, 62,254,204, 55, 63,240, 82, 64, 62,183,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,162, 23, 49, 62,195, 83, 78, 63,240, 82, 64, 62,
+183,236, 65, 63,166,200, 91, 62,147, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+166,200, 91, 62,147, 39, 75, 63, 34, 16, 81, 62,131, 64, 88, 63,162, 23, 49, 62,195, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,160,153, 25, 62, 14, 56, 90, 63,162, 23, 49, 62,195, 83, 78, 63, 34, 16, 81, 62,
+131, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 34, 16, 81, 62,131, 64, 88, 63,
+166,200, 91, 62,147, 39, 75, 63, 0, 0,128, 62, 13,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 62, 47, 12, 49, 63, 0, 0,128, 62, 19, 86, 60, 63, 92, 33,101, 62,146, 55, 52, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 92, 33,101, 62,146, 55, 52, 63, 14,139,103, 62,199,228, 40, 63,
+ 0, 0,128, 62, 47, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+ 23,200, 37, 63, 0, 0,128, 62, 47, 12, 49, 63, 14,139,103, 62,199,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 14,139,103, 62,199,228, 40, 63, 92, 33,101, 62,146, 55, 52, 63,230, 32, 78, 62,211, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,223,254, 71, 62,102,155, 54, 63,230, 32, 78, 62,
+211, 52, 43, 63, 92, 33,101, 62,146, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 92, 33,101, 62,146, 55, 52, 63, 23, 58, 97, 62, 69,233, 63, 63,223,254, 71, 62,102,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,240, 82, 64, 62,183,236, 65, 63,223,254, 71, 62,102,155, 54, 63, 23, 58, 97, 62,
+ 69,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 23, 58, 97, 62, 69,233, 63, 63,
+ 92, 33,101, 62,146, 55, 52, 63, 0, 0,128, 62, 19, 86, 60, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 62,228,153, 71, 63, 0, 0,128, 62, 13,228, 82, 63,166,200, 91, 62,147, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,166,200, 91, 62,147, 39, 75, 63, 23, 58, 97, 62, 69,233, 63, 63,
+ 0, 0,128, 62,228,153, 71, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+ 19, 86, 60, 63, 0, 0,128, 62,228,153, 71, 63, 23, 58, 97, 62, 69,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 23, 58, 97, 62, 69,233, 63, 63,166,200, 91, 62,147, 39, 75, 63,240, 82, 64, 62,183,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,223,254, 71, 62,102,155, 54, 63,240, 82, 64, 62,
+183,236, 65, 63,173,235, 42, 62,254,204, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+173,235, 42, 62,254,204, 55, 63,105, 20, 52, 62,198,160, 44, 63,223,254, 71, 62,102,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,230, 32, 78, 62,211, 52, 43, 63,223,254, 71, 62,102,155, 54, 63,105, 20, 52, 62,
+198,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,105, 20, 52, 62,198,160, 44, 63,
+173,235, 42, 62,254,204, 55, 63,173,153, 25, 62, 27, 28, 45, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 62, 58, 46, 94, 63, 0, 0,128, 62, 8,114,105, 63,230, 1, 64, 62, 49, 26, 99, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,230, 1, 64, 62, 49, 26, 99, 63, 34, 16, 81, 62,131, 64, 88, 63,
+ 0, 0,128, 62, 58, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+ 13,228, 82, 63, 0, 0,128, 62, 58, 46, 94, 63, 34, 16, 81, 62,131, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 34, 16, 81, 62,131, 64, 88, 63,230, 1, 64, 62, 49, 26, 99, 63,160,153, 25, 62, 14, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,164, 98,230, 61, 58, 26, 99, 63,160,153, 25, 62,
+ 14, 56, 90, 63,230, 1, 64, 62, 49, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+230, 1, 64, 62, 49, 26, 99, 63,159,153, 25, 62,210,154,109, 63,164, 98,230, 61, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,237,203, 76, 61, 22,114,105, 63,164, 98,230, 61, 58, 26, 99, 63,159,153, 25, 62,
+210,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,159,153, 25, 62,210,154,109, 63,
+230, 1, 64, 62, 49, 26, 99, 63, 0, 0,128, 62, 8,114,105, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 62,232,187,116, 63, 3,153, 59, 63, 0, 0,128, 63, 95,102,134, 63,242,187,116, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,210,203, 76, 61,242,187,116, 63,159,153, 25, 62,210,154,109, 63,
+ 0, 0,128, 62,232,187,116, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+ 8,114,105, 63, 0, 0,128, 62,232,187,116, 63,159,153, 25, 62,210,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,159,153, 25, 62,210,154,109, 63,210,203, 76, 61,242,187,116, 63,237,203, 76, 61, 22,114,105, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,164, 98,230, 61, 58, 26, 99, 63,237,203, 76, 61,
+ 22,114,105, 63,234,203, 76, 61, 79, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+234,203, 76, 61, 79, 46, 94, 63, 23, 70,196, 61,147, 64, 88, 63,164, 98,230, 61, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,160,153, 25, 62, 14, 56, 90, 63,164, 98,230, 61, 58, 26, 99, 63, 23, 70,196, 61,
+147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 23, 70,196, 61,147, 64, 88, 63,
+234,203, 76, 61, 79, 46, 94, 63,243,203, 76, 61, 41,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 42,138,170, 62,254,204, 55, 63,136,214,159, 62,183,236, 65, 63,145, 0,156, 62,102,155, 54, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,145, 0,156, 62,102,155, 54, 63,204,245,165, 62,198,160, 44, 63,
+ 42,138,170, 62,254,204, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42, 51,179, 62,
+ 28, 28, 45, 63, 42,138,170, 62,254,204, 55, 63,204,245,165, 62,198,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,204,245,165, 62,198,160, 44, 63,145, 0,156, 62,102,155, 54, 63,141,239,152, 62,211, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 82,111,141, 62,146, 55, 52, 63,141,239,152, 62,
+211, 52, 43, 63,145, 0,156, 62,102,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+145, 0,156, 62,102,155, 54, 63,245, 98,143, 62, 68,233, 63, 63, 82,111,141, 62,146, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 19, 86, 60, 63, 82,111,141, 62,146, 55, 52, 63,245, 98,143, 62,
+ 68,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,245, 98,143, 62, 68,233, 63, 63,
+145, 0,156, 62,102,155, 54, 63,136,214,159, 62,183,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,173, 27,146, 62,147, 39, 75, 63, 0, 0,128, 62, 13,228, 82, 63, 0, 0,128, 62,228,153, 71, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,228,153, 71, 63,245, 98,143, 62, 68,233, 63, 63,
+173, 27,146, 62,147, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,136,214,159, 62,
+183,236, 65, 63,173, 27,146, 62,147, 39, 75, 63,245, 98,143, 62, 68,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,245, 98,143, 62, 68,233, 63, 63, 0, 0,128, 62,228,153, 71, 63, 0, 0,128, 62, 19, 86, 60, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 82,111,141, 62,146, 55, 52, 63, 0, 0,128, 62,
+ 19, 86, 60, 63, 0, 0,128, 62, 47, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0,128, 62, 47, 12, 49, 63,121, 58,140, 62,199,228, 40, 63, 82,111,141, 62,146, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,141,239,152, 62,211, 52, 43, 63, 82,111,141, 62,146, 55, 52, 63,121, 58,140, 62,
+199,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,121, 58,140, 62,199,228, 40, 63,
+ 0, 0,128, 62, 47, 12, 49, 63, 0, 0,128, 62, 23,200, 37, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,173, 27,146, 62,147, 39, 75, 63,136,214,159, 62,183,236, 65, 63, 47,116,167, 62,195, 83, 78, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 47,116,167, 62,195, 83, 78, 63,239,119,151, 62,131, 64, 88, 63,
+173, 27,146, 62,147, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+ 13,228, 82, 63,173, 27,146, 62,147, 39, 75, 63,239,119,151, 62,131, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,239,119,151, 62,131, 64, 88, 63, 47,116,167, 62,195, 83, 78, 63, 49, 51,179, 62, 14, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 44,242,190, 62,205, 83, 78, 63, 49, 51,179, 62,
+ 14, 56, 90, 63, 47,116,167, 62,195, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 47,116,167, 62,195, 83, 78, 63, 42, 51,179, 62,108, 23, 67, 63, 44,242,190, 62,205, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,143,198, 62,200,236, 65, 63, 44,242,190, 62,205, 83, 78, 63, 42, 51,179, 62,
+108, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42, 51,179, 62,108, 23, 67, 63,
+ 47,116,167, 62,195, 83, 78, 63,136,214,159, 62,183,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 42,138,170, 62,254,204, 55, 63, 42, 51,179, 62, 28, 28, 45, 63, 45,220,187, 62, 7,205, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 45,220,187, 62, 7,205, 55, 63, 42, 51,179, 62,108, 23, 67, 63,
+ 42,138,170, 62,254,204, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,136,214,159, 62,
+183,236, 65, 63, 42,138,170, 62,254,204, 55, 63, 42, 51,179, 62,108, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 42, 51,179, 62,108, 23, 67, 63, 45,220,187, 62, 7,205, 55, 63,214,143,198, 62,200,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 44,242,190, 62,205, 83, 78, 63,214,143,198, 62,
+200,236, 65, 63,188, 74,212, 62,171, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+188, 74,212, 62,171, 39, 75, 63,122,238,206, 62,147, 64, 88, 63, 44,242,190, 62,205, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 49, 51,179, 62, 14, 56, 90, 63, 44,242,190, 62,205, 83, 78, 63,122,238,206, 62,
+147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,122,238,206, 62,147, 64, 88, 63,
+188, 74,212, 62,171, 39, 75, 63,130,102,230, 62, 41,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,130,102,230, 62, 82, 12, 49, 63,129,102,230, 62, 53, 86, 60, 63, 28,247,216, 62,172, 55, 52, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 28,247,216, 62,172, 55, 52, 63,243, 43,218, 62,223,228, 40, 63,
+130,102,230, 62, 82, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,102,230, 62,
+ 48,200, 37, 63,130,102,230, 62, 82, 12, 49, 63,243, 43,218, 62,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,243, 43,218, 62,223,228, 40, 63, 28,247,216, 62,172, 55, 52, 63,212,118,205, 62,228, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,206,101,202, 62,120,155, 54, 63,212,118,205, 62,
+228, 52, 43, 63, 28,247,216, 62,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 28,247,216, 62,172, 55, 52, 63,120, 3,215, 62, 95,233, 63, 63,206,101,202, 62,120,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,143,198, 62,200,236, 65, 63,206,101,202, 62,120,155, 54, 63,120, 3,215, 62,
+ 95,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,120, 3,215, 62, 95,233, 63, 63,
+ 28,247,216, 62,172, 55, 52, 63,129,102,230, 62, 53, 86, 60, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,130,102,230, 62, 1,154, 71, 63,130,102,230, 62, 41,228, 82, 63,188, 74,212, 62,171, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,188, 74,212, 62,171, 39, 75, 63,120, 3,215, 62, 95,233, 63, 63,
+130,102,230, 62, 1,154, 71, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,102,230, 62,
+ 53, 86, 60, 63,130,102,230, 62, 1,154, 71, 63,120, 3,215, 62, 95,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,120, 3,215, 62, 95,233, 63, 63,188, 74,212, 62,171, 39, 75, 63,214,143,198, 62,200,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,206,101,202, 62,120,155, 54, 63,214,143,198, 62,
+200,236, 65, 63, 45,220,187, 62, 7,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 45,220,187, 62, 7,205, 55, 63,142,112,192, 62,207,160, 44, 63,206,101,202, 62,120,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,118,205, 62,228, 52, 43, 63,206,101,202, 62,120,155, 54, 63,142,112,192, 62,
+207,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,142,112,192, 62,207,160, 44, 63,
+ 45,220,187, 62, 7,205, 55, 63, 42, 51,179, 62, 28, 28, 45, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,131,102,230, 62, 79, 46, 94, 63,131,102,230, 62, 22,114,105, 63, 87,103,198, 62, 58, 26, 99, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87,103,198, 62, 58, 26, 99, 63,122,238,206, 62,147, 64, 88, 63,
+131,102,230, 62, 79, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,130,102,230, 62,
+ 41,228, 82, 63,131,102,230, 62, 79, 46, 94, 63,122,238,206, 62,147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,122,238,206, 62,147, 64, 88, 63, 87,103,198, 62, 58, 26, 99, 63, 49, 51,179, 62, 14, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14,255,159, 62, 49, 26, 99, 63, 49, 51,179, 62,
+ 14, 56, 90, 63, 87,103,198, 62, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 87,103,198, 62, 58, 26, 99, 63, 49, 51,179, 62,210,154,109, 63, 14,255,159, 62, 49, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 8,114,105, 63, 14,255,159, 62, 49, 26, 99, 63, 49, 51,179, 62,
+210,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 49, 51,179, 62,210,154,109, 63,
+ 87,103,198, 62, 58, 26, 99, 63,131,102,230, 62, 22,114,105, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,134,102,230, 62,242,187,116, 63, 3,153, 59, 63, 0, 0,128, 63, 0, 0,128, 62,232,187,116, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,232,187,116, 63, 49, 51,179, 62,210,154,109, 63,
+134,102,230, 62,242,187,116, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,131,102,230, 62,
+ 22,114,105, 63,134,102,230, 62,242,187,116, 63, 49, 51,179, 62,210,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 49, 51,179, 62,210,154,109, 63, 0, 0,128, 62,232,187,116, 63, 0, 0,128, 62, 8,114,105, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14,255,159, 62, 49, 26, 99, 63, 0, 0,128, 62,
+ 8,114,105, 63, 0, 0,128, 62, 58, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0,128, 62, 58, 46, 94, 63,239,119,151, 62,131, 64, 88, 63, 14,255,159, 62, 49, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 49, 51,179, 62, 14, 56, 90, 63, 14,255,159, 62, 49, 26, 99, 63,239,119,151, 62,
+131, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,119,151, 62,131, 64, 88, 63,
+ 0, 0,128, 62, 58, 46, 94, 63, 0, 0,128, 62, 13,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 93,120, 8, 63, 11,205, 55, 63,140, 30, 3, 63,201,236, 65, 63,145, 51, 1, 63,121,155, 54, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,145, 51, 1, 63,121,155, 54, 63, 46, 46, 6, 63,211,160, 44, 63,
+ 93,120, 8, 63, 11,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63,
+ 35, 28, 45, 63, 93,120, 8, 63, 11,205, 55, 63, 46, 46, 6, 63,211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 46, 46, 6, 63,211,160, 44, 63,145, 51, 1, 63,121,155, 54, 63, 30, 86,255, 62,230, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,222,213,243, 62,172, 55, 52, 63, 30, 86,255, 62,
+230, 52, 43, 63,145, 51, 1, 63,121,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+145, 51, 1, 63,121,155, 54, 63,128,201,245, 62, 94,233, 63, 63,222,213,243, 62,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,102,230, 62, 53, 86, 60, 63,222,213,243, 62,172, 55, 52, 63,128,201,245, 62,
+ 94,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128,201,245, 62, 94,233, 63, 63,
+145, 51, 1, 63,121,155, 54, 63,140, 30, 3, 63,201,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 59,130,248, 62,169, 39, 75, 63,130,102,230, 62, 41,228, 82, 63,130,102,230, 62, 1,154, 71, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,130,102,230, 62, 1,154, 71, 63,128,201,245, 62, 94,233, 63, 63,
+ 59,130,248, 62,169, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,140, 30, 3, 63,
+201,236, 65, 63, 59,130,248, 62,169, 39, 75, 63,128,201,245, 62, 94,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,128,201,245, 62, 94,233, 63, 63,130,102,230, 62, 1,154, 71, 63,129,102,230, 62, 53, 86, 60, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,222,213,243, 62,172, 55, 52, 63,129,102,230, 62,
+ 53, 86, 60, 63,130,102,230, 62, 82, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+130,102,230, 62, 82, 12, 49, 63, 9,161,242, 62,223,228, 40, 63,222,213,243, 62,172, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 30, 86,255, 62,230, 52, 43, 63,222,213,243, 62,172, 55, 52, 63, 9,161,242, 62,
+223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 9,161,242, 62,223,228, 40, 63,
+130,102,230, 62, 82, 12, 49, 63,129,102,230, 62, 48,200, 37, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 59,130,248, 62,169, 39, 75, 63,140, 30, 3, 63,201,236, 65, 63, 94,237, 6, 63,207, 83, 78, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 94,237, 6, 63,207, 83, 78, 63,118,222,253, 62,148, 64, 88, 63,
+ 59,130,248, 62,169, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,130,102,230, 62,
+ 41,228, 82, 63, 59,130,248, 62,169, 39, 75, 63,118,222,253, 62,148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,118,222,253, 62,148, 64, 88, 63, 94,237, 6, 63,207, 83, 78, 63,220,204, 12, 63, 22, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 88,172, 18, 63,207, 83, 78, 63,220,204, 12, 63,
+ 22, 56, 90, 63, 94,237, 6, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 94,237, 6, 63,207, 83, 78, 63,220,204, 12, 63,115, 23, 67, 63, 88,172, 18, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 44,123, 22, 63,201,236, 65, 63, 88,172, 18, 63,207, 83, 78, 63,220,204, 12, 63,
+115, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63,115, 23, 67, 63,
+ 94,237, 6, 63,207, 83, 78, 63,140, 30, 3, 63,201,236, 65, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 93,120, 8, 63, 11,205, 55, 63,220,204, 12, 63, 35, 28, 45, 63, 91, 33, 17, 63, 9,205, 55, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 91, 33, 17, 63, 9,205, 55, 63,220,204, 12, 63,115, 23, 67, 63,
+ 93,120, 8, 63, 11,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,140, 30, 3, 63,
+201,236, 65, 63, 93,120, 8, 63, 11,205, 55, 63,220,204, 12, 63,115, 23, 67, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63,115, 23, 67, 63, 91, 33, 17, 63, 9,205, 55, 63, 44,123, 22, 63,201,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 88,172, 18, 63,207, 83, 78, 63, 44,123, 22, 63,
+201,236, 65, 63,153, 88, 29, 63,167, 39, 75, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+153, 88, 29, 63,167, 39, 75, 63,121,170, 26, 63,147, 64, 88, 63, 88,172, 18, 63,207, 83, 78, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63, 22, 56, 90, 63, 88,172, 18, 63,207, 83, 78, 63,121,170, 26, 63,
+147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,121,170, 26, 63,147, 64, 88, 63,
+153, 88, 29, 63,167, 39, 75, 63,118,102, 38, 63, 38,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,117,102, 38, 63, 78, 12, 49, 63,117,102, 38, 63, 50, 86, 60, 63,200,174, 31, 63,169, 55, 52, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,200,174, 31, 63,169, 55, 52, 63, 51, 73, 32, 63,221,228, 40, 63,
+117,102, 38, 63, 78, 12, 49, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63,
+ 45,200, 37, 63,117,102, 38, 63, 78, 12, 49, 63, 51, 73, 32, 63,221,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 51, 73, 32, 63,221,228, 40, 63,200,174, 31, 63,169, 55, 52, 63,169,238, 25, 63,229, 52, 43, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 39,102, 24, 63,119,155, 54, 63,169,238, 25, 63,
+229, 52, 43, 63,200,174, 31, 63,169, 55, 52, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+200,174, 31, 63,169, 55, 52, 63,246,180, 30, 63, 92,233, 63, 63, 39,102, 24, 63,119,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 44,123, 22, 63,201,236, 65, 63, 39,102, 24, 63,119,155, 54, 63,246,180, 30, 63,
+ 92,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,246,180, 30, 63, 92,233, 63, 63,
+200,174, 31, 63,169, 55, 52, 63,117,102, 38, 63, 50, 86, 60, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,117,102, 38, 63,255,153, 71, 63,118,102, 38, 63, 38,228, 82, 63,153, 88, 29, 63,167, 39, 75, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,153, 88, 29, 63,167, 39, 75, 63,246,180, 30, 63, 92,233, 63, 63,
+117,102, 38, 63,255,153, 71, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63,
+ 50, 86, 60, 63,117,102, 38, 63,255,153, 71, 63,246,180, 30, 63, 92,233, 63, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,246,180, 30, 63, 92,233, 63, 63,153, 88, 29, 63,167, 39, 75, 63, 44,123, 22, 63,201,236, 65, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 39,102, 24, 63,119,155, 54, 63, 44,123, 22, 63,
+201,236, 65, 63, 91, 33, 17, 63, 9,205, 55, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 91, 33, 17, 63, 9,205, 55, 63,138,107, 19, 63,211,160, 44, 63, 39,102, 24, 63,119,155, 54, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169,238, 25, 63,229, 52, 43, 63, 39,102, 24, 63,119,155, 54, 63,138,107, 19, 63,
+211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,107, 19, 63,211,160, 44, 63,
+ 91, 33, 17, 63, 9,205, 55, 63,220,204, 12, 63, 35, 28, 45, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,118,102, 38, 63, 77, 46, 94, 63,118,102, 38, 63, 19,114,105, 63,235,102, 22, 63, 59, 26, 99, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235,102, 22, 63, 59, 26, 99, 63,121,170, 26, 63,147, 64, 88, 63,
+118,102, 38, 63, 77, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,102, 38, 63,
+ 38,228, 82, 63,118,102, 38, 63, 77, 46, 94, 63,121,170, 26, 63,147, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,121,170, 26, 63,147, 64, 88, 63,235,102, 22, 63, 59, 26, 99, 63,220,204, 12, 63, 22, 56, 90, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,204, 50, 3, 63, 58, 26, 99, 63,220,204, 12, 63,
+ 22, 56, 90, 63,235,102, 22, 63, 59, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+235,102, 22, 63, 59, 26, 99, 63,224,204, 12, 63,212,154,109, 63,204, 50, 3, 63, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,131,102,230, 62, 22,114,105, 63,204, 50, 3, 63, 58, 26, 99, 63,224,204, 12, 63,
+212,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,224,204, 12, 63,212,154,109, 63,
+235,102, 22, 63, 59, 26, 99, 63,118,102, 38, 63, 19,114,105, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,120,102, 38, 63,242,187,116, 63, 3,153, 59, 63, 0, 0,128, 63,134,102,230, 62,242,187,116, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,134,102,230, 62,242,187,116, 63,224,204, 12, 63,212,154,109, 63,
+120,102, 38, 63,242,187,116, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,102, 38, 63,
+ 19,114,105, 63,120,102, 38, 63,242,187,116, 63,224,204, 12, 63,212,154,109, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,224,204, 12, 63,212,154,109, 63,134,102,230, 62,242,187,116, 63,131,102,230, 62, 22,114,105, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,204, 50, 3, 63, 58, 26, 99, 63,131,102,230, 62,
+ 22,114,105, 63,131,102,230, 62, 79, 46, 94, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+131,102,230, 62, 79, 46, 94, 63,118,222,253, 62,148, 64, 88, 63,204, 50, 3, 63, 58, 26, 99, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63, 22, 56, 90, 63,204, 50, 3, 63, 58, 26, 99, 63,118,222,253, 62,
+148, 64, 88, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,222,253, 62,148, 64, 88, 63,
+131,102,230, 62, 79, 46, 94, 63,130,102,230, 62, 41,228, 82, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,213,233, 76, 63, 35, 48, 21, 63,176,235, 70, 63,226,209, 22, 63, 80,234, 73, 63,146,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 80,234, 73, 63,146,111, 11, 63, 1,200, 79, 63, 94,152, 9, 63,
+213,233, 76, 63, 35, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 19,215, 82, 63,
+252, 29, 19, 63,213,233, 76, 63, 35, 48, 21, 63, 1,200, 79, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 1,200, 79, 63, 94,152, 9, 63, 80,234, 73, 63,146,111, 11, 63,193,204, 76, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213,233, 76, 63, 35, 48, 21, 63, 19,215, 82, 63,
+252, 29, 19, 63,220, 41, 80, 63,105, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+220, 41, 80, 63,105, 60, 31, 63,164,219, 73, 63,173, 23, 33, 63,213,233, 76, 63, 35, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,176,235, 70, 63,226,209, 22, 63,213,233, 76, 63, 35, 48, 21, 63,164,219, 73, 63,
+173, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,164,219, 73, 63,173, 23, 33, 63,
+220, 41, 80, 63,105, 60, 31, 63,196, 33, 77, 63,221, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,169,158, 70, 63,200,160, 44, 63, 0, 0, 64, 63, 24, 28, 45, 63, 5,171, 67, 63,216, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 5,171, 67, 63,216, 17, 34, 63,164,219, 73, 63,173, 23, 33, 63,
+169,158, 70, 63,200,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,196, 33, 77, 63,
+221, 52, 43, 63,169,158, 70, 63,200,160, 44, 63,164,219, 73, 63,173, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,164,219, 73, 63,173, 23, 33, 63, 5,171, 67, 63,216, 17, 34, 63,176,235, 70, 63,226,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 75,124, 83, 63,217,228, 40, 63,196, 33, 77, 63,
+221, 52, 43, 63,220, 41, 80, 63,105, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+220, 41, 80, 63,105, 60, 31, 63,218, 20, 86, 63,143,140, 28, 63, 75,124, 83, 63,217,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,139,153, 89, 63, 45,200, 37, 63, 75,124, 83, 63,217,228, 40, 63,218, 20, 86, 63,
+143,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218, 20, 86, 63,143,140, 28, 63,
+220, 41, 80, 63,105, 60, 31, 63, 19,215, 82, 63,252, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 64, 63,182, 32, 23, 63,176,235, 70, 63,226,209, 22, 63, 5,171, 67, 63,216, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 5,171, 67, 63,216, 17, 34, 63,251, 84, 60, 63,216, 17, 34, 63,
+ 0, 0, 64, 63,182, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 80, 20, 57, 63,
+226,209, 22, 63, 0, 0, 64, 63,182, 32, 23, 63,251, 84, 60, 63,216, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,251, 84, 60, 63,216, 17, 34, 63, 5,171, 67, 63,216, 17, 34, 63, 0, 0, 64, 63, 24, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,182, 32, 23, 63, 80, 20, 57, 63,
+226,209, 22, 63,169,156, 60, 63, 96,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+169,156, 60, 63, 96,116, 11, 63, 87, 99, 67, 63, 96,116, 11, 63, 0, 0, 64, 63,182, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,176,235, 70, 63,226,209, 22, 63, 0, 0, 64, 63,182, 32, 23, 63, 87, 99, 67, 63,
+ 96,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87, 99, 67, 63, 96,116, 11, 63,
+169,156, 60, 63, 96,116, 11, 63, 0, 0, 64, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 96,102, 70, 63,244, 1, 0, 63,193,204, 76, 63, 0, 0, 0, 63, 80,234, 73, 63,146,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 80,234, 73, 63,146,111, 11, 63, 87, 99, 67, 63, 96,116, 11, 63,
+ 96,102, 70, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+ 0, 0, 0, 63, 96,102, 70, 63,244, 1, 0, 63, 87, 99, 67, 63, 96,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 87, 99, 67, 63, 96,116, 11, 63, 80,234, 73, 63,146,111, 11, 63,176,235, 70, 63,226,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,160,153, 57, 63,244, 1, 0, 63, 0, 0, 64, 63,
+ 0, 0, 0, 63,169,156, 60, 63, 96,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+169,156, 60, 63, 96,116, 11, 63,176, 21, 54, 63,146,111, 11, 63,160,153, 57, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63, 51, 51, 63, 0, 0, 0, 63,160,153, 57, 63,244, 1, 0, 63,176, 21, 54, 63,
+146,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,176, 21, 54, 63,146,111, 11, 63,
+169,156, 60, 63, 96,116, 11, 63, 80, 20, 57, 63,226,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 64, 63, 93, 58,217, 62,144, 61, 57, 63, 19,196,217, 62, 85,123, 60, 63,253,230,198, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 85,123, 60, 63,253,230,198, 62,171,132, 67, 63,253,230,198, 62,
+ 0, 0, 64, 63, 93, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,112,194, 70, 63,
+ 19,196,217, 62, 0, 0, 64, 63, 93, 58,217, 62,171,132, 67, 63,253,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,171,132, 67, 63,253,230,198, 62, 85,123, 60, 63,253,230,198, 62, 0, 0, 64, 63,211,111,180, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63, 93, 58,217, 62,112,194, 70, 63,
+ 19,196,217, 62,125, 84, 67, 63, 42,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+125, 84, 67, 63, 42,211,236, 62,131,171, 60, 63, 42,211,236, 62, 0, 0, 64, 63, 93, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,144, 61, 57, 63, 19,196,217, 62, 0, 0, 64, 63, 93, 58,217, 62,131,171, 60, 63,
+ 42,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,131,171, 60, 63, 42,211,236, 62,
+125, 84, 67, 63, 42,211,236, 62, 0, 0, 64, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,160,153, 57, 63,244, 1, 0, 63, 63, 51, 51, 63, 0, 0, 0, 63,128, 46, 54, 63, 75,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128, 46, 54, 63, 75,207,236, 62,131,171, 60, 63, 42,211,236, 62,
+160,153, 57, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+ 0, 0, 0, 63,160,153, 57, 63,244, 1, 0, 63,131,171, 60, 63, 42,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,131,171, 60, 63, 42,211,236, 62,128, 46, 54, 63, 75,207,236, 62,144, 61, 57, 63, 19,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 96,102, 70, 63,244, 1, 0, 63, 0, 0, 64, 63,
+ 0, 0, 0, 63,125, 84, 67, 63, 42,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+125, 84, 67, 63, 42,211,236, 62,128,209, 73, 63, 75,207,236, 62, 96,102, 70, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,193,204, 76, 63, 0, 0, 0, 63, 96,102, 70, 63,244, 1, 0, 63,128,209, 73, 63,
+ 75,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128,209, 73, 63, 75,207,236, 62,
+125, 84, 67, 63, 42,211,236, 62,112,194, 70, 63, 19,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 43, 22, 51, 63, 35, 48, 21, 63,237, 40, 45, 63,252, 29, 19, 63,255, 55, 48, 63, 94,152, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,255, 55, 48, 63, 94,152, 9, 63,176, 21, 54, 63,146,111, 11, 63,
+ 43, 22, 51, 63, 35, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 80, 20, 57, 63,
+226,209, 22, 63, 43, 22, 51, 63, 35, 48, 21, 63,176, 21, 54, 63,146,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,176, 21, 54, 63,146,111, 11, 63,255, 55, 48, 63, 94,152, 9, 63, 63, 51, 51, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 43, 22, 51, 63, 35, 48, 21, 63, 80, 20, 57, 63,
+226,209, 22, 63, 91, 36, 54, 63,173, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 91, 36, 54, 63,173, 23, 33, 63, 36,214, 47, 63,105, 60, 31, 63, 43, 22, 51, 63, 35, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,237, 40, 45, 63,252, 29, 19, 63, 43, 22, 51, 63, 35, 48, 21, 63, 36,214, 47, 63,
+105, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36,214, 47, 63,105, 60, 31, 63,
+ 91, 36, 54, 63,173, 23, 33, 63, 60,222, 50, 63,221, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,181,131, 44, 63,216,228, 40, 63,117,102, 38, 63, 45,200, 37, 63, 38,235, 41, 63,141,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38,235, 41, 63,141,140, 28, 63, 36,214, 47, 63,105, 60, 31, 63,
+181,131, 44, 63,216,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 60,222, 50, 63,
+221, 52, 43, 63,181,131, 44, 63,216,228, 40, 63, 36,214, 47, 63,105, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 36,214, 47, 63,105, 60, 31, 63, 38,235, 41, 63,141,140, 28, 63,237, 40, 45, 63,252, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87, 97, 57, 63,200,160, 44, 63, 60,222, 50, 63,
+221, 52, 43, 63, 91, 36, 54, 63,173, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 91, 36, 54, 63,173, 23, 33, 63,251, 84, 60, 63,216, 17, 34, 63, 87, 97, 57, 63,200,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63, 24, 28, 45, 63, 87, 97, 57, 63,200,160, 44, 63,251, 84, 60, 63,
+216, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251, 84, 60, 63,216, 17, 34, 63,
+ 91, 36, 54, 63,173, 23, 33, 63, 80, 20, 57, 63,226,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,134, 14,128, 63, 39, 48, 21, 63,227, 30,122, 63,233,209, 22, 63,138, 29,125, 63,150,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138, 29,125, 63,150,111, 11, 63,159,125,129, 63, 94,152, 9, 63,
+134, 14,128, 63, 39, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,174, 73,193, 60,
+253, 29, 19, 63,209, 92,232, 57, 39, 48, 21, 63,114,207, 62, 60, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,159,125,129, 63, 94,152, 9, 63,138, 29,125, 63,150,111, 11, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,209, 92,232, 57, 39, 48, 21, 63,174, 73,193, 60,
+253, 29, 19, 63,214, 67, 87, 60,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+136,174,129, 63,110, 60, 31, 63,213, 14,125, 63,180, 23, 33, 63,134, 14,128, 63, 39, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,227, 30,122, 63,233,209, 22, 63,134, 14,128, 63, 39, 48, 21, 63,213, 14,125, 63,
+180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213, 14,125, 63,180, 23, 33, 63,
+136,174,129, 63,110, 60, 31, 63,121, 42,128, 63,230, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,210,209,121, 63,212,160, 44, 63, 36, 51,115, 63, 36, 28, 45, 63, 49,222,118, 63,226, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 49,222,118, 63,226, 17, 34, 63,213, 14,125, 63,180, 23, 33, 63,
+210,209,121, 63,212,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,121, 42,128, 63,
+230, 52, 43, 63,210,209,121, 63,212,160, 44, 63,213, 14,125, 63,180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,213, 14,125, 63,180, 23, 33, 63, 49,222,118, 63,226, 17, 34, 63,227, 30,122, 63,233,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,111,239,213, 60,223,228, 40, 63,120,226,169, 58,
+230, 52, 43, 63,214, 67, 87, 60,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+214, 67, 87, 60,110, 60, 31, 63, 13,129, 20, 61,143,140, 28, 63,111,239,213, 60,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,246,203, 76, 61, 48,200, 37, 63,111,239,213, 60,223,228, 40, 63, 13,129, 20, 61,
+143,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 13,129, 20, 61,143,140, 28, 63,
+214, 67, 87, 60,110, 60, 31, 63,174, 73,193, 60,253, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 44, 51,115, 63,188, 32, 23, 63,227, 30,122, 63,233,209, 22, 63, 49,222,118, 63,226, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 49,222,118, 63,226, 17, 34, 63, 31,136,111, 63,225, 17, 34, 63,
+ 44, 51,115, 63,188, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,116, 71,108, 63,
+232,209, 22, 63, 44, 51,115, 63,188, 32, 23, 63, 31,136,111, 63,225, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 31,136,111, 63,225, 17, 34, 63, 49,222,118, 63,226, 17, 34, 63, 36, 51,115, 63, 36, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 44, 51,115, 63,188, 32, 23, 63,116, 71,108, 63,
+232,209, 22, 63,213,207,111, 63,100,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+213,207,111, 63,100,116, 11, 63,138,150,118, 63,101,116, 11, 63, 44, 51,115, 63,188, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,227, 30,122, 63,233,209, 22, 63, 44, 51,115, 63,188, 32, 23, 63,138,150,118, 63,
+101,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138,150,118, 63,101,116, 11, 63,
+213,207,111, 63,100,116, 11, 63, 51, 51,115, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,154,153,121, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0, 0, 63,138, 29,125, 63,150,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,138, 29,125, 63,150,111, 11, 63,138,150,118, 63,101,116, 11, 63,
+154,153,121, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 51, 51,115, 63,
+ 0, 0, 0, 63,154,153,121, 63,244, 1, 0, 63,138,150,118, 63,101,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,138,150,118, 63,101,116, 11, 63,138, 29,125, 63,150,111, 11, 63,227, 30,122, 63,233,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,205,204,108, 63,244, 1, 0, 63, 51, 51,115, 63,
+ 0, 0, 0, 63,213,207,111, 63,100,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+213,207,111, 63,100,116, 11, 63,213, 72,105, 63,149,111, 11, 63,205,204,108, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,102,102, 63, 0, 0, 0, 63,205,204,108, 63,244, 1, 0, 63,213, 72,105, 63,
+149,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213, 72,105, 63,149,111, 11, 63,
+213,207,111, 63,100,116, 11, 63,116, 71,108, 63,232,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 58, 51,115, 63, 73, 58,217, 62,192,112,108, 63, 4,196,217, 62,139,174,111, 63,223,230,198, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,139,174,111, 63,223,230,198, 62,239,183,118, 63,227,230,198, 62,
+ 58, 51,115, 63, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,245,121, 63,
+ 6,196,217, 62, 58, 51,115, 63, 73, 58,217, 62,239,183,118, 63,227,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,239,183,118, 63,227,230,198, 62,139,174,111, 63,223,230,198, 62, 65, 51,115, 63,160,111,180, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 58, 51,115, 63, 73, 58,217, 62,179,245,121, 63,
+ 6,196,217, 62,185,135,118, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+185,135,118, 63, 30,211,236, 62,180,222,111, 63, 30,211,236, 62, 58, 51,115, 63, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192,112,108, 63, 4,196,217, 62, 58, 51,115, 63, 73, 58,217, 62,180,222,111, 63,
+ 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180,222,111, 63, 30,211,236, 62,
+185,135,118, 63, 30,211,236, 62, 51, 51,115, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,205,204,108, 63,244, 1, 0, 63,101,102,102, 63, 0, 0, 0, 63,170, 97,105, 63, 65,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170, 97,105, 63, 65,207,236, 62,180,222,111, 63, 30,211,236, 62,
+205,204,108, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 51, 51,115, 63,
+ 0, 0, 0, 63,205,204,108, 63,244, 1, 0, 63,180,222,111, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,180,222,111, 63, 30,211,236, 62,170, 97,105, 63, 65,207,236, 62,192,112,108, 63, 4,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,154,153,121, 63,244, 1, 0, 63, 51, 51,115, 63,
+ 0, 0, 0, 63,185,135,118, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+185,135,118, 63, 30,211,236, 62,194, 4,125, 63, 67,207,236, 62,154,153,121, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 63,154,153,121, 63,244, 1, 0, 63,194, 4,125, 63,
+ 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,194, 4,125, 63, 67,207,236, 62,
+185,135,118, 63, 30,211,236, 62,179,245,121, 63, 6,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 76, 73,102, 63, 38, 48, 21, 63, 11, 92, 96, 63,253, 29, 19, 63, 33,107, 99, 63, 94,152, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 33,107, 99, 63, 94,152, 9, 63,213, 72,105, 63,149,111, 11, 63,
+ 76, 73,102, 63, 38, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,116, 71,108, 63,
+232,209, 22, 63, 76, 73,102, 63, 38, 48, 21, 63,213, 72,105, 63,149,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,213, 72,105, 63,149,111, 11, 63, 33,107, 99, 63, 94,152, 9, 63,101,102,102, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 76, 73,102, 63, 38, 48, 21, 63,116, 71,108, 63,
+232,209, 22, 63,124, 87,105, 63,180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+124, 87,105, 63,180, 23, 33, 63, 65, 9, 99, 63,109, 60, 31, 63, 76, 73,102, 63, 38, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 11, 92, 96, 63,253, 29, 19, 63, 76, 73,102, 63, 38, 48, 21, 63, 65, 9, 99, 63,
+109, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 9, 99, 63,109, 60, 31, 63,
+124, 87,105, 63,180, 23, 33, 63, 87, 17,102, 63,229, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,205,182, 95, 63,222,228, 40, 63,139,153, 89, 63, 45,200, 37, 63, 63, 30, 93, 63,143,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63, 30, 93, 63,143,140, 28, 63, 65, 9, 99, 63,109, 60, 31, 63,
+205,182, 95, 63,222,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87, 17,102, 63,
+229, 52, 43, 63,205,182, 95, 63,222,228, 40, 63, 65, 9, 99, 63,109, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 65, 9, 99, 63,109, 60, 31, 63, 63, 30, 93, 63,143,140, 28, 63, 11, 92, 96, 63,253, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,148,108, 63,211,160, 44, 63, 87, 17,102, 63,
+229, 52, 43, 63,124, 87,105, 63,180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+124, 87,105, 63,180, 23, 33, 63, 31,136,111, 63,225, 17, 34, 63,118,148,108, 63,211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 36, 51,115, 63, 36, 28, 45, 63,118,148,108, 63,211,160, 44, 63, 31,136,111, 63,
+225, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 31,136,111, 63,225, 17, 34, 63,
+124, 87,105, 63,180, 23, 33, 63,116, 71,108, 63,232,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 65, 65, 77, 62, 32, 48, 21, 63,152, 72, 53, 62,229,209, 22, 63, 47, 67, 65, 62,147,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 47, 67, 65, 62,147,111, 11, 63,255,185, 88, 62, 90,152, 9, 63,
+ 65, 65, 77, 62, 32, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 64,246,100, 62,
+246, 29, 19, 63, 65, 65, 77, 62, 32, 48, 21, 63,255,185, 88, 62, 90,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,255,185, 88, 62, 90,152, 9, 63, 47, 67, 65, 62,147,111, 11, 63,254,204, 76, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 65, 77, 62, 32, 48, 21, 63, 64,246,100, 62,
+246, 29, 19, 63, 89, 65, 90, 62, 94, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 89, 65, 90, 62, 94, 60, 31, 63,107, 8, 65, 62,170, 23, 33, 63, 65, 65, 77, 62, 32, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,152, 72, 53, 62,229,209, 22, 63, 65, 65, 77, 62, 32, 48, 21, 63,107, 8, 65, 62,
+170, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,107, 8, 65, 62,170, 23, 33, 63,
+ 89, 65, 90, 62, 94, 60, 31, 63,230, 32, 78, 62,211, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,105, 20, 52, 62,198,160, 44, 63,173,153, 25, 62, 27, 28, 45, 63,216, 69, 40, 62,220, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,216, 69, 40, 62,220, 17, 34, 63,107, 8, 65, 62,170, 23, 33, 63,
+105, 20, 52, 62,198,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,230, 32, 78, 62,
+211, 52, 43, 63,105, 20, 52, 62,198,160, 44, 63,107, 8, 65, 62,170, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,107, 8, 65, 62,170, 23, 33, 63,216, 69, 40, 62,220, 17, 34, 63,152, 72, 53, 62,229,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14,139,103, 62,199,228, 40, 63,230, 32, 78, 62,
+211, 52, 43, 63, 89, 65, 90, 62, 94, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 89, 65, 90, 62, 94, 60, 31, 63, 83,237,113, 62,130,140, 28, 63, 14,139,103, 62,199,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 23,200, 37, 63, 14,139,103, 62,199,228, 40, 63, 83,237,113, 62,
+130,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 83,237,113, 62,130,140, 28, 63,
+ 89, 65, 90, 62, 94, 60, 31, 63, 64,246,100, 62,246, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,180,153, 25, 62,185, 32, 23, 63,152, 72, 53, 62,229,209, 22, 63,216, 69, 40, 62,220, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,216, 69, 40, 62,220, 17, 34, 63,133,237, 10, 62,219, 17, 34, 63,
+180,153, 25, 62,185, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147,213,251, 61,
+228,209, 22, 63,180,153, 25, 62,185, 32, 23, 63,133,237, 10, 62,219, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,133,237, 10, 62,219, 17, 34, 63,216, 69, 40, 62,220, 17, 34, 63,173,153, 25, 62, 27, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180,153, 25, 62,185, 32, 23, 63,147,213,251, 61,
+228,209, 22, 63, 67, 12, 12, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 67, 12, 12, 62, 98,116, 11, 63, 34, 39, 39, 62, 98,116, 11, 63,180,153, 25, 62,185, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,152, 72, 53, 62,229,209, 22, 63,180,153, 25, 62,185, 32, 23, 63, 34, 39, 39, 62,
+ 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 34, 39, 39, 62, 98,116, 11, 63,
+ 67, 12, 12, 62, 98,116, 11, 63,181,153, 25, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 92, 51, 51, 62,244, 1, 0, 63,254,204, 76, 62, 0, 0, 0, 63, 47, 67, 65, 62,147,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 47, 67, 65, 62,147,111, 11, 63, 34, 39, 39, 62, 98,116, 11, 63,
+ 92, 51, 51, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,181,153, 25, 62,
+ 0, 0, 0, 63, 92, 51, 51, 62,244, 1, 0, 63, 34, 39, 39, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 34, 39, 39, 62, 98,116, 11, 63, 47, 67, 65, 62,147,111, 11, 63,152, 72, 53, 62,229,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 8, 0, 0, 62,244, 1, 0, 63,181,153, 25, 62,
+ 0, 0, 0, 63, 67, 12, 12, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 67, 12, 12, 62, 98,116, 11, 63,109,224,227, 61,147,111, 11, 63, 8, 0, 0, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,204,204, 61, 0, 0, 0, 63, 8, 0, 0, 62,244, 1, 0, 63,109,224,227, 61,
+147,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,224,227, 61,147,111, 11, 63,
+ 67, 12, 12, 62, 98,116, 11, 63,147,213,251, 61,228,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,196,153, 25, 62, 73, 58,217, 62,171, 31,253, 61, 6,196,217, 62, 1,135, 11, 62,228,230,198, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,135, 11, 62,228,230,198, 62,153,172, 39, 62,230,230,198, 62,
+196,153, 25, 62, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,163, 52, 62,
+ 7,196,217, 62,196,153, 25, 62, 73, 58,217, 62,153,172, 39, 62,230,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,153,172, 39, 62,230,230,198, 62, 1,135, 11, 62,228,230,198, 62,214,153, 25, 62,165,111,180, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,196,153, 25, 62, 73, 58,217, 62,179,163, 52, 62,
+ 7,196,217, 62,202,235, 38, 62, 33,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+202,235, 38, 62, 33,211,236, 62,173, 71, 12, 62, 31,211,236, 62,196,153, 25, 62, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,171, 31,253, 61, 6,196,217, 62,196,153, 25, 62, 73, 58,217, 62,173, 71, 12, 62,
+ 31,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173, 71, 12, 62, 31,211,236, 62,
+202,235, 38, 62, 33,211,236, 62,181,153, 25, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 8, 0, 0, 62,244, 1, 0, 63,215,204,204, 61, 0, 0, 0, 63,251,166,228, 61, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251,166,228, 61, 67,207,236, 62,173, 71, 12, 62, 31,211,236, 62,
+ 8, 0, 0, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,181,153, 25, 62,
+ 0, 0, 0, 63, 8, 0, 0, 62,244, 1, 0, 63,173, 71, 12, 62, 31,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,173, 71, 12, 62, 31,211,236, 62,251,166,228, 61, 67,207,236, 62,171, 31,253, 61, 6,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 92, 51, 51, 62,244, 1, 0, 63,181,153, 25, 62,
+ 0, 0, 0, 63,202,235, 38, 62, 33,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+202,235, 38, 62, 33,211,236, 62,251,223, 64, 62, 67,207,236, 62, 92, 51, 51, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,254,204, 76, 62, 0, 0, 0, 63, 92, 51, 51, 62,244, 1, 0, 63,251,223, 64, 62,
+ 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251,223, 64, 62, 67,207,236, 62,
+202,235, 38, 62, 33,211,236, 62,179,163, 52, 62, 7,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 42,228,203, 61, 37, 48, 21, 63, 1,122,156, 61,254, 29, 19, 63,172,242,180, 61, 96,152, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,172,242,180, 61, 96,152, 9, 63,109,224,227, 61,147,111, 11, 63,
+ 42,228,203, 61, 37, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147,213,251, 61,
+228,209, 22, 63, 42,228,203, 61, 37, 48, 21, 63,109,224,227, 61,147,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,109,224,227, 61,147,111, 11, 63,172,242,180, 61, 96,152, 9, 63,215,204,204, 61, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42,228,203, 61, 37, 48, 21, 63,147,213,251, 61,
+228,209, 22, 63,208, 85,228, 61,179, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+208, 85,228, 61,179, 23, 33, 63,212,227,177, 61,110, 60, 31, 63, 42,228,203, 61, 37, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,122,156, 61,254, 29, 19, 63, 42,228,203, 61, 37, 48, 21, 63,212,227,177, 61,
+110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,227,177, 61,110, 60, 31, 63,
+208, 85,228, 61,179, 23, 33, 63,175, 36,202, 61,228, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 53, 80,151, 61,223,228, 40, 63,246,203, 76, 61, 48,200, 37, 63,166,139,130, 61,145,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,166,139,130, 61,145,140, 28, 63,212,227,177, 61,110, 60, 31, 63,
+ 53, 80,151, 61,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,175, 36,202, 61,
+228, 52, 43, 63, 53, 80,151, 61,223,228, 40, 63,212,227,177, 61,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,212,227,177, 61,110, 60, 31, 63,166,139,130, 61,145,140, 28, 63, 1,122,156, 61,254, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,201, 61,254, 61,207,160, 44, 63,175, 36,202, 61,
+228, 52, 43, 63,208, 85,228, 61,179, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+208, 85,228, 61,179, 23, 33, 63,133,237, 10, 62,219, 17, 34, 63,201, 61,254, 61,207,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173,153, 25, 62, 27, 28, 45, 63,201, 61,254, 61,207,160, 44, 63,133,237, 10, 62,
+219, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,133,237, 10, 62,219, 17, 34, 63,
+208, 85,228, 61,179, 23, 33, 63,147,213,251, 61,228,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,245, 6,205, 62, 37, 48, 21, 63,155, 10,193, 62,229,209, 22, 63,229, 7,199, 62,147,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,229, 7,199, 62,147,111, 11, 63, 85,195,210, 62, 96,152, 9, 63,
+245, 6,205, 62, 37, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128,225,216, 62,
+254, 29, 19, 63,245, 6,205, 62, 37, 48, 21, 63, 85,195,210, 62, 96,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 85,195,210, 62, 96,152, 9, 63,229, 7,199, 62,147,111, 11, 63,202,204,204, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,245, 6,205, 62, 37, 48, 21, 63,128,225,216, 62,
+254, 29, 19, 63, 11,135,211, 62,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 11,135,211, 62,110, 60, 31, 63,140,234,198, 62,179, 23, 33, 63,245, 6,205, 62, 37, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,155, 10,193, 62,229,209, 22, 63,245, 6,205, 62, 37, 48, 21, 63,140,234,198, 62,
+179, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,140,234,198, 62,179, 23, 33, 63,
+ 11,135,211, 62,110, 60, 31, 63,212,118,205, 62,228, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,142,112,192, 62,207,160, 44, 63, 42, 51,179, 62, 28, 28, 45, 63, 61,137,186, 62,219, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 61,137,186, 62,219, 17, 34, 63,140,234,198, 62,179, 23, 33, 63,
+142,112,192, 62,207,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,118,205, 62,
+228, 52, 43, 63,142,112,192, 62,207,160, 44, 63,140,234,198, 62,179, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,140,234,198, 62,179, 23, 33, 63, 61,137,186, 62,219, 17, 34, 63,155, 10,193, 62,229,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,243, 43,218, 62,223,228, 40, 63,212,118,205, 62,
+228, 52, 43, 63, 11,135,211, 62,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 11,135,211, 62,110, 60, 31, 63, 22, 93,223, 62,145,140, 28, 63,243, 43,218, 62,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,102,230, 62, 48,200, 37, 63,243, 43,218, 62,223,228, 40, 63, 22, 93,223, 62,
+145,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22, 93,223, 62,145,140, 28, 63,
+ 11,135,211, 62,110, 60, 31, 63,128,225,216, 62,254, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 38, 51,179, 62,185, 32, 23, 63,155, 10,193, 62,229,209, 22, 63, 61,137,186, 62,219, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 61,137,186, 62,219, 17, 34, 63, 20,221,171, 62,219, 17, 34, 63,
+ 38, 51,179, 62,185, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180, 91,165, 62,
+229,209, 22, 63, 38, 51,179, 62,185, 32, 23, 63, 20,221,171, 62,219, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 20,221,171, 62,219, 17, 34, 63, 61,137,186, 62,219, 17, 34, 63, 42, 51,179, 62, 28, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 51,179, 62,185, 32, 23, 63,180, 91,165, 62,
+229,209, 22, 63,111,108,172, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+111,108,172, 62, 98,116, 11, 63,222,249,185, 62, 98,116, 11, 63, 38, 51,179, 62,185, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,155, 10,193, 62,229,209, 22, 63, 38, 51,179, 62,185, 32, 23, 63,222,249,185, 62,
+ 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,222,249,185, 62, 98,116, 11, 63,
+111,108,172, 62, 98,116, 11, 63, 38, 51,179, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,252,255,191, 62,244, 1, 0, 63,202,204,204, 62, 0, 0, 0, 63,229, 7,199, 62,147,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,229, 7,199, 62,147,111, 11, 63,222,249,185, 62, 98,116, 11, 63,
+252,255,191, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 51,179, 62,
+ 0, 0, 0, 63,252,255,191, 62,244, 1, 0, 63,222,249,185, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,222,249,185, 62, 98,116, 11, 63,229, 7,199, 62,147,111, 11, 63,155, 10,193, 62,229,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 82,102,166, 62,244, 1, 0, 63, 38, 51,179, 62,
+ 0, 0, 0, 63,111,108,172, 62, 98,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+111,108,172, 62, 98,116, 11, 63,104, 94,159, 62,147,111, 11, 63, 82,102,166, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,153,153, 62, 0, 0, 0, 63, 82,102,166, 62,244, 1, 0, 63,104, 94,159, 62,
+147,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,104, 94,159, 62,147,111, 11, 63,
+111,108,172, 62, 98,116, 11, 63,180, 91,165, 62,229,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 30, 51,179, 62, 73, 58,217, 62, 39,174,165, 62, 7,196,217, 62,180, 41,172, 62,227,230,198, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180, 41,172, 62,227,230,198, 62,127, 60,186, 62,225,230,198, 62,
+ 30, 51,179, 62, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,184,192, 62,
+ 6,196,217, 62, 30, 51,179, 62, 73, 58,217, 62,127, 60,186, 62,225,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,127, 60,186, 62,225,230,198, 62,180, 41,172, 62,227,230,198, 62, 21, 51,179, 62,165,111,180, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 30, 51,179, 62, 73, 58,217, 62, 21,184,192, 62,
+ 6,196,217, 62, 42,220,185, 62, 31,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 42,220,185, 62, 31,211,236, 62, 27,138,172, 62, 33,211,236, 62, 30, 51,179, 62, 73, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 39,174,165, 62, 7,196,217, 62, 30, 51,179, 62, 73, 58,217, 62, 27,138,172, 62,
+ 33,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 27,138,172, 62, 33,211,236, 62,
+ 42,220,185, 62, 31,211,236, 62, 38, 51,179, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 82,102,166, 62,244, 1, 0, 63,129,153,153, 62, 0, 0, 0, 63, 3,144,159, 62, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 3,144,159, 62, 67,207,236, 62, 27,138,172, 62, 33,211,236, 62,
+ 82,102,166, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 51,179, 62,
+ 0, 0, 0, 63, 82,102,166, 62,244, 1, 0, 63, 27,138,172, 62, 33,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 27,138,172, 62, 33,211,236, 62, 3,144,159, 62, 67,207,236, 62, 39,174,165, 62, 7,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,252,255,191, 62,244, 1, 0, 63, 38, 51,179, 62,
+ 0, 0, 0, 63, 42,220,185, 62, 31,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 42,220,185, 62, 31,211,236, 62, 65,214,198, 62, 67,207,236, 62,252,255,191, 62,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,202,204,204, 62, 0, 0, 0, 63,252,255,191, 62,244, 1, 0, 63, 65,214,198, 62,
+ 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65,214,198, 62, 67,207,236, 62,
+ 42,220,185, 62, 31,211,236, 62, 21,184,192, 62, 6,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 95, 95,153, 62, 32, 48, 21, 63,224,132,141, 62,246, 29, 19, 63, 1,163,147, 62, 91,152, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,163,147, 62, 91,152, 9, 63,104, 94,159, 62,147,111, 11, 63,
+ 95, 95,153, 62, 32, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180, 91,165, 62,
+229,209, 22, 63, 95, 95,153, 62, 32, 48, 21, 63,104, 94,159, 62,147,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,104, 94,159, 62,147,111, 11, 63, 1,163,147, 62, 91,152, 9, 63,129,153,153, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 95, 95,153, 62, 32, 48, 21, 63,180, 91,165, 62,
+229,209, 22, 63,203,123,159, 62,170, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+203,123,159, 62,170, 23, 33, 63, 84,223,146, 62, 94, 60, 31, 63, 95, 95,153, 62, 32, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,224,132,141, 62,246, 29, 19, 63, 95, 95,153, 62, 32, 48, 21, 63, 84,223,146, 62,
+ 94, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 84,223,146, 62, 94, 60, 31, 63,
+203,123,159, 62,170, 23, 33, 63,141,239,152, 62,211, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,121, 58,140, 62,199,228, 40, 63, 0, 0,128, 62, 23,200, 37, 63, 86, 9,135, 62,130,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 86, 9,135, 62,130,140, 28, 63, 84,223,146, 62, 94, 60, 31, 63,
+121, 58,140, 62,199,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,141,239,152, 62,
+211, 52, 43, 63,121, 58,140, 62,199,228, 40, 63, 84,223,146, 62, 94, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 84,223,146, 62, 94, 60, 31, 63, 86, 9,135, 62,130,140, 28, 63,224,132,141, 62,246, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,204,245,165, 62,198,160, 44, 63,141,239,152, 62,
+211, 52, 43, 63,203,123,159, 62,170, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+203,123,159, 62,170, 23, 33, 63, 20,221,171, 62,219, 17, 34, 63,204,245,165, 62,198,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42, 51,179, 62, 28, 28, 45, 63,204,245,165, 62,198,160, 44, 63, 20,221,171, 62,
+219, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 20,221,171, 62,219, 17, 34, 63,
+203,123,159, 62,170, 23, 33, 63,180, 91,165, 62,229,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,180,182, 25, 63, 38, 48, 21, 63,140,184, 19, 63,232,209, 22, 63, 43,183, 22, 63,149,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 43,183, 22, 63,149,111, 11, 63,223,148, 28, 63, 94,152, 9, 63,
+180,182, 25, 63, 38, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,245,163, 31, 63,
+253, 29, 19, 63,180,182, 25, 63, 38, 48, 21, 63,223,148, 28, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,223,148, 28, 63, 94,152, 9, 63, 43,183, 22, 63,149,111, 11, 63,155,153, 25, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,180,182, 25, 63, 38, 48, 21, 63,245,163, 31, 63,
+253, 29, 19, 63,191,246, 28, 63,109, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+191,246, 28, 63,109, 60, 31, 63,132,168, 22, 63,180, 23, 33, 63,180,182, 25, 63, 38, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,140,184, 19, 63,232,209, 22, 63,180,182, 25, 63, 38, 48, 21, 63,132,168, 22, 63,
+180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,132,168, 22, 63,180, 23, 33, 63,
+191,246, 28, 63,109, 60, 31, 63,169,238, 25, 63,229, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,138,107, 19, 63,211,160, 44, 63,220,204, 12, 63, 35, 28, 45, 63,225,119, 16, 63,225, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,225,119, 16, 63,225, 17, 34, 63,132,168, 22, 63,180, 23, 33, 63,
+138,107, 19, 63,211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169,238, 25, 63,
+229, 52, 43, 63,138,107, 19, 63,211,160, 44, 63,132,168, 22, 63,180, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,132,168, 22, 63,180, 23, 33, 63,225,119, 16, 63,225, 17, 34, 63,140,184, 19, 63,232,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 51, 73, 32, 63,221,228, 40, 63,169,238, 25, 63,
+229, 52, 43, 63,191,246, 28, 63,109, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+191,246, 28, 63,109, 60, 31, 63,192,225, 34, 63,142,140, 28, 63, 51, 73, 32, 63,221,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102, 38, 63, 45,200, 37, 63, 51, 73, 32, 63,221,228, 40, 63,192,225, 34, 63,
+142,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192,225, 34, 63,142,140, 28, 63,
+191,246, 28, 63,109, 60, 31, 63,245,163, 31, 63,253, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,212,204, 12, 63,188, 32, 23, 63,140,184, 19, 63,232,209, 22, 63,225,119, 16, 63,225, 17, 34, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,225,119, 16, 63,225, 17, 34, 63,207, 33, 9, 63,226, 17, 34, 63,
+212,204, 12, 63,188, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 29,225, 5, 63,
+233,209, 22, 63,212,204, 12, 63,188, 32, 23, 63,207, 33, 9, 63,226, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,207, 33, 9, 63,226, 17, 34, 63,225,119, 16, 63,225, 17, 34, 63,220,204, 12, 63, 35, 28, 45, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,204, 12, 63,188, 32, 23, 63, 29,225, 5, 63,
+233,209, 22, 63,118,105, 9, 63,101,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+118,105, 9, 63,101,116, 11, 63, 43, 48, 16, 63,100,116, 11, 63,212,204, 12, 63,188, 32, 23, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,140,184, 19, 63,232,209, 22, 63,212,204, 12, 63,188, 32, 23, 63, 43, 48, 16, 63,
+100,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 43, 48, 16, 63,100,116, 11, 63,
+118,105, 9, 63,101,116, 11, 63,205,204, 12, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 51, 51, 19, 63,244, 1, 0, 63,155,153, 25, 63, 0, 0, 0, 63, 43,183, 22, 63,149,111, 11, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 43,183, 22, 63,149,111, 11, 63, 43, 48, 16, 63,100,116, 11, 63,
+ 51, 51, 19, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,205,204, 12, 63,
+ 0, 0, 0, 63, 51, 51, 19, 63,244, 1, 0, 63, 43, 48, 16, 63,100,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 43, 48, 16, 63,100,116, 11, 63, 43,183, 22, 63,149,111, 11, 63,140,184, 19, 63,232,209, 22, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,102,102, 6, 63,244, 1, 0, 63,205,204, 12, 63,
+ 0, 0, 0, 63,118,105, 9, 63,101,116, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+118,105, 9, 63,101,116, 11, 63,118,226, 2, 63,149,111, 11, 63,102,102, 6, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63,102,102, 6, 63,244, 1, 0, 63,118,226, 2, 63,
+149,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118,226, 2, 63,149,111, 11, 63,
+118,105, 9, 63,101,116, 11, 63, 29,225, 5, 63,233,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,198,204, 12, 63, 72, 58,217, 62, 77, 10, 6, 63, 6,196,217, 62, 17, 72, 9, 63,227,230,198, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 17, 72, 9, 63,227,230,198, 62,117, 81, 16, 63,223,230,198, 62,
+198,204, 12, 63, 72, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 64,143, 19, 63,
+ 4,196,217, 62,198,204, 12, 63, 72, 58,217, 62,117, 81, 16, 63,223,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,117, 81, 16, 63,223,230,198, 62, 17, 72, 9, 63,227,230,198, 62,191,204, 12, 63,160,111,180, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,198,204, 12, 63, 72, 58,217, 62, 64,143, 19, 63,
+ 4,196,217, 62, 76, 33, 16, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 76, 33, 16, 63, 30,211,236, 62, 71,120, 9, 63, 30,211,236, 62,198,204, 12, 63, 72, 58,217, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 77, 10, 6, 63, 6,196,217, 62,198,204, 12, 63, 72, 58,217, 62, 71,120, 9, 63,
+ 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 71,120, 9, 63, 30,211,236, 62,
+ 76, 33, 16, 63, 30,211,236, 62,205,204, 12, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,102,102, 6, 63,244, 1, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 62,251, 2, 63, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 62,251, 2, 63, 67,207,236, 62, 71,120, 9, 63, 30,211,236, 62,
+102,102, 6, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,205,204, 12, 63,
+ 0, 0, 0, 63,102,102, 6, 63,244, 1, 0, 63, 71,120, 9, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 71,120, 9, 63, 30,211,236, 62, 62,251, 2, 63, 67,207,236, 62, 77, 10, 6, 63, 6,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 51, 51, 19, 63,244, 1, 0, 63,205,204, 12, 63,
+ 0, 0, 0, 63, 76, 33, 16, 63, 30,211,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 76, 33, 16, 63, 30,211,236, 62, 86,158, 22, 63, 65,207,236, 62, 51, 51, 19, 63,244, 1, 0, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,155,153, 25, 63, 0, 0, 0, 63, 51, 51, 19, 63,244, 1, 0, 63, 86,158, 22, 63,
+ 65,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 86,158, 22, 63, 65,207,236, 62,
+ 76, 33, 16, 63, 30,211,236, 62, 64,143, 19, 63, 4,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,233,197,255, 62, 39, 48, 21, 63,101,235,243, 62,252, 29, 19, 63,132, 9,250, 62, 94,152, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,132, 9,250, 62, 94,152, 9, 63,118,226, 2, 63,149,111, 11, 63,
+233,197,255, 62, 39, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 29,225, 5, 63,
+233,209, 22, 63,233,197,255, 62, 39, 48, 21, 63,118,226, 2, 63,149,111, 11, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,118,226, 2, 63,149,111, 11, 63,132, 9,250, 62, 94,152, 9, 63, 0, 0, 0, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,233,197,255, 62, 39, 48, 21, 63, 29,225, 5, 63,
+233,209, 22, 63, 43,241, 2, 63,181, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 43,241, 2, 63,181, 23, 33, 63,225, 69,249, 62,110, 60, 31, 63,233,197,255, 62, 39, 48, 21, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,235,243, 62,252, 29, 19, 63,233,197,255, 62, 39, 48, 21, 63,225, 69,249, 62,
+110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,225, 69,249, 62,110, 60, 31, 63,
+ 43,241, 2, 63,181, 23, 33, 63, 30, 86,255, 62,230, 52, 43, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 9,161,242, 62,223,228, 40, 63,129,102,230, 62, 48,200, 37, 63,222,111,237, 62,143,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,222,111,237, 62,143,140, 28, 63,225, 69,249, 62,110, 60, 31, 63,
+ 9,161,242, 62,223,228, 40, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 30, 86,255, 62,
+230, 52, 43, 63, 9,161,242, 62,223,228, 40, 63,225, 69,249, 62,110, 60, 31, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,225, 69,249, 62,110, 60, 31, 63,222,111,237, 62,143,140, 28, 63,101,235,243, 62,252, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 46, 46, 6, 63,211,160, 44, 63, 30, 86,255, 62,
+230, 52, 43, 63, 43,241, 2, 63,181, 23, 33, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 43,241, 2, 63,181, 23, 33, 63,207, 33, 9, 63,226, 17, 34, 63, 46, 46, 6, 63,211,160, 44, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,220,204, 12, 63, 35, 28, 45, 63, 46, 46, 6, 63,211,160, 44, 63,207, 33, 9, 63,
+226, 17, 34, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,207, 33, 9, 63,226, 17, 34, 63,
+ 43,241, 2, 63,181, 23, 33, 63, 29,225, 5, 63,233,209, 22, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,138,238, 85, 63, 72,220,187, 62,218,173, 82, 63, 55, 92,210, 62,229,189, 79, 63,173,208,189, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,229,189, 79, 63,173,208,189, 62,230,250, 82, 63,117,190,166, 62,
+138,238, 85, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,149,153, 89, 63,
+201,199,165, 62,138,238, 85, 63, 72,220,187, 62,230,250, 82, 63,117,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,230,250, 82, 63,117,190,166, 62,229,189, 79, 63,173,208,189, 62,198,119, 76, 63, 90,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170,111, 73, 63, 68,135,193, 62,198,119, 76, 63,
+ 90,150,169, 62,229,189, 79, 63,173,208,189, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+229,189, 79, 63,173,208,189, 62,176,175, 76, 63,192,159,213, 62,170,111, 73, 63, 68,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,112,194, 70, 63, 19,196,217, 62,170,111, 73, 63, 68,135,193, 62,176,175, 76, 63,
+192,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,176,175, 76, 63,192,159,213, 62,
+229,189, 79, 63,173,208,189, 62,218,173, 82, 63, 55, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 52,175, 79, 63,218, 32,233, 62,193,204, 76, 63, 0, 0, 0, 63,128,209, 73, 63, 75,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128,209, 73, 63, 75,207,236, 62,176,175, 76, 63,192,159,213, 62,
+ 52,175, 79, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218,173, 82, 63,
+ 55, 92,210, 62, 52,175, 79, 63,218, 32,233, 62,176,175, 76, 63,192,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,176,175, 76, 63,192,159,213, 62,128,209, 73, 63, 75,207,236, 62,112,194, 70, 63, 19,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170,111, 73, 63, 68,135,193, 62,112,194, 70, 63,
+ 19,196,217, 62,171,132, 67, 63,253,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+171,132, 67, 63,253,230,198, 62, 61, 29, 70, 63,114, 54,174, 62,170,111, 73, 63, 68,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,198,119, 76, 63, 90,150,169, 62,170,111, 73, 63, 68,135,193, 62, 61, 29, 70, 63,
+114, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 61, 29, 70, 63,114, 54,174, 62,
+171,132, 67, 63,253,230,198, 62, 0, 0, 64, 63,211,111,180, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 52,175, 79, 63,218, 32,233, 62,218,173, 82, 63, 55, 92,210, 62, 56, 54, 86, 63, 58, 23,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 56, 54, 86, 63, 58, 23,233, 62, 41, 51, 83, 63, 24,252,255, 62,
+ 52,175, 79, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,193,204, 76, 63,
+ 0, 0, 0, 63, 52,175, 79, 63,218, 32,233, 62, 41, 51, 83, 63, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 41, 51, 83, 63, 24,252,255, 62, 56, 54, 86, 63, 58, 23,233, 62,147,153, 89, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,252, 92, 63, 58, 23,233, 62,147,153, 89, 63,
+ 0, 0, 0, 63, 56, 54, 86, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 56, 54, 86, 63, 58, 23,233, 62,147,153, 89, 63,143,190,209, 62,239,252, 92, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 78,133, 96, 63, 55, 92,210, 62,239,252, 92, 63, 58, 23,233, 62,147,153, 89, 63,
+143,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147,153, 89, 63,143,190,209, 62,
+ 56, 54, 86, 63, 58, 23,233, 62,218,173, 82, 63, 55, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,138,238, 85, 63, 72,220,187, 62,149,153, 89, 63,201,199,165, 62,159, 68, 93, 63, 72,220,187, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,159, 68, 93, 63, 72,220,187, 62,147,153, 89, 63,143,190,209, 62,
+138,238, 85, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218,173, 82, 63,
+ 55, 92,210, 62,138,238, 85, 63, 72,220,187, 62,147,153, 89, 63,143,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,147,153, 89, 63,143,190,209, 62,159, 68, 93, 63, 72,220,187, 62, 78,133, 96, 63, 55, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,252, 92, 63, 58, 23,233, 62, 78,133, 96, 63,
+ 55, 92,210, 62,242,131, 99, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+242,131, 99, 63,218, 32,233, 62,254,255, 95, 63, 24,252,255, 62,239,252, 92, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147,153, 89, 63, 0, 0, 0, 63,239,252, 92, 63, 58, 23,233, 62,254,255, 95, 63,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,254,255, 95, 63, 24,252,255, 62,
+242,131, 99, 63,218, 32,233, 62,101,102,102, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,139,174,111, 63,223,230,198, 62,192,112,108, 63, 4,196,217, 62,133,195,105, 63, 37,135,193, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,133,195,105, 63, 37,135,193, 62,249, 21,109, 63, 65, 54,174, 62,
+139,174,111, 63,223,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,
+160,111,180, 62,139,174,111, 63,223,230,198, 62,249, 21,109, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,249, 21,109, 63, 65, 54,174, 62,133,195,105, 63, 37,135,193, 62,106,187,102, 63, 54,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70,117, 99, 63,155,208,189, 62,106,187,102, 63,
+ 54,150,169, 62,133,195,105, 63, 37,135,193, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+133,195,105, 63, 37,135,193, 62,123,131,102, 63,181,159,213, 62, 70,117, 99, 63,155,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 78,133, 96, 63, 55, 92,210, 62, 70,117, 99, 63,155,208,189, 62,123,131,102, 63,
+181,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,123,131,102, 63,181,159,213, 62,
+133,195,105, 63, 37,135,193, 62,192,112,108, 63, 4,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,170, 97,105, 63, 65,207,236, 62,101,102,102, 63, 0, 0, 0, 63,242,131, 99, 63,218, 32,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,242,131, 99, 63,218, 32,233, 62,123,131,102, 63,181,159,213, 62,
+170, 97,105, 63, 65,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192,112,108, 63,
+ 4,196,217, 62,170, 97,105, 63, 65,207,236, 62,123,131,102, 63,181,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,123,131,102, 63,181,159,213, 62,242,131, 99, 63,218, 32,233, 62, 78,133, 96, 63, 55, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70,117, 99, 63,155,208,189, 62, 78,133, 96, 63,
+ 55, 92,210, 62,159, 68, 93, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+159, 68, 93, 63, 72,220,187, 62, 71, 56, 96, 63, 99,190,166, 62, 70,117, 99, 63,155,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,106,187,102, 63, 54,150,169, 62, 70,117, 99, 63,155,208,189, 62, 71, 56, 96, 63,
+ 99,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 71, 56, 96, 63, 99,190,166, 62,
+159, 68, 93, 63, 72,220,187, 62,149,153, 89, 63,201,199,165, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 33,107, 99, 63, 94,152, 9, 63, 11, 92, 96, 63,253, 29, 19, 63, 21,238, 92, 63,112,150, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,238, 92, 63,112,150, 9, 63,254,255, 95, 63, 24,252,255, 62,
+ 33,107, 99, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,102,102, 63,
+ 0, 0, 0, 63, 33,107, 99, 63, 94,152, 9, 63,254,255, 95, 63, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,254,255, 95, 63, 24,252,255, 62, 21,238, 92, 63,112,150, 9, 63,147,153, 89, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14, 69, 86, 63,112,150, 9, 63,147,153, 89, 63,
+ 0, 0, 0, 63, 21,238, 92, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 21,238, 92, 63,112,150, 9, 63,143,153, 89, 63,219, 98, 19, 63, 14, 69, 86, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 19,215, 82, 63,252, 29, 19, 63, 14, 69, 86, 63,112,150, 9, 63,143,153, 89, 63,
+219, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,143,153, 89, 63,219, 98, 19, 63,
+ 21,238, 92, 63,112,150, 9, 63, 11, 92, 96, 63,253, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 63, 30, 93, 63,143,140, 28, 63,139,153, 89, 63, 45,200, 37, 63,218, 20, 86, 63,143,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218, 20, 86, 63,143,140, 28, 63,143,153, 89, 63,219, 98, 19, 63,
+ 63, 30, 93, 63,143,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 11, 92, 96, 63,
+253, 29, 19, 63, 63, 30, 93, 63,143,140, 28, 63,143,153, 89, 63,219, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,143,153, 89, 63,219, 98, 19, 63,218, 20, 86, 63,143,140, 28, 63, 19,215, 82, 63,252, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14, 69, 86, 63,112,150, 9, 63, 19,215, 82, 63,
+252, 29, 19, 63, 1,200, 79, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 1,200, 79, 63, 94,152, 9, 63, 41, 51, 83, 63, 24,252,255, 62, 14, 69, 86, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147,153, 89, 63, 0, 0, 0, 63, 14, 69, 86, 63,112,150, 9, 63, 41, 51, 83, 63,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 41, 51, 83, 63, 24,252,255, 62,
+ 1,200, 79, 63, 94,152, 9, 63,193,204, 76, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,237, 28, 18, 61, 60,220,187, 62,151, 35,188, 60, 46, 92,210, 62,218, 74, 60, 60,150,208,189, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,218, 74, 60, 60,150,208,189, 62,195,197,197, 60, 89,190,166, 62,
+237, 28, 18, 61, 60,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,194,205, 76, 61,
+186,199,165, 62,237, 28, 18, 61, 60,220,187, 62,195,197,197, 60, 89,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 23, 23,131, 63, 89,190,166, 62,150,120,129, 63,150,208,189, 62, 15,171,127, 63, 52,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,241,162,124, 63, 36,135,193, 62, 15,171,127, 63,
+ 52,150,169, 62,150,120,129, 63,150,208,189, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+150,120,129, 63,150,208,189, 62,244,226,127, 63,179,159,213, 62,241,162,124, 63, 36,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,245,121, 63, 6,196,217, 62,241,162,124, 63, 36,135,193, 62,244,226,127, 63,
+179,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,244,226,127, 63,179,159,213, 62,
+150,120,129, 63,150,208,189, 62,142,240,130, 63, 46, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 59,113,129, 63,214, 32,233, 62, 0, 0,128, 63, 0, 0, 0, 63,194, 4,125, 63, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,194, 4,125, 63, 67,207,236, 62,244,226,127, 63,179,159,213, 62,
+ 59,113,129, 63,214, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,142,240,130, 63,
+ 46, 92,210, 62, 59,113,129, 63,214, 32,233, 62,244,226,127, 63,179,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,244,226,127, 63,179,159,213, 62,194, 4,125, 63, 67,207,236, 62,179,245,121, 63, 6,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,241,162,124, 63, 36,135,193, 62,179,245,121, 63,
+ 6,196,217, 62,239,183,118, 63,227,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+239,183,118, 63,227,230,198, 62,133, 80,121, 63, 65, 54,174, 62,241,162,124, 63, 36,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 15,171,127, 63, 52,150,169, 62,241,162,124, 63, 36,135,193, 62,133, 80,121, 63,
+ 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,133, 80,121, 63, 65, 54,174, 62,
+239,183,118, 63,227,230,198, 62, 65, 51,115, 63,160,111,180, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,110,157, 56, 60,214, 32,233, 62,151, 35,188, 60, 46, 92,210, 62, 95,151, 22, 61, 55, 23,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 95,151, 22, 61, 55, 23,233, 62,176,204,204, 60, 24,252,255, 62,
+110,157, 56, 60,214, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,167, 79, 11, 38,
+ 0, 0, 0, 63,110,157, 56, 60,214, 32,233, 62,176,204,204, 60, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,176,204,204, 60, 24,252,255, 62, 95,151, 22, 61, 55, 23,233, 62,215,204, 76, 61, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87,129,129, 61, 57, 23,233, 62,215,204, 76, 61,
+ 0, 0, 0, 63, 95,151, 22, 61, 55, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 95,151, 22, 61, 55, 23,233, 62, 68,205, 76, 61,135,190,209, 62, 87,129,129, 61, 57, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 92,196,157, 61, 49, 92,210, 62, 87,129,129, 61, 57, 23,233, 62, 68,205, 76, 61,
+135,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68,205, 76, 61,135,190,209, 62,
+ 95,151, 22, 61, 55, 23,233, 62,151, 35,188, 60, 46, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,237, 28, 18, 61, 60,220,187, 62,194,205, 76, 61,186,199,165, 62, 7,191,131, 61, 62,220,187, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7,191,131, 61, 62,220,187, 62, 68,205, 76, 61,135,190,209, 62,
+237, 28, 18, 61, 60,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,151, 35,188, 60,
+ 46, 92,210, 62,237, 28, 18, 61, 60,220,187, 62, 68,205, 76, 61,135,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 68,205, 76, 61,135,190,209, 62, 7,191,131, 61, 62,220,187, 62, 92,196,157, 61, 49, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 87,129,129, 61, 57, 23,233, 62, 92,196,157, 61,
+ 49, 92,210, 62, 89,185,181, 61,214, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 89,185,181, 61,214, 32,233, 62,154,153,153, 61, 25,252,255, 62, 87,129,129, 61, 57, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,204, 76, 61, 0, 0, 0, 63, 87,129,129, 61, 57, 23,233, 62,154,153,153, 61,
+ 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,154,153,153, 61, 25,252,255, 62,
+ 89,185,181, 61,214, 32,233, 62,215,204,204, 61, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 1,135, 11, 62,228,230,198, 62,171, 31,253, 61, 6,196,217, 62,251,181,231, 61, 38,135,193, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251,181,231, 61, 38,135,193, 62,204, 36, 1, 62, 70, 54,174, 62,
+ 1,135, 11, 62,228,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,
+165,111,180, 62, 1,135, 11, 62,228,230,198, 62,204, 36, 1, 62, 70, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,204, 36, 1, 62, 70, 54,174, 62,251,181,231, 61, 38,135,193, 62, 70,117,207, 61, 54,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 35, 68,181, 61,153,208,189, 62, 70,117,207, 61,
+ 54,150,169, 62,251,181,231, 61, 38,135,193, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+251,181,231, 61, 38,135,193, 62,164,181,205, 61,180,159,213, 62, 35, 68,181, 61,153,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 92,196,157, 61, 49, 92,210, 62, 35, 68,181, 61,153,208,189, 62,164,181,205, 61,
+180,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,164,181,205, 61,180,159,213, 62,
+251,181,231, 61, 38,135,193, 62,171, 31,253, 61, 6,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,251,166,228, 61, 67,207,236, 62,215,204,204, 61, 0, 0, 0, 63, 89,185,181, 61,214, 32,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 89,185,181, 61,214, 32,233, 62,164,181,205, 61,180,159,213, 62,
+251,166,228, 61, 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,171, 31,253, 61,
+ 6,196,217, 62,251,166,228, 61, 67,207,236, 62,164,181,205, 61,180,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,164,181,205, 61,180,159,213, 62, 89,185,181, 61,214, 32,233, 62, 92,196,157, 61, 49, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 35, 68,181, 61,153,208,189, 62, 92,196,157, 61,
+ 49, 92,210, 62, 7,191,131, 61, 62,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 7,191,131, 61, 62,220,187, 62, 79, 92,155, 61, 91,190,166, 62, 35, 68,181, 61,153,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70,117,207, 61, 54,150,169, 62, 35, 68,181, 61,153,208,189, 62, 79, 92,155, 61,
+ 91,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 79, 92,155, 61, 91,190,166, 62,
+ 7,191,131, 61, 62,220,187, 62,194,205, 76, 61,186,199,165, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,172,242,180, 61, 96,152, 9, 63, 1,122,156, 61,254, 29, 19, 63,100, 10,129, 61,113,150, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,100, 10,129, 61,113,150, 9, 63,154,153,153, 61, 25,252,255, 62,
+172,242,180, 61, 96,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,204,204, 61,
+ 0, 0, 0, 63,172,242,180, 61, 96,152, 9, 63,154,153,153, 61, 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,154,153,153, 61, 25,252,255, 62,100, 10,129, 61,113,150, 9, 63,215,204, 76, 61, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,132, 23, 61,113,150, 9, 63,215,204, 76, 61,
+ 0, 0, 0, 63,100, 10,129, 61,113,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+100, 10,129, 61,113,150, 9, 63, 91,204, 76, 61,220, 98, 19, 63,109,132, 23, 61,113,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,174, 73,193, 60,253, 29, 19, 63,109,132, 23, 61,113,150, 9, 63, 91,204, 76, 61,
+220, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 91,204, 76, 61,220, 98, 19, 63,
+100, 10,129, 61,113,150, 9, 63, 1,122,156, 61,254, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,166,139,130, 61,145,140, 28, 63,246,203, 76, 61, 48,200, 37, 63, 13,129, 20, 61,143,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 13,129, 20, 61,143,140, 28, 63, 91,204, 76, 61,220, 98, 19, 63,
+166,139,130, 61,145,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,122,156, 61,
+254, 29, 19, 63,166,139,130, 61,145,140, 28, 63, 91,204, 76, 61,220, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 91,204, 76, 61,220, 98, 19, 63, 13,129, 20, 61,143,140, 28, 63,174, 73,193, 60,253, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,132, 23, 61,113,150, 9, 63,174, 73,193, 60,
+253, 29, 19, 63,114,207, 62, 60, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+114,207, 62, 60, 94,152, 9, 63,176,204,204, 60, 24,252,255, 62,109,132, 23, 61,113,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,204, 76, 61, 0, 0, 0, 63,109,132, 23, 61,113,150, 9, 63,176,204,204, 60,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,176,204,204, 60, 24,252,255, 62,
+114,207, 62, 60, 94,152, 9, 63,167, 79, 11, 38, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,237, 83,113, 62, 79,220,187, 62, 63, 81,100, 62, 60, 92,210, 62,110,145, 88, 62,167,208,189, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,110,145, 88, 62,167,208,189, 62, 91,133,101, 62,112,190,166, 62,
+237, 83,113, 62, 79,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+206,199,165, 62,237, 83,113, 62, 79,220,187, 62, 91,133,101, 62,112,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 91,133,101, 62,112,190,166, 62,110,145, 88, 62,167,208,189, 62,239,120, 75, 62, 70,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,144, 88, 63, 62, 46,135,193, 62,239,120, 75, 62,
+ 70,150,169, 62,110,145, 88, 62,167,208,189, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+110,145, 88, 62,167,208,189, 62,170, 88, 76, 62,187,159,213, 62,144, 88, 63, 62, 46,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,163, 52, 62, 7,196,217, 62,144, 88, 63, 62, 46,135,193, 62,170, 88, 76, 62,
+187,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,170, 88, 76, 62,187,159,213, 62,
+110,145, 88, 62,167,208,189, 62, 63, 81,100, 62, 60, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,190, 86, 88, 62,221, 32,233, 62,254,204, 76, 62, 0, 0, 0, 63,251,223, 64, 62, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251,223, 64, 62, 67,207,236, 62,170, 88, 76, 62,187,159,213, 62,
+190, 86, 88, 62,221, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63, 81,100, 62,
+ 60, 92,210, 62,190, 86, 88, 62,221, 32,233, 62,170, 88, 76, 62,187,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,170, 88, 76, 62,187,159,213, 62,251,223, 64, 62, 67,207,236, 62,179,163, 52, 62, 7,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,144, 88, 63, 62, 46,135,193, 62,179,163, 52, 62,
+ 7,196,217, 62,153,172, 39, 62,230,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+153,172, 39, 62,230,230,198, 62,213, 14, 50, 62, 78, 54,174, 62,144, 88, 63, 62, 46,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,120, 75, 62, 70,150,169, 62,144, 88, 63, 62, 46,135,193, 62,213, 14, 50, 62,
+ 78, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213, 14, 50, 62, 78, 54,174, 62,
+153,172, 39, 62,230,230,198, 62,214,153, 25, 62,165,111,180, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,190, 86, 88, 62,221, 32,233, 62, 63, 81,100, 62, 60, 92,210, 62,166,114,114, 62, 63, 23,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,166,114,114, 62, 63, 23,233, 62,126,102,102, 62, 25,252,255, 62,
+190, 86, 88, 62,221, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,254,204, 76, 62,
+ 0, 0, 0, 63,190, 86, 88, 62,221, 32,233, 62,126,102,102, 62, 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,126,102,102, 62, 25,252,255, 62,166,114,114, 62, 63, 23,233, 62, 0, 0,128, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173,198,134, 62, 63, 23,233, 62, 0, 0,128, 62,
+ 0, 0, 0, 63,166,114,114, 62, 63, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+166,114,114, 62, 63, 23,233, 62, 0, 0,128, 62,149,190,209, 62,173,198,134, 62, 63, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 97,215,141, 62, 60, 92,210, 62,173,198,134, 62, 63, 23,233, 62, 0, 0,128, 62,
+149,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,149,190,209, 62,
+166,114,114, 62, 63, 23,233, 62, 63, 81,100, 62, 60, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,237, 83,113, 62, 79,220,187, 62, 0, 0,128, 62,206,199,165, 62, 9, 86,135, 62, 79,220,187, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 9, 86,135, 62, 79,220,187, 62, 0, 0,128, 62,149,190,209, 62,
+237, 83,113, 62, 79,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63, 81,100, 62,
+ 60, 92,210, 62,237, 83,113, 62, 79,220,187, 62, 0, 0,128, 62,149,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,149,190,209, 62, 9, 86,135, 62, 79,220,187, 62, 97,215,141, 62, 60, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,173,198,134, 62, 63, 23,233, 62, 97,215,141, 62,
+ 60, 92,210, 62,161,212,147, 62,221, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+161,212,147, 62,221, 32,233, 62,193,204,140, 62, 25,252,255, 62,173,198,134, 62, 63, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 63,173,198,134, 62, 63, 23,233, 62,193,204,140, 62,
+ 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,193,204,140, 62, 25,252,255, 62,
+161,212,147, 62,221, 32,233, 62,129,153,153, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,180, 41,172, 62,227,230,198, 62, 39,174,165, 62, 7,196,217, 62,184, 83,160, 62, 46,135,193, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,184, 83,160, 62, 46,135,193, 62,150,248,166, 62, 78, 54,174, 62,
+180, 41,172, 62,227,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,
+165,111,180, 62,180, 41,172, 62,227,230,198, 62,150,248,166, 62, 78, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,150,248,166, 62, 78, 54,174, 62,184, 83,160, 62, 46,135,193, 62,137, 67,154, 62, 70,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 73,183,147, 62,167,208,189, 62,137, 67,154, 62,
+ 70,150,169, 62,184, 83,160, 62, 46,135,193, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+184, 83,160, 62, 46,135,193, 62,171,211,153, 62,187,159,213, 62, 73,183,147, 62,167,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 97,215,141, 62, 60, 92,210, 62, 73,183,147, 62,167,208,189, 62,171,211,153, 62,
+187,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,171,211,153, 62,187,159,213, 62,
+184, 83,160, 62, 46,135,193, 62, 39,174,165, 62, 7,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 3,144,159, 62, 67,207,236, 62,129,153,153, 62, 0, 0, 0, 63,161,212,147, 62,221, 32,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,161,212,147, 62,221, 32,233, 62,171,211,153, 62,187,159,213, 62,
+ 3,144,159, 62, 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 39,174,165, 62,
+ 7,196,217, 62, 3,144,159, 62, 67,207,236, 62,171,211,153, 62,187,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,171,211,153, 62,187,159,213, 62,161,212,147, 62,221, 32,233, 62, 97,215,141, 62, 60, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 73,183,147, 62,167,208,189, 62, 97,215,141, 62,
+ 60, 92,210, 62, 9, 86,135, 62, 79,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 9, 86,135, 62, 79,220,187, 62, 82, 61,141, 62,112,190,166, 62, 73,183,147, 62,167,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,137, 67,154, 62, 70,150,169, 62, 73,183,147, 62,167,208,189, 62, 82, 61,141, 62,
+112,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 82, 61,141, 62,112,190,166, 62,
+ 9, 86,135, 62, 79,220,187, 62, 0, 0,128, 62,206,199,165, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 1,163,147, 62, 91,152, 9, 63,224,132,141, 62,246, 29, 19, 63,251,168,134, 62,107,150, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,251,168,134, 62,107,150, 9, 63,193,204,140, 62, 25,252,255, 62,
+ 1,163,147, 62, 91,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129,153,153, 62,
+ 0, 0, 0, 63, 1,163,147, 62, 91,152, 9, 63,193,204,140, 62, 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,193,204,140, 62, 25,252,255, 62,251,168,134, 62,107,150, 9, 63, 0, 0,128, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 11,174,114, 62,107,150, 9, 63, 0, 0,128, 62,
+ 0, 0, 0, 63,251,168,134, 62,107,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+251,168,134, 62,107,150, 9, 63, 0, 0,128, 62,209, 98, 19, 63, 11,174,114, 62,107,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 64,246,100, 62,246, 29, 19, 63, 11,174,114, 62,107,150, 9, 63, 0, 0,128, 62,
+209, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,209, 98, 19, 63,
+251,168,134, 62,107,150, 9, 63,224,132,141, 62,246, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 86, 9,135, 62,130,140, 28, 63, 0, 0,128, 62, 23,200, 37, 63, 83,237,113, 62,130,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 83,237,113, 62,130,140, 28, 63, 0, 0,128, 62,209, 98, 19, 63,
+ 86, 9,135, 62,130,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,224,132,141, 62,
+246, 29, 19, 63, 86, 9,135, 62,130,140, 28, 63, 0, 0,128, 62,209, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,209, 98, 19, 63, 83,237,113, 62,130,140, 28, 63, 64,246,100, 62,246, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 11,174,114, 62,107,150, 9, 63, 64,246,100, 62,
+246, 29, 19, 63,255,185, 88, 62, 90,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+255,185, 88, 62, 90,152, 9, 63,126,102,102, 62, 25,252,255, 62, 11,174,114, 62,107,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 0, 0, 0, 63, 11,174,114, 62,107,150, 9, 63,126,102,102, 62,
+ 25,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,126,102,102, 62, 25,252,255, 62,
+255,185, 88, 62, 90,152, 9, 63,254,204, 76, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 63, 16,223, 62, 62,220,187, 62,233,142,216, 62, 49, 92,210, 62,248,174,210, 62,153,208,189, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,248,174,210, 62,153,208,189, 62,237, 40,217, 62, 91,190,166, 62,
+ 63, 16,223, 62, 62,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 72,102,230, 62,
+183,199,165, 62, 63, 16,223, 62, 62,220,187, 62,237, 40,217, 62, 91,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,237, 40,217, 62, 91,190,166, 62,248,174,210, 62,153,208,189, 62,175, 34,204, 62, 54,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129, 18,198, 62, 37,135,193, 62,175, 34,204, 62,
+ 54,150,169, 62,248,174,210, 62,153,208,189, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+248,174,210, 62,153,208,189, 62,151,146,204, 62,180,159,213, 62,129, 18,198, 62, 37,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,184,192, 62, 6,196,217, 62,129, 18,198, 62, 37,135,193, 62,151,146,204, 62,
+180,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,151,146,204, 62,180,159,213, 62,
+248,174,210, 62,153,208,189, 62,233,142,216, 62, 49, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,170,145,210, 62,214, 32,233, 62,202,204,204, 62, 0, 0, 0, 63, 65,214,198, 62, 67,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65,214,198, 62, 67,207,236, 62,151,146,204, 62,180,159,213, 62,
+170,145,210, 62,214, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,233,142,216, 62,
+ 49, 92,210, 62,170,145,210, 62,214, 32,233, 62,151,146,204, 62,180,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,151,146,204, 62,180,159,213, 62, 65,214,198, 62, 67,207,236, 62, 21,184,192, 62, 6,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,129, 18,198, 62, 37,135,193, 62, 21,184,192, 62,
+ 6,196,217, 62,127, 60,186, 62,225,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+127, 60,186, 62,225,230,198, 62,154,109,191, 62, 68, 54,174, 62,129, 18,198, 62, 37,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,175, 34,204, 62, 54,150,169, 62,129, 18,198, 62, 37,135,193, 62,154,109,191, 62,
+ 68, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,154,109,191, 62, 68, 54,174, 62,
+127, 60,186, 62,225,230,198, 62, 21, 51,179, 62,165,111,180, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,170,145,210, 62,214, 32,233, 62,233,142,216, 62, 49, 92,210, 62,171,159,223, 62, 57, 23,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,171,159,223, 62, 57, 23,233, 62,154,153,217, 62, 24,252,255, 62,
+170,145,210, 62,214, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,202,204,204, 62,
+ 0, 0, 0, 63,170,145,210, 62,214, 32,233, 62,154,153,217, 62, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,154,153,217, 62, 24,252,255, 62,171,159,223, 62, 57, 23,233, 62,101,102,230, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 20, 45,237, 62, 55, 23,233, 62,101,102,230, 62,
+ 0, 0, 0, 63,171,159,223, 62, 57, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+171,159,223, 62, 57, 23,233, 62, 88,102,230, 62,135,190,209, 62, 20, 45,237, 62, 55, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,199, 61,244, 62, 46, 92,210, 62, 20, 45,237, 62, 55, 23,233, 62, 88,102,230, 62,
+135,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 88,102,230, 62,135,190,209, 62,
+171,159,223, 62, 57, 23,233, 62,233,142,216, 62, 49, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 63, 16,223, 62, 62,220,187, 62, 72,102,230, 62,183,199,165, 62, 99,188,237, 62, 60,220,187, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 99,188,237, 62, 60,220,187, 62, 88,102,230, 62,135,190,209, 62,
+ 63, 16,223, 62, 62,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,233,142,216, 62,
+ 49, 92,210, 62, 63, 16,223, 62, 62,220,187, 62, 88,102,230, 62,135,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 88,102,230, 62,135,190,209, 62, 99,188,237, 62, 60,220,187, 62,199, 61,244, 62, 46, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 20, 45,237, 62, 55, 23,233, 62,199, 61,244, 62,
+ 46, 92,210, 62, 21, 59,250, 62,213, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 21, 59,250, 62,213, 32,233, 62, 53, 51,243, 62, 24,252,255, 62, 20, 45,237, 62, 55, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,102,230, 62, 0, 0, 0, 63, 20, 45,237, 62, 55, 23,233, 62, 53, 51,243, 62,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 53, 51,243, 62, 24,252,255, 62,
+ 21, 59,250, 62,213, 32,233, 62, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 17, 72, 9, 63,227,230,198, 62, 77, 10, 6, 63, 6,196,217, 62, 15, 93, 3, 63, 36,135,193, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 15, 93, 3, 63, 36,135,193, 62,123,175, 6, 63, 65, 54,174, 62,
+ 17, 72, 9, 63,227,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,
+160,111,180, 62, 17, 72, 9, 63,227,230,198, 62,123,175, 6, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,123,175, 6, 63, 65, 54,174, 62, 15, 93, 3, 63, 36,135,193, 62,241, 84, 0, 63, 52,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169, 29,250, 62,150,208,189, 62,241, 84, 0, 63,
+ 52,150,169, 62, 15, 93, 3, 63, 36,135,193, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 15, 93, 3, 63, 36,135,193, 62, 12, 29, 0, 63,179,159,213, 62,169, 29,250, 62,150,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,199, 61,244, 62, 46, 92,210, 62,169, 29,250, 62,150,208,189, 62, 12, 29, 0, 63,
+179,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 12, 29, 0, 63,179,159,213, 62,
+ 15, 93, 3, 63, 36,135,193, 62, 77, 10, 6, 63, 6,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 62,251, 2, 63, 67,207,236, 62, 0, 0, 0, 63, 0, 0, 0, 63, 21, 59,250, 62,213, 32,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 59,250, 62,213, 32,233, 62, 12, 29, 0, 63,179,159,213, 62,
+ 62,251, 2, 63, 67,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 77, 10, 6, 63,
+ 6,196,217, 62, 62,251, 2, 63, 67,207,236, 62, 12, 29, 0, 63,179,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 12, 29, 0, 63,179,159,213, 62, 21, 59,250, 62,213, 32,233, 62,199, 61,244, 62, 46, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169, 29,250, 62,150,208,189, 62,199, 61,244, 62,
+ 46, 92,210, 62, 99,188,237, 62, 60,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 99,188,237, 62, 60,220,187, 62,164,163,243, 62, 89,190,166, 62,169, 29,250, 62,150,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,241, 84, 0, 63, 52,150,169, 62,169, 29,250, 62,150,208,189, 62,164,163,243, 62,
+ 89,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,164,163,243, 62, 89,190,166, 62,
+ 99,188,237, 62, 60,220,187, 62, 72,102,230, 62,183,199,165, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,132, 9,250, 62, 94,152, 9, 63,101,235,243, 62,252, 29, 19, 63,114, 15,237, 62,113,150, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,114, 15,237, 62,113,150, 9, 63, 53, 51,243, 62, 24,252,255, 62,
+132, 9,250, 62, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,
+ 0, 0, 0, 63,132, 9,250, 62, 94,152, 9, 63, 53, 51,243, 62, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 53, 51,243, 62, 24,252,255, 62,114, 15,237, 62,113,150, 9, 63,101,102,230, 62, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,103,189,223, 62,112,150, 9, 63,101,102,230, 62,
+ 0, 0, 0, 63,114, 15,237, 62,113,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+114, 15,237, 62,113,150, 9, 63,117,102,230, 62,220, 98, 19, 63,103,189,223, 62,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,128,225,216, 62,254, 29, 19, 63,103,189,223, 62,112,150, 9, 63,117,102,230, 62,
+220, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,117,102,230, 62,220, 98, 19, 63,
+114, 15,237, 62,113,150, 9, 63,101,235,243, 62,252, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,222,111,237, 62,143,140, 28, 63,129,102,230, 62, 48,200, 37, 63, 22, 93,223, 62,145,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22, 93,223, 62,145,140, 28, 63,117,102,230, 62,220, 98, 19, 63,
+222,111,237, 62,143,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,235,243, 62,
+252, 29, 19, 63,222,111,237, 62,143,140, 28, 63,117,102,230, 62,220, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,117,102,230, 62,220, 98, 19, 63, 22, 93,223, 62,145,140, 28, 63,128,225,216, 62,254, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,103,189,223, 62,112,150, 9, 63,128,225,216, 62,
+254, 29, 19, 63, 85,195,210, 62, 96,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 85,195,210, 62, 96,152, 9, 63,154,153,217, 62, 24,252,255, 62,103,189,223, 62,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,101,102,230, 62, 0, 0, 0, 63,103,189,223, 62,112,150, 9, 63,154,153,217, 62,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,154,153,217, 62, 24,252,255, 62,
+ 85,195,210, 62, 96,152, 9, 63,202,204,204, 62, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 97,187, 34, 63, 72,220,187, 62,178,122, 31, 63, 55, 92,210, 62,186,138, 28, 63,155,208,189, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,186,138, 28, 63,155,208,189, 62,185,199, 31, 63, 96,190,166, 62,
+ 97,187, 34, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,107,102, 38, 63,
+201,199,165, 62, 97,187, 34, 63, 72,220,187, 62,185,199, 31, 63, 96,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,185,199, 31, 63, 96,190,166, 62,186,138, 28, 63,155,208,189, 62,150, 68, 25, 63, 54,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,123, 60, 22, 63, 36,135,193, 62,150, 68, 25, 63,
+ 54,150,169, 62,186,138, 28, 63,155,208,189, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+186,138, 28, 63,155,208,189, 62,133,124, 25, 63,181,159,213, 62,123, 60, 22, 63, 36,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 64,143, 19, 63, 4,196,217, 62,123, 60, 22, 63, 36,135,193, 62,133,124, 25, 63,
+181,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,133,124, 25, 63,181,159,213, 62,
+186,138, 28, 63,155,208,189, 62,178,122, 31, 63, 55, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 14,124, 28, 63,218, 32,233, 62,155,153, 25, 63, 0, 0, 0, 63, 86,158, 22, 63, 65,207,236, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 86,158, 22, 63, 65,207,236, 62,133,124, 25, 63,181,159,213, 62,
+ 14,124, 28, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,178,122, 31, 63,
+ 55, 92,210, 62, 14,124, 28, 63,218, 32,233, 62,133,124, 25, 63,181,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,133,124, 25, 63,181,159,213, 62, 86,158, 22, 63, 65,207,236, 62, 64,143, 19, 63, 4,196,217, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,123, 60, 22, 63, 36,135,193, 62, 64,143, 19, 63,
+ 4,196,217, 62,117, 81, 16, 63,223,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+117, 81, 16, 63,223,230,198, 62, 7,234, 18, 63, 65, 54,174, 62,123, 60, 22, 63, 36,135,193, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,150, 68, 25, 63, 54,150,169, 62,123, 60, 22, 63, 36,135,193, 62, 7,234, 18, 63,
+ 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7,234, 18, 63, 65, 54,174, 62,
+117, 81, 16, 63,223,230,198, 62,191,204, 12, 63,160,111,180, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 14,124, 28, 63,218, 32,233, 62,178,122, 31, 63, 55, 92,210, 62, 17, 3, 35, 63, 58, 23,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 17, 3, 35, 63, 58, 23,233, 62, 2, 0, 32, 63, 24,252,255, 62,
+ 14,124, 28, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,155,153, 25, 63,
+ 0, 0, 0, 63, 14,124, 28, 63,218, 32,233, 62, 2, 0, 32, 63, 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 32, 63, 24,252,255, 62, 17, 3, 35, 63, 58, 23,233, 62,109,102, 38, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,200,201, 41, 63, 58, 23,233, 62,109,102, 38, 63,
+ 0, 0, 0, 63, 17, 3, 35, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 17, 3, 35, 63, 58, 23,233, 62,109,102, 38, 63,143,190,209, 62,200,201, 41, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 82, 45, 63, 55, 92,210, 62,200,201, 41, 63, 58, 23,233, 62,109,102, 38, 63,
+143,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,102, 38, 63,143,190,209, 62,
+ 17, 3, 35, 63, 58, 23,233, 62,178,122, 31, 63, 55, 92,210, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 97,187, 34, 63, 72,220,187, 62,107,102, 38, 63,201,199,165, 62,118, 17, 42, 63, 72,220,187, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,118, 17, 42, 63, 72,220,187, 62,109,102, 38, 63,143,190,209, 62,
+ 97,187, 34, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,178,122, 31, 63,
+ 55, 92,210, 62, 97,187, 34, 63, 72,220,187, 62,109,102, 38, 63,143,190,209, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,109,102, 38, 63,143,190,209, 62,118, 17, 42, 63, 72,220,187, 62, 38, 82, 45, 63, 55, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,200,201, 41, 63, 58, 23,233, 62, 38, 82, 45, 63,
+ 55, 92,210, 62,204, 80, 48, 63,218, 32,233, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+204, 80, 48, 63,218, 32,233, 62,215,204, 44, 63, 23,252,255, 62,200,201, 41, 63, 58, 23,233, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,102, 38, 63, 0, 0, 0, 63,200,201, 41, 63, 58, 23,233, 62,215,204, 44, 63,
+ 23,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,204, 44, 63, 23,252,255, 62,
+204, 80, 48, 63,218, 32,233, 62, 63, 51, 51, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 85,123, 60, 63,253,230,198, 62,144, 61, 57, 63, 19,196,217, 62, 86,144, 54, 63, 68,135,193, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 86,144, 54, 63, 68,135,193, 62,196,226, 57, 63,114, 54,174, 62,
+ 85,123, 60, 63,253,230,198, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+211,111,180, 62, 85,123, 60, 63,253,230,198, 62,196,226, 57, 63,114, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,196,226, 57, 63,114, 54,174, 62, 86,144, 54, 63, 68,135,193, 62, 58,136, 51, 63, 90,150,169, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 27, 66, 48, 63,173,208,189, 62, 58,136, 51, 63,
+ 90,150,169, 62, 86,144, 54, 63, 68,135,193, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 86,144, 54, 63, 68,135,193, 62, 80, 80, 51, 63,192,159,213, 62, 27, 66, 48, 63,173,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 82, 45, 63, 55, 92,210, 62, 27, 66, 48, 63,173,208,189, 62, 80, 80, 51, 63,
+192,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 80, 80, 51, 63,192,159,213, 62,
+ 86,144, 54, 63, 68,135,193, 62,144, 61, 57, 63, 19,196,217, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,128, 46, 54, 63, 75,207,236, 62, 63, 51, 51, 63, 0, 0, 0, 63,204, 80, 48, 63,218, 32,233, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,204, 80, 48, 63,218, 32,233, 62, 80, 80, 51, 63,192,159,213, 62,
+128, 46, 54, 63, 75,207,236, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,144, 61, 57, 63,
+ 19,196,217, 62,128, 46, 54, 63, 75,207,236, 62, 80, 80, 51, 63,192,159,213, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 80, 80, 51, 63,192,159,213, 62,204, 80, 48, 63,218, 32,233, 62, 38, 82, 45, 63, 55, 92,210, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 27, 66, 48, 63,173,208,189, 62, 38, 82, 45, 63,
+ 55, 92,210, 62,118, 17, 42, 63, 72,220,187, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+118, 17, 42, 63, 72,220,187, 62, 26, 5, 45, 63,117,190,166, 62, 27, 66, 48, 63,173,208,189, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 58,136, 51, 63, 90,150,169, 62, 27, 66, 48, 63,173,208,189, 62, 26, 5, 45, 63,
+117,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 26, 5, 45, 63,117,190,166, 62,
+118, 17, 42, 63, 72,220,187, 62,107,102, 38, 63,201,199,165, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,255, 55, 48, 63, 94,152, 9, 63,237, 40, 45, 63,252, 29, 19, 63,242,186, 41, 63,112,150, 9, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,242,186, 41, 63,112,150, 9, 63,215,204, 44, 63, 23,252,255, 62,
+255, 55, 48, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63, 51, 51, 63,
+ 0, 0, 0, 63,255, 55, 48, 63, 94,152, 9, 63,215,204, 44, 63, 23,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,215,204, 44, 63, 23,252,255, 62,242,186, 41, 63,112,150, 9, 63,109,102, 38, 63, 0, 0, 0, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235, 17, 35, 63,112,150, 9, 63,109,102, 38, 63,
+ 0, 0, 0, 63,242,186, 41, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+242,186, 41, 63,112,150, 9, 63,113,102, 38, 63,219, 98, 19, 63,235, 17, 35, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,245,163, 31, 63,253, 29, 19, 63,235, 17, 35, 63,112,150, 9, 63,113,102, 38, 63,
+219, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,113,102, 38, 63,219, 98, 19, 63,
+242,186, 41, 63,112,150, 9, 63,237, 40, 45, 63,252, 29, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 38,235, 41, 63,141,140, 28, 63,117,102, 38, 63, 45,200, 37, 63,192,225, 34, 63,142,140, 28, 63, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192,225, 34, 63,142,140, 28, 63,113,102, 38, 63,219, 98, 19, 63,
+ 38,235, 41, 63,141,140, 28, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,237, 40, 45, 63,
+252, 29, 19, 63, 38,235, 41, 63,141,140, 28, 63,113,102, 38, 63,219, 98, 19, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,113,102, 38, 63,219, 98, 19, 63,192,225, 34, 63,142,140, 28, 63,245,163, 31, 63,253, 29, 19, 63,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235, 17, 35, 63,112,150, 9, 63,245,163, 31, 63,
+253, 29, 19, 63,223,148, 28, 63, 94,152, 9, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+223,148, 28, 63, 94,152, 9, 63, 2, 0, 32, 63, 24,252,255, 62,235, 17, 35, 63,112,150, 9, 63, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,109,102, 38, 63, 0, 0, 0, 63,235, 17, 35, 63,112,150, 9, 63, 2, 0, 32, 63,
+ 24,252,255, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 32, 63, 24,252,255, 62,
+223,148, 28, 63, 94,152, 9, 63,155,153, 25, 63, 0, 0, 0, 63, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,188,129,107, 63, 66, 45,128, 62,235, 71, 99, 63,222, 76,120, 62, 94, 37,106, 63, 84, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 94, 37,106, 63, 84, 97, 83, 62, 65, 51,115, 63,248,151, 97, 62,
+188,129,107, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,
+151, 83,135, 62,188,129,107, 63, 66, 45,128, 62, 65, 51,115, 63,248,151, 97, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,248,151, 97, 62, 94, 37,106, 63, 84, 97, 83, 62, 65, 51,115, 63, 90,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,188,129,107, 63, 66, 45,128, 62, 65, 51,115, 63,
+151, 83,135, 62,142,123,108, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+142,123,108, 63,169,144,151, 62,231, 50,101, 63, 17,201,146, 62,188,129,107, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235, 71, 99, 63,222, 76,120, 62,188,129,107, 63, 66, 45,128, 62,231, 50,101, 63,
+ 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,231, 50,101, 63, 17,201,146, 62,
+142,123,108, 63,169,144,151, 62,106,187,102, 63, 54,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 71, 56, 96, 63, 99,190,166, 62,149,153, 89, 63,201,199,165, 62, 22,238, 93, 63,243,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22,238, 93, 63,243,101,144, 62,231, 50,101, 63, 17,201,146, 62,
+ 71, 56, 96, 63, 99,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,106,187,102, 63,
+ 54,150,169, 62, 71, 56, 96, 63, 99,190,166, 62,231, 50,101, 63, 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,231, 50,101, 63, 17,201,146, 62, 22,238, 93, 63,243,101,144, 62,235, 71, 99, 63,222, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,249, 21,109, 63, 65, 54,174, 62,106,187,102, 63,
+ 54,150,169, 62,142,123,108, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+142,123,108, 63,169,144,151, 62, 65, 51,115, 63, 93,231,157, 62,249, 21,109, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,160,111,180, 62,249, 21,109, 63, 65, 54,174, 62, 65, 51,115, 63,
+ 93,231,157, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63, 93,231,157, 62,
+142,123,108, 63,169,144,151, 62, 65, 51,115, 63,151, 83,135, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,149,153, 89, 63, 79,162,115, 62,235, 71, 99, 63,222, 76,120, 62, 22,238, 93, 63,243,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22,238, 93, 63,243,101,144, 62, 21, 69, 85, 63, 3,102,144, 62,
+149,153, 89, 63, 79,162,115, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68,235, 79, 63,
+ 37, 77,120, 62,149,153, 89, 63, 79,162,115, 62, 21, 69, 85, 63, 3,102,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 21, 69, 85, 63, 3,102,144, 62, 22,238, 93, 63,243,101,144, 62,149,153, 89, 63,201,199,165, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,149,153, 89, 63, 79,162,115, 62, 68,235, 79, 63,
+ 37, 77,120, 62, 24,186, 83, 63,245,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 24,186, 83, 63,245,176, 70, 62, 22,121, 95, 63,204,176, 70, 62,149,153, 89, 63, 79,162,115, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235, 71, 99, 63,222, 76,120, 62,149,153, 89, 63, 79,162,115, 62, 22,121, 95, 63,
+204,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22,121, 95, 63,204,176, 70, 62,
+ 24,186, 83, 63,245,176, 70, 62,152,153, 89, 63,198, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 61,119,103, 63,179,253, 30, 62, 65, 51,115, 63, 90,111, 52, 62, 94, 37,106, 63, 84, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 94, 37,106, 63, 84, 97, 83, 62, 22,121, 95, 63,204,176, 70, 62,
+ 61,119,103, 63,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,152,153, 89, 63,
+198, 31, 23, 62, 61,119,103, 63,179,253, 30, 62, 22,121, 95, 63,204,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 22,121, 95, 63,204,176, 70, 62, 94, 37,106, 63, 84, 97, 83, 62,235, 71, 99, 63,222, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,248,187, 75, 63,241,253, 30, 62,152,153, 89, 63,
+198, 31, 23, 62, 24,186, 83, 63,245,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 24,186, 83, 63,245,176, 70, 62,214, 13, 73, 63,181, 97, 83, 62,248,187, 75, 63,241,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,202,111, 52, 62,248,187, 75, 63,241,253, 30, 62,214, 13, 73, 63,
+181, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214, 13, 73, 63,181, 97, 83, 62,
+ 24,186, 83, 63,245,176, 70, 62, 68,235, 79, 63, 37, 77,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,152,153, 89, 63,111, 41,147, 61, 0, 0, 64, 63,195,111,180, 61, 0, 0, 64, 63,111, 65, 52, 61, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,111, 65, 52, 61, 38, 49,117, 63,225, 64, 52, 61,
+152,153, 89, 63,111, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,
+ 83,111,180, 61,152,153, 89, 63,111, 41,147, 61, 38, 49,117, 63,225, 64, 52, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 38, 49,117, 63,225, 64, 52, 61, 0, 0, 64, 63,111, 65, 52, 61,208,222,121, 63,102, 9,239,178,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,152,153, 89, 63,111, 41,147, 61, 65, 51,115, 63,
+ 83,111,180, 61,172, 51, 99, 63, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+172, 51, 99, 63, 48, 46,231, 61,135,255, 79, 63,120, 46,231, 61,152,153, 89, 63,111, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,195,111,180, 61,152,153, 89, 63,111, 41,147, 61,135,255, 79, 63,
+120, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,135,255, 79, 63,120, 46,231, 61,
+172, 51, 99, 63, 48, 46,231, 61,152,153, 89, 63,198, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,248,187, 75, 63,241,253, 30, 62, 0, 0, 64, 63,202,111, 52, 62, 0, 0, 64, 63, 24, 71, 7, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63, 24, 71, 7, 62,135,255, 79, 63,120, 46,231, 61,
+248,187, 75, 63,241,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,152,153, 89, 63,
+198, 31, 23, 62,248,187, 75, 63,241,253, 30, 62,135,255, 79, 63,120, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,135,255, 79, 63,120, 46,231, 61, 0, 0, 64, 63, 24, 71, 7, 62, 0, 0, 64, 63,195,111,180, 61,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 61,119,103, 63,179,253, 30, 62,152,153, 89, 63,
+198, 31, 23, 62,172, 51, 99, 63, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+172, 51, 99, 63, 48, 46,231, 61, 66, 51,115, 63,199, 70, 7, 62, 61,119,103, 63,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63, 90,111, 52, 62, 61,119,103, 63,179,253, 30, 62, 66, 51,115, 63,
+199, 70, 7, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 66, 51,115, 63,199, 70, 7, 62,
+172, 51, 99, 63, 48, 46,231, 61, 65, 51,115, 63, 83,111,180, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,122,177, 71, 63,120, 45,128, 62, 0, 0, 64, 63,218, 83,135, 62, 0, 0, 64, 63,115,152, 97, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,115,152, 97, 62,214, 13, 73, 63,181, 97, 83, 62,
+122,177, 71, 63,120, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68,235, 79, 63,
+ 37, 77,120, 62,122,177, 71, 63,120, 45,128, 62,214, 13, 73, 63,181, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,214, 13, 73, 63,181, 97, 83, 62, 0, 0, 64, 63,115,152, 97, 62, 0, 0, 64, 63,202,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,122,177, 71, 63,120, 45,128, 62, 68,235, 79, 63,
+ 37, 77,120, 62, 72, 0, 78, 63, 52,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 72, 0, 78, 63, 52,201,146, 62,169,183, 70, 63,219,144,151, 62,122,177, 71, 63,120, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,218, 83,135, 62,122,177, 71, 63,120, 45,128, 62,169,183, 70, 63,
+219,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,169,183, 70, 63,219,144,151, 62,
+ 72, 0, 78, 63, 52,201,146, 62,198,119, 76, 63, 90,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 61, 29, 70, 63,114, 54,174, 62, 0, 0, 64, 63,211,111,180, 62, 0, 0, 64, 63,162,231,157, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,162,231,157, 62,169,183, 70, 63,219,144,151, 62,
+ 61, 29, 70, 63,114, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,198,119, 76, 63,
+ 90,150,169, 62, 61, 29, 70, 63,114, 54,174, 62,169,183, 70, 63,219,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,169,183, 70, 63,219,144,151, 62, 0, 0, 64, 63,162,231,157, 62, 0, 0, 64, 63,218, 83,135, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,230,250, 82, 63,117,190,166, 62,198,119, 76, 63,
+ 90,150,169, 62, 72, 0, 78, 63, 52,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 72, 0, 78, 63, 52,201,146, 62, 21, 69, 85, 63, 3,102,144, 62,230,250, 82, 63,117,190,166, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,149,153, 89, 63,201,199,165, 62,230,250, 82, 63,117,190,166, 62, 21, 69, 85, 63,
+ 3,102,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 69, 85, 63, 3,102,144, 62,
+ 72, 0, 78, 63, 52,201,146, 62, 68,235, 79, 63, 37, 77,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,179,167,245, 61, 72, 45,128, 62, 94,217,179, 61,222, 76,120, 62,202,196,234, 61,100, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,202,196,234, 61,100, 97, 83, 62,212,153, 25, 62, 2,152, 97, 62,
+179,167,245, 61, 72, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,
+156, 83,135, 62,179,167,245, 61, 72, 45,128, 62,212,153, 25, 62, 2,152, 97, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,212,153, 25, 62, 2,152, 97, 62,202,196,234, 61,100, 97, 83, 62,214,153, 25, 62,106,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,179,167,245, 61, 72, 45,128, 62,214,153, 25, 62,
+156, 83,135, 62, 62,118,253, 61,174,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 62,118,253, 61,174,144,151, 62, 53, 49,195, 61, 17,201,146, 62,179,167,245, 61, 72, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 94,217,179, 61,222, 76,120, 62,179,167,245, 61, 72, 45,128, 62, 53, 49,195, 61,
+ 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 53, 49,195, 61, 17,201,146, 62,
+ 62,118,253, 61,174,144,151, 62, 70,117,207, 61, 54,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 79, 92,155, 61, 91,190,166, 62,194,205, 76, 61,186,199,165, 62,212, 10,137, 61,238,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212, 10,137, 61,238,101,144, 62, 53, 49,195, 61, 17,201,146, 62,
+ 79, 92,155, 61, 91,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70,117,207, 61,
+ 54,150,169, 62, 79, 92,155, 61, 91,190,166, 62, 53, 49,195, 61, 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 53, 49,195, 61, 17,201,146, 62,212, 10,137, 61,238,101,144, 62, 94,217,179, 61,222, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,204, 36, 1, 62, 70, 54,174, 62, 70,117,207, 61,
+ 54,150,169, 62, 62,118,253, 61,174,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 62,118,253, 61,174,144,151, 62,213,153, 25, 62,100,231,157, 62,204, 36, 1, 62, 70, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,165,111,180, 62,204, 36, 1, 62, 70, 54,174, 62,213,153, 25, 62,
+100,231,157, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213,153, 25, 62,100,231,157, 62,
+ 62,118,253, 61,174,144,151, 62,214,153, 25, 62,156, 83,135, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,188,205, 76, 61, 53,162,115, 62, 94,217,179, 61,222, 76,120, 62,212, 10,137, 61,238,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212, 10,137, 61,238,101,144, 62,207,133, 7, 61,236,101,144, 62,
+188,205, 76, 61, 53,162,115, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,255,162, 71, 60,
+216, 76,120, 62,188,205, 76, 61, 53,162,115, 62,207,133, 7, 61,236,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,207,133, 7, 61,236,101,144, 62,212, 10,137, 61,238,101,144, 62,194,205, 76, 61,186,199,165, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,188,205, 76, 61, 53,162,115, 62,255,162, 71, 60,
+216, 76,120, 62,190,171,221, 60,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+190,171,221, 60,194,176, 70, 62,194, 98,149, 61,194,176, 70, 62,188,205, 76, 61, 53,162,115, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 94,217,179, 61,222, 76,120, 62,188,205, 76, 61, 53,162,115, 62,194, 98,149, 61,
+194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,194, 98,149, 61,194,176, 70, 62,
+190,171,221, 60,194,176, 70, 62,193,205, 76, 61,168, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,198, 83,213, 61,179,253, 30, 62,214,153, 25, 62,106,111, 52, 62,202,196,234, 61,100, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,202,196,234, 61,100, 97, 83, 62,194, 98,149, 61,194,176, 70, 62,
+198, 83,213, 61,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,193,205, 76, 61,
+168, 31, 23, 62,198, 83,213, 61,179,253, 30, 62,194, 98,149, 61,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,194, 98,149, 61,194,176, 70, 62,202,196,234, 61,100, 97, 83, 62, 94,217,179, 61,222, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 59,239,126, 63,174,253, 30, 62,154,105,131, 63,
+168, 31, 23, 62,175,118,131, 63,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+175,118,131, 63,194,176, 70, 62, 30, 65,124, 63, 90, 97, 83, 62, 59,239,126, 63,174,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63, 90,111, 52, 62, 59,239,126, 63,174,253, 30, 62, 30, 65,124, 63,
+ 90, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 30, 65,124, 63, 90, 97, 83, 62,
+175,118,131, 63,194,176, 70, 62, 70,143,129, 63,216, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,156,105,131, 63,101, 41,147, 61, 65, 51,115, 63, 83,111,180, 61, 38, 49,117, 63,225, 64, 52, 61, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 38, 49,117, 63,225, 64, 52, 61,232,148,135, 63,144,158,125, 60,
+156,105,131, 63,101, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,153, 25, 62,
+104,111,180, 61,122,245,128, 61,101, 41,147, 61,224,153, 25, 62,225, 64, 52, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,232,148,135, 63,144,158,125, 60, 38, 49,117, 63,225, 64, 52, 61,208,222,121, 63,102, 9,239,178,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,122,245,128, 61,101, 41,147, 61,215,153, 25, 62,
+104,111,180, 61, 89, 55,179, 61, 38, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 89, 55,179, 61, 38, 46,231, 61, 96,147,208, 60, 48, 46,231, 61,122,245,128, 61,101, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63, 83,111,180, 61,156,105,131, 63,101, 41,147, 61,102,153,129, 63,
+ 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 96,147,208, 60, 48, 46,231, 61,
+ 89, 55,179, 61, 38, 46,231, 61,193,205, 76, 61,168, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 59,239,126, 63,174,253, 30, 62, 65, 51,115, 63, 90,111, 52, 62, 66, 51,115, 63,199, 70, 7, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 66, 51,115, 63,199, 70, 7, 62,102,153,129, 63, 48, 46,231, 61,
+ 59,239,126, 63,174,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,154,105,131, 63,
+168, 31, 23, 62, 59,239,126, 63,174,253, 30, 62,102,153,129, 63, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,102,153,129, 63, 48, 46,231, 61, 66, 51,115, 63,199, 70, 7, 62, 65, 51,115, 63, 83,111,180, 61,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,198, 83,213, 61,179,253, 30, 62,193,205, 76, 61,
+168, 31, 23, 62, 89, 55,179, 61, 38, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 89, 55,179, 61, 38, 46,231, 61,217,153, 25, 62,204, 70, 7, 62,198, 83,213, 61,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,106,111, 52, 62,198, 83,213, 61,179,253, 30, 62,217,153, 25, 62,
+204, 70, 7, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,217,153, 25, 62,204, 70, 7, 62,
+ 89, 55,179, 61, 38, 46,231, 61,215,153, 25, 62,104,111,180, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,192,228,122, 63, 66, 45,128, 62, 65, 51,115, 63,151, 83,135, 62, 65, 51,115, 63,248,151, 97, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,248,151, 97, 62, 30, 65,124, 63, 90, 97, 83, 62,
+192,228,122, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70,143,129, 63,
+216, 76,120, 62,192,228,122, 63, 66, 45,128, 62, 30, 65,124, 63, 90, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 30, 65,124, 63, 90, 97, 83, 62, 65, 51,115, 63,248,151, 97, 62, 65, 51,115, 63, 90,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192,228,122, 63, 66, 45,128, 62, 70,143,129, 63,
+216, 76,120, 62,201,153,128, 63, 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+201,153,128, 63, 14,201,146, 62,239,234,121, 63,169,144,151, 62,192,228,122, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63,151, 83,135, 62,192,228,122, 63, 66, 45,128, 62,239,234,121, 63,
+169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,234,121, 63,169,144,151, 62,
+201,153,128, 63, 14,201,146, 62, 15,171,127, 63, 52,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,133, 80,121, 63, 65, 54,174, 62, 65, 51,115, 63,160,111,180, 62, 65, 51,115, 63, 93,231,157, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 65, 51,115, 63, 93,231,157, 62,239,234,121, 63,169,144,151, 62,
+133, 80,121, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 15,171,127, 63,
+ 52,150,169, 62,133, 80,121, 63, 65, 54,174, 62,239,234,121, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,239,234,121, 63,169,144,151, 62, 65, 51,115, 63, 93,231,157, 62, 65, 51,115, 63,151, 83,135, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 23, 23,131, 63, 89,190,166, 62, 15,171,127, 63,
+ 52,150,169, 62,201,153,128, 63, 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+136,200,153, 59, 14,201,146, 62,207,133, 7, 61,236,101,144, 62,195,197,197, 60, 89,190,166, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,194,205, 76, 61,186,199,165, 62,195,197,197, 60, 89,190,166, 62,207,133, 7, 61,
+236,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,207,133, 7, 61,236,101,144, 62,
+136,200,153, 59, 14,201,146, 62,255,162, 71, 60,216, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 32,208,163, 62, 79, 45,128, 62,147, 92,147, 62,252, 76,120, 62,102, 23,161, 62,115, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,102, 23,161, 62,115, 97, 83, 62, 22, 51,179, 62, 2,152, 97, 62,
+ 32,208,163, 62, 79, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,
+156, 83,135, 62, 32,208,163, 62, 79, 45,128, 62, 22, 51,179, 62, 2,152, 97, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 22, 51,179, 62, 2,152, 97, 62,102, 23,161, 62,115, 97, 83, 62, 21, 51,179, 62,101,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 32,208,163, 62, 79, 45,128, 62, 21, 51,179, 62,
+156, 83,135, 62,194,195,165, 62,181,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+194,195,165, 62,181,144,151, 62,134, 50,151, 62, 29,201,146, 62, 32,208,163, 62, 79, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147, 92,147, 62,252, 76,120, 62, 32,208,163, 62, 79, 45,128, 62,134, 50,151, 62,
+ 29,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,134, 50,151, 62, 29,201,146, 62,
+194,195,165, 62,181,144,151, 62,137, 67,154, 62, 70,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 82, 61,141, 62,112,190,166, 62, 0, 0,128, 62,206,199,165, 62,247,168,136, 62, 3,102,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,247,168,136, 62, 3,102,144, 62,134, 50,151, 62, 29,201,146, 62,
+ 82, 61,141, 62,112,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,137, 67,154, 62,
+ 70,150,169, 62, 82, 61,141, 62,112,190,166, 62,134, 50,151, 62, 29,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,134, 50,151, 62, 29,201,146, 62,247,168,136, 62, 3,102,144, 62,147, 92,147, 62,252, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,150,248,166, 62, 78, 54,174, 62,137, 67,154, 62,
+ 70,150,169, 62,194,195,165, 62,181,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+194,195,165, 62,181,144,151, 62, 21, 51,179, 62, 98,231,157, 62,150,248,166, 62, 78, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,165,111,180, 62,150,248,166, 62, 78, 54,174, 62, 21, 51,179, 62,
+ 98,231,157, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62, 98,231,157, 62,
+194,195,165, 62,181,144,151, 62, 21, 51,179, 62,156, 83,135, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,128, 62, 89,162,115, 62,147, 92,147, 62,252, 76,120, 62,247,168,136, 62, 3,102,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,247,168,136, 62, 3,102,144, 62, 18,174,110, 62, 3,102,144, 62,
+ 0, 0,128, 62, 89,162,115, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,217, 70, 89, 62,
+252, 76,120, 62, 0, 0,128, 62, 89,162,115, 62, 18,174,110, 62, 3,102,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 18,174,110, 62, 3,102,144, 62,247,168,136, 62, 3,102,144, 62, 0, 0,128, 62,206,199,165, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62, 89,162,115, 62,217, 70, 89, 62,
+252, 76,120, 62, 30,130,104, 62,230,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 30,130,104, 62,230,176, 70, 62,241,190,139, 62,230,176, 70, 62, 0, 0,128, 62, 89,162,115, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,147, 92,147, 62,252, 76,120, 62, 0, 0,128, 62, 89,162,115, 62,241,190,139, 62,
+230,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,241,190,139, 62,230,176, 70, 62,
+ 30,130,104, 62,230,176, 70, 62, 0, 0,128, 62,208, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 41,187,155, 62,205,253, 30, 62, 21, 51,179, 62,101,111, 52, 62,102, 23,161, 62,115, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,102, 23,161, 62,115, 97, 83, 62,241,190,139, 62,230,176, 70, 62,
+ 41,187,155, 62,205,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+208, 31, 23, 62, 41,187,155, 62,205,253, 30, 62,241,190,139, 62,230,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,241,190,139, 62,230,176, 70, 62,102, 23,161, 62,115, 97, 83, 62,147, 92,147, 62,252, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,174,137, 72, 62,205,253, 30, 62, 0, 0,128, 62,
+208, 31, 23, 62, 30,130,104, 62,230,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 30,130,104, 62,230,176, 70, 62, 51,209, 61, 62,115, 97, 83, 62,174,137, 72, 62,205,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,106,111, 52, 62,174,137, 72, 62,205,253, 30, 62, 51,209, 61, 62,
+115, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 51,209, 61, 62,115, 97, 83, 62,
+ 30,130,104, 62,230,176, 70, 62,217, 70, 89, 62,252, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,255,255,127, 62,141, 41,147, 61,215,153, 25, 62,104,111,180, 61,224,153, 25, 62,225, 64, 52, 61, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,224,153, 25, 62,225, 64, 52, 61, 15, 51,179, 62,225, 64, 52, 61,
+255,255,127, 62,141, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 20, 51,179, 62,
+104,111,180, 61,255,255,127, 62,141, 41,147, 61, 15, 51,179, 62,225, 64, 52, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 15, 51,179, 62,225, 64, 52, 61,224,153, 25, 62,225, 64, 52, 61,144,175,161, 62,102, 9,239,178,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,255,255,127, 62,141, 41,147, 61, 20, 51,179, 62,
+104,111,180, 61, 12, 52,147, 62,109, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 12, 52,147, 62,109, 46,231, 61,231,151, 89, 62,109, 46,231, 61,255,255,127, 62,141, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,215,153, 25, 62,104,111,180, 61,255,255,127, 62,141, 41,147, 61,231,151, 89, 62,
+109, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,231,151, 89, 62,109, 46,231, 61,
+ 12, 52,147, 62,109, 46,231, 61, 0, 0,128, 62,208, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,174,137, 72, 62,205,253, 30, 62,214,153, 25, 62,106,111, 52, 62,217,153, 25, 62,204, 70, 7, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,217,153, 25, 62,204, 70, 7, 62,231,151, 89, 62,109, 46,231, 61,
+174,137, 72, 62,205,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,
+208, 31, 23, 62,174,137, 72, 62,205,253, 30, 62,231,151, 89, 62,109, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,231,151, 89, 62,109, 46,231, 61,217,153, 25, 62,204, 70, 7, 62,215,153, 25, 62,104,111,180, 61,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 41,187,155, 62,205,253, 30, 62, 0, 0,128, 62,
+208, 31, 23, 62, 12, 52,147, 62,109, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 12, 52,147, 62,109, 46,231, 61, 19, 51,179, 62,204, 70, 7, 62, 41,187,155, 62,205,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,101,111, 52, 62, 41,187,155, 62,205,253, 30, 62, 19, 51,179, 62,
+204, 70, 7, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 19, 51,179, 62,204, 70, 7, 62,
+ 12, 52,147, 62,109, 46,231, 61, 20, 51,179, 62,104,111,180, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,192, 95, 56, 62, 79, 45,128, 62,214,153, 25, 62,156, 83,135, 62,212,153, 25, 62, 2,152, 97, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,212,153, 25, 62, 2,152, 97, 62, 51,209, 61, 62,115, 97, 83, 62,
+192, 95, 56, 62, 79, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,217, 70, 89, 62,
+252, 76,120, 62,192, 95, 56, 62, 79, 45,128, 62, 51,209, 61, 62,115, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 51,209, 61, 62,115, 97, 83, 62,212,153, 25, 62, 2,152, 97, 62,214,153, 25, 62,106,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,192, 95, 56, 62, 79, 45,128, 62,217, 70, 89, 62,
+252, 76,120, 62,245,154, 81, 62, 29,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+245,154, 81, 62, 29,201,146, 62,125,120, 52, 62,181,144,151, 62,192, 95, 56, 62, 79, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,214,153, 25, 62,156, 83,135, 62,192, 95, 56, 62, 79, 45,128, 62,125,120, 52, 62,
+181,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,125,120, 52, 62,181,144,151, 62,
+245,154, 81, 62, 29,201,146, 62,239,120, 75, 62, 70,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,213, 14, 50, 62, 78, 54,174, 62,214,153, 25, 62,165,111,180, 62,213,153, 25, 62,100,231,157, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,213,153, 25, 62,100,231,157, 62,125,120, 52, 62,181,144,151, 62,
+213, 14, 50, 62, 78, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,239,120, 75, 62,
+ 70,150,169, 62,213, 14, 50, 62, 78, 54,174, 62,125,120, 52, 62,181,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,125,120, 52, 62,181,144,151, 62,213,153, 25, 62,100,231,157, 62,214,153, 25, 62,156, 83,135, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 91,133,101, 62,112,190,166, 62,239,120, 75, 62,
+ 70,150,169, 62,245,154, 81, 62, 29,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+245,154, 81, 62, 29,201,146, 62, 18,174,110, 62, 3,102,144, 62, 91,133,101, 62,112,190,166, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,128, 62,206,199,165, 62, 91,133,101, 62,112,190,166, 62, 18,174,110, 62,
+ 3,102,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 18,174,110, 62, 3,102,144, 62,
+245,154, 81, 62, 29,201,146, 62,217, 70, 89, 62,252, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 64, 27, 5, 63, 66, 45,128, 62,232,194,249, 62,216, 76,120, 62,226,190, 3, 63, 90, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,226,190, 3, 63, 90, 97, 83, 62,191,204, 12, 63,248,151, 97, 62,
+ 64, 27, 5, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,
+149, 83,135, 62, 64, 27, 5, 63, 66, 45,128, 62,191,204, 12, 63,248,151, 97, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,248,151, 97, 62,226,190, 3, 63, 90, 97, 83, 62,191,204, 12, 63, 90,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 64, 27, 5, 63, 66, 45,128, 62,191,204, 12, 63,
+149, 83,135, 62, 17, 21, 6, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 17, 21, 6, 63,169,144,151, 62,222,152,253, 62, 14,201,146, 62, 64, 27, 5, 63, 66, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,232,194,249, 62,216, 76,120, 62, 64, 27, 5, 63, 66, 45,128, 62,222,152,253, 62,
+ 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,222,152,253, 62, 14,201,146, 62,
+ 17, 21, 6, 63,169,144,151, 62,241, 84, 0, 63, 52,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,164,163,243, 62, 89,190,166, 62, 72,102,230, 62,183,199,165, 62, 70, 15,239, 62,233,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70, 15,239, 62,233,101,144, 62,222,152,253, 62, 14,201,146, 62,
+164,163,243, 62, 89,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,241, 84, 0, 63,
+ 52,150,169, 62,164,163,243, 62, 89,190,166, 62,222,152,253, 62, 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,222,152,253, 62, 14,201,146, 62, 70, 15,239, 62,233,101,144, 62,232,194,249, 62,216, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,123,175, 6, 63, 65, 54,174, 62,241, 84, 0, 63,
+ 52,150,169, 62, 17, 21, 6, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 17, 21, 6, 63,169,144,151, 62,191,204, 12, 63, 90,231,157, 62,123,175, 6, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,160,111,180, 62,123,175, 6, 63, 65, 54,174, 62,191,204, 12, 63,
+ 90,231,157, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63, 90,231,157, 62,
+ 17, 21, 6, 63,169,144,151, 62,191,204, 12, 63,149, 83,135, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 72,102,230, 62, 53,162,115, 62,232,194,249, 62,216, 76,120, 62, 70, 15,239, 62,233,101,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 70, 15,239, 62,233,101,144, 62, 75,189,221, 62,238,101,144, 62,
+ 72,102,230, 62, 53,162,115, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,168, 9,211, 62,
+222, 76,120, 62, 72,102,230, 62, 53,162,115, 62, 75,189,221, 62,238,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 75,189,221, 62,238,101,144, 62, 70, 15,239, 62,233,101,144, 62, 72,102,230, 62,183,199,165, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 72,102,230, 62, 53,162,115, 62,168, 9,211, 62,
+222, 76,120, 62, 80,167,218, 62,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 80,167,218, 62,194,176, 70, 62, 68, 37,242, 62,194,176, 70, 62, 72,102,230, 62, 53,162,115, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,232,194,249, 62,216, 76,120, 62, 72,102,230, 62, 53,162,115, 62, 68, 37,242, 62,
+194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68, 37,242, 62,194,176, 70, 62,
+ 80,167,218, 62,194,176, 70, 62, 72,102,230, 62,168, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,197, 16, 1, 63,174,253, 30, 62,191,204, 12, 63, 90,111, 52, 62,226,190, 3, 63, 90, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,226,190, 3, 63, 90, 97, 83, 62, 68, 37,242, 62,194,176, 70, 62,
+197, 16, 1, 63,174,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 72,102,230, 62,
+168, 31, 23, 62,197, 16, 1, 63,174,253, 30, 62, 68, 37,242, 62,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 68, 37,242, 62,194,176, 70, 62,226,190, 3, 63, 90, 97, 83, 62,232,194,249, 62,216, 76,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 14,171,202, 62,179,253, 30, 62, 72,102,230, 62,
+168, 31, 23, 62, 80,167,218, 62,194,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 80,167,218, 62,194,176, 70, 62,205, 78,197, 62, 95, 97, 83, 62, 14,171,202, 62,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,101,111, 52, 62, 14,171,202, 62,179,253, 30, 62,205, 78,197, 62,
+ 95, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,205, 78,197, 62, 95, 97, 83, 62,
+ 80,167,218, 62,194,176, 70, 62,168, 9,211, 62,222, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 63,102,230, 62,101, 41,147, 61, 20, 51,179, 62,104,111,180, 61, 15, 51,179, 62,225, 64, 52, 61, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 15, 51,179, 62,225, 64, 52, 61,189,204, 12, 63,225, 64, 52, 61,
+ 63,102,230, 62,101, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,
+ 83,111,180, 61, 63,102,230, 62,101, 41,147, 61,189,204, 12, 63,225, 64, 52, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,189,204, 12, 63,225, 64, 52, 61, 15, 51,179, 62,225, 64, 52, 61,144,175,161, 62,102, 9,239,178,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 63,102,230, 62,101, 41,147, 61,191,204, 12, 63,
+ 83,111,180, 61,104,154,249, 62, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+104,154,249, 62, 48, 46,231, 61, 42, 50,211, 62, 48, 46,231, 61, 63,102,230, 62,101, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 20, 51,179, 62,104,111,180, 61, 63,102,230, 62,101, 41,147, 61, 42, 50,211, 62,
+ 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42, 50,211, 62, 48, 46,231, 61,
+104,154,249, 62, 48, 46,231, 61, 72,102,230, 62,168, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 14,171,202, 62,179,253, 30, 62, 21, 51,179, 62,101,111, 52, 62, 19, 51,179, 62,204, 70, 7, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 19, 51,179, 62,204, 70, 7, 62, 42, 50,211, 62, 48, 46,231, 61,
+ 14,171,202, 62,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 72,102,230, 62,
+168, 31, 23, 62, 14,171,202, 62,179,253, 30, 62, 42, 50,211, 62, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 42, 50,211, 62, 48, 46,231, 61, 19, 51,179, 62,204, 70, 7, 62, 20, 51,179, 62,104,111,180, 61,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,197, 16, 1, 63,174,253, 30, 62, 72,102,230, 62,
+168, 31, 23, 62,104,154,249, 62, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+104,154,249, 62, 48, 46,231, 61,191,204, 12, 63,199, 70, 7, 62,197, 16, 1, 63,174,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63, 90,111, 52, 62,197, 16, 1, 63,174,253, 30, 62,191,204, 12, 63,
+199, 70, 7, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,199, 70, 7, 62,
+104,154,249, 62, 48, 46,231, 61,191,204, 12, 63, 83,111,180, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 19,150,194, 62, 72, 45,128, 62, 21, 51,179, 62,156, 83,135, 62, 22, 51,179, 62, 2,152, 97, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 22, 51,179, 62, 2,152, 97, 62,205, 78,197, 62, 95, 97, 83, 62,
+ 19,150,194, 62, 72, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,168, 9,211, 62,
+222, 76,120, 62, 19,150,194, 62, 72, 45,128, 62,205, 78,197, 62, 95, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,205, 78,197, 62, 95, 97, 83, 62, 22, 51,179, 62, 2,152, 97, 62, 21, 51,179, 62,101,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 19,150,194, 62, 72, 45,128, 62,168, 9,211, 62,
+222, 76,120, 62,179, 51,207, 62, 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+179, 51,207, 62, 17,201,146, 62,113,162,192, 62,174,144,151, 62, 19,150,194, 62, 72, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62,156, 83,135, 62, 19,150,194, 62, 72, 45,128, 62,113,162,192, 62,
+174,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,113,162,192, 62,174,144,151, 62,
+179, 51,207, 62, 17,201,146, 62,175, 34,204, 62, 54,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,154,109,191, 62, 68, 54,174, 62, 21, 51,179, 62,165,111,180, 62, 21, 51,179, 62, 98,231,157, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21, 51,179, 62, 98,231,157, 62,113,162,192, 62,174,144,151, 62,
+154,109,191, 62, 68, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,175, 34,204, 62,
+ 54,150,169, 62,154,109,191, 62, 68, 54,174, 62,113,162,192, 62,174,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,113,162,192, 62,174,144,151, 62, 21, 51,179, 62, 98,231,157, 62, 21, 51,179, 62,156, 83,135, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,237, 40,217, 62, 91,190,166, 62,175, 34,204, 62,
+ 54,150,169, 62,179, 51,207, 62, 17,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+179, 51,207, 62, 17,201,146, 62, 75,189,221, 62,238,101,144, 62,237, 40,217, 62, 91,190,166, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 72,102,230, 62,183,199,165, 62,237, 40,217, 62, 91,190,166, 62, 75,189,221, 62,
+238,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 75,189,221, 62,238,101,144, 62,
+179, 51,207, 62, 17,201,146, 62,168, 9,211, 62,222, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,134, 78, 56, 63,117, 45,128, 62,188, 20, 48, 63, 37, 77,120, 62, 42,242, 54, 63,181, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42,242, 54, 63,181, 97, 83, 62, 0, 0, 64, 63,115,152, 97, 62,
+134, 78, 56, 63,117, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+218, 83,135, 62,134, 78, 56, 63,117, 45,128, 62, 0, 0, 64, 63,115,152, 97, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,115,152, 97, 62, 42,242, 54, 63,181, 97, 83, 62, 0, 0, 64, 63,202,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,134, 78, 56, 63,117, 45,128, 62, 0, 0, 64, 63,
+218, 83,135, 62, 87, 72, 57, 63,219,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 87, 72, 57, 63,219,144,151, 62,184,255, 49, 63, 52,201,146, 62,134, 78, 56, 63,117, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,188, 20, 48, 63, 37, 77,120, 62,134, 78, 56, 63,117, 45,128, 62,184,255, 49, 63,
+ 52,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,184,255, 49, 63, 52,201,146, 62,
+ 87, 72, 57, 63,219,144,151, 62, 58,136, 51, 63, 90,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 26, 5, 45, 63,117,190,166, 62,107,102, 38, 63,201,199,165, 62,235,186, 42, 63, 5,102,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235,186, 42, 63, 5,102,144, 62,184,255, 49, 63, 52,201,146, 62,
+ 26, 5, 45, 63,117,190,166, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 58,136, 51, 63,
+ 90,150,169, 62, 26, 5, 45, 63,117,190,166, 62,184,255, 49, 63, 52,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,184,255, 49, 63, 52,201,146, 62,235,186, 42, 63, 5,102,144, 62,188, 20, 48, 63, 37, 77,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,196,226, 57, 63,114, 54,174, 62, 58,136, 51, 63,
+ 90,150,169, 62, 87, 72, 57, 63,219,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 87, 72, 57, 63,219,144,151, 62, 0, 0, 64, 63,162,231,157, 62,196,226, 57, 63,114, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,211,111,180, 62,196,226, 57, 63,114, 54,174, 62, 0, 0, 64, 63,
+162,231,157, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,162,231,157, 62,
+ 87, 72, 57, 63,219,144,151, 62, 0, 0, 64, 63,218, 83,135, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,107,102, 38, 63, 79,162,115, 62,188, 20, 48, 63, 37, 77,120, 62,235,186, 42, 63, 5,102,144, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,235,186, 42, 63, 5,102,144, 62,234, 17, 34, 63,243,101,144, 62,
+107,102, 38, 63, 79,162,115, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,184, 28, 63,
+222, 76,120, 62,107,102, 38, 63, 79,162,115, 62,234, 17, 34, 63,243,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,234, 17, 34, 63,243,101,144, 62,235,186, 42, 63, 5,102,144, 62,107,102, 38, 63,201,199,165, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,107,102, 38, 63, 79,162,115, 62, 21,184, 28, 63,
+222, 76,120, 62,234,134, 32, 63,204,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+234,134, 32, 63,204,176, 70, 62,233, 69, 44, 63,245,176, 70, 62,107,102, 38, 63, 79,162,115, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,188, 20, 48, 63, 37, 77,120, 62,107,102, 38, 63, 79,162,115, 62,233, 69, 44, 63,
+245,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,233, 69, 44, 63,245,176, 70, 62,
+234,134, 32, 63,204,176, 70, 62,104,102, 38, 63,198, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 9, 68, 52, 63,241,253, 30, 62, 0, 0, 64, 63,202,111, 52, 62, 42,242, 54, 63,181, 97, 83, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 42,242, 54, 63,181, 97, 83, 62,233, 69, 44, 63,245,176, 70, 62,
+ 9, 68, 52, 63,241,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,104,102, 38, 63,
+198, 31, 23, 62, 9, 68, 52, 63,241,253, 30, 62,233, 69, 44, 63,245,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,233, 69, 44, 63,245,176, 70, 62, 42,242, 54, 63,181, 97, 83, 62,188, 20, 48, 63, 37, 77,120, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,195,136, 24, 63,179,253, 30, 62,104,102, 38, 63,
+198, 31, 23, 62,234,134, 32, 63,204,176, 70, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+234,134, 32, 63,204,176, 70, 62,162,218, 21, 63, 84, 97, 83, 62,195,136, 24, 63,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63, 90,111, 52, 62,195,136, 24, 63,179,253, 30, 62,162,218, 21, 63,
+ 84, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,162,218, 21, 63, 84, 97, 83, 62,
+234,134, 32, 63,204,176, 70, 62, 21,184, 28, 63,222, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,104,102, 38, 63,111, 41,147, 61,191,204, 12, 63, 83,111,180, 61,189,204, 12, 63,225, 64, 52, 61, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,189,204, 12, 63,225, 64, 52, 61, 0, 0, 64, 63,111, 65, 52, 61,
+104,102, 38, 63,111, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,
+195,111,180, 61,104,102, 38, 63,111, 41,147, 61, 0, 0, 64, 63,111, 65, 52, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,111, 65, 52, 61,189,204, 12, 63,225, 64, 52, 61,208,222,121, 63,102, 9,239,178,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,104,102, 38, 63,111, 41,147, 61, 0, 0, 64, 63,
+195,111,180, 61,122, 0, 48, 63,120, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+122, 0, 48, 63,120, 46,231, 61, 85,204, 28, 63, 48, 46,231, 61,104,102, 38, 63,111, 41,147, 61, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63, 83,111,180, 61,104,102, 38, 63,111, 41,147, 61, 85,204, 28, 63,
+ 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 85,204, 28, 63, 48, 46,231, 61,
+122, 0, 48, 63,120, 46,231, 61,104,102, 38, 63,198, 31, 23, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0,195,136, 24, 63,179,253, 30, 62,191,204, 12, 63, 90,111, 52, 62,191,204, 12, 63,199, 70, 7, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,199, 70, 7, 62, 85,204, 28, 63, 48, 46,231, 61,
+195,136, 24, 63,179,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,104,102, 38, 63,
+198, 31, 23, 62,195,136, 24, 63,179,253, 30, 62, 85,204, 28, 63, 48, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 85,204, 28, 63, 48, 46,231, 61,191,204, 12, 63,199, 70, 7, 62,191,204, 12, 63, 83,111,180, 61,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 9, 68, 52, 63,241,253, 30, 62,104,102, 38, 63,
+198, 31, 23, 62,122, 0, 48, 63,120, 46,231, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+122, 0, 48, 63,120, 46,231, 61, 0, 0, 64, 63, 24, 71, 7, 62, 9, 68, 52, 63,241,253, 30, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63,202,111, 52, 62, 9, 68, 52, 63,241,253, 30, 62, 0, 0, 64, 63,
+ 24, 71, 7, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 64, 63, 24, 71, 7, 62,
+122, 0, 48, 63,120, 46,231, 61, 0, 0, 64, 63,195,111,180, 61, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 68,126, 20, 63, 64, 45,128, 62,191,204, 12, 63,149, 83,135, 62,191,204, 12, 63,248,151, 97, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,248,151, 97, 62,162,218, 21, 63, 84, 97, 83, 62,
+ 68,126, 20, 63, 64, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 21,184, 28, 63,
+222, 76,120, 62, 68,126, 20, 63, 64, 45,128, 62,162,218, 21, 63, 84, 97, 83, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,162,218, 21, 63, 84, 97, 83, 62,191,204, 12, 63,248,151, 97, 62,191,204, 12, 63, 90,111, 52, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68,126, 20, 63, 64, 45,128, 62, 21,184, 28, 63,
+222, 76,120, 62, 25,205, 26, 63, 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 25,205, 26, 63, 14,201,146, 62,114,132, 19, 63,169,144,151, 62, 68,126, 20, 63, 64, 45,128, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63,149, 83,135, 62, 68,126, 20, 63, 64, 45,128, 62,114,132, 19, 63,
+169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,114,132, 19, 63,169,144,151, 62,
+ 25,205, 26, 63, 14,201,146, 62,150, 68, 25, 63, 54,150,169, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 7,234, 18, 63, 65, 54,174, 62,191,204, 12, 63,160,111,180, 62,191,204, 12, 63, 90,231,157, 62, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,191,204, 12, 63, 90,231,157, 62,114,132, 19, 63,169,144,151, 62,
+ 7,234, 18, 63, 65, 54,174, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,150, 68, 25, 63,
+ 54,150,169, 62, 7,234, 18, 63, 65, 54,174, 62,114,132, 19, 63,169,144,151, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,114,132, 19, 63,169,144,151, 62,191,204, 12, 63, 90,231,157, 62,191,204, 12, 63,149, 83,135, 62,
+ 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,185,199, 31, 63, 96,190,166, 62,150, 68, 25, 63,
+ 54,150,169, 62, 25,205, 26, 63, 14,201,146, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 25,205, 26, 63, 14,201,146, 62,234, 17, 34, 63,243,101,144, 62,185,199, 31, 63, 96,190,166, 62, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,107,102, 38, 63,201,199,165, 62,185,199, 31, 63, 96,190,166, 62,234, 17, 34, 63,
+243,101,144, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,234, 17, 34, 63,243,101,144, 62,
+ 25,205, 26, 63, 14,201,146, 62, 21,184, 28, 63,222, 76,120, 62, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 0, 80, 0, 0, 16,148,167, 2, 58, 0, 0, 0, 0, 20, 0, 0,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
@@ -10719,2866 +12056,522 @@ char datatoc_preview_blend[]= {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65, 0, 1, 44, 0, 8,172, 96, 32,
- 0, 0, 0, 51, 0, 0, 5, 0, 0, 0, 0, 0, 63,110,222,166, 63, 55,205, 9, 63,105,132,212, 63, 65,236,201, 63,103,153,218,
- 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,103,153,218, 63, 54,155,119, 63,108,148,118, 63, 44,160,211, 63,110,222,166, 63, 55,205, 9,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 36, 63, 45, 28, 36, 63,110,222,166, 63, 55,205, 9, 63,108,148,118, 63, 44,160,211, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,108,148,118, 63, 44,160,211, 63,103,153,218, 63, 54,155,119, 63,102, 17, 87, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96, 81, 56,
- 63, 52, 55,170, 63,102, 17, 87, 63, 43, 52,229, 63,103,153,218, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,103,153,218, 63, 54,155,119,
- 63, 97, 75, 9, 63, 63,233, 92, 63, 96, 81, 56, 63, 52, 55,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,138, 63, 60, 86, 49, 63, 96, 81, 56,
- 63, 52, 55,170, 63, 97, 75, 9, 63, 63,233, 92, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 97, 75, 9, 63, 63,233, 92, 63,103,153,218, 63, 54,155,119,
- 63,105,132,212, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 98,167,103, 63, 75, 39,168, 63, 89,153,138, 63, 82,228, 39, 63, 89,153,139,
- 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139, 63, 71,153,255, 63, 97, 75, 9, 63, 63,233, 92, 63, 98,167,103, 63, 75, 39,168,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,105,132,212, 63, 65,236,201, 63, 98,167,103, 63, 75, 39,168, 63, 97, 75, 9, 63, 63,233, 92, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 97, 75, 9, 63, 63,233, 92, 63, 89,153,139, 63, 71,153,255, 63, 89,153,138, 63, 60, 86, 49, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96, 81, 56,
- 63, 52, 55,170, 63, 89,153,138, 63, 60, 86, 49, 63, 89,153,139, 63, 49, 12, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139, 63, 49, 12, 79,
- 63, 95,182,205, 63, 40,228,222, 63, 96, 81, 56, 63, 52, 55,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102, 17, 87, 63, 43, 52,229, 63, 96, 81, 56,
- 63, 52, 55,170, 63, 95,182,205, 63, 40,228,222, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 95,182,205, 63, 40,228,222, 63, 89,153,139, 63, 49, 12, 79,
- 63, 89,153,139, 63, 37,200, 45, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 98,167,103, 63, 75, 39,168, 63,105,132,212, 63, 65,236,201, 63,109, 83,168,
- 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,109, 83,168, 63, 78, 83,207, 63,101, 85,135, 63, 88, 64,148, 63, 98,167,103, 63, 75, 39,168,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,138, 63, 82,228, 39, 63, 98,167,103, 63, 75, 39,168, 63,101, 85,135, 63, 88, 64,148, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,101, 85,135, 63, 88, 64,148, 63,109, 83,168, 63, 78, 83,207, 63,115, 51, 36, 63, 90, 56, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121, 18,162,
- 63, 78, 83,207, 63,115, 51, 36, 63, 90, 56, 22, 63,109, 83,168, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,109, 83,168, 63, 78, 83,207,
- 63,115, 51, 36, 63, 67, 23,115, 63,121, 18,162, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124,225,116, 63, 65,236,202, 63,121, 18,162,
- 63, 78, 83,207, 63,115, 51, 36, 63, 67, 23,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 36, 63, 67, 23,115, 63,109, 83,168, 63, 78, 83,207,
- 63,105,132,212, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,110,222,166, 63, 55,205, 9, 63,115, 51, 36, 63, 45, 28, 36, 63,119,135,163,
- 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,119,135,163, 63, 55,205, 11, 63,115, 51, 36, 63, 67, 23,115, 63,110,222,166, 63, 55,205, 9,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,105,132,212, 63, 65,236,201, 63,110,222,166, 63, 55,205, 9, 63,115, 51, 36, 63, 67, 23,115, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,115, 51, 36, 63, 67, 23,115, 63,119,135,163, 63, 55,205, 11, 63,124,225,116, 63, 65,236,202, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121, 18,162,
- 63, 78, 83,207, 63,124,225,116, 63, 65,236,202, 63,129,223,113, 63, 75, 39,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,129,223,113, 63, 75, 39,170,
- 63,128,136, 98, 63, 88, 64,148, 63,121, 18,162, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 36, 63, 90, 56, 22, 63,121, 18,162,
- 63, 78, 83,207, 63,128,136, 98, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 59,136, 98, 95, 63, 88, 64,148, 60,111,184,160, 63, 75, 39,170,
- 61, 76,203,243, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,243, 63, 49, 12, 82, 61, 76,203,246, 63, 60, 86, 53, 60,194,162, 31,
- 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 60,194,162, 31, 63, 52, 55,172, 60,213,239,111, 63, 40,228,223, 61, 76,203,243, 63, 49, 12, 82,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,203,246, 63, 37,200, 48, 61, 76,203,243, 63, 49, 12, 82, 60,213,239,111, 63, 40,228,223, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 60,213,239,111, 63, 40,228,223, 60,194,162, 31, 63, 52, 55,172, 58,169,226,120, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,126,204,111,
- 63, 54,155,121, 63,128, 42,121, 63, 43, 52,230, 63,131, 10,136, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131, 10,136, 63, 52, 55,172,
- 63,130,141,160, 63, 63,233, 95, 63,126,204,111, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124,225,116, 63, 65,236,202, 63,126,204,111,
- 63, 54,155,121, 63,130,141,160, 63, 63,233, 95, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,163,104, 11, 63, 63,233, 95, 60,194,162, 31, 63, 52, 55,172,
- 61, 76,203,246, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,244, 63, 71,154, 2, 61, 76,203,243, 63, 82,228, 41, 60,111,184,160,
- 63, 75, 39,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 60,111,184,160, 63, 75, 39,170, 60,163,104, 11, 63, 63,233, 95, 61, 76,203,244, 63, 71,154, 2,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,203,246, 63, 60, 86, 53, 61, 76,203,244, 63, 71,154, 2, 60,163,104, 11, 63, 63,233, 95, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,130,141,160, 63, 63,233, 95, 63,129,223,113, 63, 75, 39,170, 63,124,225,116, 63, 65,236,202, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,126,204,111,
- 63, 54,155,121, 63,124,225,116, 63, 65,236,202, 63,119,135,163, 63, 55,205, 11, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,119,135,163, 63, 55,205, 11,
- 63,121,209,210, 63, 44,160,212, 63,126,204,111, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 42,121, 63, 43, 52,230, 63,126,204,111,
- 63, 54,155,121, 63,121,209,210, 63, 44,160,212, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,209,210, 63, 44,160,212, 63,119,135,163, 63, 55,205, 11,
- 63,115, 51, 36, 63, 45, 28, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,134,102, 95, 63, 94, 46, 79, 63,134,102, 95, 63,105,114, 22, 63,124,205, 52,
- 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,124,205, 52, 63, 99, 26, 58, 63,128,136, 98, 63, 88, 64,148, 63,134,102, 95, 63, 94, 46, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,203,243, 63, 82,228, 41, 61, 76,203,234, 63, 94, 46, 79, 59,136, 98, 95, 63, 88, 64,148, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128,136, 98, 63, 88, 64,148, 63,124,205, 52, 63, 99, 26, 58, 63,115, 51, 36, 63, 90, 56, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105,153, 21,
- 63, 99, 26, 58, 63,115, 51, 36, 63, 90, 56, 22, 63,124,205, 52, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124,205, 52, 63, 99, 26, 58,
- 63,115, 51, 32, 63,109,154,212, 63,105,153, 21, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,138, 63,105,114, 19, 63,105,153, 21,
- 63, 99, 26, 58, 63,115, 51, 32, 63,109,154,212, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 32, 63,109,154,212, 63,124,205, 52, 63, 99, 26, 58,
- 63,134,102, 95, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,134,102, 95, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 63, 89,153,136,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,136, 63,116,187,242, 63,115, 51, 32, 63,109,154,212, 63,134,102, 95, 63,116,187,242,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,134,102, 95, 63,105,114, 22, 63,134,102, 95, 63,116,187,242, 63,115, 51, 32, 63,109,154,212, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,115, 51, 32, 63,109,154,212, 63, 89,153,136, 63,116,187,242, 63, 89,153,138, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105,153, 21,
- 63, 99, 26, 58, 63, 89,153,138, 63,105,114, 19, 63, 89,153,138, 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,138, 63, 94, 46, 77,
- 63,101, 85,135, 63, 88, 64,148, 63,105,153, 21, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 36, 63, 90, 56, 22, 63,105,153, 21,
- 63, 99, 26, 58, 63,101, 85,135, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,101, 85,135, 63, 88, 64,148, 63, 89,153,138, 63, 94, 46, 77,
- 63, 89,153,138, 63, 82,228, 39, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 75,153, 67, 63, 54,155,113, 63, 73,174, 74, 63, 65,236,193, 63, 68, 84,124,
- 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 68, 84,124, 63, 55,204,255, 63, 70,158,169, 63, 44,160,200, 63, 75,153, 67, 63, 54,155,113,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 77, 33,196, 63, 43, 52,221, 63, 75,153, 67, 63, 54,155,113, 63, 70,158,169, 63, 44,160,200, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 70,158,169, 63, 44,160,200, 63, 68, 84,124, 63, 55,204,255, 63, 64, 0, 0, 63, 45, 28, 24, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 75,153, 67,
- 63, 54,155,113, 63, 77, 33,196, 63, 43, 52,221, 63, 82,225,225, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 82,225,225, 63, 52, 55,165,
- 63, 81,232, 16, 63, 63,233, 89, 63, 75,153, 67, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,174, 74, 63, 65,236,193, 63, 75,153, 67,
- 63, 54,155,113, 63, 81,232, 16, 63, 63,233, 89, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 81,232, 16, 63, 63,233, 89, 63, 82,225,225, 63, 52, 55,165,
- 63, 89,153,138, 63, 60, 86, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139, 63, 71,153,255, 63, 89,153,138, 63, 82,228, 39, 63, 80,139,179,
- 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 80,139,179, 63, 75, 39,164, 63, 81,232, 16, 63, 63,233, 89, 63, 89,153,139, 63, 71,153,255,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,138, 63, 60, 86, 49, 63, 89,153,139, 63, 71,153,255, 63, 81,232, 16, 63, 63,233, 89, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 81,232, 16, 63, 63,233, 89, 63, 80,139,179, 63, 75, 39,164, 63, 73,174, 74, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139,
- 63, 49, 12, 79, 63, 89,153,138, 63, 60, 86, 49, 63, 82,225,225, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 82,225,225, 63, 52, 55,165,
- 63, 83,124, 75, 63, 40,228,217, 63, 89,153,139, 63, 49, 12, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139, 63, 37,200, 45, 63, 89,153,139,
- 63, 49, 12, 79, 63, 83,124, 75, 63, 40,228,217, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 83,124, 75, 63, 40,228,217, 63, 82,225,225, 63, 52, 55,165,
- 63, 77, 33,196, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 69,223,120, 63, 78, 83,198, 63, 73,174, 74, 63, 65,236,193, 63, 80,139,179,
- 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 80,139,179, 63, 75, 39,164, 63, 77,221,148, 63, 88, 64,140, 63, 69,223,120, 63, 78, 83,198,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 63, 90, 56, 12, 63, 69,223,120, 63, 78, 83,198, 63, 77,221,148, 63, 88, 64,140, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 77,221,148, 63, 88, 64,140, 63, 80,139,179, 63, 75, 39,164, 63, 89,153,138, 63, 82,228, 39, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 69,223,120,
- 63, 78, 83,198, 63, 64, 0, 0, 63, 90, 56, 12, 63, 58, 32,136, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 58, 32,136, 63, 78, 83,198,
- 63, 64, 0, 0, 63, 67, 23,106, 63, 69,223,120, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,174, 74, 63, 65,236,193, 63, 69,223,120,
- 63, 78, 83,198, 63, 64, 0, 0, 63, 67, 23,106, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 63, 67, 23,106, 63, 58, 32,136, 63, 78, 83,198,
- 63, 54, 81,182, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 59,171,132, 63, 55,204,255, 63, 64, 0, 0, 63, 45, 28, 24, 63, 68, 84,124,
- 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 68, 84,124, 63, 55,204,255, 63, 64, 0, 0, 63, 67, 23,106, 63, 59,171,132, 63, 55,204,255,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 54, 81,182, 63, 65,236,193, 63, 59,171,132, 63, 55,204,255, 63, 64, 0, 0, 63, 67, 23,106, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 64, 0, 0, 63, 67, 23,106, 63, 68, 84,124, 63, 55,204,255, 63, 73,174, 74, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 47,116, 77,
- 63, 75, 39,164, 63, 54, 81,182, 63, 65,236,193, 63, 58, 32,136, 63, 78, 83,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 58, 32,136, 63, 78, 83,198,
- 63, 50, 34,108, 63, 88, 64,140, 63, 47,116, 77, 63, 75, 39,164, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,118, 63, 82,228, 38, 63, 47,116, 77,
- 63, 75, 39,164, 63, 50, 34,108, 63, 88, 64,140, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 50, 34,108, 63, 88, 64,140, 63, 58, 32,136, 63, 78, 83,198,
- 63, 64, 0, 0, 63, 90, 56, 12, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 30, 31, 63, 52, 55,165, 63, 38,102,117, 63, 60, 86, 50, 63, 38,102,117,
- 63, 49, 12, 78, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 49, 12, 78, 63, 44,131,181, 63, 40,228,216, 63, 45, 30, 31, 63, 52, 55,165,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 50,222, 60, 63, 43, 52,221, 63, 45, 30, 31, 63, 52, 55,165, 63, 44,131,181, 63, 40,228,216, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 44,131,181, 63, 40,228,216, 63, 38,102,117, 63, 49, 12, 78, 63, 38,102,117, 63, 37,200, 45, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 30, 31,
- 63, 52, 55,165, 63, 50,222, 60, 63, 43, 52,221, 63, 52,102,189, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 52,102,189, 63, 54,155,113,
- 63, 46, 23,240, 63, 63,233, 89, 63, 45, 30, 31, 63, 52, 55,165, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 60, 86, 50, 63, 45, 30, 31,
- 63, 52, 55,165, 63, 46, 23,240, 63, 63,233, 89, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 46, 23,240, 63, 63,233, 89, 63, 52,102,189, 63, 54,155,113,
- 63, 54, 81,182, 63, 65,236,193, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 47,116, 77, 63, 75, 39,164, 63, 38,102,118, 63, 82,228, 38, 63, 38,102,117,
- 63, 71,153,255, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 71,153,255, 63, 46, 23,240, 63, 63,233, 89, 63, 47,116, 77, 63, 75, 39,164,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 54, 81,182, 63, 65,236,193, 63, 47,116, 77, 63, 75, 39,164, 63, 46, 23,240, 63, 63,233, 89, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 46, 23,240, 63, 63,233, 89, 63, 38,102,117, 63, 71,153,255, 63, 38,102,117, 63, 60, 86, 50, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 59,171,132,
- 63, 55,204,255, 63, 54, 81,182, 63, 65,236,193, 63, 52,102,189, 63, 54,155,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 52,102,189, 63, 54,155,113,
- 63, 57, 97, 87, 63, 44,160,200, 63, 59,171,132, 63, 55,204,255, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 63, 45, 28, 24, 63, 59,171,132,
- 63, 55,204,255, 63, 57, 97, 87, 63, 44,160,200, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57, 97, 87, 63, 44,160,200, 63, 52,102,189, 63, 54,155,113,
- 63, 50,222, 60, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,101,250, 63, 99, 26, 51, 63, 38,102,118, 63,105,114, 19, 63, 38,102,118,
- 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,118, 63, 94, 46, 77, 63, 50, 34,108, 63, 88, 64,140, 63, 54,101,250, 63, 99, 26, 51,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 63, 90, 56, 12, 63, 54,101,250, 63, 99, 26, 51, 63, 50, 34,108, 63, 88, 64,140, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 50, 34,108, 63, 88, 64,140, 63, 38,102,118, 63, 94, 46, 77, 63, 38,102,118, 63, 82,228, 38, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,101,250,
- 63, 99, 26, 51, 63, 64, 0, 0, 63, 90, 56, 12, 63, 73,154, 6, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,154, 6, 63, 99, 26, 51,
- 63, 64, 0, 0, 63,109,154,206, 63, 54,101,250, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,118, 63,105,114, 19, 63, 54,101,250,
- 63, 99, 26, 51, 63, 64, 0, 0, 63,109,154,206, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 63,109,154,206, 63, 73,154, 6, 63, 99, 26, 51,
- 63, 89,153,138, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,136, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 63, 38,102,120,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,120, 63,116,187,242, 63, 64, 0, 0, 63,109,154,206, 63, 89,153,136, 63,116,187,242,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,138, 63,105,114, 19, 63, 89,153,136, 63,116,187,242, 63, 64, 0, 0, 63,109,154,206, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 64, 0, 0, 63,109,154,206, 63, 38,102,120, 63,116,187,242, 63, 38,102,118, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,138,
- 63, 94, 46, 77, 63, 89,153,138, 63,105,114, 19, 63, 73,154, 6, 63, 99, 26, 51, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,154, 6, 63, 99, 26, 51,
- 63, 77,221,148, 63, 88, 64,140, 63, 89,153,138, 63, 94, 46, 77, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,138, 63, 82,228, 39, 63, 89,153,138,
- 63, 94, 46, 77, 63, 77,221,148, 63, 88, 64,140, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 77,221,148, 63, 88, 64,140, 63, 73,154, 6, 63, 99, 26, 51,
- 63, 64, 0, 0, 63, 90, 56, 12, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 8, 71,167, 63, 55,205, 7, 61,229,192,170, 63, 65,236,200, 61,214,104,203,
- 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,214,104,203, 63, 54,155,120, 61,254, 61,201, 63, 44,160,207, 62, 8, 71,167, 63, 55,205, 7,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,173, 63, 45, 28, 27, 62, 8, 71,167, 63, 55,205, 7, 61,254, 61,201, 63, 44,160,207, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,254, 61,201, 63, 44,160,207, 61,214,104,203, 63, 54,155,120, 61,202, 36,175, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,156, 35,145,
- 63, 52, 55,172, 61,202, 36,175, 63, 43, 52,228, 61,214,104,203, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,214,104,203, 63, 54,155,120,
- 61,163,242, 32, 63, 63,233, 96, 61,156, 35,145, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,246, 63, 60, 86, 53, 61,156, 35,145,
- 63, 52, 55,172, 61,163,242, 32, 63, 63,233, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,163,242, 32, 63, 63,233, 96, 61,214,104,203, 63, 54,155,120,
- 61,229,192,170, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,174,213, 17, 63, 75, 39,171, 61, 76,203,243, 63, 82,228, 41, 61, 76,203,244,
- 63, 71,154, 2, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,244, 63, 71,154, 2, 61,163,242, 32, 63, 63,233, 96, 61,174,213, 17, 63, 75, 39,171,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,229,192,170, 63, 65,236,200, 61,174,213, 17, 63, 75, 39,171, 61,163,242, 32, 63, 63,233, 96, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,163,242, 32, 63, 63,233, 96, 61, 76,203,244, 63, 71,154, 2, 61, 76,203,246, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,156, 35,145,
- 63, 52, 55,172, 61, 76,203,246, 63, 60, 86, 53, 61, 76,203,243, 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,243, 63, 49, 12, 82,
- 61,151, 80, 53, 63, 40,228,223, 61,156, 35,145, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,202, 36,175, 63, 43, 52,228, 61,156, 35,145,
- 63, 52, 55,172, 61,151, 80, 53, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,151, 80, 53, 63, 40,228,223, 61, 76,203,243, 63, 49, 12, 82,
- 61, 76,203,246, 63, 37,200, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,174,213, 17, 63, 75, 39,171, 61,229,192,170, 63, 65,236,200, 62, 2, 27,169,
- 63, 78, 83,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 27,169, 63, 78, 83,204, 61,196, 70, 23, 63, 88, 64,147, 61,174,213, 17, 63, 75, 39,171,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,203,243, 63, 82,228, 41, 61,174,213, 17, 63, 75, 39,171, 61,196, 70, 23, 63, 88, 64,147, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,196, 70, 23, 63, 88, 64,147, 62, 2, 27,169, 63, 78, 83,204, 62, 25,153,160, 63, 90, 56, 14, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 49, 23,162,
- 63, 78, 83,195, 62, 25,153,160, 63, 90, 56, 14, 62, 2, 27,169, 63, 78, 83,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 27,169, 63, 78, 83,204,
- 62, 25,153,172, 63, 67, 23,108, 62, 49, 23,162, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 82,240, 63, 65,236,183, 62, 49, 23,162,
- 63, 78, 83,195, 62, 25,153,172, 63, 67, 23,108, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,172, 63, 67, 23,108, 62, 2, 27,169, 63, 78, 83,204,
- 61,229,192,170, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 8, 71,167, 63, 55,205, 7, 62, 25,153,173, 63, 45, 28, 27, 62, 42,235,173,
- 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 42,235,173, 63, 55,204,254, 62, 25,153,172, 63, 67, 23,108, 62, 8, 71,167, 63, 55,205, 7,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,229,192,170, 63, 65,236,200, 62, 8, 71,167, 63, 55,205, 7, 62, 25,153,172, 63, 67, 23,108, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 25,153,172, 63, 67, 23,108, 62, 42,235,173, 63, 55,204,254, 62, 64, 82,240, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 49, 23,162,
- 63, 78, 83,195, 62, 64, 82,240, 63, 65,236,183, 62, 91,200,166, 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 91,200,166, 63, 75, 39,147,
- 62, 81, 16, 34, 63, 88, 64,131, 62, 49, 23,162, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,160, 63, 90, 56, 14, 62, 49, 23,162,
- 63, 78, 83,195, 62, 81, 16, 34, 63, 88, 64,131, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 81, 16, 34, 63, 88, 64,131, 62, 91,200,166, 63, 75, 39,147,
- 62,128, 0, 0, 63, 82,228, 13, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 49, 12, 47, 62,128, 0, 0, 63, 60, 86, 19, 62,101, 33, 92,
- 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,101, 33, 92, 63, 52, 55,146, 62,103,139, 14, 63, 40,228,199, 62,128, 0, 0, 63, 49, 12, 47,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 63, 37,200, 23, 62,128, 0, 0, 63, 49, 12, 47, 62,103,139, 14, 63, 40,228,199, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,103,139, 14, 63, 40,228,199, 62,101, 33, 92, 63, 52, 55,146, 62, 78, 32,230, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 71,254,223,
- 63, 54,155,102, 62, 78, 32,230, 63, 43, 52,211, 62,101, 33, 92, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,101, 33, 92, 63, 52, 55,146,
- 62, 97, 58, 23, 63, 63,233, 69, 62, 71,254,223, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 82,240, 63, 65,236,183, 62, 71,254,223,
- 63, 54,155,102, 62, 97, 58, 23, 63, 63,233, 69, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 97, 58, 23, 63, 63,233, 69, 62,101, 33, 92, 63, 52, 55,146,
- 62,128, 0, 0, 63, 60, 86, 19, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 71,153,228, 62,128, 0, 0, 63, 82,228, 13, 62, 91,200,166,
- 63, 75, 39,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 91,200,166, 63, 75, 39,147, 62, 97, 58, 23, 63, 63,233, 69, 62,128, 0, 0, 63, 71,153,228,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 63, 60, 86, 19, 62,128, 0, 0, 63, 71,153,228, 62, 97, 58, 23, 63, 63,233, 69, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 97, 58, 23, 63, 63,233, 69, 62, 91,200,166, 63, 75, 39,147, 62, 64, 82,240, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 71,254,223,
- 63, 54,155,102, 62, 64, 82,240, 63, 65,236,183, 62, 42,235,173, 63, 55,204,254, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 42,235,173, 63, 55,204,254,
- 62, 52, 20,105, 63, 44,160,198, 62, 71,254,223, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 78, 32,230, 63, 43, 52,211, 62, 71,254,223,
- 63, 54,155,102, 62, 52, 20,105, 63, 44,160,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 52, 20,105, 63, 44,160,198, 62, 42,235,173, 63, 55,204,254,
- 62, 25,153,173, 63, 45, 28, 27, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 94, 46, 58, 62,128, 0, 0, 63,105,114, 8, 62, 64, 1,230,
- 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 1,230, 63, 99, 26, 49, 62, 81, 16, 34, 63, 88, 64,131, 62,128, 0, 0, 63, 94, 46, 58,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 63, 82,228, 13, 62,128, 0, 0, 63, 94, 46, 58, 62, 81, 16, 34, 63, 88, 64,131, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 81, 16, 34, 63, 88, 64,131, 62, 64, 1,230, 63, 99, 26, 49, 62, 25,153,160, 63, 90, 56, 14, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,230, 98,164,
- 63, 99, 26, 58, 62, 25,153,160, 63, 90, 56, 14, 62, 64, 1,230, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64, 1,230, 63, 99, 26, 49,
- 62, 25,153,159, 63,109,154,210, 61,230, 98,164, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,237, 63,105,114, 22, 61,230, 98,164,
- 63, 99, 26, 58, 62, 25,153,159, 63,109,154,210, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,159, 63,109,154,210, 62, 64, 1,230, 63, 99, 26, 49,
- 62,128, 0, 0, 63,105,114, 8, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63,116,187,232, 63, 59,153, 3, 63,128, 0, 0, 63,134,102, 95,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,210, 63,116,187,242, 62, 25,153,159, 63,109,154,210, 62,128, 0, 0, 63,116,187,232,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 63,105,114, 8, 62,128, 0, 0, 63,116,187,232, 62, 25,153,159, 63,109,154,210, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 25,153,159, 63,109,154,210, 61, 76,203,210, 63,116,187,242, 61, 76,203,237, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,230, 98,164,
- 63, 99, 26, 58, 61, 76,203,237, 63,105,114, 22, 61, 76,203,234, 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,234, 63, 94, 46, 79,
- 61,196, 70, 23, 63, 88, 64,147, 61,230, 98,164, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,160, 63, 90, 56, 14, 61,230, 98,164,
- 63, 99, 26, 58, 61,196, 70, 23, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,196, 70, 23, 63, 88, 64,147, 61, 76,203,234, 63, 94, 46, 79,
- 61, 76,203,243, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,170,138, 42, 63, 55,204,254, 62,159,214,136, 63, 65,236,183, 62,156, 0,145,
- 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,156, 0,145, 63, 54,155,102, 62,165,245,204, 63, 44,160,198, 62,170,138, 42, 63, 55,204,254,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 42, 63, 45, 28, 28, 62,170,138, 42, 63, 55,204,254, 62,165,245,204, 63, 44,160,198, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,165,245,204, 63, 44,160,198, 62,156, 0,145, 63, 54,155,102, 62,152,239,141, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141,111, 82,
- 63, 52, 55,146, 62,152,239,141, 63, 43, 52,211, 62,156, 0,145, 63, 54,155,102, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,156, 0,145, 63, 54,155,102,
- 62,143, 98,245, 63, 63,233, 68, 62,141,111, 82, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 60, 86, 19, 62,141,111, 82,
- 63, 52, 55,146, 62,143, 98,245, 63, 63,233, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,143, 98,245, 63, 63,233, 68, 62,156, 0,145, 63, 54,155,102,
- 62,159,214,136, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,146, 27,173, 63, 75, 39,147, 62,128, 0, 0, 63, 82,228, 13, 62,128, 0, 0,
- 63, 71,153,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 71,153,228, 62,143, 98,245, 63, 63,233, 68, 62,146, 27,173, 63, 75, 39,147,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,159,214,136, 63, 65,236,183, 62,146, 27,173, 63, 75, 39,147, 62,143, 98,245, 63, 63,233, 68, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,143, 98,245, 63, 63,233, 68, 62,128, 0, 0, 63, 71,153,228, 62,128, 0, 0, 63, 60, 86, 19, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141,111, 82,
- 63, 52, 55,146, 62,128, 0, 0, 63, 60, 86, 19, 62,128, 0, 0, 63, 49, 12, 47, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 49, 12, 47,
- 62,140, 58,121, 63, 40,228,199, 62,141,111, 82, 63, 52, 55,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,152,239,141, 63, 43, 52,211, 62,141,111, 82,
- 63, 52, 55,146, 62,140, 58,121, 63, 40,228,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,140, 58,121, 63, 40,228,199, 62,128, 0, 0, 63, 49, 12, 47,
- 62,128, 0, 0, 63, 37,200, 23, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,146, 27,173, 63, 75, 39,147, 62,159,214,136, 63, 65,236,183, 62,167,116, 47,
- 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,167,116, 47, 63, 78, 83,195, 62,151,119,239, 63, 88, 64,131, 62,146, 27,173, 63, 75, 39,147,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 63, 82,228, 13, 62,146, 27,173, 63, 75, 39,147, 62,151,119,239, 63, 88, 64,131, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,151,119,239, 63, 88, 64,131, 62,167,116, 47, 63, 78, 83,195, 62,179, 51, 49, 63, 90, 56, 14, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,190,242, 44,
- 63, 78, 83,205, 62,179, 51, 49, 63, 90, 56, 14, 62,167,116, 47, 63, 78, 83,195, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,167,116, 47, 63, 78, 83,195,
- 62,179, 51, 42, 63, 67, 23,108, 62,190,242, 44, 63, 78, 83,205, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198,143,214, 63, 65,236,200, 62,190,242, 44,
- 63, 78, 83,205, 62,179, 51, 42, 63, 67, 23,108, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 42, 63, 67, 23,108, 62,167,116, 47, 63, 78, 83,195,
- 62,159,214,136, 63, 65,236,183, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,170,138, 42, 63, 55,204,254, 62,179, 51, 42, 63, 45, 28, 28, 62,187,220, 45,
- 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,187,220, 45, 63, 55,205, 7, 62,179, 51, 42, 63, 67, 23,108, 62,170,138, 42, 63, 55,204,254,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,159,214,136, 63, 65,236,183, 62,170,138, 42, 63, 55,204,254, 62,179, 51, 42, 63, 67, 23,108, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,179, 51, 42, 63, 67, 23,108, 62,187,220, 45, 63, 55,205, 7, 62,198,143,214, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,190,242, 44,
- 63, 78, 83,205, 62,198,143,214, 63, 65,236,200, 62,212, 74,188, 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,212, 74,188, 63, 75, 39,171,
- 62,206,238,122, 63, 88, 64,147, 62,190,242, 44, 63, 78, 83,205, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 49, 63, 90, 56, 14, 62,190,242, 44,
- 63, 78, 83,205, 62,206,238,122, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,206,238,122, 63, 88, 64,147, 62,212, 74,188, 63, 75, 39,171,
- 62,230,102,130, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,130, 63, 49, 12, 82, 62,230,102,129, 63, 60, 86, 53, 62,216,247, 28,
- 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,216,247, 28, 63, 52, 55,172, 62,218, 43,243, 63, 40,228,223, 62,230,102,130, 63, 49, 12, 82,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102,129, 63, 37,200, 48, 62,230,102,130, 63, 49, 12, 82, 62,218, 43,243, 63, 40,228,223, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,218, 43,243, 63, 40,228,223, 62,216,247, 28, 63, 52, 55,172, 62,205,118,212, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,202,101,206,
- 63, 54,155,120, 62,205,118,212, 63, 43, 52,228, 62,216,247, 28, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,216,247, 28, 63, 52, 55,172,
- 62,215, 3,120, 63, 63,233, 95, 62,202,101,206, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198,143,214, 63, 65,236,200, 62,202,101,206,
- 63, 54,155,120, 62,215, 3,120, 63, 63,233, 95, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,215, 3,120, 63, 63,233, 95, 62,216,247, 28, 63, 52, 55,172,
- 62,230,102,129, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,130, 63, 71,154, 1, 62,230,102,130, 63, 82,228, 41, 62,212, 74,188,
- 63, 75, 39,171, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,212, 74,188, 63, 75, 39,171, 62,215, 3,120, 63, 63,233, 95, 62,230,102,130, 63, 71,154, 1,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102,129, 63, 60, 86, 53, 62,230,102,130, 63, 71,154, 1, 62,215, 3,120, 63, 63,233, 95, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,215, 3,120, 63, 63,233, 95, 62,212, 74,188, 63, 75, 39,171, 62,198,143,214, 63, 65,236,200, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,202,101,206,
- 63, 54,155,120, 62,198,143,214, 63, 65,236,200, 62,187,220, 45, 63, 55,205, 7, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,187,220, 45, 63, 55,205, 7,
- 62,192,112,142, 63, 44,160,207, 62,202,101,206, 63, 54,155,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,205,118,212, 63, 43, 52,228, 62,202,101,206,
- 63, 54,155,120, 62,192,112,142, 63, 44,160,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,192,112,142, 63, 44,160,207, 62,187,220, 45, 63, 55,205, 7,
- 62,179, 51, 42, 63, 45, 28, 28, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,131, 63, 94, 46, 79, 62,230,102,131, 63,105,114, 22, 62,198,103, 87,
- 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,198,103, 87, 63, 99, 26, 58, 62,206,238,122, 63, 88, 64,147, 62,230,102,131, 63, 94, 46, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102,130, 63, 82,228, 41, 62,230,102,131, 63, 94, 46, 79, 62,206,238,122, 63, 88, 64,147, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,206,238,122, 63, 88, 64,147, 62,198,103, 87, 63, 99, 26, 58, 62,179, 51, 49, 63, 90, 56, 14, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159,255, 14,
- 63, 99, 26, 49, 62,179, 51, 49, 63, 90, 56, 14, 62,198,103, 87, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198,103, 87, 63, 99, 26, 58,
- 62,179, 51, 49, 63,109,154,210, 62,159,255, 14, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63,105,114, 8, 62,159,255, 14,
- 63, 99, 26, 49, 62,179, 51, 49, 63,109,154,210, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 49, 63,109,154,210, 62,198,103, 87, 63, 99, 26, 58,
- 62,230,102,131, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,134, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 62,128, 0, 0,
- 63,116,187,232, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63,116,187,232, 62,179, 51, 49, 63,109,154,210, 62,230,102,134, 63,116,187,242,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102,131, 63,105,114, 22, 62,230,102,134, 63,116,187,242, 62,179, 51, 49, 63,109,154,210, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,179, 51, 49, 63,109,154,210, 62,128, 0, 0, 63,116,187,232, 62,128, 0, 0, 63,105,114, 8, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159,255, 14,
- 63, 99, 26, 49, 62,128, 0, 0, 63,105,114, 8, 62,128, 0, 0, 63, 94, 46, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 94, 46, 58,
- 62,151,119,239, 63, 88, 64,131, 62,159,255, 14, 63, 99, 26, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 49, 63, 90, 56, 14, 62,159,255, 14,
- 63, 99, 26, 49, 62,151,119,239, 63, 88, 64,131, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,151,119,239, 63, 88, 64,131, 62,128, 0, 0, 63, 94, 46, 58,
- 62,128, 0, 0, 63, 82,228, 13, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 8,120, 93, 63, 55,205, 11, 63, 3, 30,140, 63, 65,236,201, 63, 1, 51,145,
- 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 1, 51,145, 63, 54,155,121, 63, 6, 46, 46, 63, 44,160,211, 63, 8,120, 93, 63, 55,205, 11,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,220, 63, 45, 28, 35, 63, 8,120, 93, 63, 55,205, 11, 63, 6, 46, 46, 63, 44,160,211, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 6, 46, 46, 63, 44,160,211, 63, 1, 51,145, 63, 54,155,121, 62,255, 86, 30, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243,213,222,
- 63, 52, 55,172, 62,255, 86, 30, 63, 43, 52,230, 63, 1, 51,145, 63, 54,155,121, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 1, 51,145, 63, 54,155,121,
- 62,245,201,128, 63, 63,233, 94, 62,243,213,222, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,129, 63, 60, 86, 53, 62,243,213,222,
- 63, 52, 55,172, 62,245,201,128, 63, 63,233, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,245,201,128, 63, 63,233, 94, 63, 1, 51,145, 63, 54,155,121,
- 63, 3, 30,140, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,248,130, 59, 63, 75, 39,169, 62,230,102,130, 63, 82,228, 41, 62,230,102,130,
- 63, 71,154, 1, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,130, 63, 71,154, 1, 62,245,201,128, 63, 63,233, 94, 62,248,130, 59, 63, 75, 39,169,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 3, 30,140, 63, 65,236,201, 62,248,130, 59, 63, 75, 39,169, 62,245,201,128, 63, 63,233, 94, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,245,201,128, 63, 63,233, 94, 62,230,102,130, 63, 71,154, 1, 62,230,102,129, 63, 60, 86, 53, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243,213,222,
- 63, 52, 55,172, 62,230,102,129, 63, 60, 86, 53, 62,230,102,130, 63, 49, 12, 82, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,130, 63, 49, 12, 82,
- 62,242,161, 9, 63, 40,228,223, 62,243,213,222, 63, 52, 55,172, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,255, 86, 30, 63, 43, 52,230, 62,243,213,222,
- 63, 52, 55,172, 62,242,161, 9, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,242,161, 9, 63, 40,228,223, 62,230,102,130, 63, 49, 12, 82,
- 62,230,102,129, 63, 37,200, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,248,130, 59, 63, 75, 39,169, 63, 3, 30,140, 63, 65,236,201, 63, 6,237, 94,
- 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 6,237, 94, 63, 78, 83,207, 62,253,222,118, 63, 88, 64,148, 62,248,130, 59, 63, 75, 39,169,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102,130, 63, 82,228, 41, 62,248,130, 59, 63, 75, 39,169, 62,253,222,118, 63, 88, 64,148, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,253,222,118, 63, 88, 64,148, 63, 6,237, 94, 63, 78, 83,207, 63, 12,204,220, 63, 90, 56, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 18,172, 88,
- 63, 78, 83,207, 63, 12,204,220, 63, 90, 56, 22, 63, 6,237, 94, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6,237, 94, 63, 78, 83,207,
- 63, 12,204,220, 63, 67, 23,115, 63, 18,172, 88, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,123, 44, 63, 65,236,201, 63, 18,172, 88,
- 63, 78, 83,207, 63, 12,204,220, 63, 67, 23,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,220, 63, 67, 23,115, 63, 6,237, 94, 63, 78, 83,207,
- 63, 3, 30,140, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 8,120, 93, 63, 55,205, 11, 63, 12,204,220, 63, 45, 28, 35, 63, 17, 33, 91,
- 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 17, 33, 91, 63, 55,205, 9, 63, 12,204,220, 63, 67, 23,115, 63, 8,120, 93, 63, 55,205, 11,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 3, 30,140, 63, 65,236,201, 63, 8,120, 93, 63, 55,205, 11, 63, 12,204,220, 63, 67, 23,115, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 12,204,220, 63, 67, 23,115, 63, 17, 33, 91, 63, 55,205, 9, 63, 22,123, 44, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 18,172, 88,
- 63, 78, 83,207, 63, 22,123, 44, 63, 65,236,201, 63, 29, 88,153, 63, 75, 39,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 29, 88,153, 63, 75, 39,167,
- 63, 26,170,121, 63, 88, 64,147, 63, 18,172, 88, 63, 78, 83,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,220, 63, 90, 56, 22, 63, 18,172, 88,
- 63, 78, 83,207, 63, 26,170,121, 63, 88, 64,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 26,170,121, 63, 88, 64,147, 63, 29, 88,153, 63, 75, 39,167,
- 63, 38,102,118, 63, 82,228, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 49, 12, 78, 63, 38,102,117, 63, 60, 86, 50, 63, 31,174,200,
- 63, 52, 55,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 31,174,200, 63, 52, 55,169, 63, 32, 73, 51, 63, 40,228,221, 63, 38,102,117, 63, 49, 12, 78,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,117, 63, 37,200, 45, 63, 38,102,117, 63, 49, 12, 78, 63, 32, 73, 51, 63, 40,228,221, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 32, 73, 51, 63, 40,228,221, 63, 31,174,200, 63, 52, 55,169, 63, 25,238,169, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 24,102, 39,
- 63, 54,155,119, 63, 25,238,169, 63, 43, 52,229, 63, 31,174,200, 63, 52, 55,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 31,174,200, 63, 52, 55,169,
- 63, 30,180,246, 63, 63,233, 92, 63, 24,102, 39, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,123, 44, 63, 65,236,201, 63, 24,102, 39,
- 63, 54,155,119, 63, 30,180,246, 63, 63,233, 92, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 30,180,246, 63, 63,233, 92, 63, 31,174,200, 63, 52, 55,169,
- 63, 38,102,117, 63, 60, 86, 50, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 71,153,255, 63, 38,102,118, 63, 82,228, 38, 63, 29, 88,153,
- 63, 75, 39,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 29, 88,153, 63, 75, 39,167, 63, 30,180,246, 63, 63,233, 92, 63, 38,102,117, 63, 71,153,255,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,117, 63, 60, 86, 50, 63, 38,102,117, 63, 71,153,255, 63, 30,180,246, 63, 63,233, 92, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 30,180,246, 63, 63,233, 92, 63, 29, 88,153, 63, 75, 39,167, 63, 22,123, 44, 63, 65,236,201, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 24,102, 39,
- 63, 54,155,119, 63, 22,123, 44, 63, 65,236,201, 63, 17, 33, 91, 63, 55,205, 9, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 17, 33, 91, 63, 55,205, 9,
- 63, 19,107,138, 63, 44,160,211, 63, 24,102, 39, 63, 54,155,119, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25,238,169, 63, 43, 52,229, 63, 24,102, 39,
- 63, 54,155,119, 63, 19,107,138, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,107,138, 63, 44,160,211, 63, 17, 33, 91, 63, 55,205, 9,
- 63, 12,204,220, 63, 45, 28, 35, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,118, 63, 94, 46, 77, 63, 38,102,118, 63,105,114, 19, 63, 22,102,235,
- 63, 99, 26, 59, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,102,235, 63, 99, 26, 59, 63, 26,170,121, 63, 88, 64,147, 63, 38,102,118, 63, 94, 46, 77,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,118, 63, 82,228, 38, 63, 38,102,118, 63, 94, 46, 77, 63, 26,170,121, 63, 88, 64,147, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 26,170,121, 63, 88, 64,147, 63, 22,102,235, 63, 99, 26, 59, 63, 12,204,220, 63, 90, 56, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 3, 50,204,
- 63, 99, 26, 58, 63, 12,204,220, 63, 90, 56, 22, 63, 22,102,235, 63, 99, 26, 59, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,102,235, 63, 99, 26, 59,
- 63, 12,204,224, 63,109,154,212, 63, 3, 50,204, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,131, 63,105,114, 22, 63, 3, 50,204,
- 63, 99, 26, 58, 63, 12,204,224, 63,109,154,212, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,224, 63,109,154,212, 63, 22,102,235, 63, 99, 26, 59,
- 63, 38,102,118, 63,105,114, 19, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,120, 63,116,187,242, 63, 59,153, 3, 63,128, 0, 0, 62,230,102,134,
- 63,116,187,242, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,134, 63,116,187,242, 63, 12,204,224, 63,109,154,212, 63, 38,102,120, 63,116,187,242,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,118, 63,105,114, 19, 63, 38,102,120, 63,116,187,242, 63, 12,204,224, 63,109,154,212, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 12,204,224, 63,109,154,212, 62,230,102,134, 63,116,187,242, 62,230,102,131, 63,105,114, 22, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 3, 50,204,
- 63, 99, 26, 58, 62,230,102,131, 63,105,114, 22, 62,230,102,131, 63, 94, 46, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,131, 63, 94, 46, 79,
- 62,253,222,118, 63, 88, 64,148, 63, 3, 50,204, 63, 99, 26, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,220, 63, 90, 56, 22, 63, 3, 50,204,
- 63, 99, 26, 58, 62,253,222,118, 63, 88, 64,148, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,253,222,118, 63, 88, 64,148, 62,230,102,131, 63, 94, 46, 79,
- 62,230,102,130, 63, 82,228, 41, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,233,213, 63, 21, 48, 35, 63, 70,235,176, 63, 22,209,226, 63, 73,234, 80,
- 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,234, 80, 63, 11,111,146, 63, 79,200, 1, 63, 9,152, 94, 63, 76,233,213, 63, 21, 48, 35,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 82,215, 19, 63, 19, 29,252, 63, 76,233,213, 63, 21, 48, 35, 63, 79,200, 1, 63, 9,152, 94, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 79,200, 1, 63, 9,152, 94, 63, 73,234, 80, 63, 11,111,146, 63, 76,204,193, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,233,213,
- 63, 21, 48, 35, 63, 82,215, 19, 63, 19, 29,252, 63, 80, 41,220, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 80, 41,220, 63, 31, 60,105,
- 63, 73,219,164, 63, 33, 23,173, 63, 76,233,213, 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,235,176, 63, 22,209,226, 63, 76,233,213,
- 63, 21, 48, 35, 63, 73,219,164, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,219,164, 63, 33, 23,173, 63, 80, 41,220, 63, 31, 60,105,
- 63, 77, 33,196, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,158,169, 63, 44,160,200, 63, 64, 0, 0, 63, 45, 28, 24, 63, 67,171, 5,
- 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 67,171, 5, 63, 34, 17,216, 63, 73,219,164, 63, 33, 23,173, 63, 70,158,169, 63, 44,160,200,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 77, 33,196, 63, 43, 52,221, 63, 70,158,169, 63, 44,160,200, 63, 73,219,164, 63, 33, 23,173, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 73,219,164, 63, 33, 23,173, 63, 67,171, 5, 63, 34, 17,216, 63, 70,235,176, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 83,124, 75,
- 63, 40,228,217, 63, 77, 33,196, 63, 43, 52,221, 63, 80, 41,220, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 80, 41,220, 63, 31, 60,105,
- 63, 86, 20,218, 63, 28,140,143, 63, 83,124, 75, 63, 40,228,217, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,139, 63, 37,200, 45, 63, 83,124, 75,
- 63, 40,228,217, 63, 86, 20,218, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 20,218, 63, 28,140,143, 63, 80, 41,220, 63, 31, 60,105,
- 63, 82,215, 19, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 63, 23, 32,182, 63, 70,235,176, 63, 22,209,226, 63, 67,171, 5,
- 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 67,171, 5, 63, 34, 17,216, 63, 60, 84,251, 63, 34, 17,216, 63, 64, 0, 0, 63, 23, 32,182,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 57, 20, 80, 63, 22,209,226, 63, 64, 0, 0, 63, 23, 32,182, 63, 60, 84,251, 63, 34, 17,216, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 60, 84,251, 63, 34, 17,216, 63, 67,171, 5, 63, 34, 17,216, 63, 64, 0, 0, 63, 45, 28, 24, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0,
- 63, 23, 32,182, 63, 57, 20, 80, 63, 22,209,226, 63, 60,156,169, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 60,156,169, 63, 11,116, 96,
- 63, 67, 99, 87, 63, 11,116, 96, 63, 64, 0, 0, 63, 23, 32,182, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,235,176, 63, 22,209,226, 63, 64, 0, 0,
- 63, 23, 32,182, 63, 67, 99, 87, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 67, 99, 87, 63, 11,116, 96, 63, 60,156,169, 63, 11,116, 96,
- 63, 64, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,102, 96, 63, 0, 1,244, 63, 76,204,193, 63, 0, 0, 0, 63, 73,234, 80,
- 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,234, 80, 63, 11,111,146, 63, 67, 99, 87, 63, 11,116, 96, 63, 70,102, 96, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 63, 0, 0, 0, 63, 70,102, 96, 63, 0, 1,244, 63, 67, 99, 87, 63, 11,116, 96, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 67, 99, 87, 63, 11,116, 96, 63, 73,234, 80, 63, 11,111,146, 63, 70,235,176, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57,153,160,
- 63, 0, 1,244, 63, 64, 0, 0, 63, 0, 0, 0, 63, 60,156,169, 63, 11,116, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 60,156,169, 63, 11,116, 96,
- 63, 54, 21,176, 63, 11,111,146, 63, 57,153,160, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 51, 51, 63, 63, 0, 0, 0, 63, 57,153,160,
- 63, 0, 1,244, 63, 54, 21,176, 63, 11,111,146, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54, 21,176, 63, 11,111,146, 63, 60,156,169, 63, 11,116, 96,
- 63, 57, 20, 80, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62,217, 58, 93, 63, 57, 61,144, 62,217,196, 19, 63, 60,123, 85,
- 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 60,123, 85, 62,198,230,253, 63, 67,132,171, 62,198,230,253, 63, 64, 0, 0, 62,217, 58, 93,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 70,194,112, 62,217,196, 19, 63, 64, 0, 0, 62,217, 58, 93, 63, 67,132,171, 62,198,230,253, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 67,132,171, 62,198,230,253, 63, 60,123, 85, 62,198,230,253, 63, 64, 0, 0, 62,180,111,211, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0,
- 62,217, 58, 93, 63, 70,194,112, 62,217,196, 19, 63, 67, 84,125, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 67, 84,125, 62,236,211, 42,
- 63, 60,171,131, 62,236,211, 42, 63, 64, 0, 0, 62,217, 58, 93, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57, 61,144, 62,217,196, 19, 63, 64, 0, 0,
- 62,217, 58, 93, 63, 60,171,131, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 60,171,131, 62,236,211, 42, 63, 67, 84,125, 62,236,211, 42,
- 63, 64, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57,153,160, 63, 0, 1,244, 63, 51, 51, 63, 63, 0, 0, 0, 63, 54, 46,128,
- 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 54, 46,128, 62,236,207, 75, 63, 60,171,131, 62,236,211, 42, 63, 57,153,160, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 63, 0, 0, 0, 63, 57,153,160, 63, 0, 1,244, 63, 60,171,131, 62,236,211, 42, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 60,171,131, 62,236,211, 42, 63, 54, 46,128, 62,236,207, 75, 63, 57, 61,144, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,102, 96,
- 63, 0, 1,244, 63, 64, 0, 0, 63, 0, 0, 0, 63, 67, 84,125, 62,236,211, 42, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 67, 84,125, 62,236,211, 42,
- 63, 73,209,128, 62,236,207, 75, 63, 70,102, 96, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,204,193, 63, 0, 0, 0, 63, 70,102, 96,
- 63, 0, 1,244, 63, 73,209,128, 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,209,128, 62,236,207, 75, 63, 67, 84,125, 62,236,211, 42,
- 63, 70,194,112, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 51, 22, 43, 63, 21, 48, 35, 63, 45, 40,237, 63, 19, 29,252, 63, 48, 55,255,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 55,255, 63, 9,152, 94, 63, 54, 21,176, 63, 11,111,146, 63, 51, 22, 43, 63, 21, 48, 35,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 57, 20, 80, 63, 22,209,226, 63, 51, 22, 43, 63, 21, 48, 35, 63, 54, 21,176, 63, 11,111,146, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 54, 21,176, 63, 11,111,146, 63, 48, 55,255, 63, 9,152, 94, 63, 51, 51, 63, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 51, 22, 43,
- 63, 21, 48, 35, 63, 57, 20, 80, 63, 22,209,226, 63, 54, 36, 91, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54, 36, 91, 63, 33, 23,173,
- 63, 47,214, 36, 63, 31, 60,105, 63, 51, 22, 43, 63, 21, 48, 35, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 40,237, 63, 19, 29,252, 63, 51, 22, 43,
- 63, 21, 48, 35, 63, 47,214, 36, 63, 31, 60,105, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 47,214, 36, 63, 31, 60,105, 63, 54, 36, 91, 63, 33, 23,173,
- 63, 50,222, 60, 63, 43, 52,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 44,131,181, 63, 40,228,216, 63, 38,102,117, 63, 37,200, 45, 63, 41,235, 38,
- 63, 28,140,141, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,235, 38, 63, 28,140,141, 63, 47,214, 36, 63, 31, 60,105, 63, 44,131,181, 63, 40,228,216,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 50,222, 60, 63, 43, 52,221, 63, 44,131,181, 63, 40,228,216, 63, 47,214, 36, 63, 31, 60,105, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 47,214, 36, 63, 31, 60,105, 63, 41,235, 38, 63, 28,140,141, 63, 45, 40,237, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57, 97, 87,
- 63, 44,160,200, 63, 50,222, 60, 63, 43, 52,221, 63, 54, 36, 91, 63, 33, 23,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54, 36, 91, 63, 33, 23,173,
- 63, 60, 84,251, 63, 34, 17,216, 63, 57, 97, 87, 63, 44,160,200, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 63, 45, 28, 24, 63, 57, 97, 87,
- 63, 44,160,200, 63, 60, 84,251, 63, 34, 17,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 60, 84,251, 63, 34, 17,216, 63, 54, 36, 91, 63, 33, 23,173,
- 63, 57, 20, 80, 63, 22,209,226, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 14,134, 63, 21, 48, 39, 63,122, 30,227, 63, 22,209,233, 63,125, 29,138,
- 63, 11,111,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,125, 29,138, 63, 11,111,150, 63,129,125,159, 63, 9,152, 94, 63,128, 14,134, 63, 21, 48, 39,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 60,193, 73,174, 63, 19, 29,253, 57,232, 92,209, 63, 21, 48, 39, 60, 62,207,114, 63, 9,152, 94, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,129,125,159, 63, 9,152, 94, 63,125, 29,138, 63, 11,111,150, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 57,232, 92,209,
- 63, 21, 48, 39, 60,193, 73,174, 63, 19, 29,253, 60, 87, 67,214, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,129,174,136, 63, 31, 60,110,
- 63,125, 14,213, 63, 33, 23,180, 63,128, 14,134, 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,122, 30,227, 63, 22,209,233, 63,128, 14,134,
- 63, 21, 48, 39, 63,125, 14,213, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,125, 14,213, 63, 33, 23,180, 63,129,174,136, 63, 31, 60,110,
- 63,128, 42,121, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,209,210, 63, 44,160,212, 63,115, 51, 36, 63, 45, 28, 36, 63,118,222, 49,
- 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,118,222, 49, 63, 34, 17,226, 63,125, 14,213, 63, 33, 23,180, 63,121,209,210, 63, 44,160,212,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 42,121, 63, 43, 52,230, 63,121,209,210, 63, 44,160,212, 63,125, 14,213, 63, 33, 23,180, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,125, 14,213, 63, 33, 23,180, 63,118,222, 49, 63, 34, 17,226, 63,122, 30,227, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,213,239,111,
- 63, 40,228,223, 58,169,226,120, 63, 43, 52,230, 60, 87, 67,214, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60, 87, 67,214, 63, 31, 60,110,
- 61, 20,129, 13, 63, 28,140,143, 60,213,239,111, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,203,246, 63, 37,200, 48, 60,213,239,111,
- 63, 40,228,223, 61, 20,129, 13, 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 20,129, 13, 63, 28,140,143, 60, 87, 67,214, 63, 31, 60,110,
- 60,193, 73,174, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 44, 63, 23, 32,188, 63,122, 30,227, 63, 22,209,233, 63,118,222, 49,
- 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,118,222, 49, 63, 34, 17,226, 63,111,136, 31, 63, 34, 17,225, 63,115, 51, 44, 63, 23, 32,188,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,108, 71,116, 63, 22,209,232, 63,115, 51, 44, 63, 23, 32,188, 63,111,136, 31, 63, 34, 17,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,111,136, 31, 63, 34, 17,225, 63,118,222, 49, 63, 34, 17,226, 63,115, 51, 36, 63, 45, 28, 36, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 44,
- 63, 23, 32,188, 63,108, 71,116, 63, 22,209,232, 63,111,207,213, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,111,207,213, 63, 11,116,100,
- 63,118,150,138, 63, 11,116,101, 63,115, 51, 44, 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,122, 30,227, 63, 22,209,233, 63,115, 51, 44,
- 63, 23, 32,188, 63,118,150,138, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,118,150,138, 63, 11,116,101, 63,111,207,213, 63, 11,116,100,
- 63,115, 51, 51, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,153,154, 63, 0, 1,244, 63,128, 0, 0, 63, 0, 0, 0, 63,125, 29,138,
- 63, 11,111,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,125, 29,138, 63, 11,111,150, 63,118,150,138, 63, 11,116,101, 63,121,153,154, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 51, 63, 0, 0, 0, 63,121,153,154, 63, 0, 1,244, 63,118,150,138, 63, 11,116,101, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,118,150,138, 63, 11,116,101, 63,125, 29,138, 63, 11,111,150, 63,122, 30,227, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,204,205,
- 63, 0, 1,244, 63,115, 51, 51, 63, 0, 0, 0, 63,111,207,213, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,111,207,213, 63, 11,116,100,
- 63,105, 72,213, 63, 11,111,149, 63,108,204,205, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102,102,101, 63, 0, 0, 0, 63,108,204,205,
- 63, 0, 1,244, 63,105, 72,213, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105, 72,213, 63, 11,111,149, 63,111,207,213, 63, 11,116,100,
- 63,108, 71,116, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 58, 62,217, 58, 73, 63,108,112,192, 62,217,196, 4, 63,111,174,139,
- 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,111,174,139, 62,198,230,223, 63,118,183,239, 62,198,230,227, 63,115, 51, 58, 62,217, 58, 73,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,121,245,179, 62,217,196, 6, 63,115, 51, 58, 62,217, 58, 73, 63,118,183,239, 62,198,230,227, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,118,183,239, 62,198,230,227, 63,111,174,139, 62,198,230,223, 63,115, 51, 65, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 58,
- 62,217, 58, 73, 63,121,245,179, 62,217,196, 6, 63,118,135,185, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,118,135,185, 62,236,211, 30,
- 63,111,222,180, 62,236,211, 30, 63,115, 51, 58, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,112,192, 62,217,196, 4, 63,115, 51, 58,
- 62,217, 58, 73, 63,111,222,180, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,111,222,180, 62,236,211, 30, 63,118,135,185, 62,236,211, 30,
- 63,115, 51, 51, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,204,205, 63, 0, 1,244, 63,102,102,101, 63, 0, 0, 0, 63,105, 97,170,
- 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,105, 97,170, 62,236,207, 65, 63,111,222,180, 62,236,211, 30, 63,108,204,205, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 51, 63, 0, 0, 0, 63,108,204,205, 63, 0, 1,244, 63,111,222,180, 62,236,211, 30, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,111,222,180, 62,236,211, 30, 63,105, 97,170, 62,236,207, 65, 63,108,112,192, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,153,154,
- 63, 0, 1,244, 63,115, 51, 51, 63, 0, 0, 0, 63,118,135,185, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,118,135,185, 62,236,211, 30,
- 63,125, 4,194, 62,236,207, 67, 63,121,153,154, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,121,153,154,
- 63, 0, 1,244, 63,125, 4,194, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,125, 4,194, 62,236,207, 67, 63,118,135,185, 62,236,211, 30,
- 63,121,245,179, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102, 73, 76, 63, 21, 48, 38, 63, 96, 92, 11, 63, 19, 29,253, 63, 99,107, 33,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,107, 33, 63, 9,152, 94, 63,105, 72,213, 63, 11,111,149, 63,102, 73, 76, 63, 21, 48, 38,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,108, 71,116, 63, 22,209,232, 63,102, 73, 76, 63, 21, 48, 38, 63,105, 72,213, 63, 11,111,149, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,105, 72,213, 63, 11,111,149, 63, 99,107, 33, 63, 9,152, 94, 63,102,102,101, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102, 73, 76,
- 63, 21, 48, 38, 63,108, 71,116, 63, 22,209,232, 63,105, 87,124, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105, 87,124, 63, 33, 23,180,
- 63, 99, 9, 65, 63, 31, 60,109, 63,102, 73, 76, 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96, 92, 11, 63, 19, 29,253, 63,102, 73, 76,
- 63, 21, 48, 38, 63, 99, 9, 65, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99, 9, 65, 63, 31, 60,109, 63,105, 87,124, 63, 33, 23,180,
- 63,102, 17, 87, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 95,182,205, 63, 40,228,222, 63, 89,153,139, 63, 37,200, 45, 63, 93, 30, 63,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 93, 30, 63, 63, 28,140,143, 63, 99, 9, 65, 63, 31, 60,109, 63, 95,182,205, 63, 40,228,222,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,102, 17, 87, 63, 43, 52,229, 63, 95,182,205, 63, 40,228,222, 63, 99, 9, 65, 63, 31, 60,109, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 99, 9, 65, 63, 31, 60,109, 63, 93, 30, 63, 63, 28,140,143, 63, 96, 92, 11, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,148,118,
- 63, 44,160,211, 63,102, 17, 87, 63, 43, 52,229, 63,105, 87,124, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105, 87,124, 63, 33, 23,180,
- 63,111,136, 31, 63, 34, 17,225, 63,108,148,118, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 36, 63, 45, 28, 36, 63,108,148,118,
- 63, 44,160,211, 63,111,136, 31, 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,111,136, 31, 63, 34, 17,225, 63,105, 87,124, 63, 33, 23,180,
- 63,108, 71,116, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 77, 65, 65, 63, 21, 48, 32, 62, 53, 72,152, 63, 22,209,229, 62, 65, 67, 47,
- 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 65, 67, 47, 63, 11,111,147, 62, 88,185,255, 63, 9,152, 90, 62, 77, 65, 65, 63, 21, 48, 32,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,100,246, 64, 63, 19, 29,246, 62, 77, 65, 65, 63, 21, 48, 32, 62, 88,185,255, 63, 9,152, 90, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 88,185,255, 63, 9,152, 90, 62, 65, 67, 47, 63, 11,111,147, 62, 76,204,254, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 77, 65, 65,
- 63, 21, 48, 32, 62,100,246, 64, 63, 19, 29,246, 62, 90, 65, 89, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 90, 65, 89, 63, 31, 60, 94,
- 62, 65, 8,107, 63, 33, 23,170, 62, 77, 65, 65, 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 53, 72,152, 63, 22,209,229, 62, 77, 65, 65,
- 63, 21, 48, 32, 62, 65, 8,107, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 65, 8,107, 63, 33, 23,170, 62, 90, 65, 89, 63, 31, 60, 94,
- 62, 78, 32,230, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 52, 20,105, 63, 44,160,198, 62, 25,153,173, 63, 45, 28, 27, 62, 40, 69,216,
- 63, 34, 17,220, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 40, 69,216, 63, 34, 17,220, 62, 65, 8,107, 63, 33, 23,170, 62, 52, 20,105, 63, 44,160,198,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 78, 32,230, 63, 43, 52,211, 62, 52, 20,105, 63, 44,160,198, 62, 65, 8,107, 63, 33, 23,170, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 65, 8,107, 63, 33, 23,170, 62, 40, 69,216, 63, 34, 17,220, 62, 53, 72,152, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,103,139, 14,
- 63, 40,228,199, 62, 78, 32,230, 63, 43, 52,211, 62, 90, 65, 89, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 90, 65, 89, 63, 31, 60, 94,
- 62,113,237, 83, 63, 28,140,130, 62,103,139, 14, 63, 40,228,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 37,200, 23, 62,103,139, 14,
- 63, 40,228,199, 62,113,237, 83, 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,113,237, 83, 63, 28,140,130, 62, 90, 65, 89, 63, 31, 60, 94,
- 62,100,246, 64, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,180, 63, 23, 32,185, 62, 53, 72,152, 63, 22,209,229, 62, 40, 69,216,
- 63, 34, 17,220, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 40, 69,216, 63, 34, 17,220, 62, 10,237,133, 63, 34, 17,219, 62, 25,153,180, 63, 23, 32,185,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,251,213,147, 63, 22,209,228, 62, 25,153,180, 63, 23, 32,185, 62, 10,237,133, 63, 34, 17,219, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 10,237,133, 63, 34, 17,219, 62, 40, 69,216, 63, 34, 17,220, 62, 25,153,173, 63, 45, 28, 27, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,180,
- 63, 23, 32,185, 61,251,213,147, 63, 22,209,228, 62, 12, 12, 67, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 12, 12, 67, 63, 11,116, 98,
- 62, 39, 39, 34, 63, 11,116, 98, 62, 25,153,180, 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 53, 72,152, 63, 22,209,229, 62, 25,153,180,
- 63, 23, 32,185, 62, 39, 39, 34, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 39, 39, 34, 63, 11,116, 98, 62, 12, 12, 67, 63, 11,116, 98,
- 62, 25,153,181, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 51, 92, 63, 0, 1,244, 62, 76,204,254, 63, 0, 0, 0, 62, 65, 67, 47,
- 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 65, 67, 47, 63, 11,111,147, 62, 39, 39, 34, 63, 11,116, 98, 62, 51, 51, 92, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,181, 63, 0, 0, 0, 62, 51, 51, 92, 63, 0, 1,244, 62, 39, 39, 34, 63, 11,116, 98, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 39, 39, 34, 63, 11,116, 98, 62, 65, 67, 47, 63, 11,111,147, 62, 53, 72,152, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 8,
- 63, 0, 1,244, 62, 25,153,181, 63, 0, 0, 0, 62, 12, 12, 67, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 12, 12, 67, 63, 11,116, 98,
- 61,227,224,109, 63, 11,111,147, 62, 0, 0, 8, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,215, 63, 0, 0, 0, 62, 0, 0, 8,
- 63, 0, 1,244, 61,227,224,109, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,227,224,109, 63, 11,111,147, 62, 12, 12, 67, 63, 11,116, 98,
- 61,251,213,147, 63, 22,209,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,196, 62,217, 58, 73, 61,253, 31,171, 62,217,196, 6, 62, 11,135, 1,
- 62,198,230,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 11,135, 1, 62,198,230,228, 62, 39,172,153, 62,198,230,230, 62, 25,153,196, 62,217, 58, 73,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 52,163,179, 62,217,196, 7, 62, 25,153,196, 62,217, 58, 73, 62, 39,172,153, 62,198,230,230, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 39,172,153, 62,198,230,230, 62, 11,135, 1, 62,198,230,228, 62, 25,153,214, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,196,
- 62,217, 58, 73, 62, 52,163,179, 62,217,196, 7, 62, 38,235,202, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 38,235,202, 62,236,211, 33,
- 62, 12, 71,173, 62,236,211, 31, 62, 25,153,196, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,253, 31,171, 62,217,196, 6, 62, 25,153,196,
- 62,217, 58, 73, 62, 12, 71,173, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 12, 71,173, 62,236,211, 31, 62, 38,235,202, 62,236,211, 33,
- 62, 25,153,181, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 8, 63, 0, 1,244, 61,204,204,215, 63, 0, 0, 0, 61,228,166,251,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,228,166,251, 62,236,207, 67, 62, 12, 71,173, 62,236,211, 31, 62, 0, 0, 8, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,181, 63, 0, 0, 0, 62, 0, 0, 8, 63, 0, 1,244, 62, 12, 71,173, 62,236,211, 31, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 12, 71,173, 62,236,211, 31, 61,228,166,251, 62,236,207, 67, 61,253, 31,171, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 51, 51, 92,
- 63, 0, 1,244, 62, 25,153,181, 63, 0, 0, 0, 62, 38,235,202, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 38,235,202, 62,236,211, 33,
- 62, 64,223,251, 62,236,207, 67, 62, 51, 51, 92, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 76,204,254, 63, 0, 0, 0, 62, 51, 51, 92,
- 63, 0, 1,244, 62, 64,223,251, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 64,223,251, 62,236,207, 67, 62, 38,235,202, 62,236,211, 33,
- 62, 52,163,179, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,203,228, 42, 63, 21, 48, 37, 61,156,122, 1, 63, 19, 29,254, 61,180,242,172,
- 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,180,242,172, 63, 9,152, 96, 61,227,224,109, 63, 11,111,147, 61,203,228, 42, 63, 21, 48, 37,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,251,213,147, 63, 22,209,228, 61,203,228, 42, 63, 21, 48, 37, 61,227,224,109, 63, 11,111,147, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,227,224,109, 63, 11,111,147, 61,180,242,172, 63, 9,152, 96, 61,204,204,215, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,203,228, 42,
- 63, 21, 48, 37, 61,251,213,147, 63, 22,209,228, 61,228, 85,208, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,228, 85,208, 63, 33, 23,179,
- 61,177,227,212, 63, 31, 60,110, 61,203,228, 42, 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,156,122, 1, 63, 19, 29,254, 61,203,228, 42,
- 63, 21, 48, 37, 61,177,227,212, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,177,227,212, 63, 31, 60,110, 61,228, 85,208, 63, 33, 23,179,
- 61,202, 36,175, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,151, 80, 53, 63, 40,228,223, 61, 76,203,246, 63, 37,200, 48, 61,130,139,166,
- 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,130,139,166, 63, 28,140,145, 61,177,227,212, 63, 31, 60,110, 61,151, 80, 53, 63, 40,228,223,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,202, 36,175, 63, 43, 52,228, 61,151, 80, 53, 63, 40,228,223, 61,177,227,212, 63, 31, 60,110, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,177,227,212, 63, 31, 60,110, 61,130,139,166, 63, 28,140,145, 61,156,122, 1, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,254, 61,201,
- 63, 44,160,207, 61,202, 36,175, 63, 43, 52,228, 61,228, 85,208, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,228, 85,208, 63, 33, 23,179,
- 62, 10,237,133, 63, 34, 17,219, 61,254, 61,201, 63, 44,160,207, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,173, 63, 45, 28, 27, 61,254, 61,201,
- 63, 44,160,207, 62, 10,237,133, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 10,237,133, 63, 34, 17,219, 61,228, 85,208, 63, 33, 23,179,
- 61,251,213,147, 63, 22,209,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,205, 6,245, 63, 21, 48, 37, 62,193, 10,155, 63, 22,209,229, 62,199, 7,229,
- 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,199, 7,229, 63, 11,111,147, 62,210,195, 85, 63, 9,152, 96, 62,205, 6,245, 63, 21, 48, 37,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,216,225,128, 63, 19, 29,254, 62,205, 6,245, 63, 21, 48, 37, 62,210,195, 85, 63, 9,152, 96, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,210,195, 85, 63, 9,152, 96, 62,199, 7,229, 63, 11,111,147, 62,204,204,202, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,205, 6,245,
- 63, 21, 48, 37, 62,216,225,128, 63, 19, 29,254, 62,211,135, 11, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,211,135, 11, 63, 31, 60,110,
- 62,198,234,140, 63, 33, 23,179, 62,205, 6,245, 63, 21, 48, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,193, 10,155, 63, 22,209,229, 62,205, 6,245,
- 63, 21, 48, 37, 62,198,234,140, 63, 33, 23,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198,234,140, 63, 33, 23,179, 62,211,135, 11, 63, 31, 60,110,
- 62,205,118,212, 63, 43, 52,228, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,192,112,142, 63, 44,160,207, 62,179, 51, 42, 63, 45, 28, 28, 62,186,137, 61,
- 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,186,137, 61, 63, 34, 17,219, 62,198,234,140, 63, 33, 23,179, 62,192,112,142, 63, 44,160,207,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,205,118,212, 63, 43, 52,228, 62,192,112,142, 63, 44,160,207, 62,198,234,140, 63, 33, 23,179, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,198,234,140, 63, 33, 23,179, 62,186,137, 61, 63, 34, 17,219, 62,193, 10,155, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,218, 43,243,
- 63, 40,228,223, 62,205,118,212, 63, 43, 52,228, 62,211,135, 11, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,211,135, 11, 63, 31, 60,110,
- 62,223, 93, 22, 63, 28,140,145, 62,218, 43,243, 63, 40,228,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,129, 63, 37,200, 48, 62,218, 43,243,
- 63, 40,228,223, 62,223, 93, 22, 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223, 93, 22, 63, 28,140,145, 62,211,135, 11, 63, 31, 60,110,
- 62,216,225,128, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 38, 63, 23, 32,185, 62,193, 10,155, 63, 22,209,229, 62,186,137, 61,
- 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,186,137, 61, 63, 34, 17,219, 62,171,221, 20, 63, 34, 17,219, 62,179, 51, 38, 63, 23, 32,185,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,165, 91,180, 63, 22,209,229, 62,179, 51, 38, 63, 23, 32,185, 62,171,221, 20, 63, 34, 17,219, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,171,221, 20, 63, 34, 17,219, 62,186,137, 61, 63, 34, 17,219, 62,179, 51, 42, 63, 45, 28, 28, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 38,
- 63, 23, 32,185, 62,165, 91,180, 63, 22,209,229, 62,172,108,111, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,172,108,111, 63, 11,116, 98,
- 62,185,249,222, 63, 11,116, 98, 62,179, 51, 38, 63, 23, 32,185, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,193, 10,155, 63, 22,209,229, 62,179, 51, 38,
- 63, 23, 32,185, 62,185,249,222, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,185,249,222, 63, 11,116, 98, 62,172,108,111, 63, 11,116, 98,
- 62,179, 51, 38, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,191,255,252, 63, 0, 1,244, 62,204,204,202, 63, 0, 0, 0, 62,199, 7,229,
- 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,199, 7,229, 63, 11,111,147, 62,185,249,222, 63, 11,116, 98, 62,191,255,252, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 38, 63, 0, 0, 0, 62,191,255,252, 63, 0, 1,244, 62,185,249,222, 63, 11,116, 98, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,185,249,222, 63, 11,116, 98, 62,199, 7,229, 63, 11,111,147, 62,193, 10,155, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,166,102, 82,
- 63, 0, 1,244, 62,179, 51, 38, 63, 0, 0, 0, 62,172,108,111, 63, 11,116, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,172,108,111, 63, 11,116, 98,
- 62,159, 94,104, 63, 11,111,147, 62,166,102, 82, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,153,153,129, 63, 0, 0, 0, 62,166,102, 82,
- 63, 0, 1,244, 62,159, 94,104, 63, 11,111,147, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159, 94,104, 63, 11,111,147, 62,172,108,111, 63, 11,116, 98,
- 62,165, 91,180, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 30, 62,217, 58, 73, 62,165,174, 39, 62,217,196, 7, 62,172, 41,180,
- 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,172, 41,180, 62,198,230,227, 62,186, 60,127, 62,198,230,225, 62,179, 51, 30, 62,217, 58, 73,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,192,184, 21, 62,217,196, 6, 62,179, 51, 30, 62,217, 58, 73, 62,186, 60,127, 62,198,230,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,186, 60,127, 62,198,230,225, 62,172, 41,180, 62,198,230,227, 62,179, 51, 21, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 30,
- 62,217, 58, 73, 62,192,184, 21, 62,217,196, 6, 62,185,220, 42, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,185,220, 42, 62,236,211, 31,
- 62,172,138, 27, 62,236,211, 33, 62,179, 51, 30, 62,217, 58, 73, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,165,174, 39, 62,217,196, 7, 62,179, 51, 30,
- 62,217, 58, 73, 62,172,138, 27, 62,236,211, 33, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,172,138, 27, 62,236,211, 33, 62,185,220, 42, 62,236,211, 31,
- 62,179, 51, 38, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,166,102, 82, 63, 0, 1,244, 62,153,153,129, 63, 0, 0, 0, 62,159,144, 3,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,159,144, 3, 62,236,207, 67, 62,172,138, 27, 62,236,211, 33, 62,166,102, 82, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 38, 63, 0, 0, 0, 62,166,102, 82, 63, 0, 1,244, 62,172,138, 27, 62,236,211, 33, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,172,138, 27, 62,236,211, 33, 62,159,144, 3, 62,236,207, 67, 62,165,174, 39, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,191,255,252,
- 63, 0, 1,244, 62,179, 51, 38, 63, 0, 0, 0, 62,185,220, 42, 62,236,211, 31, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,185,220, 42, 62,236,211, 31,
- 62,198,214, 65, 62,236,207, 67, 62,191,255,252, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,204,204,202, 63, 0, 0, 0, 62,191,255,252,
- 63, 0, 1,244, 62,198,214, 65, 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198,214, 65, 62,236,207, 67, 62,185,220, 42, 62,236,211, 31,
- 62,192,184, 21, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,153, 95, 95, 63, 21, 48, 32, 62,141,132,224, 63, 19, 29,246, 62,147,163, 1,
- 63, 9,152, 91, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,147,163, 1, 63, 9,152, 91, 62,159, 94,104, 63, 11,111,147, 62,153, 95, 95, 63, 21, 48, 32,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,165, 91,180, 63, 22,209,229, 62,153, 95, 95, 63, 21, 48, 32, 62,159, 94,104, 63, 11,111,147, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,159, 94,104, 63, 11,111,147, 62,147,163, 1, 63, 9,152, 91, 62,153,153,129, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,153, 95, 95,
- 63, 21, 48, 32, 62,165, 91,180, 63, 22,209,229, 62,159,123,203, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159,123,203, 63, 33, 23,170,
- 62,146,223, 84, 63, 31, 60, 94, 62,153, 95, 95, 63, 21, 48, 32, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141,132,224, 63, 19, 29,246, 62,153, 95, 95,
- 63, 21, 48, 32, 62,146,223, 84, 63, 31, 60, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,146,223, 84, 63, 31, 60, 94, 62,159,123,203, 63, 33, 23,170,
- 62,152,239,141, 63, 43, 52,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,140, 58,121, 63, 40,228,199, 62,128, 0, 0, 63, 37,200, 23, 62,135, 9, 86,
- 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,135, 9, 86, 63, 28,140,130, 62,146,223, 84, 63, 31, 60, 94, 62,140, 58,121, 63, 40,228,199,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,152,239,141, 63, 43, 52,211, 62,140, 58,121, 63, 40,228,199, 62,146,223, 84, 63, 31, 60, 94, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,146,223, 84, 63, 31, 60, 94, 62,135, 9, 86, 63, 28,140,130, 62,141,132,224, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,165,245,204,
- 63, 44,160,198, 62,152,239,141, 63, 43, 52,211, 62,159,123,203, 63, 33, 23,170, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159,123,203, 63, 33, 23,170,
- 62,171,221, 20, 63, 34, 17,219, 62,165,245,204, 63, 44,160,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 42, 63, 45, 28, 28, 62,165,245,204,
- 63, 44,160,198, 62,171,221, 20, 63, 34, 17,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,171,221, 20, 63, 34, 17,219, 62,159,123,203, 63, 33, 23,170,
- 62,165, 91,180, 63, 22,209,229, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25,182,180, 63, 21, 48, 38, 63, 19,184,140, 63, 22,209,232, 63, 22,183, 43,
- 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,183, 43, 63, 11,111,149, 63, 28,148,223, 63, 9,152, 94, 63, 25,182,180, 63, 21, 48, 38,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 31,163,245, 63, 19, 29,253, 63, 25,182,180, 63, 21, 48, 38, 63, 28,148,223, 63, 9,152, 94, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 28,148,223, 63, 9,152, 94, 63, 22,183, 43, 63, 11,111,149, 63, 25,153,155, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25,182,180,
- 63, 21, 48, 38, 63, 31,163,245, 63, 19, 29,253, 63, 28,246,191, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,246,191, 63, 31, 60,109,
- 63, 22,168,132, 63, 33, 23,180, 63, 25,182,180, 63, 21, 48, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,184,140, 63, 22,209,232, 63, 25,182,180,
- 63, 21, 48, 38, 63, 22,168,132, 63, 33, 23,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,168,132, 63, 33, 23,180, 63, 28,246,191, 63, 31, 60,109,
- 63, 25,238,169, 63, 43, 52,229, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,107,138, 63, 44,160,211, 63, 12,204,220, 63, 45, 28, 35, 63, 16,119,225,
- 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 16,119,225, 63, 34, 17,225, 63, 22,168,132, 63, 33, 23,180, 63, 19,107,138, 63, 44,160,211,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 25,238,169, 63, 43, 52,229, 63, 19,107,138, 63, 44,160,211, 63, 22,168,132, 63, 33, 23,180, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 22,168,132, 63, 33, 23,180, 63, 16,119,225, 63, 34, 17,225, 63, 19,184,140, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 32, 73, 51,
- 63, 40,228,221, 63, 25,238,169, 63, 43, 52,229, 63, 28,246,191, 63, 31, 60,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,246,191, 63, 31, 60,109,
- 63, 34,225,192, 63, 28,140,142, 63, 32, 73, 51, 63, 40,228,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,117, 63, 37,200, 45, 63, 32, 73, 51,
- 63, 40,228,221, 63, 34,225,192, 63, 28,140,142, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 34,225,192, 63, 28,140,142, 63, 28,246,191, 63, 31, 60,109,
- 63, 31,163,245, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,212, 63, 23, 32,188, 63, 19,184,140, 63, 22,209,232, 63, 16,119,225,
- 63, 34, 17,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 16,119,225, 63, 34, 17,225, 63, 9, 33,207, 63, 34, 17,226, 63, 12,204,212, 63, 23, 32,188,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 5,225, 29, 63, 22,209,233, 63, 12,204,212, 63, 23, 32,188, 63, 9, 33,207, 63, 34, 17,226, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 9, 33,207, 63, 34, 17,226, 63, 16,119,225, 63, 34, 17,225, 63, 12,204,220, 63, 45, 28, 35, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,212,
- 63, 23, 32,188, 63, 5,225, 29, 63, 22,209,233, 63, 9,105,118, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 9,105,118, 63, 11,116,101,
- 63, 16, 48, 43, 63, 11,116,100, 63, 12,204,212, 63, 23, 32,188, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,184,140, 63, 22,209,232, 63, 12,204,212,
- 63, 23, 32,188, 63, 16, 48, 43, 63, 11,116,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 16, 48, 43, 63, 11,116,100, 63, 9,105,118, 63, 11,116,101,
- 63, 12,204,205, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19, 51, 51, 63, 0, 1,244, 63, 25,153,155, 63, 0, 0, 0, 63, 22,183, 43,
- 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,183, 43, 63, 11,111,149, 63, 16, 48, 43, 63, 11,116,100, 63, 19, 51, 51, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,205, 63, 0, 0, 0, 63, 19, 51, 51, 63, 0, 1,244, 63, 16, 48, 43, 63, 11,116,100, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 16, 48, 43, 63, 11,116,100, 63, 22,183, 43, 63, 11,111,149, 63, 19,184,140, 63, 22,209,232, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6,102,102,
- 63, 0, 1,244, 63, 12,204,205, 63, 0, 0, 0, 63, 9,105,118, 63, 11,116,101, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 9,105,118, 63, 11,116,101,
- 63, 2,226,118, 63, 11,111,149, 63, 6,102,102, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 6,102,102,
- 63, 0, 1,244, 63, 2,226,118, 63, 11,111,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 2,226,118, 63, 11,111,149, 63, 9,105,118, 63, 11,116,101,
- 63, 5,225, 29, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,198, 62,217, 58, 72, 63, 6, 10, 77, 62,217,196, 6, 63, 9, 72, 17,
- 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 9, 72, 17, 62,198,230,227, 63, 16, 81,117, 62,198,230,223, 63, 12,204,198, 62,217, 58, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 19,143, 64, 62,217,196, 4, 63, 12,204,198, 62,217, 58, 72, 63, 16, 81,117, 62,198,230,223, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 16, 81,117, 62,198,230,223, 63, 9, 72, 17, 62,198,230,227, 63, 12,204,191, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,198,
- 62,217, 58, 72, 63, 19,143, 64, 62,217,196, 4, 63, 16, 33, 76, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 16, 33, 76, 62,236,211, 30,
- 63, 9,120, 71, 62,236,211, 30, 63, 12,204,198, 62,217, 58, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6, 10, 77, 62,217,196, 6, 63, 12,204,198,
- 62,217, 58, 72, 63, 9,120, 71, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 9,120, 71, 62,236,211, 30, 63, 16, 33, 76, 62,236,211, 30,
- 63, 12,204,205, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6,102,102, 63, 0, 1,244, 63, 0, 0, 0, 63, 0, 0, 0, 63, 2,251, 62,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 2,251, 62, 62,236,207, 67, 63, 9,120, 71, 62,236,211, 30, 63, 6,102,102, 63, 0, 1,244,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,205, 63, 0, 0, 0, 63, 6,102,102, 63, 0, 1,244, 63, 9,120, 71, 62,236,211, 30, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 9,120, 71, 62,236,211, 30, 63, 2,251, 62, 62,236,207, 67, 63, 6, 10, 77, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19, 51, 51,
- 63, 0, 1,244, 63, 12,204,205, 63, 0, 0, 0, 63, 16, 33, 76, 62,236,211, 30, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 16, 33, 76, 62,236,211, 30,
- 63, 22,158, 86, 62,236,207, 65, 63, 19, 51, 51, 63, 0, 1,244, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25,153,155, 63, 0, 0, 0, 63, 19, 51, 51,
- 63, 0, 1,244, 63, 22,158, 86, 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,158, 86, 62,236,207, 65, 63, 16, 33, 76, 62,236,211, 30,
- 63, 19,143, 64, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,197,233, 63, 21, 48, 39, 62,243,235,101, 63, 19, 29,252, 62,250, 9,132,
- 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 9,132, 63, 9,152, 94, 63, 2,226,118, 63, 11,111,149, 62,255,197,233, 63, 21, 48, 39,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 5,225, 29, 63, 22,209,233, 62,255,197,233, 63, 21, 48, 39, 63, 2,226,118, 63, 11,111,149, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 2,226,118, 63, 11,111,149, 62,250, 9,132, 63, 9,152, 94, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,197,233,
- 63, 21, 48, 39, 63, 5,225, 29, 63, 22,209,233, 63, 2,241, 43, 63, 33, 23,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 2,241, 43, 63, 33, 23,181,
- 62,249, 69,225, 63, 31, 60,110, 62,255,197,233, 63, 21, 48, 39, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243,235,101, 63, 19, 29,252, 62,255,197,233,
- 63, 21, 48, 39, 62,249, 69,225, 63, 31, 60,110, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,249, 69,225, 63, 31, 60,110, 63, 2,241, 43, 63, 33, 23,181,
- 62,255, 86, 30, 63, 43, 52,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,242,161, 9, 63, 40,228,223, 62,230,102,129, 63, 37,200, 48, 62,237,111,222,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,237,111,222, 63, 28,140,143, 62,249, 69,225, 63, 31, 60,110, 62,242,161, 9, 63, 40,228,223,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,255, 86, 30, 63, 43, 52,230, 62,242,161, 9, 63, 40,228,223, 62,249, 69,225, 63, 31, 60,110, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,249, 69,225, 63, 31, 60,110, 62,237,111,222, 63, 28,140,143, 62,243,235,101, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6, 46, 46,
- 63, 44,160,211, 62,255, 86, 30, 63, 43, 52,230, 63, 2,241, 43, 63, 33, 23,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 2,241, 43, 63, 33, 23,181,
- 63, 9, 33,207, 63, 34, 17,226, 63, 6, 46, 46, 63, 44,160,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,220, 63, 45, 28, 35, 63, 6, 46, 46,
- 63, 44,160,211, 63, 9, 33,207, 63, 34, 17,226, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 9, 33,207, 63, 34, 17,226, 63, 2,241, 43, 63, 33, 23,181,
- 63, 5,225, 29, 63, 22,209,233, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 85,238,138, 62,187,220, 72, 63, 82,173,218, 62,210, 92, 55, 63, 79,189,229,
- 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,189,229, 62,189,208,173, 63, 82,250,230, 62,166,190,117, 63, 85,238,138, 62,187,220, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,149, 62,165,199,201, 63, 85,238,138, 62,187,220, 72, 63, 82,250,230, 62,166,190,117, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 82,250,230, 62,166,190,117, 63, 79,189,229, 62,189,208,173, 63, 76,119,198, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,111,170,
- 62,193,135, 68, 63, 76,119,198, 62,169,150, 90, 63, 79,189,229, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,189,229, 62,189,208,173,
- 63, 76,175,176, 62,213,159,192, 63, 73,111,170, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,194,112, 62,217,196, 19, 63, 73,111,170,
- 62,193,135, 68, 63, 76,175,176, 62,213,159,192, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,175,176, 62,213,159,192, 63, 79,189,229, 62,189,208,173,
- 63, 82,173,218, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,175, 52, 62,233, 32,218, 63, 76,204,193, 63, 0, 0, 0, 63, 73,209,128,
- 62,236,207, 75, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,209,128, 62,236,207, 75, 63, 76,175,176, 62,213,159,192, 63, 79,175, 52, 62,233, 32,218,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 82,173,218, 62,210, 92, 55, 63, 79,175, 52, 62,233, 32,218, 63, 76,175,176, 62,213,159,192, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 76,175,176, 62,213,159,192, 63, 73,209,128, 62,236,207, 75, 63, 70,194,112, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73,111,170,
- 62,193,135, 68, 63, 70,194,112, 62,217,196, 19, 63, 67,132,171, 62,198,230,253, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 67,132,171, 62,198,230,253,
- 63, 70, 29, 61, 62,174, 54,114, 63, 73,111,170, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76,119,198, 62,169,150, 90, 63, 73,111,170,
- 62,193,135, 68, 63, 70, 29, 61, 62,174, 54,114, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70, 29, 61, 62,174, 54,114, 63, 67,132,171, 62,198,230,253,
- 63, 64, 0, 0, 62,180,111,211, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,175, 52, 62,233, 32,218, 63, 82,173,218, 62,210, 92, 55, 63, 86, 54, 56,
- 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 54, 56, 62,233, 23, 58, 63, 83, 51, 41, 62,255,252, 24, 63, 79,175, 52, 62,233, 32,218,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 76,204,193, 63, 0, 0, 0, 63, 79,175, 52, 62,233, 32,218, 63, 83, 51, 41, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 83, 51, 41, 62,255,252, 24, 63, 86, 54, 56, 62,233, 23, 58, 63, 89,153,147, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 92,252,239,
- 62,233, 23, 58, 63, 89,153,147, 63, 0, 0, 0, 63, 86, 54, 56, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 54, 56, 62,233, 23, 58,
- 63, 89,153,147, 62,209,190,143, 63, 92,252,239, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96,133, 78, 62,210, 92, 55, 63, 92,252,239,
- 62,233, 23, 58, 63, 89,153,147, 62,209,190,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,147, 62,209,190,143, 63, 86, 54, 56, 62,233, 23, 58,
- 63, 82,173,218, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 85,238,138, 62,187,220, 72, 63, 89,153,149, 62,165,199,201, 63, 93, 68,159,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 93, 68,159, 62,187,220, 72, 63, 89,153,147, 62,209,190,143, 63, 85,238,138, 62,187,220, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 82,173,218, 62,210, 92, 55, 63, 85,238,138, 62,187,220, 72, 63, 89,153,147, 62,209,190,143, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 89,153,147, 62,209,190,143, 63, 93, 68,159, 62,187,220, 72, 63, 96,133, 78, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 92,252,239,
- 62,233, 23, 58, 63, 96,133, 78, 62,210, 92, 55, 63, 99,131,242, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,131,242, 62,233, 32,218,
- 63, 95,255,254, 62,255,252, 24, 63, 92,252,239, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,147, 63, 0, 0, 0, 63, 92,252,239,
- 62,233, 23, 58, 63, 95,255,254, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 95,255,254, 62,255,252, 24, 63, 99,131,242, 62,233, 32,218,
- 63,102,102,101, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,111,174,139, 62,198,230,223, 63,108,112,192, 62,217,196, 4, 63,105,195,133,
- 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,105,195,133, 62,193,135, 37, 63,109, 21,249, 62,174, 54, 65, 63,111,174,139, 62,198,230,223,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 65, 62,180,111,160, 63,111,174,139, 62,198,230,223, 63,109, 21,249, 62,174, 54, 65, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,109, 21,249, 62,174, 54, 65, 63,105,195,133, 62,193,135, 37, 63,102,187,106, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,117, 70,
- 62,189,208,155, 63,102,187,106, 62,169,150, 54, 63,105,195,133, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105,195,133, 62,193,135, 37,
- 63,102,131,123, 62,213,159,181, 63, 99,117, 70, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96,133, 78, 62,210, 92, 55, 63, 99,117, 70,
- 62,189,208,155, 63,102,131,123, 62,213,159,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102,131,123, 62,213,159,181, 63,105,195,133, 62,193,135, 37,
- 63,108,112,192, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,105, 97,170, 62,236,207, 65, 63,102,102,101, 63, 0, 0, 0, 63, 99,131,242,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,131,242, 62,233, 32,218, 63,102,131,123, 62,213,159,181, 63,105, 97,170, 62,236,207, 65,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,108,112,192, 62,217,196, 4, 63,105, 97,170, 62,236,207, 65, 63,102,131,123, 62,213,159,181, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,102,131,123, 62,213,159,181, 63, 99,131,242, 62,233, 32,218, 63, 96,133, 78, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,117, 70,
- 62,189,208,155, 63, 96,133, 78, 62,210, 92, 55, 63, 93, 68,159, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 93, 68,159, 62,187,220, 72,
- 63, 96, 56, 71, 62,166,190, 99, 63, 99,117, 70, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,102,187,106, 62,169,150, 54, 63, 99,117, 70,
- 62,189,208,155, 63, 96, 56, 71, 62,166,190, 99, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96, 56, 71, 62,166,190, 99, 63, 93, 68,159, 62,187,220, 72,
- 63, 89,153,149, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99,107, 33, 63, 9,152, 94, 63, 96, 92, 11, 63, 19, 29,253, 63, 92,238, 21,
- 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 92,238, 21, 63, 9,150,112, 63, 95,255,254, 62,255,252, 24, 63, 99,107, 33, 63, 9,152, 94,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,102,102,101, 63, 0, 0, 0, 63, 99,107, 33, 63, 9,152, 94, 63, 95,255,254, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 95,255,254, 62,255,252, 24, 63, 92,238, 21, 63, 9,150,112, 63, 89,153,147, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 69, 14,
- 63, 9,150,112, 63, 89,153,147, 63, 0, 0, 0, 63, 92,238, 21, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 92,238, 21, 63, 9,150,112,
- 63, 89,153,143, 63, 19, 98,219, 63, 86, 69, 14, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 82,215, 19, 63, 19, 29,252, 63, 86, 69, 14,
- 63, 9,150,112, 63, 89,153,143, 63, 19, 98,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,143, 63, 19, 98,219, 63, 92,238, 21, 63, 9,150,112,
- 63, 96, 92, 11, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 93, 30, 63, 63, 28,140,143, 63, 89,153,139, 63, 37,200, 45, 63, 86, 20,218,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 20,218, 63, 28,140,143, 63, 89,153,143, 63, 19, 98,219, 63, 93, 30, 63, 63, 28,140,143,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 96, 92, 11, 63, 19, 29,253, 63, 93, 30, 63, 63, 28,140,143, 63, 89,153,143, 63, 19, 98,219, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 89,153,143, 63, 19, 98,219, 63, 86, 20,218, 63, 28,140,143, 63, 82,215, 19, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 86, 69, 14,
- 63, 9,150,112, 63, 82,215, 19, 63, 19, 29,252, 63, 79,200, 1, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,200, 1, 63, 9,152, 94,
- 63, 83, 51, 41, 62,255,252, 24, 63, 86, 69, 14, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,147, 63, 0, 0, 0, 63, 86, 69, 14,
- 63, 9,150,112, 63, 83, 51, 41, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 83, 51, 41, 62,255,252, 24, 63, 79,200, 1, 63, 9,152, 94,
- 63, 76,204,193, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 18, 28,237, 62,187,220, 60, 60,188, 35,151, 62,210, 92, 46, 60, 60, 74,218,
- 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 74,218, 62,189,208,150, 60,197,197,195, 62,166,190, 89, 61, 18, 28,237, 62,187,220, 60,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,205,194, 62,165,199,186, 61, 18, 28,237, 62,187,220, 60, 60,197,197,195, 62,166,190, 89, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,131, 23, 23, 62,166,190, 89, 63,129,120,150, 62,189,208,150, 63,127,171, 15, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124,162,241,
- 62,193,135, 36, 63,127,171, 15, 62,169,150, 52, 63,129,120,150, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,129,120,150, 62,189,208,150,
- 63,127,226,244, 62,213,159,179, 63,124,162,241, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,245,179, 62,217,196, 6, 63,124,162,241,
- 62,193,135, 36, 63,127,226,244, 62,213,159,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,127,226,244, 62,213,159,179, 63,129,120,150, 62,189,208,150,
- 63,130,240,142, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,129,113, 59, 62,233, 32,214, 63,128, 0, 0, 63, 0, 0, 0, 63,125, 4,194,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,125, 4,194, 62,236,207, 67, 63,127,226,244, 62,213,159,179, 63,129,113, 59, 62,233, 32,214,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,130,240,142, 62,210, 92, 46, 63,129,113, 59, 62,233, 32,214, 63,127,226,244, 62,213,159,179, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,127,226,244, 62,213,159,179, 63,125, 4,194, 62,236,207, 67, 63,121,245,179, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124,162,241,
- 62,193,135, 36, 63,121,245,179, 62,217,196, 6, 63,118,183,239, 62,198,230,227, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,118,183,239, 62,198,230,227,
- 63,121, 80,133, 62,174, 54, 65, 63,124,162,241, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,127,171, 15, 62,169,150, 52, 63,124,162,241,
- 62,193,135, 36, 63,121, 80,133, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121, 80,133, 62,174, 54, 65, 63,118,183,239, 62,198,230,227,
- 63,115, 51, 65, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60, 56,157,110, 62,233, 32,214, 60,188, 35,151, 62,210, 92, 46, 61, 22,151, 95,
- 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61, 22,151, 95, 62,233, 23, 55, 60,204,204,176, 62,255,252, 24, 60, 56,157,110, 62,233, 32,214,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 38, 11, 79,167, 63, 0, 0, 0, 60, 56,157,110, 62,233, 32,214, 60,204,204,176, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 60,204,204,176, 62,255,252, 24, 61, 22,151, 95, 62,233, 23, 55, 61, 76,204,215, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,129,129, 87,
- 62,233, 23, 57, 61, 76,204,215, 63, 0, 0, 0, 61, 22,151, 95, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 22,151, 95, 62,233, 23, 55,
- 61, 76,205, 68, 62,209,190,135, 61,129,129, 87, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,157,196, 92, 62,210, 92, 49, 61,129,129, 87,
- 62,233, 23, 57, 61, 76,205, 68, 62,209,190,135, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,205, 68, 62,209,190,135, 61, 22,151, 95, 62,233, 23, 55,
- 60,188, 35,151, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 18, 28,237, 62,187,220, 60, 61, 76,205,194, 62,165,199,186, 61,131,191, 7,
- 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,131,191, 7, 62,187,220, 62, 61, 76,205, 68, 62,209,190,135, 61, 18, 28,237, 62,187,220, 60,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 60,188, 35,151, 62,210, 92, 46, 61, 18, 28,237, 62,187,220, 60, 61, 76,205, 68, 62,209,190,135, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61, 76,205, 68, 62,209,190,135, 61,131,191, 7, 62,187,220, 62, 61,157,196, 92, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,129,129, 87,
- 62,233, 23, 57, 61,157,196, 92, 62,210, 92, 49, 61,181,185, 89, 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,181,185, 89, 62,233, 32,214,
- 61,153,153,154, 62,255,252, 25, 61,129,129, 87, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,204,215, 63, 0, 0, 0, 61,129,129, 87,
- 62,233, 23, 57, 61,153,153,154, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,153,153,154, 62,255,252, 25, 61,181,185, 89, 62,233, 32,214,
- 61,204,204,215, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 11,135, 1, 62,198,230,228, 61,253, 31,171, 62,217,196, 6, 61,231,181,251,
- 62,193,135, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,231,181,251, 62,193,135, 38, 62, 1, 36,204, 62,174, 54, 70, 62, 11,135, 1, 62,198,230,228,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,214, 62,180,111,165, 62, 11,135, 1, 62,198,230,228, 62, 1, 36,204, 62,174, 54, 70, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 1, 36,204, 62,174, 54, 70, 61,231,181,251, 62,193,135, 38, 61,207,117, 70, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,181, 68, 35,
- 62,189,208,153, 61,207,117, 70, 62,169,150, 54, 61,231,181,251, 62,193,135, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,231,181,251, 62,193,135, 38,
- 61,205,181,164, 62,213,159,180, 61,181, 68, 35, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,157,196, 92, 62,210, 92, 49, 61,181, 68, 35,
- 62,189,208,153, 61,205,181,164, 62,213,159,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,205,181,164, 62,213,159,180, 61,231,181,251, 62,193,135, 38,
- 61,253, 31,171, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,228,166,251, 62,236,207, 67, 61,204,204,215, 63, 0, 0, 0, 61,181,185, 89,
- 62,233, 32,214, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,181,185, 89, 62,233, 32,214, 61,205,181,164, 62,213,159,180, 61,228,166,251, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,253, 31,171, 62,217,196, 6, 61,228,166,251, 62,236,207, 67, 61,205,181,164, 62,213,159,180, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,205,181,164, 62,213,159,180, 61,181,185, 89, 62,233, 32,214, 61,157,196, 92, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,181, 68, 35,
- 62,189,208,153, 61,157,196, 92, 62,210, 92, 49, 61,131,191, 7, 62,187,220, 62, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,131,191, 7, 62,187,220, 62,
- 61,155, 92, 79, 62,166,190, 91, 61,181, 68, 35, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,207,117, 70, 62,169,150, 54, 61,181, 68, 35,
- 62,189,208,153, 61,155, 92, 79, 62,166,190, 91, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,155, 92, 79, 62,166,190, 91, 61,131,191, 7, 62,187,220, 62,
- 61, 76,205,194, 62,165,199,186, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,180,242,172, 63, 9,152, 96, 61,156,122, 1, 63, 19, 29,254, 61,129, 10,100,
- 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,129, 10,100, 63, 9,150,113, 61,153,153,154, 62,255,252, 25, 61,180,242,172, 63, 9,152, 96,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,204,204,215, 63, 0, 0, 0, 61,180,242,172, 63, 9,152, 96, 61,153,153,154, 62,255,252, 25, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,153,153,154, 62,255,252, 25, 61,129, 10,100, 63, 9,150,113, 61, 76,204,215, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 23,132,109,
- 63, 9,150,113, 61, 76,204,215, 63, 0, 0, 0, 61,129, 10,100, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,129, 10,100, 63, 9,150,113,
- 61, 76,204, 91, 63, 19, 98,220, 61, 23,132,109, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,193, 73,174, 63, 19, 29,253, 61, 23,132,109,
- 63, 9,150,113, 61, 76,204, 91, 63, 19, 98,220, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,204, 91, 63, 19, 98,220, 61,129, 10,100, 63, 9,150,113,
- 61,156,122, 1, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,130,139,166, 63, 28,140,145, 61, 76,203,246, 63, 37,200, 48, 61, 20,129, 13,
- 63, 28,140,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61, 20,129, 13, 63, 28,140,143, 61, 76,204, 91, 63, 19, 98,220, 61,130,139,166, 63, 28,140,145,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,156,122, 1, 63, 19, 29,254, 61,130,139,166, 63, 28,140,145, 61, 76,204, 91, 63, 19, 98,220, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61, 76,204, 91, 63, 19, 98,220, 61, 20,129, 13, 63, 28,140,143, 60,193, 73,174, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 23,132,109,
- 63, 9,150,113, 60,193, 73,174, 63, 19, 29,253, 60, 62,207,114, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60, 62,207,114, 63, 9,152, 94,
- 60,204,204,176, 62,255,252, 24, 61, 23,132,109, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,204,215, 63, 0, 0, 0, 61, 23,132,109,
- 63, 9,150,113, 60,204,204,176, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,204,204,176, 62,255,252, 24, 60, 62,207,114, 63, 9,152, 94,
- 38, 11, 79,167, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,113, 83,237, 62,187,220, 79, 62,100, 81, 63, 62,210, 92, 60, 62, 88,145,110,
- 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 88,145,110, 62,189,208,167, 62,101,133, 91, 62,166,190,112, 62,113, 83,237, 62,187,220, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 62,165,199,206, 62,113, 83,237, 62,187,220, 79, 62,101,133, 91, 62,166,190,112, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,101,133, 91, 62,166,190,112, 62, 88,145,110, 62,189,208,167, 62, 75,120,239, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 88,144,
- 62,193,135, 46, 62, 75,120,239, 62,169,150, 70, 62, 88,145,110, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 88,145,110, 62,189,208,167,
- 62, 76, 88,170, 62,213,159,187, 62, 63, 88,144, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 52,163,179, 62,217,196, 7, 62, 63, 88,144,
- 62,193,135, 46, 62, 76, 88,170, 62,213,159,187, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 76, 88,170, 62,213,159,187, 62, 88,145,110, 62,189,208,167,
- 62,100, 81, 63, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 88, 86,190, 62,233, 32,221, 62, 76,204,254, 63, 0, 0, 0, 62, 64,223,251,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 64,223,251, 62,236,207, 67, 62, 76, 88,170, 62,213,159,187, 62, 88, 86,190, 62,233, 32,221,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,100, 81, 63, 62,210, 92, 60, 62, 88, 86,190, 62,233, 32,221, 62, 76, 88,170, 62,213,159,187, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 76, 88,170, 62,213,159,187, 62, 64,223,251, 62,236,207, 67, 62, 52,163,179, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 88,144,
- 62,193,135, 46, 62, 52,163,179, 62,217,196, 7, 62, 39,172,153, 62,198,230,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 39,172,153, 62,198,230,230,
- 62, 50, 14,213, 62,174, 54, 78, 62, 63, 88,144, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 75,120,239, 62,169,150, 70, 62, 63, 88,144,
- 62,193,135, 46, 62, 50, 14,213, 62,174, 54, 78, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 50, 14,213, 62,174, 54, 78, 62, 39,172,153, 62,198,230,230,
- 62, 25,153,214, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 88, 86,190, 62,233, 32,221, 62,100, 81, 63, 62,210, 92, 60, 62,114,114,166,
- 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,114,114,166, 62,233, 23, 63, 62,102,102,126, 62,255,252, 25, 62, 88, 86,190, 62,233, 32,221,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 76,204,254, 63, 0, 0, 0, 62, 88, 86,190, 62,233, 32,221, 62,102,102,126, 62,255,252, 25, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,102,102,126, 62,255,252, 25, 62,114,114,166, 62,233, 23, 63, 62,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,134,198,173,
- 62,233, 23, 63, 62,128, 0, 0, 63, 0, 0, 0, 62,114,114,166, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,114,114,166, 62,233, 23, 63,
- 62,128, 0, 0, 62,209,190,149, 62,134,198,173, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141,215, 97, 62,210, 92, 60, 62,134,198,173,
- 62,233, 23, 63, 62,128, 0, 0, 62,209,190,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 62,209,190,149, 62,114,114,166, 62,233, 23, 63,
- 62,100, 81, 63, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,113, 83,237, 62,187,220, 79, 62,128, 0, 0, 62,165,199,206, 62,135, 86, 9,
- 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,135, 86, 9, 62,187,220, 79, 62,128, 0, 0, 62,209,190,149, 62,113, 83,237, 62,187,220, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,100, 81, 63, 62,210, 92, 60, 62,113, 83,237, 62,187,220, 79, 62,128, 0, 0, 62,209,190,149, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,128, 0, 0, 62,209,190,149, 62,135, 86, 9, 62,187,220, 79, 62,141,215, 97, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,134,198,173,
- 62,233, 23, 63, 62,141,215, 97, 62,210, 92, 60, 62,147,212,161, 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147,212,161, 62,233, 32,221,
- 62,140,204,193, 62,255,252, 25, 62,134,198,173, 62,233, 23, 63, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 0, 0, 0, 62,134,198,173,
- 62,233, 23, 63, 62,140,204,193, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,140,204,193, 62,255,252, 25, 62,147,212,161, 62,233, 32,221,
- 62,153,153,129, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,172, 41,180, 62,198,230,227, 62,165,174, 39, 62,217,196, 7, 62,160, 83,184,
- 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,160, 83,184, 62,193,135, 46, 62,166,248,150, 62,174, 54, 78, 62,172, 41,180, 62,198,230,227,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 21, 62,180,111,165, 62,172, 41,180, 62,198,230,227, 62,166,248,150, 62,174, 54, 78, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,166,248,150, 62,174, 54, 78, 62,160, 83,184, 62,193,135, 46, 62,154, 67,137, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147,183, 73,
- 62,189,208,167, 62,154, 67,137, 62,169,150, 70, 62,160, 83,184, 62,193,135, 46, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,160, 83,184, 62,193,135, 46,
- 62,153,211,171, 62,213,159,187, 62,147,183, 73, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141,215, 97, 62,210, 92, 60, 62,147,183, 73,
- 62,189,208,167, 62,153,211,171, 62,213,159,187, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,153,211,171, 62,213,159,187, 62,160, 83,184, 62,193,135, 46,
- 62,165,174, 39, 62,217,196, 7, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,159,144, 3, 62,236,207, 67, 62,153,153,129, 63, 0, 0, 0, 62,147,212,161,
- 62,233, 32,221, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,147,212,161, 62,233, 32,221, 62,153,211,171, 62,213,159,187, 62,159,144, 3, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,165,174, 39, 62,217,196, 7, 62,159,144, 3, 62,236,207, 67, 62,153,211,171, 62,213,159,187, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,153,211,171, 62,213,159,187, 62,147,212,161, 62,233, 32,221, 62,141,215, 97, 62,210, 92, 60, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147,183, 73,
- 62,189,208,167, 62,141,215, 97, 62,210, 92, 60, 62,135, 86, 9, 62,187,220, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,135, 86, 9, 62,187,220, 79,
- 62,141, 61, 82, 62,166,190,112, 62,147,183, 73, 62,189,208,167, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,154, 67,137, 62,169,150, 70, 62,147,183, 73,
- 62,189,208,167, 62,141, 61, 82, 62,166,190,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141, 61, 82, 62,166,190,112, 62,135, 86, 9, 62,187,220, 79,
- 62,128, 0, 0, 62,165,199,206, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147,163, 1, 63, 9,152, 91, 62,141,132,224, 63, 19, 29,246, 62,134,168,251,
- 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,134,168,251, 63, 9,150,107, 62,140,204,193, 62,255,252, 25, 62,147,163, 1, 63, 9,152, 91,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,153,153,129, 63, 0, 0, 0, 62,147,163, 1, 63, 9,152, 91, 62,140,204,193, 62,255,252, 25, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,140,204,193, 62,255,252, 25, 62,134,168,251, 63, 9,150,107, 62,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,114,174, 11,
- 63, 9,150,107, 62,128, 0, 0, 63, 0, 0, 0, 62,134,168,251, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,134,168,251, 63, 9,150,107,
- 62,128, 0, 0, 63, 19, 98,209, 62,114,174, 11, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,100,246, 64, 63, 19, 29,246, 62,114,174, 11,
- 63, 9,150,107, 62,128, 0, 0, 63, 19, 98,209, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 19, 98,209, 62,134,168,251, 63, 9,150,107,
- 62,141,132,224, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,135, 9, 86, 63, 28,140,130, 62,128, 0, 0, 63, 37,200, 23, 62,113,237, 83,
- 63, 28,140,130, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,113,237, 83, 63, 28,140,130, 62,128, 0, 0, 63, 19, 98,209, 62,135, 9, 86, 63, 28,140,130,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,141,132,224, 63, 19, 29,246, 62,135, 9, 86, 63, 28,140,130, 62,128, 0, 0, 63, 19, 98,209, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,128, 0, 0, 63, 19, 98,209, 62,113,237, 83, 63, 28,140,130, 62,100,246, 64, 63, 19, 29,246, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,114,174, 11,
- 63, 9,150,107, 62,100,246, 64, 63, 19, 29,246, 62, 88,185,255, 63, 9,152, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 88,185,255, 63, 9,152, 90,
- 62,102,102,126, 62,255,252, 25, 62,114,174, 11, 63, 9,150,107, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 63, 0, 0, 0, 62,114,174, 11,
- 63, 9,150,107, 62,102,102,126, 62,255,252, 25, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,102,102,126, 62,255,252, 25, 62, 88,185,255, 63, 9,152, 90,
- 62, 76,204,254, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223, 16, 63, 62,187,220, 62, 62,216,142,233, 62,210, 92, 49, 62,210,174,248,
- 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,210,174,248, 62,189,208,153, 62,217, 40,237, 62,166,190, 91, 62,223, 16, 63, 62,187,220, 62,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102, 72, 62,165,199,183, 62,223, 16, 63, 62,187,220, 62, 62,217, 40,237, 62,166,190, 91, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,217, 40,237, 62,166,190, 91, 62,210,174,248, 62,189,208,153, 62,204, 34,175, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198, 18,129,
- 62,193,135, 37, 62,204, 34,175, 62,169,150, 54, 62,210,174,248, 62,189,208,153, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,210,174,248, 62,189,208,153,
- 62,204,146,151, 62,213,159,180, 62,198, 18,129, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,192,184, 21, 62,217,196, 6, 62,198, 18,129,
- 62,193,135, 37, 62,204,146,151, 62,213,159,180, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,204,146,151, 62,213,159,180, 62,210,174,248, 62,189,208,153,
- 62,216,142,233, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,210,145,170, 62,233, 32,214, 62,204,204,202, 63, 0, 0, 0, 62,198,214, 65,
- 62,236,207, 67, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,198,214, 65, 62,236,207, 67, 62,204,146,151, 62,213,159,180, 62,210,145,170, 62,233, 32,214,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,216,142,233, 62,210, 92, 49, 62,210,145,170, 62,233, 32,214, 62,204,146,151, 62,213,159,180, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,204,146,151, 62,213,159,180, 62,198,214, 65, 62,236,207, 67, 62,192,184, 21, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,198, 18,129,
- 62,193,135, 37, 62,192,184, 21, 62,217,196, 6, 62,186, 60,127, 62,198,230,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,186, 60,127, 62,198,230,225,
- 62,191,109,154, 62,174, 54, 68, 62,198, 18,129, 62,193,135, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,204, 34,175, 62,169,150, 54, 62,198, 18,129,
- 62,193,135, 37, 62,191,109,154, 62,174, 54, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,191,109,154, 62,174, 54, 68, 62,186, 60,127, 62,198,230,225,
- 62,179, 51, 21, 62,180,111,165, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,210,145,170, 62,233, 32,214, 62,216,142,233, 62,210, 92, 49, 62,223,159,171,
- 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,223,159,171, 62,233, 23, 57, 62,217,153,154, 62,255,252, 24, 62,210,145,170, 62,233, 32,214,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,204,204,202, 63, 0, 0, 0, 62,210,145,170, 62,233, 32,214, 62,217,153,154, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,217,153,154, 62,255,252, 24, 62,223,159,171, 62,233, 23, 57, 62,230,102,101, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,237, 45, 20,
- 62,233, 23, 55, 62,230,102,101, 63, 0, 0, 0, 62,223,159,171, 62,233, 23, 57, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223,159,171, 62,233, 23, 57,
- 62,230,102, 88, 62,209,190,135, 62,237, 45, 20, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,244, 61,199, 62,210, 92, 46, 62,237, 45, 20,
- 62,233, 23, 55, 62,230,102, 88, 62,209,190,135, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 88, 62,209,190,135, 62,223,159,171, 62,233, 23, 57,
- 62,216,142,233, 62,210, 92, 49, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223, 16, 63, 62,187,220, 62, 62,230,102, 72, 62,165,199,183, 62,237,188, 99,
- 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,237,188, 99, 62,187,220, 60, 62,230,102, 88, 62,209,190,135, 62,223, 16, 63, 62,187,220, 62,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,216,142,233, 62,210, 92, 49, 62,223, 16, 63, 62,187,220, 62, 62,230,102, 88, 62,209,190,135, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,230,102, 88, 62,209,190,135, 62,237,188, 99, 62,187,220, 60, 62,244, 61,199, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,237, 45, 20,
- 62,233, 23, 55, 62,244, 61,199, 62,210, 92, 46, 62,250, 59, 21, 62,233, 32,213, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 59, 21, 62,233, 32,213,
- 62,243, 51, 53, 62,255,252, 24, 62,237, 45, 20, 62,233, 23, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,101, 63, 0, 0, 0, 62,237, 45, 20,
- 62,233, 23, 55, 62,243, 51, 53, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243, 51, 53, 62,255,252, 24, 62,250, 59, 21, 62,233, 32,213,
- 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 9, 72, 17, 62,198,230,227, 63, 6, 10, 77, 62,217,196, 6, 63, 3, 93, 15,
- 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 3, 93, 15, 62,193,135, 36, 63, 6,175,123, 62,174, 54, 65, 63, 9, 72, 17, 62,198,230,227,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,191, 62,180,111,160, 63, 9, 72, 17, 62,198,230,227, 63, 6,175,123, 62,174, 54, 65, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 6,175,123, 62,174, 54, 65, 63, 3, 93, 15, 62,193,135, 36, 63, 0, 84,241, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 29,169,
- 62,189,208,150, 63, 0, 84,241, 62,169,150, 52, 63, 3, 93, 15, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 3, 93, 15, 62,193,135, 36,
- 63, 0, 29, 12, 62,213,159,179, 62,250, 29,169, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,244, 61,199, 62,210, 92, 46, 62,250, 29,169,
- 62,189,208,150, 63, 0, 29, 12, 62,213,159,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 29, 12, 62,213,159,179, 63, 3, 93, 15, 62,193,135, 36,
- 63, 6, 10, 77, 62,217,196, 6, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 2,251, 62, 62,236,207, 67, 63, 0, 0, 0, 63, 0, 0, 0, 62,250, 59, 21,
- 62,233, 32,213, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 59, 21, 62,233, 32,213, 63, 0, 29, 12, 62,213,159,179, 63, 2,251, 62, 62,236,207, 67,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 6, 10, 77, 62,217,196, 6, 63, 2,251, 62, 62,236,207, 67, 63, 0, 29, 12, 62,213,159,179, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 29, 12, 62,213,159,179, 62,250, 59, 21, 62,233, 32,213, 62,244, 61,199, 62,210, 92, 46, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 29,169,
- 62,189,208,150, 62,244, 61,199, 62,210, 92, 46, 62,237,188, 99, 62,187,220, 60, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,237,188, 99, 62,187,220, 60,
- 62,243,163,164, 62,166,190, 89, 62,250, 29,169, 62,189,208,150, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 84,241, 62,169,150, 52, 62,250, 29,169,
- 62,189,208,150, 62,243,163,164, 62,166,190, 89, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243,163,164, 62,166,190, 89, 62,237,188, 99, 62,187,220, 60,
- 62,230,102, 72, 62,165,199,183, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,250, 9,132, 63, 9,152, 94, 62,243,235,101, 63, 19, 29,252, 62,237, 15,114,
- 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,237, 15,114, 63, 9,150,113, 62,243, 51, 53, 62,255,252, 24, 62,250, 9,132, 63, 9,152, 94,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 62,250, 9,132, 63, 9,152, 94, 62,243, 51, 53, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,243, 51, 53, 62,255,252, 24, 62,237, 15,114, 63, 9,150,113, 62,230,102,101, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223,189,103,
- 63, 9,150,112, 62,230,102,101, 63, 0, 0, 0, 62,237, 15,114, 63, 9,150,113, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,237, 15,114, 63, 9,150,113,
- 62,230,102,117, 63, 19, 98,220, 62,223,189,103, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,216,225,128, 63, 19, 29,254, 62,223,189,103,
- 63, 9,150,112, 62,230,102,117, 63, 19, 98,220, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,117, 63, 19, 98,220, 62,237, 15,114, 63, 9,150,113,
- 62,243,235,101, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,237,111,222, 63, 28,140,143, 62,230,102,129, 63, 37,200, 48, 62,223, 93, 22,
- 63, 28,140,145, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,223, 93, 22, 63, 28,140,145, 62,230,102,117, 63, 19, 98,220, 62,237,111,222, 63, 28,140,143,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,243,235,101, 63, 19, 29,252, 62,237,111,222, 63, 28,140,143, 62,230,102,117, 63, 19, 98,220, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,230,102,117, 63, 19, 98,220, 62,223, 93, 22, 63, 28,140,145, 62,216,225,128, 63, 19, 29,254, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,223,189,103,
- 63, 9,150,112, 62,216,225,128, 63, 19, 29,254, 62,210,195, 85, 63, 9,152, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,210,195, 85, 63, 9,152, 96,
- 62,217,153,154, 62,255,252, 24, 62,223,189,103, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102,101, 63, 0, 0, 0, 62,223,189,103,
- 63, 9,150,112, 62,217,153,154, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,217,153,154, 62,255,252, 24, 62,210,195, 85, 63, 9,152, 96,
- 62,204,204,202, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 34,187, 97, 62,187,220, 72, 63, 31,122,178, 62,210, 92, 55, 63, 28,138,186,
- 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,138,186, 62,189,208,155, 63, 31,199,185, 62,166,190, 96, 63, 34,187, 97, 62,187,220, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,107, 62,165,199,201, 63, 34,187, 97, 62,187,220, 72, 63, 31,199,185, 62,166,190, 96, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 31,199,185, 62,166,190, 96, 63, 28,138,186, 62,189,208,155, 63, 25, 68,150, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22, 60,123,
- 62,193,135, 36, 63, 25, 68,150, 62,169,150, 54, 63, 28,138,186, 62,189,208,155, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,138,186, 62,189,208,155,
- 63, 25,124,133, 62,213,159,181, 63, 22, 60,123, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,143, 64, 62,217,196, 4, 63, 22, 60,123,
- 62,193,135, 36, 63, 25,124,133, 62,213,159,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25,124,133, 62,213,159,181, 63, 28,138,186, 62,189,208,155,
- 63, 31,122,178, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,124, 14, 62,233, 32,218, 63, 25,153,155, 63, 0, 0, 0, 63, 22,158, 86,
- 62,236,207, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 22,158, 86, 62,236,207, 65, 63, 25,124,133, 62,213,159,181, 63, 28,124, 14, 62,233, 32,218,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 31,122,178, 62,210, 92, 55, 63, 28,124, 14, 62,233, 32,218, 63, 25,124,133, 62,213,159,181, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 25,124,133, 62,213,159,181, 63, 22,158, 86, 62,236,207, 65, 63, 19,143, 64, 62,217,196, 4, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 22, 60,123,
- 62,193,135, 36, 63, 19,143, 64, 62,217,196, 4, 63, 16, 81,117, 62,198,230,223, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 16, 81,117, 62,198,230,223,
- 63, 18,234, 7, 62,174, 54, 65, 63, 22, 60,123, 62,193,135, 36, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 25, 68,150, 62,169,150, 54, 63, 22, 60,123,
- 62,193,135, 36, 63, 18,234, 7, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 18,234, 7, 62,174, 54, 65, 63, 16, 81,117, 62,198,230,223,
- 63, 12,204,191, 62,180,111,160, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,124, 14, 62,233, 32,218, 63, 31,122,178, 62,210, 92, 55, 63, 35, 3, 17,
- 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 35, 3, 17, 62,233, 23, 58, 63, 32, 0, 2, 62,255,252, 24, 63, 28,124, 14, 62,233, 32,218,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 25,153,155, 63, 0, 0, 0, 63, 28,124, 14, 62,233, 32,218, 63, 32, 0, 2, 62,255,252, 24, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 32, 0, 2, 62,255,252, 24, 63, 35, 3, 17, 62,233, 23, 58, 63, 38,102,109, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,201,200,
- 62,233, 23, 58, 63, 38,102,109, 63, 0, 0, 0, 63, 35, 3, 17, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 35, 3, 17, 62,233, 23, 58,
- 63, 38,102,109, 62,209,190,143, 63, 41,201,200, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 82, 38, 62,210, 92, 55, 63, 41,201,200,
- 62,233, 23, 58, 63, 38,102,109, 62,209,190,143, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,109, 62,209,190,143, 63, 35, 3, 17, 62,233, 23, 58,
- 63, 31,122,178, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 34,187, 97, 62,187,220, 72, 63, 38,102,107, 62,165,199,201, 63, 42, 17,118,
- 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 42, 17,118, 62,187,220, 72, 63, 38,102,109, 62,209,190,143, 63, 34,187, 97, 62,187,220, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 31,122,178, 62,210, 92, 55, 63, 34,187, 97, 62,187,220, 72, 63, 38,102,109, 62,209,190,143, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 38,102,109, 62,209,190,143, 63, 42, 17,118, 62,187,220, 72, 63, 45, 82, 38, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,201,200,
- 62,233, 23, 58, 63, 45, 82, 38, 62,210, 92, 55, 63, 48, 80,204, 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 80,204, 62,233, 32,218,
- 63, 44,204,215, 62,255,252, 23, 63, 41,201,200, 62,233, 23, 58, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,109, 63, 0, 0, 0, 63, 41,201,200,
- 62,233, 23, 58, 63, 44,204,215, 62,255,252, 23, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 44,204,215, 62,255,252, 23, 63, 48, 80,204, 62,233, 32,218,
- 63, 51, 51, 63, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 60,123, 85, 62,198,230,253, 63, 57, 61,144, 62,217,196, 19, 63, 54,144, 86,
- 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,144, 86, 62,193,135, 68, 63, 57,226,196, 62,174, 54,114, 63, 60,123, 85, 62,198,230,253,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 62,180,111,211, 63, 60,123, 85, 62,198,230,253, 63, 57,226,196, 62,174, 54,114, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 57,226,196, 62,174, 54,114, 63, 54,144, 86, 62,193,135, 68, 63, 51,136, 58, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 66, 27,
- 62,189,208,173, 63, 51,136, 58, 62,169,150, 90, 63, 54,144, 86, 62,193,135, 68, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,144, 86, 62,193,135, 68,
- 63, 51, 80, 80, 62,213,159,192, 63, 48, 66, 27, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 82, 38, 62,210, 92, 55, 63, 48, 66, 27,
- 62,189,208,173, 63, 51, 80, 80, 62,213,159,192, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 51, 80, 80, 62,213,159,192, 63, 54,144, 86, 62,193,135, 68,
- 63, 57, 61,144, 62,217,196, 19, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 54, 46,128, 62,236,207, 75, 63, 51, 51, 63, 63, 0, 0, 0, 63, 48, 80,204,
- 62,233, 32,218, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 80,204, 62,233, 32,218, 63, 51, 80, 80, 62,213,159,192, 63, 54, 46,128, 62,236,207, 75,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 57, 61,144, 62,217,196, 19, 63, 54, 46,128, 62,236,207, 75, 63, 51, 80, 80, 62,213,159,192, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 51, 80, 80, 62,213,159,192, 63, 48, 80,204, 62,233, 32,218, 63, 45, 82, 38, 62,210, 92, 55, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 66, 27,
- 62,189,208,173, 63, 45, 82, 38, 62,210, 92, 55, 63, 42, 17,118, 62,187,220, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 42, 17,118, 62,187,220, 72,
- 63, 45, 5, 26, 62,166,190,117, 63, 48, 66, 27, 62,189,208,173, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 51,136, 58, 62,169,150, 90, 63, 48, 66, 27,
- 62,189,208,173, 63, 45, 5, 26, 62,166,190,117, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 5, 26, 62,166,190,117, 63, 42, 17,118, 62,187,220, 72,
- 63, 38,102,107, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 55,255, 63, 9,152, 94, 63, 45, 40,237, 63, 19, 29,252, 63, 41,186,242,
- 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,186,242, 63, 9,150,112, 63, 44,204,215, 62,255,252, 23, 63, 48, 55,255, 63, 9,152, 94,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 51, 51, 63, 63, 0, 0, 0, 63, 48, 55,255, 63, 9,152, 94, 63, 44,204,215, 62,255,252, 23, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 44,204,215, 62,255,252, 23, 63, 41,186,242, 63, 9,150,112, 63, 38,102,109, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 35, 17,235,
- 63, 9,150,112, 63, 38,102,109, 63, 0, 0, 0, 63, 41,186,242, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,186,242, 63, 9,150,112,
- 63, 38,102,113, 63, 19, 98,219, 63, 35, 17,235, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 31,163,245, 63, 19, 29,253, 63, 35, 17,235,
- 63, 9,150,112, 63, 38,102,113, 63, 19, 98,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,113, 63, 19, 98,219, 63, 41,186,242, 63, 9,150,112,
- 63, 45, 40,237, 63, 19, 29,252, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 41,235, 38, 63, 28,140,141, 63, 38,102,117, 63, 37,200, 45, 63, 34,225,192,
- 63, 28,140,142, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 34,225,192, 63, 28,140,142, 63, 38,102,113, 63, 19, 98,219, 63, 41,235, 38, 63, 28,140,141,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 45, 40,237, 63, 19, 29,252, 63, 41,235, 38, 63, 28,140,141, 63, 38,102,113, 63, 19, 98,219, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 38,102,113, 63, 19, 98,219, 63, 34,225,192, 63, 28,140,142, 63, 31,163,245, 63, 19, 29,253, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 35, 17,235,
- 63, 9,150,112, 63, 31,163,245, 63, 19, 29,253, 63, 28,148,223, 63, 9,152, 94, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,148,223, 63, 9,152, 94,
- 63, 32, 0, 2, 62,255,252, 24, 63, 35, 17,235, 63, 9,150,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,109, 63, 0, 0, 0, 63, 35, 17,235,
- 63, 9,150,112, 63, 32, 0, 2, 62,255,252, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 32, 0, 2, 62,255,252, 24, 63, 28,148,223, 63, 9,152, 94,
- 63, 25,153,155, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,107,129,188, 62,128, 45, 66, 63, 99, 71,235, 62,120, 76,222, 63,106, 37, 94,
- 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,106, 37, 94, 62, 83, 97, 84, 63,115, 51, 65, 62, 97,151,248, 63,107,129,188, 62,128, 45, 66,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 65, 62,135, 83,151, 63,107,129,188, 62,128, 45, 66, 63,115, 51, 65, 62, 97,151,248, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,115, 51, 65, 62, 97,151,248, 63,106, 37, 94, 62, 83, 97, 84, 63,115, 51, 65, 62, 52,111, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,107,129,188,
- 62,128, 45, 66, 63,115, 51, 65, 62,135, 83,151, 63,108,123,142, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,123,142, 62,151,144,169,
- 63,101, 50,231, 62,146,201, 17, 63,107,129,188, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99, 71,235, 62,120, 76,222, 63,107,129,188,
- 62,128, 45, 66, 63,101, 50,231, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,101, 50,231, 62,146,201, 17, 63,108,123,142, 62,151,144,169,
- 63,102,187,106, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 96, 56, 71, 62,166,190, 99, 63, 89,153,149, 62,165,199,201, 63, 93,238, 22,
- 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 93,238, 22, 62,144,101,243, 63,101, 50,231, 62,146,201, 17, 63, 96, 56, 71, 62,166,190, 99,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,102,187,106, 62,169,150, 54, 63, 96, 56, 71, 62,166,190, 99, 63,101, 50,231, 62,146,201, 17, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,101, 50,231, 62,146,201, 17, 63, 93,238, 22, 62,144,101,243, 63, 99, 71,235, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,109, 21,249,
- 62,174, 54, 65, 63,102,187,106, 62,169,150, 54, 63,108,123,142, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,108,123,142, 62,151,144,169,
- 63,115, 51, 65, 62,157,231, 93, 63,109, 21,249, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62,180,111,160, 63,109, 21,249,
- 62,174, 54, 65, 63,115, 51, 65, 62,157,231, 93, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62,157,231, 93, 63,108,123,142, 62,151,144,169,
- 63,115, 51, 65, 62,135, 83,151, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,149, 62,115,162, 79, 63, 99, 71,235, 62,120, 76,222, 63, 93,238, 22,
- 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 93,238, 22, 62,144,101,243, 63, 85, 69, 21, 62,144,102, 3, 63, 89,153,149, 62,115,162, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 79,235, 68, 62,120, 77, 37, 63, 89,153,149, 62,115,162, 79, 63, 85, 69, 21, 62,144,102, 3, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 85, 69, 21, 62,144,102, 3, 63, 93,238, 22, 62,144,101,243, 63, 89,153,149, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,149,
- 62,115,162, 79, 63, 79,235, 68, 62,120, 77, 37, 63, 83,186, 24, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 83,186, 24, 62, 70,176,245,
- 63, 95,121, 22, 62, 70,176,204, 63, 89,153,149, 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99, 71,235, 62,120, 76,222, 63, 89,153,149,
- 62,115,162, 79, 63, 95,121, 22, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 95,121, 22, 62, 70,176,204, 63, 83,186, 24, 62, 70,176,245,
- 63, 89,153,152, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,103,119, 61, 62, 30,253,179, 63,115, 51, 65, 62, 52,111, 90, 63,106, 37, 94,
- 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,106, 37, 94, 62, 83, 97, 84, 63, 95,121, 22, 62, 70,176,204, 63,103,119, 61, 62, 30,253,179,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,152, 62, 23, 31,198, 63,103,119, 61, 62, 30,253,179, 63, 95,121, 22, 62, 70,176,204, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 95,121, 22, 62, 70,176,204, 63,106, 37, 94, 62, 83, 97, 84, 63, 99, 71,235, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 75,187,248,
- 62, 30,253,241, 63, 89,153,152, 62, 23, 31,198, 63, 83,186, 24, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 83,186, 24, 62, 70,176,245,
- 63, 73, 13,214, 62, 83, 97,181, 63, 75,187,248, 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62, 52,111,202, 63, 75,187,248,
- 62, 30,253,241, 63, 73, 13,214, 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 73, 13,214, 62, 83, 97,181, 63, 83,186, 24, 62, 70,176,245,
- 63, 79,235, 68, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,152, 61,147, 41,111, 63, 64, 0, 0, 61,180,111,195, 63, 64, 0, 0,
- 61, 52, 65,111, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 61, 52, 65,111, 63,117, 49, 38, 61, 52, 64,225, 63, 89,153,152, 61,147, 41,111,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,115, 51, 65, 61,180,111, 83, 63, 89,153,152, 61,147, 41,111, 63,117, 49, 38, 61, 52, 64,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,117, 49, 38, 61, 52, 64,225, 63, 64, 0, 0, 61, 52, 65,111, 63,121,222,208,178,239, 9,102, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,152,
- 61,147, 41,111, 63,115, 51, 65, 61,180,111, 83, 63, 99, 51,172, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99, 51,172, 61,231, 46, 48,
- 63, 79,255,135, 61,231, 46,120, 63, 89,153,152, 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 61,180,111,195, 63, 89,153,152,
- 61,147, 41,111, 63, 79,255,135, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 79,255,135, 61,231, 46,120, 63, 99, 51,172, 61,231, 46, 48,
- 63, 89,153,152, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 75,187,248, 62, 30,253,241, 63, 64, 0, 0, 62, 52,111,202, 63, 64, 0, 0,
- 62, 7, 71, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62, 7, 71, 24, 63, 79,255,135, 61,231, 46,120, 63, 75,187,248, 62, 30,253,241,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 89,153,152, 62, 23, 31,198, 63, 75,187,248, 62, 30,253,241, 63, 79,255,135, 61,231, 46,120, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 79,255,135, 61,231, 46,120, 63, 64, 0, 0, 62, 7, 71, 24, 63, 64, 0, 0, 61,180,111,195, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,103,119, 61,
- 62, 30,253,179, 63, 89,153,152, 62, 23, 31,198, 63, 99, 51,172, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 99, 51,172, 61,231, 46, 48,
- 63,115, 51, 66, 62, 7, 70,199, 63,103,119, 61, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62, 52,111, 90, 63,103,119, 61,
- 62, 30,253,179, 63,115, 51, 66, 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 66, 62, 7, 70,199, 63, 99, 51,172, 61,231, 46, 48,
- 63,115, 51, 65, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 71,177,122, 62,128, 45,120, 63, 64, 0, 0, 62,135, 83,218, 63, 64, 0, 0,
- 62, 97,152,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62, 97,152,115, 63, 73, 13,214, 62, 83, 97,181, 63, 71,177,122, 62,128, 45,120,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 79,235, 68, 62,120, 77, 37, 63, 71,177,122, 62,128, 45,120, 63, 73, 13,214, 62, 83, 97,181, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 73, 13,214, 62, 83, 97,181, 63, 64, 0, 0, 62, 97,152,115, 63, 64, 0, 0, 62, 52,111,202, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 71,177,122,
- 62,128, 45,120, 63, 79,235, 68, 62,120, 77, 37, 63, 78, 0, 72, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 78, 0, 72, 62,146,201, 52,
- 63, 70,183,169, 62,151,144,219, 63, 71,177,122, 62,128, 45,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62,135, 83,218, 63, 71,177,122,
- 62,128, 45,120, 63, 70,183,169, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70,183,169, 62,151,144,219, 63, 78, 0, 72, 62,146,201, 52,
- 63, 76,119,198, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 70, 29, 61, 62,174, 54,114, 63, 64, 0, 0, 62,180,111,211, 63, 64, 0, 0,
- 62,157,231,162, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62,157,231,162, 63, 70,183,169, 62,151,144,219, 63, 70, 29, 61, 62,174, 54,114,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 76,119,198, 62,169,150, 90, 63, 70, 29, 61, 62,174, 54,114, 63, 70,183,169, 62,151,144,219, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 70,183,169, 62,151,144,219, 63, 64, 0, 0, 62,157,231,162, 63, 64, 0, 0, 62,135, 83,218, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 82,250,230,
- 62,166,190,117, 63, 76,119,198, 62,169,150, 90, 63, 78, 0, 72, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 78, 0, 72, 62,146,201, 52,
- 63, 85, 69, 21, 62,144,102, 3, 63, 82,250,230, 62,166,190,117, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 89,153,149, 62,165,199,201, 63, 82,250,230,
- 62,166,190,117, 63, 85, 69, 21, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 85, 69, 21, 62,144,102, 3, 63, 78, 0, 72, 62,146,201, 52,
- 63, 79,235, 68, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,245,167,179, 62,128, 45, 72, 61,179,217, 94, 62,120, 76,222, 61,234,196,202,
- 62, 83, 97,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,234,196,202, 62, 83, 97,100, 62, 25,153,212, 62, 97,152, 2, 61,245,167,179, 62,128, 45, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,214, 62,135, 83,156, 61,245,167,179, 62,128, 45, 72, 62, 25,153,212, 62, 97,152, 2, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 25,153,212, 62, 97,152, 2, 61,234,196,202, 62, 83, 97,100, 62, 25,153,214, 62, 52,111,106, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,245,167,179,
- 62,128, 45, 72, 62, 25,153,214, 62,135, 83,156, 61,253,118, 62, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,253,118, 62, 62,151,144,174,
- 61,195, 49, 53, 62,146,201, 17, 61,245,167,179, 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,179,217, 94, 62,120, 76,222, 61,245,167,179,
- 62,128, 45, 72, 61,195, 49, 53, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,195, 49, 53, 62,146,201, 17, 61,253,118, 62, 62,151,144,174,
- 61,207,117, 70, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,155, 92, 79, 62,166,190, 91, 61, 76,205,194, 62,165,199,186, 61,137, 10,212,
- 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,137, 10,212, 62,144,101,238, 61,195, 49, 53, 62,146,201, 17, 61,155, 92, 79, 62,166,190, 91,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61,207,117, 70, 62,169,150, 54, 61,155, 92, 79, 62,166,190, 91, 61,195, 49, 53, 62,146,201, 17, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,195, 49, 53, 62,146,201, 17, 61,137, 10,212, 62,144,101,238, 61,179,217, 94, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 1, 36,204,
- 62,174, 54, 70, 61,207,117, 70, 62,169,150, 54, 61,253,118, 62, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,253,118, 62, 62,151,144,174,
- 62, 25,153,213, 62,157,231,100, 62, 1, 36,204, 62,174, 54, 70, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,214, 62,180,111,165, 62, 1, 36,204,
- 62,174, 54, 70, 62, 25,153,213, 62,157,231,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,213, 62,157,231,100, 61,253,118, 62, 62,151,144,174,
- 62, 25,153,214, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,205,188, 62,115,162, 53, 61,179,217, 94, 62,120, 76,222, 61,137, 10,212,
- 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,137, 10,212, 62,144,101,238, 61, 7,133,207, 62,144,101,236, 61, 76,205,188, 62,115,162, 53,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 60, 71,162,255, 62,120, 76,216, 61, 76,205,188, 62,115,162, 53, 61, 7,133,207, 62,144,101,236, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61, 7,133,207, 62,144,101,236, 61,137, 10,212, 62,144,101,238, 61, 76,205,194, 62,165,199,186, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,205,188,
- 62,115,162, 53, 60, 71,162,255, 62,120, 76,216, 60,221,171,190, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,221,171,190, 62, 70,176,194,
- 61,149, 98,194, 62, 70,176,194, 61, 76,205,188, 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,179,217, 94, 62,120, 76,222, 61, 76,205,188,
- 62,115,162, 53, 61,149, 98,194, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,149, 98,194, 62, 70,176,194, 60,221,171,190, 62, 70,176,194,
- 61, 76,205,193, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,213, 83,198, 62, 30,253,179, 62, 25,153,214, 62, 52,111,106, 61,234,196,202,
- 62, 83, 97,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 61,234,196,202, 62, 83, 97,100, 61,149, 98,194, 62, 70,176,194, 61,213, 83,198, 62, 30,253,179,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 61, 76,205,193, 62, 23, 31,168, 61,213, 83,198, 62, 30,253,179, 61,149, 98,194, 62, 70,176,194, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 61,149, 98,194, 62, 70,176,194, 61,234,196,202, 62, 83, 97,100, 61,179,217, 94, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,126,239, 59,
- 62, 30,253,174, 63,131,105,154, 62, 23, 31,168, 63,131,118,175, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131,118,175, 62, 70,176,194,
- 63,124, 65, 30, 62, 83, 97, 90, 63,126,239, 59, 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62, 52,111, 90, 63,126,239, 59,
- 62, 30,253,174, 63,124, 65, 30, 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,124, 65, 30, 62, 83, 97, 90, 63,131,118,175, 62, 70,176,194,
- 63,129,143, 70, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131,105,156, 61,147, 41,101, 63,115, 51, 65, 61,180,111, 83, 63,117, 49, 38,
- 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,117, 49, 38, 61, 52, 64,225, 63,135,148,232, 60,125,158,144, 63,131,105,156, 61,147, 41,101,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 25,153,215, 61,180,111,104, 61,128,245,122, 61,147, 41,101, 62, 25,153,224, 61, 52, 64,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,135,148,232, 60,125,158,144, 63,117, 49, 38, 61, 52, 64,225, 63,121,222,208,178,239, 9,102, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,128,245,122,
- 61,147, 41,101, 62, 25,153,215, 61,180,111,104, 61,179, 55, 89, 61,231, 46, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,179, 55, 89, 61,231, 46, 38,
- 60,208,147, 96, 61,231, 46, 48, 61,128,245,122, 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 61,180,111, 83, 63,131,105,156,
- 61,147, 41,101, 63,129,153,102, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 60,208,147, 96, 61,231, 46, 48, 61,179, 55, 89, 61,231, 46, 38,
- 61, 76,205,193, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,126,239, 59, 62, 30,253,174, 63,115, 51, 65, 62, 52,111, 90, 63,115, 51, 66,
- 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 66, 62, 7, 70,199, 63,129,153,102, 61,231, 46, 48, 63,126,239, 59, 62, 30,253,174,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,131,105,154, 62, 23, 31,168, 63,126,239, 59, 62, 30,253,174, 63,129,153,102, 61,231, 46, 48, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,129,153,102, 61,231, 46, 48, 63,115, 51, 66, 62, 7, 70,199, 63,115, 51, 65, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,213, 83,198,
- 62, 30,253,179, 61, 76,205,193, 62, 23, 31,168, 61,179, 55, 89, 61,231, 46, 38, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61,179, 55, 89, 61,231, 46, 38,
- 62, 25,153,217, 62, 7, 70,204, 61,213, 83,198, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,214, 62, 52,111,106, 61,213, 83,198,
- 62, 30,253,179, 62, 25,153,217, 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,217, 62, 7, 70,204, 61,179, 55, 89, 61,231, 46, 38,
- 62, 25,153,215, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,122,228,192, 62,128, 45, 66, 63,115, 51, 65, 62,135, 83,151, 63,115, 51, 65,
- 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62, 97,151,248, 63,124, 65, 30, 62, 83, 97, 90, 63,122,228,192, 62,128, 45, 66,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,129,143, 70, 62,120, 76,216, 63,122,228,192, 62,128, 45, 66, 63,124, 65, 30, 62, 83, 97, 90, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,124, 65, 30, 62, 83, 97, 90, 63,115, 51, 65, 62, 97,151,248, 63,115, 51, 65, 62, 52,111, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,122,228,192,
- 62,128, 45, 66, 63,129,143, 70, 62,120, 76,216, 63,128,153,201, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128,153,201, 62,146,201, 14,
- 63,121,234,239, 62,151,144,169, 63,122,228,192, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62,135, 83,151, 63,122,228,192,
- 62,128, 45, 66, 63,121,234,239, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121,234,239, 62,151,144,169, 63,128,153,201, 62,146,201, 14,
- 63,127,171, 15, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,121, 80,133, 62,174, 54, 65, 63,115, 51, 65, 62,180,111,160, 63,115, 51, 65,
- 62,157,231, 93, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,115, 51, 65, 62,157,231, 93, 63,121,234,239, 62,151,144,169, 63,121, 80,133, 62,174, 54, 65,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,127,171, 15, 62,169,150, 52, 63,121, 80,133, 62,174, 54, 65, 63,121,234,239, 62,151,144,169, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,121,234,239, 62,151,144,169, 63,115, 51, 65, 62,157,231, 93, 63,115, 51, 65, 62,135, 83,151, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,131, 23, 23,
- 62,166,190, 89, 63,127,171, 15, 62,169,150, 52, 63,128,153,201, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 59,153,200,136, 62,146,201, 14,
- 61, 7,133,207, 62,144,101,236, 60,197,197,195, 62,166,190, 89, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 76,205,194, 62,165,199,186, 60,197,197,195,
- 62,166,190, 89, 61, 7,133,207, 62,144,101,236, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 61, 7,133,207, 62,144,101,236, 59,153,200,136, 62,146,201, 14,
- 60, 71,162,255, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,163,208, 32, 62,128, 45, 79, 62,147, 92,147, 62,120, 76,252, 62,161, 23,102,
- 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,161, 23,102, 62, 83, 97,115, 62,179, 51, 22, 62, 97,152, 2, 62,163,208, 32, 62,128, 45, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 21, 62,135, 83,156, 62,163,208, 32, 62,128, 45, 79, 62,179, 51, 22, 62, 97,152, 2, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,179, 51, 22, 62, 97,152, 2, 62,161, 23,102, 62, 83, 97,115, 62,179, 51, 21, 62, 52,111,101, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,163,208, 32,
- 62,128, 45, 79, 62,179, 51, 21, 62,135, 83,156, 62,165,195,194, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,165,195,194, 62,151,144,181,
- 62,151, 50,134, 62,146,201, 29, 62,163,208, 32, 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147, 92,147, 62,120, 76,252, 62,163,208, 32,
- 62,128, 45, 79, 62,151, 50,134, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,151, 50,134, 62,146,201, 29, 62,165,195,194, 62,151,144,181,
- 62,154, 67,137, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,141, 61, 82, 62,166,190,112, 62,128, 0, 0, 62,165,199,206, 62,136,168,247,
- 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,136,168,247, 62,144,102, 3, 62,151, 50,134, 62,146,201, 29, 62,141, 61, 82, 62,166,190,112,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,154, 67,137, 62,169,150, 70, 62,141, 61, 82, 62,166,190,112, 62,151, 50,134, 62,146,201, 29, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,151, 50,134, 62,146,201, 29, 62,136,168,247, 62,144,102, 3, 62,147, 92,147, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,166,248,150,
- 62,174, 54, 78, 62,154, 67,137, 62,169,150, 70, 62,165,195,194, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,165,195,194, 62,151,144,181,
- 62,179, 51, 21, 62,157,231, 98, 62,166,248,150, 62,174, 54, 78, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62,180,111,165, 62,166,248,150,
- 62,174, 54, 78, 62,179, 51, 21, 62,157,231, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62,157,231, 98, 62,165,195,194, 62,151,144,181,
- 62,179, 51, 21, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 62,115,162, 89, 62,147, 92,147, 62,120, 76,252, 62,136,168,247,
- 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,136,168,247, 62,144,102, 3, 62,110,174, 18, 62,144,102, 3, 62,128, 0, 0, 62,115,162, 89,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 89, 70,217, 62,120, 76,252, 62,128, 0, 0, 62,115,162, 89, 62,110,174, 18, 62,144,102, 3, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,110,174, 18, 62,144,102, 3, 62,136,168,247, 62,144,102, 3, 62,128, 0, 0, 62,165,199,206, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0,
- 62,115,162, 89, 62, 89, 70,217, 62,120, 76,252, 62,104,130, 30, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,104,130, 30, 62, 70,176,230,
- 62,139,190,241, 62, 70,176,230, 62,128, 0, 0, 62,115,162, 89, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147, 92,147, 62,120, 76,252, 62,128, 0, 0,
- 62,115,162, 89, 62,139,190,241, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,139,190,241, 62, 70,176,230, 62,104,130, 30, 62, 70,176,230,
- 62,128, 0, 0, 62, 23, 31,208, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,155,187, 41, 62, 30,253,205, 62,179, 51, 21, 62, 52,111,101, 62,161, 23,102,
- 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,161, 23,102, 62, 83, 97,115, 62,139,190,241, 62, 70,176,230, 62,155,187, 41, 62, 30,253,205,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 62, 23, 31,208, 62,155,187, 41, 62, 30,253,205, 62,139,190,241, 62, 70,176,230, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,139,190,241, 62, 70,176,230, 62,161, 23,102, 62, 83, 97,115, 62,147, 92,147, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 72,137,174,
- 62, 30,253,205, 62,128, 0, 0, 62, 23, 31,208, 62,104,130, 30, 62, 70,176,230, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,104,130, 30, 62, 70,176,230,
- 62, 61,209, 51, 62, 83, 97,115, 62, 72,137,174, 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,214, 62, 52,111,106, 62, 72,137,174,
- 62, 30,253,205, 62, 61,209, 51, 62, 83, 97,115, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 61,209, 51, 62, 83, 97,115, 62,104,130, 30, 62, 70,176,230,
- 62, 89, 70,217, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,127,255,255, 61,147, 41,141, 62, 25,153,215, 61,180,111,104, 62, 25,153,224,
- 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,224, 61, 52, 64,225, 62,179, 51, 15, 61, 52, 64,225, 62,127,255,255, 61,147, 41,141,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,179, 51, 20, 61,180,111,104, 62,127,255,255, 61,147, 41,141, 62,179, 51, 15, 61, 52, 64,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,179, 51, 15, 61, 52, 64,225, 62, 25,153,224, 61, 52, 64,225, 62,161,175,144,178,239, 9,102, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,127,255,255,
- 61,147, 41,141, 62,179, 51, 20, 61,180,111,104, 62,147, 52, 12, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147, 52, 12, 61,231, 46,109,
- 62, 89,151,231, 61,231, 46,109, 62,127,255,255, 61,147, 41,141, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,215, 61,180,111,104, 62,127,255,255,
- 61,147, 41,141, 62, 89,151,231, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 89,151,231, 61,231, 46,109, 62,147, 52, 12, 61,231, 46,109,
- 62,128, 0, 0, 62, 23, 31,208, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 72,137,174, 62, 30,253,205, 62, 25,153,214, 62, 52,111,106, 62, 25,153,217,
- 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,217, 62, 7, 70,204, 62, 89,151,231, 61,231, 46,109, 62, 72,137,174, 62, 30,253,205,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,128, 0, 0, 62, 23, 31,208, 62, 72,137,174, 62, 30,253,205, 62, 89,151,231, 61,231, 46,109, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 89,151,231, 61,231, 46,109, 62, 25,153,217, 62, 7, 70,204, 62, 25,153,215, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,155,187, 41,
- 62, 30,253,205, 62,128, 0, 0, 62, 23, 31,208, 62,147, 52, 12, 61,231, 46,109, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,147, 52, 12, 61,231, 46,109,
- 62,179, 51, 19, 62, 7, 70,204, 62,155,187, 41, 62, 30,253,205, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62, 52,111,101, 62,155,187, 41,
- 62, 30,253,205, 62,179, 51, 19, 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 19, 62, 7, 70,204, 62,147, 52, 12, 61,231, 46,109,
- 62,179, 51, 20, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 56, 95,192, 62,128, 45, 79, 62, 25,153,214, 62,135, 83,156, 62, 25,153,212,
- 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,212, 62, 97,152, 2, 62, 61,209, 51, 62, 83, 97,115, 62, 56, 95,192, 62,128, 45, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 89, 70,217, 62,120, 76,252, 62, 56, 95,192, 62,128, 45, 79, 62, 61,209, 51, 62, 83, 97,115, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 61,209, 51, 62, 83, 97,115, 62, 25,153,212, 62, 97,152, 2, 62, 25,153,214, 62, 52,111,106, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 56, 95,192,
- 62,128, 45, 79, 62, 89, 70,217, 62,120, 76,252, 62, 81,154,245, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 81,154,245, 62,146,201, 29,
- 62, 52,120,125, 62,151,144,181, 62, 56, 95,192, 62,128, 45, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,214, 62,135, 83,156, 62, 56, 95,192,
- 62,128, 45, 79, 62, 52,120,125, 62,151,144,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 52,120,125, 62,151,144,181, 62, 81,154,245, 62,146,201, 29,
- 62, 75,120,239, 62,169,150, 70, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 50, 14,213, 62,174, 54, 78, 62, 25,153,214, 62,180,111,165, 62, 25,153,213,
- 62,157,231,100, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62, 25,153,213, 62,157,231,100, 62, 52,120,125, 62,151,144,181, 62, 50, 14,213, 62,174, 54, 78,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62, 75,120,239, 62,169,150, 70, 62, 50, 14,213, 62,174, 54, 78, 62, 52,120,125, 62,151,144,181, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62, 52,120,125, 62,151,144,181, 62, 25,153,213, 62,157,231,100, 62, 25,153,214, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,101,133, 91,
- 62,166,190,112, 62, 75,120,239, 62,169,150, 70, 62, 81,154,245, 62,146,201, 29, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62, 81,154,245, 62,146,201, 29,
- 62,110,174, 18, 62,144,102, 3, 62,101,133, 91, 62,166,190,112, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,128, 0, 0, 62,165,199,206, 62,101,133, 91,
- 62,166,190,112, 62,110,174, 18, 62,144,102, 3, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,110,174, 18, 62,144,102, 3, 62, 81,154,245, 62,146,201, 29,
- 62, 89, 70,217, 62,120, 76,252, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 5, 27, 64, 62,128, 45, 66, 62,249,194,232, 62,120, 76,216, 63, 3,190,226,
- 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 3,190,226, 62, 83, 97, 90, 63, 12,204,191, 62, 97,151,248, 63, 5, 27, 64, 62,128, 45, 66,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,191, 62,135, 83,149, 63, 5, 27, 64, 62,128, 45, 66, 63, 12,204,191, 62, 97,151,248, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 12,204,191, 62, 97,151,248, 63, 3,190,226, 62, 83, 97, 90, 63, 12,204,191, 62, 52,111, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 5, 27, 64,
- 62,128, 45, 66, 63, 12,204,191, 62,135, 83,149, 63, 6, 21, 17, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6, 21, 17, 62,151,144,169,
- 62,253,152,222, 62,146,201, 14, 63, 5, 27, 64, 62,128, 45, 66, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,249,194,232, 62,120, 76,216, 63, 5, 27, 64,
- 62,128, 45, 66, 62,253,152,222, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,253,152,222, 62,146,201, 14, 63, 6, 21, 17, 62,151,144,169,
- 63, 0, 84,241, 62,169,150, 52, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,243,163,164, 62,166,190, 89, 62,230,102, 72, 62,165,199,183, 62,239, 15, 70,
- 62,144,101,233, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,239, 15, 70, 62,144,101,233, 62,253,152,222, 62,146,201, 14, 62,243,163,164, 62,166,190, 89,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 0, 84,241, 62,169,150, 52, 62,243,163,164, 62,166,190, 89, 62,253,152,222, 62,146,201, 14, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,253,152,222, 62,146,201, 14, 62,239, 15, 70, 62,144,101,233, 62,249,194,232, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6,175,123,
- 62,174, 54, 65, 63, 0, 84,241, 62,169,150, 52, 63, 6, 21, 17, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 6, 21, 17, 62,151,144,169,
- 63, 12,204,191, 62,157,231, 90, 63, 6,175,123, 62,174, 54, 65, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62,180,111,160, 63, 6,175,123,
- 62,174, 54, 65, 63, 12,204,191, 62,157,231, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62,157,231, 90, 63, 6, 21, 17, 62,151,144,169,
- 63, 12,204,191, 62,135, 83,149, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 72, 62,115,162, 53, 62,249,194,232, 62,120, 76,216, 62,239, 15, 70,
- 62,144,101,233, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,239, 15, 70, 62,144,101,233, 62,221,189, 75, 62,144,101,238, 62,230,102, 72, 62,115,162, 53,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,211, 9,168, 62,120, 76,222, 62,230,102, 72, 62,115,162, 53, 62,221,189, 75, 62,144,101,238, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,221,189, 75, 62,144,101,238, 62,239, 15, 70, 62,144,101,233, 62,230,102, 72, 62,165,199,183, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 72,
- 62,115,162, 53, 62,211, 9,168, 62,120, 76,222, 62,218,167, 80, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,218,167, 80, 62, 70,176,194,
- 62,242, 37, 68, 62, 70,176,194, 62,230,102, 72, 62,115,162, 53, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,249,194,232, 62,120, 76,216, 62,230,102, 72,
- 62,115,162, 53, 62,242, 37, 68, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,242, 37, 68, 62, 70,176,194, 62,218,167, 80, 62, 70,176,194,
- 62,230,102, 72, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 1, 16,197, 62, 30,253,174, 63, 12,204,191, 62, 52,111, 90, 63, 3,190,226,
- 62, 83, 97, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 3,190,226, 62, 83, 97, 90, 62,242, 37, 68, 62, 70,176,194, 63, 1, 16,197, 62, 30,253,174,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102, 72, 62, 23, 31,168, 63, 1, 16,197, 62, 30,253,174, 62,242, 37, 68, 62, 70,176,194, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,242, 37, 68, 62, 70,176,194, 63, 3,190,226, 62, 83, 97, 90, 62,249,194,232, 62,120, 76,216, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,202,171, 14,
- 62, 30,253,179, 62,230,102, 72, 62, 23, 31,168, 62,218,167, 80, 62, 70,176,194, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,218,167, 80, 62, 70,176,194,
- 62,197, 78,205, 62, 83, 97, 95, 62,202,171, 14, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62, 52,111,101, 62,202,171, 14,
- 62, 30,253,179, 62,197, 78,205, 62, 83, 97, 95, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,197, 78,205, 62, 83, 97, 95, 62,218,167, 80, 62, 70,176,194,
- 62,211, 9,168, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 63, 61,147, 41,101, 62,179, 51, 20, 61,180,111,104, 62,179, 51, 15,
- 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 15, 61, 52, 64,225, 63, 12,204,189, 61, 52, 64,225, 62,230,102, 63, 61,147, 41,101,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 12,204,191, 61,180,111, 83, 62,230,102, 63, 61,147, 41,101, 63, 12,204,189, 61, 52, 64,225, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 12,204,189, 61, 52, 64,225, 62,179, 51, 15, 61, 52, 64,225, 62,161,175,144,178,239, 9,102, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 63,
- 61,147, 41,101, 63, 12,204,191, 61,180,111, 83, 62,249,154,104, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,249,154,104, 61,231, 46, 48,
- 62,211, 50, 42, 61,231, 46, 48, 62,230,102, 63, 61,147, 41,101, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 20, 61,180,111,104, 62,230,102, 63,
- 61,147, 41,101, 62,211, 50, 42, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,211, 50, 42, 61,231, 46, 48, 62,249,154,104, 61,231, 46, 48,
- 62,230,102, 72, 62, 23, 31,168, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,202,171, 14, 62, 30,253,179, 62,179, 51, 21, 62, 52,111,101, 62,179, 51, 19,
- 62, 7, 70,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 19, 62, 7, 70,204, 62,211, 50, 42, 61,231, 46, 48, 62,202,171, 14, 62, 30,253,179,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,230,102, 72, 62, 23, 31,168, 62,202,171, 14, 62, 30,253,179, 62,211, 50, 42, 61,231, 46, 48, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,211, 50, 42, 61,231, 46, 48, 62,179, 51, 19, 62, 7, 70,204, 62,179, 51, 20, 61,180,111,104, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 1, 16,197,
- 62, 30,253,174, 62,230,102, 72, 62, 23, 31,168, 62,249,154,104, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,249,154,104, 61,231, 46, 48,
- 63, 12,204,191, 62, 7, 70,199, 63, 1, 16,197, 62, 30,253,174, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62, 52,111, 90, 63, 1, 16,197,
- 62, 30,253,174, 63, 12,204,191, 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62, 7, 70,199, 62,249,154,104, 61,231, 46, 48,
- 63, 12,204,191, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,194,150, 19, 62,128, 45, 72, 62,179, 51, 21, 62,135, 83,156, 62,179, 51, 22,
- 62, 97,152, 2, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 22, 62, 97,152, 2, 62,197, 78,205, 62, 83, 97, 95, 62,194,150, 19, 62,128, 45, 72,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,211, 9,168, 62,120, 76,222, 62,194,150, 19, 62,128, 45, 72, 62,197, 78,205, 62, 83, 97, 95, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,197, 78,205, 62, 83, 97, 95, 62,179, 51, 22, 62, 97,152, 2, 62,179, 51, 21, 62, 52,111,101, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,194,150, 19,
- 62,128, 45, 72, 62,211, 9,168, 62,120, 76,222, 62,207, 51,179, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,207, 51,179, 62,146,201, 17,
- 62,192,162,113, 62,151,144,174, 62,194,150, 19, 62,128, 45, 72, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62,135, 83,156, 62,194,150, 19,
- 62,128, 45, 72, 62,192,162,113, 62,151,144,174, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,192,162,113, 62,151,144,174, 62,207, 51,179, 62,146,201, 17,
- 62,204, 34,175, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,191,109,154, 62,174, 54, 68, 62,179, 51, 21, 62,180,111,165, 62,179, 51, 21,
- 62,157,231, 98, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 62,179, 51, 21, 62,157,231, 98, 62,192,162,113, 62,151,144,174, 62,191,109,154, 62,174, 54, 68,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 62,204, 34,175, 62,169,150, 54, 62,191,109,154, 62,174, 54, 68, 62,192,162,113, 62,151,144,174, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 62,192,162,113, 62,151,144,174, 62,179, 51, 21, 62,157,231, 98, 62,179, 51, 21, 62,135, 83,156, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,217, 40,237,
- 62,166,190, 91, 62,204, 34,175, 62,169,150, 54, 62,207, 51,179, 62,146,201, 17, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,207, 51,179, 62,146,201, 17,
- 62,221,189, 75, 62,144,101,238, 62,217, 40,237, 62,166,190, 91, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,230,102, 72, 62,165,199,183, 62,217, 40,237,
- 62,166,190, 91, 62,221,189, 75, 62,144,101,238, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 62,221,189, 75, 62,144,101,238, 62,207, 51,179, 62,146,201, 17,
- 62,211, 9,168, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 56, 78,134, 62,128, 45,117, 63, 48, 20,188, 62,120, 77, 37, 63, 54,242, 42,
- 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,242, 42, 62, 83, 97,181, 63, 64, 0, 0, 62, 97,152,115, 63, 56, 78,134, 62,128, 45,117,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 62,135, 83,218, 63, 56, 78,134, 62,128, 45,117, 63, 64, 0, 0, 62, 97,152,115, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 64, 0, 0, 62, 97,152,115, 63, 54,242, 42, 62, 83, 97,181, 63, 64, 0, 0, 62, 52,111,202, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 56, 78,134,
- 62,128, 45,117, 63, 64, 0, 0, 62,135, 83,218, 63, 57, 72, 87, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57, 72, 87, 62,151,144,219,
- 63, 49,255,184, 62,146,201, 52, 63, 56, 78,134, 62,128, 45,117, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 20,188, 62,120, 77, 37, 63, 56, 78,134,
- 62,128, 45,117, 63, 49,255,184, 62,146,201, 52, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 49,255,184, 62,146,201, 52, 63, 57, 72, 87, 62,151,144,219,
- 63, 51,136, 58, 62,169,150, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 45, 5, 26, 62,166,190,117, 63, 38,102,107, 62,165,199,201, 63, 42,186,235,
- 62,144,102, 5, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 42,186,235, 62,144,102, 5, 63, 49,255,184, 62,146,201, 52, 63, 45, 5, 26, 62,166,190,117,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 51,136, 58, 62,169,150, 90, 63, 45, 5, 26, 62,166,190,117, 63, 49,255,184, 62,146,201, 52, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 49,255,184, 62,146,201, 52, 63, 42,186,235, 62,144,102, 5, 63, 48, 20,188, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57,226,196,
- 62,174, 54,114, 63, 51,136, 58, 62,169,150, 90, 63, 57, 72, 87, 62,151,144,219, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 57, 72, 87, 62,151,144,219,
- 63, 64, 0, 0, 62,157,231,162, 63, 57,226,196, 62,174, 54,114, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62,180,111,211, 63, 57,226,196,
- 62,174, 54,114, 63, 64, 0, 0, 62,157,231,162, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62,157,231,162, 63, 57, 72, 87, 62,151,144,219,
- 63, 64, 0, 0, 62,135, 83,218, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,107, 62,115,162, 79, 63, 48, 20,188, 62,120, 77, 37, 63, 42,186,235,
- 62,144,102, 5, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 42,186,235, 62,144,102, 5, 63, 34, 17,234, 62,144,101,243, 63, 38,102,107, 62,115,162, 79,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 28,184, 21, 62,120, 76,222, 63, 38,102,107, 62,115,162, 79, 63, 34, 17,234, 62,144,101,243, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 34, 17,234, 62,144,101,243, 63, 42,186,235, 62,144,102, 5, 63, 38,102,107, 62,165,199,201, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,107,
- 62,115,162, 79, 63, 28,184, 21, 62,120, 76,222, 63, 32,134,234, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 32,134,234, 62, 70,176,204,
- 63, 44, 69,233, 62, 70,176,245, 63, 38,102,107, 62,115,162, 79, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 20,188, 62,120, 77, 37, 63, 38,102,107,
- 62,115,162, 79, 63, 44, 69,233, 62, 70,176,245, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 44, 69,233, 62, 70,176,245, 63, 32,134,234, 62, 70,176,204,
- 63, 38,102,104, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 52, 68, 9, 62, 30,253,241, 63, 64, 0, 0, 62, 52,111,202, 63, 54,242, 42,
- 62, 83, 97,181, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 54,242, 42, 62, 83, 97,181, 63, 44, 69,233, 62, 70,176,245, 63, 52, 68, 9, 62, 30,253,241,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,104, 62, 23, 31,198, 63, 52, 68, 9, 62, 30,253,241, 63, 44, 69,233, 62, 70,176,245, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 44, 69,233, 62, 70,176,245, 63, 54,242, 42, 62, 83, 97,181, 63, 48, 20,188, 62,120, 77, 37, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 24,136,195,
- 62, 30,253,179, 63, 38,102,104, 62, 23, 31,198, 63, 32,134,234, 62, 70,176,204, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 32,134,234, 62, 70,176,204,
- 63, 21,218,162, 62, 83, 97, 84, 63, 24,136,195, 62, 30,253,179, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62, 52,111, 90, 63, 24,136,195,
- 62, 30,253,179, 63, 21,218,162, 62, 83, 97, 84, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 21,218,162, 62, 83, 97, 84, 63, 32,134,234, 62, 70,176,204,
- 63, 28,184, 21, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,104, 61,147, 41,111, 63, 12,204,191, 61,180,111, 83, 63, 12,204,189,
- 61, 52, 64,225, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,189, 61, 52, 64,225, 63, 64, 0, 0, 61, 52, 65,111, 63, 38,102,104, 61,147, 41,111,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 64, 0, 0, 61,180,111,195, 63, 38,102,104, 61,147, 41,111, 63, 64, 0, 0, 61, 52, 65,111, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 64, 0, 0, 61, 52, 65,111, 63, 12,204,189, 61, 52, 64,225, 63,121,222,208,178,239, 9,102, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,104,
- 61,147, 41,111, 63, 64, 0, 0, 61,180,111,195, 63, 48, 0,122, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 0,122, 61,231, 46,120,
- 63, 28,204, 85, 61,231, 46, 48, 63, 38,102,104, 61,147, 41,111, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 61,180,111, 83, 63, 38,102,104,
- 61,147, 41,111, 63, 28,204, 85, 61,231, 46, 48, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 28,204, 85, 61,231, 46, 48, 63, 48, 0,122, 61,231, 46,120,
- 63, 38,102,104, 62, 23, 31,198, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 24,136,195, 62, 30,253,179, 63, 12,204,191, 62, 52,111, 90, 63, 12,204,191,
- 62, 7, 70,199, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62, 7, 70,199, 63, 28,204, 85, 61,231, 46, 48, 63, 24,136,195, 62, 30,253,179,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 38,102,104, 62, 23, 31,198, 63, 24,136,195, 62, 30,253,179, 63, 28,204, 85, 61,231, 46, 48, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 28,204, 85, 61,231, 46, 48, 63, 12,204,191, 62, 7, 70,199, 63, 12,204,191, 61,180,111, 83, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 52, 68, 9,
- 62, 30,253,241, 63, 38,102,104, 62, 23, 31,198, 63, 48, 0,122, 61,231, 46,120, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 48, 0,122, 61,231, 46,120,
- 63, 64, 0, 0, 62, 7, 71, 24, 63, 52, 68, 9, 62, 30,253,241, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62, 52,111,202, 63, 52, 68, 9,
- 62, 30,253,241, 63, 64, 0, 0, 62, 7, 71, 24, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 62, 7, 71, 24, 63, 48, 0,122, 61,231, 46,120,
- 63, 64, 0, 0, 61,180,111,195, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 20,126, 68, 62,128, 45, 64, 63, 12,204,191, 62,135, 83,149, 63, 12,204,191,
- 62, 97,151,248, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62, 97,151,248, 63, 21,218,162, 62, 83, 97, 84, 63, 20,126, 68, 62,128, 45, 64,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 28,184, 21, 62,120, 76,222, 63, 20,126, 68, 62,128, 45, 64, 63, 21,218,162, 62, 83, 97, 84, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 21,218,162, 62, 83, 97, 84, 63, 12,204,191, 62, 97,151,248, 63, 12,204,191, 62, 52,111, 90, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 20,126, 68,
- 62,128, 45, 64, 63, 28,184, 21, 62,120, 76,222, 63, 26,205, 25, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 26,205, 25, 62,146,201, 14,
- 63, 19,132,114, 62,151,144,169, 63, 20,126, 68, 62,128, 45, 64, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62,135, 83,149, 63, 20,126, 68,
- 62,128, 45, 64, 63, 19,132,114, 62,151,144,169, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 19,132,114, 62,151,144,169, 63, 26,205, 25, 62,146,201, 14,
- 63, 25, 68,150, 62,169,150, 54, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 18,234, 7, 62,174, 54, 65, 63, 12,204,191, 62,180,111,160, 63, 12,204,191,
- 62,157,231, 90, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63, 12,204,191, 62,157,231, 90, 63, 19,132,114, 62,151,144,169, 63, 18,234, 7, 62,174, 54, 65,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 63, 25, 68,150, 62,169,150, 54, 63, 18,234, 7, 62,174, 54, 65, 63, 19,132,114, 62,151,144,169, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 19,132,114, 62,151,144,169, 63, 12,204,191, 62,157,231, 90, 63, 12,204,191, 62,135, 83,149, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 31,199,185,
- 62,166,190, 96, 63, 25, 68,150, 62,169,150, 54, 63, 26,205, 25, 62,146,201, 14, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 26,205, 25, 62,146,201, 14,
- 63, 34, 17,234, 62,144,101,243, 63, 31,199,185, 62,166,190, 96, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 38,102,107, 62,165,199,201, 63, 31,199,185,
- 62,166,190, 96, 63, 34, 17,234, 62,144,101,243, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63, 34, 17,234, 62,144,101,243, 63, 26,205, 25, 62,146,201, 14,
- 63, 28,184, 21, 62,120, 76,222, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,236,248,224, 0, 0, 0, 50, 0, 0, 0, 1, 2,237, 0, 32,
- 2,236,243,224, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,231, 1, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,236,250, 32, 2,236,254,208, 2,236,255, 16, 2,234,114, 96, 2,236,251,128, 2,236,253, 64, 0, 0, 0, 0,
- 2,236,255,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,236,250, 80, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,236,252, 16, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0,
- 2,236,253,160, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,179,128, 0, 0, 52, 64, 0, 0,188,142, 92,235, 63,128, 0, 0, 63,128, 0, 2,
- 60,142, 92,235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,236,250, 32, 0, 0, 0, 0,
- 0, 0, 0, 1, 2,236,194, 96, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,250, 80, 0, 0, 0,242, 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, 2,236,251,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0,100, 2,236,251,128, 0, 0, 0, 56, 0, 0, 0, 5, 63,128, 0, 0, 63,127,255,255, 39,251,255,255,
- 0, 0, 0, 0,127,255, 2,255, 63,128, 0, 0,191,128, 0, 0,168, 2, 0, 0, 0, 0, 0, 0,127,255, 2,255,191,128, 0, 1,
-191,127,255,253,167,251,255,253, 0, 0, 0, 0,127,255, 2,255,191,127,255,250, 63,128, 0, 3, 40, 2, 0, 3, 0, 0, 0, 0,
-127,255, 2,255, 59,110,239, 0, 60, 26,164,131,189, 14, 92,235, 12,228, 33, 95,133, 28, 3,255, 68, 65, 84, 65, 0, 0, 1, 4,
- 2,236,252, 16, 0, 0, 0,242, 0, 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, 2,236,253, 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, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 48, 2,236,253, 64, 0, 0, 0, 53,
- 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 34, 68, 65, 84, 65, 0, 0, 1, 4, 2,236,253,160,
- 0, 0, 0,242, 0, 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, 2,236,254,208, 0, 0, 0, 5,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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,236,255, 16, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0,
- 67,111,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,
- 2,236,255,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,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,
+ 8,197,152, 2, 51, 0, 0, 0, 1, 0, 0, 0,104,202,152, 2,152, 43,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,
+101,118,105,101,119, 46, 48, 48, 50, 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, 96,194,149, 2, 56, 86,169, 2,192,100,169, 2,
+ 0, 0, 0, 0, 32, 61,150, 2,152,134, 20, 3, 0, 0, 0, 0,152,118,148, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 72,198,152, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,168,199,152, 2, 1, 0, 0, 0, 5, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 8,201,152, 2, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128,179, 0, 0, 64, 52,235, 92,142,188,
+ 0, 0,128, 63, 2, 0,128, 63,235, 92,142, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,
+ 96,194,149, 2, 0, 0, 0, 0, 1, 0, 0, 0,152,140,165, 2, 68, 65, 84, 65, 44, 1, 0, 0, 72,198,152, 2, 21, 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, 32, 61,150, 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, 68, 65, 84, 65, 0, 0, 0, 20, 2,236,254,208, 0, 0, 0, 52, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 44, 2,236,255, 16,
- 0, 0, 0, 60, 0, 0, 0, 1, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 16, 2,236,255,112,
- 0, 0, 0, 57, 0, 0, 0, 4,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65, 0, 0, 0, 60,
- 2,234,114, 96, 0, 0, 0, 51, 0, 0, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,237, 0, 32, 0, 0, 0, 50, 0, 0, 0, 1, 2,237, 7, 80,
- 2,236,248,224, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,235,154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,237, 1, 96, 2,237, 6, 0, 2,237, 6, 64, 2,234,114, 96, 2,237, 2,192, 2,237, 4,112, 0, 0, 0, 0,
- 2,237, 6,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,237, 1,144, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,237, 3, 64, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0,
- 2,237, 4,208, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,179,128, 0, 0, 52, 64, 0, 0, 28,192, 0, 0, 63,128, 0, 0, 63,128, 0, 2,
- 55, 39,197,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,237, 1, 96, 0, 0, 0, 0,
- 0, 0, 0, 1, 2,236,196,224, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 1,144, 0, 0, 0,242, 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, 2,237, 2,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,100, 0, 0, 0, 32, 61,150, 2, 57, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0,128, 63,255,255,127, 63,255,255,251, 39, 0, 0, 0, 0,255,127, 2,255, 0, 0,128, 63, 0, 0,128,191,
+ 0, 0, 2,168, 0, 0, 0, 0,255,127, 2,255, 1, 0,128,191,253,255,127,191,253,255,251,167, 0, 0, 0, 0,255,127, 2,255,
+250,255,127,191, 3, 0,128, 63, 3, 0, 2, 40, 0, 0, 0, 0,255,127, 2,255, 0,239,110, 59,131,164, 26, 60,235, 92, 14,189,
+228, 12, 95, 33, 28,133, 3,255, 68, 65, 84, 65, 44, 1, 0, 0,168,199,152, 2, 21, 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,152,134, 20, 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,
- 68, 65, 84, 65, 0, 0, 0, 80, 2,237, 2,192, 0, 0, 0, 56, 0, 0, 0, 4, 63,128, 0, 0, 63,127,255,255, 39,251,255,255,
- 0, 0, 0, 0,127,255, 3,255, 63,128, 0, 0,191,128, 0, 0,168, 2, 0, 0, 0, 0, 0, 0,127,255, 3,255,191,128, 0, 1,
-191,127,255,253,167,251,255,253, 0, 0, 0, 0,127,255, 3,255,191,127,255,250, 63,128, 0, 3, 40, 2, 0, 3, 0, 0, 0, 0,
-127,255, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 3, 64, 0, 0, 0,242, 0, 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, 2,237, 4,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 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, 0, 0, 48, 2,237, 4,112, 0, 0, 0, 53, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 35,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 4,208, 0, 0, 0,242, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 48, 0, 0, 0,152,134, 20, 3, 54, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 34, 0,
+ 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 34, 0, 68, 65, 84, 65, 44, 1, 0, 0, 8,201,152, 2, 21, 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, 56, 86,169, 2, 5, 0, 0, 0,
+ 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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,100,169, 2, 6, 0, 0, 0, 64, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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,152,118,148, 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, 2,237, 6, 0, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0,
- 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,237, 6, 64, 0, 0, 0, 6,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 2,237, 6,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 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, 0, 0, 20,
- 2,237, 6, 0, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2,
- 68, 65, 84, 65, 0, 0, 0, 44, 2,237, 6, 64, 0, 0, 0, 60, 0, 0, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
- 68, 65, 84, 65, 0, 0, 0, 16, 2,237, 6,160, 0, 0, 0, 57, 0, 0, 0, 4,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 68, 65, 84, 65, 0, 0, 0, 60, 2,234,114, 96, 0, 0, 0, 51, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 1, 20, 2,237, 7, 80,
- 0, 0, 0, 50, 0, 0, 0, 1, 2,237, 14,128, 2,237, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,
-119, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,235,206,144,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,237, 8,144, 2,237, 13, 48, 2,237, 13,112, 2,234,114, 96,
- 2,237, 9,240, 2,237, 11,160, 0, 0, 0, 0, 2,237, 13,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 2,237, 8,192, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 2,237, 10,112, 0, 0, 0, 1,
- 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 2,237, 12, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0,
- 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,179,128, 0, 0, 52, 64, 0, 0,
- 28,192, 0, 0, 63,128, 0, 0, 63,128, 0, 2, 55, 39,197,172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65,
- 0, 0, 0, 4, 2,237, 8,144, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,199, 96, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 8,192,
- 0, 0, 0,242, 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, 2,237, 9,240, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 20, 0, 0, 0, 56, 86,169, 2, 53, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 44, 0, 0, 0,192,100,169, 2,
+ 61, 0, 0, 0, 1, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,152,118,148, 2,
+ 58, 0, 0, 0, 4, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,
+104,202,152, 2, 51, 0, 0, 0, 1, 0, 0, 0,152, 47,161, 2, 8,197,152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,
+101,118,105,101,119, 46, 48, 48, 51, 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, 72, 3,153, 2, 96, 33,164, 2,152, 91,169, 2,
+ 0, 0, 0, 0,128,175, 20, 3,128, 40,150, 2, 0, 0, 0, 0,112,187,147, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+168,203,152, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 8,205,152, 2, 1, 0, 0, 0, 5, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 0, 56, 46,161, 2, 3, 0, 0, 0, 5, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,128,179, 0, 0, 64, 52, 0, 0,192, 28,
+ 0, 0,128, 63, 2, 0,128, 63,172,197, 39, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,
+ 72, 3,153, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0,147,165, 2, 68, 65, 84, 65, 44, 1, 0, 0,168,203,152, 2, 21, 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,128,175, 20, 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, 0, 0, 0, 0, 0, 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, 0, 0, 80, 2,237, 9,240, 0, 0, 0, 56, 0, 0, 0, 4,
- 63,128, 0, 0, 63,127,255,255, 39,251,255,255, 0, 0, 0, 0,127,255, 3,255, 63,128, 0, 0,191,128, 0, 0,168, 2, 0, 0,
- 0, 0, 0, 0,127,255, 3,255,191,128, 0, 1,191,127,255,253,167,251,255,253, 0, 0, 0, 0,127,255, 3,255,191,127,255,250,
- 63,128, 0, 3, 40, 2, 0, 3, 0, 0, 0, 0,127,255, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 10,112, 0, 0, 0,242,
- 0, 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, 2,237, 11,160, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 80, 0, 0, 0,128,175, 20, 3, 57, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0,128, 63,255,255,127, 63,255,255,251, 39, 0, 0, 0, 0,255,127, 3,255, 0, 0,128, 63, 0, 0,128,191,
+ 0, 0, 2,168, 0, 0, 0, 0,255,127, 3,255, 1, 0,128,191,253,255,127,191,253,255,251,167, 0, 0, 0, 0,255,127, 3,255,
+250,255,127,191, 3, 0,128, 63, 3, 0, 2, 40, 0, 0, 0, 0,255,127, 3,255, 68, 65, 84, 65, 44, 1, 0, 0, 8,205,152, 2,
+ 21, 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,
+128, 40,150, 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, 68, 65, 84, 65, 0, 0, 0, 48, 2,237, 11,160, 0, 0, 0, 53, 0, 0, 0, 4, 0, 0, 0, 1,
- 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35,
- 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 12, 0, 0, 0, 0,242, 0, 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, 2,237, 13, 48, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0,
- 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 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,237, 13,112, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 2,237, 13,208, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 48, 0, 0, 0,128, 40,150, 2,
+ 54, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 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, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0, 68, 65, 84, 65, 44, 1, 0, 0,
+ 56, 46,161, 2, 21, 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, 96, 33,164, 2, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 85, 86, 84,101,120, 0, 0, 0, 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, 91,169, 2, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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,112,187,147, 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, 0, 0, 0, 20, 2,237, 13, 48, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3,
- 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 68, 65, 84, 65, 0, 0, 0, 44, 2,237, 13,112, 0, 0, 0, 60, 0, 0, 0, 1,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 16, 2,237, 13,208, 0, 0, 0, 57, 0, 0, 0, 4,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65, 0, 0, 0, 60, 2,234,114, 96, 0, 0, 0, 51,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 77, 69, 0, 0, 1, 20, 2,237, 14,128, 0, 0, 0, 50, 0, 0, 0, 1, 0, 0, 0, 0, 2,237, 7, 80, 0, 0, 0, 0,
- 0, 0, 0, 0, 77, 69, 67,117, 98,101, 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, 2,230, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,237, 15,192,
- 2,237, 21, 16, 2,237, 21,176, 2,234,116,128, 2,237, 17, 32, 2,237, 19, 32, 0, 0, 0, 0, 2,237, 22,224, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,237, 15,240, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 20,
- 0, 0, 0, 0, 2,237, 17,240, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 2,237, 19,224, 0, 0, 0, 3,
- 0, 0, 0, 5, 0, 0, 0, 80, 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, 51,128, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 4, 63,128, 0, 4, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 2,237, 15,192, 0, 0, 0, 0, 0, 0, 0, 1, 2,236,194, 96,
- 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 15,240, 0, 0, 0,242, 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, 2,237, 17, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 20, 0, 0, 0,
+ 96, 33,164, 2, 53, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2,
+ 68, 65, 84, 65, 44, 0, 0, 0,152, 91,169, 2, 61, 0, 0, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
+ 68, 65, 84, 65, 16, 0, 0, 0,112,187,147, 2, 58, 0, 0, 0, 4, 0, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,152, 47,161, 2, 51, 0, 0, 0, 1, 0, 0, 0,248, 52,161, 2,104,202,152, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 46, 48, 48, 52, 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,
+ 88, 14,167, 2,152,110,126, 2,168,144, 8, 3, 0, 0, 0, 0,104,206,152, 2,160, 93,169, 2, 0, 0, 0, 0,232,110,127, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,216, 48,161, 2, 1, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
+ 56, 50,161, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,152, 51,161, 2, 3, 0, 0, 0, 5, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0,128,179, 0, 0, 64, 52, 0, 0,192, 28, 0, 0,128, 63, 2, 0,128, 63,172,197, 39, 55, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0, 88, 14,167, 2, 0, 0, 0, 0, 1, 0, 0, 0,248, 6,131, 2, 68, 65, 84, 65,
+ 44, 1, 0, 0,216, 48,161, 2, 21, 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,104,206,152, 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, 68, 65, 84, 65, 0, 0, 0,160,
- 2,237, 17, 32, 0, 0, 0, 56, 0, 0, 0, 8, 63,128, 0, 0, 63,127,255,255,191,128, 0, 0, 73,230, 73,230,182, 26, 3,255,
- 63,128, 0, 0,191,128, 0, 0,191,128, 0, 0, 73,230,182, 26,182, 26, 3,255,191,128, 0, 1,191,127,255,253,191,128, 0, 0,
-182, 26,182, 26,182, 26, 3,255,191,127,255,250, 63,128, 0, 3,191,128, 0, 0,182, 26, 73,230,182, 26, 3,255, 63,128, 0, 4,
- 63,127,255,247, 63,128, 0, 0, 73,230, 73,230, 73,230, 3,255, 63,127,255,245,191,128, 0, 5, 63,128, 0, 0, 73,230,182, 26,
- 73,230, 3,255,191,128, 0, 3,191,127,255,250, 63,128, 0, 0,182, 26,182, 26, 73,230, 3,255,191,127,255,255, 63,128, 0, 0,
- 63,128, 0, 0,182, 26, 73,230, 73,230, 3,255, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 17,240, 0, 0, 0,242, 0, 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, 2,237, 19, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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,
+ 80, 0, 0, 0,104,206,152, 2, 57, 0, 0, 0, 4, 0, 0, 0, 0, 0,128, 63,255,255,127, 63,255,255,251, 39, 0, 0, 0, 0,
+255,127, 3,255, 0, 0,128, 63, 0, 0,128,191, 0, 0, 2,168, 0, 0, 0, 0,255,127, 3,255, 1, 0,128,191,253,255,127,191,
+253,255,251,167, 0, 0, 0, 0,255,127, 3,255,250,255,127,191, 3, 0,128, 63, 3, 0, 2, 40, 0, 0, 0, 0,255,127, 3,255,
+ 68, 65, 84, 65, 44, 1, 0, 0, 56, 50,161, 2, 21, 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,160, 93,169, 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, 68, 65, 84, 65, 0, 0, 0,144, 2,237, 19, 32, 0, 0, 0, 53, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 2,
- 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 2,
- 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 35,
- 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 5,
- 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 3,
- 0, 0, 0, 7, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 1, 4, 2,237, 19,224, 0, 0, 0,242, 0, 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, 2,237, 21, 16, 0, 0, 0, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0,
- 85, 86, 84,101,120, 0, 0, 0, 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,237, 21,176, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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, 2,237, 22,224, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0,120, 2,237, 21, 16, 0, 0, 0, 52, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2,
- 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0,
- 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2,
- 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 2, 68, 65, 84, 65, 0, 0, 1, 8, 2,237, 21,176, 0, 0, 0, 60, 0, 0, 0, 6,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 96, 2,237, 22,224, 0, 0, 0, 57, 0, 0, 0, 24,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 68, 65, 84, 65,
- 0, 0, 1,104, 2,234,116,128, 0, 0, 0, 51, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,
- 63,128, 0, 0, 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0,
- 63,128, 0, 0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 68, 78, 65, 49, 0, 0,127,128,
- 7, 91, 64, 32, 0, 0, 0, 0, 0, 0, 0, 1, 83, 68, 78, 65, 78, 65, 77, 69, 0, 0, 7, 39, 42,110,101,120,116, 0, 42,112,
-114,101,118, 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,
-112, 97,100, 0,110, 97,109,101, 91, 51, 50, 93, 0,116,121,112,101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103, 0,100,
- 97,116, 97, 0,108,101,110, 0,116,111,116, 97,108,108,101,110, 0,115, 97,118,101,100, 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, 42,112, 97,114,101,110,116, 0, 99,117,114,
-118,101, 0, 99,117,114, 0, 98,108,111, 99,107,116,121,112,101, 0,115,104,111,119,107,101,121, 0,112,111,115, 0, 99,117,114,
-118, 97,108, 0, 97,100,114, 99,111,100,101, 0,116,111,116,101,108,101,109, 0, 42,100, 97,116, 97, 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,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, 42,
-115, 99,114,105,112,116,115, 0, 42,102,108, 97,103, 0, 97, 99,116,115, 99,114,105,112,116, 0,116,111,116,115, 99,114,105,112,
-116, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,116, 0, 98,108,101,110, 0, 42,110, 97,109,101, 0,102,108, 97,103,115,
- 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, 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,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,112, 97,100, 49, 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,115, 99,114,105,112,116,108,105,110,
-107, 0,104, 0, 42,114,101, 99,116, 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,105, 98,117,102,115, 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,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, 42,118,110,111,100,101, 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,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,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,112,108,117,103,105,110, 0, 42, 99,111, 98, 97, 0, 42,101,110,118, 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, 42,111, 98, 0,109,111,100,101, 0,116,111,116,101,120, 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,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,116,101,120, 97,
- 99,116, 0,115,104, 97,100,104, 97,108,111,115,116,101,112, 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, 48, 93,
- 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,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, 98,105, 97,115, 0,115,104, 97,100, 95, 97,
-108,112,104, 97, 0,112, 97,100,102, 0,114,103, 98,115,101,108, 0,112,114, 95,116,121,112,101, 0,117,115,101, 95,110,111,100,
-101,115, 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,115,101,112,116,101,120, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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, 48, 0, 0, 0,160, 93,169, 2, 54, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 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, 2, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 35, 0, 68, 65, 84, 65, 44, 1, 0, 0,152, 51,161, 2, 21, 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,152,110,126, 2, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168,144, 8, 3, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 67,111,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,232,110,127, 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, 68, 65, 84, 65, 20, 0, 0, 0,152,110,126, 2, 53, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+ 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 68, 65, 84, 65, 44, 0, 0, 0,168,144, 8, 3, 61, 0, 0, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65, 16, 0, 0, 0,232,110,127, 2, 58, 0, 0, 0, 4, 0, 0, 0,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 77, 69, 0, 0, 12, 1, 0, 0,248, 52,161, 2, 51, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,152, 47,161, 2, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117, 98,101, 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,224, 25,167, 2,136,107,169, 2, 88, 58,161, 2, 0, 0, 0, 0,248,131, 20, 3,
+ 56, 53,132, 2, 0, 0, 0, 0, 0,204,156, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 54,161, 2, 1, 0, 0, 0,
+ 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0,152, 55,161, 2, 1, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+248, 56,161, 2, 3, 0, 0, 0, 5, 0, 0, 0, 80, 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, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 4, 0, 0, 0,224, 25,167, 2, 0, 0, 0, 0,
+ 1, 0, 0, 0,152,140,165, 2, 68, 65, 84, 65, 44, 1, 0, 0, 56, 54,161, 2, 21, 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,248,131, 20, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,248,131, 20, 3, 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, 3,255, 0, 0,128, 63, 0, 0,128,191, 0, 0,128,191,230, 73, 26,182,
+ 26,182, 3,255, 1, 0,128,191,253,255,127,191, 0, 0,128,191, 26,182, 26,182, 26,182, 3,255,250,255,127,191, 3, 0,128, 63,
+ 0, 0,128,191, 26,182,230, 73, 26,182, 3,255, 4, 0,128, 63,247,255,127, 63, 0, 0,128, 63,230, 73,230, 73,230, 73, 3,255,
+245,255,127, 63, 5, 0,128,191, 0, 0,128, 63,230, 73, 26,182,230, 73, 3,255, 3, 0,128,191,250,255,127,191, 0, 0,128, 63,
+ 26,182, 26,182,230, 73, 3,255,255,255,127,191, 0, 0,128, 63, 0, 0,128, 63, 26,182,230, 73,230, 73, 3,255, 68, 65, 84, 65,
+ 44, 1, 0, 0,152, 55,161, 2, 21, 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, 56, 53,132, 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, 68, 65, 84, 65,
+144, 0, 0, 0, 56, 53,132, 2, 54, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 35, 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, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 35, 0,
+ 4, 0, 0, 0, 5, 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, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 35, 0, 1, 0, 0, 0, 5, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0,
+ 4, 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,
+ 68, 65, 84, 65, 44, 1, 0, 0,248, 56,161, 2, 21, 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,136,107,169, 2, 5, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 88, 58,161, 2, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 67,111,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,204,156, 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,
+ 68, 65, 84, 65,120, 0, 0, 0,136,107,169, 2, 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, 68, 65, 84, 65, 8, 1, 0, 0, 88, 58,161, 2, 61, 0, 0, 0, 6, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63,
+ 0, 0, 0, 0, 1, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 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, 0, 0, 0, 0,128, 63,
+ 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 1, 0, 1, 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, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0, 68, 65, 84, 65, 96, 0, 0, 0, 0,204,156, 2, 58, 0, 0, 0, 24, 0, 0, 0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 80, 65, 0, 0,
+220, 1, 0, 0,232,102,152, 2, 27, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80, 65, 80, 83,121,115, 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, 18, 0, 0, 0, 2, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 4, 0,
+ 6, 0, 8, 0, 5, 0, 5, 0, 3, 0,100, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 4, 0, 5, 0, 3, 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,128, 7, 0, 0,128, 63,205,204,204, 61,
+205,204, 76, 63, 0, 0,128, 63, 0, 0,200, 66, 0, 0, 72, 66, 0, 0, 0, 0, 0, 0,128, 63, 0, 0,128, 63, 0, 0, 0, 63,
+ 0, 0, 0, 0, 0, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0,128, 41,182, 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,128, 63, 0, 0,128, 63, 0, 0, 0, 0, 0, 0,128, 63,240,214, 35,189, 0, 0, 0, 0,184,155,196,189, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,128, 63, 0, 0, 0, 0,205,204, 76, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,205,204, 76, 62,
+ 0, 0, 0, 64, 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,
+ 0, 0,128, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 32, 65, 0, 0,128, 63,205,204, 76, 62,154,153,153, 62,
+ 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, 0, 63, 0, 0, 0, 63,
+ 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 1, 2, 3, 4, 5, 6, 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, 68, 78, 65, 49,108,158, 0, 0,176, 98,130, 2, 0, 0, 0, 0, 1, 0, 0, 0,
+ 83, 68, 78, 65, 78, 65, 77, 69,179, 8, 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,112, 97,100, 0,110, 97,
+109,101, 91, 51, 50, 93, 0,116,121,112,101, 0,115,117, 98,116,121,112,101, 0,102,108, 97,103, 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, 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, 99,
+117,114,118,101, 0, 99,117,114, 0, 98,108,111, 99,107,116,121,112,101, 0,115,104,111,119,107,101,121, 0,109,117,116,101,105,
+112,111, 0,112,111,115, 0, 99,117,114,118, 97,108, 0, 97,100,114, 99,111,100,101, 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,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, 42,115, 99,114,105,112,116,115, 0, 42,102,108, 97,103, 0,
+ 97, 99,116,115, 99,114,105,112,116, 0,116,111,116,115, 99,114,105,112,116, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,
+116, 0, 98,108,101,110, 0, 42,110, 97,109,101, 0,102,108, 97,103,115, 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, 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,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,115, 99,114,105,112,116,108,105,110,107, 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,105, 98,117,102,115, 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,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, 42,118,110,111,100,101, 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,112, 97,100, 91, 51, 93, 0,114, 0,103, 0, 98, 0,107, 0,100,101,102, 95,118, 97,114,
+ 0,114,116, 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,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,112,108,117,103,105,110, 0, 42, 99,111, 98, 97, 0, 42,101,110,118, 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, 42,111, 98, 0,109,111,100,101, 0,116,111,116,101,120, 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,112, 97,100, 51,
+ 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, 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, 48, 93, 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,112, 97,100,102, 0,114,103, 98,115,101,108, 0,112,114, 95,116,121,112,101, 0,117,115,
+101, 95,110,111,100,101,115, 0,112,114, 95, 98, 97, 99,107, 0,112,114, 95,108, 97,109,112, 0,115,101,112,116,101,120, 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,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,110,111,100,101,116,114,101,101, 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,112, 97,100, 50, 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,110, 97,109,101, 91, 50, 53, 54, 93, 0,115, 99, 97,108,
-101, 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, 42,109, 97,116, 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,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, 42, 98,112, 0, 42, 98,101,122,116, 0, 99,104, 97,114,105,100,120, 0,107,101,114,
-110, 0,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,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,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,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,110, 97,109,101, 91, 49, 50, 56, 93, 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, 42,100,114,105,118,101,114, 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,111, 99, 0, 42,115,117,109,111,104, 97,110,100,108,101, 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,
- 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,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, 99,
-111, 91, 50, 93, 0,105,110,100,101,120, 0,118, 91, 52, 93, 0,109,105,100, 0, 99,104,105,108,100,114,101,110,115,116, 97,114,
-116, 0,112, 97,100, 91, 50, 93, 0,118, 91, 50, 93, 0, 42,118,101,114,116,115, 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, 95,101,100,103,101, 95,109, 97,112, 0, 42,118,101,114,
-116, 95,102, 97, 99,101, 95,109, 97,112, 0, 42,109, 97,112, 95,109,101,109, 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,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,115,116, 97,114,116, 0,108,101,110,103,116,
-104, 0,114, 97,110,100,111,109,105,122,101, 0,115,101,101,100, 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,115,112,108,105,116, 95, 97,110,103,108,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,100,101,102,103,114,112, 95,110, 97,109,
-101, 91, 51, 50, 93, 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, 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, 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,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,
-112, 97,114,101,110,116,105,110,118, 91, 52, 93, 91, 52, 93, 0, 99,101,110,116, 91, 51, 93, 0,102, 97,108,108,111,102,102, 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,111,112,101,114, 97,116,105,111,
-110, 0,112, 97,115,115,101,115, 0,102, 97, 99,116,111,114, 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,118,101, 99, 91, 56, 93, 91, 51, 93, 0,100,118,
-101, 99, 91, 51, 93, 0,109, 97,120, 0, 42, 42,111, 98, 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,112, 97,114,100, 97,116, 97, 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, 0, 99,111,110,115,116,114, 97,105,110,116, 67,104, 97,110,
-110,101,108,115, 0,110,101,116,119,111,114,107, 0,100,101,102, 98, 97,115,101, 0,109,111,100,105,102,105,101,114,115, 0,100,
+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,110,
+ 97,109,101, 91, 50, 53, 54, 93, 0,115, 99, 97,108,101, 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, 42,109, 97,116, 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,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, 42, 98,112, 0, 42, 98,101,122,
+116, 0,116,105,108,116, 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, 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,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,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,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,110, 97,109,101, 91, 49, 50, 56, 93, 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, 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, 42,100,114,105,118,101,114, 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,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,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, 99,111, 91, 50, 93, 0,105,110,100,101,120, 0,102, 0,105, 0,115, 91, 50, 53, 54, 93, 0,118, 91, 52, 93, 0,
+109,105,100, 0,112, 97,100, 91, 50, 93, 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,101,100,103,101, 95, 98,111,117,110,100, 97,114,121, 95,115,116, 97,116,101,115, 0, 42,118,
+101,114,116, 95,101,100,103,101, 95,109, 97,112, 0, 42,118,101,114,116, 95,102, 97, 99,101, 95,109, 97,112, 0, 42,109, 97,112,
+ 95,109,101,109, 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,115,116, 97,114,116,
+ 0,108,101,110,103,116,104, 0,114, 97,110,100,111,109,105,122,101, 0,115,101,101,100, 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, 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,100,101,102,103,114,
+112, 95,110, 97,109,101, 91, 51, 50, 93, 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,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,102, 97,108,108,111,102,102, 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,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,116,105,109,101, 0, 42,116,114,101,101, 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, 42,100,109, 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,114,116, 91, 50, 93, 0, 42,102, 97, 99,101,112, 97, 0,118,103,114,111,117,112,
+ 0,112,114,111,116,101, 99,116, 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,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,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,
-100,113,117, 97,116, 91, 52, 93, 0,111, 98,109, 97,116, 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,105,112,111,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,112,114,111,116,101, 99,116,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, 99,116,105,109,101, 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,
-115,111,102,116,116,105,109,101, 0,114,100, 97,109,112,105,110,103, 0,115,105,122,101,102, 97, 99, 0,100,116, 0,100,116,120,
- 0, 97, 99,116, 99,111,108, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,112, 97,100, 49, 91, 51, 93, 0,101,
-109,112,116,121, 95,100,114, 97,119,115,105,122,101, 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,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, 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,112, 97,100, 52, 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, 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,102, 95,115,116,114,101,110,103,116,104, 0,
-102, 95,112,111,119,101,114, 0,109, 97,120,100,105,115,116, 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,116,111,116,112,111,105,110,116, 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,110,111,100,101,109, 97,115,115, 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,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,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,112, 97,100, 53,
- 0, 42,115, 99,114, 97,116, 99,104, 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,117,110,117,
-115,101,100, 68, 78, 65, 68,117,109,109,121, 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,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,112,104,121,115,105, 99,115, 69,110,103,105,110,101, 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, 42, 97,111,115,112,104,101,114,101, 0, 42, 97,111,116,
- 97, 98,108,101,115, 0,104,101,109,105,114,101,115, 0,109, 97,120,105,116,101,114, 0,100,114, 97,119,116,121,112,101, 0,115,
-117, 98,115,104,111,111,116,112, 0,115,117, 98,115,104,111,111,116,101, 0,110,111,100,101,108,105,109, 0,109, 97,120,115,117,
- 98,108, 97,109,112, 0,112, 97,109, 97, 0,112, 97,109,105, 0,101,108,109, 97, 0,101,108,109,105, 0,109, 97,120,110,111,100,
-101, 0, 99,111,110,118,101,114,103,101,110, 99,101, 0,114, 97,100,102, 97, 99, 0,103, 97,109,109, 97, 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,
-112, 97,100, 91, 51, 93, 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,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, 99,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,114,116, 50, 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, 97,115,112, 0,121, 97,115,112, 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,115, 99,101,109,111,100,101, 0,114,101,110,100,101,114,101,114, 0,111, 99,114,101,115, 0,114,112, 97,100, 91,
- 50, 93, 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,103, 97,117,115,115, 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, 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,
+100,113,117, 97,116, 91, 52, 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,105,112,111,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,112,114,111,116,101,
+ 99,116,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, 99,116,105,109,101, 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,
+100,116, 0,100,116,120, 0, 97, 99,116, 99,111,108, 0,101,109,112,116,121, 95,100,114, 97,119,116,121,112,101, 0,112, 97,100,
+ 49, 91, 51, 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, 42,115,117,109,111,104, 97,110,100,108,101, 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,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,112, 97,100, 52, 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, 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,112, 97,114,116,105, 99,108,101,115, 0,116,111,116,112,111,105,110,116, 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,110,111,100,101,109,
+ 97,115,115, 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,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,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,112, 97,100, 53, 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,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,117,110,117,115,101,100, 68, 78, 65, 68,117,109,109,121, 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,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,112,104,121,115,105, 99,115, 69,110,103,105,110,
+101, 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,104,101,109,105,114,101,115, 0,109, 97,120,105,116,101,114, 0,100,114, 97,119,116,121,112,101,
+ 0,115,117, 98,115,104,111,111,116,112, 0,115,117, 98,115,104,111,111,116,101, 0,110,111,100,101,108,105,109, 0,109, 97,120,
+115,117, 98,108, 97,109,112, 0,112, 97,109, 97, 0,112, 97,109,105, 0,101,108,109, 97, 0,101,108,109,105, 0,109, 97,120,110,
+111,100,101, 0, 99,111,110,118,101,114,103,101,110, 99,101, 0,114, 97,100,102, 97, 99, 0,103, 97,109,109, 97, 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, 99,102,114, 97, 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, 97,115,112, 0,121, 97,115,112, 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,115, 99,101,109,111,100,101, 0,114,101,110,100,101,114,101,
+114, 0,111, 99,114,101,115, 0,114,112, 97,100, 91, 50, 93, 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,102,114,115, 95,115,101, 99, 95, 98, 97,115,101, 0,
+103, 97,117,115,115, 0,112,111,115,116,109,117,108, 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,112, 97,100, 0, 98, 97,107,101, 95,109, 97,
+120,100,105,115,116, 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,
@@ -13589,779 +12582,982 @@ char datatoc_preview_blend[]= {
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,102,116,121,112,101, 91, 49, 54, 48, 93, 0, 99,111,108, 91, 51, 93, 0,102,114, 97,109,
-101, 0,110, 97,109,101, 91, 54, 52, 93, 0, 42, 98,114,117,115,104, 0,116,111,111,108, 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,
-115,116,101,112, 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,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,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,115,101,108,101, 99,116, 95,116,104,114,101,115,104, 0,105,109, 97,112, 97,105,110,116, 0, 99,
-108,101, 97,110, 95,116,104,114,101,115,104, 0,114,101,116,111,112,111, 95,109,111,100,101, 0,108,105,110,101, 95,100,105,118,
- 0,101,108,108,105,112,115,101, 95,100,105,118, 0,100,105,114, 0, 97,105,114, 98,114,117,115,104, 0,118,105,101,119, 0, 42,
-115,101,115,115,105,111,110, 0,100,114, 97,119, 98,114,117,115,104, 0,115,109,111,111,116,104, 98,114,117,115,104, 0,112,105,
-110, 99,104, 98,114,117,115,104, 0,105,110,102,108, 97,116,101, 98,114,117,115,104, 0,103,114, 97, 98, 98,114,117,115,104, 0,
-108, 97,121,101,114, 98,114,117,115,104, 0, 98,114,117,115,104, 95,116,121,112,101, 0,116,101,120,110,114, 0,116,101,120,114,
-101,112,116, 0,116,101,120,102, 97,100,101, 0,116,101,120,115,101,112, 0, 97,118,101,114, 97,103,105,110,103, 0,100,114, 97,
-119, 95,102,108, 97,103, 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,115,121,109,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, 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,101,100,105,116, 98,117,116,115,105,122,101, 0,115,101,108,101, 99,
-116,109,111,100,101, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 0,112,114,111,112, 95,109,111,100,101, 0, 42,101,100,
- 0, 42,114, 97,100,105,111, 0,102,114, 97,109,105,110,103, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0, 97,117,
-100,105,111, 0,109, 97,114,107,101,114,115, 0,106,117,109,112,102,114, 97,109,101, 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,115, 99,117,108,112,116,100, 97,116, 97, 0,122,111,111,
-109, 0, 98,108,101,110,100, 0,120,105,109, 0,121,105,109, 0,115,112, 97, 99,101,116,121,112,101, 0, 98,108,111, 99,107,115,
- 99, 97,108,101, 0, 42, 97,114,101, 97, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 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,119,105,110,109, 97,116, 49, 91, 52, 93, 91, 52, 93,
- 0,118,105,101,119,109, 97,116, 49, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,122,102, 97, 99,
- 0,112, 97,100, 48, 0,112,101,114,115,112, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 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,111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108,111, 99, 97,108,118,105,101,
-119, 0,108, 97,121, 97, 99,116, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0, 99, 97,109,122,111,111,
-109, 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,105,120,115,105,
-122,101, 0,110,101, 97,114, 0,102, 97,114, 0, 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,103,114,105,100,108,105,110,101,
-115, 0,118,105,101,119, 98,117,116, 0,103,114,105,100,102,108, 97,103, 0,109,111,100,101,115,101,108,101, 99,116, 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,116,119,
-109, 97,116, 91, 52, 93, 91, 52, 93, 0, 99,108,105,112, 91, 52, 93, 91, 52, 93, 0, 42, 99,108,105,112, 98, 98, 0, 97,102,116,
-101,114,100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,102,108, 97,103, 50, 0,103,114,105,100,115,117, 98,100,105,
-118, 0,115,110, 97,112, 95,116, 97,114,103,101,116, 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,107,101,101,112,116,111,116, 0,107,101,101,
-112, 97,115,112,101, 99,116, 0,107,101,101,112,122,111,111,109, 0,111,108,100,119,105,110,120, 0,111,108,100,119,105,110,121,
- 0,114,111,119, 98,117,116, 0,118, 50,100, 0, 42,101,100,105,116,105,112,111, 0,105,112,111,107,101,121, 0, 97, 99,116,110,
- 97,109,101, 91, 51, 50, 93, 0, 99,111,110,115,116,110, 97,109,101, 91, 51, 50, 93, 0,116,111,116,105,112,111, 0,112,105,110,
- 0, 98,117,116,111,102,115, 0, 99,104, 97,110,110,101,108, 0,108,111, 99,107, 0,109,101,100,105, 97,110, 91, 51, 93, 0, 99,
-117,114,115,101,110,115, 0, 99,117,114, 97, 99,116, 0, 97,108,105,103,110, 0,116, 97, 98,111, 0,109, 97,105,110, 98, 0,109,
- 97,105,110, 98,111, 0, 42,108,111, 99,107,112,111,105,110, 0,116,101,120,102,114,111,109, 0,115,104,111,119,103,114,111,117,
-112, 0,109,111,100,101,108,116,121,112,101, 0,115, 99,114,105,112,116, 98,108,111, 99,107, 0,114,101, 95, 97,108,105,103,110,
- 0,111,108,100,107,101,121,112,114,101,115,115, 0,116, 97, 98, 91, 55, 93, 0, 99,104, 97,110,115,104,111,119,110, 0, 42,102,
-105,108,101,108,105,115,116, 0,116,111,116,102,105,108,101, 0,116,105,116,108,101, 91, 50, 52, 93, 0,100,105,114, 91, 49, 54,
- 48, 93, 0,102,105,108,101, 91, 56, 48, 93, 0,111,102,115, 0,115,111,114,116, 0,109, 97,120,110, 97,109,101,108,101,110, 0,
- 99,111,108,108,117,109,115, 0, 42,108,105, 98,102,105,108,101,100, 97,116, 97, 0,114,101,116,118, 97,108, 0,109,101,110,117,
- 0, 97, 99,116, 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,112,117,112,109,101,110,117, 0,111,111,112,115,
- 0,118,105,115,105,102,108, 97,103, 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,100,101,112,
-115, 95,102,108, 97,103,115, 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,115,104,111,119,115,112, 97,114,101, 0, 99,101,110,116,120, 0, 99,101,110,116,121, 0, 42,105,110,102,
-111, 95,115,116,114, 0, 42,105,110,102,111, 95,115,112, 97,114,101, 0, 42,115,112, 97,114,101, 0, 42,116,101,120,116, 0,116,
-111,112, 0,118,105,101,119,108,105,110,101,115, 0,102,111,110,116, 95,105,100, 0,108,104,101,105,103,104,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, 99,117,114,114,116, 97, 98, 95,
-115,101,116, 0,115,104,111,119,115,121,110,116, 97,120, 0,117,110,117,115,101,100, 95,112, 97,100,100, 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, 42,115, 99,114,105,112,116,
- 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, 42,101,100,
-105,116,116,114,101,101, 0,116,114,101,101,116,121,112,101, 0,116,105,116,108,101, 91, 50, 56, 93, 0,102, 97,115,101, 0,115,
-117, 98,102, 97,115,101, 0,109,111,117,115,101, 95,109,111,118,101, 95,114,101,100,114, 97,119, 0,105,109, 97,102, 97,115,101,
- 0,109,120, 0,109,121, 0,100,105,114,115,108,105, 0,100,105,114,115,108,105, 95,108,105,110,101,115, 0,100,105,114,115,108,
-105, 95,115,120, 0,100,105,114,115,108,105, 95,101,121, 0,100,105,114,115,108,105, 95,101,120, 0,100,105,114,115,108,105, 95,
-104, 0,105,109, 97,115,108,105, 0,102,105,108,101,115,101,108,109,101,110,117,105,116,101,109, 0,105,109, 97,115,108,105, 95,
-115,120, 0,105,109, 97,115,108,105, 95,101,121, 0,105,109, 97,115,108,105, 95,101,120, 0,105,109, 97,115,108,105, 95,104, 0,
-100,115,115,120, 0,100,115,115,121, 0,100,115,101,120, 0,100,115,101,121, 0,100,101,115,120, 0,100,101,115,121, 0,100,101,
-101,120, 0,100,101,101,121, 0,102,115,115,120, 0,102,115,115,121, 0,102,115,101,120, 0,102,115,101,121, 0,100,115,100,104,
- 0,102,115,100,104, 0,102,101,115,120, 0,102,101,115,121, 0,102,101,101,120, 0,102,101,101,121, 0,105,110,102,115,120, 0,
-105,110,102,115,121, 0,105,110,102,101,120, 0,105,110,102,101,121, 0,100,110,115,120, 0,100,110,115,121, 0,100,110,119, 0,
-100,110,104, 0,102,110,115,120, 0,102,110,115,121, 0,102,110,119, 0,102,110,104, 0,102,111,108,101, 91, 49, 50, 56, 93, 0,
-100,111,114, 91, 49, 50, 56, 93, 0,102,105,108,101, 91, 49, 50, 56, 93, 0,100,105,114, 91, 49, 50, 56, 93, 0, 42,102,105,114,
-115,116,100,105,114, 0, 42,102,105,114,115,116,102,105,108,101, 0,116,111,112,100,105,114, 0,116,111,116, 97,108,100,105,114,
-115, 0,104,105,108,105,116,101, 0,116,111,112,102,105,108,101, 0,116,111,116, 97,108,102,105,108,101,115, 0,105,109, 97,103,
-101, 95,115,108,105,100,101,114, 0,115,108,105,100,101,114, 95,104,101,105,103,104,116, 0,115,108,105,100,101,114, 95,115,112,
- 97, 99,101, 0,116,111,112,105,109, 97, 0,116,111,116, 97,108,105,109, 97, 0, 99,117,114,105,109, 97,120, 0, 99,117,114,105,
-109, 97,121, 0, 42,102,105,114,115,116, 95,115,101,108, 95,105,109, 97, 0, 42,104,105,108,105,116,101, 95,105,109, 97, 0,116,
-111,116, 97,108, 95,115,101,108,101, 99,116,101,100, 0,105,109, 97, 95,114,101,100,114, 97,119, 0, 42, 99,109, 97,112, 0,111,
-117,116,108,105,110,101, 91, 52, 93, 0,110,101,117,116,114, 97,108, 91, 52, 93, 0, 97, 99,116,105,111,110, 91, 52, 93, 0,115,
-101,116,116,105,110,103, 91, 52, 93, 0,115,101,116,116,105,110,103, 49, 91, 52, 93, 0,115,101,116,116,105,110,103, 50, 91, 52,
- 93, 0,110,117,109, 91, 52, 93, 0,116,101,120,116,102,105,101,108,100, 91, 52, 93, 0,116,101,120,116,102,105,101,108,100, 95,
-104,105, 91, 52, 93, 0,112,111,112,117,112, 91, 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52,
- 93, 0,109,101,110,117, 95, 98, 97, 99,107, 91, 52, 93, 0,109,101,110,117, 95,105,116,101,109, 91, 52, 93, 0,109,101,110,117,
- 95,104,105,108,105,116,101, 91, 52, 93, 0,109,101,110,117, 95,116,101,120,116, 91, 52, 93, 0,109,101,110,117, 95,116,101,120,
-116, 95,104,105, 91, 52, 93, 0, 98,117,116, 95,100,114, 97,119,116,121,112,101, 0,105, 99,111,110,102,105,108,101, 91, 56, 48,
- 93, 0, 98, 97, 99,107, 91, 52, 93, 0,104,101, 97,100,101,114, 91, 52, 93, 0,112, 97,110,101,108, 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,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, 98,112, 97,100, 49, 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, 98,112, 97,100, 91, 52, 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,118,114,109,108,102,108, 97,103, 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, 99,111,110,115,111,108,101, 95, 98,117,102,102,101,114, 0, 99,111,110,115,111,108,101, 95,111,117,116,
- 0,109,105,120, 98,117,102,115,105,122,101, 0,102,111,110,116,115,105,122,101, 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,102,111,110,116,110, 97,109,101, 91, 50, 53, 54, 93, 0,116,104,101,109,101,115, 0,117,110,100,111,115,
-116,101,112,115, 0, 99,117,114,115,115,105,122,101, 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,109,101,109, 99, 97, 99,104,101,108,105,109,
-105,116, 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,
-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,
-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,115, 99,101,110,
-101, 0,101,110,100,120, 0,101,110,100,121, 0,115,105,122,101,120, 0,115,105,122,101,121, 0,115, 99,101,110,101,110,114, 0,
-115, 99,114,101,101,110,110,114, 0,102,117,108,108, 0,109, 97,105,110,119,105,110, 0,119,105,110, 97,107,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,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, 99,111,110,116,114,111,108, 0,115,110, 97,112, 0,111,108,100, 95,111,102,115,120,
- 0,111,108,100, 95,111,102,115,121, 0,115,111,114,116, 99,111,117,110,116,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0,
- 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,108, 0,119,105,110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,104,101, 97,100,114,
- 99,116, 0,119,105,110,114, 99,116, 0,104,101, 97,100,119,105,110, 0,119,105,110, 0,104,101, 97,100,101,114,116,121,112,101,
- 0, 98,117,116,115,112, 97, 99,101,116,121,112,101, 0,119,105,110,120, 0,119,105,110,121, 0,104,101, 97,100, 95,115,119, 97,
-112, 0,104,101, 97,100, 95,101,113,117, 97,108, 0,119,105,110, 95,115,119, 97,112, 0,119,105,110, 95,101,113,117, 97,108, 0,
-104,101, 97,100, 98,117,116,108,101,110, 0,104,101, 97,100, 98,117,116,111,102,115, 0, 99,117,114,115,111,114, 0,115,112, 97,
- 99,101,100, 97,116, 97, 0,117,105, 98,108,111, 99,107,115, 0,112, 97,110,101,108,115, 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,100,105,115,112,108, 97,121,109,111,100,101, 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,115,101, 49, 0, 42,115,101, 50, 0, 42,115,101, 51, 0,110,114, 0,100,
-111,110,101, 0, 42,115,116,114,105,112,100, 97,116, 97, 0,111,114,120, 0,111,114,121, 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,110,101,119,115,101,113, 0,115,116, 97,114,116,111,102,115, 0,101,110,100,111,102,115, 0,115,116, 97,
-114,116,115,116,105,108,108, 0,101,110,100,115,116,105,108,108, 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,109,117,108, 0,104, 97,110,100,115,105,122,101, 0, 42,115,116,114,105,112, 0, 42,
- 99,117,114,101,108,101,109, 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, 99,117,114,112,111,115, 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,112,114,101,115,101,101,107, 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,101,100,103,101, 87,105,100,116,104, 0, 97,
-110,103,108,101, 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, 42,102,114, 97,109,101, 77, 97,112, 0,103,108,111, 98, 97,108, 83,112,101,101,100,
- 0, 98,117,116,116,121,112,101, 0,117,115,101,114,106,105,116, 0,115,116, 97, 0,101,110,100, 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,100,120, 0,100,121, 0,108,105,110,107, 0,111,116,121,112,101, 0,111,108,100, 0, 42,
-112,111,105,110, 0, 42,111,108,100,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,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,100,101,108, 97,121, 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,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,105,110,118,101,114,116, 0,102,114,101,113, 50, 0, 97,120,105,115,102, 0, 98,117,116,116,111,
-110, 0, 98,117,116,116,111,110,102, 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, 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,116,105,109,101, 0, 42, 97, 99,116, 0, 98,108,101,110,100,105,110, 0,112,114,
-105,111,114,105,116,121, 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,118,111,108,117,109,101, 0, 42,109,101, 0,108,105,110, 86,101,108,111, 99,
-105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 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, 98,117,116,115,116, 97, 0, 98,117,116,101,110,100, 0,109,105,110, 0,
-102, 97, 99, 0,118,105,115,105,102, 97, 99, 0,115,108,111,119, 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,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,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,114,111,116,100, 97,109,112, 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,108, 97,109,112,114,101,110, 0,103,111, 98,106,101, 99,116, 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, 52, 93, 91, 52, 93, 0,120,119,105,100,116,104, 0,122,119,105,100,116,104, 0,101, 97,115,
-101, 49, 0,101, 97,115,101, 50, 0,114, 97,100, 95,104,101, 97,100, 0,114, 97,100, 95,116, 97,105,108, 0, 98,111,110,101, 98,
- 97,115,101, 0, 99,104, 97,105,110, 98, 97,115,101, 0,112, 97,116,104,102,108, 97,103, 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, 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, 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, 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,114,101,115,101,114,118,101,100, 49, 0, 97,117,116,111,115,110, 97,112, 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,110, 97,109,101, 91, 51, 48,
- 93, 0,101,110,102,111,114, 99,101, 0, 42,116, 97,114, 0,105,116,101,114, 97,116,105,111,110,115, 0,114,111,111,116, 98,111,
-110,101, 0,115,117, 98,116, 97,114,103,101,116, 91, 51, 50, 93, 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, 50, 0,109,105,110,109, 97,120,102,108, 97,103,
- 0,115,116,105, 99,107,121, 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,122,109,105,110, 0,122,109, 97,120, 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, 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,114,101,112,101, 97,
-116, 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,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,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,110,101,101,100, 95,101,120,101, 99, 0,101,120,101, 99, 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, 42,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, 42, 42, 97,108,108,116,121,112,101,115, 0,
- 42,111,119,110,116,121,112,101, 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, 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, 98,111,107,101,104, 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, 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,112,114,101,118,105,101,119, 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,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,111,102,102,115,101,116, 91, 50, 93, 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, 99,108,111,110,101, 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, 0, 0, 0, 84, 89, 80, 69, 0, 0, 1, 24, 99,104, 97,114, 0,117, 99,104,
+ 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,111,108, 91, 51, 93, 0,102,114, 97,109,101, 0,110, 97,
+109,101, 91, 54, 52, 93, 0, 42, 98,114,117,115,104, 0,116,111,111,108, 0,115,116,101,112, 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,110, 97,109,101,
+ 91, 51, 54, 93, 0,109, 97,116, 91, 51, 93, 91, 51, 93, 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,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,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, 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,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,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,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,112, 97,
+100, 51, 91, 53, 93, 0,100,105,114, 0,118,105,101,119, 0, 42,115,101,115,115,105,111,110, 0, 42, 99,117,109, 97,112, 0,100,
+114, 97,119, 98,114,117,115,104, 0,115,109,111,111,116,104, 98,114,117,115,104, 0,112,105,110, 99,104, 98,114,117,115,104, 0,
+105,110,102,108, 97,116,101, 98,114,117,115,104, 0,103,114, 97, 98, 98,114,117,115,104, 0,108, 97,121,101,114, 98,114,117,115,
+104, 0,102,108, 97,116,116,101,110, 98,114,117,115,104, 0, 98,114,117,115,104, 95,116,121,112,101, 0,116,101,120,110,114, 0,
+116,101,120,114,101,112,116, 0,116,101,120,102, 97,100,101, 0,116,101,120,115,101,112, 0, 97,118,101,114, 97,103,105,110,103,
+ 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,115,121,109,
+109, 0,114, 97,107,101, 0,112, 97,100, 91, 55, 93, 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, 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,101,100,105,116, 98,117,116,115,105,122,101,
+ 0,115,101,108,101, 99,116,109,111,100,101, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 0,112,114,111,112, 95,109,111,
+100,101, 0, 97,117,116,111,109,101,114,103,101, 0,112, 97,100, 54, 0,112, 97,100, 55, 0, 42,101,100, 0, 42,114, 97,100,105,
+111, 0,102,114, 97,109,105,110,103, 0, 42,116,111,111,108,115,101,116,116,105,110,103,115, 0, 97,117,100,105,111, 0,109, 97,
+114,107,101,114,115, 0,116,114, 97,110,115,102,111,114,109, 95,115,112, 97, 99,101,115, 0,106,117,109,112,102,114, 97,109,101,
+ 0,115,110, 97,112, 95,102,108, 97,103, 0,115,110, 97,112, 95,116, 97,114,103,101,116, 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,115, 99,117,108,112,116,100, 97,116, 97, 0,122,111,
+111,109, 0, 98,108,101,110,100, 0,120,105,109, 0,121,105,109, 0,115,112, 97, 99,101,116,121,112,101, 0, 98,108,111, 99,107,
+115, 99, 97,108,101, 0, 42, 97,114,101, 97, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 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,119,105,110,109, 97,116, 49, 91, 52, 93, 91, 52,
+ 93, 0,118,105,101,119,109, 97,116, 49, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,122,102, 97,
+ 99, 0,112,101,114,115,112, 0, 42,111, 98, 95, 99,101,110,116,114,101, 0, 42, 98,103,112,105, 99, 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,111, 98, 95, 99,101,110,116,114,101, 95, 98,111,110,101, 91, 51, 50, 93, 0,108,111, 99, 97,108,118,105,101,119, 0,108, 97,
+121, 97, 99,116, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0, 99, 97,109,122,111,111,109, 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,105,120,115,105,122,101, 0,110,
+101, 97,114, 0,102, 97,114, 0, 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,103,114,105,100,108,105,110,101,115, 0,118,105,
+101,119, 98,117,116, 0,103,114,105,100,102,108, 97,103, 0,109,111,100,101,115,101,108,101, 99,116, 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,116,119,109, 97,116, 91,
+ 52, 93, 91, 52, 93, 0, 99,108,105,112, 91, 52, 93, 91, 52, 93, 0, 42, 99,108,105,112, 98, 98, 0, 97,102,116,101,114,100,114,
+ 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 0,102,108, 97,103, 50, 0,103,114,105,100,115,117, 98,100,105,118, 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,107,101,101,112,116,111,116, 0,107,101,101,112, 97,115,112,101, 99,116, 0,107,101,101,112,122,111,111,109,
+ 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,114,111,119, 98,117,
+116, 0,118, 50,100, 0, 42,101,100,105,116,105,112,111, 0,105,112,111,107,101,121, 0, 97, 99,116,110, 97,109,101, 91, 51, 50,
+ 93, 0, 99,111,110,115,116,110, 97,109,101, 91, 51, 50, 93, 0, 98,111,110,101,110, 97,109,101, 91, 51, 50, 93, 0,116,111,116,
+105,112,111, 0,112,105,110, 0, 98,117,116,111,102,115, 0, 99,104, 97,110,110,101,108, 0,108,111, 99,107, 0,109,101,100,105,
+ 97,110, 91, 51, 93, 0, 99,117,114,115,101,110,115, 0, 99,117,114, 97, 99,116, 0, 97,108,105,103,110, 0,116, 97, 98,111, 0,
+109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0, 42,108,111, 99,107,112,111,105,110, 0,116,101,120,102,114,111,109, 0,115,
+104,111,119,103,114,111,117,112, 0,109,111,100,101,108,116,121,112,101, 0,115, 99,114,105,112,116, 98,108,111, 99,107, 0,114,
+101, 95, 97,108,105,103,110, 0,111,108,100,107,101,121,112,114,101,115,115, 0,116, 97, 98, 91, 55, 93, 0, 99,104, 97,110,115,
+104,111,119,110, 0,122,101, 98,114, 97, 0, 42,102,105,108,101,108,105,115,116, 0,116,111,116,102,105,108,101, 0,116,105,116,
+108,101, 91, 50, 52, 93, 0,100,105,114, 91, 49, 54, 48, 93, 0,102,105,108,101, 91, 56, 48, 93, 0,111,102,115, 0,115,111,114,
+116, 0,109, 97,120,110, 97,109,101,108,101,110, 0, 99,111,108,108,117,109,115, 0,102, 95,102,112, 0,102,112, 95,115,116,114,
+ 91, 56, 93, 0, 42,108,105, 98,102,105,108,101,100, 97,116, 97, 0,114,101,116,118, 97,108, 0,109,101,110,117, 0, 97, 99,116,
+ 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,112,117,112,109,101,110,117, 0,111,111,112,115, 0,118,105,115,
+105,102,108, 97,103, 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,100,101,112,115, 95,102,108,
+ 97,103,115, 0,102,105,108,116,101,114, 95, 97,108,108, 91, 51, 50, 93, 0,102,105,108,116,101,114, 95, 99,117,114, 91, 51, 50,
+ 93, 0,102,105,108,116,101,114, 95, 97, 99,116, 91, 51, 50, 93, 0,102,105,108,116,101,114, 95,115,101,108, 91, 51, 50, 93, 0,
+102,105,108,116,101,114, 95,108,105, 98, 91, 51, 50, 93, 0,102,105,108,116,101,114, 95,103,114,112, 91, 51, 50, 93, 0,102,105,
+108,116,101,114, 95,101,110, 97, 98,108,101, 0,105,109, 97,110,114, 0, 99,117,114,116,105,108,101, 0,105,109,116,121,112,101,
+110,114, 0,115,104,111,119,115,112, 97,114,101, 0,100,116, 95,117,118, 0,115,116,105, 99,107,121, 0, 99,101,110,116,120, 0,
+ 99,101,110,116,121, 0, 42,105,110,102,111, 95,115,116,114, 0, 42,105,110,102,111, 95,115,112, 97,114,101, 0, 42,115,112, 97,
+114,101, 0, 97,117,116,111,115,110, 97,112, 0, 42,116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 0,
+102,111,110,116, 95,105,100, 0,108,104,101,105,103,104,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, 99,117,114,114,116, 97, 98, 95,115,101,116, 0,115,104,111,119,115,121,110,116, 97,
+120, 0,117,110,117,115,101,100, 95,112, 97,100,100, 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, 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, 42,101,100,105,116,116,
+114,101,101, 0,116,114,101,101,116,121,112,101, 0, 42,102,105,108,101,115, 0, 97, 99,116,105,118,101, 95,102,105,108,101, 0,
+110,117,109,116,105,108,101,115,120, 0,110,117,109,116,105,108,101,115,121, 0,115,101,108,115,116, 97,116,101, 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, 97, 99,116,105,118,101, 95, 98,111,111,107,
+109, 97,114,107, 0,112,114,118, 95,119, 0,112,114,118, 95,104, 0, 42,105,109,103, 0,111,117,116,108,105,110,101, 91, 52, 93,
+ 0,110,101,117,116,114, 97,108, 91, 52, 93, 0, 97, 99,116,105,111,110, 91, 52, 93, 0,115,101,116,116,105,110,103, 91, 52, 93,
+ 0,115,101,116,116,105,110,103, 49, 91, 52, 93, 0,115,101,116,116,105,110,103, 50, 91, 52, 93, 0,110,117,109, 91, 52, 93, 0,
+116,101,120,116,102,105,101,108,100, 91, 52, 93, 0,116,101,120,116,102,105,101,108,100, 95,104,105, 91, 52, 93, 0,112,111,112,
+117,112, 91, 52, 93, 0,116,101,120,116, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,109,101,110,117, 95, 98, 97,
+ 99,107, 91, 52, 93, 0,109,101,110,117, 95,105,116,101,109, 91, 52, 93, 0,109,101,110,117, 95,104,105,108,105,116,101, 91, 52,
+ 93, 0,109,101,110,117, 95,116,101,120,116, 91, 52, 93, 0,109,101,110,117, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0, 98,
+117,116, 95,100,114, 97,119,116,121,112,101, 0,105, 99,111,110,102,105,108,101, 91, 56, 48, 93, 0, 98, 97, 99,107, 91, 52, 93,
+ 0,104,101, 97,100,101,114, 91, 52, 93, 0,112, 97,110,101,108, 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,112, 97,100, 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,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, 97,114,109, 91, 50, 48, 93, 0, 98,112, 97,100, 91, 52, 93, 0, 98,112,
+ 97,100, 49, 91, 52, 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,118,114,109,108,102,108, 97,103, 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, 99,111,110,115,111,108,101, 95, 98,117,102,102,101,
+114, 0, 99,111,110,115,111,108,101, 95,111,117,116, 0,109,105,120, 98,117,102,115,105,122,101, 0,102,111,110,116,115,105,122,
+101, 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,102,111,110,116,110, 97,109,101, 91, 50, 53, 54, 93,
+ 0,116,104,101,109,101,115, 0,117,110,100,111,115,116,101,112,115, 0, 99,117,114,115,115,105,122,101, 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,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,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,109,111,100,101, 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,115, 99,101,110,101, 0,101,110,100,120, 0,101,110,100,121, 0,
+115,105,122,101,120, 0,115,105,122,101,121, 0,115, 99,101,110,101,110,114, 0,115, 99,114,101,101,110,110,114, 0,102,117,108,
+108, 0,109, 97,105,110,119,105,110, 0,119,105,110, 97,107,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,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, 99,
+111,110,116,114,111,108, 0,115,110, 97,112, 0,111,108,100, 95,111,102,115,120, 0,111,108,100, 95,111,102,115,121, 0,115,111,
+114,116, 99,111,117,110,116,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117,108,
+108, 0,119,105,110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,104,101, 97,100,114, 99,116, 0,119,105,110,114, 99,116, 0,104,101,
+ 97,100,119,105,110, 0,119,105,110, 0,104,101, 97,100,101,114,116,121,112,101, 0, 98,117,116,115,112, 97, 99,101,116,121,112,
+101, 0,119,105,110,120, 0,119,105,110,121, 0,104,101, 97,100, 95,115,119, 97,112, 0,104,101, 97,100, 95,101,113,117, 97,108,
+ 0,119,105,110, 95,115,119, 97,112, 0,119,105,110, 95,101,113,117, 97,108, 0,104,101, 97,100, 98,117,116,108,101,110, 0,104,
+101, 97,100, 98,117,116,111,102,115, 0, 99,117,114,115,111,114, 0,115,112, 97, 99,101,100, 97,116, 97, 0,117,105, 98,108,111,
+ 99,107,115, 0,112, 97,110,101,108,115, 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,100,
+105,115,112,108, 97,121,109,111,100,101, 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,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,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,109,117,108, 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, 99,117,114,112,111,
+115, 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,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,101,110,100, 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,100,120, 0,100,121, 0,
+108,105,110,107, 0,111,116,121,112,101, 0,111,108,100, 0, 42,112,111,105,110, 0, 42,111,108,100,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,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,100,101,108, 97,121, 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,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,102,114,101,113, 50, 0, 97,120,
+105,115,102, 0, 98,117,116,116,111,110, 0, 98,117,116,116,111,110,102, 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, 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, 42, 97, 99,116, 0, 98,108,101,110,100,105,
+110, 0,112,114,105,111,114,105,116,121, 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,118,111,108,117,109,101, 0, 42,109,101, 0,108,105,110, 86,
+101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 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, 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,115,108,111,119, 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,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,114,111,116,100, 97,109,
+112, 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,108, 97,109,112,114,101,110, 0,103,111, 98,106,101, 99,116, 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, 52,
+ 93, 91, 52, 93, 0,120,119,105,100,116,104, 0,122,119,105,100,116,104, 0,101, 97,115,101, 49, 0,101, 97,115,101, 50, 0,114,
+ 97,100, 95,104,101, 97,100, 0,114, 97,100, 95,116, 97,105,108, 0, 98,111,110,101, 98, 97,115,101, 0, 99,104, 97,105,110, 98,
+ 97,115,101, 0,112, 97,116,104,102,108, 97,103, 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, 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, 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, 42,103,114,112, 0,114,101,
+115,101,114,118,101,100, 49, 0,103,114,111,117,112,115, 0, 97, 99,116,105,118,101, 95,109, 97,114,107,101,114, 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,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, 42,112,114,111,112, 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, 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, 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, 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,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,110,101,101,100, 95,101,120,101, 99, 0,101,120,101, 99, 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, 42,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, 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,112,114,101,118,105,101,119, 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,
+105,110,110,101,114,114, 97,100,105,117,115, 0,114, 97,116,101, 0,114,103, 98, 91, 51, 93, 0, 99,108,111,110,101, 0, 97, 99,
+116,105,118,101, 95,114,110,100, 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,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,
+115,116, 97,116,101, 0, 42,104, 97,105,114, 0,105, 95,114,111,116, 91, 52, 93, 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, 98, 97,110,107, 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,100,
+105,115,116,114, 0,112,104,121,115,116,121,112,101, 0,114,111,116,109,111,100,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,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,110, 98,101,116,119,101,
+101,110, 0, 98,111,105,100,110,101,105,103,104, 98,111,117,114,115, 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,107,101,121,101,100, 95,116,105,109,101, 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, 97,
+ 98,115,108,101,110,103,116,104, 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,
+104,105,108,100,115,112,114,101, 97,100, 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, 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,109, 97,120, 95,118,101,108, 0,109, 97,120, 95,108, 97,116, 95, 97, 99, 99, 0,109, 97,120, 95,116, 97,110, 95,
+ 97, 99, 99, 0, 97,118,101,114, 97,103,101, 95,118,101,108, 0, 98, 97,110,107,105,110,103, 0,109, 97,120, 95, 98, 97,110,107,
+ 0,103,114,111,117,110,100,122, 0, 98,111,105,100,102, 97, 99, 91, 56, 93, 0, 98,111,105,100,114,117,108,101, 91, 56, 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, 97,114,116, 0,
+ 42,101,100,105,116, 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, 42,
+116, 97,114,103,101,116, 95,111, 98, 0, 42,107,101,121,101,100, 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,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,
+107,101,121,101,100, 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, 49, 93, 0,118,103, 95,110,101,103,
+ 0,114,116, 51, 91, 50, 93, 0, 42,114,101,110,100,101,114,100, 97,116, 97, 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,114,111,108,108, 0, 67,100,105,115, 0, 67,118,105, 0,115,
+116,101,112,115, 80,101,114, 70,114, 97,109,101, 0, 91, 51, 93, 0,117,102,108,117,105,100, 0,115,116,114,117, 99,116,117,114,
+ 97,108, 0, 98,101,110,100,105,110,103, 0,115,105,109, 95,116,105,109,101, 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,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, 42, 99, 97, 99,104,101, 0,109,
+ 97,120,115,112,114,105,110,103,108,101,110, 0,102,105,114,115,116,102,114, 97,109,101, 0,108, 97,115,116, 99, 97, 99,104,101,
+100,102,114, 97,109,101, 0,101,100,105,116,101,100,102,114, 97,109,101, 0, 97,117,116,111,112,114,111,116,101, 99,116, 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,102,105,114,
+115,116, 99, 97, 99,104,101,100,102,114, 97,109,101, 0, 97,118,103, 95,115,112,114,105,110,103, 95,108,101,110, 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, 95,108,111,111,112, 95, 99,111,117,
+110,116, 0,108,111,111,112, 95, 99,111,117,110,116, 0, 42, 99,111,108,108,105,115,105,111,110, 95,108,105,115,116, 0,115,101,
+108,102,101,112,115,105,108,111,110, 0, 42,115,112,114,105,110,103,115, 0,110,117,109,115,112,114,105,110,103,115, 0,111,108,
+100, 95,115,111,108,118,101,114, 95,116,121,112,101, 0, 42,105,109,112,108,105, 99,105,116, 0, 42,105,109,112,108,105, 99,105,
+116, 69, 77, 0, 42,101,100,103,101,104, 97,115,104, 0, 0, 0, 84, 89, 80, 69, 74, 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,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, 73,112,111, 0, 75,101,121, 66,108,111, 99,107, 0,
- 75,101,121, 0, 83, 99,114,105,112,116, 76,105,110,107, 0, 84,101,120,116, 76,105,110,101, 0, 84,101,120,116, 0, 80, 97, 99,
-107,101,100, 70,105,108,101, 0, 67, 97,109,101,114, 97, 0, 80,114,101,118,105,101,119, 73,109, 97,103,101, 0, 73,109, 97,103,
-101, 85,115,101,114, 0, 73,109, 97,103,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, 79, 98,106,101, 99,116, 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, 84,101,120, 77, 97,112,112,105,110,103,
- 0, 76, 97,109,112, 0, 87, 97,118,101, 0, 77, 97,116,101,114,105, 97,108, 0, 98, 78,111,100,101, 84,114,101,101, 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, 66,101,122, 84,114,105,112,108,101, 0, 66, 80,111,105,110,116, 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, 73,112,111, 68,114,105,118,101,114, 0, 73,112,111, 67,117,114,118,101, 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, 79, 99, 73,110,102,111, 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,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,117,108,116,105,114,101,115,
- 77, 97,112, 78,111,100,101, 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, 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, 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, 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, 77,111,100,105,102,105,101,114, 68, 97,116,
- 97, 0, 72,111,111,107, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,111,102,116, 98,111,100,121, 77,111,100,105,102,
-105,101,114, 68, 97,116, 97, 0, 66,111,111,108,101, 97,110, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 68,105,115,107,
- 65, 79, 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, 76, 66,117,102, 0, 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 80, 97,114,116, 68,101,102,108,101,
- 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 70,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 68,101,114,
-105,118,101,100, 77,101,115,104, 0, 79, 98, 72,111,111,107, 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, 82, 97,
-100,105,111, 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, 71,
- 97,109,101, 70,114, 97,109,105,110,103, 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, 84,111,111,108, 83,101,116,116,105,110,103,115, 0, 66,114,117,115,
-104, 68, 97,116, 97, 0, 83, 99,117,108,112,116, 68, 97,116, 97, 0, 83, 99,117,108,112,116, 83,101,115,115,105,111,110, 0, 83,
- 99,101,110,101, 0, 68, 97,103, 70,111,114,101,115,116, 0, 66, 71,112,105, 99, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,
-101, 76,105,110,107, 0, 83, 99,114, 65,114,101, 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, 86,105,101,119, 50, 68, 0, 83,112, 97, 99,101, 73,
-110,102,111, 0, 83,112, 97, 99,101, 73,112,111, 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0,
- 83,112, 97, 99,101, 70,105,108,101, 0,100,105,114,101,110,116,114,121, 0, 66,108,101,110,100, 72, 97,110,100,108,101, 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, 67,117,114,118,101, 77, 97,112,112,105,110,103, 0, 83,112, 97, 99,101, 78,108,
- 97, 0, 83,112, 97, 99,101, 84,101,120,116, 0, 83,112, 97, 99,101, 83, 99,114,105,112,116, 0, 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, 73,109, 97, 83,101,108, 0, 73,
-109, 97, 68,105,114, 0, 79,110,101, 83,101,108,101, 99,116, 97, 98,108,101, 73,109, 97, 0, 84,104,101,109,101, 85, 73, 0, 84,
-104,101,109,101, 83,112, 97, 99,101, 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, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69,100,103,101, 0, 80, 97,110,101,
-108, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,112, 69,108,101,109, 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, 69,100,105,116,105,110,103, 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, 79,111,112,115, 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, 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, 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, 67,104, 97,110,110,101,108, 0, 83,112, 97, 99,101, 65, 99,116,105,111,110, 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, 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, 68,105,115,116, 97,110, 99,101, 76,105,109,105,116, 67,111,110,115,116,114, 97,
-105,110,116, 0, 98, 82,111,116, 97,116,105,111,110, 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, 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,
+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, 0, 75,101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 83, 99,114,105,112,116,
+ 76,105,110,107, 0, 84,101,120,116, 76,105,110,101, 0, 84,101,120,116, 0, 80, 97, 99,107,101,100, 70,105,108,101, 0, 67, 97,
+109,101,114, 97, 0, 79, 98,106,101, 99,116, 0, 73,109, 97,103,101, 85,115,101,114, 0, 73,109, 97,103,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, 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, 98, 78,111,100,101, 84,114,101,101, 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, 66,101,122, 84,114,105,112,108,101, 0, 66, 80,111,105,110,116, 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, 73,112,111, 68,114,105,118,101,114,
+ 0, 73,112,111, 67,117,114,118,101, 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, 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, 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,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,117,108,116,105,114,101,115, 77, 97,112, 78,111,100,101, 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, 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, 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, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 72,111,111,107, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0,
+ 83,111,102,116, 98,111,100,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 67,108,111,116,104, 77,111,100,105,102,105,
+101,114, 68, 97,116, 97, 0, 67,108,111,116,104, 0, 83,105,109,117,108, 97,116,105,111,110, 83,101,116,116,105,110,103,115, 0,
+ 67,111,108,108,105,115,105,111,110, 83,101,116,116,105,110,103,115, 0, 67,111,108,108,105,115,105,111,110, 77,111,100,105,102,
+105,101,114, 68, 97,116, 97, 0, 66, 86, 72, 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, 68,101,114,105,118,101,100, 77,
+101,115,104, 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, 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, 80, 97,114,116, 68,101,102,108,
+101, 99,116, 0, 83,111,102,116, 66,111,100,121, 0, 70,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 79, 98,
+ 72,111,111,107, 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, 82, 97,100,105,111, 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, 71, 97,109,101, 70,114, 97,109,105,110,103, 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,
+ 84,111,111,108, 83,101,116,116,105,110,103,115, 0, 66,114,117,115,104, 68, 97,116, 97, 0, 83, 99,117,108,112,116, 68, 97,116,
+ 97, 0, 83, 99,117,108,112,116, 83,101,115,115,105,111,110, 0, 83, 99,101,110,101, 0, 68, 97,103, 70,111,114,101,115,116, 0,
+ 66, 71,112,105, 99, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,101, 76,105,110,107, 0, 83, 99,114, 65,114,101, 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, 86,105,101,119, 50, 68, 0, 83,112, 97, 99,101, 73,110,102,111, 0, 83,112, 97, 99,101, 73,112,111, 0, 83,112,
+ 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 83,112, 97, 99,101, 70,105,108,101, 0,100,105,114,101,110,
+116,114,121, 0, 66,108,101,110,100, 72, 97,110,100,108,101, 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,112, 97, 99,101, 83, 99,114,105,112,116, 0, 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, 73,109, 97, 83,
+101,108, 0, 70,105,108,101, 76,105,115,116, 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, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69,100,103,101, 0,
+ 80, 97,110,101,108, 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, 69,100,105,116,105,110,103, 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, 79,
+111,112,115, 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, 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, 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,
+ 98, 65, 99,116,105,111,110, 67,104, 97,110,110,101,108, 0, 83,112, 97, 99,101, 65, 99,116,105,111,110, 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, 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, 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, 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, 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, 0, 84, 76, 69, 78, 0, 1, 0, 1,
- 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 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, 2, 40, 0, 0, 0, 84, 0,104, 0,120, 0, 16, 0, 24,
- 0,104, 0, 20, 0,128, 0, 12, 0, 32, 1,116, 0, 0, 0, 0, 0,120, 3, 16, 1, 0, 1, 84, 0, 24, 3, 8, 0,168, 0, 0,
- 0,132, 1, 0, 0, 56, 1,184, 0,108, 0, 68, 1, 68, 0, 0, 0,108, 0,104, 0,136, 0, 56, 0, 36, 0, 56, 0, 8, 0, 16,
- 1, 56, 0, 0, 0,140, 0, 84, 1, 20, 0, 20, 0, 44, 0, 60, 0, 20, 0, 12, 0, 12, 0, 4, 0, 8, 0, 8, 0, 24, 0, 20,
- 0, 60, 0, 32, 0, 8, 0, 16, 0, 64, 0, 28, 0, 12, 0, 52, 0, 0, 0, 52, 0, 68, 0, 88, 0, 96, 0, 68, 0,108, 0, 60,
- 0, 60, 0,108, 0,112, 0, 60, 0, 96, 0, 96, 0,180, 0, 52, 0, 64, 0, 60, 0,116, 0, 40, 0, 12, 0, 60, 0, 40, 0, 44,
- 0,136, 1,132, 0, 0, 0,208, 0, 16, 0, 0, 0, 0, 0, 0, 1, 40, 0, 40, 0, 28, 0,176, 0,144, 0, 48, 0, 16, 0, 64,
- 3, 64, 0, 16, 0, 80, 0, 12, 0,152, 0, 76, 0, 8, 0,108, 0, 0, 4,156, 0, 0, 0, 60, 3, 0, 0, 36, 0,204, 0, 0,
- 0, 0, 0, 0, 0,120, 0, 36, 1, 40, 0,204, 0,180, 1,104, 0, 0, 0, 0, 0,248, 0, 12, 0, 12, 0,248, 1, 0, 0,164,
- 0,120, 0, 32, 0, 0, 0,148, 0,184, 2,224, 0, 0, 0, 0, 0,152, 0,184, 11,144, 0, 56, 8,240, 0,120, 0, 20, 0, 24,
- 0,228, 0, 32, 0,104, 0,196, 1,168, 0,184, 1, 28, 0, 0, 0, 16, 0, 28, 0, 12, 0, 24, 0, 40, 0, 16, 0, 20, 0, 16,
- 0, 24, 1, 56, 0, 0, 0, 56, 0, 44, 0, 64, 0, 48, 0, 8, 0, 44, 0, 72, 0,104, 0, 72, 0, 44, 0, 40, 0,108, 0, 68,
- 0, 76, 0, 80, 0, 64, 0,128, 0, 4, 0, 60, 0, 12, 0, 60, 0, 28, 0, 20, 0, 64, 0, 16, 0, 76, 0,104, 0, 52, 0, 28,
- 0, 56, 0, 60, 0, 56, 0,108, 0,140, 0, 4, 0, 40, 0, 0, 0, 68, 0,160, 0, 24, 1, 4, 0,108, 1, 80, 0, 60, 0,176,
- 0, 44, 0, 52, 0, 68, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 60, 0, 24, 0, 52, 0, 28, 0, 28,
- 0, 28, 0, 96, 0, 52, 0,140, 0, 36, 0,116, 0, 24, 0,164, 0, 0, 0, 0, 0, 16, 0, 24, 0, 12, 1, 16, 0, 40, 0, 64,
- 0, 32, 0, 24, 0, 12, 0, 44, 0, 20, 0, 52, 83, 84, 82, 67, 0, 0, 0,244, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1,
- 0, 11, 0, 2, 0, 9, 0, 2, 0, 9, 0, 3, 0, 12, 0, 2, 0, 2, 0, 4, 0, 2, 0, 5, 0, 13, 0, 2, 0, 4, 0, 4,
- 0, 4, 0, 5, 0, 14, 0, 2, 0, 7, 0, 4, 0, 7, 0, 5, 0, 15, 0, 2, 0, 8, 0, 4, 0, 8, 0, 5, 0, 16, 0, 3,
- 0, 4, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 17, 0, 3, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 18, 0, 3,
- 0, 8, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 19, 0, 4, 0, 4, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7,
- 0, 20, 0, 4, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 21, 0, 4, 0, 8, 0, 4, 0, 8, 0, 5,
- 0, 8, 0, 6, 0, 8, 0, 7, 0, 22, 0, 4, 0, 4, 0, 8, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 23, 0, 4,
- 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 24, 0, 4, 0, 9, 0, 12, 0, 11, 0, 13, 0, 4, 0, 14,
- 0, 4, 0, 15, 0, 25, 0, 10, 0, 25, 0, 0, 0, 25, 0, 1, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 2, 0, 19,
- 0, 24, 0, 20, 0, 4, 0, 21, 0, 4, 0, 22, 0, 4, 0, 23, 0, 26, 0, 9, 0, 9, 0, 0, 0, 9, 0, 1, 0, 26, 0, 24,
- 0, 27, 0, 25, 0, 0, 0, 26, 0, 2, 0, 27, 0, 2, 0, 19, 0, 4, 0, 28, 0, 25, 0, 29, 0, 27, 0, 8, 0, 26, 0, 30,
- 0, 26, 0, 31, 0, 28, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 4, 0, 35, 0, 4, 0, 15, 0, 27, 0, 36, 0, 29, 0, 6,
- 0, 26, 0, 30, 0, 11, 0, 37, 0, 23, 0, 38, 0, 2, 0, 39, 0, 2, 0, 40, 0, 4, 0, 15, 0, 30, 0, 13, 0, 30, 0, 0,
- 0, 30, 0, 1, 0, 7, 0, 41, 0, 7, 0, 42, 0, 2, 0, 17, 0, 2, 0, 43, 0, 4, 0, 44, 0, 9, 0, 45, 0, 7, 0, 46,
- 0, 0, 0, 16, 0, 0, 0, 47, 0, 7, 0, 48, 0, 7, 0, 49, 0, 31, 0, 12, 0, 26, 0, 30, 0, 30, 0, 50, 0, 0, 0, 51,
- 0, 4, 0, 52, 0, 7, 0, 42, 0, 11, 0, 53, 0, 29, 0, 54, 0, 26, 0, 55, 0, 2, 0, 17, 0, 2, 0, 56, 0, 2, 0, 57,
- 0, 2, 0, 19, 0, 32, 0, 5, 0, 26, 0, 58, 0, 2, 0, 59, 0, 2, 0, 60, 0, 2, 0, 61, 0, 4, 0, 15, 0, 33, 0, 6,
- 0, 33, 0, 0, 0, 33, 0, 1, 0, 0, 0, 62, 0, 0, 0, 63, 0, 4, 0, 21, 0, 4, 0, 64, 0, 34, 0, 13, 0, 26, 0, 30,
- 0, 0, 0, 65, 0, 4, 0, 66, 0, 4, 0, 67, 0, 11, 0, 68, 0, 33, 0, 69, 0, 33, 0, 70, 0, 4, 0, 71, 0, 4, 0, 72,
- 0, 0, 0, 73, 0, 4, 0, 74, 0, 4, 0, 75, 0, 9, 0, 76, 0, 35, 0, 5, 0, 4, 0, 77, 0, 4, 0, 78, 0, 4, 0, 66,
- 0, 4, 0, 15, 0, 9, 0, 45, 0, 36, 0, 19, 0, 26, 0, 30, 0, 2, 0, 17, 0, 2, 0, 19, 0, 7, 0, 79, 0, 7, 0, 80,
- 0, 7, 0, 81, 0, 7, 0, 82, 0, 7, 0, 83, 0, 7, 0, 84, 0, 7, 0, 85, 0, 7, 0, 86, 0, 7, 0, 87, 0, 7, 0, 88,
- 0, 7, 0, 89, 0, 2, 0, 90, 0, 2, 0, 91, 0, 7, 0, 92, 0, 29, 0, 54, 0, 32, 0, 93, 0, 37, 0, 3, 0, 4, 0, 7,
- 0, 4, 0, 94, 0, 4, 0, 95, 0, 38, 0, 12, 0, 4, 0, 96, 0, 4, 0, 97, 0, 4, 0, 98, 0, 4, 0, 99, 0, 2, 0,100,
- 0, 2, 0,101, 0, 2, 0, 19, 0, 2, 0,102, 0, 2, 0,103, 0, 2, 0,104, 0, 2, 0,105, 0, 2, 0,106, 0, 39, 0, 29,
- 0, 26, 0, 30, 0, 0, 0, 33, 0, 11, 0,107, 0, 40, 0,108, 0, 41, 0,109, 0, 2, 0,102, 0, 2, 0, 19, 0, 2, 0,110,
- 0, 2, 0, 17, 0, 2, 0, 15, 0, 2, 0, 80, 0, 4, 0,111, 0, 2, 0,112, 0, 2, 0,113, 0, 2, 0,114, 0, 2, 0,115,
- 0, 2, 0,116, 0, 2, 0,117, 0, 4, 0,118, 0, 4, 0,119, 0, 35, 0,120, 0, 37, 0,121, 0, 7, 0,122, 0, 4, 0,123,
- 0, 2, 0,124, 0, 2, 0,125, 0, 2, 0,126, 0, 2, 0,127, 0, 9, 0,128, 0, 42, 0, 25, 0, 2, 0,129, 0, 2, 0,130,
- 0, 2, 0,131, 0, 2, 0,132, 0, 43, 0,133, 0, 44, 0,134, 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0,137, 0, 0, 0,138,
- 0, 0, 0,139, 0, 7, 0,140, 0, 7, 0,141, 0, 2, 0,142, 0, 2, 0,143, 0, 7, 0,144, 0, 7, 0,145, 0, 7, 0,146,
- 0, 7, 0,147, 0, 7, 0,148, 0, 7, 0,149, 0, 7, 0,150, 0, 7, 0,151, 0, 7, 0,152, 0, 7, 0,153, 0, 45, 0, 15,
- 0, 0, 0,154, 0, 9, 0,155, 0, 0, 0,156, 0, 0, 0,157, 0, 4, 0,158, 0, 4, 0,159, 0, 9, 0,160, 0, 7, 0,161,
- 0, 7, 0,162, 0, 7, 0,163, 0, 4, 0,164, 0, 9, 0,165, 0, 9, 0,166, 0, 4, 0,167, 0, 4, 0, 15, 0, 46, 0, 6,
- 0, 7, 0,144, 0, 7, 0,145, 0, 7, 0,146, 0, 7, 0,168, 0, 7, 0, 41, 0, 4, 0, 38, 0, 47, 0, 5, 0, 2, 0, 19,
- 0, 2, 0, 35, 0, 2, 0, 38, 0, 2, 0,169, 0, 46, 0,163, 0, 48, 0, 17, 0, 43, 0,133, 0, 39, 0,170, 0, 49, 0,171,
- 0, 7, 0,172, 0, 7, 0,173, 0, 2, 0, 17, 0, 2, 0,174, 0, 7, 0, 81, 0, 7, 0, 82, 0, 7, 0,175, 0, 4, 0,176,
- 0, 2, 0,177, 0, 2, 0,178, 0, 4, 0,102, 0, 4, 0,111, 0, 2, 0,179, 0, 2, 0,180, 0, 44, 0, 52, 0, 26, 0, 30,
- 0, 7, 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,187, 0, 7, 0,188,
- 0, 7, 0,189, 0, 7, 0,190, 0, 7, 0,191, 0, 7, 0,192, 0, 7, 0,193, 0, 7, 0,194, 0, 7, 0,195, 0, 7, 0,196,
- 0, 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 2, 0,201, 0, 2, 0,202, 0, 2, 0,203, 0, 2, 0,204,
- 0, 2, 0,205, 0, 2, 0,206, 0, 2, 0,207, 0, 2, 0, 19, 0, 2, 0, 17, 0, 2, 0,174, 0, 7, 0,208, 0, 7, 0,209,
- 0, 7, 0,210, 0, 7, 0,211, 0, 2, 0,212, 0, 2, 0,213, 0, 2, 0,214, 0, 2, 0,100, 0, 4, 0, 21, 0, 4, 0, 97,
- 0, 4, 0, 98, 0, 4, 0, 99, 0, 7, 0,215, 0, 7, 0,216, 0, 7, 0,150, 0, 38, 0,217, 0, 29, 0, 54, 0, 39, 0,170,
- 0, 45, 0,218, 0, 47, 0,219, 0, 48, 0,220, 0, 50, 0, 8, 0, 7, 0,221, 0, 7, 0,222, 0, 7, 0,141, 0, 4, 0, 19,
- 0, 7, 0,223, 0, 7, 0,224, 0, 7, 0,225, 0, 43, 0,226, 0, 51, 0, 52, 0, 26, 0, 30, 0, 2, 0, 17, 0, 2, 0,227,
- 0, 2, 0,143, 0, 2, 0,228, 0, 7, 0,144, 0, 7, 0,145, 0, 7, 0,146, 0, 7, 0,147, 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, 81, 0, 7, 0, 82, 0, 7, 0,236,
- 0, 7, 0,237, 0, 7, 0,238, 0, 2, 0,239, 0, 2, 0,240, 0, 2, 0,241, 0, 2, 0,242, 0, 0, 0,243, 0, 0, 0,244,
- 0, 2, 0,245, 0, 2, 0,246, 0, 2, 0,247, 0, 2, 0,248, 0, 2, 0,249, 0, 7, 0,250, 0, 7, 0,251, 0, 7, 0,252,
- 0, 2, 0,253, 0, 2, 0,254, 0, 4, 0,255, 0, 4, 1, 0, 0, 2, 1, 1, 0, 2, 1, 2, 0, 2, 1, 3, 0, 2, 1, 4,
- 0, 7, 1, 5, 0, 7, 1, 6, 0, 7, 1, 7, 0, 7, 1, 8, 0, 2, 1, 9, 0, 2, 1, 10, 0, 42, 1, 11, 0, 29, 0, 54,
- 0, 32, 0, 93, 0, 52, 0, 2, 0, 26, 0, 30, 0, 29, 0, 54, 0, 53, 0,101, 0, 26, 0, 30, 0, 2, 0,143, 0, 2, 0, 19,
- 0, 7, 0,144, 0, 7, 0,145, 0, 7, 0,146, 0, 7, 1, 12, 0, 7, 1, 13, 0, 7, 1, 14, 0, 7, 1, 15, 0, 7, 1, 16,
- 0, 7, 1, 17, 0, 7, 1, 18, 0, 7, 1, 19, 0, 7, 1, 20, 0, 7, 1, 21, 0, 7, 1, 22, 0, 7, 1, 23, 0, 7, 1, 24,
- 0, 7, 1, 25, 0, 7, 1, 26, 0, 7, 1, 27, 0, 7, 1, 28, 0, 7, 1, 29, 0, 7, 1, 30, 0, 7, 1, 31, 0, 7, 1, 32,
- 0, 7, 1, 33, 0, 7, 1, 34, 0, 7, 1, 35, 0, 7, 1, 36, 0, 7, 1, 37, 0, 7, 1, 38, 0, 2, 1, 39, 0, 2, 1, 40,
- 0, 2, 1, 41, 0, 0, 1, 42, 0, 0, 1, 43, 0, 4, 0,227, 0, 4, 1, 44, 0, 2, 1, 45, 0, 2, 1, 46, 0, 2, 1, 47,
- 0, 2, 1, 48, 0, 7, 1, 49, 0, 7, 1, 50, 0, 7, 1, 51, 0, 7, 1, 52, 0, 7, 1, 53, 0, 7, 1, 54, 0, 7, 1, 55,
- 0, 7, 1, 56, 0, 7, 1, 57, 0, 7, 1, 58, 0, 0, 1, 59, 0, 0, 0,253, 0, 0, 1, 60, 0, 0, 1, 61, 0, 2, 1, 62,
- 0, 2, 1, 63, 0, 2, 1, 64, 0, 2, 1, 65, 0, 2, 1, 66, 0, 2, 1, 67, 0, 7, 1, 68, 0, 7, 1, 69, 0, 7, 1, 70,
- 0, 7, 1, 71, 0, 7, 1, 72, 0, 2, 0,129, 0, 2, 0,130, 0, 47, 1, 73, 0, 47, 1, 74, 0, 0, 1, 75, 0, 0, 1, 76,
- 0, 0, 1, 77, 0, 0, 1, 78, 0, 2, 1, 79, 0, 2, 1, 80, 0, 7, 1, 81, 0, 7, 1, 82, 0, 42, 1, 11, 0, 54, 1, 83,
- 0, 29, 0, 54, 0, 55, 1, 84, 0, 7, 1, 85, 0, 7, 1, 86, 0, 7, 1, 87, 0, 7, 1, 88, 0, 7, 1, 89, 0, 2, 1, 90,
- 0, 2, 1, 91, 0, 7, 1, 92, 0, 7, 1, 93, 0, 7, 1, 94, 0, 7, 1, 95, 0, 7, 1, 96, 0, 4, 1, 97, 0, 4, 1, 98,
- 0, 4, 1, 99, 0, 32, 0, 93, 0, 56, 0, 6, 0, 26, 0, 30, 0, 0, 1,100, 0, 7, 1,101, 0, 7, 0, 15, 0, 57, 0, 45,
- 0, 35, 0,120, 0, 58, 0, 26, 0, 58, 0, 0, 0, 58, 0, 1, 0, 59, 1,102, 0, 4, 1,103, 0, 4, 1,104, 0, 4, 1,105,
- 0, 4, 1,106, 0, 4, 1,107, 0, 4, 1,108, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 1,109, 0, 2, 1,110, 0, 7, 0, 4,
- 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 1,111, 0, 7, 1,112, 0, 7, 1,113, 0, 7, 1,114, 0, 7, 1,115, 0, 7, 1,116,
- 0, 7, 1,117, 0, 7, 0, 21, 0, 7, 1,118, 0, 7, 1,119, 0, 60, 0, 15, 0, 26, 0, 30, 0, 59, 1,102, 0, 11, 1,120,
- 0, 11, 1,121, 0, 29, 0, 54, 0, 53, 1,122, 0, 2, 0, 19, 0, 2, 1,123, 0, 4, 0,142, 0, 7, 0,221, 0, 7, 0,141,
- 0, 7, 0,222, 0, 7, 1,124, 0, 7, 1,125, 0, 7, 1,126, 0, 61, 0, 10, 0, 7, 1,127, 0, 7, 1,128, 0, 7, 1,129,
- 0, 7, 1,130, 0, 2, 1,131, 0, 2, 1,132, 0, 0, 1,133, 0, 0, 1,134, 0, 0, 1,135, 0, 0, 1,136, 0, 62, 0, 7,
- 0, 7, 1,137, 0, 7, 1,128, 0, 7, 1,129, 0, 2, 1,133, 0, 2, 1,136, 0, 7, 1,130, 0, 7, 0, 15, 0, 63, 0, 20,
- 0, 63, 0, 0, 0, 63, 0, 1, 0, 2, 0, 17, 0, 2, 1,138, 0, 2, 1,136, 0, 2, 0, 19, 0, 2, 1,139, 0, 2, 1,140,
- 0, 2, 1,141, 0, 2, 1,142, 0, 2, 1,143, 0, 2, 1,144, 0, 2, 1,145, 0, 2, 1,146, 0, 7, 1,147, 0, 7, 1,148,
- 0, 62, 1,149, 0, 61, 1,150, 0, 4, 1,151, 0, 4, 0, 15, 0, 64, 0, 5, 0, 2, 1,152, 0, 2, 1,138, 0, 0, 0, 19,
- 0, 0, 0, 15, 0, 2, 1, 91, 0, 65, 0, 4, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 0, 7, 0, 7, 0, 94, 0, 66, 0, 57,
- 0, 26, 0, 30, 0, 59, 1,102, 0, 11, 1,153, 0, 11, 1,121, 0, 43, 1,154, 0, 43, 1,155, 0, 43, 1,156, 0, 29, 0, 54,
- 0, 67, 1,157, 0, 31, 1,158, 0, 53, 1,122, 0, 11, 1,159, 0, 7, 0,221, 0, 7, 0,141, 0, 7, 0,222, 0, 4, 0,142,
- 0, 2, 1,160, 0, 2, 1,123, 0, 2, 0, 19, 0, 2, 1,161, 0, 7, 1,162, 0, 7, 1,163, 0, 7, 1,164, 0, 2, 1,141,
- 0, 2, 1,142, 0, 2, 1,165, 0, 2, 1,166, 0, 4, 1, 91, 0, 2, 0, 21, 0, 2, 0, 68, 0, 2, 0, 41, 0, 2, 1,167,
- 0, 7, 1,168, 0, 7, 1,169, 0, 7, 1,170, 0, 7, 1,171, 0, 7, 1,172, 0, 7, 1,173, 0, 7, 1,174, 0, 7, 1,175,
- 0, 7, 1,176, 0, 7, 1,177, 0, 0, 1,178, 0, 0, 1,179, 0, 56, 1,180, 0, 56, 1,181, 0, 56, 1,182, 0, 56, 1,183,
- 0, 4, 1,184, 0, 4, 1,185, 0, 4, 1,186, 0, 4, 0, 15, 0, 65, 1,187, 0, 4, 1,188, 0, 4, 1,189, 0, 64, 1,190,
- 0, 64, 1,191, 0, 68, 0, 6, 0, 43, 0,226, 0, 2, 0, 39, 0, 2, 0, 43, 0, 2, 0, 17, 0, 2, 0, 19, 0, 0, 1,192,
- 0, 69, 0, 19, 0, 69, 0, 0, 0, 69, 0, 1, 0, 62, 1,149, 0, 61, 1,150, 0, 23, 1,193, 0, 23, 1,194, 0, 2, 0, 39,
- 0, 2, 0, 43, 0, 2, 1,195, 0, 2, 1,196, 0, 2, 1,197, 0, 2, 1,198, 0, 2, 0, 19, 0, 2, 1,199, 0, 7, 0, 10,
- 0, 7, 0, 11, 0, 4, 1,200, 0, 7, 0, 42, 0, 68, 1,201, 0, 70, 0, 41, 0, 26, 0, 30, 0, 59, 1,102, 0, 11, 1,202,
- 0, 29, 0, 54, 0, 31, 1,158, 0, 53, 1,122, 0, 71, 1,203, 0, 72, 1,204, 0, 73, 1,205, 0, 74, 1,206, 0, 75, 1,207,
- 0, 76, 1,208, 0, 77, 1,209, 0, 78, 1,210, 0, 70, 1,211, 0, 79, 1,212, 0, 80, 1,213, 0, 9, 1,214, 0, 81, 1,215,
- 0, 81, 1,216, 0, 81, 1,217, 0, 4, 1,196, 0, 4, 1,218, 0, 4, 1,219, 0, 4, 1,220, 0, 4, 1, 91, 0, 4, 0,142,
- 0, 7, 0,221, 0, 7, 0,141, 0, 7, 0,222, 0, 7, 1,221, 0, 7, 0, 15, 0, 2, 1,222, 0, 2, 0, 19, 0, 2, 1,223,
- 0, 2, 1,224, 0, 2, 1,123, 0, 2, 1,225, 0, 82, 1,226, 0, 83, 1,227, 0, 9, 0,128, 0, 73, 0, 8, 0, 9, 1,228,
- 0, 7, 1,229, 0, 4, 1,230, 0, 0, 0, 19, 0, 0, 1,231, 0, 2, 0,227, 0, 2, 1,232, 0, 2, 1,233, 0, 71, 0, 8,
- 0, 4, 1,234, 0, 4, 1,235, 0, 4, 1,236, 0, 4, 1,237, 0, 0, 0, 15, 0, 0, 1,138, 0, 0, 1,238, 0, 0, 0, 19,
- 0, 75, 0, 5, 0, 4, 1,234, 0, 4, 1,235, 0, 0, 1,239, 0, 0, 0, 15, 0, 2, 0, 19, 0, 84, 0, 2, 0, 4, 1,240,
- 0, 7, 1,129, 0, 76, 0, 3, 0, 84, 1,241, 0, 4, 1,242, 0, 4, 0, 19, 0, 74, 0, 4, 0, 7, 1,243, 0, 2, 1,244,
- 0, 0, 0, 19, 0, 0, 1,138, 0, 77, 0, 4, 0, 0, 0,168, 0, 0, 0,144, 0, 0, 0,145, 0, 0, 0,146, 0, 78, 0, 1,
- 0, 7, 1,245, 0, 79, 0, 2, 0, 4, 1,246, 0, 4, 0, 17, 0, 72, 0, 7, 0, 7, 1,229, 0, 39, 1,228, 0, 0, 0, 19,
- 0, 0, 1,231, 0, 2, 0,227, 0, 2, 1,232, 0, 2, 1,233, 0, 85, 0, 4, 0, 7, 0,168, 0, 7, 0,144, 0, 7, 0,145,
- 0, 7, 0,146, 0, 86, 0, 1, 0, 85, 1,230, 0, 87, 0, 6, 0, 4, 1,247, 0, 4, 1,248, 0, 4, 1,249, 0, 0, 0, 19,
- 0, 0, 1,138, 0, 0, 1,250, 0, 88, 0, 2, 0, 4, 1,251, 0, 4, 1,248, 0, 89, 0, 13, 0, 89, 0, 0, 0, 89, 0, 1,
- 0, 74, 1,252, 0, 87, 1,253, 0, 86, 1,254, 0, 88, 1,255, 0, 11, 2, 0, 0, 11, 2, 1, 0, 90, 2, 2, 0, 4, 1,196,
- 0, 4, 1,219, 0, 4, 1,218, 0, 4, 0, 15, 0, 82, 0, 12, 0, 11, 2, 3, 0, 0, 2, 4, 0, 0, 2, 5, 0, 0, 2, 6,
- 0, 0, 2, 7, 0, 0, 2, 8, 0, 0, 2, 9, 0, 0, 2, 10, 0, 0, 0, 15, 0, 81, 1,215, 0, 81, 1,217, 0, 2, 2, 11,
- 0, 83, 0, 8, 0, 4, 2, 12, 0, 4, 2, 13, 0, 71, 2, 14, 0, 75, 2, 15, 0, 4, 1,219, 0, 4, 1,218, 0, 4, 1,196,
- 0, 4, 0, 15, 0, 91, 0, 6, 0, 91, 0, 0, 0, 91, 0, 1, 0, 4, 0, 17, 0, 4, 0,227, 0, 0, 0, 16, 0, 0, 2, 16,
- 0, 92, 0, 7, 0, 91, 2, 17, 0, 2, 2, 18, 0, 2, 2, 3, 0, 2, 2, 19, 0, 2, 0, 66, 0, 9, 2, 20, 0, 9, 2, 21,
- 0, 93, 0, 3, 0, 91, 2, 17, 0, 43, 0,133, 0, 0, 0, 16, 0, 94, 0, 5, 0, 91, 2, 17, 0, 43, 0,133, 0, 0, 0, 16,
- 0, 2, 2, 22, 0, 0, 2, 23, 0, 95, 0, 5, 0, 91, 2, 17, 0, 7, 2, 24, 0, 7, 2, 25, 0, 4, 2, 26, 0, 4, 2, 27,
- 0, 96, 0, 11, 0, 91, 2, 17, 0, 43, 2, 28, 0, 43, 2, 29, 0, 7, 2, 30, 0, 7, 2, 31, 0, 7, 2, 25, 0, 7, 2, 32,
- 0, 4, 2, 33, 0, 4, 2, 34, 0, 4, 0, 66, 0, 4, 2, 35, 0, 97, 0, 4, 0, 91, 2, 17, 0, 2, 2, 36, 0, 2, 0, 19,
- 0, 7, 2, 37, 0, 98, 0, 3, 0, 91, 2, 17, 0, 7, 2, 38, 0, 4, 0, 66, 0, 99, 0, 8, 0, 91, 2, 17, 0, 44, 2, 39,
- 0, 7, 2, 40, 0, 4, 2, 41, 0, 0, 2, 42, 0, 7, 2, 43, 0, 4, 2, 44, 0, 43, 2, 45, 0,100, 0, 7, 0, 91, 2, 17,
- 0, 43, 2, 46, 0, 39, 2, 47, 0, 4, 0, 66, 0, 4, 2, 48, 0, 7, 2, 49, 0, 7, 2, 50, 0,101, 0, 3, 0, 91, 2, 17,
- 0, 7, 2, 51, 0, 4, 2, 52, 0,102, 0, 13, 0, 91, 2, 17, 0, 43, 2, 53, 0, 2, 0, 19, 0, 2, 0, 15, 0, 7, 2, 54,
- 0, 7, 2, 55, 0, 7, 2, 56, 0, 7, 1,162, 0, 7, 2, 57, 0, 7, 2, 58, 0, 7, 2, 59, 0, 7, 2, 60, 0, 7, 2, 61,
- 0,103, 0, 6, 0, 91, 2, 17, 0, 2, 2, 62, 0, 2, 0, 80, 0, 4, 1, 91, 0, 43, 0,133, 0, 0, 2, 42, 0,104, 0, 9,
- 0, 91, 2, 17, 0, 43, 0,133, 0, 7, 2, 63, 0, 7, 2, 64, 0, 7, 2, 65, 0, 4, 2, 66, 0, 4, 2, 67, 0, 7, 2, 68,
- 0, 0, 0, 16, 0,105, 0, 1, 0, 91, 2, 17, 0,106, 0, 4, 0, 91, 2, 17, 0, 43, 0,133, 0, 4, 2, 69, 0, 4, 0, 15,
- 0,107, 0, 3, 0, 91, 2, 17, 0, 4, 2, 70, 0, 7, 2, 71, 0,108, 0, 24, 0, 26, 0, 30, 0, 2, 1,139, 0, 2, 1,140,
- 0, 2, 2, 72, 0, 2, 0, 19, 0, 2, 2, 73, 0, 2, 2, 74, 0, 2, 2, 75, 0, 2, 1, 91, 0, 0, 2, 76, 0, 0, 2, 77,
- 0, 0, 2, 78, 0, 0, 0, 17, 0, 4, 0, 15, 0, 7, 2, 79, 0, 7, 2, 80, 0, 7, 2, 81, 0, 7, 2, 82, 0, 7, 2, 83,
- 0, 7, 2, 84, 0, 62, 2, 85, 0, 29, 0, 54, 0, 31, 1,158, 0, 76, 1,208, 0,109, 0, 3, 0,109, 0, 0, 0,109, 0, 1,
- 0, 0, 0, 16, 0, 59, 0, 3, 0, 7, 2, 86, 0, 4, 0, 19, 0, 4, 0, 15, 0, 80, 0, 2, 0, 7, 2, 87, 0, 7, 0,141,
- 0,110, 0, 4, 0, 2, 0, 35, 0, 2, 2, 88, 0, 4, 0, 15, 0, 43, 2, 89, 0, 43, 0,104, 0, 26, 0, 30, 0, 2, 0, 17,
- 0, 2, 2, 90, 0, 4, 2, 91, 0, 4, 2, 92, 0, 4, 2, 93, 0, 0, 2, 94, 0, 9, 2, 95, 0, 43, 0, 36, 0, 43, 2, 96,
- 0, 43, 2, 97, 0, 43, 2, 98, 0, 43, 2, 99, 0, 29, 0, 54, 0, 67, 1,157, 0, 59, 1,102, 0,111, 2,100, 0,112, 2,101,
- 0, 9, 0, 45, 0, 11, 2,102, 0, 11, 1,202, 0, 11, 2,103, 0, 11, 1,121, 0, 11, 2,104, 0, 11, 2,105, 0, 53, 1,122,
- 0, 7, 0,221, 0, 7, 2,106, 0, 7, 2,107, 0, 7, 0,141, 0, 7, 2,108, 0, 7, 0,222, 0, 7, 2,109, 0, 7, 1,111,
- 0, 7, 2,110, 0, 7, 2,111, 0, 7, 2, 63, 0, 7, 0,172, 0, 4, 2,112, 0, 2, 0, 19, 0, 2, 2,113, 0, 2, 2,114,
- 0, 2, 2,115, 0, 2, 2,116, 0, 2, 2,117, 0, 2, 2,118, 0, 2, 2,119, 0, 2, 2,120, 0, 2, 2,121, 0, 2, 2,122,
- 0, 2, 2,123, 0, 4, 2,124, 0, 4, 2,125, 0, 4, 2,126, 0, 4, 2,127, 0, 7, 2,128, 0, 7, 2,129, 0, 7, 2,130,
- 0, 7, 2,131, 0, 7, 2,132, 0, 7, 2,133, 0, 7, 2,134, 0, 7, 2,135, 0, 7, 2,136, 0, 0, 2,137, 0, 0, 2,138,
- 0, 0, 1,123, 0, 0, 2,139, 0, 0, 2,140, 0, 0, 2,141, 0, 7, 2,142, 0, 32, 0, 93, 0, 11, 2,143, 0, 11, 2,144,
- 0, 11, 2,145, 0, 11, 2,146, 0, 9, 1,214, 0, 7, 2,147, 0, 2, 1,246, 0, 2, 2,148, 0, 7, 1,230, 0, 4, 2,149,
- 0, 4, 2,150, 0, 2, 2,151, 0, 2, 0,179, 0, 7, 2,152, 0, 11, 2,153, 0, 11, 2,154, 0, 11, 2,155, 0,113, 2,156,
- 0,114, 2,157, 0, 55, 2,158, 0, 2, 2,159, 0, 2, 2,160, 0, 2, 2,161, 0, 2, 2,162, 0, 7, 1,222, 0, 4, 2,163,
- 0,115, 2,164, 0,116, 2,165, 0,116, 2,166, 0, 4, 2,167, 0, 4, 0, 15, 0, 9, 0,128, 0,117, 0, 14, 0,117, 0, 0,
- 0,117, 0, 1, 0, 43, 0, 36, 0, 7, 2, 63, 0, 7, 0,223, 0, 7, 2, 64, 0, 7, 2, 65, 0, 0, 0, 16, 0, 4, 2, 66,
- 0, 4, 2, 67, 0, 4, 2,168, 0, 2, 0, 17, 0, 2, 2,169, 0, 7, 2, 68, 0,113, 0, 13, 0, 2, 2,170, 0, 2, 2,171,
- 0, 2, 0, 19, 0, 2, 0, 15, 0, 7, 2,172, 0, 7, 2,173, 0, 7, 2,174, 0, 7, 2,175, 0, 7, 2,176, 0, 7, 2,177,
- 0, 7, 2,178, 0, 7, 2,179, 0, 7, 2,180, 0,118, 0, 1, 0, 7, 1,137, 0,114, 0, 40, 0, 4, 2,181, 0, 4, 2,182,
- 0,119, 2,183, 0,120, 2,184, 0, 7, 2,129, 0, 7, 2,185, 0, 7, 2,186, 0, 7, 2,187, 0, 7, 2,188, 0, 7, 2,189,
- 0, 7, 2,190, 0, 7, 2,191, 0, 7, 2,192, 0, 7, 2,193, 0, 7, 2,194, 0, 2, 2,195, 0, 2, 2,196, 0, 7, 2,197,
- 0, 7, 2,198, 0, 4, 0, 99, 0, 4, 2,199, 0, 4, 2,200, 0, 2, 2,201, 0, 2, 2,202, 0,118, 2,203, 0, 4, 2,204,
- 0, 4, 0, 56, 0, 7, 2,205, 0, 7, 2,206, 0, 7, 2,207, 0, 7, 2,208, 0, 2, 2,209, 0, 2, 2,210, 0, 2, 2,211,
- 0, 2, 2,212, 0, 2, 2,213, 0, 2, 1, 80, 0, 2, 2,163, 0, 2, 2,214, 0,121, 2,215, 0,115, 0, 40, 0, 2, 0, 17,
- 0, 2, 2,216, 0, 2, 2,217, 0, 2, 2,218, 0, 7, 2,219, 0, 2, 2,220, 0, 2, 2,221, 0, 7, 2,222, 0, 2, 2,223,
- 0, 2, 2,224, 0, 7, 2,225, 0, 7, 2,226, 0, 7, 2,227, 0, 7, 2,228, 0, 7, 2,229, 0, 7, 2,230, 0, 4, 2,231,
- 0, 7, 2,232, 0, 7, 2,233, 0, 7, 2,234, 0, 70, 2,235, 0, 70, 2,236, 0, 70, 2,237, 0, 0, 2,238, 0, 7, 2,239,
- 0, 7, 2,240, 0, 29, 0, 54, 0, 2, 2,241, 0, 0, 2,242, 0, 0, 2,243, 0, 7, 2,244, 0, 4, 2,245, 0, 7, 2,246,
- 0, 7, 2,247, 0, 4, 2,248, 0, 4, 2,249, 0, 7, 2,250, 0, 7, 2,251, 0, 7, 2,252, 0, 74, 2,253, 0,122, 0, 57,
- 0, 26, 0, 30, 0, 2, 0,143, 0, 2, 0,228, 0, 2, 0,253, 0, 2, 2,254, 0, 7, 2,255, 0, 7, 3, 0, 0, 7, 3, 1,
- 0, 7, 3, 2, 0, 7, 3, 3, 0, 7, 3, 4, 0, 7, 3, 5, 0, 7, 3, 6, 0, 7, 1, 18, 0, 7, 1, 20, 0, 7, 1, 19,
- 0, 7, 3, 7, 0, 4, 3, 8, 0, 7, 3, 9, 0, 7, 3, 10, 0, 7, 3, 11, 0, 7, 3, 12, 0, 7, 3, 13, 0, 7, 3, 14,
- 0, 7, 3, 15, 0, 2, 3, 16, 0, 2, 0,227, 0, 4, 3, 17, 0, 7, 3, 18, 0, 7, 3, 19, 0, 7, 3, 20, 0, 7, 3, 21,
- 0, 7, 3, 22, 0, 7, 3, 23, 0, 7, 3, 24, 0, 7, 3, 25, 0, 7, 3, 26, 0, 7, 3, 27, 0, 7, 3, 28, 0, 7, 3, 29,
- 0, 2, 3, 30, 0, 2, 3, 31, 0, 2, 3, 32, 0, 2, 3, 33, 0, 7, 3, 34, 0, 7, 3, 35, 0, 7, 3, 36, 0, 7, 3, 37,
- 0, 2, 3, 38, 0, 2, 3, 39, 0, 2, 3, 40, 0, 2, 3, 41, 0, 7, 3, 42, 0, 7, 3, 43, 0, 29, 0, 54, 0, 42, 1, 11,
- 0, 32, 0, 93, 0,123, 0, 16, 0, 2, 3, 44, 0, 2, 3, 45, 0, 2, 3, 46, 0, 2, 0, 19, 0, 2, 3, 47, 0, 2, 3, 48,
- 0, 2, 3, 49, 0, 2, 3, 50, 0, 2, 3, 51, 0, 2, 3, 52, 0, 2, 3, 53, 0, 2, 3, 54, 0, 4, 3, 55, 0, 7, 3, 56,
- 0, 7, 3, 57, 0, 7, 3, 58, 0,124, 0, 8, 0,124, 0, 0, 0,124, 0, 1, 0, 4, 2,112, 0, 4, 3, 59, 0, 4, 0, 19,
- 0, 2, 3, 60, 0, 2, 3, 61, 0, 43, 0,133, 0,125, 0, 13, 0, 9, 3, 62, 0, 9, 3, 63, 0, 4, 3, 64, 0, 4, 3, 65,
- 0, 4, 3, 66, 0, 4, 3, 67, 0, 4, 3, 68, 0, 4, 3, 69, 0, 4, 3, 70, 0, 4, 3, 71, 0, 4, 3, 72, 0, 4, 0, 15,
- 0, 0, 3, 73, 0,126, 0, 5, 0, 9, 3, 74, 0, 9, 3, 75, 0, 4, 3, 76, 0, 4, 1, 91, 0, 0, 3, 77, 0,127, 0, 12,
- 0, 4, 0, 17, 0, 4, 3, 78, 0, 4, 3, 79, 0, 4, 3, 80, 0, 4, 3, 81, 0, 4, 3, 82, 0, 4, 0, 66, 0, 4, 3, 83,
- 0, 4, 3, 84, 0, 4, 3, 85, 0, 4, 3, 86, 0, 4, 3, 87, 0,128, 0, 4, 0, 4, 3, 88, 0, 7, 3, 89, 0, 2, 0, 19,
- 0, 2, 3, 90, 0,129, 0, 9, 0,129, 0, 0, 0,129, 0, 1, 0, 0, 0, 16, 0, 53, 3, 91, 0, 55, 3, 92, 0, 4, 2,112,
- 0, 4, 3, 93, 0, 4, 3, 94, 0, 4, 3, 95, 0,130, 0, 95, 0,125, 3, 96, 0,126, 3, 97, 0,127, 3, 98, 0, 4, 3, 99,
- 0, 4, 0, 99, 0, 4, 2,199, 0, 4, 3,100, 0, 4, 3,101, 0, 2, 0, 19, 0, 2, 3,102, 0, 7, 2,129, 0, 7, 3,103,
- 0, 7, 3,104, 0, 7, 3,105, 0, 7, 3,106, 0, 7, 3,107, 0, 2, 3,108, 0, 2, 3,109, 0, 2, 3,110, 0, 2, 3,111,
- 0, 2, 0,178, 0, 2, 3,112, 0, 2, 3,113, 0, 2, 3,114, 0, 2, 3,115, 0, 2, 3,116, 0, 2, 0,242, 0, 2, 0, 77,
- 0, 2, 3,117, 0, 2, 3,118, 0, 2, 3,119, 0, 2, 3,120, 0, 2, 3,121, 0, 2, 3,122, 0, 2, 3,123, 0, 2, 3,124,
- 0, 2, 3,125, 0, 2, 3,126, 0, 2, 3,127, 0, 2, 0,243, 0, 2, 3,128, 0, 2, 3,129, 0, 4, 0,227, 0, 2, 3,130,
- 0, 2, 3,131, 0, 2, 3,132, 0, 2, 3,133, 0, 2, 3,134, 0, 2, 3,135, 0, 2, 3,136, 0, 23, 3,137, 0, 23, 3,138,
- 0, 22, 3,139, 0, 11, 3,140, 0, 2, 3,141, 0, 2, 0, 15, 0, 4, 1, 91, 0, 7, 3,142, 0, 7, 3,143, 0, 2, 3,144,
- 0, 2, 3,145, 0, 2, 3,146, 0, 2, 3,147, 0, 2, 3,148, 0, 2, 3,149, 0, 2, 3,150, 0, 2, 3,151, 0, 2, 3,152,
- 0, 2, 3,153, 0, 2, 3,154, 0, 2, 3,155, 0, 2, 3,156, 0, 2, 3,157, 0, 4, 3,158, 0, 4, 3,159, 0, 4, 3,160,
- 0, 4, 3,161, 0, 4, 3,162, 0, 7, 3,163, 0, 4, 3,164, 0, 4, 3,165, 0, 4, 3,166, 0, 4, 3,167, 0, 7, 3,168,
- 0, 7, 3,169, 0, 7, 3,170, 0, 7, 3,171, 0, 7, 3,172, 0, 7, 3,173, 0, 7, 3,174, 0, 7, 3,175, 0, 7, 3,176,
- 0, 0, 3,177, 0, 0, 3,178, 0, 0, 3,179, 0,131, 0, 5, 0, 7, 3,180, 0, 0, 0, 17, 0, 0, 0, 80, 0, 0, 1, 91,
- 0, 0, 1, 80, 0,132, 0, 5, 0,132, 0, 0, 0,132, 0, 1, 0, 4, 3,181, 0, 0, 3,182, 0, 4, 0, 19, 0,133, 0, 4,
- 0,134, 3,183, 0, 2, 0, 19, 0, 2, 3,184, 0, 4, 1, 80, 0,135, 0, 26, 0, 2, 3,185, 0, 2, 3,186, 0, 7, 3,187,
- 0, 7, 3,188, 0, 2, 3,189, 0, 2, 3,190, 0, 7, 3,191, 0, 7, 3,192, 0, 2, 3,193, 0, 2, 3,194, 0, 2, 3,195,
- 0, 2, 3,196, 0, 7, 3,197, 0, 7, 3,198, 0, 2, 3,199, 0, 2, 3,200, 0, 2, 3,201, 0, 2, 1, 91, 0, 7, 3,202,
- 0,133, 3,203, 0, 7, 3,204, 0, 0, 3,205, 0, 0, 3,206, 0, 0, 3,207, 0, 0, 1, 80, 0, 4, 2,163, 0,136, 0, 6,
- 0, 2, 0, 77, 0, 0, 2, 40, 0, 0, 3,208, 0, 0, 3,209, 0, 0, 3,210, 0, 0, 1,250, 0,137, 0, 20, 0,138, 3,211,
- 0, 42, 1, 11, 0,136, 3,212, 0,136, 3,213, 0,136, 3,214, 0,136, 3,215, 0,136, 3,216, 0,136, 3,217, 0, 2, 3,218,
- 0, 2, 0,253, 0, 2, 3,219, 0, 2, 1,168, 0, 0, 3,220, 0, 0, 3,221, 0, 0, 3,222, 0, 0, 3,223, 0, 0, 3,224,
- 0, 0, 3,225, 0, 0, 3,226, 0, 0, 3,227, 0,139, 0, 37, 0, 26, 0, 30, 0, 43, 3,228, 0,122, 3,229, 0,139, 3,230,
- 0, 39, 0,170, 0, 11, 3,231, 0,124, 3,232, 0, 7, 3,233, 0, 7, 3,234, 0, 7, 3,235, 0, 7, 3,236, 0, 4, 2,112,
- 0, 7, 3,237, 0, 2, 3,238, 0, 2, 3,239, 0, 2, 3,240, 0, 2, 1, 61, 0, 54, 1, 83, 0, 9, 3,241, 0,123, 3,242,
- 0, 9, 1,214, 0,131, 3,243, 0,135, 3,244, 0,130, 0,144, 0,128, 3,245, 0, 32, 0, 93, 0, 11, 3,246, 0, 2, 3,247,
- 0, 2, 0, 80, 0, 2, 1, 91, 0, 2, 1, 80, 0,140, 3,248, 0, 2, 3,249, 0, 2, 3,250, 0, 2, 2,163, 0, 2, 0,179,
- 0,137, 3,251, 0,141, 0, 9, 0, 39, 0,170, 0, 38, 0,217, 0, 7, 1,175, 0, 7, 1,176, 0, 7, 0, 77, 0, 7, 3,252,
- 0, 7, 3,253, 0, 2, 3,254, 0, 2, 3,255, 0,142, 0, 68, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1,
- 0,144, 4, 2, 0, 2, 4, 3, 0, 7, 4, 4, 0, 7, 4, 5, 0, 7, 4, 6, 0, 7, 4, 7, 0, 7, 4, 8, 0, 7, 4, 9,
- 0, 7, 4, 10, 0, 7, 0,230, 0, 7, 4, 11, 0, 7, 4, 12, 0, 2, 4, 13, 0, 2, 3,210, 0, 43, 3,228, 0, 43, 4, 14,
- 0,141, 4, 15, 0,142, 4, 16, 0,145, 4, 17, 0,146, 4, 18, 0,147, 4, 19, 0, 0, 4, 20, 0, 2, 3, 46, 0, 2, 4, 21,
- 0, 4, 2,112, 0, 4, 4, 22, 0, 2, 4, 23, 0, 2, 4, 24, 0, 2, 4, 25, 0, 0, 4, 26, 0, 0, 0, 80, 0, 7, 0, 83,
- 0, 7, 4, 27, 0, 7, 4, 28, 0, 7, 4, 29, 0, 7, 4, 30, 0, 7, 4, 31, 0, 7, 4, 32, 0, 7, 4, 33, 0, 7, 0,140,
- 0, 7, 3,233, 0, 2, 4, 34, 0, 2, 4, 35, 0, 2, 4, 36, 0, 2, 4, 37, 0, 2, 0,106, 0, 2, 3,219, 0, 2, 4, 38,
- 0, 2, 4, 39, 0, 2, 4, 40, 0, 2, 4, 41, 0, 7, 4, 42, 0, 7, 4, 43, 0, 59, 4, 44, 0, 11, 4, 45, 0, 2, 4, 46,
- 0, 2, 1,231, 0, 2, 4, 47, 0, 2, 0, 19, 0, 2, 4, 48, 0, 2, 4, 49, 0, 2, 4, 50, 0, 2, 1, 91, 0, 9, 4, 51,
- 0,148, 0, 16, 0, 23, 0, 35, 0, 23, 0, 38, 0, 22, 4, 52, 0, 22, 4, 53, 0, 22, 4, 54, 0, 7, 4, 55, 0, 7, 4, 56,
- 0, 7, 4, 57, 0, 7, 4, 58, 0, 2, 4, 59, 0, 2, 4, 60, 0, 2, 4, 61, 0, 2, 4, 62, 0, 2, 4, 63, 0, 2, 4, 64,
- 0, 4, 0, 19, 0,143, 0, 6, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3,
- 0,149, 0, 6, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0,150, 0, 26,
- 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0, 4, 4, 65, 0, 4, 1, 91,
- 0,148, 4, 66, 0, 9, 4, 67, 0, 11, 4, 68, 0, 29, 0, 54, 0, 26, 0, 55, 0, 0, 4, 69, 0, 0, 4, 70, 0, 2, 4, 71,
- 0, 2, 4, 72, 0, 2, 4, 73, 0, 2, 4, 74, 0, 2, 0, 40, 0, 2, 0, 39, 0, 2, 0,106, 0, 2, 4, 75, 0, 4, 0, 19,
- 0, 7, 4, 76, 0, 23, 0, 35, 0,151, 0, 29, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2,
- 0,145, 4, 17, 0, 2, 4, 3, 0, 2, 4, 77, 0, 2, 4, 78, 0, 2, 4, 79, 0, 2, 4, 80, 0,148, 4, 66, 0, 2, 4, 81,
- 0, 2, 0,106, 0, 2, 4, 72, 0, 2, 4, 82, 0, 9, 4, 83, 0, 2, 3,219, 0, 0, 4, 84, 0, 0, 4, 85, 0, 2, 4, 86,
- 0, 2, 4, 87, 0, 2, 2,121, 0, 2, 4, 88, 0, 2, 4, 89, 0, 0, 0, 15, 0, 0, 0, 19, 0, 0, 0,253, 0, 0, 4, 90,
- 0,152, 0, 15, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0,148, 4, 66,
- 0, 7, 1,175, 0, 7, 1,176, 0, 2, 4, 81, 0, 2, 3,252, 0, 2, 4, 91, 0, 2, 1, 91, 0, 4, 0, 19, 0, 4, 0, 15,
- 0,153, 0, 29, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0,154, 4, 92,
- 0, 4, 4, 93, 0, 0, 4, 94, 0, 0, 4, 95, 0, 0, 4, 96, 0, 2, 0, 17, 0, 2, 4, 97, 0, 2, 0, 19, 0, 2, 4, 98,
- 0, 2, 4, 99, 0, 2, 4,100, 0,155, 4,101, 0, 2, 4,102, 0, 2, 4,103, 0, 2, 4,104, 0, 2, 0,169, 0, 9, 4,105,
- 0, 9, 4,106, 0, 9, 4,107, 0, 9, 4,108, 0, 9, 4,109, 0, 2, 4,110, 0, 0, 4,111, 0,156, 0, 23, 0,143, 0, 0,
- 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0,148, 4, 66, 0, 11, 4,112, 0, 2, 4, 72,
- 0, 2, 4,113, 0, 2, 0, 19, 0, 2, 1,199, 0, 9, 4, 83, 0, 11, 4,114, 0,157, 4,115, 0, 0, 4,116, 0,158, 4,117,
- 0, 4, 4,118, 0, 4, 4,119, 0, 2, 0, 17, 0, 2, 4,120, 0, 2, 4,121, 0, 2, 4,122, 0,159, 0, 27, 0,143, 0, 0,
- 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0,148, 4, 66, 0, 39, 2, 47, 0, 38, 0,217,
- 0,160, 4,123, 0, 2, 0,227, 0, 2, 0,106, 0, 2, 4,124, 0, 2, 4,125, 0, 4, 0, 19, 0, 2, 4,126, 0, 2, 4, 75,
- 0, 2, 4,127, 0, 2, 1, 91, 0, 7, 3,252, 0, 7, 1,175, 0, 7, 1,176, 0, 7, 4,128, 0, 7, 4,129, 0, 0, 4,130,
- 0, 0, 4,131, 0, 49, 4,132, 0,161, 0, 10, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2,
- 0, 2, 4, 3, 0, 2, 0,106, 0, 2, 4, 75, 0, 4, 0, 15, 0,148, 4, 66, 0,162, 0, 22, 0,143, 0, 0, 0,143, 0, 1,
- 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0, 2, 4, 3, 0, 34, 4,133, 0, 4, 4,134, 0, 4, 4,135, 0, 2, 0, 66,
- 0, 2, 0,106, 0, 4, 4,136, 0, 4, 4,137, 0, 4, 4,138, 0, 4, 4,139, 0, 4, 4,140, 0, 4, 4,141, 0, 4, 4,142,
- 0, 4, 4,143, 0, 7, 4,144, 0, 22, 4,145, 0, 22, 4,146, 0,163, 0, 9, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0,
- 0, 7, 4, 1, 0,144, 4, 2, 0,164, 4,147, 0, 4, 1, 91, 0, 2, 0, 66, 0, 2, 0,106, 0,165, 0, 8, 0,143, 0, 0,
- 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0,148, 4, 66, 0, 4, 0, 19, 0, 4, 4,148, 0,166, 0, 18,
- 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2, 0,148, 4, 66, 0, 26, 4,149, 0, 26, 0, 55,
- 0, 2, 0, 19, 0, 2, 0,106, 0, 7, 4,150, 0, 9, 4,151, 0, 7, 1,175, 0, 7, 1,176, 0, 54, 1, 83, 0, 54, 4,152,
- 0, 4, 4,153, 0, 4, 0, 15, 0,167, 0, 81, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2,
- 0, 0, 4,154, 0, 4, 4,155, 0, 2, 0,227, 0, 2, 4,156, 0, 2, 4,157, 0, 2, 4,158, 0, 2, 4,159, 0, 2, 4,160,
- 0, 2, 4,161, 0, 2, 4,162, 0, 2, 4,163, 0, 2, 4,164, 0, 2, 4,165, 0, 2, 4,166, 0, 2, 4,167, 0, 2, 4,168,
- 0, 2, 4,169, 0, 2, 4,170, 0, 2, 4,171, 0, 2, 4,172, 0, 2, 4,173, 0, 2, 4,174, 0, 2, 4,175, 0, 2, 4,176,
- 0, 2, 4,177, 0, 2, 4,178, 0, 2, 4,179, 0, 2, 4,180, 0, 2, 4,181, 0, 2, 4,182, 0, 2, 4,183, 0, 2, 4,184,
- 0, 2, 4,185, 0, 2, 4,186, 0, 2, 4,187, 0, 2, 4,188, 0, 2, 4,189, 0, 2, 4,190, 0, 2, 4,191, 0, 2, 4,192,
- 0, 2, 4,193, 0, 2, 4,194, 0, 2, 4,195, 0, 2, 4,196, 0, 2, 4,197, 0, 2, 4,198, 0, 2, 4,199, 0, 2, 4,200,
- 0, 2, 4,201, 0, 2, 4,202, 0, 0, 4,203, 0, 0, 4,204, 0, 0, 4,205, 0, 0, 4,206, 0,168, 4,207, 0,168, 4,208,
- 0, 4, 4,209, 0, 4, 4,210, 0, 4, 4,211, 0, 4, 4,212, 0, 4, 4,213, 0, 7, 4,214, 0, 7, 4,215, 0, 7, 4,216,
- 0, 2, 4,217, 0, 2, 4,218, 0, 2, 4,219, 0, 2, 4,220, 0,169, 4,221, 0,169, 4,222, 0, 2, 4,223, 0, 2, 4,224,
- 0, 4, 1, 91, 0, 49, 4,225, 0, 9, 4,105, 0, 9, 4,108, 0,170, 0, 20, 0, 0, 4,226, 0, 0, 4,227, 0, 0, 4,228,
- 0, 0, 4,229, 0, 0, 4,230, 0, 0, 4,231, 0, 0, 4,232, 0, 0, 4,233, 0, 0, 4,234, 0, 0, 4,235, 0, 0, 4,236,
- 0, 0, 4,237, 0, 0, 4,238, 0, 0, 4,239, 0, 0, 4,240, 0, 0, 4,241, 0, 0, 4,242, 0, 0, 4,243, 0, 0, 3, 90,
- 0, 0, 4,244, 0,171, 0, 48, 0, 0, 4,245, 0, 0, 4,236, 0, 0, 4,237, 0, 0, 4,246, 0, 0, 4,247, 0, 0, 4,248,
- 0, 0, 4,249, 0, 0, 4,250, 0, 0, 4,251, 0, 0, 4,252, 0, 0, 4,253, 0, 0, 4,254, 0, 0, 4,255, 0, 0, 5, 0,
- 0, 0, 5, 1, 0, 0, 5, 2, 0, 0, 5, 3, 0, 0, 5, 4, 0, 0, 5, 5, 0, 0, 5, 6, 0, 0, 5, 7, 0, 0, 5, 8,
- 0, 0, 5, 9, 0, 0, 5, 10, 0, 0, 5, 11, 0, 0, 5, 12, 0, 0, 5, 13, 0, 0, 5, 14, 0, 0, 5, 15, 0, 0, 5, 16,
- 0, 0, 5, 17, 0, 0, 5, 18, 0, 0, 5, 19, 0, 0, 5, 20, 0, 0, 5, 21, 0, 0, 5, 22, 0, 0, 5, 23, 0, 0, 5, 24,
- 0, 0, 5, 25, 0, 0, 5, 26, 0, 0, 5, 27, 0, 0, 5, 28, 0, 0, 5, 29, 0, 0, 5, 30, 0, 0, 5, 31, 0, 0, 5, 32,
- 0, 0, 5, 33, 0, 0, 5, 34, 0,172, 0, 21, 0,172, 0, 0, 0,172, 0, 1, 0, 0, 0, 16, 0,170, 5, 35, 0,171, 5, 36,
- 0,171, 5, 37, 0,171, 5, 38, 0,171, 5, 39, 0,171, 5, 40, 0,171, 5, 41, 0,171, 5, 42, 0,171, 5, 43, 0,171, 5, 44,
- 0,171, 5, 45, 0,171, 5, 46, 0,171, 5, 47, 0,171, 5, 48, 0,171, 5, 49, 0,171, 5, 50, 0, 0, 5, 51, 0, 0, 5, 34,
- 0,173, 0, 5, 0, 4, 0, 19, 0, 4, 0, 15, 0, 7, 1,230, 0, 7, 5, 52, 0, 7, 1,137, 0,174, 0, 50, 0, 4, 0, 19,
- 0, 4, 5, 53, 0, 4, 5, 54, 0, 0, 5, 55, 0, 0, 5, 56, 0, 0, 5, 57, 0, 0, 5, 58, 0, 0, 5, 59, 0, 0, 5, 60,
- 0, 0, 5, 61, 0, 0, 5, 62, 0, 0, 5, 63, 0, 2, 5, 64, 0, 2, 5, 65, 0, 4, 5, 66, 0, 4, 5, 67, 0, 4, 5, 68,
- 0, 4, 5, 69, 0, 2, 5, 70, 0, 2, 5, 71, 0, 2, 5, 72, 0, 2, 5, 73, 0, 4, 5, 74, 0, 4, 5, 75, 0, 2, 5, 76,
- 0, 2, 5, 77, 0, 2, 5, 78, 0, 2, 5, 79, 0, 0, 5, 80, 0, 11, 5, 81, 0, 2, 5, 82, 0, 2, 5, 83, 0, 2, 5, 84,
- 0, 2, 5, 85, 0,173, 5, 86, 0, 2, 5, 87, 0, 2, 5, 88, 0, 2, 5, 89, 0, 2, 5, 90, 0, 4, 5, 91, 0, 4, 5, 92,
- 0, 4, 5, 93, 0, 2, 5, 94, 0, 2, 5, 95, 0, 2, 5, 96, 0, 2, 5, 97, 0, 2, 5, 98, 0, 0, 5, 99, 0, 0, 5,100,
- 0, 2, 0, 15, 0,175, 0, 18, 0, 26, 0, 30, 0, 11, 5,101, 0, 11, 5,102, 0, 11, 5,103, 0,139, 5,104, 0, 2, 2, 54,
- 0, 2, 5,105, 0, 2, 2, 55, 0, 2, 5,106, 0, 2, 5,107, 0, 2, 5,108, 0, 2, 5,109, 0, 2, 5,110, 0, 2, 5,111,
- 0, 2, 0, 15, 0, 2, 5,112, 0, 2, 5,113, 0, 2, 5,114, 0,176, 0, 5, 0,176, 0, 0, 0,176, 0, 1, 0,176, 5,115,
- 0, 12, 5,116, 0, 4, 0, 19, 0,177, 0, 7, 0,177, 0, 0, 0,177, 0, 1, 0,176, 5,117, 0,176, 5,118, 0, 2, 3,138,
- 0, 2, 0, 19, 0, 4, 0, 15, 0,178, 0, 17, 0,178, 0, 0, 0,178, 0, 1, 0, 0, 5,119, 0, 0, 5,120, 0, 0, 5,121,
- 0, 2, 5,122, 0, 2, 5,123, 0, 2, 5,107, 0, 2, 5,108, 0, 2, 0, 19, 0, 2, 2,169, 0, 2, 5,124, 0, 2, 5,125,
- 0, 2, 5,126, 0, 2, 5,127, 0, 4, 5,128, 0,178, 5,129, 0,144, 0, 30, 0,144, 0, 0, 0,144, 0, 1, 0,176, 5,117,
- 0,176, 5,118, 0,176, 5,130, 0,176, 5,131, 0,175, 5,132, 0, 7, 5,133, 0, 22, 1,194, 0, 22, 5,134, 0, 22, 5,135,
- 0, 2, 5,136, 0, 2, 5,137, 0, 2, 5,138, 0, 0, 4, 0, 0, 0, 5,139, 0, 2, 5,140, 0, 2, 5,141, 0, 0, 5,142,
- 0, 0, 5,143, 0, 0, 5,144, 0, 0, 5,145, 0, 2, 5,146, 0, 2, 5,147, 0, 2, 5,148, 0, 2, 0, 19, 0, 32, 0, 93,
- 0, 11, 5,149, 0, 11, 5,150, 0, 11, 5,151, 0,179, 0, 11, 0, 0, 5,152, 0, 2, 5,153, 0, 2, 5,154, 0, 2, 5,155,
- 0, 2, 5,156, 0, 2, 5,157, 0, 2, 3,124, 0, 9, 5,158, 0, 9, 5,159, 0, 4, 5,160, 0, 4, 5,161, 0,180, 0, 8,
- 0, 0, 5,162, 0, 49, 5,163, 0,180, 5,164, 0,180, 5,165, 0,180, 5,166, 0, 2, 0,102, 0, 2, 0, 15, 0, 4, 5,167,
- 0,181, 0, 10, 0,181, 0, 0, 0,181, 0, 1, 0, 4, 1,199, 0, 4, 0, 21, 0, 4, 0, 27, 0, 4, 5,168, 0,180, 5,169,
- 0, 0, 4, 95, 0, 4, 5,170, 0, 4, 5,171, 0,182, 0, 12, 0, 0, 1,100, 0, 9, 0,155, 0, 0, 0,156, 0, 4, 0,159,
- 0, 4, 0,167, 0, 9, 0,160, 0, 7, 0,162, 0, 7, 0,163, 0, 9, 5,172, 0, 9, 5,173, 0, 9, 0,164, 0, 9, 0,166,
- 0,183, 0, 41, 0,183, 0, 0, 0,183, 0, 1, 0,183, 5,174, 0, 9, 0, 25, 0, 0, 0, 26, 0, 2, 0, 19, 0, 2, 0, 17,
- 0, 4, 0, 21, 0, 4, 2, 24, 0, 4, 5,175, 0, 4, 5,176, 0, 4, 5,177, 0, 4, 5,178, 0, 4, 5,179, 0, 4, 0,178,
- 0, 4, 5,180, 0, 4, 5,181, 0, 7, 5,182, 0, 7, 5,183, 0, 4, 0, 99, 0,181, 5,184, 0,180, 5,185, 0, 29, 0, 54,
- 0,139, 5,104, 0, 40, 0,108, 0, 7, 5,186, 0, 7, 5,187, 0,182, 0,218, 0,183, 5,188, 0,183, 5,189, 0,183, 5,190,
- 0, 11, 5,191, 0,184, 5,192, 0,185, 5,193, 0, 7, 5,194, 0, 7, 5,195, 0, 4, 5,196, 0, 7, 5,197, 0, 9, 5,198,
- 0, 4, 5,199, 0, 4, 0, 15, 0,186, 0, 4, 0,186, 0, 0, 0,186, 0, 1, 0, 11, 5,200, 0,183, 5,201, 0,187, 0, 6,
- 0, 11, 5,202, 0, 11, 5,191, 0, 11, 5,203, 0, 2, 0, 19, 0, 2, 0, 15, 0, 4, 1,199, 0,188, 0, 4, 0, 7, 5,204,
- 0, 7, 5,205, 0, 2, 5,206, 0, 2, 5,207, 0,189, 0, 6, 0, 7, 5,208, 0, 7, 5,209, 0, 7, 5,210, 0, 7, 5,211,
- 0, 4, 5,212, 0, 4, 5,213, 0,190, 0, 10, 0, 7, 5,214, 0, 7, 5,215, 0, 7, 5,216, 0, 7, 5,217, 0, 7, 5,218,
- 0, 7, 5,219, 0, 7, 5,220, 0, 7, 5,221, 0, 7, 5,222, 0, 7, 5,223, 0,191, 0, 2, 0, 7, 3,180, 0, 7, 0, 15,
- 0,192, 0, 5, 0, 7, 5,224, 0, 7, 5,225, 0, 4, 0, 66, 0, 4, 2, 25, 0, 4, 0, 15, 0,193, 0, 6, 0,193, 0, 0,
- 0,193, 0, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 5,226, 0, 2, 1,199, 0,194, 0, 8, 0,194, 0, 0, 0,194, 0, 1,
- 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 5,226, 0, 2, 1,199, 0, 7, 0, 21, 0, 7, 0, 99, 0,195, 0, 45, 0,195, 0, 0,
- 0,195, 0, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 5,226, 0, 2, 0,174, 0, 2, 2,195, 0, 2, 5,227, 0, 7, 5,228,
- 0, 7, 5,229, 0, 7, 2, 61, 0, 4, 5,230, 0, 4, 0, 56, 0, 4, 2, 27, 0, 7, 5,231, 0, 7, 5,232, 0, 7, 5,233,
- 0, 7, 5,234, 0, 7, 5,235, 0, 7, 5,236, 0, 7, 2, 59, 0, 7, 0,216, 0, 7, 5,237, 0, 7, 5,238, 0, 7, 0, 15,
- 0, 7, 5,239, 0, 7, 5,240, 0, 7, 5,241, 0, 2, 5,242, 0, 2, 5,243, 0, 2, 5,244, 0, 2, 5,245, 0, 2, 5,246,
- 0, 2, 5,247, 0, 2, 5,248, 0, 2, 5,249, 0, 2, 4, 48, 0, 2, 5,250, 0, 2, 1,121, 0, 2, 5,251, 0, 0, 5,252,
- 0, 0, 5,253, 0, 7, 0,172, 0,196, 5,254, 0, 55, 1, 84, 0,197, 0, 16, 0,197, 0, 0, 0,197, 0, 1, 0, 2, 0, 17,
- 0, 2, 0, 19, 0, 2, 5,226, 0, 2, 0,174, 0, 7, 2, 54, 0, 7, 2, 55, 0, 7, 2, 56, 0, 7, 1,162, 0, 7, 2, 57,
- 0, 7, 2, 58, 0, 7, 5,255, 0, 7, 2, 59, 0, 7, 2, 60, 0, 7, 2, 61, 0,158, 0, 5, 0, 2, 0, 17, 0, 2, 5,167,
- 0, 2, 0, 19, 0, 2, 6, 0, 0, 26, 4,149, 0,157, 0, 3, 0, 4, 0, 44, 0, 4, 6, 1, 0,158, 0, 45, 0,198, 0, 12,
- 0,198, 0, 0, 0,198, 0, 1, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 2,137, 0, 2, 1,136, 0, 7, 0, 4, 0, 7, 0, 5,
- 0, 7, 6, 2, 0, 7, 6, 3, 0, 26, 4,149, 0, 11, 6, 4, 0,199, 0, 11, 0,199, 0, 0, 0,199, 0, 1, 0, 0, 0, 16,
- 0, 2, 0, 17, 0, 2, 6, 5, 0, 4, 0, 20, 0, 4, 6, 6, 0, 2, 0, 19, 0, 2, 0, 15, 0, 9, 6, 7, 0, 9, 6, 8,
- 0,200, 0, 5, 0, 0, 0, 16, 0, 7, 0,230, 0, 7, 6, 9, 0, 4, 6, 10, 0, 4, 0, 15, 0,201, 0, 4, 0, 2, 0, 17,
- 0, 2, 0, 19, 0, 2, 0, 80, 0, 2, 1, 91, 0,202, 0, 4, 0, 0, 0, 16, 0, 53, 6, 11, 0, 7, 0,230, 0, 7, 0, 15,
- 0,203, 0, 6, 0, 2, 6, 12, 0, 2, 6, 13, 0, 2, 0, 17, 0, 2, 6, 14, 0, 0, 6, 15, 0, 0, 6, 16, 0,204, 0, 5,
- 0, 4, 0, 17, 0, 4, 0, 15, 0, 0, 0, 16, 0, 0, 6, 17, 0, 0, 6, 18, 0,205, 0, 6, 0, 0, 0, 16, 0, 0, 6, 19,
- 0, 2, 6, 20, 0, 2, 2, 59, 0, 2, 0,227, 0, 2, 1, 91, 0,206, 0, 5, 0, 0, 0, 16, 0, 7, 5,205, 0, 7, 3, 11,
- 0, 2, 0, 19, 0, 2, 2, 36, 0,207, 0, 3, 0, 0, 0, 16, 0, 4, 2, 27, 0, 4, 6, 21, 0,208, 0, 7, 0, 0, 0, 16,
- 0, 7, 3, 11, 0, 0, 6, 22, 0, 0, 6, 23, 0, 2, 0,227, 0, 2, 0, 80, 0, 4, 6, 24, 0,209, 0, 3, 0, 43, 6, 25,
- 0, 0, 6, 26, 0, 0, 6, 27, 0,210, 0, 17, 0,210, 0, 0, 0,210, 0, 1, 0, 2, 0, 17, 0, 2, 6, 5, 0, 2, 0, 19,
- 0, 2, 6, 28, 0, 2, 6, 29, 0, 2, 6, 30, 0, 2, 0, 80, 0, 2, 1, 91, 0, 0, 0, 16, 0, 9, 0, 45, 0,211, 6, 31,
- 0, 43, 0,226, 0, 2, 6, 32, 0, 2, 6, 33, 0, 4, 0, 15, 0,212, 0, 10, 0, 0, 0, 16, 0, 2, 0, 17, 0, 2, 0, 15,
- 0, 4, 2, 36, 0, 4, 6, 34, 0, 4, 6, 35, 0, 4, 6, 36, 0, 4, 6, 37, 0, 4, 6, 38, 0, 4, 6, 39, 0,213, 0, 1,
- 0, 0, 6, 40, 0,214, 0, 1, 0, 34, 4,133, 0,211, 0, 18, 0,211, 0, 0, 0,211, 0, 1, 0,211, 6, 41, 0, 2, 0, 17,
- 0, 2, 0, 19, 0, 2, 6, 42, 0, 2, 6, 30, 0, 2, 6, 5, 0, 2, 6, 43, 0, 2, 1, 91, 0, 2, 1, 80, 0, 0, 0, 16,
- 0, 9, 0, 45, 0,215, 6, 31, 0,210, 6, 44, 0, 2, 0, 14, 0, 2, 6, 45, 0, 4, 2,214, 0,216, 0, 3, 0, 4, 6, 46,
- 0, 4, 0, 15, 0, 43, 0,226, 0,217, 0, 10, 0,111, 6, 47, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 5,228, 0, 4, 5,229,
- 0, 0, 0, 16, 0, 4, 6, 48, 0, 2, 6, 49, 0, 2, 6, 50, 0, 7, 6, 51, 0,218, 0, 10, 0, 2, 0, 19, 0, 2, 6, 52,
- 0, 4, 5,228, 0, 4, 5,229, 0, 2, 6, 53, 0,184, 5,192, 0, 2, 0, 17, 0, 2, 6, 54, 0, 2, 6, 55, 0, 2, 6, 56,
- 0,219, 0, 7, 0, 2, 0, 19, 0, 2, 6, 52, 0, 4, 5,228, 0, 4, 5,229, 0, 2, 0, 17, 0, 2, 6, 57, 0, 7, 6, 58,
- 0,220, 0, 9, 0, 4, 6, 46, 0, 2, 0, 17, 0, 2, 0, 19, 0, 43, 0,226, 0, 70, 6, 59, 0, 0, 0, 16, 0, 7, 6, 60,
- 0, 2, 6, 61, 0, 2, 0, 15, 0,221, 0, 5, 0, 2, 0, 17, 0, 2, 0, 19, 0, 4, 0, 15, 0,139, 5,104, 0, 43, 3,228,
- 0,222, 0, 5, 0, 4, 0, 19, 0, 4, 0, 17, 0, 0, 0, 16, 0, 0, 6, 17, 0, 43, 0,226, 0,223, 0, 10, 0, 4, 0, 19,
- 0, 4, 0, 17, 0, 7, 6, 62, 0, 7, 6, 63, 0, 7, 0,221, 0, 7, 0,222, 0, 7, 2,106, 0, 7, 2,109, 0, 7, 6, 64,
- 0, 7, 6, 65, 0,224, 0, 9, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 5,228, 0, 4, 5,229, 0, 0, 0, 16, 0, 2, 0, 80,
- 0, 2, 0, 38, 0, 2, 6, 66, 0, 2, 6, 67, 0,225, 0, 8, 0, 43, 0,226, 0, 7, 2, 56, 0, 7, 6, 68, 0, 7, 2, 88,
- 0, 7, 6, 69, 0, 2, 0, 19, 0, 2, 2, 36, 0, 7, 6, 70, 0,226, 0, 7, 0, 2, 0, 19, 0, 2, 2, 59, 0, 7, 6, 71,
- 0, 7, 6, 72, 0, 7, 6, 73, 0, 7, 6, 74, 0, 7, 6, 75, 0,227, 0, 10, 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 5,228,
- 0, 4, 5,229, 0, 0, 0, 16, 0, 2, 3, 90, 0, 2, 0, 38, 0, 2, 6, 66, 0, 2, 6, 67, 0, 55, 1, 84, 0,228, 0, 7,
- 0, 4, 2, 27, 0, 4, 6, 76, 0, 4, 6, 77, 0, 4, 6, 78, 0, 7, 6, 79, 0, 7, 6, 80, 0, 0, 6, 22, 0,229, 0, 7,
- 0, 0, 6, 81, 0, 43, 6, 82, 0, 0, 6, 26, 0, 2, 6, 83, 0, 2, 0, 80, 0, 4, 1, 91, 0, 0, 6, 27, 0,230, 0, 6,
- 0, 2, 0, 19, 0, 2, 0, 17, 0, 4, 5,228, 0, 4, 5,229, 0, 0, 6, 84, 0, 0, 6, 85, 0,231, 0, 1, 0, 4, 0, 19,
- 0,215, 0, 10, 0,215, 0, 0, 0,215, 0, 1, 0,215, 6, 41, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 6, 5, 0, 2, 6, 86,
- 0, 0, 0, 16, 0, 9, 0, 45, 0, 43, 0,226, 0,232, 0, 10, 0, 7, 2,130, 0, 7, 6, 87, 0, 7, 6, 88, 0, 7, 6, 89,
- 0, 7, 6, 90, 0, 4, 0, 19, 0, 7, 6, 91, 0, 7, 6, 92, 0, 7, 6, 93, 0, 7, 0, 15, 0,184, 0, 20, 0, 26, 0, 30,
- 0, 0, 0,154, 0,233, 6, 94, 0, 9, 6, 95, 0, 35, 0,120, 0, 35, 6, 96, 0, 9, 6, 97, 0, 29, 0, 54, 0, 7, 6, 58,
- 0, 7, 6, 98, 0, 7, 6, 99, 0, 7, 6,100, 0, 7, 6,101, 0, 7, 6,102, 0, 7, 6,103, 0, 4, 0, 66, 0, 4, 6,104,
- 0, 0, 6,105, 0, 0, 6,106, 0, 0, 6,107, 0,234, 0, 6, 0, 26, 0, 30, 0, 7, 6,108, 0, 7, 6,109, 0, 7, 6,110,
- 0, 2, 6,111, 0, 2, 6,112, 0,235, 0, 14, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1, 0,144, 4, 2,
- 0,148, 4, 66, 0,184, 5,192, 0, 2, 0,227, 0, 2, 6, 52, 0, 2, 1,175, 0, 2, 1,176, 0, 2, 0, 19, 0, 2, 4, 75,
- 0, 4, 1, 91, 0,236, 0, 6, 0,236, 0, 0, 0,236, 0, 1, 0, 43, 0,226, 0, 9, 6,113, 0, 4, 0,179, 0, 4, 0, 15,
- 0, 55, 0, 4, 0, 26, 0, 30, 0, 11, 6,114, 0, 4, 0,104, 0, 4, 0, 15, 0,237, 0, 25, 0,237, 0, 0, 0,237, 0, 1,
- 0,237, 0, 36, 0, 11, 6,115, 0, 0, 0, 16, 0, 7, 6,116, 0, 7, 6,117, 0, 7, 6,118, 0, 7, 6,119, 0, 4, 0, 19,
- 0, 7, 6,120, 0, 7, 6,121, 0, 7, 6,122, 0, 7, 0,230, 0, 7, 1,129, 0, 7, 6,123, 0, 7, 2, 25, 0, 7, 6,124,
- 0, 7, 6,125, 0, 7, 6,126, 0, 7, 6,127, 0, 7, 6,128, 0, 7, 0,141, 0, 2, 0,104, 0, 2, 3,193, 0,238, 0, 17,
- 0, 26, 0, 30, 0, 11, 6,129, 0, 11, 6,130, 0, 4, 0, 19, 0, 4, 3, 46, 0, 2, 2, 62, 0, 2, 6,131, 0, 2, 0,104,
- 0, 2, 6,132, 0, 2, 6,133, 0, 2, 6,134, 0, 2, 6,135, 0, 2, 6,136, 0, 4, 6,137, 0, 4, 6,138, 0, 4, 6,139,
- 0, 4, 6,140, 0,239, 0, 31, 0,239, 0, 0, 0,239, 0, 1, 0, 11, 2,153, 0, 0, 0, 16, 0, 2, 0, 19, 0, 2, 6,141,
- 0, 2, 6,142, 0, 2, 6,143, 0, 2, 2,119, 0, 2, 1, 91, 0, 4, 1,160, 0, 4, 6,139, 0, 4, 6,140, 0,237, 6,144,
- 0,239, 0, 36, 0,239, 6,145, 0, 11, 6,146, 0, 9, 6,147, 0, 7, 0,221, 0, 7, 0,141, 0, 7, 1,111, 0, 7, 6,148,
- 0, 7, 6,149, 0, 7, 6,150, 0, 7, 6,151, 0, 7, 6,152, 0, 7, 6,153, 0, 7, 6,154, 0, 7, 6,155, 0, 7, 1,157,
- 0, 43, 6,156, 0,112, 0, 6, 0, 11, 6,157, 0, 2, 0, 19, 0, 2, 6,158, 0, 7, 2,129, 0, 7, 6,159, 0, 7, 6,160,
- 0,240, 0, 7, 0,240, 0, 0, 0,240, 0, 1, 0, 29, 0, 54, 0, 11, 2,102, 0, 4, 0, 19, 0, 0, 0, 16, 0, 4, 6,161,
- 0,111, 0, 2, 0, 26, 0, 30, 0, 11, 6,157, 0,241, 0, 15, 0,143, 0, 0, 0,143, 0, 1, 0, 4, 4, 0, 0, 7, 4, 1,
- 0,144, 4, 2, 0, 2, 4, 3, 0,148, 4, 66, 0,111, 2,100, 0, 2, 0, 19, 0, 2, 6,162, 0, 2, 4, 72, 0, 2, 6,163,
- 0, 2, 4, 75, 0, 2, 6,164, 0, 7, 6,165, 0,242, 0, 5, 0,242, 0, 0, 0,242, 0, 1, 0, 29, 0, 54, 0, 2, 0, 19,
- 0, 0, 6,166, 0,243, 0, 8, 0,243, 0, 0, 0,243, 0, 1, 0, 9, 0, 45, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 6,161,
- 0, 0, 6,166, 0, 7, 6,167, 0,244, 0, 9, 0, 43, 6,168, 0, 2, 6,169, 0, 2, 0, 19, 0, 4, 6,170, 0, 0, 6,171,
- 0, 7, 1,129, 0, 7, 6,172, 0, 7, 6,173, 0, 4, 0, 15, 0,245, 0, 6, 0, 43, 6,168, 0, 4, 6,161, 0, 4, 6,174,
- 0, 4, 0, 66, 0, 4, 0, 15, 0, 0, 6,171, 0,246, 0, 4, 0, 43, 6,168, 0, 4, 0, 19, 0, 4, 6,161, 0, 0, 6,171,
- 0,247, 0, 4, 0, 43, 6,168, 0, 4, 0, 19, 0, 4, 6,161, 0, 0, 6,171, 0,248, 0, 10, 0, 43, 6,168, 0, 4, 6,175,
- 0, 7, 0, 98, 0, 4, 0, 19, 0, 2, 6,176, 0, 2, 6,177, 0, 2, 0, 80, 0, 2, 1, 91, 0, 7, 6,178, 0, 0, 6,171,
- 0,249, 0, 4, 0, 43, 6,168, 0, 4, 0, 19, 0, 4, 6,161, 0, 0, 6,171, 0,250, 0, 10, 0, 43, 6,168, 0, 2, 0, 17,
- 0, 2, 2,201, 0, 4, 2, 24, 0, 4, 5,229, 0, 7, 6, 68, 0, 7, 2, 88, 0, 4, 0, 15, 0,111, 6, 47, 0, 0, 6,171,
- 0,251, 0, 4, 0, 43, 6,168, 0, 4, 2,116, 0, 4, 6,179, 0, 0, 6,171, 0,252, 0, 5, 0, 43, 6,168, 0, 7, 0, 98,
- 0, 4, 6,180, 0, 4, 2,116, 0, 4, 2,117, 0,253, 0, 6, 0, 43, 6,168, 0, 0, 6,171, 0, 7, 0, 80, 0, 7, 1, 91,
- 0, 7, 6,103, 0, 7, 2, 30, 0,254, 0, 6, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 6,181,
- 0, 7, 6,182, 0,255, 0, 6, 0, 43, 6,168, 0, 4, 6,183, 0, 4, 6,184, 0, 7, 6,185, 0, 7, 6,186, 0, 0, 6,171,
- 1, 0, 0, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 6,181, 0, 7, 6,182, 0, 2, 0, 19,
- 0, 2, 4, 48, 1, 1, 0, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 6,181, 0, 7, 6,182,
- 0, 2, 0, 19, 0, 2, 0, 80, 1, 2, 0, 8, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 6,181,
- 0, 7, 6,182, 0, 2, 0, 19, 0, 2, 0, 80, 1, 3, 0, 16, 0, 43, 6,168, 0, 43, 6,145, 0, 4, 0, 17, 0, 7, 6,187,
- 0, 7, 6,188, 0, 7, 6,189, 0, 7, 6,190, 0, 7, 6,191, 0, 7, 6,192, 0, 7, 6,193, 0, 7, 6,194, 0, 7, 6,195,
- 0, 2, 0, 19, 0, 2, 0, 15, 0, 2, 0, 80, 0, 2, 1, 91, 1, 4, 0, 8, 1, 4, 0, 0, 1, 4, 0, 1, 0, 2, 0, 17,
- 0, 2, 0, 19, 0, 0, 6,196, 0, 2, 0, 15, 0, 2, 6,197, 0, 43, 0,226, 1, 5, 0, 22, 1, 5, 0, 0, 1, 5, 0, 1,
- 0, 2, 0, 19, 0, 2, 0,227, 0, 2, 6,198, 0, 2, 6,199, 0, 29, 0, 54, 0,111, 6, 47, 0, 43, 0,133, 0, 7, 2, 24,
- 0, 7, 5,229, 0, 7, 6,200, 0, 7, 6,201, 0, 7, 6,202, 0, 7, 1, 58, 0, 7, 6,203, 0, 7, 6,204, 0, 7, 6, 48,
- 0, 7, 6,205, 0, 0, 6,206, 0, 0, 6,207, 0, 11, 2,105, 1, 6, 0, 8, 0, 7, 1,137, 0, 7, 6, 68, 0, 7, 2, 88,
- 0, 9, 0, 45, 0, 2, 6,208, 0, 2, 6,209, 0, 2, 6,210, 0, 2, 6,211, 1, 7, 0, 17, 1, 7, 0, 0, 1, 7, 0, 1,
- 0, 0, 0, 16, 1, 6, 6,212, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 6,213, 0, 2, 6,214, 0, 2, 6,215, 0, 2, 6,216,
- 0, 4, 0, 80, 0, 7, 6,217, 0, 7, 6,218, 0, 4, 6,219, 0, 4, 6,220, 1, 7, 6,221, 1, 8, 6,222, 1, 9, 0, 29,
- 1, 9, 0, 0, 1, 9, 0, 1, 1, 9, 6,223, 0, 0, 0, 16, 0, 2, 0, 17, 0, 2, 0, 19, 0, 2, 5,168, 0, 2, 5,194,
- 0, 2, 6,224, 0, 2, 0,106, 0, 2, 6,214, 0, 2, 5,167, 0, 11, 6, 42, 0, 11, 6,225, 0, 26, 4,149, 0, 9, 6,226,
- 0, 7, 6,217, 0, 7, 6,218, 0, 7, 1,162, 0, 7, 6,227, 0, 2, 6,228, 0, 2, 6,229, 0, 2, 6,230, 0, 2, 6,231,
- 0, 23, 6,232, 0, 23, 6,233, 0, 23, 6,234, 1, 10, 0,121, 1, 11, 6,235, 1, 8, 0, 6, 1, 8, 0, 0, 1, 8, 0, 1,
- 1, 9, 6,236, 1, 9, 6,237, 1, 7, 6,238, 1, 7, 6,221, 0, 54, 0, 13, 0, 26, 0, 30, 0, 11, 6,239, 0, 11, 6,240,
- 1, 6, 6,241, 0, 4, 0, 17, 0, 4, 6,242, 0, 4, 6,243, 0, 4, 6,244, 1, 11, 6,245, 1, 11, 6,246, 0, 9, 6,247,
- 0, 9, 6,248, 0, 4, 6,249, 1, 12, 0, 6, 0, 4, 0, 97, 0, 4, 0, 99, 0, 4, 5,167, 0, 0, 6,250, 0, 0, 6,251,
- 0, 2, 0, 15, 1, 13, 0, 11, 0, 2, 5,107, 0, 2, 5,108, 0, 2, 6,252, 0, 2, 6, 88, 0, 2, 6,253, 0, 2, 0, 80,
- 0, 7, 6, 69, 0, 2, 0,242, 0, 0, 6,254, 0, 0, 3, 58, 0, 4, 1, 91, 1, 14, 0, 3, 0, 7, 6,255, 0, 7, 7, 0,
- 0, 7, 0, 14, 1, 15, 0, 7, 0, 0, 1,100, 0, 2, 3,126, 0, 2, 3,127, 0, 2, 3,128, 0, 2, 3, 78, 0, 4, 0, 99,
- 0, 4, 2,199, 1, 16, 0, 7, 0, 7, 7, 1, 0, 7, 7, 2, 0, 7, 7, 3, 0, 7, 1,171, 0, 7, 7, 4, 0, 7, 7, 5,
- 0, 7, 7, 6, 1, 17, 0, 2, 0, 0, 0,135, 0, 0, 7, 7, 1, 18, 0, 1, 0, 0, 0, 16, 1, 19, 0, 10, 0, 0, 7, 8,
- 0, 0, 7, 9, 0, 0, 7, 10, 0, 0, 7, 11, 0, 2, 6,252, 0, 2, 7, 12, 0, 7, 7, 13, 0, 7, 7, 14, 0, 7, 7, 15,
- 0, 7, 1,101, 1, 20, 0, 4, 0, 7, 0, 4, 0, 7, 0, 5, 0, 2, 0, 19, 0, 2, 7, 16, 1, 21, 0, 10, 0, 2, 2,181,
- 0, 2, 0, 19, 0, 7, 3, 11, 0, 7, 7, 17, 0, 7, 7, 18, 0, 7, 7, 19, 0, 7, 7, 20, 1, 20, 7, 21, 1, 20, 7, 22,
- 1, 20, 7, 23, 0,160, 0, 9, 0, 4, 0, 19, 0, 4, 0, 38, 0, 23, 7, 24, 0, 23, 7, 25, 1, 21, 7, 26, 0, 7, 7, 27,
- 0, 7, 7, 28, 0, 7, 7, 29, 0, 7, 1, 58, 1, 22, 0, 4, 0, 39, 2, 47, 0, 7, 7, 30, 0, 7, 1, 26, 0, 7, 0, 15,
- 0,134, 0, 13, 0, 26, 0, 30, 0, 2, 0, 19, 0, 2, 3,253, 0, 4, 0, 77, 0, 7, 7, 31, 0, 7, 1,168, 0, 7, 7, 32,
- 0, 7, 7, 33, 0, 7, 1, 26, 0, 2, 0,253, 0, 2, 0, 15, 0, 42, 1, 11, 1, 22, 7, 34, 1, 23, 0, 6, 0, 4, 0, 17,
- 0, 4, 0, 98, 0, 4, 0, 19, 0, 4, 2,169, 0, 0, 0, 16, 0, 9, 0, 45, 0, 81, 0, 5, 1, 23, 7, 35, 0, 4, 7, 36,
- 0, 4, 7, 37, 0, 4, 7, 38, 0, 4, 0, 15, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+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, 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, 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, 68, 97,116,
+ 97, 0, 80, 97,114,116,105, 99,108,101, 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, 76,105,110,107, 78,111,100,101, 0, 67,108,111,116,104, 86,
+101,114,116,101,120, 0, 73,109,112,108,105, 99,105,116, 95, 68, 97,116, 97, 0, 69,100,103,101, 72, 97,115,104, 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, 84, 0,112, 0,120, 0, 16, 0, 24, 0,104, 0, 20, 0,132, 0, 80, 3, 32, 0,124, 1, 0, 0, 0, 0,136, 0, 4, 1,
+ 84, 1, 24, 0, 8, 3,168, 0, 0, 0,132, 0, 24, 1, 8, 1, 56, 0, 68, 2,120, 0, 68, 0, 68, 1, 0, 0,108, 0,104, 0,
+136, 0, 56, 0, 36, 0, 56, 0, 8, 0, 16, 0, 56, 1, 0, 0,140, 0, 92, 0, 12, 1, 20, 0, 44, 0, 60, 0, 20, 0, 12, 0,
+ 12, 0, 4, 0, 8, 0, 8, 0, 20, 0, 68, 0, 32, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 16, 0, 64, 0, 24, 0, 12, 0,
+ 56, 0, 0, 0, 52, 0, 68, 0, 88, 0, 96, 0, 68, 0,116, 0, 64, 0, 60, 0,148, 0,152, 0, 60, 0, 92, 0,104, 0,176, 0,
+100, 0,180, 0, 52, 0, 64, 0, 44, 0,164, 0, 28, 0,100, 0, 0, 0, 64, 0, 8, 0, 8, 0,216, 0, 76, 0, 44, 1, 0, 0,
+ 64, 0, 64, 0,116, 0, 40, 0, 84, 0, 56, 0,116, 0,148, 0,132, 1,208, 0, 16, 0, 0, 0, 0, 0, 0, 0, 68, 1, 40, 0,
+ 28, 0,176, 0,144, 0, 48, 0, 16, 0, 72, 0,152, 3, 16, 0, 80, 0, 12, 0,152, 0, 16, 0,128, 0, 80, 0,244, 0, 8, 0,
+128, 0, 0, 0, 20, 5, 0, 0, 60, 0, 0, 3, 36, 0,204, 0, 0, 0, 0, 0, 0, 0,136, 0, 36, 0, 88, 1,220, 0,196, 0,
+120, 1, 0, 0, 0, 0,208, 1, 12, 0, 12, 0, 16, 1,180, 0,120, 0, 36, 0, 0, 0,164, 0,200, 0, 52, 2, 0, 0,152, 0,
+192, 0, 16, 0, 72, 13, 56, 0, 8, 12,120, 0, 20, 0, 24, 0,228, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 52, 0,160, 0,
+232, 0,168, 1,204, 0, 28, 1, 0, 0, 16, 0, 28, 0, 12, 0, 24, 0, 48, 0, 16, 0, 20, 0, 16, 0, 24, 0, 56, 1, 0, 0,
+ 56, 0, 44, 0, 64, 0, 48, 0, 8, 0, 44, 0, 72, 0,104, 0, 72, 0, 44, 0, 40, 0,108, 0, 68, 0, 76, 0, 80, 0, 64, 0,
+128, 0, 4, 0, 60, 0, 12, 0, 60, 0, 28, 0, 20, 0, 64, 0, 16, 0, 76, 0,104, 0, 52, 0, 28, 0, 56, 0, 60, 0, 56, 0,
+108, 0,140, 0, 4, 0, 20, 0, 40, 0, 0, 0, 68, 0,176, 0, 24, 0, 4, 1,116, 0,152, 1, 56, 0, 64, 0,192, 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, 60, 0,140, 0, 36, 0,116, 0, 24, 0,196, 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, 12, 0, 44, 0, 20, 0,
+ 60, 0, 24, 0, 56, 0, 72, 0,196, 0,220, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 82, 67, 32, 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, 0, 0, 19, 0, 2, 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, 20, 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, 16, 0, 28, 0, 37, 0, 30, 0, 6, 0, 4, 0, 38, 0,
+ 4, 0, 39, 0, 2, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 4, 0, 43, 0, 31, 0, 7, 0, 27, 0, 31, 0, 12, 0, 44, 0,
+ 24, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 48, 0, 2, 0, 16, 0, 32, 0, 16, 0, 32, 0, 0, 0, 32, 0, 1, 0,
+ 7, 0, 49, 0, 7, 0, 50, 0, 2, 0, 18, 0, 2, 0, 51, 0, 2, 0, 52, 0, 2, 0, 20, 0, 4, 0, 53, 0, 4, 0, 54, 0,
+ 9, 0, 2, 0, 7, 0, 55, 0, 0, 0, 17, 0, 0, 0, 56, 0, 7, 0, 57, 0, 7, 0, 58, 0, 33, 0, 12, 0, 27, 0, 31, 0,
+ 32, 0, 59, 0, 0, 0, 60, 0, 4, 0, 61, 0, 7, 0, 50, 0, 12, 0, 62, 0, 31, 0, 63, 0, 27, 0, 64, 0, 2, 0, 18, 0,
+ 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 20, 0, 34, 0, 5, 0, 27, 0, 67, 0, 2, 0, 68, 0, 2, 0, 69, 0, 2, 0, 70, 0,
+ 4, 0, 16, 0, 35, 0, 6, 0, 35, 0, 0, 0, 35, 0, 1, 0, 0, 0, 71, 0, 0, 0, 72, 0, 4, 0, 23, 0, 4, 0, 73, 0,
+ 36, 0, 13, 0, 27, 0, 31, 0, 0, 0, 74, 0, 4, 0, 75, 0, 4, 0, 76, 0, 12, 0, 77, 0, 35, 0, 78, 0, 35, 0, 79, 0,
+ 4, 0, 80, 0, 4, 0, 81, 0, 0, 0, 82, 0, 4, 0, 83, 0, 4, 0, 84, 0, 9, 0, 85, 0, 37, 0, 5, 0, 4, 0, 86, 0,
+ 4, 0, 87, 0, 4, 0, 75, 0, 4, 0, 16, 0, 9, 0, 2, 0, 38, 0, 20, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0, 20, 0,
+ 7, 0, 88, 0, 7, 0, 89, 0, 7, 0, 90, 0, 7, 0, 91, 0, 7, 0, 92, 0, 7, 0, 93, 0, 7, 0, 94, 0, 7, 0, 95, 0,
+ 7, 0, 96, 0, 7, 0, 97, 0, 7, 0, 98, 0, 2, 0, 99, 0, 2, 0,100, 0, 7, 0,101, 0, 31, 0, 63, 0, 34, 0,102, 0,
+ 39, 0,103, 0, 40, 0, 12, 0, 4, 0,104, 0, 4, 0,105, 0, 4, 0,106, 0, 4, 0,107, 0, 2, 0,108, 0, 2, 0,109, 0,
+ 2, 0, 20, 0, 2, 0,110, 0, 2, 0,111, 0, 2, 0,112, 0, 2, 0,113, 0, 2, 0,114, 0, 41, 0, 31, 0, 27, 0, 31, 0,
+ 0, 0, 34, 0, 12, 0,115, 0, 42, 0,116, 0, 43, 0,117, 0, 2, 0,110, 0, 2, 0, 20, 0, 2, 0,118, 0, 2, 0, 18, 0,
+ 2, 0, 16, 0, 2, 0, 42, 0, 4, 0,119, 0, 2, 0,120, 0, 2, 0,121, 0, 2, 0,122, 0, 2, 0,123, 0, 2, 0,124, 0,
+ 2, 0,125, 0, 4, 0,126, 0, 4, 0,127, 0, 37, 0,128, 0, 30, 0,129, 0, 7, 0,130, 0, 4, 0,131, 0, 2, 0,132, 0,
+ 2, 0,133, 0, 2, 0,134, 0, 2, 0,135, 0, 7, 0,136, 0, 7, 0,137, 0, 9, 0,138, 0, 44, 0, 30, 0, 2, 0,139, 0,
+ 2, 0,140, 0, 2, 0,141, 0, 2, 0,142, 0, 39, 0,143, 0, 45, 0,144, 0, 0, 0,145, 0, 0, 0,146, 0, 0, 0,147, 0,
+ 0, 0,148, 0, 0, 0,149, 0, 7, 0,150, 0, 7, 0,151, 0, 2, 0,152, 0, 2, 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, 7, 0,160, 0, 7, 0,161, 0, 7, 0,162, 0, 7, 0,163, 0,
+ 7, 0,164, 0, 7, 0,165, 0, 7, 0,166, 0, 7, 0,167, 0, 7, 0,168, 0, 46, 0, 15, 0, 0, 0,169, 0, 9, 0,170, 0,
+ 0, 0,171, 0, 0, 0,172, 0, 4, 0,173, 0, 4, 0,174, 0, 9, 0,175, 0, 7, 0,176, 0, 7, 0,177, 0, 7, 0,178, 0,
+ 4, 0,179, 0, 9, 0,180, 0, 9, 0,181, 0, 4, 0,182, 0, 4, 0, 16, 0, 47, 0, 6, 0, 7, 0,158, 0, 7, 0,159, 0,
+ 7, 0,160, 0, 7, 0,183, 0, 7, 0, 49, 0, 4, 0, 45, 0, 48, 0, 5, 0, 2, 0, 20, 0, 2, 0, 36, 0, 2, 0, 45, 0,
+ 2, 0,184, 0, 47, 0,178, 0, 49, 0, 17, 0, 39, 0,143, 0, 41, 0,185, 0, 50, 0,186, 0, 7, 0,187, 0, 7, 0,188, 0,
+ 2, 0, 18, 0, 2, 0,189, 0, 7, 0, 90, 0, 7, 0, 91, 0, 7, 0,190, 0, 4, 0,191, 0, 2, 0,192, 0, 2, 0,193, 0,
+ 4, 0,110, 0, 4, 0,119, 0, 2, 0,194, 0, 2, 0,195, 0, 45, 0, 53, 0, 27, 0, 31, 0, 7, 0,196, 0, 7, 0,197, 0,
+ 7, 0,198, 0, 7, 0,199, 0, 7, 0,200, 0, 7, 0,201, 0, 7, 0,202, 0, 7, 0,203, 0, 7, 0,204, 0, 7, 0,205, 0,
+ 7, 0,206, 0, 7, 0,207, 0, 7, 0,208, 0, 7, 0,209, 0, 7, 0,210, 0, 7, 0,211, 0, 7, 0,212, 0, 7, 0,213, 0,
+ 7, 0,214, 0, 7, 0,215, 0, 2, 0,216, 0, 2, 0,217, 0, 2, 0,218, 0, 2, 0,219, 0, 2, 0,220, 0, 2, 0,221, 0,
+ 2, 0,222, 0, 2, 0, 20, 0, 2, 0, 18, 0, 2, 0,189, 0, 7, 0,223, 0, 7, 0,224, 0, 7, 0,225, 0, 7, 0,226, 0,
+ 2, 0,227, 0, 2, 0,228, 0, 2, 0,229, 0, 2, 0,108, 0, 4, 0, 23, 0, 4, 0,105, 0, 4, 0,106, 0, 4, 0,107, 0,
+ 7, 0,230, 0, 7, 0,231, 0, 7, 0,165, 0, 40, 0,232, 0, 31, 0, 63, 0, 41, 0,185, 0, 46, 0,233, 0, 48, 0,234, 0,
+ 49, 0,235, 0, 30, 0,129, 0, 51, 0, 8, 0, 7, 0,236, 0, 7, 0,237, 0, 7, 0,151, 0, 4, 0, 20, 0, 7, 0,238, 0,
+ 7, 0,239, 0, 7, 0,240, 0, 39, 0,241, 0, 52, 0, 60, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0,242, 0, 2, 0,153, 0,
+ 2, 0,243, 0, 7, 0,158, 0, 7, 0,159, 0, 7, 0,160, 0, 7, 0,161, 0, 7, 0,244, 0, 7, 0,245, 0, 7, 0,246, 0,
+ 7, 0,247, 0, 7, 0,248, 0, 7, 0,249, 0, 7, 0,250, 0, 4, 0, 54, 0, 53, 0,251, 0, 2, 0,252, 0, 2, 0,253, 0,
+ 7, 0, 90, 0, 7, 0, 91, 0, 7, 0,254, 0, 7, 0,255, 0, 7, 0, 0, 1, 2, 0, 1, 1, 2, 0, 2, 1, 2, 0, 3, 1,
+ 2, 0, 4, 1, 0, 0, 5, 1, 0, 0, 6, 1, 2, 0, 7, 1, 2, 0, 8, 1, 2, 0, 9, 1, 2, 0, 10, 1, 2, 0, 11, 1,
+ 7, 0, 12, 1, 7, 0, 13, 1, 7, 0, 14, 1, 7, 0, 15, 1, 2, 0, 16, 1, 2, 0, 42, 0, 2, 0, 17, 1, 2, 0, 18, 1,
+ 4, 0, 19, 1, 4, 0, 20, 1, 2, 0, 21, 1, 2, 0, 22, 1, 2, 0, 23, 1, 2, 0, 24, 1, 7, 0, 25, 1, 7, 0, 26, 1,
+ 7, 0, 27, 1, 7, 0, 28, 1, 2, 0, 29, 1, 2, 0, 30, 1, 44, 0, 31, 1, 31, 0, 63, 0, 30, 0,129, 0, 34, 0,102, 0,
+ 54, 0, 2, 0, 27, 0, 31, 0, 31, 0, 63, 0, 55, 0,128, 0, 27, 0, 31, 0, 2, 0,153, 0, 2, 0, 20, 0, 7, 0,158, 0,
+ 7, 0,159, 0, 7, 0,160, 0, 7, 0, 32, 1, 7, 0, 33, 1, 7, 0, 34, 1, 7, 0, 35, 1, 7, 0, 36, 1, 7, 0, 37, 1,
+ 7, 0, 38, 1, 7, 0, 39, 1, 7, 0, 40, 1, 7, 0, 41, 1, 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, 7, 0, 53, 1,
+ 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 7, 0, 57, 1, 7, 0, 58, 1, 2, 0, 59, 1, 2, 0, 60, 1, 2, 0, 61, 1,
+ 0, 0, 62, 1, 0, 0, 63, 1, 7, 0, 64, 1, 7, 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, 73, 1, 4, 0,242, 0, 4, 0, 74, 1, 2, 0, 75, 1, 2, 0, 76, 1,
+ 2, 0, 77, 1, 2, 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, 0, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1,
+ 7, 0, 93, 1, 0, 0, 94, 1, 0, 0, 17, 1, 0, 0, 95, 1, 0, 0, 96, 1, 2, 0, 97, 1, 2, 0, 98, 1, 2, 0, 99, 1,
+ 2, 0,100, 1, 2, 0,101, 1, 2, 0,102, 1, 7, 0,103, 1, 7, 0,104, 1, 7, 0,105, 1, 7, 0,106, 1, 7, 0,107, 1,
+ 2, 0,139, 0, 2, 0,140, 0, 48, 0,108, 1, 48, 0,109, 1, 0, 0,110, 1, 0, 0,111, 1, 0, 0,112, 1, 0, 0,113, 1,
+ 2, 0,114, 1, 2, 0,253, 0, 7, 0,115, 1, 7, 0,116, 1, 44, 0, 31, 1, 56, 0,117, 1, 31, 0, 63, 0, 57, 0,118, 1,
+ 30, 0,129, 0, 7, 0,119, 1, 7, 0,120, 1, 7, 0,121, 1, 7, 0,122, 1, 7, 0,123, 1, 2, 0,124, 1, 2, 0, 54, 0,
+ 7, 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, 2, 0,134, 1, 2, 0,135, 1, 7, 0,136, 1, 7, 0,137, 1, 7, 0,138, 1, 7, 0,139, 1, 7, 0,140, 1,
+ 4, 0,141, 1, 4, 0,142, 1, 4, 0,143, 1, 34, 0,102, 0, 58, 0, 6, 0, 27, 0, 31, 0, 0, 0,144, 1, 7, 0,145, 1,
+ 7, 0, 16, 0, 59, 0, 2, 0, 37, 0,128, 0, 60, 0, 26, 0, 60, 0, 0, 0, 60, 0, 1, 0, 61, 0,146, 1, 4, 0,147, 1,
+ 4, 0,148, 1, 4, 0,149, 1, 4, 0,150, 1, 4, 0,151, 1, 4, 0,152, 1, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,153, 1,
+ 2, 0,154, 1, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0,155, 1, 7, 0,156, 1, 7, 0,157, 1, 7, 0,158, 1,
+ 7, 0,159, 1, 7, 0,160, 1, 7, 0,161, 1, 7, 0, 23, 0, 7, 0,162, 1, 7, 0,163, 1, 62, 0, 15, 0, 27, 0, 31, 0,
+ 61, 0,146, 1, 12, 0,164, 1, 12, 0,165, 1, 31, 0, 63, 0, 55, 0,166, 1, 2, 0, 20, 0, 2, 0,167, 1, 4, 0,152, 0,
+ 7, 0,236, 0, 7, 0,151, 0, 7, 0,237, 0, 7, 0,168, 1, 7, 0,169, 1, 7, 0,170, 1, 63, 0, 10, 0, 7, 0,171, 1,
+ 7, 0,172, 1, 7, 0,173, 1, 7, 0,174, 1, 2, 0,175, 1, 2, 0,176, 1, 0, 0,177, 1, 0, 0,178, 1, 0, 0,179, 1,
+ 0, 0,180, 1, 64, 0, 7, 0, 7, 0,181, 1, 7, 0,172, 1, 7, 0,173, 1, 2, 0,177, 1, 2, 0,180, 1, 7, 0,174, 1,
+ 7, 0, 16, 0, 65, 0, 21, 0, 65, 0, 0, 0, 65, 0, 1, 0, 2, 0, 18, 0, 2, 0,182, 1, 2, 0,180, 1, 2, 0, 20, 0,
+ 2, 0,183, 1, 2, 0,184, 1, 2, 0,185, 1, 2, 0,186, 1, 2, 0,187, 1, 2, 0,188, 1, 2, 0,189, 1, 2, 0,190, 1,
+ 7, 0,191, 1, 7, 0,192, 1, 64, 0,193, 1, 63, 0,194, 1, 2, 0,195, 1, 2, 0, 16, 0, 4, 0,196, 1, 66, 0, 5, 0,
+ 2, 0,197, 1, 2, 0,182, 1, 0, 0, 20, 0, 0, 0, 16, 0, 2, 0, 54, 0, 67, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0,
+ 7, 0, 8, 0, 7, 0,198, 1, 68, 0, 57, 0, 27, 0, 31, 0, 61, 0,146, 1, 12, 0,199, 1, 12, 0,165, 1, 39, 0,200, 1,
+ 39, 0,201, 1, 39, 0,202, 1, 31, 0, 63, 0, 69, 0,203, 1, 33, 0,204, 1, 55, 0,166, 1, 12, 0,205, 1, 7, 0,236, 0,
+ 7, 0,151, 0, 7, 0,237, 0, 4, 0,152, 0, 2, 0,206, 1, 2, 0,167, 1, 2, 0, 20, 0, 2, 0,207, 1, 7, 0,208, 1,
+ 7, 0,209, 1, 7, 0,210, 1, 2, 0,185, 1, 2, 0,186, 1, 2, 0,211, 1, 2, 0,212, 1, 4, 0, 54, 0, 2, 0, 23, 0,
+ 2, 0, 77, 0, 2, 0, 49, 0, 2, 0,213, 1, 7, 0,214, 1, 7, 0,215, 1, 7, 0,216, 1, 7, 0,217, 1, 7, 0,218, 1,
+ 7, 0,219, 1, 7, 0,220, 1, 7, 0,221, 1, 7, 0,222, 1, 7, 0,223, 1, 0, 0,224, 1, 0, 0,225, 1, 58, 0,226, 1,
+ 58, 0,227, 1, 58, 0,228, 1, 58, 0,229, 1, 4, 0,230, 1, 4, 0,231, 1, 4, 0,232, 1, 4, 0, 16, 0, 67, 0,233, 1,
+ 4, 0,234, 1, 4, 0,235, 1, 66, 0,236, 1, 66, 0,237, 1, 70, 0, 6, 0, 39, 0,241, 0, 2, 0, 46, 0, 2, 0, 51, 0,
+ 2, 0, 18, 0, 2, 0, 20, 0, 0, 0,238, 1, 71, 0, 21, 0, 71, 0, 0, 0, 71, 0, 1, 0, 64, 0,193, 1, 63, 0,194, 1,
+ 24, 0,239, 1, 24, 0,240, 1, 2, 0, 46, 0, 2, 0, 51, 0, 2, 0,241, 1, 2, 0,242, 1, 2, 0,243, 1, 2, 0,244, 1,
+ 2, 0, 20, 0, 2, 0,163, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, 0,245, 1, 7, 0,246, 1, 7, 0,247, 1, 7, 0, 50, 0,
+ 70, 0,248, 1, 72, 0, 39, 0, 27, 0, 31, 0, 61, 0,146, 1, 12, 0,249, 1, 31, 0, 63, 0, 33, 0,204, 1, 55, 0,166, 1,
+ 73, 0,250, 1, 74, 0,251, 1, 75, 0,252, 1, 76, 0,253, 1, 77, 0,254, 1, 78, 0,255, 1, 79, 0, 0, 2, 80, 0, 1, 2,
+ 72, 0, 2, 2, 81, 0, 3, 2, 82, 0, 4, 2, 82, 0, 5, 2, 82, 0, 6, 2, 4, 0,242, 1, 4, 0, 7, 2, 4, 0, 8, 2,
+ 4, 0, 9, 2, 4, 0, 10, 2, 4, 0,152, 0, 7, 0,236, 0, 7, 0,151, 0, 7, 0,237, 0, 7, 0, 11, 2, 7, 0, 16, 0,
+ 2, 0, 12, 2, 2, 0, 20, 0, 2, 0, 13, 2, 2, 0, 14, 2, 2, 0,167, 1, 2, 0, 15, 2, 83, 0, 16, 2, 84, 0, 17, 2,
+ 9, 0,138, 0, 75, 0, 8, 0, 9, 0, 18, 2, 7, 0, 19, 2, 4, 0, 20, 2, 0, 0, 20, 0, 0, 0, 21, 2, 2, 0,242, 0,
+ 2, 0, 22, 2, 2, 0, 23, 2, 73, 0, 8, 0, 4, 0, 24, 2, 4, 0, 25, 2, 4, 0, 26, 2, 4, 0, 27, 2, 0, 0, 16, 0,
+ 0, 0,182, 1, 0, 0, 28, 2, 0, 0, 20, 0, 77, 0, 5, 0, 4, 0, 24, 2, 4, 0, 25, 2, 0, 0, 29, 2, 0, 0, 16, 0,
+ 2, 0, 20, 0, 85, 0, 2, 0, 4, 0, 30, 2, 7, 0,173, 1, 78, 0, 3, 0, 85, 0, 31, 2, 4, 0, 32, 2, 4, 0, 20, 0,
+ 76, 0, 4, 0, 7, 0, 33, 2, 2, 0, 34, 2, 0, 0, 20, 0, 0, 0,182, 1, 79, 0, 4, 0, 0, 0,183, 0, 0, 0,158, 0,
+ 0, 0,159, 0, 0, 0,160, 0, 80, 0, 1, 0, 7, 0, 35, 2, 81, 0, 2, 0, 4, 0, 36, 2, 4, 0, 18, 0, 74, 0, 7, 0,
+ 7, 0, 19, 2, 41, 0, 18, 2, 0, 0, 20, 0, 0, 0, 21, 2, 2, 0,242, 0, 2, 0, 22, 2, 2, 0, 23, 2, 86, 0, 1, 0,
+ 7, 0, 37, 2, 87, 0, 1, 0, 4, 0, 38, 2, 88, 0, 1, 0, 0, 0, 39, 2, 89, 0, 1, 0, 7, 0, 19, 2, 90, 0, 4, 0,
+ 7, 0,183, 0, 7, 0,158, 0, 7, 0,159, 0, 7, 0,160, 0, 91, 0, 1, 0, 90, 0, 20, 2, 92, 0, 5, 0, 4, 0, 40, 2,
+ 4, 0, 41, 2, 0, 0, 20, 0, 0, 0,182, 1, 0, 0, 42, 2, 93, 0, 2, 0, 4, 0, 43, 2, 4, 0, 41, 2, 94, 0, 14, 0,
+ 94, 0, 0, 0, 94, 0, 1, 0, 92, 0, 44, 2, 91, 0, 45, 2, 93, 0, 46, 2, 0, 0, 47, 2, 12, 0, 48, 2, 12, 0, 49, 2,
+ 95, 0, 50, 2, 4, 0,242, 1, 4, 0, 8, 2, 4, 0, 7, 2, 4, 0, 16, 0, 76, 0, 51, 2, 83, 0, 14, 0, 12, 0, 52, 2,
+ 76, 0, 51, 2, 0, 0, 53, 2, 0, 0, 54, 2, 0, 0, 55, 2, 0, 0, 56, 2, 0, 0, 57, 2, 0, 0, 58, 2, 0, 0, 59, 2,
+ 0, 0, 20, 0, 82, 0, 4, 2, 82, 0, 6, 2, 2, 0, 60, 2, 0, 0, 61, 2, 84, 0, 8, 0, 4, 0, 62, 2, 4, 0, 63, 2,
+ 73, 0, 64, 2, 77, 0, 65, 2, 4, 0, 8, 2, 4, 0, 7, 2, 4, 0,242, 1, 4, 0, 16, 0, 96, 0, 6, 0, 96, 0, 0, 0,
+ 96, 0, 1, 0, 4, 0, 18, 0, 4, 0,242, 0, 0, 0, 17, 0, 0, 0, 66, 2, 97, 0, 7, 0, 96, 0, 67, 2, 2, 0, 68, 2,
+ 2, 0, 52, 2, 2, 0, 69, 2, 2, 0, 75, 0, 9, 0, 70, 2, 9, 0, 71, 2, 98, 0, 3, 0, 96, 0, 67, 2, 39, 0,143, 0,
+ 0, 0, 17, 0, 99, 0, 5, 0, 96, 0, 67, 2, 39, 0,143, 0, 0, 0, 17, 0, 2, 0, 72, 2, 0, 0, 73, 2,100, 0, 5, 0,
+ 96, 0, 67, 2, 7, 0, 74, 2, 7, 0, 75, 2, 4, 0, 76, 2, 4, 0, 77, 2,101, 0, 13, 0, 96, 0, 67, 2, 39, 0, 78, 2,
+ 39, 0, 79, 2, 39, 0, 80, 2, 39, 0, 81, 2, 7, 0, 82, 2, 7, 0, 83, 2, 7, 0, 75, 2, 7, 0, 84, 2, 4, 0, 85, 2,
+ 4, 0, 86, 2, 4, 0, 75, 0, 4, 0, 87, 2,102, 0, 5, 0, 96, 0, 67, 2, 2, 0, 88, 2, 2, 0, 20, 0, 7, 0, 89, 2,
+ 39, 0, 90, 2,103, 0, 3, 0, 96, 0, 67, 2, 7, 0, 91, 2, 4, 0, 75, 0,104, 0, 11, 0, 96, 0, 67, 2, 45, 0, 92, 2,
+ 7, 0, 93, 2, 4, 0, 94, 2, 0, 0, 95, 2, 7, 0, 96, 2, 4, 0, 97, 2, 39, 0, 98, 2, 0, 0, 99, 2, 4, 0,100, 2,
+ 4, 0, 16, 0,105, 0, 10, 0, 96, 0, 67, 2, 39, 0,101, 2, 41, 0,102, 2, 4, 0, 75, 0, 4, 0,103, 2, 7, 0,104, 2,
+ 7, 0,105, 2, 0, 0, 99, 2, 4, 0,100, 2, 4, 0, 16, 0,106, 0, 3, 0, 96, 0, 67, 2, 7, 0,106, 2, 4, 0,107, 2,
+107, 0, 5, 0, 96, 0, 67, 2, 7, 0,108, 2, 0, 0, 95, 2, 2, 0, 20, 0, 2, 0,109, 2,108, 0, 8, 0, 96, 0, 67, 2,
+ 39, 0,143, 0, 7, 0,108, 2, 7, 0,174, 1, 7, 0, 86, 0, 0, 0, 95, 2, 2, 0, 20, 0, 2, 0, 18, 0,109, 0, 19, 0,
+ 96, 0, 67, 2, 39, 0,110, 2, 0, 0, 95, 2, 45, 0, 92, 2, 39, 0, 98, 2, 2, 0, 20, 0, 2, 0, 16, 0, 7, 0,111, 2,
+ 7, 0,112, 2, 7, 0,113, 2, 7, 0,208, 1, 7, 0,114, 2, 7, 0,115, 2, 7, 0,116, 2, 4, 0, 97, 2, 4, 0,100, 2,
+ 0, 0, 99, 2, 7, 0,117, 2, 7, 0,118, 2,110, 0, 7, 0, 96, 0, 67, 2, 2, 0,119, 2, 2, 0,120, 2, 4, 0, 54, 0,
+ 39, 0,143, 0, 7, 0,121, 2, 0, 0, 95, 2,111, 0, 9, 0, 96, 0, 67, 2, 39, 0,143, 0, 7, 0,122, 2, 7, 0,123, 2,
+ 7, 0,124, 2, 4, 0,125, 2, 4, 0,126, 2, 7, 0,127, 2, 0, 0, 17, 0,112, 0, 1, 0, 96, 0, 67, 2,113, 0, 4, 0,
+ 96, 0, 67, 2,114, 0,128, 2,115, 0,129, 2,116, 0,130, 2,117, 0, 13, 0, 96, 0, 67, 2, 76, 0,131, 2, 76, 0,132, 2,
+ 76, 0,133, 2, 76, 0,134, 2, 76, 0,135, 2, 76, 0,136, 2, 73, 0,137, 2, 4, 0,138, 2, 4, 0,139, 2, 4, 0, 16, 0,
+ 7, 0,140, 2,118, 0,141, 2,119, 0, 4, 0, 96, 0, 67, 2, 39, 0,143, 0, 4, 0,142, 2, 4, 0, 16, 0,120, 0, 2, 0,
+ 4, 0,143, 2, 7, 0,173, 1,121, 0, 2, 0, 4, 0,106, 0, 4, 0,144, 2,122, 0, 20, 0, 96, 0, 67, 2, 39, 0,143, 0,
+ 0, 0, 95, 2, 2, 0,145, 2, 2, 0,146, 2, 2, 0, 20, 0, 2, 0, 16, 0, 7, 0,147, 2, 7, 0,148, 2, 4, 0,242, 1,
+ 4, 0,149, 2,121, 0,150, 2,120, 0,151, 2, 4, 0,152, 2, 4, 0,153, 2, 4, 0,154, 2, 4, 0,144, 2, 7, 0,155, 2,
+ 7, 0,156, 2, 7, 0,157, 2,123, 0, 8, 0, 96, 0, 67, 2,124, 0,158, 2,125, 0,159, 2, 4, 0,160, 2, 4, 0,161, 2,
+ 4, 0,162, 2, 2, 0, 20, 0, 2, 0,163, 0,126, 0, 5, 0, 96, 0, 67, 2, 39, 0,241, 0, 2, 0,163, 2, 2, 0, 20, 0,
+ 2, 0,164, 2,127, 0, 5, 0, 96, 0, 67, 2, 4, 0,165, 2, 2, 0, 20, 0, 2, 0,166, 2, 7, 0,167, 2,128, 0, 24, 0,
+ 27, 0, 31, 0, 2, 0,183, 1, 2, 0,184, 1, 2, 0,168, 2, 2, 0, 20, 0, 2, 0,169, 2, 2, 0,170, 2, 2, 0,171, 2,
+ 2, 0, 54, 0, 0, 0,172, 2, 0, 0,173, 2, 0, 0,174, 2, 0, 0, 18, 0, 4, 0, 16, 0, 7, 0,175, 2, 7, 0,176, 2,
+ 7, 0,177, 2, 7, 0,178, 2, 7, 0,179, 2, 7, 0,180, 2, 64, 0,181, 2, 31, 0, 63, 0, 33, 0,204, 1, 78, 0,255, 1,
+129, 0, 3, 0,129, 0, 0, 0,129, 0, 1, 0, 0, 0, 17, 0, 61, 0, 3, 0, 7, 0,182, 2, 4, 0, 20, 0, 4, 0, 16, 0,
+ 39, 0,106, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0,183, 2, 4, 0,184, 2, 4, 0,185, 2, 4, 0,186, 2, 0, 0,187, 2,
+ 39, 0, 37, 0, 39, 0,188, 2, 39, 0,189, 2, 39, 0,190, 2, 39, 0,191, 2, 31, 0, 63, 0, 69, 0,203, 1, 61, 0,146, 1,
+130, 0,192, 2,130, 0,193, 2,131, 0,194, 2, 9, 0, 2, 0, 12, 0,195, 2, 12, 0,249, 1, 12, 0,165, 1, 12, 0,196, 2,
+ 12, 0,197, 2, 55, 0,166, 1, 7, 0,236, 0, 7, 0,198, 2, 7, 0,199, 2, 7, 0,151, 0, 7, 0,200, 2, 7, 0,237, 0,
+ 7, 0,201, 2, 7, 0,155, 1, 7, 0,202, 2, 7, 0,203, 2, 7, 0,122, 2, 7, 0,204, 2, 7, 0,187, 0, 4, 0,205, 2,
+ 2, 0, 20, 0, 2, 0,206, 2, 2, 0,207, 2, 2, 0,208, 2, 2, 0,209, 2, 2, 0,210, 2, 2, 0,211, 2, 2, 0,212, 2,
+ 2, 0,213, 2, 2, 0,214, 2, 2, 0,215, 2, 2, 0,216, 2, 4, 0,217, 2, 4, 0,218, 2, 4, 0,219, 2, 4, 0,220, 2,
+ 7, 0,221, 2, 7, 0,222, 2, 7, 0,223, 2, 7, 0,224, 2, 7, 0,225, 2, 7, 0,226, 2, 7, 0,227, 2, 7, 0,228, 2,
+ 0, 0,229, 2, 0, 0,230, 2, 0, 0,167, 1, 0, 0,231, 2, 0, 0,232, 2, 0, 0,233, 2, 7, 0,234, 2, 7, 0,235, 2,
+ 34, 0,102, 0, 12, 0,236, 2, 12, 0,237, 2, 12, 0,238, 2, 12, 0,239, 2, 9, 0,240, 2, 7, 0,241, 2, 2, 0, 36, 2,
+ 2, 0,242, 2, 7, 0, 20, 2, 4, 0,243, 2, 4, 0,244, 2, 2, 0,245, 2, 2, 0,194, 0, 7, 0,246, 2, 12, 0,247, 2,
+ 12, 0,248, 2, 12, 0,249, 2, 12, 0,250, 2,132, 0,251, 2,133, 0,252, 2, 57, 0,253, 2, 2, 0,254, 2, 2, 0,255, 2,
+ 2, 0, 0, 3, 2, 0, 1, 3, 7, 0, 12, 2, 2, 0, 2, 3, 2, 0, 3, 3,134, 0, 4, 3,125, 0, 5, 3,125, 0, 6, 3,
+ 4, 0, 7, 3, 4, 0, 16, 0, 9, 0,138, 0,135, 0, 14, 0,135, 0, 0, 0,135, 0, 1, 0, 39, 0, 37, 0, 7, 0,122, 2,
+ 7, 0,238, 0, 7, 0,123, 2, 7, 0,124, 2, 0, 0, 17, 0, 4, 0,125, 2, 4, 0,126, 2, 4, 0, 8, 3, 2, 0, 18, 0,
+ 2, 0, 9, 3, 7, 0,127, 2,132, 0, 33, 0, 2, 0, 10, 3, 2, 0, 11, 3, 2, 0, 20, 0, 2, 0,124, 2, 7, 0, 12, 3,
+ 7, 0, 13, 3, 7, 0, 14, 3, 7, 0, 15, 3, 7, 0, 16, 3, 7, 0, 17, 3, 7, 0, 18, 3, 7, 0, 19, 3, 7, 0, 20, 3,
+ 7, 0, 21, 3, 7, 0, 22, 3, 7, 0, 23, 3, 7, 0, 24, 3, 7, 0, 25, 3, 7, 0, 26, 3, 7, 0, 27, 3, 7, 0, 28, 3,
+ 7, 0, 29, 3, 7, 0, 30, 3, 7, 0, 31, 3, 7, 0, 32, 3, 7, 0, 33, 3, 7, 0, 34, 3, 7, 0, 35, 3, 2, 0, 36, 3,
+ 2, 0, 37, 3, 2, 0, 38, 3, 2, 0, 39, 3, 45, 0,144, 0,136, 0, 1, 0, 7, 0,181, 1,133, 0, 43, 0,124, 0, 40, 3,
+ 4, 0, 41, 3, 4, 0, 42, 3,137, 0, 43, 3,138, 0, 44, 3, 7, 0,222, 2, 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, 7, 0, 52, 3, 7, 0, 53, 3, 7, 0, 54, 3, 2, 0, 55, 3,
+ 2, 0, 56, 3, 7, 0, 57, 3, 7, 0, 58, 3, 4, 0,107, 0, 4, 0, 59, 3, 4, 0, 60, 3, 2, 0, 61, 3, 2, 0, 62, 3,
+136, 0, 63, 3, 4, 0, 64, 3, 4, 0, 65, 0, 7, 0, 65, 3, 7, 0, 66, 3, 7, 0, 67, 3, 7, 0, 68, 3, 2, 0, 69, 3,
+ 2, 0, 70, 3, 2, 0, 71, 3, 2, 0, 72, 3, 2, 0, 73, 3, 2, 0, 74, 3, 2, 0, 75, 3, 2, 0, 76, 3,139, 0, 77, 3,
+ 7, 0, 78, 3, 7, 0, 79, 3,134, 0, 40, 0, 2, 0, 18, 0, 2, 0, 80, 3, 2, 0, 81, 3, 2, 0, 82, 3, 7, 0, 83, 3,
+ 2, 0, 84, 3, 2, 0, 85, 3, 7, 0, 86, 3, 2, 0, 87, 3, 2, 0, 88, 3, 7, 0, 89, 3, 7, 0, 90, 3, 7, 0, 91, 3,
+ 7, 0, 92, 3, 7, 0, 93, 3, 7, 0, 94, 3, 4, 0, 95, 3, 7, 0, 96, 3, 7, 0, 97, 3, 7, 0, 98, 3, 72, 0, 99, 3,
+ 72, 0,100, 3, 72, 0,101, 3, 0, 0,102, 3, 7, 0,103, 3, 7, 0,104, 3, 31, 0, 63, 0, 2, 0,105, 3, 0, 0,106, 3,
+ 0, 0,107, 3, 7, 0,108, 3, 4, 0,109, 3, 7, 0,110, 3, 7, 0,111, 3, 4, 0,112, 3, 4, 0,113, 3, 7, 0,114, 3,
+ 7, 0,115, 3, 7, 0,116, 3, 76, 0,117, 3,140, 0, 66, 0, 27, 0, 31, 0, 2, 0,153, 0, 2, 0,243, 0, 2, 0, 17, 1,
+ 2, 0,118, 3, 7, 0,119, 3, 7, 0,120, 3, 7, 0,121, 3, 7, 0,122, 3, 7, 0,123, 3, 7, 0,124, 3, 7, 0,125, 3,
+ 7, 0,126, 3, 7, 0, 38, 1, 7, 0, 40, 1, 7, 0, 39, 1, 7, 0,127, 3, 4, 0,128, 3, 7, 0,129, 3, 7, 0,130, 3,
+ 7, 0,131, 3, 7, 0,132, 3, 7, 0,133, 3, 7, 0,134, 3, 7, 0,135, 3, 2, 0,136, 3, 2, 0,242, 0, 4, 0,137, 3,
+ 7, 0,138, 3, 7, 0,139, 3, 7, 0,140, 3, 7, 0,141, 3, 7, 0,142, 3, 7, 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, 2, 0,150, 3, 2, 0,151, 3, 2, 0,152, 3, 2, 0,153, 3,
+ 7, 0,154, 3, 7, 0,155, 3, 7, 0,156, 3, 7, 0,157, 3, 2, 0,158, 3, 2, 0,159, 3, 2, 0,160, 3, 2, 0,161, 3,
+ 7, 0,162, 3, 7, 0,163, 3, 7, 0,164, 3, 7, 0,165, 3, 2, 0,166, 3, 2, 0,167, 3, 2, 0,168, 3, 2, 0, 42, 0,
+ 7, 0,169, 3, 7, 0,170, 3, 31, 0, 63, 0, 44, 0, 31, 1, 30, 0,129, 0, 34, 0,102, 0,141, 0, 16, 0, 2, 0,171, 3,
+ 2, 0,172, 3, 2, 0,173, 3, 2, 0, 20, 0, 2, 0,174, 3, 2, 0,175, 3, 2, 0,176, 3, 2, 0,177, 3, 2, 0,178, 3,
+ 2, 0,179, 3, 2, 0,180, 3, 2, 0,181, 3, 4, 0,182, 3, 7, 0,183, 3, 7, 0,184, 3, 7, 0,185, 3,142, 0, 8, 0,
+142, 0, 0, 0,142, 0, 1, 0, 4, 0,205, 2, 4, 0,186, 3, 4, 0, 20, 0, 2, 0,187, 3, 2, 0,188, 3, 39, 0,143, 0,
+143, 0, 13, 0, 9, 0,189, 3, 9, 0,190, 3, 4, 0,191, 3, 4, 0,192, 3, 4, 0,193, 3, 4, 0,194, 3, 4, 0,195, 3,
+ 4, 0,196, 3, 4, 0,197, 3, 4, 0,198, 3, 4, 0,199, 3, 4, 0, 16, 0, 0, 0,200, 3,144, 0, 5, 0, 9, 0,201, 3,
+ 9, 0,202, 3, 4, 0,203, 3, 4, 0, 54, 0, 0, 0,204, 3,145, 0, 12, 0, 4, 0, 18, 0, 4, 0,205, 3, 4, 0,206, 3,
+ 4, 0,207, 3, 4, 0,208, 3, 4, 0,209, 3, 4, 0, 75, 0, 4, 0,210, 3, 4, 0,211, 3, 4, 0,212, 3, 4, 0,213, 3,
+ 4, 0,214, 3,146, 0, 4, 0, 4, 0,215, 3, 7, 0,216, 3, 2, 0, 20, 0, 2, 0,157, 0,147, 0, 11, 0,147, 0, 0, 0,
+147, 0, 1, 0, 0, 0, 17, 0, 55, 0,217, 3, 57, 0,218, 3, 4, 0,205, 2, 4, 0,219, 3, 4, 0,220, 3, 4, 0, 16, 0,
+ 4, 0,221, 3, 4, 0,222, 3,148, 0,113, 0,143, 0,223, 3,144, 0,224, 3,145, 0,225, 3, 4, 0,226, 3, 4, 0,107, 0,
+ 4, 0, 59, 3, 4, 0,227, 3, 4, 0,228, 3, 4, 0,229, 3, 4, 0,230, 3, 2, 0, 20, 0, 2, 0,231, 3, 7, 0,222, 2,
+ 7, 0,232, 3, 7, 0,233, 3, 7, 0,234, 3, 7, 0,235, 3, 7, 0,236, 3, 2, 0,237, 3, 2, 0,238, 3, 2, 0,239, 3,
+ 2, 0,240, 3, 2, 0,193, 0, 2, 0,241, 3, 2, 0,242, 3, 2, 0, 39, 3, 2, 0,243, 3, 2, 0,244, 3, 2, 0, 4, 1,
+ 2, 0, 86, 0, 2, 0,245, 3, 2, 0,246, 3, 2, 0,247, 3, 2, 0,248, 3, 2, 0,249, 3, 2, 0,250, 3, 2, 0,251, 3,
+ 2, 0,252, 3, 2, 0,253, 3, 2, 0,254, 3, 2, 0,255, 3, 2, 0, 5, 1, 2, 0, 0, 4, 2, 0, 1, 4, 4, 0,242, 0,
+ 2, 0, 2, 4, 2, 0, 3, 4, 2, 0, 4, 4, 2, 0, 5, 4, 2, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 24, 0, 9, 4,
+ 24, 0, 10, 4, 23, 0, 11, 4, 12, 0, 12, 4, 2, 0, 13, 4, 2, 0, 16, 0, 7, 0, 14, 4, 7, 0, 15, 4, 7, 0, 16, 4,
+ 7, 0, 17, 4, 7, 0, 18, 4, 7, 0, 19, 4, 7, 0, 20, 4, 2, 0, 21, 4, 2, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4,
+ 2, 0, 25, 4, 2, 0, 26, 4, 7, 0, 27, 4, 2, 0, 28, 4, 2, 0, 29, 4, 2, 0, 30, 4, 2, 0, 31, 4, 2, 0, 32, 4,
+ 2, 0, 33, 4, 2, 0, 34, 4, 2, 0, 35, 4, 2, 0, 36, 4, 2, 0, 37, 4, 4, 0, 38, 4, 4, 0, 39, 4, 4, 0, 40, 4,
+ 4, 0, 41, 4, 4, 0, 42, 4, 7, 0, 43, 4, 4, 0, 44, 4, 4, 0, 45, 4, 4, 0, 46, 4, 4, 0, 47, 4, 7, 0, 48, 4,
+ 7, 0, 49, 4, 7, 0, 50, 4, 7, 0, 51, 4, 7, 0, 52, 4, 7, 0, 53, 4, 7, 0, 54, 4, 7, 0, 55, 4, 7, 0, 56, 4,
+ 0, 0, 57, 4, 0, 0, 58, 4, 4, 0, 59, 4, 2, 0, 60, 4, 2, 0,253, 0, 0, 0, 61, 4, 7, 0, 62, 4, 7, 0, 63, 4,
+ 4, 0, 64, 4, 4, 0, 65, 4, 7, 0, 66, 4, 7, 0, 67, 4,149, 0, 5, 0, 7, 0, 68, 4, 0, 0, 18, 0, 0, 0, 42, 0,
+ 0, 0, 54, 0, 0, 0,253, 0,150, 0, 5, 0,150, 0, 0, 0,150, 0, 1, 0, 4, 0, 69, 4, 0, 0, 70, 4, 4, 0, 20, 0,
+151, 0, 4, 0,152, 0, 71, 4, 2, 0, 20, 0, 2, 0, 72, 4, 4, 0,253, 0,153, 0, 6, 0, 2, 0, 86, 0, 2, 0, 93, 2,
+ 2, 0, 20, 0, 2, 0, 73, 4, 2, 0, 74, 4, 2, 0,157, 0,154, 0, 7, 0, 2, 0, 20, 0, 2, 0, 75, 4, 2, 0, 76, 4,
+ 2, 0, 77, 4,153, 0, 78, 4, 7, 0, 79, 4, 4, 0, 80, 4,155, 0, 4, 0,155, 0, 0, 0,155, 0, 1, 0, 0, 0, 81, 4,
+ 7, 0, 82, 4,156, 0, 41, 0, 2, 0, 83, 4, 2, 0, 84, 4, 7, 0, 85, 4, 7, 0, 86, 4, 2, 0, 73, 4, 2, 0, 87, 4,
+ 7, 0, 88, 4, 7, 0, 89, 4, 2, 0, 90, 4, 2, 0, 91, 4, 2, 0, 92, 4, 2, 0, 93, 4, 7, 0, 94, 4, 7, 0, 95, 4,
+ 2, 0, 96, 4, 2, 0, 97, 4, 2, 0, 98, 4, 2, 0, 99, 4,151, 0,100, 4,154, 0,101, 4, 7, 0,102, 4, 7, 0,103, 4,
+ 0, 0,104, 4, 0, 0,105, 4, 0, 0,106, 4, 0, 0,107, 4, 0, 0,108, 4, 0, 0,109, 4, 2, 0,110, 4, 7, 0,111, 4,
+ 7, 0,112, 4, 7, 0,113, 4, 7, 0,114, 4, 7, 0,115, 4, 7, 0,116, 4, 7, 0,117, 4, 2, 0,118, 4, 0, 0,119, 4,
+ 0, 0,120, 4, 0, 0,121, 4, 0, 0,122, 4,157, 0, 6, 0, 2, 0, 86, 0, 0, 0, 93, 2, 0, 0,123, 4, 0, 0,124, 4,
+ 0, 0, 20, 0, 0, 0, 42, 2,158, 0, 24, 0,159, 0,125, 4, 44, 0, 31, 1, 53, 0,126, 4,157, 0,127, 4,157, 0,128, 4,
+157, 0,129, 4,157, 0,130, 4,157, 0,131, 4,157, 0,132, 4,157, 0,133, 4, 2, 0,134, 4, 2, 0, 17, 1, 2, 0,135, 4,
+ 2, 0,214, 1, 0, 0,136, 4, 0, 0,137, 4, 0, 0,138, 4, 0, 0,139, 4, 0, 0, 75, 0, 0, 0,140, 4, 0, 0,141, 4,
+ 0, 0,142, 4, 0, 0,143, 4, 0, 0,144, 4,160, 0, 41, 0, 27, 0, 31, 0, 39, 0,145, 4,140, 0,146, 4,160, 0,147, 4,
+ 41, 0,185, 0, 12, 0,148, 4,142, 0,149, 4, 7, 0,150, 4, 7, 0,151, 4, 7, 0,152, 4, 7, 0,153, 4, 4, 0,205, 2,
+ 7, 0,154, 4, 2, 0,155, 4, 2, 0,156, 4, 2, 0,157, 4, 2, 0,158, 4, 2, 0, 76, 3, 2, 0,159, 4, 2, 0,160, 4,
+ 2, 0, 96, 1, 56, 0,117, 1, 9, 0,161, 4,141, 0,162, 4,149, 0,163, 4,156, 0,164, 4,148, 0,158, 0,146, 0,165, 4,
+ 34, 0,102, 0, 12, 0,166, 4, 12, 0,167, 4, 2, 0,168, 4, 2, 0, 42, 0, 2, 0,169, 4, 2, 0,170, 4,161, 0,171, 4,
+ 2, 0,172, 4, 2, 0,173, 4, 2, 0, 3, 3, 2, 0,194, 0,158, 0,174, 4,162, 0, 9, 0, 41, 0,185, 0, 40, 0,232, 0,
+ 7, 0,221, 1, 7, 0,222, 1, 7, 0, 86, 0, 7, 0,175, 4, 7, 0,176, 4, 2, 0,177, 4, 2, 0,178, 4,163, 0, 68, 0,
+164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4, 7, 0,183, 4, 7, 0,184, 4,
+ 7, 0,185, 4, 7, 0,186, 4, 7, 0,187, 4, 7, 0,188, 4, 7, 0,189, 4, 7, 0,245, 0, 7, 0,190, 4, 7, 0, 41, 0,
+ 2, 0,191, 4, 2, 0,124, 4, 39, 0,145, 4, 39, 0,192, 4,162, 0,193, 4,163, 0,194, 4,166, 0,195, 4,167, 0,196, 4,
+168, 0,197, 4, 0, 0,198, 4, 2, 0,173, 3, 2, 0,199, 4, 4, 0,205, 2, 4, 0,200, 4, 2, 0,201, 4, 2, 0,202, 4,
+ 2, 0,203, 4, 0, 0,204, 4, 0, 0, 42, 0, 7, 0, 92, 0, 7, 0,205, 4, 7, 0,206, 4, 7, 0,207, 4, 7, 0,208, 4,
+ 7, 0,209, 4, 7, 0,210, 4, 7, 0,211, 4, 7, 0,150, 0, 7, 0,150, 4, 2, 0,212, 4, 2, 0,213, 4, 2, 0,214, 4,
+ 2, 0,215, 4, 2, 0,114, 0, 2, 0,135, 4, 2, 0,216, 4, 2, 0,217, 4, 2, 0,218, 4, 2, 0,219, 4, 7, 0,220, 4,
+ 7, 0,221, 4, 61, 0,222, 4, 12, 0,223, 4, 2, 0,224, 4, 2, 0, 21, 2, 2, 0,225, 4, 2, 0, 20, 0, 2, 0,226, 4,
+ 2, 0,227, 4, 2, 0,253, 0, 2, 0, 54, 0, 9, 0,228, 4,169, 0, 19, 0, 24, 0, 36, 0, 24, 0, 45, 0, 23, 0,229, 4,
+ 23, 0,230, 4, 23, 0,231, 4, 7, 0,232, 4, 7, 0,233, 4, 7, 0,234, 4, 7, 0,235, 4, 2, 0,236, 4, 2, 0,237, 4,
+ 2, 0,238, 4, 2, 0,239, 4, 2, 0,240, 4, 2, 0,241, 4, 4, 0, 20, 0, 7, 0,242, 4, 2, 0,202, 4, 0, 0, 73, 2,
+164, 0, 6, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4,170, 0, 6, 0,
+164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4,171, 0, 27, 0,164, 0, 0, 0,
+164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4, 4, 0,243, 4, 4, 0, 54, 0,169, 0,244, 4,
+ 9, 0,245, 4, 12, 0,246, 4, 31, 0, 63, 0, 27, 0, 64, 0, 0, 0,247, 4, 0, 0,248, 4, 0, 0,249, 4, 2, 0,250, 4,
+ 2, 0,251, 4, 2, 0,252, 4, 2, 0,253, 4, 2, 0, 47, 0, 2, 0, 46, 0, 2, 0,114, 0, 2, 0,254, 4, 4, 0, 20, 0,
+ 7, 0,255, 4, 24, 0, 36, 0,172, 0, 29, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,
+166, 0,195, 4, 2, 0,182, 4, 2, 0, 0, 5, 2, 0, 1, 5, 2, 0, 2, 5, 2, 0, 3, 5,169, 0,244, 4, 2, 0, 4, 5,
+ 2, 0,114, 0, 2, 0,251, 4, 2, 0, 5, 5, 9, 0, 6, 5, 2, 0,135, 4, 0, 0, 7, 5, 0, 0, 8, 5, 2, 0, 9, 5,
+ 2, 0, 10, 5, 2, 0,214, 2, 2, 0, 11, 5, 2, 0, 12, 5, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 17, 1, 0, 0, 13, 5,
+173, 0, 15, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4,169, 0,244, 4,
+ 7, 0,221, 1, 7, 0,222, 1, 2, 0, 4, 5, 2, 0,175, 4, 2, 0, 14, 5, 2, 0, 15, 5, 4, 0, 20, 0, 4, 0, 16, 0,
+174, 0, 33, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4,175, 0, 16, 5,
+ 4, 0, 17, 5, 0, 0, 18, 5, 0, 0, 19, 5, 0, 0, 20, 5, 2, 0, 18, 0, 2, 0, 21, 5, 2, 0, 20, 0, 2, 0, 22, 5,
+ 2, 0, 23, 5, 2, 0, 24, 5, 2, 0, 25, 5, 2, 0, 42, 0, 4, 0, 54, 0, 0, 0, 26, 5,176, 0, 27, 5, 2, 0, 28, 5,
+ 2, 0, 29, 5, 2, 0, 30, 5, 2, 0,184, 0, 9, 0, 31, 5, 9, 0, 32, 5, 9, 0, 33, 5, 9, 0, 34, 5, 9, 0, 35, 5,
+ 2, 0, 36, 5, 0, 0, 37, 5,177, 0, 31, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,
+ 2, 0,182, 4,169, 0,244, 4, 12, 0, 38, 5, 2, 0,251, 4, 2, 0, 39, 5, 2, 0, 20, 0, 2, 0,163, 0, 9, 0, 6, 5,
+ 12, 0, 40, 5,178, 0, 41, 5, 0, 0, 42, 5,179, 0, 43, 5, 4, 0, 44, 5, 4, 0, 45, 5, 2, 0, 18, 0, 2, 0, 46, 5,
+ 2, 0, 47, 5, 2, 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,
+ 2, 0, 55, 5, 0, 0, 73, 2,180, 0, 30, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,
+ 2, 0,182, 4,169, 0,244, 4, 41, 0,102, 2, 40, 0,232, 0, 53, 0,126, 4, 2, 0,242, 0, 2, 0,114, 0, 2, 0, 56, 5,
+ 2, 0, 57, 5, 4, 0, 20, 0, 2, 0, 58, 5, 2, 0,254, 4, 2, 0, 59, 5, 2, 0,251, 4, 7, 0,175, 4, 0, 0, 60, 5,
+ 0, 0, 61, 5, 0, 0, 73, 2, 7, 0,221, 1, 7, 0,222, 1, 7, 0, 62, 5, 7, 0, 63, 5, 0, 0, 64, 5, 0, 0, 65, 5,
+ 50, 0, 66, 5,181, 0, 11, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4,
+ 2, 0,114, 0, 2, 0,254, 4, 2, 0, 67, 5, 2, 0, 20, 0,169, 0,244, 4,182, 0, 22, 0,164, 0, 0, 0,164, 0, 1, 0,
+ 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4, 2, 0,182, 4, 36, 0, 68, 5, 4, 0, 69, 5, 4, 0, 70, 5, 2, 0, 75, 0,
+ 2, 0,114, 0, 4, 0, 71, 5, 4, 0, 72, 5, 4, 0, 73, 5, 4, 0, 74, 5, 4, 0, 75, 5, 4, 0, 76, 5, 4, 0, 77, 5,
+ 4, 0, 78, 5, 7, 0, 79, 5, 23, 0, 80, 5, 23, 0, 81, 5,183, 0, 10, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4,
+ 7, 0,180, 4,165, 0,181, 4,184, 0, 82, 5, 2, 0, 75, 0, 2, 0,114, 0, 4, 0, 42, 0, 9, 0, 83, 5,185, 0, 8, 0,
+164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,169, 0,244, 4, 4, 0, 20, 0, 4, 0, 84, 5,
+186, 0, 18, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,169, 0,244, 4, 27, 0, 85, 5,
+ 27, 0, 64, 0, 2, 0, 20, 0, 2, 0,114, 0, 7, 0, 86, 5, 9, 0, 87, 5, 7, 0,221, 1, 7, 0,222, 1, 56, 0,117, 1,
+ 56, 0, 88, 5, 4, 0, 89, 5, 4, 0, 16, 0,187, 0, 42, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,
+165, 0,181, 4, 2, 0,182, 4,169, 0,244, 4,188, 0, 90, 5, 0, 0, 18, 5, 0, 0, 19, 5, 0, 0, 20, 5, 2, 0, 18, 0,
+ 2, 0, 29, 5, 2, 0, 20, 0, 2, 0, 22, 5, 9, 0, 87, 5, 4, 0, 91, 5, 4, 0, 92, 5, 4, 0, 93, 5, 4, 0, 94, 5,
+ 23, 0, 95, 5, 23, 0, 96, 5, 7, 0, 97, 5, 7, 0, 98, 5, 7, 0, 99, 5, 7, 0, 86, 5, 2, 0, 28, 5, 2, 0,184, 0,
+ 2, 0, 56, 1, 2, 0,100, 5, 2, 0, 16, 0, 2, 0, 42, 0, 2, 0,101, 5, 2, 0,102, 5, 9, 0, 31, 5, 9, 0, 32, 5,
+ 9, 0, 33, 5, 9, 0, 34, 5, 9, 0, 35, 5, 2, 0, 36, 5, 0, 0, 37, 5, 50, 0,103, 5,189, 0, 20, 0, 0, 0,104, 5,
+ 0, 0,105, 5, 0, 0,106, 5, 0, 0,107, 5, 0, 0,108, 5, 0, 0,109, 5, 0, 0,110, 5, 0, 0,111, 5, 0, 0,112, 5,
+ 0, 0,113, 5, 0, 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,157, 0, 0, 0,122, 5,190, 0, 50, 0, 0, 0,123, 5, 0, 0,114, 5, 0, 0,115, 5, 0, 0,124, 5,
+ 0, 0,125, 5, 0, 0,126, 5, 0, 0,127, 5, 0, 0,128, 5, 0, 0,129, 5, 0, 0,130, 5, 0, 0,131, 5, 0, 0,132, 5,
+ 0, 0,133, 5, 0, 0,134, 5, 0, 0,135, 5, 0, 0,136, 5, 0, 0,137, 5, 0, 0,138, 5, 0, 0,139, 5, 0, 0,140, 5,
+ 0, 0,141, 5, 0, 0,142, 5, 0, 0,143, 5, 0, 0,144, 5, 0, 0,145, 5, 0, 0,146, 5, 0, 0,147, 5, 0, 0,148, 5,
+ 0, 0,149, 5, 0, 0,150, 5, 0, 0,151, 5, 0, 0,152, 5, 0, 0,153, 5, 0, 0,154, 5, 0, 0,155, 5, 0, 0,156, 5,
+ 0, 0,157, 5, 0, 0,158, 5, 0, 0,159, 5, 0, 0,160, 5, 0, 0,161, 5, 0, 0,162, 5, 0, 0,163, 5, 0, 0,164, 5,
+ 0, 0,165, 5, 0, 0,166, 5, 0, 0,167, 5, 0, 0,168, 5, 0, 0,169, 5, 0, 0,170, 5,191, 0, 5, 0, 0, 0,171, 5,
+ 0, 0,131, 5, 0, 0,133, 5, 2, 0, 20, 0, 2, 0, 16, 0,192, 0, 22, 0,192, 0, 0, 0,192, 0, 1, 0, 0, 0, 17, 0,
+189, 0,172, 5,190, 0,173, 5,190, 0,174, 5,190, 0,175, 5,190, 0,176, 5,190, 0,177, 5,190, 0,178, 5,190, 0,179, 5,
+190, 0,180, 5,190, 0,181, 5,190, 0,182, 5,190, 0,183, 5,190, 0,184, 5,190, 0,185, 5,190, 0,186, 5,190, 0,187, 5,
+191, 0,188, 5, 0, 0,189, 5, 0, 0,190, 5,193, 0, 5, 0, 4, 0, 20, 0, 4, 0, 16, 0, 7, 0, 20, 2, 7, 0,191, 5,
+ 7, 0,181, 1,194, 0, 57, 0, 4, 0, 20, 0, 4, 0,192, 5, 4, 0,193, 5, 0, 0,194, 5, 0, 0,195, 5, 0, 0,196, 5,
+ 0, 0,197, 5, 0, 0,198, 5, 0, 0,199, 5, 0, 0,200, 5, 0, 0,201, 5, 0, 0,202, 5, 2, 0,203, 5, 2, 0,204, 5,
+ 4, 0,205, 5, 4, 0,206, 5, 4, 0,207, 5, 4, 0,208, 5, 2, 0,209, 5, 2, 0,210, 5, 2, 0,211, 5, 2, 0,212, 5,
+ 4, 0,213, 5, 4, 0,214, 5, 2, 0,215, 5, 2, 0,216, 5, 2, 0,217, 5, 2, 0,218, 5, 0, 0,219, 5, 12, 0,220, 5,
+ 2, 0,221, 5, 2, 0,222, 5, 2, 0,223, 5, 2, 0,224, 5,193, 0,225, 5, 2, 0,226, 5, 2, 0,227, 5, 2, 0,228, 5,
+ 2, 0,229, 5, 4, 0,230, 5, 4, 0,231, 5, 4, 0,232, 5, 4, 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,239, 5, 2, 0,240, 5, 2, 0,241, 5, 0, 0,242, 5, 0, 0,243, 5, 7, 0,244, 5,
+ 2, 0,245, 5, 2, 0,246, 5, 48, 0,247, 5,195, 0, 18, 0, 27, 0, 31, 0, 12, 0,248, 5, 12, 0,249, 5, 12, 0,250, 5,
+160, 0,251, 5, 2, 0,111, 2, 2, 0,252, 5, 2, 0,112, 2, 2, 0,253, 5, 2, 0,254, 5, 2, 0,255, 5, 2, 0, 0, 6,
+ 2, 0, 1, 6, 2, 0, 2, 6, 2, 0, 16, 0, 2, 0, 3, 6, 2, 0, 4, 6, 2, 0, 5, 6,196, 0, 5, 0,196, 0, 0, 0,
+196, 0, 1, 0,196, 0, 6, 6, 13, 0, 7, 6, 4, 0, 20, 0,197, 0, 7, 0,197, 0, 0, 0,197, 0, 1, 0,196, 0, 8, 6,
+196, 0, 9, 6, 2, 0, 10, 4, 2, 0, 20, 0, 4, 0, 16, 0,198, 0, 17, 0,198, 0, 0, 0,198, 0, 1, 0, 0, 0, 10, 6,
+ 0, 0, 11, 6, 0, 0, 12, 6, 2, 0, 13, 6, 2, 0, 14, 6, 2, 0,254, 5, 2, 0,255, 5, 2, 0, 20, 0, 2, 0, 9, 3,
+ 2, 0, 15, 6, 2, 0, 16, 6, 2, 0, 17, 6, 2, 0, 18, 6, 4, 0, 19, 6,198, 0, 20, 6,165, 0, 30, 0,165, 0, 0, 0,
+165, 0, 1, 0,196, 0, 8, 6,196, 0, 9, 6,196, 0, 21, 6,196, 0, 22, 6,195, 0, 23, 6, 7, 0, 24, 6, 23, 0,240, 1,
+ 23, 0, 25, 6, 23, 0, 26, 6, 2, 0, 27, 6, 2, 0, 28, 6, 2, 0, 29, 6, 0, 0,179, 4, 0, 0, 30, 6, 2, 0, 31, 6,
+ 2, 0, 32, 6, 0, 0, 33, 6, 0, 0, 34, 6, 0, 0, 35, 6, 0, 0, 36, 6, 2, 0, 37, 6, 2, 0, 38, 6, 2, 0, 39, 6,
+ 2, 0, 20, 0, 34, 0,102, 0, 12, 0, 40, 6, 12, 0, 41, 6, 12, 0, 42, 6,199, 0, 11, 0, 0, 0, 43, 6, 2, 0, 44, 6,
+ 2, 0, 45, 6, 2, 0, 46, 6, 2, 0, 47, 6, 2, 0, 48, 6, 2, 0,252, 3, 9, 0, 49, 6, 9, 0, 50, 6, 4, 0, 51, 6,
+ 4, 0, 52, 6,200, 0, 1, 0, 0, 0, 53, 6,201, 0, 8, 0, 50, 0, 54, 6, 50, 0, 55, 6,201, 0, 56, 6,201, 0, 57, 6,
+201, 0, 58, 6, 2, 0,110, 0, 2, 0, 20, 0, 4, 0, 59, 6,202, 0, 4, 0, 4, 0, 69, 5, 4, 0, 60, 6, 4, 0, 73, 5,
+ 4, 0, 61, 6,203, 0, 2, 0, 4, 0, 62, 6, 4, 0, 63, 6,204, 0, 7, 0, 7, 0, 64, 6, 7, 0, 65, 6, 7, 0, 66, 6,
+ 4, 0, 20, 0, 4, 0, 16, 0, 7, 0,129, 3, 7, 0, 67, 6,205, 0, 1, 0, 0, 0, 19, 5,206, 0, 19, 0,206, 0, 0, 0,
+206, 0, 1, 0, 4, 0,163, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0, 68, 6, 4, 0, 69, 6, 4, 0, 70, 6,200, 0, 71, 6,
+ 0, 0, 19, 5, 4, 0, 72, 6, 4, 0, 73, 6,205, 0,189, 2,202, 0, 74, 6,203, 0, 75, 6,204, 0, 76, 6,201, 0, 77, 6,
+201, 0, 78, 6,201, 0, 79, 6,207, 0, 12, 0, 0, 0,144, 1, 9, 0,170, 0, 0, 0,171, 0, 4, 0,174, 0, 4, 0,182, 0,
+ 9, 0,175, 0, 7, 0,177, 0, 7, 0,178, 0, 9, 0, 80, 6, 9, 0, 81, 6, 9, 0,179, 0, 9, 0,181, 0,208, 0, 45, 0,
+208, 0, 0, 0,208, 0, 1, 0, 9, 0, 82, 6, 9, 0, 26, 0, 0, 0, 27, 0, 4, 0, 20, 0, 4, 0, 18, 0, 4, 0, 23, 0,
+ 4, 0, 74, 2, 4, 0, 83, 6, 4, 0, 84, 6, 4, 0, 69, 6, 4, 0, 70, 6, 4, 0, 85, 6, 4, 0,193, 0, 4, 0, 86, 6,
+ 4, 0, 87, 6, 7, 0, 88, 6, 7, 0, 89, 6, 4, 0,107, 0, 4, 0, 90, 6,206, 0, 91, 6, 31, 0, 63, 0,160, 0,251, 5,
+ 42, 0,116, 0, 7, 0, 92, 6, 7, 0, 93, 6,207, 0,233, 0,208, 0, 94, 6,208, 0, 95, 6,208, 0, 96, 6, 12, 0, 97, 6,
+209, 0, 98, 6,210, 0, 99, 6, 7, 0,100, 6, 7, 0,101, 6, 4, 0,102, 6, 7, 0,103, 6, 9, 0,104, 6, 4, 0,105, 6,
+ 4, 0,106, 6, 4, 0,107, 6, 7, 0,108, 6, 4, 0, 0, 6, 4, 0, 16, 0,211, 0, 4, 0,211, 0, 0, 0,211, 0, 1, 0,
+ 12, 0,109, 6,208, 0,110, 6,212, 0, 6, 0, 12, 0,111, 6, 12, 0, 97, 6, 12, 0,112, 6, 2, 0, 20, 0, 2, 0, 16, 0,
+ 4, 0,163, 0,213, 0, 4, 0, 7, 0,113, 6, 7, 0, 89, 0, 2, 0,114, 6, 2, 0,115, 6,214, 0, 6, 0, 7, 0,116, 6,
+ 7, 0,117, 6, 7, 0,118, 6, 7, 0,119, 6, 4, 0,120, 6, 4, 0,121, 6,215, 0, 12, 0, 7, 0,122, 6, 7, 0,123, 6,
+ 7, 0,124, 6, 7, 0,125, 6, 7, 0,126, 6, 7, 0,127, 6, 7, 0,128, 6, 7, 0,129, 6, 7, 0,130, 6, 7, 0,131, 6,
+ 4, 0,106, 2, 4, 0,132, 6,216, 0, 2, 0, 7, 0, 68, 4, 7, 0, 16, 0,217, 0, 5, 0, 7, 0,133, 6, 7, 0,134, 6,
+ 4, 0, 75, 0, 4, 0, 75, 2, 4, 0,135, 6,218, 0, 6, 0,218, 0, 0, 0,218, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0,
+ 2, 0,136, 6, 2, 0,163, 0,219, 0, 8, 0,219, 0, 0, 0,219, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,136, 6,
+ 2, 0,163, 0, 7, 0, 23, 0, 7, 0,107, 0,220, 0, 45, 0,220, 0, 0, 0,220, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0,
+ 2, 0,136, 6, 2, 0,189, 0, 2, 0, 55, 3, 2, 0,137, 6, 7, 0,138, 6, 7, 0,139, 6, 7, 0,118, 2, 4, 0,140, 6,
+ 4, 0, 65, 0, 4, 0, 77, 2, 7, 0,141, 6, 7, 0,142, 6, 7, 0,143, 6, 7, 0,144, 6, 7, 0,145, 6, 7, 0,146, 6,
+ 7, 0,116, 2, 7, 0,231, 0, 7, 0,147, 6, 7, 0,148, 6, 7, 0, 16, 0, 7, 0,149, 6, 7, 0,150, 6, 7, 0,151, 6,
+ 2, 0,152, 6, 2, 0,153, 6, 2, 0,154, 6, 2, 0,155, 6, 2, 0,156, 6, 2, 0,157, 6, 2, 0,158, 6, 2, 0,159, 6,
+ 2, 0,226, 4, 2, 0,160, 6, 2, 0,165, 1, 2, 0,161, 6, 0, 0,162, 6, 0, 0,163, 6, 7, 0,187, 0,221, 0,164, 6,
+ 57, 0,118, 1,222, 0, 16, 0,222, 0, 0, 0,222, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,136, 6, 2, 0,189, 0,
+ 7, 0,111, 2, 7, 0,112, 2, 7, 0,113, 2, 7, 0,208, 1, 7, 0,114, 2, 7, 0,115, 2, 7, 0,165, 6, 7, 0,116, 2,
+ 7, 0,117, 2, 7, 0,118, 2,179, 0, 5, 0, 2, 0, 18, 0, 2, 0, 59, 6, 2, 0, 20, 0, 2, 0,166, 6, 27, 0, 85, 5,
+178, 0, 3, 0, 4, 0, 53, 0, 4, 0,167, 6,179, 0, 2, 0,223, 0, 12, 0,223, 0, 0, 0,223, 0, 1, 0, 2, 0, 18, 0,
+ 2, 0, 20, 0, 2, 0,229, 2, 2, 0,180, 1, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0,168, 6, 7, 0,169, 6, 27, 0, 85, 5,
+ 12, 0,170, 6,224, 0, 11, 0,224, 0, 0, 0,224, 0, 1, 0, 0, 0, 17, 0, 2, 0, 18, 0, 2, 0,171, 6, 4, 0, 22, 0,
+ 4, 0,172, 6, 2, 0, 20, 0, 2, 0, 16, 0, 9, 0,173, 6, 9, 0,174, 6,225, 0, 5, 0, 0, 0, 17, 0, 7, 0,245, 0,
+ 7, 0,175, 6, 4, 0,176, 6, 4, 0, 16, 0,226, 0, 4, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 42, 0, 2, 0, 54, 0,
+227, 0, 4, 0, 0, 0, 17, 0, 55, 0,177, 6, 7, 0,245, 0, 7, 0, 16, 0,228, 0, 6, 0, 2, 0,178, 6, 2, 0,179, 6,
+ 2, 0, 18, 0, 2, 0,180, 6, 0, 0,181, 6, 0, 0,182, 6,229, 0, 5, 0, 4, 0, 18, 0, 4, 0, 16, 0, 0, 0, 17, 0,
+ 0, 0,183, 6, 0, 0,184, 6,230, 0, 6, 0, 0, 0, 17, 0, 0, 0,185, 6, 2, 0,186, 6, 2, 0,116, 2, 2, 0,242, 0,
+ 2, 0, 54, 0,231, 0, 5, 0, 0, 0, 17, 0, 7, 0, 89, 0, 7, 0,131, 3, 2, 0, 20, 0, 2, 0, 88, 2,232, 0, 3, 0,
+ 0, 0, 17, 0, 4, 0, 77, 2, 4, 0,187, 6,233, 0, 7, 0, 0, 0, 17, 0, 7, 0,131, 3, 0, 0,188, 6, 0, 0,189, 6,
+ 2, 0,242, 0, 2, 0, 42, 0, 4, 0,190, 6,234, 0, 3, 0, 39, 0,191, 6, 0, 0,192, 6, 0, 0,193, 6,235, 0, 17, 0,
+235, 0, 0, 0,235, 0, 1, 0, 2, 0, 18, 0, 2, 0,171, 6, 2, 0, 20, 0, 2, 0,194, 6, 2, 0,195, 6, 2, 0,196, 6,
+ 2, 0, 42, 0, 2, 0, 54, 0, 0, 0, 17, 0, 9, 0, 2, 0,236, 0,197, 6, 39, 0,241, 0, 2, 0, 74, 4, 2, 0,198, 6,
+ 4, 0, 16, 0,237, 0, 10, 0, 0, 0, 17, 0, 2, 0, 18, 0, 2, 0, 16, 0, 4, 0, 88, 2, 4, 0,199, 6, 4, 0,200, 6,
+ 4, 0,201, 6, 4, 0,202, 6, 4, 0,203, 6, 4, 0,204, 6,238, 0, 1, 0, 0, 0,205, 6,239, 0, 1, 0, 36, 0, 68, 5,
+236, 0, 18, 0,236, 0, 0, 0,236, 0, 1, 0,236, 0,206, 6, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,207, 6, 2, 0,196, 6,
+ 2, 0,171, 6, 2, 0,208, 6, 2, 0, 54, 0, 2, 0,253, 0, 0, 0, 17, 0, 9, 0, 2, 0,240, 0,197, 6,235, 0,209, 6,
+ 2, 0, 15, 0, 2, 0,210, 6, 4, 0, 76, 3,241, 0, 3, 0, 4, 0,140, 2, 4, 0, 16, 0, 39, 0,241, 0,242, 0, 10, 0,
+130, 0,211, 6, 2, 0, 18, 0, 2, 0, 20, 0, 4, 0,138, 6, 4, 0,139, 6, 0, 0, 17, 0, 4, 0,212, 6, 2, 0,213, 6,
+ 2, 0,214, 6, 7, 0,215, 6,243, 0, 10, 0, 2, 0, 20, 0, 2, 0,216, 6, 4, 0,138, 6, 4, 0,139, 6, 2, 0,217, 6,
+209, 0, 98, 6, 2, 0, 18, 0, 2, 0,218, 6, 2, 0,219, 6, 2, 0,220, 6,244, 0, 7, 0, 2, 0, 20, 0, 2, 0,216, 6,
+ 4, 0,138, 6, 4, 0,139, 6, 2, 0, 18, 0, 2, 0,221, 6, 7, 0,222, 6,245, 0, 9, 0, 4, 0,140, 2, 2, 0, 18, 0,
+ 2, 0, 20, 0, 39, 0,241, 0, 72, 0,223, 6, 0, 0, 17, 0, 7, 0,224, 6, 2, 0,225, 6, 2, 0, 16, 0,246, 0, 5, 0,
+ 2, 0, 18, 0, 2, 0, 20, 0, 4, 0, 16, 0,160, 0,251, 5, 39, 0,145, 4,247, 0, 5, 0, 4, 0, 20, 0, 4, 0, 18, 0,
+ 0, 0, 17, 0, 0, 0,183, 6, 39, 0,241, 0,248, 0, 10, 0, 4, 0, 20, 0, 4, 0, 18, 0, 7, 0,226, 6, 7, 0,227, 6,
+ 7, 0,236, 0, 7, 0,237, 0, 7, 0,198, 2, 7, 0,201, 2, 7, 0,228, 6, 7, 0,229, 6,249, 0, 9, 0, 2, 0, 20, 0,
+ 2, 0, 18, 0, 4, 0,138, 6, 4, 0,139, 6, 0, 0, 17, 0, 2, 0, 42, 0, 2, 0, 45, 0, 2, 0,230, 6, 2, 0,231, 6,
+250, 0, 8, 0, 39, 0,241, 0, 7, 0,113, 2, 7, 0,232, 6, 7, 0,233, 6, 7, 0,108, 2, 2, 0, 20, 0, 2, 0, 88, 2,
+ 7, 0,234, 6,251, 0, 7, 0, 2, 0, 20, 0, 2, 0,116, 2, 7, 0,235, 6, 7, 0,236, 6, 7, 0,237, 6, 7, 0,238, 6,
+ 7, 0,239, 6,252, 0, 10, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0,138, 6, 4, 0,139, 6, 0, 0, 17, 0, 2, 0,157, 0,
+ 2, 0, 45, 0, 2, 0,230, 6, 2, 0,231, 6, 57, 0,118, 1,253, 0, 7, 0, 4, 0, 77, 2, 4, 0,240, 6, 4, 0,241, 6,
+ 4, 0,242, 6, 7, 0,243, 6, 7, 0,244, 6, 0, 0,188, 6,254, 0, 7, 0, 0, 0,245, 6, 39, 0,246, 6, 0, 0,192, 6,
+ 2, 0,247, 6, 2, 0, 42, 0, 4, 0, 54, 0, 0, 0,193, 6,255, 0, 6, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0,138, 6,
+ 4, 0,139, 6, 0, 0,248, 6, 0, 0,249, 6, 0, 1, 1, 0, 4, 0, 20, 0, 1, 1, 6, 0, 0, 0,153, 5, 2, 0, 18, 0,
+ 2, 0, 20, 0, 4, 0,250, 6, 7, 0,251, 6, 36, 0, 68, 5,240, 0, 10, 0,240, 0, 0, 0,240, 0, 1, 0,240, 0,206, 6,
+ 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,171, 6, 2, 0,252, 6, 0, 0, 17, 0, 9, 0, 2, 0, 39, 0,241, 0, 2, 1, 10, 0,
+ 7, 0,223, 2, 7, 0,253, 6, 7, 0,254, 6, 7, 0,255, 6, 7, 0, 0, 7, 4, 0, 20, 0, 7, 0, 1, 7, 7, 0, 2, 7,
+ 7, 0, 3, 7, 7, 0, 16, 0,209, 0, 20, 0, 27, 0, 31, 0, 0, 0,169, 0, 3, 1, 4, 7, 9, 0, 5, 7, 37, 0,128, 0,
+ 37, 0, 6, 7, 9, 0, 7, 7, 31, 0, 63, 0, 7, 0,222, 6, 7, 0, 8, 7, 7, 0, 9, 7, 7, 0, 10, 7, 7, 0, 11, 7,
+ 7, 0, 12, 7, 7, 0, 13, 7, 4, 0, 75, 0, 4, 0, 14, 7, 0, 0, 15, 7, 0, 0, 16, 7, 0, 0, 17, 7, 4, 1, 6, 0,
+ 27, 0, 31, 0, 7, 0, 18, 7, 7, 0, 19, 7, 7, 0, 20, 7, 2, 0, 21, 7, 2, 0, 22, 7, 5, 1, 14, 0,164, 0, 0, 0,
+164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,165, 0,181, 4,169, 0,244, 4,209, 0, 98, 6, 2, 0,242, 0, 2, 0,216, 6,
+ 2, 0,221, 1, 2, 0,222, 1, 2, 0, 20, 0, 2, 0,254, 4, 4, 0, 54, 0, 6, 1, 6, 0, 6, 1, 0, 0, 6, 1, 1, 0,
+ 39, 0,241, 0, 9, 0, 23, 7, 4, 0,194, 0, 4, 0, 16, 0, 57, 0, 4, 0, 27, 0, 31, 0, 12, 0, 24, 7, 4, 0,112, 0,
+ 4, 0, 16, 0, 7, 1, 25, 0, 7, 1, 0, 0, 7, 1, 1, 0, 7, 1, 37, 0, 12, 0, 25, 7, 0, 0, 17, 0, 7, 0, 26, 7,
+ 7, 0, 27, 7, 7, 0, 28, 7, 7, 0, 29, 7, 4, 0, 20, 0, 7, 0, 30, 7, 7, 0, 31, 7, 7, 0, 32, 7, 7, 0,245, 0,
+ 7, 0,173, 1, 7, 0, 33, 7, 7, 0, 75, 2, 7, 0, 34, 7, 7, 0, 35, 7, 7, 0, 36, 7, 7, 0, 37, 7, 7, 0, 38, 7,
+ 7, 0,151, 0, 2, 0,112, 0, 2, 0, 90, 4, 8, 1, 19, 0, 27, 0, 31, 0, 12, 0, 39, 7, 12, 0, 40, 7, 4, 0, 20, 0,
+ 4, 0,173, 3, 2, 0,119, 2, 2, 0, 41, 7, 2, 0,112, 0, 2, 0, 42, 7, 2, 0, 43, 7, 2, 0, 44, 7, 2, 0, 45, 7,
+ 2, 0, 46, 7, 4, 0, 47, 7, 4, 0, 48, 7, 4, 0, 49, 7, 4, 0, 50, 7, 4, 0, 51, 7, 4, 0, 52, 7, 9, 1, 34, 0,
+ 9, 1, 0, 0, 9, 1, 1, 0, 12, 0,247, 2, 0, 0, 17, 0, 2, 0, 20, 0, 2, 0, 53, 7, 2, 0, 54, 7, 2, 0, 55, 7,
+ 2, 0,212, 2, 2, 0, 56, 7, 4, 0,206, 1, 4, 0, 49, 7, 4, 0, 50, 7, 7, 1, 57, 7, 9, 1, 37, 0, 9, 1, 58, 7,
+ 12, 0, 59, 7, 9, 0, 60, 7, 9, 0, 61, 7, 9, 0, 62, 7, 7, 0,236, 0, 7, 0,151, 0, 7, 0,155, 1, 7, 0, 63, 7,
+ 7, 0, 64, 7, 7, 0,204, 2, 7, 0, 65, 7, 7, 0, 66, 7, 7, 0, 67, 7, 7, 0, 68, 7, 7, 0, 69, 7, 7, 0, 70, 7,
+ 7, 0,203, 1, 39, 0, 71, 7,131, 0, 9, 0, 12, 0, 72, 7, 2, 0, 20, 0, 2, 0, 73, 7, 7, 0,222, 2, 7, 0, 74, 7,
+ 7, 0, 75, 7, 12, 0, 76, 7, 4, 0, 77, 7, 4, 0, 16, 0, 10, 1, 6, 0, 10, 1, 0, 0, 10, 1, 1, 0, 4, 0, 20, 0,
+ 4, 0, 78, 7, 0, 0, 17, 0, 12, 0, 15, 7, 11, 1, 8, 0, 11, 1, 0, 0, 11, 1, 1, 0, 10, 1, 79, 7, 31, 0, 63, 0,
+ 12, 0,195, 2, 4, 0, 20, 0, 0, 0, 17, 0, 4, 0, 80, 7,130, 0, 6, 0, 27, 0, 31, 0, 12, 0, 72, 7, 12, 0, 81, 7,
+ 12, 0,166, 4, 4, 0, 82, 7, 4, 0, 16, 0, 12, 1, 15, 0,164, 0, 0, 0,164, 0, 1, 0, 4, 0,179, 4, 7, 0,180, 4,
+165, 0,181, 4, 2, 0,182, 4,169, 0,244, 4,130, 0,192, 2, 2, 0, 20, 0, 2, 0, 67, 5, 2, 0,251, 4, 2, 0, 83, 7,
+ 2, 0,254, 4, 2, 0, 84, 7, 7, 0, 85, 7, 13, 1, 5, 0, 13, 1, 0, 0, 13, 1, 1, 0, 31, 0, 63, 0, 2, 0, 20, 0,
+ 0, 0, 86, 7, 14, 1, 12, 0, 14, 1, 0, 0, 14, 1, 1, 0, 9, 0, 2, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, 0, 87, 7,
+ 0, 0, 88, 7, 0, 0, 86, 7, 7, 0, 89, 7, 7, 0, 90, 7, 4, 0, 16, 0, 31, 0, 63, 0, 15, 1, 9, 0, 15, 1, 0, 0,
+ 15, 1, 1, 0, 39, 0, 91, 7, 0, 0, 92, 7, 7, 0, 93, 7, 2, 0, 94, 7, 2, 0, 20, 0, 2, 0, 18, 0, 2, 0, 16, 0,
+ 16, 1, 7, 0, 36, 0, 68, 5, 26, 0, 95, 7, 4, 0, 20, 0, 4, 0, 96, 7, 12, 0, 97, 7, 39, 0, 91, 7, 0, 0, 92, 7,
+ 17, 1, 12, 0, 39, 0, 91, 7, 2, 0, 98, 7, 2, 0, 20, 0, 2, 0, 99, 7, 2, 0,100, 7, 0, 0, 92, 7, 39, 0,101, 7,
+ 0, 0,102, 7, 7, 0,103, 7, 7, 0,173, 1, 7, 0,104, 7, 7, 0,105, 7, 18, 1, 6, 0, 39, 0, 91, 7, 4, 0, 80, 7,
+ 4, 0,106, 7, 4, 0, 75, 0, 4, 0, 16, 0, 0, 0, 92, 7, 19, 1, 4, 0, 39, 0, 91, 7, 4, 0, 20, 0, 4, 0, 80, 7,
+ 0, 0, 92, 7, 20, 1, 4, 0, 39, 0, 91, 7, 4, 0, 20, 0, 4, 0, 80, 7, 0, 0, 92, 7, 21, 1, 10, 0, 39, 0, 91, 7,
+ 4, 0,107, 7, 7, 0,106, 0, 4, 0, 20, 0, 2, 0, 61, 5, 2, 0,108, 7, 2, 0, 42, 0, 2, 0, 54, 0, 7, 0,109, 7,
+ 0, 0, 92, 7, 22, 1, 4, 0, 39, 0, 91, 7, 4, 0, 20, 0, 4, 0, 80, 7, 0, 0, 92, 7, 23, 1, 10, 0, 39, 0, 91, 7,
+ 2, 0, 18, 0, 2, 0, 61, 3, 4, 0, 74, 2, 4, 0,139, 6, 7, 0,232, 6, 7, 0,233, 6, 4, 0, 16, 0,130, 0,211, 6,
+ 0, 0, 92, 7, 24, 1, 4, 0, 39, 0, 91, 7, 4, 0,209, 2, 4, 0,110, 7, 0, 0, 92, 7, 25, 1, 5, 0, 39, 0, 91, 7,
+ 7, 0,106, 0, 4, 0,111, 7, 4, 0,209, 2, 4, 0,210, 2, 26, 1, 6, 0, 39, 0, 91, 7, 4, 0,112, 7, 4, 0,113, 7,
+ 7, 0,114, 7, 7, 0,115, 7, 0, 0, 92, 7, 27, 1, 16, 0, 39, 0, 91, 7, 39, 0, 58, 7, 4, 0, 18, 0, 7, 0,116, 7,
+ 7, 0,117, 7, 7, 0,118, 7, 7, 0,119, 7, 7, 0,120, 7, 7, 0,121, 7, 7, 0,122, 7, 7, 0,123, 7, 7, 0,124, 7,
+ 2, 0, 20, 0, 2, 0, 16, 0, 2, 0, 42, 0, 2, 0, 54, 0, 28, 1, 3, 0, 39, 0, 91, 7, 4, 0, 20, 0, 4, 0,226, 4,
+ 29, 1, 5, 0, 39, 0, 91, 7, 4, 0, 20, 0, 4, 0, 16, 0, 7, 0,125, 7, 0, 0, 92, 7, 30, 1, 10, 0, 39, 0, 91, 7,
+ 0, 0, 92, 7, 2, 0,126, 7, 2, 0,127, 7, 0, 0,128, 7, 0, 0,129, 7, 7, 0,130, 7, 7, 0,131, 7, 7, 0,132, 7,
+ 7, 0,133, 7, 31, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,134, 7, 7, 0,135, 7,
+ 2, 0, 20, 0, 2, 0,226, 4, 32, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0,134, 7,
+ 7, 0,135, 7, 2, 0, 20, 0, 2, 0,226, 4, 33, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0,
+ 7, 0,134, 7, 7, 0,135, 7, 2, 0, 20, 0, 2, 0,226, 4, 34, 1, 7, 0, 39, 0, 91, 7, 0, 0, 92, 7, 7, 0,245, 0,
+ 7, 0, 0, 1, 2, 0, 20, 0, 2, 0,242, 0, 4, 0, 16, 0, 35, 1, 10, 0, 35, 1, 0, 0, 35, 1, 1, 0, 2, 0, 18, 0,
+ 2, 0, 20, 0, 0, 0,136, 7, 7, 0,196, 0, 7, 0,197, 0, 2, 0, 15, 7, 2, 0,137, 7, 39, 0,241, 0, 36, 1, 22, 0,
+ 36, 1, 0, 0, 36, 1, 1, 0, 2, 0, 20, 0, 2, 0,242, 0, 2, 0,138, 7, 2, 0,139, 7, 31, 0, 63, 0,130, 0,211, 6,
+ 39, 0,143, 0, 7, 0, 74, 2, 7, 0,139, 6, 7, 0,140, 7, 7, 0,141, 7, 7, 0,142, 7, 7, 0,143, 7, 7, 0,109, 2,
+ 7, 0,145, 1, 7, 0,212, 6, 7, 0,144, 7, 0, 0,145, 7, 0, 0,146, 7, 12, 0,197, 2, 37, 1, 8, 0, 7, 0,181, 1,
+ 7, 0,232, 6, 7, 0,233, 6, 9, 0, 2, 0, 2, 0,147, 7, 2, 0,148, 7, 2, 0,149, 7, 2, 0,150, 7, 38, 1, 17, 0,
+ 38, 1, 0, 0, 38, 1, 1, 0, 0, 0, 17, 0, 37, 1,151, 7, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0,152, 7, 2, 0,153, 7,
+ 2, 0,154, 7, 2, 0,155, 7, 4, 0, 42, 0, 7, 0,156, 7, 7, 0,157, 7, 4, 0,158, 7, 4, 0,159, 7, 38, 1,160, 7,
+ 39, 1,161, 7, 40, 1, 30, 0, 40, 1, 0, 0, 40, 1, 1, 0, 40, 1,162, 7, 0, 0, 17, 0, 0, 0,163, 7, 2, 0, 18, 0,
+ 2, 0, 20, 0, 2, 0, 68, 6, 2, 0,100, 6, 2, 0,164, 7, 2, 0,114, 0, 2, 0,153, 7, 2, 0, 59, 6, 12, 0,207, 6,
+ 12, 0,165, 7, 27, 0, 85, 5, 9, 0,166, 7, 7, 0,156, 7, 7, 0,157, 7, 7, 0,208, 1, 7, 0,167, 7, 2, 0,168, 7,
+ 2, 0,169, 7, 2, 0,170, 7, 2, 0,171, 7, 24, 0,172, 7, 24, 0,173, 7, 24, 0,174, 7, 41, 1,129, 0, 42, 1,175, 7,
+ 39, 1, 6, 0, 39, 1, 0, 0, 39, 1, 1, 0, 40, 1,176, 7, 40, 1,177, 7, 38, 1,178, 7, 38, 1,160, 7, 56, 0, 15, 0,
+ 27, 0, 31, 0, 12, 0,179, 7, 12, 0,180, 7, 37, 1,181, 7, 4, 0, 18, 0, 4, 0,182, 7, 4, 0,183, 7, 4, 0,184, 7,
+ 12, 0,185, 7, 42, 1,186, 7, 38, 1,187, 7, 38, 1,188, 7, 9, 0,189, 7, 9, 0,190, 7, 4, 0,191, 7, 43, 1, 6, 0,
+ 4, 0,105, 0, 4, 0,107, 0, 4, 0, 59, 6, 0, 0,192, 7, 0, 0,193, 7, 2, 0, 16, 0, 44, 1, 16, 0, 2, 0,254, 5,
+ 2, 0,255, 5, 2, 0,194, 7, 2, 0,254, 6, 2, 0,195, 7, 2, 0, 52, 0, 7, 0,108, 2, 7, 0,196, 7, 7, 0,197, 7,
+ 2, 0, 4, 1, 0, 0,198, 7, 0, 0,185, 3, 2, 0,199, 7, 2, 0, 16, 0, 4, 0,200, 7, 4, 0,201, 7, 45, 1, 9, 0,
+ 7, 0,202, 7, 7, 0,203, 7, 7, 0, 13, 7, 7, 0, 89, 0, 7, 0,204, 7, 7, 0,175, 4, 2, 0,205, 7, 0, 0,206, 7,
+ 0, 0, 16, 0, 46, 1, 4, 0, 7, 0,207, 7, 7, 0,208, 7, 2, 0,205, 7, 2, 0, 16, 0, 47, 1, 3, 0, 7, 0,209, 7,
+ 7, 0,210, 7, 7, 0, 15, 0, 48, 1, 7, 0, 0, 0,144, 1, 2, 0,254, 3, 2, 0,255, 3, 2, 0, 0, 4, 2, 0,205, 3,
+ 4, 0,107, 0, 4, 0, 59, 3, 49, 1, 7, 0, 7, 0,211, 7, 7, 0,212, 7, 7, 0,213, 7, 7, 0,217, 1, 7, 0,214, 7,
+ 7, 0,215, 7, 7, 0,216, 7, 50, 1, 4, 0, 2, 0,217, 7, 2, 0,218, 7, 2, 0,219, 7, 2, 0,220, 7, 51, 1, 2, 0,
+ 7, 0, 5, 0, 7, 0, 6, 0, 52, 1, 2, 0, 0, 0,145, 0, 0, 0,221, 7, 53, 1, 1, 0, 0, 0, 17, 0, 54, 1, 10, 0,
+ 0, 0,222, 7, 0, 0,223, 7, 0, 0,224, 7, 0, 0,225, 7, 2, 0,194, 7, 2, 0,226, 7, 7, 0,227, 7, 7, 0,228, 7,
+ 7, 0,229, 7, 7, 0,145, 1, 55, 1, 2, 0, 9, 0,230, 7, 9, 0,231, 7, 56, 1, 11, 0, 0, 0, 0, 4, 0, 0, 18, 0,
+ 0, 0,205, 7, 0, 0, 89, 0, 0, 0,232, 7, 0, 0, 86, 0, 0, 0, 42, 2, 7, 0,233, 7, 7, 0,234, 7, 7, 0,235, 7,
+ 7, 0,236, 7, 57, 1, 8, 0, 7, 0,178, 6, 7, 0,106, 0, 7, 0,185, 3, 7, 0, 37, 2, 7, 0,237, 7, 7, 0,183, 0,
+ 7, 0,238, 7, 4, 0, 18, 0, 58, 1, 4, 0, 2, 0,239, 7, 2, 0,240, 7, 2, 0,241, 7, 2, 0, 16, 0, 59, 1, 4, 0,
+ 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 20, 0, 2, 0,242, 7, 60, 1, 10, 0, 2, 0, 41, 3, 2, 0, 20, 0, 7, 0,131, 3,
+ 7, 0,243, 7, 7, 0,244, 7, 7, 0,245, 7, 7, 0,246, 7, 59, 1,247, 7, 59, 1,248, 7, 59, 1,249, 7, 53, 0, 9, 0,
+ 4, 0, 20, 0, 4, 0, 45, 0, 24, 0,250, 7, 24, 0,251, 7, 60, 1,252, 7, 7, 0,253, 7, 7, 0,254, 7, 7, 0,255, 7,
+ 7, 0, 0, 8, 61, 1, 4, 0, 41, 0,102, 2, 7, 0, 1, 8, 7, 0, 46, 1, 7, 0, 16, 0,152, 0, 13, 0, 27, 0, 31, 0,
+ 2, 0, 20, 0, 2, 0,176, 4, 4, 0, 86, 0, 7, 0, 2, 8, 7, 0,214, 1, 7, 0, 3, 8, 7, 0, 4, 8, 7, 0, 46, 1,
+ 2, 0, 17, 1, 2, 0, 16, 0, 44, 0, 31, 1, 61, 1, 5, 8, 62, 1, 8, 0, 4, 0, 18, 0, 4, 0,106, 0, 4, 0, 20, 0,
+ 4, 0, 9, 3, 4, 0, 6, 8, 0, 0,153, 5, 0, 0, 17, 0, 9, 0, 2, 0, 82, 0, 5, 0, 62, 1, 7, 8, 4, 0, 8, 8,
+ 4, 0, 9, 8, 4, 0, 10, 8, 4, 0, 16, 0, 63, 1, 5, 0, 7, 0, 33, 2, 7, 0,140, 2, 7, 0,173, 1, 2, 0, 11, 8,
+ 2, 0, 16, 0, 64, 1, 5, 0, 7, 0, 33, 2, 7, 0, 12, 8, 7, 0, 13, 8, 7, 0, 14, 8, 7, 0,140, 2, 65, 1, 7, 0,
+ 4, 0, 15, 8, 4, 0, 16, 8, 4, 0, 17, 8, 7, 0, 18, 8, 7, 0, 19, 8, 7, 0, 20, 8, 7, 0, 21, 8, 66, 1, 25, 0,
+ 39, 0, 22, 8, 64, 1, 23, 8, 63, 1, 24, 8, 64, 1,164, 6, 7, 0, 25, 8, 7, 0, 26, 8, 7, 0, 27, 8, 7, 0, 28, 8,
+ 7, 0, 19, 8, 7, 0, 20, 8, 7, 0,140, 2, 7, 0,118, 2, 7, 0, 29, 8, 7, 0, 30, 8, 7, 0, 86, 0, 7, 0, 31, 8,
+ 4, 0, 15, 8, 4, 0, 32, 8, 4, 0, 16, 0, 4, 0, 65, 0, 4, 0, 33, 8, 2, 0, 20, 0, 2, 0, 34, 8, 2, 0, 35, 8,
+ 2, 0, 39, 3, 67, 1,111, 0, 27, 0, 31, 0, 4, 0, 20, 0, 2, 0, 18, 0, 2, 0,126, 7, 2, 0, 36, 8, 2, 0, 37, 8,
+ 2, 0, 38, 8, 2, 0, 39, 8, 2, 0, 40, 8, 2, 0, 41, 8, 2, 0, 42, 8, 2, 0, 43, 8, 2, 0, 44, 8, 2, 0, 45, 8,
+ 2, 0, 46, 8, 2, 0, 47, 8, 2, 0, 48, 8, 2, 0, 49, 8, 2, 0, 50, 8, 2, 0,165, 1, 2, 0,157, 6, 2, 0,132, 6,
+ 2, 0, 51, 8, 2, 0, 52, 8, 2, 0, 37, 3, 2, 0, 38, 3, 2, 0, 53, 8, 2, 0, 54, 8, 2, 0, 55, 8, 2, 0, 56, 8,
+ 2, 0, 57, 8, 2, 0, 58, 8, 7, 0, 59, 8, 7, 0, 60, 8, 7, 0, 61, 8, 2, 0, 62, 8, 2, 0, 63, 8, 7, 0, 64, 8,
+ 7, 0, 65, 8, 7, 0, 66, 8, 7, 0,138, 6, 7, 0,139, 6, 7, 0,118, 2, 7, 0,145, 6, 7, 0, 67, 8, 7, 0, 68, 8,
+ 7, 0, 69, 8, 7, 0, 70, 8, 7, 0,163, 0, 4, 0,140, 6, 4, 0,137, 6, 4, 0, 71, 8, 7, 0,141, 6, 7, 0,142, 6,
+ 7, 0,143, 6, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, 74, 8, 7, 0, 75, 8, 7, 0, 76, 8, 7, 0, 77, 8, 7, 0, 78, 8,
+ 7, 0, 79, 8, 7, 0,223, 2, 7, 0, 86, 0, 7, 0, 80, 8, 7, 0, 81, 8, 7, 0, 82, 8, 7, 0, 83, 8, 7, 0, 84, 8,
+ 7, 0, 85, 8, 7, 0, 75, 2, 7, 0, 86, 8, 7, 0, 87, 8, 4, 0, 88, 8, 4, 0, 89, 8, 7, 0, 90, 8, 7, 0, 91, 8,
+ 7, 0, 92, 8, 7, 0, 93, 8, 7, 0, 94, 8, 7, 0, 95, 8, 7, 0, 96, 8, 7, 0, 97, 8, 7, 0, 33, 3, 7, 0, 31, 3,
+ 7, 0, 32, 3, 7, 0, 98, 8, 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, 7, 0,107, 8, 7, 0,108, 8, 7, 0,109, 8, 7, 0,110, 8, 7, 0,111, 8, 7, 0,112, 8,
+ 7, 0,113, 8, 7, 0,114, 8, 0, 0,115, 8, 57, 0,253, 2, 57, 0,116, 8, 39, 0,117, 8, 39, 0,118, 8, 31, 0, 63, 0,
+132, 0,251, 2,124, 0, 34, 0,124, 0, 0, 0,124, 0, 1, 0, 67, 1,119, 8, 66, 1, 40, 3, 65, 1, 58, 7, 68, 1,120, 8,
+ 69, 1,121, 8, 69, 1,122, 8,133, 0,252, 2, 39, 0,123, 8, 39, 0,124, 8, 39, 0,125, 8, 12, 0,126, 8, 12, 0,127, 8,
+ 7, 0,187, 0, 7, 0,226, 3, 4, 0, 77, 2, 4, 0, 20, 0, 4, 0,140, 6, 4, 0,128, 8, 4, 0,129, 8, 4, 0,130, 8,
+ 4, 0,163, 0, 2, 0,194, 0, 2, 0,131, 8, 2, 0,132, 8, 2, 0,133, 8, 2, 0,245, 2, 2, 0,134, 8, 0, 0,135, 8,
+ 2, 0,136, 8, 2, 0,137, 8, 2, 0,138, 8, 9, 0,139, 8,115, 0, 39, 0, 2, 0,140, 8, 2, 0,141, 8, 7, 0, 52, 3,
+ 4, 0,142, 8, 7, 0,143, 8, 7, 0,144, 8, 4, 0,145, 8, 7, 0,134, 3, 7, 0,146, 8, 7, 0,147, 8, 7, 0,146, 8,
+ 7, 0,229, 2, 7, 0,223, 2, 7, 0,148, 8, 7, 0,216, 1, 7, 0,149, 8, 7, 0,150, 8, 4, 0, 75, 0, 2, 0,151, 8,
+ 2, 0,152, 8, 7, 0, 53, 3, 7, 0,153, 8, 7, 0,154, 8, 7, 0,155, 8, 70, 1,156, 8, 7, 0, 54, 3, 4, 0, 51, 3,
+ 7, 0, 50, 3, 4, 0,157, 8, 4, 0,119, 0, 4, 0,158, 8, 4, 0,159, 8, 4, 0,160, 8, 4, 0,161, 8, 7, 0,162, 8,
+ 7, 0,163, 8, 7, 0,164, 8, 4, 0,165, 8, 7, 0,166, 8,116, 0, 8, 0, 7, 0,167, 8, 7, 0,168, 8, 7, 0,119, 1,
+ 2, 0,169, 8, 2, 0,170, 8, 70, 1,171, 8, 4, 0, 75, 0, 7, 0,172, 8,114, 0, 13, 0, 71, 1, 51, 2, 70, 1,173, 8,
+ 4, 0,138, 2, 4, 0,174, 8, 4, 0,139, 2, 0, 0,175, 8, 0, 0, 54, 0, 2, 0,253, 0,118, 0,141, 2, 73, 0,137, 2,
+ 72, 1,176, 8, 72, 1,177, 8, 73, 1,178, 8, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index 2f7b4754d76..a8ecd0d770b 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -264,12 +264,15 @@ static Scene *preview_prepare_scene(RenderInfo *ri, int id_type, ID *id, int pr_
sce= pr_main->scene.first;
if(sce) {
-
- // sce->r.mode |= G.scene->r.mode & R_THREADS;
/* this flag tells render to not execute depsgraph or ipos etc */
sce->r.scemode |= R_PREVIEWBUTS;
/* set world always back, is used now */
sce->world= pr_main->world.first;
+ /* now: exposure copy */
+ if(G.scene->world) {
+ sce->world->exp= G.scene->world->exp;
+ sce->world->range= G.scene->world->range;
+ }
sce->r.cfra= G.scene->r.cfra;
@@ -458,7 +461,7 @@ void BIF_previewrender(struct ID *id, struct RenderInfo *ri, struct ScrArea *are
}
/* allocates render result */
- RE_InitState(re, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
+ RE_InitState(re, NULL, &sce->r, ri->pr_rectx, ri->pr_recty, NULL);
/* enforce preview image clear */
if(GS(id->name)==ID_MA) {
@@ -775,7 +778,7 @@ void BIF_view3d_previewrender(ScrArea *sa)
rdata.layers.first= rdata.layers.last= NULL;
rdata.renderer= R_INTERN;
- RE_InitState(re, &rdata, sa->winx, sa->winy, &ri->disprect);
+ RE_InitState(re, NULL, &rdata, sa->winx, sa->winy, &ri->disprect);
if(orth)
RE_SetOrtho(re, &viewplane, clipsta, clipend);
diff --git a/source/blender/src/prvicons.c b/source/blender/src/prvicons.c
new file mode 100644
index 00000000000..6222090705a
--- /dev/null
+++ b/source/blender/src/prvicons.c
@@ -0,0 +1,436 @@
+/* DataToC output of file <prvicons> */
+
+int datatoc_prvicons_size= 13732;
+char datatoc_prvicons[]= {
+137, 80, 78, 71,
+ 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,192, 0, 0, 0,192, 8, 6, 0, 0, 0, 82,220,108, 7, 0, 0, 0,
+ 6, 98, 75, 71, 68, 0, 0, 0, 0, 0, 0,249, 67,187,127, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1,
+ 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 8, 27, 17, 57, 33, 43,142, 73,203, 0, 0, 0, 29,116, 69, 88,116, 67,
+111,109,109,101,110,116, 0, 67,114,101, 97,116,101,100, 32,119,105,116,104, 32, 84,104,101, 32, 71, 73, 77, 80,239,100, 37,110,
+ 0, 0, 32, 0, 73, 68, 65, 84,120,218,237,125,121,124, 84,213,249,254,115,238,189, 51,147,201,158, 12, 73, 72,216, 3,200, 98,
+ 88, 69, 66, 38, 65, 16, 20,165, 40,213,162, 32, 45,138,203, 79,176,223, 42,180,110, 72,235,190, 97, 91, 91, 21,181,149,182, 90,
+ 20, 42, 10, 66, 80,164, 34, 59,146, 5,194, 30, 18, 8, 75, 2,201,144,144,201, 62, 73,102,189,247,158,243,251, 35,235, 36, 51,
+217,200,100, 38,229, 62,159,207,124,146,123,239,153, 59,207, 61,247,125,207,121,223,247,156,243, 30, 64,129, 2, 5, 10, 20, 40,
+ 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2,
+ 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,
+160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5,
+ 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160,
+ 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,208, 18, 36, 41, 41,105,
+180, 32, 8,143, 16, 66, 72,119,223,156, 49, 22, 46,203,242,112,198,216,203, 41, 41, 41,251, 60,241, 0,189,157,191, 2,239, 43,
+192, 61, 49, 49, 49, 27,230,204,153,227,215,157, 55,206,206,206,198,169, 83,167, 16, 25, 25, 9,131,193, 64, 37, 73,154,150,146,
+146,146,226, 1, 5,232,213,252, 21,120, 23, 2, 0, 68, 71, 71,219, 23, 46, 92,216,109, 2,180,105,211, 38, 24, 12, 6, 60,250,
+232,163,224, 56, 14, 7, 15, 30,228, 50, 51, 51, 15, 36, 38, 38, 38,164,166,166,102,116,247, 67,244,118,254, 10,188, 7,174,187,
+111, 40, 73, 18,214,175, 95,143, 5, 11, 22,160,111,223,190,240,247,247, 71, 98, 98, 34,226,226,226, 56,149, 74,149,174,215,235,
+ 39,250,114,133,244,118,254, 10,188,172, 0, 6,131, 1,193,193,193,136,136,136,128, 32, 8,208,106,181,208,106,181,208,235,245,
+ 24, 57,114, 36,167, 86,171, 51,244,122,125,156,175, 86, 72,111,231,175,192,203, 10, 80, 88, 88, 8,157, 78,215,120,172,209,104,
+ 26,133, 40, 49, 49, 17,195,135, 15,231,213,106,245,137,132,132,132, 27,124,177, 66,122, 59,127, 5, 94, 86,128,192,192, 64, 88,
+173, 86,167,115,254,254,254,141,159,164,164, 36,196,198,198, 10,126,126,126, 89,122,189, 62,214,215, 42,164,183,243, 87,224,101,
+ 5,208,233,116, 48,153, 76,173,206, 55,180,162, 90,173, 22, 73, 73, 73, 24, 56,112,160, 74,163,209,156,213,235,245, 3,124,169,
+ 66,122, 59,127, 5,157,131,208,221, 55,140,138,138, 66, 77, 77, 13,172, 86, 43,180, 90, 45, 0,160,170,170, 10,165,165,165, 40,
+ 47, 47, 71,105,105, 41, 44, 22, 11, 6, 15, 30, 12, 81, 20,213, 87,175, 94, 61,175,215,235,135,164,165,165, 21,251, 66,133,244,
+118,254, 10,188,172, 0,106,181, 26,227,199,143, 71, 78, 78, 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42,
+ 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40,138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,245,118,133,244,
+118,254, 10,188,172, 0, 0, 48,109,218, 52,124,250,233,167, 16, 69, 17,143, 63,254, 56,102,206,156, 9,181, 90,237, 84,102,209,
+162, 69, 48,153, 76, 88,183,110, 29,182,108,217,162,165,148,190, 9,224, 9, 0,204,219,149,210,219,249, 43,240,162, 15, 0, 0,
+ 9, 9, 9, 8, 12, 12,196, 71, 31,125,132,217,179,103,183, 18,158, 6,132,132,132,224,201, 39,159,132, 70,163, 97, 86,171,117,
+108,104,104,104,127, 0,196,219,149,210,219,249, 43,240,178, 2, 4, 5, 5, 97,205,154, 53,136,137,137,233, 80,249, 33, 67,134,
+ 72, 86,171,213,204,243,252,253,190, 32, 64,189,157,191, 2, 47, 43, 0, 0, 8, 66,199,173, 43, 63, 63, 63, 70, 41,149, 24, 99,
+ 26, 95, 17,160,222,206, 95,129,151, 21,160,139,144,123,121,125,202,138, 72, 41, 10,208, 37, 16, 66,100, 66, 72,175, 21,160,222,
+206,255,122,133,208, 19, 63, 98,178,216,193, 24,131, 74,224, 17,160, 81,185,109, 61, 25, 99, 50,122,111, 20,165,183,243, 87, 20,
+192, 19,200, 45,174,194,152,103, 62, 5, 0, 68,135, 5,226,252,234, 37,224,185,122, 51,153, 81, 56,142,252, 11,183, 71, 92,225,
+ 39,223, 22, 56, 50, 88,173,213,234, 99,111,136,134, 64,254, 25,249,155,244,139,158,230,166, 82,185, 85, 70,136,162,216,217, 30,
+128, 2,160,138, 15,160, 40,128, 19, 62, 63,112,186,241,255,171,149,181,248,241,100, 30,126, 54,113, 40, 0,128,154,174,192,126,
+124, 61,146,194,192, 35, 76, 51, 28,192,112, 0,183, 17,137,255,216,155,194,223,145,235, 45,148,132, 1,104, 48,129,148, 30, 64,
+241, 1,234,109, 2,202,240,159,159,178,157,206,125,113, 32,171,241,127, 90,118,190,213,119, 24, 80, 30,190, 60,165,192,155,194,
+223,197,251, 80,197, 9, 86, 20,192, 9, 59, 79, 93,194,213, 42, 51,180,234,166,142,230,135, 19,121, 40,173,182,212, 41, 72,217,
+ 5,184,208,128, 19,189,169, 2,155, 41, 1,173,247, 1, 20, 40, 10,224,220,218,191,255,240, 76, 52, 44, 89, 23,101,138, 13, 41,
+103,234, 36,166,212,101, 15,112,220,215, 43, 77, 20, 69,167, 15, 0, 13,165, 20, 0,244, 0,120, 69,172, 20, 5, 64,105,181, 5,
+255, 61,158,139, 65, 17, 33, 88,116, 75, 28,102,196, 13,106,230, 23,100,213,247, 0, 46, 20,128,178,227,189,173, 18, 25, 99, 0,
+ 16, 7,160, 76,241, 1, 20, 39, 24, 0,176, 33,229, 12, 68,153,226,161,105, 55,130, 16,224,161,105, 99,176,231,116, 62, 0,224,
+236,149,114,100,100,102, 97,148,189,166,213,247,204,140,157, 0,128,146,143,167, 7,242,212, 54, 7,192, 72, 70,137,131,227,113,
+ 90,148,232,145,168,223, 30, 54,250,168, 2,252, 4,160, 90, 17, 41,165, 7,104,108,229, 57, 66,240,224,180,186,229,179,115, 39,
+ 13, 67, 88, 64, 83,226,134,181,123, 91,155,250,162,204, 44,187,114,228, 75,229,171,227,159,225,101, 91, 49, 24,190, 2,195,171,
+132,176,183, 25,101,219, 4,142,228, 85,172, 78, 88,234,139, 21,233,112, 56,202, 25, 99,134,122,103, 88,193,245,172, 0, 71,115,
+139,113,246, 74, 57,102,142, 25,132,254,225, 65, 0, 0,141,138,199,130,196, 81,141,101, 54,159, 42,133, 85,118, 54,151,171,172,
+180,224, 23,113,170,117, 0,121, 23, 64,128,139, 91,251, 51,176, 79,202, 62, 72, 88,229,131,117, 25, 98,179,217,250,195,247,166,
+151, 40,232,105, 5, 88,187,191, 46,246,191,120,250, 24,167,243, 15, 79,111, 74,166, 80,227, 96,216, 86,230, 60,219, 82, 23,192,
+ 15, 35,192,130,246,238, 79, 8,123,166,236,189, 41,163,188, 85,105, 42,149,170, 85, 40,149, 16, 2, 74,169, 77, 81,128,235, 92,
+ 1, 44,118, 17,223,164,159,131, 46, 72,139,187,110, 26,234,116,109,236,160, 72,140, 27, 28,217,228, 39, 24, 7, 57,147, 33, 16,
+ 24, 96, 7,240, 79, 2,242, 75, 2,242, 75, 6, 28,112, 37,131,132,195,115,222,170,180,102,209,159, 70,225,231, 56, 14, 42,149,
+234, 40,234,162, 64,202,104,240,245,170, 0, 91,143, 92, 64,181,213,142, 7, 18, 71, 65, 45,180,142, 8, 62,220,172, 87, 72,175,
+ 14,199,101, 91,147,165, 67, 41,236,162,204,238,214, 45, 59,180, 36,124, 89,250,134,240,101,233, 27,116, 21,126,183, 1,200,105,
+221, 13,224,198,107, 17, 96, 15, 33,166,222, 7, 96, 0, 84,138,120, 93,135, 10,208, 16,251, 95, 60,205,117,238,168,249,250,145,
+240, 19,184,250,232, 9,193,134,226,129,141,215, 14, 92, 52,255, 43,250,119,135,247, 56,201,249,171,251, 37, 66, 88,178,139,216,
+139, 79,229,229,169,207,205, 43,212,127, 72,125,221,106, 20, 17,187,142, 20,224, 82,137, 9, 7,207, 26, 48, 49, 54, 10,113, 3,
+ 35, 92,150, 9, 11,240,195, 93,195,154,150, 24,126,109, 28, 8,153, 17, 88, 37, 88, 95,218,102,220,233, 70,188,170, 92,156,243,
+243,149, 74,164,148,130, 82, 10, 73,146, 56, 0, 13,221,139, 31,234,204, 57, 5, 62,140,110, 29, 7,248,226, 64, 22, 24, 3,146,
+ 70, 14, 64,102,126,137,219,114, 19,131, 42,241, 13,234, 82,142, 92,117,248, 97,127,101, 36, 2,107, 11, 47, 24,107, 36,171,171,
+242,140,161,159,139,211, 62,149,129,161,190, 7, 16,209, 52, 16,102, 82,196,235, 58, 82, 0,202, 24,214,255, 84,103,254,172,254,
+239, 81,172,254,239,209, 54, 74,107,157,142, 54, 24, 7,226, 94,114,165,202,221,130, 18, 2, 50,136,181, 30, 96,205,242, 86,165,
+ 53, 68,128,154,251, 18,140, 49,112, 28, 39,214,215,169,168,136,214,117,166, 0,187, 78, 93, 70, 97, 69, 45,166,142, 26,128,219,
+199, 14,118, 95, 80,118,192,126,116, 45, 14,155,194,177,187, 50, 10, 0,240, 99,121, 95,220,168,209, 88, 40,165,173,166, 19,151,
+175,142, 15,102, 96,183,182,234, 21, 0,175,231,234, 87,169, 84, 78, 74,192,113,156, 67, 49,123,174, 83, 5,104,112,126, 95,186,
+ 79,143,164,145,253,221,150,147,138, 78,192,106, 60,143,139,186, 64,236, 62, 86,167, 0, 14,198,225, 44, 63,108, 24, 33, 57,178,
+ 11,211,226, 9,198, 16,220,178,195,225,101,124,233, 11, 21,216,208, 27,168, 84, 42,155, 90,173,110,112,128, 21, 92, 79, 78,112,
+121,141, 21,219,143,231, 98, 72,100, 8, 18, 71,244,111,219, 84,170,159, 1, 58,204,191, 22, 55, 7, 87, 52,158, 63, 45,247, 31,
+ 76,235,167, 84, 54,160,236,195,201, 51, 24,195, 75, 46,140,162, 45, 97,191, 59,116,217,135,236,255, 82, 65, 16,120, 40, 19,225,
+174,207, 30,224,171,212,179,112, 72, 50, 22,221,114, 35,218,219,169,171,249, 26,128, 95, 70,229,227, 72,117, 56, 0, 32,207, 22,
+ 36,124,241,127,250, 79,110,139,170,120,141,112, 40,231, 25,110,167, 12,207,160,117, 40,209,194,113,228, 89, 95,170, 68,158,231,
+ 3,120,158,175, 97,140, 29,135, 50, 23,232,250,235, 1,214,238, 63, 13,142, 16, 44,186,165,253,125, 35,154,175, 2,251,121, 68,
+ 33,252, 57,169,241,120,111,109,255, 49, 60,193, 55, 28,195, 62, 6,252,158,180, 22,126, 10, 66, 30, 14,123, 50, 45,223,199,234,
+145, 17, 66,168, 39, 54,234, 83,224,163, 61, 64, 65, 89, 53,118,158,186,132,242, 26, 43,178, 13,101,232, 23, 30,136, 31, 79,230,
+ 1, 0,126, 54,113, 40, 98,194, 2, 91, 75,137,100, 3,173, 42, 64,165,164,198,119,165,117,243,128, 6,105, 45, 56,107,174, 51,
+241,183,148,246,199,232,128,186, 25,197,183,134,149, 96,160,159,197,201,125, 32,192,178,240,167,210, 55,249, 82, 5,138,162,216,
+ 16, 2,149, 91,154,112, 10,254,135, 21, 32,203, 80,134,101,159,237,110, 60, 46,172,168,109, 60, 30,214, 55,204,165, 2,208,242,
+ 92,128, 81, 20,219,253,240,252,197,113,173,174, 87, 75,170,198,243,159,141,202,104,174, 0, 57,132,224,255,133, 63,117, 40,181,
+ 59, 5,247, 90,215, 6, 55, 68,128, 24, 99,168,239, 1, 20, 5,184, 94, 20, 32,126, 88, 52,118,252, 97,190,203,107, 99, 7,185,
+ 30, 5,230,130,251, 65, 59,247, 3,140,112,200,216, 62,185,166,222,129,228,177,230,235, 31,109,135,207,228,173, 11, 12,208,156,
+126,112, 28, 25, 30,161,178, 15, 25, 27,100,178, 1,200, 97,132,238,235,243, 84,198, 94, 79,181,222,157, 77,141, 34, 73, 82,171,
+180,137,132, 16, 48,198,168, 44,203, 65,138, 72, 93, 39, 10,160, 11,210,226,150,209,157,219, 28,133,104, 67, 33,104, 39, 32, 4,
+192,173,131,155,206,127,191,245, 59, 57,220,116,225, 66,126,102,254,174, 63,236, 48,125,212,147,209,148,206, 78,140,115,151, 51,
+ 84,201, 12,119, 29, 59,193,221,132,222, 46, 64,138, 2,244,214, 30,192,100, 50, 9, 25, 25,222,219,255,217,100, 50,241,132, 16,
+ 42,203,178,220,197,239,247,106,254, 10,188,171, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99, 76,141,186,176, 30,
+234, 77, 17,214,204, 36, 97,132,144,198,255, 91, 94,115,119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212, 59,145,157, 53,
+127,122, 59,127, 5, 94, 68,243,184, 53,167,211,233,150, 3,232,139,166, 44,103, 50, 99, 76, 34,132,200,140, 49,153, 16, 34, 53,
+ 59, 71,155, 93,107, 56, 47, 19, 66,164,250, 4, 81,114,195, 53, 66,136, 76, 41,149, 90, 28,203, 13,118, 51,165, 84,146,101, 89,
+ 98,140, 89,204,102,243,149,174,154,115,189,156,191, 2, 47, 43, 0, 9, 12, 12,140,230, 56, 78, 77, 8, 97,245, 19,189, 26, 91,
+185,134, 86,176,249,113,125,232,143, 1,128,195,225,112,106, 65, 9, 33,172,217,167,161, 44, 44, 22,139,211, 61, 56,142, 99,132,
+ 16, 86, 89, 89,201,234,133,182,171, 51, 41,123, 59,127, 5, 94, 86, 0, 87,199, 29, 5,243,209,231,233,109,252, 21,244,180,192,
+ 36, 37, 37,141, 22, 4,225, 17, 79, 12,227, 51,198,194,101, 89, 30,206, 24,123, 57, 37, 37,101,159, 39, 30, 64,225,175,240,191,
+ 86, 5,184, 39, 38, 38,102,195,156, 57,115,186,117,137, 97,118,118, 54, 78,157, 58,133,200,200, 72, 24, 12, 6, 42, 73,210,180,
+148,148,148, 20, 15,188, 0,133,191,194,255,154,162, 64,136,142,142,182, 47, 92,184,176,219, 30, 96,211,166, 77, 48, 24, 12,120,
+244,209, 71,193,113, 28, 14, 30, 60,200,101,102,102, 30, 72, 76, 76, 76, 72, 77, 77,237,246,120,165,194, 95,225,223, 85,116,251,
+ 64,152, 36, 73, 88,191,126, 61, 22, 44, 88,128,190,125,251,194,223,223, 31,137,137,137,136,139,139,227, 84, 42, 85,186, 94,175,
+159,232,203, 54,161,194,255,250,226,223,237, 10, 96, 48, 24, 16, 28, 28,140,136,136, 8, 8,130, 0,173, 86, 11,173, 86, 11,189,
+ 94,143,145, 35, 71,114,106,181, 58, 67,175,215,199,249,234, 11, 80,248, 95, 95,252,187, 93, 1, 10, 11, 11,161,211,233, 26,143,
+ 53, 26, 77,227, 67, 36, 38, 38, 98,248,240,225,188, 90,173, 62,145,144,144,112,131, 47,190, 0,133,255,245,197,191,219, 21, 32,
+ 48, 48, 16, 86,171,115,118, 19,127,127,255,198, 79, 82, 82, 18, 98, 99, 99, 5, 63, 63,191, 44,189, 94, 31,235,107, 47, 64,225,
+127,125,241,239,118, 5,208,233,116, 48,153, 90,167,196,105,208, 98,173, 86,139,164,164, 36, 12, 28, 56, 80,165,209,104,206,234,
+245,250, 1,190,244, 2, 20,254,215, 23,255,110,223, 32, 35, 42, 42, 10, 53, 53, 53,176, 90,173,208,106,235,242,255, 84, 85, 85,
+161,180,180, 20,229,229,229, 40, 45, 45,133,197, 98,193,224,193,131, 33,138,162,250,234,213,171,231,245,122,253,144,180,180,180,
+ 98, 95,120, 1, 10,255,235,139,127,183, 43,128, 90,173,198,248,241,227,145,147,147, 3,157, 78,135, 3, 7, 14,160,160,160, 0,
+177,177,177,136,138,138,194,208,161, 67,193,243, 60, 82, 83, 83, 97, 52, 26, 33,138,162,159, 70,163,201,211,235,245,131,210,210,
+210,188,158,237, 77,225,127,125,241,247,200, 22, 73,211,166, 77,195,167,159,126, 10, 81, 20,241,248,227,143, 99,230,204,153, 80,
+171,213, 78,101, 22, 45, 90, 4,147,201,132,117,235,214, 97,203,150, 45, 90, 74,233,155, 0,158,128, 15, 76, 75, 80,248, 95, 63,
+252, 61,178, 32, 38, 33, 33, 1,129,129,129,248,232,163,143, 48,123,246,108,183,171,168, 66, 66, 66,240,228,147, 79, 66,163,209,
+ 48,171,213, 58, 54, 52, 52,180, 63,124, 32,177, 84, 75,254, 45, 43, 95,225,255,191,195,223, 35, 10, 16, 20, 20,132, 53,107,214,
+ 32, 38, 38, 6,207, 62,251, 44,102,204,152, 1,135,195,225,182,252,144, 33, 67, 36,171,213,106,230,121,254,126, 95,120, 1,205,
+249,119, 4,189,141,191,217, 46,225, 82,105, 45,142, 95,174,192,190, 51,197,136,136,155, 70, 73,212, 40,191,136,184,169,207,196,
+175,248, 79,191,235,169,254, 61,182, 75,164, 32, 8,248,252,243,207,177,122,245,106, 0, 64,114,114, 50, 22, 44,112,189,251,145,
+159,159, 31,163,148, 74,140, 49, 13,124, 36,181,160,187, 94,171, 55,243, 63,122,169, 2,155, 50, 12,200, 41, 50,129,202, 82, 99,
+ 90,119, 22, 54,158, 15,157, 50,118,124, 8,165,227, 41,149,151, 37,190,240,245, 22,202,196,215,210,255,184,232,244,255,122,253,
+ 11,158,124,136, 63,252,225, 15, 0,128,216,216, 88,124,241,197, 23,110, 21,160, 25,122,251,146, 66,159,229,127,185,204,140, 55,
+191,205,134,192, 1, 49, 33, 26, 20,148,137, 96,148,130,177, 86, 31, 2, 70,231,129,146, 95, 76,126,118,253,188,140,119, 23, 37,
+119,250,189,111,248, 9, 89, 5,158,245,167,191,121,246, 94,168,120,238,154,235,223, 99, 10, 80, 84, 84,132,146,146, 18,188,249,
+230,155,120,238,185,231,176,120,241,226, 54,203,247,246,172, 10,190,206,255, 68,126, 37, 24,163,120,235,254, 9, 24, 17, 29,140,
+ 63,109, 59,141,189, 89, 69, 96, 13,189, 64,227, 95,214,112, 76, 64,233, 59, 0, 58,173, 0,207,220, 61, 25, 14,201,179, 85,209,
+ 82,248,187, 90,255, 30, 83,128,236,236,108, 68, 68, 68,224,217,103,159, 5, 33, 4,185,185,185, 46,115,234, 52,215,222,250,165,
+136,189,117,113,138, 79,243, 63, 83,104, 2,165, 20, 2, 87,103, 33,168, 56, 82,215, 3,180,248,180, 80,130, 27,110, 90,178,198,
+255,216, 63,150, 90, 58,243, 91, 57,133,229, 40,175,181, 94, 51,103,209, 97,119,235, 59,206, 26, 59, 24, 92,253, 18, 4,187,221,
+ 14, 89,150, 57, 89,150,213, 0, 66,208,118,126,214,234,230,215, 59,164, 0,159,237,205,196,165,146,206,109,120,146,157,150,138,
+232, 81,147,240,202,198, 84, 72, 14, 59,206,156,191,136, 87,190, 78, 1,199,183,222, 56,239, 80, 77, 8, 95, 54,112,234, 72,235,
+ 0,149, 86, 8, 31, 20, 13,144,118,133, 72, 82,227,143,248,114,101,165, 15,245, 0,180,190, 98,125, 50, 63,168, 67,148,193, 40,
+195,138, 47,143,162, 95,152, 22, 57,133,149,117, 2,207, 24, 24,163,160,204,165, 57, 4,217, 95,173, 6,208, 41, 5,200, 51, 86,
+ 33,191,172,250,154, 57,239, 92,247, 49,210,183,111,236, 72, 81, 53,128, 59,235, 63,111,183, 83,246, 70, 0,103, 58,165, 0,250,
+ 17,253,220,238,249,229, 14, 17, 86, 3,138,250,248,225,238, 73,195,240,233, 71,239, 33,208,223, 31, 63,143, 31,225,186,194, 82,
+183,211, 98, 83,126,161,228, 96,167,164,240,129,223, 18,158,111, 63,197, 96,165,214,210, 93,194, 65,171, 12,224, 66, 59, 54,162,
+110, 50,153, 96,179,217, 16, 21, 21,213,252, 52, 67, 83, 94, 32, 31,237,193,234, 4,221,108,151,113,174,200,214, 36,244,148,130,
+ 82,230,214, 20, 2,215,249, 64,225,162, 91,110,236, 22,198,166, 67,201, 72,175,139,242, 32, 34,194,181,252,157, 57,115, 6,181,
+181,181, 13,141, 80, 25, 99, 44,215,205,237, 70, 1,173,246,153,232,152, 2,140,236,167,235,188, 61, 80, 58, 4, 63, 92,202, 65,
+148,202,129, 13,159,125,130, 25, 51,102, 96,242,176,104,151,101,163, 84, 14,234, 95,109, 40,179,150,151, 95,172,201,220,123, 8,
+ 61,156, 98,220,113, 98, 61,184,136, 17, 80,199,253,162,221,178, 85, 85, 85,152, 59,119, 46,118,239,222,221,242,165, 80, 95,115,
+130, 25, 99, 16,229, 58,125, 92,126,199, 72,136,242, 8,103,253,100,117,255, 63,248,167,173,204, 14,129,184, 50,133, 0,128, 93,
+125,186, 97,177,139, 68,162,255, 42,181,247,187,203,255,189, 27, 39, 47,151, 92,187,227,158, 86,183, 59, 46, 55,106, 6,248,113,
+ 83,157,174,237,122,105, 1,212, 2,143,105,211,166, 33, 61, 61, 29, 0,160,209,104,126,176,217,108, 15,187,145,159, 61, 0,102,
+244,152, 15, 48, 96,192, 0, 28, 59,118, 12,219,183,111,135,205,102,195,252,249,243,219,109,136,235,109,104,175,180,142,246,148,
+ 15, 64, 56, 30,170,209, 63,111,183,244,217,179,103,113,199, 29,119, 96,231,206,157,232,211,167,143, 15,240,119,150,233,140,188,
+ 10,164,158, 47, 65, 70, 94, 57,204, 86, 7, 40,149, 91,181,240, 78,231,160, 34, 13, 38, 80, 75, 83,232,181,159, 93,137, 4,112,
+174,241, 25,175,254,238, 44,152,188,140,196,172,118,155,175,245,131, 71,110,235,150,103,121,222,122, 18,239,103,236,192,138,123,
+226,241,240,195,191,236,136,194,119,186,225,236,144, 2, 56, 36, 25,148,117,174,103, 55,219,108,216,187,119, 47,100, 89, 70,100,
+100, 36,102,205,254, 25,108,162,228, 38,118, 72, 64,121, 1,208,104, 57,220,189,212, 15,186,232,246, 31,100,237, 43,246,142,248,
+ 10,157, 81, 2,219, 79,127, 5, 8, 15,213,168,187,218, 45,157,149,149,133, 59,239,188, 19, 59,119, 54,238,236,234, 19, 81,160,
+ 79,246,229,226,199,204,162, 38, 97,111, 33,216, 77, 2,206,156,237,125, 23,166, 80,235, 42,162, 28,152,116, 35,152,252, 29, 51,
+ 44, 25, 72, 6,252,163,194, 21,135,175,211,114, 96,232, 6, 31,224,104,110,221,252,182, 31, 79, 94, 66,217,119,206, 43, 33,127,
+119,215,205,224,185, 86,238,150,103, 20,224,181, 77,169,157,138,235, 58,204,213, 72, 91,243, 18, 26, 50, 5, 14,152,181, 24,143,
+253, 99,143,251, 22,181, 50, 92, 85, 26, 59,123,170, 72, 84,163, 4, 77,240, 47, 96,110,223,142,150, 22,190,189, 24, 27, 96,236,
+238,158,192,118,224,207, 0,199, 67, 53, 98,118,187,165, 51, 51, 51, 49,123,246,108, 76,154, 52, 9,245,137,182,188,170, 0, 57,
+ 87,107,240,227,233,171,237, 10,182,187,191,172,222,236,113, 45,252, 18,192,228,186, 15,149, 2,192,228,223, 0,120,195,165, 73,
+ 27,226,223, 24,161,185, 22,204,152, 53, 27, 67, 6, 13, 68,220,164,201,232, 31, 17,210, 34,232,224,218,138,104,227,118, 31, 3,
+216, 6,160,184,211, 10,240,214,194, 91, 58, 69,124,225,194,133,176, 86,214,217,128, 43, 86,172,192, 27,111,188,209,102,249,167,
+159,126,218,177,235,232,174, 93,165,165,165,187, 42, 42, 42,190,132, 87,183, 25, 98,176,237,255, 35, 8,199, 67, 24, 62,171,221,
+210, 39, 78,156, 64, 97, 97,161, 42, 40, 40,136,247,182, 15,176,247,140,177, 93,193,102, 45,206, 57,149,173,239, 33,154,161,118,
+214,232,138, 64, 48, 9,160,178,179, 18, 48,233,255,220, 41,192,164,161,125, 33,201,215,254, 10,111, 31, 59, 8,192,189, 46,175,
+185, 81,176,182, 26,206, 45, 93,238, 1, 58,131, 77,155, 54, 97,243,230,205, 0,128,233,211,167, 99,220,184,113, 29, 14, 35,250,
+130, 13, 93,223,213,195,186,247,109,104, 9, 15, 97,216,204,118,139,151,148,148,112, 85, 85, 85, 51,181, 90,237, 78,111,210, 46,
+ 40, 51,183, 22,108, 39,211,135,181,109, 10, 81,218,232, 24,215,139,211, 14, 63, 34,198,131,214, 11,190,179, 18,244,101,185,247,
+ 69, 76, 93, 92,236,210, 98,200,204,247,236, 72,240,182, 23,230, 65, 45,240, 61,227, 3,116, 20, 70,163, 17,203,150, 45, 3, 0,
+ 60,245,212, 83, 88,190,124, 57,222,127,255,125,220,119,223,125,237, 9,191,207,216,208, 78, 74,176,231, 13,104, 57, 30, 66,236,
+244,246,205, 62,135, 35, 66,146,164, 21, 0, 54,163,110,176,165,199, 81,108,178,180, 22,236, 86,145,157, 54, 76, 32,103, 63,239,
+220,188,201,149,175,129,138, 59,235, 91,252,230, 38, 80,195,255,195, 93,241,248,243,131,183,122,235,173,121, 70, 1, 58, 58, 16,
+182,229,253,151, 80, 94, 94,142,126,195,227,224, 55,241,110,124,188,247, 44, 54,126,247, 3, 28, 3, 39, 35,172,175,251, 73,134,
+233, 53,193, 66,241,128, 91, 38, 89, 7,106,116, 66,112,244, 77, 62, 51, 16,198, 40,172,187, 95,131,246,118, 30,194,144,169,237,
+215, 62,165, 35,234,237,204,159, 1, 48,247,228,155,183,139, 50,202,170,173,109, 10, 56, 24,197,168,126, 97, 24, 30, 19, 10,127,
+ 53, 95,175, 36, 12,187,247,236,145, 10,140,101,217, 18,175,189,164, 14, 31,144, 77,128,172,111,127,115,246,252,128, 80,219, 23,
+ 96, 82,180,139,214, 31,245,102,209, 48, 87,202,254,238,119, 25, 56, 95, 84,225,209,231,253,248,241, 89,174,230, 2,121, 70, 1,
+166,223, 56, 16,147,134, 58,218,142,138,156, 58,129, 11,199,211,160,235, 19,129,127,253,123, 45, 34,162,250,226,245,149,207,162,
+164, 32, 23,255,120,254, 33, 68,247,235,143, 71,150, 62,137, 95, 44, 92,212,186,235, 78,219, 78, 75,170, 46, 94,144,236, 72,167,
+129,186,253,224, 85,237, 63,136, 40,246,140,128, 81, 25,214, 93,175, 64,123,199, 27, 16, 6, 37,118,228, 27,183,212, 43,193, 28,
+ 0,214,158, 82, 0,158, 35, 0, 99,110,109,252,176, 64, 53,126, 63,111, 18,110, 30, 80, 14, 34, 93, 6, 88,211,134,246, 55,251,
+149, 18,201, 94,174,234, 19, 74,252, 71, 13,171,138, 38,160,119,130, 74,227, 65,101,190,141,214, 31, 96, 82,128, 43, 5, 88,144,
+ 56, 10, 86,187,103,115, 4, 11,174, 7,232,152, 71, 20, 32, 54, 42,180,221, 50, 23,143,213,201,227,250,117, 95, 96,230,228,177,
+ 88,191,126, 61,190,251,230,171,198,235, 87, 11,175,224,237,151, 95,192,200,193, 49,120,224,129, 7,156,190,219, 71, 37,202, 1,
+181, 87, 75,106,141,198,139,181,153,123, 79,194,215,246,218,165, 18,172, 59, 95,134,118,214,155, 0, 58, 52, 71,253, 86, 0,223,
+ 1,184, 27,128,173, 39, 40, 10, 60,135,240, 0, 21, 74, 76, 98, 43, 27,159,128,225,181, 7,166, 96, 92,216, 15,224,106,178, 90,
+125, 87, 63, 30, 60, 88,232,104, 80,121,180,139, 86, 30,173,148,160, 73, 17,114, 80, 55,247,198, 9,102,155, 3,213, 86,199,255,
+142, 9,212, 17,148,151,151, 35, 52, 52, 20, 51,103,214, 57,141,111,189,245, 22,198,141, 27,135,249,243,231, 35, 47, 47, 15, 35,
+ 71,142,196, 59,239,188,131, 23, 95,124,177,149, 2, 52,115, 96,124,119, 54,168, 44,194,150,242, 30,144,240,118, 71,191,113, 27,
+128,135, 0,252,163,167, 40,246, 13,209,194, 88, 89,219,202,244,153,114, 67, 20,198, 70, 21,128,171,205,114,209,102,182, 16,112,
+ 87,166,142,203,243, 50, 64,165,179, 0,166,180,188,229,206, 83,151,112,161,216,179,214,233,196, 33, 81, 16,122,202, 4,170,181,
+ 57,218, 13,107,197, 12, 28,140, 81,163,111, 68,149,217,134,146, 18, 35,114,115,115,241,205,214,239, 16, 63, 37, 1,143, 62,180,
+ 8,171,222,125, 15, 34, 5,126,191,226, 57,100,229, 92, 64,255, 1, 77,115,111,236,148, 16, 89,229,175,146, 2,250,248,225,230,
+135, 67,161, 13,110,255, 65,198,163, 26,175,190,218, 99, 61, 5,231,175,131,118,206,187, 40, 55,117,184,151,125,191, 39,133, 31,
+ 0,134, 68, 4,226,100, 94, 73,171,112,231,232, 1,225, 32,226,233,214,214, 66, 91,173, 60,117,161, 4,206,231,175,144,184,148,
+226,164,164,164, 86, 60,150,253,108,146,119,226, 22,158,138, 2,253,101,219, 17,100, 27,218, 14,107,201, 14, 59, 78, 95,184,132,
+ 37,107,118,128,202, 18,180, 33, 58,124,145, 85,131,245, 57,251,144,117,165, 2, 75,214,236,128,100,139, 0, 39,168,240,252,231,
+ 59, 17, 24,209,228, 20,103, 85,135,169,138, 7,207,184,205, 65,212, 99, 4, 77,224, 67, 29,114,130, 79, 9, 75, 0,148,244,152,
+240,207,253, 0, 92,232, 64,192,148,223, 81,225,255, 93, 79, 11,192,188,248,193,248,238, 72, 30,100,217, 57,220, 25,232,167, 2,
+161,181, 78,206,125,199, 90,249,230,202,209,226, 26,240, 23,119, 60,126,253,207,157, 56,158,231,217, 44, 43, 7,223,248, 85,171,
+ 48,168,199,122,128, 87,238,239,144,243,135,249,199, 55,227, 47,247,223,132, 1, 3, 6,224, 29,249, 34,180,154, 34, 44, 95,190,
+ 28,203,243,247,225,165,135,146,224,231,231,135, 81,127, 95,129,109,111, 62, 1,190,217,180,232,103,158, 57,232,216,115,108, 79,
+178,209,104,252,161,188,188,124,191, 47,249, 0, 78,194,223, 49,124,224, 13,225, 7,128,200, 16, 45,102,143, 31,128,173,135,115,
+157, 28, 96,231, 9,112,157,106,229, 91, 40,135,220,240,106, 74,219,234,221,254,254,248, 44,175,188,171,102,251,187,245,188, 15,
+ 0, 0,127,255,251,223,241,252,243,207,227,239,127,255, 59, 94,120,225, 5, 36, 39, 39, 67,146, 36,140, 27, 55, 14,199,143, 31,
+ 71,126,126, 62,238,184,227, 14, 39,225,111,230,189,203,148, 82,159,154, 78,220, 89,225,231,121,254, 27, 89,150,127,231, 77,206,
+191,190, 35, 14,126, 42, 14, 7, 78, 27, 80, 92, 89, 11, 6, 82, 63,106, 74, 1, 38,186,108,229,101, 81, 6,152, 36, 19, 34, 83,
+ 14, 50,117,171, 4,117, 14,253, 81, 0,207,146,184, 84,183,211,209,119,158,186,132, 18,147,197,163,207,185, 48,105,116,171,185,
+ 64,245, 38, 16,243,154, 2,232,116, 58,188,248,226,139, 88,185,114, 37,238,186,235, 46,220,123,111,221, 48,246,152, 49, 99,240,
+250,235,175,227,198, 27,111,196,154, 53,107,220,105, 47,245,165,129,176,206, 10,127, 80, 80,208, 17,149, 74,245, 65, 69, 69,133,
+ 87,121,171, 4, 14, 75,102,197, 97,201,172, 22, 9,148, 77,123, 1, 42,186, 52,117,254,181, 45,216,158,113,228,196,231,209, 97,
+214,159, 94,249, 77,255,227, 42,158,177,102,189,193,121, 18,119,176, 83, 61,178, 40, 83,183, 19, 31,123,101, 20,232,147,157, 39,
+144,107,172,234, 56,139,209,183,227,131,173, 7,241,202,223,214,163,232, 66, 54,170,203,141,144, 28,118,140,184,255,183,120,225,
+203,159, 90,219,115,213, 33,234, 43, 3,111,157,105, 25,172, 29, 42,248,135,221,215,145, 69, 85, 18, 52,175, 99,211,211, 21,190,
+ 32,252,227,198,141,147, 36, 73,218, 89, 88, 88,232, 91,225,219, 22,161,220,186, 86,189,181,169,179,244,238, 18,205,210,187,162,
+150,128,201, 75, 90,181,254, 96, 97, 0,170, 58,243, 83,115, 38, 14,245,150, 19,236, 25, 19,104,214,184, 33,168,181,117, 50,174,
+123,155,243, 62, 6, 75, 23,221,143,135,166,141,113, 89,180,228,200,143, 82, 85,213,197,147,146,168, 74,113, 12,158,156, 5,194,
+117,224, 65,170,107,125, 65,248,151, 45, 91, 6,198,152, 99,223,190,125, 62,190,168, 95,114,107, 2, 57, 69,129, 84,209,102, 16,
+129,192,122,222,191,203,102, 88, 39,157,224,221, 47, 63,128, 32,173,218,119,123,128,142, 12,132,181,135, 49,163, 70, 96,236,160,
+ 72,151,215,250,168, 68, 57,168,182,176,168,186,176,240,172,249,232,182,147,222,242, 3,186, 34,252,239,190,251, 46,158,121,230,
+ 25,230,107, 38, 92,235,214,145, 7,105, 48,129,220,216,248,148,105,109, 92,236,218, 0, 16, 14,184,176,160, 22,142, 66,127, 0,
+246, 78,251,130, 94,114,130,225,205,129,176,230, 56,113,226, 4,190,252,242, 75, 76,157, 58, 21,115,231,206, 5, 0, 12, 29, 58,
+ 20,178, 44,187,114,128, 27, 39,195,213, 59,193,232, 77,194,239, 43,252,219, 85, 0,213, 96,192,156,222,102,180,135, 48,137,135,
+ 92, 13,112, 26, 64,174, 38, 0, 78,146,184, 84,171,175, 61,203,246,237,219, 81, 88, 88, 8, 0, 40, 46,110,234,105, 40,165, 19,
+209,148, 31,116, 63,128,156, 30, 87, 0, 74, 41,230,205,155,135, 43, 87,174,224,227,143, 63,198,241,227,199, 49,114,228, 72,132,
+132,132,192,106,181, 34, 48, 48,208,149,237,230, 85, 39,152,248,247,233,178,240,251, 2,255, 14,189,151,192, 89,224, 44,135, 64,
+172,103, 93,155, 64,160, 32,128, 10,231,127,110, 7, 56, 6, 38,137, 0,150,250,226,179,172, 94,189, 26,251,246,237,115, 37,123,
+115, 80, 55, 7, 11, 0, 30,243,138, 2,212,214,214,226,202,149, 43,141,202,208,208,226, 23, 23, 23, 67, 20, 69,119, 17, 32, 48,
+198,168,220,176,132,172,135,161,185,249, 49,128,227, 59, 84,182, 95,191,126, 78,194,239, 11,252, 59,166,229, 42, 72, 81,175,131,
+ 51,167,129,171, 88, 7, 98,191,220,220,209,109,214, 26,201,118, 64,126, 15,192,123, 36, 46,213,228,139,143,242,231, 63,255, 25,
+149,149, 77, 83, 45,254,246,183,191,217, 14, 31, 62,188,174,180,180, 52, 77, 20,197,252,250, 7,202,233,200,189,186, 93, 1,130,
+131,131,113,251,237,183, 35, 59, 59, 27,159,127,254, 57,134, 15, 31,142,140,140, 12, 24,141, 70,132,133,133,185,127, 63,222,204,
+172,214, 65,225, 7,220,231,172,236, 29,153,237, 8,104, 64, 34,104, 64, 34, 32, 87,129, 56, 10, 64, 28, 6,108,217,188,209,158,
+151,119,225,115,115,109,229, 87, 99,134, 9, 63,205,127,250,156, 79, 63,199,216,177, 99,157,142,183,109,219, 38,231,230,230, 94,
+ 48,155,205,135, 76, 38,211,185,206,248,144, 30,241, 1, 54,110,220,136,215, 94,123, 13,159,125,246, 25,190,255,254,123,232,116,
+ 58,124,240,193, 7,237,125,173, 87,167, 70,236,117,252,249, 80, 48,109, 40,152,118, 44, 82,206,236,147,246,239,207, 62, 87, 80,
+ 80,126,165,170,170,138, 94, 79,245, 47, 0,128,201,100, 18, 50, 50,186,119,255,228,150,171,192, 78,158, 60,233,182,172,201,100,
+226, 9, 33, 93, 54, 33, 60,193,191,147,191,175,240,239,165,252, 5, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99,
+ 76, 13,128,213, 71, 54, 88,179, 15,234,207, 55,254,223,242,154,187,235, 45,238,213,178, 44,147,101, 89,150, 36,169,164, 62,189,
+ 96,103, 67,160, 10,127,133,127,151,249, 55, 31,114,229,116, 58,221,114, 0,125,209,148,229, 76,102,140, 73,132, 16,153, 49, 38,
+ 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84,191,184, 93,110,184, 70, 8,145, 41,165, 82,139, 99,185,193,110,166,148,
+ 74,178, 44, 75,140, 49,139,217,108,190,210, 85, 75, 94,225,175,240,239, 44,255,230, 10, 64, 2, 3, 3,163, 57,142, 83, 19, 66,
+152, 74,165,130, 40,138,141, 90,214,160,133,205,143,235, 67,127, 12, 0, 28, 14,135,147, 6, 19, 66, 88,179, 79, 67, 89, 88, 44,
+ 22,167,123,112, 28,199, 8, 33,172,178,178,146,213, 87, 90, 87,215,210, 41,252, 21,254,157,230, 79,218, 57,238, 40,124,101, 6,
+167,194, 95,225,223, 35,132,187, 5, 73, 73, 73, 2,128,217, 28,199,221,247,211, 79, 63, 45,238,109, 97, 7,133, 63,144,148,148,
+ 52, 90, 16,132, 71, 8, 33,221, 46, 75,140,177,112, 89,150,135, 51,198, 94, 78, 73, 73,217,231,137, 58, 16,186,169, 34,251, 1,
+ 40, 79, 73, 73,177,117,176,252,120,181, 90,189,132, 49,246, 43,157, 78,199,149,149,149, 9, 0, 22,123, 81, 16, 20,254, 93,231,
+127, 67,100,100,228,147,115,230,204,241,235,206,103,202,206,206,198,169, 83,167, 16, 25, 25, 9,131,193,176, 59, 41, 41,105, 90,
+ 74, 74, 74,138,207, 40, 64, 82, 82, 82, 8,128,121, 90,173,246,215, 14,135, 99,188, 32, 8, 59,146,146,146,230,166,164,164, 48,
+ 55,229, 35, 57,142,123, 80,173, 86,255,159, 32, 8, 81,241,241,241,154, 73,147, 38, 9, 90,173, 22,111,190,249,166,205, 11, 66,
+163,240,239, 38,254,209,209,209,246,133, 11, 23,118,155, 2,108,218,180, 9, 6,131, 1,143, 62,250, 40, 56,142,195,193,131, 7,
+185,204,204,204, 3,137,137,137, 9,169,169,169, 25, 94, 83,128,164,164, 36, 53,128,217,126,126,126, 75,101, 89,158, 62,108,216,
+ 48, 41, 62, 62, 62,104,232,208,161, 88,179,102,205,173, 37, 37, 37,239, 2,120,166, 69,249,185, 90,173,246, 73, 73,146,226,227,
+226,226,104,124,124,188,255,224,193,131, 27, 38,144,193,106,181,246,164,208, 40,252,189,200,191, 35,144, 36, 9,235,215,175,199,
+210,165, 75, 17, 22, 22,134,218,218, 90, 36, 38, 38,130, 82,202,101,101,101,165,235,245,250,155,211,210,210,142,247,152, 2, 36,
+ 37, 37, 17, 0, 73, 26,141,230, 49, 74,233,188,190,125,251,202, 83,166, 76, 9,137,139,139,131,159, 95,147,210, 63,246,216, 99,
+ 1,239,189,247,222, 19,183,220,114, 75, 14,165,244,148, 70,163, 89, 74, 41,157, 31, 19, 19, 67, 19, 18, 18,130,227,226,226,160,
+ 82,169,188, 97, 30, 40,252,189,200,191,179, 48, 24, 12, 8, 14, 14,110,220,124, 68,171,213, 66,150,101,232,245,122, 72,146,196,
+229,228,228,100,232,245,250,241,105,105,105, 89, 30, 85,128,122,231,102, 49,199,113,143, 6, 6, 6,170,227,227,227, 3, 38, 76,
+152,192,135,132,132,184, 44,239,239,239,143, 37, 75,150,248,175, 94,189,250, 35,173, 86,235,152, 50,101,138,118,226,196,137,124,
+104,104,104,183, 85,206,244,233,211,251,216,237,118,154,158,158, 94,209, 1,193, 81,248,123,145,127, 87, 81, 88, 88, 8,157,174,
+105, 71, 34,141, 70, 3, 89,150, 33,203, 50, 18, 19, 19, 33,203, 50,127,225,194,133, 19, 9, 9, 9, 55,166,167,167,159,239, 86,
+ 5, 72, 74, 74,138,225, 56,238, 87,106,181,122, 9,199,113, 49,147, 38, 77, 18,110,186,233, 38,117,223,190,125, 59,116,179,136,
+136, 8,172, 92,185, 82,237,239,239,175,238,206, 74, 73, 76, 76, 28, 17, 16, 16,176,210,110,183,223, 86, 93, 93, 29,219,134,208,
+ 40,252,189,200,191, 59, 16, 24, 24,216,202, 44,243,247,247,111,220,212, 59, 41, 41, 9,178, 44, 11,151, 46, 93,202,210,235,245,
+ 35,211,210,210,242,186, 69, 1,146,146,146, 18, 4, 65,216, 59,102,204, 24,122,243,205, 55,251,199,198,198,162, 43,145, 45,127,
+127,255,110,171,140,169, 83,167, 78, 11, 8, 8,120,153, 82,154, 16, 16, 16,160,150,101,249,163,236,236,108,135, 27,225, 81,248,
+123,145,127,119, 65,167,211,193,100,106, 61, 11,187,193, 20,146,101,185, 65, 9, 84, 5, 5, 5,103,245,122,253,176,180,180, 52,
+195, 53, 43,128,159,159,223,107,208,238,250,153, 0, 0, 20,252, 73, 68, 65, 84,119,222,121,167, 58, 33, 33,129,131, 23, 49,125,
+250,116, 65,150,229,251,252,253,253, 95,241,247,247,239,255,224,131, 15, 6, 76,159, 62,157, 44, 88,176,192,102,177, 88, 62,114,
+247, 61,133,191,119,249,119, 23,162,162,162, 80, 83, 83, 3,171,213, 10,173, 86, 11,160,110, 99,194,210,210, 82,148,151,151,163,
+180,180, 20, 22,139, 5,131, 7, 15,134, 40,138,234,171, 87,175,158,215,235,245, 67,210,210,210,138,187,172, 0, 73, 73, 73, 35,
+ 1, 36, 77,154, 52,201,107,149, 31, 31, 31, 31,172,209,104,150, 8,130,176, 98,232,208,161,154,135, 30,122, 40,104,202,148, 41,
+ 32,132, 96,247,238,221, 16, 4,225, 84,122,122,250, 69, 55,173,167,194,223,139,252,187, 19,106,181, 26,227,199,143, 71, 78, 78,
+ 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42, 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40,
+138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,237,146, 2,104, 52,154,151,166, 78,157,170,242, 70,148,160,186,186, 26, 28,
+199,169, 2, 3, 3,139, 38, 79,158,140, 95,253,234, 87, 1, 55,220,112,131, 83,153,111,190,249,166,166,182,182,246,207,238,238,
+161,240,119,195,205, 38,225,167,139,165, 40,169,113, 64, 45,112, 80,243, 4,106,158,131, 70,224, 48, 97, 64, 40,250, 6,251,117,
+ 11,255,238,198,180,105,211,240,233,167,159, 66, 20, 69, 60,254,248,227,152, 57,115, 38,212,106,103,183,102,209,162, 69, 48,153,
+ 76, 88,183,110, 29,182,108,217,162,165,148,190,137,166,245,192, 29, 87,128,164,164,164,104, 74,233,189,122,189, 94,232, 73,193,
+ 41, 44, 44, 68, 74, 74, 10,206,157, 59,135, 57,115,230,240, 11, 22, 44, 8,136,140,108,157, 53, 34, 63, 63, 31, 5, 5, 5,148,
+231,249,111,221,180,158, 94,231, 63,243,206,159,241,139,127,249,128, 79,240,183, 75, 20,169,121,229,216,157, 83,130,140,252, 74,
+136,110,146, 26, 19, 0, 3, 53,118,220,104,207,198, 67,119, 37,240,183,205,127, 34, 32, 50, 50,170,211,252, 61,129,132,132, 4,
+124,253,245,215,120,227,141, 55, 16, 19,227, 62, 29,125, 72, 72, 8,158,124,242, 73,108,223,190,157,213,212,212,140, 13, 13, 13,
+237, 95, 85, 85,117,165, 51, 74, 32,168,213,234,231,110,186,233, 38,174, 59,157, 39,119, 96,140, 33, 39, 39, 7,169,169,169,168,
+172,172,196,125,247,221,135,215, 95,127,189, 77,199, 45, 57, 57,217,193, 24, 91,179,127,255,126,201, 77,151,233, 85,254,137,243,
+ 30,197,211,235,126,194, 61,178, 10,145, 94,228,207, 24,240,245,113, 3,214, 30, 42,128, 85,108,127, 93, 8, 3,144,111,215,224,
+151,131,181,184, 91,216, 3,203,119,199, 96, 31, 57, 3,252,144,169, 16,162,199, 55, 46, 19,109,143,191, 39, 16, 20, 20,132, 53,
+107,214,184, 93,126,218, 18, 67,134, 12,145, 12, 6,131,153,231,249,251, 81,151,152,184,227, 10,192,243,252,207, 39, 77,154,164,
+241,228, 3, 73,146,132, 99,199,142, 33, 45, 45, 13, 1, 1, 1, 88,184,112, 33,166, 77,155,230, 50, 69,138, 83,107,102,183, 99,
+231,206,157,212,106,181,254,205, 93, 25,111,242,207,200, 45,198, 93,171,190,129,213, 33,225,238,119,190,193,190, 87, 23, 34, 58,
+ 44,176,199,249,151,155, 29,120,251,199,115, 56, 90,208,249,156,252, 19, 2,235,190,227, 47, 85,193,145,181, 5,200,218, 2,226,
+ 23, 12, 97,144, 30,108,128, 30,251,246,180,205,223, 83,232,168,240,215, 7, 16, 24,165, 84, 98,140,105,208,201, 9,158, 2, 0,
+194,113,158,241,189,204,102, 51,210,211,211,113,248,240, 97,140, 26, 53, 10, 43, 86,172,232,240,174,145, 0,176,111,223, 62, 8,
+130,112, 36, 45, 45,173,173,156,228, 94,225,159,109, 40,195,188,119,183,194,234,168,107, 24, 11,202,170,113,239,159,147,177,243,
+165,249, 8,214,106,122,140,191,201, 38,225,183,155, 51, 81, 80,209,249,100,180, 4,192,248,160,214, 89, 15,153,173, 26,226,185,
+ 29,192,185, 29,248,247,108,162, 82, 17,246, 23,242,192,148,100,104,196,239,195,151, 30,243,201, 76, 17,245,232,218,154,224,238,
+ 70,105,105, 41, 82, 83, 83,145,153,153,137,105,211,166,225,195, 15, 63,196,128,102, 27, 98,116, 20, 61,237,124,117,148,127, 65,
+ 89, 53,230,190,243, 13,170,204,206,115,200, 50,243, 75,176,240,253,109, 72,126,238, 94,168, 5,222,227,252,173,162,140,231,147,
+ 79,119, 73,248, 1, 32, 86, 91,139, 16,161,237,245, 35, 42,142,241, 0,230, 49, 96, 58,236,170,229,229, 31, 76,249, 74,144,201,
+218,144,167,211,189,155, 5,152, 81,128, 52, 53, 28, 93,205,202,209,173, 10,144,151,151,135,148,148, 20, 20, 22, 22, 98,238,220,
+185,120,238,185,231,208,213,161,248,220,220, 92, 92,189,122, 85,140,142,142,254,111, 79,213,105, 71,248,151,152, 44,152,179,106,
+ 19,174, 86,185,222,163,111, 95, 86, 62,150,124,178, 3, 47,222, 57,210,227,252,255,153,122, 25, 57,198,154,182, 91,121, 2,232,
+ 71,244, 71, 76, 88, 0,204, 54, 17,149,102, 59, 14, 95, 40, 2,101, 12, 19,130, 42,219,234,151,144,122,133,179,199,199,208, 39,
+ 52, 4, 7, 67,151,165,229,250, 66, 19, 79, 45,229,176,253,176, 18,204, 82, 6,245,228, 37, 80,141,184,163,177,245,175, 95, 74,
+217,233,244,232,215,180, 26,135, 82,138,204,204, 76,164,166,166, 66,150,101, 60,240,192, 3,184,253,246,219, 91,133,173, 58,139,
+173, 91,183,218, 41,165, 31,111,218,180,169, 61,173,238, 49,254, 53, 86, 7,238,249,211, 22,228, 22,183,157, 44,121, 99,122, 14,
+ 12,185, 57,178,218,131,252, 47,150,214, 34,249, 84,161,219,235,129,126,106,172,184, 39, 30, 11, 18, 71,161,127,120,144,211,181,
+203, 37, 38,124,180,227, 56, 6, 95,106, 61,159,204, 6, 13,252, 96, 7, 24,197,153, 50, 97,227,220, 63,166,172,245, 37, 27,135,
+ 85, 23, 65,174,200,173,219,179,109,223,219, 16,179,147, 17,227, 7, 82,191, 32,158,118,197, 7,232, 18, 28, 14, 7, 14, 29, 58,
+132,244,244,116,244,239,223, 31, 79, 60,241, 4,226,227,227,209, 29, 11,131,108, 54, 27,246,236,217,195,108, 54,219, 39,158,170,
+200,206,242,183,139, 50, 22,188,247, 45, 78, 94, 54,118,232,254,233, 37,224, 53, 33,137, 20,216,227, 17,254,255, 72,201, 3,117,
+163, 58,209, 97,129,216,242,236,189, 24, 55,216,117, 50,226,193,145, 33,120,247,161, 91, 81,242,229, 23, 78,155,156,214,112, 65,
+ 8,162, 77, 61,202,226, 56,199,224, 23,124,204,200,231,251,142,129,118,214, 27,176,238,124, 9,144, 69,200, 37,103,241,255, 6,
+ 16,149,223, 20,255,193,111,109, 39, 93,234, 1,186,132,109,219,182,129, 82,138, 85,171, 86, 97,248,240,225,221,250,144,123,246,
+236,129, 32, 8,169,169,169,169, 69,158,170,200,206,240,167,140,225,145,143,183, 99,127,118, 65,167,126,195,206,107, 95,230,231,
+175, 58, 39,111, 92,185,161, 59,185,151,155, 29,200,200,175,116,217,216, 13,208, 5, 97,247, 43, 11, 49, 64, 23,212,142,187, 40,
+ 66,107,174,123, 30, 17, 2,100,162,114, 18,126, 0, 80,243,152, 90,249,158,126,124,216,239,210, 78,250,146, 18, 8,131,244,208,
+206,122, 3,182,157, 47,131,201, 14,240,132, 97,241, 36,191,113, 83, 6, 14,122, 88, 16,134,173,155,252,234,225,234,142,222,139,
+ 67, 23,246, 21, 48,155,205,200,204,204,196,202,149, 43,187, 93,248, 27,156, 95,179,217,220, 81,231,209,227,252,151,125,182, 27,
+ 91,143, 92,232,202,163, 16,194,176, 86,184,127,213,140,238,228,191, 35,171, 16,204, 77, 79,255,135,121,250,246,133, 31,128, 92,
+ 94,103, 70,128, 87, 33, 48,225, 9,248, 49,215, 11, 99, 40, 47,223,235,139,225, 30, 97,144, 30,126,179,255, 8,162,210, 54,158,
+ 27, 17,169,158, 52, 52,156, 28, 42,251, 48, 97,164, 71,123,128,163, 71,143, 34, 33, 33,161,205, 92,159, 93,197,185,115,231, 80,
+ 82, 82, 98, 59,120,240,224, 78, 79, 85, 94,103,248,191,254, 77, 42, 62,219,155,121, 45, 63,167, 6,144,172, 90,240,206, 45,226,
+215, 47,156,234, 14,254,169,103, 93, 79,126, 28,216, 39, 24, 11,147, 70,119, 44, 94, 88,114, 6, 32, 28,180,183,191, 6, 97,112,
+ 18,196,236,100,208,106, 23, 62, 5, 35, 9, 61,102,223,215,150, 64, 42, 60, 6, 72,118, 48, 89, 4,100, 7, 24, 21, 65,168, 4,
+230,176,130, 57,106,193, 28,181,128,104, 1,179,155,235,254,111,189, 51,234, 40,194,216,225,242, 15, 19,230,235,158, 74,255,177,
+219, 21,128, 82,138,140,140, 12,188,252,242,203, 30,169,132,173, 91,183,218, 68, 81,252, 0, 30, 74,149,209, 25,254,127,251,241,
+ 56,222, 73, 62,212,120, 28,164, 85, 99, 70,220, 32,216, 68, 9, 63,158,188,228,186, 66, 9, 16,224,168, 56,100, 82,133,107, 0,
+ 76,168, 63, 29,204, 40,251,193,239,129, 85,122,219, 87, 43, 47, 95, 43,255,203,149, 86,128,104, 91, 93, 91,116,203,141, 80,241,
+ 29, 27, 83,160, 37,103,161,137, 95, 10, 97,112,221, 62,191,170,225, 51, 97, 63,246,133,139, 62, 12, 61,178,233,175,116, 97, 39,
+172,123,223,118, 37,208, 93, 65, 48, 24,219, 94,241, 97,252,178,240,167, 14,255,173, 61, 19,168, 83, 56,127,254, 60,130,130,130,
+ 16, 23, 23,215,237,149, 96,177, 88,176,127,255,126, 56, 28,142,127,122,170,162, 59,202,255,235,180, 28, 60,183,110, 31,162,195,
+ 2,241,248,109,227,240,237,138,121, 48,124,242,127,216,240,219,185,109,239,129, 69, 37,140, 40, 73,253,185,180,105,229, 68, 9,
+100, 16, 1,158, 2,176, 27, 64,164, 36, 99, 7,238,125, 91,119,173,252, 45,196,245,250,243,168,144,128,142,219,102,234, 0,168,
+199, 63,208, 36, 8, 49, 19,221, 21, 13,233, 9, 5, 16,207,239,236, 46,225,111,244,151, 25, 35, 31,151,127,144,240, 62,123,213,
+189,156, 11,157,221, 91,245,240,225,195,248,197, 47,126,225,145, 74,216,181,107, 23, 83,171,213,123,247,236,217,211,225, 13,176,
+ 61,193,127, 87,230,101,252,117, 91, 6,214, 44,189, 19, 11,244,163, 58,220,170, 2, 0, 3,145,210,210,210,234,248,111,122,161,
+ 64, 4, 62, 2,240,145,102,193,159,134, 74,178,252,172, 32,112,155,164,251,255, 58, 7,155,158,182,118,149,191,138,143,133, 67,
+110,253,181,176, 64,103,197, 56,124,161, 8,195,163,195, 17,222,226, 60, 24,133,122,226,131,206, 78,180,228, 54, 49, 4,199, 54,
+222,207,147,249,155, 60,154,249,218,111,198,139,144, 75,178, 1,209, 10, 38, 90,193, 28, 22,192, 81, 3,106, 53,129,150,157,131,
+ 92,226, 58,221, 63, 31, 58, 16,124,248, 96, 64,208,128, 89, 42, 32, 22,157,172,223,240,163, 65, 64,216,242,242,176, 41, 67, 75,
+ 62,246, 91, 24,249,155,253,181, 93, 54,129, 24, 99, 40, 47, 47, 71, 65, 65, 1,110,187,237, 54,143, 84,194,166, 77,155,204,213,
+213,213,239,122,196,190,236, 32,127,179, 93,132,192, 17, 28,122,251, 33,116, 37,162, 75, 9,231,114, 79, 45,251,215,207,231, 2,
+248, 53, 22,190, 21, 37,136,142, 9, 18,144,214, 85,254, 1,125, 71,194, 97,110,253, 51,205,103,126,214,218, 28,120,107, 75, 58,
+190, 91, 49,207, 69,171,193,129,248, 59,119, 68,204,230, 54,112, 34,226,204, 38,143,103,110, 35,218, 80, 8,131, 90,111,200, 46,
+ 95,205,132, 53,111,127,171,243,170,126, 19,161,141,127, 28, 66,191,241,173,158,195,126,126, 39, 44, 41,171,235,156,124, 0,132,
+224, 46, 94,182,165,148,175,142,191, 75,183,236,240,149, 78, 41, 0, 99,245, 59,142, 51,134,195,135, 15, 99,214,172, 89,208,104,
+186,127,238,217,153, 51,103, 80, 85, 85, 85,147,154,154,186,175,187, 5,191, 51,252, 3, 52, 42,220, 26, 55,168,235,191, 7,210,
+246,172,201, 13,127, 48, 74,128,241, 90,248, 27, 11,131, 81,105,110,189,246, 99,219,145, 11, 88,152, 56, 10,140, 1,203, 63,219,
+141, 62, 65,218, 14,243, 46,185,120, 28,193,174, 47, 93, 32,175,194, 43,123, 6, 72, 23,247,192,186,239,237, 70, 65,110,236, 45,
+110,122, 8,254, 9, 75, 27,167, 66,156, 59,127, 6,102,179, 25,186,112, 29, 6, 13,138,133,223,216,251, 32, 68,220,128,154,237,
+ 43,192,172,141,131,150,227, 0,238, 61, 0,247,119,216, 7,160,148, 54,174,195,180,217,108, 56,126,252, 56,238,185,231, 30,143,
+ 60,236,150, 45, 91,172,162, 40,190,215,221, 14,111, 79,241,247,148,195,238,138,255,228,225,209, 46,203,239,204,188, 12,139, 93,
+196,239, 55, 28,192,134,212,179,152, 60, 44,186, 99, 74,230,176, 64,147,191,219, 77, 43, 79,206,244,248,131, 51, 10,251,225, 53,
+176,238,126,189,149,240,171,135,205,128,191,254,215, 0,225,112, 56, 35, 29,241, 79,188,138,184, 23,191, 67,252,170, 61, 24,246,
+220, 70,252,252,153, 55,112,241, 98, 14,132,232,177, 8,185,255, 95, 32,126,205,167,178,176,123,171, 62,156, 60,164,165, 2,180,
+138, 67, 55,175,248,134, 79,102,102, 38,134, 13, 27,134,254,253,251,119,251,243,214,212,212, 32, 53, 53,149,216,108,182, 79,187,
+214,200,123,151,255,181,119, 82,157,227, 63,101,120, 63,215, 65, 4,187,136,121,127,217,138, 15,182, 31, 5, 0, 76, 30, 22,211,
+ 33, 2,181,199,191,130,134,147,220, 24,124,108,103,143, 42,189,185, 12,150,109,203,225, 56,241,159,214,129, 64, 65, 3,255,233,
+207, 2, 0,242,242,206,227,231,171,119,227,120,133,179,127,243, 95,131, 10,243,255,244, 21, 36, 81, 4, 23,210, 15,234, 33,122,
+ 39,151, 65,166,252,114,183, 61, 0, 99,172,177,194, 37, 73,130, 36, 73,141,199,199,143, 31,199,188,121,243, 60,242,208, 59,119,
+238,132, 90,173,222,113,173,249,102,188,197,191, 59,205,181,142,240,159, 59,105, 24, 66,252, 93,155,113, 7,234, 71,171,181,106,
+ 1, 99, 6, 69,180,111,102,228,167, 65, 62,245, 31,119,151,109, 68, 35,110,236, 49,147,231,202, 49, 88,191,121, 12,114,145,235,
+225, 18, 85,244, 88,112,218,186,177,155, 15,191,254, 14,229, 14,215, 75, 72, 79, 87,249,225,207,255,168, 11, 36,170, 6, 76,110,
+209,161,177, 71, 13,127, 77,208, 58, 41, 64,131,157,217,178,213,105,120, 17, 6,131, 1, 22,139, 5, 9, 9,221, 59, 38, 66, 41,
+197,158, 61,123,176,118,237, 90,212,214,214,190,123, 45,130,227, 13,254,221,237,167,116,148,127,144, 86,141, 71,110, 29,219,230,
+ 61,199,235, 36,168,218,153, 30,239,200,254, 22,150, 31, 86,130,103,110,167, 68,127,213, 35,243,255, 25,133,253,216, 90, 88,183,
+ 63, 3,106,117, 63, 67, 85,136,106, 26,228, 59,125,213,220,230, 45,243, 74,235,156,122, 97,192,205, 45, 47, 5,169,180, 36,168,
+185, 19,204, 26, 42,186,193,217,106, 72, 66,212,240, 57,113,226, 4,238,185,231, 30,116,215,194, 19, 89,150,177,107,215, 46,124,
+246,217,103,176, 88, 44,142,226,226,226, 45, 6,131, 33, 60, 56, 56,248,230,234,234,234, 35,157,173,190,158,230, 79,105,183,250,
+132, 93,226,255,200,140, 49, 88,179,235, 68,227,130,156,150,152,192, 95,132,121,227, 98, 8, 35,102, 67,125,195, 29, 32,129,117,
+ 19,227,152,104,133,227,226, 62,148, 30,222,128, 16, 91,126, 91, 83, 39, 77, 50, 47,175,244,184,236,139, 86,216,118,189, 2,169,
+224,144,115, 67,205,171,193,192,156,124, 0, 90,219, 20, 29, 31, 18,174,193,129, 54, 18,161,140,111,152, 8,232, 98,108,193,223,
+108,111, 60, 41, 52,111,125, 26, 42,188,249, 75,176, 88, 44, 56,127,254, 60, 94,121,229,149,107,239,226, 36, 9, 63,252,240, 3,
+214,174, 93, 11,155,205,102,191,122,245,234,214,162,162,162,100, 74,105, 49,207,243, 70, 89,150, 75,174,165,245,236, 41,254,255,
+ 90,191, 3, 16, 98,187,189,245,119,197,223, 84,107,198,169,220, 43,184,243, 87, 75,177,249,240,121, 28,207, 43, 70,218,185, 66,
+156,184,100,132, 67,114,223,194,223, 20, 84, 9,106, 42,130, 35,227,159,112,100,252,179, 46, 98, 66, 56, 48, 42,131,128,181, 59,
+186, 69, 8, 94,136,252,205,145, 98,143, 10,191,189, 22,214,255, 62, 7,217,152,237,252,219,193, 49,240,159,245, 38,236, 71,254,
+ 5, 41,191, 41, 90, 44,149,158,107,252,255,233, 7,238,194,127, 94,217, 6,145,181, 86,225, 80,149,132,217,183,212,141,112,203,
+165,173,179, 39, 50, 78, 77,157,194,160, 45, 95, 64,243, 23,113,234,212, 41, 36, 36, 36,224, 90,114, 76, 58, 28, 14,124,255,253,
+247, 88,183,110, 29, 28, 14,135,173,168,168, 40,185,168,168,232,123,142,227,140,140, 49,163, 36, 73,198,170,170,170,210,107,105,
+145,123,146,255, 85, 41,226, 52,250,224,230,238,142,246,184,226,159,125,250, 52,134,198, 77,192, 15, 89,133,216,118,244, 34,174,
+ 86,214,118,232,158, 55, 5, 87,180, 50, 51,192,104,135, 38,203, 51,134,191,233,150, 29,250,196,147,194, 79,173,149,117, 38, 79,
+153,115,170, 33, 97,144, 30,126, 51, 94, 4,209, 4, 66, 24,156,232,164, 0,114,121, 30,236,103,191,135,102,212, 93, 24, 53, 50,
+ 14,219,127, 99,196, 67,255, 76, 69,177,189,105,237,198,208, 0, 59, 62, 91, 58, 3,177,177,117,169, 93,172, 39,190,108,249,211,
+162, 57,192, 97,115, 82,128, 6,123,179,229, 11,144,101, 25, 89, 89, 89,120,253,245,215,187,244,144,118,187, 29,223,126,251, 45,
+214,175, 95, 15, 89,150,109,133,133,133,155,141, 70,227, 14,198,152, 17,128,145,231,121, 99,121,121,185,241, 90, 43,179,167,249,
+ 91,198,207,187, 25,232, 62, 5,104,139,127,118,214,105,188,254,250,235, 24, 61,122, 52,254,186,120, 6, 14,157, 47, 66,114,198,
+121,108,205, 56,143,194, 10,215,202, 16,163,177, 34, 90,109,235, 98,143,132, 47,117,149,135,158,242,104,203,111,173,130,245,219,
+ 39, 65,171,154, 77,234,227, 4,104,110,126, 12,234, 9,191, 68,195, 8, 53, 63, 48,161,254,255,166,104,144, 53,245, 35,168, 98,
+ 38,128, 11,233,135, 91,111,153,137,203,137,211,177,231,192, 30, 20,149,150, 33, 38,162, 15,110,155, 62, 19, 28,199, 3,140,194,
+146,178, 26,210,149, 99, 45,186, 54,124, 25,179,244,152,197,165, 15,208,210,254,204,203,203, 67,104,104, 40, 70,143, 30,221,169,
+ 7,180, 88, 44, 72, 78, 78,198,134, 13, 27, 64, 41,181, 22, 20, 20,108, 46, 47, 47,223,205, 24, 51, 82, 74,141,130, 32, 24,203,
+202,202,140,232,194, 34,230,182,108,232,158,226, 79,253,195,251,121,194, 7,104,143, 63, 71, 8,244, 35,250, 65, 63,162, 31,254,
+180,232, 86, 28,201,189,138,228,140,243, 72, 62,124, 30, 5,101,213, 78,230, 79, 23, 32,130,177,223,235,150, 29,254, 11, 33,158,
+221,179, 75, 46, 60,234, 36,252, 92,200, 0,248,221,246, 50,248,136, 17, 78,229,184,128, 62,224,251,222, 8,185, 56,171, 89,207,
+ 97,130,233,171,135, 17,112,219, 31,160, 30, 58, 29, 60,207, 99,214,140, 89,173, 76,171,218, 29, 47, 66, 44, 56,220,170,174,193,
+216,159,156,122,156,230,161,183,150, 54,232,153, 51,103, 58, 21, 58,172,173,173,197,230,205,155,177,113,227, 70, 80, 74, 45, 6,
+131,225,155,178,178,178,253,140, 49, 35,207,243, 70,198,152,177,170,170,202,136,174,239, 68,216,102,232,176,167,248,171,180, 33,
+241,221, 37, 34, 93,229, 79, 8, 48,121, 88, 52, 38, 15,139,198,170, 95, 78,195,241, 60, 35, 54,238,203, 64,114,250,105,140, 15,
+236,148, 2, 72,140, 97, 7,227,232,107, 17,203, 50,142, 98,185,231,163, 94,252,160, 68,240,125,199, 64, 46, 57, 11,213,136,217,
+208,232,159,116,154,215,223, 28,154,164,223,194,178,229, 9,128, 54, 57,251,204, 81,139,218,255,174,132,122,232,116, 8, 81,163,
+193,135, 15, 1, 9,208, 65,174,184, 12,185,236, 2, 28,185, 7, 64,171, 91,175,165, 98,192,247,125,150, 29,118, 26,216,115,235,
+ 3,152, 76, 38, 20, 23, 23, 99,198,140, 25,237, 62, 80,117,117, 53,190,254,250,107, 36, 39, 39,131, 82,106,190,114,229,202,230,
+178,178,178,131,140, 49, 99,189,157, 95, 28, 26, 26,106,188,120,241,162,221, 35,246,164,194, 31,199,246,124,135,204,228,100, 12,
+161,212,188, 35,219,184,189,223, 56,106,191,101,120,224, 68,157, 63, 63, 26,196,133,233, 79,112,152, 49,178, 94,237,112,124, 21,
+252,236,177,178,158, 12,251, 18,149, 22,254,247,124,220,184, 32,167, 77,101,233,115, 3,212,147, 30,169,115,228, 91,250,102,185,
+251,225,200,221,223,193, 31, 37,121, 2,228, 86,234,237,214, 7,200,206,206,198,157,119,222,217,230,188,153,170,170, 42,124,249,
+229,151, 13,203, 11,107, 13, 6,195,230,170,170,170,180, 6, 27,159, 82,106,212,106,181,198,162,162, 34, 75,101,101,165,199, 42,
+ 84,225,223,154,255,243,151,152, 81,150,139,140,235, 31, 25, 64, 18, 6, 5,106,136, 74,230,136,172, 34, 96, 50, 7,162,170, 10,
+ 95,150, 82, 0,111,131,239, 88, 46, 84,205,132, 95, 1,142, 90, 56, 78,118,121,101,233, 41,153,147,238,212,185,136,106, 53, 42,
+ 64,115, 27, 84, 20, 69,156, 63,127, 30,207, 60,243,140,203,187,149,151,151, 99,253,250,245,216,177, 99, 7,100, 89,174,169,175,
+248,140, 6,161, 81,169, 84,197,140, 49, 99, 69, 69, 69,173,171, 92,239,158, 16, 32,133,191,107,254,119,191,239,203,121,172, 58,
+218,101,112,208, 76,249, 53,248, 62, 55,192,182,255,143, 96, 82,167, 28,252, 20,162, 17,239,138,116, 51,160,215,202, 4, 98,140,
+225,226,197,139, 24, 49, 98, 4,250,245,115,246,245, 74, 74, 74,240,197, 23, 95, 96,247,238,221,144, 36,169,218, 96, 48,108,169,
+174,174, 62,202, 24, 51, 54,216,201, 0,140, 37, 37, 37, 61, 90,235, 10,127,239,242,239, 41, 8,195,102,194,191,223, 68,136,103,
+190,131,120,230, 91, 48,179, 91,203,205, 0, 32,153, 3,217, 18,218,183,127, 74, 91,107, 25, 4,198, 24,107,217, 5, 95,184,112,
+ 1, 79, 61,213, 20, 9, 43, 42, 42,194,231,159,127,142, 3, 7, 14, 64,146, 36, 83,126,126,254,150,218,218,218,147, 13, 81, 17,
+158,231,141,146, 36, 25, 43, 43, 43,123, 60, 91,152, 87,248,203,220, 81,240,244, 53,215,132,136,205,231,249,247, 98,112,218, 48,
+104,110, 90, 12,205,132, 69,117,249,129, 28, 22,124,182,230, 67, 27, 45, 57,179,121, 76, 31,122,118,100,140,176,179,239,242, 35,
+ 29,158, 77, 32, 16, 66,242,171,171,171, 71,134,133,133,129, 82,138,210,210, 82,136,162,136, 41, 83,166,192, 96, 48,224,223,255,
+254, 55,210,210,210, 32,138, 98,229,229,203,151,183,154,205,230,204, 6,231, 16,128, 81,150,101, 99, 85, 85, 85,153,183, 42,196,
+ 27,252,197,205, 43,142, 2, 56,218, 91,249,255,111,104, 2, 15,190, 79,221, 96,215, 57,115,152,188,255,136,120,188,160,160, 96,
+ 91, 85, 85, 85,167, 54,241, 16,236,118,123,106, 73, 73,201,204,254,253,251, 11,148, 82, 92,188,120, 17, 19, 38, 76,192,203, 47,
+191,140, 35, 71,142,192,110,183, 87, 24, 12,134,111,107,107,107,179, 8, 33, 37,168, 91,204, 97,228,121,222, 88, 82, 82, 98,244,
+118, 61, 40,252,189, 15,147,201, 36,100,100,100,120,243,247,121, 66, 8,149,101,185,243,185, 65, 25, 99, 25,121,121,121,246, 33,
+ 67,134, 8,118,187, 29,121,121,121,200,207,207,135,205,102,107,168,248,179,205, 91,155,102,131, 88,212, 23, 42, 95,225,239,117,
+ 24,139,139,139, 79,173, 90,181,138,183,219,237,209,140, 49, 53, 0, 86,159, 97,143, 53,251,160,254, 60,107, 10,203, 59, 95,115,
+119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212,167, 71,236,212, 8, 13, 1,128,105,211,166, 61, 79, 41,125, 11,128,236,
+112, 56,106,138,138,138,182,213,214,214,158,227, 56,174,193,198, 44, 97,140, 21,215, 79, 91,144,224, 99, 80,248,251,134, 81,162,
+211,233,150, 3,232, 91,175,156, 50,234, 18,214, 74,132, 16,153, 49, 38, 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84,
+159,228, 86,110,184, 70, 8,145, 41,165, 82,139, 99,185, 33, 35, 52,165, 84,146,101, 89, 98,140, 89,204,102,243,149, 78, 43, 64,
+ 61, 84,225,225,225, 81,140,177, 48,142,227,180, 0,136, 44,203,118,142,227,202,195,195,195, 75, 60, 53, 8,212,141, 80,248,123,
+ 57, 88, 25, 24, 24, 24,205,113,156,154, 16,194, 84, 42, 21, 68, 81,108,108,165, 27, 90,241,230,199,132, 16,218,208,226, 59, 28,
+ 14,167, 30,128, 16,194,154,125, 26,202,194, 98,177, 56,221,131,227, 56, 70, 8, 97,149,149,149,172, 94,233,196,174, 42,128, 2,
+ 5,215,172, 4, 93,181, 4,189, 69,248,255, 3,212, 21,184,121, 66,226, 69,162, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+};
+
diff --git a/source/blender/src/radialcontrol.c b/source/blender/src/radialcontrol.c
new file mode 100644
index 00000000000..404aac225c6
--- /dev/null
+++ b/source/blender/src/radialcontrol.c
@@ -0,0 +1,267 @@
+/*
+ * $Id: multires.c 13015 2007-12-27 07:27:03Z nicholasbishop $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Implements the multiresolution modeling tools.
+ *
+ * multires.h
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+#include "BIF_mywindow.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_radialcontrol.h"
+
+#include "BKE_global.h"
+#include "BLI_arithb.h"
+
+#include "mydevice.h"
+#include "transform.h"
+
+#include "math.h"
+
+/* Prints the value being edited in the view header */
+static void radialcontrol_header(const RadialControl *rc)
+{
+ if(rc) {
+ char str[512];
+ const char *name= "";
+
+ if(rc->mode == RADIALCONTROL_SIZE)
+ name= "Size";
+ else if(rc->mode == RADIALCONTROL_STRENGTH)
+ name= "Strength";
+ else if(rc->mode == RADIALCONTROL_ROTATION)
+ name= "Angle";
+
+ sprintf(str, "%s: %d", name, (int)(rc->new_value));
+ headerprint(str);
+ }
+}
+
+/* Creates, initializes, and returns the control */
+RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
+ const int original_value, const int max_value,
+ const unsigned int tex)
+{
+ RadialControl *rc= MEM_callocN(sizeof(RadialControl), "radial control");
+ short mouse[2];
+
+ getmouseco_areawin(mouse);
+ rc->origloc[0]= mouse[0];
+ rc->origloc[1]= mouse[1];
+
+ if(mode == RADIALCONTROL_SIZE)
+ rc->origloc[0]-= original_value;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ rc->origloc[0]-= 200 - 2*original_value;
+ else if(mode == RADIALCONTROL_ROTATION) {
+ rc->origloc[0]-= 200 * cos(original_value * M_PI / 180.0);
+ rc->origloc[1]-= 200 * sin(original_value * M_PI / 180.0);
+ }
+
+ rc->callback = callback;
+ rc->original_value = original_value;
+ rc->max_value = max_value;
+
+ rc->tex = tex;
+
+ /* NumInput is used for keyboard input */
+ rc->num = MEM_callocN(sizeof(NumInput), "radialcontrol numinput");
+ rc->num->idx_max= 0;
+
+ rc->mode= mode;
+ radialcontrol_header(rc);
+
+ allqueue(REDRAWVIEW3D, 0);
+
+ return rc;
+}
+
+
+static void radialcontrol_end(RadialControl *rc)
+{
+ if(rc) {
+ rc->callback(rc->mode, rc->new_value);
+ BIF_undo_push("Brush property set");
+
+ /* Free everything */
+ glDeleteTextures(1, (GLuint*)(&rc->tex));
+ MEM_freeN(rc->num);
+ MEM_freeN(rc);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWHEADERS, 0);
+ }
+}
+
+void radialcontrol_do_events(RadialControl *rc, unsigned short event)
+{
+ short mouse[2];
+ short tmp[2];
+ float dist;
+ char valset= 0;
+
+ if(!rc)
+ return;
+
+ handleNumInput(rc->num, event);
+
+ if(hasNumInput(rc->num)) {
+ float val;
+ applyNumInput(rc->num, &val);
+ rc->new_value = val;
+ valset= 1;
+ allqueue(REDRAWVIEW3D, 0);
+ }
+
+ switch(event) {
+ case MOUSEX:
+ case MOUSEY:
+ if(!hasNumInput(rc->num)) {
+ char ctrl= G.qual & LR_CTRLKEY;
+ getmouseco_areawin(mouse);
+ tmp[0]= rc->origloc[0]-mouse[0];
+ tmp[1]= rc->origloc[1]-mouse[1];
+ dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
+ if(rc->mode == RADIALCONTROL_SIZE)
+ rc->new_value = dist;
+ else if(rc->mode == RADIALCONTROL_STRENGTH) {
+ float fin= (200.0f - dist) * 0.5f;
+ rc->new_value= fin>=0 ? fin : 0;
+ } else if(rc->mode == RADIALCONTROL_ROTATION)
+ rc->new_value= ((int)(atan2(tmp[1], tmp[0]) * (180.0 / M_PI)) + 180);
+
+ if(ctrl)
+ rc->new_value= (rc->new_value + 5) / 10*10;
+
+ valset= 1;
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ break;
+ case ESCKEY:
+ case RIGHTMOUSE:
+ rc->new_value = rc->original_value;
+ case LEFTMOUSE:
+ while(get_mbut()==L_MOUSE);
+ case RETKEY:
+ case PADENTER:
+ radialcontrol_end(rc);
+ return;
+ default:
+ break;
+ };
+
+ if(valset) {
+ if(rc->new_value > rc->max_value)
+ rc->new_value = rc->max_value;
+ }
+
+ radialcontrol_header(rc);
+}
+
+static void rot_line(const short o[2], const float ang)
+{
+ sdrawXORline(o[0], o[1], o[0] + 200*cos(ang), o[1] + 200*sin(ang));
+}
+
+void radialcontrol_draw(RadialControl *rc)
+{
+ short r1=200, r2=200, r3=200;
+ float angle = 0;
+
+ if(rc && rc->mode) {
+ if(rc->mode == RADIALCONTROL_SIZE) {
+ r1= rc->new_value;
+ r2= rc->original_value;
+ r3= r1;
+ } else if(rc->mode == RADIALCONTROL_STRENGTH) {
+ r1= 200 - rc->new_value * 2;
+ r2= 200;
+ r3= 200;
+ } else if(rc->mode == RADIALCONTROL_ROTATION) {
+ r1= r2= 200;
+ r3= 200;
+ angle = rc->new_value;
+ }
+
+ /* Draw brush with texture */
+ glPushMatrix();
+ glTranslatef(rc->origloc[0], rc->origloc[1], 0);
+ glRotatef(angle, 0, 0, 1);
+
+ if(rc->tex) {
+ const float str = rc->mode == RADIALCONTROL_STRENGTH ? (rc->new_value / 200.0 + 0.5) : 1;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glBindTexture(GL_TEXTURE_2D, rc->tex);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glEnable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ glColor4f(0,0,0, str);
+ glTexCoord2f(0,0);
+ glVertex2f(-r3, -r3);
+ glTexCoord2f(1,0);
+ glVertex2f(r3, -r3);
+ glTexCoord2f(1,1);
+ glVertex2f(r3, r3);
+ glTexCoord2f(0,1);
+ glVertex2f(-r3, r3);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ glPopMatrix();
+
+ if(r1 != r2)
+ fdrawXORcirc(rc->origloc[0], rc->origloc[1], r1);
+ fdrawXORcirc(rc->origloc[0], rc->origloc[1], r2);
+
+ if(rc->mode == RADIALCONTROL_ROTATION) {
+ float ang1= rc->original_value * (M_PI/180.0f);
+ float ang2= rc->new_value * (M_PI/180.0f);
+
+ if(rc->new_value > 359)
+ ang2 = 0;
+
+ rot_line(rc->origloc, ang1);
+ if(ang1 != ang2)
+ rot_line(rc->origloc, ang2);
+ }
+ }
+}
diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c
new file mode 100644
index 00000000000..85fb5815c3e
--- /dev/null
+++ b/source/blender/src/reeb.c
@@ -0,0 +1,1923 @@
+/**
+ * $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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Martin Poirier
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <string.h> // for memcpy
+#include <stdio.h>
+#include <stdlib.h> // for qsort
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+
+#include "BDR_editobject.h"
+
+#include "BIF_editmesh.h"
+#include "BIF_editarmature.h"
+#include "BIF_interface.h"
+#include "BIF_toolbox.h"
+#include "BIF_graphics.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
+
+#include "blendef.h"
+
+#include "ONL_opennl.h"
+
+#include "reeb.h"
+
+/*
+ * Skeleton generation algorithm based on:
+ * "Harmonic Skeleton for Realistic Character Animation"
+ * Gregoire Aujay, Franck Hetroy, Francis Lazarus and Christine Depraz
+ * SIGGRAPH 2007
+ *
+ * Reeb graph generation algorithm based on:
+ * "Robust On-line Computation of Reeb Graphs: Simplicity and Speed"
+ * Valerio Pascucci, Giorgio Scorzelli, Peer-Timo Bremer and Ajith Mascarenhas
+ * SIGGRAPH 2007
+ *
+ * */
+
+int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1);
+int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1);
+EditEdge * NextEdgeForVert(EditMesh *em, EditVert *v);
+
+/***************************************** BUCKET UTILS **********************************************/
+
+void addVertToBucket(EmbedBucket *b, float co[3])
+{
+ b->nv++;
+ VecLerpf(b->p, b->p, co, 1.0f / b->nv);
+}
+
+void removeVertFromBucket(EmbedBucket *b, float co[3])
+{
+ VecMulf(b->p, (float)b->nv);
+ VecSubf(b->p, b->p, co);
+ b->nv--;
+ VecMulf(b->p, 1.0f / (float)b->nv);
+}
+
+void mergeBuckets(EmbedBucket *bDst, EmbedBucket *bSrc)
+{
+ if (bDst->nv > 0 && bSrc->nv > 0)
+ {
+ bDst->nv += bSrc->nv;
+ VecLerpf(bDst->p, bDst->p, bSrc->p, (float)bSrc->nv / (float)(bDst->nv));
+ }
+ else if (bSrc->nv > 0)
+ {
+ bDst->nv = bSrc->nv;
+ VECCOPY(bDst->p, bSrc->p);
+ }
+}
+
+void mergeArcBuckets(ReebArc *aDst, ReebArc *aSrc, float start, float end)
+{
+ if (aDst->bcount > 0 && aSrc->bcount > 0)
+ {
+ int indexDst = 0, indexSrc = 0;
+
+ start = MAX3(start, aDst->buckets[0].val, aSrc->buckets[0].val);
+
+ while(indexDst < aDst->bcount && aDst->buckets[indexDst].val < start)
+ {
+ indexDst++;
+ }
+
+ while(indexSrc < aSrc->bcount && aSrc->buckets[indexSrc].val < start)
+ {
+ indexSrc++;
+ }
+
+ for( ; indexDst < aDst->bcount &&
+ indexSrc < aSrc->bcount &&
+ aDst->buckets[indexDst].val <= end &&
+ aSrc->buckets[indexSrc].val <= end
+
+ ; indexDst++, indexSrc++)
+ {
+ mergeBuckets(aDst->buckets + indexDst, aSrc->buckets + indexSrc);
+ }
+ }
+}
+
+void allocArcBuckets(ReebArc *arc)
+{
+ int i;
+ float start = ceil(arc->v1->weight);
+ arc->bcount = (int)(floor(arc->v2->weight) - start) + 1;
+
+ if (arc->bcount > 0)
+ {
+ arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "embed bucket");
+
+ for(i = 0; i < arc->bcount; i++)
+ {
+ arc->buckets[i].val = start + i;
+ }
+ }
+ else
+ {
+ arc->buckets = NULL;
+ }
+
+}
+
+void resizeArcBuckets(ReebArc *arc)
+{
+ EmbedBucket *oldBuckets = arc->buckets;
+ int oldBCount = arc->bcount;
+
+ allocArcBuckets(arc);
+
+ if (oldBCount != 0 && arc->bcount != 0)
+ {
+ int oldStart = (int)oldBuckets[0].val;
+ int oldEnd = (int)oldBuckets[oldBCount - 1].val;
+ int newStart = (int)arc->buckets[0].val;
+ int newEnd = (int)arc->buckets[arc->bcount - 1].val;
+ int oldOffset = 0;
+ int newOffset = 0;
+ int len;
+
+ if (oldStart < newStart)
+ {
+ oldOffset = newStart - oldStart;
+ }
+ else
+ {
+ newOffset = oldStart - newStart;
+ }
+
+ len = MIN2(oldEnd - (oldStart + oldOffset) + 1, newEnd - (newStart - newOffset) + 1);
+
+ memcpy(arc->buckets + newOffset, oldBuckets + oldOffset, len * sizeof(EmbedBucket));
+ }
+
+ if (oldBuckets != NULL)
+ {
+ MEM_freeN(oldBuckets);
+ }
+}
+/***************************************** UTILS **********************************************/
+
+ReebEdge * copyEdge(ReebEdge *edge)
+{
+ ReebEdge *newEdge = NULL;
+
+ newEdge = MEM_callocN(sizeof(ReebEdge), "reeb edge");
+ memcpy(newEdge, edge, sizeof(ReebEdge));
+
+ newEdge->next = NULL;
+ newEdge->prev = NULL;
+
+ return newEdge;
+}
+
+void printArc(ReebArc *arc)
+{
+ ReebEdge *edge;
+ printf("arc: (%i)%f -> (%i)%f\n", arc->v1->index, arc->v1->weight, arc->v2->index, arc->v2->weight);
+
+ for(edge = arc->edges.first; edge ; edge = edge->next)
+ {
+ printf("\tedge (%i, %i)\n", edge->v1->index, edge->v2->index);
+ }
+}
+
+void freeArc(ReebArc *arc)
+{
+ BLI_freelistN(&arc->edges);
+
+ if (arc->buckets)
+ MEM_freeN(arc->buckets);
+
+ MEM_freeN(arc);
+}
+
+void freeGraph(ReebGraph *rg)
+{
+ ReebArc *arc;
+ ReebNode *node;
+
+ // free nodes
+ for( node = rg->nodes.first; node; node = node->next )
+ {
+ // Free adjacency lists
+ if (node->arcs != NULL)
+ {
+ MEM_freeN(node->arcs);
+ }
+ }
+ BLI_freelistN(&rg->nodes);
+
+ // free arcs
+ arc = rg->arcs.first;
+ while( arc )
+ {
+ ReebArc *next = arc->next;
+ freeArc(arc);
+ arc = next;
+ }
+
+ // free edge map
+ BLI_edgehash_free(rg->emap, NULL);
+
+ MEM_freeN(rg);
+}
+
+void repositionNodes(ReebGraph *rg)
+{
+ ReebArc *arc = NULL;
+ ReebNode *node = NULL;
+
+ // Reset node positions
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ node->p[0] = node->p[1] = node->p[2] = 0;
+ }
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->bcount > 0)
+ {
+ float p[3];
+
+ VECCOPY(p, arc->buckets[0].p);
+ VecMulf(p, 1.0f / arc->v1->degree);
+ VecAddf(arc->v1->p, arc->v1->p, p);
+
+ VECCOPY(p, arc->buckets[arc->bcount - 1].p);
+ VecMulf(p, 1.0f / arc->v2->degree);
+ VecAddf(arc->v2->p, arc->v2->p, p);
+ }
+ }
+}
+
+void verifyNodeDegree(ReebGraph *rg)
+{
+ ReebNode *node = NULL;
+ ReebArc *arc = NULL;
+
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ int count = 0;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->v1 == node || arc->v2 == node)
+ {
+ count++;
+ }
+ }
+ if (count != node->degree)
+ {
+ printf("degree error in node %i: expected %i got %i\n", node->index, count, node->degree);
+ }
+ }
+}
+
+void verifyBuckets(ReebGraph *rg)
+{
+#ifdef DEBUG_REEB
+ ReebArc *arc = NULL;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->bcount > 0)
+ {
+ int i;
+ for(i = 0; i < arc->bcount; i++)
+ {
+ if (arc->buckets[i].nv == 0)
+ {
+ printArc(arc);
+ printf("count error in bucket %i/%i\n", i+1, arc->bcount);
+ }
+ }
+
+ if (ceil(arc->v1->weight) < arc->buckets[0].val)
+ {
+ printArc(arc);
+ printf("alloc error in first bucket: %f should be %f \n", arc->buckets[0].val, ceil(arc->v1->weight));
+ }
+ if (floor(arc->v2->weight) < arc->buckets[arc->bcount - 1].val)
+ {
+ printArc(arc);
+ printf("alloc error in last bucket: %f should be %f \n", arc->buckets[arc->bcount - 1].val, floor(arc->v2->weight));
+ }
+ }
+ }
+#endif
+}
+
+/************************************** ADJACENCY LIST *************************************************/
+
+void addArcToNodeAdjacencyList(ReebNode *node, ReebArc *arc)
+{
+ ReebArc **arclist;
+
+ for(arclist = node->arcs; *arclist; arclist++)
+ { }
+
+ *arclist = arc;
+}
+
+void buildAdjacencyList(ReebGraph *rg)
+{
+ ReebNode *node = NULL;
+ ReebArc *arc = NULL;
+
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ if (node->arcs != NULL)
+ {
+ MEM_freeN(node->arcs);
+ }
+
+ node->arcs = MEM_callocN((node->degree + 1) * sizeof(ReebArc*), "adjacency list");
+ }
+
+ for(arc = rg->arcs.first; arc; arc= arc->next)
+ {
+ addArcToNodeAdjacencyList(arc->v1, arc);
+ addArcToNodeAdjacencyList(arc->v2, arc);
+ }
+}
+
+int hasAdjacencyList(ReebGraph *rg)
+{
+ ReebNode *node;
+
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ if (node->arcs == NULL)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int countConnectedArcs(ReebGraph *rg, ReebNode *node)
+{
+ int count = 0;
+
+ /* use adjacency list if present */
+ if (node->arcs)
+ {
+ ReebArc **arcs;
+
+ for(arcs = node->arcs; *arcs; arcs++)
+ {
+ count++;
+ }
+ }
+ else
+ {
+ ReebArc *arc;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->v1 == node || arc->v2 == node)
+ {
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
+/****************************************** SMOOTHING **************************************************/
+
+void postprocessGraph(ReebGraph *rg, char mode)
+{
+ ReebArc *arc;
+ float fac1 = 0, fac2 = 1, fac3 = 0;
+
+ switch(mode)
+ {
+ case SKGEN_AVERAGE:
+ fac1 = fac2 = fac3 = 1.0f / 3.0f;
+ break;
+ case SKGEN_SMOOTH:
+ fac1 = fac3 = 0.25f;
+ fac2 = 0.5f;
+ break;
+ case SKGEN_SHARPEN:
+ fac1 = fac2 = -0.25f;
+ fac2 = 1.5f;
+ break;
+ default:
+ error("Unknown post processing mode");
+ return;
+ }
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ EmbedBucket *buckets = arc->buckets;
+ int bcount = arc->bcount;
+ int index;
+
+ for(index = 1; index < bcount - 1; index++)
+ {
+ VecLerpf(buckets[index].p, buckets[index].p, buckets[index - 1].p, fac1 / (fac1 + fac2));
+ VecLerpf(buckets[index].p, buckets[index].p, buckets[index + 1].p, fac3 / (fac1 + fac2 + fac3));
+ }
+ }
+}
+
+/********************************************SORTING****************************************************/
+
+int compareNodesWeight(void *vnode1, void *vnode2)
+{
+ ReebNode *node1 = (ReebNode*)vnode1;
+ ReebNode *node2 = (ReebNode*)vnode2;
+
+ if (node1->weight < node2->weight)
+ {
+ return -1;
+ }
+ if (node1->weight > node2->weight)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void sortNodes(ReebGraph *rg)
+{
+ BLI_sortlist(&rg->nodes, compareNodesWeight);
+}
+
+int compareArcsWeight(void *varc1, void *varc2)
+{
+ ReebArc *arc1 = (ReebArc*)varc1;
+ ReebArc *arc2 = (ReebArc*)varc2;
+
+ if (arc1->v1->weight < arc2->v1->weight)
+ {
+ return -1;
+ }
+ if (arc1->v1->weight > arc2->v1->weight)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void sortArcs(ReebGraph *rg)
+{
+ BLI_sortlist(&rg->arcs, compareArcsWeight);
+}
+
+/****************************************** FILTERING **************************************************/
+
+int compareArcs(void *varc1, void *varc2)
+{
+ ReebArc *arc1 = (ReebArc*)varc1;
+ ReebArc *arc2 = (ReebArc*)varc2;
+ float len1 = arc1->v2->weight - arc1->v1->weight;
+ float len2 = arc2->v2->weight - arc2->v1->weight;
+
+ if (len1 < len2)
+ {
+ return -1;
+ }
+ if (len1 > len2)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc * srcArc, int merging)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+
+ /* first pass, merge buckets for arcs that spawned the two nodes into the source arc*/
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->v1 == srcArc->v1 && arc->v2 == srcArc->v2 && arc != srcArc)
+ {
+ mergeArcBuckets(srcArc, arc, srcArc->v1->weight, srcArc->v2->weight);
+ }
+ }
+
+ /* second pass, replace removedNode by newNode, remove arcs that are collapsed in a loop */
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+
+ if (arc->v1 == removedNode || arc->v2 == removedNode)
+ {
+ if (arc->v1 == removedNode)
+ {
+ arc->v1 = newNode;
+ }
+ else
+ {
+ arc->v2 = newNode;
+ }
+
+ // Remove looped arcs
+ if (arc->v1 == arc->v2)
+ {
+ // v1 or v2 was already newNode, since we're removing an arc, decrement degree
+ newNode->degree--;
+
+ // If it's safeArc, it'll be removed later, so keep it for now
+ if (arc != srcArc)
+ {
+ BLI_remlink(&rg->arcs, arc);
+ freeArc(arc);
+ }
+ }
+ // Remove flipped arcs
+ else if (arc->v1->weight > arc->v2->weight)
+ {
+ // Decrement degree from the other node
+ OTHER_NODE(arc, newNode)->degree--;
+
+ BLI_remlink(&rg->arcs, arc);
+ freeArc(arc);
+ }
+ else
+ {
+ newNode->degree++; // incrementing degree since we're adding an arc
+
+ if (merging)
+ {
+ // resize bucket list
+ resizeArcBuckets(arc);
+ mergeArcBuckets(arc, srcArc, arc->v1->weight, arc->v2->weight);
+ }
+ }
+ }
+
+ arc = nextArc;
+ }
+}
+
+void filterNullReebGraph(ReebGraph *rg)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+ // Only collapse arcs too short to have any embed bucket
+ if (arc->bcount == 0)
+ {
+ ReebNode *newNode = arc->v1;
+ ReebNode *removedNode = arc->v2;
+ float blend;
+
+ blend = (float)newNode->degree / (float)(newNode->degree + removedNode->degree); // blending factors
+
+ //newNode->weight = FloatLerpf(newNode->weight, removedNode->weight, blend);
+ VecLerpf(newNode->p, newNode->p, removedNode->p, blend);
+
+ filterArc(rg, newNode, removedNode, arc, 0);
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ freeArc(arc);
+
+ BLI_freelinkN(&rg->nodes, removedNode);
+ }
+
+ arc = nextArc;
+ }
+}
+
+int filterInternalReebGraph(ReebGraph *rg, float threshold)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+ int value = 0;
+
+ BLI_sortlist(&rg->arcs, compareArcs);
+
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+
+ // Only collapse non-terminal arcs that are shorter than threshold
+ if ((arc->v1->degree > 1 && arc->v2->degree > 1 && arc->v2->weight - arc->v1->weight < threshold))
+ {
+ ReebNode *newNode = NULL;
+ ReebNode *removedNode = NULL;
+
+ /* Keep the node with the highestn number of connected arcs */
+ if (arc->v1->degree >= arc->v2->degree)
+ {
+ newNode = arc->v1;
+ removedNode = arc->v2;
+ }
+ else
+ {
+ newNode = arc->v2;
+ removedNode = arc->v1;
+ }
+
+ filterArc(rg, newNode, removedNode, arc, 1);
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ freeArc(arc);
+
+ BLI_freelinkN(&rg->nodes, removedNode);
+ value = 1;
+ }
+
+ arc = nextArc;
+ }
+
+ return value;
+}
+
+int filterExternalReebGraph(ReebGraph *rg, float threshold)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+ int value = 0;
+
+ BLI_sortlist(&rg->arcs, compareArcs);
+
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+
+ // Only collapse terminal arcs that are shorter than threshold
+ if ((arc->v1->degree == 1 || arc->v2->degree == 1) && arc->v2->weight - arc->v1->weight < threshold)
+ {
+ ReebNode *terminalNode = NULL;
+ ReebNode *middleNode = NULL;
+ ReebNode *newNode = NULL;
+ ReebNode *removedNode = NULL;
+ int merging = 0;
+
+ // Assign terminal and middle nodes
+ if (arc->v1->degree == 1)
+ {
+ terminalNode = arc->v1;
+ middleNode = arc->v2;
+ }
+ else
+ {
+ terminalNode = arc->v2;
+ middleNode = arc->v1;
+ }
+
+ // If middle node is a normal node, merge to terminal node
+ if (middleNode->degree == 2)
+ {
+ merging = 1;
+ newNode = terminalNode;
+ removedNode = middleNode;
+ }
+ // Otherwise, just plain remove of the arc
+ else
+ {
+ merging = 0;
+ newNode = middleNode;
+ removedNode = terminalNode;
+ }
+
+ // Merging arc
+ if (merging)
+ {
+ filterArc(rg, newNode, removedNode, arc, 1);
+ }
+ else
+ {
+ // removing arc, so we need to decrease the degree of the remaining node
+ newNode->degree--;
+ }
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ freeArc(arc);
+
+ BLI_freelinkN(&rg->nodes, removedNode);
+ value = 1;
+ }
+
+ arc = nextArc;
+ }
+
+ return value;
+}
+
+/************************************** WEIGHT SPREADING ***********************************************/
+
+int compareVerts( const void* a, const void* b )
+{
+ EditVert *va = *(EditVert**)a;
+ EditVert *vb = *(EditVert**)b;
+ int value = 0;
+
+ if (va->tmp.fp < vb->tmp.fp)
+ {
+ value = -1;
+ }
+ else if (va->tmp.fp > vb->tmp.fp)
+ {
+ value = 1;
+ }
+
+ return value;
+}
+
+void spreadWeight(EditMesh *em)
+{
+ EditVert **verts, *eve;
+ float lastWeight = 0.0f;
+ int totvert = BLI_countlist(&em->verts);
+ int i;
+ int work_needed = 1;
+
+ verts = MEM_callocN(sizeof(EditVert*) * totvert, "verts array");
+
+ for(eve = em->verts.first, i = 0; eve; eve = eve->next, i++)
+ {
+ verts[i] = eve;
+ }
+
+ while(work_needed == 1)
+ {
+ work_needed = 0;
+ qsort(verts, totvert, sizeof(EditVert*), compareVerts);
+
+ for(i = 0; i < totvert; i++)
+ {
+ eve = verts[i];
+
+ if (i == 0 || (eve->tmp.fp - lastWeight) > FLT_EPSILON)
+ {
+ lastWeight = eve->tmp.fp;
+ }
+ else
+ {
+ work_needed = 1;
+ eve->tmp.fp = lastWeight + FLT_EPSILON * 2;
+ lastWeight = eve->tmp.fp;
+ }
+ }
+ }
+
+ MEM_freeN(verts);
+}
+/*********************************** GRAPH AS TREE FUNCTIONS *******************************************/
+
+int subtreeDepth(ReebNode *node, ReebArc *rootArc)
+{
+ int depth = 0;
+
+ /* Base case, no arcs leading away */
+ if (node->arcs == NULL || *(node->arcs) == NULL)
+ {
+ return 0;
+ }
+ else
+ {
+ ReebArc ** pArc;
+
+ for(pArc = node->arcs; *pArc; pArc++)
+ {
+ ReebArc *arc = *pArc;
+
+ /* only arcs that go down the tree */
+ if (arc != rootArc)
+ {
+ ReebNode *newNode = OTHER_NODE(arc, node);
+ depth = MAX2(depth, subtreeDepth(newNode, arc));
+ }
+ }
+ }
+
+ return depth + 1;
+}
+
+/*************************************** CYCLE DETECTION ***********************************************/
+
+int detectCycle(ReebNode *node, ReebArc *srcArc)
+{
+ int value = 0;
+
+ if (node->flags == 0)
+ {
+ ReebArc ** pArc;
+
+ /* mark node as visited */
+ node->flags = 1;
+
+ for(pArc = node->arcs; *pArc && value == 0; pArc++)
+ {
+ ReebArc *arc = *pArc;
+
+ /* don't go back on the source arc */
+ if (arc != srcArc)
+ {
+ value = detectCycle(OTHER_NODE(arc, node), arc);
+ }
+ }
+ }
+ else
+ {
+ value = 1;
+ }
+
+ return value;
+}
+
+int isGraphCyclic(ReebGraph *rg)
+{
+ ReebNode *node;
+ int value = 0;
+
+ /* NEED TO CHECK IF ADJACENCY LIST EXIST */
+
+ /* Mark all nodes as not visited */
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ node->flags = 0;
+ }
+
+ /* detectCycles in subgraphs */
+ for(node = rg->nodes.first; node && value == 0; node = node->next)
+ {
+ /* only for nodes in subgraphs that haven't been visited yet */
+ if (node->flags == 0)
+ {
+ value = value || detectCycle(node, NULL);
+ }
+ }
+
+ return value;
+}
+
+/******************************************** EXPORT ***************************************************/
+
+void exportNode(FILE *f, char *text, ReebNode *node)
+{
+ fprintf(f, "%s i:%i w:%f d:%i %f %f %f\n", text, node->index, node->weight, node->degree, node->p[0], node->p[1], node->p[2]);
+}
+
+void exportGraph(ReebGraph *rg, int count)
+{
+#ifdef DEBUG_REEB
+ ReebArc *arc;
+ char filename[128];
+ FILE *f;
+
+ if (count == -1)
+ {
+ sprintf(filename, "test.txt");
+ }
+ else
+ {
+ sprintf(filename, "test%05i.txt", count);
+ }
+ f = fopen(filename, "w");
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ int i;
+
+ exportNode(f, "v1", arc->v1);
+
+ for(i = 0; i < arc->bcount; i++)
+ {
+ fprintf(f, "b nv:%i %f %f %f\n", arc->buckets[i].nv, arc->buckets[i].p[0], arc->buckets[i].p[1], arc->buckets[i].p[2]);
+ }
+
+ exportNode(f, "v2", arc->v2);
+ }
+
+ fclose(f);
+#endif
+}
+
+/***************************************** MAIN ALGORITHM **********************************************/
+
+ReebArc * findConnectedArc(ReebGraph *rg, ReebArc *arc, ReebNode *v)
+{
+ ReebArc *nextArc = arc->next;
+
+ for(nextArc = rg->arcs.first; nextArc; nextArc = nextArc->next)
+ {
+ if (arc != nextArc && (nextArc->v1 == v || nextArc->v2 == v))
+ {
+ break;
+ }
+ }
+
+ return nextArc;
+}
+
+void removeNormalNodes(ReebGraph *rg)
+{
+ ReebArc *arc;
+
+ // Merge degree 2 nodes
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ while (arc->v1->degree == 2 || arc->v2->degree == 2)
+ {
+ // merge at v1
+ if (arc->v1->degree == 2)
+ {
+ ReebArc *nextArc = findConnectedArc(rg, arc, arc->v1);
+
+ // Merge arc only if needed
+ if (arc->v1 == nextArc->v2)
+ {
+ mergeConnectedArcs(rg, arc, nextArc);
+ }
+ // Otherwise, mark down vert
+ else
+ {
+ arc->v1->degree = 3;
+ }
+ }
+
+ // merge at v2
+ if (arc->v2->degree == 2)
+ {
+ ReebArc *nextArc = findConnectedArc(rg, arc, arc->v2);
+
+ // Merge arc only if needed
+ if (arc->v2 == nextArc->v1)
+ {
+ mergeConnectedArcs(rg, arc, nextArc);
+ }
+ // Otherwise, mark down vert
+ else
+ {
+ arc->v2->degree = 3;
+ }
+ }
+ }
+ }
+
+}
+
+int edgeEquals(ReebEdge *e1, ReebEdge *e2)
+{
+ return (e1->v1 == e2->v1 && e1->v2 == e2->v2);
+}
+
+ReebArc *nextArcMappedToEdge(ReebArc *arc, ReebEdge *e)
+{
+ ReebEdge *nextEdge = NULL;
+ ReebEdge *edge = NULL;
+ ReebArc *result = NULL;
+
+ /* Find the ReebEdge in the edge list */
+ for(edge = arc->edges.first; edge && !edgeEquals(edge, e); edge = edge->next)
+ { }
+
+ nextEdge = edge->nextEdge;
+
+ if (nextEdge != NULL)
+ {
+ result = nextEdge->arc;
+ }
+
+ return result;
+}
+
+typedef enum {
+ MERGE_LOWER,
+ MERGE_HIGHER,
+ MERGE_APPEND
+} MergeDirection;
+
+void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection direction)
+{
+ ReebEdge *e = NULL;
+
+ if (direction == MERGE_APPEND)
+ {
+ for(e = aSrc->edges.first; e; e = e->next)
+ {
+ e->arc = aDst; // Edge is stolen by new arc
+ }
+
+ addlisttolist(&aDst->edges , &aSrc->edges);
+ }
+ else
+ {
+ for(e = aSrc->edges.first; e; e = e->next)
+ {
+ ReebEdge *newEdge = copyEdge(e);
+
+ newEdge->arc = aDst;
+
+ BLI_addtail(&aDst->edges, newEdge);
+
+ if (direction == MERGE_LOWER)
+ {
+ void **p = BLI_edgehash_lookup_p(rg->emap, e->v1->index, e->v2->index);
+
+ newEdge->nextEdge = e;
+
+ // if edge was the first in the list, point the edit edge to the new reeb edge instead.
+ if (*p == e)
+ {
+ *p = (void*)newEdge;
+ }
+ // otherwise, advance in the list until the predecessor is found then insert it there
+ else
+ {
+ ReebEdge *previous = (ReebEdge*)*p;
+
+ while(previous->nextEdge != e)
+ {
+ previous = previous->nextEdge;
+ }
+
+ previous->nextEdge = newEdge;
+ }
+ }
+ else
+ {
+ newEdge->nextEdge = e->nextEdge;
+ e->nextEdge = newEdge;
+ }
+ }
+ }
+}
+
+// return 1 on full merge
+int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1)
+{
+ int result = 0;
+ ReebNode *removedNode = NULL;
+
+ mergeArcEdges(rg, a0, a1, MERGE_APPEND);
+
+ // Bring a0 to the combine length of both arcs
+ if (a0->v2 == a1->v1)
+ {
+ removedNode = a0->v2;
+ a0->v2 = a1->v2;
+ }
+ else if (a0->v1 == a1->v2)
+ {
+ removedNode = a0->v1;
+ a0->v1 = a1->v1;
+ }
+
+ resizeArcBuckets(a0);
+ // Merge a1 in a0
+ mergeArcBuckets(a0, a1, a0->v1->weight, a0->v2->weight);
+
+ // remove a1 from graph
+ BLI_remlink(&rg->arcs, a1);
+ freeArc(a1);
+
+ BLI_freelinkN(&rg->nodes, removedNode);
+ result = 1;
+
+ return result;
+}
+// return 1 on full merge
+int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1)
+{
+ int result = 0;
+ // TRIANGLE POINTS DOWN
+ if (a0->v1->weight == a1->v1->weight) // heads are the same
+ {
+ if (a0->v2->weight == a1->v2->weight) // tails also the same, arcs can be totally merge together
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_APPEND);
+
+ mergeArcBuckets(a0, a1, a0->v1->weight, a0->v2->weight);
+
+ // Adjust node degree
+ a1->v1->degree--;
+ a1->v2->degree--;
+
+ // remove a1 from graph
+ BLI_remlink(&rg->arcs, a1);
+
+ freeArc(a1);
+ result = 1;
+ }
+ else if (a0->v2->weight > a1->v2->weight) // a1->v2->weight is in the middle
+ {
+ mergeArcEdges(rg, a1, a0, MERGE_LOWER);
+
+ // Adjust node degree
+ a0->v1->degree--;
+ a1->v2->degree++;
+
+ mergeArcBuckets(a1, a0, a1->v1->weight, a1->v2->weight);
+ a0->v1 = a1->v2;
+ resizeArcBuckets(a0);
+ }
+ else // a0>n2 is in the middle
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_LOWER);
+
+ // Adjust node degree
+ a1->v1->degree--;
+ a0->v2->degree++;
+
+ mergeArcBuckets(a0, a1, a0->v1->weight, a0->v2->weight);
+ a1->v1 = a0->v2;
+ resizeArcBuckets(a1);
+ }
+ }
+ // TRIANGLE POINTS UP
+ else if (a0->v2->weight == a1->v2->weight) // tails are the same
+ {
+ if (a0->v1->weight > a1->v1->weight) // a0->v1->weight is in the middle
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_HIGHER);
+
+ // Adjust node degree
+ a1->v2->degree--;
+ a0->v1->degree++;
+
+ mergeArcBuckets(a0, a1, a0->v1->weight, a0->v2->weight);
+ a1->v2 = a0->v1;
+ resizeArcBuckets(a1);
+ }
+ else // a1->v1->weight is in the middle
+ {
+ mergeArcEdges(rg, a1, a0, MERGE_HIGHER);
+
+ // Adjust node degree
+ a0->v2->degree--;
+ a1->v1->degree++;
+
+ mergeArcBuckets(a1, a0, a1->v1->weight, a1->v2->weight);
+ a0->v2 = a1->v1;
+ resizeArcBuckets(a0);
+ }
+ }
+ else
+ {
+ // Need something here (OR NOT)
+ }
+
+ return result;
+}
+
+void glueByMergeSort(ReebGraph *rg, ReebArc *a0, ReebArc *a1, ReebEdge *e0, ReebEdge *e1)
+{
+ int total = 0;
+ while (total == 0 && a0 != a1 && a0 != NULL && a1 != NULL)
+ {
+ total = mergeArcs(rg, a0, a1);
+
+ if (total == 0) // if it wasn't a total merge, go forward
+ {
+ if (a0->v2->weight < a1->v2->weight)
+ {
+ a0 = nextArcMappedToEdge(a0, e0);
+ }
+ else
+ {
+ a1 = nextArcMappedToEdge(a1, e1);
+ }
+ }
+ }
+}
+
+void mergePaths(ReebGraph *rg, ReebEdge *e0, ReebEdge *e1, ReebEdge *e2)
+{
+ ReebArc *a0, *a1, *a2;
+ a0 = e0->arc;
+ a1 = e1->arc;
+ a2 = e2->arc;
+
+ glueByMergeSort(rg, a0, a1, e0, e1);
+ glueByMergeSort(rg, a0, a2, e0, e2);
+}
+
+ReebNode * addNode(ReebGraph *rg, EditVert *eve, float weight)
+{
+ ReebNode *node = NULL;
+
+ node = MEM_callocN(sizeof(ReebNode), "reeb node");
+
+ node->flags = 0; // clear flags on init
+ node->arcs = NULL;
+ node->degree = 0;
+ node->weight = weight;
+ node->index = rg->totnodes;
+ VECCOPY(node->p, eve->co);
+
+ BLI_addtail(&rg->nodes, node);
+ rg->totnodes++;
+
+ return node;
+}
+
+ReebEdge * createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2)
+{
+ ReebEdge *edge;
+
+ edge = BLI_edgehash_lookup(rg->emap, node1->index, node2->index);
+
+ // Only add existing edges that haven't been added yet
+ if (edge == NULL)
+ {
+ ReebArc *arc;
+ ReebNode *v1, *v2;
+ float len, offset;
+ int i;
+
+ arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
+ edge = MEM_callocN(sizeof(ReebEdge), "reeb edge");
+
+ arc->flags = 0; // clear flags on init
+
+ if (node1->weight <= node2->weight)
+ {
+ v1 = node1;
+ v2 = node2;
+ }
+ else
+ {
+ v1 = node2;
+ v2 = node1;
+ }
+
+ arc->v1 = v1;
+ arc->v2 = v2;
+
+ // increase node degree
+ v1->degree++;
+ v2->degree++;
+
+ BLI_edgehash_insert(rg->emap, node1->index, node2->index, edge);
+
+ edge->arc = arc;
+ edge->nextEdge = NULL;
+ edge->v1 = v1;
+ edge->v2 = v2;
+
+ BLI_addtail(&rg->arcs, arc);
+ BLI_addtail(&arc->edges, edge);
+
+ /* adding buckets for embedding */
+ allocArcBuckets(arc);
+
+ offset = arc->v1->weight;
+ len = arc->v2->weight - arc->v1->weight;
+
+#if 0
+ /* This is the actual embedding filling described in the paper
+ * the problem is that it only works with really dense meshes
+ */
+ if (arc->bcount > 0)
+ {
+ addVertToBucket(&(arc->buckets[0]), arc->v1->co);
+ addVertToBucket(&(arc->buckets[arc->bcount - 1]), arc->v2->co);
+ }
+#else
+ for(i = 0; i < arc->bcount; i++)
+ {
+ float co[3];
+ float f = (arc->buckets[i].val - offset) / len;
+
+ VecLerpf(co, v1->p, v2->p, f);
+ addVertToBucket(&(arc->buckets[i]), co);
+ }
+#endif
+
+ }
+
+ return edge;
+}
+
+void addTriangleToGraph(ReebGraph *rg, ReebNode * n1, ReebNode * n2, ReebNode * n3)
+{
+ ReebEdge *re1, *re2, *re3;
+ ReebEdge *e1, *e2, *e3;
+ float len1, len2, len3;
+
+ re1 = createArc(rg, n1, n2);
+ re2 = createArc(rg, n2, n3);
+ re3 = createArc(rg, n3, n1);
+
+ len1 = (float)fabs(n1->weight - n2->weight);
+ len2 = (float)fabs(n2->weight - n3->weight);
+ len3 = (float)fabs(n3->weight - n1->weight);
+
+ /* The rest of the algorithm assumes that e1 is the longest edge */
+
+ if (len1 >= len2 && len1 >= len3)
+ {
+ e1 = re1;
+ e2 = re2;
+ e3 = re3;
+ }
+ else if (len2 >= len1 && len2 >= len3)
+ {
+ e1 = re2;
+ e2 = re1;
+ e3 = re3;
+ }
+ else
+ {
+ e1 = re3;
+ e2 = re2;
+ e3 = re1;
+ }
+
+ /* And e2 is the lowest edge
+ * If e3 is lower than e2, swap them
+ */
+ if (e3->v1->weight < e2->v1->weight)
+ {
+ ReebEdge *etmp = e2;
+ e2 = e3;
+ e3 = etmp;
+ }
+
+
+ mergePaths(rg, e1, e2, e3);
+}
+
+ReebGraph * generateReebGraph(EditMesh *em, int subdivisions)
+{
+ ReebGraph *rg;
+ struct DynamicList * dlist;
+ EditVert *eve;
+ EditFace *efa;
+ int index;
+ int totvert;
+ int totfaces;
+
+#ifdef DEBUG_REEB
+ int countfaces = 0;
+#endif
+
+ rg = MEM_callocN(sizeof(ReebGraph), "reeb graph");
+
+ rg->totnodes = 0;
+ rg->emap = BLI_edgehash_new();
+
+ totvert = BLI_countlist(&em->verts);
+ totfaces = BLI_countlist(&em->faces);
+
+ renormalizeWeight(em, 1.0f);
+
+ /* Spread weight to minimize errors */
+ spreadWeight(em);
+
+ renormalizeWeight(em, (float)subdivisions);
+
+ /* Adding vertice */
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ eve->hash = index;
+ eve->f2 = 0;
+ eve->tmp.p = addNode(rg, eve, eve->tmp.fp);
+ }
+
+ /* Temporarely convert node list to dynamic list, for indexed access */
+ dlist = BLI_dlist_from_listbase(&rg->nodes);
+
+ /* Adding face, edge per edge */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ ReebNode *n1, *n2, *n3;
+
+ n1 = (ReebNode*)BLI_dlist_find_link(dlist, efa->v1->hash);
+ n2 = (ReebNode*)BLI_dlist_find_link(dlist, efa->v2->hash);
+ n3 = (ReebNode*)BLI_dlist_find_link(dlist, efa->v3->hash);
+
+ addTriangleToGraph(rg, n1, n2, n3);
+
+ if (efa->v4)
+ {
+ ReebNode *n4 = (ReebNode*)efa->v4->tmp.p;
+ addTriangleToGraph(rg, n1, n3, n4);
+ }
+
+#ifdef DEBUG_REEB
+ countfaces++;
+ if (countfaces % 100 == 0)
+ {
+ printf("face %i of %i\n", countfaces, totfaces);
+ }
+#endif
+
+
+ }
+ BLI_listbase_from_dlist(dlist, &rg->nodes);
+
+ removeNormalNodes(rg);
+
+ return rg;
+}
+
+/***************************************** WEIGHT UTILS **********************************************/
+
+void renormalizeWeight(EditMesh *em, float newmax)
+{
+ EditVert *eve;
+ float minimum, maximum, range;
+
+ if (em == NULL || BLI_countlist(&em->verts) == 0)
+ return;
+
+ /* First pass, determine maximum and minimum */
+ eve = em->verts.first;
+ minimum = eve->tmp.fp;
+ maximum = eve->tmp.fp;
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ maximum = MAX2(maximum, eve->tmp.fp);
+ minimum = MIN2(minimum, eve->tmp.fp);
+ }
+
+ range = maximum - minimum;
+
+ /* Normalize weights */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ eve->tmp.fp = (eve->tmp.fp - minimum) / range * newmax;
+ }
+}
+
+
+int weightFromLoc(EditMesh *em, int axis)
+{
+ EditVert *eve;
+
+ if (em == NULL || BLI_countlist(&em->verts) == 0 || axis < 0 || axis > 2)
+ return 0;
+
+ /* Copy coordinate in weight */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ eve->tmp.fp = eve->co[axis];
+ }
+
+ return 1;
+}
+
+static float cotan_weight(float *v1, float *v2, float *v3)
+{
+ float a[3], b[3], c[3], clen;
+
+ VecSubf(a, v2, v1);
+ VecSubf(b, v3, v1);
+ Crossf(c, a, b);
+
+ clen = VecLength(c);
+
+ if (clen == 0.0f)
+ return 0.0f;
+
+ return Inpf(a, b)/clen;
+}
+
+int weightToHarmonic(EditMesh *em)
+{
+ NLboolean success;
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+ int totvert = 0;
+ int index;
+ int rval;
+
+ /* Find local extrema */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ totvert++;
+ }
+
+ /* Solve with openNL */
+
+ nlNewContext();
+
+ nlSolverParameteri(NL_NB_VARIABLES, totvert);
+
+ nlBegin(NL_SYSTEM);
+
+ /* Find local extrema */
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ EditEdge *eed;
+ int maximum = 1;
+ int minimum = 1;
+
+ eve->hash = index; /* Assign index to vertex */
+
+ NextEdgeForVert(NULL, NULL); /* Reset next edge */
+ for(eed = NextEdgeForVert(em, eve); eed && (maximum || minimum); eed = NextEdgeForVert(em, eve))
+ {
+ EditVert *eve2;
+
+ if (eed->v1 == eve)
+ {
+ eve2 = eed->v2;
+ }
+ else
+ {
+ eve2 = eed->v1;
+ }
+
+ /* Adjacent vertex is bigger, not a local maximum */
+ if (eve2->tmp.fp > eve->tmp.fp)
+ {
+ maximum = 0;
+ }
+ /* Adjacent vertex is smaller, not a local minimum */
+ else if (eve2->tmp.fp < eve->tmp.fp)
+ {
+ minimum = 0;
+ }
+ }
+
+ if (maximum || minimum)
+ {
+ float w = eve->tmp.fp;
+ eve->f1 = 0;
+ nlSetVariable(0, index, w);
+ nlLockVariable(index);
+ }
+ else
+ {
+ eve->f1 = 1;
+ }
+ }
+
+ nlBegin(NL_MATRIX);
+
+ /* Zero edge weight */
+ for(eed = em->edges.first; eed; eed = eed->next)
+ {
+ eed->tmp.l = 0;
+ }
+
+ /* Add faces count to the edge weight */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ efa->e1->tmp.l++;
+ efa->e2->tmp.l++;
+ efa->e3->tmp.l++;
+ }
+
+ /* Add faces angle to the edge weight */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ /* Angle opposite e1 */
+ float t1= cotan_weight(efa->v1->co, efa->v2->co, efa->v3->co) / efa->e2->tmp.l;
+
+ /* Angle opposite e2 */
+ float t2 = cotan_weight(efa->v2->co, efa->v3->co, efa->v1->co) / efa->e3->tmp.l;
+
+ /* Angle opposite e3 */
+ float t3 = cotan_weight(efa->v3->co, efa->v1->co, efa->v2->co) / efa->e1->tmp.l;
+
+ int i1 = efa->v1->hash;
+ int i2 = efa->v2->hash;
+ int i3 = efa->v3->hash;
+
+ nlMatrixAdd(i1, i1, t2+t3);
+ nlMatrixAdd(i2, i2, t1+t3);
+ nlMatrixAdd(i3, i3, t1+t2);
+
+ nlMatrixAdd(i1, i2, -t3);
+ nlMatrixAdd(i2, i1, -t3);
+
+ nlMatrixAdd(i2, i3, -t1);
+ nlMatrixAdd(i3, i2, -t1);
+
+ nlMatrixAdd(i3, i1, -t2);
+ nlMatrixAdd(i1, i3, -t2);
+ }
+
+ nlEnd(NL_MATRIX);
+
+ nlEnd(NL_SYSTEM);
+
+ success = nlSolveAdvanced(NULL, NL_TRUE);
+
+ if (success)
+ {
+ rval = 1;
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ eve->tmp.fp = nlGetVariable(0, index);
+ }
+ }
+ else
+ {
+ rval = 0;
+ }
+
+ nlDeleteContext(nlGetCurrent());
+
+ return rval;
+}
+
+
+EditEdge * NextEdgeForVert(EditMesh *em, EditVert *v)
+{
+ static EditEdge *e = NULL;
+
+ /* Reset method, call with NULL mesh pointer */
+ if (em == NULL)
+ {
+ e = NULL;
+ return NULL;
+ }
+
+ /* first pass, start at the head of the list */
+ if (e == NULL)
+ {
+ e = em->edges.first;
+ }
+ /* subsequent passes, start on the next edge */
+ else
+ {
+ e = e->next;
+ }
+
+ for( ; e ; e = e->next)
+ {
+ if (e->v1 == v || e->v2 == v)
+ {
+ break;
+ }
+ }
+
+ return e;
+}
+
+int weightFromDistance(EditMesh *em)
+{
+ EditVert *eve;
+ int totedge = 0;
+ int vCount = 0;
+
+ if (em == NULL || BLI_countlist(&em->verts) == 0)
+ {
+ return 0;
+ }
+
+ totedge = BLI_countlist(&em->edges);
+
+ if (totedge == 0)
+ {
+ return 0;
+ }
+
+ /* Initialize vertice flags and find at least one selected vertex */
+ for(eve = em->verts.first; eve && vCount == 0; eve = eve->next)
+ {
+ eve->f1 = 0;
+ if (eve->f & SELECT)
+ {
+ vCount = 1;
+ }
+ }
+
+ if (vCount == 0)
+ {
+ return 0; /* no selected vert, failure */
+ }
+ else
+ {
+ EditVert *eve, *current_eve = NULL;
+ /* Apply dijkstra spf for each selected vert */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ if (eve->f & SELECT)
+ {
+ current_eve = eve;
+ eve->f1 = 1;
+
+ {
+ EditEdge *eed = NULL;
+ EditEdge *select_eed = NULL;
+ EditEdge **edges = NULL;
+ float currentWeight = 0;
+ int eIndex = 0;
+
+ edges = MEM_callocN(totedge * sizeof(EditEdge*), "Edges");
+
+ /* Calculate edge weight and initialize edge flags */
+ for(eed= em->edges.first; eed; eed= eed->next)
+ {
+ eed->tmp.fp = VecLenf(eed->v1->co, eed->v2->co);
+ eed->f1 = 0;
+ }
+
+ do {
+ int i;
+
+ current_eve->f1 = 1; /* mark vertex as selected */
+
+ /* Add all new edges connected to current_eve to the list */
+ NextEdgeForVert(NULL, NULL); // Reset next edge
+ for(eed = NextEdgeForVert(em, current_eve); eed; eed = NextEdgeForVert(em, current_eve))
+ {
+ if (eed->f1 == 0)
+ {
+ edges[eIndex] = eed;
+ eed->f1 = 1;
+ eIndex++;
+ }
+ }
+
+ /* Find next shortest edge */
+ select_eed = NULL;
+ for(i = 0; i < eIndex; i++)
+ {
+ eed = edges[i];
+
+ if (eed->f1 != 2 && (eed->v1->f1 == 0 || eed->v2->f1 == 0)) /* eed is not selected yet and leads to a new node */
+ {
+ float newWeight = 0;
+ if (eed->v1->f1 == 1)
+ {
+ newWeight = eed->v1->tmp.fp + eed->tmp.fp;
+ }
+ else
+ {
+ newWeight = eed->v2->tmp.fp + eed->tmp.fp;
+ }
+
+ if (select_eed == NULL || newWeight < currentWeight) /* no selected edge or current smaller than selected */
+ {
+ currentWeight = newWeight;
+ select_eed = eed;
+ }
+ }
+ }
+
+ if (select_eed != NULL)
+ {
+ select_eed->f1 = 2;
+
+ if (select_eed->v1->f1 == 0) /* v1 is the new vertex */
+ {
+ current_eve = select_eed->v1;
+ }
+ else /* otherwise, it's v2 */
+ {
+ current_eve = select_eed->v2;
+ }
+ current_eve->tmp.fp = currentWeight;
+ }
+ } while (select_eed != NULL);
+
+ MEM_freeN(edges);
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+MCol MColFromWeight(EditVert *eve)
+{
+ MCol col;
+ col.a = 255;
+ col.b = (char)(eve->tmp.fp * 255);
+ col.g = 0;
+ col.r = (char)((1.0f - eve->tmp.fp) * 255);
+ return col;
+}
+
+void weightToVCol(EditMesh *em)
+{
+ EditFace *efa;
+ MCol *mcol;
+ if (!EM_vertColorCheck()) {
+ return;
+ }
+
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
+
+ mcol[0] = MColFromWeight(efa->v1);
+ mcol[1] = MColFromWeight(efa->v2);
+ mcol[2] = MColFromWeight(efa->v3);
+
+ if(efa->v4) {
+ mcol[3] = MColFromWeight(efa->v4);
+ }
+ }
+}
+
+/****************************************** BUCKET ITERATOR **************************************************/
+
+void initArcIterator(ReebArcIterator *iter, ReebArc *arc, ReebNode *head)
+{
+ iter->arc = arc;
+
+ if (head == arc->v1)
+ {
+ iter->start = 0;
+ iter->end = arc->bcount - 1;
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->start = arc->bcount - 1;
+ iter->end = 0;
+ iter->stride = -1;
+ }
+
+ iter->index = iter->start - iter->stride;
+}
+
+void initArcIterator2(ReebArcIterator *iter, ReebArc *arc, int start, int end)
+{
+ iter->arc = arc;
+
+ iter->start = start;
+ iter->end = end;
+
+ if (end > start)
+ {
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->stride = -1;
+ }
+
+ iter->index = iter->start - iter->stride;
+}
+
+EmbedBucket * nextBucket(ReebArcIterator *iter)
+{
+ EmbedBucket *result = NULL;
+
+ if (iter->index != iter->end)
+ {
+ iter->index += iter->stride;
+ result = &(iter->arc->buckets[iter->index]);
+ }
+
+ return result;
+}
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index 41a600d0eb4..4510e72e659 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -137,13 +137,8 @@ typedef struct {
int rectx, recty; /* size of image */
- int sparex, sparey; /* spare rect size */
- unsigned int *rectspare;
- float *rectsparef;
-
float zoom, zoomofs[2];
int active;
- short storespare, showspare;
int mbut[5];
int lmouse[2];
@@ -153,14 +148,29 @@ typedef struct {
float pan_mouse_start[2], pan_ofs_start[2];
char *info_text;
- char *render_text, *render_text_spare;
} RenderWin;
+typedef struct RenderSpare {
+ ImBuf *ibuf;
+
+ short storespare, showspare;
+ char *render_text_spare;
+} RenderSpare;
+
static RenderWin *render_win= NULL;
+static RenderSpare *render_spare= NULL;
+static char *render_text= NULL;
/* --------------- help functions for RenderWin struct ---------------------------- */
+static RenderSpare *renderspare_alloc()
+{
+ RenderSpare *rspare= MEM_callocN(sizeof(*rspare), "RenderSpare");
+ rspare->render_text_spare= MEM_callocN(RW_MAXTEXT, "rendertext spare");
+
+ return rspare;
+}
/* only called in function open_renderwin */
static RenderWin *renderwin_alloc(Window *win)
@@ -172,8 +182,6 @@ static RenderWin *renderwin_alloc(Window *win)
rw->flags= 0;
rw->zoomofs[0]= rw->zoomofs[1]= 0;
rw->info_text= NULL;
- rw->render_text= MEM_callocN(RW_MAXTEXT, "rendertext");
- rw->render_text_spare= MEM_callocN(RW_MAXTEXT, "rendertext spare");
rw->lmouse[0]= rw->lmouse[1]= 0;
rw->mbut[0]= rw->mbut[1]= rw->mbut[2]= rw->mbut[3] = rw->mbut[4] = 0;
@@ -291,10 +299,7 @@ static void renderwin_draw_render_info(RenderWin *rw)
glClearColor(colf[0], colf[1], colf[2], 1.0);
glClear(GL_COLOR_BUFFER_BIT);
- if(rw->showspare)
- str= rw->render_text_spare;
- else
- str= rw->render_text;
+ str= BIF_render_text();
if(str) {
BIF_ThemeColor(TH_TEXT);
@@ -339,12 +344,18 @@ static void renderwin_draw(RenderWin *rw, int just_clear)
glRectfv(fullrect[0], fullrect[1]);
} else {
RenderResult rres;
+ RenderSpare *rspare= render_spare;
- if(rw->showspare) {
- rres.rectx= rw->sparex;
- rres.recty= rw->sparey;
- rres.rect32= (int *)rw->rectspare;
- rres.rectf= rw->rectsparef;
+ if(rspare && rspare->showspare) {
+ if(rspare->ibuf) {
+ rres.rectx= rspare->ibuf->x;
+ rres.recty= rspare->ibuf->y;
+ rres.rect32= (int *)rspare->ibuf->rect;
+ rres.rectf= rspare->ibuf->rect_float;
+ rres.rectz= rspare->ibuf->zbuf_float;
+ }
+ else
+ memset(&rres, 0, sizeof(rres));
}
else
RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
@@ -419,11 +430,26 @@ static void renderwin_zoom(RenderWin *rw, int ZoomIn) {
renderwin_queue_redraw(rw);
}
+#define FTOCHAR(val) val<=0.0f? 0 : (val>=(1.0f-0.5f/255.0f)? 255 :(char)((255.0f*val)+0.5f))
+
static void renderwin_mouse_moved(RenderWin *rw)
{
RenderResult rres;
-
- RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+ RenderSpare *rspare= render_spare;
+
+ if(rspare && rspare->showspare) {
+ if(rspare->ibuf) {
+ rres.rectx= rspare->ibuf->x;
+ rres.recty= rspare->ibuf->y;
+ rres.rect32= (int *)rspare->ibuf->rect;
+ rres.rectf= rspare->ibuf->rect_float;
+ rres.rectz= rspare->ibuf->zbuf_float;
+ }
+ else
+ memset(&rres, 0, sizeof(rres));
+ }
+ else
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
int imgco[2], ofs=0;
@@ -431,12 +457,16 @@ static void renderwin_mouse_moved(RenderWin *rw)
char *pxl;
if (renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
+ ofs= sprintf(buf, "X: %d Y: %d ", imgco[0], imgco[1]);
if (rres.rect32) {
pxl= (char*) &rres.rect32[rres.rectx*imgco[1] + imgco[0]];
- ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
+ ofs+= sprintf(buf+ofs, " | R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
}
if (rres.rectf) {
float *pxlf= rres.rectf + 4*(rres.rectx*imgco[1] + imgco[0]);
+ if(!rres.rect32){
+ ofs+= sprintf(buf+ofs, " | R: %d G: %d B: %d A: %d", FTOCHAR(pxlf[0]), FTOCHAR(pxlf[1]), FTOCHAR(pxlf[2]), FTOCHAR(pxlf[3]));
+ }
ofs+= sprintf(buf+ofs, " | R: %.3f G: %.3f B: %.3f A: %.3f ", pxlf[0], pxlf[1], pxlf[2], pxlf[3]);
}
if (rres.rectz) {
@@ -612,14 +642,11 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val
}
}
-static char *renderwin_get_title(int doswap)
+static char *renderwin_get_title()
{
- static int swap= 0;
char *title="";
- swap+= doswap;
-
- if(swap & 1) {
+ if(BIF_show_render_spare()) {
if (G.scene->r.renderer==R_YAFRAY) title = "YafRay:Render (previous)";
else title = "Blender:Render (previous)";
}
@@ -638,7 +665,7 @@ static void open_renderwin(int winpos[2], int winsize[2], int imagesize[2])
Window *win;
char *title;
- title= renderwin_get_title(0); /* 0 = no swap */
+ title= renderwin_get_title();
win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY, 0);
render_win= renderwin_alloc(win);
@@ -894,11 +921,11 @@ void make_renderinfo_string(RenderStats *rs, char *str)
else if(G.scene->r.scemode & R_SINGLE_LAYER)
spos+= sprintf(spos, "Single Layer | ");
- if(rs->tothalo)
- spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM (%.2fM) ", (G.scene->r.cfra), rs->totvert, rs->totface, rs->tothalo, rs->totlamp, megs_used_memory, mmap_used_memory);
- else
- spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM (%.2fM) ", (G.scene->r.cfra), rs->totvert, rs->totface, rs->totlamp, megs_used_memory, mmap_used_memory);
-
+ spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d ", (G.scene->r.cfra), rs->totvert, rs->totface);
+ if(rs->tothalo) spos+= sprintf(spos, "Ha:%d ", rs->tothalo);
+ if(rs->totstrand) spos+= sprintf(spos, "St:%d ", rs->totstrand);
+ spos+= sprintf(spos, "La:%d Mem:%.2fM (%.2fM) ", rs->totlamp, megs_used_memory, mmap_used_memory);
+
if(rs->curfield)
spos+= sprintf(spos, "Field %d ", rs->curfield);
if(rs->curblur)
@@ -922,7 +949,7 @@ static void renderwin_renderinfo_cb(RenderStats *rs)
if(render_win) {
- make_renderinfo_string(rs, render_win->render_text);
+ BIF_make_render_text(rs);
#ifdef __APPLE__
#else
@@ -1081,11 +1108,14 @@ static void do_render(int anim)
/* allow localview render for objects with lights in normal layers */
if(curarea->spacetype==SPACE_VIEW3D) {
- if(G.vd->lay & 0xFF000000) {
- G.scene->lay |= G.vd->lay;
- G.scene->r.scemode |= R_SINGLE_LAYER;
+ /* if view is defined (might not be if called from script), check and set layers. */
+ if(G.vd) {
+ if(G.vd->lay & 0xFF000000) {
+ G.scene->lay |= G.vd->lay;
+ G.scene->r.scemode |= R_SINGLE_LAYER;
+ }
+ else G.scene->lay= G.vd->lay;
}
- else G.scene->lay= G.vd->lay;
}
if(anim)
@@ -1121,36 +1151,46 @@ static void do_render(int anim)
}
/* called before render, store old render in spare buffer */
-static void renderwin_store_spare(void)
+static int render_store_spare(void)
{
RenderResult rres;
+ RenderSpare *rspare= render_spare;
- if(render_win==0 || render_win->storespare==0)
- return;
+ if(rspare==0 || rspare->storespare==0)
+ return 0;
/* only store when it does not show spare */
- if(render_win->showspare==0)
- return;
-
- render_win->showspare= 0;
- window_set_title(render_win->win, renderwin_get_title(1));
+ if(rspare->showspare==0)
+ return 0;
- BLI_strncpy(render_win->render_text_spare, render_win->render_text, RW_MAXTEXT);
-
- if(render_win->rectspare) MEM_freeN(render_win->rectspare);
- render_win->rectspare= NULL;
- if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
- render_win->rectsparef= NULL;
+ rspare->showspare= 0;
+
+ if(rspare->ibuf) {
+ IMB_freeImBuf(rspare->ibuf);
+ rspare->ibuf= NULL;
+ }
RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+
+ rspare->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0);
- if(rres.rect32)
- render_win->rectspare= MEM_dupallocN(rres.rect32);
- else if(rres.rectf)
- render_win->rectsparef= MEM_dupallocN(rres.rectf);
+ if(rres.rect32) {
+ rspare->ibuf->rect= MEM_dupallocN(rres.rect32);
+ rspare->ibuf->flags |= IB_rect;
+ rspare->ibuf->mall |= IB_rect;
+ }
+ if(rres.rectf) {
+ rspare->ibuf->rect_float= MEM_dupallocN(rres.rectf);
+ rspare->ibuf->flags |= IB_rectfloat;
+ rspare->ibuf->mall |= IB_rectfloat;
+ }
+ if(rres.rectz) {
+ rspare->ibuf->zbuf_float= MEM_dupallocN(rres.rectz);
+ rspare->ibuf->flags |= IB_zbuffloat;
+ rspare->ibuf->mall |= IB_zbuffloat;
+ }
- render_win->sparex= rres.rectx;
- render_win->sparey= rres.recty;
+ return 1;
}
/* -------------- API: externally called --------------- */
@@ -1207,10 +1247,14 @@ void BIF_end_render_callbacks(void)
void BIF_store_spare(void)
{
- if(render_win)
- renderwin_store_spare();
- else
- imagewin_store_spare();
+ if(render_store_spare()) {
+ if(render_text)
+ BLI_strncpy(render_spare->render_text_spare, render_text, RW_MAXTEXT);
+
+ if(render_win)
+ window_set_title(render_win->win, renderwin_get_title());
+ allqueue(REDRAWIMAGE, 0);
+ }
}
/* set up display, render an image or scene */
@@ -1238,6 +1282,21 @@ void BIF_do_render(int anim)
if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER);
}
+void do_ogl_view3d_render(Render *re, View3D *v3d, int winx, int winy)
+{
+ float winmat[4][4];
+
+ update_for_newframe_muted(); /* here, since camera can be animated */
+
+ if(v3d->persp==2 && v3d->camera) {
+ /* in camera view, use actual render winmat */
+ RE_GetCameraWindow(re, v3d->camera, CFRA, winmat);
+ drawview3d_render(v3d, winx, winy, winmat);
+ }
+ else
+ drawview3d_render(v3d, winx, winy, NULL);
+}
+
/* set up display, render the current area view in an image */
/* the RE_Render is only used to make sure we got the picture in the result */
void BIF_do_ogl_render(View3D *v3d, int anim)
@@ -1252,8 +1311,8 @@ void BIF_do_ogl_render(View3D *v3d, int anim)
winx= (G.scene->r.size*G.scene->r.xsch)/100;
winy= (G.scene->r.size*G.scene->r.ysch)/100;
- RE_InitState(re, &G.scene->r, winx, winy, NULL);
-
+ RE_InitState(re, NULL, &G.scene->r, winx, winy, NULL);
+
/* for now, result is defaulting to floats still... */
rr= RE_GetResult(re);
if(rr->rect32==NULL)
@@ -1279,8 +1338,12 @@ void BIF_do_ogl_render(View3D *v3d, int anim)
/* user event can close window */
if(render_win==NULL)
break;
- drawview3d_render(v3d, winx, winy);
+
+ do_ogl_view3d_render(re, v3d, winx, winy);
glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32);
+ if((G.scene->r.scemode & R_STAMP_INFO) && (G.scene->r.stamp & R_STAMP_DRAW)) {
+ BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty, 3);
+ }
window_swap_buffers(render_win->win);
if(BKE_imtype_is_movie(G.scene->r.imtype)) {
@@ -1294,7 +1357,7 @@ void BIF_do_ogl_render(View3D *v3d, int anim)
BKE_makepicstring(name, G.scene->r.pic, G.scene->r.cfra, G.scene->r.imtype);
- ibuf->rect= (unsigned int *)rr->rect32;
+ ibuf->rect= (unsigned int *)rr->rect32;
ok= BKE_write_ibuf(ibuf, name, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality);
if(ok==0) {
@@ -1318,8 +1381,11 @@ void BIF_do_ogl_render(View3D *v3d, int anim)
CFRA= cfrao;
}
else {
- drawview3d_render(v3d, winx, winy);
+ do_ogl_view3d_render(re, v3d, winx, winy);
glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32);
+ if((G.scene->r.scemode & R_STAMP_INFO) && (G.scene->r.stamp & R_STAMP_DRAW)) {
+ BKE_stamp_buf((unsigned char *)rr->rect32, rr->rectf, rr->rectx, rr->recty, 3);
+ }
window_swap_buffers(render_win->win);
}
@@ -1338,53 +1404,88 @@ void BIF_do_ogl_render(View3D *v3d, int anim)
void BIF_redraw_render_rect(void)
{
/* redraw */
- if (render_win) {
+ if(render_win)
renderwin_queue_redraw(render_win);
- }
- else {
- allqueue(REDRAWIMAGE, 0);
- }
+ allqueue(REDRAWIMAGE, 0);
}
void BIF_swap_render_rects(void)
{
RenderResult rres;
+ RenderSpare *rspare;
+ ImBuf *ibuf;
- if(G.displaymode!=R_DISPLAYWIN) {
- imagewindow_swap_render_rects();
- }
- else if(render_win) {
-
- render_win->storespare= 1;
- render_win->showspare ^= 1;
-
- RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
-
- if(render_win->sparex!=rres.rectx || render_win->sparey!=rres.recty) {
- if(render_win->rectspare) MEM_freeN(render_win->rectspare);
- render_win->rectspare= NULL;
- if(render_win->rectsparef) MEM_freeN(render_win->rectsparef);
- render_win->rectsparef= NULL;
- }
+ if(!render_spare)
+ render_spare= renderspare_alloc();
+
+ rspare= render_spare;
+ rspare->storespare= 1;
+ rspare->showspare ^= 1;
- window_set_title(render_win->win, renderwin_get_title(1));
+ RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres);
+
+ ibuf= rspare->ibuf;
+ if(ibuf && (ibuf->x!=rres.rectx || ibuf->y!=rres.recty)) {
+ IMB_freeImBuf(ibuf);
+ rspare->ibuf= NULL;
}
+ if(render_win)
+ window_set_title(render_win->win, renderwin_get_title());
+
/* redraw */
BIF_redraw_render_rect();
-
}
+ImBuf *BIF_render_spare_imbuf()
+{
+ return (render_spare)? render_spare->ibuf: NULL;
+}
+
+int BIF_show_render_spare()
+{
+ return (render_spare && render_spare->showspare);
+}
+
+char *BIF_render_text()
+{
+ if(render_spare && render_spare->showspare)
+ return render_spare->render_text_spare;
+ else
+ return render_text;
+}
+
+void BIF_make_render_text(RenderStats *rs)
+{
+ if(!render_text)
+ render_text= MEM_callocN(RW_MAXTEXT, "rendertext");
+ make_renderinfo_string(rs, render_text);
+}
+
/* called from usiblender.c too, to free and close renderwin */
+
+void BIF_free_render_spare()
+{
+ RenderSpare *rspare= render_spare;
+
+ if(render_text) {
+ MEM_freeN(render_text);
+ render_text= NULL;
+ }
+
+ if(rspare) {
+ if (rspare->render_text_spare) MEM_freeN(rspare->render_text_spare);
+ if (rspare->ibuf) IMB_freeImBuf(rspare->ibuf);
+
+ MEM_freeN(rspare);
+ render_spare= NULL;
+ }
+}
+
void BIF_close_render_display(void)
{
if (render_win) {
if (render_win->info_text) MEM_freeN(render_win->info_text);
- if (render_win->render_text) MEM_freeN(render_win->render_text);
- if (render_win->render_text_spare) MEM_freeN(render_win->render_text_spare);
- if (render_win->rectspare) MEM_freeN(render_win->rectspare);
- if (render_win->rectsparef) MEM_freeN(render_win->rectsparef);
-
window_destroy(render_win->win); /* ghost close window */
MEM_freeN(render_win);
diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c
index 65f44027aee..722675f0453 100644
--- a/source/blender/src/resources.c
+++ b/source/blender/src/resources.c
@@ -252,6 +252,8 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp= ts->edge_seam; break;
case TH_EDGE_SHARP:
cp= ts->edge_sharp; break;
+ case TH_EDITMESH_ACTIVE:
+ cp= ts->editmesh_active; break;
case TH_EDGE_FACESEL:
cp= ts->edge_facesel; break;
case TH_FACE:
@@ -272,6 +274,8 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp= ts->strip; break;
case TH_STRIP_SELECT:
cp= ts->strip_select; break;
+ case TH_CFRAME:
+ cp= ts->cframe; break;
case TH_SYNTAX_B:
cp= ts->syntaxb; break;
@@ -367,6 +371,68 @@ void BIF_InitTheme(void)
BLI_strncpy(btheme->tui.iconfile, "", sizeof(btheme->tui.iconfile));
+ /* bone color sets */
+ /* set 1 */
+ SETCOL(btheme->tarm[0].solid, 0x9a, 0x00, 0x00, 255);
+ SETCOL(btheme->tarm[0].select, 0xbd, 0x11, 0x11, 255);
+ SETCOL(btheme->tarm[0].active, 0xf7, 0x0a, 0x0a, 255);
+ /* set 2 */
+ SETCOL(btheme->tarm[1].solid, 0xf7, 0x40, 0x18, 255);
+ SETCOL(btheme->tarm[1].select, 0xf6, 0x69, 0x13, 255);
+ SETCOL(btheme->tarm[1].active, 0xfa, 0x99, 0x00, 255);
+ /* set 3 */
+ SETCOL(btheme->tarm[2].solid, 0x1e, 0x91, 0x09, 255);
+ SETCOL(btheme->tarm[2].select, 0x59, 0xb7, 0x0b, 255);
+ SETCOL(btheme->tarm[2].active, 0x83, 0xef, 0x1d, 255);
+ /* set 4 */
+ SETCOL(btheme->tarm[3].solid, 0x0a, 0x36, 0x94, 255);
+ SETCOL(btheme->tarm[3].select, 0x36, 0x67, 0xdf, 255);
+ SETCOL(btheme->tarm[3].active, 0x5e, 0xc1, 0xef, 255);
+ /* set 5 */
+ SETCOL(btheme->tarm[4].solid, 0xa9, 0x29, 0x4e, 255);
+ SETCOL(btheme->tarm[4].select, 0xc1, 0x41, 0x6a, 255);
+ SETCOL(btheme->tarm[4].active, 0xf0, 0x5d, 0x91, 255);
+ /* set 6 */
+ SETCOL(btheme->tarm[5].solid, 0x43, 0x0c, 0x78, 255);
+ SETCOL(btheme->tarm[5].select, 0x54, 0x3a, 0xa3, 255);
+ SETCOL(btheme->tarm[5].active, 0x87, 0x64, 0xd5, 255);
+ /* set 7 */
+ SETCOL(btheme->tarm[6].solid, 0x24, 0x78, 0x5a, 255);
+ SETCOL(btheme->tarm[6].select, 0x3c, 0x95, 0x79, 255);
+ SETCOL(btheme->tarm[6].active, 0x6f, 0xb6, 0xab, 255);
+ /* set 8 */
+ SETCOL(btheme->tarm[7].solid, 0x4b, 0x70, 0x7c, 255);
+ SETCOL(btheme->tarm[7].select, 0x6a, 0x86, 0x91, 255);
+ SETCOL(btheme->tarm[7].active, 0x9b, 0xc2, 0xcd, 255);
+ /* set 9 */
+ SETCOL(btheme->tarm[8].solid, 0xf4, 0xc9, 0x0c, 255);
+ SETCOL(btheme->tarm[8].select, 0xee, 0xc2, 0x36, 255);
+ SETCOL(btheme->tarm[8].active, 0xf3, 0xff, 0x00, 255);
+ /* set 10 */
+ SETCOL(btheme->tarm[9].solid, 0x1e, 0x20, 0x24, 255);
+ SETCOL(btheme->tarm[9].select, 0x48, 0x4c, 0x56, 255);
+ SETCOL(btheme->tarm[9].active, 0xff, 0xff, 0xff, 255);
+ /* set 11 */
+ SETCOL(btheme->tarm[10].solid, 0x6f, 0x2f, 0x6a, 255);
+ SETCOL(btheme->tarm[10].select, 0x98, 0x45, 0xbe, 255);
+ SETCOL(btheme->tarm[10].active, 0xd3, 0x30, 0xd6, 255);
+ /* set 12 */
+ SETCOL(btheme->tarm[11].solid, 0x6c, 0x8e, 0x22, 255);
+ SETCOL(btheme->tarm[11].select, 0x7f, 0xb0, 0x22, 255);
+ SETCOL(btheme->tarm[11].active, 0xbb, 0xef, 0x5b, 255);
+ /* set 13 */
+ SETCOL(btheme->tarm[12].solid, 0x8d, 0x8d, 0x8d, 255);
+ SETCOL(btheme->tarm[12].select, 0xb0, 0xb0, 0xb0, 255);
+ SETCOL(btheme->tarm[12].active, 0xde, 0xde, 0xde, 255);
+ /* set 14 */
+ SETCOL(btheme->tarm[13].solid, 0x83, 0x43, 0x26, 255);
+ SETCOL(btheme->tarm[13].select, 0x8b, 0x58, 0x11, 255);
+ SETCOL(btheme->tarm[13].active, 0xbd, 0x6a, 0x11, 255);
+ /* set 15 */
+ SETCOL(btheme->tarm[14].solid, 0x08, 0x31, 0x0e, 255);
+ SETCOL(btheme->tarm[14].select, 0x1c, 0x43, 0x0b, 255);
+ SETCOL(btheme->tarm[14].active, 0x34, 0x62, 0x2b, 255);
+
/* space view3d */
SETCOL(btheme->tv3d.back, 115, 115, 115, 255);
SETCOL(btheme->tv3d.text, 0, 0, 0, 255);
@@ -397,6 +463,7 @@ void BIF_InitTheme(void)
SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
btheme->tv3d.facedot_size= 4;
+ SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
@@ -448,6 +515,8 @@ void BIF_InitTheme(void)
SETCOL(btheme->tact.hilite, 17, 27, 60, 100); // bar
SETCOL(btheme->tact.strip_select, 0xff, 0xff, 0xaa, 255);
SETCOL(btheme->tact.strip, 0xe4, 0x9c, 0xc6, 255);
+ SETCOL(btheme->tact.group, 0x39, 0x7d, 0x1b, 255);
+ SETCOL(btheme->tact.group_active, 0x7d, 0xe9, 0x60, 255);
/* space nla */
btheme->tnla= btheme->tv3d;
@@ -486,8 +555,16 @@ void BIF_InitTheme(void)
/* space imageselect */
btheme->timasel= btheme->tv3d;
+ SETCOL(btheme->timasel.active, 195, 195, 195, 255); /* active tile */
+ SETCOL(btheme->timasel.grid, 94, 94, 94, 255); /* active file text */
SETCOL(btheme->timasel.back, 110, 110, 110, 255);
- SETCOL(btheme->timasel.shade1, 0xaa, 0xaa, 0xba, 255);
+ SETCOL(btheme->timasel.header, 195, 195, 195, 255);
+ SETCOL(btheme->timasel.shade1, 94, 94, 94, 255); /* bar */
+ SETCOL(btheme->timasel.shade2, 172, 172, 172, 255); /* sliders */
+ SETCOL(btheme->timasel.hilite, 17, 27, 60, 100); /* selected tile */
+ SETCOL(btheme->timasel.text, 0, 0, 0, 255);
+ SETCOL(btheme->timasel.text_hi, 255, 255, 255, 255);
+ SETCOL(btheme->timasel.panel, 132, 132, 132, 255);
/* space text */
btheme->text= btheme->tv3d;
@@ -533,7 +610,7 @@ void BIF_InitTheme(void)
char *BIF_ThemeColorsPup(int spacetype)
{
- char *cp= MEM_callocN(32*32, "theme pup");
+ char *cp= MEM_callocN(32*64, "theme pup");
char *str = cp;
if(spacetype==0) {
@@ -591,9 +668,11 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Face Selected (transp) %%x%d|", TH_FACE_SELECT);
str += sprintf(str, "Face Dot Selected %%x%d|", TH_FACE_DOT);
str += sprintf(str, "Face Dot Size %%x%d|", TH_FACEDOT_SIZE);
+ str += sprintf(str, "Active Vert/Edge/Face %%x%d|", TH_EDITMESH_ACTIVE);
str += sprintf(str, "Normal %%x%d|", TH_NORMAL);
str += sprintf(str, "Bone Solid %%x%d|", TH_BONE_SOLID);
- str += sprintf(str, "Bone Pose %%x%d", TH_BONE_POSE);
+ str += sprintf(str, "Bone Pose %%x%d|", TH_BONE_POSE);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_IPO:
str += sprintf(str, "Panel %%x%d|", TH_PANEL);
@@ -604,6 +683,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Vertex %%x%d|", TH_VERTEX);
str += sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT);
str += sprintf(str, "Vertex Size %%x%d|", TH_VERTEX_SIZE);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_FILE:
str += sprintf(str, "Selected file %%x%d", TH_HILITE);
@@ -617,6 +697,7 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Bars selected %%x%d|", TH_HILITE);
str += sprintf(str, "Strips %%x%d|", TH_STRIP);
str += sprintf(str, "Strips selected %%x%d|", TH_STRIP_SELECT);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_ACTION:
//str += sprintf(str, "Panel %%x%d|", TH_PANEL);
@@ -626,8 +707,11 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "View Sliders %%x%d|", TH_SHADE1);
str += sprintf(str, "Channels %%x%d|", TH_SHADE2);
str += sprintf(str, "Channels Selected %%x%d|", TH_HILITE);
+ str += sprintf(str, "Channel Group %%x%d|", TH_GROUP);
+ str += sprintf(str, "Active Channel Group %%x%d|", TH_GROUP_ACTIVE);
str += sprintf(str, "Long Key %%x%d|", TH_STRIP);
str += sprintf(str, "Long Key selected %%x%d|", TH_STRIP_SELECT);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_IMAGE:
str += sprintf(str, "%%l|");
@@ -649,16 +733,23 @@ char *BIF_ThemeColorsPup(int spacetype)
str += sprintf(str, "Plugin Strip %%x%d|", TH_SEQ_PLUGIN);
str += sprintf(str, "Transition Strip %%x%d|", TH_SEQ_TRANSITION);
str += sprintf(str, "Meta Strip %%x%d|", TH_SEQ_META);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_SOUND:
str += sprintf(str, "Grid %%x%d|", TH_GRID);
str += sprintf(str, "Window Slider %%x%d|", TH_SHADE1);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_BUTS:
str += sprintf(str, "Panel %%x%d|", TH_PANEL);
break;
case SPACE_IMASEL:
- str += sprintf(str, "Main Shade %%x%d|", TH_SHADE1);
+ str += sprintf(str, "Tiles %%x%d|", TH_PANEL);
+ str += sprintf(str, "Scrollbar %%x%d|", TH_SHADE1);
+ str += sprintf(str, "Scroll Handle %%x%d|", TH_SHADE2);
+ str += sprintf(str, "Selected File %%x%d|", TH_HILITE);
+ str += sprintf(str, "Active File %%x%d|", TH_ACTIVE);
+ str += sprintf(str, "Active File Text%%x%d|", TH_GRID);
break;
case SPACE_TEXT:
str += sprintf(str, "Scroll Bar %%x%d|", TH_SHADE1);
@@ -673,6 +764,7 @@ char *BIF_ThemeColorsPup(int spacetype)
break;
case SPACE_TIME:
str += sprintf(str, "Grid %%x%d|", TH_GRID);
+ str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
break;
case SPACE_NODE:
str += sprintf(str, "Wires %%x%d|", TH_WIRE);
diff --git a/source/blender/src/retopo.c b/source/blender/src/retopo.c
index 3f93edee9cd..60be622e3ad 100644
--- a/source/blender/src/retopo.c
+++ b/source/blender/src/retopo.c
@@ -85,7 +85,7 @@ typedef struct RetopoPaintHit {
float where;
} RetopoPaintHit;
-void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj);
+void retopo_do_2d(View3D *v3d, double proj[2], float *v, char adj);
void retopo_paint_debug_print(RetopoPaintData *rpd);
/* Painting */
@@ -295,7 +295,8 @@ void retopo_paint_apply()
for(i=0; i<hitcount; ++i) {
RetopoPaintPoint *intersection= BLI_findlink(&rpd->intersections,i);
- retopo_do_2d(rpd->paint_v3d,&intersection->loc.x, hitco, 1);
+ double proj[2] = {intersection->loc.x, intersection->loc.y};
+ retopo_do_2d(rpd->paint_v3d, proj, hitco, 1);
intersection->eve= addvertlist(hitco, NULL);
intersection->eve->f= SELECT;
}
@@ -320,12 +321,16 @@ void retopo_paint_apply()
void add_rppoint(RetopoPaintLine *l, short x, short y)
{
RetopoPaintPoint *p= MEM_callocN(sizeof(RetopoPaintPoint),"RetopoPaintPoint");
+ double proj[2];
p->loc.x= x;
p->loc.y= y;
BLI_addtail(&l->points,p);
p->index= p->prev?p->prev->index+1:0;
- retopo_do_2d(G.editMesh->retopo_paint_data->paint_v3d, &p->loc.x, p->co, 1);
+ proj[0] = p->loc.x;
+ proj[1] = p->loc.y;
+
+ retopo_do_2d(G.editMesh->retopo_paint_data->paint_v3d, proj, p->co, 1);
}
RetopoPaintLine *add_rpline(RetopoPaintData *rpd)
{
@@ -447,11 +452,8 @@ void retopo_force_update()
if(vd) {
if(vd->depths) vd->depths->damaged= 1;
retopo_queue_updates(vd);
- if(retopo_mesh_paint_check() && vd->retopo_view_data) {
- /* Force redraw */
- drawview3dspace(vd->area, vd);
- retopo_paint_view_update(vd);
- }
+ if(retopo_mesh_paint_check() && vd->retopo_view_data)
+ allqueue(REDRAWVIEW3D, 0);
}
}
}
@@ -749,13 +751,13 @@ void retopo_toggle(void *j1,void *j2)
allqueue(REDRAWVIEW3D, 0);
}
-void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj)
+void retopo_do_2d(View3D *v3d, double proj[2], float *v, char adj)
{
/* Check to make sure vert is visible in window */
if(proj[0]>0 && proj[1]>0 && proj[0] < v3d->depths->w && proj[1] < v3d->depths->h) {
- float depth= v3d->depths->depths[(int)(proj[1]*v3d->depths->w+proj[0])];
+ float depth= v3d->depths->depths[((int)proj[1])*v3d->depths->w+((int)proj[0])];
double px, py, pz;
-
+
/* Don't modify the point if it'll be mapped to the background */
if(depth==v3d->depths->depth_range[1]) {
if(adj) {
@@ -781,14 +783,11 @@ void retopo_do_2d(View3D *v3d, short proj[2], float *v, char adj)
void retopo_do_vert(View3D *v3d, float *v)
{
- short proj[2];
- double px, py, pz;
+ double proj[3];
/* Find 2D location (project) */
gluProject(v[0],v[1],v[2],v3d->retopo_view_data->mats.modelview,v3d->retopo_view_data->mats.projection,
- (GLint *)v3d->retopo_view_data->mats.viewport,&px,&py,&pz);
- proj[0]= px;
- proj[1]= py;
+ (GLint *)v3d->retopo_view_data->mats.viewport,&proj[0],&proj[1],&proj[2]);
retopo_do_2d(v3d,proj,v,0);
}
@@ -839,7 +838,7 @@ void retopo_do_all()
bp= nu->bp;
for(i=0; i<nu->pntsv; ++i) {
for(j=0; j<nu->pntsu; ++j, ++bp) {
- if(bp->f1 & 1)
+ if(bp->f1 & SELECT)
retopo_do_vert(G.vd,bp->vec);
}
}
diff --git a/source/blender/src/sculptmode-stroke.c b/source/blender/src/sculptmode-stroke.c
new file mode 100644
index 00000000000..455112343e9
--- /dev/null
+++ b/source/blender/src/sculptmode-stroke.c
@@ -0,0 +1,284 @@
+/*
+ * $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 by Nicholas Bishop
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Storage and manipulation of sculptmode brush strokes.
+ *
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_sculpt.h"
+#include "BLI_blenlib.h"
+#include "BIF_gl.h"
+
+#include "BDR_sculptmode.h"
+
+#include <math.h>
+
+/* Temporary storage of input stroke control points */
+typedef struct StrokePoint {
+ struct StrokePoint *next, *prev;
+ short x, y;
+} StrokePoint;
+typedef struct SculptStroke {
+ short (*loc)[2];
+ int max;
+ int index;
+ float length;
+ ListBase final;
+ StrokePoint *final_mem;
+ float offset;
+} SculptStroke;
+
+void sculpt_stroke_new(const int max)
+{
+ SculptSession *ss = sculpt_session();
+
+ ss->stroke = MEM_callocN(sizeof(SculptStroke), "SculptStroke");
+ ss->stroke->loc = MEM_callocN(sizeof(short) * 4 * max, "SculptStroke.loc");
+ ss->stroke->max = max;
+ ss->stroke->index = -1;
+}
+
+void sculpt_stroke_free()
+{
+ SculptSession *ss = sculpt_session();
+ if(ss && ss->stroke) {
+ if(ss->stroke->loc) MEM_freeN(ss->stroke->loc);
+ if(ss->stroke->final_mem) MEM_freeN(ss->stroke->final_mem);
+
+ MEM_freeN(ss->stroke);
+ ss->stroke = NULL;
+ }
+}
+
+void sculpt_stroke_add_point(const short x, const short y)
+{
+ SculptStroke *stroke = sculpt_session()->stroke;
+ const int next = stroke->index + 1;
+
+ if(stroke->index == -1) {
+ stroke->loc[0][0] = x;
+ stroke->loc[0][1] = y;
+ stroke->index = 0;
+ }
+ else if(next < stroke->max) {
+ const int dx = x - stroke->loc[stroke->index][0];
+ const int dy = y - stroke->loc[stroke->index][1];
+ stroke->loc[next][0] = x;
+ stroke->loc[next][1] = y;
+ stroke->length += sqrt(dx*dx + dy*dy);
+ stroke->index = next;
+ }
+}
+
+void sculpt_stroke_smooth(SculptStroke *stroke)
+{
+ /* Apply smoothing (exclude the first and last points)*/
+ StrokePoint *p = stroke->final.first;
+ if(p && p->next && p->next->next) {
+ for(p = p->next->next; p && p->next && p->next->next; p = p->next) {
+ p->x = p->prev->prev->x*0.1 + p->prev->x*0.2 + p->x*0.4 + p->next->x*0.2 + p->next->next->x*0.1;
+ p->y = p->prev->prev->y*0.1 + p->prev->y*0.2 + p->y*0.4 + p->next->y*0.2 + p->next->next->y*0.1;
+ }
+ }
+}
+
+static void sculpt_stroke_create_final()
+{
+ SculptStroke *stroke = sculpt_session()->stroke;
+
+ if(stroke) {
+ StrokePoint *p, *pnext;
+ int i;
+
+ /* Copy loc into final */
+ if(stroke->final_mem)
+ MEM_freeN(stroke->final_mem);
+ stroke->final_mem = MEM_callocN(sizeof(StrokePoint) * (stroke->index + 1) * 2, "SculptStroke.final");
+ stroke->final.first = stroke->final.last = NULL;
+ for(i = 0; i <= stroke->index; ++i) {
+ p = &stroke->final_mem[i];
+ p->x = stroke->loc[i][0];
+ p->y = stroke->loc[i][1];
+ BLI_addtail(&stroke->final, p);
+ }
+
+ /* Remove shortest edges */
+ if(stroke->final.first) {
+ for(p = ((StrokePoint*)stroke->final.first)->next; p && p->next; p = pnext) {
+ const int dx = p->x - p->prev->x;
+ const int dy = p->y - p->prev->y;
+ const float len = sqrt(dx*dx + dy*dy);
+ pnext = p->next;
+ if(len < 10) {
+ BLI_remlink(&stroke->final, p);
+ }
+ }
+ }
+
+ sculpt_stroke_smooth(stroke);
+
+ /* Subdivide edges */
+ for(p = stroke->final.first; p && p->next; p = pnext) {
+ StrokePoint *np = &stroke->final_mem[i++];
+
+ pnext = p->next;
+ np->x = (p->x + p->next->x) / 2;
+ np->y = (p->y + p->next->y) / 2;
+ BLI_insertlink(&stroke->final, p, np);
+ }
+
+ sculpt_stroke_smooth(stroke);
+ }
+}
+
+float sculpt_stroke_seglen(StrokePoint *p1, StrokePoint *p2)
+{
+ int dx = p2->x - p1->x;
+ int dy = p2->y - p1->y;
+ return sqrt(dx*dx + dy*dy);
+}
+
+float sculpt_stroke_final_length(SculptStroke *stroke)
+{
+ StrokePoint *p;
+ float len = 0;
+ for(p = stroke->final.first; p && p->next; ++p)
+ len += sculpt_stroke_seglen(p, p->next);
+ return len;
+}
+
+/* If partial is nonzero, cuts off apply after that length has been processed */
+static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct BrushAction *a, const int partial)
+{
+ const int sdspace = sculpt_data()->spacing;
+ const short spacing = sdspace > 0 ? sdspace : 2;
+ const int dots = sculpt_stroke_final_length(stroke) / spacing;
+ int i;
+ StrokePoint *p = stroke->final.first;
+ float startloc = stroke->offset;
+
+ for(i = 0; i < dots && p && p->next; ++i) {
+ const float dotloc = spacing * i;
+ short co[2];
+ float len = sculpt_stroke_seglen(p, p->next);
+ float u, v;
+
+ /* Find edge containing dot */
+ while(dotloc > startloc + len && p && p->next && p->next->next) {
+ p = p->next;
+ startloc += len;
+ len = sculpt_stroke_seglen(p, p->next);
+ }
+
+ if(!p || !p->next || dotloc > startloc + len)
+ break;
+
+ if(partial && startloc > partial) {
+ /* Calculate offset for next stroke segment */
+ stroke->offset = startloc + len - dotloc;
+ break;
+ }
+
+ u = (dotloc - startloc) / len;
+ v = 1 - u;
+
+ co[0] = p->x*v + p->next->x*u;
+ co[1] = p->y*v + p->next->y*u;
+
+ do_symmetrical_brush_actions(a, co, NULL);
+ }
+
+ return p ? p->next : NULL;
+}
+
+void sculpt_stroke_apply(struct BrushAction *a)
+{
+ SculptStroke *stroke = sculpt_session()->stroke;
+ /* TODO: make these values user-modifiable? */
+ const int partial_len = 100;
+ const int min_len = 200;
+
+ if(stroke) {
+ sculpt_stroke_create_final();
+
+ if(sculpt_stroke_final_length(stroke) > min_len) {
+ StrokePoint *p = sculpt_stroke_apply_generic(stroke, a, partial_len);
+
+ /* Replace remaining values in stroke->loc with remaining stroke->final values */
+ stroke->index = -1;
+ stroke->length = 0;
+ for(; p; p = p->next) {
+ ++stroke->index;
+ stroke->loc[stroke->index][0] = p->x;
+ stroke->loc[stroke->index][1] = p->y;
+ if(p->next) {
+ stroke->length += sculpt_stroke_seglen(p, p->next);
+ }
+ }
+ }
+ }
+}
+
+void sculpt_stroke_apply_all(struct BrushAction *a)
+{
+ SculptStroke *stroke = sculpt_session()->stroke;
+
+ sculpt_stroke_create_final();
+
+ if(stroke) {
+ sculpt_stroke_apply_generic(stroke, a, 0);
+ }
+}
+
+void sculpt_stroke_draw()
+{
+ SculptStroke *stroke = sculpt_session()->stroke;
+
+ if(stroke) {
+ StrokePoint *p;
+
+ /* Draws the original stroke */
+ /*glColor3f(1, 0, 0);
+ glBegin(GL_LINE_STRIP);
+ for(i = 0; i <= stroke->index; ++i)
+ glVertex2s(stroke->loc[i][0], stroke->loc[i][1]);
+ glEnd();*/
+
+ /* Draws the smoothed stroke */
+ glColor3f(0, 1, 0);
+ glBegin(GL_LINE_STRIP);
+ for(p = stroke->final.first; p; p = p->next)
+ glVertex2s(p->x, p->y);
+ glEnd();
+ }
+}
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index 0497460ac2a..3fda71bf828 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -53,6 +53,7 @@
#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_color_types.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
@@ -64,8 +65,10 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_sculpt.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BKE_colortools.h"
#include "BIF_editkey.h"
#include "BIF_editview.h"
@@ -73,6 +76,7 @@
#include "BIF_gl.h"
#include "BIF_interface.h"
#include "BIF_mywindow.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
#include "BIF_space.h"
@@ -101,6 +105,9 @@
/* Number of vertices to average in order to determine the flatten distance */
#define FLATTEN_SAMPLE_SIZE 10
+/* Texture cache size */
+#define TC_SIZE 256
+
/* ===== STRUCTS =====
*
*/
@@ -121,36 +128,47 @@ typedef struct ActiveData {
float dist;
} ActiveData;
-typedef struct GrabData {
+typedef struct BrushActionSymm {
+ float center_3d[3];
+ char index;
+
+ float up[3], right[3], out[3];
+
+ /* Grab brush */
+ float grab_delta[3];
+} BrushActionSymm;
+
+typedef struct BrushAction {
+ BrushActionSymm symm;
+
char firsttime;
- ListBase active_verts[8];
- unsigned char index;
- vec3f delta, delta_symm;
- float depth;
-} GrabData;
-typedef struct EditData {
- vec3f center;
- float size;
- char flip;
- short mouse[2];
+ /* Some brushes need access to original mesh vertices */
+ vec3f *mesh_store;
+ short (*orig_norms)[3];
- /* Adjust brush strength along each axis
- to adjust for object scaling */
- float scale[3];
+ short mouse[2];
+ float size_3d;
- /* View normals */
- vec3f up, right, out;
+ float prev_radius;
+ float radius;
- GrabData *grabdata;
float *layer_disps;
- vec3f *layer_store;
-
+ char flip;
+
char clip[3];
float cliptol[3];
-
- char symm;
-} EditData;
+
+ float anchored_rot;
+
+ /* Grab brush */
+ ListBase grab_active_verts[8];
+ float depth;
+
+ /* Adjust brush strength along each axis
+ to adjust for object scaling */
+ float scale[3];
+} BrushAction;
typedef struct RectNode {
struct RectNode *next, *prev;
@@ -166,7 +184,6 @@ typedef struct ProjVert {
char inside;
} ProjVert;
-static ProjVert *projverts= NULL;
static Object *active_ob= NULL;
SculptData *sculpt_data(void)
@@ -175,6 +192,8 @@ SculptData *sculpt_data(void)
}
void sculpt_init_session(void);
+void init_brushaction(BrushAction *a, short *, short *);
+void sculpt_undo_push(const short);
SculptSession *sculpt_session(void)
{
@@ -188,93 +207,13 @@ SculptSession *sculpt_session(void)
* Allocate/initialize/free data
*/
-/* Initialize 'permanent' sculpt data that is saved with file kept after
- switching out of sculptmode. */
-void sculptmode_init(Scene *sce)
-{
- SculptData *sd;
-
- if(!sce) {
- error("Unable to initialize sculptmode: bad scene");
- return;
- }
-
- sd= &sce->sculptdata;
-
- memset(sd, 0, sizeof(SculptData));
-
- sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size =
- sd->inflatebrush.size = sd->grabbrush.size =
- sd->layerbrush.size = sd->flattenbrush.size = 50;
- sd->drawbrush.strength = sd->smoothbrush.strength =
- sd->pinchbrush.strength = sd->inflatebrush.strength =
- sd->grabbrush.strength = sd->layerbrush.strength =
- sd->flattenbrush.strength = 25;
- sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1;
- sd->drawbrush.airbrush = sd->smoothbrush.airbrush =
- sd->pinchbrush.airbrush = sd->inflatebrush.airbrush =
- sd->layerbrush.airbrush = sd->flattenbrush.airbrush = 0;
- sd->drawbrush.view= 0;
- sd->brush_type= DRAW_BRUSH;
- sd->texact= -1;
- sd->texfade= 1;
- sd->averaging= 1;
- sd->texsep= 0;
- sd->texrept= SCULPTREPT_DRAG;
- sd->draw_flag= SCULPTDRAW_BRUSH;
- sd->tablet_size=3;
- sd->tablet_strength=10;
-}
-
-void sculptmode_free_session(Scene *);
void sculpt_init_session(void)
{
if(sculpt_data()->session)
- sculptmode_free_session(G.scene);
+ sculptsession_free(G.scene);
sculpt_data()->session= MEM_callocN(sizeof(SculptSession), "SculptSession");
}
-void sculptmode_free_vertexusers(SculptSession *ss)
-{
- if(ss && ss->vertex_users){
- MEM_freeN(ss->vertex_users);
- MEM_freeN(ss->vertex_users_mem);
- ss->vertex_users= NULL;
- ss->vertex_users_mem= NULL;
- ss->vertex_users_size= 0;
- }
-}
-
-void sculptmode_propset_end(SculptSession *ss, int);
-void sculptmode_free_session(Scene *sce)
-{
- SculptSession *ss= sce->sculptdata.session;
- if(ss) {
- sculptmode_free_vertexusers(ss);
- if(ss->texcache)
- MEM_freeN(ss->texcache);
- sculptmode_propset_end(ss, 1);
- MEM_freeN(ss);
- sce->sculptdata.session= NULL;
- }
-}
-
-void sculptmode_free_all(Scene *sce)
-{
- SculptData *sd= &sce->sculptdata;
- int a;
-
- sculptmode_free_session(sce);
-
- for(a=0; a<MAX_MTEX; a++) {
- MTex *mtex= sd->mtex[a];
- if(mtex) {
- if(mtex->tex) mtex->tex->id.us--;
- MEM_freeN(mtex);
- }
- }
-}
-
/* vertex_users is an array of Lists that store all the faces that use a
particular vertex. vertex_users is in the same order as mesh.mvert */
void calc_vertex_users()
@@ -284,7 +223,7 @@ void calc_vertex_users()
IndexNode *node= NULL;
Mesh *me= get_mesh(OBACT);
- sculptmode_free_vertexusers(ss);
+ sculpt_vertexusers_free(ss);
/* For efficiency, use vertex_users_mem as a memory pool (may be larger
than necessary if mesh has triangles, but only one alloc is needed.) */
@@ -338,7 +277,9 @@ void init_sculptmatrices()
glPushMatrix();
glMultMatrixf(OBACT->obmat);
- bgl_get_mats(&ss->mats);
+ if(!ss->mats)
+ ss->mats = MEM_callocN(sizeof(bglMats), "sculpt bglmats");
+ bgl_get_mats(ss->mats);
glPopMatrix();
@@ -367,32 +308,39 @@ float get_depth(short x, short y)
/* Uses window coordinates (x,y) and depth component z to find a point in
modelspace */
-vec3f unproject(const short x, const short y, const float z)
+void unproject(float out[3], const short x, const short y, const float z)
{
SculptSession *ss= sculpt_session();
double ux, uy, uz;
- vec3f p;
-
- gluUnProject(x,y,z, ss->mats.modelview, ss->mats.projection,
- (GLint *)ss->mats.viewport, &ux, &uy, &uz );
- p.x= ux;
- p.y= uy;
- p.z= uz;
- return p;
+
+ gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection,
+ (GLint *)ss->mats->viewport, &ux, &uy, &uz );
+ out[0] = ux;
+ out[1] = uy;
+ out[2] = uz;
}
/* Convert a point in model coordinates to 2D screen coordinates. */
-void project(const float v[3], short p[2])
+static void projectf(const float v[3], float p[2])
{
SculptSession *ss= sculpt_session();
double ux, uy, uz;
- gluProject(v[0],v[1],v[2], ss->mats.modelview, ss->mats.projection,
- (GLint *)ss->mats.viewport, &ux, &uy, &uz);
+ gluProject(v[0],v[1],v[2], ss->mats->modelview, ss->mats->projection,
+ (GLint *)ss->mats->viewport, &ux, &uy, &uz);
p[0]= ux;
p[1]= uy;
}
+static void project(const float v[3], short p[2])
+{
+ float f[2];
+ projectf(v, f);
+
+ p[0]= f[0];
+ p[1]= f[1];
+}
+
/* ===== Sculpting =====
*
*/
@@ -421,13 +369,14 @@ char brush_size()
/* Return modified brush strength. Includes the direction of the brush, positive
values pull vertices, negative values push. Uses tablet pressure and a
special multiplier found experimentally to scale the strength factor. */
-float brush_strength(EditData *e)
+float brush_strength(BrushAction *a)
{
const BrushData* b= sculptmode_brush();
float dir= b->dir==1 ? 1 : -1;
float pressure= 1;
short activedevice= get_activedevice();
- float flip= e->flip ? -1:1;
+ float flip= a->flip ? -1:1;
+ float anchored = b->flag & SCULPT_BRUSH_ANCHORED ? 25 : 1;
const float strength_factor= G.scene->sculptdata.tablet_strength / 10.0f;
if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER))
@@ -441,28 +390,28 @@ float brush_strength(EditData *e)
switch(G.scene->sculptdata.brush_type){
case DRAW_BRUSH:
case LAYER_BRUSH:
- return b->strength / 5000.0f * dir * pressure * flip;
+ return b->strength / 5000.0f * dir * pressure * flip * anchored;
case SMOOTH_BRUSH:
- return b->strength / 50.0f * pressure;
+ return b->strength / 50.0f * pressure * anchored;
case PINCH_BRUSH:
- return b->strength / 1000.0f * dir * pressure * flip;
+ return b->strength / 1000.0f * dir * pressure * flip * anchored;
case GRAB_BRUSH:
return 1;
case INFLATE_BRUSH:
- return b->strength / 5000.0f * dir * pressure * flip;
+ return b->strength / 5000.0f * dir * pressure * flip * anchored;
case FLATTEN_BRUSH:
- return b->strength / 500.0f * pressure;
+ return b->strength / 500.0f * pressure * anchored;
default:
return 0;
}
}
/* For clipping against a mirror modifier */
-void sculpt_clip(const EditData *e, float *co, const float val[3])
+void sculpt_clip(const BrushAction *a, float *co, const float val[3])
{
char i;
for(i=0; i<3; ++i) {
- if(e->clip[i] && (fabs(co[i]) <= e->cliptol[i]))
+ if(a->clip[i] && (fabs(co[i]) <= a->cliptol[i]))
co[i]= 0.0f;
else
co[i]= val[i];
@@ -471,42 +420,56 @@ void sculpt_clip(const EditData *e, float *co, const float val[3])
/* Currently only for the draw brush; finds average normal for all active
vertices */
-vec3f calc_area_normal(const vec3f *outdir, const ListBase* active_verts)
+void calc_area_normal(float out[3], const BrushAction *a, const float *outdir, const ListBase* active_verts)
{
- Mesh *me= get_mesh(OBACT);
- vec3f area_normal= {0,0,0};
- ActiveData *node= active_verts->first;
- const int view= sculpt_data()->brush_type==DRAW_BRUSH ? sculptmode_brush()->view : 0;
+ Mesh *me = get_mesh(OBACT);
+ ActiveData *node = active_verts->first;
+ const int view = sculpt_data()->brush_type==DRAW_BRUSH ? sculptmode_brush()->view : 0;
- while(node){
- area_normal.x+= me->mvert[node->Index].no[0];
- area_normal.y+= me->mvert[node->Index].no[1];
- area_normal.z+= me->mvert[node->Index].no[2];
- node= node->next;
+ out[0] = out[1] = out[2] = 0;
+
+ if(sculptmode_brush()->flag & SCULPT_BRUSH_ANCHORED) {
+ for(; node; node = node->next) {
+ out[0] += a->orig_norms[node->Index][0];
+ out[1] += a->orig_norms[node->Index][1];
+ out[2] += a->orig_norms[node->Index][2];
+ }
+ }
+ else {
+ for(; node; node = node->next) {
+ out[0] += me->mvert[node->Index].no[0];
+ out[1] += me->mvert[node->Index].no[1];
+ out[2] += me->mvert[node->Index].no[2];
+ }
}
- Normalize(&area_normal.x);
+
+ Normalize(out);
+
if(outdir) {
- area_normal.x= outdir->x * view + area_normal.x * (10-view);
- area_normal.y= outdir->y * view + area_normal.y * (10-view);
- area_normal.z= outdir->z * view + area_normal.z * (10-view);
+ out[0] = outdir[0] * view + out[0] * (10-view);
+ out[1] = outdir[1] * view + out[1] * (10-view);
+ out[2] = outdir[2] * view + out[2] * (10-view);
}
- Normalize(&area_normal.x);
- return area_normal;
+
+ Normalize(out);
}
-void do_draw_brush(const EditData *e, const ListBase* active_verts)
+
+void do_draw_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
- const vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ float area_normal[3];
ActiveData *node= active_verts->first;
+ calc_area_normal(area_normal, a, a->symm.out, active_verts);
+
while(node){
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+area_normal.x*node->Fade*e->scale[0],
- co[1]+area_normal.y*node->Fade*e->scale[1],
- co[2]+area_normal.z*node->Fade*e->scale[2]};
+ const float val[3]= {co[0]+area_normal[0]*node->Fade*a->scale[0],
+ co[1]+area_normal[1]*node->Fade*a->scale[1],
+ co[2]+area_normal[2]*node->Fade*a->scale[2]};
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
@@ -562,7 +525,7 @@ vec3f neighbor_average(const int vert)
return avg;
}
-void do_smooth_brush(const EditData *e, const ListBase* active_verts)
+void do_smooth_brush(const BrushAction *a, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
Mesh *me= get_mesh(OBACT);
@@ -573,53 +536,55 @@ void do_smooth_brush(const EditData *e, const ListBase* active_verts)
const float val[3]= {co[0]+(avg.x-co[0])*node->Fade,
co[1]+(avg.y-co[1])*node->Fade,
co[2]+(avg.z-co[2])*node->Fade};
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-void do_pinch_brush(const EditData *e, const ListBase* active_verts)
+void do_pinch_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
while(node) {
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+(e->center.x-co[0])*node->Fade,
- co[1]+(e->center.y-co[1])*node->Fade,
- co[2]+(e->center.z-co[2])*node->Fade};
- sculpt_clip(e, co, val);
+ const float val[3]= {co[0]+(a->symm.center_3d[0]-co[0])*node->Fade,
+ co[1]+(a->symm.center_3d[1]-co[1])*node->Fade,
+ co[2]+(a->symm.center_3d[2]-co[2])*node->Fade};
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-void do_grab_brush(EditData *e)
+void do_grab_brush(BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
- ActiveData *node= e->grabdata->active_verts[e->grabdata->index].first;
+ ActiveData *node= a->grab_active_verts[a->symm.index].first;
float add[3];
while(node) {
float *co= me->mvert[node->Index].co;
- VecCopyf(add, &e->grabdata->delta_symm.x);
+ VecCopyf(add, a->symm.grab_delta);
VecMulf(add, node->Fade);
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void do_layer_brush(EditData *e, const ListBase *active_verts)
+void do_layer_brush(BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
- vec3f area_normal= calc_area_normal(NULL, active_verts);
+ float area_normal[3];
ActiveData *node= active_verts->first;
- const float bstr= brush_strength(e);
+ const float bstr= brush_strength(a);
+
+ calc_area_normal(area_normal, a, NULL, active_verts);
while(node){
- float *disp= &e->layer_disps[node->Index];
+ float *disp= &a->layer_disps[node->Index];
if((bstr > 0 && *disp < bstr) ||
(bstr < 0 && *disp > bstr)) {
@@ -636,10 +601,10 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
{
- const float val[3]= {e->layer_store[node->Index].x+area_normal.x * *disp*e->scale[0],
- e->layer_store[node->Index].y+area_normal.y * *disp*e->scale[1],
- e->layer_store[node->Index].z+area_normal.z * *disp*e->scale[2]};
- sculpt_clip(e, co, val);
+ const float val[3]= {a->mesh_store[node->Index].x+area_normal[0] * *disp*a->scale[0],
+ a->mesh_store[node->Index].y+area_normal[1] * *disp*a->scale[1],
+ a->mesh_store[node->Index].z+area_normal[2] * *disp*a->scale[2]};
+ sculpt_clip(a, co, val);
}
}
@@ -647,7 +612,7 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
}
-void do_inflate_brush(const EditData *e, const ListBase *active_verts)
+void do_inflate_brush(const BrushAction *a, const ListBase *active_verts)
{
ActiveData *node= active_verts->first;
float add[3];
@@ -661,18 +626,18 @@ void do_inflate_brush(const EditData *e, const ListBase *active_verts)
add[1]= no[1]/ 32767.0f;
add[2]= no[2]/ 32767.0f;
VecMulf(add, node->Fade);
- add[0]*= e->scale[0];
- add[1]*= e->scale[1];
- add[2]*= e->scale[2];
+ add[0]*= a->scale[0];
+ add[1]*= a->scale[1];
+ add[2]*= a->scale[2];
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co[3])
+void calc_flatten_center(Mesh *me, ActiveData *node, float co[3])
{
ActiveData *outer[FLATTEN_SAMPLE_SIZE];
int i;
@@ -695,44 +660,44 @@ void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co
VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE);
}
-void do_flatten_brush(const EditData *e, const ListBase *active_verts)
+void do_flatten_brush(const BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
/* area_normal and cntr define the plane towards which vertices are squashed */
- vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ float area_normal[3];
float cntr[3];
-
- calc_flatten_center(me, node, e, cntr);
+
+ calc_area_normal(area_normal, a, a->symm.out, active_verts);
+ calc_flatten_center(me, node, cntr);
while(node){
float *co= me->mvert[node->Index].co;
float p1[3], sub1[3], sub2[3], intr[3], val[3];
/* Find the intersection between squash-plane and vertex (along the area normal) */
- VecSubf(p1, co, &area_normal.x);
+ VecSubf(p1, co, area_normal);
VecSubf(sub1, cntr, p1);
VecSubf(sub2, co, p1);
VecSubf(intr, co, p1);
- VecMulf(intr, Inpf(&area_normal.x, sub1) / Inpf(&area_normal.x, sub2));
+ VecMulf(intr, Inpf(area_normal, sub1) / Inpf(area_normal, sub2));
VecAddf(intr, intr, p1);
VecSubf(val, intr, co);
VecMulf(val, node->Fade);
VecAddf(val, val, co);
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-/* Creates a smooth curve for the brush shape. This is the cos(x) curve from
- [0,PI] scaled to [0,len]. The range is scaled to [0,1]. */
-float simple_strength(float p, const float len)
+/* Uses the brush curve control to find a strength value between 0 and 1 */
+float curve_strength(float p, const float len)
{
if(p > len) p= len;
- return 0.5f * (cos(M_PI*p/len) + 1);
+ return curvemapping_evaluateF(G.scene->sculptdata.cumap, 0, p/len);
}
/* Uses symm to selectively flip any axis of a coordinate. */
@@ -747,7 +712,7 @@ void flip_coord(float co[3], const char symm)
}
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */
-float tex_angle(void)
+float sculpt_tex_angle(void)
{
SculptData *sd= sculpt_data();
if(sd->texact!=-1 && sd->mtex[sd->texact])
@@ -773,17 +738,44 @@ float to_deg(const float rad)
}
/* Get a pixel from the texcache at (px, py) */
-unsigned *get_texcache_pixel(const SculptSession *ss, int px, int py)
+static unsigned char get_texcache_pixel(const SculptSession *ss, int px, int py)
+{
+ unsigned *p;
+ p = ss->texcache + py * ss->texcache_w + px;
+ return ((unsigned char*)(p))[0];
+}
+
+static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float v)
{
- if(px < 0) px= 0;
- if(py < 0) py= 0;
- if(px > ss->texcache_w - 1) px= ss->texcache_w - 1;
- if(py > ss->texcache_h - 1) py= ss->texcache_h - 1;
- return ss->texcache + py * ss->texcache_w + px;
+ int x, y, x2, y2;
+ const int tc_max = TC_SIZE - 1;
+ float urat, vrat, uopp;
+
+ if(u < 0) u = 0;
+ else if(u >= TC_SIZE) u = tc_max;
+ if(v < 0) v = 0;
+ else if(v >= TC_SIZE) v = tc_max;
+
+ x = floor(u);
+ y = floor(v);
+ x2 = x + 1;
+ y2 = y + 1;
+
+ if(x2 > TC_SIZE) x2 = tc_max;
+ if(y2 > TC_SIZE) y2 = tc_max;
+
+ urat = u - x;
+ vrat = v - y;
+ uopp = 1 - urat;
+
+ return ((get_texcache_pixel(ss, x, y) * uopp +
+ get_texcache_pixel(ss, x2, y) * urat) * (1 - vrat) +
+ (get_texcache_pixel(ss, x, y2) * uopp +
+ get_texcache_pixel(ss, x2, y2) * urat) * vrat) / 255.0;
}
/* Return a multiplier for brush strength on a particular vertex. */
-float tex_strength(EditData *e, float *point, const float len,const unsigned vindex)
+float tex_strength(BrushAction *a, float *point, const float len,const unsigned vindex)
{
SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
@@ -810,25 +802,17 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
}
else if(ss->texcache) {
- const short bsize= sculptmode_brush()->size * 2;
- const short half= sculptmode_brush()->size;
- const float rot= to_rad(tex_angle());
- const unsigned tcw = ss->texcache_w, tch = ss->texcache_h;
+ const float bsize= a->radius * 2;
+ const float rot= to_rad(sculpt_tex_angle()) + a->anchored_rot;
int px, py;
- unsigned i, *p;
- ProjVert pv;
-
+ float flip[3], point_2d[2];
+
/* If the active area is being applied for symmetry, flip it
across the symmetry axis in order to project it. This insures
that the brush texture will be oriented correctly. */
- if(!e->symm)
- pv= projverts[vindex];
- else {
- float co[3];
- VecCopyf(co, point);
- flip_coord(co, e->symm);
- project(co, pv.co);
- }
+ VecCopyf(flip, point);
+ flip_coord(flip, a->symm.index);
+ projectf(flip, point_2d);
/* For Tile and Drag modes, get the 2D screen coordinates of the
and scale them up or down to the texture size. */
@@ -836,44 +820,40 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
const int sx= (const int)sd->mtex[sd->texact]->size[0];
const int sy= (const int)sd->texsep ? sd->mtex[sd->texact]->size[1] : sx;
- float fx= pv.co[0];
- float fy= pv.co[1];
+ float fx= point_2d[0];
+ float fy= point_2d[1];
float angle= atan2(fy, fx) - rot;
float len= sqrtf(fx*fx + fy*fy);
if(rot<0.001 && rot>-0.001) {
- px= pv.co[0];
- py= pv.co[1];
+ px= point_2d[0];
+ py= point_2d[1];
} else {
px= len * cos(angle) + 2000;
py= len * sin(angle) + 2000;
}
- px %= sx-1;
- py %= sy-1;
- p= get_texcache_pixel(ss, tcw*px/sx, tch*py/sy);
+ if(sx != 1)
+ px %= sx-1;
+ if(sy != 1)
+ py %= sy-1;
+ avg= get_texcache_pixel_bilinear(ss, TC_SIZE*px/sx, TC_SIZE*py/sy);
} else {
- float fx= (pv.co[0] - e->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
- float fy= (pv.co[1] - e->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
-
+ float fx= (point_2d[0] - a->mouse[0]) / bsize;
+ float fy= (point_2d[1] - a->mouse[1]) / bsize;
+
float angle= atan2(fy, fx) - rot;
float len= sqrtf(fx*fx + fy*fy);
- px= tcw/2 + len * cos(angle);
- py= tch/2 + len * sin(angle);
-
- p= get_texcache_pixel(ss, px, py);
- }
-
- avg= 0;
- for(i=0; i<3; ++i)
- avg+= ((unsigned char*)(p))[i] / 255.0f;
+ fx = len * cos(angle) + 0.5;
+ fy = len * sin(angle) + 0.5;
- avg/= 3;
+ avg= get_texcache_pixel_bilinear(ss, fx * TC_SIZE, fy * TC_SIZE);
+ }
}
if(sd->texfade)
- avg*= simple_strength(len,e->size); /* Smooth curve */
+ avg*= curve_strength(len, a->size_3d); /* Smooth curve */
return avg;
}
@@ -881,36 +861,66 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
/* Mark area around the brush as damaged. projverts are marked if they are
inside the area and the damaged rectangle in 2D screen coordinates is
added to damaged_rects. */
-void sculptmode_add_damaged_rect(EditData *e, ListBase *damaged_rects)
+void sculpt_add_damaged_rect(BrushAction *a)
{
short p[2];
- const float radius= brush_size();
RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode");
Mesh *me= get_mesh(OBACT);
+ SculptSession *ss = sculpt_session();
+ const float radius = a->radius > a->prev_radius ? a->radius : a->prev_radius;
unsigned i;
/* Find center */
- project(&e->center.x, p);
- rn->r.xmin= p[0]-radius;
- rn->r.ymin= p[1]-radius;
- rn->r.xmax= p[0]+radius;
- rn->r.ymax= p[1]+radius;
+ project(a->symm.center_3d, p);
+ rn->r.xmin= p[0] - radius;
+ rn->r.ymin= p[1] - radius;
+ rn->r.xmax= p[0] + radius;
+ rn->r.ymax= p[1] + radius;
- BLI_addtail(damaged_rects,rn);
+ BLI_addtail(&sculpt_session()->damaged_rects, rn);
/* Update insides */
for(i=0; i<me->totvert; ++i) {
- if(!projverts[i].inside) {
- if(projverts[i].co[0] > rn->r.xmin && projverts[i].co[1] > rn->r.ymin &&
- projverts[i].co[0] < rn->r.xmax && projverts[i].co[1] < rn->r.ymax) {
- projverts[i].inside= 1;
+ if(!ss->projverts[i].inside) {
+ if(ss->projverts[i].co[0] > rn->r.xmin && ss->projverts[i].co[1] > rn->r.ymin &&
+ ss->projverts[i].co[0] < rn->r.xmax && ss->projverts[i].co[1] < rn->r.ymax) {
+ ss->projverts[i].inside= 1;
}
}
}
}
-void do_brush_action(float *vertexcosnos, EditData e,
- ListBase *damaged_verts, ListBase *damaged_rects)
+/* Clears the depth buffer in each modified area. */
+void sculpt_clear_damaged_areas(SculptSession *ss)
+{
+ RectNode *rn= NULL;
+
+ for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
+ rcti clp = rn->r;
+ rcti *win = &curarea->winrct;
+
+ clp.xmin += win->xmin;
+ clp.xmax += win->xmin;
+ clp.ymin += win->ymin;
+ clp.ymax += win->ymin;
+
+ if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
+ clp.ymin < win->ymax && clp.ymax > win->ymin) {
+ if(clp.xmin < win->xmin) clp.xmin = win->xmin;
+ if(clp.ymin < win->ymin) clp.ymin = win->ymin;
+ if(clp.xmax > win->xmax) clp.xmax = win->xmax;
+ if(clp.ymax > win->ymax) clp.ymax = win->ymax;
+
+ glScissor(clp.xmin + 1, clp.ymin + 1,
+ clp.xmax - clp.xmin - 2,
+ clp.ymax - clp.ymin - 2);
+ }
+
+ glClear(GL_DEPTH_BUFFER_BIT);
+ }
+}
+
+void do_brush_action(BrushAction *a)
{
int i;
float av_dist;
@@ -918,28 +928,32 @@ void do_brush_action(float *vertexcosnos, EditData e,
ActiveData *adata= 0;
float *vert;
Mesh *me= get_mesh(OBACT);
- const float bstrength= brush_strength(&e);
+ const float bstrength= brush_strength(a);
KeyBlock *keyblock= ob_get_keyblock(OBACT);
+ SculptData *sd = sculpt_data();
+ SculptSession *ss = sculpt_session();
- sculptmode_add_damaged_rect(&e,damaged_rects);
+ sculpt_add_damaged_rect(a);
/* Build a list of all vertices that are potentially within the brush's
area of influence. Only do this once for the grab brush. */
- if(!e.grabdata || (e.grabdata && e.grabdata->firsttime)) {
+ if((sd->brush_type != GRAB_BRUSH) || a->firsttime) {
for(i=0; i<me->totvert; ++i) {
/* Projverts.inside provides a rough bounding box */
- if(projverts[i].inside) {
- vert= vertexcosnos ? &vertexcosnos[i*6] : me->mvert[i].co;
- av_dist= VecLenf(&e.center.x,vert);
- if(av_dist < e.size) {
+ if(ss->projverts[i].inside) {
+ vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co;
+ av_dist= VecLenf(a->symm.center_3d, vert);
+ if(av_dist < a->size_3d) {
adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
+
adata->Index = i;
/* Fade is used to store the final strength at which the brush
should modify a particular vertex. */
- adata->Fade= tex_strength(&e,vert,av_dist,i) * bstrength;
+ adata->Fade= tex_strength(a, vert, av_dist, i) * bstrength;
adata->dist = av_dist;
- if(e.grabdata && e.grabdata->firsttime)
- BLI_addtail(&e.grabdata->active_verts[e.grabdata->index], adata);
+
+ if(sd->brush_type == GRAB_BRUSH && a->firsttime)
+ BLI_addtail(&a->grab_active_verts[a->symm.index], adata);
else
BLI_addtail(&active_verts, adata);
}
@@ -948,29 +962,29 @@ void do_brush_action(float *vertexcosnos, EditData e,
}
/* Only act if some verts are inside the brush area */
- if(active_verts.first || (e.grabdata && e.grabdata->active_verts[e.grabdata->index].first)) {
+ if(active_verts.first || (sd->brush_type == GRAB_BRUSH && a->grab_active_verts[a->symm.index].first)) {
/* Apply one type of brush action */
switch(G.scene->sculptdata.brush_type){
case DRAW_BRUSH:
- do_draw_brush(&e, &active_verts);
+ do_draw_brush(a, &active_verts);
break;
case SMOOTH_BRUSH:
- do_smooth_brush(&e, &active_verts);
+ do_smooth_brush(a, &active_verts);
break;
case PINCH_BRUSH:
- do_pinch_brush(&e, &active_verts);
+ do_pinch_brush(a, &active_verts);
break;
case INFLATE_BRUSH:
- do_inflate_brush(&e, &active_verts);
+ do_inflate_brush(a, &active_verts);
break;
case GRAB_BRUSH:
- do_grab_brush(&e);
+ do_grab_brush(a);
break;
case LAYER_BRUSH:
- do_layer_brush(&e, &active_verts);
+ do_layer_brush(a, &active_verts);
break;
case FLATTEN_BRUSH:
- do_flatten_brush(&e, &active_verts);
+ do_flatten_brush(a, &active_verts);
break;
}
@@ -978,68 +992,61 @@ void do_brush_action(float *vertexcosnos, EditData e,
if(keyblock) {
float *co= keyblock->data;
if(co) {
- adata = e.grabdata ? e.grabdata->active_verts[e.grabdata->index].first : active_verts.first;
+ if(sd->brush_type == GRAB_BRUSH)
+ adata = a->grab_active_verts[a->symm.index].first;
+ else
+ adata = active_verts.first;
+
for(; adata; adata= adata->next)
if(adata->Index < keyblock->totelem)
VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
}
}
- if(vertexcosnos)
+ if(ss->vertexcosnos)
BLI_freelistN(&active_verts);
else {
- if(!e.grabdata)
- addlisttolist(damaged_verts, &active_verts);
+ if(sd->brush_type != GRAB_BRUSH)
+ addlisttolist(&ss->damaged_verts, &active_verts);
}
}
}
/* Flip all the editdata across the axis/axes specified by symm. Used to
calculate multiple modifications to the mesh when symmetry is enabled. */
-EditData flip_editdata(EditData *e, const char symm)
+void calc_brushdata_symm(BrushAction *a, const char symm)
{
- EditData fe= *e;
- GrabData *gd= fe.grabdata;
-
- flip_coord(&fe.center.x, symm);
- flip_coord(&fe.up.x, symm);
- flip_coord(&fe.right.x, symm);
- flip_coord(&fe.out.x, symm);
+ flip_coord(a->symm.center_3d, symm);
+ flip_coord(a->symm.up, symm);
+ flip_coord(a->symm.right, symm);
+ flip_coord(a->symm.out, symm);
- fe.symm= symm;
-
- project(&e->center.x,fe.mouse);
-
- if(gd) {
- gd->index= symm;
- gd->delta_symm= gd->delta;
- flip_coord(&gd->delta_symm.x, symm);
- }
+ a->symm.index= symm;
- return fe;
+ flip_coord(a->symm.grab_delta, symm);
}
-void do_symmetrical_brush_actions(float *vertexcosnos, EditData *e,
- ListBase *damaged_verts, ListBase *damaged_rects)
+void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2])
{
- const char symm= sculpt_data()->symm;
-
- do_brush_action(vertexcosnos, flip_editdata(e, 0), damaged_verts, damaged_rects);
-
- if(symm & SYMM_X)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X), damaged_verts, damaged_rects);
- if(symm & SYMM_Y)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Y), damaged_verts, damaged_rects);
- if(symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Z), damaged_verts, damaged_rects);
- if(symm & SYMM_X && symm & SYMM_Y)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Y), damaged_verts, damaged_rects);
- if(symm & SYMM_X && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Z), damaged_verts, damaged_rects);
- if(symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Y | SYMM_Z), damaged_verts, damaged_rects);
- if(symm & SYMM_X && symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Y | SYMM_Z), damaged_verts, damaged_rects);
+ const char symm = sculpt_data()->symm;
+ BrushActionSymm orig;
+ int i;
+
+ init_brushaction(a, co, pr_co);
+ orig = a->symm;
+ do_brush_action(a);
+
+ for(i = 1; i <= symm; ++i) {
+ if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
+ // Restore the original symmetry data
+ a->symm = orig;
+
+ calc_brushdata_symm(a, i);
+ do_brush_action(a);
+ }
+ }
+
+ a->symm = orig;
}
void add_face_normal(vec3f *norm, const MFace* face)
@@ -1079,30 +1086,48 @@ void update_damaged_vert(Mesh *me, ListBase *lb)
}
}
-void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata)
+void calc_damaged_verts(ListBase *damaged_verts, BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
+ int i;
+
+ for(i=0; i<8; ++i)
+ update_damaged_vert(me, &a->grab_active_verts[i]);
- if(grabdata) {
+ update_damaged_vert(me, damaged_verts);
+ BLI_freelistN(damaged_verts);
+ damaged_verts->first = damaged_verts->last = NULL;
+}
+
+void projverts_clear_inside(SculptSession *ss)
+{
+ Mesh *me = get_mesh(OBACT);
+ if(me) {
int i;
- for(i=0; i<8; ++i)
- update_damaged_vert(me,&grabdata->active_verts[i]);
- } else {
- update_damaged_vert(me,damaged_verts);
- BLI_freelistN(damaged_verts);
+ for(i = 0; i < me->totvert; ++i)
+ ss->projverts[i].inside = 0;
}
}
BrushData *sculptmode_brush(void)
{
SculptData *sd= &G.scene->sculptdata;
- return (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
- sd->brush_type==SMOOTH_BRUSH ? &sd->smoothbrush :
- sd->brush_type==PINCH_BRUSH ? &sd->pinchbrush :
- sd->brush_type==INFLATE_BRUSH ? &sd->inflatebrush :
- sd->brush_type==GRAB_BRUSH ? &sd->grabbrush :
- sd->brush_type==LAYER_BRUSH ? &sd->layerbrush :
- sd->brush_type==FLATTEN_BRUSH ? &sd->flattenbrush : NULL);
+
+ BrushData *bd =
+ (sd->brush_type==DRAW_BRUSH ? &sd->drawbrush :
+ sd->brush_type==SMOOTH_BRUSH ? &sd->smoothbrush :
+ sd->brush_type==PINCH_BRUSH ? &sd->pinchbrush :
+ sd->brush_type==INFLATE_BRUSH ? &sd->inflatebrush :
+ sd->brush_type==GRAB_BRUSH ? &sd->grabbrush :
+ sd->brush_type==LAYER_BRUSH ? &sd->layerbrush :
+ sd->brush_type==FLATTEN_BRUSH ? &sd->flattenbrush : NULL);
+
+ if(!bd) {
+ sculptdata_init(G.scene);
+ bd = &sd->drawbrush;
+ }
+
+ return bd;
}
void sculptmode_update_tex()
@@ -1111,7 +1136,7 @@ void sculptmode_update_tex()
SculptSession *ss= sculpt_session();
MTex *mtex = sd->mtex[sd->texact];
TexResult texres = {0};
- float x, y, step=2.0/128.0, co[3];
+ float x, y, step=2.0/TC_SIZE, co[3];
int hasrgb, ix, iy;
/* Skip Default brush shape and non-textures */
@@ -1122,15 +1147,15 @@ void sculptmode_update_tex()
ss->texcache= NULL;
}
- ss->texcache_w = ss->texcache_h = 128;
+ ss->texcache_w = ss->texcache_h = TC_SIZE;
ss->texcache = MEM_callocN(sizeof(int) * ss->texcache_w * ss->texcache_h, "Sculpt Texture cache");
if(mtex && mtex->tex) {
BKE_image_get_ibuf(sd->mtex[sd->texact]->tex->ima, NULL);
/*do normalized cannonical view coords for texture*/
- for (y=-1.0, iy=0; iy<128; iy++, y += step) {
- for (x=-1.0, ix=0; ix<128; ix++, x += step) {
+ for (y=-1.0, iy=0; iy<TC_SIZE; iy++, y += step) {
+ for (x=-1.0, ix=0; ix<TC_SIZE; ix++, x += step) {
co[0]= x;
co[1]= y;
co[2]= 0.0f;
@@ -1147,90 +1172,134 @@ void sculptmode_update_tex()
texres.tg + 0.2 * texres.tb);
texres.tin = texres.tin * 255.0;
- ((char*)ss->texcache)[(iy*128+ix)*4] = (char)texres.tin;
- ((char*)ss->texcache)[(iy*128+ix)*4+1] = (char)texres.tin;
- ((char*)ss->texcache)[(iy*128+ix)*4+2] = (char)texres.tin;
- ((char*)ss->texcache)[(iy*128+ix)*4+3] = (char)texres.tin;
+ ((char*)ss->texcache)[(iy*TC_SIZE+ix)*4] = (char)texres.tin;
+ ((char*)ss->texcache)[(iy*TC_SIZE+ix)*4+1] = (char)texres.tin;
+ ((char*)ss->texcache)[(iy*TC_SIZE+ix)*4+2] = (char)texres.tin;
+ ((char*)ss->texcache)[(iy*TC_SIZE+ix)*4+3] = (char)texres.tin;
}
}
}
}
-void init_editdata(SculptData *sd, EditData *e, short *mouse, short *pr_mouse, const char flip)
+/* pr_mouse is only used for the grab brush, can be NULL otherwise */
+void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse)
{
- const float mouse_depth= get_depth(mouse[0],mouse[1]);
- vec3f brush_edge_loc, zero_loc, oldloc;
+ SculptData *sd = sculpt_data();
+ const float mouse_depth = get_depth(mouse[0], mouse[1]);
+ float brush_edge_loc[3], zero_loc[3], oldloc[3];
ModifierData *md;
int i;
+ const char flip = (get_qual() == LR_SHIFTKEY);
+ const char anchored = sculptmode_brush()->flag & SCULPT_BRUSH_ANCHORED;
+ short orig_mouse[2], dx=0, dy=0;
+
+ a->flip = flip;
+ a->symm.index = 0;
- e->flip= flip;
+ if(a->firsttime)
+ a->depth = mouse_depth;
/* Convert the location and size of the brush to
modelspace coords */
- e->center= unproject(mouse[0],mouse[1],mouse_depth);
- brush_edge_loc= unproject(mouse[0] +
- brush_size(),mouse[1],
- mouse_depth);
- e->size= VecLenf(&e->center.x,&brush_edge_loc.x);
+ if(a->firsttime || !anchored) {
+ unproject(a->symm.center_3d, mouse[0], mouse[1], mouse_depth);
+ a->mouse[0] = mouse[0];
+ a->mouse[1] = mouse[1];
+ }
+
+ if(anchored) {
+ project(a->symm.center_3d, orig_mouse);
+ dx = mouse[0] - orig_mouse[0];
+ dy = mouse[1] - orig_mouse[1];
+ }
+
+ if(anchored) {
+ unproject(brush_edge_loc, mouse[0], mouse[1], a->depth);
+ a->anchored_rot = atan2(dy, dx);
+ }
+ else
+ unproject(brush_edge_loc, mouse[0] + brush_size(), mouse[1], mouse_depth);
+
+ a->size_3d = VecLenf(a->symm.center_3d, brush_edge_loc);
+
+ a->prev_radius = a->radius;
+
+ if(anchored)
+ a->radius = sqrt(dx*dx + dy*dy);
+ else
+ a->radius = brush_size();
+
+ /* Set the pivot to allow the model to rotate around the center of the brush */
+ if(get_depth(mouse[0],mouse[1]) < 1.0)
+ VecCopyf(&sculpt_session()->pivot.x, a->symm.center_3d);
/* Now project the Up, Right, and Out normals from view to model coords */
- zero_loc= unproject(0, 0, 0);
- e->up= unproject(0, -1, 0);
- e->right= unproject(1, 0, 0);
- e->out= unproject(0, 0, -1);
- VecSubf(&e->up.x, &e->up.x, &zero_loc.x);
- VecSubf(&e->right.x, &e->right.x, &zero_loc.x);
- VecSubf(&e->out.x, &e->out.x, &zero_loc.x);
- Normalize(&e->up.x);
- Normalize(&e->right.x);
- Normalize(&e->out.x);
+ unproject(zero_loc, 0, 0, 0);
+ unproject(a->symm.up, 0, -1, 0);
+ unproject(a->symm.right, 1, 0, 0);
+ unproject(a->symm.out, 0, 0, -1);
+ VecSubf(a->symm.up, a->symm.up, zero_loc);
+ VecSubf(a->symm.right, a->symm.right, zero_loc);
+ VecSubf(a->symm.out, a->symm.out, zero_loc);
+ Normalize(a->symm.up);
+ Normalize(a->symm.right);
+ Normalize(a->symm.out);
/* Initialize mirror modifier clipping */
for(i=0; i<3; ++i) {
- e->clip[i]= 0;
- e->cliptol[i]= 0;
+ a->clip[i]= 0;
+ a->cliptol[i]= 0;
}
for(md= OBACT->modifiers.first; md; md= md->next) {
if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
const MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
- e->clip[mmd->axis]= 1;
- if(mmd->tolerance > e->cliptol[mmd->axis])
- e->cliptol[mmd->axis]= mmd->tolerance;
+ a->clip[mmd->axis]= 1;
+ if(mmd->tolerance > a->cliptol[mmd->axis])
+ a->cliptol[mmd->axis] = mmd->tolerance;
}
}
}
if(sd->brush_type == GRAB_BRUSH) {
- vec3f gcenter;
- if(!e->grabdata) {
- e->grabdata= MEM_callocN(sizeof(GrabData),"grab data");
- e->grabdata->firsttime= 1;
- e->grabdata->depth= mouse_depth;
- }
- else
- e->grabdata->firsttime= 0;
-
+ float gcenter[3];
+
/* Find the delta */
- gcenter= unproject(mouse[0],mouse[1],e->grabdata->depth);
- oldloc= unproject(pr_mouse[0],pr_mouse[1],e->grabdata->depth);
- VecSubf(&e->grabdata->delta.x,&gcenter.x,&oldloc.x);
+ unproject(gcenter, mouse[0], mouse[1], a->depth);
+ unproject(oldloc, pr_mouse[0], pr_mouse[1], a->depth);
+ VecSubf(a->symm.grab_delta, gcenter, oldloc);
}
else if(sd->brush_type == LAYER_BRUSH) {
Mesh *me= get_mesh(OBACT);
- if(!e->layer_disps)
- e->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
- if(!e->layer_store) {
- unsigned i;
- e->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
- for(i=0; i<me->totvert; ++i)
- VecCopyf(&e->layer_store[i].x,me->mvert[i].co);
+ if(!a->layer_disps)
+ a->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
+ }
+
+ if(sd->brush_type == LAYER_BRUSH || anchored) {
+ Mesh *me= get_mesh(OBACT);
+ unsigned i;
+
+ if(!a->mesh_store) {
+ a->mesh_store= MEM_mallocN(sizeof(vec3f) * me->totvert, "Sculpt mesh store");
+ for(i = 0; i < me->totvert; ++i)
+ VecCopyf(&a->mesh_store[i].x, me->mvert[i].co);
+ }
+
+ if(anchored && a->layer_disps)
+ memset(a->layer_disps, 0, sizeof(float) * me->totvert);
+
+ if(anchored && !a->orig_norms) {
+ a->orig_norms= MEM_mallocN(sizeof(short) * 3 * me->totvert, "Sculpt orig norm");
+ for(i = 0; i < me->totvert; ++i) {
+ a->orig_norms[i][0] = me->mvert[i].no[0];
+ a->orig_norms[i][1] = me->mvert[i].no[1];
+ a->orig_norms[i][2] = me->mvert[i].no[2];
+ }
}
- }
+ }
}
-
void sculptmode_set_strength(const int delta)
{
int val = sculptmode_brush()->strength + delta;
@@ -1239,146 +1308,90 @@ void sculptmode_set_strength(const int delta)
sculptmode_brush()->strength= val;
}
-void sculptmode_propset_calctex()
+static void sculpt_radialcontrol_callback(const int mode, const int val)
{
- SculptData *sd= sculpt_data();
- SculptSession *ss= sculpt_session();
- PropsetData *pd= sculpt_session()->propset;
- if(pd) {
- int i, j;
- const int tsz = 128;
- float *d;
- if(!pd->texdata) {
- pd->texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
- if(sd->texrept!=SCULPTREPT_3D)
- sculptmode_update_tex();
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j) {
- float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
- if(sd->texfade)
- pd->texdata[i*tsz+j]= simple_strength(magn,tsz/2);
- else
- pd->texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
- }
- if(sd->texact != -1 && ss->texcache) {
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j) {
- const int col= ss->texcache[i*tsz+j];
- pd->texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
- }
- }
- }
-
- /* Adjust alpha with brush strength */
- d= MEM_dupallocN(pd->texdata);
- for(i=0; i<tsz; ++i)
- for(j=0; j<tsz; ++j)
- d[i*tsz+j]*= sculptmode_brush()->strength/200.0f+0.5f;
-
-
- if(!pd->tex)
- glGenTextures(1, (GLuint *)&pd->tex);
- glBindTexture(GL_TEXTURE_2D, pd->tex);
+ SculptSession *ss = sculpt_session();
+ BrushData *br = sculptmode_brush();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, d);
- MEM_freeN(d);
- }
+ if(mode == RADIALCONTROL_SIZE)
+ br->size = val;
+ else if(mode == RADIALCONTROL_STRENGTH)
+ br->strength = val;
+ else if(mode == RADIALCONTROL_ROTATION)
+ set_tex_angle(val);
+
+ ss->radialcontrol = NULL;
}
-void sculptmode_propset_header()
+/* Returns GL handle to brush texture */
+static GLuint sculpt_radialcontrol_calctex()
{
+ SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
- PropsetData *pd= ss ? ss->propset : NULL;
- if(pd) {
- char str[512];
- const char *name= "";
- int val= 0;
- if(pd->mode == PropsetSize) {
- name= "Size";
- val= sculptmode_brush()->size;
- }
- else if(pd->mode == PropsetStrength) {
- name= "Strength";
- val= sculptmode_brush()->strength;
- }
- else if(pd->mode == PropsetTexRot) {
- name= "Texture Angle";
- val= tex_angle();
- }
- sprintf(str, "Brush %s: %d", name, val);
- headerprint(str);
- }
-}
+ int i, j;
+ const int tsz = TC_SIZE;
+ float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
+ GLuint tex;
-void sculptmode_propset_end(SculptSession *ss, int cancel)
-{
- if(ss && ss->propset) {
- PropsetData *pd= ss->propset;
-
- if(cancel) {
- sculptmode_brush()->size= pd->origsize;
- sculptmode_brush()->strength= pd->origstrength;
- set_tex_angle(pd->origtexrot);
- } else {
- if(pd->mode != PropsetSize)
- sculptmode_brush()->size= pd->origsize;
- if(pd->mode != PropsetStrength)
- sculptmode_brush()->strength= pd->origstrength;
- if(pd->mode != PropsetTexRot)
- set_tex_angle(pd->origtexrot);
+ if(sd->texrept!=SCULPTREPT_3D)
+ sculptmode_update_tex();
+ for(i=0; i<tsz; ++i)
+ for(j=0; j<tsz; ++j) {
+ float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
+ if(sd->texfade)
+ texdata[i*tsz+j]= curve_strength(magn,tsz/2);
+ else
+ texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
}
- glDeleteTextures(1, &pd->tex);
- MEM_freeN(pd->texdata);
- MEM_freeN(pd);
- ss->propset= NULL;
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
+ if(sd->texact != -1 && ss->texcache) {
+ for(i=0; i<tsz; ++i)
+ for(j=0; j<tsz; ++j) {
+ const int col= ss->texcache[i*tsz+j];
+ texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
+ }
}
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata);
+ MEM_freeN(texdata);
+
+ return tex;
}
-void sculptmode_propset_init(PropsetMode mode)
+void sculpt_radialcontrol_start(int mode)
{
- SculptSession *ss= sculpt_session();
- PropsetData *pd= ss->propset;
- const float ang= tex_angle();
-
- if(!pd) {
- short mouse[2];
-
- pd= MEM_callocN(sizeof(PropsetData),"PropsetSize");
- ss->propset= pd;
-
- getmouseco_areawin(mouse);
- pd->origloc[0]= mouse[0];
- pd->origloc[1]= mouse[1];
-
- if(mode == PropsetSize)
- pd->origloc[0]-= sculptmode_brush()->size;
- else if(mode == PropsetStrength)
- pd->origloc[0]-= 200 - 2*sculptmode_brush()->strength;
- else if(mode == PropsetTexRot) {
- pd->origloc[0]-= 200 * cos(to_rad(ang));
- pd->origloc[1]-= 200 * sin(to_rad(ang));
+ SculptData *sd = sculpt_data();
+ SculptSession *ss = sculpt_session();
+ BrushData *br = sculptmode_brush();
+ int orig=1, max=100;
+
+ if(mode == RADIALCONTROL_SIZE) {
+ orig = br->size;
+ max = 200;
+ }
+ else if(mode == RADIALCONTROL_STRENGTH) {
+ orig = br->strength;
+ max = 100;
+ }
+ else if(mode == RADIALCONTROL_ROTATION) {
+ if(sd->texact!=-1 && sd->mtex[sd->texact]) {
+ orig = sculpt_tex_angle();
+ max = 360;
}
-
- pd->origsize= sculptmode_brush()->size;
- pd->origstrength= sculptmode_brush()->strength;
- pd->origtexrot= ang;
-
- sculptmode_propset_calctex();
-
- pd->num.idx_max= 0;
+ else
+ mode = RADIALCONTROL_NONE;
}
- pd->mode= mode;
- sculptmode_propset_header();
-
- allqueue(REDRAWVIEW3D, 0);
+ if(mode != RADIALCONTROL_NONE) {
+ ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max,
+ sculpt_radialcontrol_calctex());
+ }
}
void sculpt_paint_brush(char clear)
{
- if(sculpt_data()->draw_flag & SCULPTDRAW_BRUSH) {
+ if(sculpt_data()->flags & SCULPT_DRAW_BRUSH) {
static short mvalo[2];
short mval[2];
const short rad= sculptmode_brush()->size;
@@ -1396,90 +1409,6 @@ void sculpt_paint_brush(char clear)
}
}
-void sculptmode_propset(unsigned short event)
-{
- PropsetData *pd= sculpt_session()->propset;
- short mouse[2];
- short tmp[2];
- float dist;
- BrushData *brush= sculptmode_brush();
- char valset= 0;
-
- handleNumInput(&pd->num, event);
-
- if(hasNumInput(&pd->num)) {
- float val;
- applyNumInput(&pd->num, &val);
- if(pd->mode==PropsetSize)
- brush->size= val;
- else if(pd->mode==PropsetStrength)
- brush->strength= val;
- else if(pd->mode==PropsetTexRot)
- set_tex_angle(val);
- valset= 1;
- allqueue(REDRAWVIEW3D, 0);
- }
-
- switch(event) {
- case MOUSEX:
- case MOUSEY:
- if(!hasNumInput(&pd->num)) {
- char ctrl= G.qual & LR_CTRLKEY;
- getmouseco_areawin(mouse);
- tmp[0]= pd->origloc[0]-mouse[0];
- tmp[1]= pd->origloc[1]-mouse[1];
- dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
- if(pd->mode == PropsetSize) {
- brush->size= dist;
- if(ctrl) brush->size= (brush->size+5)/10*10;
- } else if(pd->mode == PropsetStrength) {
- float fin= (200.0f - dist) * 0.5f;
- brush->strength= fin>=0 ? fin : 0;
- if(ctrl) brush->strength= (brush->strength+5)/10*10;
- } else if(pd->mode == PropsetTexRot) {
- set_tex_angle((int)to_deg(atan2(tmp[1], tmp[0])) + 180);
- if(ctrl)
- set_tex_angle(((int)(tex_angle())+5)/10*10);
- }
- valset= 1;
- allqueue(REDRAWVIEW3D, 0);
- }
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- brush->size= pd->origsize;
- brush->strength= pd->origstrength;
- set_tex_angle(pd->origtexrot);
- case LEFTMOUSE:
- while(get_mbut()==L_MOUSE);
- case RETKEY:
- case PADENTER:
- sculptmode_propset_end(sculpt_session(), 0);
- break;
- default:
- break;
- };
-
- if(valset) {
- if(pd->mode == PropsetSize) {
- if(brush->size<1) brush->size= 1;
- if(brush->size>200) brush->size= 200;
- }
- else if(pd->mode == PropsetStrength) {
- if(brush->strength > 100) brush->strength= 100;
- sculptmode_propset_calctex();
- }
- else if(pd->mode == PropsetTexRot) {
- if(tex_angle() < 0)
- set_tex_angle(0);
- else if(tex_angle() > 360)
- set_tex_angle(360);
- }
- }
-
- sculptmode_propset_header();
-}
-
void sculptmode_selectbrush_menu(void)
{
SculptData *sd= sculpt_data();
@@ -1491,6 +1420,8 @@ void sculptmode_selectbrush_menu(void)
if(val>0) {
sd->brush_type= val;
+
+ BIF_undo_push("Brush type");
allqueue(REDRAWVIEW3D, 1);
allqueue(REDRAWBUTSEDIT, 1);
@@ -1499,18 +1430,20 @@ void sculptmode_selectbrush_menu(void)
void sculptmode_update_all_projverts(float *vertcosnos)
{
+ SculptSession *ss = sculpt_session();
Mesh *me= get_mesh(OBACT);
unsigned i;
- if(projverts) MEM_freeN(projverts);
- projverts= MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
+ if(!ss->projverts)
+ ss->projverts = MEM_mallocN(sizeof(ProjVert)*me->totvert,"ProjVerts");
+
for(i=0; i<me->totvert; ++i) {
- project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, projverts[i].co);
- projverts[i].inside= 0;
+ project(vertcosnos ? &vertcosnos[i * 6] : me->mvert[i].co, ss->projverts[i].co);
+ ss->projverts[i].inside= 0;
}
}
-void sculptmode_draw_wires(int only_damaged, Mesh *me)
+void sculptmode_draw_wires(SculptSession *ss, int only_damaged, Mesh *me)
{
int i;
@@ -1521,7 +1454,7 @@ void sculptmode_draw_wires(int only_damaged, Mesh *me)
for(i=0; i<me->totedge; i++) {
MEdge *med= &me->medge[i];
- if((!only_damaged || (projverts[med->v1].inside || projverts[med->v2].inside)) &&
+ if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
(med->flag & ME_EDGEDRAW)) {
glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
}
@@ -1535,12 +1468,14 @@ void sculptmode_draw_mesh(int only_damaged)
{
Mesh *me= get_mesh(OBACT);
int i, j, dt, drawCurrentMat = 1, matnr= -1;
+ SculptSession *ss = sculpt_session();
persp(PERSP_VIEW);
mymultmatrix(OBACT->obmat);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
init_gl_materials(OBACT, 0);
+ glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
@@ -1551,7 +1486,6 @@ void sculptmode_draw_mesh(int only_damaged)
if(dt==OB_WIRE)
glColorMask(0,0,0,0);
-
for(i=0; i<me->totface; ++i) {
MFace *f= &me->mface[i];
char inside= 0;
@@ -1564,7 +1498,7 @@ void sculptmode_draw_mesh(int only_damaged)
inside the area(s) modified by the brush */
if(only_damaged) {
for(j=0; j<(f->v4?4:3); ++j) {
- if(projverts[*((&f->v1)+j)].inside) {
+ if(ss->projverts[*((&f->v1)+j)].inside) {
inside= 1;
break;
}
@@ -1577,11 +1511,12 @@ void sculptmode_draw_mesh(int only_damaged)
glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
}
+ glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glColorMask(1,1,1,1);
if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
- sculptmode_draw_wires(only_damaged, me);
+ sculptmode_draw_wires(ss, only_damaged, me);
glDisable(GL_DEPTH_TEST);
}
@@ -1615,14 +1550,15 @@ void sculpt(void)
SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
Object *ob= OBACT;
- short mouse[2], mvalo[2], firsttime=1, mousebut;
- ListBase damaged_verts= {0,0};
- ListBase damaged_rects= {0,0};
- float *vertexcosnos= 0;
+ /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
+ short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
short modifier_calculations= 0;
- EditData e;
- RectNode *rn= NULL;
+ BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
short spacing= 32000;
+ int scissor_box[4];
+ float offsetRot;
+ int smooth_stroke = 0, i;
+ int anchored;
if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
return;
@@ -1640,10 +1576,23 @@ void sculpt(void)
ss= sd->session;
}
+ anchored = sculptmode_brush()->flag & SCULPT_BRUSH_ANCHORED;
+ smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush_type != GRAB_BRUSH) && !anchored;
+
+ if(smooth_stroke)
+ sculpt_stroke_new(256);
+
+ ss->damaged_rects.first = ss->damaged_rects.last = NULL;
+ ss->damaged_verts.first = ss->damaged_verts.last = NULL;
+ ss->vertexcosnos = NULL;
+
/* Check that vertex users are up-to-date */
- if(ob != active_ob || ss->vertex_users_size != get_mesh(ob)->totvert) {
- sculptmode_free_vertexusers(ss);
+ if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != get_mesh(ob)->totvert) {
+ sculpt_vertexusers_free(ss);
calc_vertex_users();
+ if(ss->projverts)
+ MEM_freeN(ss->projverts);
+ ss->projverts = NULL;
active_ob= ob;
}
@@ -1654,9 +1603,6 @@ void sculpt(void)
getmouseco_areawin(mvalo);
- /* Make sure sculptdata has been init'd properly */
- if(!ss->vertex_users) calc_vertex_users();
-
/* Init texture
FIXME: Shouldn't be doing this every time! */
if(sd->texrept!=SCULPTREPT_3D)
@@ -1665,9 +1611,9 @@ void sculpt(void)
getmouseco_areawin(mouse);
mvalo[0]= mouse[0];
mvalo[1]= mouse[1];
-
- if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
- else mousebut = L_MOUSE;
+ lastSigMouse[0]=mouse[0];
+ lastSigMouse[1]=mouse[1];
+ mousebut = L_MOUSE;
/* If modifier_calculations is true, then extra time must be spent
updating the mesh. This takes a *lot* longer, so it's worth
@@ -1677,145 +1623,154 @@ void sculpt(void)
init_sculptmatrices();
if(modifier_calculations)
- vertexcosnos= mesh_get_mapped_verts_nors(ob);
- sculptmode_update_all_projverts(vertexcosnos);
-
- e.grabdata= NULL;
- e.layer_disps= NULL;
- e.layer_store= NULL;
+ ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
+ sculptmode_update_all_projverts(ss->vertexcosnos);
/* Set scaling adjustment */
- e.scale[0]= 1.0f / ob->size[0];
- e.scale[1]= 1.0f / ob->size[1];
- e.scale[2]= 1.0f / ob->size[2];
+ a->scale[0]= 1.0f / ob->size[0];
+ a->scale[1]= 1.0f / ob->size[1];
+ a->scale[2]= 1.0f / ob->size[2];
/* Capture original copy */
- if(sd->draw_flag & SCULPTDRAW_FAST)
+ if(sd->flags & SCULPT_DRAW_FAST)
glAccum(GL_LOAD, 1);
+ /* Get original scissor box */
+ glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
+
+ /* For raking, get the original angle*/
+ offsetRot=sculpt_tex_angle();
+
while (get_mbut() & mousebut) {
getmouseco_areawin(mouse);
+ /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
+ if (sd->rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
+ /*Nasty looking, but just orig + new angle really*/
+ set_tex_angle(offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
+ lastSigMouse[0]=mouse[0];
+ lastSigMouse[1]=mouse[1];
+ }
- if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
+ if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
+ sculptmode_brush()->flag & SCULPT_BRUSH_AIRBRUSH) {
+ a->firsttime = firsttime;
firsttime= 0;
+ if(smooth_stroke)
+ sculpt_stroke_add_point(mouse[0], mouse[1]);
+
spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
- if(modifier_calculations && !vertexcosnos)
- vertexcosnos= mesh_get_mapped_verts_nors(ob);
-
- if(G.scene->sculptdata.brush_type != GRAB_BRUSH && (sd->spacing==0 || spacing>sd->spacing)) {
- char i;
- float t= G.scene->sculptdata.averaging-1;
- const float sub= 1/(t+1);
- t/= (t+1);
- for(i=0; i<G.scene->sculptdata.averaging; ++i) {
- short avgco[2]= {mvalo[0]*t+mouse[0]*(1-t),
- mvalo[1]*t+mouse[1]*(1-t)};
-
- init_editdata(&G.scene->sculptdata,&e,avgco,mvalo,get_qual()==LR_SHIFTKEY);
+ if(modifier_calculations && !ss->vertexcosnos)
+ ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
+
+ if(G.scene->sculptdata.brush_type != GRAB_BRUSH) {
+ if(anchored) {
+ Mesh *me = get_mesh(ob);
- if(get_depth(mouse[0],mouse[1]) < 1.0)
- ss->pivot= e.center;
+ /* Restore the mesh before continuing with anchored stroke */
+ if(a->mesh_store) {
+ for(i = 0; i < me->totvert; ++i) {
+ VecCopyf(me->mvert[i].co, &a->mesh_store[i].x);
+ me->mvert[i].no[0] = a->orig_norms[i][0];
+ me->mvert[i].no[1] = a->orig_norms[i][1];
+ me->mvert[i].no[2] = a->orig_norms[i][2];
+ }
+ }
- /* The brush always has at least one area it affects,
- right beneath the mouse. It can have up to seven
- other areas that must also be modified, if all three
- axes of symmetry are on. */
- do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
-
- t-= sub;
+ do_symmetrical_brush_actions(a, mouse, NULL);
+ }
+ else {
+ if(smooth_stroke) {
+ sculpt_stroke_apply(a);
+ }
+ else if(sd->spacing==0 || spacing>sd->spacing) {
+ do_symmetrical_brush_actions(a, mouse, NULL);
+ spacing= 0;
+ }
}
- spacing= 0;
}
- else if(sd->brush_type==GRAB_BRUSH) {
- init_editdata(&G.scene->sculptdata,&e,mouse,mvalo,0);
- ss->pivot= unproject(mouse[0],mouse[1],e.grabdata->depth);
- do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
+ else {
+ do_symmetrical_brush_actions(a, mouse, mvalo);
+ unproject(&ss->pivot.x, mouse[0], mouse[1], a->depth);
}
-
+
if(modifier_calculations || ob_get_keyblock(ob))
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !(sd->draw_flag & SCULPTDRAW_FAST)) {
- calc_damaged_verts(&damaged_verts,e.grabdata);
+ if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !(sd->flags & SCULPT_DRAW_FAST)) {
+ calc_damaged_verts(&ss->damaged_verts, a);
scrarea_do_windraw(curarea);
screen_swapbuffers();
} else { /* Optimized drawing */
- calc_damaged_verts(&damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts, a);
/* Draw the stored image to the screen */
glAccum(GL_RETURN, 1);
- /* Clear each of the area(s) modified by the brush */
- for(rn=damaged_rects.first; rn; rn= rn->next) {
- float col[3];
- rcti clp= rn->r;
- rcti *win= &curarea->winrct;
-
- clp.xmin+= win->xmin;
- clp.xmax+= win->xmin;
- clp.ymin+= win->ymin;
- clp.ymax+= win->ymin;
-
- if(clp.xmin<win->xmax && clp.xmax>win->xmin &&
- clp.ymin<win->ymax && clp.ymax>win->ymin) {
- if(clp.xmin<win->xmin) clp.xmin= win->xmin;
- if(clp.ymin<win->ymin) clp.ymin= win->ymin;
- if(clp.xmax>win->xmax) clp.xmax= win->xmax;
- if(clp.ymax>win->ymax) clp.ymax= win->ymax;
- glScissor(clp.xmin+1, clp.ymin+1,
- clp.xmax-clp.xmin-2,clp.ymax-clp.ymin-2);
- }
-
- BIF_GetThemeColor3fv(TH_BACK, col);
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
- }
+ sculpt_clear_damaged_areas(ss);
/* Draw all the polygons that are inside the modified area(s) */
- glDisable(GL_SCISSOR_TEST);
+ glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
sculptmode_draw_mesh(1);
glAccum(GL_LOAD, 1);
- glEnable(GL_SCISSOR_TEST);
+
+ projverts_clear_inside(ss);
+
+ persp(PERSP_WIN);
+ glDisable(GL_DEPTH_TEST);
/* Draw cursor */
- if(sculpt_data()->draw_flag & SCULPTDRAW_BRUSH) {
- persp(PERSP_WIN);
- glDisable(GL_DEPTH_TEST);
+ if(sculpt_data()->flags & SCULPT_DRAW_BRUSH)
fdrawXORcirc((float)mouse[0],(float)mouse[1],sculptmode_brush()->size);
- }
+ if(smooth_stroke)
+ sculpt_stroke_draw();
myswapbuffers();
}
- BLI_freelistN(&damaged_rects);
+ BLI_freelistN(&ss->damaged_rects);
+ ss->damaged_rects.first = ss->damaged_rects.last = NULL;
mvalo[0]= mouse[0];
mvalo[1]= mouse[1];
- if(vertexcosnos) {
- MEM_freeN(vertexcosnos);
- vertexcosnos= NULL;
+ if(ss->vertexcosnos) {
+ MEM_freeN(ss->vertexcosnos);
+ ss->vertexcosnos= NULL;
}
}
else BIF_wait_for_statechange();
}
- if(projverts) MEM_freeN(projverts);
- projverts= NULL;
- if(e.layer_disps) MEM_freeN(e.layer_disps);
- if(e.layer_store) MEM_freeN(e.layer_store);
- /* Free GrabData */
- if(e.grabdata) {
- int i;
- for(i=0; i<8; ++i)
- BLI_freelistN(&e.grabdata->active_verts[i]);
- MEM_freeN(e.grabdata);
+ /* Set the rotation of the brush back to what it was before any rake */
+ set_tex_angle(offsetRot);
+
+ if(smooth_stroke) {
+ sculpt_stroke_apply_all(a);
+ calc_damaged_verts(&ss->damaged_verts, a);
+ BLI_freelistN(&ss->damaged_rects);
}
- switch(G.scene->sculptdata.brush_type) {
+ if(a->layer_disps) MEM_freeN(a->layer_disps);
+ if(a->mesh_store) MEM_freeN(a->mesh_store);
+ if(a->orig_norms) MEM_freeN(a->orig_norms);
+ for(i=0; i<8; ++i)
+ BLI_freelistN(&a->grab_active_verts[i]);
+ MEM_freeN(a);
+ sculpt_stroke_free();
+
+ sculpt_undo_push(G.scene->sculptdata.brush_type);
+
+ if(G.vd->depths) G.vd->depths->damaged= 1;
+
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+void sculpt_undo_push(const short brush_type)
+{
+ switch(brush_type) {
case DRAW_BRUSH:
BIF_undo_push("Draw Brush"); break;
case SMOOTH_BRUSH:
@@ -1833,10 +1788,6 @@ void sculpt(void)
default:
BIF_undo_push("Sculpting"); break;
}
-
- if(G.vd->depths) G.vd->depths->damaged= 1;
-
- allqueue(REDRAWVIEW3D, 0);
}
void set_sculptmode(void)
@@ -1846,15 +1797,15 @@ void set_sculptmode(void)
G.f &= ~G_SCULPTMODE;
- sculptmode_free_session(G.scene);
+ sculptsession_free(G.scene);
if(me && me->pv)
- sculptmode_pmv_off(me);
+ mesh_pmv_off(OBACT, me);
}
else {
G.f |= G_SCULPTMODE;
- if(!sculptmode_brush())
- sculptmode_init(G.scene);
+ /* Called here to sanity-check the brush */
+ sculptmode_brush();
sculpt_init_session();
@@ -1869,80 +1820,12 @@ void set_sculptmode(void)
}
/* Partial Mesh Visibility */
-PartialVisibility *sculptmode_copy_pmv(PartialVisibility *pmv)
-{
- PartialVisibility *n= MEM_dupallocN(pmv);
- n->vert_map= MEM_dupallocN(pmv->vert_map);
- n->edge_map= MEM_dupallocN(pmv->edge_map);
- n->old_edges= MEM_dupallocN(pmv->old_edges);
- n->old_faces= MEM_dupallocN(pmv->old_faces);
- return n;
-}
-
-void sculptmode_pmv_free(PartialVisibility *pv)
-{
- MEM_freeN(pv->vert_map);
- MEM_freeN(pv->edge_map);
- MEM_freeN(pv->old_faces);
- MEM_freeN(pv->old_edges);
- MEM_freeN(pv);
-}
-
-void sculptmode_revert_pmv(Mesh *me)
-{
- if(me->pv) {
- unsigned i;
- MVert *nve, *old_verts;
-
- active_ob= NULL;
-
- /* Reorder vertices */
- nve= me->mvert;
- old_verts = MEM_mallocN(sizeof(MVert)*me->pv->totvert,"PMV revert verts");
- for(i=0; i<me->pv->totvert; ++i)
- old_verts[i]= nve[me->pv->vert_map[i]];
-
- /* Restore verts, edges and faces */
- CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
- CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
- CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
-
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, old_verts, me->pv->totvert);
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, me->pv->old_edges, me->pv->totedge);
- CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, me->pv->old_faces, me->pv->totface);
- mesh_update_customdata_pointers(me);
-
- me->totvert= me->pv->totvert;
- me->totedge= me->pv->totedge;
- me->totface= me->pv->totface;
-
- me->pv->old_edges= NULL;
- me->pv->old_faces= NULL;
-
- /* Free maps */
- MEM_freeN(me->pv->edge_map);
- me->pv->edge_map= NULL;
- MEM_freeN(me->pv->vert_map);
- me->pv->vert_map= NULL;
-
- DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
- }
-}
-
-void sculptmode_pmv_off(Mesh *me)
-{
- if(me->pv) {
- sculptmode_revert_pmv(me);
- MEM_freeN(me->pv);
- me->pv= NULL;
- }
-}
/* mode: 0=hide outside selection, 1=hide inside selection */
-void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
+static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
{
Mesh *me= get_mesh(ob);
- vec3f hidebox[6];
+ float hidebox[6][3];
vec3f plane_normals[4];
float plane_ds[4];
unsigned i, j;
@@ -1954,23 +1837,23 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
const unsigned SHOW= 0, HIDE=1;
/* Convert hide box from 2D to 3D */
- hidebox[0]= unproject(hb_2d->xmin, hb_2d->ymax, 1);
- hidebox[1]= unproject(hb_2d->xmax, hb_2d->ymax, 1);
- hidebox[2]= unproject(hb_2d->xmax, hb_2d->ymin, 1);
- hidebox[3]= unproject(hb_2d->xmin, hb_2d->ymin, 1);
- hidebox[4]= unproject(hb_2d->xmin, hb_2d->ymax, 0);
- hidebox[5]= unproject(hb_2d->xmax, hb_2d->ymin, 0);
+ unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
+ unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
+ unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
+ unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
+ unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
+ unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
/* Calculate normals for each side of hide box */
- CalcNormFloat(&hidebox[0].x,&hidebox[1].x,&hidebox[4].x,&plane_normals[0].x);
- CalcNormFloat(&hidebox[1].x,&hidebox[2].x,&hidebox[5].x,&plane_normals[1].x);
- CalcNormFloat(&hidebox[2].x,&hidebox[3].x,&hidebox[5].x,&plane_normals[2].x);
- CalcNormFloat(&hidebox[3].x,&hidebox[0].x,&hidebox[4].x,&plane_normals[3].x);
+ CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
+ CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
+ CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
+ CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
/* Calculate D for each side of hide box */
for(i= 0; i<4; ++i)
- plane_ds[i]= hidebox[i].x*plane_normals[i].x + hidebox[i].y*plane_normals[i].y +
- hidebox[i].z*plane_normals[i].z;
+ plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
+ hidebox[i][2]*plane_normals[i].z;
/* Add partial visibility to mesh */
if(!me->pv) {
@@ -1980,7 +1863,7 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
for(i=0; i<me->pv->totvert; ++i) {
old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
}
- sculptmode_revert_pmv(me);
+ mesh_pmv_revert(ob, me);
}
/* Kill sculpt data */
@@ -2097,7 +1980,7 @@ void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
}
-rcti sculptmode_pmv_box()
+static rcti sculptmode_pmv_box()
{
short down[2], mouse[2];
rcti ret;
@@ -2152,7 +2035,7 @@ void sculptmode_pmv(int mode)
sculptmode_do_pmv(ob,&hb_2d,mode);
}
- else sculptmode_pmv_off(get_mesh(ob));
+ else mesh_pmv_off(ob, get_mesh(ob));
scrarea_do_windraw(curarea);
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c
index 4bac7fdb250..8b669d034d0 100644
--- a/source/blender/src/seqaudio.c
+++ b/source/blender/src/seqaudio.c
@@ -95,6 +95,8 @@ static int audio_pos;
static int audio_scrub=0;
static int audio_playing=0;
static int audio_initialised=0;
+static int audio_startframe=0;
+static double audio_starttime = 0.0;
/////
//
/* local protos ------------------- */
@@ -139,7 +141,7 @@ void audio_mixdown()
strcpy(buf, "RIFFlengWAVEfmt fmln01ccRATEbsecBP16dataDLEN");
totframe = (EFRA - SFRA + 1);
- totlen = (int) ( ((float)totframe / (float)G.scene->r.frs_sec) * (float)G.scene->audio.mixrate * 4.0);
+ totlen = (int) ( FRA2TIME(totframe) * (float)G.scene->audio.mixrate * 4.0);
printf(" totlen %d\n", totlen+36+8);
totlen+= 36; /* len is filesize-8 in WAV spec, total header is 44 bytes */
@@ -182,7 +184,7 @@ void audio_mixdown()
memset(buf+i, 0, 64);
- CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec );
+ CFRA=(int) ( ((float)(audio_pos-64)/( G.scene->audio.mixrate*4 ))*FPS );
audio_fill(buf+i, NULL, 64);
if (G.order == B_ENDIAN) {
@@ -216,7 +218,7 @@ void audiostream_fill(Uint8 *mixdown, int len)
for (i = 0; i < len; i += 64) {
CFRA = (int) ( ((float)(audio_pos-64)
/( G.scene->audio.mixrate*4 ))
- *(float)G.scene->r.frs_sec );
+ * FPS );
audio_fill(mixdown + i, NULL,
(len - i) > 64 ? 64 : (len - i));
@@ -302,7 +304,7 @@ static void audio_fill_ram_sound(Sequence *seq, void * mixdown,
(seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
{
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq);
+ do_seq_ipo(seq, CFRA);
facf = seq->facf0;
} else {
facf = 1.0;
@@ -331,7 +333,7 @@ static void audio_fill_hd_sound(Sequence *seq,
(seq->startdisp <= CFRA) && ((seq->enddisp) > CFRA))
{
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq);
+ do_seq_ipo(seq, CFRA);
facf = seq->facf0;
} else {
facf = 1.0;
@@ -360,7 +362,8 @@ static void audio_fill_seq(Sequence * seq, void * mixdown,
Uint8 *sstream, int len)
{
while(seq) {
- if (seq->type == SEQ_META) {
+ if (seq->type == SEQ_META &&
+ (!(seq->flag & SEQ_MUTE))) {
audio_fill_seq(seq->seqbase.first,
mixdown, sstream, len);
}
@@ -452,9 +455,8 @@ static int audiostream_play_seq(Sequence * seq, Uint32 startframe)
}
if ((seq->type == SEQ_RAM_SOUND) && (seq->sound)) {
have_sound = 1;
- seq->curpos = (int)( (((float)((float)startframe
- -(float)seq->start)
- / (float)G.scene->r.frs_sec)
+ seq->curpos = (int)( (FRA2TIME((double) startframe -
+ (double) seq->start)
* ((float)G.scene->audio.mixrate)
* 4 ));
}
@@ -467,9 +469,8 @@ static int audiostream_play_seq(Sequence * seq, Uint32 startframe)
seq->hdaudio = sound_open_hdaudio(name);
}
- seq->curpos = (int)( (((float)((float)startframe
- - (float)seq->start)
- / (float)G.scene->r.frs_sec)
+ seq->curpos = (int)( (FRA2TIME((double) startframe -
+ (double) seq->start)
* ((float)G.scene->audio.mixrate)
* 4 ));
}
@@ -495,7 +496,7 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
sound_init_audio();
}
- if (!audio_initialised && !(duration + mixdown)) {
+ if (U.mixbufsize && !audio_initialised && !mixdown) {
desired.freq=G.scene->audio.mixrate;
desired.format=AUDIO_S16SYS;
desired.channels=2;
@@ -506,11 +507,16 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
}
}
- audio_pos = ( ((int)( (((float)startframe)
- /(float)G.scene->r.frs_sec)
+ audio_startframe = startframe;
+ audio_pos = ( ((int)( FRA2TIME(startframe)
*(G.scene->audio.mixrate)*4 )) & (~3) );
-
- audio_scrub = duration;
+ audio_starttime = PIL_check_seconds_timer();
+
+ /* if audio already is playing, just reseek, otherwise
+ remember scrub-duration */
+ if (!(audio_playing && !audio_scrub)) {
+ audio_scrub = duration;
+ }
if (!mixdown) {
SDL_PauseAudio(0);
audio_playing++;
@@ -536,9 +542,17 @@ void audiostream_stop(void)
int audiostream_pos(void)
{
int pos;
-
- pos = (int) ( ((float)(audio_pos-U.mixbufsize)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec );
- if (pos<1) pos=1;
+
+ if (U.mixbufsize) {
+ pos = (int) (((double)(audio_pos-U.mixbufsize)
+ / ( G.scene->audio.mixrate*4 ))
+ * FPS );
+ } else { /* fallback to seconds_timer when no audio available */
+ pos = (int) ((PIL_check_seconds_timer() - audio_starttime)
+ * FPS);
+ }
+
+ if (pos < audio_startframe) pos = audio_startframe;
return ( pos );
}
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c
index 63069eb425d..95cae4c888d 100644
--- a/source/blender/src/seqeffects.c
+++ b/source/blender/src/seqeffects.c
@@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
#include "PIL_dynlib.h"
+#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "BLI_blenlib.h"
@@ -785,9 +786,9 @@ static void do_cross_effect(Sequence * seq,int cfra,
********************************************************************** */
/* copied code from initrender.c */
-static unsigned short *gamtab = 0;
-static unsigned short *igamtab1 = 0;
-static int gamma_tabs_refcount = 0;
+static unsigned short gamtab[65536];
+static unsigned short igamtab1[256];
+static int gamma_tabs_init = FALSE;
#define RE_GAMMA_TABLE_SIZE 400
@@ -881,9 +882,6 @@ static void gamtabs(float gamma)
float val, igamma= 1.0f/gamma;
int a;
- gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2");
- igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2");
-
/* gamtab: in short, out short */
for(a=0; a<65536; a++) {
val= a;
@@ -906,36 +904,25 @@ static void gamtabs(float gamma)
}
-static void alloc_or_ref_gammatabs()
+static void build_gammatabs()
{
- if (gamma_tabs_refcount == 0) {
+ if (gamma_tabs_init == FALSE) {
gamtabs(2.0f);
makeGammaTables(2.0f);
+ gamma_tabs_init = TRUE;
}
- gamma_tabs_refcount++;
}
static void init_gammacross(Sequence * seq)
{
- alloc_or_ref_gammatabs();
}
static void load_gammacross(Sequence * seq)
{
- alloc_or_ref_gammatabs();
}
static void free_gammacross(Sequence * seq)
{
- if (--gamma_tabs_refcount == 0) {
- MEM_freeN(gamtab);
- MEM_freeN(igamtab1);
- gamtab = 0;
- igamtab1 = 0;
- }
- if (gamma_tabs_refcount < 0) {
- fprintf(stderr, "seqeffects: free_gammacross double free!\n");
- }
}
static void do_gammacross_effect_byte(float facf0, float facf1,
@@ -1042,6 +1029,8 @@ static void do_gammacross_effect(Sequence * seq,int cfra,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
+ build_gammatabs();
+
if (out->rect_float) {
do_gammacross_effect_float(
facf0, facf1, x, y,
@@ -1926,6 +1915,8 @@ static void init_transform_effect(Sequence *seq)
scale->rotIni=0;
scale->rotFin=0;
+ scale->interpolation=1;
+ scale->percent=1;
}
static int num_inputs_transform()
@@ -1944,49 +1935,8 @@ static void copy_transform_effect(Sequence *dst, Sequence *src)
dst->effectdata = MEM_dupallocN(src->effectdata);
}
-/* function assumes out to be zero'ed, only does RGBA */
-static void bilinear_interpolation_transform_float(ImBuf *in, float *out, float u, float v)
-{
- float *row1, *row2, *row3, *row4, a, b;
- float a_b, ma_b, a_mb, ma_mb;
- float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f};
- int y1, y2, x1, x2;
-
- x1= (int)floor(u);
- x2= (int)ceil(u);
- y1= (int)floor(v);
- y2= (int)ceil(v);
-
- /* sample area entirely outside image? */
- if(x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1)
- return;
-
- /* sample including outside of edges of image */
- if(x1<0 || y1<0) row1= empty;
- else row1= in->rect_float + in->x * y1 * 4 + 4*x1;
-
- if(x1<0 || y2>in->y-1) row2= empty;
- else row2= in->rect_float + in->x * y2 * 4 + 4*x1;
-
- if(x2>in->x-1 || y1<0) row3= empty;
- else row3= in->rect_float + in->x * y1 * 4 + 4*x2;
-
- if(x2>in->x-1 || y2>in->y-1) row4= empty;
- else row4= in->rect_float + in->x * y2 * 4 + 4*x2;
-
- a= u-floor(u);
- b= v-floor(v);
- a_b= a*b; ma_b= (1.0f-a)*b; a_mb= a*(1.0f-b); ma_mb= (1.0f-a)*(1.0f-b);
-
- out[0]= ma_mb*row1[0] + a_mb*row3[0] + ma_b*row2[0]+ a_b*row4[0];
- out[1]= ma_mb*row1[1] + a_mb*row3[1] + ma_b*row2[1]+ a_b*row4[1];
- out[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2];
- out[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3];
-}
-
-
-static void do_transform_effect_float(Sequence * seq,float facf0, int x, int y,
- struct ImBuf *ibuf1,float *out)
+static void do_transform(Sequence * seq,float facf0, int x, int y,
+ struct ImBuf *ibuf1,struct ImBuf *out)
{
int xo, yo, xi, yi;
float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
@@ -1996,151 +1946,20 @@ static void do_transform_effect_float(Sequence * seq,float facf0, int x, int y,
xo = x;
yo = y;
- /*factor scale*/
+ //factor scale
factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0;
factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0;
- /*Factor translate*/
- tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0;
- ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0;
-
- /*factor Rotate*/
- factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0;
- rad = (M_PI * factRot) / 180.0f;
- s= sin(rad);
- c= cos(rad);
-
- for (yi = 0; yi < yo; yi++) {
- for (xi = 0; xi < xo; xi++) {
- /*tranlate point*/
- px = xi-tx;
- py = yi-ty;
-
- /*rotate point with center ref*/
- xaux = c*px + py*s ;
- yaux = -s*px + c*py;
-
- /*scale point with center ref*/
- xs = xaux / factxScale;
- ys = yaux / factyScale;
-
- /*undo reference center point */
- xs += (xo / 2.0f);
- ys += (yo / 2.0f);
-
- /*interpolate*/
- bilinear_interpolation_transform_float(ibuf1,out, xs,ys);
-
- out+=4;
- }
- }
-
-}
-
-/* function assumes out to be zero'ed, only does RGBA */
-static void bilinear_interpolation_transform_byte(unsigned char *in, unsigned char *out, float u, float v,int x,int y)
-{
- float a, b;
- float a_b, ma_b, a_mb, ma_mb;
- int y1, y2, x1, x2;
-
- int row1R,row1G,row1B,row1A;
- int row2R,row2G,row2B,row2A;
- int row3R,row3G,row3B,row3A;
- int row4R,row4G,row4B,row4A;
-
- x1= (int)floor(u);
- x2= (int)ceil(u);
- y1= (int)floor(v);
- y2= (int)ceil(v);
-
- /* sample area entirely outside image? */
- if(x2<0 || x1>x-1 || y2<0 || y1>y-1)
- return;
-
- /* sample including outside of edges of image */
- if(x1<0 || y1<0){
- row1R = 0;
- row1G = 0;
- row1B = 0;
- row1A = 0;
- }
- else{
- row1R= in[x * y1 * 4 + 4 * x1];
- row1G= in[x * y1 * 4 + 4 * x1 + 1];
- row1B= in[x * y1 * 4 + 4 * x1 + 2];
- row1A= in[x * y1 * 4 + 4 * x1 + 3];
- }
-
- if(x1<0 || y2>y-1){
- row2R = 0;
- row2G = 0;
- row2B = 0;
- row2A = 0;
- }
- else{
- row2R= in[x * y2 * 4 + 4 * x1];
- row2G= in[x * y2 * 4 + 4 * x1 + 1];
- row2B= in[x * y2 * 4 + 4 * x1 + 2];
- row2A= in[x * y2 * 4 + 4 * x1 + 3];
- }
-
- if(x2>x-1 || y1<0){
- row3R = 0;
- row3G = 0;
- row3B = 0;
- row3A = 0;
- }
- else{
- row3R= in[x * y1 * 4 + 4 * x2];
- row3G= in[x * y1 * 4 + 4 * x2 + 1];
- row3B= in[x * y1 * 4 + 4 * x2 + 2];
- row3A= in[x * y1 * 4 + 4 * x2 + 3];
+ //Factor translate
+ if(!scale->percent){
+ tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0;
+ ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0;
+ }else{
+ tx = xo*(scale->xIni/100.0)+(xo / 2.0f) + (xo*(scale->xFin/100.0)-(xo / 2.0f) - xo*(scale->xIni/100.0)+(xo / 2.0f)) * facf0;
+ ty = yo*(scale->yIni/100.0)+(yo / 2.0f) + (yo*(scale->yFin/100.0)-(yo / 2.0f) - yo*(scale->yIni/100.0)+(yo / 2.0f)) * facf0;
}
-
- if(x2>x-1 || y2>y-1){
- row4R = 0;
- row4G = 0;
- row4B = 0;
- row4A = 0;
- }
- else{
- row4R= in[x * y2 * 4 + 4 * x2];
- row4G= in[x * y2 * 4 + 4 * x2 + 1];
- row4B= in[x * y2 * 4 + 4 * x2 + 2];
- row4A= in[x * y2 * 4 + 4 * x2 + 3];
- }
-
- a= u-floor(u);
- b= v-floor(v);
- a_b= a*b; ma_b= (1-a)*b; a_mb= a*(1-b); ma_mb= (1-a)*(1-b);
-
- out[0]= (int)(ma_mb*row1R + a_mb*row3R + ma_b*row2R + a_b*row4R);
- out[1]= (int)(ma_mb*row1G + a_mb*row3G + ma_b*row2G + a_b*row4G);
- out[2]= (int)(ma_mb*row1B + a_mb*row3B + ma_b*row2B + a_b*row4B);
- out[3]= (int)(ma_mb*row1A + a_mb*row3A + ma_b*row2A + a_b*row4A);
-}
-
-static void do_transform_effect_byte(Sequence * seq,float facf0, int x, int y,
- unsigned char *ibuf1,unsigned char *out)
-{
- int xo, yo, xi, yi;
- float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
- TransformVars *scale;
-
- scale = (TransformVars *)seq->effectdata;
- xo = x;
- yo = y;
-
- /*factor scale*/
- factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0;
- factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0;
- /*Factor translate*/
- tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0;
- ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0;
-
- /*factor Rotate*/
+ //factor Rotate
factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0;
rad = (M_PI * factRot) / 180.0f;
s= sin(rad);
@@ -2148,26 +1967,29 @@ static void do_transform_effect_byte(Sequence * seq,float facf0, int x, int y,
for (yi = 0; yi < yo; yi++) {
for (xi = 0; xi < xo; xi++) {
- /*tranlate point*/
+ //tranlate point
px = xi-tx;
py = yi-ty;
- /*rotate point with center ref*/
+ //rotate point with center ref
xaux = c*px + py*s ;
yaux = -s*px + c*py;
- /*scale point with center ref*/
+ //scale point with center ref
xs = xaux / factxScale;
ys = yaux / factyScale;
- /*undo reference center point */
+ //undo reference center point
xs += (xo / 2.0f);
ys += (yo / 2.0f);
- /*interpolate*/
- bilinear_interpolation_transform_byte(ibuf1,out, xs,ys,x,y);
-
- out+=4;
+ //interpolate
+ if(scale->interpolation==0)
+ neareast_interpolation(ibuf1,out, xs,ys,xi,yi);
+ if(scale->interpolation==1)
+ bilinear_interpolation(ibuf1,out, xs,ys,xi,yi);
+ if(scale->interpolation==2)
+ bicubic_interpolation(ibuf1,out, xs,ys,xi,yi);
}
}
@@ -2177,17 +1999,7 @@ static void do_transform_effect(Sequence * seq,int cfra,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
- if (out->rect_float) {
- do_transform_effect_float(seq,
- facf0,x, y,
- ibuf1,
- out->rect_float);
- } else {
- do_transform_effect_byte(seq,
- facf0,x, y,
- (unsigned char*) ibuf1->rect,
- (unsigned char*) out->rect);
- }
+ do_transform(seq, facf0, x, y, ibuf1, out);
}
@@ -2671,9 +2483,10 @@ static void do_glow_effect_byte(Sequence *seq, float facf0, float facf1,
unsigned char *outbuf=(unsigned char *)out;
unsigned char *inbuf=(unsigned char *)rect1;
GlowVars *glow = (GlowVars *)seq->effectdata;
+ struct RenderData *rd = &G.scene->r;
- RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost, glow->fClamp);
- RVBlurBitmap2_byte (outbuf, x, y, glow->dDist,glow->dQuality);
+ RVIsolateHighlights_byte(inbuf, outbuf , x, y, glow->fMini*765, glow->fBoost * facf0, glow->fClamp);
+ RVBlurBitmap2_byte (outbuf, x, y, glow->dDist * (rd->size / 100.0f),glow->dQuality);
if (!glow->bNoComp)
RVAddBitmaps_byte (inbuf , outbuf, outbuf, x, y);
}
@@ -2685,9 +2498,10 @@ static void do_glow_effect_float(Sequence *seq, float facf0, float facf1,
float *outbuf = out;
float *inbuf = rect1;
GlowVars *glow = (GlowVars *)seq->effectdata;
+ struct RenderData *rd = &G.scene->r;
- RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost, glow->fClamp);
- RVBlurBitmap2_float (outbuf, x, y, glow->dDist,glow->dQuality);
+ RVIsolateHighlights_float(inbuf, outbuf , x, y, glow->fMini*3.0f, glow->fBoost * facf0, glow->fClamp);
+ RVBlurBitmap2_float (outbuf, x, y, glow->dDist * (rd->size / 100.0f),glow->dQuality);
if (!glow->bNoComp)
RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y);
}
@@ -2907,6 +2721,7 @@ void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force)
float cursor = 0;
v->frameMap[0] = 0;
+ v->lastValidFrame = 0;
for (cfra = 1; cfra < v->length; cfra++) {
if(seq->ipo) {
@@ -2933,9 +2748,11 @@ void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force)
v->frameMap[cfra] = v->length - 1;
} else {
v->frameMap[cfra] = cursor;
+ v->lastValidFrame = cfra;
}
}
} else {
+ v->lastValidFrame = 0;
for (cfra = 0; cfra < v->length; cfra++) {
if(seq->ipo) {
if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
@@ -2961,6 +2778,8 @@ void sequence_effect_speed_rebuild_map(struct Sequence * seq, int force)
seq->facf0 *= v->globalSpeed;
if (seq->facf0 >= v->length) {
seq->facf0 = v->length - 1;
+ } else {
+ v->lastValidFrame = cfra;
}
v->frameMap[cfra] = seq->facf0;
}
@@ -3183,11 +3002,33 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
struct SeqEffectHandle get_sequence_effect(Sequence * seq)
{
- struct SeqEffectHandle rval = get_sequence_effect_impl(seq->type);
+ struct SeqEffectHandle rval;
- if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
- rval.load(seq);
- seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
+ memset(&rval, 0, sizeof(struct SeqEffectHandle));
+
+ if (seq->type & SEQ_EFFECT) {
+ rval = get_sequence_effect_impl(seq->type);
+ if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
+ rval.load(seq);
+ seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
+ }
+ }
+
+ return rval;
+}
+
+struct SeqEffectHandle get_sequence_blend(Sequence * seq)
+{
+ struct SeqEffectHandle rval;
+
+ memset(&rval, 0, sizeof(struct SeqEffectHandle));
+
+ if (seq->blend_mode != 0) {
+ rval = get_sequence_effect_impl(seq->blend_mode);
+ if ((seq->flag & SEQ_EFFECT_NOT_LOADED) != 0) {
+ rval.load(seq);
+ seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
+ }
}
return rval;
@@ -3197,5 +3038,9 @@ int get_sequence_effect_num_inputs(int seq_type)
{
struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
- return rval.num_inputs();
+ int cnt = rval.num_inputs();
+ if (rval.execute) {
+ return cnt;
+ }
+ return 0;
}
diff --git a/source/blender/src/seqscopes.c b/source/blender/src/seqscopes.c
index 1fa01a6145e..c9796c356bc 100644
--- a/source/blender/src/seqscopes.c
+++ b/source/blender/src/seqscopes.c
@@ -53,6 +53,14 @@ static void scope_put_pixel(unsigned char* table, unsigned char * pos)
pos[3] = 255;
}
+static void scope_put_pixel_single(unsigned char* table, unsigned char * pos,
+ int col)
+{
+ char newval = table[pos[col]];
+ pos[col] = newval;
+ pos[3] = 255;
+}
+
static void wform_put_line(int w,
unsigned char * last_pos, unsigned char * new_pos)
{
@@ -71,6 +79,67 @@ static void wform_put_line(int w,
}
}
+static void wform_put_line_single(
+ int w, unsigned char * last_pos, unsigned char * new_pos, int col)
+{
+ if (last_pos > new_pos) {
+ unsigned char* temp = new_pos;
+ new_pos = last_pos;
+ last_pos = temp;
+ }
+
+ while (last_pos < new_pos) {
+ if (last_pos[col] == 0) {
+ last_pos[col] = 32;
+ last_pos[3] = 255;
+ }
+ last_pos += 4*w;
+ }
+}
+
+static void wform_put_border(unsigned char * tgt, int w, int h)
+{
+ int x, y;
+
+ for (x = 0; x < w; x++) {
+ unsigned char * p = tgt + 4 * x;
+ p[1] = p[3] = 255.0;
+ p[4 * w + 1] = p[4 * w + 3] = 255.0;
+ p = tgt + 4 * (w * (h - 1) + x);
+ p[1] = p[3] = 255.0;
+ p[-4 * w + 1] = p[-4 * w + 3] = 255.0;
+ }
+
+ for (y = 0; y < h; y++) {
+ unsigned char * p = tgt + 4 * w * y;
+ p[1] = p[3] = 255.0;
+ p[4 + 1] = p[4 + 3] = 255.0;
+ p = tgt + 4 * (w * y + w - 1);
+ p[1] = p[3] = 255.0;
+ p[-4 + 1] = p[-4 + 3] = 255.0;
+ }
+}
+
+static void wform_put_gridrow(unsigned char * tgt, float perc, int w, int h)
+{
+ int i;
+
+ tgt += (int) (perc/100.0 * h) * w * 4;
+
+ for (i = 0; i < w*2; i++) {
+ tgt[0] = 255;
+
+ tgt += 4;
+ }
+}
+
+static void wform_put_grid(unsigned char * tgt, int w, int h)
+{
+ wform_put_gridrow(tgt, 90.0, w, h);
+ wform_put_gridrow(tgt, 70.0, w, h);
+ wform_put_gridrow(tgt, 10.0, w, h);
+}
+
static struct ImBuf *make_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
{
struct ImBuf * rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect, 0);
@@ -82,6 +151,8 @@ static struct ImBuf *make_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
float waveform_gamma = 0.2;
unsigned char wtable[256];
+ wform_put_grid(tgt, w, h);
+
for (x = 0; x < 256; x++) {
wtable[x] = (unsigned char) (pow(((float) x + 1)/256,
waveform_gamma)*255);
@@ -110,23 +181,7 @@ static struct ImBuf *make_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
}
}
- for (x = 0; x < w; x++) {
- unsigned char * p = tgt + 4 * x;
- p[1] = p[3] = 255.0;
- p[4 * w + 1] = p[4 * w + 3] = 255.0;
- p = tgt + 4 * (w * (h - 1) + x);
- p[1] = p[3] = 255.0;
- p[-4 * w + 1] = p[-4 * w + 3] = 255.0;
- }
-
- for (y = 0; y < h; y++) {
- unsigned char * p = tgt + 4 * w * y;
- p[1] = p[3] = 255.0;
- p[4 + 1] = p[4 + 3] = 255.0;
- p = tgt + 4 * (w * y + w - 1);
- p[1] = p[3] = 255.0;
- p[-4 + 1] = p[-4 + 3] = 255.0;
- }
+ wform_put_border(tgt, w, h);
return rval;
}
@@ -142,6 +197,8 @@ static struct ImBuf *make_waveform_view_from_ibuf_float(struct ImBuf * ibuf)
float waveform_gamma = 0.2;
unsigned char wtable[256];
+ wform_put_grid(tgt, w, h);
+
for (x = 0; x < 256; x++) {
wtable[x] = (unsigned char) (pow(((float) x + 1)/256,
waveform_gamma)*255);
@@ -173,23 +230,7 @@ static struct ImBuf *make_waveform_view_from_ibuf_float(struct ImBuf * ibuf)
}
}
- for (x = 0; x < w; x++) {
- unsigned char * p = tgt + 4 * x;
- p[1] = p[3] = 255.0;
- p[4 * w + 1] = p[4 * w + 3] = 255.0;
- p = tgt + 4 * (w * (h - 1) + x);
- p[1] = p[3] = 255.0;
- p[-4 * w + 1] = p[-4 * w + 3] = 255.0;
- }
-
- for (y = 0; y < h; y++) {
- unsigned char * p = tgt + 4 * w * y;
- p[1] = p[3] = 255.0;
- p[4 + 1] = p[4 + 3] = 255.0;
- p = tgt + 4 * (w * y + w - 1);
- p[1] = p[3] = 255.0;
- p[-4 + 1] = p[-4 + 3] = 255.0;
- }
+ wform_put_border(tgt, w, h);
return rval;
}
@@ -204,6 +245,326 @@ struct ImBuf *make_waveform_view_from_ibuf(struct ImBuf * ibuf)
}
+static struct ImBuf *make_sep_waveform_view_from_ibuf_byte(struct ImBuf * ibuf)
+{
+ struct ImBuf * rval = IMB_allocImBuf(
+ ibuf->x + 3, 515, 32, IB_rect, 0);
+ int x,y;
+ unsigned char* src = (unsigned char*) ibuf->rect;
+ unsigned char* tgt = (unsigned char*) rval->rect;
+ int w = ibuf->x + 3;
+ int sw = ibuf->x/3;
+ int h = 515;
+ float waveform_gamma = 0.2;
+ unsigned char wtable[256];
+
+ wform_put_grid(tgt, w, h);
+
+ for (x = 0; x < 256; x++) {
+ wtable[x] = (unsigned char) (pow(((float) x + 1)/256,
+ waveform_gamma)*255);
+ }
+
+ for (y = 0; y < ibuf->y; y++) {
+ unsigned char * last_p[3] = {0,0,0};
+
+ for (x = 0; x < ibuf->x; x++) {
+ int c;
+ unsigned char * rgb = src + 4 * (ibuf->x * y + x);
+ for (c = 0; c < 3; c++) {
+ unsigned char * p = tgt;
+ p += 4 * (w * ((rgb[c] * (h - 3))/255 + 1)
+ + c * sw + x/3 + 1);
+
+ scope_put_pixel_single(wtable, p, c);
+ p += 4 * w;
+ scope_put_pixel_single(wtable, p, c);
+
+ if (last_p[c] != 0) {
+ wform_put_line_single(
+ w, last_p[c], p, c);
+ }
+ last_p[c] = p;
+ }
+ }
+ }
+
+ wform_put_border(tgt, w, h);
+
+ return rval;
+}
+
+static struct ImBuf *make_sep_waveform_view_from_ibuf_float(
+ struct ImBuf * ibuf)
+{
+ struct ImBuf * rval = IMB_allocImBuf(
+ ibuf->x + 3, 515, 32, IB_rect, 0);
+ int x,y;
+ float* src = ibuf->rect_float;
+ unsigned char* tgt = (unsigned char*) rval->rect;
+ int w = ibuf->x + 3;
+ int sw = ibuf->x/3;
+ int h = 515;
+ float waveform_gamma = 0.2;
+ unsigned char wtable[256];
+
+ wform_put_grid(tgt, w, h);
+
+ for (x = 0; x < 256; x++) {
+ wtable[x] = (unsigned char) (pow(((float) x + 1)/256,
+ waveform_gamma)*255);
+ }
+
+ for (y = 0; y < ibuf->y; y++) {
+ unsigned char * last_p[3] = {0, 0, 0};
+
+ for (x = 0; x < ibuf->x; x++) {
+ int c;
+ float * rgb = src + 4 * (ibuf->x * y + x);
+ for (c = 0; c < 3; c++) {
+ unsigned char * p = tgt;
+ float v = rgb[c];
+
+ CLAMP(v, 0.0, 1.0);
+
+ p += 4 * (w * ((int) (v * (h - 3)) + 1)
+ + c * sw + x/3 + 1);
+
+ scope_put_pixel_single(wtable, p, c);
+ p += 4 * w;
+ scope_put_pixel_single(wtable, p, c);
+
+ if (last_p[c] != 0) {
+ wform_put_line_single(
+ w, last_p[c], p, c);
+ }
+ last_p[c] = p;
+ }
+ }
+ }
+
+ wform_put_border(tgt, w, h);
+
+ return rval;
+}
+
+struct ImBuf *make_sep_waveform_view_from_ibuf(struct ImBuf * ibuf)
+{
+ if (ibuf->rect_float) {
+ return make_sep_waveform_view_from_ibuf_float(ibuf);
+ } else {
+ return make_sep_waveform_view_from_ibuf_byte(ibuf);
+ }
+}
+
+static void draw_zebra_byte(struct ImBuf * src,struct ImBuf * ibuf, float perc)
+{
+ unsigned int limit = 255 * perc / 100.0;
+ unsigned char * p = (unsigned char*) src->rect;
+ unsigned char * o = (unsigned char*) ibuf->rect;
+ int x;
+ int y;
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ unsigned char r = *p++;
+ unsigned char g = *p++;
+ unsigned char b = *p++;
+ unsigned char a = *p++;
+
+ if (r >= limit || g >= limit || b >= limit) {
+ if (((x + y) & 0x08) != 0) {
+ r = 255 - r;
+ g = 255 - g;
+ b = 255 - b;
+ }
+ }
+ *o++ = r;
+ *o++ = g;
+ *o++ = b;
+ *o++ = a;
+ }
+ }
+}
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.99f*val))
+
+static void draw_zebra_float(struct ImBuf * src,struct ImBuf * ibuf,float perc)
+{
+ float limit = perc / 100.0;
+ float * p = src->rect_float;
+ unsigned char * o = (unsigned char*) ibuf->rect;
+ int x;
+ int y;
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ float r = *p++;
+ float g = *p++;
+ float b = *p++;
+ float a = *p++;
+
+ if (r >= limit || g >= limit || b >= limit) {
+ if (((x + y) & 0x08) != 0) {
+ r = -r;
+ g = -g;
+ b = -b;
+ }
+ }
+
+ *o++ = FTOCHAR(r);
+ *o++ = FTOCHAR(g);
+ *o++ = FTOCHAR(b);
+ *o++ = FTOCHAR(a);
+ }
+ }
+}
+
+struct ImBuf * make_zebra_view_from_ibuf(struct ImBuf * src, float perc)
+{
+ struct ImBuf * ibuf = IMB_allocImBuf(src->x, src->y, 32, IB_rect, 0);
+
+ if (src->rect_float) {
+ draw_zebra_float(src, ibuf, perc);
+ } else {
+ draw_zebra_byte(src, ibuf, perc);
+ }
+ return ibuf;
+}
+
+static void draw_histogram_marker(struct ImBuf * ibuf, int x)
+{
+ unsigned char * p = (unsigned char*) ibuf->rect;
+ int barh = ibuf->y * 0.1;
+ int i;
+
+ p += 4 * (x + ibuf->x * (ibuf->y - barh + 1));
+
+ for (i = 0; i < barh-1; i++) {
+ p[0] = p[1] = p[2] = 255;
+ p += ibuf->x * 4;
+ }
+}
+
+static void draw_histogram_bar(struct ImBuf * ibuf, int x,float val, int col)
+{
+ unsigned char * p = (unsigned char*) ibuf->rect;
+ int barh = ibuf->y * val * 0.9;
+ int i;
+
+ p += 4 * (x + ibuf->x);
+
+ for (i = 0; i < barh; i++) {
+ p[col] = 255;
+ p += ibuf->x * 4;
+ }
+}
+
+static struct ImBuf *make_histogram_view_from_ibuf_byte(
+ struct ImBuf * ibuf)
+{
+ struct ImBuf * rval = IMB_allocImBuf(515, 128, 32, IB_rect, 0);
+ int n,c,x,y;
+ unsigned char* src = (unsigned char*) ibuf->rect;
+
+ unsigned int bins[3][256];
+
+ memset(bins, 0, 3 * 256* sizeof(unsigned int));
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ bins[0][*src++]++;
+ bins[1][*src++]++;
+ bins[2][*src++]++;
+ src++;
+ }
+ }
+
+ n = 0;
+ for (c = 0; c < 3; c++) {
+ for (x = 0; x < 256; x++) {
+ if (bins[c][x] > n) {
+ n = bins[c][x];
+ }
+ }
+ }
+
+ for (c = 0; c < 3; c++) {
+ for (x = 0; x < 256; x++) {
+ draw_histogram_bar(rval, x*2+1,
+ ((float) bins[c][x])/n, c);
+ draw_histogram_bar(rval, x*2+2,
+ ((float) bins[c][x])/n, c);
+ }
+ }
+
+ wform_put_border((unsigned char*) rval->rect, rval->x, rval->y);
+
+ return rval;
+}
+
+static int get_bin_float(float f)
+{
+ if (f < -0.25) {
+ f = -0.25;
+ } else if (f > 1.25) {
+ f = 1.25;
+ }
+
+ return (int) (((f + 0.25) / 1.5) * 512);
+}
+
+static struct ImBuf *make_histogram_view_from_ibuf_float(
+ struct ImBuf * ibuf)
+{
+ struct ImBuf * rval = IMB_allocImBuf(515, 128, 32, IB_rect, 0);
+ int n,c,x,y;
+ float* src = ibuf->rect_float;
+
+ unsigned int bins[3][512];
+
+ memset(bins, 0, 3 * 256* sizeof(unsigned int));
+
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ bins[0][get_bin_float(*src++)]++;
+ bins[1][get_bin_float(*src++)]++;
+ bins[2][get_bin_float(*src++)]++;
+ src++;
+ }
+ }
+
+ draw_histogram_marker(rval, get_bin_float(0.0));
+ draw_histogram_marker(rval, get_bin_float(1.0));
+
+ n = 0;
+ for (c = 0; c < 3; c++) {
+ for (x = 0; x < 512; x++) {
+ if (bins[c][x] > n) {
+ n = bins[c][x];
+ }
+ }
+ }
+ for (c = 0; c < 3; c++) {
+ for (x = 0; x < 512; x++) {
+ draw_histogram_bar(rval, x+1, (float) bins[c][x]/n, c);
+ }
+ }
+
+ wform_put_border((unsigned char*) rval->rect, rval->x, rval->y);
+
+ return rval;
+}
+
+struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf * ibuf)
+{
+ if (ibuf->rect_float) {
+ return make_histogram_view_from_ibuf_float(ibuf);
+ } else {
+ return make_histogram_view_from_ibuf_byte(ibuf);
+ }
+}
+
static void vectorscope_put_cross(unsigned char r, unsigned char g,
unsigned char b,
char * tgt, int w, int h, int size)
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index db901930893..9f6de0fe69d 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -71,20 +71,38 @@
#include "blendef.h"
+#include "BLI_threads.h"
+#include <pthread.h>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+
int seqrectx, seqrecty;
-void free_stripdata(int len, StripElem *se)
+/* **********************************************************************
+ alloc / free functions
+ ********************************************************************** */
+
+void free_tstripdata(int len, TStripElem *se)
{
- StripElem *seo;
+ TStripElem *seo;
int a;
seo= se;
+ if (!se) {
+ return;
+ }
for(a=0; a<len; a++, se++) {
- if(se->ibuf && se->ok!=2) {
+ if(se->ibuf) {
IMB_freeImBuf(se->ibuf);
se->ibuf = 0;
}
+ if(se->ibuf_comp) {
+ IMB_freeImBuf(se->ibuf_comp);
+ se->ibuf_comp = 0;
+ }
}
MEM_freeN(seo);
@@ -100,19 +118,64 @@ void free_strip(Strip *strip)
return;
}
- if(strip->stripdata) {
- free_stripdata(strip->len, strip->stripdata);
+ if (strip->stripdata) {
+ MEM_freeN(strip->stripdata);
+ }
+
+ if (strip->proxy) {
+ MEM_freeN(strip->proxy);
+ }
+ if (strip->crop) {
+ MEM_freeN(strip->crop);
+ }
+ if (strip->transform) {
+ MEM_freeN(strip->transform);
+ }
+ if (strip->color_balance) {
+ MEM_freeN(strip->color_balance);
+ }
+
+ free_tstripdata(strip->len, strip->tstripdata);
+ free_tstripdata(strip->endstill, strip->tstripdata_endstill);
+ free_tstripdata(strip->startstill, strip->tstripdata_startstill);
+
+ if(strip->ibuf_startstill) {
+ IMB_freeImBuf(strip->ibuf_startstill);
+ strip->ibuf_startstill = 0;
}
+
+ if(strip->ibuf_endstill) {
+ IMB_freeImBuf(strip->ibuf_endstill);
+ strip->ibuf_endstill = 0;
+ }
+
MEM_freeN(strip);
}
-void new_stripdata(Sequence *seq)
+void new_tstripdata(Sequence *seq)
{
if(seq->strip) {
- if(seq->strip->stripdata) free_stripdata(seq->strip->len, seq->strip->stripdata);
- seq->strip->stripdata= 0;
+ free_tstripdata(seq->strip->len, seq->strip->tstripdata);
+ free_tstripdata(seq->strip->endstill,
+ seq->strip->tstripdata_endstill);
+ free_tstripdata(seq->strip->startstill,
+ seq->strip->tstripdata_startstill);
+
+ seq->strip->tstripdata= 0;
+ seq->strip->tstripdata_endstill= 0;
+ seq->strip->tstripdata_startstill= 0;
+
+ if(seq->strip->ibuf_startstill) {
+ IMB_freeImBuf(seq->strip->ibuf_startstill);
+ seq->strip->ibuf_startstill = 0;
+ }
+
+ if(seq->strip->ibuf_endstill) {
+ IMB_freeImBuf(seq->strip->ibuf_endstill);
+ seq->strip->ibuf_endstill = 0;
+ }
+
seq->strip->len= seq->len;
- if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelems");
}
}
@@ -189,6 +252,66 @@ void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
*seqar= tseqar;
}
+static void do_seq_count_cb(ListBase *seqbase, int *totseq,
+ int (*test_func)(Sequence * seq))
+{
+ Sequence *seq;
+
+ seq= seqbase->first;
+ while(seq) {
+ int test = test_func(seq);
+ if (test & BUILD_SEQAR_COUNT_CURRENT) {
+ (*totseq)++;
+ }
+ if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
+ do_seq_count_cb(&seq->seqbase, totseq, test_func);
+ }
+ seq= seq->next;
+ }
+}
+
+static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
+ int (*test_func)(Sequence * seq))
+{
+ Sequence *seq;
+
+ seq= seqbase->first;
+ while(seq) {
+ int test = test_func(seq);
+ seq->depth= depth;
+
+ if(seq->seqbase.first && (test & BUILD_SEQAR_COUNT_CHILDREN)) {
+ do_build_seqar_cb(&seq->seqbase, seqar, depth+1,
+ test_func);
+ }
+ if (test & BUILD_SEQAR_COUNT_CURRENT) {
+ **seqar= seq;
+ (*seqar)++;
+ }
+ seq= seq->next;
+ }
+}
+
+void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
+ int (*test_func)(Sequence * seq))
+{
+ Sequence **tseqar;
+
+ *totseq= 0;
+ do_seq_count_cb(seqbase, totseq, test_func);
+
+ if(*totseq==0) {
+ *seqar= 0;
+ return;
+ }
+ *seqar= MEM_mallocN(sizeof(void *)* *totseq, "seqar");
+ tseqar= *seqar;
+
+ do_build_seqar_cb(seqbase, seqar, 0, test_func);
+ *seqar= tseqar;
+}
+
+
void free_editing(Editing *ed)
{
MetaStack *ms;
@@ -211,6 +334,23 @@ void free_editing(Editing *ed)
}
+void calc_sequence_disp(Sequence *seq)
+{
+ if(seq->startofs && seq->startstill) seq->startstill= 0;
+ if(seq->endofs && seq->endstill) seq->endstill= 0;
+
+ seq->startdisp= seq->start + seq->startofs - seq->startstill;
+ seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
+
+ seq->handsize= 10.0; /* 10 frames */
+ if( seq->enddisp-seq->startdisp < 10 ) {
+ seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
+ }
+ else if(seq->enddisp-seq->startdisp > 250) {
+ seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
+ }
+}
+
void calc_sequence(Sequence *seq)
{
Sequence *seqm;
@@ -242,23 +382,11 @@ void calc_sequence(Sequence *seq)
seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
seq->len= seq->enddisp - seq->startdisp;
} else {
- if(seq->startofs && seq->startstill) seq->startstill= 0;
- if(seq->endofs && seq->endstill) seq->endstill= 0;
-
- seq->startdisp= seq->start + seq->startofs - seq->startstill;
- seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
-
- seq->handsize= 10.0; /* 10 frames */
- if( seq->enddisp-seq->startdisp < 20 ) {
- seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
- }
- else if(seq->enddisp-seq->startdisp > 250) {
- seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
- }
+ calc_sequence_disp(seq);
}
if(seq->strip && seq->len!=seq->strip->len) {
- new_stripdata(seq);
+ new_tstripdata(seq);
}
}
@@ -277,26 +405,91 @@ void calc_sequence(Sequence *seq)
seq->len= max-min;
if(seq->strip && seq->len!=seq->strip->len) {
- new_stripdata(seq);
+ new_tstripdata(seq);
}
}
}
+ calc_sequence_disp(seq);
+ }
+}
+
+void reload_sequence_new_file(Sequence * seq)
+{
+ char str[FILE_MAXDIR+FILE_MAXFILE];
+
+ if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
+ seq->type == SEQ_HD_SOUND || seq->type == SEQ_SCENE)) {
+ return;
+ }
+
+ new_tstripdata(seq);
+
+ if (seq->type == SEQ_IMAGE) {
+ return;
+ }
+ if (seq->type != SEQ_SCENE) {
+ strncpy(str, seq->strip->dir, FILE_MAXDIR-1);
+ strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1);
+ }
+
+ if (seq->type == SEQ_MOVIE) {
+ if(seq->anim) IMB_free_anim(seq->anim);
+ seq->anim = openanim(str, IB_rect);
+
+ if (!seq->anim) {
+ return;
+ }
+
+ seq->len = IMB_anim_get_duration(seq->anim);
+
+ seq->anim_preseek = IMB_anim_get_preseek(seq->anim);
- if(seq->startofs && seq->startstill) seq->startstill= 0;
- if(seq->endofs && seq->endstill) seq->endstill= 0;
+ seq->len -= seq->anim_startofs;
+ seq->len -= seq->anim_endofs;
+ if (seq->len < 0) {
+ seq->len = 0;
+ }
+ seq->strip->len = seq->len;
+ } else if (seq->type == SEQ_HD_SOUND) {
+ if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio);
+ seq->hdaudio = sound_open_hdaudio(str);
- seq->startdisp= seq->start + seq->startofs - seq->startstill;
- seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
+ if (!seq->hdaudio) {
+ return;
+ }
- seq->handsize= 10.0; /* 10 frames */
- if( seq->enddisp-seq->startdisp < 20 ) {
- seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
+ seq->strip->len = seq->len
+ = sound_hdaudio_get_duration(seq->hdaudio, FPS);
+ } else if (seq->type == SEQ_SCENE) {
+ Scene * sce = G.main->scene.first;
+ int nr = 1;
+ while(sce) {
+ if(nr == seq->scenenr) {
+ break;
+ }
+ nr++;
+ sce= sce->id.next;
+ }
+
+ if (sce) {
+ seq->scene = sce;
}
- else if(seq->enddisp-seq->startdisp > 250) {
- seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
+
+ strncpy(seq->name + 2, sce->id.name + 2,
+ sizeof(seq->name) - 2);
+
+ seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
+ seq->len -= seq->anim_startofs;
+ seq->len -= seq->anim_endofs;
+ if (seq->len < 0) {
+ seq->len = 0;
}
+ seq->strip->len = seq->len;
}
+
+
+ calc_sequence(seq);
}
void sort_seq()
@@ -369,6 +562,54 @@ void clear_scene_in_allseqs(Scene *sce)
}
}
+char *give_seqname_by_type(int type)
+{
+ switch(type) {
+ case SEQ_META: return "Meta";
+ case SEQ_IMAGE: return "Image";
+ case SEQ_SCENE: return "Scene";
+ case SEQ_MOVIE: return "Movie";
+ case SEQ_RAM_SOUND: return "Audio (RAM)";
+ case SEQ_HD_SOUND: return "Audio (HD)";
+ case SEQ_CROSS: return "Cross";
+ case SEQ_GAMCROSS: return "Gamma Cross";
+ case SEQ_ADD: return "Add";
+ case SEQ_SUB: return "Sub";
+ case SEQ_MUL: return "Mul";
+ case SEQ_ALPHAOVER: return "Alpha Over";
+ case SEQ_ALPHAUNDER: return "Alpha Under";
+ case SEQ_OVERDROP: return "Over Drop";
+ case SEQ_WIPE: return "Wipe";
+ case SEQ_GLOW: return "Glow";
+ case SEQ_TRANSFORM: return "Transform";
+ case SEQ_COLOR: return "Color";
+ case SEQ_SPEED: return "Speed";
+ default:
+ return 0;
+ }
+}
+
+char *give_seqname(Sequence *seq)
+{
+ char * name = give_seqname_by_type(seq->type);
+
+ if (!name) {
+ if(seq->type<SEQ_EFFECT) {
+ return seq->strip->dir;
+ } else if(seq->type==SEQ_PLUGIN) {
+ if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
+ seq->plugin && seq->plugin->doit) {
+ return seq->plugin->pname;
+ } else {
+ return "Plugin";
+ }
+ } else {
+ return "Effect";
+ }
+ }
+ return name;
+}
+
/* ***************** DO THE SEQUENCE ***************** */
static void make_black_ibuf(ImBuf *ibuf)
@@ -433,9 +674,9 @@ static void multibuf(ImBuf *ibuf, float fmul)
}
}
-static void do_effect(int cfra, Sequence *seq, StripElem *se)
+static void do_effect(int cfra, Sequence *seq, TStripElem * se)
{
- StripElem *se1, *se2, *se3;
+ TStripElem *se1, *se2, *se3;
float fac, facf;
int x, y;
int early_out;
@@ -447,7 +688,7 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
}
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq);
+ do_seq_ipo(seq, cfra);
fac= seq->facf0;
facf= seq->facf1;
} else {
@@ -459,7 +700,8 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
early_out = sh.early_out(seq, fac, facf);
if (early_out == -1) { /* no input needed */
- sh.execute(seq, cfra, fac, facf, se->ibuf->x, se->ibuf->y,
+ sh.execute(seq, cfra, fac, facf,
+ se->ibuf->x, se->ibuf->y,
0, 0, 0, se->ibuf);
return;
}
@@ -471,14 +713,13 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
return;
}
- /* if metastrip: other se's */
- if(se->se1->ok==2) se1= se->se1->se1;
+ if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
else se1= se->se1;
- if(se->se2->ok==2) se2= se->se2->se1;
+ if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
else se2= se->se2;
- if(se->se3->ok==2) se3= se->se3->se1;
+ if(se->se3->ok == STRIPELEM_META) se3= se->se3->se1;
else se3= se->se3;
if ( (se1==0 || se2==0 || se3==0)
@@ -494,8 +735,7 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
return;
}
- /* if metastrip: other se's */
- if(se->se1->ok==2) se1= se->se1->se1;
+ if(se->se1->ok == STRIPELEM_META) se1= se->se1->se1;
else se1= se->se1;
if (se1 == 0 || se1->ibuf == 0) {
@@ -515,8 +755,7 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
return;
}
- /* if metastrip: other se's */
- if(se->se2->ok==2) se2= se->se2->se1;
+ if(se->se2->ok == STRIPELEM_META) se2= se->se2->se1;
else se2= se->se2;
if (se2 == 0 || se2->ibuf == 0) {
@@ -555,19 +794,13 @@ static void do_effect(int cfra, Sequence *seq, StripElem *se)
se->ibuf);
}
-StripElem *give_stripelem(Sequence *seq, int cfra)
+static int give_stripelem_index(Sequence *seq, int cfra)
{
- Strip *strip;
- StripElem *se;
int nr;
- strip= seq->strip;
- se= strip->stripdata;
+ if(seq->startdisp >cfra || seq->enddisp <= cfra) return -1;
- if(se==0) return 0;
- if(seq->startdisp >cfra || seq->enddisp <= cfra) return 0;
-
- if(seq->flag&SEQ_REVERSE_FRAMES) {
+ if(seq->flag&SEQ_REVERSE_FRAMES) {
/*reverse frame in this sequence */
if(cfra <= seq->start) nr= seq->len-1;
else if(cfra >= seq->start+seq->len-1) nr= 0;
@@ -581,9 +814,102 @@ StripElem *give_stripelem(Sequence *seq, int cfra)
if (seq->strobe > 1.0) {
nr -= (int)fmod((double)nr, (double)seq->strobe);
}
+
+ return nr;
+}
+
+static TStripElem* alloc_tstripdata(int len, const char * name)
+{
+ int i;
+ TStripElem *se = MEM_callocN(len * sizeof(TStripElem), name);
+ for (i = 0; i < len; i++) {
+ se[i].ok = STRIPELEM_OK;
+ }
+ return se;
+}
+
+TStripElem *give_tstripelem(Sequence *seq, int cfra)
+{
+ TStripElem *se;
+ int nr;
+
+ se = seq->strip->tstripdata;
+ if (se == 0 && seq->len > 0) {
+ se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
+ "tstripelems");
+ }
+ nr = give_stripelem_index(seq, cfra);
+
+ if (nr == -1) return 0;
+ if (se == 0) return 0;
+
+ se += nr;
+
+ /* if there are IPOs with blend modes active, one has to watch out
+ for startstill + endstill area: we can't use the same tstripelem
+ here for all ibufs, since then, blending with IPOs won't work!
+
+ Rather common case, if you use a single image and try to fade
+ it in and out... or want to use your strip as a watermark in
+ alpha over mode...
+ */
+ if (seq->blend_mode != SEQ_BLEND_REPLACE ||
+ (seq->ipo && seq->ipo->curve.first && !(seq->type & SEQ_EFFECT))) {
+ Strip * s = seq->strip;
+ if (cfra < seq->start) {
+ se = s->tstripdata_startstill;
+ if (seq->startstill > s->startstill) {
+ free_tstripdata(s->startstill,
+ s->tstripdata_startstill);
+ se = 0;
+ }
+
+ if (se == 0) {
+ s->startstill = seq->startstill;
+ se = seq->strip->tstripdata_startstill
+ = alloc_tstripdata(
+ s->startstill,
+ "tstripelems_startstill");
+ }
+ se += seq->start - cfra - 1;
+
+ } else if (cfra > seq->start + seq->len-1) {
+ se = s->tstripdata_endstill;
+ if (seq->endstill > s->endstill) {
+ free_tstripdata(s->endstill,
+ s->tstripdata_endstill);
+ se = 0;
+ }
+
+ if (se == 0) {
+ s->endstill = seq->endstill;
+ se = seq->strip->tstripdata_endstill
+ = alloc_tstripdata(
+ s->endstill,
+ "tstripelems_endstill");
+ }
+ se += cfra - (seq->start + seq->len-1) - 1;
+ }
+ }
+
- se+= nr; /* don't get confused by the increment, this is the same as strip->stripdata[nr], which works on some compilers...*/
se->nr= nr;
+
+ return se;
+}
+
+StripElem *give_stripelem(Sequence *seq, int cfra)
+{
+ StripElem *se;
+ int nr;
+
+ se = seq->strip->stripdata;
+ nr = give_stripelem_index(seq, cfra);
+
+ if (nr == -1) return 0;
+ if (se == 0) return 0;
+
+ se += nr + seq->anim_startofs;
return se;
}
@@ -594,7 +920,7 @@ static int evaluate_seq_frame_gen(
Sequence *seq;
int totseq=0;
- memset(seq_arr, 0, sizeof(Sequence*) * MAXSEQ);
+ memset(seq_arr, 0, sizeof(Sequence*) * (MAXSEQ+1));
seq= seqbase->first;
while(seq) {
@@ -620,202 +946,810 @@ int evaluate_seq_frame(int cfra)
}
-Sequence *get_shown_sequence(ListBase * seqbasep, int cfra, int chanshown)
+static int video_seq_is_rendered(Sequence * seq)
{
- Sequence *seq, *seqim, *seqeff;
- Sequence *seq_arr[MAXSEQ+1];
- int b;
+ return (seq
+ && !(seq->flag & SEQ_MUTE)
+ && seq->type != SEQ_RAM_SOUND
+ && seq->type != SEQ_HD_SOUND);
+}
- seq = 0;
+static int get_shown_sequences(
+ ListBase * seqbasep, int cfra, int chanshown, Sequence ** seq_arr_out)
+{
+ Sequence *seq_arr[MAXSEQ+1];
+ int b = chanshown;
+ int cnt = 0;
- if (chanshown > MAXSEQ) {
+ if (b > MAXSEQ) {
return 0;
}
if(evaluate_seq_frame_gen(seq_arr, seqbasep, cfra)) {
- if (chanshown > 0) {
- return seq_arr[chanshown];
- }
-
- /* we take the upper effect strip or
- the lowest imagestrip/metastrip */
- seqim= seqeff= 0;
-
- for(b=1; b<MAXSEQ; b++) {
- if(seq_arr[b]) {
- seq= seq_arr[b];
- if(seq->type & SEQ_EFFECT) {
- if(seqeff==0) seqeff= seq;
- else if(seqeff->machine < seq->machine)
- seqeff= seq;
- } else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
- if(seqim==0) seqim= seq;
- else if(seqim->machine > seq->machine)
- seqim= seq;
+ if (b > 0) {
+ if (seq_arr[b] == 0) {
+ return 0;
+ }
+ } else {
+ for (b = MAXSEQ; b > 0; b--) {
+ if (video_seq_is_rendered(seq_arr[b])) {
+ break;
}
}
}
- if(seqeff) seq= seqeff;
- else if(seqim) seq= seqim;
- else seq= 0;
}
- return seq;
+ chanshown = b;
+
+ for (;b > 0; b--) {
+ if (video_seq_is_rendered(seq_arr[b])) {
+ if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) {
+ break;
+ }
+ }
+ }
+
+ for (;b <= chanshown; b++) {
+ if (video_seq_is_rendered(seq_arr[b])) {
+ seq_arr_out[cnt++] = seq_arr[b];
+ }
+ }
+
+ return cnt;
}
-static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
+static int get_shown_seq_from_metastrip(Sequence * seqm, int cfra,
+ Sequence ** seq_arr_out)
{
- return get_shown_sequence(&seqm->seqbase, cfra, 0);
+ return get_shown_sequences(&seqm->seqbase, cfra, 0, seq_arr_out);
}
void set_meta_stripdata(Sequence *seqm)
{
- Sequence *seq;
- StripElem *se;
+ TStripElem *se;
int a, cfra;
+ se= seqm->strip->tstripdata;
+
+ if (se == 0 && seqm->len > 0) {
+ int i;
+ se = seqm->strip->tstripdata = MEM_callocN(
+ seqm->len*sizeof(TStripElem), "tstripelems");
+ for (i = 0; i < seqm->len; i++) {
+ se[i].ok = STRIPELEM_META;
+ }
+ }
+
/* sets all ->se1 pointers in stripdata, to read the ibuf from it */
- se= seqm->strip->stripdata;
for(a=0; a<seqm->len; a++, se++) {
+ int cnt;
+ Sequence *seq_arr[MAXSEQ+1];
+
cfra= a+seqm->start;
- seq = get_shown_seq_from_metastrip(seqm, cfra);
- if (seq) {
- se->se1= give_stripelem(seq, cfra);
+ cnt = get_shown_seq_from_metastrip(seqm, cfra, seq_arr);
+ if (cnt) {
+ se->se1= give_tstripelem(seq_arr[cnt-1], cfra);
} else {
se->se1= 0;
}
}
}
-static void do_build_seq_ibuf(Sequence * seq, int cfra)
+/* **********************************************************************
+ proxy management
+ ********************************************************************** */
+
+#define PROXY_MAXFILE (2*FILE_MAXDIR+FILE_MAXFILE)
+
+static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
+{
+ int frameno;
+ char dir[FILE_MAXDIR];
+
+ if (!seq->strip->proxy) {
+ return FALSE;
+ }
+
+ if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ strcpy(dir, seq->strip->proxy->dir);
+ } else {
+ if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
+ snprintf(dir, FILE_MAXDIR, "%s/BL_proxy",
+ seq->strip->dir);
+ } else {
+ return FALSE;
+ }
+ }
+
+ /* generate a seperate proxy directory for each preview size */
+
+ if (seq->type == SEQ_IMAGE) {
+ StripElem * se = give_stripelem(seq, cfra);
+ snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy",
+ dir, G.scene->r.size, se->name);
+ frameno = 1;
+ } else if (seq->type == SEQ_MOVIE) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ frameno = tse->nr + seq->anim_startofs;
+
+ snprintf(name, PROXY_MAXFILE, "%s/%s/%d/#", dir,
+ seq->strip->stripdata->name,
+ G.scene->r.size);
+ } else {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ frameno = tse->nr + seq->anim_startofs;
+
+ snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/#", dir,
+ G.scene->r.size);
+ }
+
+ BLI_convertstringcode(name, G.sce, frameno);
+
+ strcat(name, ".jpg");
+
+ return TRUE;
+}
+
+static struct ImBuf * seq_proxy_fetch(Sequence * seq, int cfra)
+{
+ char name[PROXY_MAXFILE];
+
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return 0;
+ }
+
+ /* rendering at 100% ? No real sense in proxy-ing, right? */
+ if (G.scene->r.size == 100.0) {
+ return 0;
+ }
+
+ if (!seq_proxy_get_fname(seq, cfra, name)) {
+ return 0;
+ }
+
+ if (BLI_exists(name)) {
+ return IMB_loadiffname(name, IB_rect);
+ } else {
+ return 0;
+ }
+}
+
+static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
+ int build_proxy_run);
+
+static void seq_proxy_build_frame(Sequence * seq, int cfra)
+{
+ char name[PROXY_MAXFILE];
+ int quality;
+ TStripElem * se;
+ int ok;
+ int rectx, recty;
+ struct ImBuf * ibuf;
+
+ if (!(seq->flag & SEQ_USE_PROXY)) {
+ return;
+ }
+
+ /* rendering at 100% ? No real sense in proxy-ing, right? */
+ if (G.scene->r.size == 100.0) {
+ return;
+ }
+
+ if (!seq_proxy_get_fname(seq, cfra, name)) {
+ return;
+ }
+
+ se = give_tstripelem(seq, cfra);
+
+ if(se->ibuf) {
+ IMB_freeImBuf(se->ibuf);
+ se->ibuf = 0;
+ }
+
+ do_build_seq_ibuf(seq, se, cfra, TRUE);
+
+ if (!se->ibuf) {
+ return;
+ }
+
+ rectx= (G.scene->r.size*G.scene->r.xsch)/100;
+ recty= (G.scene->r.size*G.scene->r.ysch)/100;
+
+ ibuf = se->ibuf;
+
+ if (ibuf->x != rectx || ibuf->y != recty) {
+ IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
+ }
+
+ /* quality is fixed, otherwise one has to generate seperate
+ directories for every quality...
+
+ depth = 32 is intentionally left in, otherwise ALPHA channels
+ won't work... */
+ quality = 90;
+ ibuf->ftype= JPG | quality;
+
+ BLI_make_existing_file(name);
+
+ ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
+ if (ok == 0) {
+ perror(name);
+ }
+
+ IMB_freeImBuf(ibuf);
+ se->ibuf = 0;
+}
+
+void seq_proxy_rebuild(Sequence * seq)
+{
+ int cfra;
+
+ waitcursor(1);
+
+ G.afbreek = 0;
+
+ /* flag management tries to account for strobe and
+ other "non-linearities", that might come in the future...
+ better way would be to "touch" the files, so that _really_
+ no one is rebuild twice.
+ */
+
+ for (cfra = seq->startdisp; cfra < seq->enddisp; cfra++) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ tse->flag &= ~STRIPELEM_PREVIEW_DONE;
+ }
+
+ /* a _lot_ faster for movie files, if we read frames in
+ sequential order */
+ if (seq->flag & SEQ_REVERSE_FRAMES) {
+ for (cfra = seq->enddisp-seq->endstill-1;
+ cfra >= seq->startdisp + seq->startstill; cfra--) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
+ seq_proxy_build_frame(seq, cfra);
+ tse->flag |= STRIPELEM_PREVIEW_DONE;
+ }
+ if (blender_test_break()) {
+ break;
+ }
+ }
+ } else {
+ for (cfra = seq->startdisp + seq->startstill;
+ cfra < seq->enddisp - seq->endstill; cfra++) {
+ TStripElem * tse = give_tstripelem(seq, cfra);
+
+ if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
+ seq_proxy_build_frame(seq, cfra);
+ tse->flag |= STRIPELEM_PREVIEW_DONE;
+ }
+ if (blender_test_break()) {
+ break;
+ }
+ }
+ }
+ waitcursor(0);
+}
+
+
+/* **********************************************************************
+ color balance
+ ********************************************************************** */
+
+static StripColorBalance calc_cb(StripColorBalance * cb_)
+{
+ StripColorBalance cb = *cb_;
+ int c;
+
+ if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
+ for (c = 0; c < 3; c++) {
+ cb.lift[c] = 1.0 - cb.lift[c];
+ }
+ } else {
+ for (c = 0; c < 3; c++) {
+ cb.lift[c] = -(1.0 - cb.lift[c]);
+ }
+ }
+ if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
+ for (c = 0; c < 3; c++) {
+ if (cb.gain[c] != 0.0) {
+ cb.gain[c] = 1.0/cb.gain[c];
+ } else {
+ cb.gain[c] = 1000000; /* should be enough :) */
+ }
+ }
+ }
+
+ if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) {
+ for (c = 0; c < 3; c++) {
+ if (cb.gain[c] != 0.0) {
+ cb.gamma[c] = 1.0/cb.gamma[c];
+ } else {
+ cb.gamma[c] = 1000000; /* should be enough :) */
+ }
+ }
+ }
+
+ return cb;
+}
+
+static void make_cb_table_byte(float lift, float gain, float gamma,
+ unsigned char * table, float mul)
+{
+ int y;
+
+ for (y = 0; y < 256; y++) {
+ float v = 1.0 * y / 255;
+ v += lift;
+ v *= gain;
+ v = pow(v, gamma);
+ v *= mul;
+ if ( v > 1.0) {
+ v = 1.0;
+ } else if (v < 0.0) {
+ v = 0.0;
+ }
+ table[y] = v * 255;
+ }
+
+}
+
+static void make_cb_table_float(float lift, float gain, float gamma,
+ float * table, float mul)
+{
+ int y;
+
+ for (y = 0; y < 256; y++) {
+ float v = (float) y * 1.0 / 255.0;
+ v += lift;
+ v *= gain;
+ v = pow(v, gamma);
+ v *= mul;
+ table[y] = v;
+ }
+}
+
+static void color_balance_byte_byte(Sequence * seq, TStripElem* se,
+ float mul)
+{
+ unsigned char cb_tab[3][256];
+ int c;
+ unsigned char * p = (unsigned char*) se->ibuf->rect;
+ unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
+
+ StripColorBalance cb = calc_cb(seq->strip->color_balance);
+
+ for (c = 0; c < 3; c++) {
+ make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c],
+ cb_tab[c], mul);
+ }
+
+ while (p < e) {
+ p[0] = cb_tab[0][p[0]];
+ p[1] = cb_tab[1][p[1]];
+ p[2] = cb_tab[2][p[2]];
+
+ p += 4;
+ }
+}
+
+static void color_balance_byte_float(Sequence * seq, TStripElem* se,
+ float mul)
+{
+ float cb_tab[4][256];
+ int c,i;
+ unsigned char * p = (unsigned char*) se->ibuf->rect;
+ unsigned char * e = p + se->ibuf->x * 4 * se->ibuf->y;
+ float * o;
+ StripColorBalance cb;
+
+ imb_addrectfloatImBuf(se->ibuf);
+
+ o = se->ibuf->rect_float;
+
+ cb = calc_cb(seq->strip->color_balance);
+
+ for (c = 0; c < 3; c++) {
+ make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
+ cb_tab[c], mul);
+ }
+
+ for (i = 0; i < 256; i++) {
+ cb_tab[3][i] = ((float)i)*(1.0f/255.0f);
+ }
+
+ while (p < e) {
+ o[0] = cb_tab[0][p[0]];
+ o[1] = cb_tab[1][p[1]];
+ o[2] = cb_tab[2][p[2]];
+ o[3] = cb_tab[3][p[3]];
+
+ p += 4; o += 4;
+ }
+}
+
+static void color_balance_float_float(Sequence * seq, TStripElem* se,
+ float mul)
+{
+ float * p = se->ibuf->rect_float;
+ float * e = se->ibuf->rect_float + se->ibuf->x * 4* se->ibuf->y;
+ StripColorBalance cb = calc_cb(seq->strip->color_balance);
+
+ while (p < e) {
+ int c;
+ for (c = 0; c < 3; c++) {
+ p[c] = pow((p[c] + cb.lift[c]) * cb.gain[c],
+ cb.gamma[c]) * mul;
+ }
+ p += 4;
+ }
+}
+
+static void color_balance(Sequence * seq, TStripElem* se, float mul)
+{
+ if (se->ibuf->rect_float) {
+ color_balance_float_float(seq, se, mul);
+ } else if(seq->flag & SEQ_MAKE_FLOAT) {
+ color_balance_byte_float(seq, se, mul);
+ } else {
+ color_balance_byte_byte(seq, se, mul);
+ }
+}
+
+/*
+ input preprocessing for SEQ_IMAGE, SEQ_MOVIE and SEQ_SCENE
+
+ Do all the things you can't really do afterwards using sequence effects
+ (read: before rescaling to render resolution has been done)
+
+ Order is important!
+
+ - Deinterlace
+ - Crop and transform in image source coordinate space
+ - Flip X + Flip Y (could be done afterwards, backward compatibility)
+ - Promote image to float data (affects pipeline operations afterwards)
+ - Color balance (is most efficient in the byte -> float
+ (future: half -> float should also work fine!)
+ case, if done on load, since we can use lookup tables)
+ - Premultiply
+
+*/
+
+static void input_preprocess(Sequence * seq, TStripElem* se, int cfra)
+{
+ float mul;
+
+ seq->strip->orx= se->ibuf->x;
+ seq->strip->ory= se->ibuf->y;
+
+ if(seq->flag & SEQ_FILTERY) {
+ IMB_filtery(se->ibuf);
+ }
+
+ if(seq->flag & SEQ_USE_CROP || seq->flag & SEQ_USE_TRANSFORM) {
+ StripCrop c;
+ StripTransform t;
+
+ memset(&c, 0, sizeof(StripCrop));
+ memset(&t, 0, sizeof(StripTransform));
+
+ if(seq->flag & SEQ_USE_CROP && seq->strip->crop) {
+ c = *seq->strip->crop;
+ }
+ if(seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
+ t = *seq->strip->transform;
+ }
+
+ if (c.top + c.bottom >= se->ibuf->y ||
+ c.left + c.right >= se->ibuf->x ||
+ t.xofs >= se->ibuf->x ||
+ t.yofs >= se->ibuf->y) {
+ make_black_ibuf(se->ibuf);
+ } else {
+ ImBuf * i;
+ int sx = se->ibuf->x - c.left - c.right;
+ int sy = se->ibuf->y - c.top - c.bottom;
+ int dx = sx;
+ int dy = sy;
+
+ if (seq->flag & SEQ_USE_TRANSFORM) {
+ dx = seqrectx;
+ dy = seqrecty;
+ }
+
+ if (se->ibuf->rect_float) {
+ i = IMB_allocImBuf(dx, dy,32, IB_rectfloat, 0);
+ } else {
+ i = IMB_allocImBuf(dx, dy,32, IB_rect, 0);
+ }
+
+ IMB_rectcpy(i, se->ibuf,
+ t.xofs, t.yofs,
+ c.left, c.bottom,
+ sx, sy);
+
+ IMB_freeImBuf(se->ibuf);
+
+ se->ibuf = i;
+ }
+ }
+
+ if(seq->flag & SEQ_FLIPX) {
+ IMB_flipx(se->ibuf);
+ }
+ if(seq->flag & SEQ_FLIPY) {
+ IMB_flipy(se->ibuf);
+ }
+
+ if(seq->mul == 0.0) {
+ seq->mul = 1.0;
+ }
+
+ mul = seq->mul;
+
+ if(seq->blend_mode == SEQ_BLEND_REPLACE) {
+ if (seq->ipo && seq->ipo->curve.first) {
+ do_seq_ipo(seq, cfra);
+ mul *= seq->facf0;
+ }
+ mul *= seq->blend_opacity / 100.0;
+ }
+
+ if(seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
+ color_balance(seq, se, mul);
+ mul = 1.0;
+ }
+
+ if(seq->flag & SEQ_MAKE_FLOAT) {
+ if (!se->ibuf->rect_float) {
+ IMB_float_from_rect(se->ibuf);
+ }
+ if (se->ibuf->rect) {
+ imb_freerectImBuf(se->ibuf);
+ }
+ }
+
+ if(mul != 1.0) {
+ multibuf(se->ibuf, mul);
+ }
+
+ if(seq->flag & SEQ_MAKE_PREMUL) {
+ if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
+ converttopremul(se->ibuf);
+ }
+ }
+
+
+ if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
+ if(G.scene->r.mode & R_OSA) {
+ IMB_scaleImBuf(se->ibuf,
+ (short)seqrectx, (short)seqrecty);
+ } else {
+ IMB_scalefastImBuf(se->ibuf,
+ (short)seqrectx, (short)seqrecty);
+ }
+ }
+}
+
+/* test if image too small or discarded from cache: reload */
+
+static void test_and_auto_discard_ibuf(TStripElem * se)
+{
+ if (se->ibuf) {
+ if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
+ || !(se->ibuf->rect || se->ibuf->rect_float)) {
+ IMB_freeImBuf(se->ibuf);
+
+ se->ibuf= 0;
+ se->ok= STRIPELEM_OK;
+ }
+ }
+ if (se->ibuf_comp) {
+ if(se->ibuf_comp->x != seqrectx || se->ibuf_comp->y != seqrecty
+ || !(se->ibuf_comp->rect || se->ibuf_comp->rect_float)) {
+ IMB_freeImBuf(se->ibuf_comp);
+
+ se->ibuf_comp = 0;
+ }
+ }
+}
+
+static void test_and_auto_discard_ibuf_stills(Strip * strip)
+{
+ if (strip->ibuf_startstill) {
+ if (!strip->ibuf_startstill->rect &&
+ !strip->ibuf_startstill->rect_float) {
+ IMB_freeImBuf(strip->ibuf_startstill);
+ strip->ibuf_startstill = 0;
+ }
+ }
+ if (strip->ibuf_endstill) {
+ if (!strip->ibuf_endstill->rect &&
+ !strip->ibuf_endstill->rect_float) {
+ IMB_freeImBuf(strip->ibuf_endstill);
+ strip->ibuf_endstill = 0;
+ }
+ }
+}
+
+static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
+{
+ if (!se->ibuf) {
+ if (se->nr == 0 && seq->strip->ibuf_startstill) {
+ IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
+
+ se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
+ }
+ if (se->nr == seq->len - 1
+ && (seq->len != 1)
+ && seq->strip->ibuf_endstill) {
+ IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
+
+ se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
+ }
+ }
+}
+
+static void copy_to_ibuf_still(Sequence * seq, TStripElem * se)
+{
+ if (se->ibuf) {
+ if (se->nr == 0) {
+ seq->strip->ibuf_startstill = IMB_dupImBuf(se->ibuf);
+
+ IMB_cache_limiter_insert(seq->strip->ibuf_startstill);
+ IMB_cache_limiter_touch(seq->strip->ibuf_startstill);
+ }
+ if (se->nr == seq->len - 1 && seq->len != 1) {
+ seq->strip->ibuf_endstill = IMB_dupImBuf(se->ibuf);
+
+ IMB_cache_limiter_insert(seq->strip->ibuf_endstill);
+ IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
+ }
+ }
+}
+
+
+static TStripElem* do_build_seq_array_recursively(
+ ListBase *seqbasep, int cfra, int chanshown);
+
+static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
+ int build_proxy_run)
{
- StripElem *se = seq->curelem;
char name[FILE_MAXDIR+FILE_MAXFILE];
+
+ if (seq->type != SEQ_META) {
+ test_and_auto_discard_ibuf(se);
+ test_and_auto_discard_ibuf_stills(seq->strip);
+ }
+
if(seq->type == SEQ_META) {
- se->ok= 2;
- if(se->se1==0) set_meta_stripdata(seq);
- if(se->se1) {
- se->ibuf= se->se1->ibuf;
+ if(seq->seqbase.first) {
+ if(cfra < seq->start) {
+ do_build_seq_array_recursively(
+ &seq->seqbase,
+ seq->start, 0);
+ } else if(cfra > seq->start + seq->len - 1) {
+ do_build_seq_array_recursively(
+ &seq->seqbase,
+ seq->start + seq->len - 1, 0);
+ } else {
+ do_build_seq_array_recursively(
+ &seq->seqbase,
+ cfra, 0);
+ }
}
- } else if(seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
- se->ok= 2;
- } else if(seq->type & SEQ_EFFECT) {
-
- /* test if image is too small or discarded from cache: reload */
- if(se->ibuf) {
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
+
+ se->ok = STRIPELEM_META;
+ if(se->se1 == 0) set_meta_stripdata(seq);
+ if(se->se1) {
+ if(se->ibuf) {
IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
+ }
+ se->ibuf = se->se1->ibuf_comp;
+ if(se->ibuf) {
+ IMB_refImBuf(se->ibuf);
}
}
-
+ } else if(seq->type & SEQ_EFFECT) {
/* should the effect be recalculated? */
- if(se->ibuf==0
- || (seq->seq1 && se->se1 != seq->seq1->curelem)
- || (seq->seq2 && se->se2 != seq->seq2->curelem)
- || (seq->seq3 && se->se3 != seq->seq3->curelem)) {
- if (seq->seq1) se->se1= seq->seq1->curelem;
- if (seq->seq2) se->se2= seq->seq2->curelem;
- if (seq->seq3) se->se3= seq->seq3->curelem;
-
- if(se->ibuf==NULL) {
- /* if one of two first inputs are rectfloat, output is float too */
- if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
- (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
- else
- se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
- }
+ if (!build_proxy_run && se->ibuf == 0) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ }
+
+ if(se->ibuf == 0) {
+ /* if one of two first inputs are rectfloat, output is float too */
+ if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
+ (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
+ else
+ se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
do_effect(cfra, seq, se);
}
-
- /* test size */
- if(se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
- if(G.scene->r.mode & R_OSA) {
- IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- } else {
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- }
+ } else if(seq->type == SEQ_IMAGE) {
+ if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
+ StripElem * s_elem = give_stripelem(seq, cfra);
+
+ strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
+ strncat(name, s_elem->name, FILE_MAXFILE);
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+ if (!build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
}
- }
- } else if(seq->type < SEQ_EFFECT) {
- if(se->ibuf) {
- /* test if image too small
- or discarded from cache: reload */
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- se->ok= 1;
+ copy_from_ibuf_still(seq, se);
+
+ if (!se->ibuf) {
+ se->ibuf= IMB_loadiffname(
+ name, IB_rect);
+ copy_to_ibuf_still(seq, se);
}
- }
-
- if(seq->type==SEQ_IMAGE) {
- if(se->ok && se->ibuf==0) {
- /* if playanim or render:
- no waitcursor */
- if((G.f & G_PLAYANIM)==0)
- waitcursor(1);
-
- strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
- strncat(name, se->name, FILE_MAXFILE);
- BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
- se->ibuf= IMB_loadiffname(name, IB_rect);
-
- if((G.f & G_PLAYANIM)==0)
- waitcursor(0);
-
- if(se->ibuf==0) se->ok= 0;
- else {
- if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth==32 && se->ibuf->zbuf==0) converttopremul(se->ibuf);
- }
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
- if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
- if(seq->mul==0.0) seq->mul= 1.0;
- if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
- }
+
+ if(se->ibuf == 0) {
+ se->ok = STRIPELEM_FAILED;
+ } else if (!build_proxy_run) {
+ input_preprocess(seq, se, cfra);
}
}
- else if(seq->type==SEQ_MOVIE) {
- if(se->ok && se->ibuf==0) {
+ } else if(seq->type == SEQ_MOVIE) {
+ if(se->ok == STRIPELEM_OK && se->ibuf==0) {
+ if(!build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ }
+ copy_from_ibuf_still(seq, se);
+
+ if (se->ibuf == 0) {
if(seq->anim==0) {
strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
-
+
seq->anim = openanim(name, IB_rect);
}
if(seq->anim) {
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
- se->ibuf = IMB_anim_absolute(seq->anim, se->nr);
- }
-
- if(se->ibuf==0) se->ok= 0;
- else {
- if(seq->flag & SEQ_MAKE_PREMUL) {
- if(se->ibuf->depth==32) converttopremul(se->ibuf);
- }
- seq->strip->orx= se->ibuf->x;
- seq->strip->ory= se->ibuf->y;
- if(seq->flag & SEQ_FILTERY) IMB_filtery(se->ibuf);
- if(seq->mul==0.0) seq->mul= 1.0;
- if(seq->mul != 1.0) multibuf(se->ibuf, seq->mul);
+ se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
}
+ copy_to_ibuf_still(seq, se);
+ }
+
+ if(se->ibuf == 0) {
+ se->ok = STRIPELEM_FAILED;
+ } else if (!build_proxy_run) {
+ input_preprocess(seq, se, cfra);
}
- } else if(seq->type==SEQ_SCENE && se->ibuf==NULL && seq->scene) { // scene can be NULL after deletions
- int oldcfra = CFRA;
- Scene *sce= seq->scene, *oldsce= G.scene;
- Render *re;
- RenderResult rres;
- int doseq, rendering= G.rendering;
- char scenename[64];
+ }
+ } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
+ int oldcfra = CFRA;
+ Scene *sce= seq->scene, *oldsce= G.scene;
+ Render *re;
+ RenderResult rres;
+ int doseq, rendering= G.rendering;
+ char scenename[64];
+ int sce_valid =sce&& (sce->camera || sce->r.scemode & R_DOSEQ);
+ if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
+ se->ibuf = seq_proxy_fetch(seq, cfra);
+ if (se->ibuf) {
+ input_preprocess(seq, se, cfra);
+ }
+ }
+
+ if (se->ibuf == NULL && sce_valid) {
+ copy_from_ibuf_still(seq, se);
+ if (se->ibuf) {
+ input_preprocess(seq, se, cfra);
+ }
+ }
+
+ if (!sce_valid) {
+ se->ok = STRIPELEM_FAILED;
+ } else if (se->ibuf==NULL && sce_valid) {
waitcursor(1);
/* Hack! This function can be called from do_render_seq(), in that case
@@ -832,14 +1766,15 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
re= RE_NewRender(sce->id.name);
/* prevent eternal loop */
- doseq= sce->r.scemode & R_DOSEQ;
- sce->r.scemode &= ~R_DOSEQ;
+ doseq= G.scene->r.scemode & R_DOSEQ;
+ G.scene->r.scemode &= ~R_DOSEQ;
BIF_init_render_callbacks(re, 0); /* 0= no display callbacks */
/* hrms, set_scene still needed? work on that... */
if(sce!=oldsce) set_scene_bg(sce);
- RE_BlenderFrame(re, sce, seq->sfra + se->nr);
+ RE_BlenderFrame(re, sce,
+ seq->sfra+se->nr+seq->anim_startofs);
if(sce!=oldsce) set_scene_bg(oldsce);
/* UGLY WARNING, it is set to zero in RE_BlenderFrame */
@@ -856,62 +1791,55 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
addzbuffloatImBuf(se->ibuf);
memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
}
+ } else if (rres.rect32) {
+ se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
+ memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
}
BIF_end_render_callbacks();
/* restore */
- sce->r.scemode |= doseq;
+ G.scene->r.scemode |= doseq;
if((G.f & G_PLAYANIM)==0) /* bad, is set on do_render_seq */
waitcursor(0);
CFRA = oldcfra;
- }
-
- /* size test */
- if(se->ibuf) {
- if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
-
- if (0) { // G.scene->r.mode & R_FIELDS) {
-
- if (seqrecty > 288)
- IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- else {
- IMB_de_interlace(se->ibuf);
-
- if(G.scene->r.mode & R_OSA)
- IMB_scaleImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- else
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
- }
- }
- else {
- if(G.scene->r.mode & R_OSA)
- IMB_scaleImBuf(se->ibuf,(short)seqrectx, (short)seqrecty);
- else
- IMB_scalefastImBuf(se->ibuf, (short)seqrectx, (short)seqrecty);
+
+ copy_to_ibuf_still(seq, se);
+
+ if (!build_proxy_run) {
+ if(se->ibuf == NULL) {
+ se->ok = STRIPELEM_FAILED;
+ } else {
+ input_preprocess(seq, se, cfra);
}
}
-
- }
+
+ }
}
- if (se->ibuf) {
- IMB_cache_limiter_insert(se->ibuf);
- IMB_cache_limiter_ref(se->ibuf);
- IMB_cache_limiter_touch(se->ibuf);
+ if (!build_proxy_run) {
+ if (se->ibuf && seq->type != SEQ_META) {
+ IMB_cache_limiter_insert(se->ibuf);
+ IMB_cache_limiter_ref(se->ibuf);
+ IMB_cache_limiter_touch(se->ibuf);
+ }
}
}
-static void do_build_seq_recursively(Sequence * seq, int cfra);
+static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra);
-static void do_effect_seq_recursively(int cfra, Sequence * seq, StripElem *se)
+static void do_effect_seq_recursively(Sequence * seq, TStripElem *se, int cfra)
{
float fac, facf;
struct SeqEffectHandle sh = get_sequence_effect(seq);
int early_out;
+ se->se1 = 0;
+ se->se2 = 0;
+ se->se3 = 0;
+
if(seq->ipo && seq->ipo->curve.first) {
- do_seq_ipo(seq);
+ do_seq_ipo(seq, cfra);
fac= seq->facf0;
facf= seq->facf1;
} else {
@@ -926,79 +1854,50 @@ static void do_effect_seq_recursively(int cfra, Sequence * seq, StripElem *se)
/* no input needed */
break;
case 0:
- do_build_seq_recursively(seq->seq1, cfra);
- do_build_seq_recursively(seq->seq2, cfra);
+ se->se1 = do_build_seq_recursively(seq->seq1, cfra);
+ se->se2 = do_build_seq_recursively(seq->seq2, cfra);
if (seq->seq3) {
- do_build_seq_recursively(seq->seq3, cfra);
+ se->se3 = do_build_seq_recursively(seq->seq3, cfra);
}
break;
case 1:
- do_build_seq_recursively(seq->seq1, cfra);
+ se->se1 = do_build_seq_recursively(seq->seq1, cfra);
break;
case 2:
- do_build_seq_recursively(seq->seq2, cfra);
+ se->se2 = do_build_seq_recursively(seq->seq2, cfra);
break;
}
- do_build_seq_ibuf(seq, cfra);
+ do_build_seq_ibuf(seq, se, cfra, FALSE);
/* children are not needed anymore ... */
- switch (early_out) {
- case 0:
- if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
- IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
- if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
- IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
- if (seq->seq3) {
- if (seq->seq3->curelem && seq->seq3->curelem->ibuf)
- IMB_cache_limiter_unref(
- seq->seq3->curelem->ibuf);
- }
- break;
- case 1:
- if (seq->seq1->curelem && seq->seq1->curelem->ibuf)
- IMB_cache_limiter_unref(seq->seq1->curelem->ibuf);
- break;
- case 2:
- if (seq->seq2->curelem && seq->seq2->curelem->ibuf)
- IMB_cache_limiter_unref(seq->seq2->curelem->ibuf);
- break;
+ if (se->se1 && se->se1->ibuf) {
+ IMB_cache_limiter_unref(se->se1->ibuf);
+ }
+ if (se->se2 && se->se2->ibuf) {
+ IMB_cache_limiter_unref(se->se2->ibuf);
+ }
+ if (se->se3 && se->se3->ibuf) {
+ IMB_cache_limiter_unref(se->se3->ibuf);
}
}
-static void do_build_seq_recursively_impl(Sequence * seq, int cfra)
+static TStripElem* do_build_seq_recursively_impl(Sequence * seq, int cfra)
{
- StripElem *se;
+ TStripElem *se;
- se = seq->curelem = give_stripelem(seq, cfra);
+ se = give_tstripelem(seq, cfra);
if(se) {
- int unref_meta = FALSE;
- if(seq->seqbase.first) {
- Sequence * seqmshown= get_shown_seq_from_metastrip(seq, cfra);
- if (seqmshown) {
- if(cfra< seq->start)
- do_build_seq_recursively(seqmshown, seq->start);
- else if(cfra> seq->start+seq->len-1)
- do_build_seq_recursively(seqmshown, seq->start + seq->len-1);
- else do_build_seq_recursively(seqmshown, cfra);
-
- unref_meta = TRUE;
- }
- }
-
if (seq->type & SEQ_EFFECT) {
- do_effect_seq_recursively(cfra, seq, se);
+ do_effect_seq_recursively(seq, se, cfra);
} else {
- do_build_seq_ibuf(seq, cfra);
- }
-
- if(unref_meta && seq->curelem->ibuf) {
- IMB_cache_limiter_unref(seq->curelem->ibuf);
+ do_build_seq_ibuf(seq, se, cfra, FALSE);
}
}
+ return se;
}
/* FIXME:
@@ -1009,16 +1908,16 @@ instead of faking using the blend code below...
*/
-static void do_handle_speed_effect(Sequence * seq, int cfra)
+static TStripElem* do_handle_speed_effect(Sequence * seq, int cfra)
{
SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
int nr = cfra - seq->start;
float f_cfra;
int cfra_left;
int cfra_right;
- StripElem * se = 0;
- StripElem * se1 = 0;
- StripElem * se2 = 0;
+ TStripElem * se = 0;
+ TStripElem * se1 = 0;
+ TStripElem * se2 = 0;
sequence_effect_speed_rebuild_map(seq, 0);
@@ -1027,22 +1926,15 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
cfra_left = (int) floor(f_cfra);
cfra_right = (int) ceil(f_cfra);
- se = seq->curelem = give_stripelem(seq, cfra);
+ se = give_tstripelem(seq, cfra);
if (cfra_left == cfra_right ||
(s->flags & SEQ_SPEED_BLEND) == 0) {
- if(se->ibuf) {
- if(se->ibuf->x < seqrectx || se->ibuf->y < seqrecty
- || !(se->ibuf->rect || se->ibuf->rect_float)) {
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- }
- }
+ test_and_auto_discard_ibuf(se);
if (se->ibuf == NULL) {
- do_build_seq_recursively_impl(seq->seq1, cfra_left);
-
- se1 = seq->seq1->curelem;
+ se1 = do_build_seq_recursively_impl(
+ seq->seq1, cfra_left);
if((se1 && se1->ibuf && se1->ibuf->rect_float))
se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -1074,11 +1966,10 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
}
if (se->ibuf == NULL) {
- do_build_seq_recursively_impl(seq->seq1, cfra_left);
- se1 = seq->seq1->curelem;
- do_build_seq_recursively_impl(seq->seq1, cfra_right);
- se2 = seq->seq1->curelem;
-
+ se1 = do_build_seq_recursively_impl(
+ seq->seq1, cfra_left);
+ se2 = do_build_seq_recursively_impl(
+ seq->seq1, cfra_right);
if((se1 && se1->ibuf && se1->ibuf->rect_float))
se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -1112,35 +2003,248 @@ static void do_handle_speed_effect(Sequence * seq, int cfra)
IMB_cache_limiter_unref(se1->ibuf);
if (se2 && se2->ibuf)
IMB_cache_limiter_unref(se2->ibuf);
+
+ return se;
}
/*
* build all ibufs recursively
*
- * if successfull, seq->curelem->ibuf contains the (referenced!) imbuf
+ * if successfull, the returned TStripElem contains the (referenced!) imbuf
* that means: you _must_ call
*
- * IMB_cache_limiter_unref(seq->curelem->ibuf);
+ * IMB_cache_limiter_unref(rval);
*
- * if seq->curelem exists!
+ * if rval != 0
*
*/
-static void do_build_seq_recursively(Sequence * seq, int cfra)
+static TStripElem* do_build_seq_recursively(Sequence * seq, int cfra)
{
if (seq->type == SEQ_SPEED) {
- do_handle_speed_effect(seq, cfra);
+ return do_handle_speed_effect(seq, cfra);
} else {
- do_build_seq_recursively_impl(seq, cfra);
+ return do_build_seq_recursively_impl(seq, cfra);
}
}
-ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
+static TStripElem* do_build_seq_array_recursively(
+ ListBase *seqbasep, int cfra, int chanshown)
+{
+ Sequence* seq_arr[MAXSEQ+1];
+ int count;
+ int i;
+ TStripElem* se = 0;
+
+ count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
+
+ if (!count) {
+ return 0;
+ }
+
+ se = give_tstripelem(seq_arr[count - 1], cfra);
+
+ test_and_auto_discard_ibuf(se);
+
+ if (se->ibuf_comp != 0) {
+ IMB_cache_limiter_insert(se->ibuf_comp);
+ IMB_cache_limiter_ref(se->ibuf_comp);
+ IMB_cache_limiter_touch(se->ibuf_comp);
+ return se;
+ }
+
+
+ if(count == 1) {
+ se = do_build_seq_recursively(seq_arr[0], cfra);
+ if (se->ibuf) {
+ se->ibuf_comp = se->ibuf;
+ IMB_refImBuf(se->ibuf_comp);
+ }
+ return se;
+ }
+
+
+ for (i = count - 1; i >= 0; i--) {
+ int early_out;
+ Sequence * seq = seq_arr[i];
+ struct SeqEffectHandle sh;
+
+ se = give_tstripelem(seq, cfra);
+
+ test_and_auto_discard_ibuf(se);
+
+ if (se->ibuf_comp != 0) {
+ break;
+ }
+ if (seq->blend_mode == SEQ_BLEND_REPLACE) {
+ do_build_seq_recursively(seq, cfra);
+ if (se->ibuf) {
+ se->ibuf_comp = se->ibuf;
+ IMB_refImBuf(se->ibuf);
+ } else {
+ se->ibuf_comp = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rect, 0);
+ }
+ break;
+ }
+
+ sh = get_sequence_blend(seq);
+
+ seq->facf0 = seq->facf1 = 1.0;
+
+ if(seq->ipo && seq->ipo->curve.first) {
+ do_seq_ipo(seq, cfra);
+ }
+
+ if( G.scene->r.mode & R_FIELDS ); else seq->facf0 = seq->facf1;
+
+ seq->facf0 *= seq->blend_opacity / 100.0;
+ seq->facf1 *= seq->blend_opacity / 100.0;
+
+ early_out = sh.early_out(seq, seq->facf0, seq->facf1);
+
+ switch (early_out) {
+ case -1:
+ case 2:
+ do_build_seq_recursively(seq, cfra);
+ if (se->ibuf) {
+ se->ibuf_comp = se->ibuf;
+ IMB_refImBuf(se->ibuf_comp);
+ } else {
+ se->ibuf_comp = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rect, 0);
+ }
+ break;
+ case 1:
+ if (i == 0) {
+ se->ibuf_comp = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rect, 0);
+ IMB_cache_limiter_insert(se->ibuf_comp);
+ IMB_cache_limiter_ref(se->ibuf_comp);
+ IMB_cache_limiter_touch(se->ibuf_comp);
+ }
+ break;
+ case 0:
+ do_build_seq_recursively(seq, cfra);
+ if (!se->ibuf) {
+ se->ibuf = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rect, 0);
+ }
+ if (i == 0) {
+ se->ibuf_comp = se->ibuf;
+ IMB_refImBuf(se->ibuf_comp);
+ }
+ break;
+ }
+
+ if (se->ibuf_comp) {
+ break;
+ }
+ }
+
+ i++;
+
+ for (; i < count; i++) {
+ Sequence * seq = seq_arr[i];
+ struct SeqEffectHandle sh = get_sequence_blend(seq);
+ TStripElem* se1 = give_tstripelem(seq_arr[i-1], cfra);
+ TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
+
+ int early_out = sh.early_out(seq, seq->facf0, seq->facf1);
+ switch (early_out) {
+ case 0: {
+ int x= se2->ibuf->x;
+ int y= se2->ibuf->y;
+ int swap_input = FALSE;
+
+ if (se1->ibuf_comp->rect_float ||
+ se2->ibuf->rect_float) {
+ se2->ibuf_comp = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rectfloat, 0);
+ } else {
+ se2->ibuf_comp = IMB_allocImBuf(
+ (short)seqrectx, (short)seqrecty,
+ 32, IB_rect, 0);
+ }
+
+
+ if (!se1->ibuf_comp->rect_float &&
+ se2->ibuf_comp->rect_float) {
+ IMB_float_from_rect(se1->ibuf_comp);
+ }
+ if (!se2->ibuf->rect_float &&
+ se2->ibuf_comp->rect_float) {
+ IMB_float_from_rect(se2->ibuf);
+ }
+
+ if (!se1->ibuf_comp->rect &&
+ !se2->ibuf_comp->rect_float) {
+ IMB_rect_from_float(se1->ibuf_comp);
+ }
+ if (!se2->ibuf->rect &&
+ !se2->ibuf_comp->rect_float) {
+ IMB_rect_from_float(se2->ibuf);
+ }
+
+ /* bad hack, to fix crazy input ordering of
+ those two effects */
+
+ if (seq->blend_mode == SEQ_ALPHAOVER ||
+ seq->blend_mode == SEQ_ALPHAUNDER ||
+ seq->blend_mode == SEQ_OVERDROP) {
+ swap_input = TRUE;
+ }
+
+ if (swap_input) {
+ sh.execute(seq, cfra,
+ seq->facf0, seq->facf1, x, y,
+ se2->ibuf, se1->ibuf_comp, 0,
+ se2->ibuf_comp);
+ } else {
+ sh.execute(seq, cfra,
+ seq->facf0, seq->facf1, x, y,
+ se1->ibuf_comp, se2->ibuf, 0,
+ se2->ibuf_comp);
+ }
+
+ IMB_cache_limiter_insert(se2->ibuf_comp);
+ IMB_cache_limiter_ref(se2->ibuf_comp);
+ IMB_cache_limiter_touch(se2->ibuf_comp);
+
+ IMB_cache_limiter_unref(se1->ibuf_comp);
+ IMB_cache_limiter_unref(se2->ibuf);
+
+ break;
+ }
+ case 1: {
+ se2->ibuf_comp = se1->ibuf;
+ IMB_refImBuf(se2->ibuf_comp);
+
+ break;
+ }
+ }
+ se = se2;
+ }
+
+ return se;
+}
+
+/*
+ * returned ImBuf is refed!
+ * you have to unref after usage!
+ */
+
+static ImBuf *give_ibuf_seq_impl(int rectx, int recty, int cfra, int chanshown)
{
- Sequence *seqfirst=0;
Editing *ed;
int count;
ListBase *seqbasep;
+ TStripElem *se;
ed= G.scene->ed;
if(ed==0) return 0;
@@ -1156,37 +2260,378 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
seqrectx= rectx; /* bad bad global! */
seqrecty= recty;
- seqfirst = get_shown_sequence(seqbasep, cfra, chanshown);
+ se = do_build_seq_array_recursively(seqbasep, cfra, chanshown);
- if (!seqfirst) {
+ if(!se) {
return 0;
}
- do_build_seq_recursively(seqfirst, cfra);
+ return se->ibuf_comp;
+}
+
+ImBuf *give_ibuf_seq_direct(int rectx, int recty, int cfra,
+ Sequence * seq)
+{
+ TStripElem* se;
+
+ seqrectx= rectx; /* bad bad global! */
+ seqrecty= recty;
+
+ se = do_build_seq_recursively(seq, cfra);
- if(!seqfirst->curelem) {
+ if(!se) {
return 0;
}
- if (seqfirst->curelem->ibuf) {
- IMB_cache_limiter_unref(seqfirst->curelem->ibuf);
+ if (se->ibuf) {
+ IMB_cache_limiter_unref(se->ibuf);
+ }
+
+ return se->ibuf;
+}
+
+ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
+{
+ ImBuf* i = give_ibuf_seq_impl(rectx, recty, cfra, chanshown);
+
+ if (i) {
+ IMB_cache_limiter_unref(i);
+ }
+ return i;
+}
+
+/* threading api */
+
+static ListBase running_threads;
+static ListBase prefetch_wait;
+static ListBase prefetch_done;
+
+static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t wakeup_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
+
+static volatile int seq_thread_shutdown = FALSE;
+static volatile int seq_last_given_monoton_cfra = 0;
+static int monoton_cfra = 0;
+
+typedef struct PrefetchThread {
+ struct PrefetchThread *next, *prev;
+ struct PrefetchQueueElem *current;
+ pthread_t pthread;
+ int running;
+} PrefetchThread;
+
+typedef struct PrefetchQueueElem {
+ struct PrefetchQueueElem *next, *prev;
+
+ int rectx;
+ int recty;
+ int cfra;
+ int chanshown;
+
+ int monoton_cfra;
+
+ struct ImBuf * ibuf;
+} PrefetchQueueElem;
+
+static void * seq_prefetch_thread(void * This_)
+{
+ PrefetchThread * This = This_;
+
+ while (!seq_thread_shutdown) {
+ PrefetchQueueElem * e;
+ int s_last;
+
+ pthread_mutex_lock(&queue_lock);
+ e = prefetch_wait.first;
+ if (e) {
+ BLI_remlink(&prefetch_wait, e);
+ }
+ s_last = seq_last_given_monoton_cfra;
+
+ This->current = e;
+
+ pthread_mutex_unlock(&queue_lock);
+
+ if (!e) {
+ pthread_mutex_lock(&prefetch_ready_lock);
+
+ This->running = FALSE;
+
+ pthread_cond_signal(&prefetch_ready_cond);
+ pthread_mutex_unlock(&prefetch_ready_lock);
+
+ pthread_mutex_lock(&wakeup_lock);
+ if (!seq_thread_shutdown) {
+ pthread_cond_wait(&wakeup_cond, &wakeup_lock);
+ }
+ pthread_mutex_unlock(&wakeup_lock);
+ continue;
+ }
+
+ This->running = TRUE;
+
+ if (e->cfra >= s_last) {
+ e->ibuf = give_ibuf_seq_impl(
+ e->rectx, e->recty, e->cfra, e->chanshown);
+ }
+
+ pthread_mutex_lock(&queue_lock);
+
+ BLI_addtail(&prefetch_done, e);
+
+ for (e = prefetch_wait.first; e; e = e->next) {
+ if (s_last > e->monoton_cfra) {
+ BLI_remlink(&prefetch_wait, e);
+ MEM_freeN(e);
+ }
+ }
+
+ for (e = prefetch_done.first; e; e = e->next) {
+ if (s_last > e->monoton_cfra) {
+ if (e->ibuf) {
+ IMB_cache_limiter_unref(e->ibuf);
+ }
+ BLI_remlink(&prefetch_done, e);
+ MEM_freeN(e);
+ }
+ }
+
+ pthread_mutex_unlock(&queue_lock);
+
+ pthread_mutex_lock(&frame_done_lock);
+ pthread_cond_signal(&frame_done_cond);
+ pthread_mutex_unlock(&frame_done_lock);
+ }
+ return 0;
+}
+
+void seq_start_threads()
+{
+ int i;
+
+ running_threads.first = running_threads.last = NULL;
+ prefetch_wait.first = prefetch_wait.last = NULL;
+ prefetch_done.first = prefetch_done.last = NULL;
+
+ seq_thread_shutdown = FALSE;
+ seq_last_given_monoton_cfra = monoton_cfra = 0;
+
+ /* since global structures are modified during the processing
+ of one frame, only one render thread is currently possible...
+
+ (but we code, in the hope, that we can remove this restriction
+ soon...)
+ */
+
+ fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
+
+ for (i = 0; i < 1; i++) {
+ PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread),
+ "prefetch_thread");
+ t->running = TRUE;
+ BLI_addtail(&running_threads, t);
+
+ pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
+ }
+
+ /* init malloc mutex */
+ BLI_init_threads(0, 0, 0);
+}
+
+void seq_stop_threads()
+{
+ PrefetchThread *tslot;
+ PrefetchQueueElem * e;
+
+ fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
+
+ if (seq_thread_shutdown) {
+ fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
+ return;
+ }
+
+ pthread_mutex_lock(&wakeup_lock);
+
+ seq_thread_shutdown = TRUE;
+
+ pthread_cond_broadcast(&wakeup_cond);
+ pthread_mutex_unlock(&wakeup_lock);
+
+ for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+ pthread_join(tslot->pthread, NULL);
+ }
+
+
+ for (e = prefetch_wait.first; e; e = e->next) {
+ BLI_remlink(&prefetch_wait, e);
+ MEM_freeN(e);
+ }
+
+ for (e = prefetch_done.first; e; e = e->next) {
+ if (e->ibuf) {
+ IMB_cache_limiter_unref(e->ibuf);
+ }
+ BLI_remlink(&prefetch_done, e);
+ MEM_freeN(e);
+ }
+
+ BLI_freelistN(&running_threads);
+
+ /* deinit malloc mutex */
+ BLI_end_threads(0);
+}
+
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
+{
+ PrefetchQueueElem * e;
+ if (seq_thread_shutdown) {
+ return;
+ }
+
+ e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
+ e->rectx = rectx;
+ e->recty = recty;
+ e->cfra = cfra;
+ e->chanshown = chanshown;
+ e->monoton_cfra = monoton_cfra++;
+
+ pthread_mutex_lock(&queue_lock);
+ BLI_addtail(&prefetch_wait, e);
+ pthread_mutex_unlock(&queue_lock);
+
+ pthread_mutex_lock(&wakeup_lock);
+ pthread_cond_signal(&wakeup_cond);
+ pthread_mutex_unlock(&wakeup_lock);
+}
+
+void seq_wait_for_prefetch_ready()
+{
+ PrefetchThread *tslot;
+
+ if (seq_thread_shutdown) {
+ return;
+ }
+
+ fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
+
+ pthread_mutex_lock(&prefetch_ready_lock);
+
+ for(;;) {
+ for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+ if (tslot->running) {
+ break;
+ }
+ }
+ if (!tslot) {
+ break;
+ }
+ pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
}
- return seqfirst->curelem->ibuf;
+ pthread_mutex_unlock(&prefetch_ready_lock);
+ fprintf(stderr, "SEQ-THREAD: prefetch done\n");
+}
+
+ImBuf * give_ibuf_seq_threaded(int rectx, int recty, int cfra, int chanshown)
+{
+ PrefetchQueueElem * e = 0;
+ int found_something = FALSE;
+
+ if (seq_thread_shutdown) {
+ return give_ibuf_seq(rectx, recty, cfra, chanshown);
+ }
+
+ while (!e) {
+ int success = FALSE;
+ pthread_mutex_lock(&queue_lock);
+
+ for (e = prefetch_done.first; e; e = e->next) {
+ if (cfra == e->cfra &&
+ chanshown == e->chanshown &&
+ rectx == e->rectx &&
+ recty == e->recty) {
+ success = TRUE;
+ found_something = TRUE;
+ break;
+ }
+ }
+
+ if (!e) {
+ for (e = prefetch_wait.first; e; e = e->next) {
+ if (cfra == e->cfra &&
+ chanshown == e->chanshown &&
+ rectx == e->rectx &&
+ recty == e->recty) {
+ found_something = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!e) {
+ PrefetchThread *tslot;
+
+ for(tslot = running_threads.first;
+ tslot; tslot= tslot->next) {
+ if (tslot->current &&
+ cfra == tslot->current->cfra &&
+ chanshown == tslot->current->chanshown &&
+ rectx == tslot->current->rectx &&
+ recty == tslot->current->recty) {
+ found_something = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* e->ibuf is unrefed by render thread on next round. */
+
+ if (e) {
+ seq_last_given_monoton_cfra = e->monoton_cfra;
+ }
+
+ pthread_mutex_unlock(&queue_lock);
+
+ if (!success) {
+ e = NULL;
+
+ if (!found_something) {
+ fprintf(stderr,
+ "SEQ-THREAD: Requested frame "
+ "not in queue ???\n");
+ break;
+ }
+ pthread_mutex_lock(&frame_done_lock);
+ pthread_cond_wait(&frame_done_cond, &frame_done_lock);
+ pthread_mutex_unlock(&frame_done_lock);
+ }
+ }
+
+ return e ? e->ibuf : 0;
}
/* Functions to free imbuf and anim data on changes */
-static void free_imbuf_strip_elem(StripElem *se)
+static void free_imbuf_strip_elem(TStripElem *se)
{
- if (se->ibuf) {
- if (se->ok != 2)
- IMB_freeImBuf(se->ibuf);
- se->ibuf= 0;
- se->ok= 1;
- se->se1= se->se2= se->se3= 0;
+ if(se->ibuf) {
+ IMB_freeImBuf(se->ibuf);
}
+ if(se->ibuf_comp) {
+ IMB_freeImBuf(se->ibuf_comp);
+ }
+ se->ibuf_comp = 0;
+ se->ibuf= 0;
+ se->ok= STRIPELEM_OK;
+ se->se1= se->se2= se->se3= 0;
}
static void free_anim_seq(Sequence *seq)
@@ -1201,16 +2646,42 @@ void free_imbuf_seq_except(int cfra)
{
Editing *ed= G.scene->ed;
Sequence *seq;
- StripElem *se;
+ TStripElem *se;
int a;
if(ed==0) return;
WHILE_SEQ(&ed->seqbase) {
if(seq->strip) {
- for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
- if(se!=seq->curelem)
+ TStripElem * curelem = give_tstripelem(seq, cfra);
+
+ for(a = 0, se = seq->strip->tstripdata;
+ a < seq->strip->len && se; a++, se++) {
+ if(se != curelem) {
+ free_imbuf_strip_elem(se);
+ }
+ }
+ for(a = 0, se = seq->strip->tstripdata_startstill;
+ a < seq->strip->startstill && se; a++, se++) {
+ if(se != curelem) {
free_imbuf_strip_elem(se);
+ }
+ }
+ for(a = 0, se = seq->strip->tstripdata_endstill;
+ a < seq->strip->endstill && se; a++, se++) {
+ if(se != curelem) {
+ free_imbuf_strip_elem(se);
+ }
+ }
+ if(seq->strip->ibuf_startstill) {
+ IMB_freeImBuf(seq->strip->ibuf_startstill);
+ seq->strip->ibuf_startstill = 0;
+ }
+
+ if(seq->strip->ibuf_endstill) {
+ IMB_freeImBuf(seq->strip->ibuf_endstill);
+ seq->strip->ibuf_endstill = 0;
+ }
if(seq->type==SEQ_MOVIE)
if(seq->startdisp > cfra || seq->enddisp < cfra)
@@ -1224,15 +2695,34 @@ void free_imbuf_seq()
{
Editing *ed= G.scene->ed;
Sequence *seq;
- StripElem *se;
+ TStripElem *se;
int a;
if(ed==0) return;
WHILE_SEQ(&ed->seqbase) {
if(seq->strip) {
- for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
+ for(a = 0, se = seq->strip->tstripdata;
+ a < seq->strip->len && se; a++, se++) {
free_imbuf_strip_elem(se);
+ }
+ for(a = 0, se = seq->strip->tstripdata_startstill;
+ a < seq->strip->startstill && se; a++, se++) {
+ free_imbuf_strip_elem(se);
+ }
+ for(a = 0, se = seq->strip->tstripdata_endstill;
+ a < seq->strip->endstill && se; a++, se++) {
+ free_imbuf_strip_elem(se);
+ }
+ if(seq->strip->ibuf_startstill) {
+ IMB_freeImBuf(seq->strip->ibuf_startstill);
+ seq->strip->ibuf_startstill = 0;
+ }
+
+ if(seq->strip->ibuf_endstill) {
+ IMB_freeImBuf(seq->strip->ibuf_endstill);
+ seq->strip->ibuf_endstill = 0;
+ }
if(seq->type==SEQ_MOVIE)
free_anim_seq(seq);
@@ -1267,7 +2757,7 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l
{
Sequence *subseq;
int a, free_imbuf = 0;
- StripElem *se;
+ TStripElem *se;
/* recurs downwards to see if this seq depends on the changed seq */
@@ -1279,24 +2769,27 @@ static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int l
for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
- free_imbuf = 1;
+ free_imbuf = TRUE;
if(seq->seq1)
if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
- free_imbuf = 1;
+ free_imbuf = TRUE;
if(seq->seq2 && (seq->seq2 != seq->seq1))
if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
- free_imbuf = 1;
+ free_imbuf = TRUE;
if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
- free_imbuf = 1;
+ free_imbuf = TRUE;
if(free_imbuf) {
if(ibuf_change) {
- for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
- free_imbuf_strip_elem(se);
+ se= seq->strip->tstripdata;
+ if (se) {
+ for(a=0; a<seq->len; a++, se++)
+ free_imbuf_strip_elem(se);
+ }
- if(seq->type==SEQ_MOVIE)
+ if(seq->type == SEQ_MOVIE)
free_anim_seq(seq);
if(seq->type == SEQ_SPEED) {
sequence_effect_speed_rebuild_map(seq, 1);
@@ -1331,7 +2824,6 @@ void do_render_seq(RenderResult *rr, int cfra)
ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0);
if(ibuf) {
-
if(ibuf->rect_float) {
if (!rr->rectf)
rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
@@ -1368,11 +2860,12 @@ void do_render_seq(RenderResult *rr, int cfra)
*/
{
extern int mem_in_use;
+ extern int mmap_in_use;
int max = MEM_CacheLimiter_get_maximum();
- if (max != 0 && mem_in_use > max) {
+ if (max != 0 && mem_in_use + mmap_in_use > max) {
fprintf(stderr, "mem_in_use = %d, max = %d\n",
- mem_in_use, max);
+ mem_in_use + mmap_in_use, max);
fprintf(stderr, "Cleaning up, please wait...\n"
"If this happens very often,\n"
"consider "
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 9787d699b80..15ed21d3d1a 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -65,6 +65,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h" /* used for select grouped hooks */
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
@@ -78,15 +79,21 @@
#include "BKE_colortools.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_ipo.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_multires.h"
#include "BKE_node.h"
#include "BKE_scene.h"
+#include "BKE_sculpt.h"
+#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
+#include "BKE_particle.h"
#include "BIF_spacetypes.h" /* first, nasty dependency with typedef */
@@ -96,6 +103,7 @@
#include "BIF_drawtext.h"
#include "BIF_drawscript.h"
#include "BIF_editarmature.h"
+#include "BIF_editparticle.h"
#include "BIF_editconstraint.h"
#include "BIF_editdeform.h"
#include "BIF_editfont.h"
@@ -110,6 +118,7 @@
#include "BIF_editsima.h"
#include "BIF_editsound.h"
#include "BIF_editview.h"
+#include "BIF_filelist.h"
#include "BIF_gl.h"
#include "BIF_imasel.h"
#include "BIF_interface.h"
@@ -117,8 +126,10 @@
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_oops.h"
+#include "BIF_poselib.h"
#include "BIF_poseobject.h"
#include "BIF_outliner.h"
+#include "BIF_radialcontrol.h"
#include "BIF_resources.h"
#include "BIF_retopo.h"
#include "BIF_screen.h"
@@ -138,6 +149,7 @@
#include "BSE_headerbuttons.h"
#include "BSE_editnla_types.h"
#include "BSE_time.h"
+#include "BSE_trans_types.h"
#include "BDR_vpaint.h"
#include "BDR_editmball.h"
@@ -532,9 +544,14 @@ void start_game(void)
RestoreState();
/* Restart BPY - unload the game engine modules. */
+
+ /* Commented out: testing before Blender 2.46 if it's ok to keep
+ * these modules around, they give access to relevant info for
+ * exporters to other engines...
BPY_end_python();
- BPY_start_python(0, NULL); /* argc, argv stored there already */
- BPY_post_start_python(); /* userpref path and menus init */
+ BPY_start_python(0, NULL);
+ BPY_post_start_python();
+ */
restore_all_scene_cfra(scene_cfra_store);
set_scene_bg(startscene);
@@ -603,10 +620,16 @@ void start_RBSimulation(void)
SaveState();
StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
RestoreState();
+
/* Restart BPY - unload the game engine modules. */
+
+ /* Commented out: testing before Blender 2.46 if it's ok to keep
+ * these modules around, they give access to relevant info for
+ * exporters to other engines...
BPY_end_python();
- BPY_start_python(0, NULL); /* argc, argv stored there already */
- BPY_post_start_python(); /* userpref path and menus init */
+ BPY_start_python(0, NULL);
+ BPY_post_start_python();
+ */
restore_all_scene_cfra(scene_cfra_store);
set_scene_bg(startscene);
@@ -647,15 +670,12 @@ static void align_view_to_selected(View3D *v3d)
if ((G.obedit) && (G.obedit->type == OB_MESH)) {
editmesh_align_view_to_selected(v3d, axis);
addqueue(v3d->area->win, REDRAW, 1);
- } else if (G.f & G_FACESELECT) {
+ } else if (FACESEL_PAINT_TEST) {
Object *obact= OBACT;
if (obact && obact->type==OB_MESH) {
Mesh *me= obact->data;
-
- if (me->mtface) {
- faceselect_align_view_to_selected(v3d, me, axis);
- addqueue(v3d->area->win, REDRAW, 1);
- }
+ faceselect_align_view_to_selected(v3d, me, axis);
+ addqueue(v3d->area->win, REDRAW, 1);
}
}
}
@@ -855,6 +875,25 @@ static short select_same_layer(Object *ob)
return changed;
}
+static short select_same_index_object(Object *ob)
+{
+ char changed = 0;
+ Base *base = FIRSTBASE;
+
+ if (!ob)
+ return 0;
+
+ while(base) {
+ if (BASE_SELECTABLE(base) && (base->object->index == ob->index) && !(base->flag & SELECT)) {
+ base->flag |= SELECT;
+ base->object->flag |= SELECT;
+ changed = 1;
+ }
+ base= base->next;
+ }
+ return changed;
+}
+
void select_object_grouped(short nr)
{
short changed = 0;
@@ -866,6 +905,7 @@ void select_object_grouped(short nr)
else if(nr==6) changed = select_same_layer(OBACT);
else if(nr==7) changed = select_same_group(OBACT);
else if(nr==8) changed = select_object_hooks(OBACT);
+ else if(nr==9) changed = select_same_index_object(OBACT);
if (changed) {
countall();
@@ -891,7 +931,7 @@ static void select_object_grouped_menu(void)
"Objects of Same Type%x5|"
"Objects on Shared Layers%x6|"
"Objects in Same Group%x7|"
- "Object Hooks%x8|");
+ "Object Hooks%x8|Object PassIndex%x9");
/* here we go */
@@ -904,21 +944,30 @@ static void select_object_grouped_menu(void)
void join_menu(void)
{
Object *ob= OBACT;
- if (ob && !G.obedit) {
- if(ob->type == OB_MESH) {
- if(okee("Join selected meshes")==0) return;
- join_mesh();
- } else if(ob->type == OB_CURVE) {
- if(okee("Join selected curves")==0) return;
- join_curve(OB_CURVE);
- } else if(ob->type == OB_SURF) {
- if(okee("Join selected NURBS")==0) return;
- join_curve(OB_SURF);
- } else if(ob->type == OB_ARMATURE) {
- /* Make sure the user wants to continue*/
- if(okee("Join selected armatures")==0) return;
- join_armature ();
- }
+ if (G.obedit) {
+ error("This data does not support joining in editmode");
+ return;
+ }
+ if (!ob) {
+ error("Can't join unless there is an active object");
+ return;
+ }
+
+ if(ob->type == OB_MESH) {
+ if(okee("Join selected meshes")==0) return;
+ join_mesh();
+ } else if(ob->type == OB_CURVE) {
+ if(okee("Join selected curves")==0) return;
+ join_curve(OB_CURVE);
+ } else if(ob->type == OB_SURF) {
+ if(okee("Join selected NURBS")==0) return;
+ join_curve(OB_SURF);
+ } else if(ob->type == OB_ARMATURE) {
+ /* Make sure the user wants to continue*/
+ if(okee("Join selected armatures")==0) return;
+ join_armature ();
+ } else {
+ error("This object type doesn't support joining");
}
}
@@ -957,6 +1006,9 @@ void BIF_undo_push(char *str)
else if (G.obedit->type==OB_ARMATURE)
undo_push_armature(str);
}
+ else if(G.f & G_PARTICLEEDIT) {
+ PE_undo_push(str);
+ }
else {
if(U.uiflag & USER_GLOBALUNDO)
BKE_write_undo(str);
@@ -974,9 +1026,12 @@ void BIF_undo(void)
imagepaint_undo();
else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
imagepaint_undo();
+ else if(G.f & G_PARTICLEEDIT)
+ PE_undo();
else {
/* now also in faceselect mode */
if(U.uiflag & USER_GLOBALUNDO) {
+ BPY_scripts_clear_pyobjects();
BKE_undo_step(1);
sound_initialize_sounds();
}
@@ -995,6 +1050,8 @@ void BIF_redo(void)
imagepaint_undo();
else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
imagepaint_undo();
+ else if(G.f & G_PARTICLEEDIT)
+ PE_redo();
else {
/* includes faceselect now */
if(U.uiflag & USER_GLOBALUNDO) {
@@ -1013,7 +1070,9 @@ void BIF_undo_menu(void)
allqueue(REDRAWALL, 0);
}
else {
- if(U.uiflag & USER_GLOBALUNDO) {
+ if(G.f & G_PARTICLEEDIT)
+ PE_undo_menu();
+ else if(U.uiflag & USER_GLOBALUNDO) {
char *menu= BKE_undo_menu_string();
if(menu) {
short event= pupmenu_col(menu, 20);
@@ -1122,7 +1181,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
Object *ob= OBACT; /* do not change! */
float *curs;
int doredraw= 0, pupval;
- unsigned short event= evt->event, origevent= evt->event;
+ unsigned short event= evt->event;
short val= evt->val;
char ascii= evt->ascii;
@@ -1130,7 +1189,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
@@ -1139,15 +1198,22 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
- if (event==LEFTMOUSE) event = RIGHTMOUSE;
- else if (event==RIGHTMOUSE) event = LEFTMOUSE;
+ /* only swap mouse button for selection, in modes where it is relevant.
+ * painting/sculpting stays on LEFTMOUSE */
+ if ( !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) ||
+ (G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_PARTICLEEDIT)) ||
+ (G.obedit) )
+ {
+ if (event==LEFTMOUSE) event = RIGHTMOUSE;
+ else if (event==RIGHTMOUSE) event = LEFTMOUSE;
+ }
}
if(!mouse_in_header(sa)) {
if(!G.obedit && (G.f & G_SCULPTMODE)) {
SculptSession *ss= sculpt_session();
- if(ss && ss->propset) {
- sculptmode_propset(event);
+ if(ss && ss->radialcontrol) {
+ radialcontrol_do_events(ss->radialcontrol, event);
return;
}
else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
@@ -1155,6 +1221,21 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
allqueue(REDRAWVIEW3D, 0);
}
}
+ else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
+ ParticleSystem *psys=PE_get_current(OBACT);
+ ParticleEditSettings *pset=PE_settings();
+ if(*PE_radialcontrol()) {
+ radialcontrol_do_events(*PE_radialcontrol(), event);
+ return;
+ }
+ if(psys && psys->edit){
+ if(pset->brushtype>=0 &&
+ event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
+ (event==MOUSEY || event==MOUSEX) && bwin_qtest(sa->win)==0) {
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ }
/* Handle retopo painting */
if(retopo_mesh_paint_check()) {
@@ -1302,7 +1383,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case LEFTMOUSE:
if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
sculptmode_pmv(0);
- else if(!(ss && ss->propset))
+ else if(!(ss && ss->radialcontrol))
sculpt();
break;
/* View */
@@ -1377,15 +1458,15 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
/* Brush properties */
case AKEY:
- br->airbrush= !br->airbrush;
+ br->flag ^= SCULPT_BRUSH_AIRBRUSH;
update_prop= 1; break;
case FKEY:
- if(G.qual==0)
- sculptmode_propset_init(PropsetSize);
- if(G.qual==LR_SHIFTKEY)
- sculptmode_propset_init(PropsetStrength);
- if(G.qual==LR_CTRLKEY)
- sculptmode_propset_init(PropsetTexRot);
+ if(ss) {
+ sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
+ G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
+ G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
+ RADIALCONTROL_NONE);
+ }
break;
case VKEY:
br->dir= br->dir==1 ? 2 : 1;
@@ -1409,6 +1490,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case LKEY:
sd->brush_type= LAYER_BRUSH;
update_prop= 1; break;
+ case TKEY:
+ sd->brush_type= FLATTEN_BRUSH;
+ update_prop= 1; break;
/* Symmetry */
case XKEY:
sd->symm^= SYMM_X;
@@ -1430,20 +1514,20 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case PAGEUPKEY:
if(me && me->mr) {
me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
- multires_set_level(ob, ob->data, 0);
+ multires_set_level_cb(ob, ob->data);
}
break;
case PAGEDOWNKEY:
if(me && me->mr) {
me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
- multires_set_level(ob, ob->data, 0);
+ multires_set_level_cb(ob, ob->data);
}
break;
/* Partial Visibility */
case HKEY:
if(G.qual==LR_ALTKEY) {
waitcursor(1);
- sculptmode_pmv_off(get_mesh(ob));
+ mesh_pmv_off(ob, get_mesh(ob));
BIF_undo_push("Partial mesh hide");
allqueue(REDRAWVIEW3D,0);
waitcursor(0);
@@ -1528,10 +1612,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* Shift-Tabe handling (other cases are in toets) */
if (G.qual == LR_SHIFTKEY)
{
- /* Snap toggle (only edit mesh right now) */
- if (G.obedit && G.obedit->type==OB_MESH)
+ /* Snap toggle only when supported */
+ if (BIF_snappingSupported())
{
- G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
+ G.scene->snap_flag ^= SCE_SNAP;
allqueue(REDRAWHEADERS, 0);
}
}
@@ -1541,7 +1625,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
* based on user preference USER_LMOUSESELECT
*/
case LEFTMOUSE:
- if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT))) {
+ if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_PARTICLEEDIT))) {
mouse_cursor();
}
else if (G.f & G_WEIGHTPAINT) {
@@ -1551,7 +1635,13 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
vertex_paint();
}
else if (G.f & G_TEXTUREPAINT) {
- imagepaint_paint(origevent==LEFTMOUSE? L_MOUSE: R_MOUSE, 1);
+ imagepaint_paint(L_MOUSE, 1);
+ }
+ else if (G.f & G_PARTICLEEDIT) {
+ if(G.qual & LR_CTRLKEY)
+ mouse_cursor();
+ else if(!PE_brush_particles())
+ mouse_cursor();
}
break;
case MIDDLEMOUSE:
@@ -1576,10 +1666,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
mouse_mesh(); /* loop select for 1 mousebutton dudes */
else if(G.qual==LR_CTRLKEY)
mouse_select(); /* also allow in editmode, for vertex parenting */
- else if(G.f & G_FACESELECT)
+ else if(FACESEL_PAINT_TEST)
face_select();
else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
sample_vpaint();
+ else if( G.f & G_PARTICLEEDIT)
+ PE_mouse_particles();
else
mouse_select(); /* does poses too */
break;
@@ -1700,7 +1792,15 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case AKEY:
- if(G.qual & LR_CTRLKEY) apply_object(); /* also with shift! */
+ if (G.obedit == 0 && G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
+ if(okee("Align to Transform Orientation")) {
+ initTransform(TFM_ALIGN, CTX_NO_PET|CTX_AUTOCONFIRM);
+ Transform();
+ }
+ }
+ else if(G.qual & LR_CTRLKEY) { /* also with shift! */
+ apply_object();
+ }
else if((G.qual==LR_SHIFTKEY)) {
toolbox_n_add();
}
@@ -1721,7 +1821,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
deselectall_posearmature(ob, 1, 1);
}
else {
- if(G.f & G_FACESELECT) deselectall_tface();
+ if(FACESEL_PAINT_TEST) deselectall_tface();
+ else if(G.f & G_PARTICLEEDIT) PE_deselectall();
else {
/* by design, the center of the active object
* (which need not necessarily by selected) will
@@ -1771,6 +1872,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
add_constraint(0); /* editconstraint.c, generic for objects and posemode */
+ else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) {
+ BIF_manageTransformOrientation(0, 1);
+ allqueue(REDRAWVIEW3D, 0);
+ }
else if((G.qual==LR_SHIFTKEY)) {
view3d_home(1);
curs= give_cursor();
@@ -1836,7 +1941,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if (G.qual==LR_CTRLKEY) {
if(G.obedit && G.obedit->type==OB_MESH)
Edge_Menu();
- else if (G.f & G_FACESELECT)
+ else if (FACESEL_PAINT_TEST)
seam_mark_clear_tface(0);
}
else if (G.qual==LR_SHIFTKEY) {
@@ -1849,15 +1954,29 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
extrude_armature(1);
}
}
+ else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
+ if (G.obedit && G.obedit->type==OB_MESH &&
+ !multires_level1_test()) {
+ if (G.scene->selectmode & SCE_SELECT_VERTEX) {
+ initTransform(TFM_BWEIGHT, CTX_NONE);
+ }
+ else {
+ initTransform(TFM_BWEIGHT, CTX_EDGE);
+ }
+ Transform();
+ }
+ }
break;
case FKEY:
if(G.obedit) {
if(G.obedit->type==OB_MESH) {
- if((G.qual==LR_SHIFTKEY))
+ if(G.qual == LR_CTRLKEY)
+ Face_Menu();
+ else if((G.qual==LR_SHIFTKEY))
fill_mesh();
else if(G.qual==LR_ALTKEY)
beauty_fill();
- else if(G.qual==LR_CTRLKEY)
+ else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY))
edge_flip();
else if (G.qual==0)
addedgeface_mesh();
@@ -1867,7 +1986,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
- else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb();
+ else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
+ addsegment_nurb();
+ }
+ else if(G.obedit->type == OB_ARMATURE) {
+ fill_bones_armature();
+ }
}
else if(G.qual==LR_CTRLKEY)
sort_faces();
@@ -1876,11 +2000,26 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
pose_activate_flipped_bone();
else if(G.f & G_WEIGHTPAINT)
pose_activate_flipped_bone();
+ else if(G.f & G_PARTICLEEDIT)
+ PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
else
fly();
}
+ else if((G.qual==LR_ALTKEY)) {
+ if(ob && (ob->flag & OB_POSEMODE))
+ if(okee("Flip quaternion rotations"))
+ pose_flipquats();
+ }
else {
- set_faceselect();
+ if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)){
+ G.f ^= G_FACESELECT;
+ allqueue(REDRAWVIEW3D, 1);
+ }
+ else if(G.f & G_PARTICLEEDIT) {
+ PE_radialcontrol_start(RADIALCONTROL_SIZE);
+ } else {
+ pupmenu("Note%t|UV/Face Select was removed. Editmode now allows UV editing, Add a UV layer or Unwrap (UKey)");
+ }
}
break;
@@ -1890,6 +2029,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
vgroup_assign_with_menu();
}
+ else if(ob && (ob->flag & OB_POSEMODE))
+ pgroup_operation_with_menu();
else
group_operation_with_menu();
}
@@ -1903,7 +2044,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(G.obedit) {
if(G.obedit->type==OB_MESH)
select_mesh_group_menu();
- } else
+ }
+ else if(ob && (ob->flag & OB_POSEMODE))
+ pose_select_grouped_menu();
+ else
select_object_grouped_menu();
else if((G.obedit==0) && G.qual==LR_ALTKEY) {
if(okee("Clear location")) {
@@ -1923,7 +2067,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(G.obedit) {
if(G.obedit->type==OB_MESH) {
if(G.qual==LR_CTRLKEY)
- add_hook();
+ add_hook_menu();
else if(G.qual==LR_ALTKEY)
reveal_mesh();
else if((G.qual==LR_SHIFTKEY))
@@ -1933,7 +2077,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.obedit->type== OB_SURF) {
if(G.qual==LR_CTRLKEY)
- add_hook();
+ add_hook_menu();
else if(G.qual==LR_ALTKEY)
revealNurb();
else if((G.qual==LR_SHIFTKEY))
@@ -1943,7 +2087,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.obedit->type==OB_CURVE) {
if(G.qual==LR_CTRLKEY)
- add_hook();
+ add_hook_menu();
else if(G.qual==LR_ALTKEY)
revealNurb();
/* should be G.qual==LR_SHIFTKEY, but that is taken fro handles already */
@@ -1966,7 +2110,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
else if(G.obedit->type==OB_LATTICE) {
- if(G.qual==LR_CTRLKEY) add_hook();
+ if(G.qual==LR_CTRLKEY) add_hook_menu();
}
else if(G.obedit->type==OB_MBALL) {
if(G.qual==LR_ALTKEY)
@@ -1985,8 +2129,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
show_all_armature_bones();
}
}
- else if(G.f & G_FACESELECT)
+ else if(FACESEL_PAINT_TEST)
hide_tface();
+ else if(G.f & G_PARTICLEEDIT) {
+ if(G.qual == LR_ALTKEY)
+ PE_hide(0);
+ else if(G.qual == LR_SHIFTKEY)
+ PE_hide(1);
+ else if(G.qual == 0)
+ PE_hide(2);
+ }
else if(ob && (ob->flag & OB_POSEMODE)) {
if (G.qual==0)
hide_selected_pose_bones();
@@ -2004,8 +2156,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case IKEY:
- if(G.obedit);
- else if(G.qual==LR_CTRLKEY) {
+ if(G.obedit) {
+ if(G.qual==LR_CTRLKEY)
+ selectswap_mesh();
+ } else if(G.qual==LR_CTRLKEY) {
if(ob && ob->type==OB_ARMATURE)
if(ob->flag & OB_POSEMODE)
pose_add_IK();
@@ -2022,8 +2176,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if( ob ) {
join_menu();
}
- else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
+ else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
addsegment_nurb();
+ } else {
+ error("Can't join unless there is an active object");
+ }
+
}
else if(G.obedit) {
if(G.obedit->type==OB_MESH) {
@@ -2045,7 +2203,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else {
if((G.qual==LR_SHIFTKEY)) {
- if(G.f & G_FACESELECT)
+ if(FACESEL_PAINT_TEST)
if (G.f & G_WEIGHTPAINT)
clear_wpaint_selectedfaces();
else
@@ -2062,18 +2220,40 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case LKEY:
if(G.obedit) {
- if(G.obedit->type==OB_MESH)
- selectconnected_mesh(G.qual);
+ if(G.obedit->type==OB_MESH) {
+ if (G.qual & LR_CTRLKEY) {
+ if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
+ selectconnected_mesh_all(); /* normal select linked */
+ } else {
+ selectconnected_delimit_mesh_all(); /* select linked with edge crease delimiting */
+ }
+ } else {
+ if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
+ selectconnected_mesh();
+ } else {
+ selectconnected_delimit_mesh();
+ }
+ }
+ }
if(G.obedit->type==OB_ARMATURE)
selectconnected_armature();
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
selectconnected_nurb();
}
else if(ob && (ob->flag & OB_POSEMODE)) {
- selectconnected_posearmature();
+ if (G.qual == LR_CTRLKEY)
+ poselib_preview_poses(ob, 0);
+ else if (G.qual == LR_SHIFTKEY)
+ poselib_add_current_pose(ob, 0);
+ else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ poselib_rename_pose(ob);
+ else if (G.qual == LR_ALTKEY)
+ poselib_remove_pose(ob, NULL);
+ else
+ selectconnected_posearmature();
}
else {
- if(G.f & G_FACESELECT) {
+ if(FACESEL_PAINT_TEST) {
if((G.qual==0))
select_linked_tfaces(0);
else if((G.qual==LR_SHIFTKEY))
@@ -2081,6 +2261,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual==LR_CTRLKEY)
select_linked_tfaces(2);
}
+ else if(G.f & G_PARTICLEEDIT) {
+ if(G.qual==0)
+ PE_select_linked();
+ }
else {
if((G.qual==0))
make_local_menu();
@@ -2092,19 +2276,23 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case MKEY:
- if((G.obedit==0) && (G.f & G_FACESELECT) && (G.qual==0))
- mirror_uv_tface();
- else if(G.obedit){
- if(G.qual==LR_ALTKEY) {
- if(G.obedit->type==OB_MESH) {
+ if(G.obedit){
+ if (ELEM(G.qual, 0, LR_SHIFTKEY) && (G.obedit->type==OB_ARMATURE)) {
+ pose_movetolayer();
+ }
+ else if (G.qual==LR_ALTKEY) {
+ if (G.obedit->type == OB_MESH) {
mergemenu();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
+ else if (G.obedit->type == OB_ARMATURE) {
+ merge_armature();
+ }
}
- else if((G.qual==0) || (G.qual==LR_CTRLKEY)) {
+ else if ((G.qual==0) || (G.qual==LR_CTRLKEY)) {
mirrormenu();
}
- if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
+ else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
if(G.obedit->type==OB_MESH) select_non_manifold();
}
}
@@ -2126,9 +2314,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.obedit) {
switch (G.obedit->type){
case OB_ARMATURE:
- if(G.qual==LR_CTRLKEY){
- if (okee("Recalculate bone roll angles")) {
- auto_align_armature();
+ if(G.qual==LR_CTRLKEY) {
+ pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
+ if (pupval > 0) {
+ auto_align_armature(pupval - 1);
allqueue(REDRAWVIEW3D, 0);
}
}
@@ -2154,7 +2343,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case OKEY:
- if (G.obedit) {
+ if (G.obedit || G.f&G_PARTICLEEDIT) {
if (G.qual==LR_SHIFTKEY) {
G.scene->prop_mode = (G.scene->prop_mode+1)%7;
allqueue(REDRAWHEADERS, 0);
@@ -2225,9 +2414,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case RKEY:
- if((G.obedit==0) && (G.f & G_FACESELECT) && (G.qual==0) && !(G.f & G_WEIGHTPAINT))
- rotate_uv_tface();
- else if((G.obedit==0) && G.qual==LR_ALTKEY) {
+ if((G.obedit==0) && G.qual==LR_ALTKEY) {
if(okee("Clear rotation")) {
clear_object('r');
}
@@ -2310,7 +2497,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
ob= ob->parent;
if(ob && (ob->flag & OB_POSEMODE)) {
bArmature *arm= ob->data;
- if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
+ if( arm->drawtype==ARM_ENVELOPE) {
initTransform(TFM_BONESIZE, CTX_NONE);
Transform();
break;
@@ -2338,10 +2525,16 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case TKEY:
- if(G.obedit){
+ if(G.qual == LR_SHIFTKEY) { /* toggle texture in solid draw mode */
+ G.vd->flag2 ^= V3D_SOLID_TEX;
+ allqueue(REDRAWVIEW3D, 0);
+ } else if(G.obedit){
if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
convert_to_triface(G.qual & LR_SHIFTKEY);
allqueue(REDRAWVIEW3D, 0);
+ if (EM_texFaceCheck())
+ allqueue(REDRAWIMAGE, 0);
+
countall();
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
@@ -2355,6 +2548,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
}
}
+ else if(G.f & G_PARTICLEEDIT) {
+ initTransform(TFM_BAKE_TIME, CTX_NONE);
+ Transform();
+ }
else if(G.qual==LR_CTRLKEY) {
if(ob && (ob->flag & OB_POSEMODE));
else make_track();
@@ -2369,6 +2566,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case UKEY:
+ /*// Use Ctrl Z like everybody else
if(G.obedit) {
if(G.obedit->type==OB_MESH) {
if(G.qual==0) BIF_undo(); else BIF_redo();
@@ -2376,6 +2574,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if ELEM5(G.obedit->type, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
if(G.qual==0) BIF_undo(); else BIF_redo();
}
+ }*/
+ if(G.obedit) {
+ if(G.obedit->type==OB_MESH && G.qual==0) {
+ uv_autocalc_tface();
+ }
+ }
+ else if (G.f & G_PARTICLEEDIT){
+ if(G.qual==0) BIF_undo(); else BIF_redo();
}
else if((G.qual==0)) {
if(G.f & G_WEIGHTPAINT)
@@ -2384,8 +2590,6 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
BIF_undo();
else if(G.f & G_TEXTUREPAINT)
imagepaint_undo();
- else if (G.f & G_FACESELECT)
- uv_autocalc_tface();
else {
single_user();
}
@@ -2393,11 +2597,15 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case VKEY:
- if((G.qual==LR_SHIFTKEY)) {
+ if ((G.qual==LR_CTRLKEY)) {
+ if ((G.obedit) && G.obedit->type==OB_MESH) {
+ Vertex_Menu();
+ }
+ } else if((G.qual==LR_SHIFTKEY)) {
if ((G.obedit) && G.obedit->type==OB_MESH) {
align_view_to_selected(v3d);
}
- else if (G.f & G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
align_view_to_selected(v3d);
}
}
@@ -2420,13 +2628,27 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case WKEY:
- if((G.qual==LR_SHIFTKEY)) {
+ if ( ((ob) && (ob->flag & OB_POSEMODE)) ||
+ ((G.obedit) && (G.obedit->type==OB_ARMATURE)) )
+ {
+ if (G.qual) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ val= 1;
+ else if (G.qual == LR_ALTKEY)
+ val= 2;
+ else
+ val= 0;
+
+ setflag_armature(val);
+ }
+ else if (G.qual == 0)
+ special_editmenu();
+ }
+ else if((G.qual==LR_SHIFTKEY)) {
initTransform(TFM_WARP, CTX_NONE);
Transform();
}
- else if(G.qual==LR_ALTKEY) {
- /* if(G.obedit && G.obedit->type==OB_MESH) write_videoscape(); */
- }
+ /*else if(G.qual==LR_ALTKEY) {}*/
else if(G.qual==LR_CTRLKEY) {
if(G.obedit) {
if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
@@ -2476,7 +2698,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case PERIODKEY:
if(G.qual==LR_CTRLKEY) {
G.vd->around= V3D_LOCAL;
- } else if(G.qual==0) {
+ } else if(G.qual==LR_ALTKEY) {
+ G.vd->around= V3D_ACTIVE;
+ } else if(G.qual==0) {
G.vd->around= V3D_CURSOR;
}
handle_view3d_around();
@@ -2504,7 +2728,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if ((G.obedit) && (G.obedit->type == OB_MESH)) {
editmesh_align_view_to_selected(G.vd, 3);
}
- else if (G.f & G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
faceselect_align_view_to_selected(G.vd, me, 3);
@@ -2524,16 +2748,21 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case PAGEUPKEY:
- if(G.qual==LR_CTRLKEY)
+ if (G.qual==LR_CTRLKEY)
+ nextprev_timeline_key(1);
+ else if (G.qual==LR_SHIFTKEY)
movekey_obipo(1);
- else if((G.qual==0))
+ else if (G.qual==0)
nextkey_obipo(1); /* in editipo.c */
+
break;
case PAGEDOWNKEY:
- if(G.qual==LR_CTRLKEY)
+ if (G.qual==LR_CTRLKEY)
+ nextprev_timeline_key(-1);
+ else if (G.qual==LR_SHIFTKEY)
movekey_obipo(-1);
- else if((G.qual==0))
+ else if (G.qual==0)
nextkey_obipo(-1);
break;
@@ -2550,11 +2779,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if ( (G.qual==LR_CTRLKEY)
&& (G.obedit) && (G.obedit->type==OB_CURVE) )
select_less_nurb();
- /*
else if ( (G.qual==LR_CTRLKEY)
&& (G.obedit) && (G.obedit->type==OB_SURF) )
select_less_nurb();
- */
+ else if ( (G.qual==LR_CTRLKEY)
+ && (G.f & G_PARTICLEEDIT) )
+ PE_select_less();
else {
persptoetsen(event);
doredraw= 1;
@@ -2568,11 +2798,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if ( (G.qual==LR_CTRLKEY)
&& (G.obedit) && (G.obedit->type==OB_CURVE) )
select_more_nurb();
- /*
else if ( (G.qual==LR_CTRLKEY)
&& (G.obedit) && (G.obedit->type==OB_SURF) )
select_more_nurb();
- */
+ else if ( (G.qual==LR_CTRLKEY)
+ && (G.f & G_PARTICLEEDIT) )
+ PE_select_more();
else {
persptoetsen(event);
doredraw= 1;
@@ -2617,6 +2848,8 @@ static void initview3d(ScrArea *sa)
vd->far= 500.0f;
vd->grid= 1.0f;
vd->gridlines= 16;
+ vd->gridsubdiv = 10;
+
vd->lay= vd->layact= 1;
if(G.scene) {
vd->lay= vd->layact= G.scene->lay;
@@ -2678,7 +2911,7 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(sa->win==0) return;
if(val) {
- if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&sa->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -2710,7 +2943,7 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
areamouseco_to_ipoco(v2d, mval, &dx, &dy);
- cfra = get_cfra_from_dx(sipo, (int)dx);
+ cfra = get_cfra_from_dx(sipo, (int)(dx+0.5f));
if(cfra< 1) cfra= 1;
if( cfra!=CFRA ) {
@@ -2725,11 +2958,7 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case RIGHTMOUSE:
mouse_select_ipo();
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
break;
case MIDDLEMOUSE:
if(in_ipo_buttons()) {
@@ -2769,15 +2998,15 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if((G.qual==0))
do_ipo_buttons(B_IPOHOME);
break;
+ case PADPERIOD:
+ if((G.qual==0))
+ do_ipo_buttons(B_IPOVIEWCENTER);
+ break;
case AKEY:
if (G.qual & LR_CTRLKEY) {
deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ allqueue(REDRAWMARKER, 0);
}
else if (G.qual==0) {
if(in_ipo_buttons()) {
@@ -2806,15 +3035,18 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
move_to_frame();
break;
case DKEY:
- if (G.qual==LR_SHIFTKEY)
+ if (G.qual==LR_SHIFTKEY) {
add_duplicate_editipo();
- else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ } else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
duplicate_marker();
+ allqueue(REDRAWMARKER, 0);
+ }
break;
case GKEY:
- if (G.qual & LR_CTRLKEY)
+ if (G.qual & LR_CTRLKEY) {
transform_markers('g', 0);
- else if (G.qual==0)
+ allqueue(REDRAWMARKER, 0);
+ } else if (G.qual==0)
transform_ipo('g');
break;
case HKEY:
@@ -2838,21 +3070,17 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case MKEY:
- if (G.qual==LR_SHIFTKEY) {
+ if (G.qual==0) {
+ add_marker(CFRA);
+ } else if (G.qual==LR_SHIFTKEY) {
ipo_mirror_menu();
break;
- }
- if (G.qual == 0)
- add_marker(CFRA);
- else if (G.qual == LR_CTRLKEY)
+ } else if (G.qual == LR_CTRLKEY) {
rename_marker();
- else
+ } else {
break;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ }
+ allqueue(REDRAWMARKER, 0);
break;
case NKEY:
toggle_blockhandler(sa, IPO_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
@@ -2876,8 +3104,10 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
allqueue(REDRAWIPO, 0);
break;
case RKEY:
- if (G.qual==0)
+ if (G.qual==LR_CTRLKEY)
ipo_record();
+ else
+ transform_ipo('r');
break;
case SKEY:
if (G.qual==LR_SHIFTKEY) {
@@ -2907,6 +3137,13 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
allqueue(REDRAWSOUND, 0);
}
break;
+ case ACCENTGRAVEKEY:
+ if((G.qual==0)) {
+ do_ipo_buttons(B_IPOVIEWALL);
+ allqueue(REDRAWIPO, 0);
+ }
+ break;
+
}
}
@@ -2965,7 +3202,6 @@ static void space_sound_button_function(int event)
}
#endif
-
static char *iconfile_menu(void)
{
static char string[512];
@@ -3003,10 +3239,66 @@ static void set_userdef_iconfile_cb(void *menuindex, void *unused2)
/* needed for event; choose new 'curmain' resets it... */
static short th_curcol= TH_BACK;
+static short th_curcolset = 1;
static char *th_curcol_ptr= NULL;
static char th_curcol_arr[4]={0, 0, 0, 255};
-static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
+
+static void info_dump_customcolorset (void *arg1, void *arg2)
+{
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *tcs= &btheme->tarm[(th_curcolset - 1)];
+
+
+#if 0 // this version, if we keep the button
+ /* print (name, redval, greenval, blueval) */
+ printf("Theme '%s': Bone Color Set %d \n", btheme->name, th_curcolset);
+ printf("\t'Normal': 0x%02x, 0x%02x, 0x%02x \n", tcs->solid[0], tcs->solid[1], tcs->solid[2]);
+ printf("\t'Select': 0x%02x, 0x%02x, 0x%02x \n", tcs->select[0], tcs->select[1], tcs->select[2]);
+ printf("\t'Active': 0x%02x, 0x%02x, 0x%02x \n", tcs->active[0], tcs->active[1], tcs->active[2]);
+ printf("\n");
+#endif
+
+ // this version generates code that can be copy+paste-ed
+ printf("Theme '%s': Bone Color Set - Code for Copy+Paste \n", btheme->name);
+ printf("\t/* set %d */ \n", th_curcolset);
+ printf("\tSETCOL(btheme->tarm[%d].solid, 0x%02x, 0x%02x, 0x%02x, 255); \n", th_curcolset-1, tcs->solid[0], tcs->solid[1], tcs->solid[2]);
+ printf("\tSETCOL(btheme->tarm[%d].select, 0x%02x, 0x%02x, 0x%02x, 255); \n", th_curcolset-1, tcs->select[0], tcs->select[1], tcs->select[2]);
+ printf("\tSETCOL(btheme->tarm[%d].active, 0x%02x, 0x%02x, 0x%02x, 255); \n", th_curcolset-1, tcs->active[0], tcs->active[1], tcs->active[2]);
+}
+
+static void info_user_theme_colsets_buts(uiBlock *block, short y1, short y2, short y3, short y4)
+{
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *col_set= &btheme->tarm[(th_curcolset - 1)];
+ uiBut *but;
+ short y4label= y4-2; // sync this with info_user_themebuts
+
+ /* Selector for set (currently only 20 sets) */
+ uiDefButS(block, NUM, B_REDR, "Color Set: ", 255,y1,200,20, &th_curcolset, 1, 20, 0, 0, "Current color set");
+
+ /* "Solid" Color (unselected wire-color is derived from this) */
+ uiDefBut(block, LABEL,0,"Normal: ", 475,y4label,60,20,0, 0, 0, 0, 0, "");
+ uiDefButC(block, COL, B_UPDATE_THEME, "", 475,y1,50,y3-y1+20, col_set->solid, 0, 0, 0, 0, "Color to use for surface of bones");
+
+ /* Selected Color */
+ uiDefBut(block, LABEL,0,"Selected: ", 575,y4label,60,20,0, 0, 0, 0, 0, "");
+ uiDefButC(block, COL, B_UPDATE_THEME, "", 575,y1,50,y3-y1+20, col_set->select, 0, 0, 0, 0, "Color to use for 'selected' bones");
+
+ /* Active Color */
+ uiDefBut(block, LABEL,0,"Active: ", 675,y4label,60,20,0, 0, 0, 0, 0, "");
+ uiDefButC(block, COL, B_UPDATE_THEME, "", 675,y1,50,y3-y1+20, col_set->active, 0, 0, 0, 0, "Color to use for 'active' bones");
+
+ /* Extra 'Options' */
+ uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_UPDATE_THEME, "Use 'Constraint' Colouring", 885,y2,200,20, &col_set->flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status");
+
+ /* 'Debug' Tools */
+ // these should be disabled for release... but are needed for development
+ but= uiDefBut(block, BUT, B_UPDATE_THEME, "Dump Colors Codes", 885,y3,200,20, NULL, 0, 0, 0, 0, "Prints this set's colors to the console");
+ uiButSetFunc(but, info_dump_customcolorset, NULL, NULL);
+}
+
+static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4)
{
bTheme *btheme, *bt;
int spacetype= 0;
@@ -3061,7 +3353,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
uiDefBut(block, TEX, B_NAME_THEME, "", 255,y3,200,20, btheme->name, 1.0, 30.0, 0, 0, "Rename theme");
/* main choices pup: note, it uses collums, and the seperators (%l) then have to fill both halves equally for the menu to work */
- uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|"
+ uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|Bone Color Sets %x17|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|"
"NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Node Editor %x16|Timeline %x15|%l|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|"
"Outliner %x11|Buttons Window %x12|%l|File Browser %x13|Image Browser %x14",
255,y2,200,20, &curmain, 0, 0, 0, 0, "Specify theme for...");
@@ -3081,8 +3373,12 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
else if(curmain==14) spacetype= SPACE_IMASEL;
else if(curmain==15) spacetype= SPACE_TIME;
else if(curmain==16) spacetype= SPACE_NODE;
+ else if(curmain==17) {
+ info_user_theme_colsets_buts(block, y1, y2, y3, y4);
+ return;
+ }
else return; /* only needed while coding... when adding themes for more windows */
-
+
/* color choices pup */
if(curmain==1) {
strp= BIF_ThemeColorsPup(0);
@@ -3124,7 +3420,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
}
else {
uiBlockBeginAlign(block);
- if ELEM8(th_curcol, TH_PANEL, TH_LAMP, TH_FACE, TH_FACE_SELECT, TH_MENU_BACK, TH_MENU_HILITE, TH_MENU_ITEM, TH_NODE) {
+ if ELEM9(th_curcol, TH_PANEL, TH_LAMP, TH_FACE, TH_FACE_SELECT, TH_EDITMESH_ACTIVE, TH_MENU_BACK, TH_MENU_HILITE, TH_MENU_ITEM, TH_NODE) {
uiDefButC(block, NUMSLI, B_UPDATE_THEME,"A ", 465,y3+25,200,20, col+3, 0.0, 255.0, B_THEMECOL, 0, "");
}
uiDefButC(block, NUMSLI, B_UPDATE_THEME,"R ", 465,y3,200,20, col, 0.0, 255.0, B_THEMECOL, 0, "");
@@ -3145,14 +3441,22 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3)
}
}
+/* setting the temp dir needs to set */
+void eval_utemp_dir_callback(void *dummy1, void *dummy2)
+{
+ if (!BLI_exists(U.tempdir))
+ error("temp directory does not exist, assign a valid directory");
+ BLI_where_is_temp(btempdir, 1);
+}
void drawinfospace(ScrArea *sa, void *spacedata)
{
uiBlock *block;
+ uiBut *uibut;
static short cur_light=0;
float fac, col[3];
- short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6;
- short y2label, y3label, y4label, y5label, y6label;
+ short xpos, ypos, ypostab, buth, rspace, dx, y1, y2, y3, y4, y5, y6, y7;
+ short y2label, y3label, y4label, y5label, y6label, y7label;
short spref, mpref, lpref, smfileselbut;
short edgsp, midsp;
char naam[32];
@@ -3203,6 +3507,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
y4 = ypos+3*(buth+rspace);
y5 = ypos+4*(buth+rspace);
y6 = ypos+5*(buth+rspace);
+ y7 = ypos+6*(buth+rspace);
y2label = y2-2; /* adjustments to offset the labels down to align better */
@@ -3210,6 +3515,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
y4label = y4-2;
y5label = y5-2;
y6label = y6-2;
+ y7label = y7-2;
/* set the color to blue and draw the main 'tab' controls */
@@ -3252,38 +3558,42 @@ void drawinfospace(ScrArea *sa, void *spacedata)
/* line 2: left x co-ord, top y co-ord, width, height */
if(U.userpref == 6) {
- info_user_themebuts(block, y1, y2, y3);
+ info_user_themebuts(block, y1, y2, y3, y4);
}
else if (U.userpref == 0) { /* view & controls */
uiDefBut(block, LABEL,0,"Display:",
- xpos,y6label,spref,buth,
+ xpos,y7label,spref,buth,
0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, USER_TOOLTIPS, 0, "Tool Tips",
- (xpos+edgsp),y5,spref,buth,
+ (xpos+edgsp),y6,spref,buth,
&(U.flag), 0, 0, 0, 0,
"Display tooltips (help tags) over buttons");
uiDefButBitI(block, TOG, USER_DRAWVIEWINFO, B_DRAWINFO, "Object Info",
- (xpos+edgsp),y4,spref,buth,
+ (xpos+edgsp),y5,spref,buth,
&(U.uiflag), 0, 0, 0, 0,
"Display active object name and frame number in the 3D View");
uiDefButBitI(block, TOG, USER_SCENEGLOBAL, 0, "Global Scene",
- (xpos+edgsp),y3,spref,buth,
+ (xpos+edgsp),y4,spref,buth,
&(U.flag), 0, 0, 0, 0,
"Forces the current Scene to be displayed in all Screens");
#ifndef __APPLE__
uiDefButBitS(block, TOG, 1, 0, "Large Cursors",
- (xpos+edgsp),y2,spref,buth,
+ (xpos+edgsp),y3,spref,buth,
&(U.curssize), 0, 0, 0, 0,
"Use large mouse cursors when available");
#else
U.curssize=0; /*Small Cursor always for OS X for now */
#endif
uiDefButBitI(block, TOG, USER_SHOW_VIEWPORTNAME, B_DRAWINFO, "View Name",
- (xpos+edgsp),y1,spref,buth,
+ (xpos+edgsp),y2,spref,buth,
&(U.uiflag), 0, 0, 0, 0,
"Show the name of the view's direction in each 3D View");
+ uiDefButBitI(block, TOG, USER_SHOW_FPS, B_DRAWINFO, "Playback FPS",
+ (xpos+edgsp),y1,spref,buth,
+ &(U.uiflag), 0, 0, 0, 0,
+ "Show the frames per second screen refresh rate, while animation is played back");
uiBlockEndAlign(block);
uiDefBut(block, LABEL,0,"Menus:",
@@ -3371,58 +3681,37 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiBlockSetCol(block, TH_AUTO); /* end color */
uiBlockEndAlign(block);
+ uiDefButBitI(block, TOG, USER_ZOOM_TO_MOUSEPOS, B_DRAWINFO, "Zoom to Mouse Position",
+ (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y4,mpref,buth,
+ &(U.uiflag), 0, 0, 0, 0,
+ "Zoom in towards the mouse pointer's position in the 3D view, rather than the 2D window center");
+
uiDefBut(block, LABEL,0,"View rotation:",
- (xpos+(2*edgsp)+mpref+(2*spref)+(2*midsp)),y4label,mpref,buth,
+ (xpos+(2*edgsp)+mpref+(2*spref)+(2*midsp)),y3label,mpref,buth,
0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1); /* mutually exclusive toggles, start color */
uiDefButBitI(block, TOG, USER_TRACKBALL, B_DRAWINFO, "Trackball",
- (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y3,(mpref/2),buth,
+ (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y2,(mpref/2),buth,
&(U.flag), 0, 0, 0, 0,
"Allow the view to tumble freely when orbiting with the Middle Mouse Button");
uiDefButBitI(block, TOGN, USER_TRACKBALL, B_DRAWINFO, "Turntable",
- (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y3,(mpref/2),buth,
+ (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y2,(mpref/2),buth,
&(U.flag), 0, 0, 0, 0,
"Use fixed up axis for orbiting with Middle Mouse Button");
uiBlockSetCol(block, TH_AUTO); /* end color */
uiDefButBitI(block, TOG, USER_AUTOPERSP, B_DRAWINFO, "Auto Perspective",
- (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y2,(mpref/2),buth,
+ (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y1,(mpref/2),buth,
&(U.uiflag), 0, 0, 0, 0,
"Automatically switch between orthographic and perspective when changing from top/front/side views");
uiDefButBitI(block, TOG, USER_ORBIT_SELECTION, B_DRAWINFO, "Around Selection",
- (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y2,(mpref/2),buth,
+ (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y1,(mpref/2),buth,
&(U.uiflag), 0, 0, 0, 0,
"Use selection as the orbiting center");
uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, USER_SHOW_ROTVIEWICON, B_DRAWINFO, "Mini Axis",
- (xpos+edgsp+(2*mpref)+(2*midsp)),y1,(mpref/3),buth,
- &(U.uiflag), 0, 0, 0, 0,
- "Show a small rotating 3D axis in the bottom left corner of the 3D View");
- uiDefButS(block, NUM, B_DRAWINFO, "Size:",
- (xpos+edgsp+(2*mpref)+(2*midsp)+(mpref/3)),y1,(mpref/3),buth,
- &U.rvisize, 10, 64, 0, 0,
- "The axis icon's size");
- uiDefButS(block, NUM, B_DRAWINFO, "Bright:",
- (xpos+edgsp+(2*mpref)+(2*midsp)+2*(mpref/3)),y1,(mpref/3),buth,
- &U.rvibright, 0, 10, 0, 0,
- "The brightness of the icon");
- uiBlockEndAlign(block);
-
- uiDefButS(block, NUM, B_DRAWINFO, "Rotation Angle:",
- (xpos+edgsp+(3*mpref)+(4*midsp)),y1,(mpref),buth,
- &U.pad_rot_angle, 0, 90, 0, 0,
- "The rotation step for numerical pad keys (2 4 6 8)");
-
- uiDefButS(block, NUM, B_DRAWINFO, "Smooth View:",
- (xpos+edgsp+(4*mpref)+(5*midsp)),y1,(mpref),buth,
- &U.smooth_viewtx, 0, 1000, 0, 0,
- "The time to animate the view in miliseconds, zero to disable");
-
uiDefBut(block, LABEL,0,"Select with:",
(xpos+(2*edgsp)+(3*mpref)+(3*midsp)),y6label,mpref,buth,
0, 0, 0, 0, 0, "");
@@ -3452,12 +3741,32 @@ void drawinfospace(ScrArea *sa, void *spacedata)
if (U.flag & USER_LMOUSESELECT)
U.flag &= ~USER_TWOBUTTONMOUSE;
+ uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, USER_TWOBUTTONMOUSE, B_DRAWINFO, "Emulate 3 Button Mouse",
(xpos+edgsp+(3*mpref)+(4*midsp)),y3,mpref,buth,
&(U.flag), 0, 0, 0, 0,
"Emulates Middle Mouse with Alt+LeftMouse (doesnt work with Left Mouse Select option)");
+ uiDefButBitI(block, TOG, USER_MMB_PASTE, B_DRAWINFO, "Paste on MMB",
+ (xpos+edgsp+(3*mpref)+(4*midsp)),y2,mpref,buth,
+ &(U.uiflag), 0, 0, 0, 0,
+ "In text window, paste with MMB instead of panning");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, USER_SHOW_ROTVIEWICON, B_DRAWINFO, "Mini Axis",
+ (xpos+edgsp+(3*mpref)+(4*midsp)),y1,(mpref/3),buth,
+ &(U.uiflag), 0, 0, 0, 0,
+ "Show a small rotating 3D axis in the bottom left corner of the 3D View");
+ uiDefButS(block, NUM, B_DRAWINFO, "Size:",
+ (xpos+edgsp+(3*mpref)+(4*midsp)+(mpref/3)),y1,(mpref/3),buth,
+ &U.rvisize, 10, 64, 0, 0,
+ "The axis icon's size");
+ uiDefButS(block, NUM, B_DRAWINFO, "Bright:",
+ (xpos+edgsp+(3*mpref)+(4*midsp)+2*(mpref/3)),y1,(mpref/3),buth,
+ &U.rvibright, 0, 10, 0, 0,
+ "The brightness of the icon");
+ uiBlockEndAlign(block);
-
uiDefBut(block, LABEL,0,"Middle Mouse Button:",
(xpos+(2*edgsp)+(4*mpref)+(4*midsp)),y6label,mpref,buth,
0, 0, 0, 0, 0, "");
@@ -3471,6 +3780,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
&(U.flag), 0, 0, 0, 0, "Default action for the Middle Mouse Button");
uiBlockSetCol(block, TH_AUTO); /* end color */
uiBlockEndAlign(block);
+
uiDefBut(block, LABEL,0,"Mouse Wheel:",
(xpos+(2*edgsp)+(4*mpref)+(4*midsp)),y4label,mpref,buth,
@@ -3485,6 +3795,17 @@ void drawinfospace(ScrArea *sa, void *spacedata)
&U.wheellinescroll, 0.0, 32.0, 0, 0,
"The number of lines scrolled at a time with the mouse wheel");
uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM, B_DRAWINFO, "Smooth View:",
+ (xpos+edgsp+(4*mpref)+(5*midsp)),y2,(mpref),buth,
+ &U.smooth_viewtx, 0, 1000, 0, 0,
+ "The time to animate the view in miliseconds, zero to disable");
+ uiDefButS(block, NUM, B_DRAWINFO, "Rotation Angle:",
+ (xpos+edgsp+(4*mpref)+(5*midsp)),y1,(mpref),buth,
+ &U.pad_rot_angle, 0, 90, 0, 0,
+ "The rotation step for numerical pad keys (2 4 6 8)");
+ uiBlockEndAlign(block);
uiDefBut(block, LABEL,0,"3D Transform Widget:",
@@ -3524,18 +3845,38 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiDefBut(block, LABEL,0,"Material linked to:",
- xpos,y3label,mpref,buth,
+ xpos,y5label,mpref,buth,
0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOGN, USER_MAT_ON_OB, B_DRAWINFO, "ObData",
- (xpos+edgsp),y2,(mpref/2),buth,
+ (xpos+edgsp),y4,(mpref/2),buth,
&(U.flag), 0, 0, 0, 0, "Link new objects' material to the obData block");
uiDefButBitI(block, TOG, USER_MAT_ON_OB, B_DRAWINFO, "Object",
- (xpos+edgsp+(mpref/2)),y2,(mpref/2),buth,
+ (xpos+edgsp+(mpref/2)),y4,(mpref/2),buth,
&(U.flag), 0, 0, 0, 0, "Link new objects' material to the object block");
uiBlockEndAlign(block);
+
+ uiDefBut(block, LABEL,0,"Add new objects:",
+ xpos,y3label,mpref,buth,
+ 0, 0, 0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, USER_ADD_EDITMODE, B_DRAWINFO, "Switch to Edit Mode",
+ (xpos+edgsp),y2,mpref,buth,
+ &(U.flag), 0, 0, 0, 0, "Enter Edit Mode automatically after adding a new object");
+ uiDefButBitI(block, TOG, USER_ADD_VIEWALIGNED, B_DRAWINFO, "Aligned to View",
+ (xpos+edgsp),y1,mpref,buth,
+ &(U.flag), 0, 0, 0, 0, "Align newly added objects facing the 3D View direction");
+ uiBlockEndAlign(block);
+ uiDefBut(block, LABEL,0,"Transform:",
+ (xpos+(2*edgsp)+mpref),y5label, mpref,buth,
+ 0, 0, 0, 0, 0, "");
+ uiDefButBitI(block, TOG, USER_DRAGIMMEDIATE, B_DRAWINFO, "Drag Immediately",
+ (xpos+edgsp+mpref+midsp),y4,mpref,buth,
+ &(U.flag), 0, 0, 0, 0, "Moving things with a mouse drag doesn't require a click to confirm (Best for tablet users)");
+ uiBlockEndAlign(block);
+
uiDefBut(block, LABEL,0,"Undo:",
(xpos+(2*edgsp)+mpref),y3label, mpref,buth,
0, 0, 0, 0, 0, "");
@@ -3550,30 +3891,37 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiBlockEndAlign(block);
- uiDefBut(block, LABEL,0,"Auto keyframe",
- (xpos+(2*edgsp)+(2*mpref)+midsp),y4label,mpref,buth,
+ uiDefBut(block, LABEL,0,"Auto Keyframe",
+ (xpos+(2*edgsp)+(2*mpref)+midsp),y6label,mpref,buth,
0, 0, 0, 0, 0, "");
-
- uiDefButBitI(block, TOG, G_RECORDKEYS, REDRAWTIME, "Action and Object",
- (xpos+edgsp+(2*mpref)+(2*midsp)),y3,mpref, buth,
- &(G.flags), 0, 0, 0, 0, "Automatic keyframe insertion in Object and Action Ipo curves");
-
+
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, USER_KEYINSERTAVAI, REDRAWTIME, "Available",
- (xpos+edgsp+(2*mpref)+(2*midsp)),y2,mpref, buth,
- &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in available curves");
+ uiDefButBitS(block, TOG, AUTOKEY_ON, REDRAWTIME, "Auto-Keying Enabled",
+ (xpos+edgsp+(2*mpref)+(2*midsp)),y5,mpref, buth,
+ &(U.autokey_mode), 0, 0, 0, 0, "Automatic keyframe insertion for Objects and Bones");
- uiDefButBitI(block, TOG, USER_KEYINSERTNEED, REDRAWTIME, "Needed",
- (xpos+edgsp+(2*mpref)+(2*midsp)),y1,mpref, buth,
- &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion only when keyframe needed");
+ if (IS_AUTOKEY_ON) {
+ uiDefButS(block, MENU, REDRAWTIME,
+ "Auto-Keying Mode %t|Add/Replace Keys%x3|Replace Keys %x5",
+ (xpos+edgsp+(2*mpref)+(2*midsp)),y4,mpref, buth,
+ &(U.autokey_mode), 0, 1, 0, 0,
+ "Mode of automatic keyframe insertion for Objects and Bones");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, AUTOKEY_FLAG_INSERTAVAIL, REDRAWTIME, "Available",
+ (xpos+edgsp+(2*mpref)+(2*midsp)),y3,mpref, buth,
+ &(U.autokey_flag), 0, 0, 0, 0, "Automatic keyframe insertion in available curves");
+
+ uiDefButBitS(block, TOG, AUTOKEY_FLAG_INSERTNEEDED, REDRAWTIME, "Needed",
+ (xpos+edgsp+(2*mpref)+(2*midsp)),y2,mpref, buth,
+ &(U.autokey_flag), 0, 0, 0, 0, "Automatic keyframe insertion only when keyframe needed");
+
+ uiDefButBitS(block, TOG, AUTOKEY_FLAG_AUTOMATKEY, REDRAWTIME, "Use Visual Keying",
+ (xpos+edgsp+(2*mpref)+(2*midsp)),y1,mpref, buth,
+ &(U.autokey_flag), 0, 0, 0, 0, "Use Visual keying automatically for constrained objects");
uiBlockEndAlign(block);
-
-/* uiDefButBitS(block, TOG, USER_KEYINSERTACT, 0, "Action",
- (xpos+edgsp+(2*mpref)+(2*midsp)),y2,(spref+edgsp),buth,
- &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in Action Ipo curve");
- uiDefButBitS(block, TOG, USER_KEYINSERTOBJ, 0, "Object",
- (xpos+edgsp+(2*mpref)+(3*midsp)+spref-edgsp),y2,(spref+edgsp),buth,
- &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in Object Ipo curve"); */
uiDefBut(block, LABEL,0,"Duplicate with object:",
@@ -3709,9 +4057,17 @@ void drawinfospace(ScrArea *sa, void *spacedata)
(xpos+edgsp+(2*mpref)+(3*midsp)),y3,(mpref),buth,
&U.recent_files, 0, 30, 0, 0,
"Maximum number of recently opened files to remember");
+
+ uiDefButBitI(block, TOG, USER_SAVE_PREVIEWS, 0, "Save Preview Images",
+ (xpos+edgsp+(3*mpref)+(4*midsp)),y3,mpref,buth,
+ &(U.flag), 0, 0, 0, 0,
+ "Enables automatic saving of preview images in the .blend file");
} else if (U.userpref == 4) { /* system & opengl */
-
+ int memcachemax;
+ if (sizeof(void *) ==8) memcachemax = 1024*16; /* 64bit system, 16 gig of ram would be nice */
+ else memcachemax = 1024; /* 32 bit system, cant address over 2gig anyway */
+
uiDefBut(block, LABEL,0,"Solid OpenGL lights:",
xpos+edgsp, y6label, mpref, buth,
0, 0, 0, 0, 0, "");
@@ -3748,12 +4104,16 @@ void drawinfospace(ScrArea *sa, void *spacedata)
#ifdef WITH_VERSE
- uiDefBut(block, TEX, 0, "Verse Master: ",
- (xpos+edgsp)+mpref*2+2*midsp,y5,mpref*2+midsp,buth,
+ uiDefBut(block, LABEL,0,"Verse:",
+ (xpos+edgsp+(3*midsp)+(3*mpref)),y6label,mpref,buth,
+ 0, 0, 0, 0, 0, "");
+
+ uiDefBut(block, TEX, 0, "Master: ",
+ (xpos+edgsp+(3*midsp)+(3*mpref)),y5,mpref,buth,
U.versemaster, 1.0, 63.0, 0, 0,
"The Verse Master-server IP");
- uiDefBut(block, TEX, 0, "Verse Username: ",
- (xpos+edgsp)+mpref*2+2*midsp,y4,mpref*2+midsp,buth,
+ uiDefBut(block, TEX, 0, "Username: ",
+ (xpos+edgsp+(3*midsp)+(3*mpref)),y4,mpref,buth,
U.verseuser, 1.0, 63.0, 0, 0,
"The Verse user name");
#endif
@@ -3781,7 +4141,15 @@ void drawinfospace(ScrArea *sa, void *spacedata)
(xpos+edgsp+(1*mpref)+(1*midsp)),y2,mpref,buth,
&(U.uiflag), 0, 0, 0, 0, "Allows all codecs for rendering (not guaranteed)");
#endif
+
+ uiDefBut(block, LABEL,0,"Auto Run Python Scripts",
+ (xpos+edgsp+(1*midsp)+(1*mpref)),y6label,mpref,buth,
+ 0, 0, 0, 0, 0, "");
+ uiDefButBitI(block, TOG, G_DOSCRIPTLINKS, REDRAWBUTSSCRIPT, "Enabled by Default",
+ (xpos+edgsp+(1*mpref)+(1*midsp)),y5,mpref,buth,
+ &(G.f), 0, 0, 0, 0, "Allow any .blend file to run scripts automatically (unsafe with blend files from an untrusted source)");
+
uiDefBut(block, LABEL,0,"Keyboard:",
(xpos+edgsp+(3*midsp)+(3*mpref)),y3label,mpref,buth,
0, 0, 0, 0, 0, "");
@@ -3798,12 +4166,18 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiDefBut(block, LABEL,0,"System:",
- (xpos+edgsp+(4*midsp)+(4*mpref)),y6label,mpref,buth,
+ (xpos+edgsp+(4*midsp)+(4*mpref)),y7label,mpref,buth,
0, 0, 0, 0, 0, "");
+ uiDefButI(block, NUM, B_REDR, "Prefetch frames ",
+ (xpos+edgsp+(4*mpref)+(4*midsp)), y6, mpref, buth,
+ &U.prefetchframes, 0.0, 500.0, 20, 2,
+ "Number of frames to render ahead during playback.");
+
uiDefButI(block, NUM, B_MEMCACHELIMIT, "MEM Cache Limit ",
(xpos+edgsp+(4*mpref)+(4*midsp)), y5, mpref, buth,
- &U.memcachelimit, 0.0, 1024.0, 30, 2,
- "Memory cache limit in sequencer");
+ &U.memcachelimit, 0.0, (float)memcachemax, 30, 2,
+ "Memory cache limit in sequencer (megabytes)");
+
uiDefButS(block, NUM, B_REDR, "Frameserver Port ",
(xpos+edgsp+(4*mpref)+(4*midsp)), y4, mpref, buth,
&U.frameserverport, 0.0, 32727.0, 30, 2,
@@ -3822,11 +4196,16 @@ void drawinfospace(ScrArea *sa, void *spacedata)
&(U.uiflag), 0, 0, 0, 0, "Hide files/datablocks that start with a dot(.*)");
uiDefBut(block, LABEL,0,"OpenGL:",
- (xpos+edgsp+(5*midsp)+(5*mpref)),y6label,mpref,buth,
+ (xpos+edgsp+(5*midsp)+(5*mpref)),y7label,mpref,buth,
0, 0, 0, 0, 0, "");
+
+ uiDefButF(block, NUMSLI, B_DRAWINFO, "Clip Alpha: ",
+ (xpos+edgsp+(5*mpref)+(5*midsp)),y6,mpref,buth,
+ &(U.glalphaclip), 0.0, 1.0, 0, 0, "Clip alpha below this threshold in the 3d textured view");
+
uiDefButBitI(block, TOGN, USER_DISABLE_MIPMAP, B_MIPMAPCHANGED, "Mipmaps",
(xpos+edgsp+(5*mpref)+(5*midsp)),y5,mpref,buth,
- &(U.gameflags), 0, 0, 0, 0, "Toggles between mipmap textures on (beautiful) and off (fast)");
+ &(U.gameflags), 0, 0, 0, 0, "Scale textures for the 3d View (Looks nicer but uses more memory and slows image reloading)");
/* main choices pup: note, it uses collums, and the seperators (%l) then have to fill both halves equally for the menu to work */
uiDefButS(block, MENU, B_GLRESLIMITCHANGED, "GL Texture Clamp Off%x0|%l|GL Texture Clamp 8192%x8192|GL Texture Clamp 4096%x4096|GL Texture Clamp 2048%x2048|GL Texture Clamp 1024%x1024|GL Texture Clamp 512%x512|GL Texture Clamp 256%x256|GL Texture Clamp 128%x128",
@@ -3843,22 +4222,46 @@ void drawinfospace(ScrArea *sa, void *spacedata)
(xpos+edgsp+(5*mpref)+(5*midsp)), y1, mpref, buth,
&U.texcollectrate, 1.0, 3600.0, 30, 2, "Number of seconds between each run of the GL texture garbage collector.");
-
+ /* *** */
+ uiDefBut(block, LABEL,0,"Color range for weight paint",
+ (xpos+edgsp+(2*midsp)+(2*mpref)),y6label,mpref,buth,
+ 0, 0, 0, 0, 0, "");
+
+ uiDefButBitI(block, TOG, USER_CUSTOM_RANGE, B_WPAINT_RANGE, "ColorBand",
+ (xpos+edgsp+(2*midsp)+(2*mpref)),y5,mpref,buth,
+ &(U.flag), 0, 0, 0, 0,
+ "");
+
+ if((U.flag & USER_CUSTOM_RANGE)==0) {
+ vDM_ColorBand_store(NULL);
+ }
+ else {
+ rctf butrect;
+
+ vDM_ColorBand_store(&U.coba_weight); /* also signal for derivedmesh to use colorband */
+
+ BLI_init_rctf(&butrect, (xpos+edgsp+(2*midsp)+(2*mpref)),
+ (xpos+edgsp+(2*midsp)+(2*mpref)) + mpref,
+ y3, y3+30);
+
+ draw_colorband_buts_small(block, &U.coba_weight, &butrect, B_WPAINT_RANGE);
+ }
+
uiDefBut(block, LABEL,0,"Audio mixing buffer:",
- (xpos+edgsp+(2*midsp)+(2*mpref)),y3label,mpref,buth,
+ (xpos+edgsp+(2*midsp)+(2*mpref)),y2label,mpref,buth,
0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButI(block, ROW, 0, "256",
- (xpos+edgsp+(2*midsp)+(2*mpref)),y2,(mpref/4),buth,
+ (xpos+edgsp+(2*midsp)+(2*mpref)),y1,(mpref/4),buth,
&U.mixbufsize, 2.0, 256.0, 0, 0, "Set audio mixing buffer size to 256 samples");
uiDefButI(block, ROW, 0, "512",
- (xpos+edgsp+(2*midsp)+(2*mpref)+(mpref/4)),y2,(mpref/4),buth,
+ (xpos+edgsp+(2*midsp)+(2*mpref)+(mpref/4)),y1,(mpref/4),buth,
&U.mixbufsize, 2.0, 512.0, 0, 0, "Set audio mixing buffer size to 512 samples");
uiDefButI(block, ROW, 0, "1024",
- (xpos+edgsp+(2*midsp)+(2*mpref)+(2*mpref/4)),y2,(mpref/4),buth,
+ (xpos+edgsp+(2*midsp)+(2*mpref)+(2*mpref/4)),y1,(mpref/4),buth,
&U.mixbufsize, 2.0, 1024.0, 0, 0, "Set audio mixing buffer size to 1024 samples");
uiDefButI(block, ROW, 0, "2048",
- (xpos+edgsp+(2*midsp)+(2*mpref)+(3*mpref/4)),y2,(mpref/4),buth,
+ (xpos+edgsp+(2*midsp)+(2*mpref)+(3*mpref/4)),y1,(mpref/4),buth,
&U.mixbufsize, 2.0, 2048.0, 0, 0, "Set audio mixing buffer size to 2048 samples");
uiBlockEndAlign(block);
@@ -3904,6 +4307,10 @@ void drawinfospace(ScrArea *sa, void *spacedata)
0, 0, 0, 0, 0, "Select the default texture plugin location");
uiBlockEndAlign(block);
+ uiDefButBitI(block, TOG, USER_RELPATHS, B_DRAWINFO, "Relative Paths Default",
+ (xpos+edgsp+(5*mpref)+(5*midsp)),y3,mpref,buth,
+ &(U.flag), 0, 0, 0, 0, "Default relative path option for the file selector");
+
uiBlockBeginAlign(block);
uiDefBut(block, TEX, 0, "Seq Plugins: ",
(xpos+edgsp+(3*lpref)+(3*midsp)),y2,(lpref-smfileselbut),buth,
@@ -3924,12 +4331,12 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, TEX, 0, "Python: ",
+ uiDefBut(block, TEX, B_PYMENUEVAL, "Python Scripts: ",
(xpos+edgsp+lpref+midsp),y1,(lpref-2*smfileselbut),buth,
- U.pythondir, 1.0, 63.0, 0, 0, "The default directory to search for Python scripts");
+ U.pythondir, 1.0, 63.0, 0, 0, "The default directory to search for Python scripts (resets python module search path: sys.path)");
uiDefIconBut(block, BUT, B_PYMENUEVAL, ICON_SCRIPT,
(xpos+edgsp+(2*lpref)+midsp-2*smfileselbut),y1,smfileselbut,buth,
- 0, 0, 0, 0, 0, "Re-evaluate scripts registration in menus");
+ 0, 0, 0, 0, 0, "Re-evaluate scripts registration in menus (resets python module search path: sys.path)");
uiDefIconBut(block, BUT, B_PYTHONDIRFILESEL, ICON_FILESEL,
(xpos+edgsp+(2*lpref)+midsp-smfileselbut),y1,smfileselbut,buth,
0, 0, 0, 0, 0, "Select the default Python script location");
@@ -3946,9 +4353,13 @@ void drawinfospace(ScrArea *sa, void *spacedata)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, TEX, 0, "Temp: ",
+ uibut = uiDefBut(block, TEX, 0, "Temp: ",
(xpos+edgsp+(3*lpref)+(3*midsp)),y1,(lpref-smfileselbut),buth,
U.tempdir, 1.0, 63.0, 0, 0, "The directory for storing temporary save files");
+
+ /* set the btempdir from U.temp */
+ uiButSetFunc(uibut, eval_utemp_dir_callback, NULL, NULL);
+
uiDefIconBut(block, BUT, B_TEMPDIRFILESEL, ICON_FILESEL,
(xpos+edgsp+(4*lpref)+(3*midsp)-smfileselbut),y1,smfileselbut,buth,
0, 0, 0, 0, 0, "Select the default temporary save file location");
@@ -3980,7 +4391,7 @@ static void winqreadinfospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
short val= evt->val;
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
switch(event) {
case UI_BUT_EVENT:
@@ -4053,6 +4464,13 @@ static void winqreadinfospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
MEM_CacheLimiter_set_maximum(
U.memcachelimit * 1024 * 1024);
}
+ else if (val==B_WPAINT_RANGE) {
+ addqueue(sa->win, REDRAW, 1);
+ if(OBACT && (G.f & G_WEIGHTPAINT)) {
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
else do_global_buttons(val);
break;
@@ -4092,7 +4510,7 @@ static void winqreadbutspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
switch(event) {
case UI_BUT_EVENT:
@@ -4294,6 +4712,8 @@ void extern_set_butspace(int fkey, int do_cycle)
if (sbuts->tab[CONTEXT_OBJECT]==TAB_OBJECT_OBJECT)
sbuts->tab[CONTEXT_OBJECT]=TAB_OBJECT_PHYSICS;
else if (sbuts->tab[CONTEXT_OBJECT]==TAB_OBJECT_PHYSICS)
+ sbuts->tab[CONTEXT_OBJECT]=TAB_OBJECT_PARTICLE;
+ else if (sbuts->tab[CONTEXT_OBJECT]==TAB_OBJECT_PARTICLE)
sbuts->tab[CONTEXT_OBJECT]=TAB_OBJECT_OBJECT;
}
else sbuts->mainb= CONTEXT_OBJECT;
@@ -4308,8 +4728,9 @@ void extern_set_butspace(int fkey, int do_cycle)
else if(fkey==F10KEY) {
/* if it's already in scene context, cycle between tabs with the same key */
if (sbuts->oldkeypress == F10KEY) {
-
if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_RENDER)
+ sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_SEQUENCER;
+ else if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_SEQUENCER)
sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_ANIM;
else if (sbuts->tab[CONTEXT_SCENE]==TAB_SCENE_ANIM)
sbuts->tab[CONTEXT_SCENE]=TAB_SCENE_SOUND;
@@ -4345,7 +4766,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(curarea->win==0) return;
if(val) {
- if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -4359,9 +4780,6 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
switch(event) {
- case UI_BUT_EVENT:
- do_seqbuttons(val);
- break;
case LEFTMOUSE:
if(sseq->mainb || view2dmove(event)==0) {
@@ -4372,7 +4790,7 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
getmouseco_areawin(mval);
areamouseco_to_ipoco(v2d, mval, &dx, &dy);
- cfra= (int)dx;
+ cfra= (int)(dx+0.5f);
if(cfra< 1) cfra= 1;
/* else if(cfra> EFRA) cfra= EFRA; */
@@ -4402,13 +4820,23 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
mouse_select_seq();
break;
case PADPLUSKEY:
+ if (G.qual==LR_CTRLKEY) {
+ select_more_seq();
+ break;
+ }
+ /* fall through */
case WHEELUPMOUSE:
if(sseq->mainb) {
- sseq->zoom++;
- if(sseq->zoom==-1) sseq->zoom= 1;
+ if (G.qual == LR_SHIFTKEY) {
+ sseq->zoom += 0.10;
+ } else {
+ sseq->zoom++;
+ }
+ if(sseq->zoom >= -1 && sseq->zoom < 1) {
+ sseq->zoom += 2;
+ }
if(sseq->zoom>8) sseq->zoom= 8;
- }
- else {
+ } else {
if((G.qual==0)) {
dx= 0.1154f*(v2d->cur.xmax-v2d->cur.xmin);
v2d->cur.xmin+= dx;
@@ -4416,27 +4844,27 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
test_view2d(G.v2d, sa->winx, sa->winy);
view2d_do_locks(sa, V2D_LOCK_COPY);
}
- else if((G.qual==LR_SHIFTKEY)) {
- insert_gap(25, CFRA);
- BIF_undo_push("Insert gaps Sequencer");
- allqueue(REDRAWSEQ, 0);
- }
- else if(G.qual==LR_ALTKEY) {
- insert_gap(250, CFRA);
- BIF_undo_push("Insert gaps Sequencer");
- allqueue(REDRAWSEQ, 0);
- }
}
doredraw= 1;
break;
case PADMINUS:
+ if (G.qual==LR_CTRLKEY) {
+ select_less_seq();
+ break;
+ }
+ /* fall through */
case WHEELDOWNMOUSE:
if(sseq->mainb) {
- sseq->zoom--;
- if(sseq->zoom==0) sseq->zoom= -2;
+ if (G.qual == LR_SHIFTKEY) {
+ sseq->zoom -= 0.10;
+ } else {
+ sseq->zoom--;
+ }
+ if(sseq->zoom >= -1 && sseq->zoom < 1) {
+ sseq->zoom -= 2;
+ }
if(sseq->zoom<-8) sseq->zoom= -8;
- }
- else {
+ } else {
if((G.qual==LR_SHIFTKEY))
no_gaps();
else if((G.qual==0)) {
@@ -4455,28 +4883,29 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case PADPERIOD:
if(last_seq) {
- CFRA= last_seq->startdisp;
- v2d->cur.xmin= last_seq->startdisp- (last_seq->len/20);
- v2d->cur.xmax= last_seq->enddisp+ (last_seq->len/20);
+ int len = last_seq->enddisp - last_seq->startdisp;
+ v2d->cur.xmin= last_seq->startdisp- (len/20);
+ v2d->cur.xmax= last_seq->enddisp+ (len/20);
update_for_newframe();
}
break;
case AKEY:
- if(sseq->mainb) break;
- if((G.qual==LR_SHIFTKEY)) {
- add_sequence(-1);
+ if (G.qual == LR_CTRLKEY) {
+ deselect_markers(1, 0);
+ allqueue(REDRAWMARKER, 0);
+ } else {
+ if(sseq->mainb) break;
+ if((G.qual==LR_SHIFTKEY)) {
+ add_sequence(-1);
+ } else if((G.qual==0)) {
+ swap_select_seq();
+ }
}
- else if((G.qual==0))
- swap_select_seq();
break;
case SPACEKEY:
if (G.qual==0) {
- if (sseq->mainb) {
- play_anim(1);
- } else {
- add_sequence(-1);
- }
+ add_sequence(-1);
}
break;
case BKEY:
@@ -4500,39 +4929,70 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case DKEY:
- if(sseq->mainb) break;
- if((G.qual==LR_SHIFTKEY)) add_duplicate_seq();
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
+ duplicate_marker();
+ else if ((G.qual==LR_SHIFTKEY)) {
+ if(sseq->mainb) break;
+ add_duplicate_seq();
+ }
break;
case EKEY:
+ if(sseq->mainb) break;
+ if((G.qual==0))
+ transform_seq('e', 0);
break;
case FKEY:
if((G.qual==0))
set_filter_seq();
break;
case GKEY:
- if(sseq->mainb) break;
- if((G.qual==0))
+ if (G.qual & LR_CTRLKEY)
+ transform_markers('g', 0);
+ else if (G.qual==0) {
+ if(sseq->mainb) break;
transform_seq('g', 0);
+ }
break;
case KKEY:
if((G.qual==0)) { /* Cut at current frame */
- if(okee("Cut strips")) seq_cut(CFRA);
+ seq_cut(CFRA);
+ }
+ break;
+ case LKEY:
+ if((G.qual==0)) { /* Cut at current frame */
+ select_linked_seq( 0 );
+ } else if((G.qual==LR_CTRLKEY)) { /* Cut at current frame */
+ select_linked_seq( 2 );
+ } else if (G.qual==LR_SHIFTKEY) {
+ seq_lock_sel(1);
+ } else if (G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
+ seq_lock_sel(0);
+ }
+ break;
+ case YKEY:
+ if((G.qual==0)) { /* Cut at current frame */
+ seq_separate_images();
}
break;
case MKEY:
- if(G.qual==LR_ALTKEY)
- un_meta();
- else if((G.qual==0)){
- if ((last_seq) &&
- (last_seq->type == SEQ_RAM_SOUND
- || last_seq->type == SEQ_HD_SOUND))
- {
- last_seq->flag ^= SEQ_MUTE;
- doredraw = 1;
- }
- else
- make_meta();
+ if(G.qual==LR_ALTKEY) {
+ un_meta();
+ break; /*dont redraw timeline etc */
+ } else if(G.qual == 0){
+ make_meta();
+ break; /*dont redraw timeline etc */
+ } else if (G.qual == LR_SHIFTKEY) {
+ seq_mute_sel(1);
+ } else if (G.qual == (LR_SHIFTKEY|LR_ALTKEY)) {
+ seq_mute_sel(0);
+ } else if (G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
+ add_marker(CFRA);
+ } else if (G.qual == LR_CTRLKEY) {
+ rename_marker();
+ } else {
+ break; /* do nothing */
}
+ allqueue(REDRAWMARKER, 0);
break;
case NKEY:
if(G.qual==0) {
@@ -4541,7 +5001,12 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case RKEY:
- reassign_inputs_seq_effect();
+ if(G.qual==LR_SHIFTKEY)
+ seq_remap_paths();
+ if(G.qual==LR_ALTKEY)
+ reload_sequence();
+ else if (G.qual==0)
+ reassign_inputs_seq_effect();
break;
case SKEY:
if((G.qual==LR_SHIFTKEY))
@@ -4559,6 +5024,13 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
doredraw= 1;
}
break;
+ case HKEY: /* hide==mute? - not that nice but MKey us used for meta :/ */
+ if((G.qual==0)) {
+ seq_mute_sel(1);
+ } else if((G.qual==LR_ALTKEY)) {
+ seq_mute_sel(0);
+ }
+ break;
case XKEY:
case DELKEY:
if(G.qual==0) {
@@ -4637,14 +5109,14 @@ static void init_actionspace(ScrArea *sa)
saction->blockscale= 0.7;
saction->v2d.tot.xmin= 1.0;
- saction->v2d.tot.ymin= 0.0;
+ saction->v2d.tot.ymin= -1000.0;
saction->v2d.tot.xmax= 1000.0;
- saction->v2d.tot.ymax= 1000.0;
+ saction->v2d.tot.ymax= 0.0;
saction->v2d.cur.xmin= -5.0;
- saction->v2d.cur.ymin= 0.0;
+ saction->v2d.cur.ymin= -75.0;
saction->v2d.cur.xmax= 65.0;
- saction->v2d.cur.ymax= 1000.0;
+ saction->v2d.cur.ymax= 5.0;
saction->v2d.min[0]= 0.0;
saction->v2d.min[1]= 0.0;
@@ -4660,6 +5132,7 @@ static void init_actionspace(ScrArea *sa)
saction->v2d.keepzoom= V2D_LOCKZOOM_Y;
saction->v2d.keeptot= 0;
+ saction->autosnap = SACTSNAP_FRAME;
}
static void free_actionspace(SpaceAction *saction)
@@ -4690,39 +5163,6 @@ static void init_filespace(ScrArea *sa)
sfile->spacetype= SPACE_FILE;
}
-static void init_imaselspace(ScrArea *sa)
-{
- SpaceImaSel *simasel;
-
- simasel= MEM_callocN(sizeof(SpaceImaSel), "initimaselspace");
- BLI_addhead(&sa->spacedata, simasel);
-
- simasel->spacetype= SPACE_IMASEL;
- simasel->blockscale= 0.7;
- simasel->mode = 7;
- strcpy (simasel->dir, U.textudir); /* TON */
- strcpy (simasel->file, "");
- strcpy(simasel->fole, simasel->file);
- strcpy(simasel->dor, simasel->dir);
-
- simasel->first_sel_ima = 0;
- simasel->hilite_ima = 0;
- simasel->firstdir = 0;
- simasel->firstfile = 0;
- simasel->cmap = 0;
- simasel->returnfunc = NULL;
-
- simasel->title[0] = 0;
-
- clear_ima_dir(simasel);
-
- /* simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap); */
- simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap);
- if (!simasel->cmap) {
- error("in console");
- printf("Image select cmap file not found \n");
- }
-}
/* ******************** SPACE: SOUND ********************** */
@@ -4783,20 +5223,12 @@ static void changeimagepace(ScrArea *sa, void *spacedata)
static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
SpaceImage *sima= spacedata;
- unsigned short event= evt->event, origevent= evt->event;
+ unsigned short event= evt->event;
short val= evt->val;
if(val==0) return;
- if(uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
-
- if (U.flag & USER_LMOUSESELECT) {
- if (event == LEFTMOUSE) {
- event = RIGHTMOUSE;
- } else if (event == RIGHTMOUSE) {
- event = LEFTMOUSE;
- }
- }
+ if(uiDoBlocks(&sa->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
if (sima->image && (sima->flag & SI_DRAWTOOL)) {
switch(event) {
@@ -4805,36 +5237,43 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
scrarea_queue_winredraw(sa);
break;
case LEFTMOUSE:
- imagepaint_paint(origevent==LEFTMOUSE? L_MOUSE: R_MOUSE, 0);
+ imagepaint_paint(L_MOUSE, 0);
break;
case RIGHTMOUSE:
- imagepaint_pick(origevent==LEFTMOUSE? L_MOUSE: R_MOUSE);
+ imagepaint_pick(R_MOUSE);
break;
}
}
- else {
- /* Draw tool is inactive */
- switch(event) {
+ else if (G.obedit) {
+ if (U.flag & USER_LMOUSESELECT) {
+ if (event == LEFTMOUSE) {
+ event = RIGHTMOUSE;
+ } else if (event == RIGHTMOUSE) {
+ event = LEFTMOUSE;
+ }
+ }
+
+ /* Draw tool is inactive, editmode is enabled and the image is not a render or composite */
+ if (EM_texFaceCheck() && (G.sima->image==0 || (G.sima->image->type != IMA_TYPE_R_RESULT && G.sima->image->type != IMA_TYPE_COMPOSITE))) {
+ switch(event) {
case LEFTMOUSE:
- if(G.qual & LR_SHIFTKEY) {
- if(G.sima->image && G.sima->image->tpageflag & IMA_TILES)
+ if(G.qual == LR_SHIFTKEY) {
+ if(G.sima->image && G.sima->image->tpageflag & IMA_TILES) {
mouseco_to_curtile();
- else
- sima_sample_color();
+ }
+ } else if (!gesture()) {
+ mouseco_to_cursor_sima();
}
- else if(G.f & G_FACESELECT)
- gesture();
- else
- sima_sample_color();
break;
case RIGHTMOUSE:
- if(G.f & G_FACESELECT)
- mouse_select_sima();
- else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
- sample_vpaint();
+ mouse_select_sima();
break;
case AKEY:
- select_swap_tface_uv();
+ if(G.qual==0) {
+ select_swap_tface_uv();
+ } else if(G.qual==LR_CTRLKEY) {
+ average_charts_tface_uv();
+ }
break;
case BKEY:
if(G.qual==LR_SHIFTKEY)
@@ -4843,32 +5282,44 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
borderselect_sima(UV_SELECT_ALL);
break;
case CKEY:
- if(G.qual==LR_CTRLKEY)
- toggle_uv_select('s');
- else if(G.qual==LR_SHIFTKEY)
- toggle_uv_select('l');
- else if(G.qual==LR_ALTKEY)
- toggle_uv_select('o');
- else
- toggle_uv_select('f');
+ if (G.sima->flag & SI_SYNC_UVSEL) {
+ /* operate on the editmesh */
+ if (G.qual==0) {
+ if (G.scene->selectmode != SCE_SELECT_FACE) {
+ G.sima->flag ^= SI_SELACTFACE;
+ scrarea_queue_winredraw(curarea);
+ }
+ } else {
+ error("Sync selection to Edit Mesh disables UV select options");
+ }
+ } else {
+ /* normal operaton */
+ if(G.qual==LR_CTRLKEY) {
+ G.sima->sticky = SI_STICKY_VERTEX;
+ scrarea_do_headdraw(curarea);
+ } else if(G.qual==LR_SHIFTKEY) {
+ G.sima->sticky = SI_STICKY_DISABLE;
+ scrarea_do_headdraw(curarea);
+ } else if(G.qual==LR_ALTKEY) {
+ G.sima->sticky = SI_STICKY_LOC;
+ scrarea_do_headdraw(curarea);
+ } else {
+ G.sima->flag ^= SI_SELACTFACE;
+ scrarea_queue_winredraw(curarea);
+ }
+ }
break;
case EKEY :
if(okee("Unwrap"))
unwrap_lscm(0);
break;
- case GKEY:
- if((G.qual==0) && is_uv_tface_editing_allowed()) {
- initTransform(TFM_TRANSLATION, CTX_NONE);
- Transform();
- }
- break;
case HKEY:
if(G.qual==LR_ALTKEY)
reveal_tface_uv();
else if((G.qual==LR_SHIFTKEY))
hide_tface_uv(1);
else if((G.qual==0))
- hide_tface_uv(0);
+ hide_tface_uv(0);
break;
case LKEY:
if(G.qual==0)
@@ -4880,39 +5331,20 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual==LR_ALTKEY)
unlink_selection();
break;
- case MKEY:
- if((G.qual==0))
- mirrormenu_tface_uv();
- break;
- case NKEY:
+ case PKEY:
if(G.qual==LR_CTRLKEY)
- replace_names_but();
- break;
- case OKEY:
- if (G.qual==LR_SHIFTKEY) {
- G.scene->prop_mode = (G.scene->prop_mode+1)%7;
- allqueue(REDRAWHEADERS, 0);
- }
- else if((G.qual==0)) {
- G.scene->proportional= !G.scene->proportional;
- }
+ pack_charts_tface_uv();
+ else if(G.qual==LR_SHIFTKEY)
+ select_pinned_tface_uv();
+ else if(G.qual==LR_ALTKEY)
+ pin_tface_uv(0);
+ else
+ pin_tface_uv(1);
break;
- case PKEY:
- if(G.f & G_FACESELECT) {
- if(G.qual==LR_CTRLKEY)
- pack_charts_tface_uv();
- else if(G.qual==LR_SHIFTKEY)
- select_pinned_tface_uv();
- else if(G.qual==LR_ALTKEY)
- pin_tface_uv(0);
- else
- pin_tface_uv(1);
- }
- else {
- if(G.qual==LR_SHIFTKEY) {
- toggle_blockhandler(sa, IMAGE_HANDLER_PREVIEW, 0);
- scrarea_queue_winredraw(sa);
- }
+ case GKEY:
+ if((G.qual==0) && is_uv_tface_editing_allowed()) {
+ initTransform(TFM_TRANSLATION, CTX_NONE);
+ Transform();
}
break;
case RKEY:
@@ -4922,28 +5354,98 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
break;
case SKEY:
- if((G.qual==0) && is_uv_tface_editing_allowed()) {
- initTransform(TFM_RESIZE, CTX_NONE);
- Transform();
+ if (is_uv_tface_editing_allowed()) {
+ if ( G.qual==LR_SHIFTKEY) {
+ /* Snap */
+ snap_menu_sima();
+ } else if (G.qual==0) {
+ initTransform(TFM_RESIZE, CTX_NONE);
+ Transform();
+ }
}
break;
case VKEY:
- if((G.qual==0))
- stitch_uv_tface(0);
+ if(G.qual == 0)
+ stitch_vert_uv_tface();
else if(G.qual==LR_SHIFTKEY)
- stitch_uv_tface(1);
+ stitch_limit_uv_tface();
else if(G.qual==LR_CTRLKEY)
minimize_stretch_tface_uv();
break;
case WKEY:
weld_align_menu_tface_uv();
break;
+ case MKEY:
+ if((G.qual==0))
+ mirrormenu_tface_uv();
+ break;
+ case COMMAKEY:
+ if(G.qual==LR_SHIFTKEY) {
+ G.v2d->around= V3D_CENTROID;
+ } else if(G.qual==0) {
+ G.v2d->around= V3D_CENTER;
+ }
+
+ scrarea_queue_headredraw(curarea);
+ scrarea_queue_winredraw(curarea);
+ break;
+ case PERIODKEY:
+ if(G.qual==LR_CTRLKEY) {
+ G.v2d->around= V3D_LOCAL;
+ } else if(G.qual==0) {
+ G.v2d->around= V3D_CURSOR;
+ }
+ scrarea_queue_headredraw(curarea);
+ scrarea_queue_winredraw(curarea);
+ break;
case PADPERIOD:
if(G.qual==0)
image_viewcenter();
break;
+ case OKEY:
+ if(G.qual==0) {
+ G.scene->proportional= !G.scene->proportional;
+ allqueue(REDRAWHEADERS, 0);
+ } else if (G.qual==LR_SHIFTKEY) {
+ G.scene->prop_mode = (G.scene->prop_mode+1)%7;
+ allqueue(REDRAWHEADERS, 0);
+ }
+ break;
+ case PADSLASHKEY:
+ if(G.qual==0)
+ G.sima->flag ^= SI_LOCAL_UV;
+ scrarea_queue_winredraw(curarea);
+ break;
+ case TABKEY:
+ if (G.qual == LR_SHIFTKEY) {
+ G.scene->snap_flag ^= SCE_SNAP;
+ allqueue(REDRAWHEADERS, 0);
+ }
+ break;
+ }
}
- }
+ } else {
+ /* Draw and editmode are inactive */
+ switch(event) {
+ case LEFTMOUSE:
+ sima_sample_color();
+ break;
+ case RIGHTMOUSE:
+ if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
+ sample_vpaint();
+ break;
+ case NKEY:
+ if(G.qual==LR_CTRLKEY)
+ replace_names_but();
+ break;
+ case PKEY:
+ if(G.qual==LR_SHIFTKEY) {
+ toggle_blockhandler(sa, IMAGE_HANDLER_PREVIEW, 0);
+ scrarea_queue_winredraw(sa);
+ }
+ break;
+ }
+ }
/* least intrusive nonumpad hack, only for plus/minus */
@@ -4975,8 +5477,12 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case NKEY:
if(G.qual==LR_ALTKEY) {
new_image_sima();
- }
- else if(G.qual==0) {
+ } else if(G.qual==0) {
+ /*if (EM_texFaceCheck()) {
+ toggle_blockhandler(sa, IMAGE_HANDLER_TRANSFORM_PROPERTIES, UI_PNL_TO_MOUSE);
+ } else {
+ toggle_blockhandler(sa, IMAGE_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
+ }*/
toggle_blockhandler(sa, IMAGE_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
scrarea_queue_winredraw(sa);
}
@@ -5029,7 +5535,6 @@ static void init_imagespace(ScrArea *sa)
sima->spacetype= SPACE_IMAGE;
sima->zoom= 1;
sima->blockscale= 0.7;
- sima->flag = SI_LOCALSTICKY;
sima->iuser.ok= 1;
sima->iuser.fie_ima= 2;
@@ -5042,9 +5547,61 @@ static void init_imagespace(ScrArea *sa)
extern void drawimaselspace(ScrArea *sa, void *spacedata);
extern void winqreadimaselspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
+static void changeimaselspace(ScrArea *sa, void *spacedata)
+{
+ if(G.v2d==0) return;
-/* everything to imasel.c */
+ test_view2d(G.v2d, curarea->winx, curarea->winy);
+ myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+}
+
+static void init_imaselspace(ScrArea *sa)
+{
+ SpaceImaSel *simasel;
+
+ simasel= MEM_callocN(sizeof(SpaceImaSel), "init imaselspace");
+ BLI_addhead(&sa->spacedata, simasel);
+ simasel->spacetype= SPACE_IMASEL;
+ simasel->blockscale= 0.7;
+
+ /* view 2D */
+ simasel->v2d.tot.xmin= -10.0;
+ simasel->v2d.tot.ymin= -10.0;
+ simasel->v2d.tot.xmax= (float)sa->winx + 10.0f;
+ simasel->v2d.tot.ymax= (float)sa->winy + 10.0f;
+
+ simasel->v2d.cur.xmin= 0.0;
+ simasel->v2d.cur.ymin= 0.0;
+ simasel->v2d.cur.xmax= (float)sa->winx;
+ simasel->v2d.cur.ymax= (float)sa->winy;
+
+ simasel->v2d.min[0]= 1.0;
+ simasel->v2d.min[1]= 1.0;
+
+ simasel->v2d.max[0]= 32000.0f;
+ simasel->v2d.max[1]= 32000.0f;
+
+ simasel->v2d.minzoom= 0.5f;
+ simasel->v2d.maxzoom= 1.21f;
+
+ simasel->v2d.scroll= 0;
+ simasel->v2d.keepaspect= 1;
+ simasel->v2d.keepzoom= 1;
+ simasel->v2d.keeptot= 0;
+
+ simasel->prv_h = 96;
+ simasel->prv_w = 96;
+
+ simasel->flag = 7; /* ??? elubie */
+ strcpy (simasel->dir, U.textudir); /* TON */
+ strcpy (simasel->file, "");
+
+ simasel->returnfunc = 0;
+ simasel->title[0] = 0;
+ simasel->type = FILE_UNIX;
+ simasel->files = BIF_filelist_new();
+}
/* ******************** SPACE: OOPS ********************** */
@@ -5060,7 +5617,7 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(val==0) return;
- if( uiDoBlocks(&sa->uiblocks, event)!=UI_NOTHING ) event= 0;
+ if( uiDoBlocks(&sa->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
if (U.flag & USER_NONUMPAD) {
event= convert_for_nonumpad(event);
@@ -5099,6 +5656,15 @@ static void winqreadoopsspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
outliner_find_panel(sa, again, search_flags);
}
break;
+ case RKEY:
+ outliner_toggle_renderability(sa);
+ break;
+ case SKEY:
+ outliner_toggle_selectability(sa);
+ break;
+ case VKEY:
+ outliner_toggle_visibility(sa);
+ break;
case XKEY:
case DELKEY:
outliner_del(sa);
@@ -5267,10 +5833,10 @@ void init_v2d_oops(ScrArea *sa, SpaceOops *soops)
/* outliner space is window size */
calc_scrollrcts(sa, v2d, sa->winx, sa->winy);
- v2d->tot.xmax= 0.0;
- v2d->tot.ymax= 0.0;
- v2d->tot.xmin= -(v2d->mask.xmax-v2d->mask.xmin);
- v2d->tot.ymin= -(v2d->mask.ymax-v2d->mask.ymin);
+ v2d->tot.xmax= (v2d->mask.xmax-v2d->mask.xmin);
+ v2d->tot.ymax= (v2d->mask.ymax-v2d->mask.ymin);
+ v2d->tot.xmin= 0.0;
+ v2d->tot.ymin= 0.0;
v2d->cur= v2d->tot;
@@ -5283,10 +5849,18 @@ void init_v2d_oops(ScrArea *sa, SpaceOops *soops)
v2d->minzoom= 1.0;
v2d->maxzoom= 1.0;
- v2d->scroll= L_SCROLL;
+ /* B_SCROLLO used here instead of B_SCROLL, to stop old blender's hanging on
+ * loading a file from a version with horizontal scrolling due to an old bug
+ */
+ v2d->scroll= L_SCROLL+B_SCROLLO;
v2d->keepaspect= 1;
v2d->keepzoom= 1;
- v2d->keeptot= 1;
+
+ /* NOTE: keeptot is 2, as keeptot!=0 makes sure it does get
+ * too freely scrolled on x-axis, but keeptot=1 will result
+ * in a snap-back when clicking on elements
+ */
+ v2d->keeptot= 2;
}
else {
v2d->tot.xmin= -28.0;
@@ -5521,11 +6095,7 @@ void newspace(ScrArea *sa, int type)
scrarea_queue_headredraw(sa);
addqueue(sa->win, CHANGED, 1);
- scrarea_queue_winredraw(sa);
-
- areawinset(sa->win);
-
- bwin_clear_viewmat(sa->win);
+ scrarea_queue_winredraw(sa);
for (sl= sa->spacedata.first; sl; sl= sl->next)
if(sl->spacetype==type)
@@ -5571,6 +6141,9 @@ void newspace(ScrArea *sa, int type)
sl= sa->spacedata.first;
sl->area= sa;
}
+
+ areawinset(sa->win);
+ bwin_clear_viewmat(sa->win);
}
}
@@ -5592,6 +6165,17 @@ void newspace(ScrArea *sa, int type)
/* exception: imasel space */
else if(sa->spacetype==SPACE_IMASEL) {
SpaceImaSel *simasel= sa->spacedata.first;
+ if(simasel->type==FILE_MAIN) {
+ if (simasel->files) {
+ BIF_filelist_free(simasel->files);
+ BIF_filelist_settype(simasel->files, FILE_MAIN);
+ }
+ } else {
+ if (simasel->files) {
+ simasel->type= FILE_UNIX;
+ BIF_filelist_settype(simasel->files, simasel->type);
+ }
+ }
simasel->returnfunc= NULL;
simasel->title[0]= 0;
}
@@ -5659,7 +6243,8 @@ void freespacelist(ScrArea *sa)
free_oopspace(so);
}
else if(sl->spacetype==SPACE_IMASEL) {
- free_imasel((SpaceImaSel *)sl);
+ SpaceImaSel *simasel= (SpaceImaSel*) sl;
+ free_imasel(simasel);
}
else if(sl->spacetype==SPACE_ACTION) {
free_actionspace((SpaceAction*)sl);
@@ -5680,12 +6265,6 @@ void freespacelist(ScrArea *sa)
SpaceImage *sima= (SpaceImage *)sl;
if(sima->cumap)
curvemapping_free(sima->cumap);
- if(sima->info_str)
- MEM_freeN(sima->info_str);
- if(sima->info_spare)
- MEM_freeN(sima->info_spare);
- if(sima->spare)
- IMB_freeImBuf(sima->spare);
}
else if(sl->spacetype==SPACE_NODE) {
/* SpaceNode *snode= (SpaceNode *)sl; */
@@ -5726,11 +6305,13 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
so->treestore= NULL;
}
else if(sl->spacetype==SPACE_IMASEL) {
- check_imasel_copy((SpaceImaSel *) sl);
- }
- else if(sl->spacetype==SPACE_IMAGE) {
- SpaceImage *sima= (SpaceImage *)sl;
- sima->spare= NULL;
+ SpaceImaSel *simasel= (SpaceImaSel*) sl;
+ simasel->pupmenu= NULL;
+ simasel->menup= NULL;
+ simasel->files = BIF_filelist_new();
+ BIF_filelist_setdir(simasel->files, simasel->dir);
+ BIF_filelist_settype(simasel->files, simasel->type);
+ /* see SPACE_FILE - elubie */
}
else if(sl->spacetype==SPACE_NODE) {
SpaceNode *snode= (SpaceNode *)sl;
@@ -5773,10 +6354,6 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2)
SpaceImage *sima= (SpaceImage *)sl;
if(sima->cumap)
sima->cumap= curvemapping_copy(sima->cumap);
- if(sima->info_str)
- sima->info_str= MEM_dupallocN(sima->info_str);
- if(sima->info_spare)
- sima->info_spare= MEM_dupallocN(sima->info_spare);
}
sl= sl->next;
}
@@ -5834,6 +6411,12 @@ void allqueue(unsigned short event, short val)
}
}
break;
+ case REDRAWVIEW3D_IMAGE:
+ if(sa->spacetype==SPACE_VIEW3D || sa->spacetype==SPACE_IMAGE) {
+ scrarea_queue_winredraw(sa);
+ if(val) scrarea_queue_headredraw(sa);
+ }
+ break;
case REDRAWVIEWCAM:
if(sa->spacetype==SPACE_VIEW3D) {
v3d= sa->spacedata.first;
@@ -5882,6 +6465,14 @@ void allqueue(unsigned short event, short val)
scrarea_queue_headredraw(sa);
}
break;
+ case REDRAWSEQ:
+ if(sa->spacetype==SPACE_SEQ) {
+ addqueue(sa->win, CHANGED, 1);
+ scrarea_queue_winredraw(sa);
+ scrarea_queue_headredraw(sa);
+ }
+ /* fall through, since N-keys moved to
+ Buttons */
case REDRAWBUTSSCENE:
if(sa->spacetype==SPACE_BUTS) {
buts= sa->spacedata.first;
@@ -5954,13 +6545,6 @@ void allqueue(unsigned short event, short val)
scrarea_queue_winredraw(sa);
}
break;
- case REDRAWSEQ:
- if(sa->spacetype==SPACE_SEQ) {
- addqueue(sa->win, CHANGED, 1);
- scrarea_queue_winredraw(sa);
- scrarea_queue_headredraw(sa);
- }
- break;
case REDRAWOOPS:
if(sa->spacetype==SPACE_OOPS) {
scrarea_queue_winredraw(sa);
@@ -6015,6 +6599,11 @@ void allqueue(unsigned short event, short val)
scrarea_queue_winredraw(sa);
if(val) scrarea_queue_headredraw(sa);
}
+ case REDRAWMARKER: /* markers may not always match animation */
+ if ELEM6(sa->spacetype, SPACE_TIME, SPACE_IPO, SPACE_ACTION, SPACE_NLA, SPACE_SOUND, SPACE_SEQ) {
+ scrarea_queue_winredraw(sa);
+ if(val) scrarea_queue_headredraw(sa);
+ }
}
}
sa= sa->next;
@@ -6158,7 +6747,7 @@ SpaceType *spaceaction_get_type(void)
if (!st) {
st= spacetype_new("Action");
- spacetype_set_winfuncs(st, drawactionspace, changeactionspace, winqreadactionspace);
+ spacetype_set_winfuncs(st, NULL, drawactionspace, changeactionspace, winqreadactionspace);
}
return st;
@@ -6169,7 +6758,7 @@ SpaceType *spacebuts_get_type(void)
if (!st) {
st= spacetype_new("Buts");
- spacetype_set_winfuncs(st, drawbutspace, changebutspace, winqreadbutspace);
+ spacetype_set_winfuncs(st, NULL, drawbutspace, changebutspace, winqreadbutspace);
}
return st;
@@ -6180,7 +6769,7 @@ SpaceType *spacefile_get_type(void)
if (!st) {
st= spacetype_new("File");
- spacetype_set_winfuncs(st, drawfilespace, NULL, winqreadfilespace);
+ spacetype_set_winfuncs(st, NULL, drawfilespace, NULL, winqreadfilespace);
}
return st;
@@ -6191,7 +6780,7 @@ SpaceType *spaceimage_get_type(void)
if (!st) {
st= spacetype_new("Image");
- spacetype_set_winfuncs(st, drawimagespace, changeimagepace, winqreadimagespace);
+ spacetype_set_winfuncs(st, NULL, drawimagespace, changeimagepace, winqreadimagespace);
}
return st;
@@ -6202,7 +6791,7 @@ SpaceType *spaceimasel_get_type(void)
if (!st) {
st= spacetype_new("Imasel");
- spacetype_set_winfuncs(st, drawimaselspace, NULL, winqreadimaselspace);
+ spacetype_set_winfuncs(st, NULL, drawimaselspace, changeimaselspace, winqreadimaselspace);
}
return st;
@@ -6213,7 +6802,7 @@ SpaceType *spaceinfo_get_type(void)
if (!st) {
st= spacetype_new("Info");
- spacetype_set_winfuncs(st, drawinfospace, NULL, winqreadinfospace);
+ spacetype_set_winfuncs(st, NULL, drawinfospace, NULL, winqreadinfospace);
}
return st;
@@ -6224,7 +6813,7 @@ SpaceType *spaceipo_get_type(void)
if (!st) {
st= spacetype_new("Ipo");
- spacetype_set_winfuncs(st, drawipospace, changeview2dspace, winqreadipospace);
+ spacetype_set_winfuncs(st, NULL, drawipospace, changeview2dspace, winqreadipospace);
}
return st;
@@ -6235,7 +6824,7 @@ SpaceType *spacenla_get_type(void)
if (!st) {
st= spacetype_new("Nla");
- spacetype_set_winfuncs(st, drawnlaspace, changeview2dspace, winqreadnlaspace);
+ spacetype_set_winfuncs(st, NULL, drawnlaspace, changeview2dspace, winqreadnlaspace);
}
return st;
@@ -6246,7 +6835,7 @@ SpaceType *spaceoops_get_type(void)
if (!st) {
st= spacetype_new("Oops");
- spacetype_set_winfuncs(st, drawoopsspace, changeview2dspace, winqreadoopsspace);
+ spacetype_set_winfuncs(st, NULL, drawoopsspace, changeview2dspace, winqreadoopsspace);
}
return st;
@@ -6257,7 +6846,7 @@ SpaceType *spaceseq_get_type(void)
if (!st) {
st= spacetype_new("Sequence");
- spacetype_set_winfuncs(st, drawseqspace, changeview2dspace, winqreadseqspace);
+ spacetype_set_winfuncs(st, drawprefetchseqspace, drawseqspace, changeview2dspace, winqreadseqspace);
}
return st;
@@ -6268,7 +6857,7 @@ SpaceType *spacesound_get_type(void)
if (!st) {
st= spacetype_new("Sound");
- spacetype_set_winfuncs(st, drawsoundspace, changeview2dspace, winqreadsoundspace);
+ spacetype_set_winfuncs(st, NULL, drawsoundspace, changeview2dspace, winqreadsoundspace);
}
return st;
@@ -6279,18 +6868,31 @@ SpaceType *spacetext_get_type(void)
if (!st) {
st= spacetype_new("Text");
- spacetype_set_winfuncs(st, drawtextspace, NULL, winqreadtextspace);
+ spacetype_set_winfuncs(st, NULL, drawtextspace, NULL, winqreadtextspace);
}
return st;
}
+
+static void spacescript_change(ScrArea *sa, void *spacedata)
+{
+ SpaceScript *sc = (SpaceScript*) spacedata;
+
+ /*clear all temp button references*/
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList();
+ sc->but_refs = NULL;
+ }
+}
+
SpaceType *spacescript_get_type(void)
{
static SpaceType *st = NULL;
if (!st) {
st = spacetype_new("Script");
- spacetype_set_winfuncs(st, drawscriptspace, NULL, winqreadscriptspace);
+ spacetype_set_winfuncs(st, NULL, drawscriptspace, spacescript_change, winqreadscriptspace);
}
return st;
@@ -6301,7 +6903,7 @@ SpaceType *spaceview3d_get_type(void)
if (!st) {
st= spacetype_new("View3D");
- spacetype_set_winfuncs(st, drawview3dspace, changeview3dspace, winqreadview3dspace);
+ spacetype_set_winfuncs(st, NULL, drawview3dspace, changeview3dspace, winqreadview3dspace);
}
return st;
@@ -6312,7 +6914,7 @@ SpaceType *spacetime_get_type(void)
if (!st) {
st= spacetype_new("Time");
- spacetype_set_winfuncs(st, drawtimespace, NULL, winqreadtimespace);
+ spacetype_set_winfuncs(st, NULL, drawtimespace, NULL, winqreadtimespace);
}
return st;
@@ -6324,7 +6926,7 @@ SpaceType *spacenode_get_type(void)
if (!st) {
st= spacetype_new("Node");
- spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace);
+ spacetype_set_winfuncs(st, NULL, drawnodespace, changeview2dspace, winqreadnodespace);
}
return st;
diff --git a/source/blender/src/spacetypes.c b/source/blender/src/spacetypes.c
index ea0d680e852..4a0375f2366 100644
--- a/source/blender/src/spacetypes.c
+++ b/source/blender/src/spacetypes.c
@@ -52,6 +52,7 @@
struct _SpaceType {
char name[32];
+ SpacePrefetchDrawFP winprefetchdraw;
SpaceDrawFP windraw;
SpaceChangeFP winchange;
SpaceHandleFP winhandle;
@@ -70,8 +71,9 @@ SpaceType *spacetype_new(char *name)
return st;
}
-void spacetype_set_winfuncs(SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle)
+void spacetype_set_winfuncs(SpaceType *st, SpacePrefetchDrawFP prefetchdraw, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle)
{
+ st->winprefetchdraw = prefetchdraw;
st->windraw= draw;
st->winchange= change;
st->winhandle= handle;
@@ -105,6 +107,17 @@ static SpaceType *spacetype_from_area(ScrArea *area)
}
}
+void scrarea_do_winprefetchdraw(ScrArea *area)
+{
+ SpaceType *st= spacetype_from_area(area);
+
+ areawinset(area->win);
+
+ if(area->win && st->winprefetchdraw) {
+ st->winprefetchdraw(area, area->spacedata.first);
+ }
+}
+
void scrarea_do_windraw(ScrArea *area)
{
SpaceType *st= spacetype_from_area(area);
diff --git a/source/blender/src/splash.jpg.c b/source/blender/src/splash.jpg.c
index 8a40948de58..8f930c1c769 100644
--- a/source/blender/src/splash.jpg.c
+++ b/source/blender/src/splash.jpg.c
@@ -1,7227 +1,2649 @@
/* DataToC output of file <splash_jpg> */
-int datatoc_splash_jpg_size= 231089;
+int datatoc_splash_jpg_size= 84581;
char datatoc_splash_jpg[]= {
-137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0,
- 0, 1,245, 0, 0, 1, 15, 8, 2, 0, 0, 0,212, 35,202, 57, 0, 0, 0, 4,103, 65, 77, 65, 0, 0,214,216,212, 79, 88, 50,
- 0, 0, 0, 25,116, 69, 88,116, 83,111,102,116,119, 97,114,101, 0, 65,100,111, 98,101, 32, 73,109, 97,103,101, 82,101, 97,100,
-121,113,201,101, 60, 0, 3,134, 67, 73, 68, 65, 84,120,218, 98,252,255,255, 63,195, 40, 24, 5,163, 96, 20,140,130, 97, 7, 0,
- 2,136,105, 52, 8, 70,193, 40, 24, 5,163, 96, 88, 2,128, 0, 26, 45,223, 71,193, 40, 24, 5,163, 96,120, 2,128, 0, 26, 45,
-223, 71,193, 40, 24, 5,163, 96,120, 2,128, 0, 26, 45,223, 71,193, 40, 24, 5,163, 96,120, 2,128, 0, 26, 45,223, 71,193, 40,
- 24, 5,163, 96,120, 2,128, 0, 98, 25, 64,187,255,255,255,247,255,249,181,223,167,150,252,123,122,153,145, 95,146,197, 56,156,
- 89,213,158,145,133,109, 52, 86, 70,193, 40, 24, 5,163,128,114, 0, 16, 64,140, 3,184, 62,242,239,163,115,191,247,246,253,127,
-251,144,225,255, 95, 16,159, 83,128,197, 60,150,197, 36,130,145,145,113, 52, 98, 70,193, 40, 24, 5,163,128, 66, 0, 16, 64, 3,
- 54, 62,243,255,199,167,191, 23, 55,254,127,115, 15, 90,184, 3,193,247, 15,127, 14, 77,255,189,163,253,255,215,119,163, 17, 51,
- 10, 70,193, 40, 24, 5, 20, 2,128, 0, 26,184,241,119, 96,191,225,223, 31,116,193,127,127,254, 94,217,242,115,125,217,191,103,
- 87,254,255,255, 55, 26, 61,163, 96, 20,140,130, 81, 64, 54, 0, 8,160, 1, 43,223, 25, 57,249,153,117,189, 25,121,197, 81, 11,
-125, 48,241,252,218,207,245,229,127,175,238,252,255,251,199,104, 12,141,130, 81, 48, 10, 70, 1,121, 0, 32,128, 24, 7,246,124,
-130,191, 79, 47,253,222, 63,249,255,243,171,136,242, 29, 49,246,206,200,108, 16,200, 98, 18,206, 36, 40, 59, 26, 79,195, 3,220,
-126,241,225,196,173,231,215,159,190,125,245,233,251,215,159,191,217, 89,153, 5,184,216,133,121, 56,116,228, 68, 76,148,196,101,
-133,121, 7,208,109,191,255,252,125,251,229, 7, 11, 51,147, 8, 47,231,208,181, 98, 20,140, 2,100, 0, 16, 64,140, 3,126,254,
-204,191, 79, 47,128, 69,252,191, 91,251,177,187, 79, 68,137,213, 38,141, 89,213,110, 52,170,134, 46,248,245,231,239,162, 67,215,
-167,238,186,112,237, 9,190,153, 21, 85, 9,129, 36, 71,237, 56, 59, 45,250, 23,127,192, 92, 16, 54, 97,235,166,179,247,212, 36,
- 5, 46,119,199, 13, 81, 43, 70,193, 40, 64, 3, 0, 1,196, 56, 24,206, 23,251,255,235,251,159,227,243,254,156, 91,205,240,231,
- 23,134, 28, 3, 3, 59, 23,139,101, 34,139, 65, 0, 35, 27,247,104,132, 13, 57,112,230,238,203,196, 25, 59,111, 61,255, 64,164,
-122,126, 46,182,174, 40,219, 4, 7,109,122, 58,178,126,245,241,142,141,167,129, 12,218, 21,190,116,176, 98, 20, 12, 90,240,250,
-245,235,119,239,222,189,124,249,242,223,191,127,236,236,236,223,190,125,227,228,228,148,150,150,150,145,145,249,254,253,251,251,
-247,239,255,130,193,151, 47, 95, 62,127,254, 12,100,252, 7, 3, 89, 89, 89, 69, 69, 69,102,102,102,178,237, 5, 8, 32,198,193,
-115,126,228,159,139, 27,127, 31,157,205,128, 99,241, 12,179,150, 59,139, 85, 50,147,160,204,104, 90, 25, 66, 96,235,249,251, 17,
- 19,183, 1,219,239,164,106, 12,181, 80, 93,152,229,206,204, 68,143,249,161, 53, 39,110, 69, 79,217, 1, 97,211,168,240,165,131,
- 21,163, 96, 16,130,175, 95,191,222,185,115, 7, 88,130, 3,139,108,121,121,121, 97, 97, 97, 96,177, 14,151, 58,120,240, 32,176,
-184,231,231,231,231,225,225, 17, 19, 19,227,224,224, 96,101,101,101, 99, 99, 3,146,192, 50,253,231,207,159, 64,189,111,222,188,
- 1,150,242, 74, 74, 74,228, 57, 0, 32,128, 88, 6, 79, 88,176,232,251, 51,137,169,254, 62, 52,253,223,163,179,152,178,127,175,
-237,252,247,238, 17,171,109, 6,179,130,233,104,186, 25, 18,224,234,227,183,145,147,200, 41,220,129, 96,245,137,219,236,172,204,
-115,211,221,104,237,200,243,247, 95,165,204,218, 51,212,173, 24, 5,131, 16, 92,185,114, 5,216,102,151,146,146,210,212,212, 4,
-150,218,104,178, 47, 94,188, 96,100,100, 4, 22,250,186,186,186, 88,181, 3,155,249,218,218,218,192,138,225,226,197,139,135, 14,
- 29, 50, 54, 54,230,230, 38,121, 0, 3, 32,128,168, 86,190,255,255,253,243,255,187,135, 12,127,127, 33,207,144,146,216,151, 96,
-100, 96,231,102,214,245,249,255,233,197,255, 15, 79, 17,227, 51, 48,243,254,191,184,254,107,123, 11,171,121, 44,139, 81,200,104,
-234, 25,252, 32,123,222,190,159,191,209, 11,119, 54, 22,102, 15,125,121, 27, 13,105, 25, 33, 30, 32,247,221,151, 31,151, 30,189,
-217,114,238,222,179,247, 95,209, 84, 46, 57,124,195,215, 72, 57,192, 84,153,118, 46,124,249,241, 91, 72,255,150,239,191,254, 12,
-105, 43, 70,193, 32,108,182,159, 58,117, 74, 92, 92,220,206, 14,125,226,240,199,207,223, 79, 95,124, 60,118,252,236,221,219,151,
- 45, 45, 76,180,180, 80,198, 33,255,255,255,255,231,207,191, 95,191,255,124,255,249,231,215,175, 63, 76, 76, 76,162,194,220, 70,
- 70, 70,111,223,190, 59,118,236,152,185,185, 57, 31, 31, 31, 73, 46, 1, 8, 32, 42,148,239, 64, 55,253, 61,191,246,207,213,237,
- 12,223,222,255,255,247,151, 18,163, 24, 25,153, 24,152, 89,254,127,125,139, 36,132,170,226,203,235,223, 7,167,254,123,125,151,
-213, 54,157,145, 75, 96, 52, 37, 13, 90,240,244,221,151,211,247, 94,162, 9,166, 57,235,214, 6,153,139,241,115,161,137, 79,136,
-183,159,182,235, 82,197,242, 35,127,254,162,108,122, 40, 95,118,216,215, 88,145, 70,163, 52, 63,127,255, 9,237,223,242,228,221,
- 23,218, 5, 2, 29,172, 24, 5,131, 46,229, 63,125,122,243,230, 77, 96,171, 92, 84, 84, 20, 46,248,237,251,175,251,143,223, 92,
-190,246,248,233,171,207,119,111,223,120,255,246,185,128,160,216,153,155,191,110, 62, 62, 24,224,174,207,194,204, 4,148,125,245,
-246,243,151,175, 63,129, 21,192,207, 95,127,126,195, 26, 70,162,194,188,166,134,202,170,242,194,228, 13,209, 0, 4, 16, 21,202,
-247, 63,135,166,131,167, 70,127, 82,161,170, 32,202,190,159,127, 47,109,250,255,246, 30,171, 83, 33,147,132,198,104,122, 26,156,
- 64, 90,136,103, 71,101, 96,196,196,109,111, 62,127, 7,114,185,216, 89,150,229,122,121, 26, 40, 96, 85, 12, 44,193,115, 61, 12,
-184,217, 89, 50,231,238, 67, 22,127,240,250,211,137,219, 47,172,213,165,104,211,189,216,127,242,206, 11, 26,247, 96,104,110,197,
- 40, 24, 84,224,214,173, 91,175, 95,191,182,177,177,129, 15,200,188,124,253,233,244,197,251, 55,110,191,252,242,237,231,159,191,
-127,223,188,122,248,249,195, 27, 46, 46, 62, 81, 9,133, 31,223,190,234,168, 42,126,252,252,125,255,177,155,127,255, 98,223,206,
-249,250,237,231,237,123, 47,158, 23,229,231, 97,121,175,172, 76,114, 95, 22, 32,128, 40,109, 25,253,125,114,241,239,245,221, 84,
- 41,220, 73,170, 8,254, 61,189,252,107, 67, 5,176,211, 48,186,205,117,208, 2, 91, 13,233, 99,205,225,186,114, 34, 64,246,210,
- 28, 79, 92,133, 59, 28, 36, 58,104,107,203, 8,163, 9,110, 59,127,159, 22,110,155,176,237,220,226,195,215,105,234,125, 58, 88,
- 49, 10, 6, 15,120,249,242,229,131, 7, 15,238,222,189,107,105,105, 9, 47,220,143,157,185, 59,123,233,225, 35,167,110, 60,120,
-112,239,254,157,139, 47,158, 92,103,101,101, 7,182, 98,133,196,164,153, 88, 89, 76, 13, 20,245, 52,101, 14,158,184,133,171,112,
-135,141,106, 48,222,190,115,255,200,153, 7,199,207, 63,250, 69,226, 64, 31, 64, 0, 81,218,126,255,255,229,205,255,159,159, 7,
- 36, 64,255,127,126,245,123,103,199,255,215,119, 89, 44,226, 24, 57,248, 70, 83,216, 32, 4,242, 34,124, 7,235, 66, 87,159,184,
-229,101,168, 72, 80, 49, 48, 29,251, 25, 43, 93,125,242, 22,165, 65,244,252, 61,213, 93,181,235,210,195,202,229, 71,105,234,113,
- 58, 88, 49, 10, 6, 9,120,247,238,221,245,235,215,153,153,153, 63,126,252,168,168,168,248,236,217, 51, 25, 25,153,143,159,191,
-109,216,126,250,208,209, 83,191,127,124, 97, 97,102,248,253,253,147,168,184, 36, 39, 55, 31, 43, 43, 27, 47,191,238,163,123,215,
- 61,220, 28, 76,245, 21, 55,237,190,248,251, 55,129, 49,109, 38, 38,230, 47, 95, 62,240,241, 11,159, 58,119, 71, 94,138, 79, 74,
-156,132,113,105,128, 0,162,180,124,103, 18, 87,103, 18, 85, 6,182,166,169, 93,120, 19, 55, 77,251,247,247,159,211,203,254,189,
-185,207,234,152,203, 36,140,179,121,248,234,227,183,223,127,255,241,115,177,241,112,140,208,195,135,255,252,253,247,241,219,207,
-175, 63,127,139,240,114,114,177,179,210,211,106,110, 14, 86,226, 23,179, 43, 99,164,221,151, 31,191, 81,215, 61, 55,159,189,143,
-153,178,253, 31, 45,151, 5,211,193,138, 81, 48, 24,192,239,223,191, 47, 95,190,252,237,219, 55, 53, 53, 53, 49, 49,177, 91,183,
-110,241,241,241, 61,125,250,244,204,153,243,123, 15, 93,252,245,251, 47,243,223,159,146, 82, 50, 44,156,252, 12,140,172, 76,172,
- 28,127,254, 49,126,126,247,132,155,243,143,135,155,163,172, 56,235,218,109,199,254, 51,112,225,111,241, 48, 51,179,252,254,253,
-243,211,199,119,146,210, 74,172, 44, 76, 2,124, 92, 36,185, 16, 32,128, 40, 46,223, 5,101, 88,157,139,255,156, 95,251,255,221,
-131,255,127,255, 64, 29,197,132, 97, 44, 80,132,133,245,255,219,135,255, 63, 97, 25,142,100, 68, 30,121,103,231, 97,228,224,101,
-100,231, 97, 96,229,100, 96,100, 98,248,243,243,255,207,175,160, 46,194,183, 15,184,198,231,255,221, 63,254,235,243, 43, 54,207,
- 42, 38, 9, 77,172, 10, 38,110, 63,191,238,212,109,107,117, 41, 43, 53, 41, 61, 57, 17, 96, 33, 34,200,195, 65,188, 31,127,253,
-249,251,254,203, 15, 96, 13,193,196,200, 8,116, 1, 43,120,127, 57, 19,211, 16, 56,196, 24, 88,172, 63,126,251, 25,216, 4, 62,
-123,239,229,129,107, 79,222,126,254, 49, 61,197,217, 76, 69, 98,208, 58,152,139, 29, 61,229, 0, 3,158,138,230, 3, 43,185,144,
-254,205, 31,191,253,162,157, 23,232, 96,197, 40, 24, 12,224,203,151, 47, 39, 79,158, 4, 54,216,141,140,140, 32, 34,146,146,146,
-215,174, 93,251,247,239,255,193, 99, 55, 4,132, 37, 56,184,133,254,252,103,254,247,143,233,239,191,127, 12,255,255,255,249,249,
-151,145,145, 65, 65, 89, 67,140,255,191,134,138,216,249, 27,111,174, 93,185, 34, 35,175,194,195, 35,248,247,239, 31, 88,129,206,
- 4, 4,192, 18,244,223,191,191,127,254, 0,171,143, 95, 63,126,124,125,255,230,165,168,152, 12,176, 21, 47, 43, 37,200,197, 73,
- 90, 11, 21, 32,128,168, 48,191,202, 36,174,198,230, 81, 9, 26, 7,135, 28, 7,198,196,194,200,194,134,188,109, 10,114,158,251,
-223, 7,167,127, 31,156,194,240, 9,231,116, 19,163,144, 60,147,140, 1,179,172, 62,179,168, 50, 3,175, 56,176,160, 7,149,239,
-191,191, 51,124,125,203,240,254,225,191,103,215,126, 63, 60,251,239,213,109,144, 8,102,115,255,205,221, 95,219, 91,217,188, 27,
-152,196, 84, 48,101,127,254,254,115,227,217,123, 32,154,187,255, 42, 47, 7,107, 99,168,101,161,183, 49,241, 30,188,241,244, 93,
-251,134, 83, 79,222, 1,251, 89, 76, 64,127, 9,243,114, 46,200,116,231,229, 28, 2, 93, 1, 96,199, 37,124,194, 86,248, 58, 22,
- 73,129,193,190, 1,248,221, 23,244, 19,229, 4,185,217,169,101, 56, 48,155,197, 76,217,129,182,147, 86,128,139,253,195,183,159,
- 67,200,138, 81, 48, 24, 0,176,205,126,226,196, 9, 67, 67, 67, 97, 97,196,140,209,246,237, 59,254,254,249,237, 31, 16,124,233,
-238,175, 39, 47, 62,126,255,245,151,145,225, 31,176,253,201,203,195,161, 40, 43,162, 32, 39, 34, 45, 33, 40, 46,202,199,204,196,
-244,245,235,215,147,103,174, 42,171, 25,220,185,121, 78, 78, 65,131,143, 95, 8, 88,154,255, 1,226, 95,223,190,126,249,244,227,
-251,151,223,127,126,177,178,176,253,250,253,227,235,231, 79, 76,204,204,178, 10,234,192,146, 71, 69, 65,140, 84,119, 2, 4, 16,
-213,214,191,131,150, 54,178,113,161,149,233,208,194,247,207,175,191, 23,215,255, 62,185, 24,215,222,212,255, 60, 34, 44, 58, 62,
-204,154, 46, 76, 34, 24,107,128,128,173,120, 1, 25, 32, 98, 82,180,102, 55, 9,255,123,251,240,159,139, 27,255, 61,187,130,173,
-136,191,247,107, 87, 39,123, 64, 59, 35,143, 8,154, 20, 27, 11, 98,131,239,231, 31,191, 31,190, 33,109,194,224,237,151, 31,123,
-175, 60,126,253, 25, 90,175,240,176,179,254,254, 59, 52, 38,117,191,255,250,131, 60,156, 13,236,121, 12,242, 94,199,141,103,232,
- 41, 68, 77, 82,144, 90,134, 87, 44, 59,178,235,210, 67,100,145, 82, 95,227, 11, 15, 94,239,190,252,104, 8, 89, 65,219, 4,243,
-227,247,243, 23,136,202, 73, 82, 66,128,147,131,245,236,133,135,215,110, 62,215, 82,151, 52, 54,144, 39,201, 52, 34, 53,162, 89,
- 42, 40,192, 45, 40,192, 69,158,251,159,189,248,176,247,224,141,216,112, 11,252,118, 41, 41,136, 82, 56, 44, 3, 44,220, 13, 12,
- 12,224,133,251,159, 63,255, 14, 31, 57,246,246,245,219,240,168, 88, 22, 86, 22, 43, 99,165,149,155, 79,137, 9,243,169, 43, 75,
- 40,200,138,200, 74, 9,161,181,187,185,185,185, 35, 67, 92,183,239, 57,249,255,191,193,195,123, 87,223,190,121, 6,172, 24,152,
-153, 89,127,254,252, 6,108,183, 3,155,243,204, 44, 44,108,108, 28, 92, 92,124,220,220, 2,204,204, 44,247,110, 95, 52, 48,178,
- 84,144, 19, 33,213,169, 0, 1, 68,243,253,171,255, 94,221,249,115,122,233,223,107, 59,113, 86, 12,226,234,172,118, 89, 68,237,
- 74,101,231, 99,214,241,102,146, 53,250,125, 98,209,223, 75, 27,177, 20,241,207,175,254, 62, 54,151,205,173, 28, 93, 28,117, 44,
-136,155,196, 1,104, 14, 86,102, 62, 46, 54,120,249, 46,194,199,201, 52, 68, 46,152, 98,102, 98,228,227,100,251, 54,116, 54,215,
- 28,185,249, 12, 77,196, 66, 85,146, 42, 38, 47, 58,116,109,210,142, 11,200, 34, 62, 70,138, 77,161, 86,126,221, 27,169,229,120,
- 58, 88, 65,107, 0, 44,251,150,172, 60,129, 72,249, 28,172, 33,254,198, 63,126,254,190,255,224,181,146, 2,201,133, 11,145, 26,
- 33,150, 42,194,202, 92, 50, 42, 18,132,141, 63, 64, 54, 98,138, 31, 61,121,231,222,131, 55,192,114, 31, 98, 87, 93,185, 47, 37,
-161,116,234,212, 41,117,117,117, 17, 17,144,191,254,255,103,248,246,253,247,225, 67, 71,206,158, 57, 30, 19,155,244,239, 31,227,
-175,159,191,117, 52,164, 69,133,157, 69,132,121,129, 61,126, 92,134,240,242,241,185, 59,153, 92,190,241,228,247,239,111, 79, 31,
-221, 5, 13,224, 48,253,230,229, 19, 98,231,228, 98, 98, 98, 98,103,231,102, 99, 99,103, 98, 98, 6,181,148, 25, 25, 57,185,121,
-190,190,191,203,201, 78,242, 49,139, 0, 1, 68,219,242, 29,216,208,254,181,167,247,255,203,155,120,198,100,128,197, 49,218, 50,
-118, 96,171,243,210,195,215,207, 63,124,253,245,231, 47, 59, 11,179,172, 8,175,129,188, 24,188,229,201,200, 47,201,234,148,207,
-240,247,231,223,171, 59,176,116,144, 47,111,249,167,235,203, 36,169,133,199, 85,164, 30,185, 3, 84,142,172, 3,143,246,207,223,
-127,189,249,252,253,219,207,223,255,254,131,106, 5, 81, 62, 78, 1,110, 14,114,194,237,223,255,207, 63,126,177, 48, 49,113,115,
- 80, 52, 23,250,159,200, 45, 5,224,163,107,159,188,251,242, 21,232,242,127,255,129,221, 29, 97, 94, 14, 81, 62,146,219, 80,207,
-222,125, 1,246,117,116, 73,111,101, 64,192,163, 55,159, 47,160,102, 78, 96, 39,208, 85, 79,142,242,116,120,226,246,243, 44,212,
-149,245,218, 50,194, 11,179,220,169,216,157,161,131, 21,244, 4, 49,225, 22, 91,118, 94,250,240,225,219,243,151, 31, 49,155,228,
-160,166,189, 56,191,181,133,202,181, 27,207,128,133, 56,184,140,254, 8,108, 26, 27,235,203,105,105, 72, 1, 27,209,199, 78,222,
- 5,114,127, 32,205,157, 96,213, 8,100,195,205, 71,110,116, 67, 20, 3,187, 14, 70,250,114,192,230,252,181,155,207,172,205, 85,
- 32,226,192,166, 61, 68, 4,200, 5, 22,217,130,252, 92, 62, 30,122, 64,187,206, 93,124, 8,228,194, 77,216,115,224, 58,196,100,
- 96,237, 2,212, 11,148,122,255,225, 43,176,148,231, 96,103,117,118,208, 4,235,125,125,238,226, 35,160, 70, 72,117, 2, 52, 25,
-232, 30,136, 47,172,205,149,241, 52,240, 47, 93,186, 4, 44,217,165,165,165, 33, 69,193,151, 47,191, 47, 95,185,114,242,248,225,
-144,176, 72, 94, 62,129,159,191,126,114,115,113, 1, 75,100, 9, 49,126, 34,122, 75, 63,228,164,248,101,132,255,177,179,235,254,
-249,243, 7,216, 96, 7, 22,232,144,226,229,223,191,191, 28,236, 44,194,130, 60,194,130,220, 66,252,220, 34,194,250,191,127,126,
-186,122,245,170,182, 54,105,231,238, 1, 4, 16, 13,203,247, 63,151,183,254, 57, 62,239,255,199,231, 56, 11,119, 94, 49, 86,103,
-148, 61, 74,159,190,253,156,119,224,234,166, 51,119, 31,190,249,252,233,251,207,191,255,254, 3,203, 56, 1,110,118, 21, 9,129,
- 16,115,213, 68, 7,109,200,176, 15, 35, 43, 7,171,125,206,255,111, 31,255,221, 63,142, 81, 52,254,253,125,116, 46, 91,112, 15,
-158, 75, 92, 33,149, 42,176, 48, 2,118,165,175, 62,121, 11, 44,145,129, 65,202,197,206,162, 36,198,175, 47, 47,106,171, 33,205,
-193, 70, 90,176,124,248,250, 99,253,233,187, 7,175, 61,185,253, 2, 52, 17,251, 27,232,238,255, 32,151,243,112,176, 42,139, 11,
-216,106, 74, 7,154,170, 96,110,218,196, 90,241,108, 61,119,127,231,165, 7,183,159,127, 0,150,239,204, 76, 76, 34,188, 28, 64,
- 39,249,155, 40, 27,224, 30,122, 59,123,239,229,233,187, 47, 30,188,254, 4,244,200,159,191,255, 57,217, 88,228, 69,120,205, 84,
- 36,156,116,228,120, 9,173, 23, 2, 86,165,219,206,223, 63,118,235,217,249,251,175,128, 69, 51,176, 66, 5, 6, 5,176,213, 15,
-116,185,156, 8,159,165,170,100,128,169,178, 18, 17,235,177,142,221,124, 54,107,239,229,203,143,222,124,251,245,251,122, 95, 2,
-121, 9,102,217,209, 27,104, 34,214,106, 82, 82,130, 60, 20,166,195, 39,111, 63,135,246,111, 65, 30, 82, 19,225,229, 92, 95,226,
- 75,197,197, 84,116,176,130,222, 13,249,151, 31, 33,165, 51,114, 17, 12, 44, 52,143,157,188, 35, 0, 30, 60, 1, 54,147, 63,124,
-252,246, 29,181,189, 12,100,231, 74, 8, 0, 27,200, 64,189,146, 18, 2,223,127,252, 34, 70,163,161,190, 28,164,192,133,112,223,
-127,248,182,247,224,117,103,123, 77, 96,129, 11, 52,202,223,219,112,239,129,235,144,242, 29, 88,232, 67,122, 3, 64, 17, 43,115,
- 21, 96,117, 2,172,132, 36, 37,248,129,229, 50,208,145,192,114,249,217,139,143, 16, 99,127,128, 43, 27, 32, 3,168,128, 3,169,
-191, 14,172, 30,128,102,106,169, 75, 1, 73, 96, 65, 15,148, 2,218, 5, 49, 25, 88, 1,184,216,107, 2,107, 2,160,150,188,116,
-103,172,193,242,254,253,251,207,159, 63,235,233,233, 65,154,125,159,191,254,122,250,236,197,129,189, 59,157, 92,221,164,101,228,
-191,255,248,206,195,205,206,201, 73, 84,155,236,227,135, 15, 95,191, 0,225,215,216,168,224, 27,119, 95,237, 60,112, 25, 88, 46,
-137,137,240,136, 8,241,138, 8, 1, 73, 30, 78,118,214, 95,191,255,126,251,254,243,227,231, 31,183,238,189,224,229,102,229,100,
-101,124,243,230, 13,164,223, 64, 36, 0, 8, 32,154,148,239,255,127,125,255,125,100,230,223,203, 91, 25,126,125,197,109, 51, 27,
-179,113, 24,179,130, 25, 92,224,202,227, 55, 69,139, 14, 30,185,241,244, 59,234,130,208,215,159,191,223,126,241,225,232,205,103,
-192,226,120, 66,188,131, 4,120,146,144,145, 91,136,213, 38,229,215,135, 39,255,223, 63, 70, 47,225, 31,159,251,119,255, 36,179,
- 18,246, 49, 56, 96,177,255,231,239,191, 5, 7,174,118,109, 62,243,244,221,151, 79,223, 17,235, 28,128,125, 5, 65,110,118, 53,
- 73,193, 64, 51,149, 36, 7,109, 62, 46,162,102,246, 86, 28,187,209,187,229,220,173,231,239,145,141, 66, 52,235,238,188,216,120,
-230,238,140,221,151, 10,188, 12,227,237,161,117,239,223,127,255, 14, 92,125, 2, 44,193,153, 24, 25,255,128, 22,110,178,219,104,
- 72, 29,187,245,188,125,195,169,139, 15, 95,191,250,132, 50,129,188,233,204,189, 5, 7,175,165, 58,233, 20,251, 24,179,179,162,
-196,215,209,155, 79, 39,110, 63,127,234,206, 11, 96,201,254,245,231, 31,228,113,118, 96,249, 98,175, 41, 29, 99,171,201,137,187,
-174,218,126,254,126,231,166,211, 87, 30,191,125,251, 5,203, 61, 89,167,238,190,220,114,238,222,236,125,151, 83,157,116, 11,188,
-140, 32,237, 80, 96, 13,116,250,238,203,199,111, 63,179,194, 58,158,234, 82,130, 39,239,188,168, 94,113,148,194, 93,248,192,112,
-152,189, 23,125,149,109,138,147, 14,165, 3,202,191,254, 4,247,111, 65, 14, 82,160,203, 87, 21,120,203,139, 80,109,195, 4, 29,
-172,160, 63, 0, 22,160,240,130, 30, 46, 8,108, 35,131,199, 79, 64,219,137,129,229, 53,176, 13, 14, 25, 84,241,118,215, 3, 54,
-219,103, 47, 60, 4,108,239, 3, 91,214,192,178, 21,200, 13,241, 55, 6,182,151, 33,230,224,210, 8, 44, 97,129,245,199,231, 47,
- 63,207, 95,124,116,244,228, 93,184, 69, 70,250,242,144, 33,154,107, 55,158, 63, 66,221, 15, 1, 7, 46,224,102,248,217,139,143,
-128,213, 0,208, 82, 96,125, 0,180,148,131,131, 21,104, 62,200, 46, 13, 73, 96, 73, 13,113, 60, 80, 1,176, 86,184,247,128, 1,
-220,144,127, 13, 46,205,159, 1,171, 31, 72,157,241, 30,228,102, 80, 27, 20,104, 35,196, 4,136,107,177,130, 27, 55,110,192, 55,
-145,126,253,250,235,211,199, 47, 59,182,109,210,211, 55,208,213, 53,250,241,227, 59, 23, 39, 27, 47,113, 11,243,128,173,245,183,
-239,222, 1, 11, 35, 94, 94,208,157, 54, 26,202, 98, 98, 66, 22,144, 21,225, 31, 63,125,127,255,241,219, 13, 96, 83,241,227,183,
-111, 63,126,253,255, 7, 29, 48, 96,231,226,148, 21,101,253,245,232, 17, 63, 63, 63, 43, 43,177,221,122,128, 0,162,126,249,254,
-239,205,253,223,251, 39,253,123,120,154, 1,239,206, 82, 38, 25, 3, 22,195, 96, 56,247,230,179,119, 49,147,183, 95,124,244, 6,
-151,122, 96,233,185,242,248,173,183,159,127,172,200,247, 18, 6,223,255,192, 40,174,193,162,239,255,251,192, 20,140,192,251,249,
-231,242, 38, 92,229,251,191,255, 12, 11, 15, 93,251,244,237,215,151,159,232, 11,239,126,254,249,251,226,227, 55, 32, 2, 54,135,
-129,173,218,169, 73, 78,170,120, 39,247,126,255,249,219,191,237, 92,235,250, 83, 88, 75,118, 56, 0, 90,116,225,225,235,220,249,
-251,129,213, 73,137,175, 9, 27, 11, 51,176, 68,200,158,183, 15,178,178, 27, 24,121,226, 2, 92, 6,242, 98,231,238,191,188,131,
-218, 23,134, 86, 6,255,255, 3,219,230, 77,107, 79, 2, 93, 94, 21, 96, 6,239,239, 79,217,113,161,105,237, 9,248,172, 0,138,
-195,254,254,123,254,225,235,138,227,183,246, 92,121,244,227, 23,246,221, 19,115,247, 93,169, 88,126,248,205,103,124, 55, 32,254,
-248,253,247,198,179,247,213, 43,143,222,121,249, 1, 88,179, 2, 93, 14,236,153, 0,171,132,189,151, 31, 65, 59, 82,140, 12,192,
-246, 53,208, 95,148,175, 15, 89,114,248, 58, 90, 13, 33, 41,192, 29,108,174, 74,161,177,201, 51,119,163,141,249, 76, 73,116,164,
-238,129, 7,116,176,130,254,160,174,220,247,236,133,135, 91,119, 94, 2, 22,208,144, 1, 13, 72,163, 24, 94,226, 43, 34,141, 96,
- 0, 27,197,156, 28,172,130, 2,220,192,242, 29, 26,119, 18,252,104,195,226, 88, 53, 2, 11,119, 37, 5, 81, 72,153, 11, 31,159,
- 89,188,242, 4,188, 9,204, 65,220,248, 36,208,124,228, 41, 89, 96,253,177,102,227, 89, 96, 3, 31,216,162,223,123,240, 6, 86,
- 45,112,147,137,108,110,131,199, 76,254, 1, 11, 86, 9, 9, 9,112, 1,205,240,246,221,135, 61,123,118, 8,240,241, 90, 90,219,
-255,252,249,147,141,141,133,143,151,168,194, 29,152,229, 31, 63,122,196,198,198,246,242,229, 75, 99, 99,208, 66,190,175,223,126,
- 93,188,246,228,227,151,239, 95,191,252,252, 7,218,250,243, 31,122, 83,233,127,208, 18, 66,200, 72,196,207,111,223,159,191,103,
- 17,230,252,253,244,233, 83, 5, 5, 5, 34,221, 12, 16, 64,212, 44,223,129,238,254,119,231, 48,176,192,253,255,225, 9, 1,165,
-172, 92,204,234,206,140, 44,236,112,141, 85, 43,142,226, 41,220, 17,205,138, 43,143, 90,214,157,236,143,119, 96,128,172,179, 87,
-180, 96,188,186,253,255,235,187, 24,227,254, 87, 25, 62, 62,101,224,151,198, 62, 76,140,116, 84, 33,164,180,252,255, 31,101,156,
- 26,216,129,216,125,249, 17, 48,223,174,204,247,146,196, 54, 62, 0, 41,221, 86,157,184, 85,187,242,216, 47,164, 94,185, 16, 55,
-187,147,142,156,137,146, 56, 23, 59,203,163, 55,159,183,158,191,127,253, 41,116, 65,200,231, 31,191, 27,215,156, 80, 18,231,143,
-176,210, 96,100, 96,252,241,251, 15,188, 76,252,248,253,215,237,231, 31, 32, 14, 96, 4, 57, 9,220, 82, 6, 86,143,255, 81,234,
-158,153,123, 46,185,235,203,155, 42,131,146,215,156,125,151,203,151, 29,198,156, 56, 69,243, 14,174,226, 27,216,114, 71, 43,220,
-217,152,153, 28,180,101, 93,116,228, 4,184,217,159,189,255,178,245,220,253,115,247, 95,253, 5, 55, 28,128,165,252,172, 61,151,
-165, 5,121,170,131,204,129,110, 3, 86, 78, 31,145,234,179,247, 95,127,162,217, 78, 6,248,249,251, 79,219,134, 83,104,130,133,
-222, 70,200, 11,159,200, 0, 64, 51,215,158,188,141, 44,146,239,105, 72,221,155, 67,232, 96,197,128, 0, 96,153,251,252,197, 71,
-180, 18, 22,216,230,125,254,226, 3,100, 88, 28,216,236,189,255,240,205,119,140,221, 9,144,193, 16, 96,221, 0, 44,187,225, 3,
-226,196,104, 68,212, 22,252, 92, 64,141,192,198, 53,100,173,139,152, 8, 47,120,168,250, 55,188,158,192, 4, 2, 2, 92,192,202,
- 3, 88, 85, 64, 20, 0, 91,190, 64, 27,129, 13,124,100, 91,144,245, 2, 29, 9, 52, 25, 40, 11,116, 18,100, 16,255, 61, 17,219,
-232, 62,125,250,196,194,194,242,241,227,199,187,119,239,253,249,195,248,242,229,171,223, 63,190,187,123,249,253,251,247, 31,216,
-155, 21,224,231,196, 51, 38,140, 50, 32,241,234, 21, 43, 27,219,139, 23, 47,180,180,180, 32,165,223,177, 51,119, 95,188,254,136,
- 40,211,225, 37, 59,180, 56, 99,100, 96, 2,231,196,175,223, 94,254, 96,254,247,247, 33,241,229, 59, 64, 0, 81,241,124,224, 31,
-127,206, 44,255,115, 98, 33,150, 59,152, 48,203, 71, 30, 17, 38,121, 19, 56, 23,216, 88, 62,116,253, 9, 81,182, 0,171,247,195,
-215,211, 93,244, 52,164,133, 64,230, 8, 43, 48, 73,106,255,197, 40,223, 25,126,124,250,115,239, 4,114,255, 0, 19,136,243,115,
-249, 25, 43,153,169, 72,112,178,177, 0, 91,160,219, 47, 60, 56,126,235,249, 79,164,195,202, 15,223,120, 10,172, 75,166, 36, 57,
- 97, 78,145,177, 48, 49, 61,123,247, 5, 40,139, 92,184, 27, 41,136, 77, 77,118, 50, 87,145,128, 71,115,145,183, 81,209,162,131,
-192,106, 0, 82, 82, 3, 21,119,110, 60, 99,167, 33, 35,204,203,129, 54,177,254, 31, 92,194, 26, 42,138, 5,152, 40,235,202,137,
- 0,139,209, 43,143,223,206, 63,120, 21, 94, 61,128, 6,121,223,125, 57,123,239, 37,176,124, 7,246,117,234, 86, 29, 71, 46,220,
-129,246,201, 8,243,120,232, 43, 0,101, 57, 88,153,129, 42,119, 92,120,112,242,206,139,159, 24,103,175, 51, 51, 49,253,249,251,
-175,121,221, 73,228,194, 93,144,155,189, 37,220, 58,195, 69, 15,238,211, 50, 63,211,234, 21, 71, 39,239, 56,255, 7,236,116, 96,
- 65,191,232,240, 53,111, 35, 69, 3, 5, 49,102,108,165, 56,176, 98,115,214,149, 51, 83,150, 96,101, 38,231, 68,163, 73, 59, 46,
-160, 45, 90,149, 22,226, 73,119,214,165, 36, 65,110, 60,115, 23, 88,161, 34,139,184,235,201,119, 68,218, 80,177, 16,164,131, 21,
- 3, 5,224,171,104, 32,227,224, 16,182,183,187, 46,176, 93, 12,108, 29, 3, 17,164,232, 7, 22,163,104, 26, 57,193,130,104,235,
-112,136,209,136,152,116,177, 80, 89,188,242,248,164,153,123, 33,131,248,118,214,106, 23,175, 60,158,189,240, 16,158,242, 29, 88,
- 25, 0,187, 26,160, 1, 25,240, 58, 75, 69,121,145,163, 39,238,204, 94,120,248,253,135,175,240,142, 2,176, 35, 2,236, 25, 64,
-134,239,141, 13,228,175,221,124, 62,121,230, 94, 72,237,229,227,174,183,101,231, 37, 98,218,175,247,238,221,123,245,234,213,131,
- 7,143,213,212,181,128,173, 89,126, 65,161, 63,192,150, 60,195,127,126,126,208,162, 23,162, 70,243,190,127,251,254,253,251,159,
-191,127,197,196,196,184,184, 64,125,142,155,119, 95,190,120,245, 17,102, 5, 18,249, 15,218,114, 7, 54,231, 65,108, 38, 6, 38,
-102,230,219,183,175,112,106,171, 17, 31,143, 0, 1, 68,157,242,253,223,135,103,127, 14, 77,251,123,115, 31,145,234, 25,249, 37,
-153,248, 17,235,222,246, 95,125,140,127,160, 0,101,184,227,199,239,221,151, 30, 67,203,119, 70, 38, 38, 81, 21, 44, 3, 16,127,
-126,254,187,125,136,193, 32, 16, 20, 42,216,128,177,162,216,220, 12, 55,125,121, 68, 87, 17, 88,162,245,111, 61, 91,191,250,248,
-103,164, 52,180,227,226,195, 91,207,223, 99, 14, 97, 3,203,184,125, 87, 31,223,120,246, 30,121,200,181, 45,210,218, 66, 85, 18,
-114,177, 22, 52, 85, 9,242,212,135, 88,158,127,240,250, 38,236, 16,149, 11, 15, 95, 3,139, 93, 95, 99, 37,180, 50, 18, 88, 40,
-215, 5, 91,148,251,153,194, 75, 88, 79, 67, 69, 23, 93, 57,183,182,181,200, 33,115,255,213, 39, 32, 57,107,239,229, 87, 72,205,
- 13,102, 70, 70, 96,201,219, 21,109,171, 46, 37, 4, 23, 44,241, 49,158,184,253,124,205,202, 99,104, 69, 60,208, 47,251, 65, 46,
-127,135, 92, 55, 4,154,170,100,185,233, 35,187, 28,168,172, 39,198, 14, 88,233,158,189,255, 10, 34,114,235,249,135,157, 23, 31,
-130,203,119,244, 32, 85, 20,229,155,153,234,226,170, 71,230,154, 54, 96, 71, 7,179,241,222, 24, 98, 73,234, 44, 55, 50,184,242,
-248, 77,226,244, 93,200, 34,154,210, 66, 75,114, 60,168,184,154,133, 14, 86,208, 31, 0,203,211, 24,164,117, 44,144,245,239,192,
- 22, 55,176,124,132, 44, 75,207, 75,119,126,246,226, 3,164,156, 5,182,151, 65,108,115,101, 72, 97,237,108,175, 1, 97,107,105,
- 72, 65,134, 92,128, 90,128, 37, 44, 65,141,104,150, 66, 20, 3, 77, 0, 22,190, 82, 96, 5,185,233,206,192,130, 27,104,206,247,
- 31,191, 56, 57,216,128,226,112,245, 64, 75,129, 34, 64, 45,146, 18,252,144,250, 0,168, 18,168, 43, 53,222, 14, 98, 53, 68, 11,
- 80, 1,208, 16,160, 8, 80, 1,208, 47,144,225, 32,136,123, 32, 75,101, 32,230, 96, 58, 6, 25, 60,126,252, 88, 89, 89,153,141,
-149, 77, 82, 74, 81, 88, 88,244,233,147,199,119,238,222,252,250,245,147,156,156, 20, 43, 43, 81, 29,205,127,255,254, 61,125,242,
-148,135,151,247,253,139, 23, 6, 6, 6, 64,145, 15,159,190,159,189,244, 8, 94,184,131, 10,116, 70,196,192,246,127,216, 2, 56,
-160, 56,176, 13,255,237,219,231,239, 95, 63,127,254,193,114,255,209, 27, 69,226, 86,169, 1, 4, 16,197,231,139, 1,171,150,135,
-103,126, 31,152,252,255,245, 29,226,117, 49,242,162, 44, 63, 34,105,195, 17,176,249,121,255, 21, 98,156,154,145, 91, 8,180, 7,
- 10, 99, 83,235,255,207,175, 24,190,189, 99,224,198, 18, 10,192,230,234,228, 68, 71,228,194, 29, 54, 32, 96,124,237,201,187,121,
- 7,174,192, 7, 70, 30,189,249,116,232,250, 83, 7, 45, 25,228,142, 23,176,121,254,235,207,223, 3,215, 30,163,153,121,236,214,
- 51, 96, 63,224, 7, 98,114,248, 63,176,208,255,252,253, 55,218,114,251,125, 87, 31,185,235,203,163,117,229, 66,204, 85,129,141,
-125,180,162, 1, 88,135,249, 25, 43,207, 59,112, 21, 46, 2,180,247,231,239, 63, 7,175, 61,249,139,180, 70,211, 72, 81,108, 70,
-138, 51,218, 56, 18, 43, 11,115,137,175, 9,176,114,154,189,239, 10,114,181,196,206,202,124,244,230,179, 79, 72,187,231,129, 61,
- 9,160,163,151, 28,190,254, 9, 50, 94, 4,115, 24, 11, 19, 35, 7,234,116,238,217,251, 47,129,129,207,129,154,148,185,217, 89,
-218, 35,109,200, 46,220,129, 32,111,193,254,111, 63, 81, 6,154,128,125,160, 24, 91,242, 79,126,126,243,249,123,112,223,150,175,
- 72,243, 43,192,216, 89, 91,228, 67,228,132,249, 32,177, 98, 64, 0,176, 52,199, 92, 26, 8, 94,146,136, 24,221,150, 66,106,122,
-227, 98,195, 13, 33, 70, 35, 86, 75,145, 69,224, 10, 4, 97,167,181,192,101,225,230,192, 25, 80,149, 48, 55,195,181,192, 69, 48,
-245, 34,179,177, 58,134, 1,124,221,210,183,111,223, 44, 44, 44,126,254,252,243,227,231,255,159, 63,127,200,200,202,188,122,245,
-252,199,247, 47,236,108,196,142, 34, 62,126,244,144,143,159, 31,216, 9, 48, 49, 1,141, 94,252,253,251,239,232,169, 59,192, 66,
- 31,114, 68, 11, 52,231,193, 74,121,232, 25, 92,255,161,195,173, 44, 44, 44, 79,110,223,145,148, 81, 0,138, 93,189,249,140,200,
-242, 29, 32,128, 40, 42,223,255,255,250,246,247,242, 86,208,165,169, 63, 73, 92, 59,193,202, 65, 81, 50,100, 68,154,185,101,102,
- 99, 96,194,230,139, 63, 63, 17,229,251,127,148,114,211, 82, 85,210, 82, 13,251,244, 87,172,157,230,170, 19,183,224,243,165,127,
-254,253,191,251,242,131,147,182, 44,242,160, 4,144, 5,204,216,119, 81,231, 66, 95,125,250,222,180,246, 36, 49,110,191,253,252,
-195,247, 95,127,144,139,119, 54,102, 38, 55, 61,121,180,181, 49,144, 62,129, 42,106, 55, 22, 88, 58,223,124,246,254, 13,210,156,
- 42,176,241, 14,172, 45, 36,113, 44, 34, 76,113,210,157,127,224,234, 31, 88,125, 5,169, 84,238,189,250,136, 92, 61,252,254,251,
- 15,232,101, 32, 34,232,242,231,239,191, 2,251, 13,104, 35, 48,234,146, 66,161, 22,106,100,199,228,178, 35, 55,182, 95,120,128,
- 58,133,192, 8,172,125,137, 28,202,196, 4,191,255,252,141,152,184,237,193,235, 79,200,181,218,138,124, 47,101,113,170,221, 6,
- 67, 7, 43, 70,193, 96, 3,183,111,223,134, 20,202, 76,204,204,255,254,125,227,229, 97,103,102,225,146,144, 16, 99, 97,102,252,
-251,247, 47, 49, 87, 96,191,125,243,134,149, 21, 52,236,174,164,164, 4, 44,172,129, 34, 23,175, 61,121,251,225, 43,168, 64,103,
-250, 15, 29,165,133, 23, 49, 72, 36, 35,248, 8,201,143, 31,222,252,251,255, 79, 72, 72,252,207,159, 63,178,210,196, 30, 33, 5,
- 16, 64,228,159,255,254,239,227,243,223,251, 39,255,222,215,143,179,112,103, 98,102,224, 22,198, 46,133,170, 69, 70,136,135,248,
-220, 12,204,248, 74, 98, 72, 25,233,247, 55,134, 63, 63,176,117, 44,254, 97, 61,169, 6, 8,180,100,132,113, 25,174, 36,198,143,
- 54, 26,243,225, 43,232,216, 69,228, 65, 9, 96,209, 3, 44, 19, 63,145,123,128, 20,176,120, 5, 26,200,136,116, 60,166, 16, 15,
- 7,214,213,241, 64,159,162,141, 81, 0,203,214,143,223, 64,219, 2,224, 34, 60, 28,172,120,118,240, 75, 11,241, 8, 33, 45,216,
- 2, 26, 8,236,111,125,251, 73,230,137, 93, 47, 62,124,253,240,237, 39,242,204, 1, 35,184,247, 64,246,136, 4,176,182, 40, 94,
-114, 8,189, 57,239, 97,128,217,181, 34, 30, 20, 44, 58,120,248,198, 83,100,145,137,241, 14, 14, 90,178, 84,204,234,116,176, 98,
- 4,130,239, 63,126,223, 67, 93,134, 4,228,126, 39,229,116, 57, 82,213, 19, 15, 94,191,126,205,203,203, 11,185, 26,251,215, 47,
-208,254,150,151,175, 63,223,121,240,246,237,199,191,191,126,255,127,245,242, 37,158,225, 13, 96,113, 12,108,248, 3, 11,247,159,
- 63, 65,247,123, 0, 13, 17, 19, 3,237,101,121,246,242, 35,176, 25, 14, 26,120, 1, 15,200,128,215, 65, 34, 70,222, 65, 67, 52,
-255, 97, 3, 53,160,230, 60,227,147, 71,247,164,164, 21,255,253,255,207,201,201,170, 73,244, 17,129, 0, 1, 68,102,251,253,239,
-227,243,127, 14,207,250,247,244, 34,238, 22, 58, 39,171,109,250,191, 15, 79,254,158, 91,131,197,219, 31, 95, 0,203, 95, 70,216,
-224,184,135,129,194,188, 3, 87,241,175, 50,132, 3, 94, 78, 54,119,125, 5,100,163, 24,254,226,136, 84,108,131,239,140,224, 22,
- 43,206, 74, 11,105, 12, 26,222, 52, 3, 34, 12, 65, 38, 14,212, 78, 25, 47, 7, 43,176, 48,101, 97, 98, 66, 59, 21, 22,178,140,
- 16,174, 29, 72, 41,136,242, 49,194, 23, 64, 33, 53,171,113, 12,216,161,152,246, 31, 67, 49,208,186,191,255,254,227,209,142,233,
- 89,180, 69, 41, 44, 76,140,178,194,192,196,203,134,118, 55, 30,196, 34,184,203,255,252,251,167, 33, 37, 4,244, 32,178,117,192,
-182,182, 16, 15,249, 93,177,130,133, 7,208, 14, 20,147, 23,225,173, 15,177, 32,219,192,233,187, 47,206,217,135,114, 54, 81,166,
-171, 94, 42,101,243,180,244,183, 98,100, 2,204,147, 3,128,220,152,112, 11,226,207,138, 33, 85, 61,241,224,250,245,235,144, 61,
- 77, 95,191,253,190,113, 27,116, 47, 54,100,117,176,144,144,240,135,119, 79, 69,127,254, 2, 54,225,153,152,152, 32, 51, 88,127,
-254,252,254,254,253,199,183,175, 95,129,121, 19,168,236,227,199,143,159, 62,127,102,101,101,213,213,213,189,116,233,146,184,184,
- 56, 3,104, 73,254,159,227,103,238, 66,178,244,127,164,178,234, 63,116,168, 6,156,251,192,133, 4, 80,132,133,149,245,249,179,
- 7,156, 92,220,160, 99,200,126,255,210, 82,149,102, 35,122,106, 10, 32,128,200, 41,223,255, 92, 88,255,231,228,226,255,184, 79,
-130,100,224, 17, 97,181,207, 97,209,114,251,125, 96, 42,246,106,237,211,139,255,111, 31, 50,138, 64,239,124,112,208,146,113,209,
-149, 91,119,138,168, 17,252,120, 59, 45, 85, 73, 1,216, 0,209,119,208,137,146,216,203,118, 22, 6, 54,110,148,254, 14,172,136,
- 60,123, 15,103,125,123,245,241, 91,180,177, 96, 81, 62, 46, 96,139, 30,185,236, 3, 70, 27, 23, 27, 11,218,190, 74, 77,105,161,
-214, 8,107, 49, 62, 46,180,242, 29, 88,152, 2,181, 3, 27,236, 16, 19, 32, 27,101,121, 57, 89,145, 11,110,140, 58, 5, 39,248,
-245,231,175,148, 32, 55,242, 8, 9,208,181,151, 31,227, 92, 87,122,231,229,135, 15, 72,235, 23,129,150, 2, 75,100, 73, 65,148,
- 83, 36,121, 56,216, 10,189,141, 28,181,101,209,202,119, 96, 29, 6,172,180,190,192, 92, 14, 44,214,249, 56,217,128,117,216,103,
-212,106,152,220,113, 20,134, 13,167,239,174,197,136,241, 73,137,142,100, 31, 79,127,224,218,227,226,197, 40,189, 1, 39,109,217,
-158, 24, 59, 42,230,115, 58, 88, 49,228,192,251, 15,223,190,255,248, 37, 37, 33,240, 30,188,248, 93, 80,128,235, 25,104, 41, 36,
- 27,166, 32, 3,120, 1, 12,176,252, 5,182,178,223,127,248, 10,145,133, 40, 67,110,131, 63,127,249,145,131,157, 21,249, 8, 26,
-200,225, 1,130,252, 92,144,153, 91, 14, 14,214,251, 15, 65,105,222, 72, 95, 30,188,192,241, 53,242, 38, 44,200, 89, 5, 12,224,
- 85, 52, 64,147,129,178,144, 73, 87,200, 52, 47, 92, 22,190,244, 30, 46, 11,116, 18,196, 28,160, 20,100, 98, 25,145,139,217,216,
- 4, 4, 4,128,185,244,233,243,247,144,229,203,224, 34,229, 63,176,204,189,127,255, 43, 11, 43,203,149, 43,151, 57, 57,185, 88,
-152, 65,167, 11,252,252,245,235, 59, 24, 48,130, 79,251, 5,234,149,150,150, 6,182,226, 79,157, 58,101, 99, 99,179,119,239, 94,
- 17, 17,209, 75, 55,223,124,253,246, 11, 50,206,206,248, 31,126, 66, 58, 80, 3,116,169, 12,164,224, 7, 47,145,100,250,254,253,
-203,171, 23,143,117,245,172,254,252,254,205,205,205,174,166, 44, 78,124,236, 0, 4, 16,105,229,251,255, 31,159,126, 31,157,251,
-247,242,102,232, 81,192, 88, 11, 86, 49, 53, 86,231, 66,102, 25,125, 6,148, 33, 37, 84,115,190,188,254,123,231, 48, 19,172,124,
-103,103,101,233,140,178,189,255,234,227,121,108,103, 3, 33, 3, 23, 29,185,234, 64,115, 68,129,245,250,206,223, 71,103,113,248,
-140,141,129, 71, 20,169, 84, 71,128,243, 15, 94,173, 63,117, 39,208, 12,203, 73,194,179,246, 94,254,246, 11,209, 27, 0,150,227,
-192,130,251,207, 95,148,165,232,192, 40,228, 96, 99, 49, 87,145, 88,131,180,240,249,222,171,143,146, 2,220,218,178,232,147, 30,
-223,126,254, 62,116,253,169, 7,234,213,116, 95,127,252, 38,239,234,135,239,191,254,200,137,240,201, 8,243,222,135, 13,254,254,
-253,255,127,219,249,251,233,206,122,106, 82,130,152,141,247,254,173,231,144, 45,250, 11,110,206, 27, 43,138, 3,253, 5, 95, 94,
- 9,116, 33,176, 14,208,145,197, 50, 93, 3, 52, 25,237,222, 37,204, 14, 1,121,151, 88,188,255,250, 35,111,193,126, 52,193, 80,
- 11, 85, 15,125, 5,178, 71,189, 34, 39,109, 71,238, 91,240,115,177, 21,251, 24, 95,124, 72, 32, 69,161,245, 26,127,252,250,139,
- 92,253,107,203, 8,195,135,200,232, 96,197, 80, 4,192, 34,114,239,193,235,101,249, 30,144,141,254, 33,254,198,160,173,255,246,
-154, 88, 5,183,238,188,148, 18,111, 11, 44,157,143,158,184, 3,145, 5, 22,229, 82, 30,136,242,253,232,201,187,144,181,140,112,
-145,197,224,211, 14,192, 75, 30, 47, 1, 75,103,160, 9,192,242,221,218, 66, 5,104,194,251,247,223,180, 52, 36,129, 38, 3, 11,
-122,104,216,254,248, 61,121,230, 94, 96,193, 13, 58,120,224,192,225,220,116,103,160, 44,100, 57, 38,228,156, 25,200,170, 77,160,
-105, 64, 6,208, 85,107, 54,158,133,200,138,137,240,158, 60,115, 15, 98, 14,208,118,180,126, 0,100, 79,211,215,239,127,190, 2,
- 91, 75,140,136,115,157,254,255,251, 39, 36, 36,118,252,196, 73, 85, 21,229,247,239,223, 51, 51, 51,115,112,112, 8,130, 1,232,
- 80, 48, 78, 78, 30, 30, 30,248,208, 60,176,136, 7,182,223,109,109,109, 23, 46, 89,205, 45,164,193, 4, 27, 21,128, 44,155,129,
- 48, 33,147,171,240,245, 51,204, 76, 64,200,252,224,218,117,121, 69, 13, 70,102,166,127,127,254,152,234, 43,176,146,178, 41, 4,
- 32,128, 72, 72, 88,255,222, 63,249,189,187,235,223,195, 51,248,134,243, 85,108, 89, 29,243,152, 4,160, 27,139, 24, 65, 12, 70,
- 44,165,252,191,191,127,111,237,103,214,112, 97, 18,128,206,115,170, 72, 8, 44,201,241, 44, 94,124,112, 7,238,205,193, 49, 54,
- 26,109, 17, 54, 34,124,156,208,146,229,207,207,191, 55,118, 51,124,255,128,189,154, 17, 85,101, 96,231,197, 42,245,245,231,159,
-194, 69, 7,128,109,225,112, 43,117,228,177,224,134, 53,199,183,158,191,143, 92,148, 43,139,243,123, 26, 40,220,126,241, 1,115,
- 88, 13, 40,222,184,230, 4,124, 19,236,155,207, 63,170, 86, 28,157,149,234, 34,142,116,198, 58,176, 56, 6, 54,247, 86,159,184,
-101,165, 38, 85, 25, 96, 10,159,212,253,207, 64,230,205, 62,191,255,252, 99, 97,102, 10, 50, 83, 57,126,235, 25,124,214,244,230,
-179,247,209, 83,182,215, 6,153,251,153, 32,174,223,125,242,246,115,235,250, 83,152,151,151, 2,139,117, 95, 99, 37, 96, 19, 30,
- 62, 63,252,235,239,191,217,251, 46, 91,168, 74,162,173,129,169, 89,121,116,250,174,139, 6, 10, 98, 69,222, 70,222, 70, 74,112,
-151, 51, 82, 99,249, 95,201,146, 67,104, 23, 51, 9,112,177,247,198,218,147,103, 26,176, 75, 17,212,187, 25,109,168,231,227,183,
- 95,222,157, 27, 72, 53,234,209,219,207, 86,117, 43,225,220,115,237,209,218,178,194,244,177, 98,136, 2, 96, 57, 8, 44,115,129,
- 45,113, 96, 65, 15, 44, 94,223,219,107, 66, 26,233, 88, 5, 65, 27,145, 94,124, 4, 34, 32,247,218,141,103, 64, 5, 70,250, 40,
-231,199, 65,118,177,130,100,193,103, 6, 0, 27,212,247, 31,188,246,118,215, 3, 54,189, 63,124,132, 30, 36, 0, 44,151, 33,133,
-239,189, 7,111,206, 93,124, 4, 44,148,125, 60, 64,131, 39,192,134, 57,100,155, 18,196,204,123, 15, 95, 67,142, 33,243, 1, 31,
-159,192, 0, 62, 61, 24,216, 84, 7, 22,250, 64,211,224, 86, 64,100,129, 5, 61,178, 57,232,197, 26,120,250,237,221,187,111,200,
-203, 90, 64,243,112,191,127, 63,184,119,251, 63,195,111, 77, 77, 45,102,102, 38,200,172, 41, 46,160,170,170,122,243,230,173, 15,
- 31, 62,137, 74,105,158, 63,127, 86, 93,211,232,239,223,223,144, 70, 58, 3,172,136,135,140,210, 48, 1,219,253,204,204,127,255,
-252,121,247,238,229,235, 87,207,248, 4,132, 4, 4, 69,129,141,119, 57, 25, 33, 89, 41,210,142,203, 6, 8, 32, 98,203,247,255,
- 95,223,253,222,213,245,239, 17,190,194,157,217, 56,140,213, 50,137,145, 19,113,236, 6,163,160, 12,104,138,245, 43,150, 1,132,
-255,175,110,255, 57,187,138,205,185, 0, 46,162, 37, 35, 12, 44,226,215,157,186,179,226,216,205, 83,119, 94,192,139, 78,126, 78,
- 54, 27, 13,233,120,123, 45, 55, 61,121,126,164,245,103,255,238,157,248,123,105, 19,118,167,176,113, 51,171, 59,226,113,234,195,
- 55,159,211,103,239,153,190,251,162,145,162, 56, 47, 39,235,195,215,159, 79,220,126,126,231,197, 7,228,133, 37, 28,172,204, 9,
-246,160, 83,104,126, 98, 92,144,248,231,239, 63, 53, 73,193,108,119,253,206, 77,136, 0,217,114,238,158,111,215, 70,127, 19,101,
- 19,101,113,118, 22,230,155,207,223, 3,253,178,255,234, 99, 96,131,119,243,185,123, 39,239, 60, 15, 50, 83,173, 15,177,144,160,
-236,146,141, 31,191,254,164, 58,233, 46, 57,124, 29,190, 50, 29,232,226, 51,247, 94, 38, 76,223,169, 39, 39, 2,244, 14, 15,176,
-247,250,234,227,241,219,207, 31,188,250,244, 23,163,117,253,251,207, 95, 94, 78,182, 76, 87,253,170,229, 71,224,155,179, 30,191,
-253,146, 56,125, 39,176,182,115,210,150,229,102,103, 5, 22, 64,107, 79,222,222,117,233,225,143,223,127,247, 93,125,124,225,193,
- 43, 96, 43,190, 54,200, 66, 77,138, 58, 71,177, 3, 77, 94,114, 24,125,215,120,123,164,181, 56, 63,153,167,126,159,186,251, 2,
-121, 35, 24, 45, 0, 29,172, 24,162, 0, 88, 86, 2, 75,237,179, 23, 30, 66,202, 92, 96,179, 90, 0,188, 18, 17,171,160,146,188,
- 40,164,208,119,118,208,132,108, 71, 82,242,199,114,211,142,160, 32,116, 67, 41,100,173, 58,164, 32,134,112,209,142,255,253, 14,
- 90,243,142,126, 82, 35,228, 40, 27, 65, 1,110,200,102, 90,248, 22, 92,200,234,123,232,186, 73, 65, 46,200,246, 90,136, 44, 86,
-115,144, 6, 33,153, 62,127,249,246,249,203,119,232,200, 12, 56, 87,177,178,177, 93,189,122,225,221,187, 55, 38,102,150,255, 25,
-152, 89,176, 53,171,255,254,253, 7, 62, 35,236,215, 23, 96,163,242, 31,211, 63, 70,206, 87,175, 94,200,136,177, 63, 21,147,122,
-112,239,186,162,178,214,239, 95,191, 96,171, 33,129, 13,116, 38, 38, 22,230, 63,191,129,138, 63, 0,139,245,223,191,127,177,179,
-113, 72, 74, 41,240,241, 11,253,253,243,155,131,157,197,132,244, 85,200, 0, 1, 68,108,249, 14, 44,139,255, 61, 57,143, 83,154,
-149,139,213, 54,157, 89,223, 15,126,228, 0,180,222, 19, 85,101, 18,146,253,135,173,124, 7,118, 66,254, 94, 92,255, 71, 80,134,
-217, 48, 24, 62,103, 40,204,203,153,236,168, 19,105,173,254,242,195, 55, 96, 41,243,245,199,111, 62, 46, 54,121, 17, 62, 17, 94,
- 78,180,147,114,255, 61,187,242,123,255, 68, 92,123,101,209,246,199, 98, 5, 31,191,255, 58,120,253,233,145, 27,160, 41,236,191,
- 24,119,101, 50, 51, 50,198,217,105,229,120, 24, 96,239,202,252,255, 15,236, 37, 21,122, 25,221,122,254,126,253,233,187, 48, 65,
-134,211,247, 94, 94,120,248,154,141,133,137,145,129,241,207,191,127, 72,107,225, 25, 94,125,250, 6, 44,118,255,253,163,244, 78,
- 78,160,213,192,160,152,154,228, 20,210,191, 5,249,192,150,247, 95,127,194,189,243,135,144, 45,121, 30, 6, 55,158,162,172,244,
-127,250,254,235,196,109,231,103,238,185, 4,116,249,223,127,255,144,143,120,123,247,245,231,149,199,111,169,181,109, 7,216, 16,
-206,154,187, 23, 77,208, 70, 93, 42,113,232,239,233, 31,177, 0, 88,106, 31, 59,121, 7,216,202, 6, 13,110, 28,188, 14, 57, 71,
- 12,171, 32,176, 12, 5,182,235,129, 45,101, 32,119,246,194, 67,144, 66, 31, 50, 94,143, 58,230, 3, 58, 51,224, 62,120,112,159,
- 1,180, 61, 21,122, 96, 47,100,251, 43, 74, 77,128,116,152, 1, 3,236,116, 4, 96, 3,159,147,131, 21,249,218, 16,200, 64,191,
- 32,184,105,117, 15,116, 36,189, 40,220, 10, 8,128, 28, 84, 0, 55, 7, 13,124,249,242,249, 31, 3,235,127,164,227,182,129,197,
-249,235, 87, 47, 31, 61,184, 39, 45, 45, 39, 42, 42,249,234,245, 71, 25, 41, 65,208,145,200, 63,255,124, 7,150,230,223,127,126,
-251,246,243,251, 79, 96,233,253,247, 23,176, 96,135,101, 51, 46, 30, 30, 41, 17, 62, 14,142, 95, 6, 58, 10, 7,142,188,123,250,
-228,158,140,172,202, 63,240,229,124,191,126,255,252,252,237,203,219,215, 47,190,126,254, 8,108,176,243, 11, 8, 3, 17, 27, 43,
-251, 95, 32, 0,109,145,101, 48,212,145,227, 33,253, 46, 51,128, 0, 34,186,124,191,186,157,225, 31,246,147,170, 24,249,164, 88,
- 93, 10,153,148,172, 48,215,129, 48,114, 9, 48,201, 25,255,123,140, 90, 49,192,239,206,254,251,251,247,193,169, 12,255,255, 50,
-235, 7, 50,178,176,193,186, 66,140, 60, 28,108, 60, 18,108,202, 56,118, 48, 3,235,133,127, 79, 46,254,222,217,129,123,130, 23,
-124, 46, 13, 59, 15,114,163, 21, 89, 90, 71, 70,248,195,183,159,144,194,241,239,127,244,193, 18, 96, 57,198,203,193,150,238,162,
-215, 24,106, 9, 89,106, 2, 44,239,144,231, 30,225,205,121,113, 1,238,153,169, 46,162,124, 92, 75,143, 92,135, 31,223, 8,108,
-173, 99, 46, 89,225,102,103,137,178,214,104, 10,179,130, 55, 81,127,129,156, 4, 13, 8, 96,252,227,186,139, 25,109,109,204, 95,
-152, 66,115, 85,201, 85, 5,222,133,139, 14,158,191,255, 10,249,140, 4,100,239, 0,251, 16,106,146, 2,247, 95,125,130,247,132,
-126,255,133,166, 52, 96,229, 52, 37,201, 81, 92,128,107,234,206,139,159,190,255,132, 8, 2,245,126,253,137,126,160, 13, 23, 27,
-139,183,145, 98,123,132,141, 18,184, 37, 5, 52,254,247, 31, 20,235, 72,189,202,170,106,197, 81, 96,119, 1,165,109,192,204, 52,
- 53,217,137,145,145,113,180,160, 28,162, 0,212,242,189,200, 0, 25, 3,217, 10, 62,176, 23,151, 32,164,152, 86, 82, 16,129, 28,
-227, 14,105,158,239, 61,120, 3, 40, 2, 97, 79,154,185, 23,210,208,246,113,215, 59,119, 17,116,218, 59,176,165, 15,185,253, 3,
-235,189, 75, 70, 6,114, 64,217,217, 11, 15, 67,206, 34, 6,111,100, 21,152, 60,115, 47,144,188, 15,238, 37, 64,148, 93,187,249,
- 12,114,191, 7,176,106, 89,179,241, 44,100, 54,213,217, 94, 3, 62, 20, 99,164, 47, 7, 20,135,155,131, 62,239,245,253, 59, 35,
-243, 15, 70, 38, 78,104,251, 29, 60,242,126,235,230, 85, 96, 19, 94, 85, 77, 19,200,225,227,229, 56,115,225,193,187, 15,223, 64,
- 43,102,208, 50, 4,210, 34,190,111, 95,190,188,231, 16,148, 16, 98, 22,228,253,101,110,106,120,228,200,241, 39,255,111,179,176,
-176,126,250,248,238,251,247,111, 2, 66, 34,252, 2, 66,114, 10,170,172,172,236, 64,243,129,224,207, 31,104,206, 85,148, 19, 86,
- 85, 18, 35, 35,106, 0, 2,136,232,241,247,255,216, 11,119, 38, 25, 3, 86,231, 34,172,183,158, 66, 43, 58, 29,175,191,247,142,
-255,127,126, 21,169,248, 69,174, 55,126,254,222, 55,241,223,235,123, 44,230, 49,140,124,146,140,204, 4,220,243,255,219,251,191,
-215,118,254, 62, 62,159,225, 7,238, 45,175,156,124, 44,122, 40,247,179,200,139,242,105, 74, 11,129,111,167, 3, 21, 35,153,174,
-250,198, 74, 98,205,107, 79,158,188,243,226,219,207,223,127,192,133, 38, 51, 19, 35,176, 52, 23,229,227,116,213,149,143,176, 82,
-183, 66, 58,255,143,151,147, 77, 87, 78,132,139,157,133,131,149,229,255,255,255,210, 66, 60,240,229,240,192,194, 29, 88,196,135,
- 89,168,205,217,119,249,196,157, 23,192,198, 41,176,224,134,148,193, 64,187,128, 6, 2,245, 90,168, 72,164, 58,235, 58,233,200,
- 33, 85, 33,140, 6,242, 98, 66,220, 28,144,173,176, 82,130, 60, 2, 56,246, 61, 74, 10,114, 43,137,241,243,129, 47,247,250,244,
-253,151,130, 40, 63,188, 29,109,169, 38,181,163, 50,112,246,222, 43,235, 78,221,190,255,250,211,143, 95,127, 32, 30, 1, 26,206,
-206,202, 44, 41,192, 29, 99,171, 25,104,170, 82,176,232,192,227, 55,159, 89,152,153,126,254,249,171, 32,202,199, 3,235, 6,177,
-179,178,180,132, 91,251,155, 40, 47, 62,116,253,232,205,103, 79,222,125, 6,214, 91,112, 19,128, 93, 16,160,203,141,149,196,163,
-173, 53, 2,205, 84,224,133, 47,144, 86,151, 18,188,255,250, 35, 23, 27, 43,196, 35,242, 34,188,196,167,182,195, 55,158,206,194,
- 56, 4,184,220,207, 68, 3,233,100, 5, 50,128,158,156, 8,176,182, 35, 79,111,235,250, 83,200, 19,164, 82,130,220, 19,192,167,
-215, 65,128, 28,204,119,116,176, 98,232, 2, 96, 33, 14, 57, 66,146, 1,124, 49, 8,228,212, 1,172,130, 64, 17, 56,219,219, 93,
- 23,210,108,135,156, 13, 0, 57,117, 0, 72, 66,142, 25,224, 4,115,129, 12, 96,153, 14,108,236, 3,139, 99,200,113, 5,247,244,
-229,160,230,171, 75, 65, 86,200, 64,142, 34,128, 44,131, 1,146,240,131, 7,124,192,163,246,144,197, 48,192, 2, 29,168, 24, 52,
-218,238,161, 7,172, 18,208,172,128, 84, 60, 16,115, 24,192,235, 44,209,206,173,228,231,231,127,242,244,185,140,188, 22,184,204,
-253,195,198,202,122,247,222,173, 55,111, 94, 25, 24,154,113,113,241, 8, 11,115,188,255,248,237,237,251,111,144, 12,242, 31,185,
-100,255,135, 94,220,191,123,251,129,141, 85, 72, 82, 88,228,247,239,151,134,198,198,151, 47, 93,230,225,227,151,148, 86,224,224,
-224, 6,246, 9,160,197,250,239,223,140, 76,160,182, 20,176,193, 14,244,160,146,156,136, 24,185,137, 4, 32,128, 24,137, 92,154,
-247,251,208,244, 63,167,150,161,148,242,204,108,204,234,142,172,142,121,140, 92, 4,134,101,255,222, 58,240,107,123, 43,190,179,
-224, 65,157, 0, 9,102, 93, 31,102,101, 27,208,237,169, 28,188,140,204,136,240, 5,173, 24,250,249,245,255,183, 15,255,158, 94,
-248,123,121,235,191,167, 4, 78, 2, 98, 49,137,100,117,204, 37,198, 83,183,159,191, 7,102,188,247, 95,127, 2,219,181,156,108,
- 44,114, 34,124,134, 10,162,228,221,184,196, 0,158,161,189,250,228,237,179,247, 95, 32,203, 99, 56, 88,153,101,132,120,245,228,
- 69,200,184, 8,137,180, 17,155,127,255, 47, 61,122,125,239,229,199,183, 95,126, 0, 61, 2,172,132,128,245,153,177,162, 24,241,
-123,229,129,117,204,229, 71,111,238,189,250,248, 1, 28, 20, 64, 19,128,101,144,150,140,176,140, 48, 53,139,158,239,191,254,152,
- 84, 46, 69, 59, 3, 89, 93, 82,240, 76,123, 20,133,231, 68, 82, 2,124, 58, 55, 32, 95,142, 10,236,241, 92,238,142, 27,114, 86,
-140, 2, 10,193,189, 7,175,183,236,188, 4,172, 6,128,149, 4,176,230,128, 76,180, 34, 90,161,127,254,236,218,189,247,253,199,
-223,252, 2,130, 98,162, 18,224,251, 87, 15,137,136,136, 26, 25, 91,178,179, 51,137, 10,243,156, 60,115, 31,190,140, 29,186,250,
-133, 9, 86,178, 51,129, 23,178, 35,181,235, 57,185,185,255,252,120,163, 32, 35, 32, 36, 44,118,252,194,139, 15, 31, 62,129,198,
- 36,192,157,104,200,252, 42, 23, 7,155,180,164,160,180, 4,191,184, 40, 31, 27, 43, 69,107,171, 0, 2,136,232,117,242, 22,241,
-160,211, 8,174,108,131,108, 10,101,228,151,100,214, 15,100, 49,141, 96,100, 34,108, 2,179,154, 3,211,245,221,255,110,237,199,
-215, 48,255,244,226,207,209, 57,127,206,174,100,146,210,101, 18, 81, 2,154,207,192,193, 7,108, 54, 2, 45,253,255,249,213,255,
-119, 15,255, 61,191,246,255,195, 83,194,245, 21,159, 4,139,105, 20,145,158, 82,149, 20, 84,165,222,245,205, 98,252, 92, 98,252,
- 92,244, 79,154,192, 22,189,129,130,152,129,130, 24,217, 38, 0,139, 87, 96, 83, 29,136,104,234,206,198, 53, 39, 48, 15,184,159,
-154,236, 52,128,133,251, 40, 24, 5,208, 41, 4, 5, 81, 31,240, 84, 1,252, 80, 51,148,210,143,133,197,201,201,233,212,217, 91,
- 47,158, 61,121,248,237,238,143,239,223, 89, 89, 89, 85, 84, 53,129,109, 79, 49, 17,158,235,183, 94,252, 71,140, 30,195,155, 93,
- 8,198,127,164,118, 61, 51, 51,243,199, 15,111,175, 95,185, 32, 37,225, 38, 36,200,103,172,253,127,207,225,247,160, 19,134,153,
- 25,129,253,116,160,213, 98,194,188, 64,196, 70,165, 37,179, 0, 1, 68,172, 41,140,108, 92,172, 78,249, 76, 18,154,160,251,146,
- 88, 57,153,100, 13,153,165, 73,216,179,199,106, 17,247,243,217,101,134, 47,132, 78,120,255,241,249,223,189, 99, 64, 68,190,127,
- 44, 19, 24,121,132, 71,211,235, 96, 3,167,239,190,152,184, 29,125,126, 62,209, 65,219, 86, 67,154, 12,211, 64,151, 17,126,250,
-174, 32, 6,154,120, 31, 13,219, 81, 64,173, 34, 30, 95, 27,136,149, 69, 84, 68, 88, 72, 72,228,223,191,127, 76, 76, 76,151, 47,
-159,251,246,237,171,178,162,244,167,207, 63, 62,124,252, 14, 29,153,193, 53, 20,194, 4, 45,220,153, 88,152,126,255,254,117,245,
-242, 57,117,117,221, 23,111,126,241, 62,123, 47, 43, 37,232,104,173,254,243,215, 31, 97, 65,110, 62, 30, 14,170,207, 66, 1, 4,
- 16, 9,181, 4,176,169,206,162,227, 69,102, 27, 83, 92,157,213, 38,245,247,174,110,134,127,127, 16,243,171,212, 6,204,250, 1,
-204,228,186,112, 20,208, 14,252,250,243, 55,117,214, 30,180, 57,100, 49, 62,206,246, 72,107, 82,141,186,252,232, 77,218,236, 61,
-231,192,107, 67,129,121, 33,216, 76,117,106,146,147, 0, 55,251,104, 32,143, 2, 90,247,146, 37,197,249, 94,188,252,244, 29, 52,
- 97,199,168,166,166,125,234,228, 33, 93, 45,197,187, 15,160,215, 7,226, 27,231,254, 7, 45,220,255,254,249,115,233,252, 73, 37,
-101, 13,126, 1,161,159, 63,127,222,189,255, 90, 82,140, 79, 90,130,134,199,210, 1, 4, 16, 19,221, 2,136, 69,215,151,197, 54,
- 29,122, 30, 26,190,145, 26,114, 11,119, 13, 87, 86,187, 76, 98,198,139, 70, 1, 73,224,236,189,151,171,137, 56, 93, 18, 15,232,
-216,120, 26,115,241,120,111,172,189, 32,137, 83, 29,183,158,191,119,106, 94,115, 14,190,240,255, 63,195,154,147,183, 61, 59,214,
-255,252,253,103, 52,154, 70, 1,173,129, 0, 63,151,186,170,184,138,162,168,132, 40,159,136, 48,159,179,163,237,186,245, 91,129,
-133, 61, 19, 51, 35, 90,129,138, 56,248, 10,118,187, 30,164,112,191,124,254, 20,176,112, 23, 17, 17,255,253,251, 55, 51, 51,147,
-158,182, 52, 11,141, 7, 39, 1, 2,136,174,165, 33,139, 73, 4, 35, 51,235,239,131,211, 24,254,254,162,174,201,204,186, 62,172,
-246,217,140, 28,188,163,169,144,234,224,222,171,143,247,176, 93, 12, 75,124,139, 27,121, 23, 24, 4, 40,139,243,243,115,177,237,
-188,248,128,120,115,180,101,132,107, 87, 30,195, 60,132, 14, 88,220,207, 59,112, 53,211, 85,127, 52,166, 70, 1,173, 1, 35, 35,
- 35, 47, 15, 7,228, 18,237,127,255,248,175,220, 80,188,120,246,132,158,129, 57, 19,211,127,240, 49,238,208,166, 58,228, 12, 25,
-232, 56, 5, 35,104,177,252,239,159,191, 46, 95, 60, 41, 43,175, 34, 12, 46,220,129,194,122, 90,210, 66,148,109,117, 36, 6, 0,
- 4, 16, 93,203,119, 70, 38,102,102,163, 16, 70, 30,209,223, 7,167,254,255,248, 12,135, 34, 82,125,192,198, 98,153,196, 98, 24,
-204,200,206, 61,154,254,112,129, 61,151, 31,206,218,123,121, 85,129, 15,144, 29, 54, 97, 75,154,179,174,139,174,124,231,198,211,
-123, 46, 63, 82, 18,231, 47,247, 51,121,255,245,103,197,178, 35,198, 74, 98,103,239,189,154,149,230, 2,108,113, 3,203,116, 23,
- 93,185,114,127,211, 89,123, 46, 27,195,214,222,194,181,116, 68,218, 8,242,112, 0,141, 2,182,193,129, 42, 67, 45, 84,211, 92,
-244, 48,237,253,251,239, 95,218,236, 61,127, 48,214,200,223,125,249,209,175,123, 19, 73, 94,152,158,236,132,188, 10, 5,213,119,
-143,104, 90,190, 3,125,193,204,196, 52,154,138, 70, 1,218,136,141,173,149,193,199, 79, 95, 46,156, 59,174,165,107,196,198,206,
-193, 0, 30,130, 4,239, 69,133, 78,169,254, 3,109, 79,250,251,237,195,135,187,119,174, 43, 40,169,137,138, 73,254,254, 5,106,
-160,232,104, 72, 74,136,241,209,193,145, 0, 1, 68,239, 84,203, 8, 44,227,213, 29,217,130,123,152,181, 61, 8,151,229,132,198,
-106,152,100, 12,216,130,251, 88, 76,163, 70, 11,119,252, 0, 88,154,131, 10,238, 61,151,128, 8,200,128, 20,238,171, 79,220, 42,
-247, 7,237,242, 77,159,189,247,253,215, 31,123,174, 60, 2, 22,214,105, 46,186,171,142,223, 58,123,239, 37, 80, 10, 88,190, 3,
-101,129,165, 57, 80, 11,164,112, 7, 86, 18, 16, 45, 97, 19,182, 2,201,213, 39,110, 11,114,179, 3, 11,247,244, 57,123,177,158,
-202,217,183,245, 28,124, 56,133,114,240, 3,199, 56,204,247, 95,180, 29,159,249,255,127, 52, 5,141, 2, 44, 64, 84,152,199,214,
-218, 68, 74, 90,254,198,213, 11, 15,238,221,184,127,255,230,195, 7,183, 30, 60,184,253,224, 30, 16,221,120,112,239,230,221,219,
-215,110, 94,191,244,232,225, 29,117, 13, 93, 17, 81, 9, 72,225,174,161, 42, 33, 43, 45, 68, 31, 23, 2, 4,208,192,140, 86, 51,
- 9, 43,176,186,150, 51,107,186,255, 57,179, 2,116,166, 13,142,157,177,136,211,124, 48, 58, 2,140, 34, 74, 44, 70, 33,204,234,
- 78,200,251, 84, 71, 1, 30, 0,108,179, 3,139, 99, 8, 3,210,230, 5,182,217, 59, 55,158, 1,150,236,103,239,191,130,148,218,
-192,214, 58,144,124,255,229, 7, 80, 22,216,156, 7,114,141,149,196,149,196,248, 33,227, 51, 64, 65, 72,195, 31,200,118,109, 93,
- 7,171, 57,228,128, 34,192,242, 29,104, 14,154,141,183,158,191,111, 94,119,146,138, 94,208,147, 19, 61,255,224, 21, 86,113, 26,
-183, 74, 70,147,207, 40,192, 14,148,229,133,191,126, 85, 7,149,221,127,126, 49,194, 38, 23,225,133, 22, 19, 35, 51, 4,128, 78,
- 25, 0, 15,203,104,168,138, 43,202,209,111,129, 31, 64, 0, 13,216,108, 36, 35, 43, 59,179,162, 57,147,156,209,191,231, 87,255,
-222,216,251,239,193,169,255, 95, 94, 51,252,253, 3, 46,235,255,163,229, 44,240,210,127,102, 6,102, 22, 6, 14, 62,102, 25,125,
-208,130,122, 5, 51, 6, 54,238,209, 77,237, 36,149,239,157,155, 78, 3, 25,144,125,152,192, 86,185, 32, 15,251,204, 20, 23, 96,
-185, 12,108,182,159,189,143,210,250, 6,170, 1,182,238,129,141,244,255, 43, 16,119,239,129, 26,242, 96,101,192,230, 60,176,208,
- 39,104, 99,198,156,189,152, 71,179, 81, 2, 74,125,141,163, 38,111, 71, 19,228,102,103,205,116,211,163,109, 38, 25, 29,156, 25,
- 5, 56, 7, 36, 24,117, 52, 36,255,255,255,247,226,245, 39, 80, 49,245, 15,210,254, 68,148,242,255, 24,254,253,251, 13, 29,159,
-212,214,144,148,163, 87,203, 29, 2, 0, 2,104,128, 87,155, 48, 50,179, 50,203, 24, 48, 73,106,255,255,250,246,223,179,171,255,
- 95,222,248,247,238, 17,248,106,236, 15,255,255,129, 58,221,255,129,225,199,206,195,196, 35,202, 40, 40,195, 36,166,198, 36,173,
- 11, 58,115,152,153,149,145,113, 52,203,145, 6, 4,121, 56,202,253, 76, 33, 12, 32,217, 17,105, 3, 44,190,133, 82,166, 11,114,
-179,163,237,188,223,115,229, 17,100,248,165,220, 15,229,140, 54,136, 22,198,136,126, 96,225, 78,204,102,253,227,183,158, 83,215,
- 11,193,230,170,141, 47, 62, 52,172, 57, 14, 31, 48,225,227,100, 91,145,239, 37, 47,194, 55, 26,191,163, 96,160, 0, 51, 51,147,
-190,182, 12,203,205,231,192, 34, 30,229, 52, 2, 88, 17,197,193,206, 2,222,146, 42, 32, 46, 74,239,132, 10, 16, 64,196,158, 79,
- 48, 10, 70,193, 32, 1,215,158,188, 93,127,250,238,155,207,223,149,197,249, 35,172,212, 71,183, 56,141,130, 81,128, 11, 0, 4,
-208,104,249, 62, 10, 70,193, 40, 24, 5,195, 19, 0, 4,208,232, 40,199, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251,
- 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163,
- 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79,
- 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,
-229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24, 5,163, 96, 20, 12, 79, 0, 16, 64,163,229,251, 40, 24,
- 5,163, 96, 20, 12, 79, 0, 16,128,163,171,201,149,219,134,193, 36, 69, 89,178, 61,126,239, 37, 47, 64,186, 73,175,146, 3,244,
-208, 69,239, 80,116,155, 85, 80,164, 73,147,204,140,109,253, 81, 98, 57, 93,216,128, 1,139,164,190,191,165,196,127,254,243,151,
- 64, 11, 74,212, 99,227,211, 1,148, 6,200,131,129, 27, 52,132,192, 0, 67,123,179,183,116,240, 48,187, 40,189, 21,208, 9, 60,
- 65,174,206,197,142, 86, 65,216,121,193,174,234,200,211,128, 12,153,193,129, 98, 7,117, 86,169, 79, 8,141, 0, 27,248,168,123,
- 7,206,224, 20,152,201,138, 42, 89,203, 64,214,179,217, 2,194,216,160, 78,224, 58,103,149, 9, 24,240, 6, 16,109,140, 60,192,
- 90, 5,149, 4,113, 18, 24,158, 50, 1, 23,116, 46,123, 88, 19,237,208, 9,212,187, 86, 15,151, 24, 38,148,102,229, 28,234,209,
- 70,172,128,158,110,227,212,210, 82, 41,123, 39, 27,207,211,143,187,168, 94, 83, 27,131, 70,106,123,189, 31, 78, 32,105, 59,210,
-217,155,115,237,222, 83, 47, 19,164,218,153,114, 77,137,159, 22, 91,169, 89,210,235,196,122,185,196, 82, 15,207, 47,235,115,113,
-249,201, 5, 89,218,246,204,175,231,186,196, 39,125,118, 11, 35,172,192,184, 70,223, 46,129,197,198, 70, 15, 58, 48, 18, 73, 22,
- 4,207, 54,112,239,162, 52, 78, 26, 65,244, 27,118, 95, 42, 18,220,187,150, 34, 25,200,160, 85,251,220,255, 85, 30,116, 44, 71,
-238,152,175,103,184, 8,202,156, 56,209, 23, 54,212,207,173, 94,246, 80, 84,178,193, 81, 71,237, 14,178,198, 44, 57,107,139, 15,
-136,215, 25,142,251,212,103,117, 83,238,217, 96, 14, 19,143,136,174, 18,205,136, 21,189, 31, 99,141,253,160,190, 62,104,156,150,
- 57, 14,175,163, 51,142,254,102,123, 86,157,242, 86,102,152, 87, 31, 26, 44,182,214,173,203, 42, 1,209,107,152,141, 0, 10, 27,
-170,225, 29,252,228,177, 15, 50,116,213,144,220,216,147, 96, 53,250, 89, 23, 28,195,197, 88,181, 24, 34, 75, 97,161,101,244,148,
-168,247,110,194, 32, 19,210,232,153, 53, 14,109,181,117,225, 85,181,240, 16, 1, 88,252,153,155,118,114, 93,157,246, 31, 11,189,
-212, 14,131,243,168,217, 32, 12,208,234,164, 98,143,142, 57, 52,219,108, 26,178,182, 15, 31, 63,252,190,206,127,228,243,155, 86,
- 55,206,234,140, 70, 99, 93,206, 81,169,222,155, 9,245,180, 62, 95, 32,221,235,121,237,225, 43,220,160,107, 7, 67, 72,188, 58,
-196,240, 36,215, 27,187, 25,124,134, 97, 99, 44,166, 63,230,250,240,128, 56,157, 62, 79,240,222,168,144,199,189,154, 13,253, 66,
- 38, 11, 38,245, 51,201,108,244,226,120, 47,219,203, 91,250,245,227,167,237,183,191,251, 86,242,231,149,115,193,197, 80,133,116,
-109,240,110, 91,118,130, 85,118,145,137,195,104, 55,243,156, 67, 82,212, 66,123,148, 87,106,223,209,133,182,113, 63,252,194,210,
- 11,247,201,154,117, 56,186,140, 14, 81, 88, 92, 34, 12,232,164,123,243,166,195, 90,156,135,159, 16,159,147,152, 55,109,127,224,
-112, 36, 99, 26,205, 59,122, 7, 63,185,135,189,166,202, 57,148, 89, 76,133, 53, 27, 73, 99,150,174, 35,224,220, 32, 27,115,108,
-186,159,109, 12,234, 5,160,113, 88, 10,144,153, 91,170,135, 75,142,137,146,101,133,243, 30,234,136,156,210, 75, 76, 87,152,160,
- 12,103,234, 4,222,167,182, 65,150,243, 89, 93, 50,227, 54, 36,239, 69, 14,198, 83,209,143,179, 29, 24, 47, 21,186, 91,116,173,
-176,255,127,109,202, 28, 80,171, 21,141,238,164,186,212,169,145,174,144, 59, 64,135,230,249, 93, 59,143,230, 56, 16, 8, 28, 48,
-143, 81, 77, 93,143,127, 82, 57, 46,126, 22, 17, 84,241,129, 17, 91,131,104, 5, 55,208,156,179,115,254,142,198,216,156, 31, 71,
-208, 38,158,156,133,134,194,248,129,250,106,142, 27, 47,251,245,230, 99,104, 3,117, 26,166,199,160,247,106,177, 5,152, 31,219,
-128, 96,225,129, 41,175,222,137, 12,101,243,193, 93,101,133, 11,138, 9,180, 24, 13,141,106, 13, 33,192, 40, 10,177,229,147, 35,
-192, 57,159,190,112,208,182, 83,123, 68, 94,119,213,167,246,198,175, 95,167, 92,239, 22, 54,145,220,205,188, 14,236,210,218,194,
- 33, 92,131, 9,238,225,181,108,254, 79, 73,192, 44,130, 63,159,112,189,155,136, 87, 83,131, 37, 85,107, 24, 86, 54, 12,205,142,
-167, 40,254,194, 53,237,169, 6,159,204, 68,206,130,225,187, 46,219,184, 37,247, 83,199,219,253, 32,162, 19, 30,135, 17,159, 38,
-201,126,158,223,245, 63, 1, 56, 58,155,228,200,137, 32, 10, 87,214,191,186, 91,109,207, 98, 32, 96,207,138,171,112, 4, 78, 0,
-107, 78,197,133, 56, 0, 17, 44, 48, 51,110,183,164,250,205, 76,158,102,227, 8, 75,110,169, 50,243,189,239,229,202,237,126,251,
-227,119, 3,109,161,131,194,211, 89,112,204,219, 72, 46,144,141, 6,160, 48,129,160, 21,232,199,184, 75,160,131, 64, 34,220,176,
-209,169, 24,200,224,156, 17,126,224,145, 11, 90,101, 32, 6, 0, 11,175,197, 29,249,246, 47,124, 3, 92,253,237, 87,200, 68,112,
- 7,127, 62,193,100,190,128,236, 86,122, 18,220,142,132, 92,192,211,124,154,236, 80,171, 9,130,185,129,118, 74, 66,134,154,139,
- 36,150, 73,148,156,197, 9,213,162, 52, 19,156,167,114, 74, 11, 15,132,186, 20, 31,241, 32, 2,114, 1, 73,101, 64, 77,165,140,
- 41,233, 28, 52, 96, 79,156, 7,196,252, 24,243,224,121,102, 5,234, 43,210,250,147,223, 4,232,152,195,180,143, 94, 39,132,204,
-253,236,238,147,229,240, 95,154,167, 7, 23,128,180,215, 99, 11, 77,150,104, 77, 22,169,188,166,112, 56,188,128, 26,153, 91, 14,
-246,158,238,235,125, 9,241,254, 34,175,183,112,203,159,210,197,234,154,174,118,201, 9,246,140,201,127,146,176,147,247,240,134,
- 37,135, 11,220,208, 65,117,231, 97,135, 19,163, 39, 38, 48,225,189, 59, 0,200, 73,129, 43,186,110,181, 52,170,181,181,114, 72,
-156,187, 1, 11,171,176,196,221,140,167,239, 71, 28, 92,246,243,171,239, 52,155,188,111,147,209,208,119,233, 5,109,175, 56,217,
- 59,108, 99,235,118, 77,105,176,244,209,166, 50, 42,110,102,189,156, 3,182,170, 48,246,192,115, 31, 72,193,157,146,253,122, 96,
- 68, 20, 93,104,181,199, 29,229,214, 40,208,252, 96, 2, 11,247,133, 65,141,155,235,117,177,161,135,102, 71,100,115, 76,231,157,
- 75,152,177, 27,209,226, 18, 69, 77,205,185,101, 16,181, 4,121, 76,235,192,122, 68,190,143,231, 32,186,215,111, 83, 36, 76,135,
-171,229, 21,158, 7, 21, 1,167, 80,172,230,160, 64, 39, 71, 87,221, 41, 6, 11,252,102,123, 76, 8, 72, 82, 97,112,156,155,120,
- 7, 35, 83, 6,222,113,249,240, 8, 27,241, 56, 58,133,225,184, 5,100, 35,146,218,153,241,227,207, 47,255,126,127,255,147,251,
- 7,104, 14, 98,158,139, 6,224, 61, 89, 48,105,245,112, 13,142, 49,222,218,249,153, 50,250, 3, 26, 80, 7,184, 7, 74, 6,187,
-133,230,213, 67, 74, 87, 1, 40,144, 92,118,169,209,188,216, 21, 3,140,226, 44,221,110,179, 0,225,100, 43,159,132,207, 68,234,
- 9,206,117,159,213, 46, 40,183,152,151,184,254,240, 89,127,250,245,175,251, 47,127,227, 72,230, 31, 68, 48,219,140,128,242, 22,
- 57, 24,215,112,221,230,241,132, 69,114, 56, 45,100,235, 19,201,192,201,134, 19, 45, 89,176, 15,156,113, 38,218, 21,108,156,254,
- 49, 46,134,103,156,180,157, 78, 1,113, 76,207,229,186,249,197,150,140,218,201, 23, 55,129,211, 8,179, 4,219, 21,188,169,187,
-191, 78,215, 22,180, 20,149, 18, 28, 51, 59, 61, 27, 76,174, 30, 44, 43,198,110,118, 6, 54, 13,169,136, 14,177,243,229, 29,130,
- 94, 70, 67,216, 28, 54,222, 71, 6, 70, 49, 63,215, 20,100,138, 89, 99, 26, 8,132,103, 62,220,137, 55, 45, 67, 67,168,154,234,
- 22, 29, 77, 74,113,192,222, 5,164,192, 10, 71, 50,159, 60, 48, 73, 78,211,237,212,230,125, 79,217,134,197, 35,117, 94,153,227,
-114,126,219, 33,115,254,110, 86,173,238,191,226,117,241,247, 92, 14, 84, 49,145,130, 88,207,220, 11,193,227,112, 46,182, 66, 47,
- 49,238, 25,180,220,215, 42,146,209,174, 32, 87, 74,216, 21,130,236,152,191,245,225, 29, 65, 15,132, 86,211, 60,146, 32, 17,106,
- 78,196,206,153,100,176,107, 50,228,217,167, 65,144, 8,205,167, 34, 97,224,154, 28,209,118,236,131,196, 64,177,234, 0,127, 5,
-171,141,200, 61, 8,112, 8,133,153, 85,124,131,248,174, 82,180,157, 48,171, 14,187,163, 50,170, 14,164, 65,235,246, 8,140,141,
-205, 88,196, 7,202,113,134, 51,238,108, 98, 87,200, 6, 49, 54,175,252,117, 98, 85,240,182, 97,167,193, 54,100, 75,172,254,249,
-106,209,149, 33, 76, 23, 29, 64,214,153,110,124,185,181, 3,109,212,212, 1, 45, 30,240,191,196,135,202,254,224,204,246,136, 54,
-108, 94, 17, 50,251,219,138,237,212, 10,242, 64, 15, 72,183, 84, 23,143,227,104,199,112,218,125,217,143,124,223, 13,143, 47,207,
-165, 49,222,221,109,253, 95, 0,154,206, 37, 71,114, 34,138,162,241,119,216,206,172,170, 70,205,136, 9, 3,198,189, 20,150,193,
- 30, 89, 11, 44, 0,144,170,213, 89,233, 95,124, 94, 4, 39, 26, 33,213, 40,165,114,218,241,222,189,247,220, 73, 26,127,255,205,
-219,128,152, 46, 84,168,193,181,239,219, 83, 78, 22,201, 14, 83, 29, 39, 16, 80,184,198,111,217, 55, 80, 32, 49, 63, 62,104,160,
-249,120,199,224, 48,211, 62, 2, 34,214,130, 53,253,247,206, 37, 76, 26,151, 65, 87, 18, 12,201,185,240,225, 8,208,255,223,220,
-209,141,198, 15, 24, 84, 7, 30,115,104,102,100,189,147,182,170, 99, 92,173, 10, 17,194, 48,152,214,196, 56,219, 48,122,134, 77,
-144, 76, 84,135,136, 85, 91, 7,171, 50, 57,193, 46, 11,169, 37,172, 66, 25,147, 30, 63,173,143,124,213,140, 98,205,248,105,253,
-110,253,141, 75, 73,206, 24, 50,189, 3,160,224,139,213, 85, 62, 62,144,119, 47, 75,151, 71, 83,121, 63,242, 9,191,244, 4,164,
- 39,243,174,243,135,121, 55,203,214,100,202,194,191,219,203,132,217,100,144,166,220,215, 73, 77, 55,147,231,151,165,199,184,180,
- 31,226, 43, 86,246,114,183,125, 13,106,154,239,110, 65,180,125,178,132,113,112,174, 77,179, 67,123,218,138,239,136, 13,128,196,
- 19,216,127,241, 8,185, 48,169,214, 47,142,139,214,209, 74, 34, 74, 46, 25, 13, 70,213, 61,243,216, 21,255,212, 73, 85,131,210,
- 75,191, 52, 67,234, 72,252,178,167, 90, 40, 28,151, 57,175, 76,162,237,229,104,230, 40,168, 23, 45,116, 96, 57,239,148, 48,203,
-221,154,212,223, 83,157,112,123,166,143,157,127,117,123,150,231,214, 10,127,143,124, 40,205,211,114,226,184,116,253, 75, 93,161,
- 3,170,153, 88,165, 98,216,140, 93,116,124,120, 4, 10, 7,236,224, 64,240, 46, 49, 15,146,223,190,204,106, 21,136,144, 17, 55,
-111, 39,238, 6, 4,171,140, 72, 88,119,172, 64, 40, 60,203,164, 50, 88,109, 53,212, 25,113,241,230, 23,206, 69,155, 49,248,225,
-136,136, 79,183,195,178,122, 44, 17,138,105,131, 95, 51,134, 19,100, 32, 1,155, 67,254,113, 7, 22,111, 33, 27,166,122, 21,104,
- 77,163, 97, 90, 9,214,195,214,104, 79, 40, 7,242,128,190,167, 34,198, 73,133, 72,235,103,123,255,242,211,239,186,255,201,224,
-116,238,166,130,170,136,218, 41,138, 17,194,193,136,114,170, 7,192, 91,175,220,219, 55, 73, 84, 72,160,219, 90,185,135,246,105,
-138,175, 22, 55, 98,220,225,147,118, 43, 68, 65, 73, 24,175,108, 0,208,101, 29,150,192,194, 81, 58, 28,101,130, 68, 30, 4,164,
- 73, 55, 86, 45, 14,212,107,211,155,185,255,252,203,246,227,175,127,172, 95,254,217,255,190,213,175, 90,214, 48,179, 91,193, 25,
-240,229, 0, 89,176,224,179,212,207,157, 3,236, 39,228,216, 40, 9,199,205, 19,180,152,136,121,186,194, 85, 1,115,136,162,186,
-217,186,196,189,237,236,183, 35,111,157,215,124, 33,211,151,236,226,176, 40, 64, 16, 55,209, 84, 88,103, 98, 32, 53, 29,152,171,
- 90, 96, 10,150,208,185,120, 84, 64,158, 56, 47,135,155,187,241, 52,188, 46,176,174,202,121, 54,119,145,231, 34,125,159,110,171,
-106,155,205,199,212, 64, 82,177, 41,122,180,117, 5,150,213,140, 61,249,120,214, 32, 55, 91,128,168,233, 77,179,225, 8, 50, 50,
- 4,112,119, 57,189,199,237, 9,144,102,153,130, 55, 55, 79,193, 88,161, 50, 18, 74,122, 77,206, 15,145, 62,245,182, 97,178,115,
- 91,226,183, 44,190, 94, 15,206,111, 20, 15, 74,173,184, 3, 5, 67,207,202,175,162,195, 4,216,134,187,189,104,184, 40, 47,246,
-228, 49,249,202, 67,221,116, 36,211, 99,206,197, 97, 59,149, 8, 58,146, 91,134,183, 94, 14, 96,161,241,115, 23, 60, 41,153, 62,
-108, 93, 74, 84,103,205, 28,229, 77,232, 35,245, 45,232,115, 1, 34, 21,213,126,169,175, 54,103, 49, 69,239,234,121,158, 16, 24,
-230,112,210,151,141,215, 46,125, 39,116,183,247,193,165,234, 12, 52,137,232,138, 77,245,148, 64,251,139,165,132, 53, 17,154, 4,
-238,130, 75, 61, 88,207,212, 39,167,218,131, 10, 50,109,116,149,139,162, 39,163, 63, 29, 39,165, 34, 44, 27, 61,246,124,152,189,
- 71,139, 83,109,133, 86,230, 98,170,137, 77,230,150, 53, 29,124,111,219,161,175, 25, 6, 19, 61, 80, 44,231,184,233, 60,219, 90,
- 64,151, 15, 86, 65,146,126, 66, 75, 49,184, 75,246,173,192,185, 8,186,147, 64,156,187, 38, 97,207,253, 76, 80,161,105,105, 96,
-140, 30,105, 91,178,252, 43, 0, 71,103,146, 35, 73, 17, 68, 81,159, 99,200,168,204,106, 4, 8, 88,176,227, 8,172,184, 15, 11,
-122,205,173,184, 12, 43, 14,208, 75, 80,119,103,102, 12, 62, 7,207, 82, 42,229, 80, 42, 41, 34,220,204,254,127,223,107,225,246,
-247, 63,255,152, 24, 82,145, 79,138, 5,192,170, 96,179,228, 18,148,154,116,197, 28, 33,220,167,152,169,242, 25,205,150, 80,224,
- 41,190, 28, 92,162,249,102, 29,138,233,133,172, 81, 38,190, 23, 32,226,117,104, 8, 29,192, 96,163,168, 84,213, 81,131,215, 73,
- 75,182, 89, 60,139, 74, 82, 92, 38,255,104,170,153,129, 79, 53,183,194,184,159, 94,244,156, 87,112,142,119,188, 81,118,124,154,
-133, 76,121,225, 34,141,229,197, 19,112, 88, 64, 1,150,182,100, 98, 80, 78,170, 31, 24, 53,224, 59,197, 39, 87,150,189,154, 26,
-145, 3, 18, 65,207,189, 29, 45,110, 88,176,169, 91, 75,251,221,166, 20, 99, 62,120,180,199, 54,125,189,127,178, 74,206, 59,143,
- 58, 30, 81, 68,116,231,111, 10, 48,232,145, 12,234, 84, 74, 27, 48, 42,109,175,158, 88,137,179,220,178, 75,211,119, 75, 24,167,
- 48,100,111,223,166, 49,108,110,224,205, 47, 96,136,179,193,206,179,242,195, 60,145,156,167,176, 4,198, 30, 81,211,114,232,110,
- 86,110, 6,224,209,110, 83, 4,224,221, 49,157, 9,133,239,106,213,199,208,115,154,241,250, 61,102,136, 62,175, 77, 29,185,236,
-133,148,166, 9,164,160,109,142, 40,223, 89,106,102,104,253,170,246,141, 44, 12, 89,184,180,126,174,110, 69,108, 0,125, 83, 31,
-231,120,246, 71,136, 79, 44,117, 63,220,110,211, 21, 25, 75, 73,214,171, 78,183, 18,146, 38, 27,123,241, 76,147, 83,185,228,158,
-111, 70, 82,152,174,253,110, 89,218,113,100, 56, 96,231,249, 49, 53,149, 13,100, 67,201, 24, 6, 34, 83, 27,198,144,115, 39, 46,
-161,188, 57,184, 5,128, 34, 14, 29,178, 15,215,225, 60,230,113,126,137,126,234,126,184, 16,140, 44, 41,234, 73,187, 0,237,208,
-176, 16, 83, 45,167, 9, 94,230,177, 27, 75,219, 94, 3, 11, 2, 51,157, 10, 86,100, 93,250,121,133,221, 27, 19,169,133, 19,170,
-178,132,245,130,202, 10,180,107,122,114, 49, 7,104,139, 11,206, 58, 51,215, 62, 95,122, 36, 99,174,213,247,103,157,124,249,230,
-215, 31,254,158,223,254,202,209,211, 17,154,165, 60,172, 36,105,208, 3, 0,241,228,212,158,119, 93, 34,204,156,118,110,243, 80,
-231,226,213,109,188,188, 79,215,139,153,191,181,211,205,205, 85,235,197,208, 92,129,108,192,165, 22,154,225,180, 3, 0, 65, 82,
-212,243,197,250, 73, 88, 5,188,196,111,204,210, 95,191, 5,198, 85,255,222,253,248,203, 79,251,207, 31,255,153,127,251,175,252,
- 43,140, 56,156,181,147, 32, 10, 6,132,143,245, 66, 91,185, 24,248, 42,177,212,215,103, 15,229, 74,127,156,111, 6, 64,241, 42,
-167, 52, 85,195,154, 96,128,123,247,211,108,155,196, 13,149, 76,146, 17, 2, 66,211,232,156,223,179,185,152, 2, 32, 61,149, 26,
-138,236,226, 69, 96, 93,121,113,107, 85, 23,132,212,216, 47,217,163, 1,218,221, 36, 39,114, 97,178, 3, 72, 61,230, 22,113, 83,
-135,219,124, 6,224, 89, 90, 21, 26,168, 66, 31,157,101, 50,227, 82, 0,116,100, 99,144, 5,167,126, 94,254, 75, 55, 78,145, 71,
- 64, 84,156,213,177,212, 98,177,138,248,186,199,102,205, 2, 38, 17, 88, 93,107,140, 7, 55, 33,194, 35, 59,119,125, 37, 9, 41,
-123,104,139,147, 88, 50,165,240,215, 0, 44,239,237, 13,164,201, 40,169,137,198,140,232, 11,253, 49, 74,243, 44, 22,145, 19, 23,
-231, 86,203, 87,134,160,195, 70,230, 89,222, 83, 85,230,141,184, 95,123, 76, 79,226, 3, 37,117, 67,151, 3,146, 90, 39,238, 47,
-245, 22,179,194,131, 84, 31, 66,205,221,132, 40,199,110,225,252, 59, 10, 85,113,181,199,185,246,122,115, 4, 61,250,130, 33, 62,
-212, 3, 90, 39, 44,109,152, 11,211,106, 7,152, 98, 40, 37,218,173, 80, 53, 5,215, 88,127,151,173, 0, 83, 62, 96,122, 49,184,
-145,106,187,109, 28, 6,216, 32,104, 0,178,240, 60, 1,223,193,162,163, 10,231, 37,198,163,123, 3,113,233,154,176, 48, 83,150,
- 92, 34, 69,134,207,234,238, 54, 95,223, 17,180, 66,207, 25,217,202,216,125,201, 76,187,230,126,143,122, 12,104, 92,185,180, 2,
-193, 85, 16,203,217,100, 43,218,141,235,241,211, 94, 41,221,135, 22,215, 53, 48,234, 37,123,136,214,228, 38,187, 81,250,168, 95,
-236,126,180, 19,231,121,108,248,126, 43, 10,236,217, 70,229,238,231,255, 2,112,116, 38, 59,178, 19, 65, 20,205,193, 57,185,170,
- 69, 9, 61,189, 37,172, 16, 66,226, 99,248, 14, 22,236,248, 73, 54,252, 6,188, 5, 93, 93,101,151,211, 57,114,162,165,222,244,
- 80,146, 51,242,198,141,115,195,139,182,127,252,249,123,197, 50,100,144, 42,111, 10,158, 77,226,245,250,154,232,166,137, 81,195,
- 43, 74, 80,189, 55, 2, 40,213, 70,228, 74,157, 47, 98, 16,102, 45, 75,151,114, 26,230, 97,170,163, 9, 34, 25,133, 34,100,103,
- 44,110,142,180,197,216,104,235, 68, 48,148,149,205, 28,178,177,164, 92, 16, 58, 63,225, 51, 22,190, 3,241,187,236,124,226, 9,
-203, 9,156,144,192,145,137,130, 70,155, 67,161, 58,160,151,249,137,138, 70,210, 61,146,171,234,136,106,139,195,224, 22, 28,103,
-136,239, 70,226, 33,232, 25, 22,134,148, 70,140,156,127, 29,163, 87,247,106, 20,254, 60,231, 73,193,182,234, 66, 93,242,222,112,
- 75, 93,195,161, 93,124,189,143,246,232,109, 30,199,184,219, 26,193,227,169, 14,167,249,137, 51,115, 69,188, 4,156, 55, 84, 20,
-206,180, 93,194, 26,122, 79,150,144,147, 86, 63,210,109, 29,183,239, 46,142,169,234, 47, 94, 59, 16,157, 81,143,123,225, 96, 41,
-145, 14, 61, 52,132, 83, 25,149,116,144, 61,161, 73, 60, 33, 7,108,246,201,159,239, 25,206,168,101, 82, 77,158,249,189,245,247,
-178,192,214, 79,154,170,183,109,144, 63, 16,184,186,212, 99,247,239,103,175,250,163,118,110,252,227, 57,182,187,186,140, 23,216,
-202, 52,107, 78, 34,103,142,173, 16,111,178,190,243, 13,134,247,240,233,225,170,111,230, 12,143,220, 83,230,183,203, 35,143, 51,
-219, 75, 54,216, 42,168, 2,230, 80,202,165,248,251,199,200,135, 24,239,213,192, 15, 21, 52, 61, 31,184, 65,191,235,233,101, 7,
- 67, 49,207, 71, 92,188,189,134, 82,119,241,101,117, 97, 64, 3,131,241, 51,170,113, 99,150,240, 34,156,203,208, 18, 16, 80,193,
- 47, 8,150,219,231,234, 24,195,194, 4,110, 48, 20, 24,204,250,243,223,150,113,231,135, 27, 17, 48,215, 77,232,184,127, 26,254,
-182,192, 15, 7,186,192, 59, 94,131, 68, 85,172,238, 39,125,218,251,161, 9,203,215,194, 7,113, 69,236,128,156,223,137,123, 51,
-129, 84,116,144,222,184,249,153,191,252,124,251,231,199,175,127,245,227, 27, 83,200, 54, 89,170,171,147,224, 49,197,137,137,236,
-207,129,213, 35,247, 14,119, 60, 24,176,205, 6, 11,188,189,165,182, 94,201,148, 90, 34,201, 98,109, 89,220, 77, 67,206, 38, 88,
-235,189, 3,207,121, 34, 38,180,165, 57,152, 62, 35,239, 76,107,157, 9,211,150, 8,102,252,234, 93,232, 75,180,223,255,250,203,
-235,135,223,254,214, 63,221,221,183,107,253,151,240,119, 18, 50,204, 74,195, 98, 26, 67,214,185,222, 73,132,177,210,112, 26, 96,
- 90,158,253,173, 26,206, 38,239, 20,188, 13,156,121, 53,102,167, 90,211,150,241, 88, 39,169,161,160,122, 28,112, 81, 21, 63,193,
- 71, 87,119, 34,237,107,191,129,122, 67,246,161,124, 80,251,113, 9,203,142,151, 78, 43,235,128,132,204,237, 30,117,169,116, 28,
-100,134,198,180, 33, 95,211, 70, 9,231, 11, 91,198, 67,140,186,145, 28,221, 38,236,219,100,117,213,250, 5,230,230, 75, 86,247,
- 35,100, 81, 58,252,228,219,136,148, 16,174,196, 87,140,172, 78,118, 3, 33, 52, 3, 67, 37, 71,105, 55,187, 7,225, 11,188,129,
-168, 60,100, 63, 66,164,144, 85,228, 80,247,190,189,141,254,172,156, 43,246,218,178, 42, 55, 37,155,186, 78, 70, 98,214, 14,153,
-187, 12,221, 69, 7, 70, 93,200,231,105,135,215, 92,129,190, 86,111,253, 92, 70, 55,111,135,198,180, 58,113, 78,203,155,188,144,
- 86, 46,115,200,237, 93,236,181,204,100,100,189, 60,199, 18,169,148, 68, 42, 32,216, 45, 53,166, 8, 12,146,247,224, 34, 75, 20,
-105, 57, 6,147,131, 25,162,117, 63, 22,213, 10, 77,158,220, 42,111, 49,106,249, 15,187,227,178,166, 23, 5,208,162, 22,110,203,
-205,153, 50, 70, 58,223,115,119, 52,246,147, 56,121,202,194,114,155,169, 48,155, 64,125, 89,138,201,220, 46, 42, 19, 94, 48,103,
- 78, 84,193, 53,128,244,136, 87,242,132,122,113,186,140,142,169,219,190,219,122,156, 61,143, 84,151, 45,182,118,255,176,135,197,
-231,121,250,202, 1,229, 29, 39,254,108,159, 7, 9,224, 64,235,157, 92, 0,158,234, 41,250, 24, 51,182,237,163, 71,130,198,166,
- 84,206, 79,107, 69, 53, 85, 86, 49,160,129,188,117,200,163, 16,118,200,116, 71,153, 50,220,242,255, 2,112,116,110,187,173, 20,
- 65, 20,157,190,183,103,108, 39, 16, 9, 9,126, 1,129,248, 34,158,249, 80,222,121,227, 19,144, 0,145,227, 73,220,115,233, 43,
-171,206, 67, 18,201,146,157,233,238,170,189,215,174,142, 20,243, 27,250, 62,177, 30,170,215, 65,135, 10,173, 70, 72,217,113, 77,
-178, 65,151,156, 92,147,218, 42,110,104, 11,237, 15,135, 30, 66, 42,130, 24, 44,198, 15, 36, 87, 99,157, 10,141,162,134, 36,189,
- 10,114,187, 73,198, 55, 77,239,240, 79,230,205,173,104, 74, 80,230,204,248,135,117,157,122,229,184,248, 48, 76, 64, 30, 18,203,
- 10, 95,255,111, 97,147,136, 48,124,149,144,197,239,142, 83, 64, 22, 16, 87,105,133,222, 19, 4, 60, 36,105,239,227,138,152,179,
- 44, 25,117, 64, 1, 53,118, 84,165, 9,223, 82,169, 90,132,189,247, 66,158, 92,145, 80, 36, 48, 67,228,213, 36,178, 85, 62,243,
-150,182,189,111,109,221, 31,143, 99, 99, 97,251,138,204,136,161,148,134, 29,234,146,159,201, 80,190, 43, 82, 75, 99,117, 97,249,
- 11, 57,236, 98, 95, 37,225, 46, 86,207, 47,179,191, 45,232,106,255,214,191, 92,199,213,195,238, 96,250,157,174,156,151,112, 13,
- 87, 90, 74,123, 2,117, 67, 25,180,238,180, 52,122,136,184,118, 98, 18,173,198,238,150,196,203,116, 4,112,177,103,200,149,200,
- 84, 71,191, 17, 9,199, 39, 29, 51,202,177,229,238,255,123, 95,167, 32,246,244, 65, 95, 86,179,149,225, 19,109,152,107, 36,202,
-184,119, 60,126,250,234,206,235,152, 82, 57,215,125, 29, 99,253, 2,154,210, 3, 99,219,114,134, 9,122, 73,169,199, 76,205, 73,
-233,159,169,237,212,117,206,238,106,218,163, 76, 73, 34,252,228,162, 90, 74, 64,166, 61,121,177, 35,170, 0, 66, 13,167, 59,213,
- 21, 77, 46,138, 13, 88,232, 84,153, 38,117,239, 47,250,162,154, 12,213, 76,111, 34, 91, 84,142,237, 21, 72, 47,230, 13, 55,131,
- 22,101, 36, 37,115,247,160,180,135, 60,176,100, 57, 96, 66, 24, 26,103, 3, 7,236,181,135, 4,121, 99,149,169,179, 4, 27,157,
- 11,185, 30,170,116,123,183,178,101,163,141,235,162,221,217, 1,187, 51, 86,155,181,125,245,196, 63, 16,191,102,127,134,166, 32,
-111,202,211, 29,205,162,115,158,152,117,255, 78,197, 95,190,255,221,154, 63,206, 29,146, 96,103,225, 2,194,225,209, 80,231,211,
-105,179,181, 79,218,188,149, 54,206,199,150,137,198, 87, 63,135, 48,223,237,245,102,236,140, 16, 43,153,249, 80,153, 44,117,158,
- 4,133,168,166, 93,228, 46,194, 20,209,201, 37,130,220,128,130,170,168,203, 56, 86,194,174, 92,187,202,157,217, 15,238,155,159,
-126,252,235,237,215, 63,205,207, 95,198, 63,112,226,101, 10, 52, 22,242, 8, 62,138,126,226, 28,184,188, 42,148,158,173, 57,214,
-190, 59,159,131,161,116, 53, 53, 62,121,153,125,232,114,116, 47, 3, 72, 11,161,201,140, 6, 67, 76,117, 49,160,148,242, 51,251,
- 52,133,211,200,196, 83, 53, 28,157,156,183,177, 1,211, 9,206,150, 83,110, 56,249, 17,125,169, 18,242,137,124,196, 12,246,217,
- 98,255, 81,147,174,236, 99,144,206,203,194, 3,157,180, 86,211, 78,254,112, 98, 97,243,134,124,103,225,184,199,209,237,177, 4,
-239, 12, 15,178,236, 74,221,252,214, 54, 30,102,207,246,249,214,239,218,246, 4, 65,138, 40,115,202, 49,205,231,236,215, 79,117,
-211,167, 53,114,177, 44,205,175,101,205,177,197,233, 6,156, 34,163, 70,191, 74,246,127, 46,150, 52,190, 0,183,179,189,253, 45,
-247, 22,102, 26, 91,114,124,120,151,112, 67,135,213,174,101,188, 39, 19, 44,104, 18,101, 37,208, 89,188,172,121, 40,143,162,193,
-200, 62,226,199, 48,125,209,122,111,150,164,145, 99,166,105,231, 71,154,196, 30,218,152, 97,255,155,207,232, 80,141,249,114,140,
-127,189,159,177,101, 59, 3, 4,107,111,253, 5,121,140,118, 85,186,186,195,148, 75,131,197, 64,171,163,133, 3, 88,164,205, 35,
-173, 74, 66,145,139, 21,185, 74, 48,128,172, 18, 85,113,234, 94,189,177,121, 16,136,123, 49,248,108,190,214,158,201, 34, 54,100,
-152, 11, 41,212,129, 47, 82, 42, 46,217,179, 90,210, 68, 75, 84, 13, 5, 60,163,193,104,142,240,116, 69,201,228,237,236, 66,209,
- 48, 19, 41, 82,181,104, 19,230, 32,199,241,105,158,182, 52,159,204,115, 38,204,179,124, 75, 33, 64,162,105, 13,219,177,201, 70,
- 36,137, 65,116, 88, 33, 46, 76,114, 27, 83, 5,237,198, 65,185,163,200,239, 39, 56,143,213,224,153, 91,143,168, 47, 13,240,191,
- 0, 36,154, 91,142,164, 70, 16, 69,129,124, 66,117,141,218,150, 90,242,247, 72,179,129,145,188, 24,111,192,146, 23,224,237,121,
- 21,150,151, 48,127, 86,119, 67, 65,146,228, 35,124,162,188,128,162,128,140,184,247,220, 8,204, 31,127,254,142,141, 35, 62,134,
- 66,152, 42,152, 60,232,150,154,130,211, 77,224,160,113, 22,225, 1, 28,104, 67,196, 85,167, 44, 93,169,229,153, 76, 71,109, 69,
- 74,176,105, 12,182, 8,151,121,174, 44,164,153,255,179, 53,188,170, 51, 23,171,179,156,115,192,229, 97, 77,130, 54,190, 75, 24,
- 82,138,209,189,214,216,245,155, 27,252,109,224,127,177, 82,145,174, 51,106, 26, 9, 51,217,106,134, 1,162, 94,179,226,133,180,
-191,237,174, 88,253, 14,135,234, 84, 34, 41,146,161, 13, 42, 99,212, 15, 49, 48,113,222, 28, 1, 8, 90, 79, 72, 41,135, 79,125,
- 36, 3,113, 88,123,228,117, 71, 49,178, 93, 9,187,216, 66,179, 7, 32, 7,236, 63,146,212,253,209,240,240,147,215, 55,198, 77,
-166, 51, 13, 47,201,133,112,171, 58, 92,116,206, 6, 21, 31,179,144,227, 22, 76,205,191,120, 66,170,127, 51, 49, 12,179,213,126,
-184, 17, 69,227, 92,245,155,160,217,160, 0,179,126,104, 16,251,232, 58,225, 79,103,216, 58,159,118, 18,136,248, 77, 31,135,172,
-179,209,237, 19, 82,143,110,187,109,204, 87, 79,184,207,191,156,103, 53,239,117, 39,191,212,146, 53,208, 12,199,244,128,119,246,
-246,126,156, 77,237,176,158,132,108, 72,143,224, 95, 11, 86,157,182,241,115, 54, 84,188, 9,121,136, 34, 43, 66,222, 40,203, 60,
-202,234,250,195, 36, 76,102,223, 27,214,214,160, 49,142,115,215, 44,221,117,245,196,249, 24, 2, 33,253, 67,193,109, 43,209,202,
-157,232, 16,174, 72, 94,104, 38,251,166,217, 40, 56, 33,160,221, 41,148, 41,140,208,150, 12, 60, 21, 2, 65,190,185,221, 39, 67,
-204,178, 46,134, 22,168,158,130, 39,234,170, 8, 43,231,108,135,135,178,152, 14, 57, 92,215,237, 23, 92,183, 56, 33,112, 98,228,
-163,146,219,180,104, 63,192, 74, 86, 37, 73, 80, 34,110,111, 82,236,118, 67, 61,136, 19, 28,250,120, 37,124,156, 80, 99, 46,192,
- 67,211, 69, 64,250,117, 81,160, 83, 65,119,102,141,119, 82,242,219,175,111,127,191,222,255, 34,238,224, 73,147,206, 16, 97, 43,
-180,156,148,136, 46, 97,159,173,104, 89, 8,212,169,195,217, 5,250, 91, 22, 10, 23, 27, 9, 84,142, 46,238,177,226,102, 73, 32,
-212,175,211,172, 1,233,194, 49, 95, 32,143, 81, 55,116, 92, 49, 72, 17, 83, 63,218,218, 48,214, 30,188,204,111,253,245, 23, 31,
-191,125,127,255,246,219,143,241,107, 41,255, 88,113,183,186,211, 28, 41,116,235,158,129,179,239,114,121,240, 80,247, 85, 24, 40,
-191,233, 2, 76,147, 12,157,200, 37,237,201,243, 62,250,143,234,221,233, 67,233, 77, 13,108,186,145,176,112,233, 24, 87,205, 64,
- 58,220,196,168,148, 13, 81, 21,131,185, 98,143, 82, 52, 23, 63, 39, 92,116,236,195,233, 23, 97,126, 90,244,145,136, 98,196, 41,
-209, 73,151, 30,145,231, 32, 34,178, 81,226,118,141, 20, 23,106,132, 24,235, 45,145,153,195,144,184, 59, 59, 42,105,108,138, 88,
-252,115,191, 29,188,169, 41,249,134,131, 33, 36,144, 30,231,214,148,168, 98,115,171,147, 12,166,161,215,224, 92, 23,234, 21, 16,
-226, 26,180, 34,138,217, 23,209,176, 89, 3, 77,105, 55,170,193, 46,152,246,117, 4, 99,207,201,132,235,250, 0,171,131, 56,239,
-240, 12,199, 65,231,177, 99,169,149, 12,166, 40,163,243, 92,253, 46,200,206,205,181,251, 0, 58,191,242,199, 91,134,174,242,130,
-184,242,144, 39, 33, 96, 8,213,223,230,159,150, 72,151, 46,135,225,125,235, 82, 22,101,201,203,139,191,218, 74,160,233, 63,167,
-225, 16,133, 17,244,251,101,166, 45,100,139, 24,217,148,141, 81,255, 52, 68,185,214,142, 47, 75, 51, 81,215,132,240,118,111,169,
- 88,185,175,207, 85,127,209, 27,193, 46, 74,174,137, 26,154, 66,130,241,118, 65,117, 96, 74,114, 94,186,146,217,159,227, 98,232,
- 52,195,221,118, 63, 50, 30,101,115,245, 83,109, 7,180,109, 72, 5,233,188,100, 3,193,179, 70,144,234,137, 41, 45,229, 43,204,
- 28, 68,187,128, 73,210,173,125,124, 78,159,243, 3, 85, 72,171, 18,251,123,171, 87, 38, 76,185,112, 26, 67,148, 29, 96, 82, 46,
-123,158,215,136,199, 72, 63, 65, 26,218,148, 35, 34,156,131,209,199,249, 40,146, 34, 45,211, 36, 37,201,133,202,249, 79, 0,142,
-206,100, 55,146, 34, 8,195,185, 84,102,109,205, 52, 2, 36, 36, 4, 60, 0,103,158,135, 59,226,202,131,241, 64, 92, 17, 8, 70,
-227,113, 47, 85,149, 89,185,240,253,125,179,229,182,115,139,248,151,136,144,236,127,253,253, 55, 28, 30, 98,137, 52, 70,186, 14,
-189,169,110, 14,114,152,202,113,137,157, 38,148,247, 18,248, 74,186,215, 76, 37,215, 16, 1,118,139,203, 49,145,180,144, 87, 69,
-177, 73,173,128,249, 68,157, 85, 54, 99, 26,121,118, 66,108, 80,195, 85, 46, 0,241, 30, 95, 85,212,220,250,204, 79,184, 76,128,
-212, 8,104,129,175,246, 50,191,141, 32,198, 68, 98,131, 84, 37, 67,135, 56,172,199, 1,212,215, 49,147,210,156, 59,227,183, 85,
-213, 44,196,154, 52,135,198,145, 78, 99, 8, 89, 53,177,207,132, 83,200, 37,173,123, 83,113, 49,201,117,102,164,211,189,110,233,
-184,149, 55,251, 49,162,148,242,176,253,131, 33,186,153,240,159,223,146,147,124, 47, 48, 35, 52, 6, 63,160,241,107,193,221,142,
-176,254, 23, 61,156,238, 10,144,141, 43, 40,112,241, 97,253,128, 79, 43,118,253,114, 30,243, 55, 95,205, 35, 8, 17,167,203,162,
-233,206,101, 66, 13,218, 58,135,190, 6,245,112, 67,111, 75, 24, 68, 66, 96, 67, 7, 76,250,214, 96,221, 97,211, 68, 36,202,169,
-214,116,242, 61,142,238,173, 26,220,175, 61,242, 3, 27, 46, 23,143,116,120,122,116,211, 32,109,113,188,111,201, 16, 42,174,196,
-243, 51,153,242,128,133, 15, 3, 72,150,221,165,130, 36, 79,151,150,119, 93,167,177,183, 19,200, 44,196, 39,230,213, 89, 62,142,
-233,241, 55,190, 26,226,179, 62, 9,192, 41,204, 44,188,168,172,166,249,137,238,223, 1,228, 29, 73,170,170,214,236,136, 68, 13,
-113, 45, 65,173, 82,205, 79,196, 53,206,164,104,115,147,196,223,152,120, 72, 32,107,170,215,195,229, 11, 32, 95,216, 48, 49,130,
- 74,106, 94,245,141, 46,140, 32,146,136,152,151,157, 67,202, 44, 74, 18,251,170, 81,225,103,212,116,177, 42, 92,113, 36,171, 50,
- 62,126,137, 52,169, 42,103,251,196,239,153,164,113,167, 17,150, 76,143, 66,110,237, 86,163,150,238,229, 8,211,155,141, 88,135,
-229,221,122, 20,220,217, 6,130,196,235, 18, 76, 29,191,139,225,167,111,255,232,229,227, 81, 18,120, 10,109,106, 99,231,110, 84,
- 53,224, 6, 74, 57, 97,188,185,195,124,196, 48, 20,205,131, 14, 24,128, 76, 96,178, 61,191,240,231, 29,144,133,139,243, 65,249,
-160,127,238, 62, 34, 49,109,159, 39,192, 21,194,176,178,114, 57, 39,159, 63, 85,204,216,236,251,184,244,245,107, 59,255,248,243,
-223, 63,252,242,231,249,253,125,251,139,128, 92,226,136, 92,185,249, 29,154,209, 40,151,134,202,240,152, 62,132, 67, 69, 35,195,
- 98, 41, 46,119, 50, 2,149, 4, 66, 71,199, 38, 78,178,124,187,183, 32,242, 71,101,159,115, 75, 88,124,132, 47, 31, 86, 99,181,
-197,212, 95, 99, 80,232, 27, 68,134,140, 22,156, 84,239,172, 50,182,185, 79, 56, 93,221,122, 61,174, 53,110, 48,167,205, 80, 79,
- 55, 75,127, 89,228,154,198,179, 32, 52,203,107,100,203, 2, 92,131,247, 31,252, 51,169,193,230, 80,141,175, 42,226, 84,230,181,
-217, 1,131,118, 61, 80,152,206,113, 88,145, 93,101, 73,235,241, 42,207,151,206,219,130, 74, 42, 43,226,160,198,152, 88,209,134,
- 51,238,136, 63,248, 78,131, 29,102,210, 34,184,159,201,224,128,102,205, 92,186,203, 49, 58,135,142, 57,172,231, 25, 44,198, 41,
-123, 92,151,159,250, 78, 38, 19, 43, 81, 46, 63,171,179, 41, 61,199,166, 61,148,230,251,189, 77, 24, 53,155, 80,242,225,225,195,
-115, 45,146,232, 13,193,229,198,141,120, 49,224,219,150,215,118,150,112,242,235,198,165,243, 24,215,125, 52,249,223,122,246, 48,
- 93, 53, 70,120, 68, 77,216, 69, 36,229,174, 97, 57,128,220,237, 77, 93, 65,240, 58,169,134, 31,253,179, 45,138, 69,135,189, 29,
-214, 30, 53,190, 77, 14,204,163,112,125,157,192,166,216,208,165,145, 35,175,231,227, 2,225, 89,213, 67, 23, 3,197, 53, 51,215,
- 62,146,117,113, 70, 60, 69,158,214,218, 59,155, 14, 3,105,223, 55,207, 6, 70,206,113,136,246,228, 12,135,212, 31,248,239,237,
-200,159,108, 94,202,126, 35,174, 30,159, 15,119,110, 60, 15,218,227,238, 34, 33, 26,109,219, 52,113,161, 14,111,219,222,160,198,
- 18,222, 85,248,216,247,226,239,195,208,216, 40,138, 16,178,144,218,194,179,117,248, 23, 49,113,168,216,135,161, 83,239,216,181,
-255, 5,224,216, 90,118, 28,183,129, 32,159,162, 94,158,201,108,176,216, 91, 14, 65,144,123,254, 38,191, 30, 36,167,205, 49, 88,
-216, 99,137,226,155, 76,149, 1, 99, 96, 96, 32,153, 34,187,187,170,186, 75,134,211, 43,230, 27,199, 69,165, 89,222, 78,214, 69,
-208,212, 78, 51, 59,194, 17,127, 59,244,115, 43,244, 26, 71, 54, 91,145, 45, 9, 55, 67, 42, 59, 20, 86, 71, 95, 12,232, 16,173,
-193, 50,178,100, 91,122, 22, 69,169,200, 59,112, 10, 3, 57,233, 68,245,130,205,187, 78, 59, 81,117, 16,221, 10,124, 19,135,138,
-187,101,192, 7,170,161,224, 36, 51, 67, 87, 3,172, 81,228, 94,150, 39, 51,163, 56,231, 88, 56,205,120,185,220,104, 91,200,124,
-158,193, 78, 6,103,104, 60,186,178,148,220,251,249,148, 43,152,125, 99,169, 76,200, 90, 25, 50,246, 84,159, 96,115,234,137, 26,
- 27, 93,155, 64,221,177, 46, 31,126,164, 21,172,165, 12,175, 67, 66, 6,223,243,171, 63, 59, 92, 2,241,255,212,107,175,155,154,
-252,173,230,176,232,213, 89, 75,254,104,228, 6,125,216, 80,205,219,132,154,184,153, 91, 18,203,188, 35,162,242, 48, 43,176,218,
-128,224,131,215,154, 89, 35,120, 38,249,234,215, 98,167,128,253, 14, 2,139,147, 67, 96, 48, 29, 46, 99,120, 4,140,138,180,197,
- 22,234, 35,232,176,137,174, 14,148,219,156,145,213, 9, 9,229, 62,197,163, 63,199,222, 67,232, 33,215, 83,158,165,190,169,214,
- 61,104,146, 7,179, 5,124,153,170, 33,252, 51,234,115,135, 10, 74, 9,143,112,186,244, 14, 84,152, 99, 34, 23,105, 23,161, 15,
-164, 85,238, 5,154,154,155, 82,154, 7,145,225,239, 41,141, 32, 54,133, 46,119,192,255, 17,218, 98,228,101, 34, 22,114,211, 63,
- 50, 68,217,180,173, 87, 99,127,172, 44, 30,203,134,242, 9,179,179, 16, 8, 58, 66, 69, 38, 28,204,210,178,189,114,218, 62,110,
-225, 2, 50, 11,136, 88, 44, 68,130,147, 82,100, 85,113, 67,196, 88,146, 2, 74,110,100, 68,164, 21,215,208, 74,133,157,120,245,
-234, 38, 17,147,149,182, 65, 55, 21,144, 12,195,156,192,103,146, 37, 67,140,173, 16,133, 50,127, 22, 3,101,172,198,112,212,187,
-108, 38,199,233,144, 19, 46, 69,226,152,151, 51, 45,244,254,237,183,219, 95,194,252, 29,193,174,163, 86,129,243, 99, 77,127, 11,
-155, 36,230, 76,180,124, 37, 54,243, 57,227,245, 0, 27, 78,235,217,111,234, 2, 28, 8, 74, 99,236, 2,185,141,239, 29, 18, 2,
- 75,179,156, 84, 66, 39,114, 48,174,114, 37,153, 4, 55, 29,130, 23,137,135,198, 82,178,217,155,248, 98,110,191,254,241,239,239,
-127,126, 31,191,216,243, 31, 57, 0,190,116,116, 84, 26,134, 39, 40, 14,136,101,121,170,249, 70,227, 84, 65, 89,168,150, 93,151,
- 58,158,125,219,198, 12,204, 25, 90,191, 35, 83,133, 94,160, 80,103,212,114,145,113,144,110,243, 16, 42,237,180,216, 62,232, 95,
- 60, 46,196, 10,200, 12,106,181,237, 81,156,200,162,156,145, 38,118, 21,111,124,207, 99,185,124, 76, 74, 46,205,108,185,230,151,
-182,145, 19,167,137,226,200,222,246,176,238, 31, 17, 21,176, 34,149,153,208, 5,255,149, 95, 56, 42,145, 26, 81, 4, 40, 71, 29,
- 39, 22, 29, 15,200,120, 8, 58, 47,131, 17,200,110, 37,140,227,228,117,224,199,216, 87,236,220,154, 29,101,200,169,107,146, 62,
-202,143, 90, 65,102, 16,245,118,107,230, 94, 30,217,230,183,225,128,199, 28,215,181,114, 66,229,130,190,170,238,231, 99, 6,136,
-148, 29,188,100,216,163,145, 29, 46,144, 39, 39,162, 79,185,159,204,129, 43,124, 89,118,156, 31, 71,108,215,238,141, 23,111,205,
-168,154,230, 12,237, 35,199,170,214, 94, 68,162, 57, 49, 6,249, 88,235,251, 4, 77,211, 29, 16,188,141, 92,117,252, 24, 14, 58,
- 37, 65,227,121, 30,250,206, 23, 5,192, 17, 31, 93, 49,112, 38,113,225,145, 84, 93, 95, 47,246, 92,157,175, 54,244, 34, 7, 96,
-211,188,159,103,100,100,171,202, 25, 14, 27, 22, 19, 16,126,236,180,129, 21, 51, 95, 7,242,213,163,116,182, 49, 43,148,156,237,
-222,203,116,197,227,171,161, 46,191, 12, 0,163,147, 86,222, 65,167,144,138,122,145, 87, 11, 96,173,255, 57,229,112,150, 9, 68,
- 12, 25, 47, 21, 59,218,150,173,199,126, 28, 40, 4,102,251,121, 70, 2,222,219,169,114,112, 78,233, 85,135,252, 4,245,177, 65,
-132,207,136,212, 30, 65, 11, 96, 36, 98, 15,140,243,237, 94,229,156,227,158,168,101,137, 64,169, 35, 72, 75,193,161,162, 26,179,
-211,130, 67,213,253, 64, 48, 0, 69,230,242,140, 56,149,255, 5,224,216,108,118,228,182,129, 32, 76, 82,164,168,145,102,215,118,
-246,224, 83,128, 0, 57, 6,200, 59, 5, 8,242, 4,121,190, 60,136, 15,185,229,148,216,240,236,140, 36,254,136, 84,190,154,219,
- 66, 43, 72, 28,177,187,186,170, 89, 61,252,254,231, 31,234,185,107, 14,226, 80, 47, 85, 70, 17, 34, 56, 16, 93,161,102,100, 98,
-228,175, 65,173, 98, 96,193, 10,161,227, 73, 56, 42, 26,224, 25, 93, 88, 11, 59, 71, 81, 31,242,136, 9,196,116,232, 74, 94,130,
-206, 20, 76, 88, 57,207,133,205,147,208,225,229,204,171,153, 43,178,151, 44,210, 65,156,236,146, 33, 92,224, 74,150,141,242, 73,
- 87,136,184, 97, 92, 79, 84,121,149,219, 92,183, 80,161,100, 1,243, 80, 57, 55,159, 50, 79,116,114, 27, 5, 33,147,156,107,195,
-211,206, 7,219, 32,144,106,133, 68,128,148,169,203,219,167, 94,179,221, 70,191,223,116, 82,200,206,219,228, 83,126,122, 43, 91,
-126,108,197,164, 94, 41,192,117,108,208, 76,120, 69,155, 98,169, 62,250,190,168,181,114, 89,134,139, 31,151, 72, 94,248,235,240,
-209,126,242,195, 56,206,121, 14,238,141,138,254,250,182,204,102,158,194,203, 52,198, 24, 22, 63, 93,162,116, 77,104,195, 53,156,
-107, 5,169, 34, 24,159,115, 76,172, 87, 61, 8,231,206,164,177,146,131, 8,120, 61,202,148,250,119, 82,238,212,188,202, 9, 11,
-127, 79,239, 48,144,123,189,175,164,188, 49,117,189,183,164,177,178,156, 13, 57, 96,178, 60, 47, 45, 79,233,193,229,116, 25,201,
- 56, 9,227,237, 94,182,222,183, 3, 60, 60, 61,124,150, 12,133,189,126, 59,100, 43,207, 58, 38,179,175,188,248,200, 5,254, 10,
- 41, 56,151,135,204,101, 54,141,131,111,117, 39,247,114,146,119, 19,158,228,220,149,132, 46, 32,249, 84,228,147,221,175,115,144,
- 11,162,246,237, 34,190, 59,187,130,186, 63,229,212,154,206, 81,167,173, 39,229, 2, 41, 28,134, 69,123, 8,215, 29,192,139, 65,
- 99, 99,126, 0,115,249,215,253,121, 96, 3, 67,148,155, 64,118,120,109,150,230,166,244, 25,100,234,234, 58, 68, 31,212,126,214,
-201,214,115, 67,109,163, 42,195,112, 19, 37, 49, 81,174,145,186,174,106,131,229,101, 2,100, 93,214, 72,133,155, 15, 21,130, 46,
-109,186,109,206,191,152, 31,127,253,252,151, 61,255,238,239,131,217,212,188,135, 3, 0,253,134, 95,171,147,152,118, 34, 72, 51,
-136,158,161, 6, 72, 19,175,189,113,214, 5, 10,210,161,197,219,246,175,188,229,176, 65,162,159, 85,195,122,220,141,103,216, 99,
-126, 94, 33,101,172,228, 60, 11,128,199,167, 92,237,212, 62, 82, 1,127,250,229,251,207,191,125,177,111,235,241, 15,156, 82,212,
-147, 90, 68,133,133,235, 65,150,228,134, 5, 99, 1,137,230, 10, 20,240,148,183, 66,243, 32,147, 55, 79,147,223,243, 61,208,167,
-234, 11,119,151,174,195, 25,141, 16,184,125,224, 57,199,157,220,171,231, 28, 91, 86, 51, 39,152,100, 53,201,164,132,237,125, 12,
-243, 62,173, 84,185,113, 40,150, 15,253, 64,128, 79,208, 84,177,125, 77,211,216,160, 14, 92, 6, 46, 66, 95,124,220,130, 21,222,
- 3,198, 74,111,191,142,182, 37,249,154,209,201,201, 18,227, 8, 87,147, 22,103,102,175, 99, 84, 34, 86,110,112,162,175, 16,159,
- 53, 54, 98, 65, 71,184, 0, 60,193,185,201, 56,211,143,136, 30,177,177, 63, 92, 37, 72,151, 83,236, 32,253,240,225,115, 55,141,
- 69, 6,153,238,122,180,139, 92,183,199, 62,249,215,186, 1, 92, 71, 11, 48,251, 30,199,165,213, 30, 47,210,221,131,163,222,157,
-171,149,163,242, 9,110, 7,130,179, 9,129,154, 40,163,198, 39,144, 84,130, 37, 82,168,174,198,197,152, 98,149, 51, 1,106, 55,
-189,126,200,112,196,187,173, 19,116,174,151, 33,140,250, 56,230, 18,168,210,178,109, 17, 99,218,131,150,209,134, 18, 82,162,150,
-234,208,157,212,191,174, 78,204, 49,184, 21,220, 25,161, 45,119, 62,138,153,184, 82, 88, 28, 68, 11,196,175, 51, 97,183,161,123,
-133,119,231, 99,156,160,208, 97, 51,187,136,156,109,238,209,101,182,251,100,111,224,187,131,143,182,134, 32,104,188,206, 93,161,
- 51, 59, 91,104, 65,108, 64, 56, 58, 13, 63,152,118, 67, 44, 1,214, 71,222,191,182,186,173,229,110, 30,255,141, 33,249, 29,156,
-166,156,150,186,170,103, 61, 20, 40,159, 41,221,239,201,230,170, 38, 93,215, 67, 65,145, 68,253,229,222,155,204,202, 96, 34,100,
-190, 68,117,184,213, 31, 58,224, 15,146,218,166,140,247, 6, 56,192,233,254, 23,128, 99,115,201,141,220, 8,130,104,253, 88, 36,
- 91,211,250, 24, 3, 24,190,132, 1,195, 55,242,194, 43,239,124, 54, 31,199, 24, 47,199, 27, 89, 51, 77, 54,171,138,245,241,139,
-222,104, 33,168, 91,100, 85,102,100, 68,102,164,255,227,207,223,235,131,194,119,173, 35, 89, 13, 14,116, 8, 34,159,149,152,156,
-194,229, 97,195,170, 66,166, 54, 17,230, 67,206, 69,145,138,166,201,165, 76,115,156, 38, 89,237,229, 22,205, 86,158,119,178,156,
- 71, 41,100,248, 67,229, 43,100, 1,250,190,132,118, 63,228,192, 85,223,126, 1,241,229, 31,224,167, 24,172,236, 52,112, 90,254,
- 24,134, 62,212,234,135, 76, 19,247,131, 55,214, 22, 42,232, 30, 79,130, 3, 72,168,219,104,168,200, 62,185, 45,152,116,158, 10,
- 50,159,213, 15,235,103, 26,185, 82,147,203, 93, 86, 0,117,231,107,127, 55, 71, 62,111,100,196, 56,111,135,221,210,251,121,102,
- 5, 62,135,114, 70,184, 14,140, 75,166, 99, 53,104,154,100, 59, 49,225,225, 31,100,118,180, 87,174,184, 3, 95,238,205,174,148,
-229,137,231,250, 49,122, 75, 94, 63,191,182,249,149, 8, 89,151,100,158,120,225,117,214, 0, 90,227, 57, 78, 24,129,103,237, 83,
-205,190,222,251, 42,115,101, 44, 79,222,100,176,154,114, 92,247,189,185,131, 27, 30, 45, 33,153, 67,213,190,133, 31,231,247,239,
-220, 99, 67,126,219, 91, 58,142,179,212, 1, 62,143,180,223,182,140,222,105,217,182,195,165, 84,118, 34, 50,163,248,194,199, 73,
- 21,179, 93, 91,114,112,247, 50, 19, 45,155,213,120,133,247,183,147,159,206,205,212, 35, 21,123, 67,231,184,161, 25, 57,149, 5,
-178, 90,239, 16,216,195,100,109, 81,216, 38, 91,150,183, 51,159,110, 78, 57,230,246,213, 63, 35,127, 22, 19, 38,144, 76,189, 51,
-194,103, 94,250,117, 2,112,194,231, 18,204, 26, 22,128,234, 73,102, 89,119,129,215,143,167, 58, 1, 17,106, 57, 78,109, 50,207,
- 50,138,132,213,107,252,130,170,255, 68,153, 55,144, 33, 15, 78, 93, 73, 17, 15,141, 33,177,144,150, 67,158, 67, 98, 67, 54,161,
- 7, 87, 32, 97,155,150, 46,157,186, 88, 80,231, 35,202, 86, 99,160,206, 48,150,137, 58,210, 0, 50,141,103,144,114, 96,241, 4,
- 50, 94, 60, 9, 69,112,190,253,250,250,229,237,135,191, 40,138,218,155,206, 68,116,145,177, 7,242, 78,101,219,218, 32,195, 26,
- 53,148,215, 14, 34,160,106, 12,145,250, 94, 43, 95, 0,232, 22, 75,121,248, 23,128,154,103,130,121,161, 16,162, 11,123, 22,167,
-208,192,108, 52,191,107, 61, 70,158,139, 0,136, 33,178,138,123, 49,159,127,122,125,255,229,183,191, 95,126, 30,219, 63,243,104,
- 17, 82,229, 83,154,182,139,204, 12,225, 44,238,138,202, 11, 43,228, 37,183,165,187, 40,199,128, 7,179,229, 20,104, 26, 15,120,
- 24,103,207, 83,115,105, 46,154,200,119, 52,214, 60, 54, 46, 51,184, 21,209, 64,188,119,136,187,124, 30,185,106, 60, 93,151,230,
-189, 90, 0, 74, 46,241,164, 52, 27, 45,219,106,216,109,122,152, 6, 0,195,229,203, 15,188,236,167,239,203,241,204,183, 14,117,
-238, 53, 2,209, 12, 5, 49,115, 33,123,198,133,168,154,109, 80,243,231,101,226,193,156,182, 24, 31,235, 11,212, 75,148, 75,181,
- 97, 17,201,229, 31,217,126,117, 68,205,157,236, 60,220, 65,158,191,187,176,159,102,249,190, 34,135,239,211,114, 11,215,175,219,
- 37,151,182, 91, 53, 48,110,251,209,219, 99,117,169, 66, 2,150, 9,242,249, 24,195,153,158,150,211,109, 36, 74, 54, 0, 67, 56,
-218,136,107,179, 16, 78, 53, 80,157, 92,183,220,102,255,148,204,203, 20,111,192, 25,239,170, 75,206, 23, 83, 94, 71,168,183, 94,
-214, 84,229,204, 41, 90, 39, 40, 26,253, 57,173, 2,213,242,136, 42,116,135, 67, 31,197,181,219, 15, 3, 7,247,209,132, 29, 32,
- 59, 13,135, 4,145, 51, 47, 96,138,188,151,177, 4,158, 39,221,172,147,155, 15, 58,153,167,250,105,172, 35,109,163, 80,229, 34,
- 71,108,181, 64,144, 35,101,118, 68, 7,123, 9,132, 79,136,109, 49, 71,116,233,235,197,180, 18,174, 84, 1, 32, 48,205,115,140,
-189, 38, 17, 3,219,206,111,223, 56,209,216, 62,212,146,253, 15, 21, 13,146,134, 93,163,144,108, 63, 32, 55,135, 94,246,223, 48,
-108,142,246,136,119,190, 33,163, 97,169,175, 96,177, 61,144,120, 21,232,175, 31, 99, 62,108, 2,198, 75,165,254, 6, 10,168,150,
- 52,243,204, 47, 96, 9,169, 80, 8, 70, 18,229,158,246,201,203,161,121, 86, 27, 75, 47,238,168, 65, 94,225,122,144, 51,200,183,
- 41,252, 47, 0, 11,103,146, 28, 73, 13,133, 97,205, 82, 78, 85,110,232,232,222,176, 37, 2,174,196,165,185, 0, 23,160,193,118,
- 86, 85,106, 76, 13,252, 47,131,133,195, 14,135,189, 40,233, 13,255,247, 6,193, 44,116,255,191,178,206,105,112, 61, 19, 92, 90,
-131, 0,133,116,162, 20, 47, 96,249,116,173, 4,129,215, 58,156, 0,120, 73,181,238,138,195, 63, 97,159, 16, 69,149,170, 38,162,
-205,133,149,133,176, 86, 21,137,252, 14,243,131,132, 65,142,133,194, 80, 86,150,164, 1,243,206, 33, 90, 39,100,207,213,152, 66,
-214,117,226,147, 17, 21,179,107,204, 4,242,159,166, 83, 79,196,218,135, 18,111, 8,106, 10,226,216, 12,207, 2, 77,230, 23, 50,
- 71,193, 44,174, 12, 26,253,160, 55, 19,172, 61,107,148,231,142, 4,151,103, 46, 64, 67, 56,178,125, 26,145, 70,101, 52, 15,143,
-200,171, 90, 62,166, 79,151,210, 43,225, 42, 1,225, 79, 21,218,113,109,187,158, 1, 62, 52, 61,231,120,143,234, 56,199,141, 22,
- 50,144,184,196, 58,143, 64,224,106, 52,159,251, 28, 55,234,139,227,162,140,145, 68,220, 67, 63,123,186, 77,218,207, 28,104,251,
-134, 79, 15,147, 83,250,218,101,102, 6,103, 1, 32,132,122, 86,141, 26,138,144,102,192, 27,183,227,148,160, 30,122, 8, 69,208,
- 16, 8,135,236,150, 10, 62,195,124, 61,184, 29, 98,215, 87, 55,152,102, 81, 69, 18,175,179,129,176, 70,122,197, 92,162,176,189,
-208,155, 17, 34, 31, 61, 63, 78, 4,140, 86, 98, 65,116, 6,206,157,196,239,248, 71,121,228, 81,168,179,132,188, 90, 17, 61,227,
- 83, 88, 48,125, 23, 17, 40,121, 37, 91, 4, 78,122, 39, 66,224, 42, 42, 98,224,194,105, 90,199, 31, 18,118,209, 99,184, 87,168,
-103,104, 19,240,179, 98, 18, 6, 34, 45, 50,140,155, 62, 38,254, 69, 35,152,152,244,111, 54, 63,143, 7,136, 0, 48,205,134,243,
-208, 71,115,117,122, 70,132, 2,129, 42,225,122,187,102, 27,119, 42,115,150,159, 26, 55,147,230, 52, 8,141,224,210,169, 28,200,
- 69,160, 90, 72,143, 8,214,192, 50, 59,174, 82,232,245, 74, 5, 2, 39,238,151,215,130, 68, 1,233,155, 0,232,229, 92, 38,196,
- 1,173, 96,211,154,182,155, 25, 13, 53,195, 81, 19, 39, 25,127,117,224,134, 60,146,142, 58, 58,241,229,151,245, 79,216, 72,127,
-128, 66,193, 98, 84,113,101, 50, 8, 80, 30, 80, 1,231,141,112,226,105, 99,175,249, 1, 69, 98,225, 71,158,230,222,252, 86,213,
- 59, 12,188,197,202,164,207,252, 38,210, 78,205, 57,228,240, 1,116,238,176, 67, 32, 31,190,136, 71,224, 78, 72,120,166,181,251,
- 77,248, 34,183,111,155,248,253,143,191,221,111,249,248,107,161, 66, 7,201,117, 5, 5, 22, 87,218,108, 21,211, 17, 5, 95, 82,
-143,248,125, 51, 44,130,108, 26,181,201,170,163,173,253, 68, 51,254, 39, 93, 49, 50,156, 27,142,182, 52,149, 42,140,125,165, 92,
-157, 94,202, 65,246, 95,213, 39,233,184,238, 85,101, 27, 23, 42, 86, 75,176,100, 85, 30, 31, 10,128, 91,135,202,248, 65, 73, 18,
-179, 90, 82,153,213, 49, 83,171,144,109,169,107,164,161, 98,125, 87,233, 61,241, 80,237,198, 79, 24, 1, 40,213, 48,103,160, 61,
- 12,210,229, 42,161, 34, 84,164,214, 4,143,107, 91, 11,115, 78,195,194, 51,124,127,130, 98, 82, 94,143,130,235,255, 4, 59,151,
-155, 97, 27, 84,194, 55,195,126, 53, 98,185, 63,220, 36,103, 56,174, 70, 76,124,193,137, 39,195,247,177,125,250,239, 63,248,199,
- 63,197,254,104,249, 93,215,169,151, 37,125, 42,187,242, 24, 42, 29,128,217,100, 24,118,133, 3,227,112,202, 20,197,225,224,194,
-204,186, 42, 19, 14,112, 73, 75,134, 44, 24, 76,227,155,209,183,172, 62, 22, 29, 35, 12, 19,137,203,131,195,239, 27,254,142, 6,
- 64,173,170,167, 64, 86,109,101,238, 27, 2, 33,159,153,211, 33, 67,217, 35,121, 78, 13, 2, 84,244, 57,143,125,129,191,197,109,
-208, 19, 18,196, 17,118,162,229, 31,106,217, 57, 4,110, 64,220, 42,207, 23,205, 45,193,162,222, 86,232, 58,146,228, 84, 33,176,
-137, 61, 45,116,177, 15,184, 9, 68,101, 32,107,185, 30,129, 16,231, 6, 7,121,121,128, 4,244,201, 75, 6,155, 79,232,234,122,
- 24, 90,175, 23,119, 27, 41,231, 57,223,116, 98,112,184, 57,230,234, 96, 79,214,231, 8, 85,206, 3, 77,144,178,119,225, 97, 2,
- 55, 78, 13,184,243, 12,253,106,213,236, 25, 97,212,218, 21,194,238,176,135, 24,217,192, 47,184,130,152,200, 4, 56, 34, 56,173,
-175, 46, 3,233, 52,132, 26,196,227, 12, 77,194,232,229,138,226,159, 50, 68,179,193, 0, 4,149, 30, 21, 73, 46, 61,254, 19,128,
-132,115,219,145,157, 6,162,168, 29, 95,211, 73,122, 70,208, 28, 29,129,132,196, 3, 31,195,127,243,202, 63,112,121, 0, 13,231,
-244, 45,137, 47,177, 19,179,119,243, 60,154, 78, 98,151,171,214, 46, 87,149,134, 11,194,111, 26, 73, 45,214, 33,230,116,240,205,
-176,170,237,117,163,165,193,195,196, 45, 24, 1,171,249, 68, 4,250,117,114, 84,160, 26,128,130, 6, 1,110,204,166,104,112, 4,
-197, 24,167,165, 84,118,170, 34,160,194,221,115,136, 0, 60, 54, 92,133, 95,212,140,119,128, 10,204,218,193,153,157, 64, 75,172,
- 57,197, 63,101,142, 42,193, 27,242,154, 20,134,105, 21,251,225,225,224,199,193, 15,181, 3,158,199,198,212, 45, 94, 43,176, 56,
- 57, 99, 61,124, 22,136,221,208, 48,106,107,199, 10,147,199, 7,111, 32,209,184,234, 0, 32,134, 2,192,201,225, 56,153, 52,251,
- 34,238, 54, 93,135,231, 77, 13,218, 36, 23,245,204, 58, 17, 37, 99, 10, 50, 65,117, 54, 38,159,114,218,142,209,232, 80, 6,236,
-252, 69,251,142, 93, 39, 64,154, 11,128,222, 13,131, 59,175, 93,242,210, 58,123, 18,211,132,111, 56,181,161, 76,123,223, 12,112,
-164,140,160, 39,118,245, 12, 96, 13,176, 4,214,227, 48, 59,133,188, 60,107,153,161, 69,246, 98, 73,164,144,142,155,141, 71, 48,
- 93,130,214,218,213, 94, 35, 48, 16, 11, 91, 73,164,136,156,199, 81, 34,188, 52, 47,102,152, 13,232,216, 68,204,190,139,150,194,
-174,230,175,188,207,201, 32,178,131,164,246,132,108,126, 40,216,231,158, 68, 91,128, 28,109,129,126,247, 77, 69,136, 33,108, 13,
-246,161,177,180,188, 23,219,195,240,105,120, 6,226, 13, 83,238, 5,212, 50,237, 38,179,112,233, 24,122,121, 30,234,253, 41, 62,
- 76,241,216, 32, 44,107,229,223, 42, 32,200,151, 51, 52,118,110,192, 91,245,201, 12,174,218,183, 61, 47,236,176,243,178,189,218,
- 31, 2,194, 58, 80,175,230,206,184, 74, 8,211,163,245,130,117,239,208,180, 93, 7,160,149, 71, 96, 89,129, 24,203,255,245, 86,
-120, 45, 78,224, 81,164,114,196,215,215, 24, 9,200, 80,216,179,209,128, 80, 72, 52,166,136, 61,120,155,114, 78, 60,245, 49,180,
- 22, 14, 68, 49, 44,140,101,114, 16, 86,214,247,208, 30,189,120, 10,109, 33, 7,237,250,118,241,155,114,191,229,249,177, 87, 38,
-234, 21,111,225, 25, 17,240,157,117,197,111, 65,217,137,227,174, 43,171, 10, 27,104, 39, 72, 94,206,167,185,197,208,236,178, 67,
- 55,109,155,242,208, 31, 21, 14, 77, 36,240,238, 0,226, 1, 93, 51,128, 99, 93,165,175,173, 23,181,178, 56, 13,167, 0,135, 87,
-201, 44,237,251, 63,223,255,114,255,248,189,151, 87,101,166,199, 6,103, 80,224, 58, 13, 95, 83, 26, 35, 62,191, 57, 41, 87, 54,
-200, 1,113, 44,192,113,110,222,177, 92, 29, 10, 77,246,223, 58, 29,146, 62,183, 46,104, 68, 36, 96, 42,152, 97,110,250, 51,172,
-229,200,237,240,221, 26,225, 87, 14,139, 71, 23, 96,240, 94, 54, 93, 88,191,192, 74, 58,232, 79, 15,123, 19,155, 74, 1,178, 18,
-210,148,245,108,229, 75, 57,220,121, 4, 53, 45,128, 22,165, 17, 56, 44,124,203,119,236,212,235, 70,147,129, 5, 43,115,219,253,
-224, 31,214,111, 9,220,179,251,168, 24, 21, 52, 96, 88,245,216,178,226, 43,115, 56, 41,119, 94, 99, 31,238,155,206,217,247,221,
-219,197,185, 31,166,229,231,111, 30,159,222, 63, 84,255,231,171,198,252,198, 46,194,180,242,208,239, 69, 76,240, 55, 19, 83,248,
-199, 69, 40, 4,146, 31,159,215,159,126,253,250,254,199,253,252, 87,180, 70,167, 49, 50,149, 27,212,223,112,112,202,184,147,132,
- 19,194,137, 75,173, 65,201,219,186, 55,159, 35,171,176,112, 76,244,122, 21,163,115,201,123, 8, 77,101, 50,171, 61, 22, 56,157,
-221,192, 13, 62,183, 96,153, 98, 58, 85, 21,234,158, 84,235, 17,253,103,169, 82,217, 57,250,192,164, 45,193,167, 97,113,110,216,
-132, 9, 20, 23,128, 75, 39,232,223,230, 17,248,174,157, 92,235,129, 80, 91,157, 83,169,221,194, 58, 34, 50, 6, 14,137, 56, 66,
-147, 56,104,188, 69,131,145, 79,207, 8, 33,217, 77, 35, 16,148,195,160, 44,123,187,100,100,103,217,220, 78, 61, 92,142,223,130,
-236,101, 58, 75,102,255,216,160, 80,241,116,104,145, 46,180,246,101, 44,110,134,234,215, 65,201, 50, 3, 59,110,157, 36,170,242,
-142, 63,234,210, 71,102,233, 74, 93,254,165,172, 57,179,108,178, 24, 39,151, 33,139,171, 0, 65, 0, 58,181,199, 98,113, 20,213,
- 1,105, 17, 27, 7,232,188,244, 1, 28, 96,219, 88,131, 8, 61, 86, 34,155,147, 84, 16,208,160, 15,225,247,147, 56, 7,216,112,
-186, 75, 54,230, 25, 15,158,214,255, 9, 64,194,149,235, 56,110, 68,193,190,201, 38,117,140, 48,192, 2, 78, 12, 7, 14, 28,250,
- 59,252,231, 78, 12,195,233, 38, 62, 0, 47,176,216, 25,105, 72,241,232,219, 85,116, 46, 17,100,247,123,175,170,222, 5, 85, 0,
-210,145,184,172, 5,212,168,178,253, 10,198,197, 84, 5, 68,245, 49, 68, 74,162,196,162, 88,132,121, 59, 9,174, 40, 86,104,136,
-182,141,242,144, 61, 44, 37, 53,156,207,198, 68, 34, 12,114,171, 71,165, 20,110,229, 69, 0,203,232, 82,195, 21, 61,107, 63, 2,
-170,116, 97,102,214,112,167, 12,162, 85,159,171, 6,125,207, 61,164, 15,215,205,128,224, 28,112, 4, 76,208, 77,191,215,185,152,
-221, 52,235, 50,107,142,172, 96,228,147,226, 44, 21,235, 21,112,161,196,174, 56,232,110,238, 45,171, 29,162, 77, 73, 9,170,144,
- 57,217, 6,245, 40,210, 22,175,109,218,192,227, 91, 60,113, 10,175, 2, 10,238, 28, 36, 74,160,175,177, 76,109,143, 98,142, 99,
-185,125,189, 44,103,132,221,102,220,224,158, 32,184,243,243,197, 14,254, 50, 36,216,221,171, 88,246,100,125,239,112, 88, 64, 38,
- 29,111,184, 66,109,237, 58,216,161,137, 91, 62, 35,220, 62, 21,132,150,235,160,185, 28, 51,191,153, 61,219,172,102, 67, 52, 71,
-105,149, 94,218, 81, 86,174,112, 26, 49, 65,128,180, 96, 67, 0, 72,215, 44,174, 73, 78,187,154,196, 14, 6, 33,192, 34,149, 80,
- 99, 74, 15, 78,207, 33,232, 73,169,186,123, 94, 87, 4,150,174,249,206,238,247, 77,108, 13,193,202, 50,103, 81, 63, 88, 98,104,
- 3,171,107,237, 27, 91, 85,211,148, 19,200,167,142, 92,237, 6,223, 86,129,125, 97,108, 77,136, 34, 4,169, 60,190,136,157,203,
-192,159,213, 2,199,202, 60,181, 52, 48, 73, 14,242,103,231,106, 47,154,139, 88,106,112,221,214,195,106, 54, 5,218, 51, 56,246,
- 22,121, 48,199,237,192,157,123,202, 87,223,148,217, 94,161,158,114,201, 3,247, 60, 41, 48, 21, 28,239,112,206,220, 35, 35,205,
-135,209,190, 10,220,202,145,234,227,158, 8,246,110,227, 60, 88, 15,206, 14,154,131,163,177, 10, 63,101,211, 25, 62,182,228,181,
-178,153, 42,197,214, 76, 26, 3, 51,222, 11,161, 31, 44,182,224,223,125,107,110,209, 51, 94, 21,134, 8,139,194, 37,202,189, 89,
- 59, 75,113,251,225,250,151,200,255,212, 71,211,199,182, 25, 1, 42, 96, 99,218,135, 58, 87, 18, 35, 21,202,163, 19, 44,232,165,
-188, 36,224, 94,102,131, 89,254,248, 90,234, 19,210, 88,153,202, 94,159,218,113, 40,247,114,213, 43, 68,212, 92,240,112,215, 7,
-192, 73,238,217, 77,238,246, 67,100,114, 8, 80, 20, 31, 95, 62,229, 52,135, 55,112, 96,163,157, 58, 23,166, 46,223, 64,111, 1,
- 62,146, 88,158, 4, 24, 23,123,222, 91,231,225,226,124, 50,156,172, 6,173, 96,207, 74, 1,220,194, 46,225,164, 15, 13,237,134,
-104, 57,121,208, 81, 85,125, 89,152,189, 53,230,166,245, 4,122, 4, 2,148,212, 90, 2,236,198, 90, 78,239, 69, 3, 4, 19, 26,
-177,154,115, 63, 77,244,156, 88, 41,236, 34,213,126, 24, 57,121,191,128,197, 12, 78,246, 77,108, 47,220, 25,200,225,231, 23,119,
-158,243,253, 33,149, 59,246, 1,165,232,168,197, 3, 23,134,116, 94,204,169, 67, 20,236,155,119,220,132, 17, 67,131,239,138, 37,
-140,167,120,250, 52,156,126,188,108,223, 95, 63,191, 94,222, 69,247,135,200, 59, 56,243,246,248,128, 24,130, 15,231,216,183,128,
-232, 17,219,236, 98,216,248, 96, 14,218,126,129, 13,117,227,159,151,241,215, 95, 94,207,226,246,211,111,203,207,191,127,251,238,
-139,152,166,116,191,169, 43, 71, 95,107,177,160,132, 80,154,161,203,134, 9,241, 34,238, 77, 0, 98,253, 12,133,177, 93,189,129,
- 94, 50,243, 54,154,244, 60,139, 75,146, 31, 96, 13,224, 69,189, 85,130,211,242,222, 2, 11, 61, 46,122,177, 9,250,121, 1,135,
-242,160, 45,176, 11,233,193,101,124,134,238, 59,129, 43,252,139,187,181, 89,154,122,122, 62, 76, 25,158,162,107, 91, 27, 35,226,
-180,130,104, 6,200,251,186,227,117,206,220,204,100,225,192,176, 28, 3, 5, 92,182,184,166,197, 27,179,207,107,252,191,230, 94,
-161,149, 74,241, 62,190,131,119, 69, 55,176, 85,223,132, 29,130,254,173,139,118,223,109,160,239,193, 23, 74,212,121,245,127, 43,
-183, 10, 49, 36,141,191, 33, 20, 84,118, 12, 42,203,158,102,142,173, 6, 73, 45, 72,122, 86,133,156, 87,178, 92,186, 39,235,248,
- 48,131,202,245,106,118,226, 26, 69,105, 19,236,121, 99,131, 95,168,201,176, 8,217, 16,103,131,118,157,143, 0, 20, 41,192, 24,
- 66,234,206,166,159,119, 13, 98, 6, 84,200,195,192, 84, 8,222,108,133, 36,249, 79, 0, 18,174,101, 71,110, 27, 8,138, 47, 81,
-210, 60, 22,222, 0, 78, 28, 4,190, 4, 57, 4,240, 23,248,143,114,200, 37, 31,152, 63,136,237,115,128, 92,227, 56,139,221, 85,
- 86, 18, 69,178, 69, 50, 85,227,219, 96, 46, 51, 32,217,213, 85,221, 93,109,126,253,237, 23,142,199,224,208,216, 16, 3,185, 18,
- 13,156,131,118,131, 56, 3,161,166,203,148,171,232, 60,125, 79, 14,202,197,176, 18,213,235,178, 66, 84, 11,185,152,110,220, 45,
-101, 32, 57, 71, 58, 19, 53,235,151,160, 62,202, 15,236, 51, 52,150,177, 89,123,133, 60,231, 16, 20,112, 0,193,138, 20,130,144,
-192,119, 44,225,179,142,200,169, 6,203,121, 52,205, 81,202,106,232,123, 68,176, 70,228, 39, 2, 63, 37,185,198,147,101, 91,131,
-209, 83, 51,110, 45, 32, 92,196,129,192,127, 70, 8, 71, 92, 10,125, 39,102, 9,235,150, 18, 5,103,139,245,153,171,202,186,212,
-214,150,234, 54, 63,108, 32,173, 46,184, 16,194,146,148,131, 66,211,224,131,234,220, 39,117,214,130,232,240,223, 76,144,112, 3,
-100,135,190,191, 55, 0, 61,127, 54,208,183, 89,159,169, 58,140,102, 1, 30,196, 98,220,223, 92,174, 83,187, 72, 91,197,203,212,
-227,180, 7, 36,168,219, 40,241,192,185,162,178,226, 36,187,219,206,146,194,137, 11, 80,174,160,106, 22, 93,165,239, 23, 25,175,
- 6,103,135,252,189, 65,128, 68,228,234, 89,197,176,113, 5,154, 74, 32,100, 72,220, 81,184,102,239, 56,242, 19, 13,200,219, 24,
-186, 97,235,238, 66,121,194, 89, 59, 78, 85, 54, 54,131,241,192,108,205,105, 89,192,226, 41, 58,251, 10,180, 49,252,225, 72, 32,
-150,171,118,185,173, 79,156,247, 99,203, 27,200, 91,148, 21,156, 33, 46,141,229, 68,203,198, 33,253, 10, 28,162,192, 91,179,246,
-228, 0, 43, 5,234,249, 34,163,128,240,143,128, 22, 96, 68,179, 72,192,119,122,183,126, 12,229,112,102,154, 32, 94,188,188, 64,
-252,156,160,222, 6,170,183, 9, 68, 23, 55,237,185,196,233,164,250,158,143, 70, 95,181,241, 68,243,148,189,127,118,236, 80,246,
-192,234,131,109,116, 11,194,207,241,215,228,144,158,133,166, 71, 68,162, 7,101, 53,133,237, 49, 65, 0,118,128, 47,182,181,144,
-212, 21, 13, 13,197, 67,199,181,209,152,229,220,162,165,163,205, 81,114,150, 31,127,126,253, 97,200, 31,142,253,204,225,169, 0,
-240,166, 23, 19,202,168,205,165,188,184, 3,124, 99,230, 24,119,123,206, 8,202, 48,187,135,199,146,215, 67, 54,235,132,158, 6,
-114, 93,110, 62, 3,179,231, 56, 43,148,198, 5, 33,225,187,152, 42, 23, 84,114, 57, 16,152,115,211,158, 67, 8,221, 72,143,182,
-235, 43,238,175,255,225,221,103,121,229,234,170,218, 64,115, 17,100, 36, 91,148, 18, 57,189, 57,237,116,167, 24, 22,137,193,207,
- 65, 65,153, 58,149, 25, 64, 77,146, 72,132, 64,225, 92, 81, 15,193,163,226,193, 5,136, 69, 29, 19, 5,116,202,116,126,137,205,
-245, 82,185,197, 17,112,213, 44,254, 34,219, 6,201,120,208,144, 9, 58,196,109, 44,191, 59, 16, 84,163,149,189,217,183,240,214,
- 41, 90,242, 52,248,175, 38,113, 11,218,115,108,236,174,101, 40, 26, 7, 26, 86,112,240, 11,135, 98,110,146,166,245,137,231,156,
-238, 78,200,187,230, 86,155,144, 11, 80,180,147,239,190, 29,239,223,191,254,247,253,219,223,223,188,250, 56, 13,127,148,252, 87,
- 0,185,216,179,108, 36,109, 26,175, 84,216,214, 53,160,147,136,237,102, 17,113, 93,192, 51, 47, 32, 99,235, 90,231,199, 48,127,
- 89,255,249,243,177,125,249,251, 39,253,233,221,245,191,187,251,239,103,121,251, 98,215, 20,247,150,183,131,195,155,213,184, 61,
-225, 77, 0, 92,141,137,131, 54,137, 35, 42,149, 43,226, 58,226, 2, 50,226,144, 12, 95,167,121, 80,147,178,160,247,243, 84, 77,
-204, 16,151,169,136,207,177, 64,183,191, 0,108, 21,125, 70,146, 73, 53,192, 72, 65,232,148, 25, 23,181,112, 65, 21,239,205, 65,
-184, 32,141,145,128,226,227,117,105,135,155,138, 28, 0,106, 72,137,253, 18, 70,124, 17,151,156,194,120,148,141, 70, 30, 93, 31,
-247,245,196, 29,179,129,235, 78, 33, 81,199, 24,186, 62,100, 71,234, 78,151, 25,119, 33,129,146, 17,104,172,208, 32,205,201,110,
-123,236,161,236, 59,237, 75, 89,135,103,208,134, 32, 92,220, 40,156,157,234, 86,240, 73, 8, 40,201, 37, 32, 32,211,154,185,104,
- 79,235, 13,175, 52,113, 7,146, 93,219,145,217,130, 4,220, 87, 8, 27,208,178,200,189, 1, 0,203,206,210, 81,132,155, 30, 82,
-223,196,224,222, 21, 30,254,224,236,248,117,201,207,152,123,174,236,104,189,159, 38,165,161, 73, 32, 40,110, 30,149,255, 5,224,
-224,202,149, 36,169,161,160, 84, 58,171,186,122,102,182,153,128,192, 33,192,193,192,192,230,167,246,247,248,138, 53,193, 97,141,
- 37, 2,139, 24,118,102,250, 40, 73,165,147,204,246,251,168, 80, 73,121,232,189,151,154,111,135,184,196,188, 6,246, 25, 9,206,
- 67,220,205, 0,167,190, 57, 53, 7, 56,214, 61, 66,111,179, 8,203,158, 35, 22,189,196, 12, 27,167, 56,162,146,170,169,204,236,
- 99,228, 47, 43, 81, 0,104,206, 42,137,192,212, 87, 16, 31,207,200,226, 89, 16,158, 26, 7,249,140,185,103, 61, 42, 70,168,101,
-182,168, 9,124,192,245,102, 51,251,221,184, 91, 92,197, 18, 38, 80, 28, 8,217,114, 70, 44,177,163, 80,249, 5, 52, 16,160,229,
-147, 52, 13,190,247,206, 61,113,248,240,220, 25, 20, 10, 27, 92, 74,175, 64, 8,223,177,201, 98,217,251, 5,134, 29,107,179,215,
-226,183, 28, 28, 47, 50, 22,240, 40, 92,135,197,231,165,191,226,231,100,116,251, 17,104, 12, 92,124, 26,249,128, 63, 89,117,217,
-253, 42,118, 96, 49,118,214,123, 20,199, 7,168,121, 8, 47,241, 8,112,157, 52,132,124,236,140, 57, 92,237,179,112, 46,183, 91,
-151,218, 41,192, 38,156, 75,198,174,100,131,212,240,236,114, 99,150,198, 21,144,181, 73,194, 1, 11,254, 32,219, 4,251,153,106,
-194, 27,236,134,149,192,200, 30,104, 54,145,130,123,177,206, 50, 89, 17,240,241, 51, 54, 5,100,177,155,226, 2, 62,251,111,234,
-254,156,167, 69, 38,200,226,170,176,130, 57, 97,117, 39,187, 84, 13,248,129, 44,102,214,107,139,195, 94, 59,243,224,232, 87, 2,
- 51, 35,236,163,101, 55,169,132,143, 96,114,104,239,173,130,111, 97,135,101, 82, 76, 0,161,215, 59, 75,185, 64, 14,172, 34,156,
-247,182,216, 61,141,155,232,246, 4,157,106, 22,160,174,165, 4, 31,118, 94, 68, 62,158,128, 53, 94,115,189,170, 59,136, 89,225,
-171,254,182, 28, 30,176,151,124,210,237,177,138,172,198,219, 40,199, 44, 23,238,214, 41, 10,243,237, 0,189,202, 83, 99,196, 10,
- 71, 33, 20, 11,176,101, 84, 40,215,220, 52, 25,208, 36, 59, 25,154, 23,149,216, 76, 7,251, 1,133,127,191, 59,231,220, 98, 24,
-110,146,108, 92,150, 5,194, 19, 26, 31,228,166,247, 81,102, 6, 37,201, 31,150,243,163,254,212, 94,119, 29, 12,220, 11,246, 11,
-116, 7, 47, 96,207,140, 34,102,137,234,181,139, 51,187,248, 46,213,169,125,202, 45,143,247,110,134,118,154,215,175,121,215, 49,
-229,114,192,162, 48,165,229,245, 61, 47,139,165,223,151,227,248,192, 50,110,194,202, 24, 22,240,103,210,151,104,145, 3,103,102,
-181,209,231,211,191,191,159,158, 62,190,245,203,218,170,101, 41, 48,170,234, 55,118,176, 11,175,174, 25,128,196,113, 7,222, 74,
- 21, 83, 90, 1,174,235, 91, 81,244,180,162, 63,201,123,163, 96, 22,213,108, 32, 24,133, 71, 19, 75, 96,188,163, 62, 10, 50,207,
- 89, 28,111, 44, 6,170,185,126,191,139, 43,220,221, 81, 51,199, 37,177, 7,104, 24, 93,119,112,132,244, 0,129,121,158, 25, 4,
- 45,146,199,147,225, 37, 65,158,239, 9,206, 56, 40, 14,252, 67,179,231, 56,169,177,194, 25, 2,209,241, 32,115,103,164,149,131,
-130, 99,178, 21,176, 48, 38, 1,143, 17, 55,209,143, 98,254,197,171,111,158,255,249,233,233,207,105,250,187,165, 75,220,223,240,
-111,114, 58, 40, 28,210,216, 45,118,181,101,181,122,223, 56, 36, 2, 78, 10,176,211, 47,188, 1,212,173,151,160,247,110,219, 86,
-148, 51, 49,195, 66,165,203, 75,254,235,115, 63, 62,124,253,241,215, 47,223,185,223, 62,185,159,255,216,158,206,254,245, 67,142,
- 48, 33, 26,186, 32,195, 54,232,192,206,142, 81,242,116,192, 98,105, 28, 95,231,237, 86,189,218,226,135,171, 54,143, 38,156, 82,
-132,152,216,234,161,173,131,153,101,137,158,208,232,103, 37, 2,232,222,149,114, 91, 94, 6,195,202,154, 19,135, 50,105, 43,134,
- 79, 30, 72, 84, 46,125,241,151, 12,196,114, 48,215, 55,156,132,114, 91,117, 51,217, 64,108,205,212,230,229, 22, 47,195,123,219,
-190, 70, 23, 53, 77,140,173, 89, 28,120,203,231, 69, 14, 28,165, 5, 2,226,192, 58,172,228, 10, 80, 74,253, 82,216, 4, 48,221,
-219,144,163,174, 86,199,138,135, 18,160, 75, 29, 56, 23,212, 64, 60, 21, 78,173, 0, 19, 57, 72, 0,203,218,235,189,111, 44,205,
- 5, 38, 45,156,149,243, 56,181, 59, 78,193, 56,224, 8, 20, 25, 57,105, 84, 59,183,134,103,119,129,103, 32,164,181, 90,115, 66,
-172, 57,142, 33,136,174, 21,203, 4,196, 93, 24, 70,124, 13,158,187,118,239,156,108,247, 89, 84,168,249, 20, 64, 11, 97,181,164,
- 22, 61,175,237,127, 1, 56,186,118,229, 72,138, 32,216,211,207,121,237, 74,183, 18, 58,131,224, 17, 65,240, 9,231,225,225,240,
-197,124, 6, 96, 0, 14, 17,156,197,157,115,122,236,238,244,246,244,244,139,204,137,144, 41,173, 54,166,171,171, 50,171,178,114,
-240,247,200, 70,203, 34, 7,154,212, 42,142, 74,213,174,103,167,108, 14,177,134,159,156, 2, 7,175,109,208,184, 90,120,146,212,
-165, 89, 48, 57, 83,184,192, 18, 64,199, 53, 59,113, 72,247, 5,100, 77, 45, 74, 70,106,108, 80, 95, 40, 24, 4,138, 10,149,179,
- 34,154,157,181, 91,166,140, 61, 51, 86,168,151, 56,236,109,247,213, 81, 80,101, 29, 32, 97,185,222, 53,187,111,241, 91, 46,225,
- 83, 66, 98, 65,252,240,196, 91,244,190,210,196, 18,119, 62, 74, 7,224,139,218, 41,163, 88, 13,254,149, 91, 0, 38,145, 69,131,
-225, 30, 68, 90,229, 91,162,157, 91, 77, 30, 25,145, 6,130,207, 0, 44,202, 2, 37,198,112, 67,113,174,174, 71,226,201,106,235,
-135, 67, 64, 28, 28,132, 89, 64, 7,231,142, 3, 67,211,163,224,167, 25,223,158,224, 84,186,238,221,177, 39, 7,198,117,153,186,
-131,197,117, 61, 74,214, 39,238,250, 37,210,115,197,225,176,116, 8, 41,214, 24, 35, 99, 50, 56, 15,164,136,194, 76, 4,164,187,
-129, 52, 80,128, 77,187,173, 5, 71, 86,162, 5, 36,117, 33,236,150,227,242,170, 17, 37,246,218,186, 62, 92,134, 80, 47, 52,108,
-231, 68,167, 69, 36,254, 85, 77, 77,189,218,193,151,235,185, 0,149,153, 4,220, 50,214, 94,178,119,217,217,122,211,231, 75, 2,
-183, 73,186,243, 5,245,103, 59, 40,185, 2,251,187, 28, 19, 87, 47,218, 88,234,133,151,135, 68, 2, 21, 86, 57,167,169, 97,109,
-165, 91,199, 90,111, 82, 37,101, 1, 60, 52, 23, 36, 59,109,103, 43,248,233, 39,164, 13, 81, 54, 18,133, 97, 5,165, 78,247,128,
- 37, 45,159,181,187,223,250,195, 6,202,146,183, 19, 23,134, 71,196,133, 8,131,246, 87, 63,222, 83,214,145,181, 58,212,110,208,
-141,115, 50,105,150,170, 44, 5,180,245, 57,117, 94,131,158,231,158, 14,251, 40,137, 92, 54,176, 77,115,109,146,111, 24,168,117,
- 81, 55,145, 6, 43,174,224,217, 20, 10, 54,252, 14, 18,113,222, 10, 93,111,145,128, 3,199,156, 59,207, 83,236,152,198, 24, 94,
-183,199,111,223,225, 74,188,198,165,239,184,241, 19, 43, 8,230, 91, 3,216, 18, 87,182,128,114, 6,152,239,169,122,124,238,168,
-201,252,178,238, 43,193, 14,181,111,234, 37, 10,224,220, 47,184,121, 38,236,182,166,220,233,165,181, 67,192,173, 70,142,194,183,
- 3, 76,123, 24,204, 64, 33,125,202, 52, 12, 4,173, 86,115, 39,173,157,167,160,204, 31, 63,116,127,253,174,190, 55,234, 99, 43,
- 51, 77,195,204, 90, 37, 91, 50, 97,175, 77, 75, 70,233, 56,132, 58,142,193,221,187,225, 65, 77,119,197, 79, 86,124,217,112, 97,
-132,143,175,183,219, 18,134,122,140, 96,162,169, 71,206,205,110,139,115,234,103,160,189, 97, 95, 24,212,109,140, 49, 14,174,243,
- 29, 5,195, 73, 0,141, 82, 11,207,118,174, 41,149,142,244,158,184, 12,209, 93,204,157, 64,220,121, 90,238,153, 13, 64, 97,171,
- 15, 58, 28, 79, 15,233, 52,109,223, 77,231,227,244, 89,207,111, 66,188,113, 3,157,157, 38,207,221, 21,241, 30, 33,243,233,249,
-225,223,243,211,146,202,135,247,127, 63, 29,126, 19,229,115,105,103,174,209, 33,178,237,204,122,155,169,144,239, 94, 76, 88, 74,
- 22, 75,190, 0,226, 68, 54,161,100,232,150, 81,127,218,252, 84, 26,120,224,117,141,100, 32,101,187,200,149, 18,165,137,227,237,
-109,243, 47,203,242,241,207,199,211, 63, 63,253,252,225,199,111,126,249,117,249,250,229,229,191,221, 79, 36, 82, 92, 7,246, 57,
-107,115, 3, 51, 59, 91,149, 28,197,115,114,247, 18,231, 91, 40, 4,227, 1,113,103,110,124,251,131,119,237, 14, 56, 98,106,120,
-178, 34,104, 80, 88,148,209,112, 81,122,110, 95, 33,122,154, 19, 41,102,229, 1,241,243,104, 59,100,221, 52,187, 23, 14,242,173,
- 88,113,162, 25,168,255, 82,197, 35, 40,123, 76,244, 63,179,186, 82,249,125,219,128,112,143,118, 98,107, 57,111,217,134,115, 28,
-213,243,234,165,241, 18, 37,160, 0,224, 22, 85,222, 50, 74,150, 93, 0, 69, 27, 78,205, 93,162,117,213, 7,190, 77,160,187, 33,
- 80,104, 76,190,208, 29,101, 53,116,152, 42,155,191,176,235,199, 21, 29, 16,208,208,174,136, 12, 17,146,177,122,202,178, 6,191,
- 77, 72,110, 67,236,134,222, 46,130,102, 19,102, 95,139,204,244,111,210, 56,223,161, 71, 42, 45, 22,151,165,167, 61, 79, 3, 89,
-229, 58,180,234, 53, 0, 0, 17,161, 5,223, 84,108, 97, 38,100, 41, 17,181, 65, 20,128, 59,107, 97,184, 10,252, 4,174,225,255,
- 23,128,163,107,103,142,164, 6,131,122,206,115,215,187, 94, 67,113,118,149, 19, 32, 39,185,140, 4, 18,254, 57, 20, 69, 74, 0,
-129,169,186,224,224,224,238,252,218, 29,205, 72,163, 23,221,147,187,236,181,164,239,235,110,233,235, 94, 32, 25,250,156,229,116,
- 0,243, 98,122,166,173,160, 72,240, 9,150,100, 32, 10,196,226,105,105,173, 59,190, 72,145, 44, 4, 38,112, 98,213,123, 27,101,
- 64, 65, 25,174,122,161, 61,149, 15,104, 51,127,119, 50, 25, 13,187,213,188,145,129, 40, 50,164,167,154,247,175, 58, 38,240, 61,
- 72, 4,205, 41, 59,252,216,108,192, 65,177,205, 80,245,226, 21,173, 94, 87,123, 1, 66,136,120,197, 20,215,224, 10, 40, 21,115,
-229, 37, 35,170,183, 43, 30, 61,173, 43,143, 93, 66,243, 4,100,214,137, 89,187,104,213, 52,176,154, 69,120,175, 28,223,163,167,
-146,191,148,221, 83,153,132, 3, 78,151,197, 7, 32, 12,157, 67,189, 50,188, 10,224, 0, 52,122,145,117, 86, 12,245,128,138,193,
- 62, 28,142,236, 39, 13,167,178,134,178, 31, 71, 14,127, 55, 3, 22, 45,107,203,120,146,214,208,165, 11,229, 35,115, 71,235, 74,
-107, 56,106,211,218,186, 77, 22,209,161, 12,144,173, 13,227,229, 25,118,163, 54, 87,140, 77,129,198,242, 8,146,197,176, 54,231,
-104,115, 19,213, 1,177, 34,168, 46,192,242,153,195,106,232, 52, 42,227,204,241, 26, 69, 44,124, 33, 67,237,166,147,241, 79,103,
-239, 34,159,140, 79,153,193,158,193, 66,119,172, 61,189, 67,232,144,178, 17, 17,156,116, 4, 92,144,150,171,152, 73, 34, 26,170,
- 40, 80,246,190, 84,126,148,149,118, 14, 58,127,193,223,131, 2,116,114,212,136,115,127,212,127, 45,173,237, 32, 13,161,229, 70,
-166,149,121, 18,128, 98, 14, 91, 97,129, 33, 3, 57, 64,198,231, 25,125, 1, 59,232,186,193,116,217,134,207,141, 29,228,126, 7,
-134,210,153, 4,120, 91,116,208, 16,245,227, 22, 24, 15,168, 97, 35,106, 56, 25, 15,218,111,105, 68, 51,182,102,232,192,196,123,
- 33, 2, 13,239, 56,163,152,149, 97,224, 55, 45,226, 6, 4, 51, 52,153,194, 19, 71,113,173,166, 79, 88, 26, 94,178, 41,236, 88,
-192,191,212,120,178,103,170, 98, 47,230, 86,170,125, 69,203, 31,119,233,205,215,230, 55, 17,223,235,104,233, 40,197, 31,112,155,
- 27, 67,160,240,103, 6,233,188,236, 64,146, 80,204,169, 22,236, 59,141,174,133,217,247, 10,148,227, 92, 21, 54,124,188,173,111,
-127,210,237,177,116,246, 42,253,215,125,250,187,254,243,224, 63, 60, 22,224,167,206,109,111,105,227,168,156, 94, 64,145,115,246,
-187, 27, 64,143,193, 52,116, 60, 84, 39,190, 26,126,185,214,223, 94,242,161, 15,207,121,180,140,157,128,152, 15,209,173,216,237,
-225,102,119,125, 47,119,119, 55,225,182, 61,203, 30,202,255,211, 22, 40,220, 9,124, 14, 51, 66, 14,205,243,205, 59,151, 31, 62,
-196,143,114,126, 49,151,110,160,212, 1,185, 18,116, 29,149,201,172,199,194,231,136,220,238, 7,180, 75,200, 42,101, 23,244, 81,
- 99,139,212,107, 35, 15, 80, 55,121, 56,132,180,226, 52, 27,112,235,228,113, 90, 5, 32,189,189,107,186,251, 47, 46, 71,243,235,
-245,233, 47,234,252,248, 36,128, 57,103, 90, 2,128, 37,128,115, 78, 46, 3, 72,245,239,224, 3,247,199,246,254,205, 73,184, 94,
-200, 7,143, 22,206,244,230, 1, 4, 75, 54, 81, 78,188,171, 14, 30, 34, 24,148,219, 59,183,134, 87, 21, 23,235,171,111, 62, 43,
-177,172,175, 6,237,161,228, 0,124,230,132, 95,217,209,231, 32, 39,108,114,228, 46, 87,166,209,131, 7, 4,112,183,199,229,221,
-199,159,239,190,249,247,135,239,127,252,243,246,187, 63, 94,223,199,226,110, 4,135,168, 15, 26,173,249, 64,195,125,104,232,134,
- 84, 51,103,246,122, 58,109,250, 10, 57,201,144,109, 11, 78,203,116, 35,112, 42, 72,147,122,174,125, 75,123, 96, 47, 55,227, 85,
-213,147, 18,211,122, 25,248,152,199,119,222, 92, 60,141,163,168, 95, 64,181, 62,174,230, 57,162,241,140,173, 1, 39,210,103,232,
-181,170, 79, 14, 12, 16,125,177,131,200, 41, 97, 12, 37,230,146,161,121, 57,134, 84,212, 74,249,128,218,187,116, 94, 61,214,125,
-167,236,197,190, 76,204,247, 72, 64, 14, 55,131,220,178,206,153, 0, 83, 84,119,129, 72,194,222, 89,176, 21, 15,168,197, 33,203,
-214,162, 97,154,144, 66,142,218, 97,165,215,170, 81,159,245,121,193, 33,143, 27,181,139, 96, 87,104,184,145,221, 73, 66,107, 27,
-154,102, 65,117, 59,244,129,170,132,137,201,182, 56, 44, 45,239,122, 69,211,111,223,102, 4,221, 8, 46,143,234, 45, 99,176,124,
-188, 24,152, 0,177,227,141,161, 45,156, 69,149,185,153, 81,186,168,254, 33, 94,253, 47, 0, 73, 87,211, 27, 73, 13, 5,237,118,
-219,238,158,238,124, 77, 72,196, 18,113,129,219,238, 74, 92, 56,113,225, 39,240, 83,248,149, 92,225,194, 74,128, 86,145, 86,139,
- 34,136,178, 76,122,166,187,237,246, 39, 85,217,235, 28,162,142,237,247,170,202,126,175, 30, 2,139,247,179,136, 41,218,217,209,
-126,161,101,225, 40,254, 71,253,185,113, 85, 11, 77, 3, 43,207,214, 76,118, 99, 40, 22,179,176,238, 71,130,141,170,214,225,175,
-145, 82,155,165, 7, 13, 7,206,240, 83,211,139, 13,184, 83,129,118, 44,194, 35, 39,214,104,102,157, 88,161,129, 31,106,136,145,
-158,249, 53, 24,109, 44,253,236, 99,238,128, 83,128, 39,172, 16, 53, 86,182, 47,173,234, 97, 99,100, 87,190,236,207, 2, 42,232,
- 20,171,137, 14,104,128,173,219,138,215,209,151,210, 28,217,120, 6,245, 59,184, 4,157,217,205, 93,119, 35,100,239,158, 2, 56,
- 33, 40,135, 6,231, 90, 44,139,111,118,171,240,237, 17, 11,229,187,118, 71, 36,234,183, 33, 52,121,207,226,182,103, 83,247,237,
- 14,121,181,140,141,201, 67,233,250,178, 47,237,132, 77, 56,147,109, 39,183,109,148,139, 81, 23, 28, 22,131,181,105,105, 85, 46,
-232,152,109,232, 2,168,232, 86, 7, 66, 19, 1,147, 44,230,198, 74, 33,253,130, 81, 43,240,223, 78,149,152, 60,219, 84,192,214,
-141, 83, 69,197, 89, 34,101,205, 0,204, 22, 20,125, 69,228, 30,104, 64,199, 38,237,140, 0,137, 44, 5,170,221,196,219,195, 5,
- 48,177, 57,155,167,130, 36, 30, 75,230,151,208, 83,178,150, 5, 34,164,237,158,163, 41, 97,221, 25,128,113,223, 53,102,200,171,
- 81,144, 72,208,168, 64, 15,224,220, 17,240, 37,248,120, 66,215,141, 8,229, 75,167, 54, 30,109, 14, 65, 16,155,164,127, 63, 72,
- 7, 39,118, 65,132,105, 62,158,128, 66,240,201,161,171, 35,240, 28,232,187,195,111, 86,107,158, 91, 94,133, 67, 59, 38,105, 41,
- 73, 85, 13,157,182, 17, 68, 87, 38, 36, 31,103, 57, 39,161,183, 56, 44,210,211, 91, 82, 26,208, 56,118, 72, 51,159,179,108,158,
-222,145,205,203, 91,235,203,213,111, 4,240, 35, 48,113,154,229,226,252,213,231,122,102,161, 32, 48,123,255,226,202,200,142,149,
-166, 12,235,212, 42,246,231,158,114,185, 22,177,168, 30,146,200,211, 28,139,227, 79,118,182,191, 61,255, 80,158,192,217, 57,171,
-160,204, 50, 64,247, 32, 59, 29, 66, 94, 26,124, 74,158, 57, 36,106,153,232, 72, 26,109,205,147, 40,189, 98,135, 23,123,157,210,
-218,122,245,246,199,233,167,159,167,167, 19, 8, 17, 22, 70,123,115, 41,159,206, 63,190,191,186,255,165, 62,255,126,120,120,176,
-127,159,242, 94, 95,170, 29,203,211, 69,171,249,248,159,100,223,115, 6, 78, 94,117,120,247,245,249,251,119,238, 59,143,196, 75,
-118,224, 93,179,206,254,238,155,225,250,205,205,112,119, 51, 11,255,151, 40,143, 33, 31,183, 67, 42,114,192, 98, 86,117,198, 16,
- 66,192, 90,213,217,235,215,103,246,245,237,254,233, 48,254,246, 80, 63, 28,166, 50, 66,208,108,141,228,210,118,233, 11,168,189,
- 21, 65, 65, 95,235, 62,107, 62,171, 82, 45, 74,208, 8,105,105, 29, 11,140,133,190, 50,179,146, 67, 58, 41,208,182,252,234, 85,
- 55,124, 59,222,223,238,239,133,249, 83,196,169,124, 74,201, 45,236,240,229,229, 24, 18,188,165, 88,194,102, 34,236,215,234,238,
- 46,202,149,173,235,161,206, 71, 9,166,135, 37,146,216,118, 67, 63,207,152,155, 71,229,182, 60, 47, 97,114, 91,122,156,253,218,
-204, 62,173,160,171,254,136, 99, 26, 82,187,146,189, 36,104,105,157, 89, 85,137,237,206, 15, 41, 85,124,115, 61, 31,114, 31, 21,
- 66,146,130,168,161,157,248, 49,112,198,129,251,231,143,187, 79,255,126,255,195, 38,191,122,243,235,199,157,183,203,232, 7,164,
- 17,236, 62,116, 99, 9,139,147,114, 32,145,140,213, 93,180,115,246,231, 35, 93, 87,242, 81,169,217,170,226,230,206,219,177, 77,
-238,138,229, 69,206,225,212, 1, 26,178, 85,254, 75, 45, 22, 63, 46,185,183,179,242, 35,112,130, 48, 5,166,177, 93,148,150,198,
-112,214,158,162, 62,213,216,209,118, 42, 9, 21,194, 10,182, 98,103, 58, 33,123,182,180,201, 18,103, 35,156, 45, 56,128,141,159,
-129, 12, 49,224, 92,107,213, 56, 26,246,224,192,186,229,121,208,189, 49,197,201, 85,225, 59,183,197,247,149,157,240, 52,180, 16,
-237,127,126, 81, 77,129,134,202, 18, 9,201, 4, 85,124,179,230,169,229,133,174, 49, 77,207, 17,118, 37, 85,151,212,232,145, 50,
-212,214,165,146, 10,171,229,216,102, 32,233,245,101,122,209, 2, 18,115,136, 69, 54,182,211,129,183, 68, 64, 10, 22,165, 72, 44,
-246,142,237,162, 74,216,108,100,143, 16,242,244,154,208,245,146,131,197, 54,172,155,100,233,156, 30,135,222, 85,103,146, 54,103,
-255, 11, 64,210,213,244,184,109, 67, 65,138, 31, 34, 37,217, 94,187,222, 36, 88, 20, 5,114, 74,110, 45,114,236, 15,232,189,255,
-179,167, 94,122, 40,208, 99,127, 64,123, 89, 20, 13,114,105,155, 0,206,122,119,109,125, 81,164, 72,117, 70,217,227, 46,204,149,
-104,233,189, 25,190, 55,243, 52,130,145, 23,133,139,102,210,248, 97,195,246, 42,205,158,105,255, 78,249,159, 53,220,233,213,216,
- 85,130, 66,208,165, 6,184,121,159, 28,242, 54,125, 45,176,135,122, 53, 37,225, 41, 61,255, 27,225,170,164,204, 6,200, 34,173,
-121,138, 61, 48,105,166,180, 74,214, 60,238, 51,129, 94,200, 18, 0,119,149,186, 22,195,151,142, 25, 86, 69, 34,112, 45,214, 12,
-215,192,165, 26, 78, 24, 73, 29,155,241, 68,142, 58,136,129,245,192,105,156,154, 46,142, 85,152,216,128, 18, 1,243,253,210, 83,
- 6, 62, 6,172, 92,251, 75, 0, 61,159,231, 11,123,164, 7,100,201,162, 87,113,218,133, 76, 45,145,219,130,198,239,162, 0, 23,
- 6,113,219,235,157,159, 42,127, 91,228,198,168,109,232,100,165, 93,222, 74, 81,179,178,219, 33,139,106,133, 95,217,228, 98, 37,
-155,138,168, 0,108,136, 24,150, 21,193,146,185,190, 32, 86, 52,149, 11, 94,116,253, 2, 42,139,208,162, 38,177, 1,231,163, 80,
-204,116,158,173, 77,134,202,161,133,244,127,167,220,232,187,110, 20, 44,245,235,205,216,118, 77, 49, 61,164, 41,186,121,108,115,
- 9, 20,171,108, 49,165,254,122, 93,202, 98,243,168, 60,194, 53,246,224,128,119, 76,165,196, 1,136,121, 0,124,203, 20,226, 1,
-134, 5, 14,144,162, 65, 27,174,195,167,150,245, 58, 77,119, 69,164, 2,197,146,169,244, 90,214, 76,233, 52,188, 93,157, 54,233,
- 11, 10,188, 44, 18,242, 57,119,183, 44, 23,122, 42,224,210,189, 18,166, 89,138, 39, 48, 41,151,182, 65,186,202,174,190,151, 28,
-231, 81,170,156, 27, 85, 25, 4,105,199,193,105, 52,159, 98, 79, 8,190, 43, 42,154,165, 87,225,192,213,144, 63, 64,132, 57,232,
- 76, 1,175,175,122,108, 68, 91,100,185, 50,170, 11, 29, 93,210,126, 29,252,194,201, 81, 60,183,227,217, 78,193, 91, 89, 15,230,
- 57,199,101, 38, 22,107,228, 23, 45, 0, 88, 51, 30, 19, 99, 23,190,171, 34,210,241,151,226, 4, 60, 50,216,134, 5,180,161, 57,
-178,234,244, 1, 57, 49, 75,181,182, 72,231, 52,112,180, 67,104, 37, 40, 91,162,159, 90,148,129, 13,108, 28, 7,211,137,169, 45,
-118, 79, 34, 29,138, 28,230, 0,116,192, 49, 61,203,229,225, 49,254,251,135,211, 33, 11,164, 74,117, 62, 84, 15,119,223, 54,111,
-222, 29, 79, 15,187, 15,191,234,191,127,235,251,143, 3,136,235, 99, 85, 28,141,108,242, 52, 27, 55, 42, 30, 21,215, 27,237,198,
-183,251, 95,124,126,249, 87,255,170,253,124,178,229,225,245,177,126,251,170,252,230,166, 23,226,207,249,114, 63, 60,127,158,103,
-128,162, 13, 96,187,164, 68,189,203,236,167, 42, 69,210,189,172,135,233, 84, 14,215,210,220,220,238, 54, 63,212,155,247, 31,191,
-254,253,186,180,203,105,103,166, 96, 76, 40, 79,147, 47,230, 97, 11,248, 90, 22, 60,238,163, 28,144, 71, 22,216, 88,205,254, 0,
-219,222, 82,191, 51,217, 96,195,252,194,233,205,155, 99,252,238,238, 39,145,254,201,195,101,250,196,122,124,225,165, 12,129, 14,
-212, 36, 34, 21, 94,167, 53, 49,229, 18,108,227,104,197, 86,209, 46, 72,147, 69, 45, 20,104, 16, 10, 33,245,207,237,116, 57,167,
-249, 83,127, 9,185,111,251, 33,196,212,227,239,136, 12,242, 70,153,205,161, 86,149,174, 77,118, 47,108,237,217,106, 87, 52,120,
-104,231, 50, 46,231,247,233,250,180,252,119,206,200, 10,215, 46, 63, 15, 88, 56,188, 44,227,101, 18, 21,208,205,182,188,148,161,
-189, 63,191,126,248,249,221,143,222,221,125,127,223,165,179,184, 2,112,126,213,226,198, 26,173,157, 70, 56,235,244, 84, 57,142,
- 36,113,120, 92,172, 69,112, 88,167,249,117, 86,227,203,221,235,103, 58, 14,173,206,111, 64, 32, 99, 14,214,230, 81,145,179,169,
- 81, 1, 63,223,240,148, 76,236,202,113, 50,118,108, 35, 94,130,101,192, 99,238,167, 60, 98,209, 76, 3,138, 94,210, 53,191, 6,
- 30, 13, 18,159, 66, 76, 67, 72, 29, 27,215, 70,170,189, 13, 69,135,121,226,253,250, 18,136,167, 27, 88,132,241,117,191, 83, 67,
-138,115,239,131, 29,105,214,192, 65, 52, 70,246, 49, 80, 28,151,230,228,109,105,103, 32,138,108, 43,199, 18, 5, 69, 10,129, 3,
- 33,230, 6, 0, 21,208,131,133,124,177, 41,217,182,149,117,140, 54,178,196, 3,198,134, 0,143, 75, 83, 60,184,175,233,108, 34,
-164, 84,180,158, 13,118,102,103, 27, 2,235,226,109,146, 78,238, 67,115,177,156,242,162, 76,206,128,207,244,197, 1, 0,149, 8,
- 40,181, 41, 42, 69,223,252,217, 25,132,118,234,247, 54,249,127, 1, 72,186,150, 29, 57,138, 32, 88,213, 85,213, 93,221,189, 51,
-179, 47, 63,214, 66, 66,200, 22, 55,132, 64,220,184, 34,113,230, 79,145,184,112,242, 13,113,242, 15, 96, 94,182, 64,214,218,218,
-157,109, 79,207, 84,215,155,136,230,180,135, 85,107,182,103,179, 50, 35, 42, 35, 35, 53,155, 88,116, 16,101,215,150,203, 67, 40,
- 69,151, 99, 93,109, 35,144, 84,129, 56, 69,211, 23,112,168,153,190, 27,201,244,171,233,226,194,121,213, 12, 8, 9, 56, 39,112,
-152,165,230,138, 42, 89, 76,110, 13,106,148, 90, 18,194,142, 83,201,116, 45,197,199, 71,228,134, 8,112, 83, 91,228,168,212,224,
-172,117,121, 72,154, 86,246, 8, 43,186,148, 1,209, 85, 67,213, 20,117, 38, 32,120, 65,233, 30,199, 83, 35,160, 61,254,155, 64,
-183, 51,111,202, 22, 94, 61, 44,139,143,170, 45,156, 83, 11, 11,253,245,128, 43,102,239,228,132,242, 13,102,148,142, 67, 14,149,
- 11, 92,101,227,103, 28,122, 80, 76, 53, 4,163,235, 86,123,115,234,221, 96,184, 53, 2,167,217, 92, 12, 77,181,227, 88, 81, 34,
- 34,176, 43, 78, 13,133,170,205, 5,111, 63,117,143, 98, 42,184, 91,165,177,244, 65,161,237,109,110, 7, 58, 33, 72,164, 98,246,
- 52, 70,122, 69,115,200, 16,191, 61,239, 1,144, 26, 74,250, 35,144, 57,213,112,212, 32,129, 74,208, 40, 38,135,101,109, 91,211,
- 57, 10, 4,134, 29, 23,224,145, 77,160, 20, 23,160,180, 83,222, 52, 9,181,255, 8,218,164, 1, 75, 45,138,101,156, 40,136,208,
- 97, 50,178, 61,165,179, 58,198,146, 40, 5, 79,177, 69, 5,111, 13,160, 62, 72, 93,199,220, 75,149,125,195,187,199,192,197,162,
- 8, 76,164, 97,189, 78, 53,212,213, 70, 66, 20, 58,223, 14, 58, 21,171,203,156,197,128,231,253,202,179,118, 18, 37, 31,152, 1,
-207, 20,141,138,212,116, 99, 26, 71, 49,214,124, 26, 85, 23,184, 87, 67,155,176,187,106,192, 84, 93, 12,250,195,217,105, 40,171,
-152, 8,172, 54,113, 45,163,194,143,218, 39, 69,183,184,134,126,119, 27,212,209,254, 84, 20, 96, 78, 15, 4,145,155, 54,178, 29,
-101, 25, 50, 98,221, 52,160,240, 5,116,180,189,162,242, 12,169,157,170,112,214,156,186, 46,208,149,236, 24, 59,215,168,174,161,
-209, 9, 7,196,242, 89, 45, 59, 66,218, 37, 26, 43,140,195, 59,141,224,130,126,188, 64,114,120,248, 83, 76,139,168, 35,157, 19,
- 0, 50,166, 6,241, 67, 9,197, 33,164, 9,233, 17, 25, 85, 2,168,130, 33,151, 13,219,143,226, 46, 45, 45, 25, 22, 13,140,181,
-208,250,237,208,211, 12, 7,188,203,155, 54, 82, 35,151,179,251,205,185,205,219,230, 98,251,213, 15,143, 63,251,174,187,253,165,
-253,227,231,121,190,219,138, 19,195,216,158,197, 62,175,122,241,254,132, 63,162,188,251,230,217,171, 79,150, 47,247,238,201,147,
-126,124,180, 59,136,244,107, 60,190,241,199,201, 31,253,234, 89, 62, 10, 1,132,186,218, 97,103, 75,143,125, 73,229,130, 14,120,
-145, 83,214,203,199,224,140,223,218,110,255,226,185, 31,223, 95,188,252,231,209, 49,236, 1, 34, 8, 41, 16,102,125,106,217,122,
-238,141,170, 51, 80,127, 44,198, 18,171, 92, 26, 91, 91,154,253, 22,154, 63,116, 87,245,233,215, 79, 95,158,111, 94,139,195,235,
- 5,184,230, 62,166,104,165,192,225, 88,188,160, 44, 28,196, 17,164, 58,125, 8,224,255,221,205,101,125,126, 37,175, 81,100,241,
- 70, 40, 57, 22,177, 10, 16,160, 92, 61,221,199,121,127,220, 31,210,237, 62,148,240,144, 78,173, 53,106,215,159,237, 30,155,243,
-103,109,143,247, 29, 56, 90, 35,186,144,247, 0,184,254,253,123,255,128,227,250, 70,206,255, 74,191, 11,215, 55, 98,211,203,207,
-111, 80,110,173,123,151,254,254, 43,223,223,149,135, 25,100, 75,110,165,116, 40,192, 82,185, 99,250,253,225,118,249,241,167, 79,
-191,157,203, 23,223,191,242,105, 72,123,211,234,147, 65,144, 81,246, 67,135, 61, 96, 22, 23,234,106,145, 43,141,237,184,153, 81,
- 53,179,175, 6,136, 91,178,131, 51,138,169, 21,215,179,177,224, 14, 77, 57,136,128,195,113, 78, 25,246, 71,233, 40,248,226, 6,
- 74,219,107,207,113, 19,139,179, 43,184, 41, 69, 35,105, 42,238, 25, 77,180, 6, 9,248,122, 70, 29,185,252,234,178,173,135,195,
- 18,123, 68,225,224,102, 20,161,133, 83,158,177,104, 39, 38, 46,252,208,253, 17,184,239, 24, 66,156,144,164, 14, 96,248, 74, 37,
- 84, 97, 58,242,226,136, 20, 63, 0,149, 42,195, 21,191,174,216,185,202,232,148,109,140,231, 16, 37,253, 89,245,255,251,228,240,
-177, 84,189,178,235, 78,201, 29, 50,106, 43,121,167,199,145, 72,193,185,217, 80,141,205,180,105,215,141,105,121,255, 32, 3, 96,
-118, 63,233, 92,104,127,145,103,153,118,203,102,219, 48, 83, 2,103, 4, 11, 14,146,139,150, 3, 30,200, 74,108, 83, 89,216, 72,
-147,197, 42,225, 76,247,159, 0, 28,157, 75,111,228, 68, 20,133,237,170,242,163,218,118, 55,157,100, 24,134,128,208,108, 96,139,
- 70,179, 71,252,133,249,189, 32,177,152, 45,251, 1,129, 6, 68, 72, 72, 72, 58,253,112,187,202,245,156,115, 44,101,145, 40,105,
-199,143,186, 47,215,189,223, 65, 62,100, 86, 22,254,171,102,127, 56, 7,232, 61,181,138,232,238, 53,165,248,104, 8,156, 38,164,
- 16, 7,150, 36, 10,134,232,169,116, 72, 46, 86,108, 8,196,159, 96,143, 57,193, 59,133, 69,161,201, 90,242,163,144,236,203,158,
-131,139, 13,225, 42, 13,108,159,107,148,111, 86,114,139,200,135,219,220,114,130,156,168, 5, 84, 43, 53,245, 76,216, 14, 77,153,
- 42,132,196, 88, 91,215,162,210,247,243, 60, 35,246, 44, 28, 17, 10,110, 18, 76,139, 7, 78,142,119,152,119, 14,143,117,124,242,
-130,140, 44, 43, 16,136,176,112, 79,112,201,229,180,177, 97, 79,200, 69, 90,180, 6, 8, 79,146,170, 35,246,236, 84,195,198,101,
-223,195,115,155,179,149, 20,136,222, 18,130,135, 28,179,107,135, 82, 13, 5, 82,121,242,207,116,219, 48,104, 33,128,175, 20,231,
- 74,164, 36, 18,144,197,133, 71,176, 11,195, 34,159,130,152, 86, 81,121, 88, 36, 14,178,225,140,107,198, 83,146,126,144, 35, 12,
- 65, 82,110,143,141, 64,248,146,162,205,163,151,248,184,167, 2,195, 90,185, 56, 88,248, 7,202,186,133,129,195,101,197, 68, 57,
- 39,127, 60,100,113,144, 65,171, 9,223,248, 89,203,153,131, 21, 51,155,141,178,137, 35, 82,108, 54,157,219,166, 88, 84,137, 42,
-130, 89, 81, 47, 75,175, 84,199,217, 20,184,241, 90,231,209,145, 79, 78, 61,174,134, 77, 72,170,162, 42, 97,174, 37,233, 7,106,
- 1,110, 33, 72, 82, 43,114,133, 44,192,181, 76, 11, 53,146,124,146, 0,243, 32,113, 53,228,253,203,153,188,254, 78,113,247, 38,
-156,116,143,117,177, 45, 55, 88, 67, 23, 74, 19, 57, 17, 80,128, 52,165, 33,255,146, 23,190, 36, 4,202,207,161, 53, 25, 63,227,
- 48,207, 57,223,143, 5,103,187,224,211,120,166,201, 73,206,166,193,144, 83, 73,181,197, 58,198,133,150, 93,224,186,132, 22,148,
-233, 98,165, 38,137,221, 35,145, 40,224,137,225,247,184, 45,146,213,175, 79,134,195,209, 6,185,220, 42, 52,161, 45, 39,165, 55,
-219,167, 2, 15,193, 55,133, 69,186,196, 90,212,135, 60, 27, 85,156, 83,141, 88,163, 84,248, 63,134,125,134, 53, 52,167, 68,102,
- 49, 74,121,110, 74,240,127, 19,144,135, 67,253, 91,172,204,102,215, 14, 69, 30,181, 88,104, 4, 30,177,169,218,196,113, 10, 39,
-119,236,238,154, 87,234,219,119,253, 23,111, 47,238,127, 17, 31,223,207,127,239,234,111,118,162, 97,223,167, 96,103,209, 48,193,
- 54,207,255, 92,175,135,235,205, 75, 44,255,112,186,117,241, 54,154, 49,154, 71, 68, 73,106,240, 81, 49,131, 61,191, 56, 1, 60,
-212, 42, 14,130,232,225, 57,230, 73,150,159,197,208, 43,113,192, 61,176,176, 50,115,247,106,123,245,163,121,243,243,211,198,138,
-123, 89,244,178, 90,113,138, 33,156, 97,227, 5, 7, 44, 34, 82,220,108, 9,130,240, 11,128,143,104,238,249,226,165,232,190,255,
-250,125,223,253, 26,158,111,194, 3,236,164, 46,142, 51, 69, 38,224,208, 37,162,180, 75,187, 40,136,245, 93,215, 87,178,126,125,
-161,190,108, 18,119,252, 98,177, 16, 95,101,144,201, 20, 22,241,104,231,239, 30,199,121, 60, 89,195, 61,250,107, 92, 85,191, 30,
-182,169, 26, 74,190, 73, 85,217,236,155,191, 14,241,238,118,119,243, 97,122,252,184,237,143,250, 18, 5, 86,183, 9,102,192,253,
- 60, 39, 78,107, 60,156,221, 9, 46, 68,159, 26, 29,180,144, 95,125,142,213,167,238,111,220, 17,203,156, 1, 90,182, 94,156, 77,
-250,227, 55,252,241, 79,223, 93, 94,157, 95,252,240,251,195,159,168,153, 97,200,217,242,220,249,214, 37, 29,136, 17,231,162,117,
-147,115, 72, 72,197, 66, 64,235,240, 81,196,114,169, 57,140, 57, 20,207,135,232,109,173, 73,253,145,106, 31,124, 23, 60,101, 70,
- 69, 22,156, 64,200,198,192, 73, 33, 1, 98,195,161, 37,244,254, 80,180, 27, 44,140, 62,122, 74,156,246, 13,236,207, 88, 39,103,
-119,214,229,200, 22,191, 80,152, 73, 84,229, 49, 16,177, 99,217,167,171, 3, 18,232,213,254, 63, 10, 79, 52, 57,202,182,173, 17,
- 91, 12, 49,201,217,153, 4,163,170, 86, 14,249, 89,106, 67, 52,124,155, 9,227,182,121, 66, 16,159,185,185,197,182, 53, 44,170,
-202,147,174,158, 8,220, 99,187, 97,133,115,236,197,164, 50, 12,248,146,253, 73, 6, 38,128, 36,166,234,230, 88,161, 20,214,201,
-240, 85,156,171,154,212, 69,228,163,109, 82, 13, 39, 50,224,101,175,202,118,217, 80,163, 0, 7,142, 81,173, 75, 60,104, 49, 23,
- 45,204,188, 83,198, 33,233,111,153,201,193,107, 42,253, 73, 0,142,174,100, 71,142, 34, 10,230,158,181,244, 58, 54,140, 64, 26,
- 11,236,155,143, 8,254,128, 95,224, 67,145, 16,146,127,192,242,141, 43, 2,230,224, 1,203,120, 60, 76, 79, 47,181,228, 82,149,
- 68,212, 92,123,186,213, 85,157,245, 94,196, 91, 34, 12,240,215,104,150, 42, 11,219,188,160, 48,101,109,104,122, 77, 29, 63,196,
- 53, 65,107, 1,234, 37, 38,179, 24,120,224, 34,129,124,180,162, 60, 65, 37, 40,220, 90, 85, 89, 86, 0,100,236,200,179,186,163,
-104, 28,194, 26, 52,233, 56, 27,251, 35, 53, 74,104,224, 6, 2, 2,158,132,187,123,105,184, 44,178, 56,207,112,144, 66, 70,238,
-222, 4,154, 22,204, 77, 8,189,193,157,150,148,193, 75, 52,127,205,210, 76, 79,221,184,210, 6,224, 61, 34, 57,119,115, 73,177,
-228,149, 48,167,137,195,196, 46, 82, 5,138,171,191, 25,188, 63,159, 75,103, 28,175, 64,246, 5,132, 9,255,151,105,136, 14,100,
-168, 26, 41,107,154,229, 29,204, 52,173,237,158,218,254, 53,226, 54, 16, 99,187, 81,128,247,222,183,109,118, 51,249,171,195,161,
- 55,158,195,247,146,117, 12,142,115, 59, 53,137,214,179, 48, 73,181,100,250, 69,202,138, 53, 51,192, 7,193, 1,194, 66,146, 1,
-192,173, 29, 2,124, 77,239,165, 41,122,202, 28, 2,180,225, 43,206,221, 34,210,141, 8, 79, 95,182,249,193, 36,132, 28, 46,104,
-169, 30, 44, 46,156, 12,189, 56, 36,151,199, 65,113,230,136,184, 96,192,140, 41,128, 43, 73, 12,132,136, 53,167,151,128, 94,158,
-168,197, 11,254, 77,213,231,231,184, 66, 15,160,134,244,202,121,157,129, 27,248,194, 2, 22, 55,198,119,166,143, 75, 41,116, 39,
- 22,209,102,186,218,226, 75,177,129, 66, 62, 78,199, 91, 27,129, 18, 42,163,213,185,148, 43,179, 88,152, 82,175, 2,172,193,215,
- 8,195,123, 75,241,247, 93,196,159,171,157,221,212,125,164, 5,163,144, 59,164,198,177, 4, 46,198,203, 61,139, 38,160,122,192,
-255,180,222, 67, 60,126,100,185, 68,176,130,236,116,139,168,162, 57, 51,182,252,218, 90, 47,146, 78,188,202,196,157, 76,220, 43,
-150, 11, 90, 32, 54, 49, 4,189,201, 6, 68,107,136, 25, 1,129,194,165, 69, 12,200,166, 56,140,103, 74,240, 79, 70,209,172, 3,
- 7, 19,204,204,134, 78, 76, 55,219,250,119,241,185, 3,245,154,168, 37, 24,211, 56, 3,176, 43,110, 71,167,203, 73,231, 65,186,
- 3,213, 1, 44,158,203, 77, 25,113, 70, 79,131,222, 42,223, 43, 28,238, 1,169, 36,138, 16, 1,146,142, 72, 85,150,202,176, 46,
-227,121, 38, 26,115, 97,177, 18,240, 25,169,242,253, 16,234,163,223,244,223,252,212,238,190,127,246,247,155,185,123, 7,206, 22,
-182,218,111,147, 52,219, 73, 94, 3,141, 15,225, 33,135,163, 4,228, 44,157, 70, 72, 61, 29,115, 90,102,208, 2,142,207,176, 20,
- 54, 86, 5, 7, 68,140,217, 1,205, 29,204,188, 17, 2, 33,158, 58, 76, 20,170,224, 19,194,243, 59,246,119, 95,127,185,125,217,
-189,252, 45,180, 91,221,109, 70,125,113, 8, 48,133,163, 25,233, 42,176,213, 8, 62, 87, 26, 68, 34,217,215,202,143,243,126, 63,
- 84, 63,188,250,213, 87,111,211, 93, 26, 47, 67,121, 4,158, 57, 80,176,134, 77,110, 73,175, 55,228,210,107, 47,235, 21,203,141,
- 47, 92, 89,141,121,137, 64,194, 52,101,178, 62,196,112,137,231,247,151,167,227,233,112,151,251,220, 95,173,215, 55, 55,102,245,
- 69, 91,175,217,236,228,150,126, 50,255,222,234,191,110,239,239, 62, 76,250, 79,124,210,139,215,141, 74,175,118,131,111,106, 59,
-244, 58,228,209, 12, 90, 62, 63,219,242,233,177,233,242, 78,173,254,251,231,243,225,246,114,223,228, 79,165, 7, 25,117,244, 71,
-119,221, 5,112,108,118,107,181,175,244,211, 56,125,252,112,174,126,249,249,219, 31,215,221, 87,223,125,188,255, 3,103,235,188,
- 37,247, 99,135, 33,173, 9, 58,167,108,107,206,101, 0,193,129,104, 15,245,152, 20,222, 41,148, 3, 94,119,187, 7,159, 85,174,
-200, 7,133, 77,153,214, 4, 8,139,220,161,101,171,179,167,186, 98,126, 44, 30, 72, 0, 96,183,149, 53,192, 97,255, 48,239,251,
- 94,172,148, 63, 79,126, 58, 30,193,166, 0,184, 68,142,151,222,208, 33,141,114,128, 1, 73,196,165,129, 43,166,154, 42,142, 86,
-165, 38, 41,228,172,228, 58, 73,171,122,144,229,227,124,218,170, 6, 49, 44,128,255,204,209,200,225,130, 72, 9, 6, 57,152, 82,
- 89,101, 51,189, 96, 73, 72,103, 42,253, 57,239, 88, 28, 11, 98,157,103, 60, 27,160, 43,122,172,107,101,175,144,172,164,197, 89,
- 11,178, 25, 91,101,163,243,146,205, 90, 74,210,249, 40,204,102,199, 53,151,153,206,223,165,153, 45,199,100,174, 59,125,170,207,
- 10,239, 30,141, 92, 94, 48,206,154,128,208, 96,180, 29,136,155,205,154, 78,246, 6,193,105, 21,231,255, 5, 32,233, 90,118,228,
-182,129, 32, 31, 18, 73, 73,163,221, 89,199,118, 30, 8,146,131, 3, 7, 8,226,139,191,196, 95,154,107,190, 32,200, 37,135,156,
-114, 72, 16,172,179,142,225, 93, 27,235,157,241,140, 68,138,164,168, 84, 49,151,185, 12,230, 33,169,217, 93, 69,118, 87,209, 75,
-190,165,206,244,150, 55,207,193,135,210, 36,106,229,170, 42,172, 94, 71, 35, 0, 59, 81, 96, 36, 91, 97,108, 44, 52, 6, 80, 20,
-148,212,220,166,159,170,244, 83, 85,116,174,251,170,180, 95,225, 68, 8,146, 94,181, 65,216,216, 44,130,107,164,228,166, 70, 73,
-241, 28, 17,241,189,104,216, 61,101, 5, 74,163,175,174,220, 20,156,171, 99, 94,180,130,216,106,194,167,233, 52, 16, 78, 96,242,
-118, 50,101,239,233, 52, 46,150,146,147, 92, 63,150,185, 68,113, 66,138, 89,187, 89, 78, 13, 69,145,123, 51, 83, 40, 26,183, 35,
- 5,124,170,215,131,156, 58, 74,156,140, 10, 88,211,210, 21,185, 5, 32,223,201,253, 69,206,157, 11,105, 79, 61,160, 46, 56,233,
-198,222, 0,120, 39,144, 37,112,133,206,237, 28, 98, 1,240,180,201,200,148,213, 84, 36, 81,165, 41,106,173,104,161, 76,144,201,
-216,169,214,202, 89, 87, 37,222, 22, 44, 66,112,190, 76,203, 20,168,114, 91,221,214,154, 68,207, 76, 74, 48,179,228, 96,165, 39,
- 30,176,171, 68,123, 44,112,194,122, 49, 32, 51,139, 4,169,153,113, 55,149, 53, 43, 96,126,135,180,172,202, 2, 92,152, 11,176,
-175,244, 38, 96,237,135, 73,115,119,152,140, 8,124, 27, 48,129,170,224, 11, 73,150,107,218,149,222,119,192, 76, 19, 8, 22, 53,
-198,221, 57,207, 94,151, 78,185, 49,157, 87, 86, 35,188, 61, 42, 29, 0, 21,214,186,103,207, 93,112,252, 60, 19, 45,103,246, 27,
-228,138, 13,113, 58,124, 86,108,212,160,169,200,221, 8, 12,148, 47,105,146, 19,102, 4,225,189, 15,113, 64,122, 89, 36,141, 74,
- 16, 67,101,202,221,232, 19,248, 24,208,105,169, 30,187,210, 2,166,215, 25,125, 41, 22, 51, 72,224,229, 8,148,106,104,219, 75,
-209,126, 20,239,129,211,123, 72,132, 0,151,180, 3, 0,151,192,114, 68, 1,112, 20,219,192,147,231,246, 86,147, 53,119,228, 57,
-181,200,177, 12, 15, 54,166, 85,191, 46, 43, 91,255, 57,168, 27, 60,133,237,189, 77,215,194, 31, 68,232,105, 95,150, 35,109,208,
-238,228, 34,226, 66,153, 43,224, 0, 79, 89, 4,148,180,194, 84, 14,224,190,213, 14,180,180, 70,137,176,109,244,140,191, 50,223,
-172,179,167, 83,201,255,170,181,197,146, 4, 1,141,137,145,155,221,202,144, 51,160,160,157,238, 23,123,117, 59,190, 12,207,191,
-191,122,247,195,211, 79, 63,139,229, 38,213, 54,217, 13,184, 65, 12, 96,169,138, 34,156,200,239,199,116,250, 80,210, 25, 43,168,
-148, 58,224,182, 88,161, 66,217, 60,190,151, 37, 30, 44, 57,122,186,221, 82, 81,239, 41, 59, 44, 2,199,155, 87,229, 26,117, 17,
-242,123,211,188,126,241,232,209,245,221, 19,173,111,168, 1,170,201, 68,117,116, 59, 59,127, 98,119, 56,141,222,148,150, 29,207,
- 45, 27,157,198,231, 95,252,102,155, 95,226,223,101, 57,225, 59, 61, 74, 18, 7,210, 68,135,170,128, 68,214,237,157,108, 47,133,
-113,210, 98, 5,126, 92,251, 68, 81,118,118,243,161,154,165,114, 88, 78,199,248, 30, 84,229,230,120,142,121,167,251,103, 47,250,
-253,231,157,197, 34, 54,173, 1,236, 93,203,239,127, 45,255, 92,223,222,189, 93,187,135,139,111,220,183, 95,238,212,237, 51,243,
- 38,157, 98, 58,254,249,239, 59,167, 13, 30,203,122,228,201,201,208,182,183, 15,243, 78, 70,228, 44,196,223,215, 50, 63,158, 85,
-186,215,250,241,147,215,205,220,135, 3, 30, 1,105,254, 68, 92,107,122, 10,232,188,121,123,247,213,175, 63,253,248,234,210, 15,
-223, 29, 30,254,184,112, 91,216,168,129,209,138, 80, 76,230,169, 39, 69,248, 16, 70,128,191,179, 67,209, 66, 56, 50, 40,250, 34,
- 78,121, 75, 29,133, 15,251,147, 69,125, 79,218,184, 35,222, 58, 47, 35, 50,115,213, 84, 51,177,185,140,222, 12,219, 7,129, 28,
- 51,183,147, 26, 55, 77,173,165,130,152,222, 63,248,131,108,252, 46,154, 24, 38,142,144,169,210,226,127, 83,133,253,108,230,128,
- 87,144,209,142, 29, 28, 51, 7, 32,146, 93,185, 19,186,202, 41, 10, 82, 84,238,173,102,208, 3,205, 46,101,181,144,186, 18, 2,
-182,244,213,161,200, 79,167, 61,226, 99,233, 36,253, 38, 83,155,113, 49, 26, 60,155,243, 15, 84, 86,225,144, 97,194,245, 35,192,
-206,123,100,186,124, 65,185, 42,172,109,101,219,220, 47, 64, 93, 61, 30,250,208,208, 23, 59,118, 0, 26,185,221,236,220, 56,189,
- 91, 47,133, 69, 6,117, 74,156,168, 19,138,120, 8,123,171,120, 64, 68, 51, 71, 30,100, 3,233, 94,137, 13,105,235,188,254, 39,
- 0, 73, 87,207,228, 56, 17, 5, 71,243, 45, 75,107,123, 97,119, 57,142,187, 98,171,160, 8,184, 58,130, 11, 72,200,137,136,249,
- 21,144,241,191, 72,136, 9, 73,137,142, 4,170,128,218, 58,239,221,222,122,215,178,173,145, 70,163,145,232, 54,145, 3,127,148,
- 60,154,247, 94,183,230,189,110,245,227, 79, 63, 20, 60, 71, 96,118,160, 18,197,255,198,199,243,156, 72,114,166,147, 53,166,164,
- 74,204, 73,158, 19, 73,125, 40, 34, 42,210, 40,212,201,178, 36,142,185, 4, 52,212,108,164, 5, 22,139,212,145,146,122, 38,239,
-150,150, 58,126,224, 35, 58, 0,113,240, 48, 91, 2, 92, 3,125,249,201,178, 7,134,130,125, 5,159,182,247, 20, 27,177,189,232,
-177, 78, 41, 2, 16,183,132,181,226, 56, 83,137, 44, 36, 48,238, 35,126,245,241,168, 38,221,117,209, 3,232, 81,195,173,163, 45,
-219, 16,230,208, 37, 95, 30, 99, 74, 3, 7,134,122,133, 87,142,192, 30, 1,226,228,227, 58, 35,203,187,220,163, 84, 78,214, 78,
-162, 50,165, 90,148, 40, 5,218,185,178, 30, 47,157, 54,206, 46,206, 70,178, 61, 93,210, 30,187,212, 14,247, 89, 57,194,112,131,
- 55,157,115, 64, 79,158,254, 77, 84, 23, 65,185, 52, 89, 82, 47,155,141,208,184,233,168, 39,192,227, 54, 17, 53, 50,125, 35, 29,
- 68, 70, 35,242,209,188,152, 69, 59,114,208, 13,128,100,232,203,130,179,100, 7,137, 48,207,166,231,146,230, 41,142, 3, 69,225,
-168, 8, 11, 74,154,240,217,110,211,142,158,229,112,104, 80,162, 56,191,165,192, 95,250, 94, 30, 70,242,124, 32, 27,155,170, 65,
-245,224,142,184,156, 64, 7, 5,235,180,167, 71,215,196,138, 47,100,155,163,199,150,112,212, 92,117,116, 97,161, 35,185, 17, 60,
-207, 69,121, 8,212,183, 18,212,151, 44,179, 62,195, 94, 2,180,152,145, 7, 62, 88,235,101,101,193,226, 42,246, 58, 24,127,201,
- 51,103, 91, 9, 47, 7, 11, 44,237, 28,104, 93,240,139, 51,137, 36,132,226,141, 43,116,102,169,232,126, 39,233,143, 97,214,252,
- 21, 42, 54, 98,225, 40,228,153,147, 54, 99,213,185,150,122,206,100, 20,212, 12, 65,210, 5,163, 59,207,172, 5,231, 40,156,160,
- 66, 84, 9,230,195, 64, 80, 0,206,144,162, 16,141, 74,157,122,146, 44, 27,144,240, 73, 93, 83, 12, 73,243, 96, 63, 43,237,105,
- 47,142, 90,134,172, 82,212,113,253,101,241,155, 8,127,118, 13,205,215, 18,245,169, 74,224,171,216,229,244,174, 8,143,128,222,
-132,159, 40, 59, 50,233, 83, 60,161,106,233,142,146,213, 60,193,162,198,187,155,202, 85,219,188,252,158, 81,215, 55,244,231,138,
- 21, 80, 30,101,186,133, 91, 59, 14,226,137,169,203,244, 7,170, 84,113, 48,114,151,125,185, 59,127, 37,214,215,203,208,213, 40,
-203,149, 50,238, 74, 33, 37,113, 50, 59, 0,173, 21, 97, 23,247,251,147,254, 49, 69, 48,193,148, 38,231,169, 50, 20, 82,129,139,
-198, 58,224, 63,246, 90, 42, 34,168,130, 61, 90,180,156, 20,248,183,115,195,205,193, 94,129,166,174,135, 38, 60,123,147,167,154,
-167, 72, 52, 38, 40, 68,205,190, 9,189,176,150,126, 58,154,122,202,227, 52, 63,127,177,120,253,108,245, 75,186,221,198, 54, 13,
-219,125,222,179,121, 64, 45,150,229, 85, 93, 62, 89,233,143, 62,150, 23, 87,197,229, 69, 94,129,143, 62,208,205, 98,118, 2,232,
-127, 54,170, 45, 16,142,111,239,226,221,230,248,112,127,204,199,252,116,245,225,231, 79, 62,173,174, 29,107,129,161,134,238, 31,
-191,111,126,253,249,118,119,115,253, 73,124,254,217,110, 92,197,139,104,250,215,115,252,231, 62,110, 55,105,218,168,127,111,154,
-251,219,199,102,115,184,123, 56,130, 44, 30, 14, 41, 28,198,253, 62,164, 55,233, 78,138, 91, 7,144, 46,254,158,135,171, 47,190,
-250,230,219,239,138, 80, 60,188,125,223, 35, 35, 31,103, 26,249, 8, 14, 13,139, 70,108,239,119, 79,205, 77,249,234,235,191,132,
- 87, 67, 3,202, 91,198, 97,246,115,237, 43, 59,152,109,166,154,216,194,172, 14,105,139, 85,227, 14,151, 91,153,169,152, 15, 4,
- 66, 80,193,147, 83,189,143,210,142, 29, 53, 54, 39,186, 78, 58,245, 72,109,107, 85,243, 57, 13,110, 61,248,167, 76,237,224,241,
-189,128,168,106,179,177,195,216, 1,115,209,107, 7,209, 70,211,147, 80,244,239,237,209,181,216,209, 34, 80, 67,122,110,134, 8,
-184,217,139, 54,169,128,136,110,129, 53,129,191,243,208, 1, 51,207,225, 64,133,218,204, 49,203,105, 24,230,216, 83,142,163,160,
-110, 52,226, 13, 68,201,156,244,210,133, 44,189,246, 39, 11, 36,246, 35,131,136,149, 85, 53, 1,180,231,179,218, 39, 87, 86,189,
- 34,120,118,186,226,115, 1,187, 64,100, 90,234, 24, 47, 43,211, 23,224,226,149,169,120,116, 80, 76,190, 90, 24, 57,100,231, 15,
- 89, 45,145,104, 11, 39,177,149, 1, 28,215, 64,152, 0,134, 6,149, 70, 91,112,133,201,138, 51,103, 57,187,110, 84,253,159, 0,
- 36, 93,187,142, 28, 69, 20,173, 87, 87,245, 99,102,189, 54,139,192,182,134, 0, 65,128, 16,146, 29, 16, 65, 68, 8, 9,226, 43,
- 54, 33,227,199, 16,255, 0, 63, 96,129,100,140,156, 32,132,237,221,121,236,108,119, 87, 85,215,131,115,154,108,130,213,108, 77,
-247,173,123,207,169,186,247, 28,125,253,211,117,162, 63, 53,128, 37,175,217,149,226,153, 59, 9,142,164,215,124,166,255, 6,111,
-105,144,216,217,195, 32, 41,136,209,114, 35, 71, 54,159,169,129,130, 69, 98, 21,164,166,157,142,163,155, 41, 47, 21,165,167, 3,
- 72,244,105, 48,116,240,201,156,206, 47,108, 81,151, 20,213,192,126,157, 80, 21,154,122,111,232,250,133,127,133,210, 24, 0, 2,
-193,216,185,127, 99, 30, 0,139,153,235,195, 12,112, 30,234,136, 87,124,242,160,129,121, 2, 65, 64, 73, 8,229, 20,105,181, 64,
- 89, 87,118,208,228, 35,136, 42,128, 52, 91, 43,106,206,182,191,116, 17,156,165, 45,195,220, 98, 89,194,246, 78,113,206, 6,121,
-187,147, 3,152,139,204,214,117,214,182, 75,211, 90,221, 25,212, 85,213,111, 91,219, 0, 66,169,190,215,110,117,242, 22, 60,127,
- 79,179, 69, 61,166,249, 35,160, 59,160,173, 73,132,194,154,234,152,116,166,194,247,162,158, 1,188, 24,252,132,180, 26,150,208,
-140, 57, 9,223,132, 4,194,148,183, 69,159,201,210, 2, 30,221, 56, 54, 51, 50,214, 56,115, 76, 63, 82, 79, 49,230,133,231,171,
-168,112, 88,248, 13,162,251,237,104,128,245, 29,169,222, 98, 0,171,138, 15,116, 12, 58, 45, 72,219,168,214, 78,209, 65,158,166,
- 24,192,230,116,249, 6, 66, 68, 28,123, 89,251, 6, 17, 21,117, 66, 68,118,162,207, 3,157, 95,104, 43,133,104,219, 50,191, 3,
- 1,134, 78, 40,222, 52, 73, 71, 19, 84,197, 79, 81,130,233,217,171, 22,113,202, 27,102,100,227, 70,243, 14, 12, 36, 90,139, 71,
-141,115,134,201,150,182, 69,102,233,192, 26,179, 96, 0, 47, 72,242,164,195, 54,234,117, 8, 39,226,105, 4,143,103,166, 52, 74,
- 44,223, 11,176,217, 70,240,204, 97, 66, 4, 74, 14,121, 81,109, 84,215, 13, 21,231,204, 88, 87, 49,151,132,149, 80,152, 57,160,
-130,100,208,128,213,254, 68, 8,212,122, 16,212, 74,229, 56, 21, 56, 29, 2, 70, 71, 17, 87, 54,237, 10, 14,220, 54,133,157,167,
-209,201,221, 71,230, 87,113,120, 53,157, 29,246,106, 6, 12,152,129, 16,210,249, 77,245,231,108, 64, 91,238,120, 45,174, 70, 77,
-199, 81,154,171,176, 55, 90, 83,140,152,173,158,165,173,193, 18,208,187,175,191,247,118,104,166, 59, 84,104,101, 1,138,167, 2,
-224,165, 82, 87,239,131,192,143,214,244,149, 32,104,206,248,115, 43,247,203,226,143,110, 87,212, 39, 87,229,221,112,121, 78, 60,
-184, 43,236, 9,138,137,158,216,243, 33,205, 19,105, 2, 13,150,200,224,232, 34, 92, 86, 73, 98,213,177,217,137,182, 57, 88, 3,
-155,103,121,136,158,177,221, 52, 39,220, 21,246, 69, 80,245,189, 12,160,218,129,200,124,252,106,150, 23,203,105, 1,234,176,190,
-177,188,161,167,216, 8, 77, 18, 43,141, 47,176,104,181,253,172,251, 89,157, 94,248,125,204, 99,168,126,145,219,139,238,233,251,
-253,147,157,120,114, 85,183,143,107,143, 72,235,106, 72,210,223,214,124,164, 17, 1, 54, 47,246,249, 57,199,127,227,205,221,178,
-191, 25,151, 51,229,146,118,159, 14, 31,124, 62,228,135,128,166,148,223,255,235,143,195,111,191,188,254,251,229,213,179, 47,174,
-191,249,238,199,241,112,251,251,203, 63, 95, 59,115, 20,242,230,190,220,158,195,219,131,255, 39,236,239,154, 80,102, 6,225,205,
-180,128,248,164, 16, 78, 7,106, 62,109,204,170,250,239,211, 67, 45,142, 98,122,177,247, 79,191,250,242,249, 15,223, 74,189, 57,
-133,116, 58, 28,242,129,221, 18,216, 96, 23, 88,209, 70,140,199,248,225,229, 3,253,120,247,110, 79,139,112, 5,156, 70, 92,128,
-215, 48, 81, 56,163, 87, 73,205,247, 96,182,173,161, 82,238, 60, 12,117, 40,205,130,200,153,114,157, 27,133,148, 88,226,158,174,
-227,165, 73, 26,220,215, 0,190,156,115, 23,138, 55, 11,192,114, 30, 23,149,179,167,149, 45,219,148,221,204,153,201,189, 54,216,
- 72,140,138, 49, 46, 32,109,188,180,194,250,251,201,142,235, 80, 86, 70,189, 10, 35,144,102,164,162,213, 38,205,245, 24,153,218,
- 57,199,193, 51, 87, 68,154,164, 63, 89,101, 14, 84,171, 36, 84, 70,238, 51, 20, 86,167,182, 91, 90,149,215, 44, 7,191, 42,216,
-156, 51,185,105, 9,196, 6,121,201,195, 98,217, 25,195,243, 91,163,186, 65, 91,171, 55,194, 36, 3,184,165,122,222,152,129,139,
- 56,101, 75,239, 93,179,165, 12,140,165,172,147,105,255,119,167,213,106,200,242, 65, 92,203,163, 5, 12, 1,155, 87, 36,146,174,
-145,128,136,165, 5,130,167, 74,145, 55,143, 46,254, 19,128,163,107,217,145,155,136,162, 85,229, 71,185,220,246,116,102,144,134,
- 33,137, 80, 2, 1, 33,194, 2,101,195, 50, 31,193,142, 95, 64,145,248, 9,254,129, 15,128,111, 96,133,196,130, 21, 43,118, 72,
- 44, 2, 8, 36, 80,166,103,104,119,251, 81,174, 39,231,120, 61,173,110,143,125,239,173,115,124,239, 61,167,120,245,213,151,220,
-160,166, 29,185, 47,184, 12,133,208,107, 81,196,192, 28,132,216, 52, 15, 56, 36,141,216,110, 40,244,152,185,112, 4, 48,196, 97,
-213,228, 16,106,117, 97, 45,202, 62,165, 0, 45,176, 38, 23, 61,179, 75, 20, 12, 9,124, 3,132, 96,106,184,165,185, 2,215,197,
-172, 17,238,202,109, 78,133, 19, 95,238, 56,110,252,161, 94, 59,250, 79,200,105,108,164,154,173, 13, 3, 29,187, 98, 70,169,204,
- 51,210, 44, 31, 66, 4, 27, 90, 23,207,158,148,141,238,108,113,107,231,120,118, 11,202,163,176,126,105, 86,195, 75, 87,172,173,
-192,129,156,211, 71, 33,178,177,246,253,174,171,226,133,238,246, 50,106,217,148,251, 30,229, 27,192,102,155,249,219,237, 80, 17,
-141, 74,109, 91,181,101,131,219, 84,211, 36,219,111,222, 21,194,225, 95,107, 13, 62, 13,170,153, 52,128,116, 40,183,141, 65,220,
-171, 92, 14, 59,101,182,185,163, 53,209, 6, 62,178, 43,199,189,128,200, 46,131,163,111,170,164,121,205, 82, 44,173,147, 35,202,
- 49,151,246,195, 50,117,224,113, 96, 33,163, 72, 67,133, 66,100,157, 27,212,148, 38, 31,231,132,144,158, 36, 74, 24,101,214,193,
- 93,132,175,142, 8, 49,252,140,116, 5,135,117, 52,241,171, 0, 19,198, 9, 23,216, 33,197, 83, 76,213, 74,217,126,202,145,128,
- 41,136,154,155,101,180,220, 40,248,166,110,229, 36,106,141, 36, 3,162,168,148,102,215,122,115, 41, 90,185,226,225, 13,181,103,
- 90,132,103,169, 40,126,149, 84, 11,148, 80,104,196, 72,119, 69, 17, 73,124,103,195,182,115,204,198, 52,133,236,155,194, 84, 37,
-149, 55,118,117, 85,248,142, 94, 6,220, 68,102,119, 28,136,169,106, 1,188,113,129,154,246, 21,218,139,178, 54, 96,192,179,177,
- 93, 84, 43,190,219,200, 35, 39,124, 50,209, 0, 30, 40,237,126, 35,187,169,113,147,219, 44,195, 54,206, 68,195, 1,240, 9,196,
-150, 24, 29, 80,145,108, 53, 40,164,163, 61,131, 11, 37,167,212,220, 38,132, 14,170,212,251, 18,232,127,127,169,234,119,203,239,
-237,249,159,101,208, 8, 15, 0,172, 25,129, 49, 81,112,146, 32, 99, 84,209, 82,201, 38,132,144, 8,194, 10,101,203,190,200,149,
-147,148,122,225, 19, 83,170,119, 56,198,218, 79, 95,156,202, 27, 36,114, 41,150,182, 1, 1,147, 76,187, 2,101,174,161,146,175,
-146,192, 90,174,226,190,242,182,150, 72,253,241, 28,110,239,202,107,145, 63,185, 49,101,106,150, 52,115, 36, 34, 41, 96,196, 99,
- 24, 15, 28,202, 5, 58,218, 84, 9, 19,119,173, 90,148, 58, 18,227,205,236,132, 94,153, 84,101, 88,212,230,101, 76, 23, 99, 69,
-139, 6, 89,109, 43, 38, 8,167,120,108,196,237,226,222,127,157, 30,246,213,152, 4,200,145,103, 79, 48,119,148,213,151, 11,135,
-161,104,179,240,248,163,254,215, 7,254, 71,123,154,232,214,219,154,230,233,147,250,189, 71,242,250, 50, 24,147,144,146, 43, 82,
- 19, 64,244, 32,214, 99, 84, 7,246,116,113, 92, 77,148, 78,115,247,241,246,110, 25,254, 29,242, 93,234,250,246,209,243,203,254,
-130,250, 78,160,166,211, 97,248,233,135,223,255,251,229,234,249,103,175, 94,126,241,205,219, 47, 63, 95,220,155,239,190,253,250,
-207,187,243, 95,193, 15,179, 58,158, 7,142, 25, 69, 55,156,252, 69, 89,237,189,208, 6, 97,150,140,174, 31,104,249,198, 89,135,
-180,106,138,123, 27,246, 82, 94, 93,152, 15,122, 45,198,211,207,191,189,126,250,226,195,221,199,207,246, 15,223, 49,166, 27, 78,
- 71,115, 63,113, 19,175, 46, 8, 9, 1,173,215, 63,174,158, 60,254,123,247,172, 60,222,198, 14, 73, 72, 85,185, 28, 98, 33,141,
-211, 81, 89, 32,217, 90, 39,201,166,194, 5, 85,108, 61, 93, 52, 19,162, 93, 35,255,150,102,223, 54, 56,104,156,223,228,111,179,
-179, 56,234,112, 0, 44, 18,151, 18, 0,232, 23,156, 67, 32,111,249,132,162, 25,194,110,244,171, 94,236,168,215,181,228,194,196,
-166, 76, 55, 38,234, 71, 39, 64,212, 33, 78, 20,144, 89, 44,254, 12,120,142, 83, 32,211, 55,100,162, 15, 12,109,253,124,246,241,
- 94, 82,137,139,102,100,142, 94, 54, 20, 71,149, 32, 88, 72,124, 7, 98, 12, 78,141,232,173, 42,182, 60,184,179, 64,119,206, 26,
-183,133, 38,245, 34,130,248,218,230,186,245,243, 91,217, 36,154, 97,128, 12, 87,155,119,101,121,115, 89, 32,135,104,122, 36, 22,
-141,223,171,245, 78, 54, 32,204, 56,124, 64,191, 53,145, 63,178,180, 6, 52, 21, 42, 21, 29,194,128,136, 47,225,234,144, 58, 57,
-236, 98,155, 77,220, 38, 62,234, 57, 90, 37,254, 23,128,164,107,217,145,156, 8,130,229, 42, 87,185,108,183,167,187, 25,134, 5,
- 1, 43, 33,208, 74, 92,144, 0,241, 3,112, 65, 92,248, 3,238,156,249, 6,126,130, 31,225,192, 1, 9,137, 3, 72, 35, 36,184,
-176, 11, 2,193,176, 8,137,153,157,238,182,219,174,151,203, 68,152,235, 28,102,198,229,116,102, 68, 86,102, 68, 25, 43, 2,189,
- 85, 51, 67,243,203, 91, 71,183, 4,149, 6,144,176, 42,191,204,150,243,126,212,130,159, 57,166,142,239, 74,209,151,151,147, 47,
-194,173,134,116, 11,128, 16,105, 82,157,153,198, 2,101,101,104,194,100, 50,125,116,204,232, 36, 48, 13,231,227, 51,173,164, 10,
-205,171,146,188,238,117,210,188,215,142, 29,165, 30, 29, 75,225,156,109,112,139,175,150,244,204,157,103,223,233, 57,158, 18,251,
-179, 81,251,233,112, 22,118, 63, 0,137, 4,240,167,150, 38,226,212,139, 83, 78, 4, 59, 14, 69, 97,199, 98, 76, 1, 53,200, 38,
-121, 39,240,199,151,171, 75,117,235,172, 71,121,167,134,108, 93,169,100, 81, 63,216, 86, 47,184,229, 99, 27,105, 74,246,188,204,
-210,225, 95,104, 27,112,102,160,155,162, 65,192, 80,111, 66,208,228,158,171,100, 72, 15,186,217, 0,187,159,145, 41,123,112,122,
-131, 66,145,153, 67,227, 50,227,220, 74,130, 41,218,210,100,226,183,180,148,255, 47,238, 18,158,208,247, 71,244,153,238,131,129,
- 38,190, 17,164,105,108, 68,133,135, 88, 38, 71, 11, 43, 80,170, 98,147,242, 57,205, 49, 75, 78,128, 57, 20, 83, 26, 73,184,245,
- 38, 35,241,248,169,185,227, 22, 70, 70,149, 12,160,215, 58,255,156,232, 88, 8, 60, 76,249,228,222,212, 23,105,159,232,240,212,
-164,213, 18,131, 25,172, 86, 72,221, 26,193,166, 27,159,120,131,209,181,212,171,162,231,121,106,132, 68,152, 32,180, 0,232,207,
- 22, 37,101,245,187,208,212, 90,181,136,191, 25,169,166,176,178,118,148, 60, 68, 78, 2, 36, 0,247,212, 58,230, 46,166,165, 10,
-231,118,109,118,162,222, 36,237, 81,234,253,152,230,154,243,168,106, 48, 26,184, 37,143,231, 61,162,146,130,166,198, 18, 8, 80,
- 78,142,125, 38,145, 15,138,125,134,133, 93,186,130,189,192,137,110, 29, 28,190,146,156,144,210, 19,133, 20,212, 11, 52,231,148,
- 17,217, 41, 88, 80, 62,103, 15, 82, 59,206,106, 21,173,201, 32, 64,249,130,162,194,205,102,233, 69,241, 52,158,193, 57, 39,142,
-115, 5, 66,207,105, 0,122,206,113, 42, 42, 4,156, 76, 43,157, 18, 73, 68,164, 94,208,215,101,212, 14, 28,103, 55,107,182,196,
-103, 5,236,209, 2, 27,221,163,232, 13,179,218,230, 85, 75,202,112,141, 22,224,218,251, 75, 61,247,154,155, 33,120, 92, 3,186,
- 84, 58,174,240, 48,238,192, 47,211,241, 31,249,198,239,211,123,175,109, 79,179,249, 69,132,151, 40,102,146,142, 75, 24, 64,146,
- 41,101, 69, 15,220, 44,117,203, 33,244, 2,181, 24,191,121,108,230, 43,179,146, 21, 60,166,226,246,175, 71, 49,160,111, 76,156,
-115,239, 77, 93, 19, 47, 20,157, 16,207,172, 24, 42, 86,193,181,125,166, 3,168, 89,173, 71,228,129,140,144, 32,222, 71,249,168,
-175,138,239, 69,255,107,118,109,181,123, 32, 94,233,196,126, 11, 6, 76,245,203,116, 82,248,170, 51, 47,173,241,156, 56,105,222,
-167,121, 11, 86, 18,220,236,255,141,253,237,208, 39,198,232,243,175,214,219,231, 76,107,241,142, 74,163,252,147,199, 39,247, 91,
-249,250,203,159, 63,250,228, 51,177,171, 86,187,101,113,255,243,183, 79,110,254,126,247,163, 79,135,175,190,120,113,187,125,236,
-203,211, 48, 87,109, 52, 21, 14, 65,253,116, 63,221,114, 61,197,227,160,246,170,196, 91,124,103, 79, 21,196,155,232,235,174, 6,
-196,219, 86,197,195,174,188,190,249,243,250,203,239, 62,248,248,253, 63, 46,132,122,235,205, 43, 85, 78,223,124,189,220, 29, 39,
-132,205, 6, 20, 43, 63,253,235,240,240,250,199,183, 63,124,244,195,240, 32,164,163, 46,229,221, 81, 90,189,193, 75, 83,147, 55,
- 92,249,180, 39, 57, 10, 35,245, 68,169,219, 75,165, 78, 85, 14,148, 70, 87,147, 28,109, 84,129, 58, 59,188,192, 51,217,244,131,
- 97,198, 77,121, 60,220,210,244, 0, 36, 48, 24,176,105, 55, 58,112, 35,100,242, 20,216, 89,200,224,193, 25, 68, 60,202, 73, 90,
-135, 40, 14,139,227, 72,225, 28,152,230,210,168,165,149, 14, 85, 4,217,144,151, 51, 62,244, 6, 4, 10, 63,163,235,176, 1,153,
-165,112, 88, 66, 58,198,103,203,188,140, 51,148,209, 22,158, 46,101, 69,236,193,160, 81,252,180,216,108, 27,164,199,179, 15,157,
-173, 0, 15,180, 6,252,158,230, 49, 82,249,160, 22,193,109,154, 72,130, 60, 81, 98, 16, 52,212,130, 17, 70,111,229,218,243,166,
-122,175,218,118, 85,179,171,166, 35,240, 46,237, 18,145,119, 19, 34,190, 92, 23, 23,202,112,206, 23,188,221, 42,115, 46, 26, 4,
-135,140,106,220, 32,131,238,112,102,255, 9, 64,211,181,236,202, 81, 67,193,182,221,118,187, 31,119,238,220, 7, 34,143,139,128,
- 8,129,196,134,108,216,160, 32, 16, 95, 1,251,252, 1,226,111,248, 8,150,252, 3, 18, 43, 22,144, 13, 27, 18,146, 12, 34, 51,
-211, 79,187,253,160,170, 35,102,123, 71,234, 59,110,251,156, 42,159,115,170,212,211,239,159,114,138, 60,109,166,216,108, 76, 11,
- 70,112, 56, 39, 83, 68, 13,129,217,131,118, 96,223, 9,254,125,155,251,165,197, 18, 65, 73,193,126, 23, 33, 56, 45,136,112,181,
-224,188,128,159, 47, 66,211,177, 4,132,212, 1,215, 57,128, 10,145,231,134,150,143, 84, 74, 91, 37,160, 42, 98,226,234, 69,177,
-132, 81,110,141,152,192, 19, 14, 24, 41, 96, 61,166, 19,150,188,247,116, 88, 73, 72,161, 38, 13,209,245,193,106, 55, 45,105, 2,
- 59, 91,227,208, 59,234,232,249,145,221, 1,163, 90, 84, 95, 80,164,202,129, 8, 8,111,117,105, 68,147, 76,141, 61, 97, 27, 48,
-135, 86, 85, 70, 95, 52, 1,176,175,193, 18, 91,144,124,181,179,134,205,138,183,123, 28,174,198, 0,127,104, 94, 92,217, 76,115,
-185,170, 51, 34,212, 66,128, 35,237,105, 8,195, 25,123, 33, 89, 14, 4,185, 97, 45, 28,121, 49, 16,125, 33,139, 50,232,225, 84,
-226,235,177,164,226, 23,150, 21,180, 44,225, 9,179, 4,216, 34, 66, 68,120, 77, 37,248,136,228, 3,138, 48,155,209, 47,200, 57,
- 65, 12, 0,111, 57,142,242,168, 54,180,207,238, 55,154,162, 58, 17,230, 55,160, 12,103,130, 84,207, 57, 84,132, 70,191, 56, 63,
-143,136, 13,101, 61, 1, 6, 47,148,126, 3,120,174,233,198, 69,199,114, 75, 10, 65,109, 39,154,234, 5,176, 61,250,179,151,121,
-160,209, 26,171,104, 88, 24,139,192,203,106,113, 81,123, 45,111, 20, 30,168,129,209, 17, 84,178,234, 16,100,140,236, 52,104,178,
-108,141,183, 23,165,139, 84, 36, 51, 72,208,187,210, 82, 75,146,213, 7, 11,160,109, 40,233,135, 52,145, 86,124,167,234,150,197,
-242, 6,156,109,198,117, 64,190, 44, 41, 42,152, 65, 70,107, 49, 87,244,225, 35,192,160, 57, 14,184, 44, 87,133,126,242,108, 22,
- 51,234, 66,187, 5,236,204, 21,111,141,157, 64, 42, 88,243, 5,147,165, 91, 84,136,188,250,163, 55,120,142, 28, 89,166,123, 59,
- 64,109, 27, 82,179,233, 35,129, 6,120, 86,125,134,243,152,174,179,186,183,254,188, 0, 40, 2,201,141, 96,231,153,158,227, 47,
- 83,152, 83,209,227,151,135,173,237,159, 29,190,180,105,243,155, 26, 9, 86, 77, 81,130,207,110,149,165,216, 17,129,117,143, 62,
-113,183,159,169,241,181, 98, 23, 87,146, 96,192,145, 29, 55, 6,167, 20,107,104, 40,172, 87, 58, 16,136, 64,211, 39, 14,182, 35,
- 40, 32,142, 44,170, 58,156, 78, 87,119, 53, 98,249, 75,159, 86,150,182,252,236,166,153,119, 98, 64, 9,111,109,169, 86, 44,237,
-186,153,231,208,120, 21,201,129, 74, 37,172, 69, 8, 74,165,241,174, 9,233,216,177, 28, 64,115, 56,170, 76, 9,150, 65,142,201,
- 63,254, 35,190,191, 51, 7, 34, 78, 78,132,208,193, 10,240,169, 86,141, 40, 16,225,242, 67, 49,222,243, 63, 5,188,222, 15, 30,
- 21, 15,154, 92, 97, 85, 70,129, 51, 52,142,217, 71,217, 15,156, 28, 47,105,238, 64, 72,224, 57, 17,158,250, 98, 58, 47,224,191,
-231,193,219, 32,174,118,237,245,245,165,190,228,252, 4, 8,216,179, 95,142,243,139, 79, 63,250,230,199,135, 95,125,199, 98,244,
-255,159,139,155,251, 95,124,252,249,151,223,254,112,122,246, 91,173,219, 55,203,244,207,120,188,191,171,251, 34,252,250,124,248,
-115, 8, 67,140,115, 84, 71, 39,254,157,200, 88,170, 74, 29,114, 4,167,123, 96,101,107,243,135, 87,205,221,190,251,235,197,241,
-247,195,240,228,235, 39, 8,253,175,252,144,223,121,247,246,230,118,122,254,170,236, 39,240, 17,225,176, 87, 11,219, 31,222,187,
-203,127,223, 61, 62,245, 71,157,231,213,156,218, 61,128, 17,248, 36, 80, 91, 69,160, 27, 52, 64, 32,248,216,233,114,117, 78, 79,
- 56,139,116, 92, 66,176,117,217, 81,196,215, 11,142, 17,175, 42,204,196,117,156,110, 11,253, 72, 51, 0,236,207, 49,206,120,204,
-121,196,127,120,164,220,172, 73, 98,112,243,196, 38, 38, 78, 91, 15,175, 7,214,195,168, 11, 22,129,207,241, 54, 67, 73,237,115,
- 80,167, 72, 75,189,232, 1,233,144, 36, 41,216, 68,159,114, 65, 7, 3, 31,100,169, 13, 2,133, 80,178, 9,244, 67,136,236, 58,
- 4, 62,145, 32,115, 85, 99,128,178, 52,246,199,202,193,121,108, 63,228,232,102,218,215,120,137, 66,239, 28,222,206,117, 83,167,
-182, 40,106,131, 80, 46,140,170,120,169, 41,101,103,227, 90, 86,109, 77, 69,214, 18,167,100, 62,171,203,149, 93,236,179, 7,179,
- 86, 43,229, 95, 65,202,187,196,238,198,128,231, 47,109,157,116,147,149,245,125,170,129, 1, 74,206, 75, 80,214,252, 63, 1,184,
-186,118,221, 72,138, 40, 90,213, 93, 93, 85,221, 61, 61,158, 25,219,194,130,149,144, 16,114,178, 34, 0,137, 96,191,102, 3,126,
-131,156,239, 32,216, 95, 64, 36,155, 35, 33, 2, 2,136,144, 44, 12,171, 69,182,199,179,211,211,207,122, 53,231, 12, 25, 14, 28,
- 89,154,113, 61,238, 61,231,214,189,231, 96, 23, 85,118,150, 55,160,214,187,162, 86, 36, 88,154, 91,102, 5, 40,164, 20,254, 18,
-159,192, 9,153,179,131, 43, 45,229,169, 66,131,223, 6, 73,194,251,145, 30, 76, 41, 15, 97,240,136, 32,225,236,211, 71,224,122,
- 92,248, 36,160,193, 77,198,188,152, 8,225,112,113,129,195,123, 42,251,101,245, 89, 35, 88,142,211, 17,161, 92,209,133,111,118,
- 8,139, 76,148,241,191, 6,242, 49, 0,102, 12, 52,141,201, 91, 22,177, 63, 0,248,251, 57,105, 0, 16,208,128, 89,207,212,133,
-193, 38, 1, 55,151, 71, 22,124,231,221,180, 43,118, 1,244,202,136,181, 47, 79, 73,110,189, 51, 27,217,217,143, 46,217, 65,110,
- 74,112,154, 32, 83,101, 64,152,202, 80,216, 88, 0, 9,204,165,210, 61, 18,106,152,155, 85, 53, 98, 15,177,238, 3,165, 56, 65,
-196, 44,171,199,188,107, 8,155, 99, 9, 6,202,247, 48, 45,140,244,200,119, 52,206,241,121, 2, 34,156, 40,132,165, 82,228, 12,
- 15,152, 16,104,224,228, 43,201,162,211,172,168, 97, 4,252, 8,132,178, 60,118, 14,144,174, 74,241,106, 73,173,197,193,235,193,
- 52, 69, 31,145,194,146, 26,249,172,246,152,229,187,195,232, 87, 89, 40, 77,209, 77,157,138, 93, 39, 53,176,246,108,105,178, 45,
-129, 55, 22, 78,165,138,128,240, 7, 60,167, 34, 8, 0,190, 57,168, 81,198, 87,141,200,234, 69, 81, 82, 16, 97,227,243,231, 64,
- 27, 30,172,101, 42,113, 35,104,166,101,207, 94,137,180, 97,233,249,120, 86,169,120,188, 48,174, 94, 26,234, 6, 21,193,196, 83,
-216, 94,251, 44, 47,105,252, 94, 88,211,118, 69, 46,253,182,241, 54,242, 85, 55, 17,248,203, 54, 83, 26,233,170, 74,170, 75,251,
- 41, 27, 70, 63,150, 26, 96,191,201,188,148,211, 52, 79, 6,119,160,186, 86, 0,210,233,220,175, 32,106,225,132, 70,178,197, 1,
- 15,235,180, 84,160,195,145,131, 31, 77, 29,143,132, 10,162,202,217,107, 67, 49, 67,195, 38,206,224,179, 52, 45, 77, 57, 35, 55,
-120,250, 17,159, 39, 54, 17, 57, 65,248, 22,246, 92,181,156, 93, 23, 85, 93, 54, 8,190, 8, 97,164,131, 29,142,103, 74, 99,232,
- 15, 68,241, 88,160, 83, 34,132,230,201,158,151,213, 9,204, 71,184,140, 53,245,149,197,102, 81,161,243, 84,120,157,115,250,111,
- 25,196,216,142,115,115, 17, 70, 62,208, 40, 44, 44, 32,146,114,132,201, 72,154,124,175,161, 78,159, 52,236,220, 25,128,235,196,
-108, 84, 61, 7,100,158, 98, 16,237, 40,251,251,225,234,179,230, 34, 95,246,180, 21,230,123,113, 92,172, 97,251,190, 64, 60,178,
-140,242, 57,237, 37,176,159, 1,217, 77,239, 57,131,193, 70,106,169, 78,153,199,237,165,150,169,137, 89,206,139, 70,217,183, 10,
- 11,144,225,184, 80, 84, 63,114,116,103, 41, 44,245,249,129, 34, 16, 5,144,122,176,133,117,116, 47, 46, 55,191,136,221, 83,136,
-159,178,121,225,216,139,113,144, 19, 66,198,128, 27,157,107, 35, 44,168, 59,197, 69, 50,154, 34,231, 4, 15,147,155, 78,209,117,
- 62,246,131,240,198, 94,235,237, 77,129,204,149,234,126, 60,140,119,191,118,141,249,230,139,215,223,138,245, 70,252,239,231,249,
-233,135, 31,223,252,241,253,119,211,244, 92,246,203,253,126,196,183,197, 10,220, 63,248,127, 90, 87, 84,154, 93,206,248,183, 61,
-251,132, 91,183,252,182, 31,191,220,230, 55, 86,183, 62,126,158,153,175,175, 54,229,174,249,253, 93,247,230,253,187, 63,239, 30,
-110, 63,249,234,222,189, 61,100,195,205,203,219,250,239,191, 30,222, 62,173,135,100,183, 52,228,122,192,253,253,233,231,219, 23,
-175, 14,155,143,211,254,174,193,177,154, 0,216,240, 97,195,123, 33, 54, 28,125, 43,115,211,105, 62,165,217,149,142, 71,196,111,
-151, 77, 44, 90, 39,199,206,168,146,130, 78,189,100,174, 72, 33,206,126, 40,214,149,217, 14, 51, 0,123, 0,226,226, 27, 39,229,
-183,117,225, 30, 89, 38,148,165,183,115,234,112,172, 99, 88,251,202,184, 98,204,219,180, 18, 44,250,103,200, 34,174, 75,100,202,
- 22, 24, 74, 3,211, 79,103, 39,162,108,194,153,167,134, 46, 96, 19,224,178,230, 84, 29, 13,179,138, 33,168,197,168, 75,197,161,
-112,195, 82, 8,141, 74,147,236,139, 34, 67, 80,187,148,186,168,245, 0,194,186, 1, 61,247,214, 54,185, 14,186, 27, 18, 71, 73,
- 27, 87,167, 18,121, 37, 74,186,208,158,107,174,235, 24, 74,210, 90, 86,121, 38, 36, 15, 47,125, 72,101,189,194,127,178,232,106,
-150,147, 40,129,249,102,251,193,138,161,114,102, 94, 10,132, 81,160, 62,179,106,129, 31,133,187,112, 54,101,203,250, 95, 1,152,
-186,146, 29, 73,106, 40,232, 37,157,118, 46,213,217,203, 76,183, 70,204, 5, 46,160, 65,220,184,207,127,112,227, 87,248, 48, 14,
-240, 1,128,132,232, 3, 18,210,128,104, 24, 70, 51,189, 84, 58, 51,189,164, 77, 68,113,225,214,151,234,172, 74,251,189,136,176,
-223,123, 1, 78, 31,217,130, 78, 50, 69, 59, 15, 14,149, 62, 53, 90, 58, 33,103,236, 75, 54,139, 88,252, 79,231,198, 53,213, 22,
-120,216,176,115, 55, 41,223,212,182, 21, 60,133,165, 11, 20, 72,142, 90,211, 78,111,172,204,241, 31,144,165, 34, 37, 58, 89,128,
-147, 58,246,145, 88, 69, 91,119, 96,193,182,157,156, 56, 0,144, 96,199, 42, 70,218, 38, 55,146,253,230, 76,144,241, 41,131,205,
-248,251,153,248,205, 19, 76,229,232, 34, 93, 3, 21, 70,142, 58,204, 18, 1,247, 94, 38,224,129,195,147, 57,169,214,134,118, 40,
- 13, 8, 92, 49, 45,226, 1, 26,215,109,231,187,243, 3, 18,195, 24,215,234,117, 29,167, 44,250, 11, 54, 49,103, 61,129,132, 34,
-217,153,243,103,141, 69,144, 79,244,252,163,132, 25,104, 63,206,102, 39, 4,219,220,234, 78, 3,223,193,210,120, 27,110, 78,190,
- 35,228, 86, 14, 50,177, 0,255,218,198,200,141,243, 20,138, 57, 93,218,241, 44,144,238,199, 45,136,134, 8,216,132, 15, 0,202,
- 64, 35,156,140, 53,227,153,158, 76,118, 93,115,186, 55, 53, 1, 39,188,125,194, 46,170,200,226,206,107, 40,164, 61, 8,154,104,
- 92,141,235, 49,149,101,231,105, 54,176, 30,204, 87,174, 60,189,169,197,235, 61,110,147, 43,155,110,116,162, 62, 79, 16, 69,131,
-198, 51,247, 3,178,210, 62,176,216, 23, 52,109, 77,174,121,192, 87,113,249, 52,252, 79,106,236, 58,133,149,195, 39,164,161,230,
-108,227, 51,218, 58, 47,166,155, 56, 42,155,188, 72, 15,197, 92,226, 51, 17, 0,114,178,117,170,107, 97,113,166, 11, 54, 7,187,
-141,216, 60,245,160,155, 68,239, 25,131, 84, 69, 19, 73, 36,122, 44, 84,191,216,253, 12,121,147,151,160,106, 66,148,213, 0, 24,
-245, 62,229, 30,200,232,138,228,125, 3,248, 66, 89,149,237, 36, 22,144,189, 67, 60,186,138,161,148,145,242, 23,152,104, 99, 5,
-114,131,156,130,102,236,189,221,161,164,130, 48, 81, 82,152, 24, 22, 31,225,165,106, 94,114,183,156,213,138,156,221, 89, 32, 35,
-199,249, 66,122, 63, 36, 90,242,106,150, 3, 20,209,121,181, 96, 33,158,196,164,120,224,229,144,232, 19, 53, 50,163, 45,139,220,
-139, 99, 16, 91, 66,140,178,200,119, 85,217,181,136,221,181,252,241,198,121,105, 60, 77,100,164,177,120,163, 29, 4,188, 42,167,
- 42, 68,232,161,238, 36,226, 72,236, 14, 13, 88,249, 0, 98,225,140, 60,221,137, 94, 52, 78,190,139,207, 63,209,215, 85,255,201,
-176,201, 52,181,227,245,176, 61,130,168, 10,122, 41,178, 55,171, 58,104,113,192, 87, 91,163,201,141,231,124,122,144, 18,108, 49,
-188,189,116, 86,186, 72,138,159,163,224,176,122,169, 13, 84,132, 1,225, 75,136, 25, 14,195,247, 28,156, 32,198, 14,192,215,232,
-101, 7,207, 31,175,229,227,185,187,141,219,117,156, 55,164,117,205, 26, 19,252, 48, 48,127,228, 9,222, 97,112, 82,156,230,109,
-120,222,240,219,119,245,180,198,108, 83,242,235, 81,132,251, 52,156,155,209, 86,200, 0,217,135,251,187,237,237,175,195,139,143,
-191,121,249,250,235,255, 37,117,174,198,127,127,173,127,255,243,221,143,223, 47,199,245,213, 52, 33,190,156, 6,243,147,155,140,
-126, 91,131,148, 7,164, 43, 58, 50,107,122, 26,211,121, 75,190,155,203, 93, 91,134, 75,245,226,178,127,253,252,101,119,211,139,
-248,120,115,165,247,219,250,243,221, 79,159,126,246, 10,244,102,121, 88,222,222, 36,245,229,231,239,127,248,197,205, 15,217,209,
- 13,218,118,249,254,205,219,143,110,191,189,250,226,171,223,126,151,237, 25,244,189, 1,151, 50, 37,158, 33,127, 29,172, 93,216,
-223,128, 5, 87, 62,254, 21,131, 82, 78,181,121,207,250,105, 93, 56, 35,140,198, 18,144,137,169, 84,239, 74, 40,122, 12, 49,244,
- 96, 16,205,188,207,188,202,139, 64,183,144,123, 36,111, 53,206,237,190,127,224,100, 2,250,143,218, 92, 23, 39,183,194,106, 80,
-253,184, 44,245,216, 66,164, 7,139, 39,171,147,223,134,140,153,163,216,157,112,162,151,155,209, 22, 66, 14,248, 31,229, 10,157,
- 66, 7,115,137,180,126,232, 55,185, 64,210, 98, 99,133,193,184,182,233,117, 64,194,181,213, 22, 35,244, 33,157, 33,163,151,126,
-234,179,153, 89,206,203, 49,253, 88, 39, 55,169,163, 10,108,147, 76,170,101, 23, 58, 68, 90, 87, 56,218, 89, 34,174,134,130, 87,
-108,141,205, 45,107,124, 23, 95,186, 14,105,101,230,209,126,144, 37,142,229, 16,140,241,132, 87,214,102,123,127, 49, 76,143,226,
- 74, 67,160,114,248,112,253,240,175, 0, 84, 93,193,174,227, 52, 20,181, 29, 59,118,146,166,125,237,155,167,209,240, 22, 8, 36,
- 70, 72,136,145,216,204,158, 15,152, 21, 31,197, 87,241, 3,179, 64, 26, 88, 33,216,176,123,204, 43,180, 77,211,196,142, 29,103,
-206, 9, 11, 68,183, 85,165, 52,182,239, 61,231,250,222,115, 88,153, 43,214, 6, 53,236, 77, 79,183,135, 98,157,236, 67, 28,161,
- 53, 76,163,156, 31,241, 20, 44, 90,210, 43,147,125,141,201,101,124, 79,107,100,250,226, 1, 30, 16,114,241,138, 14, 71,193, 38,
- 32,231,114, 18,173,158, 78,192,192,195, 58,139,142,181,239, 51, 96, 67,110,129, 34,188, 28, 3,171, 94,134,147, 2,156, 66, 88,
- 60,169,179,164, 28,200,114,185,122,203, 30, 29,112,209,148,220,177, 79,136, 60, 28,144, 12,121,210,212, 44, 9, 71, 29,104,177,
- 78, 85,148,222,184, 6,236,153, 55,235,203, 48, 24,182,230,148,153,243, 0, 69, 52,117,139, 45, 87, 23, 21,112,102, 94,246, 15,
-205, 60,123, 68, 31,171,220, 0,228,142, 4, 96, 65, 75,118, 75,140, 14, 9,100,107,212,137,109, 77,115, 99, 13, 98,195,200,129,
-114, 32, 95, 10,176,121,149,124, 1,190, 66, 93, 6, 96, 73, 2, 39,228,165,196,217, 74, 94,157,165, 98,189,167, 11,244,188,205,
-172, 1,100,250,156, 2, 70,106, 68,142,165,231, 99,139,182,139, 89,132, 75, 12, 91,121,235,217, 3,203, 54,232,110, 24,186, 92,
-174,206,214,179,159,136, 32,122, 93,224, 23, 8,226, 33,116, 88, 97, 86,187, 65,117,227,237,124,147,247, 8, 18,115,238,168,105,
-165,206, 74,218,152, 74,108, 58,236,130, 2,104, 22,217, 33, 81, 77,238, 44, 4, 53,100, 40,186,232, 1,198, 21,232, 27, 61,239,
-129, 54,247, 90,177, 3,106,164,160,231,192,122,137, 68, 28,188, 11, 57, 57,181, 99, 29, 92,109,168,164,155,213,181,110,108,102,
- 31, 40,225, 43, 57, 73,105,103,206, 92,139,196,123,231, 78,131, 90, 5,154,172,100,213, 6,155,177,120,236, 59, 22,126, 79,130,
-140,127,127, 46,134,151,153,122,187,235,212,113, 81, 2,115,108, 0, 56, 29,111, 85, 18,219, 54,120,213, 0,212,195, 10, 68, 98,
-205, 0, 7,134,154,147,200, 65,216, 11,116,210, 69,178, 7,100,210,171,232,243, 60,130,111, 36, 4,199,130, 46,218,185, 74,108,
-167,197, 14, 6,234, 64,156,213,125, 29,131,149, 60, 16, 2,225, 50, 32, 25,233,233, 25,239, 72, 76,120, 59,207, 11,205,209,123,
- 54,176,248, 73,172,131,175,162, 48, 20,165, 44,214, 37,228, 28,168,252,183,103,128,146,144, 44, 44,138, 63,171,178, 27, 89,102,
- 41, 93, 89,233, 89,241,162,211, 72, 36,117, 35,145,208, 0, 87,232,162,225, 45,254,231,137,238, 6,120, 44,181, 20,126, 94,213,
-107,111,207,105, 23,110,174, 44,163, 7,103,222, 80, 92, 3, 16, 47, 71,189,196,118,150,141,146, 71,234, 4,226,213, 99, 67, 41,
- 36, 93,164,185, 65, 59, 77,215, 49, 49, 42,241,145,161, 30, 97, 81,237, 65,157, 40,219,207, 58, 15,144, 80,229,109,107,189,183,
-180,253, 41,144, 77, 17, 63, 71, 57,140,230,149, 27,246, 95,237,126,125,180, 63, 45,254,151,120, 14,198, 1,117,152,121,179,112,
- 2, 31, 4,156,167, 87,136,181,238, 7,196, 0, 22, 85,134,138,227,194, 8, 14,199, 57,103, 0, 7,171, 54,245,225,177, 54, 22,
-239,198, 95,158,135,252,199,225,245,155, 31,219,183, 63,252, 63,184,255,247, 49, 15, 47, 79,253,116,124, 74, 47,172,121,216,149,
- 78,140, 41, 40,221, 26, 18, 36, 86,130,128, 70,120, 52, 10,189,246, 65,155,185,191,229,223,131,120,247,217,183,239, 94,223, 63,
-190,249, 92,124,179, 23,239,127,171, 62,142,213,245,169,255, 59,174, 78, 4,210,165,205,124,189,216,195,225,197,151, 95,168, 15,
- 31, 52,210, 61,200,198, 19,239,250,242,207,239,191,254,238,251,127,118,119,141,250, 43, 46,154,166,211,246,149,138, 39,118,214,
- 37,234,215,106,170,168, 6,179, 25,117, 87, 13,216,220,163,207, 99,121, 51, 54, 78,161, 77,190, 36,240,169,169,145, 25, 3,224,
- 80, 47,107, 77, 19, 98,138,180,154,235, 20,175,226,236,134,106, 90,139,215,195, 73,223,149,226,156, 61,229,196,169, 17, 21, 20,
-120, 31,176,167,174,135, 92,213,244,152, 28, 83, 49, 46,193,209, 39, 60, 53, 8, 65,188,238,175, 29, 14, 77, 57, 68,239, 0,231,
- 23,139, 35,226,240,173, 73, 84,167, 13, 81,130,187,170, 45, 13,188, 23, 67, 51,105, 73,114,161, 57, 67,142, 47, 91, 32,126,100,
-122,208,146,188, 56,121,136,142,172, 7,111,116,177,219, 24,176, 61,250, 77,181,197, 6,239,140,106, 13,117,153,238, 65, 26,231,
- 41,226, 71,177, 47, 56,204, 48, 72,179,113, 92,198, 82,205,137, 98,182,148,128,197, 66, 24,160,202,246, 54,211, 67, 42, 41, 47,
-116,184, 52,154,212,227,147, 0,108, 93,205,110,220, 54, 24,228,191,168,149,100,111, 29,231, 84,196,135,246,226,244, 5,122, 8,
- 2,244,101,242, 32,121,174,158,138, 30, 11,228, 9,130, 30, 10, 4, 49,146,198, 91, 75,150, 68,137,127,157, 81,175, 61, 44,124,
- 89,239, 10, 92,242,155,249,200,225,140,249,239, 90,138, 85,148,229,123,154, 61, 81, 76, 83,143,251,118, 26,108,144, 27,191,174,
-197, 28, 75,185,147, 65,101, 10,104,177,128,170,113,145,123, 44, 12, 60,198,194,225,228, 98, 30, 13,218,211,134,174,160,117,204,
- 18,204,221,226,211, 99, 2, 7,218, 35,102,196,110, 39,110,170, 22,202,104,208,108,131,129, 50,156,134,228, 2,140,252,113,141,
- 42,239,237,126, 1,179, 6, 35,177, 46, 8,135,241,214, 1,139,127,162,104, 37,129,122, 52, 21, 96,105,230, 83,118,113, 65,153,
- 0,153, 3,245, 91,245, 34,167,155,173, 67,109,197,168,105, 96,254,126,250,251, 60,169,116,125, 18,226,165,174,141,156, 82,236,
- 79, 54,159,146, 48, 47,122, 44, 45,158,157, 89, 3, 68,104,240,203,215, 53,169,238,140,161, 5, 68, 87, 20,102,172,126,230, 79,
- 37,234,113,216, 6, 98,116,240,152, 38, 25, 77,235, 10, 26, 73,160,173,115,102,102, 86, 53,150, 16,175, 77,198, 80,120, 10, 48,
-231, 65, 81,106,111, 10,240, 42,142,135,151,138, 88,215,153,158,205, 17,212,169, 76, 33,199,186, 53, 99, 0, 0,248,138,217,184,
-240, 98, 89, 73, 77, 42,254,130, 89,149, 27,223,142,170,117, 95,192,142, 81, 92,166, 67,202,134,206, 37, 69,218, 43,187, 29,232,
- 16,153, 58,176,211,192,147, 23,167, 34,117, 54, 32, 80,117, 57, 83, 0,233,176,120, 55,112,210, 10,234,108, 51, 51,184, 74,197,
- 56, 3,131,237,236,100, 35,163,107,236,181,148,155,103,210,180, 0, 11,146, 98,214,244,173,151,215,104, 85, 50,129, 32,150,167,
-125, 59,183,109,140,150, 39,185,232,122,173,137,154,150,126, 33, 49,199,142, 74,157,231, 74, 47, 37, 69, 15,194, 33,172,225,172,
- 55,189,208,116,254, 89,117,182, 45, 59,243,106,232, 30,102, 0, 86,188,180,164,169,123,156,155,116,189,219, 14,203,202, 85, 0,
-205,106, 69, 31,209, 72, 23,116, 50,231, 68,205,131,234,229, 17,166,137,122, 89,120,158,232,152, 52,249, 79,155,141,103, 48, 91,
- 15, 78,195, 32, 2,121,208, 91,128,118,178,202,153,222,124, 19,118,161, 26,103, 71, 87, 91, 3,133,162,105, 88,234,225, 4,169,
-192,230, 0,206, 40,192,237, 42, 48, 77,241, 62,113,248,228, 81, 63, 80, 49, 1,164,106,179,126,194, 63,138,238, 8,121,220,229,
-160,247, 75,106,104,151,109,128,147, 27,131, 16, 40,159,148, 54, 8,106,105,220,113,135, 88, 73, 18, 39, 48,189,198, 58,135,239,
- 49,101,221,194,180,126,127,219,190,210,241,161,238, 3,143, 15,234,152, 80, 2,152, 76,176, 41,102,205,250, 90,243,161, 46, 38,
- 27,230,166,252, 30,248, 35, 85, 62,159,214, 67,217, 42, 49,178,114,126,241,193,153,153,246,114, 78, 63, 74, 49,114, 91, 62,211,
-111, 23,176,251, 92,110,175,151,254,222,255,126, 99,126,205,203, 95,129,200,222, 74,172,102, 52, 2,188, 69,151, 50,123,120, 96,
-150, 39, 32, 29,226, 60,204,164,180,160,165,144, 27, 79, 83, 35,221,202, 68,186, 26,154, 19, 58,102, 35, 46,211,227,248,249,238,
-238,205,251,254,245,255, 22,119,138,123,240,199,220,189,254,249,205, 47, 31,254,248,237, 81,133,243,162,116,175,213,165, 80, 39,
-125,165,197, 87, 94,117, 63,248,192,225,120, 75,125, 73,245, 37,117,231,239,222,189,253,161,191,191, 21,251, 87,241,225, 79,241,
-121, 92, 46, 43,158,242,170,101,121, 13, 98, 53,189,122, 6,196, 55,189,252,233,213,244,233,147, 28,191,160,248,204, 70,202,185,
- 62,125, 92,253,199,135,252,226,254,225,219, 19,186,182,197,134,161, 76,160,136,253, 54,208,222, 88, 37,116,122, 91, 26, 80,137,
-116, 97,216, 46,232,113, 12, 65,168,234,213,211, 62,162,170,161,214, 46,129,154,229,110, 75,182,210, 82,177, 69,177, 96,251,111,
- 69,171, 83, 93, 3,125, 77, 81,254, 23, 63, 23,231,243,152,133,221,244,200,147,153,157, 33, 93,158,141, 0, 56,163, 11,135, 42,
-140, 10, 96, 65, 90, 64,246,235,245, 22, 15,102,138,174, 34,121, 48, 49,115, 82,121, 2,184,129, 14,161,214, 74,127,211,169, 1,
- 80,135,246,183,148, 78,213,209, 83,242,107,234,134,218, 76,205, 32,138, 62, 38, 77,215,225, 67,193,140,193,194,140,157,155,221,
- 53, 74,108,206, 24,199, 16,122,173, 90,138, 28, 54, 48, 77,116,198,194,226,219,152, 42,212, 74, 74,182,157,101, 54, 11, 79, 43,
- 13, 91, 95,116,220, 64, 58,225,185,195,159, 35,167, 20, 94,152,165, 65, 7, 83, 49,154,230, 95, 1,152,186,150, 29,201,105, 40,
-106,199,142,227, 84, 82, 53,221,244, 12,106,122,102,209,243, 64, 8, 70, 35,177,230, 35,144, 88,176,230, 59,248, 30, 62,132, 5,
- 98,219, 18, 72,136,215, 6, 9, 52, 61,211, 48,213, 85, 73, 42, 78,236,216,230,156, 44, 16, 82,109,186, 84,106,165, 92,246,189,
-231, 92,223,123,142,230,128,148,208,134,163,140,243,106,171, 68, 80,138,103, 13, 28,110,194,226,201,154, 18,107, 52, 25, 11,185,
-172, 84,131,156,127, 2,152,227, 18, 4,207, 1, 26,124, 48, 79, 28, 22, 99, 21,157, 35, 74, 44,232,175, 83,172, 20,162, 36,188,
-140,217,207,122,105,125,246, 42, 33,103, 6, 90,104,150, 75,116,174, 31,145, 12, 70, 33,218,165, 21, 73,238,229, 36,198,218, 45,
- 20,248,150,161, 22,123,240, 2,236, 80,167,168,150,180, 28, 91, 59,229,230, 76,117,248,103,181, 58,133,185,153, 16, 16,166,211,
- 39,207,174, 30, 63,125,249,233,147,231, 79, 95, 52, 82, 93, 8, 21, 78,239,186,223,239,142, 63,223,186,183,247,126,196,193, 80,
- 83,115, 14,182,132, 31, 4,116,110,161, 11, 88,162, 90, 74,170, 84,165,207,170,184, 90, 63, 37,163, 21,123,190,108,169, 6, 94,
-246,101,203,226, 93,143,253,128,104,207,115, 73,155, 8,214,148, 56,149, 66,170,142, 8, 64,211,137,101,204, 37,190, 15,178,195,
- 20, 10, 77, 67, 55, 55,135, 35, 78,235,146,163,103,188,236,140, 80,206, 43,125,184, 55, 86,143,123,240,237,189, 49,125,157,244,
- 62,154, 78,141, 54,251, 33,252, 9,130,208,202,116,148,233,240,183,120, 0,200,194,133, 98, 47, 55, 53, 75, 64,179,212,100, 40,
-201,208, 36,207,118,109,188,169,197,105, 0,155, 42,183, 86, 13, 72, 55, 71, 60,213, 92, 83,195,162, 58, 0, 29, 97, 79, 26, 89,
- 7, 14, 57,158,203,218, 33, 11,110,203, 70, 69,219,153,170,210, 11, 16,105, 91,188, 63,121, 64, 94,185,101,177, 95, 45,148, 73,
-110, 21,157,172,187, 58,181,202,238,154, 18, 52, 22,144,207,153,124,129,109,128,197,201,113, 30,228,110,151, 83, 71, 95,150,185,
- 69,246,160,115,100,244,179, 31, 77,250,167, 14, 87, 74, 25,233,250,184, 13,209, 1,179,250,176,195,193,199,215, 59, 31, 92,189,
-148, 70, 89,117, 64,104,221, 80, 53, 4,177, 45, 81, 83, 63,209, 99,187, 2, 85,210,142,106,173,114,195,218, 75,148, 84,177, 64,
- 96,177,241,108, 57, 47, 69, 53,216,129,202, 76,197, 90,177, 74,180,236,162,136, 27,120, 51,255, 44,168,105, 62,115,220,138, 83,
-220, 50,140, 75, 49, 68, 74,222,225, 92, 40, 47, 36, 91, 53,133,181,236,118, 5,128,178,253, 58,220, 3,150, 85,115,166,131, 23,
-219, 38,147, 58,116,171,241,118,197,144,104, 83,175,210,123,165, 0,209,171, 27,222,193,128,208,136,130, 90, 39, 81,113, 86, 13,
- 49,111,208,178,162, 69,153, 18,114,117, 44, 43,170,254,245,114,125,177,124, 47,144, 46,204,150,133,143,121, 43, 72,206,135,181,
-205,151,125,209, 68, 62,120, 2,173, 64, 36,215, 86,208,137, 14,153, 17, 36,228,161, 52, 65,167,144, 11,135, 51, 71,161, 88, 29,
-171,233, 48,233,199,127,141,190,210,142, 89,188,110,168, 91, 63, 93, 95,154,238,197,195,111,182,242, 91,223,243,190, 79, 74,206,
- 50, 68, 26,194,230,196,184, 29,145,109, 40, 41,194, 94, 0,170, 6,229, 25,224, 33, 0,254,133,169, 92,166,200,214, 93,170, 10,
-103, 11,164,134,237,125, 90,198,159,182, 31,188,250,186,253,248,203,255, 21,100,254, 11,238,114,125,173, 98,232,102,243,249,103,
- 95,221,222,252,241,195,241, 77,184,136, 87,117, 58,155,237, 3, 85,124,244,200,252,242,155,192, 46,216, 81, 81, 72, 23,188,167,
- 3, 79, 95, 16,146, 62,188,120,212,118,111,197,119,183, 66,140,226, 92, 33, 72,254,218,205,239,240, 19,232,170,112,202,141,106,
-239,167,186, 12,187, 97,169,158, 92, 23,151,175,187,195,221,101, 70,136, 53, 61, 13,165,230,235,155, 31,159,127,241,236,230, 14,
-216,227, 30,103,128, 38, 33,147,161, 98, 40,145,171, 5, 65,157,115, 15,154, 96,203, 58, 59,172,108,230, 52,225, 1, 16,181,196,
- 7, 74, 53,229,213,145, 34,248, 67,200,161, 54,197,189, 7,118, 25, 25, 33, 39,164,248, 92,158,192,132,156,149,210,152, 98,166,
- 87,226, 76,203,115, 42,146, 0, 51, 4,202,181, 38,233, 41, 1,135,147,160, 89, 15,178,244,220, 78,125, 11, 52,190,145, 81,110,
-163,181,224,198,186,216,173, 2,184, 21, 8, 32,206,118,214,103,160,170,180,126,181,116,163,147,148,145, 91, 16,224, 71,240,127,
-159,139,166,182,128,253, 75,156,198, 82,217,184,241,243, 9,155, 16,184,112, 83, 35,250, 33,142,130,158,233,181,106,226, 22,217,
- 6,237, 60,203, 72, 57,204, 9,168, 12,240,103,226,141,191,161,225,238,236,176,206, 29,240,159, 92,213,229,171,120, 40,172,213,
- 56, 87, 96, 11,115,233, 60, 29, 86, 9,139, 38,229,109,217, 31,254, 21,128,167,107,217,113,156,136,162,245,112,185,108, 39,157,
-244, 99, 90,244, 44, 6, 16,163, 65, 61,188,212, 72,128,144, 0,137, 5,191,193,130, 63,224,195,248, 10,196, 10,177, 65,195,138,
- 89,208,139, 17,104,186,153,166,147,248, 81,229,122,113,142, 7,177,136,148, 44,156,196,118,249,222,115,110,221,123, 78,197,253,
- 81, 68, 56,177,112, 77, 42,241, 46, 62,143, 52, 61,164,254, 0,184,116,160, 92,119,205, 77,233,144,125, 60, 20,254, 74,160, 42,
- 75,230, 46, 45, 86, 94,149,230,211, 57, 57,209, 0, 34,181, 35, 34,126,154,133, 67, 54, 57, 24,235,146,141,243,136,168, 8, 40,
- 55,201,253,228, 99, 53,214,193,136,228, 28, 48,185, 1, 21,194,243,115,239, 69,255,114, 60,226, 28, 79,221,213,115,239, 83,244,
-131,166,153,195,164,179,239, 7,170,126, 77,182, 61,204, 90,205,120, 15,176,246, 42,168,214, 78, 31,189,115,254,245,103, 95,124,
-112,245, 33, 43,172, 98, 39,196, 13,109,164,133, 92,157,233,171,179,213,213,211,211,195, 93,251,236,249,221,139,184,167, 6,159,
- 31,138,237,218,234,184, 0, 37, 81,180,141, 13,217,128, 87,141, 5,165, 64,186, 12,179, 32, 84, 5, 25, 18,108,111,110,164,225,
- 80,110,166,219,243,162, 64,131,101, 10, 8,173, 41, 1, 94,202,235, 81, 47, 74,172,105,144,242, 52, 21,122, 80,181,197, 70,119,
-200,177,143,186, 14,179, 73, 78, 78,177, 47, 10,232,201,151, 94, 45, 45,253,163,167,220, 79, 12,102,247, 79,240, 97, 24, 8, 45,
-142,239,124,106,205, 48,121, 13,108,159, 83,220,167, 9,139, 51,177, 31, 71,103,219,215,206,142, 98,237,185,207,228,217, 38, 64,
-113, 68,252,229,206, 82,122, 43,148,228,122,193,161,135, 74, 14,160,241, 8,135, 10, 75,158, 19,255,137, 74,255,138, 19,173, 6,
-217,133,213,180,166, 65,232,150, 57, 33,154, 91,167, 57, 70,125, 58,201, 82,221,183, 38,198,216,205,212, 22, 23, 78,199, 78,233,
-126, 96,103, 31,153, 28, 71,125, 92,234, 17,154, 36,224, 5,184,134,103,199,147,204,222,227,137,218, 73,115, 0,136,166,243,166,
-178,247, 74, 86,115, 65, 30,234,178,104, 76, 51,175, 56, 5,223,201,215, 98,112,136, 65, 59,106, 59,228, 77,166,137, 29,150, 19,
-219, 88,169,143,160, 90,206,150,106,112, 91, 14,193, 10, 22, 68,176,202,169, 18,154, 22,177, 30, 61,128, 25, 19,187,167,118, 52,
-243, 58,134,126, 41,202, 90,127, 27, 37, 53,105, 56, 17,161, 76, 30,172,220,113,251, 25,103, 34, 88,147, 0,116, 95,106,142, 72,
-176, 65,220, 7,170, 86, 34,208, 59, 90, 75,210, 29, 24, 23,206,201, 5,158, 34,145,207,130,157, 26,254,207,149, 94,121,181, 70,
-220, 84,128, 94,114,195,182, 22,154,189,148,137,137,133,218, 75, 70, 50,178,224, 81,227, 28, 30, 94,160,239,129, 10, 5, 27,145,
-110, 41,103,252,168,214, 47, 38, 90, 26,211,222, 20,199,137,210, 9,171,151, 53, 57,231, 6,236, 10, 36,120,166,129,137, 90,246,
-185, 13, 85, 30,168,217,170,167, 42,159, 84, 72,194,146,190,184,202,173, 76,126,124,168,190,113, 66,183,180, 33,229, 16,100,204,
- 23,143,170,252,184,249,161,217,255, 56, 2, 79,212,173,100,125,115,193, 81,153,190, 49, 11, 43, 1,161,166, 59,113,225,222,193,
-242, 27,110,162,231,155,104, 16, 86,192, 21, 67,162,107,129, 97,193, 7,233,112,186,185,174, 31, 60,249,238,228,171,111, 23,164,
-158,254, 43, 90, 9,249, 63,108, 23,139, 64, 9,174, 14, 40,252,187,239,191,119,254,214,153,252,245, 90,237,170,104,117,172,135,
- 18,205,195,243,213,199,159, 62,248,249,151,219,251,105, 86,148, 74, 40, 1, 72,122, 93, 62,191,124,251,251, 47, 47, 75,126,149,
-135,221,244,178, 95,159,172,159,165,252,199,205,237,234,141,230,205,167,151,227,120,168,114, 62,109, 87,120, 6,227,180, 47, 23,
-155,139, 79,158, 28,126,255,109,239, 92,234, 26,224,219,202,133,254,250,167,147,191,175,172,221, 70, 87,142,135,173, 43,209,202,
- 14,240,106,221, 34,132,108,102,207, 50,206, 38,112,226, 77, 5, 63, 0, 54,131, 75,133, 30, 39,108, 76,153,199, 70,130, 87,171,
-157,154, 27, 4,254, 52,106, 57, 40,110, 76,135, 62,164, 56, 68,182, 71,249,186, 1,132,242,127,225, 18, 26, 43,147,165,207, 0,
-110, 78,104, 16,115, 44,145, 31,189,195, 0,216, 58, 49,140,178, 9,171,186, 75,254,225,104,125, 87, 15, 70,109, 43, 42, 73, 8,
-124, 76,169, 3,238, 53,102,149,218,173,207,195,209,100,116,155,216,254,186, 7,126, 4,160,174, 58,115,196,185,249,122, 23,139,
-186, 27,228, 86,106, 26,120,100,234,196, 85, 38,128, 59, 31,149, 14,247,249, 56, 7, 29, 53, 56, 71,131,168, 7, 36,150, 82, 5,
- 38,107, 89, 82,160,112,187, 54,161,102,102,169,212, 52, 56,154,230,216, 70, 82,253,130, 5,130, 80,173,217,200,115, 71,237,224,
- 40,251,237, 10,199,165,232,244, 1, 95, 95,219,170,251, 87, 0,150,174,109,181,174, 42,138,238,117,219,247,189, 99, 26, 72, 82,
-233,177, 1,241,242, 34,226,147, 80,144,226,165,126,134, 79,254,146,191, 35, 40,254,128,208, 7, 73, 44,165,150,162,210, 36,231,
-178,239,123,221, 28,227,212,188, 37,112,206, 33,123,205, 57,215, 24,243,204, 57,134,166,190, 98,178,204, 73,173, 29,184,231,222,
- 74, 33,216,173,195,141, 41,143,134,209, 22, 12, 8,208,253,157, 1,147,227,100,175,112,150,251,212,100, 59,168, 36,200,148,152,
-163,232, 44,236,190,174,161,224,244,246,108,217,148, 27, 92,167, 71,174,164, 71,145,143, 20, 91, 90,210,158,254,181, 35, 1, 58,
-115,109,238, 71,219,148, 96,206, 93,226,232, 94,187, 19,139,161,217, 14, 8,131,144,247, 2,239,143, 91,120,242,125,135,187,172,
- 44,171,174, 18, 89,183,106,147,255,117,121,113,241,195,179,111, 62,254,244, 17,217,174,123, 62, 13,247,193,243, 71,104,192,237,
-137, 93,101,182,204, 76,243,224,236,201,151,151,221,109,123,253, 50,238,185,221,137, 26, 52, 1,180, 7, 89,215,132,237,120, 68,
-194,199, 81,187, 9, 55,191, 50,134, 60, 74,129,187, 0,140,240, 43, 49, 14,112,208, 8,219,129,142, 59, 45,205,146,250, 76,245,
-203, 92, 29,237,190, 35, 77,124, 88, 3,199,216,174,122, 77,167, 53, 76, 36,140, 64, 97, 56, 64, 1, 52,134, 98, 15, 68, 28,250,
- 74,232,195, 74, 84,134,164, 87,241,142,250,237, 62,116, 33,153,242, 48,135,216,231,168,205,189, 7,170,176,171,199, 93, 61, 28,
- 87,168,230,176,181,161, 9,163, 7,251, 96,218,210,128,121, 77,240, 57, 58, 85, 28, 59,117, 82,157,122,208,137,192,254, 88, 67,
-187,221,101,160,161, 11,136, 1, 77,253,146, 64,183,168,106,178, 50,132, 80,115, 13, 74,164,230,140,243,250, 69, 41,194,154,228,
-141,204,184,205, 70,149, 73, 90, 6,227,200,241,175, 39,190, 70,165,151,122, 52,193,246,234, 61,109, 50, 71,135, 6, 60, 39,250,
-219,138,101,183, 3,243, 10, 58, 69,196,165, 56, 93,103,216,210,174, 71,151,148,247, 25, 62,201,215, 0,230,133, 46, 22, 63,164,
- 5,130, 70,150, 46,100, 69,234, 84, 69, 27, 31, 74,144,113, 42,152, 43,216,162, 88,147, 41,243,185,146, 20,175,227, 48,155, 44,
-168, 13, 28,228,128, 48,181, 61, 8,138,161,205, 22, 40, 1, 93,225,242,156,235,140, 26,188, 89,245, 25,128, 68,156, 37,238,133,
-172,141, 83,158,128,164,203, 20, 60,143,174, 8, 30,103, 18,227, 0,254,148, 0,101,172,130,216, 17,245, 10, 33, 27,215, 36,181,
-137,108,142, 38,101,156,242,229,180, 40,238,104,148, 53,103,147,190, 83,245,118, 72, 55,181, 29,238,241, 46, 0,128, 66,131,140,
-228,156,230, 52, 64,119, 52, 25,227, 73,211,185, 6,196,227, 68,250, 3,226,140,252, 33, 32,148,251, 82,218,189,172,255, 30,174,
- 30,159,190, 78,245,221,154, 29,188, 3, 83, 90,124, 74,184, 38,121,172,120,184, 52, 72, 5, 96, 48, 49, 61,202, 75,149, 9,208,
- 57, 21, 79,246,252,130,110,241,193, 76,146, 35,103, 92,106,215,245,197,181, 63,245,113,175,120,203,138, 49, 60,218,100,175, 62,
-154,127,205,252,207,243, 34, 67, 81, 83,215, 21,207,206,176, 33,202, 85, 49, 84,121,160,117,252,126, 20, 59,194,249,138,153,147,
-206,126, 4, 51,149,220,174,176, 93, 12, 25, 5,183, 12,120,180, 72, 10,121,253,251,248, 80,125,181,121,242, 35, 43, 56, 21, 3,
-147,119, 50,210,199,229,138,112,156,150,251,127,102, 14, 9, 72,242,113,182,249,246,235,239,255,120,115,115,251,207,161,221,182,
-155,182, 56, 17,217,135,190,250,252,147,179,135, 39,197,139,219,254,207,235,221, 52,135,147,211,252,187,207, 46,127,122,250,244,
-242,217, 38,249,237,149, 58,188,172, 27,196, 97,254,203,205,155,231,255,250,247,175,174, 46,155,243, 23, 55, 47,111,125, 95, 54,
-101, 49, 84, 58,186,225,109,180, 89, 51,204,153, 50,115,195, 98, 1,158, 44,238,222,218, 15, 94,239,170,199, 95,116,221,221,130,
- 2,145, 58,224,132, 57,113, 69,111, 75, 49,169,214, 83,187,101, 85, 28, 95, 92,193,241,151, 28,121, 55,185, 81,171,106, 26,132,
-155,183, 90,218,123,100, 23,157, 20,197, 1, 33, 45,108,238, 14, 59,118, 36,173,245,179, 1, 84, 48,185, 12,121,216,143, 84, 37,
-215, 40, 29,211,158, 74,191, 84, 89,194,125, 41, 16,154, 43,125,203, 23,147,149, 66, 21,168,113,129,222,149,237, 81, 18,139,134,
-212,222,103,200, 68,147,158,175, 17, 36, 21, 55,205,140,196, 23, 53,254,116,160,202, 76,117,206, 56,142,113,187, 30, 18,118,202,
-219,202,183,231,209,205,167,139, 5, 6, 70,193,230,170, 43,202, 12,237, 76, 80,113,243, 40, 38,205,217,144,166,166, 45,205, 12,
-136, 38, 21, 64,118,216, 26,211,152, 88, 13,139, 51,203, 34, 99,246, 32,117, 40,186,131,227, 36,149,206, 80, 40, 17,145,120,157,
- 69,170, 46, 84, 95, 69, 18,180, 74,141,217,188, 68, 14, 38, 59,209,252, 39, 0, 73,215,206, 35, 71, 17, 6,187,123,186,167,123,
-246,117,190, 59,131,208,233, 76,112, 1, 72, 32,217,150, 45,145, 0, 33, 1, 41,130, 0,126, 4,191, 11,137,152,132,136,148, 12,
- 11,217,145, 37,132, 49, 18,247,220,189,221,121,246,147,170,113,114,193,105,116,115, 51,219, 93, 95, 85,239,247, 85, 49, 82,135,
-140, 80,162,246,128, 44, 49,189, 27,247, 97,116,211,156, 8, 16,231, 57, 12,186, 18, 39, 14,180, 42,154,211, 84,156,214,140, 12,
-179, 37,160,203, 52,166, 62, 7, 71,159,226,236, 3,115,216,193,205,129, 94, 38, 51,161, 49,166,210,185,112,143,234,120, 48,216,
-150,122, 0, 3,204,131, 30,177,160,129, 19,139, 92,143,209, 12, 3, 88,235,132,194, 49,141, 92,232, 75,134,224,225, 78, 58,153,
- 67,183,176, 98, 5,218,198,141,244, 96,242,237,118, 18, 79, 62,122,250,195,183, 95, 62,122, 40, 69,247,199,176,223,210, 82, 67,
-150, 57,100,125, 30,251,129, 2,199,166,199,251, 40,247, 98,188,213,250,237,250,228,209, 83,251,225,171,235,227,255,186, 36,204,
-248, 32, 23,122,132,101,166, 25,208,167, 46, 49,176,144, 22,199,244,233,161,233,126,165, 19, 27,250,135,204,246, 31,233,152,165,
- 39, 50, 83, 19,129, 67,130, 19, 67,120,106, 54,136,122, 67,199, 72,182, 97, 1, 38,135, 61,232, 67, 36, 61,110,251,126,118,202,
-117,179, 67, 81,215, 58,168,167,110, 4, 57,185, 47,110,174,150,187,155,228,250,116, 16, 1,160, 37,251, 81, 76,209,111,163, 56,
- 77,122,137, 10,168,239,216,232, 61,129,105,208,203, 45,214, 32,224, 60,205, 54,121, 98,239, 5, 45, 36,241, 95,191,243,251,223,
-161,176, 66,235,213, 70,170, 54,160,164, 87, 80, 41, 57,246, 74, 97,127,172,211,228,173,157, 99,206,107,240, 1,155,104, 80,218,
-100,160,141, 4,214, 40,142, 6,102, 43,167, 69, 57,202,116, 55,129,196,199,143, 3, 93,211,177,250,160,228, 38,232,163,100,226,
-157,239,171, 3, 13,134,188,164,139,191, 93, 1,123,161, 75,124,156,106, 85,201, 67, 4,191,157, 14, 70,116,185,234, 87,181,194,
-158,137,227,142,223,159,173,205,101,128, 78,174, 79,252,228,119,218,126,160,244, 68, 95, 1,161,218,113,101,197,104, 37,253, 30,
-104,164,106, 80, 35,174,133, 56,194, 98, 13, 2,207,163,215,248, 20,114, 5,145, 89, 17,222, 73, 41, 64, 20, 32,155, 10, 40,122,
- 81, 35,179,136, 65,244,109,202,245,102,116,138,238,106, 37, 28, 56,118,128, 87,230,247, 18,239, 20,191, 93,115, 74,141,137,212,
- 85, 38,194,115,182,144, 80,200, 22, 26, 60, 96,166, 66, 19,179, 11, 63,137, 57,144,220,138,219,178,251, 87,158,159, 59,160,154,
- 94,133,160, 99, 29,156, 53,146, 54,165,227,210,205,199,111, 88,178,222,177,247, 93,246,218,121, 92, 51, 74,222,204,134,181, 43,
- 98, 83,165,183,225,253,117,255,249,137,252, 61, 87,145,167, 87, 5,104,130,119, 45, 24,241, 88,142, 68,185, 43, 11,155,197,106,
- 62,241,196,159, 1, 57,216, 27, 72, 34,108,207,160, 20, 21, 97,170,104,159,205,161,141, 93,185,248,103,103,151,234, 10,100, 35,
-136,247,206,155,171, 79,234,159, 77,251,114,108, 25,168, 45,125,230,201,190,154,133,193, 52,143, 79, 27,150, 6,172, 86,230,101,
- 85, 52,212, 79, 29,181, 32,180,168, 28, 66, 96,224,250, 50,209, 72,197, 51,205, 79,149,203, 55,219,114,125,126,246,221,143, 98,
-121, 65, 12, 39,247, 87,239,228,204, 12,235, 97,174, 18,133,184, 79,115, 52, 79, 7,126,163,158, 61,255,230,139,151,175,127,250,
-245,151,215,224,207, 61,164,233,212,171,116, 84,252, 87, 15, 55,223,159, 29,255,245,241, 57, 94,180,141,250,235,139,179,117, 8,
- 55,191,189,248,243,239, 75,179,111,107,151,182,254,240,226,106, 27,165,120,242,236,113,218,244,119,221,141, 13,126,177, 95,228,
- 70,117, 32,136, 14, 26,182,132,211, 85,219,222, 31, 75,185,140,148,118, 35, 20,207,155, 87,167,159,126,118,221, 66,141, 2, 64,
-123,144,143,101,209,189,230,202,190,191, 2,225, 48, 43,195,132,249, 8,113,199, 20,180, 2,152,156, 80,213,120, 49, 61,239,161,
-253,232, 8, 53,141, 93,204,190,183,194,203, 5,191, 4, 52,186,214, 30, 4,249,118,232, 26, 90, 12,225, 50, 30,250, 0,210,107,
-213,128,202, 55,173, 82, 96,226,181,183, 11,118,113,196, 77, 93, 77,248,124,199,172, 57, 37, 3, 70,157,177,190,180,115, 70, 89,
- 90, 16,139, 1, 2,182, 84, 57,186,178,234,155,161, 81,186,107,150,213,162, 3,100, 67, 48,169, 77, 4,228,171,117,210, 68, 22,
-179,199,219,172,160, 1, 56,234, 6, 34,111,154,169,143,149, 11,196, 88,118,228,202,154, 93, 58, 54,186,121,194, 6,123, 84,229,
-110,209, 66, 29,172,251,186,137,156,226,149, 43, 5,194,168, 7, 23, 28,155, 36, 24,184,148, 5,208, 93,130,213, 15,155, 6,140,
-185,233, 7, 48,192,105,108,244,104,193,227,193, 30,254, 23,128,164,107,217,145,155,136,162,174,151,203,118,187,231, 65, 50, 25,
-105,132, 8, 40, 72, 9, 26, 64,236,224, 7,216,178, 97,199,130, 47,224,219, 88,176, 96,141,216,195, 6, 41,160, 72, 72,195,240,
- 8,104,186,103,250, 97,187,236,122,184, 56,199,249,128,238,118,219,183,206,163,124,235, 92, 61,194,197,234,202,164, 99, 7,129,
-194, 73,127, 51,180,161, 15,110,249,209, 82,210,114, 21,203, 52, 99, 11,197, 14, 41,201,157,219, 10,143,133,179,140, 61,183,187,
- 86, 53, 53,147, 99,231, 93, 84,113,230,145,156, 88,122,176, 1, 72, 15, 96,122, 15,215,128,159, 24,199,185, 19,157,219, 85, 2,
- 88, 52,254, 53, 13,166, 63, 7,170,108,119,255,153,113, 5, 92,134, 71,112, 62,115, 2, 79,225,226,232, 85, 30,123,157, 55,197,
-124,138, 47, 83,181,225,224, 42,177, 81,241,211,103, 47,190,249,234,185,106,254, 72,155, 27,151,118,240,132, 60,104, 79,215, 96,
- 81,203, 34,247, 5,231,202, 49,141,129, 41,236,186, 10,113, 12,199,151,181,217,127,116,245,236,234,254,233,159,187,199,177,241,
- 57,147, 27,217,217, 31,103, 30,252, 32,114, 6, 17,135, 90, 30, 19, 71, 9, 2, 28,192,127,154,121, 65,220,216, 52, 89,244,240,
-119, 16, 96,248,199,236, 82, 13,102,217, 19,244, 94, 78,154,151,108,178,115, 64, 39, 25, 54, 14,152, 42,130,157, 30,194,222, 64,
-185,169,110, 72,102,216,222,245,226,168,176,222,166,164,106, 55, 8,153,247,188,147,131,234,224, 3,244,228, 96,118, 68,122, 29,
- 15,217,112,158, 56,179,132,231, 37, 9, 93,245, 96, 18,193,236, 11,158, 98, 0,227, 30, 53,187, 72, 56,129, 0,252, 15, 78,134,
-240, 71,217, 0,100,173,195,101, 90,104,108,141,213,114, 81,114, 54,250,225,111,179,122,187, 47,170,170,196, 98, 31, 12,124, 91,
- 26,240, 49,184, 19, 89, 92,204,120, 86, 77, 40,246,146, 67,208, 75, 16, 86, 93,107,216,143, 0,124,241,233,204,163,240,227,110,
- 26, 43,213, 40,127,108, 8,140,178, 43, 96, 61,250,148, 59,220,144,145,131,202,195, 12, 38,192, 69,212,225,116,178,187,100,173,
-244, 27, 96,209, 12,203,221,130, 24, 81,244,205,201, 92, 65,212,244,167,252,175,103,241,145, 3,233,113,154, 11, 95, 16, 12, 90,
-107, 78, 4,132, 41,210,231, 0,119,138, 9,120, 30,175, 42, 0, 85,197, 62, 62,160, 78,195, 22,114, 64,123,244, 40,114,240,131,
-129, 70,157,177,222,160,209, 99,116,178, 61,135, 24,227,220,139, 6, 34,144,217,242, 40,117,190,252, 42, 89, 8, 61,196,203,146,
-232, 80, 97,245, 44,209, 21, 67,230,158, 59, 55,113,236,155,214,116,190,247, 42, 45, 15,237, 69,250,138, 13,132, 13,190, 63,131,
- 58, 4, 83,167, 74, 72, 19, 72, 70,173,199,217,232,177, 41,219, 41,176, 5, 61, 1,194, 6,109, 18,243, 8,109, 9, 23, 80, 12,
-157,134, 92,132, 85,242,191,251,167, 48, 71,231,118,200,234, 30,144, 26, 15,160,223, 90,242,181, 35,252, 95, 91,140,133,128, 15,
- 43, 39,166, 82, 49,148,160,197, 77, 20,236,242,180, 51,200, 25, 79, 34,219,114, 5,194,185,250,229,248,193, 91,225, 97, 2, 47,
-248,247, 78,234,187, 23,229,247,166,251,137,225,115,242, 36,151,134,241,109, 18, 70, 26, 90,166,228,171, 95,177,180,247,244, 94,
-174,150, 60,179, 97,137, 68,128, 12, 1,247,113,232,115,132,191, 98, 82,224, 68, 61, 83, 22,205,190, 15,191,253, 28, 63,251,248,
-243,242,253,107,194,121, 70, 65,146, 26,216,157, 9, 26, 4,214,195, 22,226,222,161, 0,223, 76,127,240, 28,163, 29,252,168, 78,
- 46,191,248,242,235, 99, 44,190,251,241,219,151, 55,189, 85,242,172, 14,143,159,216,119, 67, 99,235,117,107, 56, 54,114,251,224,
-126, 64,193, 31,252, 69, 28,111,239,142,208, 13,219, 67,250,231,182,255, 55,232, 79,174,175,223,249,240,249,171,155,135,237, 52,
-230,106,198,125,149,171,179,121, 39,155,185,203,167,151,114,109,220, 93,129,178,168, 80, 72,135,165,177,243,246,215,203,105,247,
- 42,138,186,232, 28, 42,200,122,235,106,138, 67, 21,217,251,113, 96,152, 52,172, 54,163,169,147, 95,222,205,224,217, 14, 3,150,
-140, 79,118, 59,206,219,121, 84,246, 97, 35,196, 35,248,187, 46, 76,130, 99,230,216,183,127,240, 13,251,176,196, 20, 2, 4, 56,
- 30, 47,240,130, 73,172, 5,207, 56,148, 96, 11, 40,117,153, 90, 69, 33, 53,176,203, 60, 48,144, 79, 25, 16,233,180,150, 80,232,
- 50, 12,103,105, 77,103,201,156, 62, 89,113,195, 69,139,116,120, 82,232,215,149, 92,177,151, 67,178,109, 27,191,103, 76,171,193,
-199, 18, 30,176,205,181,110, 2, 37, 23,243,185,157, 82, 53, 7,234,102,185,110, 78,214,187, 1, 5,215, 55, 73,185,128,149, 15,
-118, 21, 16, 77,121,111,219,115,160, 54,199,180,249, 54, 87,147,174,247,227, 14, 32,148, 26, 43,216,255, 24,143, 86, 24,103,219,
-162,210,226, 62, 28,123,187,174,134,169,128, 50, 21,203,129,138, 38,185, 16,139,255, 5, 32,233,234,121, 36, 39,162, 96,187,187,
-221,109,123,188, 3,171,189,147, 86, 43,241, 33,116, 58,193, 6,128, 8, 8, 16, 49, 57, 18,225, 37,252, 58,126, 5, 25, 4, 68,
- 39, 33,129,116, 4,136, 59,216, 99,111,246,227,118,198,110,219,253,105,170,134,116, 2,203,242,188,126,175,234,245,123, 85, 0,
- 78,128, 52,139,214,108,249,234, 37,249,202,254, 47, 38,105,217,123, 17, 92,152,160,249, 70, 38,115, 2,182, 13,188,225,101,118,
-162, 43, 15, 40,206, 1,217, 49,205, 40, 72,180, 94,160,155, 90,153,100,202, 32, 74, 11, 96,169,204,116, 91, 24,139,158,111, 17,
- 49,178, 49,247, 98,159, 7,229,130, 89,247,179,178,142,211, 33,110, 80, 8,249, 96,129,153,115, 41,227,188,218,105,169,123,218,
- 83, 22, 32,217,211,109, 55, 37, 93, 23, 20,149,217,185,207, 63,126,242,236,155, 79, 84,247,202,253,253, 2, 73,182,182, 22,132,
-147,189, 20, 53, 9, 70,124, 2, 62,211,218,201,136, 48, 29,240, 58, 21, 88,204, 58,138, 52,205,217, 25,243,239,217,227,215, 34,
- 95,190,242,103,130,178,115, 52,230,166, 3, 52, 5,238, 57,240, 8,142,155,245,148,170,173,140, 92,155, 42,166, 87,203,172,205,
-158,110,168, 37,209,137,153,166,104,236,149, 20,245,128,255,105, 26, 64, 49,240,159, 75, 29,228,216, 33,100, 64,180,214,116,176,
-105, 12,119,189,211,209,238, 85,220, 38,127, 18,226, 77,145, 43,149,165, 15, 66,234,135,153, 2, 81,168,101, 56, 72,160, 89,244,
- 6,159, 87, 16,249,182, 66, 94,229,244, 28,152, 40, 94,252,168, 72, 87,215, 35, 34,144, 19, 89, 11,152,143,193,183, 63,138, 13,
-175, 66, 79,210, 3, 18,183, 56,123, 14, 80,160, 17,198,164,108,155,163,178, 56,142,101,173,184,146,115,129,180,162,202, 97,245,
-231, 53,147,169,197,209,200,192,154,108,237, 79,168,105,161, 81,162,163, 76, 24,173,182,167,217,159,104,211,110,132,119, 40, 89,
- 11,151,104,253,186, 88,217, 17,193, 1,225,214,145, 35,250,201, 13, 43,160, 15, 42,167,239,113, 48, 1, 68,116,105,173,156,171,
- 94, 1, 8,205,190, 69,190,109,215, 80, 59, 23,244,227, 58,239,157, 58,152,173,173,139,221, 37,115, 14, 14, 28,193, 14,101,240,
- 6,240,184,173,196, 73, 5,168,136, 35,134,218,156,128,134, 27,109,201,144,218,116, 23,104, 11,143,132, 46, 22,234,133,196, 22,
-233, 39,225, 61, 64, 68, 80,158, 86,246,220, 69,234, 45,160, 75,160,156, 51,178,115,192, 9, 88,219,142, 22,224, 62, 71, 16,152,
- 2,106, 16,185,227,194,110, 60, 59,137,132,166,137, 64,137,147, 16,160,205,198, 84, 58,162,172, 8,124,251,102, 84,230, 31, 97,
-118,119,177,106,185,228,144,114,101,105,144, 69,137,108,118, 44,234,138, 70, 92,163,143,129,154,139,170,160,216, 55,101,102,223,
-190,208, 98, 8,100,208,128,252,229, 3,126,242,107,249,189, 60,121, 42,234,179,234, 55, 17,111, 4,197, 36,232,196, 41,114, 45,
-245, 9,178,199,177,141,114,124, 46,112,204, 74, 29, 98, 26,151,225,105,165, 7, 60,237, 58, 89, 55, 31,190, 92,222,219,137, 97,
- 35,111, 92,188,252,192, 44, 79,229, 15,221,242,124, 60, 68,174,130,227,227,103,146,149,170,208,230, 86, 39,202, 15, 31,135,245,
- 65,114,116,122,176,148,223, 70,232,128, 21, 76, 96,244,137,194, 87,244, 84,168,214,145, 10, 60, 93,163, 1,161,126,121,254,230,
- 34,127,116,254,213,183, 43, 8,126,228, 76, 1, 39, 50,193, 71, 39, 98, 27,146, 26, 46, 58, 38,226,122,150,136,148, 82,142, 97,
- 14,213, 84,238, 31, 90,117,246,236,187,239,207, 31,233,159,127,252,233,215,235,171, 63,175, 7,233,162,120, 20,223, 52,131,220,
- 3, 18,217,155, 97,252,227,133,208,189,189, 56,183,147, 95,223, 94,141,127,221,135, 91,109, 46,191,248,244,203,175, 63,243,126,
-220,189,220,149,184, 72, 35,185,141, 21,222, 2,101,113,139, 55,202,251, 59,121,209,139,235,219,240,254, 41,111,195,199, 73,188,
-123, 37,182, 15,210,216,119,220,225, 94,174,141, 14, 3, 74, 96,199,137,106, 28,138, 45, 80,214,152, 35,253, 71,231, 10,172,101,
- 10, 73,107,159, 50,101,198,169,189, 24,204,132,122,188,196,211, 46, 7,122,102,103,138, 5, 28,150,174, 52,172, 23, 0,240,198,
-233, 84,211,169,144,203,125,156,157, 66,200, 81,175,144,192, 26,135,165,177,199,113,180,128, 44,199, 62, 78, 69,177,238,100,217,
- 46,236,232,205,161,115,163, 84, 44,178,102, 34, 39, 38,166,255,165,245,139, 4,172,161,161,207, 54,211,227,185, 37, 7, 5,166,
-217,170,176,114, 29,133, 55, 47,186,218,210,158, 27, 81, 51, 73, 78,185,207,113,193, 99,182, 62,212,155, 12,248,177, 40,199, 37,
-232,225,196,169,152,245,130, 4, 35,166,141, 11,160,105,107, 16,189,153,121, 85, 24, 90, 15, 82, 53,205, 92,107, 52, 64, 22, 11,
- 32,170,234,107, 79,203, 3,189, 65,129, 74,245,114,168, 42,160,175, 22,172,231, 63, 1, 56,186,122,222,184,141, 32,186,203,229,
-146, 75,234,120, 39, 75, 23, 65,137,140,216, 1, 12,216, 93,128,164, 74,145, 38, 69, 2,184, 72, 23,184,201,223, 12, 82, 36,191,
- 32, 48, 16,192,169,156,202,130, 96,201,150, 46,150,142,199,143,253, 36,243, 30, 91, 22,252,218,217,153,247,118,102,222,112,170,
-178,162, 38,142,153, 18,110,233,121,140,199, 99, 98,192, 85,206, 97,138, 28,180, 25,184, 21,167, 18,159, 27, 17, 7, 19,199,143,
-192,104,198,121,208,136, 81, 86,186,121,239,132, 54,135, 49,141, 49,230, 61, 92,142,112, 58,236, 29,126, 84,171,199, 69,126, 51,
- 18,170, 62,140,101,208,243,190, 79,143,128,202,210, 1, 94, 87, 86,243,116,158,151,125,187,239, 11, 64,162, 65,172,225, 84,225,
- 93, 57,176, 1,190, 64,110,130, 3,132, 94,193, 25,219,108,253,248,244,215,239,191, 57, 61,191,118, 87,127,165,224,242,108, 37,
-169, 41,207,108,156,156,225, 46, 21,249, 34, 66, 1,194, 49,168, 6,143, 17, 65, 50,175,193,230,177, 1, 36,179, 5,183,112,109,
-167, 91, 13,204,123,179, 59, 22,117,174, 64, 60,105,104, 62,114,172, 51,214, 15,102, 96,152,107,158,173,131,125, 15, 31,179, 80,
-140, 44, 57,211, 96,255,188, 6,211, 17, 30,222, 39,243, 41, 80,236, 83, 89,117, 7,198, 77,104,232, 82,188,223, 91,131,221,222,
-177,192,109,175, 17,200, 98,116, 45,118,213, 78, 61, 12,221,177,110,236,164, 0,132, 58, 68,148,190, 83,123,150,137,240, 68, 47,
- 89, 32,222, 97,238,119,156, 65,173, 77, 57,144,255, 68,189, 20, 14,177,236, 13, 36, 65,214, 25,194,125,126,160, 54, 37, 40,133,
-142, 49, 91,186,213,242,168,212, 90,206, 70,230, 93,188,205, 68, 67, 5,231, 8,146, 6,158,148, 10,220, 42, 30,105, 22, 23, 48,
- 81,171, 67,185, 12, 2, 68,144, 30,130, 88, 73,157,173, 0,234, 38,234,182, 35,124,215,121,182, 83,109,195,132, 39,176, 46, 66,
-118,168,115, 83,204,133, 11, 35,144, 32, 37, 29,139,246,128,135,250, 88,167, 42,128, 59, 74, 96, 47,188,197,228,128,134,124, 39,
-179,193, 20,195, 7,217,157,134,167,177,242,107,219,249,124, 35, 42, 54,227, 85,169, 63, 54, 48,152,138, 67,117,141, 6,104,128,
- 67,178,172,242, 0, 36, 49,186,160, 48,157, 90,244,208, 41,137, 15,118,235,150,180,117, 57,202,170, 72,251,130,106,217, 58,230,
-124, 81, 29,254, 99,239, 34, 43,193,167,229, 36, 1,200,183, 79,178, 0, 11, 82,172,147,203,237, 28,237, 97, 81,159,244, 20,220,
- 77, 84,248, 99,126,117, 92,154, 59,168,113,183, 90,202,160, 56,170,142,137, 99, 54,198, 33, 48, 38, 42,189,187, 70, 52, 21, 15,
-224,132,125,200, 89, 96, 27, 0,214, 34, 94,172,112, 84,233, 18,204, 90, 83, 7,143,210, 95,112,240, 85,192, 23,131,219, 25,203,
-188, 45, 92,202,116, 16,102,174, 93, 38,229,208, 87,239, 46,211,182,213, 63, 93,204,255,174,204,165,117,109,210, 33, 22, 75,167,
- 32,211,181, 13, 7, 82, 17, 14,193, 11, 31,205,222,202,180,149,115,163,176, 88, 53,192, 74,243,230,246,249,219,222,203,162, 75,
-249,139, 39,245,225, 69,253,123,117,251, 71,123, 88, 7,217,104,146,224, 41, 80, 65, 15, 33, 55,144,169, 26,202,248, 8, 92, 42,
-131, 4,214,255,196,108, 67, 65, 44, 17, 61,155,141, 23,195,130, 59, 12,248, 53, 49, 36,101,106,121,117,213,237,254, 17, 47,127,
-249, 81, 60,125,158,210,184, 28,204,204, 25,119,219, 40,188, 37,205,161, 36, 42,179,241,108,192, 73, 25,181,217, 56, 90,193,179,
-116,115,220,249, 54,153,147,250,187, 31, 94,125,113,246,108,251,250,183,191, 95,191,217,221,218,155,247, 61, 34,213, 42,101,155,
-179,121,216, 40,187,195,255,119,239,238, 91,113, 63,129, 58,232,175, 46,126,126,249,245,118,253,108, 60, 78, 55,239,175,123, 23,
-116, 62,171, 33,236, 66,246, 89,101,243,207,203,253,125, 2, 35, 61,217, 60,122,245,173,248,243,210,124,124,235,190,188, 80,110,
- 20,159,128, 20,239, 46, 87,143,159,244,237,165, 50, 83,116, 71, 35,153, 74, 12, 99,220,136, 59,158,184, 71, 3, 3, 96, 83,124,
- 25,213, 64,225,177,108, 96,175, 5, 66,250, 7,191, 12,237,216,251,222, 20,210, 2,228,152,154,157, 27,136,196,222,122,206,252,
- 59, 72,185,138, 50,114,140, 60, 96,234,193,215,155,178, 45,132,177,122,148,154, 5,136, 92,102,152, 27,220,103,113,148,205,174,
-156, 84,173,215, 28,221, 25,216,150, 74, 16, 95,176,241, 31,251,168,132,191, 57,211,169, 29,244,185,178,201, 0,206,104, 81,212,
-120, 14, 25, 81, 77,136,161, 98,126,178,148,218, 88, 69, 33, 4,172,131,139,118,246, 69,145, 87,107,217, 99, 31,229,115, 9, 67,
-116,211, 88, 86, 0,110,136, 28,121,211,149,105,147,108, 2,126,233,235, 56,229,186,129, 83,108,110,178,185, 6,166, 34,214, 73,
-212, 83,132, 95, 43,241,206, 67, 22, 16, 91,156, 63, 26, 70, 60, 62, 18, 28,197, 58, 98, 25,129, 32,108,252, 95, 0,142,174,109,
- 71,110, 34, 10,186,111,182,219,115,217, 75,130,180,160,136,101,137, 16, 44, 18, 66,130, 55,248, 5, 30,249, 70, 62,134, 7,196,
- 62, 32,144,162, 40, 16, 68, 38,144,157,204,238,216,227,118,223,220, 84,249,213,154,209,140,251,114, 78, 85,247, 57, 85, 58,230,
-137, 12, 17,180,149,230, 7,136, 85,192, 2,128,169,224,234,120,192,170, 82, 87, 86, 34, 58, 12, 77,102,179,132, 18,158,125,241,
-115, 22,224,201, 1, 8, 75,122, 65,129, 15,131,247,116,128, 22,145,215,179, 88, 80,250,204,231,163, 72,113,242,190, 31,104, 23,
-148, 38,188,122,234,246, 27,201,235,201,236,136,171,226, 33, 35,201,227, 71,221,236, 1, 38,220,164, 87,128,137,103,101, 83, 26,
- 57, 91,140,209,196, 75, 53,144, 72, 43,155, 31,190,251,252,233,205,139,240,250, 46,185, 94,183, 45,255, 23,213, 42,217, 84,186,
- 40, 43,179,191,157,124, 73,108,171, 60,242,222,181,234, 88, 58,166, 18, 65, 12, 65,138, 73, 96,162,221,171,203,206,198,246,118,
- 7,114,221, 58,193,155,203,137, 62, 61,129,247, 22, 96,122,128, 73,218, 71, 77, 87,155, 68,158, 67,103,228, 83,146,247,141, 81,
- 97,110,166, 48, 1,126,150, 80, 26, 26,138, 82,123, 75, 1, 18,157,144,239, 78,199,134, 26, 45, 72,119,135,140,117, 6,180, 25,
- 26, 60,140, 84, 26, 83, 46,236,135,183,195, 24,241,145,246,216, 98, 34,138, 21,131, 31,144,149, 16,212,179, 87, 85,168,173,119,
-106,150, 1,228,122, 76, 0, 25, 60,143,157,176, 50, 19,242,133,188, 64,140, 97,175, 58,237,228, 34,165, 42, 67,173,153,234,139,
-158,162,192, 22,218, 34,147,145,113, 0,212, 97,170,169, 59,142,192, 37, 92, 26,145,139, 90,107,220,220,155,121, 44,181,109,211,
-194, 81,144,182,226,170,144, 53, 58, 3,236,167, 52,235,207,165,171, 18, 85, 12,100, 12,139,113, 44, 64, 21, 86,115,239, 49,252,
-211, 97, 66, 48, 77, 94,171,122,148, 3, 16,134,158,207,177, 74,103, 29,212,220, 70,185,146,194, 87,248,154,144, 15, 98,172,189,
- 91,153,245,228, 23,248,191, 69,232,177, 60, 47,104, 87, 2, 73, 20,161,130,166, 41,108, 15, 22, 35,181, 95,212, 42,179,245, 27,
- 41,244, 12, 4,170,163, 89, 34, 27, 94, 89,184,197, 37, 85,139,165,140, 94,205,128,145,157,183, 13,197,179,121,160, 64,140, 45,
-227, 32,104, 25, 6, 24,158,169, 35, 75, 75,211, 82, 58, 62,230, 33, 69, 87,241,230,103, 0,208,170, 12, 79, 40,129,166, 22, 49,
-218,229,200, 1,137,213, 83, 36,169,178,216,171,145,218,142, 34, 86,213, 63,152,189, 16,107,143,244,152,243,182,168, 72, 26,144,
- 41, 88, 56, 81, 49,117, 53,171,161, 20, 58,147,128,163, 33,135, 80,185,160, 96, 92, 22, 13, 40,100, 10,118, 33,179,109,199,166,
- 7,132,183, 55, 85,119, 63,125,121,181,125,254, 68,255,189,214,251,185,217,229,132,160,158, 64,142,146, 2,147,105,117,107, 37,
-210,214, 60, 90, 16, 28,133, 9, 4, 61,221,252,233,182,127,132,106,101,246, 82,126,116,213, 30,111,213, 79,230,223,223,122, 30,
- 81, 47, 62,142,129,208, 10, 60,146,186, 88,143,248,170, 20, 8,103, 38, 83,243, 92, 4,101, 75,245, 88,137, 53,141,102,210,105,
-169,162, 1,120,224, 5, 26, 59, 78,166, 88, 0,146,173,110,119,255, 29,214,219,139, 15, 16,220,251, 35,251, 0,245, 57, 91, 32,
- 3,237,226, 37,226,123,228, 41, 28,134, 21,127,114, 17, 20,193,156, 1, 48,199,162, 78, 46,204,177,212,121,238,223,255,181,159,
-218,205,179,103,223,254,248,225,243,239,191,186,251,229,247,159,127,189,123,249,118,247,248,206, 31,119,111,232,202,215, 98,237,
-175, 53,239,233,175, 46, 63,254,250,211,111, 62,251,226,250,230,226,245,110,220,191,122,183,239, 29,182, 8, 38,240, 2,139, 59,
-158,211, 94, 49, 1,157,244,195,211, 49,182,241,137,145,215,183,230,240,114, 2, 89, 63,195,198,191, 79,101,255, 66,220, 92, 39,
-195,247,174,128,250, 43,182, 79,204,117,245, 8,226,125, 84,105,120,200,101,147,139,243, 8, 73, 9,112,109, 96, 29,111,156,253,
-227, 82, 21,210, 4,160, 78,188, 77, 83, 88,164,154,168,221,197,221, 81,162,170, 61,137, 77,172,151, 26, 50, 96,169, 99,103, 62,
- 17,141,201,254,210, 96,157,121, 58,211, 81, 20,201,173, 83, 55,218,216,104, 59,167, 77,215,101,140,167, 0, 37,232,128,105,105,
-221, 7, 56,176, 54, 98,219, 84,253,144, 18,213, 66,145,130,130,110,241, 98,118,122,207, 62, 14, 43, 12,130, 26, 85,129, 77, 61,
- 63, 36,138,156,153, 88, 76,202, 23,202, 78, 72, 35, 52,105,203,114, 80,170,211,101, 85, 64, 0,188,231,221, 54,165,185,183, 39,
-155, 78,162,119,198,117,137,149,150,179,232,168, 68, 94, 81,123, 75, 81, 16,164,139, 54,102,170,250,177,168, 27,116, 67,234, 88,
- 19, 72, 69, 36, 57, 63, 96,128, 53, 64, 95,193,242,149,255, 11, 64,210,181,244, 70, 82,131, 65,219,237,118, 63,103, 54, 67, 66,
- 86,236, 30, 65, 92,216,189, 33, 78, 72,252,110,254, 1, 18, 55, 36,132, 64,218,195, 34, 8, 9,217,204,163,159,110, 63,169, 26,
-110,163, 25, 37, 99,181,198,245, 85,217,223, 87, 5,198,139, 55, 83,117,205,227,243, 91,187, 50,172,158, 97,215, 21,141,169,153,
-121,134,253,239, 12,155, 89, 54, 70,165,104,246,200, 41, 72,254, 92, 3,161,193, 80,105, 70,192,158,120,207,227,229,188,216, 69,
-206,107,192, 6,234,221,112,206,178,170, 2, 54, 61,243,177,193, 3,151, 44, 47, 18,132,139, 57,100,248,239, 16, 86, 22,251,204,
- 62,138, 65,230,131,204, 77,163, 27,154,168,107,218,118,208,236, 79,185,207,251,198, 45, 15,210,125,245,217,155, 31,222, 43, 49,
-252,226,220,200,169, 33,193, 57, 25, 81,156,175,142, 56, 90,200,149,151, 48, 32, 89, 49,210,206,166,204,108,247, 98, 76, 47, 56,
-219,202,154, 85,120,194, 2,147,185,193,167,126,127,253,218,248,151,111, 78, 19, 4,215, 5,196,134,190, 31,190, 10,160,169,180,
-118, 1,140,187, 20,156,247,141,240, 43, 27, 13, 23,179,228,189, 42,226,148, 92,118,155,114, 96, 72, 98, 70,217, 8, 3, 8,172,
- 43,216,100,139,114,200,148,190,109, 98,136,113,156,128,157, 43,227,171,150,225,165,146,219, 53,232,173,146, 26, 27,104, 89, 41,
-118, 47,249,128,109, 8, 44, 90,155, 81,131, 91, 11, 72, 75, 79,173, 15,100, 0, 75,195, 82, 64, 4,165,100,152, 3, 49,171, 99,
-142,234,186,226,209, 56,212, 5, 0,153, 88, 38, 84,180, 30, 63, 16,195, 11, 31, 14, 66, 54, 0, 67, 8,242, 90, 49,108, 59, 74,
- 91,209,120, 40, 31,107, 93,225, 49, 67, 6, 64,111, 6, 0, 97,240,105,199, 62,153, 64, 59,217,125,199, 28, 14, 14, 99,162,204,
- 0,217,232,110,153, 44,106,137,235,186,249, 57, 88,115,233,241, 65, 40, 42,181, 48,149, 24, 85,108,252,228,119,183,182,208,144,
-222,145,110, 58, 33,153,125, 53,102,191,110,246, 85, 86,173,173, 38,200,142,181,164,222,193,131,155, 33,187, 51,104, 15,115,182,
-153,164, 19, 64,161,116,180,170,174,233, 65,154,247, 70,245,130,254, 26, 32,182, 91,193, 23,103, 87,188, 2, 1, 43,233,220, 89,
- 50,126, 38, 95, 7,223,141, 49,110, 99, 72, 22,160, 90,172, 46, 39,218,239,179,143,128, 41, 42, 32,196, 91,125,157,191,135,248,
-228, 69,119,206, 27, 39,126, 56,166,169, 65, 56,128,188,215,201, 31, 30,177,114, 96,143, 23,147,248,107,182,130, 9, 57, 95,135,
-248,119,244,229, 80,195, 99,130,240, 49, 45,190,161, 14,163,143, 21, 37, 69,169, 64,139, 12, 83,215, 45,196,186, 47, 86,158,227,
-153, 80,196, 22, 11, 64,101,192,154,186, 8,238,147,153,190,147, 70,246, 50, 21, 80, 78,155,142, 31, 93, 89, 62,184,251,103,113,
-127,147,223,220,164,175, 81,187,218,254, 92, 84,199,235,133,192,255,173, 41,120,113, 39,194, 1,218,244,195,116,243,167,197, 86,
- 63,183, 97, 86,197,219, 54,181, 95,202, 31,229,252,219,249, 52,230, 98,199,211, 82, 23,120, 22,164,212,246, 41, 89, 80,170,193,
-210,190,110, 39,244,139,168, 24,159,155,237,172,128,172, 37,120, 59,239,106, 20,170, 54, 39,154,178,215,109,206, 35, 13,144, 68,
-128,246,139,207,131, 59,128,249,237,202, 56,175,215, 40,129,149,199,123,122, 75,195,150, 54,250, 6,130, 85, 1,208, 83,213, 39,
-239, 34,141,119, 20, 3,198, 54,185,218, 35,125, 26,227,108, 87,183,232,203,135,191,157, 44,210,225,237,251,239,111,223,125,247,
-237,113, 60, 63,157,198,143,207,159,214,241, 52,228,164,110,191,184,171,119, 96,154,123, 54,207,249,225,215,159,255,152, 98,158,
-138,135, 46,246, 76,144, 4,105,238,101, 33, 39,227,132, 59,165,214,136,233, 37,222, 87,254,167, 39,245,143,200,173,209, 79, 83,
- 58,152, 34,156,130, 56, 98,181,250, 95,157, 74, 11, 56,116,192,249,115,176,113, 62,166,155,251, 92,230,139,113,251,229,217,250,
- 46, 50, 23, 3,144, 34,252, 2,242, 99,183,150,222,117, 18,171, 45, 93,153, 56,196, 95, 89, 48, 22, 77,155, 1, 80,240,158, 39,
- 34,156, 46,138,177,108, 65,153, 58,126, 23,211, 1, 26, 14,218,119,138, 97,125,181,169,116,209,207,114,151, 42, 0, 90,212, 37,
- 42,121,220, 70,189, 55, 7, 0,190, 42,111,188,190, 20,120, 60,194,252, 53,165, 22, 98,175,234,238,130,154,202, 30,187, 82,174,
-171, 19, 27,180,168,174,187,176,177, 35,222, 0,240, 32, 55,186, 86,199,156, 70,191, 78,170,223,117,126,184, 88, 35,119, 2,197,
- 99,140,156, 33,215, 13,216, 55, 8,119, 90, 68,120,220,249,186, 48, 77,233, 87,104,186, 36,167,230,226, 7,206, 33, 54,154,209,
- 0,216,232, 75,140,248,205,135,220,162, 70,129,136,174,103, 81,148,214,211,123,104, 95, 65,228, 98,179, 91, 20,122, 19,107,241,
-159, 0, 28, 93,203,114, 27, 55, 16,196, 99,176, 79,146,178, 20, 39,246, 37,135, 84,202,151, 28, 82,190,228,183,115,200,111,228,
-150, 31,200,193, 86,149, 28, 75,162, 72,238, 46, 22,192, 2, 72,247, 94, 84, 69,145,172, 2,177,192, 76,207,171, 91,172, 25, 83,
-217, 43, 76, 66, 12, 76,178, 47,214,244, 52,156, 81,194,194, 74,161, 48, 52,150,146,114,195,121,174,241, 2, 67, 8,180,157,215,
-179,103, 27,123, 18,231,218, 9, 59,231, 23,210, 65,132, 85,227,194,190,136, 99,131,226,249, 81,159,190, 44,106,128,101,243,209,
- 78,193, 58, 55,219,101, 72,115,241,247,155, 5,168,224,236,160,237,154,244, 83, 41, 10,174,239, 46, 14,164,169,159, 41,179,163,
- 6, 11,219,212,144,200,222, 73,255,199,231,223,212,240,247,250,245,121, 39,220, 36, 33, 24,126, 66,166, 46, 48,236, 98, 75,102,
- 54,246,199, 45,120,168,137, 57,108,216, 43,248,135, 75,214,158,117, 52,252,221, 12, 11, 98,228, 61,150, 98,159,224,143, 63,220,
-255, 58,135,195,102, 39,201, 41, 25,132, 91,158, 35,229,134,196, 11,235, 10, 39, 88, 42,112,244,118, 99,246, 32,213,212,152, 57,
- 45, 56, 22,136,216, 16,198,198,236, 3,155,108, 18, 73,103, 36, 51,175,117, 41,184, 51, 76, 1,248, 55,246, 44,133, 93, 80, 57,
-171, 17, 1, 60, 28, 88, 9,214,195,218,179, 21,177, 32, 6,190,172, 4,159, 90,183, 62,168,113,203, 17,160,151,233,255,107,140,
-192,255,184,245, 3,240,218, 72, 21,244, 32, 98,111,148,196,214,216,101,236, 76, 78, 0,176,147, 40, 67,138, 22,166,162,185,109,
-153,204, 19,236,211, 0, 16,206,205,181,179, 29, 14,192,140,120,170,148, 3,147, 77, 64, 18,116,193, 42, 33, 62,192,243, 12,213,
-205,249,244, 94, 66, 99,205, 93, 40,177,151,195,129, 41,254, 25,192, 3, 40, 46,199,182,152,196,161,215,150,165,245,154, 0,163,
-231,209,133, 37,187, 53, 68, 26, 74,224, 3,234,157, 31,222, 33,220,170,111, 79,105,124, 96,241,129, 5,201, 31, 56, 54,160,137,
- 7,136,142,143,138,100, 91, 51, 62, 73,158, 30,132, 70,210,155, 12,200,239,243,127, 29,140,190, 57,236,134,100, 21, 59, 14, 84,
-111,215, 8,163, 90, 38, 8,152, 87, 35, 49, 88,180,123, 3,123, 98,181, 92, 79,108,245,101,177,153,100, 3, 66, 97,176,147,162,
- 20,193,209,108, 15, 77,216,135, 22,178,164,232, 53,135, 40, 97, 97,216, 56,100,202,222,191,141,175,236,165, 84,224, 23, 47,204,
-222, 32, 30,118,100, 25, 99,107, 57,208,205,178, 40,248, 14,137,223,107,189, 58,118,254, 86, 68, 7,134, 21, 29,220, 91,129, 11,
- 77, 8,162,157, 83, 84, 36,188,193, 39, 73,236,175, 52, 16, 30,168,176, 82, 24, 39,113,226,181, 52,136,152, 55,149, 78,236, 34,
- 3,120,161,222,163,228, 91,172,245, 91, 73,207,101,216,139,201,119, 77,252,185,121,203,164,214, 46, 20, 34, 90, 77,190,250, 19,
- 86, 48,245,183,193,172,157,195, 89,236, 7,215,254, 62,252,121, 58,255,117,254, 14,152,170,242, 5, 48, 37,225, 92, 82,159,252,
- 5, 91,105,124,205,225,155,226,131, 95, 85, 63,215,249,163, 30,135,156, 88, 93, 84,249, 70,201, 32, 98,246,180, 1,155,168,169,
-232,214,152,168,107,103,131,231,131, 35,145,219, 74, 30, 15,213,146,108, 81,193,192, 52,212, 14, 6,198,201,189, 10,243, 84,146,
-179, 43, 96, 45,222,155, 72, 67, 5,128, 27, 18,192, 61, 86,198,230, 43,102, 67, 16,247,157, 61,254,161,174,241,245, 75,246,109,
- 26, 92,119,255,254,151,187,143, 63,126, 74, 90,228,237,117, 13,151,171,170,203, 37,191,132,199,233,201,222,166,249, 70, 54, 39,
-224,229,160,165, 69,232,174,118, 38,255, 9,119, 7, 22,255,249,221, 67,124,124,250,148,190,254,243,239,230, 67,184,151,122,196,
-130, 99, 89, 97,219,158,167, 1,160,246, 10,120,118,189, 53,186,103,227, 47,238,235,169,191,226, 54,158,133,178, 47,146, 0, 14,
-194, 25,168, 2, 32, 42, 47, 91,237, 68, 0,107,241, 45, 83,230,104,173, 5, 80,223,194,166, 71, 1,200,216, 56,138, 90, 29, 85,
-109, 72, 0, 36,100,245,201, 83, 60,178, 63, 76,218,200, 12, 56, 41,156,100, 68, 8, 67, 64,104,212, 65,177, 67, 77,198,198,104,
- 0, 65,215,142, 36,110, 50,212,254,164,218, 48,169, 63, 77,122, 72,125,118, 8, 12,230,238, 3,185,156, 56, 57,221,247,205,210,
- 32,120, 85,100,149, 98,182, 59,194, 27, 52, 50,159, 97,193, 23,193, 75,111,201, 86,171, 11, 66, 0, 59,183,236,130,133, 5,210,
-177,175,162,187, 62,110,210,135, 48,177,113,181,117, 71,173,131, 80, 33,110,216, 26, 99,231, 87,135,159, 77, 69, 83,158,239,122,
-152, 87,229,186, 0, 43,120, 8,173, 87,106, 29, 97, 73, 28,245, 57,214, 90,143, 19,236, 78,252, 95, 0,142,174,100, 55,114, 27,
- 10,114, 17,181,219,221,157,113, 14,185,206, 57, 64, 78,249,253,252, 67,144, 91,144, 5, 51, 8,130,140,103,236, 94, 36, 74,220,
-153, 42,157,220,134,221,232, 22,249,248, 88, 69,190, 87,213, 80, 59, 7,171, 38,174, 5, 4, 92,233,206, 43, 13, 14, 5,196, 24,
- 65, 10, 52,205,152,203,109, 46,237, 2,226, 44,124, 94,144,254, 90, 49,198,107,168, 14, 8,117,140,222,215,253, 10,230,232,241,
- 0,114,127,187,109,143, 57, 54,207,226,191,111, 36, 54,193,167,137,141,230,200,209, 30,223,194,224, 71,158,237,195, 97,104, 59,
-124,147, 57,250,149,198,160,145,226,131, 18,127, 13, 98, 27,205, 56,237, 31,202,178,116,151, 11,128,162,147,189,158,238, 47, 63,
-125,188,137,253, 47,208, 11,149,222,138,105,168, 64,154, 78,138,183, 3, 36, 17, 72,241, 20,255,162,152, 57,149, 78,216, 22,201,
-170,234,227,138, 77, 62,240, 60, 57,129,139, 71,138,195, 24,226,197, 16,254,232, 47,151,203,240,227,167, 55, 57, 15,200,253,155,
- 8, 81,165,167, 82,239, 89, 97,207, 26, 85,107, 11,151, 41,189,237,188, 2,122,163,141, 47,192,123, 42, 90,198, 83,109,240, 27,
-128,174,207,182,219,250,140, 96,234, 71,225,202,251,251, 87, 68, 78, 4, 59, 6,254,175, 98, 79, 87,225,238,143,210,182, 49, 57,
-207,195,125,154, 55,246, 72,210,157,122,240, 90, 54,230, 71,195,162, 65,250,212,230,185,105,157,165, 99, 64,117,204,108,171,170,
-131, 3,189,148,116,228, 96,131, 11, 91, 28,183,210,130,206, 60, 89,189, 99,207,126, 46,142,218,243, 77,192,174,158, 0,226, 88,
- 7,210, 4,177,219,195,230,124,170,136, 68,115,146,188,245, 91,203,214, 96,198,117,237,187,231, 41,143, 69,154,234, 64,231, 89,
- 35, 5,254,125,103,163,121, 90,133, 26,171,180,149, 94,189, 49,221,190, 22, 53,202,100,252, 82,244,249,154, 73, 43,121,102,165,
-122,161,242, 85, 15,137, 71, 32, 93, 2,118, 85,214,176, 19,114,152, 8,173, 61, 27,133,148,106, 87, 60,204,104,155, 77,214, 14,
-244,180,232,188, 19,117,128, 43,134, 68, 26,216, 15,131,142,131, 4, 58, 42,251,145,102,123,246,214, 49,206, 90, 45,193,240, 14,
-237, 78, 76,171,178, 66,173, 53,207, 42,130,110, 96,195,156, 68,155, 59,204,164, 70, 32,181, 2,235,203,217, 60,204,233,232,208,
-164,154,251, 20,211, 81, 21,227, 59, 49,178,248, 91, 99,196,103,122, 23, 48,209, 7,126, 16,251, 65,122,124, 20, 59,195, 40, 84,
-102,232, 5, 42, 91, 67,211,202,249,117, 69, 92, 86, 22, 49,131, 49,240,214,183,178,102, 22,111,190, 53, 89, 73,123, 40,248, 41,
-229,212,107,163, 46, 2,208, 10, 3,151, 7,234,112,139,118,207, 71,161, 28, 32, 38,248, 49, 18, 39,208,132,169, 10,203, 13,147,
- 67, 99,214,202, 18, 70,132,126,162,217, 13, 85,156,217,141,137, 45, 10, 25,196, 85,241,250,116, 49, 72, 77,141, 83, 20, 30, 79,
- 47, 31,187,223,166,237,151, 47, 64, 79, 60,166,194,192,111, 52,139,205, 71, 31, 23, 64, 81,113, 65,148, 71, 46,126, 9,197, 74,
- 80,222,243, 72,159, 18, 22, 11, 88, 13,106,230,217,122, 2, 24, 76, 12,171,230, 14,255,141, 1, 60,212,232,132,191,138, 31,206,
-227,195,110,238,207,191,219,243,207, 30,176, 92, 99,132,105,150, 24, 8, 22, 34, 91, 72,188, 96,157, 87,241, 32, 41,160,170,120,
-133,133,229,253,225, 58,160, 49,226, 75, 80, 82,223,204,225,115, 33,246,165,245,106,245,136,116,139,216,247, 59,189, 35,245, 53,
- 44, 9,112, 93,174, 95,154,165,185,150,171,204,223, 81,201,146,167, 81,255,150,199,188,181,152,189, 15, 34,149,224,254,137,214,
-127,127,118,191,219,151,207,191, 46,183,245,126,103,151,232,173,169, 19,183, 40,236, 39, 34,174, 14,216,188, 2,249, 33, 39,131,
- 63, 45, 91, 87,245,202,227, 10, 23, 1, 32,108,197, 2,237,218,224,124,115, 15,216,210,132,193,211,239, 18,212, 26,236, 40,237,
- 9,107,205, 28,118, 32,135,192,115,234, 39,154,140, 33, 75, 3,239, 40,221,142,181,169,131, 66,226,180,134, 66,133,173, 1,247,
-108,193,104,135, 25,217,163,222,198, 48,200, 49,116, 13, 2,184,243, 81, 13,192,223, 39,140,141, 33,110,161,113,119,159,106, 55,
- 40,149,207, 3,207, 32,232,155, 46,117,223,108,119,197,195,164,201,104,202,192,124, 19, 79, 10,100, 14,252, 91,123,111,222,105,
-144, 80, 1,212,134,177, 75, 22,137, 95, 90,227,187, 14, 9, 98,239,195,201, 2, 78,130,209, 83, 6,164,244, 64,138,157, 88,246,
- 94,110, 64,147,195, 94,119,141,172, 31,125, 0,119, 6,121,152,183,149,198,246, 82, 15,110, 45,236, 27,206,170,189, 54,192,100,
-200,218, 3,165,156, 82, 10,173, 42,230, 68,128,244,191, 0, 28, 93,203,174,219, 54, 20, 20, 41,190, 36,217,206,189,185,105,208,
-166, 64,139,162,139,254, 64, 63,190,171,126, 64, 86,249,129, 22, 13, 16,116,147,220,218,214,139,164,248,234,140,183,182, 97, 75,
-242,225, 57, 51,228, 57, 51, 10, 48,255,212, 79,115, 57,216, 32,194,241,143,195, 87,106,118, 55, 73, 5,249,157,147,113, 59,178,
-229,150,192, 49,140,233,102,101,199, 12,164,236,173,174,135,162,178,111, 73,184,195,227,118,127, 40, 52,136, 65,223,193,253, 81,
-216,234,181,230,237,240,103,106,162,208, 77,187,173,161,142, 95, 99, 30,121, 21, 46,149,225,222,217,231,114, 63, 78,148,252, 60,
-117,147, 29, 53,202,237, 64,185,136, 55,193, 88,186, 28, 95,116,255, 60,216,237,237,143, 47, 79,147,239, 94, 55,110, 65, 14,156,
-196, 0,170,163,113, 55,213,113, 18,129,153,160,175, 39,233, 63,231, 11,143, 14,165,191,115,212,237,102,119,140,104,156,126, 71,
-222,191, 80, 24, 74,239,108, 87, 91,182,172, 62,189,127,249,112,155,127,222,226,235,148,143, 80, 76,213,171, 0, 71, 21,139,180,
-247,178,245,148,208,169,166,248, 21,196,133,115, 17, 8, 41,143,175,227, 17,214,173, 33, 72,193, 19,187, 45, 3,202, 47, 35, 74,
-159, 57, 47,102, 93, 55,144, 16,237, 54,124,116, 69,237, 10, 0,174, 57, 57, 30,114,112,252, 23, 40,226,219,125,165, 79, 33,187,
- 72,211,212,197,123,118, 23, 95, 77, 85, 30, 65,132,240,111,180, 52, 74, 22,233, 38,215, 77,250,222,212,173, 68, 42,183, 9,199,
-252,140,234,212, 45,246, 33, 56, 27,133, 91,132,140,242,100,250,237, 5, 40,171,239,246,138,136,215, 99,122,166,200, 20,133,246,
- 3,202,248,214, 80,112,202,185, 71, 54,186,116,122, 30,114, 6, 29, 63,248,144, 64,225,182,210,118,148,243,198,182, 61,182, 80,
-209,205,128, 6, 95,101, 60, 68,224, 30, 99,100,223, 28, 66, 10, 81, 98, 81,118,197,150, 26, 80, 44,174, 39,112,202,121, 71, 18,
-227,161,128,182, 53,103,119,148, 59, 45, 80,216,169,170,242,102,180,162,188, 15, 10,151, 57,178, 53,103, 30, 81,171, 42,107, 14,
-198,136, 71, 35, 36,222,158, 75, 25, 59,245,116,136,152, 29, 64,147, 65,214, 69, 32,129,143,177,145, 65, 70,164, 4, 90, 30,119,
-108,103,224,212, 25, 86, 38, 72,186, 12,185, 23,113, 15,146,210,122,184,137, 81,156, 63, 40,241,185, 0,189,179, 98, 2, 89, 81,
-115,157,122, 75,125,246,168,124, 15,241,200, 70, 41,111, 46, 77, 36,119,253,152,211, 44,141,173,241, 8, 28,206, 40,123,206,139,
-133, 18,228,230,187,227, 63, 64, 89,234,123, 10,188,241, 24,143,145,160,104,135, 86,244,235,176,249, 97, 20,200,189, 60, 89, 40,
-218, 60,208, 94, 21, 4,141,253,142,148,103,174,197,148, 30, 1,122,165, 11, 26,234,164, 82, 88,229, 72, 29, 29,173,174, 2,101,
-231,237, 78, 1, 42,192,103,167, 72, 26,232,121, 60, 37, 4,159,202,120,140, 91,113, 79, 78,124,223,255,185,126,185,202,221,114,
- 60,203,235,176,114,107, 19,176, 60,236,113,161, 44,121,211, 73,244, 94, 92,231,250,250,185,157, 92, 60,153,119,114,144, 53, 30,
-137, 7,246,141,154, 52,138, 66,229,212,151,111,146,237,156,162, 46,175, 10,124, 54,250,116,249,193,134,254,254,207, 95,127,252,
-246,242,187,253,229,167, 24, 61,208,160, 84, 99, 79, 57,150,142,219, 87,192,245, 1,127, 39,126, 18,220,253, 6, 96,212,184, 1,
-207,237,196, 76, 23, 24,173, 53,149,142, 81, 51, 35,125, 51,147, 99, 11,143, 68, 53,156, 61, 45,147,114, 89,247,229,240,113,141,
-173,198,217,190,235,210, 56, 81,198,182,177,117,220,128, 74, 32,207,231,136,252,180,179,249,228,242,235, 80,235,251,111, 31,183,
-127,255,254, 50, 11, 96,155, 41, 68,175, 57,148, 96, 30,179, 86, 97,233,147, 18,212,223, 21,233,109, 1,107, 40,189, 86,203,150,
-212,186,234,129, 13,175, 43,136,116, 70,102,209,209,161,218,246, 62, 56,121,219, 85,241, 61, 18, 42, 24,172, 73, 60,140, 2, 52,
- 81,108, 84, 3,140,146, 60, 87, 65,150, 96, 36,209, 77,199, 21,117, 29,229,100,237,119, 88,223, 13, 68,199,225, 63, 62,143,221,
-130, 84,175,198, 52,161, 84,208,180, 79,115,243,118,170,101,125,156,113, 79,102, 77,245,121, 6,178,175,184, 37, 1,178,145,109,
- 59,245, 2,164, 89,157,101, 59,144,156,146,113, 3, 37, 51, 0, 54,164,166,156,128,170,170,153,113,113,157, 93, 78, 58,134, 10,
-236,164,213,137,248, 2,117, 84, 61, 25, 92,211, 28,103, 35,135,118, 18, 10, 15, 8, 16,222,169,103,105,108, 78,200,101, 87, 82,
-184, 55,173,124, 53, 72, 73, 58,245,120,156, 96,111, 15,155,103, 80,106,141, 34,133,117,131, 87,247,155,202,163, 77, 19,126,218,
-143,157,199,119,239,234,127, 1, 56,186,146,221, 56,110, 40,200,230,214,235, 44,138, 44, 71, 8,178,220, 2,127, 82,254, 49, 63,
-146,107, 16, 32,200,201,128,141,216, 66,100,123,102,122,103,147, 77, 50, 85,115,211, 65,208,140,154,236,247,170,222, 82,165,165,
-220, 6, 65,163, 99,147,145,119, 41,194, 40, 51,155,154,160, 72, 35,135, 29, 16,116,186,135, 2,169,203,185, 85, 47, 98, 38,121,
-247,114, 92, 47,151,162,168, 29, 37,232,144,106,163,112,118,230, 94,148, 12,248,149,117,162, 25,225,142,104, 22,228, 12,216, 42,
-253,200, 78, 20, 64,122,211, 26,110, 11,172, 51,112,211, 91, 43,108,117,174,233, 37,242, 6,231,175,252, 85, 71,202, 78, 5,113,
-214,128,132,171, 81, 22, 84,193,109,233,233,220,138,118, 88, 23, 78,186,222, 25, 60, 94,170,219,142, 8, 73,213,159,142,251, 89,
- 8,217,120, 67,129,143,239,179, 46,220,244, 48,180, 44,224,198,224,134,159,117, 98,199,144,105,157,230, 23, 96,209,136,239,241,
-253,233,244,247,177,252,229,245, 22, 56, 64, 70, 45,218,151, 98, 71,220, 70,242,236, 65,187, 29, 30,195,202,154,158,201,115, 68,
- 52,103, 93,123,247, 8,105,235, 85, 82,133, 72,222,162,239, 82,139,244, 50, 43,159,194,164,229, 25, 7, 63, 58, 94,220, 13, 33,
-226,150,235,117,191, 93,229,148,166,151,121, 20,235, 68,209,135,218,252,248,253, 35, 30, 73,109, 90,183,111,249,210,191,188,190,
- 2, 10,231,206,109, 86,151,153, 54,124, 60,128, 44, 78,108,127, 23, 75, 45, 56,115,189,199, 53,113,220, 70,225, 36,167,146,245,
-117,134, 23, 28,229,230,167,148,125,230,170, 60,110,145, 85, 64,133,116, 18,171,112, 40,214,238, 21,103,252, 4,167,191, 1, 28,
-123,252, 61,135,212, 34,171, 50,207,134,187,127,143,201, 52, 21,176,191, 95,191, 1,254,202,253, 62,236, 7, 84,156, 7, 78,128,
-126, 3,200,180,212,196,144,222, 37, 10, 84,236,116,226,200,236,194,115,182,143,221, 19,186,187, 80, 8,173, 51,224, 42,200, 12,
-236,245, 68,215,207, 15,246, 64,253, 35,118,194,140,138, 96,146,189,162, 58,174, 2,203, 12,118,140,125,187,181, 25,236,155,255,
- 88,205, 45,188,134,147,150,117, 77,147, 87,110,205,149,193,229,184, 37, 41, 27,246,204,243, 5, 48,214, 82,198,169,207,177,165,
-139,227, 93,139, 11,175,227,232, 89,141,148,166,101,205, 37,164, 16, 10,188,174,106,224,228, 67, 72,247,137,200,187, 91, 44, 40,
-121,212,108,171,110,154, 15,150,133,247, 21,193,152,138, 35,156, 3, 46, 5, 88,180, 42,185, 7, 80, 70, 23,116,181,147, 59, 55,
-244, 88, 1,106,162, 86, 65,187, 35,120,131,150,129,227,176,113,221,112,233, 77,123,100,109, 64,117,196,123, 31, 92,101,247,141,
- 27,127,182,160,119,129,166,249, 6, 62, 18,232,123,111,234,240,149,142,123, 5, 64,205,102, 20,222, 59,124,161,218, 16, 49,177,
- 70, 98,193, 17, 42,155,211,146,119, 59,112,157,241,135,159,139, 63,212,235,159,251,144,149,213,211, 18, 47,189, 87,139,159, 56,
- 10, 73,195,123, 67,165, 85,164, 97,186,233, 62,157, 64, 54,253,167,247,225,185, 25, 79,143, 71,127, 87, 24,208, 5,115, 50,190,
-180, 90,164, 63,112,242,231,176,164,237, 44,154,149,138,128,206, 81,137,234,167, 99,101,191,251,248,249,243,239, 79,221,111,234,
-249, 87,143, 84, 42,157, 80,120,193, 43, 26,213,196,188,226,144, 34,117,165,129, 29, 21,181, 74,150, 82,182,130,123,237,177,203,
- 71,167, 38,155,254, 83, 13,189,228, 29,168, 96,214, 95,110,171, 54, 49,237,126,190,174, 87, 59,131,114,233,194, 53,117,213, 54,
-199, 61, 12,128, 4,130, 57,199, 87,243,162, 6, 85,212,169,242, 75, 6,126, 56,191,233,230,217,254,243, 87,248,247,131,248,202,
-205,120,202, 54,236,162,162, 44,180, 24, 11,220, 88,209, 93, 62,188, 91, 63,125, 76,122,158,122, 26, 52, 26,218, 44,214, 27, 29,
-135, 39, 90,193,109,146,149, 89, 42, 58,219, 27,237, 37,112, 53, 16,191,131,182,145,152, 47, 41, 42,251,130,196, 55, 13,167, 74,
-138,189, 43, 21,200, 13, 39, 90,235,128, 92,165, 21,194,181, 56,120,164, 1, 22,181, 41,212, 89,166,170,156, 99, 99,236,246, 28,
- 15, 44,245, 85,186, 68, 78,193,197, 86,173,170,113,159,113,251,140,139,111,181,178,143, 53,213, 83,167, 32,170,178, 80, 72,223,
-184, 31,235,152,142, 32,183,166,110,251, 42,149,243, 22,189,211,174,209,231,213,129, 98, 1,231,112,238, 36,157, 92,140, 97, 91,
- 31,170,135,173,248, 66,220, 50, 25, 87, 15, 21,216,156, 9,137,132,179, 96,113,212,166,212,204, 35,179, 57,167, 10,105, 62,225,
-150,250, 80, 13,171,242,200,181, 68, 51,138, 50, 27,177,169, 64, 72,142,210,244, 0,214,118, 47,186, 62,176, 30,210, 60,137, 98,
- 48,251,204, 18,208,255, 2,144,116, 53, 45,146, 20, 81, 48, 63, 42, 51,235,107,186,123,220,113, 6,196, 69,193,133, 5, 5,193,
-131, 39,143, 94, 61, 9,254, 71,127,132,226, 94,244,224, 65,240, 34, 8, 10, 11, 30,220,117,183,157,174,234,250,202,172,204, 74,
- 35,202, 62,244,165,153,238,170,156,151,239, 69, 84,190, 23, 65,191, 31,181,103,184,235,186,251,193, 26,143,149, 19, 84, 43,116,
-224,144,160,252,107,154, 47,210, 95, 17,165,131,178, 69, 19,240,121,148,235,232, 84,139, 60, 55,129,145,129,189,115,228,106,200,
- 19,211,189, 6,162,176, 51,155, 63, 66, 25,170,140,108,102, 23,160, 60,175,106,118,249,133, 56, 57,141, 77,185,210,175,224, 50,
- 99,117,148, 57,196, 33,214,215,233, 8,160,117,123,191,205, 7, 93, 10,195,230, 24, 16, 51, 93,173,167,224,176,123,150, 40,204,
- 69,216, 34,147,138,154, 40,238,104, 51,203,195, 85,108, 89,154,157,201,236,212, 46,174,202, 35,214,141,219, 1,133,155,170,200,
-192,229, 9, 53,161,204,236, 98, 29, 84, 92, 16,182, 20,232, 3,147,158,254, 58, 61,232,252, 26,140,104,177,241,228,173, 34,102,
-167, 43,166, 10, 73, 81,219, 17, 49, 27, 84, 95,232,185, 47,106, 11,170, 60, 79, 85, 64, 65, 13,201,214, 23,139, 36, 18, 85, 23,
- 55,191, 48,244,215,116,209, 4,193, 20,176,201, 22,148,166,155,175, 69,124,236,253, 77,121,253,226,163,167,159,124,250,217,215,
-223,124, 41, 45,192,119,191, 79,205,239,122,127,120,157,139, 63,127, 27,190,253,238,231,239, 95,252,244,234, 77,135,244,114, 83,
-131,240,129,195,122,189,242,160,135, 77, 61, 27,251,127,176,213, 34,111, 22,252, 47, 81, 26, 39, 2, 11, 1,246, 43,199,142,106,
-154, 9,105, 85,176,239,249,180,106,167,171,113, 43,117,232,163, 82,180,220, 4,207,177,165, 67, 52, 83, 36,113,166,104,161,197,
- 34,201, 18, 76, 48,251, 74,250, 78,186, 41, 45, 39,109,218, 4, 44, 61, 93, 65, 60,215,124, 37, 37,197, 15,252, 11,252, 38,166,
-144,139, 85,146, 14, 57,206,121,225, 54,105, 98, 8,146,128,234,242,142, 48,156,134, 54,121,238, 85, 5,154, 48, 97,193,129,167,
-253,130,255,114, 28, 70,165,195,120,169, 98,241, 79, 58,221, 33,199,220,180,135,218,190,127,231,222,189,111,155, 18,185, 18,232,
-228,229, 62, 51,105,247,101, 65,126,124,178,191, 87, 66, 92, 70,132,215,220,142,221,129,112,103, 14, 27, 72,141,200,224, 41,212,
-171, 9,162, 1,139,104,220, 82, 60,112, 54,199, 80,149, 94,243, 49, 22, 69, 83,157, 17, 11,213,186,145,246,197,133,110, 37, 76,
-244,102,151,204,162, 74,130,227,175, 85, 8, 40,199, 63,117, 61, 88, 23,128, 43,246,233,214,111, 12, 47,161,231,204, 14,243, 38,
-207,107,168,174, 18, 36, 39, 30,249, 0,204, 78, 88,254,126, 99,239, 11, 46,114,153,129, 34, 61,231, 84, 54, 85,152,122,139,151,
-180,130,151,128, 41, 54,108,124,206, 51,173,163,100, 73, 59, 72,144,241,178,228,116, 3,174,223, 20, 30,188,129,166,104,255,123,
- 87, 45,108,244,163, 67,135,122, 80,197,195,252,195,235,199,110, 28, 14,105,138,253,228, 39, 84,135,172, 71, 87,106,159, 29,105,
- 33,118,190,112,245,134,154,123, 43,245,179, 15, 14,221, 37,156, 31,215, 15, 39, 32,165,194, 47, 72, 2,244,219,226,248, 33,200,
- 77,160, 54,158, 94,196,222,188, 92,168, 49, 79, 65, 15,244,154,180,178, 93,189,120,113,254,117, 56,158,191, 50,207, 62,215,247,
- 21,109,140,116,162,214,118, 20, 21, 27,138,146, 79,165,116,200,108,201,176, 65, 28, 5, 45,175, 14, 55, 38,116,168,210,225, 33,
-210,133,100, 12,110, 26,231, 4,164,186, 0, 36, 38,153,108,213,106, 99,154, 99,246, 32, 90,114,165,196, 56, 11,247, 35,190, 1,
-132, 25, 40,220, 45,178, 46,186,227,173, 59,187,167,111,223,164,191,127, 63,255,241, 8,174,139, 10, 94,137,192, 7,145, 20,205,
-225,112,213,198,124,149,253,216,127, 44, 94,189,124,254,222, 47, 63,118,111,207,211,214, 6, 87,168, 1, 97,254,164, 80,221,184,
-197,125,194,212,111,243,200,221, 78,103, 21,195,163, 50,148,101,203,145, 51,100, 2,179, 25, 95,131,218,103,117, 37, 7,136,166,
- 68, 33, 82,142,194,201,163,164, 39,157, 93, 27,117,116,173, 42,181, 11,129,126,194,173,173,121,106, 97,151, 2,128,119,219, 13,
- 49,240,149, 17,217,235,168,214,123,160, 59,196,158,145,189,247,212,179,166,105, 39, 54, 24,138,110,114,135, 91,149,104,170, 44,
-105, 41,137,139,108,242, 77, 31, 27, 97, 93, 45,125, 24, 19,202,101, 42,154, 1,245,109,141,174,228, 84, 98,136,193, 46,244, 11,
-213,217, 89, 31,231, 93,154, 21,247, 66,233,147, 59, 19,230,169,188, 46, 45,123, 13,215, 84,138,114,150,203,113, 65,173,138,168,
-234, 64, 34,226,166, 37,148, 64,176,219,229,210,182,247, 29, 62,199, 14, 63,136, 24, 65,148,244, 52, 7, 83, 3,126,148,165,252,
- 79, 0,146,206,101,213,142, 34, 10,195,117,235,234,234,203,190, 28, 56, 39, 42,209, 16, 81,113,172,224,204,144,129,224, 68,112,
-232, 92,240, 45,124, 29, 95, 64,167,190, 65, 32, 19, 17,145,204,162, 30,200,201,185,236, 75,223,171,187,170,252,255,206,100,179,
-103,187,119,119,245, 90,255, 87,181,214,250,217, 21,144, 82, 25,148, 7,240,134, 76, 65, 75, 64,251,183,205, 60, 91,168,233, 81,
-172, 30,113, 71,200, 48, 87,154,216, 29, 58, 80, 83, 15, 18,232,101,174, 79,190, 29,109,143,215, 26, 87, 51,198, 46, 28, 52,123,
-127,151,229, 52,142,167, 67, 7,185, 89,166,121,114,147,155,161, 91,144, 20, 32, 51, 11,224, 4, 66, 82, 49, 67,235,203, 76,109,
- 83, 85, 37,122,143, 24, 45,171,189, 7,121,187, 26,249,161, 42,113,199, 69,218,217,165,129,106, 78, 5,148,154, 56,231, 57,200,
-159,165,151, 80, 70,187,196,160,221,179,143,105,129,138, 58,199,172,202, 0,199,145,231,196, 66,237, 22,129, 71,236,161, 87, 85,
-178, 70, 22,239, 54, 39,147, 56, 40, 86,237,217,249, 16, 89, 91, 25,133,159,122,136, 89,240,134,222,220, 14,227, 17, 18,127, 29,
- 61, 46, 29,112,148,245, 98,237, 48, 94,248,185,145,193, 91,118,194,220,139, 97,178,253, 5, 89,192,142, 67, 0, 94,204, 7,224,
- 14,116,236,236,131, 96, 53, 25, 11, 11, 89,237,200, 73,231,205, 18,186,101,122,124,169,126,248,233,219,175,191,250, 78,136, 55,
- 98,105,167,187,191, 99,255, 58,210,237, 9,235, 4,228, 22,204,238,233, 39,207, 62,253,249,217, 55, 63,254,247,217,175,191,252,
-245,219,239,127, 30,110, 30,118, 91,203,157,110,195, 38,100,169, 69,234,184,159, 64,108, 5, 42, 98, 49,112, 16, 71,204,117,218,
- 91,193,227,111,100,229,109,224,152,228,129,219,202,213,224,146,135, 88,136, 29,148, 4, 84, 10, 61, 6, 82, 26,124,226,140, 34,
- 81, 85,108,103,167, 43,139,158,134, 24,204,228, 66, 49,217, 77, 28,134,172,185, 23, 85, 24, 89, 45, 35, 83, 55,120, 21,192,118,
-118, 26, 56,140,191,152,146,163,175, 23, 34, 22,251,139, 9,242,139, 44, 11, 62,182, 65,110,135,161, 87,133,246,140, 60, 96, 38,
-103,234, 49,244,248, 84, 16,216,119, 13,212,241,133,123,239,201,199,159,235,247, 63,120,244,248, 98,112,117, 45,168,214,142,171,
- 37,106,192, 61, 89, 34,176,214,225, 57,114,198, 29, 61,135,254, 69, 12,148,102,171, 84, 87,234,170,218, 21, 87,187,125,136,197,
-177,171,250,238,195, 99,115, 51, 55, 71,135,236,143,212,146,230,128,108,101,146,169,226,212,174, 19,192, 28,119, 99,228, 27, 30,
-171,154, 85,188,227,230,128,132,188,161, 60, 88, 39, 81,175, 3, 90, 56, 74,153,191,207, 66, 64, 37,206, 28, 81, 32, 84, 59,109,
- 14,255,120, 91,219,165, 85,220, 39,211,156, 54,156,209,115, 38, 51,189,202, 0, 60, 59,201, 41, 68, 49,103,229, 75,146,153,175,
- 69,153,112, 19, 89,174,144,188, 31,241,126,114, 79,145, 19, 1, 54,198,181,156, 89,128,124,143,200,176, 26, 60, 2, 58, 87,171,
- 10,223,211, 31,166,112,113, 94,197,153, 95,219,213,202, 76,179,136, 25, 65,121,188,123,117,188,158,186,209, 79, 71,201,109,113,
- 58,179,207,208,104, 75,147, 26, 96, 89,167, 12, 91,122,248, 55, 31,160, 59, 31,201, 47,158,239,175,100,220,149,233, 6,171, 45,
-163,155,206,216,211, 43, 18,228,148, 73,214, 28,133, 75,109, 16,227,230, 24,107, 37,161,187,206,190, 70, 74, 65,198, 40,150,225,
-234, 69, 60, 94,187,151, 47,237,254,123,121,245,212, 84, 84,170, 94,116, 6, 16,204, 98,125, 3, 5,175,217,221,230,104, 13,136,
-165,228, 38, 19,114,215,171, 33,207,187,211, 57,208,220, 44, 3,114, 47,177,111,233,209,114,185,173,216, 46,128, 68, 61,135, 26,
- 36, 43,114,133,117,228,188,182,109,187,128, 63,171, 98, 10, 89,115,242,238,230,248,164,125,107,253,235,219,107,209, 53, 28, 41,
-138, 52,164, 34, 51,124,135, 80, 63,175, 79, 7,175, 61,244,200,125,154, 94,253,241,229,243,143, 94, 20, 69,144,103, 17,205,112,
- 56,155,198, 38,155,173, 17,125,234, 86, 59, 6, 29,103,229,170, 48, 4,167, 7,213,144, 52, 56,244,128, 34,168,136, 27, 27, 88,
- 23, 68,151, 42,188, 10, 11,168,220,210,104,197, 56,165, 13, 36,185,172, 32,190,125,124, 64, 8, 71,180,102, 99, 73,230, 54, 2,
-144, 49,114, 11,179, 68, 48,115, 91, 44, 2,228,130,102,242, 60,134,130, 44,157,192, 17, 90,235,204,156, 16,254,162,205, 55,239,
- 26,206,163,173,242, 76, 22, 60, 69,212,195,152,201, 26, 57, 28, 8, 54,118,222, 64,132, 65, 65,208, 98, 56, 0, 40, 64,146,114,
-223, 99,101, 20, 69, 18,243, 62,225, 91, 58,229,129,120, 25,217,185, 7,156,104, 39, 78,105,204,205,185,215, 69,193, 17, 91,184,
-126,113,155, 92, 91, 46,245,130,160,102, 19,144,222,203, 92,212, 66,234,253, 91,145,155,242,184,231,105,184,245, 64, 41, 90, 30,
-108,163,239, 77,214,143,226,127, 1, 72, 58,151,222, 56,170, 32, 10,247,125,118,207,195, 99,123,156, 68,114, 44, 34, 36, 96,195,
- 35, 44, 34,111,144,216,177,205, 79, 96,201, 54,252, 39,126, 18, 18, 82, 8, 16,136,229,196,198,142,221,238,153,126,220,190,175,
-230,156,102,227,101,123,124, 93,115,234,171,190, 85,117,212,143,175,126,226,187,152,200,198,205,121, 59,102, 90,130, 82, 50,141,
-234, 1,185,126, 2,173,231,128, 96,106, 38,213,239, 80, 63, 87,114,116, 41,119,185, 11, 69,157,156,195,239,225,120, 22, 34, 50,
- 58, 25, 92,168, 22,174, 46,215,186, 43,217,154,109, 23,134, 98, 54, 33,109,163, 90,197,193, 33, 72,104, 4, 90,109,139,147,117,
-206,160, 10, 40,146, 60,128,226,173,183,102,131,186,183,223, 44,149, 93,226, 48,196,129,226, 77,156,121,196, 97,191, 92,126,190,
- 29,170,147,119,190,223,240, 41,211, 60,108,150,145,162,227,196, 61,186, 86,211,131, 14,228, 61,137,217,224,146,221,178, 92,160,
- 96,216,254,225, 0,169,144, 96, 7,156, 55,213, 42,198,155,156,118, 10, 96, 42, 70, 91,110,213,234,197,235,183,111, 43,231,166,
-241,128, 77, 40,136,238,166,245,197,190,237, 35, 23,207, 58, 63,148,141,190,143,163,208, 36,245, 74, 57, 49,221, 41,239,111, 11,
-203,117,147,177,235, 19, 49,173,147, 67, 59,172,130,220, 59, 94,202,134,113,106,189,191,111,174,190, 62, 59,125,245,243, 15, 95,
-125,249, 89,106, 94, 55,183,191, 13,205, 85, 24, 92,138, 28,103, 28, 60, 59, 47,123, 31,218,186, 27,154, 27,189,187, 56,254, 68,
-157,127,255,237,249, 55, 95, 92,252, 83,255,113,117, 13, 46, 94,150,128,229, 48,183,104,112,170,130, 89, 23,233, 4,176, 56,139,
-212,144, 41, 50,146,205,157, 28, 79,101,227,222,146,151, 13,210, 67, 38,216, 39, 59, 32,158,193, 35, 3, 7,197,166, 74,145,139,
-240, 40, 14,241, 91, 54, 98,162,226, 20, 69,195,122, 75,164,158,235, 79,228, 19,122,205, 2,227, 34,223, 94,242,218,215,144, 36,
- 18,178,127,203,170,129,174, 93,116, 32,204, 44,163,229,188, 31, 8, 73,173, 20,162,231,253,118, 40, 43, 72,138,146,248,172, 54,
- 15,174,235, 82,214,246,244,236,236,217,249,243,163,151, 47, 15,158,157,169,237, 97,171,205,135, 52,254,155,246, 55, 49,214,201,
-215, 57, 54, 25,129, 7, 17,229,125,120,131,146,144,109, 55, 9,210,143, 60, 93,103,215, 38,212, 80,253, 71,145,111,100,186, 91,
- 86,151,135,155,253,122, 3,109, 94,238, 30,154,201,177, 77,222,143,203,181,250,171,248,251,119, 95,243,194,160,223,103,144,210,
-130,203, 93,121, 68,105, 30,182,135,240, 3, 60,217, 5,111,230,213,183,115, 59,141,164,135, 36,151, 21,160,190, 81, 92, 54,134,
- 48,220,108,158,127,218,168,199,161,175, 57, 28,199,165, 5,168,253,166,249,207, 54,243,180,153,155,232, 41, 12,230,167, 45, 60,
-206,170, 74, 75, 80,141,204,150,251, 69, 65, 66, 69, 69,128,212, 3,141, 28,167,143, 73, 65,103, 34,157, 85,144,253,144, 47, 82,
-164,207, 89, 65, 10, 86,137,134,171,163,174,102,215,157, 50, 77, 40,146,239,156,124,178,177,195,248,235, 47,205, 59, 1, 73,119,
-119,163,107, 93,255, 48, 34,170,231,237,244,133,239, 11,182,206,240,189,106,154, 55,216,139, 33,115,141, 43,157, 16,232,222, 65,
- 0, 78,128,149, 82,226, 31,174, 53,163, 62,245, 96, 87,128,130,144,188,133, 67,241, 44, 93,226,155, 51,181,210, 90,208,255,214,
-217, 78,174,255,140,183,111,228,245,101, 81,183,105,216,170,124, 10, 2,181, 69,180, 75,232, 11, 0,124, 93,130, 2, 70,183,194,
- 7,143,244,210,234,162, 31,198, 93,116, 1, 82,117,213,137,251, 93,200,229,195, 38, 75,245,224, 18,187,208,237,132, 26, 81,181,
- 40,143,244,118, 88,159, 24, 41, 77,199,246,219,195,230,125,187,184,172,159,214,151,103,205, 69, 83,223,238,155,130,222,139,101,
-249,255, 16,130,159,242,113, 1, 70,100, 86,235, 10, 6,191,212, 21,168, 77,173,194,119, 47,158,126, 80,199,215,111, 46,109, 66,
- 65,194, 43, 81,176, 25,191,102,248, 49, 64, 45, 33,199, 85, 4,168,103, 36,253, 20,233,175, 77,219,228,176,209, 40,200,133,242,
-198, 20, 20,242,138, 60,101, 22, 26,130,239, 55,168,240,160,208, 58,175, 13,242, 32,200,208,136,229,241, 97,128,166,136,199,130,
-102, 81,118, 37,202,213, 35,156,224, 98,144, 7, 38,143, 0,110,161,215,171, 60, 65,234, 38,109,142, 22,126, 52,194, 23,214,139,
-112, 66, 52, 7,113,133,172,253, 65,228,238, 14,110,155,201,220,145, 59, 9,123,100, 74, 61,111, 5, 98,155,155,178,164, 11, 94,
-117, 20,196, 54, 68,137, 78,170,230,110, 8,132,207,130,201, 63,132,108,172,158, 70, 60, 2,161, 20,189, 41, 83,216, 10,187,167,
-225,145,171, 34,136, 79, 2,140, 1,109,121, 63,114, 98,100,237,233,230,139,128,119, 82, 4, 99, 1,234,220,192,142,100, 94, 6,
-104,154,229, 30,205,255, 4, 32,233,218,117, 35, 41,162,104, 87,117, 61,186,231, 97,108,150, 53,216,160,101, 3,200, 86, 4, 4,
- 43, 36, 18, 66,126,128, 4, 66, 68,136, 68,196,231, 17,146, 33, 17,172,240,106,133, 0,239, 2,246, 24,108,207, 78,119, 77, 87,
-215,147,115,134,112, 94, 82, 79, 87,213,185,231,220,190,247,220,246,155,111,191, 86, 57,227, 2, 1,231,224,159,244,111,104, 19,
- 0, 14,251,122,127,112, 60,215, 80,169, 49,142,144,119, 64,245,148,162,195, 9, 0,192,203,153,134,213,114, 0,235, 15, 9,210,
-118,104, 87, 59,136, 23,191,101,154,166,199, 55, 84, 11,178, 49, 1,194,103,198, 36,157,186,169,118,253, 82, 91,171, 1, 55, 61,
-111,235,178, 91,165, 28, 31,234,220,117,253,194, 86, 41, 27,162,187,210, 93, 55,151,149,137, 70, 31,201,218,119,158,179, 39,155,
- 15,207, 79,254, 77,229,134,105, 13, 49,183,180, 39, 97,113, 32, 15,110,249,223,255,249, 80,135,223,198,228,129,138,108,114, 97,
- 41, 36,203,105,150,135,134,171,189,238,233, 52, 95,238,183, 34,208,197,165,146, 89,158, 74,251,241,197,139, 11,177, 76, 14,114,
- 59,108,163,223,197,102,168,102, 7,182, 54, 65,116, 14,128,159, 60,186,125, 52,233,170,193, 7, 37,236, 92,145,206,203,192,126,
-213,185,161,229, 20,153, 78,200,182,138, 10, 46, 90, 23, 9,122,102,127, 55,140,231,239,157,125,255,221,151, 15,206,132,251,235,
-143,241,126,219, 36, 39,133, 5,164, 75,185,197,249, 1,235,145,197, 55,244,244,221, 85, 63, 78,187, 27,183,217, 88,247,251,233,
-147,245,231,159,125,180, 27,142,126,121,118, 73,158,204,113,217, 26, 82, 2, 60,126, 46,208,139,124, 16, 42,176,250,212,245,216,
- 35, 42, 97, 79,247,122,137,123, 0, 82,103,170,206,116,159, 82, 56, 21, 29,199, 20,172,101, 0,139,145, 10,171,130, 93, 81,140,
-225,115, 60,224, 2,200, 73,154,163,181, 21,210, 13,188, 6,242,178, 69, 44,129, 2,185,231,163,107,129,159, 4,206, 96, 71, 8,
- 10, 51,211,176,108,132, 3, 9,162,243,173, 70,104,231,140, 10,197,196, 23,174, 37,245,193,180,250,208,222, 89, 52,203, 96,167,
-228, 58,211,189,253,244,211, 39, 95,125,241,232,233, 39,171,119,223,191, 6, 97, 47,251,235,121,250, 51,115, 38, 31, 51,227, 2,
-234,189, 66,248,120,102, 98,216,136, 57,240,140, 51, 73,126, 48, 44,228,119, 2,179,214, 80, 5, 16, 69, 45, 68,131,203, 17, 49,
-120,211,201,235,227, 19, 27,203,177,219, 66,255,184,217,168, 7,233, 74, 60,127, 14,196,117, 74,184, 77, 22,219,178,104,185,248,
-180, 62,103, 90,129,174, 42, 80, 22,138,198,241,108, 20, 64, 8,239, 88, 96,197,164, 61,199,214, 42,126, 42,120, 88,194,241,227,
- 55,239, 78,207,117,252,135,111, 5, 14,231,102,125,150,132, 70,192, 13,129,200,192, 49, 92,149, 22,196, 10,103, 27, 11, 7,156,
-102,197,100,150, 44, 27,164, 72, 32,202, 67, 79, 81,139,179,227,169,118, 2,122,168, 38, 9, 20,198,249,225,172, 88, 90,192,200,
- 4,216, 81, 89,105,240, 79,203,230, 44,214, 80, 85,191, 16,234,244, 52, 94,164,159,126,184,187, 45,123,214, 11, 36, 78,123, 76,
- 96, 92,101,239,105, 51,222,206,136,167, 12, 35,144,148,180,107, 27, 56, 81,182,208, 91, 68,204,145,205,134,146, 30,221,197,234,
-130, 80, 23, 3, 51,208,100, 70,224, 74, 80,199,224,104, 22, 47,164,181, 38,132, 24,118,121, 49, 2, 62,234,125,144, 96,116,173,
-218,136,179, 95,227,250, 89,251,242,231,242,250, 50, 93,223,136,171, 44,124, 87,253, 10,108, 84, 56,219,140,208, 74, 18, 88,234,
-189,171, 97,114, 65,142,160,168,105, 78,187,223, 58,113, 43,110,249,232, 35, 45,109,219,211,170,252, 92,245,118,217,155,229,156,
-215, 43,209,159,236,119,177,190,184, 61,121,185, 89,255,253,234,145,190,220,206,183,119, 67, 30,217, 54,204,217,107, 51,254,168,
-140, 11, 41, 33,102,200, 68, 14, 51,103, 16,156,223, 50,216,181, 8,191,201,173,211, 7, 15,251,245,227,119,126,124, 21, 92, 51,
- 73, 64,208, 80,233,247, 66, 3,237, 12, 29,175, 59,200, 56,223,184, 73, 1, 97,173, 42,138, 30, 14, 88, 27,213,183,156,190,162,
-109,171,251, 16,203, 27,107, 86,173, 2, 61,177, 86,253,186,231, 84, 21,220,139,195, 48,115, 68,128,110, 37,187, 85, 38,197, 21,
-203, 21,159, 48,202, 30,193, 24, 8,104,193, 80,141,102, 61,148,112, 71,133,163,215,253, 94,129, 99, 65,209, 47, 16,108, 68, 56,
- 56, 89, 73, 26, 11,134,156,122, 14,233, 13, 80, 78,224, 24, 59, 85,141, 7,171,141, 91, 67,101, 34,177,192, 44, 49,171,208, 30,
- 29,235, 94,129, 5,211,136,191,168,219, 9, 26, 58,122,165, 16,192,171, 89,146,221, 43,173,141,241,121,108, 23,205, 17,139,209,
- 83, 64, 88,135,132,199,134,245,179, 53,109,201, 33,100, 92,217,248,122,223,122, 48,230, 69,200, 67, 57, 50,243, 34,168,145,186,
-180, 52,128, 84,132,124, 51, 37,255,159, 0, 28, 93,201,142, 36, 53, 20, 76,111,105,231, 82,213,221,211, 52,219,104, 70, 8, 14,
-112, 1, 33, 46,220,224,134,184, 32,110,124, 10,226,135, 16,255,192,157, 19, 18,220,184, 32, 4,195, 52, 67,111, 84, 85, 87,110,
-118,218,153, 38,162,164, 58,165, 84,155,159, 29, 47,194,126, 47,172,227, 50,225,145, 15, 9,164,223, 67,160, 68,164,224,128,113,
-198,218,200,200,146,138,142, 62,179, 62,206,108,189, 18,144, 45,143,221,146,106,144, 0,147,124,182,211, 36,204,200, 51,171, 48,
- 47,125,215,184,176, 64, 14, 97, 90,238, 26,169,150,163,149,219,106, 83,170, 48, 5,179, 90, 5,130, 56, 89,137,180, 80, 42,235,
-195, 33,173,162, 51,221,186,230,174,124, 77,108, 32,192, 0, 76,213, 70,173, 96, 52, 72,181,103,190,209, 53,195, 81,216,237,166,
- 44, 94,197,249,253,221,243,118,123,215,205, 93, 81,108, 23, 5,121,142, 87, 77, 33,158, 71,188, 85,178,143, 48,230,145, 53, 3,
- 4, 11, 90,218, 27, 21,183, 5, 11,213,143, 90, 47, 72, 6,243,116,175,128,170,153,189, 70,146, 61,147, 14,127, 47, 44, 15,234,
-209,121, 58,167, 33,247,173, 1, 92,237, 31,228, 30, 17, 91, 68, 50,148,126, 26,114,163, 31, 2, 52,224,133,193, 58,140,121,199,
- 59, 10, 45,190, 87, 97,101, 79, 75, 80, 32, 57, 16, 67,251,191, 33, 21,206,120, 16,223,170,226,152,190,249,234,211,246,242,250,
-240,199,203,121,166, 79,173, 92, 39,161, 1,100, 71,238,232,209,129,222, 33,249,112, 51, 36,159,210, 53,184,176, 81, 93,223,187,
-223,127,169,223,251,232,219,239, 62, 7, 84,124,255,195,143,117,179, 56, 64, 52,203,145,148,211,134,190, 88,192,212, 86,176,233,
- 64, 72, 16, 53, 60, 31,199, 16,218, 44,181,168, 39,195,122,151,198, 97,169,148,126,158, 93,205,126, 14,176, 86,139,233,144, 86,
-222, 50,165, 33,239, 7,182, 59,217,197, 33, 96,188, 28, 24,242, 3, 90, 96,158,145, 33, 87, 44, 82,103, 79, 13,172,224,166,160,
- 98, 60, 54, 90,199,132,201, 6,126, 14, 56, 60,213, 35, 77,192,122,214,141,226, 87,159,105,177,178,191, 20,160, 51, 1, 90,110,
-124,213,234,119,190,254,236,221, 47,190, 92,171, 43,128,245,159,224,187,179,191,205,116,105,247,220,106,207, 45,242, 28, 75,158,
- 22, 87,240,157, 61, 97,184, 56,221, 68,154,154,147,125, 33, 45,184,132, 64,140,232,248,150,105,210,152,217, 99,195, 94, 63,132,
-213, 71,105, 76, 28,159, 63,125, 22,211, 7,251,155, 42, 97,198,130,131, 53, 54,221, 38,189, 43, 26, 93,120, 83, 12,129, 26,159,
-255,157,214, 73, 60, 86, 5,133, 87, 19, 49,157, 71,251,150, 91,240, 52, 75, 4, 51,167, 57, 75, 81, 74,145,207,242, 88,231,241,
- 56,171, 1,138,167,147,220,246,131, 10,180,139,105, 38, 3,132,136, 82, 91,122,155,200,131,197,248,137,149,215,135,173,169, 84,
-183, 82,150, 52,229, 43, 28,233,214, 2,218, 43,161,177,140,230, 21,143,188,134, 55, 66,153, 15, 57,103, 23,109, 46, 49,245, 87,
-222, 37, 2, 81, 12, 58,143,197,164,217, 74, 23,185,141,218,103,150,172,102,113,184,129, 30,246, 94,113,127,145,183,240, 20, 97,
- 15,142,170,232,237,110,242, 36,243, 52,233,102, 98, 95, 33,210,193,144,101, 57,167, 26, 26,150,242,248, 84, 38, 35, 32,174,139,
-110, 22,109, 8,169, 81, 13,123, 53, 12, 79, 79, 64, 39,226,201,165, 1,124,214, 45,238, 74,239, 94,196, 27,191, 88, 58,162,231,
-235, 59,100,138,178,218, 45,246,237,251,237,246,174,126,242, 91, 28, 46, 98,168,203,125,171,210,235,126,189, 28,194,211,168,240,
-145, 27,175,139,209,111,150,148, 38, 33,250,112,113, 24,236,190,127,235, 28,129, 86, 87,236,234, 31,166,121, 62, 31, 65, 30,221,
-120,184,135,244, 82, 98, 0, 7,188,126,115,254,119,189,187,235,237,225, 62, 47,175,246, 43, 45,108,131,180, 9, 19, 57,181, 88,
- 43,208, 36,116,129,194,184,216, 81, 71,250, 96,178,200,179,248,207, 84, 78,206,243,163,212,127,165, 23, 63, 93,127,252,225,179,
- 79,158, 61,249,249, 87, 47, 43,150, 31, 0, 18,145,237, 7,214,173,104, 12, 50, 35, 83,210,157, 60,170, 76, 71,218, 84, 67,226,
-152, 30, 51,223, 74,231, 75,160, 66, 37,163,171, 20,168,183, 98, 33,157, 11,114,216, 0, 32, 17, 93, 37,149,101,255,221, 26,211,
-114, 89, 66,134,212, 69, 57,130, 86,138,237, 70, 61, 32,196,189, 46, 54, 86,176, 79, 73, 48, 21,212, 38,215,111, 96, 4,250, 46,
-150, 12,247,250,104,212, 89,157,163, 23,157, 84, 85,227,153,114, 11,200, 94, 64, 60,171,185,242,140, 76,157,233, 28, 23, 65,119,
- 69,199, 93, 65,163,124,194,108,146,210,110,244, 57,126, 38,150,162,151,123,103,202,214, 86, 29,248, 23, 84,223, 73,142, 95, 4,
-127, 89,186,225, 65, 15, 13,100, 9, 4,164, 48,107, 60,117,233,108,163,137, 13,141,232, 16, 80,172,190,232,202,149,213,175, 62,
-173,147, 70, 38,209, 14, 60,198,120,233,138,195, 40,106,251,191, 0, 28, 93,201,110,229, 68, 20,173,201,179,223,144,134, 4,130,
-154, 64,139, 5, 2, 53, 18,136, 47, 64, 98,199,143,176,227, 35,179, 67, 98,193,176, 1,169, 37,212, 10, 77,120,157,126,163, 93,
-101,215, 96,115,142,179,203, 32,231,185,124,235,220,115,174,235,158,107,132,139, 29,216, 20, 2, 42,140,158,149,117,118,233,123,
-217,135, 0,124,159,113, 93,228,107, 72,130,112, 22, 86, 92, 74, 54,233, 35, 11, 69,113,216, 7,168,158,208, 99,211,197, 60, 7,
-139,243, 32,138, 32, 75, 78,180,194, 28,217,123,233, 54, 66,174,154,232, 99,206,169,230, 90,157,114,133, 11, 5, 89, 95, 55, 53,
-242,201,203, 15,159,111,174,205,233, 12,160, 40,206, 49,238,221,219,106, 21,166,182,169, 57, 49,174, 98, 37, 83, 68,201,190, 79,
-164, 87, 97, 83,248,251,244,241,203,226, 47, 99, 78,193,205,204,146, 90, 47, 38,189, 3, 11,249, 26,248, 85,205, 68, 8,167, 77,
-193,179,157,130,227, 15,133,177, 52, 95,132,214, 67,190,188,188, 83,151, 97,134, 36,204, 57, 79, 30, 57, 40, 43,111,254,221,157,
-196,249,105,148,107, 48, 54, 64,130, 67,108,100,200,165,150,138, 96,144, 26, 34,200,247,200,100, 3, 13, 11,167, 71,144, 12,108,
-122,163,186,114, 94,143,110, 62,121, 5,238,128,125,239,139, 43, 21,159,158,169,173, 60,131,191, 62, 60,216,103,237,245,183, 95,
-223,134, 55,247, 41,112, 72, 40,105,202,164,192, 3,104,218, 31,122,128, 38,189,159,130,199, 13, 78,122,169, 20, 20,144,249,244,
- 35,183,151, 60,253,254,199,234, 75,247,211,143, 95, 60,188,250,239,254,231, 95,161, 46, 83, 93, 19,167, 34, 30, 27,100, 30,243,
- 67,160,227,194, 8, 32, 0,113, 6, 47,161, 83,181, 38,201, 71,128,219, 12,219, 99,170, 50, 93, 52, 0,185,185,164,147,162, 84,
- 45,187, 97, 64,119,124, 16, 69,114,245,202,211, 79, 26, 64, 7, 77, 85,128, 89,226, 86,217,113,170, 38,245,120, 82, 88,255, 70,
-177, 3, 35, 2,124,248,182, 35,112, 58, 60,109,122, 35, 64,250,170,138,138,141,165,120, 4,236, 10, 0,206, 7,215, 31,157,186,
-253,232,243,239,190,186,251,254,135,242,230, 14, 32,246, 52, 15, 7,111, 89,155,150, 28,105,169, 23, 61, 5, 0,179,132, 24, 3,
-229, 25, 17,154, 75,201, 8,183,179,184, 71,168, 78,152,101,236, 4,128, 25, 11,211, 69,190, 81, 6, 27,118, 41,117,244,247, 84,
- 23,195,227, 80, 55,117,106, 95,235, 23,187, 23,119,101,247,207, 29, 46,147,175, 75,154,114,148,135,180,166, 18,200, 21,201,210,
- 25, 32, 80,177,240, 98,217,248,203,142, 81,186,203, 7,129, 76, 27, 37, 29,105,202,121,177,147,147,203, 36,139,192, 51, 54,117,
- 79, 97,132,187,218,251,172,194, 94, 5,212,132, 49,141,174, 24, 42, 72, 28, 91,204,224, 89,114,214,163, 98,181, 88,120,154,239,
- 21,147,199, 99, 19,156, 55, 77,203, 65,203, 14, 59,205,195,238,115,206,178,218,184, 83,154,181,104, 34, 52, 39, 42,177,111,138,
- 39,213, 69, 70,219,168, 52,241, 43, 94, 2,143,228,209,143,151, 71,232,179, 45, 66,202,100,200,150,128, 75,132,142,222,220,136,
-139, 53, 30,210,242, 24,187, 12,105,155,246,221,166, 86,197,176, 12,156, 2, 83,135,192,206,216,224, 55,141,210,142,198, 64,237,
-148,148,253, 62,105, 48, 3, 64,197,212,209, 17,194, 23,162,230,156, 98,227,114,179,205, 82,124,223, 68, 7, 2,137,128,146,243,
-216,237,210,122, 13,204, 9,250,152,241,136,146, 8, 59,197,147, 61,136,173,223,212,140, 45,196,195,124, 69,182, 89,198, 9,222,
-206,102,200,223,181,235,195,246, 19,125,126,194,223, 62,226,225,110,192,168, 50,177, 63,122, 53,218, 57,151,111, 65,237,134,139,
- 7,167,182, 7,247, 70, 77,172, 2,247, 88,181,106,113,107, 23,101,169,241, 89,102,153, 14,216,200,146,212, 36,227, 57, 85,142,
-188, 93,198, 39, 74, 44,246, 32, 65,139,161,128,234, 52,216, 87, 15,251,207,254,124,253,233,243,111,238,127, 1,193,228,177, 45,
-132, 5, 57, 53,254, 51,196, 47,242,156, 97,191, 14,178, 4,126,216,140, 68,212,177, 81,149,176,114, 27,251,139, 73, 53,136, 34,
- 93, 91, 40,247,171, 78,235,102, 66,130, 73,141, 76,178, 41, 60,126, 71, 35, 14,144,148,153, 77,100,208,170,231,171, 82,246, 16,
- 75, 88,110,168, 53,250,135, 8,107, 43,160,171, 94,101,209,169, 26,220, 25, 97,154,185,182,221,248,211, 74,100, 77, 24, 60,240,
-191,140,200, 85,189, 2,241,210, 61, 2, 65, 34, 19, 37,250, 52,169, 50, 49, 14,124, 94,138,118, 94,222, 1, 73, 14, 95, 73,197,
-180,136, 73,214, 69, 20,205,224,161,169, 13,187, 54, 39,214,250, 90,208, 17, 9, 86, 0, 24, 61, 25,201, 23, 32, 88, 51, 8,181,
-144, 23,149,178,248,222,225,137, 14,231,106,197, 17,193, 86, 0,188, 63, 40, 16, 98, 49, 28, 75,100,168, 36, 93,124, 47,167, 3,
-118, 55,164,255, 5,224,232, 90,118,221,182,161, 32, 69,138, 18,101, 73,118,156, 71,131,220, 32,187, 0,217,220, 2, 45,208, 7,
-208, 69,247,237, 31,116,217, 85, 63,160, 64, 87,253,193,126, 65,209,162, 64, 17,220, 38, 23,185, 47,251, 90, 15,138,226,171, 51,
-222, 25, 94,216,146, 72,157, 51, 67, 14,103, 24, 85,233,241,133, 46, 30,103,209,136,120,222, 43,149, 77, 41,193,134,130,141, 97,
- 94,175,198,216,200,206,131, 18, 75, 0,131, 97, 18,209, 77,138, 39,217,208,106,134, 85,117,197,116, 59, 21, 26,104,238,144,226,
-110, 54, 92, 36,110,184, 87, 68, 73,145,166, 26, 89,197,125,155,230, 81,120,251,178,238,190,249,226,242,219, 47, 47,182,207,140,
- 16,237, 89, 53, 49,158,195, 98,138,235,235,227,251,219,229,207,143,135,213, 58, 32, 84,219,182, 59,134, 72,111, 86,198, 24,216,
-207, 84,186, 87,251,171,195, 87,111, 94, 29, 99, 30, 75,187,160, 79,113,135,156,222,201, 26,240, 70, 49,122,181, 90, 13, 21,192,
- 92, 60,117, 84,224,227, 31,153,132, 12,146, 59, 62,210,125,170,208, 21, 13, 19, 83,161,193,227,246,162,189,248,231,239,255,150,
-136,203, 12,190,153,152,217,128,145, 31,238,178,209, 15,105,213, 0, 32,131,156,113,133,213,236, 65, 37,215,130,238,179, 7, 85,
-212,139,158, 64,215,132, 51, 57, 0, 56, 88,208,123,180, 31, 93,182, 9,236, 97, 9,202, 47,242,187,239, 47, 69, 61,141,247, 87,
- 50,188,200,210,170, 30,252, 14,124,121,140, 74, 19,184, 85, 35,240, 79, 84, 67,230,169,143,174,164,179,126, 77, 69, 93, 49,209,
-118, 19,244,255,253,149,121,251,252,247,223,126,252,233,231,143, 1,156,131,197, 16,119,187, 40, 38, 4,102,176,175,202,165,166,
-207,161, 1, 51,165,215,247,217, 54, 4, 60,140,226, 33, 80,173, 54, 11,186,213,143,140, 60,119, 52,145, 40, 58,220,241,172, 14,
- 91, 70,175,246,161,102,175,103, 54,123,234,211, 98,164, 87,186,116, 39,197, 67, 76,139,216, 74, 58,156, 88,229,125,207,120,139,
- 74,212, 11,192,121,189,172, 81, 60,221,128,136,229, 21,220,213,128,198,134, 14, 23,226,189,171, 49, 75,187,119,111, 63,255,229,
-215,119, 23,175,102, 33,174,132, 69,147, 59, 80,219,132, 57, 73, 91, 58,195,228, 8,148,239, 88, 49, 88, 3, 52, 41, 80, 38, 32,
- 80,117, 24, 37,187,208,177, 88,209, 38,165, 12,228, 14, 0,228,106,194,124,119,121,100,148,149,119, 9,109, 41,160,195, 14,220,
-108,136,115,210, 79,100,109,135,205,215,255,238,222,188,190,249,107, 73,251,125,221, 3, 45,129, 56,243, 87, 45, 26, 33,195,224,
- 8,216,209,141, 76, 66, 63,163,189, 76,212,212,137,154,115,138, 83,125,110,150,204,161, 42,169, 72, 21,142, 22, 52, 92,234,211,
-199, 77,127,115,115,239, 93,112,231,232,168,145,254,111,197,100, 50,181, 41, 30, 32, 15,195,144, 14, 52, 8,108,155,202, 99, 60,
-128,178, 53, 64,180,143,160,236, 69,179,161,109, 9,143,103, 37, 30, 29,165, 88, 20, 20, 30,183, 12, 62,170, 50,133,233, 5,109,
-251,184,194, 89,214,140, 93,198, 7,198, 67,233, 82, 56, 27,146, 41, 70,177,221, 71,112, 60,116,181,192,124,208, 21,244,132,105,
- 30, 85,108,101,175,114,151,130, 43,162, 63, 90,160, 13,123, 86, 50, 97,252,167,129,158,225, 70, 38, 58, 1, 2,185,212,229,170,
-121, 20,140, 58,181, 83, 17,159,199, 39,231,200, 26, 38,116, 7,158,135, 44,241,164, 6, 46, 86, 8, 83, 29, 65,172,116,122,221,
- 84,215,159,194,112, 19,230,105,211,239,154, 71,103,227,138,114,187, 50, 6,238,129,135,204, 64, 24, 76, 28, 44, 48,243,234, 85,
-184,142,193,102,148, 63, 31, 91, 0, 68, 16,184,199, 28, 80, 0,143,116,171,115,152,135, 94, 45,182, 72,186,136, 75, 89,237, 36,
-133, 15,204, 25,170,118,220, 83,137,214,161,184, 71, 63,157,147,102,185,245,129, 55, 31,243, 97,181, 58,110, 75,154,167,112,241,
- 78,119,117, 29, 27,239,178, 64, 81, 76,250, 33,158,238,253,135, 63,238, 46,127,136, 23, 79,219,187,187, 7,197,121,131,159,245,
-229, 9, 36,156,240, 87,219,218, 30, 67,177, 99, 36, 67,105,227,252, 44,147,203, 75, 99,154, 54, 47,204,136,161,214, 5,232,215,
- 55,141,222,131,189,249,186,218, 43,121,144,211, 82,117, 52, 24, 70,241,211, 96, 59,210, 72,101,137,212,233, 73,166,103,225, 27,
-224,164,118,155,231,177,111, 83,104,129, 78,153,248, 38,229, 70,246,155,151,168, 50, 46, 13,147, 54, 47, 30,114,209,152, 83,149,
- 26,167, 10,131,158,179,184,102,206, 77, 89,172,189, 7,100,109,171,122,106, 0,162,234, 91,189,203,226, 67,165,208,236, 81,131,
-130, 25,204,140, 26,222, 13, 38,108,104, 52,204, 8, 69, 58,162,108, 83,255,201,214, 53,158,163,154,171,104,103, 52, 11, 84,207,
-154, 1,102,120,133,208,251,105,243,113,114,162,174, 22, 93, 41,215,100,180, 28, 63, 48,132,144, 2, 43,154, 92,138,174,161, 55,
- 64,144, 12,217,245,167,255, 5, 32,233, 90,118, 36,167,161,168,227,216,142, 19,215,107,170, 97, 52, 5,172,160, 17,210, 72, 32,
- 88, 12,136, 13,136,245, 72,172, 89,177,225,135,248, 1,126,128, 21, 63,192, 31,208, 27, 16, 59,164, 97, 52, 18, 51, 76,215,116,
-119, 85, 37,149, 56,126,113, 78,179,232, 77,171,165,142,147,235,123,207,177,239, 61, 7,121,161, 47, 41, 60,224,129,144,146, 43,
- 31,120,117,165,243,208, 29,226, 64,107,152,132, 69, 49,107, 85,213,221,121,180,131, 36, 76,162,216,117, 1,235, 59,238,115,191,
- 18,109,181,230, 61, 30,160, 72, 29,146,109, 13,157, 10,216, 87,228, 84, 90,205,168,162,141,188,243,242, 34,111,191,249, 98,247,
-228,179,247,183,111,225,155,254,155,250,235,137,178,216,164,222,186, 90, 40,179,218,237, 54,187,221,197, 39, 31,110,255,124,118,
-251,242,239, 51,199,231,151, 10, 92,151,254,109,248,234,216, 74, 74,188, 24, 63, 94,222, 92, 47,220,213,208, 1, 67,177, 42, 35,
- 53, 83,253,151,216, 16,208,198, 87,158,122, 37,153,195, 17,216,241,129,134,180,115,153,167,125, 57,141,153,134, 14, 85,218, 84,
-168,211, 18,207,250, 54,118,200,163,195,171, 43,127, 58,216,169,213, 39, 21, 8,142,198,113,146,117,177, 32, 95,211, 60, 35,141,
- 81, 74, 48,148,118,166, 41,195,132,236,109, 56, 2,118,174,242, 93, 27,212,208,214, 85, 40, 35, 94, 87,190,177, 34,239,117,155,
-146, 6, 80, 92,199,199,159,183, 66,252,142, 56,212, 72,171,156,195, 0, 10, 0,238, 17,165,201,168,164,148,151,150, 38,229,142,
-128, 69,229,128, 28, 48,130,129,117, 84,200,193,146,172, 60,159,222, 84, 47,127,123,248,209,183,223,127,247,245,143, 63,253,108,
-115,108,145,130,231,218,228, 88,107,221,139,188,168,193,127,105,158, 76,137,220,133,232, 50,150,155,238,155,167, 56,173,195, 86,
-121,106,151, 86, 86, 0,164, 83,115, 9,233,130,115,231, 41, 26,144, 67,167,122,228, 35, 45,218,137,118,247, 41,242,150,130,238,
-174,116, 7, 51, 29,144,189,114,116,235, 74, 50,140,116,117,201,182,180,185, 70,110, 5, 22, 6, 38, 65,181, 4,131,201, 58,147,
-237,188, 74, 15, 47, 63,120,250,195,229, 87, 79, 68,109,175,144,166,230,193,211,232, 8,101,145, 46, 43,236, 43,161,172, 23, 85,
-211,217, 85,196, 75, 65, 32,122,150, 92,117,175, 33,100,216,218, 58,123, 37, 57,221,149,135, 1,117, 18,197, 88,220,196, 8,174,
-207,155, 13, 17, 7,154, 22, 82,134,134,208, 45,137,195,113, 28,164, 61, 52,221,123,255,172, 55,215,217,164,107,191,123,199, 3,
-150, 36,236, 17,102,112,201,203, 65, 42,236, 69,158,162, 11,150, 97,113, 47, 69,196, 95, 58,207, 3, 46,142, 7, 6,182,211,180,
-168,125, 70,248,255, 13,139,240,200,195,178,228, 5,138, 4, 13, 38, 53,229, 96, 93, 25, 19,152, 77, 4,135, 7, 97, 4, 58,198,
-218,218,236, 18, 43, 27, 86, 57, 1,190,227,175, 29,160,133,172,206, 28, 66, 10, 36,128,236, 51,165,247,153, 47,236,165, 50,130,
-237,202, 17, 5, 56, 38, 53,226,189, 2, 19, 6,228,238, 41,211,202,105,131,168,224,241,145,160,157,242,201,109,226,131,174, 12,
- 71, 69,189,106,133,148, 60, 3,244,166, 12, 48, 73,241,168,166,241,174,152,186,142,163, 63,207,193,204,188,157,168,182,197,155,
-162,143, 53, 37,161, 17, 31, 99, 89, 78,226, 14, 43, 69,236, 53,165, 12,114,194,171,179,197, 32,160, 27,228,255, 58,147,188, 98,
-103, 36, 74,141,174,117,216,207,211, 90,188,123, 41,230,155,249,143,191,228,235,219,188,186,144,174,169,155,108, 42, 71, 19,168,
-249,156, 60, 50,226,113,123,110, 42,124, 92, 4, 82, 76,155, 48,132, 25, 81, 51, 85,189,198, 67,170,142, 35,107,170, 94,130,111,
-100,144,103,119,160,184, 53,126,202,189,209,163, 5, 43,173, 35,222,161,164,169, 66,110, 85,237,109, 86, 3,235,160, 83,121, 68,
-102, 41,146,125,163,188,122,177, 88, 4, 18, 77, 67,187, 90,122, 79,162,132, 1,254, 13,251,240,236,197,155,167,234,249,151,159,
-174,127,249, 53,106,128, 93,224,164,148, 22, 9,255, 69,205,167,174,169, 43,208,249,133, 14,125, 67,113, 37,158,246,112, 70,102,
- 35,111,138,118,149,193, 54,169,180,117,165, 5,223,108,228,212, 28,214, 98,149,152, 66, 1,201, 86,216, 28,113, 83,115, 4, 38,
-225,221,218, 71,141,161,144,108,227, 98,177, 29,123, 43,145, 53, 22,154, 51,111,217, 90,225,207,218,130,140, 35,196, 14,180,228,
-186, 21,173,229,237,153,214,101, 75,175,123,123,162, 47, 23, 59,100,129, 44,100, 76, 0,117, 46, 45,122, 49, 98, 83, 79,214,246,
- 42,230,216, 35, 25,244,153,167,171, 40,150, 33,208,125,171,112, 10,194, 73,154, 13, 8,198,109,103, 38, 3,192, 35,173, 0,125,
-241, 83,139,192,221, 30,197, 57,182, 17, 79,107,163, 68,173, 13, 0, 3,161,163,118, 25,232,160, 22,203, 70,101, 36,223,218, 53,
-203, 64,141,119,196,211, 9, 28,209,159, 16,245,255, 9,192,209,181,236,202, 81, 67, 65,219,109,247,115,110,195, 37,132, 92, 37,
- 74, 34,193, 6, 69, 32,144, 34,238,130, 13, 18, 44, 97, 31, 33,126,128,111,100,197, 50, 72,217, 32,193,130, 13,130, 16,114, 65,
- 40,119, 30,221,110,183,159, 77,213,108, 71,163,153,110, 63,206,169,178,207,169,170,158,125,255,205,116,192,140,187,201,211,150,
-212,159,108,198,234, 91,188,197,191,219, 76,119, 33,112, 92,240,135, 61, 8,179, 99,129,197,186,108,121,102,237,153,207, 41,128,
- 33, 70,236,117,185,199, 48,118,186,117,107,187, 25,213, 52, 3, 94, 96, 75,109, 93, 53, 83, 22,250,113,255,240,187,175,222,191,
-126,138,140,248,231,233,246,215,249,248,210,187,215,180,141,144, 71, 65,137,139,218,165,255, 82, 58,138,112,232,218,195,131,247,
-234, 59,227,149, 5,121, 72,125,200,174, 3,127, 69,114,146, 29,253,218,218,232,227,227,206, 79, 23,122, 47,140, 77,133, 46, 53,
- 27, 21,241, 49, 61, 6, 24, 8, 89, 78, 10,163,148, 7, 59, 85, 90,165,105, 14,199,169,100, 48,235,134,135,152,137, 7,109, 98,
-112,132,113,151,247,219,221,199, 47,158, 63,199,120, 91,153, 98,216,162, 10, 1,201, 98,138,171,141, 44, 36,198,216, 55,121, 93,
-253, 52, 99,109,102,106, 6, 6,215, 32,240, 88, 0,141,228, 45,160, 37, 40,150,162,197,173,143, 35,213,114, 91, 57,248, 98,195,
-116, 27,191,254,242,211,203,139, 95,150,191,193,204, 2,118, 49, 5, 6, 36,143,189,184,165,169, 19,178,178,147,142,106, 10,137,
- 34,245, 96,201,241,108,249,200, 67, 23, 70, 4,134,237,124,106,238,214, 31,125,248,197,143, 63,252,188,236, 39, 76, 36, 24, 19,
-171, 99, 42, 61, 45,101, 48,216,244,231, 19,120, 89,176,225,103, 4, 4, 19, 90, 83, 70,201,227, 30, 26,191, 32,116, 35, 77,117,
- 32,243,162, 86,224,215,122,217,182,139,254,108, 93,125, 96,229, 12, 85, 53,125, 8,148, 89, 65,230, 64, 80,166, 70, 47,133, 31,
-144, 40,250,205, 31,120,233,130,248,154, 53,143,215,253,200,135,166,166, 28, 64, 46, 98,182,243,206, 3, 80, 92,125,242,249,245,
-179,111,239,126,118,221, 40,125,147, 14,183, 33,120,218,254, 84,120, 71,236,101, 16,135,115, 67, 25, 63, 18,108,246,161,221,125,
- 60, 75,247,158, 13,225,214,152,169,220, 25, 41, 62,157,248, 28,219,190, 84, 72,195, 54,249, 57, 22, 91,194,105,203,248,206,191,
- 5, 28, 37,184, 42, 88,182,122,148,147, 68, 72, 64, 82,234,251,109,248,224,225,155, 87,192, 47,205, 59,246,197,180, 63,170,181,
-158, 67, 89,121, 84, 41, 35,245, 19,197,102,120,211,196,107,207,116,110,105, 21,103,163, 62,106, 13, 51,226, 99, 57,140,130,151,
-184, 82,139, 1, 60,185, 23,227,213, 61,241,228,222,205,235,191,128, 37,120,197,146,149,157,193, 36,204,214, 44, 33,199,214, 35,
-191, 78, 41, 90, 32,101,132, 73,140,116,201,180, 61, 9,221, 76,205,222,116,150, 45, 43,141, 48, 9,104,168, 42,129,103, 36,180,
-108,103,170,100, 61,215,170, 24, 95, 17,245,216,234,175,130, 89, 57,180, 96, 93,180, 4,167,172, 63,126,100,219, 61,232,167, 87,
-225,247,223, 92,164, 59,156,158,241,232,141, 97,110,195, 51, 35,176,226, 1,170,122,192, 14,199,204,107,204,157, 7, 14,100,227,
-245,166, 71,133, 55, 70, 54, 62,139, 45,179,196, 4,128,130,202,217,172,244, 71, 14, 66, 16, 6, 1, 21,213, 76,207,228, 66,253,
-251,178, 38,122, 12,212, 96, 92, 70, 73,167,135, 62, 63,186,100,139,210,205, 27,241,143, 83, 11,200, 83,150, 39, 71,127, 19,103,
- 17, 3,168,188,159, 68, 83,188,105,119,157,161,124,116, 51, 40,181, 27, 85,175,181,111,163,120, 11,204,201, 24,203, 51, 7, 80,
-152, 36, 13, 29,216,138, 88, 11, 11,136,204, 69, 26,216, 38,171,144, 30, 42,222,174,232,218, 43,222, 87, 11,217, 84, 38, 6, 96,
- 78,112, 0,196, 34, 42,227,175, 77,212,172,130, 7, 94, 43,189,174,221,230,219, 9, 32, 49,220,127, 36,212,147,167, 63,253,225,
-177,251,216,110, 43, 10,120,151,239, 75, 87,148,109,157,108,117,197,172,108, 88,252, 74,113,176,186,239,180,121,215,167,183, 29,
- 86, 39, 82,126,224,145,147,236,105, 85,220, 20,172,168, 49, 85, 32, 31, 1, 44,213,230,150, 23,136,148, 9,224, 21, 69,146, 14,
-179,142,209, 90, 8, 59,122,106,174,175,185,168,150, 22,120, 18,251,212,244, 78, 98,171,116,153,240,147,197,132,128, 27,227, 80,
-111,170,190,227, 98,219, 75, 95,151,224,134,208,181, 30, 63, 32,143,106,192,232,247, 5,195,105, 53,192, 65, 6, 94, 26, 91, 18,
-177,205, 32,226, 94, 20, 29, 53, 18,165,212, 43, 18, 38,255,111,246,107, 3,146,207,186, 3,121, 68,104,220, 1,114,119,193, 75,
-103,186,195,224,204,138,215,112, 90,154,220, 83,193, 8,176,165, 98,223,126, 1,164, 94, 22,141, 85, 86,213,129,101,218,128, 80,
-120, 61, 48,102,163,255, 23,128,163,107,217,145,163,134,162,126,148,221,174,170,174,153, 78, 38, 19,134, 32, 36, 64, 40, 74, 36,
-248,134,176,101,135,178,138,216,176,226, 75, 89, 32, 30,155,132, 77,178, 0,196, 34, 17, 35,146,153,233,174,151, 93,182,203,156,
- 83,203,110,117,119,117,185,238,227, 92,251,222,115,244,243,239, 95, 32,106,174,118, 54,147,241,203, 52,121, 78, 5,247,195,201,
-151,211,122, 51,203, 52,247,121,138,126, 48, 19,249, 91,166,187,113,224,248,193, 90, 33, 41,113,167, 35,193, 78,185, 44, 7, 41,
- 47,180, 44, 93,187,183,173, 61,116, 28, 45,175,242,131, 54,247,238, 99,245,248,197, 51,241,249,211,215,199,127,127,237,223,191,
-207, 84,238, 0, 22, 58,103, 59, 30,150,145,238,102,229, 58, 2, 87,179, 33, 49,144,153,232,236,188,121,212, 68,159,246,183, 11,
-162,210,202,199, 53, 75,206,249,170, 62,187, 67,191,126,102,199,235, 70,189,150, 5,209,105, 71, 46,170,109, 64, 69,201,209, 24,
- 47, 45, 34,233,170, 80, 43,250, 33,133,155,237, 16,194,166, 30, 43,122,228, 16,142, 95,216, 71,136, 96, 88, 95,228,238,171,159,
-126,121,213,245, 28,114,203, 33, 76,112,150,137,210,196, 64,174,114,152,189, 84,243, 76, 69, 33, 4,115,175,241,116,162,156, 85,
-226, 73,150,100,183, 96, 14,168,192,202,237, 20, 13, 82, 65, 43,169, 90,110,125,206,140, 8,171,251,246,155, 47,186,123,111, 98,
- 15,139,106,201,104, 27, 5, 45, 87, 81,197, 71,199, 93,148, 60,167,103, 79,251, 66, 70, 55, 56, 88,113,248, 76,222, 38, 16, 87,
-193, 62,162, 21, 0, 83,249,201, 94,125,253,199,203,255,126,251,253,175,189,106, 81, 58,144, 28,176, 48,126,242, 52,121,163,228,
-111, 40, 4,164,241,155, 45,162,135,212, 88, 9,103, 21, 27,182, 91, 89,175,212,143, 44, 35, 55,186,125, 91,167,106,235,176,201,
- 21,114, 11, 16, 2,208, 64,217, 75, 18, 99,228,228, 34, 37, 74, 72,170, 67,225, 62,164,202, 53, 44, 64,124,154,188, 36, 13,195,
-226,140,188,178, 56,128,186,115,145,251, 49,204,209,124,116,248,242,187,231, 79,126,248,241,226,242,234,173,240, 31,194, 56,111,
-243,160,192, 93,236,206,227, 25, 55,238, 75,147, 91,153,189,135, 98,200,146,220,182,140,236, 65,100, 15,247,226, 20,154, 72, 9,
-215,164, 98, 94, 28,100,207, 57,232, 52,194,194,144, 63,216, 47, 67, 89,134, 89,228,163, 94,132, 71, 42,130,147,201,152, 71, 14,
-202, 98,137,164, 42,165,126,242,240,237,155, 71,161,216,203,211,159,211,187,235, 20,119, 84,221, 64,173, 51,144, 26, 5,215,218,
-109, 12, 4,101,227,137,134,135, 35,128, 76,219,129, 42, 30,201,100,128, 21, 89, 81,244,139,196, 31,177, 90,164, 22,117,237,149,
-248,244,193,223,215,167, 51, 75,101, 27,220, 16, 42,238,138,153,116, 69, 70, 99,231, 11,103,163, 20,105,247, 97, 23,196,181,180,
-101,197,169,109,118,191,121,216,169,151, 5, 88, 37,144, 80,152, 41,145, 83, 26,164,241, 48,100,127, 71, 61,178, 82, 42,196,158,
-148,116, 94,112,169, 3,231,157, 96,169,100,155, 70,157,160,173,179,241, 24, 95,254, 60, 31, 11, 9, 32,129, 25,182, 94, 48,238,
-202, 33,126, 1, 26,192,115, 27,138, 94, 41,131, 10, 92, 58,206, 49, 49, 52,122,184, 27, 37,104,216,106, 47, 1,221,129,241,107,
- 65, 93, 4, 96,227,128,119,148, 36,207,178,138,150,172,116,100,125, 71,100,242,220,232, 43, 43, 69, 70, 82, 85,166, 92,185,118,
-119,177,215, 15, 93,238, 68, 50, 67,242, 55,128,213,210,225, 42,136, 26, 93,136, 39, 20,114,133,186,211,109, 66,140, 17,202,101,
-210, 33,111,252, 59,197,224,133,108,115,205,145,228,149,165,233,132,170, 95,117, 53, 7, 13,120,246, 16,245, 93, 40, 84,189,181,
- 76,179,236, 16,166,124,198, 86,181,168,226, 67, 52,148,254, 20, 12, 43, 78,222, 23,210, 20, 60,116, 10,104, 58,105,125, 89, 26,
- 15, 32, 91, 96,215,143,159,126,242,234,118, 61,253,243,193, 33, 78, 87,122, 34,107,100,177,168, 82, 26,202,184,145, 67, 34, 59,
- 57, 85, 28, 20, 53, 60,126, 41,109, 86,147, 59,148, 75, 10,202, 84,123,199, 29, 57,228,218,106, 80,243,238,208,193,132, 74,224,
-166,253,121, 70,209, 93,237, 92,116, 40,211,186,182, 74, 75,194, 15, 87, 13,183, 39, 77, 89,108,166, 88, 66,101,238, 80, 78,140,
-189,225, 32,170, 72,117,182,138, 93,232, 26,182,137, 63, 66, 45, 77,248, 22,172,213, 45,197,159,161,192, 39,254, 34,147,151,156,
- 27,177,224,150,162, 54,220, 59,246,114, 81, 59,132,102,178,157,194, 51, 26,132, 4, 97, 52, 80, 65,136,205,185,106, 11,223, 0,
- 44,195, 50,234,218,160, 56,176,130,146, 7,248,150,139,165, 78,192,214,251, 98,179, 35,105, 87,210, 60, 45, 4, 18,172,100,169,
-225,184, 77,233,225,254, 68, 53,225, 94,202, 28,102, 90, 57, 66,183,252, 47, 0, 73, 87,178, 35, 73, 13, 5,211, 78, 59,157,206,
-165, 26,141,154,110, 54,181, 52,160, 17, 32, 36,184,114,226, 6, 18,226, 15,144,248, 14, 36, 62,141, 27, 92, 71, 32, 78, 92, 17,
-195, 50,163,161,153,234,172,170,204,180,211, 27, 17,201,177, 14, 85,101,121,121, 47,194,126, 47,162,254,234,155, 47,145,178, 46,
-155,247,177,156,211, 63,130, 87, 6,142, 91, 47,150,101, 42, 11, 38, 54, 68,106, 31, 2,130,130,216,198, 93,197,169,148, 77,179,
-189,147,154,219,173,236, 17,162,114,233,175, 54, 36, 2,187,120, 55, 88, 36, 22,201,246,134,112,152,238,190,254,226,112,119,247,
-253,241,143, 95,214,135, 72,139,107,218,172, 59,165,233,115,200,119,208,226,169, 91,149,207,170, 32,176,237,221,246, 72, 35,225,
- 69,103,151,155,225, 16,183,241,184,246,154, 66,215,171, 76,124,214,235,243,253,170,174, 93,245,164, 60, 72,227,127,163,218,210,
- 54,213,213,196,214,142, 66,203, 40,225,182,109,153,195,234,242,197, 7,176,208,165, 81,206,131,112,208,216,168,232,124,138,124,
-128, 8,160,115,189,181,183, 63, 63,253,117, 78, 15,169,166, 93, 80, 4, 49, 59, 50, 53, 47,145,250, 59,103, 42, 63,108,108, 30,
- 5, 71,247, 70,159,130, 94, 21,217,102, 17,115, 5,118,108, 10, 34,113,205,250,140,165,137,169, 90, 45,213,125, 0,250,243,209,
-167,207, 63,123,255,181,155,103,151, 87,224,226, 20,167,103,131,139,234, 56,165,108,207,194, 71,140, 89,239,245,216,108,129, 78,
- 32, 77,152,112, 46,210,202, 58,217,186, 5, 8,227,109,170,244,205,245,155,107,120,251,135, 31,159, 54,216, 12, 13, 40,105,165,
-221,174,238,139, 67,163,228, 5, 32, 60, 84, 72, 25, 88, 75,105, 17,211, 76,209,154,114,215, 94, 2,137, 85,165,190, 40, 82,230,
-110,148, 83, 5,130, 78,108, 69,243,192,134,226, 50, 64,132, 44, 93,144,180,214, 45,187, 82,243, 10,242,195, 87,186, 64, 41, 31,
-214,243,128, 49,177,149, 16, 84,177,139, 52,126,244,205,186,164,173,168,241,163,199, 31,124,251,221,237, 39,159, 34, 90,255,238,
-143,156, 39,102, 68, 10,186,128, 29,132, 93,161, 17, 19, 62,236, 53, 48,248,237, 85,128, 51,173,244,227,101,101,193,100, 68,164,
-156,128,230,127,102, 94,160,145,195,128, 20, 36,208,136,248,111, 70,124, 47, 41, 4, 66,120,108, 98,197,107,154, 25, 4, 17, 9,
- 70,165, 37,103,234,249,239,250,239, 67, 51,126,252,198, 95, 47,158, 36,119,190,214,203,124,255, 39, 25,214, 43,154,209,233,192,
-250,247,204, 78,123,178, 93, 68, 17, 36, 75, 6,113,190, 91,176,162, 38, 52,180,248, 64,120,165, 46, 17,245,197,170,210, 81,165,
-160,125,167,139,143,223,122,182, 76, 86,215, 27,130, 94, 0, 62,174, 93,143, 25,161, 69,161, 46,244,137, 89,165,201, 9,145,100,
- 70, 76, 47, 14, 59,131,234,163, 72, 69, 52, 98,194, 57, 23, 15,216,133,136,119,146,142, 49,102, 23,245, 93, 68, 60,137,160,103,
- 67,152,229,162,245, 94, 82,135, 60,227, 72, 99, 14, 16,244,194,255,251, 3, 67,244, 82,149,171,215,235,231, 63, 5, 55,197,153,
-154,239, 94,208,107,199, 0,108,155,250, 20, 48,109,148, 97,136, 73,198,189,164,190,207,166,237,153,151, 65, 56, 34,209,143,162,
-162,131,195, 1, 46,141,166,125,156,174, 89, 98, 10,210, 16, 89, 72,201,175, 83,119,175, 35,175,137, 99,230,187, 8,171,119,216,
-177, 87, 93, 16,213, 40,163, 47, 15, 0,165,188,151,247, 62,165, 41,110,107, 9, 84,221,103, 97,139, 26,178,174, 20,137,173, 9,
- 93, 33, 70,201, 88,165, 64, 87, 73, 65,102, 90,177, 23,163,214, 7,171,113, 10, 87,147,213,204,242, 67,153,233, 23,100,104,114,
-203, 18, 30,189,129, 54,129, 67, 81,231, 95,136,221, 83, 36,198, 94, 32, 9,168, 32,105, 98, 18, 60, 66, 32, 14,107, 1,229,232,
- 16,198,128, 53, 54, 38,105,211,139, 15,223, 51,127,223,188,251,242,254,185,171,146,223, 5, 99, 35, 21,194, 90,222,105, 43,169,
- 31,177,215,106,180, 93, 53, 52, 36,141, 45,120, 13,206, 82, 55,154,129, 0,205, 58,106, 73, 34, 99, 8, 59,220,234,177,200,126,
- 19,249,170,173,172,177, 76,188, 3,194, 79,104,218, 45, 96, 49,128, 25,237, 85,115, 9, 97,176,105, 85, 24,143, 3,200,142, 20,
- 44,162,114, 45,112, 84,127, 94, 11,235,193,156, 22, 53,136,100,159, 55,156,193, 69,249,193,128, 9, 83,235,162,185,180, 11, 22,
- 8,104, 94,225,112,130,183, 17,184, 43,196,107,178,197,203,108,114,193,240,152,191,244, 9,163,140, 81, 59, 3, 20,118,158, 1,
- 52,129, 31,114,117,154, 82, 93, 88,120, 89,128, 27,236, 54,122, 75, 9, 81,141,172,130,184,169,138, 54,246,145, 21, 25, 72,163,
-169,232, 81, 16,100, 51,151,186,113, 14, 24, 1,185,158,242,185,200, 77, 99, 59,171,220,252, 39, 0, 75,215,178, 26,199, 17, 69,
-235, 93,221, 61,210, 88,150,144, 72, 12,134,128,192, 1, 7, 19,131,241, 15,120,145,165, 87,129,124,131,241,183,101, 17,200, 87,
-100,149, 23,100,151, 64,176, 73, 28, 35,205,179,171,187,158,157,115, 6, 47,103,161, 81, 79,117,221,123,207,169,186,247, 28,253,
-205,119,223, 46,188, 73, 77, 38,133, 60,141,109,139, 0, 60,164,208, 66,219,119, 72, 86,114,218,135,186, 79,225, 62,204,230, 88,
-156,237,114,110, 92, 93,196,125, 18, 81, 17, 13,206, 26,232,162, 60, 68,109,209,235, 11, 84,249,190,239, 65,147,186, 28,221,245,
-171,167,253,215,143,127,220,252,251, 75,102,127,112, 15,182,162,176, 96,117,162,190, 19,229,157,176, 71, 2, 79,105, 79, 39,246,
-167,137, 29, 80,177,130, 39,200,105,227,212,116,227,183,247,241,114,163,134, 94,242, 16,180, 81, 70, 14,133,114, 76,122,216, 13,
-183,157,177,171,229, 93, 60,190, 47, 7, 64, 6,159,177,159,202, 78,110, 38, 82,183,133, 51,170,188, 74, 92,148, 30, 43,213,133,
- 40,126, 54,148, 66,114,138, 12,152,173,187,124,252,228,215,223, 62,126, 0, 63,161,184,135,184,103,235, 26,118,217,148, 19, 50,
- 13, 39,215, 69, 22, 28,221,154, 58,100,126, 35, 82,136,252,196, 70,221, 84, 40,190, 17,241,158,128,132, 44, 48,240,154,215,105,
- 68,111, 61, 27, 94,199,231,207,110, 63,191, 77,245,191,224, 9,220, 16,237,115, 99, 52, 25,122, 0,205, 84, 30,161, 30, 43,165,
-199,153,166,219,201, 22,132, 67,244,180, 70, 3,242, 83, 13, 65,192,137,166,214,157,165,207,214, 79,126,248,254, 39,112, 25, 30,
-153, 43,142,187,207,148,128,197, 70, 67, 0, 96,209,188,165,204,115,110, 20,203, 93, 26,197,200, 88, 68,156, 2,252,179,222,106,
- 67, 93, 77,205, 19, 65, 0,221,142, 50, 14,244, 53,181, 72, 23, 25,171, 20,144,196,177, 83,121, 26,109,154, 1,211, 78,213,118,
-120,165, 3, 13, 62, 65, 72,153,158, 35,190,184,107,138,179,162,117, 22, 95,188,126,253,242,205,219,155,213,213, 59,113,188, 11,
-212,148,139,146,142,214,154,211, 61, 68,104,133, 89,134, 45, 60, 8,207, 45,229, 25, 57,175, 39,117, 88, 84, 22, 88, 74, 17,150,
- 26,120,182,186,180, 25,233, 65, 90,167,130, 64,209,165,160, 53,118,193,198,180,163, 40,169,130,192,206,119, 22,251,177, 76,105,
- 98, 62, 95,114, 40, 50, 22, 79,199,161, 69, 2, 59, 89,181,126,118,243,231,199,167,211,252,254,209,245, 60,126,248, 61, 29,151,
-182,211, 37, 81,198,252,147,155, 54,111,232,136,205,219, 73,189,140, 22, 17,242,116, 17,176,124,130,240, 82, 32,186, 37, 98, 4,
-165,191, 72,177,186,144,234,234,197, 95,105,186,216,110,165,246, 28, 43, 51,131,156,202, 64,109, 4, 36,219,169, 26, 94,167,171,
-112,164,132,174, 65,200,178,141, 75, 72,188,191, 74,191,179,216, 21, 20, 45,194,102, 71, 53, 22,201,221,212,128,220, 80, 30,164,
-227, 1, 34,222,145,167,170, 44, 25, 5, 30, 66, 31, 4,173, 38,192, 61, 43,118, 65, 77,113, 92,234,114,249,229, 42,222,165,191,
-255, 72,142,178, 85, 26,248, 26, 69, 53, 83, 46, 47,143,248,107, 57,156, 73,155,178, 11,108,149,117,154,180,190, 2, 57, 12, 20,
-159,232,170,222,105, 14,109, 15,150, 36,138,247,169,166,166,115, 90,248,209,141,120,226, 69,232, 73,208, 95,165, 77,171, 10, 68,
-247,228,181,192,187, 95, 67,135, 24, 35, 60,234,213,222,238, 70, 80,184,214, 91,214,128, 49,214,184, 41,199, 67,162,121, 0, 22,
-222,120,155,189,137,182,108, 53,109, 47,144, 26, 61,149,115, 17,121,100,123, 2, 8, 19,149, 42,214,228, 80,196, 58, 84, 84,214,
- 12,193,142, 79,154,161,212,158,204, 13, 43,143,159, 43,122,169,246, 73,198, 56, 59,202, 71,209,211,129, 29,115, 39,165,126, 75,
-195, 44,182,154, 14,206,211,189,103, 57,121, 61,184,124,109,123,249,213,163,159,255,217, 2,236,157, 63,188,242, 93, 11, 14,249,
-212, 1, 45,160, 6,209,156,200, 75,131,186, 43, 84,245,218,177,149,214,183,206,202, 51, 25, 31, 0,222,107, 54,153,173,236, 66,
-139,109,117,143,146, 14, 22, 4, 0, 33, 1,170, 2,158, 21,187, 81,227, 71,163, 76,202,121,206,105, 60, 63,248,249,129, 25, 50,
-141,138,155, 61,199,174,161,212,181, 50, 83,227,233,167,108,178,207,188,149,177, 19, 56,251, 2, 40, 96, 28, 56, 12, 21,231, 85,
-135,189,112, 65,165,198, 97, 98,184,249,224, 2,234, 75, 60,172,240,255, 22,246, 14, 33, 22, 58, 64,139,110, 71, 83,215,153, 64,
-172, 8, 15,204,176,150, 18,204,148,133, 4, 84, 78,245,180,101, 64,169, 86, 9,232,242,166, 26,170, 74, 23, 0, 65, 81, 6,206,
-107, 78,154,154, 83, 88,119,205, 6,108, 84, 88,106, 37,117,246,120, 0,139,228,113,100, 88, 38,227,114,182,255, 11, 64,210,181,
-235, 72, 82, 67, 81, 63,235,217,213,221, 51,172,180,210,106, 2, 36, 64, 48, 36,128, 8, 32, 71, 68, 75,206, 23,108,176,159,180,
- 95,176,255, 64, 66, 74,134, 64, 34, 71,204,160,133, 1,209,189, 61,229, 42,151, 31,101,206,169,205, 90, 29,149,237,235,115,207,
-177,125,207,213,223,126,255,141, 95,206,128, 52, 57,173,206, 36,119, 41,155, 85,195,146,167, 52, 79, 98, 84,238, 80, 70,235, 87,
- 29,146,183,126,134, 84,102, 31, 44,208, 15, 68, 69, 13,128,105,154,168, 83, 5, 82,208,138,122,127, 52, 51,254,194,167,177, 52,
-121,255,197,205, 71,207, 63,254,209,253,253,195, 20,119,239,202,244, 16,103, 54,111,143,226,120, 96, 89,241,109, 4,251, 82, 75,
- 33,177, 59,189, 74,251,210,204, 44, 91,160, 73,148,206,201, 85,245,124, 5, 13, 22, 15, 39, 95, 89,229, 42, 57, 69, 0, 83, 88,
-141, 63, 67,249,156,215,247,211,250,201,241,234,172, 47,115, 40,231,156, 33,230,216,228,136,229, 35,101,123,175, 26, 55,159, 49,
-154, 55,234, 50, 19, 38, 22,228,122, 54,232,212,144, 47,199,155,221,195,125,250,253,183,135, 29, 84, 64,172, 29,132, 50,166, 42,
-219, 49,176,180,136, 79,216, 50,249, 52,114,141,207,185,169, 89,188, 88, 38,233,160,149, 51,166,106,235,208,145,161,210, 5,205,
- 95,147,140, 20,101, 88, 93,253, 79,126,124, 50, 60,251,236,235,103,209,253,199, 34, 87,177,149,167,243, 45, 96, 2, 85,201,204,
-115,200,104,114, 13, 42, 39,242,116,181, 53, 18, 76, 9,195, 47,188,168,219, 78,138,245,246,222, 2, 99,110,111,190,122,245,250,
- 39,239, 46, 93,199, 97,224,195,233,212,196,183,168, 32,191,236,121, 94,147,143, 10, 26,153,130, 7, 86,169,122, 87, 50, 89,153,
- 88,135,157, 90,116, 77,119, 84, 76, 73,104, 76, 94, 89, 63,130,220, 1, 77,248, 56,178,200, 89, 27, 21,232,195, 85,122,165,192,
-185, 98,100, 83,212,172, 35, 27, 50,107, 19,181, 52,134, 55,235, 86, 58,191,200,246,248,225,139,151,159,126,247,252,164,204, 31,
-129, 85,190,136, 39,236,205,173,125,181,162,243, 42,169,232,202, 62,186,188,118, 22,216,187, 89,176,213, 70, 17, 64,240,113, 41,
-163,152, 92,242,206,231,191,130,169, 26,115,144,200,101, 37, 26, 30,117, 0, 58,121,246,149,210, 25,210, 56,172, 1, 74, 12, 2,
- 49,229,203, 42,188, 82, 99, 41, 39,240,214, 4,212,198, 88, 48, 2, 30,229, 86,226,234,203,227,155,187, 91,119,190, 63,182,215,
-245,253,207, 19,208,241,212,172,180,248, 84,198,103, 40, 91,158,117, 41, 49, 50,248,249,219, 47,162,234, 8,238,128,143, 70,109,
-158,239, 53,187,171,234,176, 53,238, 26,212,241,122,177, 31,220,254, 2, 66, 84,156, 48, 61, 86,203, 65, 2, 33,143, 74,224,151,
-222, 26, 29, 66,176,205,190,237,114,208, 49,112,231, 97, 53, 65,116,120,250,193,234, 68,172, 74, 44,209,134,224, 44, 67,143,125,
-224, 48,247,185,244, 44,200,161,108,193,111,195, 46,205,137,185, 14, 97,237, 53, 95, 82, 6, 22, 27,215, 77,153,237,170,150, 85,
-214,215, 79,247,255,222,205,111,238, 38, 33,167, 69,109,221, 45,233, 7, 18,233, 2,108,124, 0, 16, 87,242, 61,153,123,218, 0,
-219, 69, 2,252, 98,197,251,156, 98, 17, 6,235, 1,171, 54,130, 12,150, 84, 41,197,130, 99,146,104, 79,239, 8, 97,102,228,238,
- 50,251,184, 61, 68, 72,113,148,147, 14, 80, 34,216,192,172,121,149,140,196,183, 86, 65, 66,167,201,176,167, 83,201,225, 97,237,
- 32,100, 70, 16,191, 52, 61, 38,176,155, 9,148,155,246, 54,114,109, 42,139, 13, 29, 85,239, 33,101, 72, 86,100, 86,122,166, 59,
- 53, 27,189,143,241, 45, 80,156, 73, 13, 49, 43, 27, 80,246, 68,187,206, 11,216, 7,229, 85, 1, 30,156,138,223,133,205,114,134,
-158,213,228, 63, 44, 77,128, 46,166, 1, 53,200,118,222, 10,180,129,151, 9,144, 21,179, 48,131,121,242,249,237,175,127,118,110,
-244,214,224, 59,248,142, 28,179, 83, 63, 69,220,106, 22,106, 97,184, 67,103,155,174,158, 92, 62,238,129,127, 77,218, 65, 94,212,
-218, 33, 13, 0, 4, 32, 93,210, 33,207, 57, 15,177,107,251, 13, 91, 75, 47, 49,133, 64,204, 85, 15,234,226, 35,111,182, 75,160,
- 39,204,144,216, 73, 3, 59, 81, 95, 66,238, 6,236, 28,138,107,236,213,142, 22, 33,203,140,229,236,185, 83, 4,115, 12,102,215,
-183, 60, 99, 45,222, 46,188, 61, 55, 10,241, 98,139,205,105,245,192,248,186,197, 50,245,222,242,217, 86, 84, 59, 30, 71,201, 42,
- 65,155,132, 6,201, 94, 85, 10,129, 77,123, 4,224, 65,182,241, 88,129,154, 41,154, 47,232,182,211, 49,247, 32,171,152, 29, 48,
- 10,185,195,103,198,118, 98,199,236, 52,177,244,218,176,182,189,193, 54, 26, 27, 95,235,193,164,222,164, 12, 25,223, 68, 91,107,
- 63,255, 47, 0, 71, 87,207,235, 70, 17, 69,231,123,214,235,216, 78,244,172, 60,145, 68, 72,128, 4, 1, 36, 64, 41,105,160, 72,
-145, 38,127,131,138,159, 70, 65,195, 95,160,163,160, 64, 17, 18, 5, 5,232,249,161, 60,219,239,121, 63,102,102,103,102, 57,103,
-123,203, 94,207,222, 57,247,156,153,123,207,213,111, 95,127, 23, 32,107, 23, 28, 11,236, 91,237,103, 26, 39,158,179, 44,253, 5,
-177,209, 32,208,207,108,129,193, 19, 73,218, 90, 74,171,252, 44, 86,214, 22,237, 52,180,135,216,212, 6,164, 54, 94, 3, 59,231,
- 38,168, 43,112, 96,223,104,251,201,219,143,254,216, 14, 63,159,111,199, 98, 91,197,203, 64,207,203, 23,228,165,236, 75,197,190,
- 91, 25, 86,246, 1,203,247,117, 30, 5,146, 70, 57,206,165, 44, 80, 56,145, 81,131,210,164,193,219,195,227,162,239,210,117,168,
-118, 21,142,153,238,237,134,242,155, 55,150,195, 33,236,250,205,243, 77,125,186,121, 28,164, 8,181, 79,179,213, 60,201, 97,205,
-177,201,180,153,145,161, 79, 19,190,158, 39,212, 64,126,188,186,182,210,236,199,110,159,184,221,151,159,254,254,231,157, 58,135,
-236, 12, 62,228,193, 34,121, 75,197,201, 79,208,167,231, 73, 5, 57,146, 76,179,147,177, 70, 86,241,168,174,229, 17, 57, 98,175,
-213,102,169,164, 87,231,196,122, 44, 95,240, 50,234,218,251,251, 88,251,206,189,121,189,151,245, 95,142,104,103,110,161,161, 39,
-251, 17, 33,242, 29,173,103, 83,209, 88, 76,108,103,176,120,214,129,179,117, 23,111,123,173, 53, 57,112, 85, 72,245,144,231, 92,
- 3,119,245,237, 79,191,188, 59,156, 14, 27, 80, 93, 32,104, 85, 77, 98, 79, 20,152, 10, 72, 53, 95, 47, 2,147, 73,143,238, 45,
-134,197,138, 20,103, 45, 30,175, 66, 41, 65, 34,187, 71,190,152, 49,180, 64, 83,218,111,120,101, 52, 81, 5, 92, 20,124,111, 66,
-198,145, 65,203,218,129,143,208,221,174,212, 41,173, 72,166,156,145,200,111, 59, 81,250, 18,135,251,171,207, 94,125,253,227, 15,
- 31,126,245,234, 70,148,219,208,227, 77,201,197, 83, 69, 45,227,190,237, 98,151,128, 60,182, 18, 44, 59, 76,128, 71, 49, 38,125,
- 97,215,128,138, 41, 61,164, 52,148,190, 31,198,255, 74,119,207,131,229,237, 51, 48, 69, 69,165,139,191,190, 76,186,154,122, 51,
-117, 0,104, 22, 4,165, 27, 27,223,103,118, 31, 95,180,206, 57,199,138, 15,100, 71,156, 38, 56, 84, 8,146,106,215,238,234,251,
-235,155,195, 62,142,231,173,120,161,110,223,117,151,174, 97, 85,161,232, 64,144, 71,109, 0, 7, 61, 16,113,174,154, 71,189,134,
-187,131,213,184,224,245,208, 3, 32,242,145,166,231,108,134, 51,196,102, 90,216, 34, 60,155, 47, 62,255,251, 84,108, 56,178,141,
-146, 3, 5, 27, 80, 95, 60, 60,231,124, 72, 78,147, 2,230, 38, 86,202,142,133,136, 93, 2, 51, 77, 26,133,236,147,169,103,100,
- 42, 4,132, 40,216,208, 14, 9,175,230, 25, 4,110,113,225, 36, 43,148, 60,170,227,213,234,180,204, 98, 2,114, 56,172,152,231,
-232,103, 8, 51,110,113, 14, 16, 83,151,176,125,225,246,207,198,223,126, 77,227,195, 19, 55,127,240, 49,192,139,179,110, 83,136,
-225,148,212, 93, 31,161,174,176,221,181,223, 53,198,177,186,130, 61,250,134,238,240,172, 8,231,241, 95,163,170, 71, 46,194,226,
-131, 13,178,106, 6,144,141, 85, 78,120, 57,163,101, 7, 80, 65, 94, 87,156, 69, 13, 30,211, 97,229,197,120, 3,253,196,189, 23,
-250,204,226,243,177,206, 23,252,123, 58,195,172, 65,241, 45, 77,195, 13,189, 41,196,233, 88, 65,240, 11, 29, 56,243,113,224,169,
- 78, 23,216,107,175, 87,226,129,180, 22, 59,162,168,161, 64,112, 59, 8, 67, 41, 56,220,177,231, 92,231, 19, 9, 80,181, 49,231,
- 94,134,152, 71, 16,223, 76, 13,207,219,227,186, 40,192,204,128, 82, 18,244, 24, 60, 74, 34,115, 65,237, 48, 14, 4,183,164,103,
- 33,112,255,242,155,231,127,237,221, 63,249,178,213,179, 75,173,223,216, 25,164,102,102, 69, 77,105, 28,253,169,216,194, 84,231,
-173, 78,126,213, 54,167, 40, 7, 14,255, 5, 11,210,120, 64,132,171,131, 94, 50, 52,143,209, 5, 64,193,155, 5, 54, 35, 33, 40,
-198, 89,110,215,190,164,182,120, 96, 28,141,149, 13,183, 91,110, 12, 39,187, 86,146, 38, 60, 26, 71,189, 69, 4,229, 28, 21,146,
- 66, 19,173, 22,156,236,205, 46, 21,193, 2,137, 50, 47, 39, 38,122,153,124, 41, 70, 99, 57, 38, 36,251,150,150,196,128, 20,168,
- 41, 59, 4,195,206, 15,136,116,238, 96,232,101, 59,175,238,189, 81, 38,237, 88,137,196, 66,248,117,205, 50,149,137, 7,116, 96,
-234,196,155,165, 51,119,122,224,137,240,154,174, 33, 8,206,104, 28,226,214,210,212, 96,166,192, 54,205,148, 56,199, 21,225,240,
- 40,134, 34, 86,130,191, 48,253, 47, 0, 71,215,178, 27, 73, 17, 4,235,209, 93, 53,213, 61,110,143,103, 89,175,119,121, 72, 72,
-200,172, 44,173,144, 16, 32, 78, 32, 62,128,255,128,239,226,204, 63,112,230,202,129, 11, 66, 32, 48,107, 99,227,121,244,179, 30,
- 93, 67, 68,223, 44, 31,198,158,238,172,204,136,172,204, 8,253,245,183,159,177,113, 51,248,118,136, 93,151, 74, 48,197, 54,117,
- 94,131,148,150, 7, 79,211,191,189,151, 32,204,156,211, 15,140, 8,222,255,129,157, 77, 26,228, 7,145, 98,140,222, 54, 49, 6,
- 60, 0, 43, 77,179,229,154,231, 62,158,125,121,249,234,211,139, 31,246,221,173, 55,239,148, 22,100,156,247,229, 5,178,129,169,
-144, 66, 85,201,133, 58,170,105, 80, 85, 32,107,142, 69,109,241, 64, 0,107,151, 53,165,169, 72,143,148,101,165,143,100,170,171,
- 93,101,228, 67,251,126, 34,250,223, 41,234, 44,196,236, 65, 89, 6, 61,221, 79, 81, 63,244,151, 94, 94, 63, 63, 59,175,234, 40,
-233,135,224, 41,175,146,112,184, 75,110, 48,227,216,141,114,106, 35,224, 54,222, 21, 82, 99,106,128, 61,145,116,186,171, 15, 94,
-238,110,227,207,191,162,174, 4,167,181, 31,203,136, 16, 86,126,226, 42, 49,162, 37, 22, 64, 60,147, 2,167,200,248,226, 0,253,
- 3,167, 47,145,185,164, 77,253,172, 98, 24,235,138,205, 78, 28, 51, 78,218,245,150,106, 8,157, 60,246,254,243,143,111,182, 47,
- 79,225,176, 35, 76, 93,102, 55, 50,119, 93, 54, 34,214, 52, 15,206,120,121,134,118, 16,236,211, 24,228, 89, 2,187, 2, 21, 80,
- 81, 21, 76, 70,242, 46, 42,133, 72,251,252,139,159,126,252,229,238,237,223, 27,229, 72,183,153,144, 68, 56,195,167,226, 31,101,
-146,157,180,226,115, 87, 84,199, 35, 55,170, 10,206,138,114, 57,182, 12, 46, 73, 75, 51,205, 65, 56, 16,200, 42,205,171,176,136,
-186,115, 10, 51, 11,156, 63,118,149, 53,117,120,109,206, 5,175, 26, 9,240,149,104,168,231, 42,192,138, 14,187,160,207,223,251,
-230,171,155,239,190, 23,219, 87, 79,167,241, 48,118,121,209, 97, 36,214, 35,245, 72, 52,197,210, 56,251,236,146, 38, 49,142, 56,
-154,170,119, 26, 28, 23,232,227, 32,253, 99,236,143,113,220,165,177, 75,125,203,188,251,236,114,173, 95, 44, 10, 17, 72, 48, 19,
- 37,194,168, 72,156, 82, 30,184,226,205,139,198, 73,164,209,203, 73, 82, 0, 99,200, 29,157, 84, 79,171, 54,113,143,115,165, 80,
-155,228, 6,223,114,181,185,185,254,243,254,194, 31,254,113,235,109, 35,159,252,253, 91,223,150,128,229, 40, 81, 38, 20, 85, 89,
- 32,198,240,247,150,182, 21, 21, 94, 80, 86, 21,119, 66,137, 16,193,198,170,165, 28,114, 68,255, 36,139,154, 63,187, 75, 97,175,
- 63,249,253,110,140,195, 19, 88, 22,133,189,201,183,105,109,151, 92,195,142, 43, 40,192,137,247,227,163,220, 39, 38,200,217,227,
- 89, 7, 93,236,204,108, 38,179,146, 39,208, 69,192,213,140, 4, 26,188,106, 44, 48, 48,138, 6, 85,104,128,153,231,148, 80,214,
-107, 78,122, 90,167,217,238, 24,217,213, 93, 38,107,102,174,113,186,130, 2, 63,209,140, 89, 95,125,164,250,223,242,221, 31,175,
-111,116, 99, 93,199,209,169, 83, 71, 29,173, 92,212,243, 1, 5,231, 49, 28,158,186, 7, 36, 87,164,184, 77,195,156,218,230,112,
- 46, 36, 59, 14, 5, 93,139,148,181,165,229,192,142,156,237, 40,227,145,107,127,129, 94,226, 5, 87, 68,143, 34,182, 28, 55,161,
-160, 38,157, 67, 53,205, 6,244,188,207,114, 60,226,189,242,206,164, 67,104,178, 66,231,182, 37,173, 13, 96, 81,200, 71,131,160,
- 13,155,201, 83,127, 18,139, 35,231, 76, 85,176,204, 73, 74,192,193, 49,250,255,136,236,255, 45,244, 35, 96,224, 81,229, 14,156,
-122, 68,152,231,105,198,199, 32, 38, 4,135, 84, 56,217,191, 25, 4,151, 12, 36,167, 62, 22,115, 74,218, 37, 9, 82, 66,142,148,
- 22, 66, 95, 72,201,200, 52,188,212, 58, 7,136, 64,152, 85,226,195, 55,239,222, 94,109,118,127, 77,139,105, 70,217,173, 41,254,
- 34,243, 80,173, 4,199,118,109, 93,174, 74,135, 42,230, 28, 61, 69,140, 78,217,154,181,139,204,206,242, 25,168, 46,126,129, 10,
-155, 44, 21,163,195,100,215,167,217,153, 41,116,154,112,149, 91, 56,217,243,130, 16, 71,146,157, 74, 87, 2,140,142, 57, 69, 54,
- 4,169,102, 97, 74,132,164, 25,230, 6, 37,154,126,231,200, 0,200,186,136, 16, 74, 96, 34,131,177,239,100, 80,207, 93,170, 7,
-148,176, 90,204,213,139,131, 71,198, 15, 43, 4,148,119, 74,175,103,151, 22, 74, 5,222, 3,252, 98, 65, 72, 1,250, 61,192,131,
-141, 57,248, 53, 45,181, 40, 88, 71,107,225,100, 40, 51, 9, 8,205,171, 65, 0,207,101,236,156,144, 76,210, 88, 15, 48,199, 40,
-222,200,247,195,100,164, 60,227, 38, 86,162,140,226,116,114,244,235, 13,253,112,110, 74,169,254, 23,128,163,107,217,145,156,134,
-162, 73,252, 74,170, 83, 93, 69,207, 52, 51, 72,195, 67, 51, 12,219, 17, 72, 32,129, 52, 91,126,128, 37,136,255, 99, 3,223,129,
-132,196, 7, 32,102,129, 68,247,244,131,174,206,211,142,237,216,156,147,117, 73,149, 84,249,250,222,115,236,123,207, 17,223,189,
-125, 59,216,190,162,228,229,137, 93,101, 57,142,115, 96, 79, 90,223,167,217,185,217,209, 44,181,230,236,161,140,198,163, 34, 1,
-117,160,118, 24,141,204,185, 26, 30,198,237,176, 65,234,198, 52,181,164, 36,177, 5, 78,189,190,252,252,251,203,171,227,253, 47,
-221,236, 69,121,174, 40, 91, 13, 10, 34,184,105, 12,185, 80,169,219, 2, 43, 94, 26, 74, 57, 33,207,132, 68,197,248,117, 59,186,
- 45,116, 9,182, 74, 85,190,186,116, 68,107,185,188,111,245, 77,230, 72,244,197,188,118, 58,246,210, 9,176,141,169,212,108, 9,
- 27, 78, 99,188,191,233,243,181,253, 34,152,215, 23, 31,124,186,191, 60,111,212,184, 61, 84,216, 98,216,180,190, 67,164,105, 56,
-254, 38, 60, 6, 24, 47, 11, 79,101,178,243,195,254,240,226,236,247, 63,167,177,239,141,166,125,118,230,168,200, 90, 77,229, 38,
-114, 94, 76,147, 34, 21, 34,210,172,134, 82,209,186,241,137, 76, 62,153, 33, 57, 65,203, 92,151,165, 30,179,234,227, 44, 40,100,
- 34, 76, 4,111, 13,214, 45, 15,234,155,175,143, 66,188,155, 35, 2,138,246,123,165, 60,202,226, 80, 40,193,187, 83, 84, 74,148,
- 65,252,116, 13,232, 38,217,246,186,162,102,250,109,240, 31,229, 0,181,151, 9, 96, 77,109,243,236,203, 95,127,251,227,253,237,
-245, 89,187,171,120,160, 90, 84, 96,162, 19,229,101, 12,184,159, 96, 55,255,110, 27,224,144,134, 87, 11, 92,209,130, 23,119,160,
-166,108, 87, 64, 80,141, 66,153,108, 72,150,240, 26, 8,153,188,119, 66, 9, 30,158, 88,201, 35,138,186,198, 94,150,156,127,110,
-217, 62,170, 54,120, 59,148,160,170,190,151,175,126,254,233,205, 15, 63, 34,144,222, 47,221, 67, 88, 50,207,210,240,138,113,187,
- 28, 86,200,196, 59, 60,141,198,199,148,224, 71,133, 4,228,152,211, 28, 66,103,253, 35,120,140, 95,110,227,112, 90,163,141,254,
- 97,233,134,252,244,229,147,139,207, 90,234, 97, 33,235, 69,149,123, 54, 76,134,222, 91,246,220, 38,208,200,229, 6,201, 35, 44,
-137,119, 8,133, 93,195,163,226, 44,102, 0, 78, 4, 0,207, 84, 54, 87,212,246, 60,107,204,241,219, 87,239, 78,237,228,175, 68,
- 91, 63,179,113,248,247,111,202,242,175, 90,113,160, 32, 7,228, 57,164, 26,148,104,228,188,213, 80, 79, 77,209,254,130,133,137,
-150, 38, 88,148, 2, 47, 43, 73,162,203, 77,254,191,168,143,197,254,245,155,127, 74, 59,119,221, 98,140, 70, 4,222,249,220,101,
- 0,226, 0, 66,155,104,213, 92, 6,236,197,122, 32,141, 6,242, 41,199, 85, 44, 46, 48,133,155, 72,229,120,154, 6, 99, 7,212,
-209,130,233, 34,203,244,244, 81, 4,137, 64,169, 80,166,160,178,225, 57,135, 17,178,198,110,117,137, 68,105, 27,249,226, 73,177,
- 16, 99, 37,102,124,111, 42,154,121,215,166,253, 39,207,125,255,241,243,255,174,110,101,159,146, 27,214,147,173, 26, 87,198, 0,
-168, 12, 66, 8, 12,153,150,126,153,175,173, 64,241,211,230,120, 40,139, 51,227, 31, 93,131, 0, 22,105,244,137, 6,112, 70,211,
- 58, 89,137,199,200, 62, 53, 30, 20,174,244, 76,113, 60,182, 82, 52,226,226,244,112,234,100,150, 14,239,100,172, 83,108,112, 66,
- 93,180, 18,152,151,250, 42,150, 72,159, 14, 99, 57,143,117,182, 88, 44,246,135,151,148, 60, 3,121,193,183,186, 53,206,148, 54,
-163,218, 25,155,134, 17,116,128,244,107,154, 28, 40, 63,219, 19,188,164, 60,213,226, 65, 92,155, 76, 47, 45,144, 89,228, 69, 44,
-177,167,255, 34, 81, 59,106, 11,113,151,170,118, 42, 34,245,241,198, 61,243, 34, 19,144,161,217,154, 1,228, 38,176,132,247,255,
-232,168,239, 94,124,245,215,195, 35,146,145, 52,132, 94, 88,241,106,255, 52,200, 85,108,125, 41,192, 96, 60, 45,113,116, 76, 67,
-164,243,210, 45, 9,163,231, 73, 43,124,234,162,220,213, 10,108,136, 61,220,168,177, 96,122,126,135, 77,116, 17,218,220, 68,212,
- 81, 10,104,234,176,178,217,131,114,101,123,206,174,243, 64, 33, 89, 63,179,105, 20,165, 30,204,206,123,186,219,209,246,209,199,
-233,144, 65,155, 26,118,178,240,206,195, 36,252, 9,115, 5,200,231,216,218,206,190,213,216, 56,236,246, 80,213,177,137,168,148,
-200,158, 6, 21,173,210, 11, 10, 9, 66, 89,210,245,219,155, 32,134,118,221,238, 27, 80,132, 87, 84, 45,141,240, 96, 83,172, 40,
- 7,202, 32,131,112, 27, 26,182, 33, 10, 85, 86, 86, 33,190,165,187,235,116,142, 85,211, 42,176,209,114, 0,172, 40,204, 14, 56,
-220, 83, 22, 54,119,226, 67,172,232,255, 2,144,116, 37,187,113, 21, 81,180, 94, 13,175,222,212,221,177,131, 25, 68,162, 8, 19,
- 11, 41,114, 16, 66, 98, 7, 97,201,134,255, 96,193, 63, 33, 62,129,143, 96,203, 14, 22, 1, 9,164, 88, 33,161,229,182,123,120,
-115, 77,156,243,178,180,221,139,118, 85,221,123,207,185,117,234, 92,245,237,247, 95, 77,105,238, 66,209, 79,156, 84, 56,210,142,
- 50,133, 0,242,233,178,149, 86,192,207,200, 41, 40, 88,166,225, 62,135,228,109, 94,174,179, 70,168,210,117,138,110,144, 86,154,
- 10,101, 45,165, 1,135,172,208,149, 64,121, 52,239,127,215,252, 50,111,255, 24,204, 70,129,119,226, 56,148, 90, 53,180,109, 18,
-178,162,186, 38, 20, 73, 47, 51, 90,240,225,101, 2,136, 88,116, 19, 25,226, 51,129,254, 83, 36,206,191,202, 42, 80,183, 42,220,
-112,184, 40,111,172,252,232,245,246, 66,165,110, 70,156,113,150, 8,141,149, 20, 87, 68,154,249,182,221,221,222,236,110,222,108,
-155,126,252,244,224, 63,209,250,243,234,252,217,217,199,151, 27,234,221, 2, 69, 53, 20,244,170, 84,178, 87,148,175,136, 25,218,
-227,225,209,103,171,245,217,227,191,126, 63, 96, 13,100, 69, 77,110, 39,133, 99,123,213, 83, 76,142,122, 20,144, 11,147, 31, 92,
-206,169, 25, 78,244,162,237,120,121,100,116, 86,121,112, 81, 69, 91, 88, 65, 75, 86,170, 17,134,152,207, 81, 24,241,234,205,221,
-243,167,215, 23, 87,218,119,109, 34, 4,164, 99, 59,128, 26,240,160, 76, 52, 17, 98,139,148,147,205,189,180, 52, 96,137, 36,141,
- 34,155, 54,241,157, 1, 30,187, 1,206,216, 38,127,239,234,167,159,127,221,223, 29,154,186, 70, 17,244, 52,151,101, 54,231, 52,
- 86,156,180,104,109, 20, 10,124, 28, 65, 89, 57, 27,217,195, 89,220, 14, 21,209,196, 42, 3, 44,241, 37,159, 11,234,154,158, 13,
-154,170,189, 44,143,238,109,105, 84,231,150,209,205, 65,244, 10, 68,200,133,153, 90,203,224,237, 74,205,211,176, 59,137,203,199,
-215, 63,252,120,249,245,139,189, 16,175,135,125, 71,147,101, 98,225, 69,211, 41,151,145,175,110,121, 65, 4,144, 22,128,203,188,
- 58, 9,154, 83,119, 34,180,200,135,169,219,251,211, 60,182,187, 56,222,143,199,118, 28,239,195,250,188,124,114,253, 80,157, 59,
-223, 59, 49,113,128, 72,192,185, 11, 50,158, 40,140, 14,168,113, 39,128, 64, 66, 25,179,143,238, 62,133,131,231,108,150,126,226,
-248,162,134, 51, 24,241, 13,120, 5,101,211,166,178,233,242,203,183,219, 57,187, 71,230,191,120,144, 38,119,251, 50,238,217, 90,
- 35, 24,166,198,147, 89, 16, 56, 7, 11, 0, 72,168, 17,184, 17, 17,165,168, 54, 49, 97, 42, 22,187, 94,193,214, 13,151, 74,114,
-202,116, 60, 19,235,167, 87, 47,129, 4,238, 90,148, 93,107, 20,197, 84, 13,152,214,226,132, 49, 77, 40, 18, 45,162,148, 18,139,
- 96,216, 39,164,110, 59,247,236,250,141, 57, 61, 98,143, 0,249,246, 68,126,163,171, 48,205, 66,114,212, 56,194,135,179,194, 29,
-199,252, 33, 43, 26,203, 27,245, 34, 51,194,206, 20, 71,122,166,126,106,109, 77,142,207,231,216, 93, 80,131, 99,103, 30,125,241,
- 36,254, 57,255,251,219,233,168,193,162,186,255,248,190, 51,234, 48, 32,145, 2,223,246, 97,114, 32,241,156,152,213,237,187,191,
- 71,196,159,217, 20,149,204, 11,207,135, 71,178,210,118,169,211, 78,142,177,150,168,195, 46, 71,198, 90, 94,143,201,192,217,122,
- 42,103, 40,251, 94,106,231, 71, 44,197, 20,251,180,104, 0,106,142,114,213, 67, 54,203,108, 39,243,117,239,176, 5,100,241, 10,
- 12,195,224,128,160, 94,112,152, 81,163, 65,245, 6, 64,136, 34, 80,208, 51,225, 63, 73,133, 66, 90,228, 85, 53, 78, 7, 88, 14,
-184,111,239,104,188,180, 40,238, 2,168,254,221,144,198,192, 57,214, 96,169, 64, 80,200,121,128,161, 88, 30,132,142,101,163, 42,
- 50, 31, 0,251,232,140,143,194,217,131,143,124,251, 36,177,102,168,167,209,122,241,240,131, 54,127,241,205, 63,187,109, 29,241,
-219, 18, 20,197,200, 28,168, 93, 42,159,249, 26, 95, 0,235, 55,148,107,157,235,242,172, 84, 25, 49,183,219, 0,203, 99,155, 75,
-105,149,241, 67,145,234, 92,207,146, 61, 8,148,135,119, 26,156, 44, 6, 11, 2, 77, 23,113, 95, 0, 12, 79,105,205,238,191, 24,
- 23,202, 71,175,167,198, 22, 15, 62, 4,244, 92,197,114, 46,138,172,228, 78,101, 52,167, 68, 36,204,169,171, 1,129, 75,164, 1,
-107,230,193,131,124,230,166, 6,163, 77, 77, 65,107, 13,159, 55, 64, 99, 93, 38,241, 19,214,202,241,149, 53,159,153,232,146,222,
-196,158,105,195,146, 17,135, 1,153,114, 10,162, 0, 37, 96,243,144,137,144,109, 48, 93,175,169,171,199,182, 80,173,133,147, 84,
-148,251,105, 14, 43,147,173,188, 14, 43, 59, 7, 75,127, 49, 28,107,215,204,174,227,189, 15, 32,177, 97,159, 10,133,254,127, 1,
- 72,186,150, 28,201,137, 40,104,231,207,118,217,174,234, 70, 93, 61, 51, 32, 90, 72,204, 6, 22, 12, 18,108,184, 15, 27,142,193,
- 93,184, 1, 39, 96,137, 88,194,102, 4, 66, 48,160,233, 30, 84,116,117,185, 92,118,254,156, 73,132,185, 64,165,203, 47, 51, 94,
- 68,250,189, 23,234,254, 48,220,158,167, 28,204,164, 22, 26, 95,101,126,155, 0, 96, 90,107,170,114, 48, 2, 47,199, 24,126, 3,
-247,156,239, 8, 26, 26, 45,180,167, 43,148,170, 53,100,176,145,224,146,122, 89,134,190,147,201,181,115, 83,250,171,102, 91,247,
-170,206,231, 25,187,153,135,103, 73,149, 98, 47,210,218,196,232,177, 93,156, 2,129,203, 72,184, 35, 0, 61,246, 29,195,142, 93,
- 91, 57, 68, 56, 44,235,232, 63,126, 80, 65, 6, 71,218, 58,149, 28,163,157,230,240,251,254,250,245,139,241,203,223, 14,113, 43,
- 78,177, 6,125, 2, 87,179, 42,251,192,193, 32, 23, 89,156,235,242, 60, 92,230,241,254,231,163, 77, 89,170,125,155,244,245, 93,
- 27, 62,249,112,247,233, 7,119,191, 62,232, 95,230,199,191, 12, 45, 86, 13,210, 18,100, 88,140,231,241,239,127,191,250,236,197,
- 79,175,110,127,252, 97,232,203,105,147,187,110, 1, 53,173,193,239, 61,152,164, 96,246, 96,239,181, 81,197,172, 88, 10,229, 88,
- 24, 73,147,137,169,120, 18, 56,238,121,132,232, 53, 32,173, 53, 27, 21,154,164,129, 20,157,190, 63, 29,190,251,254,143,111,239,
- 94,245,250,207, 81,152, 56, 38, 80, 26, 16,115, 78, 97,215,190, 40, 26,122, 21,147,182,176,136,136, 64,160,251,117,236, 43,150,
-173,161, 84,117,117,235,166,176,121,214, 64,203, 62,188, 61, 75, 22, 54, 6,185,122,137,207,216, 21, 58, 65,193, 64,219,123,226,
- 18,117, 4,212,223,121,204, 59, 73, 43, 34, 11, 45, 14, 16,246,185, 2, 35,206, 32,169,205,150,139,129, 47,114, 32, 57,118, 50,
-146, 87,171,242, 85,147,112, 40,109,210,189, 17,143, 45,131,179,241,177, 43,211,187,199,147,214,187, 47, 94,190,252,250,155,253,
-179,143, 14,197,252,230, 18, 64, 10,153, 78,192, 66, 18,117, 71,201,138,107, 67,231, 70,100,164,236,150, 18,120,184,184,114, 10,
-238,120,241,167,232,171, 56,189, 83,211,155,181,116,208,165, 33,228,244, 84, 52,187,205,243,143,183,226, 57,168,213,178, 32,219,
- 87,116, 87,205, 51,248,123,140,187,178, 60,132,252,143, 77, 86,151,201, 22, 19, 71,100,130, 20, 10, 11,184, 91,242,153,227,130,
-248,158, 50,237,160,145,251,120, 43,190, 7,118,232,203,124,132,100,242,199,119, 99,215, 53,253,123, 86,158,216,123, 42,162,105,
-101,120,194, 51,202, 2,112, 40,242,204,158, 77,215, 87,153, 5,136,156,219,219, 52,129,189,230,188,133, 23, 69,175,138,181,227,
-135,140,226, 74, 68, 49,164,163, 15,173,212,120,108, 54, 34,232,121,210, 27,177,208, 19,232,106, 98,205,251, 4,248,186, 38,246,
- 44, 10, 72, 15, 58,206,110, 77, 97,133,187,164,174,206,105,174,233,198,164,199,180,149, 53,226,236, 29,143,117, 31,216,220, 47,
- 56, 71, 32,120, 64,147, 3, 94, 97,145,230,255, 22,125, 22,200,164,232,251, 98,153, 32, 59,140,164, 57,156,137, 71,117,122,253,
-118, 18,195,196,246,128, 68,143,218,226, 40, 57,255,143, 19,195,216, 3, 76, 23, 31,186, 56, 60,136,253, 33, 29, 31, 31,199,155,
-243,245,231, 55,239,203, 10, 24, 33, 71,151, 54, 10, 79, 14, 42, 37,155,188,241,188, 58,226,101, 57,141,221, 5,180,120,194,143,
-180, 26,218,101, 24,140,159,112,138, 56,101, 18,171,204,129, 78,130,185, 2, 4,243, 30,124, 65,156, 0,186, 6,146, 67,238,172,
-209, 80, 50,218, 48,211,129,225,210, 38,140,195,157, 28, 80, 70,100,219,113,178, 66,151, 12,242, 4,155,192,240,238,214,182, 67,
-179,145, 72, 47,108, 59,204,113,211,136,121,225,157,233,226, 75, 40, 27, 64,106,147,121, 27, 81,173, 26,158, 85, 5,216, 94, 6,
-162,221,220, 8,121, 44, 89, 80, 60, 22,172,227,194,150, 74, 1,228, 37, 93, 6, 58,150,214,117, 81, 7,131,231,103,137, 39,254,
-171, 7, 84,233,208, 35,154, 44, 85,106, 98, 86,142,203, 94,202, 65,178, 92, 9,199, 24,202,210,202,170,214,213, 6,116,194, 41,
-193,249, 14,136,142,229, 32,183, 64,223,128,136,183,198,146,114,136, 35,232, 88, 11, 85,199, 15, 53, 30,113, 83,211, 50,155, 65,
-205,226,160,170,161,161,231, 89,230,119, 25, 68,193,229,190,107, 1,214,107,241, 91, 66,152,158,102, 99,122, 96,177, 4,189,209,
- 44,168, 64, 2,140,131,220,138,226, 98, 91, 97, 26,221,174,246, 81, 96, 88, 96,207, 14, 26,190, 88, 47,168,243, 52,145,117,213,
-160,209,121, 94,244,122,229,222, 86, 21, 68,161,106,133, 56, 21,233,105, 9,190,118,102,166, 43,166,219, 55,190,220,202,177, 26,
-107, 31,177,129,144,158,166,185,175,179,171, 3,132,217,201, 94,197, 14,140,206, 6, 78, 59,118, 41,196,255, 4, 32,233,106,118,
-228, 38,194,160,251,207,221,182,103,102,103,181, 67,164, 16, 17,130, 56,128,162,172, 68, 34, 14,192,129, 75, 30,131, 60, 29, 23,
-110, 60, 4, 87, 14, 92,208, 2, 17, 40, 2, 20,101, 66,118,119,102,199,158,177,187,221,221,166,202,121,128,217,245,140,187,191,
-175,170,187,190, 42,245,228,235, 39, 12, 97, 78, 52, 4,198,226,185,147, 21,213,112,146, 83,149, 99,152,147, 43,155,114,152, 22,
- 6, 0, 2,157,184, 60,103,179,229,112, 35,251, 38,218, 81,205,224,156, 74,148,189,170,148,141,246, 12,220,173,201,139,229,163,
- 47,196,207,254,245, 31, 99,181, 20, 6, 72, 34, 10,154,113,106,208, 23,173,107,222, 41,130, 75,153,177,120,111,162,239, 86,197,
- 28, 63, 77,137,212,184, 68, 63,152,243, 35, 19,202, 20, 96, 44, 54, 2,125,189, 58, 16,248, 1,196,177,108, 30,252,245,106,125,
- 76, 55, 22,168,106, 0, 34,233, 38,195,196, 67,160,170, 48,143,188,139, 80, 13,102, 48, 14, 47,206,203,253,233,245,245,171,171,
-237,175, 47,255,187,139,182, 89, 45, 63,168, 15,157,234,119, 99,197, 65, 70,242, 43,108,154,208, 86,235,248,248,203, 7, 87,191,
-171,119,219, 91,192, 18,170,124, 50,167,105,120, 63, 77,215, 16, 94, 8, 4, 77, 39,116,224,223, 76,131, 75,116,210,233, 72, 75,
-255,172, 59,192, 50,105,188, 68, 43,191,168,115, 79, 19,112, 48,201, 18, 96, 97,183,223, 94,222,255,116,179,222,246,109, 50, 11,
- 71, 1,163, 0,144,162,142, 86,197,227, 84,226,103,177,120,223,156, 64, 3, 12, 67, 93, 18,158, 40,118, 86, 73,208,205,113, 23,
-151,143, 63,250,247, 55,243,195,143, 63, 41, 0, 20,173, 5, 19,112,184,139,192, 34,162,157,227,213, 81,185, 12,143,205, 13,253,
-203, 4, 39, 90,231,165,182,152,101,112,180,119, 4,171,107,166, 3, 74, 74,169, 85, 27, 51,125, 4, 11, 2, 36,224, 8,124,137,
- 74,133,202, 27, 95,224,113, 26,192,227, 22,207, 17, 15, 97,243,252,219,203, 23,223,169,205,199,127, 78, 67, 55,244,116,191, 81,
- 76, 12,119, 20,223, 0,142,166, 57,247, 8,203,122, 64,135,153, 80, 16, 81, 87,243, 33,245,111,125,215, 38,191, 79,221,117,113,
-125,235,253, 48,208,111,254,200,161,235,212,139, 15, 63, 95, 62,124,118, 22,168,121, 6, 33,154,205, 10, 60, 79, 27,211, 62,199,
- 62,199, 22,117, 28, 59,143,237, 62, 94,235,116, 72, 98, 79, 15,211,204,172,202,130, 14,190, 53, 13,108, 64,154, 28,157,174,243,
-197, 39,103,195,195,167,255,108,143,231,188,196, 61,185,123,155,179,225,237,176,187,153,146,203,193, 76,179,168,137, 86, 47,120,
-246, 70,224,221,240,218, 26,176, 94,162,235, 99,117, 77, 26,101,132,158, 1, 5,239,245, 13, 51, 90,208, 85,243,170,216,124,118,
-249,203,155,120,183,123,183, 48,248,216, 40,129,199,123,107, 15, 1,197, 88,161,161, 19,241,161, 60,178, 76,166, 86, 5, 52,230,
- 80, 0,141,112, 20,182,125, 63,108,199,212, 1, 1,150, 59,210,125,213, 97,215,152,200,145,135,206,209, 1,222, 70, 9,144, 72,
-117,190,102,200,125,198, 70, 56, 81, 23,232, 59,105,208,239,179,197,159, 52, 52,151, 20,245,250, 98,188, 81, 87,223,255,189,239,
-246,183,178,187, 1, 42, 14,137,202,119, 5,248,163, 60,141,221,153, 88, 22,152,247,119, 36, 80,156,106, 43, 83,235,219, 55,222,
- 28, 85,243, 8,100, 89, 6, 32,190,164, 76, 71,166, 52, 1,173,119,101,159, 40,226, 1,160, 86,129, 78, 57,153,248,184,192, 46,
-169, 26,102, 43, 57,116,145, 41, 25,151, 74,188,231,193, 36, 46, 57,193,159,124,101,164,215,214,169,113, 53, 57, 20,133,181,116,
- 86, 59,160, 95,173,135, 21, 86,130, 48, 77,177,180, 5,227, 10, 74,169,128,195,129, 80,106, 10, 16, 52, 85, 61,133,176,156,174,
-226,201, 44, 5,251,108,162, 3,232, 46, 77, 1, 37,157, 35,152, 0,145,230, 60, 29,122,234,131, 37,148,104,197, 96, 0, 52,223,
- 23,142, 30,237,226, 92, 0,148,163,169,218,149, 11,174, 42,234,111,190,122,121,244,129, 6,166,149, 1, 48, 34,184,180,248,156,
- 9, 94, 27,236,190,146,211, 24, 26, 16,194, 68, 60, 33,170,143, 4,174, 46,106,169,232,183,137, 66,143, 95, 82, 80, 27, 79, 55,
- 86,135, 39, 91,226, 93,152,129,162, 4,146, 69, 59,161,173,240,212,202,213,156,101, 53, 6, 59, 38, 21, 23,188,198, 53,150,118,
-213,150,229, 72,211, 25,171, 4,187,155,142,204,134, 40, 79,137, 65,190,177, 28,153, 26, 5, 92, 63,187,232,161,130, 48, 8,152,
-103,200,104,167,102,170, 51, 35, 62, 82,148,193,245,150, 9, 95,224,148, 40,231, 89,232,138, 62,164, 32, 94,148, 72, 24,192,144,
-114,208, 62,219,158,129, 82, 28,198, 62, 44, 10,219,148,174,143,161, 28,141,162, 28, 32, 24,158,228,128,241,122,254, 39,203,251,
-226, 19, 47,169, 81, 11,141, 73, 3,123,136, 10,128,226,128,230,255, 11,192,209,213,243, 72, 78, 4,209,110,247,135,187,237,249,
-216,133, 97,225,238, 56,145,158, 78,128, 46, 67, 23,144, 19, 67, 64,192, 15, 37, 1,233, 50,180, 18, 34, 66, 32, 2,164, 61,193,
-125,104,197,126,141,199,118,183,221,238,230, 61, 39, 19,142,236,118,213,171, 87, 93, 85,175,212,243, 23, 79, 40, 33, 61, 30,195,
- 24, 8,101,112, 61,228,150, 35,144,135,123,102, 16,135,225, 62,101,158,145, 22,179, 0,237,248,179, 53,237,228,230,250,108, 82,
-237,182,228,157,204,114, 7,254,182,109, 9, 39,217,133, 20,157,187,120, 97,127,157,174,255,202,124,118,132, 41,224,251, 25, 50,
- 29,206, 68,155,150, 16,201, 45,106, 45, 1,178, 10,188,233, 38, 36,142,210, 6,149,241, 85, 50, 59,156,243, 58,222,185,220,107,
- 13,122,154,211, 16, 64,188,230,229,230,112,177,113,253,211, 63,222,191,113,220, 47,219,135, 99,233, 69, 28,122,206,163,216, 25,
- 41,113,176, 9, 4, 49,108, 29, 14, 14,111, 1, 38,236,156,205,253, 24,222, 92, 93,255,217,229,157, 62, 60,170, 79, 81,223,129,
-104, 35,126,224,148,164,149,253, 16, 14,159,181,155,253,147,171, 75, 57,142,111, 83,150, 72,101, 96,140, 28,208,167, 36,189, 16,
-155,165,186, 71,114,183, 14,175, 10, 68,193, 68,213,178, 74, 58,228,141,163,210, 30,116, 92,246, 76,218,245, 13,199,238,165,159,
-197,153,144,221,105,234,131,126,249,249, 33,159,254, 29,169, 51,200,211,174,192, 72,236, 86,204, 31,176, 51, 88, 78,148,100,169,
-121,200, 90,178, 98,196, 69, 26,136,201,253, 78, 10,111,141,171, 31,125,245,211,171,219,159,127,252,229, 99,229, 96,175, 6,166,
-153,121, 23,100, 24,126, 16, 35,157, 85, 32,212, 53, 69, 5, 98,109, 29, 11,164,182,161,115,216,197, 17,180, 28, 91, 32,141, 80,
-163,145, 94, 24,222, 55, 89, 69, 9,130, 86,114, 81, 75,209,205,158,136, 55,102,124, 70,110,155,154,194, 88, 54,159,126,255,221,
-179,111,127,152,221,254, 58,245, 57,142,156,149,205, 84, 83,129, 47, 38,118,254, 23,197,169, 74,209, 83,214, 23, 12, 25, 33,246,
- 8,116, 14,199, 35, 87, 18,158,114, 57,190,159,198,119, 48,129,201,198,210,245,235,152,117, 41,174,241, 95,126,179,207, 7, 0,
-123, 96,204,140,178,132,138,107,219,145,103,222,195, 81,211,114, 76,120, 72,182,202, 28, 87, 6,175,216,225,193, 93,145,221, 68,
-173,174,196,174,127,182,236, 43,155, 63, 42,217,228, 79, 30, 63, 61, 61,253,240,245,213,184,241, 49, 14, 85,152,218,115,144,136,
-127,222, 2, 67,225,178,234, 36,214,114,143,230,150,205,140, 55, 79,222, 86,129, 89,171,144,134,125,138,136, 28,212,157, 33,244,
-150,181, 43, 71, 24, 87,165, 70, 60,254,226,249,101, 23,195,205,157,228,236,103,233,136,159,224, 23,170, 3, 46, 40,142, 52, 46,
- 99, 65, 54, 66, 65,248, 18, 31, 4, 23,132,129, 40,176,111,206,234,211,166,233, 51, 88,156,150,136,163, 0,110, 17,166,117, 4,
- 7, 46, 40, 44, 80,203, 50,125, 69,212,165,211, 42,195,226,116,138,229, 78,219,102,182,205,170, 79, 95,150, 98, 1, 60,153,130,
-194,187,250,247, 87,175, 47,127,123,119,189,139, 83,179,221, 55,245,193, 89,208, 79,227, 77, 93,193,108,135,179, 6,201, 20, 69,
- 5, 43,202, 65,172,225, 11,216,138,132, 34,255,215,119,247,183,211,118, 99,155,139, 86,236,117, 92,202,137,210,210, 84, 51, 17,
- 30,238,149, 7, 94,108,202, 62,138,187,129, 53, 77, 98,154,134, 33, 38,239, 23,187,173,184,155,154, 58, 36,114,168, 53,178,181,
-236, 68,179,103,127, 73, 65,230,217,122,110,254,145,203,198, 58,189,171,244, 86,249, 26, 54,106, 54, 13,143,185,178, 20,161, 89,
-216,152,165,212,134, 67, 23, 44,252,207, 28,113,187, 77,196, 60,239, 53,220,198,151, 60,232, 98,152,100,209, 32,117, 86,147,224,
-174, 41,120, 70,128,169, 37,217, 33,223,148,101,241,107,105,128,237, 75,236,195, 69,178, 56, 88, 96,111,217,138,178,251,250,229,
-223,203,109,101,149, 77, 66, 52,161,112, 20, 34, 9,208, 66,208, 30, 22, 97, 39,141,255,227,230, 31,117,134,143,239,144,110,206,
-218, 81, 25, 3, 70, 48,109,252, 94,174,219,211, 97, 34, 14,244,162, 97, 15,154, 2,182, 78,197,196, 26, 81, 63,229,181,138,205,
-169, 18, 82,191, 46,184, 84,157, 87, 29,203,125,245,152,189, 63,207,125, 61, 45, 75, 50,193,167,216,198,130, 40, 8,100,228, 62,
- 16, 13,122,226, 1, 66, 15, 61, 39,244,193,255,121, 15,168, 77,238,102, 10,148,214,180,147, 42,140, 83,239,178,240,197, 62, 36,
-199,185,177,106,193, 41,101, 13,150,161,220,172,225,131,165,138, 56, 57,223,222, 3, 89,170,185,201,202, 71,139,136,217, 82, 58,
-222, 34, 27, 53,149,167, 6, 49,171,225,130,221, 98,164, 45,160,110, 19,165, 82,149, 52, 17,159,135,101, 11, 61, 15,158,130, 67,
- 38,254, 47, 0, 75, 87,206,227, 72, 17, 70,171,235,236,234,195, 51, 54, 94, 45,247,106,119, 69,194, 34, 33, 96, 67, 18, 16, 18,
- 33, 25,255,137,152,127, 68,184, 17, 36, 28, 2, 1, 2, 33,134, 25,118, 60, 30,183,187,203,213,213, 85,188,103,145, 56,242,213,
- 85,223,241,222,119,170,103, 31,190,183,224,200, 19,172,214, 57, 34,104,166, 56,225,139,205,162,113,131, 67, 58, 0,250,169, 46,
-207,149, 7,118,130, 24,107, 87, 4,109,141,181, 14, 70,102,194, 85, 71, 54,162, 93, 38,117, 4, 7, 84,198,142,182,228,157,126,
-251,221,254, 59,125,255, 67,152,186,202,185,180,201, 28,198,205,104, 22,132,183, 97, 77, 1,157, 77, 3, 45,231,194, 97,213,114,
- 51, 17,174,115,174, 89, 24, 3,237, 79,227, 57,215, 90,177, 26, 65,213,101, 60,204,233, 80,205,112, 66,167, 74, 12, 23,253,227,
-159,126, 86, 99,186,177, 12,227, 0, 77,203, 20, 64,194, 98, 9, 5,212,120,156,211, 0,187,112, 61,134,104,102, 14,240,193, 49,
-225,242, 96,228,171,227, 52,254, 54,202,135,175,117,155,114, 0, 93,176,214,179,239,207,177, 33, 21, 98,248,228,125,167,242,250,
-219, 95,231,121, 60,116,145,101,220, 44,195,149, 38,198,124, 80,165,211,242, 20, 88,179,197,125,106,156, 81,205,118,205, 14,128,
-187,101,236, 29,222,218,197,153, 91,106,116,218, 86, 50,176,145,129,184,255,247,187,155,199,111, 60,127,244,142,153,110,246,113,
-250, 63,187,155, 97,172,106, 89,215, 16, 14,144, 49,144, 69,142, 58,101, 58, 9,204,230,212,148,113,189,196,173,171, 69,255,106,
- 39, 38,247,213,215,223,252,249,215, 31,189,135,234,114, 78, 11, 36,103, 1,113, 17,204,190, 10, 11,100,194, 30, 58, 93,184, 68,
- 28, 0, 69,130,238,209,164,176, 25, 36,192, 69,193,170,140, 73,247,248,243,106, 13,231,104, 56,178, 2,178,217, 24,110, 47,113,
- 35,215,134,194,210,179,179, 77,198, 97,111, 31,173,159,126,241,229,235,159,124,206, 49,144,167,251,145,169, 60, 54, 98, 50, 22,
-202, 78, 33,224, 5,217, 48, 30, 10,227,158, 34, 23,228,225, 20,247, 75,126, 57,132,251,124,248,183,220, 93,205,183,135, 57, 92,
-133,229,192,169,118, 0,227,148,104, 2, 70,249,244,249,131,205, 71,102, 30,241, 75, 21,168, 10,174, 27,236, 28,228,113,222,225,
-240,217,161,191, 28,171,116,171,228,158,241,226, 24,240, 22, 22,175,164, 56,151,129,185, 24, 6,203, 93,225,204, 23,136, 50,136,
- 89,159, 94,249,224,217,174,221,236,174,255, 54, 93, 5,119, 62,233,233,205,246, 97,190,254,241,172,121,198, 28, 11,132, 13, 12,
- 20,230, 8,160,112,196,111, 53,210,177, 60, 81, 51, 69,141,231,176,145,213,167,128,181,172, 47, 23,236,221, 80,149,104,203,147,
-143,223,122,113, 51,221, 93,133,220,230, 19,216,124,204, 58,229, 29,164, 22,103,113, 44,199,196,176,131,231,162,136,243,246,205,
-204,142, 60,186,139,162,134,120, 42, 3,160,114, 16, 45,131, 18, 66,194,221, 66,189, 57,102, 85,231, 6,162, 9,210, 45, 85,103,
-207, 99, 35,133, 57, 39, 66,228, 26, 28,213,177, 74, 52,152, 2,230,226,202, 2,107, 6,163,157,149,219,148,229,246,159,239, 95,
-200,226,155,149,119,160, 89,179, 2,189,247,186, 61,109,237,198, 74,237, 53, 64,180,109, 21, 94,151,149,173, 60,140, 31,172,155,
-246,181,106, 13,231, 44,191,220,143,129, 99,178,218,166, 54, 77, 51,184, 89,178,158,185, 1,212,181,170,245,231,189, 22,194,121,
-189,138,224, 27,203, 50,115,225,145,128,170,148,154, 97,154,154,147,210, 59, 7, 59,187,120,111,241,145,220,131,111, 47, 62, 86,
- 44,117,185,112, 30, 86, 68, 85,173,101,127,178,243,157,102, 14, 78, 47,189,181, 15,250,203,185,164, 30,150, 65,246, 89,199,181,
- 50,222,234, 89,110, 91, 9,131, 31,172, 56,193, 24, 3, 45, 3,201, 16,236,112, 68,178, 72, 34, 44,165,131,254, 36, 46, 98,186,
-100,140,134,139, 81, 45,190, 51,149, 0,142,162, 43,119,166, 25,138,179,194, 83,179, 45,237,103,159,254,146,201, 10,147,209, 86,
-183, 42,136, 99,236, 32,240,209,227, 81,156, 49, 16,255,106, 4,178,169,129,156, 43,230,148,115, 49,222,129,187,233,104,210,160,
-224, 62,143,181,240,135, 52, 36, 91, 92,119,161,125, 2,130,224,124, 19, 51,153, 64,169,163, 86, 85,204,126,205, 85,176,217,224,
- 46, 50,148,106, 85,171, 4,162, 9,237, 63, 41, 63,202, 12,124,214,223,175,240, 55, 23,240, 49,142,253,101,106, 81,152, 38,170,
-177,224, 14, 0, 8, 12,199,156, 0,143, 21,184, 59,107,164, 62,181, 56,152,212, 48, 23,212,223,141,209,104,138, 2, 35,157,112,
-189,192, 16,130, 45,200, 9,188, 78,170, 70,135, 18,227, 22,174, 87,250, 4,121, 90, 41, 49,136,253, 17,119,156, 47,162, 97,117,
-156,190, 47,167, 62,216,138, 51,189, 21, 0, 46,252, 82, 85,119, 64,118,120, 96,198,179, 74, 4,201,181, 71,235,210,127, 2,112,
-116,245,188,149, 19, 81,212,158,111,127,189, 36, 47,129,149, 0, 45, 97,217, 93, 9,241, 41, 10, 68, 71, 77, 69, 71,203,239,161,
-231,183, 80, 64, 65,129, 4, 13,116, 43,173,132, 68,131, 86,187,218, 77,148,151,247, 97,123,236,241,204,112,142,165,116,137, 95,
-252,198,215,247,158, 51,115,238,185,242,195, 79, 63, 24,103,159,194, 17, 40, 58, 82, 82, 80,136,157, 18,106, 12,133, 6,178, 68,
- 13,104,106, 80,133,142, 38,202, 96,184, 26,220,132,210, 33, 82,167,177,242,172,115,224,108,182,172, 27, 51, 0,208,102,132,193,
- 58,159,170,249,232,108,184,218,255, 57, 85,160,116,136,118,133,250,158, 74,185,128, 3, 49, 3, 33,187, 86, 74, 84,162, 26, 35,
- 91,159,217, 14, 82,224, 34, 65,145, 51,150, 38,241, 0, 24,181,216, 75, 57,202, 60, 0, 28,166,128,156, 50, 34,231,130,185, 92,
-180, 23,125,120,250,207,235, 87,205,137, 77, 90, 72, 8,121, 58,249,212, 87,130,214, 77,225,128,162,188,243,110,158,177, 8, 52,
-237, 11, 52,112, 4, 25,112, 30, 0,252,118,127,146, 23,246, 73, 7,132,112,135, 10, 85, 80,186,106,139,128,213,201,210,249,199,
- 95, 61, 48,250,189,191,254,184,149,242,128,213,222, 32,167, 80,108, 26,151, 94, 86,154,195,148,218,161, 4,181, 21,156,190, 84,
-104,195, 35,246, 24,220,236, 57,251,124,212, 52,182,155, 57,126, 90,173,191, 80, 8,227,251, 52, 62,127,209,127,242,244,225, 3,
-243, 38, 13, 35,114, 37,237, 34,253,213, 60,212, 51,181, 8,109,158,187, 60,215, 57,111,203,227,166, 8, 58,203,173,170, 42,189,
- 41,218, 77, 91, 52,239,255,248,211,175, 63,255,242,247,101,109, 76,195,118,102, 10, 40,215, 35,119, 73, 87,127, 58,138,197,168,
-104, 29, 12, 72, 77,135, 51,154,127,101,201, 3,214,181, 71, 90,182, 77,215,224,161, 86, 25,223,197,163, 34,213,114, 83,187, 3,
-112,142, 1,173, 50,231,141, 65,186, 46,242, 82, 34, 56,178,125,120,249,228,251, 31,222,254,242,235,187, 98,185, 29,119,107, 32,
-179, 71, 26, 4,103,230, 43,146,215,161,118,130, 13, 28,233,144, 69, 47,196,110, 94,142,249,212, 79,135,125, 26,222,164,253,237,
-105,216, 77,243,235,197, 14,130,138,238, 25,224,155, 86,137, 55, 62, 92,191,219,124,246,221, 69,180,235,134,119, 47, 57,206, 36,
- 80, 57, 71, 19,154,133,135,186, 97, 34, 65,184,239, 3,199,251,121,217, 31,121,248,146,123, 29,246, 83,244,132,182,124, 75, 5,
-219,145,116, 39, 65,116,177, 62,221,231,143,158,253,247,168,188,221, 1, 20, 3,241, 76, 19,170,241,213, 37,242,235,233,134,174,
-203,220,251, 90,237,111,150,164, 58,165, 70,192,168, 60,209, 76, 15,185, 69,208,126, 1, 37, 18, 89, 56, 41,231,104,159,180,170,
-182, 17,106,233,250,139,143,127,123,117, 58,254,123, 15, 62, 62, 28, 56,121, 41,172,134, 96, 27, 54, 96,209, 28,124,154,114,177,
-224,222,229,139, 80,130,212,131,101,115, 64, 0,248, 56, 5,236, 14, 81, 78, 55,202,160,184, 65, 78,157, 24,191, 7, 13, 49,138,
-200, 53,198,149, 20, 85, 83, 47, 89,217, 64,165,154,212,107,119,219,121,153, 90, 77,201,107, 88,135, 19,240,108, 76,109,175,227,
-179,223, 23,240,133,179,234, 16, 35,245,195,134, 78, 70,116,220, 68,142, 82,180,110,195,221,145,172, 3, 80, 79,201,101,246,206,
-138,174, 4, 42,212,132,235, 98, 56,250,229,165,175, 93,123,177,109, 99,109, 15,248,199, 14,140, 81, 0,116,211,159,131,104, 23,
- 75, 36, 22, 96,156, 82,107, 44,131, 51,156,231,200, 86,171,164, 57, 49, 13,145, 1,236, 21, 2,126, 38,110, 71, 43,246, 16, 41,
-223, 85,192, 18, 20,100,187, 82, 32, 1, 57, 64, 11,142, 2, 94, 42, 32, 22, 73,159, 91, 41, 84,139,187, 83,160,169, 29,251, 44,
-241, 7,248,116, 20,157,180,172, 55,205, 10,237, 75, 42,210, 1,228, 81,240,144,138, 67,238,217, 61,187,172,186, 22,101,129,112,
- 65,139, 85, 4, 43,208, 68,199,244, 54,168, 77,185, 1, 45,125, 39,155,111,190,125,222,123,235, 65, 3,115,243, 22,214, 11,192,
-233,204,218, 0,110, 55,137,109,231,112,229, 89, 11, 14, 77,223, 5, 59,157,251,113, 52,165,159,241, 62, 46, 22, 60, 3, 5,105,
- 84,170,106,172,181, 60, 83,234, 45,158,176, 19, 83, 24,185,125, 87, 90, 51,210,250,198, 34,111,224,209, 9,225,240, 74,242, 80,
-254,102, 44,235,168,140, 1,122,112, 10, 44, 57,177, 37,183,167,133,135, 1, 50, 81,192, 72, 14,224,186,239,138,211, 76,171,234,
-140,196,165,163, 17, 20,249,212, 86, 73,178,196,120, 98,247, 56, 5, 96,180,242,163, 25,156, 1, 95, 1,105,209, 11,176,155, 86,
-173,138, 8,206,184, 87,103,190,154, 98, 28,102,233, 0,140,138,250,142,214,123, 81,140, 8,127,220,182,236,121,114, 84, 46, 78,
-226, 73, 2, 4, 81, 18,153, 76, 91,206,193,198, 98, 80,137,115, 70,144, 1,198, 52,111,253, 38, 0, 57,138,255, 5, 96,233, 90,
-118,220,168,162, 96,223,103,191,236, 25, 39,195,136, 40,128, 34, 2,132,217, 13, 18,130, 85, 62,130, 95, 96,195,191,176,229, 87,
-216,178,224, 19, 88, 32,129, 88, 64,120, 68, 1,194,216, 99,247,243,190,169, 50,108, 70,150, 70,182,102,218,183, 79, 85,157, 62,
-167, 74,221,124,112, 35,244,146, 34, 83, 67, 32,103,220, 62,244, 16, 41, 59, 19,241, 49, 35, 35,217, 42,111, 6, 93,117,154, 45,
- 6, 91,218, 62, 61,152,116, 78, 53, 94, 78,177,206, 12,142,178,233,255, 52, 60,250,177,144,120,187, 21, 24,246,228,253,237, 79,
-131,163, 39,140,140, 62,181, 84,112,168,149,194, 52,213, 18, 56, 13,142,139, 77, 83,126,205,236,170,115,244, 13, 40, 5, 10, 67,
- 36, 36,181, 41,120,128,150, 98,218, 37, 55,108,170,236,202, 10,128, 4,109, 45, 40,255, 87,143, 62,252,241,229,228,150,215, 76,
-156,179,177, 46,241,126,174, 28,110,102,112,116,151,173,114, 80, 1, 41, 46,110, 77, 29, 32, 20, 50, 17,239,142, 78,179, 75,162,
- 81,248,223,126,231,234,194,188, 98,184,157, 97, 39, 84,158,167, 85,150, 20, 90, 91,110,110,175,167,120,245,203,207,227, 28, 78,
-248, 50,106, 14, 60, 50, 6,103,145,132,151, 60,134,206,112,132,100, 57,111, 6,137,115, 22, 83,236,148, 25, 1,191, 40,186,165,
-173, 64, 6,139, 53,144,185, 28,184, 6, 21, 27,126,251,103, 83, 63,254,232,221,116, 28, 15,108,228,199,182, 50, 23,166,118,149,
- 7,127,230,227, 66, 17,112,116, 78,202,238, 68,219,227, 96,163,218,109,223,220, 85,215,111,124,243,245,139, 47,191,250, 86, 67,
-184, 53,245, 28,113, 71, 37,177,114,253,160,165,149, 10,106, 1,138,186,132,238,148,131,224,222, 59,138,190,139,182, 54,165,212,
-114, 99, 84,106,128,199,156,188,228,163,175,200, 89, 31, 72, 79, 25,244, 12,114,144, 30,154,144, 22,112,168,156, 34, 78,119,202,
-177,253,228,246,233,231, 95, 92, 62,126,250, 58,207,211, 58, 14,124,160,194,248,180, 66,107,218,204, 30, 18, 80,137,230, 69,147,
-103,115,116, 9,226,148, 6, 80,214,191,214,245,222,159,238,146,127,185,220,237,227,130,170, 61,148,112,160,223, 58, 61,120, 93,
-153,238, 51,228,198,237,103,143,244,179,102,217, 51, 40,146, 17, 6,160,106,171,230,188,234, 24,195,169, 44, 71,229,142,142,129,
- 73, 3, 74, 55,192, 36,151, 49,104,151, 5,103,157, 32, 82, 42,235,217,243,192,149, 5,226,104,206, 68,132,166,223, 92, 63,127,
-246,253,159,162, 94, 15,126,231,213, 94, 76,227,188, 23,213, 91, 93, 35, 79, 47, 24, 37,195,230, 0, 53, 63,219, 39,182,184, 16,
-228, 70,113,224, 50,113,205,254, 60, 57,131, 98, 7,206, 7,248, 80,124, 20, 93,101,142, 18,109,203,147, 79,223,251,110,175,238,
-254,248, 59,119,245, 4, 30, 35, 36,243,136, 35,243, 5,124, 72,109,133, 51, 68,235,127,197, 7,170,142,107,236, 22, 44, 20,132,
-151,157, 78,177,230, 92,210,188,177,233,152, 77, 71, 39, 17, 46, 73, 17,101, 32, 71, 20,153,112,101, 26,229,136,148,174,158,234,
- 30,191,132, 50,106,192, 9,140,175,171,131,212,228,152, 1,167,142, 22, 98,139,234,182,102,218,175,191,254, 32, 87,217, 41,117,
-238,115, 43,215,218, 11,160,121,109,101,160,209,239,194,157, 23,208, 38,136,252,226, 90,148, 51,102,241,246,208,108, 70,109, 58,
-177,217, 41, 92,187, 33, 12,199,123,185,233, 54, 23,178,132, 41, 49,140, 22, 98, 5,127,118, 27,193,125,232,151, 2,113,210,100,
-111,115,235, 3, 39,180,104, 88,153, 23,145,154,149, 98,101, 89, 37, 84, 2, 74,156, 92, 46,241,179, 40,253, 32,187, 13, 16,175,
-166,249, 67, 17,231,244, 82,167,243,140,195,182,172, 28,106, 22, 38, 50, 4,217, 15, 41, 28,203, 58, 75, 46,212, 79,184,234,185,
-112,158,137, 29,119,147,240,141,148, 19,148,139,103,122,177,107, 98, 23, 68,160, 23,145, 60, 9,112,240,170,213, 76,233, 38,252,
- 84, 18, 58,108,205, 28,253,174, 54,217,246,241,250, 82,248,143,159,255, 62, 29, 0, 0,166, 94,109, 35,135,172,112,219, 86,148,
- 33,184,132,156,205,135,112, 44,217, 29,113,199,132,198, 53,171,216,245, 32,222,117,218,128, 43, 67,114,133,206, 71,223,204, 75,
-106, 65,226, 0,187, 41, 51,220, 8, 34,162,105, 41,215,229,216,156, 69,218, 98,255, 11,222,177, 65,163,186,250,214, 74,102, 15,
-175,163,247,238,172, 42, 26, 58,122,113,217,219, 65,255, 63,164, 73, 69, 69,163,156,237, 97,214,189, 13, 92,137, 18, 49,157,214,
-228, 25,159, 93, 53, 58,117,142,105,174, 76,246, 27,129, 18, 90, 0, 85,232, 73,103,141,219,154, 21, 24, 19,125,161,127, 27,123,
- 82, 37, 91,103, 26,203,211, 47,189,140,186,103, 87,223,131, 38,119, 90,207,237,177, 7,224,204, 80,167,248,127,185,212,186, 58,
- 40,182, 18,130, 77,166,245,106,108, 43, 10, 76,207, 53, 78,167,103,213,255, 43, 0, 73,215,210, 35, 55, 17, 6,251,237,182, 61,
-227,157, 29,178,188,130, 86,136, 72, 81,148, 8, 65, 14, 68,156, 64, 92,184,195,127,226, 47,112, 65,252, 25, 14, 28, 56,112,136,
-114, 34, 18, 18,145, 86, 65,100, 39, 59,227,241,187,221,110,170,156, 57,174, 70, 94,123,218,253,125, 85,221, 93, 85,250,179,207,
- 31,152, 1,163,161,136,157,178, 97,137, 97,217,104,208,222, 66,246,238, 78,133,202,154,162,223, 58,225,181,159,193, 98,150,129,
-107,229, 34,149, 41,183, 99, 47,250,114,246,115,201,163,129,168, 35, 33,130, 99,186,192,128,141,208,188,154,223,123,242,129,216,
-212,127,140, 92,152,203,168, 9,215,152, 93,206,102, 25,149,245, 32, 65,121, 6, 2, 79,109, 67,168, 36,109,113, 70,181,122,161,
- 99,230,209, 31, 64,155,140, 27,100, 77, 56,142,163, 94,215, 11, 25,188, 7,226,142, 54,127,184,119,149,159,199,123, 47, 95,222,
-200,165,195,187, 58,235, 64, 91,245, 16,139, 91,202,161,222,248, 16,142,134, 11,142,104,175, 96, 42, 11, 67,194, 21,173, 31, 1,
-218,116, 87,119,163,187,120,122,159,251,167,201, 22,171, 40,141,118,120,104,166, 93, 51,150,149,126,252,116, 63,134,203,191,158,
-191,213, 83,167, 28,232, 98,220,208, 31, 35, 83,148, 11,208,125, 46,120,181,171, 0, 44,185, 55,239, 0,160,128, 89,102, 9,132,
- 45,141, 73, 62,241,192,108,112, 70,219,247, 23, 87, 88,193,228,208,173,250,254,241,195,126,250,123, 62,250, 4,122, 71,191,151,
- 45, 6,211,105,188, 34,103, 92,198,232,171, 8, 30,132, 90, 36,213,246,209,181,168,231, 95,126,254,243,167, 95,127, 27,155,186,
- 42, 93, 81, 90,122,213,208, 68,148, 78, 6,173, 3,126,203, 2,117, 14,178, 96,173,154,251,157,246,218,166,204, 43, 14, 19,238,
-139,251, 63,206,169,141, 23, 0,106, 78,131,248,199,204, 91, 93,224, 69, 64, 63,246,106, 49,237,209,184, 44, 12,221,152,178,203,
-111,158,125,250,227, 15, 50,223,191,166,174,167, 15,224,110, 73,173,169, 98,171,196, 86,224,233,129, 84,231, 86,160, 31,213, 82,
-189, 17, 75, 55,163,184,157,111,194,249,144, 78,205, 92,255, 23,250,195,178,212,179,155, 88, 47,152,165,129,145, 43,228,216,241,
-220,203,179,239,174,238,127,187, 11,117, 75,171,194,119,232,147, 41,106,138,231, 51, 90,138,194, 65,142, 1,179,167, 70, 45,248,
- 10,166,242,173,180,253,140, 33, 7, 85,232,198, 40, 91, 10, 27, 79,158, 90, 4, 89,218, 37,215, 41,159, 54,159, 92,150, 95, 60,
-122,254,207,191,178, 65,129, 70, 75, 59,191,179, 27,250,104, 87, 85,243,177,105,106, 77,183, 78,214,148,213,169, 13,117,145,126,
-181,248,228,120, 14,186, 97,172, 46, 99,137,134, 17,160, 59, 22,236, 91,160, 69, 50,118,241,250,203, 7,191,223,164,219, 87,199,
- 34, 19, 20, 3,246, 83, 59,209, 10, 13, 52,227,108, 64,177,117,125, 98, 28, 1, 61, 48,102,131, 73,209, 9, 87,212, 33, 96, 62,
-117, 52,235,232,134, 9,220,192,214,242,194, 83, 58,150, 6, 31,232,224,108,243, 25,184, 47, 29,103,157, 11,121,148, 10, 93,216,
-173,118,204,104, 51,168,173, 34, 21, 92, 68,226,126,255,104, 23, 48,116,235,104, 67,155,235,143,175, 14, 47, 94, 52,167,163, 40,
-183, 40,201, 75, 63,177, 46,132,166, 19, 83, 1, 54,156,171, 62, 67, 45,145, 3, 73,175, 88, 83, 47, 84, 7,116,100,151,209,165,
- 53, 51, 37, 99, 55, 50,170, 62,140,175, 79,253,222,138,203, 15, 55,174,146, 53, 26, 68,160,146,142,180,218, 59,134,159, 2,154,
-180, 64, 80,146,241,139,192,106,139, 66, 45,218,181,140,174, 49,128,222,192,242, 41,228,105,212,151, 11,110,143, 90, 95, 77,219,
-169, 41,166,183, 52, 87, 76, 57, 90, 71,204, 6,112,251, 20,134,140,155, 36, 0, 56,105, 13,182, 23,185,117, 18,247,196,147, 70,
-174,101,255,142,126, 10,147, 42, 35,115, 60,125,152, 81,205, 35,151, 95,104,246,105, 11,246,167,130,135,251, 5,152,245, 78, 38,
-111,196,222, 11,220,115, 5, 32,207,192,247,233,226,122,223,125,245,245,225,238,176,248, 77,191,173, 84, 43,131,181,161,200, 24,
-129,108, 82, 89,134, 59,185, 71,101, 44,116, 48,219, 50,103,150,138, 44,245,160,186, 40, 50,115, 2,252, 49, 92,141,116, 6,160,
-116,202,108,169,163, 43, 65,183, 24,255,138,114, 46, 47,206,237,128,135, 85,222,197,206,152,161,152, 65, 59, 38,193,227, 33,184,
- 82,164,239, 69, 26,139,205, 5,254,160,122, 16, 2, 48, 29,234,183, 99,180, 11, 70, 56,226,119, 2, 30,114,137,201,186,142, 27,
-203,196,227, 21,222, 46,103,128, 31, 38,158,221, 82, 43,131, 20,244, 23,176, 67, 68,255, 26,197, 6,212, 73,250, 35,173, 81,134,
- 82, 68, 89,216, 86, 79, 3,165, 66, 1, 48,133,122,147,133, 39, 69,120,236, 87,182,248, 93,106,252, 71,174,203, 36,102, 40,176,
-194,141,116, 88,226,158, 60, 55,182,168, 71,213, 38,164,158,176, 77,153, 28, 23,249, 95, 0,146,174,100, 71,142, 34, 10,230, 82,
-153,181, 79,143,105, 11,204,176,140,192,178,198, 39, 16,134, 3,103, 14, 72, 92,144, 63, 10,241, 9,252, 3,223,192,145, 11, 7,
- 14, 28, 65, 66, 26,143, 44, 25,188,140,167,183, 90,114,171, 36,162, 56,182,212,234, 37,235,229,123, 17,153,241,226,233, 79, 30,
-126, 60, 78, 5,117, 1,216,153,170,143,162,201,148,106,204,120,171,194,111,170,101,137,172, 59, 81,152, 91,113,229, 41,203,139,
- 85, 98,179,245,202,188, 76,235,242, 33, 36,218,161, 0,166,175,246,210, 20, 85,251, 55, 83,216,118,151, 87, 31, 60, 27,194,107,
- 41, 26,224, 65,100,220,140,140, 6,246,202,171, 68, 83, 88,154,168,101,219,164,136, 7,235, 75, 77,243, 16, 21,107,122, 80,200,
-163,217, 0,223,143,116,237, 61,142,113,113,102,224, 24,120, 16, 60,181,148,116, 56, 92,244,118,123,121,115,187, 92, 31,144,110,
-217, 6,199, 27, 92, 73,169,148, 67,224, 88,222,218, 72,172,224, 8,112,228,114,208, 84, 10,181,120, 24, 94,123,112, 1,113,123,
- 23, 31,127,138,250,123,160,144,161,162,202,128,205, 10,138, 62,149, 49,198,238, 92,125,246,228,193, 97,232,255,250, 19, 5,248,
-100, 1, 93, 83, 5,132, 89, 24,160, 74,196,186, 28,108, 2,192,117,158,151, 97, 11,199,108, 88, 14, 98, 71, 70, 97, 71,149, 98,
- 54,193,234,227,137, 38, 14, 95,137,251,248,218,155,111,159,244,170,248,125,220,151, 17, 57, 60, 13,153, 52,158,134, 31,153,206,
-103,247, 68,168,155,210,119,143, 74,123,190,121,243,183,253,225,199, 95,126,250,249, 87, 29,210,253,190,227,201, 22,221,114,104,
-104,192,251,105,205,203,102, 41,129,233,216, 27,224,193,239, 51, 39, 33,129,164,207,181, 86, 30,128,199, 32, 74, 40,247,107,120,
- 64,132,224,235,207, 69,141, 5, 86, 77, 63,206,177, 13,148,215, 52,194,141,146,195,208,139,139,167,223, 92,124,247,212,235,246,
-165,199, 58, 3,144,209, 71,196,112,192,123,142,235,240, 58,210,244,101, 24,197,108,241,225,242,224,231,183,241,180, 11,195,237,
-184,163, 78, 38,228,231,211,238, 69,206,195,194, 97,246, 71,149,157,164, 41, 86, 91,248,183, 97,220,165,143, 62,239, 30,125,127,
- 14,188, 19, 29, 59,117, 41, 12,167,111, 98, 49,239, 67,160,133, 92, 76,167, 28,239,226, 2, 32,204,171,125,228,119, 84, 71,229,
-240, 89,222,158, 50, 29,157,204,234, 84,148,105,136, 38, 56, 54,158,253, 92,241,189,139,251,195,251, 95,220, 60,251, 23,228,221,
-197,108,204,236,130,189, 29, 80, 6,196,135,221,166,206,175,176,244, 41, 24,181,165, 31,172,112,171,141, 61, 32, 52,181, 43,192,
-137, 88, 31, 10,144,104,134, 12,190,213,229,241, 4,190, 65, 25,165,176,249,242,171,135,191, 13,238,250,143,157,162,241,147,125,
- 7,113,137, 76,188,158,201, 84, 33, 17,197,100,108,108,206,240,221, 87,190,202,203, 56,217,136, 29,134,112, 75,190,234,228, 12,
- 86,239, 0, 25, 16,101,200, 6,101,147, 5,112,252,177,149, 60,240, 0, 69,163, 35,146, 1, 21,167,207, 27,208,150,192,191, 74,
- 40,219, 97, 92,163, 79,232, 14,241,111,128,243, 26,188, 51,205,135,114,251,110, 57, 9,247,234, 58, 78, 81,183,109,145,131,202,
- 38, 55,253, 82,177,135, 5, 97, 92, 7,187,241,200,212,133,228,177, 61,184, 81, 89, 98, 65,172, 72,228,242, 84,177,246, 74, 86,
-133, 42,123,124,103,124,113, 55,236, 7,125,222,169,134,202,248,194,103, 23,207,212, 82,161,232, 90, 14,239,181,246,100, 36,229,
-235,199, 68, 23, 49,187, 90,224,219, 72,199,137,227,178,146, 28, 57, 87, 68,217,108, 1,167,146,160, 0, 87,231, 49,224, 28,104,
- 91,230, 22, 95,112, 58, 32,167, 98, 2,176,209,125, 45, 24,142,184, 98, 27,157,152,144,206,217,255, 67,192,143,151, 75,225, 23,
-198, 26,202,236,248,255,148, 0, 35,122,150, 21, 16, 69, 84, 4,177,202,221, 5,162,116,212,248,229,170,168,144,206,120, 85,116,
-102,211,131,175,175,110,174,190,252,199, 13,141, 61,218,136, 71,105,102,172,164,177,101, 84,128, 75,171,109, 58, 50, 1, 89, 43,
-130,223,199,145,102,143,203,166, 76,181,172,121,237, 10,226,162, 81, 16,192, 28,194,136, 63, 53,129, 67,184, 38,201,131,180,155,
- 4,162, 86,225,123,219,198, 35,238,176,129,129,217,216,101, 41, 35,208, 58,136, 25, 61, 1, 39,158, 45,215,197, 60,226, 17, 12,
- 98, 29,163,206, 22,231, 83, 14,227, 20, 80, 70, 68, 1,170,204, 67, 71,202,133,167, 46,154,182, 70, 70, 71, 57, 0,130,152,120,
- 80,142, 18,224, 52, 0, 42,181,206, 40,139, 0,188,179,226,176, 66,173,163, 29, 12,152,170, 95,132,139,109, 61, 97,147,172,141,
-236,179,148,219, 5, 60,197, 82,199, 40, 82,168, 81,139, 81,231,176,130, 70,113,168,137, 58,233,206,211, 29,192,220,211,216, 50,
-103,115,172, 77, 9,240,220,206,225, 4,192,103,139,253,127, 2,144,116, 45, 59,114, 19, 81,212, 85,101,151,159, 61,221, 67,207,
-116, 38, 19, 36,134,144,192, 38, 2, 33,196,134, 13,127,129,216, 32,241, 41,124, 3,136,127,225, 15,178, 3, 36, 4, 10, 11, 80,
- 34,145,160, 76,210,211, 79,219, 85,174, 23,231, 52, 82, 47, 90,234,182,100,217,247,113,110,221,115,207, 85,143, 31,173, 18, 10,
- 78,147, 25, 50,183,172,129,199,168,148,198,210,171,188,162,238, 5,202, 79,228,121, 14,234,115,165,143,175,225,105,129,226, 63,
-145, 67,233, 41,113, 58, 66, 20,253,108, 46,118, 14,192,193,178,182,131, 31,248,218,187, 23,219,213,199, 87,103,139,236,119,111,
-107,106, 88,104,228,157,130,227,225,220,107,209, 70, 14, 52,224, 11,119,143,112,213, 3, 64, 68,193,238,147, 44, 38,220, 42,238,
-102, 88,111, 5, 18,219,113,207,169,245,192,165,243,110,227,217,175,210,200,112,119,139,165,187,122,231,163,231,235,222,174,223,
-164, 88,199,218, 13, 28, 90, 49, 35,249,190,227,212,140, 40,207, 92, 47,216,186,231, 97, 16,153,214,138,155, 17,168,103,228,119,
-233,242,222,242,225,229,142,231, 56, 5, 92, 84,115, 6,115,209,147,222,147,161,168, 28,155,121,124,242,217,117,209, 62,124,246,
-236,181, 12,123,114,214, 1,252, 2,245,233, 6,252,221,240,154,138, 4, 39, 10,252, 32,217,104,220,191,241, 67, 13,139,144,165,
- 36, 66,165,184, 8,178,100,112,131, 11,243, 15, 46,190,254,242,158, 61,222,154, 73,112,145, 57,140,223, 32,183,161, 76,229, 35,
-109,155,229,226,254,148,175,174,127,123,122,248,254,135,159,191,251,241,167, 63,254,124,145, 55, 98,222, 54,108,149,196,176,215,
- 19, 42,144,147, 19,147,241,209,104, 10,231,203,137, 35,247,162, 68,104,207,201, 45,118,220, 82, 67, 34, 90, 91,209,136, 59,224,
- 7, 93, 86,220, 10,157,183,136,128, 77,197, 41, 29,171,242, 37,189,147,131, 36,254,122,249,224,219,111,102,159,126,113,200,228,
-191,227,206, 82, 81,144,243,157, 20, 74, 63, 29, 60,113,220, 6,150,144, 13, 3, 25, 98,168,247,250, 56,188, 28,247,190,223,237,
-195,238,239, 48,108,237,230,159,120, 88, 59,210, 22, 1,146, 35, 15,186, 66, 39, 52, 79, 49,226,230,224,175,238,215,159,124,245,
-126,126, 1,188,207, 1,111, 54,130,185,195,193,147,237,195,129, 23,149,221, 57, 7, 51, 70,241, 99, 40,109, 31, 15, 33,219,115,
-135,234,212,123,170,133,246, 86, 88,146,148, 93,145,145, 98,135,192, 56,230,122, 17,171,203,236,230,201,163, 95,154, 27,123,187,
- 41,213, 56,246, 72, 87,206, 80,235, 34,219,140,219, 84, 63,184,145,153,221,174, 41, 61,159, 21, 25,226, 56, 28, 5, 5, 97, 46,
- 85, 35,119, 93,232,118,130,241,151, 92, 44, 4, 37, 5,135, 65, 14,148,197, 73,189,208,199,235,199,231,111,223,237,126,125,122,
-148,165,171, 45,242, 40,155,196, 3, 89, 77,200,182,106, 27,201,145,182,167, 9, 88,212,224,110,237,155, 46,235, 75,199,213, 12,
-149,192,203, 45,163,226,216, 94,237,148,166,238, 83,176, 40, 99,168, 14, 86, 31,244, 4, 80,232,106,159,170, 66,140,138,193,170,
-172,124, 26, 80, 10, 70, 46,105,208, 0,184,220,192,156,162,227, 86,248,170, 8, 60,189, 43,212,252,189,155,221,155,215,253,250,
- 47,169,117,168,243, 64,125, 94,224, 92,131, 28,194,195,241, 70,226,181,100,101, 98,171, 18, 32, 51,151,117,141, 27, 84,200,230,
- 66,243,172, 52,144, 45, 28, 93, 39,170, 89,187,200,212, 96,253,221,219,193, 28, 93,123,126,182, 64, 60, 64, 82, 27,189, 78,220,
- 94, 49,177, 79, 54,205,203,182,236, 10, 88,112, 19,139, 29,138,233, 0, 92,135,103,213,215,108, 46,180,185, 68,253, 21,203, 33,
-105, 60,134, 25,176,118,213, 0,127, 84,154,118,206,182,153, 23,147,137, 74,169, 35,207,132, 41, 19, 39, 41,134,136, 16, 30, 10,
-146, 31,149,101,171,229, 52,160, 27, 41,139,246,191,250, 15, 41,116,236,223, 19, 69,160,194,132, 7,113, 77,184,160,177,208, 30,
-249, 65,149,227,170, 48, 19, 86,212,211,197,231, 31, 62, 95,174,212,237,171, 28,240, 79, 23,182, 65, 13,100,149, 73,125,115,194,
-164, 89,211,100,190,149,136,236,157, 69, 20,238,148,172,203, 72,176, 55, 9,192, 48,191, 87, 73, 74,186, 76,165,249,101,166, 60,
-172,199, 40, 69, 10, 73,185, 53,192, 71, 70, 85, 77, 92, 27,173, 80,158, 77,206,151,210,146, 35,144,107,134,145,100,102,110, 10,
-178, 27, 59, 59,139, 19, 2, 99,114,165,245, 46, 84, 72, 98, 43,188,144,188, 59, 0,139,197,204,113, 70, 87, 84,181, 63,243,254,
- 40,194, 88, 82, 83,135,131,255,196,251,134,222, 26, 29, 23,161,245,228, 21, 2, 16,105,175,121,129, 80,254, 28, 46,212,167,202,
-107, 39,107,229, 78, 26,123,248,177,206, 6, 92,154, 77, 9, 73, 11,229,149,142,212,117,144,210, 21,212, 42, 87, 84,107, 46,165,
-222, 31,180,243,102, 60,159,233,188,119,169, 49,182,236,116,180, 62,250,255, 4,224,232, 90,118,228, 38,162,168,237,122,184,108,
-183,123, 58, 61,210, 72, 25, 68,164, 25, 2, 11, 64,132, 13, 35,182,136, 5,130, 5,159,195,143,176, 99,199, 71, 32, 86,124, 3,
-172, 2, 1, 34,132, 20,162,100, 50,147,233,153,177, 93,174,135,171, 56,199, 82,175, 90,106, 87,219,190,117,207, 57,117, 95,226,
-252,241, 67,252,169, 14,220, 80, 26,216, 75, 83,228,109, 79, 39, 32, 90,166,237, 79, 64, 84,240,242,181,235, 99, 81,207, 48, 93,
-246,174,103,185,125, 1,128,145,248,106,100,219, 37,120, 79, 99, 71,122, 30,206,155,102,247,147,178,185,255,243,245, 65,196,179,
- 15, 30, 25,145, 94,120,198,255, 74, 18,149,181, 23,104,161,113,215,128,112, 3, 33, 88,225,129, 8,141,213, 65,108, 65, 82,138,
-150,103, 41, 30,158, 61,205,156, 36,198,198,229,180, 32, 24,244, 90,112, 15,226, 81,230, 27, 61,220,143,167,199, 98,119,210, 62,
-255, 47, 31, 46, 65,221, 32,156,153, 80, 31,157,174,175,231, 43,165,217,239,179, 91, 44,232, 57, 49, 87, 16, 78,100,146,236,172,
- 86,140,244, 48,237, 39,143,134,120, 15,220, 7,231, 86,213,122, 14, 7,182, 80, 2, 29, 96,167,195,220,171,242,195, 79,223,247,
-221,246,223,167,247,126,186,146, 29, 83,134,170,117, 34,243,102, 13, 27, 44, 42,196, 9,232,171,152,253,207,169,238, 44,233, 4,
-111, 42,214,136, 44,214,131,228, 28, 45,180, 71,251,205, 87,221,147, 39,119,126, 4, 80, 25,119, 0,219,115,240,135,114,205,165,
-217, 63,108,219,119,206,127,123,122,245,195,143,127,127,247,253, 47,191, 62,251,203,121,215, 26,179,169, 21,165, 2, 76, 40, 0,
- 61, 21,167, 16,129,189, 22, 5,156,133,229, 64, 55, 6, 60,193,232,235,121,237,150, 91, 5, 1,113,186,209,170, 86, 84,178, 80,
-152,141,218, 70,177,144,252,231,122, 83, 29,229,142,103, 31, 59,165,217,139, 27,118, 43,223, 59, 59,253,246,203,246,252,227, 67,
- 49,189,177,119,129,106,175,164,232, 94,155,187, 45, 88,146,111, 39, 78,113,174,228,144,171, 97,137,111,210,252,210,223, 30,252,
-120,157,134, 87,241,246,165,205,183,169,184,225, 47,196,219,216,207,149, 77, 80,113, 21, 92, 9, 95,193, 91,184, 42,245,217,215,
-251,163, 11, 3,166, 79,124,229,228,144,196,180,116,175, 35,139, 70,150, 56,206, 44,154,245,240,104,193,223,214,165,133, 8,224,
- 78,194,115, 99, 91,120,139,117,163,205,236,254,136, 79, 43, 11,125,172, 27,252,195,221,162, 78,154,205, 71,159,255,225,125,152,
- 47,173, 6, 13,171,202,235,118, 14, 75, 31,230,217,187, 49,136,211,221,209, 3, 63, 56,144, 45, 92, 83,233,112, 92,139, 28, 75,
-155,186, 49, 7,176,202, 50, 68,184, 50,199,104,165, 97,111,238,204,168,151,100, 25,175,211,169, 61,219,158, 92, 60,254,249,167,
- 23, 85,180, 77, 22,215, 80,109,236,147, 19,170,129,185,205,172,186,134,123,198, 27,102,158, 5,108,159, 21,130,172, 22, 93, 10,
-108,177,117, 63,224,129,112,120, 37, 36,214, 62,249,155, 42,195, 85, 99, 95, 45, 16, 66, 29, 91,138,245, 37,207,188, 60,127,225,
- 56,196, 66,110,240, 46, 43,205,121, 27,145,245,171,224, 84, 75,153,214,188, 48, 24,154,247,106, 15, 13,189, 95,158,253, 62, 1,
-229, 1,247, 65, 2,169,120,116,142,109,232, 72,233,180,150,209, 8, 30,241,105,136, 70, 48, 35, 85, 57,211,238, 96,129,155,104,
- 76,155,211,198, 24, 53,193,201,173,153,225, 29, 96, 61, 93,222,216,233,110,194, 61, 55,219, 29, 76,107,211, 85,222, 37, 29,157,
-208,163,213,153, 67,141, 28,248, 1,238, 72, 60, 0, 96,231,186,236, 68,219,201,150, 69,155,177,217,117,253,187,125,191,223,213,
-170, 77,179, 26,129,238, 83, 4,197,171, 44,104,170,140, 17, 42, 25,110, 84, 50,219, 25, 28, 61,243,156, 47, 11,250,116,224, 23,
-212,178, 99,132, 66,176, 56, 31,254,131, 93,227, 2,192, 85, 67, 97,164, 53,163,134, 45,237, 64, 75,193,101, 11, 70,137, 5,148,
- 73,140,178,232, 65, 1,141,104,100,232,143, 54,242,226,139,127,234, 45,204,229,126,203, 52,188,100,193,239, 57,240, 38,186,173,
- 82,227, 90, 16,137,139, 85,163,153, 37, 71, 23, 44, 65, 3,198, 42, 97, 84,213,215,245, 50,182,254,164, 8,203, 92,186,192, 98,
- 68,161, 67,217,110, 15,133, 63, 30,112,231, 97, 54,121, 74,217, 36,169,219,186,155,124,102,138,144,210,165, 26, 36, 52, 8, 96,
-186, 19,154, 49,190,134,167,126,182,115, 34,104,205, 64,169, 78,240,185,206, 20,163, 91,154,217,118, 6,238, 76, 21,131,202, 76,
- 21,101, 64,217,143, 28,154,165,152,120, 50,175, 19, 46, 19, 88,226,172,141, 29,114,199, 29,187, 56, 14,113,131,208, 98,147,209,
-194,182, 5,252,149, 16,115, 72, 89, 25,182, 46, 89,176,165, 60, 11, 63, 23, 33,171, 78,141,245,212,143,173, 13,150, 35,110,139,
- 46,150,147,107,176,228, 44,125, 21, 35,200,173,230,232, 99, 80,206,169, 43,203,174, 22,226,127, 1, 56,186,150,221, 58,138, 40,
- 56,253,154,158,199, 29,251,218,215, 4, 57,137, 69, 34,130,144, 64,100, 1,236, 34,248, 1, 36, 86, 44,216,242, 53,108,249, 16,
-214,252, 1, 18, 27,132,178, 64, 74,192,100,227,128,237,248,237,121,118,207,116, 55, 85,119,125,117,165,153,158, 62,231, 84,117,
-159, 83,165,142,158, 29, 81, 32, 95, 44,221, 72, 32, 59,231, 98,171,205, 85,203, 84,122,221,210, 27, 9,133,123,146, 8,121,227,
- 53, 5,189,137,105,166, 80,238, 8, 63, 82, 45, 80,207,118, 80,150,229, 76,119,110, 12,179, 19, 19, 50, 51,123,196,228,146,142,
-207,187, 74, 63,251,244,233, 27, 14, 78,105,155,229,123,164,204,114, 11,123, 73,137, 13, 24,209,188,140,218, 56,202,112, 43,148,
- 79,149,249,187,120,131,178,217,197,192,195, 25, 5, 12, 14, 88,135,244,188,176,183, 54,245, 50,210,213,141,147, 47,119,227,237,
-163,195,184,217,188,119,121,181, 92,220,183,114, 10, 42, 84, 75, 49, 42,187,180,247,168,235, 9, 92, 73,244,209,244,216,177,169,
-213,201, 80,123, 88, 56,112,239, 1,164, 91,125,241, 28, 59,234, 46,114,142,157, 7, 72,188,221,197,207,216,137, 91, 39, 25,112,
-254,114, 87,126,246,113,179,217, 60, 60,126,229,252,253,237, 82,141, 5,182, 92,180,192, 60,198, 34,127,115,144, 50,183, 92,215,
-229, 94,199, 50,143,108, 70, 5,135, 85, 85, 37, 1, 39,156,139,215, 93,250,224,112,239,135,111,115,219,158,222,179, 43, 28,143,
-158,205,188, 94,170, 80, 59, 31, 60, 46,146,125,255,231, 95,174,127,252,233,229,175,191,253,185, 51,187,117, 89,175,128, 97,116,
-114,137, 13,143, 10,177, 35, 41, 17,150,102, 33, 39,158, 39,152,173,195, 28,165, 31,177,137,106,224,117,141, 20, 97,152,141,139,
-130, 98, 82,202, 0,185, 23,185, 71,132,154, 88,175,117,185,111,217,204,100,243, 97,123, 29, 59,211,239,178,124,254,249,193,247,
-223, 85, 7, 71,231, 1,148, 98,220,182,220, 80,218, 51,219,182,183, 71,186, 73, 73, 31,231, 5, 80, 34,111, 93,108,147,187,246,
-253,201,208,183,254, 6, 80,251,237,114,123,177,140,103, 73,247,233, 6, 43, 44,104,124,205, 46,250,168, 44, 87, 39, 27,175,178,
- 81,165, 47,191,217, 28,126, 85,141, 29,111, 38,217,229,202,185,189, 89,208, 48,196,128,232, 99, 29,120, 91, 61,171, 0, 64,212,
-133, 56, 75,193,177,110,124, 91,225,125, 48,157, 66,228,131, 81, 8,138,153, 80,177,157,254, 74, 70, 35,246, 7,235,214,155,170,
-250,228,195,243,191, 78,120, 90,209, 89, 57, 37, 85, 17, 1, 78,109,100,179,242,212, 14,181,221,236,214,187,233, 10, 1,132,140,
- 3,132,146,247, 1,137,145, 35, 52,189, 72, 35, 15,179,192,187,134,109, 67, 16, 39, 80,105,122, 65, 21, 73,160, 83,211,197,143,
-190,126,250,242, 85,184,125,123, 97,104, 98, 73,189,211, 28,120, 63,203,122, 10,103,137,224,229,128,199,173,104, 78, 41,102, 94,
-188, 27, 59, 7,167, 57,195, 72,251,104,147, 91, 89,122, 18,116,198,132,224, 65,111,133, 87, 46, 98,173,180, 71,212,165, 85, 32,
-225,162, 62, 1,114,178,204, 64,198,220,164,188,118,130,173,226,129,183, 65, 84,183, 3,126, 72, 20, 86,157, 83,223, 28, 60, 17,
-170, 25, 94,191,166,182,127, 37,203,104,120,130,139,220,104,140, 40, 41, 95, 35,183, 14, 57,245, 20,123,196,234, 62, 96,128, 55,
- 37,128,103, 14, 68,217,161,142,174, 68,207,158, 7,215, 1, 56, 21,186,193, 46,217,183,133,114,167,111,250,219,155,251,155,211,
-128,144, 47,215,149,222, 41,214, 22,165,160, 88, 37,177,105,108,115, 96,155,104, 55, 15,246, 86, 15,243, 29, 81,155,131,166, 30,
- 87, 67, 86,190,251, 47,158,252,113,119,242,251,217,223,199,255,158,252,115,118,121,121, 53, 81,224,215, 83,236,167,240,212, 35,
-111, 3,150, 49,204,209, 89, 77,184,229,213, 48, 39, 79, 69,110,240,115,182, 49,113, 35,186,101, 10, 41,227,232,164,160,230,170,
-162,181, 23,221, 45, 21, 85,130,165,229, 52, 9,219,252,108,214,228,196, 15,166, 18,219,126,161,233,209,227, 39,195,139, 23,199,
-239,206,181, 53,113,224,120, 34,106,129,215,192,221,171, 0,208,158,155,113,177, 41, 79, 43, 91,230, 76, 38,102, 47,219,243, 90,
-215, 11,231,105,194,136,122, 67,113,191, 12, 47, 22,114, 0,139,117,214,129, 78, 5,187,196,169, 76,249, 92,208, 82,116, 95, 41,
- 58, 59, 8,231,123, 60,175,164,161, 4,152,253,237,208, 68,151,120,103,131,133, 7,159, 9,168,146, 99,170,102,229,170,186,114,
-195,132,255, 3, 98,173, 92,177,144,251,104, 23,124,109,136,191,150, 98, 26,200, 37, 82, 19,169,245,221, 2, 51,240,148,115,166,
-125, 89, 54, 1, 53, 79, 70,161,142,108,251,150, 80, 1,176, 37,104,231,132,207,142,253, 25,115, 35,239,144, 89,228,186,152, 26,
-160, 94, 10, 49,160, 90,206, 89,184,155,170, 85, 46, 77,155,101,141,156,118,129,167, 11, 20,145,126,141, 18, 22, 38, 85,165, 42,
- 43, 80, 46, 40,103, 79, 13,167,177,251, 95, 0,142,174,101, 55,146, 34, 8, 86,215,163, 95,158,135,135, 5, 22, 44,144,109, 89,
-128,118, 87,172,144,184, 32, 56,113,226,202, 15,112,224,135, 16,191,192,133, 31,224,204, 17, 33,113,224,130, 88, 33,193, 34, 89,
- 11,235, 53,158,177,123,166,159,245,108, 34,252, 5,211,211,149,149, 25,145, 29, 25,169, 78,159,158, 8,196, 3,254, 87,162,126,
-178,188,183, 43,137,253,132, 95,243, 64,179, 9, 4,139,249, 38,103,115, 42,218, 90,105,206, 27, 83,138,136,235,171,130,112,210,
-206, 35, 30,203, 15, 40,154,140,112, 55, 88,221,227,230, 36, 87,136,201,246,187,103,151,203,211,197,123,231,175,247,135,240, 50,
-184,181,100,187,208,103,116,241,170, 53, 56, 74,198, 29,194, 51, 77,144,130,140,222,247,157,109,239,240, 6,178, 78,122,237,144,
- 48, 35, 13,178, 1, 40, 17, 46,184, 84,202,246, 26,249, 97, 94,240,208,156,115,125,115,115,114, 52, 60,124,119, 49,101,249,221,
- 22,240, 13, 20,214, 81, 23, 7,168, 92,224,201,169,185, 49,148,108,112,179,147,185,199,222, 34,121, 99,194,180,112,143,206,143,
- 55,226,165,141, 37,189,210,114, 65,111, 87, 6, 22,237, 5,217, 11, 81,214,246,214,232,233,236,253, 7, 39,143, 47,110,254, 16,
-251,253, 22, 20, 70,148, 17, 47,187,140,178, 30,144, 78,139, 73, 39,199,246, 61,205,131, 10, 21,213,210, 12, 86, 84, 6, 41, 57,
-237,218,224,197,230,235,175, 86, 79, 63,188,217,253,118,232,113, 23,108,156,219, 52,134, 57, 55,250,226, 2, 8,251,252,219,239,
-110,190,249,254,167,241,234, 80, 46,165, 92,149, 40,111,168,181,224,193,129,171,138, 12,187, 14,129,180,128,187,193,197,108,150,
-156,138, 75, 65, 79,193,205, 99,182, 96, 59,197,128, 44,123, 36, 21, 83,200,251,207,176, 5, 57, 20, 40, 40,237,185,181,225, 87,
- 35, 83, 25,109, 66,189,234,234, 40,109, 93,125,250,241,241,151, 95, 56,125,244,202,221, 29,232, 8, 43,153,116,195, 76,127, 15,
-144,108,218,119,201,110, 70,206, 1,108,111, 50,113, 24,134,195,188,111,108,119, 27,239, 26,123,120, 21,211,181,117, 99,240,157,
-208,113,230, 70,114, 27,205, 40, 57,239,131,107, 89,100, 3,104,171,139,143, 62,219, 60,249,252,141,177, 12,177, 75, 8, 93, 26,
- 94, 83,254,195,145,130,185, 7, 83,119,161,141,161,195,201, 2, 39, 76,126,167,144, 8,124,207, 33, 70,201,237, 47,214,121, 35,
- 71, 4, 63,229, 22, 11,202,178,233,207,158, 1,136,173,184,148,231,225,217,105,115,113,242,252,159, 30,225,123, 39,109, 20, 99,
- 54,250, 62,136,144, 71,176,125, 17,187,219,113, 90,110,214,103,168,208,195,158,223, 77, 43,133, 34,136,135, 13,154,203, 23,184,
-204, 26,213, 38, 1, 85,112,184, 93, 15,244, 1, 50,158, 50, 40, 11,232, 25,199,211, 79, 30,212,143,223,249,225,199,157, 15,125,
- 85,115, 81,238, 68,215,104,186,214,134,249,254,131, 7,239, 65,146,206, 40,171, 71,170, 79,185,133,137,210, 86, 67, 15, 8,154,
-107, 40,250, 57, 70, 54,212,156, 13,129,250,190,146,110, 90,168,208,243, 10, 39,131, 3,194,115,206, 83, 30, 43,151,234, 81,248,
-178, 82,130, 83,239, 96, 7, 69,222,169,185,141, 38, 55,128, 29, 32, 80, 35,170,186, 56,126,235,129,191,190,181,187, 43, 95,208,
-117,207,151,197,232, 66, 73,185, 40,248,166, 46, 80,144, 77, 81, 86, 65,174,185,148, 65,145, 7,179,176,129,152,198,170, 60,170,
-168,145, 43, 17,182,185,154,141,232,185, 58,103, 94, 85, 0, 7,249, 90,165,125,211,108, 95, 52,255, 93,245,109,107,199, 91, 13,
-168, 57,128,211,222,136,102,240,219,203,105,251,111,119,125,185,251,235,151,230,247, 95,159, 95,254,124,185,253,251, 69, 59,236,
-154,105, 15,142, 80,191,157,111, 86,245,155,175,213, 69, 93,155,165, 82, 72,140,173,160,212, 50,164, 99, 64,184,193,183,109, 86,
- 11,153,216,177,241,149, 5, 21, 5, 80,137,118, 44,199, 56, 83, 54,225,104,200,196, 65,253,148, 29,105, 26,140, 81,228,203, 33,
- 85,138, 24,116,142, 19, 79, 92, 16,169,178,146,182,201,200,249,233,104,173, 54, 31, 61,249,243,131,179,108,215,212,107, 20,140,
-130, 91, 54,116,141, 28, 37,233,192, 12, 96,134,204,139, 74,155,245, 54, 11, 59,206, 40,208,203,113, 97, 17, 86,101,170,151,120,
-255,117, 37, 37,142, 94,120,151, 79,247,110, 64, 25, 29,128, 13,247,159, 72,219, 34,231,187,130, 22,100, 89, 44, 58,128, 65,183,
- 86, 21, 55,134, 76, 90,151,137,195, 66,154,122, 13, 69,221,193, 10,160, 98,145,144,146,178, 96, 56, 4, 38,128,252, 21,112,212,
- 1, 92, 5,117,155, 6,108,105, 84, 38,223,151, 73,214,115, 57, 28, 43, 25,114, 94,212,130, 30,132, 28, 48,237,180, 43,151, 27,
-159,107,122,117,120, 51, 34, 90,189, 80,209,236,231,177, 60, 48, 99,163,136,215,201,154,122, 30,145, 53,230, 26,240,156, 66,202,
- 56,201,136, 40,230,162,160, 66,229, 57, 32, 18, 10, 8,104, 8, 59,230,145, 11,194, 99, 30,145,182,148,224, 50,175,146,115, 38,
-217,255, 2,144,116, 45,187,141, 20, 81,180,171,235,209, 15, 63, 98, 59, 18, 97,130, 19, 96, 3, 35,205,102,128, 45, 18,179, 27,
- 13,255,128,248, 25,190,133, 29, 75, 62, 4,118, 8,177,137, 38, 97, 98,199,196,238,151,187, 30,221,197, 57, 61,107,171, 37,119,
- 87,213,185,231,214,189,247, 28,249,229,246,122,164, 37,219,128,229,159,249,228,132,116, 26,169,205, 56, 80,193, 5, 25, 50,117,
-206,113,248, 45,214, 3, 76,111,168, 99,210, 81,103, 58, 14, 54, 44,244,217,131,252,209,104,171, 39,254,156, 21,194,100, 75, 25,
- 92,229,154, 1,216,222, 55,153, 27,250,240,112,255,100,190,186,124,125,125,123,234, 79, 59, 96,136, 82, 82,210, 83, 53, 5, 46,
- 37, 57,178, 49,170,163, 99, 47,135,115, 29, 71,155, 34, 41,105, 56,173,173, 44, 32, 28,127,132, 22,142,238, 76, 79,122, 25,168,
- 33, 72,233, 57,252,221,150,125,203, 99, 99,219, 83,189,217,250,155,219,121, 80,229, 63,187,230,120, 68, 62, 76, 97, 6, 31,172,
-181, 8,230,122,152, 57,239, 73, 2, 1,183,153, 11,236, 51,136, 32,168,243,175,183,230, 82, 62, 56, 80, 34,147, 32,199,194, 54,
- 18,218, 69,203,250, 17,165, 61,152,104,116,222, 51, 20,221,108, 87,219,151, 47, 30,238,138,170,122,206,116,101,216,128,174,216,
-149,146,142,122, 40, 10,118, 3, 59, 42,126,225,157, 58, 49, 39,124, 68, 48,215,133,185,250,233,231,205,219,183,125,243,254,212,
- 30, 66,125,176,103, 79,129,125, 33,203,219,235, 23,131,249,236,151, 95,223,255,246,251, 31,160,229,235, 37, 75,254, 0, 56, 27,
- 16,197, 38,191,188, 60, 38,214, 81,151,196, 80,253,135,190,126, 36,254,164,137,120,233, 66,129, 15, 0,240,100,248,168, 75, 96,
-242, 85,226,229,138, 55, 6,133, 44, 1,181,203, 92, 21,121, 54,211, 67,228, 76, 5, 40,140,104,135,139, 60,223,188,251, 65,188,
-249,222, 9,117,111,171,202,211, 93, 48, 19,212,119,114, 36,177, 88,254,164,163, 77,135,245,162,214,162,103,253,179, 58,132, 83,
-215, 54,143,178,122, 26,219, 93, 95, 31,188,173, 71,243, 31,120,247, 40, 0,238, 83, 93,132, 67,107, 51,150,175, 69, 51, 30,207,
-241,139,173,249,238,199,203,118, 34, 92,148,101, 20, 38, 78, 62, 85, 9,241,221,120, 38,171,131,171,232,229, 54, 54,129,162,205,
-145,142,100,162, 30, 3,210, 62,196, 63, 63,184, 22,143, 88, 54, 75, 79,226, 83,178, 72,138, 82,166,101,126,206, 2, 40,248,246,
-155,151, 15,139,197,253,135, 67, 26,218,102,207,177,252,199, 90,114, 74,132, 23, 35,200, 58,196,113,148, 85,151,126,178,186,249,
- 52, 61,116,186,141,206,120, 9, 12,180,211,241,140, 50,167,124,105, 55,181, 18, 70,205, 74,131, 5,139, 46,216,235, 23,121,246,
- 71,117,178,175,222,109,255,252,203,236,119,255,206, 98,198,228,132,181, 13, 32,199,192,139,154, 86, 56,142,175,166, 84,220, 55,
-188,247, 55,244, 70, 29, 78,136, 17,125,106, 18, 67,246, 53,104,109, 21,231, 32, 50,128, 45,117,121, 17,164,107,149,205,220, 42,
- 34,190,101, 54, 85, 3, 5,228,216,150, 82,142,101,160,240, 38,101,201,253,164, 77, 66,227, 98, 31, 74,170,250,105,100,245, 26,
- 31, 43, 22, 70, 92,126,126,190,219,185,221,179, 84,170, 92,208, 27,128, 73,143,137, 25, 13,180,176,249,180, 43, 18,178,215, 68,
-201,141, 73, 2, 45,118,124,193,126, 70,172, 42, 11, 95,150,157, 13,193,112,226, 21, 40, 49,155, 36,168,193,156, 23,107,106, 54,
-250,172, 15, 93, 93,221,239, 63, 60,237,159,246,207,205,221,225,244,248,252,180, 63,214,199,182, 13,189,208,126,189,201,151, 55,
-133, 94,155,139,139,229,250,106,190,185,154, 25,144,162,162,200,151,192,119,154,112,164, 61, 14,125, 72,215,147,181,217,152,181,
- 22, 7, 40, 22, 96, 76, 26,155, 22, 32,142, 47, 55, 80,183,176, 23, 75,223, 11,149,230, 13,125, 79,220,144,180, 3, 21,147,242,
- 76,218,143, 94,231,108, 41,231,224,185,200,197, 56, 67,244,162,154,156, 86,105, 49,247,171,219,168,190,125,243,183, 94,148, 29,
-150, 25,201,213, 34, 17, 61,142,225, 88, 83,113,146, 34, 40,161,200,123,205, 68, 73, 47,138, 57, 22, 26,159,145, 42,230,153,100,
- 1,155,148,105,154, 38, 94,129, 59, 98, 91,210, 92, 10, 25,247,168,120,221,111,103, 20,153,147,179, 72, 47, 23,246,228,170,162,
-201,192,121, 50,252, 28, 76,165, 88,140, 77,147,174,164,167, 2, 75, 83,244,114, 25, 17,142, 0,231,227,148, 98,159,115, 9, 60,
- 22, 88,108,228,148,128,130,142, 61,189, 0, 88, 59,249, 13, 8, 28,101,239,240,110,188,236, 75, 39,185, 97, 96, 69,121,166,206,
-167, 78,144, 94, 23,171, 81,107,182, 43, 81,209,144, 99, 72,200,234,140,234,227, 36,236,111, 76,182, 68,204,167,128,189, 25, 18,
-151, 76, 94, 85,125,229,166,235, 70,112,151,148,196, 78,209,145,213,179,217, 26,251, 71, 78,202,177, 14, 25, 49,158,249, 95, 0,
-142,174,109, 71,110, 34, 10,218,221,110,187,219,246,120,102,103,178, 65,236, 74, 17,160,192, 62, 32, 37, 64, 94, 81,164, 60,194,
-115,126,144, 47,224, 11, 16,226, 3,144,120,128, 23,164, 8, 33, 72,196,238,100, 55,115,241,189,111, 84,249, 3,108,141,167,219,
-117,170,220,231, 84,201,237,238, 10,101, 2,148, 33, 14,137,177,244,205,213, 17,232, 91, 90,149,108,162,232,153,243,214,211,147,
- 44,128,147,159,233,147,194,236, 97, 2, 45,187, 63,142, 52, 29,195,230, 23, 40,203,163, 61,114,250, 20,111, 67,119,208,185, 43,
-120,204, 41,163,109,215,219, 55, 15,183,127,252,231,119,187,103, 55, 79,138,225,244,119,123, 31, 28,222, 73,219,198, 81,204,157,
-117,247, 71, 55, 30,104,247,139,171, 15,158,175,169,195,253,249,209, 50,101,191,132,244, 90,248,211, 52, 43,199,185,185, 46,216,
- 36, 57,211,222, 7,132,200, 69,153,131, 6,180, 39, 87,134,120,243, 69,113,249, 88,117, 86,191,253, 48,216,101, 32,140,214,149,
- 65, 73,134,125,228,117, 13,196,183, 53, 36,217, 54,179,126,176, 86,127,243,220,236,196,193,111, 12,123,154, 25, 12, 16, 25, 44,
-197, 44,199,100,137,154, 99,158, 13,173, 43,249,241,107,248,232,106,243,236,219,155,195, 65,253,254,235,221, 28,199,236,162, 42,
-234,124, 98, 80, 18,173,255,243,125, 1,200, 91,146, 88,128, 17,211,126, 18,173,205,190,127,117,249,250,181, 15,231,227,233, 93,
-199, 16,233,247, 88, 2,247, 48, 7,185, 93,125,254,232,201, 79,111,210, 31,126,252,109,108,167, 90,240,248,169,135,166, 96,150,
- 79, 58, 9, 54, 2, 51, 88,129,145,169, 5,246, 85, 28,217,105,144,121,197,177,194,217,209,129, 66, 26,215, 44,227,246,133, 90,
-218,164,192,189, 51, 85, 23,140, 85,195,115,111, 33,136, 0,239, 99,110, 99,181, 91, 51,222, 78,234,213,250,209,119, 47,171,175,
- 95, 28,146,176, 31,186, 19,150, 75,114, 28,106,113,219,103,192, 4,207,189,195, 12,242, 88, 39,173,141,239,237,240,222,247,119,
-115,247,175,253,176,159,187,189, 59, 63,244,227, 91,151, 29,213, 48, 4, 8, 80, 80, 53, 53,241, 98,235, 37,246,201, 37,112,114,
-224,252,114,115, 45, 94,188,220, 53,159,152,254,236, 57,166,194, 46, 6,246, 89,101, 52, 48,167, 3, 50, 22,150, 54,252, 39, 58,
- 78,218,118,236, 25, 70, 38, 98,239,109,199,252, 92,246, 41, 76,168,217, 28,151, 7,100,112,136, 44,208, 47,243, 33,161,187,131,
-105,124,179,245,215,207, 63,253,115, 88, 61,220, 30, 19, 14,218, 64,149,162, 12, 70, 35,188, 31,152,230,171, 64,215,166,176,199,
-175, 85,213, 87,101,106,197,209,255,147,230, 35,163,191,179,108,241,212,139, 74,106, 79, 18,236,216, 26, 17, 53, 71, 81, 37,100,
- 61, 24, 15, 42,185,141,227,187,233,250,105,169, 63,123,252,203,207,119, 89, 63, 57, 67,166, 14, 85,129,237,198, 49,168, 84,109,
-150,244,227,164, 11,161,228,208,241,121,146,248, 35, 60,160,196,208,100,132, 81,174, 16, 52, 21, 45, 72, 19,160,248,156,119,206,
-152, 93,111, 2,243, 50, 81, 13, 51, 91, 10,223, 88,168,238, 20,178,130, 78,100, 12,235, 16, 46, 76,153, 82,106,112, 35,179, 0,
-192, 66, 81, 70,146, 86,201,139,212,245,126,234,197,197, 42,172, 27,123,251, 87,123,104,121, 86,140, 11, 32,189, 86,100, 65, 9,
- 63, 69,176,249,167,156,130,111,217,253, 10, 14,156, 48,186,104, 90,235,197,117, 30,139, 91,130,223,165,246,156, 85,180, 78,197,
-235, 95,120,195,126,198,213, 42,129, 80, 92, 89, 40, 61,213,152,162,218, 21, 77,174,215, 31, 87,213,122,149,111, 85,211,168,122,
- 7, 32, 87,185,145,235, 38,175, 55, 53,106,143, 40,113,187, 66,207,153, 89,163,100,231, 26,240,198, 70, 75,201,200, 23, 30,122,
-210, 39, 0,242,129,209,110,144,192,206,167,189,232, 70,186, 67, 65,159,207, 33,240,148, 30,136,177,240,247, 20,191,139, 62, 37,
-114, 7,202,206,233,201, 20,133,140, 91,165,240,155,197, 23, 12,139, 98, 10, 13,118,175,195,120,113,117, 57,126,249,234,222,158,
-141,114, 28,186,213,192, 97,199,249,226, 44,148, 37, 91,255,232,191, 21, 38, 77,143,107,104, 52,104, 0,240,121, 81, 6,227, 85,
-231,211,122, 37,121,228,153,181,102,200, 80,226, 42, 69, 3, 48,231,128, 43, 2,119,207, 73, 35, 1,183, 34, 61,117,208,144,115,
- 4,221,118,208,202, 88, 6, 81,140,105, 62, 53,115, 83, 52,250,220, 71,136,115,250,119, 39,189,162, 89,143, 76, 19, 80,168, 68,
- 67, 53, 73, 57,128, 61, 31,210,108, 80, 64,164, 66, 57,126,243, 4,222,206, 83,153,170,104, 32,184,178,105,164,135,162,175, 12,
- 61,197,176,255,197,220,198,173, 18,145,109, 38, 88,166,108, 30,243,105,102,255, 4,196, 55, 30, 44, 22, 14,197, 45,149, 90,131,
-166,142, 71,224, 81, 63, 8, 49, 99,187,106,154,245,130, 75,228,185,195, 2,156,180,149, 67,203,114, 89,228,115,198, 9,109,223,
- 36,107,172,154,227,107, 45,255, 23,128,163, 43,217,145,163,136,130,153, 85,149,181,116,118,117,207,216,195,200, 54, 26,139,209,
-192, 28, 0,217, 72, 32,196, 1,129,124, 68,226, 35, 16,255,194,111,240, 47,136, 43, 39,206, 44, 54,198,158, 49,118, 47,211,181,
-100,101, 86, 46, 68,244,125,150,170,202,204,247, 34,242,189, 23,145,127,114,253, 62,232, 17, 61,168,233, 54,207, 78,105,163, 67,
-217, 81, 50, 83,208,127,200,233,101,109, 71, 78, 15, 91, 58, 47,229,149,183, 96,164,119,147, 99, 79,131,205, 70,107, 39, 96,245,
-142,173,177, 3, 99,125,153,109, 66, 24, 67,126,231,156, 25,216, 33,210,205,107,147,110,111, 95,254,254,143,123,124,118,253,209,
-213,131, 70,221,116, 67, 23,122, 80, 69, 19, 6, 96, 54,195, 28, 61,149,162,166, 13, 10, 32, 97,118,212,229, 76, 18,236,220,224,
- 12,166,187, 76,142, 17, 9,197,118,142,179, 95, 38,201, 59,176, 35,252,243, 24, 98,208,167,106, 10,198, 6,160,221,195,197, 73,
-120,242,169,174,117,253,170, 3,228,244,179,139,170,166, 39, 54,103, 42,143,102,247,244,123, 13, 89, 47,196,105,211,126,251,213,
-144,141,123, 16, 72, 18, 61,214,240,145, 61, 20,187, 65,233, 11, 22,177,170, 62, 53, 34, 80, 44,218,114,220,102,223,158,166,167,
-159, 3,176, 92,190,123,209,247,239, 14,185,157,234,188,196,233, 3,123,100,253,182,160, 91,115,104,202,100,145, 34, 87,207,190,
- 60,251,241,135, 89,152,110,255,122, 51,238, 92, 60, 96,159,251,195,237,228, 66,117,241,241,249,175,127,228, 63,253,252,220,116,
- 59,182, 31,148,249, 14, 91,206,130, 17,242, 58,187, 84, 28,239, 12, 44, 46, 19, 93, 40, 26,155,113,180,206, 73,240, 35,130, 4,
-108,119, 58,222,212, 10,132,187,105,218,204,230,245, 58, 59, 41,181,173, 4,145,221, 73,185, 70, 92, 41,235,234, 61, 61,164, 83,
- 79,195, 26,123,249, 65,251,253,119,211,245,213,139, 48,108,251,126, 35, 82, 11,240,138, 61,196,108,205,171, 78,124,118, 10,188,
- 74,147,229,125, 12,155,113,220,203,126,159,204,232,251,173, 59,188,141,187, 87,222,191, 9,254,128, 32,233,205, 20,149,139,147,
- 97,217,199, 42, 89, 86,210, 44, 99,149,178,191,122,142, 50,126,253,205,242,252,201,186,119, 71,227,218,178,224,221, 79, 60,138,
-211, 7, 26, 38, 99, 49, 41,144, 58,176,194, 5,108,238,167, 20, 71,222,117, 12, 27,228,117,193,172, 49,225, 25, 20, 93, 79,166,
- 57, 26,240,235,227,111, 47,132,102,247,169, 66, 32, 95, 61,190, 95, 95, 63,253,229,207, 27, 60, 1, 14,117,156,246,135, 33, 28,
-253,218, 45,151,105, 70, 48,139,233, 88, 33,124,123,240,231, 87,235, 71,165,239,194,158,138,212, 43, 18,126, 73, 79, 53,172, 55,
-104, 17,167, 39,105, 88, 24, 57,124,238,115,138,197, 0,249,168,123,130,174,105,243,244,225,103, 15,126,251, 87,190,188,217,100,
- 28,196,195, 87, 18, 13, 18, 56,165,113,217,137,108,112, 22, 40,110,155,197, 73, 86, 81,214, 42,182, 44, 16,178,146, 15, 82, 82,
-203,160,151, 28,187, 27, 44,206,215,228, 10,142,159,120, 11, 48, 40,114,189, 88, 86, 7,224,107, 46, 45, 2, 92, 5, 88,215,226,
- 7, 16,133,138, 1,104, 27,140,186, 47, 41,120, 81,184,132,188,233, 61,114, 93,100,147, 87,102,182,226,225,189,213,217, 35,255,
-247,127, 98,218,202,101,211,207,121,105, 99, 59,208,199,167, 4, 64, 80, 94,215,193,148, 71, 27, 0, 16,212,177, 65,114,137,173,
-158,199, 80, 81,115, 75, 44,241,229,151,113, 88,165,184, 19,213, 66, 81,189, 5,240,199,115, 22,182, 69, 64,125, 88, 75, 0,254,
- 69, 65,101, 92, 29,232,145, 1, 38,168,212,162, 93,228,170,174, 78,128,171, 1,149,117,177, 0,111, 4,224,163,189, 37,222,121,
-100,248,225, 77,122, 40, 64,178,124,109, 4,223,214, 2,171, 83,175,159,102, 76,163,243, 67, 30,170, 0,224,236, 56,105,155, 24,
-127,168, 88, 39, 88,232, 17,199,244,218,228, 19,223,152,244,130,111, 34, 89,167, 73, 28, 13, 80,186,174,130,138, 72,131,237, 42,
-107,191,120,182,185,184, 12,126,171,115,202,143, 82,211,159,124, 73,169, 74,151, 49, 39, 60, 46, 84,200, 22,243,209,242,107, 6,
- 92, 5,198,231, 76, 8, 30, 84,183, 49,113,122,154,198, 95,188, 9,195, 31,240,130, 85,239,188,210,216,114,173,139,237, 54, 7,
-244, 71,218, 42,202, 9, 39,146,253,148, 32, 60, 50,130,215,136, 36, 70,246, 95, 68,160,206,125,136, 45,185, 28,190,173,165,112,
- 9,190, 68,172, 92, 48,170, 78, 83,228,253, 0,176, 47,248, 76, 77,165,198,140, 93,160,236, 40, 96,235,159,227,181,147, 10, 7,
- 93, 20,163, 23, 53, 30,144, 58, 82,160,143,246,190,241,136,218,236, 93, 31,155, 85,222, 20,108, 79, 1,162,144, 5, 43,133,128,
-153,222,219,177, 20,110,177, 2,149, 67,226,161,144, 79, 49, 80, 30,118,191,138,222,185, 22, 8,218,205,148, 65,146,108,181,147,
-210,106, 73,123,196,228,250, 81, 7, 44, 70,246,191, 0, 28, 93,203,110, 36, 69, 16,172,103, 87,119,215,120,102,253, 96,177, 22,
-140,196, 2,203, 32, 88, 12, 18,226,192, 5, 1, 87,174,156,184,241,101,252, 7, 39, 36, 14,240, 15,172,196, 1,179,107,227,181,
-113, 79, 79, 63,234,213, 68,204,213,150,101,117, 85,102, 70, 70, 85, 86,132,190,120,124,202,201, 94, 69,197, 0,137, 94,134, 48,
-182,200,224,192,234,163,198, 71,208, 78,172,196, 72,185, 4, 42,230, 74, 67,191,180,192,254,138,158, 61, 29,125,131,209, 99, 98,
- 83,101, 12, 29,242,110, 88,124,216, 33,184,166,251,133,103,156, 38,162, 45,196, 87,165,252,223,195,195,111,191, 95,101,255,236,
-243,247,159, 31,159,227,131,239, 0,194,138, 8,184, 40, 36,191, 30,203, 76, 63, 28, 83,109,194, 10, 13,213, 16, 59,108,196, 92,
- 64,170, 93, 27,120,137, 12, 54, 52,247, 70,236, 83, 4, 49, 70,236,163,242,163,229,231,141, 43, 22, 88,167,130,234,115, 23,132,
- 28, 63,126,102,182,239,232,198,182,131,173, 95, 47,225,254,193,240,177,193, 40,129, 38, 51,118,163, 55,103,103,235, 47,182,213,
-246,205,219,125,156,163,119, 52,161,166,210, 10,141,226, 56,255, 45, 44,217,235,156,140,206, 18, 52, 24, 61,162, 25,115, 24,129,
-107,224,137,219,143,222, 59,255,224,195,127, 94,236,250,112, 29,142,114, 23,221,169,212,249,145, 24, 60,130, 94,231, 46,244,147,
-250,244,179,139,159,126,172,218,179,155,241,122, 0,217, 76,175,129, 16, 0, 49,212, 78,108,212,218, 63, 58,251,249,151,242,242,
-197, 75,107,121, 71, 8, 80, 45,227,193, 8, 93,114,194,153,198,175,108,216,169, 7, 70,237,237,195,152, 60,226,104,230,161, 24,
- 53, 88,208, 91, 0,215,193, 25, 68,180,212, 90,113,101,169, 93,133, 64,175, 17,204,162,108,252,137,136,210, 85,190, 49,102, 74,
-147, 63,125,254,212,253,240,117,121,227,244, 42,116,119,232, 15,168, 1, 39, 12,103,160,168,215,169, 5, 21,117,122, 62, 31,192,
-110,223,171,124,139, 10, 46,247,221,180,187,153,239,187,240,234,122, 76,175,150,114, 91,244, 72, 89, 63, 26, 76, 6, 48, 39,158,
-226,176,255,215,106, 37,245,196, 25,148, 50,249,242,237, 55,235,139,203,213,158,128,156,148, 71, 48, 29,238, 86,145,169,169, 40,
-203,123,237, 60,204, 97,182,169,231,187, 34, 30, 96, 33,249,129,227,131,114, 61, 26, 59,185,208,108, 42,238, 80,168, 14,191,208,
- 3,169,212,114,176, 88, 66, 15,163,144, 55, 79,194,230,203,147,244,214,229,159, 87,127, 35, 96,204,160, 99,135, 30, 76,118,102,
- 25,199,172, 1,239,224, 47,183,124,103, 31, 16,238, 15, 67,120,210,124,114,220,212,251,253, 56, 68, 14,217, 41,142,195, 39, 26,
-102,113,138, 27, 75,155,235,188, 58,104,122, 2, 0,154, 72,169, 99,237, 41,155,179,219, 79, 79,143,215,151,223,111,127,253, 35,
-238,111,254,165,212,119,225, 12,221, 18, 81,132,150,220,210, 40, 6,229,217, 78, 18,216, 67, 1, 3, 44, 30,186,198, 64,157,188,
-144,233,179,172, 6,254, 73, 51, 88,191, 1, 74,153, 53,175,250, 91,221, 72, 58,185,231, 33, 41,231, 18,167, 70, 26,181,144, 96,
-167, 92, 3, 14, 69,160,241,115,197,120, 16, 7,147,103, 81,181, 72, 93, 0, 35,175, 44, 69,234,186,185, 58,125, 59,185,163,124,
-117,109,119,247, 72, 72,187, 50, 28,190,105,121,151,134,192,224,203, 36,158,124, 58, 53, 69,135, 16, 17,148, 84,173,235, 34,218,
-165,247, 84,124, 92,144,178,168,152, 82, 30,227,255,238, 51, 24,226, 72,113,173, 5,251, 55, 86,224,149,227,134,131,207, 43,139,
- 92,171,232,179,220, 40, 39,107,141,214,203, 71,145, 86, 88, 65,109, 44,189,169, 74,171,117,160, 18, 54,237,173,198,156, 44, 86,
-197,138, 56, 35,101,115,230, 77, 36,126,160,231,156,239,192, 42, 88,210, 5,126,120,152,169,243,168,243, 20,107,164,122,133,224,
-193, 57,186, 52,170, 9,162,159,163,156,103,214,124,207,109, 1,231, 53,226,187, 61,140,219,162, 20,159,152,225,252,221,199,243,
- 87,223,253,133,181,230,107,234, 90,163,163,152, 93, 3,232, 3, 5,173,144, 35,119, 83,149,188,182, 85,114, 65, 73, 0, 63,216,
- 53,168, 65, 59, 75, 52,180, 30, 59,131,246,137, 79,123, 58, 65,247,206, 35,106, 9, 32,181,249, 24, 30,241, 57,184, 85, 70, 78,
-236,214, 6, 5, 83, 69, 62,217, 70, 61,202, 10,141,225, 17, 8, 93,203,135, 46,189,147, 40,139, 27,128, 67, 53,170,174,166, 38,
-124,163,189, 83,148,241,217,233,172,145,156, 25,204, 6, 8,214,247,129,181,147, 19,184,205, 20,117,235, 75,161, 95,244, 65, 83,
-146,234, 16,220,113, 89, 99, 91,131, 22,243, 78, 47,165,178,149,215,149,166, 61,232, 4, 0, 2,178, 1,117,199,228,102,124,142,
-206,160, 17,218,142,193,155, 41,183,113,162,173, 27,104, 65,156, 12, 31, 33,106,148,141,162, 26,186,225,121, 26, 15,202,201,242,
- 0, 1, 59, 12,212, 70,144,107,128, 99,178,255, 11,192,209,181,236,200, 77, 68, 81,187,202,101, 87,219,238,233,199, 48, 12,211,
- 61, 33,137, 34,162,132, 9, 1,132,196, 67, 2, 9,137, 61, 63,193,142,111,226, 27,248, 11, 54,236,178, 2, 22, 40,210,144,145,
-152,100,232,233,110, 63,235, 97, 23,231,248, 7,102,218,174, 91,247,158,227,123,239, 57,242,209,131, 77, 35,236, 36,160, 63, 53,
- 52,185,124, 29,215, 25,114,169, 83,125,224,170,169,167,118, 4, 31,222,138,136,122,168, 17,135, 21, 27, 58, 6,141,179, 35, 8,
-117,112,131,233, 28,229,194,216,245,112,153,181,195, 65, 56, 4,146,156, 57, 15,132,237,231, 6,247,134, 51,194,205,125,255,219,
-223,127,253,254, 71,147, 47, 62,122,246,244,197,252,116, 94,226,192, 56, 36,150, 15, 67,162, 50, 68,120, 46, 53,112, 49,110,195,
-230,116,249,240,189,205,249,122,126,190, 60, 91,174,215,249, 82,231, 42, 46,233,159,106,128, 30,141, 55, 28,162,161, 8, 6,234,
- 13, 46,175,137,217, 38,193, 83, 88,211, 30,205, 73,209, 61,249, 56,124,251, 92,125,242,168,188,216,204,182,107,117,246,193,201,
-135,219,242,226, 50,123,121,165,126,248,206, 62,219,128,232,182,156, 65, 66,221,173, 6, 18,203,201,239, 7,136, 0, 68, 36, 78,
-197, 64, 77, 94, 27, 8, 58, 56,204, 21,131,218,251,216, 30, 67,146,189,219, 92, 20, 87,159, 61,184,187, 91, 29,118, 93, 22,118,
-243, 1, 16, 4,249,216,241,222, 27,249,197,139,205, 79, 63, 15,171,237,253,221,117, 61, 28, 6,119, 20,134, 58,174, 93,243, 6,
- 25, 60,187,124,178,186,143,150,191,252, 10,144, 92,199,120, 89,236,214, 57,210,213, 48,137, 18,143, 20, 68,166,228,109, 22, 18,
-176, 71,142,108,250, 48,121,224,149,184,239,200, 77,122,146, 98,201,217,179,176, 39,113,140, 91,183,140,103, 50,205,230, 50,203,
-105,231, 57,211, 82, 83,133, 80,203, 60, 20,105,249,253, 55,203, 31,191,250, 55, 61,121,221, 31,247,174, 71,106, 67,152,117,180,
-195, 14,114,242, 48, 55,209,208,139, 54, 14, 85, 26,106,103,246, 67,117,108,171,131, 51, 55,110,255,143,171,110,251,230, 63, 31,
-237,233, 77, 48, 78,159,169,250,145,199, 47,232, 76, 70,171, 13, 81,114,214,166,171,198,190, 13,219, 11,253,242,235,165, 97,155,
- 71,196, 43,126, 67,140, 57, 31,197,137,125, 84, 42,118,126,106,238, 0,142, 10,220,206,117,149,162,102,100,229, 65, 71,219, 93,
-112, 13,184,163,176,102,232,144,199,186, 92,182, 76, 0,169,163,182, 61, 3,146, 59, 34,169, 44, 67,145,249,179,199, 87,215,201,
-236,246,102, 71, 55, 46,196, 55, 74, 54, 95, 4, 69, 72,187, 4,239, 49, 47, 40, 24,103,171, 1,108,212,190,185,137, 68,182,250,
-116, 29,183,199, 35,206, 47,109, 35, 42,110,151,209, 52,127, 56,142, 53, 42,165, 27, 0, 91, 13,149, 36, 44, 87,165, 40,110, 5,
-188,136,103,125,123,189,123,254,101,169, 46,207,255,124, 5, 6,185, 87, 66, 11,154, 5,211, 16, 10,177, 95,184, 20,201,160, 1,
-127,101,190,230,158, 9,224, 26, 14,223, 11, 84,104,164, 86, 94, 4, 80,246,118, 24,142,164, 9,116,233,234, 73, 21,154,185,164,
-159,192, 80, 26, 92,120,129,114, 66, 45, 19,112,108,148, 14, 5, 32,207,212, 98,193, 42, 42, 84,124,215, 81, 72,155,221, 9,193,
- 65, 72, 20, 17,215, 28,148,120, 87,175, 78,243,197,251, 30, 0,231,237, 45,126,147, 9,129,211,145,105, 34,105,102, 52, 91, 3,
-120,209,131,134, 98, 53, 53,231,103,145, 38, 51, 20,176, 68,231, 66,114, 34, 71, 50,210,169, 10,217,210,121, 62, 98,233, 66,152,
-107,162,243,249, 34,229, 54, 38,183, 78,197,162,164,225, 91,164, 66,145,203, 46,142, 50,239,117,153, 34,116,114,170, 1, 75, 74,
- 89,242,147, 82,240, 5,101,220,169,143,129, 35,162,189, 88, 97, 1, 76, 53,222, 43,135,141,241, 63,168,210,213, 7,138,102,224,
- 0,122,196,154,237, 81, 2,129,137, 19,110,111, 83, 98, 35,225,103,247, 5, 46, 95, 42, 13, 82, 29,114, 33,146,225,140,202, 69,
- 20,167, 47, 66,153,122,189,200,214, 87,159,239, 31, 62,181,135,123,141,226,192,237,227, 73, 62, 43,150, 35, 37,247, 12, 91, 16,
-209, 58, 48,244, 76, 25, 1,181,203,193, 55,248,123,218, 73, 51,234, 57, 66, 81, 20,241,200,125,118, 79,121,108,246, 3,112,232,
- 93,159,107,128,169,160, 21,240, 17, 7, 83,173,181,135, 69,186,140, 80,208,184,139, 90,143,157,218, 14,181, 17, 66,142,235,196,
-165, 70, 80,162,111,166,232, 86,175,168,249,155,214,141,239, 37, 21,236,116, 87, 1,183, 31,181, 83, 62, 43,221, 34, 42, 51, 37,
- 42,207, 1, 77,126,144,233,152,175, 91,171,113, 50,133, 1, 34, 5, 64, 7,196, 6,251,205,102, 46,143, 76,192,251,160, 87, 75,
-224,228, 9,219, 42,160,145,200,134, 62,233,164,231,204, 40, 69, 74, 45, 57, 65,172,168,146,195, 6, 76,204,111,213,105, 84,240,
-199,100, 73, 64,165,140, 82, 29, 87, 72, 52, 98,174, 40, 58,150,162,112, 78,162,156,190,248, 95, 0,150,174,166, 55,142, 34, 10,
-118,247,124,246,204,110,236,181, 99, 71, 14,182, 54,150, 33,137,225, 20,133,128, 18,137, 3,226, 0, 87, 36,254, 45, 8,164, 72,
-156, 64, 96, 33, 14,112, 32, 32, 72, 28, 7,140,215,235,249,234,238,153,238,166,106,197,125,119,103,102,167,187, 94,189,215,239,
- 85, 37, 39,199,119, 55,217, 16, 88,195,152, 90,172, 55,220,124,194, 89,152, 48, 99, 99,152,242, 45,144,111,112,148, 47,226, 56,
- 33,110, 4, 64,166, 34, 88, 94,116, 9, 88, 31,232,179,233, 39, 15,154,173, 72, 97, 92, 26,140,231, 36,101, 98,170,235,186, 51,
-120,151, 78,103,202, 34, 1,229, 56,130,202, 93,250,219,249,249,151,223,254,249,211,175,238,194,158, 44,247, 30,237,222,123,175,
- 58, 56,185,181,124, 50,219,125, 80, 47, 79,171,197, 7,122,239,169,212,239,190,188, 62,254,254,247,234,155,159,203,175,126, 40,
-127,124,189,124,101,246,250,236, 80,111, 31, 30,104,189,163,145, 1,197, 85, 67,237,176, 30,172,117, 43,189, 69, 73, 22, 79,160,
-207,130, 1, 59,188, 10,107,103,219,174,175,231,237, 91,135,246,193,161, 60,125,232,238,223, 15, 39, 7,253,209, 29,151,135,149,
-237, 56, 21,152,210, 1, 20, 25,148,244,115,164,198, 0,165,144, 9, 33,122,158,243,176,104, 63, 6,218,255, 36,150, 22,154,216,
- 25, 2, 63,108, 61, 13,202,154,237,189,241,241,211,163,157,219,251,231, 47,210,127, 84,107,117, 55, 7, 59, 95,205,235,157,253,
-207,191,152, 47,223,190, 92,189,240,225,218,136, 94,216, 94,245,131,155,204, 52, 52,126,216,173,238,189,255,206,215,103,229,243,
-231,175,192,109, 43, 68, 5,150,178,121, 4,179, 25, 0,230,208,104,204,255, 87,197,166, 11, 50,187,163, 19, 54, 28, 33,107,202,
-169,165,185,153,179, 28,193, 81,240,169,180, 74,117,113, 43, 17,192,244,156,149,207, 58, 84,192,251, 34, 55, 57,118,104,190, 93,
-205, 63,251,104,241,236,209, 31,210,255,210,175,193,166,192,232,156,160,210, 36,214, 8, 59, 32, 21,245, 66, 70,112,186,108,144,
-126,109,109,227,250, 70, 94,253,213,175,174,176,143,252,245,155,169,249, 59,228,255, 38,193, 77, 13, 77,119, 65,209, 89, 16, 23,
- 70,148, 84, 34, 5,117,205, 10, 23,135, 40,174,188, 56, 58, 72, 31,127,178, 40,142,149,209, 17, 57,166,204, 18, 97, 54,133,159,
-148, 14,218,108, 92, 2,173,234,169, 23,183,145,112,166, 23, 72,108, 58,223,102,161, 83,146,221,177, 50,239, 64,164,112,141,144,
-180,200,181, 38,206,109,178, 87, 73, 0,115, 75,173,202, 74,250,122,202,110,103,179,211,103,103, 23, 55,171,117, 11,122,210, 82,
- 25, 36,208, 59,146,138,223, 98,221,142, 26,171, 83,197,110, 0, 82,171, 93, 21,155,203,254, 34, 21, 15,151,179, 59,235,182,197,
-187,219, 21, 14, 41, 61,160,164, 99,213,103, 68, 2, 94,110,232,203,152, 48, 88,128,147, 33,202,150,164,192, 85,205,114, 46,144,
-251,195, 79,151,175,123,125,246,221, 27,133,128, 91,112,194,118,240, 84, 43,193,186,199,198, 8, 41, 24, 11,117,142,107,193,176,
-176, 24,121, 40, 88,217, 17,207,121, 57,210,245, 26, 9, 49,197, 86, 17,250,147,105, 50,148,216, 45,242, 1,128,178,200, 54,134,
- 22,217,141, 7,190, 90,224, 40,143,128,145,211,107,172, 53,167, 50, 4,121, 85,251,100,192,159, 69,165,182,209,116,147,244,142,
- 61,208,214,100,161,231,104,126,146, 31,250,151, 43, 68,144,105, 22, 21,167, 96, 64,138,148,211, 94, 98,251,215,192, 76, 73,213,
-126, 41, 90,159,143,125, 42, 23, 78,217, 52,178,114,138,200, 92, 20,243,177,142,114,136,160, 92, 97, 75,171,118,140,227,192,233,
-127, 9,158, 63, 74,118,175,243, 72, 7,116,139, 22,229, 85, 16, 57, 88,200, 14,112,173,102,134, 94,230,198,103, 97, 83, 77, 6,
- 96, 17,249,227,148,179, 61, 54,150, 35,125, 43,123, 63,233, 24,154, 41,105,129,127, 25,237, 83, 0, 79, 6,251,200, 0, 27,114,
- 78,170,186,176, 15,240,167,234, 55,113, 58, 77,130,158,171, 84, 83, 85, 24, 65, 70,112,114, 53, 43,241,184,243, 52, 34,107, 72,
-199,109,233,247,239, 86,197,147,143,207,193,238, 64, 37, 18,106,157,167,110,134,187, 5,235, 54, 30, 87,173, 74,118, 13, 79,248,
- 94, 18,168,145,234,179,218,228,216, 32, 53, 15, 36, 25,144, 57, 22,155,149,128, 47, 93,201, 14,124,211,200,220,231,185, 86,128,
-238,206,150,192, 12,107, 55,246,222,180,249,181,243,166,188, 76, 98,166,211,104, 12,187, 97, 76,224,193, 60, 16,112, 66,184,196,
-195,106,112, 7, 71,101,125,236, 40,196,234,194,115,184,220,130, 89, 71,188,219,172, 67, 74,126,131, 63, 49, 49, 92,253, 93, 98,
-105,139, 44,233,250, 87,130, 30, 57, 80,124,192, 52,107,137, 99,177,153,198, 31, 64, 49,182,192,106, 51,155,209, 22,172,180,162,
-183, 45,114,185, 18, 28, 25, 47,111, 94, 33, 33,192,106,149,172,180, 40,225, 57,200,201, 67,200, 16,171,114, 66,166,215, 10, 55,
- 0, 93,233, 19, 72, 61,178, 38,128, 30,199, 33, 41,250,162,181, 27,145,211,242,250, 63, 1, 56,186,150,221, 70,138, 40, 90,175,
-174,126,186,109,231, 33, 24, 6, 13, 4,101, 16, 8,129,196, 6,101, 1, 59,190, 2,137, 5, 18, 11, 62,138, 5,223,192, 47,176,
- 64, 44,137,148, 25,105, 22, 3,210,144,104, 38,137, 19,219,253,170,174, 39,231,218, 43, 75,182,236,238,174,170,123,207,169,186,
-247, 28,229,157,151,116, 26,194,216,128,193,225, 72, 39, 18,232,145,220,147, 16,167, 45, 89,151, 49,170,100,178, 70,229, 26,112,
-220, 82, 83, 37,178,115, 78,226, 73,108,139,197, 56, 91, 45,216, 74,242,253, 44,148, 5,125, 29,137,255, 54,128,237,177, 1, 38,
-148,197,228,198,228, 7, 75,165,122,184,164, 26, 65,109, 89, 25,219,252,245,250,213,159,151,151,191,101,205,242,189, 15,150,235,
-234, 9,171,236, 46,206, 75,183,217,226,158, 55,219,153,164, 26,153,239,120,166, 73,245,150,235,154, 79,170,212, 73, 54,231,237,
-234,203, 79,190, 62,251,184,123,234, 54,217,187,235,187,241,110,122, 28,122,204, 20,170,100, 34,143, 35,242,214,117,142,119, 54,
-101,180,134,196,253,176,195, 99, 93,200,217,144,172,103, 77,226, 55, 72, 6,250,160,135, 47,137, 61, 70,150,122, 65, 7,199, 92,
- 57, 18, 10, 2,112, 9,212,243,226,233, 43, 84,168, 11,140, 98,171, 40,145, 16, 38,143,209,241,183,118,118,237, 41,191,248,166,
- 57,251,244,187,223,127,109, 95, 92,253,123, 63, 13,250,105,251,203,207,226,252,139,219,225,174,143, 29, 0, 11, 7,218, 77, 59,
-234, 83,155,145, 26, 76, 56,201,157,159,244,229,223,189,150, 83,173,228,142,142, 40, 15,202, 69,228, 72,137, 80, 75,141, 48,146,
- 42,134,144,170,129,221,200, 47,155,230,129, 6,136, 15,121, 14,130, 64,141,227,146,103, 76,147,148, 91, 19,165, 43,136, 24, 83,
- 63, 9,101,206, 53,240,179, 9, 41,227,197, 89,187,250,254, 91,119,254,249, 63,190,187,178, 19, 8, 36, 21,166, 71, 42,113,199,
-253, 82,225, 15, 2, 61,102, 37,199,136,109,193,163, 67,191, 55,227,198, 63, 76,108,122, 27, 59, 27,231, 91, 27, 31, 88, 54, 82,
-175, 81,126,168,225,203, 37, 27, 45, 53,187, 33,184,155,131, 24,143, 19,192,152,212,107,122,244, 76,124,117, 81,181, 31,170,177,
-155, 1, 84, 65, 39,137,120, 87, 4, 98,145, 5, 56,249,181, 1,204, 10, 95,204,126,196, 4, 34, 17, 33, 58,161,244, 36,198,142,
-119, 22,211,117,207,194, 8, 2, 70,167, 75,150,147, 79, 65, 41,200, 8,155, 52, 11,105, 79,150,142, 16,129,247,215, 85,235,143,
-236,187,215,143, 42, 37,173,227, 4,222, 61, 83,217,215,104,146, 13,201, 52, 73,239,105,211,174,154, 35,208,235, 6, 67, 85,248,
-238,141,253,227,236,253,159, 78, 79,197,221,127,172, 23, 25,137,105,145, 64, 35,130,184, 34, 83, 51, 73,198, 48,101,162, 10, 57,
- 74,232,200,184,193, 91, 79,110,163,179,120,243,242,118,113,114,243,227, 15, 79, 94, 94, 61,123,241,234,166,144,136,182,139,164,
- 88,195,229,108,105, 3,100,192,106, 23,185,176,201, 49,154,169, 91,204, 54,161, 11, 65,242, 50,149, 98, 37, 25, 31,140, 68,181,
-230,131, 97, 77, 78,246, 21,136,245, 10,127, 57, 4, 83,114, 61,131,183,138, 34,155, 0,190,233,108, 23,191,130,156,166, 6, 38,
- 22,149,155,242,108,136,108, 73,202,214, 17, 17,255,144, 86,138,100,241,191,253,112, 79, 98,139, 77,245,209,115,189,191, 25,182,
-215, 82,244, 98,177, 0, 58, 41, 60,174, 68,135,173,203,164,106,143,163, 51,132,185,228,206,251, 64, 85, 78, 41, 32,136,227, 97,
- 11,201, 86, 46,142,237,218, 25,196,148,232,145, 62,195, 90,104,231,198, 34, 1,167, 55, 88, 15,132,171,243, 2, 0,141, 75, 80,
-170, 66,103, 70,199, 56,138,146, 76,180, 88,137, 64, 76,153,125, 53,217,125,142, 24,103,169,221,223,211,139, 59,110, 75,144, 45,
-178,180, 12, 42,204, 33, 59,200,136, 34,208,203, 0, 40, 49, 41, 89, 72, 29,144, 34,105, 23,156,116,202, 1,197,107,145,187,222,
- 91, 60, 55, 14,220,109,138, 99,166,250, 40, 51,234,214,109,132, 5,220,214,121,106, 62,187,120, 56,121,238,205, 91,217, 44,133,
- 65, 6,175, 14,166,119,219, 24, 58,230, 78,141,158,102,189,245,189, 44,243, 74,137, 85, 16, 27,172,157,149,172,167,105, 11, 56,
-178, 96, 21,203, 68,232,250, 36, 49, 2,117, 82, 69,169,178,138,136, 28,146,140, 29,146, 92, 39, 78,213,129,184,246,196,249,130,
- 20, 16,201, 65, 10,232,183,119, 53,134, 32, 91, 46, 2, 73,109, 59, 16,164, 29, 41,126, 62,238, 98, 46, 67, 46,234,130, 79,150,
-236,186, 93,225,237,152,107,149, 26, 47,188,169, 49, 4,170,176,194,121, 0, 28,218, 9,145,158,149, 67,234, 74,218, 73,195, 74,
-206, 61, 50, 47, 98, 76, 43,230, 41, 40, 3, 56, 26,196, 35,185, 45,107,135,216,153,143,248,164,101,182,212, 42,100, 1,108,193,
-216,153, 21,252,184,110,175,189, 95,141, 51,177,218,210, 97,125, 21,126, 0,119,113,110,169,113, 13,202, 76,209, 20, 98, 97,212,
-145, 63, 64,214, 89, 31,249, 21,150, 79, 60, 74,190,249, 95, 0,146,174,101, 71,142, 34, 8,118,117, 85,245,123,167,103,118,141,
-189, 54,214, 98, 35,144,197,193,226, 96,132,144, 17,226,130, 79,252, 36,226, 63, 16, 63,129, 16, 92, 16,178,132, 95, 98,103,118,
-166,167,171,187,170,235, 65, 68,115, 30,237, 72, 91,147, 21, 25,153,149, 25, 33, 31,220,108, 70,201, 69,241,128,155,229, 81, 26,
-129,189, 3, 90,128, 33, 25,242,217, 44,105,219,231, 52,123,128,116,181,176,171,232, 2,174,246, 76, 9, 26, 20,220, 18,101, 28,
- 95,154, 71,154,172, 6, 74, 35,228,122,106,241,129,165, 51, 67,166, 57,165, 27, 92, 89,110, 16,226, 89, 9,228,173, 41,134,124,
-175, 43,218,157,222,102,165, 86,181, 75,119,111,134, 15,195,254,253,219,225,246,221,105,191,248, 59,212,255,248,150,203, 77,117,
-113,121,117,221, 53, 87,156,197,106, 27,181,181, 67,219,136,236,157, 57,254,246,183,249,253, 40, 15,238,163,244,201,199,159, 94,
-150,253,113,220,159,206, 35, 35, 9,165, 15, 66, 68, 44, 40,188,106, 86,162, 33, 1, 68,217, 5,102, 55,194,131,154,112,194,137,
-117,171,206,129,151, 20,191,152, 22,190,190, 51,217,177, 27, 12,106, 11,102,154,115,165,136, 77,121,166,127,164, 43, 4, 90, 62,
-231,171, 52, 21, 71, 2, 11, 35,146,166, 56, 87,118,216,110,210,139,151,143,159,253,240,252,112,234,190,249,194,124,253,114,156,
-222,152,229, 52,230,167, 76,236,233, 6, 49,162,148,195, 33,217, 0, 22,223, 63,190,127,144, 15,126,250,249,159,201, 89, 5, 40,
-144, 8,106, 14, 10,113,243,130,123,219, 92, 55, 77,124, 9, 88,105,165,206,194,234,151,141,195,224,188, 19,117,104,104,172, 25,
-202, 70,226, 80, 11,122,117, 0,215, 91,145,182, 93,115,113, 81, 22, 77,143, 63, 25, 42,245,213,231,247,126,124,149,110,158,254,
-105,143,239,151,217,112,232,107,101, 48, 64,229,132, 42, 65,204,105, 30, 5, 40,155,165, 33,178,221,251,179, 73,163, 9,167, 41,
-191,187,181,195,191,243,252, 58,197, 61,232, 74, 50, 67, 0,103, 36, 12,219,213, 40,151, 47,222, 43,242,182,220, 3,195,137, 57,
- 54,213,227,183,223,247, 15,159,180, 67,253,191,130, 23,200, 10,126,102,130, 56,241,125, 33, 29,195,161, 6,176, 17,147,121, 19,
-168,249,126, 84,193,208,203, 20,161,201,177, 49, 35,139,129,111, 68,220,213, 29, 11, 53,164, 22, 39,226,169, 84, 19, 27, 54,103,
-100,151, 27, 84,220,151,238,201,179,155,253,238,250,143,191,142,248, 29,230,115, 6,202, 96,139, 5,183,198,131, 67,154, 40,169,
-252,129,255, 45,156, 20,138, 74,155, 79,177,119,168,117,236,235, 67,250,242, 81,221, 47,135,217,198, 82,151, 82,132,172, 13, 72,
- 14,244, 29, 64,149,230, 16, 22,244,102, 64,172,218, 21,116,216, 36,147,244, 4, 67, 85, 60,236,111,159,190,232, 31, 61,255,236,
-151, 95, 39,119,247, 1,192,198,124, 15, 22,159, 40,224,101,184,168,130,220, 45,162,166, 55,180, 63, 11,246, 96,202,200,165, 42,
- 95,243,124, 86, 3, 13,238,175, 71,209, 75, 92,136,188, 74,149, 67,193, 45, 93,217,117,156,128,169,112,175,133, 26,180,215,161,
-232, 72,131,233,227, 27,194, 60, 27,170, 56,224, 8, 57,201, 41,140,157,131, 79,113,140,168, 28,192,203,172,247, 7, 51, 30,138,
- 98,215,110, 31, 78,241, 24,198, 91,220, 86,155,167,245, 57,131,187,131, 69, 38,122, 16,108,157,140,173, 41,168, 21, 91,193, 23,
- 29,165,147, 44, 89,168,251, 54, 86, 86,137,137,201, 59,149, 69,198,165,125,142,101,229,190,168, 0,135, 35,247, 5, 74,147,137,
- 58, 3,122,171,229,140,176,209,124,128,160,158,149,164,104,187, 66, 25,135,154, 70, 53,193,123, 96,184,163,105,108,167,188, 32,
-198, 87,182,116,214,118, 51, 85,125,194,201, 95,120, 41,129, 92,115, 42,168,117,184,142,151,121, 34,123, 85, 32, 33,101, 20,131,
-149,158, 64, 47,164,196,165,140, 82, 37,246,250, 47, 98, 80, 59,220,175,112,117,255,186,252,238,213, 91,176,116,115, 18, 57, 85,
-128,163,115, 39,177,209,203,101,235,250,141,188,222, 21, 87, 59,127, 35,230,205,232,202, 15, 62,242, 13, 34, 44,148,142,195,193,
-183,178, 27,155,180, 58,160,102,162,237, 87, 21, 18,132, 21,231, 26,115,182, 93,155, 57,212, 92, 10,174,211,236, 93,205,203,205,
-217,152,164,202, 65, 45,149,202, 42, 92,188,218,134,187,210,112,114, 13, 28, 62, 47,116,157,167,190,145, 3, 16, 28,240, 65, 19,
-117, 9,198, 72, 51,153,197, 73,195,205, 77, 54, 88,231,188,148,203, 28,171, 10,161, 89,209,119, 52, 32,101,137, 51, 87, 89,178,
-122,161,236,144, 43,168,210,137,244,192, 45, 21,117, 14,171,178,169,142,171,228, 97, 4,228, 2,170,252,200,229,168, 85, 47,221,
-226,210, 32,117,166, 35,106,156, 41, 55,115,237, 20, 5,100, 5,130, 44, 78, 94,115, 84, 6, 33,152,245,168,128,124,165, 23,181,
-232,173, 79, 22, 40,133,192,254, 79, 0,146,174,101, 55,142, 34,138, 86,117,117, 85,191,102, 50,211,142, 99, 99,108, 39, 74,226,
-196,137,242,146, 16, 98,137,132,196,138, 53,191,200,146,207, 96,205, 6, 88,194, 34,114,132, 67,176,103,156,153,238,174, 55,231,
- 52, 59,175, 70,237,122,220,123,206,173,123,207, 81,253,209,105, 21,144,175,144,215, 34, 49, 44, 93,238, 0,221,203, 72, 49,248,
-130,182,183,200, 95,105,208,224,203,129,210, 86,123, 69,125, 72,201, 33,120,246, 14, 35, 35, 27, 96, 33, 75,101, 62,186,145,148,
-185,169, 64, 90,141,106,124, 91, 54,108, 57,213, 56, 0,102,209,253, 31, 93,170, 64, 80,102, 92,162,217,163,238, 26,144,171,149,
- 42, 30,244,205,178,235,187,131,190, 95,119,253,106, 81, 53,171, 99,131,243, 11,104,221,204,235, 78, 45, 17,173,166,160,213,170,
-169,211, 50,130,158,237,255,141, 31,182,183,191,125,144,183,113,117,126,124,130,205,211,251,205, 30,232,171, 45,114, 67,105, 14,
- 79, 77, 46, 85,123,250,196, 72,195, 73, 95, 26,156,114, 34,142,106,192,194,167, 10,209,183,192, 70, 10, 34, 58,240,148,217, 31,
- 16, 48,146,243,128,116,191,155,133, 48, 10, 86, 74, 88,183,195, 13, 44,117,154,221, 94,104, 93,132, 95,192, 34,249,100, 71,208,
- 24,251,160,245,223,124, 53, 93, 60,252,199,222,221,216,109,148, 59, 82, 2,207,243, 62, 34,130,225, 82, 58, 86,107,212,253,167,
- 15, 55,249,240,167,159,255, 94, 84, 56, 84,130, 58, 29,197,220,122, 14, 84,194,121, 0, 36, 20,186, 49, 11,138, 3,224,158,165,
-249,229,151,179,161, 51,106, 82, 64,128,134, 29,144, 20, 84,104, 22,149,169,171,110,161,187, 5, 54, 6,144,221,136, 49,136,133,
-248,238,117,255,227,183,238,222,250, 15,119,115, 53,129,181, 20,236, 31, 21,108,234,162,170, 82, 25, 6, 57, 80,254,161,216,201,
-124,231,135, 77,112, 55,241,110,242,159,110, 67,248,104,227,159,110,252, 4,176,147,216,102, 15,150,184,203,203,137,226,185,131,
- 5, 17,164,224, 34, 45,155, 51, 27, 23, 29,123,211, 4,240,253,229,171,238,226, 77,251, 25, 89,160, 7,236,211,108,198, 23, 51,
-188, 67, 58,209,236,219,139,128,119,145,218,206,193, 17,175,227,139,252,150, 99,228,190, 42,210, 86, 83,100,219,226, 80, 81, 49,
- 2,212, 89,222, 25,176, 92, 10,165, 91, 58,120, 91,138,167,241,125, 82, 84,226,222,162, 56,122,251,242,119,223,223, 92,253,133,
- 36,239, 45,118,128, 79,190, 49,208,202,145,206, 19, 49,236,176, 23, 99, 98,119, 48,176, 61,150, 83,225, 47,182,228,188,124,177,
-126,220,237, 63,150, 27,228, 73, 55, 18,170, 40,195,119,129, 50, 40,160, 78,218,113,104, 62, 20,148,137,167, 87, 34,169,212,172,
-212,149, 74, 59, 59,217,247,241,213, 15,171,243,199,135,191,254,178, 9,159, 57, 89,163,199,194,178, 66, 75,203, 9, 14,117, 53,
- 98,154, 24, 10, 35, 11,107,146,209,212,103,185, 12,147,116, 6, 11, 98,240,243,228,186,201, 33,144, 21, 84, 48,157,170,130,164,
-216,152,206,209,209, 3, 65, 70,216, 76,139, 14,220,136, 50, 20, 27,150,232, 75, 14, 59, 33,249,243,113,222, 69,190,186,228, 48,
-237,183,174,197,135, 70, 55,133, 97,212,215,187,226,202, 14,237, 65,123, 82, 54, 10,184,175,180,114,129,157,174, 67,159,107,224,
- 0, 71,227, 70,181, 66,216, 86,180, 49, 97,159, 64,169, 59,234,212,129, 84, 25,186,133,198,212,209,193,141,255, 57,206, 50,118,
- 10, 60, 6,215,123,237,169,239,217, 34,200,150,192,206,147,215,181, 98,185, 47,216,138, 42,189, 38,211, 94, 88,137, 84,143, 8,
-109,115, 83, 84, 73,103,118, 16,131,145, 99,229, 59, 92, 43,155,173,194, 50, 75, 65,219,100,164,109,121, 13, 52, 3, 2,210, 25,
- 0,253, 58,139, 37,226, 7,214,112, 22, 69, 69, 98, 5,161, 95, 74,160,239,130,130, 90, 85,137,175, 31,234,234, 80,184,178,147,
-205,129,186,127,249,253,248,252,145, 31,175,233, 92,203,231,233,245,147,254,236,197,233,151, 95, 63, 45,222, 60, 43, 47, 47,226,
-243,179,248,236, 81,120,125,238,222,125,113,246,100,121,116,146, 78,139,124,140, 79,169,248,198,184, 92,228,134, 42,188, 9,121,
-211, 18, 47,243, 97,102, 54,135, 15,217, 21,210,230,214, 39,228,211, 49,237,119, 57,153, 53,171,216,192, 84,161,193, 6,198,138,
-227,148,185,171, 65,146, 85, 48, 19,144,104,166, 52,154, 23, 86, 78,110,147, 59, 42, 34,130, 72,108,154, 33,251, 42, 33,144, 36,
- 47,181, 30, 58,225, 50, 11,169, 98,139,216,141,108,134, 91, 12, 20, 52,134,145, 51,210,116,199,145, 46,105, 0,203,118, 35, 84,
-163, 17,111,231,217,172,192,160, 66, 86, 19, 60, 34, 29,248, 5,141,180,216,128, 89, 69, 16, 22,160,170, 42,178,199,222,234, 58,
- 21, 75, 51, 52, 26, 23,135,233, 26, 8, 10,148, 11, 95,133,219,144, 35,149, 32, 92,213,234, 28,100,205,113,195, 0,198,244,159,
- 0, 36, 93,203,142, 27, 85, 20,188,125, 95,253,244,140,199,137,130, 18,133,128,152, 16,177, 64,192, 2,177, 0,132,132,144, 96,
-197, 15, 35,177, 1, 33,148, 69, 96, 17,164, 40, 72,108, 66, 30,243,112, 60,182,187,221,125, 95,221, 77,149, 89,142, 44,141,103,
-220,247,158,170,242, 57,167, 74,221,127,176, 74, 54,160,178, 12,116, 9,162,221,208,120,156,204, 18, 56,157, 96,127,133,118,146,
-201, 21,186,196, 85,200, 5,109, 38,241,231, 24,230,149, 49,120, 1, 69,111,102, 42,159,149, 56,160, 98, 96,218,148,194, 59,250,
-178, 80, 3,136,144,172, 76, 46,101,201, 80, 90, 25,112,145,115, 40,178,106, 58,107,169,191, 24, 34, 32, 85,131,162,191, 84, 83,
-227, 11,215,224, 42, 55,133, 5, 72, 27, 77,199, 29,118,116,108, 93,140,204, 26,196, 61, 58,109,204,202,148,237, 46, 54, 80, 1,
- 9,216,161,241, 8,250,120,125,189,255,103,200,111,150,239, 60,108,170,179,184,222, 93,161,174,114, 7, 92,105,105, 29,160, 91,
-133,226,152, 45, 65, 15,155,160, 3,179, 29, 56,179,223,139, 49,167,175, 17,208,222, 70,134, 37,115,172,159, 40, 0, 89, 2, 64,
- 81,199,144, 14,166,204, 36, 0, 42, 19, 35,217, 87, 60, 46, 51,208,197,144, 54,122,130,138, 90,204,135,208,254, 59, 92,188,244,
-237,171, 3,234,101, 55,203, 1,138, 78,197,203, 24, 14, 12, 22, 5,226,116,116,199,198,103, 33,207,239,223,123,190,182, 63,255,
-180,109,128,239,204, 4,103, 60, 58, 81,133, 13,146, 4, 4,239,193,218,254,103,188,184,134, 32,155,126,180,204, 82,152,128,241,
- 52,130,135,178, 90, 9, 46, 64,230,181, 62, 1,151,170,106,160, 90,108, 80,139, 82, 94, 53,227,226,251,239, 86, 63,126,125, 35,
-229,159,253,110, 67, 55, 11,124,220, 76, 89, 76,212,204,168,199,157, 23, 28,229,215,194,187,184, 77,253,229,136,170,254,118, 39,
-250,139,195,230,239,121,253,194, 79, 7, 14,142,133, 46,233, 20,153, 91, 6,109, 19, 64,212, 4,161,157, 11,180, 92,182,146,185,
-102, 31, 29, 63, 12,227,249,167,230,139,175,154, 88,170,233,246, 4,133, 10,217, 42, 42,118,130,102, 77,155, 91,206,188, 50,100,
- 53, 3, 49,198,253,135, 18, 24,250,228, 15, 34,238,147,107,211,180,205,228, 14, 68,116,118, 14, 64,168,170, 97,100,158, 6,145,
- 40,249,173, 8,145,111, 90, 86,162,106, 40,209, 85, 53,149,183,237,157,207, 30,254,246,194,109,135, 54, 89, 99,123,141, 58,221,
- 91, 70, 87, 13,242, 32,244,228,183,160,101, 28,182,162,235,159,156, 74, 60,199, 68,159, 59,186, 90,221, 93,125,217, 20,211,198,
-113, 99,200,219,172, 25,129, 64, 66,225, 85,240, 92,246, 52, 24, 84,157,232, 5,203, 35,129, 26, 9,140,101, 63,146,216,126,232,
- 58,115, 35, 63,254,225,253,235,185,254,235, 9, 52,200,129,126,133, 16, 36,122,182, 54,243,123,112, 46,154,168, 44,140,109, 59,
-208,216,168,142, 13, 55,166,202,115,169,144, 86,115,189, 55,242,100, 68,177,164,141, 59,119,117,241,154,203,117,214, 91,171,246,
-158,182,163,167,252,246,217,137,102,244, 9,229, 35,224,180, 74,198, 83,179, 91,159, 59,232,199,121, 8,173,162,124, 78,121, 41,
-167, 33,236, 56, 59,221,236,251,238,166,125,126, 8,241,244,214, 39,119, 74,125,245,230,109,235, 33, 76, 77, 45,179, 61, 27,144,
-185,136,118,158, 71,174,118, 49,171, 18, 31,141,117,236,215,114, 60, 14,220, 21, 71,186,144,116, 54, 8,137,185,200,236, 63,114,
-139, 66,210,100, 99,244, 49,174, 52, 21, 3,200, 76,141,255,193,251,160,162,174,161,183, 32, 18,248,189, 37, 51,183,167, 81,213,
-126,112,102,100,170, 67,206,124, 17,211,235, 0,121, 12,158,199, 45,124, 90,178, 9, 57,128,151,232,108,145, 49,190,120, 28, 50,
-212, 58,156,231, 33,159, 87, 96,254,147,132,238, 65,157, 85,228,198,145,131,186,185, 58, 81, 54, 3,142, 44, 83,165, 5,112,213,
-126,243,237, 90,184,201,119,147, 56,255,224,228,209,231, 31,153, 7,239,189, 94, 86,143,205,230,151,110,253,107,127,249,135,127,
-249, 36,110, 31,103,253,239,121,122,122, 54, 61,189,251,238,179, 71,167,198,200,123,179,255,240,170,127,227,138, 11, 91,227,183,
-211, 65,128,211,167,162, 44,237,130,171,136, 44,239,205, 2,108,125,242,146, 17,168,184, 79, 43, 69, 51, 48, 47, 92,233, 22, 33,
-171,114,229, 34,132, 12, 30,216, 6, 60, 67, 50, 14,202,209, 52, 87, 50, 55, 84,234, 26,178, 54, 26,167,217, 55, 53,193,224,209,
-177,196, 50,189,179, 96, 72, 51,109, 60, 37, 4, 84,162, 76, 4, 30, 42,214, 99, 46, 99,131,233,104, 16,181, 29, 91,161,245, 50,
-201, 43,148, 6,202,221, 0,213,165, 80,141,122, 59, 50,187, 44, 58, 46,176,114, 73,178,233, 44,234, 45,232, 79,226,170,160,243,
-177, 51, 86, 59, 19,128,226,190,143, 21,240, 54,171,163, 28,157,189, 5, 90, 98, 80,114, 12,212,132, 43,184,112,138,123,104,254,
- 19,128,163,107,233,141,163, 8,131,211,175,153,158,217,245,122,109, 69, 94,135, 4, 12,129, 75,132,224,134, 0,241, 7,224,140,
-196, 47,229, 39, 32,129,196, 13, 69,194, 39,164, 56, 32, 18,178,218,167,103,122,122,250, 69,213, 28,124, 91, 75,246,246,215,253,
- 85,117,215, 87,165,110,111,150,102, 4,134, 22,244, 88,227,235, 51,197, 95,232, 15,116,224,203,185, 86,150, 83, 70, 21, 31,101,
-233, 60,213, 21, 99, 34,190,127,219,168,121,252,181,107,116, 6, 79,167,193,150,236,240,179,222, 24, 29,233, 22,210,110,240,201,
-141, 85,181, 15, 19, 64, 20, 42,117,126, 54,172, 24,155,134,102,141, 37,125, 22,173, 4, 24, 53,105, 17,219,117, 81,186, 93,121,
-195,200, 87,240,157, 22,204,231,162,177, 98,236, 36,143, 66, 26,159,250,165, 30,121,186,142, 49, 97,235,197, 92,151,110,240,131,
-197,206, 8, 98,231,198,191,254,243,135,225,234,238, 99,123, 35,207,199,145,246,172,198,154,166, 20,135, 3,131, 87, 98, 50, 15,
- 50,170,249,188,155,101,255,156,235, 81, 81,240,198, 93,248,222, 80, 15,130, 69, 68,225, 50,138, 7, 11,165,152, 63,220, 42, 62,
- 55, 21, 26,242,232,196, 56, 35, 38, 16, 50, 40,149,186,191, 25,194, 83, 74,194,139,136,228,233, 77, 31,163, 26, 68,102,138, 98,
-164, 80, 76, 74, 13,228,190,231, 27, 83,152,138,107,196,205,211, 79,238,119,229,215,223,183,139, 11, 63,171, 7, 43, 91, 89, 79,
- 97, 38, 51,153,192,109,193, 45,121,249, 9, 0, 64, 47,224,106, 2,164, 83,117,114,165, 65,141, 88, 84, 71, 99, 42,217, 94,234,
-186,181,118,200,235, 11, 99,175,171,253,108,118,243,217,102,249,211, 15,203,239,190,122, 83,197,251,254,248,152,105,150, 44, 36,
- 19,115, 38,210, 17,134, 49, 68, 51,118,128,223,233, 81,134, 67, 62, 12,121,120, 23,134,135,184,219, 78,195,155,236,222,167,195,
- 46,231, 93, 69, 18, 16,242,212, 87,206,129, 50,242,112,151,243, 0, 30, 21, 55,153,130, 72, 57,115,129,237,144,110, 46,245,203,
-111, 87,234, 41,106, 47,131, 23,162,107,170, 80,199, 58,209,174, 72,242, 89, 26,191,150, 3,190, 61,252, 59,105, 2, 49,118,156,
-221,215, 30, 37, 60,225,208, 10, 94,244,134,202, 60,195,167,169, 42,143,211,145, 98,176, 80,176,135, 28,199, 93,181,174,168, 62,
- 88, 40, 80, 65,177, 26,151,119,151,237,231, 95,252,246,176, 21,248,230, 66,232, 11, 93, 18,206, 11, 83,124,160,247, 34,179, 16,
- 4,253,244,176,116,147,156, 28, 57, 79, 25, 10,168, 38, 48,228,195, 94,189,248,116,113,103, 79,199,248,152,104, 77, 13,150,203,
-100,213,180,226, 66,115,116, 10,120, 34, 36,209, 73, 32, 9,166,249, 37,146, 21,176, 10,236, 47,176,206,211,249,248, 65, 83,125,
-253,227,243,183,219,171, 87,127,188,139,205,164, 90, 53, 77,188,233, 25, 29,243,109,241,201,100, 77,180, 20,212,207,198, 96,128,
- 44,197, 90,244,144,188,178,156,188, 71,145,100, 98,251, 10,223,211,162,161, 1,211,130, 41,185,153, 49,116,157,174, 53, 13, 87,
-169,255,150, 73, 75, 62,158, 81,127, 3, 76, 22, 74,100,212, 3, 80, 89, 74,182,169,142, 33,156,250,192, 6, 96, 14,104,211,193,
-159,208, 44,131,255, 27,160, 66, 47, 62,172,155,182,239,169, 79,225,131,107, 93, 93,233, 88,235,204,120, 18,128,185, 60,129, 23,
- 21, 54,195,217,207,221, 56,149,231,123, 52,234,146,139, 53,115,122,112, 67, 11, 42,236,120,186,254,170,226,218,174, 54, 39,172,
- 10,136,122,182, 35,119, 69,109, 61, 47,163, 18,227, 67, 26, 42,189,105,157, 33,203, 25,199, 12, 61, 68, 27, 58, 78,197,156, 27,
- 26,193, 14, 96,193,130, 73,174, 65, 48,201, 73,196,126,164, 6, 27,172,105, 80, 57, 2,228,185,106,161,153, 28, 54,143,174,103,
-213,152,216, 49,159,171, 54, 12,216, 54, 38, 47, 86,211,122,181,190,254,230,251,211,237,117,120,127,126,210,222,125,249,114,243,
-209,179,127,205,244,243,240,231, 47,251,215,175,251,163,243,227,236,112, 8,178,224, 69, 60,103,119,246,251,237, 63,233,244, 86,
-250,251,219, 39,175, 94, 92, 52,162, 60, 63,250,149,136,174,229,196, 87,160,101, 85,165,172,200, 62,209, 53,161, 56,252, 77, 35,
-186,160, 13, 10,231, 12,120,209, 16,119,104,244,216, 36,168, 0,211, 99, 39,140,125,156,134,131,138,227, 82,246,185,218,165,252,
- 24,183, 81,156,242, 73,119,189, 51,124, 19,167,228,164,230, 20,142, 7, 17,168, 83,196,134, 67,167, 98, 37, 78,128,102, 49,142,
-212,142, 70,234, 45, 3, 3,210,121,227,133, 51, 30,204, 5,200, 41,211, 88, 3, 64,219, 17, 75, 14,124,134,158, 98, 66, 19, 86,
-168,252,214,129, 71,215,217, 36, 84,203, 56, 36, 54, 98,169, 82, 77, 28, 12,196, 82, 11, 27, 44,237, 90,179,163,244,253,124,210,
-245,158,190,177,242, 76, 85,195,208, 93,106,222, 52,114, 13,100,245,191, 0, 36, 93,203,142,220, 68, 20, 45, 87,149,203,101,187,
- 95,243,232,204, 48, 36, 48,201,228,193,104, 80,132, 0,161,108,144,144,216,176, 97,207,119,178,103,195, 14,177, 68, 89,128, 34,
- 5, 80, 2,173, 73,102,166, 31,110,191,170,202,197, 57,102,215, 26,245, 72,110,251,214, 61,231,248,222,123,174, 58, 61, 63,230,
-166, 83, 14,229,135, 12, 23,101, 27,168,138, 72,225,155, 70,203,169,117, 8,123, 46, 41, 12,121,153,133, 34, 3,169, 10, 45, 16,
- 4,231, 88,165,129,139,250, 36, 40,109,167,100, 86,232, 34,119,137, 46,129,137,198,100,117,219,221, 65,178,212,239,121,119,229,
-201,233,217,225,108,122, 86,116,174,107, 45,117,233, 70,226,147,104, 11, 83,122,221,106,107,139, 98,150, 67,170,245,101,171, 51,
- 39,202,177,194, 0,185, 57,207, 14,134, 2, 68, 16,231, 2, 12,184, 51,185,155,114,164, 62,149,222, 2,204, 18, 95,208, 89,149,
-211,111, 32, 95,171,235,254, 54, 44,206,150, 71,199,118, 37,182, 29,242,112,115,196, 87, 30,192, 62, 57,167,149,113,146,176, 57,
- 69,112,199, 84,159,114, 56,133, 47,222,217,221,165,161, 44,144,156, 60, 89,122,154,106, 96, 66,218,177, 93, 36,142,134, 97,100,
-249,130,150,156,116,235,166,126, 17,238,127, 95, 39,217,211,131,159, 22, 85,252, 70,239, 17,106, 98,207,240, 9,251, 16,119, 81,
-180, 28, 18, 64, 72, 65, 55,248, 13,212,215,240,241,249,135,127,175,229, 79,191, 54, 22,120, 67, 43,247,216,211, 94,137,198, 15,
- 17,119, 25,162, 8,170, 42,165, 77, 24, 55, 16,105, 74,108,174, 70,158, 73,142,130, 66,174, 23,172,138,218, 18, 15, 1, 0,137,
- 75,207,157,231, 12,250,139, 7,246,135,239,253,147, 79, 94,245,213,239,213,190,163,187,175,107, 25,165,109, 39,183,163,145, 27,
-180,222,166, 65,166, 11,183,190,190,238,183,107, 87,247,161,222,245,208, 66,219, 85,183, 89, 57,189, 7, 3, 24, 10, 32,147,103,
-207,164,239, 8,229, 78,137,188, 29,205, 42, 53, 11,131,100,228,124,103, 37,118, 85,200,151,226,203, 47,202,242, 35, 67,183, 62,
-203, 38,103, 93, 22,195, 68,166, 19,142,214, 69,150,137, 45, 4, 17, 87,227,176,103, 25,161, 27,194, 14, 1, 46, 58, 15,233, 62,
- 12, 85,226, 32,231,247, 49,237,113,128,112,119,232, 99,131, 39, 96,118, 45,215, 69,117,236, 85,159,120,242, 36,246,165,210, 27,
-211, 45,159, 94,188,150,203, 63,223,190,209,227,104, 12,141,252, 56,225,111, 84,237, 2,206, 39,103, 95,117, 93, 13,129, 6, 23,
-206,226,156,128, 33, 88,192, 3, 45,161,111,110,122,177, 40,191, 58,205,135,127,170, 48, 17, 36,152,172,120,114,233, 39, 43,134,
- 53,237,152, 34,205,131,164, 48, 46,221,104,246,119,155,152,101, 8,116,101, 12,224,199,111,174, 55,203,199, 7,159,125,253,232,
-213, 47,226,221,230, 95, 16,227, 18,164,211, 10, 46,182,193,179, 50, 81,245,222,121,178, 96,154,189,166,177, 0,158,245,209, 73,
-174, 22,176, 9,155,174,249,226, 89, 24, 81, 34,201,245,251,169,200,198,255, 2, 18,166,205, 64, 79,217, 72,244, 6, 34,212, 44,
-245,138,190,193,181, 32,227,171,180,170,131,107, 6,173,107, 71, 87, 54,159, 41,232,193,174,170,251, 53, 97,209,143,171,210,170,
- 91,255,242,175,106,103,167, 23, 79, 63, 56,218,175,215,198,179, 19,137, 91, 53,104,113,233, 92, 90,114,124, 85, 50,243,114,104,
- 82, 65,109,176, 51,209, 64,254,112,218,136,125,210,195,144,227,111,116, 90, 77,172, 21,154,156, 90,149,160,127,165,225,233,230,
- 0, 66, 96,230,151, 78,141, 59,104,108, 99, 67,146,212,236, 1,229, 50, 80,221, 5,207,122,148,162,153,253,142,181, 26,252,154,
-208,141,182,115,158,104, 88, 34, 62, 58,128,136, 31,103, 5, 21,173,222, 99,172, 10,154,117,171,113,153,168, 41,227, 2,172,202,
-208,137,220, 72,121,176, 72,204,129,186,127,249,194, 93, 93,220,185,187, 67,245,240,249,165, 42,213,143,219, 63,126,222,174, 94,
-187,174,140, 56,214, 68,161,200,250, 25,178,188, 6, 14,114,133,202, 16,114, 92,117,179,211,110, 91,169,228,183,251,247,252,209,
-244,164, 90,159,212, 56, 53,172, 63, 89,205,141,170,142,133,182,136, 95, 93,246,220, 73, 48, 65, 46, 0,254, 34, 92,161, 93,102,
-118, 1,241,213,200,116,179,222,206,228,229,243,233,179,171,243,217, 55,159,222,251,238, 34,255,246,217,227,207,159, 28, 62, 92,
- 28, 63,152, 92,205,119,197,155,119, 73, 31,111,222,179,138,140, 52, 44,115,160, 4, 40, 60,104, 14,158, 38, 23, 27, 71,157, 65,
-235,118,194, 53,129,195,255,166,213,190,177,251, 14,113, 30,112,242,145,111,172, 85,177, 66, 62, 23,217, 14,231,192, 78,141,114,
-185,158, 82, 52,123,114,201,249,144, 53,137,209,156,173, 80, 20, 98, 28, 32,224,244,119,110,216,240, 53, 99,177, 38,177,180,152,
- 45,134, 44,207,193,191, 60, 24,212, 0, 49,161,216,228, 83,139, 66,228, 94, 77,231,211,255, 4, 32,233, 90,118,228,168,161,168,
-171, 92,101,215,171, 31,211, 25,134, 76, 52, 48, 18, 19, 65,130,120, 9,132, 4, 18,240, 7, 89,176, 65, 66, 72,136,111, 96,195,
-111,241, 3, 40, 11,196, 34, 27, 54, 36, 67,194, 40,202, 0, 73, 24,230,221, 93,143,238,178,203, 54,231, 20,155,222,149, 84,237,
-242,189,247, 28,251,222,115, 18,142,105,210, 74,154,144,186,183,113, 47, 81,235,170, 88,183,138,194,179,156,149,231, 62, 27,216,
-131,156,198,161,225,184, 89,153, 75,173,166, 62,239, 29,128,175,226,149,212, 44,247,109,133,141,229, 75,236,232, 33,227, 5, 71,
-210,109,125,114,251,189, 79,223,152,190,246,161,122,125, 81,238, 76,145, 42,231,200, 59,189, 21,215,114,243,236, 80, 61,124,124,
-252,232,164,190, 54, 47, 64, 87, 1, 18, 40,163,146,150, 81, 87,150, 85,195,166,212, 9,175,150,121,223, 95,128, 91, 53, 20, 92,
-235,128, 63, 65, 25, 53,234,157, 72,138,222,164,194,157,249,114,205, 9, 36,171, 64, 72,132,236,159,188, 60,239,211,189,123, 7,
-119,111,234,195,147, 43, 35, 95, 65, 78,214,161,224,202,240, 34, 19,223,222,209,244, 68,209, 6, 41,248, 41, 17,152,232, 0, 57,
-233,153,105, 17,226,128,248,142,217, 9,152,138,238,147, 60,217,192,210,196, 9, 74,167,113, 99,158, 15, 94,211,199,218, 5,148,
- 79, 67,241,150,154, 18,227,116, 38,197,238,237,132,165, 44,247,168,159, 71,174,230,193, 57, 91,177, 9,215, 32,181,169,209,177,
-155, 83,152, 8, 79,150, 46,216, 44,244, 81, 70,125,246,255,165,199,217,250,129,162,139,176,163, 36, 33,107, 8,130,135,130, 77,
- 32, 98,113,208, 42, 2, 67, 76,146,197, 28, 44, 56,163,133,231, 76,219, 97, 2,244,243,197,187, 91,223,221,115,197,141,167,155,
-139,191,128, 64, 56,201,144,142, 55, 4, 45, 42, 27, 71,240,221, 26,240,198,152, 54, 30,120,159, 57, 0,108,181,245,186,107,237,
-213,243,104,221,154,245,185,104,234,136, 71,162,198, 93, 33,103,244, 66,245,168,232,226,106,156,232, 69,146, 93, 83,175, 5,212,
- 43,218,108,128,134, 73,216,187, 88,124,254,118, 57, 63, 80,171, 28,192, 61, 74, 42, 90,216, 35, 60,134, 4, 72, 49,161,154, 74,
- 25, 25,246,191,136,144,103,225, 50, 66,173,165,205, 24,135,170,232,204, 70, 87,192, 66, 82,112,186, 29,197, 39, 64,203, 27,188,
-151, 0,233, 34,243,227,100, 33,143,134,236,104,101,168,167, 58,104, 43,231, 66, 47, 14,142, 86, 64, 81,106,138,154,102, 68,106,
-136, 11, 65, 23,128,148,122, 63,168,141, 29, 89,151,203, 37, 5,186, 86,241, 56,255,135,186,219, 1,164, 68, 85,212, 61, 58,188,
-252,253,173,221,119,182, 38, 23,161,217, 8, 53, 72, 10,164, 36, 32,209, 28, 41, 99, 23, 61,144,105,140,178,189,144,238,192, 73,
-154, 73, 69,116,217, 2,184, 65,232,172,147,250,202, 62,254,241,225,157,111,221,215,223,223, 60,254,225,246,233,217,145, 47,155,
-212,103,248, 95, 32,219,114, 26,219,152,189,229,202,130,142, 6, 19, 98,128,159, 66,186,202,197,161,239,145, 88,145, 70,145, 65,
-163,229,198,105, 69,227, 39,225,203, 12,140, 46, 43,102,224, 50,190,213,249,220,137, 62,205, 5,232,203, 90,178, 2,225,195,201,
-124,101,125, 1,160, 47, 43,175, 55,110,104,115, 19,129, 28,118,180,168,193, 58,132, 13,150,167, 72,211,165,108,138, 40, 51,245,
- 79, 79,204,203,116,239,171,253, 91,219,254,114,245,212,133, 34, 23, 83,141, 64,236,216,245,171,141,231,244, 92, 86,120,218,156,
- 17, 84, 0,197,199, 69, 66,233, 51, 74,162, 53, 61,118,140, 74, 98, 5,152,102, 82, 3,226, 16,154, 75,157,129,154,177, 5,198,
- 24, 80,244,204,135, 6,149, 34, 80,244,144,221,151, 83,145,182, 67, 37,134,101,224,213, 96, 54,227,249, 97,109,250,124,108,191,
-105,149, 71,221, 69,178, 83, 54,244,169,191,182, 1, 43, 14,196,219,230,162,164, 47,164,141, 82,188, 51,163, 41, 30, 69,195,145,
- 65,120,230,225,121,158, 31,235, 65, 42, 89,220,216, 13, 31,188,127, 17, 87,147,176,247,230,157, 58, 29,126,185,252,227, 55,219,
-166, 82,168, 72, 35,208,176,170,126, 28,156, 85,252,197,195,174, 13, 73,171,227,209,151,150,242,183,147,186,195, 27,254,124,235,
-213, 99,185,248,230,193, 50, 23,242, 20,149, 40,179, 62, 87, 52,176,110, 73, 45,235, 45, 98,131,158,238,203, 86,116, 94,207, 56,
-191,183, 60,127, 49,148,147,157,143,247,182, 63,187, 91,164,219,127,138,254,153, 48, 39, 98,248, 87,240,116,126,216,169,118, 69,
-245,145, 16,245,151,103,251,191, 30,237,223,127,112,250,124,246,119, 19,173, 82,155, 72,144,195, 89,100,144,185,131,110,150,173,
-247, 27,157, 76, 45, 10, 37, 61, 96, 10, 9,136, 29,148,109, 19, 81, 34, 61,180, 0,151,218, 57, 51, 25, 0,254,229,208, 73, 49,
-103,183, 93,210, 42,101,106, 35,114, 81,101, 64, 12,137,141,199,134, 51,206, 92, 70,201,154, 38, 53,116,159,170,192,203,235,224,
- 39,102, 89,216,120,253,207,174,159,164, 57,181,235,226,100, 70,250, 51,169,251, 78, 87, 67,176,174,235, 18,241,159, 0, 28, 93,
-203,110, 28, 69, 20,173,238,234,174,234,199, 60, 60,100, 72, 0, 7, 35, 35,107,192,176, 32, 1, 41,155,176,130, 5, 32,182, 8,
- 22,240, 29,252, 22, 75,150, 89, 32, 33, 33, 22,128, 37, 99, 33, 1, 2, 18, 20, 27,107,198, 51,238,233, 71,117, 85,117,113, 78,
- 47,189,177,166,235,113,239, 57,117,239, 61, 71,190,122,116, 71, 14,248, 13,214,204,226, 34,140, 51, 54,160,104, 10,225, 60,178,
-145, 66, 40, 47, 39, 44,155, 43, 29, 82,165, 71, 77,228,146,189,131, 73,148,165, 28,101,155, 74,145, 45,233, 46,144,150,101, 73,
-112,155,239,250,232,228,238,195,175, 63, 93,125,249,137, 61, 61, 58, 91, 76,158, 37,230,124,111,206,155,238,220,216, 95,189,187,
- 56,208,235,251,175,185,247, 30,138, 15, 31,189,252,214,225,155, 51,125,239,233, 77, 90,245,142, 66,114,113, 60, 41,102,156,194,
-205,216,193, 35, 23, 72,117,166,116,154,162, 91,110, 42, 85, 31,117,141, 76,183, 32,131, 3, 82,183,108, 20, 13, 35,100, 31,243,
-209, 32,147, 6,233,174,106,186,235, 97,113, 58,147, 50,189,238,124,142, 3,196,254,117,205,233, 20,234,210, 1, 49,112,156, 18,
-248, 79,199, 72, 53, 45, 9,231, 96, 85, 60,118,183,178,190,236,136, 59,216, 63,131, 64, 77, 75, 38,199, 25, 79,132,250, 52,234,
-233,184, 64,127, 17, 14,155, 82,240, 95,140,226,136,248,207, 54,236, 3,104, 43,161,163,115,118,180, 56,164,111,226, 86, 80,232,
-220,197,133,139,216,107, 30,196,226,222,180,202, 15,191,249,246,122, 90,226, 62,151,244,138, 68,208,207, 6,250,115,178,155,134,
-116,147,200,125,220, 71,236, 60,231,250,232,157, 26,187, 2,104, 51, 36,236,116, 64, 26,204,139, 1, 76, 46,207,179,233, 87,159,
- 45,191,248,216,233,217, 15,251,203,127,237, 53, 8,139, 28, 35, 59,191,131,126,176,117,237, 26, 4,116,105,254, 51,109, 39,129,
- 36,154,171,170,185, 25,218,205, 80, 61,119,213,229, 32, 46,135,105,197,232, 33,118,126,111,200,205, 25,104,164,104, 28,123, 19,
-217, 10,153,177,180, 13, 8,143, 8,158, 5, 74,245,182,141, 63, 60, 73, 86, 15, 74,131,208,190, 28,167,213,199,151, 27, 65, 79,
-178, 64,129,215, 36, 21, 76,119, 92, 54,177,211, 33,116, 61, 0,125, 75,167, 69,215, 75,187, 55,206, 37,161, 74,220, 45, 75,249,
-126,199,215,152, 64, 4,206,145,119,144, 8,133,184, 69,229, 39,170,128,134, 2,108, 38,109,202,174,124,165,152, 63,120,231,231,
-171, 77,251, 39,171, 82, 46, 15, 88, 90, 99,196,188,143,111,250, 78,150, 67,133,179, 18, 40,209,168, 53,229, 77, 40,119,199,153,
-206,184,100, 45, 55, 2,108, 88,111,219, 70,191,248,248, 88,215,205, 53, 86, 50, 43,177,179, 38, 81, 56,187, 56,201,200,185, 49,
-251,188, 10,172, 30, 77,212, 84, 63, 22,224, 41,172, 64, 67, 68,124,185,191,141,141,105,226,218,174, 62,154,175, 30,221,253,241,
-123,209,223,174, 39, 73,218, 78, 18,199,140,198, 74, 84, 47,212,164, 19, 45, 21, 84, 28, 69,168, 60, 82, 72,228, 57,131, 24,211,
- 56,217,166, 73, 31,166, 75,250,121,224,111, 55,103,245,204,236,184,178, 47,244, 53, 61,128,211,241, 57,205, 2,143, 41,170,251,
-131,152, 54,157,154,152, 26,188,137, 66,186,209,190, 78, 45,117, 26, 98, 48,116, 80,239, 96, 16,117,187, 77, 55, 52,126,154, 53,
- 82,154,126,251,172,254,171, 82, 89,177,124,123, 97,186, 77,229,168,199,157,244, 8,181, 56, 95, 84,102,164,227,172, 27,116, 54,
- 90,137,122,203,230, 21,156,126,100, 75, 21, 79,100, 68,147, 5,128, 64, 92,126,112,168, 41,104, 35, 55,211, 14, 85, 71,217,175,
- 48,173,123, 6,230, 38,194, 47,240,200, 29, 8, 60,118, 72,165, 25,100,170,217,116,192, 8, 41,216,252,161,135, 30,148,223,248,
-229, 85, 4, 40,185,111,109,170, 53, 32,179, 6,163,146,150, 79,137,130, 23, 1,217,185, 24,135,173, 64,107, 38,216,129,194, 19,
-187,230,170, 84, 97,190,136,102,119, 14, 22,239,190,191,153, 41,215,229,167,247,211,185,127,178,254,237,204,182, 14, 48, 39,208,
-128,153, 42, 54,124, 18,222, 1,112,120, 74,247, 56, 58, 16,203, 62, 5,165,195,126,121,190,175,244, 49,174, 29, 43,218,187,131,
- 98,171,213, 75,235,166,136,253,134,242,191, 90,216,125,230,218, 64, 89,138, 88, 33,138,198, 34,206,129, 46,134, 14,151,215,153,
-236,245,233,209,231,143, 23,171,195, 11,185,255,110,247,207, 89,253,247,239,187,167,117,179,217, 87, 55,174,189,220,246, 55,235,
-118,125, 33,219,159,202,217,243,227, 55,194, 7, 39, 71,121,126,252,203, 31,184,182,183,128,153,133, 72,149,162,237, 64, 66,127,
- 73,172,169, 73, 65,191,134, 26, 36, 17, 55, 48,106,180,231,139,141,194, 23, 15,137,178, 9, 86,148, 46,105,161,139, 82,128, 47,
-164,172,206, 83, 57,136,250,129, 82, 0,136,100,202,211, 21,192,142, 45,236,128,129,186, 16, 17,206, 59, 57,130, 4,211,233, 51,
-222, 26, 62,134,122,171,129,155, 34,239, 77, 54,204,218, 32,210, 68,207,131,243, 69,217,237,254, 23,128,164,107,217,141,163,136,
-162,213,245,234,215, 56,227, 56, 99,199,196, 22, 54,193, 40,200, 96,196,138, 5, 72, 32,146, 15,224, 31, 16,159, 23,137, 29, 27,
- 54,136, 31, 72, 88, 0, 11, 35, 34, 69,177, 29,201,175,153,233,158,126, 84, 87, 85,115, 78,179,179, 37,143,103,166,170,235,222,
-115,110,221,123,142, 58, 56,216,199,254,178,151,192, 42,100, 30, 33,173, 41,172, 13,227, 86, 90, 80,223, 81, 81, 26,138,214,218,
-179,156, 98,227, 41, 22, 25, 17, 38,110,219, 66, 79,131,219, 78, 20,179,220, 26,149, 15,243,121, 47,101,237,103,207, 15, 63,249,
-233,133,126,118,242,242,242,230,183,171,119, 87,245, 80,183,247,155,182, 27,134, 74,186,149,106,218,190,174,235,219,251,139,205,
-250, 58, 81,111, 15,143,223,127,246, 69,254,229,241,113, 94, 60, 94,185, 97, 85, 53,229,246, 44, 47, 41,182, 36,217,169,106,131,
-180, 91,105, 76,172,147,198,184, 82, 80, 95, 46,153,231, 27,250, 18,179,173,139, 18,202,194,109,123,203, 25,122, 35, 50, 32,134,
-230,178,209, 39, 31, 28, 61, 41,222,180, 66, 61, 58,164,241,128,160, 57,107, 72, 16, 76, 29,213,249,233,157,176, 66, 0,239,233,
-140, 53,133,105, 15, 20, 78, 2,192, 50, 87, 84,131, 96, 41,116, 42,204,152,169,250,130,220, 64,245, 16,150,120,120,209, 74, 27,
- 19,150,125,199,158,245, 7, 68, 50,209,131, 34, 32,150, 15, 64, 96,188, 71, 10, 19, 14,189,241, 28,179, 4,146, 95, 70, 63,137,
-247, 47, 62,154,151, 79, 15, 94,254,124, 59,179, 25, 33, 20,208,171, 26,116, 63,227,160,170, 5, 86,167, 3, 93,166, 40, 2, 11,
- 54,139, 79,161,168, 95, 70, 79,213, 82,234,109,228,157, 98,204,165,233,141,211,114,107,177,183,251,227, 15,234,197,247, 87,210,
-253, 89, 95, 92,131,107, 43, 7, 82, 30, 89,133,190,165, 68,163,195,119, 66, 12,237,130, 3, 96,191, 20,109, 31, 58,236,196, 91,
- 81,223, 36,183,151,221,221, 21,123, 10,219, 58,178,174,128, 37, 3,218,238,145, 42,105,231, 8, 28,141,207,207,185,128,145, 25,
-113, 80, 52,194,160,120,169, 36,248,222,223, 19, 95,125, 51,151,143, 73,241,245,124,146,142, 7,218,180, 74,206,153,153,216, 92,
-134, 84,203,142, 23, 29,133,244, 29, 5, 52,134, 64,163,201,190,197,161,195,226,245,205, 36, 11, 46,122, 55, 86, 9,246,142, 6,
-214,236,254,179,162,139,174, 9, 93, 39,202,200,118, 20, 94,141,100,137, 85, 74,239,248,131,195,195,230,195,131, 87,127, 45, 5,
-163, 57,146,192,168, 40, 90, 26,117,153, 84,173, 47,189,108, 7, 16, 2,223, 73,236,178, 73,250,132, 30, 9,120, 83,224,165,146,
-247, 72,158,134,145,224, 69,249,183,167,249, 76, 94, 55,236,186,215, 20,113,144, 89,104, 37,200,139,110,113, 72, 2, 75,176, 66,
-165,149,180,109,104,179,128, 28, 80, 54, 73, 82, 9, 54,255, 35,191,143,114,211,215,105,101,142,191, 59,146,122,239,245,175, 75,
- 19, 87, 10, 15, 40, 50, 96,136, 57,128,167, 1, 80, 7, 12, 86,212,149, 1, 25, 30, 71, 0,224, 12, 97, 13,187,149, 1, 16,224,
- 15,124, 62, 55,107, 42, 25, 14,133, 9, 90,143,233,255, 55,252, 72,224,105,214,245,120,134, 50, 1,166,102,177, 99,192,217,109,
- 93, 59, 78,189, 57,221,225,119,230,233,145,126,132,177,139,203, 62, 49,182, 21, 26,204,172,238,162, 79,189,222, 56,197,250,247,
-112,241,174, 58, 95,202,189,253,244,100,199,129, 22, 55,128, 73,137,238,179, 16, 82, 16, 72,234, 11, 25, 28,218, 66,183,248,247,
-214,176,184,196,188, 40,179,108, 4,119, 73, 12,101,143, 39,121,178, 17,148, 64,249,216, 90,206, 90,132, 34,155, 1, 91,103,188,
-164,229, 5, 1,197, 18,194,184,193,177, 41,120,127,197,177, 71,132,250,104, 91, 99,106,196,116,142, 99,154,212, 13,116,250,137,
-102,233, 16,196,248, 10, 26,220,122,198, 82, 18, 8, 94, 99,243,103, 43, 12,190, 8,232,112,234, 51,149,109,101, 49,217, 25,119,
- 22, 15, 22,159,127, 61,156,157, 94,175,205,211,135, 15,159,236,254,126,127,254,170, 89,213,194, 33,207, 12,192, 82,162,197, 3,
-180, 73,108, 39, 99, 59,117, 17,247, 35,189,141, 0,184, 12, 85, 2,131, 26,221, 52, 84,203,126, 49, 78, 75,199,228,118, 47,211,
- 85,125, 86,177,239, 73,154, 10, 89,161, 47,217,250, 73, 23,236, 84,207, 6,234,158, 83, 28, 68,133,197,217,238,179,231,167,235,
-212,252,114,255,239, 31,213,245, 93,116,124, 87, 37,113,254,132, 81, 15,148,199, 74, 73,223,136,118,109,215, 87,155,100,245,143,
-221,250,251,228,211,241,232,209,199,245,157, 57,127,243, 94,168, 14, 36, 27,216,157,157, 29,126,186,246, 75,100,229, 3,165, 62,
- 65, 27,148, 76,114, 58, 16, 99,205,115, 28,200, 77, 85, 69, 44,104,234,196, 12,105,107, 24,200, 92,194,212,128,149, 52,119,131,
-140,169, 43,244, 18,156, 15, 27,135, 84,141, 44,198, 90, 62,178, 98, 39, 28,155, 77, 61, 56, 7,221,157,102, 96,183,125, 43, 51,
-145,105, 14,204, 46,170,222,107, 26,157,231, 73, 40,130,250, 79, 0,146,174,101, 53,142, 35,138,118,117,117, 85,117,183,102, 70,
- 47, 39, 82,140, 44, 35,108, 99, 28, 98,208,194,132,132,224, 93,246,249,134, 64, 22,249, 68,147,117, 32,155,124, 64, 32, 49,177,
-193,182,228, 40, 99,105,102,250, 85,239,156,211, 89, 9, 33,132, 24,213,173,115,207,173,123,239, 57,242,236,252,212,208, 16,166,
- 86,236, 99,179,193, 68,233,105, 16,154,182, 13, 77, 80,168, 1,151,203, 4, 38,229,219,250, 48,205, 11,149,203,118,105, 24,207,
-213,106,137, 47, 56,164,182,174,193,135, 76,239,251,229,203,199,143,126,250,254,205,114,245,234,227,213,251,105, 92,152,220,240,
- 1, 88,206, 93, 50, 62,119,239,218, 85, 93, 82, 87,111, 80,229,216, 15,105,125, 55,136,126,125,188,127,247,236, 97,245,205,147,
-139, 85,243,224,198,233, 13, 48, 65,155,166,170,246,144, 23, 12, 19,207, 28, 31, 96,212, 40, 33, 73, 57,172,166,146, 67, 37,133,
- 71,197,105, 92, 31, 28,136, 99,170,105, 87, 79, 81,196,193, 87,247, 62,187, 60,185,234, 73,238,169,203,158, 17, 68,134,111,178,
-161,195,239,162, 38,224, 88,124, 99, 80,220, 43,150, 28, 96, 78,192,253,166, 20,156, 93, 33, 52, 87, 36, 89, 92,226,227, 91, 63,
-208,141,203,127, 56, 34, 48,133,114,182,186, 78, 8,222,162, 47, 69,225, 1, 11,114,202,217,219, 72, 21,176,108,123,199,119,130,
- 45,160, 63,210, 49, 17, 71, 25,245, 45,187,173,244,143,210, 7,199,251, 15, 62,127,245, 91,110,114,106,246,145,125, 90, 93, 22,
- 9,236, 81, 39, 74,206, 87, 26,229, 8,203,166, 44, 86, 89,212, 85,101,151, 13, 51,124, 9,164,208,166, 50,236,217, 33,237,121,
-241,229,163,251, 63,255,104, 94,188,184,242,255,254,221, 95,117,249,182,165,241,138, 45, 0,232,161, 79,113, 76,160, 39,118,244,
-182, 87,225, 46, 79,219, 56,140,169, 27,211,240, 46,130, 47,239, 62,229,113, 19, 70,132,216, 93,214, 92, 0,230, 16,111, 23, 57,
- 36, 71,213, 37, 75,201, 86,205,207, 63, 43,174, 85, 92,150,149,179, 63,122,223,133,186, 45, 46,191,221,107,206,155,140,128, 55,
- 21, 97, 76,205,130, 39,146,182, 12,130,106, 24,153, 10,104, 28,211,162,235, 5,133,213, 61,155,161, 40, 35,124, 4,155, 73, 28,
-210,218,130, 98,197,210, 33,223, 20, 84, 21, 24, 98, 28,217,210,137,248,153,155, 91, 29,255,107,190,167,194, 28,235, 18,248,180,
- 8,167, 79,158,190, 46, 79,255,122,123, 13,184,146, 92, 60,182, 52,131, 7,143,235, 19, 85,228,113, 39, 34, 91, 72,243,220,149,
-143, 84,175, 79,226,142,201,134,235, 39, 96,144,202,105,111,214, 69, 58, 61, 95, 61, 11,113,232,250, 76, 47, 78,176,124,160, 94,
- 54,160,237, 61,137,164,216,229, 12,102,138,132,211, 74, 46, 62, 68,225, 41,125,140,172, 89,164, 19,126, 82,181, 75,155,245,230,
- 40,185,231, 63, 28, 57,119,248, 59,242,141,223, 25, 42,230,131,241, 42, 80,139,145,111,222,168, 67,128,182, 92, 54,158, 5,163,
-185, 0,177, 64,109, 65,211,188,138, 27, 11, 90, 31,224,238, 89,110,152,245, 53,187, 45,166,172,188,151, 94, 80, 52, 24,117, 97,
-226, 56, 10, 5,149,170, 98, 81,168, 41,241,129,212,177, 89,131,243,217,210, 57, 42,103, 7,216,193, 17,115,242, 56,202,137,148,
- 5, 25, 74,116,123,217, 68,101,251,241,207,181, 10, 71, 39,207,169,207, 50,148,131,247,149,104, 38,214,127,224,228,118,154, 29,
- 43, 60, 72, 90, 50, 58, 91, 43, 41,163, 41, 81,157, 20, 77, 81, 91, 69, 23,229, 68,207, 58,118, 18, 84, 80,121,138,196,126,220,
- 53,250,120, 84,117,160, 47,103,104,170, 5,138, 30,252,219, 3,187,224,198,233,176, 87,148,220,254,181,227, 48,201,201,176,171,
- 33, 51,202,239, 32, 82,180,160,233, 73,140,201,230,196,241,118, 62, 58, 20, 38,210,100, 46,206,214,100,249, 48, 53, 74,155,165,
- 22,203,226, 64, 55, 39, 23, 95,217,199, 47,251,250,122,229,238, 93,156,191, 15, 87,191,118, 31, 1,201,109, 24,157,178, 93,246,
-244,228, 64,149,196, 63,192, 9, 89,201,231, 47,201,183,154,216, 36,201,174, 76,195, 81, 89,220, 93,126,123, 92,182,108,102, 42,
-115, 45,196,201, 7, 10,167,221,106,193, 97,113, 64,135,116, 54, 59,132, 13,133,252, 41, 74,231, 23, 15,143,239,127,119,249,166,
-140,191,108,222,254,225,119,115,136,204, 66,104, 57,236,138,188,205, 67,231,211,109, 14,182, 2, 61, 65, 96, 59,240, 18, 51,172,
-173,238,110,206,206, 55, 95,127,113,118,243,207,211, 55, 31, 94,199, 21,224, 37,208,134,171, 20, 56, 34,247,201,171, 76,209,212,
-176,135, 26,167, 44, 7,196,183,165,206,185, 67,225,170,138,212, 53,117,158,104, 50, 0, 54,133,171,203,134, 54,194,105,107,180,
- 48, 93,224,218,184, 41,106, 95,164,106,146, 91,167,167, 52,235,153, 56,175, 36, 64,141,204, 98,209,150,166,117,110, 26, 85,173,
-128, 66, 32, 60, 25, 0, 82, 26, 43,233, 4,169, 1,111,255, 9, 64,210,181,244,200, 77,132, 65,183,251,101,183, 61,143,132, 93,
- 86,104,217, 69, 27, 30, 17, 8, 34, 20, 36, 2, 7,174, 8,126, 1, 71,126, 1,255, 14,113,228,192, 33, 71, 36,110, 32,130, 18,
- 2, 81, 96, 51,217,204,174,103,236,182,187,219, 77,213,112, 29,205, 88, 51,110,119,125, 85, 61,223, 87, 37,207, 46, 78, 24,159,
- 81,151,206, 5,163,156,104,170,106, 89,105,233,116,169,143,108,173,179,171,100, 66,213,175,151,216,245, 66, 92, 47, 86,235,166,
-110, 18,170, 11,232, 71,123, 91,220, 94,149,186,208, 85,109,192,148, 62,190,115,239,155,207, 94,172,250,239,159,255,190,161, 55,
- 56, 59, 57, 43,166,179,228,130, 54, 26,210, 23, 99,224, 0,177,232,176,247, 8,186, 32,252,168,200, 97,156,128, 70,226,198,216,
-167,111,159,212,239,189,241,122, 46,150,143,182, 75,157,167,163,149, 1,124, 48,130, 81,170,165,180, 70, 85,218, 38,231,186,200,
-254,245, 98,178,123,144, 63, 80, 14,212, 85, 75, 49, 73, 51,160,130,110,208,224,221,246,163,139, 41, 47,119,204,119, 12, 33,241,
-200, 79,133, 29,219,241, 65, 44, 64,117,123,212, 88,195, 51, 69, 38, 32,178, 3, 84,243,223,161,196, 3, 60,192,150,106,212,140,
-149, 8,244, 91,211, 4,250, 67,186, 55, 49,159,227,206,130,211, 55, 6,101, 64, 27,208, 6, 19,201,124,193,208, 81, 53,198, 48,
-100,134, 23, 14,201,139, 48, 13,120,144,115,128,172, 27,227,193,157, 99,110, 42,125,113,255,244,167,223,194,230, 89,183, 88,180,
- 32,157,190, 28, 33, 58,155, 66, 51,112, 13, 43,107,240, 77, 56, 25,156, 76,194,143, 81,181,109, 3, 0, 65,218,182, 28,200,165,
-141, 55,213, 87, 95,190,249,221,183,226,236,236, 73,122,252,231,240,143, 7, 5,246,168, 46, 62,236,251, 60,132, 50, 79,161,239,
- 65, 59,230,233, 10,224, 19,139, 46,128,174,238, 46,203,112,153,175,247,161,187,138,175, 46, 3, 30,166, 98,152,204,150, 21,232,
- 70,138, 97, 96, 46, 12,187,156,137,150,236, 6,161,111,130,164,247, 75,168, 14, 3, 55, 57,249, 72,139,154,123, 15,204,249,221,
-102,191,158,153,249,234,176, 50, 80,182,108, 54,131,104, 47,220, 1, 34, 5,251, 58, 89, 47, 81,126,167, 6, 72,151,233, 92,131,
- 21,137,121, 63,251, 41,229, 29, 48,165,162,225, 20,143,209,105, 19, 8, 46,189, 31, 56, 85, 84, 65, 30, 67, 55,208, 85, 23,180,
-174,140, 54, 79, 90, 77,101,110, 79, 76,123,247,243,135, 93,223,245, 59, 23,105,233,212, 75,144, 40, 25,160, 81,220, 52,212, 12,
- 85, 30,103,176,231, 48, 1,162,233,145, 95, 50, 22, 76,206,149,101,116,148, 40,193,127, 5, 64,101, 24,247, 47,203,197,167,119,
- 92, 53,238, 19,123, 28, 36,118,195,193,117, 15,202, 94, 50, 61, 22,203, 92,207,108, 98,135,252,248,127,186, 10, 79, 60, 11,115,
-137,125, 5, 66,192, 46,177,121,222,108,182, 71,171,124,255,235,243,231, 94,255,250,240, 90,185,125,147, 93,162, 67, 15,143,252,
- 11,207,105, 62,208, 67, 78, 64,131,154,224,179,194,182,199,180,181, 41, 83,102, 4, 72, 22, 43,233, 0,247,194,229,166,169,214,
- 9, 5, 14,181, 81,172,177,244,235,164, 90,154,163,104,118, 87,210, 19,146,238, 4,224,234, 30,124, 68, 41,109,231,126, 14,209,
-210, 95, 23,240, 82,206,144, 22, 6,104, 51, 66,180,216, 56,168, 91,219, 97,217,150, 16, 66,219,107,255,203,223, 29, 94, 60, 61,
-113,175,133,112,195,148, 96, 77,107,227,152,233,230, 44, 50, 67,225, 80,127,113, 47,231, 81, 45,178,153,212,216, 13, 14, 52,216,
- 30,236,208,163, 2,121,143,213,193,136,173,156,213, 14,194,166,193,109, 13,181, 13,218, 99, 3,138,131,159,134, 9, 16,150, 52,
- 44, 41, 6, 25,177, 80, 12,238, 16,140,226, 6,245, 79,227, 14, 69, 99, 0, 71,158,202, 30,218, 55, 67, 66,143,158,187,137,182,
-103,197,108, 41, 89, 68,176,114,229,102,144, 99, 84,115,166,192, 91,121,124,242, 65,253,197,251,253,173, 20,187,242,124,113,180,
-146, 63,110,255,122, 50,114,210,112, 84,172, 68,236,106,224,153,253, 24,194,138,243,225,184,141,236, 35,160, 49, 16, 83,177, 52,
-219,122,106,182, 68,204,137,154, 58,231,185,226, 32, 75, 25,111,150,242,116,115,245,161, 24, 95,153, 50, 40,223,243, 92,214,219,
-184,112, 37,170, 68, 10, 41,232, 99,245,214, 39,239,252,235,198, 31, 54,127,108, 10,185, 4,115, 68,201, 74,224,131, 96, 31, 57,
-224, 74, 28,130,204,220, 38, 80, 7,204, 9,136, 65,183,153,227,254, 47,163,152, 94, 84, 71,143, 30,188,123,254,236,241,250,231,
-167,253,218, 68,236,246, 33, 23, 38,122, 8, 85,239,156,241, 85, 54, 35,112, 64, 39, 80,250, 14, 23,217, 41,201, 91,136,117, 17,
- 12, 75, 10, 13, 24,234, 65,130, 3,124,216,141,236,150,137,241,130,128,171, 24, 61,147,196, 65,255, 61, 16,203,226,125,114,166,
-229,164,154, 39,206,189,129, 72,248,105,167,132, 92, 88,217,133,229,208,143, 85, 43, 10, 79,103,116,250,182,237,255, 19,128,164,
- 43,217,141,219,136,130,205,222,184,136, 28, 45,177, 44,196, 75, 4, 33, 64, 12,219,176, 29, 31,114,243, 55, 36,167, 92,114,202,
- 49, 95,149,143,201, 33,200, 7, 36, 72,114,176, 5,200, 30,217,128, 34,141, 70, 51,211,100,147,189,164,138,214, 15, 72, 34,155,
-245,170, 94,191, 87,165,206,158, 60, 28, 57,231, 87, 90,222, 94,128, 32, 26,222, 32,182, 86,216,100,235,232,100,125, 84,215,210,
-236,201,178,237, 82, 87,236, 91,221, 17,251,155, 3,165, 27, 27,199, 5, 42, 70, 89,229,152, 43,215, 60,255,241,233,205,105,255,
-235,229,114, 25,213, 94,106, 45,253,217, 6, 39,164,159, 15, 10, 59, 27,160,201, 66, 77,186,103, 46,165,165,223,254, 62,104,167,
- 2,249,116,219,100, 76, 24, 69, 31, 62,117,245,245,179, 47,245, 81,253,213,114,155,122,209,211, 45, 87,107,188, 3, 6, 98,130,
-141, 92, 51, 84,109, 13,146,212, 67, 58,150, 94, 84,227, 78,241,122,190,128,178,102,128,223,199,164,162,207,167,199,139,215, 79,
- 54, 18,152, 39,115, 13,193,104,202,158,129,227,224, 50, 33,115, 25,125, 98,196,116, 50, 12, 60,111,102, 23, 77, 80, 64, 59,129,
- 69, 23,146, 83, 79,102,151, 81, 5,138,118, 94, 0,129,112,152,173,127, 37,127, 12, 56, 62, 48, 79, 49, 19, 94, 40,111,178,155,
-100,220,197,209, 76,192,214, 45,227,194, 61,200,125, 31,193,244,131,211,128,255, 48,140,155, 36, 24,126,125,155, 69,155, 30,189,
-122,252,238,178,249,235,223,208,116,168,184,248, 84, 90,112, 60,188,220, 57, 88, 74,181, 13,239,187, 44,199,223,181,172,232,112,
- 70,239, 40, 3, 76,212, 64,224,227,170,251,229,135,131,159,127,242, 85,241,110,124,251,190,255, 4, 2,171,211, 46, 79,119,211,
-112,131, 7,194, 1, 25,252, 31,110, 27, 65,219,253, 77,244, 65,172,239,196,234,163,236,167,157,191, 5, 95,246,241, 38, 71, 28,
-109,144,132,149, 96, 55,195,207, 55,171,115,104, 8,247, 45,195,188, 72,102, 65, 36, 64, 45,216,150, 24,172, 92,128, 83, 42,177,
-137,233,213, 55,250,233,183, 16, 29,133,228,226, 18,123,166,243,202, 35,115, 51,213,130, 13,104,249, 57, 80, 62,243, 97,129, 94,
- 21, 99, 17,166,209,175, 39,191, 77,137, 49, 73,130,127,220,173, 70,213, 41,220,124, 99, 1,130,204, 17, 60,154, 49,100, 23, 86,
-248,208,130, 0,177,117,179,181, 37,120, 88, 9,197,109,166,163,151, 85, 58,123,243,207,249, 5, 16, 22,180,107,203, 22,208,188,
-104, 7,210,251,159,229, 4,193, 54,113, 79, 6,159,134, 15,220,199,208,140, 31, 17,243,132, 19,119,197,240, 88, 21,251, 14,168,
-206,235,149,239, 78,187,151, 93,190,243,183,211,192, 21, 64, 77,182,148,137,190,153, 67, 13, 64,182, 28, 0, 28,153, 62, 68,106,
- 14,225,169,152, 5,202, 81, 88, 96,251, 30, 78, 96, 9,190,178,250,224,238,221, 87,111,190, 63,185,184, 56,249,251,252, 74,107,
-103,217,109, 17, 28,109,128,178, 69, 65,142, 9,228, 9,191,147,179,143,220,243, 8,220, 81,248, 34,214,100, 14, 49, 54,248, 85,
- 80, 55, 45,183, 91,237, 88,214,192,222, 49,151,109,114, 67, 79, 87,101,134,121,131, 35, 70, 26, 1, 78,138,193,129,197, 40, 45,
- 68,206, 38,134, 80, 82, 8,150, 12, 53,212, 64,176,145,175, 79, 3, 66,131, 4, 85, 80,155, 69,147, 89, 63,106, 57,228,139,109,
-232,219,195,199, 15, 15,143,107,240, 39, 71,219, 18, 80,234,154, 54,130,138,193, 21, 10,156,208,130, 39, 50, 52, 38, 85, 21, 71,
-164,184,193, 38,185,253,162,231, 8, 67,192,208, 4,225, 81,209, 58, 63,211,239, 87,179,206, 73, 77, 3,237, 42,249,212,143,144,
- 40,144,139,168,129,244,135, 45,196, 70,163,142, 75,208,146,141, 55,168,229, 14,106, 4, 56,138,239,118,206, 53, 24,198, 78,201,
-157,206, 85, 79,199, 6,128,179, 6,215, 43,101, 81, 87, 77, 45,187, 35,115,244,224,164,126,253,194,223,191,215,111,174,202,226,
-236,209,131,247,187,213,239,126, 69, 99,116,102, 87,140,204,114, 24, 81,191,107, 35,118, 28,226,135,122,161,241,154,101,124, 2,
- 45,143, 2, 61,239, 12,175,168,104,250, 38,197,103,208, 41,101,133, 42, 29,240, 88, 47,253,179,169, 92,130,213, 2,121, 43,212,
- 24,118,237, 7,246,168,118,189,137,199,223,125,221, 29,183,191,173, 46,207,253, 16,180,108,178,219, 8,131, 15, 9, 5,222,132,
-222,226,181,207,215,113,154, 54, 85,100,134,140, 71,165,135,249,148,184,225, 61,169, 52, 94,155,197,242,249,225,139, 63,254,172,
-151,226,109, 83, 25,250,196, 93,133,161, 45, 11, 72,191,145, 83,221, 56, 27,113,220, 35,214, 1, 9,161,148,178,211, 46,212, 46,
- 57, 40, 48, 48, 16,175,120,211,101, 39,223,139, 69,189, 6,237,237, 39, 91, 2,168,112,182, 39,240, 23, 77,109, 7, 85, 11, 69,
-146, 22, 36, 62,236,117,137,110,175,216, 47,115,167,133,241, 25,186,106,106, 19, 78,211,162,148,117,177,208,110,119, 80, 52,255,
- 11, 64,210,181,236,198, 81, 68,209,174,174,170,238,170,238,121, 56,118, 12,138,145, 21, 12,138,149, 44, 12,130,136, 21, 66,130,
- 13,130,255, 96,195,103,241, 15, 44,145, 88,178, 66, 72,217,241, 76,164, 88, 88,142, 29,207,244,216,253,168,174, 23,231,152,221,
-172,122,170,103,234,222,123, 78,213,189,231,200,147, 39,143,116,187,104,116, 37, 4,135, 84,150,173, 44,128,225, 75,219, 84,170,
-197,175,175, 30,236, 47,215,181, 73,122,201,235, 96,125,168,171, 22, 36,173,105,181, 92, 87,117,156,205, 94,163,230,197,222,168,
-237,217, 7,143,191,202, 63,108, 46,254,234,211, 18, 81, 14,144, 8,234, 10,182,204, 3,110,145, 65,222, 57,182, 83,234,108, 60,
-194,136,118, 33,162, 19,106, 44,202, 32,200, 42,168,206, 38,107,100,120, 55, 77, 55,185,188, 60, 57, 10, 77,121,116,222, 47,118,
- 89,233, 88,161,210,137,152, 26,164, 82, 35, 59,201,118,174,117,110,132,158,133, 24,138, 1,113, 55, 73, 60,202,161,124, 32,205,
-174, 63, 59,174,190,254, 60, 63,180,175,182,219, 32, 44,123,253,131,201,243,132,186, 77,255,157, 16,193,236, 52,245,237,144, 16,
- 39, 4, 76, 16, 61, 79,179, 34,114,197, 46, 24,197,246,231,130,253, 4, 20, 34, 82,158,179,172,220,182, 5,207,113, 53,197, 56,
-105, 53, 94,246, 46,123, 75, 67,144,224,130, 2,239, 69,233,114,201, 17, 39,209,121,103,142,252,200,254,239, 80,237,120, 43,108,
-193,241,145,129, 31,148, 31, 62,123,188,169,246, 94,252,114,107, 81, 32,133,215,141, 22,141,165,134, 42, 13, 96,106, 10,222, 71,
-222,105,214, 20,201, 9,134,183,134,190,215,250, 46,216,143,222, 51,223,125,191,255,205,183,219,162,251,189,127,113,149,183, 5,
-246,201,136,108,190, 11,125,200,161,167,160,235,140, 93,113,147,199, 45,208,185, 0,132,247, 93, 73,190,247, 10,104, 61,221, 92,
-167,240,150,141,237,213,206,243,250,145, 77,101,168,188, 20,151,239,136, 89,121,209,216,115,118,155,199, 50,224,136, 84,148,174,
-139,192, 31, 63, 95,109,210, 59, 71,197,167,159, 88,119,160,192, 99,106,144, 29,182, 7,226, 17,139,178,182,209,206,114,159,202,
-161, 28, 13, 82,108,142, 37,253, 28, 56, 71,145,169, 57, 9,156, 68, 68,213,143, 9,148, 32, 3, 25,163, 84, 34, 60, 80,229,163,
-224,136,145, 15,254,206, 86,140,161, 2, 88,207,176, 87, 7,192, 16,144, 81, 88, 89,139,189,121,255,244,240,250,240,217,223, 23,
-215,189,156,219,229,236,119,168,118, 81,227, 21, 86, 98,102, 83,165,191, 2,204, 55,105,197,113,254,216,245, 64, 84,177,141,136,
-122, 90,102,243,142, 52,241,214, 4,232, 33,235, 60,222,164, 96,223,253,226,180,154,198, 77,129,191,187, 45,139,255,199,150, 1,
-179,214, 69,110, 50, 88, 11, 10,169,162,133,114,166, 86, 43,125,183, 81,132,138, 80,113,134, 32, 7,106,100, 83,240,211,135,238,
-223,221,193,211,197,199,103,199,191,189, 20,111, 47, 54,146,216, 64, 47,188,154,157,228,212, 40,231,246, 36,167,225,147,178, 90,
-218,154,138,108, 36,125, 0, 31,214, 98, 55,154,251,230,218, 58,120,201,115,213,182, 78, 22,235,145, 20, 84,175,153, 70,241, 61,
-162, 1,165,232,115,104, 66,133,250, 53,110,171,213, 8,124, 74,125, 92, 71,155,215,236, 39,192,237,122,234,131,149,173, 40,193,
-179,252,214,177,141,150, 82,229, 52, 31, 75,195,157, 60,255,243, 10, 75, 59, 49,234,120, 57,230,187,130,142,202,198,137, 74, 77,
-161,213,244, 78, 78, 46, 42,115, 11,158, 36,106,138,254,212, 85,200,181, 79, 65,207, 0, 79,145,166,180,148,201,196,179, 60,205,
- 27,217,238,158,217, 96,147,117, 74, 70, 43, 49,196, 20,177, 84,188, 36,125,131, 80, 16,228,144, 98,235, 71,108,167, 49,149, 11,
- 61, 38,103,144,148,115,198, 98, 91,224,119,207,161,177, 91, 81,172,198,130,168, 70,139, 86, 23, 86,233,246, 64, 46, 31, 38,213,
-218,246,236,203,244,228, 81,218,116,113, 48, 75,181,127,116,240, 99,119,254, 70,108,149, 82, 32,119, 53,130, 75,154,148, 57, 95,
-158, 56,226, 25, 34, 47,155,228,189,171, 8,210, 9,221,230, 28, 71,250, 8, 56,216,132, 38,168,118, 62,210,165,206, 97,115,142,
- 70,167,206, 63,119,229, 27, 65,211, 8,246,132, 74,117,171,233, 4,130,136,238, 15,151,239, 63, 61,254,185,127,253,235,140, 13,
- 17, 83, 81,245, 0,104,114,204,212,183, 84, 72, 81,247,180, 29,129, 89,250,251, 54,159,114,198,251,160,158, 83, 50,158, 13,167,
- 60, 44,243, 85,233, 46,237,233,120, 56, 61,255,233,159, 63,218,208,183,148, 33, 54,101,196,147,102,137,236,115,233,188,114,217,
- 13,209,152, 59,105, 56,106, 71,135, 7,228,143,236,230, 27, 0, 74,202,229, 99,131, 77, 67,112,114, 28,252,174,155, 12, 29,246,
-120,200, 49, 21,110,100, 11, 35,103,130,151,211, 44,145,123,234,193,173,182,213, 44,245, 14,127, 7,214, 87, 26, 64,131,130,131,
-117,117,140, 17,136,137,103,131,160,167,205,127, 2,176,116, 45, 59,114, 19, 81,180,108,151,171,202,143,238, 30,146,204,132, 9,
-140, 2, 8, 77,128,129, 21,108, 2, 89, 51,159,132,196, 55,241, 11, 44, 17,176, 67, 72, 32,161, 72, 72, 36, 16, 6,102, 50, 15,
-187,253,168, 42, 87, 21,231, 88,172, 91,114,183,221,183,206, 61,231,250,222,115,139,247, 63,126, 15, 4,189, 65,240,237,140,174,
-171, 42, 19,242,192, 52,185, 73,219, 82,149,166,222,178, 69, 12,223,171,141,198,147, 6,208,175,163,170, 91,219,222, 43, 11,171,
-118, 82,179,173, 43,171,142, 78,207,155, 95,245, 47,223,140,248,174,118,171,254, 31,255,113,235,202, 45,150, 82, 89, 53, 71,174,
-227,176, 32, 8,184, 67,124, 71,214, 86,245, 58,215,195, 92, 43,220, 58, 49,203, 85, 63, 17,236, 44, 44, 47,142, 55,233,190,186,
-247,239,208, 4, 49,170,150,166,148,222, 65,252,113, 32,177,156,242, 41, 78,222,236,141,197,237,131,168,130,155, 22,183,139, 57,
-124, 88,126,249, 44, 63,127,210, 29,111,159,191,186, 5,162, 39,205,118, 16, 41,247, 66,115,175, 26,114,166,228, 2,241,201,205,
-139,205,234,162,194,241,170,139,181, 79, 59, 33,243,107, 16,128,134,253,121,244,125,105, 83,201,161,117,214, 45,153,163,115, 54,
-223,112,124,197,113, 13, 55,126,161, 52,154,109,216, 54,248,153,110,150, 80,206, 97,212,182,143,190, 7,231,194, 39, 68, 88,176,
- 38,155,144, 90,196, 28, 66,111, 50,208,244,183, 31, 53, 15,222, 57,252,238,199,222, 46,169, 52,219,160,243, 86,130, 86, 33,155,
-228, 1, 26,206, 13,173,174,211, 1, 36,148,107, 70,182, 2,250,187,208,232,234,252,163, 55,191,254, 74,157,125,120,147,158,255,
-209,255, 14, 13, 38,160, 76,250,142,130,212,222, 57,206,157,116,113,184,158,247,203,146,192,166,246,144,219, 62,140,214, 78,225,
-114, 72,115, 31,246, 16, 24, 72,154,131,119, 49,141,150,227, 84, 5,174,192,210, 34, 43,221, 89,226,212,151, 22,162, 3,196,175,
-116, 85, 42,145, 12,144, 6, 28, 4,169, 74,228, 77,250,226,105,213, 28,181,126,147,233, 26,145,144, 51, 17,233,162, 80,224, 53,
- 92,125,133, 52, 84, 32, 81,200,117,149, 20, 2,140,125,143,158, 27,101, 22, 26, 1, 5,228,159, 14,128,108,151,171, 52, 93, 66,
-228,250, 16, 22,123,189, 58, 63, 64,153,178, 56,163,240,151, 79,251,181,225, 77,208, 22, 24,241,207,238, 41,176,226, 19,255,232,
-147,207,127,139,102,184,234, 32,171,131, 53,243,100, 0,165, 51,117, 58,235,249, 72, 65, 42,200,234, 54, 1,216,129,202,160,204,
- 32,206, 8,177,171,141, 40,232,247,203,238,117,157,249,122, 2,202, 11,163, 57,235,118,246,110,125, 20,187,113,158, 89,134, 45,
-214,114, 30,238, 95, 38, 18,125,195,201, 7,103,100,196,201,238, 57,175,173,228,186, 72,143, 47, 65,150,130,247,183,206, 66, 32,
- 57,218,105,126, 53, 60,252, 84,127,246,244,228,175,159, 55, 23,175,255, 49,136,237,182, 68, 2,216,201,196,150,161,106,221,131,
- 91, 21, 59, 45, 51,182,101,103, 7,149,148,107,147, 17, 48, 20,143, 23, 15,146,165, 82,144,125,190,202,112, 42, 4,111,104,241,
- 51,123, 81,121, 54,211,226, 17,123,176,161,232,104,162,150,199,180, 53, 67, 30, 57, 58, 90,215, 51, 83,178,242, 50,239,250, 49,
-181,120,222, 94,210, 43,123, 85, 10, 50, 47,125,229,100, 41,238, 23,102, 43,254,188,139, 63,221,108,155,227,205, 41, 18,152, 29,
- 58,246, 86, 3, 2, 71,165,132,108,203,161, 92,173,231, 16,245,214, 7,199,200, 95, 0, 59,210,150, 90,151,206,210,198, 1,146,
-216,177,130,157, 43, 45,115,199,174, 86,174,204,203,214,205,198,248, 89, 74, 64, 6, 57, 23, 38,190,252,240, 56,139, 83, 93,118,
- 16,110,144, 98, 1, 64,234,239,148, 24, 61,247, 69,216,120,237,185,233,136, 46, 74, 52,134,240,186,142, 98,163,154, 70,103,111,
-136,205,225,193,225,227,179,252,131,211,113,153,147,243, 75,217, 62,230,108,233, 15,251,191,251, 72,211,104,110, 96, 91, 16,214,
- 64, 68, 80, 89, 58,229,178,254,158, 65, 13,173,107,193, 86,235,188,172,168,185,131,139, 70,202, 17, 64, 76, 37, 66,235,164,117,
-208, 43, 51,190,220, 22, 98,120,118,185, 92, 8, 92, 39,242,253,107,142, 51, 34, 41,249,194,124,252,228, 45,252, 29,223,246, 87,
- 29,165, 45,232,189, 7,206,150,139,196,193,154,184,220,199,116,220,203, 14, 72,230, 96, 99,142,244, 40, 12, 71,224,161, 80,179,
-133,173,248,244,121, 1,119,142,139, 30,111, 78,118, 39,223,191,120,240,242,226,101,189,171, 71, 57,235,215,184, 20, 2, 53, 74,
- 7, 52,170,148, 75,147, 73,203,222,229,211,196, 33, 58,240, 1,157,170,166,182, 4, 75,170, 78,144,181,121, 46, 74,229,161,219,
-205,172,108,172,217,248,194, 87,132, 69, 61,203, 8, 32, 89,232, 92, 95, 57, 40,195,134, 78, 3,226, 14, 32, 30, 76,148, 37, 23,
-251, 34, 0,166,210,248, 52, 30,184, 78, 46,241, 54,216,255, 4,224,232,218,118,227, 40,162, 96,223,102,102,167,103,189,217, 56,
-142, 45, 91, 4,130, 66, 2,130, 23, 43,178,223, 80,254,128, 63, 64,249, 5,254,133, 47,226,137, 7, 16,226, 38,241, 64, 20, 41,
- 66,225,162,216,217,139,119,119,166,111,211, 77,213,188, 90,107,187,119,166,187, 78, 85,119,245, 41,125,121,249,153,246,157,177,
-141,198, 75,109,205, 56, 3,253,111,108,109,103,150, 93,177,164, 53, 93,189, 80, 93,107,219, 57,132,103, 55,170,118,113,210, 48,
- 98, 71,116, 74, 67, 43, 84,182, 56,213,220, 63,127,124,245,250,219,253,155,213,148,107,231,166, 12, 63, 84,138, 42,249, 32, 13,
- 13,213, 12, 88, 70,201, 2,195,192, 84,173,216,106, 67,139, 35,169, 38,207, 51, 91, 51, 87,244,112, 53, 21, 4,137, 60, 68,223,
-199,232, 14,113,220,127,112,230,138, 57,251,231,174, 77, 61,212,180,228,201,178, 8,149, 7,212,198, 65,233,202,101, 54,113, 59,
- 72, 55, 36, 35,218,207, 63, 60,254,234,178,188,120,242,231,122,188, 61,220, 28, 66,164, 9,102,244, 58,215, 9, 10,146, 61,175,
- 5,187,132,153,232, 84,192, 0,233,136, 48, 28, 41,221, 74,132,133,165,202,116,249, 66,236, 67, 80, 22,134,131,229, 50,114,125,
-211, 66,204,239,197, 48, 12, 40, 64,172,173, 17,160, 15,237, 22,239,114,218,102,122,110, 83, 15, 82, 17,217, 24,198,167, 85, 28,
-181,134,136,102,252,245,123, 54,212, 21, 60,207, 43, 29,125,245,144,214,230,227,171,199,223,255, 92,111, 92,121,120,210,205, 2,
- 32,142, 79, 67, 44, 50, 29,146,248,254,224,204,110,106,104, 54,159,177, 39,112,152,191,124,121,242,205,215,149, 93,188, 57,252,
-242,215,250,253,193, 39, 1,176, 46, 43, 31,119,101,104,243,102, 27,242, 70,184, 93,201,189,176,107, 89,110, 11,208,252,144,242,
-246,111, 35,111,133,191,139,205, 54,131,186, 80,190, 78,221,125, 69,144,152,159,130,167, 5,228,170,210,179, 7, 47, 32, 30,115,
- 25,227,237,168,177, 38,111, 40,202,111,230,169, 79,236,243, 23,215,250,163,167,182,183, 32, 67, 5, 90, 75,207, 11,227, 46,239,
- 67, 4,142,146,185,191,128, 26, 64,126, 93,244,212, 76,167,118, 68,202, 52, 99, 46,197, 22,122, 74, 64, 51,141,255, 49, 80, 21,
-111, 47, 42, 44,179,160,182,124,127,116, 60,236, 2,192, 61,149, 96,125, 26,166,185, 0, 54,182, 31,167, 63, 86,203, 50, 87,247,
- 78,243,236,147,235, 95, 87,217,121, 7,118, 16,122, 20,233,208,170,161, 17,227, 64,243, 60,143,168, 18,126,198,108,139, 84, 24,
-204,237, 3,221,153, 98, 54,249, 90, 49, 89, 26, 87,101, 91,241,165,242,134, 71, 9, 67, 28,143,239, 95,207, 69,216,172,185,135,
-100, 43, 94,168,159, 41,224,148, 33, 42,107,176, 77,211,147,134, 80,116,130,183,109,128,242,204,157,151,140, 81, 38, 96, 96,237,
-211, 85, 0,113,112,179, 11,111,253,197,151,203,167,207, 79,127,255, 81,238,221,187,160, 83, 59,111, 85,171,241, 84,104,212,230,
-110, 52, 70, 52, 0,249, 92, 82,173,195,188, 2, 95,165,143, 6,171,145,231, 97, 13, 13, 41,214, 50, 85, 56, 73,176,122,222,197,
-171,129,248,190,217,118,236, 80,174,182, 75, 47,171, 22,255, 23,224,178, 65,109, 86, 98, 54,224,219, 14,171,166,106,226, 48,199,
- 16,143, 80,149,176, 98, 71,157,204, 94,141,213, 17,152, 59, 94,116,219,113, 59,193, 90,250,237,111, 83,124,189, 26,244,226,226,
-209,131,108, 55, 27,166,218, 90,179, 15, 53, 19, 94, 3,232, 13, 72, 69,175,238,113,127, 9,165,206,180,182,162, 31,162,146, 32,
- 23,117,197, 27, 11, 96,195,137,137, 83, 3,112,213, 37,240, 52, 30,158,167,108, 81,217, 67, 82,222, 41,182,135, 85, 60,149, 10,
-208,131,128,164, 3, 42,254,190,247, 70,104, 7, 4,132,176,198,211,247,202, 22,181, 84,202, 0,238,187,178,104,141, 90, 30,169,
-206, 60, 56,242,139,211,197,241,167, 87,242,217,233, 93, 92,185,205, 93, 73, 33,229,179, 71,231, 63,197,221, 31,225, 95, 70, 22,
-112,171, 14,139, 92, 12,140, 55, 19,188, 58, 39, 61,241, 2, 92,190, 76,237,160,228, 66,230, 22,228,205,232, 29, 8, 62, 6,216,
-177,141,189, 43, 80,231,248, 48, 68,139, 96, 71,200,216, 15,207, 87,249, 93,157, 13,102,108,212,108, 19, 47,170, 3,166,205,121,
-243,228,217,197, 15,187,219,223, 24,208,194,124, 69, 32, 85, 47, 85,207, 83,151,200,202,158,167,134, 20,220,207, 55,208, 57, 76,
- 78, 87,220,166,204,211,173,110, 94,143,161,219,130,214, 76, 26, 55,204,195,126,153, 94,124,247,234,109,181, 80, 71, 49,227, 55,
-110, 98,242,109, 86,118,236,231,133,141,104,216, 50, 12, 83,113,104,234,186,236,107,222,129,102,155,186,186, 0, 70, 68, 16,209,
-199, 37,196,156,163,233,160,236, 66,227,202,205,144,215, 33,117, 18, 12,125,208, 16, 1, 12, 87, 73,227, 70,175,215, 85,133,226,
-204,237, 93, 37,241,121, 61,116,202,214, 59,211, 2,123,247, 80,117,170,186,135, 21,243,191, 0, 36, 93,203,110, 28, 69, 20,173,
-103,119,117,207,244,120,108,227, 8,112,136, 37,243, 8, 9,145, 32, 10,136, 5,107,150, 44, 16, 75,254,128, 95,226, 43,224, 31,
-216,176, 38,202,202,139,200, 88,202,195,246,216,211, 51,213,221,213,213, 85,156,211,200,139,177,100,143,229,169,174, 91,247,156,
-186,247,158,163,159,125,255,133,212,235,194,209,234,162,114,102,173, 79, 26,112, 53, 91,137,181, 89, 22,139,198, 45,105, 7,107,
-171,208, 4, 87,175,107,233, 26,103, 42,179, 45,215, 37,185, 79, 93, 59,225,130, 59,254,242,252,244,211,191,126,111,239, 70,117,
-192, 97, 81,142,186,141, 30, 71,250, 68,151, 64,163, 99,164, 21, 9,104,231,200,161,217,178, 90, 41, 75, 41,185, 72,185,163, 68,
- 47, 8, 85, 16, 75, 81,178, 1, 9,187,163,236,126,200, 99,236,135,228,143, 87,160,128,235,219,205,105,155,176,241,124, 44, 83,
-236,241,162, 99, 24, 91,154,178, 2,179, 53,199, 31, 29,254,244, 93,255,227,183, 87,181,185,184,122,115,221, 33,186,238,193, 5,
- 41,181,155, 71,178,115,176,210, 52, 40,121,135,141,230, 67, 65, 49,184,110,246,178, 37, 18,163,101,146,108, 58, 19,141,141, 28,
-215,212,170,144,164,122,248,153,162,197,139,225,228,161,165, 0, 95, 66,204, 43, 94,245, 7, 67,143,119,177, 79,129, 51,174, 35,
-248, 35,141, 96, 17, 39,145,170,102,188,217,225,120, 60,144, 1, 69,112,163,146,200,236, 13,167,205,240, 62, 93,219,211,167,199,
-175,111, 30,189,185,146, 46,177,178,233, 26,197, 38,234, 98,166, 83,213,132,192,197, 67, 27,176, 52,247,241,204,174,126,251,245,
-228,231, 95,188, 24, 46,218,151,239,198,187,113,184,145, 20, 98,148,209,123,177,223, 38,154,141, 95, 42,177, 77,187,205, 72,239,
-194,109,222, 68, 80, 64,186,212,246,244,207,142,251, 62, 3,178,133, 93,162,252, 46,210,198, 64,208, 64,125,149,158, 19, 3,188,
-230, 22,162,213, 44,105,230,185, 27, 82,104,177, 85,146,142, 85,147,222,139,252,122,151, 30, 61,209,207,159, 47,240, 72,212,161,
-164,110,132,163,109,180,114,133, 29, 73,102, 56, 17,160,105,167, 72, 67, 94, 49,178,179, 58,179,198,136,165, 24,177,246,180,217,
-152, 53,123, 82,140, 62,210, 77,120,199,185,139,160,152,233,144, 61, 52,113, 96,169,211,152,111, 41, 24,172,102,125,202, 60, 55,
- 36, 43,103,244,193,212, 60,121,120,255,201,215, 47,223,190, 71, 38, 90, 41,172,242,228, 83,218, 88,160,134,180,233, 13,206,102,
-100, 32, 51,155,250,244,119, 50, 32, 45,235,100, 60,206, 37, 78,140,142,156,206,158,104,252,100, 4,115, 45,139,134, 41,249,233,
-223,100,191,250,172, 57,154,118, 61,194,124,201,203,117,170,234, 35,220, 11, 60, 52, 74, 34,129,126,196,185, 84, 44,136,151,103,
- 27, 94,252,103, 5,253, 0, 44,130,174,167, 78,110, 2,132,111,140,247,247,246,189,255,240,135,234,217,139,179,139, 87,230,246,
-170,205, 57, 87, 35, 19,134, 94, 42,238,232, 18,155, 54, 29, 91,123,176, 80,253,161, 22, 75,196,166,238, 86,148, 3,174,106,135,
- 12,106, 28,117,214,113,216,166, 1, 80, 61, 3, 83,129,204, 3, 68, 75, 93,246, 69, 35, 10,214,245,189, 47,114, 77,167,140,161,
-196,161,159, 90, 67,101,238,144,213,182,171,139, 61, 78, 79,172,180,169, 23, 19, 8,215, 14,152,101, 24, 52,245,230,136,108,108,
-166, 77,104,113,160,241,253,213, 59, 21,106,119,190,206,108, 6,245, 1,116, 68,213,106, 97, 41,180,181,199,167, 7, 27, 72,179,
-206, 47,120,209,221,255, 29,179, 89, 20,130,130,179, 96,246,200,173,139, 81,134,229, 34, 1,212,135,158,178,238,216, 57, 28,155,
-194, 7, 89,156, 20,179,189, 26,136, 25, 66, 40,117, 30, 47,153,138, 71, 88,165,128,192,159,168,223, 71,109, 27,189,103, 75, 34,
- 14, 36, 91, 56, 91, 21,216,232,211, 98,125,244,224,243,199,234,233,249, 8,208, 10,170, 0, 24,154,237,195,229,217, 7, 71,255,
-248,235,183,211, 70,234,182,164,235,125,110,241,118,172,134, 28,172,168,235, 56,142,115, 21,158,100,138,157, 95,224,175, 30,187,
- 29,152,140, 2,214, 38,150, 28,204, 7, 8, 92, 68,170,246, 57,169, 83,116, 82,238,134,111,110,245, 13,167, 28,169,146,210,229,
-190,142,145,151,190,143, 63,182,149,250,163,189, 12, 72,101,218,238,167, 4,166, 8,116, 54,178,186, 78,169, 42,110,123, 4,191,
-136, 75, 98,215,200,210, 20, 75,119,142,221,161,162, 24,231, 12,195, 47, 57,167,214, 66, 93, 63, 40, 95,252,249,247,229,182,189,
-139, 81,181,125, 72,131, 88,117,192,237, 58,181, 90,150, 45,210,102,115,195,202,228,222, 27,159,186,144, 84,200, 33,116,169,239,
-123, 53,255, 97,221,171,229, 16,204, 48, 37, 18, 58,250,209,234,213, 92, 21,137, 59,176,169,154,125,245,241, 30,169, 2,188,143,
-173, 47, 42,117, 56,157, 57,219, 83,240,247,123,231,101, 5,112,202,154,154,119,147,252, 79, 0,146,174,102, 71,142, 26, 12,186,
-109,119,219,253,179, 51,179,195, 46, 89,237,146, 31, 41, 74, 16, 2,133, 92,200,133,192,133, 19,207,193,137,231,131,119, 0, 9,
- 33, 69,226, 64, 56, 37,145, 16,104,119,179, 25,205,244,204,184,221,118,183,169, 50,183,213, 74, 59,218,113,187,235,171,242,247,
-185, 74,125,241,252,203,229,133,110,214,105,173, 77,217, 53, 45, 21, 56,221,171,171, 18,122, 79,150,173, 41,165,109, 5, 77, 6,
-108, 19,165,225,155, 48,138,165,236,206,116,201,209,248, 54,170,205,114,241,244,108,187,254,245,167,219,155, 8, 29, 17,170,196,
-248, 56, 44, 58,251, 8, 35,179,100, 88, 84,125,161, 45,205,108,120, 41,200,128,172,224,247,248,186, 88,157, 2, 52, 12, 91, 86,
- 24,192,145,170, 50,239, 59,164, 52,238, 35,237, 13, 80, 92,220,253,123,255, 62,184,183,177,204, 73,253,120, 8,231, 33, 52, 97,
-180,109,173,186,197,234,197, 19,245,253,179,187,239,158,190,185, 84,127,246,155,119,123, 46,146, 77, 76,118,194,218,143, 46, 59,
-138,142, 60,112, 44,122, 57, 98,253,254,111,144,214, 81, 24,167,161,149, 98, 71, 83,119, 6,132,229, 62,155, 4,114,102, 56,231,
-192, 95,161,139, 78, 64,162, 1, 85, 24, 8,153, 3, 9, 82,118, 53,103,207,206, 13,115, 12,185, 60,129,249,209,243, 54,162, 36,
- 13, 46, 0, 29,171, 34, 92,211, 1,142,132,195, 39, 15,124,139,218,121, 66,190,215,122,161,213,229,227,110,245,201,250,183,223,
-153,210, 54, 53,139, 74,181,109, 57,149, 86, 3, 95,161,219, 38, 80, 61, 23,167,222,126,253,249,163, 31,126, 76, 95,125,251,143,
-120,251,182,127,117, 61,244,242,184,243,110, 55,249,113,118,187,249,112, 59,171, 77,242,248,225,253, 36,204,156,182,168,217,105,
-231,121,122, 8,204,243,144, 53,199, 57,246,243,225,142, 35,249, 97, 40, 92,182,150,105,242, 0, 49,240,174,215,217,245, 5,155,
- 41,208, 56, 12, 91,153,126,235, 90,176,105, 93,165,150,134,176, 2,181,161, 91,167,151,223,212,237,170,242,109,217, 46, 75,218,
-176,129,186,114,200,138, 98, 74, 26,102,110, 9,182,220, 24,174, 2,245,154,232,144,155, 56, 92,176,141,244,152,239,149,238, 71,
- 31, 11,135,106,140, 23, 97, 91, 2, 94, 33, 31,228,150, 15, 3,184,132, 23,119, 24, 24,158,224,233, 7, 73, 28, 22,117, 33, 27,
- 30,209,204,216,188,118, 60,127,116,127,115,241, 96,243,225, 58,226,207,253, 0,169, 17, 80,106, 29,231,201,107, 82, 40, 72, 49,
-157,189,184,192,250, 82,211, 8,113,218, 16,251,152,218,157, 39,151,115,131, 21,236,109,152,166, 22,148,173,166,128,221,111,196,
-242,162,123,190, 24, 54,238, 0, 8, 44,122,182, 29,114,251,140, 35, 64,202, 49, 96,158, 94,184,138,202,155, 61, 90,108, 23, 8,
- 11,193,224, 54, 69, 43,170, 9,152,167,117,228, 8,217, 81,112,244,235,221,112,245,242,244,242,241,197, 95,175, 99,191,191,173,
-172,154,207,233,244, 9,102,141, 5, 95,157, 24,119, 2,250, 8,129, 21, 22,144,201,153,111,163,154,212, 6, 80, 57, 57, 94, 28,
- 3,189, 81, 60, 14, 4, 74, 98,167, 81, 54, 72, 60, 23,192,189, 62, 28, 11,218,248,242,157,130,170, 16,186,169,244, 82,130, 21,
- 20, 19,157,236, 5, 74,245,204,225, 25, 25, 70, 15,190, 86,248, 19, 81,236, 34, 45,180, 24, 97, 58,207, 11,148,153, 26, 15,219,
- 52,224,223,254,117, 63,142,245,242,225, 71,157,153,222, 59,142, 19,160, 14,166, 3, 52, 76,145, 44,152, 30,189, 8, 5, 93, 67,
-240,213, 79, 1,255,178, 25, 37,180,213,112, 44,181,179, 0, 49,237,226,134,215, 31,193, 15,241, 22, 48,224,194,241, 34,233,132,
-135,112,192, 39, 15, 96,100,105, 90, 37,115,152, 77,143, 58,144,192,160,107, 60, 33,139,149,157,184, 83,198, 56,200,100,140, 50,
- 39, 85,117,149,218,211,121, 93, 46,174, 62,253,108,120,118,255,131, 97,184, 98,132,208,143,199, 80,116,103, 75, 91,137, 95, 32,
-135, 24,246,199,235, 20, 96,203, 35,247,168, 7,153, 60, 45, 61,173, 85, 50,202,230, 3, 61, 39,152,156,158,155, 55,180,239,152,
-243, 41, 27,157, 1, 3, 51, 59,253, 82,212, 90,152,100,235,234,102,255,226,160,254,150,249, 52, 18,255,127, 37, 3,120,152,106,
- 86, 79, 46,110,142,215,127, 12,119,163, 0, 52,242,170, 4,223,126, 6,120,240,172, 61,187, 77, 50, 58, 24,176,218,242,234, 29,
- 74,216,196, 45, 42, 2,231, 35, 9, 95, 3, 79,231, 19,239,118, 51,239, 64,150,193,216,135, 63,191, 10,219,254,186,229,241, 19,
-207,232,108, 1, 82,192,254, 22,217, 94,178,209,135, 80,233,106, 54,154, 23,223, 20, 20, 70,217, 51, 4, 90,115,180,171, 86, 94,
-122, 35,110,104,240,183,183,193,239,167, 36,135, 82, 56, 65, 3, 4,104, 8,199,160,223,170,183, 21, 40,240, 60,117,208, 92, 6,
-132, 32,170,170,167,117,150, 9, 60,235,172,154,150, 84,104, 23,172,253, 79, 0,146,174, 93, 55,146, 42, 10,222,190,143,190,253,
-156,177,141,141, 1,173, 16, 66, 34, 96,165,149, 86,218, 28, 68, 76,142, 4,191, 65,204, 63, 16,242, 11,252, 4, 49, 17, 1, 34,
- 0,132, 48,200,107,216, 93,205,216,158,158,233,231,125, 81,213,196,150,165,153,158,211,231, 84,221, 91,167, 74,111,243, 45,183,
- 65,178,205,193,132, 26,173,189, 17,182,164,112,196,186,202,228,162,222,208,224, 16,132,185,237,175, 76,214,175,235, 43,131,108,
- 54,130, 82, 2,171,152, 29, 28,219,250,250,234,151, 31,194,205,212,130, 54, 15, 34,238, 68,108,129,225, 50,238,154,225, 71,232,
- 14,114,115, 78, 19,173, 50, 75,131,163, 20,176,168,208,251, 48,154, 85,121, 25,120,184,169,100, 89, 98, 16,132, 52,216,132,255,
-204,195,208,103,186,226,140,245,111,186, 49, 28,247,255,170,246,239, 23,117,240,231,117,119,184, 76,166, 70,169,148, 60,179, 62,
- 36,241,170,127, 56,116,195,216,117,185, 9,133,168, 84,177, 79,138,214,186, 92, 23, 2, 61, 74,189,227, 45,161,112,103,206,211,
- 30, 18, 45, 60, 37,218,245, 22, 32,152,130, 65,151, 84, 79, 48, 31, 37,210,155, 3,240,218,175,107,235,115, 42, 35,197,235,153,
- 6,224,162,100, 22, 99, 14,252, 35, 77, 17,136,175,207, 41,238, 11,244,195,166,137, 55,222, 1,204, 45, 46,224,163,160, 40,250,
- 77,224, 98,244,204,242,170,205,103,180, 85, 96,134, 19, 5,230,170, 77,125, 72, 55,127,237,222,121, 62,159, 95,213,243,163,105,
-173,166, 74,173,136,249,192,112,198,173, 54,247, 99,189, 61, 47, 62,255,164,252,234,139, 81,229, 55,203,207,119,221, 27,148,253,
- 50, 46, 50,238,233,128, 48,228,153, 60, 36,127, 31,143, 49,158,146, 3,117,112, 15, 50,244,232,145, 40,220,160, 68,156,239,197,
- 36, 85,241, 8,232,236,199, 40,200,240, 25,156, 78,189, 35, 10,172, 2,209,157,201, 38,163, 23, 23, 37, 87,240, 59, 12,136,213,
- 29,147, 65,175, 84, 87,203, 46, 15,225, 36,142, 46,126,250, 84,159, 93, 0, 72,170,162,166, 79, 58,166,126,178, 5, 42, 68, 54,
- 19,215, 13,140,225,157, 70, 22,214, 51,123,204, 83,114,105, 12, 51, 10,198,105,223, 0, 92,229, 39,165,241,203,166, 62,197,131,
- 1,137, 10, 22, 85,185,106, 51,240, 94, 40,222, 11, 25, 0,220, 19,213, 46,188,131, 15, 96,231,116,245, 98, 55,105,162,174,181,
-125,114,253, 79, 7, 20,212,172, 54, 48, 83,234, 39,177, 77,170,208,217, 73,122,153, 40, 10,137,129,182,192,160,234, 70,142, 41,
-181, 59, 17,212,122, 98,179,172, 39,210,229,178,128,197, 24,197, 36,241,153,129,148,146, 17,150,253,171,201,199,183,207,170,135,
-199,112, 74,162, 41,240,181,179,211,234, 29,205, 8, 69,112,123, 5,220, 15,146, 4, 92, 98, 49, 26, 61, 87,221,124,203,243,215,
- 12,140,100, 6, 43, 0, 61,146,153,157, 20,173, 34, 83,119,123,171,191, 79, 31,127,249,252,235,111,158,125,247,173,125,253,251,
-159,234, 24,172,110, 69, 57, 59, 43, 27,160,162,217, 13,128,157,165,115,111,101,118,142,245, 42, 85,154,178,116,190,193,227,215,
-131,165, 44, 34, 23,235,160, 5,104,182, 69,239,226, 54,113,148,250,236,194, 21,161,194,251, 61, 58, 31, 43,244,224, 71, 17, 92,
- 85, 88,185,245,227, 81,208,125,128,219,183,118,166,165,157, 24, 76,147,244,164, 25,131, 48, 37,157, 3,158,160, 11, 11,213, 84,
-125,216,224,221,106,180,247, 63,253,145,196, 78,126,246,238,251, 79,230,151,119,185, 88,142,149,157,193, 29, 57, 49, 37, 83,159,
-179, 98,171,199,113, 54,187, 26,253,102,116, 12, 98, 76,102,113,149,167,102, 44, 95,108,172,213, 56,133, 83,232, 82,160,175,228,
-255, 82,193,189, 43,248, 80,101,118,196,111,145, 82,191, 20, 92,136, 4,255, 90,240,112,104, 73,230, 36,154,153, 2,247,207, 36,
- 88, 13, 96, 36,222,199,162,105,234,235,143,194,211, 15, 38, 32,226, 7,176,183,209, 51,187, 35,122, 64,244,252, 65,168, 91,102,
-111,104, 38,220,226,147,100, 35,157,254, 66,180,108,244,198,155,138, 11,151, 62,160,181, 17,244, 41,106,182,132,102, 66, 83,148,
- 26,181,108,104,216,198,191, 48, 86,218, 12, 32,153, 65, 57, 59, 13,128, 32,123,153,213,129,233,165,134,183, 28, 62, 94,230, 31,
-154,226,199,163, 3,164, 74,185,207,228, 36, 67,225, 70, 42,238, 0, 19,208,181, 13,105, 59,120,186,209,214, 51,112, 72,225, 91,
-163,124,129, 98,122, 45,209,238,220,122,113,195,123, 25,154, 83, 37,170,253,146, 41,126,123,175,126,113,231,126, 69,187, 96,242,
-194, 20, 59, 80,170, 41,207,131,242,101,175,194, 33, 74,250,128,103,254, 52, 79, 11, 8, 84,109, 84, 95,102, 12,200, 27,128, 62,
- 80, 51,157, 61,216,205,100, 67, 91, 3, 30, 6,124,180,234, 40, 42, 86, 39,243,177, 68,110,182,152, 93, 11, 0,150,216,233,165,
-209,178, 93,172,206,211,228,117, 5, 70, 26, 38, 89,214,203,126,105,235, 50, 70,176,134,255, 4,224,232, 74,118,228, 40,162, 96,
- 46, 85,153, 85,213,219,216, 98, 60, 30,203, 26,132,176,196,193, 50, 50,146, 37,240, 17, 14, 28,248, 6,174,124, 41, 23, 14, 92,
-230, 0, 18,150, 89,198,146, 7,131, 77, 79,119,215,154, 91, 37, 17,245, 1,173, 82, 87,230, 91,226,213,139, 8,253,213,119, 95,
- 20,181,218, 72,116,238,118,179, 51,166, 54,130,170,147, 22, 93,126, 99,144,195,203,100,249, 13,200, 24,188,240, 94,218, 53,103,
- 94,165,218,106, 46,135,211,159, 92,250,237,197, 39,159,253,245,163,251,233,218,159,115,216,190,124,108, 94, 80,246, 17,109, 47,
- 63,218,104, 77,245,119,160, 39,157, 45,234,147, 26,172, 82, 20, 62,163,209,115, 57, 51,160, 9,215,201, 37, 55,114, 21,218,125,
-150,123, 2, 63,126,131, 20,139,189,198,236, 70, 55,124,184,235,218,125, 58,221,138,244,170, 80,191,207,167, 55,199,253,187,241,
-212, 29,186,130,250,117, 45,109, 70,194, 66,107, 53,128,101, 19,245, 97, 1, 93, 73,200, 2, 96,246,148,243, 10,212,166,146, 41,
-209, 66,145,251,124, 29,131,157,206,159,116, 42, 84,244,178, 55,204, 23,248,123,177,206, 28,161,178,121,144,102, 83,202, 69,128,
-133, 64,158,106,239, 82,244,161, 16,148,187,199,185,207, 29,249,208, 41,144,161,234, 10, 98, 81, 46,228,226,161, 29, 37,208,125,
- 80,213, 17,109,174,230, 34,184, 85,184,161, 74, 43,156,212,229,243,251, 93,119,117,243, 38, 54, 43, 33, 27,244,177, 59,188,156,
-222, 41, 61,231,143, 26,251,195,247,103,223,126,125,171,218,215,119,215,255,142,183,115,156,196,120,151,198,137,178, 83, 14,117,
-113,175,167, 67, 28, 58,146, 28,215, 3,231, 69,211,144,199, 94,152, 41,143, 3,121,133,241,144, 67, 68,226, 74,232, 83, 86,153,
-171,192, 83,224,224,157,118, 43,130,236,191,204,177, 53,235, 13,173,116,113,141,137,175, 72, 24,175, 56, 76, 82, 36,225,148,243,
- 93, 59, 63,125,170, 95,188,220,246, 86,231, 45, 26, 95, 54,251,102, 35,105, 20,101,113,104, 36,164,179, 25,166,250,186, 89,184,
-143,148, 21,163,223,149, 54,185,117, 83,145, 98,143,128, 16,110,200,115,160, 39,133,115,165,108, 82,221,205,114,148,190, 23,181,
-145,195, 16, 98, 52,131, 15, 26, 80, 35,144, 6, 23, 11,145, 20,245,136,245, 86, 84,213,252,224,209,218,124,249,205,245,127,253,
- 97, 58, 9, 90,158,251,112,164, 94,135, 50,110,216,147, 30, 95, 49,158, 81, 68, 5,127, 47,215,172, 46,222,123, 75,229,174, 9,
-143,110, 82,129,176, 33,211, 36,144,159,173,185,115,104,144,147,147,190,109,227,213,197,249,199,198,119,190, 35, 2, 30, 41,178,
-184, 0, 51,192, 57,175,113,248, 98,177,170,165,187, 94,145, 26,138, 40,106, 23,164, 95,220,168, 61, 85,196, 53, 26,178, 53, 0,
- 7,197,224, 80,249,252,216,206,127,119,151, 47,119, 23, 79, 30,255,249,155,118,221, 65,213,238,126,133, 95, 84, 40,234, 13, 89,
-170,136,193, 66,199, 82,117,129, 28,236, 38, 90, 20,179,220,152, 74, 58,218,136,171,202,197, 17,151,129, 19, 35,212,184,106,170,
- 93,218, 86, 6, 32,214,166,228,154, 0, 40,104, 27, 90, 56, 13,126,227,163,159,227,144,206,108,137,215,119,158,108, 95, 37, 68,
- 80,236, 44,189, 95,145,172,233,113, 32,200, 51, 77,184, 43,180, 57,143,228, 95, 4,206,191,197,189,244,246,238,116,176,103,159,
-150,171, 42,220,100, 74, 1, 34,237,115, 77,139,188, 13,164, 53, 89,250, 3,115,231, 92, 59,198, 14, 32, 85,240,105,208,225, 32,
- 42, 23, 76, 87, 0, 26,182,193,217, 35, 80, 57, 58, 24, 36, 47,223,227,122,167,133,130,195,203,195,128,158,198,172, 53,173, 47,
-131,155,169,254, 44,208,139, 8,133,115,105,106,127, 89,218,157, 88,159, 21,143, 30, 63, 79,159,191,152, 31,228,211,251,147,104,
-156,112,157, 2,174, 70, 73, 24,119, 15,207, 46,230,233,231,120, 66,215, 50,112, 1,178, 51, 42, 53, 18, 73,104,139,182, 33,115,
- 22,132,234, 78,201,126, 93,208,119,112,150, 53, 25,229, 9,255,212,207, 98,181,161,163, 43,215, 17,169,180,162,231,154, 59,198,
-117,111,227,229, 77,251, 44,150,111, 85,105,209, 70, 76,252, 16, 5,248, 20, 30,110,174,238,169, 95, 78,239,254,145,222, 45,110,
- 59,220,123, 35,205,151, 46,211,212, 38, 68,150,151, 20, 27, 93,163,247, 70, 72, 41,252, 29, 52, 0,220,197, 20,186,166,163, 65,
-230,248, 1,185,158,147, 53, 81,162,170,132,178,214,175,255,120,246,106,255,171,140, 21, 3, 62, 9, 58,124, 26, 0, 74,154, 70,
-209, 4,145, 18, 82, 18,149,132,214,228,146,187,192, 62, 24,125, 76, 25, 39,136,115,194, 19, 23, 19,191, 0,180, 0, 28, 69, 25,
-223, 16,167,170,108, 56,111, 36, 61,202,106,125,104, 11,169,218,170, 0, 50,226,194,163,204,171, 73,186, 80,172, 54,186, 79,232,
-106,150,253, 39, 42, 74,196,255, 5, 32,233, 90,118,228, 38,162,104,189, 93,101, 79,119,103,210,131, 16,132,215, 6,177, 97, 17,
- 16, 18, 11,144, 88, 32,241, 59,124, 4,124, 7,127, 2, 98,207,146, 5, 66, 68, 34, 17, 17, 40, 36,100,122,218,118,219,174, 42,
- 87,113,142,103, 53,234, 77,183,199, 85,117,239, 57,117,239, 61,199,216,157,241,202,219, 27,154, 7,138,234,157,214,187,189,211,
-129,174,220, 94, 98,239,179,141,151,229, 8,103,214,229,176,234,112,216,129,112, 53,148,168,183, 53, 24, 51, 91, 29,119,237,192,
-201, 82, 68, 22,134,117,182, 24,157,182, 27,151, 64, 35,144,138, 77,160,167, 40,173,139,188, 8, 49,135, 88,117, 95,187, 61,107,
-136,216, 84, 0,193,138, 92, 84,227,168,118,108,159, 1,115, 20, 57,112,126,210,229, 20,141,124,149, 29,142, 2, 48,187,110, 42,
-182,123,140,102,146,165,115,180, 25, 93, 89,230,229,240, 52,157, 81, 98, 69,124,156,139,138,121,113, 23,126,237, 36,105,138, 4,
-158, 56,208, 72, 25, 9,217, 78,188, 36, 1,222,212, 8, 85,224, 50,206, 48,150,197, 82,233,115,185,142, 66,181, 7, 0,206,237,
- 12, 3,171,123,146,118, 42,204, 46,200, 72,169, 82,122, 79, 16,121,102, 10,202,131,188,109, 58,100, 42,123, 74,229,131, 61,213,
-197, 24,154, 38,234,130,148, 62,233,121, 42,180, 21,185,172,209, 73, 74, 33, 85,154,212, 84, 47,186,198, 12,177,172,227,240,225,
-123,233,103,123, 53,219,126,239, 44,194,151,224, 48, 83,247,213,151,254,155,207, 94,236,143,127,212,167,191,157,254, 98, 9, 49,
- 95, 10, 48, 2, 13, 43, 82,158,146,156,238, 64,159,214,233, 54,113, 28, 41,201,115,169,253,109, 13, 75, 29,248,107,202, 14,194,
-206, 18,187, 54, 35,232, 75,222, 21, 98, 53,134, 69,116,146,194,239,200,149,196,233,114,211, 51,227,216,199,189,147,136,232, 28,
- 13,121, 72,102, 12,111, 81,119, 87,249,245, 89,236, 30,138, 79,191,232,250,166, 25,199, 28,222, 32, 76, 12,135, 10,228, 76,113,
-122,252, 67,142,127,172,165,200,215,150,206, 41,185,142, 47, 83, 43, 45,217,198,205,193, 72, 80, 34,153,218,157,181,171,233,206,
- 1, 81,129,252,156, 57, 69,134,192, 83,227,146, 57,140, 55,234,192,107, 46,226, 68,179,110, 86,165,155, 97,105, 1, 78, 0,138,
-126,235,250,217, 72,255, 54,254,114,173,255,129, 52, 29,125,153,105,117,195,107,131,105, 13,182,142, 3, 71,162, 36,162, 96,179,
-250,133,147,131,249,164,175, 17,159,144, 81, 52, 8,183, 1, 35,221,172,122, 8,225,219,146,247,215,108,154, 94,231,225,151, 39,
-229,163,199, 71, 55,191, 6, 47,194,185, 65, 38,144, 20, 17,212,133, 22, 79,197,102, 54, 55,144,113, 76,120, 35,200,119,138, 98,
- 98,160,206,125,113,187,109,136, 92, 17,116, 11,186, 3,146,139,168, 88, 95, 62,121, 30,126,148, 31,127,253,201,183,223,191,243,
-195,119,229,197,211,103,200,200, 93,167,213, 92,105,209, 23,216,141,173,236,180, 13, 82, 56,169, 91,202,171, 39, 36,119, 29,210,
- 40,246, 65,120,172, 78,117,197,165, 37,107,218,120, 16, 42, 85, 5,206, 17, 70, 36, 81,203,185, 39,183,154,102, 15, 66, 9,244,
- 32, 67,150, 26, 57,178,157, 87, 17,102,137,211,208, 43, 71, 41,164,220,116,192,172, 55,238, 52, 34, 15,167, 27, 0,239,128, 4,
-143, 83,189, 94, 26, 68,187, 89,141,193,253,254,234,242,211,205,187,159,179,217,226,215,126, 95,154,198, 83,123, 59, 34,150,165,
-220, 91,215, 10,185, 96,215, 85,228, 62, 11,234,161, 1,119,103,188,140,126,192, 74,159, 98,186, 31, 0,203,108, 47, 90, 10,199,
- 70, 50,226, 79, 95,149, 4, 62,189,163,220,174, 92,183, 14, 16, 64, 83,172,195, 89,139,163,161, 99,138,245,129,205,121, 65,188,
-217,134,238,237, 71,254,253, 15,250,195, 75,253,111,209,242,202, 2,148, 25,114,154, 90, 39,101,162,234,192, 29,118,202,167, 16,
-109,236,121, 49,195,174,127, 15,108,102,144,170, 60, 62, 62,216, 64,228, 10, 86,190, 90, 22,191, 88,176, 18,142, 21, 78,132, 88,
- 65, 35, 57,208, 0,228, 93, 47, 59,151,214, 65,149,101,172,143, 6,255, 39, 30,167,220,202,166, 51, 74, 46,102,105,164,191,222,
-239,254, 46,229,121, 1,252, 76, 49, 33,172, 75, 94,215, 22,176,133,245,254,144, 24, 77,240,143, 56,143, 5, 71,244,104,170, 7,
-176,197,182, 48, 44,130,176, 61, 3,207,110,133,154,139, 97,137,166,208,131,205,177,179, 20,220,230, 76, 29,205,208,128,245, 84,
-208,175,109,130, 2,251,184, 49,212, 0,196,185, 94, 0,175,197,189,240, 56, 34,122,209,150, 78,176,133, 35, 15,151,162,205,217,
- 59,132,175,134,237,245,120, 67,123,175,150,146,254, 65,138,167, 7,195,152, 64,125,117, 51,171, 22, 15, 54, 93,226, 67,100,124,
-215,228,124,174,120, 79,229, 8,218,209,138,201,165,150,126,124,211,255, 2,112,116,109, 43,114, 84, 81,244, 92,235,218,149,238,
-233,196, 27, 24, 39, 68,133,128, 35, 8,190,120, 65,130, 31,224,139, 63, 45,232,147, 72, 30,124,144, 6, 13, 73,196, 76,167, 47,
- 85,117,234, 92,170,142,107,213,203, 76, 51, 52, 61,213,167,206,217,123,173,218,123,175,165,159,255,244, 93,163,111,182, 55, 59,
- 75,149,232, 40,186,178,166,204,120, 2, 57, 54,198,143, 93, 83,201,178,161,254,125, 77,115, 73,156, 86,128, 81, 91, 36, 64,205,
- 58, 20,165,168,192, 24,246, 31, 60,126,115, 40, 94,252,114,158,217,119, 65,249, 20,192,201,113,157, 0,108,137, 16, 83,140, 86,
-128,158,225,220, 35,134,128,191,123,133, 93,136, 3,135, 44,195,118, 20,214, 48, 0,148, 44,253,228,139,233,191,215, 20, 43,154,
- 76,184,130,154, 6,234, 70, 97,171,196,224,176, 7, 35,117,116, 64,185,245,160, 38, 90, 33,208, 33, 41, 35,146, 30, 19, 2,147,
-212, 52, 44, 34,217, 71,104,187, 7, 19,167, 94, 59,162, 48, 34, 95,233,104,235,161,215, 57, 90, 91,179, 63, 23, 0,131, 37, 2,
-189,176, 37, 72,172,229,210, 13, 29,121, 52,150,168, 3, 63,161,158,120,202, 5, 45,106,240, 91,174,120,151,167,143,130, 42,216,
- 87,156, 46, 24,216,215,191,176, 21,140,207,224,215, 97, 99,133,127, 8,180,136,171,192, 23, 94, 0, 93,105, 49,193, 80,140, 24,
- 4, 90, 38, 89, 79,171,117, 55, 87, 59,253,228, 89,253,215,171,253,241,126,114,206,134,114,255,197,227,246,231, 31,199,231,223,
-255, 91,218, 23,151, 63, 14,151,151, 41, 58,229,174,201,189, 19,180,151, 65,222,191,204,203, 73,176,137, 97, 38,239, 66,252,137,
- 67,158, 6, 16,178,213, 66, 29,239, 9, 57,227, 76,122,113,245, 75, 51, 35,112,208, 49,117,117,174, 33, 84,167,168, 58,149,141,
-217, 27, 19, 4,135, 84,217,250, 45, 41,189, 23,184, 82,171,177,149, 21,103,164,144, 4,162,176,252,112,103, 30,222, 54,227, 38,
-201, 71,186,227,180,180, 44,106,203,138,115, 57,171, 13, 64, 9,189,175,129,214, 88,160,101, 42,230,248, 60, 9,126, 46,176,222,
- 96,118,226,104,248, 34,136, 56, 74, 61,186,233,194, 70, 58,217, 83,115,102,117, 79,227,101, 51,163, 79,192, 99,113, 26, 36,214,
-135,178, 4, 37, 21,245, 21,110, 80, 39,171, 90, 60,252,230,219, 87,221,238,248,238,144, 89,178, 22,105,192,251, 98, 28,221,160,
-170, 18,244,139,211,144,160,212,184,234, 57,205, 83,129,207, 44,226,228,216,203,135, 91, 70, 49, 58,156, 63, 28,210, 27,166, 11,
- 32,222, 92,205,133,201,174,214,103, 71, 6,246,242, 42,159,126,190,249,196,247,103, 69,207, 39,234, 24,210,104,130,254,136, 88,
- 80,108,204,165,208,180,231, 5,244,218,209, 44, 15,199,140,141, 96,195,250,184,128,182, 44, 72, 97, 89,183,244,208, 83,220, 97,
-100, 48, 23, 28,218, 55,238,253,103,237,167, 95,127,244,246,212,189, 61, 93,203,141,227,195, 40, 36,175,202, 70, 90,153, 82,138,
- 52, 37,142, 16, 34, 97,120, 89,231,106, 50, 0,239, 17, 31,106,128,154,194,162,103,103,249,152, 76, 98,235,243,169, 56,117,237,
-173, 40, 39,121, 50, 37,101,131, 19, 43,184,160, 98, 81,184,156,219, 94, 75, 89,235, 42, 33, 43, 53, 58,109, 26, 3,248, 95, 86,
-128,228,139,159, 53,197,123, 40,174,174,198, 56,208, 38, 11,175, 2,123, 89, 39, 96,145,215,163,223,154, 15, 63,246,247,174, 31,
- 84,172,229, 98, 3,141,169, 37, 22,215, 19, 27,169, 50,207,195,213, 78,137, 78,118,177,119,184,122,211,103,226, 37,234, 34, 1,
- 83,227,216,235, 97,194,162, 71,142,128, 47,154, 26,212,200, 10,125, 44, 0,142,172,106,240,211,167,170,192,126, 83, 37,139, 52,
- 37,226, 7,160, 67,179,221,188,119,251,196,220,125,117,220,110,166, 49,198, 30, 24,236,140, 93,221,183, 97, 85,110,181,217,180,
-159, 61,106, 66,248,149,200,102, 81,227,201,103, 11,150,111,196,176, 20,116, 15,203, 20,118,149,114, 53,145, 19, 28,165, 29,192,
- 35, 2,107,173,188,113, 5,101,241, 28, 85,165, 83, 67,178,190,106,221,178,244,226,253,151,127,159,255, 49,203, 64, 3, 3, 32,
- 67, 5, 4, 52, 91,185,189,221, 99, 71, 30,112,202, 52,226,200,182, 0,164,156,189, 36,145,244,171, 80, 67, 69,119, 58, 49, 84,
- 2,200,173, 77,134, 34,227,138, 86,135,188,251, 84,249,194,183, 7, 70,198,162, 2,159,211, 74,130,198, 44,202,234,230,183,195,
-221,239,253,159, 15,118,237, 34,144, 19,130, 24, 99,200,171,222,143,164, 70,155,143, 0,176, 14,127, 65, 64, 80,200, 42,136, 75,
-201,177,159,244,228, 85,196,151,205,233, 65,205,123, 2, 26, 14,158,235, 40,203,140,128, 56, 37,178,138, 37, 42, 53, 56,211, 82,
- 41,177,155, 47, 51, 80, 84, 1,154,176,236, 55, 23,145,251,150,202, 83,128, 51,178,165,144, 21,219,123,254, 23,128,164,107,203,
-113,163,138,130,221,247,217,221,110, 63,198, 26, 17, 41, 72,188, 18, 69, 12,154, 72, 68,249, 69, 44,130, 21,176, 0, 86,195, 46,
- 88, 0, 75, 96, 19, 8, 34, 2, 34,146, 19,152,145,219,238,199,125, 83,213,124,249,195, 86,187,221,190,247,156,170,123,206,169,
- 82,135,219, 39,213, 25,104,221, 53, 55,242, 86, 31,240,181,155,188, 47,246,182,218, 0, 0,167,143,132,161, 5,130,193, 6, 26,
-129, 61,139,235, 64, 82,119, 64, 23,220,155, 98,155,172,179, 28, 99, 9, 47,239, 55,119, 82,159, 18,104, 53, 96,133,235,215, 71,
- 63,208,236,192, 32,110, 34,132,238, 37, 79,167,182,158,216, 69,113,178, 66, 88, 10,189,176,227, 98, 85, 58,209, 28, 62, 5, 97,
-118,197, 91,100, 46,192,130,121, 32, 22,165,230,213, 20,172, 41,241, 95,214,187, 82,246, 99,246, 29,200,223,185,234, 31, 37,112,
-219, 76,242, 38,242, 34,253, 34, 41, 10,135,144, 90,240,143,164, 6, 47,142, 29,208,129,158,191,128, 39,180,133,119, 88,184, 88,
-133,154,126,136,116, 45,102,135,195,122, 36, 79,153, 41,160, 48, 50, 10,187, 80,147,154, 85, 38, 25,176,125, 72,164, 98,168, 56,
-145, 48,215,190,208,252, 58,226,182, 85,108, 35,146, 45,242,144,197, 35, 5, 61,213, 72, 57, 34,130, 73, 15,248, 3,216,208, 79,
- 7, 58,240,114,172, 37,208, 68,202,203,128,199,167,176,245,214,247,211,233, 82,189,120,255,205,171,207, 77,121,209,152,241,229,
-221,245,235,251,119, 85,245,187,251,235,159,233,239,235,124, 90,135, 2, 23, 15, 22,226,176,149, 23,144, 4,121, 94,234, 25,123,
-148, 6, 76,165,126, 20,142,106,211,108, 59,115, 96,205,108, 52,164, 83,236,234, 0, 83, 93,231,234,242,255,232, 38,229,208,216,
-225, 78,233, 93,201, 83, 66,206,239, 84,156,215,232, 86,234, 61,149,106, 94, 37, 18,137,243,233,219,195, 58,213,148,243, 39, 95,
-138,207,190,221,231, 67,109, 64, 27,241, 45,237,162,123, 78,167, 17,199,170, 8, 72,131, 31,136,168,150,181,169,120,160, 45,217,
-106, 78, 27,148, 40,103, 54,189, 11,170,116,208,235,130,138,187, 62,249,169,114,154, 99, 16,184, 62,208, 57, 47,129,165, 27, 66,
- 94,128,167,103,214, 48, 74,213, 52,136,248,188, 12,146, 5,201, 68,155,236, 94,229,155,227,251, 15, 69,121,124,182, 3, 54,242,
- 8,127,193, 92, 70,154,152, 57,218, 5, 77, 89,107, 5,196, 50, 48,239,123,234, 91,135,141,166,187, 30, 82,184,199,111, 89, 88,
-135, 4,159, 3,140,212,212, 70,100,167,143, 31,189,161, 61,144, 30,243,248,118,218,190,110, 14,246,122, 70, 96, 93,235,120, 37,
- 32, 83, 4,205, 59, 26, 74,254,116,117,103,188,224,206, 45,149, 39,212,218,102, 67, 81,155,148, 65,204, 17, 84, 67,170,215,162,
- 48,115,102, 66,228, 17,106, 12,195,187, 63,229,207,243,211,239,238,190,255,225,201, 79, 63, 62,255,245,183, 63,184,165,122,121,
- 4,146, 0,137, 2, 60,105, 27, 99, 29,182,175,103, 23, 53, 94,218,201,106, 10, 40,179, 13,163, 6, 98,163, 55,164,177,196,133,
-158,165, 22, 73, 39,113,160,116,167,221,160,229, 49, 39, 51, 86,147,110, 26,107, 90, 23,146,154, 74,109,229,220,157,235,216,214,
- 88, 11,101, 46,209,224,121,134,166,223, 10,176,140, 88,143,128,217, 26,155, 14, 32,162,201,233, 34,219,157,124, 16,198, 92,210,
-245, 77,222,222, 31,159,153,211, 47,244, 74,235, 55,118, 96, 33, 84,177,132, 35,169, 14, 20,146,105,206,100, 41,215, 60,177, 1,
- 2,172, 23, 12, 50,215, 15,124, 82,215, 52,213,209,181,181, 15, 20, 0, 65,186,167,246,156, 23,235,108, 56, 23, 19,235, 64,156,
-198, 66,190, 1,215, 67,168,145,170,123,154, 55,182,189,125,246, 92,125,241,213,195,238,144,166, 15, 34, 4, 68, 2, 32, 69, 60,
-224, 22,113,123,208,117,119,242,145,102,242, 74, 52, 46,227,205,177, 61,178,215, 56,178, 95,135,240,140, 14,112, 85, 92, 11,253,
-244,219,210,236,111,163, 8, 26,123,224, 18,253,133,232,220, 72,247, 68,220,135, 17,100, 45,224,118, 66,187,195,219,235,126,201,
-111, 84,217, 7, 68,158, 66, 25,245, 49,199,143,101,223,201, 71,150, 61, 25,145, 34,168, 33,165, 99,177, 26,219, 4,230,192,146,
- 56, 5, 52, 12, 91, 69,228,186, 63,128, 11, 89,120,143,212, 15,209, 78, 42, 75, 69, 63,176, 99,132,113, 79, 48,206,115,105,112,
-157, 38, 33,152,244, 90,238,132,158, 66,228, 5,110, 34, 37, 58, 75,227, 6, 60,174,102,215, 44,141,116, 59,177,157,253, 50,212,
-236, 5,138,158, 77,134, 11, 62,148,228,152,194,102, 4,119, 0, 21, 69,108,141, 60, 0,162, 17,116,106, 91,166, 30, 26,176,224,
- 46, 41, 57,233,167,125,154,203,118,235,130,136,203,210, 34, 78,116,243, 82,225, 99,139, 74, 45, 48,241, 40,106, 37,254, 19,128,
-165,107, 91,145,163,138,162,117,110,117,233,211,213,157,201,196, 97, 28, 34, 4, 12, 33, 16,112, 30,196, 7, 5, 17,191, 64,255,
-210,111,208,143,136,224, 75, 4,209,135,136,195,152, 75, 79, 95,170,171,234,220, 93,171,240,117, 24,250, 86,251,172,189,214,217,
-123,175,173,126,248,241,123,179, 6,164,218, 26,144,177,185, 0,238, 7,219,202,205,178,160,174,110, 55, 74, 58,219,244, 16,174,
-218,244,136,101,218,180,196, 30,105,167, 3,172, 75, 99,204,132, 76, 39,188,237,174,182, 63,255, 20,223,229,242, 68,226,119,135,
-120, 91,122,144,121,171, 27,107, 14, 66,112,181,223,160,185, 46,167,107, 41,232,229, 10, 12, 33,115, 70,210,178,179, 2, 25,149,
-183, 82,221,180,123,136, 39, 8,121,139,215,244,238, 36, 32,214, 38,181,216,230, 59,207,237,201,178,222,145, 31,206, 51,231,221,
- 89,163,167, 21, 26,112,132, 14, 39,220,223,104, 68, 55,208, 2,201,184, 82,101,162, 58,222, 89,140,185, 57,240, 50, 2,159,164,
-216,210, 69,208, 45,165, 70, 67,159,241, 53, 96, 5,188, 35, 54, 27,201,229,104, 29, 13,193, 20, 16,161, 46,248,105,217,152, 97,
-105,237,157, 99,170,217,163,193,238,137,165,207,117,217,224,129,183, 62, 39,240, 18, 98, 40,190,221,145,253,184,248,221,171, 81,
-144, 1,113, 68, 11,193, 86,106, 43, 34,132, 58, 13,250,185, 43,205, 92,177,106, 8, 96,220, 92,168,155,103,251, 47,191,184,187,
-125,245,215,245, 39,127,150,251,223,247,111, 62, 30,238,231,121, 39,170, 41,129, 55, 1,222,231,161,248, 7,154,155,141, 31, 76,
-216,199,121,200, 9, 26, 6, 16, 3,109, 52, 2,222, 20,160, 15, 40, 6,248, 28, 2,111, 62,129, 52,187,153,205, 31,157, 42,224,
-116, 32,161, 28,139,243, 8, 10, 86,129,212,114, 63,238,151, 1,209, 81, 47,171, 77, 25,202, 84, 33,146,174,218,236, 5,120,127,
-206,143,183,213,183, 95,117,226,162, 38, 65,177,108,188,171, 87, 53,141, 43, 58,154,126,165, 22,255,165,169,249,219,165, 34, 88,
- 90,240,203,255, 51, 68,106,112,184,128,231,137, 86, 4, 25,112, 26,134,148, 38, 54, 65, 24,135, 3, 20,112,180,124, 84,113, 86,
-236,232,163,139,149, 86, 97, 18, 35,200, 52, 71,224,198,165, 76,235,219,130,131,217,137,242,232,249,147,230,213,215,175,119,239,
-116, 89,104,117, 56,206,156,159,193,209, 63,211,176,105,226, 70, 82,136, 54, 14, 68, 20, 14,148, 53,136,122, 58, 95,120, 86,143,
-185,108, 90,225, 88,177,113,125,233,154, 71,112, 39, 73, 55,172,170,112,195, 60,235, 44,222, 29,242,246,155,151, 27,125,222,129,
- 11,211, 93,132, 39, 24,137,128,183,174,224,140, 18, 60,113,143,151, 98, 57,184, 28, 43,211,136,197, 3,183, 98, 25,169,139,164,
-140,108,177, 82, 28, 21,109,232,122,178,220, 91, 20,117, 70,178, 25,243, 91,177,121,174,111,191,187,158, 31,204,135,127,102, 14,
-200,174, 68, 5, 42, 25,120, 89,139, 35,133,124,168,154, 70,172,184, 72, 41,178, 37,169, 24,239,237,170,119,185, 29, 1, 89,220,
- 17, 1, 4,160,125, 1,242, 48,159,171,234,160, 49, 29, 21,134, 8, 13,178, 68,131,111,147, 91,160, 2,248,151,209, 29, 73, 83,
- 17,101, 96,185,197,172, 52,131,150,203, 36,245,164,181, 5,227,115,217,180,146, 53,117, 4,103,179, 20, 93, 27,147,255,245,243,
-229,227, 23, 91,121,183, 63,236,161, 40,144,182, 82,140, 93,150,222,249, 50, 74,136, 21, 60, 67,238,107,116, 37,156,106, 94, 18,
-202, 82, 31, 85, 96,129, 60, 32,105,131,123,121,200,132, 40,195, 80, 13, 44,215,227,224, 48, 83,176, 63, 46, 20, 53,196,253,186,
-166, 17,190, 21,237,117,174,215,177,223,182,219,155,207,253,139,219,177,235,163,219, 81,148,139,116, 94, 77, 33,110,147,171, 32,
- 36,131,150, 73, 30,252,112,249,244, 51,196,239,111, 46,173, 1,123,248, 59, 93,109,184,237,144,173, 41,138,227,120, 75,183,128,
-206,213,177, 74, 58, 72,189,169,122,132,166,205, 30,228,197,131,123,148,236, 19, 13, 96, 91,110, 2,108, 71, 9, 65, 34,111,222,
-220, 95, 28, 78,127,116,117,155,128,206,102,164, 44,243,227,229,167, 47,175,218,215,147,251,187,156,145,248, 35,203,115,138,108,
-165, 24,164, 87,132, 72, 95, 42,171,233, 66,199,166, 1, 53,235, 98,193, 3,184, 17,171, 94,172,112,104,137, 1,165,213, 80,196,
- 43,181, 22,237, 35,178,184,248,209,164,167,191,252,250,236,206,189,237,154, 85,117, 65,139, 20, 58,203,121, 83,217, 26,212, 16,
-100, 30,138,102, 0,121,111,160, 53,115, 46, 33,227,228,144, 7,114,161,138,117, 76, 41,188, 56,165,239,156,230, 66, 40, 46, 51,
-224,128, 84,156,102, 8,110, 51,197,188, 22,206,177,165, 28,135, 1,143,205, 26,174, 53, 79,199, 34, 90, 19,149,239,251, 38,156,
-232,113,102,130,156, 76,253,159, 0, 36, 93,201,142, 28, 69, 16,205,202,172, 92,106, 27,106, 4,163, 81, 31,176,100,131,145, 44,
-115, 65,226,140,144,143,240, 3,124, 38,127,225,187,205, 9, 16,139,125, 64,150, 60,118,119, 85,117,109,185,249,189,226, 54, 61,
-106, 85,103,102,101, 70,188,200,136,120, 79,253,252,203, 79,123,217, 57, 0,160,210, 8,219, 87, 50,116,136,213,109,190, 85,171,
-147,182,113,134, 2, 71,187, 32, 89, 68, 64,204,170,181, 69,196, 2,128, 79, 24,110, 42,196,196,132,195,251,233,171, 83,250,152,
-222,188, 94, 22,178,227,194,193, 98, 58,124, 11, 3,211,119,148,210,150, 55, 92, 39, 71, 63, 40,139,100, 74,167, 14,237, 16,137,
-192, 84, 51,177,169, 73, 18, 41,175,239,103,216,139, 13, 47, 50, 15,235, 24,217,185,182,248, 17,163, 73,113,155, 97,245,150, 24,
-243,204, 52, 71, 36,235, 52,217, 18, 69, 58,199,163, 30, 28,251, 76, 75,108,188, 15,137,229, 31,129,181, 74, 86, 25, 60, 73,147,
-138, 47,178, 35, 97, 44,112,206,177, 22, 23, 43, 2,124, 64, 37, 96,195,200,204,153,149, 91,179, 1,216,236, 73, 55,227,173, 80,
-142,177, 94, 96,242, 49,185, 18, 79,194,188, 5, 76, 62,162, 48,236,170,220, 86,210,242,122, 32,112, 19, 32,230, 3,134,137,100,
-180,108, 41,201,132,112,141, 53,148,155,102, 97,174,101, 15,189,184, 8, 29, 14, 46,181,141, 14, 30,145, 52,239, 35,211,238,215,
- 7, 63,190,191,254,247, 48,255, 61, 61,252,187,108, 15, 34,108, 33,124,240,192,101,227, 36, 23, 56,148, 75, 8,163,220, 49, 45,
- 31, 61,133, 9,165, 28, 41,228, 82,172, 49, 94, 4,249,180, 54,234,241,238,163,164,170, 22, 75,239,153,237,135, 85, 88,118, 88,
- 98, 50,102, 97,191, 18,183, 35,220, 73, 24, 5,173,176,162,177,160,113,183,136,241, 9,106,115,201, 68, 82, 49, 9, 18,228, 12,
- 54,191,248,209, 60,122, 82, 45,172, 43, 84,170,147,250,255,219, 24,184, 15, 27,149, 74,101,195, 41,241, 57, 36,227, 38, 17, 26,
-115,130, 18,232, 99, 75, 11,175,239,177, 98, 30,126,253,188,199,107,193, 16,155,194,175, 42,206,145, 20,146, 87, 22,170, 48, 87,
-114,222,236,138, 80, 56, 59,124,119,161,235,173,241, 56,234,112,145, 23,161,114,185,145,226,254,219, 39,255,220,125,247,238,205,
-171,224,153, 97,159, 86, 44,116, 96,165, 4, 75, 25,225,206,125,128,111, 38,242,137, 84, 96,228, 77, 74, 92, 23, 15,176,193,219,
-112, 28, 51,210,141, 30,210,104, 21,237,218,173, 18, 94, 83,184, 11, 14, 31, 0,221,241,154, 53,255,245,209,221, 61,174,159,230,
- 48, 45, 3,118, 96,212,120, 67,212, 58,230,128,216,250,176, 28, 66, 79,228,218,200, 36,173, 56, 72,164, 13, 19, 76,148, 66,103,
-122, 25,203,152,117, 76,218,102, 67,153, 1,133,241,179,107, 2,230,117, 26,252,187,169,121, 84,126,243,253,157,182,167, 63,254,
- 4,218,155,116,143,160,174,149, 77,208, 71,110, 42,119, 14,112, 89, 71, 50,238,193,128,152, 5,187, 2,187,142, 87,229,252,117,
- 4,111,218, 93,173,221, 96,119,123,140,218, 89,196,132, 37, 70, 89, 81, 2,174,232,182, 50,110, 38, 24, 32,196, 21,110,219,144,
- 74,109,146,182,168,200,197,167, 15,186,254,173,110,123, 4, 44,125,206, 83,114, 88,184,196,250, 79, 32,115,132, 25, 89,173,182,
-137,227,162, 67,245,244, 62, 13,191,189,237, 28,207, 14,166,118,193,250,172,179,173,212,114, 52,192,233, 49,176, 46, 10,115,220,
-243,138, 87, 55,230,171, 36, 35, 90, 62,211,237,176,168,157, 18, 5,240, 37,145,242,112,128,168,107,134,137, 87, 83,190,205,101,
-184, 49,206,132,214,101,213,200,246, 70,125,254,229,215,246,241,179,161,239,137, 61, 5, 64,234, 30,140, 39, 96, 94,181,178, 41,
-150,139,169,174,102,246,215,185, 57,125,113,223,233,183,251, 36,120,171,206,142,102, 3, 35, 18,125, 47,152,180, 48, 0,154,216,
- 40, 33,212, 26, 91,209,104, 30, 52,138,134, 33,176, 15, 97, 7,150, 97,141, 91,174, 43,158,216, 50,150,237,166, 6, 64,205,231,
-175, 1,142,242, 16, 24,110,178, 47, 5, 31,132,219, 78,245,243, 59,249,146, 61,118,233,150,245,185, 52, 59,178, 28, 18, 11,101,
- 82, 69,105, 78,152,252,242,160,156, 43,200, 91,143,181, 47, 2, 55,131,136, 76,174, 33,102,165, 94,231,134,127,125,166, 42,205,
- 70,200,172,116,189,151,251, 15,191,254, 46,231,130, 50,203,149,181, 97,233, 0, 10,186,163, 16, 60, 88,134,168,192,121,248,227,
-200, 61,203,218,183, 88, 69,129, 57,121, 50,255,250,180,193,248,196,134, 39,140,162, 56, 55,170,241, 69,115,166, 16,115, 73, 29,
-161,108,216,236,161,212, 32,210,190,215,108, 7, 38,164,207, 53,155, 1,237,129,210, 92, 13, 59,177,235,218,181,102, 55,198,127,
- 18,128,164,171,231,145,163,136,130,253, 53, 51,221, 51,251,113,103, 29, 50, 50,248, 32,176, 28,216, 58, 57, 32, 65,164, 68,132,
-132,252, 80, 2,255, 4, 7, 36, 72, 16,155, 0,163,131, 91,237,221,238, 78, 79,119, 79,119, 15, 85,227, 96,131,213, 74,171,221,
-254,120,175,234, 77,189,122,250,231, 95,126,234,212,246,106,167, 45,194,225, 54,153,194,185, 77, 91,159,129,105,249, 32, 75, 3,
-227,210, 59,180,179,192,100,138, 79, 30,116, 29,196,136,236,183, 40,125, 74,100,179,142,222,106,210,109,118,242,195,175,159, 91,
-102, 16, 42,177,253,101, 35,152,140,232,241, 32,244,126,163,173,151, 61, 34,181,193,111,108,236, 42,201,219, 84, 78, 38, 2, 82,
- 30,250,214,181,151,127,198,120, 31, 90,101,107,170,211, 17, 91, 77,121, 93, 1, 21,194,138, 31,106, 12,134,118,122, 65,197, 64,
-250,127, 57,200, 56,139,167, 57,167, 39,225,113,247, 78,153,149,221,137, 49,171,195, 57,139, 28,254,136, 47,166, 79,190, 37,123,
- 91, 12,189,218,232,248,197, 14,246,106, 51,141, 18,150,200,169,143,242,166,145, 65,153, 45,253, 29,244,156, 57, 20, 52, 2,132,
- 36,164,133, 85,210, 10,116, 89,151,136,168,109,216,159, 12, 6, 29, 89,129, 7,130,166, 30, 18,249,195,207,200, 36,136,186,149,
-131,157, 4,246,198,176,212, 81,169,186,152, 5, 64,107,183, 86, 77, 5,191,152, 83, 44, 34, 79,204,160,211, 82,142,117,186,175,
-135,143,179, 63,198, 57,149,120, 42,113,228, 68, 25,138,125,113, 79,206, 73,165, 60,202,213, 92,225, 92,167, 32, 89, 28, 70, 54,
-194, 25,155,169,125,153, 40,143,209,235,140, 39,240, 72,188, 16,119,214,102, 28, 67, 63, 51,234, 4,193,246,215, 9,130,102, 53,
-134, 65,168,103, 62, 2,212,209, 98, 84,212, 53, 93, 89, 49, 10, 1,192,191,167, 69, 19, 34,115,189,123,165,191,127,183,125, 68,
- 6,186,146,205, 78,181,125,117,157, 49,142,102,164,180, 57,161, 71, 21,235, 48,166,163,201,165,164,255,221,106, 57, 33,203, 50,
- 45, 53, 52,216, 25,100,121,186,161, 22, 44,135,158, 75,204,167,154, 79,237,146,202,236,169, 53, 89,130, 25,159, 50,189, 85,165,
- 9, 97,206,143, 64, 38,146,243, 71, 9, 88,232, 7,128,252, 19,122, 33,158, 55, 47,222,125,247, 91, 6,209, 64, 78, 64,156, 75,
- 7,106,237,114, 98,119, 25,109,144, 47, 19, 9,161,207, 26,231,187,178,127, 6,111,153,239,216,182, 49,203,186,227, 8, 83, 61,
-139, 58,177,105,118, 66,246, 5,217, 37, 44,199, 53,196, 30,184,207, 55, 56, 93, 66, 82,250,205, 87,110,240, 99, 52,180, 24,106,
-176,136,189, 17, 44,226,243,190, 19,176,203,213,210,158, 25,177, 84, 83,216, 58,133,136,235,165,104,217, 86,179,150,241, 40,162,
- 43,177,208, 92, 99, 29,108, 2,198,168, 57, 96, 54,196,135,203,112,173, 94,190,189,249,226,197,238,120, 16,255, 6,240, 93,240,
-244,138, 35,159,232,157,168,117, 80, 3,119,141,226,173,105,183,139, 78,113, 48, 87, 28,230,237,226, 1,208, 91,179, 21,102, 67,
-167, 76, 28,216, 58,232, 49,182, 0, 55,224,169,117,232, 41,239,182,197, 38, 15,144,130, 37,162, 4, 16, 33,201,247,216, 99,128,
- 56,172, 89,172,113, 10,116,172,142,192,208,226, 84, 59, 66,140,176,178,114,228,164,104, 47, 60,188,141,218,188,122, 38,252,159,
-191,203,235, 1, 31,186, 51,184,248,194,198,226, 80,218,113, 41,115,148, 23,153,232,234, 21, 82,168,109,136,211,200, 46,182, 26,
-229,164, 42, 91,209,193,220,244, 82,103,146, 93,122, 29, 22,213, 12,133,147,165,116,189,236,141,123,169, 54,123, 5,254,103,246,
- 55,207,190,249,214,222,253,232,251,141, 80, 15,117, 57,211, 25, 81, 48,161,184,100, 1,181,146, 4, 57,165,195,108,240,226,184,
-156,190,190,125,125, 61, 28,198,251,255,100, 30,180, 5, 93,136,226,156,169,112,154, 65,174,241,227,156,192,142,135,110,193,125,
-126,212,130,102, 65,113,141,185,236, 51,213, 93,159, 59,250, 49,131,165,224,158,227,188,216,242,229,223, 79,119, 31, 31,254,160,
- 53,188,217, 0, 14,197,100, 41,108,235,197,173,189,117,234, 67, 70,174, 2,189,244, 53, 63, 26,246, 84,116, 8, 92,244, 50,164,
- 22,147, 78, 76,107,253,205, 74, 25, 22, 67, 73,175, 32,130,176, 45,221,126,145, 23, 56,220,110, 15, 6,199,158,169,206,232,206,
-244,250, 83,253,244,195,251,191, 46, 97,119,210,206, 53,162, 75,201,173,242,239,228,189, 93, 71,104,116,179,232, 23, 71, 33, 46,
- 34,249, 90, 42,101,254, 36,197, 22,198,217, 94,103, 14,110, 99,117, 24,127,136, 18, 17, 57,239,212,232,116,227,250, 66,137, 67,
- 2,112,203, 55, 58,239,219, 38, 48,191, 22,112, 52,154,186,105,229, 3,231, 55,101, 96,156,142, 15,195, 82, 14,177,251, 95, 0,
-146,174,165, 69,174, 42, 12,222,243,188,143,126, 50, 73,154, 33,138,232,194,160, 46, 92, 8, 17, 65,112,239, 47,200, 58, 63, 52,
-219, 44, 69, 20, 4, 65, 37, 4, 92,152, 48, 51, 61, 61,247,113,222,199,170, 59,251,105,250,222,233,239, 81,117,206,247, 85,169,
-159, 95,191, 2, 62,180,205,100, 41, 26,183, 67,121, 68,176,128, 57,135, 62,210,216,128,107,188, 49,107,242, 3,186, 77,168,121,
- 27, 45,231,198, 12, 64, 12,222,138,114,119, 60, 20,247, 66, 63,121,113, 53,143,229,159,191,106,211, 38,125, 0,140,111, 29, 79,
-206,236,208,148,161, 11,173, 78,180, 50,176,202,182,104, 86,138, 14,194,134,246,218,121, 39,192,200,237,182,220,207, 15, 55, 81,
- 71,180, 2, 35,202, 50, 45, 14,108,133, 83,101, 3, 2,125, 68,102,130, 94, 0,249,102, 74,150,210,209, 19,184,209,102, 80, 86,
-124, 25,160,135, 44, 46,243,176, 62, 52, 14, 52, 51, 36,125,163,229,145, 10,111,160,146,113, 43,204, 72,151,208,210, 1, 1, 20,
- 79, 35, 20,218,120, 73, 67,213, 57, 10, 69, 86,174,233, 71,139, 90,133,144,165,141, 36, 23, 91,135,202,147, 59,199,235, 71, 80,
- 78,227,189,209,168,101,224, 61,146, 19,220, 36,189,162, 2,112, 61, 42,183, 59, 52, 41, 36, 34, 42, 56,254, 31,188,130, 66,202,
-115, 78,173,162, 19,138,189,229,149,126,162,225, 31, 85,247,253,232,155,121,185,164, 24,111,151,243,153, 10,209, 2,229, 28,165,
-107, 4,190, 19,206,215, 52,115,245, 62, 68,212,113,252, 53,170, 31, 96,105, 93, 80, 21, 29,215, 10, 19,192, 28,114,239, 54, 93,
-178, 58, 52,114, 9, 28, 78, 3,212,154, 11, 72,172,158,168, 1, 73, 53, 71, 20,117,122, 52, 36,206,182, 78,171,110, 47,208,114,
-175, 27,144, 50, 10, 66, 41, 1, 20,153,128,173, 40, 50,161, 71, 89,223,159,203,245, 81,252,240,114, 95,158,119, 40, 16,253,174,
-161,230, 98,167, 41, 62, 63,100, 18, 16,238, 1, 3, 41, 10,178, 46, 4, 35,210,145, 50,124,122, 29, 62,246, 25,120, 71,177,168,
-217, 73, 70,190,129, 73,196,236,177,128,249, 18, 56, 6,166,241, 3,187,136, 71, 96,128,160,204, 40,250, 1,137,202, 36, 10,188,
- 6,232,181,112,171,173,246,112,212, 87,159,234,237,247, 63,253,234,238,207,255, 93, 86, 81,136, 75, 4,236,158, 28, 94, 31, 17,
-149, 65,190,192,130,134,101, 89,240, 21, 30,152,122,193,243,241,170,141, 71, 41,174,165, 15, 32,237, 41, 1, 84,119,192,196,154,
-136,175,172,162,227, 8,140, 1, 88, 27,185, 26,209,249,208,242,239,230,244,244,250,240,141,149,227,244, 64, 57, 49,188, 19, 93,
-253, 42, 69,144, 12, 29,183, 57,151, 14, 46,227,233,137,208,160,172,187,226, 99, 45, 27, 41,121,187, 83, 52, 18,212,160,116, 10,
-121, 32, 7, 66,205,227,175,223, 19,238,160,233, 38, 23,226,195,184,209,229,244,229,179,231,159,237,223,253,209,244, 55,119, 45,
- 58,229, 94,154,100,142,253,114,191, 30,148,160, 29,241,196, 86,147, 28, 9,103,181,208,136,207,180, 52,129,227, 89, 42,247,109,
-105, 5,205,144,221, 94,136, 77, 95, 16,115,125,201,201,101,149, 90, 49, 43,223, 27,137, 42, 55,115,198,149,139,121,214, 33,101,
- 19, 16,153, 68, 71, 90,135, 4,240,211, 79, 41,213,214,208,185, 49,200, 71,241, 11,116,197, 75, 62,171,120,252,246,106, 25,127,
-251, 19, 29,155,123, 98,137,174, 39,202, 91,237,204, 44,212, 45,114,135,235, 3,217, 44, 96,133,197, 7, 77, 17,158, 57,139, 49,
-115,237,193,112, 13,168, 6,138,249, 51, 34,206,200,156, 70,245, 98, 90, 68,127, 20, 93, 84, 79,246, 82,132, 54, 41,125,250,234,
-197,230,139,239,110,158,245,193,255,171, 24,233,120, 48,112,100, 4,249,148,186,224, 56,235, 53, 10,211, 70, 39,132,245, 41,120,
- 19, 78,159, 92,159,178,127,239, 57,107, 73,209,120, 13,136, 54,208,157,132, 14, 84, 1,248, 51,180,116, 69,112, 40, 33,205, 21,
- 74,161, 40,214, 36,142,181,131, 52, 15,188, 0,229,160, 10,239, 70,180, 95,106,247,242,247, 15,203,199,240,119,208, 9,239, 85,
-235,185, 3,180,137, 40, 89,245,243,211,215,157,248,101,190,171,154,100, 18,237,108,135,104, 68, 11, 7, 16,231, 37,109, 75,143,
-205,102, 21,144, 69, 89, 80,155, 85,215, 76,148,230, 17, 69, 37,222, 8,168,186, 41,178, 83,160,174, 20,152, 4,220, 8,182, 60,
-125,251,238,199, 55, 31, 63,156, 54, 0,154,219,158, 51,154,185, 29,128, 43, 76, 58,244,232,127, 50,130,116, 27, 3,248,157,192,
-142,121,168, 74,135,133,186, 10,235,225, 39, 88,231,172,162, 76,178,120, 11, 4, 47,140, 9,162, 45,156, 70, 71, 45, 40, 35, 62,
-205, 51, 34,149,228, 46,129,175,112,215, 71,211,186, 97,198, 83,208, 87,174,149,101,162,196, 9, 71,173,165, 69,210,253, 47, 0,
- 73,215,178, 35, 57, 17, 4,237,122,186,220,118,247,244, 12,176,218,129, 5, 36, 24, 14,136,189, 32,205, 21,196, 63,112,226, 3,
-248, 79,110,136, 11, 95, 0, 2, 45,176,210,238, 48,189,211,110,191,234, 73,132, 57,119, 75,237,174,114,102, 70, 84,101, 70,200,
- 31,126,252,254,250,125,159,212,141, 33, 11,223,201,118,102,140, 57, 10,222,153,210,209, 16, 5,121, 63,131, 8,128, 17, 97,205,
- 0, 84,121,141, 78, 33,102, 84, 77,189,110,252, 5, 17, 61, 0,118, 53,159,126,213,229,223,194,227, 31, 20, 67,171, 64, 68, 91,
- 22,204,170, 9,160, 47,235,162,133, 76,109,167, 76,208,116,135,109,149, 43,108,161,113, 90,238, 75,190,196,121, 24,217, 30, 10,
-146, 48, 39, 94,182,162,204, 24,144,140,108,219,253,213,179,238,240,193,177, 57, 90, 99,205,241,168,176, 74,250, 96,220,190, 39,
- 25, 61,228,232,235, 66, 43,120,169, 4,117,161, 38,192, 67, 89,194,148,168,206,150,229, 28,168,147,133, 7,190,208,127,181,110,
- 79, 18,121,169,128,232,108, 71,160, 52,216,204,116,208,110,154,148,131,193, 42, 34,181,235,196,196, 37, 81, 63, 3, 49,111,229,
-120, 48,130, 95, 65,110,139, 33,109,134, 69,168, 79,155, 33,123,205, 46,129,226, 54,127, 0,138,207,240,146,141,182, 55, 46,210,
-175,215,215, 29,114,244,192,107,171,172,101,104,120,110,110, 55,235, 48,112, 23,148, 19,125,142,150, 5,129,174, 26,145,214, 7,
- 20,149, 70,129, 42,212,167,149, 97,165,240, 0, 88, 8, 18,126, 24,216,115, 98,189,244, 99, 94,121, 88,185, 53, 38, 11, 51, 34,
-204,192, 67,105, 71, 33, 58,201,139,120, 64, 89,138,164,243, 58,130, 3, 58, 35,113, 65,189, 22, 30, 80, 63, 46, 53, 30,233,138,
- 13,162,121, 52,168,137, 28,200,172, 57,232, 87, 61,248, 50,119,229,219,111,244,237,203,230,140,124, 12, 92,208, 23,181, 43,170,
- 1,165, 81,117,231,183,213,165,129, 7,246,157, 71,189,182,240, 76,188,208, 59, 86, 0, 88, 21, 77,101,160,115,224, 64, 64, 16,
-203,232, 81,116, 80,139,210,185, 0, 53,115,238, 40,199,244, 78,209,176,118, 27,100, 1,150,102,159, 41, 61,137, 42, 29, 16, 47,
-236, 29,219,212,145,138, 61, 86,218,229,238,147,103, 79,183, 47, 95,253, 59,169, 11, 64, 78, 61, 37,145,189,152,148, 5,113, 2,
- 51, 31,116,110, 22,170,126,143, 73,185, 57,106,191, 81, 8, 95,115, 38, 73,154,132, 13,161,211, 13, 11,193,138,135, 76,113,118,
-244, 40,174, 57,203, 33, 38,145, 2,239, 81,234,216,138, 78, 43, 36,176, 55,235,238,254, 35,212,150,135,153, 30, 47,138, 6,111,
-138,141, 70, 25,233,230,188,245,225,101,228,146, 12, 90, 70,102,106,147, 54, 12, 13,141,180,220, 11,182, 7, 40,170,230, 82,208,
-153, 90,197,155, 69,128, 85, 90, 96,193,180,192,107, 25,198, 21,255,194, 76,135, 23,199,187,207, 15, 79,177,255,231, 45, 64,211,
- 82, 91,150, 86, 67,123,116, 42,183,224,149,178,116, 6,137,162,242,163,137, 90,181,109,127, 44, 77, 91,235,185,240,154, 15, 25,
-196, 93, 24,108,226,130,156, 95,124,159,134,228, 26, 31,177, 47,192,115, 61, 96, 23,138,170, 97,127, 93, 46,187,105,155,114,147,
-162,172, 67,166, 88,164, 94,176, 73, 79,206,151,240,104, 77, 24,148,244,153,114,195,126, 56,251,247, 62,254,236,235,244,231,233,
-175, 87,190, 53,200, 30, 13,184, 72,140,244, 34,203,129,198,191, 72,155, 12, 72,138, 18,231,180,174,175, 61, 22,206,105, 36, 24,
- 67, 9,151, 36,148, 47,132, 68, 77,206,128, 80,133, 10,177,178,225,109,162,181,117,179, 87,254,121, 18,109,123,251,226,121,125,
-247,221,228,250, 82, 78,155,222, 96, 92,179,163,175, 37,222,137, 75,182, 9,229,142,115,170,164,206,248,104,165,112,223,155,245,
-244,161,187,219,237,222,206, 79, 83,246,136, 67,124,183,222, 14, 73, 50,135,165,153, 27, 98, 90,129,136, 35,123,176,116,172, 30,
- 11,125,179, 28,123,126,163, 83, 82, 39,160,145,226,219, 48, 47, 55, 55,238,245,233,254,151,191,127,189, 10, 11,205, 95, 50,128,
-107, 76,139,154,171, 5, 53,251,139,221,157, 94,126,190,208,205, 4,201,234, 66,167, 2,159, 35, 40, 14, 94,197,145, 27,207,247,
-249,127, 73, 85,132, 14,163,189,224,119,121,145, 7,150,102,186, 10, 27,132,146, 9,224,235,104,132, 80, 25,217, 84,131, 52,247,
- 63, 61,124,249, 46,254,126,221,180,107, 71, 78, 71,253, 34, 17,247,128, 32, 45,221,223,171,212, 95,107,164,252,220, 98,219,234,
-117,224,177, 66,173, 60,120, 23,190,168, 46,108, 97,176,148,146,148, 93,159,236,172,114,220, 1,107, 26,250, 23, 55, 85, 35,133,
-238,129,236,141,109, 56, 71, 35, 22, 77,137, 32,194, 66,163, 40,142, 12,218,150,218, 2,216, 22,132, 43,237,142,109, 15,255, 9,
-192,209,213,244,200, 77, 68, 65,187, 63,252, 53,246,204, 78,118,147,133,136, 8,130, 16, 66, 2, 20, 14, 57,112,224, 15,112, 66,
-226, 39,115, 4,137, 67, 16,202,133, 3, 17, 68,201, 70,203,204,122, 60,238,118,127,185,169,154,219, 28, 70,182,236,238, 87,175,
-202,253, 94, 61, 16, 26, 87, 6,208, 57, 68,176,168, 89,187,217,208,137,175, 12,138, 87,197,130, 50, 11,148,236, 7,212, 22,145,
- 29, 12, 91, 90, 64,182,252, 82,134,201, 86, 74,129, 30,131,178,228, 96, 15,119,239,174,191,104, 95,254,252,209,124,120,120,123,
-180, 38,216,155,208, 81,101, 32, 8, 92,108, 32,245, 59,149, 64,157, 32,205,175,216, 74, 1,112,208, 65,137, 17, 58,107, 78,133,
-153,132,246,154, 7,174,201, 26, 96,100,219,245,253,103,235,246,246, 97,251,213, 7,251,185, 17, 59, 22,210,172, 75, 31, 3,246,
-168, 73,199,222, 31,111,199, 63, 84,249,126,186, 53,241,244, 38,204,139, 79,195, 58, 66, 43, 55,245,188,174,214,159,199, 2,180,
- 47,212,101, 5, 84, 29, 64,228, 37,244,141, 19,137,213, 54, 82,181,136,237,196, 22,106, 35, 56,103,197,169, 75,179, 42,235,156,
- 67, 26, 42, 36, 6, 48, 97, 54, 76,248,178,155, 89,158, 69, 15, 46,172,180, 97, 17, 87,222,177, 76, 39, 52, 52,171, 80,214,185,
- 70,149,151,158, 57,154,206, 32, 57, 59, 81,147,190,241, 68,181, 92,101,243, 68,208,180,245, 84,110, 98, 46,110, 82,181,215,235,
- 68,187,177, 26, 55,108, 0,147,161, 30, 10,119, 74,192, 96, 64, 54,171, 6, 29, 96, 9,146,157, 83,117,100, 29,233,152,191,208,
-233,121,185,184, 92, 38,138,163,117, 62,179,199, 76, 67,124, 75, 42, 33,232, 10,163,120,198, 46,104,254, 90,156,177,106, 41,147,
- 6, 2, 28, 56,214,172,216,107,175,216,238, 65, 50,235,181,162, 63, 94, 6, 29,144,172,138, 40,210, 57,100,176,142,239,159,203,
-111, 62,237,239, 20,178,106, 81, 63,213,154, 54,131,144,132, 53,195, 11,241,138, 0,132, 44, 39, 48,106,158,207, 66, 36,213,186,
- 0,127,192,219,104, 0,229,106,101, 3, 37,107, 16, 50, 24, 22,174, 12, 1,111,201, 4, 28,182,150,165,163, 54,207,151,193,115,
-236,202,129, 25, 99,131,240,132,202, 41, 28,153,125, 80, 44, 96,160,234,184,216,137,136, 58,239,191,125,246,167, 60,141,238, 40,
-119,149,176, 71,115, 49,243,185, 25,157,137,113,198,165, 68,182,165, 77, 42,249,165, 6,235,231, 71,232, 14,250, 69,142, 43,244,
- 95,244, 59,154,187, 53,133,198,189, 30, 85,149,230, 4, 37,213, 4, 63,117,156, 75, 37, 61, 79,132,183,208, 67,129, 19,183, 16,
-127,211,221,249,168,247,207,182, 87,225,237,125,230, 76, 35,133,221,202,193,131, 67, 33, 93,140, 39,170, 34, 26, 68,115,112, 23,
-187, 37,232,107, 53, 4, 66,192,170, 32,216,243, 99,250,123, 59,186,183, 38, 61,179,203,183,232, 47,108,104, 6,201, 86,137, 14,
- 40,193,190,121,131,128,218, 63,255,228,199,159,158,252,250,155,124,253, 42, 57, 27,183, 44, 78,109, 66, 11,210,143, 12, 93,153,
-138,115, 48,138,208, 84,185,242,244,219,227,104, 48,177, 14, 65,211,234, 14,111, 7, 12,196,171,250,186,208,115, 94,231,124, 61,
-166, 65,196,243, 94,101,195,131,124,224, 98,232, 76, 59,109,232,103, 61,128,245,215,238,146,173, 16, 77,160,215,202, 44,219,170,
- 63, 85,171, 60,250, 70, 59,118, 92, 46,120,192,110,251,226,233,234, 95,189,198,222,170,192,202,115, 57, 98, 23, 45,162, 74, 23,
- 67, 21,252, 9,203,235, 72,182,105,154, 97, 46,149, 35, 43,132, 14, 18,238, 90,180,108, 0, 2,205,204, 21,155,176,120,182, 11,
- 70,104, 24, 80,205,166,108,144,216,122, 5,188,221, 62,250,184,253,250,203,241,241, 46,141,239, 11,139,149,134,192,193, 70, 65,
-122,155,240, 43,234, 16, 17, 2, 78, 45, 78, 7,145,193, 82, 99,144,162,143,238,252,225,223,191, 15,223,189,124,209, 13,191, 68,
-168,249,114,136,203, 41,207, 29, 51, 8, 40, 63,100, 90, 65, 39, 73,229, 33, 31, 75, 55,150,141,111, 47,159, 4, 86,170,109,224,
- 24,222,152,130,146, 63, 36,113, 94,229, 15,191,255,115,248, 47,222,215,216,202, 16,147, 21,244, 60, 0, 23, 90, 92,100,168,197,
- 9,107,187, 9,225, 30,156, 62, 55,123,228,208,148,124,121,136, 69, 83,225, 95,116,140,181, 50, 66, 29,107, 54,109,177,251, 5,
- 47,179,239, 16,184,145, 69, 67, 0,119,128, 34,199,225,240,176,177, 95, 42, 8, 67,163, 79,230,246,175,233,221, 13,128,111,179,
- 27,202,160, 29, 50, 1,184, 7, 88,248, 1,108, 15, 25,226,161, 69, 62,110,163, 8,229, 36,114,183,221, 1,172, 42,115,198,214,
-210, 45,182, 88, 53, 25, 8,178,165,177,200,232,150, 31, 65,179,180, 84,102, 66,136,121,161,109,166, 42,195,154,173,199, 83, 95,
- 73, 41, 16,236,172, 34,128,128, 74,243, 2, 49,180,193, 5, 6,117,165,162,228, 12,135,224,133,250, 95, 0,146,174,166,199,145,
- 26,136,182,219, 31,237,254, 74,102,146,153, 65, 44, 11,172, 86,139, 56, 48, 18, 90,110,128,144,184,193, 1,132,196, 63,225,103,
- 34, 33, 36, 36, 56,112,155, 5, 41, 44,218,157,201, 36,221,233, 15,187,109,243, 94, 56, 38, 82, 58,110,219, 85,126, 85,174,122,
- 79,254,248,211,247,185, 88, 25, 44, 16,240,123,152, 40,214, 84,241,110,202, 77,136, 57, 22, 82, 39,179,227, 17, 15, 65, 12, 77,
-212,132, 8, 91,241, 70,216, 5,214, 31, 57, 53,224,103,189,209,148, 18, 20,113, 63,220,124, 18,175, 95,180, 97,151, 46, 6,196,
-221,233,136, 64,170,182,190,101, 58, 32, 5, 93,250,188, 85,121,177,202, 67, 52, 21,134, 37,199,104,135,215,222, 29,215, 57,211,
-129,226,220,166,152,217,139,118,243,236,246,113,251,221,171,250,135,191,228,139, 71, 39,134,225, 24,195,212,133,225,190,143,111,
-148,232, 92,218,133,219, 93,253,209,235,236,203,204,126,108,154,247,245,230,185,173, 42, 27, 92,181,206,242, 10, 75,168,217,121,
-117, 12, 76,146, 25,150, 94,226, 11, 18, 88,147,199, 59,178,172, 43, 99,153,179,156, 88, 53,171,235,229,220,131, 24,229, 54,157,
-233, 38,200,229, 66,157,232,130, 98,220,212, 14,213,255, 19,126, 36,182, 8,159, 53,134,196, 8,232, 4, 3, 24, 41,198,161,232,
- 79,217,168, 60,159,179,159,172, 71,129,157,136,165, 96,135,138,234,121,185,153,124,180,154, 53,179,201,107,195, 94,250,188, 8,
- 25,115,192, 19, 57, 82, 48, 74, 96,112, 0,123,224,114,153,199, 41,158,121,201,125,244,251, 48,122, 57, 76,241, 52,177,173,169,
- 58,200,145,217, 64, 0, 98, 57, 1,248,100,153, 33,223, 35,220,118, 86,178,172, 90,204,146,213,246, 13,222, 77,122,172,198,144,
-203,186,192,191, 98, 92,234,144,150,178,142, 88,120, 88, 55,108, 3,199, 17,140,105,194, 63,143,105, 47,211,147, 39,217, 87, 95,
-215,105,173,129,244, 53, 34,187, 77, 80, 76,126, 25,202, 47,224, 49, 44, 52,143, 76,135,105, 18, 9, 71, 22,242,101,103,148, 91,
- 40,170,199,249,165, 23, 17, 15,157, 66,236,231,112,110, 47, 76,231,142, 94,248,247,227, 63, 46, 77,153, 29,129, 92, 2,176,163,
-234,232, 45,204, 4, 32, 49, 13,152,233,142,164, 8, 56,129, 42,155,205,148,140, 3, 52, 18,219,141,108, 63,253,236,119,127, 51,
-238,239, 0,176,237,144,145, 91,114,201,122,173, 15,136,238,108,172,224,143, 34, 37,192,129, 67,169, 40,226,114, 50, 94, 49,115,
-134, 29, 13, 63, 76, 22,203,214, 74, 55,195,161,240, 99,126,148, 5, 38, 92,197,154,151,189,234,208, 80,203,208,149, 24,121, 66,
- 8,246,128,147,241,106,253,242,202, 12,251,131,223, 36,174,135,226,197, 56, 38,208,227,212, 47,152,199, 83, 56,183,202,200,219,
- 24, 42,120,106,152,186,101,182,209,132,138,253, 27,194,226, 59,106, 78,233,146,172,188, 18, 78, 21, 97, 70,101, 76,155,180,109,
-243,182, 88, 16, 19,204,189,232, 78,106, 43,158, 62,189,108,218,203,221,155,210, 79,189, 95,173, 4, 38,153, 5,127, 42,154, 34,
-247, 94,152,134,105, 73, 50,125,201, 51, 81,101, 92, 12,143,110,214, 44, 45,216,199,217,104, 25,179,181,177,244,154, 60,230, 57,
- 59,166, 88, 23, 75,209,142, 37, 68,235,210,162, 23,222,206, 76, 25, 0,107,193,236, 89,223,143,204,214, 47, 14,208, 88,247, 39,
- 25,198, 30,163,249,123,254,240,221,247,190,189,190,127,245,243,111,251,183, 41,147, 5, 76,147, 12,209, 46, 97, 65, 27,167, 16,
- 71,122, 15,164, 31,120,233,199, 86, 91,178,196,177,224, 21,120,149,138, 26,140,232, 42, 94,137, 8,227, 17, 30, 10, 71,219,202,
-204, 85, 94,172,141,177,181, 93,233,171,235, 27,123,251,205,116,249,129,143, 7,229,217,250,231, 11,156, 94,152, 47, 79,149, 45,
- 7,131, 19, 12,100,103, 31,241, 90,185,124,236,128, 78, 6,182,181,196,225,225,254,241,157,139,207,183,155,105, 57,189,101,171,
- 25,201,234,109,160,254, 42,156,224, 74,136,141,168,173, 44, 27, 21, 44, 64, 51, 57, 93, 45,112, 27, 54,132,164,216, 26, 54,203,
-137, 33,215,245,213,243,221,191, 47,127,185,251,117, 49,123, 31,215, 94,132, 81,177, 17,164,150,177,235,226,144,235,103,155,198,
-234, 63,187,227, 9, 91,136,241,193, 2,179,150,148,144,196,203,200,105, 65,184,210, 45,146, 87, 60,216, 12,150, 18, 9, 48, 92,
-221, 80,144, 53, 1, 67,123,210, 19,195, 98, 27, 69, 21, 32, 56,200,126,182,225,230,238,225,139, 63, 78, 71,161, 10, 12, 13,155,
-175, 4,114,169,125,125, 50,108,171, 38,242,156,164, 27,165,110, 7, 28, 71, 97,209,172, 71,118, 57,187,182, 22,114,250, 27, 7,
-115,166, 0, 33, 35,114, 24,232, 76, 14, 21, 3, 52,138,189,160, 72, 88, 71, 50,159, 34, 20,165, 41, 10, 11, 80,102,224,231,108,
- 43,147, 77,161, 70, 40, 81, 99,151,227,112,139,198,203, 67,211,216, 58,137,217,253, 39, 0, 73,215,178, 27, 57, 17, 69,253,168,
-114,217,229,118,119, 72, 39, 51, 65, 36, 25, 17, 36, 52,210,140, 96,129, 88,176, 26, 33, 22, 72,108,216,241, 3,136, 79,224,167,
-248, 1,214,108, 71, 66,108,216, 1, 98, 51,210, 12, 36,221,233,118,183,219,229,122,114,142, 89, 38, 74,210,142,171,234,222,115,
-110,157,123,110,249,253, 15,223, 93, 18,125,224,112,128,210, 15, 65,198, 56, 95, 14, 50,112, 21,214,250, 17, 43, 73, 63,159, 2,
- 32,140,117, 6, 0, 83, 57, 34, 15,252, 63,173,110, 83,100,131,103,207, 13,208, 36,240, 88, 95,159,250,190,187,107,158,126,120,
-121,129, 0,249,111,106,144,208, 61, 2,110,217, 57,250, 80,118, 68,173,156,168, 82,249,128, 61,177, 83,167,147, 4,224,149,210,
- 22,163,159,175, 68, 14,122,189,210,231, 95,190,169,191,249, 35,220,216,233,157,136,111,155,124,175, 57,230,201, 73,196, 99,139,
-101,154, 62, 80,214,164, 77,238,183, 99,150,109,132,122, 35,110,182,205,103, 59,253, 60, 59,255,120, 85,171,101,110,154,203,157,
-195, 31,149, 14, 89,122,234,193,200,188,168, 41,200, 46,102,195, 10, 80, 26,122,109, 88,122,244, 35, 7,226,157, 23, 52, 5,101,
- 67,112, 57,225,237,129,125, 1,178,208,124,159, 87,228,200,101,157,199,231,158, 18,135,192,206, 54,132,136, 15,108, 13, 51, 7,
-132, 23, 97,198,138,147,252, 66, 57,141, 46,211,217, 68, 51, 31, 55,245,108,192, 97, 49,151, 5, 27, 58,208, 32, 57,224,212,176,
- 93, 22,107,142,204,201, 73, 81, 89,213,112,182, 21,226, 26, 53, 9,202, 19,191,142, 2,233,122,220, 39,131, 93,231,104,136, 40,
-251,132,248,104,203, 52,166,226,224,163, 56,102,172,169,119,177,146, 20,122, 8,218,242,226, 84,226,148, 35, 28,176,144,134,231,
-180,160, 39,188,226, 5, 38,162,250,160,144,216,211,128,236,229, 97,100,199,151,201, 3, 24, 50,175,130, 59,113,243,201,167,159,
-127,113,251,234,182,175, 86,197, 33, 47, 4, 54,203,194, 41, 89,137, 51,176, 71, 73,191, 96,193,186, 30,235,219,200,137, 82, 81,
- 67, 38, 29,231,112,151,244, 22, 2,110, 72,131,154,142, 34, 42,131, 47,157,137, 52, 14,180,148,178,196,119, 41, 58, 36,186,156,
-148, 60, 80,192,131, 67, 90, 32,161,148,192,107,177,228,207,100,133,161, 31,142,205, 88,217, 6,223,110, 74,138, 49,222,187,187,
- 8, 47, 94,254,250,215,225,120,232, 65, 93, 0, 79,119, 96,223,136, 40,134,142,162, 89, 45,221, 16,152,127, 76,197,246, 88,156,
-101,229,247,237,169,238, 5,213,168, 62, 44,230,138, 41,136, 88,164,207, 48,150, 24, 11,150,187, 54, 12, 53,193, 41,128,190, 12,
-108,138, 74,196,166,236,124,113,147,125,152,210,203,235,213,197,180, 61, 58, 68, 29,252, 14, 53, 69,105,160,155, 24,221,132,130,
- 11,186,160,236,223,135,128, 96,178,230,228, 16,228,128,184, 72,192, 80, 68,187, 93,165,176,125, 90,246, 64,228,172, 78, 40,189,
-236,234,167, 23,205,249, 85,189,104,235, 75, 89,105, 45,241, 18,193,237,130, 43,149, 89, 63,233,174,175,158, 28,251, 96, 55,174,
- 53, 86, 41,217, 1, 43,210,168, 64,129, 85,105, 97, 42,177,200,193,189,101, 75,148,225, 86,165,157,219,208,128,111,121,141, 14,
-204, 95,186, 78,143,181,106, 65, 46,176,113,132, 23,142,238, 6,199, 52,170,165,108,216,239, 83, 88,142,145,205, 26, 38,132,113,
-112,188, 55,201,246,142,247, 71,219, 24, 31,213,195,113,184,187,126,246,227,183,237,217,223,191,252,246,122,163,124,165,100,169,
- 69,196,126,115,179, 18,225,126, 2, 78, 71,128,226, 16,187, 97,226,248,108,106,136, 41, 33,201,240,202, 26,150, 52, 41,250, 8,
-248,102, 21,216,119,210, 22,237, 34, 86, 67,206, 30,250,148, 42, 93, 46, 63, 90,171,231, 95,245,207,110,179,254, 45,135, 84, 20,
-172,151,185,108,156, 29,131,216, 33, 24,248,204, 83, 19, 54, 22,220, 5,233, 22,228,124,162,129, 51,118, 14, 14,233,233,241,254,
-190, 55,215,239,191, 88,116,118,218, 61,240, 70,203, 87, 81, 42, 32, 51,252,199,108, 47, 13, 67, 4, 83,220,166, 84,211,129, 3,
- 11,133, 21,192, 67,210,149,164, 4,120,237,207,150,185,210,175,126,122,125,216,238,127,175,206,217,184,139, 64,227,168, 3,165,
- 80,116, 95, 72,128,170, 91,121,177, 22,127,110, 30,233, 2,156,140,179,166,200, 15,108,142, 44, 65, 64, 60, 78,169,142,213, 50,
- 38, 77, 93, 1,157, 31, 56,123,153,253,119, 28, 15, 73,184,195,154,162,154,192,145, 56,153,146,162,193, 56, 54, 95,255,252,207,
-202,171,221, 21,112, 31,240,129,174, 56,105,146, 98,137,189,111,177,133, 23,185, 84,103,157,197,209,210,120,153, 44,221,183,160,
-242, 78,116,206,153, 6,159,225,117, 99,216,131,104, 78, 93,226,220, 22, 47, 68, 53,168, 58,153, 36,113,178,234,120, 26,102, 99,
-165, 38,155,202,164, 67,178, 43,132,249,166,176, 3,101, 44,117, 61,206,118,248,164, 26,160, 31,178, 84, 3,221, 70,254, 19,128,
-165,107, 89,145,164,136,162, 25, 17,153,145,145,143,206,202,174,126, 14,211, 13,211, 51, 66,207, 70, 93, 12,174, 68, 68, 92, 41,
-126,128,136,123,193,189,191,229, 55,136,184, 18, 4,113, 51, 48, 61, 11, 81,212,110,230,209, 93,213,249,136,200,200,136,244,156,
-210,109, 83, 13, 85,153, 17,247,158,115,239, 61,231,170, 47,191,249,218,231, 99,212,248, 23,124, 39,176, 43,156,124,157, 73,214,
-158,181, 65,142, 18,169,207,241,218, 23,223,177,153,226, 40,179,194, 29, 15,210, 41,182,204,123,214,232, 0, 33,231,221,230, 34,
-220,112, 55,138,105,123, 29,205,118,255,233,201,209,229,250,100, 79,173, 84, 82, 46,114, 50, 34, 63, 76,138,146,230, 80,224, 9,
- 91,201,250, 94,142,135, 98, 69, 70,179,138,105, 70,112,169,171,253, 71,229,201,135,207,245, 39, 55, 73,153,249,127, 74,250,113,
-233,232,121,180, 55, 83, 31, 51, 54,104,185,108,201, 23,156, 86,202, 86, 42,179,197,220, 23,122,114,241,198, 83,191,117,220, 31,
- 63,115,235,203,252,240,104,101, 76,110,238, 64, 69,250, 57,116, 55,244,124,228,108, 15,155, 80, 52, 40, 21,160,148,115,152,168,
- 69,164, 96, 50,208, 96,101, 65,212, 66, 80,176,187,206, 62, 93, 77,105,106,248,191,242, 83, 76, 96,194, 75, 50,230, 19, 85, 95,
-145,216, 27, 81, 11, 60,156,245, 93, 92,128, 33,132,232, 55,130,133,248, 77, 4, 56, 30,183,252,212,130,131, 75,243, 59,105, 60,
- 46, 28,133, 17,220,250,108,240, 2, 69,164, 11, 62, 75,217,160,173,130, 22,240,130, 59,231,157,242,150, 90,206, 2, 32, 74,128,
- 58, 0, 27,207,118,196, 75, 91, 70,145,134, 13, 64, 55, 35, 8, 2,201,140,252,234,115,176, 81,205,182,120, 24, 69,146, 23,138,
- 26,104,153,153,196,148,146,246, 9,200,103,163, 88, 94,249, 68,215,184,225,222, 3, 96, 87, 81, 31,164,117, 91, 29,156,157,158,
-127,246, 65,252,252,139,254,211,175,158,188, 35, 87,215,191,108,113,108, 15,101, 90,176,214,145,103,236,158, 35,154, 0, 82,114,
- 35, 44,109, 88, 23,128, 43,129, 0,164,233,238,206,223, 16,105, 91, 35, 44,238,140,224,194,170,158, 58, 35, 32,167,176, 73,113,
- 40,102,235,149, 93,156, 99,235, 19,116,131,202,133,142,130,252,225,126,158,123,157, 13,190,191,231,184,225,127,166, 90,148, 74,
- 40,142,158, 46,109, 82, 60, 76,246, 47,207,255, 44,158, 62,127,251,178,176, 58,155,210, 98,100,193, 28,153,146, 70,111,248,161,
-110,158,144, 55,230, 80,189,162,131, 29,178, 7,226, 93,201, 41, 88, 60,130, 32, 86, 49,100, 2,207, 60,178,134, 72,179,154, 66,
- 9, 36,115,112,183,160,163,235,242,124,231,104,164,169,143, 65, 42, 16,236, 28,149,226,173,119,121,219,188,191,206,230,215, 93,
-228,130,246, 68, 78, 56, 94,116, 12, 4, 75,163,160,201, 44,217,134,164,133,219,126,162, 36, 49,174, 82,176, 59,128,133,180,197,
-185, 5,142, 46,228, 42,141,109, 45,142,219,228,236, 97,124,112,148,180,171,184, 74, 66,155, 47,235,131,165, 46, 69,173,147,166,
-162, 93,176,235,228,252,166, 90,251,139,139,125,151, 53,175,187,113, 46, 51,228,102,228, 6,141, 91, 63, 75, 6,134,164,156,220,
-172,129,234, 17, 6, 64,186,139,121, 14,165,141,136, 21, 54,230,200,154,192,104, 99,232, 61,199, 30,180, 85, 3,216,117,129,147,
-231,239, 57, 3, 44, 44,130,167, 3,123,101,207,187,220, 34,104,149,146,155,134,241,113, 36,168,110,233, 54,183,221,233,147,245,
-119,223,154,179,223,127,251,233,251,151,183,119,177, 17, 6, 84,192,131,125,146,225,210,150,143,170,100, 15, 24,199,245,159, 11,
- 23,188,134,252, 14,175, 9,153,135, 67,219,249, 68, 99, 15, 53,224, 33,113, 37, 60,112,198,136,231, 89, 47,141,169,244,113, 81,
- 85,170, 61, 63, 48,239,126, 60, 28, 94,196,113,155, 14, 29,205,113,164, 97,215, 72, 59,208,126,186, 7,208,154,123,142,118, 84,
- 35,215, 61, 2,209,227, 21, 5, 63,112,228,131, 94, 32, 18,233,243,205,246,111,223,157, 62,126,252, 76,235,191,188,187, 13, 30,
-231, 15,161,128,238,179, 64,146, 92,109, 65,166,193, 54, 58, 43, 74,187,225, 10,228, 31,213,151, 33,140, 32,235,117,243,222, 15,
- 87,213,207, 87, 63,150, 13, 72,156,193,181,221,233,173,233,162,116, 79,209,194,232, 55,238, 65,243,168, 17,191, 94,255, 49,216,
- 59,186,100, 4,106,138, 35, 16, 18,128, 66,156,162, 29,192, 2,144, 48, 44, 13,107, 18,178, 14,205, 65, 60,214,202,132,218,241,
-194,104,184,101,203,112,215,110,116,190,110,206, 94,116, 31, 93,109, 69, 77, 93, 36,161, 52,194, 85,193,209,143,189, 36,219, 91,
-240,103,185,205, 66,208, 90, 3, 29, 38,119,211,184, 24,174,175,183, 62,184, 2,168, 37, 51,224, 55,160, 66, 1, 49, 0,151, 91,
-239,237,230,133,164,200, 38,175,214, 42,215,210, 42,145,182,117,113,148,150,187,109, 52, 89, 64,102, 76,193, 35,243,196,115,225,
- 87,153, 54,129, 97, 76,227,100,151, 74, 43,171, 2,213, 31,255, 10, 64,210,181,236,198, 81, 68,209,170,234,174,234,215,244,204,
- 56, 51, 14,118,172,196, 10,142, 32, 68,137, 88, 96,137,236, 96,225, 13, 59, 22,124, 3, 91,118,136,255,225, 43, 96,143,196,134,
- 44,178, 9, 2, 69,177, 32,142,133,147,201,120,218,211,207,234,170,226,156,201,106,188,153,135,187,234,158,123, 78,213,189,231,
- 70,223,255,248, 45, 50, 84,238, 18, 4, 52, 35, 23,152,224,129,181,144,115,206,211,254, 51,162,135, 86,220,112,176, 14,135, 14,
-114, 98, 14,196,173,230,181, 38, 13,155, 84,159,242,136,174,219, 74,182,254,213,131,102,148,133,225,253,106,120,187,246, 31,135,
-197, 39,251, 7, 71,243, 89,153,205,157,198, 46,167,243, 1,118,208, 60,206,160,238,176, 97, 82,192, 27, 18, 3,132,228,244, 32,
- 95, 28,157,188, 75,206,254, 9, 95, 92,116,107,211, 95,178, 76,153,237,106,244, 35, 33,138,209,218,175,240,212,174,146, 27, 86,
-178,138,146,189,101,160,130,217, 12,180,122, 9,114,233, 94,175, 93,175,204,126, 91,124, 94, 29,156,198,139,195,185,246,147, 73,
-101, 34,209, 55,174,222,208,115,201,102, 54,170,216,240, 38, 6,229,166,161, 93, 33, 38, 56,120,205,246, 52, 37, 32, 65, 87, 96,
-214,224,185,156, 34, 4, 89, 35,111,128, 94, 30, 2,142, 86,141,222, 66,225,215,169,109,182, 52, 60, 6, 96,109, 59,182, 32, 88,
-182, 90, 4, 68, 33, 20,173,229, 88, 97,200, 3,213, 67, 19,240,152,153,243, 67, 16, 57,142,246, 30, 44,181, 98, 61, 58,164,183,
-225,242,249, 15,163,130, 4, 91,184, 52,187,188,195,176,241,109,173, 56,194,110, 8, 73, 79,243, 28,144,221, 17, 16,127,205,204,
-132,117,142, 38,154,115,175,128,194,200,224, 25,251,202,251,200, 23, 83,221, 37,146,145, 9,181,207,146, 50, 43, 18, 82,140,116,
-236,176, 85,115,105, 99, 17, 45,246,103,251, 95, 62,154,157, 62,253,232,187,179,245,211,179,243,197,201,159,213,208,191,170,191,
-186,250,181,179,231,219, 34, 87,244,204, 71,228,122,182,212,231,248,131,119,181, 66,199, 60,108,100,109,243,174, 5,148, 23, 21,
-248, 47,240, 69,134,158, 6,195, 24,106, 13,241,221, 33,209,117,193,221,176,107, 28,140,216, 87,212,125,182,114, 98, 28,199, 70,
-236,144, 7,217,128,198,239, 44,209,128, 46,108, 88,244,147,209,241, 90,208,164, 47,193, 74, 7, 3, 60, 93,168,135,167,247,158,
-117,119, 86,215,111,160,170, 64, 67, 88, 93, 83,140,209, 6,192, 0,154,194, 89,170, 50, 75,214,120,122,165,234,192,141, 34,189,
-105,253, 22,194, 47, 5,169,209,248,117,144,161,178, 84, 37, 94,169,109, 53,160, 14,112,207,202, 56,154,255,237,204,154, 84,132,
-236, 60, 27, 99, 96, 57, 62,188, 4, 62, 12,238,237, 32,102,123,199, 39, 97,104,250,213, 0,117, 51, 24,101,160,240, 2, 69, 41,
- 4, 25, 24,215, 76,202, 89, 4, 69,192, 22,125,124, 58, 7,215,131,134, 25,159,123,177,199,190, 57, 49, 95,250,195,165,206,151,
- 33,186, 45,121,190,147,208,178, 12, 57, 4, 4,144, 86,226,144,138,115,150, 49, 1, 76, 37,228, 88, 21, 27,121,116,120,111,111,
- 57,223,188,167,159, 77, 16, 38,207,192,216,114, 59, 6, 44,174,203,150, 82,209, 23,184,109,104,249,225,229, 4,170, 20,207,159,
-207, 64, 21, 22,106, 34,194, 23, 64,166, 76, 60, 2,220,180, 41,178, 94, 10, 5,202,233, 19,216, 65,209,110, 2,189,119,113,115,
-157, 74,197,132,128,119, 87,155,234,242,101,123,250,248,201, 79, 63,220,189,211,255,245,252,231, 23,231,175, 43,215,198,123,160,
-106, 96,234, 90,165, 44, 12,209, 9,111,123,192, 94,232,201, 50, 6, 23,223,112, 88,138, 2,242, 25, 78,220,157,117,140,248,160,
- 85,232,101, 59,245,144,158,137,148,153, 1,154, 77,146,101, 80,183,198,201,193,212, 60,249,186,155, 62, 8,221, 21,189, 54,141,
-109, 63,184,246,185,145,205,121,189,160, 35, 5,126,219,238,138, 10, 72,206, 27, 93,219,155,174, 41,148,104, 66,138,160, 65, 18,
-119, 1,226,217,157,255,251,162,191,209,247, 63, 59, 14,237,133,221,108, 5,135, 30,199, 33,113,124,128, 96, 88, 59,183, 62,136,
- 14,232, 23,118,100,244, 25,128, 33, 78, 59,145,201,195,251,159,254,125,249,224,151,223,255, 8,238, 93, 92,166, 8, 20, 58,176,
-130,240, 15,180,237, 66,162, 46, 98,215,182,254, 56,190,189,104,159, 95, 93,178,226, 68,213, 65,209,156,195, 0,198,121,198, 81,
- 40, 53,152, 98,103,122, 19,242, 81,182,154, 83,190, 56,173, 98, 84, 26,203, 11,110, 81, 74, 66,182, 2, 78,219, 13,240,236,238,
- 90,124,243,219,197, 60,148,255, 25,108, 6, 29,242,148,243, 10, 41, 7,114, 45,179, 85,174, 51,186, 2,235, 9, 47,135,107,155,
-140,244, 99, 65,124, 14,193, 2,196,122, 35,116,107,124,173, 6,145,170,168,247,170,224,140, 94,167,144, 63, 91,203, 44, 51,166,
-137,156,132,104, 83, 20,189,168,193, 43, 16, 57,187, 62,181,209,153, 64, 83, 35, 51,118, 64,143,109,208,229,208, 13,222,231,160,
-133, 82,200, 91,101,248, 95, 0,146,174,165, 71,110, 34, 12,118,219,221,126,142,103, 50,195,102,178, 15, 41,136,135, 54, 7,164,
- 61,160, 32, 36, 30, 23,238,252, 21,110,252, 31,110,252, 9, 56, 1,183, 72, 43, 17, 36,162, 68, 9, 97,149,144,144,221,157,157,
-245,187,221,238, 54, 85,102, 53,167,157,209,200, 30,119,127, 95,149, 93, 95,149,202, 29,205, 5, 25,138, 42, 70,245,255, 56, 21,
- 13, 37, 50,154, 24, 5,156,229,231,205,229,208,215, 50, 89,136, 58,162, 83, 42,160,101,165, 57,156, 96,129,128, 37, 40,173,199,
-114, 24,187,136, 49,117, 89,109, 70,133, 79,160, 97,220,150,227,163,199,215,241, 95,201,201,221,229, 55, 7,249, 39, 7,135, 38,
-115,175,124,119, 69, 81, 52,184,127,181, 27,117,166, 87, 91,165, 78,146,187,199,181,191,255,188,253,232,181,238, 35,127,117, 20,
- 12, 70, 2, 4, 59,202,178,237,104,168,253,177,209, 50, 26,104, 46, 54,154, 56,236, 38, 29,205,108, 81, 0,220, 0,208, 78,224,
-223, 18,237, 44, 85,247, 60, 86,159, 40,167,176,238,229,186, 61,254,234,230,240,203,147,253,249,123,155,159,162,103, 79,118,239,
-106,223,216,254,245,168, 57,104, 66, 11,107, 85,138, 24, 63,110, 5,206, 63,210, 7,194,152,249, 25, 61,227, 73,100,196, 7,246,
- 99, 5, 94, 17,234, 27,225,136,154,131,174, 5, 49,183,153, 15,250, 86, 96,211, 12, 55, 52, 79,203,163,137, 75,172, 5,254,160,
-172,223, 99,211,117,129,105, 38,159, 25,128,174,112, 10, 91, 41,176, 78,244, 34,156,141, 43, 92, 80,134, 54,179, 82,169, 12,224,
-177,238, 67,254,211, 78,165, 34, 67, 88, 78,113,238, 20, 16, 30,182,130, 19,141, 17,166,247,170,151, 29, 21, 25, 64,230, 33, 74,
- 42, 69,244,184, 38,185, 30,140,102,218,239, 58, 81, 33,229,230,232,253,113, 54, 84,224, 9,161,115, 45,175, 8, 74,240,114,187,
- 90, 31, 29,174,206,142,170,237, 89,191, 44,222,221, 63,178, 47,227,235,219,191,189,249, 71, 84, 55,186, 84,159, 31,186,245,240,
-242,205,168, 64,217, 0,177,166,174, 15,214,204,133,197,241,130,238, 74, 98,165,113, 70, 88,212, 84, 99, 73,225,143,114,209,144,
- 49, 88,174,107, 39, 3, 68,203, 49, 34,127, 75,169,164,104, 44,118, 16,103,199, 73, 51, 20,253,170,200,152,195,217,141, 28,237,
- 7,148, 72, 93,247,190,163,197, 46, 39,173,122, 75,109, 66, 38, 88,235,167,121, 14, 78, 5,224, 92,239, 63,171,223,234, 50,231,
-128, 88, 95, 83, 38,198,204, 27,133, 78, 89, 43,182,219,168, 17,197,232,195,212, 37, 40,190,209,144, 20,224, 91, 97,208,140, 32,
- 94,166,208, 17,138, 7,206, 62, 29,141, 96,198, 44, 10,173,220, 98, 33, 69,195,158,141,150, 55,116, 88,109,130,114,242, 42,113,
-140,151,198, 41,181, 65,121,177,251,109,181,252,248, 65,145,191,208,104,219, 12, 6,225, 40, 28,237, 22,124, 49, 99, 54,167,152,
- 78, 81, 12,178,195, 91,169,154, 71, 79,103,251, 72, 41,115,108, 90,188, 14, 67,193,244,107, 41,175,230, 88, 8,170, 46,230,113,
-178,110, 30,210, 73,102,191, 61,188,173, 25, 63,234, 43, 91,237,116,116,126,178, 61,206, 62, 77,254,120,162, 47,175,198, 78, 53,
-121,210, 77,233, 74,113,132,126, 24,204,224,226, 68,243,222,225, 34, 5, 87, 3,125,142, 25, 43,238,121,122,121, 0,200, 53, 82,
- 92, 53,196,125,220,185, 14,229,115, 23,105,237,104, 52, 66,123, 67,134, 72, 38,210,129, 21, 53,198,180,192, 18,255,118,162,137,
-191,126,120,250,253,119, 50,219,255,252,252,135,167,111, 47,107,213,240,164, 40,245,147,129,167, 89,235, 48,106,127, 75, 61,211,
-152, 37,113, 47,169,247,232, 58,171,105,191, 20,166, 52,242,240, 67, 46,123,108,198, 94,232, 69,176, 97,212, 38,233, 76,188, 81,
- 34,197,250, 11,150,201, 73,242,224, 11,123,239,212, 87,173,165,212, 10, 21, 98,152,244,156,245,132,166,208,128, 33,199, 56, 84,
-229,155, 14,203,152,160,200,148, 86,214, 73,145, 96, 5,118,125, 47, 41,159,180,252, 38, 78,115,153, 88,253,250,231,249,106,251,
-237,103,167, 15,109,249,168,107,247,116, 31,109,152,218, 75,121,106, 59,169, 2,139,198, 74,206, 84,105, 67, 81,160,241,139,225,
-224,206,217,139, 87, 31,252,248,203,239, 59,123,177,202, 83,222, 41,205, 19,167,109,132,110, 19,205,242,104, 20,187,189,168, 90,
-217, 10, 61, 68, 81,198, 9, 54, 57,120,215,237,122, 73,149,239,194,135,124, 96, 62,161,208,224,192,201,145, 37,118,171, 88, 72,
- 57,165, 65, 76,156,195,116, 62,122, 21, 87,168,162, 67, 16,175,214,147, 76, 63,124,124,185,241,203,139,149,170,198,166,104,169,
- 75,214,232,254,131,195, 69, 40, 1,213,239,196,106, 15,204,152,226,180,108,148, 36, 28,232,110,246, 11, 5, 90, 14,188,137,239,
-154,180,125, 3,124,226,252,134, 18, 74, 14,204, 88,234, 56,154,112,218, 4,203, 22,224,125,204, 40,210, 78,108, 81, 15,162,138,
- 77, 70,185,182, 21,110, 1, 44, 9, 22, 16, 20,122, 24, 87, 96,104, 32, 13,168,109, 54,113, 7,109,210,236, 58,249,159, 0, 28,
- 93,203,110, 28, 69, 20,173,234,234,170,126, 78, 15,201, 36,142, 3, 73,196, 67, 81,136,131, 34,136,120, 45,144,144, 88,176,204,
- 42,108, 88, 69,136, 21, 95,198, 7,240, 15, 44, 64, 94,176,136,132, 64,178, 98, 91,188,108,143,123,166, 95,213, 93,221, 93,156,
-211,203,145, 71,237,153,154,170,123,207,189,117,207, 57,234,229, 15, 47,112,234, 20, 29,243,216, 88,242,139,191, 95, 48, 36,222,
-119,202,240, 86, 6, 24,148,114,122,101, 73,189, 91,156,167,201, 79, 65, 3, 72,186, 83, 93, 30,166,200,179,161, 47,201,222,115,
-244, 69,117, 85,204,174,170, 67,188,148, 70,175,141, 64,133,120,126, 49, 92,190,190, 4, 0, 77,175,134,163,249,214,179, 36,126,
- 34,223,248,200,172,223, 87,119, 30,155,213,199, 85,246,249,153,123,247,247,118, 44,155,173,114,151, 40, 87,232,132,138,226,216,
-249, 22, 11,138, 13, 77, 66, 95,198, 62,201, 52, 74, 21, 3, 78, 58,177, 86, 50, 13, 52,205,127,125, 18,178,184,119,186,165, 96,
-190,141,162,198,136,204, 37, 2, 33, 59, 27,174,246, 99,209,221, 60, 26,239, 63,137,214,171,131, 96,231,219,198,213,125,215,202,
-122,235,120, 6, 45,157,224,103,171,252,162,160, 18,206,180, 66,159, 22,229, 69,135,239,220,143,192, 30,216,208,218, 79, 88,133,
- 22, 27, 75, 41, 43,188,173,176,183,128,180, 1,254, 68,207, 94,190,116,251,217, 37,192, 29,222, 87,174, 65,245,131, 44,207,122,
- 24,225, 73, 54, 66, 2, 17, 1,221,162, 76,157,107, 26,203,144,231, 20, 72, 90,114,147, 30, 75,250, 25, 69, 50, 22, 78,210,128,
-128,222, 74,223, 82, 75,250,122,239,250,218,231,154,210,163, 86,210,120, 45, 2,174, 44, 56,245, 9,152,114,131, 3,221, 34, 69,
-150,210,130, 19,147, 35, 42,118, 74, 20, 5,173, 69, 28,221, 28, 30,190,253,233,163,249,147, 47,110,124,243,162,251,250,121,247,
-240,209,223,250, 78,221,215,219,203,243,249,159,157,236,175,132, 13,119,109,149,230,155,231,197,137,107,127,221,101,169, 65,225,
-157,107, 31, 41,189, 81, 38,231,232,176, 78,120,241, 23, 80, 67,143, 61, 13,206,136,113,182, 50,154,226, 64, 47, 42,101, 28, 32,
- 83,235,169,234, 41,194,235, 88,112,224,193,156,208, 71, 92,236,103,179, 11, 81,216,247,158,206,238,162,243, 59, 63,161, 26, 4,
-170,119,150, 45, 70, 57, 0,199, 8, 58, 38, 25,178, 2,124,178,232,208,197,226,193, 7,233,244,224,179, 95, 94, 93, 4, 99,109,
- 10,146, 94,107,202,161,136,100,162,214, 54,189,178,114, 58, 7, 2,180,186,165,195, 62, 12, 19,191,113, 70, 17, 42, 0, 85,164,
- 10,219, 56, 58,155,166, 64, 3, 81, 86,226, 29,162,149, 40, 75, 88, 97,207, 11,167,120, 14,199, 76,242, 62, 99, 67,194, 92, 56,
-179,228, 28, 17,194,203,211, 38,121,240,230,135, 98,216,249, 29, 47, 51, 20, 64, 52,163,135,201,189, 39, 19, 90,152,194, 83, 56,
-118,149, 7, 73, 22,224, 17, 55, 1,224,102, 89,196, 50, 59, 64,244, 99,115,150,171, 84, 47,194,156, 75,231,137, 88, 65,115,214,
-114, 89, 62, 36, 99, 33,167,197,249, 47,162, 11, 16,240, 24,254,145,171,211, 66,223,187, 29, 4,242,224,244,122, 77, 38, 90, 20,
-208,215, 52,136, 19,109,227, 36, 85,125,170,104,104,235, 76, 14,200, 23, 77,189, 52, 28,190, 42,169, 50, 56, 20, 52, 28, 32,231,
- 77,246,156,232,154, 18, 45,219, 94,137,138,220,189, 62, 27,166,221,164,133,109,255, 45,251,139,174,116,155,239, 94,222,253,254,
- 91,173,175,126, 62,255,241,245,233,159,101,189,227, 12,122,140,159,218, 72,235,144, 70,200,159,197, 15,178, 70,124,193, 89, 14,
-189,109,189,172, 70,100,108,110,188,128, 86, 87,206, 4,212,163,160, 71,151, 66,253, 38, 82,146,255,162,181, 54, 89,100, 18, 89,
-220, 46,242,167, 95,245,111, 29, 13, 87, 13,181,198,102,129, 3,138,128,106,168, 0,185, 31,156, 9, 53,158, 8, 84,104, 7, 93,
- 89, 64,181, 45, 47,169,177, 57, 6,223, 68,234,186,159, 19,156,139,174, 70,144,105,187,217,186,134, 67,200, 66,252,247,234,248,
-236, 96,243,248,254,221,253,118,123, 50,118, 9,221,154,236, 16,236,105, 27,172, 42, 35, 90,203, 97,100,202, 93,118, 0, 35,155,
-195,135,103,219,247,126, 58, 62, 62,217, 30,199,128,217, 70,197, 17,245, 36, 45,130,179,162,149, 58,202, 58, 19,248,202,204,128,
-106,207,110,221, 91, 23,191,149, 23, 29,189,175, 98,142,121,227, 68,227, 83,132,156, 96, 74, 69,166,167,132,130,223,161, 74,108,
- 99, 44, 78, 89, 27, 46,110, 17,209,220, 24,210,170, 45,239,181,243,228, 29,151,124,249,199,244,244,175,193,197, 33,224,244,202,
- 40,229, 73, 11,116, 46,177,216,249,163, 16, 43,165, 7, 36, 10,175,244, 28,148,157, 8,199,149,139,137,118,226, 81,236,169, 37,
-214,210, 27,100, 74,226,156,206,161,128,126, 14,127, 25, 38,149, 6,249, 62,234, 85,191, 82, 69,131, 0,130,143, 46, 17,188,176,
- 42, 70,173, 35,192,152, 64,163,170,230,157,114,104, 85,142,168,221,167,145,219, 15, 9, 94,246, 72,249,244, 73, 87,227,255, 2,
-144,116, 53, 59,114,212, 96,208,109,187,219,237,158,233,217,153, 44,176, 11, 1, 14, 89, 18,105, 5,138,224, 0,130, 35,220,243,
- 2,188, 30,111,192,133, 87, 8, 8, 14, 16,148, 72, 8,162, 4,146,141, 8,251, 51, 63,237,110,183,187,221,166,170,115, 92,237,
- 30, 86, 51,254,190,175,202,159,171, 74,207, 70,175,220, 36,198,140,234, 14,190, 25,227, 98,151,229, 4, 52, 72,235, 65, 64, 83,
-204,189, 18, 96,164,197,200, 98, 2, 16,142, 91,185,224, 2, 24, 29,204, 59, 7, 52,206,213,200,160,146, 15, 96,117,204, 4,191,
- 52, 78, 23, 96, 6,152, 3, 55,114,101,251,131,238, 14,215,191,191,220, 47, 30, 95, 86,171,112, 34,115, 27,139, 65,243,245,126,
- 24,204, 11, 6,107, 84, 55, 75,185, 73,226,173,160,188, 70,159, 43,202,222,208,166,191, 82,154,202,198, 44,246,150,207, 87,172,
-172, 92,192,148,115,229, 44, 28, 52,248,170, 18,102,155,189, 62,218,224, 27, 4, 83, 2,161, 48,185,157,173,125,179,206,136, 85,
-124, 45,219,171, 88,191,187,191,255,109,186,247,149,122,242,253,250,209,143,241,217,127,237,214, 55,205,196,188,114,153, 49,183,
-215,225,175, 5, 99,242,112,250,146, 10, 70,101,123,195,124,104, 32,131,237,184, 67,201,242, 46, 62,165, 57,227,166,109, 99, 57,
-169, 3,159,190,160,149,139,157, 72,101, 27,209,164,209,141, 40,164, 83,170,193, 12,188,162,165, 28,200, 76, 87,208,215, 50,186,
-108, 88, 2, 12, 73, 59,205, 85,143,102, 99,185, 76, 69, 55, 56,212, 9,216,185, 7,220, 6,125, 18, 20,130, 42,199, 24, 50,165,
-150,128, 22, 32, 14, 19, 21, 73, 81, 28, 99,170,203,182,204,215, 75, 12,136, 41,225, 67,215,192,108,153, 67,141, 90,111,192,166,
-187,169, 58, 62, 53, 31,212,242,211,251,221,217,151,251, 59,245, 85,191,250,247,106,215,253,243, 23,160, 62,168, 97,140,161, 0,
- 3, 88, 52, 9, 8, 90, 68,151,212,189,211,238, 61,249,244,133, 46,243, 82,103,212,150, 79,139, 92,206, 73, 99, 68,189,124,229,
- 3, 36,104,113,160,123,252, 64, 11,124,156,144, 89, 29,201,199,254, 50,164, 27, 77, 22, 77, 21,204, 28,233,211, 40,110,131,151,
- 66,188,154, 24,118,130,143,151,143, 90,146, 66,127,143,204,203, 19, 13,138,153,170,175, 46,208,134,190,158,109,168,120,181,142,
- 70,207,157,179, 40,140,216,188,127,242,199,202,247,224,242,195,224,195,162, 92,148, 18, 39, 90,197, 6,172,164, 35, 39, 25, 49,
-223,183, 65, 14,182,182,188,193, 61, 24, 67,247,193, 29,106, 11,103, 61,179, 33,101, 21,102, 61, 23, 65,204, 57,124, 71, 14, 35,
-149,150,165,207, 90, 26,121,130,152,160, 64,223, 80,179,233, 0,210,160, 39,125, 4, 66, 79, 35,203,232,194,207, 23,238,235,187,
-235,250,114,187, 3, 72,221, 2, 8,129,214, 8, 46,169,164,100, 3,103,188,147,200,214, 82, 20, 45,183,219, 21,179,149,149, 94,
- 79,178, 22, 92,152,141, 20,189, 36, 67,237, 7, 51,118,152,121,155,222, 68,251,100,102, 14,181, 13, 35, 45, 74, 37,183, 87,104,
- 47,234,104, 66,255, 72,105,218,223,228,246,226,252,188,201,235,227,167, 47, 79, 72,220,228, 94, 87,109, 10,235, 17, 31, 79, 69,
-189,158,143,198,234,169, 63, 80,250, 55, 48,179, 92,143,213, 98,234,123, 66,115,207,103, 18, 86,148, 76,245,152, 47,153, 81,172,
-147,215, 12, 50,118,166,237,253,176,181, 95,124,126,246,224,193,234,236,244, 39,241,203,197,179,135, 23,175,246,254,112, 80,186,
- 85, 99, 14, 68, 34,135, 57, 86,131,146,212, 62, 7, 57,221, 79,169,247,148, 58, 43, 31, 71, 53,214,183, 10,252,214,104, 46, 48,
- 2, 88, 87,150, 42, 16,179, 69, 38,175,163,226, 6, 62, 3, 50,200,139,126, 89, 31,153, 79,190, 9,183, 63,114,237,206,100,141,
- 88,110, 99, 95, 57, 28, 37,186, 9,129,232, 2,176, 22, 93,215,140, 99, 21, 51,154,115, 2, 48, 79,186, 27, 18,166,136,106,120,
- 87, 49, 6, 55,236,168,232,137, 18, 13,208, 3, 49, 68,134, 10,164,250,245,244,247,195,223,158,159,223,185,171,228,163,222, 53,
- 0,124, 97,196,255,149, 98, 37,251,126,105,102,147,131,161, 25,245, 58,223,124,120,246,124,255,217,119, 63,252,122,233,255,180,
-245, 66, 4,211,123, 45,218,209, 83, 39,213,210,127, 0,240,188, 4, 38, 16, 94,142,224, 99,139, 13, 53,132,232,122, 86, 70,122,
- 79, 72,234,174,138, 34,102,205,136,142, 96, 34,173,103, 84, 81,102,170, 48, 64, 33,183,142,192, 73,233,118,239, 68,201,206,165,
-173,121,219,110,202, 70,126,252,248,112,123, 59,108,243, 28, 3, 38,229,133, 62, 56,192, 94,204,199,190, 8, 85,199,108,153, 16,
- 8,245, 71,109,151,170, 11, 53,201,172,147, 78, 22, 94, 22, 21,170,194,131, 7,214,170,107,122, 57,133,140, 86,205, 46, 78, 6,
-216,116, 5,132, 29,105,175,134,158, 84, 84,224,248, 56,124, 21,119,167, 58,113,208,107, 94, 35,242, 26, 43,129, 77, 10, 16, 57,
-174, 70, 21,122, 99,200, 27,128,112,148,102,100,236,205,255, 2,144,116, 45,173,149, 20, 97,180, 94, 93,221,183,251,222,155,100,
-146,144, 24,131, 10,227,204, 48,224, 98, 64, 16, 17, 65,221, 40, 8,238,116, 35,136, 63, 64,252, 89,254, 10, 87, 46, 68,102, 41,
-136, 89,102,192, 71,204,227,154,155,219,143,234,174,170,174,246,156, 54,171,132,144,132, 84, 87,127,231,156,170,239, 59, 71,127,
-247,253,215,120,107,250, 62,177,120,225, 65,199,127,253, 56, 56,185, 27, 93,235,117, 96,163, 76,139, 79,232,171,201,228,242,214,
-140,124,199,167, 7, 91,116,183,131,199,170, 77,212,176,216,135,125, 64, 17,137, 41,187,215,189,231,205,211, 98,237,123,232,129,
- 14,202, 72,150, 5,132,128, 37, 25, 53,133,197, 50,183, 43,117,131, 63,127,152,225,177,220,230, 60,220, 3, 18,161,168, 45,104,
-178, 23, 24, 41,156, 19,106,122, 53, 71, 46,141, 60,152, 70,105, 41,241, 80,115,236,176,169, 81,162,138,210, 75,149,147, 6, 89,
- 58,197,217, 69, 90, 58, 58,123, 24,181,164,183, 89,202, 86, 11, 31,161,233, 41,100,170, 64, 59,164,219,176, 60,110, 31,127,178,
- 56,123,167, 82, 40, 81,215,244,108, 27,250,221, 77, 2, 97,235, 39,206,192,146,100, 57, 77, 75, 31, 94, 82,141,106, 27, 6,195,
-161,120,179,163, 3, 82,108,133,219,137,113, 51, 57, 79, 83,251,224,149,219,162,202,177,171, 13,156,186,233,116, 80, 52,144,234,
-239,241, 44, 12,175,160,246,243, 42,233, 1,168,136,215,128,179,211,146, 71,191,137,173,212,160,231,157,193, 15, 38,188, 66, 59,
-198,230, 1, 67,229,208, 78,206, 41, 19,176, 72,178,158,114,176, 80,206,217, 97,117, 38,181, 6, 81, 43,166,140, 31, 60,156, 29,
- 64,136,246, 56, 88, 76,215,190,144,214, 75,125,240,214,219,143, 94,188, 48, 95,125,219,126,246, 69,122,252,225,214, 22,205,195,
-205,250,246,114,232, 91, 32,168,198,214,233,156,114, 42,239,176, 10,127,238, 55,201, 69,239, 91,253,241,153, 58,175, 95, 94,129,
-238, 13,121,185, 98,202, 44,173, 29, 80,253, 50, 82, 46, 9, 29,109, 81,154,153, 58, 44,217, 11,102, 56,142,175,152, 82,128,245,
-225, 0, 17,228, 96,116, 84,146,110,114, 53,163,151, 98, 77,235,134,208, 1,215,109, 15,118, 22,217,146, 60,228, 60,101, 74, 28,
-235,183, 80,128, 99,159, 20,179,131, 89, 6,233,119,170, 68,145,131, 4, 66, 6,138,242, 76, 28, 61,123,247,231, 77,117,249,215,
-102,177,180,115,198,206,174,209,133,237, 69, 62, 41, 38,163, 69, 41,157,241, 28,232, 48,193,136,245, 36,252,146, 54,137,168, 56,
-204, 55,204, 56,163,198,147, 53, 59, 87,100,105,218,129,217,138, 76, 12,103,106,139,206,245, 52,186,204,101,188,239,192,151,203,
- 33, 49,182,190, 68,125,159,141, 99, 68,216,182,241,236,205,147,167,114,114,193,141, 69, 84, 11, 81,226,215, 28, 37, 91, 40,240,
-180,137,193,199,137, 6, 6,123, 82, 22, 12,202, 20, 10,223, 59,166,111, 14, 48, 74, 52, 16, 16,114,190,124, 99,162, 48, 93, 98,
- 70, 30,105, 16,198, 7, 72,143,249, 86, 44,210,132,136,183, 63, 57,211,205, 81, 45, 57,176, 40, 64,189,141,242,143, 14,170,211,
- 67,128,249,162,125,160,219,102, 17,128, 3,113, 96,142, 37,246,129,109, 67, 70,213,168,122,107,202,222,197,133,171, 86, 99, 13,
-141, 82, 78, 45, 94, 61, 84, 94,233,193,215,218,172,217,180,157, 15, 74, 52,247, 55,226, 86,172,202,211,207, 63, 61,255,230, 75,
-121, 88, 92,244, 63,254,122,249,219,182,190, 10,187,127,148,188, 27,255,159,197,207,106, 10, 27, 6, 60,104,202, 89, 53,205,246,
-183,120, 52,158,174, 19, 17,194,102, 50,206,198,147, 18, 16, 73,132,204, 56, 66, 54,133,165, 98,119,100, 97,195,145, 92, 84,154,
-151,103,207, 63,240,111,188,223,220, 59, 25,106,246,113,249, 9,186,152,253,134,115, 76, 53,255, 21,219,221,169,200, 30,119,144,
-105,159,123,188, 87,100, 17,162,141, 0, 39,219,225, 31, 98,167, 65, 40,125, 86,186, 80, 71,122,173, 27,107, 27,151,130, 75,219,
-205,238,201,235, 79,206,207,219,230,239,235,145,160, 0,176,209,198,209, 41, 91, 77,129, 3,187,161, 63, 61,127,237, 46, 60,253,
-225,167,139,223, 95,253,178,127, 82,230, 99, 14,252,218,173,198,146,169, 46,105,204, 1, 81, 26, 42,140,167,246,108,130, 27,138,
-246,244,163,103, 7,254,230,162,187,138,218,114,212, 76, 52,156,222,164,118, 71,225,200,103,239,175,232,130,183,204, 89,110,234,
-110,183,145,245,117,215, 3, 92, 82,101,243,242,240,120, 42,158,255,145,222,123, 53, 28,135,113,171, 76,135,141, 76,133,150, 9,
-103, 82, 41,171, 56,143,249, 7,208, 61,198,108,229,123,166,212, 93, 27, 44,152, 71, 96,124,175,138, 54,175,171,149,237,219,225,
- 1, 26, 81,107,142,151, 0, 69,141, 2,128, 23,107,118, 71,246,163, 15, 58,106, 20,177,232, 67, 9, 92, 41, 56,233, 34, 19,182,
-177,134,204, 7,184, 75, 18,210, 64, 45,160,242, 57, 65, 30, 98, 76, 47, 5,232, 27, 42,176, 53,162, 23,233, 63, 1, 88,186,154,
- 29,185,137, 48,216, 63,254,105,219,227,217,221,217,236, 2, 18, 68, 44, 34, 72, 32,161, 36, 18, 7, 68, 4, 66, 2, 33,193, 9,
-229, 5,184,113,226,200, 59,241, 0,188, 0, 7,114,224, 2, 71, 14, 81,148, 72, 97, 9,129,221,157, 25,143,221,182,219,221,110,
-170, 12,231, 93,205,104,218,237,250,170,186,191,175, 74,127,251,253,151, 17,148,121,162,197,162,162,169, 64, 51, 70, 51, 10, 91,
- 13,163,162,158,234, 7, 3,162,160, 51,134,105,118, 96,166,179, 31,167, 34,193,195, 47,131,245,169,135,166, 3,252, 50,194,101,
- 49,112,236,217,250, 12, 65,233, 92,127, 56,152,158, 11,217,161, 88, 78, 41,106,145, 46,241, 19,116,219, 72,186,213,112,214, 80,
-154,210, 73,230, 78, 75,198,106, 79,218, 24,186,125, 4,186,236,227,127,150,116,121, 72,241,130,125,140,142, 75, 98, 66, 31, 68,
-207,114, 32,138,101,176, 12,165,117,170, 69, 21,105, 34, 11,192,164,187, 92, 10, 57,158, 58,111,116, 41,215, 41, 24,113,158, 15,
- 38,209, 41,158,145,170, 38,155,142,215,174,190,227,238,126, 14, 37,126, 42,253,170,106, 32,163, 18, 63, 79, 3, 54, 97,240, 86,
-122, 15, 69, 63, 81, 34,106,105,175,162,199, 14, 98, 74, 1,175,212,197, 86,204, 21,251,181,129,105, 32, 59, 28,198, 83,116,111,
- 9, 96, 34,244, 50, 85, 60,161,172, 35, 16,255,168, 30, 29, 35,202, 34, 91,140, 68, 48,120, 54,204,146,214,118, 82, 22,100,200,
- 39, 12,132,192,239,112,250, 40,149,187,150, 7,221,140, 23, 84, 9, 10,189, 77, 18, 16,118, 93,101,235,141,204, 76, 66,102, 93,
-106, 85,228, 80, 72,107,159, 67,155,235, 88, 39,253,192, 84,195,180, 59,153,231, 91,111,221,175,190,120, 24, 63,254, 58,188,255,
-225,203,213,102,110,254,174,119,151,173,125,193, 68,222,137,204,171,164, 25,155,112,208, 40, 0,109,155, 29, 86, 94,237,143,121,
-163, 85,214, 15, 47,158,219,238,137, 91,101,196,175,130,152, 67,243,174, 12,220,148,209,147, 64,114, 94,100,207,139, 7, 28,119,
-210,146, 70, 40,242, 5, 15,192, 35,121, 81, 76, 99,153, 14,208, 13,134, 41,241, 93, 74, 76,135,102,246, 55,216, 45, 52,244, 72,
- 34,143, 74,121,191,102,103,211,201, 30,117,110, 24, 38,190,197,108, 28, 93,211, 42,135,180,182,172,232,184, 3, 44, 92,189,105,
- 78, 62,125,239,167, 23,162,217, 95,175,177,246,118,152, 15, 12, 76, 38,177,116, 88, 20, 81, 70,130,103,106,100, 5,113,236,253,
- 33,160, 52, 4, 14, 76,170,222, 67,112, 4, 19,120,110, 59, 71,229,251, 37,116,135,247,183, 74, 67, 87, 26,254,133, 77,170,156,
- 29,174, 68,217, 69,124, 28,222,136,197, 70,153,184,139, 61,124,126, 36,186,222, 63, 15,235,243,139,179, 11,213,140,186,205, 66,
- 33, 13,128, 44, 38,117,197, 38,177, 66,136,163, 76,158, 68,206, 12,227,193,198, 19,153,222, 38,153,144,195,114,200,174, 24,184,
- 44,152,200, 22,197, 64,159,118, 30,203,248,255,170,216, 18,166, 18,228,255,174,157, 0,255, 66,196,142,172,159,173,134,189,136,
- 37,205,243,199, 75, 83,110,111,157, 84,248, 33, 87,109,209,199,132,182,133,140,190, 1,135, 15, 53, 39, 25, 6,105,134, 44,100,
- 54,160, 98,239,218, 18, 27,149,227,207, 2,216,156,140, 12,179,223, 1,210,228, 21,248,105, 23,207,212,107, 95,125,118,241,221,
- 55,245,187,239, 60, 85,191,254,242,231,207,191,255,117,185,221,118,198,221, 4,181, 15,201, 72,231,213, 0, 45, 71,243, 95,197,
-185, 36,172, 51,164, 59, 45,138, 53,160,141, 23,243,204,163,192, 27,203,145,145,153,189, 98, 46, 82,177,168,121, 69,155, 19, 20,
-252,122, 35, 87, 37,104,172, 57,191,247,209,120,251,193,182,219,123,209,105,149,238, 90,201,151,134,135, 38,114, 4,158,205, 10,
- 36, 59,218,141,191, 73, 10, 48, 37,108,114,118, 12,123,215,106,162, 37, 24,208,216,237,129, 24, 59, 11,252, 26, 18,240,168, 17,
-149,119, 56,128, 80,142, 6, 36,188,158,247,219,195,112, 56,254,224,238,235,157,123,218, 88, 11, 24,237, 1,158,187,224, 90,148,
-241,169,247, 60,209, 62,123,227,193, 15, 63, 14,191, 61,126,116, 90,114,248, 46,110, 5,202, 3, 68,225, 56,197,229, 4,144, 29,
- 66, 88, 54,207,188,112,209, 56,124,242,171,159,220,155,174,255,120,134,170,197, 4,168, 30,228, 65,177, 3, 83,122, 71, 91,139,
-153,233,102, 12,174, 99,190,236,108,134, 52,203,171,252, 44,203, 95,145,229, 29,187,185,255,210,188,253,108, 58,237, 83, 55,228,
-123, 29,193,103, 2,157,185, 56,203,173,115, 16,101,178, 56, 38, 55, 69, 38, 75, 20,216, 10,110, 4,168, 12,109,154,117,206,131,
- 20,255, 51, 3, 23,167,171, 86,237,251, 94,230, 77, 33,161,153,102,230, 55,117,116,146,202,139,130, 46,253,198,133,204,164,138,
-110,197,128, 69,232,102,181, 98, 68, 17, 68,175, 53,199,217,146, 83, 85,128,126, 5,230, 68,129,242,131, 64,225,229,168,236,129,
-231,107, 57, 83, 7,192, 37,254, 21,128,164, 43,217,145,163, 8,162, 85, 89,153,181,247,116,207,230,217, 48, 99,201, 66,136, 11,
- 22, 2,201, 71, 16, 39, 44,241,181,220,248, 1, 64, 22, 66,248, 0,226,100,236,182,140,177,103,166,167,187,214,172,202,141,247,
-154,107,119,151,186, 42, 43, 35,226, 69,100,196,123,114,178,130,228,217, 33,223,172, 66,118,231, 60,238,136,220,220,166,203, 17,
- 90, 87,113, 51, 68,233,135,113,135,164,214,195,143, 25, 0,127,107, 68,143, 29,100,144, 87,204, 19,153,136, 53,214, 6,215,119,
- 81,175,136,110, 0, 37, 84,174,246, 82,176, 36, 87,109,125,161, 99, 91, 69,137, 50, 3, 1,249,232,211,229, 56,145,242,173,239,
- 26,151,145,104, 11,107,192,142, 43, 53,241,160, 67, 99,155, 37,120,171,198,187,212,250, 70, 38,135,108, 62,246, 20,186, 76,210,
- 67,159, 57, 30,251, 9, 13,132,223, 14,129, 39, 56,108,121, 73,106,228,125,164, 21,212,145, 60, 65, 8, 46,253, 4,131, 35,127,
- 78,238, 1,218,106, 83,140,196, 88,136,222, 99, 24, 94,166, 99, 60, 93, 62, 25,190,127, 82, 53,235,195, 23, 63,248, 63,127,223,
-189, 90, 55,247, 25, 0,223, 72,106,225, 20,222, 66,180,190,194,109,104,188, 99,171,200,118, 16,193, 29,135, 27, 74,254,197,166,
- 40,150, 54, 12,113, 40,128,124,217, 88, 30,239,105, 11, 96,176, 54,137, 21,231,233, 21, 76, 36, 67,224,106,217, 79,149, 79,123,
-162,170,135, 46,157,128,236, 99,233,169, 4,144,164, 81, 7,175, 22,202,228,216, 32,152,113, 72, 66,198,209, 5, 2, 12,103,118,
- 40,161, 66, 58,156, 88,151,164, 67,144,141,208, 21,124,214,136,189, 1,144, 92, 44,220, 97,118, 61, 60,253, 42, 58,185,218, 93,
- 62, 21,245,202,223, 32, 65,188, 3, 40,178, 70,182,162,226,120,141,233, 17,241,228, 56,184, 32, 53,217,153,198,164,169, 26,108,
-199,182, 54, 65,108,116,251,217,233,121, 61,189, 93,251, 94,120, 96,223,132, 12,141, 53,144,169,231, 32, 26,172, 25,120, 25,254,
- 10,123, 54,161,148, 48, 11,202,196, 35,150,172,121, 8,229,130,188,219,148,127,213, 36,242, 84, 29,115, 65,215, 91, 32, 21,101,
- 41, 76, 60, 3, 75, 86,177,185, 97, 49, 15, 17,185,115,243, 1, 91, 97,221, 52,177, 64, 95,179,159,246,255,118,248,168, 72,162,
-222, 80,234,172, 56,138, 22, 71,167,157, 45,154,215,239,202,222,139, 11,229,103,105,151, 10,127, 1,159, 50, 28,251, 77, 16,199,
- 91,142,134, 58,195, 19,124, 44,187, 41,133, 50,226,214,198, 85,142,235,103,231,246,166,202, 74,189, 20, 41,126,105, 23, 86,234,
-193, 96, 91,122,149, 34, 63,195,163,205,198,170, 48,151, 75,103,144,126, 79,112, 93, 76, 10,224, 25, 67, 66, 88,149, 21,209,240,
-246,239, 31, 87, 23,159, 94,159,101,187, 6,175, 74, 29,193,190,114,206,254,151,212,178,137, 42,191,215,120,192, 79,225,220,207,
-201, 77, 35,183,172,213,114, 0, 7, 43, 45, 41,226, 38, 89,172,163, 36, 3,117,121, 2,107,112,228,204,141,247,196,232,130,112,
- 62,217, 31, 38, 4, 77,156,236, 74, 50,182,113, 6, 32,229,188,107,171,243,244,215,199, 15, 79,206, 30,124,241,215,250,248,213,
-251, 77,172,122, 83, 91,201,154, 95,209, 32, 1,183,209,208,181, 64,162,163,183,205,187,253, 32,148,105, 7, 25,215,166,239,123,
-127,191,157,245,152, 47,203,171,103,223,201,175,191, 52,153,122, 29,125,120,115,247,219,250,254,229, 6, 78,165,221,228,243,142,
- 37,101,106, 30,212,100,211,116, 35,208,130,141, 57, 13, 68,154,169,182,145,213, 28,108, 22,188, 98,193, 45, 65,204, 45, 18,137,
-199,193,115, 85, 18,155,152, 3,136,142, 2,169, 7,137,182, 69, 41, 22,161,170,203,213, 39,159,235,235,111,255,213,189,208, 0,
-151, 19,236, 83,150,156, 33,142, 92, 6,207, 99, 16, 27,122,183, 27,118,249,209,198, 41,217,246,236, 55, 13,134,220,194,190,136,
- 69, 71,244, 13,227, 50,198,213, 7, 0, 18, 73,243,222, 14,117, 82,168, 41,169, 0,211,162,113, 27, 52,188,237,105,246,211, 31,
- 47,190,121,249,236,108,245,160,185,221,132, 62,168,145, 13,186, 62,119, 19,112,223, 48, 93,156,127,252,203,157,251,249,159,231,
-114,129,133,173,198, 86,237,210,176,112,115,181,139, 91,198,110, 88, 92,106,225,196, 39, 54, 99,123,164, 14,122,122,124,181, 40,
-252,122,230,252,107, 78,141,117, 99,145,147, 97, 63, 36, 43, 58, 80,133, 79, 82, 42,199,137,226,224, 50,251, 72,156, 63,178,217,
-229,152, 46,135,179, 19, 77,190, 24,152,212, 22, 40, 34,237,166,184, 58, 36,177,170, 87, 21, 64, 68,213,249, 22,254, 57, 76, 2,
- 14, 31,208,112,156,210, 64, 10, 6,164,131, 25, 76, 15, 89,190, 56, 74, 30,157, 87,117,109,117,126, 58,227,235,187, 27,191,141,
-250,231,205, 27, 29,110, 43,175,125,234, 50, 36, 57,228,237,233, 15,236, 98,152, 84,230, 41,240,145,185, 84, 68,242, 30,219, 90,
-205, 9,194,141, 31, 99,197, 83,175,237,104, 15,162, 28, 24, 10,112,215, 91, 83,215, 34,145,117, 23,108,184, 85,247,101,168,138,
-249, 63, 1, 72,186,150, 29,201,105, 40,106, 39,206,203,169, 84,186,139,110, 26,122, 80, 75,205, 48, 60, 52, 98,129, 52, 72,204,
-134, 29, 27,196,239,242, 1,179, 98,195, 6, 16, 45, 36, 52, 61, 51, 13, 20, 51,253,170,174, 74, 85, 98,199,142,205, 57,197, 15,
- 84,197,137,239,189,231,216,247,158,195, 81, 89,222,254, 5, 61,110, 54, 37,232, 71,145,218,137,250, 86,110, 64,166, 5, 20,158,
- 86,107, 67,131, 81, 96,177, 48, 74,203, 49, 36, 26,212,187,253,164, 88,166,214,156,113,113,134,221, 73,117,204,130,237,172,226,
-245, 59,128, 82,239,202,156, 13,167,206,166,150,205,203, 60, 87,172,166, 66, 36, 3,234,185, 49, 0,123, 37,160,186, 72, 55,233,
- 0,112, 32,203,224, 84,113, 32, 63, 16,168, 66,178, 1, 57,247,236,145,160,142, 80,224,196, 55,182, 11,229, 32,240,101, 82,192,
- 90,138,185,132,230, 16, 81,155, 25, 79,181,239,130, 22, 90, 41, 72, 1,106,137,228,168, 3,138,138, 22,142,210,220, 32, 56,192,
-212,216,168,125, 85,112,222, 19,172, 58,238,236,205, 13,104,181, 57,126,106,190, 59, 43,190,186,126,239,242,197,252,231, 95,147,
-127, 95, 47,183,183,214,250,194, 68,148,168,109, 39, 50, 27, 34, 29,219,167, 98, 63,216, 72,179,220,210,143, 10, 96, 35, 45,242,
-169, 57,140,118, 67, 33,151,148, 58,168, 9, 95, 82,160,181,116, 58, 97,231, 51,227,203, 38, 51, 58,220, 3, 2,105, 58,142,226,
- 89, 41,183, 81,199, 30,105, 44, 43,154,118,140, 83,182,167, 1, 41,178,186, 87, 46,211, 50, 31,149,244, 33, 89,140,101,174, 7,
- 30,222, 7,197,121, 89,239, 10, 94, 72,214,135,243,246,248, 84, 62,126, 38, 78,191,233, 78,207,157, 25,132, 93, 53,247,191, 8,
-219, 42, 21, 75,124,215,217,218,248,249,193, 78, 75, 55,178, 11, 11,168, 91,186, 18, 1, 81,225, 7, 70,211,251, 34,197,227,199,
-172,187,251,172,125, 63, 79,140,159, 37,238,193,129,203, 41,192, 29,202,160,168,162,151,170, 44, 67,203,169, 22,202,114, 97,205,
- 45,165, 79,217, 66,224, 19, 10,192, 78,244,144, 12,236, 99,158,120, 76, 35,188, 25, 20, 34, 59,136, 9,156,244,127,135, 66, 19,
- 99,190,162,131, 21,165,216,146, 17,223, 14,208, 83,121,203,105,110,203, 51,139,116,111, 25,136, 10, 90,130, 22,163, 4, 38, 76,
-134, 85,147, 93,117,243,238,237, 95,224,171, 85,202, 28,211,122, 79,208, 48,234,164,147,199, 33,205,236,198,225,139, 6,138, 49,
-103,186,161, 62, 32, 13,218,167,170, 10,201,146,183,215,114, 70,250, 10,246, 4,180, 61,137,114, 55,243,226, 40, 13, 15, 5,157,
-146,115,153, 83, 21, 22, 47, 60,221,154,168,172,219, 91,159, 5,213, 90,205, 1, 13,217,247,169,170,105, 70,127,253,106,123,245,
-241,233,227, 69,222,197, 77,210, 46, 98, 6,186, 40,121, 24, 84,228, 60,159, 65, 29,160, 11,204, 1,229, 20, 28,103, 21,104, 34,
- 19,105, 75, 44,196,157, 0, 29, 37,105, 83,130, 93,105, 91,165,106, 90,178,160, 42,170,125, 99, 49,145, 36, 15,139,120,111, 11,
-186, 4,236,138,194, 73, 92, 76, 53,172,148, 90, 42,165,117,247,210,191,153,105,247,236,201,211,147,131,143, 46,151,237,203,181,
-170, 2,234,180,208,116,201, 66,133,225,124, 29, 94, 74,147,115,232,217,107,181,234,135,113,189,187,235, 22, 71,213,201, 15,207,
-243,111,159, 79,117,133,204,254,207,230,247,229,187,203,110,186, 49,170, 40, 37,234, 67,196, 63,110, 85, 42,122, 16,228, 64, 57,
- 58, 80,248, 41,166,148,193, 67,178, 96,163, 42,224,187, 50, 41,105,133,141, 19, 22,176, 55, 13, 1,123, 13, 88, 7,253, 1,232,
- 96, 39, 43,188, 6, 89,233, 89, 86,205, 50,125,122,222,157,125,189,150,218,173, 47,154,185, 68,232,210, 8, 97,218,223, 8,211,
-225,225,129,110, 94,224,239, 57, 82, 34, 22,145,184,120,189,141,123, 42,179, 77, 50,225, 87,228,132, 99,230, 43,103,205, 29,138,
-122,225,230,165, 4,194,117,136,117, 64, 43, 73,246, 80,108, 81,141,228,189,127,123,241,114,247,228,123,173,111,227, 8,218, 33,
-120,197,238, 31,162, 55,147, 90,164,230,104,241,211,143,203,109,255,238,164,173, 6,236,136,202, 87, 8, 90, 71,115,167, 34, 3,
- 76, 20, 99,240, 8, 35,101,205,222, 98, 22,108,243,240,211, 47,142,131,184,160, 21,100,198,163, 71, 17, 84, 94,136,225,222, 59,
- 19,171,138, 22,158, 89, 93, 45, 30,205,195,226,115,159,159, 47,203,122, 64, 2,159, 54,118,123,165,145, 87,107,196, 46,187,134,
-251,140,202,250,243,168, 70,110,167, 29, 7,128,170,218,251,129, 77,219,134,158,155,211,100,123, 90, 66, 45,114, 35,190,172,244,
- 39, 31,202,179,195, 55,229,201,159, 2,248,179,224,211,137,208, 10, 51,255,237,213,163, 23,151,231,127,220,221,190, 28,254,110,
-178, 78,243,116, 34,167,206,164,124, 8, 90,201, 66,154, 77, 16,138, 22, 91,160,217,148, 75,177,222,249, 88, 78, 72,140, 49, 73,
-237, 16, 16,253,202,246, 53, 48, 79,143,213,149,174,174,196,124,179, 18,137,254, 79, 0,146,174,101, 71,142, 26,138,186,108,151,
- 93, 85, 93,221, 61,157,153,204, 3, 37, 65, 3,100, 17,134, 89,160,145,178, 96,197,130, 61,223,192,159,241, 25,172, 88, 32,177,
- 64, 40, 72, 44,144, 18,146,129, 4, 33,230,145,164,167, 95, 85,126,148, 31,220, 83,217,181,212, 82,171,203,229,123,239, 57,246,
-189,231, 72, 76,142,227,252,205,207,253, 14,110,127,185, 87, 16,164, 66,191,144,233,222,231,186,245, 25,138, 91,202,184, 33,244,
- 66,212,178, 99,166,240,202, 72,140,228, 91, 75,212, 96, 7, 59,204, 18, 50,159,137,217,173,145,133, 21,205,100,189, 50, 98,191,
-245,193,229,106,170,150,193, 29,121,226,119, 93,175, 96, 3, 52, 36, 19, 74, 8, 97,235,188, 99, 70,150,177, 46, 49, 58, 80, 18,
- 83,171,179, 39, 12,209,239, 32, 67,150, 38, 1,230,124, 56, 88, 26,229, 58,179, 86, 86,247,112,186,233,129, 64, 84,244,140,128,
-182, 80,200,189, 3,238,198,169,154,204,117, 70,142, 41,178,161,116, 86,210, 82,164,176, 99,109, 86,112,178,197,113, 34, 1,165,
-154,254, 46,163, 92,218, 90,191,190,121,206,139,198,207, 63,218, 60,253, 78,126,121,167,175,255, 56,253,243, 87,245,234,217,219,
- 55,111,232,173, 64,109,123,240,197,128,126, 5,130, 72, 85,155,160, 86, 51,129, 20, 14,198,180, 35, 44, 41,160,187,173, 41,190,
-113, 35, 74,219,179, 38,124,214,150,134,232, 77,225, 92, 69, 69,133,171,200, 26,207, 58, 72, 13,103,171, 50,101, 16,193, 69,139,
-154, 75,245,182,218,241,162,158, 18, 33,160,154,164, 37,109,189, 38, 38, 13,223,249,168,188,137,220,180,253,108, 77,127, 54,233,
-121, 49, 59, 58,105,142,159,172, 63,185,216,220,255,204,197,137, 9,157,184,122,177, 7,145, 90, 21,226, 36, 64, 68, 13,233, 25,
-106, 52,156,243,102,216,249,186,169,124, 40,253, 42, 97,122,196, 15, 13,163, 55, 64, 59,217,174,118,153, 15,135,247, 79,238,153,
-213,213, 50,250,185, 46,209, 62,203,247,232,171, 17, 82, 19,186,198, 85, 4, 61, 25,107, 56,101, 46, 34, 82,195,136,195,198, 26,
- 71,193,138,187, 55,220,181,209,146,163,153,184, 31, 66, 43,107,202, 7, 27, 40,164, 88, 47,204,144,209,254, 79,161, 91,229,194,
- 36,136,205, 6,185,133,164, 18,186, 43,167, 99, 38, 36, 48, 56, 54, 43, 49, 12, 76, 10,136, 65,228, 3,118,124,188,248,193,244,
- 70,186,217,172, 31,176,198, 10, 82,158,169, 34,212,226, 43, 89, 89, 90, 24, 93, 52, 68,246,121,142,166, 37, 62,216, 17,240,230,
-199, 60,109,104,203,207,224,239, 72,228, 18, 18, 35, 68,213, 32, 89, 75, 40,139,151, 4, 83, 26, 94, 19,230,182, 12, 45, 7, 77,
-150,180, 28, 49,176,169, 46,186, 48,118,193, 23,157,195, 16, 66,131,115,240,196,142, 7,183,101, 63,253,155, 79,159,156, 76,173,
-115, 74, 6, 77, 89,154, 66, 58,160, 39,142,248, 8,225,198,250, 1,156,191,242, 82,240, 69,132,205,196,128,243,153, 15, 40,254,
-131, 56, 52, 33, 95,162,141,148,102,160, 81, 47,100,116,193,143,131, 15, 18, 82, 3, 49,110,233,129,115, 76,240,237, 19, 91,200,
-227, 17, 0, 33, 88, 51,250, 28,230,220, 82,161,180,219, 91,173,239, 30,158,124,122, 56, 63,229,255, 28, 93, 94,205, 66, 94, 82,
-144, 76, 74, 21,171,206, 18,236, 88, 49, 56, 8,248,213,202, 66,244,249,236,209,193,233,193,193, 87, 23,166,110, 94,178,155, 43,
-243,243,237,250,189,179,111, 7,177,133, 73, 89,236, 50,206,195,225,216, 51,206, 91, 16,166,237,153, 68,195, 36,247, 96, 17,144,
- 9,170, 18,155,211,167,154, 30,114,236, 52,176,101, 3, 77, 44,248, 18, 22,165, 82, 54,193, 93, 68,115, 51, 97,165, 30,164,208,
-250,164,223, 63,124,156,191,248,250, 29,159,243,119,175,139,186,165,232,138, 29, 1, 22, 98,192, 6,221, 76, 97,183,102, 43,153,
-234,140, 28,202,243,206, 19, 55,119, 40, 20,140,173,119, 65, 82, 96, 18, 62,136, 21,108,187, 44,133,167,156,250, 91, 43,139,132,
-217, 34,195, 41, 47, 12,201,186, 81,171,145,167, 59,167,235,244,251,139,155,111,191, 89, 88,166,123, 76, 81,135, 97,153,122,140,
- 64,199,195,143,235,101,124,112,121,253,188,152,164, 97, 2,179,106,140,138,240, 98, 45,106,250, 49, 61,228, 86,140,230, 13,165,
-218,210,123, 15,172, 75,177,217, 44, 30, 78,183,203,219,255,242, 80, 18,250, 22,196, 52, 26,194,147, 10, 94, 43, 51,220,234,242,
-123, 4,220, 31,172,246, 47,174,197,180,232, 76,182,127, 11, 93,150,186,138, 83, 77,140, 51,120, 88,130, 49, 8,215, 55,206,139,
- 70, 66,141, 54, 83, 9,183,104, 67, 43,146,130,167,180, 50,155,174,201,195, 66,170,197,249, 94, 56,155,189, 94, 84,191, 49,241,
-151,187,185, 89, 93,142, 55, 67,132, 72, 59,159,171, 98,190, 55, 63,255,188, 60, 63,123,180,222, 60,254,254,151,167, 63,190,124,
-230,154,126, 15,150,100, 16, 38,118, 84,255,186, 4, 93, 16,248, 87,173,101, 22, 20, 13,182,198,181,147,225,201, 21,169,118, 20,
- 34, 69, 93,244,188,162, 52,146,120, 86, 2, 30, 85,142,128,225, 42,176,255, 5, 32,233,218, 90,219, 56,162,240,206,204,206,204,
- 94, 36, 75,178, 90,219,169,141,237, 80, 2, 46, 9, 4,210, 62, 5, 74,251, 82,242,115,250,123,250,119,250, 84, 40,133,150,166,
- 16,218,138,134, 24, 91, 68,177,236,232,178,151,185,247,124, 27, 61, 46,210,174,102,103,230,156,243,157, 57,231,251, 80,171, 76,
-225, 24,218,246, 57,223, 73,139,149, 24, 82,247, 49,210,189,187, 29, 27, 88,132,189, 55, 22,116, 78,145,124,114,199, 65, 88, 68,
- 23,105,170, 8, 62, 49,195,233,199, 78,119,197,110,172,202, 44,229,132,129, 37,223,140, 92,102, 56, 79, 21,106,144, 55,118,103,
-123,185, 70, 30, 56,113,191,209, 97,234,200,208,150,202, 21,228, 29, 20,248, 94,132, 75, 80,242,160, 71,246,178, 1,141, 32,244,
- 25, 2, 20,223, 61,189, 67,233,135,234, 50,164,179,179,208,149, 53,253,239, 56,112,160, 98, 35, 85,228,250,245,192, 56,219,129,
- 10, 82,162, 56, 15, 60,168,130,174,208, 8,106,244,121,131,232,144,118,155, 82,136, 56, 9,222, 16, 2, 41,123, 46,164,130, 14,
-159, 14,182,111,110,220, 54,136,226,112,117,242,146, 95,254, 80,124,183,170, 23,127,141,223,254,214, 92,255, 26,205,214, 92,239,
- 93,247, 49, 11, 5,180, 51, 53,131,105,163,145, 41, 2, 37, 90,139,172, 71, 19, 49,164, 61, 17,135,161, 42, 34,171, 9,152,145,
-153,148, 52,197,156, 28, 68,172,152,231,108, 20, 56, 65,167,141,149,249, 28,124,161,214, 72, 83, 64,151,160, 12, 20, 87,102,165,
-206, 93, 14,242,116,104, 17, 57,231,113,110,193, 71, 61,171, 89,154,156, 30,217,179,171,244,248,233,118,246,100, 51, 58,217,154,
-192,214, 43,197,222,105, 89, 21,132, 10, 19,141, 97, 32,179, 83,168, 69,235, 57, 50, 3,185,133, 4, 1, 77,139, 75,113,199,107,
-189,141,133, 88,167,142, 92, 32,173, 0,166,130, 18, 50,156,231,163, 43,249,208,136,141,146, 99, 30,125,236, 68, 56,144, 56, 19,
- 68,139,176,129,143,232,200,136, 7, 63, 1, 51,123,238,243, 65,230, 15, 73,121, 48,145,180, 9, 85, 31,209, 69,111, 66,171,154,
- 93, 50,169, 47, 26,110,218,208, 5, 73,118,159,158,132, 12,113,203,102, 93,234,154,104, 6,253, 43, 1, 82, 66,240, 26,144,161,
- 67, 89,186, 24, 8, 14,134,250,153,220, 37, 59,201,202,121,229,243,203,215,111,150, 77,204,167,233, 17,255, 64, 80, 50,107, 14,
- 1,227,200,196,186,214,131, 4, 6, 28,164, 50, 38,123, 64, 91,209,145,161,108,147,214, 49,151,180,201,122, 90, 36, 18,185,187,
- 84,230,166, 32,208,150,151, 93,182, 31,184,247, 65, 23, 97,201,129, 66, 3,196,164, 52,214, 2, 9, 77, 10, 43, 43,238,188,106,
- 51, 73, 64,144,239,178,112, 96,131, 85,135, 52, 33, 90, 44,110,214,111, 46,167,207, 62, 63,102,178, 5,135,148,130,222, 91, 72,
-150,214,148, 80,199,224, 27, 9,251,129, 35,118, 80, 52, 39,239, 10,105,168, 79,167,198, 45, 52,230, 57,184, 97,144,108,255,164,
- 42,135, 80,184,224, 4,204, 96,190, 53,156, 91,114,129,190, 25, 37,144,141, 31, 72, 36,224, 24, 42, 36,229,161, 32, 82,210,139,
-182,253,134,153,223,245,232,238,219,171,203,171,249,197,226,237,103,127, 46,205,251,187,135, 40,214,150, 2,170,189,219, 59, 94,
-132,163,111,206,212,247, 95,155,147,115, 50,106,139,108,123,211,252,178,220, 47,173,217, 24,176,140,116,142,160, 54,159, 15, 2,
- 40, 1, 71,251, 30, 62,140,161,115, 4,125,102, 89,214, 70,178,102, 91,224, 19, 10,243,224, 24, 51,131,218, 93,200, 80,208,255,
-133, 24, 11,133,181, 25, 45, 24, 77,240,154, 19,238,214, 21, 58,236,108, 49,203, 15, 78,207,204,197,171,149, 58,235,236,146, 3,
- 26,214, 94, 52, 66, 90, 47, 64,194, 72,129, 29,130,120, 49,115,170, 23, 61, 1,124, 90, 22,116,107,137,137,100,130,246,191,173,
-146, 37, 87,142,222,153,106, 47, 65,117,139,188,184, 9, 61, 10,170,138,212,146, 53, 54,145, 98,146, 6,165,173,112, 16,185,188,
-243, 55,153,122,126,172,228,173,104, 80, 88, 41, 83, 65,227,203,237,232,100,242,199,173, 93,154,119,245,148, 19, 58,115, 29, 91,
-129,250, 58,211,193, 87,154,181, 37, 3, 52,222, 58,149, 19, 38, 38, 96,109, 30,246,221,139, 39,179, 47,142,238,255,254,183, 87,
- 93,137,118, 45, 20,255,147,225,202,242, 34,176, 73, 40, 68,125,116,254,213,189,126,124,219, 22,235,176,152, 31, 98,233,120, 85,
- 83,116, 86,119,198,143,235, 56,144, 1,131,150, 70, 57,136,110,198,135,196,198, 81,241, 54, 53,149,107, 24,217,199,144,111, 41,
-250,213,233, 80,140,158, 62,186,253,178,248,217, 53,255,109,222, 55, 13, 84, 75, 11,156,107,167,134, 77,147,179, 40,145,222,116,
-247, 15, 43, 50, 85,183,147,139,127,126,124,245,242,197,233,217, 79,175,251,213,135,235,217, 60, 74,180, 52,203,196, 91, 6,128,
-129,146,188,228,233,145,157, 33, 7, 31,184,214, 40,164, 22,163, 81, 40, 66,187, 66, 7, 80,198, 29,193,115,102,233, 67, 38,118,
- 74,251,249,127, 1, 72,186,182,221, 56,138, 40,216,247,153,217,217, 89,123,125,141, 34, 8,146, 19,146, 88,130, 7,120, 10, 72,
- 60,240,153,252, 7,127,129, 16, 8, 17, 33, 5, 97,129, 99,236,128, 47,235,221,217,185,118, 79, 55, 85,203,235, 62,204,206,229,
-244, 57,167,186, 79, 85, 25,213, 83,210,101, 26, 58,141, 94,187, 71, 19, 76, 48, 78, 45, 59, 69,177,114, 55,162,147, 66, 88, 34,
-235, 4, 77,213,131,184,222,118, 8, 1,141,244,182,226, 9,204,195, 48,238, 5, 84,224,206,212,109, 59,186,118,176,104, 72,237,
- 61,165,161, 99,187, 18,139,224,245, 20,247,173, 10, 93, 48,114,140, 77,190,205,212,214,200, 37, 96,159,161,109,101, 78, 87,244,
-222,233, 76, 84, 21,176,226,212, 71,242,152, 29,238,110, 52,153, 50, 59,253,186, 52, 20,162, 48, 0,222,148, 81,163, 78, 6,113,
-185, 20, 89, 86,164,109,235, 12,194,138,204, 78, 58, 67,113,243,135, 35,181, 59,179, 20, 64,119,170,150,210, 61, 43,225,107, 20,
-129,202,171,124,152, 18, 79, 6,204, 68,163,207, 12, 0, 95,116,222, 91, 74,167,218,238,214,168, 60,186,217,234,236, 11,241,226,
- 77, 62, 60,236, 79,117,253,219,187,229,191, 63,235,237,125,119,241, 75, 79, 89, 84,132,238, 34, 54,205,196, 33,169,128,242,100,
-235,144,102, 69,105,177, 52, 12,190, 31,121, 22, 78, 69,224,143, 73, 12,198, 22, 69,232,103,162, 88, 79,227, 76,155,143, 92,114,
- 22,216, 74,207, 98,238,100,176,181,108, 45,121,157,104,195,187,109,238, 76,202, 22, 11, 93,103,149,204, 14, 94,136,147, 79,253,
-226,164, 62,122,117, 57, 63,213,168,162,253,170,108, 46,144, 28, 74,250, 63,149, 58,153,136,235,139, 66, 24, 32,138, 14,203, 24,
- 16, 89,247, 36,229,175,181,205, 41, 23,237,236,106,154,201, 6, 72,118,205,181,237, 99,149,109, 67, 67,137,192, 77,247,228,217,
-190,177, 87, 67, 98,218,166, 44,143,229,190,128,172, 4, 82, 77,152, 34,170, 69,178,154,242,182, 0, 17,185,198,139, 70, 16,135,
-222, 27, 50,201, 84, 2,246, 10, 67,172, 7,154,239, 20, 94,174, 73,175, 28, 58,128,138, 4,136,224,209, 48,142, 0,249,168,171,
-234,142,244, 37,220, 25,197,164,149,244,104,202,226,200, 74,109, 34,147, 11, 82, 31,133, 10, 45, 71, 95, 0,207,150, 65,172, 78,
-170,225,207,235,188, 32, 47,151,126,159, 89,160, 61, 47,234,145,178, 74, 54,213,158,238, 40,212, 28,219,224, 57, 85,101,157,198,
- 67, 34,103, 2, 11,123, 87,116,131,137,126,203,249, 25,153, 13,162,108, 51,145,111, 55,168,223,193,234,109,246, 64,101, 80,252,
-181,141,222,235, 61,211, 69,159,167,126, 52,182, 45,166,101, 35,199, 94,207, 75,212, 56,239, 20, 94, 33,214, 79, 4, 16,191,216,
-148,159,157, 43, 84,173, 88,204, 83,166, 40,228,137,170, 49,251,152, 2, 54,169,213,220, 73,247,220,144,241, 57, 21,173,200,215,
-178,220,165,137,129,218, 21, 26,189, 23,167, 87,249, 11,109,163,201,229,154, 40,246, 33, 38, 14,255, 11,189,179,152, 18,228,185,
-203,255,121, 95,114,202,118,147,242,158, 78,129, 28,133,197,245,247,162,104,186,199,107,155,173,142, 15,239,143, 15, 62, 57,107,
-170,119,239, 15,175,174,231,119,119,166, 80,253,211,167,251, 95,158, 95,157,190,186, 19,233, 31,113,121,121,247, 97, 43,234,174,
-125,223, 11,222,130, 65,185,150,251, 40,133,150,115,165, 19, 5,170,128,193,228,134, 71, 31,220,236, 76, 98, 61, 26,160, 45,252,
-223, 40,201, 84,162, 52,209,206,222,171,209, 42,239,137, 83, 17,195,142,122,133, 52, 28,138,115, 58,246,145,100,109,130, 45,204,
-225, 97,229,143,190,189, 41,207,250, 15,127,196,140,226,184, 7,177,169,101, 55,116,248,214,222, 50,169,232, 73, 54,121, 0,100,
- 87,200, 47,104,190,100,103, 67, 15,100, 45, 44, 77,190,210, 35,137,128,174, 66,255,181,161,198, 56,143,116,200,144, 71,134,167,
-217,129,229, 22,120, 12,247, 93,164,215,105,162,183,189,153,154,219,235,191,215, 95, 63, 57,118, 55,155,122,188,145, 3,226,166,
- 31, 76, 38, 85,249,242,237, 79, 94,182,141, 91,204,185,143,108,211, 49,190, 9, 71,114, 57,107, 10,120,139,196,224,104, 24,150,
- 81,241, 31, 63, 13,135, 95,189, 62, 50,205,175, 35, 2,236,212, 33, 92, 17,161, 99,165,212, 50,164, 71,183,151,242,226,228,217,
-205,236,249, 95, 77,163,202, 30,201, 13,217, 81, 91, 44,111,128, 90,244,190, 29, 96,123,158, 87, 60, 78,113,145, 4, 28,210, 44,
- 11, 52,119, 64, 55,121,155,211,255, 5,160,212, 59,157, 94,190,182,237,217,236,135, 42,188, 93,221, 94,141, 44,114,149,118,189,
- 68,138,147, 29, 18,210,244,168,118,222,246, 46, 41,158,199,180,177,242, 23,125,185,252,254,155,211, 55,214,125,254,221,143,231,
-183,195,239, 7,102,164,187, 64, 4,218, 75,222,140,128,186, 0,166, 94, 84, 74,143,179,201,175,106,244,150,120,169,163,121, 96,
-115, 57,150, 3, 61, 59,144,238,154, 12, 64,100,136,232, 60,194,127, 2,176,116, 45, 61,114,212, 96,208,207,126, 79,207,238, 44,
- 44, 36,104,115,131, 68,202,141,135,196, 29,142,240,187,248, 81,156,185,113, 64, 28,144, 34,180, 17, 73,128,176,203, 62,123,250,
-101,187,221,166,170,197,125,164,177,218,118,185,202,159,191, 42,163, 52,142,207, 12, 31,216,207,155, 77, 58,126,215,185,144,198,
-213,249,110, 28, 64,142,151,132,163,116,225,163,107, 76,207,216,219, 7,223,239,243, 86,251,101,212, 88, 25, 67,194, 54, 60,234,
- 96,102, 94,127,211,127,205,117, 75, 5,178,155,133,149,165, 13,118,209,230,179,192,161, 86, 27,190,197, 15,102,189, 45, 99,169,
-141,122, 24,229,206,140,131,169, 22,224,164,211, 80,142,188,148,209,224,160,180,231, 95,188, 46, 30, 1, 37, 69,252, 80,100, 61,
-219,155, 3, 52, 58,241, 43,145,150,128,122,177, 0, 56,174,123,191,214, 89,118,116, 18,250, 18,235,211,156,249, 9,252, 87,130,
- 48,106,124,105, 73,255, 2,149, 49,117, 15, 18, 24,202,207,217, 45,155,194, 50, 75, 0,235,217,242,225,190, 46,102,134, 34,105,
- 76, 73, 31, 24, 24,214,167,241,159, 5, 90, 95, 29,250,170, 29,191,252,166, 48,223,237,213, 32,254,122, 3, 42,115,232,126,181,
-239,222,186,171, 87, 82,122, 19,124, 8,192,204,114, 6,111, 52, 15,251, 37,176, 26,154,180,203, 26,147, 87,162,187,119, 6,136,
- 98,170, 67,164,195,235, 20, 44, 88,110, 90, 99, 3,214, 70,167,240, 90,236,151,234,169,108, 58,123, 90,151,126, 74,250,160, 63,
-254,106, 57,185, 24,204,233, 44,243,235,234,228, 81,167,108,184,149,247,175,155, 37,219, 1,154,242, 84,251, 18,167,128, 91,200,
- 99,243, 29,107, 54,236,169, 73, 0, 73, 96, 86, 70,135,108, 15, 66, 30, 37,100,138,140,174, 80,204, 63,182,133,163, 17,216, 53,
-214,105, 62, 96,183, 2,251,253,167, 77, 33,143,151, 30,236, 25,195,101, 65,220, 24, 72,215,173,237,153,121,186,108, 54, 85,140,
-194, 51, 12,118, 19, 35, 67,106, 5,139, 5,150,241,195, 6,228,126,197, 58,199,153,239, 40,254,248,178, 66,200,100,140, 25, 58,
- 38,241,237, 50, 38, 44,152, 41,110,151,246, 33, 12,153,152,217,234,238,198,173,178,170,196, 76, 51, 52, 66,140,220,174, 36,116,
- 33, 30, 91,241,252,196,222, 9,128, 72, 86, 87,208,223, 74,230, 52,188, 86, 56, 29,176,131,245, 56, 2,226, 3,211,179, 0,152,
- 77, 38,170,106,197,217, 40, 45,152, 74,142,209,176, 49,229, 0, 77,101,161,214,135,193, 22, 5,150,178,199,255, 86, 19,184,197,
-138,207,132,239, 95,224,200, 96,231,161, 52,224, 32, 96,162,160, 11,138, 14,114, 53,237,168, 28,214, 72,222, 97,167, 85,166, 29,
- 43, 45,123,170,212,121,115,217, 47,141,165,194, 1,125,146,229, 30,210, 67, 71,136, 52,246,213, 71,134,104,180,130, 54, 67, 11,
- 43,165,116,146, 93,232,178,130,225,219, 97,187,189,226,125, 7,115, 54, 98, 16,140,125,197,216,221, 22,182, 78, 35,121,204, 88,
-250, 63,138, 98, 11,127, 3, 89,149,172, 58,131,154, 64,137,208,111,156, 21, 90, 43,193,166,195, 77,124,184,182,250,207,243,182,
- 62,127,249, 76,188,172,183,123,219,183, 28,158,255, 45,189,127, 56,190,194, 71,158,166,137, 69, 98, 3, 2, 76,111, 5,108,252,
-132,233,116,245,162,122, 97,238,173,200,249,160,103,221, 97,221,197,225,200, 97, 26,203,234, 20,100,136,152, 5, 59,254, 34, 59,
- 60, 90,197, 92,120,145,209,132, 83,101,169,214,114,198, 8, 11, 62, 97,168, 75, 19, 27, 85,159,198,179,143, 14,250,226,219,191,
- 15,159, 31,253,191,133, 81,160, 73, 30,200,222, 51,205, 40, 54,160, 7, 65,205, 89,116,222, 85,171, 27,217,113,203, 2,110,132,
-212, 55,166, 6, 71, 96,252, 95,131,205,247,120, 7,168, 3, 61, 98,101,121, 2, 87,234,124, 25,129, 5,150, 49,179,194,221,196,
- 45,121,181,182, 57,142, 88,103, 3,142,159,252,182,179, 55,119,225,147,243,100,130,138, 70,215, 54,221,165,212,212,106, 81,213,
-239,143,239, 14,205, 76,208, 59,225, 76, 49, 78,178, 83,186,225,173, 20,219,199,189,104,118, 37, 32,172, 43,215,116,191, 28,210,
-179, 23, 47,196,213, 31,239,227, 12,198, 66,187, 13, 32,252, 50, 39, 59,198, 42, 83,103, 79,158,190,169,190,184,188, 7, 67,185,
- 41,178,218, 73,108, 87,133, 19, 11, 83, 2, 49, 23,193, 94,233,148,199,187, 98, 72, 70,111,213, 62, 2,142,228, 74,119,180,201,
-100, 45, 95,187,174,144,229, 79,158,183,119,159, 85, 63,174,241,231,227,149, 8,139,149,115,110,250,217,180, 46,208,239,158, 77,
- 33,140, 66,195, 38, 42, 36, 13,212,161,173,244,188, 76,185,115,169,253,224,151,175, 47, 94, 87,254,251, 31,126, 58,235,167,203,
-221, 89, 59,168, 44,235, 98, 73,239, 29,166, 70,165,142, 47,132,129,165,153, 14,123,171, 70,159,235, 97, 96, 54, 50,251,189,189,
- 99,112, 48,232,249, 92,128,167,172,241, 63, 1, 72,186,146, 29, 57,138, 32,154,149,107,173,221, 61,214,216, 8,164, 97, 59,250,
- 0, 7,144,124,240,137, 31,225,167,248, 33,254,128,229,138, 4,146,133, 25,218,179,244, 76,109,153,149,171, 95,148,213,151, 62,
-116,171, 74, 81,153, 17, 47, 42, 95,188, 39, 87,122, 33,153,182,224, 84, 83, 77, 83,214,115,142,184, 16,146,129, 67, 15, 30,213,
- 57,215,106, 25, 3,160, 31, 48,185, 34,164, 50,212,206,250, 74, 88,235,251, 42,121,177,230,165, 81, 11,147,195, 26,212,236,114,
- 29,201,217,226,132,170,162, 16,190,206,208, 57, 45, 47,154,157,218, 28,240, 93,183,125,193, 90, 99,107,101,129,159, 55,161, 94,
- 96, 47, 39,219, 52,134,175, 74,110,106, 50,188, 51,128,232, 64, 63,105, 87, 69,229,252,131, 45,163, 22, 39,173,148, 79,181, 99,
-149, 33, 47, 74, 65, 30,175,136, 80, 61, 11, 26, 8,173,170,176,214, 36, 89,126,220,125,191, 52,217, 96, 75, 45,182,209, 34,209,
- 16,126,148,251,208,201,162,145, 37, 25, 29, 19, 6,175, 58,229, 36,127,158, 34,151, 73, 18, 77,147,196,103,128,240, 67,142,232,
-249,201,207,212,132, 17, 72, 72, 61,221, 70,174, 23,109, 82,221, 70,217,223, 29,126,146, 95,247, 42,166, 35,153, 4, 88,177,221,
-213, 88, 62,151,123,149,221, 80,252, 67,228, 47,203,227, 92, 37, 52, 28,209, 62,180, 64,124,169, 13,173, 69,133,223,108,205,154,
-196, 17,193,114, 64, 42, 95,204, 24,100,183, 93,221, 40,236, 15,217, 93,114,179,136,134,235,176,185,192,248, 45,170,106,154,238,
-143,168,239, 68,115, 55, 36,218,187,235,238, 99,223, 73, 20, 66,114, 25, 70,128,148,146,100, 91,198, 86,100, 56, 50,148,104,229,
- 56,151,227, 62,216,224,119,123, 64,189, 10,119,228,243,145, 57,164,104,133, 54,169,105,158, 63,136,181, 59,124,117, 82,110,113,
- 30,173,114, 34,242, 79,110,120,140, 58,121,207, 77,204,138, 12,174, 4, 35, 76, 33, 62,217,112, 83, 83,135,155,140,164, 45,147,
- 36,176, 59, 62, 72,231,200, 68,250,158,228,103,216, 99, 88,239, 72,191,128, 93,184, 78,101, 7, 48,108,115, 21,186, 48,181,178,
-128, 14, 2,171,219,211,144,214, 62,175,207, 84,100, 36,101,205, 72,109,237,211, 65,107, 27,217,103, 95,222,252, 25,211,249, 28,
- 62,127,161,105, 56,196, 0,121, 12, 7,177,161,159, 47,162,198,174, 66,229, 53, 60,144, 11, 99,224, 83,174, 55, 46,209, 50, 22,
-192, 59, 69, 47, 77,144,100, 35,169,103, 50, 58, 7,108, 9, 84, 97,241,152, 58, 94,174,170,198,166, 3,143,104,184, 72,107,209,
-187, 69,138,231, 94, 16,175, 60,160,174, 71,116, 1,122,144,149,144, 8, 2,217, 85, 51,148,186,228, 55, 1, 32,196,218, 53, 85,
- 43, 32, 48, 19, 61, 63,221, 80,151,193, 30, 18, 29,146,202,157,190, 79,252,230, 42, 45,132,220,113,225, 68,108, 99,116,205,204,
- 4,114,143, 89, 59, 78, 10,118, 49,118,168,108, 68, 86,203, 68,159,163,173,135, 86,134,136,153,136,123, 32, 35, 33, 98,137,146,
- 50,253,152,104, 96, 8,127, 65, 54, 32,150, 26, 17, 43,121, 77, 60, 59,100, 67, 22,163, 91, 66,120, 44,249,127,154, 51, 62,100,
-102,199, 52,137,120,158,253,106,195, 35,141, 26,226, 57, 20,165,170, 1,187,185, 18, 91,136, 46, 7, 23, 3,126,131,135,216,230,
-130, 59, 93, 75,153,201,175,182, 88, 94, 22,142,196,128, 98, 21, 16,174, 64, 19,103, 45, 77,221,226,246,164,178,164,188,198, 91,
-164, 70,238, 16,116, 64,169, 54, 99,121, 1,208,152, 90,244,199, 94,125,243,253,221,205,235,177,250,143,109,239,115,101,100,170,
-189,232,116,155,125,157, 13, 32, 93,122, 26,105, 96, 34, 0,158, 47,202,200,109,217,188,235, 25, 71,219, 79, 2,160,135,146,230,
-167,168,121, 55,209,112,139,110,230,253,237,149,100,147, 9, 72,248,157,184,191, 68,221,153,107, 31,111,203,218,181, 57,174, 40,
- 22, 81,245, 21,170,161,235, 39,231, 18, 59, 93,233,218,242,186,218, 80,123, 7,220,216,209, 78,236,159,116,247,170, 39,154, 19,
- 57,153,207,108, 61, 21,242, 12,196,198,164,220,140,180, 79, 68,193,156,151,163, 16,115,178,111,223,152, 97,120,127, 30,239,101,
-209,196,149,208, 42,157,179,238, 80, 75,101,251,234,229,248,197,143,231,119,158, 53,127, 69, 92, 62,100, 65, 60,104, 54,187,186,
- 38,238,180,234,246, 86,195,104, 58,214,143,235,181,206, 78,214, 13,113,129,100,172,108, 36, 50, 22,214,173,189,254,118,120,184,
-105,126,117,143,191, 61,123,244, 7, 92,132, 53,198, 39,128, 82,134,142, 8, 24,184,225, 36,176,109,242, 62, 3, 66,167,215,210,
-163,210,165,108, 93, 54,108, 89,124,254,251,221,119,167, 63,126,254,225,205, 47,191, 87,234,242,175,169,119, 37, 90,128,187, 75,
-193,195,192,126, 69,117,177,100,116,124, 24,163,181,193, 30,213,138,192,136, 7,233, 11, 95,186,173,159, 24,105,186, 13, 58,133,
-240, 81, 0,146,174,165, 55,110, 27, 12,138, 47,145,210, 90,107,215, 27,167,175,156, 10, 52,237,161, 64,145, 99,127, 66,127,108,
-127, 72, 46,189, 7,104, 79,109,128, 24,177,157,125,104, 41,138,207,206,168,103, 47, 12, 73,252, 56,156, 33,249,205,232,178, 90,
-225, 46,166, 95,186,197,172, 71, 12, 86,173,253, 37,197,109, 71,227,232,230,156, 86,123, 58, 59,227,158,185, 45, 24,252,156,205,
- 82,231,238, 25,120,193, 4,218, 28, 99,150, 47, 0,154,154, 83,156, 29,232, 43,214, 95,161, 78,244, 65, 13, 69,183,163,100,123,
- 9,240,233,156,176,156, 26,185, 46,137,105, 77, 16,121,221,189, 93,217,213,111,197, 37, 64,187,103,140,233, 4, 89,122, 9, 12,
- 92, 22,142,205, 52, 75,110, 35,163, 6,202,100,138,144,125,104,224, 22, 12, 61,112,144, 88,169, 11, 99, 25, 6,201,144, 84, 76,
-235,178,133,214,196, 26, 20, 83,146,105,250, 91,139,222, 59,117, 2, 11, 84,153, 33,174,140, 72,154,176, 86,247,108,144,136, 0,
-252, 40,167, 84, 30, 68,251, 18,229,176,105, 87,159,229, 94,116, 76,115, 25, 81,104, 76, 60,159,169,242,232,142, 90,164, 63, 78,
-202,211,212,180, 30, 74,255, 57,117,241, 44,129,200,152,175,119,110,220, 47,195,143, 29,143,204, 12,192,135,217,236,118, 13,229,
-213,165,181, 7, 59,227,159,246,188,213, 75,203,246,169,207,151, 66,160, 99,131, 3,128, 99,181, 65, 60, 2, 73,109, 90, 84, 62,
-141,121, 14, 86,105, 40, 11,131,103,103, 90, 11, 6,127,172, 37,101, 39,153, 41,103,166,202,160,201, 90,216, 8, 95,248,218,202,
- 66,247,232,154,140,105,195,202,172,144,174,239, 37,180, 75,162,193,241,152,193, 58,125, 13,144, 94,158,217, 64,131,105,246,170,
- 63, 93,211,201,221,127,253,250,238,239,232, 25, 85,139, 33, 57,107,230, 12,246, 70, 40,192,139, 43,148, 1, 64, 48,197,189,226,
- 10,250,236,202,118,171,155,153, 23, 45, 87,193,228,187, 44,143,204,125,206, 96, 31, 79, 60, 40,165, 37, 93,211, 1,159, 60, 39,
- 82, 95,213,204, 12, 36,206, 53,102,154,242, 9,125, 41,244, 73,111,212, 82,220, 2,130, 74,128,102,198,114,101, 52, 27, 8,204,
-216,245,120,215,111,238,159,206,145, 97,101,234,142,198, 89,139,137, 78,148, 29, 72,100, 24,118,147, 87,224, 47, 1, 72,149, 49,
-128, 86, 14,167,100,120, 18, 40,188,149, 65, 58,252, 38,165, 10,129,211, 67,255,142, 40, 41, 45,174,213,179, 25,178, 55,207, 98,
-136, 32,203, 97,164,107, 92, 39,119,121,200,253,120,170,144,172,180, 88, 25,186, 27,207,244,189, 28,233, 99,119,232,114,232, 59,
-134,243,197,233,112,176,188,220,179, 56, 49, 60,136, 97, 79,235, 72,113,164,197, 91, 55, 48, 99,152,187,228,220,127, 97,196, 48,
-189,127, 55, 59,127,124, 12, 26,220,208,207,129, 13, 66,153, 38,254,249, 66,138, 88,213,198, 43, 91,209, 62,210, 57, 31, 84, 12,
-229, 12, 82,235, 80,193,255,219,215, 73,110,223, 84,138, 5, 69, 79,124, 87,161,141,241, 53,153,239, 51,225,173,233,245,220,190,
-146,140, 17, 8,241,227,179,120, 14,233,180,250,151,185, 94,148,233,245,150,149,215,120, 39, 0,210,176, 19, 49,144,197, 52,171,
- 45, 32,237,156,130, 19, 50, 43,144,105, 20,242,237,220,240,215,228,104,200, 44, 50,131,188, 49,117,124, 87,104,159,220,109,141,
-235,219,137, 55, 88, 23,219,221, 70,250,223,128,152,118,131, 43,253,114,248,214,189,250,245,151,127,190,127,247, 41, 92, 65, 28,
-245,178, 55,210,126, 97, 52, 45, 86,195, 35, 86,187, 25,162, 99, 69,105,162, 82,118, 2, 32, 48, 45, 89,250,243,174,241,176,164,
-143, 46, 26,157,240, 24,235, 26, 50,139,195,161,246,162, 90, 32,186, 22, 97,171,167,154,235, 20, 0, 78,174, 88,109,234,106,114,
- 93,121,125,188,211,231,194,178,135,162, 57, 50,149,194,150, 1,184,207, 6, 88, 98,193,109,191,134, 29,232,173,187, 21, 87,209,
- 3,171,129,212,124,193, 30, 69, 40, 42,251,133,133,166, 11,123,153,247, 67,157,215,203,252,230,167,159, 95,135,199, 63,253,194,
- 56,245,133,151, 53,155,113, 77,140,217,222, 30,166,239,222,125, 56,155,151,246,113, 84, 55, 3, 40,224, 34,231, 67,131,110,212,
-204, 63,218,164,114, 94,156,217,155,130,185, 37,119,236, 86,189, 46, 60,110,101,155,199,172,111, 36, 24,176,119, 63,168, 15,111,
-220,251,240,229, 95,255,153, 57,240,214, 49,161,189,211, 22,234,173, 69, 47,120, 11,112, 11,143,187,144, 32,104, 38,220,239,121,
-133,174,163,187,114,150, 91,127, 64,188,246,237,253,239,111,197,227,250,219, 31,127, 29,119,123,223,158,100,194,236,141,197,220,
-120,201, 19,157, 57, 37, 9, 41, 15,189,167, 45, 10,113, 74,154,197,201,148, 24,212,203,130,129,192, 99, 41,229,151,255, 4,224,
-232, 90,118, 43,169,161,160, 31,237,182,251,145,155,155, 64,162, 65,179, 64, 32, 13,179, 99,135,196, 15,176,225,127,249, 5, 54,
- 72,236, 88, 17, 52, 18, 25,129, 6,134, 73,210,125,187,219,143,182, 77, 85,111,163,228,230,218, 62,143, 58,246, 57, 85, 28,137,
-138,211, 70, 50, 67, 2,216, 37, 96,227,224,160, 49,233, 28,188,221, 54, 24,244,167, 54, 90,156,137,241,117, 5,156,154, 61,176,
- 66,215,192, 92,121,121, 71, 37,159, 37, 81,119,224,210,192,164,107,217,248, 62, 45, 77, 62, 68, 54, 66, 66,126, 71,170, 64,161,
- 13,143,155,144,119,244, 25,213, 24, 39, 15, 18, 57,159, 74, 87,102,182,123,236,131, 9, 65,217,205,152,222, 56,118,175,235, 84,
- 44, 53,235,241, 89,148,153,128,181, 57,111,199, 38,238, 35,239,117,251,200,209,105,132,250,237,184, 70, 96,223, 98,107, 80,119,
- 34,140, 33,154,182,136,122, 9, 33,139, 92,198, 45,101, 97,202,156, 11, 21,103, 85, 2,222,182, 89,244,166,214,147, 72, 64,247,
- 66,103, 67,241,108, 10, 57, 38, 82, 28, 34,234,116, 40,147, 23, 71, 86, 59, 56, 27,153,158,148,236,135,155, 13,208, 65, 18,137,
- 3, 1,226,156,116,114,199, 77,226, 98, 16,171,183,245,184,112, 41, 36, 86, 86,219, 36, 6, 36,166, 88,254,130,153, 63, 1,158,
-169, 38,145,135,134, 53,253,162,129,128,247, 43,149,218,168,146,219,117,104, 7,242,248, 70,128, 13,132,207,214, 32, 36, 15,216,
- 43, 4,122, 42,221,145,220, 8,177,211,248, 35,170,143,114,192,142,153,150, 76, 93, 62, 73,118,249, 53,110,166,222, 51,121, 45,
- 41, 24, 75,153,233, 4, 35, 92,121, 3,131,159, 32,206,162, 28,191,139,250, 99,143,188, 2, 20, 83,133,219,116,155,234, 85,123,
-190, 86,127,188,148,185,202, 19, 22,143, 2, 17,117, 5, 53, 44, 98,174,168,118, 2,187, 15, 40,217,128,202,162, 61, 8,186,146,
- 1,254,209, 10, 78,218, 9,159,243,156,212,214,214,188, 3,155,162, 78, 17, 83, 92,177,135,131,221, 63,194,238,138,178, 53, 81,
- 4,186,102,146, 22,148,106,108,244,123,127,244,124,147,207,145, 79,200,135,166, 71,101, 87, 33,162,193,226, 56,157,115, 26,132,
-124,213,125,248,125,184, 61,245,200,202, 90,103,178,217,213,146, 91,215, 41,135,211, 27,105,125,108,243,200,142,234,161,250, 30,
-121, 30, 43,226,109,227, 77,163,245,124, 53,153,137, 76,134, 30,201,184, 94,138, 76, 81,132, 81,156,117,190, 94,129,248,100,128,
-235, 99,163, 45,252,106,124,214,177,179,140,210, 43, 28,147,106,238,124,180,162,251,158, 74, 14,217, 14,123,130,209,223,218,175,
-238, 23, 33, 81, 25,223,230,254, 76, 98,134, 76, 14, 76,124,233,204,145, 37,138,111, 34, 6, 22, 24, 29,169, 20,201,177, 64,250,
- 2, 62, 22, 81,195,148, 93,238,254, 96, 35,165, 98, 13,162, 76,174,158, 13,255,216,174, 12,100, 67, 82, 27, 79, 65, 9, 28, 62,
- 98, 16,210, 67,207,123, 2, 73, 17,194,194,169,176, 72, 98,150,194, 30,127, 10,157, 17,187,194, 98,172, 80, 52,183, 36,167,203,
-190,236,233,233,120,166, 31,240,103,146,234,210,240,222,103,124,187,189, 82,159,150, 68, 12, 28, 71,231, 68,205,206, 95, 86,204,
- 61,148,206, 72,121,158,213,234,149, 36,191, 20,161, 66,154, 1,249,210, 21, 76, 75,209,178, 43, 67, 78, 25,216, 46, 11, 63,107,
-250, 46, 37, 89,211,216,219,187,218,221,234,155,111, 94,255,251,197,143,239,197,117,147, 30,107,127,242,103, 85,210,122, 64,159,
- 16,122, 18, 26,102,239,168,116,132, 74, 43,250,139,168,254, 41,214, 22,134,218,151, 69,214, 48, 45,168,152,176, 70,178, 15, 97,
- 41,157, 3,170,195,138,237, 33, 93,174, 3,131,112,212,174, 38, 27,184,209, 72, 57, 17,117,248, 90, 12,109,102, 7,234, 64,178,
- 32, 78, 27,111,200,218,143, 60, 8, 28, 68,111,214,207,248, 31, 41, 0,211, 2, 9,218, 57, 95,172,190, 96,143, 93,236, 56, 9,
-215,240, 53, 49, 20, 61,200,147, 23,207,107,253,254,219, 47,191,123,243,242,254,215,199, 28, 53,146, 7,204, 72,253,195,153,248,
- 70,156,206,183,111, 31, 62,220,253,246,247, 67,123, 66, 93,110,204, 57,250,172,156,237,201,227,141,104, 99, 44, 91,206,249,184,
-135, 58,151,130,101,185,157, 16,255,234, 30, 72, 94,177,227, 20, 59,177,125,246,117,255,231,231,195,207,235,203, 35, 78, 73,176,
-241, 80, 31,220, 50,161,108, 27,206,137, 4, 90,250,120, 73,230, 16,245,126, 12,205, 30,106, 90,182,203,134, 83, 40,124, 61, 27,
- 91,209,142,115,220,220,127,191,252,240,234,205, 79,239,238, 31, 62,189,123,173,235,136,108,105, 38, 24, 14,106,250,105, 59, 59,
- 34, 48,191,193,201, 27,147,214,224,144, 8,179,147,151, 66, 42,181, 39,223,216,152, 41,254, 41,255, 23,128,163,107,217,145,164,
- 6,130,126,148, 93,174,234,154,174,105,208, 14,106,193,238, 17,238, 28,184,112, 70,226, 67,249, 12,190, 2, 14,136, 19, 2,105,
-197, 72,244,238,116, 87,215,195, 46,191,136,104,105, 46, 45,205, 76,181, 92,118,102, 68, 58, 51,162, 49,136,227,138,141, 48,136,
-101, 9,223,115,245,146,162,128, 33, 79,126,246,153, 98, 77, 96,250,251, 53, 42,246,203, 4,192,183,165,165, 39,174, 40,119, 67,
-147, 41, 67, 11, 90,128, 55,223,232, 66, 25,127, 77, 35, 72, 60,168, 94,140, 58,218,124,170,123,223,202, 56, 31,138, 85, 33,187,
- 78, 42, 60, 98,143,170, 52, 7,142,201,205,222, 34,119, 22,135,120,107, 39, 66, 39, 28, 95,228, 8,165,121,196, 57, 10,207,243,
- 2,218,200, 25,186,192,254, 59, 16,163,156,251, 60,168, 22,145, 57, 31, 3,208, 66, 40,129,118, 86,166,225,148,249, 80, 53,232,
- 1,152, 16,142,151, 10, 88, 42, 42, 81,178,163,137, 30,213,182, 69,226,125,180,221, 0,164, 82,177, 41, 40, 11,192,237,189,118,
- 58,106,225,108, 81, 51,123,106, 20,203,247, 44, 60, 26,129,205,173, 35,109,214,228,221,200, 81,101, 59, 55, 43,109,131,145,119,
-101, 67, 85, 54,236, 42,113,199, 95, 43,209, 71, 97, 82,106,154,122, 76,230, 6,212, 67,173,171,202,201, 99, 68,196,151, 58, 52,
-182,220,104, 74,188, 63,250,136, 40, 5, 9,136, 81,217, 89, 77,167, 40,128,203,216,108, 7,144, 89,201, 30, 54, 83,159, 1,134,
-131, 91,231, 50, 74,219,183,244,208, 76,138, 46,162, 96, 25, 77, 3,210, 76, 39,151,117,203,181,167,218,156, 6,145, 2, 23,147,
-212,134, 71,130,147,102,109,189,152,193, 12,144,148, 34,222, 6, 72,132,243,183,135,197,188, 28,235,119,231, 44,166,109, 93,106,
-122,210,156,214,193, 75, 52,188, 57,103,205, 39, 40,208,141,234,114, 6,202,149, 93,186, 33,108, 97, 65,168,163,146, 34, 51, 88,
-218,192, 14,176,145,118, 68,109, 49,217,130, 92,131, 99,117,105,205, 36,243,206,161,199,213, 19,238, 27,157, 0,218, 62,227, 52,
- 48,176,110, 53,136,251, 14,164, 78,193, 72,215,177,242, 78,231, 91, 54,165,136, 33,147,179, 62,157, 6,243,238,240,223,239, 77,
-113,247,157,174,150, 3,187, 94, 52, 34, 85, 49, 25, 81, 96,210,230, 9, 63,206,106,186, 80,172,181,246, 32,254,126,163,130,131,
- 0, 11, 50, 8,235, 42,175,166,186, 67,203, 98,106, 44,227,184,152, 88, 2, 45,213,229,163, 98,180, 81, 89, 7,232,119,144,102,
- 41, 22, 11,140, 72, 58,100, 6,213, 98,251, 81, 71,175, 90, 23,105, 3, 88,116,154,205,203,123,253,242, 33, 9,125,202,195, 87,
-156, 63, 16,153,122,151,108,116,121,204,159,114,136, 55, 98, 55, 2, 27,106,182, 78, 83,206,150,154,236, 8,172, 65,178, 18, 79,
- 9, 39,100, 74,128,131, 84, 54,240,239,200,145,171,125, 97, 3,252,198, 45, 74, 99, 17,234,216, 33,118, 99, 51, 38, 49, 7, 90,
- 7, 24, 86, 99,132,227,144,101,150, 26,187,135,134,241,197, 83,173,136, 61,218, 53, 93,103, 32,225,114, 79, 73,238, 13, 78,185,
-231,147, 20, 16, 47, 78, 38, 61,163,168,126, 17,175, 50,142, 81, 14, 58,223,178,122, 19,220,107, 86,155, 75, 19, 76, 80,171, 54,
- 85, 49,205,247, 25,196, 34, 68,185, 1, 89,108,188,147, 0,127,192,209,230, 93,123,149,186,227,133, 47,157,185, 52,109,138,144,
- 63, 99,167,114,183,159, 79, 95,124, 62,255,252, 17,148, 42,254,171,246, 20,194, 39,219,119,248, 5,169, 7, 64,144,253,222,105,
- 69,179,184,100,227, 2,152,163, 39,144,112,171, 26,128, 51,243,233,146, 41,116,210,123, 47,104,194,141,221,129, 64, 22, 53,130,
-190,239,250, 0,196,150,217, 94,186,230,149, 93, 69,181,147,193,208,218, 50,173,230, 32, 31,222,243,217,199,189,125, 54,215,161,
-190,238, 65, 52,163, 56,145,170, 20, 28,122, 22, 95, 13,171,171,224, 3,138,159,118,167, 1, 0, 91,207,254,185,157, 13, 95, 69,
- 57,176, 84,138,251, 58, 55,239,111,230,135,239,223,137,244,199,117,185,119, 29,222,138, 18, 83, 68,196,241,199,248,252,225,252,
- 38,191,253,251,242,143,248,242,181,181, 3,255, 17, 24,143, 22, 7, 64,102,231, 58, 55,115, 70, 80,114,232,121, 78,224,142, 67,
- 75, 33, 41,202,222,179,246, 14,128,176,129,116,143,231,254,227,201,254,186, 47,127, 93, 95,145,230, 43,211, 51,239, 41,167,172,
- 12, 85,227,170,125,120, 13,167,218, 24, 89, 89, 27,109, 5, 91, 4, 16,205, 22, 44,207,181,231, 64,208, 51, 16, 90,166,158,195,
-210, 77,194,127,253,205,111, 63,189,255,241,151, 63,251,163,185,129,244,168,109,145,174,107, 56, 52,217, 70,230, 24,100,111,213,
-183,217,119,193,227,101,128,202,223,150,128, 69,127,178, 22, 64, 46,214, 78,152,255, 5, 32,233,234,121,228,182,161, 32, 41,146,
-146,168,175, 59,251, 12, 24,112, 42,219,141,221, 6,105,211,165,140,127,178, 11,255, 2, 23,169, 2, 24,118,151, 34,198,101,189,
-186,149,196,111,102, 70,238,118,113, 88,232,196,143,247,102,200,247,102,244,109, 3,179, 63,144,162, 54,127,163, 78, 38,239,138,
- 60,203,182,100,194, 24, 93, 14,135,221, 24,247,112,176,116, 30, 17, 67, 2,131,206, 19,136, 14,109,122,250, 77,136,169, 58,100,
- 87,160,240, 86,239, 94,246, 51,214,222,105,213,184,172, 30,168,253,146,109,103, 49,142, 77,231,133, 28,213, 45,184, 61,155, 81,
-197, 86, 81,145,172, 17,207,226, 78, 46,122,217,243, 36,103,137,180, 64,209,157, 32,116,223,230, 82,132,230,169,159, 64, 42,194,
- 60,169,126,196,223,156,233, 52,123,129, 4,173,129,126,210,218, 78, 12,154,229,166,153,142, 26,206,164, 10,120,142, 69,167,146,
-241,244, 94, 63, 84,154,232, 87,208,140, 38,167, 93,212,243,242, 15, 31,193, 94,202, 93,245, 92, 79,166, 2,168,211,118, 88, 28,
-162, 53, 20, 59,207,108, 70,140,173,211, 4, 61,207, 98,170,128, 50, 9, 80,160, 4,208, 84, 37,244, 33,131, 48,206, 98,167, 70,
-118, 5, 97, 13, 51,118,210,120, 29, 91,147,202,203,231,145, 42, 30,170, 92, 1, 63, 3,164, 83, 55,233, 1, 65, 52,214, 2, 66,
- 46,235,201, 71, 0,239, 94,240,224,244,144,187, 56,237, 15,170, 6, 49, 1, 24, 11,136,183,199,210,245,251, 0, 4,175, 53, 73,
- 30,141,144, 48,175,245,185,165, 10,145, 71,252, 56,109,195, 14, 96,159,150,215,216,162, 57, 37,119, 11,255, 71,196, 78, 64, 83,
- 22,170,182,121,227,231, 67, 99,103,215, 43,115, 92, 16,147, 69, 0,109,126,200, 9,251, 89, 36, 79,201,213,100,139, 12, 18,175,
-142, 0, 71,185, 63,218, 18,138,115, 33, 22,201, 11, 57,226, 80,170,173,129,176,241,242, 6,192,219,213, 3,145, 2,193, 43,201,
- 39,154, 49, 61, 13,148,191, 7, 94, 66,194, 4,181, 2, 50,200, 52,105, 54, 32,213, 60, 80, 40,167,239, 97,161,147, 20,207, 28,
- 41,133,193,186,146,216, 17, 19,119,163,232,151,249,123,110, 30, 47,110,233, 31, 64,167,217, 27,121, 92,151,234,124, 55,107, 67,
-236,110,168,219, 30, 66,140,218, 22, 53, 53,225, 63, 67,149,139,206,105, 73,233, 30,176, 53,235,251,222,101,213, 71, 7,198,205,
- 60,198, 41, 14,209,227,245, 91,175,227, 56, 36, 96,238, 70,155,112, 4,254, 20, 64, 65,107, 43,215, 72,153, 24,246, 48,108,121,
- 54, 44, 32, 65, 42,156,134,251,223,127,237,197,253,234, 86,192,234, 71,106, 15,225,149,207, 30,229, 83,206, 0, 1,119,100, 60,
-213, 99,205, 0,101, 78,128,240,202,148,127, 30,190,139,179, 98,139,250, 51, 66,242,252, 45, 10,139, 88,200,147,151,170, 0, 69,
-132, 46,187,244,149,233, 1, 35,172,140, 26, 12, 7, 36,208, 68, 19,243, 9,152,194,235,164,200, 78, 92,214, 82, 98, 76,241,220,
-149, 45, 32,200,149, 0,180, 72, 11,188, 91,146,125,193,218,154, 56,164,101, 43, 49,148, 22,123, 38,203, 13, 84, 6, 52,122,173,
-236, 5,188,177, 74, 6,252,177,174,200, 78, 20,235, 93,183,104, 50,152, 95, 13,224,234,142, 69,180, 88, 50,120,178,162,112,158,
- 0,190,196,244, 89, 35,211, 44,177,161,244,162, 82,171, 86,173,108,218, 95,244,246,238,249, 47,251,235, 15, 95,134,247,217,127,
-211, 72, 5, 29,168, 19, 38, 59,241,110,187,234,160, 38,160, 58,231, 87, 95,135, 0, 36,191, 29,160, 27, 13, 70,188,164, 27, 53,
-139,150,131,119, 14,222,128,130,184, 26,189,175,179,214,123,216, 1,163, 50,213,142, 61, 23,182,186, 43, 83,234, 89,219,241,208,
-134, 45,181,251,200,222, 11,164, 4,107, 20,109, 12, 53, 37, 29,176,139,196, 89, 32, 17,232, 42, 70, 8,216,100, 63,212,220, 73,
- 36, 34,160, 76,246,128,131,138,107,196,220,164, 17, 37,218,142, 26,118,146, 42, 8, 70, 92,196,155, 87,239,254,248,173, 94,191,
-252,203, 87, 71,242, 45, 28,180, 0,190,114, 63,155,225,237,231,191,253, 85,254, 51,166, 69,201,197, 88,140,185,166, 70, 42,118,
- 26,118, 31,189,181,226,225,239, 76,167, 70,189, 84,124,213,158,253, 62,137,210, 7,146,253,153,203,203,250,253,161,126, 58,126,
-124,197,162, 88, 99, 26,157, 0,205, 64, 34, 37, 72,228,213,103,139,100, 76,111,142,100,145,205, 72,236, 16,105, 41,236, 82,154,
-171,236, 58, 12,131,102,220, 98, 21,106,193,202,164,165,208,166,197,227, 95,127,190,122,255,241,219, 75, 23,158,234, 20,172,152,
-171,106, 66,142,200,149,116,163,144, 3,126, 94, 18, 98,177, 53, 14,155,250, 10,100,184, 99, 32, 28, 72, 2,136, 32,155,199,255,
- 23,128,163,107,217,141,227, 6,130, 36,135, 28,114, 30,218, 21,100, 25, 22, 18,228, 16, 32, 9, 16,223, 12,228,230,187,115,204,
- 79,251, 11,114, 74, 14, 1,108,196, 65, 16,172, 32,107,181, 59,124, 13,201, 73,213, 92,116, 16,102, 23, 18,134,221, 93,213,236,
-174, 66,194,153,179,143,244,102,202,142, 83,228, 57,230, 24, 67, 0, 73,154, 11,130,197, 0, 59, 47,225,170,172, 21,190, 46,117,
-225,204,145, 92,218, 66,171, 1,162,233,182,160,248,160,216,172, 55, 13, 57,162,173, 47,248,133, 41,215,118,123,192,241, 22,188,
-254,107, 21,120,188,222, 4, 61,209,109, 4, 60,127,234,198, 25, 20, 53,198, 52,116,129,250,104, 40,139,224,176, 25,128, 86,154,
-100, 39, 0, 37, 84,178,161,118,118,139, 39, 49,142,171,158,100, 62,201,120, 99,122, 10,165,117, 32,203,229, 14, 97,166, 13, 39,
- 99, 23, 13, 50,136,175,200,149,146,209,185,234,209, 80,187,191, 56, 93, 71, 42, 4,169,181, 4,203,123, 72,119,161,239, 35,142,
-101,200,180,187,160,215, 55,185, 7,231, 51,216,207, 94,235, 34,245, 52,118,218,243,202, 17,161, 78, 98,216, 35, 73,244, 69,101,
-212,172, 73, 1, 88,138,231,160, 16,220,244,191, 14,213, 82,157, 24,208, 9,101, 69,134,176,175, 16,232,166, 61, 21,186, 80, 95,
-192, 28,162,212,189,227,221, 63,200, 93,234,233,212,101,214,216, 81,201,133, 93,165,213, 1,133, 24, 86, 46,124,145,106, 7,135,
- 83,104, 19,254, 27, 11,212, 71,147, 84, 36,160, 1, 37, 38,202,199,185,187,107, 94,211,113,180,123, 42,188, 18, 29,172,184,106,
- 9, 28, 70, 67, 84, 54, 78,118, 42,136,180,236, 68,116, 34,123,211,163,102,117,165,229,172,123, 51,248,249,226,189,116,156, 76,
- 91,144,243, 95,109, 62,159,190, 36,122, 58, 73, 46,107,207,134,215, 32, 20, 43, 45,136,106, 65,193, 80,110,174,226,253, 75,229,
-216, 43,160,125, 42,199, 49,203, 94, 81,210, 87, 10,242,212, 11, 80, 95,108, 1,169,132,105,139, 29, 52,161,194,190,245,216,128,
-254, 87, 60,136, 3,195, 65,250,178,171,205,208,123, 22, 57,125,239,201,208, 93, 86,137, 67, 15,138,177,153, 65,140, 70, 3, 32,
-249,179, 45,207,167,254, 62,169,134, 18,126, 61,206, 93,202, 15,120,114,214,249,204, 25,167,204, 63, 79,206, 18, 63, 61, 39,222,
- 10, 96,192, 21,152,105,200, 40,198, 40,201, 42,232, 39, 54, 69,192,197,106,149, 47,143,155,118,198, 90, 21, 70,145,207,114, 11,
- 40,179,220,236, 88,175, 90, 57, 29,114,233,246,129,240, 7, 84, 79, 29,151, 77,198, 99,115,212,113, 56,100, 47,126,254,233,240,
-203, 59, 46,194, 80,149, 10,133,156,237,114, 45,246, 75,109,130,119,160, 23, 14,125,208,208, 68,110,248,232,184,209,206,145, 22,
-151,224,132,156,245,167,255, 9, 21,232, 42, 23, 77, 81,223, 54,121,209,220,216,166, 6,152,100,177, 12,128,117,192,150,148,222,
- 86,210,107,218,202, 27,133,195,133,196,183,181, 50,129, 2,130, 83, 75, 87,115,162,158,154, 65,184, 37,196,118, 0,174, 7, 23,
- 23,244,245, 96, 86, 85,224, 61,106,229, 40,117, 35,221,214,180,146, 68,174, 68, 26,161, 34, 16,208, 56,205, 29, 3,151, 85,216,
- 34,226, 56,141, 96,235,149, 32,153, 7, 22,200, 18,184, 14, 71, 68, 39,141,112,171, 13, 16,102, 50,212,137,164,110,138,146, 3,
-138, 33,178,123, 61,140,250,245, 15, 71,249,227,135, 63,222,188, 45,203, 51,226, 37,211, 65,210, 4,192,184, 52, 57,187,108, 49,
- 3, 36,159,213, 85,173, 67,223,165,163, 69,248, 5,155,241,250,240,156,173, 32, 35,235, 99,181, 55, 8, 24,160, 71,159,112,162,
-106,119,201,115, 42, 79,150,151,235, 28,101,206,120,207,125,148, 49, 7, 75,145,222,177, 82,230, 14,143, 35, 96, 54, 35,113,188,
-108, 67,149,173, 20,248,199, 97,178,182,112,171, 69,221,174,116,194,104,219,122, 68, 41,234,251, 86,158, 93,155, 18,216,230, 20,
-251, 2,198, 52,104, 39, 13,144, 10, 0, 89,205, 50,190,136,225,183, 95,191, 21,195, 95,255,125,125, 18,206, 34, 0,215,207, 34,
- 33,230,238,187,105,250,254,159,203,195,151,211,231,249,187,238,118,192,121,202,117,228, 66,156, 67,206,162,110, 94, 22,235,216,
- 29, 38, 78, 34, 32,255,168,115, 68, 22,160,241,198,193, 81,197, 62, 73,245,102,184,134, 91,243,177,248, 63,217, 93,247,101, 40,
-136,190,101,211, 0,238,244, 32,167, 42, 13,216,229,196,251,236,253,230, 95,114,149, 98,164,227, 6,151, 46, 87, 97, 81,151, 93,
-163,142, 53, 50, 23,225, 98, 15,252,106,138,122,201,203, 55,119,159,222,222,191,255,253,239,127, 71,160,129,201,111,203,130,130,
- 74,105,249,232, 37,251,168,120,183,243, 44, 82,104,158,114,148,179,223,192,101,187, 13,228,108,218,128, 81,214,255, 5,224,232,
- 90,118,236, 38,162, 96, 63,237,182,125, 95, 19,164,137, 80,144, 88, 0, 18, 36,236,178,207, 6,164,124, 52, 75,254, 0,177, 64,
-138,148,101, 20, 17,148,153,123,175,237,118,191,169,242,254,142, 61,238,199, 57, 85,221,231, 84, 97, 49, 93, 37,146,105, 14,165,
- 55,245, 9,232,145,151,251, 52,120, 70,176, 48,108, 97,246, 55,138,190,133,216,120,169,192,102, 57,225,107, 96,249, 86,209,155,
- 12, 41, 98,194, 21,130,207,215, 91, 29, 1, 91, 36, 57,145,205,210,164, 70,175, 75,164,192,138,132, 46,181, 31, 0,116,125,237,
-204, 9,104, 50,141,108,114,167,250,108,230,205, 94,178,132,242,125, 63, 76,224, 75,248,166, 50,184,187, 92,213, 20,123,159,121,
-228, 18, 23, 10,253, 96,237,179,171, 86,101,141,209, 16,164,251, 60, 54, 1,112, 66,160, 38, 34, 52,251,177, 39,205, 73, 88,151,
- 81, 68,179,170,140, 88, 30, 24,105,196,218, 82,168,237, 64,167,200,220,243, 90, 76, 38,196, 59,228,149,196, 13,169, 52, 18, 12,
- 34, 31,157,154, 16,219, 58, 71,165, 53, 67,215, 42,246,205,218, 98,102,218,185,177,146,173,141,216, 82,136,188,162,123,224,187,
-176,115, 43,160, 71,166, 40,171, 69,188,126,194, 7,226,103,106,207,219, 46,226, 75, 44,128, 44, 9,213,148, 11, 6,246,110,172,
-165, 61, 22,187,101, 10, 81,247, 70, 81, 55,118, 23,211, 7,174, 34, 9,117,122, 55,154,163, 67, 59, 53,219, 64,127, 74,152, 22,
- 36,135, 35,229,140,123, 26,158, 18,153,130, 14, 33,150,139,218,215,142,170,160, 42,130,149, 94,140,160,206, 53,203, 27, 43,242,
-116,166, 99, 56,198, 28, 33,124, 99,213,198,193,198,217,203,203,185,123, 24,218,108, 0, 3,181,216,243, 8,254,163,238, 89,213,
- 73,208,128,143,183,109, 88, 26, 61,155, 42,121, 33,131, 8, 45, 41, 17,192, 83,135,134, 79,145, 43,130,200,222,233, 86,133,142,
- 91, 89, 21,135,127,197,238,140, 96, 98,117, 70, 58, 80,180, 4,241,138,250, 71,188,215, 46, 75, 36,204, 12,187, 48, 50,208,106,
-192,214, 80,251,121, 89,143, 41, 7, 83,147,216,141,211,143,245,223,199,239,242,197,240,234,106,210,248,162, 8,192,164,124,223,
-109,119,233,140,101, 31,127, 91,157, 53, 64, 59,200,216, 92, 54,120, 45,219,107,177, 13, 10,187,238, 86, 44,162, 19,198,141, 78,
-125, 72, 53,100, 27,161, 1,204, 20,177, 82,179,213,178, 55, 15,127, 62,184,206,131,196, 29,229,183,117,251,146,237,118,145,151,
- 89,131, 6, 32,194,229,114, 60, 92, 94,189,254,185,255,253, 29,198,226, 99,122,158,119,174,161,118,101,176,200,130, 23,145,118,
-233, 24,107, 72,109, 48, 77, 44,152,161,189,184, 76,148, 36, 64,202,102, 65, 68,195,104, 83,106,170, 82,219,134,142,244,171,162,
-191, 93, 48,244, 2,225, 97, 26, 81,155, 88, 88, 58, 96,128,112,159,115, 66,212, 30, 27, 96, 81,219,165,208,104,248,173,185,139,
-120, 54,147,117,158, 1,171, 0,220,120, 74,144, 15,216,123, 64, 50, 44, 0,107, 43,150, 48,127, 23,233,197, 13,128,174, 65, 78,
-203,202,117, 67, 87,141, 47,108,113,163,239, 84,174,242,191,128, 17,175, 52, 25,192, 36,110, 84,205,186,233,184,180,124, 23, 94,
-155, 3, 41,114, 38,238,237,240, 96,107,198, 36, 31, 58, 58,131,246,120,114,147,166, 60,188,252, 38,254,240,254,159,211,155,251,
-237, 51, 88,174, 46,190, 31, 20,175,132, 24,143,176, 18, 14,213,205,120,213,216, 5, 57, 10, 49,219,101,117,197, 96,250,188, 6,
-223,190,202,110, 3, 7, 49,224,217,165,216,181,110,170,166,102, 65,238, 40, 77,235,173, 93,251,181,101,128,149,171, 82,238, 38,
-131,117,156,245,182,223, 54,146, 45,179,138, 63,241, 40,129,190, 93,114, 2, 98, 27,188,160, 36,241,110,105, 51,179,144, 52, 95,
-203,227,171,120, 57, 95,114,188,107,231,170,221,128,171, 45,136, 57,213,111,141,166, 95, 29, 38, 67, 45,207,249,251, 23, 63,253,
-246,230,176,124,252, 84, 86,170,164,176,183,206,209, 49,237,124,124, 57, 78,191,124,254,240,100,199,175, 54, 30, 48,182, 64, 71,
-157,146,161,163, 89, 11, 30, 57,119,225,204, 18, 86,202, 30, 18, 64, 28, 1,229, 3,221,227,221,184,153, 5,235,117,208,250, 81,
-255, 81,226,223, 0,192,186, 30,252,156,213,245, 94, 85,160,183, 41, 48, 82,204,238,212,132, 67,164,194,254,180,121, 0,110,163,
-242, 2,107,168, 26,237,245, 12, 79,254,114, 2, 42, 3,210,226,205, 80, 32,129,239, 9,133, 18,182,217,252,215,175,199,183,127,
- 74,121,170,224, 68,186, 78,231, 45, 32,245,241,124, 78,165,187,160,191, 76, 13, 83, 12,250, 72,222,199,238, 94,149, 93, 26, 17,
-219,188,206,126,251, 95, 0,142,174,101, 71,114, 34, 8,214,203,174,242,184,221,211, 59, 52,218,101, 15,112,128, 19,119, 14,252,
- 2,240, 7, 72,252, 52, 8,137, 3, 7, 4, 2, 33,118,118,198,238,182,235, 93, 38,194,183,150, 90,234, 25, 87,149, 51, 35, 50,
-179, 34, 76,180,229, 86,114,187,143, 21, 33, 72,233, 96,198, 37, 35,250,228,244,156,239, 37,103,183,237, 55,170,186,111, 75, 65,
- 80,138, 81, 6,166,160,142, 58,233, 8,120,178,217,106, 88, 88,194,211,100, 48, 22, 4,107,172, 3, 61, 9, 63, 82,245, 91,126,
- 34,165, 1, 23, 67,250,205,130, 3,229,189,122, 4,192,112, 32, 35,106, 52,171,212, 15,231,146,212,234,216,255,236,107, 28, 54,
-205,122,182,178, 88, 3, 38, 16,196,179, 7,137, 48, 72,254,136,231, 64,166,202, 85, 89,199,123,172, 55,173, 65,215,246, 67,143,
- 19, 89,101, 37, 9,162, 51,160,109,148, 31,155,180, 88,162,216, 88,253, 56, 94, 58, 10, 63, 97, 55,204,198,137, 33,196, 76,156,
- 82, 1,246, 18,148,158,152, 78,145,197,155, 45,210, 2,196, 84, 28,119, 13,114,242,136,179, 43, 50,254, 69,144, 63, 57,226, 43,
- 73,149, 30, 42, 89, 74, 26, 63, 70,149,177,191,120,149,140, 24,216, 3,171,156, 27,244,141, 90, 92, 78, 17,215,145,210,171,179,
-108, 14, 88,203, 30,115,167, 8, 7,185, 82, 50,193,240,157,235, 40,151, 99, 15, 27, 26,150, 19,168,132, 6,102,195, 26,177,223,
-176, 44, 28,159,225,172, 17,165,212, 64,133, 83, 48,143,136, 89, 42, 4, 26, 0, 61,245, 26, 32,197, 97,153,148, 71,116,195,114,
- 99,223, 1,242,202, 36,226, 96, 98, 72,192, 72,125,236, 90, 54,105, 64, 10,165,240,181, 2, 47, 47,174, 34, 85, 63,169,203,233,
-249,111,228,126,122,191,170,226, 71, 35,199,254, 68,175,180,144, 88,203,164,153, 96, 23,145,129,143, 91,195, 61,111,195, 0,164,
-114, 0,181,210, 17,155,234,176, 54,203, 15,136, 86,209, 11, 29,144,242,168, 18, 78, 19, 32,154, 20, 48, 79, 34,210, 20,172,224,
-170, 56, 93,229,154, 8,138,143,121,102,143, 86,112, 28, 66, 83,184,133, 53,160,158,130, 46,213, 58,247, 38, 60,190,161,246,243,
- 69,174,153,182, 46,187, 5,128, 29,168, 32,154,199, 86,239,250,157,206,243,249,133,130,167,136,209,234,184,193,161,192, 52, 69,
-113, 61, 77,112, 1,122, 0,123, 7,249, 16,235,172, 57, 64, 57,149, 9,188, 83,234,172,156, 30, 7, 41,182,132, 36, 12,172,217,
-125,168,235, 21, 15, 9,136, 76, 92,151,241,131, 35,107,252, 28, 97,168,246,242,244,217,119,223, 95, 63,255,226, 63,209,254, 12,
-243,124,216,199, 31,147, 48,164, 30, 12, 49, 28,240,164,220,154, 36,182,167, 73,107, 71,199, 25,222, 27, 56,172,167,216,146, 78,
- 37,229, 29,188, 19, 47,111,160,217, 17, 63,116, 22, 20, 58,169, 67, 99,180,178, 23,192, 50, 80,218,169, 28,226,149,167, 37, 35,
- 72, 63, 69,205,117,226,121,225, 28, 34,199, 82, 37,199,116,107,166, 34, 97,144, 2,120,141, 61, 40,188,136,244,235,225,240,107,
-175, 56, 90,180, 1, 29,231,230, 77,219,168, 36, 19, 65,239,103, 10, 17,176,130,129,179,146,115,102,227, 94,197,176,171,149,186,
-159,122,214,203, 98, 58,159, 13,242,153, 82, 15,172, 33,151,128,179, 56, 90,214,196, 45,224, 7, 96,128,222, 79,226, 46,246,241,
-186,190,191,190, 53,223,254,240,235,244,205,203,125,177,157,160,115, 24,176, 8,208, 26,146, 85, 4,207,244,123,162,213,252,238,
-179,187,157, 86,115,107,197,179,210,157,121,255, 48,203,110,165,157,240,230, 28, 0,206,234,135,154,177, 89,117, 4, 42,193,102,
-173, 23,113,222, 18,120,217,242, 58,169, 83, 10,165, 15, 17,155,144, 12, 91, 97,173,205,141,175, 40, 62, 88,202,159,111,178,167,
-102,193,142,252,108, 57, 24, 4,184,110,179,127,245,214,234,208, 62,118,250,217, 33, 85,232,120,110, 83,170,110,218, 85, 92,245,
-165, 87,131, 17,115,214,202, 81,227,189,203,238,199,159,190, 52, 15,191,255,245,239,179, 4,157,191,177, 35,219,128, 2,122,227,
-158,222,253,225,199,127,210,111,211,104,217,252,238, 17,187,177,202,194,139, 54,142, 64,136, 87, 94,146,101,117, 44, 58,221, 69,
- 58,241, 68,252,213, 6, 36,230, 95,138,197,154,124,245,182,253,178, 47, 63,191,110,247,161,157, 34,133,212,177,237,160,114,154,
-247, 25, 24,150,120, 25,156,247,192, 17,150, 56, 48,131,164,126,140,162, 86,113, 72, 18,177,189, 2, 22,185, 71, 86, 59, 40, 65,
-218, 56,227, 80, 29,165,138, 20,184, 93,221,190,190,156,173, 67, 90,152, 41, 56,224, 0,252,147,223,232,206, 89,204,136, 28,249,
-169, 10, 13,209, 56, 47, 44, 27, 24, 43,222, 47,247, 25, 59,212,165,221,247, 85,254, 47, 0, 71, 87,146, 27,199, 17, 4,107,239,
-101,122,200, 25,145,146, 37, 64,128, 32, 3, 62,217,208,197, 63,208, 69, 79,214, 19,244, 4, 65,130, 12,216, 39,219,176,196,109,
-122,169,189, 28,209, 0,193, 3,135, 32,186,139,153, 89,145, 85,145, 17,200,179,108,183, 46, 33, 6,190, 7,192,159,118,161,208,
-232,140, 48, 28,242, 1,159, 4,181, 16,186,162,158, 1,252,237,205, 53,250, 58, 95, 66, 70,141, 68, 16,154, 33, 83,154,109,241,
-141, 60,189,161,214,202,131, 15,236,216, 93,159,220,126,110,157, 41,153,165, 38,141,111, 8, 6,153, 85,105,188,186,192,215,228,
-176,192,120,108,128, 83,128,107,141, 7, 95,141, 26, 40,229,169,238, 16,106,141,103,223,128, 43,168,148, 38, 33, 57, 92,197, 6,
- 2, 36, 92,144, 54, 22,117, 48,236,170, 37,156, 35,211, 5,141,102, 44,198,106,202, 64,160,131, 11,187,160, 1, 45, 55,120, 4,
-158, 9, 68, 21,138,186,184,138,229, 33, 1,229, 26, 64,141, 12,248,139,218,202, 28,229,113, 48,182,142,161,242,112,195, 81, 46,
-218,211, 8,175,238, 74,197, 26, 48, 77, 95, 87,250,242, 80,198, 2,176, 67,179, 59,160, 36, 24, 22, 13,157, 44,194,177,207,109,
-176, 8, 24,119, 0,234, 47,163, 5, 32,204,102, 13,115,211,151, 38, 93,179, 28,159, 48,212,122, 61, 73,193,146,183,213, 17,144,
-207,231,105,178,243,136, 4,141, 40,117,188,114, 97,165,145,114, 46, 27,126, 7,121,222,204,200,190,193, 46, 88,243, 31, 60,193,
- 62,159,196, 35,231, 84,164, 24,196, 18,139,203, 58,112,214, 66,208,214, 22, 5, 54,147,113,136,252, 17,244,139,236, 69, 93,242,
-178,101,192,234,177, 59, 94,176,186, 36, 68,181, 23,135,235,214,125,122, 58,145, 86,208,221,107,235, 91, 29,232,162,130,103,236,
-144, 79, 36,125,176, 94, 3, 94,241,150,127, 13,164,231, 33,172, 35,213,184,128,236,105,151,179,201,109, 69,237,240, 65,208,215,
- 5, 81, 25,239,241,159, 37,225, 20,189, 75, 34,131, 82, 29,170,246,169, 62, 40,186,185,143, 60,202, 39,107,142, 22,150,149,178,
- 51,180,168,115,180, 53, 23, 60, 67,173,167, 9, 5,174, 60, 44,197, 92,115, 36, 7,117, 64,175,156, 35,234,164, 6,158, 40, 53,
- 44, 70,122, 63, 12, 1,208, 29, 64,241, 41, 24,250,210,144,200, 2, 84,117, 1,232,192,207, 13,237, 73,132,184,198, 38, 16, 73,
- 68, 80, 50, 13,201,144,225, 95, 57,102, 63,225,201,143,182,146,188,133,140,230, 69, 92, 26,186,201,227,239,175,255, 9,125,107,
-127,122,255,254,252,238,183,236,142,255,136,167,187,205,223, 83,208,130,175,102,246,153,210,186,223,169,134,157, 51, 58,137,221,
-170,157,197, 61, 43, 50, 93,209,251,197, 40,132,229,229,170,140,251, 16, 53,246,113,201,209,154,188, 91,209,231, 96, 72,161,214,
- 21,251,122,206,120,204, 66,129,117,228, 80,115,104,246,139, 2,156, 92, 83,203, 55, 28,229, 65,187,155, 88, 20,176, 76,141,244,
-207,226,149, 68, 37, 18, 49,144,165,167, 66, 79, 79, 76,106, 14,169,128,194,189,166, 48,235,180, 26,118,222, 0, 80,228,120,102,
-244, 1, 41,208, 38, 22, 27,204,134,237,146,238,197, 77,123, 0,254, 60,239,166,190,137,146,228,101, 35, 97,178,158, 41,183, 44,
-149, 29,107,215,174, 6, 83,142,244,179,225,202,158,247,246,232,213,115,243,246,195,231,233,247, 63,131, 63,217,216, 3, 75, 7,
-192, 26,141, 14, 31,219,187,225,209, 0,234,198,170,132, 69,246, 9, 52,198,232,140, 11, 58,192,176, 33,198,177,122,249,162,230,
-120, 52,104,120,117, 91, 12, 90,182, 17, 81,113, 88, 51,144,128,239,138,143,213,166, 57,138, 88,131,238,169,234,125,133, 52,190,
- 32,217, 37,101, 70,250, 84,121,155,137,162, 82, 99,149,211, 24, 51,189,233,221,116,123, 37,196,223,164,179, 0,133,144,180,210,
-183,237,210,247,233,245,225,230,143,127,117,121, 89,232,189, 68,189,239,232, 26,157,122,159,145,199, 40,158, 30,211,207,175,127,
-121,247,107,153,191,124,165,196, 16, 58,114,116, 40,138, 87,186,207, 94, 78,189,123,243,215,215, 37,139,251,160,187,147,125,222,
- 33,224,176,213, 81,130,252,168,141, 88, 19,202, 59,135,240,177,232, 5,224,245,160, 34, 0, 95,155,147, 61,147,249, 22,222,190,
-200,223, 38,251,241,110,221, 92, 58, 10,192, 54,108,248,105, 67,195,103,118,219, 54, 69,197,115,196,166,236,195,174,134,205,105,
-184,146, 58, 35,123, 45, 35,243, 73,161,208,120,236, 5, 90,142,149, 10,130,137, 34,173,237,200,170, 68,180, 55,160,144,232,241,
-128,119,199,142, 30,234, 52, 12,143, 78,153,157, 3,142,170, 13, 56,139,102, 14, 17,238,111,240,222,232,138, 57,196, 15, 60,229,
-104,158,165,111, 17, 71,238,127, 1, 56,186,122,222,198,141, 40,184,223, 43,138,164, 37,159,239, 96,228, 3,200, 33, 8, 82,164,
-189, 50,125,128,212, 41,242,199,147, 38, 8,140, 84,119, 9,206,177,100,137,228,146,251,121, 51,170,172,194, 16,168,229,219,121,
- 51,187,239,189, 49,172,126, 75,244,112,198,211, 71,200, 18, 53,200,124, 17,127,209, 77,182,198, 88, 86,176, 92, 91, 23,197,114,
-158,168, 95, 91, 28, 67,199, 78, 86,246,142, 42, 0,225,115,163,215, 16,180,187,196,143,165,143, 25, 94, 49,231,133, 89, 5, 89,
- 93, 86, 31,216, 42, 81, 0, 84,234, 21, 26, 46,251,233,120,126,140, 3, 7,195,148, 9,137,223,170,113,148,216,185,144,216,167,
-205,244,134, 14, 40,205, 2,250,228, 0,121,107, 0,228, 33,215,131,217,109,151,219, 84,187, 44, 6,153,102, 72, 67,199,189, 3,
-190,130,157,214,122, 97, 22,108, 12, 75, 85, 28,111,213,234, 60, 95,135, 40,100,217, 34,107, 7,183, 44,174, 37,124,222,196, 29,
-182,101,111,169, 74,192,155,147,237, 35, 2, 83,131, 71,178,220, 83,139,152,192,160, 4,242, 4,167, 37,208,111, 50, 93, 89, 55,
-220,250,153, 86,211,131, 88, 51, 48,172, 26,119,217, 32, 88,194, 94,220,252,123,120, 63,231,128,197,160,254,236,229,233,147,104,
-175, 2,209,197, 57, 15,126, 71,161, 37, 78,224, 25, 28, 89,146, 26,132, 10,242,129,232,119, 72, 60,142,182, 34, 25,218,154, 54,
- 16,236,215,189,245,182, 23,111,187,137,142,146,109,208,108, 42,109,160,162,216,105,133,198,204,192,114,104, 96,149,104, 7,250,
- 89,222,107,206,194, 91,123, 31,103,132,185,200,118,151,183, 92, 74,200, 32,197,107,217, 53,182,148, 70, 7,190, 12, 38, 33,161,
- 24,163, 11,224,197,234, 94,247, 34,255, 95, 78,214, 88,182,170,103,157, 15, 9,202, 19, 73,136, 39, 93,224,220, 28, 3,239, 8,
-107,200,101,226,214,225, 93, 85, 1, 23,192, 58,201, 37,151,173,174,208,171,117,201, 47,154, 71,167, 75, 2, 37,112,154, 13,152,
-178,180,203,178,113,240,221, 42, 0,243, 44,171,203,252,158,169,242,188,108, 87,216,211,164,110,125,159,185,227,144,174, 35,242,
- 61,200,244, 27, 44, 72, 19,111,199,215, 60,128,244, 53,218,203,138,244,206, 46, 27, 50,120, 91,156,190,239,109,153,221,232,150,
- 50, 36,177,106,123,149,107,218,177,136, 71,181,126,200,136,251,118,199,146,237, 30, 20, 21,137,158,227, 88,243, 53, 45,177, 79,
-188,196, 31, 54, 91,104,138,205,139,172,101,141, 32,173,185,238,189,157, 59, 53, 84,144,253, 60, 46,221,219,119,239,127,253,197,
-191,255, 1,248,248, 28,175, 19,173,182,236, 72,227, 9,137,188, 30, 57, 59,140, 77, 89, 8,179,174,153, 36,121,248,130, 52, 6,
-160,102,127, 0,135,233, 88, 22,189,241,115, 14,156,115, 23,140,198,194, 88, 15, 80, 6, 53,177,171,143, 57,128,155,128, 64, 34,
- 1,180, 89,213,104, 0,244,172,108,128,114,207, 54,241, 18,145, 51, 82,245,169,230, 9, 50, 10,192,165,125, 71,223, 43, 90, 10,
-156, 93,122, 3, 37, 11,149, 6, 57, 91,241,255,219,210, 42,182,239,186,213, 51, 2,149,222,237,160,146, 54,148,176, 70,115,174,
-172,201,104,117,137,114, 46, 44,115, 0, 4,207,136,130,169,176,227, 45, 84, 4, 74,189,208, 65,140, 62,227,145,103,194,193,241,
-144,171,232,218, 33, 24, 30, 58, 58,246, 58, 9,237, 44, 31,235,227,241,193,252,244,243,211,195,135,167,244,111,139, 72,249, 96,
- 0,119, 92, 11,150, 96, 70, 93,189,146,171, 74,123, 86,157, 65,143, 0,136, 93,208,107,200,122,116, 13, 81,146, 1,204,237,230,
-124, 41, 11,176,206,226,169,148,159,217,215, 26, 55,214,220,101,164, 43,164, 5,203,187, 2,144,190, 23,188,160,132,156,193, 54,
-124,150, 15,154, 29, 29, 7, 68,200,252,163,217,184,201,121,192,230,170, 7, 57,210, 30,140, 94,100, 20, 68, 72, 29,160,189, 32,
- 72,223,125,255,213,223,207, 94,185,245,232, 29, 30, 14,223,110,207, 82,142, 74, 3,156, 95,192, 61,190,249,253,183, 31, 69,121,
- 58, 61, 67,232, 27, 2, 63,116,205, 42, 78,157,252,250,254,219, 63, 63, 30, 62,197,167,241,209,131, 59,128, 47,206,190,244,100,
- 47,157,235,228, 22, 64,108,195, 93,207, 11,108, 30,255, 38, 94, 50,209, 73,201,142,118,235, 1, 79, 0,165, 67,254, 99,249,231,
- 63, 22, 38,180,204, 92, 84, 42, 40, 35,226, 1,191,204,115,182, 19, 40, 17, 66,180, 85, 43,183,137,227, 31,101,230, 85,153, 41,
-197, 32, 98,247,224,112,120,127, 26,235, 87, 32,163, 36, 40, 15, 22,165,203,110,182,181,187, 77, 82,110,114,153, 30, 14,219, 94,
-237,233, 34,111,134,138,204,205,169,225, 45,239,188, 41,135,163,185, 76,156, 15,165, 70,232,241,156, 47, 19,128,124,208, 30,122,
- 6,203, 79,158,251, 69, 0,142,174,101, 71,142, 34, 8,118,117,189,250, 53, 51, 59,227,149,133,224,194,205,230, 0, 7, 75,136,
- 27,248,110,127,185,111, 8, 36,100,201, 18, 39,131,196,194,206,184,167, 31,213,245, 36,162,207, 59,210,246,212, 84,102, 70,100,
- 71, 70, 2, 28,139,173, 61, 4,181,157, 66,253,116, 19,101,227,197, 84,103,117, 79,203,237,115, 51,235, 96,102,208,152, 41,117,
-193,254,147,192, 42, 2, 7,173,144,105,188, 54,133,110,240,156,121, 41,117, 99,137,231,217,178,173,194,173,200,198, 9,250, 18,
-214, 38,112,243, 91,211,165,136, 59,175,197,139, 97,243,196,112,136,108,252,239,218, 30,129,108,244, 45,175,218,168,174,238,117,
-115,162,248,130, 77,227, 81, 90, 74,118, 19, 21,147, 50,187,181, 34, 21,136,213,124,202,185,110,197,152,234,115,146,184, 44,121,
-203,157, 4,136, 46,107,165,142,138,194, 66, 32, 33,185,229, 57, 27, 26, 96, 5,156,145,192,161,116, 64, 79,125,238,235,202,186,
- 26,188,113, 3,150, 33, 11, 6,163,214,131, 65, 12,249,109, 98, 98, 19,181, 56, 33,116,105,132, 17,169, 43,229, 98,105,118, 38,
-144, 87,239, 71,126,177,134,226,120,252, 25,121,151,210, 89,112, 17, 46,168, 5,248,143, 10,160,150,162,138, 16, 77,187,191,245,
- 93,169, 3, 67, 84,244,142,130,103, 81,183,243,204,221, 53, 18,135, 29, 43,182, 33, 10, 88,140,200,193,105,156,225,102,227,128,
- 42, 79, 83, 93, 42, 76,135, 38,104,238,118, 53,168, 2, 20,165,160, 76, 37,107,164, 32,153,160, 11, 55,229, 26,141, 2,237, 3,
- 60, 69,101, 13,244,245, 80, 40,195,220, 84, 36,118, 95, 39, 5, 70,236,203, 62,214, 59, 33,175, 0,196,211,126,179,211,114,107,
- 30, 17,112, 95,190,200, 0, 16,192,145, 26,174,106,202, 72,189, 53,181, 90, 58,229, 53,239,243,218, 3, 7, 1,131, 23,157, 98,
-147, 55,148,118, 51, 75,230, 3,230,160,234, 20,219, 18,124,103,203, 2,176,194, 89,206,137, 43, 25,105, 12,137,227,138, 46,115,
-155, 23, 55, 95,167,158,141,114,206, 52,165, 93, 81,196, 61,164,251,164,103,205,237,131, 40,130, 28,146,151, 93,210,143,186,234,
-173,248, 28, 79, 98,210,246, 82, 1, 48,148,231,150,150,240, 72, 29, 11, 56,193,127,235,246,160, 2, 37,189, 5,119, 58, 15,244,
-142,115,128,157,121,157, 42,215,150,115, 89, 22, 16,166,170,215, 62, 48, 65,150, 22, 5, 43,101,235,129, 49, 18,231,201,146, 69,
-208, 4, 13,200,160, 86, 83, 58, 96, 37,174,217, 93, 15,229,171, 31,127,120,249,211, 47,151,243,229,239,188, 92,183,117, 45, 8,
- 49,190,193,164,159, 5,211, 58, 81,144,228,224,147,192,143, 14, 76,222,176, 58,131,229,210,191,144,179, 9,123, 21,207,108,208,
- 69, 48,217, 66,215,205, 53, 0,234, 36,132,110,114,108, 41, 74, 78, 62, 9,205,209, 95, 1,228, 76, 59, 53,160,163,178, 47,162,
- 42,137,239,159, 19,149, 38, 68,215,133,118, 78,212, 1, 35,191, 9,183,228, 67,166,137, 84, 88,138,156, 40, 87,227, 70, 39,176,
-232, 59, 3, 8, 15,162, 16, 0,185,196,224,105,247,140, 76, 11, 98, 0,192,135,186,186,236, 47, 30,198, 93,111,192,142, 70,158,
-198, 28, 54, 42,235,121,218,138, 22, 64,108,254, 16,143,208,106, 20,145, 96,135, 90,118,188,155,120, 30,117,230, 28,242,227,195,
-165,188,250,249,183, 23,111,255,154,130, 97,235,184, 45,149,115,249,190,160,202,225,119, 1, 14, 90, 71, 79,243,162,235,152,210,
-161, 7,197,243, 98, 68, 53,180, 83, 28,101,154,146,233,189, 26,149,136,215,202, 54, 49, 68,239, 64, 6, 65, 42, 64, 98, 1, 53,
- 4,229,239,142,211,231,220,217, 16,213, 5,217, 96,149,247,144, 30, 58,215, 44, 56,111, 26,190, 44,184,200,224,234,238,168, 57,
-110,128,115, 59,128,252, 60, 86,195,215,220,103,139,164,104,168,156,163,146,225,166,228,226,255,252,254,205, 55, 31, 62, 61,120,
-255,175,218,240, 29,100,213,138, 54,136,201,231,155,158, 69,236,223,191,251,238,213,235,233,254,251,199,140,171,206, 53, 84, 41,
- 52,213,253,217, 31,135,161,169, 95, 63, 61, 93, 27, 50, 89, 73,177, 37, 8,142, 0,122, 56,161, 0, 59,148,163,222,200, 69, 4,
- 1,134,102, 84, 75, 21,108,197,222,184, 40,233, 89,249,169,116,223,190,108,254,208,211,175,119,186,217,247, 92, 35,146,232,151,
- 6, 92, 0, 52,195,141,148,146,166,162,230,172, 56, 5,139,186,198,117, 64, 20,193,169, 57,148,169,138,134,182,111, 53,251, 91,
- 9, 8,166, 54,224, 77,133,198,104,248,136, 19,124,165,207,125, 59, 17,121,243,234, 27,128,221,193, 88, 57,113, 95, 28, 67,212,
- 3, 66,216,194,247,207, 8,109,219,181, 50,205,155, 67,114,213,185, 25,172,242, 27,251, 25,217,202,227,246,191, 0, 28, 93,201,
-170, 28, 71, 16,172,165,171,170,171,123, 70,111,222,198, 3,161,163,193, 96,140, 78, 62,200, 7, 95,141,175, 62,250,171, 5,190,
- 25,124, 52,182, 37, 63,105,150,222,107,117, 68,195,192, 48,115, 24,122,186,171, 50, 34, 43, 51, 35, 88, 63, 91,177, 11, 65, 7,
- 98,154,145, 30,143,212, 41, 43,110,171,224, 0,141,119, 95,204, 43, 62, 53,230, 54,173,233,116,112,211, 48,230, 53, 15,137,134,
-109, 53,146,101, 84,246,112,148, 45,143,130, 89, 62,149, 1,164,147,247, 10,107,116,212,234,145, 98,133, 13, 41,117, 82,253, 42,
-229,147,188, 83,135,106, 29, 66,110,183,237,173,138, 88,238, 41, 96,115,124,229,211, 28,250,146,242,225,177, 70,167,150,140,180,
- 35, 70,228,232,148,214,241,206,130,147, 52,229,203, 20, 14,193,197,134,106,216, 64,151,176, 31, 90, 79,101,235,164,158,151,178,
- 72,150, 13,157,162, 6,114,181,249,228, 21, 96, 37,172,172,139, 82,211, 8, 97, 74,105,179, 85, 18, 85, 48,239, 70,220, 56,251,
-143,196,195,233, 30,187, 31, 87,146,167,218, 24, 78, 90,210,136, 57, 50, 57,167,113,145,247, 82,220,112,253,236, 29, 3,120,112,
- 72,149, 86, 33,105,206, 14,233, 45,101,190, 16,101, 1, 47,185, 37, 50, 47,234,104,203,212,100,188,154, 76,209,244,171,104, 30,
- 40,228,166, 19,193,155,167, 58,146,149,243, 68,207,247,195,193, 45,106, 65,208, 51,171,160, 28,106,237,186,132,219, 93,176, 19,
- 84,131, 64,185, 89,159,173,182,219,156, 34, 59,100,182, 13, 48,169,239,108, 25, 20, 59, 35,192, 4,232,193, 48,187, 67,155, 3,
-112,139,237, 73,156,122, 45,105,186, 72,164,254, 77,199, 90,100,191,250,171, 41,106,177,233,175,206, 55,167,227,215,192,190,237,
-186, 88,186, 66,152,160, 99,171,141,175,110, 53, 60,117,208,194,118,117, 29,139,236,177,139, 27, 26,208, 40, 54,110,197,177,206,
- 3,201, 33,158, 21, 13, 20,199,118,219,228, 54, 4, 10,144,109,106,185,114,174,116,142,107, 5, 21,160,158,249,238,207,182,171,
-157, 99,161, 58, 33,166, 42, 70,203, 43,227, 92, 54, 21,241,100,103,234, 70,211, 93,233,173,196,122, 19, 79, 38,127, 58, 54,194,
-107, 3,250,179, 37,107, 82,146,206,135, 35,210, 92,161,238, 31,179,187,217,117,192,253, 98,187, 64,217,187,121,124, 41,193,183,
- 92,115, 75,237, 43, 51,220, 94, 89,231, 98,136,140,116,236,242, 0,148, 53, 30, 89,133, 57,115,252,244,122,138, 72, 16, 12,253,
- 56, 75,152, 75,243,248,237,175, 63, 61,127,255,254,179, 80,127,206,151, 69,208,161,160,149,101, 1,140, 82, 2, 12, 59,217,236,
-241, 29,107, 44, 49,194,237, 19,183, 52, 97,231, 54,222,246,201, 12, 89,247,100, 36,237,178,190, 37, 98,103, 54,156, 66, 98,229,
- 13,161,151, 99, 48,204, 18,115, 6,241,211,128,219,168,116,240,130, 13,109,248,149,132, 39, 0,220, 97,114,181, 14,187,123, 65,
- 74, 72, 81, 10,110,203, 18, 87, 0,248, 90,166, 85, 43,240, 20, 81,219, 30,185, 80,216, 94,107,227, 12,232, 4,235, 2, 23, 69,
- 13,116, 25, 64, 57,228, 44,233, 5,198,214,155, 12, 92, 9, 69,175, 23, 10,228,211,233, 7, 81,124, 2,156,196, 3,190,228, 76,
- 14,126, 11,124, 65, 25,221, 28,189, 3, 91,238,181,152,123,113,111,196,220, 82,102,167,191, 15, 71,163, 30,190,121,190,189,255,
-229,143, 55,223,157,135,155, 40,171,199, 95, 6, 59,223,179, 76, 86,154,167,219, 4,192,214, 26,132,155,103, 1,215,254,182, 77,
-201, 14,216,166,198, 46, 91,246,125,123,151,104,191,228,168,176, 38,104,171,101,219, 50,196, 21,108, 92, 25, 54,242, 4, 82,221,
- 86,215,171, 14, 25,113,112, 68,136,199, 34,121,212,151,241,141,116, 8, 58, 14, 96,168, 92,181, 30, 0, 78, 83,234,142,237,254,
- 98,197,119, 47,226, 29, 24,160, 24,164,162,116,144,102, 73,188,182,216,255,231,255,222,190, 59, 63,148,167,215,244, 73,188,108,
-126,233,145,111, 82,237, 14,168,243,217,124,248,225,199,223,126,238,197,249,227,120, 25, 21,155,200, 56, 87, 19, 39,164,119,233,
-233,237,211,191,203,243, 57,255,222,246,186,141, 61,155, 41, 40,203,177, 57, 74, 66, 80, 4,205,222, 14, 35,222,240, 95,213, 60,
- 83,154, 94, 23,123, 85,213,217, 37,207,193,182, 71,127,156, 62,222,192,112,177, 10,193,124,130,174,180,138,163, 93,113, 2,238,
-115, 60, 8,228, 83,148, 91,172, 77,182,187, 62,235, 22, 0,236,133,106,201, 71, 37,246,147,176, 66, 43,115,149, 77,203, 46, 17,
- 44, 46,151,230,146,218,164, 73, 41,140,163,155,227,157,248,251, 31,128, 91, 83, 58, 85, 94,106, 59, 31,177, 86,213,129,146, 78,
-174, 20,109,117, 59,186,116,138, 54, 82,100,163, 67,232,136,213,113,134, 59,176, 40,221,169,255, 5, 32,233, 74,118,221, 40,162,
-104, 85,215,208,163,109,158,227, 64, 80, 36, 80, 34,177, 9, 40, 31, 16, 36, 4, 98,207, 30,126, 18,137, 15, 97, 1, 91, 36, 18,
- 6, 41,128,157,247,220,109,119,117, 13,174,226,156,206, 7,184,221, 93,195,189,231,220,225, 92, 29,202,102,104, 46,211,109,203,
- 42, 62,245,160,125, 44,169, 62, 30,177, 4, 61,222, 85, 87,176,107, 23, 88,143,222,153, 24,211,195,100, 2, 5,229,224, 51,202,
-236,176,202, 64, 92,122,192,171,224,132,230, 46,227,186,123,118, 60, 88,183,108, 75, 61, 63,105, 92,199,198,116, 54, 34,236,234,
-219, 80,194,168, 14,117,221, 2, 84,105,152, 92,115, 45,229,192, 80,146, 97, 93, 33, 54,181, 82,107,195, 76,224, 4, 55,192, 26,
- 61, 85,197,112, 65,164, 15, 64,220,153, 35, 74,128,223, 23, 14,111, 30,153,135,162, 60, 16,181, 11, 35, 7, 23,168,148, 47,141,
-226,186,202,166,146,100,227, 93, 98, 51,172, 96,141,170, 81, 20, 3,231,132, 63,156,143,142,202,192, 56,248,160,169,140,150,181,
- 56,133, 0, 29, 25,240,142, 73, 84,177, 22, 57,219,133, 17, 72,193, 17,167,184,156, 56,153,184, 61,213,162, 25,168, 1,194, 95,
- 90,166, 64,237,101, 21,187, 85,108,193,194, 54,193, 22,118,131, 4,186, 11, 21,192,158,162, 0, 51,168,124, 3, 60, 1, 60,183,
- 50,205, 84, 88, 12,201,196, 29,206,189,242, 6,204, 68, 82, 44,172, 5,221, 7,105, 81,109,103,129,110,237,206,231, 9,255,169,
- 53,217, 93,100, 21,163, 86, 19, 7,185, 21,117, 7,108,131,215,246,148,159,175,240,224,194, 2,185, 82, 37,198, 8,170,188,100,
- 13,139,135,159,185,202,130, 66,164, 56,219,101, 6,155,131, 29, 48,218,231,147, 42,106,111,236, 91,207,178,130,202, 4, 86,229,
-194, 12, 42,166,172, 96,160,146, 6,219,109, 42, 15,227,207,166, 23, 77,225, 99,170,182,194,130,113,100,161,154, 65,185,113, 41,
- 34,136,173,129,209, 27,227,114, 18, 6, 60, 32,148, 58, 48,188, 27, 22,246,206, 0,119,192, 73,123,139,123, 34, 0,215, 28,229,
- 11, 8,222,239,212, 90,237,158, 87,251,174,139,236, 21,224,117, 93, 74,108,172,222, 3,237,132, 59,131, 63,224, 28,140, 75, 76,
-122,228,116,131, 18,217,204,153,153,135,128, 37, 96, 44,187,206,236,219, 55,147,226, 40, 71,207,218, 93, 99,177, 24,203, 22,174,
-103,147,254,243,226,144, 40, 81,175,123, 71,181,119, 86,132,129,185,218,235,176,248, 45,117, 47, 89,198,162,112,185,212,243,167,
-143,191,253,234,240,233,103,240, 75,199, 56,178,199,241, 70,207, 19,152,249,124,191,255, 12,201,172, 74, 51,106, 96,156,133, 5,
-145, 11, 37,184,227,123, 61, 30,179,166,197,214,146, 20,197,124, 14,107,247,224,252,230, 40,151,186, 48,192, 17,216, 57, 46, 87,
- 86,228,176,141,224, 21, 1, 70, 95, 95, 77, 2,157,110, 88,104,138,207,193, 39,193, 49,137,144, 97, 4, 89,173, 0,191,203,206,
-222,212,204,249, 66, 97,202, 96,109,145,239,176, 45, 21,252, 43,219, 47,250,208, 9,234, 24, 38,199, 46, 66, 63, 41, 92, 45,247,
- 0,114,206, 1, 61,212,202,159, 4,136,107,140,149,135, 15,187, 6,214, 66,122,106, 7,225, 12,203,154,242,201,108, 92,146,140,
- 41,225,128,156,117, 46, 3,108,124,237,141, 36, 81,219,196,161,239, 62,122,241,244,254,227, 47,127,201,159, 63, 28, 79,189,189,
-230,219,208,202,102,102,151,206,194, 49, 58, 14, 71,122,179,171, 62,220,155,244, 72, 53,237,166,216, 71,233, 28,195,159,203, 39,
-103,103,244,233,221,125,250, 59,171,127,109, 22,181, 23,204, 65, 81,173,144,201,247, 8,132,121, 60,203,132, 39, 10,160, 54,155,
- 97, 3,148, 99,120, 9, 16,171,242, 11,240,141, 75,206,245,176,131, 62, 39, 5,210,130,123,198,254,198,204,161,160,109, 43,210,
-113, 12,251,195,238,241, 94, 10, 63,151, 58,201,196,113, 69, 74,193,229,213,238,126,188,123,246,246,213,119, 47,127,250,209,143,
-111,126,215,173,241, 12, 24, 44, 50,110,191,254,230,139, 31,190,239,132,254,249,252,199, 95,249,102, 25, 26, 88,165,212,129, 71,
- 53,168,251,254,217, 63,111,196, 85,176,179, 8, 30,113,169,157,103, 79,108,131,197,156,143,194,246,216,138, 2,127,218, 39,102,
- 8,101,127, 78,108, 17, 1, 55,205,231,186,139,250,201,139,195,235,205,235,223,174,115, 46,122,195,249,214,247, 0, 84, 56,100,
- 65, 82, 76,198,174,234,117,176,223,216,110, 85,181,107, 90,198, 51,169,131,107, 87,241,254, 83,145,158, 77,156,120,180,111,169,
- 68,100,193,229,128,253, 68,109, 27, 22, 96, 7, 27, 41, 28, 62,139,244,252,215,211,173, 21,243, 38,181,137, 50, 64,193,132,108,
- 82,158,122, 15,191,162,133,218,238,110, 94, 39,202, 99,126,144,111, 99, 13,188,215, 73,184,207,144,120,127,186,255, 5,224,232,
- 90,122,228, 38,194, 96,219,253,240, 99,108,207,206,108, 2, 90,164, 21, 73, 86, 4, 1, 7, 34,133, 83, 56,112,226,204, 47,229,
- 39,112, 66, 92,185,129,224,128, 2, 10, 36, 10,154,101,231,225,105,187,221, 47,170,230,186, 90,105,215,109,119,125, 85,223,163,
- 62,133, 72, 91,215, 83, 49,150,220,109,102,113,154,235, 99,159,240,112,133,128,198, 50,227,102,209, 78, 61,228, 92,116,210,157,
- 19,253, 4,193, 52, 20, 24,106,196,101,175,240,176,170, 73, 11,225,132, 56,212,210, 36, 83,123, 93,171,198, 53,178,131,248, 95,
-124, 69, 11,145, 64, 39, 93, 85, 92,225,137,128, 43,166,128,120, 24,214, 8, 61,231,251, 58,117, 99,215,211,141, 27,122,128,203,
-252,240, 69,224, 64,230,133,234,161, 48,185,116,199, 50, 52, 94,179,149,132, 5,124, 57,155, 11, 17,225,154,167,128, 95, 0,142,
-217, 32, 64, 63, 14,244,139,179,172,107,230,132, 64, 74, 95,133,203,148, 54,254,238,138,247, 53, 87,186, 32, 62,148,201,113,178,
- 60,111, 88, 94,208,172, 7,182, 96, 49, 2,124, 57,224,176, 78,228,201, 0,180,186, 13,158,251,195,184, 57, 94,115,181, 55,135,
-115, 46,190,214,130,163,197,115,145,142, 43,132,113, 47, 67,167, 33,234,228, 44, 0,244,224, 37,148,191, 21, 36,150,112,237, 80,
-142,218,221,159,149,234, 64,227,200,191,185,239,167, 16, 19,228, 91, 4,167,209, 42,112, 36,142,115,234,142,131, 78,138, 29,120,
-206,207, 96, 15, 8,150,213, 89,207, 50, 84,113,198,195,103, 40,185, 42, 64, 23,135,229,148, 47, 29,211,204, 79,226,109,227,114,
-196, 92,198,110, 65, 16,172,101,228,156, 19, 56,166, 39,108,200, 42, 50,137, 30,112, 96, 9,145,213,106,159,247,117, 9,188,145,
-242, 56,143, 80,234,156,129,203, 7,220,234,165,140,134, 13,148, 80,243,181,231,164, 54,239, 86, 16, 71,246, 0,137,118, 42,217,
-119,188,162,123,124, 91, 46,187, 37,218, 89, 31, 64, 45,197, 33, 66,206,198,212, 23,246,158,253,138,202, 7,188, 58,200,238,116,
- 20, 51, 2,129,194, 53, 20,215,100,170,180, 99, 97,138,230, 50,199, 83,116, 34,175, 5,222,225,210,228, 86,115,141,106, 0, 19,
- 89, 65,228,196,167,207,118,211,143,101,119,114,156,255,229, 5,201, 52,232, 84,224,197,236, 56, 81, 53,139,252, 19,224,106,159,
- 6,246,222, 40,206,233,140, 39,211, 2, 3, 19,123,175, 35, 91, 79,207, 38,224,231,181,118,149, 53,129,115,128, 16,165,114, 5,
- 52,203, 42,208, 88,175,136,117,255,205,151,143, 94,189,176,221,246,117, 0, 7, 96, 63,117,201, 92, 47,141,238,147, 98,121,116,
-190,116,158,250, 75,174,113,133,207,140, 27, 85, 19,157, 30,153,144,129,220,229,123,154,178, 93, 68, 26,196,165,162, 76, 2, 97,
-240,117, 84, 56, 94,118,146,225,175,210, 46, 51, 81, 75, 71,201, 61,228, 92, 72, 71,112,241, 42,136,102, 78,141, 52, 15, 37,152,
- 61,216, 57, 51,227, 66,186,153, 43,126, 35,248, 20, 94,159,197, 83,151,133,163,228, 13, 26,208,239,183,130,238,173, 97, 46,140,
- 77,231, 90,121, 43,152, 37,228,191, 80,112,117, 96,116,226, 77, 2,154, 65,147,204, 22,188, 43, 90,191,116,179, 96,139,106,193,
-108,162,166,231, 26,183,109,113, 36, 98, 5,180,205,106, 64, 52, 46,171,170,135,182, 26, 6, 77,254,179, 90, 30,111, 30, 95, 63,
-185,251,227,238,213, 47,233, 54,228,253,101,101,224,214,168,120, 16, 39, 64, 86,225,182, 75, 85,223, 42,243,217,117,254, 96,251,
-206,244,127,166,243,125,136,199, 96,195,163, 94, 60,199,167,172,159,143,183, 55,195,238,238,247, 55,195, 78,252, 61,164, 19,104,
-253,186, 53,167, 98, 90, 64,170,206,197, 3,160,218, 76,173,209, 59,187,232,200, 11, 1,248,161,198, 41, 16,233,197, 67, 44,229,
-106, 1, 5,216, 95,129,234,212,221,156,164,167,179,184,157,162, 14,170,191,137,231,255,236,211,237,231,136,110, 92,142,148, 91,
- 28,139, 1,250, 24, 25,122,237, 38,121,248,235,245,183, 95,223, 92,221,124,241,195,247,242,221,191,111,155,169,249,244,195,103,
- 47,191,123,249,226,171, 70,164,159,236,207,111,195,152, 12,148,185,139, 96,175,105,159,221, 33,174, 63, 94, 3, 64,246,239,255,
-233,105,182, 61, 76,208,243,244,137, 99, 5,135, 75,155, 31,178,255, 72,171,227, 88,233,122,114,147,171,228,102, 12,117,178, 62,
-173,167, 6,114,233,234,201,173, 28,220,175,187,227, 20,128, 57,131, 93,188, 76,141,242,151,212,122, 85,151, 11,247, 14, 33, 32,
- 79,160,217,106,157, 74,197, 52,157,198,157,212,108,160,224,138,185, 51,211,105,222, 3,193,202,180,194,197,196, 7, 79, 47,116,
- 64, 54, 0,156,165,213, 30, 88,207,234,157,147,159,252,118,146, 67, 45,171, 90,178,160, 43, 58,208,126,221,118, 67, 56,143,125,
-218,204,235,177,177,181, 55,218,140,107, 85,238,160,178,218, 48,151,109, 6, 31,156, 70, 81,169,255, 5, 32,233,106,122, 35, 39,
-162, 96,183,251,203,109,123, 38,153, 36, 98,181,104,247,128, 8, 39,110,187,136, 5, 33,113,128, 35,127, 26,137, 27, 39,110,136,
- 15, 65,144, 34,177, 75,216, 76,102,198, 99,187,237,254,160,202,220, 70,202,140, 35,217,126,239,213,235,247,170, 74, 7,231, 40,
-195,141,151, 1, 89, 52, 25, 83, 71,224,202,202,201, 33,112,233,116,160, 83, 73, 81, 61, 30,141, 72,155,147,127,168,230,161, 26,
- 54, 50,100,131, 52,135, 7,162, 98, 33,125,221, 1,220,102, 63,200,170, 43, 25,173,126, 83,209, 37, 75, 0,221,113,125, 2,255,
-222, 62, 67,159,140,116, 69, 43, 44,158,230,177,140,165,118,232,114,166, 6, 34,167,160, 11, 89,148,192,164,214,166, 88, 16, 46,
-195, 28, 54,101, 72,169, 57, 71, 51,218,184,229, 94, 22,170,138, 52,211, 17,133,131, 27,183,128, 36,189,157, 0, 81, 43, 59,162,
-108,228, 57, 0,230,161,209, 17, 3, 66,255, 89, 44, 83, 35,246,177,217,225, 77, 87,130,155, 61,171, 18, 64, 6,134,161,255,139,
- 28, 51, 79,192,106,202, 67, 87,179, 21, 13,189,113,241, 5, 21, 92,165, 23,158,143, 22,142,224,129,199,198,121,150, 13, 98,148,
-219, 19,149,241,128, 38,133,109, 86, 59, 69, 23,240, 0,250,163,144, 54, 82,206,135,148, 90, 66,191,133,201, 34, 33, 49,170,179,
-118,128,211,203, 72,213,159,154,211, 76,191,232, 61,185,249, 74, 77,210, 79,233,176,211,184,211,221,152,122,198,101, 12,148,191,
- 55,212,169, 71, 74,243,104, 22,242, 58, 41, 77, 1, 16, 33, 47,195,214, 69, 98, 86, 82,112, 1,125, 22, 84,113,153,252,255,212,
-236,232,104, 38,111,128,220,169,148, 89,184,159,109,100, 92,108,197,209, 24,208, 99, 68,215,213,249, 69, 76, 8,173, 67, 76,163,
- 17, 45,210,174, 49, 36,102,170,206, 8,155,212,192, 65, 1,171, 87, 92, 87, 53, 41,174,130,203,116,195, 20,231, 35,199,241,121,
-175,228,144,208,228, 17, 58,206,229, 18, 29,208, 84, 17,117,246, 49,105,138,188,199, 89, 85,179,168,171, 17,152, 93, 83,102,150,
-147,252,184,158,182, 91,146,231,197,232,121,194, 3,204,118, 89,243,165, 7,170,167, 2,175, 45,226,132, 34, 94, 62,248, 48,108,
- 27, 69, 98, 85,114,114, 26,185, 21,142,139, 46, 35, 42, 69, 57,249,210,234, 43,116,248, 60,216, 66,241, 90,144, 36, 99,157,208,
-237,140,122,172,122,229,110,182,168,219,151,253, 73, 58,155,134,234,200, 53, 40, 45,204,116,193,163, 78,137,251,148,231, 37, 68,
-196,132,255,238,115,247,250, 13, 57,168,115,207,201,176, 76,171,201, 55,247,161,216,128,173, 26, 57,180,200,230,208, 83,172, 7,
- 76, 40,253,132,187,171,177,146,160, 2, 48,157, 74, 19,191, 68, 47, 14,174,184, 89,218, 85, 80,195, 27,159, 87,215,202,236, 50,
-178,150, 72,180, 17,215,148,203,205,129, 14,188,138,226,202, 18,233, 76,175, 83, 32,242, 80,129,231, 18, 55, 12,233,181, 38,205,
-194,152, 20,225,172,233,199, 69, 22, 74,212, 79, 74,116,148,156, 64,139, 72, 2,104, 9,161, 43,238,200, 13, 0,160, 72,153, 66,
-255,192, 45,247,234, 96, 73, 71, 25,150, 58,240,188,212, 70, 20, 41, 0, 61,246, 73,244, 67, 82, 43,143,206, 27,165,149, 71, 8,
- 38,225,240,233,202, 58, 79,199,112,123, 49,251,218, 95, 61,191,118,183,175,126,217,125,246,227,176,171,250,195,230, 98,225, 50,
- 50,202,126, 10,103,105, 82,238,110,253,229,199,221,191,207,111,222, 89,127,127, 24,254,122,252,115,140,231, 64, 75,135, 16, 76,
-169, 99,156,154,205,193,123,253,197,213,237,167,221,205, 15,247, 31,253,250,116,183,228, 63,236,126, 71, 31, 61,145,143, 90, 82,
- 16, 15, 79,183,159,102, 92, 91,180,132, 30,139, 68, 91,161,243,128,148, 48, 25,213, 68, 50, 64,154, 49, 47, 65, 12,126,217,106,
-180,103, 18,192, 87, 29,145,156,197, 83,149, 95,127,253, 66,136, 83,100, 95,149,208,176,114,191,233, 64,238,161,243,234,244,176,
-191,255,233,231,175,190,121,243,229,171,111,223,135,185, 75,222, 55,189, 16,123, 49,124, 31,239,222,207, 1,249, 19,205,178,226,
-221, 70,130, 71,144,184,216,250,246,239,254,230,109,252,103,167,209,163,205,146, 35,146,200, 39, 15,204,101,103,105, 84, 85,200,
- 5,207, 76,192,239, 42,177, 13,238, 34,164,147,156, 78,241,220,188,124,121,253,201,213,111,234,237,239,180, 77,169, 55,104, 1,
- 56, 95,193,189, 95,102,202, 34,161,214,215,200, 52,106,203,149, 31, 73,207, 20, 14, 33,128, 10, 5,185,249, 22, 56,195,100,237,
-164,241, 37,121, 5,172,192,115,203, 49, 79, 66,182, 86,168, 26,127,142,143,248,177,212,187,113,235,174,239, 30, 95,228,210, 95,
-111, 11, 96, 42, 74,187, 23,180,249, 44,237,185,156, 78, 6,152,213,180,136,115,115,230,238,132,104, 72,238,232, 54, 93, 25,129,
- 47,148,169,155,202,213,255, 9, 64,210,149,236,200, 81, 68,193,172,204,172,204,218,186,122, 54,240, 96,131,128, 3,210,248,128,
- 5, 66, 32, 46,136, 3, 95,205,153, 19,200,130, 3, 18, 39, 12, 18, 96, 13,214, 96,247, 82,123,229, 70, 68,249, 58,234,195,116,
-117,189,120, 47, 50,227, 69,232,219, 98,153,215,194, 21, 1, 95,219, 75,109,235,213, 58,212, 41,254,102,129, 56,182,207,150,105,
-167,153,199,138,167, 52, 79, 53,186, 79,233, 18, 55,202, 48,175, 2,125,192,251,101, 33, 49,113, 79,158,178, 87, 97, 76,181, 5,
- 74,106, 47,235, 90,210,190, 90, 73,183, 55,113, 23,175,175,108, 58,201, 6, 80,199,165,107,147,229,204, 48,199,252,163,119, 64,
-107,169, 37,230, 91, 23,215, 25,164, 78,101,171, 90,103, 81,118, 58,171, 99,159, 87,235,160,185, 29,149,179, 72, 65, 19, 75,129,
-142, 93,162, 99,137,147,159, 42,137,121,189,255, 47, 94,212, 49,204, 38, 78,217, 40, 19, 15, 24,123,193,251,211, 64, 81,241,194,
- 24, 83,106,117,137,193, 24,214,171,204,205,145,183, 38,164,143,124,184,193,112, 83,128, 38,148, 13,229,123,105,165,184, 68,239,
-189,115, 83,202, 71,158,162, 5, 74,175,149, 28,132, 47, 3,245,196,130, 17, 36,203,204, 84, 34, 14,126, 24,140,156, 23, 83, 42,
-170,108, 2, 25,166,238, 71, 45, 34, 26, 74,120,124,239,179, 62,151,205,236,151,188,168,117,106, 10, 96,109,236, 10,207,212,226,
-128,255, 33, 45,232,122, 0, 17, 43,164, 85,251, 57,239,105,165,158,236, 96, 12,234, 38,247,203,132,247, 79, 37, 70, 25,198,194,
- 90, 87, 76, 60, 65,244, 96, 71,148,215,206, 25, 53, 63,117,229,162,167, 61, 6, 79,105,162,155, 2, 31,173,226, 53,146, 50,189,
-157,252, 61, 6,207,236,140,151,129,113,171, 19, 91, 66,210, 97,230,138, 74,180, 91,158, 11,149,149,129, 2,199, 82,209,158, 42,
-113,127,135,199,209, 3, 5, 13,249,254,188, 62,232, 21,116,240, 56,178,191,102,220, 16, 24,192,146, 44,125, 32, 66,206,140,185,
-140, 66,110, 13,188, 69,119,224,229,210,102,135,126,136,226,210,138,209, 82, 16,169,107,222,180, 22, 42, 99, 16, 32,190,111,201,
-250,113,215,121,147,202,139,198,138, 11,119,115,113,248,234, 89,241,252,167, 1, 32,150,152,210,228,185,169,149,104,228,172,215,
-145,251,109,225,141, 75, 55,213, 14,221, 21,244, 53,250,184,101,201, 97,106, 38,238,205,157,113,239, 1, 69,175, 64, 32,179,119,
-153,133,152,164,200, 99,237,196,209,173,231, 50,150, 55,159,126,254,232,139,187,225,227, 39,139,240,175, 24, 60, 73,255, 6, 90,
- 85,160,213,242, 98,140,191,198, 91, 31,119,134, 24,109, 14, 51,126, 51,155, 41,183,204, 84,254,198,248,168,167,238,141, 54, 88,
- 34,175,222,250, 3, 99,114, 15, 11, 13, 73, 49,197,111,143, 13,152, 58, 59, 38,136, 40, 73, 75, 48,238,207,161,180,217, 5,230,
- 16, 6, 10, 59, 35,106,169,142,246, 65,130,212,219,173,143, 10,231,198,164,151,108,181,139,164, 33,217,234,214,164,150, 99,210,
-167, 8,132, 1,105, 19,168,132, 42,209, 97,104,136, 1,255,118, 4,101, 33, 51, 58,245,153, 92,162,234, 25,216,199,101, 40,224,
- 87,164, 11,205,196,140,123,148,175, 64, 15, 4,122, 90,158,185,163,171,163, 84, 77,219, 40,142,178,173, 2,244,232, 70,182,215,
-246,230,195,253,112,253,205,207,151,119, 47, 6,244,165,127,234, 98,209,129,114, 78,211, 46,103, 76,109,135,203,175, 31, 55, 79,
- 63,120, 17,211, 31, 99,127,120,184, 63, 6,215,201,161,100,120, 66,146,148, 73, 59, 69,153,253,241,220,117, 38,205,191, 94,230,
-230,187, 39,223,190, 95,127,246,253,159,234,213,223,191,155, 98, 14, 49, 55, 75,200, 79,121,135, 70, 47, 85,139, 50, 86, 52, 0,
- 79, 65,197,162, 31, 23, 67,185, 75, 64,173,249, 78, 58, 12,170,166,212, 60,230,229, 62,134, 76,152,118, 90,213, 29, 83, 54,150,
-119, 31,229, 66,252,181,177, 40,116, 31,238,101, 5,203,104,161, 66, 23,228,139,247,247,231, 31,159,183, 95,190,124, 71,214, 96,
- 68,113, 58,224,135,119,175, 15, 24, 43,136,217,168, 91,116,240, 16,228,126,163,216, 34,218,246,106,236,218,202,254, 86,114, 31,
- 80,226, 69, 11, 98, 89, 65,150,240,120,188,191,106,252,250, 58,109,215, 36, 3, 33, 30,196,148,146, 32,167,132,121,116,251,248,
-233, 39,247,249,225,151,211,155,137, 94, 88, 74,165, 9, 21,180,228, 43,176, 2, 99,224,150,247, 5,120, 5,124, 52, 73, 22,165,
-167,242,193,234, 22, 35, 33, 87, 12,168,234, 45,121,219, 65,182,173,103, 94,246,246,153,104, 35, 70, 99,177,212, 34,163,188, 93,
-223,106, 89,209,250, 80,228,207,126, 0, 95,181,255,210,101,211,236,196,232,246,248,228, 78, 19, 92, 42,148,194, 46, 4, 87, 50,
-200, 9,148,158,139,151,205,149,172,245, 12,152, 77,197,190, 51, 35,222,172,255, 5, 32,233, 74,118,219, 56,162, 96,207,244, 58,
-156, 17, 69, 42,138, 35, 3, 10, 96, 56,128, 45,192,151,192,112,150, 99, 62, 34, 95,153, 91,254, 33, 64, 78,185,248,226,115, 54,
-216, 80,108, 81,228,112,182, 94, 83, 53,190, 16,224,129, 24,178,249,186, 94, 85,247,123,245, 0,176, 13,207,228,236,162,250, 75,
-108,169, 44,135, 60, 57, 97,219, 46,143,103, 40,129,125,112, 30, 84,141, 67,250, 52,107, 32,165, 49,147,143,141,214, 75, 45, 23,
- 85, 57,118, 75,103,229, 11,237, 50,161,149,205,165, 76, 75,197, 89,205,166,174,219,213, 17,213,149,176, 11, 95,141, 44, 4, 51,
-202,225, 99,105,231,221, 80,103, 99,116, 54, 67, 9,110, 29, 73,230,149,167, 67, 23, 36,237,168, 32,204,181,108, 34,239, 57,177,
- 71,228,192, 42,171,184,233,205,188,142,176,104, 56,237,112,226,168,106,173, 84,236, 75,123,157,103,155, 79, 3, 40,176,144,150,
- 71, 15,113, 46,195, 63, 41,111,165, 85,245,227, 41,250,102,218, 10,135, 84, 3,238, 82,185,226,238, 3,228,254,178, 3,164,101,
- 2,219,196,182, 61,109, 45, 4,210,106,126,196,107,227,180, 20, 97, 56, 64,111,157, 63,201, 62, 81,161,215,137,107, 97,157, 64,
-211,169, 84,141, 6,112, 2,242, 41, 58,176,146,192, 58, 27, 71,215, 30, 48, 34,136, 52,172, 21, 18, 53, 2,199,131,220,131,242,
- 23, 25,217,241, 89, 62,143,170,147, 28, 97,164,216,126, 11, 98,139,197,218,241,141, 75, 16,197, 10,128, 46,173,232, 76, 53, 0,
- 90,165, 12,120, 46,205,159,243, 57,179,123,166,118,238, 0,186, 22, 52,114, 82,160,131, 33,239, 87,105,187, 71, 95, 42,158,168,
- 35,243, 34, 55,112,227, 9,213,167,152, 23,128, 78,239,231,186,221,108, 68, 57,124,144,245,101, 2, 69,196,178, 9,218,107,178,
-137,206,214,210,145, 73, 37, 99,104,186,216, 71, 0, 86,169, 11, 18, 37,187,162, 88,234, 38,231, 81,206,103, 57,185, 37,208,167,
- 79,225,167,129,177,234, 17,107, 39,231,227, 60,157, 75,139,133, 51,114, 14,193,101,210,195,235, 26,112, 41,188,163,237, 21,126,
- 0, 18,190,165, 97,156,114,174,240, 32, 18,108,122, 43,147, 74, 27, 41,175,191, 86, 95,118,234,234,101,155,174, 33, 68, 63,254,
-252,211, 23,207,182,187,223,222,181,247,231,251,105, 60,252, 53,150,250, 49,237,155, 51, 18,226, 39,233, 59,163,171,105,214,198,
- 35, 70,188, 75,139,176, 38, 34, 50, 74,213, 25, 14,146, 67, 90,130,180, 29,102,112,232, 65,166,241, 92,111,130, 19,213,222,238,
-170, 23, 47,119, 63,190,190,120,246, 13,152,248, 81, 76, 51, 24,105, 33,123,162,229, 15,228,100, 34,133,103, 73, 27,245, 27,207,
-100,212,122,236,190,226,252,122,151, 41,214, 91, 25, 78,234,225, 65, 59,232,192,178, 94, 35, 40,188,242,138, 97, 49,185,208, 85,
-167,140, 61,125,211, 33,155,196,194, 62, 67, 44,234,200,154, 72,159,129,130,214,212, 96,236, 85,218,176, 64, 84, 61,132,124,146,
-106,168,124, 27,227, 80, 71,142, 64,102, 31, 7,210, 85, 68,220,205,180,178, 1,217,196,151,153,165,196, 14, 65,120,213,200,228,
- 15,128,178,210, 92, 80,114,145,137,246, 82,241,174, 39,132, 30, 58,152,201, 7, 59, 43,228, 69,209,160, 1,193,203, 1, 8,142,
-165,113,117,210, 98, 6,139,180,114, 99,170,104,140,122, 82, 83,232,201,108,117,188,184, 49, 87,207, 95,124,120,250,253, 31,227,
-221, 18,143,122, 57, 52,149,171, 45, 1, 99,158,253,114,230, 49,230, 15, 55,238,219,231,127, 15,211,219, 19,196,194, 49,249,137,
- 67, 45, 35,216,210, 60,149,172, 35, 30,213, 70,147, 77,136,192,148, 42,121,253,241,124,234,252,175,223,237,223, 40,247,250,151,
-147, 24, 31,222, 73, 77,243,219,212, 77,247,122,218,158,128, 91, 25,144, 81,129, 69, 73, 57,214,150, 3,153,245, 8,157,131,132,
-177,147, 46,157,193, 26,195, 30,128, 5,249,160,201,194,186, 44, 66, 63,220,222, 62,189,185,109,132,248,143,141,143, 28,253,148,
-233,123,161,214,182,254, 65, 39,171,237, 14, 57,250, 48, 63,246,149, 86,177,200,234,140, 92,232, 21,253,171, 37, 80, 58, 29,145,
- 20, 39, 25,117,189,128, 43, 47,136,255,209,117,135,251, 35,232, 23, 99, 57,206,173,189,202,216, 89,126,236,240,175, 54,155,135,
-172,162, 79,128, 58, 48,179,168, 92, 59,143,147, 26,178,236,110,159,188,186,187,123,191, 89,126, 31,254, 61, 68, 4, 84,166,227,
-117, 98, 65, 22,239, 4, 62, 87, 19,179,180, 10, 15,130,130,134, 46, 67,220, 92, 84, 9, 72, 52, 91,132,108,134,156, 55, 52,148,
- 32,133,192, 38,128, 54, 8, 6,127,138,104,148,248, 36,165,141,217, 33,157,208,169, 91,132,205,165,189,250, 51,191,121,251,126,
-188, 73, 78, 90,171,219,220, 39, 54,245,104,191,173, 89,110, 92, 28,116,232, 82, 76, 99, 9,225,222, 55, 60,223, 87,165,182,195,
-181,216,232,230,194,225,249,195,255, 2,144,116, 45, 61,142, 19, 97,176, 95,182,219,237,100, 50,155,153, 12, 3,136, 97, 37,132,
- 4,135,133,189,140,132,180,218, 3,127,153,127,128,184, 32, 33,193, 9,137, 27,210, 34, 96,197, 60,147, 56,118,187,219,221, 77,
-149,247, 20, 77,164, 76, 98,187,251,171,239, 81, 93,101,168,176, 20,231, 58, 32,230, 97,161,202,253,161,214,199, 72,106,166,117,
-227, 52, 77,177,213,167, 80,205,135,140,183,165,149, 19,242, 9, 43,169,184,105, 92,174,116,225, 71, 26,148, 9, 13, 42,105,239,
-197, 90, 13, 72,150,213,121,125,148,186, 37,106,205,174, 1,198, 87, 66,110,218,199,202,127,164, 67,135, 12, 84, 20,217,216,190,
-243,184,222, 70, 90,178,158, 17,200, 36, 82,106,170,247,102,147,102,206,142,145, 71,163, 46, 75, 6,101, 1,123,154,101,138, 61,
-146, 80,124, 52,236,107, 13,220, 26,177,131,200, 81,152,234, 30,225,175,110, 66,175,175, 91, 54,196,169, 42, 24,173,181, 0, 92,
- 73,253,242,178,118,165, 12, 60, 97,170,168,183,131,130,178,226, 4,195, 35, 44,230,140,103,223, 56,138, 98,205,153,210, 92,156,
- 97, 11, 82, 7,169, 1,133, 63,216, 53, 38,185,155, 74,222,168,159, 54,128, 65, 74, 72, 68,250, 64,196,217,205,128,194, 46, 70,
- 18, 85, 85,181,136,147,144,182, 76,127, 34,220, 84, 96, 56, 15,203,106,211, 68, 29,140,119,134,190,197,244, 50,166,166,186, 32,
-243, 49,101,236,216, 65,148, 75,139, 45, 77, 38,225,168, 16, 28,226, 40,232,196, 83, 7, 13,108, 43, 37,175,242, 66, 14,173,198,
- 69, 75,103, 19,216,103,103, 39, 57, 3, 19,151, 23, 79,133,145,170,201,158,188, 95, 18,251,142, 81,219,185,212,185,138, 52, 68,
- 51,101, 43,227,148,253,168,206, 63, 65,141,119, 32,247, 82, 35, 25,212, 8,194, 60, 29,166,122, 60, 33, 58, 80, 9, 71,126, 75,
-161, 38,141, 54, 6,113,137, 60, 18,201,154, 86,165, 28, 69, 31,205, 96,204, 16, 79,125, 25,106,213, 30,128, 89, 81, 15, 64, 62,
- 33,157, 60, 34, 47, 93,212,191,177,184, 31,148,176,228, 99,138,203, 11,181,196, 59, 69, 83,232,182, 20, 87, 16,212,213, 58,219,
-149, 50, 87,114, 39,220,250,202,116, 95,116,213,205, 58,168,114,186,127,232, 54,211,237,155,253,237,155,149, 31,234,247,239,182,
-239, 7,117,183,223,221, 63, 14,216, 72,247, 99, 56, 77,169,159,163,188,119, 99,228,212,118,110, 18, 93,143, 42, 97,233, 37,154,
-176,133,239,156, 94,139, 6,213, 96,231,218,221, 77,181,221,213,155, 46,189,188, 9,171,237,131,144,143,121, 60, 76, 52,185,206,
-108,182, 80,147,141, 3,213, 68,127, 13,108, 69,191,148, 24,137,178, 9,203, 32,196,112,240,174,120,114,156,204,246, 68,225, 28,
- 77,171, 42,124, 95, 33, 74, 19, 84,121,169,115, 67,197,176, 15,125, 27, 84,172, 13,207,179,164, 94, 68,143,220,135, 6,151,154,
- 54, 23, 52,133,149,131, 8,120,240,138, 46,105,146,214,113, 98,112,153, 35,176,129,200,142, 69, 98, 7,132,192, 68,219, 86, 95,
- 70,143, 52,138,234,153,100,224, 96,229,227,127,117,116,228, 66,228,150,207,200,211,145, 51, 36, 53,164,231, 67,244, 71,228,123,
- 88,196,117,131, 61, 82,166, 13, 3, 14, 86, 24, 69,108, 22, 13,121, 92, 43,162, 30, 50, 76, 81,144,150, 59,189,170, 12,210, 22,
- 60,125,181,222, 94,111,174, 86, 95,125,249,235,217,235, 63,101,189, 47,239,214, 76, 18,102,220, 5, 96,204, 49,233,125,166,119,
-225,219,139,213,215, 31,255,126, 24,254,221, 63, 61,248,193, 83, 59,149,205,207,153, 83, 30,137, 31,148,129, 49, 25, 79,214, 79,
- 53,162, 42,106,111, 30,138,174,253,209, 63,207, 63,125,187,243,243,171,183, 63,252, 86,134,191,127, 25, 80,202,123,115,214,122,
-124,123,126,210,189,245,225, 24,206, 87,181, 25, 53, 79,148,119, 58,180, 58,196,124, 70,243,199, 12, 0,125,182,241, 90,212, 88,
-197, 60,229, 66,165,242,249,245,247,159, 82,179,225,132,200,192, 19, 6, 88,183,108, 42,180,145,194,247,108, 70, 82, 64,169,169,
-219,121, 31,129, 94, 64, 66,220,248, 52,153, 69, 11, 40, 32, 9,167,145, 56,222,161, 37,227, 72, 53,212,117,173,170, 75, 15, 0,
-107,114,161,128, 95, 26,242, 35, 89, 76, 77, 59,242, 44, 16,176, 50,108,108, 55,162,200,174,122, 77, 27,240,232,227,238,243,207,
- 94,222,126,243,143, 29,127, 28,255,122,136,129, 6, 59,146, 50,132, 28, 72,154, 23,128,186,228,239, 22, 1, 49,165,217,221,113,
- 9, 91, 85, 29, 79, 85,182,101, 75, 98,204,135, 51, 32, 84,247,225,101, 89,142,101, 16, 70,170,134, 93,210,113,138, 77,160,105,
-167,188, 32, 35, 49, 39,183,158, 7,245,221,207,255, 93,169,238, 15,119, 54,162, 78, 87,179,181,206, 81, 33, 78, 84,186, 59, 6,
-182,181,101,131, 13,176, 42,117, 56,247,200,214,207,154, 33, 62,137,168,207, 77,168,203, 97,156, 58,151,154,255, 5, 96,233, 90,
-118,227, 54,130,224,188,248,230,114,215, 81, 28, 73,128, 15,202,201,129, 15, 54, 16, 32, 57, 37,191,155, 47,201, 7, 36, 64,144,
-131, 79, 1, 98,192, 48,164,104, 95, 36,135,156,103,170, 40, 95, 4, 65, 43, 44,150, 59, 61,221, 85, 51,221, 85,166,108,123,246,
-151, 96, 63,130,199,156, 16,170,167,221,208,212,255,117, 72, 77, 46, 62, 46,192,112,223, 96,195,239,204,105, 21,107,219,162, 70,
-213,180,185, 59,241,196,169, 81, 52, 48, 85, 85,239, 11,148,160,107,168,234, 48,180,136,165,118,220, 23, 7,148,115,212,142, 3,
-138,250,166, 29, 81,228,198, 22,229, 43, 60,172, 92,233,220, 73,129,221,118,162, 91, 16,225,164,141, 19,109,103,196,190, 97, 94,
-225,201,239, 49, 91, 45,177,102,158,146, 25,185,174,185,163, 56,249, 36,103, 59, 23,248,250,194,180,120, 97,246, 10,184,255,121,
-169,250,107, 4,160,184,128, 64,229,208, 18,138,129,109,233,163, 91, 69, 73, 45,157, 99, 41, 6, 54, 58,130,233,165,224, 76,106,
-232, 60,215, 58,217, 1,135, 33, 76, 22,125, 90, 68,217,227,133,205,149, 39,209, 99,143, 36, 57,209,128, 86, 88,106,241, 20, 60,
-227, 22,150,141,201, 52,176,198, 58,141, 88, 64, 43,170, 5,155, 90,218, 98,179,251,174,120, 73,129,212,184,236,131,193,159, 42,
-159,148, 52,103,122,182,232, 41, 15,145,174,161, 75,220,238, 96,145,153,128,230,118,117,133,218, 86,122, 90,175,172, 57, 0,230,
-139, 56, 55,218,163,180, 83,148, 29, 48,113,246,168, 81, 84,131,193,199, 0, 36, 88,183,211, 98, 67,177, 73, 74,168,211, 72, 83,
-115, 74, 21,160, 61,106, 90, 12, 42,124,235,103,234,175,230, 24,129,253,228,181, 68,122,233,131, 62, 77,246,170, 76,169,123, 63,
- 11,125,244, 62,214,163,231, 60, 0,146, 92,165, 88,189,106, 77,215, 48,246,249, 38,108,159,196, 41,175,172, 93, 41, 22,239, 86,
-239,232,176,149,221,132,221,162, 92,100,186,151,108,170,215,108, 80, 65,194,148, 40,169,250, 21,192,150, 22,244,169,218,134, 61,
-229,166, 6,126, 45, 85,173,217,167,237,119, 42,222,113,148,120, 87,152,225,181,106,106,109,110,196,183,175,155,226, 94,164,239,
-148,173,156, 90, 65, 57,228, 56,173,114,158,116,117,172,219,238,225,135,238, 65,200,175,231, 36,162,216,126,150, 66,220,125, 61,
- 22, 71, 26,163,202, 76,224,129, 54, 15,167, 15,226,197, 13,149,192,251,121,195,222,203,246,255,120,135,115, 0,178,182,125, 82,
-236, 28,231,153, 9, 55,160,167, 35,204,246,230,196,143,153, 22,165,155,183,148,166, 41,236, 54,158, 44, 12,158,166, 23, 91, 7,
-111, 78, 11,117, 52,115, 9,220, 41,184, 62,155,129, 41,104,160,170, 1, 61, 76, 29,147, 21, 17,172, 23,181,179,243,206, 80,195,
- 26, 20, 78, 16,121,243, 42, 41, 37,132, 23,190,168,236, 47,185, 92,196, 42,227,196,107,127, 89, 60,178,111, 66,159, 69,244,202,
-123, 16, 60, 63,131,230,112,148, 60,180, 11, 79,167,195,214, 14, 36, 67, 16, 83, 94, 45,197,103,176,113,241, 73, 52,106, 61, 98,
-124, 17, 10,180,218, 48, 98, 29, 77,178,120, 83, 60,178, 89,189,104,242,139,175,158, 2,105,170,106,147,177,190, 3,241, 94,219,
-161,222,175,101, 87,220,191,187,123,186,253,249,175,254,251,143,151,181, 50, 95, 6,138,104,130, 60,230,169,124,214, 35,146, 70,
- 14, 83,119,200, 55, 15, 55,255,174,242,143,233, 40,243, 24,228,113,196,194,206,168,115,187,181,125, 90, 18, 40,188, 7,114, 9,
-113, 6,133,199,175, 84,217, 1,202, 64,173,209,182, 89,100, 74, 79,127,254,242,102,127, 93,223,254,246,233,111, 29,206,200,192,
-197,218, 38,118,127, 9, 61,184, 18,107,224,118,126,179,219, 44, 47,193, 52, 0, 25, 8, 1, 48, 34,206, 53,135,144,173, 11,243,
- 94,230,133,106,193, 93, 37,126,124,255, 70,136, 47,145, 87,189, 84,198,167, 96,242,156,115, 52,154,118, 93,190,142,108, 31,167,
- 36, 86,164, 33,175,176,225,197,184, 28,169, 53,207, 52,252,162, 37, 30, 34,186, 8, 14,143,214,176, 53, 75, 34,124, 67, 50, 51,
- 13, 67,196,160,159,207,253, 61,170,124, 51, 57,169, 42, 87, 23,217,140,201,218,149, 15, 50, 91,215,250,219,159,126,189,253,240,
-246, 81, 93, 63,206,159, 93,184, 52,216,185,238,146,157,228,196,130,119, 52, 2,104,182,249, 1, 94,210, 32,138,102,212,114,205,
- 70,208,134, 8,160, 8, 84,164,160,205, 50, 7, 65, 17, 90, 85,172,123,228,113,189, 13, 15, 10, 49,114, 8,162, 66,114,223, 99,
-167, 7,245,212, 15,186,200,239,127,255,244,225,159,243,231,174,177,200,120,105, 0,111, 54, 21,210, 0,168, 93, 79,173,251, 29,
- 34, 43,236,198, 3,200, 15,248,181,213, 37, 34,153,150, 35, 96,239, 6, 53,195,139,107, 17, 64,219,254, 23,128,165,171,233,141,
-219,134,130,252, 18, 69, 74,222, 93,103,107, 59,253, 10,144,158,138,164, 8,122,234,181,183,254,242,246,212,131, 17,228, 7, 20,
- 45, 96,164,104,227,120,237,221,149, 40, 74,252,232,140,220,187, 37,120, 73,241,189,153,199,247,102, 12, 91, 41, 56,129, 3,200,
- 90,128,182, 54,105, 63,181,113,222,204, 15,203, 84, 74,186, 8, 93, 61,179,103, 31, 95,244, 69,183,208,219,111,137, 72,118,174,
-239, 75, 9,148, 75, 17,214, 76,136, 7,178,185,190, 36, 33, 68, 58, 68,124,189,143, 29,168, 42, 64, 57,162,234,139,194,227,201,
-227, 96,119, 62,206, 20, 88,114, 91,176,154,179,161, 67,163,143, 13, 64,183,175,187, 27, 63,157,105,109, 32,242,128,197,101,229,
-153, 74, 98,172, 85,235, 37,207, 3, 34,183,246,139,200,219,165, 2,208,176, 35, 82,215, 33, 31,173,178,160,232,145, 32, 70,119,
-179,104,231, 25,231,220, 25, 75,119,203, 76,167, 68, 11,146,204,169,107,100, 74, 77, 27, 37, 60,215, 37, 44, 2,135,184, 37,237,
-120, 50,210,143,165, 57, 38,254, 22,228, 68,111, 12, 75, 23, 22, 4, 49,150,208,101,206, 25, 70, 18,170,220,209,112, 30,223,194,
-128,127,171,198, 58, 27,240,138,193,253,175, 67, 76,255, 63,224, 52, 54,184,177,182, 77, 37,234, 12, 88,184,234,156,233,116,190,
-108, 60, 34,139, 43,249,209, 2,231,226,220,226, 60, 26, 75, 21,217,180,161, 42,111,245,178, 54,124,237,194, 19,137, 23,100,208,
- 11, 59, 40,105, 61, 34, 60,242, 1,125, 43,188,163,133, 44,150, 40, 55, 88,103,124,230,170, 90, 73, 5, 61,138, 94, 37, 39, 31,
-106,251, 4, 62, 3, 44, 79, 99, 32, 44,127, 29,214,174, 36,159,243, 89, 70,189,140,192, 33,180, 81, 86, 27, 71,220,203,107, 80,
-150, 30, 87,245, 0, 65, 5, 91,100,147,146, 53, 77,228,240, 25, 82, 36,122,110, 38,142,213,141,115, 24, 57,182,147,176,247, 28,
- 61,148,188,106,166, 93,116, 30,168,120, 71,255,208,153, 66,170,171,194,123,107, 56,161, 34,179,220, 9,181, 3,186, 87,242,202,
-182,123,209,121,211,246,202,189, 84,219,125,221, 58,107, 95, 40,115,101,210,158, 10,206, 58,146, 33,153,174,231,205, 25,114, 76,
- 50,249, 1, 12,251, 64, 11, 16, 48,121,141,148,214, 1, 15, 40,181,242,225,118,162,213,189, 60,137,188, 91, 33, 52,249,146,168,
-119,171, 80,204,137, 30,148, 2,219, 85,232,131, 33,186,133, 90,205,145, 51,110, 32,236,134, 86, 46, 56, 30, 28, 35, 18,207, 86,
-210,207, 98,238, 11,239,221,229,250, 30, 35,115,226, 13, 4,187, 30,159,231,155,212, 68, 75, 61,169, 40, 84, 81,151, 85, 93, 33,
-137,100, 41, 29, 82,120, 89, 42,194,152, 11,226, 59,208,187, 67,160, 81,113,209,216, 17,159, 87, 93, 55,160, 50, 33,129, 64, 56,
-135, 68,135,249, 72,111,242, 85, 83,242, 84,176, 3, 35,210, 74,207,122, 62,125,224, 18,191,240, 10,112, 47,147,107,197,233,200,
- 85,197, 35, 83, 6, 81,161,223,223,229, 42,105, 80, 79, 50, 72,103,240,249, 29, 3, 59, 54, 37, 65, 33, 2, 23,120,180,230, 90,
- 10, 78,126,246, 42,247,178,105,144, 84, 92,227,217, 91, 86,110,172,151, 11,226,124,254, 66,237, 47,191,190,120,245,234,238,203,
- 95,254,202,215,255,142,247, 62, 15, 54, 54, 83,187,168, 18, 74,238,105,161,170,158, 76,148, 33, 92,253,252, 58,244,221,237,225,
-120, 8,143, 77, 57,142,248,229,172, 31,254, 61, 97,123, 57,159, 44,130, 57, 97,103,210, 50,202,146,232,231, 83,121,233, 15,204,
- 12, 30,217, 87,177, 27, 15,209,213,223,126,188, 22,191,190,125,247,199,237,239,125,125,172, 91,187,156, 69,246, 53, 4,213, 33,
- 81,184,131,111,244,228,243,116,204,237, 83,246,170,167, 63, 11,171,197,139, 88, 59, 76,245, 73,181, 38,127,190,171, 95,249,155,
- 55,223,239, 69,253, 0,126,165,207, 89,204,100, 43, 96, 39,172,234, 80, 23, 66,211,155,171,193,206, 79, 20, 72, 69,206, 77,146,
-228,142,152, 0,132,163,165,192,152, 98, 23, 42,235,160, 7,150,189, 16, 34,179,254,244,237,171,235, 63,223,155,249,169,148, 22,
-129, 61, 8,237, 71,139, 37, 5, 18,138, 33,219,168,163, 5,179, 26,202,203,230,155,183,111, 94,191,251,225,163,250,248, 33,220,
-255,147,230, 62,128, 26, 35, 36, 57,202,249,114,192, 2, 20, 61,231,192, 59,238, 42,172,173,103, 21,198, 41,181,194,117,173,178,
-136,195,216,127,145,118,189, 5, 6, 43, 93, 18,165,137,149,148,115,245, 13, 97, 87, 4, 32,149,237, 11, 69,110,144,187,195, 70,
- 3,135,126,247,254,248,211,109,254,220, 93,124,218, 74,181,145,172,184,142,248, 21,201,180,141,182,210,129, 47,206, 56,168, 58,
-182, 64, 8,120,254,114,212, 75, 83,152,207,156,166, 27,149, 75,113,216, 54,182,109,186,255, 4, 32,233, 90,118, 36, 39,130, 96,
- 85,185, 30,118,181, 61,175,101, 37,102,197, 30,128, 3,172,184,128,180,203,141, 19,154,207,224, 95,248, 62, 56, 51,210, 46,226,
-128, 52,160,101,152,221,153,110,183,237,118, 61,137, 48,199,150, 90,221,150, 93,153, 25,145,206,140,208,224, 18,200, 71, 14,249,
- 62,118, 30,132, 99, 57,229,210,156, 89, 60,161,176,119, 22,148,166, 31, 70, 51,186, 28,138, 60, 63,222, 27,110,179,119,237, 97,
-139, 45, 23,128, 16,122, 80,196, 52,201,246,162,167,212, 20,152,121, 53, 22,213,104,185,192, 89,222, 38, 37,154,166, 85,160,207,
-214, 43, 46, 14,228,226,179,151, 19,245, 56, 70,100,219,246,233, 2,149, 7,255, 21, 15,225,195,195,220,123,240,237, 68,196,164,
- 21, 10,223,244, 24, 54,193, 23,142,115,138,118,161,249,215,147,141, 50,162, 76,176,185, 16,244,161, 41, 59,112, 97, 95,123,156,
-237,180,198, 82,193, 92, 29, 48,186,154,130,240,141,225,118,109,155,174,148, 1,211, 85,173,213,145,162, 54, 96,191,117, 81,187,
- 46,162, 82,121,100,122,164,232, 46, 94, 46,136, 97,203,206,113,226, 46, 56,127,109,143,186, 65, 12,136,167,179,215,101,112,164,
-125,153,235, 59,106, 37, 33,174,146, 62,161,120, 34,169,165,143,131, 9,113,183, 74,182, 94,193,174,242, 10,204, 37,250,181, 17,
-157, 94,136,127, 17,167, 45, 8, 16,146,142,244,170,106, 99, 87, 77, 41,172,255,181, 47,139,222,225, 22, 46,106, 65,238, 80, 92,
-125, 2, 44,167,165, 90,148,163, 4, 25, 62, 1,198,208, 38,161, 0,184,168,200, 87,129, 28,167,225,222, 12,206,181, 66, 62,159,
- 66,173, 17,151, 84, 86,124,125, 49,213,114,146,117,169,237,149,158,167,152,143,149,234, 8, 6,191, 35,179,250,107,253,251,159,
-234,116, 4, 97,236, 26,131, 82,220,138,124,224,142,206,122, 89,155, 99,173, 29,117, 88,213,137,251, 88, 37,176,184,166, 17, 37,
- 59, 30,116, 30,142,228,175,184, 41,121, 18,125, 95,103,199,181, 73,206, 10, 1,210,171,140,171, 5, 69,159,105,198, 39,188,139,
- 11, 71,211,117,215, 73, 61,112,223,174,251, 76,244,214, 1,116,248, 43,119,249, 76,202, 79,116, 24, 42, 57,202,208,162,164, 2,
-224, 74,106, 77, 6,132, 74,131,170, 75,165,117, 65,121, 86,201,253, 63,197, 87, 23,123,154, 89, 3,196,130, 19,210, 13,226, 9,
-144, 71,208,128, 71,167,178,108,106,160,205,166,194,119,226,102, 26,229,151, 55,189, 73, 17,185,162, 36,206, 16, 26, 85, 30, 36,
- 21,112,182,249, 24,165,117,102,252, 23, 49,211,203, 90,166,109,124, 22, 17,183, 19,106,101,251,133, 91, 20, 52, 3,218, 76, 5,
- 43,213, 8, 56, 72,179,101,140,178, 9,126,214,196,183,250, 92, 89,151,148, 39,223, 88,132, 92,241, 97,226,212,223, 12,102, 94,
-193,132, 36, 51,143,137, 72,150, 8, 17,230,120,224,244,109,206,198,160,234,178, 27, 20, 29,112, 37,135, 12,145, 49,247,224,154,
-137, 90,186,229,223, 77,100,128, 38,194, 72,232,244,138, 71,233, 72, 2,135, 67, 31,143,162,119,128,158, 39,106,116, 7,212, 49,
- 1, 14,182, 22,182,209, 44, 43,127,179,120,170,185, 92,244,218, 94,136, 83,161, 18, 55, 69,237,145,238,187,180, 18,106,149,171,
-103,157,254,226,230,221,243,175,127, 75,198,231, 59,238, 98,116, 8,227,148,183, 58, 79,131, 36,170, 48,229,189,136, 95, 14,231,
-215,215,119,227, 50,141,163, 1,130, 85, 56, 7,107,157, 11, 27, 85,212,169, 78, 11, 69,249,150,134,195,115, 93, 50,132, 14, 85,
- 33, 77, 94,121, 65, 59,128, 71, 68,189, 72,103, 31,238,119, 47,253,237, 79,223,223,252,252,238,229,253,251, 95,135,110,208,122,
- 33, 50, 1,183,243,168,103, 93,255, 72, 13,252, 48, 0, 44,199, 33, 81, 76, 13,135, 27,113, 14,246,233, 40, 67,185, 56, 35, 30,
-155,143,223,189,121,197,174,227, 50,210,109, 79, 34,218, 54,139, 59, 54,187, 11,169, 28,119, 97,136, 12,114,176, 60, 60,235,156,
-193, 91, 17,228,129, 83,205, 96, 69, 70,110,253,110,122, 58,149,176,195,163, 87, 21,241, 25,238, 95,124,245,250,207,183,223,204,
-211,173,102,249,182,179,205, 54, 36,117,108, 63,198, 99,195,149,225,152,214,203,235, 87,159,255,112,243,233,139,243, 91,113,247,
-199,233,253, 24, 98, 71,216,158,214, 52,175,236,190, 53,182,156, 2, 85,122,233, 74,118,153,205, 82,165,201,231,217,182, 45,184,
- 65, 41,180,239, 27, 6,147,102,186, 27,129, 30,101,142,116, 6,246, 93,101,146,198,137, 21,245, 4, 97,128,218,211, 84,123,116,
-118,114,242,108,104,191,125, 59,254,248,203,131,116,226,119,239,192, 36, 26, 84, 50,190, 41,146,213, 3,249, 25,225, 11, 78, 87,
-107, 99,121, 46, 78, 15,219,108,111,202,131,111,212,226, 75,137,225, 72, 91,168,213,117,182, 51, 19,192,216,127, 2,112,116,118,
-171,146, 19, 81, 20,174, 74,165, 42,157,206,233,238,115,230, 28, 70, 17, 84, 16, 69, 65, 80, 16, 28, 16,230, 66,241,214, 7, 80,
- 95,192, 11,223,209, 39, 80,188, 19,230, 70,116, 96, 64,240,252, 72,119,167,147,170, 84, 82,174, 47,208,244, 85, 55, 36, 84,237,
- 93,107,237,218,123, 45,247,243, 79,223, 23,227,129,208,244, 75,247, 0, 28, 83,143,136,150, 36, 55, 9,195,183,231,212, 44, 73,
- 32,119,234,183, 33,220, 91,241,160,188,217, 14, 92, 22,152,164,127, 13,147, 88,120, 8,173, 18,159, 32, 68, 9,117,232,230,197,
-183,183,235,224,162,105, 20,224,190,107,219,210,184, 6,199,226,141, 86,225,138,254,213, 88,215,141, 11,136,231, 43,106, 70, 69,
-233, 92,185,102,110, 49,114, 45,135, 94,244, 7,253,201,168, 4,230,185,111, 17, 7, 31, 70,119, 78, 4,242,228, 76, 18, 76, 31,
- 3, 34, 64,142,242, 43,214, 20, 20,249,133, 72,115,112,155,201, 15,130,236,151, 76,237, 37, 42,216, 3,174, 8,200, 2,213, 97,
-106, 82, 67, 92,120, 91,119,202,164, 38, 71,186,155,107,250, 30, 86, 85,223,224,113, 49, 93,144,216, 39,245, 57,144, 30,147,212,
- 90,143,181, 10,109, 49,146, 92,232,196,247,107,109, 26,181, 37,139,148,230, 80,139, 90,196,171,115,162, 11, 84,105, 42,135,122,
-167, 12, 9, 65,212, 47,240,156,194, 97, 3, 72, 88, 97,197,132,142,148, 19,223,106,156,162, 26,250,228, 4, 96, 17,149,195, 72,
- 68, 57, 69, 27,144, 41, 26, 75, 31, 15, 38, 58,202,251,136, 32, 40, 63,172, 98, 48,136, 16, 41,217,142, 12,201,164,161, 18, 79,
- 49, 46,139,109,142, 21,226, 32,193,196,234, 84, 48, 50,205, 54,197, 65,235,228,211, 92, 82,153,155,119, 9,131, 95,205,178, 5,
-180, 83,146,211,233, 71,127,133, 13,112,227, 5, 59, 8,229, 70,133, 48,157, 49, 98,200,243,153,254,194,252,152, 21, 82, 39, 68,
- 34,230, 26, 71, 8, 83, 30, 13,179,241,131, 29, 42, 12,152,180,255,240,219,177,165,222, 25,120,210,198,111,182, 97,179,183,203,
- 45,250,179,135,107,119,253, 78,181,223,215, 55,207,237,213,123, 27,119, 88,184,163,216,214,165,117, 84, 20,180,184, 84,186,237,
- 66, 83,218, 30,165,207, 41, 97,158,142, 59,227,110, 45,143,156, 13, 99, 11,122, 42,116, 72,152, 1, 7, 69,111, 86,174, 68, 82,
-103, 53, 23,220, 84,214,154,191,144,219,140, 78, 17,163, 6,226, 63, 88,206,173,104, 19, 13, 6,108, 48,249,140,171,240, 40,175,
- 77,177, 29,243, 12,189,109,191,142,193,103,230,227,168,207,156,192,245, 72,175,174,237, 47,122,164, 5,145, 24, 42, 90, 19,146,
-222, 40,183, 38,186,254,233,125, 73, 8, 71, 48,104, 54, 42, 1,122,164,224, 45,194, 29, 41,105, 69,196,170, 75, 21,107, 17, 67,
- 29, 95,220,227, 14, 34, 87,115,140,218, 97,198, 81,213,193,223, 28,251,162, 85,193, 68,187,160, 89,176, 18,182, 8,198,205,125,
- 20, 94,241,199,232, 21,208,226, 34,250, 66, 81, 48, 22,152, 12,179,161,188, 40,197,159, 98,142,243,220,101,223, 56,209, 63, 87,
-109,173,221, 98,105,184,209,193,222,185, 25, 13,246,180, 15,243,221,199,239,219,207,190,123,117,243,226,205,216,187,248, 48, 86,
-125, 85,225, 70, 51, 79, 33, 86,194, 19,151,226, 16,240, 75,249, 36, 34,252,226,230,173,103,207,126,239,159,222,140,143, 24, 1,
-150, 33, 10,246,136, 57,187, 56,184, 62,214, 12, 33,181, 92, 51, 11, 27, 79,212, 20,180, 7, 39,166,147, 46, 43,155,199,185, 72,
- 60, 27,211, 63,115,254,224,237,235,135,225,211,223,254,122,117, 37, 52,112,169, 39, 65, 43, 46, 56,235,176, 73,126, 73, 32,132,
-117, 66, 16,242,207,208, 58, 45, 36,173,157,195, 93,214,222, 20,144, 59,253,187,252,240,227,151,183,183,247,105,122, 16,178, 50,
- 99, 94, 3,189,112, 84,206,193,114,232,162,224, 65,215, 19,138, 63, 43, 37, 67,210,149,156,107, 46,206,250,132,104,153,173, 71,
-184,175,199,178,107,202,229,104,243, 88, 62,252,162,185,251,228,249,253, 63, 33,222, 63,185, 56,159,226,252,120,124, 74,121,232,
-171,209,135,253,225,238,163,175,191,249,252,171,151,211,141,249,115,250,251,143,203,113,154, 78, 78,232,183,231, 30, 39, 79,125,
- 85,254,107, 5,172,120,199,174, 34,245, 30,118,136,207,116, 10, 44,167,205,205,116,138, 16,152,158, 77, 48,164,227,118,219,163,
-248,217,136,178, 89,158,103, 17,254, 81,180, 9,182, 50, 46, 42, 36, 82,119,135,238, 16,174,191,125,157, 95,254,242,116,154,202,
-235, 93,195, 56,165,232,132, 96,164,128,133,215,127,171, 78,185, 79, 40,214,215,217, 40, 52, 15,230,178,221, 5,159, 92, 16, 1,
-215,214, 93, 58,127,244,182,180,231, 86, 25,184, 75,118,155,226,255, 2,144,116, 45, 59,114, 20, 65,176,222,213,143,121,236,174,
-133,141,199, 90,224, 98,139, 3, 66,248, 55,184,112,229,194,103,114,228,192,141, 51, 23, 16, 8, 25, 36,144,151,149, 89,239, 76,
- 79,215,116,189,186,137,104,159,119,118,186,167,171, 51, 35,162, 42, 51,210,208,134,138, 13,156,130, 51, 63, 90,207,193,111,114,
-186,148, 25,164,208,196, 27,223,158,182, 89,159,119, 42,166, 22, 55,165,110, 6, 16, 6, 8, 3,219,180,250, 17,193, 28, 64,241,
- 84, 65,194,167,161,156,111, 88,148,182, 29,244,120,235, 26, 13,157,169,244, 86, 65, 25, 85,186, 56,119,174,199, 61, 1,225,170,
- 85, 44,210,141, 64,166,105,191,128, 26, 39, 8, 12,215,187,121, 25,200, 96, 93, 63, 61, 84,159, 73, 16, 20,160, 67, 46, 62,136,
-212,211, 10,121, 65,110,119, 49, 14, 35, 27, 82, 52, 36,138,203,238,132,151,180, 6,117, 86, 55, 32,199, 91,118, 17,245,231,121,
-212,125, 59, 55, 46, 64, 96,217,246,106, 25,135,153,246,242, 27,145, 71, 13,100,215, 94, 25,173, 18, 40,110, 39,253, 14,249, 26,
-210,102, 97, 14,206,141, 74,185,180,142,227,157, 32,133,247,116, 49,160, 13, 98,102, 93,184,236,245, 2,249,103,103,230,194, 11,
-231,247, 84, 90,179,104,206,175,115, 98, 25,216,195,212,209, 25,133,133,189, 51,159, 63,162, 1,172, 8,106,169, 3,245,176,244,
- 23, 13, 90, 92, 23,207,126,102,197,126,176,190, 70, 90, 29,224,177,178,110,135,155, 69, 8,196, 80, 30, 33,172, 13,231,166, 33,
-199, 3,254,158,182,250, 33,201, 73,211,208,210, 44,171,207,149,152, 88,163, 36, 72,242,202,158,172, 53, 64,195,113,184, 17, 27,
- 72,147,157, 76,147,245,169,230,225, 52,118,170,180, 34, 2,200,255, 83,229,193,142, 0, 82, 80,129,106,145,236,216, 24,234, 23,
- 44, 14,253,242,196, 20,105,154,218, 84, 13, 46,194,253, 95,252,130,100,135,149,250, 64,110,211,201,194, 29,223,179, 5,164,156,
-132, 15,218,207, 37, 32, 7, 64,137,209,162, 83, 75,112,110, 60, 75,173,119, 74, 94,122, 57, 54,114,163, 69,191,149,110,103,154,
- 94,239, 15,234,234, 74, 55,128,110, 3, 85,226,230,173,164,201,114, 99, 89, 80, 14, 18,196,237, 65, 54, 96,176,183, 15, 2, 12,
- 32,198,153,186,129, 45, 78,116,149,160, 39,199,106,107, 96,106,221,175, 59, 39, 31, 74, 91, 72,168, 89,242,198,227,205, 73,177,
- 16, 63, 84,209,211,102,217, 71, 62, 76,158,165,108,215,122,246,160, 21,205,112,215, 49, 44,121,221,199,215,107,193, 35, 13, 32,
- 74, 33, 82, 10,223,242, 59, 63,212, 35,229,200,210,125,208, 36,150,211, 10,202,111,220,134,162,141,116, 13, 81,175, 23, 64,184,
- 0,123, 75, 12, 17,242,156,202, 26,127, 79, 42, 31,133,103,177, 2, 82,118, 2,111,161, 64,144,179,207, 60,126,159, 22, 31,243,
-114, 41,208,210, 39, 44,227, 59,186,147, 78, 81, 52, 72, 25,116,147, 1, 16, 45, 27,161,166, 32, 78, 35,251,200, 51,253,124, 10,
-101,224,162, 31,161,240,230,243,178, 14, 60,183,129,176,143,203,141,149,231, 28, 72, 14, 3,128,110,230, 24,112,142,199,234,160,
-225,140, 1,161, 97,163, 58,125, 54,124,191,216, 39,224, 1,178,235,205,179, 79,158, 60,124,245,205,239,254,197,253,187,127,180,
- 25, 54,116,117, 35,243,133,176, 75,134,246, 64, 44,206,196, 69,172, 29,101,109,234, 71,135,235,187,148,126, 59,221,141,117, 90,
-234, 16, 32, 11,156, 29,145, 94,105,120,127,210,186,223, 50,127, 26,118,216,203,176, 30, 87,131,221, 41, 30, 87, 95,250,212, 0,
-220,178, 82,155, 22, 42, 35,134,115, 62,254,244,245,235, 47,190,255,241, 69, 14,111,228,181,157, 85, 46, 30, 28, 44,167,136,247,
- 8,228,180,248, 51,189,116, 69,139,255,106,221,118,153,218,139, 57, 74,249, 86, 15,200, 77,225,242,249,167,175, 94,190,186, 18,
-245, 87,153,192,244,102,197,193, 66,146,238,144, 45,150, 11, 84,181,172,187,224, 88,105,207,247, 2, 16, 15,196,187,112,150, 36,
- 62,160, 56,170,199, 35,254,102,109,109, 0,117,172, 54, 42,235, 55,254, 48,205,162,164,187, 63,111, 95,234,111,191,251,242,120,
-121,125,255,230,252,254,145,245,215,125,231,158, 29,250,231, 7,173,196, 73,136,159,197, 95,191,228,123,196, 0, 2, 83,147,181,
- 15, 41, 65, 61,118,109,134, 10, 48,136, 84,233, 27, 69,154, 50, 27,221, 8,118,105, 3,181,173,167,255,160,140, 50,117,220, 55,
-107,111,184,222, 93,203, 38,206, 18, 40, 88,216,158, 95,171,233,178,218, 53,211,104,194, 34,174,221,238,234,144,235,237, 15,127,
-127,252,199,241,237,212,252,251, 84, 15,102,254,140,219,117,134, 39,129, 52, 99, 50,114,116,247, 8,220,102,222, 59, 30, 58, 45,
-115,244,207,249,213, 27,128, 93, 50, 35,231,175, 10, 78,202, 16,109,140,221, 89, 70, 32,136,251, 95, 0,146,174,108, 71,146, 26,
- 8, 86,249, 40,187,142,174,158,222, 89,113,136,167, 69, 2, 86, 72,124, 1, 63,192, 27,127, 15, 72, 72,104,197, 50,128,208, 72,
-211, 83,151, 93,229,139,136,218,199, 86,119,171,213,101, 59, 51,194, 25, 25,137,228,128,189,146,192,248,119, 29,205, 12,208,160,
-149,246,125, 26, 86,128,216,171,210,229, 5,201,244,112, 89,141,226,228,166, 84, 32,188, 73, 1,216,124,190, 40, 96,153,116, 25,
-125, 18,173,112,220, 89, 73,183, 99,110, 43,163, 3,158, 99, 12,114, 52, 1,156,238,205,174, 82,175,143, 65,118,142,213, 7,144,
- 47, 70, 58,179, 6,182,243,225, 0, 0, 99,231,214,165, 89,132, 37, 25,160,187,178,118, 78, 63,139,210,136,152,220,177, 1, 10,
-121, 35,169, 97,186,219, 54, 20,195,130,164,226,120, 70,192,227,213, 52,216,114, 34, 32, 30,166,141, 86, 93,162, 7,195, 74, 6,
-132, 92,177,229,209,141,199, 20,248,140, 46,141,104,194,209,117,182, 45,196,218, 75,210,150,115, 4,106,222,128,151,202, 70,197,
-149,200, 2, 48,235, 12,245, 14,207,203, 55, 32,198, 44,177,177,217,231,149, 28,130,230, 90, 93,166, 32,228,142, 24,127, 32,156,
- 12,117,116, 56,219,188, 55, 3,240, 5,227, 73,231,216,164, 6,176, 79,241, 30,143, 18,128,178,211, 12,250,232,229, 3, 85, 37,
-200, 57,156, 77,125,113,194,115, 54,135, 40,137, 14,106, 28,175, 73, 40,137,124, 31, 60,176,106,174,101, 35,176, 97, 38, 91,238,
- 30,127,143,179, 37,176,164, 17, 75,113,108, 86,201,187,194,234,128,110,150,125,226,244,249, 98,197,124,202, 25,214, 82,166, 24,
-134, 76,199, 19, 16,156,141,101,175,102,150, 72, 12, 91,162, 54, 9,251, 14,152, 65, 87,187, 60,173, 29, 56,185, 26,168, 44,209,
-172, 30, 48,119,162,117, 53,208, 95,120, 13,236,247,212,205,194,126, 88, 33, 56,244,135,205,206,134,227, 73,171,208,177,209, 51,
- 78,108,249,225,235, 75, 93,245,185,222,217, 99,192, 46,157,177, 26,129,218, 31,196,240, 57, 54, 82, 61,220, 84,247, 64,141, 64,
-238,101,176,165,110, 3, 73,138, 37, 22, 38, 76, 38,216,103,198, 57,235,162,192,122,155,250, 20,124,155, 83,139, 72, 25, 68, 98,
-252,229, 26,237,231,157,121, 60,105,225,105, 87,198, 82, 13, 77,216,233,228, 66,223,172,150,108,188, 62,187, 80, 41, 88,228, 61,
- 19, 47,158, 78,191,121, 89, 22, 54,138,126,170,214, 82, 98, 4,202,148,104,236,136,216,141, 95,161, 13, 55,160,108,226, 88, 66,
-201, 27, 48, 50, 4,233, 79,255,153,138, 65, 63,178,236, 10, 92, 86, 5, 74, 71,217,200,108, 10,175, 8, 74, 95,249, 82, 57,183,
- 3,201,243, 25, 13,156,217,132,197,119, 18,191, 79, 65,122,235,121,161,132,184,108, 98,186, 74,247, 18,234, 93, 88,143,109, 81,
-246,117, 95, 76,217,183,170, 9, 5,100,240,240, 28,238,196, 97,162, 8,124,133,141,241, 13,240, 56, 72,222,182, 39, 98, 7,202,
- 50,237,153,239,128,154, 71,234, 13,137, 89, 53, 19, 31,101, 64,192, 24,248,156,229,187,192,240,137, 94, 60, 61, 62, 11,104,114,
- 12, 95, 93, 46,239,126,248,243,237,143,127,228,239,214,244,143,237,112, 28, 70,187,223,107, 58, 12,182, 21,133, 96,171, 13, 20,
- 87, 34,130, 92,164, 11,254,175,161,249,214,118,243,226,166,196, 26, 92,100,222,197, 62,151, 56, 29,134,189,152, 57,167,121,137,
-253,236, 23,122,242, 91, 67, 81,241,182,182,205, 98, 88, 67,167, 11, 66,202, 57,115,242, 27,152, 78,173,158,255,219,190,124,255,
-251,237,139,219,211,175,191, 61,150,146,215, 40, 31,155,149,210, 46,106, 43,105, 67,180,196,114, 83,108,163, 5, 21,247,133,181,
- 75, 41,205, 85,200,105,241, 49,254,252,211,215, 85,181,132, 57,158, 94,151,115,181,209, 99,147,245,110, 16, 11, 79,168, 70, 32,
-207,190, 5,197,198,245, 61,178,125, 18,219,195, 99,149, 79, 43, 46,146, 46,122, 62,114, 16,171,228, 68, 50,206,246, 0,195,104,
-107,241, 50,237, 79, 31,170,199,233,106,222, 94,191, 71,142,111, 79,117, 44, 88,213,135,234,254,241,248,251,200,139,207,133,210,
-150, 93,203,112,207,199,186, 51, 91, 3, 35,121,164,245, 2,146,132,127,219,183, 55,219,181,157, 1,108,105, 65,209, 68,234,240,
-125,125, 60, 31, 11, 32,175, 95, 23,132, 57, 17,128,110,196,181,110, 20, 78, 92, 86, 59,229,108,199,168,156, 80, 15, 69,235,182,
- 69,206, 51,223,252, 59,191,251,101,105,158,252,199,139,117, 93,249,236,202, 81, 28,145, 3,128,232, 78,155, 7, 4,184,202,247,
- 8,211, 25,187, 86,243,185, 3,126, 35,242,170, 87,143, 99, 36, 15,192, 4, 61,108,121, 65, 78, 43,186, 41,143,136, 26,198,233,
- 80,255, 47, 0, 73, 87,174,228, 72, 17, 5,187,206,190, 37,205, 73, 16, 16,107, 97, 96,173, 5, 46, 63,128,189, 95,180,255,135,
- 65, 4, 6, 56, 28,193, 26,236,174, 70, 26,245, 89, 87, 23,153,189,222, 68, 40,164,145,170,235,189,151,249,174, 4,162,214, 17,
- 52, 51,180,189,172,198,114,225,244, 11,222,209, 45,199,170,184,112,142,246, 41, 78,215,182, 2,142, 24, 91, 41, 6, 93,155, 82,
-111,171, 95,131, 0, 63, 45, 78,194, 92, 98, 95,145,214,182,134,173, 70, 65, 13,115,105,112,107, 14, 93, 3,126,120, 56, 58,132,
-251,227,201,194, 65,154,153,122,231, 1,244,197, 50,179,217,173,237, 10, 34,231,138, 87,234, 75,178,128, 12,224,182, 5, 55,201,
-210,172,240,180,217, 3,158,106,149, 98,233,156,247,118, 99,115, 6, 32, 16, 14,164, 10,227,106, 65, 72,239,179,180, 54, 53,109,
-177,204,114,120, 41,186,211,216, 95,213,120,135,176,227, 79,147,112,217, 89, 54, 93,105,218, 2, 2, 88, 53, 57,186,143,131,146,
-117,176,137,211, 82,190, 7, 39, 86, 53,101, 47,217,227,179,177,159, 23,252,205, 1,135, 72, 68, 54,166,113, 22,174,181,247,187,
-103,113, 37,254,134, 37, 91,195, 66, 61, 59,208, 76, 22,175, 23, 93,117, 32, 4, 41,213, 66, 1,195, 3, 44, 21,172, 48,179,186,
-234, 44,219,197, 60,229, 92, 15,166,144, 33,249, 62, 38, 7,243, 72,165, 69,140, 33,177,244, 76,140, 81,178, 37,112, 63, 64, 29,
-166, 85,119, 8, 28,212,233,202,102,204,193, 28,231,160, 84, 53,113, 48, 46, 84,251, 24,230,200,124, 39,136, 94, 26, 86, 60,128,
-100,235,146,210,207,107,186, 20,246, 17,255,171, 12,125, 18,212,230,233,182,226,146, 74,106,204,133, 99, 94, 6, 33,199,178,209,
- 77,182,211,153,186, 56, 27, 85,165, 96,122, 66,223, 36,155, 42,185, 8,129,219, 64,120, 84,147,130, 61,115,153,161,150,219,203,
- 86,188,194, 32, 3, 55,253,116,226,118,230, 42,126,209, 20,249,172,234,227, 62,106, 10,242,226, 13, 39, 19, 31, 41, 26,220, 86,
- 86,119,169,121,192, 35, 86,245, 41, 29,224,220,241, 61,172,137,192,119,189,202,173,219,123,145,120, 76,108, 80,130,155, 16, 53,
-115,166,233,138,151, 89, 52,165, 56,125,189,109,156,123, 37, 66,103, 29,196,239,112, 27,238, 85,239,254, 26,190,176, 18,136,152,
-121,225, 46, 62,238, 40,224, 24,212, 78,207,217,241, 45,246,185, 83,120,220,189,238, 58,211, 71, 51,155,157,190,144,246, 93, 93,
-207,236,123, 44,185,141,128,208,127, 23,223,219,223,181,114,184,137,168,168,102, 69, 4,145,131, 74, 13, 21, 91, 33,225,120, 60,
- 75, 29, 0,147, 97, 23,124, 7,239,202, 48,168,162, 68,200,245,179,199,235, 50,178, 75,143,205,238, 75,230, 44,115,250,178,199,
-187,136,147,152, 35, 59,105,156,203,114, 13, 96, 63,240, 75,190, 1, 38,230, 5, 74, 55, 86, 70,169,186,237,115,128,179,163,238,
- 48,144, 93,176, 96,224,193, 12,201,202,109,228,215, 12, 5,119,152,238,177,102,222,117,164, 84,102, 3, 17,108, 2, 63, 29,254,
-106, 18,236, 2, 16,204,238,104,166,127, 31, 77,108,242,214,249,218,164,246,171,186,121,122,251,233,187,159,255, 18,207,226,252,
-103, 5, 50,199,123,109, 62,227,177,168,229,117,115,167, 8, 55,127, 6, 20,189,224,231, 92,214,193,156, 70,255,240,166, 86,149,
- 90,174, 31,124,166,176,210,204,237,104,179,137, 83, 31, 87, 95, 3, 5, 0,230, 74, 85, 46,149, 14,136,102, 5, 15, 10, 14, 68,
- 44, 44, 24,186,150,223,174,206,204, 58, 1,154,129, 65, 72,152,231,100,166, 63,222,253,248,211,251,223,126,125, 19, 41,157, 25,
-207, 60,135,138,203,213,165,214, 46, 51, 53,163,213,234,243, 29, 80, 15,149, 57,197,156,183,228,194,236,202,167,227,219, 31,158,
-139,226,247, 36,110, 64,228,128, 17,187,150,233,170, 16, 65, 96, 65,220,182, 67,189, 48,242,106,166,107,152,168,148,123,105,142,
-221,211,128,245,139, 14,116,114,153,173,220, 26,204, 26,167, 21,141,229, 68, 25,192, 85,241,186,165,229,150, 63,250,216,124,204,
- 10,215,126,221,213,118, 44,187, 93,247, 61,253,220,102,192, 1,121,234,182,204,139, 79, 19,238, 97, 71,177, 95,152, 96,117, 56,
-125,125,127,232,106,219,125, 63,139,242,159, 23,243,225,242,237, 8, 12,195,253,132,112,243, 94,151,237,125,249,239,163, 25, 0,
- 51, 15,224,180,176,211,246, 33,154, 42,111, 35, 53, 19, 98,107, 27,247,128, 15,242,223, 12,235,221,223,215,240,203,127, 47,186,
-190, 62,203,160, 76,255,105, 53,224,191, 68,150,102, 88,110,112,204,119, 32,107, 25,128, 28,116,172, 88,202, 20, 27, 3,116,208,
-155, 38,171,184,242, 22,131,237, 58,121,204,159, 29,162, 98,193, 5,185, 37, 30,153,172,189,214,255, 11, 64,211,213,244,184,109,
- 67, 65,126,136, 20, 41, 89,222,100,145, 6,109,138,162,135,182, 64, 15,249, 15, 65,175,253,253,189,245,216, 54,200, 54,200,238,
-122, 45, 75, 20, 63, 59,195, 34,123,242, 97,109, 89, 22,249,222,204,227,123, 51, 72,184, 19,248, 92,165,136, 72,144, 84,228, 29,
-240, 12,199, 21, 0,209, 77,121,219, 0, 49,252, 82, 54, 32,150, 19, 0,142, 51,141,122,145,170,133,149,191,197,194,249,212,108,
-144,104, 45,152, 93,156,104, 97,172,219, 16,175, 54,126, 50, 51,232,188,218, 53,144,247, 29,146,207,108, 31,165,152,152,177,163,
-162,108,198,245, 98, 47,154,142,166, 22,203, 36, 6,243,140,192,141,253,164,243,205,140,249, 96,121,180,222,182, 90,185, 57,145,
-157,128,243,199,117, 28,101, 74, 57, 34,152, 89,157, 86,147, 47,217,164, 43,242, 42,128, 81,181,163,220,162,207, 7,141,131,163,
- 38,241, 8, 34, 3,149,208, 73,108, 1,180,141,172, 66,143,216, 17,116,213,145, 8,225, 99, 51,195, 42, 85, 84,236,139,241, 20,
- 47,111,230, 0, 72, 86,207,184,113,196,146,146, 61,143,205, 82,165,181, 50,168, 59, 86,160, 88, 66,123,161,128,160, 50, 67, 39,
-196,216,150,134,206,213, 88,238,121, 69, 72, 90,135,222, 78,227, 44, 89,210, 20,216, 14,245,212,138, 95, 26,107,197, 0, 72,165,
-104,190, 67, 70,218,224,152, 57,114, 92, 29, 11,179, 50,206,130,231,208,199,207, 73,119, 12, 25,155, 67,131, 36,203,225, 65, 2,
-216,236,248, 60,211,123, 36,104,100, 49,164,164,215,163, 43,207,108, 67, 4,176,139, 71,152,181,222,198,248,132,252, 3,246,121,
- 32,192, 20,242,131, 91,192,110,163,140,229, 38,232,244, 24, 26,168, 27, 91,161, 11,222,187, 10,241, 78,104, 75,211, 60,246, 63,
- 54, 54,115,233, 40,147, 10, 52, 44,153,168,158,153,227,104,246,156,135,188,205,184,120, 57,171,182, 42,118,169,214, 21,217,146,
-147,178, 78, 33,247, 84,121,174,224, 56,248, 61,207,192,155,247,154,189,229,179, 88,220, 48, 47,218,190,209,242, 68,215, 84,122,
- 88,207, 69,117,243, 80, 81,145,210,168,162,213, 70, 60, 40, 4,254,192,174, 84, 86,167, 89, 42, 44,228, 73, 32, 76,212,209,165,
-104, 89,243,253, 60, 72,246,250,213,214, 11, 47,244, 9,236, 85, 26,195, 29,221,149, 30, 73, 29, 40,212,204,166,197,175,234,190,
- 61,154,179, 28,235,191, 58, 98,247, 41,114, 86,213, 17,111, 29,217, 1, 91, 80, 45,165,193,232, 34, 73, 63, 66, 86,216,169,149,
-209,250, 41,137, 18,199, 65,177, 87, 49, 22,157, 51,117, 6,114, 31,246, 7,184,247,204,161,101,103,193, 44, 50,170,128,173, 35,
- 67,226,241,242,100, 20,184, 43,177,173,163,126,198,110, 66, 86,163,195,230,176,149,100,168,197, 16,174, 92,218,160,228, 5,228,
-107,107,103,150,169,121,100, 93,188,138, 81, 76, 79,241,113, 67, 74, 65, 74, 68,142,233, 74, 15,216,103, 28,188,164,225, 15,167,
-156,170,152, 58,211,193,107, 7, 88, 59,116,111, 91,230, 83, 97, 61, 29,154, 64, 8,205,189, 63,255, 64,156,125,186, 59, 77, 63,
-125,120,112,191,255,141,111,120,252,227,230,255, 21,144,136, 78,244, 45,185,137, 29,182, 71,220, 65,137,107, 48,129,167, 3,215,
- 49,155, 83, 46,202,226, 34,183, 45,221, 50,109,214, 74, 78,189,193,174,130,242,111,217, 48,143,106,203,243, 68, 59, 23,250, 68,
- 99,253, 82, 62, 69, 81,238,162,221, 14, 92,198,114,152,150,253,231,205,148, 58,114, 44,112,127,121,255,179, 51,246,156,242,191,
-109,116, 41,110, 0, 38,122,183,141, 62, 90,212,250, 25,144, 81, 71, 73, 63, 63,182,123, 32,142,180,112, 80,185,230,183, 95,127,
-209,126,175,219,167, 70, 57,200,131,250,204,124, 2,153, 25,154, 54, 63,184,219,204,245,130,203,241,120, 75,119,133, 94,158,145,
- 99,127,214, 62,192, 71,142,184, 75, 42, 2,229,129,201, 16,255,128, 59, 5,166,153, 25,188, 4, 7, 58,163,192,182,198, 67, 38,
-208,245,216,180,192,175, 84,219,203,182, 34,240, 93, 5, 16,120,232, 96,140,254,215,103, 53, 46,230,205,219,111, 23,255, 46,202,
-239,255,252, 98, 62, 62,148,135,184,139,120,113,126, 47, 41, 31,193,176, 65,221,190,142,174,188,168,215,127,137, 31, 75,138,223,
-181, 50, 31,233,222,250,111,220,236, 29,181,138,106,184, 11,135,250,120,171,127, 60, 94, 31,195,165, 12,207,198,249,123,227,117,
-126, 85,237,254, 74,173,138, 46,237, 90,226, 98,248,171,159, 5,208, 19, 21,243, 18, 71,179, 17,126,144,222, 10,167,168,181, 5,
- 1,200, 99,166,206, 79,200,160,124,158, 70,187,148, 94, 67, 76, 23, 85,173,255, 9,192,209,181, 44,199,109, 3, 65, 16, 15, 2,
- 32,119, 41,201,170,196, 41,199,149,164,114,243, 23,228,154,156,252,241,190,230,154,114, 14,118, 41,101,151, 30, 20, 31, 32, 72,
- 60,210,205,147, 78,187,218, 93, 14,122,186, 49, 51, 61,186,166,149,123, 22,249, 52,156,130,192,162,175,137,168,119, 66,190,220,
-226,215,108, 66, 3, 93, 97,219, 81, 14,118, 97, 97,231, 56,252, 97, 86,221,120,207, 18,112, 52,233,142,221, 42,224, 94,141,165,
-153,151,187,120,217,214, 33,182, 87,111,251, 30,162,213, 92,141,149,179, 55,111,169, 47,204, 11,203, 48,115, 86,111, 46,195,220,
-188,226,120,106, 15,158,237,185,135,166, 0,118,138, 90, 21, 34,239, 0,107, 3, 97,180, 26,217, 43, 27, 17,157, 1,182, 77,221,
- 72, 27,167,166,134,208,170, 30, 40, 47,161,232, 42,192, 8, 44,222,113,171, 99,221, 54,240,151,183,119, 37, 45, 64,160, 94,214,
-101,142, 23,111, 22,195,133,181,182, 74,195,155, 85,112,194,206,178,159, 37,207, 82,221,158,125,112, 74,131,202,115, 59, 17,176,
-100,104,212, 74, 69,202, 38, 26, 95,218,204,127, 12,228,173, 22,225,182,201,103,218,187,146,239, 1, 42, 68, 47, 99, 98, 95, 35,
-157, 33,201,159,228,133, 62,102,233, 5,156,156, 94, 10,110,146,229,220, 47,197,206, 6,121,218,208, 32,145, 68,227,165, 3, 69,
-198,105,109,124, 39, 71,250,232, 20,214, 24, 56,253, 74,195,100, 78, 45, 12,185, 2,144,246,144,123,101, 38,100,179, 58,175,181,
- 5,120, 24,186,151, 39,252,232, 71,113, 65,245,215,249, 63,164,178, 37, 27,110,143,206,221,243,177,202, 2,116, 95, 16,250, 11,
-190, 65, 93, 58, 61,199,121,221,236, 61, 66, 91,237, 27, 39,179, 6, 67,183, 19, 96, 38, 36,250, 65,127,123, 57,211, 48,125,171,
-218,106,206, 5,114,198,126,227,222,201,200, 11,153,227,208,160,163, 72,114, 58, 7,246,158,249, 12,125, 69,247,187, 22,108, 93,
- 54,218, 38,128,213, 61,126, 19, 7,234, 13, 62, 70, 87,179,203,207,189,117,106,112, 86,227,128,209, 90, 8,192,179, 73, 7, 24,
-240,138,118,128,188,126,225,177,147, 28, 17, 63,175,101,206,243,201,150,184, 74, 38, 94,216,221,207,171,121, 82, 50,144,191,227,
- 92,129,163,104,144,197,235,171,246, 92,140, 71,193, 45, 88,101,163,141, 18,123,155,217,128,166, 89,109,229, 93, 57, 94,235, 8,
-194,231,117, 44,107,151,226, 44, 93,210, 20,185, 21,226,134, 24,199, 62,170,149,245, 77,113,197,123, 53,128,117,188, 7,157,209,
- 43, 99,126,247,178,246,162, 32,186, 2,189,219,249,105, 82, 13, 92,167,206,125, 40,203, 81,236, 90,160,153, 17, 68,120,150,143,
-154,221,243, 58,165,192, 16,170,187,139, 51,161, 57,107,136, 43,129, 63,250,145,247, 45,146, 39, 12,223, 56,165,169,178,211,100,
- 21, 27,178, 59, 36, 83,172,251, 19, 0, 91,234,158,219,236, 71, 64, 18,148,236, 65,194,152,105,120,200,124, 20, 18,189,245,185,
-178,236,204, 87, 28, 58, 87, 34, 34, 8, 89,227, 17,129,173, 56,103, 61,161, 32, 41,229,174,161,125,147,191, 87, 93,151,174,239,
-255,248,122,243,215, 3,152,203,242,249,218,214,165, 70, 29, 60,221, 56,203,200,190,174, 6,153, 55, 64,103, 56, 72,154,137,155,
-230,186,190, 91,198,249,145, 86,254,103, 13, 19, 90, 98, 61,199, 34,130, 81,227,194, 93,189, 80, 67, 61,167, 12,167, 23, 85,175,
- 38,152, 92, 87,102, 12,115, 78, 26, 4, 86, 79, 14, 46,132, 69, 86, 96,253, 23,159,236, 41,153,206,228,180, 60,125,251,233,183,
- 47,119,221,187,239,255,254,253,195,123,164, 81, 25, 86, 36,121,227, 6,186,240,210, 12, 58,229,155, 31, 69,216,119, 51,131,146,
-212, 1,225,152, 67, 39,110,254,252,248, 43,200,251,118,188, 66, 64, 9, 28,211,157,171,187, 88,152,168, 52,118,224,201,134, 44,
-215,180,168, 80, 32, 15, 32,237,192,117, 78, 35, 42,214,166,216, 9,158,104, 63, 17,205,217, 26,143, 96, 41,220, 32,134, 0,239,
- 32,186, 10,215, 43, 78, 78, 12, 69, 65,151, 33,235,226,193,241,101, 59,244, 0, 36, 66,248, 30,145,167,139,143,249,161,132, 55,
-189,107,172,239,149,191,180,239,126,255, 69,136, 15,159, 62,167,127,190, 46,147,120,205,102, 26,174,222,196, 43,136,137,209,214,
-251, 6,137, 1,100, 76,216,145,115,132, 26, 71,222,125, 1,253,193,119,124, 20,254,219,162,117,187,171, 35,229, 7,169, 72,108,
- 33,163,111,237, 30, 57, 40,202,177,200,220,204, 98, 7, 59,180, 8,105,188,141, 7,139, 51,238,188, 37, 29,252,174,156,104,172,
-138,207, 26, 0,222, 21, 26,138, 18,100,202, 70,131, 33,103,144,209,187,139,152,199, 12,148, 80,161,224, 65,185,212,236,255, 11,
- 64,210,181,244,200, 77,132,193,126,186,253, 90,143, 20,118, 34, 72, 36,200,129, 95, 0,167, 92,184,242,211,249, 5, 32,148, 11,
-138, 20, 9, 9,208,106,214,227,177,221,111,170, 58,123,157, 29,207, 76,219,223,163,186,235,171, 50, 61, 58, 15,125,228, 66,137,
- 68, 43,206,131,226,251,139,140, 27,250, 68, 59,224,169,156, 30,246, 63,125,250, 62,160,220,134,238, 17,181, 66,113, 48, 72,249,
- 6, 29,234, 78, 7,238,174,233,110, 94, 84,239, 99,112,175,178, 94,104,246, 89,189, 67, 73, 31, 7,117, 44,207,182, 79,151,188,
- 3, 73, 0,142, 23,148,135, 45, 15,113,184,199, 1, 49, 19,198,138,128,169,192,255,104,115,156,120,112, 86, 76,186,221, 28, 79,
-241,240, 33, 44, 86,109, 97,252,215,140, 49,189,176, 90,115, 3, 2, 17, 95,215,236, 71, 14, 11,169, 28,251,108,163, 45,250,148,
- 97, 1,188, 85, 47,183, 24, 18, 18,225,134,251, 58,168,204,163,139,117,145, 79,100,139, 34,234,107,179, 70, 83, 88, 57,114, 55,
-124, 47,230, 51,114, 30,144, 86, 1,164, 97,223, 61,167, 55, 1,123,154, 22, 99,218,122,231,176,142, 91,165,248, 33,190,101,199,
- 40, 11, 36,154,161, 84,146, 88, 51, 81,196,134,194,241,121,240,201,242, 88, 92,225,254, 34,123,154,160,154,150,228,149, 20, 66,
-228,114,169,210, 24,208,247,142, 8, 44,218, 4,100,153,194,168,231,106,168,168, 51,137,240,160, 78, 65,126, 99,142,179, 56, 82,
-191,212,174, 17,123,138, 94,146,146, 12,176, 36,247, 29,111, 40,225, 72,230,209, 13,232,164, 92,232, 57,205,229, 55, 87,158,214,
-203,174,139,191,227,218,212, 9, 84, 42,102,217,101, 29,105, 85, 90,233,254,156,216, 82,142,217, 56,233,111,228, 43, 8,138,126,
-178,245, 66,126,197,235, 21,207,183, 50, 57,116,150,219,139,153,254,204,133,188, 8,180,246, 20,155, 21, 20, 57,236, 0, 18,104,
-100, 91, 44,213, 69, 1,146,208,225,117,212, 23, 66, 90, 25,156,156,156,213,239, 57,250,182,124, 35, 81,223,204,115,226, 86,241,
- 76, 30,131,180, 99,155,241,148,140, 47,196, 27, 90, 15,114,118,114,219, 83, 33, 35,174,107,135,180,205, 67,195,242,179,124, 19,
- 39, 35,187,223,235,130,229,197, 90, 53, 31, 64,192,156, 38,195,215,252, 92,115, 35,191, 83, 23,175,126,157, 72, 50,109,246, 88,
-144,173,196,139,240,111,162, 7, 83,251, 79, 86, 2,238,250, 35, 23,189,112, 55, 68,243, 24,215,200,150, 11,106,115, 77,163, 56,
-112, 20,184, 63,153, 98, 50,220,160, 37,220,255,234,110, 64,183,161,148,240, 53, 10,235, 8, 18,255, 30,203, 74, 87,142,228, 83,
-240, 52,213, 70,115, 20, 26, 57,135,116, 86, 19,203,121,202, 21,120, 77, 8, 23, 16,176,205,178, 80,172,167,166,138, 17,167, 68,
- 37,158, 58,137, 8, 62,196, 63, 40,199, 14, 40, 83,160, 51,206,135, 66, 28, 85,190,127, 35, 43,102,227,233,195,153,217,170,166,
-166,212, 22,201,249,101,150,231,238, 82,165,240, 50, 71,184, 51, 83,126,147, 90, 71, 1,174,114,172,106, 30,175,191, 60,139,248,
-238,115,249,245,203,166, 85,247, 25, 40, 85,230, 62, 97,149, 71,171,214,162, 15,154,231,200, 16,148, 69,126, 10,128,203, 42, 60,
- 37, 26,140, 69, 35,253,220,223,239, 47,175,251,181,151,150, 98, 9, 84, 44,174, 33, 35, 80, 80,217, 79, 17,111,198,236, 58,237,
-119,155, 15,227, 66,212,162,207, 3, 15, 82,118,142,246,106,170,178,242,113,233,151, 76,181,234,130, 98, 34, 81,233, 87, 31,191,
-119,226,195,119,239, 62,253,213, 25,142, 96, 22,131,213,121,141,233,236,182,233,156,233,230,167,253,154, 41,114, 75, 67, 32, 30,
-161,222,191,236, 31,127,254,233,195,123,202,166,202,180, 16,126,101,170, 98,211, 96,240, 36, 31, 21,235, 29,129,114, 73,190,161,
-194, 39,253,160,125,108,244, 77,165, 1,137, 10,197, 13,203,102,155,194, 84,226,137, 78, 72,164,122, 41,125,110, 60,174,192, 13,
-162,115, 8, 15,204, 79,253, 48,209, 43,117, 75,244,251,205,210,211,148,147, 90, 67,128, 48,105, 67, 99, 56,244,198, 93,166,238,
-237, 15,215,225,237,143,175,105,254,237,143,250,251,167, 63,133, 61,175,111, 6, 97, 23, 45,167, 66, 58,160,106, 39,167, 28, 72,
-158,199,245,216,190,237,129, 73, 37,143,236, 59, 17, 20,167, 73, 0, 52,139, 87,127,151,240, 40,232,122,173,157,229,161,205, 4,
-108,207,129,125, 58,124, 1,223,170, 1,191, 5, 89,143, 93,136, 36,191, 36,232,234,196,136,102,194,122, 78,131,227,154,217, 15,
-238, 22,234,132, 90,135,220,159,122,246,111, 66,248,208,158,230, 56, 80,202, 4,168, 16, 77,174,118,241,127, 1, 72,186,146, 92,
-183,141, 40,216, 51,217, 18, 37,218, 63, 65,128, 36,112, 16,100,147, 3,228, 0,201,222, 39,246, 5, 12, 95, 32,139,192,240, 34,
-187,111,228, 3, 95, 18,199,158,216,169,106, 47,181, 17,165,102,191,161,222, 80,101,182,172,218, 6, 47,226,104,144,142,235, 27,
-228, 69,176, 93,190, 44, 36,148, 45, 59, 71,153,148,115,145,147, 38,110,113,207, 29,222, 95, 97,143,179,226, 69,175, 42,154,126,
-191,236, 62, 60,128, 0,206,198, 15,250,201, 2,240, 57, 60, 5,238,134, 26,224,200,188, 83,247,208,240,153,204,208, 84,236,170,
-129,199, 84,186, 47,205,242, 56, 77,207, 10,197,202,102,119,229,124, 28,160,240, 86, 95, 41, 95,121,140,150,155,216,118, 99,183,
- 27,134,166,248,131, 97, 60, 20,143,135,155, 92,100,194,225, 39,119,216,217,102, 42, 3,156, 39,187,135,224, 70,215,109, 72, 53,
-138, 60,133, 60,114,152,216,154, 35,164, 59,174, 67,215,193,130,214,124, 65,140, 24,145,147,183,194,250,149,149,150,186, 70,114,
- 44, 4,105,168,124,157, 73,203,143,124, 64,172, 28, 69,196, 7,227,113,110,217, 38,129,128,179,203,178,123, 18, 48,201,163,231,
-158, 60,140,152,197, 2,123,239,133,221,216,109,164,197, 71,132, 64, 98, 11,182,242, 88,196, 73, 83,141, 70, 51, 0, 0, 7,224,
- 74, 13, 22, 54, 30,144, 77,215,118, 70, 8,109,148, 87,153,152,245,100,237,119, 63,235,202,105,158,153, 35, 8,117, 56,137,201,
-246,117,173,214,134, 85,110, 30,192, 81,221, 35, 57, 63, 4, 41,102, 31,105,218,163, 89,230, 62,150,101,132, 37,195, 67,175, 8,
-158,234,101, 79,195,181,235,215,245,174,246, 87, 66, 50, 60,155,194,115,164, 39,118,234,224,156,200, 22, 59,163,185,175, 15, 44,
-137,176, 87, 0,127,113, 17,235,220,142, 76, 71, 68,193,232,138,217, 56,190, 72,182,121, 41,178, 37,187, 70,161,185,176, 47,251,
-221,213,185,190,136, 11,183, 94,135, 65, 0,146,104,124,223,128,131,146, 74,219,154,225,251, 75,115,238, 20, 75, 63,106,226,208,
- 95, 83,180,163, 44, 40, 27,161, 73,249, 33,153, 89, 52,114, 7, 89, 40, 43, 41,187,190, 57, 52, 82, 23,193,217, 23,209,107, 69,
-214, 13, 81,217,132,145,108,119, 59,224,164,130, 96, 94, 52,183,233,154, 42,176, 96,197,187,137, 46, 85,246, 73,225,253,190, 53,
-172, 91,202,139,223,188, 11,189,144, 30,132,139,191,142,233, 52,236, 46, 82, 76,169, 82,216, 24,174,131, 90, 45,109, 17,160, 9,
-139, 10, 78,237,225,149, 53,102, 12, 65, 58, 44,164,118,112,176,171,230,128, 29, 76,230,178,205, 47,181, 78,149, 10,216,213, 30,
- 43,155,111, 60,200, 71, 49, 81, 44,176, 60, 97,226,166, 28,112, 79,229, 30,204,126,139, 92,188,194,205,103, 11,130,227,234,128,
- 68,142, 52,124,176,223,140,124,206,114, 7,178,161,171, 99, 27, 97,166, 59,151,113, 73, 95,196, 72,199, 38,238, 53, 51, 83,206,
-137,165,152,166, 79, 46,174,116, 89,162,225, 36,254,127, 60, 61,226,144, 46,242,183,178, 12,191,255,249,207,191,127,124,253,170,
-116,125,238, 88,113, 40,150,201, 0, 76,225,134,112, 30, 1, 57,112,203, 19, 60, 8,177, 20, 25, 84,235,127, 48,242,101,149,122,
- 9,184,112,119, 55, 79, 34,251, 45,204,134, 11,165,202, 46,226, 85,113, 96,127,199,227, 84, 61,221, 58,151, 77, 32,187,154,189,
-138,178,237, 2,142,104, 4, 2, 63,200,103, 10,180,123,100,238,214, 34,248,108,192,224, 28,214, 44, 36, 68,186,189,251,249,135,
- 79, 39, 57, 46,170, 27, 76,238, 56,144,236, 35,209,175, 6,166, 16,121,159,145,174, 26,229,143,209,144,184,241, 36,244, 95,239,
-127, 20,226, 75, 92,158,165,179, 12,110,181, 34,111, 63,184,173,195, 42, 41,217, 68,116, 66,102, 82,112,139, 46, 45,136,190,112,
- 22,144,181, 11, 4,210,169, 71,154, 43, 1,180, 57,243,156,197, 76,181, 66,132,225,213,198,196,230,151, 70, 50,220,166,209,112,
-245,165, 10,177,238, 90,221,245,194, 37,168,122,220, 3, 78, 50, 16, 5, 27,127, 54,238,123, 53,140, 79, 63,253,250, 78,190,249,
-229,195,199,199,223,207,159,183,240,184,190, 53,222, 95,225,127,220,106, 40,177,227, 54,235,223, 44, 73,225,207, 35, 57, 73,173,
-202,232, 53, 34,217, 0,207,150, 1,215, 35, 87, 93, 96,109,154,227,142,184,128,158,147, 49,128, 34, 44, 60,198, 84, 46,157, 98,
- 82, 19, 72, 82, 27, 57, 39, 39,158,100,157,136,158,128, 5, 21, 64,250, 77,182,165, 69,100, 14,222, 2,167, 53,193, 8,101,169,
-118, 39,230, 84,201,110,124, 70,166, 91,195,249, 96, 49,141, 26,180,154, 61,203,255, 5, 32,233, 90,118,228,182,129, 32,197,167,
-164,145,118,118,189, 64, 0,199,200, 41,183,196,200, 33,255,255, 7,201, 15,216,134, 29, 32, 8,130, 61, 56,179,155,157,145, 72,
-138, 47, 87,209,215, 57, 12,102,248,232,174,102,119, 85,105, 13,148,115, 56, 26,227, 53, 18,239, 40, 38, 0,124,162, 11, 53,239,
-178, 43,102,247,183, 41, 34,172, 20,156, 30,147,128, 53,236,238,134, 51, 2,141,214,153,243,233,202,101,196,129, 85,142,215, 50,
- 83, 3, 21, 16,109,200,246,168, 11,110,170,173, 51,254,176, 1,210, 65, 97,119, 7,104, 59, 38, 19,196, 43,112, 79,161, 84,152,
-106, 91,116,237, 85,157,145, 45, 80, 42, 61,232,250,124,155, 84, 60, 70,160, 40,143, 66,183,153,127, 43,223, 63,177, 49,131,181,
- 37, 33,155,238, 28, 56,146, 59, 50, 71,201,243,200,231, 78,252,122, 32, 36,121, 98,109, 32, 36, 91,115, 37,225,178, 32,148, 12,
-198, 91, 89,200,121,151,231, 57,177, 3,163,238, 87,157, 8, 30,236,144, 70,234,208, 51, 53,178, 67,195, 6, 90,211,125,190,157,
- 84,143, 72,198, 77,165, 47,174,228,180, 85,227, 16,135, 26, 13,112,252,215, 88,149,234,207, 1,130, 34, 97,204, 81,153,107,165,
-163,190,111,241, 24,248, 48,105, 21, 86,196,152,137, 13, 13,217,237,212,143, 56, 72,211, 35,202, 88,113,221,176, 71,153,235,172,
-218, 4,204, 38, 56, 24,207,217, 14,187, 56,234,126,251, 35,237,128, 44, 86,201,128,221,106,172, 25, 43,192, 13,159,157,247, 73,
- 38, 15,252, 86, 98,229, 45,165,237, 45,190, 60,237, 46,139,255,244, 58,149,227,120, 57,200,255, 1,150, 73,119,118,104,233,217,
-251,182,215,238, 59, 86,197, 20,235, 78, 15, 9,212,126, 62, 6, 0,110,164, 73, 73,145, 58,162,221, 82, 29,105, 59,161,177, 31,
- 12,136, 16,232,127,125,243,156, 36, 53,179,125,173, 20, 35,199,254, 75, 87,205,139, 46,247, 3,135,208,173, 24, 23,121, 66,181,
-179,138, 59,197, 49,173,113,182,195, 42,249, 92,131, 37,155, 85, 39, 70, 99, 73,156, 72,166,216, 12,180,143,111,174, 61,232,138,
- 98, 37, 37,145,233, 64, 72, 5, 24,122,104,148,190,174, 8,159, 56,244,245,251, 52,187,160,252, 8,229, 69,216,172,164,204, 35,
-242,234, 94, 16, 7, 88,170, 10,114, 7,186,102,123,203, 36, 41,244, 7, 1, 26,115, 24,117, 2,182, 34, 7,167, 75, 65,116,201,
- 1,114,227,136,226, 16, 44, 15, 47,100,231,197,114, 16,158,150,130, 20,199, 14, 10,133,105,119,255,164,186, 90,193, 14, 33,114,
-183,136, 56, 92, 53,144,111,193,205, 67,109,204, 14,236, 81,213,165,149,133, 54,136, 8, 10,219, 81, 17,133,149,247,153,242, 63,
-226,255, 77,211,120,176, 37,164,137,240, 26, 79,200,150, 51, 51,102, 34,159, 86,135,141,237, 3,156,105,128, 92, 36,174,148, 24,
- 15, 73,181,185, 54, 47,137,107, 75,242,128,114, 23,182,137, 68,247, 57,100,193, 72,117,179, 74,130, 78,167, 61, 8, 50, 15, 57,
-108,206, 37,193,135,154,249,171, 93,196,176,210, 67,130, 15,127, 57,181,143,159,223,125,186,206,102,255,139,110,244,228, 48,200,
- 16,231,168, 61,149,130,141,197,175,121, 19,182,116,105, 47,143, 27,170,230, 74,157,122,212,120,184,157, 84,248,204, 54,109,225,
-235,115,249,249,237,252, 78,221,254,241,187, 91,150,129,214,110,148, 0, 19,116, 70, 12,121, 66, 8, 91,251,110, 4,160, 26, 58,
- 22,144,242,140, 48,186, 74,113,195,181, 82, 28,137,111, 71,117, 6, 69,109, 69,196, 51, 15,180, 48, 44,203, 16,129,162,211, 16,
-145, 6, 4,101,186, 57,240, 72,245, 4, 67,193,188, 76,247, 18, 5, 32, 26,226,211,237,215, 95,126,255,237,253,143,162,254,157,
-178, 35,194,245,155,188,105,146,233,144, 96,113, 39, 17, 89, 67,223, 34,156,208,202,201,103,172, 85, 54,116,141, 22, 8, 7, 0,
- 6,227,161, 8,241,115,217, 90,113,162,207, 86, 10,190,228,144, 93,125,176, 77,190,177,154,103,231,131, 78,106,188,239,188, 85,
-161, 1,198,196, 45,237,216,195, 98, 5,202,210, 59,247,248,195,227,195, 79,239, 63, 92,238,255,252,227,233,203,151, 79,116,134,
- 62, 45, 66,217, 43, 74, 19,211, 98, 19,147,209, 59,138,213, 23, 64, 93,119,126, 34, 45, 60,173,179,164,118, 34, 5, 64,104,246,
-110, 72,169,174,180,141,167,166, 85,180, 19,219, 78,156, 28, 31,223,100, 64,134, 16, 13, 11, 48,205,199,219,139,245,103,128, 13,
- 47,252, 73,119, 29, 53, 25, 22,138, 2,145,139,171, 21, 74, 45, 28,231, 20,143, 41, 17, 22,226, 92, 26,190,104,208, 52, 92,120,
-139,100,112,149,233, 68, 3, 14, 23, 90, 62,103,115,251, 38, 0, 73,215,178, 27, 53, 16, 4, 61, 79,123,108,239, 6,146, 32,110,
- 40, 66,136,127,225,204, 31,115,227,198, 5,129, 4, 39, 78, 16,148,176,241,174, 61,158,241, 60,168,114,246,184, 90,201,235,121,
-116, 87,205,116, 87,233,148, 78,130, 13, 16,221,168,242, 82, 10,230,215, 27,154, 4, 30,175,221,211,148,167,116, 24,219,135,209,
-217,185,180,171, 3, 63, 62,197,120, 29,129, 28, 86,127,196,246,234, 94,197,186,117,219, 82,131,182, 93, 53,216,219,120,217,118,
- 91, 88,191, 67,222, 8,104,109,253,160,244,217, 33,109,117,155, 15,193,144,213,243, 79,166,168, 87,172, 21, 47, 7, 76,104,155,
- 30,206, 9,212,118,116, 33,150,116, 42,102,165, 28, 65,213, 79,128, 59,133, 91,143,195, 83, 49, 85,201,178, 75, 87, 34, 67, 0,
-117, 1, 36, 43,158, 40, 8,111, 95, 42,112, 54, 57,141, 87, 71,238, 78,240,111, 63, 52, 87,133,178,238, 50,180,188,141,185, 81,
-197, 72, 74, 63, 87,147,232,195, 37,124, 1,222, 48, 74, 83,247, 38,155,118, 76, 18, 11, 76,129,143,111, 92, 11,190,169,125,155,
-237, 40,119, 3,199,224, 87,162,253,129,170,128, 1,163,140,164,163, 55, 66, 85, 3, 34,183,166,205,164,108, 53,213,205,159,253,
- 58,148,201,217,208,242, 93,239,205, 82,154, 7, 17,174,167,164, 45,128, 32, 66, 82, 15,142,138,101,132,173,199,221, 88,123,100,
- 7,112, 2, 65,155, 76, 94, 60, 14,166,139,244, 17,155,144,165,217,149, 19, 47, 52, 2, 2,122,142, 30, 28, 24,248,144,130, 70,
-227, 37,198, 62,250, 80,214, 8, 52, 57,149, 24, 2, 8, 91, 73,142,189,163,105, 86,126, 66,224, 89, 16, 10, 98, 48, 45,101,172,
-194, 65,119, 70, 41, 5, 42, 20,242, 2,170, 59, 34, 76,107, 54,253, 97,120,128,122, 22,246, 89, 81, 96, 13, 97,197,129, 36,248,
- 99,144, 78, 82,218, 60,224,171,186,203,109, 43, 26,253,208,241,241, 58,201,165, 49,131,109, 70,193,165, 62, 90,221, 43, 49,170,
- 66,145, 22, 42,183,107,236,115,199,115,115, 76, 69, 3,228,194,190, 61, 26, 6, 2,173,240, 9,192,171,212,192,238, 88,244,206,
-162, 68, 35, 13, 91,202,137,217,201,186,119,177, 54, 30,179, 72,150,205,224,121,219,179, 84, 0,181,111,247,160,239, 37,157,170,
-111,104,122, 40,116,216,135, 85, 90,252, 24, 17,122,213,172,132,153,196,174,253, 68, 61,255,228, 88, 43,169, 12, 43,205,120, 55,
- 74, 17,114, 30,214, 35, 33, 37,187, 23, 83,226, 89,136,198, 84,251,174, 32, 56,152, 54,224, 46,228,196,133,119,151,187, 89,103,
- 32,237,125, 98,143,149, 96,149,106,197,226, 76,247, 86,184,186, 2,167,196,144,150,122,137,136, 51, 72, 18, 60, 90, 0,238,205,
-255, 82,157, 65,218, 89,134,233,127, 87,146,169,160, 11, 72,167,226, 53, 29,173,199,227,126,126,132, 68, 91, 0, 69,120,229,221,
-132,182,224,189, 10, 91,238,124,105,250,149, 87,169,219,222,190, 69,243,247,218,236, 24,125,231, 41,138,247,197,174,178,104, 5,
- 31,191,251, 3,182,166, 14,129,153, 5, 99, 53,139,203,235, 31, 63,111,110,239, 30,211, 89,131, 59,176, 61, 28,239,249,136,169,
-193,138, 55,117,122, 82,135,192, 22, 8,123, 70,204, 5,246,163, 53, 88, 86, 1,161, 87,173,136, 39,139, 75,167, 63, 63,126,221,
-189,185,125,161, 14,191,122, 36,192,137,174,174, 62, 23,135,159,118, 24, 88, 10,205,166,250,108,108, 85,144,151, 26,218,142, 2,
- 53, 21,106,212,173, 87,141,156,145, 19, 3, 72,191, 29, 50, 77,129, 49, 40,188,214,109,228, 73, 94,178,235, 25,200, 1,222,129,
- 48, 22, 71,183,156,188,198,197,202,101,109,110, 15, 84,230, 10,211,220,235,246,195,199,183, 77,243, 61, 76,127,217, 58, 21, 9,
- 83,120,174,206,244,152,176, 24, 17,217, 36,241,128,102, 31, 31, 86,215,178,223,244,114,105,101, 64, 44,201, 30,177, 45,158, 4,
- 99, 63, 64,109,161, 9, 24,240, 20, 21, 66,103, 1, 84,197, 22, 86,102, 78,252,141,162, 30, 16,201, 69,164,173, 88,142,216, 14,
-103,208, 47, 49,128,177,183,214, 30,245,155,119,119,135,241,253,167, 47,229,243,215,111,127, 46, 63,219,235, 94, 15, 47,128, 84,
-186, 88,238,245,191, 46,142, 35, 0,198,195, 75,117, 69,125,171, 75, 38,252,172,131,124,118,204, 46, 85,168,101,118, 8, 24,231,
- 30,144,187, 25,180, 95, 12,246, 16, 8, 95, 91,137,177,217,221,200,202,181,174, 3,226,216,196,188, 90,163, 15, 1, 9,173, 11,
- 52, 59,166, 94,137,136,134,109,210,120, 61,211,202,136, 77, 3,130, 23, 40, 27,215,242, 0,197,131,116,101,128,180,146, 88, 17,
-191, 81,190,161,176,171,241,156,100,144,161,219,210,252, 95, 0,146,174,165, 55,146, 26, 12,182, 31,221,237,118,207,236,100, 38,
-123, 88, 16, 71,196, 1,164, 21, 92,118, 15,252,101,126, 7, 8,137, 59, 18,136, 95,176,217,201,204,244,203,237, 39, 85,206, 33,
- 82, 18, 41, 73,199,109,127,174,250, 30, 85,154, 14, 40,190,102, 48,193,130,227,234, 98,246, 53,166,108,162,114, 12, 9, 86, 92,
- 94, 92,233, 71,127,200,225, 70,119, 97, 60, 77,112,182,157,230,219,122, 85,250,162,165,232, 64,255,116,215, 17,208,109,155, 17,
-125,182,234,121,112, 65, 12, 13,153,148, 82,224,110, 25, 49, 69,112,254,154,130,193, 88, 85,191, 58, 44,186,197,110,110,135,132,
-151,122, 50,202, 59,229, 87,191,108,161, 55,173,148, 6,219,117,233, 57, 97,232,248,195,133,253,137, 1, 56, 45,107,218,190, 74,
-242, 84,137,147, 35, 18, 46, 75,252, 89,175, 91,146,184,134,174,111, 61,203, 48,153,255,148, 67, 84,215,189,206,122,218,154, 17,
-108, 82, 70, 60, 30, 22,255,192,201, 12,241, 86,221, 51, 77, 45,153,135,140, 40, 21, 7,170,125,168,202,113,198,173,241, 20,160,
-147, 5,145, 73,177, 54, 31,114, 66, 76,167,232, 99, 77,246,250,196, 62,177, 52, 80,253, 22,155,133,196, 37,119,201,168,119,236,
-128,142,184, 63, 59,188, 68,166,132, 69,218, 75,111,197,146, 11, 14, 58, 89, 80,202, 35,149, 2, 65,197, 20, 24, 6, 40, 33,104,
-118,148,222, 9, 93,123, 19, 1,105,149,201,210,244, 56, 21,120,240,120,193,178, 41,121,245,209,128,144, 91, 44, 75, 46,229, 30,
-180,244, 97,114,148, 29, 1,160,138,192, 95,110,147,199,213,131, 53,148, 35, 69,199,150,188,156, 6, 93,167,169,130,154,179, 31,
-175, 77,120, 82,108,198,227, 20, 11,141, 61,195,202,138,117,168,169, 11,196,190, 5,251,132,147, 67, 41,238,156,102, 13,187,242,
-199,146,103,192, 13, 78, 81,102, 14,130, 81,181,181,177, 37,155,182,237,245,248, 92, 58, 73,233,126,186,204,130,174, 57, 37,198,
- 88, 46,172, 72, 52, 59, 91, 19,154, 30,161, 25,203,217,151, 54,215,182,118,124,206,202,231,155,236, 46, 11,251, 25,251,180,208,
-186, 2, 8,132,134,136,134,105, 26, 48,127,230, 71,170,147,198,155, 74, 47,219,100, 17,218, 29, 46, 12,142,177,100,219,208, 46,
- 12,216,119, 6,250, 84,154,130,108,172,191, 54,138,179,106,248, 62,253, 6,123, 58, 85,179,147,213, 87, 83,108, 60,143,103,163,
- 36,167,150, 65, 9, 84,117, 88,194, 33,140,153,106, 63, 9, 65, 28,241,189,138,239,244,249, 86,239,129, 42, 96,224, 1, 30,185,
-229, 21,246, 33,184, 16, 86, 41, 80,226,190, 91,167, 16, 22,206, 82,138, 90, 60,245,115,123,243,113,112, 37,225, 86, 5, 73, 94,
-112,107,120,175,164,197, 69, 18,153,127,237, 67,113,137,186,241,131,103,231,221,221, 81, 51, 69, 7,191, 19,138,234,188,171, 30,
- 47, 69,165,151,218,180,217,213, 84, 12, 54,220,150, 56,190,228,170,103,228, 88, 51, 77,182, 10,235,119,181,212, 0,204,104,116,
-197,236,149,216,112, 28,143,185, 17, 53,205,219,135,199,239,223,124,251,211,203,116,206,241,213, 34,248, 26,132, 9,128,183, 34,
- 30,251,142,104, 41,238, 86,222,118, 92, 34, 1,216, 57,136,107,219,214, 2,179,163,152,209, 61, 21, 43,245,237,191,245,203,175,
-167,143,230,248,207,252, 85,224,220,216, 75,217, 30, 10,187,213,129,115,128, 90, 29, 68,153,129, 83, 99,122, 47, 88,112,223, 50,
-141,115,129, 28,111,173,122,199,201, 27,103, 16, 55, 12,157,194,133, 87, 70,179,221, 86, 61,222,219,167, 50,154,117,200, 26, 7,
-120, 42,249,164,180,112,150,179,251,170, 55,165,223, 18,238,190,213,108,175,175,241,211,231,143,191,252,252,220,228,191,217, 74,
- 3, 66,202, 67, 4,218,236,153,124,159,241, 37,226, 3, 71,199, 89,250,102,119, 1, 11,243,133,170,207, 8,223,120, 67, 1,228,
-157, 80,204,209,220, 36,158,193,238,170,190,231, 20, 53, 91,241,148,220,232,154,236, 6, 26, 61,208,121, 97, 84,233, 65, 57, 25,
- 49,166, 48, 43, 26, 36, 39, 44,179,182,231,230,251, 31,191,187,202, 31,126,251,235,250,199,159,255, 94, 70,224,157, 3, 93,210,
- 54,153, 94,154,109,144,254,108,187,106,223,190,232,149,136,142,227,162,231, 3,109,169, 10,130, 40, 66,130, 80, 79,236, 16, 2,
- 78,212,161,159, 88, 48,213, 45, 63,218,141,206, 26,160, 36, 86,124, 1,227, 12,120,172, 48,225, 87, 15,154,174,185,174, 93,187,
-120,212,216, 17,116,176,122,156,213,162,246,227,163, 76, 8, 82, 6,145, 86,223,115, 58,137,118,111,131,127, 21, 11,208,141,110,
-152,255, 64, 84,101,143, 41,179,209,160,134, 59, 0,123, 35, 39, 27,202,255, 2,176,116, 53, 45,146, 20, 65, 52,191, 51,171,186,
-122,102, 68, 6,241, 3,132, 5, 15,130, 7, 97,253, 29,226,207,221,251,122, 22, 15,162,236, 77,193,139,238,236,246,204, 84, 87,
-101,101,102,101,166,239,213, 8,115, 24,232,166,235, 35, 35, 35,222,203,136,120, 97,182,246,196, 17,101, 94, 69, 14, 19, 99, 34,
-222,136, 6,166,150,235, 33,187, 33, 99, 10,156,145,226, 83, 11,128,108,103,243,153, 93,151,107, 45, 19,184,174,189, 95,180,114,
- 29,159, 8, 86,164,118,248, 7,113, 55, 94,175, 98,240,253,131, 25, 1, 23, 71,246,198,140,237, 41,164,102,252, 0,200,108, 43,
-118,227, 78, 31,219, 93,180, 88, 57,128,243,139,152,117,173, 28,192,136,197, 68,152,106,107,220, 82, 84,193, 37, 69,113,218,158,
- 99, 29,118,235,210, 14, 32,152, 68,193,229, 74,145,102,130,203,233, 64,140,215,136,119, 43,221, 13, 21,218, 61,204,175,143,150,
-131, 96,172, 29,229,205, 96,105,240, 62, 59,128, 35, 53, 49, 75, 26,130,210, 67,226,190, 0,202,187,165, 60,189, 41, 88,163,160,
- 67, 65, 60,193,102, 22, 1,252,207, 51,147,168, 97,109,243, 33, 8, 94, 0,107, 0,254, 16,128,176,152, 64, 19, 8, 14,226,180,
-215, 71, 60,240,216,125,161,106,190,208,185, 73, 59,140,236,115,100, 35,146,179,131,115, 60,229,133,187,181,106,112, 5,236, 16,
-100,149, 53,227,141, 1, 38, 5,120,147,106, 89, 2, 69, 41, 89,193, 34,105,129, 23,134,229,162, 84, 2,208, 38,158, 54, 33,212,
-134,205,139,231, 36, 16, 5,176, 45,103, 17,240,123,133, 25, 64,150, 87,111,107,100,179, 1, 48,152, 92, 88,248,153,202,163,110,
- 81, 47,238,218, 57,182, 52,214,249, 10,124,156, 88, 12, 68,213,216, 2, 0, 57,248, 6, 96, 90, 89,213,110, 97,208, 48,191,149,
- 50,119,204, 35, 82,181, 69,165, 98,188, 4, 95,215, 85,242, 64,184,164,113, 54, 98, 96, 95,180,198, 93,157,123,141,216, 70,184,
-164,158, 88,113,164,130,117,216, 21, 62, 32,184,139,118,226, 44, 11, 10,140, 5,142, 64,252,191, 76,155,226, 94,237,101,114, 48,
-107,253, 72,165,168,236,200,115, 43, 4, 0,172,239,246,130, 30,241,230,121,244,207, 10,110, 42, 34,242, 99,250, 48,138,234, 71,
-128,119,197,170, 66,152, 23,200,197, 35,209, 46,139,120, 34,199,162,178,213,138,147,189,192, 2,130,196,255,138,103,239,184,168,
-158,119, 78, 72, 50, 20, 96, 38, 45,144, 71,146,149,122,253,236,139, 58, 58, 98,116, 78, 69,177, 13,180,239,182,187,220,240,104,
-108,148, 70, 28,201,157,199, 59,178, 36,159, 46,222, 46,125,187, 91, 28,185,144, 90,162,230,107,161, 82, 69,110, 23, 86,194, 24,
- 10, 24,101,241,192,217,219,240,184, 51,238, 36, 18,179,178,142,119,149,112,117, 10, 65,121,101,189,181,105,210,192,192, 1, 30,
-153,223, 5, 99, 41,235,165,176,217, 20, 64, 86,108,185, 48,233,131, 47,128, 44, 12,149, 16, 30,247, 30, 14,228,254,201, 49,112,
-228,200, 45, 48,185,202,148,194, 17, 32,245,241,146,237, 81,254,249,162,160,195,114,155, 93, 98, 87, 95,222, 63,127,245,234,143,
-241,230,117, 89, 31, 30,235,149, 24, 43,210, 9, 70,253, 36,131, 9, 60,132,134, 45,150, 27,132, 46,173,158, 84,118,102,110, 91,
- 75,203,137, 29, 3,171, 6,124,252,251,175,119,191,125,254,195,247, 95,126, 23, 63,254,146, 31, 88,212, 43, 71, 30,180,112,197,
-176,235,224, 48, 3, 51,217, 8,156, 48, 36, 39, 67,228,193,206,104, 99,108,251, 2,240,160,123,112,218, 53, 32, 20,112, 56, 31,
- 90, 27,128,202,220,237,109, 75,118, 26,114, 45,216, 0,128, 74,194,147, 71,180,118,103, 57,190,192, 47,136,175,249,253,126,223,
- 62,253,241,167,111,132,120, 23,159,102,162,236, 88,240,215, 19, 5,217,193,144, 26, 75,121,179,165,198, 4,189, 61,127, 27,102,
-108, 90,255,200,186,124,106, 4,177,225, 77, 49,147,141,125, 1,150, 19,149,249, 71,168,123,191, 3,182,128, 7,158, 57,168,169,
-193,212, 55, 99,102, 22, 81,110,216,116, 36,145, 90,101, 78, 45,111,119,110, 60,219,179, 58,125,241,234,235,217,125,251,230,237,
-159, 63,255,254,235,136,155, 11, 68,125,235, 2,112, 33, 62,120,119, 30,119,102,197, 75, 92,199, 51,149, 8,214,240, 12,143,109,
- 16,232, 92, 74,108,169, 1, 25, 55, 3,107, 46, 67, 86,224,232, 84, 61,227,192,113, 19,227,138,176, 52, 77,117,107, 14, 44, 29,
-209, 47,139,109, 96, 25, 75,134,145, 88, 7,111,127,174, 91, 15,230,223,186,141,158, 26,220, 74,166,105, 10,100, 40,157, 26,215,
-120,223, 64, 23,251,164,199,147, 10, 20, 96, 82,213, 5, 66, 60, 5,234, 62,176, 89,130,170,213, 25, 20,193,167, 32,255, 19,128,
-164,107,215,145,164, 8,130, 93,239,238,158,217,221,227, 22, 9, 9, 4, 8, 9,204, 51,206,194, 70,247, 11,152, 56,248,124, 18,
-159,192, 39,224, 97, 97, 98,129,116,194, 65,194,224,116,203,204,214,116, 87,119,117,189,136, 40,140, 29,105, 87, 51,179, 51,157,
-217,153, 25, 89,153, 17,234,251, 31,222, 56, 42, 54,156, 50, 21, 84, 50,153, 10,224,249,133,157,125,124, 82,203,244,210,212,222,
- 18, 23,170,169,198,167, 40, 52, 51, 69, 49,230, 61,224,202,164,124, 32,102,155,251,128, 66,110,214,179, 17,156,103,127,116, 40,
-231,226,125,194,111,205,225,233, 47,182, 35,233, 7,235, 57,216, 43, 67, 65, 74,176, 99,229, 72,203, 38, 35,128,232,140,248,207,
-251,137,103, 95, 40,120,169,150,178, 77,121,116,211,234, 77,121, 22, 8,162,100,183, 12,135,136,114, 71,161, 16,245,116,168, 41,
-231,127,236,128,108,184,175,212, 23, 85,231,204,147, 69,110,143,164, 92,197,203, 59,120,254, 41,114, 6,164, 56, 77,214,150,137,
-146,109, 77,143, 39,161, 38, 68,216,217, 32,201, 79,164,171, 80, 93,165, 57,126, 80,219, 70,103, 28, 80,144,201,107, 30, 22,150,
- 75, 7, 1,159,154,152,134,136, 14, 11, 25, 79,250,192, 73,159,131,222, 68,113,214,172,184, 32, 8,244, 0,124, 65, 24, 67,152,
- 69, 37, 86,110,235, 3,177, 52,106, 59,178,131,196,115,197,131,249, 72,104, 42,165,119, 77, 56, 41, 2,126, 40,111, 32, 56,144,
-133, 2,138,148,175, 8,120, 58,166, 26, 52, 62, 66, 93,120, 48,181, 7,158,143,121,164,113, 20,153,246,114,217,117,185, 34, 55,
-215, 12,243,240,248,225,240, 91, 92, 72,120, 56,252, 79,177, 58,122,132,208,205, 55,135,244,177,150,224,131, 1, 44, 67,188,182,
-226,213,157,149,254,109, 25, 93, 34, 55, 89,202,163, 52, 19,165,189,213,102,254,229,188, 41,251,222, 8, 30,117,201,205,146, 20,
- 27, 79, 98,189,203,147, 11, 18,140, 38, 82, 86, 42, 55, 87,229, 68, 61,181, 7,171,102,215,202, 75,169, 17, 21, 79, 89,147,121,
- 89,118,142, 22, 50,227, 74,214,227,172,186, 88,195,177,209,193,171, 64,241, 33,252, 31, 14, 30, 87,139, 12, 44,217, 50,233,236,
- 96,236,182, 11, 66, 26,196, 65,198,143,206, 4,150,184,232, 34,251, 4,137,129, 37, 41, 60,210, 97, 0,247, 75,249,190,149,186,
- 87,156,157, 33, 77, 45, 9, 96, 43,110,220, 68, 46, 75,114,197, 17,247, 81, 16,146,140,145,217,136, 98,152, 24,168, 8, 82,145,
- 96, 25,237, 9, 62, 80,106,118, 33, 33,174,157, 18, 80,115,243, 43, 37, 50,199, 80,203,146, 27, 85, 85,112,183, 33, 34,170,145,
-115,167,134,219, 33,158, 54, 24, 39,174,206, 35,180,251,227,150,128, 70,219,190, 21,127,205,171,175,242,170,226, 51,128, 43, 18,
-169,180,110, 32, 85, 82, 34,103,105,144, 42,237, 20,159,115, 48,234, 90,166,216, 22,158, 18, 26,132,173, 4, 84, 80, 56,233, 7,
- 11,164,206, 80,233, 58,116, 65,160, 15,125,206,125,237,193, 93,247, 93, 90,211, 79,107, 76, 95, 9, 56,244,192,246, 62, 15,238,
-248,167,200,229, 57,119,182,136,149,237,241,113, 31,191,250,226,242, 78,223,196,251,194, 55, 61,128, 53,233,228,184,235,216,127,
- 52,114, 91,185,168,205, 93,130,124,222, 13,193,181, 65,254,209,168,170,198,188,150,250,180,196, 79, 94,127,244,113,254,251,183,
-221, 91,135,235, 89, 90, 23,101,160, 17,184, 61,160,141,218, 5,188,161,184, 89,107,138, 32, 1,190,115,115, 14,129,108,184,171,
-242,222,232, 3, 21,190, 50, 15, 18, 73,186,217, 73,135,144, 62,251,249,151,191,214,248, 36, 79,148,255,113, 39,133, 68,224,110,
-194,179, 71, 69,209,180,232,183,203,251,237,219,239, 94,189,249,230,195,186,254,158, 42,151,224,200,158,123, 59,218,243,145, 99,
- 66,192,200,240, 68, 88,150, 93, 64,182,100, 96, 45,188, 20,249,144,141,115,248,204,141,140,123, 28,190, 69,157, 20, 20, 64, 11,
-183, 62, 80, 70, 77,141,172, 82, 98,160, 8,159,135,185,185,143,134, 90,142, 74, 82,249,200, 11,239,247,186, 75, 56,226,248, 66,
-220, 63,220,125,249,245,167, 23,241,249,143, 63,189,253,245,207, 63,228,164,167, 60, 75,242,129, 13,137, 26,247,245,156,146, 62,
- 19,151, 29, 81,142,197,178,170,227,132, 38,217, 32,129, 86, 9, 40, 19,210,142,192, 3, 97,189,136, 23, 0, 64,250,241, 69,181,
-133,131,200,109, 30,181,164,106,111, 94, 4, 76, 56,220, 70,141, 48, 20,183, 13,208, 56,160,128, 69, 84, 85, 22,197, 9,252,146,
- 98, 74,228, 48,227,210, 31, 82, 93, 19, 19,139,113, 83, 86, 90, 52,152,141, 77,229, 43,190, 33,220, 76, 52,185,227, 43,250, 98,
-213,210,226, 59,113,192,113,234,127, 2,144,116, 45, 59, 82,228, 64,176,236,178, 93,175,238,158,225, 49, 66,163,229,192,101, 1,
- 33,129,196, 71,172,118,255,129, 35, 7,254,140, 31,224, 79, 56,129,132, 4,104, 37, 96, 22, 52,221,213,245,180, 93,182, 55,194,
-156,123,164,234,233,114,166, 35, 51, 35, 35,202, 87,111,254,193, 49, 65,169, 25,212, 12,136, 4,116, 65, 41, 58, 84,106, 40, 48,
-197,104,185,122,176, 26,146,238, 86,220,174,150,146, 62,174,216,144,119, 87,121, 65,101, 93,157,155,201,186, 50,128,115, 91, 67,
-119,178, 14, 96,212,236,144,252,106, 93, 76,157, 70, 6,149,134, 38, 82, 36, 49,187,220, 28,231,130, 87, 63,110,182, 88, 15, 83,
- 15,200, 54,144,202,191, 34,131, 23, 72,177, 35, 94,106,178, 43,137,103,138,131, 4, 73, 85, 26, 78,115,149,164, 52, 84,172,246,
-237, 20, 46,103,194,229,153, 59,104,157, 16,119,154,176, 95,185,207,235, 90,165, 19, 10,195,182,105,220,185,144,123, 90,140,150,
-221,174,147,242, 2,199, 73,103,194, 23, 29,228,227, 14,231,170, 52,154,211, 52, 74, 99,149,244, 94,225,202, 99, 75,156,151, 74,
- 42, 45,104, 73,183,227, 80,219,132, 58,156, 61, 46,146, 94,202, 9,224,210,147,113,140, 12, 41, 35,135,196, 50, 55,254, 74,154,
-209, 82, 32, 19,184,202,224, 90, 19,156,218, 0,137, 54, 26, 17,197,132, 86, 53,153,117,129, 83,162,168,245,163,217,146,145,156,
-164, 87, 0, 34, 56, 3,124,127,158,157, 4,165,105, 71,180, 2, 31, 82,199, 62,101,151, 8,160,144,145, 92,217, 24, 34, 42, 10,
- 4,187,118,177,199, 13,220, 7,191,166,129,100, 93, 92,238, 21, 42, 18, 59, 14,156, 66,203,105, 5,106,231,222, 58,234,159, 90,
-205,168, 35,251, 94,152,234,241,213,193,126,255, 48,103,252, 23,243, 36, 95, 71,148, 78, 36,138, 73, 27,240, 96,151,245, 86, 19,
- 7, 54,100,108,255, 30,106,210, 85,143,210,116,194,176,116,145,170, 50,200, 38,205,157,178,235,100, 68,136,170,182, 10, 50,238,
-240, 61, 53,125,143,113, 93, 82,171, 16,255, 40,149,140, 74, 74, 67,114,157, 83,144, 93, 78,153, 5,132,145,160, 11, 61, 16,132,
-151,220,226,207,148, 76, 97, 35, 61,172,221, 70,158,161,224,204,133,215, 97,182, 2, 32, 57,157,201,159,161,206, 21, 86,149,141,
- 87,168,177,142, 42,155, 68,201, 16, 0,164,136,200,217, 92,202,113,196, 34, 53, 91,171,138,144,182, 46,133, 44, 27, 78,197, 26,
-142, 45, 11,210,133,144,223, 23,233,133,231,106, 48,137,227,184, 23,144, 41, 34, 61,218, 40, 73, 73, 69, 50, 60, 20, 96,125, 8,
-103,165,202, 35,130, 82, 0,230,173,103, 54,125,131,109,126, 89, 73,115, 88, 84,101, 99,116,125,114, 67, 48,179, 60,167,120,242,
- 98, 95,200,133, 3,116, 32, 13,162,233,218, 23,150,186,203,197, 54,123,179,164,172,220, 65,195, 10,220,231,115, 40, 71,111, 34,
- 94,182,207,204, 29,199, 36,206, 57, 33,181,237, 56, 86, 21,217,229, 90,101,240,158, 45, 98, 41,176,192, 36,149, 25, 67,173,230,
- 95,146, 28,169,216,118,234,148,168,200,184, 22,172,142, 84,208,251,248,232, 69,181,200, 7, 55,255, 30,131, 30, 16,208,246,164,
-215,224, 44, 13,152,138,122, 70,190, 63,142, 65, 57, 33,195, 50,157,112,253,120,133, 34,176,188,213,113,160,208, 40, 10,188, 79,
-231,161,187,126,246,164,251,185,108, 95, 44,158, 81,117,113,223,226, 40, 20,113,159,180, 41,187,170, 72, 53,159,181, 99,230, 12,
-138, 44, 94,220, 0,181,217,233,186, 33, 31, 15, 47,173, 1,190,187,207,177,138, 0,192,156,174, 30, 94,255,113,245,236,230,171,
-250,113,123,252,121,123, 92,188,189, 25,156,103, 74, 88,151,105,153,251,217,205,254,239,191, 94,190,126,243,180, 16, 95,151,211,
-127, 2,175,120,142,197, 41,133, 62,218,145,139,114, 2,249,201,102,155, 45,147, 21, 59, 38, 42,122, 81,246,117,205, 74,126, 38,
-183,213, 50, 31, 50,160, 74, 83,108,167,202, 22, 37,175,164,250, 29, 5,187,233, 40, 24,105,181,231,184,232,183,166,101,164,232,
- 42,247,197,216,179, 41,211, 46,169,187,234,250,225,159,125,249,252,237,187,207, 31,191,189,175,239, 53, 23, 21, 32, 15,126, 50,
-238,229,249,125, 61, 5,111,187,118, 44,106,132, 55,178,251, 9,208,225, 48, 91,150, 52, 37, 87, 66, 20, 93, 37, 21,249, 83, 52,
-101,162,109,118,222,129,188, 68,189,131, 20,168, 47,113, 23,107,177, 20,146, 50,132, 89,141, 19, 39,237, 23, 82, 54,146,163,211,
-220, 96, 35,179, 78, 31, 16,143, 99, 2, 52,175,179,242,208,217, 59,128,111,160,152, 77, 26, 36,232,141,126, 67,228,223,156, 1,
-191,183,164, 80,249,225, 24,155,128,143,207, 94, 28,200,118,150,213,102, 16,116,219,255, 2,144,116, 53, 45,146, 20, 81, 48, 63,
-170,178, 42,171,171,107,237, 93,216, 93,212, 61, 40,130,232, 44, 8, 43,232, 77, 16, 79,123, 89,132,189, 8,130, 39,255,166,224,
-193, 63,224, 77, 65, 16, 68,144,101,157,177,103,186, 43,179,243,219,136, 26,152,203, 12,195, 76,245,171,204,247, 34, 50,223,139,
-208, 63,252,248,210,224,137,120, 13, 22, 56, 19,133,184,197, 99, 66,246, 11, 8, 60,222,165, 95,217,242, 15,196,157, 98,194, 15,
-149, 11,204,103,131,147,139,215, 39,235, 91, 31,145, 93, 56, 38, 6, 88,215,217,125,223,141,250,108,199,114,176, 53,209,236,189,
- 62,113,120,244, 7,228,250, 72,145, 29, 72,155,112,180,152, 13,224, 21,170,157,177,159,123,163, 58,215,244, 30, 12, 41,216, 28,
-241,219,101,208,227,141,165,225,141, 75,180, 10,170,180, 22,204,125,244,211,253,252,113,243, 94,155, 81, 81,163,101, 64,148,147,
-176, 67,148,155,137, 20,214,219,195,186,239,172, 24, 70, 51, 41,118, 58,114,252, 71,163, 8,209,140,188,179,105, 0,173,146, 60,
- 79, 96, 38, 64,162,125,135,159, 37,179,238,129,124, 86,142, 54,119,108,180, 80, 14, 88,210,241,152,189, 24,170, 47,202, 65, 69,
- 54, 59,101,118,209, 79,154,114, 36, 69,178,137,148, 39,191,160,137, 40,153, 74,107,106,110,163,136, 59,138,141, 55,196, 28,197,
-165, 27,196,165, 83, 7,182,135, 49,143, 55, 43,193,147, 41,131, 57,130,140,116, 38, 83,186, 48, 96,207,147,136, 85, 54,215,115,
- 24, 48,145, 65, 2,142,214,144, 68,188, 1,151,202,237,182, 21,135,100, 31,101,167, 79,221, 90,198,214,206,218,161,230, 6,100,
-125,229,252,169, 56,164,199,116, 87,169,140,136,124,189,218,186, 79,101,141, 52,162,185,142,182,174,151,219,236,250,229, 74, 15,
-226,252, 91, 38,109, 67, 25,228, 92,152,151,138,106,155,178,166,255,170, 56, 53,177,103, 23, 11, 85,211, 2,184, 14,243, 75,117,
- 91,127, 40,245, 93,120,184, 5,180,219, 63, 40, 51,128, 14, 32,221,174, 24, 20,182,123, 7, 67, 77, 52, 85, 56, 92,138,247, 66,
-196,206, 1, 2, 38,232, 30, 57,136,165,132,199, 26,150,210,187, 85,210, 64,133, 29, 59, 52,111, 5,217,162,160, 58,181,169,182,
-227, 90, 14,215,226,113,216,145,200, 35, 97,252,233, 28,197,118,234,181,169,196, 0, 7,172,149,160,141, 10, 86,146,242,137,165,
-120,197, 1, 37, 96, 69,236, 89,150, 67, 83, 1, 84,162,236,169,133,152, 40,114, 65, 7,147,198,233, 42, 10,119,209,237, 97,235,
-144,139,156,233,229,209, 61, 95, 85,186,208,199, 46, 34,235,161,118,215,202,139, 83,124,229,202, 1,105,144, 80, 31, 46,111,115,
- 60, 70,113,141,136, 25,185,146, 33,227,193,142, 43,149,220,253, 81, 30,239,232,221,145,162,154, 92, 79,193, 91, 84,183,208,216,
-245,177,141, 17, 54, 94,244, 74,235,171, 31, 76,218,172,128, 64,137,207,116,209,237,251,124, 1, 51,137,129,170,104,122, 67,235,
-154, 55, 62,216,229,140, 95,229,244,229,134,217, 21, 47, 84, 17,117,236, 0,196, 25,196,179, 83,194,107,222, 41, 33,210, 30, 57,
- 3,219,202,202,186,136,121, 81, 20, 49,152, 65,218,211,152,195,179, 47,159,221,252,243,232,223, 55,127,203, 1,235, 43, 88,128,
-182, 21, 52, 58,198, 44,221, 82,202,105,162,211,192,181,196, 62,153, 65,129,106,188, 76,156,221, 53,160,219,226,180,156,238,142,
-167,195, 71,159, 60,127,186,252,229,142,119, 61,144, 12, 10,243,156,245, 28, 0, 8,177, 98,213,254,194,214, 54, 90, 84,168,169,
- 7, 58, 2,160,218,177,174, 78, 90,245, 88, 28,160,120, 7,163,166,162,102,148, 99, 7,148,124,243,251, 23, 95,203,215,223,126,
-246,226,197,213,163,167, 31,188, 59, 60,158,215,110, 94, 22,187,223,237,150,253, 87,207, 63,253,254,187,111, 94,189,190, 82,244,
-248,251,163,172, 89,251,160, 86, 4, 54, 6, 96, 1, 95,226,109, 36,217,202,212,154, 19, 78, 51, 94, 52, 10,162, 61,166,216,228,
- 53, 80, 3,227,134, 19,186,123, 39,178,181,113,150, 93,108, 61,206,133,204, 3, 91, 28,187, 38,111,218,146, 84, 33,227,237, 16,
-120,183, 10, 43,182,129, 17,187,222, 28,212,251, 31,127,120,120,239,243,159,127,121,243,211,159,191,210,232,202,207,113,151,131,
- 27, 29, 97, 13, 79,197,128, 79, 64,203,108,166, 69, 15, 91,112, 34,168, 73,144,101, 70, 5, 9,170,242,212,170,244, 62, 0, 83,
-178, 29, 14,236, 47,113, 43,248, 40, 17,234, 68, 71,175, 6,202,153,114, 92, 61, 80,144,201,227, 24,235, 0, 70,133,213, 14, 74,
-114, 49,146,226,224, 78,137,135,237,140,244,109, 98,185,165,131,218, 48, 81,154, 65,177,225, 32,143,248,239, 88,210, 29, 59, 18,
-232,176, 27, 52,240,247,132,239,131,142, 52, 40, 75,219,148, 76, 24, 12, 24,105, 42,255, 11, 64,210,213,243, 72, 82, 67, 65,187,
-109,183,221,221, 59,195,238,138, 69,160, 37, 2, 17, 33, 2, 66, 66,254, 2, 18,186, 63,120,191,128, 0, 2,226,147, 32, 65, 4,
- 36,144,160,213, 73,220,233, 52, 55,215,243,209,237,182,219,110, 83,229, 13, 38,153,209,104,166,221,237,247,170,252,234,213,211,
-236, 40, 90,166,108, 22, 14,170,113, 78,113,166, 73, 92,140,155,177, 69,108, 36,250, 84,150, 66,177, 40, 7,144, 83, 43, 45, 40,
-144, 48,227,110,195, 67, 50, 32,107,103, 39, 7,101, 25,229, 82, 47,175,136,152,115,254,200,211,119, 22,215, 71,116,122,236,189,
- 74, 87,191,250, 46, 34, 40,180,235,234, 99,190,181,134,106,223, 0,254, 97,183, 75,192, 13, 90,205,164,230,139,213, 14, 23,100,
-178, 61,165, 60,137, 14, 16,186,108, 39,229, 89,209,148, 93, 25,230, 15, 75, 9,158, 67, 48, 43,221, 0,173,191, 7,176,245,171,
- 26,140,238,145, 74,144, 67,237, 22,240,112,226, 82,229, 29, 32,161,217,229,161, 49, 46,225,231, 74,115,159, 36,253,210,135,194,
-186,204, 66,243,114,100, 57, 48,255, 18,180,100, 53, 67, 58, 30,199, 48,232,203,165, 56,211,208,184, 8, 27, 13,175,161,112,192,
-236,135,118,113,107, 71,245,114, 66,226,112,134,181, 94,214, 0, 90,158,140,251, 94,168, 72,223, 13,179, 18,226,226,205,153, 65,
-187, 40,158,169,166, 92,109,186, 77, 1,246, 17,115,213,188,103, 30,215, 34, 86,234,160, 84,192,111, 33, 75,105, 90,158, 2, 93,
-156,177,251,187,101, 68, 90, 72,181,233, 18,105, 29,128, 1, 15,138,111,166, 48, 93, 52,199,152,231,124,198,246, 74, 23,151,124,
-144, 55,209,149, 20, 34, 18,249,202,137, 1,235,137, 30,242, 98,204,235, 76,218, 24,251,109,215, 38,112,103,240,157, 24,118, 55,
- 0, 20,248, 20,200, 96, 41, 83, 22,125, 27,136, 72,131, 14, 15,188,120, 90,129,167, 38, 2,253, 41, 19, 60,205,121,135,129,253,
- 70,177,107,194,108,244, 93,106, 69,203,246,102,217,128, 90,115, 8, 25, 11,249, 91,211,133,130, 27, 78,111, 87, 22, 44,197, 94,
- 80, 32, 18, 43, 4,125,110,160, 39,222, 0,178, 90,144,159,109, 33,246, 40,186,170,141,158,213, 15,128,213, 11,203,216,197, 96,
- 85, 58, 74,237, 18,249,127,174,154, 73, 42,224, 69,170, 45,168, 20,121,243,168, 65,105,150,149, 54, 54,106,214,230,149,140,191,
- 33,137,220, 40, 38, 6, 18,161,103, 6, 7,158, 59,246,148, 99, 55,179,200,183,110,108,234,182,114,163, 56, 27,209,130,253,144,
- 13, 81, 58, 73,209,213,250,144,168,137,126,207, 81, 72,212,184,240,222,226,217,104,102, 0,135,121, 2, 20, 98, 23, 39,194,214,
- 65, 31, 75, 25, 82, 4,103,152,199,230,237, 69, 68,191,217,107,118,123,181,214, 58,115,123, 43,177, 44, 14,188,227, 92, 38,154,
-232,146,141, 32, 16,223,204,146,201, 26,223,205,136, 81, 27,133,197,139,170, 98, 67, 74,124,167,122,194,238,170,137,125,137,213,
- 74, 84, 84, 71, 6, 89,189,195, 42,108,167, 43,102,230, 81, 59,253,143,171,228, 83, 86, 99, 36,160, 38,186,208,243,168,162, 26,
- 8,121, 19,111, 55, 91,100, 8,226,240, 52, 62, 28, 94,125,245,245,119,127, 31, 31,203,235, 39,243,185, 30,129,123, 7,171,104,
-122, 54,251,195, 58,196,112,252,152,138, 2,235,227,133, 35, 1,249,223,236,148,199,208, 7, 19,237, 78,254,251,223,171,159,255,
-249,254,199,111,126,184,247, 63, 29, 95, 31,201, 92,217, 41,140,197,176,224,164,169,233,228,208,116, 44,130,176,217, 99,235, 55,
- 19,233,246,143,109,175, 74,199, 94, 19,253, 41,224, 85, 90, 2,182,173,202,250,244,102,252,243,221,239,159, 60,190,249,226, 51,
-243,237, 11, 39,220,163,216, 30,158,253,201, 42, 57, 57, 11,241, 36, 46,127,132,119,103,125, 29, 11, 0, 43,226,195, 33,226, 6,
- 77,130,102,198,137, 14,212,162,170, 30, 11, 79,232,216, 51, 36,120,252,214, 57,236,183,245, 66,113,165,229, 92, 62,149,199, 70,
-236, 86, 36,185,154, 0, 40,223, 82,213, 87,154, 41,178,145, 41, 37,194,121, 65, 75, 2,197,197, 71, 72, 52, 88,112,219,108,183,
-122, 55,236,191,124,249,203,251, 95,255,250, 77, 32, 68,219, 27, 36, 11,115, 17,105, 31,210,218,143, 9, 8,246,106, 27,229,103,
- 53,237,155,150, 50,132,152,154,237,109, 28, 58,195,169, 58, 96, 67,158,189,114,215,109,163,123, 60,226, 87,234,189,195,167,241,
- 46, 15, 64,192,124, 10,207,162,239, 75,135, 92,108, 42, 59,159,125,164,229,130,110, 3, 40,229,114,212, 5,132, 18, 28,116,153,
-115,135,208, 99, 21, 82, 76,100, 45,158, 45,219, 91, 71,127, 40, 68,239,211,178,182,184,197,162,186,233, 48,130,229,209,132,253,
- 34,114,219, 46,108,145,112,116, 96,154,205,172,123,245,191, 0, 28, 93,203,142,228, 52, 20,245, 43,137,147,174,154, 30, 96,211,
- 98, 52, 18,176, 2,150,240, 43,124, 2,159,136,196, 63, 32,182, 45, 33, 49,154,161, 23, 13, 12, 51,221, 83,174,196,137, 29, 63,
-194, 57,174,101,171,170,229,196,246,245, 57,215,247,158,163,127,250,249, 7, 49, 58,193,218, 70, 0, 85,166, 72,214, 1,167,219,
- 21, 47, 43, 26,159,216,251, 46,152,234,157, 17,136, 14,173,124,202,173, 90, 7,112,218,128, 20, 55,183,109, 21,169,175, 79, 55,
-147,161, 78,203,168,234,244, 89,157,172, 88,142,121,168, 32,234,130, 69, 51,125, 58, 9, 11,114,149,252, 39,214,103,236,128,211,
-177,204, 84,187, 25,214,213,105,221,177,123,154,197,223,234,211,190, 82, 70,192,210,138, 50,225, 7, 67, 71,221, 73,252,111,234,
-214, 57,156, 68, 47, 58,102,106,176,197, 44, 31, 60,182, 54, 37, 77,129,252, 10,124, 89, 41,154,156,251, 81, 77,188, 14,162,145,
- 83, 72,183,114, 3,178,193,132, 35, 36, 79,227,208, 76, 57,196, 4, 4,170, 39, 26, 6,116, 32,126,172,185,163,234, 28, 9, 60,
- 0,126,214, 25,177,166, 82, 42,223,215,146, 78, 43,195, 3,209, 38,109, 11, 42,117,141,120,187,153,233,100, 87, 40, 73,167,232,
- 14,140,247,138, 33, 19,155, 70,125,166,237, 37, 40,188,100,254,127, 8,134, 18, 25, 85, 2, 35, 28,173,220, 66,104,118,208,130,
-109, 10, 6,153, 34,232,249,216,116,238,232, 21,193,254,102,185, 81, 43,151,130, 34, 37,230,167,188, 57, 74,183,104,103, 86, 0,
- 17, 28,244,162,172,224,194,155,120, 70,192,141,123,127, 88, 13,250,157, 98,217,253, 92, 2, 6, 63,109,149,173, 41,160, 18,216,
-132,145,202, 5,245, 8,171,248,234,115,165,118,231,194,188,247,196, 91, 32,118, 56,115, 2, 17,183, 82,205, 12, 54, 3,192,158,
- 15,107,154, 84, 0,206, 65,246,116,215,170, 41, 40,114,218, 69, 63, 82, 96,155, 23, 8,132,235,152,123, 99,130,169, 56,226, 18,
-139,254, 89,176,164, 4, 43,174,168,214,198, 43, 10,246,238, 81, 7, 36, 28,160, 36,160, 46,154, 9,213, 3, 36,147,173,249,192,
- 7, 0,174,169, 82,239, 78, 54,249,221, 14,187,152,237,203,236,189,145,173,228, 59,183,246, 49,123, 88, 4,137, 66,215,164,194,
- 76, 61,135, 69, 95,227,210,140, 21,176, 99,129, 59, 91, 61, 6,237, 61, 34, 78, 77,205, 34,235,204,228, 45, 48, 50, 21, 31, 76,
-179,211,232,177,126,240,213, 61, 39, 60, 93,174, 52,136,222,113,186,129,146, 14, 85, 44,145, 26,192, 6,175,141,230, 25,181, 18,
-140, 45, 51,129,174,136, 41, 39, 74,115,198, 93,132,156,241,154,197,179,136,115, 74,238,136,142,135,118,225,133,165,237, 76,119,
- 82,213, 44, 25,164,238,130,191, 81,134, 68,118, 8,250,173,146,157,205,240,150, 30,224, 49,202,152,171,235,164, 94, 15,192, 43,
-182, 30, 5, 6, 55,213, 48, 38,158,106,104, 85,143, 86,138,165,101,222,219, 74,101, 54,226,210,130, 62,233, 53,115,146, 32,249,
-148,168, 7,111,177,138,209, 46, 15,244,250, 16,147,178, 64, 3, 55,212,221,162,140,128,166, 27,210,151, 63,202, 87,223,223,189,
-253, 61,123,247, 31, 59,244, 55, 83,230,108,207, 75, 31,142, 35,102,172, 25,138,232, 0,102, 70, 79,133,119, 12, 97,207, 76,173,
- 97, 95,109, 67,138,251, 95,151,191,247,211,183,223,189,254, 98,192,106,203,190,200,179, 60,206,246,102,100,229, 46, 75,223,219,
- 33,124,238,217,153,140, 15,246, 36,117,236,250,238,197, 93,255, 18,163,120,149, 89,156,138, 21, 25, 98, 71,246,187, 92,221,191,
-238,241,241,254,242,225,254,195,211,195, 27,255,241,157,187,190, 93, 31,238,151, 55,127,248,119,239,195,227, 67,124,255, 20,254,
-137,121,171,105,165, 8,212,118, 45,197,211, 29, 7,172, 63, 52, 33, 86, 67,187,230,118,244,201, 44, 45, 86, 90,195, 3,212,215,
- 44, 4,149,214,100, 76,217, 85,169,214, 64, 77,221,224, 85,102, 39,120, 47, 5,202,230, 13,120,119, 26,216,129,145, 48,251, 27,
-181,125,154,138,157,156,110,165,190,235, 95,127,253,205,159,151,187, 95,126,253,173,158, 62, 78,242,150,174,173,163, 78,174,175,
- 38, 54, 44, 40, 34,240,176,185, 41, 73,209,244,214,215,141,226,243,180,191,192, 4, 5, 38,124, 89, 31, 83,148,102,113,156, 1,
-180, 4, 68, 86,125,126,169,135, 80,166, 4,160,118, 6,141, 51,224,142,222, 24,236, 35,222, 34,208, 39, 23, 27, 25,241, 68,173,
- 83, 29, 45, 72, 86, 2,215, 90,115, 92,118, 9, 54,112, 19,170,147,216, 52, 33,182,206,249,189,170,206,200,160,204,136,169,235,
- 84,142,222, 90,188,160,221,247,224,253, 20, 48, 55, 75,135, 17,197,195,235, 89, 70,243,220,253, 47, 0, 73,215,178, 34,199, 17,
- 4,187,222,221, 51, 61,203, 72, 72, 70,224,131, 15, 6,129,116, 17,250, 8,255,134,192,255,230,175,208,167, 72, 96, 31,132,193,
- 62,120,188,238,233,169,174,119, 57,162,116, 91,118, 97, 31,181, 89,153, 17, 89,153, 17,234,211,175,191,224, 43,251,189, 10,159,
-100,223,214, 16,130, 50,248,201,100, 5,143,192,181,254,174, 43, 8,164,169, 0,243, 89, 28,121,183, 18,208,169, 28,137,249,142,
- 62, 54,220, 21,209, 84,104,181, 8,142, 39, 73, 21,178,233,188, 60,102, 98, 36, 42, 50,101, 63, 47,153, 30, 25,108, 0, 24,212,
-252, 4,112,131,202, 26,196, 61,115, 91, 14,223, 20, 68,188,210,150, 38, 6, 99,105, 89, 53, 33,144, 8, 72,193,129,162, 8,124,
-102, 83,123,136,220,155,137,146, 77, 13, 77, 67, 62,121, 98,127,120,177,118,102, 39,102,106,167,106,204, 56,126, 0,115,139, 44,
-100,218,226,174, 86, 88, 43,207,107, 95,158, 92,193,191, 65,233, 66,177, 0,109, 22,173, 4,248,150,165, 31, 43,170,126, 59,138,
-184,180,110, 28, 91,188,138,226,206,124,175, 1,225,230,130,228, 2, 92, 53,242,245,144, 88, 76,124, 65, 69,204, 58,139, 75,106,
-139, 3,241,176,108, 71,168,149,207,166, 73,115, 22,148, 2, 1,224,141,199,232, 86, 56,170, 86, 13, 37, 9,133, 88, 43, 74, 14,
-133, 38,182,244,162,230,227,171,166,167, 43, 62,129, 0, 46, 81,210,141,249,168, 40,126, 41,248,144, 18,144,134,164, 42,104, 70,
-222,222,213,189, 83,245,230,232,161,112,150, 71,114, 32,160,183,114,171, 49,170, 7,247,176,136, 23,251, 69,224,234, 11,143,179,
- 76, 54,202, 51,192,113,208,128,122,126,139, 63,253,124,122,163,108,216,111,181,241,189, 68, 80, 43, 24, 0,136,110,226, 52,111,
-162,104, 46, 16, 37,107,157,243, 19, 85,221,169,140,201, 37,105, 98, 50, 99, 88, 32, 65, 77, 22, 43, 87, 78,168,209,224, 80,247,
-110,185,240,220, 23, 32,235,202,158, 61,221,100,134, 3, 30, 69, 26,216, 1, 4,152,236,201,114,108,155, 42,236, 52,133,225, 6,
- 45,141, 30,145,253, 19,115,106, 21,195,139,129, 59,167, 8, 51,145, 5,136, 4, 7,128, 56,219,194,254, 22, 31,155,233, 18, 5,
-232,133,107, 15, 42,217,190, 11,226,177, 86,130, 13, 21,190,231,148, 38,185,229,170, 41, 30,119,224,119,194,177, 1,130, 24, 42,
- 81,182, 3,213,237, 72,158,243,205,145, 96, 69,245,128, 98,192,237, 2,181,171,238,107, 98,137, 2,131, 42, 49,212,122, 55,211,
-214,147,231, 76,107, 66,210,207, 53,121,117,107, 58,164, 26,254,108,226,198, 49, 75,127,147,207,184,107,147, 89,219,201, 92, 28,
- 0,168,162,161, 11, 48, 6,168,143, 46, 43,240, 78,119,190,115,170, 71, 83,253,129,171, 83,227,185, 25, 73,231,154,166, 17, 31,
- 18,168,249,129,143,135,210,162, 24,139,242, 28,253,151,195,181,155,107, 68, 34, 20,113, 50, 67,126, 88,176, 75, 67,169,200,225,
-108, 98, 4,109,249, 40,240,197,200, 36, 77, 90,191,155,222,168,233,188,206,237, 36,236,220,104, 25,161,155,123,133, 84, 24,204,
- 35,190,126,251, 36,221,143,127,124,141,165,110, 82,236,147, 49,161, 90,208,146, 48,118,137, 69, 81,155, 50,220, 47,178,218,144,
-219,131, 53,227,196,143, 25,220, 76,183,252,120,254,242,247, 95,219,233,221,135,247, 31,175, 46,164,252, 44,120, 25,198,174,218,
-213, 90, 14,133, 77,210,157, 37,149,133,112,250,184,105,179,187, 92,186,126,221,197, 25,127, 12,213,217, 65, 42, 81,213,168,148,
- 51,113, 92,134, 93,187,140, 3,143, 42,167,127,167,253, 86, 30,177,164,255, 16,239, 71,185,151, 45,113,109, 51,221,155,247, 19,
- 8,230,158,219,177,229,180, 13, 59,147,161, 15, 4,176,200,127,189, 48,134,244, 69,115,253, 80,141, 73,252,105, 12,196, 35, 6,
- 79,156, 17, 64,138, 0,116,163, 70, 1,210,200,202,177, 13, 58,252, 86, 78, 98,213, 59, 39, 80, 41, 4,126, 37, 79, 3, 46, 65,
-202, 18, 47,228, 15,111,174,211,203,143,191,125,254,231,155,255,125,158,215,198,254, 10,157,141, 30,168,255,148,251,175, 99, 8,
-122,166,146,141, 29, 3, 95,217,148,139,122, 33,114,162, 29,157,160,130,214, 33,180, 27, 86, 37, 75,112, 20,172, 35,102, 4,113,
-143, 75,214,224, 10,136,134,153,187, 16, 71,102, 10, 41,194, 25, 5, 38, 40, 15, 46,107,228, 57, 71, 95, 16, 84,158, 25,215, 2,
- 47,182, 49,174, 63, 23,138, 60,141,145, 11,238,103,139,137,166,129,137,203,224,137, 15,204,126, 82, 13,213, 96,177,138, 6,194,
- 37,135,120, 36,141, 4,215, 81,112,245,178,206,249,127, 1, 72,186,154,222,168,145, 32,218,159,110,219,201, 36, 33, 98, 87,144,
-160,160, 93, 16, 66, 8,110,252, 17, 46,251, 95,247,180,135, 61,237, 79, 88, 36, 46,104,247, 0, 82, 96,102,226,113,183,171,187,
-221,188,103, 14, 57,141, 52,158,216, 93,175,234,185,170,222,179,127,124,120, 73,162,161,220,194,201,130, 83,235,232,147, 94, 39,
- 55,247, 43,146,194, 58,199,156,210,146,246,133,188,134,202, 91, 64,231,113,112,116, 3, 66,224,129, 91,140,150, 51, 57,142,160,
-149, 93,238, 89, 4, 87,145,153,107, 68,192,114,229, 37, 82,173,155,157,121, 59,173, 49,225,252, 35,140,182,247,215,197,231,137,
- 68, 28,177,134,191, 38, 50,129, 43, 32,251,234,239, 72,200,115, 57,247,219, 50, 61, 14,251, 32, 22,104,153,216,105,178,156,185,
- 20,234, 48, 88, 59,224, 25,142,248,124,245, 28, 75, 57,167, 89,184, 53, 33, 32,226,198, 21, 21,159,174,166, 13,221, 14,193, 21,
- 58, 4, 4,232,162,244,206, 83, 87, 61, 16, 95, 58,241,116, 84, 65,254,109,150,117,169,113,166,113,134,103, 0, 93, 74, 14, 36,
- 63, 63,228,185,178,251,222,115,196, 79, 34,158, 4,125,135, 43,126, 57, 42, 91,148,249,163,105,251, 30,152,228,185, 9, 79,219,
- 16,124, 72, 60,163,226,190,233, 88, 26,247, 26, 57, 64, 58,138,144,115,252,208,209, 36, 10, 23,231, 38,178,160,168,110,155,251,
- 59, 67, 55, 42,154,220,117,220, 70,100,190,156,106,206,129, 83,188, 32,217, 81, 78,224, 18, 92,169,137, 54,184,249,161, 10,178,
- 49,162, 57,172,178,128,104,196,111,155,253, 39,223, 88, 73, 71, 42,138,130,164, 76,115, 70,225, 74,130, 49, 14,192,110,189,182,
-178,196, 82,234,237,203,219, 87,251,245,235,241, 63,196,126,199, 86, 50, 98,195,113, 42, 6,105,180, 35, 60, 34, 10,105,147, 96,
-117, 15,158,199,158, 24,174, 16,112,175,245, 86,152,115, 43,128, 99, 56,172,175, 61,221,123, 56, 74,202,175, 9,155,168,159,227,
- 18, 70, 67,194,164,161, 18,253, 53,232,126, 12, 80,109, 67,139, 32, 44,128,253, 62,231, 77, 52,204,109, 2,192,138,254, 54,250,
-193,106,154, 76,115,123, 41,207,171,166,199, 51,147,207,166,247, 19, 27, 87,137, 19, 93,121,169,146, 95, 20,165, 46,169,175, 3,
-184,204,108, 20, 48,254, 36,117,236,217,211, 50,214, 85,196, 74,218, 92,183,106, 38, 7,215, 73, 64, 22, 51,125,193, 87, 26, 48,
- 57,153,140, 79, 90,151,161,214,200,196, 87, 51, 33, 56,225,234,192,126,179,204,157, 80,218,151, 62,162, 11,231,113, 27, 14, 56,
-130, 35,223, 43,189,167,144,255,151, 61,169, 63, 30, 93, 40, 62,140, 40,112,116, 26,168, 75,216,198, 33,141, 84,166, 29,113, 40,
-112,172,132,147, 84, 2, 66, 25, 52, 95,187,121,229, 11,149,140,217,115,196,163,203, 22,240,248, 80,248,206, 29,191, 74,184,210,
-193,251,193,153, 72,212, 43,102,235,111,105,142,247, 60,162, 66, 15,199,139,146,231, 92,205,229,182,211,139,111,251, 57, 78,147,
-204,102, 28, 75, 47, 44, 53, 14,234,120,173,174, 76,191,134,196,193,220, 1, 7,190,106,215,219, 75, 38,150,221,238,112,243,230,
-242,241,211,155, 79, 31,231,233,255,111,197,184, 8,148,159,193,111, 27,210,124, 8,230, 92, 23, 20,245,186,164,171,131,238, 71,
- 74,113, 74, 97,215,253,148,109, 63,132,254,120,250,248,239,231,253,124,247,244,249,251,223, 95,159, 43,125, 18, 90,233, 81,235,
-147,175,152, 24, 98,126,237, 46,252,245,245,217,227, 95, 31, 61,187,189,122,242,238,242,151,223,118, 79,238,118, 55, 23, 87,187,
-209,184, 76, 25, 36,201,225,104,234, 65,163,136, 6, 27,159, 99,162, 18,246,170,114, 2, 50, 41, 46,128, 22,160,102,139, 7,212,
- 12, 40, 83, 43, 30, 65, 1, 93,138, 28,104,195,185, 70,218,193, 45,192, 83,197,199, 54,208,119, 21, 20, 91,141,180,250,226,222,
-170, 98, 63, 29, 41,208, 20,158,138,109,110,118,107,226,180,230,168,243, 76, 82, 94,105,135,198,183, 9,168, 56, 19,125, 83,117,
-102,103, 17,100,218,247,200, 74,215,195,243, 23,111,255,250,180,251,243,239,127,198,187, 4,156, 6,119,149, 8, 68, 54, 78, 74,
-119, 65,167,116,170, 35,161, 58, 70,158,192,173, 91,218, 61,138, 49,156, 43,212,111, 14, 56,167,211,241,204, 6, 81,145,221,167,
- 3,208,165,128, 47,106, 17,148,250,200, 14,244, 88, 85, 94,197,131,229,246, 45, 85, 22,241, 79,224,104, 78,125, 61, 27, 80,223,
-110, 63, 3, 12,150, 92, 82, 47,107,168,192,214,211,196, 37,120,190,225, 51,172, 24,192, 7, 43, 78, 84, 75,150,210,112, 43,176,
-198,113,104,228,208,164,121, 84,227,134,236, 46,100, 11,164,207,200,220,197, 74, 93,238,165,253, 16,128,165, 43,217,145,163,136,
-130,149, 89,185,212, 50,238,217,220, 30,141,145,140,198, 22, 96, 14,246, 9, 16, 95,194,141,239,227, 39,184,115,231, 96, 9, 33,
- 64,128, 4,150,144,103,220,221,181,229, 78, 68,218,215,145,106,170, 43,151,120,241, 50,227,189,104,191,251,254,117,110, 17,148,
-222,231, 14, 43, 57,131,236,196,228,218,230, 65, 83,124, 5,156, 96,251, 88,141,191, 21, 53,226,245,105, 14, 42,174, 70, 31,230,
-153,221, 29,250,185, 48, 68, 34,140,210,247,167,106,220,170, 22, 23,224,173,144, 5,109, 25,193,201,133, 97,240,121, 9, 1, 65,
-225,152,102,236,251,251,213,136,139, 35, 50,235, 56,109, 66,135,149,115, 31, 93, 14,188,106, 3, 22,129, 15, 45, 31,220,170,211,
-140, 20, 10, 17, 48,103,222,176,176, 33, 51,243, 23, 30,145, 42, 86, 90, 74,133,241,100,113,145,149, 87, 45,105, 38,171,223, 59,
-150,179,165, 17,156,191, 27,229,104, 58,129, 25,193,108, 37, 30,210,203, 66, 20, 55,141, 30, 52,159, 2, 73, 28,176, 0,120,214,
- 26,175,145,123, 37,140,114,183, 99,241, 56,173,168,148,100, 27, 44, 60,189, 58,228,152, 65,187,150,159, 25,217,137, 12, 20, 19,
-248, 39, 23,131,196, 5,180,173, 67, 24,102,145,102,105,172, 28, 11,189,165,197, 0,160, 72,154,120, 39,232,160, 27,120,190,207,
- 30,193,153,190, 50,217,168,192, 59, 31, 65,223, 92,182,177, 6, 19,102, 85,196,125, 21,125, 83, 19, 95, 10, 83, 38,172,115,239,
- 2,251,115,234, 3, 66, 41, 50, 28,252, 80, 90, 16, 81,202,169, 18, 89, 32,224, 45, 32,105,117,158,118, 52, 57,232, 57,176,128,
-101, 41,113,232,212,217, 17,216, 19,167,153, 70, 40,248,236,105,137,231,251,203, 47,143,199,255,242,219,220, 87,171,129, 54,183,
- 90,116,165,114,170,170, 72,103, 17, 40,102, 48,138,246,170, 1, 54, 33,224,155, 71, 13,128,157,215,162, 67, 54,116,185, 70,144,
-161,170,217, 88,228, 4,236,189,200,250,170, 86, 0, 88,155,228, 36,237,173, 89, 79,203,106,163, 24,232,209,134,105, 76, 94,214,
- 70,207,113, 94, 17, 80,133,228,117, 46,219, 63, 69,124, 51,222,234, 89,208, 84,143, 83, 74, 77,163, 65,168,104,104,225, 88,150,
- 92,125, 7,121, 20,212, 82,180, 40,131,107, 35,198, 43, 91,177,104,210,240, 85,114, 25,108, 96, 58,108,208, 45,183,226,221,130,
-176,105, 54, 60,145, 41,214,162,239, 14,237,237, 51,144, 20,236,178, 73,211,150, 84,240, 11,213,150,136,127, 5,255, 1,235,150,
-213,101, 30, 83,130,240,134, 0,196,142,115,213,201, 90,178,177,213, 81,151, 3, 50,219,229,132, 23, 56, 9, 68,127, 68, 39, 29,
- 67,249,165,161, 81,146, 86,148, 44,203, 70,143,209,179,177, 12,173, 39, 34,207,108, 50,197,101, 98, 97, 10,136,136,131, 84, 74,
-139, 50,108,105,170,190,130, 76,126, 18, 25, 59,117, 19, 70,247,248,113,173,236,164,160,233, 12,128,158,122, 16,202,219,177, 15,
- 1,134, 99, 83,123, 21, 84,252, 74,226,163, 39,159,173, 81,114,168,100, 31,241,213, 26, 74, 42,131, 85,136,167,182,183,186, 47,
-227, 8, 6, 71, 30, 79,191,184, 6,220,103,126,124,183,123,126,119, 51, 29,186,183,239,254,145,219,105, 4,191,198,160,135,101,
-114,136,114, 30,172,206,211, 6,165, 43, 93, 88,129, 33,138,197, 6,241,136,205, 15, 96, 4,161, 90,223,252,253,230,167, 63, 79,
- 23, 87,223, 62,251,236,213,147, 79,190,184,188,126, 90,236,217,112,113,211,159, 63,217,239,159,237,239, 94,158,191,248,122,188,
-253,198,156,127, 37,221,167,191,255, 50,255,250,219,246,215, 31, 74,134,235,199, 47, 95,236,118,183, 87, 79,245,138,100, 73, 30,
-144,178,131, 10,117,253, 0, 6,232,104, 80,148, 57,251,115,216,214, 68, 43,168, 57,199, 57,178,190,163, 78,153,120,104,194, 67,
-114, 60,216,197, 88, 53,234,132,132, 66,115,213,238, 50,118, 94,243, 65, 22, 12, 30,139, 37, 24,232,162, 68,197,172,249,104,156,
-174,102,128,137, 8,150, 29,161,162,146,224,193,148, 67,144, 7, 87,153, 13,118, 63,249,131,162, 3,146,105,110, 63,191,249,119,
-125,254,195,143, 63,223,151,119,123,219, 55,136,219,128, 99,160, 38,149, 1, 60, 20, 97,145,171, 65,174,170,149,176, 96, 31, 54,
- 56, 48, 80,115, 57,132,152,172,199,150, 5,141,239,197,174,200, 51, 79, 41,240, 92,134, 11, 94,145,219, 65, 11,109, 16,146,237,
- 68,109,137,211,198, 83,222,232,173, 11,154,202,131, 13, 48,149, 66, 55, 69,106, 60,185,187, 60,205, 59, 3, 77,108, 17, 81,250,
- 93,155, 23,123, 98, 91,115, 95,207,111,153,126, 56,204,235,194, 50,149, 24,173, 9,200, 42,232,222, 1,124,174,162,154, 69,130,
-229,113,121, 17, 30, 90,188,236,127, 1, 72,186,154, 30,187,105, 40, 26,127,196,249,122, 31, 76,167, 48,180,176, 24,132,144, 96,
-209, 5, 8, 9,137, 21, 11, 86, 8,137, 45,255, 12,126, 11, 43, 54,237,174, 42,176, 64, 2, 81,132, 4, 26, 68, 81,251, 94, 94,
- 18,199,142,237,152,115,194, 15,120,147,196, 99,223,123,238,245,185,231, 96, 91, 39, 87,229, 6,105,114, 90,202,172, 55, 63, 33,
-126, 16, 7,185,122,196, 17,163,115,224,232, 29,128,164, 85,150, 40,173,226,213,135,119,117, 19,174, 22, 63,102, 67, 57,183, 54,
- 80,152,160, 75,117,192,209,161, 49,146, 73, 19, 75,132,180,244, 65,121,156,248,144,154,147,102, 16,156,202,179, 92,154,216,187,
-101, 30,246,197,232,197,195,209,143,139,222, 70, 28, 67, 85, 68,155, 86,108, 53,210,230,118,197,100,149,218,167, 57,109,227,221,
- 65,157,181,223,215,161,154, 83, 37, 56,180,203,203, 93, 41,187,138, 98,254,189,145,141, 33,173, 93,217, 66, 43,111,174,141,113,
-111, 32,146,142,106,190, 47, 12,229,107, 87, 94,152,237,241,155, 61,208, 82, 75, 93,128, 76, 71,194,136,231,170, 57,144,162,139,
-199, 11,124, 88,157, 87, 21,228, 72,219,101, 32, 45, 33, 3,234, 32,173, 12, 91,191,193, 83,130,184, 37, 25, 11, 79, 34, 87,133,
-158,241,133,155,145,237,105, 94,132, 26,185, 23,169,205,255, 19, 48, 10,206,154,146,149, 29, 12,192,196, 34,231, 84,180, 50,188,
-170, 75, 90,220, 52, 73, 5,230,114,250,119,162, 22,102, 19,102,187, 16, 53,106, 18,248,108,253,114,205, 26, 56, 75,209,203,146,
-146, 60,171,220,201,139, 29,108,174,151,121, 46, 61,163, 70, 20,245, 84, 76, 82, 13, 43, 41, 24,134, 29, 37, 78,142,232, 70,202,
-127,162,221, 45,189,195,119,229,186,214,129, 78,133, 8, 99,242,116, 9,244, 54,177, 5,233,172,222, 32,176, 34,219, 72, 43, 71,
- 68,135,150,221,187,128, 26, 50,106,195, 43,119,236,216,148, 38, 13,248,142,195,128,183, 45,134,132,108,136, 51,230, 40,154, 29,
-194, 72,130, 15, 82, 24,169,132, 13, 2,172, 38, 67, 26, 85,170,217,100, 17,200,222,146, 30,161,159,188, 52,234,250,152, 78, 35,
-243, 16,166, 33,112,208, 76,118,161,168,172,167,154,157,218,158, 66, 51, 20, 84, 41, 43,199, 85, 3, 22, 55,149,115,173,116,196,
- 82, 38,114, 11,116, 67,243,152,194,166,190, 72,157,222,180, 35,165, 28,173,220,107, 66,200,115,200, 28,147, 95, 35,105,253,202,
-121,122,234,106, 71, 25,108,132, 55,218, 80, 52, 65, 78, 52, 12, 65,249,168,105, 83,152, 67,175, 1,126, 29,118, 40,170,156, 57,
- 77, 40, 18,234,168, 28,234, 52,160,216, 98,169,133,176,137,141,159,127, 1,118,232, 36,142,195, 38,109,169,232,232, 75, 69, 51,
-156,196,171,146,110, 53,243,142, 14,197,189, 80, 93, 52,246, 26,239, 84,213, 3,192, 45,160, 18, 5, 60,129, 49,245, 97,229, 45,
- 70,149,250, 40,219,206, 0, 18,179,151,232, 86, 68,243,203, 78, 54, 62, 29,176, 90,123,222,181,146,163,144,104,248,133,244, 94,
-174,200,181,185, 11,233,101,166,167,123,163,232, 39,188,110,222,115,120,237,227,214,145,247,219,184, 2,167,156, 54, 1, 50,189,
-178,105, 66,105, 19,212,164, 23,209,117,165,199, 31,180,193,100, 44,136,158, 94, 12,205,238,183,155, 7,215, 95,126,253,222,241,
-241,189, 39,223, 61,189,155,239,194,195,195,235, 46, 11, 82, 42,115,181, 79, 76, 31,113, 80, 46, 30,112,142, 73, 1, 22,106,175,
-115, 23,243, 88,182,149,121,208,185,223,255,122,246,237, 55,191,118,111,221,126,246,225, 71, 95,125,254,201,253,155, 21,201,142,
-142,145,227,122,113,197, 47,223, 15,143,127,124,250,243, 15,207,254,232,255,182,214,158,235,179, 28,204, 85,170,110,223,126,247,
-253, 15,110,190,248,244,157, 71,143, 62,126,243,170,126,254,231,243,225,164,220,105,246,101, 83, 97,217, 1,228, 81,215, 23,217,
- 28,163,237,163,217,229,121, 34, 0, 63, 32,151,155, 21,123, 18,168,174,140,209, 77,121,153, 57,173,154,218,176,179,198,156,214,
-117,135, 45,166,147,116,164,144, 99, 45,200,121, 23,172, 20,207, 5,201,137,153,229, 80,180,155,106, 23,254, 3, 37, 97, 39, 18,
- 36,125, 37, 73, 42, 77,212,249,139,130,170,247, 66,220, 59, 30,187,171,219, 39, 63,217,115,184,187, 62, 52,169,165,254, 27,224,
-140, 1, 30, 19,168,184,203,241, 21,237, 35,101, 19,125, 97,210, 56,152,235,242,100,154,101, 65,225, 68, 13,236,112, 48,136,121,
-213,107,147,140,181, 31,229,178, 51,216, 66, 93, 64, 14,174,101, 16,135,189,114,226,112,137,254,168,124, 35, 61,135,185,163,178,
-186,156, 74,133,132,112, 14, 47, 0, 84, 16,158,144, 99,234,194, 69, 20,206,162, 5, 90,172, 40, 82, 61, 93, 98, 96,231,219,166,
-210,149,216, 13, 64,118, 61,133,254, 0,199, 44,109,132,236, 25, 37,244, 42,205,232,108,133,223,163,140, 46, 47, 41, 84, 43,105,
- 65, 36,143, 85, 90,254, 39, 0, 73, 87,179, 27, 73, 13, 6,221,118,187,221,238,206, 76,102,179, 73, 16, 43, 4, 28, 22,237,129,
- 60, 2, 28, 17, 60, 5,207,199, 3,112, 91,137,156,184, 32,126, 14, 72,104, 47, 8,177,226, 71, 90,133,201, 76,207,116,187,109,
-183,109,170, 58,167,220, 70,138,219,174,175,202,254,190,170, 58,205, 58,217,228,221,144, 23,163,164,119,245, 28, 38, 78, 38,128,
-113, 80,211,178, 44, 22, 54, 51,134,104,135, 46,111, 71,190,250,142,185,151,216,149, 23, 32, 71,193,250,209, 54,197,203,103,117,
- 87,166, 33, 14, 99,238,180,110, 24, 40,188, 31,211, 78,207, 23,218,204, 78,240,109, 91, 97,187, 62, 94,110,196, 67, 83, 32,147,
- 83, 10,226, 16, 53, 64,115, 39, 14,123,144, 52,224, 75,115, 64,137, 44,128, 10,201, 46, 31, 80,152, 45,150, 51,204, 40,117,153,
-150,209,236,251,246,124,168, 12, 59,153, 0,210,169,118,207, 32, 17,187, 93, 2,215, 75,132,157, 94,183,210,153,230, 66,185, 22,
- 75,218, 40, 27,113, 80, 79, 88,129, 74,217, 70, 7,148,132, 14,188, 7, 84, 10,122, 50, 48,198, 56,155,124,177, 44,215,168,155,
-180, 86,162,109, 31, 31, 47,151,154, 33, 44,107, 3,235,122,185, 66,127,159,193,182,125, 98,119,120,203,168, 94,192, 35, 68, 70,
- 88,131,157,193, 93, 13, 5, 2, 40, 97,204,178,171,155,204, 36, 8,126,159, 74,216, 20, 7,112, 68,203,113,253, 66, 15,117,165,
- 83,177, 28, 86,228,236,203,184,122, 30,182,180, 94,175, 7, 54, 65,129, 45, 66, 13,202, 62, 85,103,200,174,213,250, 16, 80,232,
-178, 31, 92, 96,159,160,211, 57,128, 87,120, 3, 45,155, 26, 32, 74, 24,128, 20,144, 54, 13,212,172, 42,158,133, 92,178, 35,150,
- 46,191, 32,126,224,140, 13,179,230, 35,232, 0,136,237,187,227,113,121,185, 43,251,203,249, 33, 86, 13,160,156,247,182, 14, 7,
- 88,114,155,244, 69, 56,205,152, 52,209, 41,208,206, 4, 78, 15, 69,138,149,223,208,156, 20,251,140,247,221,128,174, 78,181,158,
- 65, 33, 12, 95, 18,204,210,229, 41, 65, 61, 96, 38, 15, 25,153,164, 83, 27,127, 39,173,118, 24,192, 93, 96,175,159, 24,217, 70,
-141, 39,181,166,149,158,138,220,230,202,227, 16,204,140, 40, 2,153,155,113,202, 23,173,141,130, 68,165,199,192,127,158,173, 49,
-154,206, 3,153, 70, 3,156, 86,168,146, 21,167, 88, 24, 4, 42,167, 30,114, 60,247, 28,157, 54, 88, 19,240,178,121,167,204, 88,
-146,103,204, 34,192, 50,226,175,102, 94, 28,118,240, 42,139,233, 29,253, 24,128, 72,146,147, 60, 99,116,116, 52,225, 61,110, 6,
- 32, 15,139, 99, 83, 14,223, 3,210, 32,194, 73,120,253, 4, 1,162,121, 20, 5,116,184,165,155,206, 77,173, 39, 85,157,193, 96,
-172, 8,114,129, 14, 44,177, 49,198, 52,245, 60,213,236,245, 98,176, 83,167,169,124, 83, 72,183,165, 10,170, 15,229, 92, 51, 30,
-100,177,224, 77,150, 46,106, 20,153,203, 13,237,197,229,248,116, 71,185, 38, 72, 24,124,186,158,126,102,116,185,202,229,236, 84,
-175,184,128, 57, 71, 38,232,100,161,159,146, 45,214,151, 85,185,190,181,114,221,153,108, 39,102, 62,217, 3, 29,232,170, 25,182,
-114,220, 50,215,182,237, 24, 33, 54, 31,241,175, 88,213,156, 65,213,186,171,248,229, 23,175,238, 94,125,126,255,250,247, 95,222,
-190, 61, 60, 12,213,206,103,221,208, 14, 12,194,164, 22,131, 1,135, 71, 1,207,155, 89,230, 54, 78,149,112,117,161,211,180,172,
- 95, 92, 95,109,230,248,247,233,205, 55,175,223,220,223,191,223,117,215,238, 66, 13,251, 52, 29,247,113, 58, 78,167,253,212, 46,
- 91,211,118,207, 55, 47, 46,119, 31, 47,205,241, 38,185,152,254,114,127,252,246,227,207,223,126,127,251,217,221, 39, 95,127,245,
-225,203,143,238,134,254,221,191,242,207,122,154, 42,187,128, 90, 58,215,217,211, 82, 79,227, 56, 22, 63, 69,157, 50, 20,205,228,
-138, 59,196,122, 44,170,199, 57,163,183,108,117, 96,247, 85,101,101,212, 85,164, 11, 79, 88, 31,254,217,187, 64, 81,195,208, 29,
- 38, 4,176, 9, 82, 44,156,251, 20, 28,106,129, 82, 75, 16, 90,231,165, 26,249, 56, 47, 61, 93, 54,231,213,200, 8,223,138,222,
-149,189,184,250,244,131, 95,255,185,253,238,167, 31,120,147,134,223,155,133,116,242,244,158, 52,116, 30,150,160, 93, 28,251, 55,
- 64, 45,156,200, 37,108,217,123,204,224, 4,237, 51,168,177, 55, 99, 31,159, 63, 6, 99,182,113, 55,105, 11, 57,160,141, 94,103,
-215, 4, 51,106,135,243, 84, 25,101, 45,148, 87, 59,207,143,133, 21, 24,232,105,118,238,177,233,174, 41,152, 23, 95, 51, 70,190,
- 42, 10, 27, 41,129,112, 87,238, 24,148,105, 20, 13,168, 53, 42, 88,237,212,150,211,240,168,234,250, 20, 54, 30,128, 46,103, 57,
- 66, 96,123, 84, 94,149,250,246,148,130, 5, 97,196,206, 12, 28, 23,166,187,239,128, 3,149,203,255, 2,144,116,109, 43,114, 27,
- 81, 80,173,190, 74,154,213,172, 25, 59,236, 67, 8, 6, 99,112, 30, 18, 66, 48,248, 55, 12,249,209,252,130, 95,252, 15, 6, 39,
- 47,235, 60, 24,178, 27,207,234,214, 23,117,119,170,100, 88, 88,152,129, 65,211, 35,157, 83,117, 46, 85,242,253, 31,111,122, 51,
-129,149,198,201, 81,218, 9, 15,239,228,165,228, 47,235,187, 70,134,133, 88, 49,168, 99, 41, 91, 79,224, 21, 34, 53, 33, 1, 83,
- 0, 71, 2,230,128, 59, 89,154,207,176,202,176, 11,218,239, 85,101,216, 78,234,185,254,163, 30,242,208,208, 29, 46,205, 79,107,
- 31,168,170,252,232,151, 5,168,206,108,174,222,166,140, 12, 5,196,176,205, 27, 43,191, 34,100, 0,168, 80, 87,144,141,190,176,
- 72,147,242, 33,188, 15,222,189, 79, 86,159, 57, 51, 87,141, 43,248,206,170, 61,172,173,201, 56,228, 85,218, 60, 54,135,104,109,
- 29,113, 42, 23,112,191,164, 1, 84,163, 60, 13, 61, 14, 73,202,206,170, 30, 73, 50,171, 78,233,106, 89, 27, 62, 81, 50, 28, 8,
- 90, 32,198, 47,199,108,153, 62,224, 17, 46,132, 75,165,252,227, 44, 26, 80,222,202,198, 80,229, 16, 21,165,129,232, 3, 38, 1,
- 52,233, 95, 83, 78, 10, 95, 86, 83, 48, 46,115, 43,168,104, 54, 10, 40,248, 41,191,107,219,112, 96,166, 25, 56, 44,194, 41, 86,
-100, 17, 43,220, 49, 65,195,167,134, 47,178,177,152,128, 85,101, 94,107,222, 10, 85,148,130,200,251,188,221,120,185, 53,249, 42,
-163, 7, 75,221, 60,199,209, 42,215, 14, 54,173, 39, 60,228, 19, 82, 75,246,123,148,147, 74,131, 95, 86, 51,148, 9, 23, 82,150,
- 22,153,191,196, 68, 63, 8,196,131,111, 94,187, 73,248,145,226, 93, 96,106, 91, 42,239,126,254,225,102,123, 92, 0, 7,169,136,
-132,208,193,171,193,147, 60,113, 40, 29, 7, 70,103,209,214, 80,201,195, 30,243, 24,192,140,128,119,225,145,205,205,232, 82, 27,
- 89,106,183, 89,173, 20,109,210,188,255, 89,177, 2, 55, 18, 20,112,217,119,224, 95, 0, 81, 14, 27, 94, 35,237, 30,124,204, 87,
-132,118,177, 31,131, 40,114, 7,139, 4, 62,192, 81,177,209,210,108, 13,149,198,216, 22,162, 27, 99,182,185,181,123,153, 67, 93,
-232, 63, 92,102,118,124, 2, 98, 27, 48,234,127,109,221, 41, 58,130,124, 78,185, 79, 4,113, 36,130, 39, 4, 90, 21,151,182,128,
-147,114,214, 41,169,107,145,115, 72,145, 62,212,194,171, 52, 31,134, 93,169, 73,180,133,231,216, 84, 94,143, 29,209, 69,120, 74,
-144,132, 18, 10,112,253, 18, 40, 85,189, 34, 57, 71, 64,121, 60,110, 76,171,184,162,126,229,170, 66, 66,126, 6,201,187,213, 74,
- 3,243, 88,192,131,164,139, 86, 10,113,192,172,236,248, 32,244, 10,105, 41, 9,151, 84, 75,197, 88,214,125,141, 42,146,133, 2,
-220,211,192,241,197,144,216, 24, 28, 75,196, 61,168,143,119, 65,249,172, 54,188,233, 56,225, 56, 3,144,119,192, 96,136, 65,148,
-138, 24, 5, 87, 94,124,145,142, 47,130,213,152,122, 76,143, 82,215,130,189,107,238, 52, 33,251,179,244,207, 2, 3,117, 28,180,
-163,170,170, 3, 3, 0,183, 84,141, 29, 1, 33,232, 67,239, 4,215,122, 51, 3, 33, 45,213, 99,153, 69,187,220, 62,247,191,254,
-254,250,183,215, 63,197, 32,238,239,255,221,191,109, 46,225, 93,171, 17,202, 50,208, 34,229,188, 87,252, 51,184, 88, 5, 50, 58,
-120,186,210,103,205,126,219, 89, 58,243, 76, 69,196,160,245,225,169,254, 83,246, 7, 55, 60,117,231,230,114, 57, 93,158,191, 24,
- 47,174, 85,192,160,108,183, 84, 32, 61,167,111,207,114,236,250,144,202,253,151, 79, 31,255,254,250,245,179,186,251,241,229, 47,
-175,206,141, 65,234,142,135, 69, 26,229, 27,129, 41,217, 85,207, 58,122,170,222, 9,220, 27,133, 75, 24,100, 76, 87, 17, 17, 54,
-175, 84,130,236, 0, 97,168,109,138, 51, 42,120,247,251, 48, 92, 50,237, 33, 66,199, 74,150,162,221, 5, 87,159, 73, 71, 0,178,
-230, 66, 65, 35,240,236,208, 10,106,205, 85,122,170,179,223, 7,202,200,136,121,247,234, 70,221,189,253,243,195,151,191, 30, 62,
-155,179, 3,100, 67,134,136, 44, 6,113,151,183,239,216, 64, 14, 39,106, 46, 94, 59, 36,163, 98,185, 93,216,172,129,133,222,206,
-153,200,125,226, 21, 63,246,174,236,150,139,157,180, 65, 80, 63, 33, 43,216,136,160,211, 34, 65,141, 93, 17, 70, 3, 6, 58,224,
- 45,213, 82, 31,201, 89,100, 36, 16,237, 64, 35, 38, 97, 11,240, 33, 61,191,246,202,129,197,120,170,205, 52,224, 19,217,100,110,
- 6,169,119, 27, 91,106,104,135,200,225, 5,217, 5, 79,167, 1, 81,198, 77, 40, 2,225,164, 76,165,172,240,158,129,187, 90, 81,
- 22,105, 65,106, 34,216, 67,254, 95, 0,146,174, 92, 71,138, 24, 10,182,207,190,220,195, 2, 18, 2,145, 0, 1, 72,136,100,197,
-103,144,241,183,196, 4,100, 72, 16, 17, 18,112,105,145, 88,102,166,167,237,110, 95, 84, 53,217, 38,171,157, 29,219, 85,245,174,
-122,234,205,219,103, 37, 35, 14, 82, 61, 51,204, 51,168,220,215,139, 93, 57,210,121, 60, 72,125,134,178,193, 23,125, 6,243,120,
-196,249, 52, 75,173, 75,197,103,116,185,120, 13,169,189, 22, 26, 32,211,201, 9,231, 64,101,214,107,111, 82,228, 82, 99, 17,153,
- 77, 52,197, 39,168,111,135,183,185, 92,148, 95,153,200, 50,140,125,103,249, 71, 31,103, 21,221, 73,118,137,141, 7, 9,136, 12,
-221,178, 45,184,129, 37, 25, 90, 3, 6,110, 52, 98,163, 58,164, 56,164, 26, 19,134, 22,113, 49, 87,101, 65,151, 68,183, 41, 92,
- 65,192,234,163, 54,140,125,110,157, 96, 8, 45, 20,190,190, 78,220,183, 45, 96,118,192, 51, 20,238,160,184, 73,201, 72,117,144,
-166,213, 70,114, 30,207, 86, 64,125,105, 58,250,118,131, 57, 88,215,225, 98,161,141,221, 83, 96,247, 32,232, 72,175,109,214,204,
-198, 26,182,205,225,118,209,114,154,163,206, 43, 7,123, 26,142,132,172,244, 71,209,170,213, 29, 21, 46, 13,223,217,167, 71,240,
-150,116,240,101,151, 22,110,172, 81,172,144,208,248,146,140, 36,198,130,127,108,155, 21,107, 64,133,189, 51,218,147, 96,138,143,
- 17, 58,252,196,156,113,252,187,228,113, 41,183,220,205,193,105,255, 51, 45,122, 74,115,202,107,115, 97, 88,101,104,252,149,232,
- 16,126,206, 80, 89,162,205,156, 80,219,205, 73, 32,248, 84, 42, 61,141, 38,241, 78,113,235,131, 63, 90,238,227, 25,236,245,195,
-251,227,205,205, 41,122,196, 25,204,236,138, 66,113, 97,136,236, 45,101, 27, 69, 42, 24, 2,228,194, 22, 48, 7, 86,224,118, 65,
-102, 48, 71,220, 30,186,119, 66,124, 84, 40, 70,203,156, 38,157, 11,200,214, 36, 70, 16,147, 98,213, 45,149,154,153,138,158, 33,
-234,113, 47, 16, 31,200,141,165, 58,154,248, 2,208, 57,201,113,106,152, 3, 1,183,250, 8,189,145, 35,126,194,233,107,206,120,
- 31, 21,136,202, 47, 44, 98,111,180,240, 5,117, 42, 19, 24, 55, 37,193,168, 98, 93,232,233, 6,105,158,233,140,182,225, 65, 48,
-161, 14, 34, 88, 68, 10, 49,109, 0,134,221,123, 96, 3,115, 0,189,247, 95,196,217,205,186, 68,150,224,252,204, 81, 71,181,196,
-203,188, 91,194, 6,182, 67, 21, 47,146,111,206,171,236,189, 92, 16, 36, 29,101,184,228, 18,184, 16, 2,122, 39,142,218, 77,102,
-135, 74, 49,208, 39,180,210,198, 95, 1, 90,216,251, 56, 24, 38,223, 44, 48,109,101, 89,120,118,204,249, 73,182,137, 3,168, 18,
- 93,137,172,149, 8,213, 55,174,116,212,135,125,255, 18,142,124,208,208,150, 96,114, 73,243, 22,104, 42,208,178,116,130,146, 77,
-182,156,113,118,108, 25,216,183,126,179, 20,206, 20,176,181, 81,119,118,218, 45,255, 56, 12,190, 55,116, 67,244,119,146, 1,230,
- 48, 54, 67,215, 33,142,174, 19,141,151,105,112, 15, 92,239,133,190,226,210, 4, 59,200,193,236, 94,160,144, 37,108,177, 5,202,
- 65, 4,159,166,123,233,213,245,243,235,215, 47,197,212,253,254,241,253,120,252, 83, 67, 98, 63,144, 78, 45,167,196, 4,253,197,
-117, 5, 99,226,182, 89,118,205, 33,208,167,199,149,112, 26, 60, 39, 29,180,250,112,104,156,114,135, 56, 12, 45, 48,122,228, 68,
-209,124,235,192,132,245, 14, 91,131,184,156, 28,210, 5,239,119, 84, 7, 37,206,189,248,242,245,215,135,207, 63,135,112,247,217,
-147,199, 79, 31, 64, 22,196,149,117,102,112,157,224,200, 64,150,108,114,179, 42,104, 77,111, 81, 79,209,161,112,147, 85,102, 49,
- 25,239, 15,112,131, 8, 67, 89,150,186, 98,187,155,201,114,204,104,223,208,222, 52, 30,167,169,128, 71, 80,237,122, 46, 28,177,
-192,177,115,131,122,221,216,245, 83, 87,154,207, 20,113,182, 52,255,135,142,185, 59, 60,125,245,226,211,183,123,239,222,127,188,
- 26, 75,239,134, 2,228,160,159,157,221,123, 0, 44,180,204, 6,141,129,239, 16,218, 99,204,202,233,185, 5, 75, 90, 67, 83,233,
-166,111, 44,254,132, 13,221,190,164, 64, 77,255, 65,251, 96, 92, 51, 41,206,142,136,148, 71, 49, 85,206,195,239, 83, 49, 92, 82,
- 57, 78,138,117, 63,200,231, 45,235, 11, 71, 42, 57,220, 44, 99, 9,107,231, 67, 89,192, 63, 35,225, 26,247, 26,250, 13, 55,238,
- 82,111,215, 4,140,171, 56,138,208,118,129, 80, 15, 41, 11, 86, 1,235, 5, 27,214,118,173, 85, 45, 32, 80,197,109, 88, 43, 0,
- 9, 66,242, 6,248,143,232,240,159, 0, 36, 93,187,110, 20, 65, 16,156,217,121,236,251,206, 8, 11, 68, 6,194, 56, 32, 66, 4,
- 4,252, 3, 1,127,201, 87,240, 25, 68,200,152, 8,201, 22,182,239,246,246,118,231, 77,213, 18,222,157,100,107,103,103,186,171,
-123,170,171,212,215, 47,239,216,134,228, 52,123,164,129, 65, 21, 23,187, 80,214,134,158,206,235,124,183, 82,107, 4, 43, 46,236,
-210, 69, 61,213, 56,147, 75,197,194,212, 69,182, 4,232,191,134, 29, 23,216,252,176,142,140,103, 69, 42,168, 95, 60,118,188,116,
- 0,253,154,243, 35, 8, 55,138,170,228,108, 83,208, 30,132,196, 71, 29,128, 73, 43,143,224,103,179,246,143,198, 61,136,190,211,
- 97,112, 52, 97, 20,103, 32, 30,237,133, 29,228, 65,233,190, 65, 76, 68, 60,227,253, 56,254,219,211,148,240,126,187,222, 4,206,
- 76, 33, 6, 55,154, 77, 15,192,235,189, 80,118,108,108, 83,214,140, 83,209, 25,161,250,198,208,246, 25,136,139,204, 81, 64, 11,
- 68,247,178,147,113,176,236, 21, 96,213,121,105, 82, 41,242, 98, 2, 22, 48,114,202,137, 71, 16,143, 79,119,202, 53, 87,244,103,
-178,182, 65, 69, 65,205, 4,236,238, 74,119, 8, 40,210,238,145,112,232, 24,207, 43, 44,102,132,100,105,184,145, 17,214,105, 30,
- 79,196, 29, 20, 59,251, 42, 48,231, 8,106,218,109, 82, 91,188,115, 69, 72, 82,118,246, 60,172,153, 6,148,225, 36, 16, 21, 29,
-187, 35,154,154,193,164,139,234,188, 84,113, 29,231,199,178, 82,217, 85,217,182,242,193, 45, 13, 13,185,232, 98, 81,166,163,198,
-105,187,115, 20,187,193, 27,119,231,132,245, 71, 36,165, 15,100,164,204, 41, 57,236, 0, 81, 88, 75,141, 29,226,220, 48,188,125,
-117, 57,174,127,206,118, 18,137, 66, 29, 72,205,125, 75, 46, 39,117,155,168,166,154, 36,112, 31,162, 7, 86,207,146,224,146,167,
-232,176,116, 93,101, 99, 82,164,173,208, 69, 9,136,214, 22,169, 14, 20,159, 39,127,147,164,125, 10, 53, 38,178,186,162,164,229,
-113,113,248, 51, 43, 63, 21,167,242, 49, 39,195, 6,139, 56,150,212, 81,155, 70,224,231, 44,129, 71,144, 34,207,149,198,177, 14,
- 60,232, 57, 79,185,116,217,215,100, 92,228, 42,114, 80,213, 39, 60,253,162,163,150,233,124,244, 26, 27, 7,171, 71,223,128,205,
- 95,109,165,241, 41, 34, 72, 38, 13,165,146, 19,117,156,129,228,201, 8,115,164,211,121, 74,172,210,192,102, 58,120,106,186, 35,
-224,207, 84, 15, 71, 30, 5,174,143,129, 5, 74,156, 25, 43, 21,114,216,137,205,193,158,126,231,188,190, 4, 72, 48,185,233, 71,
-172, 15,175,120, 83,163,211,136,111,137, 33,240, 56,101,143,210,204, 59,131, 64,130,227,142,116,150,101,143,115, 84, 90, 23, 17,
- 79, 23, 68,123, 32,236,222,199,142, 21, 92,232,133,251,175, 3,105,100,155,107,217,241,118,112, 31, 73, 69, 99,199,133,156, 71,
-196, 42,213,237, 82,133, 2,207, 26,138,151,163, 94,160,155,137, 58,211, 99, 27,111, 94, 57, 83,154,146,176,114,156,252,151,197,
- 52,156,135, 82, 21, 99, 9,160, 71,196, 38, 24, 34,118, 55,234, 5,251, 76, 34,184,144, 40,215,151,166,147,180,207, 52,155, 54,
-115, 82,114,142,100, 66, 47, 7, 20, 80, 30,192, 88, 63,237,118,242,253,245,155,207,159, 62, 24,243,252,246,246,233,238,225,225,
-228,206, 59, 0, 53, 49,250,176, 88,193,146, 26,233, 34,224, 29,114, 61,182,169,134, 21, 63, 91, 90,168, 36,218, 29,168, 81, 85,
- 46, 76, 28,220, 77,130,109,223, 78,183,148, 11,210, 14,184,116,163, 85,109, 50,178,165,173, 7,147,245, 62,221,159,214, 31, 55,
-247, 63,127,133,139,254,245,213,245, 11,132, 48,148,205,121,142,155,184, 12,181,187, 37, 82,123,146,205, 76, 70,173, 17, 84, 94,
- 59,158, 10, 79, 23,160,138,163,168, 47,202,232,113, 95, 26,105, 37,111, 14, 55,221,104, 69,211,129,138,156, 66,178, 92,200,168,
- 65, 6, 93, 55, 6,146,192,241, 48,200,105,202,137, 16,216,221, 98,175,115,144,109, 39, 47,175, 94,158,186,143,223,190,223,252,
-245,191,205,112,129,215, 10,172, 92,232,233,182,169,238,146,233, 67,165, 13,142,204, 33,144,139, 58, 30, 19, 80,107,235,172,105,
- 28, 13, 0, 20,189,200,148,225, 40,223,200, 9,110, 59, 59,102,105,122,200,212,170,183, 66,234,110,199,107, 58, 26,204, 2,145,
-196,252,200, 98, 75,161,114, 56, 32, 59,215,203,133, 52, 75,110,168, 25, 13,124, 59,138,160, 55, 18, 38, 14, 47, 96,147,199,126,
- 99,219,113,221,188,186, 34, 13,156, 81,204, 59,242,206, 53, 21,123,163,247, 3, 2, 75, 20, 56, 0, 97,226, 60, 58,170,199,152,
-102,228, 7, 81, 63, 36,206, 62,107,253, 79, 0,142,206,102,199,114, 26,136,194,137, 99,199,206,237,155, 75, 55,221,179,128, 97,
- 57, 35,196,108,144,120, 8, 36, 94,128, 13,239,202,130,229,136, 13,107, 22, 8,137, 13, 51, 35,186,231,254, 36,142,157,216,156,
- 47,251,238,200, 55,169,159,115,202, 85,167,186,159,127,121,215, 40, 31,153,219,217,177, 25,198,220,148,180,135,185, 82, 67, 45,
-139, 64, 73,149,229,201,193, 94,154,107,106,197,240,187, 40, 52,143, 6, 94,242, 74,163, 13, 82, 56,150, 86,121, 75, 15, 70,184,
- 40,204,196,103, 74, 35,195,226,134, 60,164, 84,194,166,192, 99, 22,119,125, 62, 40,124,234,121,206,198, 57, 77,219,167,120,105,
- 87,215,197, 58,103, 90, 34,186,102,102,177, 17, 67,229,172,171, 23, 56, 95,105,135,211,201, 98,254,184,180,206,217, 74,251,137,
- 17, 45,239,220,120, 96,126, 84,230, 43, 2,231, 71, 51,122, 69,156,169, 58, 25,250,170,119,154, 13, 55,168,199,241, 30,217,117,
-156,209,160,166,165,247,221, 7,125, 0,180, 3, 44,227,107, 27,255,229,149,234, 43,155,246,154, 92, 79,126,163,204,176,119,133,
- 32, 4,211,161,124,178,246,189, 85,252, 87,124,101, 32, 7,246,172, 15,194,186, 19, 46,220,104,110,139, 66,230,114, 73,172,136,
-230,252,108, 99,227, 16, 89,215, 67,178, 49, 17,137,106,186, 65,113, 68,182, 35,161,107,178,239, 15,222,124,111,183, 40,103, 73,
-180, 38,174,136,182,204, 10,150, 81,177,124,137, 75, 81, 32, 44,113,251,204,187,153,215,115,206,140, 3, 0, 10,207,125,187,156,
-170,146,117,140,172,243, 97, 54,106,166, 75,187, 8, 44,187, 22,238, 78,227, 13,192, 69,120, 1,176,172,240, 62,152,249,122,218,
-238,103,247, 60,217,183, 79,135,175,182,143,179,141,130,121, 58,168, 17, 42, 56,208, 5,227, 95, 41,241, 90,241,239,100, 29,189,
-165, 74,165, 12, 0,148, 24,246,158,108, 36,182, 45, 42,104,122,246,190, 37,175,206,212,149,244,131,210,146,154, 93,149, 32, 35,
- 78,164, 48,107,203,141, 9, 96,249, 26,131,196, 10,245,133, 92,149,196,205, 4,135, 99, 6, 44, 11, 75, 43,253,228,114,187, 99,
- 92, 44, 71, 54,198,181,226,170,161,108, 76,242, 50, 85,209,204,108,151, 92, 39,154,145, 54,134, 72,217,106,152, 46,156, 56,237,
-253, 76,134,245,216, 10, 45,109,125,161, 16,177,138,133, 71,249,125,214,171, 90, 82, 66, 14,168, 64,107,148, 72,155,207,194,116,
-203, 75,108,236, 96,211,165,108,147, 24,221,190,133, 73,121, 54,213,120,221, 53, 24,216,115, 34, 14,224,230,100,141,210,241, 69,
- 84,174,207,202,167, 67, 19,142,138,252, 54,132,170,112, 80,157,167,234,237,100, 85, 8,141, 58, 43,235, 82,204,115, 71,111,183,
-208,103,239, 81,251, 66,225,187, 25,160, 49,250, 35,202, 68, 92, 71, 12,221,169,214,113,231,147, 15,117, 29,250,109, 83, 96,242,
-138,227,198,119,237, 72,154,239,167,224, 28,203, 31,234, 62, 65, 95,134,129,193, 12,170,157, 45, 74,251,226,162, 69,135,218,185,
-236,138,117,210,127, 4,133,220,149, 35, 17,120, 31, 58,185,203, 23,163, 17, 47,111, 30,117, 66, 5, 65, 90,128, 21, 47,242,157,
-227,247,245,117, 63,116,177,119, 70, 56,214,204,204,231, 35, 98, 65,227,214,217,143,221,219,111,191,254,241,167,239,191,121,248,
-242,250, 33,254,253,225,223, 73,102, 39, 88, 39, 54, 38,134,231, 5,106,243, 48,245,163,147,173,138,246,150,133,148, 36,247,112,
-202, 72,113,230, 34,155, 81, 47,196, 21, 80, 96,170,194,114,178,173,126,141, 1, 89, 98, 49, 7, 87, 83, 41,197, 94,156,139,190,
-211,105,142,211, 95,159,254,121,255,254, 99,124, 30,223,125,247,230,245,235,187,229,252,194,252,180,111,182,155, 71,155,159,205,
- 14, 30,193, 69,130,140,156,149,123, 26,182, 64,140,198,190, 82,242, 15,135,167,134,125,134,123,105,152,237,232, 12, 0, 89,100,
-137, 20,102,216,218,146,216,123, 33,210, 87, 89,148, 8,194,189,238,130,110, 16, 54,171,120,213, 30,195,211,195,227,253,155, 31,
-126,253,237,191,223,255,252,227,248,200,229,180, 16,107,107,105,120,226,186,114, 80,208,245,135,165,174, 2,169,178, 1, 69,160,
-224,142,215,205,159,186, 20, 14, 53, 20,202, 21,125, 24, 87, 83,118,149, 60, 65,192,243,233,174,139, 19, 34,123, 22, 97, 79, 87,
-246, 2,178,149, 3,137,111,200, 4,194, 76,103,119,180,140,217,244, 76, 50,137, 9,121, 65,147, 57, 51,156,177, 23,150, 10,107,
-169,232, 30, 42, 13,250,249,203, 18,233,224, 17, 46,172,220, 14, 97, 44, 89,246, 17,110,249, 86,228,242, 73, 36,152,202, 91,110,
-245, 37,169, 15,246,192,148,169, 91,209,226,173,135,101, 75,255, 11, 64,210,149,228,184,113, 4,193,218,151,230, 52,103, 32, 91,
- 16,180, 24, 2,102,110,190,232, 1, 6,116, 20,160,247,234, 21, 58,250,102,248,102, 65,208, 69,203, 64,100,111,213,181, 57,162,
-117,228,128, 67, 54,171,171, 50, 35,178, 51, 35,244,187,247, 15,243, 94,103,132,180,137,230,202, 75, 74,217, 36, 28,165, 66,124,
- 95,212, 8,168,237,212,101, 58,203,243,176,122,128,144,125, 91,131, 33,147,178, 78,172,116, 23,195,187, 8,127,134, 38, 47, 77,
- 1,250, 71,223, 40,119,131,253, 20,167,217, 78,248,140,213, 39,108, 91,128,126,151,214,105, 9,192,238,195,198,185, 28,179, 32,
- 49, 32,198,117,119,184, 54,178,139, 15,108, 29, 41, 27, 72,132,206,154,162, 12, 64, 92,250,169,176,118, 96, 83, 51,205,172, 52,
- 13, 69,131, 27,246,222,218,201,135,104,217, 12,225, 54,223,220,137,131,115,183, 22,127, 4,102,240,222,104, 10, 57, 14,129,179,
- 13, 94,223,176, 87, 24,135,209, 0,234, 90, 86,250,245,147,128,159, 76,113, 33, 79, 33, 20, 4, 50,122, 79,101, 10,139,179,194,
-140,176,225, 29,101,173,113, 37, 26, 8,145, 22, 50,108, 21,225,190, 97, 29,199,217,177,118,196,114,186,137, 96,189,212, 49,174,
- 4,244,166, 17, 23,193, 41, 53, 37,204,113,119, 41, 97,134,100,133,108,160, 56,251, 99,129,201, 1,215,232,195, 19,250,204, 9,
-159,106,105,186,162,151,218,102,128,101,132,227,152,127, 56,100,103, 62,214, 49, 36, 20,166, 46,200, 78,227, 70, 25,149,117,249,
-113,245,101,150, 19, 88, 79,145, 6,219,130,158,166, 28, 48,218, 64,142,166, 43,155,158,118,189, 96, 63, 6,153,177, 24,248, 79,
- 65, 29,208, 60,115, 62, 46,206,226,218,213,171,123,249,192, 96, 71,169, 0, 48, 81,103,228, 8, 28, 22,187, 26,155, 70,100, 2,
- 3, 80,212, 53, 85, 56, 59,156, 12, 18, 6,107, 93,101,170,249,232,178, 72,200,206, 88, 38, 44, 57,101,158,173,214,107,167, 26,
-253, 89,179, 9, 23,100,201,229,178,182,202,198, 51, 89,127, 82, 36,184,210,181,155,218,196, 59,126,101,225, 83,194,163, 7, 82,
-128, 39,226,188,203,235,190, 81,150,156,226,156,184, 19,253,130,211,193,226,120, 3, 63,108,148,220,100,167,110,106,121,167, 70,
- 36, 21, 55, 54, 81, 43,187,161, 55,105,196, 68, 75,248, 76,239, 36, 65,147, 97,224,231,239, 28,112,145,224,225,186,167,201,224,
-147, 65,172, 75,146,171, 85,128, 56,129, 86,123,212,242,194,121, 77, 59, 22, 80,103,132,169,204, 89, 64, 36,141,105,145,121, 49,
- 49,249,147,115,192,194, 32,222,225,142, 6,223,184,209,202,105,202, 25, 43, 58,106,212, 49,176,240, 8,244, 4, 30, 14,244,109,
-143,137,164,161,247,129,252,215, 82,245, 59, 47, 56, 98,103,203,250, 27,181,109, 92,212, 8,141,162, 69,107,111,172, 56,215, 37,
-210,248, 10,161,188, 86,175, 6,173, 2,200,179,106,183,221, 42, 14,188,222,130, 17,121, 29,192, 77,249, 12, 71, 30,224,179,128,
-188,114,230, 62,240, 13,136,242, 78, 31,118,236, 22,136,151,151,101,162,226, 64,159,151, 34, 52,141,236,202, 89, 59,131, 8,223,
-124, 11,136, 57, 55,135,228, 55,104,110, 81, 6,104,180, 18,222,136, 70, 81, 38,146,206, 80,232, 96,215,151,250,248, 88,202, 99,
- 19,223,141,203, 47, 94, 63,251,235,237,155, 63, 94,190,116,118,190, 92,190, 21,176,180,209,223,177,174, 91,231,150,177, 97,231,
- 74, 83, 69, 36,144, 12,220,102,132,190,161,173, 56, 82, 31,190,128,194,223,234, 4,172,207,211,162,246,182, 2, 69,172,148, 18,
-218,104,156,116,213, 96,178,155, 59,113,188,249,206, 69, 31,253, 87,241,248,239, 63,159,191,252,135, 40,242,252,207,251, 39, 0,
-102,233, 43,101,135, 83,100, 91, 4,118,153,190, 22,100,165,194,133,232,171, 87, 32,113, 0, 88, 3,226,179,179, 62,130, 71, 27,
- 57, 81,150,132,155,149,150, 2,189,177,224, 39, 40,143,184, 54, 92, 30,203,247, 52,145,233,117,165,143, 37, 80, 29,229,196, 71,
- 86, 3,204,160, 94, 63,220,127,186, 62,255,240,241,239,203, 29,189,172,109, 45, 0,166, 32,171,121,148,177,114,218,159, 91,215,
-171, 93, 24, 36,144,184,111, 32,206, 72, 11,226,183,194,106, 0, 80,116,100,205,246, 20, 51,173, 60, 9, 30,129,152,195,239, 56,
- 78, 35,159,221, 26,141,168,229,244,224,156,207, 88, 42,188, 10, 37, 32, 89,142, 38, 28, 90, 56,224,194,182, 55, 42,252, 13,251,
-173, 48, 11, 72, 98, 70,250, 46, 8,176, 84,204,150,184,151,117,195, 81,114,219,254,203, 66, 30,233, 19, 8,175, 46, 96, 93, 62,
- 41,249,147, 79,124,133,197,157,206,154,113, 43,146,142,149,164,157, 94, 47,201, 85,109,229,186, 0,171,252, 47, 0, 73, 87,215,
- 35, 55, 17, 4, 61,223, 51, 30,239, 94, 54, 4,161, 4, 17,164,132, 8,137, 39,196, 79, 65,252, 78,254, 6,239,240, 10, 18, 2,
-164, 40, 10,218,187,141,237,181, 61, 51,158,161,202,188,157,180, 39,173,189,238,233,174,110, 87, 87,169, 31,127,250,198, 60,214,
- 0,168,149,103, 73,214, 50,205, 17, 76, 65,146, 70,229,234, 76, 81,159, 16, 83,211,237,214, 18,206, 36,247, 81,218,214, 7,199,
- 37, 50, 30, 61,154,175, 5,190,144,195,233,236,235,138,216, 91, 43, 14,186, 51,199, 58,143, 22,232,167, 87,228,133, 74,184, 36,
-202,134, 11,164,108,248, 78,252,229,237, 54,163,204,213,254,182, 0,172, 77,129,212,111, 47, 72, 28,224, 62, 46,128,107, 58,136,
-141, 66, 47,254,112,145, 7, 90,232,171, 99,142,110,136, 35, 82, 74, 29, 55,245,202,201,134, 24,207, 50,116,174, 19, 23,165, 67,
-238, 57, 51,241,189, 50, 36,105,139,160,241, 75, 33,181,247, 8, 25,181,227, 52,184,103,186,144, 52,207,174, 88, 56, 82,227,217,
-230, 90,252, 15,144, 82,230,219, 23,196,114, 90,154, 69, 41, 69, 86,222,105,149,167,181,158, 41,177,219, 12, 85, 7, 45,215,118,
- 72,213,231,120, 24, 87, 59, 54,244, 20, 92, 1, 74,135, 47,162, 59,166, 52, 37,114,147,135, 84, 67, 92,165,160,245, 39, 81, 69,
- 71, 2, 16,213, 12, 58, 0, 20,106, 32,161,191,155,201,120,104, 75, 1,246,101, 90, 68,169,211,162,142, 25, 93,207,125,169, 40,
-198,228, 90,233,146, 12,213, 3, 76,215,171,101,202,233,182, 51,108,235, 66, 61, 4, 53,145,254,135,108,183,115,198,138,128,216,
- 18,238,119, 89,205,156, 23, 79,131, 99,185,114,153,252, 19,141,233,196,187, 87,254,219,110,191,187,201,158,248,182, 73,156,173,
-142,226, 16,105, 71,194, 69, 52, 83,152,156, 70,235,137,202,103,137,221,159,246, 40, 94,200, 35,200, 52, 89,167, 71,178, 98,168,
-217,152, 72, 69, 35,149,175,113,239,169,187, 21,117, 3,112,238,238,179, 33,148,195, 13,109,220,197,167,231, 14, 96, 23,229, 15,
- 36, 96,242,138,172, 52,115,234,189,149,196,201,227, 78, 91, 29, 52, 65,211,212,197, 81, 0, 89, 83, 69,152,212,229,182,172,123,
- 66,116,108, 37, 19,248,181,252,212,153,185,208,236,232, 80,123,236, 14,253, 47,206,239, 38, 96,180,189, 92,209,119, 8,117,104,
- 81,206,165,187, 23, 28,131,198, 13,195, 6,196,192, 49, 17, 95,169,177, 69, 66, 66,180, 1,217,193,113, 35,122, 29,107,220, 84,
-153, 57, 43, 90,241,192, 2, 85, 72, 26,223,173, 41,209,203, 22, 41, 50,161,188,194,247,216, 33, 80,231, 47,118, 3, 62, 5, 72,
-178,232,110, 41,152,214, 34,243,164, 91, 43,170,186,184, 15, 61, 14, 78, 67,140,163, 49, 83, 1,145,240,160, 34, 23,118, 55, 46,
-237,227, 42, 23,171,165, 67,151,168, 80,231,159,155,139,108,210, 85,196,106, 47,100,236,209,231, 35,133,180, 96,245,233, 34,241,
- 8,200, 31, 27,252, 89,225,244,107,125, 6, 72, 45,195,169,126,225,211,154, 37,138,180,181, 92,105,192,207,238, 14, 55,129,207,
- 70,238, 82, 57,131, 42,160,184,202,215,203,129, 52, 1, 62, 52, 10,137,161,237, 70, 91,209,255,191, 40, 99,232,136,123, 80, 31,
- 5, 95,143, 23, 18, 51,169,207, 3,176,113,173,183,177,102,228,203,143,202, 63,189,252,242,245,247, 63,188,125,243,250,213,150,
-218,159, 31,222,255,251, 55, 77,165, 80,154,206,145, 19, 58, 81,213,184, 0, 21, 21, 4,135,152,140, 55, 81,212,181, 80,154,129,
- 43,201,229, 9,125, 24,109,228,244,206, 77,243,157,174,159,201, 19,191,133, 67,208, 71, 28,108,166,251, 37,181, 1, 64, 57,202,
-127,174,239,127,251,245, 26,235,231,111,222,125,245,240,124,206,219, 53, 63, 2,213,234,118, 78, 72, 64,149,182, 18, 21, 13,173,
-226,128,134,133, 67, 60, 52,215, 83, 63,203, 5,190,179,145,145,246, 98,133,174, 33, 20, 55,203,148,173, 73,137, 10, 38,173,140,
- 18,248, 97,254,192, 15, 54,195,251, 30,171,227, 28, 44,148,175,223,190, 44, 47,190,251,249,151,191,126,127,252, 67,191, 8,253,
- 68,159,197,123,116, 20,188,203, 22,137,126, 25,140,245, 1, 33, 72,237,166,221, 13, 46,156, 99,216, 78,157, 92, 75, 64,220,102,
-103, 41, 95, 91,240, 7,218, 51,167, 45, 71, 1,178, 13, 78, 6, 52, 72,165,158,124, 52,104, 50, 36,160,194,179,125, 27,144,133,
-170,207, 72, 42, 39, 60, 83,187, 32, 61, 0,254, 93, 28, 71,182,172,177,146,118, 79,235, 66,141,116, 81,187,101,158,203,116,165,
-181, 49, 15,196,186,122, 52,163, 20, 49,199,181,169,112,219,199, 59,208, 45,238,223,242,144,237, 91, 46,171, 1,146,161,189,102,
-162, 92, 71,247,145,238,212,147,226,232, 34,253, 39, 0, 73,215,182, 27,183, 13, 5, 41,222, 41,201,181,235, 20, 70, 81,180, 72,
-242, 16, 20, 5, 10,180, 64,251, 5,249,132,124,100,126, 33, 95,145,135, 2,125,203,115,128,160, 13,106,239,234, 70,145, 20,217,
- 25, 25,126,179, 23,235, 93,137, 60,103, 70,156, 51,163,222,190,123, 29, 75,211,161, 48,217, 80,150,174,111,116, 73,101, 8,103,
-221, 77, 93,211,142, 45,230, 1, 71,109, 48, 33, 99,171,229, 72,227,228, 14,108,116,217,221, 1, 14,192, 83,212,198,136,249, 72,
-187,219,206,226,107, 89, 93,114,216, 50,213,212, 64, 97, 50,248, 28, 19,250,208, 46,175, 70,114,144, 7,208, 87, 92,115, 91,177,
- 91, 44,101, 39, 81, 59,160, 50,144,116,208,247,137, 81, 32,146, 19,109, 6, 24,129, 96,173,120,109,149,236,123,195,153,201, 71,
-115, 4, 73,247,100, 1, 54,171,194,156,228, 80,121,152,234,228, 77,227, 51,111,138,206, 15,187,187, 29,200,221,122,227,253,136,
-237, 83, 57,155,165,209,205, 45,159,141, 97,127,105,143,150,140,206,193,217, 38,142, 70, 68, 9, 42,129, 27, 43,167,156, 26,157,
- 93, 25,173,133,165,154, 2, 48,126,197,189,150, 52,167,115,119,212, 19, 54,158,118,161, 48,115,190, 29,251, 2, 11,120,192, 26,
-227,216,185,164, 24,118, 38, 44, 70,217,180, 28, 4, 83,129, 89,186, 76,160,103,220, 56, 35, 38,228,115,200, 26,112, 66,246, 12,
- 35, 64, 3, 88, 40, 22,231, 76,194, 0,120, 0,102,181, 4,236, 87,106,175,155,194,141, 20, 17,197,109, 95,214, 45,170,109,205,
-123,190,128,147, 41,103, 55,121,160,198,104,177, 2, 1,236, 25, 21, 76,158,158,233,123, 6,148, 46,116,136, 49,104, 76,224,223,
-224,130, 40,210, 13, 29, 42,179,223,214, 31, 95,220,252,122,183, 94,210,172, 26, 9, 7,170, 11,149,189,140,136,236,196,136,101,
- 76,165, 96,237,165, 92, 27,181,102,174, 28, 0,154, 81,230,141, 60, 57, 13,156,218,103,130, 37, 48, 83,212,221,130,247,231,131,
-213,124, 5,154, 55,232,136, 51, 22,215, 23,194,188,101,106,201,156,134,190, 69,196,204,136,219, 12, 52, 77,203, 69,225,128,208,
- 39, 0, 62, 92, 49, 86,255,231, 23,112,120, 99,107,255,132,212, 47, 18, 23,105,197,223,112,201,175,226,120,210,252, 70, 27,141,
- 68, 40, 64, 93,207,168,213, 5, 77, 85, 22,144, 31,202,231, 52, 81,240,225,208,213, 87, 78,161,235,184, 43, 67,131, 76,194,161,
- 90,168,200,172,180,236,164, 82, 77, 63,219,198,214,250,117,105,107,230,217, 91,212, 45,143,168, 31, 60, 45,117,157, 1,115, 42,
- 86,154, 91, 54,168, 62,227, 23, 6,107, 79, 8,117, 27, 64, 31,246,107, 10,170,151, 93, 8, 62, 74,139, 75, 52,130,172, 41,203,
- 44, 41, 38,167,131, 15,228,111,129, 19,136,146, 29,179,143,213,164, 43,157, 50,122,165, 80,223,216, 41,132, 27, 89, 76,253, 25,
-195,100,233, 19, 22,178, 82,138, 42, 60, 20, 76, 39, 70, 5, 94,217, 56,167,164, 80,187,111,198,142, 42, 83,186, 20,112,194,108,
- 5, 94, 2, 16,244,148,247,146, 78,122,218, 26,248,129,147, 25,104,238,187,193,122,181,248,137, 28,208,172, 75,166, 76,169,153,
- 78,127, 67, 23, 9,160,125, 0, 94,186,217, 4,234, 8,169, 31, 48,148,108,160,230,181,238,124, 42,143,130,197,105,124,186,111,
-212,122, 41,243,211, 33, 46, 90,253,119,255,240,234,247, 63,127,254,237,151,151,229,169,253,187,127,190, 60,174,141, 70,215,206,
-164,106,120,124,117,102,219,108,201,251,150,209,120,179,188,142,252,148,179,236, 60,202,199, 92,231,206,146, 47,233, 82,124,117,
-215,148, 44,143, 14, 12,201, 6,254,147,206, 84,210,118, 6, 52,104, 68,197,159,254,254,244,229,235,231,225,205,171,215, 15,223,
-167,199,109, 71,117,182,153,143,159, 14,158,207,213,179, 69, 83,198,201,163, 45, 74,189,141,244, 12, 41, 40, 43, 64,135,203,244,
-187, 38,194, 65, 5, 65,123,207, 11,199,163,208,157,211, 68,189,113, 93,218,113, 47, 76, 54, 21, 69,249, 78,135, 59,245,240,211,
-119,238,135, 63,222,127, 88, 62,126,250, 11,205,218,163,173,246,104,176, 99,113,196,227, 29, 32,228, 40,209,132,154, 55,124,210,
-207,188,157, 6,254,156,250, 73,173,245,120,178,221,125,174,183,248,124,128,240,194,246, 46,120, 58, 7, 25, 52, 85,223,182,166,
- 43, 24, 47, 74,147,150,179, 59,202, 32, 6, 53,225,243, 99, 9,156,246,113,120, 91,121, 28,218, 50, 76,103, 89, 43, 22,220,210,
- 42,227,141, 91,218, 0,142,129, 51, 85,205, 97,160,133,147, 96,176,161,223,227,120,134, 7,179, 43,199,234, 64, 98, 14,218,137,
-154, 51, 52,126,139, 77,244,109,195,142,220, 40,103,151,220, 21,128,102, 83, 41,103, 56, 64,219,211,255, 2,144,116, 37, 59,142,
- 20, 81, 48,247,165, 22,219, 51, 64,163, 57, 64, 75,112, 4, 46,220,248, 7,110,252, 40, 31,194, 13, 9, 9, 78, 92, 70,163,153,
-129,161,151,114, 85,102, 85, 46, 68,184,111,125,112, 91, 46, 59, 51, 94,188, 45, 66,255,242,243, 55, 7, 40,115, 25,122, 45,201,
-227,202,148,252, 94, 81,137,167, 41, 46,138,226, 45, 43,141,192,151,119,180,173,148, 55,151, 82, 3,132, 1,242, 30,135, 7,158,
-225,160,130, 22, 76,135, 3,109, 7, 25, 29, 87,171,210,114,157, 17, 61,106,246, 17,100,112, 9,184,231,228, 13, 35, 80, 94,246,
- 1, 56,160,118, 58, 17,128,236,104, 54,225,151, 50, 36,253, 96,205, 42,148, 7, 5, 14, 61, 36, 39, 15,249,202,225, 57,169,169,
- 18, 89,202, 70, 80, 69, 78,197, 26,159,230,206, 81, 13, 89, 69, 6,128, 54,227, 70,117, 13, 52, 41, 56,182, 83,115,178,182, 33,
-186, 50,141,202,214,160,130,158,193, 76,124, 28,128,115, 32, 44, 96,163,212,160,195, 21, 80, 6, 79,198, 31,142,232,123,222,173,
-201, 20,226, 7, 24,218,155,236,195,139,192, 62, 93, 96,114,185,102, 9, 2, 57, 39,174, 28,114,238,103,111, 52, 3,245, 55,255,
-103,245, 50,243,196,206,181, 66, 22,102,228,104,120,134,241, 14,246,249,120, 6, 9,158,164,204, 61, 2,157, 88, 47, 18,233, 54,
- 61,137,196, 89, 81,182,178,111,187,216, 72,194,105,152,189,116,176,250,140,179,153,104,104,143, 96,158, 82,123,104,242, 54, 57,
-134,200,220,232,125,188,246, 26, 0,239, 36,184,101, 93,241, 33,174, 93,174, 7, 77,179,249, 83,201, 70, 55,144,222, 79, 82,115,
- 73,186, 5, 64, 72,211,199, 99,181, 25,220,171,179, 23,212,244,249,205,248,195,235,125, 5, 65,208, 0, 34,192,147, 28,103,138,
-211,155,118, 19,249,218,184,143, 69,133,137, 70,221, 66,197, 46, 40,181, 10, 55,203, 25,118,119,170,229,153, 67, 17,200,116,105,
-127, 70, 67, 43, 54,133, 26,203, 58, 71, 91,139,216, 11,174, 92,246, 28,235,233, 8,129,143,172, 11,225,173,194, 70,237, 47, 41,
-244, 2, 6,197,166, 5,105, 10,135,138,175,236,119,244,205,128,160,105,252, 1,222,186, 32, 35, 17, 44,113,176,162,213,113, 97,
-248,194, 12,146,194,241, 8,245,216,212,213,109, 20, 62, 19,200, 81,109,146, 10,231,240, 95, 81,234,109, 81,156,170, 79,130, 62,
-127, 8, 24,158,137, 11, 46,246, 82,169,188, 7, 40,218, 39, 32, 68,167, 4, 70, 39, 18, 29,156,167, 2,158, 3,213, 60, 24,173,
- 56,181,151, 81,104,228,183, 22,233, 24, 24,126, 84, 45, 2,158,219, 0, 22,114, 6, 75,163,105, 4,245, 6, 44, 59,143, 60,134,
- 54, 38,238,250, 90,170,108,129,153,227,201,220,232,104,145,102,174, 56, 87,166,131,141,224,252, 93, 87,213, 55,119,145, 85,198,
-242, 41, 76, 66,167,106, 9,218,226, 78,219,193,122,112, 78,192,213,140,252, 94,187, 9,201, 48,203, 38,108,154,211, 18,105, 64,
- 42, 19, 61,229, 30,104,208, 60,180,205,154,105,112,199, 42, 95, 37,117,138, 92, 73, 55,209, 1, 55,250, 37,218, 11,130, 62,248,
-141,160,164, 6,200, 66, 96,153,152, 5,203,207,144, 36, 32,129,118, 52,238,242, 66,220, 58,241, 20,156,112, 92,144,149,136,163,
-180, 48,112, 84,214,224,108, 34, 55,107,233,197, 94, 90, 59,114,221,254,169,253,193,248,116,190,188,254,241,167,239,238,191,255,
- 98,249,120,188,253,251,109,173,153,174,218,243, 32,192,112,139,170, 3, 62,174, 70, 72,234, 49, 16,130, 51, 0,188,114, 43, 82,
- 89, 63,116,224, 90,252, 84, 29, 43, 25, 1,236,212,148,234,232,210,200,165,244, 12, 38,129,255,223,164,227,148,151, 23, 99,249,
-243,195,187,247, 31,252,253,155,111,239, 63, 87,233,191,143,244, 32,189, 42, 78, 52, 56,110, 19, 47, 79,130, 99,198, 35,199,244,
- 99,208,113,164,224, 59,190,117,170,102,178,109,126,164,141, 78,194,128, 54,220, 21, 16,168,186, 26,142, 49, 35, 93,220, 1, 1,
-186,102,151, 93,183, 39,117,186,139, 95,127,249,213,239,127,185, 95,127,251,195,221,109,226, 28,152, 89,225,212, 40, 16,107,166,
- 11,233,160,102, 55, 40,183,243,122, 89,229,140, 8, 0,214, 49, 83, 1,207,225,153, 71, 85,195, 24,228,236,145,182,229, 54, 26,
- 15,182,163,156,165,180,214,100, 46, 77,143,156,132, 22,145,230,164,101, 84,251,232,194,202,154, 6, 59,124, 56,209, 49, 62,117,
-147,251,238, 3,120,162,160, 97,238,158, 2,216,185, 66, 66,237,186, 88,211, 90,205,214, 94, 68,221, 21, 40, 13,162,164,225,134,
-214, 32, 31,193,218,214,248, 76,185, 3,164,243, 7, 23,232, 73, 19, 64,193, 54,228,173, 37,225, 59, 47,187,126, 66,188, 80,148,
-252,160,148,159, 87,255, 11,192,209,149,236,200, 81, 68,193,220,179, 50,171,171,187,103, 48, 70, 28,240, 5,100,201,150, 56,113,
-241, 47,112,230, 79,249, 14,142,156, 16,226,130, 37, 22, 25,141,167,107,186,182,220,136,200,251,168,213, 93, 83,249, 34, 34,223,
-123, 17,250,199,159,222,138,125,141, 14,196,250,120, 94,226, 64,155, 48, 94,233, 84, 48,125,222,108,153,101,237,151,253,138,171,
- 84, 56,117, 70,151, 3,255, 86,106,116, 87,135, 13,132, 60,166,211,222,122,202, 15, 78,181,139,219,214, 52, 61, 24,128,183, 39,
-212,116,136, 24,176, 87,142,137,160, 34,108,194,142,119,121,128, 19, 86,206,140,175,169,110,245, 63, 77, 43,229, 83,205, 92, 12,
-232,190, 63,244, 40,161,239,134, 75,120, 6, 92, 76,109, 15, 16,251, 78,175,174, 13,129, 89,145,237, 44,252, 48,184, 81,169, 56,
- 66,242,244,140,165,233, 18, 39, 16, 24, 0,234, 24, 98, 8, 61, 57,109, 56,241,171, 0, 76, 44,216,114,228, 68,155, 9, 12, 37,
-160,169, 40, 35, 26, 57,227,218,232,222,104, 24, 55,156,132, 14,201,208,157, 32,112, 48, 94,155,124,159, 25, 90, 0, 94, 21, 32,
-125,148,185,211,116, 92,243, 28, 15,188,166,103,143, 86, 50,202, 19, 79,166,177, 85,214,216, 73,233,110,181, 5,252,105,212,246,
- 1, 44, 26, 68, 66,174,236,153, 83, 63, 89,227,153, 68,193,181, 76, 8,107, 25,101,102,218,131,197, 95, 49, 47,241, 96,216,123,
- 61,240,219, 53,109,180, 32,224, 33,129,150,245, 88,119,117,128,212,149,210,121, 30,234, 97, 10,173, 46,123,201,123,178,169, 39,
- 9,216, 59,135,242,128, 82,121, 41,250, 64,189,167,191,100,189,113, 23, 94, 51,158, 25,154,210,228,141, 67,152,143, 95, 15, 63,
- 92,215,167,251, 46,162,247, 16, 26,228,167,236, 83,109,128,191,196, 6,105,235, 9,141, 52,155,110,125, 74,180,176, 63,167,110,
-140,252, 76,247,186, 0,134, 70,185,207,130,238,133, 94, 28,155,220, 63, 87,192,118,206,230, 14,100, 59,152,213,177,176,201,195,
-226,190,243, 2, 25, 15, 88, 86, 72, 9, 9,238,203,144,120, 40,143,156,122, 35,184,168, 99,195, 43, 85,237,144,118,128,103,144,
-219, 65, 99, 91, 6, 17,223, 32,205, 65,187, 1, 55, 61, 95, 79, 49, 44,139,235,174, 16,118,142, 15, 24,167, 54,199,122, 95,233,
-232,174, 73, 66,218,142,250,150,100, 31, 86,195, 91,206, 88,209,252,194, 34,222, 98,233,233,134, 6,200,197,209, 54,227,133,211,
-208,113, 16,114,160, 1, 7, 68,215, 37,243,202, 47, 88,223,172,173,180, 76,131,202,196, 75,150, 60,195,105, 7,149,140,145, 74,
- 12,166, 6, 25, 35,180,130, 63,188,240, 36, 20, 1, 47,235,190, 26, 98, 59, 47, 59,173, 86,108, 6,107,174, 96,129,249, 7, 26,
- 95, 26,178,147,147, 26,206, 92,143, 50,103, 33,199, 56,121, 27, 55,156, 18, 53, 1, 13,129, 97, 16,243,128, 34, 19, 70, 32,100,
-148,117, 45, 92,192, 59, 41,254,254, 75,229, 85,159,118, 40, 62, 20,175,248,198, 70,114,234, 11,149,253, 81,109, 83, 29, 80, 82,
- 47,204,189, 65,249, 31, 20, 33, 64,208, 19, 33,143, 87,229, 95,137, 83,132,118,181,204, 62, 59,187,240,200,117, 52,195,145, 4,
-182,104, 13,205, 52, 27, 15,217,192, 36,195, 62, 7, 88,117,237,222, 8,142,134,204, 56,248,138,214, 1, 40,175,207,121,251,167,
-228,143,102, 88,190,156,190,248,240,225,251,119,239, 95,151,185,252,253,251, 83,186,229, 53, 66, 92, 43, 43,152,183,245,188, 30,
-150,251, 89, 40, 37,205,245,100,214, 23,124,240,206,224,187, 70,171, 6, 83, 64,186,244, 11,116, 23,206,136, 29,171,128,128,242,
- 68,201, 0, 88,189,242, 2,123,114,122,241,226,227, 31,127,253,249,201,124,251,230,205,245, 97, 61,238, 11,160,116,158, 15,240,
- 32,223,132,159,105,200, 57,125,195, 88,105,235, 44, 71,220, 32,119, 44, 14, 27,141,252,250,139,195, 99,180,113,115,223,108,183,
- 6,136,130,122, 59, 22, 54,186, 41,143,130,155,130, 24, 95,157,191,250,238,221,111,159,222,254,252,203,175,155,252,215,202,139,
-219, 5, 85,132,205,243,216, 82,179,165, 58,205,156, 6,230,116, 40,111, 60,126, 35,189,147,162, 43, 54, 50,125,172, 93, 27,144,
-158,201, 18, 58, 26,206, 53,136,108,108, 84,193,156,115, 27,159, 82, 3,193, 59,131, 21, 64, 94,104,143, 87, 62, 67, 2,191, 6,
-114,140,211,174, 39, 48,200,185, 66, 65,225,219,107,194,174,168, 51, 59,163, 47,220, 3, 15,220,181, 95, 10,216,224, 0, 62,196,
-145,107,202,238, 52, 23, 78,128,138, 29, 5, 20,252,221,213, 61,122,176,242,172,134,207,125,244, 14,218,120,117, 86, 22,183,210,
-204,220,190,176,153, 12,114,223, 29,124, 50,128,165,253, 47, 0, 71,215,178, 35, 57, 17, 4, 93, 79, 87,217,253, 96,182,165,229,
-130,196, 92, 64, 90, 16,135, 61,240, 9,124, 0, 31,203,141,207,224,188, 23,196,172, 86, 98,192,211,109,187, 92, 47,215, 70, 88,
-154,203, 72, 45,181,221, 85,149, 25,145,149, 25,161,126,255,237,167, 61, 59,156, 10,233, 30, 26,137, 94,136, 87,156,231, 71, 16,
-120,200,181,172,251, 99,167,107, 18,239,101,216,226,199, 55,170,189, 70,148,227, 48,130,147,241, 63, 61,200,155, 1, 42, 72,224,
-136,157, 53,241,252,141,179,236,158, 85, 43, 98,231, 86,143,174,232, 20,198, 42,150,206,101,240,134, 55,249,150,172,240,166,101,
-145,198,220,205,120,117, 57,170,110, 98,233,179, 37, 50,122,176, 24,162,232, 98, 56, 17,186,175, 94, 46,166,158,138, 63,119, 98,
-233,199,174, 12,163,108,126, 52, 91, 1,176, 79,209, 32,151,235,161, 81,214,137, 19, 13,120, 11,139, 3,160,199,190,217,203, 80,
-174,128,198,253,101,108,126,192,106, 81,104,142, 22,204,218,211, 75,137,173,233,120, 41, 10,142, 90,131, 16, 68, 7,102,110, 86,
- 26,107,112, 96, 20, 0, 37, 1, 97,185, 93, 39,117,216,191,116, 0,171,149,165,120, 44,222, 94,210,178, 71,144, 80, 65,207,109,
-193,136, 94,165,225, 16,128,172,138, 67, 83,141, 92, 35,118,137, 50,149,145,173,178,158,109, 5, 32,194, 58,177, 28,157,104,165,
-151, 21, 35, 79, 87, 0, 25, 92,169,255, 31, 29,188,128, 70, 72,246,157,122,200,205,205, 46,223, 19, 34, 83,212,154,174,114, 8,
-189,106, 42,185, 81,103,174,109, 57, 81,100, 28, 40, 29,120, 41,114,206,159,215,233,185, 0,232,130,213,129,182, 97,121,230,146,
-103,214, 9,233,252, 77,177,189, 33, 78, 77,124,120,126,255,115,187,255,187,109, 78,247,210,101,222, 81, 92, 89, 65, 58,138,177,
- 30, 63, 63,187, 6,113,234,102,202, 30, 82, 34,233, 81,122,169, 11, 24,161,138, 41,170,109,213, 75,222,135,196,238,120,185, 29,
-157, 30,200, 14,141, 62,146,161, 25, 27,235,178,139,180, 30,222, 58,135, 20,145, 12, 44,105,229,136,231,110, 43, 53,123, 90,177,
-135, 45, 33,133,145, 11,123, 63,232,141,210,221,143,241,215,229, 11,151, 36, 92,247,109, 1,183,221, 11, 50, 65,163, 50,231,220,
-183,117,105,217,182,120,200,182,227, 87,107,155, 78, 73,168, 84,242,112,212,121, 26, 71, 27,234, 6,190,143, 72,129,116,162,179,
-215,244, 12, 87,118,228, 29,179,114, 64,221, 72,230,216, 4,215,210, 81, 4,130,185, 93, 33,255,236,253,208,115, 36, 79,210, 63,
-193,225, 25,186, 91,243,223,198,118,109,108, 75,140,248,240, 69,141,206,235,147,190, 40,108,122,196, 18,174,152,169, 70, 14,236,
-205, 26,146,183,186, 12,125,237, 37,253,178,189,114, 6,136,172, 34, 23, 32,250, 55,122, 22,154,254, 12,170, 14,118,210,111,219,
-211,174,220, 9, 95,167, 78,245,201,137, 11, 13,106,252,187, 65, 59, 65,185, 11, 28, 30,215,227, 57,243, 85,213, 11,192, 59,254,
-211,174,210, 90, 20,209, 88, 92, 98,102, 25, 24,127,194,121,150, 41,134, 30,233, 18,252, 88,219,147, 48,125,246, 89,110, 83,221,
- 84, 30,223,237,131,209,245,234, 70,213,128,203, 29,197, 90,104,144,219, 29, 86,175,146,244, 0,207, 23,164,100,219, 33,183, 63,
- 88, 27, 59, 85,104,141, 66,197, 54,154,223,130, 63,228,195,225,155,166,145,156,126,120,180, 28,150, 90, 94,181,191,223,110, 63,
-124,252,245,227,243,205, 78,255, 76,159,255,190,203, 37, 32, 73,172,128,240,177, 88, 90, 1,212, 18,216, 59, 85,217,213,145, 10,
-126,170, 64,209, 87, 10, 5,240, 6,198, 32,164,108,115, 57, 97,239,100,100, 62, 67,227,197, 7,246,141,180, 33,177,181,199, 81,
- 75,236,245,229,203,203,203,229,199, 95,222,159,246,207, 45,133,178,102,111, 61, 29,175, 88, 25, 22,142,146,207,116, 65,119, 64,
- 39, 19,139,162,146,131,221,192, 2, 93,153, 59, 61, 43, 0,139,146, 19, 82, 47, 11, 28,120,227,196,251, 22,107, 16,118,149,118,
-242,187, 15,223,175,242,249,143, 63, 63,253, 53,125,146, 35,104, 35,136, 82,227,140, 7,194,110, 48, 70,130,211,117,225,172,216,
- 4, 77, 83,177, 42, 57,234,170,240,145,234,213, 62, 88,179,136, 77,140,217, 3,180,141, 0,154,163, 51,198,153,167,203, 9, 88,
- 25,232, 94, 32,131, 72, 48, 45,143,252,197, 16, 54, 91, 99, 69,111,223,158,118,153, 17, 22, 98, 61, 59, 74,205,251, 98, 78, 73,
-110, 38,166,192,104,212,183, 96,104,180, 73, 1, 36,131, 69,168, 54,103, 22,225, 43,176,154, 53,129,109,199,186,230,165,228, 5,
-121,178, 36,236,141, 32, 12, 69, 86, 17,167,243, 12,140,159, 55, 68, 78, 68,180,105, 9,101,146,148,160,199, 1,164,158,207,210,
-150,175, 2,144,116, 37, 59,146, 19, 81, 48, 23,231, 98,151,171,166,213, 53, 35,154, 85, 8,113,229,198,129, 11, 39,238,156,249,
- 70,126,131, 15,224,130,196, 1,113, 30, 49, 51,162,167,171,108,167,115, 39,194,124, 64,169,228,180,243,189,136,183, 68,232,159,
-127,249, 54, 77,186,228,186,185, 20,129, 93, 83,161,197, 29,191,108,176, 91, 71, 13, 41, 96,246, 65,251,213,215, 29, 60,189,115,
- 66,145, 11,164, 81,241,164,221, 38,237,156,178, 1,218,196, 21,123,224, 84,158,208, 41,224,131,197,137, 26,138,183, 33,138,208,
- 52, 65, 83,164,202, 56, 34, 76,156,156,216, 75,222,154,165,167, 35,135,135, 79, 27, 61,144, 60, 0, 90, 62,154,144, 19, 75,135,
-217,139,188,134,113, 30,175,166,101,164, 74,250, 27, 14,167,169,244,163, 41, 49,150, 56,142,110, 6,219,152,108, 26,202,165,217,
-151,201,130, 31,121, 92, 42, 92,231,108, 88,148, 5, 46, 3,102, 49,204,111,170, 80, 47, 76,210,151, 79, 82, 81,166,104,219,207,
-157,154,206,220,171,217,233,139,102,216,127,215,236, 37,148, 67, 84, 37,154,109,175,172, 35, 81, 43, 28,199,216,169,236,162, 89,
- 29, 73, 11,117,156,108,158,172,100,231,144,188,152, 86,175,138, 99, 63, 23, 74, 29,135,195,134,232, 48,140,107, 13, 0,221, 58,
-186, 47, 33, 69,180,157,210, 22, 14,193,145,179,252, 57, 19, 91,111, 82, 45, 68,238, 0,185, 73,103,214,142,233,192,136, 56, 89,
- 55,117, 11,212,215,102, 91, 65,150, 28,169, 93, 62, 47,236,216, 73,199,133,172, 80, 57, 17,219, 58,231, 19,123, 32,239,120,224,
-108, 61,200, 9,135,170, 88,251, 7, 25,255, 8, 94,239, 64,189,219,210,250, 93,255,248,245,211,167,195,219,143,142, 69, 53,241,
-144,141,215,179,171, 52, 32,161, 85, 42,160,110,165, 99, 50, 46,248,126,168,177, 30,217,167, 70, 67,223,186,123, 13,139, 56,135,
-238, 39,129,235,179,198, 30, 42,165,209,245,166, 19, 94,164,208, 33,214,203,210,147, 87, 53,214,225, 69,133,129,138,247,132,214,
-237, 72,156, 32,126, 92,209,215, 84, 33,123,166, 38,110, 95,218,142,127,149,108, 10,117, 46, 11, 32, 34,178,231,183, 38,123,185,
-209,140, 17,188,151, 91,228, 1,143,134, 72,165,144,181,241,131, 53,106, 10,210,123,150,209,205,142, 8, 14,232,124, 76,133,209,
-244, 2,220, 71,145, 26, 89, 93,138, 66, 20,198, 41,224,205,131,218,140,154, 19,207, 30, 16,209, 58,150,131,216,163,167, 32, 69,
-127,212,180,145, 25, 37,119,251,103, 14,198, 40,142,253, 1,196, 78,131, 62,169,215,163,197,233,216, 84,198,228,184, 40,216, 57,
- 26, 9,238,230,196, 33,247, 5, 76, 42,240,192,173,254,111,197, 65, 99, 60,174, 3,107, 71,171, 35,228, 12, 11,200, 63,130,170,
- 2,174,155,179, 22,231,141, 35, 20,156,226,113, 14, 97, 55, 83, 32, 31, 87,129, 42, 64,153, 82,162, 35, 39, 2,144,132,204,164,
-173, 0, 95, 57,107,238,196, 95,247,177,156,138,151,167,209, 15,186,168, 89,185,121,234,250,124, 25,192,120, 10, 16, 97,222, 59,
-176, 42,224,115, 41, 17,168, 70, 77,200,198,131,182,106,216,251, 6,188, 54,226,152, 76,167, 60, 22,149, 53, 40, 71,102,169, 20,
-164, 29,171,139,154, 7, 76,255, 96,118, 30, 11, 61,186,169,128, 99,184, 1,194,231,144, 67, 63,252, 83,128,108,164, 0, 35, 67,
-196,249,208,234, 7,237,255,125,243,213,151, 63,252,244,221,155,207,206,239,254, 89,223, 45, 43,190,194,199,208,155,205, 27,231,
-134,134, 19,112, 2,129,136, 27,145, 49,108, 79,154,131,216, 77,197,169,117,239, 65, 77,128, 76, 57, 98,231, 12,190, 30,106,216,
- 5, 89,222, 63, 63,191, 15,139,189, 69,185,164, 38,195,223,127,189, 92,175,159,127,243, 20,150,231, 91, 14, 8,123,181, 81, 41,
-155,143, 64,134,133, 55, 86,104,137,213, 14, 29,177,194,230, 48, 0, 44,171,159, 93,166, 85,197,178,245,142, 92, 87, 44,245, 35,
- 45, 66, 48,248,147,114,103,241,244,201, 23,230,213,247,191,254,246,246,143, 63,127,247,175, 17,122, 61,162,146, 97, 25, 68, 2,
- 23,179, 52, 7,202,161,141,221,201, 14, 38, 59,224,200,239, 93, 79,199,118,216, 52, 81,194, 10,188, 14,152, 15,108,200,106,231,
-187, 17,143,198,169, 66,235, 13,115, 27,236, 21,136,243, 68,113,149, 87,166, 41, 55, 9,119, 2, 95, 57, 9,118, 36,105, 70,210,
- 87,160,190, 67, 26,213,112, 76,183,170, 64, 65,110, 21, 7, 78,157,168,216, 98, 94, 29,167,129,236,186, 22, 58, 86, 2, 59,112,
- 91,168, 68,213, 42,107, 30,116, 1,234, 69,200, 27,194,208,205,164, 8, 72, 45, 54,124,239,154,211,143,250,158,170,199,179, 11,
-131, 60,120, 55,184, 2,117,104,179,148,255, 9,192,209,181,236, 72, 78, 4, 65,219, 85,229,170,178,221,237,110,177,195, 10,241,
- 56, 44,104, 17, 23, 36, 14,115,225,199,225,176, 92, 57, 33,113, 65,226,192, 5,105,133,230,194, 48,211,126,116,189,109, 34,252,
- 1,253,176,171, 42, 50, 34, 43, 51, 67,226,157,216,106,225,192,201,127,165,186,128,177,237, 11, 80,200,140,160, 76,181, 90, 53,
- 61,214, 14,159,155,126,162, 16, 93,182,222,170, 5, 66,116, 80, 1, 12, 89,150, 83,201,246, 30,231,225,130,157,218,208,133, 41,
- 55,160,205,180,236,201, 9,112,218,158,124,186,137,202,104,205,241,250,126,105,246,169, 19,125,102,118, 87,113,178,245,198,108,
-165,127,241, 28,202,133,216, 63, 96,185,180,108,193, 98, 92,117, 98, 51, 16, 34, 60,253, 60,121,163, 0, 97,218,165, 82,169, 32,
-183, 8,110,130, 95,148,199,154, 39,155,113,242, 13,167,186, 41, 44,106,176, 3,237,193, 32,168,129,195,157,144,228, 20, 71, 97,
-196,145,112, 42,108, 10,164, 21, 51, 37, 79, 8, 21,120, 90,103,243, 4,109,238, 25, 28,235, 8,102,191, 99,201,242,176,103,135,
-192, 20,154,104,218,118, 91,180, 15, 55, 97,240, 6, 74,161,187, 14,208, 92,179, 45, 58, 29,212,135,131, 57,121,125, 91, 56,122,
- 43,103, 35, 64,248,200,228,129,229,217, 11,127,222, 58,102, 79,200,213, 43, 58, 10, 67,104,225,255,178,238,250,168, 20,134, 34,
-162,135, 77, 47,154,185,180, 8,174, 38, 87,175,147,122, 22,238,236,135, 86, 66,251, 58,231,143,250,252,138, 85, 77,251,110,180,
-175,231,251, 90, 64,249, 58,168,196,201,234,180, 69,149, 23, 72,234, 26, 36,131,134,201, 81,133, 60,137,139, 52, 67,149,240, 36,
-188,136,212,180, 39,155,218,252,244,165, 95,161, 16,238,181,236, 72,253, 75, 99,194,230,112, 0, 33, 15, 10,132,130,206,213,152,
-177, 98, 16,185,137, 53,137, 0, 96, 93, 76,177,142,105,127,232,216,201,236,197, 49,103,178,187, 35,145, 54,170,242, 44,253, 9,
-107, 27,150, 32,223,204, 34,248,166,238, 54,246, 76,215,213, 73, 65,133, 75, 1,109, 9, 26,229, 89, 32, 26,153,253, 46,140,244,
-236,255,173, 87,224, 64,168,238,166, 50,158,131,140,154,150,253, 28, 0,149, 73,179,236,119, 0, 18,214, 91,211,237,238, 38,196,
- 37,214,208, 75,216,183,253,182, 63, 87, 51,175, 71,196,206, 27,195, 45,143,130,137, 31, 68,252,195,162,173,211, 45,158, 84, 58,
- 78, 14,130, 10,134,170, 90, 0, 4,231,130,195, 72,251,178,101,151,248,154,150,121,173, 93,231,113,149,161,175, 57, 82,111,111,
-109, 82, 45,150,131, 25, 59,240, 38,201, 28,166,105, 76,204, 52,210,242, 88, 91,173, 62,137,137,111,156, 16,217, 56,206,120, 85,
-148,135, 64,203, 88, 65,184,199, 24, 13,104,136, 44,121, 1, 71,247, 15,182,154,214, 26,172,105,144,217, 2,236,192, 77,123,211,
-131,208,172,201,128, 41, 32,120,239, 13,103, 26,224,131, 39, 99, 56, 67,131, 99,114, 55,230,139, 37,226,210,219,118,215,173,120,
- 73,144, 28,246,218, 84,231, 51,135,120,211,190,130, 19, 28,124, 29,150, 89,223,161, 96,166,151,117,190,223,103,236,198,168,206,
-248, 40,189,101,157,206,106,137,238, 44, 70,171,194, 98, 36,128, 22,180,204,215, 77, 39, 65, 87,246,144,244,166, 8, 32, 80, 72,
- 44,200, 96,147, 7,139,143, 57,254,245, 32,237,158,168,178,225,252,128, 99, 64,202,229,154,117,152,137,246,205,208, 89,101,250,
-199,205,207,245,233,201, 92,222,253,248,248,197,227, 15,239,126,249,240,215,207, 31,126,127, 90,125,157,123,105,142, 58, 9,236,
-108,232,226, 1, 27,108,115,192,244,114,120,120, 23,250, 58,131, 9,141,136,151, 90, 94, 17,204, 23, 57,215,254,254,223, 44,188,
-120,252,246,171,183,223,189,249,254,155,175,175,253,217, 60,136,219, 61, 93,188, 27, 63,254, 57,129,215, 89, 78, 37, 42, 9,162,
-181,222,174, 96, 91,180,117,139, 56,137,175, 12,238,236, 77,137,133, 21, 41, 83, 94,217,252,190,213, 32, 93, 78,211,249, 17, 1,
-217,181,246,211, 58,235, 86,219,246,250,217,216, 95,223,255,244,219,199, 95,255,254,195, 60,200, 1, 71, 49, 26,225,188,187,180,
-160, 8,224,182,214,118,133,101,228, 77, 47, 98, 17,221, 90,202,120,110, 63,191,145, 49,128, 73,235,202,154,224, 12,147, 80,224,
- 44,150, 77,140, 58,129, 89,218,169,207, 90,157,247, 48,238,237,171,240,145, 93, 77, 94,117, 8,227,186,219,171, 69,109,178, 4,
- 94,184,117,178,177, 81,182, 93,237,116, 72, 47,113,143,167,109,168, 98,242, 80,115, 10,123,241, 78, 79, 44,250, 18,240, 90, 19,
-140,204, 24,208, 41, 55,249, 88, 78, 16, 18,174, 81,227,157, 41,113, 40,141,152, 92,163, 3,116, 69,177,128, 97,128,217,146, 88,
-140,158,210, 34,246, 24, 44, 32, 12, 18, 3, 98, 4, 52,111, 74,219,255, 2,112,116,245, 60,178,211, 80,212,241, 71,236, 56,153,
-157,221, 89, 9,104,144, 30, 13, 13,210,163, 1, 81,208, 33,138, 87,240, 87,105,104,232, 95,133,160,161,128, 14, 9,137,234,177,
-210, 14,187, 51,147,196, 95,177, 57, 39,253,104,102,226, 92,223,123,142,125,239, 57, 96,233,120,149, 8,123,119, 18,253, 69,228,
-171, 6,174,238,168, 68,123, 82,227,154, 22,222,111,228, 10, 4,183, 51,184, 28, 58,100, 78, 10, 64,117,219,124,219,202,199,216,
-241,169, 28,124,158,228, 3,232,113, 0, 48, 25, 37,219,246,105,199, 0,238,103,250,117,170, 8,200, 62,214, 64,107,216, 59,147,
-177, 58, 5, 80,178,203, 28,210,196, 50,182,250, 60, 0, 34,129,158,145, 47,174,133,190,224, 55,122, 75, 19,133,141,120, 4,234,
-153, 28, 44,152, 5, 8,153,105, 74, 78,109,163,237,163, 83,246, 50,138,163, 81,135,116,100,227,168, 28,250,163, 74, 65, 28,234,
-102,139, 7,223,145, 83,164,223,119,227, 25,166,242, 52,149,232, 64,210,121,219, 71,117, 38,222,138,111,126, 59,103,234,173, 0,
-164,107, 80, 7, 32, 25, 20,133, 25, 88, 82,128,169,161, 34,176,149,129, 19, 92, 36,158,187, 56, 34,125,136,176,150,150, 6, 66,
-186,188,114,132, 66, 60,112,103,174,181,152, 93,203,191, 91,205,204, 19, 70,106,213, 3,138,178, 25,184, 23,253,156,197, 48,156,
- 83,209, 14, 12,199,200,152, 64,138, 44, 88, 23,207,182,219, 70, 55,111, 94,211,167, 12,184,203,243, 51,235,251, 83, 69, 61,111,
-231,176, 18, 43,128,213,136, 16,105,101,176,246, 79,235,230, 81, 2, 34,231,140,181,155, 11, 74, 97,163, 60,225,116,145, 67, 16,
-252,144, 64,213, 2,166,105, 47,142, 77,145,146, 74,228, 57,160,198,209, 27,168, 63,109,168, 7,166,214,139, 51, 35, 42,176,124,
- 4,210,208, 20,129,144, 93, 80,148,216, 64,200,230,150, 6, 39,212, 34,216,173,202,196, 95, 86, 2,100, 64, 39,170, 96,225,247,
-182,200,118,255, 74, 78,194,171,209,238, 76, 45,214,201,138,203, 67,121,229,129, 40,184,141,136,200, 88,215,173, 96,181, 98,215,
- 61,230,245,130,204,197, 20, 98, 50,149,177, 59, 77,195, 44,189,223, 97, 35,209,176,206,103, 11, 26, 66,104, 20, 80,224,217, 9,
-211, 52, 7,157,153,198,157,201, 82,173, 6,111,181, 49, 22, 29,197, 81, 21, 79,141, 0, 97,148,203,108, 94, 1,120, 3,209,157,
-123, 54,211,181, 10,134,137, 55,166,218, 0, 98,147, 37,224,170,145,148,181, 72,109,240,149,141,230, 20, 89, 84, 84, 68, 6, 93,
-244,205,198, 73,222,247, 49, 52,141,224, 25, 26,106,143, 5, 27,163,175,235,208,201, 65, 3,115, 81,181,120,173, 19,171,148,162,
-133, 99,107, 30,193,212,118, 5, 10, 65, 37,101,106, 79, 35,229, 72,155, 91, 84,190,148, 78, 95,181,240, 4,110, 34,242,222,139,
-249,113, 16, 27,216,192,140,154,141, 58,239,140,203,194, 81,207, 67, 30,217,120,101,195, 46,204,150, 77,218,221, 66, 57,197,132,
-128,189,171, 83,111,169, 39, 6,216,227, 83, 50,163,155, 27,242,195, 22, 66, 4,252,234, 80,145, 69,190, 83,143, 86,202,126,212,
-169, 69,141, 72,101,183,247, 40, 90,112,117, 1,213, 3,206,243,197, 46,142, 61, 40,138, 83, 72,120,215,149,166, 9, 26,196, 72,
-210,237,147, 1,211,237, 76,115,135,150,228,130,123, 11,115, 54, 8, 12, 78, 64, 33, 55, 75,149,100,157,246,134, 88,148,194,121,
-173, 75, 1,180,214,135,127,204,241,179,119,239, 62,255,238,219, 55, 63,254,244,251,251, 95,255, 10,233, 98,237,208,118,135,111,
-182,172,243,236,152,198, 23, 96, 79, 72, 42,168,235, 72,246, 53,105,123,240,192,132,249,195, 44,141,253,230,203, 47,190,255,225,
-237,215, 95,125, 42,196,127, 66,220,132,248, 87,136,149,142,140, 31,158,254,254,243,252, 18,216,153,215, 18, 39,127, 28,171, 63,
-109, 21, 57,115,165, 40,233, 15,136,144,111, 27, 53,179,193,203, 35,214,170,137,104, 16, 25, 53,242,224, 73, 78,186, 1, 98, 12,
-125, 27,235,225,120,252,232,205,219,247,191,229,159,127,249,195, 25,225, 62,153,240,197,203,125, 30,205,182, 84, 16,142,118,239,
-193,244, 60, 21,202,139,185, 12,155,233,162,149,195,229, 57, 29,192, 8,189, 29,123,112, 45, 89, 38, 27,250,123, 44,164,117, 96,
-210,106,210,146,147,148, 39, 16,205,219, 38,166,236,121,143, 2,176,179,137,167,254,104, 69,112,125, 5, 8, 28,101,168,160,174,
-253, 43,205,221,139, 92,177, 51, 56,254,140, 61,191,224, 63,134,193, 26,178,235, 21, 43,133,200,196, 99,181,196,176,104, 17,165,
- 49,216,187,113,151,158,187,214,228,175, 83,232,158, 81,192,151, 66,163, 83, 87,138, 40, 47, 11,168,175,230,148,153, 5,193, 53,
- 6, 25,108,230,128,197, 54, 4,202,211,209,239,163,254, 47, 0, 73,215,178, 27, 57, 17, 69,235,237, 42,151,187, 39, 19, 6, 4,
-131,196, 2, 17, 4, 11, 88,178, 68,176,102, 5, 11,190, 3,137,111,227, 35, 96, 5, 2, 33,216,176, 28, 49,147, 76, 38,233,182,
-203, 46,151,203,197, 57,205, 50, 73,119,199,109,223,123,235,220,215, 57,250,219,111, 62, 65,138,119, 79, 93,226,198, 37,232, 5,
-168, 90,246, 75,193, 93,122,147,143,105,228, 8,248,242,160, 6, 78, 20,102, 18,103, 34,118,112,137, 79,217, 81, 46,207,188,107,
- 14,118,198,253,233, 67, 76, 1,103,169, 31,154,201,186,134,173,177, 88, 88,154,139, 90, 88,146,227,155,177,182,199,236, 97, 50,
-143,194, 60,101,129, 54,112, 86, 18, 17, 34,195, 61, 53,103, 98, 89, 26,164,156, 57,130, 97,135,195, 94,178,255,247,132, 84, 93,
-187,114, 69,169, 28,145,209,144, 28,195,236,182, 5,164,188,237,216,227, 45, 62,192, 34,241,245,240,106,215,251, 67, 71,122,192,
-106, 96,193, 48, 80,252, 30,207,140,108,239,117, 97,235, 30,215,133,192, 32,201, 71,197,205, 85, 92,223, 10,184,103, 73, 51, 94,
-114,199, 81, 16,130,193, 66,146,114, 36,157, 48,245,137, 4, 22,148,231,160,240, 35,233,241,121,205, 26,192,215, 94, 90,202,172,
-208,224,104, 48,236,190, 95,136,223,129,193,124,159, 1,187, 96,107,129,252, 51, 92,223,171,184,118,242,210, 20,230,201, 86,140,
-190,112,193,155,186,163, 82, 52,153, 40,216, 32,205, 3,185, 10, 5, 14,182,115, 59, 3,230,109, 25, 32,208,238, 43,238,251,220,
-201,180,226,196, 45,156, 66, 71,130, 22,250,156,146, 88,112, 14,197, 60,100,183,173,251, 52, 89, 30,237,192, 50,141, 18, 83,165,
-121,124,168, 87, 38, 46, 72, 69, 56, 61,210, 38,120, 25, 44,238,240,197,167,207, 14,175, 95,157, 84, 50, 46,144,239,209,110, 54,
-113,136,133,134,141, 44,230,178, 5,200,116,176,176, 45, 9,252,142, 68, 42,159,184, 63,135,167,151,107,147, 39, 0, 8,178,174,
- 23, 67, 56,140,176,206,142,170, 33, 35,244, 88, 8,154,223, 42,220,135,120,117, 33,251, 8,129,165,252,178,240,230, 85, 56,184,
-119,227,193, 24,235, 17, 47,102,131, 80,230,174, 10,206, 2,192, 99, 74, 41,226, 25, 21, 78,126,224,124,109,254, 9, 43,184,100,
-112,199,165,247, 28, 81,129,247, 74, 96, 99, 4, 35, 67, 26,170,165, 86, 23, 21, 98,150,181, 44,157,119, 7,121, 58,194,147, 17,
-143, 37,171,233,149,171, 34, 98, 32,101, 98, 33, 32,161,142,111,100,207,188,233,183, 57,159, 71,146, 47,142,142, 28, 69,236,240,
-121, 44,194, 90,106, 0,235, 43, 88, 25, 91, 91,171,236,143,209,165,222, 32,218,183,192,214, 13,210,109, 10, 9,100,252,172, 45,
-183, 89, 41,107, 86, 17,166, 55, 64, 51, 68,192, 29, 14, 70, 10,137, 72,249,118, 27, 54,110, 63, 3,114,196, 94, 68,238,175,179,
-185,204, 34,239, 26,184, 91,111,251,227, 78, 98, 31,167, 13,208, 90,211, 1,127,114,106,208,212,133, 47, 36, 35,141, 22,246,108,
-165,235,162,130,139, 31,119, 50,148,115,150,125,207,235,121, 70, 38,211, 56,108, 52, 60,215, 7,143,156,163,183, 17,145, 68,134,
-224,168,134, 26,141,236, 66, 22, 46, 71,171, 19, 9,166,251, 75,165,144, 20, 25,149,247,143, 61, 27, 30,107, 43, 48,106,243,100,
-234,151,197,114,133, 30, 81,195, 94,142, 91,106,106, 81, 32, 8,249,143, 48, 90,167,252,191,178, 4,139, 80, 27,213, 47,155, 94,
-119, 74,184, 76,109, 77,101,187,215,250,206,244,254,179,207,111,190,254,242, 70,140,234,247,159, 95,190,153, 19, 92,194,153,125,
- 26,173,167, 28, 53, 55, 62,144, 34, 34, 44,247,118,134,101,140,227,227,120,123,255,241,205,135, 63,254,240,213,119,223,191,243,
-254,243, 59, 81,255,154,199,191,215,249,159,117,186, 75,231, 23,226,254,118,254,243,229,139,219,173,222, 86, 61,145,242,124,245,
-217, 38,216,182,166, 78, 64, 99,255,176, 33,130,159, 37,229, 24, 79,112,227,182,158, 21,243, 80,106, 80, 33,106,236,213,117,122,
-208,241,218,217,172,250,247,204, 7,239,126,244,203, 31,215, 63,253,246,171, 85, 39,123,237,225,168,212,145, 32,157, 6,190, 14,
- 39, 70,240,116,151,205, 27,220, 39,142,186,144, 95,198,247, 67, 73,139, 26, 14, 72,232,185, 33, 6,156,208,210,225, 72,110, 45,
- 47,194,234, 68,216,187, 14,105, 0, 73, 77,120, 3,129,172, 88,174,189,154, 88, 76, 0, 66,104,110,231,169, 56, 15,230, 95,224,
-149, 92,159,146,111,146,245,157, 7, 56,190, 54,150,116,121,178,173,170,156,151, 83, 27,119, 42, 75, 87,137, 60,121,203, 11,129,
- 98, 93, 21,240,131, 45,192,207,219,163, 90,144, 23,113,151,218,218,154, 39, 45,230, 21,255,116, 55,112,234,107,171, 22, 65, 5,
- 38,188,246, 52, 39,192,101, 50,107, 23,153,149,220, 89,110,254, 79, 0,142,174, 36, 71,138, 24, 8,122,183,203, 53,221, 51, 98,
- 88, 78, 92, 16,130, 3, 72,128,196, 1,241, 1, 30,128,248,199,188,137,215,112, 70, 28, 57, 1,130, 97, 29,232,233, 90, 92, 94,
-138,136, 58,142,212,154,118,185, 51,211, 17,229,204, 8,253,250,205, 99,112, 82,240, 78,246,181,148,130,221, 28, 92, 13, 99,160,
- 27,165,225,164,128,181, 26,167,234,206, 46,211, 76,131, 91, 51,107, 22, 2, 48,110, 84, 63,158, 34, 14, 43,117, 50,167,197,170,
- 77,123, 28,161,159, 0,217, 59,235,226, 94,200, 48,250,178,100,252, 26,154, 82, 78, 38, 83,214, 53, 33,225,174,230,169, 4,103,
-230,107,109, 92, 43,170,160,176, 32,213, 56,153,135,244, 82,217, 83,158, 4,180,125, 97,161,230,232, 29,123, 28, 64,115, 24,248,
-194,161,180,239,186,146, 67,153, 38, 80,177,216,221, 48,222,226, 88, 4, 8,169, 49,235, 28,212,112,102, 41,201,175,195,106, 61,
-142, 81, 96,230, 98, 93,182, 29,141, 24,144,101,173,219,204,127, 16, 44,116,175,200,114, 11, 25,169, 18,158,131, 67,135, 40,164,
- 84,108,193, 9, 16, 57, 59, 39, 11,181, 12, 2,199,128, 81,251, 84,118,170,114, 8, 26, 96, 36,114,158,195, 97,189, 85,216,117,
-215,184,228,230,184,107,149, 35, 65,156,125, 81,244,221,108,116,234, 46,130, 88, 64,168,121, 94,163, 38,189, 33, 2, 23, 22,193,
- 11, 82, 73,109, 21,145, 43,197,198,104,238, 94, 89,127, 64,202,104,198,125, 76,165, 21,246, 65,147,158,153,190, 38,149, 14, 51,
-152,138,244, 43, 34,131,252,119, 6,214,174,170, 3,104,153, 23,202,222, 2, 94, 15,236,148,162,150, 94,173, 3,223, 4, 83, 25,
-235,168,179, 92,186,135, 15,110,221,185,250,122,221,165,241,140, 42,145,189,246,190,151,114, 15,144,176,233, 66, 34,105,144,154,
-138, 77,155,212,227,197, 97,235, 80,199,155,153, 54, 37,246,137,138, 47,235, 0,154, 37,125, 49,211,196,174, 32, 65,101, 2, 67,
- 5, 16,185, 25, 83, 80,150, 77, 70,148, 38,207,234, 81, 42, 47, 38,221,222, 38,151,125,162, 61, 85, 81,139,219, 70, 28,216,242,
- 79, 81, 15, 20,228,182, 56,138,183, 33,138, 65, 19, 58,108,230,237, 48,179, 47, 35, 80, 63, 33, 32,183, 20,135,199, 80,160, 27,
-107, 19,149,154,168, 14,231,217, 29, 73, 53, 49, 14, 2, 26,138,196, 32, 95, 37,111, 94,168,214,168, 57,132,195, 17, 98, 4,152,
-206,145,157, 60,132,241,209, 83,105, 14, 95,182,115, 72, 81,187, 20, 15,226,189,175, 52, 82,139,214, 73,252,208,214, 91,172,202,
-156,137, 50,208,103,173,101,182,223, 73,208,111,139, 13,115, 14,212,105,217,175,181,179, 50, 71,124,152,173,216, 32,153,170, 71,
- 24, 2,219, 90, 28,192, 64, 15,180, 96,138,188,106, 93,115,202, 72, 5, 45, 3, 47,103, 16,234,168, 26,212,250,217, 33,228, 78,
-180, 11,186, 43, 53,244, 8,120,233,233,154, 37, 34,144,118,113,167,198,243,245,250, 17,208, 55,129,108,131,182, 39,206,133,153,
-169,105,111, 59, 0, 62,195, 70, 32,117,138, 53, 72,129,131,103,103, 0, 47,131, 15, 52, 30,231,187, 73,225, 60,223,201,172,193,
- 80,185,211, 70,206,101, 34, 52,183,209, 95,217, 1,161,177,237,184, 94, 39,155,200,175, 42,181, 36,138,160, 38, 73,163,101,202,
-184,185,205,205,170, 29, 18,157, 2,121, 3, 68,181, 35,250,239,208,137, 1,165,180,177,137, 13, 15,154,121, 41, 88,210, 33, 47,
-191,180,249,227,187,243, 71, 79,238, 63,127,116,183,214,116,249,249,251,223,195, 80,188, 60,195,127,230, 93, 7,206,164, 37, 71,
- 2,213,223, 63,211,245,114,124,245,226,217,197,197,203,187, 64,237,245, 67, 26,191,204,227, 63, 20, 45, 13, 52,129,199,252,158,
-203,101, 61,124,154,126,253, 85,161, 97, 57, 77,142,188, 28, 90, 70, 62, 16,149,181,220,150, 46,136,207,131,184,162, 49, 18,205,
- 50,253, 17,188, 76, 81, 86,108, 47, 39, 48,173,149,123,184, 6, 0,211,120,239,201,211,143, 63,110,190,125,247,254,210,127, 59,
-177,248, 73,165,230,101,179,159, 60,111,151, 53, 17, 13,141, 6,229,102,173,137,132,104,179,229, 29,118,143, 15, 6,112,203,243,
-196,151, 0,173,239, 79,122,170,203,177,248, 87, 23,207, 7, 32, 3, 4,115, 4,176,164,160,166,222,245,180,226, 43,125,110, 40,
- 90,180,194, 38,196, 43, 1, 44,153,130, 2,133, 46,142, 20,181,244, 96,202,107,175,176,255,248,174, 44,218,166,224,190,122,238,
-235,102, 78, 82, 80, 78,181,105,115, 30,192, 75,104,217, 87, 1,214, 13, 85,167,235,232,113,156,150,201,255,243, 14, 53, 93,166,
-165,202,195, 41, 69, 18,228,132, 63, 87, 49, 76,153, 61, 41,219,236, 55,128,155,112,203, 92,254, 11, 64,210,213,180,202, 81, 68,
-209,174,239,174,238,153,113, 34,121, 38, 32,184, 84, 72, 66, 86,242,240, 31,184,114,231,198,181,110,252,101,254, 13,255,132,171,
-132, 16, 8,130, 24, 94,124,239, 77, 79, 85,119,215,151,231, 84,118, 3, 3, 51, 77,117,221,123,207,169,186,247, 28,245,203,207,
-223,229,130,212,177,175,215, 70, 24, 14,178,139, 8,185,152, 56, 68,221,221,227,180, 2,148,195,211, 16,137,186,163, 22,235,196,
-202,146,145,142, 45,173,170, 92,181, 20,234,157,109,151,163,250, 18, 20,196, 77,148,137, 65,118,166,231,136,242,122,232,231,147,
-248,158, 93,162,226,138,252,168, 54, 91, 39, 20, 17,254, 93,180,212,200,105,212, 80,154, 50, 16, 7,248,116, 48, 8,101,118, 97,
-210, 33, 24, 91,109, 70, 77, 69,224, 18,174, 33,178,205,122,250,239,152,253,165,250,141,244,121,144, 17,121,222, 78, 30,245, 13,
- 25,214, 89,228,169,147,175,245, 72,175, 7, 73,185,112,100,129,207, 98,189, 40,192,218,115, 2, 78,109,125,162, 67, 24,202, 5,
- 16,140,128,249,209, 2,142, 61, 70, 91,229, 57,142,162,255, 23,133,123,186,154, 13,240,105, 97,117, 29, 24,234, 20, 51, 69,189,
- 7,156,199,246, 71,189,215,214,114,124,152,215,137,141, 94, 95,181, 91,105, 37,207,233, 15,208, 69, 3, 34, 9, 40,205, 56,194,
- 10,208,246,116,160,104,179, 25,158,214,182,200, 66, 89, 7,222,144,238, 11,202,202,154,123,174, 19,129,210, 89, 17,136,114,163,
- 5,161, 77,113, 49, 33, 95,194, 70,199,212,114,105, 32, 57, 72,222, 32,224, 26,153,117,167,188, 70,179,197,177,177, 68,172,154,
-125,251,134,167,250, 73,210, 78,175,228,207,160,140,206, 71, 59, 48,235,139,151, 55,207,214, 15, 15,165,126, 49,178,235, 9, 28,
- 43,155,196,241,239, 93,215, 37, 17,232, 37,124,110,118,161,104,218, 78,149, 58,177,126,202, 41, 33,134,134,251, 72,143,166,150,
- 4,112, 3,125, 0, 34, 86,162, 57,144, 91,161, 64,250,155, 67, 62,158,110, 14,134, 50,142,147, 72, 28, 99,115,120, 82,233,134,
-112,238,154,249,146, 75, 64,165,241, 1, 8,162,104,211, 39,203, 53, 37,218, 19,214, 74,245, 51, 14, 4,232, 33,103,122,240,173,
-150,146,241, 96, 97,185,126,196,130, 73, 44,133,228, 62, 96, 91,136, 59,128,144,241, 80, 97, 38, 79, 84,234,100,193, 89,132,222,
-177, 26,195,141, 7,116,164, 94,130, 53,200,237,210, 57, 63, 82,178,139,106, 49, 67,215,213, 20,118, 28,187, 96,179,205,216, 62,
-192,129,136, 68,218,188,105,122,121,153,157, 7, 9,226,232,164,179,180,124,195,235,176,102,180, 94,239,136, 52, 87, 38, 37,121,
-217, 50,209,113, 73, 14,246, 4,140,134, 71,229, 5,171, 26,119, 54,143,143,192,144,211, 52,172, 14,121,104, 4,154, 64, 29,219,
-228,209, 80,110, 13,165,132, 7, 54,170, 26, 9,156, 39,136, 32,216, 34,139,170,168,157,155, 54, 95,176,225, 71,165,100,100,151,
-237, 34,123, 79,148,116,171, 4,108,199,218, 81, 69,225, 64,135, 48, 20,240, 26,233,194,106,217,248, 45, 78,212, 86, 69,140, 0,
-159, 88, 7,222,128,119,230,244,228, 68, 77,244,142,212,135, 90, 14, 6,148,203, 62, 82,151, 3, 12, 22,165, 18, 47, 6, 9, 69,
-225, 39, 0,122, 42,197, 33, 88, 31,168, 57,203,235, 41,150,112, 75, 23, 96, 98, 64,209,167,173, 57, 4,133, 2,219,218, 74,124,
- 51,116, 75, 96,130, 79, 14,104,243,190, 66,112,170,254,190,197,127,245,120,127,126,254,244,246,246,213,247,175,191,126,248,240,
-248,238,237,221,150,150, 32, 27,210,142, 79,242,180,167,251,144,228, 53,255,250,211,143,191,253,254,195, 56,190,201,159,254, 10,
-143,255,180,235, 14,180,163,175, 82,132,146,238,114,184, 19,203, 18, 62,254, 29, 46, 15,121, 22, 38, 82,253, 81,202,200,152,164,
- 45,237, 21,255,135,100,175,176, 51,250,117,150, 42, 70,211,167, 9,143,243,164, 17, 8, 74,171,199,153,164,125, 82,135,175,230,
-155, 23,223,190,187,124,243,199,159,111,131,123,127,172,231,210, 71,104,132,179,153, 26, 58,156,145, 25, 41,183,217,186, 10, 51,
-178, 18,176, 91,163,190,129, 3,151,178,243,208, 47, 58,207, 94,157,142, 92, 45,186,138,202,181,152,153,204, 6, 5,193, 55, 77,
- 28, 33, 42,123,212, 52,237,194,236, 17, 76, 74,123, 55,167,114,160, 93, 23,208,137,106,231,180, 86, 47, 47,236,170,203, 99,237,
- 71,215,185, 70,250, 50, 24, 30, 5,240,120,180, 68, 14, 66, 79, 62, 20, 96,180,181,139, 49, 82, 92,116,223,120,143, 53,204,105,
-137,146,117,136,195,144,156,242,138, 79, 82,145, 37,236, 70,135,109,184,238,129,182,244,172,221, 37,152,142,192, 36,189, 20,128,
-165, 69,249, 95, 0,142,174, 93, 85,142, 35, 10,118, 79, 63,167,103,246,222,229, 98, 9, 4,178, 4, 78,140,141,193, 24, 20, 40,
-112,228, 31,176, 35, 59, 16,254, 74,127,134, 18, 69, 2,103,150, 65, 15,144,109,233,238, 99,102,250,237,170, 73, 54, 89, 88,122,
-251,113, 78, 85,247, 57, 85,234,151,223,190, 93,176, 93, 28, 51, 52, 35, 24, 78,134,162, 55,195,153,186,111,149,151, 89,103, 96,
- 67,158,246, 43,144, 87, 71,176, 97, 89,204, 45, 14,139,107,215,137,111, 90, 3, 55,193, 0,214, 77,163,188, 92,235, 45,181,211,
-144, 85, 88, 47,135,147, 81, 98, 6, 95, 66, 28,195,177,193, 16, 78, 87,140,251,162,162, 75, 3,123,207, 64,194,239, 21, 75,105,
-156, 60, 13,188,248,155, 3,226,208,120,227,129,177,193, 9,113,194, 12, 77,171, 88,147,168, 37, 59, 78, 87, 68, 48,160, 36,196,
-202, 60,106, 61,149, 27,103, 17, 63,171,161,228,225,148, 37,223,196,177, 50, 53, 55,111,244, 60, 33,184, 8,250,251, 10,122,125,
- 15,236, 32,203,153, 66, 36,146, 50, 28,200, 94,180,247,166,123, 44, 53,154, 36, 35, 18, 5,115,105,164,183,182, 20, 5,165,211,
- 54,186,201, 49, 64, 18,171, 81, 52,202,100, 42,157, 1, 78,231, 49, 91, 11,206, 89,146,103,205,123, 54, 52, 15,106, 1, 11,192,
- 11, 67, 29, 44,245,174, 52, 37, 49, 0, 14, 78, 54,241,178, 42,106, 28,168,179, 91,243,198,242,147,207, 14,243,194,234,241,148,
- 2,210, 99,210,200, 34,235,191,210,110,235,186, 97,207, 11, 48,181, 45,180,101,141,139, 1, 88, 42, 25,120,131, 42, 93, 10, 72,
-104,241, 32, 67, 99, 76,217,240, 13,245,176,245,243, 66,241,182,149, 69,105,114, 40,250, 12,120,201,210, 21, 5,210, 1, 2, 2,
-246,193,139,250,233,248,252,135,199,254,253,223,159,107,113, 71, 0, 60, 49, 55, 71,187,188, 36,144, 58,193,216,183, 79,248,175,
-148,207, 67,186,216,246,134,216,245,210, 27,210,144,196,158,233, 37, 10,183, 81, 31,134,133, 34, 8,183, 68,212,180,244, 2,183,
-240, 9,193,178, 80, 64,242,216,210, 34,203,222, 74,236,201,116, 41, 39,132,101, 38, 78, 96,209, 57,102, 86,147,162, 7, 80, 86,
-204,174,102,139,153,181, 60, 76,192, 97, 90, 47,136,135, 64,166, 74,217,136,196,174, 98,160,240, 3,226, 73, 63, 48,214, 72,111,
-176,164, 72,216, 49,178, 11,127, 81,251, 85,108,241,166,241,250,208, 60,148, 83,178,172,136, 24,187, 13,224, 34, 56,130, 58,207,
- 89, 42,146,238,230, 45,207,236,190, 85, 51,206,161, 86,128, 19, 22,251,204,177,201, 14,120,130, 42,235, 55,119,172,133, 61,146,
-183, 97,147, 87,205,254, 83, 96, 64,227,229,224,241, 5, 8,143,180,101,107,188, 5, 78,195, 52,208, 65, 3, 83,108,210,222, 74,
-160,169, 56,233, 48,127,130,182,187,157,247,128,248, 11,192, 20, 46, 83, 26,207,171,169,213, 13,233, 18,140,210, 85,203,130, 51,
-185,247,100,130,163, 3,233, 27,147, 2,130, 38, 85,206, 28, 61,148,169, 21,137,176,171, 75, 87,163,216, 45, 32,181, 7, 85,114,
-162, 77,149, 98, 10, 7, 95, 2,126, 90, 98,178,228, 72, 27,226,210,199,225, 64,207,120,121, 16, 24, 93,117,160, 3, 94,208,240,
-130,218,171,180,213, 13,122,186,101,131, 65, 62,181,114, 97,238,194,190, 46, 89,212,145,122,194, 29, 36, 76,179,229,129,250, 86,
-137,158, 11, 84,125, 20,124,184, 19, 21,163, 98, 23,103, 97,199, 6,223,213,187,201, 45, 38,246,126, 99,148, 43, 69,233, 88,227,
-209,150,114, 77, 53,191, 1,213, 62, 62,248,242,199,159,190,255,238,155,175,228,233,148, 78,247,239,254, 57,157,115,185,126,248,
-132, 41,254,249,215,103, 47,126,127, 42,196,171,248,246,117,137, 87,138,220, 71, 35,207, 72, 4,113, 89,240,145,175, 31,227,242,
-223,118,190, 40, 63, 4, 64,222,251,220,119, 11, 96,190,162,128,181, 42, 22, 48,241,141,135,162,179,189, 1, 40,233,184, 81,166,
-210,209, 85, 66,130,182, 56,166, 66, 36,253,249,139,242,228,201,163,143,234,235, 63, 94,254,245,230,237,159,193,206,108, 81,212,
- 66,133, 68, 9, 87,207,154, 10,252,162,225, 75, 41,120,130, 4, 76,238,108,145,172,250, 78, 47,136, 45, 87,201,166,183,135,163,
- 92,211,176,225,200,133,193,218, 89,177,159,236,209, 29, 22,114,194,126, 4,161,219,219,180,181,241, 92, 63, 63,248,219,249,162,
- 1,242,146,244,244,105, 90,150,190, 30, 88,170,132, 40,221,178,114, 62,213,232, 0, 11,193,177,179, 92,131, 26,193,202, 22, 50,
-163, 78, 29, 13,177, 70,125,159,105,149,236,121,119, 75,135, 61,201, 39, 40,129,136,152,250,198, 2, 75, 62,157,136, 57, 93, 64,
-115, 55, 26, 93, 98, 29, 54,140,174,103, 58, 72, 85,113, 41, 8,218, 11, 38,167, 4,106, 87, 0,186,253, 47, 0, 73,215,178, 35,
- 71, 17, 4,171,235,213,213,213,189,179, 94, 27,140,141, 4,103, 46, 72, 8, 9,137,131,101,249,226,131,205,137, 31,224, 15,252,
- 99,252,137,191,193,167,229, 0, 50,150, 49, 59, 59,253,168,174, 71, 58,162,125,155,195,104, 30, 93, 85,153, 17,149,153, 17,230,
-247, 63,126, 36,190, 21,179,252, 55,119, 35,242, 6,126,202,144,182, 12,138, 99,138, 95, 0,115,230,214, 77,118,107, 2,106,139,
-205, 41, 49,219,158,119,227, 0,225, 37, 6, 10, 47,120, 77, 38,242, 40, 74,244,141,178,197,182, 4,250, 74,119, 81,101, 0,205,
-189,204,244,131,115, 59,114,238,222,144,160,144,190, 78, 23,128,191,198,219,189,253, 16,191,180,233,225,135, 85, 22,132,240,181,
- 27,165,158, 65,116,215,196,192, 90, 2,157, 55, 88,140, 54, 72,216, 94,186, 27,160, 22,153, 2, 85,159,180,227,159, 50, 54,102,
-207,153, 13, 43, 62,244,166,209,245, 88,155, 96,211,184,215, 79,166,170,153,118,131,202,111,238,138, 37, 85,241, 22,193, 15,148,
- 68,134,164, 46, 94,249,181,164,206,141, 28,219,220, 87,192,214, 43, 91,230,182, 31,112, 28,168,222,103, 7, 56,195,185,118, 97,
-219, 12,169,108,208, 91, 35, 17, 48,244, 70,225, 4, 72, 89, 65,125,120,251,222,247, 82, 64,119, 19,120,152, 49, 8, 47, 28, 27,
-226,172, 68,208,133,144, 64, 76,108, 62,247,133,173, 26,136, 10,182,199,138,249,164,239,147, 95, 56,123,217,149,122,183,148,234,
-105, 42,108,174, 5, 84,139,254,127, 20,121,219,233, 50,146, 13,245, 4,202,209,108,131,221,169, 87, 21,178, 90,102, 31,238, 1,
- 98,230,132, 56,114,239, 65,121, 42, 56,150,231, 69, 47, 93,245, 12,141,194,169,145,187,113,228, 70,205, 51, 21, 11,158,253,240,
-104,252,251,223, 46, 87,247,128,247,174,189,246, 20,206, 18,234,207, 17,214,177,191,143,118,189,180,191,187, 51, 26,220, 6,188,
- 17,231,255,172,230,139,138, 73,233, 9,132,189,149,237,232, 66, 71,172, 60,185, 74,177, 6,170,127, 89,207, 4,138, 37,156,139,
- 92,211, 50, 10, 31,164,215,106,212, 68, 81, 50, 59, 27,125, 97,243, 79, 55,218,193, 83, 6,104,237, 17,225, 66, 13,180,138, 7,
-144,144,193,231, 66,249, 22,103,109, 71,193, 96, 71, 73, 94,252,178,163,249, 82,121,181,211,240,194, 1, 38,103,113, 84,235, 28,
-220, 53, 27, 0, 59, 63, 85, 29,177,200,149,189,181,120,228,134,109,210, 96,148,172,165,244,128,157, 17,208,156,142,204,115,161,
-116,186,211,238,132,228,230,134, 27,128,183,149,189, 5, 88,172, 9, 80,151, 18,179, 1,199, 55, 93,216, 46, 13, 60,223, 89,234,
-115, 25, 78, 1, 83,197,159,234, 34,148,129,228, 48, 50,168,193,136,247,179, 53,142,181, 87, 16, 89,206,185,214,225,139,188,169,
-229,198, 4, 70,164,189, 71, 44,216,168,170,103, 69, 76, 55, 87, 38,156,241,155,238,208, 29,210,216,188, 41, 43, 60,255,177, 82,
- 63, 98,147,238,152,173,221,121,187,100,144,195, 41,114, 36, 72, 4, 64,205,125,143, 3, 33, 73,165, 17, 91,203, 45,150,194, 91,
-177, 81,142, 58,145,255, 52,196, 71, 4, 39, 86, 98, 27,219,127,237,177, 14, 88,255,175,147,120,150,221,246,222,170, 99,248,187,
-157, 75,153,233, 4, 39,204, 59,180,164,196,247,114, 88,129, 11,207,154, 28,165,128,241,250, 16,175,210,212,232, 64,120, 63, 20,
-203,104, 92,218,168, 20, 97, 15,123,145,204,150, 54,218,235, 74, 85, 35,206,122,162,157,160,166,120,138,128,133,110, 31,107,254,
-203,134,143, 79,190,253,254,215,231, 63,191,254,237,151,209,143,195,181,156,226,233,205,155, 23,175, 94, 62, 81,234,109,190,189,
- 45,101, 69,100,109,155,194,190,204,115, 93,150,182,223,237,203,255, 82,102,202, 57, 52,156, 84, 36,153,129, 57,209,210, 33, 71,
-246,114,200,114,217,210,131, 65, 44,185,224, 9,176, 12, 66, 17,217,140,255,222,156,185, 50, 28,249,213,189, 27,141,251,166, 61,
-126,250,221,197,255,244,231,219,247,183,255,188,139, 95,209,105,217, 25,106,237, 0, 92,116,159,220,121,243,121, 52, 57,118,187,
-146,133,179, 68, 88,168,140,224, 73,247,141, 24,236,217, 1,201,167, 43, 38,139,146, 89,229, 9,246, 32, 58,116, 79, 7,216,156,
- 56, 66, 7, 70,134,116, 97,135, 54,132, 40, 5, 17,189,241, 22, 77,238, 87,170,150,179,229,106, 11,218, 78,204,161, 0,218,149,
-186, 96,121,231, 68, 71,175,176,181,104,140,225,168,216,228, 57,126,157,121,153,185,174,250, 60,121,196,108, 94, 91,210,130, 70,
- 35, 92,114,112, 68, 74,165,219,117, 35,210, 26,218,229, 78,165, 15,108, 50,169, 6,241, 36, 83, 62, 19,244,114,195,225,167,211,
- 31, 5,163,193,116,128,246,104, 89,236, 63, 11,192,209,181,236,200, 81, 4,193,122,119, 85,245,204, 24,176,145,216, 59,178,100,
- 36,206,112,227, 4,223,128,196,135,242, 17,190, 89,226,108, 35, 14,230,130,108,207, 78,119,215,187,136,232,211, 30,118,102,119,
-212,147,149, 25,145,149, 25,161,255,248,253,245, 72,108, 67, 1,231, 94,165,185,215,169, 59, 62,199, 65,125,217, 58, 46, 52,235,
-164,133,143,213,164,126,116, 64, 20,227,230, 20, 91,241,154, 77,226,171, 30, 28,104, 47, 52,158, 12, 96,160, 7,242,175,196,169,
-136,205, 2,224, 24,181, 34,212,151,192, 29,160, 30,217,154,255,194,187, 29,142,176,245, 6,202, 81, 51, 49,142, 26, 56,154, 72,
-156,202,114, 46,165,112, 21, 79, 95, 56, 68, 96,167,187,152,210, 87, 48,120, 84,206,137,108, 32,134,151,180, 76, 88,240,252,198,
- 96,126,142,161,207, 29,103,129, 14, 11,156,240, 82,134,179,226, 9, 8,223, 1,246, 52,125, 61,175,220,232,137,160,197,177, 83,
- 18,214, 33,249,180,185,128,223,225,104,119,113,143,138,218, 12,125, 38, 68,113, 59,119, 60,240, 25,251,169,232,174,244,134,116,
-130,231,200,206, 13, 56, 42, 21,115, 11,161, 89, 77,224, 84, 11,197,175, 29,119,217, 5,215,101,135, 62, 37, 89,249,147, 34, 42,
-180,113,160,172, 64, 1, 48, 71, 25,195,151,105, 64,143,122, 31, 96,120,243, 46,231,210,104,147,245, 60,122, 70, 9,228,100, 86,
- 59, 10, 74,211,248, 92, 81,166,169,228, 92, 43,120,157,236,245,211, 6,172,143,144, 73,114, 30, 19, 85,209,226, 69,237,145,102,
-121,112,244,123, 83,120,115,235,195,228,253,213, 29, 24,210,100,246,160, 51,142,104,104,118,183,156,143, 0,244,167,243,119,158,
- 42,196,215, 79,223,250,237,239,237,186, 91, 90,202, 82,121,195,116, 10, 6, 80,160,127,107, 72,155,224,141, 0, 53, 15, 61, 56,
-193,220, 91,166, 64, 49, 7, 34, 19, 16,237,195, 28,121,126, 58,232, 71,202, 21,197, 97, 82,117, 33,112,171, 11,105, 42, 83,149,
- 45, 72,164, 44, 28,124,239, 40, 35,107,164,239,142, 2,183,205, 72,142,120,164, 37,206, 68, 4, 56, 50, 2, 96, 65,178, 43, 96,
-107, 38,115, 25,208,129, 87,125, 69, 81,148,176,178, 23, 50,217,244, 20,160,131,168,200, 57,151,160, 79,172, 58,170, 35, 7,151,
- 92, 68,192, 3, 55, 13,105, 78,161, 94,246,200,125,231,177, 40, 80,245,192,173,135, 43, 55, 15,169, 85,187,176,113,217,233, 84,
- 21,132,137,125,198,114,201,182, 39, 63, 42, 37, 77, 69,138, 64,188,107, 80,163, 0, 22, 72,250,100, 52,207, 46,156,147,131, 87,
- 89,160, 41,188, 19,159,107,115,236,246, 35,182, 94,250,180,170,145,181, 71, 12, 59, 46, 73, 45,213, 92, 4, 42, 24,128,177,136,
-158,198, 74, 26,132,237, 54,188,225, 13, 3, 64,128,163,239, 23, 98, 30, 33,162,253, 1, 98, 72, 29, 0, 64, 63, 54,209,108,225,
-117, 97,177,217, 27,132, 75,168,146, 68, 95,206,148, 40,143, 68,243, 56, 57,206, 41, 0,206,252,209, 36,107,241, 43,232, 24,197,
-129,245,130, 58,243,130,243,139,175,118,109, 57,248,232, 67,229, 36,176, 65,236, 46,206,171,201,254, 91,102,107,209,130,116, 14,
-133,195,241, 66,169,206,207, 60, 80,168, 41,162,138, 34,173, 41, 77,226,121,111, 63, 17,167,149,171,203,220, 98, 37,191, 85,226,
-153, 19, 91, 50,245, 78,253,107, 41,206, 65, 27,186,103,253, 87,103,227,119, 78, 17,106,226,149, 58,211,169,171,192, 44, 47,169,
-143, 12,236,129, 47,109,255,220,242,191,122, 62,212, 98,126,120,243,253, 47, 63,255,244,235,111, 79, 79,223, 29,226,120,187,253,
-243, 1,100, 72, 82, 43,165,141, 61,117,144, 15, 0, 26,252, 11,228,193, 47,188,214,221, 19,193, 39,199, 31,128,236,240, 50,203,
- 1, 10,110, 22,156, 94, 40,156,114, 25,136, 44,170,236,198,174,210, 53,244, 27,119,192,163,211,155,247,214,107, 35,231,203, 55,
-223,232,235,143,127,190, 43,127,125,124,239,227,176, 40,217,185, 91,127,161,201,180,238,235,145, 58,103,164,187, 8,204, 39,129,
-187, 87,102, 87, 11, 47, 75,153,190,245,215, 87, 16,201,101,139,210,111, 55, 47,166,187,161,118, 75,239,240,215,249,160,113, 24,
- 34, 74,121,180,211, 34, 94, 13,229,189,233, 58, 57,235,222,184, 95,111, 93,209, 81,103, 51, 61, 42,226,112, 61, 3,179,210, 9,
-167, 23, 96,160,217,238, 45,217,125,185, 35, 76,218, 71,241,176,115,213,160,235, 99, 84,250, 3, 36, 64,199,173,150, 34,104,134,
-212,193,101,186,190, 4,154,107,131, 35, 17,208, 87, 54,173,251,188,196, 83,193, 77,210, 32,243, 25,191,176,187,216, 1, 92,169,
-117,142,120,146, 59, 71,237, 19,105, 88,255, 95, 0,146,206,157,199,114, 34, 10,194,221,110,191,218,246,189, 51, 27, 32, 2, 66,
-132, 68, 8, 33, 63,133,128,191, 74, 70,182, 33, 9, 18, 1,210,174, 52, 66,176, 90,198,215, 99,187,237,126, 80,159, 55,157,192,
- 99, 95,187,207,169, 58,221, 85,229,126,249,249,167, 88,216, 42,221, 4, 73, 87,242, 75,155,135, 43, 19,113, 53,196,180, 6,213,
-172,170,121,136, 17,167,169, 47,209,160, 1, 99,118, 89, 23,127,107, 38, 24,190, 94,126, 55,137, 77,246,193, 8, 66,124, 9,188,
-240, 14,136,224,196, 8, 15,212,108,186,198,138,218,138,147,223, 78,176,163, 11, 79,140, 14,200,189,221,243,104,243, 99,175, 55,
-161, 79, 45, 83, 79,112, 74, 36, 75,201, 33,232, 87, 35,107, 46, 9,115,168,202,158,194, 56, 36,193,100,149,239, 20, 4, 50, 99,
-227,133,156, 84,124,134, 62,219,241,196,216, 58,223,142,211, 30, 29,135,189, 90, 68,120,253, 46, 60, 93, 18, 41,107,222,223,115,
- 88,128, 49,245, 78,126, 33,172, 83,173,238,109, 47,111,105,199,155,183, 34, 73,103, 86,121,106,214, 29,203, 87, 19,121, 74, 52,
- 37,167,120, 34,155,247, 76,232, 24,220,163,181, 76,130,164,229, 26, 29,160, 77,177,151,231, 19,154, 27,236,165, 90,102,244,171,
- 21,223, 96,224, 91, 46,129, 44, 39, 62, 73,250, 21,169,206,145,197,100,253,219,250, 82,226, 39, 49,241, 28,242, 26,150,253,120,
- 96, 17,217,116,230,211,182, 20, 17, 66,203,201, 37, 33,180,124,245, 22,183, 90, 85,129,253,200,203,140,220,184,187,208, 40,138,
- 93, 6,134,164, 86, 79,213,138, 54,114, 20,157, 44, 76,143, 84, 17, 78,186,191,181,239, 42,250,177,153,143,135,107,126,248,254,
-171,238,223, 15,175,233,184, 31,189, 40,188,189,129, 75,117,145, 5, 1,172,209, 47,241, 8,135,238,126,251,172, 85,137, 53,211,
-113,217,100,158,252, 86,236,182,111,171,243,171, 57, 25,188,136,190,179, 55,129, 64, 70,184,197, 48,105,187,118,186,130,168, 3,
-155,112,248, 57,232, 71, 36,233,104, 17,184,193, 97,215,159, 43,127, 16,201, 18,106,241,181,157, 84,108,196,116, 6,130, 13,213,
- 91, 84,245,242,203,149,106, 87,217,133,168,177,166, 82, 29,209,215,164, 14, 36,138, 41,144,130,249, 13, 26, 82,108,123,252,165,
-138,112,194,203,174,187,199,170,231, 80,242,116, 51,238,222,228,213,213, 99,177,207,156,102,246, 73,168,249,178,169,232,155, 49,
-180, 71,237,180,200,171, 41,185,155, 64, 89,231,138, 19, 20,211,141,139, 6,162, 55,102,243, 21, 23, 9, 87,103, 20,159,195, 64,
-204,151,119, 56,173,185,169, 18, 46, 3,173,232, 94, 56,172,101,104,184,131,101, 34,162,187,111,153, 61, 98, 99, 71,216,167, 94,
- 76, 79,252, 32,166, 63, 14,219, 38,213,216,234, 36, 88, 54,138,245,218, 78, 87, 13, 86, 80,174,230, 9, 69, 45, 84,185, 98,155,
- 46,151,206,194, 48, 71, 64,190,191, 57, 4,231, 13,147, 62,164,167,194, 27, 66,102, 87,112, 64,205, 55,166, 38,134, 90, 76,215,
-197, 33, 30,231, 44,173, 39,206,245,243,123,133,118,224, 56,175, 80,135,106,141,254,195, 88,167,242, 84,244,165,106,209, 68,220,
- 45, 27, 4, 14, 15,110, 14, 35, 33, 82,183,176, 43, 22,243, 33, 32, 99, 37, 64, 40,109,142,125,165, 22,127,107, 55, 24, 80,205,
-127, 36, 90,170,204,208, 1, 60, 59, 8,230, 98,110,122,168,136,180,221, 16, 93, 71,136,245,121, 33,161,254,178, 17, 19,100,153,
-243,254,154,226,223,165,252,149,242,199,248,242, 71,250,252,143, 33,194,141,141, 28, 45,239,140, 97, 92,196,231, 82,176, 70, 72,
-181, 78, 2, 10,251,108,123,180, 74,237,241,234, 75,135, 56,168, 62, 73,122,103,180,110,219,208, 10,136, 85,254,185, 52,109, 60,
- 90,140,239,111,241, 48,183,170,249,218,213,171, 29,223,165,167,239,190,237,239, 63,254,250, 62,252,246,231,239,227, 29,121, 33,
-209, 99,117,179,152,177,126, 13,219,115, 74, 99,119,189,195,122, 86,197, 10,101,221,186,206,171,208,168,130, 91,162,183,106,204,
-233,206,179, 31, 38,116,168, 28, 34,253, 38,218,173,237,124, 87,183,162, 81,108,234,244, 19,163, 71,110,105,173,124, 55,179,135,
-172,183,236, 59,219,224,199, 80, 89,181,145,165,110, 67, 74,237,242, 37, 56, 52,182, 15,162,174,237,149, 35,233,231,116,246,162,
-219,156,223,167, 72,111,198, 99,118, 34,252, 22,146, 26, 98, 22, 58, 24, 14,180,130,250, 48,142, 42,207,103,231, 65,131,122, 23,
- 51,116,151,227, 78,111, 64,116, 21, 26,117,110, 17,231,172,135, 17,251,216, 76,192, 53, 90,173,217, 68,127,154,193,196,255, 5,
- 32,233,108,150,227,182,129, 32, 76, 0, 36, 0, 46,247, 71,178,236,139, 83,121, 2, 95,252, 40, 46,191,114, 78,121,135, 28,226,
-147, 43,149,131,203, 43, 45, 73, 16, 63,116,127,244, 69, 23,105,181, 36, 1,204,116,115,102,186,221,215, 47,159, 61, 86,122,107,
-159,117, 83,218,244, 93,138,227, 92, 30,104, 1, 91, 98, 82, 62,227,116,163,239,245,190,207,188, 71,218, 19, 97, 45, 14, 77, 57,
-177,155, 45, 31,113,230, 44,228,164,173,227, 73,245,186,182,164,123,228,170, 90,191, 9,252,235,252, 50,180,234, 86,179,137, 72,
-139, 67,221,177,228, 65,238,101, 96,203,139, 83,107, 37, 17,211, 57,149,252, 64, 58, 89, 28,147, 87, 41,190,241,202,255, 98,181,
-164,214, 8,158,104, 9,231,116, 14, 6,253,201,216, 7, 42,153, 74,249,110,192,111, 74, 89, 20,235, 36,220,144,123,161,183,172,
-157,101,235,165,235, 55, 5,254, 29, 85, 95,180,171,244, 32, 22, 55,156,186,137, 65,162,140,101, 98,221,205,219,208, 29, 98, 16,
- 59, 86,244,250, 21,218,182,136, 36,137, 64, 41,197, 4, 18, 1, 33, 92,176,136,236,184,185, 34,108, 67,183, 7, 77,205,104,188,
- 13, 74, 92,126, 78,138,101, 51,214,221,138,222,150,241, 60,226,153, 33,141,193, 99,109, 10,133, 46, 26, 29, 35,211,144, 89, 76,
-149, 89, 75,197, 96, 94,197, 27, 38, 64, 30,229,129,231,168,155, 25,189, 58, 28,130,149,189,151,215,130,233, 76,115,249,205,107,
-133, 59,177, 43, 44, 68,116, 87,162,141,138,156,233,170,163,167,147,104,211,233,238,238,102, 73,137, 19,131,116,173,190, 67, 16,
- 93, 28,102,161,171, 73,185,186,156,152, 66,255,244,199,203,203,247,255,214,107, 54,215,161,191,184,168, 43, 75,169,155,203,221,
-208, 56, 92, 82,135, 82,120, 20, 43,183,126,196, 12, 74, 87,167,208,154,114, 19,113, 94,223, 0,130, 76, 80, 11,138, 8, 55,237,
- 98,180,205, 15, 48,249, 13,213,139, 34,194,166,127, 35,222,165,101,243, 2,180,165, 49, 48, 52, 97,169, 45,236,181, 62,161, 83,
-203,235,108,218,244,178, 83,230,111,138, 27, 67,152,178, 78,111,137, 97,242,132,142,116, 60,181,253, 92, 4,101,246,154, 55,252,
- 77,135, 54,217,241, 55,124, 59, 17,207,152,123,125,182, 35, 54, 29, 17, 31, 19,234,253,163, 32, 22, 78, 88,169,226,155,215, 2,
-233, 8, 37,223,126,232,168,124, 22,191,122, 61,147, 81,164, 43, 68,166, 50, 5,243,170,125,191,225, 53,213,159,143,241, 89, 61,
- 46,157,171, 78,208,191, 20, 55, 46,103,101, 14, 51,210, 32,213,150,158, 94,210,158, 63,108,238, 62,236,227,245, 54,222,194,233,
-233, 67,120,121, 14,215,209, 93,111,211,245, 73,233, 64, 76, 94,123,145, 10,114,243,191,117,224, 42,182,126,250, 49,148,163,167,
-240,176, 50,162,148, 16,244, 53,198,141,130, 25,205, 7, 43, 50, 41,178, 23, 68, 68,142,114,166, 18,204, 32, 40,188, 29, 85,123,
-139, 28, 63,111, 44,168,222, 42, 28,193, 35,116,240,132,198,208,117,142,212, 64, 4, 45, 68,145,232,163,230,145,244,207,149,134,
-141,196, 56,170,115, 76,109,116, 13,165, 79,151, 34, 18, 55, 90, 34,241, 53, 90, 50,240, 90,195,232, 72, 11,188,224, 99,213,149,
-182, 10,150, 20,165,111,139,205, 17,106,130,173,189,118, 64,148,173,213, 21,251, 74,186,238, 16, 30, 65, 11,117, 63,204, 37,186,
-112, 76,145, 50, 27,181,211, 91,185,233,160,147,232,205,161, 76, 67, 97, 84,156, 78,105, 33,125,107,255,127,239, 30, 15,228, 91,
-248, 28,126,235, 14, 7,245,154, 93,163,194,132, 51,170,160,108,199,132, 59, 70,200,126,137,218,133,148,147,152, 77,212,226,105,
-219, 49,153, 92,118, 95,105,137,208,181, 36,175,100, 48, 77, 86,129, 20,125,242,119,125,155,194,243,159, 47,239, 63,126,250,251,
- 95,251,215,183,127,234,101, 14,195, 77, 39,196, 86,131, 12,172, 0,119, 17,231, 84, 44, 9,249,222,253,180,200,123,220, 60,202,
-117,140,121, 12, 27, 43,144,243,136, 67,117, 54,109, 26,199, 82,131,232,217,185,215, 18, 46,151,119, 31,252,134,244,163, 27,247,
-184,123, 37,195, 61, 78, 67,217,204, 20, 79,121,143, 12, 33, 42,225,104, 29, 16,184, 19, 96, 13,152, 81,109,117,201,139, 82,231,
-253, 21,141,168, 88,170,136,243,207,136,191, 74,223,175, 43,109, 15, 24,190, 34, 62, 91,211, 91,232, 7, 93, 98,195,140, 32,107,
- 99,204,140, 96, 48,180, 62,186,100,194,227,135,224,212, 70, 89, 83,201, 46, 85, 20,131, 78,194, 10,173, 42, 66,108,172, 6, 45,
-230, 5,235,235,168,173, 5,209, 7,185,253, 18,128,164, 43, 73,146,219, 6,130, 0,136,141, 91,183, 70, 91, 40, 66, 47,240,255,
- 95,160,147,255, 96, 71,248, 5,210,168, 23,130, 13, 98,117, 38,117,159, 24,178, 9, 84, 85, 38, 80,149,169,229,196, 43,150, 94,
- 56,240, 63,164,157, 38,207, 7,187, 26,245,138, 69,164,115,143,223,232, 95,163, 23,188, 82, 53, 29, 9,236,172,230,130,224,250,
- 24, 57,182, 73,248,208, 79,179,229,172,202,155, 19,224,132,207,207,222, 37, 0,151,212, 52,143,171, 90, 2,198,100, 3, 78, 70,
- 56, 33, 78,207, 70, 41,255, 42, 9,216, 33, 61,144,113,197,113,218, 92, 1,181,153,167, 8,159, 80,140,142, 72,127, 36,170, 12,
- 80,222, 21, 64,198, 76,254,248, 45,190,208,157,112, 38, 71,168, 3, 94,169, 2, 54,239,154,206,212, 6,101,208,227,201,196,147,
-207,146,157, 13, 78,216, 22,214,144,131, 3, 68, 89, 77,222,126,246,111,174,211,106, 51,236,175,202,134,140, 44, 95,187, 87,147,
-227,132, 52, 69,217,182, 76, 69,146,196, 3,152, 33,113,232,159, 53,245,102, 16,102,187, 46,227,217,161, 81,129,166,244, 31, 3,
- 16,172, 39,112,184,167,226,236, 82, 94, 43,240,188,236,247, 24,157,208, 43, 85,238,129, 98,111, 28,249,198,102,119, 57,109, 19,
-224,148, 42, 63,123, 15,128,108,248,207,168,240,219, 81,172, 0, 17,149, 37,108, 90, 55,159,233,142, 7, 26,117, 96,231, 63,115,
-245,160,187,210, 27, 58, 74, 35, 26,194,152, 0,139,221, 47,213, 22,222,178, 58, 69,157,230, 60,139,247, 39,167,128,144,212, 99,
-214, 62,123,132,225,160, 39,218,190,140, 77,220,187,100, 71,121, 41, 7,192,110,101,127,123, 21,120,166,161,202,125,201, 71,147,
- 1,107, 69, 43, 6,171,245,229, 14,110,213, 65, 12,217,245, 69,173,161, 30, 35,225, 63,202, 80, 43,242,126, 12, 67, 86, 35,216,
-124, 43, 15,132,195,131,134, 88,198,210,221, 14, 36,242,134,132, 84,179,213, 3, 62, 46,213,210,152,199,232, 79,205,121,111, 47,
- 98, 50,171, 3,255,141, 8, 77, 94, 17, 54, 85, 70,233, 27, 72,179,220,102, 26,165,202,205, 35,249,181, 81,176,219,125, 1,128,
-194,183,115, 44,171,188,187,199,111,173,156,153, 7, 75, 90,128,106, 80, 41,213, 65,147,132, 33, 30,150,154,191, 88, 69, 47,169,
- 4,101, 19,133, 4,129, 3,172, 96,182, 3, 39,178,185, 77,107,226,124, 2,224, 56, 24,131,230,222, 19,129,182, 41,216,131, 52,
-129,147, 34,142,169, 80,192, 87,205,197,143,181, 63, 40,178,132,236,227,102,201,198,185,158,121,242, 88,205,135,197, 12, 87, 59,
-139,105,124,123, 19,139,192, 14, 21,212, 88,113,191,187, 8, 55, 82,106,188,129,141, 40, 80,113,249,104,196,119,201, 57, 29,117,
- 71, 89, 22,225,104,113,217, 31,247, 70, 93,220,152,193, 22,217, 54,237,197,190, 35,175,171, 36,139,237, 94, 35,180,117,137, 94,
-216, 64,144,148,228, 49, 94,176,101,106,189, 42,251,206, 73, 8,118,100,139,115, 24, 63,247,165, 82, 50, 41,102,158, 96,174,168,
-252, 40, 29,150,206,144, 11, 88, 5, 22, 32, 21, 30, 52,153,254, 16,154,252,198,244, 40, 65,233,217,141,144,138,154, 14,185,179,
- 31,134,198, 21,181, 32, 47, 23,142,188, 19, 22, 82,191, 39,233,188,179,117,204, 44,166,238, 5,105,129,200,177,160, 32,157,224,
- 58, 3,181, 9, 5,200, 56,122,142, 0,249,131,102, 33,150,119, 42, 84,246,226,105,178,227, 22,153, 73, 40, 0, 10, 68,212,212,
- 30,234,211,121,224,211,196,251,141,214,201,129, 77, 12,188,246, 58,199, 13, 21, 5,243, 58,173,167,176, 34,149,207,162,231,143,
-175,244,197,109,167,172,240,175, 62, 77, 54, 9,114, 42,225,212,150,183,193,210,155, 14,127, 15,176, 57, 37,124, 13, 61, 92, 42,
-165, 84,198, 17, 97,102,123,188, 78,151,207,211, 95,127,255, 99,127,252,251, 95,247,245, 90,222,128, 66, 35, 98, 17,123, 43, 29,
-106,166,229, 28,147, 14,176, 14, 80,255, 70,171,174,151, 49,149, 77,239,105, 48,115,121, 77, 38,189,166, 15, 62, 93, 81,218,170,
- 86, 22,159, 51,207, 40, 67,222,120,247,196,130, 82, 31,117,104, 26, 47,252,213, 15,248, 37,151,218,143,189,158, 42, 68, 61,186,
-248,122, 56, 84,175,228, 90, 91, 57,138,170,144, 36, 62, 77,110,167,250,231,227,194,118, 86,196,126, 3,180,156,195,158,244,216,
-118,112, 37,145, 34,121, 97, 79, 50,176, 93, 18,196,181,169, 81,134,199, 48,212, 16,230,105, 76, 73,119, 25, 51,217,245, 81,197,
-156,236, 94,176, 55,196,246,172,107,161,236, 76,178,121, 24, 98, 10,158, 19,243, 52, 6, 25,182, 87, 86,128, 40, 40,153,181,255,
- 47, 0, 73, 87,178,219,198, 17, 5,123,122,153,158,141,155, 69,217,200, 33,129,129, 32, 31,144,255,191,249, 11,146, 75, 2,228,
-224, 0, 57, 88, 14, 44, 90,228,144,179,244,158,170,201, 81, 18, 8,177,123,222,188, 87,245,182,210, 7,238,250,225, 38, 78, 93,
- 69,219,104,183, 20, 86, 69,159,218, 85, 44, 8,176,205,154, 35,103, 37, 82,219, 53, 25, 52,107, 31,173, 89,244,163, 94,224, 38,
- 58, 54,148, 11,139, 15,110, 99,138,197,214,218,168,107,165,224,165,251, 33,195,145,209,187,100,160,100,184,119, 41, 57, 79,120,
-168,139, 95, 88,190,220,122, 16, 57, 83, 77, 17,172,219,228,213, 41,198,165,112, 44, 88,159,220,169, 24,199,109, 30, 51,144,161,
-231,134, 16,170, 32,226,212, 53, 40, 56,240,239, 37,102, 48, 2, 66,130,123,238,218,192,202,253,169, 44, 56, 37, 2, 42,128, 63,
- 76, 71, 92, 74,104,101,106, 17, 89, 92,253, 20,214,111,177,223,165,120,179,176, 91, 24,123,218,129, 35,205, 75, 3,239,193,129,
-166,218,113,252,179,241,184,152, 57, 27,174,117, 97,195, 96,222, 58, 42,153,127,100, 77, 45,192,244,170, 93, 53,174,226, 88, 52,
- 46, 72,139, 13,195,114, 5, 98,172, 41, 39, 66,105,172, 38,137,166, 1, 40,149,234,123, 98, 25,172,224, 42,185,106, 59, 52, 12,
- 19, 19, 76,195, 49, 80,233,217,133,134,115,175,125,152, 47, 75,184, 42, 49,192, 66,189, 11,111,235, 29,247, 73,190, 76,244,173,
-217,206,123,139,240, 70, 84,241, 54, 41, 61,252, 80, 7,127,176,142,195,200,176,128,200, 69,150, 76,100, 11,132,107,143,235,192,
-219,187,122,248,239,210,107, 19, 57,228, 38, 17,184, 76,185,135,160,147,189,178,148,119,207,106, 8,158,237,191,227, 36,106,149,
-159, 17,179,180,222,202,184,234,182,227, 76, 29,243,118,149,156, 46,161,117,248, 10,242,206, 74,165,160,210, 41,252,128, 76,211,
-119,207,242, 13, 16, 97,102,151,158,136, 98,157,248, 29,244,187, 64, 29,163,204,156, 30,130, 97, 94,104,139, 65,108, 49, 32,193,
-223,178, 21,160,162, 6,132, 98,163,237, 67,227, 45, 51, 92, 27,144, 41, 40,138,151,139,107,255,140,230,232,109, 2,142,222,213,
-228, 12,120, 2,184, 9,219,129,101,217, 61,255, 78, 45,243, 28,129, 81,249,111,224,186, 58,188, 45,199, 62, 49,123,147, 56,166,
- 18, 17,217,225,122,130,236,106,144, 51,123,140, 34,239,148,179,121, 23,155,224, 40, 37, 5, 70,150, 1,133, 50,120,140,169,216,
- 25,239, 17,245,117,182,212, 78, 92,149,115,149,164, 86, 11, 28,188,172, 70,211, 29,247,125, 28, 14,189,218,127,164,147,226,120,
- 81,251,237,229,245,183,223,221,159, 47,243, 95,255,252,241,229,235, 69,172,175,240,207,215, 47,234,190, 51,128,147,167,168, 58,
-235,250,214,244,231,253,243,241,221,241,252,254,167,131,249,245,135,247, 31,127,105,135,167, 29, 51, 27,164, 69, 15, 65,133,221,
- 34,220, 87, 74, 49, 93,129, 94,118, 0,142,169,165,237,120,209,112,239, 90,101, 15,176,106, 91,169,254,131,148,123,196, 76, 1,
- 32, 44, 7,214,205, 56, 76, 53,176, 56,167, 71,208,106, 66,104,144,147,252,255, 46,207, 64, 17, 28,254, 24,105,188, 99, 73,235,
-231,233, 58,222,166,171,121,243, 9,134, 78,231,137,167, 54,212,116,220,192, 48,160, 16,153, 57,209, 85,178, 91,190,202, 27, 25,
-173, 99,203, 22, 26, 46,202,187,114, 70,196, 90,207, 94,254,150, 37,119,255,240,218, 20,202, 42, 45, 56,173, 93,250,104, 94, 57,
- 10, 11,206, 47,210,150, 64,225,226,188, 73,187, 1,116, 95, 80,222,195, 37,124, 97,177,165, 87,198,106, 91, 67, 20, 84,151, 17,
-106,210, 70,151,139,107,168,167,133, 96, 3,183, 36, 19,128, 39,184, 60,224, 62, 5,241,188,133, 47,214, 51, 19,144,176,165,212,
- 71, 93,171,227,155,117,173, 94, 77,233, 99,181, 14,176,249, 20,134, 34,199, 26,129, 5,118, 89, 53,170, 57,159,206, 63,255,248,
-247,203,135, 79,159,255, 21,213,250, 12, 67, 81,253, 21,193,175, 15,126, 65, 4, 79, 64,119,243, 29,158, 24, 55,161,128,142, 17,
- 54,135,164, 22, 68, 97,205,209,135,196,199, 79,130,252, 8,100, 80, 82,135,116,151,122, 72, 45, 14,100,116,107, 30,210, 29,217,
- 88,107,135, 98, 39,233, 18,115,163,133, 75, 66,113,108,181,184, 56,216, 16, 42, 4, 4, 95, 44, 47,109,153, 23,171,224,236,114,
- 21,184,251,164, 22, 19, 32, 54, 69, 11,185, 79, 19,176, 99,162,122,182,111,124,179,206, 32, 2, 44,140, 55, 75,192,137, 91,165,
-173, 80,183, 10, 16, 20,191,142,102,214, 14,216,149,212, 37, 61, 74, 59,143, 54,229,144,122, 0,121,202,239,140,204,184, 3,161,
-117,220, 94, 61, 71,142, 10,103, 49,172,182,126,228,187,116,203,185,252, 39, 0, 71,215,182, 35, 55, 17, 68,251,222,109,123,238,
-203,102, 73, 8, 36, 18, 72,252,255, 47,240, 3, 8, 9,133,135, 60,128,208, 66,200, 64,118, 61, 59,118,187,187,221, 23, 78,205,
-195,104,164,209,140,173, 30,187, 78,157,211,174, 58, 5,141,106,107, 39, 0,187, 26,137,120, 73, 55, 35,152,164,155,141,151,100,
- 16, 60,214, 60, 23, 48,132, 69,227,223, 4,169,155,109,160,185,105,173,163, 73,118, 0, 68,219,175,117, 1, 91,222,186, 8,109,
-122,220,117,118, 5, 77, 51,118,126,169,167,172,249,110, 41,214,123, 37,201,168, 48, 0,189,243, 43,166, 3,245,234, 24,196,105,
- 40,252, 11,195,133,220,176,176, 6,145,233, 25,154,156, 82, 27,104, 70, 14,141, 28, 52,213, 43, 50,116, 3,164,229, 91, 39, 13,
-178,174, 82,248,105, 40,113,147, 9,160,188,220,151,177,118, 6,188, 0,185, 11,217, 5, 49, 30, 72, 4, 48, 0, 72, 15, 52,127,
-209,113, 22, 84, 33,115,168, 98, 0,255, 38,227,175,237,178, 82,171, 42, 91,237, 80,171,154,200,145,152,201, 14,236,194, 65,218,
-151,220, 22,165,104, 47,151,204,151, 64, 2,161,207,253,130, 43, 82, 54,139,155,174, 12,164, 98,106,234, 30, 76,207,130,225, 34,
- 69,145, 13,147, 27, 59,101,242,101, 87, 15,130, 13,142, 50,241, 68,181, 44,100,175, 13,189,210, 46,139,225,235, 76, 69,247,185,
-229, 18,218,244, 18, 20, 78, 5, 86,180,232,108,163,240,136,121,233,129,174, 59,220,242, 98,156,178,166,225, 23, 96, 70,235,148,
-130, 12,134,187, 78,180, 67,178, 88,242,228,231,141, 90,175,182,172,163, 2,106, 67,168,246,154,140,155,201, 33,104, 72,228,128,
-102,100, 20,108, 57,185,250,185, 82,109,169,109, 39,211, 23, 8, 55,139, 48, 16,243, 53,127,126,122,254,177,128,252,144,107,111,
-164, 89,165,162,223,201, 92,105,184,138, 88, 52,109,174,234,128,243, 47, 61, 67, 36,210, 80, 97, 41,210,192,247, 65, 92,205, 26,
-183,194, 45,141,199,188,112,114,116, 32,127,133, 29,162,160,109,207,105, 54, 6,228,128,234,206,122,106,177,224, 58,237, 25,185,
-151, 35,142, 32, 9, 0,101,121,177, 88, 49,205,125, 48, 32,173, 34,132, 66,206,125,132,231, 38,105,234,145,147, 8,187, 64, 13,
- 2,212, 9, 54,103, 34,130, 23, 14,149, 69,207, 33, 54, 26,242,142,188,187,152, 70,170,217,128,242, 12,174, 3, 79, 2, 17,137,
- 76,116, 86,166, 99,237, 38, 97,168, 93, 60,107, 83, 45,245, 69, 67,105, 27, 7,162, 64,205,103,212,232, 38,185,234,212, 6, 7,
- 72, 61,200,103, 79,128, 2,145, 27,185,113,197,104,139,163, 88,182, 31,246, 95,245,224,197,223, 49,254,245,244,105,250, 48, 94,
-255,250, 61, 63,254,246,243, 47, 31,211,167,165,254, 59,254,173, 51,114,160,109, 71,223,119,198,245, 22, 75, 51,239,248,107,219,
- 81,245, 56, 80, 38,241,151,194,211,121, 42,143, 23,171,254, 68, 56,181, 39,149,143,114,216,222,189,213,252,237, 67,247,230,245,
-112,255, 48, 32,245,222,157, 78,135,227,129,251, 56,236,128,127,102,127, 0, 79, 50,221,173, 60, 25, 23,109,126, 58,215,106,114,
-220,156, 47,208,248,230,146,174,235, 37,125,241, 35,209,101,255,232, 95,216,127, 79,126,202,237,234,169,218, 54,202, 84,195, 80,
-236,106,120, 80,245,160,202,242,195, 55,253,241,180,253,254,253,221,221,240,254,219,119, 33,253, 51,142,243, 71, 63, 94,145,119,
-235,137,175,163, 97,146, 12,111, 86, 13, 38, 97, 57,248, 70, 5, 67,195, 29, 66,227, 29,245, 85,209,128,112, 23, 37,209, 87,106,
- 97, 21,120, 93,215,220, 21, 8,146,122,146,181,111,194,173, 64, 48,113, 81,228,120, 69, 54,178,144,217,237, 70,194, 20,201, 4,
- 21,193,176,169, 51, 59,208,118, 25,211, 81,220, 4, 40, 20, 29,203,184,113, 17,155, 27,230,102, 44, 52,129, 71, 1, 85,174, 28,
- 12,132, 71,234,192,194,161,146, 33, 83, 79, 33, 45, 4,116, 69,148, 84, 7,217,120,164, 98,140,166,143, 60, 42,160, 4,153, 94,
-155,173, 38,207, 63,160,144, 4,129, 20,194,241,221,158,223,191,122,248,245,143, 55, 63,125, 56, 79,246, 60,108,182, 84,148,128,
-127, 52, 33, 74,101,243,246,185, 35, 75,126, 42, 69,151,253,228,249,192,150,117, 91,207,161,211,157,219,250,136, 91,141,198, 82,
-145,103,133, 82, 67,195,155, 67, 30, 57, 21,136, 84,196,151,166,249,244,197, 88,218,113,112, 34,117, 84,168, 4,149,123,191,154,
- 66,110, 37, 88,136,238,165,216,164, 30, 10, 58, 38, 26, 2, 82,188,162,162,228, 38,161,111,157, 78, 81, 83, 1,113,245,218, 11,
- 41,157,199,138, 37,247,161,172,126,148, 14,208, 85, 39, 61, 38, 86, 99,235,240, 93, 64, 16, 68,161,207, 17,113,243,210,158, 91,
-181, 42,139,104,102, 92, 18,124,170,131,148, 12,231, 0,119,203,185, 34,113, 83,217,104, 91,235,101,109,131, 0,244, 32,127, 36,
- 80,209,231,219, 86,234,148,255, 23,128,164,107,217,117,164,134,130,182,219,110,187,159, 73,110,224, 10, 33, 64,108,216, 32,205,
-138, 37,252, 58, 11,118, 8,205, 15,160, 1,193, 8,105,196,157,153,123, 39,175,238,118,251,209,166, 42,236,162, 36,138,210,109,
-159,115,170,220,167,234,104, 95,183,126,210,141,189,196,240,105, 45,219, 32,129,103, 28,104,228,160,228,181, 10, 39,154,163,201,
- 26,213,109,197, 77,207, 7,172, 1, 46, 88,223,181,121,236,179,172, 0,229, 34,245, 71,118,232,214, 92,102, 49, 13, 26, 1,220,
-230, 3,170,206,162, 22,132, 41, 37,116,244, 82,173, 59,127, 67, 73,247, 32,124,242,127, 48,241,108,122,167,129,184,172, 73,171,
-178,108, 51,156,125,146, 61,229,207,199, 69,214, 10,160, 23, 20,177, 2, 1, 55, 13,170, 58,117, 33,116,156, 72,165,119, 64,252,
-160, 65, 50,222,248, 16, 94, 25,233,103,105,145, 46, 15,211, 42,155,109,176,160, 50,168, 63,203, 89, 2,143,232,170,151,231,133,
-210,199, 29,184, 98,213, 77,245,199, 80,215,253,166,183, 75, 20, 95,138,246,202, 14,164, 9,137,173, 71, 26,110, 80, 19,177, 26,
-128,209,156,247,117, 3,242,246, 60, 78, 65,198, 19,115, 56,226,170,241, 21,147, 22,100, 82,182, 57,224, 83,145, 26,161,123,186,
- 51, 97,179,191,188,199,230,173,233, 91, 98,124, 7, 72,176, 97, 15, 1,111,110,145,174, 27,216,237,105, 38,217, 86, 46,225,125,
-141,229,205,109, 90,159,154, 43, 24,234,176,173, 87,118,227, 39,185,200,123,141,107,243,109, 74,123,100, 96,176,179,230, 60,209,
-137, 19,127,101, 19,102,222, 64,130,162,141, 26,228,124,126,113,159, 81, 45,180,229, 75, 86,124, 26,166, 74, 42,211, 57,247,216,
-160, 72,199,177,154,114,226,108, 68,246,130,235, 24, 55,103, 1,133,128, 44, 30,212,252,177,205,213, 52,170,157, 81, 51,251, 9,
- 19,207, 21, 81,153,244,138,139,118,183, 2,128, 49,131, 69,176,121,175,226,172,143,194, 31,144, 52, 61,204,247,217,172,165,220,
- 18,152,210,210,108, 23,205, 30,204, 77,175,142,110,191, 91, 61,227,170, 68, 2,216,174, 45,187, 71, 10, 16, 25, 0,160, 6,228,
- 2, 4, 84,106,176,124,152,161,228, 49, 91, 90,186,219, 37, 58,124, 89, 2,255,128, 62,182, 21,237, 53,171,132, 68, 6, 24, 2,
- 12, 59, 29,104,122,125, 1,255,198,122, 24,206,103,161, 86,181, 74,118,203, 76,181,172,254, 73, 87,186,152,171,112,200, 33,202,
-152,154, 6, 87, 74,183, 1,176, 13, 59,182, 7,143,226,145,183,241, 74,130,214, 74,227,157, 70,180,116,105, 16,195,126,236,143,
-118,208, 35, 80, 76,143,212,147,188, 63,133,229,215, 63,222,255,242,231,167,183,191,191,126,247,247,245, 36,238,120, 42,205, 85,
- 99, 59,167,187,241,110,236, 29,187,104, 53, 48, 81, 10,105,223, 37, 53,234,228, 13, 21,204,123, 61, 7,179, 7,129, 71, 68,211,
-194,162,202,114, 87,210,226,251,146,162,127, 51,133,167,191, 78,191,129,219,186,156,159, 77,103, 66,101, 76,252, 34, 30,133, 84,
-139,182, 59,189,142,139, 61, 1, 46,136, 21,101,227,124,219,123,142,152,184,116,132, 92,129,246, 92,243,213, 87,157,232,116,190,
- 90, 96,244,198,234,177, 88,193,209, 23, 0,152, 2,244,117,229,112,150, 11, 39,198,172,207,239,252,203,155,234,248,186,195,186,
-253,248,195,247, 63,125,247,237,231,223, 60, 60,126,157,230, 15,111, 95,206, 79, 82,242,190,243,164, 1,249, 92,183,177,189, 75,
- 88,214,137,150,145,236, 49,194, 7,181,138, 85,185, 82,126, 16, 43,111, 26, 58,167,134, 80, 76, 91,230,147,104, 26, 14,229, 48,
- 36, 29, 89,219, 26,247, 90,113,196, 31,245,223,160,120,114, 1,203, 88,178, 26,105,211,215,114,208, 1,157, 66,103, 85,144,125,
-234,187,200,196, 4,145,188, 90,169,146,189, 51, 83, 1, 32,148, 17,220, 8, 16, 33,211,140,229, 51, 52,108,163, 61,167,116,110,
- 80,168, 49,236,217,195, 90,187,240,168, 76,160, 64, 96,189,173,226,223,100,199, 58,205, 82, 13,109, 26,183,118,175,190,122,124,
-248,103,123,245,243,243,229, 54,222, 90, 18, 57,132,165, 59, 45,192,207, 35,211, 68, 45,196,125, 74, 48,248,221,161, 79,190,196,
-164, 76,180, 14, 52, 83, 7,191, 32,220, 93,187, 77,161, 71,176, 26,197, 9,102,197,134,187,108, 73,217,193,178, 61,136, 98, 49,
-182,128,182,131, 14, 40,108,128,134,147,202,224,159,101, 86,166, 81, 86, 69,225, 51,181,248, 31, 68,222,173, 93, 97,175,241, 74,
-191, 72,113, 45, 28, 92, 22,136, 56,242,173, 45, 53, 94, 76, 83,244,142,246,142, 77,109,178,137,230,185,246, 61,194,165,172,105,
- 91,149,199, 13, 11,148, 19, 86, 79, 78,237, 3, 29, 11,193,216, 57,236, 25,181,177, 84,151, 21,168, 5, 25,157,174,218, 88,148,
- 76, 49,190,224, 41,131,147,147, 37, 57,116,243,172,228,150, 15,209,129, 22, 92,245,127, 2,112,116, 45,203,113, 20, 65,176,167,
-159,243,218, 93, 45,146,176,130, 27, 23, 2, 56,249, 3,252,235,220, 57, 16, 56,194,192, 1,130, 8, 28, 1, 7,217,152,181,102,
-118, 94,221,211, 15, 50,247,168,203, 72,234,174,174,202,236,174,202, 68,105, 3, 65,198, 31,138,227,244,136,124, 26,229, 78, 13,
-160,117, 91,239,123, 42,220, 0,195, 94,103,124, 5, 24, 25, 21,105,232, 35,170,103,125,177,190, 54,170,183,167, 67, 1,127,204,
-173,161, 69, 70,131, 18, 61, 27,123,166,217,237, 52,115,248, 61, 82,199,115, 28,217,220,109, 58,160, 55,111,241,249, 13,144, 61,
-249, 80,153, 74,182,170,169,203,117, 80,233,190, 85, 99, 0,223, 14,150, 67, 65, 6,219,179,163, 20, 33,111,128,138, 86,149, 43,
- 84, 67,186,230,210,121,138,137,172,247,149,186,122,255,119,108,187,163,241, 65, 31,241,123, 59,195, 44, 97, 55, 4,207, 32,105,
-137,216, 4, 42, 41,105,117, 9,251,153,106,169,163, 46,192, 55,221, 2,212, 29,102, 96,173,147,106, 61,240,189, 7, 12,222,250,
- 10,204, 10,140,204,239, 13,219,228,138, 94, 5,149,184,236, 85, 30,232,162, 73,138,161,139, 34,237, 64,125, 85, 20, 25,166,186,
-152, 64, 46,194,145,138,238, 54,136, 48, 42,113,226,165, 65, 86, 29,246,108,165,130, 27, 39,153,132,195,105,151,145, 66,205,168,
-255,253, 26, 71,134,244, 62,173,124,108,243,195, 54,128,212, 76, 7,123,229, 32,169,103, 39, 61,200,136,103,227,142,231,125,153,
- 90,123,187,233,170, 3,109,205,235,121,210, 99,141,120, 81, 93,236,233,143,238,194,178,183,101,163,129, 38,142, 88,139, 8,181,
-128, 54,116, 51,228,212,106,166,229, 44, 7,212,232,179,209,114, 28, 26, 64,141, 34, 92,211, 39, 85, 29,219,224, 61, 31,147, 62,
- 37, 20,246,157,214, 45,182,208,252, 5,177,147,168, 58,227,248,224,196, 55,119,128,177,144,252,146, 15,160,178, 47, 21,144,227,
- 6, 44,132,136,218,145, 36, 40, 85,147,182,100,111, 19, 52, 67, 20,239,185,222, 68,231, 89,153, 3,242, 14,219, 87,215,196, 21,
-171,162,207, 53,159,129,240,101, 44,154,246, 23,224, 20, 89, 44,253,157,179, 30,122,202,164,178,111, 29, 72,214,226,120,103, 58,
- 86, 15, 62,116,157, 65,100,233, 96,119, 20, 64,123,243,189, 66,214,232,216,112,137,170, 79,247, 88, 96,151,104, 56,213,162,119,
-167, 52,167,235,114, 11,168, 46,168, 48, 69, 65,144, 74,124,198,210,105, 73, 99,164,206, 90,171, 85,131, 36,125, 62, 8, 42,189,
-239,105,150,239,255,202, 63,255,250,159,255,252,239,187,223, 47,191, 61,143, 31,253,116,186,200,197, 25,208,187,165, 62,246,189,
-123,133,255, 77, 60,165, 62,177, 89, 82,245, 82,206,210,174,206,144, 55,131, 50,205,149,209, 89,190,236,124,243,111,159,181, 51,
-187,199, 81, 66,161, 13, 71,182,114, 62,149, 41, 96,241,143,117,154, 80,122,246, 47, 0,114,220, 3,162,252,171,168, 13, 5,244,
-231,189,145, 75,189,220,197, 43, 98,232,170, 15,128, 34,245,182, 78,200, 42,219,248,168,124, 48,136, 41,227,183,182,178,192,159,
- 7,239,106,108,162,236, 41, 68, 16,252, 72,107,244, 4, 88,201,241,201, 74, 28, 15, 10, 0,207, 86, 42,244,202,201, 59,251, 32,
-205,203, 60, 47,254,199,183, 63,253,242,238,109,123,247,234,205,119,223,190,254,230,251,167,254,235,189,255, 48,132,127,230, 15,
- 99,162,112, 89, 42,246,232, 42,159, 77, 23,105,240,113,229, 64, 26,170,166,183, 85, 79,183, 78,177,154,244, 34,242, 77, 74, 2,
-217, 69,214, 37, 48,165, 1, 38,105,112, 31,185,224,199, 72,220,135,173, 28, 18,135, 40, 65, 12,204,173, 91,140,237, 20,124,115,
- 43,124,176, 42,209,210, 89,140,131,118, 19, 71, 5, 35,231,225,193,194,121, 73, 19,227,206, 9, 59,234,157,128, 68, 25, 49, 75,
-234, 24, 37, 94,222,238, 46, 4, 33, 60, 88,110, 67,201, 86, 67,203, 99, 49, 3, 75, 62,234,180, 56,217,166,154,114,218, 13, 8,
-254,151,119, 15,207,249,245, 15,127,212, 31,151, 63, 27,215,226, 96,230,141,102, 77,198,212,179, 44, 0,172,185,207, 37,197, 92,
-165,254,180, 51, 43, 55,134, 21,150,238,137,108,227,245, 62, 30,129, 36,107,186,111, 57,153,214,212, 25,138,209, 83,225, 66, 44,
-156,188,243,249,212, 3,241,103,142,159, 20, 1, 86,153,219,230,172, 8,169,132, 78,183,252,128,212, 84, 54,133,154,199, 35, 74,
-191, 60,190, 68,123,138,223, 99, 87,108,112, 89, 43, 68,252, 94, 9, 15,138, 89,216, 96,152, 74, 92,146,176, 28, 63,164,184,120,
- 66,198, 83, 96,169, 70, 3, 23, 83, 11, 34,219, 13,172, 10, 71, 70,114, 38,127,150,121,189, 93, 27,173, 40,106,165, 43, 46,147,
-113,183,236,159,136, 69, 34,159, 68, 33, 34,226, 73,111,161, 99,223, 22, 40, 17,152, 82, 84,255, 11,192,209,181,236,216, 77, 68,
-193,182,187,219,238,246,189,190, 30, 6, 72,102, 68,148, 69,196, 46, 34, 72, 89, 34, 62, 1,241, 13, 32,177,224, 55,216,177,227,
- 51, 16, 75,216, 68,172,120,111, 32,201, 2, 9, 69, 17, 8, 33, 33, 22, 48, 25,184,115,253,104,187, 31,110,170, 60,251,171,177,
-219,221,117,170,236,115,170, 84,153,207,237,193, 59, 96,105,156, 14, 64,161,101, 25,230,196,180, 34, 60,161,200,118,249,168, 14,
-154, 65, 66, 89,158,103, 59,111, 81, 88, 47,131,176, 65,237,133,151,214,108,132,194, 3, 41,168, 49,152, 12,239,109, 15, 8, 14,
-116, 45, 98,219, 56, 22,239, 96,106,208, 31,126, 25,208,222, 55,122, 1, 5, 47, 67, 5, 37, 15, 85,174,124,153,199,218,201, 2,
- 52, 37,150,180, 77,221, 65,100, 0, 71,163, 72, 45,179, 97,246, 16, 71,162,154, 20, 46,102, 23, 1,229,165,242,178,155, 53,120,
- 12,254,156, 42,106, 89,249, 42,149,192,216,209, 69,190,164, 17,146, 89,141,237,136, 10, 49,174, 76,247,157,117,178, 39,148,172,
- 43, 89,220, 34,173,132,130,202,181, 27,214,222,119,218, 92, 85,184, 76,139,199,190,212,193, 22, 32,137,107, 15,142, 92, 46, 45,
-174, 99,130,174, 99,231,116, 41, 91,191,133, 35,245,217,236, 61,227, 59, 33,144, 56,165,144,148, 14,153,147, 82, 40, 5, 69, 3,
-226, 51,231, 5,139, 52,122, 72, 57,156,125,190,237,203,121,107,133,145,142,134,253, 69,242,120, 16, 17,224,233,167,232, 11,239,
-174, 93,152,138,109,234,184,240,203, 20, 0, 14,235, 78, 38, 70,241,205, 55,168, 53,102,161,149, 25, 86,240, 36,198, 85, 30, 20,
- 59,209,146,219, 62, 80, 45,161,206,163, 53,102,170, 3,235,200, 41, 52, 13,199, 6, 22, 90, 38,201, 14,204, 29, 56, 95,203,221,
- 44,243,158,241,136, 97, 20,219,204, 61, 0, 42,246, 70,140,166,241,127,151,122,151, 45,174, 89,177,255,113, 41,183,147, 24,152,
- 30,159,169, 11,146,167,219,186, 50,138,111,158, 87,171,110,134, 16, 80,151, 44,199, 29,135, 0,120, 92, 25, 66, 18,216,196,145,
-117, 24, 11, 54, 21, 64, 25, 66,145, 90,108, 78, 90,219,167,113,170, 6,156,222,195,116,134,139,139,154, 89,174, 56, 10, 34, 74,
-212,147,134,109, 89, 64,103, 59,243,237, 39,205,221,176,221,192, 71,249, 8, 57,223,195,174,197,162,173,156, 17, 14,144,113, 58,
- 52, 22,148, 94,112, 92,176, 22, 21, 22, 48,243,115, 99,228,110,175,235,133,243,122, 21, 99, 11, 44,132,152, 26,182,161,245,181,
-188,104, 59, 93, 3,160, 81,110,203,117, 39,204, 30, 36, 97,154,221,213,168,158,252,114,243,248,241,191,207,254, 24,175,242, 95,
-227, 63,241,183,211, 9, 60,163, 49,117,211,172,180, 70,189,213, 53,123,223,101, 6,246, 13, 45, 88,177,172,153, 26,206,200,244,
-100, 80, 61,170,105,158,109, 65,131, 27, 99, 2,237, 69,146,153, 45, 71,100, 67, 43,146,165,179, 80,128,234, 26,164,142,217,184,
- 24,109,155, 86,218, 14, 49,252, 16,168, 0,185,186,112,114,114,237, 95, 77,154,153, 62,202, 50,219, 83, 69,240,187,157,160, 95,
-130, 97,143,249, 66,111,154,172, 42,123, 4,143, 16, 67,226, 75, 41,181, 99,244,252,120,237,167,198,159, 87,244,106, 55, 11, 59,
-152,140,214,115, 76,219,208, 50, 13,160,132, 43, 44,249, 77,147,154,238,162,141, 51,177, 98,185, 41, 94,124,241,244,171,111,158,
-157, 63,184,127,231,225,221,123,119,111,159,139,203, 63,143, 47,142,167,227,180, 6,192, 83,142, 3, 29,254, 50,128,235, 76, 21,
-125,244,102, 22,216, 6, 56,219, 52,112, 83, 12, 48, 13, 96,213, 74, 67,123,133, 92,147,157,114,248,155,206, 36, 26, 39,127, 51,
-183, 97, 14, 83, 17,142, 66,236,112, 40,216,164,150, 32, 86,139,210, 56, 80, 27,143,219, 79,128,161,134,177,105, 37, 8, 59,126,
-178, 43,189,195,158,205, 94, 64,166,157,229, 62,196, 6,100, 57,120,172, 79,189,175, 23,136,243,181, 12,140, 42, 97,139,144,181,
-248, 63, 17,108,111,219, 65, 88,191, 85, 86, 66,175,234, 78,176, 82, 94,118,151,189,122,253,187,171,249,243,239,127,120,237,204,
-180,111,181,213, 80, 47,231,141,195,166, 88,164, 48, 55, 89,215,210,111,166,177, 96, 62, 0,205, 35, 24,122,248,244,163, 47, 63,
-252,248,157,116, 93,173,151,208,194,184,229,178, 72,209,224,126,227,220,116,121, 89, 92,170, 42,105,171,182,200,167, 3, 20,205,
- 9, 5,102,150,170, 19, 53, 61,219, 25,166,176,238, 33, 43,165, 24, 59, 61,226,160,226, 16,212, 18, 43,242,228,209,143, 63,125,
-251,188, 31,220,197,237,179, 55, 31,222,123,240,246, 93,149,253,204,160,135,160,244,174,116, 3, 0, 91,235,213,121,167,202, 73,
- 7, 16, 74,233,219, 84, 23, 98, 76,170, 89, 38,231,202,231,191,255,247,245,163, 95,223,127,239, 13,122, 46, 65, 95,244,105,126,
-133, 95,192, 75,195,192,218, 14,108, 16,202, 28, 63,179,121,110, 93,217, 75, 22,125,155,220,201,169, 32, 63,251,228,231,119, 63,
-184, 15, 54, 79,231,101, 43,174,219,245,127, 1, 72,186,150, 28,201,137, 40,152, 95,167,211,174, 79,247,244,180, 16,171,145,152,
- 77,111, 16, 8,177, 97,193, 41, 56, 4, 98,205, 25, 56, 0, 23, 96,139,132, 56, 1, 75, 4, 18, 18, 32, 86, 35,196,102,166,153,
- 13, 12,173,162,171,203,109, 59,127, 78, 19, 81,236,170, 85,106,171,236,204,247, 94,132,243, 69, 60,131, 32, 73,204,253,243, 80,
- 31,229,166,139,166,211, 42,133, 22,204, 30, 91,171, 95,226, 32, 61, 17, 93,238,128,194, 7, 53, 55,153, 28, 85,118,250, 44,117,
-228,123, 99,103,206,198, 23,210, 98,111,202,210,109,181,116, 94, 79,142,162,221,100,214,126,240,102,169,214,228,169,132,204, 46,
- 81, 13,170,140,140, 63, 37, 20,200, 98,135,221,214,191, 41, 75,144,251, 62, 22,128,185,182, 2,145, 30,186,122,145,199,132, 53,
- 76,169,197,242, 94,136,209, 73,123, 50,160,224,248, 0, 84, 81, 59,161, 64,185, 82, 78,155, 18, 1,183,102,142,108,208, 21, 97,
-200,147, 54,209, 60, 34,161,141,214,115,242, 82,169,167, 66,139,131,105,118, 39,172,112,186, 83,118,227,240, 88,144,182, 0, 41,
-133,184, 10, 81,131,231, 21,195, 49,208, 62,182,107,243,207,121, 72,242,194,118,200, 92, 4,205,145, 65,232, 27,239, 80,232, 76,
- 59,165,194,193,164,174,112,114,125, 69,189,108,226, 67, 27,176, 78, 8, 81, 37,130, 1,144, 6, 3, 42,170,215, 77,198,246, 42,
- 9,121,177,103,103,171, 70,106,252,183,166, 26, 6, 29,248,170, 4,123,173, 5,243, 76,115, 94, 74,166, 8,182,108,239,215,169,
-144,159, 81, 4,136,130, 61,168, 24,216,114,102,159, 86, 82,252,137,181,202,180,168,225, 72,198,158,138, 25, 5,144, 33,187,101,
-229, 92, 41, 71,234, 80, 65,216,200,178, 20,229, 37, 10, 55,176,216,208,236,145, 35, 53, 29,240, 56, 33,124, 84,250,158,200,220,
-142, 98,237,197, 33,216,157,160,103, 19,251,159,192,159, 45, 64, 24,237,236,105,204,196, 62, 3,218,105,230, 1,215,170,184,233,
-122,169,228,176,216,147, 69, 61,116,224, 70, 11, 37,150,116,193,160,243,196, 92,147,165,146,115,145, 97, 6,103, 12,163, 16,141,
-173, 79, 52, 69,238, 98,226,193, 11, 74,104,189, 64,252,182, 46, 47, 52, 83, 17, 20,199, 71,159, 77,110, 20, 25,248,255,195,148,
- 3,130,132,164, 77,176, 51, 56,111, 30, 86,144, 1,164,192, 25,184,107,109, 19,251, 21,107, 80,147,162,160,177,224, 34,198,115,
-226,229, 54,233, 94, 91,183,191, 50,215,198, 7,115, 65, 75,192, 65,238,194, 97,126,253, 82,190,140,211,237,225,246,239,223, 30,
-254,188,127,124,149, 78,211,157,138,126,218, 0,100,174,219,227, 19,179,111,155,119,205,110,104,114,215, 2,231, 75,143,223,141,
-250,195,214, 87,214,203, 70,246,219,163, 25,173, 11, 28,190, 88,213,166,165,143,160,206, 40, 47,145,115,252,120,194, 29,117,228,
-144, 59,196,159, 4,154,203,212, 58, 30, 54, 6,177,227,227,241,104,187,167, 60,103,226, 4,213, 70, 14,236,213,140, 10, 76,155,
- 90,228,158,186, 87, 69,169,228,140,130, 1,160,195,113, 86, 62,235,156, 46,181,187,223, 13,120, 84,227, 17,152, 53,184,172,233,
-218, 86,102, 93,182, 18,128, 73,177, 77, 4, 17,132,235, 74, 71,103, 3,199,230, 58, 29, 84,218, 2, 84,144,245, 37,190,142,226,
- 32,226,213, 54,206,234,185, 11,215, 13, 15,157, 78,107,252,233,197,139, 31,191,127,253,225,205,243,247,222,185,121,254,204,236,
-246,127,197, 60, 31, 15,111,210, 50, 59, 16, 34, 64,214, 11, 4,213,170,252,188,218,136,104, 93, 45, 27, 61, 57, 26, 30,181, 51,
-148,172,234,217,157,148,135, 55, 0,190, 84, 99, 82, 8, 43,176, 63,116, 16,216,166,180,173,213, 60, 92,194, 63, 82,233,128,141,
-196,193, 28,248, 89, 64,183, 21,127,131,187, 3,157,151, 24,151, 36,203,216, 81,163,195,157,154, 11,112, 26,144,223,124,182,118,
-146, 96, 61, 8, 41, 41, 57,143, 22, 48, 91,212, 81,167, 58, 71,219,246,214, 53, 77, 93, 58,192, 74,181,226,107, 85,174,222,190,
- 12,203,251,223,189,146,191, 28,127,255,225,219, 95, 59,239, 62,253,232,134,208, 16,207,174, 91,202,157, 97,147,250, 76,181, 0,
-187,204, 23, 51,158,192, 17,120,168, 36,176,136, 53,164,107,128,124,237, 54, 91,233,114, 57,173,213,186,201, 43,218, 28,170,230,
- 45, 36, 35, 93,186,213,203,210,123,149,106,182, 74, 2, 27, 10, 20, 22, 65, 91, 6,229,129,117, 71,154, 58,183, 77, 45,238,170,
-173,143, 95,126,241, 13, 54,247,103,159,127, 34,247,230,112,251,199,215, 95,253,252,193,199,207,166,149,157, 24,153,175,140, 23,
- 43,168,105, 93,150,199, 83, 65,110,109, 27, 92, 86, 33,227, 77,156, 6,137, 26, 41,241, 48,206,138, 19,206, 40,110,115, 51,219,
-172, 65,152, 89,107, 12, 91, 33,150,129,158,230,186, 55,225, 20, 70,144,215,177, 8, 71, 35, 94, 67, 95, 79,138,158,113, 83,222,
-211,101,162,176,143,125,245,107,251,159, 0, 36,157,207,143, 20, 69, 20,199,171,170,187,170,127,237,252,216, 25,126, 10,108, 76,
- 68, 87, 57,172,152,168, 1, 12,154,120, 50,198, 24, 19,226, 69, 15, 92, 77,220,139,127,128,103, 15, 30, 61,120, 51,196,132, 68,
-189, 17, 57, 24, 99,130, 7, 56, 16, 73, 8,137, 8, 65,118, 89, 64,133, 97,103,153,157,237,238,234,234,238,170, 46,191,111,185,
-206, 97,102, 50, 83,239,189,239,167,235,189,239, 67,114, 6,254, 69,162, 18,124, 38,105,252,211,210,158,241,112,135, 44, 31,182,
-185,145, 52,180,104,165, 46, 61, 36, 1,128,226,185,154,149, 73,143,188,171,147,134,247,169, 61, 28,149, 76,205, 23,248,152, 55,
- 92, 43, 62,196, 39,230,156,239, 5,182,246, 32,241, 43, 4,189, 16, 89,229,235, 52,109, 35,156,241,233, 40,216,174, 58, 89, 56,
- 40, 80,179,208,209,114,215,140,137, 73, 96, 7,130, 27,129, 23,234, 64, 55,105,132, 4,194,250,116, 79,167,200,244,206, 87,228,
- 20,145,161, 94,138,150,110,207,133,156,225, 0,251, 40, 78,242,196,179, 45,201,153, 46,194,136,124, 78, 72,104,251,110,134,240,
-221,163, 75, 97, 7, 79,163, 72, 8,147,117,131, 46,110, 11,171, 33,176, 89, 94,217, 65, 12, 97, 41, 59,104, 27,227,230, 1,228,
- 66, 15,245,160,207,234,186, 17, 8,189, 62, 40,186, 99,181,138, 29, 99,145, 51,109,101,107, 25, 32,178,240, 51,236,222,255,245,
-152,172,184, 23, 54, 36,213,134,147,158,177, 86, 90, 72,244, 0, 98,172,107,131, 36,104,149,207,163, 36,218,210, 80,154,144,240,
- 42,103, 56,203,117, 67, 70, 9,204,150, 22,232, 82, 5,179,176,241, 21,107,144,214, 3, 32, 19,169, 96, 95,116, 60, 71,222,135,
-182,183, 76,246,232, 41,119, 2,138,237,249, 88,219,113,227,166,125,148,149,103, 46,236, 97, 59,108,200,225, 69, 27, 2, 20, 48,
-195,128,211, 40, 33,249,142,171, 58,131, 80,226, 86, 90, 89,119, 62,197, 91,251,170, 11,161,182, 82, 35, 7,178,106,250,174, 18,
-174,214,140,252,162, 28,100, 69, 52, 0,208,229,244,240,142, 27,234, 97,105,107, 23,123,114,247,151,128, 8,196, 27,244, 43, 74,
- 9,131,132,115, 81,193,218, 2,137, 15,181, 43, 52, 5, 89,206,165,146,238,207,120,142, 47, 70, 45, 61, 86, 65,226,238,110, 24,
-169,201, 96, 61,137, 61,240,211,233,134, 70, 89,226,160,138, 26, 69,107,221, 83,148,208, 48,226, 69, 38, 84, 9,216, 33,147,101,
- 75, 51, 23,174,139, 3,210,138,204, 23, 81, 20,117, 90,122, 62,211, 9,216, 67,236,195, 27,182,241, 32, 9,166,110, 0,244,236,
-177, 33,194,123,127, 90,151, 3,224,218, 2, 40,101, 44,242,182,221, 42,210,155,255,149,147,127, 38, 55,103,229,230,227,122,125,
-167,170, 55, 81,196,252,188, 96, 62,233, 0,120, 41, 97,124,140, 50, 61,146,202,141,145, 37, 93,102, 41, 66, 1, 33,188,105,101,
- 3, 72,226,219,100,197, 85,211, 74,187,194,171,168, 41, 77, 82,100,148,175, 4,173,187,224,162,108, 12, 50, 89, 63,163,245, 89,
-128, 25,168, 66,174, 12,121,165,135,228,249, 69,102,249,129,220, 75, 45,173,101, 30,246,198, 73,205,136, 54,108,203,101, 81, 59,
- 21, 4,130,150, 27, 3, 22, 99,238,162,126, 83, 34,179, 2,147,104,172, 67,114,163,194,197,192,110, 37,178,211, 28, 80,149,182,
- 42, 81, 46,247,101,207, 42, 47,159, 93, 0,129, 5,105, 45,138,140,184,102, 86,209, 96,115,135, 47,198,186, 29,198, 98, 20, 3,
-178,233, 65, 78, 39,239, 44,195, 37,229, 63,212, 6, 80,175, 66,158, 27, 88, 19,168, 81,141, 84, 21,121,173,195,226,218,244,206,
-213,141,181, 35,163,236,196,129,253, 47,157, 92, 62,120,232, 8,155,253,171,231,179,157, 92,151, 52,123,110, 68,184, 0, 98,148,
- 77, 81, 67, 72,107, 78,251,131, 61,212,141,165, 3, 7,220, 67,209,101,188,234,209, 46, 74, 28, 48, 50, 62,112,180,139,135, 77,
- 76,155, 0,104, 81,136, 66,105,156, 31,119,162,232,154, 93, 15, 81,232, 1,234, 4,158, 33, 72, 56,185, 97,133, 9,181, 80, 36,
- 10, 1,144, 58, 89, 43, 3, 24,166,253,222,144, 38, 67, 38,170,200, 8,154,120,166, 75,227, 90,248,172,163,230, 27, 59,198,143,
-137,191, 42,102, 17,237, 63,110,189,218, 19, 44,142, 70,186, 57,250,203,134,187,227, 30,252,125,245,222,241, 83, 47,222,191,251,
-232,201,218,116,116, 40, 13,171,238,183,243,215,145, 15, 30, 63,154,228,211,226,221,179, 39, 15, 47, 67,173,186,171, 23,175,109,
- 79,230,244,224,143, 49, 19,236, 99, 61,245,235,215, 63,191,124,250,216,237, 43,183, 79,125,116,188, 11,118, 46,159,191,156,100,
- 9, 96,241,211,213, 15, 51,229, 46,252,120,101,253,207,135, 73,134, 60,194, 62,255,242,172, 31,166, 63,124,115,241,214,141,123,
-186, 48,239,124,112,226,227,213,247, 85,129,108, 80,248,100,184,118, 99,190,177, 62,249,234,220,106,163,105,127,228,161,165,209,
-103, 95,156, 65, 10,107, 27,253,211,183,151, 30,172, 63,133,136,121,239,204,202, 43,111, 46, 61,186,171,255,248,125, 93,101,252,
-254,173,217,153, 79, 86,190,255,238, 90, 28, 73,163,219, 55,222, 94,122,237,173, 3,138,220,176,186, 26,193, 53, 11, 47,156,187,
- 1, 82, 51,149,125,253,244,193,135,107,197,214, 20, 2,132,218,175,150,143,141,118, 26, 3,217,122,244,248,126, 28,169,155,127,
-109, 66, 89,172,188,186,200,104, 32, 73, 88, 51,191,126,233,201,225,165,225,243, 47,136,255, 5,224,232, 90,122,164,168,194,232,
-173,186,117,111, 85,215,163, 27,153,233, 17, 6, 38,168, 81, 17,149, 49, 6, 18, 19, 97, 64, 67,220,136,102, 76, 92,144, 24, 23,
-236, 52, 49, 49,110, 76,116,195,146,184,117,111, 92,233,194, 4,227, 6,212, 5,130, 9, 15,137,130, 70, 34, 35, 50,196, 9, 14,
- 24,102, 28,122,122,186,235,113,171,238,163, 60,223,252,128, 78,245,226,214,121,220, 58,223,249,160,246,160, 52, 21,252,144,159,
- 81, 41, 84, 84, 38, 90, 83, 96,216,209,178,240, 70,154, 56,225, 5,196, 20, 88, 72, 85,137,109,189,144,246,204, 83,247, 80,204,
-135, 33, 88, 38,236, 53,128, 77,248, 8,217,227, 61,225, 37,218, 80,252, 57,168,187, 42, 28, 43,208, 13,141,199, 39, 35, 97, 51,
-161,105, 67,134,166, 54,201,180,216, 86,155, 49, 77, 30, 67,134,212,113,201, 70,222, 8, 68, 27, 11, 48,141,247,144,196, 91, 13,
-191, 96,130,166,160, 40,151,139,146, 78, 90, 81, 51, 96, 45,189, 13,234,181,118, 76, 9,149,214,129, 31,201,162,130,211, 47,101,
- 12,249,220,104, 22,133,109, 99,131,220,171, 68,215,118,100,157,241,112,173,136, 3,161, 59,170,196, 73,215,182, 71,107, 35, 10,
-205,180,196, 1, 54,172,142, 56, 31,242, 40,133,111, 32,232,166,202,150,138,233,184, 12, 30,192,182, 89,191, 27, 7, 86, 82,216,
- 26,110,193,107, 75,128, 79, 65,227,148,180, 76,218,177,168,214, 89,194, 6,141, 11, 21,109,117,240, 65,249, 0, 55, 79,209, 87,
- 3, 99,221,184,208, 64, 86, 42, 97,162, 5,119, 70,240, 92,217,212, 52,229,208, 27,103, 85, 86,143, 2,109, 41,251,170, 92, 16,
-155, 49,197,123, 61,151,183, 53,180,146, 37, 89,231,137,114,211, 41, 1,152,139, 22,184,227, 58,208,237,134,165, 26,128, 31,106,
-128, 42, 3, 24,166, 17, 69,116,152, 7,193, 14, 12,240,203,172,169, 3, 30, 84,220,209,180,128, 97,171, 33, 76, 86, 45, 52, 28,
- 73,199,181, 77,172,115,138,103,130, 69,254,179,253, 72,172,110,173,235,145,196,131, 82, 42,191,129, 15, 24, 66,189,109,208,181,
- 40, 60,167,134,233,195,251,184,181, 77,107,192,132,110, 84,219, 97,212, 22,236, 68, 43, 35, 72, 0, 90, 57,155, 56, 32, 51, 53,
- 17,176,205, 98, 76,138,101,149, 20, 26, 74, 68, 69,241,115, 27,148,138, 38,128,101,196,116, 6, 49,209,194, 11, 68, 65, 27,102,
- 42,108,165,171,184, 54, 80,103, 84,100,213, 10,190,217, 63, 10, 97,196,169,168,167,107,164, 89,111, 42,250,104, 53, 21,217,196,
- 74,209,233,108, 73,133,156, 17,245, 84, 80,154,244,206,128, 47,230,160,234, 96,112,119,180,156, 87,195,123,234,175,241,224,254,
-191,109,174,168,217, 50,242,253,170, 5,197,114,234,180,145,126,214, 21,211, 19,180, 31,206, 87, 28,134, 62,193,147, 38, 97,206,
-120, 14,197, 83, 22,150,170,218, 33, 63,240,199,228,200,117, 96,135,164,131,237,128, 74, 16,144, 0, 94, 72,251, 94, 64,155, 56,
- 48, 18, 50, 1,178,139,154,168,188, 88, 6,106, 40, 92,214,172, 17, 82,215,142,238,253, 61, 6, 62, 5,104,129,152,149,106, 41,
-131,233, 53, 27, 17, 13,113, 91,186, 47,174,123, 34, 20, 84, 57, 72, 97,116, 74, 46,233,146,117, 89, 22,211,106,236,210,244, 20,
-224, 48, 41, 64,166,224, 11, 19,166, 30,205,125,176, 34,128, 60,144, 52, 3,199, 27, 65,145,104,210,155, 52, 16,167,134,156,197,
- 48,120,148,154,240, 18,197,168,106,149,211, 6,104,104, 34, 67, 11, 86,157, 78, 18, 95, 3, 87,161,146, 44, 37, 99, 42,170,135,
-229, 33,125,144, 9,214,187, 81, 22, 77,114,133,211,188,166,212,183,215,151,206,111,172,239,153,216,241,216, 84,242,212,244,195,
-219, 38, 12,179,171,133,183,150,215,166,146, 21, 7, 12, 36,161, 89, 7,145,196,122, 84, 81, 77, 27, 20,135,181, 96, 17, 72,114,
- 62, 54, 82, 6,181,231,172,164, 6, 27, 30, 67, 12,192,166,112, 75,145, 88,159, 27,227, 85, 20, 84,166, 27, 25,120, 50,156,217,
-136,242, 53,110, 76,141,208,173,139, 61,218, 68,100,172,108,106,218, 34, 31, 82,149,150,165, 70, 56, 22,250,224, 0, 42,220, 2,
- 35, 87, 20,184,242,240,251,218,178,142,102, 93, 5, 77, 24, 16, 81,138,176,169,123, 91,250, 38,156,190,124, 59,185,182,126,175,
-155,200, 27, 23,238,204, 31,127,185,183, 43,190,126,241,214,225,183,246,249,169, 92,189, 59,120,230,224,147, 7,143,189,176,248,
-235,210,111,103,111, 79,206, 28, 94,184,180, 16,119,131, 23,231,143,182,145,254,226,163,175, 2,205,242, 42,191,191,244,160, 63,
-179, 50,123,228,137,108, 90,124,115,242,199,227, 31,191,214,207,194,159,127,249,231,236,169,243,175,191,251,234,220,177, 3,111,
-188,147, 66,209,127,255,249,119, 87,127,184,186,125,247,142,155,191,255,125,242,203, 15,241,102, 47,223, 26,120, 0, 89, 27, 54,
- 13,222,122,255,226,149,133,125,135,158,167, 26, 68, 90,180,193,125, 73, 29,118,202,137,159, 78,255,217,159,202,222,126,255,165,
- 60, 31,125,242,193,153,217, 61, 83, 77,217, 92,187,116,231,200,252,211,115, 71, 31,113, 97,248,222,137, 67,181,203,155,161,251,
-244,196,229,253,123,119,194,125, 57,136,221, 86,159,251,250,198,238,189, 19,179,115,219,225,118, 86,150, 71, 7, 94,217, 69,147,
-189, 85,113,250,179,155,147, 59,179,110,155,158, 59,181,248,232,115,125,120,237, 63, 46,172,236,127,243,113,171,224,210, 33,232,
-221,149, 51,171,105, 55,152,121,182, 7,232,249, 95, 0,146,174,231, 69,142, 34,140, 86, 85, 87, 85,255,156,158,237,221,217,221,
- 36,106, 80, 20, 3, 30, 36, 4, 77, 68, 65, 16, 81, 68, 61,121,241, 32,222,189, 11,193,171,127,128,127,128, 10, 57, 9,158, 22,
- 2, 30, 68,188,228,144,131, 98,192, 16, 66,130, 68,208,172,152,100, 55,217,153,157,153,238,174,238,174,234, 42,223,183,158,230,
- 48, 63, 24,186,170,223,247, 94,245,247,189, 39, 25, 13,213,208, 86, 24,130,237, 65,185, 69,111,125,238, 6,240,141, 16, 7, 55,
-183, 81,109, 69, 41,233, 96,152,252, 85,156, 30, 21,133, 39, 4, 92,161, 32,199, 93, 85,202,164,179, 37,141,151,106, 91, 64,228,
-155,137, 39, 43,157, 56,235, 59,197, 10, 20,159, 4,202,237, 36, 17,192,110,156,100,118, 1,171, 14,249, 22,136,123,146,112, 71,
-198, 39, 62, 20,179,116, 9, 50, 13, 85, 80,183,246, 88, 68, 19,232,250,145,156,128,180, 72,117, 74, 17,198, 30, 32, 10,234,204,
-226, 29, 40, 53, 41,125, 9, 38, 19,119, 52, 32,156, 59, 73,244,209, 58,200,118, 30, 59,190, 88, 24, 93, 76,196,124,221, 98,175,
- 71,128,212,110, 0, 33, 93,197,190,194,125,189,136,250, 66, 38,174, 7, 67,204, 71,219,231,210,199,147,160,149,179, 54,100,158,
-148, 46,151,138,124, 56, 35,202, 34, 16,192,106,178,255,160, 25,157,176, 18, 99,195,171, 74, 46, 59, 70, 41,123, 46, 80,241, 99,
- 54,210, 50,119,126, 5,138, 7, 89, 27, 59, 34, 29,203,193, 79,173,130,160, 24, 69,215, 6,101, 45,148, 49, 54,191,147,199, 99,
- 29, 81,190,236,194,116, 82,245,199,218,137,121,159,116,113, 29,177,209,180,228,218,185,108, 56,157,205,107,154,189,229,188,222,
-114,212,154, 0, 22, 78,109, 73,148,235, 30,157,156,143, 39, 53,135,122,237, 0,236,146,146,163,173,228,217,255, 61,110, 96, 44,
-228,133,141, 59,155,196,133, 47, 32, 71,240, 46,216,145,111,200,128,154,129,150, 66,215, 59,200, 84,157,171, 98,195, 12, 71, 94,
-100,102,137,202,205, 39, 75,158,205, 68,148,184,113, 69, 46,225, 2,139,140,197,235,216, 64, 78, 32,114, 18,201, 86,122,211, 82,
- 91, 51,208,221,146,195, 12, 37,160,174, 86,100, 95,112, 34,217,197, 64, 6, 88, 52,165,184,160, 84, 60, 15,113, 35, 92,172, 1,
-157,171,192,176, 85,203,192, 20,136, 96,156,119,174,211, 33,108,184,173, 35, 97,139,172,199,162, 86, 1,223,166,206,117,128, 98,
-156,168, 5,174,246,184,189, 35, 78,205, 50,235,162,135,211,252,240,137,188,113,232, 30,223, 17,247, 22,227,193,195,199,245,122,
-176,220,184,150,140,207,214,137,165, 54,110,222,179, 44,219,156, 2,240,100, 28, 25,145, 43,174, 18, 48, 22, 95,146,165,171, 69,
-125, 53,208, 47,158,178, 18,141,166,199, 32, 41, 13, 88,137, 33, 27, 80,175, 12,136, 35, 39,179,129,174,167,184,131,193,169, 42,
-178, 54,205,192, 92, 68, 30, 5, 79,243,108,248, 48,177,125,166,215, 10, 74,204, 87,124, 58, 6,130,179, 54,149, 46, 51,138, 66,
-246, 12, 74, 23,249,161,201,190, 64,217, 26, 50,242, 48, 11, 77,154,241, 13, 19,175, 85,163, 29, 79, 93,186, 68, 29, 24, 4, 84,
-148,207,129, 44, 6, 98,188,151,158,122,251, 58,155,135, 38, 99,113,237, 80, 4,215,244,108,151, 78, 63,180,200,186,172,151,198,
- 25,202,166, 19,186,235, 28, 10, 42,229, 95, 83, 91, 35,235, 33, 23,248,162,160, 46, 21,157,244, 29,254,137,103,169,210,126, 80,
- 94, 13, 98, 90,155, 94,106,142, 61,225,179, 60,145, 16,162,205,224, 10,147,151,128,163, 89,111,230, 96,242,114, 54,242, 52, 49,
- 97,117,125,127,254,235, 93,177, 85,157,217, 61,179,125, 97,182,179,179,251,220,238,212,178,246,129, 89,206, 23,125,221, 55,163,
-149, 39,253,171, 82,141, 77, 27, 53,182,171, 56,107,200,145,159,145,223, 8,185,246,163,136,104,236,156, 2,100,141, 74,126, 48,
- 14,107, 71,182,223,154, 30, 91, 41,141,101, 10,108,148,224, 46,100,167,211,198,244,156,146,172,119,148,228,128, 17,144, 26, 26,
-225,162,148, 64,242,170, 60,153,163, 86,248,113,155, 79,167,161, 27, 59, 32,210, 52, 34,111,233, 97,195,198, 17,197,193, 55,178,
-170,188, 11,179, 31,175,143, 55,135,131,113,119, 92, 61,144,166,233,227,243,207,190, 84,196, 87,174,254,112,241,147,119,162,116,
- 5, 82, 49, 57, 61,113, 37, 43, 51,230,235,182, 8,221, 95,183,254,125,249,131,115,110,218,230, 60,163,163, 12,190,166,184, 29,
-198, 94,253,248, 18,200,210,163,251,135,125,107,247,190,189, 70,110, 37,198,101, 37,214, 51,154,223,249,103,239,234,111,160, 95,
- 79, 14, 86,111,188,119,225,210,185,237,166,238,190,186,124,229,133,231, 79,189,249,225, 43, 2,220,129,111,134,196, 11,239,201,
- 31, 8,144,195, 91,188,126,249,249, 55, 0,188,187, 55,247,191,251,233,139,223,127,185,255,254,167,175,231, 40,230, 19, 93,109,
- 23,183,254, 88,167,241,120,250,236,230,107,111, 63, 3, 66,125,252,200,238,125,125,251,120,209, 66,164,244,198,177,245,156,177,
- 21, 32, 40,183,225,222,237,163,143, 62,123,113,185,132,162, 47,171, 83, 19,232,109, 40,185,159,191,255,243,252,187, 79,199, 83,
-149, 7,150,151,250, 96,191,214, 17,203, 39,250,108,169,201,233,143,177, 27,215,254,206,166,234,226, 91, 79, 13,224,102, 60,252,
- 39, 0, 71,215,206, 98, 73, 17, 70,171,170,235,217,143, 59,119, 28,103, 71, 93,124,236,128,179,129, 26,153,136,153,153, 24, 8,
- 26, 24,153,152, 26, 8,134, 62, 49, 95, 16, 19,193, 23,198,162, 34, 46, 38, 50, 32, 27,105, 34, 12, 34, 35, 58,178,200, 46,187,
-137,195,122,231,222,233, 71,117, 87,117, 87,123,190,249, 1,183,185,245,250,190,115,234,171,239, 28, 68, 81, 67, 26,148, 82, 82,
-183, 56, 87, 74,123,128,181,198,247, 29, 61, 14,209, 5, 0,251, 80,182,122,210,100,217, 4,182,111,187,134, 39, 26, 57, 97,230,
-251, 2, 11,125,237,197, 98,123,185,199,201, 32,100,236,129,128,182,200,204, 94, 75, 51,102, 21, 48, 71,195,182,221,216, 70, 81,
-235,113,118, 81,110, 66,237,149, 84,121, 5, 20,200, 58, 82, 41, 91, 74,182,222, 77,172,221, 98,125, 40, 43, 71,101,221,224,153,
- 27,200,170, 5, 7,160, 42, 71,236,155,177, 47,148,232, 71,165, 73, 5,156,203, 1,144,196,144,248, 50,189,191,138,231,105, 33,
-235,190,114, 72, 10,150,206,189,164,219,225, 6,112,133, 52,139, 60, 87, 32,138, 36,190, 55,170, 94,225,132,143,110,114, 65, 76,
-205, 76, 34,231,134,169, 28,199, 67, 1,255,215, 60, 45, 93,156,221,130,196,194, 17,236,133,167, 24,160,106,178,254,206,149, 93,
- 38, 30, 99,170, 93, 86,140,145,100, 62,133, 97,158,164,189, 60,210,153,227,105, 29, 16,162,221, 50,139,235, 64, 37, 67,159, 33,
-162,111, 36, 6,209,205,101, 24,235, 96,233, 38, 94,204,160, 0,235,213, 80, 26,138,149,227,122, 32, 29, 68, 61, 96,162,155, 73,
- 22,181,246,102, 24, 83,139, 1, 56,196,169,181, 16, 57, 85,178,186,164, 28,181, 95,171,152,167, 42, 19,153, 3,156, 67, 92,154,
- 51,155,170, 62,130, 29, 3, 55,207,248, 43, 67,174,120, 72,136,146,149,141,255,154,188, 66,100,161,167,137,216,119, 88,227,146,
-129,144,225, 99,136,211, 67,155,153,189, 57,147,255, 37,190,195, 84,165,242, 94, 5, 55,146, 64, 0, 9,222, 43,122,243,130, 21,
- 41, 72,232,173,136,226, 44,164, 82,226, 27, 98, 36,200,205,233,165, 36,245,162, 79, 32,138, 1,168,198,146,246, 66,207,103, 76,
-107,156, 72,211,146,228,162,147, 48,103, 76, 25,207, 22,234,162, 68, 44,151,126,158,129,132,157, 15,100, 22, 33,205,189,172, 45,
- 50, 47, 55,126,224,123, 83, 17,123, 18,152,198,214, 76,142,104,250,165,203,188,182,139,159,154,234,248,183,243, 99,192,192, 59,
-235, 57,109, 90,117,225,131,208, 69,146,220, 85,202, 86, 99,182, 43,138, 9,243,133,204, 87, 10, 4, 98,203,131,196, 62, 38,215,
-213,185,231, 3,230,171,243,188, 29, 61, 15, 85,110,217, 69, 91,190,162,115, 72, 74, 21,125,100,212,217,100,201,247,139,244,119,
- 72, 98,119,118, 37,201, 18,196,128,140,137,188, 30, 38,164,183,220, 68, 83,234,102, 32,195, 19,176, 50, 77,152,131, 3, 1,109,
-209,147, 28,107, 51,214,146, 15, 13,213, 23,149, 6, 34, 37, 95,132,184,208,100,141, 86,100,101, 7,220,144,134,209, 5,221, 11,
-157, 37, 59, 85, 8, 93,122,109,133,156, 74, 16,160, 60,120, 67,174, 28, 64,200, 76, 54, 84, 27,226,128, 74,142,154, 1,251, 45,
-230, 73, 91,132,129, 20, 48,153,200,198, 27, 80, 98,182,102,146,107, 55,235, 49, 14,102, 36,195,161,139, 42, 35, 22,190,193,215,
-163,209, 88,178, 4,234, 85,240,110, 78,219, 11,141, 95,112,178,242,158,197, 69, 81,187,146, 32, 15, 81, 1, 73, 55, 73,226,144,
-100, 70, 22, 82, 97, 55,101,219, 37,232, 71,214,137,246,230,237,219,199,127,201,220,238, 61,190, 91, 30, 60,188,115,176,127,229,
- 33, 80,190,234,110,205,239,212,229,212,159,173, 27,234,139, 20,224,129, 54, 79,180,231, 2, 83,110, 12, 3, 39,144, 24, 50, 65,
-210,103, 84,251,142, 61,136,230,164,128,234,200,121,142, 35,150, 82, 75,207, 72, 10, 69,243,185, 75, 57, 6, 79, 30,240,212, 80,
-115,209, 68, 49,145, 14,166,230,154, 81,199,124,206,105, 54, 39,203, 16,246, 53, 53,161, 40,238,146,214, 56,234,204,208, 5,158,
-181,113, 97, 51, 97, 30,189,113,215,252,188, 58,205, 47,231, 5,227,191, 31,221, 68,194,185,254,254, 87, 56, 10, 67, 63, 12,183,
- 78,246, 46, 47, 73,215, 63,114, 64,150,142, 44, 16, 85,183, 64,210,224, 58,105, 25, 52,207,105,191,249, 92,106, 18, 16, 71,130,
- 44,181, 6,123, 13,213,110,245,202,187, 47,228, 22,169, 76, 97,198, 86, 39,171,175, 63, 61,124,231,147, 55, 47,221,111,190,251,
-226, 80, 10,189, 92, 20, 31,125,243,214,201, 31,183,142,110,252,249,193,235,159,127,118,253, 90, 32,191, 27,178,210,121,242,233,
-131, 47, 63,252,254,229, 87,159, 7, 55,123,251,227,215,242, 48,191,244,220,123, 8, 3, 69,153,249,102,195,194, 3, 29, 1, 72,
-182, 93, 22,125,232,200, 70,104, 6, 18,153,126,248,246,151, 43, 87,119, 94,124,246, 25,159,234,107,111, 28,110,242,178, 91, 37,
- 42, 97, 69,186, 76, 63, 93, 81, 14, 52,224, 82, 66,157,243,242,215, 31,255,121,112,191,220,127,172, 52, 30,152, 73, 93,125, 98,
-231,239,163,123,224,137,143, 60,181,149,172, 32,219,123, 42,179,201,245,105, 59,180,228,233, 12,242,254,191, 0, 28, 93, 77,143,
- 20, 69, 24,174,207,238,234,158,233,153,221,157,101, 65, 98, 8,155, 16,194, 34, 6, 72,144,131, 33, 70, 19, 47, 28,244,160,198,
-131, 7,253, 11, 38,254, 9,127,129,127,192,131, 87, 15, 98, 34, 23,179, 26,163, 70, 89, 34,129, 21,228, 91, 32,172,187, 58,236,
-206,244, 71, 85,117, 87,181,207, 59,115,157,233,206,244, 71,189,207,243, 84,213,251, 60,202,227,125,195,171,130, 43,214,109,232,
-131,173, 83,212, 87, 75,182,106, 94, 58,207, 84,223,205, 5,198, 84,141,223, 57,147,231, 85, 51, 46, 2,136, 22,106, 69,199,218,
- 90,184,204,172,185, 3,214, 23,140,155, 96, 12, 57,146,132, 33, 72, 94, 26,147,208, 31,176,208, 15, 32,224,101, 67, 6,223, 96,
- 82,162, 75,138, 2,223,203,253,172,176,174, 51,168,115, 26,228, 82, 86, 5,215,125, 85,245,228,248,237,115,158, 22,251,182, 54,
- 19, 12, 91,150, 84, 76,186,206, 37,121,153,209, 62, 29,168,127, 49, 52,168,147,170, 2, 13,226,182,201, 18,118, 48,230,117, 93,
- 80,204, 94, 40,187,236,208, 42, 71, 53, 12,217, 68, 59,159,166, 73,157,144,177, 40, 20,118, 93,164,178,104,198,189,201, 27,223,
- 13,220,140, 47,171,188, 66, 41,111,194,204, 91, 90, 21, 86,135,121,172, 65,248, 77,218,207, 61,203,113,109, 35,140,213,110, 12,
-112,201, 91,220,239, 37, 81,121,158,131,185, 43, 93,167,138,210,248,160,156, 45,128, 61, 11,203, 32,127,166,167,104,185,198,142,
- 57,131, 4,149,214, 83,194,179,163, 80,165, 16, 91, 5, 80,135, 40, 46,133,172,234,206,250,105, 35, 44, 45, 37,136, 25, 43, 5,
-174, 26, 7, 68, 91,101,130, 67,204, 39,114,100, 91,218,175, 40, 53, 14,166,102, 55,114,101,137,224,162,158,235,154, 22,189,125,
- 76,116,214, 71,238,117,221,162,152,242,210,178,195, 69,251, 34,237,204,108, 97, 48, 71, 4,220, 5,218, 96, 5, 6, 69, 49,163,
-133, 3, 4,210, 98,127,156,161, 84,181,255,185,102,157,140,178, 64,207,185, 89,120,157,117,203, 60,221, 3,224,246,253, 40,104,
-171, 60,110,229, 20, 4, 74,215, 30,204,146, 2,243, 92, 39, 67,170, 48,136, 53,133, 83, 47, 60,145,231, 82, 20, 64, 60,102,108,
- 80, 20,114, 76,105,225,139,253,152,140, 18,242,162,214, 13,111, 23,137,171, 24,220, 22,151, 48,231, 98,133, 83, 47, 60,196,108,
-171,155,133, 75, 33,208,184, 58, 40, 71, 49, 73, 35, 37, 84, 68,234,189,205,239,250,228,219,159,196,142,223,209,205, 60, 59,144,
- 11,155,188,188,167, 85, 97,239,201, 30, 81,214,174,119, 80, 80,180,108,172, 23,246,253, 50, 5,228,236,104,168, 4, 73, 33,134,
- 45,160,153,246,243,136,132,173, 6,227,200,164,219, 43, 12, 41,217, 5,206,162, 48, 90,100, 20, 47,158, 82,172, 76,214, 75, 55,
-232, 83, 72, 63,199,173,226,195, 16, 71,153,119,178,111,151,140,148, 3,218, 44, 27,124, 14,165,157, 37, 60,136, 84, 46, 28,161,
-240,180,172,223,203,128, 20, 50,175,201, 84,107,172, 82,202,226,145, 57,200,169,178,173,215,114,152,133, 90,136, 73,151,151,188,
- 91, 25,228,125, 52, 77, 23,161, 27,216, 96,201,122,163,210, 48, 40,193, 63, 22,206,106, 96, 1,157, 49, 19,142,114,230,201, 55,
- 20, 18, 48,135,208, 11,100, 70,205,185,170,130,178, 21, 80,134, 77,135,201,208, 53,212,225,205,160, 37, 53,181, 56,162,168, 71,
-181, 98, 87, 94, 12,201,165,147, 67,114,199, 90,103, 65, 6,177, 95,141, 83, 30,199, 9, 3,152,149,185,227,220,228,157, 10, 73,
- 70,157,108,209, 46, 3, 27,138, 62, 2, 18,178,174,228, 6,245, 62, 30, 66,109,173, 83,177,172,201,235, 96,186,253,108,231,206,
-227, 7,253,245,225,145, 35, 47, 95, 94, 93,154,188,114,242,232, 36, 97,251,247,247,230,213,254,227,103,241, 31,240,246,158, 25,
-131,147, 65, 90, 10,112, 44,192,188,246, 97,206,249, 4, 60, 59, 80,132,139, 81, 30,176, 95, 18,156,178,138,119, 96, 50, 3, 7,
- 58,236,168,205,162,233,240, 31, 3,144, 37,198, 82,183,120,192,138,194, 45,189, 14,180,211,131, 38, 2, 24,211,180,162, 31,160,
-167,104,126,134,132,136,204, 13,245, 45,135, 48,114, 26, 52,248,171, 39,197,245,221, 94,174, 13,149, 98, 42,228, 55,127,248,235,
-189,207, 62,152,172, 79,114,214,108,126,189,125,237,183,231,163,141,211,145,186,129, 33, 33,141, 26, 49,161, 4,110,238,137,179,
-199,110,109,222,126,227,147, 75, 79, 31, 61, 71, 41, 44,228,136, 28,252, 64, 66,103, 83, 38,179, 67,167, 78,244,108,251,246,149,
-155,231,222,189,104,247,227,253, 31,239, 29,219,120, 9,143, 52,145,246,241,115,119,231,198,163,147, 23, 54,158, 62,116, 15,254,
-252,251,237,203,231, 70,249,218,247,223,252,194, 73,149,136,134, 39, 80,207,103, 46,158, 30,142,190,251,226,243, 47, 63,254,244,
-125, 89,136, 27, 15,118,113,230, 46,203,207, 95,122,245,215,171,219, 27,167, 15,223,125,248,239,116,175, 90, 63,179,182,253,199,
- 11, 73, 19,146,117, 40, 3,205, 74,129,183,118,225,247,107, 79, 23, 72,195,168, 99,157,182, 59,184, 83, 23, 86,183,174, 62, 57,
-127,233,248,238,108, 86,237, 4, 87,251,233,110,253,214, 71, 39,149,119,122,216,181,121,183,126,118,101,235,231,157,131,158,189,
-246,206,113, 17,168,219, 11,159,139,111, 30,189,181,181,187,121,229,222,235, 31, 30, 53, 46,253, 95, 0,142,174,166, 55,142, 34,
- 10,246,116,207,116,207,204,238,218,107,175,237,120,109,108, 39,177,140, 33, 72, 86,162,152,143, 3, 2, 78, 32,184,113, 67, 66,
- 66, 2,254, 0,119,126, 9, 39, 46,112, 3, 69, 8,229, 68,136,144, 18, 1,138,136, 72,140,192, 72, 96, 39,193,137, 29,199,118,
- 98,239,236,206, 76,207, 87, 83,229,227,106,165,153, 81,127,188, 87,213,253, 94,149,250,232,227,247,104, 90,164,156, 75,235, 52,
- 87, 18,187, 21,252, 80, 69,182,196,240, 2, 70, 54, 84, 89, 15,171,180, 86,212,208,212,248,219,212,165, 9, 17,231,218,212,186,
- 46, 91, 6, 65, 29,105,176,138, 65, 40, 11, 86, 77,213,237,118,228,192,215, 65, 34,141,153, 60, 45,150,224, 57, 48,146,112, 46,
-165, 46, 26,150,104, 0,217,130,113, 10, 11,176, 91,155,218, 20, 97,204, 43, 62,213, 29, 83,153,171,156, 54, 35,228, 61, 53,230,
-251, 42, 18, 97, 26,106, 17, 73,254,160, 89,133,161, 48, 45,205,119,164, 98, 11, 25,205,247,170,202, 8, 64, 44, 0, 49,182, 95,
- 82,230,189,162,239, 79,144, 87, 8, 36, 50, 32, 5,171,203, 41,101, 3,139,213, 7, 4, 11,134, 9,232,211,180, 68, 2, 80,160,
- 16,174, 36, 5,225,100,208, 68,100,147,141,143, 21,139, 1,196, 38, 48, 5,245, 81, 12,229,194,240,149,181, 17, 60,227,148, 88,
- 41,121,217, 56, 63,169,173, 74,107,191, 35, 11, 47, 23,120,151,215,132, 57,178, 17,251, 65,140,159, 14, 2, 68, 96,160, 89,112,
-213, 36,203,240,204,180,176, 3, 11,154,156,100, 22, 99,210, 36,118,196,190,139,198,123, 74, 47, 73,223,183,217,137,203,101, 1,
-188,169,104,222, 2,196, 76,153, 31,229,106,115,250, 69, 0,149,108,247, 71, 42,168,128, 83,117, 44,192,127, 89, 63,203,170, 65,
- 12,103,141,224,133, 5, 28, 38, 67, 25, 22,163,134,202,167, 30, 11, 13, 17,195,216, 88,224, 70,194, 69, 66, 43,171,148, 9, 70,
-178, 57,103,226,116,247,137,237, 16, 64,177,212, 87,120, 21, 77, 8,189,210,178,195,156,185,132, 82, 1, 30,197, 9,144,248,232,
-170, 13,124, 78, 53, 87, 30,171,102, 34,169,232,204, 72,167, 8,118,178,122,128, 13,216,152,128, 36, 73,229,149,192,174, 44,184,
-164, 23, 18,123,227,216,238, 74, 31,168,154, 10, 89, 60,155,149, 44,116,196, 78, 22,222, 73, 13,164, 89, 96,212,128, 44,188,138,
-173,109, 54,159,106,181,110,215,225,141,223, 83,147, 38, 74,233,145, 86,181,166, 66,120,142,200, 48,244, 75, 4, 0, 4, 5,203,
-251, 61,186, 75,122,212, 63,104,232,235,195, 6, 18,228, 27,164,182, 60, 47,100,164,188, 60, 64, 78,196, 28,210,228,199, 98,135,
- 54, 85,133,240, 16, 59, 26, 65,132,108, 31, 7, 61,140, 77, 38,253, 8, 20, 59, 98,107,152,103,187,202,175,180,107, 33, 71,210,
-224, 41,100,143, 2, 85,165,129,230,157,160, 68,139,170, 69, 64,209, 44, 57, 93, 81,242, 76, 53,222, 24,162,104,164, 34, 76, 60,
- 93,153, 64, 77,104, 50,233,183, 84,228,132, 25, 22,181, 28,183,198, 27,167,186, 89, 29, 25, 23, 96,253,213, 2,145,223,239, 56,
- 74, 31, 81,248,210,199,228, 7, 3,109, 37, 11, 2, 43, 63,160, 74,193,233, 80,199,197,176, 20, 60, 51,106, 78,199, 26,208, 12,
-212,146, 62,182, 50, 15,125, 43, 85,139,109,153, 21, 64, 2,246, 80, 48, 89, 56,222,189, 35,239, 82,178,222,181,100, 91,149, 90,
- 83,223,210, 55, 46, 22,109, 97,219, 29,145, 10,221, 32,247,149,149, 70,252, 29,122, 50,240, 41, 32,225,147,162, 7,202, 13, 53,
-112,139,105,123, 20,202,140, 39, 92, 24,197,174, 8,138,199,135,187,119, 55, 15,110,109, 63, 26,238,247,116,188, 56,127,126,185,
- 55,213,235, 78,133, 21,178, 17, 80,247,113,105, 91, 82, 71, 82, 86, 64,227,188,134,111, 52,120, 65, 45, 11, 95, 14,172,149,126,
-225, 3,211,129, 16,105,169, 89,222,136,233,194,162,113,167,165,240,152, 72, 44, 79, 43,189, 60, 10, 28, 89,181,211, 20, 77,235,
- 86,236,122,161,122,178,147, 45,217,152, 56, 12, 84, 39,100,164,110,129,129,165, 19, 97,199, 87, 51,215, 30,205,127,115,112, 18,
- 68,121, 71,209,120,176,202,196,195,205,157,215,223,190, 88,186,176, 28, 23,157, 78,188,179,177,189,178,182,112,248,224,201,153,
-229,185, 56,108, 59, 59, 28,156,100,171,151,198,162,197,231,158,237,101,119,175,110,204,246, 39, 71, 39,217,210,171,115,120,242,
-222,191, 71,231,223,185, 16,116,199,241,172,139,235,203, 91,119,238,255,124,117, 99,251,207,157,185, 11, 11,171,175, 60,223,237,
- 70,223,126,113,253,191,173,195, 75,151,151,198, 38,163, 23,214,250,191, 94,187,253,221, 87, 63,108,255,117,239,179,207, 63, 8,
-251, 51, 90,208,105,129,226,223,214,188,245,238,229,227,161,253,254,235, 31,127,186,114,107,112,120,242,254,135,111,206, 46,180,
- 23, 87,102, 50, 91, 95,249,242,151,228,241,232,147, 79,223,152,158, 46,142, 14, 70,201,179,242,197,181,121,111, 20,190,244,242,
-236,141,235, 91,191,221,188,215, 63,215, 75, 7,118,253,181,197,103, 73,158,164,249,202,226,153,254,217,246,241, 94,121,231,230,
-206,104,223,206,174,246, 30, 62, 56,182, 73,121,255,143,195,127, 54,159,230, 66,119,195,158,145,246,232, 48,155, 91,152, 56, 59,
- 15, 70, 98,189, 25,181,243,119,182,188, 62, 61,177, 20, 15,247,237,193,110,222, 95,152,248, 95, 0,142,174, 45, 69,178, 34, 10,
-230,205,231,205,188,143,238,174,238, 65, 65, 84, 28, 28, 16,193,239, 89,128, 63, 46,195,101,249,229, 22, 68, 65,230, 99, 86, 32,
- 46, 65,127,132, 65,212,161,171,166,238, 43,159, 55,175,113,138,130,254,172,162,243, 17, 39, 34,243,100, 68,243,246,247, 31,230,
-184,204,117, 58, 22, 19,234,198, 66,212,151,137,157,154,203,127,105, 91,138,222,195, 7, 91,235, 30,204, 7, 8, 37,185,218, 44,
-188,208,159,242, 1, 74, 18,136, 97, 88,255,168,239,248, 8,198,150,157,115, 67,180,141, 17, 2, 12, 24, 44, 30,220, 34, 73, 37,
- 33,115,169, 31,126,107,148,139,177,118,124, 57, 79, 71, 22,210,243, 11, 86, 69, 8, 11, 54, 33,168,157, 7,126, 79,207,239,121,
-255,113, 58,111,178,178,208,111,244, 24,102, 81, 61,229, 36,233,150,135, 3,188, 7,179,222,113,191,147,157,159,242,182, 16, 1,
- 53,236, 18,223, 25, 55, 86,159,232,129,227,190, 8,217,241, 38,129,233, 16,160,241, 90, 12, 61, 51, 98,254,228,250, 6,122,143,
-211, 57, 77, 30,236,232,219,106,120,122, 65,130,187,247,224,172,234,228,116,150,222, 81,112,136, 93,114,167,221, 53,241, 81,113,
- 62, 86,150, 56,221, 76,138, 20,111, 73,202, 96,122, 81,144,126, 20,244, 62,132, 53, 38,133,184,235,173,110,142, 89, 95, 39, 54,
- 67, 31, 66,189,207, 41,133, 80, 14, 57,165,231,176,146,121,196,148, 82, 61, 31, 87, 61,175,229, 41,167,205, 63, 47,183, 24, 23,
- 12, 78,153, 83,165,126,115, 58,238,209,139,239, 78, 61,246, 51, 24,146, 26,120,207, 99, 14,218,218, 67,182,205,193,155, 78, 21,
- 33, 29,176, 84,215,141, 18,255,110,119,123,100, 77,122,200,104,119,179, 78,115,166, 6, 50,138, 43, 75,248,238, 29,176, 14,172,
- 5, 16, 64, 68, 50, 17,130,167,174, 86, 93,221,183,223,124,245,207,219, 55,139,140,236,100,238,200, 92, 91,130,208,131, 41,165,
- 51, 91,111,174,110,225, 90, 21,148, 50,249, 26, 28,113, 42, 30,123,114,193, 0,100,128,253,180, 30,235, 5, 5,183,233,107,189,
- 6,166, 14, 58, 18,219, 41,164,147,210,176, 0,133, 45,121,123, 80, 64,134,225,228,145, 78,102,106,166, 90, 69, 23, 99, 16,158,
-152,177,106,171,236, 36, 37,147, 43,240, 21,138, 37,102,245, 80, 45,126,208,191,124,253,201,155,236,126,254,229,250,100, 98,164,
-254, 88,186, 29, 74, 4,211, 21, 75, 96, 66,141, 75, 40, 17,140,252,118,168,223, 19,128,236,201, 1,139,236, 29,107,102, 71,238,
-119,204,213, 0,228,152, 1,129,138,129, 28,154,198, 67,225, 23, 86, 28,181,207,235, 2,102,132,145, 66,245,237, 26, 53,202, 3,
- 84,249, 14,245,147,185,184, 68,117, 15, 94,113,160,252, 12,178, 3,228,135,226,172,241,187, 82,183, 8, 37, 0, 49, 45,159,251,
- 70, 23,166,195, 56,203,125, 24,240,131,160,162,117,196, 2,178, 59, 47,253, 50, 6,237, 41, 0,142,152,186,170,208,200,190, 11,
-210,203,214,147,243, 47, 96, 46,243,178, 47, 94, 31, 3,101, 99, 81,163, 36,202, 86,218,200,105, 12, 75,164,250,171,208, 42, 1,
- 57, 51,228, 18,102,140,142, 45, 26,212, 43,176,124, 50, 55, 84,194, 67, 83, 37, 89,107, 22,153,220, 35,178,224,122,192,138,121,
-112,226, 25,211,245,120,180,129,245,162,167, 59,240,212, 13,242, 22,113,102,177, 39,142,169, 4, 39,123, 40,243,187,176, 71, 5,
-140,204, 87,182,221,227,147, 47,246,100,114,164,160, 79,112, 54, 6,241,184, 20,234,214, 9,187, 49, 91,245, 45, 4,233, 4, 1,
- 25,150,120,142,190,149,159,191,248,236,245, 71, 79, 95,188,122,124,121, 58,179,229,221,249,175,127,207,127, 95,118, 65,177, 32,
- 96,110,168, 85,224,131,102,144,208, 29,162,241,100,134,178, 65,254,239,108,196, 16,198,178,217,250,160,243,177, 97,239, 80,195,
-191, 30,205,150, 41, 85,230,206,210, 35,149, 66,175,210, 48, 40, 10, 59,173, 23, 34,117,236,230, 32,107, 21,230, 75,139,163,104,
-214,140, 35, 52,226,151, 63,253, 33,127,155,114, 41, 27,170,128,125, 40, 91,166,119, 11, 13,254, 83,253, 88, 99,202, 98, 70, 5,
-206,148,132,166,184,219, 68, 35, 34,232, 20,198,137,187,234,207, 31,154,214, 30,105,158, 89,117,169,219, 91, 85,115, 20,168, 66,
-124,117,252, 94,100,138,164,233, 92,199,120,111,249,238, 93,215,231,209, 90,186, 47, 29, 80,211, 37, 15,248, 99, 76, 67,206, 42,
- 0, 51, 69,111,106,201,110, 12,120, 2,238, 71, 29,162,169,145,244, 92, 40, 86,185,228,198,145, 71, 27, 25,161,121,190, 65,245,
- 69,234, 20,243,105, 93, 53,111,195,178,222, 94,142,148,162,215,210, 56,243, 62,231,118,158,247,129, 56,159, 36,179,116,104,155,
-163,217, 84,166,131, 55,147,197,202, 82,194, 30, 0, 69, 34,107,211,131, 60,150, 64,167,115, 18,107,153,127,253,241,207,239,190,
-255,218,118, 92,172,144,169,160,174, 5,155, 54,155, 38,158,233,205,133, 50,245,127, 1, 72,186,150, 29, 57,138, 32, 88,213,245,
-236,199,244, 88,172,144,204, 2, 22, 88,252,143,239,220,249, 67, 78,156,248, 3, 11,203, 7,176,132,100,241, 16, 8,105, 97,215,
- 51,211, 93,239, 34,162,125,107,205,238,106,180, 85,149,153, 17,213,153, 17,234,219,239, 94,213, 28, 5,223, 84, 81,169,240,218,
- 76, 77,237,134, 88,170,125,215,143,114,143, 33,106,212,252,173, 63,230, 37, 34,191,142,186, 95, 84, 11, 56,242,186,211, 40, 85,
- 79, 36, 6, 64, 96,200,235, 44,180,182,116,121,165,134, 55,137,252,164, 38,118, 71, 89,205,119, 44,136,101,147, 91,126,164,238,
- 88, 79, 32,138,195,226,144,163,162,228,160, 10, 29, 57,218,120,114,206, 93, 3,190,196,118,135,253,241,212,123, 70,150,152,168,
- 73,136,133, 65,152,205,128, 8,207,116, 25,171,193,241,174,202,141,121, 25,210,121,180,169,251,185, 12,218, 99,101, 17, 73,244,
-235, 18,179, 22,163,144,225,132, 50, 96,219,197,243,159,162,101, 13,184,144,105, 0,115, 32,146,158,183,185, 17,143,156,114, 92,
-130,202, 30,104, 14, 48,100, 8,249, 24,202,235, 19,173, 4, 4,219, 47,164, 13,117,180,133,166,209,130,198,205, 38,227,124, 37,
-226, 71,153,145, 94, 69,168, 73, 7,221,120,253, 0,202, 85, 31,203,195, 30,183, 22, 93, 2, 36, 6,103,255,119,111, 91,111,225,
-150,110, 72, 89, 25,101, 52,129,176,231, 28, 3, 78,128,228,184,106,160,187,118,221,155,188, 37,161, 20,177, 44,210, 32,130,247,
-169, 6,172, 36,125,225,216,127, 71, 77, 14,187, 32,171,157, 61,206, 17, 18,163, 7, 34,100,166,191,109,192,239,125, 35, 54, 99,
- 99, 58,176,132,108, 45, 53, 15, 56,148,168, 72,166,105, 70,198, 57,213, 1,201, 66,148,251,151,159,245,183,239, 26, 80, 52,205,
- 49,228, 97,213, 35, 3,182,147, 55,165, 2,128, 30,235,162,252,144, 14,198, 71, 39, 38, 94, 22,136,124,163,253,105, 52,101,220,
-100,247,200,188, 77, 83,102, 22,112, 60, 31,246, 5,156,121, 97, 18, 63,166,186,204,113, 75,243,241,142, 24, 16, 17, 20,135,134,
-153,182, 69, 26, 88,137,169, 85,189,247, 43, 85,246,187,176, 32, 77,160, 70, 89,216,116,250,230,235, 55,127,234, 95,127,122, 56,
- 61,115, 84,165, 75,188,241, 23, 32,123, 33,130,147,149, 84,113,142,168, 70, 68,106, 40,226, 78,135, 74,202,144, 88, 14,114,130,
-198,225,208,120, 78, 17,250, 98,134,120,248,143,162, 6, 44,192,215,159,186, 30,207, 20,253, 24,143,233, 1,103,233,199, 61,168,
-228,195,128,159,118,191,144,191, 40,124,156,239,240,183,137,222,148, 82,118, 58,178,149, 10,160,172, 13, 37,124, 29, 77,198,199,
- 37,201,225, 84, 38, 79,191,223, 18,205,236, 20,251, 94,104,245,154, 79, 42,124, 50, 40,181,143,116,151, 95,197, 74, 91,137,170,
-147,243,244,140, 4,239,178,213, 96, 85,151,105, 5,155, 10,209,245,238,187,104, 31,212,164,105,112, 32, 19, 69, 44, 64,228, 34,
-219,127,246, 33, 53,222,139, 9,142, 67,160, 60, 87,206,141, 90,199, 70, 68,118, 67, 97,155,200, 53,112, 48, 42,242,121,193,250,
- 72,183,206, 8,208,109,156, 28,123,242,124, 89,118,107,176,175, 70,122,169,102,187,142, 11, 85,183, 27, 74, 32, 73, 91,192,179,
- 25, 85,201, 1, 49,187,123, 58, 29, 56,121,183, 95, 64, 8,104,192, 13,150, 33, 85, 97,203,144, 88, 7, 36, 66,131,165, 40, 70,
- 92,175,127,191,249,237,253,143,111,127,127,253,190, 62, 60,124,245,242,203, 23,159,127,225,205, 18, 47,151,173,246,160, 38,223,
- 15,165, 98,113,204, 18,161,200,180,189, 97,119, 20,157,114, 72,202, 5,149,157,135,206,102, 36,170, 1,149,130,231, 73,114,212,
- 2,185,192,154,211,196,110, 33,229, 57, 10,135,128, 95,170,183,160,112,156,200,192, 17,186, 59,207,123,126,254,195,207,250,251,
-191,254,120, 58,229,133, 30, 39,235,189,223,106,156, 62, 76, 84,189, 67, 73, 18,122,159, 91,222,232,115, 15, 54, 15, 44, 36,234,
- 13, 57, 66, 37, 80,206, 60, 92,233,246,217,182, 44, 79,177,239,136, 46, 61, 73, 51, 92, 80,190, 81, 22, 98,187, 43,147, 50,227,
-126,190,173,221,204,244, 25,114,236,127,194,118,217,131,199, 86,117,200,221,233,177, 88,190, 50,160, 9, 68, 57, 68,212,164, 25,
- 39, 32, 34,222, 73, 10, 43,188,220,105,253, 83,240,139,200, 24,146, 23, 35, 84,136,161,193,100, 53, 88,248,217, 92,193,234,229,
- 85,249, 66, 63, 98, 69,241, 89, 17, 16, 37, 28, 5, 12,219, 19,223,161,138, 86,216,198, 23,118,156, 56,172, 76,226,188,239,208,
-116, 93,207,179, 6, 73, 66,130, 65, 93,161,103,164,248,231,151,255,206,171,187,127,113, 6,102, 82,161,115,110,191,155,126,163,
- 91,189, 2,180, 70,248,172,249,127, 1, 6, 0,223, 79, 84,236,136,122,237,252, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+255,216,255,224, 0,
+ 16, 74, 70, 73, 70, 0, 1, 2, 0, 0,100, 0,100, 0, 0,255,236, 0, 17, 68,117, 99,107,121, 0, 1, 0, 4, 0, 0, 0, 95,
+ 0, 0,255,238, 0, 14, 65,100,111, 98,101, 0,100,192, 0, 0, 0, 1,255,219, 0,132, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2,
+ 2, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 2, 1, 2, 3, 2,
+ 2, 3, 4, 4, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,255,192, 0, 17, 8, 1, 26, 1,
+245, 3, 1, 17, 0, 2, 17, 1, 3, 17, 1,255,196, 0,225, 0, 0, 1, 4, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 4, 5, 6, 8, 0, 3, 9, 2, 10, 1, 11, 1, 0, 0, 7, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
+ 4, 5, 6, 7, 1, 8, 9, 10, 16, 0, 1, 3, 3, 3, 2, 3, 4, 6, 6, 5, 7, 6, 12, 2, 11, 1, 2, 3, 4, 17, 5, 6,
+ 0, 18, 7, 33, 49, 65, 19, 8, 81, 97, 34, 20,113,129,145,161, 50, 9,177, 66, 35, 51, 21, 10,193, 82, 52, 22, 23,209,225, 98,
+114,130, 36, 53,240,241,146, 67, 83, 54,162,115,131, 68, 37, 38,150,182,214, 55,151, 26,178, 99, 24,194,179,100, 69,118,166,198,
+ 39, 56, 25, 17, 0, 1, 3, 2, 4, 2, 6, 7, 5, 4, 9, 3, 2, 5, 5, 0, 1, 0, 2, 3, 17, 4, 33, 49, 18, 5, 65, 6,
+ 81, 97,113, 34, 19, 7,240,129,145,161,209, 50, 20,177,193, 66, 35, 8,225, 82,210, 21,241, 98,114,130,146, 51,211, 36, 22, 67,
+ 52, 23,162, 83,178,194, 85, 24, 9,226,242,115, 37, 53,255,218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0,251,244,208, 65,
+102,130, 9, 5,217, 87, 36,218,238, 74,179, 34, 43,151,116,192,150,171, 83,115,148,164,194, 93,196, 54,175, 32, 60, 81, 85,132,
+ 23, 41,184,167,173, 59,105,181,233,152, 67, 39,211,233,241,116,157, 26,171,167, 85, 59,181,166, 52,173, 43, 78, 9,213,136,132,
+205, 31,212, 23, 8,181, 13,122,105,171, 77,123,218,107,133,105, 90, 87,138,228,238, 3,235,143,148,184,187,145,110,248, 15,170,
+123, 51,141, 48,110, 14,165, 55,139,117,149,168, 50,241,244, 56,175,217,148, 53, 25, 8,110,124, 50,159,194,234, 55, 46,157,106,
+179,208,120,171,150,191, 81, 59,207, 36,238,210,237, 92,239, 9,104,212,105, 35, 88, 1, 96, 57, 80, 52, 1, 36, 71,131,155, 87,
+127,107,135,183, 57,155,244,227,178,243,198,209, 22,237,200,211, 7, 29, 34,177,185,228,137, 8,206,165,196,152,229, 28, 90,234,
+ 55,169,185,158,172, 99,217, 21,139, 44,179,192,200, 49,171,180, 27,221,150,230,194, 36,193,185, 91,100,166, 84, 73, 44,172, 84,
+ 20,173, 4,142,157,136,238, 15, 67,215, 94,208,219,119, 43,125,226, 6, 92,218,200,217, 34,120,171, 92,210, 11, 72, 60, 65, 11,
+196,251,150,217,113,179, 78,251, 91,184,221, 28,172, 52,115, 92, 8,112, 35,129, 5, 60,233,242, 98,179, 65, 5,154, 8, 44,208,
+ 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4,
+ 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,
+102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,
+104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,
+130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 46,110,250,156,129,235,110, 79, 36, 72, 95, 16,221,151, 15,
+143,126, 70, 10,108,173, 88, 38, 67,132,250, 94,242,211,243, 31, 59,243, 32, 58,183, 11,251,138, 72, 37, 59,118,210,134,186,242,
+199,155, 27, 63,152,251,134,236,231,114,252,205,109,142,150,232, 12,124,108, 53,167,123, 94,188, 75,181, 86,148,168,165, 41,141,
+ 87,171, 60,165,222,124,182,219,182,150,183,152, 97,115,175,181, 59, 89,123, 36,120,165,123,186, 52, 96, 27,166,149,173, 13,107,
+194,138,129,103,252,247,234,239,140,239, 7, 30,203,185,102,239, 14,248,218, 66,228,218,226, 94, 32,220,165,193, 10, 0,164, 72,
+ 75, 8,112, 50,165, 3, 80,149,144,105,214,148,166,188,187,206, 62, 97,243,231, 34, 92,253, 38,225,186, 17, 53, 49, 99, 36,142,
+ 66,222,141, 90, 65,210, 79, 0,113,166, 52, 94,167,228,207, 46,121, 7,159,109,190,179,110,218,129,130,184, 61,241,203, 24,119,
+ 78,141,100, 23, 1,196,129, 74,225, 84,206,246, 41,234,175,212,188, 11,109,202,237, 6,251,153,192,137,230, 61,105,186,222,154,
+137,111, 86,199,133, 21,228,188,226, 89,117,104, 93, 7, 64, 74, 73,235,223, 64,114,119,152, 30,115, 91, 69, 61,196,114, 77, 8,
+239, 70,249, 76,113,212, 30, 44, 46,210,226,211,213,221, 43,167,156,252,189,242, 90,234, 91,123,121, 35,130,115, 70,200,200, 68,
+146, 80,142, 15, 13,212,208,225,215,222, 25, 41, 15, 29,114, 39,168, 79, 69,153, 20,102,114, 44,114,237, 31, 17,187,203, 42,184,
+226,247,133,111,177, 93,202, 0, 14, 46, 28,148, 23, 27, 98, 66, 81,215,114, 15, 94,155,146, 69, 52,235,150,121,143,155,127, 78,
+ 23, 77,101,253,179,197,156,142,239, 70,226, 12,111, 60, 76,111,110,166,181,244,232,207,241, 2, 50,105,204,252,183,202, 31,169,
+ 75, 87,191,111,185, 97,188,141,189,217, 90, 8,145,131,128,145,142, 13,115,153, 94,145,135,225,112, 57,246,143, 15,245, 5,129,
+230,252, 59,120,230,123, 11,147, 38, 88,113,220,118,249,126,191, 90, 89,109, 6,249,110,123, 28,136,185,114,225, 41,181,173, 13,
+249,201, 66, 40,138,172, 37, 85, 4, 43,105,174,190,140,249,123,205,182, 94,101,217,193,123,182,190,172,149,193,148, 56, 22, 63,
+ 0, 88,241,141, 11, 73, 21,165,106, 40, 69, 65, 11,230,231,152,188,165,123,229,133,229,197,150,230,202, 62, 38,151,213,184,135,
+176, 2, 67,216, 77, 42, 28, 1,165,105, 67, 80,104, 65, 67,143, 70,222,182,248, 47,215, 87, 26, 75,229, 46, 10,184,228, 18, 44,
+182,187,203,152,237,246,217,148,216, 92,199,239,150, 75,235, 44, 49, 33,113,221,108,169,214, 93,218,212,132, 31, 49,135, 86,131,
+ 90, 5, 84, 29,105,220,219,202, 23,156,151,114, 45,111, 67, 67,203,117, 2,211, 80, 91, 82, 43,211,192,224, 64, 43, 43,228,206,
+118,177,231,187, 67,121, 96, 92, 88, 29,164,135, 55, 73, 14,160, 52, 60, 14, 4, 98, 9, 29,104,205,205,156,211,199, 62,158, 56,
+195, 43,230, 62, 90,190,171, 25,227,220, 38, 28,121,249, 37,241, 54,233, 55,101, 64,139, 41,246,163, 33, 95, 47, 17,167,228, 57,
+185,231,144,154, 33, 7,189, 79, 74,234, 43,103,218, 46, 55,235,150, 90, 90,183, 84,175, 52,104,168, 21,194,185,154, 12,130,153,
+222,247,187,110, 93,181,146,246,237,218, 97, 96,171,141, 9,160,173, 50, 0,156,202, 77,193, 92,235,198, 30,164,248,191, 25,230,
+ 78, 28,200,255, 0,189,124,123,151,183,112,118,193,123, 54,233, 54,133,204, 69,178, 91,240,158, 38, 52,198, 88,146,214,217, 17,
+156, 72,222,129, 90, 84, 84, 16, 79,119,157,154,227,151,238, 95,103,118,221, 50,178,154,133, 65,165, 64, 35, 16, 72,200,133,205,
+139,124,182,230, 75, 72,239,108,223,174, 23,215, 75,168, 69,104, 75, 78, 4, 3,152, 60, 17,119, 81,106, 89,102,130, 11, 52, 16,
+ 89,160,130,165, 28, 23,235,243,211,247,168,206,127,230,191, 78, 92, 93, 55, 41,186,102,220, 5, 38, 77,183,144, 46, 87, 28,121,
+ 86,124,109,171,228, 11,140,139,100,152, 80,222,125,196,200,148,184,242,162,172, 41,192,192,108,138, 20, 45, 85,213,187,123,228,
+155,238, 94,177,182,191,186, 13, 17,220, 98,192, 13, 93, 77, 33,192,154, 96, 42, 8,194,181,233, 10,149,176,115,238,223,204,183,
+247, 91,117,161,121,146,216,210, 66, 91, 70,212, 56,180,128, 78, 38,132, 28,105, 78,130,174,190,170, 42,234,179, 65, 5, 18,207,
+179,172, 87,140, 48,124,195,146, 51,171,187, 24,254, 23,128,227, 23,204,199, 44,190, 73, 66,221, 98,211,142,227,113,157,153, 50,
+ 66,144,210, 86,235,158, 84,118, 84,173,136, 73, 81,165, 18, 9, 32,105,213,141,148,187,148,209,219,194,221, 82, 61,193,173, 29,
+ 46,113,160, 30,178, 83, 77,194,254, 45,174, 9, 46,103,118,152,227,105,123,143, 67, 90, 42, 79, 78, 0,112,197,124,234,175,243,
+234,230,254, 83,184,223, 47,222,147,191, 45,222,101,230,158, 32,199,174, 50, 33,185,157, 72,185, 92, 89,184,222, 4, 93,170, 90,
+ 4, 91, 54, 61,122,137, 9,224,223, 82,202,101,200, 88, 10, 73, 82, 71, 99,188, 59,201,107, 13,164, 54, 61,215,119,130, 11,135,
+ 10,232,238,208, 87,173,207, 97, 35,175, 75, 71, 90,243,179,124,247,220, 55,146,249,118,125,146,226,226,217,166,154,234,234,154,
+112,163, 35,120, 6,156, 53, 56,226, 48, 93, 31,252,188,255, 0, 52,110, 28,252,192, 96,101, 22, 91, 30, 57,127,226,190, 97,192,
+ 67,107,206,120,151, 45,125, 19, 46, 22,248,142, 57,228,252,228, 9,136,109,129, 62, 50, 36,254,193,210,182, 90,117,183, 5, 28,
+101, 1, 77,169,116, 14,124,242,226,239,145, 29, 27,164,123,101,130, 79,146, 70,228,120,208,140,104,105,136,196,130, 50, 38,134,
+154, 71,151,126,104, 89,121,134,201, 25, 27, 29, 21,196, 95, 60, 79,196,129,149, 65,195, 80,174, 7, 0, 65,205,162,160,158,156,
+107, 60, 90, 98,205, 4, 21, 7,245,151,249,132,240,255, 0,163, 92,155,131,248,239, 38, 98, 70, 97,202, 92,245,200,152,142, 25,
+138, 96,118,107,139, 80,174, 22,204,127, 33,185,177,110,149,144,220, 92, 90, 29,249,104,112,214,246,214,134,194,167,221, 30, 91,
+ 96, 37, 46,184,213,219,148,249, 22,239,155, 34,185,184,140,232,134, 8,220,247, 60,138,130, 90,210,224,198,244,184,211, 31,221,
+ 24,156,192, 52, 30,114,243, 10,207,147,166,181,181,148, 23,207,113, 43, 24,214, 2, 1, 1,206, 13, 47,119, 67, 69,112,194,174,
+ 56, 12,137, 2, 15,204,131,243, 64,183,126, 94,239,240, 12, 37,112,134, 65,205, 87, 30,125,127, 62,139,100,183,227,217, 82, 49,
+217,182,233,152, 66,241,246,208,202, 25, 54,219,139,147, 92,158,229,253, 9,109, 8, 9, 32,162,148, 81, 80,164,175,151,190, 93,
+ 59,159, 91,114,255, 0,169,108, 45,128, 48,146,230,212, 16,237,120,215, 83,104, 6,140,107,211,212,162, 60,203,243, 61,190, 93,
+ 58,209,159, 74,233,221,112, 94, 26, 26,237, 36, 22,104,194,154, 93, 82,237, 98,128,116,117,170, 48, 63, 62,142,100, 34,163,242,
+177,245, 58, 65,236, 68,155,169, 31,251,155,171,143,254, 23,178,255, 0,235,118,191,250,127,213, 84,127,252,237,127,255, 0,208,
+ 47, 63,245,255, 0,164,187,249,196,249,211,252,153,198,184, 38,127, 47, 29,184,226, 51, 51, 28, 67, 26,201,230, 98,183,125,223,
+197, 49,185,119,232, 76,202,114, 4,157,237, 48,191, 54, 26,221, 45, 57,185,180,157,201, 53, 74,123, 12, 63,112,181, 22, 55, 18,
+194,215,135,134, 61,205, 14, 25, 59, 73, 35, 80,207, 3, 74,140, 74,244, 6,219,118,111,237,162,157,204, 44, 47, 99, 92, 90,115,
+105,112, 7, 73,192, 98, 43, 67,128,236, 68, 45, 51, 79, 86,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,
+130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8,
+ 38,155,158, 65, 97,178, 41,148,222,111,118,139, 74,164, 5,170, 58,110,119, 38, 96, 41,244,183, 64,162,128,234,209,187,109, 69,
+105,165, 99,133,242,252,173, 39,176, 85, 20,184, 55, 50,146,197,203,113, 89,217, 4,252, 74, 22, 77,143,204,202,173,118,248,151,
+107,158, 51, 22,243, 26, 70, 65,110,181, 79, 52, 98, 75,240,144,225,146,203, 79,159,221,184,180, 4,171,192,157,117,214,210, 49,
+130, 66,215, 6, 19, 64,104,104, 72,204, 3,149, 66, 1,224,154, 84, 85, 72, 52,138, 50, 97,200,242,188, 95, 15,130,205,211, 45,
+201, 44, 24,181,182, 68,248,118,184,247, 28,142,241, 30,201, 5,251,157,193, 91, 35,198, 67,210, 92,105,181, 58,250,254, 22,219,
+ 7,114,143, 64, 14,150,130,222, 75,147,166, 54,185,198,149,160, 4,154, 12,206, 28, 2, 43,158, 25,137, 52, 79,218, 69, 25, 51,
+ 77,200,241,235,108,182,237,247, 27,245,150,223, 61,208,218,154,133, 54,232,196, 89,110,165,226, 82,130,150,220,113, 43, 86,229,
+ 2, 5, 7, 83,165, 89, 3,228, 26,154,210, 71, 72, 5, 20,184, 12, 9, 79, 58, 73, 25,102,130, 9,181,119,171, 59,119,136,248,
+235,151,107, 98, 50, 9,150,201,183,168,150, 37,207,105, 55,137, 86,123,115,172, 49, 34, 91,113, 74,252,245,178,195,242,153,109,
+199, 82,157,169, 82,208,146, 65, 82, 65, 80, 68,226,210,250, 29, 32,210,180,194,166,164, 10,229, 82, 1,195,168,174,106, 21,167,
+ 20,178, 76,152,208,163,189, 46,100,134, 34, 69,142,218,158,145, 38, 75,169, 98, 59, 13, 32, 85, 74, 90,212, 66, 82, 0,238, 73,
+209, 26,210,227, 64, 42, 87, 73,162,221,174, 32,179, 65, 5,154, 8, 33, 71, 32,242,246, 43,128,218, 46, 87, 91,141,194, 44,120,
+ 54,135,151, 30,247,144, 92, 75,145,113, 44, 95,201, 65,113,215,110,119, 0,133, 50,194, 88,105, 37, 75, 64, 37, 67,160, 33, 59,
+129,215, 90,210,227, 65,154, 4,209,113,219,153,191, 53, 59, 98,175, 87, 12, 35,128,176, 46, 68,230,156,165, 46,155,108, 44,234,
+229,123,184,113,166, 1,243,238, 44, 52,236,168,118,219,114,162, 92,166,196,142,162,165,163,205, 80, 42, 66,127,122,106, 22,171,
+189,159, 38, 56,198, 37,185,126,129,208, 26, 77, 59, 78, 94,202,244,102,161,101,222, 6,173, 49,182,167,183,238,248,209, 59,187,
+249,144, 51,109,178, 90, 45, 95,220,251,230,119,121,131,104,182,162,239,150,195,230,123,149,182,197,117,186,165,132, 9, 15, 67,
+ 54,216,177,131,241,203,149,242,220,232, 20, 62, 33,184, 29,197,252, 28,130, 37, 26,140,196, 52,229,221,198,156, 43,222,193, 55,
+126,251,167, 0,204,123,127, 98,191, 62,141, 61, 83, 91,125, 77, 88, 51, 89, 17, 45,247,123,124,188, 46,241,108,129, 41,171,131,
+205,221,162,165, 23, 72,254, 96, 67, 23, 54, 91,101, 19, 3, 79,180,243,100, 56,216,113, 59,104,178,162,119, 26,182,253,177, 59,
+100,120, 26,195,154,234,208,241,194,149,168,245,244,169, 75, 27,209,122, 9,161, 4,102,174,134,160, 83,229,169,247,216,138,195,
+210,100,188,212,104,209,218, 91,207,200,125,192,203, 12, 50,208, 42, 82,214,181, 16,148,165, 32, 84,146,122,104,146,202,216, 90,
+ 94,242, 3, 64,169, 39, 0, 0,204,147,192, 35,197, 19,167,112, 99, 1, 46, 38,128, 1, 82, 73,200, 0, 51, 43,147,254,168,125,
+125,121, 78,207,227,158, 2,147,243,151, 7, 22,253,178,235,200, 17,219, 18, 27, 67,171,253,153,106,204,154, 40, 60,162, 73, 2,
+ 77, 41,255, 0,102, 15, 69,143, 18,121,199,250,155, 33,206,218, 57, 92,235,144,146,199, 78, 5,113, 56,105,132, 99,168,159,223,
+255, 0, 0, 56, 57,123,139,201,159,210,248, 44,102,241,205, 35, 68, 96, 7,182,220,154, 96, 49,213, 57,195, 72, 25,232,207,247,
+200,197,171,154,156, 81,143,140,227,153,241, 27, 6, 90,185, 50, 85,123,203, 27,106,252,110, 78, 45,114,229, 72, 11, 91,143, 33,
+245, 44,239, 42,117,196, 20,174,166,181, 58,242,183,150, 91, 35,121,159,154,236,172,183, 74,184, 62,227,243, 67,235, 87, 22,213,
+206,107,171,141, 92, 70,147, 92,113, 94,174,243, 63,124,119, 43,242,157,237,238,214, 90,211, 29,183,229, 22, 82,141, 14,163, 90,
+230,211, 10, 52, 59, 80,166, 24, 46, 63,126,115,190,174,253, 69,187,235, 47,147,120, 22,221,152,102,124, 97,197, 28, 37, 50,211,
+137,225, 56, 38, 45,120,151,139, 91, 46, 49, 4, 24,146, 77,230, 82, 34,173,143,157,114,226,183,188,214,156, 93, 66, 91,216,148,
+ 80, 2, 79,233,159,201, 94, 73,218,236, 54, 59,123,134, 67, 27,228,145,181, 46, 45, 7, 77, 9, 1,141,253,208,208, 41, 65, 76,
+ 87,229,183,207,142,124,221,247, 13,254,230,214, 73,165,100, 81, 58,141,104,115,134,170,128,226,247, 99,222, 46, 38,181, 53,194,
+148, 87,163,242, 76,245, 15,204, 62,167,120,195,212,247,166,158,119,200,242, 46, 74,227,204, 19,143, 25,228, 14, 63,204,114,249,
+174, 94,238,220,121,145,177,243, 9, 68, 54,174, 50, 60,199,203, 79,134,188,246,218, 91,132, 32, 33,208,145,181,106, 26,243,199,
+235, 83,203, 45,151,115,216, 36,115,163,100,110,146, 57, 73, 0, 1, 71, 70,194,246,202, 6, 64,180,224, 72,204, 26, 21,233, 79,
+208,191,154,155,230,221,191,199, 24,150, 73, 27, 28,145, 0, 92, 73,238,200,253, 15,136,156,200,120,196, 2,112, 34,161,116, 11,
+210,174,117,114,179, 88, 61, 67,225, 94,123,202,179,100,220, 19,201, 19,215, 23,121, 44, 55,114,181, 90,228,165, 14, 4,246, 73,
+ 83, 79, 40, 19,227, 64, 60, 6,190, 85,126,135,249,138, 91,110, 99,147,107, 36,152,165, 12,144, 14, 1,236,145,162,180,225, 86,
+184,130,120,208,117, 47,173,191,174,174, 93,134,231,150,153,186, 0, 4,177, 23,199, 94, 37,146, 70,243, 74,241,163,154, 8, 28,
+ 42,122, 87, 26,255, 0, 39,175, 68,254,164, 61, 95,240,231, 34, 51,131,250,189,228,127, 78, 92, 87,139,103, 82, 91,143, 96,227,
+ 25, 14,195,184, 95,179,153,144, 97,173,249,183, 7, 35, 77,183,184,182,152,140,152,232,105,181,173, 85, 59,246,249,125, 74,254,
+228,121,183,206,150, 28,167,127, 16,147,111,138,226,119,198, 9,116,153, 53,129,198,141,109, 67,177, 38,164,156, 56, 86,188, 62,
+ 10,249, 47,200,155,143, 57,109,211, 24,247, 41,109,109,217, 41, 1,177,102,233, 11, 91, 87, 58,133,184, 1,164, 1,143, 26, 83,
+139,110,125,234,203,213, 95, 30,113,215,230, 45,249,105,122,151,229, 41,252,233, 19,143,240,155,171,152,134,127,121,146,229,210,
+247,109,185, 96,247,235, 26,212,129, 53,242,185,142, 69,184,192,127,204,242,100,184,181, 50,224, 9, 74,168, 85, 87, 54, 92,179,
+182, 95, 92,109, 60,197,183, 66, 32, 50, 72, 3,152, 48, 4, 61,143,224, 48,171, 92, 41, 80, 5, 70, 52, 77, 47,249,175,117,219,
+237,183,158, 88,220,231, 55, 2, 40,201,100,135, 18, 11, 30,206, 39, 26, 57,166,180, 36,233, 56, 85, 0, 81,235,155,155, 49,207,
+ 79, 94,137,125, 28, 96,249,247, 37,113, 95, 19, 61,137, 77,204, 57, 66,243,194,204,188,190, 83,203,220,201,242,220,141, 43,141,
+ 15,200,122, 59,175, 55, 10, 12, 80, 89,142,135, 18,149,186,181, 23, 55, 4, 32, 9,129,201,118,146,223,238,155,196,209,197, 44,
+254, 38,152,196,180,240,219,166, 40,241, 53, 6,149, 39, 19, 76, 0, 20,204,168, 71,115,221,236, 59,118,211,178, 67, 44,177, 91,
+248,122,164, 48,130,101,126,169,100,193,180, 32,144, 26, 48, 21, 21, 36,214,180, 8,219,108,245, 89,202,222,150,121,159,136,249,
+ 27,209,118,117,235,243, 59,196,209,113, 76,126,102,227,159, 83, 24,125,194,241,141,223,109,107,121,128,226, 99,165,183, 37, 50,
+179, 42, 50,158, 1,126, 82, 28,101,105, 66,208,179, 82, 4, 49,229,203,110,101,178,158,223,122,102,222,201, 41, 88,159,110,224,
+ 8, 52, 57,214,135, 3, 78, 36, 16, 72, 33, 78, 55,154, 46,185, 86,254,222,231, 98,126,229, 36, 85,164,209,220,177,197,174, 21,
+ 25, 82,163, 17, 94, 0,180,128, 65, 87,147,138,249, 83,243, 5,252,196, 61,108,250,205,244,177,104,245,141,155,113, 15, 4,224,
+ 92,151,200, 43, 82,177,107, 29,186, 14,105,107,196,237,121, 20,232, 54,155, 61,178,116,102, 33, 79,138,143, 34,137,144,234,164,
+ 18, 82,216, 10, 11, 39, 84,205,218,207, 99,228, 29,151,109,220,206,222,201,174,165,141,159, 51,157,160,184,198, 28,231, 56, 18,
+ 65,199, 33, 78, 60, 21,239,102,190,230, 15, 49,247,221,211,105, 27,148,144, 90, 67, 43,254, 86,183, 88,104,145,205, 99, 26, 64,
+ 4, 97,153,174, 67,138, 23,224, 30,165, 61, 84,254, 85,126,182,189, 82,250,122,201,249,211, 50,245, 41,128, 96,188, 7,151,114,
+ 53,146, 15, 37, 94, 38,221,152,122,251, 26,195, 30,247,101,144, 27,145, 42, 83,176,214,220,135,196,105,130, 59,193, 46, 55, 85,
+ 80, 16,157,178,183,251, 6,219,230, 94,205, 99,127, 29,179, 45,166,146,225,177,187,195, 0, 96, 94, 90,225,128, 21,192, 85,181,
+ 21, 7, 14,216,125,183,152,247, 79, 42,183,221,195,109,146,234, 75,168, 99,182,124,141,241, 9, 61,224,192,246, 28, 73,166, 39,
+ 75,168,104, 70, 61, 20,156,122, 25,244,227,235,251,243, 54,192,242, 63, 87, 25,135,230, 23,204,124, 93,120,187,229,119,232,152,
+ 53,135, 10,186, 74,103, 28,182,205,177, 59,183,115,182,248,151, 24, 48,162, 71, 68,129,229,183, 21,166,107,176,110, 82,142,234,
+ 22, 28,237,204,187, 47,151,119, 77,218, 45,246,168,101,107, 88,210,247, 62,154,142,161,192,150,146, 77, 49, 46, 39, 62, 10, 71,
+144,185, 87,126,243, 58,209,219,213,206,241, 60, 46,115,220, 35,107, 9,210, 11, 78,101,161,205, 0, 87, 0,208, 50,198,171,155,
+156, 35,234,127,212, 15,162,155,159,230,109,200,138,200, 97,206,245, 45, 35, 57,182,241, 45,239, 62,135, 26, 52,248, 80,185, 31,
+ 33,201,175,169,189,223, 88,108, 50,152,139, 37, 80, 37,174, 57,242,130, 3,139, 66,182, 80,109,214,133,189,242,213,135, 57, 29,
+150, 13, 4, 90, 8,221, 32, 97,168, 37,141,141,154, 88,113,175,226, 21,198,180, 7, 21,153,236, 28,213,184,114, 48,223,110, 53,
+131,122,100,108, 69,224, 2, 4,142,146, 77,111, 24, 83,240,184,140, 41, 82, 48,224,188,227, 60,175,123,191,240,107,156,151, 43,
+212, 39,230,115, 59,213,228,251,124,188,150,195,127,199,160, 93, 46,124, 69, 38,244, 93, 83,177, 34, 9, 41,184,124,219,145,221,
+104, 37, 42,146,217,160, 36,168, 52, 82,157,135,151, 59,120,130,255, 0,233,190,155,107, 22, 0,134,150,184,180, 75, 74, 98,105,
+ 74, 3, 94, 29, 28,107,138,237,174,230,110, 54,239,170,250,173,216,238, 68, 23, 7, 52, 56,195,170,181, 2,181,169,105, 31,136,
+113,198,148,193, 89,142, 83,252,216,191, 50, 27,247, 28,122, 35,176, 99, 28,143,147,241, 55, 45,229,211, 51, 62, 46,206,151,115,
+195, 96,192, 60,129,144,219, 46,246,120,150,123,196,166, 46,118,183, 11,101,232,183, 36, 33,242,202, 66, 20,176,225, 3,173, 4,
+ 6,215,229,167, 47, 65,113,185, 73, 36, 77,154,222, 48,217, 25, 71, 19,161,165,142, 46,104, 45,119, 2,211, 74,227, 74, 43, 38,
+239,230,175, 51, 92, 91,109, 81,197, 43,225,184,144,190, 39,213,128,107,112,123, 26,199,144,230,225, 80,225, 90, 97, 90,175,169,
+207,203,239,210,199, 38,122,106,225,172,171, 18,230,110,115,202,253, 69,100,220,147,153,220,121, 23, 32,202, 51,146,236,153, 49,
+231,100, 86,203, 92, 25, 86,246, 19, 38, 84,213,252,162, 21,110, 46, 54,130,176, 63,104,175,132,107,204,252,233,204,240,243, 61,
+219, 39,182,182,101,180,108,140, 49,172,103, 67, 92,226, 28,104, 7,123,189, 67,216, 49, 94,174,228, 78, 83,159,148,236,159,111,
+119,116,251,169, 36,144,200,231,191,165,205,107, 75, 69, 73,238,141, 53, 29,167, 5,110,112,126, 43,227, 62, 38,197, 97,226,248,
+ 70, 41,141,225, 88,110, 61, 13,230,237,214, 75, 53,185,139, 45,130,201,111, 74,150,243,129,166, 90, 75,108,176,128,165, 41,106,
+ 32, 1, 82, 73,238,117, 88,187,187,155,114,149,211, 76,247, 62, 71, 28, 92,226, 75,137,203, 18,113, 61, 10,215,103,101, 6,213,
+ 11, 97,129,141,142, 38, 12, 26,208, 26,214,140,240, 3, 1,210,190, 89, 63, 42, 40,237,243,215,230,235,235,131,213, 55, 24, 70,
+249, 94, 24,110,229,200,246,107, 85,218,218,217, 98,217,146,187,157,228, 49, 94,183, 58, 41,181, 46, 11,132, 91, 43,247, 23, 82,
+ 42, 82,165,182, 85,213, 64,159, 73,121,170,255, 0,228, 92,171,181,237, 87, 6,183, 29,199, 16,115,104, 99, 8,119,176,188, 48,
+117, 3, 76,151,150,188,159,103,252,135,155,247,109,226,216, 82,219,243, 26, 8,201,198, 73, 1,105,235,212, 24, 94,122, 9, 21,
+205,125,114,235,204,107,214, 42,155,250,232,245,173,197,190,132,120, 30,253,204,188,142,250,103,220, 84, 92,178,113,222, 11, 22,
+ 64,102,243,200, 89,196,134,156,114, 53,190, 57,218,191, 37,164,132, 23,101, 73, 82, 74, 90,105, 42, 85, 20,178,132, 46,219,201,
+124,159,115,206,215,205,179,183, 20, 25,189,252, 24,206, 46, 61, 39,128, 28, 79, 85, 72,166,115,223, 59,218,114, 21,131,239,110,
+ 77, 78, 76, 96,205,239,166, 13, 29, 3,139,143, 1,142, 38,128,252, 90,115,111, 29,250,155,185,250,148,244, 53,235, 27,213,141,
+218, 66, 57, 59,214, 39,168,107,126, 71,109,193,159,134,184,104,192, 48, 28, 26,249,134,127, 5,134,211, 78, 60,226,225, 54,168,
+215,205,172,193, 80,222,203,104, 65,121, 74,144,227,161, 62,179,218, 55, 93,183,249,110,235,180,109, 77,252,139, 59, 98,210,250,
+215, 91,222,201,117,156,177,161,102, 46,201,196,157, 35, 72, 21,241,158,247,179,238,163,116,218, 55,173,225,223,238, 47,174,131,
+132,116,167,135, 27, 31, 14,129, 74,225, 80,252, 27,155, 64, 26,137,113,117, 58,213,252,193,153, 85,183, 5,229, 79,202,187, 55,
+189, 53, 54, 69,159, 14,228, 30, 85,202,174,204, 91, 88, 18,174, 47, 91,113,235,175, 26,203,125, 17,218, 42, 64,113,197, 52,202,
+130, 18, 84, 42,104, 42, 53,151,249, 13,104,237,194,199,122,129,148,212,248,163,104,174, 2,174,108,224, 87,170,167, 21,173,254,
+162,111, 89,182,238, 27, 21,196,149, 45,142,105, 30,105,137,163, 95,110, 77, 7, 19, 65,130, 54, 97, 31,204, 21,233, 98, 54,109,
+100,194, 57,135,211,215, 59,240,173,146,236,236,102, 96,102,217,109,130, 28,166, 34, 67,144,225, 66,103, 92, 45,237, 62,137,204,
+199, 72, 21, 90,226, 38, 74,129,232, 18, 64, 39, 80,215, 30, 65,238, 38,221,211, 90, 92,219,206,230,230,214,184,226,122, 26,105,
+ 66,127,181,165, 78,219,126,163,118,193,114,216, 47,109,110,109,218,227,131,222,209,128,233,115, 65,212, 7,246,117, 47,161,252,
+ 98,247,143,100,184,253,159, 34,197, 46, 86,235,206, 55,125,182,194,188, 88,238,246,137, 77,206,181,221, 45, 87, 54,146,244,121,
+ 49,222,105, 74,109,230,159,101,105, 91,107, 65, 33, 64,130, 13, 14,176,201,161,125,187,221, 28,128,181,205, 36, 16, 69, 8, 35,
+ 2, 8,224, 65,204, 47, 65, 65, 59, 46, 88,217, 35,112,115, 28, 1, 4, 26,130, 8,168, 32,140, 8, 35, 16, 83,246,147, 74,172,
+208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205,
+ 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 95, 60,223,156,239, 21,223,249, 27,156,253, 44, 58,222, 49,
+149,220, 48,232, 92,105,234, 62,215,145,100,246, 62, 13,186,115,205,191, 28,185, 94,237, 45, 51,107, 75,182,139,105,108,137, 18,
+103, 22,209, 13,245, 58,159,151,116,166, 85, 22, 24, 41, 59, 71,149,251,131, 44,173, 46,198,166,135,153, 34, 32, 25, 4, 68,128,
+238,247,120,240, 2,181, 20,239, 14,238, 21, 85,221,234, 35, 36,145,224,105, 71,112,213,195,163,210,153,170, 49,135, 88,253,123,
+241,190, 22,139,231, 29,113, 23, 54,113,182, 88,223,167,223, 74,248, 39, 37,185, 96,198,110,146,185, 2,221,197, 24,221,223, 37,
+102,224,253,173,197, 91,228,206, 98,224,236,102,173,146,164,199,140,194,228, 68,105,229,167, 96, 13,154, 91, 46,166,217,239,165,
+209, 60,209, 61,158, 52,206,101, 75,116,151,150,178,154,177, 0,182,186,128, 36,128,226, 6, 56,168,246, 54,226, 33, 86,181,192,
+233,104, 56, 26,210,167,223,151, 98, 55,113,189,207,243, 4,228,235,142, 91,134, 94,249,231,213,213,159, 10,196, 56, 35,159,179,
+204, 19, 52,177, 96,183,220, 22,239,149,228, 88,114,163, 75,199,109, 83, 39,228,152,204, 43,149,221,107,151, 41,248,203,121,182,
+ 25,122, 66, 91,242,155, 41,242,201, 17,119,209,236,214, 13,100,172,183,182, 47,116,209, 53,205, 46,107,131, 67,170, 30,224, 24,
+242, 27,128, 6,149, 32, 86,167, 52,226, 51,113, 41, 45, 47,125, 3, 92, 65,161, 21,166, 67, 17,138,128,102,249, 23,171,158,104,
+182,225, 80,185,234, 47,171,235,190,106,198, 81,232,106,251,130,225, 22,238, 45,186,195,225, 43,134, 45, 30, 5,162, 78, 89,127,
+189,152,182,143, 32, 92,152,191, 7,252,245,200,117,178,219,132,161, 41, 40, 5, 13, 59,180,131,109,218,220,243,102,109,131, 52,
+220,135, 56,189,190, 32,117, 92, 24,214,213,213,210, 91, 74, 80, 26,140,115,196,165, 35,166,156, 15, 19, 93,106,202, 10, 26, 83,
+ 10,147,134,117, 77,217, 7, 47,254,106,214,102,185, 22,231,117,202,189, 77, 90,185, 93, 77,242, 76, 92,215,143, 32,113, 94, 77,
+127,197,173,194, 44,160,253,154,225,139,200, 99, 27,254,236,218,162,182, 90,101,134, 94,139, 57,227, 37, 43, 41, 41, 30, 96, 42,
+ 82, 29,183,151,165,240,218,214, 64, 97,238,105,121,123, 3,142, 20,112,120, 47,214,227,153, 32,180,105,167, 82, 14,154,236,106,
+ 36,187, 86, 53, 20, 62,170, 97, 65,237,197,116,139, 30,244,179,206, 46,243, 23, 60,100,174,228,240, 57,123, 55,176,122,118,244,
+253,146,227, 57,127,169, 14, 7,179,242, 21,231, 46,206,100, 63,200,151, 17,101,178, 92, 84,108,182,203, 2,173,210, 76,102, 29,
+ 44, 71,112,160, 57, 29, 78,160,108, 78,250, 60,220,193,104, 45,173,227,208, 98,141,211,202, 11, 97,149,204, 13,109, 34, 26,156,
+ 59,197,213, 21, 34,164,100,105,158, 18, 77,180,147, 91,141,117, 16,214,226,230,131, 83,222,192,101, 79,232, 72,120,243,152, 57,
+199, 6,229,238, 12,201, 5,231,214, 30, 89,233,226, 44, 76, 62, 63,169, 25, 60,149,196,217, 85,246,249,106,230,123,222, 33,200,
+109,220, 45,209,109,199, 31, 69,233,200,136,191, 34,197,243, 40,183, 70,114, 12,121, 31, 46,150,150,143, 49,105, 81,175,118,219,
+ 75,187,105,217,166,217,183, 53,119,131,161,236, 0,198, 36,138,132,157, 90,107,167, 93, 53, 16,247, 10,212, 26, 46, 71, 52,140,
+123, 77, 94, 89,134,170,131,157, 29,213, 92,233,150, 9, 30, 31,144,122,182,202,112,107,222,123,122,203,125, 70, 90,178,126, 61,
+227,111, 70,217, 62, 29, 97, 76, 57,246,104, 89, 6, 87,154,231,185, 60, 76,185, 23,107, 99,144, 1,187,169,187, 4, 56,104,153,
+ 17,240, 82,203,106, 11, 90, 18, 74, 22, 15,115, 14,219,111, 51, 97, 99, 32, 44,123,238, 3,142, 4,134,182, 38, 24,244,186,189,
+222,241, 52, 35, 51,128, 57,133,198, 58,103,180,184,151, 84, 6,211,180,184,214,163,142, 8, 54,172,163,157, 83,149, 97,153,245,
+218,215,234,142,255, 0,203,247, 15, 78,217,198, 13,234, 6,253,115,178,103, 56,182, 61,195,121,174, 69,202, 92,107,252, 69, 22,
+ 7,173,118, 9, 11, 48, 45,246,248, 50, 28, 92,108,113, 43,113,232,104, 15, 7, 17,188,190, 36,254,158,211,195,124, 45, 54,226,
+ 17, 59, 93, 16, 6, 55, 25, 26, 33,154,154,170,225,222, 36,140,100,160, 14,194,135, 36,142,185, 42, 28,117,151,105, 33,217,224,
+117, 55, 42, 12,187, 56, 40,126, 77,110,231,108,155, 18,228,204,167, 59, 87,168, 60,222,246,231,166, 79, 87, 28, 95,197, 15, 92,
+ 56,163, 41,118,211,156,189, 97,201, 90,185, 88,173,183,171, 77,222,211, 58,226,226,101, 90,164,174, 68,118,111,234, 43,144,152,
+237,161,213, 58,166,212,133, 58,129,246,144, 73, 20,112,248, 44,111,143, 3,223, 71,178,173,171, 40,226,215, 53,192, 96,225, 66,
+ 99,193,186,137, 20,173, 81, 28, 36,112,113,118,163,221,112, 24, 28,113,192, 16, 71,219,208,172, 14,121,152,122,184,113,185,108,
+ 98,185, 63,170,152, 60,179, 51, 53,228,203, 87,168, 59, 81,196,110,140,113,230, 1,133,191,156,194,139,136,200,195,100,200,180,
+174,196, 28, 93,157,198,190, 85,219, 76,137, 5,232,191, 50,236,205,202, 66,148,152,107, 59,109,180, 80,200,219,115, 8, 99, 12,
+ 71, 83,117,185,222, 25, 50, 9, 0,118,175,154,181, 15, 13,163,180,134,230,156, 72,249,184, 23,234,169,213,129,160, 21,194,152,
+ 83, 46,138,225, 90,174,158,122, 84,143,157,217,158,245, 25,134,230, 55,156,255, 0, 33,178, 96,190,162,174,248,247, 24, 94,121,
+ 30,108,171,205,250,119, 30,203,196,241, 11,170, 75,119, 41,137, 15,220,227,183,122,185, 92, 91,105,242,165,132,237, 45, 5,126,
+202,130,133,204, 46,134, 95,166,150, 38,177,174,124, 0,188, 48, 0, 3,245,200,220,134, 0,233, 13,168,245,241, 82,182,154,155,
+173,174, 36,128,236, 43,209, 64,126,218,163,119, 40,228,179, 49,124, 70,108,203,108, 27,197,206,231, 37,232,208,162,219,177,232,
+130,117,254, 67, 14, 44, 42, 98,161,180,167, 26, 74,158,102, 10, 94,113,178,165,128, 20,145, 95, 97,174,129, 92, 19,180, 5,227,
+172,109,206, 93,201,111, 89, 38, 97,102,106,221,132, 96,119,123,222, 21,131,241,164,246, 81, 42, 44, 15,216, 6,103, 92,110, 72,
+ 42,117,137,115, 46,108, 74,113, 27,234,180,162, 58,202, 82,181, 41,247,201,120, 92, 45,126, 95,155,167,163,175,224,137, 77,120,
+ 28,145,133,188, 75,141,120,139, 27,114,223,133, 96, 24,157,133, 55, 4,255, 0, 10,182,216,113,251, 20, 75, 80,189, 76,144,157,
+141,176,176,132, 55,230, 37, 93, 55,149, 19,211,218,104, 10,119, 55,179, 94, 29, 82,189,206, 61,100,149,200,225,100, 34,141,104,
+ 29,139,128,158,160,248, 75,211, 45,171,149,114, 38,237, 56,165,239, 32,185, 49, 33,165,228,113,109,217, 66, 45,188,115,111,203,
+210, 84,185,205,218,173,200,132,224, 12,182,242,182, 18,146,138,168, 40,128, 1,214,171,177, 27,169, 45,152,102,112,175, 10,130,
+ 77, 56, 87, 26, 87,213,219,138,172,222,136,132,135, 64, 62,163, 65,246,125,234,235,254, 93, 60,143,134,226,217, 85,239,130,241,
+156, 78,211,137, 64,200, 96,207,205,226, 68,181, 61, 37,246,147,117,183, 37,134, 23,188,200,117,229, 54,101,199, 66,214,148, 36,
+165, 7,201, 90,146,144,162,178,170,239, 55,237,207,238,220,106,212, 0,161, 24, 10, 99,133, 41, 65,137, 79,246,153,218, 43, 29,
+ 41,199,181,118, 3, 84, 53, 54,168,199,174,252, 43,154,115,206, 60,199,172,124, 80, 36,203,180,191,118,150,140,234,203,111,150,
+ 33, 92, 46,144,214,150,140, 58,169, 75,109, 46, 48,211,137,116,188,221,122,146,131, 66, 18,117,231,111,212,119, 42,243, 31, 55,
+237,144, 90,108, 61,230, 25, 15,142,192,224,199, 61,180, 26, 49, 36, 2,192,117,106,109,113, 37,166,134,139,209,223,166,222,107,
+229,190, 79,221, 39,188,223,251,178, 8,199,128,242,210,246,177,213, 58,240, 0,144,242, 11,116,186,152, 0,225, 81, 84, 56,244,
+173,232,134,221,130,136,121,167, 35, 50,197,207, 42,162, 30,137, 16,167,124, 75, 57, 80,252, 45, 5,126, 37,245,234,225, 30,228,
+208,117, 44,252,150,253, 61, 90,121,118,214,223,238, 26,102,220, 8,168, 57,178, 26,140,153, 92,221,210,242, 58,155, 65,137,121,
+231,111,234, 38,239,204,103, 59,111,219,181, 67,183, 3, 66, 50,124,212, 57,190,153, 55,161,128,245,186,167, 1, 65,253, 89,241,
+ 78, 71,192, 28,239, 55, 34,177,166, 84, 11, 37,254,248,238,107,132, 94,217,106,140, 70,150,227,223, 48,236,100,168,213, 59,225,
+ 72, 85, 54,159,212, 41, 52,161,215,145,124,240,228,219,223, 43, 57,161,219,141,166,166, 69, 44,166,120, 36, 3, 0,253, 90,156,
+218,229, 86, 56,228,115,105, 29, 43,216, 30, 69,243,157,143,154,220,172,221,186,239, 75,229,138, 33,111, 60,100,226, 89,167, 75,
+ 95, 76,232,246,140,198, 78, 7, 28, 20,119,155,108,191,151,231,174,180,216,114, 79, 88, 28, 75,144,217,121,115, 31,179, 68,177,
+185,200,220,123, 42, 68, 9, 55,203,116, 26,150,218,121,112,223,105,215, 18,149, 41, 91, 16,251, 75,217, 82, 18,186, 29,123, 35,
+202,111,255, 0, 32, 35,150,172,196, 23,134, 72, 36,205,193,172, 18,196,231, 83, 23, 52,124,204, 39,136,165, 58,202,241, 95,156,
+ 31,254, 59,199, 53,222,125, 69,163, 98,184,102, 77, 38, 67, 12,205,109,112,107,136,238,188, 14, 6,181,234, 9,146, 6, 69,233,
+195,211,191, 20,100, 60, 23,232,203,140,229,224, 88,190, 94,229, 51,124,214,248,226,157,202,114,152,229, 30, 90,219, 83,142, 63,
+ 38, 75,129,214,255, 0,102, 86,243,189, 17,185, 9, 66, 66,137,214, 53,250,136,253, 99,221,249,179, 4,150, 54,102, 93, 18, 55,
+ 67,229,144, 6,157, 7, 54, 71, 27, 77, 26, 29,248,137,196,138,138,113, 91, 87,233,191,244, 91,101,228,252,241,223, 93,136,131,
+227,118,182, 69, 25, 46, 30, 32,201,242, 72,225, 87, 22,254, 16, 48, 6,134,188, 21,168,244, 69,233,222,243,154, 98,188,157,145,
+206, 63,193,227,102,152, 46, 77,129, 99,211,228,198, 83,190, 75,119,232,174,199,114,102,202,163,204, 64,117,104,218, 2,133,118,
+ 30,160, 16,117, 96,253, 27,114, 52,219, 14,190,102,186,101, 4,133,172,132, 28, 9, 99, 92, 28,247,118, 57,192, 53,167,250,164,
+229, 74,192,126,180,121,234, 30, 96, 12,229,123, 87,212,198, 28,249,156, 49, 13,123,152, 88,198,255, 0,105,173,115,156,225,253,
+ 96, 51,173, 41, 23, 5,254, 75, 63,152, 39,163,187, 62, 70,159, 74,126,188,237,152, 85,199, 46,149,179, 42,180,191,131, 22,241,
+139,172,104,200, 8,141, 41,182,100, 57,117, 13, 74,100, 41,196,249,129,160,118,144, 55, 0, 41,175,171, 27,223,156, 59, 47, 54,
+ 72,211,186,109, 69,225,131,186, 67,251,195,164, 18, 3,106,211,134, 21, 95, 35,246, 15, 36,119,238, 77,137,237,218,119,129, 27,
+158,123,224,199,220, 52, 24, 16, 9,117, 28, 49,198,157, 24,169,191, 30,126, 66, 57, 19, 28, 83,234,114, 71, 41,243,210,243,207,
+ 83, 30,165, 44,110,218,174,188,185,125,179, 63,115,139, 99, 55, 43,172, 75,189,201,207, 41,217,127, 55, 53,235,148,168,160,191,
+ 33,199, 82,162, 0, 1, 32,110, 10, 97,127,231,119,141,121,100,109,237,124, 59, 59,103, 84, 68, 28, 1,113, 13, 45,110, 32, 80,
+ 6,131,128, 0,250,240,164,142,221,228, 23,129,101,124, 46,110,204,183,215,109,210,233,156,210, 67, 65,112,123,168, 9,171,139,
+136,196,146, 56, 96, 49,174,203,239,228, 25,120,255, 0, 5,189, 55, 47,143,185,213,174, 62,245, 83,233,169,139,149,186,199,203,
+ 86,188,125,195, 97,203, 45, 11,189,220,111,118,246,164,193, 50,150,228,103, 45,210, 46, 46, 6,222, 74,215,185, 42, 90, 86,133,
+164,164, 35,150,254,118,255, 0,187,189,250,155, 95, 18,202,232,130, 98, 46,197,167, 67, 88,234, 58,152,234, 13, 21, 20, 28, 40,
+ 65,173,123,115,228, 31,251, 43, 15,165,187,240,175,237, 1, 13,152, 55, 7, 13,110,123, 65,109,106, 52,151, 26, 26,156,200, 32,
+138, 82,194,112, 31,160,191,204,113,142,124,193,121,115,212,207,174, 71,114,108,123, 3,140,237,189, 60,117,198,184,188,108,111,
+ 22,203,237,175,169,181,184,197,218, 58,162, 49, 9,228,188,227, 40, 46,184, 98, 41,234, 36, 6,221,108,252, 66,189,190,243,158,
+195, 37,140,150,123,110,214, 24,231,154,248,146, 56,185,205, 61, 45,196,156, 49,167,122,157, 32,171, 55, 47,114, 47, 49,199,184,
+ 69,123,186,238,229,237,140, 17,225,196,208,214,188, 30, 15, 4, 1,137, 2,167, 73,119, 67,134,104,197,232,223,242,217,201,189,
+ 44,250,207,245, 97,234,110,119, 36, 90,114,203, 39,169, 12,171, 41,201, 96, 99, 80,177,231, 45, 18,177, 84,228,119,217,151,132,
+176,227,235,148,250,100,249, 41,148, 26,220,148, 38,164,110,160,237,168,254,110,231,246,115, 54,215, 97,183, 54, 18,195,108,198,
+180,187, 85,117, 81,129,181,165, 5, 50,174,101, 73,114, 95,150,239,229, 61,223,113,220,221, 56,120,187,123,156, 26, 27, 77, 53,
+121,125, 9,169,174,116,200, 40, 47, 47,254, 82,163,152,191, 48,188,211,213,214, 97,156,218, 47, 60, 95,200,252, 97, 59,139,242,
+190, 40, 93,141,232,215, 71,173, 23, 92,105, 56,244,133, 38,230,153,123, 82, 74,106,242, 72,100, 20,154, 80,212, 87, 79,172, 60,
+207,118,217,176,197,180,193, 17,108,209,202, 36,108,186,133, 1, 15,214, 59,180,245,102,163,247, 31, 41, 89,187,115, 20,187,205,
+196,161,208,203, 9,137,209,105, 53, 33,209,248,103,189, 95, 94, 74,159,241,215,228,251,249,133,122, 81,151,150,224, 30,143, 61,
+125,185,129,240, 94, 95,122,149,113,118,211,119,197,132,188,150,210,137,128, 52,167,153, 73,109,248,168,150, 35,165, 41, 84,136,
+203, 96,172,164, 18, 18, 64,165,175,114,243,103,100,230, 93, 23, 27,174,213,226, 92,177,160, 84, 58,141, 52,224,114, 58,107,192,
+234,162,167,237,126, 77,111,252,171,174,219,103,222, 60, 43, 71,184,157, 46,101, 92, 43,196,102, 53, 83,136,211, 84,227,233,255,
+ 0,249,126, 34, 97, 88,239,169,206, 63,230,126,103,119,145,177, 79, 80, 56,253,170, 45,186,251, 6,194,109,153,150, 37,148,227,
+247, 7,174, 80,111, 43,126, 68,169,141, 74,144,137, 14, 2,232, 41, 1, 96,173, 36,209,103, 72,111,190,121,203,127, 53,149,197,
+165,176,137,246,228,212, 23, 85,174,107,154, 26, 89, 64, 1, 2,131, 14,140, 58, 18,252,191,250,124,135,110,130,254,218,242,232,
+205, 29,203, 64, 4, 55, 75,216,230,184,185,175,169, 36, 19, 83,143, 78, 35,138, 97,179,126, 85,191,153, 87, 15,241,147, 92, 17,
+138,254, 98, 86, 28, 47,211,165,129,244,170, 29,238, 46, 45,252, 3, 56,199,172,169,146, 36, 6, 24,186, 41,105,151, 9,160,233,
+160, 66, 46, 73, 77, 14,208, 2, 14,221, 43,113,230, 87, 47,110,183, 70,250, 77,156,190,237,217,141, 85, 99,141, 41, 82,218, 80,
+154,127, 82,188,115,197, 35,109,229, 95, 50,236,246,131,111,139,124, 17,217, 51, 34, 25,165,237,109,107, 64,234,212, 10,255, 0,
+ 92, 14, 25, 96,172,247,171, 15,202, 59,145,189, 72,102, 30,139,115,151,249,249,185,151,191, 75,177,109, 76,228,247,124,183, 22,
+ 69,195, 36,228,217,112, 46,214,251,154,230, 62,252, 39,161, 70,142,235,194, 17, 65,163, 39,184, 38,180, 53,174,114,191,153,241,
+114,237,182,225,110, 45, 0, 23, 85,160, 99,168,216,193,107,155, 64, 8, 36,129, 94,149,104,230,223, 41,102,230,123,173,178,229,
+215,132,155, 61, 58,139,219, 87, 72, 67,218,234,146, 11, 64, 39, 79, 66,238,173,189,133,198,131, 18, 58,233,189,136,237, 52,170,
+118,220,128, 1,214, 64,182,197,243,253,249,224,250,219,202, 49,124,111, 25,244, 1,233,197, 82, 47,222,162,253, 80, 34, 38, 61,
+146,198,176, 63,186,233,138,113,174, 72,225,137,242,101, 73, 33, 49,228,100,138,222,193, 82,213, 70,226, 37,247, 23,176, 45,167,
+ 53,186,121, 57,202, 17, 78,247,239,219,141, 27,105,107, 87, 2,114,115,219,141,122,195, 51,195, 55,233, 2,180, 33,121,239,207,
+ 14,117,154, 8,227,229,221,174,174,189,187,163, 92, 27,155, 99,113,165, 58,140,152,140,114, 96,113, 52,168, 43,160,191,150,247,
+162,220, 95,209, 79,167, 44, 67,140,237, 72, 98,110, 72,227, 63,199,243,220,145, 12,150,157,202, 51,155,171,109,252,244,186, 31,
+137, 45, 55,177, 17,227, 32,245, 75, 45,182, 13, 85,185, 71, 58,231,158,109,155,157, 55, 25, 47,100,193,191, 43, 27,251,172, 31,
+ 40,237,226,238,151, 19,195, 5,167,121,125,201,144,242, 38,217, 21,132, 84, 47, 29,233, 29,251,242, 31,152,246,112,104,224,208,
+ 56,212,174,131, 40,237, 5, 71,176, 4,253,154,168, 43,178,248,121,228,222,108,245,111,207,254,185, 98,122,166,245, 59,249,114,
+250,191,228,174, 62,227, 39,159,107,128,125, 62, 71,227, 12,158,195,140, 96,204,199,144,151, 34, 73,185, 25, 24,228,212, 79,146,
+ 75, 72,147, 44,165,164,135,159, 13,238,253,131, 45,177,175, 96,218,237, 59, 78,203,178, 29,171,109,222, 44,226,150, 95,243,166,
+ 50, 70, 92,252, 49, 13,164,131, 72,224, 49, 52,109,105,222,113,114,241, 37,230,241,188,239,219,248,222, 55, 93,146,250,104, 98,
+255, 0, 34, 1, 20,141,107, 49,192,186,177,187, 81,252, 78,192,106,117, 43,221,104,106,142,126,101,126,185,185, 75,212, 23, 46,
+122, 15,200,178,159, 67,156,231,233,238,119, 8,242, 62, 71,125,197,177, 78, 65,183,220,227,221,249,142,117,198,235,134, 73, 92,
+ 11, 42,101, 99,246,199, 28,121,135, 45, 12,178,160,203,111, 29,210, 91,248, 65, 32, 41,207,151, 60,149,103,177, 89,110,144,193,
+185, 91,220, 54,104,131, 92,230, 22,145, 16, 13,148,106,125, 30,234, 3,168,156, 72,193,167, 30,134,190,104,115,229,247, 48,223,
+237, 51, 79,181, 92,219, 58, 9,156,230,178, 64,224,102, 37,208,157, 44,172,109,169, 26, 64,192, 59, 23, 12, 58,126,179,248, 37,
+188, 55,214, 7, 19,240, 87, 59,243, 31,167, 19,199,188,149,140,181,144, 93,177, 76, 87,149, 49,164,203,228, 78, 36,184,204,146,
+228, 9, 34, 59,243,237,240,230,193, 93,193,136, 44, 60,189,140,183,185, 62, 81, 32,236, 66,181,229,189,220, 73,203, 87, 23, 54,
+ 22,151,126, 36, 46,210, 28,232,221,249,114,128, 42, 42, 26,226, 28, 1, 36,102,120,244,149,235,173,145,209,243, 85,181,174,229,
+123,101,225, 78,221, 78,107, 37,109,100,136,146, 90,104, 92,208, 90, 92, 0, 57, 10,138,116, 5, 76,255, 0, 61, 78, 24,227, 60,
+151,242,224,230, 92,178,251,100,180,183,144,241,100,156, 15, 41,193,111,239,178,210, 39, 89, 47,147,242, 27, 77,173,212, 48,242,
+192, 82,127,136, 68,156,228, 85,160, 31,139,122,122, 21, 4,210,231,228,158,227, 61,151, 48,219,199, 17, 58,101,214,215,129,145,
+104, 99,157,136,254,169, 1,221, 84,237, 84, 95, 62,246,203,123,254, 89,185,150,102,141,113, 22, 57,142, 57,181,198, 70,180,208,
+255, 0, 88, 18,218,113,175, 98,131,126, 82,126,171,112,126, 59,244, 11,232,127, 9,229,204,177,196,114, 7, 44,222, 50,142, 50,
+227, 60, 97, 9, 84,251,245,206, 13,167, 37,191,196,128,250,153, 43, 43,143, 2, 21,174, 19, 40, 92,167, 40,216,248, 27, 77, 86,
+180, 32,186,243, 59,150,166,190,223,183, 73,173, 89,249, 48,134,200,247,100,208, 76,108, 46, 21,226,226,226,112, 24,230, 78, 0,
+148,211,202,110,106,131,111,229,205,166, 27,201, 63, 58, 98,232,227,110,110, 32, 73, 35, 90,105,193,161,173, 29,227,134, 64, 98,
+ 64, 93, 58,227, 15, 85,152,239, 45,242, 54,107,128,226,188,103,203, 8,182,224,121,166,109,199,215,190, 76,186,218,236,209, 56,
+241,121,102, 3, 35,229,167, 70, 97,196, 95, 29,187,185,185,239,133,165,170, 2, 82,175, 18, 53,158,238, 92,186,253,170, 8,230,
+150,104,181, 72,198, 60, 70, 11,139,244,188, 84, 19,220,211,150,125,229,165,109,124,204,205,222,226, 88, 34,130,109, 49,200,248,
+221, 33, 12, 17,234, 97,163,128,239,151,103,151,117, 24, 57, 19,148,241, 94, 48, 86, 4,222, 76, 47,110,200,228,174, 70,198,248,
+183, 19,137, 96,199,229,228, 83, 37,229, 89, 58, 36,188,209,117,168,109, 58,184,241,163, 69,135, 34, 76,185, 78, 0,219, 44,182,
+183, 28, 82, 80,146, 68,117,134,217, 46,229,226,152,244,210, 56,221, 35,137, 33,163, 75,104, 56,230, 73, 32, 0, 49, 36,128, 49,
+ 82,155,142,235, 22,215,225, 9,117, 86, 89, 27, 27, 67, 90, 92, 75,157, 82, 43, 74,208, 0, 9,115,142, 13, 0,147,128, 85, 42,
+ 7,230, 73,233,206,226,155, 93,197,152,124,184,206, 37, 51, 9,226,254, 69,189,103,115,120,162,235, 11, 19,193,240,190,103,184,
+ 93, 45,152,205,202,250,227,173,166, 93,182, 53,214, 77,162, 66,155,144,184,229,176,214,215,212,176,202,188,205, 90, 95,229,238,
+225, 30,166,147, 22,176,249, 24, 24, 36,105,115,221, 16,107,158,214,112,113,104,112,168,173,107,221,166,172, 21, 70, 63, 50,246,
+217, 52,184, 9,188, 50,200,228, 47, 49,184, 53,140,149,206,108,110,127, 22,135, 22,154, 26, 82,157,226,116,226,173,166, 47,202,
+ 56,238, 76,230,108, 21, 30,233,141, 49,132,102,119, 28, 42, 68,236,173,166, 44,240, 50, 7,237,140, 91, 93,114,225,106,119,230,
+ 28, 76,184, 69,235,163,113, 82,249,218,124,228,173,178,144, 64,221, 86,185,219,100,182,240,241, 14, 47, 96,117, 27, 82, 69, 75,
+133, 29,134, 14,238,147, 78,138, 21,110,181,221, 99,186,241,112, 45, 12,121,101, 93, 64, 29, 64,211,169,184,226,218,184, 10,225,
+222,168,162,107,198,121,179, 5,202, 50,222,103,195,163,203,147,106,184,112, 70, 99,140, 96,249,196,235,240, 98,215,102, 55,188,
+183, 27,178,101, 17, 62, 78, 66,159, 62,115,102,219,127,138,149, 41,105, 65, 14,239, 64, 4, 0,162,173,206,207, 53,180, 86,243,
+ 16, 8,157,142,123, 0,169, 52,107,221, 25,168,166, 7, 83, 15, 78, 20, 41, 43, 93,242, 11,169,174, 97, 4,131,110,246,177,229,
+212, 2,174,141,146, 10, 26,226, 52,188,116, 99, 80,183,242,215, 50, 97, 60, 45,138,181,152,102,143,221, 92,180,189,126,195, 49,
+244,179,142, 89,159,201,174,225,236,234,245,110,176, 67,145,242, 80,210,236,149, 71,110,225,117,142, 31,117, 8, 33, 9, 85,122,
+146, 1, 46,215,180, 77,188, 75,225, 67, 77, 90, 92,123,196, 52,119, 26,231,145, 83,133,104,211, 65,197,119,119,222,160,217, 34,
+241,167, 39, 78,166, 55,186, 11,143,125,237, 96, 52, 24,211, 83,133, 79, 4,167,137,185, 99, 20,230,140, 78, 70,101,135, 55,126,
+102,215, 15, 47,207,176, 89,177,178, 92,126, 86, 53,119,135,146,241,165,238,126, 63,118, 97,200,178,219,109,193,228, 92,237,175,
+182, 20, 5, 13, 60, 13, 64, 46,233,181,203,180, 74, 33,155, 78,162,198, 60,105, 33,192,181,237, 15,105,168,233,107,130, 62,209,
+187,195,189,194,102,135, 86,144,247,176,234,105,105, 14,141,238, 99,133, 15, 67,154, 66, 37,234, 57, 73,172,208, 65,102,130, 11,
+ 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,171,
+207,168, 95, 81,248,159,166,235, 94, 45,125,205,172,185, 20,251, 22, 81, 51, 52,181,181,115,177, 48,204,164, 91,238,248,150, 47,
+123,202, 90,136,235,107,117,183, 86,237,218, 61,134, 68, 72, 73,105, 42, 43,125, 77,160,211,120, 58,154,217,118, 57, 55,199, 61,
+145, 57,161,205, 13, 52, 60, 67,158,214, 87,177,165,192,154,240,169,224,155,220, 92,139, 96, 11,134, 6,190,224, 79,190,138,168,
+207,252,211,120, 50,223,100,185,228,174, 97,252,152,253,134, 22, 54,221,238, 4,216,118, 86, 37,203,190,221, 89,131,198,211,231,
+ 89,162,194,110, 74,166,170,125,173,158, 76,134, 37, 48,166,129, 66,162,205, 7,247, 63, 21,137,158, 95,221,189,226, 61,113,234,
+ 46,161,196,224, 43, 48, 14, 38,148,210,239, 4,208,215, 29, 77,233, 77, 14,235, 24, 21,161,165, 63,135, 14,222,247,184,167,201,
+ 63,153,119, 12, 91,239,140, 91, 46,120,182,119, 22,211,120,206,237,248,110, 33,149, 49, 22, 29,198,197,151,219,149,152,101,120,
+133,202,249, 13, 76, 74, 91,166, 5,153,120,132,203,164,167, 54, 84, 66, 82, 30, 9, 63, 18, 82,139,121, 22,233,236,212,215,178,
+161,133,206,110, 32,180,248,108,144, 52,212,124,206,241, 3, 64,253,234,133,211,185,176, 26, 16,105, 90, 3,211,137, 21,236, 20,
+175, 98,124,201,189, 92,230, 55,139, 55,163, 44,219,135,184,230,102, 75,103,245, 51,154,101,208,127,185,119,153,176, 44,217, 37,
+207, 17,129,134,229, 55,251,116,184,211,223,154,139,116, 32,234,237, 17,167, 41,197, 41,194,168,229, 72, 66, 20,234,146, 52,148,
+ 28,183, 20, 78,189,138,230, 80,215, 64,214,157, 64, 18, 3,140,140,105, 4, 1, 83,243, 22,240,239, 98, 77, 17,159,120,226, 35,
+115, 27, 93, 68,225,213, 66,126,234,246, 42,177, 96,252,220,236, 63,197, 57, 17,119,206, 59,189,188,219,121, 68,166, 48,108, 70,
+ 68,235, 94, 33,117,177, 89,112, 92, 43, 12,186,229, 80,110, 55, 57,247, 3,111,185, 92,152,201,242, 69,195,130,196, 50,124,228,
+148,170,168, 66,124,197, 88, 38,242,221,250, 99,209, 32,249,123,206,163,156, 9,116,146, 53,132, 0, 42, 26, 88,202,184,156,186,
+206, 9,163,119,129, 83, 81,199, 1,150, 64, 19,143, 77, 78, 8,198,223,230,127,133,175, 31,139,157, 57,194, 92,167, 31,142,178,
+ 43,247, 45,225,124,127,145,189, 58,198,155,190,111,158,113, 76,179, 12,219, 91,180,127, 18,249,187,122,110,210, 1,102, 43,243,
+ 11,123, 92, 74,131,201,109, 27, 92, 84, 97,228, 25,117,152,124,120,252, 70,134, 57,194,142,163, 90,241, 90,234,165, 14,145,137,
+ 2,184,101, 83,130, 91,249,171,105,171, 73,210,106, 6, 88,145,213,214,160, 23,207,204,234,245,197, 60,139,205,120, 63, 50,240,
+252,203,117,251, 12,201,222,127, 31,194,108,249,125,137, 23, 43, 78, 13,143, 97,152, 77,242,123,110, 92,228, 92, 91,135,125,186,
+ 92, 39,229, 65,118,232, 80,210,146,164, 18,218,212,133, 52, 84,183,145,114, 19, 55, 24, 32,150,214, 96, 90,230,226,226,215, 80,
+184,201, 35, 71,116, 10,181,160, 51,188,227,199, 17, 90,224,155,183, 67, 19,156,215,183, 16,114,168,202,128,231,196,227,128, 86,
+ 50,217,235,186,203,125,227,204,207,147,172,124, 53,201,114,241, 75, 63, 43,127,129,216, 20,217, 55, 11, 4, 23,121,103,148,165,
+230, 40,194,161, 65,182, 71, 55,101,204,128,204,155,163,205,173, 82,110, 76,176, 16,141,228,164,148, 0,184, 73, 57, 69,208,204,
+203,119,207, 24,121,143,196,112,163,142,134,120,126, 33, 36,233,161, 32, 87, 6,147, 83, 78,156, 28,139,240,230,151,134,154, 86,
+131, 44, 77,105,211,211,210,135,242,255, 0, 50,171, 44, 11,183, 39,227, 50,189, 61,242,219,153, 79, 9,218,173,242,185, 90,221,
+ 2,243,139,191, 7, 25,188,223, 47,247, 76,114,213,110, 98, 75,183,184,235,185, 57,120,184, 65,142,168,142, 71,100,163,203,144,
+149,188, 89, 40, 90, 67,214,242, 43,222,216,164, 23, 17,232,148,157, 4,135,212,128,214,189,198,154, 77, 52,130,107, 83, 90,183,
+ 10,212, 36,206,230, 1,112,208,106,220,242,195, 18, 7, 30, 63,122,182,220, 33,205,243,121,106,231,202,184,197,255, 0,143,111,
+ 28,109,154,112,230, 97,101,195,115, 12,126,231,124,183,228,145,204,236,134,195,106,200,226, 59, 18,109,185,215, 25,125,181,219,
+111, 49,202,170, 18, 82,189,201,161,165, 77,111,118,218, 70,220,216,100,100,130, 70, 74,210,230,144, 8,192, 57,204, 53, 7, 44,
+ 90,125, 73,228, 19,153,139,129, 20, 45, 52, 60,120, 3,247,166,111, 82, 89,131,184, 85,158,203,115, 74,228,219,152,158,213,226,
+200,246, 72,133,184,220, 59, 34,167, 46, 10,192,113,196, 2,134, 21, 41, 12,173,180, 60,186, 80,110, 72, 80, 43, 0,165,180,196,
+217,102, 26,242, 2,171,183, 14, 45,110, 10,154,113, 79, 53,163, 22,178, 95,114,156,138,241,154, 69,199,243,219,194,174,152, 45,
+131, 21, 48,227, 77,186,217, 33, 50, 34,174,239, 57,233,237,174, 75, 9,184,184,208, 91, 1,146,159,135,169,170,247,210,110,125,
+153,219,164,154,163, 32, 0, 49,207,213,235,251,168,154,182,232, 91,138, 28, 82, 76,247,212, 17,190,217,238, 12,224, 71, 34,195,
+242,159,225,178,152,180,101,185, 94, 96,246, 72,164,203,121, 1,191, 43, 99,237,184,136,198, 83,101,113,247, 52,164,129,230, 21,
+ 15,218, 37,181, 36,237,229,207,161, 34,103,157, 97,164, 18,218, 82,163,239,236,227,146, 35,175,188, 96, 90, 48, 39,138,231,141,
+183,142,185,143, 32,201,166, 97,246, 94, 42,202, 87,146, 90,228,170, 29,242, 20,182, 60,245,218,230, 55,209,104, 34, 24,151,184,
+ 37, 67,241,186,166,210, 71, 80,174,186,190, 59,114,137,145,137, 11,154, 26, 69, 65, 38,158,206, 42, 8, 91,188,184,180, 2, 79,
+ 82,235,191,161,255, 0, 75,119,190, 25,131,127,206,249, 25,132, 39,145,114,149,174, 27,113, 63, 98,161,100,177,161, 64,132, 15,
+ 37,110,165, 37,208,148, 36, 35,122,138, 82,128, 84, 74,214,179,172,251,153,119,182,238, 4, 69, 17,171, 6, 36,229, 83,240, 10,
+123,111,179, 48, 85,206,207,236, 31,181,116, 15, 85, 53, 38,178,149,232,122,141, 4, 22,104, 32,160,124,141,198,120, 95, 43, 99,
+114,177, 76,230,199, 18,247,105,146, 9, 74, 95, 78,217, 48,223,161, 1,232,238,166,142, 48,226,107,209,104, 80, 58,175,243, 55,
+ 43,109,252,227,104,251, 29,202, 22,203, 11,184, 28,193,233,105, 24,181,195,131,154, 65, 29, 42,195,203, 28,213,184,114,109,219,
+ 47,182,201,221, 20,205,226,220,136,232,112, 53, 14,105,226,215, 2, 15, 66,230,166, 91,249, 95,219, 31,156,227,216,103, 35, 77,
+182,192, 90,148,164, 66,188,218, 81,117,117,148,158,201, 14,161,248,164,211,222, 14,188,165,188,254,141,118,219,169, 75,172,119,
+ 9, 97, 97,252, 47,140, 75, 78,194, 31, 25,246,215,181,122,207,100,253,104,238, 86,145, 6, 95,237,209, 76,241,248,153, 35,162,
+175,104, 44,144,123, 40,165, 60,111,249,108,226, 24,253,198, 53,199, 55,200,100,101,134, 43,168,117, 48,131, 2, 13,181,213, 32,
+212,111,105, 43,113, 75, 21,253, 85, 44,131,226, 14,172,220,157,250, 78,216,121,122, 86,207,127, 44,151,111,105,168,107,128,100,
+117, 29, 44, 5,197,221,133,196, 30, 32,170,199, 57,254,173,247,254, 98,133,214,251,124, 81,217,177,194,133,205, 37,242, 80,231,
+ 71,144,208,222,208,208, 71, 2, 23, 73, 44, 24,245,167, 25,182, 70,180, 89,161,179, 10, 12, 86,144,211, 76,176,216,109, 1, 45,
+128, 7, 65, 64, 40, 6,189, 71, 12, 44,183, 96,142, 48, 26,214,128, 0, 2,128, 1,144, 3,128, 11,202,211, 76,251,135,153, 36,
+113,115,156, 73, 36,154,146, 78,100,147,153, 41,235, 74, 36,214,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 10,130,122,182,
+227, 63, 84, 57, 87, 36,113, 12,254, 4,228, 43,238, 51,199,249, 99,172,241,231,168, 24,144,178,117, 89,228, 98,120, 69,178,237,
+111,201, 27,200,241,244,110, 74,152,185,204,141,108,159,141, 56,236,112,167, 54, 92,153,124,141,176,130,147,115,229,189,207,110,
+180,182,156, 94,196,215, 74,206,252, 61,218,234,121,107,153,161,253, 44, 5,205,148, 3,133, 99, 45,252,106,139,205, 59, 86,231,
+123,117,110,108, 38,115, 33,127,114,122, 58,133,172, 14,108,158, 36,125, 15, 33,175,132,145,141, 37,107,178, 98,231, 52,254, 30,
+252,212,110,183, 94,101, 98,231,201, 60,189, 18, 93,231, 58,198, 99, 71, 86, 51,146,216,236,184,142, 65,133,207,229,108,102,224,
+185,248,141,216,231,175, 92, 49,245,216,184,230, 45,198, 44,136,171,198,237,255, 0, 48,135, 22,218,132,201, 1, 14, 57,121,110,
+245,203,113, 54,223, 76, 49, 16, 35,119,204,215,151, 53,226,222, 65,166, 70,248, 33,175,215, 57, 97, 4, 75, 38,154, 3,220,109,
+ 64,207,159,177,115, 76,206,185,215, 60,192,186, 70,142,235,152, 24,230, 27,168,221,170, 39,120,229,204, 44,183, 15,105,105,134,
+ 45, 64,145,223,117, 9,157,243,167, 8,122,210,185,228, 30,163,120,255, 0, 2,135,206, 57,191, 26,100, 92, 77,138,219,248,203,
+ 34,228, 30,102,182,181, 18,223,150,226,114,176,231,227, 91,236,172,175, 46,152,229,217, 19,205,190,224,237,194,117,254,213, 6,
+ 80, 81,121,181, 75,158,204,148, 33,150, 59, 46,249,180,197, 29,156,247, 6, 22, 76,217, 92,100,107, 34,118, 45,112,148, 23, 56,
+248, 99, 77, 42,208,214,198,247,182,148, 33,145,150,146,231,251,246,193,188,205, 37,237,189,176,158, 72, 29, 11, 68,110,146,102,
+208, 57,166, 34, 26,193,226,146,224,237, 47, 47,116,172,141,245,212, 11,228,107,128,106,174, 96,193,191, 50, 89,185,183, 63, 47,
+142,167,242,147, 82,239, 88,207,169,182,240,188,134, 47, 41, 88, 45,156, 85,114,196,175,248, 36,216, 92,105, 99,197,172,202,185,
+177,113,176,228,118,172,205,112,164,205,187, 76,135, 29,186, 33,245, 25,206,182,234, 27,108,187, 70,225,203,241,195,106, 46, 4,
+116, 14,183,214,223, 13,230, 64,225, 48, 51,190, 71,105, 45,124, 78,139, 80,107, 26,231, 28, 90, 52, 2, 9, 39,222,182,222,100,
+150,123,195,108,101,171,155,115,161,222, 36, 98, 34,215, 64,225,110,200,217,168, 57,147, 54,109, 37,210, 57,173, 24, 56,248,132,
+ 16, 5,174,244,245,109,245, 93,195, 24,167,170, 6,114,187, 71, 32,243, 87,240, 59,133,159, 37,244,225,143,102,252,147,106,188,
+229, 89,170,228, 96,152,243,247, 59, 73,190, 78,156,159,145, 97,121,216,185,199,109, 87, 39, 16, 26, 71,196,208, 49,252,173,213,
+189,234,125,183,120,150,204,198,232,225,212, 11,103,115, 24,224,214,126,115,195, 93,160, 12, 79,131,160,157, 0,212,231,222,170,
+181,108, 86,251,166,201, 13,240,145,178, 79,165,193,214,237,124,141, 46,127,228, 70, 92,221,101,221,209,227,235, 3, 89, 20, 25,
+119,104,190,102,112,239, 75,191,157,118, 19,234,195, 54,245,149, 47,210,206, 35,157,115,158, 99, 50,251, 37,219,191, 32,231, 88,
+118, 67,106,199, 23,124,216,209, 77,170, 59, 25,180, 81, 21, 49,109,237,136, 17,134,245, 6,227,213,164,208, 29,122, 31,113,230,
+158, 74,220, 54,168,246,127,173,145,150,204,166, 12,100,173, 46,211,143,120,152, 77,106,238,241,233,118, 43,204,187,103, 40,115,
+230,217,187,203,190,125, 4,114, 93, 73,171, 25, 36,133,193,186,176,238, 1, 48,165, 27,220, 29, 13,192, 46,153, 96, 92,245,252,
+194,151,220,166,197,143,101,254,157,120, 43, 8,197,174,178, 21,108,186,229,205, 57,142,204, 56,180,121,109,173,180, 79, 44,199,
+206, 46,111,186, 34, 56,164,184,164, 55, 13,210, 64, 32, 54,191,194,115,203,237,179,144, 45,225,115,224,187,184,145,224, 84, 54,
+146, 13, 84,252, 53, 48,180, 10,229,139,135,104, 90,110,223,186,249,143,115, 51, 35,184,179,182,142, 55, 26, 23,214, 51,166,191,
+138,130,119, 19, 67,141, 3, 93,216, 81,143,242,120,193,191, 51,204, 27, 43,231, 68,122,235,201,243,155,222, 41,117,184, 91,149,
+135, 64,228,156,245,142, 67,189, 35, 38,105,249, 38,124,171, 76,134, 38, 79, 16,109,171,100,182,148,199, 75,136,106,187, 75, 45,
+ 36, 5,147, 21,230,198,229,203,119,237,181,254, 68,198, 7,128,117,150, 48,176,105,160,210, 28, 8, 21,125,107,141, 9,233, 39,
+ 5, 47,228,222,213,205, 59,115,238,207, 48,200,247, 48,145,160, 73, 32,145,218,170,117, 22,144, 93,165,148,166, 21, 3,247, 64,
+197,119,145,118,203,123,138, 43,114, 27, 11, 82,186,149, 41,176, 73,214, 48,183, 85,194,143,205,243,209,231, 61,250,137,231, 79,
+203,179, 52,224,222, 53,254,247,226,252, 35,202,217, 86, 69,202,247, 38, 50, 75, 54, 63,253,216,179, 92,175, 24, 36,168,239, 22,
+ 46,119, 24, 82, 38,239,143,102,154,173,177, 27,117, 67,101, 8, 5,104, 10,217,124,175,230,187, 14, 93,176,221,161,188,151, 67,
+231,133,173,140,105,123,181, 16,201,133, 42,214,144, 49,115,126, 98, 6, 61, 69, 97,190,109,242,118,229,204,251,142,205, 61,140,
+ 58,227,183,157,206,148,234, 99,116,180,190, 2, 13, 28,230,151, 96,199, 96,208, 78, 29, 98,182, 11,243, 5,141,249,146,227, 49,
+ 56, 55, 58,252,191, 17,130, 94, 25,194, 21,149, 43,149,184,187, 41,122, 35, 50,121, 16, 93,209, 9, 22,246,212,155,139,144, 97,
+170, 60, 32,204,133,172,181,112,142,248, 90,211,177, 74, 73, 82,117, 3,200, 46,229,215,139,136, 55,239, 17,186,195,124, 57, 26,
+ 9,209, 74,234,249, 65, 53, 53, 25,181,205,160, 53, 3, 5, 98,243, 29,156,207, 25,182,184,229,223, 13,218, 11,188, 72,222, 64,
+241, 43, 77, 63, 49,104,160,161,201,237,117, 72,161, 56,174, 69,243,246, 13,249,208,254,104, 54,220, 91,130, 57,187,135,120,219,
+210,223, 5,177,147, 90,175,121,181,194,213, 53,149,170,251, 46,214,170,182,228,152,226,255, 0,123,186,207, 16,210,181, 59, 22,
+ 35,105,101,133, 60, 18, 94,118,168, 66,218,212,246, 77,223,147,188,181,115,239,108,103,150,238,235, 73, 12, 4, 28, 43,208,116,
+ 49,173,174, 78,113,212,224, 50, 24,144,114, 29,251,101,231,127, 52,219, 29,134,225,111, 13,157,166,160, 94, 65, 6,180,233, 2,
+ 71,185,212,205,173, 26, 90, 93, 77, 78,192, 17,217, 60,143,209,188,174, 56,226, 31, 68,124, 85,195,152,201,186, 89, 56, 15,158,
+184,150,245,145,202,118,116, 56, 55, 8,152, 30, 27,102,200, 98,202,185, 73, 92,135,163,153,110, 42,117,197, 46, 56,211, 1, 75,
+ 43,117,106, 67,116,221, 76,130,215,154, 62,186,227,114,187,189,125, 31,113, 4,128, 96, 72,214,247, 48,134,138, 3, 65, 70,208,
+ 19, 65, 64, 1, 43,107,188,229, 31,229,246,219, 93,157,139, 43, 29,181,196, 68,154,128,116, 49,146, 2,227, 82, 42,106,234,144,
+ 42,106,226, 64,205, 69,109,222,157,238,127,254,154,156,127,202, 60,119,233,116,240, 31,247, 51, 57,230,139,255, 0, 50,115,136,
+200, 49,165,167,212,158, 55,158, 91, 46, 81, 96,192, 67, 86, 91,180,204,130,127,157,123,155, 18,242,226, 47,176,227,166, 34,163,
+121,113,247,238, 7, 79, 37,223,154, 54,121, 45,103,189,241,203,217, 16,138, 45, 50,126, 67,152,230,146,238,243, 67, 5, 24, 29,
+ 31,229,185,197,250,170,234, 81, 50,135,151, 92,119,184,174,237,236,126,156, 50, 73,157, 44,218,163,255, 0,112,215,181,193,173,
+163, 28,100,117, 94, 91, 33,241, 90,208,194,202, 54,181, 93, 90,159,102,181, 93,255, 0,133,174,237,109,133,112,114,205,113,143,
+121,181,174,100,100,190,171,109,222, 50, 28,109, 18, 88, 42, 4,180,226, 16,234,210, 22,154, 26, 40,142,196,235, 60,142,103, 69,
+ 93, 36,138,138, 26,113, 29, 7,169,105,114,192,201,180,235, 0,233, 53, 21,224,122, 71, 94, 37,114, 75,157,125, 18,242, 6, 89,
+205, 92,229,200,152, 38, 45, 49, 24,142, 51,197, 62,140, 91,226, 78, 41,139,200, 3, 18,226, 78,121,127,129, 47,121,205,210,249,
+131,228, 22,104, 87, 24,236,150, 12, 57,150,214,109,210, 46,140, 8,204,190,242, 23,251, 86, 19, 45,163,169,236,156,227, 5,173,
+157,189,188,239, 26,221, 45,207,137, 38,141, 82, 69,227, 50, 38,178, 86, 56,180,154,212, 56,184, 48,234, 45, 4, 96,237, 37,100,
+ 59,247, 35,220, 93,223, 93, 92,193, 25,240,219, 13,167,133, 24,126,152,166,240, 95, 51,159, 11,216, 28, 5, 40, 88, 24, 94, 52,
+135, 16,113,104,120, 67,235, 79,160,252,175, 46,231,171,246, 69,201, 30,157,113, 57,220, 73,118,202,127, 48, 76,186,223, 96,203,
+ 78, 39,126,183, 91,110, 92,247,109,225,212, 99, 79,170,218,205,194,107, 77,202,157, 43, 29,189,165, 78,180,146, 89, 91,106, 91,
+139, 64,117,165,184,254, 94,118,138,214,197,177,219,221, 60, 78, 27,102,210, 91,226, 2, 68, 46,185,214, 53, 16, 48, 1,241,224,
+115, 4, 0, 13, 8, 17,240,242, 12,183,155,131,228,185,179, 97,183, 47,189,112,107,188, 55, 0,102,109,175,134,116,135, 30,241,
+ 44,147, 17,145, 4,146, 42, 9,128,122,118,244, 57,234, 83, 15,190, 99,188,135,206,184, 91,153,230, 55, 9,143, 76, 56,166,111,
+192,121, 78, 89,141,221, 44, 87,152,210,120, 15, 0,227,172,231, 57, 76,196,220,221,143, 46,239,138, 95,109, 82,226,161, 51,100,
+132,174, 18, 46, 42,132, 28,118,100,119, 22,251,127,231, 61,186,237,143,183,178,147, 67,207,142,230, 76,214,188, 17,254,238,105,
+162,138,154,106, 25, 35, 28, 15,116, 96,243, 30,186, 6, 56, 8,254, 92,228, 93,206,206, 70, 92,223,199,226, 48,125, 59, 95, 11,
+157, 25, 7,253,148, 48, 77, 53,117, 16,100,141,237,115,123,198,133,130, 66,202,151,180,155, 45,249,119,241,164,220,194, 70,119,
+201, 60,149, 43, 23,228,251, 71, 13, 61,100,244,127,233,211, 54, 76,166, 50,251,126, 77,197, 94,153,175, 55, 23,226,102, 12, 74,
+ 9, 92,101,220, 47, 23, 25, 81,154,155, 33,189,202, 76,155,104,216,179,183,122,171,188,251,184,139, 65, 29,189,184,116,110,154,
+183, 51, 55, 22,150,201, 59, 64, 49,145,158,150,180, 18,208,115,108,152,142, 10,205,229,206,216,235,195, 45,205,209,100,173,134,
+150,176, 62,161,193,209,219,189,196, 74, 14, 90,156,226, 3,136,196, 58, 44, 15, 19,213,155, 61,150,207,143, 91, 99, 89,172, 22,
+155,101,142,209, 8, 56,152,118,171, 60, 6,173,150,216,137,121,106,113, 97,166, 24, 66, 26,111,115,139, 82,142,212,138,146, 79,
+115,172,198, 89,159,112,226,249, 28, 92,227,153, 38,164,250,202,214, 33,129,150,205, 12,141,161,173, 25, 0, 0, 3,212, 19,150,
+147, 74,172,208, 65,102,130, 11, 52, 16, 89,160,130,205, 4, 22,104, 32,179, 65, 5,154, 8, 44,208, 65,102,130, 11, 52, 16, 89,
+160,130,205, 4, 22,104, 32,134,124,167,195,252,125,205, 22,107, 6, 63,200,246, 22,242, 27, 70, 51,156,225,188,141,104,134,235,
+238, 48,219, 57, 86, 7, 53,185,246,231,151,229,169, 62,106, 18,251,116,113,165,213, 14, 32,169, 11, 5, 42, 35, 79,246,253,206,
+109,173,206,124, 14,210, 92,199, 48,255, 0,101,194,135,246, 28,193,197, 37, 44, 45,156, 0,225, 90, 16,125, 97, 10,237,254,141,
+125, 58, 91,101,226,210,227,241,228, 37,156, 55,148, 57, 67,152,108, 49,165, 76,126, 93,190, 54,111,204, 49,230,197,190, 58,184,
+238, 56,166, 93,101,230, 39, 41, 12,198, 82, 75,109,108,107,203, 74,124,180, 82, 65,252,207,122,240,240,100, 61,232,217, 25,202,
+186, 99, 32,183, 30,154,140, 78,102,166,185,164,133,148, 98,152,100, 73,245,156,211, 67,126,134,253, 52, 55,141, 96,248,159,248,
+126, 29,179,113,223, 16,114, 39, 6, 98,237,200,188,204,145, 42, 47, 29,242,163, 76,181,122,142,235,235,121, 78,190,244,148,180,
+ 74,100,184, 75,136, 43,112,161, 64,184,170,168,121,178,252,190, 73, 60, 78,243,229,100,142,192,124,236,249, 77, 56, 1,209,145,
+160,174, 72,191, 67, 21, 0,166, 1,164, 14,195,154, 89,126,244,107,195, 23,216,152,132, 52,185,201, 24,234, 56,250, 70, 59, 35,
+ 2,127, 12,229,140,135, 14,155,132,171, 24,198, 94,196, 35, 34,210,253,186,225, 29,219,123,107,176,190,227, 15,182,202,146,151,
+ 74,148,167, 2,148,165, 18, 88,121,158,234, 18,243,249,110,215, 93, 90,152,199,106,171,252, 67,168, 16,107,222, 21, 21,203,130,
+235,172,152,234,102, 41,149, 9, 20,160,166, 30,165, 25,181,254, 95,254,153,177,199, 17, 47, 11,198,243, 30, 62,188,176,251, 78,
+ 68,201,248,251,148,242, 92, 43, 46,137, 28,216,172,248,236,152,194,235,110,186, 49,112,113,155,133,186,195, 5, 83, 16,235,170,
+243, 95,105, 50,151, 89, 3,205,211,137, 57,202,254,124, 37,115, 94,222,135,177,142,111,204,231,131,164,180,138,130,231, 82,131,
+ 0,116,142,238, 8,163,111,137,191, 40, 32,244,130, 65,200, 15,184,125,185,167,153, 94,134,253, 54,206,194,109,156,119, 59, 11,
+185,206,196,108,247,222, 84,201,109,246,233,185,141,222, 92,166,111,124,202,101,170,247, 36,205,114,106,167,173,197,185, 53,199,
+ 35,186,167,138,217, 94,213,182,160,180,133, 4,155,205,151,204,148,206, 30, 3,200, 96, 36, 53,185, 71, 77, 34,148,165, 48,196,
+ 82,132, 96,112, 93, 54, 17, 22,233, 35, 10,147,153,227,154,108,143,232, 63,129,161,220,238, 89, 28, 41,124,205, 7, 52,189, 92,
+ 46, 83,239, 92,135, 3,212, 14,107, 3,145,111, 40,189,219,108,214,153,209,101, 95, 25,190, 34,228,252,105, 81, 49,235,117, 99,
+173,226,134,212,195,106,100, 54, 80,154, 29,220,221,120,230,134, 17, 17, 96, 0, 6, 24,163, 44, 20, 46,112, 33,186,104, 8, 46,
+118, 52,169,169,173, 87, 5,132, 96,215,189, 94,157, 70,188, 6,117,234, 9,253, 30,139,120, 9, 24,181,235, 9, 22, 60,167,251,
+173,125,153,146, 93,228,218, 7, 34, 95, 80,220, 76,139, 38,202, 27,204, 92,187,197,117, 55, 1, 34, 53,194, 38, 66,210, 36,196,
+156,219,129,230,105,181, 11, 9, 36, 20, 79, 52,222, 25, 27, 46,166,235, 0, 10,232,110, 65,158, 30,147,133, 11, 75, 48, 45,200,
+241, 8,223, 67, 29, 11,104,105,218,122,107, 94,218,241, 81,123,151,161,126, 20,131,133,114,253,147, 14,199, 91, 86, 79,203,248,
+ 1,195,114,123,255, 0, 34,228,121, 14,112,156,150,100, 75,181,223, 32,139,112,187,190, 47, 81, 47, 18,100,166,245,122,145, 33,
+ 82,216,156,211,233,253,154, 91,113, 41,101,180,165,195, 57,182,233,242,194,249, 93,221,137,250,154, 24, 24,218,119, 90,210, 26,
+ 52,150,129,165,160, 80,180,140,234, 49, 40,134,193,129,174, 13, 24,184, 80,214,167,137, 56,227, 92,207, 74,146,250, 82,244,223,
+119,244,247,106,228,201, 89, 94,123, 51,145, 51,110, 89,207,218,206,242,123,212,137, 55,121,177,226, 42,221,103,181,216,225, 68,
+102, 69,254,241,126,188,202,242,161, 90,155, 82,221,147, 57, 95, 18,138, 91, 67, 77, 37,182,210,135, 48,239,141,222, 93, 16,142,
+ 48,200,227,102,150,142,239, 23, 23, 19, 70,181,173, 24,187, 32,222,210, 77, 74, 61,165,177,183, 14,169,169, 38,188,122, 41,196,
+147,195,165, 90, 27,149,174,221,120,136,228, 11,172, 24,183, 8, 79, 83,204,141, 45,148,190,210,136,236,104,160,104, 71,129, 29,
+ 71,134,160, 35,145,209, 29, 77, 36, 20,232,128,236, 10,230,223, 59,122, 71,228, 23,178,197, 95, 56,121, 86,235,134, 55,114,105,
+189,216,165,208, 52,149, 98,210, 90, 7,122, 33,186,253,194, 18, 76, 87,148,124,196,180, 74,138, 22, 84, 5, 16, 82, 5,195,104,
+223,217, 20,122, 38, 52, 61, 52, 38,190,206, 42, 46,234,205,206, 53,102, 42, 37,197,254,138,121, 18,243,150, 65,157,204,102, 5,
+187, 24,180, 62,137,205,218,237,110, 71,221, 53,246,255, 0, 10, 64,102,116,245, 21,215,179,170,113, 33, 2,165, 8,223, 69,135,
+ 23,220,201, 19, 25,249, 71, 83,248, 96, 64, 29,120,231,212,137, 13,139,137,239,138, 5,213, 88,112,161,219,227,181, 18, 12,102,
+ 98,198, 97,166, 88,105,150, 27, 13,161, 13, 48,144,132, 39,167,245, 80,144, 7,187, 84,103, 60,188,212,154,149, 46, 5, 50, 74,
+180, 85,213,154, 8, 47,231,159,125,254,109,127,204, 38,218,132,252,175, 12,250, 45,113,213, 16, 18,151,184,243, 57, 80,169,255,
+ 0, 87,145, 83,170, 37,175, 50,221, 76,123,205,101, 59, 15,241, 42,149,190,249,113, 41,197,172,246, 31,138,178,156, 11,252,201,
+191,153, 47, 42,204,105,220,131,134,253, 26, 89,172,107,107,204, 84,184,152, 6,107, 25,226, 61,160,189,200,111, 36,123,170, 53,
+ 76,230,175, 52,231,217, 6,152, 25, 27,228,174, 68, 56,253,142, 10, 23,117,231,105, 44,123,177,181,174,119, 69, 15,220, 85,160,
+191,255, 0, 48,135,169,188, 57,149, 77,202, 44, 62,150, 26,132,132,130,161, 3, 2,203, 28,127,119,210,188,216, 32, 83, 80,155,
+127,154, 28,195,184,182,177,216,197,235, 15, 31,252,229, 39,107,205, 91,173,200,168,182,111,191,248,148,115,255, 0,185, 79,153,
+221,130, 39,193,195,253, 62, 79,142, 80,165,249,172,225,217, 34, 82, 2, 5, 77, 64,203,214, 70,173,150,123,239, 53, 94, 13, 95,
+ 79,108,209,214, 36,255, 0, 80, 41,219,123,173,226,224,106,240,162, 3,172, 59,248,144,194,209,252,208,254,162,242, 27,180,219,
+125,159,137,120, 5,230, 97,184,166,204,149,226, 57, 62,213,169, 61, 59,255, 0,123, 82, 53, 51,105,127,204, 51,154, 57,182,163,
+251,175,255, 0, 85, 61,181,126,229,112,234, 31, 4,122,157,252, 73,246, 95,243, 44,122,178, 97,123, 90,226, 47, 78,100,120,111,
+196,242,114,126,236,196,106,110, 23,110,239, 29,227,111,254, 23,255, 0,168,165,197,173,232,204,197,236,119,241, 38,213,255, 0,
+ 50,247,171,227,248, 56,147,211, 74, 61,238, 97,217, 74,255, 0, 70,106,157, 58, 31,205, 56,248, 7,212,239,226, 40,255, 0, 77,
+118, 51, 49,251, 15,197, 37,115,249,151, 61,101,144,124,158, 44,244,184,147, 78,158,118, 15,151, 40, 87,253,156,220,105,120,223,
+124, 15,125,177,250,171,241, 74, 8,110, 6, 97,190,164,208,191,230, 92,245,210, 20, 66, 56,163,210, 89, 79,133,112, 76,198,167,
+255, 0,235,205, 75,178,164,119,179, 79,217,108, 8,198,181, 75,225,255, 0, 50, 63,175,153,230,145,184,139,210, 90,207,255, 0,
+200,185,135,255, 0, 30,104,175,149,172,204,165,155, 99,175, 42,173, 82, 63,153, 55,215,180, 87,204,103,184,139,210, 98, 93, 31,
+171,253,196,204,127,248,243, 70,107,218,225, 90,174, 27, 16, 13, 49, 73, 87,252,203, 94,187, 91, 59, 92,226,111, 73,105, 35,195,
+251,137,152,255, 0,241,230,140, 40,236,151, 62,144, 12,234,158,173,191,204,117,235,246,234,141,241,120,139,210, 82,144, 63,173,
+130,230, 63,252,121,164, 37,184,100, 57,165, 25, 96, 36,200,148,154,233,252,200, 62,189,237, 74, 31, 55,196, 62,145,193, 62, 35,
+ 4,204, 9,255, 0,223,205, 8,167,108,217, 32,253,188, 51, 50, 83, 49,254,101,207, 93, 68,215,252, 36,244,145, 95,105,192,243,
+ 2,127,247,243, 78, 40,147,250, 70,244,149,176,255, 0, 50,223,174,115,180,142, 37,244,146,162, 77, 41,253,195,204, 43,245,127,
+235,230,138, 42,141,244,109,233, 41, 83,127,204,179,235,125, 43, 2, 71, 17,250, 83, 66, 8,248,138,112, 76,189, 39,255, 0,126,
+ 78,136, 73, 57, 81, 27,232,216, 51,175,167,169, 36,151,252,203,126,183,210,163,242,188, 73,233, 41, 73,246,189,128,229,228,253,
+217,216,209,154, 15, 20, 87, 89,179,129, 41,189,175,230, 94,245,226, 74,247,113, 7,164, 21, 80,157,133, 24, 14, 98,158,158,250,
+231,135, 74,119, 82,102,207, 28, 10, 84,223,243, 47,122,233, 73, 5, 92, 73,233, 25,178,127, 17, 70, 7,152,143,255, 0,191, 52,
+ 83,212,148, 22, 77,226, 74,214,239,243, 53,122,231, 65,162,120,167,210, 73,240,235,130,102, 63,252,121,162,174,253, 19, 58, 74,
+144, 74,254,100,111, 93,195, 27,153,120,143,197,126,145, 95,151, 25,131, 37,184,202,192,243, 5, 33,104,110,133, 98,159,223,208,
+170,237,173, 58,234, 15,113,220,165,182,107,140, 64, 84, 14, 32,159,176,133, 98,216,121,126,214,254,230, 56,238, 28,240,199, 56,
+ 3,164,128,113,235, 45, 35,220,148, 91,127,153, 51,214,229,198,217, 30,106,120,175,210,141, 29,105, 11, 90, 6, 13,151,209, 27,
+197,123,127,126, 73,167, 93,102,247, 30, 97, 95, 67,148,113,123, 29,252,107,210,214,159,167,157,142,229,186,188,123,175,241,199,
+254,138,210,255, 0,243, 34,250,222, 98,133,142, 38,244,150, 22,180,133, 2,172, 19, 46, 34,191, 86,116, 60,116,132, 94,100,223,
+ 63, 54, 69,236,119,241,165,157,250,115,217, 7,253,123,175,241,197,254,138, 68,207,243, 42,122,236,120,236, 60, 77,233, 47,117,
+105,255, 0,113,115, 10, 5,127,237,230,164,163,231,219,183,225,162, 63, 99,191,137, 23,255, 0,183, 61,151,255, 0,126,235,252,
+113,255, 0,164,159,237,127,204,119,235,154, 99,168, 75,220, 79,233, 61, 53, 35,113,107, 6,203,130,169,223,161, 57,209,211,248,
+121,202,234, 65,139, 35,246, 59,248,146, 50,254,157,246,102,127,214,186,255, 0, 28,127,233, 45, 87,175,230, 71,245,195,110,102,
+ 66,217,226,175, 74, 74, 91, 96,148,121,184, 62, 94,180,138, 2, 78,237,185,202, 79,134,158,142,105,185,253,214,123, 15,241, 40,
+185,252,134,218, 34, 4,137,174,127,197, 31,250, 72,233,108,252,253,253, 99,189,197,150,220,226,225,198,190,153,209,115,155, 15,
+230, 22,212,124, 67, 41, 77,181, 46,239,219, 64,133,102, 42,114,148, 32,254,240,234,171,185,249,139,125,102,242,214, 71, 17,237,
+ 14,254, 48,156,108,222, 64,236,219,140,166, 55,205,116, 0,232,116,125, 31,255, 0, 17, 81,188, 35,249,134,253, 95,101, 31,198,
+155,147,198, 62,154,132,139,108, 73, 18, 89,110, 22, 33,148, 36,172,178,146,164,133, 5,230, 75, 39,121, 27, 69, 8,235,164, 32,
+243, 31,112,149,236,105,100, 32, 56,129, 93, 47,233,254,218,152,187,253, 58,108, 22,241,200,241, 61,225, 45,105, 52,215, 22, 52,
+ 4,255, 0,236,241, 85,234,119,243, 48,122,244,108,191, 22, 71, 15,122, 68, 90, 79,152,195,236, 61,129,102, 46, 37, 73, 53, 74,
+144,160,115,218, 43,167, 66, 8,214,213, 12,222, 32, 14, 7,214,188,147,119,179, 54,221,206,141,218,129, 6,132, 26,123, 14, 9,
+174,217,252,204,190,183, 45, 16,226, 90,224,240,159,164, 11,109,182,223, 29,152,112,109,246,206, 61,203,160,193,133, 14, 58, 66,
+ 91,105,150, 81,157, 6,218, 66, 18, 0, 74, 82, 0, 3,160,210,242, 61,242,146,231, 26,147,137, 39, 18, 79, 90, 99, 30,221, 20,
+ 45, 12,104,163, 64,160, 2,128, 1,212, 40,158,191,251,157, 61,108,237,175,248, 71,233, 81, 38,158, 56, 78, 92, 69,127,246,228,
+105, 46,247, 82, 87,232,163,235,247,124, 22,148,255, 0, 51,127,174,103, 77, 26,226,111, 73,125,251,171, 5,204, 79,232,207, 52,
+ 9, 33, 24,109,236, 60, 79,167,169, 54, 92,255, 0,153,207,215,226, 95,137,109,178,240,239,164, 89,183,105,210, 89,142,203, 14,
+ 96,121,153,109,180,188,105,189, 84,207,146,104,158,253,245, 92,222,249,142, 61,161,142, 56, 23,142, 10,255, 0,201,222, 89,201,
+205, 51, 48, 29,109,136,156, 92, 41,238,194,138,209,179,252,193,158,176,173,152,252,121,185, 47, 30,250, 95,254, 44, 98,165,233,
+109,219,112,204,170, 60, 38,220,219, 82, 18,151,115, 87,151,223,218,173,101,211,121,159,184,135,105,142, 56,115,253,215,255, 0,
+ 26,244,116, 31,166, 93,135,195,213, 45,197,221,105,193,241, 15,182, 18,170, 47, 40,127, 52,207,173,220, 78, 67, 80,113,142, 34,
+244,151, 62,108,151, 10, 24,110,229,132,102, 47, 4,160,119, 90,195, 89,219, 6,128,106,217,179,115,109,245,243,117, 76,200,128,
+234, 14,251,220, 86,101,205, 30, 80,236,187, 92,162, 43, 73,110, 92,127,172,232,207,217, 16, 81, 8,159,205, 61,249,138, 72,105,
+ 11, 60, 51,232,200,173, 67,174,206, 59,206, 2,106, 7,191,145, 73,212,193,230, 73,135,225,111,176,252, 84, 99, 60,162,177,112,
+255, 0, 50,106,255, 0,105,159,192,157,160,255, 0, 52,119,230, 31, 36,213,206, 30,244,104,148,127,163,199,153,184,251,207, 33,
+157, 32,254,105,153,163, 6,179,216,126, 41,220, 94, 77, 88, 63, 57, 39,255, 0, 19, 63,129, 77, 97,127, 51,135,175,121, 44,135,
+ 23,196,190,144,129, 0, 21, 4, 96, 57,152, 6,190,202,231,231, 76, 31,206, 87, 13,252, 44,246, 59,248,148,132,126, 72,237,142,
+206, 91,143,241, 51,253, 52,228,207,243, 50,122,245,112,252, 92, 71,233, 30,157, 43,179, 2,204,171,244, 1,253,254,235,162, 14,
+116,185, 63,134, 63, 99,191,137, 58, 30, 70,109, 92,101,184,255, 0, 20,127,233,167,102, 63,153, 91,215, 99,160, 21,113, 71,164,
+177, 83, 77,169,193,115, 16,160,126,188,239, 65,220,235,114,223,193, 31,177,223,196,148, 30, 69,109, 63,251,215, 63,226,143,253,
+ 36,205,115,254,102,175, 93,176,221, 12,177,196,190,146,157, 90,148,132, 37, 10,192,243, 21,173,110, 44,208, 0, 6,122, 59,158,
+154, 69,220,239,118, 50,100,126,199,127, 18,227,252,140,217,216, 43,227, 92,255, 0,138, 63,244,148,186, 55,243, 39,250,216,110,
+ 35, 6,229,198,126,147,126,124,160, 42, 75, 80,112,108,193,113,219, 81,235,181, 42, 57,210,137,167,109, 90,118,221,206,246,233,
+186,165,107, 5,122, 1,251,220,178, 30,100,229,141,171,108,148,197,106,249,156, 70,101,206, 97, 30,170, 48, 36, 83, 63,153,131,
+214,147, 40, 42, 99,137,253, 46, 46,149,248,149,130,229,202, 79,221,156,131,169,166, 79, 33,207, 79,191,226,170, 46,218,162, 25,
+ 23,123,190, 10, 29, 43,249,157,253,118,161,194,152,252, 75,233, 29, 73, 29,188,220, 7, 50,221,245,211, 62, 26,118,215, 19,154,
+ 65,219,116, 99, 34,125,223, 4,147,255, 0,185,243,215,178,127, 23, 16,250, 66, 34,190, 24, 38,102,147, 79,253,190, 58,237, 79,
+ 4, 95,229,236,233, 62,239,130,222,239,243, 62,250,236, 12,130,207, 16,250, 73, 83,255, 0,213, 86, 13,152,148, 87,232, 25,224,
+ 63,126,147,212,250,227, 74,122,117,174,157,190, 62, 4,251,190, 9, 10,255, 0,154, 11,215,195,105, 59,248,115,210, 42, 87, 79,
+135,255, 0, 81, 51, 34,154,251,255, 0,245,251, 71, 14, 39,161, 23,249,123, 7, 19,238,248, 38,127,254,232,191,204, 29, 36,149,
+240,255, 0,163,141,128,254,175, 31,230,187,169,255, 0,212, 47,232,209,234,137,244, 45,233, 41, 59,255, 0,205, 51,235,241,160,
+ 54,112,215,164, 5, 19,220,156, 11, 52,160, 63,253, 64,209, 14,174,165,199, 89,176,116,250,122,146, 23,127,154,123,243, 4,109,
+ 11, 42,225,255, 0, 70,205, 40, 36,148,249,156,125,155, 41, 38,159, 71, 33,141, 19,196,113,224,131,108,152,238, 37, 71, 97,255,
+ 0, 53,103,230, 63, 58, 74,152,143,194,126,139,150,132,168,130,239,248,119,156,132, 1,237,255, 0,230, 55, 93, 28,200, 26, 49,
+ 73, 27,102,142, 37, 78, 90,254,104,255, 0, 95,108,199, 43,184,241, 47,163,159,152,167, 68, 70,192, 51, 84, 36,125, 59,185, 5,
+ 71,239,211,115,114,120, 4,217,204, 3, 36,186,205,252,208,222,190,238, 43, 90,222,226, 31, 71,237,198, 74,168,149, 35, 2,205,
+ 2,200,250,249, 0,143,187, 73,186,233,227,128, 69, 32, 5,190,245,252,209, 30,187, 45,204, 45,200,252, 79,233, 5,107, 2,163,
+205,192,243, 53, 38,191, 86,126,147,160,203,167,156,192, 92, 13,170, 5,228,127,205,175,249,132,217, 89,117,108,240,207,162,215,
+ 28, 73, 33,176,239, 30,103, 37, 38,158,218,114, 50, 78,157, 70,247, 61, 40, 35,170, 23,185,252,224, 63,153,144, 63,178,224,207,
+ 67, 4,120,110,227, 76,248,159,187,147, 70,156, 22,163,248, 33, 32, 99,249,193,255, 0, 51,215,100,249, 42,224,143, 66,161, 27,
+169, 81,198,124,128, 21, 79,254,167, 29, 34,237, 67, 42, 34, 24,148,150, 23,243,117,126,103, 82,158, 40, 87, 6,122, 24, 67, 96,
+ 84, 31,240,207, 63,221, 95,254,166,255, 0, 70,147,241, 28, 5,112, 71,250,117, 52,143,252,217,223,153, 11,182,183,165, 57,194,
+254,136,211, 49,178,173,141,167,141,243,191, 40,128, 60, 65,228,157,221,253,250, 98,111,100,241, 52, 80, 83,215,241, 72,150, 16,
+104,156,155,254,108, 63,204,104,199,138,235,156, 45,232,168, 41,237,187,194,120,235, 58, 9, 21, 30, 21,228,115,168,217, 55,169,
+152, 93,131,112,234, 63, 20,207,197,117, 72,193, 59, 47,249,174,191, 48,196, 77,102, 55,248, 53,232,199, 98,218,222,181,127,135,
+153,198,224,125,223,255, 0,145,117, 20,121,158,228, 70, 95,165,153,244, 31,226, 92,100,206, 44, 46, 32, 39, 1,252,214, 31,152,
+ 49,130,185,127,224,231,163, 93,201,150,219, 0,127,135,217,190,207, 45, 97,100,159,254, 97,214,191, 8,211, 63,249,133,222,170,
+105,142,148,232,119,241, 40,239,230, 82,107,211, 65, 79, 95,197,112, 55, 38,225,254, 24,197, 96,139,204,139,218,239, 10,136, 60,
+244,239, 88,216,162,223, 94,202, 87,244,107, 37,178,230, 13,202,253,254, 24,102,154,172,170, 61,214,238,119,120,109,109, 42,157,
+ 56, 71,154,151,146, 77,185, 91,236,208,254, 94,207,106, 42,143, 16, 51, 64,133,121,100, 1,215,196,251,117,120,219,185, 2, 41,
+ 72,150,225,213,118,102,170,235,178,114,131, 30, 68,179, 26,185, 23, 51, 70, 93,200,155, 45, 93,208,100, 49, 33,178, 11, 78, 85,
+ 91,107,236,174,180,173,179,111,138,201,154, 24, 5, 22,139, 29,147,109,219,164,101,216,170,174, 99, 58, 79, 28, 89,102,217,161,
+188, 86, 46,238,169,171,123,100,252, 72, 14,154, 10,117,241,174,151,145,190, 8, 32,113, 76,231, 38,217,165,163,138, 37,113,174,
+ 54,108, 88,228, 53,173, 39,231,102,160, 73,146,225, 31, 25, 83,157,122,253,186,115,107, 24,141,169,205,148, 62, 19,122,212,253,
+207, 48, 85,110,168,144, 7,115,167,173, 52, 79,170,181, 80,169, 53, 72,173,123,104,245, 93,205, 49,207,114,228,219,173, 38, 51,
+ 37, 72, 43, 78,245, 83,245,116,180, 69,188, 82, 51,234, 35,187,154,242,137, 87,135,167,108, 84,112,136,200, 64,162,232,122,171,
+233,210,146,185,167, 36, 75, 70, 61,131,188,166,246,187,245,202,216, 82,166, 21, 66, 60, 59,118,211, 9,173,155, 54,106, 78, 57,
+139, 50, 83, 7,239,226,108, 63,157,117,166, 62,112, 83,184, 21, 58,101,244,197,174,211,141, 19,159, 23, 10,241, 67,187,212,153,
+210,246,187, 29, 8, 75,160,212,129, 78,191,163, 82, 86,237, 17,103,146, 97,113,170, 65,134,105, 92, 44,131, 33,138,202, 90,101,
+ 95, 47,180, 10,237, 20,169, 26,117, 51, 34,148, 98, 20,108, 17,207, 11,171,171, 5,249, 42,117,198,225, 69, 77,125,110,171,223,
+237,211, 70, 68,216,242, 10, 88,188,187, 52,128,182, 71,134,148,170, 45, 23,182,247, 54,180,172, 38,187, 72, 52, 61,123,107,135,
+ 16,186, 48, 79, 18,174,198, 67, 30, 87,202,182,131,180, 39,120, 29,116,221,144,104, 53,170, 85,210,106,194,137,132, 70,121,243,
+ 70,208, 85, 83,210,157,186,233,103, 60, 55, 52,152,105, 43,114,173,210, 98, 81, 79,167, 98, 84, 43,208,131,162, 9, 4,153, 35,
+104, 45,205, 36,146,168,133,165, 4,173, 65,202,244, 21,208, 5,192,245, 33,164, 38,166,161,151,150, 55, 19, 66,104, 43,216,105,
+ 71, 58,136, 53,168,173,106,197, 55,194, 74,220,187, 22,217, 91,100, 22,203,128, 13,170, 20, 34,158, 61, 53, 11, 61,192, 36,141,
+ 42, 90,222, 18, 40, 65,201, 67,113,101, 61,108,151,124,197,159,116,188,109, 82,202, 33,185,187,119,204,193,148, 10,218, 82, 72,
+247,124, 63, 78,177,110, 98,178,250, 73, 92, 50, 7, 17,235, 94,215,242,239,125,254,115, 99, 27,142, 46, 3, 73,237, 10, 94,139,
+116,185, 9, 74,219,109,195,180, 43,117, 18,106, 19,210,158,234,234,163,168, 51,138,209,140,110,119, 5,231,248, 99,241, 31, 11,
+ 91, 46, 33, 10, 59,208,178,159,129, 96,247, 0,246, 61,245, 49,107, 40,126, 73,118,194, 64,169, 82,187, 51,172,182, 73, 45,214,
+160,117, 63,171, 95,242,106,201,104, 52,140, 84,125,224,160, 81, 76,193, 94, 76, 89,234,223, 81,228,188, 84, 79,234, 13,166,191,
+113, 58,155, 96,195, 21, 83,191,120,210, 85,177,205,238,109,227, 62,158,112, 75,107,100, 7,166,219, 34, 73,117, 42, 85, 84, 67,
+232, 5, 66,155,186, 85, 73,175,252,218,206,247,134,137, 38, 61,169,215, 43, 3,227, 75, 39, 70, 10,149, 98, 25,181,206,221,126,
+125,187,124,199,162,166,229,178, 36,165,182,186, 81, 42, 95, 90, 80, 40,209, 61,232, 7,113,227,216,175, 13,184,210, 9, 25, 39,
+115,223,187,196, 32, 28,211,101,197,183,215, 50, 82,148,202,210, 84,243,132,165, 74, 11, 80,169,236, 72, 36, 87,219, 77,122, 11,
+111,120,240, 89, 78,128,188, 39,191,194,239,171,155, 86,122,207,218,153, 29,104, 2,119, 54, 71,213,169, 32,234,170,251,163, 33,
+ 52,203, 74, 82, 13, 7,126,154, 53, 81, 52, 45,176,153,117, 13,173,240,211,138, 74, 1, 80,162,106, 10,135,187,199, 81,219,133,
+252,118, 49,151,200,224, 0, 83,123, 46,207, 54,241, 59, 96,129,165,206, 60, 2, 51,224,152,226, 45,205, 55,146,220,162,249,115,
+157, 11,121,130,234,119, 22, 5, 1, 1, 36,251,255, 0, 14,188,243,188,110,231,115,153,210, 87, 51,130,247,127, 43,114,219, 57,
+118,210, 43,112, 49,104,196,245,230,154,121, 23,145, 92, 68, 41, 73,113,103,178,201,248,232,128, 18, 60, 5,122,251,180,207,111,
+176, 51,188, 41, 61,251,122, 22, 80, 56,245, 42, 40,171,183,247,138,249, 46,238,247,198,208, 87,203,196, 77, 74,130, 91,111,186,
+170, 79,138,181,166,197, 8,180,140, 48, 44, 18, 41,206,225, 51,166,118, 53, 56, 34,141,176,178,152,205,138,124, 64,124, 64, 10,
+138, 42,148, 29,125,186, 70,103,112, 86,187, 88,197, 19,227, 78,179,230, 20,160,124, 41,248, 66, 69, 41, 81,246,118,212,108,239,
+210,165, 97,135, 82,156, 91, 92, 97, 45, 36, 18,181, 84, 36, 4, 10, 26,245,241, 36,254,141, 68,201, 34,149,138,220, 41, 69,189,
+165,203,144,134,211, 84, 2,160, 64, 71,226,218, 60, 41,212,159,171, 92,108,189, 37, 56, 48, 41,123,182,255, 0,144,130,251,202,
+108,182, 27, 71,195,184, 4, 56,189,195,191, 82,104, 15,188,232,237,146,169, 23,196, 66, 23,219,223,143, 34,100,219,132,147,230,
+ 34, 48, 91, 17,219, 66,146, 74,228,175,241, 40,248, 0,129,208,120,214,186,154,216,246,231, 95, 76, 14, 52, 24,149,159,243,167,
+ 48,199,179,219, 56, 18, 11,157,128, 31,106, 89, 2,240, 96, 23,118,199,105,208,162, 78,247, 0, 52, 10,214,172, 45, 69, 6, 37,
+121,106, 89,204,142, 46,235, 74, 93,202,157, 82, 20,129, 17,154, 40,117,248, 0,167,221,163, 11, 64, 78,105, 19,113,194,138, 31,
+ 45,207,152,117, 78,236, 8,220,107,180,118,211,182, 13, 2,137,187,141, 82, 23, 18, 66, 73,218, 77, 5,122, 15,102,141,146, 37,
+ 18, 38,139,175, 60, 16,211,110, 21, 31,195, 68,248,232,133,224,102,138,218,146,156, 37,197,187, 50,223,197, 17, 75, 74,147,208,
+211,174,146,214,210,112, 40,207, 14, 28, 20, 96,199,156,167, 84, 21, 25,212,162,132,212,166,131, 75, 9, 27, 76,210, 97,164,168,
+237,197,185, 45,172,182,128,126, 47,184,232,120,192,113, 72, 74,237, 9, 34,216,100,165, 31, 56,165, 56,164,212,237,211,105, 39,
+ 35,229, 77,196,154,150,164,220,188,149,252,188, 80,136,137, 87,194, 84, 0, 11, 63, 94,145, 14, 46,205, 54,147, 58,149,181, 41,
+111,207, 73,121,229, 58, 15, 85, 2,170,143,211,161, 82,136,104, 6, 9,241,119,150, 32, 52, 91,105, 65, 40,219,218,160,104,186,
+ 75,146, 96,113, 67, 44,167, 43, 1,167, 2, 29,168,165, 8, 10,255, 0, 62,150, 99, 40,142,209, 85, 92,175,243,220,188, 57,177,
+ 10, 52, 66,137, 34,181,174,164, 34,109, 18,204, 9, 69,186,200,167, 91,108,173, 62,206,164,119,210,133,201, 74, 39, 1,106,141,
+ 22, 82, 20,182,194,168, 65, 32, 10,233, 55,214,136, 28, 20,197,182,163, 7,153, 45, 49,177, 14, 38,159,134,132,157, 34,214,146,
+ 49, 74,146, 28, 18,248,177, 92, 51, 87, 28,182,175, 37, 68,120,116, 58,106,248,168,234,164,220,197, 60,155, 17,166, 45,236, 4,
+163,226,110,135,168,234, 53, 94,186,182, 34,170, 52, 67, 82, 66,102, 13, 45,233, 75,146,107,181, 13,109,168,240,213,126,104, 67,
+ 90, 25,210, 82, 83,197,161,148, 82, 65, 25, 31,221,231, 19,215,127,206,178,170,248,211,106,255, 0,167, 77, 62,152,106,201, 70,
+125, 40,213, 84, 27,206, 39,114, 46, 80,211,236, 65,199,111, 76, 90,155, 74,144,219,105,136,166,210,177, 79,125, 53,221,177,150,
+118, 36, 23, 72,210,238,213, 87,219,237,224,181, 32,185,192,185, 28,189, 31, 97,153,132,185,200,178, 53,111,145,107,126, 76,157,
+210, 36,207,104,178,195, 72, 90,250,146,163,211,160,247,233,222,249,205,118,155, 76,126, 35,223, 80, 56, 12,202,176,187,120,138,
+208, 84,185,118,122,221,195, 28,112,145, 28,102,121,188, 47, 61,182,193,121, 17,157, 82,130, 40, 5,106, 17, 64, 41,244,235, 44,
+159,205, 93,218,250,167,110,178,113,111, 2, 71,197, 69, 93,115,141,221,203,180,219, 66, 72,233,162,139,185,194,126,134,243,156,
+218, 26,110,188,141,243,115,172, 75, 65,122, 27, 97, 69, 9,113, 63, 75,222,239, 17,170,213,215, 59,115,189,209,252,171, 74,122,
+118, 36, 99,187,220,239, 92, 42,202, 34,221,239, 2,244,141, 25,230,161,218,111,238, 37,132,236,104, 58, 64, 9, 74, 83,211,254,
+211, 83,123,111, 48,115,201,102,169,109,197,122, 61, 2,120,251,173,221,166,141, 96,162,108,185,240,199,166,185,172, 39,248,102,
+126,218, 28,113, 53,218,226,137,165,126,135, 53, 39,105,206,252,221, 9,252,235, 42,142,175,232, 79, 27,121,186, 70, 42, 99, 7,
+216,161, 50, 61, 56, 96, 83,129, 70, 57,200,246,133,172, 18, 16,211,238,132,253, 29,201, 58,176, 65,230,142,229,109,255, 0,117,
+ 96,255, 0, 80, 78,224,223,110, 27,254,108, 37, 15,114, 63, 78, 25,101,153, 42,118, 20,171, 69,233,154, 85, 42,135, 36, 37,106,
+ 31, 65,232,117,107,218,188,209,177,190, 33,178, 53,241,158,176,166, 97,222, 98,126,117, 8, 51,119,197, 47, 54, 39, 60,171,165,
+177,248,106, 61, 18, 92, 69, 80,170,123, 20, 9, 7, 90, 5,142,231, 6,226, 53, 66,240,225,212,165,163,145,178, 10,131, 84,198,
+168, 43, 62, 20,250,180,254,169, 74, 44, 16, 28,253,111,179, 93,170,237, 23,164,193, 80, 61,127, 70,133, 80,162,219,242, 84,238,
+ 62,209,174, 85, 26,137,238,213,142,162,226,162,149, 72,105,138, 10,141,253, 43,164, 38,156,197,194,169, 70, 71,175,138, 79, 38,
+194,244,103,214,128,148, 60,134,143, 85,160,244, 32,104,205,152, 56, 32, 99, 33,100,163, 13,113,210,210, 33,132, 58,145, 66,189,
+160, 87, 92,107, 28, 13,107,130,235,136, 35, 36,205,242, 97, 73,162, 81,241,123,105,223, 74,213, 16, 10,175,109, 69,117,186, 20,
+ 40,167,223, 77, 21,192, 59, 53,209, 80,188, 74, 67,142,163,107,174,149, 80, 16, 1, 58, 0, 6,228,187,137, 81,225,110, 9, 93,
+127, 21, 79,179, 93, 47, 70,108,117, 79, 12,218,220, 85, 2, 91, 38,190, 0,117,211, 41,174,217, 16,171,141, 2,149,181,219, 36,
+185,112,107, 26, 73, 42,127, 97,193,175,119, 66,132,167,204,106, 49,161, 52,115,227, 8,246,132,159,208, 72,214,119,190,249,139,
+ 97,182, 85,161,218,157,213,151,181,109, 92,171,228,142,235,188,129, 36,141,240,217,214,113,237,165, 62,218, 34,198, 51,194,136,
+106,232,155,155,233,110, 76,182,227,169,133,160,133, 36, 75,138, 14,224, 41, 95,133,104, 53,167,126,228, 84,142,167, 21,230,143,
+ 48, 91,187, 16, 90, 40, 62,207,217,233,217,234, 30, 66,242,188,242,188,110, 4,212,156,250, 13, 56,246,255, 0, 69,120,155, 21,
+136,225, 88,244, 87, 25,118,100, 49,229, 37,196,135, 80,164,254,221, 45,168,208,168, 30,181, 40,173, 23,237, 73,175,113,172,230,
+239,124,145,245,210, 86,175, 14,208, 27, 67, 69,116, 56,251, 12,225,184,242,159,131,126,197,172,183,139,117,206, 39,154,228, 89,
+150,244,191, 5,255, 0, 34,161,218, 54, 73,218,162,217, 27,182, 16,126, 18,180,147,241,141, 65,157,250,237,148, 44,121, 4,113,
+ 7, 17,233,233,193, 39,119,183,213,164, 54,129, 35,205,189, 38,250, 89,202, 91, 49,177, 59,133,195, 5,187,204, 36,192,113,169,
+230,108, 38,165,170,169, 76,119, 18,189,222, 96, 74,146,160,138,144,107,240,149,255, 0, 86,219,180,249,139,184, 89, 56,120,192,
+ 61,163, 60, 61, 61, 56, 42,197,198,202,233,154, 73,104,245, 97,135, 74,160,156,205,232, 15,151,236, 18,157,115, 30,151,106,205,
+ 49, 9,234,105, 48,239,182, 57, 5,242, 23, 32,169, 37,167,218, 80, 11,105, 69, 32,148,146, 40,106, 5,119,116,214,165,182,249,
+153, 99,117, 21, 93, 86,201, 67, 86,159,184,170, 38,225,203,210,185,250, 70, 93,120, 21,239,145, 48, 27,134, 83, 27, 22,198, 31,
+109, 81, 89,179, 91, 99, 70,144,133, 36,130, 3, 8, 75, 97, 32,127,164,170,147,244,123,245, 74,189,230,127, 26, 71, 61,190,165,
+109,217,121,108, 88, 64,117, 28, 92,106, 87,188, 11,208,213,195, 40,150,212,171,108,168,113, 79,206,195, 97,191,152,123, 98, 10,
+ 10,201, 82,197,105,184, 23, 9, 29,125,157,233, 93, 55,127, 59,253, 40,239,130,146,119, 47,196,247,212, 20,219,206,126,140,249,
+ 23,138,174,119,185, 44,219,157,190,226,208,231, 76,139, 18,253,110,105, 82, 35,203,249, 34, 3,203,232, 9, 74, 27,221, 82,163,
+211,111,197,219,174,183, 94, 74,243, 30,203,125,138, 56,195,192,146,153, 31, 96,245,159,183, 5,229,158,126,242,166,247,111,146,
+ 75,216,218, 93, 19,168,225,210, 42, 42,106, 56, 1,143,168,118,170, 97, 46,206, 82, 72, 83, 99,217,213, 58,213, 35,184,170,195,
+103,178, 45,224,154, 17,100, 75,175,182,143, 35,121, 90,194, 82,157,181,169, 39,166,148,124,224, 3, 82,154,178,204,185,192, 1,
+138, 56, 96, 60,116,111, 55, 40,232,184,199, 16,217,131, 33,135, 99,165, 73,162, 95, 88, 39,169, 29,148,146, 18, 64,247,251,181,
+231,175, 49,121,183,199,151,233,161,117, 88, 7,123,172,254,197,236,255, 0, 37, 60,188,254, 83,104,111,238,152, 4,206, 61,218,
+230,214,255, 0,250,190,197, 99,243, 76, 6, 26,177,230, 33,199, 97,182, 86,134,218, 88, 90, 17, 64,150,138,136, 7,220, 3, 97,
+ 68,125, 90,204,173,119, 34,215, 98, 86,181,113, 30,183, 26, 5,204,174,116,192, 50, 6, 87, 62, 12, 38, 94, 75, 40,110, 75,242,
+ 94,234,118, 48,135, 22,158,226,148,220,148,159,163, 90,159, 42,110, 81, 74,224,231, 28,120, 44,179,159,246,201,228,143, 75, 62,
+ 92,202,169,246,239,150,182, 4,196,117, 62, 82,218, 3,122, 85,240,236,236, 64, 85,125,254,221,104,210, 48, 73,136,197,101, 54,
+146, 11,110,233,194,138,109, 18,246,218,209,229,182,226, 85,187,104,248, 71, 65, 78,221,123,157, 48,145,133,185,171, 69,165,232,
+118, 1, 76,173,155,156,216,163,214,189, 70,161,110,159,161, 90,172,206,170, 34, 85,146, 11,178, 54,165, 38,128, 83,169, 77, 58,
+234,189,113, 53, 21,134,222, 42,163,101,134,209, 26, 43, 33,233, 43,109,149, 52,157,235, 93, 70,224, 71, 80,145,253, 99,166, 76,
+144,202,104, 19,231, 48, 70, 49, 67, 60,243, 55, 76,217, 12,216,173,142,132,186,226,188,183,131, 41,222,227,108, 2, 42,181, 40,
+168,144, 64,232, 43,227,171, 30,223, 99, 37,217, 12, 0,170,103, 49,239,176,237, 49,185,238,112,193,107,133, 30,197, 18, 28,118,
+ 16,211,129, 40, 72,221,186,170, 82,148,123,146, 64, 64, 36,251,128,214,175,181,237,174,176,140, 53,180,175, 19, 69,228,254,101,
+230, 19,190, 78, 94,250,233,224, 43,128, 29,130,139, 85,210, 44, 16,132,185, 13,218,131, 66, 81, 79,195,247,234,110, 18,225,154,
+170, 72,107,146,104,143, 29, 47, 60,150,214,176,128,163,248,143, 77, 41, 35,180,138,128,147,107,117, 26, 41,252, 28, 42, 35,136,
+ 75,138,125, 14,238,161, 9, 73,175,125, 69,201,126,236,168,158, 50,220,113, 75,213, 97,130,195,162, 48,138,149, 5, 39,169, 35,
+195, 76,221,112,247, 28,209,131, 3, 77, 40,181, 59,109,131,109,109, 79, 38, 59, 41, 40, 4,133, 20,128, 70,186, 30,233, 48, 70,
+ 49,181,138, 25,120,203,162, 68,109, 33,213, 54,106, 79,195, 65, 93, 46,216,201, 77,165,153,172, 24,161,205,199, 47, 51,194,211,
+ 28,182,203, 96,145, 93,160, 18, 52,225,177, 81, 66,207,124, 92,104,213, 17,155,112,101, 41,243, 3,129,107, 31,138,186, 55,134,
+ 83, 93,117,205, 66,111, 89, 11, 41,111,112, 90, 80,186,116,167,252,250, 81,177, 81,115, 82,128, 73,201, 28,125, 73, 66, 22, 60,
+202,138, 40,120,105,118,178,137, 55, 26,175,207,239, 27,209,255, 0,122,250,138,169,226,107,253, 58, 4,116, 34, 1, 84,130, 94,
+ 94,167,155,242,131,191, 26,190, 17, 95,249,244, 82, 52,174,181,152,168,125,209,115, 93, 9,234,165,133,158,165, 38,162,135, 66,
+ 41, 26,243,154, 81,178, 2,104,189, 91,241,245, 22,156,121, 72,161, 34,181, 34,189,180,169,184, 13,112, 0,165, 91, 78,149, 35,
+132,218, 85, 31,201,252, 46, 50,170, 36,210,155,169,254,109, 51,150, 99, 12,195,247, 74,111, 35,203, 30, 58, 10,114,135,111, 43,
+123,115,237,215,226,233, 81, 94,218,127, 28,173,144, 96,156,196,225, 34, 34,179,101, 98, 83, 45,108,109, 41, 91,100, 17,211, 69,
+145,225,153,148,187,232,208,165,113,172, 40,253,155,138,105, 33,105, 3,174,222,166,154, 32, 58,133, 81,218,202,133,249,114,182,
+121,196, 48,221, 20,178, 63, 8,234, 1,211, 57,195, 31,135, 20,147,154,218,225,154,111,143,143, 63, 30, 11,203,148,146,133, 45,
+195,180, 40, 16, 72, 30,205, 85, 36, 96,117,206,158,128,154, 73, 21,115, 94, 5,186,111,203,169,205,139,249, 80,250, 27,174,223,
+135,168, 87, 95,187, 78,190,145,180,175, 26,161,224, 54,139,162, 56, 71, 16,112, 46, 79, 0,198,155,205,140,187, 41,180, 85,245,
+198,183,209,148,158,189,212, 94,254,141,121, 67,116,230, 93,222,197,245,101,150, 7,164,254,197,130,201, 53,213,191,120,197,130,
+ 62,225,126,158,120,159,228, 91,103, 17,229, 8,171,218,229, 23, 49, 37, 81,150,229, 9,247, 44, 18,125,186,142,119, 52,223,195,
+ 40,154,246,208,150,116,102,152, 51,114,158, 9, 68,179, 66, 75,122, 20,231, 45,244,189,117,151,142,205,111, 18,200,173,183, 57,
+206, 68,113,184,254,100,212, 62,226,220, 88,160, 52,220,149, 87,234,214,133,180,121,231,101,111,220,150,221,204, 3,160, 81,104,
+ 54,126, 98,219, 22,232, 49,105, 84,223,135, 61, 5,243,102, 13,112,203, 50,220,182,206,151, 23,113,157, 33,216,174,180,149,130,
+166, 73, 33, 52, 11, 3,245, 71,129,213,150, 31, 62,246, 73,165, 17,181,228, 18,157,199,206, 54,208, 59, 83,178, 42, 71,149,224,
+185, 5,148,185, 26,101,178, 99, 11, 21, 9, 90,152, 90, 19, 81,236, 52,166,181,157,147,154,108,183,166,135, 65, 43, 79, 85, 69,
+ 85,206,195,116,131,113,104, 49, 56, 20, 61, 16,110,241, 26, 63, 51, 25,221,169, 38,138,218, 72,166,172,236,145,175,200,169,102,
+176,140,210, 38,100, 72,101,210,224, 82,219,169,238,133, 20,145,250, 52,185,140, 63, 48,187,160, 21, 44,181,101,247,216,207, 6,
+225,221, 46, 45,109,165, 41, 41,106, 71,216, 73, 26, 99,113,179,219, 92,255, 0,153, 19, 79,168, 34,155,118, 63, 54,133, 32,187,
+ 95, 47, 89, 3, 13,162,234,248,145,229,143,133,101,189,171, 63, 73, 20, 26, 37,142,207, 6,218, 73,133,180,170, 82, 56, 27, 22,
+ 65, 70, 23, 4, 39,186, 77, 79, 98,117, 45, 84,186,195, 4,129, 82,147,244,245,208,170, 26, 87,131, 15,220,126,243,174,213, 10,
+ 47, 98, 26,148, 0,216,107,225,208,235,153, 46,209,126,136, 46,164,213, 33, 73, 62,209, 80,116, 10, 0, 81,109, 75, 18, 80, 20,
+ 2,215, 69,244, 85,122,147,162,144, 10, 48,170, 74,171,106,148, 73, 85,126,205, 26,180, 92,162,246,139,112, 30, 7,252,250,229,
+ 87,104,146, 75,142,175,195, 77,138, 61, 2,200, 33, 10,255, 0, 91,217,244,253,190,221, 22,180, 74, 6,235,195,138,106, 54,199,
+138,136,116, 41, 36,117, 35,220,125,158, 4, 17,216,235,134, 65,152, 70, 17, 16,104, 83,141,190,201,231,188,134,194, 22,173,234,
+ 0, 20,130,162, 9,247,117,174,160,247,189,226, 61,166, 23, 77, 33, 0, 15, 82,184,114,151, 44, 75,204,183, 76,182,137,164,146,
+115, 2,180, 29, 42,196,225,156,118, 0, 30, 99, 10, 81, 90, 66,183,174,165, 52,167,226, 73,165, 83,244,107,203,124,219,207,179,
+239, 14,160, 58, 90, 50, 3,239,233, 94,242,228, 47, 43,173, 57, 90, 49, 65,169,231, 55, 59,238, 28, 7,161, 86, 39, 25,193, 81,
+ 21,198, 92, 84,122,165, 36,121,135,109, 66,144,123,212, 15, 2, 60,107,172,186,238,249,211,230, 86,189, 4, 44,183,200, 34,108,
+124, 98,220,196,166,196,117,159,151,117, 33,108, 56, 5, 84,194,197, 62, 21, 86,149, 9, 61, 43,222,157, 60, 43,168,199, 72, 92,
+ 19,166,191, 79, 4,150,225,104,142,216,248, 84, 26, 90,156, 59, 16,175,235,143, 97,246, 43,192,123,107,236, 58, 35,106,228,229,
+179, 6,224, 82, 31,154,157, 1, 8, 74,100, 62,201,243, 89,118, 42,210,162, 66, 93, 35,173, 42, 63, 89, 0,133, 3,167, 80,176,
+ 56,226,154,220,188, 57,164,133, 7,188,230,115, 26,113,104, 75,238,121,190,115,101, 69, 43, 33, 32,245, 86,224, 15, 84,144, 20,
+122,120, 29, 75, 68,214,244, 38,126, 25,161, 41,223, 10,245, 31,148, 98, 51,154, 67,210,215, 54,216,234,158, 67,240,100, 40,170,
+ 59,205,133, 41,194,141,166,169, 20, 86,240, 15,211,167,175,218,155, 48,171,112, 42, 34,229,172,150,173,112,197, 93,232, 24,246,
+ 23,206,246,243,147,216,163,162, 46, 78,195, 9, 14, 71, 97, 32,162,228,220,100, 35,115,219, 64,168, 53, 27,182,246, 36,170,190,
+ 20,138,123,159,105,129, 10, 10, 77, 86,100, 49,206,252,179,199,163,211,224,167, 45,250, 74,228,236,171, 16,114,247,199,143, 72,
+104,219,155,146,213,218, 10, 73,101,248,147, 35, 5, 56,212,134,170, 71,153, 29,228,133,121,149, 32,160,146,122,164, 0, 79, 4,
+173,188, 7, 83,107, 69, 3,123,205, 16,242,245,203, 99,149,216,156,143, 3, 94, 29, 69, 72,184,154,249,157, 97,150,203,214, 19,
+203,248,179,151,155, 52,198,126, 89,216,119, 38, 22,167,144,101, 45,134, 94,162, 92, 1,117,163,234, 37, 42,167, 65, 67,210,163,
+ 85,221,193,174,219,229, 19, 90, 56,181,195,136, 87, 54, 58,219,152,227,107,152,241, 95, 81, 4, 80,224,120, 16,114,251, 21, 35,
+245, 59,233, 75,134, 45, 87, 59,214,103,136, 78,157, 26,221, 49,210,212, 60, 90, 11,200,112,219,211, 5, 12,182, 93,113,110,124,
+103,230,142,245,130,122, 3, 95, 10, 13,105,156,179,231,126,231, 20, 77,182,149,141,115,218, 77, 94,107, 82, 42,105,151, 66,162,
+ 94,121, 13,181,239,178,155,153,181,198, 75, 27,131, 40, 25, 90, 99, 74,212,240,233,204,170, 9,112, 78, 47, 46,125,166,219,139,
+ 98,205,219,162,193,156,209,151,117,125,197,203,159, 51,202,219,190,132,128,132,133, 37, 39,176,241,212,221,199, 60,110, 55,109,
+ 62, 44,199, 30, 3, 1,157, 84,221,143,149,123, 54,214, 65,134,221,181,109,123,199, 19,149, 62,196,113,196,112, 25,146,109,203,
+200, 60,149,181, 25,136,241, 45,208,216, 78,229,109, 43,144,227,238,184, 85, 78,205,182,176,132,215,169, 43, 72, 29,141, 42,114,
+ 92, 25, 78, 56,149, 59,115, 51, 45, 15,134,220, 6,126,234,122,118, 35, 36,251, 43, 87,118,163, 91,210,218, 19, 32,180,202, 29,
+243, 20, 18,134,154,109, 33, 52, 81,240, 9,235,212,248,117,250, 26,212,131, 80,161, 60, 86,183, 18,171,183, 36,241,171, 75,137,
+ 45,233, 44,121,130,115,106, 66,137, 69, 55, 48,160, 20, 7,106,252, 73,162,190,186, 30,186,153,218,119, 23, 90,188, 16,114, 93,
+220,109,163,220,163,115, 58, 87, 17,185,235, 6,151,136,231, 83, 27, 13,184, 33,220, 95,114, 76, 69, 54, 9, 11,105, 84, 89,168,
+167,116,135, 18, 53,233, 14, 92,190,110,225,108, 15, 16, 49,244,245, 47, 44,115,126,222,237,182,236,142, 14, 56, 40,182, 57, 9,
+197,173,186,165, 64,133, 14,132, 26,212,247,174,156,222, 60, 53, 27,104,107,164,162,178,120,174, 58,185,158, 82,157,222, 27, 20,
+169, 3,232,247,234,157,127,114, 24,181, 61,178,216,144, 42,138, 75, 93,175, 30, 74, 84,218,211,230, 37, 61, 74, 85, 74, 83,196,
+154,211, 85,253, 14,185,118, 25, 43, 11,166,101,168,235, 67, 28,147,145,230, 93,102,255, 0, 4,199,218, 47, 79,124,109,220,149,
+209,182, 91, 38,133,110, 47,178, 64,246, 87,174,173, 27, 86,196,233,156, 40, 21, 11,152,249,202, 45,185,142, 46,118, 41, 93,139,
+ 25, 54,182,150,244,135,157,147, 58, 73, 14,202,125,194, 70,247, 21,223,165, 79, 65,225,173, 99,106,218,153, 96,220, 51, 94, 95,
+230, 94,103,155,125,144,234, 52,109,112, 9,244,177,238,253, 58,155, 10,160,229,229, 49,219, 85,119,212,123, 41,162,188,187,240,
+162, 12, 82,101, 70, 0,146, 42, 40,122, 30,218, 82,168, 47,104,184, 78,140, 43, 30, 74,234,142,187, 73, 39,160,210,110,133,175,
+204, 35, 7,145,146, 86,206, 85,113,124, 18, 84, 60,196,138, 18, 73,174,146, 54,108, 70, 18,149, 29,190, 92,238,210,227,184,148,
+ 60, 66,136, 61, 42,122,233, 70, 91,181,188, 17, 95, 35,156, 21,104,191, 93, 47,172,220, 29, 68,196, 58,164, 32,171,105, 27,136,
+160,215,100, 45,137, 66, 93, 23, 19,138,140,185,148,180,210, 21,185,197, 5, 15,213, 36,142,186, 54,130,113, 77, 64, 81,201, 89,
+139,142,110, 67,106, 63, 23, 64,106,117,221, 40,222, 31, 21, 29,147, 57,217, 73, 42,113,210,144, 1,232, 84, 78,142, 27, 68, 82,
+113,193, 55,162,107, 45, 31, 48, 21, 40,143, 96, 36,232,186, 80, 33, 53,207,159, 42, 66,183, 51, 29,245,129,236, 73,209,131, 23,
+ 90,210,152,182, 93, 36, 73, 78,216,111,167,168,238,146, 6,186, 99,170, 56,105,162, 36, 88,172,215,215, 91, 43,113,175, 49, 41,
+ 72, 81, 14, 3,240,164,125, 90,137,187,139,233,127, 52,123, 19,105, 32, 48,159, 16, 41, 56,151, 18, 42, 22,202,156, 10,124,165,
+ 85,107,178,106,158,227,219,168,137,110, 29,116, 65,140, 80,166,205,156,206,238,235, 72, 77,104,187,218, 21,103,184,220, 88,124,
+ 34, 93,181,197,249,145,150,104,178,104,122,123,251,105, 99, 36,147,197, 66, 59,193, 72, 1,174, 60,115, 9,254,221,146, 64,118,
+205, 13,244,141,247, 25,123, 85,229, 36, 84,182, 8,255, 0,151,125, 41, 97,174, 22, 80,230, 87,109,135,128,220, 51, 41,231,251,
+251,110,178, 33,166,220, 2, 68,183, 84, 18,150,155, 59,200, 81,240,247,232,183,119, 63, 77,143,204,228,131,222, 99, 53, 56,148,
+ 81,178, 92,231,222, 34, 7,212,216,140,135, 82, 10, 65,232,173,167, 81,205, 55,183,231, 61, 45, 72, 23, 92,221,154, 14,235, 81,
+239,136,241,190, 50,151,113, 18, 57, 22,251, 46,223, 5,147,185, 73,142,224,109,110, 10,246, 31, 10,148,107,238,211,109,234, 91,
+205,186, 42, 89, 48, 61,231,137, 74,208,217,142,238, 37, 95,187, 78,109,232, 95, 21,143, 21, 42,194, 47,121, 92,150,192,253,163,
+237, 21, 33,106, 30,245,251,126,141, 97,187,143, 47,115,150,233, 35,158,217,217, 16, 41,180,210,207, 39, 64, 69, 17,234,127,210,
+ 23,240, 85, 91,135,167,207,253, 28, 86,144,167, 40,159, 59,120, 4, 3, 77,158,202,234,183,255, 0,140,249,187, 87,137,252,200,
+106,232, 76,181, 79,251,203,128,120,255, 0, 17,103,152,117,179,228,217,179,149, 45,212,255, 0,188,200,106, 90, 28,116,138,117,
+253,110,167, 90,189,239, 51,217,110, 47,212, 95,150, 66,133, 83,223,112,219,151,106, 37, 88,254, 47,198,179,203,124, 4, 62, 21,
+116,179, 64,106,139, 82,215, 33,104, 43, 53,254,181,118,245,240,166,150,135, 97, 28,203,137,123, 75, 61, 74, 82, 13,160,238, 67,
+ 18, 40,157,189, 65,114,142,127,198,156,122,213,226,203,153,222, 34, 93, 36, 72, 13, 68, 80,146, 93,169, 20, 2,155,234,123,159,
+ 13, 89,182,255, 0, 45,118,200, 27, 71,196, 28,122,212,143,252, 86,214,221,181, 45, 4,171,165,233,175,213, 79, 54,219,248,171,
+ 25,126,251,145, 46,248,183,153, 67,142, 55, 63,113, 14, 32, 1,208,215,114,122,159,118,171,155,167,145,219, 22,230,231, 59,193,
+ 13,113,226, 18,206,229, 59, 59,168,192, 45,162,189,184,239,172, 46, 58,202, 45,168,178,242,111, 27, 90, 86, 84,128,133,220,163,
+ 68, 74, 30,175,109,219,155, 29,126,177,172,154,255, 0,244,239,184,108,179,125, 78,205,122,246,154,212, 52,156, 61,133, 8,249,
+ 93,150, 67,253,185, 45, 33, 50, 94,113, 46, 2,206, 80,252,204, 54,247, 30, 3,206, 37, 71,248,108,165, 0,144,165,120, 82,130,
+159,102,173, 59, 78,253,204,124,174, 68,123,164, 37,237, 31,136, 41, 43,125,214,230,199,187,112,205, 77,233, 85,115, 46,225,123,
+124, 87,156,113,183, 35,180,209,113, 73, 75,236,186, 22,202,211,245,118,250,245,183,242,255, 0, 51,179,119, 96, 44, 56,241, 7,
+ 48,172, 86,215,112, 95, 10,176,227,208,161,171,227,156,126,214,201,113, 55, 36,189, 35,109,118,165, 99,241,123, 59,106,204,219,
+137, 30,114,193, 59,208,209,197, 50, 11, 72, 73,160, 64, 32, 86,149, 61, 41,246,105,226, 34, 67, 38,220, 60,212, 32,182, 74, 79,
+138,124, 15,211, 77,117,114,171,103,240,167, 87, 68,165, 31, 8,233,215, 66,168,213, 94,211,100, 53,234,143,249,125,154, 21, 66,
+171,127,240,176,145,248,116, 42,186, 10,243,252, 54,191,171,162,160,180,187,109, 88, 21, 13,147,174,174,164, 42,130,161,248,133,
+ 61,196,107,168, 45,237,219, 84,175,194, 19, 79,167,252,218, 41, 40,193,108, 85,144,184, 40,164, 5,104,133,244, 74,181,160,175,
+213, 90, 3, 45,165,183, 27,109,105, 53, 8,105,193,237,254,169,232,164,245,234,104,117, 89,230, 13,250, 29,146, 35, 44,142,161,
+224, 56,146,175,188,147,202, 23, 92,221,114,216, 33,109, 88, 8,212,226, 48,104,237,195, 30,170,138,162,102, 25,135,194,113,109,
+ 60,184,242, 91, 89, 32,133,109, 15, 51, 95,245,192, 74,190,173,186,242,191, 52,115, 77,198,245, 33,116,175,168,224, 56, 14,192,
+189,239,201,220,149,103,202,144, 54, 59,120,192,195, 19,196,158,146,120,250, 81, 90, 60,115, 28, 75, 77,163,108,114,154, 80,160,
+ 41, 36,178,179,237, 11, 77, 10, 21,238, 35,174,179,233,223,171,138,190,178,109, 56, 82,136,129, 26, 27,140, 84,151, 72, 8,170,
+219, 90, 84, 80,227,103,175, 74, 13,162,148,237,247,215, 76,203, 66, 84,206, 74,107,151, 39,229,220, 91,228,176,231,154,218,144,
+234, 66, 54,161, 64,215,105,165, 1,233, 83, 95, 29, 2,193, 74, 4,118, 74, 93,154,133,221,174,143,161,143, 45, 14, 16,223,152,
+ 22,213, 77, 86,217, 79, 90, 37, 68, 84, 16,122,233,104,226,198,169, 83, 39, 2,162, 55, 11,227,235,138,211, 14,186, 54,130,118,
+146,119, 80,160,215,167, 66,105,255, 0, 54,142,232,200,117, 66, 90, 23,183, 77, 10, 23, 94, 36,130,227,174,133,133, 18, 71,197,
+ 90,208,212,248,118,238,116,246, 58,148, 82, 67, 69, 56, 32,125,246,250,168,179, 95,140,226,246,182,250,214,243, 71,119,224,120,
+164, 5, 0,123,246, 52, 31, 73,213,199,109,103,136,197, 85,220, 95,225, 62,170,219,250, 59,231,185,152,198, 79,102,101,249,127,
+179,102, 82, 28,113, 5,117, 11, 68,101, 37, 46,162,158, 32,179,230,244,211, 13,239,110,195, 80, 76,223,166,254, 39, 70,238, 32,
+175,167, 94, 22,202,109, 88,165,255, 0, 25,201, 87, 56, 61,135,103,174, 57, 5,136,233,113,104,137, 10,242,160,211,142,164,109,
+ 42, 79,237, 99,188,135, 2,136,167,194,160, 0,166,227, 87,183,107, 98,145,146, 83, 10,208,172,111,155, 45,100,221,173,102,183,
+167,231, 68, 3,129,166, 37,184,211,216, 65, 30,177, 94,133,227,213,212, 24, 80,174, 17,239,176, 96,161, 72, 97,216,111,197, 91,
+106, 5, 44,199,242,157,168,113, 35,177, 73, 66,150,130, 8, 65,218,123,157,212,105,190,219,233,144,185,131,186,114, 71,242,146,
+240,200,195, 4,174,161,198,190,209,241,167, 78, 61,139,230,187,156,179,247, 50,158, 77,190, 91,226, 73, 84, 88,233,118, 67, 77,
+183, 25,101,182,140,117, 80, 37, 10, 79, 90, 16,145,181, 71,198,132,233,229,134,216, 35,132, 75, 76, 87,165, 25,126,109,233, 9,
+199, 0,134,120,253,178,199, 6,226,132, 73,121, 65,177, 82, 85,184,110, 42, 82, 72,248, 71,115, 90,246, 26,121,165,249,148,222,
+234,243, 83, 72,106,182,124,106,220, 11,196, 49,110, 47, 33,150,247, 56,236, 86,220, 39,202,109, 29, 6,228,166,148,220,186,109,
+ 39,216, 41, 74, 10,105,104,222, 27,154,206,247,198, 73, 93, 97, 44,206,173,195, 23,149,229, 66, 9, 72,118,142,186,239,150, 28,
+ 43, 90,187, 2,173,160, 0,144, 58,248,123,186, 87, 69,146,112, 50, 74,108,246, 70,241,181,122, 12,223,178, 38,110,204, 72,101,
+217, 12,173, 12,160,151,222,121, 95,179, 52, 35,183, 67, 90,170,158, 63, 69,116,102, 72, 48,166,106,109,155,105,128,245, 42,101,
+202,124,127,141,101,114,252,187,172, 70, 92,125,244, 37,182, 30, 66, 1,145, 25,180, 44, 45, 69, 53,235, 67,215,189, 62,206,250,
+ 79, 41,239,239,219,240, 39,187,208,179,110,119,229,102,238,160, 61,131,188, 21,118,103,133,224, 90,100,161,230, 24, 75,204,173,
+199, 28, 65, 11,243, 16,150,146,162, 0,168, 21, 81,233,219,199,235,160,210,238, 46,254,173,154,163, 53, 89, 62,222, 78,221, 39,
+135, 51,116,154,166, 28,143, 33,182,227, 44,186,195, 14, 69,101,109,239,109, 97, 36, 10, 17,223,175,110,132,117,233,168, 72,172,
+ 93, 57, 86,231,238,173,183,109,107, 64,131,209, 94,203, 57, 38, 90,217,199,246, 49,105,109,123, 37,222, 30,116, 33, 29, 13, 10,
+ 89, 71,119, 21,239,165, 7,183,195, 86,221,183, 98, 7, 53,156,243, 31, 59,120, 2,141, 40,233,141,224, 48,177,216,169,106, 44,
+ 84,153, 11, 1, 82,165,173,106,117,249, 14,248,169, 74, 85, 73,169,213,242,206,217,150,130,141, 24,172, 67,116,220, 38,221, 31,
+170, 66,105,192, 39,201, 54,199,155, 65, 41,110,170,247,245,212,139,100, 80,175,128,132,222, 97,173, 40, 73,113,179,184,157, 42,
+ 29, 84,213,204,162,244,155, 98, 86, 58,157,149,250,186,125,154, 5,196,100,137,164, 47, 82,172,209,208,197, 91,120, 45, 68,117,
+ 77,107,253, 26,227, 94, 78, 97, 7, 48, 81, 69,219,182, 37,135, 28,248,170,165, 26,208,157, 42, 18, 45,109, 18,117,198,109,131,
+185, 45,144,165,170,135,167,183, 64, 26,174,130, 22,183,153, 65,248,122,110,165, 64,241, 58, 21, 64,144,152, 37, 88, 98,220,146,
+226, 87, 25, 14, 57, 66,147, 84,212,245,215, 28,208,236,210,110, 96,126,104,126,231, 22, 90,229,184,242,101, 64, 0, 18, 72, 82,
+106, 63,163, 71, 14,162, 68, 91,142, 33, 52, 57,194,246, 20, 44,173, 45, 44,119, 61,244,109, 75,134,217,171, 63,194,171, 34, 62,
+ 19, 24,171,167,137,240,251, 53,192,252, 81, 27,110,208,114, 94,127,195,123, 27, 2,137,130,217, 3,250,221,127,163, 70,212,148,
+240, 90, 56, 47, 11,197, 45,113, 64, 8,134,194, 69,105, 82,128, 71,232,208,212,135,134, 2,252,153,142, 91, 99,182,133,165,136,
+231,114,106, 10, 82, 1, 31,118,138,215,234, 64,176, 4,216,152,200, 74, 86,211, 97, 41, 74,210, 80, 66,122, 29,170,250, 52, 30,
+208,225, 66,147, 45, 8, 13,157, 98,243, 44,201,126,114,101, 4, 60, 20, 94,139,241,124, 78,166,189,137,241,175,109, 85, 93,124,
+ 12,198, 24,197,105,197, 67, 11,182,153, 12,108, 25, 42,147,116,190,220,149,114,146,235, 14, 56,202, 94, 94,217, 45, 2, 66, 86,
+227,117, 21, 35, 79,203,197, 58,209,158,229, 63,195,114,107,179,114, 19, 29,105, 46,124,218, 68,102,213, 66,162,222,254,212,160,
+175, 83,168,219,155,195, 19, 78,140,194, 66, 73,221, 11, 73, 8,237,135,113,189,212, 93, 23,117,188, 7, 95, 73,163,145, 18,249,
+ 37, 71,119, 90, 80,208, 10,106, 58, 59,175,168,110,179,154,108,203,175, 29,181,200,171, 11, 2,223,127, 42, 66, 26,101,196, 39,
+225, 67,109,182,142,180,236, 40, 5,107,245,105, 79,230, 14, 96,204, 0,144,146,249,209,228, 85,178,227,111, 78,252,173,200, 95,
+ 39, 27, 30,194,175,247, 55, 36, 37, 27, 30, 16, 92,109,144, 84,123,238, 90, 70,170,251,191, 59, 90,109, 32,186,105,216, 41,158,
+ 42, 46,231,119,240,241, 46, 11,166,188, 77,249, 77,243,110, 93, 26, 52,156,174, 51, 88,188, 62,138, 82,164,169, 40, 88, 73,247,
+185, 65,247,107, 39,223,255, 0, 81,187, 70,216, 11, 98,118,183,117, 40,203,174,112,130, 6,231,138,186, 35,242,138,192,134, 46,
+171, 49,207,217,254,246,169, 72,121, 63,239,168,242,194, 80,149, 5, 14,219, 63, 18,134,178,175,254,232, 38,250,141, 94, 7,228,
+246, 42,199,252,249,158, 45, 48,162,249,224,245, 27,249,118,122,241,225, 70,159,157,111,153,118,203, 45, 76,161, 78,252,205,189,
+194,167, 20,132, 10,154, 10, 45, 11,251,117,163,242, 95,156, 92,167,205, 4, 53,205,108,111, 60, 10,177,218,221, 91, 56,208,208,
+ 37,152, 45,199, 60,181,241,254, 43,140,102,208,174, 16,111,242, 94, 64,152,205,194, 33,140,250,118,208,117,232, 1,235, 83,211,
+ 94,139,217, 45,108, 92, 4,182,110, 5,167,160,212, 43,125,155, 98,160, 44, 42,188,122,212,186, 53, 62, 87, 30,226,113, 73, 80,
+118,225, 12, 56,132,254,176, 74,183, 26,143,120, 26,183, 51, 4,250,225,245,160, 87, 95, 12,183, 24,120, 46, 51,110,142,203,136,
+249,123, 84, 80, 66, 91, 35,226, 82, 65,240,250,116, 81, 35, 99,249,156, 61,169,215,140,198, 52, 84,128,166, 80,163, 93, 22,224,
+109, 22,249,110,209, 35,168,100,154,253,218, 65,219,141,187, 48, 50, 55,218, 17, 63,152, 66,220, 11,219,237, 91,100, 71,187, 52,
+231,192,203,241,156, 72,239, 69, 50,177,245,244, 35, 78,152,232,174, 91,129, 14,111,168,132,229,143,108,195, 2, 8, 72,164, 79,
+203,220,108, 54, 46,114,223, 97,179,251,135,157, 43, 80, 79,178,167,169,250, 14,153,179,101,130,222, 79, 22, 22,134,184,244, 38,
+226,201,177, 59, 92,120, 20,178, 45,202,224,150,129,117, 10, 11,232, 20, 15, 90,125,186,149, 17,151,209, 63, 99,201, 24,162, 14,
+ 61, 10, 28,230, 23, 38,227, 49, 44, 39,176, 73, 61,116,222,226, 87, 70,104,208,158,194,208,225,222, 41,138,234,244,104,179,212,
+204, 71,126, 97,160,122, 40, 10,233,204, 53,123,106,224,147,146,141, 56, 37,112,220, 91,148, 37,186, 3,226, 70,148, 45,162, 32,
+114,144,181, 5,110,143,133, 0,215,221,162,209, 27, 85, 82,163,104, 87, 64, 91,175,188, 14,223,118,184,133, 87,224,179,182, 58,
+158,135,222, 63,205,174, 16,187,169,106, 93,181, 6,163,165, 71,180, 10, 29,113,119, 82, 70,229,153,151, 58,157,164,251, 53,213,
+218,173,137,178,182,210, 18,180,245, 61, 62, 26, 15,249,244,155,157, 92, 18,141, 90,103,165,136,113,252,231, 90, 41, 61, 16,218,
+ 18, 6,247, 92, 87,100,141, 67,110,251,156,123, 68, 46,154, 67,128,247,158,133,106,229,110, 93,159,154,110,217,105,110, 59,206,
+ 56,158, 0,113, 39,211, 20,229,140,226,114,238,178, 4,183,209, 85,173, 65, 84, 82, 42, 26, 79,130, 70,240, 7, 79,118,188,167,
+205,156,205, 46,241, 51,164,121,160,224, 43,128, 29, 11,232, 63, 35,114,117,183, 41,218, 50,222, 17, 82, 49,115,169,139,143, 18,
+125, 48, 86, 71, 29,198, 76,117, 50,141,161,178, 2,106,160,128,144,125,253, 6,179,137,229,212, 86,136, 29,164,102,138,219,154,
+128,197, 65, 27,144, 8, 46,167,106, 65, 30,250, 19,247,233, 38,176,189, 49,124,184,212, 40,141,194,252,208,222, 18,225,168,169,
+170, 40,149, 40,251, 43,218,191, 78,151, 22,132,160,219,176,213, 3,189,228,140,237, 43, 75,196, 36,142,187,136,174,234,125, 67,
+ 78, 34,179,115,142, 75,142,189, 12,227,138, 19,221,243, 88,237, 56, 27, 91,169, 34,167,109, 85,240,170,158, 30,226, 53, 32,205,
+188,156,130, 68,238, 45, 28, 84, 18,118,104,210,210, 54,186, 54,165, 93, 40,161, 80,107,208,251,125,218,112,221,180,138,224,184,
+ 55, 65, 80, 65, 76, 18,114, 36, 62,211,159, 24, 82,232,107,212,117,167,101,123,255, 0,205,162,125, 17,105, 79, 25,184, 7, 12,
+208, 27, 56,184,133,200,243, 66,214,131,188, 81, 85, 0,182,180,246, 35,220, 71,249, 53,101,218,163,208, 20, 30,233, 62,180,221,
+129,100,114,172, 89, 52, 41, 44, 58,164, 36, 74,110, 66, 58,209, 32, 57,209,104,250, 8, 4, 31,175, 82,119,144,137, 99, 32,244,
+ 40,187, 89,139, 30,190,138,120,111,156, 47, 19,120,235, 24,181, 67,154,242,157,183,204,183,220,226,164,157,225,153,209,146, 90,
+ 11,219, 81,209, 76, 41, 72, 52,247, 3,224,117,151, 92, 69,224,189,192,244,165,239,182,184,230,121,148,140, 75, 72, 61, 96,227,
+246,226,172, 79, 56,250,134,155, 59, 2,140,205,254,216,185,146,154, 98, 75, 50, 95,108, 35,206,242, 92, 67,129, 43, 21, 73,218,
+ 2,214, 84, 58,244,162, 73,232, 8,211,200, 34,109,200,210, 85, 11,108,216,255, 0,149,221, 58, 72, 93, 64,125,158,159,181,124,
+209,114, 22, 65,113, 99, 46,114,116,121, 79,184,211,178, 66,156,121, 36,165, 59,214, 58,129,240,254,162,148, 71,213,171,157,181,
+171, 93, 22,158,165,166, 27,183,151,130,229, 35,181,101,237,191,228, 46,116,167,155, 14, 23,213,248, 80,226,210, 2,148,128, 15,
+112,159,136,117, 10, 21,236,123, 16,117, 19,113, 98,230,100, 20,237,188,204,151, 50,174, 95,167,235,217,127, 33,132,182, 37,135,
+146,141,173,186, 95, 97, 43,105, 45, 2, 58,167,225,218,131, 74,117,232, 71,134,160,231,110,140, 40,163,119,168, 67,163,170,182,
+124,198,136,226, 31,158,233,109, 13,150, 2,210, 18,208, 83, 65, 10,246,116,173, 77, 41,208,125,116,212, 68,210,227, 65,154,109,
+202,240,212,227,151,106,231, 78,115, 17,230,217,109,216, 27,213,231, 17,189,192,241, 66, 55, 18, 72,175,197, 68,208,128, 85,180,
+208, 80, 10, 86,186,146,176,126,167,119,184, 43,157,211, 26, 27,135, 20, 28, 78, 31,125,200,166, 55, 1,183,138,238, 15,169,196,
+ 20,197, 82,155,101,168,201, 80, 10,112,168, 10, 0, 5,123,159,166,154,179,219,220, 54, 44, 70, 74,167,127, 24,252, 67, 36,166,
+201,196, 55, 25,202,109, 12,221, 46,140, 60,167, 18,135, 27, 50, 64,140,134,210, 65,232,129,230, 41, 69, 70,131,235, 62,243,169,
+118,115, 28,150,162,141, 56, 42,181,223, 45,218,222,144,100,101, 74,143,101,126,145,236,247,169,169,122,112,126, 86,231, 11,146,
+ 24,243,150,152,192,164,246,115, 97, 1, 84, 3,168, 39,194,157, 73, 36,169, 23, 60, 92,193,131, 92, 61,129, 33, 55, 33,216,223,
+ 15,204, 97, 35,180,143,179,211,218,167,120,191, 2, 65,177,178,197,174, 33, 17, 98,180,200,216,196, 88,200,142,210, 84, 65, 32,
+ 36, 4,158,131,105, 36,248,120, 84,233,127,252,157,127, 0,160,120,167, 96, 81,143,242,103,101,188,113,113,132,151,127,105,212,
+ 30,170,211,238,233, 86,183,143,189, 25, 71,205,162,186,236,203,243,150, 55, 3, 78,124,185, 84,116,190,211,242,220, 77, 90, 65,
+ 59,129, 72,169, 1, 68, 3,237,235,210,189, 62,123,207,102,224,217, 34,107,133, 70, 68,138, 14, 61,167,211,178, 10,247,244,239,
+183, 61,181,138, 89, 24,113,232, 61,157,128,123,126,248, 31, 35,122, 37,229, 92, 37,153, 83,217,180,175, 33,182, 69, 50, 22,185,
+246,166, 75,169,249,102, 0, 37,210,128, 10,146,158,163,241, 80,247, 59,118,141,199, 79,229,239, 54,246,189,236,181,158, 32, 99,
+205, 48,119, 73,225, 94,159, 74,215, 5,143,115, 23,146,123,142,212,215, 73, 8, 18,176, 87,229,206,131,142,158,142, 29, 57,225,
+ 65, 85, 81,238, 24,187,177,148,166,157, 97,109,184,130, 66,144,182,246, 45, 10, 30, 4, 17, 81,173, 90, 27,145, 32,168, 43, 16,
+189,176,116, 4,135, 2, 8, 81,199,172,171, 79,100, 31,179,252,218,124,215, 85, 66, 72,205, 41,185,118,162, 43,240,117,250, 52,
+173, 83, 98,154, 31,176,165,111, 37,237,196, 20,247, 77, 41,174,162,164,211, 45, 41,242,136, 1, 33,100,138, 18, 6,133, 23, 10,
+103, 24,154,139,129,245, 58,165, 31,234,142,218, 25,162,105,169, 75, 35,216,220,137, 41, 50, 27, 72, 82,122,111, 73, 2,134,159,
+110,138,230,234,193, 40, 13, 19,194,225,197,150, 74, 92,105, 44,251, 84, 0,255, 0, 38,147,210, 88,143, 80,229, 27,184, 89,219,
+106,170,104,151, 82, 15,116,128,127, 70,148,107,137,205, 38,226, 1, 81, 11,188,119,163,160, 45,150, 20,186,245,232, 59,105, 64,
+ 42,138, 84, 97,192,234,208,119,167,106,143,234,145,212,104,217, 34, 85, 71,167,194,145, 33,162,148,166,134,181, 7, 93,173, 17,
+ 28,106,162,215, 40,242, 88, 96, 36,149, 21, 0, 69,126,173,115, 80, 73, 57,212, 80,111, 62, 99, 18,131,138,222,164, 37, 64,148,
+251, 64,211,121,231,107, 26, 73, 52, 20, 76,166,184, 12, 4,147,130,135,242, 43,232,188, 66,109,196,180,176,252, 81, 65, 65,221,
+ 10,239,225, 78,157,245, 85,180,187,136, 23,104, 28,115, 80,208,221, 68,202,150, 42,241, 3, 28,182, 94,103,174,219, 34, 11,226,
+100,167, 71,146,228,118, 11,139, 47, 43,167, 64,144, 85,212,251,180,199,112,190,250,114, 94, 14, 9,165,206,227,164, 97,154,191,
+ 62,158,255, 0, 45,175, 82,252,161,121,180,206,196, 56,238,243, 54,214,235,141, 46, 52,233,208, 28,139, 29, 72, 81,232, 84,146,
+154,159,171, 89,142,241,230,166,209,180, 7,125, 68,237, 14, 28, 43, 85, 22,221,224, 79,133, 8, 95, 71,126,158,127, 33,238, 64,
+202, 99, 91,238,124,211,145,219,113, 86, 27, 75,101, 80,155, 82, 80,226, 91,160,232, 71, 87, 15,217,175, 55,115,119,234,162,195,
+102, 46,101,139, 76,135,211,212,141, 3, 68,142, 36,188, 6,174,186,113,151,229, 85,233, 35,135, 35, 48,236,246, 32,229,183, 56,
+233, 66,148,244,136,232, 82, 86,227,126,245,238, 81,235,175, 53,243, 15,234,131,120,221,156, 67, 28, 88,211,208,126, 9,166,225,
+108,220,116, 73, 84,118,157, 99,198,176,166, 17, 3,141,176,219, 53,189, 44,167,203,101,112,237,232, 14,165, 35,183,196, 18, 78,
+179,211,230, 36,219,177, 46,186,149,231,180,172,215,118,177,185,144,254, 89, 65,156,131, 31,231,188,186, 75,140, 91,152,152,212,
+ 99, 95,194, 84,144, 1,255, 0, 87, 82,246,188,215,182, 64,218,200,236, 85, 82, 78, 89,220, 46,157, 70,180,148,199,255, 0,232,
+189,205,223, 47,252,100,207,127,248,144, 32,136,254, 97,243, 11,103,169, 52,174,238,224,105,223,254, 64,219,235,167, 73,211,210,
+149,255, 0,128,110, 26,117, 83, 30,133,241,173,194,159,158, 95, 63, 97,177,227, 90, 57, 62, 4, 44,234,194,181, 33, 50,144,227,
+ 73,112,173,147,248,170,211,187,129,233,236, 86,190,138,243, 31,233,127,103,220, 73,146,206,177, 73,194,159, 16,182,171,205,134,
+ 59,140,176, 43,175,124, 71,234, 95,209,119,172,219, 76, 41, 23,139, 84, 44, 39, 38,125,160, 16,218,146,150,154,102, 66,254, 16,
+ 75, 75, 33,105,234,123,164,157,101,179,242,255, 0, 54,121, 77, 39,137,109, 41,150, 38,240,234,237, 80,186, 46,182, 71,213,143,
+212,222,133, 93,253, 78,126, 94,145,173, 55,171,119, 38,227,109,163, 54,176, 64, 63, 49, 7,228, 92, 18,144,208,167, 74, 41, 53,
+ 41, 59, 79,225, 80,213,239,151,124,249,184,230, 55, 11, 57,199,131, 46, 88,224,144,190,230, 43,203,215, 6, 48,105, 40, 41,106,
+203,165, 91,202, 45,230,202,136,170,135,178, 50,152,144,218,146,182,124,161, 74, 16,105,236,214,185, 15, 39,238,123,187, 68,142,
+185,238,158,132,163, 57, 99,115,220, 70,167,207, 64,122, 17, 46,223,200, 51, 25, 45,169,184,144,146, 64, 21, 5,148,170,163,239,
+210,204,242,150, 73,113,150,233,254,213, 33, 23,151,143,118, 50, 92, 58,189,170, 96,213,250, 22, 88,147, 10, 69,181,166,164,184,
+ 40,151,216, 69, 0, 62,218, 13, 57,111, 44,238,124,167,249,150,211, 25, 24, 51,105, 82,182,251, 29,254,201,141,188,133,237,232,
+ 41,178,111, 19,228, 54,248,203,184,194,144,220,232,202, 42,112,178, 69, 92, 74,123,244,233,215, 86, 61,143,159,173,239,159,224,
+ 92, 15, 14, 65,134, 57, 43, 70,221,188,139,158,228,163, 75,250, 20, 65,187, 91,206,168,182,243, 1,181, 5, 20,168, 20,208,130,
+ 60, 53,162, 49,225,226,160,224,167, 42,164,144,241,189,232,161, 14,108, 62, 2,160,107,180, 70, 14,162, 86,172, 70, 50,126, 32,
+209,221,222,187,106, 73,209,181, 33,169,126, 35, 27,150, 93, 72, 77, 82,216, 35,245, 79,109, 26,168,106, 83,123,125,160,176,128,
+ 60,178,163, 78,164,131,164,221,138,232,114, 94,109,207, 44,244, 70,223, 96,218,122,253,218, 42, 54,165,228,227,238, 56, 55, 46,
+163,234, 52,208,173, 23,117, 45, 14, 99,169, 20,220, 79,212, 58,232, 85,119, 82,111,122,202,211, 68,154,171,167, 94,218,232, 67,
+ 82, 32,241, 54, 3,104,228, 75,212,171, 83,183,134,160, 46, 35,107,113,105, 61, 20, 66, 59,247,254,141, 27,193, 36, 84,228,154,
+220,238, 31, 78, 67, 90, 42, 74,107,200,184,254,222,140,174, 69,190,215, 33, 55,107,117,173,213, 50,153,133,194,150, 93,146, 13,
+ 21,178,137, 27,130,123, 19,175, 52,249,159,205,109,184,151,233, 97,117, 90,220,200,233, 94,239,242, 31,145,159,180,217, 11,251,
+166, 22,203, 40,192, 28, 40,222, 24,117,231,217, 68, 82,199,177,102, 45,241,218, 20, 8, 7,168,161, 77,107,236, 5, 74, 38,149,
+214, 21,113, 57,148,212,175, 69,234,240,240, 31,122,155,124,179, 49,211,189,212,164,182, 8,169, 46, 4, 40, 1,244, 15,103,187,
+ 77, 79,121, 33,226,209, 69,114,123,252, 54, 35,146,135,147,179,105, 73, 74, 58, 16, 64,241, 42, 72,220, 62,141, 61,182,132,146,
+144,145,252, 85, 81,203, 57, 21,155,114,100,149,190,209, 75,106, 33, 64, 14,164, 30,212, 39,160,233,237, 58,181,217,237,158, 53,
+ 48, 85,203,173,195,233,201,199, 5, 83,115, 47, 83,150, 27, 79,154,216,154,219,135,227,109,109,186, 2, 29, 73, 29, 13, 20, 20,
+174,222,253, 91,108,185, 66, 89,169,221, 84,253,195,158, 96,181, 6,175, 85,250,103,169, 88,151, 55, 86,150, 93, 36, 19,240,213,
+ 95,170, 61,227,199,223,171, 12,124,154,230, 12, 66,170,201,230, 60, 78, 61,210,182, 67,230, 95,154,115,113,116, 31,131,114,129,
+ 63,137, 42, 52, 63, 95, 99,244,233, 41,185,104,198, 50, 78,173,185,217,179, 28,209, 38,203,200,108,203, 8, 42,113, 36, 20,142,
+194,189,253,223, 72,175,215,168, 27,173,148,177, 91,172, 57,148, 73,197, 39,191, 92,145, 53,218,213, 37, 11,219, 69, 82,169, 87,
+ 65, 78,221, 69,124, 52,218, 27, 67, 0, 83, 39,113, 23, 41,211, 23,138,204,135, 24,169, 1,230,158, 65, 67,157,197,107,208, 31,
+117, 58,143,179,217,164,174, 36, 45, 10, 66,214, 48,236, 87, 88,184, 31, 32, 22, 75,125,182, 60,230,221,125,133, 22, 27,105, 1,
+176,226,227,173,127,133, 72, 85, 10,146,104, 41, 80, 58,129, 94,160,157, 80, 55, 8,252,119, 26,102,167,100,238,179, 20,123,245,
+ 1,157,186,206, 33, 22,212,202,158,112, 78, 72, 66,148,218,128,114, 74,163,161,106, 66, 92, 80, 9, 43, 27,137, 80, 74,205, 1,
+ 3, 77,237, 93,225,102,162,118,237,184, 92,202, 92, 41,135,167,236, 92,140,201,153,147, 46,123,197, 75, 33,215,158, 72, 32,163,
+ 99, 11, 10, 61, 55, 83,104, 20,168,240,213,174,214,228, 48, 10, 43, 11,236, 43,154,139,198,142,226, 93, 95,157, 77,166,142,184,
+234, 2,118,186,133, 4,170,138, 85, 78,210, 8, 52,251,143, 93, 59,150, 80,252, 66, 60, 22,230, 60, 10,180,252, 5,117,109,140,
+154,221,251, 22,131,160,245, 45,186, 91, 40,100,138, 83,204,170,106,124, 58, 87,199,235,175,238, 44,210,210,185,118,223, 17,132,
+ 46,144,242,172,232,114,113,104,205,152,105,109, 43,143, 29, 82,151,231, 23, 36, 56, 89, 66,146,154, 30,137, 72, 74, 87, 64, 0,
+233,214,164,244,213, 62, 76, 95,130,111,176, 52,196,227, 82,104, 62,245,206,124,150,227, 21,135, 38, 45, 73,105,150,219, 9, 90,
+ 84,239,225, 27, 77, 18,128, 8,234, 73,167, 82, 43,219,221,171, 5,156, 52, 3,167,211, 21, 53,113, 57,125,107,146, 31,181,158,
+195,101, 50,139, 9,113,175, 55,122, 12,170,144,252,148, 40,126, 1,236, 65,220, 59,119,212,184,179,112,165, 79,169, 69,248,204,
+125, 64, 10, 89,141,231,209,153,101, 15, 7, 25, 71,149, 33,110,169,110, 40, 56,181, 44,141,128,128, 72,175, 80, 72, 21,234, 79,
+ 94,157,141, 45,163,156, 40,146, 5,160,213, 19, 33,102,240,102,165,198, 66, 18,162,226,188,194, 84,179,181, 77, 32, 80,147,216,
+208, 83,175,182,190,205, 69,207,104,232,133, 83,216, 36,107,205, 42,138, 56,100, 35,123, 89,184, 46, 57, 5,111, 48,148, 7, 18,
+ 18,167, 0, 27,143, 64, 40,132,164, 37, 35,104,240, 32,123, 53, 90,220,103, 49,224, 21,138,198,220, 54,138,224, 99, 18,198, 58,
+212,102,210,226, 93,125,146,151, 13, 58,182,218,202,129, 42, 62,238,148,250, 43, 77, 84,100,121,144,169, 9, 33, 18,133, 99, 44,
+217,152,156,211,109, 74, 89, 82, 86,130,211,161,105, 72, 42, 10, 72, 33, 41, 20, 52,218, 59,159, 3,237,166,145,137,230, 19,168,
+112, 80,151, 27,120, 21,162,167, 62,164,253, 43,194,191, 91,164,231,184, 12, 52,124,219, 37,247,174,150,116,148,165, 78, 71,108,
+ 84,173,189,197, 78,190,177, 66, 84,181,119, 36,212,146, 69,125, 43,229,119,154,101,142, 22, 87,206,192,208, 53,221,125,124, 0,
+251, 58, 40,188,229,230,159,149,195,121, 97,187,178,104, 19, 52, 85,205, 24,106, 29, 63,218,247,149,203,105,246, 38, 24, 82,208,
+227, 69, 11, 65, 33, 72, 90, 74, 84, 8,240,161,235,175, 83,193, 62,176, 8, 56, 47, 24,223,217,186, 23, 16,225, 66,162,146,173,
+113,199,102,197,106,124, 41,211, 82, 13, 53, 80, 18, 54,137,141,235, 99, 59,186, 55,223,216, 52,178, 64,148,153,251, 51, 33, 27,
+148,217, 35,161,252, 53,166,130, 45, 82, 99,107, 82,246,134, 88, 82,129,237,181, 21,166,129, 32,102,187, 85,177, 22, 57, 8, 80,
+ 18, 33,189,177, 95,132,249,102,154, 69,242, 1,145, 71,107, 74, 77, 46,196,182, 83,230, 22,194, 80, 79, 64,122,170,154, 12,148,
+ 61,117,192,132,198,213,177, 12,186,226,220, 62, 98, 22, 15,192, 71, 65,165, 28, 42,145,112,170,106,147,102, 75,203, 89, 74, 82,
+ 19,215,225,167,183, 93,201, 29, 70,102, 97,193,210,165, 54,154, 30,166,148,233,174, 25, 40,136,229, 24,151,139, 74, 97, 11, 82,
+154,170, 82, 9,232,147,225,166,230,125, 41,155,165, 45,205, 68,100, 99,226,110,230,252,162, 84, 9, 20, 9,169,174,154,203,121,
+165, 71,205,116, 50, 83,204, 7,210,183, 41,242,141,197,136, 56,126, 15,119,185,124,194,210,148, 73, 84, 55, 26,138,119,116,174,
+226,154,145,244, 13,103,252,217,206,118, 59, 68, 71,234, 39,107,122,113,197, 87,247, 25,252, 70,233,170,235,191,167,191,200,219,
+ 48,202,227, 34,227,204,243, 96, 98,246,119, 82,149,170, 50, 71,146,249,109, 93, 72,248,129, 89, 63, 64,215,147,121,223,245, 37,
+103,182, 31, 15,110, 37,206, 10,165,120,116,140, 36,210,186,111,198, 31,149,223,160,175, 79,206, 51,115,149,139,181,152, 95,216,
+ 40,113,111,205,161,105,111, 55,215,199,114,148, 43,244,107,207, 28,195,231,175, 48,115, 37, 88,215,232,111, 82,139,151,125,142,
+217,180,174,162,174, 68, 14, 85,176, 98, 16, 27,176,241,134, 21,111,177,193,142,128,196,100, 91,160,132,109, 74,122, 15,138,133,
+ 95,126,178,187,166,220,110, 46, 50, 93, 74, 92, 78,117, 42,187,115,204, 82, 72, 78,129, 69,173, 25,111, 37, 94,137,145, 58,114,
+109,112,201, 37, 75,146,240,142,132,167,222, 84, 64,212, 69,197,132, 46,193,162,167,169, 54,134,242,230, 67,153, 77,183, 30,111,
+226,124, 28,132,103,156,157, 98, 67,232,170,156,140,212,244, 72,118,169,238, 58, 40, 15,191, 72, 91,249,121,127,188,187,253,180,
+ 14,199,169, 88, 45, 36,148,208, 60,170,231,201,159,155,175,163,254, 32,135, 37, 80,196,140,170,229, 20,150,210,211, 78,164,165,
+110,142,223, 10, 42,122,253, 58,181,109, 63,167,125,231,116,147, 68,157,192,172,214, 87, 16, 87, 78,146, 92,185,255, 0,154,255,
+ 0, 48, 54, 75,144,202, 93,159,136,248,254, 5,145,183, 10,146,153,178,155, 74, 28, 74, 59, 3, 83,185, 90,218, 57,111,244,157,
+ 27,228,104,184,144,184,169, 9,175,165,111,118, 38, 0, 74,175,231,243,103,245, 58,114,164,100,223,222,136,123,208,195,141,127,
+ 13,161,249, 99,230, 41, 10,239, 95, 13,180,237,175, 71, 15,210,238,194, 54,227,105,163,243, 51,175, 28,143,197, 56,250, 89,188,
+ 58,234,252,204,215,199, 36,152,117,153, 9,162, 54,183,229, 33,107,240, 7,174,189,159, 43, 52, 5, 39, 56,208, 42,174,199, 9,
+ 90,158,172, 43,135,205, 59, 10, 44, 82,135, 24, 92,119,139, 43,243, 17,216,130,146, 13,117, 20, 54, 97,124,107, 40,168,232, 41,
+132, 59,103,212, 59, 84,138,232,112,231,230, 7,205,220, 91,205,145, 49, 22,114, 23,114, 60, 29,198, 60,153,150, 91,178,254,109,
+ 42,103,118,218,124, 95, 10,250,120, 40,125,122,162,243, 95,147,123, 79, 51, 10,136,196,114,240,115,112,197, 43,117,179, 67,113,
+133, 40,122, 66,233, 54,119,149,112,151, 56, 88,223,203, 49,231, 98,225,249,163, 44, 23,167, 91, 91, 30, 75, 50, 30,165, 79,236,
+205, 58, 21,123, 53, 13,202, 91,110,247,200,147, 11, 73,201,154,216,158,233, 56,144, 59, 81,109, 35,159,108,112, 97,239, 49, 85,
+ 24, 23, 21,135, 84,209, 90, 84, 91, 82,155, 37, 42,168, 86,211, 74,143,167, 91,235, 0,112, 5, 90, 26,234,138,162, 13,150,241,
+112,183, 58,153, 80,148, 2,250,119, 21,209, 37,183,108,162,133, 45, 28,134, 60, 66, 48,219,249, 7, 38, 83, 77, 37,166, 55, 57,
+ 81,189, 63,245,110, 39,198,163, 84,253,223,145,237, 55, 90,151, 10, 59,131,134,105,181,245,172, 87,194,174,109, 29,210, 20,186,
+ 69,186, 53,253, 12,220, 3, 38, 4,229, 37, 38, 66, 2,118,165,106,241,168,165, 15,211,168, 61,177,215,252,170,255, 0, 6,122,
+201, 7, 3,208,162,153, 52,219,121,163,241,103, 74,118, 69,189, 16,227, 38,163,121, 29,212, 58,141,104,118,215, 44,187,110,184,
+205, 66,152,138, 97, 40,171, 78, 9, 3,146, 27,118,137,111,111, 67, 67, 78,253, 52,236, 53, 43,170,169,242, 10, 90,113, 41, 74,
+154, 7,165, 42, 70,184, 90,187,169, 63, 33, 13, 52,144, 60,180,211,232,215, 52,163, 7, 47,197, 76,134,218,168,180, 37, 39,219,
+ 79,243,104,104, 93,214,149, 48,244, 23,206,212,148,253,186,230,146, 16,214,156, 81,104, 98, 71, 84,148,212,246, 21,239,174,100,
+187,169,109, 24,187, 14, 29,170,109, 43, 42,240, 7, 68,115,168,142,211, 84,205, 63, 16, 24,203, 51,111, 86,230,158,182,202,144,
+216,140, 29,108,150,254, 97, 79,212,109,173, 58, 84,119, 35,182,170,252,211,189, 13,182,202, 71,151,112,167,181,104,126, 90,242,
+233,230, 13,226,222, 32,192,104,237, 70,185, 0, 49,169, 82, 60, 27, 23, 40, 66, 95,152,167,159, 88, 72, 82,220, 71,198,119, 44,
+141,192, 39,160, 72, 30,193,175, 25,110,151,166,119,147,149, 74,250, 75, 4, 34,217,129,160,214,129, 21, 35,197,102, 45,118,149,
+ 54,154,175,175,146, 59,251, 15,214, 58,146,117, 17, 66,236, 17, 36,150,184,148, 41,228, 60,238,211, 98,139, 32, 73,117,182,252,
+164,144, 66,214,134,208, 64,247,133,129, 81,169, 91, 45,181,243,144, 0, 81,211,222, 54, 17,168,154,118,174,107,242,143,170,120,
+ 16,164,127, 10,179, 56,253,234,232,235,138,102, 53,166,220,202,165,203,121,197, 84, 36, 54,150,193, 89,169,167,134,180,253,147,
+147, 31, 32,215, 39,117,189, 39, 0,179, 78, 96,231,216,173,157,225, 69,223,121,201,173, 21, 39,216,129,145,120, 67,213, 87, 60,
+ 76, 84,181,219,255, 0,184, 86, 9,161, 75, 96,220, 92,255, 0,210,138,101, 93,130,152, 65,243, 17,240,255, 0, 90,135,221,171,
+ 39,243,141,159, 96, 26, 90,124, 87,142,140,189,185, 42,251, 57,107,152,249,179,188,224, 32,136,244,252,212,235, 25,143, 90,155,
+ 55,249, 82,103, 19, 25, 18,230,228,151, 43,139,219, 66,156, 82,208, 18,130,181,119,239, 74,117,247,157, 41, 23,153, 17,188,209,
+177, 80,118, 37,207,145,148, 21,150,228,151,118,132, 48,203,191, 47, 44,227, 11, 42, 83,105,150,243, 91, 85,177,210,159,217,170,
+131,181, 71, 79, 13, 78, 89,115,164, 23, 38,143,193, 66,223,249, 59, 45,176,172, 47,212,171,205,243,133,179,108, 89,110, 5,195,
+152,159, 47,117, 84, 1,113, 6,157,105,210,190,205, 79,182,234, 27,191,144,130,169,183,124,175,121,181, 30,251, 72, 3,138,110,
+178, 93, 46,246,121, 72,102,104,113, 32, 47,203, 36,212, 1,218,189,245, 25,125,183,182, 64,104, 18,251,118,227, 45,179,128,113,
+ 42,193,217, 22,245,213,166, 75,100,184,118,209,101, 39,125,104,124, 69, 53, 70,220,109,252, 5,170,236, 87,223, 85, 76, 81,231,
+ 13,180,184,220,134, 67,204,132, 39,112,163,155, 84,160, 65,167, 69, 36, 10,253,227, 84,187,217, 43,146,212,108, 26, 90, 40, 66,
+232, 79, 14,218,231,183, 58,218, 94, 90,220,132,219,125, 16,191, 49,178, 91, 34,161, 32,130,129,220, 84, 84,255, 0,147, 85, 89,
+222,215, 87,165, 59,187, 46,104,193, 73,121,243, 33,117,225,110,182,196,253,179,140,121,106,125, 74, 86,253,169, 10, 0,246, 20,
+ 53,221, 74,253, 52,212,124, 76, 15,113,169, 82, 91, 60, 70, 54,151, 83, 53, 82, 39,218, 88, 83,168,126,171, 19, 74,210,164,149,
+182, 40, 19, 78,191, 8, 43,241, 21, 29, 7,211,211, 79,153, 41,111, 28, 21,137,173,175, 12, 84, 70,225,105,113, 10, 90,222,140,
+202, 3,136,113,191, 48, 15,196,189,194,181, 61,118,245,241, 63, 95,125, 59,130,230,156, 80,150, 12, 49, 10, 85,198, 6, 80,200,
+ 88,242,156, 84, 54,219,121,178, 28, 79, 70,138,193,221, 67, 80,164,208,129,218,158, 26,230,225, 32, 12,199, 18,152,120,117,168,
+224,186,159,200, 97,165,241,204, 25,123,153,249,181, 69,105,196,146,161,178, 58, 20,146, 84,147, 65, 83, 67,214,132,119,233,238,
+213, 18,181,148, 36, 54,160, 90,231, 14, 11,147,220,131,115,146,244,167,144, 10, 22,165, 56,224,109, 46, 29,172,163, 97,234,165,
+ 87,189, 40,107,236,233,227,211, 87,237,186, 16,214,130,137,123, 54,162, 64, 85,230,235,126,121,169, 14,182,137, 37,228,178,154,
+151, 84, 74, 67,207,146, 1, 32,116,162, 19,209, 40, 79,115,208,116, 29, 53,101,130, 13, 66,164,122,124, 84, 28,179,232,192, 21,
+162, 21,218,114, 95, 67, 40,125, 94,106, 2, 20,250,138,234, 27, 89,170,169, 78,222,202,125, 58,119,225, 53,162,180, 76,157, 49,
+121,160, 40,253,134,221,203, 91, 86,227,238, 33,166, 98, 35,206,117, 75,171,206,110, 80, 38,158,223,197,212,234, 34,245,130, 70,
+145, 69, 33,108,227, 27,135,106,188, 60,123,150,180,245,174, 59,105,253,130, 91,109,123, 71, 82,124,215, 8, 10, 90,136,235,185,
+ 64, 0, 62,143, 3, 90,102,123,165,145, 14,245,173, 2,198,232, 60, 87,169, 29, 70, 78,235, 12,255, 0,186,172, 14,137, 1, 36,
+213, 91,192,175,210, 77, 79, 83,219,195,167, 65,170,249,180,170,146,108,227,138, 93,105,228, 11,148, 73, 13, 45,110, 41, 32, 26,
+ 1,191,227, 0,247, 80, 29, 40, 72,169, 7,195,190,131,172,193, 93, 58,100,193, 90, 62, 62,228,200,242, 20,210,102,124,187,177,
+ 29, 1,185, 76, 56,194, 37, 71, 91,100,128, 16,160,229, 91, 95, 78,166,160,247,235,219, 77, 68, 78,128,234,109, 65, 25, 21, 11,
+184,217, 9, 90, 64, 64,175, 84,126,146,237,146, 45, 82,185,139,139, 92,138,229,174, 66,215, 35, 37,197, 27,113, 66, 69,173,103,
+169,145, 25, 59, 54,134,212,107, 86,202,235, 94,137, 4,144, 53,234, 31, 41,188,203,117,238,157,186,248,141, 96, 81,142,233,234,
+ 61,125,126,213,227,191, 54,188,184, 0,201,125,104,194, 28, 49,123,120, 17,251,205,235,233, 30,204,112, 92,205,155,139, 58, 13,
+ 66, 15,249,117,233, 56,101,170,242,165,220, 52, 81,249, 56,252,132,117, 12,245, 4,233,243, 93, 85, 12,241, 68,149, 86,199, 80,
+130, 93,106,160,119, 4, 87, 71, 72,151, 81, 99,108, 60,216, 10,105,148,162,158, 59, 43,253, 26,227,152, 10,232,125, 22,153, 55,
+153,177, 42,151, 90,109,212,154,128, 11, 98,169,251,180,221,246,141,126, 41, 86,221, 22,168,219,241, 87, 49, 74,121,101,116,115,
+226,242,235, 68,138,251,180,179, 35, 12, 24, 34,248,133,201,166, 69,173,221,167,203, 71,106,232,235,149, 76, 10,129, 45,181, 43,
+114,104, 9,233, 93, 2,138, 94,149,219,161, 79,151, 41,168,113, 97, 63, 50, 67,203, 13,180,203, 13, 23, 92, 90,143, 64, 2, 82,
+ 9, 58,101,113, 35, 98, 5,206, 32, 0,155,203, 54,149,120,120,135,208, 55, 47,242,242,227, 63, 34,192,254, 61,100,119,106,157,
+155, 61, 1,149, 6,149,220,209, 84, 9,233,237,214, 33,206,254,115,237, 60,164,210, 29, 40,123,199, 0,171,219,134,239, 28, 3,
+ 23, 46,161,241, 15,229,173,233,163,137,203, 23,124,237,209,151,223,218,216,243,145, 74,196,150, 82,242,122,144, 77, 10, 7, 95,
+ 96,215,142,185,211,245, 41,187,111, 46,116,118, 3,195,103, 78, 69, 82,111,121,161,141, 39, 78, 42,232,199,206,184,247,142,160,
+136, 24, 46, 49,138, 98,177,227,163,203,110, 82,154,101,169, 33, 41,241, 42, 53, 95,217,172, 2,246,109,219,153,164, 46,158, 73,
+100, 39,128,173, 21,106,227,124,184,186,193,128,160,166,107,234,119, 15,132, 28,123, 39,228,168, 76,161, 32,147, 30, 28,145, 95,
+162,164,234,107,106,242,187,119,220,205, 33,180,127,105, 9,131,118,219,187,211,136, 42,167,102, 62,191,120, 59, 30, 46,166,222,
+219,249, 52,164,110,218,227,139,114, 66, 20,161,254,168, 9,214,175,177,254,153,247,205,198,134,111,203,106,150,182,228,249,101,
+249,130,164,156,189,249,164,242, 92,104, 47,142, 48,198,109, 54,166,208, 20, 60,247, 25, 72,113,182,255, 0,173, 65, 85,154,107,
+ 88,219,255, 0, 74,214,150,109, 18, 93, 72,231,145,152, 83, 13,228,225, 11,117, 46, 76,250,128,252,198,253, 80,101,214, 25,161,
+238, 71,151,108, 45,169,123,218,180,188, 88, 45,147,225, 82, 73,161,214,153,178,121, 53,176, 89, 0, 35,183, 26,135, 72, 79,109,
+246,104, 94, 40, 6, 43,153,150,126,122,203,114, 92,168, 93,243,204,243, 33,154,211, 11, 47, 47,231,174,174,173, 14,168,147, 94,
+133, 91,104, 61,195, 90, 0,229, 72,108, 35,211,107, 11, 65,225, 64, 19,137,118,162,198,126, 80,197, 69,179, 78,116,254, 35,123,
+146,136, 79, 45,118,247, 20, 75, 69, 74, 52, 80, 29,143, 95,110,156, 89,242,133, 27,226, 72, 59,233,222,223,183, 24, 59,210, 1,
+169, 72,120,231,148, 46, 15, 73,144,150,158,110, 42, 73, 9, 92,199,151,181, 45,143, 96, 39,169, 63, 70,167,108, 54, 49,105,139,
+ 6, 37, 74, 67,108,117, 86,136,253,254, 35, 90,254, 87,229,133,237,100,109,170,238,222, 98,188,164,206,253, 84, 86,148,161, 27,
+190,205, 76,255, 0, 41,109, 43, 94,242,123,244, 45,249,171,138,230,245,246,234,146,177,228,158,173, 54, 26, 10, 79,142,172,146,
+141,102,137,163,219,226, 57, 91, 46, 52,202,127,135,227, 86,244, 60, 84, 84, 80, 43,215,175, 93, 72, 71, 30, 24, 41, 8,192, 1,
+ 70, 49,123,196,119,249,163,231,157,113, 73,105, 45,119, 39,181, 84,116,140,157,195, 82,136, 75, 90,234,156,149,252,180, 95, 33,
+184, 27,114, 60,165,142,163,168, 81, 6,154,138,155,126,130, 19,164,226, 83, 73,183,120, 24,104, 49, 69,251, 21,205,183, 11, 65,
+144,226,202,138,106,170,212,125,218,236, 27,215,212, 26, 53,133, 8,247, 47, 20,247, 90, 85,133,197, 98,124,200, 72,113, 67,192,
+208,208,157, 77,131, 81, 85, 40,215, 84, 35,173,150,222,203, 73, 79, 98,174,155,122, 14,250, 33,197,118,170,111,110,125,196,184,
+ 88,144,205, 26,236,149,246, 26, 69,240,137, 69, 28, 42, 17, 77, 29,129, 79,223, 44,222,224,148,172, 45,167, 5, 22,147,214,149,
+253, 58,140,139,108,250, 71,234,136,208,116, 38,173,183,240, 93, 86,100,144,187,141,199,109,207, 49,130, 70,243,187,111,191,232,
+ 26,153,106,122, 10,113, 98,208,242, 83,240,182,179, 65, 90,129,254,109,116,154, 33,169, 61, 71,199,223,144,216, 94,229, 34,158,
+ 4,117,209, 67,151, 67,151,234,241, 55, 13, 84,180, 41,193,254,174,187, 84, 42,178, 62, 21, 57,245,159,146,109,218,208,157,169,
+ 79, 77,113,210, 6,230,186, 42,114, 74, 98, 97,121,107,146, 10, 34,179, 33,208,133, 81, 65, 9,252, 58, 78, 91,136,227, 21,113,
+ 71,100,110,147, 0, 21,157,193, 56,229,104,132,203,243,227,173,201,159, 10,148,149,163,177, 31,126,170, 87,251,139,222,226, 25,
+146,158,179,181,104, 3, 86,106, 45,207,209,144,137, 24, 46, 38,211, 40,140,243,210, 37, 94,230,165, 13,138,252,164, 68,249, 77,
+149,116,162,129,113, 68,208,251, 5,123,235, 31,243, 2,253,205,128, 48,147,137, 94,163,253, 63,237, 53,158,123,178, 48,107, 67,
+ 71,105,196,253,201,170,204,211,112, 27, 45,133,121, 73, 82, 40, 92, 90,186,169, 35,219, 95,139,175,178,191, 71,179, 88, 12,248,
+154,175, 85,185,245, 8,111,203,220,149,141,241,230, 53, 46,245,115,184, 70,134,136,236, 62, 80,176,202, 80,167,148,208,240, 37,
+ 74,169,175,143,142,165,182, 61,174, 77,206, 64,198, 10,146, 84, 22,237,186, 51,107,140,201, 43,168,208, 42,106, 87, 55,172,184,
+ 63, 47,250,178,187,170,230, 37,202,192,248,209,111, 45,227,114,125,165, 38,239,117,132,217,234,166, 91, 88,109, 13, 33, 73,255,
+ 0,173, 90,182,142,244, 58,212,124,123, 94, 90,164, 49,179,198,185,166, 66,154, 90,127,172,122,186, 22,118,203, 59,238,115,252,
+215, 63,233,236,235,243, 26,235,120,254,168, 60, 15, 78, 42,233, 96,120, 47,165,127, 79,204, 53, 10, 28, 8, 87,140,129,202, 55,
+ 33,219, 76,115,118,200,238,143,154, 2,151,174, 47, 7, 30, 86,229,118, 67, 64,167,217,166, 15,177,191,222,221,226, 94, 74, 75,
+120, 52,119, 88, 61, 67,237, 83,113,110,123, 63, 39,183, 69,156, 77, 15,226,227,222,121,237, 38,167,213, 90,116, 5,103, 44, 57,
+143, 39,221, 35,131,197, 94,145, 51,203,164,103, 14,232,151,107,134, 49, 58, 43, 18,144,127, 88, 72,125, 17, 35,185,238, 58,239,
+242,235,107,108, 29, 36, 99,223,241, 80, 23,190,109, 64,195, 71, 75,234,168, 30,236,211,148,245,122,252, 9,243, 88,244,172,166,
+ 33,133, 45,126, 82,155,182, 41,194,131,224, 66,167, 23, 58, 14,212,235,174,135, 91, 51, 41,135,179,246, 40,193,230,230,222, 78,
+ 47, 39,251,197, 3,115,206, 77,245, 17,138,178,233,228,175, 75,121, 20, 59,120, 27,165, 75,143,142, 76,122, 26, 18,154,124, 74,
+118, 26,159,101, 20,167, 66,163,163,198,250,159,203,146, 55,117, 28,254,229, 49,101,230, 78,221,121,221,241, 8, 63,218, 7,220,
+113, 85,113,238, 83,226, 28,221,231,152,118, 1,198,229,188, 84,211,145, 39,178,153,176,154,112,147, 84,254, 20,186,208, 74,186,
+244,173, 61,154,149,130,243,233,143,230, 70, 91,253,102,159,185, 79,182,254, 29,209,180,134, 70,191,250,174,195,222,171, 47, 48,
+122,113, 98,125,190, 69,231, 27,142,149, 5,161,115, 26, 92, 93,175, 65,144,132,245, 82,154,117, 0,164,211,196, 26, 40,120,141,
+ 92,172,247, 32,230,130, 92, 28,222,158,142,209,193, 80,247,158, 92,109,193, 38, 38,150, 72, 51,105,227,216,120,170,223,196,203,
+145, 11, 34, 56,237,193, 10,109,230,156, 74, 22,130,138,109, 70,234,118,167,183,221, 93, 71,243, 29,187, 93, 15,136,213, 29,202,
+146,190,222,231,194,126, 97,117, 59, 8,226,134,238, 2, 26,145, 17, 78,148,161,151, 10,148,154, 36,117,234, 84,124, 41, 66, 71,
+142,176,123,219,231, 49,196, 2,189, 25,106, 35,208, 9, 87, 6,201,142,167, 24,180, 73,146,127, 26, 35,236, 65,242,234,219,117,
+ 30, 29, 15, 80, 62,207,118,171,175,115,184,163,190,102, 92,188, 52,100,170,246,103, 44,205,184,200,113,194,183, 92,169,216, 91,
+ 70,229, 2,107, 74,119,246,248,105, 88, 42,173, 86,208,180, 52, 10, 33, 99,172, 41, 83, 17,243, 40, 81, 82,128,105,166,212,224,
+222, 21,237,160,169, 29, 7,142,159,214,141,193, 58, 99,123,193, 47,184, 89,226, 77,134,255, 0,154,186, 81, 10,105,150,146, 41,
+181,123,217, 21, 21, 36,154, 7, 1,239, 94,154, 44,110, 44, 53, 8, 74,250,247, 86,140, 46,218, 45,151, 68,161,214,183,149,184,
+218, 91, 81, 64,163,123, 9,169, 87,135,126,159, 95,176,107,151,111,214,212,197,216, 18,186, 21,124,113, 23, 12, 30, 21,180, 60,
+162, 19,110, 5, 37, 20, 67,138,109,164,252, 65, 98,138, 85, 16,175,103,135, 77, 65, 70,206,254,165, 7, 28,190, 19,221,214, 87,
+ 41,121,138, 35, 54,183,165,111,113,198, 35, 33,110, 21,200,144, 82, 36, 78,116, 31,192,148,164,116, 74,127,170,145,211,237,214,
+129,181, 3, 37, 58, 83, 59,233,116,130, 74,166, 23, 43,235,105,151,185, 6,155, 85,189, 8, 32, 40, 37,209,248, 86,160, 58, 18,
+138,213, 41,173, 43,220,211, 87, 72, 96,160, 85, 57,238,234, 84,211, 18,140,252,208,210,201, 63,239, 11, 90,192, 90,170, 84, 5,
+ 42, 73,241, 0,116,255, 0,159,164,125,244,162, 58,133, 39, 96,195, 38, 39,212,172, 5,134, 43, 76,161,181, 62,165, 24,234,121,
+ 43, 95, 64,149,205,113, 36, 16,144, 43, 77,169,167, 65,246,158,218,175, 75, 57,113,162,159,100, 32, 10,171, 47,133, 92,211, 22,
+ 48, 83,174, 41, 5, 78,121,197, 2,133, 67,250,160, 10, 10, 80, 26, 39,167, 78,230,157,245, 1,123, 24,149, 74, 91,200,230, 96,
+142, 48, 47,111, 61, 29, 42, 74,144,192,119,227, 52,162,148,128,124, 43,227,211,195,244,245,213,126, 72, 40, 84,187, 37, 95,143,
+ 92,215,181, 68, 44,132,171,161, 82,151, 77,228,248,147,212,168,159,103,244,105,185,143, 20,253,146,212, 41, 62, 55,153, 73,132,
+243, 49, 80,241, 8, 74,130,148, 73, 81,169, 7,193, 41, 35,183,113,215,233, 39, 68,146, 0,236, 81,129, 5,116, 95,130,249, 42,
+211,114,138,113,203,202, 25,149,111,185, 71,114, 12,232,110,252, 45,188,195,192,161, 68,169, 93, 43, 66,105,214,163,195, 81,129,
+210, 88,202,217, 99, 36, 57,166,160,246, 42,190,255, 0,182,253, 75, 9, 25,211,208, 42,125,234, 35,211,156,222, 50,204, 66, 45,
+ 78,166,126, 37,145,135,110, 56,237,192, 13,254, 83, 43, 85, 87, 25,213,109, 74, 74,216,175,113,220, 83,223,175,108,121,117,206,
+204,230,171, 32,247, 97, 43, 40, 30, 58,248, 17,212,126,213,243,243,204,190, 76, 60,185,117,170, 32, 76, 50, 18, 91,134, 45, 60,
+ 90,123, 51, 7,136, 35,173, 4, 85,196, 51,156,142,100, 38,108, 87, 20, 70,224,213, 69,122,248,120,235, 68,102,227,141, 52,149,
+145, 92, 90,233,226, 20,187, 19,225, 20, 74, 96,189,116,136,151,106, 58,109, 70,224,126,221, 53,188,220,157, 90, 49, 37, 21,184,
+226,163,124,147,196, 86,203, 44, 15, 62, 35, 74,142,234,143, 68,249, 96, 3,165,246,251,231,204,237, 37, 39,115, 11, 88,218,170,
+211, 47, 12, 46,168, 7, 73, 65, 73,232, 74, 69, 15,219,169,199, 58,156, 20,120, 33,201,178, 78, 33,117, 74, 82,220, 56,134, 66,
+123,110,108, 84,129,162,125, 67, 7,204,104,142, 26, 78, 73,202,203,197,153, 29,249, 74,109,182, 75, 69,190,170,221,223, 77,231,
+220, 34,131, 18, 82,209,192,233, 19,125,251,136,178,104,175,132,170, 19,202, 67,103,170,219, 69, 65, 3,199,182,187, 21,244, 82,
+228, 81, 36,129,236,224,172,207,166,124,167,142, 56,122,100,171,222,101,137, 38,255, 0,122,106,191, 38,137, 17,194,144,219,128,
+252, 53, 36, 26, 1,227,172,219,204, 62, 93,220,185,146, 49, 13,148,218, 24,115, 85,141,226,218,226,228,105,136,209, 90,220,183,
+243, 11,189, 72,142,168,120,253,136, 91, 97,161, 37, 12,198,140,132,176,210, 18, 59,116,233,172, 33,191,166,113,118,253,119,115,
+234, 62,213, 83, 60,162,249,141,101,146,170,165,102,158,176,185, 70,242, 94, 49,231, 42, 10, 21,186,159,182, 83,138, 21,247, 13,
+163, 87, 61,163,244,237,178,237,244, 47,102,179,216,159, 65,202, 54,241, 98, 69, 85, 93,202, 57,111,147, 47,232,121,217,153, 21,
+233,246,149, 82,164,179, 33, 77, 55, 67,254,169, 7,239,214,149,183,249,125,181,109, 64, 8,173,216, 15, 88, 10,106, 29,146, 40,
+199,117,129, 87, 43,238, 97, 45,110, 57,243,210, 36,184,224,221, 85, 72,117, 78, 42,191,237, 18,117,111,183,218,153, 8,238, 52,
+ 1,212, 19,214, 90, 6,112, 66,219,182,112,219, 37, 91,159, 9, 2,189,212, 6,158,139, 70,179, 52,175,134, 27,154, 23,222, 57,
+ 50,220,128,227,110,205, 70,213, 2,149, 37, 70,169, 41, 61,252, 52,163, 97, 97, 71,104,105, 85,206, 70, 53,102,202,178,176,164,
+221,163,179,142,190, 20,245,209, 11,116, 20,162,167,240,237,241, 7,190,171,252,196,195, 97,108,233, 32,102,167,156,168,163, 55,
+ 74,219, 68,231,196,218,185, 86, 78,113,200,176, 27,124,247, 49,252, 22, 34, 36, 49, 8,169,167,174, 32, 0, 29, 90,122, 19, 90,
+117, 36,142,218,172,242,182,219,125, 39,231, 94,186,132,228,213, 21,178,217, 92,185,190, 44,230,149,224,171, 3,211, 10,157, 75,
+193, 70,148,237,236,214,128,214, 97,165, 88,132, 41,218, 45,234,224,235, 6, 12,119,156,101,165, 31,143,202, 81, 74,220,247,116,
+235,215, 64,143, 8, 97,154, 83,195,170,154, 3,127,254,239, 56,207,158,175,149,249,150,171, 26,159,181, 43,218,186, 43,117,123,
+129, 94,154, 75,189, 85,223, 4,209, 31, 56,243,136,177, 57, 81,210,246,101,116, 13,169,101, 42,242, 27, 88, 4, 15,166,186,175,
+110,155,253,204, 85, 22,209, 87,172,170,164,247,210, 71,132,109, 86,101,140, 91,136, 45, 54,230,227, 66,243, 95, 91,109,237,109,
+ 68,151,126, 47,169, 73, 26,130,183,222,247,151,186,175,193,190,196,156,119,183, 36,213,216, 4, 7,179, 99, 56,250,121, 6, 83,
+204,220, 16,128, 82, 84,150,206,212,169, 41,169,255, 0, 72,253,154,187, 67,119, 53,224, 1,236, 42, 67, 83,174, 62, 97,130,179,
+118,215, 34, 68, 75, 77, 71, 95,154, 42,144, 20, 8, 85,117, 49,107, 99, 16, 21, 49,208,167,112,218, 70,223,194,172, 53,145,207,
+149,183, 69,122,164,149, 4,147,211, 73, 90,204, 12,206, 96,201, 60, 32, 55, 36,117,227,251,226,165, 60,164, 40,208, 35,183,129,
+212,217, 9, 74,171, 29,102,186, 33,199, 80,210, 92, 5, 85, 2,149, 26, 73,216, 46, 23, 81, 26,109, 54,119,110, 94, 75, 44,133,
+188,234,246,128,148, 10,158,191, 70,147,124,130, 49, 82,140,214,151,154, 4, 90,137,198,151,196,178,151,191,135,184, 91, 74,119,
+ 41, 74, 73,232, 52,203,249,148, 85,165, 83,143,164,146,149,162,252,106,199, 25,135,233, 45,178, 3,102,138, 79,178,159, 70,156,
+185,228,182,173, 77,201,210,113, 75,228,170,214,217, 75,113, 25,246, 3, 95, 31,191, 66, 32,226, 42,228, 28,224,114, 79,214,219,
+ 12,201,129, 42, 76, 82,150,137, 31, 30,209, 64, 52, 12,205, 6,149,197, 24, 49,199, 26, 41,132,140, 29,192, 35,183, 26, 74, 29,
+113,224, 42,159,133, 59, 73,250, 14,131,101, 20,169, 64,179,161, 79,236,124, 73,118,106, 27,179, 76,168,141, 4,180, 85, 66,180,
+169, 68,125,103, 76,100,188, 99,156, 5, 9, 78,153,110,240, 9,173, 20,102, 60, 92,130,207, 42, 66, 33,186,210, 82,165,168, 56,
+181, 32, 26,245,240,211,153,109, 35,184,161,112, 72, 50,233,240,156, 20,250,201,148, 92,109, 77,168,190,150,165, 58,163, 93,219,
+ 69, 1,212,124,187, 99, 56,100,158,195,184, 56,102,171, 86,125,144,207,204, 57,125,225, 32, 54,132, 90,109, 22,200, 8, 8, 29,
+ 66,164, 85,229,245,233, 78,138, 72,167,187,223,175, 59,249,166, 67, 46, 68, 99, 32,209,239, 94,229,242, 22,220, 67,178,248,199,
+ 55,189,196,158,204, 61,212,246,164,249,221,201,156,126,222,150,130,144,149,148, 87,104, 87,150, 9, 3,169, 82,128, 42,251, 6,
+177,177, 9,148,209,109,208, 78, 9,212,114, 92,244,181,216,100,250,145,228,219,133,203, 32,119,103, 23,241,180,183, 26, 44, 56,
+222,235, 93,218,237, 19,172,135,100,133, 26, 56,136,235,163,109,179,250,238, 84, 18, 18,133,107, 75,177,129,219, 37,187, 96,135,
+ 9,229, 21,115,184,181,167, 32, 58,221,211,192,118,170, 44,205,143,152,238,164,186,185,198,214, 7,105,107,120, 72,241,153, 63,
+213,110, 84,226,123, 23, 75,125, 60,250,110,228,159, 86,151, 68,217,112,230,228,241,215, 8,218, 95,110, 37,199, 47,110, 18, 87,
+ 59, 33, 92, 51,177,198, 33, 15,217,161,213,166,132, 23, 8,242,219,236, 18, 72,219,163,207, 61,183, 45,176, 52, 0,233,143, 14,
+138,241,113,244, 43, 49,231,159, 50,157, 14,168,227, 56,100, 0,232,251,135,219,195,165,125, 0,122,113,252,185,248, 3,133, 89,
+141, 47, 27,193,162, 78,200,131, 73, 76,156,187, 32, 6,247,146,201, 89, 20, 81,249,151,247,169,144,191, 20, 50, 16,143,244,117,
+ 24,199,222,111,103,243, 28,116,244, 12, 2,243,126,243,205,151, 23,196,234,121,161,224, 48, 31,183,215, 85,208, 11,103, 21,217,
+ 34,180,132, 53,109, 97, 33, 32, 0, 18,202, 69, 6,172, 54,156,172, 8,196, 42,140,155,139,157,197, 44,155,198,182,197,182, 71,
+200,181,219,254,204,105,212,220,170, 0,201, 38,203,247, 14, 40, 25,156,241, 13,146, 99, 14,165,251, 92,119, 82,164,144, 66,152,
+ 73, 20, 63, 86,170, 91,142,200,235,108, 90,165,109,119, 55, 2,184,133,235, 51,242,209,226, 30, 86,106,239,144, 89,172,136,196,
+ 51,175, 37,231, 99,100,214, 6, 68, 89, 78,201, 77, 74, 76,166,147,181,169, 96,158,138,243, 6,234,116, 10, 79,125, 49,178,222,
+230,177, 58, 30,106,206,130,180,174, 93,230,201,236, 75,104,234,180,112, 63,113,225,246,117, 46, 2, 98,139,205, 56, 19,148,102,
+113, 7, 44,219, 85, 42,210,102,252,163,161,246,246,195,185,219,148,178,211,115, 97,169, 95,132,129,215,253, 19, 84,171,198,182,
+ 83,121,244,237, 19,192,123,135, 48,189, 83,202,187,180, 92,215, 0,105, 61,240, 59,167,136, 61, 7,239,246,142, 8, 51,207, 92,
+ 95,107,226,223, 82, 88,212,187,107,129,220,103, 39,110, 29,198,223, 33, 72, 9,110, 84,119, 66, 92, 69, 54,147,184,138,245, 30,
+208,117,109,181,185,254, 99,100,246,140,104, 42, 59, 8, 85,253,222,219,249,125,236,114,145, 77, 85, 14, 29, 96,250, 21,214, 78,
+ 57,176,214,193, 18,236,210, 22,168,239,132,133, 42,155, 18,235,212, 9, 41, 77, 69, 8,110,135,113,247, 80,107, 19,190,183,211,
+ 33, 11, 67,143,116,214,192, 43,193, 62,230,215,150,225,219,141,190,222,152,239, 62,148,144,243,142, 4,173,191, 53, 64, 10, 32,
+ 40,252, 52, 3,219, 95,210, 33,110,218, 26,104,167,118, 54, 25,157,168,228,170,181,214, 3,207, 60,119, 6, 83,185, 74,113,215,
+ 20,118, 49, 83, 83, 90,116,220,125,234,211,120,222, 1, 90, 60,108,210,202,161, 21,208, 54,212,227,177,231, 20,150,150, 65,112,
+ 55,176, 42,157,182,131,246, 13, 73,179, 16,155,190,114,210,147,166,228,226,188,134,214,202,136,111,122,144,176, 1, 81, 6,157,
+125,228, 17,165, 67,104, 18,126, 40,125, 74,149, 91,146,194,228, 52,242, 13, 9, 74, 69, 64,162,183, 3,215,165,123,215,184,211,
+121, 1, 34,137, 9, 8,105, 86, 14,229, 45,249, 24,188,119,190,105,216, 81,227, 52,218, 94, 92,102,214,235,138, 79, 96, 78,199,
+ 19, 81,211,168, 80,167,182,186,111,108,220,105, 74,168, 43,142,227,205, 10,230, 95, 61,222, 99, 41,233, 66, 57,118, 74,247,168,
+ 25,111,148,164,128,138,138, 32,110, 36,251,124, 41,224, 53,160,108, 80, 28, 42,171,251,189,198,150,170, 60,171,164,116,206,255,
+ 0,122,113, 10, 78,240, 27, 11, 62, 82, 20,123,248,210,190,250,159,175, 87,159,166,113,111,116, 42, 3,183, 22,181,253,226,172,
+102, 29,124,135, 26, 51, 46,186, 89, 45,186,216, 66, 20,226,135,237, 82,145, 77,169, 73, 20, 72,247,248,125, 61, 69, 82,254,209,
+206, 36, 43,174,221,185, 52, 52, 28, 17, 90, 6, 83, 9,110,135, 86,226, 72,108,237, 69, 20,146, 63,213, 72,161, 72, 3,199, 80,
+239,178,112, 20,162,154,110,226,215, 26,213, 23, 49,251,210,222, 75, 74, 74,138, 18,241, 74,183, 42,159,132,123, 6,234,154,251,
+255, 0,203,168,171,136, 52,224,164,237,238,117,119,138, 54,218,111, 96,182,219, 78, 56,104, 83,248,201,236,131, 78,137,165, 79,
+197,227,211, 81, 18,219,169, 22, 92,116, 41, 19,183, 86,151, 66,202,214,163,217, 39,112, 90,235,226, 79,130, 0,247, 13, 50,117,
+186,127, 21,206, 9,108, 43,148,118,210,149, 41,137, 37, 98,155,151,243,137,101, 10, 53,240, 1,146,175,191,235,209, 60, 49,208,
+148,241, 94,114, 35,217,251, 81,175,142,115,229, 91,238, 49, 82,192, 12, 45, 11, 73, 74,214,234,151, 64, 15,189, 67,237,219,166,
+ 87, 54,192,138,209, 41, 83, 32,163,143,216,186, 77, 61, 45,114,215, 14, 77,182, 24,241,165,222, 44, 43,106,249,107, 46,124,111,
+213,128, 67,173,161, 91,142,223, 49,181, 30,157,137,165,125,186,181,249, 97,191,127,199,247, 70,235, 36, 70,254,233,245,228,105,
+219,235, 88,119,155, 60,165,252,242,194, 88,227, 0,190,154,155, 95,222,110, 57,244,145, 80,168,138,225,150, 38,135, 3, 46, 33,
+182,215, 69,177, 93,189, 82,122,244,174,189,181, 8, 18,183,183,138,249,237,122,211, 11,136, 34,132, 26, 17,216,138,214,158, 67,
+182, 91, 99, 8,234,181, 16, 82,141,187,136,253, 97,166,143,217,221, 33,173, 83, 49,126, 25,193, 9,179,140,129,252,157,213, 36,
+176,148, 70, 73, 37,180,237,234, 1,212,157,158,222,219, 92,120,166,151, 23,134,110,196, 62,183,225,177, 47, 82, 81, 21,229, 8,
+233, 90,130,119,168, 0, 5,126,157, 57,158, 67, 8,168, 21, 73, 68, 4,134,137,125,243,141, 98, 98,238,178,220, 91,235,101, 79,
+144, 0,220,149, 4,149,123,141,117, 29, 28,166,243, 23, 51, 36,253,205, 22,249, 57, 16,184,243,138,231,151, 92,156,155,170, 38,
+ 33,209, 85, 33, 27,104, 43,244,105,141,241,107,187,186,104,156,219,146,222,245,106,139,235,227,148,166,170,146,150,220, 73, 29,
+ 82,180,130, 8,211, 12, 27,136, 78, 11,203,240, 65,156,243,134,172, 79, 50,245,193,181,166, 9, 66, 74,151,182,137, 6,159, 94,
+158,219,223, 61,167, 78,105,132,214,192,226,169,182, 69, 99, 98, 20,151, 91,136,233,125,180,149, 13,213,175,109, 79, 70,194,241,
+ 82, 20, 99,216, 1,160, 67, 59,157,185,211,184,121,100,142,190, 26, 84, 66, 23, 3, 86,200, 50, 34,124,139,182,247, 96, 4,168,
+ 54,173,206,148,142,218,143,184,180,112,118,160, 83,232, 92, 41, 69, 79,249, 88,165,185, 14,183,106,136,165, 16, 87,189,192,158,
+198,190,209,169, 27,104, 31, 76, 83,105,128, 57, 42,115,148,200,187, 52,167, 75,145,157, 53,221,219,160,211,145,100,211,137,197,
+ 50,250,113,153, 85,250,251,123,117,162,234,100, 64, 90,135, 80, 77, 77, 71,223,165, 62,145,188, 2, 56,107, 91,193, 3,114,108,
+138, 92, 86,223, 85,189, 83, 35,121,169, 82, 22,148,172,128,164,159,120,209, 29,108, 14, 5, 17,238, 10,190, 1, 46,125,197,108,
+ 37, 11, 83,178, 92, 85, 1, 21, 82,148,173, 49,186,140, 68, 53, 28,130, 40,152, 48, 18,114, 73, 46,118,233,150,153, 10,137, 45,
+ 5,183, 65,234,146, 40, 70,145,183,149,151, 35, 83,114, 66, 41, 68,162,173,201, 56, 89, 84, 26,112, 56, 83, 85, 15,194, 41,216,
+233, 66,218,228, 42,151,213,165, 23,196,134, 63,187,139,122,191,239,127, 50,209,252, 61,134,213,244,209, 60, 7,106,165, 56, 34,
+120,248,245, 34,133,173,167,145, 71, 22,181,169, 99,174,229, 18, 72,167,210,117, 33, 21,155, 92, 42,241,234, 81,173,136, 28, 74,
+144,219, 93,126,235, 41,108, 52,181,171,203, 29, 84, 84, 72, 20,211, 31, 11,234,102,210, 0, 13, 9, 17, 73, 95, 65,144, 78,246,
+140, 53,246,175,106,185,161, 31,181, 41,218,165, 1, 67, 77, 78,134,134,228,159, 0, 2,178,120,253,145,246,162,177, 33,208, 20,
+ 66,146,118,171,169,233,166, 2,224,201, 33,101, 48, 70, 71,139,109,205,165,199, 97,149,163,111,150,128, 8,219,211, 72, 90,109,
+134,222, 71, 72, 78,107,138,119,137, 93, 91,110,122,210,202,182, 39,198,157, 63,167, 82,161,168, 43, 73,199,210,109, 11,152,133,
+220,101,121,105, 43, 73, 42,173, 52,214,228, 61,163,184, 17,227, 13, 39,188,175,198, 19,156,241,205,141,136,193, 14,182,236,164,
+160, 85,100, 84,215,235, 58,172,221, 90, 92,220, 28,114, 82,144, 92, 67, 10,113,201,125, 65,209,245, 67,180,186, 18,193, 73, 65,
+ 29, 6,228,233,205,158,200, 0,171,243, 72,207,185,151, 30,234,128, 43, 49,126,121, 83,232,109,110, 41,211,185, 69, 41,175, 85,
+106,122, 56, 3, 5, 20, 99,159,168,213, 98, 63,143, 92,104, 97,176,231,152,163,240,138, 83,175,134,149,160,110,104,149,170, 37,
+227, 67, 60,182,199, 44, 78, 10,242,220,234,148,173, 53, 27,126,173, 51,250,104,164,118,161,154,112,235,137, 24, 40,114, 71,108,
+ 90,248,184,236, 6,223,181,165,114,118,254,251,104, 10,220, 71,183,190,144,146,197,207, 63, 54, 8,209,222, 6, 12,177, 79, 12,
+191,118,150,251,202, 83,178, 90, 66,201,163, 97,210, 19, 79,168,233,219, 45,154,193,146, 65,247, 46,119, 20,164, 66,117,103,106,
+210, 8, 63,136,158,164,157, 42, 90,146, 14, 74, 12, 8,173, 15,137, 35,119,125, 54,145,169,204, 78,232, 84,241, 23, 22, 36,115,
+ 62,110,183, 20,134, 97, 89,164, 49,231,146, 54,164, 22,163, 53,220,251,104, 42,125,192, 83, 94, 91,243, 36, 58,107,233, 15, 88,
+ 3,212, 23,208, 95, 41,218,219, 62, 94,181,107, 78,109, 36,246,151, 19,251, 59, 21, 71,231,190,107, 85,202,233,145,219, 44,145,
+ 93,158,245,146,211, 54,105,142,218, 74,216,136, 26, 74,131, 74,146,164,159,133, 79, 58, 82,219, 77,147, 74,154,252, 68, 26, 87,
+118, 93,144, 55, 67,229, 52, 14,112, 29,189, 52,236, 24,146,172,219,190,242,232,163,123, 34, 26,158,214,147, 78,142,138,246,154,
+ 0, 58,213,140,244,207,233,238,249,149,193,226, 94, 10,178,162, 83, 47,229, 41,141,148,242, 61,196,124, 82, 34, 90, 37, 20,186,
+249, 91,148, 4, 45, 72,119, 96, 4,116,113,106, 52,234,117, 41,117,185,182,220, 75,120,236,235, 70,142,190, 30,160, 61,192, 42,
+119, 56,110, 99,150,172, 25,108, 15,202,204,113,205,199, 19,237, 53, 39,170,171,235,255, 0,131,248,151, 29,192, 49,108,123, 20,
+198,237, 48,237, 86,139, 45,186, 36, 8,113, 34,178, 27,109,150, 35,164, 36, 14,157,201,238, 73,234, 79, 83,170,150,215,108,253,
+194, 93,111,196,147, 82, 87,145, 55,157,201,247, 15,115,220,106, 73, 87, 6,207,105,109,150,208, 2, 18, 58,123, 41,173,159,101,
+218, 3, 0,193, 83,229,148,184,172,202,115,108, 3,143, 97,179, 59, 59,204,113,108, 62, 27,229, 72,142,254, 75,124,141,101, 68,
+165,167,169, 75, 95, 48,227,101,210, 7,130, 42,117,109,146, 75, 93,173,161,215, 18, 49,131,250,196, 15,181, 54, 21,126, 3, 21,
+ 36,176, 92,177,236,190,193, 3, 38,197,174,214,188,135, 30,186,199, 50,109,183,155, 60,198,238, 22,233,209,194,138, 74,218,121,
+165, 41, 11, 1, 73, 41, 52, 61,193, 26,151,130,214, 45,198, 15, 30, 2,215,198,107, 71, 2, 8,192,208,251, 14, 7,173, 20, 73,
+ 67, 78, 57, 40, 38, 89,110,108,182,191,133, 61,143,134,168,123,238,220, 5,112, 78,162,125, 21, 29,229, 59,107,104, 18, 73, 74,
+104, 82,191, 13, 98,251,197,160,141,199, 5,105,219, 39,201,124,224,126,104, 60, 93,108,151,142, 64,228, 27,124, 86,154,189, 98,
+247,118,100, 25, 77, 35, 99,170,133, 45,105,105,228,149, 14,165, 52, 33,116,246,164,107,187, 52,132,181,209, 28,168,183,255, 0,
+ 43,183,119, 89,223,177,149,238,191, 15, 88,196, 31,180,122,215, 51,185,182,211, 35, 47,227,255, 0, 77,247,255, 0, 45,249,147,
+154,191, 74,199,118, 54, 9, 89, 75, 78,238, 73, 37, 63, 29, 2, 92,161, 32,246,175,187, 87, 78, 82,144,182, 57, 24, 78, 77, 63,
+111,237, 91,119,152, 32, 7,181,227,139,154,125,163, 31,177,116, 57,140,166, 53,159, 19,198,241,160,194, 63,137, 49,108,107,116,
+ 86, 20,148, 52,211,174,165, 59, 17,183,112, 80, 13,160,117,233,222,164,245, 36,234,151,184,195, 71,184,132,223,100, 99,167,239,
+ 19,130, 26,228,241,114,116,133,201,242, 89,242, 29,169,107,246,187,219,247,129,176,184, 9, 62, 37,123,125,222,234,156,241,177,
+199,188, 74,213,246,186,176, 13, 8, 49,122,123, 34, 69, 66, 83, 24,169,196,148,213,109,213, 67,165, 59,133, 80,143,126,144,101,
+188, 68,215, 21,102,117,236,172,109, 48, 66,139,178,167, 48,149,252,245,189, 14,169,104,220,212,136,219,134,210, 79,128,168,235,
+167,173, 99, 79,202, 83, 39, 92,184,226,224,162,170,186, 50,151,210,118, 61, 29, 41, 32,180,243,205, 16,217, 35,191,141,126,147,
+165,227,129,244,174,107,175,188,140,101,130,159, 99,202, 76,241,185,167,219, 32, 40, 0,164, 43,114, 74,188, 5, 71, 65,238,210,
+ 50, 48,198,113, 9,188,183, 65,195, 58,163,148,199, 28, 78, 34,238,215, 18,151, 91,103,106,170, 73,109,193,225,186,134,148, 81,
+232,126,159,110,133,172, 21,117, 84, 12,215,128,190,133,115, 35,155, 15,206, 38,107,107,109,104, 45,135, 86,162, 79, 68,171,189,
+ 73, 2,164, 83,173, 77,126,158,244,208,118, 54, 80,138, 42,238,249, 40,240,205, 87, 50,179, 11,215,240,137,207, 54,135, 86, 74,
+ 13, 80,216, 86,240, 20, 58,212, 83,244,107, 93,219,172, 77,195, 69, 66,243,222,255, 0,188,139, 9, 8, 5, 55,194,230, 73,177,
+ 18,132, 81,211,229,167, 98, 73,220, 64, 3,216,154,132,143,179, 75,205,203, 2, 76, 84,117,175,152, 46,136, 83, 20, 73,198,121,
+226,146, 26,249,199, 75,109,183,180, 39,114,118, 32, 31, 10, 1, 81, 64,124, 62,221, 68, 94,114,137,161,210, 21,163,109,243, 29,
+174,112, 15, 52, 10,212,225,220,253,103,124, 54,210,167,164, 57,181, 37, 84,118,138,123,219, 82, 84, 41,244, 13, 83,239,121, 74,
+ 86, 99,165,104,187,119, 61,193, 56,166,176,172, 86, 61,202,214,249, 69,183, 28,155, 29,176,190,187, 55,252, 36,116,160, 21, 85,
+ 72,213,118,227,151,100,103,225, 42,213,111,205, 49, 63,241, 4, 89,133,159, 66,146, 27,102, 60,132,187,190,149, 75, 53, 89,160,
+247, 14,135,232,212, 28,251, 43,163,197,193, 78,219,111,205,154,129,166,168,157, 99,187,182,234, 3,171, 93, 1, 72,234,224, 1,
+ 93,125,129, 85,251,181, 1,115,106, 91,128, 86, 43,123,192,225, 82,166, 86,251,144,110, 67,107,101,208,146, 22,146,118,144, 9,
+161,247, 83, 76,140, 29, 42, 69,183, 64,174,141,122,103,228, 69,194,184,194, 68,165, 57, 46, 62,244,161,214,246, 36,165, 77,171,
+162,146,119,116,234, 61,163, 81,146,219,150, 59, 80,192,168,141,225,191, 81, 17, 0,226,143,188,137,195,216,212,108,133,111, 70,
+117,198,163,228, 97,119,139,107, 69,178,132, 50,220,197, 21,249, 65, 85, 33,126, 93,105, 95,187, 94,178,228, 30,106,147,116,177,
+101,113,115, 0,105,245, 12,215,128,252,210,229,102,237,183,238,149,191, 36,181,119, 97,174, 33, 68, 36,241,133,138,205,105,125,
+ 87,118, 83,183,105, 40,126,157, 71,179, 90, 4,123,140,147, 60,105, 89, 44,246, 76,137,166,168, 6, 32,216, 96,220,157,222,200,
+153, 16, 40,132, 13,181,241,212,252,140,146, 86, 96,104, 84, 3, 30,200,221,142, 33, 44,184,206,177, 22,139, 80, 44,237,180,179,
+209, 46, 4,128,160,163,239,211, 56,236,101, 6,174,122,112,251,198, 17, 64,212,247,104,226,107, 78, 83, 13, 19, 46, 87, 6,155,
+125, 67,115,109, 41,254,160,248,105, 57, 46,223,108,234, 1,130, 86, 56, 4,226,164,226,136,120, 7, 27, 79,196,174, 18, 86,236,
+196,185,111, 80, 59, 18, 85, 80, 7,219,166, 55,151,173,185, 2,131, 20,246,214,213,208,230,112, 72,243,236,186,209,103,125, 76,
+161,239, 53,212, 84, 20, 54,106, 42, 62,141, 35, 30,219, 37,206, 35, 36,105, 47, 89, 6, 7, 53, 88, 51,140,241,203,212, 69, 66,
+101,183, 25, 79, 98, 82,146, 10,135,219,169,155, 45,171,233,141, 78, 42, 58,226,255, 0,197, 20, 10,190,205,128, 23, 82, 89, 85,
+ 13,122,237,175,125, 75,233, 76,131,212,102, 85,136, 61, 93,140,168,253, 13,147,161,146, 48,114,135,220,177,215,155, 14,121,104,
+ 83,101, 64,131,240, 17,223,233,208,160,114, 48,121, 8, 33,145, 96, 37,245,184,165,181, 85, 47,113,234,154,146, 78,149,107,168,
+133, 85,124,203,184,189,229,249,191,238,149, 79, 95,139,203,233,165, 90,245,194, 85, 99,202, 56,141,213,151,105, 12, 30,167,245,
+ 52,160, 40,168, 1,147,113, 43,165,167, 27,254, 31,224,161,187,203,209, 8, 69,117, 16, 74, 15, 18,203,133,148, 91,101,124,175,
+236,218,154,217, 93, 80,105,180,157, 50,220,226,241,224,123, 70,100, 40,251,168, 76,172,115, 71, 20,151, 63,226, 27,157,211, 41,
+157, 49,168,228,178,226, 89, 45,237, 73,218, 58,117,251,245, 27,177,219,139,107,118,177,217,226,145,177,133,214,209,134,149, 22,
+ 99,135,174,241, 84, 10,162,172,138,244, 59, 15, 77, 76, 55, 75,114, 78,205, 92,165, 63,225,228,255, 0,146, 49,254, 89,123,170,
+ 63, 80,248, 3,165, 53,163,211, 5, 63, 97,187,116, 40,198,109,197, 11,249, 81,248,146,158,138, 35,199, 81,151,183,115, 75, 25,
+ 48,138,117,149, 25,113, 51,220,210, 88,142,216, 62, 63,198,243,237, 8,155, 13, 51,162,203,144,157,196,168, 41, 32,168,245,247,
+141, 86,246,246,110,246,238, 46, 33,174,105, 81,182,130,234, 60, 72, 4, 41,131, 56,236, 40, 65,107,138, 92,126,191,128, 19,215,
+244, 13, 91,173,230,184,127,206,208, 20,204,114, 61,223, 48, 68, 44,118,198,236,182,144, 28, 66,209,212, 80, 84,211, 82, 13,104,
+110, 52, 78, 43, 68, 77,135,139,134, 91, 43, 35,160, 78,140, 77, 87, 53, 41, 62, 49,142, 16,242,228,159,192,165, 80, 87,167,232,
+209, 64,210,139, 90, 35, 5,182, 9,136, 18,164,170,190, 62,221, 27,230, 67, 82,150,179, 46,115, 20,113, 27,146, 64,248, 71, 94,
+186, 5,161, 20,185, 59,218,211,120,144,250,166, 72, 75,165, 21,162, 82, 42, 78,147, 56, 36,203,168,172,246, 19, 13,247, 32,178,
+167, 82, 80,149, 16,104,164,245,215, 40,134,164, 98,182, 45,246,220, 67, 81, 77, 22, 8,161, 3,181, 62,253, 20,178,185,161,170,
+133, 18,109, 80,111, 87, 73, 76, 53, 40, 62,229, 72, 74, 74, 16, 64, 72,247,246,210, 36,199, 0, 37, 42, 11,230, 52, 87, 15, 4,
+227,235, 52, 72,141,170,106, 67,242,222,108, 40, 37,116,160, 81, 29,143, 93, 87, 46,119, 25, 36,117, 25,146,152,182,180, 99, 71,
+123, 52,146,255, 0,128,220, 99, 61, 34,224,212,100,162, 50, 9, 41,109,190,164,167,234,212,173,181,243, 40, 26, 78, 41,149,197,
+147,234, 92, 6, 10, 2,227, 11, 0,238, 97,198,205, 72,248,129, 26,147, 4, 59, 34,152, 16, 91,152, 90, 90,129,231, 41, 33,208,
+160,146,161, 90,127, 87, 72,205,128, 74,196,113,197,115, 95,156,175,173,225,220,183,202,118,171, 34, 84,135,102, 68,180, 78,105,
+107, 3,112,126, 92, 22,106,170, 26,130, 2,147,184, 18, 40,123,145, 74,235,206, 60,239,107,226, 94,234,127, 26, 47,121,249, 83,
+117,227,108, 16,134,227,167, 80,245,212,250,117, 42,201,196,216, 43,121,100,136, 22, 22,153, 13,219,178,124,178,202,237,226,115,
+242, 3,179,111,140, 69,158,204,169, 78,171,122,124,197,163,202,136,176, 22,149, 20,245, 2,170, 53, 81,165,238, 23,133,179,130,
+ 78, 45,105, 0,112, 21,105, 3,171,143,244, 45, 39,107,219,199,133,151,116,184, 56,158, 46,210,117, 99, 92, 72,238,211,227,154,
+250, 74,252,183,184,253,137,183,142, 67,228,217,108, 39,230, 46, 87,182,113,219, 89, 41,160, 98,219,100, 31, 16, 71,245, 66,159,
+113, 85,167,176,106,181,191, 75, 87, 69,110, 50,107,106,123, 79,236,162,243,159,155, 59,169,158,231,195, 7, 1, 83,247,125,213,
+245,174,247, 97,177, 80,150,219, 52,240, 72, 26,183,114,189,168,192,175, 58,223,201, 82,138, 23, 59,213,179, 23,176, 94,114, 75,
+187,226, 45,167, 31,180,220,111,119, 73, 68, 84, 71,183, 90,153, 91,239,184, 71,142,198,155, 39, 91, 45,161,109,180, 69,231, 32,
+ 43,236, 10, 21,238, 95, 49,124,245,207,118,203,204,118,253, 64,243, 13,226, 36, 97,202,121,206, 57,199,152,140,171,149,217, 54,
+188, 91, 25,149,124, 75,210, 35,198,126, 67,137,120, 66,182,216,173,232, 38,123,237,161, 74, 43,220,224,109,215, 29,166,188,145,
+103,101,184,249,195,190,207,226, 72, 99,133,142,112,104, 57, 53,141, 58,107,215, 83, 71,122,250,147, 22,220,185,146, 17, 90, 1,
+239, 93,110,225,143,204, 99,131, 51,123,111,166, 92, 11,129,241, 92,150, 78, 37,201,111,179,134, 88,103,100,113, 24,199, 21,104,
+198,177,216,243,162,165,246,226, 55, 34, 83,206, 41, 78, 91,129, 1,123,126, 2, 84,175,139,166,189, 65,109,230, 21,173,133,236,
+ 60,185, 99, 11,255, 0, 41,161,142,123,169, 77, 45, 0, 84, 80,154,146, 72, 36,186,156,112, 36,224,148, 46,113,120,107, 71,116,
+ 98, 73,204,158,206,178,106, 73,246, 99, 81,123, 50,153, 77,134, 86, 84,161, 90, 31, 29, 62,223, 30, 8, 42, 93,138,133,243, 5,
+230, 58, 4,148,249,128, 80, 44,119,214, 43,189, 55, 83,138,177,237,163, 16,184, 95,249,128, 78,139, 47,135, 51, 52,238, 74,148,
+168, 18, 18,216,173,127,106,174,137, 31,110,163,182,152, 79,136,182, 62, 71, 36, 95,193, 79,223, 11,158, 92,119,129,228,220,157,
+129,113, 70, 21,136,219, 31,159,116,180, 95,174, 55,155,132,148,199,115,202,132,167,246, 37,164, 7, 83, 80, 84, 64,220, 81,180,
+244,238, 40,117,101,219, 92,108,131,220, 70,117,167,197,122, 31,156,247, 24, 30,230,181,207, 29,208,218,245, 82,184,123,215, 70,
+236,158,133,178, 92, 42, 16,200,175,176,175,114,174,115, 26, 68,137,146,110,237,188, 29, 66,158,162,182,209,106,101, 10, 77,104,
+ 65, 74, 72, 30, 32, 30,154,131,220,156, 72, 58,176, 30,197, 89,218,185,198, 9,228, 17,197, 76, 48, 20,199,236, 66, 92,139,132,
+110, 87, 41, 23, 24,236, 72, 95,204,161, 71,203,136,204,230,132,133,168,246,242,216,113, 97,107, 35,182,209,183,220, 15, 74,231,
+ 87, 87,172,133,212, 43,208,123, 53,223,137, 19, 92,122, 21,100,201,120,254,245, 97, 80, 76,163, 42,173, 40,249,173, 72,100,180,
+235,109,168,244, 93, 9, 4, 15, 98,187, 29, 41, 20,209,200, 84,172,243,187, 78, 8, 79,116,177, 75, 83,206,165,230,202,144, 10,
+182, 83,166,244, 47,199,199,199,169,174,156,181,162,149,106, 98,110,200, 36, 56, 21, 11,145,109,130,234, 75, 46, 48, 16,145, 95,
+ 53, 37, 59, 91, 39,218,107,223,235,211,166,135,179, 16, 82, 6,102,203,193, 59, 89, 49,152, 49,214, 31,135, 53,208,165, 15,137,
+128,148, 20, 41, 35,245,104, 82,106, 15,179,238,210,158, 55,137,131,194, 74, 72,139, 69, 90, 81, 54, 52,168, 51,173, 23, 11, 53,
+ 31,102,226, 33,186, 99,249,204,186,150, 28,121,170, 40, 35,204, 82, 66, 72, 52,246,244,240,212,165,157,184, 25, 16, 85, 67,113,
+146, 72, 30, 28, 70, 11,156, 60,246, 26,105,137, 97,177,181,111, 45,109, 33, 36,213,109,184,149, 40,160, 17,244, 40,164,143,118,
+175, 91, 21,173, 30, 42,160,119,189,192, 62, 19, 67,138,163,216,247,166,124,207,147,238,207,187,105,181,201,148,135, 29, 39,113,
+220, 26, 66, 20,105, 64,105, 78,154,213, 25,186, 71, 98,192, 9, 11, 29,255, 0,134,205,189, 74, 94, 65,165, 87, 73,184,147,242,
+183,180,222,108,173, 59,152, 41,184,179, 10, 20,165,197,109, 31, 49, 33,106, 85,104, 10, 65,220,146, 21, 78,227,174,160, 47,185,
+180,180,159, 12,173, 19,105,242,190,212, 48,120,173,169, 70,231,255, 0, 40,252, 34, 91, 21,183, 69,117, 8, 75,104, 78,247,155,
+113,149,184, 59,212, 13,181,234,123, 29, 66,203,206, 87, 12, 21,170,178, 51,203, 61,177,212, 5,131,212,153, 95,252,163,113, 22,
+ 14,229, 38,241, 12, 39,169, 92, 57, 14, 38,167,181, 79, 85,126,128, 61,154,133,155,204, 43,168,142, 2,189,161, 73, 51,202,125,
+166, 97,128, 35,177,197, 70,110,223,150, 60, 11,114, 20,156,123, 55,200,173,146, 27, 74,138, 17, 32,183, 45,162,224,237,184, 41,
+ 41, 85, 43,239,211,113,230, 76,181,164,176,180,143, 88, 74, 59,201,187, 96, 43, 4,242, 52,250,138, 27, 31, 74,188,245,199,139,
+117,232,110, 88,114,168,204,168, 22,144,220,195, 22,122,208,223,141, 30, 66, 27, 4,143, 13,228,104,211,243, 54,223,184,224,240,
+246, 30,202,143,119,193, 37, 7, 37,110,155, 57, 38, 55, 50, 65,218, 65,247,138,123,214,216,217, 78, 79,142, 78,110,215,152, 89,
+231, 89, 39,168, 15, 45,135, 28, 73,109,221,189, 78,210, 14,213,208,119,219, 81,168,217,118,232,110,129,124, 15, 14, 9,251, 47,
+238, 44,136,101,195, 11, 79,181, 26, 49, 60,198, 45,197,104, 72, 90,212,122,127, 89, 66,190,234,128, 62,237, 87, 46,246,211, 17,
+ 86, 11, 93,200, 72, 21,208,226, 12,133,112,174, 49,139, 78, 41, 9, 43, 73, 63, 29, 15,217,227,244,106, 42, 91, 77, 67, 16,141,
+113,120, 28, 41, 85,214, 89,183,196, 92, 56,194,201,146,252,186,100,200,177, 58,212, 39,159, 75, 65,111, 70,106, 89, 5,151, 20,
+160, 66,146,130,186,160,133, 85, 53, 34,130,189,117,165,121, 79, 46,139,167,218,151, 83, 80,168, 21,206,153,128, 50,173, 49,194,
+135, 14,133,230,239, 57,109,152,109, 12,197,181,210,112, 32,101, 90, 12, 78, 24, 87, 14, 35, 28,171, 66,128, 57, 22,103, 47, 33,
+ 74,152,125,192,219, 10, 20, 45,143,102,189, 59,103,183, 54, 12,120,175, 29, 94,223, 58, 92, 10, 29,174,209, 26,132,132,244, 39,
+175, 93, 75,105, 42, 28,189, 32, 93,186, 32, 39,106,133,125,133, 90, 26, 87, 53, 44,105, 23, 22, 86,133,197,125,104, 8, 32,164,
+ 7, 13, 58,123,171,162, 62, 22,188, 80,132,118,204, 89,145, 83,225,144, 93, 36, 90, 28, 66,238,101,167,208,146,144,222,227, 85,
+ 13, 68, 29,189,172,147, 6,224,164,133,251,156,204,241, 65,219,133,153,251,147,203,113,245,169,110, 41, 68,149,169, 93,235,169,
+ 96, 4, 66,129, 71, 23,153, 13, 74,141, 63,140, 54,157,201, 90,106,107, 78,245,215, 74, 26,148,130,199,199, 86, 9, 43,109,119,
+ 59,130, 24,108,245, 83,106,167, 81,246,234, 38,238,242, 70, 96,198,213, 63,130, 22,187,230, 52, 70, 24, 88,175, 21,194,142, 26,
+ 43,140,226,146,158,171, 80, 29, 72,212, 27,205,212,166,164, 21, 42,207, 5,162,149, 85,167,147,113,171, 27,183, 71, 23, 98,109,
+ 42,141, 95,212, 31, 15, 79,187, 83,219,112,120,109, 31,154,141,187,123,107,220, 85,250,243,137,121,180,218,216, 75,128,244, 36,
+116,212,152, 77, 67,148, 34,229,128, 63, 52,150,254, 95,206,220,146, 54,161, 53, 85, 78,184, 92, 25,137, 74, 2, 92,134, 55,174,
+ 33, 0,169,183,162, 41,167, 21,217, 43, 69, 14,140, 37, 14,196, 21,195,130, 28,185,233,234,225,145, 74,249, 27,109,162, 68,215,
+ 86,104, 19, 29,130,225,235,237, 61,134,153,222,110,112,237,236, 47,153,225,160,113, 38,137, 55,188, 55, 18,136, 86, 15,203, 75,
+145, 50,128,153, 9,180,197,181,161,106, 10, 14, 78,112, 37, 64,123,104, 40, 62,253,100,251,255, 0,158, 91, 22,200, 75, 93, 46,
+178, 56, 52, 85, 69, 79,186,195, 14,101, 25,173, 31,148,140,151, 82,219,151,220,226,193, 5,197, 1,189, 6, 67, 1, 73, 62,207,
+137,100,235, 41,220, 63, 84,246, 48, 18, 32,180,149,223,221, 63, 5, 28,237,254, 50,112, 5, 40,187,126, 82,118,160, 54, 65,228,
+ 75, 19,238, 82,161, 63, 53, 28,245,251, 70,162,162,253, 89,194, 49,146,198, 80, 63,178,239,130, 41,230, 6, 55, 54,148, 41,255,
+ 0,254, 87, 95,255, 0,142,136, 63,222,107, 15,201,124, 64,202,243, 26,232,106, 0, 21,243, 54,117, 21,213,131,255, 0,186,157,
+171,192,241, 60, 9, 53,116, 80,252, 42,185,255, 0, 39,183,203, 26,244, 47,156,171,252,199, 39,162, 44, 4, 32,161,165,186,159,
+ 56,142,193, 36,245,251,181,235, 9,225,171, 67, 89,146,153,124,122,128, 3, 36,121,199,231, 64,182, 91, 97, 50,210,208, 67,109,
+ 32, 80, 17, 93,222, 58,115, 16,210, 41, 68,184,143, 72, 69,107, 21,237,135,118,212, 5, 39,223,165,244,162,228,140, 54,107,228,
+100, 37, 9, 66, 82, 59,117,168,215, 52,174, 34, 92, 27,186, 28, 66, 18, 16, 28,220, 0,218, 58,214,186, 26, 23, 42,137,216,221,
+178, 77,195, 98, 91,132,180,182, 79,112,154, 87, 73, 77, 86,140, 18, 79,125, 2,181,248,111, 24, 90,101,219,147, 34,224,181,161,
+250, 2, 27,168,239,250,116,208, 78,241,133, 17,227, 0,182,164,162, 61,151,140, 45, 46, 58, 60,216,158, 99,105, 35,105, 35,184,
+211,157, 68,132,145, 40,138,140, 18,217, 17, 40,110, 37,169,181,142,149,220,128,105,160, 42,115, 69, 37, 19,108,216,148,102,226,
+182, 17, 8, 37, 84,252, 33, 52, 3, 70,162, 45, 84,170,223, 96,126, 19,169,113,155,115,107, 80, 32,213, 73, 26,228,140,214, 40,
+128,126,146,166, 76,201,200, 74,210,220, 72, 12,199, 32, 83,120,106,167, 77, 89,182,179, 50, 73, 75,182,241,205,201, 74,237,242,
+243, 22, 10,119,203, 90,118,157,192,132, 80,143,119,125, 42, 44, 34,232, 92,250,199,214,181, 82,103, 57, 7, 34,109,147,111,117,
+107,124,169, 59, 74,148,157,195, 73, 29,182, 42,228,151, 27,156,128, 81, 70, 35,205,188, 77,184, 33, 47,148,150,212,177, 68,121,
+ 91, 7, 95,175, 75, 11,118,197,136, 72,153,221, 41,197, 92,252, 43, 0,198,110, 22, 54, 38, 94,140, 40,206,121, 97,101,107,113,
+ 40, 52, 3,185,213,106,238,226, 77, 68, 54,180, 86,139, 59, 88,156,193,170,149, 92, 14,245, 69, 2,205,146,122,129,230, 73,216,
+203,209,101,218, 24,151, 18,193, 29,248,128,186,212,199, 45, 49, 90,105,241,240,143,139,107,129, 72, 80, 39,218, 41,216,235, 4,
+231,125,203,253,221, 56,133,238,207, 41,182, 83,111,178, 68, 28, 41, 90,154,117, 18, 72, 67,159, 78, 88,229,210,221,201,150,211,
+113, 68,212,162, 75, 55, 71, 99,137,110,134,193,113,168, 82,118, 81,148,138,162,132,138, 29,234,233, 65,210,154,161, 75,116,203,
+151,128,218, 97,241, 28,127, 98,212, 91,102,251,104,164,113,175,202,125, 40,190,155,125, 2, 71,143,111,226, 27, 81,109, 33, 46,
+ 75,185,222, 38, 63, 95,196, 94,145, 41,226,107,227,238,212, 22,234,253,119,143,175, 10, 15, 96, 11,196,222, 98,184,186,254, 95,
+ 87,216, 23, 89,177, 41,105,242,155, 21,240, 30, 58,209, 57,102, 64,208, 22, 47,123,153, 83, 12,198,193, 27, 57,193,179, 12, 42,
+ 92,135, 34,197,204, 49, 92,135, 22,147, 37,159,222,199,143,127,136,244, 69,173, 52, 32,213, 9,120,145,215, 90,171, 7,212,192,
+248,255, 0,121,164,123, 69, 20, 75,241, 95, 49, 92,159,101,226,233,156,101,118,244,179,234,199, 12,121,121, 14, 3,145,218, 47,
+141,219,110, 55,169, 88,100,149,228, 56,210,164,196,143,115,180,220,139,155,231, 67,188, 91,221, 82, 1, 65, 41, 45,184, 72,216,
+234, 66,135,137,222,238,101,242,167,120,184,250, 72, 75,237,229,113,208,224,221, 69,160,226, 65, 26, 72, 2,167, 42, 82,173, 4,
+ 40, 3, 4,194, 67, 79,148,145,219, 95,130,188, 30,128,253, 50, 71,135,157,216,121,192, 99,115, 48,174, 41,227,188, 85,171, 7,
+ 11, 98,147,226,189, 5,119, 41,210,162, 61, 17, 87, 52, 55, 35,107,174,199,143, 10, 83,201, 68,151, 81,189,247, 92, 46, 5, 20,
+160, 87,109,242,167,100,220,102,146, 77,227,120, 97,108,238, 39, 77,105, 83,171, 50,125,153,101,208, 51, 82,182, 97,205, 20,112,
+161, 7,218,186,115,159,102, 40,140,195,191,181, 3,161,253, 97,173, 39,121,190,173, 84,180, 12,212, 87, 47,249,199,148,224,192,
+ 76,231, 36,204,105,148, 54,151, 20,165, 45,208,144, 0,250,252, 53,156, 93, 48,220,186,129, 91,118,200, 42, 66,227,213,226,237,
+ 63,213,214,107,254, 29,227, 74,113, 56, 12, 43,136, 25, 70, 68,219,136,111,248,151,144,176, 76,104,101,207,132,212,167,171,135,
+167,128,246,234,106,215,109, 27,115,117,201,243, 17,151, 71,106,215, 54, 75, 83,181,134,221, 63, 7, 15,148,125,235,191,158,148,
+125, 50,241, 63, 13, 98, 54,212,216,236,208,190,116,199,108,252,205,193,108, 92,110,239,184,154, 19,188,173, 45,167,184,173, 18,
+131, 79,187, 70,133,226, 67,169,228,118, 97,247,170,206,255, 0,189,220, 95,188,130,227, 79, 88, 10,123,234, 66,233,183, 13,184,
+150,173,233,138, 99,176,164,165, 42,109, 8, 75,221, 63, 18, 74, 11,109,212,142,255, 0,163,199, 85,206,105,154,177,147, 74, 80,
+122,116, 41,255, 0, 46, 33,215,124,198,147, 90,159, 78,149,197, 7,231, 77,254, 48,249,114,228,166, 80,167, 22,130,162,225, 14,
+121,110,254, 29,165, 65,205,244,247, 1,211,173,125,152,109,220,218,170, 64, 94,247,219, 45, 67, 34, 0, 10,224,135, 60,150,203,
+119, 54,210, 93, 90,222,156,194, 23,189,126, 74,158, 19, 16,232,216, 20,149,144, 2,141, 13, 84,154, 10,126,146,217,220, 81, 72,
+253, 17,118, 67, 5, 86,167,218, 11, 65,253,237,160,109, 74,130, 93, 85, 8, 9, 30,206,190, 35,221,171, 4, 87, 41,180,246, 0,
+228, 49, 66,155,173,133, 82,222, 87,151, 17,110, 41, 9, 82,193, 36, 54,146,175,105,168,248,190,138,125,218,146,183,189,224, 83,
+119,237, 69,152,168, 67,105,149, 29,229,178,166,220, 14,249,129, 45,182,132,133, 41, 84,237,184,244,219, 79,102,221, 75,199,162,
+ 76,147, 57, 26,232, 43, 92, 66, 51, 98,188, 91,123,207, 33, 59,229, 54,228,105, 77,163,246, 59, 16,230,226,180,138,142,131,111,
+179,217,169,189,189,134, 18, 15, 5, 64,230, 61,218, 54,130,210,169,183, 45,112,222, 70,239, 35, 90, 45,121, 52, 67, 6, 59,178,
+214, 28,146,182, 76,102, 37,173,163, 77,195,122,148,147, 80, 79, 99,222,167,199,166,131, 97, 43, 91, 17, 44,205, 82,109, 67, 46,
+101, 26,221,221, 24,171,239,196, 12,240,119, 24, 90,162,219,165,202,178,174, 96, 66, 12,169,178,166, 34, 53,174, 58,148, 63, 8,
+ 34,138,121, 67,198,166,159, 70,146,150, 9,231,117, 72, 42,206,203,248,173,197, 24, 64, 30,170,159,130,189, 56, 95, 53,250, 98,
+105,152,172, 73,228, 76,113,167,170,133, 42, 36, 41, 49,152,104, 0, 1,254,178,138,136, 53,238,170,253, 26,110,251, 41, 27,155,
+ 74, 64,110,147, 74, 79,133,164,246,186,191,122,180,184,231, 38,122,122,144,219, 74,182,231, 54, 9, 42,216,130,226,100,184,194,
+247, 5, 84, 0,149,109, 66,137, 20, 21, 63,209, 77, 48,158, 48,204,194, 59, 78,225,113,255, 0, 76,250,137,248,149, 35,189,185,
+130, 94,226,137,150, 57,182, 41,173,148, 23, 43, 14, 75, 37, 97, 74, 29, 14,212,149,111,173, 8, 62, 35,167, 77, 46, 33,134,118,
+212,129, 84,255, 0,111,185,185,182,118,137, 67,135,109,125, 2, 14,221,120,214,201,122,138,227,137,134,219,165, 97, 64,144,132,
+ 7, 21,215,184,232, 43,227,227,168,233,172, 33, 39, 0, 21,218,223,123,116, 36, 2, 80, 74,245,193,165, 74,125, 49, 88,113,224,
+ 83,181, 12,175,106, 84, 8, 29, 64, 42,234,126,189, 49,151,101,109,206, 65, 78, 13,253,142,104, 46, 33, 80, 47, 80,222,159,216,
+185, 65,122, 37,210,208,227, 43,109, 46, 41,185, 13, 39,203,151, 26,163,241, 33,104,162,146, 71,114, 43,215,161,165, 53,200,236,
+102,217,143,137, 17,237, 25,132,218,238, 43,125,241,154, 29,143, 88,192,250,138,162, 56,118, 53,124,198,238, 18, 44, 87, 71, 36,
+205, 97,149,147,108,190, 45, 8,136,169, 44,130, 54,182,226, 82,225, 59,197,105, 94,149,250,244,250,230,120, 55, 6,120,177,138,
+ 59,241, 55,225,212,168,198,198,227,102,121,138, 83,169,159,133,216, 99,219,142,106,226,113,146,158, 76,134, 74, 22,181,121,107,
+ 27,130,154, 53, 77, 61,229, 74,212, 73,131, 87, 4,218,234,235, 71, 21,214, 62, 21,200,163, 63, 96,184,227,215, 37, 7,109,247,
+ 56, 5,137, 13, 44,213, 41, 4, 84, 42,159,111,252,134,167,121, 82,213,209,110, 48,185,184, 29, 65,103, 60,241, 59,100,219,174,
+ 75,133, 71,134,234,245,138, 34,202,189, 53, 91, 47,204,162,109,146,232, 2, 86,144,189,129, 64,144, 15,133, 53,234, 59,125,193,
+236, 20,112,197,120,138,125,181,178,226,215, 96,160, 89,159, 1,220,113, 72, 66, 80,117,217,136,236,164,161, 27,191, 70,165, 45,
+111, 68,230,132, 81, 67, 93,216,155,113, 80,106,130, 82, 49, 80, 9,171, 78, 33, 64,144,106, 40, 71,223,167,228, 40,218,164, 98,
+200,168,228,116, 89, 30,255, 0, 13, 16,133,221, 73, 91, 54,136,239, 44, 7,151,229,164,143,197,227,164,159, 80, 48, 74, 48,130,
+113, 77, 83,108,225,167, 84, 35, 56,165,164, 86,138, 31,229,208, 96, 46, 24,132, 30,224,211,129, 76,206,219, 86,144,119,182, 73,
+175,122,117,209,139, 87, 3,211, 76,139, 67,146,123, 37,105, 3,196,116, 63,209,162,232, 1, 27,196, 37, 72, 45, 24,109,132,198,
+ 50,110,243,157, 71, 79,221, 37,116, 63,167, 81,119, 82,202,215,105, 99, 84,141,187, 35,112,171,220,145, 61,140,217,228,124,195,
+ 80,252,197, 70, 77,118, 43, 97, 89,208, 46,123, 40, 93,154,232, 13,121, 32,100,161,208,240,200, 14, 93,219, 69,209,167, 5,188,
+ 47,170,202, 41, 81,244,233,119,200, 92,206,238,105, 54, 0, 29,222,201, 20,101,113,239, 25,184,202, 28,129, 47,229, 37, 37, 35,
+226, 88, 73, 27,190,209,168,151,153,206, 98,161, 74, 55,193,224, 80, 27, 60,193,173,162, 64, 49,231, 55, 53, 85, 20, 82, 16, 58,
+125,250,123,101,168, 10, 17, 68,206,228,138,224,106,153, 45,119, 11,254, 19, 24,255, 0, 5,141, 4, 58,170,159,152,122, 63,152,
+180,159,112,213,119,126,229, 11,126,100, 52,184, 46,211,208, 13, 20,117,204, 2,227, 50,155,174, 92,131,201, 23,144,160,246, 69,
+ 57,128, 42, 60,184,202,242, 27, 77,124, 2, 71, 77, 65, 91,121, 77,177,218, 98, 45,154,227,210,113, 76,219,182, 66, 63, 10,135,
+185,114,203,220, 37, 79,100, 55, 69, 30,191,249,201, 26,151,103, 34,109, 49,124,182,177,251, 18,237,179,137,185, 52, 38,225,114,
+202, 82,225, 82, 47,183, 77,224, 83,172,130,127, 79, 77,114, 78, 69,218,165, 20,117,172,116,254,202,233,179,137,217,180, 36,223,
+ 61,150,121,222,111,241,139,158,253,219,183,121,189, 55,123,125,154,105,255, 0,142, 54,106,215,233, 99,246, 38,223,201,109,181,
+107,208, 42,190, 75,160, 58,227,202,163,160,169,117,241, 26,213,218, 0,192, 39,163, 5, 58,182,165,244,169, 38,139,160,165, 1,
+237,163,210,136, 34,221,141, 50,148,200, 90, 85,176, 39,175, 94,244,210,111,117, 16,211,169, 19,172, 74,154,242,155, 66,106, 6,
+224, 10,180,179, 91, 64,147, 56, 43, 85,128,227,238, 44,176,243,160,184, 72, 73,234, 9,235,160, 82, 78,122,185, 56,125,185, 72,
+ 75, 65, 49,169, 77,189,118,105, 23, 53, 36, 93, 85,102,113,136,146, 84, 26,108,160, 33,181, 20,133, 18, 59, 13, 34,230, 85,112,
+ 62,138,225, 98,120, 38, 31, 38,214,211,239,221, 80,220,191, 46,170,105, 68,143,139,237,212, 84,179, 78,215, 80, 12, 20,156, 80,
+ 66,246,212,187, 20,156,227,109,162,106,219,142,180, 45,148,146, 18,160, 59,141, 74, 66, 73,110, 42, 50, 80, 26,104, 50, 83,251,
+ 94, 62, 54, 32, 81, 30, 30, 20,254,157, 44,147, 83, 72,248,170, 22, 18,105,214,181,232, 58, 29,117, 10, 85, 73, 35,227,141,164,
+ 38,141, 38,163,167,109, 25,116, 4,228,187, 22,230,202, 82, 18, 21, 74, 87,110,184, 87, 67,106,144, 70,198, 20,202,156,113,244,
+ 50,170,212,238, 82, 7, 65,164, 92,250, 35, 50, 50, 84, 91, 36,201,120,255, 0, 13,109,115,178, 76,130,207,109, 67, 8, 82,212,
+149,188,146,245, 19,215,162, 18, 74,143,217,168,203,205,210, 27, 65, 89, 30, 2,179,109, 28,171,127,189, 58,150,208,185,221,116,
+160,246,156, 23, 60,253, 68,122,220,145,119,182,204,195,120,110,225, 53,180, 60,219,177,101,228,100,185, 21, 13,180,224, 41, 82,
+ 25, 20, 10,169, 31,173, 74,107, 53,223,249,214, 38,180,178, 10,246,252, 23,164, 57, 3,201, 41, 98,123,110, 55, 45, 38,152,134,
+ 3, 81,235, 52,167,169, 4, 56, 95, 30,151, 31, 30, 84,187,138, 60,215,230,111,113,114,228, 81, 78,190,226,201, 82,138, 65, 94,
+245, 18,163,226, 69, 61,250,243,103, 51,110,127, 83, 41, 32,175,100,236,219,104,181,141,172,166, 1, 18,176,235,107,144, 57, 95,
+ 18,155,229,186,150, 4,199,216,113,215,119, 20,132, 75,101,198,199,128, 77, 20,165, 14,195,237,212, 54,213,115,223,161, 83, 87,
+150,190, 44, 79, 3,247, 79,167,185,118,215,209, 70,111, 22, 22, 37, 39, 30,147, 33,182,102, 90, 47,151, 72,206,178,163, 69, 36,
+ 41,229,168,116, 38,189,142,157,239, 17, 22, 92, 23,140,136, 7,220, 23,132, 60,203,219,221, 29,244,132,140,233,246, 83,237, 5,
+117,103, 15,203, 24, 33,180,249,232,236, 60,127,207,171, 30,197,122, 34, 32, 21,134, 95,219,144, 74, 55, 66,201, 35,150,193, 47,
+ 39,183,183,252,250,213,118,253,204, 83, 53, 4,248,202,103,190, 93,241,249,170, 97,219,140, 59, 84,231, 97,175,205,136,236,232,
+109, 75,114, 43,131,174,230,212,226, 84, 91, 62,244,234, 81,247,177,191, 23, 0, 74, 79,194, 37, 12, 50,238, 77,182, 91,163,188,
+183,238, 44,182,148, 5, 84,151, 0,160, 31, 94,163,110,247, 76, 48, 78,162,128,149,203,239, 81,254,178, 48,252, 69, 11,132,205,
+225, 19,110,210, 10,218,135,108,131, 89,115,165, 60, 63, 85,182,155,220,181,159,160,106,183, 59, 29,113,222,121,210,222,147,130,
+182,108, 92,187,117,188,201,225,218,196,233, 29,208,209, 90,118,156,128,235, 52, 11,133,252,223,200, 92,183,206,249,155, 88, 74,
+ 28,119, 29,182,220, 11, 78, 94, 98, 25, 69, 19,216,128,242,170,150,164,121, 69, 69,149, 60,142,165,160,119, 4,245, 85, 43, 77,
+ 58,177,100, 80,180,189,130,189,100,103,216,182,139, 62, 70, 28,186,214,186,240,131, 45, 43,160, 26,134,255, 0,104,241, 61, 89,
+ 14,181,214,255, 0, 73,124, 69, 27,142,177,107, 84, 24,214,232, 12, 53, 29,150, 2, 84,139,115,106, 66,148, 0,170,183, 58, 74,
+201, 39,173, 74, 70,160,183, 27,191, 17,217,162, 95,202,100,192,174,163, 89, 50,102, 45,118,228, 7,229,132,178,148, 13,201,117,
+ 72, 40, 77, 58,211,106, 10, 82, 15, 79,102,162,141,217, 98,171,187,110, 55, 14,192, 98,135,188,175,159, 66,200, 49,121,214,232,
+117,156,135,227,173,166,212,220,127,152, 64,119,160, 9, 59, 0,167, 90,116, 35, 80,219,181,215,213,176,180,171,167, 39,236,178,
+ 88, 93,178, 67,133, 13,115,162,228,117,219, 30,189, 92, 46,114,201,185,166,217, 45, 14,148, 38, 57, 11, 62,106, 10,141, 82,177,
+ 84,213, 59,123,164,142,253, 40,123,140,186,226,199, 73, 43,219,219, 85,227,124, 38,144,194,225, 76,211, 29,199,141, 50, 21, 70,
+ 83,174,161,169, 96, 21, 17, 37,176,160,133, 56,210, 84,165, 21,110,160, 27, 18, 1, 59,135,106,117,233,168, 73, 88,232, 93, 64,
+ 21,174,219,112,129,227, 28, 58,189, 58,208, 11, 35,179, 60,236,131, 29, 81,136, 81,117, 97,215,147, 69,165,107,253, 98, 77, 9,
+ 85, 61,195,166,158, 70,100, 41,249,142, 22, 10,212, 33, 61,243, 20,148,135, 84,152,238,149,182,173,159,136, 4, 37, 97, 67,194,
+167,174,165,109,228, 45,205, 68,220,185,142, 28, 20,203,141,248, 2,251,158, 79,142,204, 59, 99,135,115,137, 14,203, 83, 74, 44,
+128, 79, 94,167,225, 87,212, 78,172, 54, 58,230, 52, 25, 44,231,154, 57,130,223,103,140,186, 71, 10,244, 46,213,240, 39,164,251,
+118, 49,103,138,197,217,167,155, 47, 33, 41, 88,134,135, 27, 66,148, 69, 10,150, 85,176,215,218, 41,245,235, 67,219,109,244,128,
+ 10,241,239, 56,115,179,183, 25, 73,136,229,210,161,126,171,255, 0, 45,171,134, 93,139,221, 50, 76, 73,152, 55,149, 6, 28,150,
+184,229,135, 35, 93,142,212,244,216,178,133, 37, 91, 7, 98,181,144, 7,134,172,140,183,146,206,146, 10,233, 77,185,123,158, 26,
+231, 8,167,192,229, 94, 11,134,124, 53,233, 75,211,203, 28,163,114,193, 57,251, 4,149, 43, 55,114,107,174,219, 37,102,247, 41,
+119,171, 13,209,141,221, 27,102, 50,221, 16, 88, 40, 29, 2, 67, 61, 71, 93,199, 87, 75,109,230, 87,196, 60, 50, 48,232, 2,170,
+ 31,158, 44, 46, 99, 63, 83, 12,142, 49,158,179,135,167,160, 86, 11,243, 22,252,190,184, 71, 24,244,169,111,228,206, 27,225,220,
+ 2,205,112,192, 51,123, 13,211, 49,149,136,226,112,108,247, 89, 56, 77,201,167,225,188,183, 94,139, 20, 60,243,108, 76,122, 50,
+148, 20,170, 1, 85,146, 2,107,163, 77,185, 78,248,234, 30,106,163,188,176,220,162,126,232, 33,190, 58,152,246,144, 3,142, 26,
+129, 7,136, 56,145, 84, 31,244,185,149,254, 92, 30,159,120,230,229,151,250,152,244,177,118,231, 12,122,255, 0, 99,177, 70,184,
+ 51,193,119,235,134, 67,201,216, 21,234,216,228,167, 12,199,225,255, 0,122,237,104, 98, 60,214, 22,132,200,114, 36,244, 45, 42,
+ 74, 2,163,237, 81, 41, 75,149,183,184,110,174, 31, 5,248, 14, 4, 97,172, 1, 66, 15, 12, 6,125,103,130,216,188,195,229,189,
+214,194, 1,113,177,190, 88,200,125, 70,154,144,230,144, 48, 28,106,211,141, 52,241, 56,174,120,103, 94,162,239,158,168,125, 89,
+217,241, 79,203, 79,134,249,183,211,103, 13,155, 92, 75,114,241,156,239,145,174,220,153,120,121,248, 79,201, 84,155,244,215, 50,
+ 11,165,197,187,122, 92,141,229,131, 1,169,238, 37, 42, 66,200,117, 91,168,153,174,100,219,246,107, 56,204,174,107, 27,208, 1,
+161, 39,213,138,135,228,126,104,230,119,157, 55, 51, 74,230,180,247,228,123, 6,150,131,144,239, 0, 9,174, 67, 2,125, 74,222,
+122,114,230, 47, 94,153, 79, 55, 89,120, 3, 28,184,226, 92,147,145, 92,156,200,196,117,100, 12,202,195, 86,182,241, 88,114,102,
+190, 95, 88,102, 98, 27,243, 90,138,164,180,189,133, 5, 69, 63, 24, 6,162,133, 6,221,103,126, 9,136,189,135,172,135, 15,184,
+173, 91,152,249,210,227,147,160, 23, 55,237,138, 88,240,174,144, 88,241, 82, 0,192,212, 28,215, 68,238,190,160,185, 27,136,158,
+ 22,207, 83,188, 69,157,240,226,188,228, 70, 86, 91, 62, 3,119,174, 63,117,245,168, 37, 63,250,118,212,236,187, 91, 94,101,126,
+ 4, 72,113,181, 17,250,181, 4, 4, 37,218,103,136,254, 81,107,250,129,199,216,104,125,137,190,199,230,174,203,190,144,216,229,
+208,227,248, 95,135,191, 36,167, 40,203,113,190, 66,181,181,113,180,221,109,153, 45,182, 75, 91,155,145,111,117, 15,189,177, 97,
+ 32, 42,137, 86,215, 5, 59,208,233,137,148,154,178, 70,144,122, 10,213,182,171,182, 17,170, 51,135,110, 30,162,185,161,201,246,
+246,176,188,213, 40, 0, 42, 12,181, 38,100, 39,210, 2, 27, 41, 87,113, 66, 64,220,147,208,129,170,109,245,191,210, 74, 94,223,
+148,171,108,237, 27,148, 26, 78,106, 95,130,223,226,200,117,199,235,181,194,165, 44, 46, 67,197,245, 19,222,181, 20, 31,102,165,
+182,246,137,133, 66,197,185,154,218, 75, 7,233, 56, 43,161,193,151,185,185, 13,250, 69,166,222, 20,228,134,217,113,149, 4, 18,
+180,124, 98,163,168, 52,233, 67, 79,171,182,175,252,177,100,223,172,137,196,100,107,236, 89, 79, 58, 92, 62, 13,170,224,244,176,
+180,122,240,251, 74,234,207, 22, 88,165,216, 98, 52,237,198, 83,161,213,160, 85,149, 40,144,154,235,108,154, 95, 28,247, 87,148,
+173,161, 48, 12, 81,106,237, 46,196, 98,171,248,146,227,169,130, 14,224,253, 41,215,233,209, 90,210,220,146,143,112,167,123, 37,
+ 84,185, 35, 21,199,101, 37,219,157,138, 84, 17, 64,165, 56,210, 28, 2,132,123,171,169, 11,107,194,211,165,224,168, 75,219, 54,
+187,190,194, 21, 98,149, 46, 35,107,113,181, 41, 59,146, 74, 79, 94,157, 53, 45,158, 42, 14,180,193, 53, 42, 76, 18, 73, 43, 79,
+219,174, 82,171,154,151,164,174, 59,221, 26, 1,116,254,168,174,142,216,203,184, 20,155,167,107,112, 36, 47, 37,150, 73,162,146,
+ 1,254,170,133, 63, 78,138, 90, 66, 80, 60, 59, 37,225, 80, 90,113, 63, 8, 72,175,176,104,180, 70, 5, 54,201,179, 41, 64,144,
+144,160,124, 41,162,209, 26,169,101,138, 21,194, 58,156,249,118,152,218,132,147, 71,147,222,154, 97,123, 27, 31,131,170,158,218,
+ 74,230,229, 68,177, 89, 50, 27,124, 51,115,181,198,113,164,168,165, 69, 13,138,138,125,250,100,237,173,192, 86, 55, 20,245,155,
+147, 73,163,218, 18, 75,250,241,187,196, 84,162,217, 0, 51, 40,247, 52,160,169,209,109,227,154, 3,249,135, 4,121,229,134,113,
+220, 24,160,237,210,214,236, 55,138, 20,210, 87,215,184, 21,166,165, 88,225, 32,168, 81,206, 5,134,133, 71, 31,138,149, 31,219,
+ 36, 37, 29,126, 18, 61,186, 49, 98, 46,164,255, 0,110,227,216,247,120,226, 67, 50,162, 48, 85,250,171, 80, 73, 63,126,152,207,
+114, 33, 52, 32,167,113, 65,226,140, 10,104,190,113,155,214,134,139,238,187, 25,214,213,217, 77,184, 9,251,142,132, 87, 13,155,
+ 37,201, 33, 49,102,160, 18, 49,132, 44, 18,128, 1, 21,234, 6,156,233, 73,130,154,191,187,242,235,229,126,174,234,238,167,134,
+134,144,187, 85,242,199,106,226,137,161,228, 56,164,154, 40,130, 7, 93, 74, 7, 98,144,200, 35, 29,163,138, 29, 82, 18, 92,104,
+208, 0, 65,210,196,162,106,162,127,255, 0, 14,229,182,180, 53, 21, 10, 82,137, 3,104,169,215,106,185,169, 28,177, 14, 32,187,
+162, 35, 83, 31,138,233, 72, 41, 81, 1, 39,182,186,194, 30,234, 85, 54,158, 95, 13,164,174,141,240, 79, 30, 97,114, 45, 78,202,
+190,182,180,152,113, 86,226,194,147,213, 42, 64,246, 18, 53, 55, 30,220,202, 98, 85, 54,235,123,151, 85, 26, 20,215, 23,132,197,
+214,229, 52, 90,162, 45,187,123, 18, 10, 25, 82,197, 55, 36, 19,219, 80,151,172, 16, 62,129, 88,236,165,116,241,135, 59, 53,101,
+241,204,101,229, 33,164,161, 33, 42, 20,173,116,193,210, 81, 58,162, 41, 64,176, 57, 27,111,154,232, 6,131,162, 85,160, 36, 5,
+ 0, 20,202, 11, 62, 73, 6,169, 35,218, 85, 74,107,190, 32, 70, 12, 39, 37, 52,133, 58, 19, 91,124,249,240,227,211,169, 47, 73,
+ 66, 40, 7,210, 70,184,102, 1, 42,219,103,191, 38,148,252,222, 95,140, 69, 0,189,148, 89, 27, 74,122, 26,220, 27,232,126,165,
+104,134,237,131, 50, 19,184,246,155,153, 62, 88,220,125, 69,111, 95, 44,241,204, 1,254,251,154, 88, 89, 32, 86,142,207, 67,100,
+143,111,196, 70,145,118,229, 19, 51,120,246,169, 24,121, 98,254,127,150, 7,158,192, 74,136,223,189, 80,240,230, 60,202,222,145,
+152, 88,223, 74, 82,162,147, 30,234,195,197, 91,125,129, 46, 18,116,198,125,246, 8,133,117, 15,106,176,109,254, 93,110,119,164,
+ 15, 5,205,237, 4,125,170,162,114,103,230, 11,139,166, 44,155,126, 23, 29,119, 9, 14, 5, 54,219,197, 41, 13, 40,158,157, 20,
+ 36, 36,143,171, 85, 13,211,156, 90,192, 67, 2,215,249, 99,201, 55,234,107,238,156, 59, 1,248,174,118,101,217,142, 79,203,119,
+ 69, 77,200, 46, 10,105,133, 56, 84,136,109,201,113,214,144, 20,107,213, 30, 99,180,250,117,148,239, 28,204,249, 73, 53,244,245,
+175, 77,114,239, 39, 65,182, 52, 49,128, 10,122,112, 82,220,119, 5,179, 50,211, 40, 90,156,146,229, 80, 67, 44,161,100, 45, 71,
+181,118,165, 39,237, 80,214,105,184,239, 79,144,149,168,109,251, 75, 34, 3,225,241, 86,243, 3,196,165, 34, 52,121,110, 63,229,
+ 52,219, 84, 75,106, 65, 64, 66, 19,217, 32, 26, 83,233,173,125,231,174,169, 27,141,239, 74,154,142, 33, 90, 4,245, 38, 40,143,
+120,143, 47,114, 55,198,121,183,155,117, 85, 4, 56,218,129, 73, 0, 14,189,123,234, 55,111,190,209, 40, 37, 77, 27, 90, 71,128,
+ 71,156, 78,233,122,146,239,247,167,141,239, 80,237, 87,151,220,255, 0,210,182,203,128, 90,225, 73,150,223, 69, 21,108, 90, 20,
+ 9, 35,161, 7, 90,173,171, 25,121, 16,212, 42,176,126,114,228,171, 93,226, 66,219,154,181,220, 28, 51,254,142,175,101, 21,154,
+199, 57,247,212,118, 60,210, 21, 59, 5,179,221,144,215, 64,253,159, 39, 4,190,145,216,134,159,105, 5, 53,246,111, 63, 78,156,
+ 65,182,177,134,184,133,136,110,158, 73,178,115,249, 23, 67,177,205, 35,222, 9,251, 17, 69,175, 89, 28,206,136,161, 63,225, 77,
+201,165,254, 16,183,175,176,219,110,191, 72,125, 71,238,212,196, 51, 54, 14, 46,246, 42,203,188,129,188,115,191,238, 33,167,247,
+191,133, 64, 50,111, 85,254,160,102, 33, 73, 99, 28,197,172,137,112, 80, 59,117,203, 75,142, 53, 95, 31, 41,136,235,173, 7,134,
+241,167,127,204,157,248, 98,121,245,128,164,109, 63, 79,162,191,238, 47,154, 7, 16,214, 18,125,165,193, 84,126, 70,229,174, 78,
+191,249,168,204,121,126, 5,178,218,238,224,244, 76, 50, 2,227, 74, 41, 87,226, 65,147, 53,199,118,244,233,185, 8, 7, 93, 6,
+250,224,209,141, 99, 7, 78, 46, 62,252, 21,223,106,242,127,151,182,170, 62,111, 26,119, 14, 14, 33,173,246, 55, 26,117, 18,168,
+238, 71,207, 92, 99,129,207,157,103,192, 19, 55, 50,207, 46,111,124,172,155,187,175,174,235, 42, 33, 32,146,101,221, 93, 10, 67,
+ 97, 29, 74,155,100,149,142,219, 64,234, 29,218,236, 71, 81,146,229,229,206,235,251,135, 5,115,185,221,173,246,152, 68, 54, 80,
+182, 54, 14, 12, 20, 21,235, 60, 79,180,162,127,165,188, 70, 77,207, 49, 93,246,250,243,179, 46,119, 41,138,157, 46, 82,144, 10,
+150,242,190, 37,165,180,149,149, 54,148, 10, 37, 32, 18, 0,167,115,212,175,184, 78, 24,221, 45,202,139, 50,220,164,117,203,139,
+221,153, 43,188,214, 5, 64,176, 90,227,198,135, 21,200,175,199,142,195,142,133,188,151, 74,119,164, 20,213, 65, 32,168,170,163,
+165, 43,238,213, 34,105,241,169, 85,118,218, 58,233,216,156,207, 66,154, 64,195,167,228,182, 41,217, 86, 81, 44,163, 27,128, 12,
+150, 96,197, 73, 50, 37, 33,130,119, 37,107, 27, 66,119,154, 1,227, 74,159,102,152,198, 13,243,180,183, 37, 53,108,230, 88,204,
+219,120,135,230,187, 2, 78, 66,188,105,212,171,213,243,145,163,100,174,166,201, 22,114, 45, 54,102, 20,234, 90,180, 91, 28, 76,
+ 70,146,148, 2, 42,234,211,241,186, 86,165, 81, 64,154,123, 6,173, 49,114,224, 0, 23, 45,171, 97,229,235,125,180,137, 40, 31,
+ 41,205,206,199,216, 50, 20,225,197, 62,225,248,206, 56,245,198, 12, 41, 54,152,174, 60,235,107, 83, 41, 91,129,223, 49,134, 6,
+234,149,138,126, 34,122,125, 94,205, 47,255, 0, 28,182,120,239, 52, 31, 82,181, 94,110,179,193, 19,158,199,144, 7, 71, 79, 98,
+176,105,227, 44, 38,241,104, 49,157,182,182,195,210, 25, 86,246, 99, 60,166,145, 25,195,208, 40,144, 71,196, 71, 67,166,242,242,
+ 69,149,201,249, 64, 85, 47,249,117,253,156,186,131,234,208,120,138,147,251, 21, 21,229, 79, 79, 80,161, 75,126, 85,150, 84,136,
+141,161,247,246,121,159,181, 5, 45,170,171, 40, 29, 65,169, 29,245, 21,115,200, 48, 52,126, 89,167,189,106,219, 79, 57, 13,194,
+ 48, 38,104, 38,131, 36, 4,183,241,201,129,114,143,253,226,143,243,112, 20,243,101, 82,226, 50, 74,146,133, 31,196,164,133, 10,
+128, 0,174,223,167,169,213, 62,243,150, 37,178, 53, 34,161, 45,186,203,245, 17, 56,218,186,142,166, 68,253,135,226,186, 95,194,
+ 82, 48,251, 29,190, 52, 40,150,166, 88,101, 97, 63, 45, 50, 43, 4, 50,240, 72, 31, 18, 93, 8, 5, 68,215,168,239,220, 30,218,
+117,182,200,200,176,162,242, 79, 61, 88, 94, 92,200,227, 35,141,120,130,113, 30,170,171,143, 26,235, 1, 1,146,133, 23, 71,192,
+ 64, 74, 18, 40, 13, 58, 84,130, 70,174,118,247, 0,128,177,137,108,220,210, 65, 86,139, 20,186, 68,185, 90,227,195,184, 50, 82,
+210,144, 2, 81,231,121,110, 20,145, 74,237,168, 74,133, 15,106,106,247,181,221, 71, 51, 4,114,142,239,109, 15,192,170,213,220,
+ 15,137,218,163, 56,174, 64,126,102, 95,151,159,248,133,106,111,153, 56, 93,167,198, 83, 98,116, 74,188,218, 97,167,202,152, 26,
+104, 21,166, 92, 96,144, 11,133,146,154,169, 41, 53, 9,169, 2,128,233, 75,171, 38,237, 63,157,110,237, 81,241, 4, 80,183,226,
+ 62,206,142,141, 3,147,249,164, 95, 3, 97,126, 0,168,238,158, 7,168,244, 30,138,252, 23, 51,184, 75,214,180, 60,118, 4,238,
+ 43,245, 3, 98, 49,218, 13,202,195,242, 49,125,135,243,120,205,250, 36,166,252,135, 99,201, 82,129,105,191,152,105,116, 45,189,
+ 64,160,161,180,170,181,210,240,220,195,114, 64,107,128, 36,100,120,246,124, 51, 81,188,195,229,253,246,210, 77,229,163, 75,225,
+105,174,166,252,204, 35, 28, 64,199, 12,234, 48,226,104,130,247,159, 65, 87, 43, 30, 86,255, 0, 32,250, 44,229, 60, 86,231,142,
+ 92,156,117,197,241, 55, 34,202, 76, 27,141,166, 13,193,196, 56,244, 56, 55, 50,135, 97,220, 89, 9, 73, 67, 40,154,150,138, 1,
+234,183, 20, 84,163, 9,186,236, 45,184, 6,149, 14,244,162,209,185, 59,207, 79,165, 99, 45,183,104,203,163,105,249,154, 61, 85,
+160,161, 6,157, 21,199,161, 58, 98,254,155,125,127, 94,111,147, 24, 87, 15,217,177,228,189, 50,224,194,174,204,114, 6, 47,101,
+181,170,215,122,119,230, 28,253,180, 11,155,175, 31,148,148, 80,236,112,150,149,183,101, 2, 72, 37, 38,175, 47, 44,220,205, 70,
+185,216,103,159,171,167,160, 45, 68,121,221,202,150, 17,151, 70, 28,226, 0, 1,165,175, 53, 34,184,226,218, 3,137, 6,185,133,
+214,159, 64, 62,131,177, 79, 74,215, 59,239, 46,114, 62, 73,105,206,121,219, 43,183,202,181, 61, 54,204,149,140, 87, 16,180, 79,
+ 90, 28,144,212, 15, 61, 13,188,244,153,133,180,252,204,146,148, 10, 13,136, 72, 77, 74,173,187,125,187, 54,168,232, 77, 77, 61,
+159, 21,230, 31, 52,124,203,147,159,103,211, 19, 12,112, 3, 90, 28,220,122, 72, 24, 1,212, 9,199, 19,194,151,147,146,109,248,
+166, 79,105,159, 6,225, 22, 28,184,243, 24,121,135,227,200,109, 47, 50,243, 78,164,165, 73, 82, 84, 8, 80, 80, 52, 32,141, 87,
+ 55,123,253, 56,180,226,179,107, 22,185,174, 20, 95, 57,126,174, 61, 21, 59,197,179,239, 28,181,233, 90,225, 23, 3,200, 89, 46,
+ 92,110,220,113, 82,207, 26,230, 69,160, 84,180, 38, 26, 10, 91,180,201,118,159, 11,241,130, 80, 77,124,196, 18,162,224, 71,110,
+230,150, 92,145, 13,232,212,220,131,191, 19,125,124, 71, 81,245,116, 45,223,146, 57,186,251,101, 32, 68,250,183,139, 78, 32,252,
+ 15, 88, 92,167,202,249,206,213,205,184, 61,151, 38,110, 27,246,108,130,215,123,249, 28,134,211, 35,251, 69,174,230,138,181, 33,
+149,131, 78,206, 1,255, 0, 61,116,166,249,180,155, 55, 56, 28, 90, 69, 65,233, 29, 43,216,156,163,205, 76,223,173,153, 35, 48,
+ 32,208,131,152, 61, 8,145,131, 57,242,214, 25,114,146,135, 30, 75,205,109, 14, 3,189, 40, 85, 59,158,167,165,104, 8,175,179,
+182,161, 54,121, 4, 46,161,201, 33,206,150,159, 92, 90, 91,154,237,103,161,142, 28,180, 99,252, 85,105,229, 11,228,165, 11,142,
+ 84,100, 77,109,167, 85,230, 38, 43, 13, 58,226, 27, 72, 87, 95,196,218, 82,122,154,235,105,229, 83,111, 48,212,199, 7, 60,102,
+ 1, 21, 30,174, 11,202, 94,105,222, 93, 90,191,233, 93, 27,155, 22, 4, 18, 13, 29,135, 79,174,158,165,114, 46, 25,101,174, 42,
+ 84,166,164,160,132,123, 61,131, 90, 20, 97,220, 2,193,166,123, 71, 21, 92,249, 87,145, 12,216,169,135, 1,247,104,107,230, 41,
+ 10, 32,253,218,152,219,224, 32,234,114,175,110, 87, 26,198,150,170,204,238,103, 38, 2, 94,109,199, 37, 56, 22, 8, 0,184, 72,
+235,244,234, 78, 72,131,242,162,137,100,142,102, 8, 83,144,102,239,168,168,182,210,145,212,245, 6,164,232,204,102,148,147,187,
+200, 23,156,242,133,242,213, 1, 78,192, 14, 21, 5,124,103,173, 66,117, 35, 97, 19, 36,120, 15,201, 49,190, 47,100,100,179, 53,
+ 18,180,122,181,179, 97, 48, 12,220,130,225,230,186,132,146, 99, 37, 42,222, 84,145,219,174,173,194, 40,152, 40, 0, 84, 87, 90,
+220,220,187, 50,153,241, 95, 93,151,110, 71,205,161,217,108,216,148,134,108,142, 61,181,203,138,219, 40, 78,192, 64,175,197,215,
+182,162,183, 43,120,116, 18, 51, 86, 77,174,210,123,115,223, 53, 10,255, 0, 89,242,248,178,218, 66,139,128, 21, 0, 72, 42,234,
+ 43,170,145, 20, 86, 32,165, 77, 95, 98, 17, 79, 49, 62,218, 87, 69, 70,170, 43,225, 47, 99, 23,182,204, 41, 63, 12,202,124, 52,
+ 94,221,231, 81, 27,131,228,135,188, 50, 82,246, 12,100,162,135, 53, 37,187,225, 56,242,155,115,230, 45,142,163,106, 73, 15, 33,
+ 85,175,191, 76,224,186,127, 7, 39,147, 91,176, 96, 90, 80, 14,237,107,137, 14, 99,205,194, 90,195,105, 81,218, 55,124, 67,236,
+212,220,125,246,213,202, 17,231, 65,193, 71, 95,130,135,107, 80, 84,125,164,146,107,165, 41, 68, 93, 85, 76,146, 49,246, 29,174,
+234,130,123, 10,211,174,184,187, 84,212,237,153,232,180, 75, 79,173, 8,175, 96,178, 40, 52, 82,208,236,194, 56,121, 25, 20,201,
+112,133, 49, 84,105,217,239, 20,119, 9, 91,149, 79,223,162,136,218,220,130, 49,148,156,202,142,184,203,209,138,144,179,186,181,
+161, 29,127,167, 70, 33, 13, 73, 47,241,143,135,229, 62, 88,121,155,182,110,250,116, 79, 11, 26,213, 31,196, 92, 47,180,226, 77,
+173,228, 32,197, 9,161, 29, 72, 3, 79,157, 40,106,224,183,123,184, 35, 53,167, 13,180, 6,146, 36,149, 38,137, 21, 9, 3,244,
+233,163,239, 90,212,226, 61,182, 89, 50, 9,237,139, 54, 33,101,144,153, 78, 52,151,246,144,104,227,130,159,163, 77,223,185,181,
+169,244,124,187, 60,217, 4, 90,131,204, 92,111,103,132,152,242,225,197, 37, 40,218,166,131,200, 77,105,254,182,221, 51,126,236,
+198,241, 82, 17,242, 77,204,220, 61,201,189, 94,167,248,246,204,211,236,193,182, 45, 45,186, 8, 90, 25,147, 24,238, 7,221,231,
+ 87,238,209,135, 50, 24,240,212,156, 71,229,108,147, 26,144, 61,255, 0, 4,215, 31,214,206, 51, 99,111,202,181,227, 82,197, 9,
+ 52,105,200,224,169, 71,196,157,142,105,148,220,194,215, 26,146,167,237,188,173,150,128, 84,123, 10, 71, 47,243, 14,188,181,185,
+ 54,219, 13,210, 49, 29, 16, 68,136,107,233,244, 24, 21,251,244,205,219,251, 84,204, 62, 85,211,230,161,245, 31,226, 80, 91,159,
+230, 3,202, 18,138,190, 81,203,140, 98,170,237, 42, 68, 85, 20,143,246, 98, 13, 55,119, 48,211, 34,166,173,252,176,129,185,179,
+237,248,168, 13,195,214,151, 51,220, 74,146, 50, 75,195, 1, 95,170,150,153, 52,251, 26, 26,106,254, 97, 61, 42,114,219,203,155,
+102,127,210, 30,245, 23,127,212, 55, 44,222, 84, 75,249, 45,245,253,253,255, 0,100,223,143,251, 35, 76, 37,230, 32, 51, 42,193,
+107,200, 81,183,229,140, 36,199, 56,228, 91,178,129,126,237,149, 57, 81, 79,130, 89, 96, 0,123,211,105, 0,106, 54,110,102,104,
+226, 21,146,215,145,195,127, 7,185, 47,139, 11, 33,184, 83,231, 36, 95, 92, 7,184,122,224,175,190,132,106, 26,227,154,186, 40,
+172,214,124,150,209,158,165, 43,183, 98, 17, 86,164,153, 77,203, 90,188, 74,238, 69, 66,190,240, 58,253,255, 0, 86,171,247,124,
+209, 35,178,112,246, 43, 61,167, 42, 67, 31,225, 39,180,162, 61,171, 17,101,148,133,193,180, 50,242,128,174,244,169,114,148, 0,
+246,128,218,212, 62,177,170,189,230,242,249,126,103,171, 85,158,213, 28, 57, 49, 17,109, 86, 27,255, 0,194,166,173,114, 16,145,
+226,220, 71,131, 67,235, 83, 91, 71,217,170,189,221,235, 93,155,149,158,210,223, 78, 64, 35, 94, 47,105, 92, 96,219,151, 53, 41,
+ 14, 26, 16,195,143,150, 26, 71,211, 82, 43,244, 1,170,213,221,192, 53,162,176, 65, 17, 56, 81, 27,226,102,172, 90, 97, 6, 33,
+ 33,185,178, 2,118,249,139,120, 37,180,159, 98, 69, 13, 62,221, 87, 39, 6, 99,208, 20,148, 54, 96, 26,149, 14,185,100, 57,197,
+217,213, 8, 54,155,109, 23, 80, 28,147,112, 32, 26,251,131,125,117,219,123, 72, 24,106,247,159, 80,253,169,211,231,124, 66,141,
+ 96,246,166, 91, 85,227,154, 49, 25, 14, 73,131,103,181,220,218,113,210,235,145, 99, 75,126, 2,150, 43,250,164,178,243,117,167,
+180,143,171, 87,157,179,123,183,181, 1,186,157, 78,176, 15,222, 21, 95,118,178,147,112,196,177,181,234, 36,125,197, 78, 81,207,
+252,227, 29,180, 38, 47, 29,101, 65, 73, 79, 86,205,214, 0, 96,255, 0,170,167, 36,124, 93,125,137,213,194, 14,102,219,233,223,
+147,216, 10,165,220,114,245,201,119,114, 47,105, 31, 20,193,117,245, 55,206,146, 92,249, 72,124,119, 54, 68,132, 36, 87,231, 50,
+ 22, 34,176,218,255, 0,170, 92,101,137, 41,235,238, 6,158, 58, 95,254, 81,182, 70, 42, 92,125,159, 18,138,222, 84,191,126, 76,
+104,237,119,192, 21, 10,254,249,122,156,204,223,117, 82, 99,227, 88,180, 85,133,165,104, 83,178, 50, 7,146,147,226,151,119, 64,
+ 66,105, 94,149,108,215,217,166,211,243,221,148, 3,242,152, 92,122,205, 61,192,125,233,120,121, 46,229,199,243,158,198,246, 2,
+ 79,180,145,246, 33, 46,127,199,119,127,151,145,117,228, 76,186,243,144,136,228,188,221,181,201, 6, 29,158, 58,135, 94,177,153,
+216,135,136,240, 14,110, 35,221,164,109,249,202,227,114,112,142, 16, 24, 15, 70,126,220,209,174,185, 94,207,111,105,146, 98, 94,
+ 70, 64,229,236, 24, 31, 90,136,113,189,138, 19,225,219,176,142,212,118, 74,195,112,153,111,107, 62, 76,116, 43,224, 66, 72, 20,
+ 74,156, 35,114,138,122,158,131,232,188, 91,176,193, 24, 7, 23, 28,214, 43,190,222,253,108,230,152, 52,100, 6, 1,118, 59,210,
+198, 52,150,161,195,187, 58,200,110,175,236,136,240,142,146, 80, 83, 74,124,103,117, 78,242, 72, 0, 87,196,247,233, 91,221,238,
+244,146,208,171,243, 91,235,111,169,117, 59, 30,183,177, 37, 48, 26,117,165,172,190,243, 79, 62, 93,112,130,186,117, 73, 1, 36,
+ 18, 87, 95,111,217, 77, 83,110,110, 42, 40,162,217, 9,136,151, 14, 2,129, 94, 92, 38,199, 6, 86, 61, 22,206,244, 69, 38, 3,
+140,238,118, 49, 63,238,234,109,228, 2,166,128, 36, 18, 9, 36,144, 71, 74,253, 90,115,182,130,226, 0, 36, 5, 68,221,238,157,
+ 12,174,149,167,189,211,199, 60,208,175, 59,244, 53,197,121, 84, 41,183, 11, 5,177,204, 86,250,166,214,228, 91,142, 62,231,200,
+173,185, 71,226, 10, 82, 19,251, 39,104,127, 85,105, 35, 90, 29,131,230,140, 10, 56,145,208,113, 68,218,252,199,220, 54,105, 65,
+ 18, 85,181,196, 28,143,167, 78,106,143, 88,217,201, 56,247, 51,119,142,249, 1, 42,182, 94, 45,139,242,217,152,227,101,152, 55,
+187, 82,212, 67, 83,152,117, 73, 85, 91,116, 32,131,241, 29,170,220,133,124, 64,234,121,208,135,183, 83,120,251,151,166,246,126,
+ 98,131,153,236,133,204, 6,166,152,183,139, 93,196, 83,210,163, 20,114,228, 62, 75,227, 62, 57,199, 18,236, 60,140, 61,116, 75,
+ 13,151,227, 7, 80,184,173, 56,229, 86,165, 37,212,144,165, 18,122, 40, 31,179, 65,176,151, 80, 10,168,125,178, 11,237,194,119,
+ 58,229,141,108, 92, 14, 71, 14,144,169,216,186,243,231, 58, 92, 68,142, 57,192,230,200,128,166,196,120,249, 21,229, 75,181, 89,
+ 31,102,167,171, 41, 90, 84,227,201,234,104,164,160,131,237, 58,109,113,115, 5,159,117,238,171,186, 6, 39,224,165, 47,249,191,
+109,229,134,152,245,130,115,160,206,189,106,111,101,244,133,234,173,201,112,164,223,159,197, 27,136, 29, 66,223,105, 37, 74,121,
+182,136, 59,182,146,180, 10,237,173, 58,106,187,184,110, 81,185,166,145,187,215, 69, 92,103,156,118,111,117, 41, 65,235, 86,125,
+222, 47, 86, 39, 96,183,198,152,250,163,202,111,122, 94,123, 98, 18,218,148, 72, 73, 74, 83, 85, 4,130,174,235, 77,105,172,222,
+246, 86,151, 7, 52, 80,168,107,174, 99,110,249, 51,158,214,130, 61,126,158,162,166,216, 85,222, 76, 97, 21,181, 57,243,109,180,
+230,209,230, 47,204,113, 20,234, 65, 73,241, 73,232,105,247,234, 86,198,239, 1,138,207,247,205,184, 57,206, 32, 81, 30,228,103,
+170, 98, 16, 49,221,145, 25,216,237, 37,244,249, 73, 91, 72,117,180,248,144, 8, 4, 87,161,161, 20,239,225,171, 52,123,145,166,
+ 6,138,156, 54,154,187, 17, 90,167, 76, 3,155, 24,201,228,203,177, 93,219,162,130, 72, 90, 29, 94,229, 44, 10,124, 72,160, 74,
+171, 66, 20, 8, 4,248,165, 71, 82, 48,111,142,197,146, 98,211,233,233,197, 11,254, 91, 54,192, 75, 30, 99,211,211,222,190,118,
+ 63, 54,207, 76,183,110, 61,205,211,205,184, 43,114,153,198,111,202, 45,229, 45,219,105,242,236,165,245,209, 47, 56,214,197, 71,
+146,194,202,232,224,113, 4, 37, 95,235, 10,163,111, 56,239,192,104, 78,108,174, 53,253,189,139,103,228, 61,232,206,198, 7,184,
+130, 59,174,161,225,215,211, 78,131,152, 92,176,198,100,115, 22, 50,134,110, 92,111,154, 73,181, 54,164,161,198,225, 4,173,251,
+ 72, 29,194, 83, 27,204, 75, 44,131,236,101, 40,211,104,185,230, 77,184,232,153,186,154, 56, 28,125,249,251,214,145,188,121, 47,
+180,115, 99, 76,161,162, 57, 14, 58,152, 52,154,245,129,221, 62,182,171, 65,134,122,188,245,117,134,182,203, 23,123, 60, 44,162,
+ 58, 40, 76,155,100,215, 33,184,177,211,160,101,224,176, 15,254, 87, 82, 44,231,205,178,239,252,198,185,135,168,212,125,203, 40,
+221,191, 76,183,112,146,109, 46, 88,241,208,246,208,251, 69,126,197, 99,177,239,204,131,146, 24, 83, 76,222,248,195, 57,105,244,
+237, 75,191, 36,196,105,237,215,198,129, 18,203,135,223, 68,104,147,111, 91,116,194,173,184,167,104, 35,226,169,146,249, 5,190,
+192, 79,229, 49,223,217,120,199,219, 68,109,183,250,234,187,228,145,148,166,241,140,201,165, 4,209,108,200,197,167,180,226, 9,
+250, 88,161,250,137,213,110,242, 75,105,143,118,226, 51,253,224, 62,212,217,190, 83,110,182, 6,178, 90, 73,234, 26,191,248,106,
+171,183, 50,122,169,185,222,237,243,109, 49,172, 55,231,230, 58,210,145,242,198,203, 41, 46,238, 88,160,168, 83, 98,157, 79,142,
+155,219,236,110,185, 33,204, 32,142,154,138,123, 85,147,106,229, 27,139,115, 67, 19,193,235, 4, 46, 47, 78,225,108,171, 3, 77,
+234,235,144, 67,254, 31, 47,145, 51, 91,150, 86,205,177, 43,221,242,144,166,190,243,224,168, 80,109, 42, 83,189,189,218,178,243,
+ 6,232, 4,108,134,181,208,208,218,244,208,126,197,233, 79, 46,185, 97,214, 17, 57,206,226, 65,167, 66,189, 60, 73,196,247, 76,
+139, 9,184, 76,179, 45,183,229, 67, 97, 10,151, 3,205, 72,117,216,199,187,129, 36, 5, 40, 38,157,192, 85, 59,154, 83, 89,251,
+119, 47, 1,196,171,158,245, 12,101,236, 99,240,169,192,240,175, 66,232,151,166,123,206, 67,128,227, 81,177,201,146,111,130,215,
+ 21,110,161, 12, 7,146,251, 49,144,181, 18,164, 6,212, 85,176,110, 38,160, 17,246,234, 55,254, 76,251,105,252, 72,156, 3,147,
+109,215,151,227,186,136, 49,205,107,133, 56,143,176,171, 67, 58,101,166,250, 20, 90,121,242,235,157,144,227, 1,194, 73,247, 29,
+165, 63, 85,117,176,242,207,155,230, 45, 49,220,180,118,131,246,230,188,237,205,190, 70,219,238, 90,164,183,118,135, 28,104,104,
+ 71,171, 47,122,132,220,176, 25,142, 33, 79,155,100,133, 50,107,251, 95, 32,165,178, 62,154, 83, 91,126,213,207, 22, 27,155, 71,
+135, 51,107,209,197,121,167,127,242,179,116,217,158, 65,132,185,189, 34,132,123,138, 25,221, 48, 38,158, 43, 6, 58, 82,174,160,
+142,149, 7, 86,118,110, 44,120,168,112,162,161,207,177,207, 1,210,232,220, 15, 69, 16,186,245,198,168, 59,192,140, 73,234,122,
+ 10,255, 0, 70,150, 23,173, 60, 66,100,237,186, 70,102,211,236, 40, 51,127,227, 54, 94, 75,140,189, 8,184,133, 2, 20,149, 34,
+160,253,218, 81,183,116,200,164, 93,104,120,133, 94,178, 63, 79,216,156,151,212,236,171, 18, 29, 33, 69, 91, 87, 85, 39,236, 58,
+116, 55, 71,129, 77, 72,141,178, 3,130,252,178, 96,246, 76, 88,132,218,236,113,161,148,116, 11,109,128, 23,211,223, 74,232,142,
+188, 50,102, 87,126,150,156, 17, 70,203, 54,226, 87,177,136,147, 95, 72, 20, 72,141, 29,199,190, 33,225, 68,164,233, 9, 46, 67,
+ 56,132,164,123,123,229, 61,214,147,216, 9, 83, 56, 87,123,203, 33,198,164, 88,238,105, 95, 93,138,126, 42,216, 32,123,126, 48,
+154, 13, 34,110,154,104, 67,199,181, 57, 27, 60,249, 24,157, 94,194, 20,130,213,124,201,237,143, 34, 99, 16,231, 53, 67,185, 47,
+108, 81,108, 15,245,135,195,247,232,178, 94, 65, 32,163,156, 61,168,241,108, 87,141, 53,108, 79,246, 34, 27,156,215,151, 53, 12,
+198,146,243, 97, 42, 73, 77, 94,121, 33,116,255, 0, 84,157,255, 0,118,163,124, 27, 82,234,135, 5, 32,118,251,240,220, 99,117,
+ 59, 61, 10, 31,189,154, 76,121,245,188,252,166,130,156, 36,208,149, 29,213,246, 81, 39, 82,108,186,140, 10, 52,168,217,118, 75,
+150,154,189,132,118,131,240, 95,136,204,220,170,128,126,180, 29,138, 15, 95,211,165, 68,237, 60, 83,119,109,146,179,240,149,233,
+ 57, 76,137, 43, 74, 91, 88, 42, 53,232, 72, 26, 55,136,209,197, 34,235, 71,142, 5, 99,215,105, 79, 40,176,226,182, 43,193, 64,
+251,126,237, 25,174, 7, 20,139,163, 44,192,173,105, 75,206, 2,135,215,230,127, 81, 85,234, 53,210,104,138,182, 22, 27, 91, 59,
+ 84,131,230, 15,194,162, 58, 29, 38, 93, 68, 42,152,127,135, 39,230, 60,223, 43,226,173, 43, 79,191,236,210,126, 46, 43,154,149,
+ 28,147,192,127, 35, 27,204,142, 31, 67,196, 31,139,204,218, 5, 63,219,174,170,215, 59,185, 7, 19,130,211, 44,172,153, 65,128,
+175, 96, 67, 11,254, 24, 44, 13,186,102, 93,100, 54,160, 13, 82,149,200, 29,189,232,233,168, 43,141,204,200,123,181, 87,125,186,
+193,130,149,104,247, 32, 6, 65, 46, 26, 20,180,181,116, 42,234, 65,171,207,149,125,171,107,175,219,168,233, 47, 36,226, 74,185,
+ 90, 88, 68,114, 99,125,136,119, 41,184, 82,137,243,238,196, 2,122, 52, 10, 78,239,117, 92,105, 71,236, 35, 76,223,122,241,151,
+167,189, 88,109,246,232,248,183,220, 62, 9, 15,247,102, 20,138,132, 71, 74,146,175,214,125,212,161, 96,123, 82, 20,234,210,126,
+177,245,105,148,187,140,131, 50,167,173,182,184,143,225,251, 23,134,240,235, 33, 86,199, 11,138, 88,173, 82,162,195,255, 0, 96,
+102, 50,105,255, 0, 75, 76, 37,220,229,225,247,253,255, 0, 5, 57,111,180,194,115,251, 7,221,241, 78,241,176,187, 64,234, 45,
+207, 41,186,245, 91, 49, 2, 58,125, 43,154,223,232, 26,143,151,115,147,247,189, 61,138,102, 13,166, 33,248, 61,159,254,228,251,
+ 27, 24,198,208, 64,217, 45, 32, 80, 20, 7, 74, 72, 63, 70,249, 3,236, 86,163,228,220,102, 60, 71,167,177, 75,195,182, 64, 56,
+ 31, 79,106,149, 66,199,241,212, 80, 37,155,169, 30, 1, 77, 33,214,254,197,163,113,251, 53, 27, 45,244,167,161, 74,197, 97, 8,
+224,125, 59, 84,182, 29,131, 26, 33, 62, 96, 35,198,143, 89, 82,225, 31, 90, 99,167,244,233,132,151,178,250, 31,218,164, 35,179,
+139,208, 15,130,144,179,102,197,154, 77, 74,109,180, 29,119, 24,206, 71, 89,250,146,224,253, 26,100,251,201,143, 19,233,234, 79,
+ 25,105, 16,224, 61, 61,105, 91,108,227, 77,138,182, 34,168,143,100,183, 27, 31, 97,109, 95,167, 77,223,113, 41,204,167,108,181,
+139,128, 74, 17, 58,206,193, 30, 91, 76,116, 63,246,233,116,127,225, 4,157, 54,124,175, 57,148,233,150,236, 28, 19,172, 92,177,
+152,106, 74,163, 56, 24, 90, 8, 41,117,173,136, 82, 72,246, 20,144,116,206, 70,151,102, 83,216,226,104,224,159,219,228, 2,239,
+246,201, 66, 98,105,212, 60,128, 23, 95,111,152,219,205,184,163,254,177, 63, 70,153, 62, 14,164,242, 56,192,200,145,233,236, 78,
+ 81,178,187, 59,132, 86,227,114,137,225, 66,203, 51, 80,170,251,194,154, 82, 0,250,244,206, 75,122,240, 79,227,115,155,208,125,
+223, 21, 50,179, 92,227, 72,113, 62, 85,238, 19,198,160,124,107,148,208,250,194,153, 74, 71,219,166, 18, 91, 81, 61,108,167,247,
+ 79,187,226,141, 22,107,187, 49,219, 75,111, 92, 44,238,110,233,229,162,236,194, 20,162, 63,209, 91,205,145,245,141, 50,117,169,
+ 57, 32,249, 7, 67,189,132,253,202,115, 14,242,181,172, 54,143,224,224, 16, 10, 16,155,188, 55,228, 0, 60, 66, 68,133,255, 0,
+151, 69, 22,133, 55,124,236,110,122,191,194,239,130,247,116, 85,208,178, 84,155,109,204, 51, 77,202, 41, 66,220, 67,132,248,132,
+ 54,146, 18, 41,237,239,162,253, 33, 71,138,238, 33,248,135,187,239, 81,133, 58,236,116,131, 46,213, 50, 10, 22,162, 18,185, 49,
+ 28,101, 75,168,169,238,143,183,174,131,173,139,115, 75,182,229,178,252,142, 7,178,138, 81,103, 84,118,219, 15, 58,173,137,113,
+ 59,194, 2,107,208,246,218,144, 43,223,196,142,190, 21,208,100, 85,193, 50,188,148,130,171,175, 59,178,155,236, 69,176,195,143,
+ 6, 84,191, 35,105,240, 64,161,112,212, 29,181, 32, 16, 85,219,192,120, 87, 66,229, 11, 96, 36, 4,133,154,243,141,241,138, 18,
+ 43,154, 22, 96,240,218,118,239, 99,178, 40, 45,166, 20,226, 19,229,176, 54,133, 54,223,116,164,251,232, 1, 34,163,185, 39,166,
+181,105,137,100,101,221, 75, 10,194, 87,149,220,126, 13,105, 13,219,172,204,165, 95, 47, 29,182,246,136,225, 0, 37, 11,219,182,
+137, 5, 41,169, 29, 78,225, 65,226,105,215, 89,182,229, 45, 73, 78,229,183,206,131,250, 21,226,199, 46, 80,208,148, 59, 32,110,
+ 63,179,242,146, 15,198, 86,143,196,170,238,160, 77, 69, 42,126,202,234,177,113, 45, 83, 3,102,225,131, 85,190,192,179, 24, 11,
+ 73, 99,205, 73, 8,121,166,155,248,186,165, 64,154,252, 84, 53, 74, 77, 13,106,123,211,195, 79, 44, 46,195, 10,207,183,205,161,
+237,198,156, 21,179,198, 46,177,230, 50,130, 29,109,109, 19,181, 43,222,149,133,110,167, 81,214,166,186,212, 54, 75,214,200, 5,
+ 78, 11, 41,221, 45, 29, 17, 56, 98,171, 15,173, 14, 22,199, 57, 47, 0,254, 34,153,166,201,148, 99,101,217,246, 11,252, 61,141,
+206,136,181,237, 15, 50, 86, 82,119,181, 32, 4,249,141,158,149, 9, 61, 10, 65,213,154,107,166,218, 16,230,226, 14, 99,211,138,
+178,121,115,191,220,108,215,160, 48,157, 14,193,195,129,232, 52,234,225,235, 84, 79,211, 79,162,120,121,133,229, 25, 79, 35,223,
+ 36,230, 13,194,117, 14,199,135,113, 41,118,214,202, 27, 80,216,164,199,248,146, 87, 80, 78,229,214,131,168,161,236,198,231,115,
+117,227,188, 24, 70,145,196,241, 90,223, 60,243,227,236, 99, 12,136,157, 71,220,186,232, 45,216,222, 29,107,143,111,182,177, 6,
+ 24,142,132,165,148, 54,218, 27, 94,212,244,168,160,235,218,186,133,191,150, 43, 6,208, 17,171,222,176, 88,204,219,156,133,239,
+169,174,104,111,145,114, 37,186, 4,103,220, 83,227,202, 0,188,220,129, 85,160,129, 93,192,160, 38,181,168,161,173,126,173, 84,
+ 47,119,144, 65, 3,218,172,219,126,193, 36,174, 2,152,229, 69, 79,243, 78, 75,143,121,114,106, 20,211,142,109,112,134,144,226,
+ 18, 34,172,211,111,192,150,148,149,124, 73, 42, 82, 84,107, 66,106,160, 71,106,116,215, 6,103, 18, 86,179,181,236, 14,179,107,
+104, 70, 94,191, 93, 71, 96,251, 10,138,218,175,136,136,211,101, 14, 5,169,237,203, 45,249, 84, 91,172,110, 34,149, 31,133, 73,
+ 61,200,234, 41, 83,215,174,159, 91,205,161, 11,235, 19, 41, 56, 43, 31,134, 50,187,133,186, 67,239, 17,114,128,166,211,185,165,
+169, 34, 67, 59, 69, 20,166,193,232, 20,145,213, 67,199,184,237,210,102,218,224,186,188, 66,164,238, 54,226, 23, 0, 59,174,175,
+171,214,132, 28,162,145,129,229, 22,156,190,215, 54, 28,203, 67, 79, 71,135, 61,230,137,109,223, 45,196,169,109, 41,228,129, 81,
+ 69, 40, 52,231,250,202, 33, 85, 52,212,151,136, 1,210,210, 15, 71,167,218,164, 54,200,141,252, 38, 55,130, 29,143,195, 15,180,
+122,148,191,146,173,152,231,168, 30, 24,201, 49, 21, 34, 20,201, 19,173, 50, 83, 18, 53,192, 37,214,230,173, 45,154, 41, 10,160,
+ 83,107,216,118,149, 34,132, 16, 15, 99, 80,137,185,200,131, 71, 52,215,211,236,244,193, 61,181,175,217, 46,154,247,142,233,192,
+211,133,126,238, 63,180, 99,242,205,142,226, 55,174, 58,228, 91,255, 0, 28,223, 34,200,138,204, 11,131,237, 66, 47,160,126,206,
+ 63,152, 82,144,161, 79,212, 61, 42,154,251,170, 41, 86,187,253,187, 46,216, 38,103, 28,215,167,185,107,116, 45,140, 54,181, 28,
+ 59, 21,157, 99, 26,101,182,247, 0,217, 45, 39,122,146,164,128, 86,145,222,149, 5, 39,216,122, 14,189, 13, 14,179,215,196, 65,
+ 87,136,239,139,192,232, 78, 22,139,198, 55,106,148,151,228,249, 13,109, 59, 80,189,128,199, 82,199, 77,171, 4,252, 63, 72,175,
+208, 60, 27,201, 11,158, 19,176, 92,236,177, 71, 28, 75,155,112,235,116,193, 28,177, 12, 40,109, 11, 44,148, 37,105,112,116,248,
+129, 72, 29,252,105,215,219,227,168,153,246,215,191,165,114,109,185,215, 12,204,163,179,124,213,128, 56,150,141,202,209, 99,153,
+209, 42, 67,243, 33, 50,243,236,147,226, 3,141,184, 62,177, 95,118,144,109,188,182,255, 0, 43,136,236, 37, 64,191,150, 31, 41,
+171, 73, 77,249, 30,101,196, 57,140, 37,194,188, 97, 86,105,108, 62,159, 41,187,140, 39,162,249,141,142,213,216,227,107,103,167,
+138,122, 31, 10,142,250, 47,139, 36,121,147,237, 79,108,118, 11,219, 39,107,138, 98, 63,170, 90,105,238, 53,245,170,193,112,227,
+172, 79, 19,188, 42,247,130,220,164, 88, 34,185,185,107, 77,173,167, 45,106, 36,247, 42,109,165,148,158,135,169, 65,167,191,184,
+211,200, 55, 71,183,186,250,158,213,108, 54,242,110, 17,233,153,141, 39,219,233,235, 10, 86,196,140,106,101,188,188, 47,204,170,
+228,128,107, 41,152, 42,134,251,142, 36,126, 21, 22,155,144,149, 31,165,186,233, 57, 42,227,171,130, 69,177,203, 9,208, 91,135,
+109,126,218,125,168,113,112,205,110, 54, 89, 10, 74, 38,133,161, 42,162, 94,117, 69, 0,143,121, 49, 99,233,236, 19, 81, 60, 59,
+107,103, 24,183,236,248,149, 32,180,115, 69,214, 13, 28,114,109,181, 8, 29,221,121,230,227, 16,127,215,112,211, 82, 17,220,184,
+124,164,251, 84,108,251, 19, 31,133, 15,168, 41,219, 28,251,231, 36, 9, 23,107,115,228,126,175,241,192,226,123,118,163,109,154,
+125,186,148,183,223,110,109, 62, 71, 17,235, 63, 21, 9,115,202, 81, 92, 96,224,127,194, 62,240,177,238,112,180, 56, 54,184,139,
+ 27,254,224,251,146, 20,127,240,117, 51, 15, 60,238, 48,229, 51,253,170, 2,227,203, 27, 27,159,154, 22, 30,214, 55,224,153, 36,
+115,110, 40,208, 37,219, 29,129,211,214,161,216,137,124,171,234,112, 42,154,145,103,152,155,159,254,243,253,191,177, 69, 63,201,
+141,182, 76,224,143,252, 1, 71,229,250,130,193,227,147,255, 0,169,120, 99,206, 14,203,145,105,142,178, 8,241,162,155,254,141,
+ 46, 57,255, 0,116,127,253,103,255, 0,136,253,201, 31,252, 37,181,102, 98,103,248, 25,240, 77,227,212,123,142,164,162,199,131,
+ 99, 32, 1,240,191,106,197,146,235,227,253,182, 27, 73, 58,231,252,187,114,155, 57, 95,237, 63,125, 82,237,242,163,103,179,196,
+181,163,252, 33, 70,110,220,237,148, 73, 10, 23, 8, 54,214, 0, 4, 37, 19,237,241, 45,139, 74, 69,123,124,192, 73, 32,123,198,
+148,143,152,111,220,127,205,127,180,253,201,201,228, 93,161,131,252,182,159, 85, 84, 38, 87, 56, 76, 74, 10, 29,144,193,108,147,
+ 68, 38, 72,117,143,160,124,152,113,180,211,234,211,182,110,183,143, 53,116,142,245,146,136,121, 95,110,136, 81,145,180,118, 52,
+124, 20, 78, 95, 50,217,220, 82,215, 41,203,107,138,173, 74,188,207,152, 88, 87,254, 91, 98,137,212,156, 23,215,103,241, 31,106,
+139,185,217,172,217,134,129,236,248, 96,163, 82,121,139, 24, 70,226,147,108, 83,134,181, 34, 58,119,245,255, 0, 97,105,251,245,
+ 61,107,123,116,127, 25, 30,213, 86,189,218,109, 5,127, 46,190,166,255, 0, 74,138,205,230, 27, 66,170,152,210, 27,143, 90,213,
+ 40, 74, 99,131, 95,110,205,160,253,154,180,216,207, 59,233,169,196,250,117,170,102,225, 97,111, 21, 67, 98,104,247,125,129, 68,
+102,114,132,103,149,253,181,194, 9,173, 16,189,200,250,122,129,171,174,223,226, 58,153,159, 79, 90,204,119,198, 67, 24, 53, 13,
+ 30,157,116, 91, 32,114, 51, 45,186,141,146, 10,212, 79, 77,163,227,255, 0,241, 17,247,106,219,111, 27,136,197,100,155,163,163,
+175,116,131,216, 0,248,162, 4, 78, 70,138, 22,132,203,243,144, 86, 1, 74,212, 41, 90,253, 90,144,141,181, 24, 42,133,206, 7,
+ 26,162,133,131, 46,181,169, 31, 52,228,150, 93, 64, 31,186, 82,129, 95,223,166,211, 74, 65,211, 68,128, 96, 3, 81, 83, 24, 55,
+232, 55,105, 40,102, 26, 16,181,184,173,168,101, 32, 21,149, 31,101, 52,202,238,237,150, 81,153, 37,117, 26, 51, 37, 48,154,229,
+172, 5,199, 0,140, 31,225,253, 44,255, 0, 54, 92,111,248,178,145,243, 73,129, 81,188,197, 71, 69, 26,119,232, 84, 53,231,227,
+231,254,223,252,232,109,255, 0,244,104, 65,127, 13, 85, 20,251,213, 59,254, 99, 7,213,248, 60, 58,122,213, 87,245, 3,234,115,
+133,113, 24, 15,195, 97,216, 42, 82, 27, 93, 18,155,143,155, 66, 7,245, 74,105,246,235, 72,101,140,183, 57, 2,182,235,109,216,
+196,107, 95,114,226,151, 42,250,176,196,178, 9,146, 24,176, 90, 17,112,117,110, 45, 41, 13, 71, 66,147,214,190, 40, 72,212,164,
+ 28,187, 38,100,149, 97,181,230,130,195, 67,167,211,214,130,176,178, 75,222, 70,225,119,251,180,211, 12,172,146, 11,177,159, 32,
+131,254,218, 81,247,232,151, 27, 35,227,202,170,233,183,115, 84, 47,193,196,123, 10,150,181,106,121, 40, 75,146, 44,144,106,174,
+191, 11,178, 35, 47,167,189, 46, 44,106,189,115,104,246, 26, 26,251, 42,175,219,118,231, 20,160, 22,187,223, 69,250, 24,136,131,
+255, 0, 9,144,231,130,144,205,205, 65,144,125,138, 46, 51, 68,127,180, 70,161,166,132,140,233,236, 87, 43, 59,173, 89, 56,251,
+126, 41,122,102,181, 25,180,182,155, 93,254, 32,238, 17, 22,227, 30, 98, 58,120,249,104, 96, 46,158,250,234, 58, 75,122,241, 30,
+255, 0,138,159,130,228,142, 31,252, 39,238, 91,211,121,180,183,181,199,154,189, 48,191, 25, 15,217, 27,116,238,247,171,204,104,
+159,183, 81,242,219, 59,164,123, 84,196, 23, 67,163,221,251, 66,116,141,146, 90,186, 3,119, 13, 36,248, 58,212,136,223,106, 82,
+227,232, 31, 80,211, 9, 45, 29,209,233,238, 83, 16,222,180,103,246,255, 0, 74,120, 98,235, 9,229, 5, 71,184,218,214,175,106,
+228,173, 4,253,111,195,111,238, 94,152,190, 7, 14,159, 79, 90,147,138,118, 59, 47,143,220, 19,160,156,248, 70,244,249, 18, 82,
+159, 6, 37,181, 32, 15,161, 41,152,149, 15,250, 58,104,232,207,167,244, 39,236,123,125, 63,165, 37, 93,237,214,234,167, 33, 58,
+132,248,173, 81, 22, 17,255, 0, 75,106,255, 0, 78,146,116, 4,167,109,123,115, 72, 23,147,199,241, 72, 29,250,159, 48,138,253,
+192,105, 51,108, 82,205,145,165,126, 39, 37,104,255, 0,214, 10,125, 43, 3,244,157, 34,235, 90,167, 13,152, 4,189,139,219,110,
+145,229,184,210,148,127, 85, 78, 41,175,189, 84, 31,126,144,117,177, 9,195, 38,111, 82,123,102, 68,199,135,236, 35, 7, 85, 79,
+194,205,193, 46,175,254,130, 55,172,253,154, 64,219,211, 63,177, 57,108,237,244, 41,107, 10,184,184,226, 80,184, 10,166,224, 20,
+100,169,196, 37, 4,255, 0,164,166,219,219,246,233, 51, 0, 9,118, 76,222, 20, 70, 60, 86,211, 17,255, 0, 41, 43,200,173,208,
+ 36, 26,127,187, 72,121,167, 66,107,215,246,110, 48,178,133, 30,157,151,180,248, 0, 78,163,231,132,116, 39,241, 93, 57,191,132,
+145,213,240, 82, 41,243, 32,219,158,242, 92,147,118,149, 33, 62, 2, 51,177,194,125,134,142, 52,158,254,227,166, 6,220,158,133,
+ 42,201,195,198, 21, 78,118, 59,251,177, 86, 37, 22, 18,160, 87,248,205, 28,153, 79, 14,169, 46, 22,143,188,145,162, 58, 10,224,
+139, 33, 20,197, 73, 38,229,162, 66,211,231,173, 79, 41, 40, 9,105,128,104,211, 32,211,245,137,173,125,222,222,253, 52, 95,164,
+ 41, 38,191, 12,147,141,139, 59,147,108,146, 4, 87,166, 55, 44,111, 80, 76,119,140,100, 26,118, 4, 39, 98,143, 90,245, 36,126,
+141, 34,235, 98,187, 35, 25, 40,239, 0,123,113, 68, 43, 62,127,114,154, 29, 76,183, 90,145, 38, 66,156, 11,144,251, 45,188, 89,
+ 20,235, 69, 20,149, 81, 41,232, 77,122,123, 70,147,240,244,168,235,155, 70, 12, 90, 41,235, 42, 33,151,165,185, 54,247,166, 56,
+ 82, 80,194,100,187, 29, 7,112, 66, 82,194, 9, 91,206, 80,158,170, 0, 37,182,199, 85,117, 87, 68,138,170,251,202,163,190, 22,
+ 61,207, 78, 45,109, 6, 34,184,252, 7,223,209,128,196,229, 91,248,103, 45, 55, 46, 77, 47,169, 99,204, 97, 65, 13, 37,212,121,
+129, 85,232, 16,132, 2,133, 1,183,167, 66, 58,116,237, 93,105, 59,172, 70, 56, 51, 89,101,142,151,191, 37,218,158, 55,202, 37,
+ 66,113, 94,100,184,173, 48,194,188,175,133,133,180,242,157,117, 33, 64, 43,204,117, 97, 85, 73, 36,246,165, 53,146,223,247,137,
+ 87, 24,236,195,154, 56,224,173, 77,191,145, 60,136,241,148,196,134, 84,151, 25, 65, 91,134,163,202, 67,223, 14,224, 40, 5, 84,
+160, 79,252,134,160, 36,106,231,242,192,236,194, 34, 99, 28,180, 32,203, 97,196, 72,114,177,155,218, 91, 21,249,116, 29,202, 74,
+193,247,168, 19, 74,119,250,180,148,125,210,163,119, 29,136, 92, 48,130, 6, 62,222,165,109,248,251,158, 92,140,195,129,215,183,
+176,216,109,166,136,252, 40,174,210,162,132,130,127, 0,119,168, 30, 0,159, 1, 89,171, 45,198, 75,124,138,203,119,254, 82,108,
+132, 80, 98,113, 62,158,175,120, 80, 15, 84, 94,165,222,107, 2,158,150,182,180, 30, 2, 50,205, 73,163,129, 33, 68, 4,144, 14,
+210, 43,212,253, 30, 58,186,109,155,140,155,140,160, 57, 65,108,156,176,219, 9,195,201,200,215,223, 79,106, 32,122, 82,229, 56,
+182,238, 36,182,221,165,255, 0,196,238,209, 17,112, 75, 59, 54, 37, 12, 23, 20,218, 82, 73, 74, 80, 20,181,118, 1, 85, 61,187,
+232,183,123,168,176,149,244,249,151, 57,179,105,126,229,118, 26, 62, 70,225,235,165,123,104, 19,143, 38,243, 67,171,147, 58, 27,
+ 74, 66,218,222, 18, 91,162,138, 16,182,106,149, 33,123,170, 7,152,234, 14,210, 9,232, 72,239, 67,170,126,227,124,251,151, 26,
+228,165,249,115,150,154,214,181,231, 63,143, 17,216, 14, 61, 99,163, 5, 87,114,190, 88, 47, 7, 98, 54,225,102,140, 56,197, 20,
+163,177,108, 56, 40, 67,117,161, 29,201,165,117, 18,224, 92,180, 45,191,100, 17,209,196, 84,214,190,177,210,132,174,242, 27, 40,
+ 40,142,202,234,235, 14, 44, 59,212, 83,109, 18, 18,170,118,233, 81, 94,221,192,209, 68, 84, 86, 1,100, 93,137,226,153,229,115,
+ 69,174, 28,118, 37,200,148, 33,136,146, 8,117,227,241, 37, 1, 74,242,234,190,221, 86,126, 19,237,233,219,197,211, 35, 39, 36,
+ 87,108,245,113,235, 8,197, 96,245, 73,102,135, 18, 64,141,121,183,169,194,216,101, 72,110,112, 74, 94,163,102,139,109, 67,117,
+ 20, 42,122,128,122, 18, 8,169, 35, 78, 35,141,237, 56, 96,171,215, 92,174, 38, 34,163,173, 65, 57, 91,212, 62, 45, 62,196,178,
+110, 9, 54,217,200, 49,174, 97, 41, 3,228,223,127,106,216,144, 60,165, 16, 91, 67,169, 30,105, 71,225, 31, 16,173, 58,203, 88,
+194,233, 29,214,147,131,100,117,158, 36,101,146, 18,241, 95,172,139, 77,166,123, 88,255, 0,204, 38, 84, 65, 58, 59,113,228, 37,
+221,142,124,187,162,161,183, 40, 72, 74,219,115,114, 82,224,173, 69, 18,123, 39, 82,151, 59, 83,142, 35, 4,218,243,109,108,224,
+184,230,130, 62,171,151,138,255, 0,124, 98,103,216,252,182,100,179,120, 45, 74, 41, 65, 10,242, 77,197, 37,192,166, 84, 58, 4,
+ 72, 74, 10,139,117,162, 86, 15,109,230,177,114,181,226, 50,195,152, 87, 94, 77,121, 32, 71, 39, 12, 21, 89, 60,131,116,101,199,
+254, 91,204,114,222, 80, 22,151, 24,110,173,178,162,144, 14,240,122, 32, 40,116, 61,105, 94,154,171, 75,110, 73,201,108, 86,209,
+ 70,214,140,113, 64,156,135,150,131, 83, 36,199, 64,100, 60,226,212,135,144,129,242,232,126,157, 8, 83, 74, 20, 7,219,183,238,
+237,165, 27,101, 81, 85, 49, 1, 13,166, 41, 13,135, 59,122, 92,164,148,182, 82, 80,160,149,160,185,251, 70, 18,123, 20,164,132,
+144, 40,126,141,113,246,129,185,169, 70, 85,195, 2,143,145,249,138,221,107,183, 49, 22,229, 10, 58,222,104, 81, 15,124, 69,151,
+ 83, 74, 18, 54,148, 45,181, 17,220,164,148, 26, 83,101,123,199,203, 98, 30,186,200, 95,170,161,222,159, 15, 74,164,200,230, 91,
+111,157,231, 91,238, 15, 52,218,182,169,216,105, 32, 76,105, 42,238, 81,240,252,188,196,143,244,118,171,196,128,158,186, 97, 38,
+214, 84,196, 46,194,142, 2,189, 60, 62, 35,211, 20,244,231, 51, 6,162,174, 75, 50, 20,252, 84,127,106, 49,216,249,105,140,182,
+ 71, 85,184,197, 86,133,163,175,226, 66,200, 61, 77,104, 14,155,127, 40, 47, 78, 89, 59, 24,104,225, 67,237, 30,212, 46,189,114,
+149,166, 99,255, 0, 57, 6,235, 25, 42, 7,227, 9, 90,119,163,196,111,232,146,131,237, 27,105,239, 58,121, 6,214,248,240, 33,
+ 47, 44,236,112,193,126,197,229,119, 18, 18,126,106,224,170,129, 82,192,105, 8, 88,255, 0, 93, 14, 37, 71, 75, 29,187,177, 49,
+115,155,208,146, 76,228,203,122, 79,154, 33,196, 67,223,172,228,182, 67,171, 80,255, 0,198, 45, 78, 83,254,142,151,142,192,244,
+251, 18, 15,149, 70,228,243, 25, 36,179, 29, 59,251,169, 40,100, 0, 82,125,137, 9, 13,182,161,244,167, 78,155,183, 83, 52,213,
+211,132,136,242, 77,250, 90, 65,121,130,204,119, 58,214, 76,149,193,143, 95,126,229, 71, 74, 79,190,186, 93,182,140,110, 66,190,
+244,147,229, 39,141, 23,131,201, 17, 33,141,207,195,128,242,197,106,149, 68,122,230,176,161,226, 80,234,219, 10, 7,218,135, 20,
+ 52,229,144, 14, 1, 50,150,167,241, 59,236, 73,222,245, 1, 62,218, 10,109, 22, 27, 44, 71,145, 85,121,201,137,228, 56, 15,130,
+208, 26, 89, 29, 0, 21, 10, 7, 78,227,181, 5, 71,203,110, 29,243, 23, 31, 95,244,168, 45,243,212,110,123,112,253,156,139,187,
+ 74, 74, 43,176, 51, 9,162,164,138,118, 43,218,149, 32,208,245,170,181, 33, 21,163,120,166, 70, 8,226,249, 69, 16,174,233,205,
+ 57,124,130,164, 27,188,147, 74,157,140, 2,234,147, 83,255, 0,228,164, 55,255, 0, 73, 71, 82,112,218,183,163,238,251, 83, 9,
+156,214,228, 7,219,246,124, 84, 62,103, 35,228,239,154,187,113,151,215,176,122, 88,104,172, 31, 99,109, 16, 73,250,206,164,225,
+129,163,130,139,184,113,112,248,252, 18, 38, 50, 28,174,228,224,109,133,190,183, 9, 0, 15, 45,205,228, 31,244, 22, 10,190,179,
+246,234,126,206,192,204,104,214,215,211,167, 37, 87,220,239, 89,102,210,101,120, 0,122,189,192, 85, 25,240,126, 38,228, 28,193,
+207,219, 62,236, 54,128,220, 85, 41,211, 25, 9, 7,222,216,112,125,101, 67, 86,219, 77,134, 76, 9, 20, 89, 78,247,207, 86,150,
+192,134, 56,184,245,101,246,162,155, 62,157,114,120,203, 59,229, 45,123, 13, 15,151, 29, 78, 5,123,252,195, 64,107,237, 26,190,
+237,156,188,214,128, 93, 90,172, 47,152,124,203,115,201,108, 97,160,123,125,216,173,239,113, 28,235,114, 84,167,139,165,105,253,
+101, 0, 58,253, 66,186,182, 67, 97, 28,124, 22, 93,123,205, 19,221, 19,222,167,102, 10, 56,113, 91,228,121,105, 68,102, 87, 32,
+214,168,160, 82,251,125, 58,127,225,177,163,161, 65, 62,237,242,156, 73, 42, 71,115,118,228,136,141, 53,113,182,188,204,166, 17,
+ 68,173, 40, 34,180,250, 52,197,145,232,113, 45, 56, 46,205, 56,112,239,102,162,177, 47,247,134, 31, 66, 91, 68,138,149,132,165,
+ 0, 26,168,147, 64, 41,239,209,110,101,108, 96,151,112, 81,114, 75,164, 46,140,240,150, 38,246, 57,142,171,144, 51, 36,150,214,
+ 91,255, 0,209,208,156, 20, 82,148, 69, 71, 67,247,157,120,111,207, 95, 55,157,121, 33,218,118,215, 97,248,156, 22, 89,205,188,
+203,167,242, 98, 61,169,195,252, 79,189,156,152,100,159, 23,200,161,195, 8, 49,183,246, 95, 42,233, 4,138,118,253, 65,175, 49,
+125, 35,116,233,175,127,230,175, 26,172,179,196, 58,171, 92, 87,204,220, 14, 26,188,223,214,155,143, 34,229,147,167,188, 72, 81,
+136, 37,157,135,221,180, 26,125,186,251, 32,203, 86,179, 32,189,100,110,136,201, 19,172,248, 54, 63,105, 83,113, 49,236,122, 51,
+207,116, 66, 95,117,160,243,132,251,122,138,107,178,233,133,186,157,146,231,142, 79, 21, 56,111, 12,202,203,201, 97,118,242,202,
+ 86, 42,148,165,157,137,167,213, 65,164,109,165,138,237,186,155, 66,142, 46,139, 50, 39,218,167,246, 46, 32,200,103,244, 37,198,
+ 82,186, 5, 4, 38,135,174,139, 53,132, 82,230,209,236, 82, 54,252,193, 61,175,200,247, 15, 89, 68, 8, 94,151,238,243,200, 82,
+ 74,220, 90,133,122,249, 72, 39,233, 5,165,149,125,103, 81, 55, 27, 20, 18,126, 16,173, 27,127,152, 55,150,199,252,199,122,234,
+126,212,221,123,244,199,154, 89,216, 83,177,219,144,145,220,109,183, 54,227,106,255, 0,160, 16, 84,126,147,170,205,231, 42,196,
+236,129, 90, 86,205,230,172,230,129,238, 7,182,138,191, 95,113,236,171, 23,146,235,114, 45, 86,121, 97, 10, 80,113,110, 50,243,
+ 82,129, 79,112, 18, 36, 21, 36,251,190,237, 86, 46,249,103, 77,104, 79,181,106, 91, 87, 63,139,128, 9, 3,217,240, 80,227,147,
+192, 75,158, 77,214,202,235,105,173, 10, 69,196, 52,216, 63,248,167,226, 80,253, 37,205, 86,174,118, 73, 35,173, 43,236,253,170,
+251, 99,204,177,207, 79,150,157,180,247, 20,239, 25, 56,149,197, 20,105, 42,105,107,161, 13, 27,115, 42, 34,190, 10,121,130,173,
+190,226,122, 29, 65, 79,109, 44, 94,133, 90,109,111, 98,147,135,216,151,166,193,105,165, 99,186,138, 87,111,195, 53,123,183,123,
+ 18,133,186,216, 39,253, 84,157, 71, 72, 94, 51, 10,110, 23,198,238,159,122,220, 49,183,210,170,197,147, 51,204, 52, 33, 13,172,
+169, 97, 63,233,126,205,210, 62,178, 52,209,207,233, 9,251, 30,209,147,150,243, 96,190,208,237,113,247,219,241,243, 97, 56,177,
+ 95,122,130, 86,208,250,206,144, 46, 3,130,118,217,135, 23, 4,152,218,165, 54,175,218, 49, 8,172, 31,137, 40, 83, 1,117,247,
+165, 33, 71,238,210,101,201,195, 92, 15, 66, 95, 25, 47,178,160, 62, 77,186,120,255, 0,184,180,232, 35,235, 74, 15,216,116,147,
+146,192,131,196,169, 19, 15, 90,210,159,247,187, 20, 26,210,190,112,121,108,185, 95,161,217,174, 33, 63, 82,116,137,199,138, 80,
+ 18, 50, 63, 98, 66,236,235, 34, 31, 5, 12, 6,192, 52, 13,181,114, 97,224, 85,236, 9, 91,109,147,245,104,120, 46, 41,102, 93,
+105, 56,169,108, 76,170,213, 17,144, 23,109,156,129,212,111,126, 82, 33, 54,174,148, 4,134, 25,109, 70,158,194,179,166,114, 91,
+ 21, 39, 5,200,119, 17,233,235, 74, 98,228,225, 71,253,205,150, 67,100,144,219, 36,149, 52, 1,239,181,199, 84, 94, 73, 39,189,
+ 23,215, 77,221, 7, 74,125,227, 12,198,106, 87, 2,252, 92, 33,183,252,246,186,164,184,203, 73,109, 77, 36, 10,116,168, 82, 86,
+107,218,149, 39,223,162,253, 56, 9, 39,220,158,213,238,100,215,100,200, 91,236,165,216,237,160,109,105, 75, 71,148, 58,116, 2,
+165,237,160,147,254,149,116,111, 4, 1,138, 77,183, 14,175,167,193, 51, 34,234, 91,124, 71, 68,221,234,168, 11, 12,165,181,182,
+133, 30,224, 81,202,146, 61,189,116,140,144, 2, 50, 78, 89, 59,171,195,211,212,138,182, 27,219, 41,142, 0, 14,186,144,154, 58,
+248,125, 8,114,160, 3,176,126,204,132,212,247,169, 52,239, 74,244,212, 60,144,209,201,204,242,157, 56, 17, 95, 78,180,225,145,
+229,202,155,101,145, 13,184,109, 55, 18, 4,117,149,209,215, 42,228,133,164, 41, 74, 52, 34,137, 73, 77, 27, 29,255, 0, 88,245,
+ 89,213,179,151, 59,146, 14,181,145,115,125,190,182, 57,199, 21, 76,248,215,145,211,140,242,163,165,171,116,104,238, 54, 86,180,
+ 45, 79,184, 3, 45,133, 39,113, 81, 46,116,220,154,214,157,251, 26,246, 58,246,225,107,227,219, 12, 86, 43,101, 40,109,193, 97,
+ 93, 82,196,121, 95,248,139, 45, 21,148,237, 93, 37,173,208,242,194,148,231, 90, 3,212,149,117, 61, 62,159,126,178,171,251, 77,
+ 39, 37,164,217, 82,152, 20,117,179,114,203,237,178, 86,225, 9,216,133, 5, 36, 62, 84,148, 37,190,128,128, 71, 82,170, 10,127,
+155, 85,217,160,167, 5, 50,219,109,121, 59,220,164,246,190, 75,146, 29,222,242,212,146,146,221, 82, 30,170,148, 54,246, 42, 29,
+125,154,143,115, 40, 83,151,217,106, 20, 71,140, 87,147,102, 54, 91,113,185,169, 15,182,132, 6,127,108, 66, 66,139,106, 65, 86,
+202,208,147, 90, 26,251,188, 52,164, 64,147, 85, 87,220,246,230, 16, 90, 70, 7, 63,104,226,132, 62,169, 57, 61,211,131, 34, 51,
+215, 18,235,229,213, 50,138,172, 44,186,242,130,146,163,186,157,118,161,180,142,189,117,122,229,118,126,101,122, 1, 84, 59,219,
+ 33, 27,234,214,208, 23, 15,180, 31,125, 74,187, 28,109,200, 50,177,222, 53,199,172,107, 66, 28,140,187, 85,185,144,202,157, 45,
+ 58, 80,148,238,120,182,160, 79,196,133,245,160, 73, 53, 53,246,234,189,186, 60,248,142,175, 74,106,221,173,183,211,153,154,104,
+224, 73,175, 14,170,246,143, 82, 20,101, 60,155, 37,115, 30,112,203, 89,116,184, 28, 90,139,169, 91,205,135, 9, 27, 86, 0, 21,
+165,105,184,143, 15, 17,215, 80,199, 53,123,177,218,195, 24, 5, 5, 50,254,132, 13,202,185, 79,201,142,202, 11,239, 0, 20,168,
+231, 96, 90,214,193, 80, 37, 42, 5, 53,162, 72,168,210,140,139, 82,153,138,207, 70, 52, 67, 91,143, 36,201, 67, 49,103,124,246,
+192,242, 54, 21,182,231,154,221, 66,141, 10, 21, 90,246,219,211,234,211,152,224,175, 4,232,194,209,128, 80,187,215, 40,164, 35,
+203, 18, 54,169, 13,186,169,104, 65, 37, 79, 38,131,114,234, 58,244,252, 67,169,236, 61,131, 79, 34,180, 92, 45, 8, 99,114,231,
+ 89,118,200,129, 77,189,243, 49,154,144,223,204,239, 90,148, 18, 8, 53,216, 79, 98, 69,107, 79,127,191, 82,214,251,118,163, 68,
+194,103,180, 98, 85, 87,229, 31, 82, 50, 31, 19, 96,218, 38,150, 82,230,199, 42, 28,216,162,158,164, 85, 41, 9, 29, 82,174,180,
+241, 21,232, 58,106,219,182,109, 32, 98,224,171,155,133,224,102, 0,160,149,135,155,238,246,235,147,115, 25,186, 61,231, 50,176,
+248,171,138, 80, 77, 8, 80, 85, 60, 64, 32,110, 79,136,166,167, 31, 98,215, 10, 81, 66, 25,181, 35,171, 60,215,125,201, 35, 51,
+ 13,251,139,175,219,155, 5,159, 32,184,167,156,136,194,246, 40, 36,119, 37, 41, 82, 7,225,233, 81,184,124, 70,186,171,110,214,
+ 33,130,160, 43, 87, 47, 60, 7,117,169, 53,187, 59,153,105, 89, 92, 25, 46,200, 81,109, 33,212,183, 37, 73,112, 33,195,251,198,
+214,217, 74,146,161,221, 42,237,221, 36, 20,169, 73, 53, 23,217,137, 51, 90, 27, 46, 42, 40,228, 42,189,100,119, 59,188,201, 43,
+145, 18, 74,100,151, 10,129,101,211, 29,165, 80,211,114, 18, 20, 2, 2,207,116,143,132, 30,221, 40, 53,211,108, 35, 24, 41, 43,
+ 75,128, 74, 69, 7, 39,191,197,148,131, 26,100,132, 22, 65, 79,203,190,242,252,230,233,248,144, 82,234,149,186,148,246,246,240,
+210, 46,183,105,224,166, 99,185,225,130, 81,115,205,228,221, 16,166,222,113,164, 60,133,157,229,194, 40,107,226, 21, 69, 1,239,
+246,120,215,160,211,119, 91, 6,149, 39, 12,250,194,142, 59,150,169,184,175, 70, 84,199, 82,164, 41, 84, 74, 93,248,153, 81,235,
+208, 14,134,167,194,148,237,162, 27,122,154,209, 61,100,224,102,161,168,228, 91,205,162, 74,156, 68,215,194, 83, 83,230,180,233,
+ 42, 9, 87,114,164, 40,154,131,226, 60,125,180,211,182, 88,181,252, 18, 50,223, 22,138, 28,147, 21,199,145, 99,202,145,231, 25,
+ 11,138,243,132,149,184,210,119, 48,167, 15,115,229,146,130, 43,254,138,190,170,233,243, 54,236, 50, 81,178,110,160, 97, 85,182,
+ 30,113, 37, 59, 75,115,226,245, 21, 42,109,199, 24, 95,255, 0,179,167,254, 30,147,147,111, 29, 11,177,238, 61, 99,222,164,109,
+103, 50, 28, 74, 82,251,201,117, 62,247, 4,132,143,162,180,211, 83, 99,167, 36,227,235, 67,179, 78,204,231,138,109,176,150, 37,
+ 41, 32, 26,236, 66,148,132, 87,222, 54,208,125, 26, 39,209, 99,136, 69, 55,116,249, 87,179,200, 47,212,146,255, 0, 83,248,202,
+ 82, 66,148,125,229, 69, 32,255, 0,209,209,190,132, 20, 95,171, 62,158,159,114,111,123, 53, 47, 85, 33, 97, 67,189, 11,155,232,
+127,212, 70,212,159,174,186, 89,182,148,224,146,117,197,120,166,119,239,114,165, 13,169, 93, 82, 79,224, 0, 37,160,125,189,170,
+147,227,248,116,233,144,209, 53,123,245, 38,199,228,182, 13,100,203,165, 0,248,124,194,178, 65,175,116, 0, 65,251, 6,157,199,
+ 11,157,144, 77, 37,115, 71,204, 87,134, 64,154,234, 24,137, 9,249, 78, 42,155, 21, 44,169,148, 40, 31, 4, 36, 20,169, 94,224,
+ 21,169,139, 77,181,242,154,125,152,168, 75,253,210, 43, 70,151, 83,214, 77, 7,188,163,198, 11,193,217,126, 88,227,102, 61,174,
+ 82, 90, 81, 70,253,177,132, 38,130, 21,223,113, 72,113,245,125, 99, 87,205,171,148,228,150,132,179,252, 95, 5,140,243, 79,154,
+ 86,155,112,112,241,129, 61, 12,199,255, 0, 81,253,171,161,124, 83,233, 50, 28, 4, 69,147,118, 82,131,148, 69, 81, 29,180,237,
+ 71, 95, 31, 49, 42, 53,247,237, 4,107, 75,219,185,109,144, 1,168,251, 48, 11,204,188,203,230,148,183,196,136, 88, 0,233,117,
+ 92,126, 30,229,118,113,254, 35,197,172,172,182, 24,131,185,105, 2,139,117,229, 45, 85,251,118,143,168,106,209, 13,147, 98, 24,
+ 5,148, 95,111,115,223, 26,189,228,167,185,216,133,169, 8,167,203, 51,216,244, 35,121,169,251,116,236, 71, 69, 14,233, 73, 67,
+187,223, 29,194,158,219,168,110, 34,119, 44, 29,169, 66, 43, 83,246,104,212,210,147,173, 80,224,113, 67,214,183, 27, 46, 65,242,
+214,235,187, 80, 93, 69, 8, 4,251,198,145,146, 70,184, 35, 0,230,149, 35,191,112, 26, 81,109, 23, 89,254, 74,210,235, 91,208,
+216,218, 77, 8,247, 10,234, 24,223, 2,237, 45, 9,205,197,187,163,110,167, 21, 25,227,175, 79, 54,135,239, 39, 38,189, 71, 67,
+118, 91, 90,140,144, 30, 0, 33,106,107,175,136,235,238,215,155, 60,248,243, 92,114,221,171,172,109, 28, 12,239,195, 14, 21, 89,
+215, 52,111,130,198, 50,198,158,241, 78,217,238, 66,238, 97,120, 98,193,101,107,203,180,194, 34, 59, 17,163,141,168,218,147, 65,
+208,123,124,117,225,136, 24,232, 67,167,152,213,238,196,146,177, 89,231, 51, 59, 81,204,162,144,225,248,163, 4, 84, 99,229,255,
+ 0, 30,112, 34,230,136, 85, 30,121,132,202, 84,149, 42,157,250, 41,196,234, 15,235,166, 50,125, 70,147,225, 3,167, 87, 10,156,
+ 71,216, 82,255, 0, 64,239, 7,196,167, 21, 66, 51, 79,202, 71,146,160,121,147,176,156,158, 29,242, 34, 18, 86,152,235,115,122,
+213, 79, 1,215,118,190,200, 90,115,140, 82,225, 32,162,245,116,155,107,135,202, 80, 44,122, 60,229,252, 2,110,251,254, 47, 53,
+ 40,140,175,138, 68,118, 11,205,252, 30, 61,171,169,246,223, 91,223,182,128,131, 85, 25, 44, 79,135, 48,137,118, 94, 59,126, 82,
+144,153, 77, 20, 58,138, 36,135, 89,216,164,211,220, 70,143, 13,187, 45,197, 24, 40, 19,127, 17, 28,241,158, 48,109,128,218,203,
+105, 81,233,211,104,235,165,179, 93,212,143, 22, 60, 24, 81, 9, 17, 82,145, 65, 83,176, 31,232,208,210,128,114, 40,192,227,171,
+116,134,246, 75, 97,165,161, 66,138, 74,155, 20, 80,246, 30,157,117,195, 21, 82,204,153,204,200,168,214, 95,233,119,141,243, 40,
+171, 68,235, 76,125,234, 66,146, 62, 13,141, 36,145,220,237,163,138,247,124, 90,105, 45,139,101,204, 41,219, 30, 97,158,200,247,
+ 92, 87, 63,185,107,242,203,131, 53, 50,102, 98, 87,181, 67, 53, 82,218,143,242,105, 88, 81, 62, 3,203, 86,224, 61,149, 35, 80,
+ 23,123, 43, 29,146,208,118,159, 51,157,110, 64,144,123,232,185,181,201, 62,141,249,123,142, 22,252,132, 48,171,156, 54,234, 75,
+251, 26, 65,160,240, 1,197, 47,175, 79, 5,106,181,125,203,135,161,107, 59, 23,152,208,220, 82,142, 32,251, 85,126, 85,215, 42,
+199, 94, 49,231,179, 58, 42,155,248, 8,105,210,164,146,158,134,169,125, 18,217, 61,191, 84, 15,179, 84,219,238, 95,211, 92, 61,
+ 61, 84, 90,190,217,205,141,152, 12,125, 61,117, 82, 40, 28,139, 31,225, 19,109,200, 89,168,222,225,181, 70, 62,103,210, 88,110,
+ 40,169,241, 34,135, 85, 75,173,157,204,203,237, 87,107, 61,241,178, 12,202,152,181,157, 99,110, 0,164,217, 2,150, 83,219,229,
+ 84,194, 1,246,130,169, 18, 15,217,246,106, 18, 75, 39,179,138,176,195,122, 36,226,125,137,103,247,206, 43,227, 99, 72,157, 17,
+ 32, 0, 18,195,201,116, 26,123,150,210, 72,211, 55, 91,150,167,236,146,171, 83,185, 36, 66,221, 22,221,224,154,126, 47,226,173,
+176, 15,210,145, 19,250,116,151,132, 83,150,184, 40,188,187,168, 37, 74, 96, 76, 74, 85, 90,249,146,252,234,253, 96,160,125,218,
+ 80, 51,165, 28, 59,161, 70, 39, 92,101,117,163,143,164, 43,185, 32,138, 15,119, 90,159,183, 74,177,128,174,153, 72, 94, 33, 94,
+ 37, 71, 79, 73,243, 81,224, 82,220,197,179,187,233, 27, 71,233,215, 29, 16, 57, 0,150,100,253, 37, 75, 44,217, 85,193,167,146,
+219, 47,161,167, 87, 80,151,254, 89, 51, 38, 83,222,165,162,163,233, 7, 77,164,133,167, 52,229,179,156,134, 30,180, 86,177, 74,
+184, 73, 32,200,148,151, 26, 61, 92,157, 33,192,157,139, 3,226,166,208, 80, 40, 15,234,159,164, 87,187, 73, 3, 90,156, 49,196,
+231, 95,106,121,184, 78, 88,109,198,216,146, 11,203, 66, 82, 31, 8, 79,152, 26, 39,105,218,146, 21,177, 53, 85, 7, 80,123,244,
+215, 40, 56,174, 52,145,151,218,134,178,110,115,209, 55,107, 42, 91,168, 64,162,144,168,233,121,213,212,117, 63,132,168,110,247,
+159,176,105, 66, 26,236,215, 42,225,149,125,165, 20,112,219,200,249,119, 29,152,211,170, 81, 40, 75, 45, 15,138,133, 95,133, 39,
+161, 66, 7, 74,252, 41,169,240,241,164,109,205,184, 39, 10, 35, 58,229,225,184,146,141,208,108,207, 92,173,146, 71,152,131, 86,
+157, 83,160,199, 37, 1,231, 7,198,175,197, 83,229, 2, 58,251,189,218,113,181,184, 68,240,104,170,155,255, 0,230, 50,149,173,
+ 87, 54, 57,122, 44,140, 31,145, 35,220,195,101,134,151, 37, 81, 74, 66, 9,248, 79,180,251,135,127,179,219,173,159,105,156, 94,
+219,150,117, 44, 51,123,128,216, 92, 54, 94, 4,209, 91,190, 57,206, 29,122, 52, 67,243,110, 10, 33,151, 22,217, 73, 74, 94, 69,
+ 1,160, 81, 27, 77, 21, 90,117,233,223, 84,237,202,216, 2, 66,186,237,179,235, 0,245, 43, 59, 3, 43, 50,159,109,214, 92,242,
+ 90,152,182,207,149, 90,249, 36, 80, 80,251,106, 15,183,244,106,159,115, 8, 10,221,107, 82, 58,209, 46,211,145, 56,243,237,161,
+ 50, 77, 55, 36,173,212,141,219,204,116,245,240,246, 54, 53, 5, 60,116, 83, 81,138,132,105,199,242, 71,218, 75,106, 11,248, 86,
+221, 20,186,238,222, 73,218,107,225,210,162,135,233,211, 65, 80, 83, 27,155,118,184, 98,131,158,167,114,119, 87, 98,199, 45,197,
+ 94, 98, 38,221,109,204, 33, 33,192, 64,249,135, 54,168, 0,107,208,212,138,107, 68,229, 65,139,143, 67, 10,204,119,152, 64,125,
+ 71,239,171,201,101,191,110,194,227, 33,199,234, 99,177,103, 16,156,113, 97,111, 4, 80,212, 3,227, 80, 62, 46,190,239, 19,170,
+126,229,139,220,122,211,253,178, 26, 57,180, 25,135, 87,211,211,165, 5,242,204,185, 45,174, 66, 43,180, 58,241, 42, 85, 11,110,
+ 36, 55,218,135,168, 29, 9,173,126,173, 48, 96,247,171,148, 22,196,129,212, 61,190,156, 21,122,201,115, 79, 45, 69,164,186,250,
+ 93, 14, 85,179,224, 64, 37,123,171,212, 0, 82,175,135,223,169, 40, 33, 75,150,209, 9,175,185,124,244, 66,253,130, 82, 91, 15,
+ 45,231,130,222, 44,169, 41, 64, 79,106, 2,146,146,146, 69, 9,241,250,245, 39, 4, 34,184,166,178,132, 53,186,231, 51,154,113,
+ 15, 45,199, 99,169,192, 23,230,184,160,166,234,201, 41, 82, 71, 94,181,222, 9, 73,212,196, 22,192,168,169,164, 33, 9, 51, 12,
+218, 99, 48, 11, 81, 93,102, 80,154,208,113,214, 90,125, 43, 90, 29,222, 66,104, 58, 41, 91, 71,122,120, 26,106,122,206,220, 19,
+138,129,187,184, 45,174, 42,176,207, 93,230,237, 41,113,255, 0,135, 78,249,151,205, 90, 18, 26, 40,124,161, 38,187, 82,173,180,
+ 87, 69,119,255, 0,155, 86, 70,189,144,182,160,133, 91, 45,117,203,232, 83,211,216, 77,242,223,229, 9, 14,249, 5,149,180,239,
+205, 33,123,148, 89, 86,197, 5, 0,146,122, 40, 18, 8, 52,234, 59,246, 58, 96,253,213,180,238,138,149, 49, 22,209, 83, 87, 26,
+ 5, 58,176,242, 6, 25,131,180,182, 62,110,125,202,242,226,130, 22,244,104,222,100, 84,111,248, 78,239, 48,169, 95, 8, 61, 42,
+132,143,121, 20,212, 77,205,173,206,227,141, 0,106,145,135,114,178,219, 8,109, 73,119, 98,154, 94,243,118,230,170,205,118,180,
+ 58,243, 81,238, 48, 75, 19, 89, 74, 60,160,137, 97, 69, 14, 80, 1,208, 44, 39,112, 3,218,117, 90, 54,142,133,197,174,224,174,
+150,215,204,184, 96,112, 79,255, 0,222,197,206,183, 71,142,234, 84,185,145,227, 41,214,229,237, 62, 96, 43, 5, 65, 39,167, 93,
+201, 88,168, 62,207,110,144,146, 26, 98,164,237,228, 0,208, 21, 17,186, 95, 38, 57,251,112,162,130,157,168,113,135, 58, 36, 32,
+208, 29,164,138,209, 11, 31, 9,238, 1,241,165, 2, 30, 29, 20,204, 82, 12, 13, 83, 89,185, 46,107, 41,113,135,219, 18,218, 89,
+ 66,171, 37,176,242, 72,254,177,221,241,130, 13, 15,212,124, 73,210, 46,101, 48, 57, 41, 88,164, 4, 84,102,153, 46,203,148,144,
+151, 30, 64, 96,168, 20,238, 15, 35,200,112, 38,149, 41, 53,232, 64, 34,169,253, 3,166,143, 27, 42,131,174, 20, 62, 67,171, 52,
+164,166,220, 0,212,183,184,173,212,110,241, 65, 72, 36,255, 0,178,122,248,233,244,108,233, 76,101,156,156,147, 44,152,209,214,
+175,218, 58,164,212,212, 45, 9, 36, 1,237, 53, 64, 61, 60, 77, 62,189, 60,104, 33, 70,190, 64,252,210, 93,178, 35,245, 67,190,
+107,126, 7,171,106, 62,207,196, 61,158,253,116,128,228, 80,242,196,169,171,171,141,157,171, 75,137, 52,238, 21, 81,245,145,211,
+ 73,186, 26,167, 12,185,162,115,110,231,188, 3,243, 73, 29, 63, 10,223, 82, 72,251, 8,210,126, 13, 56, 37,126,166,188, 82,214,
+238, 44, 10, 21,201,100, 82,149, 27, 67,180,250, 10,138,244,113, 1, 60, 23, 13,200, 25,148,164,223,162, 50,158,142,173, 84,241,
+ 89,223, 67,238, 0, 4,141, 57,138,196,191,130,109, 38,226,216,248,175, 12,223,102,220, 29, 17,109,177, 39,207,121, 71,106, 90,
+134,202,156, 11, 39,195,107,105, 63,118,166,237, 57,122, 91,131,221,105,246, 42,230,229,205,246,187,120, 38, 89, 26, 59, 72, 8,
+185,133,241, 39, 33,101,242, 89,109, 54,249, 22,164, 60,177,229,160,177,181,253,181,234, 13, 79,156,107,226, 41,245,234,239,182,
+114, 51,158, 65,144, 44,119,153,124,234,183,179, 4, 64, 65, 61, 35,227,146,232, 23, 19,122, 83,118,216, 89,153,123, 76,229, 56,
+ 10, 75,161, 81,155,132, 55,159, 16,161, 85,147,254,199,219,173, 19,110,229,136,173, 6, 66,171,206, 60,207,230,165,214,236, 72,
+ 14, 52,237, 39,211,218,186, 37,132,113,149,178,205, 18, 58, 98,198, 3,203, 74, 54,170, 72, 50,220, 27,127,210, 90, 81,247, 13,
+ 89,162,180,108, 98,128, 44,162,243,117,150,233,196,185,199, 20,114,182,218,102,180, 19, 70,193,106,128,116, 77, 0,167,232,211,
+182,198, 2,139,115,201, 68,107,102, 19,119,186,197, 91,236, 54,162,132, 2,105, 74,147, 77, 55,150,237,144, 16, 10,115, 13,155,
+231, 26,130,140, 72,177,191, 21, 79,137, 44,188,149,178,162,149,111, 71,195,211, 78, 90,240,241,130,108,232,203, 14, 33, 71,211,
+145,199,176, 73, 15, 24,168,125, 64,209, 40, 80, 29,254,195,164,166,139,197, 20,170,236, 83,120, 38,180, 73,231, 94, 35,229, 15,
+249,210,219, 76, 82,158,168, 66, 82, 18, 5, 58,251, 52,193,209, 8, 5, 2, 52,151, 62, 49,169, 91,109, 86,233,183,137,200,128,
+151, 87, 38, 10, 8,222,165,157,201,109, 31,243,107, 47,243, 23,157,109,249, 38,197,243,200, 64,125, 14,145,214,161, 55,141,220,
+ 89, 70, 75,143, 98,129,243, 30,105, 26,223, 25, 56,110, 62,164,164,130, 27,144,166, 8, 27,215,216,214,158,195,175,154,183,215,
+211,115, 45,228,151,247, 36,157, 68,145, 94, 1, 96, 91,182,226,111,164, 46, 37, 49, 96, 56,220, 12, 62,210,246, 99,145,165, 1,
+ 77,161, 78, 68, 97,208, 55,186,179,212, 26, 31,126,141,180,108, 23, 92,239,122,219, 27, 64, 72,175,120,142, 1, 43,178,237, 79,
+220,164, 20, 24, 33, 58,185,186,238,121, 45,171,233, 82,188,132, 71,145, 13, 16, 55,143,248,107,142, 54, 84,118,253, 41, 79,134,
+189,172, 60,147,176, 27, 1,217,232,223, 20,128,250,241,212, 1, 31,122,215, 63,145,199,224,125, 62, 26,169, 85,105, 56,239,159,
+ 99,130,205,169,247, 31,113,101, 97, 42,146, 20, 41,215,232, 38,186,191,178, 23, 55,230, 90,191,212, 12,193, 86,174,215,147, 99,
+247,232,202, 98, 98,225,220,153,121, 52, 91, 82,153, 75,138, 9, 87,133,123,142,250,148,134,228,195,242,166,238,252,195,138,134,
+101, 92, 27,198,249, 19, 95, 49, 22,222,221,182, 75,149, 82, 95,142, 62, 29,199,175,116,245, 31, 94,166,109, 55,217,225,235, 9,
+ 25,108, 98,120,235, 80,248,252, 3,106,179, 49,230,169,215,159,105,176, 85,185, 40, 42,248, 71,191,199, 82, 45,230, 41, 36, 56,
+ 4,172, 59,100, 36,119,138,129, 75,110,213,110,184, 46, 36, 87, 85,177,181,109,218,180,237, 80, 35, 87, 11, 25, 93, 51, 3,156,
+160,174,218,216,158, 67, 78, 10, 71, 26,124, 22,155,220, 85, 94,158, 58,144, 1, 54,213, 68,241, 26,116, 71,146,130,146,165, 21,
+ 40, 36, 4,138,232,218, 80,214,167, 81,172, 17,101, 50,133, 45,162,160,164,131, 66, 59, 87,234,210, 46,183, 5, 28, 52, 21,226,
+225,128,227,247, 24,110, 71,151,107,105,244, 41, 36, 41, 75,100, 59, 64,125,197, 42,175,253, 29, 36,251,112, 66,125,111,112, 96,
+ 53,105, 92,229,245, 31,232, 47, 9,207, 26,151,115,177,216,227, 70,186, 41, 46,184,159,144,112,192,146,227,148,173, 10, 20, 29,
+ 65,167,127,137, 34,189,186,106, 18,247,105,100,195, 37,162,242,247, 58,207, 96, 64, 46, 52, 92, 34,229,207, 77, 25, 71, 28, 92,
+231,199, 92, 57,187, 98, 56,176,182,229,193, 16,228, 33, 3,177,166,237,170, 29, 59,143,179, 84, 13,207, 99, 45,174, 11,208,124,
+187,206, 45,187, 13,196, 99,214,171,161,129, 50, 34,202, 92,133, 37,162, 15, 85, 24,170, 74,107,244,237, 3, 84,123,205,184,181,
+106,155,126,238, 31, 74, 39, 22,204,148,237, 11, 64, 64,238, 3,195,203,233,238,221,183, 85,233,172,232,173, 86,247,225,195, 48,
+151,137,113,154, 21,120,198, 73, 20,248, 84,226, 93,175,253, 20,171,238,212,123,237,143, 10,169,120,239, 27,196,133,249,252, 74,
+ 19,134,141,180, 82,127,172,195, 66,132,253, 42, 72,210, 14,183, 35, 52,241,151,141, 57, 47,199,149,230,166,136, 83, 77,214,180,
+243,221, 67,117,250,104,122,253,154, 32,102,148,231,197,212, 51, 90,226, 88,190,108,146,150,162, 33,125,212,247,204,164, 52, 62,
+159,215, 3,253,157, 9, 30, 90,187, 21, 30,114, 78,241,173,255, 0, 42,232, 30, 99, 82, 10, 18,167, 22,136,224,166, 59,109,163,
+250,238, 80, 30,254,192, 73,240,166,153,189,245, 82, 76, 97, 10, 97, 26,255, 0,241,180,220,138, 20, 71, 9,109,182, 80, 54,178,
+134,199, 90, 4,142,149, 81, 52,169,250, 79,183, 72, 24,186, 18,190, 33, 82,152,215, 84,190,101, 33,105, 1,114, 16,180, 34, 65,
+233,229,166,160, 31, 14,149, 42, 87,214, 52, 60, 35,130,239,140, 49, 28, 86,155,115,107, 83,146, 96,184,210, 18,228,228, 44, 23,
+ 43,181, 73,220, 16,224,161,236, 40,215,109, 22,104,240,175, 66, 52,115,240,233, 68,171, 83,112,194,218,128, 18, 80,229,189,111,
+121,169, 64, 30, 81,149,181, 36, 19,216,144, 15, 83, 83,250,117, 20,242,106,187, 33, 14, 10,199,218,110,173, 69,128,184, 86,136,
+204,169, 81, 80,175, 61,247,213,188, 72, 80,234, 13, 7,227, 33,207,137, 41, 53, 4,128,105, 94,234,195, 88,187,206, 85,155,214,
+ 11,151, 80, 84,174,127,250,159,132, 46,201,129, 39,203, 73,145, 29, 70,128, 52, 2,150, 82,126, 34,104,107,210,190, 35,191, 93,
+104,156,169,184, 22,146, 56, 21,159,115,142,212,215, 70, 58, 70, 52, 73,248,165,217,142,218, 33,121,166,136,138, 27,105,208, 7,
+194, 84, 18, 0, 79, 64,107, 74, 84,253,154,113,188,150,135, 26, 38,251, 11, 28, 88, 42,173,101,142, 74,130, 91,119,112, 42,108,
+ 54,210,129, 73, 53, 86,228,130,175,252, 33, 79,118,169, 55,101, 94,109, 89, 76, 17, 62,197, 57,214, 92,171,109, 18,209, 59,201,
+ 35,175,225,234,144,125,138, 42,212, 5,205, 10,156,133,132, 4,124,199,164,173,224,210, 27, 36, 33, 38,181,240, 0, 10,119,175,
+186,154, 96,198,211, 19,210,155, 94, 30,174, 30,244, 27,245, 3, 37,110, 79,227,232,221, 54,202,203, 44,168, 80, 40,248, 82,148,
+190,215,126,148, 35,175,134,180, 46, 91,104,107, 36,112,253,194,179,125,213,165,242, 6,145,248,253, 62,229,122, 35,188, 98,216,
+224,199, 82,128, 66, 26,101,109,146,146,122,134,201, 74, 72,236, 42, 77, 69, 71,142,168,215,175,171,207,106,154,219,225,168, 36,
+ 14, 31,122, 0,101,183, 83,189,105, 82, 87,230, 40,212,188,163,184,173, 68,124, 42,234, 58, 18,118,244, 3,182,155,194,117, 43,
+ 91, 33,208, 48, 85,235, 35,124,190,226,165,168, 45, 44,161,176,143,216, 54, 77, 16,181, 37,117, 20,246, 42,189,125,250,156,132,
+211, 4,221,205, 60, 16,250,241,118,249,184,113, 89, 75, 42, 66,233, 41,133,170,133,104, 95,151,240,251, 13, 69, 85,247,234, 78,
+ 22,128, 83, 9, 88, 66, 18,100, 50,156, 45,183, 29, 77, 48,241,136,181,200,109, 46,160, 45,109,165,224,144, 80,146, 83,215,162,
+106, 8,239,169,155, 98,162,174, 34,169, 65,123,140, 27,166, 65, 45,152,171,218, 35,151, 82,151, 22,175,132, 54, 31, 33, 33, 93,
+136,160,160, 36, 13, 79,199,114,203,118,215,138,129,154,201,215, 46,234, 79,211,113, 37,241,234,219, 83,178, 38,135, 10, 80,235,
+ 44,148,135,108,242, 0, 3,106,208, 20, 84,219,190,208,180,138,119,241,211, 99,126,111, 78,145,146, 85,182, 12,181,110,179,154,
+ 12,228, 89,125,247, 46,185, 23, 37, 41, 98,211,107,171,115,110, 17,165, 59, 2, 76,199,146,104,164,254,205,126, 64, 0, 82,128,
+ 50,122,116,165,117, 55,244,209,237,209, 52,211,190,243,135, 80,233, 85,215, 54,109,214, 71, 59, 81, 17, 51,222, 86,235, 51, 22,
+155,156, 37, 6, 90,184, 70, 44,149, 56, 31,113,104,154,181,164, 36,238, 36,143,150, 9, 10, 2,191,129, 84,246,211, 72, 75, 57,
+131, 19, 68, 72,172,126,160,208, 2,146,204,249,196, 76,141, 10, 45,196, 56,132,186,154,199,145,189,181,182,181,110, 1, 1, 74,
+ 72,110,161, 36,214,170, 29,123, 14,154,136,146,147,146,105,154,182,218, 7, 89,180, 10,224, 17,174,223, 5, 76, 68, 98, 25,218,
+169, 44,188,228,119, 92,109, 73,121,103,207, 8,248,137, 73, 53,218,190,222,234,106, 22,226, 60, 85,154,198,238,162,189,106, 55,
+116, 66,148,137, 13, 16, 90,145, 31,204, 75,137, 90,104, 23,177, 73, 53, 73,255, 0, 73, 4, 83,232, 35,199, 76, 75,104, 85,162,
+ 9, 3,155,130,142, 51, 41,216, 78, 9, 36,146,209, 41, 46, 4,244,113,167, 18,104,124, 62,191,163,220, 70,136,230, 87, 4,254,
+ 41,169,138,147,220,242,104, 47, 91, 11,101,180,188,210,188,176,246,209, 71,163,188,216, 32, 21, 14,129,105,161, 37,181,130,149,
+ 38,165, 36,169, 21, 10, 17, 65,138, 66,230, 93, 38,160,161,146,228, 33, 43, 91,145,164,146,157,253,252,133, 60,193,175,138,246,
+130, 69,125,187, 65,251,245, 34,200,171,154,140,146,242,139,203,153, 34, 67,101,151,252,167, 40, 41,240, 32,148,244,237,209, 73,
+ 74,197, 60, 0, 58, 93,182,253, 9,163,239,131,243, 76, 98,251, 34, 35,133,200,143, 81,181, 18, 10, 8,222,209, 7,184, 82, 77,
+122, 31, 26,253,122, 84, 91,106,205, 54, 55,218,120,224,151,167, 43,140,226, 3,119, 91, 66, 36, 71, 38,165,232, 36, 52,176,125,
+201, 82, 92,100,125, 73, 26, 59,108,201,200,164,223,184, 1,141, 22,135,101,226,242, 13, 98,203,184, 71,113, 85,163, 75,128,165,
+ 0,124, 7,236,158, 36,253, 59, 6,158, 67, 96,247,102, 19, 9,183,134,199,199,211,212,165,120,206, 7,117,203, 31, 67,118,137,
+147, 26, 65, 35,115,162, 51,254, 71, 94,213, 82,163,183,182,191,235,106,195,101,177,153,127, 8, 85, 13,223,156, 91,102, 13,100,
+ 35,214, 63, 97, 87, 91,137, 61, 10,223,179, 9,108, 57, 62, 91,110, 37, 93,126, 43,235, 79, 41, 53,236, 84,219, 44,202, 90, 63,
+218, 3,216,117,122,219,185,105,173,196,128,177,142, 98,243, 61,205,168,105,113,245, 31,190,139,166,220, 87,249,121,218,172, 13,
+ 50,253,193,112,119,252, 11, 86,216,206, 78,220, 62,135, 67, 45,167,223, 65,245,106,233,103,181, 54, 17,146,197, 55,158,119,150,
+249,199,230,246,209, 93,220, 99,211,254, 37,140,182,203, 76,199, 72, 20, 66, 93,105, 8, 34, 51,129, 61, 40, 80,189,255, 0,118,
+166, 35,128, 53, 81,238, 55, 7,204,106, 81,134,219,128,216,219,218,204, 56, 72, 36,244,218,145,254, 77, 45, 77, 24,148,202,166,
+ 66,143, 88, 23, 22, 88,174, 13,173,187,140, 34,193, 73, 27,104,222,208,117, 23,125,120,232,126, 82,165,246,253,189,179,252,225,
+ 17,175, 60, 77,143, 34,216,182, 96, 55,229, 58,132,252, 46, 17, 93, 68,183,115,146, 39, 85,216,133, 47, 46,209, 19,219,165,184,
+ 20,201,143,219, 19, 97,138,228, 87,214,151, 13, 72, 31, 15,134,152,223,223,125, 65,212, 18,214, 86,102,213,186, 78, 41, 37,214,
+211,103,186, 70,148,210,163,180, 30,113, 10,163,155, 40,119, 17,162, 91, 94, 75, 25, 6,184, 46,220, 88,199, 43, 78, 24,170, 95,
+200, 88,143,240, 41, 33,249, 46,160,180, 93,171,105, 21,232, 60, 59, 83, 86,155,109,196, 92, 10, 42,109,245,145,181,196,161,183,
+206,166, 84,150, 33,196,108,170, 67,171, 75,109,132, 14,167, 81,187,190,231, 30,219, 11,230,148,209,173, 21, 42, 26,121,132, 64,
+146,138, 57, 29,210, 55, 25, 97,228,154, 42,247,114, 97, 74, 53, 31, 27,123,199,219,175,153,222,106,243,220,190, 96,110,142, 99,
+ 79,228, 70,104, 58, 13, 22, 59,205, 59,187,174, 94, 88,220,149,110,195,241,149, 93,230,202,204,114, 85,148, 91,216, 82,164,171,
+205,233,230, 41, 38,161, 34,191,126,169, 80, 91,203,186,204,203, 11, 65, 87,184,211, 14, 29,106,171,183,237,239,220, 36, 13, 1,
+ 4,253, 64,250,132,180, 90, 96, 60,241,117, 45,219,160, 37, 77,195,134,130, 7,158,180,116, 29, 63, 70,189,181,200,124,153,107,
+229,133,144,115,128,117,203,198, 61, 85, 90,245,180, 81,114,228, 63,215, 43,150,191,227,118,116,172,188,114, 47,202,188, 49,182,
+ 94, 85,179,228,246, 26, 42, 60,149, 5,239,237,225,229,119,247,234,111,235,238,181,253, 94, 57,168,159,172,159, 95,212, 99,154,
+170,216, 95,173, 62, 93,195,214,211, 55,105, 19,210,226, 72,171,143, 54, 85, 74,125, 52, 86,183,155,142, 93, 99,178, 11, 95, 15,
+ 5, 95, 14, 29,252,202, 47,113,165,198, 23,139,155, 78,174,160, 22,214,229, 20,174,221, 62, 42,106, 18,126, 94, 13, 61,208,148,
+ 50,144, 48, 93,103,226, 63,204, 19, 10,201, 35,179, 30,244,251,113,156, 81, 1, 42, 42, 9, 21, 63, 65,211, 57,246,215, 66, 48,
+ 9,171, 46,141,113, 87,239, 10,245, 15,131,229, 17,155,102, 4,248, 50,188,208, 16,164, 40,165, 71,226, 30,194,117, 9, 51, 93,
+ 17,201, 75, 67,114, 28, 40, 82,252,147, 12,197,111, 46, 38,239, 13,168,229,197, 40, 56,164, 50, 71, 90,245,246,234, 74,203,122,
+146,216, 82,184, 36,102,182,100,166,180, 66, 44,210,221, 18,216,227, 0, 91,220, 98, 55, 77,206,165, 6,180,247,211,191,213,171,
+158,211,185, 11,161,139,177, 81,183,241, 6,252,173,162,149,226, 13, 91,102,178,209,137, 16,190, 17, 79,136, 38,163, 83,198,102,
+179, 50,154,199, 9,126, 65, 23,161, 42, 50, 64,108,160, 33, 73,232, 80, 69, 8,166,150, 14, 4, 85,116,247,112, 42,109, 3, 27,
+153, 61,159, 61,136,171, 83,116,174,237,158, 26, 65,247, 81,180,208,148,230, 59, 87,200, 42, 2,107,185, 89,216, 70,248,179,162,
+160,146, 40,164, 56,158,132,125, 30, 58,238, 18,138,132, 59,208,154, 28, 10,171,156,193,192,248,143, 32, 91,100, 64,122, 51, 45,
+169,212,168,182,159,194,194, 29, 35,162,130, 0, 83, 34,135,191,236, 73, 62,209,166,115,216,182, 97,136, 83,123,103, 48, 75,183,
+ 56, 22,185,113,115,158,255, 0, 47,140,162, 11,146,230,226,209, 81, 33,194, 86,235, 73,255, 0,116,216,180, 3, 83, 70,148,132,
+200, 81, 39,183, 65,170,158,225,203,173,147, 16, 61,235,100,229,223, 50, 52, 80, 72,104, 59, 62,245,203,204,251,132,121, 51, 13,
+152,252,107,181,130,227, 11,203,174,229,179,109,113,166,214,132,215,226, 5, 44, 32,125,167, 84,139,221,132,199, 94,233, 91, 30,
+209,206, 17, 94, 0, 89, 40,247,124, 80, 38,108, 73,112,220, 41,146, 86, 20,158,132, 57,209, 95, 93, 15, 77, 85,238,118,226,206,
+ 10,243,105,187,135,211,189, 84,222,153,233,108,254, 52,251,232,170,159,180,171,250, 53, 13, 45,153,232, 83,208,110,173,233, 78,
+209,111, 73, 52, 31, 17, 20,165, 66,202,212,145, 79, 5, 84, 1,168,249, 45, 72,205, 77, 91,238, 65,235,107,183, 7,183, 18,210,
+154, 91, 66,138, 80,109,127, 48,225,250, 77,118,163, 72, 58, 42, 41, 56,238,189,137,238, 28,185,178, 82,132,238, 13,249,174,161,
+150, 89,175,196,235,202, 32, 15,122,233, 94,231,166,153, 62, 32, 20,155, 46,117, 10,156, 20,182,200,152,115,238,139, 90,151, 91,
+123, 14, 53, 29, 46, 5, 80,190,150, 65, 82,148,145,226, 86,150,212,226,186,244,162,143,122, 2,147,152, 90, 17,196,213, 53, 78,
+242,166, 41,210,129, 27,246,126,115,137, 67, 91, 1, 9,222,122,132,247,253, 98,163, 77, 43, 20, 88, 98,144,158,228,106,193, 76,
+ 45,243, 18,203, 80, 31, 77, 29, 89, 82, 86,224, 63, 18,210,182, 84, 91,160,250, 80,223, 79,118,145,154, 44,215, 89,115, 90, 83,
+ 53, 53,143, 45,108,249,103,104, 6, 67,206,124,194,136,170,156, 45,249,106,173, 79,176,171,175,249,181, 0,241,223, 82,224,248,
+145,213, 77, 83,156, 72,181, 33, 45,196,140,205, 36, 71,242, 67,139, 27,150,164,165, 98,170,167,122,210,131,254, 66,146, 12,178,
+250,134,226, 85, 90,226,239,233,158, 59, 85, 77,228,153,247, 71,242,233,104,155,185,105,122, 35,114, 35, 23, 42,180,132, 44,170,
+170, 2,164,118,160, 61, 7,134,174, 91, 75, 88,203, 96, 88, 49, 6,133, 82,247,121, 95, 37,229, 30,106,210,218,142,132, 82,226,
+232, 32, 68, 83, 64,211,162,148,134,194, 42, 22, 86, 19, 90,247,174,225, 90,234, 43,115,186, 46, 56,169,173,186,200, 54,148, 86,
+ 30, 4,111, 36,151, 62, 53,169, 9, 82,203, 65, 53, 82, 31, 95, 80,122,119, 2,190,221, 85,230,158,170,207, 13,176, 68,156,118,
+ 42, 95,108,168, 29,235, 11, 90,202,191, 84, 16, 54,154, 87,218,138, 43, 81, 55, 15, 53,162,127, 27, 0, 10,194, 98,150,221,206,
+182,144,218, 70,226,146, 2, 7, 90, 30,170, 30,207,113, 26,107, 27,170, 84,118,224,116,180,159, 90, 24,115,125,129,215,115,206,
+ 36,138,170,184, 29,202,237,235, 13,211,104, 40,142,235, 42, 90,128,241,169,168,213,251,151,222, 91, 4,238, 57, 6, 42, 21,235,
+ 91, 52,141, 0, 99, 82,126, 10,241,101, 22, 19, 26,215, 21, 45, 44, 7,140, 68, 53,176,130,216, 87,236,210, 18, 69,124, 8, 2,
+157, 61,221,206,168,247,111, 15,126, 41,254,205, 33, 0,208, 97, 95, 64,170, 54, 87, 14, 66,228,190,165,108,218,210, 28,105,213,
+210,149, 82,200, 77, 83, 79, 16, 77,126,145,164,152,224, 50, 87,136,104, 91, 67,154, 15, 93,227, 74,109,127, 47, 64, 2, 10,138,
+182, 38,165,208,216,252, 61,104, 73, 21,160,247,105,252, 51, 35, 62, 22,144,160,179,162,178,218,159, 99,104,105,216,236,170, 91,
+ 98,132, 43,106, 72, 10, 59,189,133, 52,168,247,215,196,234, 82, 57,141, 19, 7,193, 83,212,134,215, 40,112,101, 5,165,106, 79,
+158, 9, 66, 84, 7,130, 8, 52, 61,234,126, 26,244,255, 0,157,236,119, 78,102, 73,180,150, 33,217,161,109,242,124, 11,119,157,
+ 21,230, 24,105,242,133, 38,155,147,229,184,147,241,111, 66,203,129, 64,215,175, 90,143, 17,169, 43,114,249,241, 5, 71,220, 53,
+144, 12, 66, 8, 92, 50, 43,138,221,121, 51,221,117,216,225, 10, 76, 85, 51, 43,206,144,151,151,240,182, 60,192,225,232,163, 67,
+219,234,233,171,118,221,100, 28, 71,189, 81,119,107,215,184,233, 30,165, 10,205,157, 93,153,118, 44, 46, 2,219, 92,185, 80, 25,
+185,221,203,138,243, 30,107,231, 85,240,149, 26,212, 16,145, 90,253, 30, 29,229,167,104,153,230, 83,147, 69, 7,106,109,122,243,
+103, 28,118, 76,249,156, 42,238,206,180, 84,198, 95,139,107,133, 36,174, 51, 18,210,182, 25, 97, 1,109,160,165, 11,120,117, 82,
+168, 65,236, 13, 7, 79,232,213, 54,246, 83, 43,176, 86,157,186,204, 66,209, 84,223, 49,136,207,188, 82,211, 8, 67,193,213, 56,
+226,207,225, 41,100, 21,172,143,115,123,194,143,180, 3,161,106,226,220,202,115,124,192,224, 40, 48, 82,155, 20,135, 35, 71, 14,
+200, 62,112,113,239,132, 56, 58, 85, 96, 57, 80,123,167,168,167, 67,174, 92, 13, 73, 59, 83,165, 55, 95,101,176,226, 21,229, 59,
+ 34, 43,201,105, 72, 93, 0,121, 47,118, 9,234, 11,100,117, 29, 40, 15,142,163,244,211, 53,100,138, 66, 64, 34,136,117,243,175,
+ 35,224, 19, 99,200, 66,182,168,161,199,188,133, 52,161,208, 16, 95,242,210,106, 5, 8, 7,173, 7,176,104,120, 58,147,166, 94,
+104,205, 52, 74, 68,196,173,110,131,186, 50,210, 65,113,129,231, 54, 1,240, 37,164,172,125,159,102,156,197, 23,181, 54,185,188,
+ 25,131,130,137,190, 97, 54,240, 82,164, 18,162, 73,162,219,117, 2,190,224, 80, 14,164,227,133,212,201, 87,166,188, 97, 56, 21,
+233,201,113,118,141,165,244,208, 10, 84,165,228, 31,183,203, 41,250, 52,179,109,201, 41,179,175,116,140, 82, 69,121, 15,168,108,
+117,196, 57, 78,149, 77, 17,255, 0,226,233,169, 8,108,220,120, 38, 18,223,179,247,168, 83,197,191, 31,187,200,112,121, 1, 74,
+169,252, 72, 59,106, 15, 99, 94,157, 62,163,169, 88, 54,210,252,194,135,184,221,188, 44,157,138,180,124, 83,233,175, 37,206,158,
+ 97,213,198, 92,116, 56,227, 97, 14,168,174, 18,215,191,173, 82,177, 25,196, 57,211,177, 4,106,106,219,104,211,138,170,238,156,
+210, 35, 4, 28,125, 61, 75,171,220, 21,232, 22,240,155,157,189,119, 59,140,255, 0, 36,184,209,249,119,147,243,110,161, 0,215,
+186, 80, 64,250,119,143,160,118,213,195,109,219,154, 27,169, 98,188,201,206, 46,169,141,163, 62,209,247,175,160, 14, 21,244,153,
+137, 97,118, 72,206,202,101,114,156, 44, 32,164,186,170,169,181, 83,176, 34,132, 15,117,116,229,247,133,134,141, 84, 25, 99,250,
+174,243,206,105,191, 49,181,183, 96,189, 61, 10, 11, 40, 17,146,163,180, 4,246, 26,179,237,239,241,227, 4,170,102,224,207, 2,
+ 66, 2,135,184,252,116,154, 73,216,154,246,240,166,164,131, 84,121,114,120,199, 36,196,114,236,195, 76, 62,134, 86,165, 1,185,
+ 95,135, 72,221, 81,172, 36,167, 54,131, 91,192, 5, 92, 11, 66,161, 91,109,205, 57, 41,246, 15,192, 10,156, 20, 3,182,168,247,
+ 18,235,121,162,188, 64,193, 19,113, 77, 55,140,211, 25,140,195,138,114,226,197, 18, 13, 82, 20, 9,233,162,182, 9, 37,192, 52,
+174, 73,119, 20, 66,164,170,247,144,242,182, 31, 29,247, 10, 39, 14,129, 71,167, 81, 81,165,142,213, 47, 16,154, 29,222, 35,197,
+ 9,110,220,233,103,142, 23,242, 65,111, 40, 87,226, 3,167,233,210,195,104,144,142,132,201,251,219, 27,146,170,153,247, 37,220,
+114,123,146,138,202,211, 25, 42,248, 82,123, 1,246,233,244, 54,194,205,167,165, 86,119, 11,243,116,122,145, 67,136,177,196, 67,
+141, 47, 56,200, 82,148, 67,136,209, 48,210,239, 77,234,240,160, 62,221,120,215,245, 33,230,113,129,131,105,179,127,125,223, 53,
+ 22,125,204,123,152,129,186, 65,197, 15,239,207, 77,228,252,189,249, 43, 90,147,103,132,247,196,181,116,101, 13, 32,248,120,118,
+ 29, 53,228, 59, 72,159, 11, 91, 27, 1,116,175, 56, 14, 36,149,149, 8,157,125, 37, 6,100,170,253,234, 71,151, 45,152,157,145,
+203, 61,174, 98, 98, 91,109,237,249,110, 33,165,109, 50, 92, 64, 35,104,167,122,145,215, 94,201,242,171,144, 99,228,155, 81,184,
+222,180, 27,151,138,180, 28,197,120,173, 58,198,194, 61,130, 16,247,124,228, 96,185, 97, 27, 31,202,249,150,252,111, 55,132,200,
+111, 29,142,233, 49,216,114,169, 67,160, 30,157, 59,107, 94,218,118, 89,249,130, 95, 26,106,233,235, 70,176,219,165,221,228,241,
+ 36,201, 30, 63,184, 80, 63,133,255, 0, 3,249, 22,190, 76,181,176,181,229,116, 36, 10, 87,233,235,173, 75,249, 29,191,211,248,
+ 26,112,251,250, 85,227,249, 92, 94, 23,133, 76, 22,158, 71,244, 85, 99,185, 45,101,171,122, 18, 0, 53, 30, 80,235,245,211, 87,
+ 22,200, 81,132,164, 42, 95,154,250, 39,143, 28, 60, 45, 49,101, 67,152,130, 75, 79,181,248, 66,135,111, 17,163,211, 89,197, 56,
+109,205, 5, 16, 14,227,197, 28,241,198, 43,249,171,107,146,110, 48,154, 36,165, 27,149,187,106,125,213,208,125,156,115, 46, 9,
+ 26, 81, 19,143,189,106,114, 71, 20, 76, 97,188,134,209,113,101,182,150,132,186,225, 43, 82, 0, 71,222, 41,168,155,174, 94,100,
+227,173, 24, 19,192,174,172,240, 71,230,123,105,186, 57, 21,139,148,221,172,186,148, 5,249,174,238, 40, 61,188, 77,117, 85,187,
+229,183,199,139, 83,134,206, 90,186, 73,141,250,153,193,249, 37,132, 48,213,206, 12,132,184,221, 82,217,116, 5, 2,125,157,107,
+168, 25, 45, 39,180,117, 64, 33, 59,138,118,188,119,149,132,227,188,211, 30,138,143, 46, 35,209,212, 10,232,161,187,181,117, 37,
+ 5,212,178,124,228,213, 62,183,186,142, 28, 40, 40,173,190, 27,135,218, 50, 4, 38,238,147,230,165, 84, 89, 74, 77, 64,212,177,
+220, 37, 3, 79, 4,233,150, 16,220, 29,106,194,219, 98,193,183,196, 12, 54,218, 27,109, 9,241,233,219, 69, 99, 76,216,149, 32,
+ 67, 97, 20, 25, 42,181,158,200, 51, 50, 25, 33,133,132,180,133, 20,130,131,223, 87, 77,186, 15, 14, 49, 85, 74,220,231,241, 37,
+ 52, 80,121, 16,216, 91, 91, 28,170,141,106, 87, 94,160,233,233,141, 48,212,181,173,152,139,140, 98, 72,140,196,214, 21,248,153,
+146,210, 95,105, 95, 74, 84, 8, 58,110,251,125, 73,120,231, 49,226,210,171,255, 0, 35,122,112,225,188,250, 52,147,123,227,203,
+ 59,207, 58,149,169,107,182,194, 98, 51,229,103,245,129, 40,162, 13,122,213, 52, 62,253, 70,207, 96,199,230, 21,135,111,230, 27,
+171, 66, 52, 74,225,218, 74,226,103,170, 79, 68,124,111,141, 11,133,203, 25,176,229, 16,194, 84,225, 75, 76,124,179,236,238,161,
+238,167,101,165,213, 87,219,170,174,227,178,178,132,134,250,123, 86,177,203,220,231,113, 41, 2, 73, 1,245,145,255, 0,202,184,
+191,150,225,178,177,251,155,241,195, 18, 98,161,181,185,180,201,113,180, 40,164, 19,223,246,202, 2,158,226,117, 71,190,218,244,
+240,247,127, 74,217,182,189,243,196, 0,234, 30,223,232, 81, 79,147,220, 19,230, 79,101, 35,199,108,166,220,219,238, 59,119, 40,
+234,181, 53,137, 31,133, 92,173,247, 80, 70, 47, 74,227,178,162,118,110,144,176, 79,194,233, 45,148, 37, 35,186,146,149, 41, 5,
+116, 30, 0,125, 90,141,146,201, 78,219,239, 26, 83,138, 81, 37,149,108,132, 36,200, 37,165,165, 82,157, 65, 97, 52,112, 16,173,
+160,138,164, 4,158,186, 99, 37,157, 51, 83, 86,251,177, 34,138, 71,100, 84,244,148, 53,179,107, 33, 42, 66,149,184,132,128,233,
+ 27,136,161, 52, 42, 0, 36,159, 17, 93, 50,154, 0,165, 32,191,170, 44, 90,225, 46, 90, 91,147, 69, 24,240,147,243, 65,213,160,
+161, 14,203,162, 66, 54,138,212,164, 4, 0,145,227,212,246,173, 26,187,242,240, 74,153,188, 90,169, 69,142,214,238,248,165,209,
+241,167,113, 86,211, 84,182, 20, 74,137,239, 69, 42,167,244,234, 62,230, 68,250,212, 85, 17,221,128,135,227,178, 90, 9, 50, 15,
+156,134, 90, 95, 70,148,190,173,158,189, 41, 85, 26,142,158,253, 64,200,243, 90,171, 20, 13, 20,211, 84,224,214, 46,155,205,173,
+115, 89, 88, 73, 20,105, 43,243, 64, 75, 18,156,162,118,251,122,244, 32,125, 58,144,219,174,244, 16, 10,171,243, 5,181, 9, 45,
+206,158,133, 86,126, 97, 97,216,147, 44, 19, 94, 67,140,170, 18,100,219, 93,114,165, 94,112,112, 5,166,162,148,166,212,248,123,
+117,125,218, 98, 5,146, 6,228,104, 86,103,184,221, 17, 36, 69,217,138,143,109, 62, 8,157,198,115, 19, 50,219, 20, 48,146, 10,
+ 28, 66,193,223,241, 16,144,104, 73, 7,217, 93, 85,247, 72,244, 56,171,238,211, 48,123, 1, 86, 82, 19,161, 10,139,229, 37, 11,
+ 92,197, 54,166, 16,217, 53, 35,171, 98,189,107,210,132,211, 85, 89,184,171, 60, 40,137,139, 68,116, 45, 97, 41, 73, 75,139, 69,
+ 73,116,164, 39,230, 91, 9, 39,216, 40,176,161,211,250, 52,202, 87,131, 68,163,134,145, 90,171, 99,199,209, 3,235,103,105, 77,
+105,181, 68, 19, 69, 40, 83,175,249,116,215, 78,156,179, 80,123,140,194,157,252,148,115,147,237, 77,204,231, 14, 27,142,164, 5,
+ 37,153,183, 57,139, 64, 93, 62, 20, 6, 72,162, 72,170,190, 33, 65,171,166,207, 33,101,133,201,234, 30,242,169,146, 1,226, 2,
+222, 0,251,135,194,138,233,103,104,140,228, 68,180,150, 9,101,182, 89, 90, 36, 54,162,147,213,176, 71,122,116, 61, 43,211, 84,
+169,142,163,138, 87,101,213, 29, 13,113, 53,192,246,170, 65,200, 8, 75, 74,125,107, 65,108, 42,142, 52,162,141,164,109, 52, 41,
+ 62, 30,194,146,126,141, 37, 19,136, 43, 69,181,141,175,104, 40, 17, 54, 83,178, 89,146,210,188,178,244,114,226,154, 11,220,149,
+ 45, 13,244, 52, 34,189, 82,149,120, 87,218, 61,207,227,166, 9,196,140,162, 24,221,158,104, 62,101, 41,123, 36, 54, 20, 92, 90,
+206,228,187, 21,212,144,164,159,213, 52,216, 59, 83,160,247,117,146,136, 20,209,238,110, 72, 87, 54,117,181, 44,207, 97,233, 11,
+133, 37,108,255, 0,185, 41,193, 68,173, 9,220, 2, 74,138,135,198, 9,233, 94,227,196,116,172,132, 80,151, 16,155,207,113,160,
+ 85, 84,236,218,232,185,170, 84,103, 18,242,100, 52, 74, 75,232, 93, 82,161,220, 16,107, 66, 8,247, 3, 79,110,174, 27,101,166,
+147, 80,169, 91,213,240, 45, 32,168,214, 15, 99,190,230, 87,248,172, 70,105,199, 44,214,117,133, 75,125, 14,111,106, 67,192,130,
+106, 64, 0,132,143,233,213,201,225,187,124, 37,206,249,157,146,170,236, 54,210,111, 23, 90,199,200,223,121, 80,121,116,200,185,
+ 35, 49,191, 20,175,201, 55,151,109,240,156, 75,159, 2, 96, 90,148,152,204,237, 29, 41,189, 45,133, 83,235,211,123,183,120, 48,
+181,189, 85,245,148,218, 51,245,215,243, 75,253,109, 35,177,184,125,200,199, 13, 17,163, 56,146,202,148, 82,166, 66, 99,121,238,
+249,168,113,234,111,220, 73, 2,189, 79,127,109,122,251,106, 19,227, 85,122,180, 24, 12, 86,155,179, 75,143, 84, 33, 10, 46, 33,
+231,219,121,194,170,111, 19,148, 77, 71,216, 41,244,104,144,147,154,113, 59, 6, 74, 69, 21, 74,143,108, 65,115,227, 66, 25, 99,
+168,236, 28, 27,144, 15,187,168,235,244,104,242, 26,148,198, 32, 2,143, 95, 24,243,155, 75,145,221, 38,161,205,136, 81, 34,136,
+ 81, 43, 8, 63, 82,201, 7,216,105,224,116,214,152,226,165,162,126, 24, 33,228,168,197,196,148,189, 86,214,158,251,253,191,242,
+246,233,220, 80,147,146, 74, 91,192, 5, 9, 81,231,109, 82, 2,137, 68,133, 20, 30,197, 43, 32, 80,251,193, 41,251,245, 47, 12,
+ 21,224,160, 46,175, 41,136,118, 9, 26,172,110,147, 84,174,165, 93, 77, 28, 81, 36,123,234, 41,247,234, 86, 11, 66,120, 42,245,
+213,240,111, 31,122,150, 99,120, 5,203, 33,148,212,102,160,121,197, 68, 36, 41,129,229,169, 65, 95,214,248, 66, 79,211, 81,169,
+171,109,172,189, 86,239,119,193, 0, 56,174,143,240, 7,160,251,110,103, 38, 19,183,185,251, 27, 81, 67,143, 71,106, 86,199, 18,
+ 15,112,161,185, 97, 84, 30, 41,167,211,171,101,134,198,211,243, 44,203,126,231,153, 45,235,225,253,235,177,124, 99,249,110,122,
+115,183,196,102, 84,182,239, 11,188,165, 9, 75, 75,134,219, 44, 51,187,192,173,164,164, 50,234,129,236,165, 36,234,117,155, 32,
+ 97,168, 24, 44,246,227,204, 59,153, 1,105, 53,246,255, 0, 74,232, 71, 12,250,107,226, 44, 5,108, 51, 42,218,226,202, 86, 22,
+195,147,172,214,164,154, 18, 77, 66,145, 0, 44,119,239,187, 74, 75,182,212,119,104,162,155,205, 50,220, 97, 37, 71,172,253,229,
+ 92,185, 56, 54, 25, 54, 51,106,179,177, 17,185, 17,210,146,200,101, 8,111,240,246,232,132,164,125,218,103, 16,125,174, 28, 19,
+123,128,203,190,245,106, 82,121,215, 59,157,142,208,251,111,176,226, 18,218, 20,150,212,146, 79,109, 42,203, 81, 43,197, 10, 65,
+247, 38, 22, 26,133, 74, 50,219,212,201, 55, 87,221,121,213,141,238, 43,105, 36,212, 84,234,231,109, 8,137,128, 5, 74,185,152,
+202,242, 74,107,151,108,148,213,164, 93,157, 62,107, 61,233,187,226,235,162, 11,166,151,232, 25,163,186,209,193,154,206, 74, 31,
+ 26,225, 37,201, 8,118, 29, 80,164,172,109, 86,238,160,233, 89,105, 67, 84,218, 58,212, 81, 88, 75, 58,239,247, 72, 81, 88,151,
+ 57, 98, 57, 66, 65, 74, 84,107,180,253,122,166,220, 95, 69, 3,141, 27,138,184, 65,103, 45,195, 5, 93,130,109,207, 49,203, 69,
+162,217,243, 47,202,121, 11, 82,107,241,172,209, 74, 58, 78,199,118,146,121, 40, 0,162,230,225,181, 71, 3, 42, 78, 42,167,228,
+ 46,219, 93, 67,129, 31, 18,147, 90, 31, 18, 63, 78,173,129,228,170,147,154, 16,158, 84,166, 26, 82,209, 69,128, 73,250,180,140,
+175,162, 69,201,195, 6,198,145,152,100, 76, 90,146,218,148,215,152,135, 36, 59,250,168,105, 38,180,250,245,150,249,151,206,113,
+114,118,219, 45,203,207,122,132, 52,117,168,173,194,232, 91, 48,184,162,247, 44,100, 12,182,139,119, 30, 99, 10,248, 25, 72, 68,
+135, 27, 52, 21, 29, 20, 77, 62,141,124,190,185,189,155,152, 46,164,191,184,196,184,224, 62,197,141,110,215,166,242, 74, 4, 30,
+203,242,107, 87, 31,226,111,197, 76,180, 50,182,227, 56,236,249, 33, 84, 82,151, 78,160,123,207,134,189, 59,228,247,150, 77,137,
+191,206,119, 22,225,155, 26, 85,199,151,118,118,217, 71,245, 19,122,151, 50,156,176, 93,185,187, 43,118,245,120, 83,145, 49, 8,
+ 18, 74,216,105,100,143,154,242,207, 66, 65,239, 93,122, 63,109,217,228,223,102,241,229,194, 49,144, 83, 54,187,123,247,137,124,
+ 89, 48,103, 4, 95,153, 59, 28,198, 34, 38, 4, 38, 2, 27,142,128,132, 33,180,129,248,122,117,214,171,105,104,216, 26, 26,193,
+ 64,175, 16,194,216, 70,150,133, 11,254,248,197,243,124,255, 0,150,115,203,223,183,177,174,223,110,158,248,105,122, 47,160,190,
+ 99,244,109,114,194, 44, 50, 47,226, 99, 83, 35, 71, 66,148,240, 41, 71, 77,162,189,199,183, 78,227,148, 60,209, 69,190, 34,193,
+ 85, 67,165,113, 76, 27,181, 84,136,109,184, 21,214,161,176,122,157, 58,211, 68,152, 53, 76, 23, 79, 79, 86,185,177, 84,137, 86,
+182,220, 77, 59, 41,144,123,235,132,233, 93, 56, 32, 7, 34,250, 18,196,115, 43, 67,168, 56,236, 84,184,180,174,142,166, 50, 66,
+234, 71,180, 0,116,171, 37, 33, 24, 18, 49, 11,153,156,139,249,107,100,120,228,247,103, 97,211, 39, 91,150, 28,220,150, 66, 8,
+ 69,124, 59,116,211,166,185,143, 29,228, 99,112, 66, 36,113, 15,162, 95, 86,209,146,221,203, 30,157, 49,230,218, 80,248,131,107,
+112, 16, 59, 87,106,129,212,101,209,182, 7, 75,130,121, 5,187,238, 6,166,174,152,240,239,167,127, 87,150,242,199,241,152,238,
+148, 5, 33, 43,117,108,185, 93,190, 38,165, 95,167, 80,147, 67,108,211, 86,165,159,183,204,240,187,157,233,231, 17,200,240, 60,
+ 44, 28,186, 79,206, 78,113,189,203,101, 93, 54, 18,107,218,166,148,211, 71, 66,217,157, 70,169,173,189,142,178,143,188,106,167,
+153, 14, 84, 36, 71,118, 60, 72,202, 97,197,213, 27,135, 78,154,148,181,219,116,154,164, 46,247, 50, 90, 64, 8, 52,237,137,111,
+ 58,183,221, 82,150,183, 20, 84,162, 72, 36,147,245,234,196,202, 52, 81, 87, 92,210,227, 82,181,156,116, 43,165, 52,109, 72,190,
+ 26,214,113, 84,138,171,173,116, 82,250,174,136,232,155, 38, 99,197,190,169,221,227,208,104,164, 85, 26,148, 66, 46, 64,226,184,
+ 89,125,178, 84, 57, 47,220,163, 45,230,212,128,228, 93,206,168, 21, 15, 96, 10,211, 57, 34,212,159, 90,220,152, 8, 33,113, 7,
+213, 15,229,185,146,223,213, 42,237,143,223, 50, 59,171,128,173,109,196,115, 30,122, 91,157,201, 0, 45, 72,109, 20, 30,205,218,
+132,187,219, 27, 42,209,118, 94,111, 54,244, 4, 1,235, 92,117,207,125, 44,114,222, 3, 61,200,143,225,247,249, 37, 11, 90, 80,
+ 91,177,200, 15, 60, 82,124, 16,134,156,251,149,170,245,198,196, 15, 5,164, 88,115,115,100, 0,235, 3,215,251, 16,142,227,136,
+231, 86, 16,163,121,196,239,150,198,209,227,114,182, 73,131,186,157,246,133,236, 42,167,143,179, 80,243,108, 29, 74,203,111,205,
+ 65,223,140, 31, 90,100,102,240,200,115,201,117,169, 17,214,147, 69,144,146,128, 15,188,169,195, 79,175, 80,183, 91, 11,155,193,
+ 88,236,185,161,174, 63, 50,159,216,228, 91,220, 27,158,187, 70, 97,176,104, 82,236,181, 41,213, 14,255, 0,128,127,200,234,169,
+123,182, 58, 51,145, 87,125,191,122,108,180,197, 20, 97,100,144,190, 92, 68,136, 86,249,168, 73, 81, 39,111,197,211,167, 80, 6,
+239, 96,251,124, 53, 93,154,196,140, 72, 86,184,119, 22,145, 64,106, 84,168, 92,100, 48,211, 5,131,181,196,213, 68,145, 82, 87,
+237, 3,167, 65, 90, 36,123,105, 77, 68,207,107, 85, 53,107,122, 27, 76, 84,202,207, 37,247,237,206,165,213,236,114, 45, 93,108,
+ 42,133, 74, 69, 82, 0,169, 61, 40,181,166,191, 77, 60, 53, 9,113, 6,146,172,150,215, 33,194,169,246,223,116,126, 51,110, 64,
+ 73, 45, 55, 34, 68, 87,220,104, 44, 20, 20,164,148,133,248, 15,134,181,251, 52,156, 48,208,164,119, 9, 4,162,188,104,130,254,
+162,154, 97, 22,232,114, 24, 90,157, 72,150, 24, 75,200, 61, 65,114,155,130,186,245, 72, 21, 2,190,237, 95,249, 97,250,156, 90,
+122, 22, 71,205,113,120, 77, 15,111, 74,102,226,169,243, 88,181,121,171,147, 6, 59, 73, 90, 18,132,124,211,106,148,162, 40, 41,
+229,133, 21,138,143,118,155,239,118,160, 56,138, 41, 62, 95,220, 53,181,189,138,219,227,179,210,227,208,126, 93,239, 53, 98,137,
+ 67,142,132,182, 58, 0,144, 82, 7,138,137,175, 83,236,213, 18,230, 28,214,129, 5,198, 8,231,138,178,147, 33,180,176, 60,229,
+121,148,232,104,193, 66, 11, 41, 69,107,211,162, 82,174,255, 0, 95,142,162, 37,101, 49, 78,159, 53, 66,180,184, 86,200,229, 41,
+105,207,217,182,234,246,110, 27, 2,208,133, 40,110,221,236, 3,175,109, 34,214,146,160,119, 7,214,184, 87, 63, 79, 98, 11,242,
+ 94, 88,219,124,251,129, 76,101,244, 59, 15, 31,249, 38,166,188,149,130,219,111, 94,147, 41,164, 2, 18,170,133, 18,134,105, 94,
+225, 96,251, 53,126,219,173,233,181, 76, 56,184,143, 96, 42, 34,218,216,201, 28,178, 83, 0, 64,246,214,190,242,173,245,215, 38,
+ 77,210, 43,116, 89, 45,164, 20,160,147,185, 14,165, 93, 83,236, 41,248, 85, 84,147,225,211,160,213, 2, 88,205,104,149,178, 99,
+ 97, 26,191,164,122,113,246,170,241,152,196,243,154, 88, 43, 68,136,206, 2,190,137,220, 81,187,227, 63, 64, 39,174,139, 28, 68,
+149,103,130,236, 48, 87, 46, 10,177,228,114, 62, 86, 91,140, 54,166,194,124,149,183,231,162,129,178, 17, 83,251, 68,146, 8, 33,
+ 95,173, 90,208,234, 78, 24, 41,154,114,110,181,138,132, 23,186, 76,242,196,134,228, 44,121,106, 74,213,181,165,151,130, 84,154,
+ 16, 18,105,184, 2, 62, 33, 83,169, 88,226,174, 73,155,165, 13,197, 2,114,105,123,153,112,149,133, 54, 18, 91,104, 23, 3,101,
+109,248,119, 87,116,210,157,198,172, 22, 54,250,136,162,129,220, 47, 12, 96,213, 87,233,165, 83,239, 44,217, 45, 45, 31,226,243,
+214, 27, 67, 20, 47,236, 67,191, 9, 36, 40,168, 86,135,165, 70,180, 61,171,109, 33,190, 35,199,116, 44,211,113,189,117,228,158,
+ 12,121,159,114,189,118,252, 42, 7,167,238, 11,189,228,215, 6,217,249,169,150,121,146,209,243, 32, 37,212,207, 8, 37, 8, 21,
+235, 87, 28, 33, 32,123, 77, 52,202,233,231,121,184, 17,140,170,175,123,120,103, 45, 88,190, 83,129,107, 73,237,244, 43,150,152,
+245,205,200,172, 49, 40, 45, 74, 82,208,126,105, 7,241, 23,130, 66, 74,129,239, 82,158,189,117, 57,127,183,153, 77, 0,193,101,
+ 59, 54,230,216,154, 28, 78, 60, 84,181,156,156,151, 35,161,167,148, 27,101, 40, 0, 19, 82,215, 90,154,123,147, 94,154,132,155,
+101,113,198,138,223,109,204, 12, 20, 21, 82,167,242,165,184,148,151,127,104,224, 75, 42, 95, 80,119,150, 8, 6,159, 72,251,136,
+211,102,236,174, 28, 19,231,239,173,119, 20,243,109,202, 67,232,114, 18,233,229,186,218,131, 36,145,211,112, 42, 31, 98,201,254,
+157, 39, 54,210,225,193, 8,119, 86, 56,230,189,191, 37, 75,104, 58,217, 41, 72, 1, 42, 79,112,217,246, 16,125,135,199,252,186,
+ 66, 61,172,184,208,132,230, 77,212, 49,181, 5, 41,177,226, 57,102, 99, 53,168, 54, 27, 12,203,131,175, 40, 33, 14,180,193, 17,
+129, 61, 58,169, 91,118,146,123, 10,253, 26,179,237,252,188, 94,169, 91,191, 55, 50,219,230, 32, 43,229,197,191,149,239,168,206,
+ 72, 92, 85,183,109,137,101,102, 83,105,116, 46,106,138, 84,132, 42,134,142,182, 64,117,186,215,161, 82,105,237, 32,117,213,162,
+ 46, 94, 17,138,184, 44,226,243,204,104,181, 16,215,123, 61, 40,175, 70, 25,249, 27,114, 83,101,185, 25,108,181, 45,165, 20,172,
+ 61,142,191, 30,226,225, 6,132,133,180,183,152,160,235,225, 94,189,171,167, 12,177, 99, 14, 74, 10,231,157, 76,192,233, 42,220,
+225,127,148,246, 49,199,108, 55, 62,235, 29,217,202,104,165,106,249,168,108,162, 95, 78,189,131,106, 66, 79,182,139, 87,211,171,
+ 29,141,180, 78,160,162,161,111, 28,205,116,234,144,112,245,252, 85,171,197,248,114,195,136,199,106, 53,182, 47,203,180,194, 66,
+ 80,217,101, 9, 35,111,189, 27, 1,251, 53,101,138,216, 55, 37, 64,185,220,228,184, 53,113, 68,184,141,127, 15, 83,106,104,124,
+ 77,144, 83,240,128, 62,193,167, 98, 16, 69, 20,105,152,131, 85, 40,155,147, 77,185, 54,203,110,132,167,202, 72, 74, 74, 6,213,
+116,209, 98,179,108, 68,144,143, 45,219,165, 24,173,150,220,142,237,109,116, 59, 30, 83,169, 35,176, 43, 52, 58,228,214,140,151,
+ 2, 23, 98,187,146, 35, 80, 83,181,227,144, 50, 11,148,111,150,125,212,148, 17, 67, 81, 90,215, 77,163,219, 35,140,234, 9,196,
+187,172,146,138, 20, 25,187, 50,235,174, 45,111, 51,230, 37, 68,168,168, 39,199, 82, 64, 80, 40,183, 18, 74,139,205,184,169,198,
+ 77,185,199,220,106, 63, 96,133,116, 78,146,240, 26, 14,160, 49, 74,153,220, 91,164,156, 20, 57,104,114,220,181,174, 59,233, 82,
+ 79,196, 15, 66,127, 78,132,135, 12,146,109, 29,104,153,136,242, 98, 32,193,114, 61,197,176,183, 90,175,148,190,128,154,106,167,
+186,237, 6,103,234, 98,179,237,123,184,129,154, 94,133,156,131,203,151,123,195,206, 67, 92,112,152,136, 52,111,119, 74,129,165,
+236, 54, 97,108, 42, 78, 41,174,225,188, 58,235, 0, 48, 85,218,239,144, 72, 91,234, 82, 93, 74, 21, 67,240, 19,223,239,212,189,
+ 3, 2,131,123,203,148, 75,251,205,185,255, 0, 37,230,210,165,173, 97, 9, 72,161, 42, 82,186,116,250,116,194,234, 80,192, 73,
+ 56, 4,217,238,162,180,246,119, 33,113,142, 4,238, 64,235,105, 77,246,246,201, 68, 68, 30,142,164,188, 58, 83,199,167,134,190,
+117,121,231,206,175,230,253,200,216, 66,239,201,140,227, 76,176, 89,135, 53,110,245, 37,141, 42,183,221,115,120,152,226, 36, 92,
+110, 50,155,123, 33,185,149, 41, 1,197,141,204,161, 70,190,222,148,211,223, 40,124,177,119, 51,220,182,121,218, 69,188,126,244,
+203,149,182, 35,122,255, 0, 22, 65,128, 85, 43,145, 50, 57, 89,141,201,168, 83,167, 41,187, 66, 23,230,202,218,191,223,158,230,
+189,122,215,176, 26,246,191,252,120, 73,162, 22,141, 49, 48, 96, 2,210,165,219,205,203,154,204,152, 20,122,102,121,105,179, 65,
+ 69,186,213,229,198,139, 29, 1, 8, 66, 8, 21, 3,196,211,185, 58,184, 91, 89,182, 6,134,180, 80, 5, 59, 12, 66, 38,134,180,
+ 80, 33,157,215,144,173,229, 11, 90,188,181,172,214,165, 74, 7,174,159, 54, 52,176, 8,125,254, 40,197,249,192,198,214,182,245,
+ 52,233, 78,227,223,163,248,104,212, 95, 80,222,171,253,112,227,252,141,101,103,142,120,133, 55, 11,189,198,229, 40, 51, 58,107,
+ 44, 40,176,219, 74,160, 31, 23, 96, 58,159, 29, 77,218,109, 70, 46,252,152, 5, 91,184,191, 19,247, 88,161, 28,121,141, 72,254,
+ 29, 14, 60,150,252,201, 77, 71,104, 62,162,146,106,237, 6,238,191, 78,146,144, 84,154, 39, 48,138,138, 35, 52, 92, 40, 75, 82,
+ 91,118, 58, 72, 85, 5, 10,124, 78,153,185,164, 26,156,146,237,136,184,162, 11,124, 56,240,132,151,213, 25,164,199,219,184, 2,
+ 43,211, 77, 77,251, 53,105,226,165, 70,214,253, 58,184, 33, 77,251,141, 44, 51, 36,252,171,240, 90, 95,197, 69, 31, 46,163,166,
+159,176,146, 42,163,164,140, 86,136,139,138, 64,178, 97,150,245, 67,131,111,100, 19,214,161,177, 77, 48,155,110,241,221,168,149,
+ 43,109,126, 45, 91,164, 4,241, 55, 36,185, 76,142,182, 45,224, 68, 61, 64, 41, 78,223,209,174,183,106,111, 20, 73,183, 71,188,
+ 81,184, 37, 86,219,165,253, 49,144,196,137, 46, 46,128, 86,149,235,167,145,217,178, 60,130,103,245,114, 56, 80,148,191,115,238,
+ 16,167, 66,148,126,142,218,114,214, 1,146, 73,207, 46,205, 42,105, 61, 58,130, 52,106, 46, 85, 40,216, 60, 19,247,104, 46,213,
+104, 83, 79, 31,194, 58, 15,110,130,230, 43, 81,135,191,170,210, 61,253, 53,197,218, 85,120, 54,232,231,193, 53,246, 83,252,250,
+ 33, 21, 71, 24, 36,175,218, 99,184,130,151, 25,101,212,145, 66,149,182, 22, 62,195, 93, 34,232,234,148, 15,162,135,220,112, 76,
+106,122, 93,110, 78, 57,103,146,135,129, 14,161,251,123,110,161,192,124, 10, 74, 72, 58, 72,192, 10, 85,183, 47,110, 68,160,237,
+251,211,199, 20,221, 86,166, 31,226,236, 49,214, 28,168,116, 12,110, 39,150,176,122,146,164,150,138, 9,246, 42,149, 30, 7, 73,
+ 58,216,116, 37,134,233, 59, 78, 15,119,180,170,179,204,255, 0,151, 79, 0,231,182,105, 45, 67,227,252,126,221,119,117,181,134,
+174, 42,132, 94, 92, 93,223,213, 78,224,183, 15,176, 41,123, 71,122,123, 90,203,100,215,140, 66,150,179,230, 75,139,114, 9,121,
+167, 66,224,119,169,207,203,131, 35,225,251,140,137,184,107,151, 27,165,185, 39,115,112, 19, 31,204,144,183, 20, 73, 63,186, 13,
+180,132, 1, 94,148, 36, 26,119, 73, 10, 53,157,203,101, 18, 14,232, 90,239, 42,115,207,139,132,166,138,141,139, 6, 79,142, 70,
+ 67,210,109,115, 98, 15,131,108,151,227, 56, 80,162,225, 33, 41,110,137, 59,138,207, 68,237,234,122,246,213, 18,235,151,156,243,
+146,218,173,121,174, 24,219,243, 10,175,203,102, 90,255, 0,207,167,231,222,113,176,217, 0, 54,182,202, 86,216, 71,137, 73,235,
+187,199,183, 78,148,169,232, 97,174,185,113,237, 24, 53, 78, 89,243, 84, 79,112,239, 4,117,179, 95,226, 72,101,104,109,208, 55,
+ 54,153, 14,147, 74,186,225, 33, 72, 71,112, 40,144, 62,179, 83,218,154,168,221,236,143,105,169,106,189,217,111,145,189,180,107,
+150,183,114,120,139,116, 37,199,208,181,164, 41, 59,144,161,229,180,194,104,128, 73, 7,168, 40, 65, 39,223, 95,102,154,127, 41,
+115, 56, 39, 15,221,219, 46, 69, 10,179,187,236,123,245,170, 77,189, 83,145, 85, 52, 67, 42,117,117, 20,117, 37, 38,170, 4,143,
+137, 72, 63, 69,125,154,154,218,173,221,107, 32, 52, 85,125,246, 70, 93,196, 69, 80, 87,142, 50,119,162,228, 17, 34, 79,148,211,
+ 81,222,121, 77,179,187,163,105, 81, 21,168, 21, 0, 5,117,167,191,217, 74,234,197,187,216, 11,136,139,154, 49,162,165,108, 91,
+147,172,230, 12,113,192,149,210, 76, 37, 18, 94,118,218,250,139, 69,135,147, 88,205,126, 48,134,170, 58,128,147, 78,181, 58,203,
+ 46,173,244,146, 22,185, 5,238,166,138, 21,108, 49, 75,121,105, 97,164,173, 65,160,226, 93,243, 54,129,209, 74, 5, 40, 81,236,
+ 58,146, 41,225,168, 87,193, 92, 82,147, 95,105, 20,224,136,121,111, 35,227, 24, 29,157,183, 36, 77, 6,226,166,150,219, 17,210,
+ 82,185, 18,101, 16, 74,182,128, 20, 79, 79, 10, 83,191,211,165,109,118,183,220,190,141, 10, 30, 93,196, 0, 92,231, 0,223,185,
+ 84, 52,228,214,123,252, 44,130, 85,242,101,224,222,111, 83, 81, 61,155,148, 75, 84,183, 13,181,216,229, 10,100, 33,196,178, 82,
+ 3, 11,105, 37, 21,233,238,239, 93, 30,222,218, 59,120,219, 21, 91, 74, 80,226, 49,174,105,236, 92,197,101, 20, 38, 7, 60, 81,
+222,239,232, 40,209,196,220,253,111,157, 25, 88,214, 89, 41, 17, 47, 80,182,180,196,153,109,170, 44, 11,162, 42, 0, 45, 23,104,
+104,175, 20,119, 4,211,175, 66,106, 59,174,192, 98, 37,204,197,188, 41,143,181, 64,179,117,143, 93, 24,240, 69,113,167,218, 61,
+ 48, 70, 43,171,137,146,141,232, 41,122, 59,137, 62, 98,161,184, 84,164, 82,165, 42, 2,166,157, 15, 78,189,134,161, 99,179,224,
+ 70, 42, 79,249,157, 49,174, 29,104, 37,146, 90,139,190, 98,194, 18,244,144, 92, 89,119,202, 82, 75,169, 72, 6,165, 6,180, 52,
+ 61,125,191, 78,164, 34,180, 74,127, 54,160,165, 85,122,188,226,210,164, 45,229,182,228,102, 30, 43, 90,124,157,202, 66,192, 71,
+112, 16, 43, 79,209,169, 75,123, 50,120, 46, 77,188,180, 5, 82, 57, 10,236,251, 23,103, 49,171,114,214,237,233,245, 37,191,150,
+109, 97,104,140, 42, 6,226,146,130,106,160,122, 0, 65,246,235, 70,229,254, 94,241, 0,150, 65, 70, 15,127, 82,166,110,123,195,
+174,223,224,196,113, 62,229, 98, 56, 79,211,196, 28, 81,168,124,141,148,132, 37,228,169,185, 96, 73, 89, 82,200, 87,196,107,184,
+215, 83,187,141,217,184, 30, 12, 67, 12,176, 83,252,187,177,199, 96,226,249,136,173, 43,138, 53,115,167,166,191, 85,158,168,161,
+217, 49,254, 43,227, 27,177,193,145,242,119,117, 93, 47, 14,183, 96,137,120,108,167,246, 38, 63,204,169,178,235, 73, 7,205, 42,
+165, 21,240,237,175,140,191, 46,114,193,181, 6, 89, 7,120,172,171,204,223, 50,236,222,239,161,130, 80, 90,211,223, 35, 17, 81,
+147,112,232,227,215,216,162,120,143,228,185,234,226,232,225,141,118,182, 98, 24,200, 70,207,247,153, 87,225, 45,151, 91, 52,169,
+ 71,144,135, 42, 69,127, 10,130,125,132,246,173,163,249, 64, 43, 34,255, 0,156,219, 66, 48, 46, 62,165, 98, 90,252,131,185, 45,
+ 45,196,146,190,103,195,131,174,182,218,165,197,254, 9, 49,149, 69,112,143,137, 33,123,220, 74,194,123, 3, 65, 95, 96,210,159,
+201,218,120, 4,205,190, 98,181,167,229,119,180, 41,195, 31,144,245,195,229, 66,151,205, 9,106,106, 26, 32, 50,155, 55,153, 20,
+188, 0,162,130,247,110, 41, 61, 65, 65, 72, 35,250,199,190,138,118, 56,207, 5,223,252,154,240,112, 97,246,168,188,175,201, 3,
+ 51,134,162, 97,114, 92, 55,157,105, 36,164, 57, 5, 72,218,250, 77, 82,122, 31,141, 11,233, 94,160,142,163,226,165, 74, 46,216,
+ 35,114,113, 31,153,238,105,174,147,237, 77,214, 31,202,199, 59,198,111, 49, 87,127, 76,123,164, 70,166, 52,137,177,212, 20,166,
+ 92, 98,160, 42,138, 77, 9, 77, 43, 82, 40,104,122, 16, 64,222,212,114,219, 1,173, 20,185,243, 59,198, 97, 0,144, 72, 93,120,
+244,217,233, 75, 14,227, 59, 66, 82,205,146, 43,114, 67,149, 41,126, 58, 86,135, 80,170, 84, 58,213, 60,180,185, 65,241, 45, 0,
+ 26,244,252, 32, 3, 63,105,183,182, 1, 64, 22,101,191,115, 12,155,140,149, 46,195,211,220,175,245,190,209,108,182, 65,104, 91,
+217,106, 35,173,129,181, 17,219, 13, 37, 7,220, 5, 0,211,193, 1,113,161, 24, 42,209,155,136, 56,163, 78, 6,237,197,208, 29,
+122,228,130,218,122, 22,157, 85, 13, 62,189, 69, 95, 68,216,240, 13, 82,251,124,143,147, 18,236, 18, 14, 73,190, 62,177,242, 13,
+ 45,178,210,146, 65, 40, 34,135, 74,237,118,193,221,226,147,221,110, 11,123,160,170,237, 46, 11,164,170,128, 80,248,253, 58,178,
+ 53,160, 42,219,170,152,221,138, 90,175,152, 43,244,141, 42, 17, 50, 72,150, 16, 65,218,144, 15,183, 64,162,169, 38, 61,132, 93,
+114, 20,169,113, 86, 54,142,192,247, 58, 97,119,126,203, 92, 10,144,180,219,159,119,139, 84,177,238, 21,204, 25, 72,113,216,143,
+ 33, 10,166,194,243, 11,108, 47,232, 42, 2,181,211, 81,187, 71,198,169, 99,180,188,100,106,152, 39,241,182, 79, 21, 4,170, 9,
+ 88, 72, 53, 1, 53, 29, 52,118,238, 81, 56,230,147,118,221, 43,120, 33,149,235, 15, 90,146,180,204,130,182,213,214,167,203, 34,
+135, 78,219, 56,118, 69, 52,125,185,110, 97, 9,175, 56,163,145,210,179, 27,119,143,194,170,244,250,180,166,170,164, 12,116, 67,
+121, 49, 46,145, 86, 71,149, 64,146,104, 64,240,209, 29, 69,192, 8, 81, 92,129,183,101,178, 68,141,168, 90, 71, 69,118, 61, 52,
+218,154, 81,201,170, 1,100,177,220, 14,111, 75,197, 42, 69,104, 66,169, 95,179, 72,189,201, 39, 43, 49,195,190,154,240,204,143,
+ 31,193,249, 11, 46,229, 11,221,158,118, 67, 26,237,123,137,142, 69,227,180, 94,108, 81,224,217,238,179,237,105, 84,171,168,190,
+177, 33, 42,113,219,122,214, 80,221,189,116, 73, 29, 73,233,170, 31, 60,206, 91, 97, 36,108,152, 70,247,130, 1, 32,159,179, 31,
+101, 79, 82,175,111,123,164, 59,123,116,200,226, 9, 21, 20, 21, 25,145,211, 94, 29, 9,191,159,160,222,172,153,139,182,169,243,
+109,178,237, 48,173, 22,203,158, 57, 50,212,250,222,182, 92,173, 55, 54, 67,145,164, 54, 29,109,135,219, 46, 36,245, 67,205, 33,
+105, 53,170, 70,188, 53,178,121, 91,122,119, 83,107,117,165,196,144,247, 61,164,150,185,174,196, 16, 72, 6,132,112, 32, 30,144,
+168, 27,127, 47, 77,189, 93,211, 2,204, 13, 69,104, 65,203, 58, 31,104, 5,115, 23,150,133,230, 52,151,175,114,238,104, 80, 53,
+162, 18,231, 70,219,175, 68,142,186,247,111, 44,109,150,251, 52, 12,182,129,180, 0,123, 79, 74,216,173,246,111,160, 96,107,114,
+ 10,175,206,228, 66, 55,161,114, 73, 32,144, 9, 85,122,253,186,185,178, 36,187, 88,132,249, 22,115, 32,173, 69, 15, 18, 15,136,
+ 63,231,211,134,181, 46, 26,133, 87, 60,230, 96,220, 11,202, 35,175,142,148, 1, 28, 54,138, 23,253,243,145,243,129,207, 53, 85,
+161, 29,253,227, 93,162, 54,149,247,125, 99,226, 28, 7, 28, 62,101,174,197, 14, 59,164,245,123,203, 5,210,126,147,219, 79,223,
+ 51,228,204,168, 86,219,178, 60,130,159, 66,178,219, 97, 10,198, 97, 40, 39,185, 26, 78,133, 40, 26, 27,146,145, 91, 75, 12,200,
+ 66,159, 77, 91, 73,169,219,236,210, 83, 48,185,180, 9,120, 94, 26,234,148, 67,185,228,208,141,185, 49,225,249,133, 91, 54,109,
+ 36,244,233,168,120,118,199, 7,234,114,154,155,117,105,143, 75, 80,161,230,124,213,169,197,160,110, 82,137, 39,185,235,169,230,
+182,138,190,227, 82,155, 94,183, 21, 43,184,161,210,129, 16,138,165, 12, 70,102, 56, 29,170, 61,250, 4, 85,116, 96,156,154,119,
+240,236, 72,167,183, 92,210,133, 83,179, 75, 77, 62, 32, 53,202, 35, 85,123, 82,145, 90, 36,164,125,122, 11,139, 18, 9,241, 7,
+244,104, 81, 5,190,157, 40,125,148,215, 16, 94, 11,125,250,253,186, 8, 38, 23,226, 75,122,106, 20,211,155, 26, 73, 27,133,105,
+ 81,163,130, 40,147, 32,147,130,120, 75, 73, 29, 20,170,211,165,125,186, 37, 18,185, 37, 40, 97,165, 15, 15,183, 68,162, 48, 41,
+ 59,241, 90,251,117,205, 43,164,166, 41, 80, 27, 80, 52, 26,225,101, 87, 42,132,185,223, 30,216,114,235,124,203,125,202, 27, 78,
+137,145,222,134,181,148,130,164, 49, 40,108,114,149, 29,212,130, 69,126,131,225,164, 93, 0, 41,205,189,209,128,130, 56, 26,160,
+ 53,207,209,223, 26,228,139,117,179,101,134,137, 18, 90, 84, 72,174, 54,194, 18,236, 8,206,167,203, 88, 97, 91,119, 54,162,213,
+ 91, 74,193,170, 82,104,146, 52,205,246,173,104, 56, 41,104,247,187,135, 56, 81,197, 10,243, 15,202, 87,130,103, 89, 86,193,197,
+162,217,149, 45,196, 63, 50,241, 17, 33, 19,246,182, 62, 20, 54,122, 16, 7,114, 9,161, 36,146, 9, 59,132,113,142, 41,123,160,
+ 41,216,183,251,219, 94,251,156,170,158,113,249, 41,224,249, 29,174, 90, 56,175, 52,202, 49,251,170, 27, 82, 91,106, 84,182,166,
+197,147, 33, 29,119,186, 92,242, 64, 11, 52,223,180,244, 20,218, 9, 21, 44, 47, 54,187,118, 98,230,226,172, 27, 95,152, 87,213,
+210, 72,211,236, 92,178,230,239,202,135,213,143, 22, 38, 67,118, 7, 45,249,218, 16,219,138,152,187, 49,249, 87,131,105, 20, 80,
+ 74, 20,178,165,154, 3, 83,222,134,131,185,212,113,229,184,110, 70,166,133,112,181,243, 75,194,238, 60,145,233,233,251, 23, 47,
+179,174, 58,229, 62, 62,148,168, 25,214, 39,125,176, 62,160,160,211,119, 22, 84,210,100,134, 73, 5,196, 16,104,226, 55,146, 55,
+ 39,165,106, 43, 80,117, 31, 47, 44,248,103, 5,105,183,231,102,222,182,161,213, 66,127,153,147, 21,216,207, 33,146,135, 18,242,
+ 28, 46,148, 21, 29,205, 41, 74, 9, 77,126,145,208,107,135,105, 32, 81, 54,126,240, 53, 84,103, 85,118, 56,123,158,173,182,136,
+237,199,202,203,209,166, 70, 75, 72,109, 77,183, 84,190,134,210, 64,221,180,149, 36,141,162,163,167,127, 13, 81, 55,126, 80,124,
+142,213, 16,193,104, 27, 63, 58, 71,160, 50,115, 66, 56,174,145,226, 49,185, 87,145,241,168, 87,140, 35, 31,254, 25,143, 92,144,
+212,216,119,155,144,243, 92,155, 14, 98, 55,161,230, 90, 65,161, 73, 20, 35,114,135,126,213, 26,172,142, 85,250,119,126,113,199,
+160, 36,247, 79, 50,173, 96,238, 70,117, 56,123, 20,163, 11,244,135,157,228,119,131,115,191, 61, 58,227, 54, 67,219,156,149, 41,
+ 69,197, 37, 53,232,148,248, 36, 1, 65, 65,167,147,196,200, 27,165,130,138,141,113,207, 2,103,106,115,149,239,199,253, 34, 73,
+137,110,102, 59,145, 74,138,146,148, 42,169,241, 35, 85,121, 96,115,221, 84,220,243,172,125, 40,121,157,250, 18,157,116, 66,203,
+ 48, 11,237, 60, 74, 86,223,151, 94,138,212,157,137,115, 51, 73,158,117,143,165, 64, 45,190,137,249,118,206,194,173,184,230, 69,
+119,183, 50, 74,131, 81,174,136, 55,104, 0, 42,128, 38,139, 82, 93, 74, 66,106, 0, 75,130,131,183, 97,169, 55, 90,197, 55,121,
+205, 21,234,193, 47, 23,152,194, 0, 5,106, 7, 74, 71,200,126,156, 61, 64, 97,120,133,251, 39,190,189,134, 55, 96,197,109, 50,
+175, 51, 39, 56,101,192,117,139,124, 6, 11,146, 87, 68,135,146,118, 33, 10, 88, 30, 61,180,239,110,216, 35,187,120, 99, 73,169,
+ 41,201,243, 82,221,206, 3, 73, 46, 38,148, 7,143, 5,199,123,207, 57,103,249,115,172,218,241,252,118, 53,189,217,136, 44,184,
+164,133,220,166,185, 81, 79,128, 36, 37, 85,235, 81, 64,117,162,216,114, 44, 86,230,178, 56,149, 45, 55, 52,201,112, 59,173,210,
+ 58,202,179,254,156,253, 6,250,128,207,174,145, 50,102,120,214,254,132, 56, 68,149,228, 25,189,113,107, 97,243, 83,185, 43, 73,
+154, 19, 41,244, 47,245, 84,195, 43, 26,178, 75,181,190, 86,136,216, 3, 90,153, 69,207,219, 95, 46,180,190, 89,117,203,208,222,
+241,246,228, 61,100, 46,230,112,143,162, 11, 38, 30,229,158,253,202,179, 90,206, 47,214,223, 46, 84, 59, 10, 99,134,176,203, 44,
+192, 1, 10, 12, 47,114,231,184,201,252, 14, 61, 68,131, 69, 6,194,130, 84, 36, 54,238, 94,138,207,189,155,186,214, 85,206, 94,
+112,223,243, 16,116, 48,126, 84, 39, 12, 15,121,195,172,240, 7,136, 29,149,162,232,188, 51,111,110, 58, 25,108, 37, 5, 9, 9,
+ 74, 83,208, 36, 15, 1,225,169,230,219,172,140,207, 84,251, 5,231, 80,164,164, 0, 91,240, 36,212,233, 79, 4, 34, 9, 74,144,
+249,105,121, 61,122,107,130, 42, 35,107,170, 76,243, 10, 64,248, 10,127,166,186,239,134,185,173, 39,143,105,157,115,120, 53, 25,
+173,238, 43,165, 64,168,210,114, 6,198, 42, 82,177, 53,210,154, 53, 74, 33,113, 61,206,115,163,248,129, 67,109, 16, 66,170, 58,
+237, 61,245, 29, 45,243, 25,150,106, 82, 45,178, 71,124,198,129, 59, 93,241,124, 99, 21,135,229,173,101,114,215,185, 66,157,138,
+148, 73,253, 39, 69,182,154, 75,131,134, 72,215, 80, 69,108,220,115, 66,215,167, 4, 40,236, 79,193, 83, 79,163, 83,141,141, 65,
+ 25, 22,180, 95, 36, 70,175,146,242,219, 7,184, 74,200,254,157,113,208, 7,102, 23, 91, 59,153,145, 77,242,175,234,125, 95,182,
+ 90,156, 62,213, 42,186, 51, 97, 12,200, 46, 58, 98,252,211, 51,183, 37, 26,150,136, 87,180, 87, 74,104, 68, 47, 72, 23, 37, 18,
+ 71,237, 82, 82, 71,122,107,186,104,185, 90,169,254, 29,111,198,217,177,228,249, 12,251, 52,108,138,125,154, 69,129,171,125,182,
+231, 46, 67, 54,132,199,185,153, 72,125,247,219,136,236,119,222, 83,110, 54,200,109, 62,114, 83,241, 29,193, 93, 0,224, 5,238,
+ 13,173, 19, 13,202,232,217, 69,173,128, 19, 80, 49,245,169,189,159,147, 29,130,204, 72,182, 91, 93,175, 14, 94,199, 5,206,126,
+ 52,151, 33, 75,185,172,168,132,126,209, 78, 45,200,232, 67, 68, 36,182,210,192, 81,170,151, 83, 77,169,205,100, 43,168, 98, 84,
+ 19,119,249,165,104, 99,157, 65,213,133,123, 84,154, 39, 33,207,130,225,122, 46, 73,114, 66,150,127,106,133,205,113,230,100, 10,
+215,107,173,173, 74,109,212,147,221, 43, 4, 31, 17,166,142,183, 46, 20, 35, 4,164,119,198, 19,169,143, 32,245, 21, 55,145,158,
+ 99,215, 27, 10,242, 5, 54,196, 71, 98, 75, 98,221,123,137, 28,127,187, 55, 34, 82, 22,166, 36, 54,146, 73,109, 18, 60,167, 2,
+144, 42, 18,164,244, 32, 45, 41, 16, 23,219, 83,152,224, 88, 48, 43, 65,216, 57,133,183,172, 45,148,247,155,199,164,116,160,214,
+ 79,158,226,239, 69,146,184,118,165,220, 75, 73, 42,121,198, 99,151, 16,200,161, 53, 81, 72, 33, 61, 1,239,164,237,246,249,137,
+196,209, 73,220,238, 48,129,128,170,168,249, 85,242, 52,215, 92,145, 29,148, 48,217,169, 8,173, 41,171, 12, 49,152,133, 9,170,
+173,207, 40,144,212, 10, 32,157,242,234, 6,229, 33,105,233, 90,138,245,210,133, 33, 84, 36,187,207,254, 33, 88,232, 11, 47,184,
+160,219, 77,180, 10,150,227,139, 52, 74, 82, 7, 82, 73, 61, 0,210, 14,193,113, 71, 50, 94, 11,231,118,237,206,220,207, 15,242,
+167,240,196,176, 37,170,226,188, 2,236,136, 77,195, 81,232,242,157, 49, 54, 37,179,253,114,105,239,211, 89, 93, 65, 83,146, 35,
+130,181,246,183,209,137,240, 47, 12,219, 36, 44, 53, 60,227, 57, 68,105, 37, 93, 22,143, 59, 34,188, 74, 32,248,138,124,207, 93,
+ 98,251,140,207,230,201, 89,225, 14,232,123,199,177,212, 89, 79, 55, 56,223,220, 70,198,126,237, 63,245, 21, 78, 61,103,231, 8,
+182,230,150, 8, 44, 76,109, 33,142, 42,226,183, 54,111,162,149,243,118, 72,143, 87,191,143,153, 93, 89,217,176,182,202,114,224,
+222,246,134, 2,127,178,208, 22,189,202,214, 81,217,218, 71, 79,155, 72, 30,204, 23, 53,178,187,243, 23,216,142,162, 83,233, 82,
+ 84, 79, 66,238,167, 96,107,161, 56, 43, 9,104,118,106,167,102,150,232, 49, 18,235,241,223, 21,170,142,208,170,255, 0, 78,167,
+173,110, 30,236, 10,107, 52, 13,110, 33, 3, 37, 77, 83,170, 41, 81, 59,107, 74,215, 82,156, 19, 58, 10,168,221,196, 54, 18,173,
+160,174,160,245,175,109,112, 18, 81,205, 2,138,108, 30,118,250,123,169,163,162,175,232,141, 49,244,202,116,173,164,121,105, 61,
+146, 52,246, 56,244, 10, 21, 21, 44,154,205, 64, 94, 90, 33, 3,226, 39, 74, 81, 39, 85,176,202, 71,100,104,105, 67, 82,253,249,
+196,167,241,172, 31,117,117,205, 43,161,212, 81,219,158, 70,220,103, 80,211,105,222,181, 40, 10, 39,169,235,163,181,149, 73, 62,
+106, 39,102, 93,114, 82, 18,160,157,187,128,233,219,190,185,146, 80,119,151,165,194,112,157,203,112,132,120,142,154,238,165,194,
+ 18,232,173, 5,166,141,158,131,223,162,146,186,220,114, 78, 97,146,145, 67,220,235,149, 70,162,212,168,142, 41, 64,130, 64,250,
+117,208,229,205, 41, 82, 90, 41, 29,254,221, 22,171,180,162,242,225, 35,196,247,215, 80,201, 40,102, 59,239,182,167, 19,241, 37,
+ 53,175, 94,189, 52,147,165, 13, 52, 74,178, 18,241, 80,147,239,218, 79,112, 65,161,210,131, 20,150, 75,243,122, 23,227, 67,174,
+160,113, 88,119,164, 18,149, 29, 5,204,151,226, 86,165,126, 35,245,147,174, 81, 0, 87,133,134,252, 72, 31, 94,133, 42,186,155,
+100, 50,194,253,135, 92,162, 21, 90,237,174, 8, 19, 90,146,150,139,129,165, 5, 80,245, 29, 52,156,177,120,141,162, 82, 25,124,
+ 39, 7, 41, 86, 81,150,170,245, 17,184,129,178,194, 0,162,136, 20,211, 27,125,188, 68,106,159,221,238, 70,118,209, 68, 33,177,
+ 50, 51,100,195,117,104, 75,128,213, 72,241,174,156, 75,110,201, 51, 9,164, 83, 58, 63,148,166,201,182,103, 36,239, 50, 17,243,
+ 5,117,222, 28, 72, 82, 85, 95,104, 61, 14,184, 33, 13, 20, 11,134, 66, 77, 74, 8,114, 31,167, 46, 55,228,216,206, 68,203,240,
+155, 37,213,135,186, 63,230, 91,155, 67,178, 16,122, 20, 41,192,144,230,210, 59,132,168,105, 55, 66, 10,117, 5,252,214,230,172,
+113, 10,141,103,127,148, 79,165,220,194, 67,242,219,196, 28,178,203,120, 4,182,229,185,245, 68,137, 5,177,216, 52,203, 42,111,
+117, 42,127, 18,171,237, 81,237,164, 29,108,211,193, 76,195,204,215, 81,102,234,160,221,235,242, 76,244,236,236,118,227, 89,174,
+153,101,174, 74,212,132,191,116,122,224,153,138,141, 26,163,127,146,192, 67,104, 91,138, 29, 1, 89, 9, 20, 7,105,248,130,154,
+ 73, 98,211,193, 61,111, 56,220, 3, 83, 69,209, 62, 9,244,189,132,112,150, 17,103,226,187, 98,230,222,172,216,253,185, 10,179,
+ 78,189,169, 18,110,106,129, 49,231,149,229,186,180, 4,164,249, 78,133,165, 0, 1, 68,109, 26,202,185,182,208,193, 61, 70, 68,
+ 40,251,173,206, 75,135,248,149,207, 28, 21,148,199,248,243, 28,183,200, 67,108,219, 24, 64, 61,136,108,127,147, 84,151, 69,172,
+226,144,117,243,207, 20, 68,127, 26,179,198, 17,210, 34, 55,241,190,132,143,132,116,174,186,219, 70,164, 77,243,250, 84,226,211,
+134, 90, 22,222,247, 33, 52,160,122,128,164, 2, 52,238, 59, 38,158, 8,159, 88,243,197, 59,127,113,236,206, 40,168, 91,152,248,
+122,131,229,138,244,211,184,236,155,208,136,235,167, 30, 40, 29,203,184,173,150,116,120,118, 9, 22,200,114,225, 76,121,110, 79,
+135, 38, 50, 36, 71,147, 18, 58,107,177,196, 44, 20, 41, 42,112,160, 20,145,212, 87, 87, 94, 85,219,195,231,213, 76, 26, 43,247,
+ 38,134,229,205, 53, 7, 20, 26,183,113,237,138,200,148, 34,203, 97,179,218, 25,109, 5,166,219,182,218,216,130,132, 52,123,164,
+ 6,144,154, 3,236,214,163, 28, 32, 32,251,135,203,243, 56,159, 90,151, 69,130,243, 20, 9,248,135,106,120,105,113, 16, 68,214,
+ 82,167,109,146,100,131, 79,131,232, 26, 85,173, 13, 69,113, 46, 77,203,132,109,231,115,128,171,175,115,255, 0, 46,154, 88, 10,
+164,200,210,150,177,113, 78,228,248, 14,157, 43,236,215,116, 32, 30,164,236, 74, 90,210,146,142,128,251,252, 52,153,109, 18,129,
+213, 75, 2, 20,177, 85,168,235,135, 4,124,212,203, 27,185,191,101,172,134, 89,105,209,223,227,239,166, 55, 49, 9,176, 42, 70,
+210, 99, 6, 32, 41, 59,220,164,148,133, 37,216,155, 92, 2,130,157,171,166, 31,202,171,197, 73,127, 56,233, 8, 87,146, 95, 94,
+191, 63,231, 56,128,148, 39,240,143,112,212,149,181,176,128, 96,161,238,238, 77,201,169, 81, 23, 82,216, 79,226,161,246,123,244,
+241, 52,162,104,125,143, 48, 31, 45, 70,190,239, 29,118,168,180,170,108, 49, 22, 21,251, 66, 79,191, 93,170,230,149,225,200,161,
+191,141, 36,143,190,186,229, 87,116,173, 97, 53,252, 98,163,183, 65,160,186, 2,158, 97,201, 64,180,242, 4,122,212, 63,136, 71,
+113,148,154,208, 63, 18,243,105,119,117, 7,136,104, 56, 58,251, 78,131, 79,125,189,191,113, 81,219,195, 1,182,127,171,237, 9,
+ 38, 63,102, 55,219,154, 96,252,219, 54,248,237, 69,157,114,184,220, 31, 5, 77, 91,237,118,166, 87, 34, 75,197, 41,248,156, 40,
+101,181,108, 66,122,169, 84, 72,234, 70,156,202,255, 0, 12, 85, 83, 45, 45,157,119, 32,141,185,159, 66,157, 89, 99, 9,191,170,
+ 85,179, 28,157,145,197,189, 55, 26, 84,139, 90,111,173,198, 84, 59,241,132,133,186,182,135,144,173,208,157,113,164, 18,210, 9,
+116, 41, 84, 65, 80,168, 86,155, 54,115, 94,240, 20, 83,215, 91, 8,138, 50,230, 60,146, 5,104, 70,126,158,180,213,137,222, 17,
+ 1,219,187, 50,109, 81, 47,240, 46,246,177,111,145,107,159, 33,200,241, 22,235, 18, 99,204, 97,197,169,149, 33,210, 27,145, 21,
+ 5, 73, 66,146, 84,157,200,220, 2,142,141,115,164,140,122, 84, 86,221,112,251, 87,151, 50,152,130, 19,181,206,111, 50,191,111,
+151,146,194,149,152,139, 13,156,149,185, 39, 27,106, 85,179, 25,176, 37, 61, 66, 90,110, 8,106, 20, 36,162,191,133, 9, 72, 21,
+210, 81,201, 17,192, 0,148,159,234,164,172,133,206, 52,226, 43, 65,236,192, 33, 21,234, 85,155,148,161, 72, 70, 87,144,218,241,
+ 92,170,206, 24,146,156,194,108, 71,157, 94, 77,102,222, 27,145, 18, 91, 48,218,113,201,179,155,243, 18,228, 87,148, 18, 86, 2,
+208,243,155,124,181, 55,201,160,166, 44, 30,165, 33,182,239, 52, 5,179,187, 33,129,204,246,117,245, 31,105, 67, 43,231, 7,225,
+151,248,175, 39, 12,228,188,138, 29,236, 40,136, 41,206,241, 8,246, 60,114,236, 40, 58, 42,100, 27,173,197,203,122,214,170,132,
+ 7, 89, 83,125, 65, 91,173,138,168, 51,146,172,232, 42, 82, 13,214, 41, 77, 8,112, 29, 36, 97,238, 63, 20,202,205,151, 32,244,
+247,108, 69,165, 81, 26,135,203,119,168, 70,102, 85,144,180,166,166,207,195, 45, 51,201, 92, 43,101,166, 83, 69,196, 70,114, 84,
+ 63, 46, 84,169,145,215,189, 73,117, 12, 33, 73, 66, 93,243, 79,108,214,201,222,119,177, 48,222,239,223, 17,240,162, 56, 83, 18,
+ 58,248, 15, 86,125, 57, 32,130,178,251,149,190,240,197,211,230,165,162,107, 18,190,104, 75, 68,133,183, 45, 50, 1, 39,127,152,
+ 8, 88, 85,122,214,181,211,139,136,204,172, 33,167, 18, 21, 73,224,211, 3,138,245,201,188,203,149,114,108,139, 79,247,158,224,
+103,174,203, 1,235,116, 73,206,180,129,114,146,195,206,173,245, 42, 91,224, 7, 37,185,230, 56,175,219, 58, 84,178, 40, 10,136,
+ 2,144,251,126,204,219, 49,169,212, 47,199, 26, 15,127, 73,235, 56,162,198,199,202, 67,166, 58,156, 5, 1, 57,210,181,196,241,
+207, 51,138, 17,115,151, 22,122,127,228, 92,134,197,153,101, 89,231, 41,228, 23,105, 92,113,198,184,244,172, 91,143, 26,129,137,
+219,113,105, 56,181,142, 13,189,239,152,186,221,162,221, 21,113,121,111,176,181, 41,150, 33, 54,132,141,191,239, 10, 81, 82, 80,
+251,232,188, 87, 23, 26, 5,114,135,125,101,156, 76, 99, 65,113, 3, 28,104, 62,245,204,175, 83, 94,159, 46,124, 74,155, 6, 95,
+199, 89, 77,223,144, 56,151, 48,151, 50,213,107,188, 93,109, 72,178,101, 88,182, 83,110,105,183,164,217,175,112,216,145, 41,134,
+221, 12,186, 30,137, 41,151, 75, 82, 90,220,164,236,117,183,216,101, 25, 96,108, 31, 48, 10,201,183,223,141,193,186,153, 90,140,
+199, 16,168,254, 65,108,191,165, 59,230, 55, 37, 45,175,169,222,146, 7,223,162,198,232,201,238,167,238,212, 51, 80, 39,224, 56,
+129,248, 79,180,233,194, 73, 49,202,101,123, 72, 82, 9, 29,124, 52, 40,186,152,254, 81, 94,101,118, 43,111,126,222, 58,237, 16,
+170,254,131,104, 67,228,252, 36,129, 95, 29, 73, 40, 76, 86,245,173,109, 13,206, 44,109, 3,173, 78,185, 84, 99,130, 76,228,180,
+169, 63, 0, 6,181,234,157,116, 5,202,166, 89, 46, 58,162, 74,119,127, 70,142, 17, 14, 41,161, 75, 75, 78,135, 36, 34,164, 83,
+105, 34,167, 70, 68,200,226,164,112,167, 58,162,148,183,185, 65, 93,146,145,212,253, 90, 77,192, 12,210,172, 36,228,164,149, 43,
+ 72, 75,233, 90, 10,135,235, 10,105, 54,144,114, 74,185,132,102,151,196, 67, 17,209, 68,175,161,235,212,232, 28, 87, 3, 64, 75,
+126, 97,163, 64,149,117,215, 40,187, 85,181, 47,148,143,110,185, 69,213,169,201,105, 30,237,118,139,133,203, 79,156,133,131, 83,
+215,191, 77,118,139,149,170,196, 58,180,212, 54,242,146, 15,112, 14,138, 90, 14, 97, 25,174, 45,200,175, 52, 90,122,159,136, 31,
+172,232,203,139,198,194, 77,127, 14,186,139, 68,169, 40, 41,167, 90,232,164,213,118,139, 91,160,168,211,168,233,223, 93, 8, 20,
+133,200,171, 95,103, 40, 61,149,209,170,138, 90,180,249, 62, 73,248,148, 87,247,232, 86,168, 82,137,115, 84, 35,240,211,219,162,
+144,142, 10,199, 18,210,129, 73, 64, 80,246, 31, 13,114,136, 21,185,146, 27, 64, 72, 31, 8,236, 61,154,225, 11,160,209, 41, 18,
+ 27,255, 0, 71, 92,210,141,173,106, 91,205,247,233,162,232, 93,214,155,222,144,129, 95,132, 29, 20,177, 13,105,169,201, 81,170,
+119, 32, 87,232, 30, 58, 65,236, 67, 88, 76,107,146,202,114, 11, 61, 9, 2, 67,114,225, 20,237, 36, 18,118,184,138,154, 80,109,
+216,186,117,241,213, 7,157, 45,117,194,217, 7, 3, 79,111,244, 37, 88,244, 85,141, 20, 33,198,220,165, 41,172,164,182,133, 40,
+ 77, 83,147,237,121,238,195, 38,155, 68,166,187,159,110,140,193, 82,136, 74, 43,219, 27, 65,109, 13,138, 26, 0, 53, 37, 11, 81,
+106,159,188,148,180,131,219,177, 39,234,211,230, 49,118,170,179,102, 15,179, 63, 32,184, 60, 87,251, 56, 74, 76, 22,187,126, 48,
+ 60,199, 8,247, 18,164,143,164,107, 73,229,107, 95, 14, 34,242, 62, 99,238, 9,171,136, 42, 34,181, 71, 34,133, 93, 61,212,213,
+197,141, 70,168,162,110,112,138,254,192,253, 64,105,112,213,194,228,162, 50,228, 87,227,208, 32, 46,180,149,170,228,200,125,174,
+189,254,142,186, 13,193,117,216,168,128,107,202,119,168, 61,254,173, 41,154, 70,138, 77, 22, 66, 91,108, 18,118,244,246,233, 34,
+150,105, 74,133,230, 50,122, 23,122,142,253,117,205, 40,250,194,240,171,234, 17,209, 14,168, 39,216, 21, 65,174,104,170, 30, 34,
+ 76,229,229,135, 63, 18,170,125,167,219,161,161, 15, 18,169,166, 69,217, 85,163,106,220,159, 96,166,186, 26,184, 92,180, 53, 37,
+114, 78,208,218,214,163,224,145, 93, 3,221, 64, 85,202, 87, 3, 21,189,206,111,204,102, 11,190, 95,122,237,166,154, 62,242, 56,
+243, 41,236,118, 82, 60, 84, 4,217,113,182, 73,183,172,181, 41,165, 52,177,224,164,233, 72,230,108,152,180,164,100,137,209,154,
+ 16,152, 92,113, 33, 36, 40,130,116,162, 79, 52,195, 38,122,216, 36,208, 20,138,246,166,186, 23, 43, 69, 44,193, 46,159, 51, 39,
+ 35, 97,191,196,238, 27,145, 23, 5,122, 22,226,180, 31, 63,103,149, 93, 1,131,135,106, 99,186, 29, 86,239,236,251,194,243,140,
+228,144,172,215,101, 59,114,101,233, 22,155,133,182,239, 98,187, 55, 24,143,155, 69,186,249, 21,216,174, 58,200, 82,146,146,236,
+127, 55,205,105, 42, 80, 5, 73, 0,154, 19,167,115, 55,196,109, 21, 50,198,235,232,229,108,148,168, 25,246, 28, 18, 27, 84, 11,
+ 38, 25,118, 70, 84,238,121,100,200, 63,135, 71,158,253,138,209,100,133,114,106,235, 34,236,243, 14,183, 17,114,126,114, 4, 88,
+209,155,140,242,210,227,192, 60,178,118,237, 64, 80, 86,240,204, 68,231, 26, 17, 69,101,186,222, 97,240,206,135, 85,196, 26, 10,
+ 30, 61, 53,195, 4, 51, 93,249,216,138, 42,105,229, 36,143,234,170,154,118,230,135,102,169,237,121,110, 74,199, 75,202, 68,187,
+156, 44,166,197,142,242,205,226,195,108,152,216,196, 46,119, 76,138,223,198, 24, 76, 43, 69,180,128,152,141,162, 76, 59,132,121,
+155,208, 41, 41,102, 96,243,138,148,167, 27, 5,194, 53, 10,235, 38,234,212,231, 0,229,118,139,122,144,196, 34,130, 23, 57,148,
+165, 78, 0,244,215, 2, 61,232, 8,223, 25,228,185,174, 77,114,155,103, 70, 19,141, 99,242, 47,111, 72, 44, 61,201,214, 11,138,
+177,203, 76,231,212,164, 54,150,209,113, 19, 38,252,179, 71,106, 67, 76,149,174,157, 19, 83, 77, 63, 55, 76,104,165,106,171,237,
+217,174, 38,113, 45,101, 5,120,145,128,251,232,161, 8,203,159,200,230,102, 24,196, 46, 35,228,206, 58,127, 30,181,222,239,216,
+158, 65,147, 9,143,193,201,108,216,210, 86,244,150,110, 77,200,183, 68,110, 44,135,160, 54,228,150, 94, 97, 97, 27,145,228,249,
+103,120,113, 44,152, 68,142, 26,169,138,152,190,219, 5,188, 69,241,147, 86,244,241,247, 33,125,171, 36,114,241,144,216,237,153,
+ 3,198, 37,174,227,120,181, 91,238, 23, 39,186,139,125,186, 75,205,180,227,196,168, 80, 6, 90, 37, 95, 86,156,186,212,102, 10,
+174,178,224,184,128,236,149, 70,205,125, 74,250,136,103,158,238, 24,141,150,217,116,110,211,111,207,100, 97, 49,189, 54, 24, 74,
+127, 12,184,178,196,227, 5, 54, 71,172,233, 65, 68,153, 79, 37, 33,147, 63,105,150, 92, 62,114, 94, 15, 81,122,142, 99,156,204,
+201,170,208, 13,148, 37,154, 3, 6,158,143, 78, 61,121,163,239, 40,226, 17, 45,152,238, 59,124,141,196,220,145,196,115,174,121,
+151, 32, 99,235,176,242, 30, 89, 11, 52,122,245,106,199, 35, 88, 36,197,185,219,166,219,173,118,216,110, 70, 91,183,105, 17,129,
+105, 79,130,182, 85,251, 98,173,201, 76,165,188,134, 74,234,224,169,123,165,140,118,101,190, 25, 36, 26,241, 7, 46,196,212,197,
+155, 12, 71, 33,241,239, 8, 61,130,222, 46, 23,206, 66,193,109,183,217, 28,154,238, 76,184,238, 89, 51, 12,182, 3,179,108,208,
+225, 90, 91, 96, 69, 84, 54,220,242, 35,205, 84,135, 22,234,247,169,198,148,206,192,133,176,155,116, 16,202, 35,235, 82,246,188,
+190,217,237, 12,213, 58,180,147,213,135, 5,230,241,199,214,235,183,167, 63, 80,150,217,237, 49, 33, 56,229,163,141,249, 18,222,
+219,205,111, 12,223,237,121, 69,179, 31, 67,237,154,209, 43, 76, 12,158, 99,117,167,225, 90,135,142,163,247,121,245,196, 93,209,
+ 68,243,148,199,135,112, 91,192,180,251,168,185,107,148,241,212,107,188, 23, 35,150,218, 10,218,173,170, 13,128, 65,167,209,170,
+212, 23, 70, 55, 84, 21,161,201, 0,144, 81, 83, 76,139,143,151,108,184, 63, 13, 96,146,133,157,164, 14,154,183,219, 92,120,237,
+ 5, 87,230,140,196,234, 40,155,152, 59,157, 74, 81,184, 87,182,207,111,213,167, 26,146, 85, 90, 63,184,202,216, 71,144,124,205,
+226,131,103, 77,189,122,246,209,117, 26,245, 35,212, 81,125,205,198,154,196,150,247,167,162, 79,186,154,150, 34,138, 24, 56, 57,
+106,113,131, 55,115, 77, 5, 43,161, 38,158,237, 54,184,186,109,168,171,144,211,175, 36,200,227, 78, 68,171,116, 35,105,165, 15,
+126,154,113, 28,130, 81,168,100,147,166,149,250,212,149,175,225,242,119, 31,109, 43,215, 74, 81, 24, 21,142,197, 75,157, 93,100,
+123, 69, 83,219, 64, 32, 69, 82,171, 43,141,218,103,137,143, 53,243, 9, 79,224,104,167,225, 20,210, 23, 49, 25,219,164, 26, 37,
+237, 37, 22,238,212, 69, 83,165,223, 33, 23, 9, 1,208,194, 24, 64,236,148,138,116, 26, 45,181,183,128, 41, 84,123,187,191,169,
+117,105, 68,219,252, 85, 31,214,211,157, 41,166,165,233, 23,100,120,125,186, 5,168,106, 91,133,241, 35,166,238,222,237,115, 66,
+238,181,233, 55, 48,241,168, 63,118,134,154, 33,170,169, 75, 18, 22,235,169,109, 0,169, 74, 61, 0, 29, 78,138,227,164, 85, 25,
+160,184,208, 41, 33,182,207,105, 41,113,198, 22, 18, 69,107,180,246,211,113,112,215, 26, 2,156,186,217,237, 21, 33,123,109, 73,
+165, 21,220,119, 4,105, 84,142, 73, 83, 45, 9, 10,216,208, 78,239,105,209, 92,253, 57,163,177,154,206, 11,203,209,203, 42,218,
+163,215,220,117,208,250,174, 61,154, 51, 94,118,110, 27, 71,218,116, 42,185, 69,134, 50,169,212,253,199, 67, 85, 87,116,164, 15,
+130,223, 64,138,211,219,163, 2,136, 66, 72, 30, 88, 61, 69, 7,209, 77, 26,136,181, 91,170,149,129, 85, 83, 92, 93,205,120, 82,
+195, 99,162,171,174,132, 50, 73, 92,152, 18, 59,232, 81,112,185, 35, 92,181, 30,218,225,193, 12,214,131, 33, 74,168, 39,175,209,
+164, 30,240, 18,173,109, 85,124,245, 7,207,152, 87, 0, 96,247,108,215, 49,148,243,112,109,209, 29,146, 68, 64,211,178, 1,109,
+ 36,245, 67,142, 54, 0, 52,232,107,223,167, 83, 65,166,165,250,240, 79, 32,181, 51, 26, 5,243,154,223,231, 85,146,103,190,170,
+248, 73, 86,219, 92, 43, 23, 19, 90,121, 46,203,109,190, 7,227, 37,153,211, 49,252,137,195,108,150,243,155,156,124,160, 70, 98,
+ 90,164, 37, 33,125, 84,129,216,106, 23,125,180, 23, 54,210, 71,196,138,250,198, 33, 72, 62,196, 66,211,196,175,176,120,210, 26,
+118, 43, 15,160,130,151, 26, 74,193, 30,197, 13, 96,238,114,142, 33, 43, 69, 23,242,228, 0,127,222, 90,165,124, 58,232,209,148,
+ 66, 17, 82,200,138,120,246, 21,212,173,176,170, 37, 18,219,228,145, 18,223, 42, 73, 52, 12,178,226,207,208,145, 93, 73,198,205,
+ 69, 21,238,160, 85, 2, 99,147, 42,165, 74,109,105,114, 82,221,150,160, 83, 66,149, 75, 81,112,143,168,174,154,216,118,168,132,
+ 80,177,163,128, 9,179,218,232,205, 8, 72,217, 91, 68,148, 57, 80,126,141, 76, 0,186,218, 37, 64, 50,142,173,141,223, 86,186,
+143,128,201, 40,170, 74,106,144,106, 7, 81,174, 35,102,145,173,224, 65, 73, 30,222,135, 66,136, 85, 51, 61,176, 40,149, 36, 10,
+ 30,228,107,168,169,166, 91,128, 32,159, 48,129,225, 65,236,215, 80, 42, 42,101,254,213, 73,173,122,253,103, 71, 73,165,205,169,
+107,237,219, 68, 40,192, 47, 43, 74,234, 69,116, 42,187, 69,229, 59,144,107,225,161,154,232, 10, 67,100,191, 55,106,148,153, 11,
+142,151,194, 72, 59, 20, 42, 13, 52,222,120, 76,162,149, 78,109,231, 16,154,145, 84,107,182,243, 60, 70, 88, 12,170, 19,108,171,
+176, 9, 72, 29, 53, 16,253,171,173, 78, 51,121, 20,201, 43,147,150, 98, 89, 70,196, 74, 97,180,201, 89, 9, 36, 80,117, 86,154,
+155,121,109,126, 92,146,166,226, 27,191,155, 53, 15,204,112,168, 81, 45,142, 92, 45,170, 36,132, 23, 54, 82,189, 59,232,182,219,
+179,181,233,122, 74,231,107,104,110,166, 42,181,113,188,165, 42,117,167, 21,181, 73, 42, 4, 30,148, 35, 86, 16,107,138,174,147,
+ 76, 20,163,135,100,202,185,230, 23,123, 92, 6,100, 79,153, 51, 4,228, 6,226,194,132,194,228,202,146,242,109, 50,150, 18,219,
+104, 5,107, 39,111, 64, 6,134,170, 17,218, 19, 75,230,151,194,240, 49,238,148, 69, 86, 51, 43, 20,227,236,211, 33,228,158, 59,
+228, 43, 77,190,219, 51, 20,147, 19, 38, 77,137,251, 83,150,152,115, 94,126, 27,251, 17, 57,150, 98,207, 14,200,149, 23,246, 5,
+230,212,105,185, 46, 38,138, 10, 90, 91,141, 36,105, 32,245, 42,214,223,181,155,128,230,202,215, 55, 0, 65,161,251,243,173, 71,
+177, 87,235,199, 37,112,189,145,179, 53, 87,252,211, 46, 90, 65,113,140,126, 30, 50,206, 44, 36,168,117, 13,203,184, 61, 62,104,
+136, 61,165,136,239,248,128, 71,226,209, 29,116, 78, 65, 59,143,151,168,123,239,195,168, 99,251, 61,235,198,117, 38,210,236,139,
+110, 79,136,160,127,115,115,107,115, 57, 30, 56,134,156, 91,232,181,137, 66,147, 45, 75, 90,212,181,151,108,243, 67,145, 23,189,
+ 69, 74, 8, 75,157, 82,226, 73, 90, 25, 60, 70,227,159, 21, 17,185, 90,125, 28,165,160,119, 78, 35,179,246,100,135,124,165,199,
+ 14,115, 38, 86,156,250, 31, 42, 98, 54, 36, 95,217,183,140,162,211,157,203,186, 34,237,138, 79,132,195,109, 73, 84,100,198,183,
+204, 76,232,111, 56,133, 59, 17,184,202, 46, 33, 42,242,148,216,216, 22,182, 47,129,192,154, 10,171, 45,166,239, 11,163, 26,221,
+ 71, 1, 66, 49,225,209, 64,164,144,239, 44, 68,137,136,241,110, 43,153,223, 44,184, 6, 57, 29,155, 19, 23, 59,140,199,236,145,
+ 46,247, 11,164,199,164,220, 47,151, 8,113, 93,125, 12,249,210,101,172,165, 35,204, 91,113,208,211, 69, 75, 40,169, 80, 70, 98,
+110, 2,165, 66, 94, 95, 11,249, 51, 33,153, 15,137,244,203, 4, 66,131,103,114, 11,156,139, 99,151,141,115,101,142,219,141,180,
+109, 86,220,211, 47,190, 34,197,141,114, 21,241,233, 76, 50,152, 80, 44,194,222,255, 0,205, 54,236, 55, 28,152, 93,106,232,234,
+ 3, 41, 10, 81,253,171, 97, 77,132,207,159,133, 20,133,230,223, 14,219, 22,179, 33, 36,210,157, 7,179,212,164, 14,241, 6, 63,
+114,193,173, 51, 26,125, 16,179, 43,165,194,248, 32,218,238, 37, 49, 45,153, 4, 40, 63, 40,132,196,133, 37,123, 90, 19,218,113,
+197, 56, 35,184,160, 93, 66,210, 27,171,128, 33,198,178, 76,232, 94, 26,227,159,177, 35,109, 96, 47, 96, 50,197,137, 4,138,113,
+200,100,130,119, 91,159, 46, 71,156,238, 46,139, 84,166,111,141, 69, 56,216,185,187,199,176, 71, 39,179,107,242,254, 91,248,112,
+191, 42,219,253,228, 67, 30, 71,236, 62, 88, 75, 8,242,255, 0,103,183,103,195,169, 86, 70,218,107, 35, 20,193,215,179,134,248,
+ 58,141, 50,167, 30,206,159, 82,215, 35,133,114, 44, 58, 21,165,121,117,165,235,106,174,127, 61, 34, 37,174,106,194, 39,196, 92,
+101, 33,167,188,248,181, 46,196,112,168, 36, 20, 58,148,172,128, 9, 78,221,164,179,150,231, 89,163, 82,205,178,116, 0,107, 4,
+ 84, 84, 85, 73,110, 88,204, 40,190,161,253, 53, 95, 12, 95, 45, 51, 49, 78, 63,184, 33,234,124, 62, 70, 51, 50,225,111, 89, 7,
+216,147,108, 90, 79,208,117, 90,187,111,251,166,158,176,180, 13,177,255, 0,255, 0, 92,122,154,239,189, 68, 38,216,158,115,134,
+125, 77, 50,211, 46,167,230,120,139, 26,112, 2,217, 3,100, 94, 64,194, 29, 81,237,250,169, 73, 36,233,230,224,223,201,119,171,
+237, 10, 15,150, 78,155,159,238,159,185,114,198,234,184, 54,165,249, 47,144,243,171, 52, 75, 96,248,157, 64,195,107,226,100,180,
+ 9, 46,180, 96,171,214,109,140,170, 85,203,231, 62, 87,201, 67,164, 30,162,189, 15,213,171, 30,223,220,110,149, 9,118, 75,141,
+ 84,110, 30, 44,144, 72, 91, 1,104, 62,196,245, 26,145, 41,158,164,249,253,205,103,202,243,190, 91,221,248, 77,104,126,173, 21,
+ 13, 75,234,222, 52, 23, 90, 77, 58, 0, 60, 1,233,169,162,229, 22, 27, 68,241, 14,123,214,245, 40,183, 28, 45, 68, 82,164, 87,
+191,213,168,189,195,109, 27,128,163,138, 81,146,104, 80,235,245,194, 72,146,149,150, 85, 87, 85,248, 80, 9, 0, 19,167,214, 86,
+162,217,154, 1, 72,202,243, 90,167, 24,242, 3, 12, 37,197, 55,241, 20,133,109,167, 90,233,114, 42,140, 29, 64,189, 66,184,189,
+ 49,107, 14, 69,216,129,248, 79,180,125,154, 5,180, 65,175,213,193, 47, 90, 42, 40, 26, 20, 62,237,113, 24,166,215, 97,133,154,
+171,160, 62, 26, 54,170, 34, 22,213, 36, 48, 90, 77, 77,122,125, 58,237, 87, 52,164, 82, 18,210, 1,162,210,159,125,105,174,133,
+195, 68,145, 17,212,231,196,149, 84,123,141, 70,187, 84, 90, 85, 63,217,212,212,103,191,222,144, 92,108,138,105,181,195, 92,241,
+221, 41,213,179,219, 25,239, 12, 19,148,105,194, 21,209, 50, 88, 96,169,148,170,187, 72,168,209, 12,101,236,161, 56,163,137,132,
+114,106,104,193, 26,227,103,182,137, 16,188,185,113,144, 22, 27,219, 77,180,235, 79,163, 80,167,109,123, 93, 80, 85,128,110,177,
+ 61,148,112, 66,107,165,221,151, 38, 58,184,224, 33,162,162, 82, 7, 78,154,156,134, 50,214,208,170,236,242, 7, 58,161,126, 68,
+190, 33,179,248,138, 79,180, 42,154, 59,163,170, 35,100,210,157,145,115, 75,230,163,226, 39,198,181, 58, 41,109, 17,245,234, 82,
+ 91, 85,190,101,205,105,110, 51, 10, 90,143,106, 13, 53,154,118,196, 49, 41,196, 16, 58,115, 70,133, 33,147,134, 95, 88, 70,243,
+ 25,106, 20,175, 65,219, 77, 27,185, 70,120,167,142,219, 37,104,201, 67, 46, 22,217,241,220, 45,190,210,155, 87,177, 66,154,125,
+ 20,237,144, 96,152, 75, 11,163, 52, 33, 50, 57, 18, 74,122,169, 53, 26,112, 28, 18, 5,165,105,216,176, 40, 69, 7,191, 70, 92,
+165, 23,238,212, 1, 69,119,208, 92, 90,254, 89,133, 84,147,245, 87, 68, 46,162, 48,104, 41,178, 98,216,140,133,173, 74, 66, 16,
+132,169, 75, 90,148, 18,148, 37, 61, 73, 36,246, 0,105,187,228,162, 93,177,213,113, 71,215, 7,230,161, 23,133, 47, 23, 78, 52,
+225,187,124, 75,222,115, 21,130,153,119,219,139, 63, 51,105,182, 60,179, 74,180,144, 20,219,165,190,164,239, 52,240,167,142,161,
+ 55, 29,205,150, 77,171,138,210,121, 67,144,102,230, 23, 7, 56, 16,207, 79, 98,249, 76,245,117,207, 92,253,206,247,213,101, 92,
+175,149,203,202, 84,219,143,187, 13, 13, 69,110, 5,186, 10, 94,240,102, 60,102,153,109, 32, 10, 10,169, 53,246,147,168,123, 62,
+103,138,224,150,212, 2,180, 13,231,203,185, 54, 72,245, 68,195,167,167, 18,168,253,186,249, 33,185, 41, 59,212,133, 37, 85, 20,
+ 36, 41, 42, 7,191,186,154,115, 45,222,190, 43, 60,184,219,206, 84, 95,208,163,242,238,252,197,248,139,212,167,167,222, 57, 98,
+231,200,120,236,110, 99,179,227, 54,171, 22,125,134,221,110,173, 65,201, 63,188,150,134, 16,204,153,140,198,117,105,118, 68,121,
+171,108,190,211,173,133, 38,138,218, 72, 90, 84,145,143,239, 27,108,150,146,184,134,157, 4,212, 30, 20,253,138,167,119,100,251,
+119, 26,131, 78,149,211, 11,102,125,143,165,168,143, 75,188,219, 99, 50,245,194, 4, 54, 29,126, 99,109, 33,217,115,220, 75, 76,
+180,146,162, 1, 83,174,173, 40, 66,123,146, 64, 29, 78,162,224,212, 77, 40, 83, 35, 26, 57,194,202,236,150,230,139,146,238,144,
+154,220, 40,128,185, 41, 10, 87, 74,244, 21,169,232, 53, 96,179,141,210, 96, 1, 37, 54,112, 81,252,135, 41, 55,214,255, 0,134,
+194,142,240,183, 60,105, 58, 91,233, 49,252,216,255, 0,172,219, 72, 80, 14, 18,224,233,186,128, 0, 73, 4,158,154,187,237, 27,
+ 20,146, 56, 62, 65, 65,215,159,177, 35,137,112,168,193, 68,111, 73, 55, 39,150,251,141,161, 37, 68,244, 72,160,235,245,106,255,
+ 0,105, 8,183, 20, 9,107,137, 13,193,212, 84, 65,118,198, 89, 81, 90,208, 69,123, 87,182,164, 3,234,155,104,162,210,166,155,
+ 72, 81,109, 73, 3,217, 94,180,215,106,133, 18, 1, 49, 44,168,138, 5, 87,167,125,118,139,129,212, 73,164, 54,235,135,207,104,
+123,233, 94,250, 21, 93, 35,138,107,125, 72, 89,253,170,118,145,220, 87,217,174,174, 38,135,204,101,133, 38,180, 62, 26, 21, 67,
+ 5, 29, 92, 97,231,110, 66, 9,240,174,143, 84, 74, 37,108,238, 77, 52, 68,112,156,130, 27, 41, 10, 93, 61,253,117,196, 96,188,
+ 58,195, 69, 33, 77,120,248,123,244, 16,160, 72, 86,135, 54,148,134,250,142,190,253, 4, 19, 60,167, 84, 62, 21,164,160,138,245,
+241,215, 40,185, 84,192,253,201,113, 28, 75,205, 60,226, 92, 66,183, 2, 20, 71, 81,162, 57,186,176, 64, 59, 73,168, 69,203, 31,
+ 40,197,145,108, 16,239, 47,160, 39,203,242,138,150,170, 84,118,241,213,110,247,109, 37,213,106,178,217,238, 96,183, 75,208,115,
+144,113,235, 52,182, 36, 94,172,183, 38,137, 1, 75, 83, 72,116, 10,215,221,163, 90, 94, 73, 1, 12,120, 77, 47, 45, 35,144, 23,
+176,170,171, 54,237, 37, 14,173, 41,144,182,212,157,237,149, 54,225, 74,138, 15, 66, 42, 60, 8,239,171, 5, 42, 42,160, 53, 83,
+ 5,238,221,101,106,232,203,207,174,224, 16,180, 36,168, 33,107,252, 68,106, 62,226,224,194,105, 68,254,222,220, 74, 43, 85, 26,
+126,212, 29, 90,218,117, 37, 73, 66,136, 10,165, 65,210,161,218,133, 82, 46, 26, 74, 37, 96, 25,204,172, 38, 28,156,118,117,158,
+ 14, 89,132,206,159,252, 82,102, 49,117,125,216,134, 45,209, 77,165,149, 77,183, 76, 96,135,224, 73, 83, 40, 74, 20,161,185,183,
+ 2, 80, 30,105,208,218, 2, 64,115,152,106, 19,123,155, 88,238,219,166, 65, 81,239, 29,158,148, 83, 43,159, 36,240,132, 0,244,
+184,152, 7, 38, 93, 37,109, 82,162,216,238, 89,189,182, 29,173,151,141,118,135,231, 71,179,153, 18, 80,147, 77,201,109,150, 84,
+161,217, 72, 61,116,169,186,121,232, 81, 99,151,225, 6,165,206,167, 70, 31,109, 62,229, 11,143,204, 24,158, 97, 18, 69,171,144,
+113,168,120, 18,161, 72, 82,240,252,131,142,113,223,156,133,109,183, 60, 42,229,182,237, 22, 76,207,159,184, 52, 29,253,179, 83,
+213, 37,217, 40, 42,113, 10, 75,205,150,146,199, 34,184,115, 14, 56,163,222,108,177,204,208, 35,163, 72,247,246,241,245,250,186,
+ 40, 85,226,252,211,132,236,247, 22,153,200,249, 78, 94, 86,218, 82,150, 34,196,197,241,171,156,105, 17, 27, 89, 63, 10,157,191,
+ 71,182, 52,194, 91,174,250, 52,151, 55, 31,132,109,174,244,175, 36,245, 29,209,237, 85,201, 54, 23, 49,255, 0,154,254,239,245,
+106,126,218, 15, 79, 90,184, 18,185, 11,136,236,184, 29,219, 30,145,156, 72,157,142,231, 11,131,101,200,158,117, 2,223,110,181,
+ 99,179, 94, 75, 82,229, 38, 40,118, 88,114, 95,202,173,105, 67,165, 7,202, 73, 81, 70,245, 20,169, 12,238, 30,102,195, 74,147,
+218,173,134,219, 95,204, 38,166,148, 24, 10,116,211,137,251, 58,248, 81,139, 95, 39, 55,103,196,159,139,148,114, 86, 81,105,183,
+ 69,131,149, 53, 39,138,240,142,108,191,229,248, 74,236,176,175,120,148,123, 91,209,163, 68,204,155,105,217, 82,160,204,189,180,
+168,130,227,181, 45, 71,109,245, 52,148,245, 90, 47,104, 24, 43,100, 47, 36, 2, 84,195,143,189, 68, 65,226,235, 86, 9,109,197,
+ 51, 59,157,155, 1,118,223,147,228, 55,123, 12, 62, 69, 68, 27,223,241, 20,192,188,202, 98, 28,135, 35,228,110,188,196,137, 14,
+197,136,209, 34,206,202, 75,133, 0, 45, 91,194, 92,139,154,216,183, 22,146, 58,129, 42, 74, 25,195,176,112, 7,180, 5,179, 36,
+229,156, 90,103, 49,225,185, 46, 75,202,151,140,202, 37,139,143, 39, 94,219,204,162,231,210,155,200, 88,157, 18,211,117,184,194,
+106, 28,193, 52, 63,108,150,102, 41,157,176,146,234, 74, 31, 89,105, 72,220,165, 36,194, 72, 31,226,141, 68,154, 12,235,212, 84,
+176,211,225,154, 83, 60,148, 67, 59,230,118,114,156, 65,252,102, 47, 59,228,156,181, 38, 70, 53,101,129,123,199,249, 11,157,178,
+ 43, 38, 13,151,200, 23,107,146,174, 87, 23, 98,221, 47,118,125,139,138,166, 32, 53, 10, 19,133,162,182, 21,243, 37,165, 45, 42,
+ 80,146,100, 50, 22,210,181,237, 39, 21, 30,233, 89, 94,133, 90,174,124,101,233,210,110, 83, 26,249, 10,225, 5,219, 4, 44,237,
+190, 57,147, 99,151,152, 72,243,110, 42,159,146,177, 33,188,147,206, 47, 48,240,183, 53,138,187, 46, 34,222,109, 65, 2, 67, 13,
+ 58,176, 4,128,157, 73, 67, 24,104,161, 9,156,146, 84,212, 21, 3,229,126, 53,192,219,197, 49, 23,176,214, 44, 50,166, 73, 82,
+127,140, 76,133,125, 69,214,235,231,151,238, 73,242,221, 65,201,230, 58,132,121, 77,178,122,217,153, 3,225, 62,113,221, 71, 22,
+ 99, 3, 50, 9, 55,188,187, 50,163, 24,167, 1,203,189, 70, 15,180,150, 17,219,224, 82,192, 87,223,166,211, 95,182, 19, 66, 19,
+168, 44, 95,112, 42, 17,120,122, 91,145,252, 9, 82,183,181,243, 1,196, 36, 55,189, 59,104, 66,191,201,166,255, 0,205, 69,114,
+193, 59,254, 80,237, 53,174, 43,177, 13,127,183,245,234,222,171, 1, 46,240, 61,180, 68,112,152,166,254,249,191,236,253,199,239,
+123,253, 90, 56, 73, 59,212,180,191,217, 63,187,209,154,131,146,168,189,135,238,254,174,218,225, 93, 9,196,246,240,250,251,107,
+136,201, 11,255, 0,236,248,232, 5,194,153,101,118, 87,244,104,225, 36, 84,114,127,238, 85,251,191,246,180,112,146,118, 73,202,
+203,253,144,126,235,191,235,104,174,205, 30, 60,147,243, 63,139,255, 0, 55,250,244, 66,149, 9,221, 29,191,243, 95,233,210,101,
+ 25,107,119,177,253,215,251, 29,181,208,130,142,191,251,195,248,127,218,210,161, 36,228,145,127,137, 63, 95,225,209,130, 42,145,
+ 90,251,143,197,220,118,239,164,100, 75, 49, 89,222, 47,236,127,179,118,253,127,222,106,177,186,171, 94,207,151, 4,112,119,240,
+143,220,246, 63,188,212, 2,176, 4, 23,207,127,122, 63,225,157,143,225,253,230,167,246,204,184,170,246,235,159, 4, 28,147,217,
+ 95,131,199,232,213,129,138,186, 84,125,238,255, 0, 95,135,109, 46, 18, 37, 33, 95,143,255, 0,173,160,184, 22,132,246, 63, 87,
+109, 34,244,172,104, 75,205,255, 0,252,169,207,255, 0,226,255, 0,247,102,235,255, 0,119,255, 0,227, 63,187, 87,246,127,244,
+189,154,143,149, 73,216,255, 0,152,220,179, 25,228,190, 19,175,159,138,231,253,167,254, 39, 51,251, 95,246,191,222,171,247,255,
+ 0,254,119,253,167,250, 85,214, 63,204, 95,231, 59,231,207,138,247,135, 40,255, 0,218, 71,254, 95,202, 62, 95, 79, 98, 25,228,
+191,217,135,252, 63,247, 8,254,219,253,135,177,252,126,239,235,106,154,207,159,241,103,195, 53,111,191,255, 0, 36,252,153,113,
+203,250, 21, 57,203,191,226, 19, 63,238,167,227, 87,252, 39,247,191,243,251,117,160,109,153, 15,243, 63,188,188,231,205, 95, 59,
+191,237,255, 0,185,159,244,169, 22, 29,253,162,219,253,183,251, 92, 79,248,127,246,207,198, 63,115,254,159,245, 61,250,155, 11,
+ 54,184,245, 46,164,207,255, 0,185,184,111,255, 0,237,207,253,228,177,255, 0,223,127,251,143,217, 95,240,143,255, 0,124,255,
+ 0,176,211, 88, 62, 99,242,101,195, 63, 95, 82,141,103,207,255, 0, 79, 46, 25,250,215,208,239,229,163,255, 0,123, 83,255, 0,
+204,207,248, 19,191,252,218,255, 0,188,221,217,252, 30,239,235,123,180,134,223,255, 0,124,222,195,150, 94,175, 76,170,173, 55,
+223,255, 0,133, 47,249, 92, 62, 76,255, 0,189,233,157, 23,114,252, 71,226,240,255, 0,144,214,143, 18,196, 28,148, 55,251,196,
+118,238, 63,121,219,235,211,151,100,143, 30, 97, 32,202, 63,118,215,238,127, 8,253,215,215,223, 92,180,204,230,148,188,200,100,
+134,174,254, 35,251,207,171, 82, 10, 56,164,209,255, 0,180, 15,195,223,254,187,240,104,143,201, 25,153,169, 60,143,236, 95,249,
+159,135,238, 63, 30,154, 55,230,226,159, 73,242,240, 80, 57,223,140,233,224, 76, 74,100,255, 0,174, 31,131,241, 15,197,248,126,
+189, 25,217, 46, 55, 52,188,119, 87,246,110,222, 26, 73,153,113, 74,191, 62, 9,173,207,222,159,195,248,143,224,210,195, 36,146,
+221,250,159, 80,239,219, 69, 93, 9, 68, 94,222, 30, 63, 78,184, 81,154,188,171,247,199,183,213,160, 87, 70,105,150,225,217, 95,
+186,241,252,125,244, 17, 74,132,205,236,191,220,118, 58,225, 92, 80, 75,143,246,103, 63,214, 63,131,250, 52,153,205,119,130,143,
+183,255, 0, 13,147,253,191,177,253,231,246,111,175, 76,230,249,198, 73, 70,252,135,230,245, 33, 61,231,183,255, 0,194,127, 18,
+191,113,251,255, 0, 30,250,154,118, 67, 37, 13, 30,103,230,245,173, 86,207, 15,163,254,175,183,215,168,217,189, 74, 78, 47, 90,
+148, 69,236,127,178,127,229, 52,138, 88, 44,147,248, 85,255, 0, 12,236,123,254, 47,171, 68, 62,180,113,234, 80,185,157,149,253,
+143,199,190,186, 81, 20,105,207,214,254,197,254,215,109, 20,174,168,172,239,223, 15,236, 94, 63,217,191,123,227,165,152,155, 92,
+101,195,214,191,110,223,240,164,127,199,255, 0, 8,253,247,246, 79, 31,187, 71,114,137,143,230,252, 42, 34,215,246, 83,251,206,
+199,240,254,239, 76,228, 83,236,201, 70,229,118, 87,238,187,159,199,223,234,210, 46, 75, 4,208,143,196,127,180,248,254, 15,193,
+219, 77,164,254,234,116,207, 90, 65, 23,251, 74,191,179,126, 35,251,207,197,167, 13,201, 32,252,212,246,223,216,127, 98,237,250,
+223,135, 70, 40,138, 75, 11,241,143,236, 94, 31,187,208, 93, 8,197,137,254,175,252, 67,191,254,107,248, 52,210,124,255, 0, 10,
+121,109,253,239, 82,177,131,254,234, 47,254, 39,253,161,175,252,111,225, 94,163, 63, 31, 5, 57,255, 0, 75,241,125,235,255,217,
};
diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c
index 626aec10a2e..230e8b69de9 100644
--- a/source/blender/src/toets.c
+++ b/source/blender/src/toets.c
@@ -73,6 +73,8 @@
#include "BIF_editseq.h"
#include "BIF_editsound.h"
#include "BIF_editmesh.h"
+#include "BIF_imasel.h"
+#include "BIF_editparticle.h"
#include "BIF_interface.h"
#include "BKE_object.h"
#include "BIF_poseobject.h"
@@ -108,6 +110,9 @@
#include "BIF_poseobject.h"
+#define VIEW_ZOOM_OUT_FACTOR (1.15f)
+#define VIEW_ZOOM_IN_FACTOR (1.0f/VIEW_ZOOM_OUT_FACTOR)
+
/* ------------------------------------------------------------------------- */
static int is_an_active_object(void *ob) {
@@ -155,6 +160,7 @@ void persptoetsen(unsigned short event)
float phi, si, q1[4], vec[3];
static int perspo=1;
int preview3d_event= 1;
+ short mouseloc[2];
float new_dist, orig_ofs[3];
@@ -243,14 +249,20 @@ void persptoetsen(unsigned short event)
if(G.vd->persp==2) {
G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
}
- else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
+ else if(G.vd->dist<10.0*G.vd->far) {
+ getmouseco_areawin(mouseloc);
+ view_zoom_mouseloc(VIEW_ZOOM_OUT_FACTOR, mouseloc);
+ }
if(G.vd->persp!=1) preview3d_event= 0;
}
else if(event==PADPLUSKEY) {
if(G.vd->persp==2) {
G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
}
- else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
+ else if(G.vd->dist> 0.001*G.vd->grid) {
+ getmouseco_areawin(mouseloc);
+ view_zoom_mouseloc(VIEW_ZOOM_IN_FACTOR, mouseloc);
+ }
if(G.vd->persp!=1) preview3d_event= 0;
}
else if(event==PAD5) {
@@ -372,7 +384,6 @@ void persptoetsen(unsigned short event)
if(G.vd->depths) G.vd->depths->damaged= 1;
retopo_queue_updates(G.vd);
- retopo_force_update();
if(preview3d_event)
BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
@@ -466,6 +477,10 @@ int blenderqread(unsigned short event, short val)
activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
return 0;
}
+ else if(G.qual==LR_CTRLKEY) {
+ activate_imageselect(FILE_LOADLIB, "Load Library", G.lib, 0);
+ return 0;
+ }
break;
case F2KEY:
if(G.qual==0) {
@@ -506,6 +521,15 @@ int blenderqread(unsigned short event, short val)
activate_fileselect(FILE_MAIN, "Data Select", str, NULL);
return 0;
}
+ else if(G.qual==LR_CTRLKEY) {
+
+ memset(str, 0, 16);
+ ob= OBACT;
+ if(ob) strcpy(str, ob->id.name);
+
+ activate_imageselect(FILE_MAIN, "Data Select", str, 0);
+ return 0;
+ }
else if(G.qual==0) {
extern_set_butspace(event, 1);
}
@@ -710,27 +734,40 @@ int blenderqread(unsigned short event, short val)
}
else if(ob->type==OB_MESH) {
if(ob==G.obedit) EM_selectmode_menu();
+ else if(G.f & G_PARTICLEEDIT)
+ PE_selectbrush_menu();
else if(G.f & G_SCULPTMODE)
sculptmode_selectbrush_menu();
else set_wpaint();
}
}
}
+ else if(G.qual&LR_CTRLKEY && G.qual&LR_SHIFTKEY){
+ PE_set_particle_edit();
+ }
break;
case BACKSPACEKEY:
break;
-
- case AKEY:
- if(textediting==0 && textspace==0) {
- if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
+ case SPACEKEY:
+ if (curarea && curarea->spacetype==SPACE_SEQ) {
+ SpaceSeq *sseq= curarea->spacedata.first;
+ if (G.qual==0 && sseq->mainb) {
play_anim(1);
return 0;
}
- else if(G.qual==LR_ALTKEY) {
+ }
+ break;
+ case AKEY:
+ if(textediting==0 && textspace==0) {
+ if ((G.qual==LR_ALTKEY) && (curarea && curarea->spacetype==SPACE_VIEW3D)) {
play_anim(0);
return 0;
}
+ else if ((G.qual==LR_ALTKEY) || (G.qual==(LR_ALTKEY|LR_SHIFTKEY))){
+ play_anim(1);
+ return 0;
+ }
}
break;
case EKEY:
@@ -748,6 +785,8 @@ int blenderqread(unsigned short event, short val)
break;
case IKEY:
if(textediting==0 && textspace==0 && !ELEM3(curarea->spacetype, SPACE_FILE, SPACE_IMASEL, SPACE_NODE)) {
+ ob= OBACT;
+
if(G.f & G_SCULPTMODE) return 1;
else if(G.qual==0) {
common_insertkey();
@@ -919,6 +958,11 @@ int blenderqread(unsigned short event, short val)
if(G.qual==LR_CTRLKEY) {
if(okee("Erase all")) {
if( BIF_read_homefile(0)==0) error("No file ~/.B.blend");
+
+ /* Reset lights
+ * This isn't done when reading userdef, do it now
+ * */
+ default_gl_light();
}
return 0;
}
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index 15193c1b460..8b0df0322ab 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -288,7 +288,7 @@ short button(short *var, short min, short max, char *str)
uiBoundsBlock(block, 5);
- ret= uiDoBlocks(&listb, 0);
+ ret= uiDoBlocks(&listb, 0, 0);
if(ret==UI_RETURN_OK) return 1;
return 0;
@@ -305,7 +305,7 @@ short sbutton(char *var, float min, float max, char *str)
getmouseco_sc(mval);
- if(mval[0]<150) mval[0]=150;
+ if(mval[0]<250) mval[0]=250;
if(mval[1]<30) mval[1]=30;
if(mval[0]>G.curscreen->sizex) mval[0]= G.curscreen->sizex-10;
if(mval[1]>G.curscreen->sizey) mval[1]= G.curscreen->sizey-10;
@@ -313,19 +313,20 @@ short sbutton(char *var, float min, float max, char *str)
block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_ENTER_OK);
- x1=mval[0]-150;
+ x1=mval[0]-250;
y1=mval[1]-20;
- uiDefButC(block, TEX, 32766, str, x1+5,y1+10,125,20, var,(float)min,(float)max, 0, 0, "");
- uiDefBut(block, BUT, 32767, "OK", x1+136,y1+10,25,20, NULL, 0, 0, 0, 0, "");
+ uiDefButC(block, TEX, 32766, str, x1+5,y1+10,225,20, var,(float)min,(float)max, 0, 0, "");
+ uiDefBut(block, BUT, 32767, "OK", x1+236,y1+10,25,20, NULL, 0, 0, 0, 0, "");
uiBoundsBlock(block, 5);
mainqenter_ext(BUT_ACTIVATE, 32766, 0); /* note, button id '32766' is asking for errors some day! */
- ret= uiDoBlocks(&listb, 0);
+ ret= uiDoBlocks(&listb, 0, 0);
if(ret==UI_RETURN_OK) return 1;
return 0;
+
}
short fbutton(float *var, float min, float max, float a1, float a2, char *str)
@@ -355,7 +356,7 @@ short fbutton(float *var, float min, float max, float a1, float a2, char *str)
uiBoundsBlock(block, 2);
- ret= uiDoBlocks(&listb, 0);
+ ret= uiDoBlocks(&listb, 0, 0);
if(ret==UI_RETURN_OK) return 1;
return 0;
@@ -415,7 +416,7 @@ int movetolayer_buts(unsigned int *lay, char *title)
uiBoundsBlock(block, 2);
- ret= uiDoBlocks(&listb, 0);
+ ret= uiDoBlocks(&listb, 0, 0);
if(ret==UI_RETURN_OK) return 1;
return 0;
@@ -465,7 +466,7 @@ int movetolayer_short_buts(short *lay, char *title)
uiBoundsBlock(block, 2);
- ret= uiDoBlocks(&listb, 0);
+ ret= uiDoBlocks(&listb, 0, 0);
if(ret==UI_RETURN_OK) return 1;
return 0;
@@ -602,7 +603,7 @@ int do_clever_numbuts(char *name, int tot, int winevent)
uiBoundsBlock(block, 5);
- event= uiDoBlocks(&listb, 0);
+ event= uiDoBlocks(&listb, 0, 0);
areawinset(curarea->win);
@@ -763,13 +764,6 @@ ListBase tb_listb= {NULL, NULL};
#define TB_PAD 2048
#define TB_SHIFT 4096
-typedef struct TBitem {
- int icon;
- char *name;
- int retval;
- void *poin;
-} TBitem;
-
static void tb_do_hotkey(void *arg, int event)
{
unsigned short i, key=0;
@@ -892,6 +886,7 @@ static TBitem tb_object_select_grouped[]= {
{ 0, "Objects on Shared Layers|Shift G, 6", 6, NULL},
{ 0, "Objects in Same Group|Shift G, 7", 7, NULL},
{ 0, "Object Hooks|Shift G, 8", 8, NULL},
+{ 0, "Object PassIndex|Shift G, 9", 9, NULL},
{ -1, "", 0, do_view3d_select_object_groupedmenu}};
static TBitem tb_object_select[]= {
@@ -899,6 +894,7 @@ static TBitem tb_object_select[]= {
{ 0, "SEPR", 0, NULL},
{ 0, "Select/Deselect All|A", 1, NULL},
{ 0, "Inverse", 2, NULL},
+{ 0, "Random", 3, NULL},
{ 0, "Select All by Layer", 0, tb_object_select_layer},
{ 0, "Select All by Type", 0, tb_object_select_type},
{ 0, "SEPR", 0, NULL},
@@ -919,8 +915,8 @@ static TBitem tb_face_select[]= {
static TBitem tb_mesh_select[]= {
{ 0, "Border Select|B", 0, NULL},
{ 0, "SEPR", 0, NULL},
-{ 0, "(De)select All|A", 2, NULL},
-{ 0, "Inverse", 3, NULL},
+{ 0, "Select/Deselect All|A", 2, NULL},
+{ 0, "Inverse|Ctrl I", 3, NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Random...", 5, NULL},
{ 0, "Non-Manifold|Shift Ctrl Alt M", 9, NULL},
@@ -929,7 +925,7 @@ static TBitem tb_mesh_select[]= {
{ 0, "Triangles|Shift Ctrl Alt 3", 11, NULL},
{ 0, "Quads|Shift Ctrl Alt 4", 12, NULL},
{ 0, "Non-Triangles/Quads|Shift Ctrl Alt 5", 13, NULL},
-{ 0, "Group From Selection|Shift G", 21, NULL},
+{ 0, "Similar to Selection|Shift G", 21, NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "More|Ctrl NumPad +", 7, NULL},
{ 0, "Less|Ctrl NumPad -", 8, NULL},
@@ -949,7 +945,9 @@ static TBitem tb_curve_select[]= {
{ 0, "SEPR", 0, NULL},
{ 0, "(De)select All|A", 2, NULL},
{ 0, "Inverse", 3, NULL},
-{ 0, "Row|Shift R", 5, NULL},
+{ 0, "Random...", 13, NULL},
+{ 0, "Every Nth", 14, NULL},
+{ 0, "Row|Shift R", 5, NULL}, /* shouldn't be visible in case of bezier curves*/
{ 0, "SEPR", 0, NULL},
{ 0, "(De)select First", 7, NULL},
{ 0, "(De)select Last", 8, NULL},
@@ -960,6 +958,15 @@ static TBitem tb_curve_select[]= {
{ 0, "Less|Ctrl NumPad -", 10, NULL},
{ -1, "", 0, do_view3d_select_curvemenu}};
+static TBitem tb_mball_select[]= {
+{ 0, "Border Select|B", 0, NULL},
+{ 0, "SEPR", 0, NULL},
+{ 0, "(De)select All|A", 2, NULL},
+{ 0, "Inverse", 3, NULL},
+{ 0, "SEPR", 0, NULL},
+{ 0, "Random...", 4, NULL},
+{ -1, "", 0, do_view3d_select_metaballmenu}};
+
static TBitem tb__select[]= {
{ 0, "Border Select|B", 'b', NULL},
{ 0, "(De)select All|A", 'a', NULL},
@@ -1049,9 +1056,9 @@ static TBitem tb_mesh_edit_face[]= {
{ 0, "SEPR", 0, NULL},
{ 0, "Convert to Triangles|Ctrl T", 2, NULL},
{ 0, "Convert to Quads|Alt J", 3, NULL},
-{ 0, "Flip Triangle Edges|Ctrl F", 4, NULL},
-{ 0, "Set Smooth|W, Alt 3", 6, NULL},
-{ 0, "Set Solid|W, Alt 4", 7, NULL},
+{ 0, "Flip Triangle Edges|Ctrl Shift F", 4, NULL},
+{ 0, "Set Smooth|Ctrl F, 3", 6, NULL},
+{ 0, "Set Solid|Ctrl F, 4", 7, NULL},
{ -1, "", 0, do_view3d_edit_mesh_facesmenu}};
@@ -1059,13 +1066,13 @@ static TBitem tb_mesh_edit_normal[]= {
{ 0, "Recalculate Outside|Ctrl N", 2, NULL},
{ 0, "Recalculate Inside|Ctrl Shift N", 1, NULL},
{ 0, "SEPR", 0, NULL},
-{ 0, "Flip|W, 9", 0, NULL},
+{ 0, "Flip|Ctrl F, 1", 0, NULL},
{ -1, "", 0, do_view3d_edit_mesh_normalsmenu}};
static TBitem tb_mesh_edit[]= {
{ 0, "Exit Editmode|Tab", TB_TAB, NULL},
-{ 0, "Undo|U", 'u', NULL},
-{ 0, "Redo|Shift U", 'U', NULL},
+{ 0, "Undo|Ctrl Z", 'u', NULL},
+{ 0, "Redo|Ctrl Shift Z", 'U', NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Extrude|E", 'e', NULL},
{ 0, "Duplicate|Shift D", 'D', NULL},
@@ -1259,12 +1266,15 @@ static void tb_do_transform_clearapply(void *arg, int event)
clear_object('s');
break;
case 3: /* apply scale/rotation */
- apply_object();
+ apply_objects_locrot();
+ break;
+ case 4: /* apply scale/rotation */
+ apply_objects_visual_tx();
break;
- case 4: /* apply deformation */
+ case 5: /* apply deformation */
object_apply_deform(ob);
break;
- case 5: /* make duplicates real */
+ case 6: /* make duplicates real */
if (ob->transflag & OB_DUPLI) make_duplilist_real();
else error("The active object does not have dupliverts");
break;
@@ -1276,17 +1286,19 @@ static TBitem tb_transform_clearapply[]= {
{ 0, "Clear Rotation|Alt R", 1, NULL},
{ 0, "Clear Scale|Alt S", 2, NULL},
{ 0, "SEPR", 0, NULL},
-{ 0, "Apply Scale/Rotation|Ctrl A", 3, NULL},
-{ 0, "Apply Deformation|Shift Ctrl A", 4, NULL},
-{ 0, "Make Duplicates Real|Shift Ctrl A", 5, NULL},
+{ 0, "Apply Scale/Rotation to ObData|Ctrl A, 1", 3, NULL},
+{ 0, "Apply Visual Transform|Ctrl A, 2", 4, NULL},
+{ 0, "Apply Deformation|Shift Ctrl A", 5, NULL},
+{ 0, "Make Duplicates Real|Shift Ctrl A", 6, NULL},
{ -1, "", 0, tb_do_transform_clearapply}};
static TBitem tb_transform_snap[]= {
{ 0, "Selection -> Grid|Shift S, 1", 1, NULL},
{ 0, "Selection -> Cursor|Shift S, 2", 2, NULL},
-{ 0, "Cursor -> Grid|Shift S, 3", 3, NULL},
+{ 0, "Selection -> Center|Shift S, 3", 3, NULL},
{ 0, "Cursor -> Selection|Shift S, 4", 4, NULL},
-{ 0, "Selection -> Center|Shift S, 5", 5, NULL},
+{ 0, "Cursor -> Grid|Shift S, 5", 5, NULL},
+{ 0, "Cursor -> Active|Shift S, 6", 6, NULL},
{ -1, "", 0, do_view3d_edit_snapmenu}};
static void tb_do_transform(void *arg, int event)
@@ -1552,6 +1564,7 @@ static TBitem tb_node_addsh[]= {
{ 0, "Vector", 4, NULL},
{ 0, "Convertor", 5, NULL},
{ 0, "Group", 6, NULL},
+ { 0, "Dynamic", 7, NULL},
{ -1, "", 0, NULL}};
static TBitem tb_node_addcomp[]= {
@@ -1564,6 +1577,7 @@ static TBitem tb_node_addcomp[]= {
{ 0, "Matte", 7, NULL},
{ 0, "Distort", 8, NULL},
{ 0, "Group", 9, NULL},
+ { 0, "Dynamic", 10, NULL},
{ -1, "", 0, NULL}};
/* do_node_addmenu() in header_node.c, prototype in BSE_headerbuttons.h */
@@ -1612,11 +1626,21 @@ static TBitem *node_add_sublevel(ListBase *storage, bNodeTree *ntree, int nodecl
}
}
else {
- bNodeType *ntype= ntree->alltypes.first;
- for(a=0; ntype; ntype= ntype->next) {
- if( ntype->nclass == nodeclass ) {
- addmenu[a].name= ntype->name;
- addmenu[a].retval= ntype->type;
+ bNodeType *type= ntree->alltypes.first;
+ int script=0;
+ for(a=0; type; type= type->next) {
+ if( type->nclass == nodeclass ) {
+ if(type->type == NODE_DYNAMIC) {
+ if(type->id)
+ addmenu[a].name= type->id->name+2;
+ else
+ addmenu[a].name= type->name;
+ addmenu[a].retval= NODE_DYNAMIC_MENU+script;
+ script++;
+ } else {
+ addmenu[a].name= type->name;
+ addmenu[a].retval= type->type;
+ }
a++;
}
}
@@ -1635,11 +1659,14 @@ static TBitem tb_node_node[]= {
{ 0, "Duplicate|Shift D", TB_SHIFT|'d', NULL},
{ 0, "Delete|X", 'x', NULL},
{ 0, "SEPR", 0, NULL},
+ { 0, "Make Link|F", 'f', NULL},
+ { 0, "SEPR", 0, NULL},
{ 0, "Make Group|Ctrl G", TB_CTRL|'g', NULL},
{ 0, "Ungroup|Alt G", TB_ALT|'g', NULL},
{ 0, "Edit Group|Tab", TB_TAB, NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Hide/Unhide|H", 'h', NULL},
+ { 0, "Rename|Ctrl R", TB_CTRL|'r', NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Read Saved Render Results|R", 'r', NULL},
{ 0, "Show Cyclic Dependencies|C", 'c', NULL},
@@ -1735,6 +1762,8 @@ static void do_group_addmenu(void *arg, int event)
ob->dup_group= BLI_findlink(&G.main->group, event);
if(ob->dup_group) {
+ rename_id(&ob->id, ob->dup_group->id.name+2);
+
id_us_plus((ID *)ob->dup_group);
ob->transflag |= OB_DUPLIGROUP;
DAG_scene_sort(G.scene);
@@ -1949,6 +1978,9 @@ void toolbox_n(void)
}
}
+ /* save present mouse position */
+ toolbox_mousepos(mval, 1);
+
mywinset(G.curscreen->mainwin); // we go to screenspace
block= uiNewBlock(&tb_listb, "toolbox", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
@@ -2019,7 +2051,7 @@ void toolbox_n(void)
case OB_MBALL:
menu1= addmenu_meta;
menu2= tb_edit;
- menu3= tb__select;
+ menu3= tb_mball_select;
menu4= tb_transform_editmode2;
menu5= tb_obdata; str5= "Meta";
break;
@@ -2083,7 +2115,7 @@ void toolbox_n(void)
}
}
}
- else if (G.f & G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
menu3 = tb_face_select;
}
}
@@ -2107,6 +2139,7 @@ void toolbox_n(void)
menu1[3].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_OP_VECTOR);
menu1[4].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_CONVERTOR);
menu1[5].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_GROUP);
+ menu1[6].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_OP_DYNAMIC);
}
else if(snode->treetype==NTREE_COMPOSIT) {
menu1[0].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_INPUT);
@@ -2118,6 +2151,7 @@ void toolbox_n(void)
menu1[6].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_MATTE);
menu1[7].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_DISTORT);
menu1[8].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_GROUP);
+ menu1[9].poin= node_add_sublevel(&storage, snode->nodetree, NODE_CLASS_OP_DYNAMIC);
}
@@ -2206,7 +2240,7 @@ void toolbox_n(void)
}
uiBoundsBlock(block, 2);
- event= uiDoBlocks(&tb_listb, 0);
+ event= uiDoBlocks(&tb_listb, 0, 1);
/* free all dynamic entries... */
BLI_freelistN(&storage);
@@ -2230,3 +2264,74 @@ void reset_toolbox(void)
tb_mainy= -5;
}
}
+
+/* general toolbox for python access */
+void toolbox_generic( TBitem *generic_menu )
+{
+ uiBlock *block;
+ uiBut *but;
+ TBitem *menu;
+ int dx=96;
+ short event, mval[2];
+ long ypos = -5;
+
+ tb_mainx= -32;
+ tb_mainy= -5;
+
+ mywinset(G.curscreen->mainwin); // we go to screenspace
+
+ block= uiNewBlock(&tb_listb, "toolbox", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+ uiBlockSetCol(block, TH_MENU_ITEM);
+
+ getmouseco_sc(mval);
+
+ menu= generic_menu;
+ while(menu->icon != -1) menu++;
+ uiBlockSetButmFunc(block, menu->poin, NULL);
+
+ /* Add the menu */
+ for (menu = generic_menu; menu->icon != -1; menu++) {
+ if (menu->poin) {
+ but=uiDefIconTextBlockBut(block, tb_makemenu, menu->poin, ICON_RIGHTARROW_THIN, menu->name, mval[0]+tb_mainx,mval[1]+tb_mainy+ypos+5, dx, 19, "");
+ uiButSetFlag(but, UI_MAKE_RIGHT);
+
+ uiButSetFunc(but, store_main, (void *)+32, (void *)ypos);
+ } else {
+ /* TODO - add icon support */
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, menu->name, mval[0]+tb_mainx,mval[1]+tb_mainy+ypos+5, dx, 19, NULL, 0.0, 0.0, 0, menu->retval, "");
+ }
+ ypos-=20;
+ }
+
+ uiBlockSetButmFunc(block, menu->poin, NULL);
+
+ uiBoundsBlock(block, 2);
+ event= uiDoBlocks(&tb_listb, 0, 1);
+
+ mywinset(curarea->win);
+
+ reset_toolbox();
+}
+
+/* save or restore mouse position when entering/exiting menus */
+void toolbox_mousepos( short *mpos, int save )
+{
+ static short initpos[2];
+ static int tog;
+
+ if (save) {
+ getmouseco_areawin(mpos);
+ initpos[0]= mpos[0];
+ initpos[1]= mpos[1];
+ tog=1;
+ } else {
+ if (tog) {
+ mpos[0]= initpos[0];
+ mpos[1]= initpos[1];
+ } else {
+ getmouseco_areawin(mpos);
+ }
+ tog= 0;
+ }
+}
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 84ad5a91551..d846ba2c197 100755..100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -48,6 +48,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
+#include "DNA_action_types.h" /* for some special action-editor settings */
+#include "DNA_constraint_types.h"
#include "DNA_ipo_types.h" /* some silly ipo flag */
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
@@ -55,8 +57,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h" /* PET modes */
#include "DNA_screen_types.h" /* area dimensions */
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
@@ -74,12 +74,22 @@
#include "BIF_toolbox.h" /* notice */
#include "BIF_editmesh.h"
#include "BIF_editsima.h"
+#include "BIF_editparticle.h"
#include "BIF_drawimage.h" /* uvco_to_areaco_noclip */
+#include "BIF_editaction.h"
+#include "BKE_action.h" /* get_action_frame */
+#include "BKE_constraint.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "BKE_bad_level_calls.h"/* popmenu and error */
+#include "BKE_particle.h"
+#include "BKE_bmesh.h"
+#include "BSE_drawipo.h"
+#include "BSE_editnla_types.h" /* for NLAWIDTH */
+#include "BSE_editaction_types.h"
+#include "BSE_time.h"
#include "BSE_view.h"
#include "BLI_arithb.h"
@@ -146,6 +156,9 @@ static void helpline(TransInfo *t, float *vec)
glDrawBuffer(GL_BACK);
}
}
+
+
+
/* ************************** INPUT FROM MOUSE *************************** */
float InputScaleRatio(TransInfo *t, short mval[2]) {
@@ -262,16 +275,26 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
}
else if(t->spacetype==SPACE_IMAGE) {
float divx, divy, aspx, aspy;
-
+
transform_aspect_ratio_tface_uv(&aspx, &aspy);
-
+
divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
-
+
vec[0]= aspx*(G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/divx;
vec[1]= aspy*(G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/divy;
vec[2]= 0.0f;
}
+ else if(t->spacetype==SPACE_IPO) {
+ float divx, divy;
+
+ divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
+ divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
+
+ vec[0]= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx) / (divx);
+ vec[1]= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy) / (divy);
+ vec[2]= 0.0f;
+ }
}
void projectIntView(TransInfo *t, float *vec, int *adr)
@@ -280,13 +303,20 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
project_int(vec, adr);
else if(t->spacetype==SPACE_IMAGE) {
float aspx, aspy, v[2];
-
+
transform_aspect_ratio_tface_uv(&aspx, &aspy);
v[0]= vec[0]/aspx;
v[1]= vec[1]/aspy;
-
+
uvco_to_areaco_noclip(v, adr);
}
+ else if(t->spacetype==SPACE_IPO) {
+ short out[2] = {0.0f, 0.0f};
+
+ ipoco_to_areaco(G.v2d, vec, out);
+ adr[0]= out[0];
+ adr[1]= out[1];
+ }
}
void projectFloatView(TransInfo *t, float *vec, float *adr)
@@ -295,7 +325,14 @@ void projectFloatView(TransInfo *t, float *vec, float *adr)
project_float(vec, adr);
else if(t->spacetype==SPACE_IMAGE) {
int a[2];
-
+
+ projectIntView(t, vec, a);
+ adr[0]= a[0];
+ adr[1]= a[1];
+ }
+ else if(t->spacetype==SPACE_IPO) {
+ int a[2];
+
projectIntView(t, vec, a);
adr[0]= a[0];
adr[1]= a[1];
@@ -350,12 +387,58 @@ void convertDisplayNumToVec(float *num, float *vec)
static void viewRedrawForce(TransInfo *t)
{
- if(t->spacetype==SPACE_VIEW3D)
+ if (t->spacetype == SPACE_VIEW3D)
force_draw(0);
- else if(t->spacetype==SPACE_IMAGE) {
- if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
+ else if (t->spacetype==SPACE_IMAGE) {
+ if (G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
else force_draw(0);
}
+ else if (t->spacetype == SPACE_ACTION) {
+ if (G.saction->lock) {
+ short context;
+
+ /* we ignore the pointer this function returns (not needed) */
+ get_action_context(&context);
+
+ if (context == ACTCONT_ACTION)
+ force_draw_plus(SPACE_VIEW3D, 0);
+ else if (context == ACTCONT_SHAPEKEY)
+ force_draw_all(0);
+ else
+ force_draw(0);
+ }
+ else {
+ force_draw(0);
+ }
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ if (G.snla->lock)
+ force_draw_all(0);
+ else
+ force_draw(0);
+ }
+ else if (t->spacetype == SPACE_IPO) {
+ /* update realtime */
+ if (G.sipo->lock) {
+ if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE)
+ force_draw_plus(SPACE_BUTS, 0);
+ else if (G.sipo->blocktype==ID_CA)
+ force_draw_plus(SPACE_VIEW3D, 0);
+ else if (G.sipo->blocktype==ID_KE)
+ force_draw_plus(SPACE_VIEW3D, 0);
+ else if (G.sipo->blocktype==ID_PO)
+ force_draw_plus(SPACE_VIEW3D, 0);
+ else if (G.sipo->blocktype==ID_OB)
+ force_draw_plus(SPACE_VIEW3D, 0);
+ else if (G.sipo->blocktype==ID_SEQ)
+ force_draw_plus(SPACE_SEQ, 0);
+ else
+ force_draw(0);
+ }
+ else {
+ force_draw(0);
+ }
+ }
}
static void viewRedrawPost(TransInfo *t)
@@ -368,6 +451,14 @@ static void viewRedrawPost(TransInfo *t)
allqueue(REDRAWIMAGE, 0);
allqueue(REDRAWVIEW3D, 0);
}
+ else if(ELEM3(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_IPO)) {
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
scrarea_queue_headredraw(curarea);
}
@@ -376,12 +467,12 @@ static void viewRedrawPost(TransInfo *t)
void BIF_selectOrientation() {
short val;
- val= pupmenu("Orientation%t|Global|Local|Normal|View");
- if(val>0) {
- if(val==1) G.vd->twmode= V3D_MANIP_GLOBAL;
- else if(val==2) G.vd->twmode= V3D_MANIP_LOCAL;
- else if(val==3) G.vd->twmode= V3D_MANIP_NORMAL;
- else if(val==4) G.vd->twmode= V3D_MANIP_VIEW;
+ char *str_menu = BIF_menustringTransformOrientation();
+ val= pupmenu(str_menu);
+ MEM_freeN(str_menu);
+
+ if(val >= 0) {
+ G.vd->twmode = val;
}
}
@@ -486,12 +577,26 @@ static char *transform_to_undostr(TransInfo *t)
return "Trackball";
case TFM_PUSHPULL:
return "Push/Pull";
+ case TFM_BEVEL:
+ return "Bevel";
+ case TFM_BWEIGHT:
+ return "Bevel Weight";
case TFM_CREASE:
return "Crease";
case TFM_BONESIZE:
return "Bone Width";
case TFM_BONE_ENVELOPE:
return "Bone Envelope";
+ case TFM_TIME_TRANSLATE:
+ return "Translate Anim. Data";
+ case TFM_TIME_SCALE:
+ return "Scale Anim. Data";
+ case TFM_TIME_SLIDE:
+ return "Time Slide";
+ case TFM_BAKE_TIME:
+ return "Key Time";
+ case TFM_MIRROR:
+ return "Mirror";
}
return "Transform";
}
@@ -516,11 +621,11 @@ static void transformEvent(unsigned short event, short val) {
Trans.flag |= T_SHIFT_MOD;
Trans.redraw = 1;
break;
-
+
case SPACEKEY:
if ((Trans.spacetype==SPACE_VIEW3D) && (G.qual & LR_ALTKEY)) {
short mval[2];
-
+
getmouseco_sc(mval);
BIF_selectOrientation();
calc_manipulator_stats(curarea);
@@ -531,7 +636,7 @@ static void transformEvent(unsigned short event, short val) {
Trans.state = TRANS_CONFIRM;
}
break;
-
+
case MIDDLEMOUSE:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
@@ -619,21 +724,31 @@ static void transformEvent(unsigned short event, short val) {
case XKEY:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
if (cmode == 'X') {
- if (Trans.con.mode & CON_USER) {
+ if (Trans.flag & T_2D_EDIT) {
stopConstraint(&Trans);
}
else {
- if (G.qual == 0)
- setUserConstraint(&Trans, (CON_AXIS0), "along %s X");
- else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
- setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
+ if (Trans.con.mode & CON_USER) {
+ stopConstraint(&Trans);
+ }
+ else {
+ if (G.qual == 0)
+ setUserConstraint(&Trans, (CON_AXIS0), "along %s X");
+ else if (G.qual == LR_SHIFTKEY)
+ setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
+ }
}
}
else {
- if (G.qual == 0)
- setConstraint(&Trans, mati, (CON_AXIS0), "along global X");
- else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
- setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
+ if (Trans.flag & T_2D_EDIT) {
+ setConstraint(&Trans, mati, (CON_AXIS0), "along X axis");
+ }
+ else {
+ if (G.qual == 0)
+ setConstraint(&Trans, mati, (CON_AXIS0), "along global X");
+ else if (G.qual == LR_SHIFTKEY)
+ setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
+ }
}
Trans.redraw = 1;
}
@@ -641,21 +756,31 @@ static void transformEvent(unsigned short event, short val) {
case YKEY:
if ((Trans.flag & T_NO_CONSTRAINT)==0) {
if (cmode == 'Y') {
- if (Trans.con.mode & CON_USER) {
+ if (Trans.flag & T_2D_EDIT) {
stopConstraint(&Trans);
}
else {
- if (G.qual == 0)
- setUserConstraint(&Trans, (CON_AXIS1), "along %s Y");
- else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
- setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+ if (Trans.con.mode & CON_USER) {
+ stopConstraint(&Trans);
+ }
+ else {
+ if (G.qual == 0)
+ setUserConstraint(&Trans, (CON_AXIS1), "along %s Y");
+ else if (G.qual == LR_SHIFTKEY)
+ setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+ }
}
}
else {
- if (G.qual == 0)
- setConstraint(&Trans, mati, (CON_AXIS1), "along global Y");
- else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
- setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking global Y");
+ if (Trans.flag & T_2D_EDIT) {
+ setConstraint(&Trans, mati, (CON_AXIS1), "along Y axis");
+ }
+ else {
+ if (G.qual == 0)
+ setConstraint(&Trans, mati, (CON_AXIS1), "along global Y");
+ else if (G.qual == LR_SHIFTKEY)
+ setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking global Y");
+ }
}
Trans.redraw = 1;
}
@@ -698,7 +823,10 @@ static void transformEvent(unsigned short event, short val) {
break;
case PAGEUPKEY:
case WHEELDOWNMOUSE:
- if(Trans.flag & T_PROP_EDIT) {
+ if (Trans.flag & T_AUTOIK) {
+ transform_autoik_update(&Trans, 1);
+ }
+ else if(Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 1.1f;
calculatePropRatio(&Trans);
}
@@ -714,7 +842,10 @@ static void transformEvent(unsigned short event, short val) {
break;
case PAGEDOWNKEY:
case WHEELUPMOUSE:
- if(Trans.flag & T_PROP_EDIT) {
+ if (Trans.flag & T_AUTOIK) {
+ transform_autoik_update(&Trans, -1);
+ }
+ else if (Trans.flag & T_PROP_EDIT) {
Trans.propsize*= 0.90909090f;
calculatePropRatio(&Trans);
}
@@ -850,6 +981,7 @@ void initTransform(int mode, int context) {
if(Trans.spacetype==SPACE_VIEW3D) {
calc_manipulator_stats(curarea);
Mat3CpyMat4(Trans.spacemtx, G.vd->twmat);
+ Mat3Ortho(Trans.spacemtx);
}
else
Mat3One(Trans.spacemtx);
@@ -865,6 +997,7 @@ void initTransform(int mode, int context) {
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
+ /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
mode = Trans.mode;
calculatePropRatio(&Trans);
@@ -922,6 +1055,34 @@ void initTransform(int mode, int context) {
case TFM_BONE_ROLL:
initBoneRoll(&Trans);
break;
+ case TFM_TIME_TRANSLATE:
+ initTimeTranslate(&Trans);
+ break;
+ case TFM_TIME_SLIDE:
+ initTimeSlide(&Trans);
+ break;
+ case TFM_TIME_SCALE:
+ initTimeScale(&Trans);
+ break;
+ case TFM_TIME_EXTEND:
+ /* now that transdata has been made, do like for TFM_TIME_TRANSLATE */
+ initTimeTranslate(&Trans);
+ break;
+ case TFM_BAKE_TIME:
+ initBakeTime(&Trans);
+ break;
+ case TFM_MIRROR:
+ initMirror(&Trans);
+ break;
+ case TFM_BEVEL:
+ initBevel(&Trans);
+ break;
+ case TFM_BWEIGHT:
+ initBevelWeight(&Trans);
+ break;
+ case TFM_ALIGN:
+ initAlign(&Trans);
+ break;
}
}
@@ -958,6 +1119,13 @@ void Transform()
}
Trans.redraw = 0;
}
+
+ /* If auto confirm is on, break after one pass */
+ if (Trans.context & CTX_AUTOCONFIRM)
+ {
+ Trans.state = TRANS_CONFIRM;
+ break;
+ }
/* essential for idling subloop */
if( qtest()==0) PIL_sleep_ms(2);
@@ -1136,7 +1304,10 @@ void ManipulatorTransform()
Trans.redraw= 1;
}
break;
- }
+ }
+
+ // Numerical input events
+ Trans.redraw |= handleNumInput(&(Trans.num), event);
}
}
}
@@ -1160,7 +1331,7 @@ void ManipulatorTransform()
}
-/* ************************** TRANSFORMATIONS **************************** */
+/* ************************** TRANSFORM LOCKS **************************** */
static void protectedTransBits(short protectflag, float *vec)
{
@@ -1219,6 +1390,265 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu
}
}
+/* ******************* TRANSFORM LIMITS ********************** */
+
+static void constraintTransLim(TransInfo *t, TransData *td)
+{
+ if (td->con) {
+ 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);
+ }
+
+ /* Evaluate valid constraints */
+ for (con= td->con; con; con= con->next) {
+ float tmat[4][4];
+
+ /* 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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ }
+ else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
+ /* 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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ }
+ }
+ }
+
+ /* 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]);
+ }
+ }
+}
+
+static void constraintRotLim(TransInfo *t, TransData *td)
+{
+ if (td->con) {
+ bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
+ 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->flag & TD_USEQUAT) {
+ /* quats */
+ if (td->ext)
+ QuatToMat4(td->ext->quat, cob.matrix);
+ else
+ return;
+ }
+ else if (td->tdi) {
+ /* 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];
+
+ EulToMat4(eul, cob.matrix);
+ }
+ else {
+ /* eulers */
+ if (td->ext)
+ EulToMat4(td->ext->rot, cob.matrix);
+ else
+ return;
+ }
+
+ /* Evaluate valid constraints */
+ for (con= td->con; con; con= con->next) {
+ /* we're only interested in Limit-Scale constraints */
+ if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
+ bRotLimitConstraint *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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ }
+ else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
+ /* 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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ }
+ }
+ }
+
+ /* copy results from cob->matrix */
+ if (td->flag & TD_USEQUAT) {
+ /* quats */
+ Mat4ToQuat(cob.matrix, td->ext->quat);
+ }
+ else if (td->tdi) {
+ /* ipo-keys eulers */
+ TransDataIpokey *tdi= td->tdi;
+ float eul[3];
+
+ Mat4ToEul(cob.matrix, eul);
+
+ tdi->rotx[0]= eul[0];
+ tdi->roty[0]= eul[1];
+ tdi->rotz[0]= eul[2];
+ }
+ else {
+ /* eulers */
+ Mat4ToEul(cob.matrix, td->ext->rot);
+ }
+ }
+}
+
+static void constraintSizeLim(TransInfo *t, TransData *td)
+{
+ if (td->con && td->ext) {
+ 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)) {
+ /* scale val and reset size */
+ return; // TODO: fix this case
+ }
+ else {
+ /* 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) {
+ /* 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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->mtx, tmat);
+ }
+ else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
+ /* 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) */
+ Mat4CpyMat4(tmat, cob.matrix);
+ Mat4MulMat34(cob.matrix, td->smtx, tmat);
+ }
+ }
+ }
+
+ /* 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)) {
+ /* scale val and reset size */
+ return; // TODO: fix this case
+ }
+ else {
+ /* Reset val if SINGLESIZE but using a constraint */
+ if (td->flag & TD_SINGLESIZE)
+ return;
+
+ Mat4ToSize(cob.matrix, td->ext->size);
+ }
+ }
+}
+
/* ************************** WARP *************************** */
void initWarp(TransInfo *t)
@@ -1228,6 +1658,7 @@ void initWarp(TransInfo *t)
t->mode = TFM_WARP;
t->transform = Warp;
+ t->handleEvent = handleEventWarp;
t->idx_max = 0;
t->num.idx_max = 0;
@@ -1255,12 +1686,31 @@ 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;
- t->val= (max[0]-min[0])/2.0f; // t->val is free variable
+ if (max[0] == min[0]) max[0] += 0.1; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
+ t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */
+}
+
+int handleEventWarp(TransInfo *t, unsigned short event, short val)
+{
+ int status = 0;
+
+ if (event == MIDDLEMOUSE && val)
+ {
+ // Use customData pointer to signal warp direction
+ if (t->customData == 0)
+ t->customData = (void*)1;
+ else
+ t->customData = 0;
+
+ status = 1;
+ }
+
+ return status;
}
int Warp(TransInfo *t, short mval[2])
@@ -1291,8 +1741,13 @@ int Warp(TransInfo *t, short mval[2])
Mat4MulVecfl(t->viewmat, cursor);
VecSubf(cursor, cursor, t->viewmat[3]);
- // amount of degrees for warp
+ /* amount of degrees for warp */
circumfac= 360.0f * InputHorizontalRatio(t, mval);
+
+ if (t->customData) /* non-null value indicates reversed input */
+ {
+ circumfac *= -1;
+ }
snapGrid(t, &circumfac);
applyNumInput(&t->num, &circumfac);
@@ -1312,21 +1767,24 @@ int Warp(TransInfo *t, short mval[2])
circumfac*= (float)(-M_PI/360.0);
- for(i = 0 ; i < t->total; i++, td++) {
+ for(i = 0; i < t->total; i++, td++) {
float loc[3];
if (td->flag & TD_NOACTION)
break;
- /* translate point to center, rotate in such a way that outline==distance */
+ 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];
-
- phi0= (circumfac*dist/t->val); // t->val is X dimension projected boundbox
+
+ /* t->val is X dimension projected boundbox */
+ phi0= (circumfac*dist/t->val);
vec[1]= (vec[1]-cursor[1]);
@@ -1339,7 +1797,7 @@ int Warp(TransInfo *t, short mval[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);
@@ -1442,6 +1900,9 @@ int Shear(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
if (G.obedit) {
float mat3[3][3];
Mat3MulMat3(mat3, totmat, td->mtx);
@@ -1597,8 +2058,8 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
if (td->ext) {
float fsize[3];
-
- if (t->flag & (T_OBJECT|T_TEXTURE)) {
+
+ if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) {
float obsizemat[3][3];
// Reorient the size mat to fit the oriented object.
Mat3MulMat3(obsizemat, tmat, td->axismtx);
@@ -1612,7 +2073,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
protectedSizeBits(td->protectflag, fsize);
- if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
+ if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't resize objects itself
/* handle ipokeys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
@@ -1626,11 +2087,11 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
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)){
/* 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];
@@ -1639,13 +2100,16 @@ 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);
@@ -1675,6 +2139,8 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
}
else VecAddf(td->loc, td->iloc, vec);
+
+ constraintTransLim(t, td);
}
int Resize(TransInfo *t, short mval[2])
@@ -1707,6 +2173,8 @@ int Resize(TransInfo *t, short mval[2])
constraintNumInput(t, size);
}
+ applySnapping(t, size);
+
SizeToMat3(size, mat);
if (t->con.applySize) {
@@ -1720,11 +2188,14 @@ int Resize(TransInfo *t, short mval[2])
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 cliiping needeed */
+ /* evil hack - redo resize if cliping needed */
if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) {
SizeToMat3(size, mat);
@@ -1811,6 +2282,9 @@ int ToSphere(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
VecSubf(vec, td->iloc, t->center);
radius = Normalize(vec);
@@ -1821,6 +2295,7 @@ int ToSphere(TransInfo *t, short mval[2])
VecAddf(td->loc, t->center, vec);
}
+
recalcData(t);
@@ -1849,6 +2324,9 @@ void initRotation(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->fac = 0;
+
+ if (t->flag & T_2D_EDIT)
+ t->flag |= T_NO_CONSTRAINT;
}
static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
@@ -1864,10 +2342,20 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
VecAddf(td->loc, vec, t->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
- QuatMul(td->ext->quat, quat, td->ext->iquat);
+
+ 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);
+ }
}
}
/**
@@ -1907,29 +2395,32 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
VecAddf(td->loc, td->iloc, vec);
+ constraintTransLim(t, td);
+
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
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);
+
+ constraintRotLim(t, td);
}
}
else {
/* translation */
-
VecSubf(vec, td->center, t->center);
Mat3MulVecfl(mat, vec);
VecAddf(vec, vec, t->center);
/* 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]);
@@ -1937,10 +2428,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
}
else VecAddf(td->loc, td->iloc, vec);
+
+ constraintTransLim(t, td);
/* rotation */
if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
-
if(td->flag & TD_USEQUAT) {
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
@@ -2002,6 +2494,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
VECCOPY(td->ext->rot, eul);
}
}
+
+ constraintRotLim(t, td);
}
}
}
@@ -2016,6 +2510,9 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
if (t->around == V3D_LOCAL) {
VECCOPY(center, t->center);
}
+ else {
+ center[0] = center[1] = center[2] = 0.0f;
+ }
VecRotToMat3(axis, angle, mat);
@@ -2023,6 +2520,9 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
/* local constraint shouldn't alter center */
if (t->around == V3D_LOCAL) {
@@ -2059,16 +2559,16 @@ int Rotation(TransInfo *t, short mval[2])
float final;
- int dx2 = t->center2d[0] - mval[0];
- int dy2 = t->center2d[1] - mval[1];
+ double dx2 = t->center2d[0] - mval[0];
+ double dy2 = t->center2d[1] - mval[1];
double B = sqrt(dx2*dx2+dy2*dy2);
- int dx1 = t->center2d[0] - t->imval[0];
- int dy1 = t->center2d[1] - t->imval[1];
+ double dx1 = t->center2d[0] - t->imval[0];
+ double dy1 = t->center2d[1] - t->imval[1];
double A = sqrt(dx1*dx1+dy1*dy1);
- int dx3 = mval[0] - t->imval[0];
- int dy3 = mval[1] - t->imval[1];
+ double dx3 = mval[0] - t->imval[0];
+ double dy3 = mval[1] - t->imval[1];
/* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
double deler= ((double)((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3) ))
/ (2.0 * (A*B?A*B:1.0));
@@ -2086,7 +2586,7 @@ int Rotation(TransInfo *t, short mval[2])
dphi = saacos((float)deler);
if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
- if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
+ if(t->flag & T_SHIFT_MOD) t->fac += dphi/30.0f;
else t->fac += dphi;
/*
@@ -2119,7 +2619,7 @@ int Rotation(TransInfo *t, short mval[2])
outputNumInput(&(t->num), c);
- sprintf(str, "Rot: %s %s", &c[0], t->proptext);
+ sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
while (final >= 180.0)
@@ -2179,6 +2679,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
{
TransData *td = t->data;
float mat[3][3], smat[3][3], totmat[3][3];
+ float center[3];
int i;
VecRotToMat3(axis1, angles[0], smat);
@@ -2189,10 +2690,22 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ VECCOPY(center, t->center);
if (t->around == V3D_LOCAL) {
- if (t->flag & T_OBJECT)
- VECCOPY(t->center, td->center); // not supported in editmode yet
+ /* local-mode shouldn't change center */
+ if (t->flag & (T_OBJECT|T_POSE)) {
+ VECCOPY(t->center, td->center);
+ }
+ else {
+ if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE)) {
+ VECCOPY(t->center, td->center);
+ }
+ }
}
if (t->flag & T_PROP_EDIT) {
@@ -2201,8 +2714,10 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
Mat3MulMat3(mat, smat, totmat);
}
-
+
ElementRotation(t, td, mat);
+
+ VECCOPY(t->center, center);
}
}
@@ -2221,10 +2736,7 @@ int Trackball(TransInfo *t, short mval[2])
/* factore has to become setting or so */
phi[0]= 0.01f*(float)( t->imval[1] - mval[1] );
phi[1]= 0.01f*(float)( mval[0] - t->imval[0] );
-
- //if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
- //else t->fac += dphi;
-
+
applyNDofInput(&t->ndof, phi);
snapGrid(t, phi);
@@ -2243,8 +2755,13 @@ int Trackball(TransInfo *t, short mval[2])
}
else {
sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
- }
+ if(t->flag & T_SHIFT_MOD) {
+ if(phi[0] != 0.0) phi[0]/= 5.0f;
+ if(phi[1] != 0.0) phi[1]/= 5.0f;
+ }
+ }
+
VecRotToMat3(axis1, phi[0], smat);
VecRotToMat3(axis2, phi[1], totmat);
@@ -2310,6 +2827,7 @@ void initTranslation(TransInfo *t)
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
char tvec[60];
char distvec[20];
+ char autoik[20];
float dvec[3];
float dist;
@@ -2330,24 +2848,35 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
sprintf(distvec, "%.4e", dist);
else
sprintf(distvec, "%.4f", dist);
+
+ if(t->flag & T_AUTOIK) {
+ short chainlen= G.scene->toolsettings->autoik_chainlen;
+
+ if(chainlen)
+ sprintf(autoik, "AutoIK-Len: %d", chainlen);
+ else
+ strcpy(autoik, "");
+ }
+ else
+ strcpy(autoik, "");
if (t->con.mode & CON_APPLY) {
switch(t->num.idx_max) {
case 0:
- sprintf(str, "D: %s (%s)%s %s", &tvec[0], distvec, t->con.text, t->proptext);
+ sprintf(str, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]);
break;
case 1:
- sprintf(str, "D: %s D: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext);
+ sprintf(str, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext, &autoik[0]);
break;
case 2:
- sprintf(str, "D: %s D: %s D: %s (%s)%s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext);
+ sprintf(str, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
}
}
else {
if(t->flag & T_2D_EDIT)
sprintf(str, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[20], distvec, t->con.text, t->proptext);
else
- sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext);
+ sprintf(str, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[20], &tvec[40], distvec, t->con.text, t->proptext, &autoik[0]);
}
}
@@ -2359,7 +2888,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;
+
if (t->con.applyVec) {
float pvec[3];
t->con.applyVec(t, td, vec, tvec, pvec);
@@ -2367,7 +2899,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
else {
VECCOPY(tvec, vec);
}
-
+
Mat3MulVecfl(td->smtx, tvec);
VecMulf(tvec, td->factor);
@@ -2381,6 +2913,8 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]);
}
else VecAddf(td->loc, td->iloc, tvec);
+
+ constraintTransLim(t, td);
}
}
@@ -2388,7 +2922,7 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
int Translation(TransInfo *t, short mval[2])
{
float tvec[3];
- char str[200];
+ char str[250];
if(t->flag & T_SHIFT_MOD) {
float dvec[3];
@@ -2488,6 +3022,9 @@ int ShrinkFatten(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
VECCOPY(vec, td->axismtx[2]);
VecMulf(vec, distance);
VecMulf(vec, td->factor);
@@ -2535,23 +3072,23 @@ int Tilt(TransInfo *t, short mval[2])
float final;
- int dx2 = t->center2d[0] - mval[0];
- int dy2 = t->center2d[1] - mval[1];
- float B = (float)sqrt(dx2*dx2+dy2*dy2);
+ double dx2 = t->center2d[0] - mval[0];
+ double dy2 = t->center2d[1] - mval[1];
+ double B = (float)sqrt(dx2*dx2+dy2*dy2);
- int dx1 = t->center2d[0] - t->imval[0];
- int dy1 = t->center2d[1] - t->imval[1];
- float A = (float)sqrt(dx1*dx1+dy1*dy1);
+ double dx1 = t->center2d[0] - t->imval[0];
+ double dy1 = t->center2d[1] - t->imval[1];
+ double A = (float)sqrt(dx1*dx1+dy1*dy1);
- int dx3 = mval[0] - t->imval[0];
- int dy3 = mval[1] - t->imval[1];
+ double dx3 = mval[0] - t->imval[0];
+ double dy3 = mval[1] - t->imval[1];
- float deler= ((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3))
+ double deler= ((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3))
/ (2 * A * B);
float dphi;
- dphi = saacos(deler);
+ dphi = saacos((float)deler);
if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
if(G.qual & LR_SHIFTKEY) t->fac += dphi/30.0f;
@@ -2585,6 +3122,9 @@ int Tilt(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
if (td->val) {
*td->val = td->ival + final * td->factor;
}
@@ -2646,6 +3186,9 @@ int CurveShrinkFatten(TransInfo *t, short mval[2])
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
if(td->val) {
//*td->val= ratio;
@@ -2741,6 +3284,9 @@ int PushPull(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
VecSubf(vec, t->center, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
t->con.applyRot(t, td, axis);
@@ -2769,6 +3315,201 @@ int PushPull(TransInfo *t, short mval[2])
return 1;
}
+/* ************************** BEVEL **************************** */
+
+void initBevel(TransInfo *t)
+{
+ t->mode = TFM_BEVEL;
+ t->flag |= T_NO_CONSTRAINT;
+ t->transform = Bevel;
+ t->handleEvent = handleEventBevel;
+ if (G.editBMesh->imval[0] == 0 && G.editBMesh->imval[1] == 0) {
+ /* save the initial mouse co */
+ G.editBMesh->imval[0] = t->imval[0];
+ G.editBMesh->imval[1] = t->imval[1];
+ }
+ else {
+ /* restore the mouse co from a previous call to initTransform() */
+ t->imval[0] = G.editBMesh->imval[0];
+ t->imval[1] = G.editBMesh->imval[1];
+ }
+}
+
+int handleEventBevel(TransInfo *t, unsigned short event, short val)
+{
+ if (val) {
+ switch (event) {
+ case MIDDLEMOUSE:
+ G.editBMesh->options ^= BME_BEVEL_VERT;
+ t->state = TRANS_CANCEL;
+ return 1;
+ //case PADPLUSKEY:
+ // G.editBMesh->options ^= BME_BEVEL_RES;
+ // G.editBMesh->res += 1;
+ // if (G.editBMesh->res > 4) {
+ // G.editBMesh->res = 4;
+ // }
+ // t->state = TRANS_CANCEL;
+ // return 1;
+ //case PADMINUS:
+ // G.editBMesh->options ^= BME_BEVEL_RES;
+ // G.editBMesh->res -= 1;
+ // if (G.editBMesh->res < 0) {
+ // G.editBMesh->res = 0;
+ // }
+ // t->state = TRANS_CANCEL;
+ // return 1;
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
+int Bevel(TransInfo *t, short mval[2])
+{
+ float distance,d;
+ int i;
+ char str[128];
+ char *mode;
+ TransData *td = t->data;
+
+ mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal";
+ distance = InputHorizontalAbsolute(t, mval)/4; /* 4 just seemed a nice value to me, nothing special */
+
+ applyNumInput(&t->num, &distance);
+
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[20];
+
+ outputNumInput(&(t->num), c);
+
+ sprintf(str, "Bevel: %s", c);
+ }
+ else {
+ /* default header print */
+ sprintf(str, "Bevel - Dist: %.4f, Mode: %s (MMB to toggle))", distance, mode);
+ }
+
+ if (distance < 0) distance = -distance;
+ for(i = 0 ; i < t->total; i++, td++) {
+ if (td->axismtx[1][0] > 0 && distance > td->axismtx[1][0]) {
+ d = td->axismtx[1][0];
+ }
+ else {
+ d = distance;
+ }
+ VECADDFAC(td->loc,td->center,td->axismtx[0],(*td->val)*d);
+ }
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ return 1;
+}
+
+/* ************************** BEVEL WEIGHT *************************** */
+
+void initBevelWeight(TransInfo *t)
+{
+ t->mode = TFM_BWEIGHT;
+ t->transform = BevelWeight;
+
+ 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;
+
+ t->fac = (float)sqrt(
+ (
+ ((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+ +
+ ((float)(t->center2d[0] - t->imval[0]))*((float)(t->center2d[0] - t->imval[0]))
+ ) );
+
+ if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
+}
+
+int BevelWeight(TransInfo *t, short mval[2])
+{
+ TransData *td = t->data;
+ float weight;
+ int i;
+ char str[50];
+
+
+ if(t->flag & T_SHIFT_MOD) {
+ /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
+ float dx= (float)(t->center2d[0] - t->shiftmval[0]);
+ float dy= (float)(t->center2d[1] - t->shiftmval[1]);
+ weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
+
+ dx= (float)(t->center2d[0] - mval[0]);
+ dy= (float)(t->center2d[1] - mval[1]);
+ weight+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -weight);
+
+ }
+ else {
+ float dx= (float)(t->center2d[0] - mval[0]);
+ float dy= (float)(t->center2d[1] - mval[1]);
+ weight = (float)sqrt( dx*dx + dy*dy)/t->fac;
+ }
+
+ weight -= 1.0f;
+ if (weight > 1.0f) weight = 1.0f;
+
+ snapGrid(t, &weight);
+
+ applyNumInput(&t->num, &weight);
+
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[20];
+
+ outputNumInput(&(t->num), c);
+
+ if (weight >= 0.0f)
+ sprintf(str, "Bevel Weight: +%s %s", c, t->proptext);
+ else
+ sprintf(str, "Bevel Weight: %s %s", c, t->proptext);
+ }
+ else {
+ /* default header print */
+ if (weight >= 0.0f)
+ sprintf(str, "Bevel Weight: +%.3f %s", weight, t->proptext);
+ else
+ sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext);
+ }
+
+ for(i = 0 ; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->val) {
+ *td->val = td->ival + weight * td->factor;
+ if (*td->val < 0.0f) *td->val = 0.0f;
+ if (*td->val > 1.0f) *td->val = 1.0f;
+ }
+ }
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ helpline (t, t->center);
+
+ return 1;
+}
+
/* ************************** CREASE *************************** */
void initCrease(TransInfo *t)
@@ -2849,6 +3590,9 @@ int Crease(TransInfo *t, short mval[2])
if (td->flag & TD_NOACTION)
break;
+ if (td->flag & TD_SKIP)
+ continue;
+
if (td->val) {
*td->val = td->ival + crease * td->factor;
if (*td->val < 0.0f) *td->val = 0.0f;
@@ -2874,14 +3618,13 @@ void initBoneSize(TransInfo *t)
t->mode = TFM_BONESIZE;
t->transform = BoneSize;
- t->idx_max = 0;
- t->num.idx_max = 0;
+ t->idx_max = 2;
+ t->num.idx_max = 2;
+ t->num.flag |= NUM_NULL_ONE;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
-
- t->flag |= T_NO_CONSTRAINT;
-
+
t->fac = (float)sqrt( (
((float)(t->center2d[1] - t->imval[1]))*((float)(t->center2d[1] - t->imval[1]))
+
@@ -2891,6 +3634,29 @@ void initBoneSize(TransInfo *t)
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
+static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
+ char tvec[60];
+ if (hasNumInput(&t->num)) {
+ outputNumInput(&(t->num), tvec);
+ }
+ else {
+ sprintf(&tvec[0], "%.4f", vec[0]);
+ sprintf(&tvec[20], "%.4f", vec[1]);
+ sprintf(&tvec[40], "%.4f", vec[2]);
+ }
+
+ /* hmm... perhaps the y-axis values don't need to be shown? */
+ if (t->con.mode & CON_APPLY) {
+ if (t->num.idx_max == 0)
+ sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext);
+ else
+ sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
+ }
+ else {
+ sprintf(str, "ScaleB X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
+ }
+}
+
static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
{
float tmat[3][3], smat[3][3], oldy;
@@ -2917,7 +3683,7 @@ int BoneSize(TransInfo *t, short mval[2])
float size[3], mat[3][3];
float ratio;
int i;
- char str[50];
+ char str[60];
/* for manipulator, center handle, the scaling can't be done relative to center */
if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0) {
@@ -2965,11 +3731,14 @@ int BoneSize(TransInfo *t, short mval[2])
Mat3CpyMat3(t->mat, mat); // used in manipulator
- headerResize(t, size, str);
+ 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);
}
@@ -3052,8 +3821,17 @@ int BoneEnvelope(TransInfo *t, short mval[2])
for(i = 0 ; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
- if(td->val) *td->val= td->ival*ratio;
+ if (td->val) {
+ /* if the old/original value was 0.0f, then just use ratio */
+ if (td->ival)
+ *td->val= td->ival*ratio;
+ else
+ *td->val= ratio;
+ }
}
recalcData(t);
@@ -3094,16 +3872,16 @@ int BoneRoll(TransInfo *t, short mval[2])
float final;
- int dx2 = t->center2d[0] - mval[0];
- int dy2 = t->center2d[1] - mval[1];
+ double dx2 = t->center2d[0] - mval[0];
+ double dy2 = t->center2d[1] - mval[1];
double B = sqrt(dx2*dx2+dy2*dy2);
- int dx1 = t->center2d[0] - t->imval[0];
- int dy1 = t->center2d[1] - t->imval[1];
+ double dx1 = t->center2d[0] - t->imval[0];
+ double dy1 = t->center2d[1] - t->imval[1];
double A = sqrt(dx1*dx1+dy1*dy1);
- int dx3 = mval[0] - t->imval[0];
- int dy3 = mval[1] - t->imval[1];
+ double dx3 = mval[0] - t->imval[0];
+ double dy3 = mval[1] - t->imval[1];
/* use doubles here, to make sure a "1.0" (no rotation) doesnt become 9.999999e-01, which gives 0.02 for acos */
double deler= ((double)((dx1*dx1+dy1*dy1)+(dx2*dx2+dy2*dy2)-(dx3*dx3+dy3*dy3) ))
/ (2.0 * (A*B?A*B:1.0));
@@ -3143,6 +3921,9 @@ int BoneRoll(TransInfo *t, short mval[2])
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
*(td->val) = td->ival - final;
}
@@ -3158,101 +3939,727 @@ int BoneRoll(TransInfo *t, short mval[2])
return 1;
}
-/* ************************** MIRROR *************************** */
+/* ************************** BAKE TIME ******************* */
-void Mirror(short mode)
+void initBakeTime(TransInfo *t)
{
- TransData *td;
- float mati[3][3], matview[3][3], mat[3][3];
- float size[3];
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = 1.0f;
+ t->snap[2] = t->snap[1] * 0.1f;
+ t->transform = BakeTime;
+ t->fac = 0.1f;
+}
+
+int BakeTime(TransInfo *t, short mval[2])
+{
+ TransData *td = t->data;
+ float time;
int i;
+ char str[50];
- Trans.context = CTX_NO_PET;
+
+ if(t->flag & T_SHIFT_MOD) {
+ /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
+ time= (float)(t->center2d[0] - t->shiftmval[0])*t->fac;
+ time+= 0.1f*((float)(t->center2d[0]*t->fac - mval[0]) -time);
+ }
+ else {
+ time = (float)(t->center2d[0] - mval[0])*t->fac;
+ }
- initTrans(&Trans); // internal data, mouse, vectors
+ snapGrid(t, &time);
- Mat3One(mati);
- Mat3CpyMat4(matview, Trans.viewinv); // t->viewinv was set in initTrans
- Mat3Ortho(matview);
+ applyNumInput(&t->num, &time);
- createTransData(&Trans); // make TransData structs from selection
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[20];
- calculatePropRatio(&Trans);
- calculateCenter(&Trans);
+ outputNumInput(&(t->num), c);
- initResize(&Trans);
+ if (time >= 0.0f)
+ sprintf(str, "Time: +%s %s", c, t->proptext);
+ else
+ sprintf(str, "Time: %s %s", c, t->proptext);
+ }
+ else {
+ /* default header print */
+ if (time >= 0.0f)
+ sprintf(str, "Time: +%.3f %s", time, t->proptext);
+ else
+ sprintf(str, "Time: %.3f %s", time, t->proptext);
+ }
+
+ for(i = 0 ; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
- if (Trans.total == 0) {
- postTrans(&Trans);
- return;
+ if (td->flag & TD_SKIP)
+ continue;
+
+ if (td->val) {
+ *td->val = td->ival + time * td->factor;
+ if (td->ext->size && *td->val < *td->ext->size) *td->val = *td->ext->size;
+ if (td->ext->quat && *td->val > *td->ext->quat) *td->val = *td->ext->quat;
+ }
}
- size[0] = size[1] = size[2] = 1.0f;
- td = Trans.data;
+ recalcData(t);
- switch (mode) {
- case 1:
- size[0] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS0), "");
- break;
- case 2:
- size[1] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS1), "");
- break;
- case 3:
- size[2] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS2), "");
- break;
- case 4:
- size[0] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS0), "");
- break;
- case 5:
- size[1] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS1), "");
- break;
- case 6:
- size[2] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS2), "");
- break;
- case 7:
- size[0] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS0), "");
- break;
- case 8:
- size[1] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS1), "");
- break;
- case 9:
- size[2] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS2), "");
- break;
- default:
- return;
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ helpline (t, t->center);
+
+ return 1;
+}
+
+/* ************************** MIRROR *************************** */
+
+void initMirror(TransInfo *t)
+{
+ t->flag |= T_NULL_ONE;
+ if (!G.obedit) {
+ t->flag |= T_NO_ZERO;
}
+
+ t->transform = Mirror;
+}
- SizeToMat3(size, mat);
+int Mirror(TransInfo *t, short mval[2])
+{
+ TransData *td;
+ float size[3], mat[3][3];
+ int i;
+ char str[200];
- if (Trans.con.applySize) {
- Trans.con.applySize(&Trans, NULL, mat);
+ /*
+ * OPTIMISATION:
+ * This still recalcs transformation on mouse move
+ * while it should only recalc on constraint change
+ * */
+
+ /* if an axis has been selected */
+ if (t->con.mode & CON_APPLY) {
+ size[0] = size[1] = size[2] = -1;
+
+ SizeToMat3(size, mat);
+
+ if (t->con.applySize) {
+ t->con.applySize(t, NULL, mat);
+ }
+
+ sprintf(str, "Mirror%s", t->con.text);
+
+ 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);
+ }
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+ }
+ else
+ {
+ size[0] = size[1] = size[2] = 1;
+
+ SizeToMat3(size, mat);
+
+ 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);
+ }
+
+ recalcData(t);
+
+ headerprint("Select a mirror axis (X, Y, Z)");
+
+ viewRedrawForce(t);
}
- for(i = 0 ; i < Trans.total; i++, td++) {
+ return 1;
+}
+
+/* ************************** ALIGN *************************** */
+
+void initAlign(TransInfo *t)
+{
+ t->flag |= T_NO_CONSTRAINT;
+
+ t->transform = Align;
+}
+
+int Align(TransInfo *t, short mval[2])
+{
+ TransData *td = t->data;
+ float center[3];
+ int i;
+
+ /* saving original center */
+ VECCOPY(center, t->center);
+
+ for(i = 0 ; i < t->total; i++, td++)
+ {
+ float mat[3][3], invmat[3][3];
+
if (td->flag & TD_NOACTION)
break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ /* around local centers */
+ if (t->flag & (T_OBJECT|T_POSE)) {
+ VECCOPY(t->center, td->center);
+ }
+ else {
+ if(G.scene->selectmode & SCE_SELECT_FACE) {
+ VECCOPY(t->center, td->center);
+ }
+ }
+
+ Mat3Inv(invmat, td->axismtx);
- ElementResize(&Trans, td, mat);
+ Mat3MulMat3(mat, t->spacemtx, invmat);
+
+ ElementRotation(t, td, mat);
}
- recalcData(&Trans);
+ /* restoring original center */
+ VECCOPY(t->center, center);
+
+ recalcData(t);
+
+ headerprint("Align");
- BIF_undo_push("Mirror");
+ return 1;
+}
- /* free data, reset vars */
- postTrans(&Trans);
+/* ************************** ANIM EDITORS - TRANSFORM TOOLS *************************** */
- /* send events out for redraws */
- viewRedrawPost(&Trans);
+/* ---------------- Special Helpers for Various Settings ------------- */
+
+/* This function returns the snapping 'mode' for Animation Editors only
+ * We cannot use the standard snapping due to NLA-strip scaling complexities.
+ */
+static short getAnimEdit_SnapMode(TransInfo *t)
+{
+ short autosnap= SACTSNAP_OFF;
+
+ /* currently, some of these are only for the action editor */
+ if (t->spacetype == SPACE_ACTION && G.saction) {
+ switch (G.saction->autosnap) {
+ case SACTSNAP_OFF:
+ if (G.qual == LR_CTRLKEY)
+ autosnap= SACTSNAP_STEP;
+ else if (G.qual == LR_SHIFTKEY)
+ autosnap= SACTSNAP_FRAME;
+ else if (G.qual == LR_ALTKEY)
+ autosnap= SACTSNAP_MARKER;
+ else
+ autosnap= SACTSNAP_OFF;
+ break;
+ case SACTSNAP_STEP:
+ autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
+ break;
+ case SACTSNAP_FRAME:
+ autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
+ break;
+ case SACTSNAP_MARKER:
+ autosnap= (G.qual==LR_ALTKEY)? SACTSNAP_OFF: SACTSNAP_MARKER;
+ break;
+ }
+ }
+ else if (t->spacetype == SPACE_NLA && G.snla) {
+ switch (G.snla->autosnap) {
+ case SACTSNAP_OFF:
+ if (G.qual == LR_CTRLKEY)
+ autosnap= SACTSNAP_STEP;
+ else if (G.qual == LR_SHIFTKEY)
+ autosnap= SACTSNAP_FRAME;
+ else if (G.qual == LR_ALTKEY)
+ autosnap= SACTSNAP_MARKER;
+ else
+ autosnap= SACTSNAP_OFF;
+ break;
+ case SACTSNAP_STEP:
+ autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_STEP;
+ break;
+ case SACTSNAP_FRAME:
+ autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
+ break;
+ case SACTSNAP_MARKER:
+ autosnap= (G.qual==LR_ALTKEY)? SACTSNAP_OFF: SACTSNAP_MARKER;
+ break;
+ }
+ }
+ else {
+ if (G.qual == LR_CTRLKEY)
+ autosnap= SACTSNAP_STEP;
+ else if (G.qual == LR_SHIFTKEY)
+ autosnap= SACTSNAP_FRAME;
+ else if (G.qual == LR_ALTKEY)
+ autosnap= SACTSNAP_MARKER;
+ else
+ autosnap= SACTSNAP_OFF;
+ }
+
+ return autosnap;
+}
+
+/* This function is used for testing if an Animation Editor is displaying
+ * its data in frames or seconds (and the data needing to be edited as such).
+ * Returns 1 if in seconds, 0 if in frames
+ */
+static short getAnimEdit_DrawTime(TransInfo *t)
+{
+ short drawtime;
+
+ /* currently, some of these are only for the action editor */
+ if (t->spacetype == SPACE_ACTION && G.saction) {
+ drawtime = (G.saction->flag & SACTION_DRAWTIME)? 1 : 0;
+ }
+ else if (t->spacetype == SPACE_NLA && G.snla) {
+ drawtime = (G.snla->flag & SNLA_DRAWTIME)? 1 : 0;
+ }
+ else {
+ drawtime = 0;
+ }
+
+ return drawtime;
+}
+
+
+/* This function is used by Animation Editor specific transform functions to do
+ * the Snap Keyframe to Nearest Frame/Marker
+ */
+static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, Object *ob, short autosnap)
+{
+ /* snap key to nearest frame? */
+ if (autosnap == SACTSNAP_FRAME) {
+ short doTime= getAnimEdit_DrawTime(t);
+ double secf= FPS;
+ float val;
+
+ /* convert frame to nla-action time (if needed) */
+ if (ob)
+ val= get_action_frame_inv(ob, *(td->val));
+ else
+ val= *(td->val);
+
+ /* do the snapping to nearest frame/second */
+ if (doTime)
+ val= (float)( floor((val/secf) + 0.5f) * secf );
+ else
+ val= (float)( floor(val+0.5f) );
+
+ /* convert frame out of nla-action time */
+ if (ob)
+ *(td->val)= get_action_frame(ob, val);
+ else
+ *(td->val)= val;
+ }
+ /* snap key to nearest marker? */
+ else if (autosnap == SACTSNAP_MARKER) {
+ float val;
+
+ /* convert frame to nla-action time (if needed) */
+ if (ob)
+ val= get_action_frame_inv(ob, *(td->val));
+ else
+ val= *(td->val);
+
+ /* snap to nearest marker */
+ val= (float)find_nearest_marker_time(val);
+
+ /* convert frame out of nla-action time */
+ if (ob)
+ *(td->val)= get_action_frame(ob, val);
+ else
+ *(td->val)= val;
+ }
+}
+
+/* ----------------- Translation ----------------------- */
+
+void initTimeTranslate(TransInfo *t)
+{
+ t->mode = TFM_TIME_TRANSLATE;
+ t->transform = TimeTranslate;
+
+ /* num-input has max of (n-1) */
+ t->idx_max = 0;
+ t->num.flag = 0;
+ t->num.idx_max = t->idx_max;
+
+ /* initialise snap like for everything else */
+ t->snap[0] = 0.0f;
+ t->snap[1] = t->snap[2] = 1.0f;
+}
+
+static void headerTimeTranslate(TransInfo *t, char *str)
+{
+ char tvec[60];
+
+ /* if numeric input is active, use results from that, otherwise apply snapping to result */
+ if (hasNumInput(&t->num)) {
+ outputNumInput(&(t->num), tvec);
+ }
+ else {
+ short autosnap= getAnimEdit_SnapMode(t);
+ short doTime = getAnimEdit_DrawTime(t);
+ double secf= FPS;
+ float val= t->fac;
+
+ /* apply snapping + frame->seconds conversions */
+ if (autosnap == SACTSNAP_STEP) {
+ if (doTime)
+ val= floor(val/secf + 0.5f);
+ else
+ val= floor(val + 0.5f);
+ }
+ else {
+ if (doTime)
+ val= val / secf;
+ }
+
+ sprintf(&tvec[0], "%.4f", val);
+ }
+
+ sprintf(str, "DeltaX: %s", &tvec[0]);
+}
+
+static void applyTimeTranslate(TransInfo *t, float sval)
+{
+ TransData *td = t->data;
+ int i;
+
+ short doTime= getAnimEdit_DrawTime(t);
+ double secf= FPS;
+
+ short autosnap= getAnimEdit_SnapMode(t);
+
+ float deltax, val;
+
+ /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
+ for (i = 0 ; i < t->total; i++, td++) {
+ /* it is assumed that td->ob is a pointer to the object,
+ * whose active action is where this keyframe comes from
+ */
+ Object *ob= td->ob;
+
+ /* check if any need to apply nla-scaling */
+ if (ob) {
+ deltax = t->fac;
+
+ if (autosnap == SACTSNAP_STEP) {
+ if (doTime)
+ deltax= (float)( floor((deltax/secf) + 0.5f) * secf );
+ else
+ deltax= (float)( floor(deltax + 0.5f) );
+ }
+
+ val = get_action_frame_inv(ob, td->ival);
+ val += deltax;
+ *(td->val) = get_action_frame(ob, val);
+ }
+ else {
+ deltax = val = t->fac;
+
+ if (autosnap == SACTSNAP_STEP) {
+ if (doTime)
+ val= (float)( floor((deltax/secf) + 0.5f) * secf );
+ else
+ val= (float)( floor(val + 0.5f) );
+ }
+
+ *(td->val) = td->ival + val;
+ }
+
+ /* apply nearest snapping */
+ doAnimEdit_SnapFrame(t, td, ob, autosnap);
+ }
+}
+
+int TimeTranslate(TransInfo *t, short mval[2])
+{
+ float cval[2], sval[2];
+ char str[200];
+
+ /* calculate translation amount from mouse movement - in 'time-grid space' */
+ areamouseco_to_ipoco(G.v2d, mval, &cval[0], &cval[1]);
+ areamouseco_to_ipoco(G.v2d, t->imval, &sval[0], &sval[1]);
+
+ /* we only need to calculate effect for time (applyTimeTranslate only needs that) */
+ t->fac= cval[0] - sval[0];
+
+ /* handle numeric-input stuff */
+ t->vec[0] = t->fac;
+ applyNumInput(&t->num, &t->vec[0]);
+ t->fac = t->vec[0];
+ headerTimeTranslate(t, str);
+
+ applyTimeTranslate(t, sval[0]);
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ return 1;
+}
+
+/* ----------------- Time Slide ----------------------- */
+
+void initTimeSlide(TransInfo *t)
+{
+ /* this tool is only really available in the Action Editor... */
+ if (t->spacetype == SPACE_ACTION) {
+ /* set flag for drawing stuff*/
+ G.saction->flag |= SACTION_MOVING;
+ }
+
+ t->mode = TFM_TIME_SLIDE;
+ t->transform = TimeSlide;
+ t->flag |= T_FREE_CUSTOMDATA;
+
+ /* num-input has max of (n-1) */
+ t->idx_max = 0;
+ t->num.flag = 0;
+ t->num.idx_max = t->idx_max;
+
+ /* initialise snap like for everything else */
+ t->snap[0] = 0.0f;
+ t->snap[1] = t->snap[2] = 1.0f;
+}
+
+static void headerTimeSlide(TransInfo *t, float sval, char *str)
+{
+ char tvec[60];
+
+ if (hasNumInput(&t->num)) {
+ outputNumInput(&(t->num), tvec);
+ }
+ else {
+ float minx= *((float *)(t->customData));
+ float maxx= *((float *)(t->customData) + 1);
+ float cval= t->fac;
+ float val;
+
+ val= 2.0*(cval-sval) / (maxx-minx);
+ CLAMP(val, -1.0f, 1.0f);
+
+ sprintf(&tvec[0], "%.4f", val);
+ }
+
+ sprintf(str, "TimeSlide: %s", &tvec[0]);
+}
+
+static void applyTimeSlide(TransInfo *t, float sval)
+{
+ TransData *td = t->data;
+ int i;
+
+ float minx= *((float *)(t->customData));
+ float maxx= *((float *)(t->customData) + 1);
+
+
+ /* set value for drawing black line */
+ if (t->spacetype == SPACE_ACTION) {
+ float cvalf = t->fac;
+
+ if (NLA_ACTION_SCALED)
+ cvalf= get_action_frame(OBACT, cvalf);
+
+ G.saction->timeslide= cvalf;
+ }
+
+ /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
+ for (i = 0 ; i < t->total; i++, td++) {
+ /* it is assumed that td->ob is a pointer to the object,
+ * whose active action is where this keyframe comes from
+ */
+ Object *ob= td->ob;
+ float cval = t->fac;
+
+ /* apply scaling to necessary values */
+ if (ob)
+ cval= get_action_frame(ob, cval);
+
+ /* only apply to data if in range */
+ if ((sval > minx) && (sval < maxx)) {
+ float cvalc= CLAMPIS(cval, minx, maxx);
+ float timefac;
+
+ /* left half? */
+ if (td->ival < sval) {
+ timefac= (sval - td->ival) / (sval - minx);
+ *(td->val)= cvalc - timefac * (cvalc - minx);
+ }
+ else {
+ timefac= (td->ival - sval) / (maxx - sval);
+ *(td->val)= cvalc + timefac * (maxx - cvalc);
+ }
+ }
+ }
+}
+
+int TimeSlide(TransInfo *t, short mval[2])
+{
+ float cval[2], sval[2];
+ float minx= *((float *)(t->customData));
+ float maxx= *((float *)(t->customData) + 1);
+ char str[200];
+
+ /* calculate mouse co-ordinates */
+ areamouseco_to_ipoco(G.v2d, mval, &cval[0], &cval[1]);
+ areamouseco_to_ipoco(G.v2d, t->imval, &sval[0], &sval[1]);
+
+ /* t->fac stores cval[0], which is the current mouse-pointer location (in frames) */
+ t->fac= cval[0];
+
+ /* handle numeric-input stuff */
+ t->vec[0] = 2.0*(cval[0]-sval[0]) / (maxx-minx);
+ applyNumInput(&t->num, &t->vec[0]);
+ t->fac = (maxx-minx) * t->vec[0] / 2.0 + sval[0];
+
+ headerTimeSlide(t, sval[0], str);
+ applyTimeSlide(t, sval[0]);
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ return 1;
+}
+
+/* ----------------- Scaling ----------------------- */
+
+void initTimeScale(TransInfo *t)
+{
+ t->mode = TFM_TIME_SCALE;
+ t->transform = TimeScale;
+
+ t->flag |= T_NULL_ONE;
+ t->num.flag |= NUM_NULL_ONE;
+
+ /* num-input has max of (n-1) */
+ t->idx_max = 0;
+ t->num.flag = 0;
+ t->num.idx_max = t->idx_max;
+
+ /* initialise snap like for everything else */
+ t->snap[0] = 0.0f;
+ t->snap[1] = t->snap[2] = 1.0f;
+}
+
+static void headerTimeScale(TransInfo *t, char *str) {
+ char tvec[60];
+
+ if (hasNumInput(&t->num))
+ outputNumInput(&(t->num), tvec);
+ else
+ sprintf(&tvec[0], "%.4f", t->fac);
+
+ sprintf(str, "ScaleX: %s", &tvec[0]);
+}
+
+static void applyTimeScale(TransInfo *t) {
+ TransData *td = t->data;
+ int i;
+
+ short autosnap= getAnimEdit_SnapMode(t);
+ short doTime= getAnimEdit_DrawTime(t);
+ double secf= FPS;
+
+
+ for (i = 0 ; i < t->total; i++, td++) {
+ /* it is assumed that td->ob is a pointer to the object,
+ * whose active action is where this keyframe comes from
+ */
+ Object *ob= td->ob;
+ float startx= CFRA;
+ float fac= t->fac;
+
+ if (autosnap == SACTSNAP_STEP) {
+ if (doTime)
+ fac= (float)( floor(fac/secf + 0.5f) * secf );
+ else
+ fac= (float)( floor(fac + 0.5f) );
+ }
+
+ /* check if any need to apply nla-scaling */
+ if (ob)
+ startx= get_action_frame(ob, startx);
+
+ /* now, calculate the new value */
+ *(td->val) = td->ival - startx;
+ *(td->val) *= fac;
+ *(td->val) += startx;
+
+ /* apply nearest snapping */
+ doAnimEdit_SnapFrame(t, td, ob, autosnap);
+ }
+}
+
+int TimeScale(TransInfo *t, short mval[2])
+{
+ float cval, sval;
+ float deltax, startx;
+ float width= 0.0f;
+ char str[200];
+
+ sval= t->imval[0];
+ cval= mval[0];
+
+ switch (t->spacetype) {
+ case SPACE_ACTION:
+ width= ACTWIDTH;
+ break;
+ case SPACE_NLA:
+ width= NLAWIDTH;
+ break;
+ }
+
+ /* calculate scaling factor */
+ startx= sval-(width/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
+ deltax= cval-(width/2+(curarea->winrct.xmax-curarea->winrct.xmin)/2);
+ t->fac = deltax / startx;
+
+ /* handle numeric-input stuff */
+ t->vec[0] = t->fac;
+ applyNumInput(&t->num, &t->vec[0]);
+ t->fac = t->vec[0];
+ headerTimeScale(t, str);
+
+ applyTimeScale(t);
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
+
+ return 1;
}
/* ************************************ */
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index ccba909cd6d..76c480bba8b 100755..100644
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -539,6 +539,10 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[]) {
sprintf(text, ftext, "view");
setConstraint(t, t->spacemtx, mode, text);
break;
+ default: /* V3D_MANIP_CUSTOM */
+ sprintf(text, ftext, t->spacename);
+ setConstraint(t, t->spacemtx, mode, text);
+ break;
}
t->con.mode |= CON_USER;
@@ -594,12 +598,21 @@ void BIF_setSingleAxisConstraint(float vec[3], char *text) {
Mat3Ortho(space);
Mat3CpyMat3(t->con.mtx, space);
- t->con.mode = (CON_AXIS0|CON_APPLY);
+ t->con.mode = CON_AXIS0;
+
getConstraintMatrix(t);
+ startConstraint(t);
+
/* start copying with an offset of 1, to reserve a spot for the SPACE char */
- if(text) strncpy(t->con.text+1, text, 48); // 50 in struct
-
+ if(text)
+ {
+ strncpy(t->con.text+1, text, 48); /* 50 in struct */
+ }
+ else
+ {
+ t->con.text[1] = '\0'; /* No text */
+ }
t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec;
@@ -618,11 +631,21 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text) {
Mat3Ortho(space);
Mat3CpyMat3(t->con.mtx, space);
- t->con.mode = (CON_AXIS0|CON_AXIS1|CON_APPLY);
+ t->con.mode = CON_AXIS0|CON_AXIS1;
+
getConstraintMatrix(t);
+
+ startConstraint(t);
/* start copying with an offset of 1, to reserve a spot for the SPACE char */
- if(text) strncpy(t->con.text+1, text, 48); // 50 in struct
+ if(text)
+ {
+ strncpy(t->con.text+1, text, 48); /* 50 in struct */
+ }
+ else
+ {
+ t->con.text[1] = '\0'; /* No text */
+ }
t->con.drawExtra = NULL;
t->con.applyVec = applyAxisConstraintVec;
@@ -700,7 +723,8 @@ void BIF_drawPropCircle()
BIF_ThemeColor(TH_GRID);
/* if editmode we need to go into object space */
- if(G.obedit) mymultmatrix(G.obedit->obmat);
+ if(G.obedit && t->spacetype == SPACE_VIEW3D)
+ mymultmatrix(G.obedit->obmat);
mygetmatrix(tmat);
Mat4Invert(imat, tmat);
@@ -710,7 +734,8 @@ void BIF_drawPropCircle()
set_inverted_drawing(0);
/* if editmode we restore */
- if(G.obedit) myloadmatrix(G.vd->viewmat);
+ if(G.obedit && t->spacetype == SPACE_VIEW3D)
+ myloadmatrix(G.vd->viewmat);
}
}
@@ -840,24 +865,40 @@ void postSelectConstraint(TransInfo *t)
t->redraw = 1;
}
-void setNearestAxis(TransInfo *t)
+static void setNearestAxis2d(TransInfo *t)
+{
+ short mval[2];
+ short ival[2];
+
+ getmouseco_areawin(mval);
+ ival[0]= t->imval[0];
+ ival[1]= t->imval[1];
+
+ /* no correction needed... just use whichever one is lower */
+ if ( abs(mval[0]-ival[0]) < abs(mval[1]-ival[1]) ) {
+ t->con.mode |= CON_AXIS1;
+ sprintf(t->con.text, " along Y axis");
+ }
+ else {
+ t->con.mode |= CON_AXIS0;
+ sprintf(t->con.text, " along X axis");
+ }
+}
+
+static void setNearestAxis3d(TransInfo *t)
{
float zfac;
float mvec[3], axis[3], proj[3];
float len[3];
int i, icoord[2];
short coord[2];
-
- t->con.mode &= ~CON_AXIS0;
- t->con.mode &= ~CON_AXIS1;
- t->con.mode &= ~CON_AXIS2;
-
+
+ /* calculate mouse movement */
getmouseco_areawin(coord);
mvec[0] = (float)(coord[0] - t->con.imval[0]);
mvec[1] = (float)(coord[1] - t->con.imval[1]);
mvec[2] = 0.0f;
-
-
+
/* we need to correct axis length for the current zoomlevel of view,
this to prevent projected values to be clipped behind the camera
and to overflow the short integers.
@@ -920,6 +961,25 @@ void setNearestAxis(TransInfo *t)
sprintf(t->con.text, " along %s Z axis", t->spacename);
}
}
+}
+
+void setNearestAxis(TransInfo *t)
+{
+ /* clear any prior constraint flags */
+ t->con.mode &= ~CON_AXIS0;
+ t->con.mode &= ~CON_AXIS1;
+ t->con.mode &= ~CON_AXIS2;
+
+ /* constraint setting - depends on spacetype */
+ if (t->spacetype == SPACE_VIEW3D) {
+ /* 3d-view */
+ setNearestAxis3d(t);
+ }
+ else {
+ /* assume that this means a 2D-Editor */
+ setNearestAxis2d(t);
+ }
+
getConstraintMatrix(t);
}
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index a115a0d207a..45e75bff39b 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -58,8 +58,10 @@
#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_modifier_types.h"
+#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -70,10 +72,12 @@
#include "DNA_property_types.h"
#include "DNA_vfont_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_listBase.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_blender.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_constraint.h"
#include "BKE_depsgraph.h"
@@ -84,12 +88,16 @@
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_lattice.h"
+#include "BKE_key.h"
+#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"
+#include "BKE_bmesh.h"
#include "BIF_editaction.h"
#include "BIF_editview.h"
@@ -97,21 +105,27 @@
#include "BIF_editconstraint.h"
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
+#include "BIF_editnla.h"
#include "BIF_editsima.h"
+#include "BIF_editparticle.h"
#include "BIF_gl.h"
#include "BIF_poseobject.h"
#include "BIF_meshtools.h"
#include "BIF_mywindow.h"
#include "BIF_resources.h"
+#include "BIF_retopo.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BSE_view.h"
+#include "BSE_drawipo.h"
#include "BSE_edit.h"
#include "BSE_editipo.h"
#include "BSE_editipo_types.h"
+#include "BSE_editaction_types.h"
+#include "BDR_drawaction.h" // list of keyframes in action
#include "BDR_editobject.h" // reset_slowparents()
#include "BDR_unwrapper.h"
@@ -119,6 +133,8 @@
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+#include "editmesh.h"
+
#include "blendef.h"
#include "mydevice.h"
@@ -128,6 +144,8 @@ extern ListBase editelems;
#include "transform.h"
+/* local function prototype - for Object/Bone Constraints */
+static short constraints_list_needinv(TransInfo *t, ListBase *list);
/* ************************** Functions *************************** */
@@ -370,8 +388,14 @@ static void createTransEdge(TransInfo *t) {
td->ext = NULL;
td->tdi = NULL;
- td->val = &(eed->crease);
- td->ival = eed->crease;
+ if (t->mode == TFM_BWEIGHT) {
+ td->val = &(eed->bweight);
+ td->ival = eed->bweight;
+ }
+ else {
+ td->val = &(eed->crease);
+ td->ival = eed->crease;
+ }
td++;
}
@@ -465,6 +489,10 @@ static short apply_targetless_ik(Object *ob)
Mat4MulMat4(tmat, offs_bone, rmat);
}
+ else if(parchan->bone->flag & BONE_NO_SCALE) {
+ Mat4MulMat4(tmat, offs_bone, parchan->parent->pose_mat);
+ Mat4Ortho(tmat);
+ }
else
Mat4MulMat4(tmat, offs_bone, parchan->parent->pose_mat);
@@ -511,6 +539,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
{
Bone *bone= pchan->bone;
float pmat[3][3], omat[3][3];
+ float cmat[3][3], tmat[3][3];
float vec[3];
VECCOPY(vec, pchan->pose_mat[3]);
@@ -518,6 +547,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
td->ob = ob;
td->flag= TD_SELECTED|TD_USEQUAT;
+ if(bone->flag & BONE_HINGE_CHILD_TRANSFORM)
+ td->flag |= TD_NOCENTER;
td->protectflag= pchan->protectflag;
td->loc = pchan->loc;
@@ -530,21 +561,34 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
QUATCOPY(td->ext->iquat, pchan->quat);
VECCOPY(td->ext->isize, pchan->size);
- /* proper way to get the parent transform + own transform */
+ /* proper way to get parent transform + own transform + constraints transform */
Mat3CpyMat4(omat, ob->obmat);
- if(pchan->parent) {
- if(pchan->bone->flag & BONE_HINGE)
- Mat3CpyMat4(pmat, pchan->parent->bone->arm_mat);
- else
+
+ if(pchan->parent) {
+ if(pchan->bone->flag & BONE_HINGE)
+ Mat3CpyMat4(pmat, pchan->parent->bone->arm_mat);
+ else
Mat3CpyMat4(pmat, pchan->parent->pose_mat);
-
- Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0); // dang mulserie swaps args
+
+ if (constraints_list_needinv(t, &pchan->constraints)) {
+ Mat3CpyMat4(tmat, pchan->constinv);
+ Mat3Inv(cmat, tmat);
+ Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, cmat, 0,0,0,0); // dang mulserie swaps args
+ }
+ else
+ Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0); // dang mulserie swaps args
}
else {
- Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat); // huh, transposed?
+ if (constraints_list_needinv(t, &pchan->constraints)) {
+ Mat3CpyMat4(tmat, pchan->constinv);
+ Mat3Inv(cmat, tmat);
+ Mat3MulSerie(td->mtx, pchan->bone->bone_mat, omat, cmat, 0,0,0,0,0); // dang mulserie swaps args
+ }
+ else
+ Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat); // Mat3MulMat3 has swapped args!
}
- Mat3Inv (td->smtx, td->mtx);
+ Mat3Inv(td->smtx, td->mtx);
/* for axismat we use bone's own transform */
Mat3CpyMat4(pmat, pchan->pose_mat);
@@ -586,6 +630,9 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
Mat3Inv (td->smtx, td->mtx);
}
}
+
+ /* store reference to first constraint */
+ td->con= pchan->constraints.first;
}
static void bone_children_clear_transflag(ListBase *lb)
@@ -593,7 +640,11 @@ static void bone_children_clear_transflag(ListBase *lb)
Bone *bone= lb->first;
for(;bone;bone= bone->next) {
- bone->flag &= ~BONE_TRANSFORM;
+ if((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED))
+ bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
+ else
+ bone->flag &= ~BONE_TRANSFORM;
+
bone_children_clear_transflag(&bone->childbase);
}
}
@@ -604,6 +655,7 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
bArmature *arm= ob->data;
bPoseChannel *pchan;
Bone *bone;
+ int hastranslation;
t->total= 0;
@@ -614,6 +666,8 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
bone->flag |= BONE_TRANSFORM;
else
bone->flag &= ~BONE_TRANSFORM;
+
+ bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
}
}
@@ -627,21 +681,87 @@ static void set_pose_transflags(TransInfo *t, Object *ob)
}
}
/* now count, and check if we have autoIK or have to switch from translate to rotate */
+ hastranslation= 0;
+
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
if(bone->flag & BONE_TRANSFORM) {
+
t->total++;
if(t->mode==TFM_TRANSLATION) {
if( has_targetless_ik(pchan)==NULL ) {
- if(pchan->parent && (pchan->bone->flag & BONE_CONNECTED))
- t->mode= TFM_ROTATION;
- else if((pchan->protectflag & OB_LOCK_LOC)==OB_LOCK_LOC)
- t->mode= TFM_ROTATION;
+ if(pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) {
+ if(pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM)
+ hastranslation= 1;
+ }
+ else if((pchan->protectflag & OB_LOCK_LOC)!=OB_LOCK_LOC)
+ hastranslation= 1;
}
+ else
+ hastranslation= 1;
}
}
}
+
+ /* if there are no translatable bones, do rotation */
+ if(t->mode==TFM_TRANSLATION && !hastranslation)
+ t->mode= TFM_ROTATION;
+}
+
+
+/* -------- Auto-IK ---------- */
+
+/* adjust pose-channel's auto-ik chainlen */
+static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen)
+{
+ bConstraint *con;
+
+ /* don't bother to search if no valid constraints */
+ if ((pchan->constflag & (PCHAN_HAS_IK|PCHAN_HAS_TARGET))==0)
+ return;
+
+ /* check if pchan has ik-constraint */
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data= con->data;
+
+ /* only accept if a temporary one (for auto-ik) */
+ if (data->flag & CONSTRAINT_IK_TEMP) {
+ /* chainlen is new chainlen, but is limited by maximum chainlen */
+ if ((chainlen==0) || (chainlen > data->max_rootbone))
+ data->rootbone= data->max_rootbone;
+ else
+ data->rootbone= chainlen;
+ }
+ }
+ }
+}
+
+/* change the chain-length of auto-ik */
+void transform_autoik_update (TransInfo *t, short mode)
+{
+ short *chainlen= &G.scene->toolsettings->autoik_chainlen;
+ bPoseChannel *pchan;
+
+ /* mode determines what change to apply to chainlen */
+ if (mode == 1) {
+ /* mode=1 is from WHEELMOUSEDOWN... increases len */
+ (*chainlen)++;
+ }
+ else if (mode == -1) {
+ /* mode==-1 is from WHEELMOUSEUP... decreases len */
+ if (*chainlen > 0) (*chainlen)--;
+ }
+
+ /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
+ if (ELEM(NULL, t->poseobj, t->poseobj->pose))
+ return;
+
+ /* apply to all pose-channels */
+ for (pchan=t->poseobj->pose->chanbase.first; pchan; pchan=pchan->next) {
+ pchan_autoik_adjust(pchan, *chainlen);
+ }
}
/* frees temporal IKs */
@@ -651,11 +771,15 @@ static void pose_grab_with_ik_clear(Object *ob)
bPoseChannel *pchan;
bConstraint *con;
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- for(con= pchan->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ /* clear all temporary lock flags */
+ pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP|BONE_IK_NO_YDOF_TEMP|BONE_IK_NO_ZDOF_TEMP);
+
+ /* remove all temporary IK-constraints added */
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
data= con->data;
- if(data->flag & CONSTRAINT_IK_TEMP) {
+ if (data->flag & CONSTRAINT_IK_TEMP) {
BLI_remlink(&pchan->constraints, con);
MEM_freeN(con->data);
MEM_freeN(con);
@@ -667,27 +791,28 @@ static void pose_grab_with_ik_clear(Object *ob)
}
}
-/* adds the IK to pchan */
-static void pose_grab_with_ik_add(bPoseChannel *pchan)
+/* adds the IK to pchan - returns if added */
+static short pose_grab_with_ik_add(bPoseChannel *pchan)
{
bKinematicConstraint *data;
bConstraint *con;
- if (pchan == NULL) { // Sanity check
- return;
- }
+ /* Sanity check */
+ if (pchan == NULL)
+ return 0;
- /* rule: not if there's already an IK on this channel */
- for(con= pchan->constraints.first; con; con= con->next)
- if(con->type==CONSTRAINT_TYPE_KINEMATIC)
+ /* Rule: not if there's already an IK on this channel */
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (con->type==CONSTRAINT_TYPE_KINEMATIC)
break;
+ }
- if(con) {
+ if (con) {
/* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
data= has_targetless_ik(pchan);
- if(data)
+ if (data)
data->flag |= CONSTRAINT_IK_AUTO;
- return;
+ return 0;
}
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
@@ -699,68 +824,93 @@ static void pose_grab_with_ik_add(bPoseChannel *pchan)
data->rootbone= 1;
/* we include only a connected chain */
- while(pchan && (pchan->bone->flag & BONE_CONNECTED)) {
+ while ((pchan) && (pchan->bone->flag & BONE_CONNECTED)) {
+ /* here, we set ik-settings for bone from pchan->protectflag */
+ if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
+ if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
+ if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
+
+ /* now we count this pchan as being included */
data->rootbone++;
pchan= pchan->parent;
}
+
+ /* make a copy of maximum chain-length */
+ data->max_rootbone= data->rootbone;
+
+ return 1;
}
-/* bone is a canditate to get IK, but we don't do it if it has children connected */
-static void pose_grab_with_ik_children(bPose *pose, Bone *bone)
+/* bone is a candidate to get IK, but we don't do it if it has children connected */
+static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
{
Bone *bonec;
- int wentdeeper= 0;
+ short wentdeeper=0, added=0;
/* go deeper if children & children are connected */
- for(bonec= bone->childbase.first; bonec; bonec= bonec->next) {
- if(bonec->flag & BONE_CONNECTED) {
+ for (bonec= bone->childbase.first; bonec; bonec= bonec->next) {
+ if (bonec->flag & BONE_CONNECTED) {
wentdeeper= 1;
- pose_grab_with_ik_children(pose, bonec);
+ added+= pose_grab_with_ik_children(pose, bonec);
}
}
- if(wentdeeper==0) {
+ if (wentdeeper==0) {
bPoseChannel *pchan= get_pose_channel(pose, bone->name);
- if(pchan)
- pose_grab_with_ik_add(pchan);
+ if (pchan)
+ added+= pose_grab_with_ik_add(pchan);
}
+
+ return added;
}
/* main call which adds temporal IK chains */
-static void pose_grab_with_ik(Object *ob)
+static short pose_grab_with_ik(Object *ob)
{
bArmature *arm;
- bPoseChannel *pchan, *pchansel= NULL;
+ bPoseChannel *pchan, *parent;
+ Bone *bonec;
+ short tot_ik= 0;
- if(ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
- return;
+ if ((ob==NULL) || (ob->pose==NULL) || (ob->flag & OB_POSEMODE)==0)
+ return 0;
arm = ob->data;
- /* rule: only one Bone */
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(pchan->bone->layer & arm->layer) {
- if(pchan->bone->flag & BONE_SELECTED) {
- if(pchansel)
- break;
- pchansel= pchan;
+ /* Rule: allow multiple Bones (but they must be selected, and only one ik-solver per chain should get added) */
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if (pchan->bone->layer & arm->layer) {
+ if (pchan->bone->flag & BONE_SELECTED) {
+ /* Rule: no IK for solitatry (unconnected) bones */
+ for (bonec=pchan->bone->childbase.first; bonec; bonec=bonec->next) {
+ if (bonec->flag & BONE_CONNECTED) {
+ break;
+ }
+ }
+ if ((pchan->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL))
+ continue;
+
+ /* rule: if selected Bone is not a root bone, it gets a temporal IK */
+ if (pchan->parent) {
+ /* only adds if there's no IK yet (and no parent bone was selected) */
+ for (parent= pchan->parent; parent; parent= parent->parent) {
+ if (parent->bone->flag & BONE_SELECTED)
+ break;
+ }
+ if (parent == NULL)
+ tot_ik += pose_grab_with_ik_add(pchan);
+ }
+ else {
+ /* rule: go over the children and add IK to the tips */
+ tot_ik += pose_grab_with_ik_children(ob->pose, pchan->bone);
+ }
}
}
}
- if(pchan || pchansel==NULL) return;
- /* rule: if selected Bone is not a root bone, it gets a temporal IK */
- if(pchansel->parent) {
- /* only adds if there's no IK yet */
- pose_grab_with_ik_add(pchansel);
- }
- else {
- /* rule: go over the children and add IK to the tips */
- pose_grab_with_ik_children(ob->pose, pchansel->bone);
- }
+ return (tot_ik) ? 1 : 0;
}
-
/* only called with pose mode active object now */
static void createTransPose(TransInfo *t, Object *ob)
{
@@ -768,6 +918,7 @@ static void createTransPose(TransInfo *t, Object *ob)
bPoseChannel *pchan;
TransData *td;
TransDataExtension *tdx;
+ short ik_on= 0;
int i;
t->total= 0;
@@ -785,8 +936,10 @@ static void createTransPose(TransInfo *t, Object *ob)
if (!(ob->lay & G.vd->lay)) return;
/* do we need to add temporal IK chains? */
- if((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION)
- pose_grab_with_ik(ob);
+ if ((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION) {
+ ik_on= pose_grab_with_ik(ob);
+ if (ik_on) t->flag |= T_AUTOIK;
+ }
/* set flags and count total (warning, can change transform to rotate) */
set_pose_transflags(t, ob);
@@ -820,6 +973,8 @@ static void createTransPose(TransInfo *t, Object *ob)
if(td != (t->data+t->total)) printf("Bone selection count error\n");
+ /* initialise initial auto=ik chainlen's? */
+ if (ik_on) transform_autoik_update(t, 0);
}
/* ********************* armature ************** */
@@ -1113,10 +1268,15 @@ static void createTransCurveVerts(TransInfo *t)
if((nu->type & 7)==CU_BEZIER) {
for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
if(bezt->hide==0) {
- if(bezt->f1 & 1) countsel++;
- if(bezt->f2 & 1) countsel++;
- if(bezt->f3 & 1) countsel++;
- if(propmode) count+= 3;
+ if (G.f & G_HIDDENHANDLES) {
+ if(bezt->f2 & SELECT) countsel+=3;
+ if(propmode) count+= 3;
+ } else {
+ if(bezt->f1 & SELECT) countsel++;
+ if(bezt->f2 & SELECT) countsel++;
+ if(bezt->f3 & SELECT) countsel++;
+ if(propmode) count+= 3;
+ }
}
}
}
@@ -1124,7 +1284,7 @@ static void createTransCurveVerts(TransInfo *t)
for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
if(bp->hide==0) {
if(propmode) count++;
- if(bp->f1 & 1) countsel++;
+ if(bp->f1 & SELECT) countsel++;
}
}
}
@@ -1146,12 +1306,21 @@ static void createTransCurveVerts(TransInfo *t)
head = tail = td;
for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
if(bezt->hide==0) {
- if(propmode || (bezt->f1 & 1)) {
+
+ if( propmode ||
+ ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
+ ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
+ ) {
VECCOPY(td->iloc, bezt->vec[0]);
td->loc= bezt->vec[0];
VECCOPY(td->center, bezt->vec[1]);
- if(bezt->f1 & 1) td->flag= TD_SELECTED;
- else td->flag= 0;
+ if (G.f & G_HIDDENHANDLES) {
+ if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
+ else td->flag= 0;
+ } else {
+ if(bezt->f1 & SELECT) td->flag= TD_SELECTED;
+ else td->flag= 0;
+ }
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
@@ -1163,22 +1332,25 @@ static void createTransCurveVerts(TransInfo *t)
count++;
tail++;
}
- /* THIS IS THE CV, the other two are handles */
- if(propmode || (bezt->f2 & 1)) {
+
+ /* This is the Curve Point, the other two are handles */
+ if(propmode || (bezt->f2 & SELECT)) {
VECCOPY(td->iloc, bezt->vec[1]);
td->loc= bezt->vec[1];
VECCOPY(td->center, td->loc);
- if(bezt->f2 & 1) td->flag= TD_SELECTED;
+ if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
td->tdi = NULL;
- if (t->mode==TFM_CURVE_SHRINKFATTEN) {
+ if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
td->val = &(bezt->radius);
td->ival = bezt->radius;
- } else {
+ } else if (t->mode==TFM_TILT) {
td->val = &(bezt->alfa);
td->ival = bezt->alfa;
+ } else {
+ td->val = NULL;
}
Mat3CpyMat3(td->smtx, smtx);
@@ -1188,12 +1360,20 @@ static void createTransCurveVerts(TransInfo *t)
count++;
tail++;
}
- if(propmode || (bezt->f3 & 1)) {
+ if( propmode ||
+ ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
+ ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
+ ) {
VECCOPY(td->iloc, bezt->vec[2]);
td->loc= bezt->vec[2];
VECCOPY(td->center, bezt->vec[1]);
- if(bezt->f3 & 1) td->flag= TD_SELECTED;
- else td->flag= 0;
+ if (G.f & G_HIDDENHANDLES) {
+ if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
+ else td->flag= 0;
+ } else {
+ if(bezt->f3 & SELECT) td->flag= TD_SELECTED;
+ else td->flag= 0;
+ }
td->ext = NULL;
td->tdi = NULL;
td->val = NULL;
@@ -1219,16 +1399,16 @@ static void createTransCurveVerts(TransInfo *t)
head = tail = td;
for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
if(bp->hide==0) {
- if(propmode || (bp->f1 & 1)) {
+ if(propmode || (bp->f1 & SELECT)) {
VECCOPY(td->iloc, bp->vec);
td->loc= bp->vec;
VECCOPY(td->center, td->loc);
- if(bp->f1 & 1) td->flag= TD_SELECTED;
+ if(bp->f1 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
td->ext = NULL;
td->tdi = NULL;
- if (t->mode==TFM_CURVE_SHRINKFATTEN) {
+ if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) {
td->val = &(bp->radius);
td->ival = bp->radius;
} else {
@@ -1270,7 +1450,7 @@ static void createTransLatticeVerts(TransInfo *t)
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
if(bp->hide==0) {
- if(bp->f1 & 1) countsel++;
+ if(bp->f1 & SELECT) countsel++;
if(propmode) count++;
}
bp++;
@@ -1290,12 +1470,12 @@ static void createTransLatticeVerts(TransInfo *t)
bp= editLatt->def;
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
- if(propmode || (bp->f1 & 1)) {
+ if(propmode || (bp->f1 & SELECT)) {
if(bp->hide==0) {
VECCOPY(td->iloc, bp->vec);
td->loc= bp->vec;
VECCOPY(td->center, td->loc);
- if(bp->f1 & 1) td->flag= TD_SELECTED;
+ if(bp->f1 & SELECT) td->flag= TD_SELECTED;
else td->flag= 0;
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
@@ -1312,6 +1492,160 @@ static void createTransLatticeVerts(TransInfo *t)
}
}
+/* ******************* particle edit **************** */
+static void createTransParticleVerts(TransInfo *t)
+{
+ TransData *td = NULL;
+ TransDataExtension *tx;
+ Base *base = BASACT;
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleSystemModifierData *psmd = NULL;
+ ParticleEditSettings *pset = PE_settings();
+ ParticleData *pa = NULL;
+ ParticleEdit *edit;
+ ParticleEditKey *key;
+ float mat[4][4];
+ int i,k, totpart, transformparticle;
+ int count = 0, hasselected = 0;
+ int propmode = t->flag & T_PROP_EDIT;
+
+ if(psys==NULL || G.scene->selectmode==SCE_SELECT_PATH) return;
+
+ psmd = psys_get_modifier(ob,psys);
+
+ edit = psys->edit;
+ totpart = psys->totpart;
+ base->flag |= BA_HAS_RECALC_DATA;
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ pa->flag &= ~PARS_TRANSFORM;
+ transformparticle= 0;
+
+ if((pa->flag & PARS_HIDE)==0) {
+ for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
+ if((key->flag&PEK_HIDE)==0) {
+ if(key->flag&PEK_SELECT) {
+ hasselected= 1;
+ transformparticle= 1;
+ }
+ else if(propmode)
+ transformparticle= 1;
+ }
+ }
+ }
+
+ if(transformparticle) {
+ count += pa->totkey;
+ pa->flag |= PARS_TRANSFORM;
+ }
+ }
+
+ /* note: in prop mode we need at least 1 selected */
+ if (hasselected==0) return;
+
+ t->total = count;
+ td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)");
+
+ if(t->mode == TFM_BAKE_TIME)
+ tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension");
+ else
+ tx = t->ext = NULL;
+
+ Mat4One(mat);
+
+ Mat4Invert(ob->imat,ob->obmat);
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ TransData *head, *tail;
+ head = tail = td;
+
+ if(!(pa->flag & PARS_TRANSFORM)) continue;
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
+
+ for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
+ VECCOPY(key->world_co, key->co);
+ Mat4MulVecfl(mat, key->world_co);
+ td->loc = key->world_co;
+
+ VECCOPY(td->iloc, td->loc);
+ VECCOPY(td->center, td->loc);
+
+ if(key->flag & PEK_SELECT)
+ td->flag |= TD_SELECTED;
+ else if(!propmode)
+ td->flag |= TD_SKIP;
+
+ Mat3One(td->mtx);
+ Mat3One(td->smtx);
+
+ /* don't allow moving roots */
+ if(k==0 && pset->flag & PE_LOCK_FIRST)
+ td->protectflag |= OB_LOCK_LOC;
+
+ td->ob = ob;
+ td->ext = tx;
+ td->tdi = NULL;
+ if(t->mode == TFM_BAKE_TIME) {
+ td->val = key->time;
+ td->ival = *(key->time);
+ /* abuse size and quat for min/max values */
+ td->flag |= TD_NO_EXT;
+ if(k==0) tx->size = 0;
+ else tx->size = (key - 1)->time;
+
+ if(k == pa->totkey - 1) tx->quat = 0;
+ else tx->quat = (key + 1)->time;
+ }
+
+ td++;
+ if(tx)
+ tx++;
+ tail++;
+ }
+ if (propmode && head != tail)
+ calc_distanceCurveVerts(head, tail - 1);
+ }
+}
+
+void flushTransParticles(TransInfo *t)
+{
+ Object *ob = OBACT;
+ ParticleSystem *psys = PE_get_current(ob);
+ ParticleSystemModifierData *psmd;
+ ParticleData *pa;
+ ParticleEditKey *key;
+ TransData *td;
+ float mat[4][4], imat[4][4], co[3];
+ int i, k, propmode = t->flag & T_PROP_EDIT;
+
+ psmd = psys_get_modifier(ob, psys);
+
+ /* we do transform in world space, so flush world space position
+ * back to particle local space */
+ td= t->data;
+ for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++, td++) {
+ if(!(pa->flag & PARS_TRANSFORM)) continue;
+
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
+ Mat4Invert(imat,mat);
+
+ for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
+ VECCOPY(co, key->world_co);
+ Mat4MulVecfl(imat, co);
+
+ /* optimization for proportional edit */
+ if(!propmode || !FloatCompare(key->co, co, 0.0001f)) {
+ VECCOPY(key->co, co);
+ pa->flag |= PARS_EDIT_RECALC;
+ }
+ }
+ }
+
+ PE_update_object(OBACT, 1);
+}
+
/* ********************* mesh ****************** */
/* proportional distance based on connectivity */
@@ -1445,9 +1779,14 @@ static void get_face_center(float *cent, EditVert *eve)
}
}
+//way to overwrite what data is edited with transform
+//static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
static void VertsToTransData(TransData *td, EditVert *eve)
{
td->flag = 0;
+ //if(key)
+ // td->loc = key->co;
+ //else
td->loc = eve->co;
VECCOPY(td->center, td->loc);
@@ -1468,6 +1807,10 @@ static void VertsToTransData(TransData *td, EditVert *eve)
td->tdi = NULL;
td->val = NULL;
td->tdmir= NULL;
+ if (BIF_GetTransInfo()->mode == TFM_BWEIGHT) {
+ td->val = &(eve->bweight);
+ td->ival = eve->bweight;
+ }
#ifdef WITH_VERSE
if(eve->vvert) {
@@ -1489,43 +1832,33 @@ static void make_vertexcos__mapFunc(void *userData, int index, float *co, float
VECCOPY(vec, co);
}
-/* hurmf, copy from buttons_editing.c, i have to sort this out what it means... */
-static void modifiers_setOnCage(void *ob_v, void *md_v)
+static int modifiers_disable_subsurf_temporary(Object *ob)
{
- Object *ob = ob_v;
ModifierData *md;
+ int disabled = 0;
- int i, cageIndex = modifiers_getCageIndex(ob, NULL );
+ for(md=ob->modifiers.first; md; md=md->next)
+ if(md->type==eModifierType_Subsurf)
+ if(md->mode & eModifierMode_OnCage) {
+ md->mode ^= eModifierMode_DisableTemporary;
+ disabled= 1;
+ }
- for( i = 0, md=ob->modifiers.first; md; ++i, md=md->next )
- if( md == md_v ) {
- if( i >= cageIndex )
- md->mode ^= eModifierMode_OnCage;
- break;
- }
+ return disabled;
}
-
/* disable subsurf temporal, get mapped cos, and enable it */
static float *get_crazy_mapped_editverts(void)
{
DerivedMesh *dm;
- ModifierData *md;
float *vertexcos;
- int i;
-
- for( i = 0, md=G.obedit->modifiers.first; md; ++i, md=md->next ) {
- if(md->type==eModifierType_Subsurf)
- if(md->mode & eModifierMode_OnCage)
- break;
- }
- if(md) {
- /* this call disables subsurf and enables the underlying modifier to deform, apparently */
- modifiers_setOnCage(G.obedit, md);
- /* make it all over */
+
+ /* disable subsurf temporal, get mapped cos, and enable it */
+ if(modifiers_disable_subsurf_temporary(G.obedit)) {
+ /* need to make new derivemesh */
makeDerivedMesh(G.obedit, CD_MASK_BAREMESH);
}
-
+
/* now get the cage */
dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
@@ -1534,10 +1867,8 @@ static float *get_crazy_mapped_editverts(void)
dm->release(dm);
- if(md) {
- /* set back the flag, no new cage needs to be built, transform does it */
- modifiers_setOnCage(G.obedit, md);
- }
+ /* set back the flag, no new cage needs to be built, transform does it */
+ modifiers_disable_subsurf_temporary(G.obedit);
return vertexcos;
}
@@ -1560,17 +1891,17 @@ static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3,
}
#undef TAN_MAKE_VEC
-static void set_crazyspace_quats(float *mappedcos, float *quats)
+static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
{
EditMesh *em = G.editMesh;
EditVert *eve, *prev;
EditFace *efa;
- float *v1, *v2, *v3, *v4;
+ float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
long index= 0;
/* two abused locations in vertices */
for(eve= em->verts.first; eve; eve= eve->next, index++) {
- eve->tmp.fp = NULL;
+ eve->tmp.p = NULL;
eve->prev= (EditVert *)index;
}
@@ -1578,44 +1909,49 @@ static void set_crazyspace_quats(float *mappedcos, float *quats)
for(efa= em->faces.first; efa; efa= efa->next) {
/* retrieve mapped coordinates */
- v1= mappedcos + 3*( (long)(efa->v1->prev) );
- v2= mappedcos + 3*( (long)(efa->v2->prev) );
- v3= mappedcos + 3*( (long)(efa->v3->prev) );
-
- if(efa->v2->tmp.fp==NULL && efa->v2->f1) {
- set_crazy_vertex_quat(quats, efa->v2->co, efa->v3->co, efa->v1->co, v2, v3, v1);
- efa->v2->tmp.fp= quats;
+ v1= mappedcos + 3*(long)(efa->v1->prev);
+ v2= mappedcos + 3*(long)(efa->v2->prev);
+ v3= mappedcos + 3*(long)(efa->v3->prev);
+
+ co1= (origcos)? origcos + 3*(long)(efa->v1->prev): efa->v1->co;
+ co2= (origcos)? origcos + 3*(long)(efa->v2->prev): efa->v2->co;
+ co3= (origcos)? origcos + 3*(long)(efa->v3->prev): efa->v3->co;
+
+ if(efa->v2->tmp.p==NULL && efa->v2->f1) {
+ set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
+ efa->v2->tmp.p= (void*)quats;
quats+= 4;
}
if(efa->v4) {
- v4= mappedcos + 3*( (long)(efa->v4->prev) );
-
- if(efa->v1->tmp.fp==NULL && efa->v1->f1) {
- set_crazy_vertex_quat(quats, efa->v1->co, efa->v2->co, efa->v4->co, v1, v2, v4);
- efa->v1->tmp.fp= quats;
+ v4= mappedcos + 3*(long)(efa->v4->prev);
+ co4= (origcos)? origcos + 3*(long)(efa->v4->prev): efa->v4->co;
+
+ if(efa->v1->tmp.p==NULL && efa->v1->f1) {
+ set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
+ efa->v1->tmp.p= (void*)quats;
quats+= 4;
}
- if(efa->v3->tmp.fp==NULL && efa->v3->f1) {
- set_crazy_vertex_quat(quats, efa->v3->co, efa->v4->co, efa->v2->co, v3, v4, v2);
- efa->v3->tmp.fp= quats;
+ if(efa->v3->tmp.p==NULL && efa->v3->f1) {
+ set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
+ efa->v3->tmp.p= (void*)quats;
quats+= 4;
}
- if(efa->v4->tmp.fp==NULL && efa->v4->f1) {
- set_crazy_vertex_quat(quats, efa->v4->co, efa->v1->co, efa->v3->co, v4, v1, v3);
- efa->v4->tmp.fp= quats;
+ if(efa->v4->tmp.p==NULL && efa->v4->f1) {
+ set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
+ efa->v4->tmp.p= (void*)quats;
quats+= 4;
}
}
else {
- if(efa->v1->tmp.fp==NULL && efa->v1->f1) {
- set_crazy_vertex_quat(quats, efa->v1->co, efa->v2->co, efa->v3->co, v1, v2, v3);
- efa->v1->tmp.fp= quats;
+ if(efa->v1->tmp.p==NULL && efa->v1->f1) {
+ set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
+ efa->v1->tmp.p= (void*)quats;
quats+= 4;
}
- if(efa->v3->tmp.fp==NULL && efa->v3->f1) {
- set_crazy_vertex_quat(quats, efa->v3->co, efa->v1->co, efa->v2->co, v3, v1, v2);
- efa->v3->tmp.fp= quats;
+ if(efa->v3->tmp.p==NULL && efa->v3->f1) {
+ set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
+ efa->v3->tmp.p= (void*)quats;
quats+= 4;
}
}
@@ -1627,17 +1963,48 @@ static void set_crazyspace_quats(float *mappedcos, float *quats)
}
+void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
+ BME_Vert *v;
+ BME_TransData *vtd;
+ TransData *tob;
+ int i;
+
+ tob = t->data = MEM_callocN(td->len*sizeof(TransData), "TransObData(Bevel tool)");
+
+ for (i=0,v=bm->verts.first;v;v=v->next) {
+ if ( (vtd = BME_get_transdata(td,v)) ) {
+ tob->loc = vtd->loc;
+ tob->val = &vtd->factor;
+ VECCOPY(tob->iloc,vtd->co);
+ VECCOPY(tob->center,vtd->org);
+ VECCOPY(tob->axismtx[0],vtd->vec);
+ tob->axismtx[1][0] = vtd->max ? *vtd->max : 0;
+ tob++;
+ i++;
+ }
+ }
+ /* since td is a memarena, it can hold more transdata than actual elements
+ * (i.e. we can't depend on td->len to determine the number of actual elements) */
+ t->total = i;
+}
+
static void createTransEditVerts(TransInfo *t)
{
TransData *tob = NULL;
EditMesh *em = G.editMesh;
EditVert *eve;
EditVert **nears = NULL;
+ EditVert *eve_act = NULL;
float *vectors = NULL, *mappedcos = NULL, *quats= NULL;
- float mtx[3][3], smtx[3][3];
- int count=0, countsel=0;
+ float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
+ int count=0, countsel=0, a, totleft;
int propmode = t->flag & T_PROP_EDIT;
- int mirror= (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR);
+ int mirror = 0;
+
+ if ((t->context & CTX_NO_MIRROR) == 0 || (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+ {
+ mirror = 1;
+ }
// transform now requires awareness for select mode, so we tag the f1 flags in verts
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
@@ -1678,6 +2045,15 @@ static void createTransEditVerts(TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel==0) return;
+ /* check active */
+ if (G.editMesh->selected.last) {
+ EditSelection *ese = G.editMesh->selected.last;
+ if ( ese->type == EDITVERT ) {
+ eve_act = (EditVert *)ese->data;
+ }
+ }
+
+
if(propmode) {
t->total = count;
@@ -1697,10 +2073,23 @@ static void createTransEditVerts(TransInfo *t)
if(propmode==0) {
if(modifiers_getCageIndex(G.obedit, NULL)>=0) {
if(modifiers_isDeformed(G.obedit)) {
- /* disable subsurf temporal, get mapped cos, and enable it */
- mappedcos= get_crazy_mapped_editverts();
- quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
- set_crazyspace_quats(mappedcos, quats);
+ /* check if we can use deform matrices for modifier from the
+ start up to stack, they are more accurate than quats */
+ totleft= editmesh_get_first_deform_matrices(&defmats, &defcos);
+
+ /* if we still have more modifiers, also do crazyspace
+ correction with quats, relative to the coordinates after
+ the modifiers that support deform matrices (defcos) */
+ if(totleft > 0) {
+ mappedcos= get_crazy_mapped_editverts();
+ quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
+ set_crazyspace_quats((float*)defcos, mappedcos, quats);
+ if(mappedcos)
+ MEM_freeN(mappedcos);
+ }
+
+ if(defcos)
+ MEM_freeN(defcos);
}
}
}
@@ -1716,12 +2105,17 @@ static void createTransEditVerts(TransInfo *t)
}
}
- for (eve=em->verts.first; eve; eve=eve->next) {
+ for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
if(eve->h==0) {
if(propmode || eve->f1) {
VertsToTransData(tob, eve);
-
+
+ /* selected */
if(eve->f1) tob->flag |= TD_SELECTED;
+
+ /* active */
+ if(eve == eve_act) tob->flag |= TD_ACTIVE;
+
if(propmode) {
if (eve->f2) {
float vec[3];
@@ -1736,11 +2130,22 @@ static void createTransEditVerts(TransInfo *t)
}
/* CrazySpace */
- if(quats && eve->tmp.fp) {
+ if(defmats || (quats && eve->tmp.p)) {
float mat[3][3], imat[3][3], qmat[3][3];
- QuatToMat3(eve->tmp.fp, qmat);
- Mat3MulMat3(mat, mtx, qmat);
+ /* use both or either quat and defmat correction */
+ if(quats && eve->tmp.f) {
+ QuatToMat3(eve->tmp.p, qmat);
+
+ if(defmats)
+ Mat3MulSerie(mat, mtx, qmat, defmats[a],
+ NULL, NULL, NULL, NULL, NULL);
+ else
+ Mat3MulMat3(mat, mtx, qmat);
+ }
+ else
+ Mat3MulMat3(mat, mtx, defmats[a]);
+
Mat3Inv(imat, mat);
Mat3CpyMat3(tob->smtx, imat);
@@ -1765,10 +2170,10 @@ static void createTransEditVerts(TransInfo *t)
MEM_freeN(nears);
}
/* crazy space free */
- if(mappedcos)
- MEM_freeN(mappedcos);
if(quats)
MEM_freeN(quats);
+ if(defmats)
+ MEM_freeN(defmats);
}
/* ********************* UV ****************** */
@@ -1813,26 +2218,25 @@ static void createTransUVs(TransInfo *t)
{
TransData *td = NULL;
TransData2D *td2d = NULL;
- Mesh *me;
- MFace *mf;
MTFace *tf;
- int a, count=0, countsel=0;
+ int count=0, countsel=0;
int propmode = t->flag & T_PROP_EDIT;
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+
if(is_uv_tface_editing_allowed()==0) return;
- me= get_mesh(OBACT);
/* count */
- tf= me->mtface;
- mf= me->mface;
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->v3 && mf->flag & ME_FACE_SEL) {
- if(tf->flag & TF_SEL1) countsel++;
- if(tf->flag & TF_SEL2) countsel++;
- if(tf->flag & TF_SEL3) countsel++;
- if(mf->v4 && (tf->flag & TF_SEL4)) countsel++;
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if (simaUVSel_Check(efa, tf, 0)) countsel++;
+ if (simaUVSel_Check(efa, tf, 1)) countsel++;
+ if (simaUVSel_Check(efa, tf, 2)) countsel++;
+ if (efa->v4 && simaUVSel_Check(efa, tf, 3)) countsel++;
if(propmode)
- count += (mf->v4)? 4: 3;
+ count += (efa->v4)? 4: 3;
}
}
@@ -1843,26 +2247,25 @@ static void createTransUVs(TransInfo *t)
t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
/* for each 2d uv coord a 3d vector is allocated, so that they can be
treated just as if they were 3d verts */
- t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
+ t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
if(G.sima->flag & SI_CLIP_UV)
t->flag |= T_CLIP_UV;
td= t->data;
td2d= t->data2d;
- tf= me->mtface;
- mf= me->mface;
- for(a=me->totface; a>0; a--, tf++, mf++) {
- if(mf->v3 && mf->flag & ME_FACE_SEL) {
- if(tf->flag & TF_SEL1 || propmode)
- UVsToTransData(td++, td2d++, tf->uv[0], (tf->flag & TF_SEL1));
- if(tf->flag & TF_SEL2 || propmode)
- UVsToTransData(td++, td2d++, tf->uv[1], (tf->flag & TF_SEL2));
- if(tf->flag & TF_SEL3 || propmode)
- UVsToTransData(td++, td2d++, tf->uv[2], (tf->flag & TF_SEL3));
+ for (efa= em->faces.first; efa; efa= efa->next) {
+ tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ if (simaFaceDraw_Check(efa, tf)) {
+ if(propmode || simaUVSel_Check(efa, tf, 0))
+ UVsToTransData(td++, td2d++, tf->uv[0], simaUVSel_Check(efa, tf, 0));
+ if(propmode || simaUVSel_Check(efa, tf, 1))
+ UVsToTransData(td++, td2d++, tf->uv[1], simaUVSel_Check(efa, tf, 1));
+ if(propmode || simaUVSel_Check(efa, tf, 2))
+ UVsToTransData(td++, td2d++, tf->uv[2], simaUVSel_Check(efa, tf, 2));
- if(mf->v4 && (tf->flag & TF_SEL4 || propmode))
- UVsToTransData(td++, td2d++, tf->uv[3], (tf->flag & TF_SEL4));
+ if(efa->v4 && (propmode || simaUVSel_Check(efa, tf, 3)))
+ UVsToTransData(td++, td2d++, tf->uv[3], simaUVSel_Check(efa, tf, 3));
}
}
@@ -1875,7 +2278,7 @@ void flushTransUVs(TransInfo *t)
TransData2D *td;
int a, width, height;
Object *ob= OBACT;
- Mesh *me= get_mesh(ob);
+ EditMesh *em = G.editMesh;
float aspx, aspy, invx, invy;
transform_aspect_ratio_tface_uv(&aspx, &aspy);
@@ -1896,7 +2299,7 @@ void flushTransUVs(TransInfo *t)
/* always call this, also for cancel (it transforms non-selected vertices...) */
if((G.sima->flag & SI_BE_SQUARE))
- be_square_tface_uv(me);
+ be_square_tface_uv(em);
/* this is overkill if G.sima->lock is not set, but still needed */
object_uvs_changed(ob);
@@ -1950,6 +2353,479 @@ int clipUVTransform(TransInfo *t, float *vec, int resize)
return (clipx || clipy);
}
+/* ********************* IPO EDITOR ************************* */
+
+/* for IPO Editor transform - but actual creation of transform structures is not performed here
+ * due to bad globals that would need to be imported specially for this
+ */
+static void createTransIpoData(TransInfo *t)
+{
+ /* in editipo.c due to some globals that are defined in that file... */
+ make_ipo_transdata(t);
+}
+
+/* this function is called on recalcData to apply the transforms applied
+ * to the transdata on to the actual keyframe data
+ */
+void flushTransIpoData(TransInfo *t)
+{
+ TransData2D *td;
+ int a;
+
+ /* flush to 2d vector from internally used 3d vector */
+ for (a=0, td= t->data2d; a<t->total; a++, td++) {
+ /* we need to unapply the nla-scaling from the time in some situations */
+ if (NLA_IPO_SCALED)
+ td->loc2d[0]= get_action_frame(OBACT, td->loc[0]);
+ else
+ td->loc2d[0]= td->loc[0];
+
+ /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */
+ if ((t->data[a].flag & TD_TIMEONLY)==0)
+ td->loc2d[1]= td->loc[1];
+ }
+}
+
+/* ********************* ACTION/NLA EDITOR ****************** */
+
+/* Called by special_aftertrans_update to make sure selected keyframes replace
+ * any other keyframes which may reside on that frame (that is not selected).
+ */
+static void posttrans_ipo_clean (Ipo *ipo)
+{
+ IpoCurve *icu;
+ int i;
+
+ /* delete any keyframes that occur on same frame as selected keyframe, but is not selected */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ float *selcache; /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */
+ int len, index; /* number of frames in cache, item index */
+
+ /* allocate memory for the cache */
+ // TODO: investigate using GHash for this instead?
+ if (icu->totvert == 0)
+ continue;
+ selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums");
+ len= 0;
+ index= 0;
+
+ /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting
+ * as there is no guarantee what order the keyframes are exactly, even though
+ * they have been sorted by time.
+ */
+
+ /* Loop 1: find selected keyframes */
+ for (i = 0; i < icu->totvert; i++) {
+ BezTriple *bezt= &icu->bezt[i];
+
+ if (BEZSELECTED(bezt)) {
+ selcache[index]= bezt->vec[1][0];
+ index++;
+ len++;
+ }
+ }
+
+ /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */
+ if (len) {
+ for (i = 0; i < icu->totvert; i++) {
+ BezTriple *bezt= &icu->bezt[i];
+
+ if (BEZSELECTED(bezt) == 0) {
+ /* check beztriple should be removed according to cache */
+ for (index= 0; index < len; index++) {
+ if (IS_EQ(bezt->vec[1][0], selcache[index])) {
+ delete_icu_key(icu, i, 0);
+ break;
+ }
+ else if (bezt->vec[1][0] > selcache[index])
+ break;
+ }
+ }
+ }
+
+ testhandles_ipocurve(icu);
+ }
+
+ /* free cache */
+ MEM_freeN(selcache);
+ }
+}
+
+/* Called by special_aftertrans_update to make sure selected keyframes replace
+ * any other keyframes which may reside on that frame (that is not selected).
+ * remake_action_ipos should have already been called
+ */
+static void posttrans_action_clean (bAction *act)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
+
+ /* loop through relevant data, removing keyframes from the ipo-blocks that were attached
+ * - all keyframes are converted in/out of global time
+ */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (NLA_ACTION_SCALED) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ posttrans_ipo_clean(ale->key_data);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
+ }
+ else
+ posttrans_ipo_clean(ale->key_data);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&act_data);
+}
+
+/* ----------------------------- */
+
+/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
+static short FrameOnMouseSide(char side, float frame, float cframe)
+{
+ /* both sides, so it doesn't matter */
+ if (side == 'B') return 1;
+
+ /* only on the named side */
+ if (side == 'R')
+ return (frame >= cframe) ? 1 : 0;
+ else
+ return (frame <= cframe) ? 1 : 0;
+}
+
+/* fully select selected beztriples, but only include if it's on the right side of cfra */
+static int count_ipo_keys(Ipo *ipo, char side, float cfra)
+{
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int i, count = 0;
+
+ if (ipo == NULL)
+ return count;
+
+ /* only include points that occur on the right side of cfra */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ /* fully select the other two keys */
+ bezt->f1 |= SELECT;
+ bezt->f3 |= SELECT;
+
+ /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
+ count += 3;
+ }
+ }
+ }
+
+ return count;
+}
+
+/* This function assigns the information to transdata */
+static void TimeToTransData(TransData *td, float *time, Object *ob)
+{
+ /* memory is calloc'ed, so that should zero everything nicely for us */
+ td->val = time;
+ td->ival = *(time);
+
+ /* store the Object where this keyframe exists as a keyframe of the
+ * active action as td->ob. Usually, this member is only used for constraints
+ * drawing
+ */
+ td->ob= ob;
+}
+
+/* This function advances the address to which td points to, so it must return
+ * the new address so that the next time new transform data is added, it doesn't
+ * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob, side, cfra);
+ *
+ * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
+ * on the named side are used.
+ */
+static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
+{
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int i;
+
+ if (ipo == NULL)
+ return td;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* only add selected keyframes (for now, proportional edit is not enabled) */
+ if (BEZSELECTED(bezt)) {
+ /* only add if on the right 'side' of the current frame */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
+ /* each control point needs to be added separetely */
+ TimeToTransData(td, bezt->vec[0], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[1], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[2], ob);
+ td++;
+ }
+ }
+ }
+ }
+
+ return td;
+}
+
+static void createTransActionData(TransInfo *t)
+{
+ TransData *td = NULL;
+ Object *ob= NULL;
+
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ int count=0;
+ float cfra;
+ char side;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* is the action scaled? if so, the it should belong to the active object */
+ if (NLA_ACTION_SCALED)
+ ob= OBACT;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
+
+ /* convert current-frame to action-time (slightly less accurate, espcially under
+ * higher scaling ratios, but is faster than converting all points)
+ */
+ if (ob)
+ cfra = get_action_frame(ob, CFRA);
+ else
+ cfra = CFRA;
+
+ /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
+ for (ale= act_data.first; ale; ale= ale->next)
+ count += count_ipo_keys(ale->key_data, side, cfra);
+
+ /* stop if trying to build list if nothing selected */
+ if (count == 0) {
+ /* cleanup temp list */
+ BLI_freelistN(&act_data);
+ return;
+ }
+
+ /* allocate memory for data */
+ t->total= count;
+ t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)");
+ if (t->mode == TFM_TIME_SLIDE)
+ t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max");
+
+ td= t->data;
+ /* loop 2: build transdata array */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ Ipo *ipo= (Ipo *)ale->key_data;
+
+ td= IpoToTransData(td, ipo, ob, side, cfra);
+ }
+
+ /* check if we're supposed to be setting minx/maxx for TimeSlide */
+ if (t->mode == TFM_TIME_SLIDE) {
+ float min=999999999.0f, max=-999999999.0;
+ int i;
+
+ td= (t->data + 1);
+ for (i=1; i < count; i+=3, td+=3) {
+ if (min > *(td->val)) min= *(td->val);
+ if (max < *(td->val)) max= *(td->val);
+ }
+
+ /* minx/maxx values used by TimeSlide are stored as a
+ * calloced 2-float array in t->customData. This gets freed
+ * in postTrans (T_FREE_CUSTOMDATA).
+ */
+ *((float *)(t->customData)) = min;
+ *((float *)(t->customData) + 1) = max;
+ }
+
+ /* cleanup temp list */
+ BLI_freelistN(&act_data);
+}
+
+static void createTransNlaData(TransInfo *t)
+{
+ Base *base;
+ bActionStrip *strip;
+ bActionChannel *achan;
+ bConstraintChannel *conchan;
+
+ TransData *td = NULL;
+ int count=0, i;
+ float cfra;
+ char side;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
+
+ /* Ensure that partial selections result in beztriple selections */
+ for (base=G.scene->base.first; base; base=base->next) {
+ /* Check object ipos */
+ i= count_ipo_keys(base->object->ipo, side, CFRA);
+ if (i) base->flag |= BA_HAS_RECALC_OB;
+ count += i;
+
+ /* Check object constraint ipos */
+ for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
+ count += count_ipo_keys(conchan->ipo, side, CFRA);
+
+ /* skip actions and nlastrips if object is collapsed */
+ if (base->object->nlaflag & OB_NLA_COLLAPSED)
+ continue;
+
+ /* Check action ipos */
+ if (base->object->action) {
+ /* exclude if strip is selected too */
+ for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT)
+ if (strip->act == base->object->action)
+ break;
+ }
+ if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
+ for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
+ if (EDITABLE_ACHAN(achan)) {
+ i= count_ipo_keys(achan->ipo, side, cfra);
+ if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
+ count += i;
+
+ /* Check action constraint ipos */
+ if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (EDITABLE_CONCHAN(conchan))
+ count += count_ipo_keys(conchan->ipo, side, cfra);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Check nlastrips */
+ for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT) {
+ base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
+
+ if (FrameOnMouseSide(side, strip->start, CFRA)) count++;
+ if (FrameOnMouseSide(side, strip->end, CFRA)) count++;
+ }
+ }
+ }
+
+ /* If nothing is selected, bail out */
+ if (count == 0)
+ return;
+
+ /* allocate memory for data */
+ t->total= count;
+ t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (NLA Editor)");
+
+ /* build the transdata structure */
+ td= t->data;
+ for (base=G.scene->base.first; base; base=base->next) {
+ /* Manipulate object ipos */
+ /* - no scaling of keyframe times is allowed here */
+ td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA);
+
+ /* Manipulate object constraint ipos */
+ /* - no scaling of keyframe times is allowed here */
+ for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
+ td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA);
+
+ /* skip actions and nlastrips if object collapsed */
+ if (base->object->nlaflag & OB_NLA_COLLAPSED)
+ continue;
+
+ /* Manipulate action ipos */
+ if (base->object->action) {
+ /* exclude if strip that active action belongs to is selected too */
+ for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT)
+ if (strip->act == base->object->action)
+ break;
+ }
+
+ /* can include if no strip found */
+ if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
+ for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
+ if (EDITABLE_ACHAN(achan)) {
+ td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
+
+ /* Manipulate action constraint ipos */
+ if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (EDITABLE_CONCHAN(conchan))
+ td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Manipulate nlastrips */
+ for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT) {
+ /* first TransData is the start, second is the end */
+ if (FrameOnMouseSide(side, strip->start, CFRA)) {
+ td->val = &strip->start;
+ td->ival = strip->start;
+ td++;
+ }
+ if (FrameOnMouseSide(side, strip->end, CFRA)) {
+ td->val = &strip->end;
+ td->ival = strip->end;
+ td++;
+ }
+ }
+ }
+ }
+}
+
/* **************** IpoKey stuff, for Object TransData ********** */
/* storage of bezier triple. thats why -3 and +3! */
@@ -2043,31 +2919,86 @@ static void ipokey_to_transdata(IpoKey *ik, TransData *td)
/* *************************** Object Transform data ******************* */
-static void ObjectToTransData(TransData *td, Object *ob)
+/* Little helper function for ObjectToTransData used to give certain
+ * constraints (ChildOf, FollowPath, and others that may be added)
+ * inverse corrections for transform, so that they aren't in CrazySpace.
+ * These particular constraints benefit from this, but others don't, hence
+ * this semi-hack ;-) - Aligorith
+ */
+static short constraints_list_needinv(TransInfo *t, ListBase *list)
{
+ bConstraint *con;
+
+ /* loop through constraints, checking if there's one of the mentioned
+ * constraints needing special crazyspace corrections
+ */
+ if (list) {
+ for (con= list->first; con; con=con->next) {
+ /* only consider constraint if it is enabled, and has influence on result */
+ if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0)) {
+ /* (affirmative) returns for specific constraints here... */
+ /* constraints that require this regardless */
+ if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1;
+ if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1;
+ if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1;
+
+ /* constraints that require this only under special conditions */
+ if (con->type == CONSTRAINT_TYPE_ROTLIKE) {
+ /* CopyRot constraint only does this when rotating, and offset is on */
+ bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data;
+
+ if ((data->flag & ROTLIKE_OFFSET) && (t->mode == TFM_ROTATION))
+ return 1;
+ }
+ }
+ }
+ }
+
+ /* no appropriate candidates found */
+ return 0;
+}
+
+/* transcribe given object into TransData for Transforming */
+static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
+{
+ Object *track;
+ ListBase fakecons = {NULL, NULL};
float obmtx[3][3];
- Object *tr;
- void *cfirst, *clast;
+ short constinv;
- /* set axismtx BEFORE clearing constraints to have the real orientation */
+ /* axismtx has the real orientation */
Mat3CpyMat4(td->axismtx, ob->obmat);
Mat3Ortho(td->axismtx);
- /* then why are constraints and track disabled here?
- they dont alter loc/rot/size itself (ton) */
- cfirst = ob->constraints.first;
- clast = ob->constraints.last;
- ob->constraints.first=ob->constraints.last=NULL;
-
- tr= ob->track;
- ob->track= NULL;
-
- where_is_object(ob);
-
- ob->track= tr;
-
- ob->constraints.first = cfirst;
- ob->constraints.last = clast;
+ td->con= ob->constraints.first;
+
+ /* hack: tempolarily disable tracking and/or constraints when getting
+ * object matrix, if tracking is on, or if constraints don't need
+ * inverse correction to stop it from screwing up space conversion
+ * matrix later
+ */
+ constinv= constraints_list_needinv(t, &ob->constraints);
+ if (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(ob);
+
+ if (constinv == 0) {
+ ob->constraints.first = fakecons.first;
+ ob->constraints.last = fakecons.last;
+ }
+
+ ob->track= track;
+ }
+ else
+ where_is_object(ob);
td->ob = ob;
@@ -2083,23 +3014,35 @@ static void ObjectToTransData(TransData *td, Object *ob)
VECCOPY(td->ext->dsize, ob->dsize);
VECCOPY(td->center, ob->obmat[3]);
+
+ Mat4CpyMat4(td->ext->obmat, ob->obmat);
- if (ob->parent)
- {
+ /* is there a need to set the global<->data space conversion matrices? */
+ if (ob->parent || constinv) {
float totmat[3][3], obinv[3][3];
- /* we calculate smtx without obmat: so a parmat */
+ /* Get the effect of parenting, and/or certain constraints.
+ * NOTE: some Constraints, and also Tracking should never get this
+ * done, as it doesn't work well.
+ */
object_to_mat3(ob, obmtx);
Mat3CpyMat4(totmat, ob->obmat);
Mat3Inv(obinv, totmat);
Mat3MulMat3(td->smtx, obmtx, obinv);
Mat3Inv(td->mtx, td->smtx);
}
- else
- {
+ else {
+ /* no conversion to/from dataspace */
Mat3One(td->smtx);
Mat3One(td->mtx);
}
+
+ /* set active flag */
+ if (BASACT && BASACT->object == ob)
+ {
+ td->flag |= TD_ACTIVE;
+ }
+
#ifdef WITH_VERSE
if(ob->vnode) {
td->verse = (void*)ob;
@@ -2177,39 +3120,404 @@ static void clear_trans_object_base_flags(void)
}
}
+/* auto-keyframing feature - checks for whether anything should be done for the current frame */
+short autokeyframe_cfra_can_key(Object *ob)
+{
+ ListBase keys = {NULL, NULL};
+ ActKeyColumn *ak;
+ float cfra;
+ short found= 0;
+
+ /* only filter if auto-key mode requires this */
+ if (IS_AUTOKEY_ON == 0)
+ return 0;
+ else if (IS_AUTOKEY_MODE(NORMAL))
+ return 1;
+
+ /* sanity check */
+ if (ob == NULL)
+ return 0;
+
+ /* get keyframes that object has (bone anim is stored on ob too) */
+ if (ob->action)
+ action_to_keylist(ob->action, &keys, NULL, NULL);
+ else if (ob->ipo)
+ ipo_to_keylist(ob->ipo, &keys, NULL, NULL);
+ else
+ return 0;
+
+ /* get current frame (will apply nla-scaling as necessary) */
+ // ack... this is messy...
+ cfra= frame_to_float(CFRA);
+ cfra= get_action_frame(ob, cfra);
+
+ /* check if a keyframe occurs on current frame */
+ for (ak= keys.first; ak; ak= ak->next) {
+ if (IS_EQ(cfra, ak->cfra)) {
+ found= 1;
+ break;
+ }
+ }
+
+ /* free temp list */
+ BLI_freelistN(&keys);
+
+ return found;
+}
+
+/* auto-keyframing feature - for objects
+ * tmode: should be a transform mode
+ */
+void autokeyframe_ob_cb_func(Object *ob, int tmode)
+{
+ IpoCurve *icu;
+ char *actname="";
+
+ if (autokeyframe_cfra_can_key(ob)) {
+ if (ob->ipoflag & OB_ACTION_OB)
+ actname= "Object";
+
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ if (ob->ipo || ob->action) {
+ ID *id= (ID *)(ob);
+
+ if (ob->ipo) {
+ icu= ob->ipo->curve.first;
+ }
+ else {
+ bActionChannel *achan;
+ achan= get_action_channel(ob->action, actname);
+
+ if (achan && achan->ipo)
+ icu= achan->ipo->curve.first;
+ else
+ icu= NULL;
+ }
+
+ while (icu) {
+ icu->flag &= ~IPO_SELECT;
+ if (IS_AUTOKEY_FLAG(INSERTNEEDED))
+ insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
+ else
+ insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
+ icu= icu->next;
+ }
+ }
+ }
+ else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
+ short doLoc=0, doRot=0, doScale=0;
+
+ /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
+ if (tmode == TFM_TRANSLATION) {
+ doLoc = 1;
+ }
+ else if (tmode == TFM_ROTATION) {
+ if (G.vd->around == V3D_ACTIVE) {
+ if (ob != OBACT)
+ doLoc = 1;
+ }
+ else if (G.vd->around == V3D_CURSOR)
+ doLoc = 1;
+
+ if ((G.vd->flag & V3D_ALIGN)==0)
+ doRot = 1;
+ }
+ else if (tmode == TFM_RESIZE) {
+ if (G.vd->around == V3D_ACTIVE) {
+ if (ob != OBACT)
+ doLoc = 1;
+ }
+ else if (G.vd->around == V3D_CURSOR)
+ doLoc = 1;
+
+ if ((G.vd->flag & V3D_ALIGN)==0)
+ doScale = 1;
+ }
+
+ if (doLoc) {
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_X);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Y);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Z);
+ }
+ if (doRot) {
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_X);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Y);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Z);
+ }
+ if (doScale) {
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_X);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y);
+ insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z);
+ }
+ }
+ else {
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
+
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
+
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_X, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
+ insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
+ }
+
+ remake_object_ipos(ob);
+ allqueue(REDRAWMARKER, 0);
+ }
+}
+
+/* auto-keyframing feature - for poses/pose-channels
+ * tmode: should be a transform mode
+ * targetless_ik: has targetless ik been done on any channels?
+ */
+void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
+{
+ bArmature *arm= ob->data;
+ bAction *act;
+ bPose *pose;
+ bPoseChannel *pchan;
+ IpoCurve *icu;
+
+ pose= ob->pose;
+ act= ob->action;
+
+ if (autokeyframe_cfra_can_key(ob)) {
+ if (act == NULL)
+ act= ob->action= add_empty_action("Action");
+
+ for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
+ if (pchan->bone->flag & BONE_TRANSFORM) {
+ /* clear any 'unkeyed' flag it may have */
+ pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* only insert into available channels? */
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ bActionChannel *achan;
+
+ for (achan = act->chanbase.first; achan; achan=achan->next) {
+ if (achan->ipo && !strcmp (achan->name, pchan->name)) {
+ for (icu = achan->ipo->curve.first; icu; icu=icu->next) {
+ /* only insert keyframe if needed? */
+ if (IS_AUTOKEY_FLAG(INSERTNEEDED))
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
+ else
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode, 0);
+ }
+ break;
+ }
+ }
+ }
+ /* only insert keyframe if needed? */
+ else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
+ short doLoc=0, doRot=0, doScale=0;
+
+ /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
+ if (tmode == TFM_TRANSLATION) {
+ if (targetless_ik)
+ doRot= 1;
+ else
+ doLoc = 1;
+ }
+ else if (tmode == TFM_ROTATION) {
+ if (ELEM(G.vd->around, V3D_CURSOR, V3D_ACTIVE))
+ doLoc = 1;
+
+ if ((G.vd->flag & V3D_ALIGN)==0)
+ doRot = 1;
+ }
+ else if (tmode == TFM_RESIZE) {
+ if (ELEM(G.vd->around, V3D_CURSOR, V3D_ACTIVE))
+ doLoc = 1;
+
+ if ((G.vd->flag & V3D_ALIGN)==0)
+ doScale = 1;
+ }
+
+ if (doLoc) {
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+ }
+ if (doRot) {
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
+ }
+ if (doScale) {
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
+ insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
+ }
+ }
+ /* insert keyframe in any channel that's appropriate */
+ else {
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
+
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
+
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
+ insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
+ }
+ }
+ }
+
+ remake_action_ipos (act);
+ allqueue(REDRAWMARKER, 0);
+
+ /* locking can be disabled */
+ ob->pose->flag &= ~(POSE_DO_UNLOCK|POSE_LOCKED);
+
+ /* do the bone paths */
+ if (arm->pathflag & ARM_PATH_ACFRA) {
+ //pose_clear_paths(ob);
+ pose_recalculate_paths(ob);
+ }
+ }
+ else {
+ /* tag channels that should have unkeyed data */
+ for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
+ if (pchan->bone->flag & BONE_TRANSFORM) {
+ /* tag this channel */
+ pchan->bone->flag |= BONE_UNKEYED;
+ }
+ }
+ }
+}
+
+/* very bad call!!! - copied from editnla.c! */
+static void recalc_all_ipos(void)
+{
+ Ipo *ipo;
+ IpoCurve *icu;
+
+ /* Go to each ipo */
+ for (ipo=G.main->ipo.first; ipo; ipo=ipo->id.next){
+ for (icu = ipo->curve.first; icu; icu=icu->next){
+ sort_time_ipocurve(icu);
+ testhandles_ipocurve(icu);
+ }
+ }
+}
+
/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */
-/* note; transdata has been freed already! */
+/* note: transdata has been freed already! */
void special_aftertrans_update(TransInfo *t)
{
Object *ob;
Base *base;
- IpoCurve *icu;
- int redrawipo=0;
+ short redrawipo=0, resetslowpar=1;
int cancelled= (t->state == TRANS_CANCEL);
+
+ if (t->spacetype==SPACE_VIEW3D) {
+ EM_automerge(1);
+ /* when snapping, delay retopo until after automerge */
+ if (G.qual & LR_CTRLKEY) {
+ retopo_do_all();
+ }
+ }
+ if (t->spacetype == SPACE_ACTION) {
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ ob = OBACT;
+
+ if (datatype == ACTCONT_ACTION) {
+ /* Depending on the lock status, draw necessary views */
+ if (ob) {
+ ob->ctime= -1234567.0f;
+
+ if(ob->pose || ob_get_key(ob))
+ DAG_object_flush_update(G.scene, ob, OB_RECALC);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+
+ /* Do curve cleanups? */
+ if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 &&
+ (cancelled == 0) )
+ {
+ posttrans_action_clean((bAction *)data);
+ }
+
+ /* Do curve updates */
+ remake_action_ipos((bAction *)data);
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ /* fix up the Ipocurves and redraw stuff */
+ Key *key= (Key *)data;
+ if (key->ipo) {
+ IpoCurve *icu;
+
+
+
+ if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 &&
+ (cancelled == 0) )
+ {
+ posttrans_ipo_clean(key->ipo);
+ }
+
+ for (icu = key->ipo->curve.first; icu; icu=icu->next) {
+ sort_time_ipocurve(icu);
+ testhandles_ipocurve(icu);
+ }
+ }
+
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ }
+
+ G.saction->flag &= ~SACTION_MOVING;
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ synchronize_action_strips();
+
+ /* cleanup */
+ for (base=G.scene->base.first; base; base=base->next)
+ base->flag &= ~(BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA);
- if(G.obedit) {
- if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
+ recalc_all_ipos(); // bad
+ }
+ else if (t->spacetype == SPACE_IPO) {
+ // FIXME! is there any code from the old transform_ipo that needs to be added back?
+
+ /* resetting slow-parents isn't really necessary when editing sequence ipo's */
+ if (G.sipo->blocktype==ID_SEQ)
+ resetslowpar= 0;
+ }
+ else if (G.obedit) {
+ if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
allqueue(REDRAWBUTSEDIT, 0);
/* table needs to be created for each edit command, since vertices can move etc */
mesh_octree_table(G.obedit, NULL, 'e');
}
- else if( (t->flag & T_POSE) && t->poseobj) {
+ else if ((t->flag & T_POSE) && (t->poseobj)) {
bArmature *arm;
- bAction *act;
bPose *pose;
bPoseChannel *pchan;
short targetless_ik= 0;
-
+
ob= t->poseobj;
arm= ob->data;
pose= ob->pose;
/* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
pose->flag |= POSE_DO_UNLOCK;
-
+
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
- if(!cancelled && t->mode==TFM_TRANSLATION)
+ if (!cancelled && t->mode==TFM_TRANSLATION)
targetless_ik= apply_targetless_ik(ob);
else {
/* not forget to clear the auto flag */
@@ -2219,81 +3527,15 @@ void special_aftertrans_update(TransInfo *t)
}
}
- if(t->mode==TFM_TRANSLATION)
+ if (t->mode==TFM_TRANSLATION)
pose_grab_with_ik_clear(ob);
-
- /* automatic inserting of keys */
- if((G.flags & G_RECORDKEYS) && (!cancelled)) {
- act= ob->action;
-
- if (!act)
- act= ob->action= add_empty_action("Action");
-
- for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
- if (pchan->bone->flag & BONE_TRANSFORM){
-
- if(U.uiflag & USER_KEYINSERTAVAI) {
- bActionChannel *achan;
-
- for (achan = act->chanbase.first; achan; achan=achan->next){
-
- if (achan->ipo && !strcmp (achan->name, pchan->name)){
- for (icu = achan->ipo->curve.first; icu; icu=icu->next){
- if (U.uiflag & USER_KEYINSERTNEED)
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
- else
- insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
- }
-
- break;
- }
- }
- }
- else if (U.uiflag & USER_KEYINSERTNEED) {
- if ((t->mode==TFM_TRANSLATION) && (targetless_ik==0)) {
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
- }
- if ((t->mode==TFM_ROTATION) || ((t->mode==TFM_TRANSLATION) && targetless_ik)) {
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- }
- if (t->mode==TFM_RESIZE) {
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
- }
- }
- else {
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
-
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
-
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
- }
- }
- }
-
- remake_action_ipos (act);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWTIME, 0);
+ /* automatic inserting of keys and unkeyed tagging - only if transform wasn't cancelled (or TFM_DUMMY) */
+ if (!cancelled && (t->mode != TFM_DUMMY)) {
+ autokeyframe_pose_cb_func(ob, t->mode, targetless_ik);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
- else if(arm->flag & ARM_DELAYDEFORM) {
+ else if (arm->flag & ARM_DELAYDEFORM) {
/* old optimize trick... this enforces to bypass the depgraph */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
ob->recalc= 0; // is set on OK position already by recalcData()
@@ -2301,91 +3543,32 @@ void special_aftertrans_update(TransInfo *t)
else
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
+ if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
allqueue(REDRAWBUTSEDIT, 0);
-
+
+ }
+ else if(G.f & G_PARTICLEEDIT) {
+ ;
}
else {
base= FIRSTBASE;
- while(base) {
-
+
+ while (base) {
+
if(base->flag & BA_DO_IPO) redrawipo= 1;
ob= base->object;
-
- if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO;
+
+ if (modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO;
+ else if((ob == OBACT) && modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
/* Set autokey if necessary */
- if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){
- char *actname="";
-
- if(ob->ipoflag & OB_ACTION_OB)
- actname= "Object";
-
- if(U.uiflag & USER_KEYINSERTAVAI) {
- if(base->object->ipo || base->object->action) {
- ID* id= (ID *)(base->object);
-
- if (base->object->ipo) {
- icu= base->object->ipo->curve.first;
- }
- else {
- bActionChannel *achan;
- achan= get_action_channel(base->object->action, actname);
-
- if (achan && achan->ipo)
- icu= achan->ipo->curve.first;
- else
- icu= NULL;
- }
-
- while(icu) {
- icu->flag &= ~IPO_SELECT;
- if (U.uiflag & USER_KEYINSERTNEED)
- insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
- else
- insertkey(id, ID_OB, actname, NULL, icu->adrcode);
- icu= icu->next;
- }
- }
- }
- else if (U.uiflag & USER_KEYINSERTNEED) {
- if (t->mode==TFM_RESIZE) {
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
- }
- else if (t->mode==TFM_ROTATION) {
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
- }
- else if (t->mode==TFM_TRANSLATION) {
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
- insertkey_smarter(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
- }
- }
- else {
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
-
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
-
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
- insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
- }
-
- remake_object_ipos (ob);
- allqueue(REDRAWIPO, 0);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWTIME, 0);
+ if ((!cancelled) && (t->mode != TFM_DUMMY) && (base->flag & SELECT)) {
+ autokeyframe_ob_cb_func(ob, t->mode);
}
base= base->next;
@@ -2395,13 +3578,14 @@ void special_aftertrans_update(TransInfo *t)
clear_trans_object_base_flags();
- if(redrawipo) {
+ if (redrawipo) {
allqueue(REDRAWNLA, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
}
- reset_slowparents();
+ if(resetslowpar)
+ reset_slowparents();
/* note; should actually only be done for all objects when a lamp is moved... (ton) */
if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED)
@@ -2421,19 +3605,21 @@ static void createTransObject(TransInfo *t)
/* count */
for(base= FIRSTBASE; base; base= base->next) {
- if TESTBASELIB(base) {
+ if TESTBASE(base) {
ob= base->object;
/* store ipo keys? */
- if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
+ 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++;
+ for(ik= elems.first; ik; ik= ik->next)
+ t->total++;
- if(elems.first==NULL) t->total++;
+ if(elems.first==NULL)
+ t->total++;
}
else {
t->total++;
@@ -2451,15 +3637,20 @@ static void createTransObject(TransInfo *t)
tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension");
for(base= FIRSTBASE; base; base= base->next) {
- if TESTBASELIB(base) {
+ if TESTBASE(base) {
ob= base->object;
- td->flag= TD_SELECTED;
+ td->flag = TD_SELECTED;
td->protectflag= ob->protectflag;
td->ext = tx;
+
+ /* select linked objects, but skip them later */
+ if (ob->id.lib != 0) {
+ td->flag |= TD_SKIP;
+ }
/* store ipo keys? */
- if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
+ if(ob->id.lib == 0 && ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
popfirst(&elems); // bring back pushed listbase
@@ -2488,7 +3679,7 @@ static void createTransObject(TransInfo *t)
CFRA= (int)(ik->val/G.scene->r.framelen);
do_ob_ipo(ob);
- ObjectToTransData(td, ob); // does where_is_object()
+ ObjectToTransData(t, td, ob); // does where_is_object()
td->flag= TD_SELECTED;
@@ -2511,7 +3702,7 @@ static void createTransObject(TransInfo *t)
where_is_object(ob); // restore
}
else {
- ObjectToTransData(td, ob);
+ ObjectToTransData(t, td, ob);
td->tdi = NULL;
td->val = NULL;
td++;
@@ -2519,7 +3710,7 @@ static void createTransObject(TransInfo *t)
}
}
else {
- ObjectToTransData(td, ob);
+ ObjectToTransData(t, td, ob);
td->tdi = NULL;
td->val = NULL;
td++;
@@ -2547,6 +3738,9 @@ void createTransData(TransInfo *t)
sort_trans_data_dist(t);
}
}
+ else if (t->context == CTX_BMESH) {
+ createTransBMeshVerts(t, G.editBMesh->bm, G.editBMesh->td);
+ }
else if (t->spacetype == SPACE_IMAGE) {
t->flag |= T_POINTS|T_2D_EDIT;
createTransUVs(t);
@@ -2556,6 +3750,23 @@ void createTransData(TransInfo *t)
sort_trans_data_dist(t);
}
}
+ else if (t->spacetype == SPACE_ACTION) {
+ t->flag |= T_POINTS|T_2D_EDIT;
+ createTransActionData(t);
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ t->flag |= T_POINTS|T_2D_EDIT;
+ createTransNlaData(t);
+ }
+ else if (t->spacetype == SPACE_IPO) {
+ t->flag |= T_POINTS|T_2D_EDIT;
+ createTransIpoData(t);
+ if (t->data && (t->flag & T_PROP_EDIT)) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
+ }
+ }
else if (G.obedit) {
t->ext = NULL;
if (G.obedit->type == OB_MESH) {
@@ -2617,6 +3828,17 @@ void createTransData(TransInfo *t)
createTransPose(t, base->object);
}
}
+ else if (G.f & G_PARTICLEEDIT && PE_can_edit(PE_get_current(ob))) {
+ createTransParticleVerts(t);
+
+ if(t->data && t->flag & T_PROP_EDIT) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
+ }
+
+ t->flag |= T_POINTS;
+ }
else {
createTransObject(t);
t->flag |= T_OBJECT;
@@ -2630,3 +3852,5 @@ void createTransData(TransInfo *t)
G.scene->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
}
+
+
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index 60ec15330ef..6738d437ab6 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -44,6 +44,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@@ -54,12 +55,18 @@
#include "BIF_resources.h"
#include "BIF_mywindow.h"
#include "BIF_gl.h"
+#include "BIF_editaction.h"
#include "BIF_editarmature.h"
#include "BIF_editmesh.h"
+#include "BIF_editnla.h"
#include "BIF_editsima.h"
+#include "BIF_editparticle.h"
#include "BIF_meshtools.h"
#include "BIF_retopo.h"
+#include "BSE_editipo.h"
+#include "BSE_editipo_types.h"
+
#ifdef WITH_VERSE
#include "BIF_verse.h"
#endif
@@ -67,6 +74,7 @@
#include "BKE_action.h"
#include "BKE_anim.h"
#include "BKE_armature.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
@@ -75,6 +83,7 @@
#include "BKE_group.h"
#include "BKE_ipo.h"
#include "BKE_lattice.h"
+#include "BKE_key.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -85,6 +94,7 @@
#endif
#include "BSE_view.h"
+#include "BSE_editaction_types.h"
#include "BDR_unwrapper.h"
#include "BLI_arithb.h"
@@ -139,7 +149,7 @@ void getViewVector(float coord[3], float vec[3])
static void clipMirrorModifier(TransInfo *t, Object *ob)
{
ModifierData *md= ob->modifiers.first;
- float tolerance[3];
+ float tolerance[3] = {0.0f, 0.0f, 0.0f};
int axis = 0;
for (; md; md=md->next) {
@@ -147,6 +157,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
+ axis = 0;
if(mmd->flag & MOD_MIR_AXIS_X) {
axis |= 1;
tolerance[0] = mmd->tolerance;
@@ -159,28 +170,71 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
axis |= 4;
tolerance[2] = mmd->tolerance;
}
- }
- }
- }
- if (axis) {
- TransData *td = t->data;
- int i;
+ if (axis) {
+ float mtx[4][4], imtx[4][4];
+ int i;
+ TransData *td = t->data;
- for(i = 0 ; i < t->total; i++, td++) {
- if (td->flag & TD_NOACTION)
- break;
- if (td->loc==NULL)
- break;
+ 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;
- if(axis & 1) {
- if(fabs(td->iloc[0])<=tolerance[0] || td->loc[0]*td->iloc[0]<0.0f) td->loc[0]= 0.0f;
- }
+ 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] ||
+ loc[0]*iloc[0]<0.0f) {
+ loc[0]= 0.0f;
+ clip = 1;
+ }
+ }
- if(axis & 2) {
- if(fabs(td->iloc[1])<=tolerance[1] || td->loc[1]*td->iloc[1]<0.0f) td->loc[1]= 0.0f;
- }
- if(axis & 4) {
- if(fabs(td->iloc[2])<=tolerance[2] || td->loc[2]*td->iloc[2]<0.0f) td->loc[2]= 0.0f;
+ if(axis & 2) {
+ if(fabs(iloc[1])<=tolerance[1] ||
+ loc[1]*iloc[1]<0.0f) {
+ loc[1]= 0.0f;
+ clip = 1;
+ }
+ }
+ if(axis & 4) {
+ if(fabs(iloc[2])<=tolerance[2] ||
+ loc[2]*iloc[2]<0.0f) {
+ loc[2]= 0.0f;
+ clip = 1;
+ }
+ }
+ if (clip) {
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(loc, imtx, loc);
+ }
+ VecCopyf(td->loc, loc);
+ }
+ }
+ }
+
}
}
}
@@ -198,6 +252,8 @@ static void editmesh_apply_to_mirror(TransInfo *t)
break;
if (td->loc==NULL)
break;
+ if (td->flag & TD_SKIP)
+ continue;
eve= td->tdmir;
if(eve) {
@@ -215,21 +271,128 @@ void recalcData(TransInfo *t)
#ifdef WITH_VERSE
struct TransData *td;
#endif
+
+ if (t->spacetype == SPACE_ACTION) {
+ Object *ob= OBACT;
+ void *data;
+ short context;
- if (G.obedit) {
- if (G.obedit->type == OB_MESH) {
- retopo_do_all();
-
- /* mirror modifier clipping? */
- if(t->state != TRANS_CANCEL)
- clipMirrorModifier(t, G.obedit);
-
- if(G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR)
- editmesh_apply_to_mirror(t);
-
- DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
+ /* determine what type of data we are operating on */
+ data = get_action_context(&context);
+ if (data == NULL) return;
+
+ if (G.saction->lock) {
+ if (context == ACTCONT_ACTION) {
+ if(ob) {
+ ob->ctime= -1234567.0f;
+ if(ob->pose || ob_get_key(ob))
+ DAG_object_flush_update(G.scene, ob, OB_RECALC);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+ }
+ else if (context == ACTCONT_SHAPEKEY) {
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
+ }
+ }
+ }
+ else if (t->spacetype == SPACE_NLA) {
+ if (G.snla->lock) {
+ for (base=G.scene->base.first; base; base=base->next) {
+ if (base->flag & BA_HAS_RECALC_OB)
+ base->object->recalc |= OB_RECALC_OB;
+ if (base->flag & BA_HAS_RECALC_DATA)
+ base->object->recalc |= OB_RECALC_DATA;
+
+ if (base->object->recalc)
+ base->object->ctime= -1234567.0f; // eveil!
+ }
- recalc_editnormals();
+ DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ }
+ }
+ else if (t->spacetype == SPACE_IPO) {
+ EditIpo *ei;
+ int dosort = 0;
+ int a;
+
+ /* do the flush first */
+ flushTransIpoData(t);
+
+ /* now test if there is a need to re-sort */
+ ei= G.sipo->editipo;
+ for (a=0; a<G.sipo->totipo; a++, ei++) {
+ if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+
+ /* watch it: if the time is wrong: do not correct handles */
+ if (test_time_ipocurve(ei->icu)) dosort++;
+ else testhandles_ipocurve(ei->icu);
+ }
+ }
+
+ /* do resort and other updates? */
+ if (dosort) remake_ipo_transdata(t);
+ if (G.sipo->showkey) update_ipokey_val();
+
+ calc_ipo(G.sipo->ipo, (float)CFRA);
+
+ /* update realtime - not working? */
+ if (G.sipo->lock) {
+ if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) {
+ do_ipo(G.sipo->ipo);
+ }
+ else if(G.sipo->blocktype==ID_CA) {
+ do_ipo(G.sipo->ipo);
+ }
+ else if(G.sipo->blocktype==ID_KE) {
+ Object *ob= OBACT;
+ if(ob) {
+ ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ else if(G.sipo->blocktype==ID_PO) {
+ Object *ob= OBACT;
+ if(ob && ob->pose) {
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ }
+ }
+ else if(G.sipo->blocktype==ID_OB) {
+ Base *base= FIRSTBASE;
+
+ while(base) {
+ if(base->object->ipo==G.sipo->ipo) {
+ do_ob_ipo(base->object);
+ base->object->recalc |= OB_RECALC_OB;
+ }
+ base= base->next;
+ }
+ DAG_scene_flush_update(G.scene, screen_view3d_layers());
+ }
+ }
+ }
+ else if (G.obedit) {
+ if (G.obedit->type == OB_MESH) {
+ if(t->spacetype==SPACE_IMAGE) {
+ flushTransUVs(t);
+ if (G.sima->flag & SI_LIVE_UNWRAP)
+ unwrap_lscm_live_re_solve();
+ } else {
+ /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */
+ if ((G.qual & LR_CTRLKEY)==0)
+ retopo_do_all();
+
+ /* mirror modifier clipping? */
+ if(t->state != TRANS_CANCEL)
+ clipMirrorModifier(t, G.obedit);
+
+ if((t->context & CTX_NO_MIRROR) == 0 && (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+ editmesh_apply_to_mirror(t);
+
+ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
+
+ recalc_editnormals();
+ }
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
Nurb *nu= editNurb.first;
@@ -306,18 +469,23 @@ void recalcData(TransInfo *t)
/* bah, softbody exception... recalcdata doesnt reset */
for(base= FIRSTBASE; base; base= base->next) {
if(base->object->recalc & OB_RECALC_DATA)
+ {
if(modifiers_isSoftbodyEnabled(base->object)) {
base->object->softflag |= OB_SB_REDO;
+ }
+ else if(modifiers_isClothEnabled(base->object)) {
+ ClothModifierData *clmd = (ClothModifierData *) modifiers_findByType(base->object, eModifierType_Cloth);
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
+
}
}
}
else
where_is_pose(ob);
}
- else if(t->spacetype==SPACE_IMAGE) {
- flushTransUVs(t);
- if (G.sima->flag & SI_LIVE_UNWRAP)
- unwrap_lscm_live_re_solve();
+ else if(G.f & G_PARTICLEEDIT) {
+ flushTransParticles(t);
}
else {
for(base= FIRSTBASE; base; base= base->next) {
@@ -345,10 +513,16 @@ void recalcData(TransInfo *t)
}
}
- /* softbody exception */
- if(modifiers_isSoftbodyEnabled(ob)) {
- if(ob->recalc & OB_RECALC_DATA)
- ob->softflag |= OB_SB_REDO;
+ /* softbody & cloth exception */
+ if(ob->recalc & OB_RECALC_DATA)
+ {
+ if(modifiers_isSoftbodyEnabled(ob)) {
+ ob->softflag |= OB_SB_REDO;
+ }
+ else if(modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
}
/* proxy exception */
@@ -376,6 +550,39 @@ void recalcData(TransInfo *t)
}
+void initTransModeFlags(TransInfo *t, int mode)
+{
+ t->mode = mode;
+ t->num.flag = 0;
+
+ /* REMOVING RESTRICTIONS FLAGS */
+ t->flag &= ~T_ALL_RESTRICTIONS;
+
+ switch (mode) {
+ case TFM_RESIZE:
+ t->flag |= T_NULL_ONE;
+ t->num.flag |= NUM_NULL_ONE;
+ t->num.flag |= NUM_AFFECT_ALL;
+ if (!G.obedit) {
+ t->flag |= T_NO_ZERO;
+ t->num.flag |= NUM_NO_ZERO;
+ }
+ break;
+ case TFM_TOSPHERE:
+ t->num.flag |= NUM_NULL_ONE;
+ t->num.flag |= NUM_NO_NEGATIVE;
+ t->flag |= T_NO_CONSTRAINT;
+ break;
+ case TFM_SHEAR:
+ case TFM_CREASE:
+ case TFM_BONE_ENVELOPE:
+ case TFM_CURVE_SHRINKFATTEN:
+ case TFM_BONE_ROLL:
+ t->flag |= T_NO_CONSTRAINT;
+ break;
+ }
+}
+
void drawLine(float *center, float *dir, char axis, short options)
{
extern void make_axis_color(char *col, char *col2, char axis); // drawview.c
@@ -413,6 +620,7 @@ void initTrans (TransInfo *t)
/* moving: is shown in drawobject() (transform color) */
if(G.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->data = NULL;
@@ -459,6 +667,8 @@ void initTrans (TransInfo *t)
if(t->spacetype==SPACE_VIEW3D) {
if(G.vd->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
t->around = G.vd->around;
+ } else if(t->spacetype==SPACE_IMAGE) {
+ t->around = G.v2d->around;
}
else
t->around = V3D_CENTER;
@@ -551,7 +761,7 @@ static void restoreElement(TransData *td) {
if (td->val) {
*td->val = td->ival;
}
- if (td->ext) {
+ if (td->ext && (td->flag&TD_NO_EXT)==0) {
if (td->ext->rot) {
VECCOPY(td->ext->rot, td->ext->irot);
}
@@ -646,6 +856,19 @@ void calculateCenterCursor(TransInfo *t)
calculateCenter2D(t);
}
+void calculateCenterCursor2D(TransInfo *t)
+{
+ float aspx=1.0, aspy=1.0;
+
+ if(t->spacetype==SPACE_IMAGE) /* only space supported right now but may change */
+ transform_aspect_ratio_tface_uv(&aspx, &aspy);
+ if (G.v2d) {
+ t->center[0] = G.v2d->cursor[0] * aspx;
+ t->center[1] = G.v2d->cursor[1] * aspy;
+ }
+ calculateCenter2D(t);
+}
+
void calculateCenterMedian(TransInfo *t)
{
float partial[3] = {0.0f, 0.0f, 0.0f};
@@ -653,7 +876,8 @@ void calculateCenterMedian(TransInfo *t)
for(i = 0; i < t->total; i++) {
if (t->data[i].flag & TD_SELECTED) {
- VecAddf(partial, partial, t->data[i].center);
+ if (!(t->data[i].flag & TD_NOCENTER))
+ VecAddf(partial, partial, t->data[i].center);
}
else {
/*
@@ -678,7 +902,8 @@ void calculateCenterBound(TransInfo *t)
for(i = 0; i < t->total; i++) {
if (i) {
if (t->data[i].flag & TD_SELECTED) {
- MinMax3(min, max, t->data[i].center);
+ if (!(t->data[i].flag & TD_NOCENTER))
+ MinMax3(min, max, t->data[i].center);
}
else {
/*
@@ -709,7 +934,10 @@ void calculateCenter(TransInfo *t)
calculateCenterMedian(t);
break;
case V3D_CURSOR:
- calculateCenterCursor(t);
+ if(t->spacetype==SPACE_IMAGE)
+ calculateCenterCursor2D(t);
+ else
+ calculateCenterCursor(t);
break;
case V3D_LOCAL:
/* Individual element center uses median center for helpline and such */
diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c
index 773ae3d17ec..8fcb329f2f9 100644
--- a/source/blender/src/transform_manipulator.c
+++ b/source/blender/src/transform_manipulator.c
@@ -53,6 +53,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -63,6 +64,7 @@
#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
@@ -76,6 +78,7 @@
#include "BIF_space.h"
#include "BIF_transform.h"
#include "BIF_editmesh.h"
+#include "BIF_editparticle.h"
#include "BSE_edit.h"
#include "BSE_view.h"
@@ -231,53 +234,20 @@ int calc_manipulator_stats(ScrArea *sa)
EditMesh *em = G.editMesh;
EditVert *eve;
float vec[3]= {0,0,0};
- int no_faces= 1;
/* USE LAST SELECTE WITH ACTIVE */
if (G.vd->around==V3D_ACTIVE && em->selected.last) {
EM_editselection_center(vec, em->selected.last);
calc_tw_center(vec);
totsel= 1;
- if (v3d->twmode == V3D_MANIP_NORMAL) {
- EM_editselection_normal(normal, em->selected.last);
- EM_editselection_plane(plane, em->selected.last);
- } /* NORMAL OPERATION */
} else {
- if(v3d->twmode == V3D_MANIP_NORMAL) {
- EditFace *efa;
-
- for(efa= em->faces.first; efa; efa= efa->next) {
- if(efa->f & SELECT) {
- no_faces= 0;
- VECADD(normal, normal, efa->n);
- VecSubf(vec, efa->v2->co, efa->v1->co);
- VECADD(plane, plane, vec);
- }
- }
- }
-
/* do vertices for center, and if still no normal found, use vertex normals */
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->f & SELECT) {
- if(no_faces) VECADD(normal, normal, eve->no);
-
totsel++;
calc_tw_center(eve->co);
}
}
- /* the edge case... */
- if(no_faces && v3d->twmode == V3D_MANIP_NORMAL) {
- EditEdge *eed;
-
- for(eed= em->edges.first; eed; eed= eed->next) {
- if(eed->f & SELECT) {
- /* ok we got an edge, only use one, and as normal */
- VECCOPY(plane, normal);
- VecSubf(normal, eed->v2->co, eed->v1->co);
- break;
- }
- }
- }
}
} /* end editmesh */
else if (G.obedit->type==OB_ARMATURE){
@@ -333,7 +303,7 @@ int calc_manipulator_stats(ScrArea *sa)
bp= nu->bp;
a= nu->pntsu*nu->pntsv;
while(a--) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
calc_tw_center(bp->vec);
totsel++;
}
@@ -357,23 +327,6 @@ int calc_manipulator_stats(ScrArea *sa)
}
ml= ml->next;
}
- /* normal manipulator */
- if(totsel==1){
- float mat1[4][4];
-
- /* Rotation of MetaElem is stored in quat */
- QuatToMat4(ml_sel->quat, mat1);
-
- /* Translation of MetaElem */
- mat1[3][0]= ml_sel->x;
- mat1[3][1]= ml_sel->y;
- mat1[3][2]= ml_sel->z;
-
- VECCOPY(normal, mat1[2]);
- VECCOPY(plane, mat1[1]);
-
- VecMulf(plane, -1.0);
- }
}
else if(G.obedit->type==OB_LATTICE) {
BPoint *bp;
@@ -381,7 +334,7 @@ int calc_manipulator_stats(ScrArea *sa)
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
- if(bp->f1 & 1) {
+ if(bp->f1 & SELECT) {
calc_tw_center(bp->vec);
totsel++;
}
@@ -427,9 +380,30 @@ int calc_manipulator_stats(ScrArea *sa)
/* restore, mode can be TFM_INIT */
Trans.mode= mode;
}
- else if(G.f & (G_FACESELECT + G_VERTEXPAINT + G_TEXTUREPAINT +G_WEIGHTPAINT)) {
+ else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) {
;
}
+ else if(G.f & G_PARTICLEEDIT) {
+ ParticleSystem *psys=PE_get_current(OBACT);
+ ParticleData *pa = psys->particles;
+ ParticleEditKey *ek;
+ int k;
+
+ if(psys->edit){
+ for(a=0; a<psys->totpart; a++,pa++){
+ if(pa->flag & PARS_HIDE) continue;
+ for(k=0, ek=psys->edit->keys[a]; k<pa->totkey; k++,ek++){
+ if(ek->flag & PEK_SELECT){
+ calc_tw_center(ek->world_co);
+ totsel++;
+ }
+ }
+ }
+ /* selection center */
+ if(totsel)
+ VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid!
+ }
+ }
else {
/* we need the one selected object, if its not active */
@@ -461,7 +435,55 @@ int calc_manipulator_stats(ScrArea *sa)
break;
case V3D_MANIP_NORMAL:
- if(G.obedit || (ob->flag & OB_POSEMODE)) {
+ if(G.obedit) {
+ float mat[3][3];
+ int type;
+
+ strcpy(t->spacename, "normal");
+
+ type = getTransformOrientation(normal, plane, 0);
+
+ switch (type)
+ {
+ case ORIENTATION_NORMAL:
+ if (createSpaceNormalTangent(mat, normal, plane) == 0)
+ {
+ type = ORIENTATION_NONE;
+ }
+ break;
+ case ORIENTATION_VERT:
+ if (createSpaceNormal(mat, normal) == 0)
+ {
+ type = ORIENTATION_NONE;
+ }
+ break;
+ case ORIENTATION_EDGE:
+ if (createSpaceNormalTangent(mat, normal, plane) == 0)
+ {
+ type = ORIENTATION_NONE;
+ }
+ break;
+ case ORIENTATION_FACE:
+ if (createSpaceNormalTangent(mat, normal, plane) == 0)
+ {
+ type = ORIENTATION_NONE;
+ }
+ break;
+ }
+
+ if (type == ORIENTATION_NONE)
+ {
+ Mat4One(v3d->twmat);
+ }
+ else
+ {
+ Mat4CpyMat3(v3d->twmat, mat);
+ }
+ break;
+ }
+ /* pose mode is a bit weird, so keep it separated */
+ else if (ob->flag & OB_POSEMODE)
+ {
strcpy(t->spacename, "normal");
if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) {
float imat[3][3], mat[3][3];
@@ -503,6 +525,9 @@ int calc_manipulator_stats(ScrArea *sa)
Mat4CpyMat3(v3d->twmat, mat);
}
break;
+ default: /* V3D_MANIP_CUSTOM */
+ applyTransformOrientation();
+ break;
}
}
@@ -1334,13 +1359,13 @@ static void draw_manipulator_rotate_cyl(float mat[][4], int moving, int drawflag
/* ********************************************* */
-float get_drawsize(View3D *v3d)
+float get_drawsize(View3D *v3d, float *co)
{
ScrArea *sa = v3d->area;
float size, vec[3], len1, len2;
/* size calculus, depending ortho/persp settings, like initgrabz() */
- size= v3d->persmat[0][3]*v3d->twmat[3][0]+ v3d->persmat[1][3]*v3d->twmat[3][1]+ v3d->persmat[2][3]*v3d->twmat[3][2]+ v3d->persmat[3][3];
+ size= v3d->persmat[0][3]*co[0]+ v3d->persmat[1][3]*co[1]+ v3d->persmat[2][3]*co[2]+ v3d->persmat[3][3];
VECCOPY(vec, v3d->persinv[0]);
len1= Normalize(vec);
@@ -1359,7 +1384,7 @@ float get_drawsize(View3D *v3d)
static float get_manipulator_drawsize(ScrArea *sa)
{
View3D *v3d= sa->spacedata.first;
- float size = get_drawsize(v3d);
+ float size = get_drawsize(v3d, v3d->twmat[3]);
size*= (float)U.tw_size;
diff --git a/source/blender/src/transform_orientations.c b/source/blender/src/transform_orientations.c
new file mode 100644
index 00000000000..1502ea70582
--- /dev/null
+++ b/source/blender/src/transform_orientations.c
@@ -0,0 +1,643 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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): Martin Poirier
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_listBase.h"
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+
+#include "BIF_editmesh.h"
+#include "BIF_interface.h"
+#include "BIF_space.h"
+#include "BIF_toolbox.h"
+
+#include "blendef.h"
+
+
+#include "transform.h"
+
+
+/* *********************** TransSpace ************************** */
+
+void BIF_clearTransformOrientation(void)
+{
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ BLI_freelistN(transform_spaces);
+
+ if (G.vd->twmode >= V3D_MANIP_CUSTOM)
+ G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+}
+
+void BIF_manageTransformOrientation(int confirm, int set) {
+ int index = -1;
+
+ if (G.obedit) {
+ if (G.obedit->type == OB_MESH)
+ index = manageMeshSpace(confirm, set);
+ }
+ else {
+ index = manageObjectSpace(confirm, set);
+ }
+
+ if (set && index != -1)
+ {
+ BIF_selectTransformOrientationFromIndex(index);
+ }
+}
+
+int manageObjectSpace(int confirm, int set) {
+ Base *base = BASACT;
+
+ if (base == NULL)
+ return -1;
+
+ 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(base->object);
+}
+
+/* return 1 on confirm */
+int confirmSpace(int set, char text[])
+{
+ char menu[64];
+
+ if (set) {
+ sprintf(menu, "Custom Orientation %%t|Add and Use %s%%x1", text);
+ }
+ else {
+ sprintf(menu, "Custom Orientation %%t|Add %s%%x1", text);
+ }
+
+ if (pupmenu(menu) == 1) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+int manageMeshSpace(int confirm, int set) {
+ float mat[3][3];
+ float normal[3], plane[3];
+ char name[36] = "";
+ int index;
+ int type;
+
+ type = getTransformOrientation(normal, plane, 0);
+
+ switch (type)
+ {
+ case ORIENTATION_VERT:
+ if (confirm == 0 && confirmSpace(set, "vertex") == 0) {
+ return -1;
+ }
+
+ if (createSpaceNormal(mat, normal) == 0) {
+ error("Cannot use vertex with zero-length normal");
+ return -1;
+ }
+
+ strcpy(name, "Vertex");
+ break;
+ case ORIENTATION_EDGE:
+ if (confirm == 0 && confirmSpace(set, "Edge") == 0) {
+ return -1;
+ }
+
+ if (createSpaceNormalTangent(mat, normal, plane) == 0) {
+ error("Cannot use zero-length edge");
+ return -1;
+ }
+
+ strcpy(name, "Edge");
+ break;
+ case ORIENTATION_FACE:
+ if (confirm == 0 && confirmSpace(set, "Face") == 0) {
+ return -1;
+ }
+
+ if (createSpaceNormalTangent(mat, normal, plane) == 0) {
+ error("Cannot use zero-area face");
+ return -1;
+ }
+
+ strcpy(name, "Face");
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ /* Input name */
+ sbutton(name, 1, 35, "name: ");
+
+ index = addMatrixSpace(mat, name);
+ return index;
+}
+
+int createSpaceNormal(float mat[3][3], float normal[3])
+{
+ float tangent[3] = {0.0f, 0.0f, 1.0f};
+
+ VECCOPY(mat[2], normal);
+ if (Normalize(mat[2]) == 0.0f) {
+ return 0; /* error return */
+ }
+
+ Crossf(mat[0], mat[2], tangent);
+ if (Inpf(mat[0], mat[0]) == 0.0f) {
+ tangent[0] = 1.0f;
+ tangent[1] = tangent[2] = 0.0f;
+ Crossf(mat[0], tangent, mat[2]);
+ }
+
+ Crossf(mat[1], mat[2], mat[0]);
+
+ Mat3Ortho(mat);
+
+ return 1;
+}
+
+int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3])
+{
+ VECCOPY(mat[2], normal);
+ if (Normalize(mat[2]) == 0.0f) {
+ return 0; /* error return */
+ }
+
+ /* preempt zero length tangent from causing trouble */
+ if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0)
+ {
+ tangent[2] = 1;
+ }
+
+ Crossf(mat[0], mat[2], tangent);
+ if (Normalize(mat[0]) == 0.0f) {
+ return 0; /* error return */
+ }
+
+ Crossf(mat[1], mat[2], mat[0]);
+
+ Mat3Ortho(mat);
+
+ return 1;
+}
+
+
+int addObjectSpace(Object *ob) {
+ float mat[3][3];
+ char name[36] = "";
+
+ Mat3CpyMat4(mat, ob->obmat);
+ Mat3Ortho(mat);
+
+ strncpy(name, ob->id.name+2, 35);
+
+ /* Input name */
+ sbutton(name, 1, 35, "name: ");
+
+ return addMatrixSpace(mat, name);
+}
+
+int addMatrixSpace(float mat[3][3], char name[]) {
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts;
+ int index = 0;
+
+ /* 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 not, create a new one */
+ if (ts == NULL)
+ {
+ ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix");
+ BLI_addtail(transform_spaces, ts);
+ strncpy(ts->name, name, 35);
+ }
+
+ /* copy matrix into transform space */
+ Mat3CpyMat3(ts->mat, mat);
+
+ BIF_undo_push("Add/Update Transform Orientation");
+
+ return index;
+}
+
+void BIF_removeTransformOrientation(TransformOrientation *target) {
+ ListBase *transform_spaces = &G.scene->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) {
+ if (selected_index == i) {
+ G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
+ }
+ else if (selected_index > i)
+ G.vd->twmode--;
+
+ BLI_freelinkN(transform_spaces, ts);
+ break;
+ }
+ }
+ BIF_undo_push("Remove Transform Orientation");
+}
+
+void BIF_selectTransformOrientation(TransformOrientation *target) {
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts = transform_spaces->first;
+ int i;
+
+ for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) {
+ if (ts == target) {
+ G.vd->twmode = V3D_MANIP_CUSTOM + i;
+ break;
+ }
+ }
+}
+
+void BIF_selectTransformOrientationFromIndex(int index) {
+ G.vd->twmode = V3D_MANIP_CUSTOM + index;
+}
+
+char * BIF_menustringTransformOrientation() {
+ char menu[] = "Orientation%t|Global%x0|Local%x1|Normal%x2|View%x3";
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts;
+ int i = V3D_MANIP_CUSTOM;
+ char *str_menu, *p;
+
+
+ str_menu = MEM_callocN(strlen(menu) + 40 * BIF_countTransformOrientation(), "UserTransSpace from matrix");
+ p = str_menu;
+
+ p += sprintf(str_menu, "%s", menu);
+
+ for (ts = transform_spaces->first; ts; ts = ts->next) {
+ p += sprintf(p, "|%s%%x%d", ts->name, i++);
+ }
+
+ return str_menu;
+}
+
+int BIF_countTransformOrientation() {
+ ListBase *transform_spaces = &G.scene->transform_spaces;
+ TransformOrientation *ts;
+ int count = 0;
+
+ for (ts = transform_spaces->first; ts; ts = ts->next) {
+ count++;
+ }
+
+ return count;
+}
+
+void applyTransformOrientation() {
+ TransInfo *t = BIF_GetTransInfo();
+ TransformOrientation *ts;
+ int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM);
+ int i;
+
+ if (selected_index >= 0) {
+ for (i = 0, ts = G.scene->transform_spaces.first; ts; ts = ts->next, i++) {
+ if (selected_index == i) {
+ strcpy(t->spacename, ts->name);
+ Mat3CpyMat3(t->spacemtx, ts->mat);
+ Mat4CpyMat3(G.vd->twmat, ts->mat);
+ break;
+ }
+ }
+ }
+}
+
+
+int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
+{
+ Base *base;
+ Object *ob = OBACT;
+ int result = ORIENTATION_NONE;
+
+ normal[0] = normal[1] = normal[2] = 0;
+ plane[0] = plane[1] = plane[2] = 0;
+
+ if(G.obedit)
+ {
+ ob= G.obedit;
+
+ if(G.obedit->type==OB_MESH)
+ {
+ EditMesh *em = G.editMesh;
+ EditVert *eve;
+ float vec[3]= {0,0,0};
+
+ /* USE LAST SELECTED WITH ACTIVE */
+ if (activeOnly && em->selected.last)
+ {
+ EditSelection *ese = em->selected.last;
+ EM_editselection_normal(normal, ese);
+ EM_editselection_plane(plane, ese);
+
+ switch (ese->type)
+ {
+ case EDITVERT:
+ result = ORIENTATION_VERT;
+ break;
+ case EDITEDGE:
+ result = ORIENTATION_EDGE;
+ break;
+ case EDITFACE:
+ result = ORIENTATION_FACE;
+ break;
+ }
+ }
+ else
+ {
+ if (G.totfacesel >= 1)
+ {
+ EditFace *efa;
+
+ for(efa= em->faces.first; efa; efa= efa->next)
+ {
+ if(efa->f & SELECT)
+ {
+ VECADD(normal, normal, efa->n);
+ VecSubf(vec, efa->v2->co, efa->v1->co);
+ VECADD(plane, plane, vec);
+ }
+ }
+
+ result = ORIENTATION_FACE;
+ }
+ else if (G.totvertsel == 3)
+ {
+ EditVert *v1 = NULL, *v2 = NULL, *v3 = NULL;
+ float cotangent[3];
+
+ for (eve = em->verts.first; eve; eve = eve->next)
+ {
+ if ( eve->f & SELECT ) {
+ if (v1 == NULL) {
+ v1 = eve;
+ }
+ else if (v2 == NULL) {
+ v2 = eve;
+ }
+ else {
+ v3 = eve;
+
+ VecSubf(plane, v2->co, v1->co);
+ VecSubf(cotangent, v3->co, v2->co);
+ Crossf(normal, cotangent, plane);
+ break;
+ }
+ }
+ }
+
+ /* if there's an edge available, use that for the tangent */
+ if (G.totedgesel >= 1)
+ {
+ EditEdge *eed = NULL;
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f & SELECT) {
+ VecSubf(plane, eed->v2->co, eed->v1->co);
+ break;
+ }
+ }
+ }
+
+ result = ORIENTATION_FACE;
+ }
+ else if (G.totedgesel == 1)
+ {
+ EditEdge *eed;
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f & SELECT) {
+ /* use average vert normals as plane and edge vector as normal */
+ VECCOPY(plane, eed->v1->no);
+ VECADD(plane, plane, eed->v2->no);
+ VecSubf(normal, eed->v2->co, eed->v1->co);
+ break;
+ }
+ }
+ result = ORIENTATION_EDGE;
+ }
+ else if (G.totvertsel == 2)
+ {
+ EditVert *v1 = NULL, *v2 = NULL;
+
+ for (eve = em->verts.first; eve; eve = eve->next)
+ {
+ if ( eve->f & SELECT ) {
+ if (v1 == NULL) {
+ v1 = eve;
+ }
+ else {
+ v2 = eve;
+
+ VECCOPY(plane, v1->no);
+ VECADD(plane, plane, v2->no);
+ VecSubf(normal, v2->co, v1->co);
+ break;
+ }
+ }
+ }
+ result = ORIENTATION_EDGE;
+ }
+ else if (G.totvertsel == 1)
+ {
+ for (eve = em->verts.first; eve; eve = eve->next)
+ {
+ if ( eve->f & SELECT ) {
+ VECCOPY(normal, eve->no);
+ break;
+ }
+ }
+ result = ORIENTATION_VERT;
+ }
+ else if (G.totvertsel > 3)
+ {
+ normal[0] = normal[1] = normal[2] = 0;
+
+ for (eve = em->verts.first; eve; eve = eve->next)
+ {
+ if ( eve->f & SELECT ) {
+ VecAddf(normal, normal, eve->no);
+ }
+ }
+ Normalize(normal);
+ result = ORIENTATION_VERT;
+ }
+ }
+ } /* end editmesh */
+ else if ELEM3(G.obedit->type, OB_CURVE, OB_SURF, OB_FONT)
+ {
+ extern ListBase editNurb; /* BOOO! go away stupid extern */
+ Nurb *nu;
+ BezTriple *bezt;
+ int a;
+
+ for (nu = editNurb.first; nu; nu = nu->next)
+ {
+ /* only bezier has a normal */
+ if((nu->type & 7) == CU_BEZIER)
+ {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--)
+ {
+ /* exception */
+ if ( (bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT )
+ {
+ VecSubf(normal, bezt->vec[0], bezt->vec[2]);
+ }
+ else
+ {
+ if(bezt->f1)
+ {
+ VecSubf(normal, bezt->vec[0], bezt->vec[1]);
+ }
+ if(bezt->f2)
+ {
+ VecSubf(normal, bezt->vec[0], bezt->vec[2]);
+ }
+ if(bezt->f3)
+ {
+ VecSubf(normal, bezt->vec[1], bezt->vec[2]);
+ }
+ }
+ bezt++;
+ }
+ }
+ }
+
+ if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0)
+ {
+ result = ORIENTATION_NORMAL;
+ }
+ }
+ else if(G.obedit->type==OB_MBALL)
+ {
+ /* editmball.c */
+ extern ListBase editelems; /* go away ! */
+ MetaElem *ml, *ml_sel = NULL;
+
+ /* loop and check that only one element is selected */
+ for (ml = editelems.first; ml; ml = ml->next)
+ {
+ if (ml->flag & SELECT) {
+ if (ml_sel == NULL)
+ {
+ ml_sel = ml;
+ }
+ else
+ {
+ ml_sel = NULL;
+ break;
+ }
+ }
+ }
+
+ if (ml_sel)
+ {
+ float mat[4][4];
+
+ /* Rotation of MetaElem is stored in quat */
+ QuatToMat4(ml_sel->quat, mat);
+
+ VECCOPY(normal, mat[2]);
+ VECCOPY(plane, mat[1]);
+
+ VecMulf(plane, -1.0);
+
+ result = ORIENTATION_NORMAL;
+ }
+ }
+
+ Mat4Mul3Vecfl(G.obedit->obmat, plane);
+ Mat4Mul3Vecfl(G.obedit->obmat, normal);
+ }
+ else if(ob && (ob->flag & OB_POSEMODE))
+ {
+ }
+ else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
+ {
+ }
+ else if(G.f & G_PARTICLEEDIT)
+ {
+ }
+ else {
+ /* we need the one selected object, if its not active */
+ ob = OBACT;
+ if(ob && !(ob->flag & SELECT)) ob = NULL;
+
+ for(base= G.scene->base.first; base; base= base->next) {
+ if TESTBASELIB(base) {
+ if(ob == NULL) {
+ ob= base->object;
+ break;
+ }
+ }
+ }
+
+ VECCOPY(normal, ob->obmat[2]);
+ VECCOPY(plane, ob->obmat[1]);
+ result = ORIENTATION_NORMAL;
+ }
+
+ return result;
+}
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c
index 5b4ead1f519..23bfaf048df 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -56,6 +56,8 @@
#include "BIF_mywindow.h"
#include "BIF_resources.h"
#include "BIF_screen.h"
+#include "BIF_editsima.h"
+#include "BIF_drawimage.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -76,6 +78,7 @@ void setSnappingCallback(TransInfo *t);
void ApplySnapTranslation(TransInfo *t, float vec[3]);
void ApplySnapRotation(TransInfo *t, float *vec);
+void ApplySnapResize(TransInfo *t, float *vec);
void CalcSnapGrid(TransInfo *t, float *vec);
void CalcSnapGeometry(TransInfo *t, float *vec);
@@ -83,45 +86,98 @@ void CalcSnapGeometry(TransInfo *t, float *vec);
void TargetSnapMedian(TransInfo *t);
void TargetSnapCenter(TransInfo *t);
void TargetSnapClosest(TransInfo *t);
+void TargetSnapActive(TransInfo *t);
float RotationBetween(TransInfo *t, float p1[3], float p2[3]);
float TranslationBetween(TransInfo *t, float p1[3], float p2[3]);
+float ResizeBetween(TransInfo *t, float p1[3], float p2[3]);
-// Trickery
-int findNearestVertFromObjects(int *dist, float *loc);
+/* Modes */
+#define NOT_SELECTED 0
+#define NOT_ACTIVE 1
+int findNearestVertFromObjects(int *dist, float *loc, int mode);
/****************** IMPLEMENTATIONS *********************/
+int BIF_snappingSupported(void)
+{
+ int status = 0;
+
+ if (G.obedit == NULL || G.obedit->type==OB_MESH) /* only support object or mesh */
+ {
+ status = 1;
+ }
+
+ return status;
+}
+
void drawSnapping(TransInfo *t)
{
if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
(G.qual & LR_CTRLKEY)) {
- float unitmat[4][4];
- float size;
- char col[4];
-
- glDisable(GL_DEPTH_TEST);
-
- size = get_drawsize(G.vd);
-
- size *= 0.5f * BIF_GetThemeValuef(TH_VERTEX_SIZE);
+ char col[4];
BIF_GetThemeColor3ubv(TH_TRANSFORM, col);
glColor4ub(col[0], col[1], col[2], 128);
- glPushMatrix();
-
- glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
-
- /* sets view screen aligned */
- glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]);
-
- Mat4One(unitmat);
- drawcircball(GL_LINE_LOOP, unitmat[3], size, unitmat);
-
- glPopMatrix();
-
- if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ if (t->spacetype==SPACE_VIEW3D) {
+ float unitmat[4][4];
+ float size;
+
+ glDisable(GL_DEPTH_TEST);
+
+ size = get_drawsize(G.vd, t->tsnap.snapPoint);
+
+ size *= 0.5f * BIF_GetThemeValuef(TH_VERTEX_SIZE);
+
+ glPushMatrix();
+
+ glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
+
+ /* sets view screen aligned */
+ glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]);
+
+ Mat4One(unitmat);
+ drawcircball(GL_LINE_LOOP, unitmat[3], size, unitmat);
+
+ glPopMatrix();
+
+ if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ } else if (t->spacetype==SPACE_IMAGE) {
+ /*This will not draw, and Im nor sure why - campbell */
+
+ /*
+ float xuser_asp, yuser_asp;
+ int wi, hi;
+ float w, h;
+
+ calc_image_view(G.sima, 'f'); // float
+ myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+ glLoadIdentity();
+
+ aspect_sima(G.sima, &xuser_asp, &yuser_asp);
+
+ transform_width_height_tface_uv(&wi, &hi);
+ w = (((float)wi)/256.0f)*G.sima->zoom * xuser_asp;
+ h = (((float)hi)/256.0f)*G.sima->zoom * yuser_asp;
+
+ cpack(0xFFFFFF);
+ glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], 0.0f);
+
+ //glRectf(0,0,1,1);
+
+ setlinestyle(0);
+ cpack(0x0);
+ fdrawline(-0.020/w, 0, -0.1/w, 0);
+ fdrawline(0.1/w, 0, .020/w, 0);
+ fdrawline(0, -0.020/h, 0, -0.1/h);
+ fdrawline(0, 0.1/h, 0, 0.020/h);
+
+ glTranslatef(-t->tsnap.snapPoint[0], -t->tsnap.snapPoint[1], 0.0f);
+ setlinestyle(0);
+ */
+
+ }
}
}
@@ -129,7 +185,13 @@ int handleSnapping(TransInfo *t, int event)
{
int status = 0;
- // Put keyhandling code here
+ if (BIF_snappingSupported() && event == TABKEY && (G.qual & LR_SHIFTKEY) == LR_SHIFTKEY)
+ {
+ /* toggle snap and reinit */
+ G.scene->snap_flag ^= SCE_SNAP;
+ initSnapping(t);
+ status = 1;
+ }
return status;
}
@@ -169,13 +231,22 @@ void initSnapping(TransInfo *t)
{
resetSnapping(t);
- if (t->spacetype == SPACE_VIEW3D) { // Only 3D view (not UV)
+ if (t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) { // Only 3D view or UV
setSnappingCallback(t);
+ /* Edit mode */
if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+ (G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
(G.obedit != NULL && G.obedit->type==OB_MESH) && // Temporary limited to edit mode meshes
- (G.vd->flag2 & V3D_TRANSFORM_SNAP) && // Only if the snap flag is on
- (t->flag & T_PROP_EDIT) == 0) // No PET, obviously
+ ((t->flag & T_PROP_EDIT) == 0) ) // No PET, obviously
+ {
+ t->tsnap.status |= SNAP_ON;
+ t->tsnap.modePoint = SNAP_GEO;
+ }
+ /* Object mode */
+ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+ (G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
+ (G.obedit == NULL) ) // Object Mode
{
t->tsnap.status |= SNAP_ON;
t->tsnap.modePoint = SNAP_GEO;
@@ -197,20 +268,25 @@ void setSnappingCallback(TransInfo *t)
{
t->tsnap.calcSnap = CalcSnapGeometry;
- switch(G.vd->snap_target)
+ switch(G.scene->snap_target)
{
- case V3D_SNAP_TARGET_CLOSEST:
+ case SCE_SNAP_TARGET_CLOSEST:
t->tsnap.modeTarget = SNAP_CLOSEST;
t->tsnap.targetSnap = TargetSnapClosest;
break;
- case V3D_SNAP_TARGET_CENTER:
+ case SCE_SNAP_TARGET_CENTER:
t->tsnap.modeTarget = SNAP_CENTER;
t->tsnap.targetSnap = TargetSnapCenter;
break;
- case V3D_SNAP_TARGET_MEDIAN:
+ case SCE_SNAP_TARGET_MEDIAN:
t->tsnap.modeTarget = SNAP_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
break;
+ case SCE_SNAP_TARGET_ACTIVE:
+ t->tsnap.modeTarget = SNAP_ACTIVE;
+ t->tsnap.targetSnap = TargetSnapActive;
+ break;
+
}
switch (t->mode)
@@ -224,7 +300,17 @@ void setSnappingCallback(TransInfo *t)
t->tsnap.distance = RotationBetween;
// Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead
- if (G.vd->snap_target == V3D_SNAP_TARGET_CENTER) {
+ if (G.scene->snap_target == SCE_SNAP_TARGET_CENTER) {
+ t->tsnap.modeTarget = SNAP_MEDIAN;
+ t->tsnap.targetSnap = TargetSnapMedian;
+ }
+ break;
+ case TFM_RESIZE:
+ t->tsnap.applySnap = ApplySnapResize;
+ t->tsnap.distance = ResizeBetween;
+
+ // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead
+ if (G.scene->snap_target == SCE_SNAP_TARGET_CENTER) {
t->tsnap.modeTarget = SNAP_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
}
@@ -252,6 +338,15 @@ void ApplySnapRotation(TransInfo *t, float *vec)
}
}
+void ApplySnapResize(TransInfo *t, float vec[3])
+{
+ if (t->tsnap.modeTarget == SNAP_CLOSEST) {
+ vec[0] = vec[1] = vec[2] = t->tsnap.dist;
+ }
+ else {
+ vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
+ }
+}
/********************** DISTANCE **************************/
@@ -316,6 +411,27 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3])
return angle;
}
+float ResizeBetween(TransInfo *t, float p1[3], float p2[3])
+{
+ float d1[3], d2[3], center[3];
+
+ VECCOPY(center, t->center);
+ if(t->flag & (T_EDIT|T_POSE)) {
+ Object *ob= G.obedit?G.obedit:t->poseobj;
+ Mat4MulVecfl(ob->obmat, center);
+ }
+
+ VecSubf(d1, p1, center);
+ VecSubf(d2, p2, center);
+
+ if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
+ Mat3MulVecfl(t->con.pmtx, d1);
+ Mat3MulVecfl(t->con.pmtx, d2);
+ }
+
+ return VecLength(d2) / VecLength(d1);
+}
+
/********************** CALC **************************/
void CalcSnapGrid(TransInfo *t, float *vec)
@@ -325,9 +441,34 @@ void CalcSnapGrid(TransInfo *t, float *vec)
void CalcSnapGeometry(TransInfo *t, float *vec)
{
- if (G.obedit != NULL && G.obedit->type==OB_MESH)
+ /* Object mode */
+ if (G.obedit == NULL)
+ {
+ if (t->spacetype == SPACE_VIEW3D)
+ {
+ float vec[3];
+ int found = 0;
+ int dist = 40; // Use a user defined value here
+
+ found = findNearestVertFromObjects(&dist, vec, NOT_SELECTED);
+ if (found == 1)
+ {
+ VECCOPY(t->tsnap.snapPoint, vec);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
+ }
+ }
+ /* Mesh edit mode */
+ else if (G.obedit != NULL && G.obedit->type==OB_MESH)
{
/*if (G.scene->selectmode & B_SEL_VERT)*/
+
+ if (t->spacetype == SPACE_VIEW3D)
{
EditVert *nearest=NULL;
float vec[3];
@@ -337,7 +478,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
// use findnearestverts in vert mode, others in other modes
nearest = findnearestvert(&dist, SELECT, 1);
- found = findNearestVertFromObjects(&dist, vec);
+ found = findNearestVertFromObjects(&dist, vec, NOT_ACTIVE);
if (found == 1)
{
VECCOPY(t->tsnap.snapPoint, vec);
@@ -358,6 +499,33 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
t->tsnap.status &= ~POINT_INIT;
}
}
+ else if (t->spacetype == SPACE_IMAGE)
+ { /* same as above but for UV's */
+ MTFace *nearesttf=NULL;
+ float aspx, aspy;
+ int face_corner;
+
+ find_nearest_uv(&nearesttf, NULL, NULL, &face_corner);
+
+ if (nearesttf != NULL)
+ {
+ VECCOPY2D(t->tsnap.snapPoint, nearesttf->uv[face_corner]);
+
+ transform_aspect_ratio_tface_uv(&aspx, &aspy);
+ t->tsnap.snapPoint[0] *= aspx;
+ t->tsnap.snapPoint[1] *= aspy;
+
+ //Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
+ }
+
+
/*
if (G.scene->selectmode & B_SEL_EDGE)
{
@@ -403,20 +571,60 @@ void TargetSnapCenter(TransInfo *t)
}
}
+void TargetSnapActive(TransInfo *t)
+{
+ // Only need to calculate once
+ if ((t->tsnap.status & TARGET_INIT) == 0)
+ {
+ TransData *td = NULL;
+ TransData *active_td = NULL;
+ int i;
+
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
+ {
+ if (td->flag & TD_ACTIVE)
+ {
+ active_td = td;
+ break;
+ }
+ }
+
+ if (active_td)
+ {
+ VECCOPY(t->tsnap.snapTarget, active_td->center);
+
+ if(t->flag & (T_EDIT|T_POSE)) {
+ Object *ob= G.obedit?G.obedit:t->poseobj;
+ Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ }
+
+ t->tsnap.status |= TARGET_INIT;
+ }
+ /* No active, default to median */
+ else
+ {
+ t->tsnap.modeTarget = SNAP_MEDIAN;
+ t->tsnap.targetSnap = TargetSnapMedian;
+ TargetSnapMedian(t);
+ }
+ }
+}
+
void TargetSnapMedian(TransInfo *t)
{
// Only need to calculate once
if ((t->tsnap.status & TARGET_INIT) == 0)
{
TransData *td = NULL;
+ int i;
t->tsnap.snapTarget[0] = 0;
t->tsnap.snapTarget[1] = 0;
t->tsnap.snapTarget[2] = 0;
- for (td = t->data; td != NULL && td->flag & TD_SELECTED ; td++)
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
{
- VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->iloc);
+ VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->center);
}
VecMulf(t->tsnap.snapTarget, 1.0 / t->total);
@@ -437,27 +645,64 @@ void TargetSnapClosest(TransInfo *t)
{
TransData *closest = NULL, *td = NULL;
- // Base case, only one selected item
- if (t->total == 1)
+ /* Object mode */
+ if (t->flag & T_OBJECT)
{
- VECCOPY(t->tsnap.snapTarget, t->data[0].iloc);
-
- if(t->flag & (T_EDIT|T_POSE)) {
- Object *ob= G.obedit?G.obedit:t->poseobj;
- Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ int i;
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
+ {
+ struct BoundBox *bb = object_get_boundbox(td->ob);
+
+ /* use boundbox if possible */
+ if (bb)
+ {
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ float loc[3];
+ float dist;
+
+ VECCOPY(loc, bb->vec[j]);
+ Mat4MulVecfl(td->ext->obmat, loc);
+
+ dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
+
+ if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist))
+ {
+ VECCOPY(t->tsnap.snapTarget, loc);
+ closest = td;
+ t->tsnap.dist = dist;
+ }
+ }
+ }
+ /* use element center otherwise */
+ else
+ {
+ float loc[3];
+ float dist;
+
+ VECCOPY(loc, td->center);
+
+ dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
+
+ if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist))
+ {
+ VECCOPY(t->tsnap.snapTarget, loc);
+ closest = td;
+ t->tsnap.dist = dist;
+ }
+ }
}
-
- t->tsnap.dist = t->tsnap.distance(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
}
- // More than one selected item
else
- {
- for (td = t->data; td != NULL && td->flag & TD_SELECTED ; td++)
+ {
+ int i;
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
{
float loc[3];
float dist;
- VECCOPY(loc, td->iloc);
+ VECCOPY(loc, td->center);
if(t->flag & (T_EDIT|T_POSE)) {
Object *ob= G.obedit?G.obedit:t->poseobj;
@@ -480,7 +725,7 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-int findNearestVertFromObjects(int *dist, float *loc) {
+int findNearestVertFromObjects(int *dist, float *loc, int mode) {
Base *base;
int retval = 0;
short mval[2];
@@ -489,7 +734,7 @@ int findNearestVertFromObjects(int *dist, float *loc) {
base= FIRSTBASE;
for ( base = FIRSTBASE; base != NULL; base = base->next ) {
- if ( TESTBASE(base) && base != BASACT ) {
+ if ( BASE_SELECTABLE(base) && ((mode == NOT_SELECTED && (base->flag & SELECT) == 0) || (mode == NOT_ACTIVE && base != BASACT)) ) {
Object *ob = base->object;
if (ob->type == OB_MESH) {
diff --git a/source/blender/src/unwrapper.c b/source/blender/src/unwrapper.c
index d92508f7729..061165042d8 100644
--- a/source/blender/src/unwrapper.c
+++ b/source/blender/src/unwrapper.c
@@ -49,13 +49,16 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
#include "BLI_arithb.h"
#include "BLI_edgehash.h"
+#include "BLI_editVert.h"
#include "BIF_editsima.h"
#include "BIF_space.h"
#include "BIF_screen.h"
+#include "BIF_editmesh.h"
#include "blendef.h"
#include "mydevice.h"
@@ -188,45 +191,52 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
}
/* Parametrizer */
-
-ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill, short sel)
+ParamHandle *construct_param_handle(EditMesh *em, short implicit, short fill, short sel)
{
int a;
MTFace *tf;
- MFace *mf;
- MVert *mv;
- MEdge *medge;
+
+ EditFace *efa;
+ EditEdge *eed;
+ EditVert *ev;
+
ParamHandle *handle;
handle = param_construct_begin();
- mv= me->mvert;
- mf= me->mface;
- tf= me->mtface;
- for (a=0; a<me->totface; a++, mf++, tf++) {
+ /* we need the vert indicies */
+ for (ev= em->verts.first, a=0; ev; ev= ev->next, a++)
+ ev->tmp.l = a;
+
+ for (efa= em->faces.first; efa; efa= efa->next) {
ParamKey key, vkeys[4];
ParamBool pin[4], select[4];
float *co[4];
float *uv[4];
int nverts;
-
- if (mf->flag & ME_HIDE)
- continue;
-
- if (sel && !(mf->flag & ME_FACE_SEL))
+
+ if ((efa->h) || (sel && (efa->f & SELECT)==0))
continue;
- if (implicit && !(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
+ tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+
+ if (implicit &&
+ !( simaUVSel_Check(efa, tf, 0) ||
+ simaUVSel_Check(efa, tf, 1) ||
+ simaUVSel_Check(efa, tf, 2) ||
+ (efa->v4 && simaUVSel_Check(efa, tf, 3)) )
+ ) {
continue;
+ }
- key = (ParamKey)mf;
- vkeys[0] = (ParamKey)mf->v1;
- vkeys[1] = (ParamKey)mf->v2;
- vkeys[2] = (ParamKey)mf->v3;
+ key = (ParamKey)efa;
+ vkeys[0] = (ParamKey)efa->v1->tmp.l;
+ vkeys[1] = (ParamKey)efa->v2->tmp.l;
+ vkeys[2] = (ParamKey)efa->v3->tmp.l;
- co[0] = (mv+mf->v1)->co;
- co[1] = (mv+mf->v2)->co;
- co[2] = (mv+mf->v3)->co;
+ co[0] = efa->v1->co;
+ co[1] = efa->v2->co;
+ co[2] = efa->v3->co;
uv[0] = tf->uv[0];
uv[1] = tf->uv[1];
@@ -236,16 +246,16 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill, short
pin[1] = ((tf->unwrap & TF_PIN2) != 0);
pin[2] = ((tf->unwrap & TF_PIN3) != 0);
- select[0] = ((tf->flag & TF_SEL1) != 0);
- select[1] = ((tf->flag & TF_SEL2) != 0);
- select[2] = ((tf->flag & TF_SEL3) != 0);
+ select[0] = ((simaUVSel_Check(efa, tf, 0)) != 0);
+ select[1] = ((simaUVSel_Check(efa, tf, 1)) != 0);
+ select[2] = ((simaUVSel_Check(efa, tf, 2)) != 0);
- if (mf->v4) {
- vkeys[3] = (ParamKey)mf->v4;
- co[3] = (mv+mf->v4)->co;
+ if (efa->v4) {
+ vkeys[3] = (ParamKey)efa->v4->tmp.l;
+ co[3] = efa->v4->co;
uv[3] = tf->uv[3];
pin[3] = ((tf->unwrap & TF_PIN4) != 0);
- select[3] = ((tf->flag & TF_SEL4) != 0);
+ select[3] = (simaUVSel_Check(efa, tf, 3) != 0);
nverts = 4;
}
else
@@ -255,12 +265,11 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill, short
}
if (!implicit) {
- for(medge=me->medge, a=me->totedge; a>0; a--, medge++) {
- if(medge->flag & ME_SEAM) {
+ for (eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->seam) {
ParamKey vkeys[2];
-
- vkeys[0] = (ParamKey)medge->v1;
- vkeys[1] = (ParamKey)medge->v2;
+ vkeys[0] = (ParamKey)eed->v1->tmp.l;
+ vkeys[1] = (ParamKey)eed->v2->tmp.l;
param_edge_set_seam(handle, vkeys);
}
}
@@ -271,17 +280,36 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill, short
return handle;
}
+
+extern int EM_texFaceCheck(void);
+
void unwrap_lscm(short seamcut)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
ParamHandle *handle;
short abf = G.scene->toolsettings->unwrapper == 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ /* add uvs if there not here */
+ if (!EM_texFaceCheck()) {
+ if (em && em->faces.first)
+ EM_add_data_layer(&em->fdata, CD_MTFACE);
+
+ if (!EM_texFaceCheck())
+ return;
+
+ /* select new UV's */
+ if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) {
+ EditFace *efa;
+ MTFace *tf;
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ simaFaceSel_Set(efa, tf);
+ }
+ }
+ }
- handle = construct_param_handle(me, 0, fillholes, seamcut == 0);
+ handle = construct_param_handle(em, 0, fillholes, seamcut == 0);
param_lscm_begin(handle, PARAM_FALSE, abf);
param_lscm_solve(handle);
@@ -304,17 +332,16 @@ void unwrap_lscm(short seamcut)
void minimize_stretch_tface_uv(void)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
ParamHandle *handle;
double lasttime;
short doit = 1, escape = 0, val, blend = 0;
unsigned short event = 0;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
- me = get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(!EM_texFaceCheck()) return;
- handle = construct_param_handle(me, 1, fillholes, 1);
+ handle = construct_param_handle(em, 1, fillholes, 1);
lasttime = PIL_check_seconds_timer();
@@ -397,18 +424,38 @@ void minimize_stretch_tface_uv(void)
void pack_charts_tface_uv(void)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
ParamHandle *handle;
- me = get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(!EM_texFaceCheck()) return;
- handle = construct_param_handle(me, 1, 0, 1);
+ handle = construct_param_handle(em, 1, 0, 1);
param_pack(handle);
param_flush(handle);
param_delete(handle);
- BIF_undo_push("UV pack charts");
+ BIF_undo_push("UV pack islands");
+
+ object_uvs_changed(OBACT);
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIMAGE, 0);
+}
+
+
+void average_charts_tface_uv(void)
+{
+ EditMesh *em = G.editMesh;
+ ParamHandle *handle;
+
+ if(!EM_texFaceCheck()) return;
+
+ handle = construct_param_handle(em, 1, 0, 1);
+ param_average(handle);
+ param_flush(handle);
+ param_delete(handle);
+
+ BIF_undo_push("UV average island scale");
object_uvs_changed(OBACT);
@@ -422,14 +469,13 @@ static ParamHandle *liveHandle = NULL;
void unwrap_lscm_live_begin(void)
{
- Mesh *me;
+ EditMesh *em = G.editMesh;
short abf = G.scene->toolsettings->unwrapper == 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
- me= get_mesh(OBACT);
- if(me==0 || me->mtface==0) return;
+ if(!EM_texFaceCheck()) return;
- liveHandle = construct_param_handle(me, 0, fillholes, 1);
+ liveHandle = construct_param_handle(em, 0, fillholes, 1);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c
index 020eb502765..7ed1c430431 100644
--- a/source/blender/src/usiblender.c
+++ b/source/blender/src/usiblender.c
@@ -74,6 +74,7 @@
#include "BKE_blender.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_exotic.h"
#include "BKE_font.h"
#include "BKE_global.h"
@@ -81,7 +82,9 @@
#include "BKE_mball.h"
#include "BKE_node.h"
#include "BKE_packedFile.h"
+#include "BKE_texture.h"
#include "BKE_utildefines.h"
+#include "BKE_pointcache.h"
#ifdef WITH_VERSE
#include "BKE_verse.h"
@@ -94,12 +97,14 @@
#include "BIF_interface.h"
#include "BIF_usiblender.h"
#include "BIF_drawtext.h"
+#include "BIF_editaction.h"
#include "BIF_editarmature.h"
#include "BIF_editlattice.h"
#include "BIF_editfont.h"
#include "BIF_editmesh.h"
#include "BIF_editmode_undo.h"
#include "BIF_editsound.h"
+#include "BIF_filelist.h"
#include "BIF_poseobject.h"
#include "BIF_previewrender.h"
#include "BIF_renderwin.h"
@@ -173,9 +178,7 @@ static void init_userdef_file(void)
}
if(U.mixbufsize==0) U.mixbufsize= 2048;
if (BLI_streq(U.tempdir, "/")) {
- char *tmp= getenv("TEMP");
-
- strcpy(U.tempdir, tmp?tmp:"/tmp/");
+ BLI_where_is_temp(U.tempdir, 0);
}
if (U.savetime <= 0) {
U.savetime = 1;
@@ -197,6 +200,19 @@ static void init_userdef_file(void)
U.ndof_rotate = 100;
}
+ if(U.flag & USER_CUSTOM_RANGE)
+ vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */
+
+ /* Auto-keyframing settings */
+ if(U.autokey_mode == 0) {
+ /* AUTOKEY_MODE_NORMAL - AUTOKEY_ON = x <==> 3 - 1 = 2 */
+ U.autokey_mode |= 2;
+
+ if(U.flag & (1<<15)) U.autokey_flag |= AUTOKEY_FLAG_INSERTAVAIL;
+ if(U.flag & (1<<19)) U.autokey_flag |= AUTOKEY_FLAG_INSERTNEEDED;
+ if(G.flags & (1<<30)) U.autokey_flag |= AUTOKEY_FLAG_AUTOMATKEY;
+ }
+
if (G.main->versionfile <= 191) {
strcpy(U.plugtexdir, U.textudir);
strcpy(U.sounddir, "/");
@@ -365,6 +381,100 @@ static void init_userdef_file(void)
/* set default number of recently-used files (if not set) */
if (U.recent_files == 0) U.recent_files = 10;
}
+ if (G.main->versionfile < 245 || (G.main->versionfile == 245 && G.main->subversionfile < 3)) {
+ bTheme *btheme;
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
+ }
+ if(U.coba_weight.tot==0)
+ init_colorband(&U.coba_weight, 1);
+ }
+ if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 11)) {
+ bTheme *btheme;
+ for (btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* these should all use the same colour */
+ SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tipo.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255);
+ }
+ }
+ if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 13)) {
+ bTheme *btheme;
+ for (btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* action channel groups (recolour anyway) */
+ SETCOL(btheme->tact.group, 0x39, 0x7d, 0x1b, 255);
+ SETCOL(btheme->tact.group_active, 0x7d, 0xe9, 0x60, 255);
+
+ /* bone custom-color sets */
+ // FIXME: this check for initialised colors is bad
+ if (btheme->tarm[0].solid[3] == 0) {
+ /* set 1 */
+ SETCOL(btheme->tarm[0].solid, 0x9a, 0x00, 0x00, 255);
+ SETCOL(btheme->tarm[0].select, 0xbd, 0x11, 0x11, 255);
+ SETCOL(btheme->tarm[0].active, 0xf7, 0x0a, 0x0a, 255);
+ /* set 2 */
+ SETCOL(btheme->tarm[1].solid, 0xf7, 0x40, 0x18, 255);
+ SETCOL(btheme->tarm[1].select, 0xf6, 0x69, 0x13, 255);
+ SETCOL(btheme->tarm[1].active, 0xfa, 0x99, 0x00, 255);
+ /* set 3 */
+ SETCOL(btheme->tarm[2].solid, 0x1e, 0x91, 0x09, 255);
+ SETCOL(btheme->tarm[2].select, 0x59, 0xb7, 0x0b, 255);
+ SETCOL(btheme->tarm[2].active, 0x83, 0xef, 0x1d, 255);
+ /* set 4 */
+ SETCOL(btheme->tarm[3].solid, 0x0a, 0x36, 0x94, 255);
+ SETCOL(btheme->tarm[3].select, 0x36, 0x67, 0xdf, 255);
+ SETCOL(btheme->tarm[3].active, 0x5e, 0xc1, 0xef, 255);
+ /* set 5 */
+ SETCOL(btheme->tarm[4].solid, 0xa9, 0x29, 0x4e, 255);
+ SETCOL(btheme->tarm[4].select, 0xc1, 0x41, 0x6a, 255);
+ SETCOL(btheme->tarm[4].active, 0xf0, 0x5d, 0x91, 255);
+ /* set 6 */
+ SETCOL(btheme->tarm[5].solid, 0x43, 0x0c, 0x78, 255);
+ SETCOL(btheme->tarm[5].select, 0x54, 0x3a, 0xa3, 255);
+ SETCOL(btheme->tarm[5].active, 0x87, 0x64, 0xd5, 255);
+ /* set 7 */
+ SETCOL(btheme->tarm[6].solid, 0x24, 0x78, 0x5a, 255);
+ SETCOL(btheme->tarm[6].select, 0x3c, 0x95, 0x79, 255);
+ SETCOL(btheme->tarm[6].active, 0x6f, 0xb6, 0xab, 255);
+ /* set 8 */
+ SETCOL(btheme->tarm[7].solid, 0x4b, 0x70, 0x7c, 255);
+ SETCOL(btheme->tarm[7].select, 0x6a, 0x86, 0x91, 255);
+ SETCOL(btheme->tarm[7].active, 0x9b, 0xc2, 0xcd, 255);
+ /* set 9 */
+ SETCOL(btheme->tarm[8].solid, 0xf4, 0xc9, 0x0c, 255);
+ SETCOL(btheme->tarm[8].select, 0xee, 0xc2, 0x36, 255);
+ SETCOL(btheme->tarm[8].active, 0xf3, 0xff, 0x00, 255);
+ /* set 10 */
+ SETCOL(btheme->tarm[9].solid, 0x1e, 0x20, 0x24, 255);
+ SETCOL(btheme->tarm[9].select, 0x48, 0x4c, 0x56, 255);
+ SETCOL(btheme->tarm[9].active, 0xff, 0xff, 0xff, 255);
+ /* set 11 */
+ SETCOL(btheme->tarm[10].solid, 0x6f, 0x2f, 0x6a, 255);
+ SETCOL(btheme->tarm[10].select, 0x98, 0x45, 0xbe, 255);
+ SETCOL(btheme->tarm[10].active, 0xd3, 0x30, 0xd6, 255);
+ /* set 12 */
+ SETCOL(btheme->tarm[11].solid, 0x6c, 0x8e, 0x22, 255);
+ SETCOL(btheme->tarm[11].select, 0x7f, 0xb0, 0x22, 255);
+ SETCOL(btheme->tarm[11].active, 0xbb, 0xef, 0x5b, 255);
+ /* set 13 */
+ SETCOL(btheme->tarm[12].solid, 0x8d, 0x8d, 0x8d, 255);
+ SETCOL(btheme->tarm[12].select, 0xb0, 0xb0, 0xb0, 255);
+ SETCOL(btheme->tarm[12].active, 0xde, 0xde, 0xde, 255);
+ /* set 14 */
+ SETCOL(btheme->tarm[13].solid, 0x83, 0x43, 0x26, 255);
+ SETCOL(btheme->tarm[13].select, 0x8b, 0x58, 0x11, 255);
+ SETCOL(btheme->tarm[13].active, 0xbd, 0x6a, 0x11, 255);
+ /* set 15 */
+ SETCOL(btheme->tarm[14].solid, 0x08, 0x31, 0x0e, 255);
+ SETCOL(btheme->tarm[14].select, 0x1c, 0x43, 0x0b, 255);
+ SETCOL(btheme->tarm[14].active, 0x34, 0x62, 0x2b, 255);
+ }
+ }
+ }
/* GL Texture Garbage Collection (variable abused above!) */
if (U.textimeout == 0) {
@@ -439,6 +549,8 @@ void BIF_read_file(char *name)
retval= BKE_read_exotic(name);
if (retval== 0) {
+ BIF_clear_tempfiles();
+
/* we didn't succeed, now try to read Blender file */
retval= BKE_read_file(name, NULL);
@@ -450,7 +562,7 @@ void BIF_read_file(char *name)
if(retval==2) init_userdef_file(); // in case a userdef is read from regular .blend
- G.relbase_valid = 1;
+ if (retval!=0) G.relbase_valid = 1;
undo_editmode_clear();
BKE_reset_undo();
@@ -489,6 +601,8 @@ int BIF_read_homefile(int from_memory)
int success;
struct TmpFont *tf;
+ BIF_clear_tempfiles();
+
BLI_clean(home);
tf= G.ttfdata.first;
@@ -534,13 +648,15 @@ int BIF_read_homefile(int from_memory)
static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
{
char pidstr[32];
+#ifdef WIN32
char subdir[9];
char savedir[FILE_MAXDIR];
+#endif
sprintf(pidstr, "%d.blend", abs(getpid()));
#ifdef WIN32
- if (!BLI_exists(U.tempdir)) {
+ if (!BLI_exists(btempdir)) {
BLI_strncpy(subdir, "autosave", sizeof(subdir));
BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
@@ -553,7 +669,7 @@ static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
}
#endif
- BLI_make_file_string("/", buf, U.tempdir, pidstr);
+ BLI_make_file_string("/", buf, btempdir, pidstr);
}
void BIF_read_autosavefile(void)
@@ -633,20 +749,23 @@ static void readBlog(void)
tmps[2]='\\';
tmps[3]=0;
- fsmenu_insert_entry(tmps, 0);
+ fsmenu_insert_entry(tmps, 0, 0);
}
}
/* Adding Desktop and My Documents */
- fsmenu_append_seperator();
+ fsmenu_append_separator();
SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
- fsmenu_insert_entry(folder, 0);
+ fsmenu_insert_entry(folder, 0, 0);
SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
- fsmenu_insert_entry(folder, 0);
+ fsmenu_insert_entry(folder, 0, 0);
- fsmenu_append_seperator();
+ fsmenu_append_separator();
}
+#else
+ /* add home dir on linux systems */
+ fsmenu_insert_entry(BLI_gethome(), 0, 0);
#endif
BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
@@ -656,16 +775,16 @@ static void readBlog(void)
char *line= l->link;
if (!BLI_streq(line, "")) {
- fsmenu_insert_entry(line, 0);
+ fsmenu_insert_entry(line, 0, 1);
}
}
- fsmenu_append_seperator();
+ fsmenu_append_separator();
/* add last saved file */
BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */
- fsmenu_insert_entry(name, 0);
+ fsmenu_insert_entry(name, 0, 0);
BLI_free_file_lines(lines);
}
@@ -742,11 +861,17 @@ static void do_history(char *name)
void BIF_write_file(char *target)
{
Library *li;
- int writeflags;
- char di[FILE_MAXDIR];
+ int writeflags, len;
+ char di[FILE_MAX];
char *err;
- if (BLI_streq(target, "")) return;
+ len = strlen(target);
+
+ if (len == 0) return;
+ if (len >= FILE_MAX) {
+ error("Path too long, cannot save");
+ return;
+ }
/* send the OnSave event */
if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript(&G.scene->id, SCRIPT_ONSAVE);
@@ -758,7 +883,7 @@ void BIF_write_file(char *target)
}
}
- if (!BLO_has_bfile_extension(target)) {
+ if (!BLO_has_bfile_extension(target) && (len+6 < FILE_MAX)) {
sprintf(di, "%s.blend", target);
} else {
strcpy(di, target);
@@ -826,6 +951,16 @@ void BIF_write_autosave(void)
BLO_write_file(tstr, write_flags, &err);
}
+/* remove temp files assosiated with this blend file when quitting, loading or saving in a new path */
+void BIF_clear_tempfiles( void )
+{
+ /* TODO - remove exr files from the temp dir */
+
+ if (!G.relbase_valid) { /* We could have pointcache saved in tyhe temp dir, if its there */
+ BKE_ptcache_remove();
+ }
+}
+
/* if global undo; remove tempsave, otherwise rename */
static void delete_autosave(void)
{
@@ -835,7 +970,7 @@ static void delete_autosave(void)
if (BLI_exists(tstr)) {
char str[FILE_MAXDIR+FILE_MAXFILE];
- BLI_make_file_string("/", str, U.tempdir, "quit.blend");
+ BLI_make_file_string("/", str, btempdir, "quit.blend");
if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
else BLI_rename(tstr, str);
@@ -891,6 +1026,8 @@ void BIF_init(void)
BIF_resources_init(); /* after homefile, to dynamically load an icon file based on theme settings */
+ BIF_filelist_init_icons();
+
init_gl_stuff(); /* drawview.c, after homefile */
readBlog();
BLI_strncpy(G.lib, G.sce, FILE_MAX);
@@ -904,6 +1041,9 @@ extern ListBase editelems;
void exit_usiblender(void)
{
struct TmpFont *tf;
+
+ BIF_clear_tempfiles();
+
tf= G.ttfdata.first;
while(tf)
{
@@ -944,6 +1084,7 @@ void exit_usiblender(void)
free_blender(); /* blender.c, does entire library */
free_matcopybuf();
free_ipocopybuf();
+ free_actcopybuf();
free_vertexpaint();
free_imagepaint();
@@ -970,9 +1111,18 @@ void exit_usiblender(void)
quicktime_exit();
#endif
+ /* undo free stuff */
+ undo_editmode_clear();
+
+ BKE_undo_save_quit(); // saves quit.blend if global undo is on
+ BKE_reset_undo();
+
if (!G.background) {
BIF_resources_free();
-
+
+ BIF_filelist_free_icons();
+
+ BIF_free_render_spare();
BIF_close_render_display();
mainwindow_close();
}
@@ -984,12 +1134,7 @@ void exit_usiblender(void)
if (copybuf) MEM_freeN(copybuf);
if (copybufinfo) MEM_freeN(copybufinfo);
- /* undo free stuff */
- undo_editmode_clear();
-
- BKE_undo_save_quit(); // saves quit.blend if global undo is on
- BKE_reset_undo();
-
+//
BLI_freelistN(&U.themes);
BIF_preview_free_dbase();
diff --git a/source/blender/src/verse_mesh.c b/source/blender/src/verse_mesh.c
index 8c7d6509502..d458e7f4c1c 100644
--- a/source/blender/src/verse_mesh.c
+++ b/source/blender/src/verse_mesh.c
@@ -677,7 +677,6 @@ void post_vertex_create(VerseVert *vvert)
if(em && (vvert->vertex)) {
struct EditVert *eve = (EditVert*)vvert->vertex;
VECCOPY(vvert->co, eve->co);
-/* printf("\tpost_vertex_create: %d send and NOT_OBSOLETE\n", vvert->id);*/
send_verse_vertex(vvert);
verse_callback_update(0);
@@ -1496,8 +1495,8 @@ void create_meshdata_from_geom_node(Mesh *me, VNode *vnode)
MEdge *medge = me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
for(i = BLI_edgehashIterator_new(edges); !BLI_edgehashIterator_isDone(i); BLI_edgehashIterator_step(i), ++medge) {
+ memset(medge, 0, sizeof(struct MEdge));
BLI_edgehashIterator_getKey(i, (int*)&medge->v1, (int*)&medge->v2);
- medge->crease = medge->pad = medge->flag = 0;
}
BLI_edgehashIterator_free(i);
}
diff --git a/source/blender/src/verse_object.c b/source/blender/src/verse_object.c
index fc937469d42..107aae59845 100644
--- a/source/blender/src/verse_object.c
+++ b/source/blender/src/verse_object.c
@@ -295,6 +295,7 @@ void b_verse_pop_node(VNode *vnode)
vbitmap->height,
vnode->name,
0,
+ 0,
color);
((Image*)vbitmap->image)->vnode = (void*)vnode;
sync_blender_image_with_verse_bitmap_node(vnode);
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 9c8f333e2f7..7491fc6fbc8 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -66,13 +66,16 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_object.h"
+#include "BKE_sculpt.h"
#include "BKE_utildefines.h"
+#include "BIF_transform.h"
+#include "BIF_editparticle.h"
#include "BIF_gl.h"
-#include "BIF_space.h"
-#include "BIF_mywindow.h"
#include "BIF_previewrender.h"
+#include "BIF_mywindow.h"
#include "BIF_retopo.h"
+#include "BIF_space.h"
#include "BIF_screen.h"
#include "BIF_toolbox.h"
@@ -86,6 +89,7 @@
#include "mydevice.h"
#include "blendef.h"
+#include "transform.h"
#include "PIL_time.h" /* smoothview */
#include <float.h>
@@ -153,6 +157,11 @@ void initgrabz(float x, float y, float z)
* (accounting for near zero values)
* */
if (G.vd->zfac < 1.e-6f && G.vd->zfac > -1.e-6f) G.vd->zfac = 1.0f;
+
+ /* Negative zfac means x, y, z was behind the camera (in perspective).
+ * This gives flipped directions, so revert back to ok default case.
+ */
+ if (G.vd->zfac < 0.0f) G.vd->zfac = 1.0f;
}
void window_to_3d(float *vec, short mx, short my)
@@ -718,7 +727,7 @@ void viewmove(int mode)
float reverse, oldquat[4], q1[4], si, phi, dist0;
float ofs[3], obofs[3]= {0.0f, 0.0f, 0.0f};
int firsttime=1;
- short mvalball[2], mval[2], mvalo[2];
+ short mvalball[2], mval[2], mvalo[2], mval_area[2];
short use_sel = 0;
short preview3d_event= 1;
@@ -754,6 +763,7 @@ void viewmove(int mode)
QUATCOPY(oldquat, G.vd->viewquat);
+ getmouseco_areawin(mval_area); /* for zoom to mouse loc */
getmouseco_sc(mvalo); /* work with screen coordinates because of trackball function */
mvalball[0]= mvalo[0]; /* needed for turntable to work */
mvalball[1]= mvalo[1];
@@ -926,9 +936,10 @@ void viewmove(int mode)
}
}
else if(mode==2) {
+ float zfac=1.0;
if(U.viewzoom==USER_ZOOM_CONT) {
// oldstyle zoom
- G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
+ zfac = 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
}
else if(U.viewzoom==USER_ZOOM_SCALE) {
int ctr[2], len1, len2;
@@ -940,14 +951,17 @@ void viewmove(int mode)
len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5;
len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5;
- G.vd->dist= dist0 * ((float)len2/len1);
+ zfac = dist0 * ((float)len2/len1) / G.vd->dist;
}
else { /* USER_ZOOM_DOLLY */
float len1 = (curarea->winrct.ymax - mval[1]) + 5;
float len2 = (curarea->winrct.ymax - mvalo[1]) + 5;
-
- G.vd->dist= dist0 * (2.0*((len2/len1)-1.0) + 1.0);
+ zfac = dist0 * (2.0*((len2/len1)-1.0) + 1.0) / G.vd->dist;
}
+
+ if(zfac != 1.0 && zfac*G.vd->dist > 0.001*G.vd->grid &&
+ zfac*G.vd->dist < 10.0*G.vd->far)
+ view_zoom_mouseloc(zfac, mval_area);
/* these limits are in toets.c too */
if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid;
@@ -997,7 +1011,49 @@ void viewmove(int mode)
BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
}
+
+void view_zoom_mouseloc(float dfac, short *mouseloc)
+{
+ if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ short vb[2];
+ float dvec[3];
+ float tvec[3];
+ float tpos[3];
+ float new_dist;
+
+ /* find the current window width and height */
+ vb[0] = G.vd->area->winx;
+ vb[1] = G.vd->area->winy;
+
+ tpos[0] = -G.vd->ofs[0];
+ tpos[1] = -G.vd->ofs[1];
+ tpos[2] = -G.vd->ofs[2];
+ /* Project cursor position into 3D space */
+ initgrabz(tpos[0], tpos[1], tpos[2]);
+ window_to_3d(dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
+
+ /* Calculate view target position for dolly */
+ tvec[0] = -(tpos[0] + dvec[0]);
+ tvec[1] = -(tpos[1] + dvec[1]);
+ tvec[2] = -(tpos[2] + dvec[2]);
+
+ /* Offset to target position and dolly */
+ new_dist = G.vd->dist * dfac;
+
+ VECCOPY(G.vd->ofs, tvec);
+ G.vd->dist = new_dist;
+
+ /* Calculate final offset */
+ dvec[0] = tvec[0] + dvec[0] * dfac;
+ dvec[1] = tvec[1] + dvec[1] * dfac;
+ dvec[2] = tvec[2] + dvec[2] * dfac;
+
+ VECCOPY(G.vd->ofs, dvec);
+ } else {
+ G.vd->dist *= dfac;
+ }
+}
void viewmoveNDOF(int mode)
{
@@ -1201,7 +1257,6 @@ void viewmoveNDOF(int mode)
}
-
/* Gets the lens and clipping values from a camera of lamp type object */
void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend)
{
@@ -1429,18 +1484,10 @@ void obmat_to_viewmat(Object *ob, short smooth)
/* dont set windows active in in here, is used by renderwin too */
void setviewmatrixview3d()
{
- Camera *cam;
-
if(G.vd->persp>=2) { /* obs/camera */
if(G.vd->camera) {
-
where_is_object(G.vd->camera);
obmat_to_viewmat(G.vd->camera, 0);
-
- if(G.vd->camera->type==OB_CAMERA) {
- cam= G.vd->camera->data;
- //if(cam->type==CAM_ORTHO) G.vd->viewmat[3][2]*= 100.0;
- }
}
else {
QuatToMat4(G.vd->viewquat, G.vd->viewmat);
@@ -1655,8 +1702,7 @@ void initlocalview()
if(G.vd->localvd) return;
- min[0]= min[1]= min[2]= 1.0e10;
- max[0]= max[1]= max[2]= -1.0e10;
+ INIT_MINMAX(min, max);
locallay= free_localbit();
@@ -1751,9 +1797,7 @@ void centerview() /* like a localview without local! */
float new_ofs[3];
float new_dist;
-
- min[0]= min[1]= min[2]= 1.0e10;
- max[0]= max[1]= max[2]= -1.0e10;
+ INIT_MINMAX(min, max);
if (G.f & G_WEIGHTPAINT) {
/* hardcoded exception, we look for the one selected armature */
@@ -1795,9 +1839,12 @@ void centerview() /* like a localview without local! */
}
}
}
- else if (G.f & G_FACESELECT) {
+ else if (FACESEL_PAINT_TEST) {
ok= minmax_tface(min, max);
}
+ else if (G.f & G_PARTICLEEDIT) {
+ ok= PE_minmax(min, max);
+ }
else {
Base *base= FIRSTBASE;
while(base) {
@@ -1929,8 +1976,7 @@ void view3d_home(int center)
max[0]= max[1]= max[2]= 0.0;
}
else {
- min[0]= min[1]= min[2]= 1.0e10;
- max[0]= max[1]= max[2]= -1.0e10;
+ INIT_MINMAX(min, max);
}
for(base= FIRSTBASE; base; base= base->next) {
diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c
index 1fbc8d43920..63ab0616162 100644
--- a/source/blender/src/vpaint.c
+++ b/source/blender/src/vpaint.c
@@ -51,11 +51,13 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
@@ -64,6 +66,7 @@
#include "BKE_armature.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_cloth.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_deform.h"
@@ -71,6 +74,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
@@ -103,14 +107,14 @@
#define VP_ADD 1
#define VP_SUB 2
#define VP_MUL 3
-#define VP_FILT 4
+#define VP_BLUR 4
#define VP_LIGHTEN 5
#define VP_DARKEN 6
#define MAXINDEX 512000
VPaint Gvp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT+VP_SPRAY, 0};
-VPaint Gwp= {1.0, 1.0, 1.0, 0.2, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT, 0};
+VPaint Gwp= {1.0, 1.0, 1.0, 1.0, 25.0, 1.0, 1.0, 0, VP_AREA+VP_SOFT, 0};
static int *get_indexarray(void)
{
@@ -177,7 +181,7 @@ void do_shared_vertexcol(Mesh *me)
mface= me->mface;
mcol= (char *)me->mcol;
for(a=me->totface; a>0; a--, mface++, mcol+=16) {
- if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
+ if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
scol= scolmain+4*mface->v1;
scol[0]++; scol[1]+= mcol[1]; scol[2]+= mcol[2]; scol[3]+= mcol[3];
scol= scolmain+4*mface->v2;
@@ -207,7 +211,7 @@ void do_shared_vertexcol(Mesh *me)
mface= me->mface;
mcol= (char *)me->mcol;
for(a=me->totface; a>0; a--, mface++, mcol+=16) {
- if(tface==0 || (tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
+ if((tface && tface->mode & TF_SHAREDCOL) || (G.f & G_FACESELECT)==0) {
scol= scolmain+4*mface->v1;
mcol[1]= scol[1]; mcol[2]= scol[2]; mcol[3]= scol[3];
scol= scolmain+4*mface->v2;
@@ -250,7 +254,9 @@ void make_vertexcol(int shade) /* single ob */
shadeMeshMCol(ob, me);
else
memset(me->mcol, 255, 4*sizeof(MCol)*me->totface);
-
+
+ if (me->mr) multires_load_cols(me);
+
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSEDIT, 0);
@@ -327,7 +333,7 @@ void clear_vpaint_selectedfaces()
ob= OBACT;
me= get_mesh(ob);
- if(me==0 || me->mtface==0 || me->totface==0) return;
+ if(me==0 || me->totface==0) return;
if(!me->mcol)
make_vertexcol(0);
@@ -698,7 +704,7 @@ static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
{
- if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) *col= mcol_blend( *col, paintcol, alpha);
+ if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) *col= mcol_blend( *col, paintcol, alpha);
else if(Gvp.mode==VP_ADD) *col= mcol_add( *col, paintcol, alpha);
else if(Gvp.mode==VP_SUB) *col= mcol_sub( *col, paintcol, alpha);
else if(Gvp.mode==VP_MUL) *col= mcol_mul( *col, paintcol, alpha);
@@ -712,7 +718,7 @@ static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int
alpha= (int)(255.0*Gvp.a);
- if(Gvp.mode==VP_MIX || Gvp.mode==VP_FILT) testcol= mcol_blend( *colorig, paintcol, alpha);
+ if(Gvp.mode==VP_MIX || Gvp.mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
else if(Gvp.mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
else if(Gvp.mode==VP_SUB) testcol= mcol_sub( *colorig, paintcol, alpha);
else if(Gvp.mode==VP_MUL) testcol= mcol_mul( *colorig, paintcol, alpha);
@@ -743,7 +749,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int
struct ImBuf *ibuf;
int x1, y1, x2, y2, a, tot=0, index;
- if(totface>=MAXINDEX) return 0;
+ if(totface+4>=MAXINDEX) return 0;
if(size>64.0) size= 64.0;
@@ -773,7 +779,7 @@ static int sample_backbuf_area(VPaint *vp, int *indexar, int totface, int x, int
size= (y2-y1)*(x2-x1);
if(size<=0) return 0;
- memset(indexar, 0, sizeof(int)*totface+2); /* plus 2! first element is total */
+ memset(indexar, 0, sizeof(int)*totface+4); /* plus 2! first element is total, +2 was giving valgrind errors, +4 seems ok */
while(size--) {
@@ -839,7 +845,7 @@ static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, floa
if(dw==NULL || uw==NULL) return;
- if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
+ if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
dw->weight = paintval*alpha + dw->weight*(1.0-alpha);
else if(Gwp.mode==VP_ADD)
dw->weight += paintval*alpha;
@@ -862,7 +868,7 @@ static void wpaint_blend(MDeformWeight *dw, MDeformWeight *uw, float alpha, floa
float testw=0.0f;
alpha= Gwp.a;
- if(Gwp.mode==VP_MIX || Gwp.mode==VP_FILT)
+ if(Gwp.mode==VP_MIX || Gwp.mode==VP_BLUR)
testw = paintval*alpha + uw->weight*(1.0-alpha);
else if(Gwp.mode==VP_ADD)
testw = uw->weight + paintval*alpha;
@@ -1087,7 +1093,7 @@ void weight_paint(void)
float vpimat[3][3];
int *indexar, index, totindex, alpha, totw;
int vgroup_mirror= -1;
- short mval[2], mvalo[2], firsttime=1, mousebut;
+ short mval[2], mvalo[2], firsttime=1;
if((G.f & G_WEIGHTPAINT)==0) return;
if(G.obedit) return;
@@ -1160,9 +1166,6 @@ void weight_paint(void)
mvalo[0]= mval[0];
mvalo[1]= mval[1];
- if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
- else mousebut = L_MOUSE;
-
/* if mirror painting, find the other group */
if(Gwp.flag & VP_MIRROR_X) {
bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1);
@@ -1188,7 +1191,7 @@ void weight_paint(void)
}
}
- while (get_mbut() & mousebut) {
+ while (get_mbut() & L_MOUSE) {
getmouseco_areawin(mval);
if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
@@ -1235,7 +1238,7 @@ void weight_paint(void)
/* make sure each vertex gets treated only once */
/* and calculate filter weight */
totw= 0;
- if(Gwp.mode==VP_FILT)
+ if(Gwp.mode==VP_BLUR)
paintweight= 0.0f;
else
paintweight= editbutvweight;
@@ -1249,7 +1252,7 @@ void weight_paint(void)
(me->dvert+mface->v3)->flag= 1;
if(mface->v4) (me->dvert+mface->v4)->flag= 1;
- if(Gwp.mode==VP_FILT) {
+ if(Gwp.mode==VP_BLUR) {
MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = verify_defweight;
if(Gwp.flag & VP_ONLYVGROUP)
@@ -1269,7 +1272,7 @@ void weight_paint(void)
}
}
- if(Gwp.mode==VP_FILT)
+ if(Gwp.mode==VP_BLUR)
paintweight/= (float)totw;
for(index=0; index<totindex; index++) {
@@ -1347,6 +1350,39 @@ void weight_paint(void)
/* this flag is event for softbody to refresh weightpaint values */
if(ob->soft) ob->softflag |= OB_SB_REDO;
+ /* same goes for cloth */
+ if(modifiers_isClothEnabled(ob)) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ if(clmd)
+ {
+ /* check if we use the edited vertex group at all */
+ if((clmd->sim_parms->vgroup_mass==ob->actdef) ||
+ (clmd->sim_parms->vgroup_struct==ob->actdef)||
+ (clmd->sim_parms->vgroup_bend==ob->actdef))
+ {
+ clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+ }
+ }
+ }
+
+ /* and particles too */
+ if(ob->particlesystem.first) {
+ ParticleSystem *psys;
+ int i;
+
+ psys= ob->particlesystem.first;
+ while(psys) {
+ for(i=0; i<PSYS_TOT_VG; i++) {
+ if(psys->vgroup[i]==ob->actdef) {
+ psys->recalc |= PSYS_RECALC_HAIR;
+ break;
+ }
+ }
+
+ psys= psys->next;
+ }
+ }
+
BIF_undo_push("Weight Paint");
allqueue(REDRAWVIEW3D, 0);
}
@@ -1360,7 +1396,7 @@ void vertex_paint()
float vpimat[3][3];
unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2;
int *indexar, index, alpha, totindex;
- short mval[2], mvalo[2], firsttime=1, mousebut;
+ short mval[2], mvalo[2], firsttime=1;
if((G.f & G_VERTEXPAINT)==0) return;
if(G.obedit) return;
@@ -1372,9 +1408,9 @@ void vertex_paint()
if(me==NULL || me->totface==0) return;
if(ob->lay & G.vd->lay); else error("Active object is not in this layer");
- if(me->mtface==NULL && me->mcol==NULL) make_vertexcol(1);
+ if(me->mcol==NULL) make_vertexcol(0);
- if(me->mtface==NULL && me->mcol==NULL) return;
+ if(me->mcol==NULL) return;
/* ALLOCATIONS! No return after his line */
@@ -1403,10 +1439,7 @@ void vertex_paint()
mvalo[0]= mval[0];
mvalo[1]= mval[1];
- if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
- else mousebut = L_MOUSE;
-
- while (get_mbut() & mousebut) {
+ while (get_mbut() & L_MOUSE) {
getmouseco_areawin(mval);
if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
@@ -1456,7 +1489,7 @@ void vertex_paint()
mcol= ( (unsigned int *)me->mcol) + 4*(indexar[index]-1);
mcolorig= ( (unsigned int *)Gvp.vpaint_prev) + 4*(indexar[index]-1);
- if(Gvp.mode==VP_FILT) {
+ if(Gvp.mode==VP_BLUR) {
fcol1= mcol_blend( mcol[0], mcol[1], 128);
if(mface->v4) {
fcol2= mcol_blend( mcol[2], mcol[3], 128);
@@ -1596,7 +1629,7 @@ void set_vpaint(void) /* toggle */
return;
}
- if(me && me->mcol==NULL) make_vertexcol(1);
+ if(me && me->mcol==NULL) make_vertexcol(0);
if(G.f & G_VERTEXPAINT){
G.f &= ~G_VERTEXPAINT;
diff --git a/source/blender/src/winlay.h b/source/blender/src/winlay.h
index b9539897dbb..32479a34a2c 100644
--- a/source/blender/src/winlay.h
+++ b/source/blender/src/winlay.h
@@ -89,3 +89,9 @@ Window* winlay_get_active_window(void);
void winlay_process_events (int wait_for_event);
void winlay_get_screensize (int *width_r, int *height_r);
+
+ /* Copy and paste functions in ghostwinlay.c */
+
+char *getClipboard(int flag);
+
+void putClipboard(char *buffer, int flag);
diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c
index ca3a312f98b..50d69fcdc76 100644
--- a/source/blender/src/writeimage.c
+++ b/source/blender/src/writeimage.c
@@ -148,9 +148,15 @@ void save_image_filesel_str(char *str)
case R_RADHDR:
strcpy(str, "Save Radiance HDR");
break;
+ case R_FFMPEG:
case R_PNG:
strcpy(str, "Save PNG");
break;
+#ifdef WITH_DDS
+ case R_DDS:
+ strcpy(str, "Save DDS");
+ break;
+#endif
case R_BMP:
strcpy(str, "Save BMP");
break;
diff --git a/source/blender/verify/intern/Makefile b/source/blender/verify/intern/Makefile
index 74430193c79..c05f035caf2 100644
--- a/source/blender/verify/intern/Makefile
+++ b/source/blender/verify/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_2_C_WARNINGS)
# path to our own external headerfiles
diff --git a/source/blender/yafray/YafRay_Api.h b/source/blender/yafray/YafRay_Api.h
index 8c47a79837f..a05e9752a1a 100644
--- a/source/blender/yafray/YafRay_Api.h
+++ b/source/blender/yafray/YafRay_Api.h
@@ -8,8 +8,6 @@ extern "C" {
void YAF_switchPlugin();
void YAF_switchFile();
int YAF_exportScene(Render* re);
- void YAF_addDupliMtx(Object* obj);
- int YAF_objectKnownData(Object* obj);
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/yafray/intern/Makefile b/source/blender/yafray/intern/Makefile
index a00a1fed73f..f7f6ccb559f 100644
--- a/source/blender/yafray/intern/Makefile
+++ b/source/blender/yafray/intern/Makefile
@@ -33,10 +33,6 @@ DIR = $(OCGDIR)/blender/yafray
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/yafray/intern/api.cpp b/source/blender/yafray/intern/api.cpp
index f59c5e1f73e..0cb1c6fafdf 100755..100644
--- a/source/blender/yafray/intern/api.cpp
+++ b/source/blender/yafray/intern/api.cpp
@@ -11,6 +11,4 @@ extern "C"
void YAF_switchPlugin() { YAFBLEND = &byplugin; }
void YAF_switchFile() { YAFBLEND = &byfile; }
int YAF_exportScene(Render* re) { return (int)YAFBLEND->exportScene(re); }
- void YAF_addDupliMtx(Object* obj) { YAFBLEND->addDupliMtx(obj); }
- int YAF_objectKnownData(Object* obj) { return (int)YAFBLEND->objectKnownData(obj); }
}
diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp
index c8c0b3c6bb1..ac7d2703eb8 100755..100644
--- a/source/blender/yafray/intern/export_File.cpp
+++ b/source/blender/yafray/intern/export_File.cpp
@@ -2,6 +2,8 @@
#include <math.h>
+#include <cstring>
+
using namespace std;
static string command_path = "";
@@ -1188,7 +1190,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
}
-void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
+void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
{
ostr.str("");
// transform first (not necessarily actual obj->obmat, can be duplivert see below)
@@ -1230,7 +1232,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
string matname(face0mat->id.name);
// use name in imgtex_shader list if 'TexFace' enabled for this material
if (face0mat->mode & MA_FACETEXTURE) {
- MTFace* tface = RE_vlakren_get_tface(re, face0, 0, NULL, 0);
+ MTFace* tface = RE_vlakren_get_tface(obr, face0, obr->actmtface, NULL, 0);
if (tface) {
Image* fimg = (Image*)tface->tpage;
if (fimg) matname = imgtex_shader[string(face0mat->id.name) + string(fimg->id.name)];
@@ -1412,7 +1414,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
string fmatname(fmat->id.name);
// use name in imgtex_shader list if 'TexFace' enabled for this face material
if (fmat->mode & MA_FACETEXTURE) {
- MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
+ MTFace* tface = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
if (tface) {
Image* fimg = (Image*)tface->tpage;
if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)];
@@ -1437,14 +1439,14 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
}
else if (vlr->flag & R_FACE_SPLIT) { ui2++; ui3++; }
- MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
+ MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
if (uvc) {
ostr << " u_a=\"" << uvc->uv[ui1][0] << "\" v_a=\"" << 1-uvc->uv[ui1][1] << "\""
<< " u_b=\"" << uvc->uv[ui2][0] << "\" v_b=\"" << 1-uvc->uv[ui2][1] << "\""
<< " u_c=\"" << uvc->uv[ui3][0] << "\" v_c=\"" << 1-uvc->uv[ui3][1] << "\"";
}
- MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0);
+ MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0);
// since Blender seems to need vcols when uvs are used, for yafray only export when the material actually uses vcols
if ((EXPORT_VCOL) && mcol) {
@@ -1508,13 +1510,13 @@ void yafrayFileRender_t::writeAllObjects()
{
// first all objects except dupliverts (and main instance object for dups)
- for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin();
+ for (map<Object*, yafrayObjectRen >::const_iterator obi=all_objects.begin();
obi!=all_objects.end(); ++obi)
{
// skip main duplivert object if in dupliMtx_list, written later
Object* obj = obi->first;
if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
- writeObject(obj, obi->second, obj->obmat);
+ writeObject(obj, obi->second.obr, obi->second.faces, obj->obmat);
}
// Now all duplivert objects (if any) as instances of main object
@@ -1534,7 +1536,7 @@ void yafrayFileRender_t::writeAllObjects()
// first object written as normal (but with transform of first duplivert)
Object* obj = dup_srcob[dupMtx->first];
- writeObject(obj, all_objects[obj], obmat);
+ writeObject(obj, all_objects[obj].obr, all_objects[obj].faces, obmat);
// all others instances of first
for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16) { // number of 4x4 matrices
@@ -2015,7 +2017,7 @@ bool yafrayFileRender_t::executeYafray(const string &xmlpath)
{
ostr.str("");
if (re->r.mode & R_BORDER) {
- ostr << command_path << "yafray -c " << re->r.YF_numprocs
+ ostr << command_path << "yafray -c " << re->r.threads
<< " -r " << (2.f*re->r.border.xmin - 1.f)
<< ":" << (2.f*re->r.border.xmax - 1.f)
<< ":" << (2.f*re->r.border.ymin - 1.f)
@@ -2023,7 +2025,7 @@ bool yafrayFileRender_t::executeYafray(const string &xmlpath)
<< " \"" << xmlpath << "\"";
}
else
- ostr << command_path << "yafray -c " << re->r.YF_numprocs << " \"" << xmlpath << "\"";
+ ostr << command_path << "yafray -c " << re->r.threads << " \"" << xmlpath << "\"";
string command = ostr.str();
cout << "COMMAND: " << command << endl;
diff --git a/source/blender/yafray/intern/export_File.h b/source/blender/yafray/intern/export_File.h
index 5d2e0c53a21..0eb1bfec1ed 100755..100644
--- a/source/blender/yafray/intern/export_File.h
+++ b/source/blender/yafray/intern/export_File.h
@@ -18,7 +18,7 @@ class yafrayFileRender_t : public yafrayRender_t
virtual void writeTextures();
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators();
- virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
+ virtual void writeObject(Object* obj, ObjectRen *obr, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects();
virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
virtual void writeLamps();
diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp
index 6a6137fefe9..361939df9c4 100644
--- a/source/blender/yafray/intern/export_Plugin.cpp
+++ b/source/blender/yafray/intern/export_Plugin.cpp
@@ -1,6 +1,9 @@
#include "export_Plugin.h"
#include <math.h>
+
+#include <cstring>
+
using namespace std;
@@ -98,6 +101,9 @@ static string YafrayPath()
static char *alternative[]=
{
"/usr/local/lib/",
+#ifdef __x86_64__
+ "/usr/lib64/",
+#endif
"/usr/lib/",
NULL
};
@@ -121,6 +127,9 @@ static string YafrayPluginPath()
static char *alternative[]=
{
"/usr/local/lib/yafray",
+#ifdef __x86_64__
+ "/usr/lib64/yafray",
+#endif
"/usr/lib/yafray",
NULL
};
@@ -183,7 +192,7 @@ bool yafrayPluginRender_t::initExport()
cerr << "Error loading yafray plugin: " << PIL_dynlib_get_error_as_string(handle) << endl;
return false;
}
- yafrayGate = constructor(re->r.YF_numprocs, YafrayPluginPath());
+ yafrayGate = constructor(re->r.threads, YafrayPluginPath());
cout << "YafRay plugin loaded" << endl;
plugin_loaded = true;
@@ -243,7 +252,7 @@ bool yafrayPluginRender_t::writeRender()
params["bias"] = yafray::parameter_t(re->r.YF_raybias);
params["clamp_rgb"] = yafray::parameter_t((re->r.YF_clamprgb==0) ? "on" : "off");
// lynx request
- params["threads"] = yafray::parameter_t((int)re->r.YF_numprocs);
+ params["threads"] = yafray::parameter_t((int)re->r.threads);
blenderYafrayOutput_t output(re);
yafrayGate->render(params, output);
cout << "render finished" << endl;
@@ -1079,7 +1088,7 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
}
-void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen *vlr, MTFace* uvc, bool comple)
+void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, ObjectRen *obr, VlakRen *vlr, MTFace* uvc, bool comple)
{
if (uvc)
{
@@ -1107,9 +1116,9 @@ void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen
}
}
-void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple)
+void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, ObjectRen *obr, VlakRen *vlr, bool comple)
{
- MCol *mcol= RE_vlakren_get_mcol(re, vlr, 0, NULL, 0);
+ MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0);
if (mcol)
{
@@ -1142,7 +1151,7 @@ void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, b
void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
- map<VertRen*, int> &vert_idx,VlakRen *vlr,
+ map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv)
{
Material* fmat = vlr->mat;
@@ -1150,7 +1159,7 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
string fmatname(fmat->id.name);
// use name in imgtex_shader list if 'TexFace' enabled for this face material
if (fmat->mode & MA_FACETEXTURE) {
- MTFace* tface = RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
+ MTFace* tface = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
if (tface) {
Image* fimg = (Image*)tface->tpage;
if (fimg) fmatname = imgtex_shader[fmatname + string(fimg->id.name)];
@@ -1171,7 +1180,7 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
faceshader.push_back(shaders.size()-1);
}
- MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
+ MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
int idx1, idx2, idx3;
idx1 = vert_idx.find(vlr->v1)->second;
@@ -1183,20 +1192,20 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
- if(has_uv) genUVcoords(uvcoords, vlr, uvc);
- if (EXPORT_VCOL) genVcol(vcol, vlr);
+ if(has_uv) genUVcoords(uvcoords, obr, vlr, uvc);
+ if (EXPORT_VCOL) genVcol(vcol, obr, vlr);
}
void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &shaders,*/vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
- map<VertRen*, int> &vert_idx,VlakRen *vlr,
+ map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv)
{
Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
faceshader.push_back(faceshader.back());
- MTFace* uvc = RE_vlakren_get_tface(re, vlr, 0, NULL, 0); // possible uvcoords (v upside down)
+ MTFace* uvc = RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); // possible uvcoords (v upside down)
int idx1, idx2, idx3;
idx1 = vert_idx.find(vlr->v3)->second;
idx2 = vert_idx.find(vlr->v4)->second;
@@ -1207,12 +1216,12 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh
faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
- if (has_uv) genUVcoords(uvcoords, vlr, uvc, true);
- if (EXPORT_VCOL) genVcol(vcol, vlr, true);
+ if (has_uv) genUVcoords(uvcoords, obr, vlr, uvc, true);
+ if (EXPORT_VCOL) genVcol(vcol, obr, vlr, true);
}
void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx,
- map<VertRen*, int> &vert_idx, VlakRen* vlr, int has_orco, Object* obj)
+ map<VertRen*, int> &vert_idx, ObjectRen *obr, VlakRen* vlr, int has_orco, Object* obj)
{
VertRen* ver;
float tvec[3]; // for back2world transform
@@ -1277,7 +1286,7 @@ void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vi
}
}
-void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
+void yafrayPluginRender_t::writeObject(Object* obj, ObjectRen *obr, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
{
float mtr[4*4];
mtr[0*4+0]=obmat[0][0]; mtr[0*4+1]=obmat[1][0]; mtr[0*4+2]=obmat[2][0]; mtr[0*4+3]=obmat[3][0];
@@ -1338,8 +1347,8 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
fci!=VLR_list.end();++fci)
{
VlakRen* vlr = *fci;
- genVertices(verts, vidx, vert_idx, vlr, has_orco, obj);
- if(RE_vlakren_get_tface(re, vlr, 0, NULL, 0)) has_uv=true;
+ genVertices(verts, vidx, vert_idx, obr, vlr, has_orco, obj);
+ if(RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0)) has_uv=true;
}
// all faces using the index list created above
vector<int> faces;
@@ -1350,9 +1359,9 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
fci2!=VLR_list.end();++fci2)
{
VlakRen* vlr = *fci2;
- genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
+ genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, obr, vlr, has_orco, has_uv);
if (vlr->v4)
- genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv);
+ genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, obr, vlr, has_orco, has_uv);
}
// using the ObjectRen database, contruct a new name if object has a parent.
@@ -1382,15 +1391,14 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
// write all objects
void yafrayPluginRender_t::writeAllObjects()
{
-
// first all objects except dupliverts (and main instance object for dups)
- for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin();
+ for (map<Object*, yafrayObjectRen >::const_iterator obi=all_objects.begin();
obi!=all_objects.end(); ++obi)
{
// skip main duplivert object if in dupliMtx_list, written later
Object* obj = obi->first;
if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
- writeObject(obj, obi->second, obj->obmat);
+ writeObject(obj, obi->second.obr, obi->second.faces, obj->obmat);
}
// Now all duplivert objects (if any) as instances of main object
@@ -1408,7 +1416,7 @@ void yafrayPluginRender_t::writeAllObjects()
// first object written as normal (but with transform of first duplivert)
Object* obj = dup_srcob[dupMtx->first];
- writeObject(obj, all_objects[obj], obmat);
+ writeObject(obj, all_objects[obj].obr, all_objects[obj].faces, obmat);
// all others instances of first
for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16)
@@ -1437,7 +1445,6 @@ void yafrayPluginRender_t::writeAllObjects()
}
}
-
}
void yafrayPluginRender_t::writeAreaLamp(LampRen* lamp, int num, float iview[4][4])
diff --git a/source/blender/yafray/intern/export_Plugin.h b/source/blender/yafray/intern/export_Plugin.h
index 1ce4988a260..660271daf96 100644
--- a/source/blender/yafray/intern/export_Plugin.h
+++ b/source/blender/yafray/intern/export_Plugin.h
@@ -35,7 +35,7 @@ class yafrayPluginRender_t : public yafrayRender_t
virtual void writeTextures();
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators();
- virtual void writeObject(Object* obj,
+ virtual void writeObject(Object* obj, ObjectRen *obr,
const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects();
virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
@@ -48,18 +48,18 @@ class yafrayPluginRender_t : public yafrayRender_t
virtual bool initExport();
virtual bool finishExport();
- void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,MTFace* uvc, bool comple=false);
- void genVcol(std::vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple=false);
+ void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,ObjectRen *obr,VlakRen *vlr,MTFace* uvc, bool comple=false);
+ void genVcol(std::vector<yafray::CFLOAT> &vcol, ObjectRen *obr, VlakRen *vlr, bool comple=false);
void genFace(std::vector<int> &faces,std::vector<std::string> &shaders,std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
- std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
+ std::map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv);
void genCompleFace(std::vector<int> &faces,/*std::vector<std::string> &shaders,*/std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
- std::map<VertRen*, int> &vert_idx,VlakRen *vlr,
+ std::map<VertRen*, int> &vert_idx,ObjectRen *obr, VlakRen *vlr,
int has_orco,bool has_uv);
void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx,
- std::map<VertRen*, int> &vert_idx, VlakRen* vlr, int has_orco, Object* obj);
+ std::map<VertRen*, int> &vert_idx, ObjectRen *obr, VlakRen* vlr, int has_orco, Object* obj);
};
class blenderYafrayOutput_t : public yafray::colorOutput_t
diff --git a/source/blender/yafray/intern/yafray_Render.cpp b/source/blender/yafray/intern/yafray_Render.cpp
index 1106e197335..01da4683d71 100644
--- a/source/blender/yafray/intern/yafray_Render.cpp
+++ b/source/blender/yafray/intern/yafray_Render.cpp
@@ -8,6 +8,8 @@
#include <math.h>
+#include <cstring>
+
using namespace std;
void yafrayRender_t::clearAll()
@@ -73,7 +75,20 @@ bool yafrayRender_t::exportScene(Render* re)
// as well as associating them again with the original Object.
bool yafrayRender_t::getAllMatTexObs()
{
+ ObjectInstanceRen *obi;
+ ObjectRen *obr;
VlakRen* vlr;
+ float mat[4][4];
+
+ // convert blender object instances to dupli matrices
+ for(obi=(ObjectInstanceRen*)re->instancetable.first; obi; obi=obi->next) {
+ if(obi->flag & R_DUPLI_TRANSFORMED) {
+ // compute object matrix with dupli transform, need to transform
+ // obi->mat out of view space for it
+ MTC_Mat4MulSerie(mat, re->viewinv, obi->mat, re->viewmat, obi->obr->ob->obmat, 0, 0, 0, 0);
+ addDupliMtx(obi->obr->ob, mat);
+ }
+ }
// Blender does not include object which have total 0 alpha materials,
// however, the objects might have been included in the dupliMtx list,
@@ -84,69 +99,72 @@ bool yafrayRender_t::getAllMatTexObs()
// but on the other hand that could also hide the real problem of course...
map<string, Object*> renderobs;
- for (int i=0; i < re->totvlak; i++) {
-
- if ((i & 255)==0) vlr=re->vlaknodes[i>>8].vlak; else vlr++;
-
- // ---- The materials & textures
- // in this case, probably every face has a material assigned, which can be the default material,
- // so checking that this is !0 is probably not necessary, but just in case...
- Material* matr = vlr->mat;
- if (matr) {
- // The default assigned material seems to be nameless, no MA id, an empty string.
- // Since this name is needed in yafray, make it 'blender_default'
- if (strlen(matr->id.name)==0)
- used_materials["blender_default"] = matr;
- else
- used_materials[matr->id.name] = matr;
- // textures, all active channels
- for (int m=0;m<MAX_MTEX;m++) {
- if (matr->septex & (1<<m)) continue; // only active channels
- MTex* mx = matr->mtex[m];
- // if no mtex, ignore
- if (mx==NULL) continue;
- // if no tex, ignore
- Tex* tx = mx->tex;
- if (tx==NULL) continue;
- short txtp = tx->type;
- // if texture type not available in yafray, ignore
- if ((txtp==0) ||
- (txtp==TEX_MAGIC) ||
- (txtp==TEX_PLUGIN) ||
- (txtp==TEX_ENVMAP)) continue;
- // if texture is stucci, only export if 'nor' enabled
- if ((txtp==TEX_STUCCI) && !((mx->mapto & MAP_NORM) || (mx->maptoneg & MAP_NORM))) continue;
- // In the case of an image texture, check that there is an actual image, otherwise ignore.
- // Stupid error was here (...if (txtp & TEX_IMAGE)...),
- // which happened to work sofar, but not anymore with the extended texture support..
- if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
- used_textures[tx->id.name] = mx;
+ for(obr=(ObjectRen*)re->objecttable.first; obr; obr=obr->next) {
+ for (int i=0; i < obr->totvlak; i++) {
+
+ if ((i & 255)==0) vlr=obr->vlaknodes[i>>8].vlak; else vlr++;
+
+ // ---- The materials & textures
+ // in this case, probably every face has a material assigned, which can be the default material,
+ // so checking that this is !0 is probably not necessary, but just in case...
+ Material* matr = vlr->mat;
+ if (matr) {
+ // The default assigned material seems to be nameless, no MA id, an empty string.
+ // Since this name is needed in yafray, make it 'blender_default'
+ if (strlen(matr->id.name)==0)
+ used_materials["blender_default"] = matr;
+ else
+ used_materials[matr->id.name] = matr;
+ // textures, all active channels
+ for (int m=0;m<MAX_MTEX;m++) {
+ if (matr->septex & (1<<m)) continue; // only active channels
+ MTex* mx = matr->mtex[m];
+ // if no mtex, ignore
+ if (mx==NULL) continue;
+ // if no tex, ignore
+ Tex* tx = mx->tex;
+ if (tx==NULL) continue;
+ short txtp = tx->type;
+ // if texture type not available in yafray, ignore
+ if ((txtp==0) ||
+ (txtp==TEX_MAGIC) ||
+ (txtp==TEX_PLUGIN) ||
+ (txtp==TEX_ENVMAP)) continue;
+ // if texture is stucci, only export if 'nor' enabled
+ if ((txtp==TEX_STUCCI) && !((mx->mapto & MAP_NORM) || (mx->maptoneg & MAP_NORM))) continue;
+ // In the case of an image texture, check that there is an actual image, otherwise ignore.
+ // Stupid error was here (...if (txtp & TEX_IMAGE)...),
+ // which happened to work sofar, but not anymore with the extended texture support..
+ if ((txtp==TEX_IMAGE) && (!tx->ima)) continue;
+ used_textures[tx->id.name] = mx;
+ }
}
- }
- // Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
- // ignore null object pointers.
- // Also make list of facetexture images (material 'TexFace').
- if (vlr->ob) {
- int nv = 0; // number of vertices
- MTFace *tface;
-
- if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
- if (nv) {
- renderobs[vlr->ob->id.name] = vlr->ob;
- all_objects[vlr->ob].push_back(vlr);
-
- tface= RE_vlakren_get_tface(re, vlr, 0, NULL, 0);
- if (tface && tface->tpage) {
- Material* fmat = vlr->mat;
-
- // only save if TexFace enabled
- if(fmat && (fmat->mode & MA_FACETEXTURE))
- imagetex[tface->tpage].insert(fmat);
+ // Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
+ // ignore null object pointers.
+ // Also make list of facetexture images (material 'TexFace').
+ if (obr->ob) {
+ int nv = 0; // number of vertices
+ MTFace *tface;
+
+ if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
+ if (nv) {
+ renderobs[obr->ob->id.name] = obr->ob;
+ all_objects[obr->ob].obr= obr;
+ all_objects[obr->ob].faces.push_back(vlr);
+
+ tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
+ if (tface && tface->tpage) {
+ Material* fmat = vlr->mat;
+
+ // only save if TexFace enabled
+ if(fmat && (fmat->mode & MA_FACETEXTURE))
+ imagetex[tface->tpage].insert(fmat);
+ }
}
}
- }
+ }
}
// now remove any objects from dupliMtx_list which are not in the renderlist
@@ -168,7 +186,7 @@ bool yafrayRender_t::getAllMatTexObs()
// in all_objects with the name given in dupliMtx_list
if (!dupliMtx_list.empty()) {
- for (map<Object*, vector<VlakRen*> >::const_iterator obn=all_objects.begin();
+ for (map<Object*, yafrayObjectRen>::const_iterator obn=all_objects.begin();
obn!=all_objects.end();++obn)
{
Object* obj = obn->first;
@@ -187,16 +205,16 @@ bool yafrayRender_t::getAllMatTexObs()
return true;
}
-
-
-void yafrayRender_t::addDupliMtx(Object* obj)
+void yafrayRender_t::addDupliMtx(Object* obj, float mat[][4])
{
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
- dupliMtx_list[obj->id.name].push_back(obj->obmat[i][j]);
+ dupliMtx_list[obj->id.name].push_back(mat[i][j]);
}
+#if 0
+
bool yafrayRender_t::objectKnownData(Object* obj)
{
// if object data already known, no need to include in renderlist, otherwise save object datapointer
@@ -217,3 +235,5 @@ bool yafrayRender_t::objectKnownData(Object* obj)
objectData[obj->data] = obj;
return false;
}
+#endif
+
diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h
index 4002f514a6e..43d2c6c602a 100644
--- a/source/blender/yafray/intern/yafray_Render.h
+++ b/source/blender/yafray/intern/yafray_Render.h
@@ -52,6 +52,12 @@ extern void error (char *fmt, ...);
#include <vector>
#include <set>
+class yafrayObjectRen {
+ public:
+ std::vector<VlakRen*> faces;
+ ObjectRen *obr;
+};
+
class yafrayRender_t
{
public:
@@ -62,7 +68,7 @@ class yafrayRender_t
// mtds
bool exportScene(Render* re);
- void addDupliMtx(Object* obj);
+ void addDupliMtx(Object* obj, float mat[][4]);
bool objectKnownData(Object* obj);
protected:
@@ -72,7 +78,7 @@ class yafrayRender_t
bool hasworld;
- std::map<Object*, std::vector<VlakRen*> > all_objects;
+ std::map<Object*, yafrayObjectRen> all_objects;
std::map<std::string, Material*> used_materials;
std::map<std::string, MTex*> used_textures;
std::map<std::string, std::vector<float> > dupliMtx_list;
@@ -86,7 +92,7 @@ class yafrayRender_t
virtual void writeTextures()=0;
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname)=0;
virtual void writeMaterialsAndModulators()=0;
- virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0;
+ virtual void writeObject(Object* obj, ObjectRen *obr, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0;
virtual void writeAllObjects()=0;
virtual void writeLamps()=0;
virtual void writeCamera()=0;
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index a34ed069b02..2b566d77a29 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -44,10 +44,17 @@ INCLUDE_DIRECTORIES(../../intern/guardedalloc
../kernel/gen_system
)
+
+
IF(WITH_QUICKTIME)
ADD_DEFINITIONS(-DWITH_QUICKTIME)
ENDIF(WITH_QUICKTIME)
+IF(LINUX)
+ ADD_DEFINITIONS(-DWITH_BINRELOC)
+ INCLUDE_DIRECTORIES(${BINRELOC_INC})
+endif(LINUX)
+
IF(YESIAMSTUPID)
ADD_DEFINITIONS(-DYESIAMSTUPID)
ENDIF(YESIAMSTUPID)
@@ -191,6 +198,10 @@ FILE(READ ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt BLENDER_LINK_LIBS)
SET(BLENDER_LINK_LIBS bf_nodes ${BLENDER_LINK_LIBS} src blender_python blender_render blender_radiosity blender_IK bf_elbeem)
+IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ SET(BLENDER_LINK_LIBS ${BLENDER_LINK_LIBS} extern_binreloc)
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+
IF(UNIX)
# Sort libraries
SET(BLENDER_SORTED_LIBS
@@ -254,6 +265,7 @@ IF(UNIX)
bf_moto
blender_python
bf_quicktime
+ extern_binreloc
)
FOREACH(SORTLIB ${BLENDER_SORTED_LIBS})
diff --git a/source/creator/Makefile b/source/creator/Makefile
index f68855af96f..a7f2dfeecb6 100644
--- a/source/creator/Makefile
+++ b/source/creator/Makefile
@@ -38,14 +38,11 @@ CSRCS = creator.c
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I../blender/render/extern/include
CPPFLAGS += -I../blender/radiosity/extern/include
+
# two needed for the kernel
CPPFLAGS += -I../blender/imbuf
CPPFLAGS += -I../blender/makesdna
@@ -63,6 +60,10 @@ ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -I$(NAN_QUICKTIME)/include -DWITH_QUICKTIME
endif
+ifeq ($(WITH_BINRELOC), true)
+ CPPFLAGS += -I$(OCGDIR)/extern/binreloc/include -DWITH_BINRELOC
+endif
+
ifeq ($(NAN_YESIAMSTUPID), true)
CPPFLAGS += -DYESIAMSTUPID
endif
diff --git a/source/creator/SConscript b/source/creator/SConscript
index 9bc49b2fc30..833b56eccd8 100644
--- a/source/creator/SConscript
+++ b/source/creator/SConscript
@@ -15,4 +15,8 @@ if env['WITH_BF_QUICKTIME']==1:
incs += ' ' + env['BF_QUICKTIME_INC']
defs.append('WITH_QUICKTIME')
+if env['WITH_BF_BINRELOC']==1:
+ incs += ' ../../extern/binreloc/include'
+ defs.append('WITH_BINRELOC')
+
env.BlenderLib ( libname = 'blender_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 1 )
diff --git a/source/creator/buildinfo.c b/source/creator/buildinfo.c
index feda7484f79..69d3b090086 100644
--- a/source/creator/buildinfo.c
+++ b/source/creator/buildinfo.c
@@ -38,6 +38,7 @@
#ifndef WIN32
char * build_date=BUILD_DATE;
char * build_time=BUILD_TIME;
+char * build_rev=BUILD_REV;
char * build_platform=BUILD_PLATFORM;
char * build_type=BUILD_TYPE;
#else
diff --git a/source/creator/creator.c b/source/creator/creator.c
index d63e69255eb..b7a756949f1 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -97,6 +97,10 @@
# include <sys/rtprio.h>
#endif
+#ifdef WITH_BINRELOC
+#include "binreloc.h"
+#endif
+
// from buildinfo.c
#ifdef BUILD_DATE
extern char * build_date;
@@ -124,7 +128,7 @@ extern void winlay_process_events(int wait_for_event);
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];
/* Initialise callbacks for the modules that need them */
void setCallbacks(void);
@@ -159,6 +163,7 @@ static void print_version(void)
printf ("Blender %d.%02d (sub %d) Build\n", G.version/100, G.version%100, BLENDER_SUBVERSION);
printf ("\tbuild date: %s\n", build_date);
printf ("\tbuild time: %s\n", build_time);
+ printf ("\tbuild revision: %s\n", build_rev);
printf ("\tbuild platform: %s\n", build_platform);
printf ("\tbuild type: %s\n", build_type);
#else
@@ -169,30 +174,33 @@ static void print_version(void)
static void print_help(void)
{
printf ("Blender %d.%02d (sub %d) Build\n", G.version/100, G.version%100, BLENDER_SUBVERSION);
- printf ("Usage: blender [options ...] [file]\n");
-
+ printf ("Usage: blender [args ...] [file] [args ...]\n");
printf ("\nRender options:\n");
- printf (" -b <file>\tRender <file> in background\n");
+ printf (" -b <file>\tRender <file> in background (doesn't load the user defaults .B.blend file)\n");
+ printf (" -a render frames from start to end (inclusive), only works when used after -b\n");
printf (" -S <name>\tSet scene <name>\n");
printf (" -f <frame>\tRender frame <frame> and save it\n");
- printf (" -s <frame>\tSet start to frame <frame> (use with -a)\n");
- printf (" -e <frame>\tSet end to frame (use with -a)<frame>\n");
+ printf (" -s <frame>\tSet start to frame <frame> (use before the -a argument)\n");
+ printf (" -e <frame>\tSet end to frame <frame> (use before the -a argument)\n");
printf (" -o <path>\tSet the render path and file name.\n");
printf (" Use // at the start of the path to\n");
printf (" render relative to the blend file.\n");
printf (" The frame number will be added at the end of the filename.\n");
- printf (" eg: blender -b foobar.blend -o //render_ -F PNG -x 1\n");
- printf (" -F <format>\tSet the render format, Valid options are..\n");
- printf (" \tTGA IRIS HAMX FTYPE JPEG MOVIE IRIZ RAWTGA\n");
+ printf (" eg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a\n");
+ printf ("\nFormat options:\n");
+ printf (" -F <format>\tSet the render format, Valid options are...\n");
+ printf (" \tTGA IRIS HAMX JPEG MOVIE IRIZ RAWTGA\n");
printf (" \tAVIRAW AVIJPEG PNG BMP FRAMESERVER\n");
printf (" (formats that can be compiled into blender, not available on all systems)\n");
- printf (" \tHDR TIFF EXR MPEG AVICODEC QUICKTIME CINEON DPX\n");
+ printf (" \tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS\n");
printf (" -x <bool>\tSet option to add the file extension to the end of the file.\n");
- printf (" -t <threads>\tUse amount of <threads> for rendering\n");
- printf ("\nAnimation options:\n");
- printf (" -a <file(s)>\tPlayback <file(s)>\n");
+ printf (" -t <threads>\tUse amount of <threads> for rendering.\n");
+ printf (" [1-8], 0 for systems processor count.\n");
+ printf ("\nAnimation playback options:\n");
+ printf (" -a <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n");
printf (" -p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n");
printf (" -m\t\tRead from disk (Don't buffer)\n");
+ printf (" -f <fps> <fps-base>\t\tSpecify FPS to start with\n");
printf ("\nWindow options:\n");
printf (" -w\t\tForce opening with borders (default)\n");
@@ -216,6 +224,19 @@ static void print_help(void)
printf (" -R\t\tRegister .blend extension\n");
#endif
printf (" -v\t\tPrint Blender version and exit\n");
+ printf (" --\t\tEnds option processing. Following arguments are \n");
+ printf (" \t\t passed unchanged. Access via Python's sys.argv\n");
+ printf ("\nNote: Arguments must be separated by white space. eg:\n");
+ printf (" \"blender -ba test.blend\"\n");
+ printf (" ...will ignore the 'a'\n");
+ printf (" \"blender -b test.blend -f8\"\n");
+ printf (" ...will ignore 8 because there is no space between the -f and the frame value\n");
+ printf ("Note: Arguments are executed in the order they are given. eg:\n");
+ printf (" \"blender -b test.blend -f 1 -o /tmp\"\n");
+ printf (" ...may not render to /tmp because '-f 1' renders before the output path is set\n");
+ printf (" \"blender -b -o /tmp test.blend -f 1\"\n");
+ printf (" ...may not render to /tmp because loading the blend file overwrites the output path that was set\n");
+ printf (" \"blender -b test.blend -o /tmp -f 1\" works as expected.\n\n");
}
@@ -224,7 +245,7 @@ extern void winlay_get_screensize(int *width_r, int *height_r);
int main(int argc, char **argv)
{
- int a, i, stax, stay, sizx, sizy;
+ int a, i, stax=0, stay=0, sizx, sizy;
SYS_SystemHandle syshandle;
Scene *sce;
@@ -234,6 +255,11 @@ int main(int argc, char **argv)
int audio = 0;
#endif
+
+#ifdef WITH_BINRELOC
+ br_init( NULL );
+#endif
+
setCallbacks();
#ifdef __APPLE__
/* patch to ignore argument finder gives us (pid?) */
@@ -277,7 +303,7 @@ int main(int argc, char **argv)
signal (SIGFPE, fpe_handler);
#else
if ( getenv("SDL_AUDIODRIVER") == NULL) {
- setenv("SDL_AUDIODRIVER", "dma", 1);
+ setenv("SDL_AUDIODRIVER", "alsa", 1);
}
#endif
#endif
@@ -289,7 +315,7 @@ int main(int argc, char **argv)
// need this.
BLI_where_am_i(bprogname, argv[0]);
-
+
/* Hack - force inclusion of the plugin api functions,
* see blenpluginapi:pluginapi.c
*/
@@ -314,6 +340,12 @@ int main(int argc, char **argv)
exit(0);
}
+ /* end argument processing after -- */
+ if (!strcmp( argv[a], "--")){
+ a = argc;
+ break;
+ }
+
/* Handle long version request */
if (!strcmp(argv[a], "--version")){
print_version();
@@ -323,7 +355,7 @@ int main(int argc, char **argv)
/* Handle -* switches */
else if(argv[a][0] == '-') {
switch(argv[a][1]) {
- case 'a':
+ case 'a': /* -b was not given, play an animation */
playanim(argc-1, argv+1);
exit(0);
break;
@@ -377,6 +409,10 @@ int main(int argc, char **argv)
init_def_material();
+ winlay_get_screensize(&sizx, &sizy);
+ stax=0;
+ stay=0;
+
if(G.background==0) {
for(a=1; a<argc; a++) {
if(argv[a][0] == '-') {
@@ -395,7 +431,6 @@ int main(int argc, char **argv)
a++;
sizy= atoi(argv[a]);
- setprefsize(stax, stay, sizx, sizy, 0);
break;
case 'd':
G.f |= G_DEBUG; /* std output printf's */
@@ -411,18 +446,10 @@ int main(int argc, char **argv)
break;
case 'w':
- /* XXX, fixme zr, with borders */
- /* there probably is a better way to do
- * this, right now do as if blender was
- * called with "-p 0 0 xres yres" -- sgefant
- */
- winlay_get_screensize(&sizx, &sizy);
- setprefsize(0, 0, sizx, sizy, 1);
G.windowstate = G_WINDOWSTATE_BORDER;
break;
case 'W':
- /* XXX, fixme zr, borderless on win32 */
- /* now on all platforms as of 20070411 - DJC */
+ /* XXX, fixme mein, borderless on OSX */
G.windowstate = G_WINDOWSTATE_FULLSCREEN;
break;
case 'R':
@@ -448,6 +475,9 @@ int main(int argc, char **argv)
}
}
+ if ( (G.windowstate == G_WINDOWSTATE_BORDER) || (G.windowstate == G_WINDOWSTATE_FULLSCREEN))
+ setprefsize(stax, stay, sizx, sizy, 0);
+
BPY_start_python(argc, argv);
/**
@@ -456,12 +486,16 @@ int main(int argc, char **argv)
* added note (ton): i removed it altogether
*/
- BIF_init();
+ BIF_init(); /* loads .B.blend */
+
+ BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */
}
else {
BPY_start_python(argc, argv);
+ BLI_where_is_temp( btempdir, 0 ); /* call after loading the .B.blend so we can read U.tempdir */
+
// (ton) Commented out. I have no idea whats thisfor... will mail around!
// SYS_WriteCommandLineInt(syshandle,"noaudio",1);
// audio = 0;
@@ -500,6 +534,10 @@ int main(int argc, char **argv)
if(argv[a][0] == '-') {
switch(argv[a][1]) {
+ case '-': /* -- ends argument processing */
+ a = argc;
+ break;
+
case 'p': /* prefsize */
a+= 4;
break;
@@ -622,7 +660,9 @@ int main(int argc, char **argv)
if (!strcmp(argv[a],"TGA")) G.scene->r.imtype = R_TARGA;
else if (!strcmp(argv[a],"IRIS")) G.scene->r.imtype = R_IRIS;
else if (!strcmp(argv[a],"HAMX")) G.scene->r.imtype = R_HAMX;
- else if (!strcmp(argv[a],"FTYPE")) G.scene->r.imtype = R_FTYPE;
+#ifdef WITH_DDS
+ else if (!strcmp(argv[a],"DDS")) G.scene->r.imtype = R_DDS;
+#endif
else if (!strcmp(argv[a],"JPEG")) G.scene->r.imtype = R_JPEG90;
else if (!strcmp(argv[a],"MOVIE")) G.scene->r.imtype = R_MOVIE;
else if (!strcmp(argv[a],"IRIZ")) G.scene->r.imtype = R_IRIZ;
@@ -634,13 +674,16 @@ int main(int argc, char **argv)
else if (!strcmp(argv[a],"QUICKTIME")) G.scene->r.imtype = R_QUICKTIME;
else if (!strcmp(argv[a],"BMP")) G.scene->r.imtype = R_BMP;
else if (!strcmp(argv[a],"HDR")) G.scene->r.imtype = R_RADHDR;
- else if (!strcmp(argv[a],"TIFF")) G.scene->r.imtype = R_IRIS;
+ else if (!strcmp(argv[a],"TIFF")) G.scene->r.imtype = R_TIFF;
+#ifdef WITH_OPENEXR
else if (!strcmp(argv[a],"EXR")) G.scene->r.imtype = R_OPENEXR;
+ else if (!strcmp(argv[a],"MULTILAYER")) G.scene->r.imtype = R_MULTILAYER;
+#endif
else if (!strcmp(argv[a],"MPEG")) G.scene->r.imtype = R_FFMPEG;
else if (!strcmp(argv[a],"FRAMESERVER")) G.scene->r.imtype = R_FRAMESERVER;
else if (!strcmp(argv[a],"CINEON")) G.scene->r.imtype = R_CINEON;
else if (!strcmp(argv[a],"DPX")) G.scene->r.imtype = R_DPX;
- else printf("\nError: Format from '-F ' not known.\n");
+ else printf("\nError: Format from '-F' not known or not compiled in this release.\n");
}
} else {
printf("\nError: no blend loaded. cannot use '-x'.\n");
@@ -674,8 +717,63 @@ int main(int argc, char **argv)
}
}
else {
- BKE_read_file(argv[a], NULL);
- sound_initialize_sounds();
+
+ /* Make the path absolute because its needed for relative linked blends to be found */
+ int abs = 0;
+ int filelen;
+ char cwd[FILE_MAXDIR + FILE_MAXFILE];
+ char filename[FILE_MAXDIR + FILE_MAXFILE];
+ cwd[0] = filename[0] = '\0';
+
+ BLI_strncpy(filename, argv[a], sizeof(filename));
+ filelen = strlen(filename);
+
+ /* relative path checks, could do more tests here... */
+#ifdef WIN32
+ /* Account for X:/ and X:\ - should be enough */
+ if (filelen >= 3 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
+ abs = 1;
+#else
+ if (filelen >= 2 && filename[0] == '/')
+ abs = 1 ;
+#endif
+ if (!abs) {
+ BLI_getwdN(cwd); /* incase the full path to the blend isnt used */
+
+ if (cwd[0] == '\0') {
+ printf(
+ "Could not get the current working directory - $PWD for an unknown reason.\n\t"
+ "Relative linked files will not load if the entire blend path is not used.\n\t"
+ "The 'Play' button may also fail.\n"
+ );
+ } else {
+ /* uses the blend path relative to cwd important for loading relative linked files.
+ *
+ * cwd should contain c:\ etc on win32 so the relbase can be NULL
+ * relbase being NULL also prevents // being misunderstood as relative to the current
+ * blend file which isnt a feature we want to use in this case since were dealing
+ * with a path from the command line, rather then from inside Blender */
+
+ BLI_make_file_string(NULL, filename, cwd, argv[a]);
+ }
+ }
+
+ if (G.background) {
+ int retval = BKE_read_file(filename, NULL);
+ sound_initialize_sounds();
+
+ /*we successfully loaded a blend file, get sure that
+ pointcache works */
+ if (retval!=0) G.relbase_valid = 1;
+
+ /* happens for the UI on file reading too */
+ BKE_reset_undo();
+ BKE_write_undo("original"); /* save current state */
+ } else {
+ /* we are not running in background mode here, but start blender in UI mode with
+ a file - this should do everything a 'load file' does */
+ BIF_read_file(filename);
+ }
}
}
@@ -704,6 +802,7 @@ static void error_cb(char *err)
static void mem_error_cb(char *errorStr)
{
fprintf(stderr, errorStr);
+ fflush(stderr);
}
void setCallbacks(void)
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 80db437bcd9..0e0d8982527 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -105,11 +105,16 @@ static BlendFileData *load_game_data(char *filename) {
fseek(file, 0L, SEEK_SET);
char* filebuffer= new char[len];//MEM_mallocN(len, "text_buffer");
int sizeread = fread(filebuffer,len,1,file);
- if (sizeread==1)
- {
+ if (sizeread==1){
bfd = BLO_read_from_memory(filebuffer, len, &error);
+ } else {
+ error = BRE_UNABLE_TO_READ;
}
fclose(file);
+ // the memory is not released in BLO_read_from_memory, must do it here
+ delete filebuffer;
+ } else {
+ error = BRE_UNABLE_TO_OPEN;
}
if (!bfd) {
@@ -135,6 +140,10 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
STR_String exitstring = "";
BlendFileData *bfd= NULL;
+ // Acquire Python's GIL (global interpreter lock)
+ // so we can safely run Python code and API calls
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
bgl::InitExtensions(1);
do
@@ -176,9 +185,13 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
bool lock_arrays = (displaylists && useVertexArrays);
- if(displaylists && !useVertexArrays)
- rasterizer = new RAS_ListRasterizer(canvas);
- else if (useVertexArrays && bgl::QueryVersion(1, 1))
+ if(displaylists){
+ if (useVertexArrays) {
+ rasterizer = new RAS_ListRasterizer(canvas, true, lock_arrays);
+ } else {
+ rasterizer = new RAS_ListRasterizer(canvas);
+ }
+ } else if (useVertexArrays && bgl::QueryVersion(1, 1))
rasterizer = new RAS_VAOpenGLRasterizer(canvas, lock_arrays);
else
rasterizer = new RAS_OpenGLRasterizer(canvas);
@@ -340,7 +353,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
initGameKeys();
initPythonConstraintBinding();
-
+
if (sceneconverter)
{
// convert and add scene
@@ -460,6 +473,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
if (bfd) BLO_blendfiledata_free(bfd);
+
+ // Release Python's GIL
+ PyGILState_Release(gilstate);
}
extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
@@ -478,6 +494,10 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
STR_String exitstring = "";
BlendFileData *bfd= NULL;
+ // Acquire Python's GIL (global interpreter lock)
+ // so we can safely run Python code and API calls
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
bgl::InitExtensions(1);
do
@@ -605,7 +625,9 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
ketsjiengine->SetUseFixedTime(true);
- ketsjiengine->SetTicRate(blscene->r.frs_sec);
+ ketsjiengine->SetTicRate(
+ (double) blscene->r.frs_sec /
+ (double) blscene->r.frs_sec_base);
// the mainloop
while ((blscene->r.cfra<=blscene->r.efra)&&(!exitrequested))
@@ -663,4 +685,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
if (bfd) BLO_blendfiledata_free(bfd);
-} \ No newline at end of file
+
+ // Release Python's GIL
+ PyGILState_Release(gilstate);
+}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 8f7609aed74..413b16bc300 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -54,8 +54,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
#include "RAS_OpenGLRasterizer/ARB_multitexture.h"
#include "BL_Material.h" // MAXTEX
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index caf3d120fab..7e32ade37f2 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -452,4 +452,37 @@ RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial(
return NULL;
}
+void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
+{
+ int state = rasterizer->GetMotionBlurState();
+ float motionblurvalue;
+ if(state)
+ {
+ motionblurvalue = rasterizer->GetMotionBlurValue();
+ if(state==1)
+ {
+ //bugfix:load color buffer into accum buffer for the first time(state=1)
+ glAccum(GL_LOAD, 1.0);
+ rasterizer->SetMotionBlurState(2);
+ }
+ else if(motionblurvalue>=0.0 && motionblurvalue<=1.0)
+ {
+ glAccum(GL_MULT, motionblurvalue);
+ glAccum(GL_ACCUM, 1-motionblurvalue);
+ glAccum(GL_RETURN, 1.0);
+ glFlush();
+ }
+ }
+}
+
+void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
+{
+ m_filtermanager.EnableFilter(filtermode, pass, text);
+}
+
+void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)
+{
+ m_filtermanager.RenderFilters(canvas);
+}
+
unsigned int KX_BlenderRenderTools::m_numgllights;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index dc638d1a43a..3c2d4ac8e35 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -55,6 +55,7 @@ class KX_BlenderRenderTools : public RAS_IRenderTools
bool m_lastlighting;
static unsigned int m_numgllights;
+
public:
KX_BlenderRenderTools();
@@ -100,7 +101,16 @@ public:
void* tface);
bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+
+ virtual void MotionBlur(RAS_IRasterizer* rasterizer);
+
+ virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
+
+ virtual void Render2DFilters(RAS_ICanvas* canvas);
+
};
#endif //__KX_BLENDERRENDERTOOLS
+
+
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 2a7503d610d..b38599685af 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -43,6 +43,7 @@
#include "KX_GameObject.h"
#include "STR_HashedString.h"
#include "DNA_action_types.h"
+#include "DNA_nla_types.h"
#include "DNA_actuator_types.h"
#include "BKE_action.h"
#include "DNA_armature_types.h"
@@ -384,7 +385,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
/* Find percentages */
newweight = (m_blendframe/(float)m_blendin);
- blend_poses(m_pose, m_blendpose, 1.0 - newweight, POSE_BLEND);
+ blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
/* Increment current blending percentage */
m_blendframe = (curtime - m_blendstart)*KX_FIXED_FRAME_PER_SEC;
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 0e2a009a192..271385bb144 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1514,7 +1514,8 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
default:
break;
}
-
+ delete shapeprops;
+ delete smmaterial;
}
@@ -1599,7 +1600,8 @@ static KX_GameObject *gameobject_from_blenderobject(
KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
gameobj = gamecamera;
- gamecamera->AddRef();
+ //don't add a reference: the camera list in kxscene->m_cameras is not released at the end
+ //gamecamera->AddRef();
kxscene->AddCamera(gamecamera);
break;
@@ -1845,6 +1847,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
vector<parentChildLink> vec_parent_child;
CListValue* objectlist = kxscene->GetObjectList();
+ CListValue* inactivelist = kxscene->GetInactiveList();
CListValue* parentlist = kxscene->GetRootParentList();
SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
@@ -1852,7 +1855,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
CListValue* logicbrick_conversionlist = new CListValue();
- SG_TreeFactory tf;
+ //SG_TreeFactory tf;
// Convert actions to actionmap
bAction *curAct;
@@ -1913,10 +1916,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
eulxyzPrev[0]=blenderobject->rot[0];
eulxyzPrev[1]=blenderobject->rot[1];
eulxyzPrev[2]=blenderobject->rot[2];
- tmp.scale((float)blenderscene->r.frs_sec,(float)blenderscene->r.frs_sec,(float)blenderscene->r.frs_sec);
+
+ double fps = (double) blenderscene->r.frs_sec/
+ (double) blenderscene->r.frs_sec_base;
+
+ tmp.scale(fps, fps, fps);
inivel.push_back(tmp);
tmp=eulxyz-eulxyzPrev;
- tmp.scale((float)blenderscene->r.frs_sec,(float)blenderscene->r.frs_sec,(float)blenderscene->r.frs_sec);
+ tmp.scale(fps, fps, fps);
iniang.push_back(tmp);
blenderscene->r.cfra=blenderscene->r.sfra;
update_for_newframe();
@@ -1986,19 +1993,35 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (isInActiveLayer)
{
objectlist->Add(gameobj->AddRef());
- tf.Add(gameobj->GetSGNode());
+ //tf.Add(gameobj->GetSGNode());
gameobj->NodeUpdateGS(0,true);
gameobj->Bucketize();
}
+ else
+ {
+ //we must store this object otherwise it will be deleted
+ //at the end of this function if it is not a root object
+ inactivelist->Add(gameobj->AddRef());
+ }
if (converter->addInitFromFrame){
gameobj->NodeSetLocalPosition(posPrev);
gameobj->NodeSetLocalOrientation(angor);
}
}
-
+ /* Note about memory leak issues:
+ When a CValue derived class is created, m_refcount is initialized to 1
+ so the class must be released after being used to make sure that it won't
+ hang in memory. If the object needs to be stored for a long time,
+ use AddRef() so that this Release() does not free the object.
+ Make sure that for any AddRef() there is a Release()!!!!
+ Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
+ */
+ if (gameobj)
+ gameobj->Release();
+
base = base->next;
}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index d8e5a255a7c..e9ec6f9116b 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -175,7 +175,7 @@ void BL_SkinDeformer::Update(void)
for (int v =0; v<m_bmesh->totvert; v++)
VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
- armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, m_bmesh->totvert, ARM_DEF_VGROUP, NULL );
+ armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
RecalcNormals();
/* Update the current frame */
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 44e62f1601a..7fbec8679fb 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -123,29 +123,29 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
delete (ipoList);
}
- vector<KX_WorldInfo*>::iterator itw = m_worldinfos.begin();
+ vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin();
while (itw != m_worldinfos.end()) {
- delete (*itw);
+ delete (*itw).second;
itw++;
}
- vector<RAS_IPolyMaterial*>::iterator itp = m_polymaterials.begin();
+ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
while (itp != m_polymaterials.end()) {
- delete (*itp);
+ delete (*itp).second;
itp++;
}
// delete after RAS_IPolyMaterial
- vector<BL_Material *>::iterator itmat = m_materials.begin();
+ vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
while (itmat != m_materials.end()) {
- delete (*itmat);
+ delete (*itmat).second;
itmat++;
}
- vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin();
+ vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
while (itm != m_meshobjects.end()) {
- delete (*itm);
+ delete (*itm).second;
itm++;
}
@@ -229,6 +229,11 @@ struct BlenderDebugDraw : public btIDebugDraw
}
}
+ virtual void reportErrorWarning(const char* warningString)
+ {
+
+ }
+
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
{
//not yet
@@ -258,6 +263,9 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
Scene *blenderscene = GetSceneForName2(m_maggie, scenename);
e_PhysicsEngine physics_engine = UseBullet;
+ // hook for registration function during conversion.
+ m_currentScene = destinationscene;
+ destinationscene->SetSceneConverter(this);
if (blenderscene)
{
@@ -355,16 +363,90 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
m_alwaysUseExpandFraming
);
+ //These lookup are not needed during game
m_map_blender_to_gameactuator.clear();
m_map_blender_to_gamecontroller.clear();
-
m_map_blender_to_gameobject.clear();
- m_map_mesh_to_gamemesh.clear();
- //don't clear it yet, it is needed for the baking physics into ipo animation
+ //Clearing this lookup table has the effect of disabling the cache of meshes
+ //between scenes, even if they are shared in the blend file.
+ //This cache mecanism is buggy so I leave it disable and the memory leak
+ //that would result from this is fixed in RemoveScene()
+ m_map_mesh_to_gamemesh.clear();
+ //Don't clear this lookup, it is needed for the baking physics into ipo animation
+ //To avoid it's infinite grows, object will be unregister when they are deleted
+ //see KX_Scene::NewRemoveObject
//m_map_gameobject_to_blender.clear();
}
+// This function removes all entities stored in the converter for that scene
+// It should be used instead of direct delete scene
+// Note that there was some provision for sharing entities (meshes...) between
+// scenes but that is now disabled so all scene will have their own copy
+// and we can delete them here. If the sharing is reactivated, change this code too..
+// (see KX_BlenderSceneConverter::ConvertScene)
+void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
+{
+ int i, size;
+ // delete the scene first as it will stop the use of entities
+ delete scene;
+ // delete the entities of this scene
+ vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
+ size = m_worldinfos.size();
+ for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
+ if ((*worldit).first == scene) {
+ delete (*worldit).second;
+ *worldit = m_worldinfos.back();
+ m_worldinfos.pop_back();
+ size--;
+ } else {
+ i++;
+ worldit++;
+ }
+ }
+
+ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
+ size = m_polymaterials.size();
+ for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
+ if ((*polymit).first == scene) {
+ delete (*polymit).second;
+ *polymit = m_polymaterials.back();
+ m_polymaterials.pop_back();
+ size--;
+ } else {
+ i++;
+ polymit++;
+ }
+ }
+
+ vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
+ size = m_materials.size();
+ for (i=0, matit=m_materials.begin(); i<size; ) {
+ if ((*matit).first == scene) {
+ delete (*matit).second;
+ *matit = m_materials.back();
+ m_materials.pop_back();
+ size--;
+ } else {
+ i++;
+ matit++;
+ }
+ }
+
+ vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
+ size = m_meshobjects.size();
+ for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
+ if ((*meshit).first == scene) {
+ delete (*meshit).second;
+ *meshit = m_meshobjects.back();
+ m_meshobjects.pop_back();
+ size--;
+ } else {
+ i++;
+ meshit++;
+ }
+ }
+}
// use blender materials
void KX_BlenderSceneConverter::SetMaterials(bool val)
@@ -380,7 +462,7 @@ bool KX_BlenderSceneConverter::GetMaterials()
void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
{
- m_materials.push_back(mat);
+ m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
}
@@ -401,6 +483,11 @@ void KX_BlenderSceneConverter::RegisterGameObject(
m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
}
+void KX_BlenderSceneConverter::UnregisterGameObject(
+ KX_GameObject *gameobject)
+{
+ m_map_gameobject_to_blender.remove(CHashedPtr(gameobject));
+}
KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
@@ -428,7 +515,7 @@ void KX_BlenderSceneConverter::RegisterGameMesh(
struct Mesh *for_blendermesh)
{
m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
- m_meshobjects.push_back(gamemesh);
+ m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
}
@@ -453,7 +540,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
{
- m_polymaterials.push_back(polymat);
+ m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
}
@@ -518,7 +605,7 @@ SCA_IController *KX_BlenderSceneConverter::FindGameController(
void KX_BlenderSceneConverter::RegisterWorldInfo(
KX_WorldInfo *worldinfo)
{
- m_worldinfos.push_back(worldinfo);
+ m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
}
/*
@@ -548,7 +635,7 @@ extern "C"
{
Ipo *add_ipo( char *name, int idcode );
char *getIpoCurveName( IpoCurve * icu );
- struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, int);
+ struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
void testhandles_ipocurve(struct IpoCurve *icu);
void Mat3ToEul(float tmat[][3], float *eul);
@@ -761,27 +848,27 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_X);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_Y);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_Z);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_X);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_Y);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_Z);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z);
@@ -791,7 +878,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = position.x();
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
#endif
@@ -800,7 +887,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = position.y();
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
@@ -810,7 +897,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = position.z();
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
#endif
@@ -819,7 +906,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = eulerAngles[0];
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
@@ -829,7 +916,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = eulerAngles[1];
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
@@ -839,7 +926,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
if (icu1)
{
float curVal = eulerAngles[2];
- insert_vert_ipo(icu1, frameNumber, curVal);
+ insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
testhandles_ipocurve(icu1);
@@ -917,27 +1004,27 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_X);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_Y);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_LOC_Z);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_X);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_Y);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y);
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
if (!icu1)
- icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, OB_ROT_Z);
+ icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z);
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index a897922d51b..8ac5386d442 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -51,10 +51,13 @@ struct SpaceIpo;
class KX_BlenderSceneConverter : public KX_ISceneConverter
{
- vector<KX_WorldInfo*> m_worldinfos;
- vector<RAS_IPolyMaterial*> m_polymaterials;
- vector<RAS_MeshObject*> m_meshobjects;
- vector<BL_Material *> m_materials;
+ // Use vector of pairs to allow removal of entities between scene switch
+ vector<pair<KX_Scene*,KX_WorldInfo*> > m_worldinfos;
+ vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials;
+ vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects;
+ vector<pair<KX_Scene*,BL_Material *> > m_materials;
+ // Should also have a list of collision shapes.
+ // For the time being this is held in KX_Scene::m_shapes
GEN_Map<CHashedPtr,struct Object*> m_map_gameobject_to_blender;
GEN_Map<CHashedPtr,KX_GameObject*> m_map_blender_to_gameobject;
@@ -72,6 +75,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
STR_String m_newfilename;
class KX_KetsjiEngine* m_ketsjiEngine;
+ class KX_Scene* m_currentScene; // Scene being converted
bool m_alwaysUseExpandFraming;
bool m_usemat;
@@ -99,6 +103,7 @@ public:
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas
);
+ virtual void RemoveScene(class KX_Scene *scene);
void SetNewFileName(const STR_String& filename);
bool TryAndLoadNewFile();
@@ -106,6 +111,7 @@ public:
void SetAlwaysUseExpandFraming(bool to_what);
void RegisterGameObject(KX_GameObject *gameobject, struct Object *for_blenderobject);
+ void UnregisterGameObject(KX_GameObject *gameobject);
KX_GameObject *FindGameObject(struct Object *for_blenderobject);
struct Object *FindBlenderObject(KX_GameObject *for_gameobject);
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index a6baa04b045..f76a0fb82e5 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -37,6 +37,8 @@
#define BLENDER_HACK_DTIME 0.02
+#include "MEM_guardedalloc.h"
+
#include "KX_BlenderSceneConverter.h"
#include "KX_ConvertActuators.h"
@@ -45,6 +47,7 @@
#include "SCA_PropertyActuator.h"
#include "SCA_LogicManager.h"
#include "SCA_RandomActuator.h"
+#include "SCA_2DFilterActuator.h"
// Ketsji specific logicbricks
@@ -69,7 +72,7 @@
#include "KX_GameObject.h"
/* This little block needed for linking to Blender... */
-
+#include "BKE_text.h"
#include "BLI_blenlib.h"
#include "KX_NetworkMessageActuator.h"
@@ -836,7 +839,84 @@ void BL_ConvertActuators(char* maggiename,
baseact = tmp_vis_act;
}
break;
+
+ case ACT_2DFILTER:
+ {
+ bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
+ SCA_2DFilterActuator *tmp = NULL;
+ RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode;
+ switch(_2dfilter->type)
+ {
+ case ACT_2DFILTER_MOTIONBLUR:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR;
+ break;
+ case ACT_2DFILTER_BLUR:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_BLUR;
+ break;
+ case ACT_2DFILTER_SHARPEN:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_SHARPEN;
+ break;
+ case ACT_2DFILTER_DILATION:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_DILATION;
+ break;
+ case ACT_2DFILTER_EROSION:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_EROSION;
+ break;
+ case ACT_2DFILTER_LAPLACIAN:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_LAPLACIAN;
+ break;
+ case ACT_2DFILTER_SOBEL:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_SOBEL;
+ break;
+ case ACT_2DFILTER_PREWITT:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_PREWITT;
+ break;
+ case ACT_2DFILTER_GRAYSCALE:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_GRAYSCALE;
+ break;
+ case ACT_2DFILTER_SEPIA:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_SEPIA;
+ break;
+ case ACT_2DFILTER_INVERT:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_INVERT;
+ break;
+ case ACT_2DFILTER_CUSTOMFILTER:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_CUSTOMFILTER;
+ break;
+ case ACT_2DFILTER_NOFILTER:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
+ break;
+ case ACT_2DFILTER_DISABLED:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_DISABLED;
+ break;
+ case ACT_2DFILTER_ENABLED:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_ENABLED;
+ break;
+ default:
+ filtermode = RAS_2DFilterManager::RAS_2DFILTER_NOFILTER;
+ break;
+ }
+
+ tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
+ _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),rendertools);
+
+ if (_2dfilter->text)
+ {
+ char *buf;
+ // this is some blender specific code
+ buf = txt_to_buf(_2dfilter->text);
+ if (buf)
+ {
+ tmp->SetShaderText(STR_String(buf));
+ MEM_freeN(buf);
+ }
+ }
+
+ baseact = tmp;
+
+ }
+ break;
default:
; /* generate some error */
}
@@ -854,9 +934,12 @@ void BL_ConvertActuators(char* maggiename,
gameobj->AddActuator(baseact);
converter->RegisterGameActuator(baseact, bact);
+ // done with baseact, release it
+ baseact->Release();
}
bact = bact->next;
}
}
+
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 5b30f5a4a2e..b277af7dbc2 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -174,6 +174,8 @@ void BL_ConvertControllers(
gameobj->AddController(gamecontroller);
converter->RegisterGameController(gamecontroller, bcontr);
+ //done with gamecontroller
+ gamecontroller->Release();
}
bcontr = bcontr->next;
diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp
index a1807732416..ebfb45066b7 100644
--- a/source/gameengine/Converter/KX_ConvertProperties.cpp
+++ b/source/gameengine/Converter/KX_ConvertProperties.cpp
@@ -105,8 +105,9 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
// set a subproperty called 'timer' so that
// we can register the replica of this property
// at the time a game object is replicated (AddObjectActuator triggers this)
-
- timeval->SetProperty("timer",new CBoolValue(true));
+ CValue *bval = new CBoolValue(true);
+ timeval->SetProperty("timer",bval);
+ bval->Release();
if (isInActiveLayer)
{
timemgr->AddTimeProperty(timeval);
@@ -128,6 +129,8 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
{
scene->AddDebugProperty(gameobj,STR_String(prop->name));
}
+ // done with propval, release it
+ propval->Release();
}
prop = prop->next;
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 40c15302553..61759ddf654 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -386,8 +386,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
bool bFindMaterial = false;
PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
- if (isInActiveLayer)
- kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
+ //will be done in KX_TouchEventManager::RegisterSensor()
+ //if (isInActiveLayer)
+ // kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
@@ -732,6 +733,8 @@ void BL_ConvertSensors(struct Object* blenderobject,
logicmgr->RegisterToSensor(gamecont,gamesensor);
}
}
+ // done with gamesensor
+ gamesensor->Release();
}
sens=sens->next;
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
index defcdffb6fc..2cf29e9dd62 100644
--- a/source/gameengine/Converter/KX_IpoConvert.cpp
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -100,9 +100,9 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
ipocontr->GetIPOTransform().SetPosition(
MT_Point3(
- blenderobject->loc[0]+blenderobject->dloc[0],
- blenderobject->loc[1]+blenderobject->dloc[1],
- blenderobject->loc[2]+blenderobject->dloc[2]
+ blenderobject->loc[0]/*+blenderobject->dloc[0]*/,
+ blenderobject->loc[1]/*+blenderobject->dloc[1]*/,
+ blenderobject->loc[2]/*+blenderobject->dloc[2]*/
)
);
ipocontr->GetIPOTransform().SetEulerAngles(
@@ -134,7 +134,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetPosition()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_LOC_X, true);
}
@@ -145,7 +145,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetPosition()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_LOC_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_LOC_Z);
@@ -155,7 +155,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetPosition()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_LOC_Z, true);
}
// Master the art of cut & paste programming...
@@ -167,7 +167,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaPosition()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_DLOC_X, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DLOC_Y);
@@ -177,7 +177,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaPosition()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_DLOC_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DLOC_Z);
@@ -187,7 +187,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaPosition()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyPosition(true);
+ ipocontr->SetIPOChannelActive(OB_DLOC_Z, true);
}
// Explore the finesse of reuse and slight modification
@@ -199,7 +199,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetEulerAngles()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_ROT_X, true);
}
ipo = ipoList->GetScalarInterpolator(OB_ROT_Y);
if (ipo) {
@@ -208,7 +208,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetEulerAngles()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_ROT_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_ROT_Z);
if (ipo) {
@@ -217,7 +217,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetEulerAngles()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_ROT_Z, true);
}
// Hmmm, the need for a macro comes to mind...
@@ -229,7 +229,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_DROT_X, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DROT_Y);
if (ipo) {
@@ -238,7 +238,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_DROT_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DROT_Z);
if (ipo) {
@@ -247,7 +247,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyOrientation(true);
+ ipocontr->SetIPOChannelActive(OB_DROT_Z, true);
}
// Hang on, almost there...
@@ -259,7 +259,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetScaling()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_SIZE_X, true);
}
ipo = ipoList->GetScalarInterpolator(OB_SIZE_Y);
if (ipo) {
@@ -268,7 +268,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetScaling()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_SIZE_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_SIZE_Z);
if (ipo) {
@@ -277,7 +277,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetScaling()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_SIZE_Z, true);
}
// The last few...
@@ -289,7 +289,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaScaling()[0]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_DSIZE_X, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Y);
if (ipo) {
@@ -298,7 +298,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaScaling()[1]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_DSIZE_Y, true);
}
ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Z);
if (ipo) {
@@ -307,7 +307,7 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
&(ipocontr->GetIPOTransform().GetDeltaScaling()[2]),
ipo);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyScaling(true);
+ ipocontr->SetIPOChannelActive(OB_DSIZE_Z, true);
}
{
diff --git a/source/gameengine/Expressions/Expression.cpp b/source/gameengine/Expressions/Expression.cpp
index 5c5e1abea34..f16f572c322 100644
--- a/source/gameengine/Expressions/Expression.cpp
+++ b/source/gameengine/Expressions/Expression.cpp
@@ -22,7 +22,9 @@
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-
+#ifdef _DEBUG
+//int gRefCountExpr;
+#endif
CExpression::CExpression()// : m_cached_calculate(NULL)
{
m_refcount = 1;
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 48898dfc1f5..56208ab4ad5 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -169,7 +169,28 @@ PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
return pyname;
}
+/*#define CVALUE_DEBUG*/
+#ifdef CVALUE_DEBUG
+int gRefCount;
+struct SmartCValueRef
+{
+ CValue *m_ref;
+ int m_count;
+ SmartCValueRef(CValue *ref)
+ {
+ m_ref = ref;
+ m_count = gRefCount++;
+ }
+};
+#include <vector>
+
+std::vector<SmartCValueRef> gRefList;
+#endif
+
+#ifdef _DEBUG
+//int gRefCountValue;
+#endif
CValue::CValue(PyTypeObject *T)
: PyObjectPlus(T),
@@ -186,6 +207,12 @@ effect: constucts a CValue
*/
{
//debug(gRefCountValue++) // debugging
+#ifdef _DEBUG
+ //gRefCountValue++;
+#ifdef CVALUE_DEBUG
+ gRefList.push_back(SmartCValueRef(this));
+#endif
+#endif
}
@@ -199,6 +226,18 @@ effect: deletes the object
ClearProperties();
assertd (m_refcount==0);
+#ifdef CVALUE_DEBUG
+ std::vector<SmartCValueRef>::iterator it;
+ for (it=gRefList.begin(); it!=gRefList.end(); it++)
+ {
+ if (it->m_ref == this)
+ {
+ *it = gRefList.back();
+ gRefList.pop_back();
+ break;
+ }
+ }
+#endif
}
@@ -293,7 +332,7 @@ void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
}
// Add property at end of array
- (*m_pNamedPropertyArray)[name] = ioProperty;//->Add(ioProperty);
+ (*m_pNamedPropertyArray)[name] = ioProperty->AddRef();//->Add(ioProperty);
}
@@ -356,10 +395,13 @@ bool CValue::RemoveProperty(const STR_String & inName)
if (m_pNamedPropertyArray == NULL)
return false;
- // Scan all properties, as soon as we find one with <inName> -> Remove it
-// CValue* val = (*m_pNamedPropertyArray)[inName];
- if (m_pNamedPropertyArray->erase(inName)) return true;
-
+ CValue* val = GetProperty(inName);
+ if (NULL != val)
+ {
+ val->Release();
+ m_pNamedPropertyArray->erase(inName);
+ return true;
+ }
return false;
}
@@ -379,7 +421,7 @@ void CValue::ClearProperties()
!(it == m_pNamedPropertyArray->end());it++)
{
CValue* tmpval = (*it).second;
- STR_String name = (*it).first;
+ //STR_String name = (*it).first;
tmpval->Release();
}
@@ -469,8 +511,9 @@ void CValue::CloneProperties(CValue *replica)
for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
!(it == m_pNamedPropertyArray->end());it++)
{
-
- replica->SetProperty((*it).first,(*it).second->GetReplica());
+ CValue *val = (*it).second->GetReplica();
+ replica->SetProperty((*it).first,val);
+ val->Release();
}
}
@@ -489,10 +532,6 @@ double* CValue::GetVector3(bool bGetTransformedVec)
}
-
-
-
-
/*---------------------------------------------------------------------------------------------------------------------
Reference Counting
---------------------------------------------------------------------------------------------------------------------*/
@@ -504,6 +543,9 @@ CValue *CValue::AddRef()
// Increase global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue++);
+#ifdef _DEBUG
+ //gRefCountValue++;
+#endif
m_refcount++;
return this;
}
@@ -518,7 +560,9 @@ int CValue::Release()
// Decrease global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue--);
-
+#ifdef _DEBUG
+ //gRefCountValue--;
+#endif
// Decrease local reference count, if it reaches 0 the object should be freed
if (--m_refcount > 0)
{
@@ -546,6 +590,9 @@ void CValue::DisableRefCount()
m_refcount--;
//debug(gRefCountValue--);
+#ifdef _DEBUG
+ //gRefCountValue--;
+#endif
m_ValFlags.RefCountDisabled=true;
}
@@ -590,11 +637,14 @@ CValue* CValue::FindIdentifier(const STR_String& identifiername)
} else
{
result = GetProperty(identifiername);
+ if (result)
+ return result->AddRef();
+ }
+ if (!result)
+ {
+ // warning here !!!
+ result = new CErrorValue(identifiername+" not found");
}
- if (result)
- return result->AddRef();
- // warning here !!!
- result = new CErrorValue(identifiername+" not found");
return result;
}
@@ -717,7 +767,7 @@ int CValue::_setattr(const STR_String& attr,PyObject* pyobj)
oldprop->SetValue(vallie);
} else
{
- SetProperty(attr,vallie->AddRef());
+ SetProperty(attr,vallie);
}
vallie->Release();
}
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index 127edfc151d..4f40fa22b9e 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -35,6 +35,7 @@ SET(INC
../../../intern/string
../../../source/gameengine/Expressions
../../../intern/moto/include
+ ../../../source/gameengine/Rasterizer
${PYTHON_INC}
${SDL_INC}
)
diff --git a/source/gameengine/GameLogic/Makefile b/source/gameengine/GameLogic/Makefile
index eab4e7faa7e..aea1e463146 100644
--- a/source/gameengine/GameLogic/Makefile
+++ b/source/gameengine/GameLogic/Makefile
@@ -42,6 +42,7 @@ include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += -I../Expressions
+CPPFLAGS += -I../Rasterizer
CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
new file mode 100644
index 00000000000..f3b5b1fdda2
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -0,0 +1,118 @@
+#include "SCA_IActuator.h"
+
+#include "SCA_2DFilterActuator.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <iostream>
+
+
+SCA_2DFilterActuator::~SCA_2DFilterActuator()
+{
+}
+
+SCA_2DFilterActuator::SCA_2DFilterActuator(
+ SCA_IObject *gameobj,
+ RAS_2DFilterManager::RAS_2DFILTER_MODE type,
+ short flag,
+ float float_arg,
+ int int_arg,
+ RAS_IRasterizer* rasterizer,
+ RAS_IRenderTools* rendertools,
+ PyTypeObject* T)
+ : SCA_IActuator(gameobj, T),
+ m_type(type),
+ m_flag(flag),
+ m_int_arg(int_arg),
+ m_float_arg(float_arg),
+ m_rasterizer(rasterizer),
+ m_rendertools(rendertools)
+{
+}
+
+void SCA_2DFilterActuator::SetShaderText(STR_String text)
+{
+ m_shaderText = text;
+}
+
+
+
+CValue* SCA_2DFilterActuator::GetReplica()
+{
+ SCA_2DFilterActuator* replica = new SCA_2DFilterActuator(*this);
+ replica->ProcessReplica();
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+bool SCA_2DFilterActuator::Update()
+{
+ bool result = false;
+
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ if( m_type == RAS_2DFilterManager::RAS_2DFILTER_MOTIONBLUR )
+ {
+ if(!m_flag)
+ {
+ m_rasterizer->EnableMotionBlur(m_float_arg);
+ }
+ else
+ {
+ m_rasterizer->DisableMotionBlur();
+ }
+ }
+ else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
+ {
+ m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText);
+ }
+ return true;
+}
+
+
+PyTypeObject SCA_2DFilterActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "SCA_2DFilterActuator",
+ sizeof(SCA_2DFilterActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0,
+ __repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+PyParentObject SCA_2DFilterActuator::Parents[] = {
+ &SCA_2DFilterActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+PyMethodDef SCA_2DFilterActuator::Methods[] = {
+ /* add python functions to deal with m_msg... */
+ {NULL,NULL}
+};
+
+
+PyObject* SCA_2DFilterActuator::_getattr(const STR_String& attr) {
+ _getattr_up(SCA_IActuator);
+}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
new file mode 100644
index 00000000000..7b0cfff951e
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -0,0 +1,44 @@
+#ifndef __SCA_2DFILETRACTUATOR_H__
+#define __SCA_2DFILETRACTUATOR_H__
+
+#include "RAS_IRasterizer.h"
+#include "RAS_IRenderTools.h"
+#include "SCA_IActuator.h"
+
+
+class SCA_2DFilterActuator : public SCA_IActuator
+{
+ Py_Header;
+
+private:
+
+ RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
+ short m_flag;
+ float m_float_arg;
+ int m_int_arg;
+ STR_String m_shaderText;
+ RAS_IRasterizer* m_rasterizer;
+ RAS_IRenderTools* m_rendertools;
+
+public:
+
+ SCA_2DFilterActuator(
+ class SCA_IObject* gameobj,
+ RAS_2DFilterManager::RAS_2DFILTER_MODE type,
+ short flag,
+ float float_arg,
+ int int_arg,
+ RAS_IRasterizer* rasterizer,
+ RAS_IRenderTools* rendertools,
+ PyTypeObject* T=&Type
+ );
+
+ void SetShaderText(STR_String text);
+ virtual ~SCA_2DFilterActuator();
+ virtual bool Update();
+
+ virtual CValue* GetReplica();
+ virtual PyObject* _getattr(const STR_String& attr);
+
+};
+#endif
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index b1d210fd1c1..fae1b5dfa6b 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -55,7 +55,9 @@ SCA_IObject::~SCA_IObject()
SCA_SensorList::iterator its;
for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
{
- ((CValue*)(*its))->Release();
+ //Use Delete for sensor to ensure proper cleaning
+ (*its)->Delete();
+ //((CValue*)(*its))->Release();
}
SCA_ControllerList::iterator itc;
for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
@@ -99,6 +101,7 @@ SCA_ActuatorList& SCA_IObject::GetActuators()
void SCA_IObject::AddSensor(SCA_ISensor* act)
{
+ act->AddRef();
m_sensors.push_back(act);
}
@@ -106,6 +109,7 @@ void SCA_IObject::AddSensor(SCA_ISensor* act)
void SCA_IObject::AddController(SCA_IController* act)
{
+ act->AddRef();
m_controllers.push_back(act);
}
@@ -113,6 +117,7 @@ void SCA_IObject::AddController(SCA_IController* act)
void SCA_IObject::AddActuator(SCA_IActuator* act)
{
+ act->AddRef();
m_actuators.push_back(act);
}
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 43dd6bef83e..1a65f8311ed 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -160,6 +160,8 @@ PyMethodDef SCA_ISensor::Methods[] = {
METH_VARARGS, GetInvert_doc},
{"setInvert", (PyCFunction) SCA_ISensor::sPySetInvert,
METH_VARARGS, SetInvert_doc},
+ {"evaluate", (PyCFunction) SCA_ISensor::sPyEvaluate,
+ METH_VARARGS, Evaluate_doc},
{NULL,NULL} //Sentinel
};
@@ -331,4 +333,14 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb
Py_Return;
}
+char SCA_ISensor::Evaluate_doc[] =
+"evaluate()\n"
+"\tRe-evaluate the sensor so that isPositive() and other methods are up to date\n"
+"\twith current game conditions. BGE does it automatically on each frame so it's\n"
+"\tnot usually needed.\n"
+"\tReturns True or False if the sensor evaluates positively or negatively\n";
+PyObject* SCA_ISensor::PyEvaluate(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return BoolToPyArg(Evaluate(NULL));
+}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index fb2dca97d06..8de4480cf2e 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -97,6 +97,11 @@ public:
bool negmode,
int freq);
+ /** Release sensor
+ * 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 void Delete() { Release(); }
/** Set inversion of pulses on or off. */
void SetInvert(bool inv);
@@ -122,6 +127,7 @@ public:
KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
+ KX_PYMETHOD_DOC(SCA_ISensor,Evaluate);
};
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index fb8c340b09e..4898dbed95f 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -212,6 +212,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
newprop.SetLength(oldlength - 1);
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
} else {
/* append */
@@ -219,6 +220,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
STR_String newprop = tprop->GetText() + pchar;
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
} else {
if (!IsDelete(keyIndex)) {
@@ -227,6 +229,7 @@ void SCA_KeyboardSensor::AddToTargetProp(int keyIndex)
STR_String newprop = pchar;
CStringValue * newstringprop = new CStringValue(newprop, m_targetprop);
GetParent()->SetProperty(m_targetprop, newstringprop);
+ newstringprop->Release();
}
}
}
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index 8b79703a6fc..048d6992c73 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -51,6 +51,10 @@ SCA_LogicManager::SCA_LogicManager()
SCA_LogicManager::~SCA_LogicManager()
{
+ /* AddRef() is not used when the objects are added to m_mapStringToGameObjects
+ so Release() should not be used either. The memory leak big is fixed
+ in BL_ConvertBlenderObjects()
+
int numgameobj = m_mapStringToGameObjects.size();
for (int i = 0; i < numgameobj; i++)
{
@@ -58,8 +62,9 @@ SCA_LogicManager::~SCA_LogicManager()
assert(gameobjptr);
if (gameobjptr)
(*gameobjptr)->Release();
-
+
}
+ */
/*for (int i=0;i<m_sensorcontrollermap.size();i++)
{
vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]);
@@ -72,6 +77,8 @@ SCA_LogicManager::~SCA_LogicManager()
}
m_eventmanagers.clear();
m_sensorcontrollermapje.clear();
+ m_removedActuators.clear();
+ m_activeActuators.clear();
}
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index c3e2066fc65..c798503ae8a 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -90,12 +90,11 @@ bool SCA_PropertyActuator::Update()
if (oldprop)
{
oldprop->SetValue(newval);
- newval->Release();
} else
{
propowner->SetProperty(m_propname,newval);
}
-
+ newval->Release();
break;
}
case KX_ACT_PROP_ADD:
@@ -123,9 +122,11 @@ bool SCA_PropertyActuator::Update()
CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
if (copyprop)
{
+ CValue *val = copyprop->GetReplica();
GetParent()->SetProperty(
m_propname,
- copyprop->GetReplica());
+ val);
+ val->Release();
}
}
@@ -239,11 +240,12 @@ PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, Py
CValue* prop = GetParent()->FindIdentifier(nameArg);
- if (prop) {
+ if (!prop->IsError()) {
m_propname = nameArg;
} else {
; /* not found ... */
}
+ prop->Release();
Py_Return;
}
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index 09332b870c9..cdd0666947e 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -66,11 +66,11 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
//CValue* resultval = m_rightexpr->Calculate();
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
m_previoustext = orgprop->GetText();
- orgprop->Release();
}
+ orgprop->Release();
if (m_checktype==KX_PROPSENSOR_INTERVAL)
{
@@ -82,16 +82,28 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
void SCA_PropertySensor::PrecalculateRangeExpression()
{
CParser pars;
+ //The context is needed to retrieve the property at runtime but it creates
+ //loop of references
pars.SetContext(this->AddRef());
STR_String checkstr = "(" + m_checkpropval + " <= "
+ m_checkpropname + ") && ( "
+ m_checkpropname + " <= "
- + m_checkpropmaxval;
+ + m_checkpropmaxval + ")";
m_range_expr = pars.ProcessText(checkstr);
}
-
+// Forced deletion of precalculated range expression to break reference loop
+// Use this function when you know that you won't use the sensor anymore
+void SCA_PropertySensor::Delete()
+{
+ if (m_range_expr)
+ {
+ m_range_expr->Release();
+ m_range_expr = NULL;
+ }
+ Release();
+}
CValue* SCA_PropertySensor::GetReplica()
{
@@ -164,7 +176,7 @@ bool SCA_PropertySensor::CheckPropertyCondition()
case KX_PROPSENSOR_EQUAL:
{
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
STR_String testprop = orgprop->GetText();
// Force strings to upper case, to avoid confusion in
@@ -177,9 +189,8 @@ bool SCA_PropertySensor::CheckPropertyCondition()
} else {
result = (orgprop->GetText() == m_checkpropval);
}
- orgprop->Release();
-
}
+ orgprop->Release();
if (reverse)
result = !result;
@@ -244,15 +255,15 @@ bool SCA_PropertySensor::CheckPropertyCondition()
{
CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
- if (orgprop)
+ if (!orgprop->IsError())
{
if (m_previoustext != orgprop->GetText())
{
m_previoustext = orgprop->GetText();
result = true;
}
- orgprop->Release();
}
+ orgprop->Release();
//cout << " \nSens:Prop:changed!"; /* need implementation here!!! */
break;
@@ -388,12 +399,13 @@ PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyOb
return NULL;
}
- if (FindIdentifier(STR_String(propNameArg))) {
+ CValue *prop = FindIdentifier(STR_String(propNameArg));
+ if (!prop->IsError()) {
m_checkpropname = propNameArg;
} else {
; /* error: bad property name */
}
-
+ prop->Release();
Py_Return;
}
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index 0ebcacdb21a..77cc3dc8a5c 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -77,6 +77,7 @@ public:
KX_PROPSENSOR_TYPE checktype,
PyTypeObject* T=&Type );
+ virtual void Delete();
virtual ~SCA_PropertySensor();
virtual CValue* GetReplica();
void PrecalculateRangeExpression();
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index 474ad08eee3..b0e69076a3e 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -61,6 +61,7 @@ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj,
m_parameter2(para2),
m_distribution(mode)
{
+ // m_base is never deleted, probably a memory leak!
m_base = new SCA_RandomNumberGenerator(seed);
m_counter = 0;
enforceConstraints();
@@ -78,6 +79,7 @@ SCA_RandomActuator::~SCA_RandomActuator()
CValue* SCA_RandomActuator::GetReplica()
{
SCA_RandomActuator* replica = new SCA_RandomActuator(*this);
+ // replication just copy the m_base pointer => common random generator
replica->ProcessReplica();
CValue::AddDataToReplica(replica);
@@ -432,12 +434,12 @@ PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyOb
CValue* prop = GetParent()->FindIdentifier(nameArg);
- if (prop) {
+ if (!prop->IsError()) {
m_propname = nameArg;
- prop->Release();
} else {
; /* not found ... */
}
+ prop->Release();
Py_Return;
}
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index f747504a697..56c7ed538b8 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -54,11 +54,15 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
: SCA_ISensor(gameobj,eventmgr, T)
{
m_iteration = 0;
+ m_interval = 0;
m_lastdraw = false;
+ // m_basegenerator is never deleted => memory leak
m_basegenerator = new SCA_RandomNumberGenerator(startseed);
m_currentDraw = m_basegenerator->Draw();
- RegisterToManager();
+ //registration is done globally, don't do it here
+ //Note: it was probably done to work around a bug in Evaluate(). It is now fixed
+ //RegisterToManager();
}
@@ -73,6 +77,7 @@ SCA_RandomSensor::~SCA_RandomSensor()
CValue* SCA_RandomSensor::GetReplica()
{
CValue* replica = new SCA_RandomSensor(*this);
+ // replication copies m_basegenerator pointer => share same generator
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
@@ -98,20 +103,25 @@ bool SCA_RandomSensor::Evaluate(CValue* event)
/* this is a reasonable way of generating bools. Check Knuth. */
/* Furthermore, we only draw each <delay>-eth frame. */
- bool drawResult = false;
-
- if (m_iteration > 31) {
- m_currentDraw = m_basegenerator->Draw();
- drawResult = (m_currentDraw & 0x1) == 0;
- m_iteration = 1;
- } else {
- drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
- m_iteration++;
+ bool evaluateResult = false;
+
+ if (++m_interval > m_pulse_frequency) {
+ bool drawResult = false;
+ m_interval = 0;
+ if (m_iteration > 31) {
+ m_currentDraw = m_basegenerator->Draw();
+ drawResult = (m_currentDraw & 0x1) == 0;
+ m_iteration = 1;
+ } else {
+ drawResult = ((m_currentDraw >> m_iteration) & 0x1) == 0;
+ m_iteration++;
+ }
+ evaluateResult = drawResult != m_lastdraw;
+ m_lastdraw = drawResult;
}
/* now pass this result to some controller */
- m_lastdraw = drawResult;
- return drawResult;
+ return evaluateResult;
}
/* ------------------------------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index 1a3c0402e31..08bb5226be1 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -45,6 +45,7 @@ class SCA_RandomSensor : public SCA_ISensor
unsigned int m_currentDraw;
int m_iteration;
+ int m_interval;
SCA_RandomNumberGenerator *m_basegenerator;
bool m_lastdraw;
public:
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index 7a2c3d91e72..1ca884f6dec 100755..100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -5,6 +5,7 @@ sources = env.Glob('*.cpp') + env.Glob('Joystick/*.cpp')
incs = '. #/source/kernel/gen_system #/intern/string'
incs += ' #/source/gameengine/Expressions #/intern/moto/include'
+incs += ' #/source/gameengine/Rasterizer'
incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_SDL_INC']
diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp
index dbe875957b0..8bbac10f7ca 100644
--- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.cpp
@@ -32,6 +32,8 @@
#include "GPC_KeyboardDevice.h"
+#include <cstdlib>
+
/**
* NextFrame toggles currentTable with previousTable,
* and copies relevant event information from previous to current table
diff --git a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
index 5b3c2c84edb..840230902f8 100644
--- a/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_PolygonMaterial.cpp
@@ -43,8 +43,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index 0f6bec30437..388882e67e4 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -570,4 +570,37 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
}
}
+void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
+{
+ int state = rasterizer->GetMotionBlurState();
+ float motionblurvalue;
+ if(state)
+ {
+ motionblurvalue = rasterizer->GetMotionBlurValue();
+ if(state==1)
+ {
+ //bugfix:load color buffer into accum buffer for the first time(state=1)
+ glAccum(GL_LOAD, 1.0);
+ rasterizer->SetMotionBlurState(2);
+ }
+ else if(motionblurvalue>=0.0 && motionblurvalue<=1.0)
+ {
+ glAccum(GL_MULT, motionblurvalue);
+ glAccum(GL_ACCUM, 1-motionblurvalue);
+ glAccum(GL_RETURN, 1.0);
+ glFlush();
+ }
+ }
+}
+
+void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
+{
+ m_filtermanager.EnableFilter(filtermode, pass, text);
+}
+
+void GPC_RenderTools::Render2DFilters(RAS_ICanvas* canvas)
+{
+ m_filtermanager.RenderFilters( canvas);
+}
+
unsigned int GPC_RenderTools::m_numgllights;
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index b7f73df3c34..d90f0e5da45 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -149,6 +149,13 @@ public:
int applyLights(int objectlayer);
bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+
+ virtual void MotionBlur(RAS_IRasterizer* rasterizer);
+
+ virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
+
+ virtual void Render2DFilters(RAS_ICanvas* canvas);
+
protected:
/**
* Copied from KX_BlenderGL.cpp in KX_blenderhook
@@ -173,3 +180,5 @@ protected:
#endif // __GPC_RENDERTOOLS_H
+
+
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 0d2aa774394..5ef20514390 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -46,8 +46,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include "GPG_Application.h"
@@ -533,7 +537,11 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
goto initFailed;
if(useLists)
- m_rasterizer = new RAS_ListRasterizer(m_canvas);
+ if (useVertexArrays) {
+ m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
+ } else {
+ m_rasterizer = new RAS_ListRasterizer(m_canvas);
+ }
else if (useVertexArrays && bgl::QueryVersion(1, 1))
m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
else
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index b0eb1d9c2ca..0993446c77b 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -34,10 +34,6 @@
#include <iostream>
#include <math.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifdef __linux__
#ifdef __alpha__
#include <signal.h>
@@ -290,7 +286,7 @@ int main(int argc, char** argv)
bool fullScreenParFound = false;
bool windowParFound = false;
bool closeConsole = true;
- RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+ RAS_IRasterizer::StereoMode stereomode;
bool stereoWindow = false;
bool stereoParFound = false;
int windowLeft = 100;
@@ -301,14 +297,13 @@ int main(int argc, char** argv)
GHOST_TUns32 fullScreenHeight= 0;
int fullScreenBpp = 32;
int fullScreenFrequency = 60;
-
+
#ifdef __linux__
#ifdef __alpha__
signal (SIGFPE, SIG_IGN);
#endif /* __alpha__ */
#endif /* __linux__ */
BLI_where_am_i(bprogname, argv[0]);
-
#ifdef __APPLE__
// Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
/*
@@ -334,12 +329,9 @@ int main(int argc, char** argv)
GEN_init_messaging_system();
// Parse command line options
-#ifdef WIN32
#ifndef NDEBUG
printf("argv[0] = '%s'\n", argv[0]);
#endif
-#endif //WIN32
-
#ifdef WIN32
if (scr_saver_init(argc, argv))
@@ -370,11 +362,9 @@ int main(int argc, char** argv)
;)
{
-#ifdef WIN32
#ifndef NDEBUG
printf("argv[%d] = '%s' , %i\n", i, argv[i],argc);
#endif
-#endif //WIN32
if (argv[i][0] == '-')
{
switch (argv[i][1])
@@ -397,11 +387,9 @@ int main(int argc, char** argv)
SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
-#ifdef WIN32
#ifndef NDEBUG
printf("%s = '%s'\n", paramname, argv[i]);
#endif
-#endif //WIN32
i++;
}
else
@@ -412,7 +400,7 @@ int main(int argc, char** argv)
}
else
{
- SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
+// SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
}
}
}
@@ -533,13 +521,16 @@ int main(int argc, char** argv)
printf("error: window size too small.\n");
}
- if (error)
+ if (error )
{
usage(argv[0]);
+ return 0;
}
- else
+
+ if (!stereoParFound) stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
+
#ifdef WIN32
- if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
+ if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
#endif
{
#ifdef __APPLE__
@@ -547,6 +538,7 @@ int main(int argc, char** argv)
SYS_WriteCommandLineInt(syshandle, "nomipmap", 1);
//fullScreen = false; // Can't use full screen
#endif
+
if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0))
{
GPC_PolygonMaterial::SetMipMappingEnabled(0);
@@ -768,7 +760,7 @@ int main(int argc, char** argv)
printf("error: couldn't create a system.\n");
}
}
-
+
return error ? -1 : 0;
}
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index ab0479eb88b..3b74b74727a 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -9,8 +9,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include <iostream>
#include "BL_Shader.h"
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index d6b57f062f2..53e1af46e4e 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -8,8 +8,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include <iostream>
#include <map>
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index 86f114b2f51..51cfe30179c 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -142,7 +142,11 @@ bool KX_NetworkMessageSensor::Evaluate(CValue* event)
result = (WasUp != m_IsUp);
- // Return true if the message received state has changed.
+ // Return always true if a message was received otherwise we can loose messages
+ if (m_IsUp)
+ return true;
+ // Is it usefull to return also true when the first frame without a message??
+ // This will cause a fast on/off cycle that seems useless!
return result;
}
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index fa1c67f251c..c3aa83bec69 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -15,8 +15,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include "KX_BlenderMaterial.h"
#include "BL_Material.h"
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index aa5d1f1cec1..aa7c75e9633 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -24,7 +24,18 @@ CcdPhysicsController(ci)
KX_BulletPhysicsController::~KX_BulletPhysicsController ()
{
-
+ // The game object has a direct link to
+ if (m_pObject)
+ {
+ // If we cheat in SetObject, we must also cheat here otherwise the
+ // object will still things it has a physical controller
+ // Note that it requires that m_pObject is reset in case the object is deleted
+ // before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec)
+ // The non usual case is when the object is not deleted because its reference is hanging
+ // in a AddObject actuator but the node is deleted. This case is covered here.
+ KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject();
+ gameobj->SetPhysicsController(NULL,false);
+ }
}
void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
@@ -58,6 +69,7 @@ void KX_BulletPhysicsController::SetObject (SG_IObject* object)
}
+
void KX_BulletPhysicsController::setMargin (float collisionMargin)
{
CcdPhysicsController::SetMargin(collisionMargin);
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 011443054a7..b75662f01c9 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -32,7 +32,8 @@
*/
#include "KX_Camera.h"
-
+#include "KX_Scene.h"
+#include "KX_PythonInit.h"
#include "KX_Python.h"
#include "KX_PyMath.h"
#ifdef HAVE_CONFIG_H
@@ -57,7 +58,9 @@ KX_Camera::KX_Camera(void* sgReplicationInfo,
m_name = "cam";
m_projection_matrix.setIdentity();
m_modelview_matrix.setIdentity();
- SetProperty("camera",new CIntValue(1));
+ CValue* val = new CIntValue(1);
+ SetProperty("camera",val);
+ val->Release();
}
@@ -391,6 +394,7 @@ PyMethodDef KX_Camera::Methods[] = {
KX_PYMETHODTABLE(KX_Camera, setProjectionMatrix),
KX_PYMETHODTABLE(KX_Camera, enableViewport),
KX_PYMETHODTABLE(KX_Camera, setViewport),
+ KX_PYMETHODTABLE(KX_Camera, setOnTop),
{NULL,NULL} //Sentinel
};
@@ -759,3 +763,15 @@ KX_PYMETHODDEF_DOC(KX_Camera, setViewport,
}
Py_Return;
}
+
+KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
+"setOnTop()\n"
+"Sets this camera's viewport on top\n")
+{
+ class KX_Scene* scene;
+
+ scene = PHY_GetActiveScene();
+ MT_assert(scene);
+ scene->SetCameraOnTop(this);
+ Py_Return;
+}
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 60f0b107940..34a3d2f2653 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -251,6 +251,7 @@ public:
KX_PYMETHOD_DOC(KX_Camera, enableViewport);
KX_PYMETHOD_DOC(KX_Camera, setViewport);
+ KX_PYMETHOD_DOC(KX_Camera, setOnTop);
virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index fcc793ec5c9..465a021cd43 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -682,8 +682,6 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
#endif //WIN32
-static GEN_Map<GEN_HashedPtr,btCollisionShape*> map_gamemesh_to_bulletshape;
-
// forward declarations
static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool polytope)
{
@@ -701,14 +699,6 @@ static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool
int numPoints = 0;
btVector3* points = 0;
- btCollisionShape** shapeptr = map_gamemesh_to_bulletshape[GEN_HashedPtr(meshobj)];
-
- // Mesh has already been converted: reuse
- if (shapeptr)
- {
- //return *shapeptr;
- }
-
// Mesh has no polygons!
int numpolys = meshobj->NumPolygons();
if (!numpolys)
@@ -850,13 +840,15 @@ static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool
if (numvalidpolys > 0)
{
- //map_gamemesh_to_bulletshape.insert(GEN_HashedPtr(meshobj),collisionMeshShape);
if (!polytope)
{
- concaveShape = new btBvhTriangleMeshShape( collisionMeshData );
+ bool useQuantization = true;
+ concaveShape = new btBvhTriangleMeshShape( collisionMeshData, useQuantization );
//concaveShape = new btTriangleMeshShape( collisionMeshData );
concaveShape->recalcLocalAabb();
+ if (collisionMeshShape)
+ delete collisionMeshShape;
collisionMeshShape = concaveShape;
}
@@ -865,8 +857,10 @@ static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool
return collisionMeshShape;
}
-
- delete collisionMeshShape;
+ if (collisionMeshShape)
+ delete collisionMeshShape;
+ if (collisionMeshData)
+ delete collisionMeshData;
return NULL;
}
@@ -1020,7 +1014,10 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
// ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
if (!bm)
+ {
+ delete motionstate;
return;
+ }
bm->setMargin(0.06);
@@ -1056,6 +1053,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
compoundShape->addChildShape(childTrans,bm);
+ kxscene->AddShape(bm);
//do some recalc?
//recalc inertia for rigidbody
if (!rigidbody->isStaticOrKinematicObject())
@@ -1075,6 +1073,9 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
btTransform identTrans;
identTrans.setIdentity();
compoundShape->addChildShape(identTrans,bm);
+ //note abount compoundShape: Bullet does not delete the child shapes when
+ //the compound shape is deleted, so insert also the child shapes
+ kxscene->AddShape(bm);
bm = compoundShape;
}
@@ -1111,9 +1112,6 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_collisionShape = bm;
-
-
-
ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
ci.m_restitution = smmaterial->m_restitution;
ci.m_physicsEnv = env;
@@ -1122,8 +1120,12 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
//need a bit of damping, else system doesn't behave well
ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
-
+ ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
+ ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
+
KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
+ //remember that we created a shape so that we can delete it when the scene is removed (bullet will not delete it)
+ kxscene->AddShape(bm);
if (objprop->m_in_active_layer)
{
@@ -1187,17 +1189,6 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
void KX_ClearBulletSharedShapes()
{
- int numshapes = map_gamemesh_to_bulletshape.size();
- int i;
- btCollisionShape*shape=0;
- for (i=0;i<numshapes ;i++)
- {
- shape = *map_gamemesh_to_bulletshape.at(i);
- //delete shape;
- }
-
- map_gamemesh_to_bulletshape.clear();
-
}
#endif
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 67c82ee2082..bc608d26c50 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -105,7 +105,19 @@ KX_GameObject::~KX_GameObject()
delete m_pClient_info;
//if (m_pSGNode)
// delete m_pSGNode;
-
+ if (m_pSGNode)
+ {
+ // must go through controllers and make sure they will not use us anymore
+ // This is important for KX_BulletPhysicsControllers that unregister themselves
+ // from the object when they are deleted.
+ SGControllerList::iterator contit;
+ SGControllerList& controllers = m_pSGNode->GetSGControllerList();
+ for (contit = controllers.begin();contit!=controllers.end();++contit)
+ {
+ (*contit)->ClearObject();
+ }
+ m_pSGNode->SetSGClientObject(NULL);
+ }
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index f3bf529a37d..db910a46a81 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -416,7 +416,7 @@ public:
void
UpdateIPO(
float curframetime,
- bool resurse,
+ bool recurse,
bool ipo_as_force,
bool force_ipo_local
);
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
index 920a65be0fb..a4cb9970492 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -51,20 +51,21 @@ typedef unsigned long uint_ptr;
#include "KX_ScalarInterpolator.h"
#include "KX_GameObject.h"
#include "KX_IPhysicsController.h"
+#include "DNA_ipo_types.h"
+#include "BLI_arithb.h"
// All objects should start on frame 1! Will we ever need an object to
// start on another frame, the 1.0 should change.
KX_IpoSGController::KX_IpoSGController()
-: m_modify_position(false),
- m_modify_orientation(false),
- m_modify_scaling(false),
- m_ipo_as_force(false),
+: m_ipo_as_force(false),
m_force_ipo_acts_local(false),
m_modified(true),
+ m_ipo_start_initialized(false),
m_ipotime(1.0)
{
m_game_object = NULL;
-
+ for (int i=0; i < KX_MAX_IPO_CHANNELS; i++)
+ m_ipo_channels_active[i] = false;
}
@@ -115,21 +116,60 @@ bool KX_IpoSGController::Update(double currentTime)
}
SG_Spatial* ob = (SG_Spatial*)m_pObject;
-
- if (m_modify_position) {
- if (m_ipo_as_force) {
-
- if (m_game_object && ob) {
+
+ //initialization on the first frame of the IPO
+ if (! m_ipo_start_initialized && currentTime > 0.0) {
+ m_ipo_start_point = ob->GetLocalPosition();
+ m_ipo_start_orient = ob->GetLocalOrientation();
+ m_ipo_start_scale = ob->GetLocalScale();
+ m_ipo_start_initialized = true;
+ }
+
+ //modifies position?
+ if (m_ipo_channels_active[OB_LOC_X] || m_ipo_channels_active[OB_LOC_Y] || m_ipo_channels_active[OB_LOC_Z] || m_ipo_channels_active[OB_DLOC_X] || m_ipo_channels_active[OB_DLOC_Y] || m_ipo_channels_active[OB_DLOC_Z])
+ {
+ if (m_ipo_as_force == true)
+ {
+ if (m_game_object && ob)
+ {
m_game_object->GetPhysicsController()->ApplyForce(m_force_ipo_acts_local ?
ob->GetWorldOrientation() * m_ipo_xform.GetPosition() :
m_ipo_xform.GetPosition(), false);
}
-
- } else {
- ob->SetLocalPosition(m_ipo_xform.GetPosition());
+ }
+ else
+ {
+ //by default, leave object as it stands
+ MT_Point3 newPosition = ob->GetLocalPosition();
+ //apply separate IPO channels if there is any data in them
+ //Loc and dLoc act by themselves or are additive
+ //LocX and dLocX
+ if (m_ipo_channels_active[OB_LOC_X]) {
+ newPosition[0] = (m_ipo_channels_active[OB_DLOC_X] ? m_ipo_xform.GetPosition()[0] + m_ipo_xform.GetDeltaPosition()[0] : m_ipo_xform.GetPosition()[0]);
+ }
+ else if (m_ipo_channels_active[OB_DLOC_X] && m_ipo_start_initialized) {
+ newPosition[0] = (m_ipo_start_point[0] + m_ipo_xform.GetDeltaPosition()[0]);
+ }
+ //LocY and dLocY
+ if (m_ipo_channels_active[OB_LOC_Y]) {
+ newPosition[1] = (m_ipo_channels_active[OB_DLOC_Y] ? m_ipo_xform.GetPosition()[1] + m_ipo_xform.GetDeltaPosition()[1] : m_ipo_xform.GetPosition()[1]);
+ }
+ else if (m_ipo_channels_active[OB_DLOC_Y] && m_ipo_start_initialized) {
+ newPosition[1] = (m_ipo_start_point[1] + m_ipo_xform.GetDeltaPosition()[1]);
+ }
+ //LocZ and dLocZ
+ if (m_ipo_channels_active[OB_LOC_Z]) {
+ newPosition[2] = (m_ipo_channels_active[OB_DLOC_Z] ? m_ipo_xform.GetPosition()[2] + m_ipo_xform.GetDeltaPosition()[2] : m_ipo_xform.GetPosition()[2]);
+ }
+ else if (m_ipo_channels_active[OB_DLOC_Z] && m_ipo_start_initialized) {
+ newPosition[2] = (m_ipo_start_point[2] + m_ipo_xform.GetDeltaPosition()[2]);
+ }
+
+ ob->SetLocalPosition(newPosition);
}
}
- if (m_modify_orientation) {
+ //modifies orientation?
+ if (m_ipo_channels_active[OB_ROT_X] || m_ipo_channels_active[OB_ROT_Y] || m_ipo_channels_active[OB_ROT_Z] || m_ipo_channels_active[OB_DROT_X] || m_ipo_channels_active[OB_DROT_Y] || m_ipo_channels_active[OB_DROT_Z]) {
if (m_ipo_as_force) {
if (m_game_object && ob) {
@@ -137,13 +177,71 @@ bool KX_IpoSGController::Update(double currentTime)
ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() :
m_ipo_xform.GetEulerAngles(), false);
}
-
} else {
- ob->SetLocalOrientation(MT_Matrix3x3(m_ipo_xform.GetEulerAngles()));
+ double yaw, pitch, roll; //final Euler angles
+ double tempYaw=0, tempPitch=0, tempRoll=0; //temp holders
+ ob->GetLocalOrientation().getEuler(yaw, pitch, roll);
+
+ //RotX and dRotX
+ if (m_ipo_channels_active[OB_ROT_X]) {
+ yaw = (m_ipo_channels_active[OB_DROT_X] ? (m_ipo_xform.GetEulerAngles()[0] + m_ipo_xform.GetDeltaEulerAngles()[0]) : m_ipo_xform.GetEulerAngles()[0] );
+ }
+ else if (m_ipo_channels_active[OB_DROT_X] && m_ipo_start_initialized) {
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ yaw = tempYaw + m_ipo_xform.GetDeltaEulerAngles()[0];
+ }
+
+ //RotY dRotY
+ if (m_ipo_channels_active[OB_ROT_Y]) {
+ pitch = (m_ipo_channels_active[OB_DROT_Y] ? (m_ipo_xform.GetEulerAngles()[1] + m_ipo_xform.GetDeltaEulerAngles()[1]) : m_ipo_xform.GetEulerAngles()[1] );
+ }
+ else if (m_ipo_channels_active[OB_DROT_Y] && m_ipo_start_initialized) {
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ pitch = tempPitch + m_ipo_xform.GetDeltaEulerAngles()[1];
+ }
+
+ //RotZ and dRotZ
+ if (m_ipo_channels_active[OB_ROT_Z]) {
+ roll = (m_ipo_channels_active[OB_DROT_Z] ? (m_ipo_xform.GetEulerAngles()[2] + m_ipo_xform.GetDeltaEulerAngles()[2]) : m_ipo_xform.GetEulerAngles()[2] );
+ }
+ else if (m_ipo_channels_active[OB_DROT_Z] && m_ipo_start_initialized) {
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ roll = tempRoll + m_ipo_xform.GetDeltaEulerAngles()[2];
+ }
+
+ ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll));
}
}
- if (m_modify_scaling)
- ob->SetLocalScale(m_ipo_xform.GetScaling());
+ //modifies scale?
+ if (m_ipo_channels_active[OB_SIZE_X] || m_ipo_channels_active[OB_SIZE_Y] || m_ipo_channels_active[OB_SIZE_Z] || m_ipo_channels_active[OB_DSIZE_X] || m_ipo_channels_active[OB_DSIZE_Y] || m_ipo_channels_active[OB_DSIZE_Z]) {
+ //default is no scale change
+ MT_Vector3 newScale = ob->GetLocalScale();
+
+ if (m_ipo_channels_active[OB_SIZE_X]) {
+ newScale[0] = (m_ipo_channels_active[OB_DSIZE_X] ? (m_ipo_xform.GetScaling()[0] + m_ipo_xform.GetDeltaScaling()[0]) : m_ipo_xform.GetScaling()[0]);
+ }
+ else if (m_ipo_channels_active[OB_DSIZE_X] && m_ipo_start_initialized) {
+ newScale[0] = (m_ipo_xform.GetDeltaScaling()[0] + m_ipo_start_scale[0]);
+ }
+
+ //RotY dRotY
+ if (m_ipo_channels_active[OB_SIZE_Y]) {
+ newScale[1] = (m_ipo_channels_active[OB_DSIZE_Y] ? (m_ipo_xform.GetScaling()[1] + m_ipo_xform.GetDeltaScaling()[1]): m_ipo_xform.GetScaling()[1]);
+ }
+ else if (m_ipo_channels_active[OB_DSIZE_Y] && m_ipo_start_initialized) {
+ newScale[1] = (m_ipo_xform.GetDeltaScaling()[1] + m_ipo_start_scale[1]);
+ }
+
+ //RotZ and dRotZ
+ if (m_ipo_channels_active[OB_SIZE_Z]) {
+ newScale[2] = (m_ipo_channels_active[OB_DSIZE_Z] ? (m_ipo_xform.GetScaling()[2] + m_ipo_xform.GetDeltaScaling()[2]) : m_ipo_xform.GetScaling()[2]);
+ }
+ else if (m_ipo_channels_active[OB_DSIZE_Z] && m_ipo_start_initialized) {
+ newScale[2] = (m_ipo_xform.GetDeltaScaling()[2] + m_ipo_start_scale[2]);
+ }
+
+ ob->SetLocalScale(newScale);
+ }
m_modified=false;
}
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h
index 3b20f47f5fc..1ebd6900741 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.h
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.h
@@ -38,27 +38,40 @@
#include "KX_IPOTransform.h"
#include "KX_IInterpolator.h"
+#define KX_MAX_IPO_CHANNELS 19 //note- [0] is not used
+
class KX_IpoSGController : public SG_Controller
{
KX_IPOTransform m_ipo_xform;
T_InterpolatorList m_interpolators;
- /* Why not bools? */
- short m_modify_position : 1;
- short m_modify_orientation : 1;
- short m_modify_scaling : 1;
+
+ /** Flag for each IPO channel that can be applied to a game object */
+ bool m_ipo_channels_active[KX_MAX_IPO_CHANNELS];
/** Interpret the ipo as a force rather than a displacement? */
bool m_ipo_as_force;
/** Ipo-as-force acts in local rather than in global coordinates? */
bool m_force_ipo_acts_local;
-
+
/** Were settings altered since the last update? */
bool m_modified;
/** Local time of this ipo.*/
double m_ipotime;
+ /** Location of the object when the IPO is first fired (for local transformations) */
+ class MT_Point3 m_ipo_start_point;
+
+ /** Orientation of the object when the IPO is first fired (for local transformations) */
+ class MT_Matrix3x3 m_ipo_start_orient;
+
+ /** Scale of the object when the IPO is first fired (for local transformations) */
+ class MT_Vector3 m_ipo_start_scale;
+
+ /** if IPO initial position has been set for local normal IPO */
+ bool m_ipo_start_initialized;
+
/** A reference to the original game object. */
class KX_GameObject* m_game_object;
@@ -80,16 +93,12 @@ public:
/** Set reference to the corresponding game object. */
void SetGameObject(class KX_GameObject*);
- void SetModifyPosition(bool modifypos) {
- m_modify_position=modifypos;
- }
- void SetModifyOrientation(bool modifyorient) {
- m_modify_orientation=modifyorient;
- }
- void SetModifyScaling(bool modifyscale) {
- m_modify_scaling=modifyscale;
+ void SetIPOChannelActive(int index, bool value) {
+ //indexes found in makesdna\DNA_ipo_types.h
+ m_ipo_channels_active[index] = value;
}
+
KX_IPOTransform& GetIPOTransform()
{
return m_ipo_xform;
@@ -105,3 +114,4 @@ public:
#endif //__IPO_SGCONTROLLER_H
+
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index 2e4250dfe1e..b2ec49b31ac 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -55,6 +55,8 @@ public:
class RAS_IRenderTools* rendertools,
class RAS_ICanvas* canvas)=0;
+ virtual void RemoveScene(class KX_Scene *scene)=0;
+
virtual void SetAlwaysUseExpandFraming(bool to_what) = 0;
virtual void SetNewFileName(const STR_String& filename) = 0;
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index b72e29e955f..287634fc7ec 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -66,7 +66,7 @@ STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp";
class CIpoAction : public CAction
{
float m_curtime;
- bool m_resurse;
+ bool m_recurse;
KX_GameObject* m_gameobj;
bool m_ipo_as_force;
bool m_force_ipo_local;
@@ -78,7 +78,7 @@ public:
bool ipo_as_force,
bool force_ipo_local) :
m_curtime(curtime) ,
- m_resurse(recurse),
+ m_recurse(recurse),
m_gameobj(gameobj),
m_ipo_as_force(ipo_as_force),
m_force_ipo_local(force_ipo_local)
@@ -90,7 +90,7 @@ public:
{
m_gameobj->UpdateIPO(
m_curtime,
- m_resurse,
+ m_recurse,
m_ipo_as_force,
m_force_ipo_local);
};
@@ -211,12 +211,6 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
(*i)->Release();
}
m_events.clear();
-
- if (m_type != KX_ACT_IPO_PLAY)
- {
- if (bNegativeEvent)
- RemoveAllEvents();
- }
}
double start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0);
@@ -226,6 +220,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
{
if (m_starttime < -2.0*start_smaller_then_end*(m_endframe - m_startframe))
{
+ // start for all Ipo, initial start for LOOP_STOP
m_starttime = curtime - KX_KetsjiEngine::GetSuspendedDelta();
m_bIpoPlaying = true;
}
@@ -238,17 +233,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
{
// Check if playing forwards. result = ! finished
- if (!bNegativeEvent)
- {
- if (start_smaller_then_end > 0.0)
- result = (m_localtime < m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
- else
- result = (m_localtime > m_endframe && !(m_localtime == m_startframe && bNegativeEvent));
- }
+ if (start_smaller_then_end > 0.0)
+ result = (m_localtime < m_endframe && m_bIpoPlaying);
else
- {
- result = (m_bIpoPlaying && (m_localtime < m_endframe));
- }
+ result = (m_localtime > m_endframe && m_bIpoPlaying);
if (result)
{
@@ -267,7 +255,6 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
} else
{
m_localtime=m_startframe;
- SetStartTime(curtime);
m_direction=1;
}
break;
@@ -275,7 +262,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
case KX_ACT_IPO_PINGPONG:
{
result = true;
- if (bNegativeEvent && ((m_localtime == m_startframe )|| (m_localtime == m_endframe)))
+ if (bNegativeEvent && !m_bIpoPlaying)
result = false;
else
SetLocalTime(curtime);
@@ -297,14 +284,18 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
}
case KX_ACT_IPO_FLIPPER:
{
- result = !(bNegativeEvent && (m_localtime == m_startframe));
+ if (bNegativeEvent && !m_bIpoPlaying)
+ result = false;
if (numevents)
{
+ float oldDirection = m_direction;
if (bNegativeEvent)
m_direction = -1;
else
m_direction = 1;
- SetStartTime(curtime);
+ if (m_direction != oldDirection)
+ // changing direction, reset start time
+ SetStartTime(curtime);
}
SetLocalTime(curtime);
@@ -332,18 +323,26 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
m_bNegativeEvent = false;
numevents = 0;
}
- SetStartTime(curtime);
+ if (!m_bIpoPlaying)
+ {
+ // Ipo was stopped, make sure we will restart from where it stopped
+ SetStartTime(curtime);
+ if (!bNegativeEvent)
+ // positive signal will restart the Ipo
+ m_bIpoPlaying = true;
+ }
+
} // fall through to loopend, and quit the ipo animation immediatly
}
case KX_ACT_IPO_LOOPEND:
{
if (numevents){
- if (bNegativeEvent){
+ if (bNegativeEvent && m_bIpoPlaying){
m_bNegativeEvent = true;
}
}
- if (bNegativeEvent && m_localtime == m_startframe){
+ if (bNegativeEvent && !m_bIpoPlaying){
result = false;
}
else
@@ -414,8 +413,12 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
result = false;
}
- if (!result && m_type != KX_ACT_IPO_LOOPSTOP)
- m_starttime = -2.0*start_smaller_then_end*(m_endframe - m_startframe) - 1.0;
+ if (!result)
+ {
+ if (m_type != KX_ACT_IPO_LOOPSTOP)
+ m_starttime = -2.0*start_smaller_then_end*(m_endframe - m_startframe) - 1.0;
+ m_bIpoPlaying = false;
+ }
return result;
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index e76e28bcb7b..b879dd2ebee 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -631,10 +631,10 @@ void KX_KetsjiEngine::Render()
RenderFrame(scene, cam);
}
- set<class KX_Camera*>* cameras = scene->GetCameras();
+ list<class KX_Camera*>* cameras = scene->GetCameras();
// Draw the scene once for each camera with an enabled viewport
- set<KX_Camera*>::iterator it = cameras->begin();
+ list<KX_Camera*>::iterator it = cameras->begin();
while(it != cameras->end())
{
if((*it)->GetViewport())
@@ -966,9 +966,17 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
scene->CalculateVisibleMeshes(m_rasterizer,cam);
scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+ PostRenderFrame();
}
-
+void KX_KetsjiEngine::PostRenderFrame()
+{
+ m_rendertools->PushMatrix();
+ m_rendertools->Render2DFilters(m_canvas);
+ m_rendertools->MotionBlur(m_rasterizer);
+ m_rendertools->PopMatrix();
+}
void KX_KetsjiEngine::StopEngine()
{
@@ -985,7 +993,7 @@ void KX_KetsjiEngine::StopEngine()
for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
{
KX_Scene* scene = *sceneit;
- delete scene;
+ m_sceneconverter->RemoveScene(scene);
}
m_scenes.clear();
@@ -1039,6 +1047,8 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
scene->SetActiveCamera(activecam);
scene->GetObjectList()->Add(activecam->AddRef());
scene->GetRootParentList()->Add(activecam->AddRef());
+ //done with activecam
+ activecam->Release();
}
scene->UpdateParents(0.0);
@@ -1207,7 +1217,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
KX_Scene* scene = *sceneit;
if (scene->GetName()==scenename)
{
- delete scene;
+ m_sceneconverter->RemoveScene(scene);
m_scenes.erase(sceneit);
break;
}
@@ -1305,7 +1315,7 @@ void KX_KetsjiEngine::ReplaceScheduledScenes()
KX_Scene* scene = *sceneit;
if (scene->GetName() == oldscenename)
{
- delete scene;
+ m_sceneconverter->RemoveScene(scene);
KX_Scene* tmpscene = CreateScene(newscenename);
m_scenes[i]=tmpscene;
PostProcessScene(tmpscene);
@@ -1463,3 +1473,5 @@ void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
b = m_overrideFrameColorB;
}
+
+
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 16b53b6b688..fcb4d0a0790 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -179,6 +179,7 @@ private:
void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
+ void PostRenderFrame();
void RenderDebugProperties();
void SetBackGround(KX_WorldInfo* worldinfo);
void SetWorldSettings(KX_WorldInfo* worldinfo);
@@ -201,6 +202,8 @@ public:
void SetSceneConverter(KX_ISceneConverter* sceneconverter);
void SetGame2IpoMode(bool game2ipo,int startFrame);
+ RAS_IRasterizer* GetRasterizer(){return m_rasterizer;};
+
///returns true if an update happened to indicate -> Render
bool NextFrame();
void Render();
@@ -342,3 +345,4 @@ protected:
#endif //__KX_KETSJI_ENGINE
+
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 34561045cab..8f85a889d21 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -191,7 +191,36 @@ bool KX_NearSensor::Evaluate(CValue* event)
return result;
}
+// this function is called at broad phase stage to check if the two controller
+// need to interact at all. It is used for Near/Radar sensor that don't need to
+// check collision with object not included in filter
+bool KX_NearSensor::BroadPhaseFilterCollision(void*obj1,void*obj2)
+{
+ KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent());
+
+ // need the mapping from PHY_IPhysicsController to gameobjects now
+ assert(obj1==m_physCtrl && obj2);
+ KX_ClientObjectInfo* client_info = static_cast<KX_ClientObjectInfo*>((static_cast<PHY_IPhysicsController*>(obj2))->getNewClientInfo());
+ KX_GameObject* gameobj = ( client_info ?
+ client_info->m_gameobject :
+ NULL);
+
+ if (gameobj && (gameobj != parent))
+ {
+ // only take valid colliders
+ if (client_info->m_type == KX_ClientObjectInfo::ACTOR)
+ {
+ if ((m_touchedpropname.Length() == 0) ||
+ (gameobj->GetProperty(m_touchedpropname)))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData * coll_data)
{
@@ -208,20 +237,22 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData
client_info->m_gameobject :
NULL);
- if (gameobj && (gameobj != parent))
+ // these checks are done already in BroadPhaseFilterCollision()
+ if (gameobj /*&& (gameobj != parent)*/)
{
if (!m_colliders->SearchValue(gameobj))
m_colliders->Add(gameobj->AddRef());
// only take valid colliders
- if (client_info->m_type == KX_ClientObjectInfo::ACTOR)
- {
- if ((m_touchedpropname.Length() == 0) ||
- (gameobj->GetProperty(m_touchedpropname)))
- {
+ // These checks are done already in BroadPhaseFilterCollision()
+ //if (client_info->m_type == KX_ClientObjectInfo::ACTOR)
+ //{
+ // if ((m_touchedpropname.Length() == 0) ||
+ // (gameobj->GetProperty(m_touchedpropname)))
+ // {
m_bTriggered = true;
m_hitObject = gameobj;
- }
- }
+ // }
+ //}
}
return DT_CONTINUE;
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index d1b8984b91b..599d6cce918 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -77,6 +77,7 @@ public:
virtual void ReParent(SCA_IObject* parent);
virtual bool NewHandleCollision(void* obj1,void* obj2,
const PHY_CollData * coll_data);
+ virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2);
virtual void RegisterSumo(KX_TouchEventManager *touchman);
virtual PyObject* _getattr(const STR_String& attr);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 7a937d5e349..58369ddcab6 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -44,8 +44,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#ifdef WIN32
#pragma warning (disable : 4786)
@@ -618,7 +622,31 @@ static PyObject* gPyMakeScreenshot(PyObject*,
Py_Return;
}
+static PyObject* gPyEnableMotionBlur(PyObject*,
+ PyObject* args,
+ PyObject*)
+{
+ float motionblurvalue;
+ if (PyArg_ParseTuple(args,"f",&motionblurvalue))
+ {
+ if(gp_Rasterizer)
+ {
+ gp_Rasterizer->EnableMotionBlur(motionblurvalue);
+ }
+ }
+ Py_Return;
+}
+static PyObject* gPyDisableMotionBlur(PyObject*,
+ PyObject* args,
+ PyObject*)
+{
+ if(gp_Rasterizer)
+ {
+ gp_Rasterizer->DisableMotionBlur();
+ }
+ Py_Return;
+}
STR_String gPyGetWindowHeight__doc__="getWindowHeight doc";
STR_String gPyGetWindowWidth__doc__="getWindowWidth doc";
@@ -645,6 +673,9 @@ static struct PyMethodDef rasterizer_methods[] = {
{"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
{"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
{"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
+ {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
+ {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_VARARGS,"disable motion blur"},
+
{"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"},
{"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_VARARGS, "get the eye separation for stereo mode"},
@@ -1128,3 +1159,8 @@ void PHY_SetActiveScene(class KX_Scene* scene)
{
gp_KetsjiScene = scene;
}
+
+class KX_Scene* PHY_GetActiveScene()
+{
+ return gp_KetsjiScene;
+}
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index a4c2d1453a6..edb7cfe4a3f 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -53,6 +53,7 @@ void exitGamePythonScripting();
void dictionaryClearByHand(PyObject *dict);
void PHY_SetActiveScene(class KX_Scene* scene);
+class KX_Scene* PHY_GetActiveScene();
#include "MT_Vector3.h"
void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color);
diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp
index 7b13cb1fd7d..ea17e0b3dd6 100644
--- a/source/gameengine/Ketsji/KX_RayCast.cpp
+++ b/source/gameengine/Ketsji/KX_RayCast.cpp
@@ -77,6 +77,14 @@ bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsE
if (callback.RayHit(info, result_point, result_normal))
return true;
+ // There is a bug in the code below: the delta is computed with the wrong
+ // sign on the face opposite to the center, resulting in infinite looping.
+ // In Blender 2.45 this code was never executed because callback.RayHit() always
+ // returned true, causing the ray sensor to stop on the first object.
+ // To avoid changing the behaviour will simply return false here.
+ // It should be discussed if we want the ray sensor to "see" through objects
+ // that don't have the required property/material (condition to get here)
+ return false;
// skip past the object and keep tracing
/* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index ef3ec3e0be3..5c56f8f62b1 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -143,7 +143,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_
}
- return true;
+ return bFound;
}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 45b2db10b33..7366e374a10 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -326,6 +326,8 @@ void KX_SCA_AddObjectActuator::InstantAddObject()
m_lastCreatedObject = replica;
m_lastCreatedObject->AddRef();
+ // finished using replica? then release it
+ replica->Release();
}
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 996c605df21..526f893df5a 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -35,6 +35,7 @@
#pragma warning (disable : 4786)
#endif //WIN32
+
#include "KX_Scene.h"
#include "MT_assert.h"
@@ -74,10 +75,18 @@
#include "NG_NetworkScene.h"
#include "PHY_IPhysicsEnvironment.h"
#include "KX_IPhysicsController.h"
+#include "KX_BlenderSceneConverter.h"
#include "BL_SkinDeformer.h"
#include "BL_DeformableGameObject.h"
+// to get USE_BULLET!
+#include "KX_ConvertPhysicsObject.h"
+
+#ifdef USE_BULLET
+#include "CcdPhysicsEnvironment.h"
+#include "CcdPhysicsController.h"
+#endif
void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
@@ -112,7 +121,8 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_adi(adi),
m_networkDeviceInterface(ndi),
m_active_camera(NULL),
- m_ueberExecutionPriority(0)
+ m_ueberExecutionPriority(0),
+ m_sceneConverter(NULL)
{
m_suspendedtime = 0.0;
m_suspendeddelta = 0.0;
@@ -124,6 +134,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_objectlist = new CListValue();
m_parentlist = new CListValue();
m_lightlist= new CListValue();
+ m_inactivelist = new CListValue();
m_euthanasyobjects = new CListValue();
m_delayReleaseObjects = new CListValue();
@@ -171,12 +182,9 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
KX_Scene::~KX_Scene()
{
-// int numobj = m_objectlist->GetCount();
-
- //int numrootobjects = GetRootParentList()->GetCount();
- for (int i = 0; i < GetRootParentList()->GetCount(); i++)
+ while (GetRootParentList()->GetCount() > 0)
{
- KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(i);
+ KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(0);
this->RemoveObject(parentobj);
}
@@ -186,6 +194,9 @@ KX_Scene::~KX_Scene()
if (m_parentlist)
m_parentlist->Release();
+ if (m_inactivelist)
+ m_inactivelist->Release();
+
if (m_lightlist)
m_lightlist->Release();
@@ -213,11 +224,38 @@ KX_Scene::~KX_Scene()
{
delete m_bucketmanager;
}
-
+#ifdef USE_BULLET
+ // This is a fix for memory leaks in bullet: the collision shapes is not destroyed
+ // when the physical controllers are destroyed. The reason is that shapes are shared
+ // between replicas of an object. There is no reference count in Bullet so the
+ // only workaround that does not involve changes in Bullet is to save in this array
+ // the list of shapes that are created when the scene is created (see KX_ConvertPhysicsObjects.cpp)
+ class btCollisionShape* shape;
+ class btTriangleMeshShape* meshShape;
+ vector<class btCollisionShape*>::iterator it = m_shapes.begin();
+ while (it != m_shapes.end()) {
+ shape = *it;
+ if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ {
+ meshShape = static_cast<btTriangleMeshShape*>(shape);
+ // shapes based on meshes use an interface that contains the vertices.
+ // Again the idea is to be able to share the interface between shapes but
+ // this is not used in Blender: each base object will have its own interface
+ btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
+ if (meshInterface)
+ delete meshInterface;
+ }
+ delete shape;
+ it++;
+ }
+#endif
//Py_DECREF(m_attrlist);
}
-
+void KX_Scene::AddShape(class btCollisionShape*shape)
+{
+ m_shapes.push_back(shape);
+}
void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
@@ -246,6 +284,11 @@ CListValue* KX_Scene::GetRootParentList()
return m_parentlist;
}
+CListValue* KX_Scene::GetInactiveList()
+{
+ return m_inactivelist;
+}
+
CListValue* KX_Scene::GetLightList()
@@ -266,7 +309,7 @@ SCA_TimeEventManager* KX_Scene::GetTimeEventManager()
-set<class KX_Camera*>* KX_Scene::GetCameras()
+list<class KX_Camera*>* KX_Scene::GetCameras()
{
return &m_cameras;
}
@@ -367,8 +410,15 @@ void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj)
{
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
- NewRemoveObject(orgobj);
-
+ if (NewRemoveObject(orgobj) != 0)
+ {
+ // object is not yet deleted (this can happen when it hangs in an add object actuator
+ // last object created reference. It's a bad situation, don't know how to fix it exactly
+ // The least I can do, is remove the reference to the node in the object as the node
+ // will in any case be deleted. This ensures that the object will not try to use the node
+ // when it is finally deleted (see KX_GameObject destructor)
+ orgobj->SetSGNode(NULL);
+ }
if (node)
delete node;
}
@@ -418,7 +468,7 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
replicanode->SetSGClientObject(newobj);
// this is the list of object that are send to the graphics pipeline
- m_objectlist->Add(newobj);
+ m_objectlist->Add(newobj->AddRef());
newobj->Bucketize();
// logic cannot be replicated, until the whole hierarchy is replicated.
@@ -574,7 +624,9 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// add a timebomb to this object
// for now, convert between so called frames and realtime
m_tempObjectList->Add(replica->AddRef());
- replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02));
+ CValue *fval = new CFloatValue(lifespan*0.02);
+ replica->SetProperty("::timebomb",fval);
+ fval->Release();
}
// add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
@@ -637,7 +689,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
-
+ // don't release replica here because we are returning it, not done with it...
return replica;
}
@@ -657,7 +709,8 @@ void KX_Scene::RemoveObject(class CValue* gameobj)
// recursively destruct
node->Destruct();
}
- newobj->SetSGNode(0);
+ //no need to do that: the object is destroyed and memory released
+ //newobj->SetSGNode(0);
}
void KX_Scene::DelayedReleaseObject(CValue* gameobj)
@@ -677,8 +730,9 @@ void KX_Scene::DelayedRemoveObject(class CValue* gameobj)
-void KX_Scene::NewRemoveObject(class CValue* gameobj)
+int KX_Scene::NewRemoveObject(class CValue* gameobj)
{
+ int ret;
KX_GameObject* newobj = (KX_GameObject*) gameobj;
//todo: look at this
@@ -707,6 +761,7 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
{
m_logicmgr->RemoveDestroyedActuator(*ita);
}
+ // the sensors/controllers/actuators must also be released, this is done in ~SCA_IObject
// now remove the timer properties from the time manager
int numprops = newobj->GetPropertyCount();
@@ -721,20 +776,28 @@ void KX_Scene::NewRemoveObject(class CValue* gameobj)
}
newobj->RemoveMeshes();
+ ret = 1;
if (m_objectlist->RemoveValue(newobj))
- newobj->Release();
+ ret = newobj->Release();
if (m_tempObjectList->RemoveValue(newobj))
- newobj->Release();
+ ret = newobj->Release();
if (m_parentlist->RemoveValue(newobj))
- newobj->Release();
+ ret = newobj->Release();
+ if (m_inactivelist->RemoveValue(newobj))
+ ret = newobj->Release();
if (m_euthanasyobjects->RemoveValue(newobj))
- newobj->Release();
+ ret = newobj->Release();
if (newobj == m_active_camera)
{
- m_active_camera->Release();
+ //no AddRef done on m_active_camera so no Release
+ //m_active_camera->Release();
m_active_camera = NULL;
}
+ if (m_sceneConverter)
+ m_sceneConverter->UnregisterGameObject(newobj);
+ // return value will be 0 if the object is actually deleted (all reference gone)
+ return ret;
}
@@ -850,7 +913,7 @@ MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix()
KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
{
- set<KX_Camera*>::iterator it = m_cameras.begin();
+ list<KX_Camera*>::iterator it = m_cameras.begin();
while ( (it != m_cameras.end())
&& ((*it) != cam) ) {
@@ -863,7 +926,7 @@ KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
KX_Camera* KX_Scene::FindCamera(STR_String& name)
{
- set<KX_Camera*>::iterator it = m_cameras.begin();
+ list<KX_Camera*>::iterator it = m_cameras.begin();
while ( (it != m_cameras.end())
&& ((*it)->GetName() != name) ) {
@@ -875,7 +938,8 @@ KX_Camera* KX_Scene::FindCamera(STR_String& name)
void KX_Scene::AddCamera(KX_Camera* cam)
{
- m_cameras.insert(cam);
+ if (!FindCamera(cam))
+ m_cameras.push_back(cam);
}
KX_Camera* KX_Scene::GetActiveCamera()
@@ -896,6 +960,17 @@ void KX_Scene::SetActiveCamera(KX_Camera* cam)
m_active_camera = cam;
}
+void KX_Scene::SetCameraOnTop(KX_Camera* cam)
+{
+ if (!FindCamera(cam)){
+ // adding is always done at the back, so that's all that needs to be done
+ AddCamera(cam);
+ if (cam) std::cout << "Added cam " << cam->GetName() << std::endl;
+ } else {
+ m_cameras.remove(cam);
+ m_cameras.push_back(cam);
+ }
+}
void KX_Scene::UpdateMeshTransformations()
@@ -1099,6 +1174,8 @@ void KX_Scene::LogicEndFrame()
for (i = numobj - 1; i >= 0; i--)
{
KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i);
+ // KX_Scene::RemoveObject will also remove the object from this list
+ // that's why we start from the end
this->RemoveObject(gameobj);
}
@@ -1106,11 +1183,11 @@ void KX_Scene::LogicEndFrame()
for (i = numobj-1;i>=0;i--)
{
KX_GameObject* gameobj = (KX_GameObject*)m_delayReleaseObjects->GetValue(i);
- m_delayReleaseObjects->RemoveValue(gameobj);
-
+ // This list is not for object removal, but just object release
+ gameobj->Release();
}
-
-
+ // empty the list as we have removed all references
+ m_delayReleaseObjects->Resize(0);
}
@@ -1215,6 +1292,11 @@ void KX_Scene::SetNodeTree(SG_Tree* root)
m_objecttree = root;
}
+void KX_Scene::SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter)
+{
+ m_sceneConverter = sceneConverter;
+}
+
void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
{
m_physicsEnvironment = physEnv;
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index ba479c5e543..58120d49dc4 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -39,6 +39,7 @@
#include <vector>
#include <set>
+#include <list>
#include "GEN_Map.h"
#include "GEN_HashedPtr.h"
@@ -84,6 +85,8 @@ class RAS_IPolyMaterial;
class RAS_IRasterizer;
class RAS_IRenderTools;
class SCA_JoystickManager;
+class btCollisionShape;
+class KX_BlenderSceneConverter;
/**
* The KX_Scene holds all data for an independent scene. It relates
* KX_Objects to the specific objects in the modules.
@@ -110,6 +113,7 @@ protected:
CListValue* m_objectlist;
CListValue* m_parentlist; // all 'root' parents
CListValue* m_lightlist;
+ CListValue* m_inactivelist; // all objects that are not in the active layer
/**
* The tree of objects in the scene.
@@ -119,8 +123,12 @@ protected:
/**
* The set of cameras for this scene
*/
- set<class KX_Camera*> m_cameras;
-
+ list<class KX_Camera*> m_cameras;
+ /**
+ * The set of bullet shapes that must be deleted at the end of the scene
+ * to avoid memory leak (not deleted by bullet because shape are shared between replicas)
+ */
+ vector<class btCollisionShape*> m_shapes;
/**
* Various SCA managers used by the scene
*/
@@ -129,10 +137,12 @@ protected:
SCA_MouseManager* m_mousemgr;
SCA_TimeEventManager* m_timemgr;
+ // Scene converter where many scene entities are registered
+ // Used to deregister objects that are deleted
+ class KX_BlenderSceneConverter* m_sceneConverter;
/**
* physics engine abstraction
*/
-
//e_PhysicsEngine m_physicsEngine; //who needs this ?
class PHY_IPhysicsEnvironment* m_physicsEnvironment;
@@ -296,9 +306,10 @@ public:
void DelayedReleaseObject(CValue* gameobj);
- void NewRemoveObject(CValue* gameobj);
+ int NewRemoveObject(CValue* gameobj);
void ReplaceMesh(CValue* gameobj,
void* meshobj);
+ void AddShape(class btCollisionShape* shape);
/**
* @section Logic stuff
* Initiate an update of the logic system.
@@ -315,6 +326,10 @@ public:
);
CListValue*
+ GetInactiveList(
+ );
+
+ CListValue*
GetRootParentList(
);
@@ -330,7 +345,7 @@ public:
GetTimeEventManager(
);
- set<class KX_Camera*>*
+ list<class KX_Camera*>*
GetCameras(
);
@@ -368,6 +383,15 @@ public:
class KX_Camera*
);
+ /**
+ * Move this camera to the end of the list so that it is rendered last.
+ * If the camera is not on the list, it will be added
+ */
+ void
+ SetCameraOnTop(
+ class KX_Camera*
+ );
+
/** Return the viewmatrix as used by the last frame. */
MT_CmMatrix4x4&
GetViewMatrix(
@@ -496,6 +520,8 @@ public:
bool IsClearingZBuffer();
void EnableZBufferClearing(bool isclearingZbuffer);
+ void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
+
class PHY_IPhysicsEnvironment* GetPhysicsEnvironment()
{
return m_physicsEnvironment;
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 4c999b0ed69..8e546b896bc 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -54,6 +54,7 @@ KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
m_physEnv->addTouchCallback(PHY_OBJECT_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
m_physEnv->addTouchCallback(PHY_SENSOR_RESPONSE, KX_TouchEventManager::newCollisionResponse, this);
+ m_physEnv->addTouchCallback(PHY_BROADPH_RESPONSE, KX_TouchEventManager::newBroadphaseResponse, this);
}
@@ -79,6 +80,26 @@ bool KX_TouchEventManager::newCollisionResponse(void *client_data,
return false;
}
+bool KX_TouchEventManager::newBroadphaseResponse(void *client_data,
+ void *object1,
+ void *object2,
+ const PHY_CollData *coll_data)
+{
+ PHY_IPhysicsController* ctrl = static_cast<PHY_IPhysicsController*>(object1);
+ KX_ClientObjectInfo* info = (ctrl) ? static_cast<KX_ClientObjectInfo*>(ctrl->getNewClientInfo()) : NULL;
+ // This call back should only be called for controllers of Near and Radar sensor
+ if (info &&
+ info->m_sensors.size() == 1 &&
+ (info->m_type == KX_ClientObjectInfo::NEAR ||
+ info->m_type == KX_ClientObjectInfo::RADAR))
+ {
+ // only one sensor for this type of object
+ KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(*info->m_sensors.begin());
+ return touchsensor->BroadPhaseFilterCollision(object1,object2);
+ }
+ return true;
+}
+
void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index 21faceef799..73b868278db 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -56,7 +56,12 @@ class KX_TouchEventManager : public SCA_EventManager
void *object1,
void *object2,
const PHY_CollData *coll_data);
-
+
+ static bool newBroadphaseResponse(void *client_data,
+ void *object1,
+ void *object2,
+ const PHY_CollData *coll_data);
+
virtual bool NewHandleCollision(void* obj1,void* obj2,
const PHY_CollData * coll_data);
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 5b013e75e4e..7e3904113ab 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -274,10 +274,10 @@ PyObject* KX_TouchSensor::PySetProperty(PyObject* self,
if (!prop->IsError()) {
m_touchedpropname = nameArg;
- prop->Release();
} else {
; /* not found ... */
}
+ prop->Release();
Py_Return;
}
@@ -351,8 +351,8 @@ PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname);
if (!val->IsError()) {
newList->Add(m_colliders->GetValue(i)->AddRef());
- val->Release();
}
+ val->Release();
}
i++;
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index f1a2a26e822..9781bdb3769 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -57,8 +57,6 @@ protected:
class SCA_EventManager* m_eventmgr;
class PHY_IPhysicsController* m_physCtrl;
- class PHY_ResponseTable* m_responstTable;
- class PHY_PhysicsController* m_responsObject;
bool m_bCollision;
bool m_bTriggered;
@@ -86,7 +84,11 @@ public:
virtual bool NewHandleCollision(void*obj1,void*obj2,const PHY_CollData* colldata);
- PHY_PhysicsController* GetPhysicsController() { return m_responsObject;}
+ // Allows to do pre-filtering and save computation time
+ // obj1 = sensor physical controller, obj2 = physical controller of second object
+ // return value = true if collision should be checked on pair of object
+ virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2) { return true; }
+
virtual bool IsPositiveTrigger() {
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index d92742d8799..fba2ecc223b 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -61,9 +61,9 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
aDir[0] = attachDir[0];
aDir[1] = attachDir[1];
aDir[2] = attachDir[2];
- aAxle[0] = attachAxle[0];
- aAxle[1] = attachAxle[1];
- aAxle[2] = attachAxle[2];
+ aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding)
+ aAxle[1] = -attachAxle[1];
+ aAxle[2] = -attachAxle[2];
printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
@@ -152,6 +152,7 @@ PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* self,
if (PyArg_ParseTuple(args,"fi",&force,&wheelIndex))
{
+ force *= -1.f;//someone reverse some conventions inside Bullet (axle winding)
m_vehicle->ApplyEngineForce(force,wheelIndex);
}
Py_INCREF(Py_None);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index a131054f5e5..fe9aa4419e4 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -36,6 +36,7 @@ float gAngularSleepingTreshold = 1.0f;
btVector3 startVel(0,0,0);//-10000);
+
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
@@ -104,12 +105,13 @@ public:
};
+
void CcdPhysicsController::CreateRigidbody()
{
- btTransform trans = GetTransformFromMotionState(m_cci.m_MotionState);
+ btTransform trans = GetTransformFromMotionState(m_MotionState);
- m_bulletMotionState = new BlenderBulletMotionState(m_cci.m_MotionState);
+ m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
m_body = new btRigidBody(m_cci.m_mass,
m_bulletMotionState,
@@ -118,17 +120,20 @@ void CcdPhysicsController::CreateRigidbody()
m_cci.m_linearDamping,m_cci.m_angularDamping,
m_cci.m_friction,m_cci.m_restitution);
-
-
//
// init the rigidbody properly
//
//setMassProps this also sets collisionFlags
//convert collision flags!
-
+ //special case: a near/radar sensor controller should not be defined static or it will
+ //generate loads of static-static collision messages on the console
+ if ((m_cci.m_collisionFilterGroup & CcdConstructionInfo::SensorFilter) != 0)
+ {
+ // reset the flags that have been set so far
+ m_body->setCollisionFlags(0);
+ }
m_body->setCollisionFlags(m_body->getCollisionFlags() | m_cci.m_collisionFlags);
-
m_body->setGravity( m_cci.m_gravity);
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
@@ -140,12 +145,14 @@ CcdPhysicsController::~CcdPhysicsController()
if (m_cci.m_physicsEnv)
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
- delete m_MotionState;
+ if (m_MotionState)
+ delete m_MotionState;
if (m_bulletMotionState)
delete m_bulletMotionState;
delete m_body;
}
+
/**
SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
*/
@@ -275,7 +282,7 @@ void CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dloc
void CcdPhysicsController::RelativeRotate(const float rotval[9],bool local)
{
- if (m_body )
+ if (m_body)
{
m_body->activate(true);
if (m_body->isStaticObject())
@@ -319,33 +326,39 @@ void CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,flo
}
void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)
{
- m_body->activate(true);
- if (m_body->isStaticObject())
+ if (m_body)
{
- m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- }
+ m_body->activate(true);
+ if (m_body->isStaticObject())
+ {
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
- m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
- btTransform xform = m_body->getCenterOfMassTransform();
- xform.setRotation(btQuaternion(quatImag0,quatImag1,quatImag2,quatReal));
- m_body->setCenterOfMassTransform(xform);
- m_bulletMotionState->setWorldTransform(xform);
+ m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
+ btTransform xform = m_body->getCenterOfMassTransform();
+ xform.setRotation(btQuaternion(quatImag0,quatImag1,quatImag2,quatReal));
+ m_body->setCenterOfMassTransform(xform);
+ m_bulletMotionState->setWorldTransform(xform);
+ }
}
void CcdPhysicsController::setPosition(float posX,float posY,float posZ)
{
- m_body->activate(true);
- if (m_body->isStaticObject())
+ if (m_body)
{
- m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ m_body->activate(true);
+ if (m_body->isStaticObject())
+ {
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+
+ m_MotionState->setWorldPosition(posX,posY,posZ);
+ btTransform xform = m_body->getCenterOfMassTransform();
+ xform.setOrigin(btVector3(posX,posY,posZ));
+ m_body->setCenterOfMassTransform(xform);
+ m_bulletMotionState->setWorldTransform(xform);
}
-
- m_MotionState->setWorldPosition(posX,posY,posZ);
- btTransform xform = m_body->getCenterOfMassTransform();
- xform.setOrigin(btVector3(posX,posY,posZ));
- m_body->setCenterOfMassTransform(xform);
- m_bulletMotionState->setWorldTransform(xform);
}
@@ -389,49 +402,59 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque
{
btVector3 torque(torqueX,torqueY,torqueZ);
btTransform xform = m_body->getCenterOfMassTransform();
- if (torque.length2() > (SIMD_EPSILON*SIMD_EPSILON))
+ if (m_body && torque.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
m_body->activate();
+ if (m_body->isStaticObject())
+ {
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+ if (local)
+ {
+ torque = xform.getBasis()*torque;
+ }
+ m_body->applyTorque(torque);
}
- if (local)
- {
- torque = xform.getBasis()*torque;
- }
- m_body->applyTorque(torque);
}
void CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
{
btVector3 force(forceX,forceY,forceZ);
- if (force.length2() > (SIMD_EPSILON*SIMD_EPSILON))
+ if (m_body && force.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
m_body->activate();
+ if (m_body->isStaticObject())
+ {
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+ {
+ btTransform xform = m_body->getCenterOfMassTransform();
+ if (local)
+ {
+ force = xform.getBasis()*force;
+ }
+ }
+ m_body->applyCentralForce(force);
}
-
-
- btTransform xform = m_body->getCenterOfMassTransform();
- if (local)
- {
- force = xform.getBasis()*force;
- }
- m_body->applyCentralForce(force);
}
void CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
{
btVector3 angvel(ang_velX,ang_velY,ang_velZ);
- if (angvel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
+ if (m_body && angvel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
m_body->activate(true);
- }
-
- {
- btTransform xform = m_body->getCenterOfMassTransform();
- if (local)
+ if (m_body->isStaticObject())
{
- angvel = xform.getBasis()*angvel;
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+ {
+ btTransform xform = m_body->getCenterOfMassTransform();
+ if (local)
+ {
+ angvel = xform.getBasis()*angvel;
+ }
}
-
m_body->setAngularVelocity(angvel);
}
@@ -440,16 +463,20 @@ void CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,floa
{
btVector3 linVel(lin_velX,lin_velY,lin_velZ);
- if (linVel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
+ if (m_body && linVel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
m_body->activate(true);
- }
-
- {
- btTransform xform = m_body->getCenterOfMassTransform();
- if (local)
+ if (m_body->isStaticObject())
{
- linVel = xform.getBasis()*linVel;
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
+
+ {
+ btTransform xform = m_body->getCenterOfMassTransform();
+ if (local)
+ {
+ linVel = xform.getBasis()*linVel;
+ }
}
m_body->setLinearVelocity(linVel);
}
@@ -458,14 +485,16 @@ void CcdPhysicsController::applyImpulse(float attachX,float attachY,float attac
{
btVector3 impulse(impulseX,impulseY,impulseZ);
- if (impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
+ if (m_body && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
{
m_body->activate();
+ if (m_body->isStaticObject())
+ {
+ m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
+ }
btVector3 pos(attachX,attachY,attachZ);
- m_body->activate();
-
m_body->applyImpulse(impulse,pos);
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 11fef56401f..54b4bcc40ee 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -46,7 +46,8 @@ struct CcdConstructionInfo
StaticFilter = 2,
KinematicFilter = 4,
DebrisFilter = 8,
- AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter,
+ SensorFilter = 16,
+ AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter,
};
@@ -61,6 +62,7 @@ struct CcdConstructionInfo
m_collisionFlags(0),
m_collisionFilterGroup(DefaultFilter),
m_collisionFilterMask(AllFilter),
+ m_collisionShape(0),
m_MotionState(0),
m_physicsEnv(0),
m_inertiaFactor(1.f)
@@ -85,9 +87,8 @@ struct CcdConstructionInfo
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
-
- btCollisionShape* m_collisionShape;
- class PHY_IMotionState* m_MotionState;
+ class btCollisionShape* m_collisionShape;
+ class PHY_IMotionState* m_MotionState;
CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication
float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor'
@@ -96,11 +97,12 @@ struct CcdConstructionInfo
class btRigidBody;
+
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
{
btRigidBody* m_body;
- class PHY_IMotionState* m_MotionState;
+ class PHY_IMotionState* m_MotionState;
btMotionState* m_bulletMotionState;
@@ -215,7 +217,11 @@ class CcdPhysicsController : public PHY_IPhysicsController
return m_MotionState;
}
-
+ class CcdPhysicsEnvironment* GetPhysicsEnvironment()
+ {
+ return m_cci.m_physicsEnv;
+ }
+
};
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index bc69fe85eff..25defbd5587 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -251,6 +251,22 @@ public:
};
#endif //NEW_BULLET_VEHICLE_SUPPORT
+class CcdOverlapFilterCallBack : public btOverlapFilterCallback
+{
+private:
+ class CcdPhysicsEnvironment* m_physEnv;
+public:
+ CcdOverlapFilterCallBack(CcdPhysicsEnvironment* env) :
+ m_physEnv(env)
+ {
+ }
+ virtual ~CcdOverlapFilterCallBack()
+ {
+ }
+ // return true when pairs need collision
+ virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const;
+};
+
void CcdPhysicsEnvironment::setDebugDrawer(btIDebugDraw* debugDrawer)
{
@@ -302,7 +318,11 @@ m_numTimeSubSteps(1),
m_ccdMode(0),
m_solverType(-1),
m_profileTimings(0),
-m_enableSatCollisionDetection(false)
+m_enableSatCollisionDetection(false),
+m_solver(NULL),
+m_ownPairCache(NULL),
+m_ownDispatcher(NULL),
+m_filterCallback(NULL)
{
for (int i=0;i<PHY_NUM_RESPONSE;i++)
@@ -310,8 +330,10 @@ m_enableSatCollisionDetection(false)
m_triggerCallbacks[i] = 0;
}
if (!dispatcher)
+ {
dispatcher = new btCollisionDispatcher();
-
+ m_ownDispatcher = dispatcher;
+ }
if(!pairCache)
{
@@ -321,14 +343,16 @@ m_enableSatCollisionDetection(false)
btVector3 worldMax(10000,10000,10000);
pairCache = new btAxisSweep3(worldMin,worldMax);
-
+ // remember that this was allocated by us so that we can release it
+ m_ownPairCache = pairCache;
//broadphase = new btSimpleBroadphase();
}
+ m_filterCallback = new CcdOverlapFilterCallBack(this);
+ pairCache->setOverlapFilterCallback(m_filterCallback);
setSolverType(1);//issues with quickstep and memory allocations
-
- m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,new btSequentialImpulseConstraintSolver());
+ m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,m_solver);
m_debugDrawer = 0;
m_gravity = btVector3(0.f,-10.f,0.f);
m_dynamicsWorld->setGravity(m_gravity);
@@ -346,7 +370,8 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
- m_dynamicsWorld->addRigidBody(body);
+ //use explicit group/filter for finer control over collision in bullet => near/radar sensor
+ m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
if (body->isStaticOrKinematicObject())
{
body->setActivationState(ISLAND_SLEEPING);
@@ -778,7 +803,20 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
delete m_dynamicsWorld;
+ if (NULL != m_ownPairCache)
+ delete m_ownPairCache;
+
+ if (NULL != m_ownDispatcher)
+ delete m_ownDispatcher;
+
+ if (NULL != m_solver)
+ delete m_solver;
+ if (NULL != m_debugDrawer)
+ delete m_debugDrawer;
+
+ if (NULL != m_filterCallback)
+ delete m_filterCallback;
}
@@ -841,9 +879,10 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
addCcdPhysicsController(ctrl1);
}
+ //Collision filter/mask is now set at the time of the creation of the controller
//force collision detection with everything, including static objects (might hurt performance!)
- ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter;
- ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterGroup = btBroadphaseProxy::AllFilter;
+ //ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger;
+ //ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterGroup = btBroadphaseProxy::SensorTrigger;
//todo: make this 'sensor'!
requestCollisionCallback(ctrl);
@@ -962,9 +1001,47 @@ void CcdPhysicsEnvironment::CallbackTriggers()
}
-
-
-
+// This call back is called before a pair is added in the cache
+// Handy to remove objects that must be ignored by sensors
+bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
+{
+ btCollisionObject *colObj0, *colObj1;
+ CcdPhysicsController *sensorCtrl, *objCtrl;
+ bool collides;
+ // first check the filters
+ collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+ collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+ if (!collides)
+ return false;
+
+ // additional check for sensor object
+ if (proxy0->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger)
+ {
+ // this is a sensor object, the other one can't be a sensor object because
+ // they exclude each other in the above test
+ assert(!(proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger));
+ colObj0 = (btCollisionObject*)proxy0->m_clientObject;
+ colObj1 = (btCollisionObject*)proxy1->m_clientObject;
+ }
+ else if (proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger)
+ {
+ colObj0 = (btCollisionObject*)proxy1->m_clientObject;
+ colObj1 = (btCollisionObject*)proxy0->m_clientObject;
+ }
+ else
+ {
+ return true;
+ }
+ if (!colObj0 || !colObj1)
+ return false;
+ sensorCtrl = static_cast<CcdPhysicsController*>(colObj0->getUserPointer());
+ objCtrl = static_cast<CcdPhysicsController*>(colObj1->getUserPointer());
+ if (m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE])
+ {
+ return m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE](m_physEnv->m_triggerCallbacksUserPtrs[PHY_BROADPH_RESPONSE], sensorCtrl, objCtrl, 0);
+ }
+ return true;
+}
#ifdef NEW_BULLET_VEHICLE_SUPPORT
@@ -998,12 +1075,19 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi
{
CcdConstructionInfo cinfo;
+ // memory leak! The shape is not deleted by Bullet and we cannot add it to the KX_Scene.m_shapes list
cinfo.m_collisionShape = new btSphereShape(radius);
cinfo.m_MotionState = 0;
cinfo.m_physicsEnv = this;
- cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_KINEMATIC_OBJECT;
+ // declare this object as Dyamic rather then static!!
+ // The reason as it is designed to detect all type of object, including static object
+ // It would cause static-static message to be printed on the console otherwise
+ cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE/* | btCollisionObject::CF_KINEMATIC_OBJECT*/;
DefaultMotionState* motionState = new DefaultMotionState();
cinfo.m_MotionState = motionState;
+ // we will add later the possibility to select the filter from option
+ cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter;
+ cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter;
motionState->m_worldTransform.setIdentity();
motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2]));
@@ -1137,6 +1221,74 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
break;
}
+ case PHY_CONE_TWIST_CONSTRAINT:
+ {
+ btConeTwistConstraint* coneTwistContraint = 0;
+
+
+ if (rb1)
+ {
+ btTransform frameInA;
+ btTransform frameInB;
+
+ btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z);
+ if (axis1.length() == 0.0)
+ {
+ btPlaneSpace1( axisInA, axis1, axis2 );
+ }
+
+ frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(),
+ axisInA.y(), axis1.y(), axis2.y(),
+ axisInA.z(), axis1.z(), axis2.z() );
+ frameInA.setOrigin( pivotInA );
+
+ btTransform inv = rb1->getCenterOfMassTransform().inverse();
+
+ btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA;
+
+ frameInB = inv * globalFrameA;
+
+ coneTwistContraint = new btConeTwistConstraint( *rb0,*rb1,
+ frameInA,frameInB);
+
+
+ } else
+ {
+ static btRigidBody s_fixedObject2( 0,0,0);
+ btTransform frameInA;
+ btTransform frameInB;
+
+ btVector3 axis1, axis2;
+ btPlaneSpace1( axisInA, axis1, axis2 );
+
+ frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(),
+ axisInA.y(), axis1.y(), axis2.y(),
+ axisInA.z(), axis1.z(), axis2.z() );
+
+ frameInA.setOrigin( pivotInA );
+
+ ///frameInB in worldspace
+ frameInB = rb0->getCenterOfMassTransform() * frameInA;
+
+ coneTwistContraint = new btConeTwistConstraint(
+ *rb0,s_fixedObject2,
+ frameInA,frameInB);
+ }
+
+ if (coneTwistContraint)
+ {
+ //m_constraints.push_back(genericConstraint);
+ m_dynamicsWorld->addConstraint(coneTwistContraint);
+ coneTwistContraint->setUserConstraintId(gConstraintUid++);
+ coneTwistContraint->setUserConstraintType(type);
+ //64 bit systems can't cast pointer to int. could use size_t instead.
+ return coneTwistContraint->getUserConstraintId();
+ }
+
+
+
+ break;
+ }
case PHY_ANGULAR_CONSTRAINT:
angularOnly = true;
@@ -1207,12 +1359,18 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
{
CcdConstructionInfo cinfo;
+ //This is a memory leak: Bullet does not delete the shape and it cannot be added to
+ //the KX_Scene.m_shapes list -- too bad but that's not a lot of data
cinfo.m_collisionShape = new btConeShape(coneradius,coneheight);
cinfo.m_MotionState = 0;
cinfo.m_physicsEnv = this;
cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
DefaultMotionState* motionState = new DefaultMotionState();
cinfo.m_MotionState = motionState;
+
+ // we will add later the possibility to select the filter from option
+ cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter;
+ cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter;
motionState->m_worldTransform.setIdentity();
// motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2]));
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 66a6ed59c17..9f14cf6cbef 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -42,6 +42,7 @@ class btBroadphaseInterface;
class btOverlappingPairCache;
class btIDebugDraw;
class PHY_IVehicle;
+class CcdOverlapFilterCallBack;
/// CcdPhysicsEnvironment is an experimental mainloop for physics simulation using optional continuous collision detection.
/// Physics Environment takes care of stepping the simulation and is a container for physics entities.
@@ -49,9 +50,8 @@ class PHY_IVehicle;
/// A derived class may be able to 'construct' entities by loading and/or converting
class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
{
+ friend class CcdOverlapFilterCallBack;
btVector3 m_gravity;
-
-
protected:
btIDebugDraw* m_debugDrawer;
@@ -166,7 +166,7 @@ protected:
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl);
-
+ //These two methods are used *solely* to create controllers for Near/Radar sensor! Don't use for anything else
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);
@@ -229,10 +229,22 @@ protected:
std::vector<WrapperVehicle*> m_wrapperVehicles;
- class btDynamicsWorld* m_dynamicsWorld;
+ //use explicit btDiscreteDynamicsWorld* so that we have access to
+ //btDiscreteDynamicsWorld::addRigidBody(body,filter,group)
+ //so that we can set the body collision filter/group at the time of creation
+ //and not afterwards (breaks the collision system for radar/near sensor)
+ //Ideally we would like to have access to this function from the btDynamicsWorld interface
+ //class btDynamicsWorld* m_dynamicsWorld;
+ class btDiscreteDynamicsWorld* m_dynamicsWorld;
class btConstraintSolver* m_solver;
+ class btOverlappingPairCache* m_ownPairCache;
+
+ class CcdOverlapFilterCallBack* m_filterCallback;
+
+ class btDispatcher* m_ownDispatcher;
+
bool m_scalingPropagated;
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
index 6cdf1d41dc1..67a74d11564 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
@@ -206,6 +206,8 @@ void SumoPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCa
case PHY_STATIC_RESPONSE:
sumoRespClass = PHY_STATIC_RESPONSE;
break;
+ case PHY_BROADPH_RESPONSE:
+ return;
default:
assert(0);
return;
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
index 3952377181a..c289b9d8bcb 100644
--- a/source/gameengine/Physics/common/PHY_DynamicTypes.h
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -19,7 +19,6 @@ subject to the following restrictions:
-class PHY_ResponseTable;
class PHY_Shape;
@@ -40,10 +39,11 @@ struct PHY__Vector3
typedef enum
{
PHY_FH_RESPONSE,
- PHY_SENSOR_RESPONSE, /* Touch Sensors */
+ PHY_SENSOR_RESPONSE, /* Touch Sensors */
PHY_CAMERA_RESPONSE, /* Visibility Culling */
PHY_OBJECT_RESPONSE, /* Object Dynamic Geometry Response */
PHY_STATIC_RESPONSE, /* Static Geometry Response */
+ PHY_BROADPH_RESPONSE, /* broadphase Response */
PHY_NUM_RESPONSE
};
@@ -81,6 +81,7 @@ typedef enum PHY_ConstraintType {
PHY_POINT2POINT_CONSTRAINT=1,
PHY_LINEHINGE_CONSTRAINT=2,
PHY_ANGULAR_CONSTRAINT = 3,//hinge without ball socket
+ PHY_CONE_TWIST_CONSTRAINT = 4,
PHY_VEHICLE_CONSTRAINT=11,//complex 'constraint' that turns a rigidbody into a vehicle
PHY_GENERIC_6DOF_CONSTRAINT=12,//can leave any of the 6 degree of freedom 'free' or 'locked'
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 931dc0e988c..ba1fb8473d3 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -85,7 +85,6 @@ class PHY_IPhysicsController
// dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
virtual void setRigidBody(bool rigid)=0;
-
// clientinfo for raycasts for example
virtual void* getNewClientInfo()=0;
virtual void setNewClientInfo(void* clientinfo)=0;
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index 5e4fd681914..d90b3d82e6b 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -107,6 +107,7 @@ class PHY_IPhysicsEnvironment
virtual void removeSensor(PHY_IPhysicsController* ctrl)=0;
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0;
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0;
+ //These two methods are *solely* used to create controllers for sensor! Don't use for anything else
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0;
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0;
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
new file mode 100644
index 00000000000..d5a870a0040
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -0,0 +1,340 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#define STRINGIFY(A) #A
+
+#include "RAS_OpenGLFilters/RAS_Blur2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Sharpen2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Dilation2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Erosion2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Laplacian2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Sobel2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Prewitt2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_GrayScale2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Sepia2DFilter.h"
+#include "RAS_OpenGLFilters/RAS_Invert2DFilter.h"
+
+#include "STR_String.h"
+#include "RAS_ICanvas.h"
+#include "RAS_2DFilterManager.h"
+#include <iostream>
+
+#ifdef WIN32
+// OpenGL gl.h needs 'windows.h' on windows platforms
+#include <windows.h>
+#endif //WIN32
+#ifdef __APPLE__
+#define GL_GLEXT_LEGACY 1
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#include "RAS_OpenGLRasterizer/RAS_GLExtensionManager.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+RAS_2DFilterManager::RAS_2DFilterManager():
+texturewidth(-1), textureheight(-1),
+canvaswidth(-1), canvasheight(-1),
+numberoffilters(0),texname(-1)
+{
+ isshadersupported = bgl::QueryVersion(2,0);
+ if(!isshadersupported)
+ {
+ std::cout<<"shaders not supported!" << std::endl;
+ return;
+ }
+
+ int passindex;
+ for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
+ {
+ m_filters[passindex] = 0;
+ m_enabled[passindex] = 0;
+ }
+
+}
+
+RAS_2DFilterManager::~RAS_2DFilterManager()
+{
+}
+
+unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource)
+{
+ GLuint program;
+ GLuint fShader = bgl::blCreateShaderObjectARB(GL_FRAGMENT_SHADER);
+ GLint success;
+
+ bgl::blShaderSourceARB(fShader, 1, (const char**)&shadersource, NULL);
+
+ bgl::blCompileShaderARB(fShader);
+
+ bgl::blGetObjectParameterivARB(fShader, GL_COMPILE_STATUS, &success);
+ if(!success)
+ {
+ /*Shader Comile Error*/
+ std::cout << "2dFilters - Shader compile error" << std::endl;
+ return 0;
+ }
+
+ program = bgl::blCreateProgramObjectARB();
+ bgl::blAttachObjectARB(program, fShader);
+
+ bgl::blLinkProgramARB(program);
+ bgl::blGetObjectParameterivARB(program, GL_LINK_STATUS, &success);
+ if (!success)
+ {
+ /*Program Link Error*/
+ std::cout << "2dFilters - Shader program link error" << std::endl;
+ return 0;
+ }
+
+ bgl::blValidateProgramARB(program);
+ bgl::blGetObjectParameterivARB(program, GL_VALIDATE_STATUS, &success);
+ if (!success)
+ {
+ /*Program Validation Error*/
+ std::cout << "2dFilters - Shader program validation error" << std::endl;
+ return 0;
+ }
+ return program;
+}
+
+unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
+{
+ switch(filtermode)
+ {
+ case RAS_2DFILTER_BLUR:
+ return CreateShaderProgram(BlurFragmentShader);
+ case RAS_2DFILTER_SHARPEN:
+ return CreateShaderProgram(SharpenFragmentShader);
+ case RAS_2DFILTER_DILATION:
+ return CreateShaderProgram(DilationFragmentShader);
+ case RAS_2DFILTER_EROSION:
+ return CreateShaderProgram(ErosionFragmentShader);
+ case RAS_2DFILTER_LAPLACIAN:
+ return CreateShaderProgram(LaplacionFragmentShader);
+ case RAS_2DFILTER_SOBEL:
+ return CreateShaderProgram(SobelFragmentShader);
+ case RAS_2DFILTER_PREWITT:
+ return CreateShaderProgram(PrewittFragmentShader);
+ case RAS_2DFILTER_GRAYSCALE:
+ return CreateShaderProgram(GrayScaleFragmentShader);
+ case RAS_2DFILTER_SEPIA:
+ return CreateShaderProgram(SepiaFragmentShader);
+ case RAS_2DFILTER_INVERT:
+ return CreateShaderProgram(InvertFragmentShader);
+ }
+ return 0;
+}
+
+void RAS_2DFilterManager::StartShaderProgram(unsigned int shaderprogram)
+{
+ GLint uniformLoc;
+ bgl::blUseProgramObjectARB(shaderprogram);
+ uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTexture");
+ if (uniformLoc != -1)
+ {
+ bgl::blUniform1iARB(uniformLoc, 0);
+ }
+ uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_TextureCoordinateOffset");
+ if (uniformLoc != -1)
+ {
+ bgl::blUniform2fvARB(uniformLoc, 9, textureoffsets);
+ }
+ uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureWidth");
+ if (uniformLoc != -1)
+ {
+ bgl::blUniform1fARB(uniformLoc,texturewidth);
+ }
+ uniformLoc = bgl::blGetUniformLocationARB(shaderprogram, "bgl_RenderedTextureHeight");
+ if (uniformLoc != -1)
+ {
+ bgl::blUniform1fARB(uniformLoc,textureheight);
+ }
+
+}
+
+void RAS_2DFilterManager::EndShaderProgram()
+{
+ bgl::blUseProgramObjectARB(0);
+}
+
+void RAS_2DFilterManager::SetupTexture()
+{
+ if(texname!=-1)
+ {
+ glDeleteTextures(1,(const GLuint *)&texname);
+ }
+ glGenTextures(1, (GLuint *)&texname);
+ glBindTexture(GL_TEXTURE_2D, texname);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
+ GL_UNSIGNED_BYTE, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+}
+
+void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
+{
+ canvaswidth = texturewidth = width;
+ canvasheight = textureheight = height;
+
+ GLint i,j;
+ i = 0;
+ while ((1 << i) <= texturewidth)
+ i++;
+ texturewidth = (1 << (i));
+
+ // Now for height
+ i = 0;
+ while ((1 << i) <= textureheight)
+ i++;
+ textureheight = (1 << (i));
+
+ GLfloat xInc = 1.0f / (GLfloat)texturewidth;
+ GLfloat yInc = 1.0f / (GLfloat)textureheight;
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ textureoffsets[(((i*3)+j)*2)+0] = (-1.0f * xInc) + ((GLfloat)i * xInc);
+ textureoffsets[(((i*3)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc);
+ }
+ }
+
+ SetupTexture();
+}
+
+void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
+{
+ if(!isshadersupported)
+ return;
+
+ if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
+ {
+ UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight());
+ }
+ GLuint viewport[4]={0};
+
+ int passindex;
+ bool first = true;
+ for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
+ {
+ if(m_filters[passindex] && m_enabled[passindex])
+ {
+ if(first)
+ {
+ glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+ glViewport(0, 0, texturewidth, textureheight);
+
+ glDisable(GL_DEPTH_TEST);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ first = false;
+ }
+
+ StartShaderProgram(m_filters[passindex]);
+
+ glBindTexture(GL_TEXTURE_2D, texname);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glBegin(GL_QUADS);
+ glColor4f(1.f, 1.f, 1.f, 1.f);
+ glTexCoord2f(1.0, 1.0); glVertex2f(1,1);
+ glTexCoord2f(0.0, 1.0); glVertex2f(-1,1);
+ glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1);
+ glTexCoord2f(1.0, 0.0); glVertex2f(1,-1);
+ glEnd();
+ }
+ }
+
+ if(!first)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
+ EndShaderProgram();
+ }
+}
+
+void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text)
+{
+ if(!isshadersupported)
+ return;
+ if(pass<0 || pass>=MAX_RENDER_PASS)
+ return;
+
+ if(mode == RAS_2DFILTER_DISABLED)
+ {
+ m_enabled[pass] = 0;
+ return;
+ }
+
+ if(mode == RAS_2DFILTER_ENABLED)
+ {
+ m_enabled[pass] = 1;
+ return;
+ }
+
+ if(mode == RAS_2DFILTER_NOFILTER)
+ {
+ if(m_filters[pass])
+ bgl::blDeleteObjectARB(m_filters[pass]);
+ m_enabled[pass] = 0;
+ m_filters[pass] = 0;
+ return;
+ }
+
+ if(mode == RAS_2DFILTER_CUSTOMFILTER)
+ {
+ if(m_filters[pass])
+ bgl::blDeleteObjectARB(m_filters[pass]);
+ m_filters[pass] = CreateShaderProgram(text.Ptr());
+ m_enabled[pass] = 1;
+ return;
+ }
+
+ if(mode>=RAS_2DFILTER_MOTIONBLUR && mode<=RAS_2DFILTER_INVERT)
+ {
+ if(m_filters[pass])
+ bgl::blDeleteObjectARB(m_filters[pass]);
+ m_filters[pass] = CreateShaderProgram(mode);
+ m_enabled[pass] = 1;
+ }
+}
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
new file mode 100644
index 00000000000..227d2a26d41
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -0,0 +1,91 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_I2DFILTER
+#define __RAS_I2DFILTER
+
+
+
+#define MAX_RENDER_PASS 100
+
+class RAS_2DFilterManager
+{
+private:
+ unsigned int CreateShaderProgram(char* shadersource);
+ unsigned int CreateShaderProgram(int filtermode);
+ void StartShaderProgram(unsigned int shaderprogram);
+ void EndShaderProgram();
+
+ float textureoffsets[18];
+ float view[4];
+ unsigned int texname;
+ int texturewidth;
+ int textureheight;
+ int canvaswidth;
+ int canvasheight;
+ int numberoffilters;
+
+ bool isshadersupported;
+public:
+ enum RAS_2DFILTER_MODE {
+ RAS_2DFILTER_ENABLED = -2,
+ RAS_2DFILTER_DISABLED = -1,
+ RAS_2DFILTER_NOFILTER = 0,
+ RAS_2DFILTER_MOTIONBLUR,
+ RAS_2DFILTER_BLUR,
+ RAS_2DFILTER_SHARPEN,
+ RAS_2DFILTER_DILATION,
+ RAS_2DFILTER_EROSION,
+ RAS_2DFILTER_LAPLACIAN,
+ RAS_2DFILTER_SOBEL,
+ RAS_2DFILTER_PREWITT,
+ RAS_2DFILTER_GRAYSCALE,
+ RAS_2DFILTER_SEPIA,
+ RAS_2DFILTER_INVERT,
+ RAS_2DFILTER_CUSTOMFILTER,
+ RAS_2DFILTER_NUMBER_OF_FILTERS
+ };
+
+ unsigned int m_filters[MAX_RENDER_PASS];
+ short m_enabled[MAX_RENDER_PASS];
+
+ RAS_2DFilterManager();
+
+ ~RAS_2DFilterManager();
+
+ void SetupTexture();
+
+ void UpdateOffsetMatrix(int width, int height);
+
+ void RenderFilters(RAS_ICanvas* canvas);
+
+ void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text);
+};
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index 8ecc9e7ad05..560c6741260 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -48,7 +48,6 @@ class RAS_IPolyMaterial;
*/
class RAS_IRasterizer
{
-
public:
RAS_IRasterizer(RAS_ICanvas* canv){};
@@ -398,7 +397,15 @@ public:
virtual bool QueryLists(){return false;}
virtual bool QueryArrays(){return false;}
+
+ virtual void EnableMotionBlur(float motionblurvalue)=0;
+ virtual void DisableMotionBlur()=0;
+
+ virtual float GetMotionBlurValue()=0;
+ virtual int GetMotionBlurState()=0;
+ virtual void SetMotionBlurState(int newstate)=0;
};
#endif //__RAS_IRASTERIZER
+
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index fa3c777553d..771c34a595f 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -34,6 +34,7 @@
#include "MT_Transform.h"
#include "RAS_IRasterizer.h"
+#include "RAS_2DFilterManager.h"
#include <vector>
#include <algorithm>
@@ -41,6 +42,7 @@
class RAS_IPolyMaterial;
struct RAS_LightObject;
+
class RAS_IRenderTools
{
@@ -52,7 +54,8 @@ protected:
bool m_modified;
std::vector<struct RAS_LightObject*> m_lights;
-
+
+ RAS_2DFilterManager m_filtermanager;
public:
enum RAS_TEXT_RENDER_MODE {
@@ -61,7 +64,7 @@ public:
RAS_TEXT_PADDED,
RAS_TEXT_MAX
};
-
+
RAS_IRenderTools(
) :
m_clientobject(NULL),
@@ -174,6 +177,18 @@ public:
struct RAS_LightObject* lightobject
);
+ virtual
+ void
+ MotionBlur(RAS_IRasterizer* rasterizer)=0;
+
+ virtual
+ void
+ Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)=0;
+
+ virtual
+ void
+ Render2DFilters(RAS_ICanvas* canvas)=0;
+
virtual
class RAS_IPolyMaterial*
CreateBlenderPolyMaterial(
@@ -195,3 +210,5 @@ public:
#endif //__RAS_IRENDERTOOLS
+
+
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 689772f51c4..757784be87f 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -69,6 +69,11 @@ bool KX_MeshSlot::Less(const KX_MeshSlot& lhs) const
return result;
}
+KX_MeshSlot::~KX_MeshSlot()
+{
+ if (m_DisplayList)
+ m_DisplayList->Release();
+}
RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
index 7d875242c2e..ded6af999c4 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
@@ -69,10 +69,21 @@ public:
*/
class KX_ListSlot
{
+protected:
+ int m_refcount;
public:
- KX_ListSlot(){}
- virtual ~KX_ListSlot(){}
-
+ KX_ListSlot(){ m_refcount=1; }
+ virtual ~KX_ListSlot() {}
+ virtual int Release() {
+ if (--m_refcount > 0)
+ return m_refcount;
+ delete this;
+ return 0;
+ }
+ virtual KX_ListSlot* AddRef() {
+ m_refcount++;
+ return this;
+ }
virtual void SetModified(bool mod)=0;
};
@@ -96,7 +107,7 @@ public:
m_DisplayList(0)
{
}
- ~KX_MeshSlot(){}
+ ~KX_MeshSlot();
bool Less(const KX_MeshSlot& lhs) const;
};
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 4219b641b5c..b7147ea6c42 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -474,7 +474,9 @@ void RAS_MeshObject::ClearArrayData()
{
KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
if (ao)
+ {
delete *ao;
+ }
}
}
diff --git a/intern/action/test/action_c_test/TestAction.c b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h
index 0b4896dadd7..ac4c2456573 100644
--- a/intern/action/test/action_c_test/TestAction.c
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h
@@ -1,5 +1,4 @@
/**
- * $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -29,35 +28,27 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#include <stdio.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "TestAction.h"
+#ifndef __RAS_BLUR2DFILTER
+#define __RAS_BLUR2DFILTER
+char * BlurFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
-void printApplied(ACT_ActionPtr action, ACT_ActionUserDataPtr userData)
+void main(void)
{
- printf("%s: applied\n", ACT_ActionGetName(action));
-}
-
-void printUndone(ACT_ActionPtr action, ACT_ActionUserDataPtr userData)
-{
- printf("%s: undone\n", ACT_ActionGetName(action));
-}
+ vec4 sample[9];
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ }
-void printDisposed(ACT_ActionPtr action, ACT_ActionUserDataPtr userData)
-{
- printf("%s: disposed\n", ACT_ActionGetName(action));
+ gl_FragColor = (sample[0] + (2.0*sample[1]) + sample[2] +
+ (2.0*sample[3]) + sample[4] + (2.0*sample[5]) +
+ sample[6] + (2.0*sample[7]) + sample[8]) / 13.0;
}
+);
+#endif
+
diff --git a/intern/action/test/action_cpp_test/TestAction.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h
index 3cd5ed893ad..44f67af3d75 100644
--- a/intern/action/test/action_cpp_test/TestAction.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h
@@ -1,5 +1,4 @@
/**
- * $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -29,30 +28,27 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
+#ifndef __RAS_DILATION2DFILTER
+#define __RAS_DILATION2DFILTER
-#ifndef _H_ACT_TESTACTION
-#define _H_ACT_TESTACTION
+char * DilationFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
-#include "ACT_Action.h"
-
-#include <iostream>
-
-class TestAction : public ACT_Action
+void main(void)
{
-public:
- TestAction(const STR_String& name) : ACT_Action(name) {}
- virtual ~TestAction() { cout << m_name.Ptr() << ": deleted\n"; }
-protected:
- virtual void doApply() { cout << m_name.Ptr() << ": applied\n"; }
- virtual void doUndo() { cout << m_name.Ptr() << ": undone\n"; }
-};
-
-#endif // _H_ACT_TESTACTION
+ vec4 sample[9];
+ vec4 maxValue = vec4(0.0);
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ maxValue = max(sample[i], maxValue);
+ }
+
+ gl_FragColor = maxValue;
+}
+);
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h
new file mode 100644
index 00000000000..80b6f184c36
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h
@@ -0,0 +1,53 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_EROSION2DFILTER
+#define __RAS_EROSION2DFILTER
+
+char * ErosionFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
+
+void main(void)
+{
+ vec4 sample[9];
+ vec4 minValue = vec4(1.0);
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ minValue = min(sample[i], minValue);
+ }
+
+ gl_FragColor = minValue;
+}
+);
+#endif
diff --git a/intern/action/intern/ACT_Action.cpp b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h
index a94c3c9f336..29cc91814ce 100644
--- a/intern/action/intern/ACT_Action.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h
@@ -1,5 +1,4 @@
/**
- * $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -29,40 +28,17 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date April, 25, 2001
- */
-
-#include "ACT_Action.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#ifndef __RAS_GRAYSCALE2DFILTER
+#define __RAS_GRAYSCALE2DFILTER
+char * GrayScaleFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
-ACT_Action::ACT_Action(const STR_String& name, bool applied)
-: m_name(name), m_applied(applied)
+void main(void)
{
+ vec4 texcolor = texture2D(bgl_RenderedTexture, gl_TexCoord[0].st);
+ float gray = dot(texcolor.rgb, vec3(0.299, 0.587, 0.114));
+ gl_FragColor = vec4(gray, gray, gray, texcolor.a);
}
-
-
-void ACT_Action::apply()
-{
- if (!m_applied) {
- doApply();
- m_applied = true;
- }
-}
-
-
-void ACT_Action::undo()
-{
- if (m_applied) {
- doUndo();
- m_applied = false;
- }
-}
+);
+#endif
diff --git a/intern/keymaker/mt19937int.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h
index e49c7bc3a27..a3482f9647f 100644
--- a/intern/keymaker/mt19937int.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h
@@ -1,5 +1,4 @@
/**
- * $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -29,18 +28,17 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-/* ex:ts=4 */
+#ifndef __RAS_INVERT2DFILTER
+#define __RAS_INVERT2DFILTER
-/**
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * Mersenne Twister prototypes
- */
-
-/* external: */
-void sgenrand(signed long seed);
-unsigned long genrand(void);
-
-/* internal: */
-void lsgenrand(unsigned long *seed_array);
+char * InvertFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+void main(void)
+{
+ vec4 texcolor = texture2D(bgl_RenderedTexture, gl_TexCoord[0].st);
+ gl_FragColor.rgb = 1.0 - texcolor.rgb;
+ gl_FragColor.a = texcolor.a;
+}
+);
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h
new file mode 100644
index 00000000000..636ecdb68aa
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h
@@ -0,0 +1,56 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_LAPLACION2DFILTER
+#define __RAS_LAPLACION2DFILTER
+
+char * LaplacionFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
+
+void main(void)
+{
+ vec4 sample[9];
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ }
+
+ gl_FragColor = (sample[4] * 8.0) -
+ (sample[0] + sample[1] + sample[2] +
+ sample[3] + sample[5] +
+ sample[6] + sample[7] + sample[8]);
+ gl_FragColor = vec4(gl_FragColor.rgb, 1.0);
+}
+);
+#endif
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h
new file mode 100644
index 00000000000..8046aacfbb1
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h
@@ -0,0 +1,61 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_PREWITT2DFILTER
+#define __RAS_PREWITT2DFILTER
+
+char * PrewittFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
+
+void main(void)
+{
+ vec4 sample[9];
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ }
+
+ vec4 horizEdge = sample[2] + sample[5] + sample[8] -
+ (sample[0] + sample[3] + sample[6]);
+
+ vec4 vertEdge = sample[0] + sample[1] + sample[2] -
+ (sample[6] + sample[7] + sample[8]);
+
+ gl_FragColor.rgb = sqrt((horizEdge.rgb * horizEdge.rgb) +
+ (vertEdge.rgb * vertEdge.rgb));
+ gl_FragColor.a = 1.0;
+}
+
+);
+#endif
+
diff --git a/intern/action/test/action_c_test/TestAction.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h
index 487d8777b81..b56911a48b4 100644
--- a/intern/action/test/action_c_test/TestAction.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h
@@ -1,5 +1,4 @@
/**
- * $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -29,23 +28,17 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
-/**
-
- * $Id$
- * Copyright (C) 2001 NaN Technologies B.V.
- * @author Maarten Gribnau
- * @date March 31, 2001
- */
-
-#ifndef _H_ACT_TESTACTION_C_H_
-#define _H_ACT_TESTACTION_C_H_
-
-#include "ACT_ActionC-Api.h"
-
-void printApplied(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-void printUndone(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-void printDisposed(ACT_ActionPtr action, ACT_ActionUserDataPtr userData);
-
+#ifndef __RAS_SEPIA2DFILTER
+#define __RAS_SEPIA2DFILTER
-#endif // _H_ACT_TESTACTION_C_H_
+char * SepiaFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+void main(void)
+{
+ vec4 texcolor = texture2D(bgl_RenderedTexture, gl_TexCoord[0].st);
+ float gray = dot(texcolor.rgb, vec3(0.299, 0.587, 0.114));
+ gl_FragColor = vec4(gray * vec3(1.2, 1.0, 0.8), texcolor.a);
+}
+);
+#endif
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h
new file mode 100644
index 00000000000..e5f942a535c
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h
@@ -0,0 +1,55 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_SHARPEN2DFILTER
+#define __RAS_SHARPEN2DFILTER
+
+char * SharpenFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
+
+void main(void)
+{
+ vec4 sample[9];
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ }
+
+ gl_FragColor = (sample[4] * 9.0) -
+ (sample[0] + sample[1] + sample[2] +
+ sample[3] + sample[5] +
+ sample[6] + sample[7] + sample[8]);
+}
+);
+#endif
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h
new file mode 100644
index 00000000000..545e76601e8
--- /dev/null
+++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h
@@ -0,0 +1,60 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __RAS_SOBEL2DFILTER
+#define __RAS_SOBEL2DFILTER
+
+char * SobelFragmentShader=STRINGIFY(
+uniform sampler2D bgl_RenderedTexture;
+uniform vec2 bgl_TextureCoordinateOffset[9];
+
+void main(void)
+{
+ vec4 sample[9];
+
+ for (int i = 0; i < 9; i++)
+ {
+ sample[i] = texture2D(bgl_RenderedTexture,
+ gl_TexCoord[0].st + bgl_TextureCoordinateOffset[i]);
+ }
+
+ vec4 horizEdge = sample[2] + (2.0*sample[5]) + sample[8] -
+ (sample[0] + (2.0*sample[3]) + sample[6]);
+
+ vec4 vertEdge = sample[0] + (2.0*sample[1]) + sample[2] -
+ (sample[6] + (2.0*sample[7]) + sample[8]);
+
+ gl_FragColor.rgb = sqrt((horizEdge.rgb * horizEdge.rgb) +
+ (vertEdge.rgb * vertEdge.rgb));
+ gl_FragColor.a = 1.0;
+}
+);
+#endif
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
index c8ed2dd6960..26b00f02e7d 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
@@ -108,7 +108,7 @@ static OSStatus bglInitEntryPoints (void)
// Frameworks directory/folder
err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
- &fileRefParam.ioVRefNum, &fileRefParam.ioDirID);
+ &fileRefParam.ioVRefNum, (SInt32*)&fileRefParam.ioDirID);
if (noErr != err) {
DebugStr ((unsigned char *)"\pCould not find frameworks folder");
return err;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index 7270a6d2a99..afa98fdb274 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -25,13 +25,23 @@
#define spit(x)
//#endif
-RAS_ListSlot::RAS_ListSlot()
+RAS_ListSlot::RAS_ListSlot(RAS_ListRasterizer* rasty)
: KX_ListSlot(),
m_flag(LIST_MODIFY|LIST_CREATE),
- m_list(0)
+ m_list(0),
+ m_rasty(rasty)
{
}
+int RAS_ListSlot::Release()
+{
+ if (--m_refcount > 0)
+ return m_refcount;
+ m_rasty->RemoveListSlot(this);
+ delete this;
+ return 0;
+}
+
RAS_ListSlot::~RAS_ListSlot()
{
RemoveList();
@@ -62,7 +72,7 @@ void RAS_ListSlot::DrawList()
}
}
if(m_list != 0)
- glNewList((GLuint)m_list, GL_COMPILE_AND_EXECUTE);
+ glNewList((GLuint)m_list, GL_COMPILE);
m_flag |= LIST_BEGIN;
return;
@@ -76,6 +86,7 @@ void RAS_ListSlot::EndList()
glEndList();
m_flag = m_flag &~(LIST_BEGIN|LIST_MODIFY);
m_flag |= LIST_END;
+ glCallList(m_list);
}
}
@@ -95,8 +106,9 @@ bool RAS_ListSlot::End()
-RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas)
-: RAS_OpenGLRasterizer(canvas)
+RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock)
+: RAS_VAOpenGLRasterizer(canvas, lock),
+ mUseVertexArrays(useVertexArrays)
{
// --
}
@@ -106,6 +118,18 @@ RAS_ListRasterizer::~RAS_ListRasterizer()
ReleaseAlloc();
}
+void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list)
+{
+ RAS_Lists::iterator it = mLists.begin();
+ while(it != mLists.end()) {
+ if (it->second == list) {
+ mLists.erase(it);
+ break;
+ }
+ it++;
+ }
+}
+
RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(const vecVertexArray& vertexarrays, KX_ListSlot** slot)
{
/*
@@ -118,10 +142,10 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(const vecVertexArray& vertexarrays,
if(!localSlot) {
RAS_Lists::iterator it = mLists.find(vertexarrays);
if(it == mLists.end()) {
- localSlot = new RAS_ListSlot();
+ localSlot = new RAS_ListSlot(this);
mLists.insert(std::pair<vecVertexArray, RAS_ListSlot*>(vertexarrays, localSlot));
} else {
- localSlot = it->second;
+ localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef());
}
}
MT_assert(localSlot);
@@ -155,16 +179,29 @@ void RAS_ListRasterizer::IndexPrimitives(
if(!useObjectColor) {
localSlot = FindOrAdd(vertexarrays, slot);
localSlot->DrawList();
- if(localSlot->End())
+ if(localSlot->End()) {
+ // save slot here too, needed for replicas and object using same mesh
+ // => they have the same vertexarray but different mesh slot
+ *slot = localSlot;
return;
+ }
+ }
+
+ if (mUseVertexArrays) {
+ RAS_VAOpenGLRasterizer::IndexPrimitives(
+ vertexarrays, indexarrays,
+ mode, polymat,
+ rendertools, useObjectColor,
+ rgbacolor,slot
+ );
+ } else {
+ RAS_OpenGLRasterizer::IndexPrimitives(
+ vertexarrays, indexarrays,
+ mode, polymat,
+ rendertools, useObjectColor,
+ rgbacolor,slot
+ );
}
-
- RAS_OpenGLRasterizer::IndexPrimitives(
- vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
- rgbacolor,slot
- );
if(!useObjectColor) {
localSlot->EndList();
@@ -190,20 +227,61 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(
localSlot = FindOrAdd(vertexarrays, slot);
localSlot->DrawList();
- if(localSlot->End())
+ if(localSlot->End()) {
+ // save slot here too, needed for replicas and object using same mesh
+ // => they have the same vertexarray but different mesh slot
+ *slot = localSlot;
return;
+ }
+ }
+
+ if (mUseVertexArrays) {
+ RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(
+ vertexarrays, indexarrays,
+ mode, polymat,
+ rendertools, useObjectColor,
+ rgbacolor,slot
+ );
+ } else {
+ RAS_OpenGLRasterizer::IndexPrimitivesMulti(
+ vertexarrays, indexarrays,
+ mode, polymat,
+ rendertools, useObjectColor,
+ rgbacolor,slot
+ );
}
- RAS_OpenGLRasterizer::IndexPrimitivesMulti(
- vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
- rgbacolor,slot
- );
if(!useObjectColor) {
localSlot->EndList();
*slot = localSlot;
}
}
+bool RAS_ListRasterizer::Init(void)
+{
+ if (mUseVertexArrays) {
+ return RAS_VAOpenGLRasterizer::Init();
+ } else {
+ return RAS_OpenGLRasterizer::Init();
+ }
+}
+
+void RAS_ListRasterizer::SetDrawingMode(int drawingmode)
+{
+ if (mUseVertexArrays) {
+ RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode);
+ } else {
+ RAS_OpenGLRasterizer::SetDrawingMode(drawingmode);
+ }
+}
+
+void RAS_ListRasterizer::Exit()
+{
+ if (mUseVertexArrays) {
+ RAS_VAOpenGLRasterizer::Exit();
+ } else {
+ RAS_OpenGLRasterizer::Exit();
+ }
+}
+
// eof
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index 82840cd1399..4b3304d7396 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -2,17 +2,20 @@
#define __RAS_LISTRASTERIZER_H__
#include "RAS_MaterialBucket.h"
-#include "RAS_OpenGLRasterizer.h"
+#include "RAS_VAOpenGLRasterizer.h"
#include <vector>
+class RAS_ListRasterizer;
class RAS_ListSlot : public KX_ListSlot
{
unsigned int m_list;
unsigned int m_flag;
+ RAS_ListRasterizer* m_rasty;
public:
- RAS_ListSlot();
+ RAS_ListSlot(RAS_ListRasterizer* rasty);
virtual ~RAS_ListSlot();
virtual void SetModified(bool mod);
+ virtual int Release();
void RemoveList();
void DrawList();
@@ -33,15 +36,17 @@ enum RAS_ListSlotFlags {
typedef std::map<const vecVertexArray, RAS_ListSlot*> RAS_Lists;
-class RAS_ListRasterizer : public RAS_OpenGLRasterizer
+class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
{
+ bool mUseVertexArrays;
RAS_Lists mLists;
RAS_ListSlot* FindOrAdd(const vecVertexArray& vertexarrays, KX_ListSlot** slot);
void ReleaseAlloc();
public:
- RAS_ListRasterizer(RAS_ICanvas* canvas);
+ void RemoveListSlot(RAS_ListSlot* list);
+ RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
virtual ~RAS_ListRasterizer();
virtual void IndexPrimitives(
@@ -66,6 +71,11 @@ public:
class KX_ListSlot** slot
);
+ virtual bool Init();
+ virtual void Exit();
+
+ virtual void SetDrawingMode(int drawingmode);
+
virtual bool QueryLists(){return true;}
};
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 53ec7a02e6f..4f9c3a1bfb3 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -46,8 +46,12 @@
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
+#if defined(__sun__) && !defined(__sparc__)
+#include <mesa/glu.h>
+#else
#include <GL/glu.h>
#endif
+#endif
#include "RAS_Rect.h"
#include "RAS_TexVert.h"
@@ -82,7 +86,9 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_setfocallength(false),
m_noOfScanlines(32),
m_useTang(false),
- m_materialCachingInfo(0)
+ m_materialCachingInfo(0),
+ m_motionblur(0),
+ m_motionblurvalue(-1.0)
{
m_viewmatrix.Identity();
@@ -1979,3 +1985,15 @@ void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
else
glDisable(mode);
}
+
+void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
+{
+ m_motionblur = 1;
+ m_motionblurvalue = motionblurvalue;
+}
+
+void RAS_OpenGLRasterizer::DisableMotionBlur()
+{
+ m_motionblur = 0;
+ m_motionblurvalue = -1.0;
+}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index d95ced658ce..6728905aa57 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -91,6 +91,10 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
int m_noOfScanlines;
bool InterlacedStereo() const;
+ //motion blur
+ int m_motionblur;
+ float m_motionblurvalue;
+
protected:
int m_drawingmode;
TexCoGen m_texco[RAS_MAX];
@@ -293,8 +297,22 @@ public:
const RAS_TexVert& v2,
const RAS_TexVert& v3,
const MT_Vector3 &no);
-
+
+ virtual void EnableMotionBlur(float motionblurvalue);
+ virtual void DisableMotionBlur();
+ virtual float GetMotionBlurValue(){return m_motionblurvalue;};
+ virtual int GetMotionBlurState(){return m_motionblur;};
+ virtual void SetMotionBlurState(int newstate)
+ {
+ if(newstate<0)
+ m_motionblur = 0;
+ else if(newstate>2)
+ m_motionblur = 2;
+ else
+ m_motionblur = newstate;
+ };
};
#endif //__RAS_OPENGLRASTERIZER
+
diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp
index 232ceb06958..4787847da0d 100644
--- a/source/gameengine/SceneGraph/SG_IObject.cpp
+++ b/source/gameengine/SceneGraph/SG_IObject.cpp
@@ -128,6 +128,11 @@ ActivateDestructionCallback(
// Call client provided destruction function on this!
m_callbacks.m_destructionfunc(this,m_SGclientObject,m_SGclientInfo);
}
+ else
+ {
+ // no callback but must still destroy the node to avoid memory leak
+ delete this;
+ }
}
void
diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h
index ef5af717d60..7ba13cc0a87 100644
--- a/source/gameengine/SceneGraph/SG_Node.h
+++ b/source/gameengine/SceneGraph/SG_Node.h
@@ -173,7 +173,7 @@ public:
void
SetSimulatedTime(
double time,
- bool resurse
+ bool recurse
);
/**
diff --git a/source/kernel/gen_messaging/intern/Makefile b/source/kernel/gen_messaging/intern/Makefile
index cd6afa19a3f..8b204800650 100644
--- a/source/kernel/gen_messaging/intern/Makefile
+++ b/source/kernel/gen_messaging/intern/Makefile
@@ -36,10 +36,6 @@ DIR = $(OCGDIR)/kernel/$(LIBNAME)
include nan_compile.mk
-ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
- CFLAGS += -funsigned-char
-endif
-
CFLAGS += $(LEVEL_1_C_WARNINGS)
# path to our own external headerfiles
diff --git a/source/nan_compile.mk b/source/nan_compile.mk
index d356d13be42..afea7a01239 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -43,8 +43,8 @@ ifneq ($(NAN_NO_KETSJI), true)
CFLAGS += -DUSE_SUMO_SOLID
CCFLAGS += -DUSE_SUMO_SOLID
ifeq ($(NAN_USE_BULLET), true)
- CFLAGS += -DUSE_BULLET
- CCFLAGS += -DUSE_BULLET
+ CFLAGS += -DUSE_BULLET -DWITH_BULLET
+ CCFLAGS += -DUSE_BULLET -DWITH_BULLET
endif
else
CPPFLAGS += -DNO_KETSJI
@@ -65,8 +65,8 @@ DBG_CCFLAGS += -g
ifeq ($(OS),beos)
CC = gcc
CCC = g++
- CFLAGS += -pipe -fPIC
- CFLAGS += -pipe -fPIC
+ 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
@@ -81,11 +81,11 @@ ifeq ($(OS),darwin)
CC = gcc
CCC = g++
ifeq ($(CPU),powerpc)
- CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5
- CCFLAGS += -pipe -fPIC
+ 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
- CCFLAGS += -pipe -fPIC
+ CFLAGS += -pipe -fPIC -ffast-math -march=pentium-m -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
endif
REL_CFLAGS += -O2
REL_CCFLAGS += -O2
@@ -103,8 +103,8 @@ ifeq ($(OS),freebsd)
CCC = g++
JAVAC = javac
JAVAH = javah
- CFLAGS += -pipe -fPIC
- CCFLAGS += -pipe -fPIC
+ 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
@@ -140,8 +140,8 @@ ifeq ($(OS),linux)
CC = gcc
CCC = g++
# CFLAGS += -pipe
- CFLAGS += -pipe -fPIC
- CCFLAGS += -pipe -fPIC
+ CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing
# CCFLAGS += -pipe
REL_CFLAGS += -O2
REL_CCFLAGS += -O2
@@ -158,8 +158,8 @@ endif
ifeq ($(OS),openbsd)
CC = gcc
CCC = g++
- CFLAGS += -pipe -fPIC
- CCFLAGS += -pipe -fPIC
+ 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
@@ -171,23 +171,44 @@ ifeq ($(OS),openbsd)
endif
ifeq ($(OS),solaris)
- CC = gcc
- CCC = g++
+ # 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
+ else
+ CC = gcc
+ CCC = g++
+ #CC = cc
+ #CCC = CC
+ endif
+
JAVAC = javac
JAVAH = javah
- CFLAGS += -pipe -fPIC
- CCFLAGS += -pipe -fPIC
- REL_CFLAGS += -O1
- REL_CCFLAGS += -O1
+ 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
+# endif
+
+ REL_CFLAGS += -O2
+ REL_CCFLAGS += -O2
+
NAN_DEPEND = true
- ifeq ($(CPU),sparc)
- OPENGL_HEADERS = /usr/openwin/share/include
- CPPFLAGS += -DSUN_OGL_NO_VERTEX_MACROS
- JAVA_HEADERS = /usr/java/include
- JAVA_SYSTEM_HEADERS = /usr/java/include/solaris
- else
- OPENGL_HEADERS = /usr/local/include
- endif
+# ifeq ($(CPU),sparc)
+ ifeq ($(findstring sparc,$(CPU)), sparc)
+ OPENGL_HEADERS = /usr/openwin/share/include
+ CPPFLAGS += -DSUN_OGL_NO_VERTEX_MACROS
+ JAVA_HEADERS = /usr/java/include
+ JAVA_SYSTEM_HEADERS = /usr/java/include/solaris
+ else
+ # OPENGL_HEADERS = /usr/X11/include/mesa
+ OPENGL_HEADERS = /usr/X11/include/
+ endif
AR = ar
ARFLAGS = ruv
ARFLAGSQUIET = ru
@@ -197,8 +218,8 @@ ifeq ($(OS),windows)
ifeq ($(FREE_WINDOWS),true)
CC = gcc
CCC = g++
- CFLAGS += -pipe -mno-cygwin -mwindows
- CCFLAGS += -pipe -mno-cygwin -mwindows
+ CFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing
+ CCFLAGS += -pipe -mno-cygwin -mwindows -funsigned-char -fno-strict-aliasing
CPPFLAGS += -DFREE_WINDOWS
REL_CFLAGS += -O2
REL_CCFLAGS += -O2
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index efc3c050527..36b140c1ffb 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -102,7 +102,7 @@ endif
else
export NAN_FTGL ?= $(LCGDIR)/ftgl
export NAN_FFMPEG ?= $(LCGDIR)/ffmpeg
- export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libavcodec.a
+ export NAN_FFMPEGLIBS ?= $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a
export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include
endif
@@ -111,7 +111,7 @@ endif
endif
export WITH_OPENEXR ?= true
-
+ export WITH_DDS ?= true
ifeq ($(OS),windows)
export NAN_WINTAB ?= $(LCGDIR)/wintab
@@ -136,17 +136,24 @@ endif
else
ifeq ($(OS),linux)
ifeq ($(WITH_OPENEXR), true)
- NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
- NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
- NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs OpenEXR | sed -s "s/-l//g" )))
+ NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
+ NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
+ NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs OpenEXR | sed -s "s/-l//g" )))
endif
else
- export NAN_OPENEXR ?= /usr/local
- export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a
+ ifeq ($(OS), solaris)
+ # this only exists at the moment for i386-64 CPU Types at the moment
+ export NAN_OPENEXR ?= $(LCGDIR)/openexr
+
+ export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a -lrt
+ else
+ export NAN_OPENEXR ?= /usr/local
+ export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a
+ endif
endif
endif
ifeq ($(WITH_OPENEXR), true)
- export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR
+ export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR
endif
endif
@@ -165,6 +172,7 @@ endif
export NAN_PYTHON ?= $(LCGDIR)/python
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= $(LCGDIR)/jpeg
@@ -211,10 +219,12 @@ endif
export NAN_PYTHON ?= /System/Library/Frameworks/Python.framework/Versions/2.3
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= -framework Python
else
export NAN_PYTHON ?= /sw
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
endif
export NAN_OPENAL ?= $(LCGDIR)/openal
@@ -229,6 +239,10 @@ endif
export NAN_NSPR ?= $(LCGDIR)/nspr
export NAN_FREETYPE ?= $(LCGDIR)/freetype
export NAN_GETTEXT ?= $(LCGDIR)/gettext
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/libintl.a
+ ifeq (($CPU), i386)
+ export NAN_GETTEXT_LIB += $(NAN_GETTEXT)/lib/libintl.a
+ endif
export NAN_SDL ?= $(LCGDIR)/sdl
export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include
export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a -framework Cocoa -framework IOKit
@@ -270,6 +284,7 @@ endif
export NAN_PYTHON ?= /usr/local
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
export NAN_OPENAL ?= /usr/local
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= /usr/local
@@ -314,6 +329,7 @@ endif
export NAN_PYTHON ?= $(LCGDIR)/python
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= $(LCGDIR)/jpeg
@@ -326,6 +342,7 @@ endif
export NAN_NSPR ?= $(LCGDIR)/nspr
export NAN_FREETYPE ?= /usr/freeware
export NAN_GETTEXT ?= /usr/freeware
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib32/libintl.a
export NAN_SDL ?= $(LCGDIR)/sdl
export NAN_SDLLIBS ?= -L$(NAN_SDL)/lib -lSDL
export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include/SDL
@@ -356,12 +373,9 @@ endif
export FREEDESKTOP ?= true
export NAN_PYTHON ?= /usr
- ifeq ($(CPU),ia64)
- export NAN_PYTHON_VERSION ?= 2.2
- else
- export NAN_PYTHON_VERSION ?= 2.3
- endif
+ export NAN_PYTHON_VERSION ?= 2.5
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
export NAN_OPENAL ?= /usr
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= /usr
@@ -380,7 +394,7 @@ endif
ifneq ($(NAN_USE_FFMPEG_CONFIG), true)
export NAN_FFMPEG ?= /usr
- export NAN_FFMPEGLIBS ?= -L$(NAN_FFMPEG)/lib -lavformat -lavcodec -lavutil -ldts -lz
+ export NAN_FFMPEGLIBS ?= -L$(NAN_FFMPEG)/lib -lavformat -lavcodec -lavutil -lswscale -ldts -lz
export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include
endif
@@ -402,6 +416,8 @@ endif
# enable freetype2 support for text objects
export WITH_FREETYPE2 ?= true
+ export WITH_BINRELOC ?= true
+
# enable ffmpeg support
ifndef NAN_NO_FFMPEG
export WITH_FFMPEG ?= true
@@ -417,6 +433,7 @@ endif
export NAN_PYTHON ?= $(LCGDIR)/python
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= $(LCGDIR)/jpeg
@@ -456,24 +473,26 @@ endif
export ID = $(shell /usr/ucb/whoami)
export HOST = $(shell hostname)
- export NAN_PYTHON ?= /usr/local
- export NAN_PYTHON_VERSION ?= 2.3
+ export NAN_PYTHON ?= $(LCGDIR)/python
+ export NAN_PYTHON_VERSION ?= 2.5
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
- export NAN_OPENAL ?= /usr/local
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
+ export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
- export NAN_JPEG ?= /usr/local
- export NAN_PNG ?= /usr/local
+ export NAN_JPEG ?= $(LCGDIR)/jpeg
+ export NAN_PNG ?= $(LCGDIR)/png
export NAN_TIFF ?= /usr
export NAN_ODE ?= $(LCGDIR)/ode
export NAN_TERRAPLAY ?=
- export NAN_MESA ?= /usr/src/Mesa-3.1
- export NAN_ZLIB ?= /usr
+ export NAN_MESA ?= /usr/X11
+ export NAN_ZLIB ?= $(LCGDIR)/zlib
export NAN_NSPR ?= $(LCGDIR)/nspr
export NAN_FREETYPE ?= $(LCGDIR)/freetype
export NAN_GETTEXT ?= $(LCGDIR)/gettext
- export NAN_SDL ?= $(shell sdl-config --prefix)
- export NAN_SDLLIBS ?= $(shell sdl-config --libs)
- export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags)
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/libintl.a $(NAN_GETTEXT)/lib/libiconv.a
+ export NAN_SDL ?= $(LCGDIR)/sdl
+ export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include/SDL
+ export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a
# Uncomment the following line to use Mozilla inplace of netscape
# CPPFLAGS +=-DMOZ_NOT_NET
@@ -502,20 +521,18 @@ endif
export NAN_PYTHON_VERSION ?= 2.5
ifeq ($(FREE_WINDOWS), true)
export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/freepy.a
export NAN_FREETYPE ?= $(LCGDIR)/gcc/freetype
export NAN_ODE ?= $(LCGDIR)/gcc/ode
- ifeq ($(NAN_SDL),)
- export NAN_SDL ?= $(LCGDIR)/gcc/sdl
- export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include
- endif
+ export NAN_SDL ?= $(LCGDIR)/gcc/sdl
+ export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include
else
export NAN_PYTHON_BINARY ?= python
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python23.lib
export NAN_FREETYPE ?= $(LCGDIR)/freetype
export NAN_ODE ?= $(LCGDIR)/ode
- ifeq ($(NAN_SDL),)
- export NAN_SDL ?= $(LCGDIR)/sdl
- export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include
- endif
+ export NAN_SDL ?= $(LCGDIR)/sdl
+ export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include
endif
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
@@ -527,6 +544,11 @@ endif
export NAN_ZLIB ?= $(LCGDIR)/zlib
export NAN_NSPR ?= $(LCGDIR)/nspr
export NAN_GETTEXT ?= $(LCGDIR)/gettext
+ ifeq ($(FREE_WINDOWS), true)
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/freegettext.a $(NAN_ICONV)/lib/freeiconv.a
+ else
+ export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/gnu_gettext.lib $(NAN_ICONV)/lib/iconv.lib
+ endif
# Uncomment the following line to use Mozilla inplace of netscape
# CPPFLAGS +=-DMOZ_NOT_NET
@@ -554,6 +576,8 @@ endif
export NAN_PYTHON ?= $(LCGDIR)/python
export NAN_PYTHON_VERSION ?= 2.3
export NAN_PYTHON_BINARY ?= python
+ export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
+
export NAN_OPENAL ?= $(LCGDIR)/openal
export NAN_FMOD ?= $(LCGDIR)/fmod
export NAN_JPEG ?= $(LCGDIR)/jpeg
@@ -605,3 +629,8 @@ ifeq ($(NAN_NO_KETSJI), true)
export NAN_JUST_BLENDERDYNAMIC=true
export NAN_NO_OPENAL=true
endif
+
+# INTERNATIONAL implies WITH_FREETYPE2
+ifeq ($(INTERNATIONAL), true)
+ export WITH_FREETYPE2=true
+endif
diff --git a/source/nan_link.mk b/source/nan_link.mk
index e6824643a04..e0745e9c1d4 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -52,7 +52,6 @@ SOEXT = .so
ifeq ($(OS),beos)
LLIBS = -L/boot/develop/lib/x86/ -lGL -lbe -L/boot/home/config/lib/
- LLIBS += -lpython1.5
endif
ifeq ($(OS),darwin)
@@ -118,7 +117,14 @@ ifeq ($(OS),openbsd)
endif
ifeq ($(OS),solaris)
- LLIBS = -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl
+ ifeq (x86_64, $(findstring x86_64, $(CPU)))
+ LLIBS = -lrt
+ LLIBS += -L$(NAN_MESA)/lib/amd64
+ else
+ LLIBS += -L$(NAN_MESA)/lib
+ endif
+
+ LLIBS += -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldl -lsocket -lnsl
DYNLDFLAGS = -shared $(LDFLAGS)
endif
@@ -162,3 +168,9 @@ endif
ifeq ($(WITH_FFMPEG),true)
LLIBS += $(NAN_FFMPEGLIBS)
endif
+
+ifeq ($(INTERNATIONAL),true)
+ LLIBS += $(NAN_GETTEXT_LIB)
+endif
+
+LLIBS += $(NAN_PYTHON_LIB)
diff --git a/tools/Blender.py b/tools/Blender.py
index 040928b6d55..967bf1fcd3c 100644
--- a/tools/Blender.py
+++ b/tools/Blender.py
@@ -143,7 +143,7 @@ def setup_syslibs(lenv):
lenv['BF_PNG_LIB'],
lenv['BF_ZLIB_LIB']
]
- if lenv['BF_DEBUG']==1 and lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
+ if lenv['BF_DEBUG']==1 and lenv['OURPLATFORM'] in ('win32-vc'):
syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
else:
syslibs.append(lenv['BF_PYTHON_LIB'])
@@ -191,12 +191,15 @@ def buildinfo(lenv, build_type):
"""
build_date = time.strftime ("%Y-%m-%d")
build_time = time.strftime ("%H:%M:%S")
+ build_rev = os.popen('svnversion').read()[:-1] # remove \n
+
obj = []
if lenv['BF_BUILDINFO']==1: #user_options_dict['USE_BUILDINFO'] == 1:
if sys.platform=='win32':
build_info_file = open("source/creator/winbuildinfo.h", 'w')
build_info_file.write("char *build_date=\"%s\";\n"%build_date)
build_info_file.write("char *build_time=\"%s\";\n"%build_time)
+ build_info_file.write("char *build_rev=\"%s\";\n"%build_rev)
build_info_file.write("char *build_platform=\"win32\";\n")
build_info_file.write("char *build_type=\"dynamic\";\n")
build_info_file.close()
@@ -205,6 +208,7 @@ def buildinfo(lenv, build_type):
lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
'BUILD_DATE=\'"%s"\''%(build_date),
'BUILD_TYPE=\'"dynamic"\'',
+ 'BUILD_REV=\'"%s"\''%(build_rev),
'NAN_BUILDINFO',
'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
@@ -328,7 +332,7 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(builddir,binary, binary)
commands.getoutput(cmd)
- cmd = 'find %s/%s.app -name ".svn" -prune -exec rm -rf {} \;'%(builddir, binary)
+ cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(builddir, binary)
commands.getoutput(cmd)
cmd = 'find %s/%s.app -name .DS_Store -exec rm -rf {} \;'%(builddir, binary)
commands.getoutput(cmd)
@@ -388,15 +392,18 @@ class BlenderEnvironment(SConsEnvironment):
lenv.Append(CPPDEFINES=defines)
if lenv['WITH_BF_GAMEENGINE']:
lenv.Append(CPPDEFINES=['GAMEBLENDER=1'])
+ if lenv['WITH_BF_BULLET']:
+ lenv.Append(CPPDEFINES=['WITH_BULLET=1'])
# debug or not
# CXXFLAGS defaults to CCFLAGS, therefore
# we Replace() rather than Append() to CXXFLAGS the first time
+ lenv.Replace(CXXFLAGS = lenv['CCFLAGS'])
if lenv['BF_DEBUG'] or (libname in quickdebug):
lenv.Append(CCFLAGS = Split(lenv['BF_DEBUG_FLAGS']))
- lenv.Replace( CXXFLAGS = Split(lenv['BF_DEBUG_FLAGS']))
+ lenv.Append( CXXFLAGS = Split(lenv['BF_DEBUG_FLAGS']))
else:
lenv.Append(CCFLAGS = lenv['REL_CFLAGS'])
- lenv.Replace(CXXFLAGS = lenv['REL_CCFLAGS'])
+ lenv.Append(CXXFLAGS = lenv['REL_CCFLAGS'])
if lenv['BF_PROFILE']:
lenv.Append(CCFLAGS = Split(lenv['BF_PROFILE_FLAGS']),
CXXFLAGS = Split(lenv['BF_PROFILE_FLAGS']))
@@ -425,6 +432,8 @@ class BlenderEnvironment(SConsEnvironment):
if lenv['OURPLATFORM']=='sunos5':
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
+ if lenv['CXX'].endswith('CC'):
+ lenv.Replace(LINK = '$CXX')
if lenv['OURPLATFORM']=='darwin':
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
diff --git a/tools/btools.py b/tools/btools.py
index 1dc35bb7248..a1a953296d9 100755
--- a/tools/btools.py
+++ b/tools/btools.py
@@ -1,8 +1,12 @@
+
import os
import os.path
import SCons.Options
import SCons.Options.BoolOption
-import subprocess
+try:
+ import subprocess
+except ImportError:
+ pass
import string
import glob
import shutil
@@ -26,6 +30,7 @@ def validate_arguments(args, bc):
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
'WITH_BF_FMOD',
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH',
+ 'WITH_BF_DDS',
'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB', 'BF_FFMPEG', 'BF_FFMPEG_INC',
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
'WITH_BF_PNG', 'BF_PNG', 'BF_PNG_INC', 'BF_PNG_LIB', 'BF_PNG_LIBPATH',
@@ -42,15 +47,19 @@ def validate_arguments(args, bc):
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS',
'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB',
- 'WITH_BF_FFMPEG',
'WITH_BF_PLAYER',
+ 'WITH_BF_BINRELOC',
'CFLAGS', 'CCFLAGS', 'CPPFLAGS',
'REL_CFLAGS', 'REL_CCFLAGS',
'C_WARN', 'CC_WARN', 'LLIBS', 'PLATFORM_LINKFLAGS',
'BF_PROFILE_FLAGS', 'LCGDIR', 'WITH_BF_VERSE',
'BF_VERSE_INCLUDE',
'VERSE_BUILD_BINARY', 'VERSE_BUILD_DIR', 'VERSE_REGEN_PROTO',
- 'BF_TWEAK_MODE'
+ 'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
+ 'WITHOUT_BF_INSTALL',
+ 'WITH_BF_OPENMP',
+ 'WITHOUT_BF_INSTALL',
+ 'BF_FANCY',
]
arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE',
@@ -159,6 +168,8 @@ def read_opts(cfg, args):
('BF_OPENEXR_LIB', 'OPENEXR library', ''),
('BF_OPENEXR_LIBPATH', 'OPENEXR library path', ''),
+ (BoolOption('WITH_BF_DDS', 'Use DDS if true', 'true')),
+
(BoolOption('WITH_BF_FFMPEG', 'Use FFMPEG if true', 'false')),
('BF_FFMPEG', 'FFMPEG base path', ''),
('BF_FFMPEG_LIB', 'FFMPEG library', ''),
@@ -240,6 +251,8 @@ def read_opts(cfg, args):
('BF_FREETYPE_LIB', 'Freetype library', ''),
('BF_FREETYPE_LIBPATH', 'Freetype library path', ''),
+ (BoolOption('WITH_BF_OPENMP', 'Use OpenMP if true', 'false')),
+
(BoolOption('WITH_BF_QUICKTIME', 'Use QuickTime if true', 'false')),
('BF_QUICKTIME', 'QuickTime base path', ''),
('BF_QUICKTIME_INC', 'QuickTime include path', ''),
@@ -290,6 +303,10 @@ def read_opts(cfg, args):
(BoolOption('BF_BUILDINFO', 'Buildtime in splash if true', 'true')),
(BoolOption('BF_TWEAK_MODE', 'Enable tweak mode if true', 'false')),
+ (BoolOption('BF_SPLIT_SRC', 'Split src lib into several chunks if true', 'false')),
+ (BoolOption('WITHOUT_BF_INSTALL', 'dont install if true', 'false')),
+ (BoolOption('BF_FANCY', 'Enable fancy output if true', 'true')),
+ (BoolOption('WITH_BF_BINRELOC', 'Enable relocatable binary (linux only)', 'false')),
) # end of opts.AddOptions()